--a910 000d69bbd7740110002 Page 1 of MANIFEST
88872c 1 test-file
e80832 2 MANIFEST
91e07b 3 winhashes.asc
7b96b1 D libs/
01ec61 D libs/pgpcdk/
135f1a D libs/pgpcdk/priv/
876a79 D libs/pgpcdk/priv/networklib/
5d89a4 D libs/pgpcdk/priv/networklib/pgpsockets/
d253d4 D libs/pgpcdk/priv/networklib/pgpsockets/win/
28243f D libs/pgpcdk/priv/networklib/pgpsockets/win/src/
6477e4 4 Makefile
6c052b D libs/pgpcdk/priv/networklib/win32/
3c3973 5 PGPsdkNetworkLibDLLMain.c
4a87e8 6 PGPsdkNetworkLibDLLMain.h
f8d70e D libs/pgpcdk/win32/
a1b977 7 pgpConfig.h
f0f32b D libs/pgpcdk/win32/PGPcdk/
97a929 8 PGPcdk.def
a83e89 9 PGPcdk.dsp
d456c6 10 PGPcdk.dsw
3fd041 11 pgpsdk.rc
6d7c64 12 resource.h
d13a74 D libs/pgpcdk/win32/PGPsdkNetworkLib/
5fe578 13 PGPsdkNetworkLib.def
e0d239 14 PGPsdkNetworkLib.dsp
7116f8 15 PGPsdkNetworkLib.dsw
7ed435 16 PGPsdkNetworkLib.rc
1d6f7d 17 resource.h
01d71e D libs/pgpcdk/win32/PGPsdkUI/
9912dd 18 PGPCL.h
51caff 19 PGPCollectRandomDataCL.cpp
7d90af 20 PGPCollectRandomDataDialog.cpp
6d9e73 21 PGPKeyServerDialogs.cpp
2210b1 22 PGPOptionsDialog.cpp
523227 23 PGPPassphraseCL.cpp
a41455 24 PGPPassphraseDialog.cpp
840510 25 PGPRecipientDialog.cpp
32b009 26 PGPsdkUI.def
da6a2e 27 PGPsdkUI.dsp
488693 28 PGPsdkUI.dsw
d2ad12 29 PGPui.rc
f4671f 30 PGPui32.h
268e9e 31 PGPuiVer.rc
f84d2d 32 RDdrag.c
2ffc14 33 RDdrag.h
427bfb 34 RDdraw.c
18cac2 35 RDdraw.h
72c8c4 36 RDkeyDB.c
0aa939 37 RDkeyDB.h
ef8d7a 38 RDlstmng.c
a56c7f 39 RDlstmng.h
8a8e9b 40 RDlstsrt.c
ec6f9e 41 RDlstsrt.h
c83d26 42 RDlstsub.c
22dc23 43 RDlstsub.h
1b9675 44 RDmain.c
06e4ef 45 RDmove.c
89fef4 46 RDmove.h
a98888 47 RDprecmp.h
4511d6 48 RDproc.c
85a0ef 49 RDproc.h
2e5c48 50 RDserver.c
72bd4d 51 RDserver.h
541502 52 RDstruct.h
13afe9 53 UIhelp.h
fdae61 54 pgpCLUtils.c
5302e3 55 pgpCLUtils.h
7b1fbb 56 pgpImage.h
1a4525 57 pgpKB.h
ea3a1e 58 pgpKBNT.c
afac42 59 resource.h
d68acf D libs/network/
--c724 00054feb39340110002 Page 2 of MANIFEST
93f770 D libs/network/ldaplib/
126239 D libs/network/ldaplib/win32/
df4b0f 60 liblber.dsp
004f74 61 libldap.dsp
7506ed D libs/pfl/
588416 D libs/pfl/win32/
aa2e6c 62 pgpMemLockWin32.h
3929fb 63 pgpPFLConfig.h
3a1613 D libs/pfl/win32/InstallDll/
d5eee6 64 install.cpp
b0ba44 65 install.def
23ab77 66 install.dsp
ac9895 67 install.dsw
dd158e D libs/pfl/win32/SecureMemory/
e0f6fd D libs/pfl/win32/SecureMemory/win95/
536527 68 PGPmemlock.dsp
3e3820 69 PGPmemlock.dsw
b4a5cf 70 PGPmemlock.mak
9e8255 D libs/pfl/win32/SecureMemory/win95/Install/
4dfcca 71 PGPml95_Install.txt
fd1339 D libs/pfl/win32/SecureMemory/win95/Source/
93ed2f 72 pgpML.rc
31bce5 73 pgpMLdevdcl.asm
a96248 74 pgpMemLock.c
fd5ec9 75 pgpMemLock.def
8d6dd0 76 pgpVer.h
21a408 D libs/pfl/win32/SecureMemory/winNT/
6986cc 77 DIRS
8d13db D libs/pfl/win32/SecureMemory/winNT/Install/
622e2c 78 PGPmemlock.ini
ec8205 79 PGPmlNT_Install.txt
a63cfc D libs/pfl/win32/SecureMemory/winNT/Source/
0b82ec 80 MAKEFILE
998d4f 81 SOURCES
f23822 82 pgpMemLock.c
6d4e66 83 pgpMemLock.rc
da4e86 84 pgpVer.h
57c08a D libs/pfl/win32/pflCommon/
ccdfba 85 pflCommon.dsp
330893 86 pflCommon.dsw
192bac D libs/pfl/win32/pgpAsyncDNS/
935af1 87 pgpAsyncDNS.c
9e5cde 88 pgpAsyncDNS.h
16eeee D clients/
b44290 D clients/disk/
b798fa D clients/disk/win32/
41907c 89 PGPdisk.dsw
99c345 90 PGPdiskApp.dsp
829e42 91 PGPdiskApp.dsw
f7606c 92 PGPdiskDrvNT.dsp
98be2d 93 PGPdiskDrvNT.dsw
488861 94 PGPdiskDrvWin95.dsp
276c34 95 PGPdiskDrvWin95.dsw
c5ccb1 96 PGPdiskInstallHelper.dsp
83d3f1 97 PGPdiskInstallHelper.dsw
d062bf 98 PGPdiskResident.dsp
0986ea 99 PGPdiskResident.dsw
0ba378 100 PGPdiskShellExt.dsp
04472d 101 PGPdiskShellExt.dsw
a7a6a7 D clients/disk/win32/Encryption/
d2889c 102 Cast5.cpp
72c5e1 103 Cast5.h
a30581 104 Cast5Box.cpp
8508c4 105 Cast5Box.h
7bdcd1 106 CipherContext.cpp
8dd02e 107 CipherContext.h
58069d 108 CipherUtils.cpp
3a903d 109 CipherUtils.h
24283b 110 PGPdiskRandomPool.cpp
f0b50a 111 PGPdiskRandomPool.h
3265fc 112 SHA.cpp
54d9b6 113 SHA.h
--e894 0005617e53a40110002 Page 3 of MANIFEST
b93ba0 D clients/disk/win32/PGPdiskApp/
bf38e2 114 PGPdiskApp.rc
95514f 115 PGPdiskAppVer.rc
a1b5d9 D clients/disk/win32/PGPdiskApp/Res/
2e3302 116 PGPdiskApp.rc2
1c7d15 D clients/disk/win32/PGPdiskApp/Source/
c1d587 117 CAboutBoxDialog.cpp
2a8661 118 CAboutBoxDialog.h
171a70 119 CConfirmPassphraseDialog.cpp
16cb3a 120 CConfirmPassphraseDialog.h
10c4db 121 CConvertPGPdiskThread.cpp
b58b35 122 CConvertPGPdiskThread.h
ca7b81 123 CConvertWizConvertPage.cpp
c359e8 124 CConvertWizConvertPage.h
664fcd 125 CConvertWizDonePage.cpp
ab682d 126 CConvertWizDonePage.h
7a78c6 127 CConvertWizIntroPage.cpp
240e35 128 CConvertWizIntroPage.h
8bdada 129 CConvertWizRandomDataPage.cpp
27771d 130 CConvertWizRandomDataPage.h
ce987c 131 CConvertWizardSheet.cpp
970248 132 CConvertWizardSheet.h
d69e86 133 CCreatePGPdiskThread.cpp
25f8e9 134 CCreatePGPdiskThread.h
a6d8bc 135 CDiskWizADKPage.cpp
fd799d 136 CDiskWizADKPage.h
d0635d 137 CDiskWizCreationPage.cpp
84a175 138 CDiskWizCreationPage.h
8521f6 139 CDiskWizDonePage.cpp
96477b 140 CDiskWizDonePage.h
61840b 141 CDiskWizIntroPage.cpp
cd59c0 142 CDiskWizIntroPage.h
b2e6cf 143 CDiskWizPassphrasePage.cpp
1200d3 144 CDiskWizPassphrasePage.h
ae694f 145 CDiskWizRandomDataPage.cpp
c8c754 146 CDiskWizRandomDataPage.h
4cae2d 147 CDiskWizVolumeInfoPage.cpp
8bfb32 148 CDiskWizVolumeInfoPage.h
2601b1 149 CDiskWizardSheet.cpp
41e539 150 CDiskWizardSheet.h
fb7f9c 151 CDriveLetterCombo.cpp
40ba0b 152 CDriveLetterCombo.h
7fec5e 153 CGetUserInfoDialog.cpp
d98cc1 154 CGetUserInfoDialog.h
5375ca 155 CGlobalCSearchPGPdiskThread.cpp
054a3d 156 CGlobalCSearchPGPdiskThread.h
035e67 157 CGlobalCWizDonePage.cpp
b1d42c 158 CGlobalCWizDonePage.h
deb1d4 159 CGlobalCWizIntroPage.cpp
2959fb 160 CGlobalCWizIntroPage.h
27d9d1 161 CGlobalCWizSearchPage.cpp
0c6891 162 CGlobalCWizSearchPage.h
2e2d46 163 CGlobalCWizardSheet.cpp
3b7cbd 164 CGlobalCWizardSheet.h
44ed98 165 CMainDialog.cpp
63eee4 166 CMainDialog.h
cfdd9c 167 CNagBuyDialog.cpp
f10026 168 CNagBuyDialog.h
6675ee 169 COpenPGPdiskDialog.cpp
22456f 170 COpenPGPdiskDialog.h
78dedb 171 CPGPdiskApp.cpp
474152 172 CPGPdiskApp.h
a145d2 173 CPGPdiskAppACI.cpp
d1a3b0 174 CPGPdiskAppACI.h
894181 175 CPGPdiskAppPassphrase.cpp
1cdfed 176 CPGPdiskAppPassphrase.h
3e8f64 177 CPGPdiskAppRegistry.cpp
49e0af 178 CPGPdiskAppRegistry.h
65951e 179 CPGPdiskAppVolumes.cpp
f7c724 180 CPGPdiskAppVolumes.h
74e9d3 181 CPGPdiskAppWinutils.cpp
569be1 182 CPGPdiskAppWinutils.h
--8ccd 000b61b0da940110002 Page 4 of MANIFEST
43778e 183 CPGPdiskCmdLine.cpp
79482d 184 CPGPdiskCmdLine.h
5165e9 185 CPreferencesSheet.cpp
3e02ba 186 CPreferencesSheet.h
8323d4 187 CPrefsAutoUnmountPage.cpp
6114b1 188 CPrefsAutoUnmountPage.h
91a73b 189 CPrefsUnmountHotKeyPage.cpp
21c59c 190 CPrefsUnmountHotKeyPage.h
29c3c2 191 CPublicKeyDialog.cpp
3cf840 192 CPublicKeyDialog.h
6bce2a 193 CSavePGPdiskDialog.cpp
f5f17c 194 CSavePGPdiskDialog.h
c7fd1f 195 CSecureEdit.cpp
e6ce82 196 CSecureEdit.h
77c487 197 CSinglePassphraseDialog.cpp
0a1b84 198 CSinglePassphraseDialog.h
dd80ec 199 CSplashScreenDialog.cpp
5303e3 200 CSplashScreenDialog.h
5a0c07 201 CSuperHotKeyControl.cpp
4e35ed 202 CSuperHotKeyControl.h
885cf3 203 CUnmountPGPdiskDialog.cpp
25cef1 204 CUnmountPGPdiskDialog.h
f837ed 205 File.cpp
f7579e 206 File.h
b837be 207 Globals.h
ccb411 208 PGPdisk.cpp
bdafa6 209 PGPdisk.h
71f25f 210 PGPdiskHelpIds.h
91ef70 211 Resource.h
79d024 212 StdAfx.cpp
4630d9 213 StdAfx.h
d4e702 214 VolFile.cpp
0b379c 215 VolFile.h
518737 216 Volume.cpp
87e6d2 217 Volume.h
38fac4 D clients/disk/win32/PGPdiskDrvNT/
69502c 218 PGPdisk.rc
291deb 219 RunBuild.bat
f9eab4 220 RunBuildAux.bat
3d53e0 221 makefile
cad844 222 makefile.inc
404b0c 223 msglog.mc
ce8cf8 224 pgpsym.bat
248951 225 sources
9148c3 D clients/disk/win32/PGPdiskDrvNT/FakeSource/
ab26b0 226 Crtdbg.h
68e6a7 227 Limits.h
79b5be D clients/disk/win32/PGPdiskDrvNT/Source/
d51f42 228 CPGPdiskDriver.cpp
eab512 229 CPGPdiskDriver.h
6a878a 230 CPGPdiskInterface.cpp
cbd126 231 CPGPdiskInterface.h
3700e9 232 CPGPdiskInterfaceComm.cpp
50815b 233 CPGPdiskInterfaceComm.h
4193a0 234 CPGPdiskInterfaceErrors.cpp
4f921a 235 CPGPdiskInterfaceErrors.h
3744b0 236 CPGPdiskInterfaceHooks.cpp
a24ecd 237 CPGPdiskInterfaceHooks.h
dc2708 238 CPGPdiskInterfaceVolumes.cpp
e956bf 239 CPGPdiskInterfaceVolumes.h
0c664b 240 CRunTimeExtras.cpp
20a24a 241 CRunTimeExtras.h
2e166b 242 FSCTLCodes.h
a2c7ec 243 File.cpp
177cf8 244 File.h
f90794 245 Function.h
bea45f 246 Globals.h
7128a8 247 KernelModeUtils.cpp
1a6be6 248 KernelModeUtils.h
061bd7 249 LockableList.h
b32d99 250 LookasideList.h
b69fc4 251 NtThreadSecurity.cpp
--5f30 0004ea63f7440110002 Page 5 of MANIFEST
f6e9f4 252 NtThreadSecurity.h
557945 253 OperatorNewFixups.h
3dc858 254 PGPdisk.cpp
aab325 255 PGPdisk.h
3c501c 256 PGPdiskRequestQueue.cpp
047b1c 257 PGPdiskRequestQueue.h
042519 258 PGPdiskWorkerThread.cpp
72dedb 259 PGPdiskWorkerThread.h
96e3f0 260 UserMemoryManager.cpp
53f200 261 UserMemoryManager.h
5619a8 262 VolFile.cpp
c42812 263 VolFile.h
cbfcea 264 Volume.cpp
29cf68 265 Volume.h
17fd97 D clients/disk/win32/PGPdiskDrvWin95/
b9fc26 266 PGPdiskDrvDebug.bat
7ef1db 267 PGPdiskDrvDebug.mak
e26fb0 268 PGPdiskDrvDebugAux.bat
f10ea5 269 PGPdiskDrvRelease.bat
d43f38 270 PGPdiskDrvRelease.mak
b8b53e 271 PGPdiskDrvReleaseAux.bat
85cec5 D clients/disk/win32/PGPdiskDrvWin95/FakeSource/
fbf8c6 272 Crtdbg.h
4b38d1 273 Limits.h
a2fa9a 274 Stdarg.h
3623ab 275 Stddef.h
8bf99c 276 Stdlib.h
ca0b05 277 String.h
2ec8a3 D clients/disk/win32/PGPdiskDrvWin95/FakeSource/sys/
cbbdae 278 Types.h
a773ce D clients/disk/win32/PGPdiskDrvWin95/Source/
0df05f 279 CPGPdiskDrv.cpp
e9ed9b 280 CPGPdiskDrv.h
b0a7cb 281 CPGPdiskDrvComm.cpp
c36c49 282 CPGPdiskDrvComm.h
7a47df 283 CPGPdiskDrvDebug.cpp
030cb5 284 CPGPdiskDrvDebug.h
d8f5bd 285 CPGPdiskDrvErrors.cpp
1509e0 286 CPGPdiskDrvErrors.h
619675 287 CPGPdiskDrvHooks.cpp
ede12b 288 CPGPdiskDrvHooks.h
3dc8c2 289 CPGPdiskDrvIos.cpp
df391d 290 CPGPdiskDrvIos.h
912593 291 CPGPdiskDrvVolumes.cpp
856fbb 292 CPGPdiskDrvVolumes.h
ad4b52 293 CPGPdiskDrvWinutils.cpp
b39236 294 CPGPdiskDrvWinutils.h
7484f4 295 DcbManager.cpp
81bd30 296 DcbManager.h
90653b 297 FatParser.cpp
70c33c 298 FatParser.h
895aab 299 File.cpp
30a610 300 File.h
28881b 301 FileSystemParser.cpp
fea0c1 302 FileSystemParser.h
6e4c22 303 Globals.h
bbfeb3 304 IopProcessor.cpp
ebf40d 305 IopProcessor.h
15db0f 306 PGPdisk.cpp
27dc6d 307 PGPdisk.h
230b9e 308 PGPdiskVrcSource.cpp
687746 309 PlacementNew.h
099aab 310 VolFile.cpp
744c00 311 VolFile.h
9fd9a9 312 Volume.cpp
2abd2a 313 Volume.h
c3be79 314 Wrappers.h
c062f2 D clients/disk/win32/PGPdiskInstallHelper/
aedf90 315 PGPdiskInstallHelper.def
1da454 316 PGPdiskInstallHelper.rc
8cd751 317 PGPdiskInstallHelperVer.rc
4e5d73 D clients/disk/win32/PGPdiskInstallHelper/Source/
--8365 000fe88bdc240110002 Page 6 of MANIFEST
343024 318 CPGPdiskInstallHelperDll.cpp
0eb03e 319 CPGPdiskInstallHelperDll.h
6621c9 320 Resource.h
9315c7 321 StdAfx.cpp
dde70b 322 StdAfx.h
afbac5 D clients/disk/win32/PGPdiskResident/
532e86 323 PGPdiskResident.rc
91eda6 324 PGPdiskResidentVer.rc
8928ba D clients/disk/win32/PGPdiskResident/Source/
bc1432 325 CHiddenWindow.cpp
76d6da 326 CHiddenWindow.h
22d57e 327 CPGPdiskResidentApp.cpp
60fde6 328 CPGPdiskResidentApp.h
3e4f2f 329 Globals.h
eb5f23 330 Resource.h
bc6b2d 331 StdAfx.cpp
42625e 332 StdAfx.h
41e4a8 D clients/disk/win32/PGPdiskShellExt/
b4e641 333 PGPdiskShellExt.def
466d09 334 PGPdiskShellExt.rc
71140a 335 PGPdiskShellExtVer.rc
81dbb3 D clients/disk/win32/PGPdiskShellExt/Source/
640ca4 336 CPGPdiskShellExtDll.cpp
08b9a3 337 CPGPdiskShellExtDll.h
3f969b 338 CShellExt.cpp
51eecd 339 CShellExt.h
4fe6c1 340 CShellExtClassFactory.cpp
120a84 341 CShellExtClassFactory.h
b3dfc3 342 Globals.h
cd2153 343 Resource.h
8708b3 344 StdAfx.cpp
e64020 345 StdAfx.h
ccee70 D clients/disk/win32/Shared/
e8b75b 346 CommonStrings.cpp
356444 347 CommonStrings.h
1db621 348 DriverComm.cpp
3c4ae8 349 DriverComm.h
afc53c 350 DualErr.cpp
aa0ee9 351 DualErr.h
f82dbb 352 Errors.cpp
967ebb 353 Errors.h
e38fc9 354 FatUtils.cpp
1cede5 355 FatUtils.h
5f4466 356 GenericCallback.h
bc5e59 357 LinkResolution.cpp
9237ec 358 LinkResolution.h
6f1362 359 PGPdiskContainer.cpp
7c89d2 360 PGPdiskContainer.h
3f855a 361 PGPdiskDefaults.h
75417b 362 PGPdiskFileFormat.h
3cb035 363 PGPdiskHighLevelUtils.cpp
3d3c25 364 PGPdiskHighLevelUtils.h
c1fa27 365 PGPdiskLowLevelUtils.cpp
622f2e 366 PGPdiskLowLevelUtils.h
1273a3 367 PGPdiskPfl.cpp
46c9c5 368 PGPdiskPfl.h
b6a012 369 PGPdiskPublicKeyUtils.cpp
d589da 370 PGPdiskPublicKeyUtils.h
cac05c 371 PGPdiskRegistry.cpp
20e3bd 372 PGPdiskRegistry.h
18e2e2 373 PGPdiskResidentDefines.h
0d51f3 374 PGPdiskVersion.h
6bcc4e 375 Packets.h
ae7455 376 Required.h
434b3b 377 SafeObject.h
80fac5 378 SecureMemory.cpp
d81519 379 SecureMemory.h
eb4b3e 380 SecureString.cpp
5f746b 381 SecureString.h
ac79bf 382 SharedMemory.cpp
9da6d1 383 SharedMemory.h
fe1d9b 384 SimpleQueue.h
--1149 0008c44ebcc40110002 Page 7 of MANIFEST
86ae2c 385 StringAssociation.cpp
3d355e 386 StringAssociation.h
9fa46f 387 SystemConstants.h
d5f074 388 UtilityFunctions.h
e75537 389 WaitObjectClasses.cpp
ac2f42 390 WaitObjectClasses.h
a4b99e 391 Win32Utils.cpp
31216d 392 Win32Utils.h
3e4d68 393 WindowsVersion.cpp
2fcc9d 394 WindowsVersion.h
d41b95 D clients/pgp/
3bec2e D clients/pgp/shared/
3ca816 D clients/pgp/shared/JPEG/
f5e2ec D clients/pgp/shared/JPEG/win32/
b126ed 395 jpeglib.dsp
2be8db 396 jpeglib.dsw
d0a87b D clients/pgp/win32/
ea4a37 397 EudoraPlugin.dsp
bc5dff 398 EudoraPlugin.dsw
c6622f 399 EudoraPluginV4.dsp
29c596 400 EudoraPluginV4.dsw
81776f 401 OEloader.dsp
30e219 402 OEloader.dsw
a51054 403 OutlookExpress.dsp
5ed958 404 OutlookExpress.dsw
6d01a7 405 PGP55.DSP
8ccb41 406 PGP55.DSW
b54ecc 407 PGPadmin.dsp
cea271 408 PGPadmin.dsw
b6ee76 409 PGPcl.dsp
58296a 410 PGPcl.dsw
9f8b64 411 PGPhk.dsp
064182 412 PGPhk.dsw
9f3385 413 PGPkeys.dsp
7e0e0a 414 PGPkeys.dsw
d93997 415 PGPlog.dsp
107a68 416 PGPlog.dsw
fa6eba 417 PGPsc.dsp
c5abc6 418 PGPsc.dsw
0a42c4 419 PGPtools.dsp
8d8cb5 420 PGPtools.dsw
88face 421 PGPtray.dsp
2634f8 422 PGPtray.dsw
6104a4 423 Pgpwctx.dsp
3c392b 424 Pgpwctx.dsw
34e3cc 425 TreeList.dsp
ed76ba 426 TreeList.dsw
11838f 427 pgpExch.dsp
845163 428 pgpExch.dsw
85138e D clients/pgp/win32/EudoraPlugin/
687cc5 429 CBTProc.c
cd1279 430 CBTProc.h
d866d4 431 CreateToolbar.c
b08344 432 CreateToolbar.h
9e40a7 433 DisplayMessage.c
9344c3 434 DisplayMessage.h
f7311b 435 EudoraINI.h
ead6d0 436 EudoraMailHeaders.c
e89b25 437 EudoraMailHeaders.h
6f5d58 438 EudoraMainWndProc.c
f510ad 439 EudoraMainWndProc.h
e171e2 440 EudoraReadMailWndProc.c
2c581a 441 EudoraReadMailWndProc.h
c9f933 442 EudoraSendMailWndProc.c
40d0cb 443 EudoraSendMailWndProc.h
5f3fc8 444 MapFile.c
d35e35 445 MapFile.h
2f49d7 446 MyMIMEUtils.c
25236f 447 MyMIMEUtils.h
b8036f 448 PGPDefinedMessages.h
dc52c0 449 PGPPlug.c
8c3c7c 450 PGPPlug.h
--224b 0003a0f5ed140110002 Page 8 of MANIFEST
fb2e33 451 PGPPlugTypes.h
150485 452 PGPplugin.def
a14392 453 PGPplugin.rc
ddac25 454 PGPpluginVer.rc
9c85c7 455 ReadMailToolbarWndProc.c
5297b7 456 ReadMailToolbarWndProc.h
22ee6c 457 SendMailToolbarWndProc.c
5d3f4f 458 SendMailToolbarWndProc.h
bec59a 459 TranslatorIDs.h
4db075 460 TranslatorUtils.c
358b8b 461 TranslatorUtils.h
074f6a 462 Translators.c
3925d2 463 Translators.h
9cd689 464 resource.h
34db72 465 strstri.c
46b834 466 strstri.h
adece4 467 transbmp.c
8c3d67 468 transbmp.h
52af89 D clients/pgp/win32/EudoraPlugin/emssdk/
f28490 469 BUFTYPE.CPP
e7f06f 470 BUFTYPE.H
d2642b 471 ENCODING.CPP
93a395 472 ENCODING.H
67bc67 473 MIMETYPE.CPP
f020d5 474 MIMETYPE.H
81e1ad 475 RFC1847.CPP
39a32e 476 RFC1847.H
b2a519 477 RFC822.CPP
f93648 478 RFC822.H
fd1f6f 479 ems-win.h
d0b8bc 480 file1847.cpp
afb725 481 file1847.h
fc0ef4 D clients/pgp/win32/EudoraPluginV4/
8470d3 482 DisplayMessage.c
5f0732 483 DisplayMessage.h
930414 484 MapFile.c
2b65e9 485 MapFile.h
d28993 486 MyMIMEUtils.c
99e32b 487 MyMIMEUtils.h
dc903b 488 PGPplugin.def
f47402 489 PGPplugin.rc
93b080 490 PGPpluginVer.rc
3ed790 491 PluginMain.c
1deb46 492 PluginMain.h
222400 493 TranslatorIDs.h
80e26b 494 TranslatorUtils.c
52d995 495 TranslatorUtils.h
03975d 496 Translators.c
c5fde5 497 Translators.h
9072b1 498 resource.h
85e1c3 499 strstri.c
46dcfd 500 strstri.h
6420fd D clients/pgp/win32/EudoraPluginV4/emssdk/
2e5d0e 501 BUFTYPE.CPP
3d947d 502 BUFTYPE.H
f45633 503 ENCODING.CPP
ff86d6 504 ENCODING.H
b9a6c6 505 MIMETYPE.CPP
68d44c 506 Mimetype.h
3762ae 507 RFC1847.CPP
7ac8a6 508 RFC1847.H
12ad32 509 RFC822.CPP
f88882 510 RFC822.H
8c7687 511 ems-win.h
6ce633 512 file1847.cpp
9165dc 513 file1847.h
382ab5 D clients/pgp/win32/INCLUDE/
939ae1 514 PGPcl.h
da876d 515 PGPgm.h
40d262 516 PGPhk.h
a3a813 517 PGPkm.h
3abdf9 518 PGPpk.h
--4604 000f598422040110002 Page 9 of MANIFEST
4369ca 519 PGPsc.h
be9410 520 TreeList.h
91f8d1 521 pgpImage.h
133a94 522 pgpVersion.h
904f06 523 pgpWerr.h
ab27e4 D clients/pgp/win32/INCLUDE/Help/
2f1731 524 PGPclHlp.h
26042c 525 PGPpkHlp.h
a789e3 526 RDhelp.h
6d01f1 D clients/pgp/win32/Installer/
4446e9 527 build.bat
12aeeb 528 setupinstall.bat
eeae34 D clients/pgp/win32/Installer/Disk1/
b0a25b 529 setup.ini
b12131 D clients/pgp/win32/Installer/docs/
bf01fd 530 DSReadMe.txt
c2cee7 531 FreewareReadMe.txt
8debf2 532 Pgp60.cnt
54409f 533 PGPdisk.cnt
c4e2ce 534 PPReadMe.txt
7924d8 D clients/pgp/win32/Installer/Extras/
55bd64 535 adobe.url
dcbb2f 536 eudora.url
d49a6c D clients/pgp/win32/Installer/keyrings/
a20df6 537 samplekeys.asc
c12976 538 WhatIsThis.txt
cdfc5f D clients/pgp/win32/Installer/licenses/
11adec 539 fieldlic.txt
ed1002 540 freelic.txt
bef23a 541 license.txt
0a7db7 542 reglic.txt
927f7e 543 triallic.txt
eb8f07 D clients/pgp/win32/Installer/setup/
08a0ea 544 SETUP.LST
7db02f 545 setup.ini
7ae6fe 546 setup.rul
ffe05c D clients/pgp/win32/Installer/Uninstaller/
3dffc3 547 BUILD.BAT
5c3b8b D clients/pgp/win32/Installer/Uninstaller/Disk1/
e09e24 548 SETUP.INI
17f4ae D clients/pgp/win32/Installer/Uninstaller/Uninstall/
a92a25 549 SETUP.LST
72e49e 550 setup.rul
1bd94f D clients/pgp/win32/OEloader/
ba5f16 551 main.cpp
a5ab94 552 msimn.rc
27d9d8 553 msimnVer.rc
c61d9d 554 resource.h
826940 D clients/pgp/win32/OutlookExpress/
4fc3c8 555 CBTProc.cpp
4ef02d 556 CommonWndProc.cpp
38858e 557 HookProcs.h
cfe953 558 MainWndProc.cpp
593860 559 PGP55oe.rc
149597 560 PGP55oeVer.rc
42124a 561 PluginInfo.cpp
043d76 562 PluginInfo.h
500863 563 ReadMsgWndProc.cpp
b61310 564 Recipients.cpp
6f3972 565 Recipients.h
2381a3 566 SendMsgWndProc.cpp
e379ca 567 TextIO.cpp
f41d84 568 TextIO.h
2409e4 569 UIutils.cpp
9f6328 570 UIutils.h
03333f 571 UnknownWndProc.cpp
f4a31e 572 main.cpp
ecf80a 573 resource.h
0a3a2d D clients/pgp/win32/PGP55/
c69ec7 574 main.c
860fb4 D clients/pgp/win32/PGPWCTX/
f52bb4 575 CTXMENU.DEF
--c249 00091c23bef40110002 Page 10 of MANIFEST
a9c48c 576 Ctxmenu.cpp
b74af1 577 FolderContext.reg
fdcbab 578 PGPwctx.reg
5ce16c 579 PGPwctxVer.rc
881fd9 580 PRECOMP.H
e70e03 581 Pgpwctx.cpp
764d28 582 Pgpwctx.hpp
56aee0 583 Priv.h
725a49 584 RESOURCE.H
4a679c 585 SClink.cpp
38b0b0 586 Shexinit.cpp
593d0d 587 pgpCodes.hpp
a305c6 588 pgpwctx.rc
a49f11 D clients/pgp/win32/PGPadmin/
e476a9 589 AdditionalDecryption.cpp
f03ea4 590 ClientPrefs.cpp
ddbc56 591 CopyInstaller.cpp
629bbc 592 CopyInstaller.h
de91b6 593 CorpKey.cpp
c2e259 594 CreateWiz.cpp
691e53 595 CreateWiz.h
b6c124 596 DefaultKeys.cpp
cd52f0 597 FindInstaller.cpp
a4d0cb 598 FindInstaller.h
1ac9f8 599 Finish.cpp
9c8db5 600 InstallOptions.cpp
1c7516 601 Intro.cpp
6ba83e 602 KeyGen.cpp
49a3e4 603 License.cpp
d669c2 604 Misc.cpp
1346c3 605 PGPadmin.cpp
8d3612 606 PGPadmin.h
a9a6b7 607 PGPadmin.rc
190b40 608 PGPadminVer.rc
daac68 609 PassPhrase.cpp
8a32e6 610 Review.cpp
4062c1 611 Revoker.cpp
8b3f90 612 ServerUpdates.cpp
55c34a 613 Utils.cpp
0e0d4d 614 Utils.h
2933f7 615 resource.h
4d323a D clients/pgp/win32/PGPsc/
d4de6e 616 AddKey.c
95b87b 617 ClVwClip.c
6869f8 618 ClVwClip.h
464a79 619 Clipbrd.c
b62f9f 620 Clipbrd.h
657922 621 DDElog.c
7749c7 622 PGPsc.rc
3e6f76 623 PGPscVer.rc
45d478 624 Precomp.h
803d26 625 ProgVal.c
8f5e60 626 ProgVal.h
ddc0b1 627 SaveOpen.c
2027a1 628 Tempest.c
7ae2c4 629 Utils.c
c40e19 630 WFfat.c
5dc696 631 WFfat.h
f8fd88 632 WFnt.c
fe54dd 633 WFnt.h
b10c7c 634 WFwiz.c
96c4f3 635 WFwiz.h
3838f4 636 decrypt.c
13384b 637 encrypt.c
87605b 638 events.c
32d162 639 events.h
b72bf8 640 main.c
e1f8cb 641 pgpsc.def
3401ff 642 recpass.c
276002 643 recpass.h
e0bb09 644 resource.h
91a027 645 saveopen.h
--d834 000954a7e2140110002 Page 11 of MANIFEST
6ad710 646 wipe.c
49b8fa 647 working.c
8fd426 648 working.h
9abb5c D clients/pgp/win32/PGPcl/
4cc735 649 CLabout.c
bbc8fa 650 CLcache.c
96af7e 651 CLerror.c
bcaf8f 652 CLexpire.c
6856c1 653 CLgroups.c
c3001c 654 CLkspref.c
5e79c5 655 CLmisc.c
4d2c68 656 CLnag.rc
2e77c5 657 CLphrase.c
4bff60 658 CLprefs.c
04796c 659 CLquery.c
71e79f 660 CLrand.c
93505b 661 CLrecip.c
3b81ce 662 CLrecon.c
dc5c14 663 CLsdksrv.c
a3dec8 664 CLselect.c
ad6322 665 CLsend.c
7fd8b5 666 CLserver.c
73ec5f 667 CLsplash.c
63f724 668 CLsplash.rc
8368b5 669 CLsrvprf.c
708db7 670 CLwarn.c
b0d7b8 671 KMAddUsr.c
c26e51 672 KMChange.c
e23a95 673 KMColumn.c
a1d8a3 674 KMConvrt.c
5d80e8 675 KMFocus.c
07abe2 676 KMIDataObject.cpp
c26dbe 677 KMIDataObject.h
de80b0 678 KMIDropSource.cpp
6ee7be 679 KMIDropSource.h
4467a3 680 KMIDropTarget.cpp
caee73 681 KMIDropTarget.h
e3caac 682 KMIEnumFormatEtc.cpp
0e35cf 683 KMIEnumFormatEtc.h
0c7085 684 KMKeyIO.c
b9ca28 685 KMKeyOps.c
6ce1b4 686 KMMenu.c
9cc5de 687 KMMisc.c
7524cd 688 KMNotPrc.c
ad55ad 689 KMPhoto.c
a9faa2 690 KMProps.c
9f88d6 691 KMRevoke.c
108946 692 KMShare.c
d241f9 693 KMTree.c
60ee61 694 KMUser.c
99d92b 695 KMserver.c
b31d43 696 PGPcl.c
28a44b 697 PGPcl.def
d6fb01 698 PGPcl.rc
e3baeb 699 PGPclVer.rc
4a91db 700 PGPclx.h
71f343 701 PGPkm.c
6310e5 702 PGPkmx.h
e518d9 703 resource.h
27f74c D clients/pgp/win32/PGPhk/
cd6dde 704 hook.c
3977f0 705 pgphk.def
7a2531 706 PGPhk.rc
71f96e 707 PGPhkVer.rc
013b46 708 resource.h
cee506 D clients/pgp/win32/PGPlog/
1ba273 709 ListMng.c
5ecccf 710 ListMng.h
8699f1 711 OwnDraw.c
65fab7 712 OwnDraw.h
61467a 713 PGPlgVer.rc
9548d9 714 PGPlog.rc
--63f5 0008f476cbc40110002 Page 12 of MANIFEST
d72130 715 Precomp.h
3746cd 716 main.c
1d7087 717 resource.h
6e227e D clients/pgp/win32/PGPtray/
ced7e8 718 EnclyptorProc.c
53cba7 719 EnclyptorProc.h
84f538 720 Main.c
a7f63b 721 PGPTrayVer.rc
47e5ae 722 PGPtray.rc
0b280a 723 Precomp.h
02d8aa 724 RESOURCE.H
2cb1dc 725 Taskbar.c
b6d29a 726 Taskbar.h
308cd8 D clients/pgp/win32/PGPkeys/
093d9d 727 Choice.c
c7c579 728 Choice.h
5cec71 729 ChoiceProc.c
819f91 730 ChoiceProc.h
58ff8d 731 GMIDropTarget.cpp
bc4f7d 732 GMIDropTarget.h
0d22f0 733 GMMenu.c
4ef3ed 734 GMMisc.c
8aea84 735 GMNewGrp.c
24d2c3 736 GMNotPrc.c
7a2a75 737 GMOps.c
784e35 738 GMTree.c
c0e4e6 739 PGPgmx.h
c41d81 740 PGPkeys.c
44526f 741 PGPkeys.rc
3700fc 742 PGPkeysx.h
26abaf 743 PKMenu.c
de7ab2 744 PKMisc.c
9e3e78 745 PKMsgPrc.c
0b4c13 746 PKTool.c
77d458 747 PKUser.c
c2dace 748 PKVer.rc
6a4182 749 PKgenwiz.c
043891 750 Search.c
5989a8 751 Search.h
d61461 752 SearchCommon.c
c2e0c6 753 SearchCommon.h
d8fbc1 754 SearchFilter.c
300f66 755 SearchFilter.h
77138a 756 SearchProc.c
8fbf08 757 SearchProc.h
98b615 758 resource.h
0af56b D clients/pgp/win32/PGPtools/
3f5b46 759 PGPtlVer.rc
f12125 760 PGPtools.rc
963c05 761 Precomp.h
b0bddd 762 main.c
f4b824 763 openfile.c
a944cf 764 openfile.h
9d3163 765 proc.c
4403cc 766 proc.h
fa0000 767 resource.h
58206f D clients/pgp/win32/TreeList/
7a391d 768 TLMisc.c
9188c3 769 TLMouse.c
3a34ff 770 TLMsgPrc.c
f5846c 771 TLPaint.c
65f4e7 772 TLTree.c
52b2a6 773 TLintern.h
057b0b 774 TreeList.c
1d6958 D clients/pgp/win32/pgpExch/
4ea644 775 Attachments.cpp
111576 776 Commands.cpp
3b8d72 777 Exchange.h
243c30 778 GUIDS.CPP
0a370d 779 GUIDS.H
617c2b 780 Main.cpp
8f6055 781 MessageEvents.cpp
--b179 001d6039ddf40110002 Page 13 of MANIFEST
211be2 782 MsgProps.cpp
f30450 783 PropertySheets.cpp
b7c0ac 784 Recipients.cpp
9475fb 785 Recipients.h
e9c6f3 786 STDINC.H
5bb969 787 STDNOTE.CPP
218aa0 788 UIutils.cpp
b3246e 789 UIutils.h
2260ad 790 outlook.h
50a399 791 pgpExch.DEF
e122cf 792 pgpExch.RC
f960f5 793 pgpExch.reg
6c8f01 794 pgpExchVer.rc
fa69bf 795 readme.txt
639a49 796 resource.h
2f8698 D clients/pgp/win32/shared/
6a84be 797 AddKey.c
727c5a 798 AddKey.h
ae3867 799 BlockUtils.c
c7eb16 800 BlockUtils.h
e9603f 801 DecryptVerify.c
3f85af 802 DecryptVerify.h
94d916 803 EncryptSign.c
818ffd 804 EncryptSign.h
6c2f82 805 Prefs.c
30bf43 806 Prefs.h
d8465c 807 RichEdit_IO.c
544073 808 RichEdit_IO.h
4d5af1 809 SharedStrings.h
9bfbb7 810 SharedStrings.rc
8b43e9 811 SigEvent.c
1da9b6 812 SigEvent.h
91f911 813 VerificationBlock.c
8a5b19 814 VerificationBlock.h
1ee4e3 815 Working.c
1a87a5 816 Working.h
e81c75 817 Working.rc
a33500 818 WorkingResource.h
05bd2b D·
7759b1 819 binaries1.zip
d6bb09 820 binaries2.zip
--d064 000555cac7e40110003 Page 1 of winhashes.asc
2a0fa4 -----BEGIN PGP SIGNED MESSAGE-----
851b04 Hash: SHA1
6caf5a
f21d8f c8ad6a0abedc563f2b765e07afae349c0c0e43ea ·MANIFEST
a29ead 3634c85efbb4934207ef92640fe47a0b719e9147 ·clients/disk/win32/Encryption/Cast5.c¶
15df46 pp
68944e fc7e8f974d198199384c199b228547ade087b21c ·clients/disk/win32/Encryption/Cast5.h
651b07 49a770fe365566673aa1e7a0de9a7e95c1dd0d40 ·clients/disk/win32/Encryption/Cast5Bo¶
ab861f x.cpp
3da28e cb091770ea95ad75492aac365f3e9b01c1fecfeb ·clients/disk/win32/Encryption/Cast5Bo¶
79a872 x.h
6424ce 6c55fbea3f51b572083738249b5749fe15a8fffe ·clients/disk/win32/Encryption/CipherC¶
e1a2f6 ontext.cpp
8e46ff 4fa2e188e31b7dd4f05acb7b3335990b41c57bb4 ·clients/disk/win32/Encryption/CipherC¶
d0f9e7 ontext.h
311ac2 f89d32ab56b29663412d0b2344becdea19ce0bd3 ·clients/disk/win32/Encryption/CipherU¶
d3100c tils.cpp
e05ad9 4311e5209aba25d4a28338162e375ba212334f0b ·clients/disk/win32/Encryption/CipherU¶
bf621c tils.h
88f622 55bfc73add16c203af0639e6213f55434aca0d84 ·clients/disk/win32/Encryption/PGPdisk¶
838740 RandomPool.cpp
556802 b4447c6e4f92cec91c461966cb3680cddf6a9a1e ·clients/disk/win32/Encryption/PGPdisk¶
e91477 RandomPool.h
998e97 f79fdf315871dbd278527153de51a50df12cbfe3 ·clients/disk/win32/Encryption/SHA.cpp
699b83 3ebce22a46e5734003c277da4ce844163e80df2c ·clients/disk/win32/Encryption/SHA.h
d9f2d3 3d3b6ced466551824ebeeb515d5c959b86d6faee ·clients/disk/win32/PGPdisk.dsw
f1b042 a9b79f851e83208c8325a373477e431fc925bfbf ·clients/disk/win32/PGPdiskApp.dsp
fce772 394a80a8b4fef6a600f0e9d1742242acb0ae1ec0 ·clients/disk/win32/PGPdiskApp.dsw
b1a1d7 babaeff766b03651bf3a6a7114bcac47fef62938 ·clients/disk/win32/PGPdiskApp/PGPdisk¶
cf7c37 App.rc
bae719 1ea2fd7d6832b1eb5521d122926ac948a16f77c7 ·clients/disk/win32/PGPdiskApp/PGPdisk¶
0455b2 AppVer.rc
cd65a9 8a445d081b43e0e37d222fef9e2266975b84aac5 ·clients/disk/win32/PGPdiskApp/Res/Cre¶
938e56 dits1.bmp
235a0e 5318edf52f2accda19a0b0b1d159913d5278d0a1 ·clients/disk/win32/PGPdiskApp/Res/Cre¶
1f9ad1 dits4.bmp
05e463 d2ec59739460c79bb764cc65a3e6710f8432fe75 ·clients/disk/win32/PGPdiskApp/Res/Cre¶
caab25 dits8.bmp
f32119 727b91d81ab468b0457400ec9e38072d992e1c0e ·clients/disk/win32/PGPdiskApp/Res/PGP¶
d7ce08 diskApp.rc2
3f9728 fe1d7e4659250753f2968d75f0a79ee33858b374 ·clients/disk/win32/PGPdiskApp/Res/Sid¶
ad5870 ebar1.bmp
931097 ba186ef59589892b4445e1610d820afcf63258d5 ·clients/disk/win32/PGPdiskApp/Res/Sid¶
284cf7 ebar4.bmp
71297e d2caf12949d5319a6c9c2c8d8c74f9a1cd3bcece ·clients/disk/win32/PGPdiskApp/Res/Sid¶
207d03 ebar8.bmp
7bf62b fc1ea0f1ec2e279ae7f0afb23d21429e253e818e ·clients/disk/win32/PGPdiskApp/Res/Spl¶
227733 ashScreen1.bmp
a44f97 6cc591e14f8cdee76d1beed839b431a922f0ab75 ·clients/disk/win32/PGPdiskApp/Res/Spl¶
4463b4 ashScreen4.bmp
00aaae 2dd6fe4804faa1157744c5fc2be9efd48ba307a0 ·clients/disk/win32/PGPdiskApp/Res/Spl¶
c95240 ashScreen8.bmp
024a29 f214ecea429091a1e42e81455fb90c29aa1b65a0 ·clients/disk/win32/PGPdiskApp/Res/ico¶
993602 nCapsLock.ico
5b685e 91c5103e89e4eaad964602e77291bc2f13ca7b59 ·clients/disk/win32/PGPdiskApp/Res/ico¶
3b5cd5 nMain.ico
7cab27 8f8ea8a969d1036a109b65f323faa79ea652bbd1 ·clients/disk/win32/PGPdiskApp/Res/ico¶
466f98 nMount.ico
0f530d c276ca2c6e52389678c2d1ecf36f6cbc6785ce6c ·clients/disk/win32/PGPdiskApp/Res/ico¶
aad0c5 nNew.ico
e7f50b e23124d2ae10e34e0a0a6f6c2601bfe110a0e002 ·clients/disk/win32/PGPdiskApp/Res/ico¶
84ca4e nPGPdisk.ico
2dc486 eebe525cca51fae0a91f820eb99ef843848e0535 ·clients/disk/win32/PGPdiskApp/Res/ico¶
fb235b nPrefs.ico
9198d6 8a4edeca3b68355832a398c8b8b1065878daeaa3 ·clients/disk/win32/PGPdiskApp/Res/ico¶
ebe7c1 nUnmount.ico
e77cf1 1cdfda19d4b815aa35a9ba39d040c73e97ebd2d1 ·clients/disk/win32/PGPdiskApp/Source/¶
6a1bc4 CAboutBoxDialog.cpp
ca8cff 0a86745a0e68393f298ee894f0d9c32801caa109 ·clients/disk/win32/PGPdiskApp/Source/¶
0a70c8 CAboutBoxDialog.h
ae2558 1cd5a25221ebea6d63065f83d1e949cc7f91635e ·clients/disk/win32/PGPdiskApp/Source/¶
552356 CConfirmPassphraseDialog.cpp
--4028 0008521a0de40110003 Page 2 of winhashes.asc
4d780e a17c1b3771dd82ee27e3e526e11370d77a7f4323 ·clients/disk/win32/PGPdiskApp/Source/¶
6b0423 CConfirmPassphraseDialog.h
ba824b 274da2cec5c3806546e52cee2c57e93e2b482055 ·clients/disk/win32/PGPdiskApp/Source/¶
64579c CConvertPGPdiskThread.cpp
bf19cf 195b28bcfa784d2030af092a2b67991011114d16 ·clients/disk/win32/PGPdiskApp/Source/¶
f5b435 CConvertPGPdiskThread.h
1faffa 16f236ed6faa509bebf3a298a18465ad558b3012 ·clients/disk/win32/PGPdiskApp/Source/¶
5eb7da CConvertWizConvertPage.cpp
fc117e f2f1c32cf2d833160b968b8d72aaee584f3ed357 ·clients/disk/win32/PGPdiskApp/Source/¶
c8bc76 CConvertWizConvertPage.h
c00e0d ce98bdcc88935a8eee6e71cf5fbeedbc683fab13 ·clients/disk/win32/PGPdiskApp/Source/¶
50025f CConvertWizDonePage.cpp
09047f f01039bc657e25eb54a1e78d76ed8fd27c13871b ·clients/disk/win32/PGPdiskApp/Source/¶
227c98 CConvertWizDonePage.h
a11191 d06139797e06130cb3ec112a628db744ef8a4094 ·clients/disk/win32/PGPdiskApp/Source/¶
5d6b80 CConvertWizIntroPage.cpp
da05f8 247e1aeead2c77e2b7f329f273fbd16115c2cde0 ·clients/disk/win32/PGPdiskApp/Source/¶
42d6c5 CConvertWizIntroPage.h
4e13f1 8d554ef42961d3bea977d45e88d07ef6593cf700 ·clients/disk/win32/PGPdiskApp/Source/¶
e05e72 CConvertWizRandomDataPage.cpp
57a234 d576064af3d416c126c7552a6ff70a17dbdb87e5 ·clients/disk/win32/PGPdiskApp/Source/¶
f43fa6 CConvertWizRandomDataPage.h
7789e7 b747fd73ac74ad108ea142252bb8ab739de31249 ·clients/disk/win32/PGPdiskApp/Source/¶
84aad5 CConvertWizardSheet.cpp
88fe7a af7fe904dfe4936db2c1bc374faae529f6a1e0ca ·clients/disk/win32/PGPdiskApp/Source/¶
347787 CConvertWizardSheet.h
21a72a 8eaa05686658b6acdaaa34a8d90187e70d8e0b5c ·clients/disk/win32/PGPdiskApp/Source/¶
aa02ef CCreatePGPdiskThread.cpp
16d55a 0ee055459d51d50d1a694b32fa43db5c0738fb77 ·clients/disk/win32/PGPdiskApp/Source/¶
b2df7d CCreatePGPdiskThread.h
6a49c6 e444af4c04fe93a3e1cc66992d6e858e5d97f174 ·clients/disk/win32/PGPdiskApp/Source/¶
2757d7 CDiskWizADKPage.cpp
84d26f fca6eebae7d572574077bb7f2b9061fd6df7c66c ·clients/disk/win32/PGPdiskApp/Source/¶
c5f8ec CDiskWizADKPage.h
2065a0 ef196b73198a527d43b1b4fea6a29804734a31be ·clients/disk/win32/PGPdiskApp/Source/¶
43be05 CDiskWizCreationPage.cpp
36a649 d4e07f544ae8a7166c3baa165d8bf6bb6bb6fd52 ·clients/disk/win32/PGPdiskApp/Source/¶
26b4d5 CDiskWizCreationPage.h
903ff7 afb2fb2260ac6f5e4eb12088c429f2c16ffd5709 ·clients/disk/win32/PGPdiskApp/Source/¶
f4a5a6 CDiskWizDonePage.cpp
80d2fc 5f56956ac9b4219797ddef7bc75ba8bfc7cf0c5a ·clients/disk/win32/PGPdiskApp/Source/¶
62d03c CDiskWizDonePage.h
30739b 081ff41e0eb9e04ceb174836e11cd7f1608e5023 ·clients/disk/win32/PGPdiskApp/Source/¶
3d0169 CDiskWizIntroPage.cpp
bc57db b0fec5491b59fb5dda67e48e9dca31c5c79dfc70 ·clients/disk/win32/PGPdiskApp/Source/¶
ad3547 CDiskWizIntroPage.h
854db4 147c36e2c28e777b87fe4b2d1b5d5b647263c8e0 ·clients/disk/win32/PGPdiskApp/Source/¶
26e8be CDiskWizPassphrasePage.cpp
16b264 fe9e3ecd1172e0e399fe0424eb4cfedb8f41d0fd ·clients/disk/win32/PGPdiskApp/Source/¶
52512b CDiskWizPassphrasePage.h
ca28cc a52be76170dbab279313473b1828ce499832beb4 ·clients/disk/win32/PGPdiskApp/Source/¶
0e61ba CDiskWizRandomDataPage.cpp
ef2e7d afd976f21e96b53d19b61386aaa7e0b8523ff86a ·clients/disk/win32/PGPdiskApp/Source/¶
c2323c CDiskWizRandomDataPage.h
d8de61 c8e42ac4d66c160ff899455743393045bba26e57 ·clients/disk/win32/PGPdiskApp/Source/¶
6f5cab CDiskWizVolumeInfoPage.cpp
549381 61aa0e2fa15aa31c3834e371c810cde5b9816904 ·clients/disk/win32/PGPdiskApp/Source/¶
df6999 CDiskWizVolumeInfoPage.h
5b533a ea3831591c5cb62e1d60b65441479d90427dd145 ·clients/disk/win32/PGPdiskApp/Source/¶
9d0d2c CDiskWizardSheet.cpp
5da850 197da3cf4d9ca6f04199c6b4a8cbc7f637b78d8c ·clients/disk/win32/PGPdiskApp/Source/¶
f0db23 CDiskWizardSheet.h
f862ab 3a4dc49dfb429b262f868b184699b8c83d855311 ·clients/disk/win32/PGPdiskApp/Source/¶
9dfe85 CDriveLetterCombo.cpp
c235bf f2697a5e545137e5b7e40249b2c1305e71839ec0 ·clients/disk/win32/PGPdiskApp/Source/¶
925f45 CDriveLetterCombo.h
0d0680 fa8c3f02ac0588a9e67dfb8a0a2c6202588be1eb ·clients/disk/win32/PGPdiskApp/Source/¶
936969 CGetUserInfoDialog.cpp
e2b29d b950c1312ebfe6303e23778da8154b3d21ede630 ·clients/disk/win32/PGPdiskApp/Source/¶
7c0bdb CGetUserInfoDialog.h
e468c9 656e1dee13bc5e42466fecc0bdd5f3148a88639b ·clients/disk/win32/PGPdiskApp/Source/¶
8524d9 CGlobalCSearchPGPdiskThread.cpp
--d607 000fb9a4ff640110003 Page 3 of winhashes.asc
1de9ee 3b617ceadc54807820b1c981b25b6325f21024b5 ·clients/disk/win32/PGPdiskApp/Source/¶
08e8b1 CGlobalCSearchPGPdiskThread.h
93b98e 4586f4908fddc41312fe142498cff420befd2444 ·clients/disk/win32/PGPdiskApp/Source/¶
b336ad CGlobalCWizDonePage.cpp
6dd923 375521e3107d599d4ce8cb23399662d45178ab68 ·clients/disk/win32/PGPdiskApp/Source/¶
98c473 CGlobalCWizDonePage.h
10c14f baf5c80e2feb0c2d1167bd074b3d48c050a3ed1d ·clients/disk/win32/PGPdiskApp/Source/¶
02bf29 CGlobalCWizIntroPage.cpp
436528 cfc9d3da97ff8b1d0361e9cb9c1bf184aa9dc12e ·clients/disk/win32/PGPdiskApp/Source/¶
478fa0 CGlobalCWizIntroPage.h
84e5ff 053563b23b60a2fb288285fdbfb4bb93f50c221a ·clients/disk/win32/PGPdiskApp/Source/¶
6cb661 CGlobalCWizSearchPage.cpp
b28226 4b63709ecf049dc2f36a520b152b8005247bddf0 ·clients/disk/win32/PGPdiskApp/Source/¶
2816a0 CGlobalCWizSearchPage.h
d837fb dcffb66cb05f04c10189ca44afda4dfee13f12b7 ·clients/disk/win32/PGPdiskApp/Source/¶
929e27 CGlobalCWizardSheet.cpp
11d97e eaef4f702437ac94b8a4571dd799332a3ccbff38 ·clients/disk/win32/PGPdiskApp/Source/¶
22cf6c CGlobalCWizardSheet.h
6d597a 89390f66a9e6d070dce25d6908a15d58253860a6 ·clients/disk/win32/PGPdiskApp/Source/¶
c06a8c CMainDialog.cpp
fe10a1 5cb10d2eb2e7b56ab2d0f180fa9d73d7c95a5ad5 ·clients/disk/win32/PGPdiskApp/Source/¶
59e781 CMainDialog.h
f283b9 6f12e11279dbc269b843ab328d12729a3285f84c ·clients/disk/win32/PGPdiskApp/Source/¶
9d6967 CNagBuyDialog.cpp
89d285 608e8360dc7821df1115e6791b2c8cfc5ebdcc73 ·clients/disk/win32/PGPdiskApp/Source/¶
227b35 CNagBuyDialog.h
7573a5 f4c713da9bee4827d04f38d8bb745eb22fbbb300 ·clients/disk/win32/PGPdiskApp/Source/¶
9b8416 COpenPGPdiskDialog.cpp
894b06 2f7a02f038ea7ed03f11c5f5e0bd8317716acf44 ·clients/disk/win32/PGPdiskApp/Source/¶
f343fb COpenPGPdiskDialog.h
823d20 84e6fdc0243c750bff20b90fe01d26d5346cdb84 ·clients/disk/win32/PGPdiskApp/Source/¶
7a3129 CPGPdiskApp.cpp
6f73cd 05635407e631c3f8194d541209644b110cd06f96 ·clients/disk/win32/PGPdiskApp/Source/¶
04705a CPGPdiskApp.h
076fff a42c3fb1bcc13b430903f311f6a37182cef92f85 ·clients/disk/win32/PGPdiskApp/Source/¶
8d78d7 CPGPdiskAppACI.cpp
ad120f 8596d8cf854c5cf34d458bf385164e5b9776674e ·clients/disk/win32/PGPdiskApp/Source/¶
60b98d CPGPdiskAppACI.h
55c111 4c34fa4fc9e78f6822b72e91abc3c175ea1f4ef8 ·clients/disk/win32/PGPdiskApp/Source/¶
a9f74b CPGPdiskAppPassphrase.cpp
75ede8 aa476cf5b55da8dd44e9ad0dda1dc4ab9188da91 ·clients/disk/win32/PGPdiskApp/Source/¶
1edee7 CPGPdiskAppPassphrase.h
484e9e 88e7754aa39e634341ed870b43b56ef0ba576d38 ·clients/disk/win32/PGPdiskApp/Source/¶
b2433e CPGPdiskAppRegistry.cpp
3969b9 af2f67fb4b873d5251ddac4652c8523dfe3d5e38 ·clients/disk/win32/PGPdiskApp/Source/¶
19f806 CPGPdiskAppRegistry.h
bd493e d78c48e76a32eb254d6ac42c87b4022a8d921b6d ·clients/disk/win32/PGPdiskApp/Source/¶
18a9b6 CPGPdiskAppVolumes.cpp
a67602 da4f212dc00a14f9c5bb84077bc31e50391d1287 ·clients/disk/win32/PGPdiskApp/Source/¶
9d837f CPGPdiskAppVolumes.h
9686ad 1232bf601ee50dc656b2ed526c1248badf45599c ·clients/disk/win32/PGPdiskApp/Source/¶
c7afc0 CPGPdiskAppWinutils.cpp
21ce48 df4894ae0ef7f9a9123642bc6af8be593a0d7e07 ·clients/disk/win32/PGPdiskApp/Source/¶
d9c17b CPGPdiskAppWinutils.h
ce9af2 2dda09fed5429430a0ba0199ce2f86b1df20cf04 ·clients/disk/win32/PGPdiskApp/Source/¶
b1eb5e CPGPdiskCmdLine.cpp
72d91b 502f0fd184ec9662eaeec50a38aba27506060545 ·clients/disk/win32/PGPdiskApp/Source/¶
0a9524 CPGPdiskCmdLine.h
af55d0 aa61be5dea19909e9961510f2c504139f5ba870b ·clients/disk/win32/PGPdiskApp/Source/¶
f5b7be CPreferencesSheet.cpp
4a4890 f08fd868b6b584392ca7a2966f44ef8b554c20d9 ·clients/disk/win32/PGPdiskApp/Source/¶
708261 CPreferencesSheet.h
2093cc 222d9cf569dd982ba74a6c93c092156fcaeed727 ·clients/disk/win32/PGPdiskApp/Source/¶
d40f79 CPrefsAutoUnmountPage.cpp
884e66 fa9359a32d65a52f582fde58bc1116ad23c52e24 ·clients/disk/win32/PGPdiskApp/Source/¶
d7c514 CPrefsAutoUnmountPage.h
3239a8 e7b848527e76fac5790393fbd014c09888d868b0 ·clients/disk/win32/PGPdiskApp/Source/¶
f69e71 CPrefsUnmountHotKeyPage.cpp
6231d6 df0302d9946f84f3baecdcb54ae14bbbfd32dcce ·clients/disk/win32/PGPdiskApp/Source/¶
b96a78 CPrefsUnmountHotKeyPage.h
66562b 89765867371475fae384ec6622f041dd0a787c23 ·clients/disk/win32/PGPdiskApp/Source/¶
fb5514 CPublicKeyDialog.cpp
--287f 000dcbf55b540110003 Page 4 of winhashes.asc
22f032 ded3ff3438149f7eda1580df11be7903788592e2 ·clients/disk/win32/PGPdiskApp/Source/¶
db7f69 CPublicKeyDialog.h
cef52e a9c6199c650ea389d09c14bce0fbc3c9717ea970 ·clients/disk/win32/PGPdiskApp/Source/¶
b73c88 CSavePGPdiskDialog.cpp
e26917 a85e5b88bd5de49ec1adc510e9c538cb35aac9f8 ·clients/disk/win32/PGPdiskApp/Source/¶
f3d965 CSavePGPdiskDialog.h
e9e051 25ca497f42cc32328f4032b3ed34683e092d5080 ·clients/disk/win32/PGPdiskApp/Source/¶
3520cb CSecureEdit.cpp
e7c62c b78426f14a4dcfa70424607118c981511f8a6acb ·clients/disk/win32/PGPdiskApp/Source/¶
0937b2 CSecureEdit.h
2fb865 1d576ec0032c4a86a35ef339d0cbc8cfa4748cba ·clients/disk/win32/PGPdiskApp/Source/¶
99f55a CSinglePassphraseDialog.cpp
0f470a c425339bfabfe7f5a224b6dc6658ce43c3067da8 ·clients/disk/win32/PGPdiskApp/Source/¶
5af4f6 CSinglePassphraseDialog.h
1cfebd f92a3df60eaa5496e5c71c51195138c12d6a388b ·clients/disk/win32/PGPdiskApp/Source/¶
0bce51 CSplashScreenDialog.cpp
a909c9 419c4b05582174f790206bf0e8290b49b04aeca5 ·clients/disk/win32/PGPdiskApp/Source/¶
6893c8 CSplashScreenDialog.h
e5383c 571dfa9d161394d47cc283e426a862bc660445d8 ·clients/disk/win32/PGPdiskApp/Source/¶
be9245 CSuperHotKeyControl.cpp
e4d4e5 47eb29d721bdc36dcbc09032f596ca24923e85f7 ·clients/disk/win32/PGPdiskApp/Source/¶
7f134e CSuperHotKeyControl.h
1cde90 ce31805436dcac1287be1e2eec9c9592471bed9e ·clients/disk/win32/PGPdiskApp/Source/¶
c8c0ff CUnmountPGPdiskDialog.cpp
e03183 8a8553595f220ce8ac4de71e6b1712e652d7f4ef ·clients/disk/win32/PGPdiskApp/Source/¶
8eb090 CUnmountPGPdiskDialog.h
a05964 813d690294268de430950529f85f0c7b3e9a3337 ·clients/disk/win32/PGPdiskApp/Source/¶
5ad911 File.cpp
cb9555 ddc524e5ea4a932baab46f988830b6fd102e942e ·clients/disk/win32/PGPdiskApp/Source/¶
8a0bd6 File.h
6663bb 4356c1bc00036dde3715634e951ea954e288c87c ·clients/disk/win32/PGPdiskApp/Source/¶
0e0808 Globals.h
9ce5a3 52c25cde0b8ea747dfe912d7ddf44f3d37fc2ef0 ·clients/disk/win32/PGPdiskApp/Source/¶
8b8c3f PGPdisk.cpp
81323d 4761d7d0a82ab0ae3eb9afd1bae8fbfd51f743d4 ·clients/disk/win32/PGPdiskApp/Source/¶
969d31 PGPdisk.h
f3e6a8 77f7b51d4262ff693279bbd5264ab52686b54125 ·clients/disk/win32/PGPdiskApp/Source/¶
3e3f06 PGPdiskHelpIds.h
520cf3 8ba8a28b74daf8757fd89604ba948c6d45bbe8dc ·clients/disk/win32/PGPdiskApp/Source/¶
935cf6 Resource.h
f538a9 1c5b1fed4a2bee12357b31dbb49b761e4e7ed16a ·clients/disk/win32/PGPdiskApp/Source/¶
566d55 StdAfx.cpp
a83abb 9de56f08d3c0860c4968796d3b3e8b3c182ac0f8 ·clients/disk/win32/PGPdiskApp/Source/¶
beae07 StdAfx.h
fbdddc 4e813964e69b2b341b942e9ef87be2795b23df1c ·clients/disk/win32/PGPdiskApp/Source/¶
858bdc VolFile.cpp
cd92b5 2f9e2c3ea350f81b7db2c44e8d1fb23af7fdfb57 ·clients/disk/win32/PGPdiskApp/Source/¶
8d0f3c VolFile.h
83ef11 d468457b49dfc891ffd1b81d262f8a349718eb95 ·clients/disk/win32/PGPdiskApp/Source/¶
cd2cf2 Volume.cpp
b4f78e d9b525d2bb439a1ef74865ed534f67c63167486a ·clients/disk/win32/PGPdiskApp/Source/¶
482659 Volume.h
f34ef4 0d63a6ecf20490d9adc98f8ef53c5a5d4bfcc155 ·clients/disk/win32/PGPdiskDrvNT.dsp
4b6e46 5413fb4388fa61200808e7c406c877941bf5c23e ·clients/disk/win32/PGPdiskDrvNT.dsw
114ded 071ff205034dce411c1d173871b0fbaa52f7eecc ·clients/disk/win32/PGPdiskDrvNT/FakeS¶
99a7a9 ource/Crtdbg.h
628e37 fceaf4cbc974c35d43dc9f0957ce141e080a88dd ·clients/disk/win32/PGPdiskDrvNT/FakeS¶
27322f ource/Limits.h
3407cc 76301ab36c38311170f8964e949a098be0d91d35 ·clients/disk/win32/PGPdiskDrvNT/PGPdi¶
eddb35 sk.rc
d94f1f 810ddb00301916bc615a63a56966eaa1541f1253 ·clients/disk/win32/PGPdiskDrvNT/RunBu¶
a83bd4 ild.bat
f356d0 c15f34cf3755f896c06146f12b4c4b5a68d814b0 ·clients/disk/win32/PGPdiskDrvNT/RunBu¶
7deb5c ildAux.bat
b80092 b4fe4583e692cc4cd9146170bb5e1958278d4dcd ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
7e3719 e/CPGPdiskDriver.cpp
4bda64 480e41e82171b913c117333a476f9d475921cf8f ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
c9165a e/CPGPdiskDriver.h
489831 1ed201d44812407192bdf323b137be45949b3d7a ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
130e45 e/CPGPdiskInterface.cpp
66c9f7 a14e468a0ef1dec847228937b0330a08cc995dbe ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
dc7f71 e/CPGPdiskInterface.h
--c42b 0007653f6d340110003 Page 5 of winhashes.asc
4dff19 484fee3cc0db534ed1d64167f4a99771cc3f3f49 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
a58d16 e/CPGPdiskInterfaceComm.cpp
2bb180 ce0a902ba3ee1f392c17ae80e39940c7017a35cd ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
cd8e11 e/CPGPdiskInterfaceComm.h
8b92c2 9145e4bfbe01e32191f4422b3e979b2857a48ec4 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
e2f1a7 e/CPGPdiskInterfaceErrors.cpp
d99be5 bdeb5e18fa8d84ebcc2d51bf7de22fa32bc16c06 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
40659d e/CPGPdiskInterfaceErrors.h
94ed77 13c26d4d705caae055f1bfa384848c15a3681c7c ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
e4b7b2 e/CPGPdiskInterfaceHooks.cpp
14da9c 9f96f47edea48d7ec20205ff3f72391d66454b7f ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
fae2ad e/CPGPdiskInterfaceHooks.h
7ee087 5933a7c0e01b8c5ed46fe01439424f6781d85ad8 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
a046f0 e/CPGPdiskInterfaceVolumes.cpp
e0cb8b 57dc1fd1a80fa8bcc1f9a226a41a1a3806534d6a ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
54abf7 e/CPGPdiskInterfaceVolumes.h
6b2ed3 ba1ab6aa4d717dba342e839fa11e5b73bdc1780f ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
0d129c e/CRunTimeExtras.cpp
e95614 6148cf9a59eaf9bce332f3d2aa24a407de93d4d8 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
0c68d8 e/CRunTimeExtras.h
c50a11 0128ed2c5a495319e491038f5a749dabb003688a ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
37bbc8 e/FSCTLCodes.h
955b22 d5a1027349416ee1df48aecda7616d911da08de3 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
f3fc33 e/File.cpp
f21b29 4f132b4de8a32fa97b728dfec709186533661d38 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
6a6fd6 e/File.h
eb05df 7835654659f3341856b66fdabbfbced91026effa ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
3b49d9 e/Function.h
679806 770a4c7b1efebd9bec5f9ad9b6ad1c29a66b2318 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
900a3d e/Globals.h
657b35 6671b80a535b2d3942bceb7cc0ac47a2f9a4c281 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
04cc4e e/KernelModeUtils.cpp
b7ac0d 9e9e3bbc864c09f9f80222ea0e6526dbc572a877 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
dac937 e/KernelModeUtils.h
7de9bf 8e1b14d5e49c75c0d09cd1691f89fa5ccdd41910 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
c150c6 e/LockableList.h
39f3d4 1b21e3fbce4d3a367a0666bda2fcbf9eeccd834a ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
58b83b e/LookasideList.h
8b492c 70455071d13c1ecd154f61f1cb23efdbf84c2fd2 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
646ad9 e/NtThreadSecurity.cpp
f14f90 712afd11ba384924d196921a4c07284e3be8914d ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
be5aa6 e/NtThreadSecurity.h
5e8441 38434bbe1a0f1e82c81ae2b89aaf3bec170a3d7d ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
fea13c e/OperatorNewFixups.h
ff4623 191c404c6712d4c7c7ee571e51aab32ac4e447a8 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
5c6737 e/PGPdisk.cpp
569948 4dc8c080b30872f64c6289d01e96494737a3c9a3 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
059f04 e/PGPdisk.h
e36355 cd9288efe120b031eed548e1505bf0e7ff8a65c4 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
5f5ad4 e/PGPdiskRequestQueue.cpp
7ca815 7a56e92b1e0bfc743a5f597e93b8386391c027f1 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
5d6304 e/PGPdiskRequestQueue.h
2359af ec3fc5a9da6a2f09a8e0cd0d95d1ab58648fb969 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
81caf5 e/PGPdiskWorkerThread.cpp
d5ef93 d1ded4b8c2b788a9c694ee55bfe3e56d56c55d64 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
d2df48 e/PGPdiskWorkerThread.h
9409d3 0ab0ec3df210fe67d488f4ce1ec59b76a31cf4b9 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
dc7fa8 e/UserMemoryManager.cpp
2775ef e5b2b262790a1d1a246da92d23807bccdf0d82ce ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
e1e298 e/UserMemoryManager.h
b63f1b 36ad24a26262a2afeb47d6425addc46f63e7b59e ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
2860d4 e/VolFile.cpp
0760e7 4af0cf62eddba8172fe5ecae96018cc5401050de ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
8a0d09 e/VolFile.h
c27f88 d5d8c183496ed19d68942614d3d0118228a1f729 ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
284ade e/Volume.cpp
3371fb b85292bce6b64872a95cfb0050f64650da845a5c ·clients/disk/win32/PGPdiskDrvNT/Sourc¶
3a037b e/Volume.h
86766a 24972729374028e9d3bc66ab2276426562a588b3 ·clients/disk/win32/PGPdiskDrvNT/makef¶
af74de ile
ae649e 5bac2642f08462a4113461293c84ffbd1a850feb ·clients/disk/win32/PGPdiskDrvNT/makef¶
766db4 ile.inc
--a24d 000feea064f40110003 Page 6 of winhashes.asc
90c6ad 6ee2ba3659fef5d52362d1884f48528e3e03a2df ·clients/disk/win32/PGPdiskDrvNT/msglo¶
c2aa2b g.mc
567ccb 5856bb282fdde73da194cde94ff1b18ed5055d60 ·clients/disk/win32/PGPdiskDrvNT/pgpsy¶
6d74ba m.bat
cc05d8 b831e98d51ef9c2846f2edd61f5324be2619375d ·clients/disk/win32/PGPdiskDrvNT/sourc¶
a84906 es
24badb f37e54623f6fd06ec0e5736b78f4a4292d48a76a ·clients/disk/win32/PGPdiskDrvWin95.dsp
cc29fa 71ff12485444861adbdd4208a50bf5991506209a ·clients/disk/win32/PGPdiskDrvWin95.dsw
d4e2d5 5501b64a6542667833048352f3552c7140b43a93 ·clients/disk/win32/PGPdiskDrvWin95/Fa¶
8eb100 keSource/Crtdbg.h
9c37a5 05a1eff4dc498fecfa9271090f6b4f54b3a62704 ·clients/disk/win32/PGPdiskDrvWin95/Fa¶
ed2486 keSource/Limits.h
94670e 992c3e1ec7d725356dbcf97be215a4e7738e8f0a ·clients/disk/win32/PGPdiskDrvWin95/Fa¶
49462b keSource/Stdarg.h
01a624 151c73c9dd89970fbc95b509e205235081d65546 ·clients/disk/win32/PGPdiskDrvWin95/Fa¶
65ca8b keSource/Stddef.h
5b0703 c1057dca02ed8b1c8dbede79951e0a8f771facea ·clients/disk/win32/PGPdiskDrvWin95/Fa¶
87ee0f keSource/Stdlib.h
eb4b59 b297e48fd8e83f9a8bc911640a62811233560d65 ·clients/disk/win32/PGPdiskDrvWin95/Fa¶
2b4907 keSource/String.h
6a630e 0df203d030f65dd84a180905f5c49979fff85957 ·clients/disk/win32/PGPdiskDrvWin95/Fa¶
dea633 keSource/sys/Types.h
1def93 7e04db76317e182b4ac873ce5238becfd472a537 ·clients/disk/win32/PGPdiskDrvWin95/PG¶
ee302a PdiskDrvDebug.bat
3ede5d e928eef617bb2e28cd6a164d40340de77eeae157 ·clients/disk/win32/PGPdiskDrvWin95/PG¶
ed948a PdiskDrvDebug.mak
0a12e4 17ec3f2d87ed160f9d37cbd4fc425299f5ae236b ·clients/disk/win32/PGPdiskDrvWin95/PG¶
8893db PdiskDrvDebugAux.bat
124032 8674e278799695879ce0da66103a6731f228789a ·clients/disk/win32/PGPdiskDrvWin95/PG¶
8fe9aa PdiskDrvRelease.bat
b78564 5981902a351c0146a2773754f62876c8de6da3af ·clients/disk/win32/PGPdiskDrvWin95/PG¶
be4d0a PdiskDrvRelease.mak
d54b93 66d1d14aabbb204123b6a535fd0d9f0d3e8d6cb4 ·clients/disk/win32/PGPdiskDrvWin95/PG¶
261714 PdiskDrvReleaseAux.bat
dc7366 b43df3ecc3d0d7005ed1eadf0a5cf0d8a38971cd ·clients/disk/win32/PGPdiskDrvWin95/So¶
5a6592 urce/CPGPdiskDrv.cpp
0976b0 2153b121d5e408ba9bcc033ec5570323dc7a6a57 ·clients/disk/win32/PGPdiskDrvWin95/So¶
a536b4 urce/CPGPdiskDrv.h
b37c86 0bbff310e6a7fe31d13cf72e3c7888d497b1dc61 ·clients/disk/win32/PGPdiskDrvWin95/So¶
d60ea4 urce/CPGPdiskDrvComm.cpp
8a7ef0 a7bbdf568f005ff536ad37ecfde7cf9f1d0f16d6 ·clients/disk/win32/PGPdiskDrvWin95/So¶
8441f7 urce/CPGPdiskDrvComm.h
453036 8a23977bdf436803e4a05e51dc824b524c479404 ·clients/disk/win32/PGPdiskDrvWin95/So¶
cec704 urce/CPGPdiskDrvDebug.cpp
cc5ed9 4eea6f2facf72f6472ddc2c96708b42db0f9ef81 ·clients/disk/win32/PGPdiskDrvWin95/So¶
77e305 urce/CPGPdiskDrvDebug.h
56eb81 f44e964427ceaa4b0a6e7b9ff12623161b0a92d1 ·clients/disk/win32/PGPdiskDrvWin95/So¶
814eea urce/CPGPdiskDrvErrors.cpp
dc6295 516092566ccb90dd9cdd3e0fba844e23c18fd749 ·clients/disk/win32/PGPdiskDrvWin95/So¶
3ae62f urce/CPGPdiskDrvErrors.h
b46a65 f3b0e028eb60d0710f56acfb4417e80b648f1a7a ·clients/disk/win32/PGPdiskDrvWin95/So¶
8f21a8 urce/CPGPdiskDrvHooks.cpp
fb230c e81506541a2413a321eb0b154e1fcf565e951037 ·clients/disk/win32/PGPdiskDrvWin95/So¶
1a605a urce/CPGPdiskDrvHooks.h
279e87 1feec8c0807048916c18b6a23ae6752a445f3c3f ·clients/disk/win32/PGPdiskDrvWin95/So¶
117edf urce/CPGPdiskDrvIos.cpp
fc2dbd caf5ef0f351fb11b3cdcad76e4c150a921b357c5 ·clients/disk/win32/PGPdiskDrvWin95/So¶
8d1424 urce/CPGPdiskDrvIos.h
3bacf2 8c736beaa151036670f87158c54e2de0e267150c ·clients/disk/win32/PGPdiskDrvWin95/So¶
fcdfae urce/CPGPdiskDrvVolumes.cpp
264b02 32bebe2be81f81c5b99b9e2399c3c6e0ce60e93c ·clients/disk/win32/PGPdiskDrvWin95/So¶
fe3ded urce/CPGPdiskDrvVolumes.h
0d8cc3 118deeee8b5193155271d93d984e9aa49d4d7f11 ·clients/disk/win32/PGPdiskDrvWin95/So¶
e3337f urce/CPGPdiskDrvWinutils.cpp
05beed 4be3df8c5cb9f59eae8ac99e274dc4c861b739e5 ·clients/disk/win32/PGPdiskDrvWin95/So¶
4d765e urce/CPGPdiskDrvWinutils.h
203126 6380d8ea690d00fafee8cdbfea1bd500ea5d0500 ·clients/disk/win32/PGPdiskDrvWin95/So¶
fdf50e urce/DcbManager.cpp
af875b 4b68bb0eaa3cc7cf6cabcad68f1041fef9df042a ·clients/disk/win32/PGPdiskDrvWin95/So¶
9141c0 urce/DcbManager.h
45fb5f c640b16044abb05316f996c9838a2794e17c1261 ·clients/disk/win32/PGPdiskDrvWin95/So¶
fe1c58 urce/FatParser.cpp
--6b02 000d50d05b840110003 Page 7 of winhashes.asc
32b349 f2859e627cf6993df3e4704f15f4abbf82b055af ·clients/disk/win32/PGPdiskDrvWin95/So¶
540579 urce/FatParser.h
737e8b ef7294d2e283568a64700c92e4b3422cb5edfd61 ·clients/disk/win32/PGPdiskDrvWin95/So¶
a23d22 urce/File.cpp
26f6c3 7d17606cbeba513beb65bfe2e8cd4185535555d8 ·clients/disk/win32/PGPdiskDrvWin95/So¶
6bfab2 urce/File.h
9ca33a 370caea0fbf2345ce9d030a7595c1c11009564da ·clients/disk/win32/PGPdiskDrvWin95/So¶
6add3a urce/FileSystemParser.cpp
bbc664 e3b4dccf17cdce780652c951ab1860a7ebc6cca3 ·clients/disk/win32/PGPdiskDrvWin95/So¶
f7176d urce/FileSystemParser.h
c25436 3ed65f1cf8a5b892bd070092d1cb420fa3ce857d ·clients/disk/win32/PGPdiskDrvWin95/So¶
1c0bf4 urce/Globals.h
04be0a 398efc9afe2791efec2782fed401ce9dc89f3463 ·clients/disk/win32/PGPdiskDrvWin95/So¶
5fac60 urce/IopProcessor.cpp
721ae0 22067daec1b4b9d2767be93171a368c26cdb952c ·clients/disk/win32/PGPdiskDrvWin95/So¶
7a1116 urce/IopProcessor.h
bb26d6 7aef9ac56bfaea9780def4c2e323124caf350319 ·clients/disk/win32/PGPdiskDrvWin95/So¶
4a6b0c urce/PGPdisk.cpp
f94404 466cc35106da4b6ad04c2bcba215555c2643b6b7 ·clients/disk/win32/PGPdiskDrvWin95/So¶
a69ecd urce/PGPdisk.h
f8228b d9b52ac00e5fcb972954339da6d527ecfb2a405c ·clients/disk/win32/PGPdiskDrvWin95/So¶
3fb97a urce/PGPdiskVrcSource.cpp
e832e2 2fbf078a3f28e1e1331c40dde642a35e74194d3d ·clients/disk/win32/PGPdiskDrvWin95/So¶
fb5219 urce/PlacementNew.h
9fb748 950e19a0579159990743ae790322d738a4371aa0 ·clients/disk/win32/PGPdiskDrvWin95/So¶
276cef urce/VolFile.cpp
2a576b bd25a733998c390c8cba74d3baa2137b3734636e ·clients/disk/win32/PGPdiskDrvWin95/So¶
670cc0 urce/VolFile.h
735a3c fd1ebe15094a80faec553abe724869668b5e97ec ·clients/disk/win32/PGPdiskDrvWin95/So¶
f01112 urce/Volume.cpp
830da9 3aad555510f733ae4c3607255e8c37e79c74ae7e ·clients/disk/win32/PGPdiskDrvWin95/So¶
12c26a urce/Volume.h
8d245d 60ef051fe0e6bcaf91d8f8bc2924946f86a5751c ·clients/disk/win32/PGPdiskDrvWin95/So¶
336b2c urce/Wrappers.h
1dd73a 2f0171747cd0936b474c91e36512d31aba86a939 ·clients/disk/win32/PGPdiskInstallHelp¶
694372 er.dsp
27a6a0 e962b74dedac98e958c9c87f17745ab0c5d0d5f4 ·clients/disk/win32/PGPdiskInstallHelp¶
2b0e7a er.dsw
85698b c40a0c816d82a8bfc0ec8e32917573457225c326 ·clients/disk/win32/PGPdiskInstallHelp¶
7ef1ce er/PGPdiskInstallHelper.def
a09ad9 bfb230eed2f6fd803b15836597d843402a80b0b2 ·clients/disk/win32/PGPdiskInstallHelp¶
2adf6a er/PGPdiskInstallHelper.rc
127ffa 3b781ae5566b86a1041ad97f1bf9708524c36d88 ·clients/disk/win32/PGPdiskInstallHelp¶
d9acb9 er/PGPdiskInstallHelperVer.rc
c5ba88 5b548cf8107c0cd998014d7eb6fbbe4c31d7dad8 ·clients/disk/win32/PGPdiskInstallHelp¶
176c3f er/Source/CPGPdiskInstallHelperDll.cpp
81f40d 4ca009b7fad243673d7436d29e406daab5bfcca4 ·clients/disk/win32/PGPdiskInstallHelp¶
50b176 er/Source/CPGPdiskInstallHelperDll.h
e79d76 c0b18f85578e56e264aa87f886d35ec8f1ccd234 ·clients/disk/win32/PGPdiskInstallHelp¶
adce35 er/Source/Resource.h
1c4092 e033407263f142f1d8b9d0eb9370838abb96e0ad ·clients/disk/win32/PGPdiskInstallHelp¶
17ff96 er/Source/StdAfx.cpp
affe25 00148d239f6118af1306a9570747d0977a9ce67c ·clients/disk/win32/PGPdiskInstallHelp¶
de97ee er/Source/StdAfx.h
1e0f90 4304edee251a2512575c98939f041a5bf30b5874 ·clients/disk/win32/PGPdiskResident.dsp
686c92 26e5f5cc84152cc406078db7fc04c403a7a36a14 ·clients/disk/win32/PGPdiskResident.dsw
c2d83d fd2fe2ddef7f10ed33d91f3992826d29ed26021f ·clients/disk/win32/PGPdiskResident/PG¶
13a8af PdiskResident.rc
d262a9 41a1c44cdd07402955768dfaf3e0d82b5647fdfd ·clients/disk/win32/PGPdiskResident/PG¶
af2252 PdiskResidentVer.rc
e65fff 57ae3a3d86cb03426a8e039976b02963fea4c9ea ·clients/disk/win32/PGPdiskResident/So¶
7141f8 urce/CHiddenWindow.cpp
c77ca2 b0206fcdddca6cc4c91a7c1e5c65266c85acd26f ·clients/disk/win32/PGPdiskResident/So¶
7f57d6 urce/CHiddenWindow.h
483957 ad2db561fe2bbfad6b5eca9441203f1676c9f359 ·clients/disk/win32/PGPdiskResident/So¶
743a84 urce/CPGPdiskResidentApp.cpp
ca7213 d6d268164e5eaa43d17cbeaeab50a53d78022fdf ·clients/disk/win32/PGPdiskResident/So¶
1d5488 urce/CPGPdiskResidentApp.h
96f0cf f72efd5ac252baaa42535b09f6b62265d96a9a5b ·clients/disk/win32/PGPdiskResident/So¶
c50bf4 urce/Globals.h
1ee3d5 6f5113a1602d65901bebb728c4c2e60f45afea69 ·clients/disk/win32/PGPdiskResident/So¶
d56116 urce/Resource.h
--d25f 000e3d93b3e40110003 Page 8 of winhashes.asc
d5866f 2ba841f1c62dff1619a878581e160a9f09b19f4a ·clients/disk/win32/PGPdiskResident/So¶
5950b5 urce/StdAfx.cpp
2004c0 de1c8238b007afcaa1ffa403a61f4b708e582b31 ·clients/disk/win32/PGPdiskResident/So¶
b84a34 urce/StdAfx.h
8b4657 fe9089e01d9c0212ac35a29281c146ca1fa11de2 ·clients/disk/win32/PGPdiskShellExt.dsp
e459d0 6be38ffbb61dcc3c7241f449d949c7bc1c8a356e ·clients/disk/win32/PGPdiskShellExt.dsw
1a1deb 9bec7f8f9b5199585b172eac82614e271b6fe1da ·clients/disk/win32/PGPdiskShellExt/PG¶
cbd3cd PdiskShellExt.def
3ca81d 15a199184b8ab75a61837f9bd367b859696c19b7 ·clients/disk/win32/PGPdiskShellExt/PG¶
c8c679 PdiskShellExt.rc
5f6a79 be92fdbd8286c9ac581fb33c966b86a5ed394695 ·clients/disk/win32/PGPdiskShellExt/PG¶
f784c1 PdiskShellExtVer.rc
ffb715 a204a64f758746b9278a027fc40103c97e66f1f2 ·clients/disk/win32/PGPdiskShellExt/So¶
ac7c46 urce/CPGPdiskShellExtDll.cpp
b004e2 c824400f50a4c6e22cfe19eff524ccc727c9cc45 ·clients/disk/win32/PGPdiskShellExt/So¶
2c5679 urce/CPGPdiskShellExtDll.h
23e7bf 4b8ed8e4a682874ee6f399ae39a9b3bab9d07951 ·clients/disk/win32/PGPdiskShellExt/So¶
1b55fe urce/CShellExt.cpp
6f7f6a 2b97eda19f112eb44132305de1cf1b531215f29b ·clients/disk/win32/PGPdiskShellExt/So¶
091954 urce/CShellExt.h
6fa977 df8b6ce4a8a5a5b6da4b8c72959160d3bafa0e15 ·clients/disk/win32/PGPdiskShellExt/So¶
a304bc urce/CShellExtClassFactory.cpp
0f7011 0eceb99703865f5670b6b7578fb5a49bc7d8f282 ·clients/disk/win32/PGPdiskShellExt/So¶
aabf1d urce/CShellExtClassFactory.h
de356f 727081499fca727a9deb75bcc1ea0410e9a33aca ·clients/disk/win32/PGPdiskShellExt/So¶
290bf4 urce/Globals.h
ecce52 eeb9837ab10d760030658ff544a46fb217ed8174 ·clients/disk/win32/PGPdiskShellExt/So¶
546116 urce/Resource.h
6ae6c0 a3a10de9d2b2b5b8add688517932dff82fc19f1a ·clients/disk/win32/PGPdiskShellExt/So¶
fc50b5 urce/StdAfx.cpp
9e03e3 976b65964882df8962b327fe31080176ceaa4483 ·clients/disk/win32/PGPdiskShellExt/So¶
254a34 urce/StdAfx.h
965bf3 eabf016ca4a87803063b16f0b295ae13157f9b2d ·clients/disk/win32/Shared/CommonStrin¶
9dc8a7 gs.cpp
fd79b8 914fcd033668dfd1c6919792b7e13791ab179ebf ·clients/disk/win32/Shared/CommonStrin¶
48f908 gs.h
fa5d48 fdd886586c51195b73a1e220b731a899346def01 ·clients/disk/win32/Shared/DriverComm.¶
81636f cpp
da7130 ce004d79736f1377f7a6ca0822bdf6e9b831d5ea ·clients/disk/win32/Shared/DriverComm.h
d89f6b 5e0a73ba93d59ea3ffd8ac093bb75a42719bf265 ·clients/disk/win32/Shared/DualErr.cpp
18d86a 4774bc5aba84232fdeb8a55ca5706616f05b07e0 ·clients/disk/win32/Shared/DualErr.h
eb01c2 6c65d4523f82c63905ffa1603c109868617840ea ·clients/disk/win32/Shared/Errors.cpp
c40964 93a3543aa381674cd04af4578d3945fb123caae3 ·clients/disk/win32/Shared/Errors.h
e46423 8f126081325afcd808908f58e69b969cf059bc05 ·clients/disk/win32/Shared/FatUtils.cpp
914e63 deac3b41a65915c28d90e340fc80f06cab740dc0 ·clients/disk/win32/Shared/FatUtils.h
0d510f 7c58360a24b9cc4a1a8bfc46ce156ca1cc74c6ff ·clients/disk/win32/Shared/GenericCall¶
0de2c5 back.h
5b5dab 30ef5962ad44436b0071f0edb3383da0ac973d46 ·clients/disk/win32/Shared/LinkResolut¶
291e26 ion.cpp
37ed79 e8a27e09a599414e38b1bec0aafeb3efaab69a6c ·clients/disk/win32/Shared/LinkResolut¶
4749c4 ion.h
ac8dcd a6e650263b4808b6e85d99e3331cc1578efc02d4 ·clients/disk/win32/Shared/PGPdiskCont¶
bfeabf ainer.cpp
e178ac b8d0c36d74ae64e3600b306baff3b758b28469b3 ·clients/disk/win32/Shared/PGPdiskCont¶
85fa2a ainer.h
720577 f58604c091d82e0784b74b46b564b85b0b7d4d59 ·clients/disk/win32/Shared/PGPdiskDefa¶
1f072e ults.h
2f3a06 43a4333c7200fad57a12ac9c5967b525b80f9054 ·clients/disk/win32/Shared/PGPdiskFile¶
cb21e7 Format.h
4b8f24 2b310c2c889d64688b3ea9a67c02002b661d1c6e ·clients/disk/win32/Shared/PGPdiskHigh¶
ad2628 LevelUtils.cpp
c8aabe 31319e866ac3d91b1f6087aaa2e530f48ec925f6 ·clients/disk/win32/Shared/PGPdiskHigh¶
e1f437 LevelUtils.h
e2be11 286ac17c4e5a470512f979d93af0de129c11dc10 ·clients/disk/win32/Shared/PGPdiskLowL¶
20c451 evelUtils.cpp
9bd17a ef0acacb3e028b3e6dca9ba72a17a61c1fb374d5 ·clients/disk/win32/Shared/PGPdiskLowL¶
cbacba evelUtils.h
3f0cbe 7c92916ebed18a042e562ed5f7884bc0eed8d50b ·clients/disk/win32/Shared/PGPdiskPfl.¶
90636f cpp
6c6689 27e61690334961cfa80ab88b26231f124e4d4dbd ·clients/disk/win32/Shared/PGPdiskPfl.h
33b44e 4dc43366986c712eb19fe0c2654857e0d9b2cd27 ·clients/disk/win32/Shared/PGPdiskPubl¶
e3ae8f icKeyUtils.cpp
--57a0 000a0c1c21940110003 Page 9 of winhashes.asc
c31263 b039d6a4c3df314cddedf652b603720f5592142b ·clients/disk/win32/Shared/PGPdiskPubl¶
43fc6e icKeyUtils.h
d45e5c 71cbba81849ed5fbf94a5e146db3666ccc4b527b ·clients/disk/win32/Shared/PGPdiskRegi¶
7002ad stry.cpp
68505d 9c0dc5bcf440019db508dcb4fb1987a1f5b61b1a ·clients/disk/win32/Shared/PGPdiskRegi¶
e1db3d stry.h
aa88d5 e57702b680f8e4b8a852fb9ba63b46a3d728a83e ·clients/disk/win32/Shared/PGPdiskResi¶
9559d5 dentDefines.h
3b2c11 4cda3da9fdf8dbde697405aedaf9050085c7a338 ·clients/disk/win32/Shared/PGPdiskVers¶
9749c4 ion.h
58019a c7cf08eabe80d1d976d8be3fa26e816fb7abbcb9 ·clients/disk/win32/Shared/Packets.h
37fb29 5741921ae90907310ab8420e71bb5af45e40686e ·clients/disk/win32/Shared/Required.h
320747 a56eef8b867d8e532745f1ffc64f7839cdeed996 ·clients/disk/win32/Shared/SafeObject.h
6c96fc 71a1695e80c6c792c5266c5a0e5c69caaf42a43b ·clients/disk/win32/Shared/SecureMemor¶
7e8234 y.cpp
c11e89 3e89a94e1857c4304de57cf03e697f367192f711 ·clients/disk/win32/Shared/SecureMemor¶
0cb4c9 y.h
f02135 12662ca4b39e63ae99da6b68b2adde02d9bc4f1b ·clients/disk/win32/Shared/SecureStrin¶
f5f926 g.cpp
452781 1d0adcb18ce411348d0c1d0cb6514b54b489d176 ·clients/disk/win32/Shared/SecureStrin¶
b4d92a g.h
8ab828 0a9dcb63973ed0075d908fed13da1c1d41169630 ·clients/disk/win32/Shared/SharedMemor¶
6b8234 y.cpp
0325f3 923aae9af82a35368566648118e2416fe2ef9fad ·clients/disk/win32/Shared/SharedMemor¶
92b4c9 y.h
56f5b3 d14283e6a1300294f39f046b0c29353a03a14960 ·clients/disk/win32/Shared/SimpleQueue¶
c817ef .h
e2664a 963054c2d30b535d0e6939691d8ca46f02e4e3cb ·clients/disk/win32/Shared/StringAssoc¶
8ad850 iation.cpp
1cb34e 1079ee8ba8bb7c50f682b28e1549d0f64efbcf53 ·clients/disk/win32/Shared/StringAssoc¶
97462d iation.h
af2418 dfe220fe0d44929f77189481b146876ae3308dbb ·clients/disk/win32/Shared/SystemConst¶
76d5c7 ants.h
335110 c305a0b51288f6ee3f7a42b4e3ef5edaab5333e3 ·clients/disk/win32/Shared/UtilityFunc¶
3d694f tions.h
cc49f5 f12903947a9aeeb46256269843fa098b7a44cfa5 ·clients/disk/win32/Shared/WaitObjectC¶
49d9e5 lasses.cpp
985826 a7e5d164dd731ad3423ff41a57df9c31ed49eca1 ·clients/disk/win32/Shared/WaitObjectC¶
059c15 lasses.h
38da4a 527bdb711dd9c7f127165c0f62b74560f2dfd21e ·clients/disk/win32/Shared/Win32Utils.¶
97636f cpp
6f17e2 a646ff914410e1ccaff96953b24685e6b9a73652 ·clients/disk/win32/Shared/Win32Utils.h
4ca35f ccb313fdc2f9aeb7dd1431673eb56a4d703f7420 ·clients/disk/win32/Shared/WindowsVers¶
7f1e26 ion.cpp
c8bb35 52908381906f14279773c7d65609290984a10b85 ·clients/disk/win32/Shared/WindowsVers¶
4149c4 ion.h
90380f 820f3f71a090b6c17259f18588826831917101f8 ·clients/pgp/shared/JPEG/win32/jpeglib¶
1bda03 .dsp
a92ff0 80c09286203e825afe78cdfe0bb33f40209f9b8f ·clients/pgp/shared/JPEG/win32/jpeglib¶
4c970b .dsw
3130fc bb89e75fc630d1bda1bb23e82c8a80f8d48b4fb0 ·clients/pgp/win32/EudoraPlugin.dsp
814165 e16b703cfccef5f9e9a78bd62e5a04baeb20c08c ·clients/pgp/win32/EudoraPlugin.dsw
a090bd e3a434b6a8beed6044799fcac43ed3f13b69dad1 ·clients/pgp/win32/EudoraPlugin/CBTPro¶
f34f6e c.c
75dfd3 0b9e9f62b7a2ccb402bbd8258bdc1330dd4fc554 ·clients/pgp/win32/EudoraPlugin/CBTPro¶
98abc6 c.h
522782 0eedf15b2efe2d5dd24a491b437325f227e7d773 ·clients/pgp/win32/EudoraPlugin/Create¶
47760f Toolbar.c
775478 86afa4889c9b883185ebdd8c800010186521e2a0 ·clients/pgp/win32/EudoraPlugin/Create¶
e592a7 Toolbar.h
0ebdbd 137bd065becfdb14468f29db79a99cc4953e9303 ·clients/pgp/win32/EudoraPlugin/Displa¶
b7ddd0 yMessage.c
d3b7c2 c970af32fdbf03868ec3fe958c9da0754f5f81d4 ·clients/pgp/win32/EudoraPlugin/Displa¶
2e3978 yMessage.h
f08371 5939d32f449ec13cd429036411053fc7a7b208f9 ·clients/pgp/win32/EudoraPlugin/Eudora¶
f17f03 INI.h
d08456 58a35453bad91d948e5041163118fb88163f5fa7 ·clients/pgp/win32/EudoraPlugin/Eudora¶
d312c5 MailHeaders.c
880208 d876084d2bd66fbfcb0e245adf79e91ac5542d0a ·clients/pgp/win32/EudoraPlugin/Eudora¶
92f66d MailHeaders.h
c7d2cd f216a8689526653648a87bd0a6e4e8c8515ceb81 ·clients/pgp/win32/EudoraPlugin/Eudora¶
a0140d MainWndProc.c
--1673 000ef8c41ea40110003 Page 10 of winhashes.asc
4974a9 3fff9c1df1bf273ffe111bcc7b0a662187e8cff6 ·clients/pgp/win32/EudoraPlugin/Eudora¶
e2f0a5 MainWndProc.h
a22ce6 de1ead572394022bd80470f58c1dd0f1039ed191 ·clients/pgp/win32/EudoraPlugin/Eudora¶
b4bdc4 ReadMailWndProc.c
b15084 f85e9a9640edde900635229c09c4d6fd957274a8 ·clients/pgp/win32/EudoraPlugin/Eudora¶
82596c ReadMailWndProc.h
a1b6c7 8b11b2111579bb8a338aa59473e908519206a0a9 ·clients/pgp/win32/EudoraPlugin/Eudora¶
d9a7a4 SendMailWndProc.c
7e3337 d933ec76c66468d3a33bc733e7647b4226a69023 ·clients/pgp/win32/EudoraPlugin/Eudora¶
ba430c SendMailWndProc.h
e40583 c7b14ad1431db1cf5f1c40e064b3d1d71fa50674 ·clients/pgp/win32/EudoraPlugin/MapFil¶
ce04f4 e.c
970d17 64093ee5f1a2eec06f7b7b31abffb558e42af595 ·clients/pgp/win32/EudoraPlugin/MapFil¶
fee05c e.h
73e9b6 ff35854f1faf21802d2f180af6b0fb30ed673738 ·clients/pgp/win32/EudoraPlugin/MyMIME¶
ad2f5c Utils.c
6e35cb 4ce8d0e490705276e882c13830e89c08c705d1f4 ·clients/pgp/win32/EudoraPlugin/MyMIME¶
59cbf4 Utils.h
58ab6b 7acfe14fafe6ab94fec95051a6c304dbee242bfd ·clients/pgp/win32/EudoraPlugin/PGPDef¶
591a6d inedMessages.h
f4f09a 4ffc67203c3207e8880ff7a55f4bf9939b07a5e3 ·clients/pgp/win32/EudoraPlugin/PGPPlu¶
5a3d82 g.c
59fbd7 009258d2b7fd062c55faacd58031c1db78dbfe05 ·clients/pgp/win32/EudoraPlugin/PGPPlu¶
68d92a g.h
6e66ba e9abd6db3e0ea09b15101a4a4bf210990ca284a0 ·clients/pgp/win32/EudoraPlugin/PGPPlu¶
f7aa1b gTypes.h
9f599b 71f1ee29e34f8c4405e3939a9cc1932470894069 ·clients/pgp/win32/EudoraPlugin/PGPplu¶
555cae gin.def
8060e0 9b185cc38c20dee906c91e275cb0ee62ccbb55c0 ·clients/pgp/win32/EudoraPlugin/PGPplu¶
36f542 gin.rc
6135d7 5fc48e2259fc8d6306169805916d95b2ec0d6f75 ·clients/pgp/win32/EudoraPlugin/PGPplu¶
beb703 ginVer.rc
662cee e46d40034bb531d5c88d67e7b1da577a6351ddc9 ·clients/pgp/win32/EudoraPlugin/ReadMa¶
e97178 ilToolbarWndProc.c
8d59e7 061e5a70b740e523a9b476c823a808cbfd49eeb0 ·clients/pgp/win32/EudoraPlugin/ReadMa¶
9f95d0 ilToolbarWndProc.h
cf4dd3 4368eb127701d015a5047a82ea91c3e2c22ad9fa ·clients/pgp/win32/EudoraPlugin/Res/Eu¶
daed76 dora.bmp
c38435 a88ee792220dcd5b17c73c80f58d35a2c4a48370 ·clients/pgp/win32/EudoraPlugin/Res/ad¶
d42cc6 dkey.ico
600edb 0e5e860061b0245bfdc2adf32603029acee22809 ·clients/pgp/win32/EudoraPlugin/Res/lo¶
d3643f ck.ico
fbdda3 57b8e0fcd16c56883403f798bff9c60da5a23f47 ·clients/pgp/win32/EudoraPlugin/Res/lo¶
078a6d ck1.ico
52e6c4 dcf106c94998c92b6b690618565cd07cfaf10b94 ·clients/pgp/win32/EudoraPlugin/Res/lo¶
1b8610 ck2.ico
0ef58b 171f1a53bd0b4e69d037c9cfad59faacc4fa540a ·clients/pgp/win32/EudoraPlugin/Res/lo¶
67823b ck3.ico
4af58b 171f1a53bd0b4e69d037c9cfad59faacc4fa540a ·clients/pgp/win32/EudoraPlugin/Res/lo¶
bb9eea ck4.ico
b529cd 84ba3e4afb0301e9907c87b6132a48dd419cd1b4 ·clients/pgp/win32/EudoraPlugin/Res/lo¶
4c9ac1 ck5.ico
b3ec5c 5d4bcc68e59a53d7a9b0f45660bdc0ff2a30fba5 ·clients/pgp/win32/EudoraPlugin/Res/pg¶
3bfb9b p32.ico
4d8a4b f73e0278955604a63310923cbe1a7c39e55039c5 ·clients/pgp/win32/EudoraPlugin/Res/pg¶
c2ab00 p50.ico
2a8a37 b1acc20ea3845741bf2a5addfea3df100ec6bf3b ·clients/pgp/win32/EudoraPlugin/Res/re¶
cb8bf7 adtool.bmp
7e1481 cb5e95c651800dbc003491769bcf280f36499a29 ·clients/pgp/win32/EudoraPlugin/Res/se¶
0f97bb ndtool.bmp
af2e03 f37ce66e3d245385c65197d5e7d79f7fd557f37d ·clients/pgp/win32/EudoraPlugin/Res/si¶
3f1fce gn.ico
49620c 97dad984e179435aecfb03b637ad095faf7a6824 ·clients/pgp/win32/EudoraPlugin/Res/ve¶
10d44c rify.ico
aebf60 fff21a2308a891175d47406ed40887d3a913b730 ·clients/pgp/win32/EudoraPlugin/SendMa¶
ba7178 ilToolbarWndProc.c
ee580d d490a326cb356d39009ad0d807f63075e34a0376 ·clients/pgp/win32/EudoraPlugin/SendMa¶
8b95d0 ilToolbarWndProc.h
07978a 9230ad65ce62652381a1e6068e43b1d7f03002d2 ·clients/pgp/win32/EudoraPlugin/Transl¶
b5e771 atorIDs.h
46dfc5 0f8c2fbd552c0a6d8357a2c3c0295c7ae96a5d0a ·clients/pgp/win32/EudoraPlugin/Transl¶
eff360 atorUtils.c
--29a0 000db17948f40110003 Page 11 of winhashes.asc
8cfdaa 3d9dc5295f0bb89103a39f8ae2e2af44f849f44c ·clients/pgp/win32/EudoraPlugin/Transl¶
c817c8 atorUtils.h
0a7358 a0f17c0768a6cb6ae8f6d53593f3cfda5b9124cf ·clients/pgp/win32/EudoraPlugin/Transl¶
821908 ators.c
cfd726 01f7b35055099f5a301d83340a4df6ef30eb5441 ·clients/pgp/win32/EudoraPlugin/Transl¶
03fda0 ators.h
4a9561 2745d327e52806e6f1e110ddfb7d895c94a62ffc ·clients/pgp/win32/EudoraPlugin/emssdk¶
52c661 /BUFTYPE.CPP
5ddbb8 6bcf01e0070a3eab0fdaacbc20677b53647d5a91 ·clients/pgp/win32/EudoraPlugin/emssdk¶
d4a5a9 /BUFTYPE.H
1c80e0 1fbdbdf100a3d146fd5e638972151e74ca6ba1bc ·clients/pgp/win32/EudoraPlugin/emssdk¶
185d0d /ENCODING.CPP
40548f bbcdf0a6cdc20b6da88b1b983d12252068455a5c ·clients/pgp/win32/EudoraPlugin/emssdk¶
a90ba0 /ENCODING.H
5871e1 3acb8deab0044a62aa80370735507e9012a76239 ·clients/pgp/win32/EudoraPlugin/emssdk¶
f41515 /MIMETYPE.CPP
d82162 94308970c7154f8cb44ff7ec960d84a25df0922b ·clients/pgp/win32/EudoraPlugin/emssdk¶
13950e /MIMETYPE.H
71f3d8 42b81994860bd5de804c5943f9f8831a613ffdf5 ·clients/pgp/win32/EudoraPlugin/emssdk¶
6df7ac /RFC1847.CPP
6e693c cb9bb2088c9c5ea1eedb8b2e271545109a7eb335 ·clients/pgp/win32/EudoraPlugin/emssdk¶
38f125 /RFC1847.H
ed2761 79c6afe9ecae380d73ebcd93b82ade27e55bb4dd ·clients/pgp/win32/EudoraPlugin/emssdk¶
f31e35 /RFC822.CPP
8acbb7 2240c47f8ff645cbf5729222e8b361738c99e66c ·clients/pgp/win32/EudoraPlugin/emssdk¶
cff1c5 /RFC822.H
298889 56680a7b9c281b87595c4213f68cca7db5531dbd ·clients/pgp/win32/EudoraPlugin/emssdk¶
a7c510 /ems-win.h
e349e3 a1f23398755ba3df4a1509021eb45b899ac4141b ·clients/pgp/win32/EudoraPlugin/emssdk¶
aa2b37 /file1847.cpp
cbdb78 4003b7781578cc41c8e9c62028f0589b1e6431aa ·clients/pgp/win32/EudoraPlugin/emssdk¶
198e03 /file1847.h
b43f8b a6e6bc5a609038d94c641177ff61cca7dfcf60e7 ·clients/pgp/win32/EudoraPlugin/resour¶
345c23 ce.h
356544 37fd8a45bb6b18233326fc95d071b6127ee62c48 ·clients/pgp/win32/EudoraPlugin/strstr¶
1f93c0 i.c
2dab11 817d90cd3a0eeeee1ef665965b8b6051af1c7139 ·clients/pgp/win32/EudoraPlugin/strstr¶
117768 i.h
f9bd2a 17da125b8203af96662f7edeeabdbe29c7ceff78 ·clients/pgp/win32/EudoraPlugin/transb¶
5174c5 mp.c
1842d4 5651714ab027383fff804711f2302c971877a0b7 ·clients/pgp/win32/EudoraPlugin/transb¶
2a906d mp.h
bb27cf f3ba2127efd404aa5ecd3cb87844ec36a055d7cd ·clients/pgp/win32/EudoraPluginV4.dsp
9e9875 1deeb8c9151c98746387d36d1d7efcd471599756 ·clients/pgp/win32/EudoraPluginV4.dsw
38e6c2 137bd065becfdb14468f29db79a99cc4953e9303 ·clients/pgp/win32/EudoraPluginV4/Disp¶
6ec978 layMessage.c
9aecbd c970af32fdbf03868ec3fe958c9da0754f5f81d4 ·clients/pgp/win32/EudoraPluginV4/Disp¶
892dd0 layMessage.h
beff4f 7abeea8e564ab7ee61a333ca8fae90280ff1bfc7 ·clients/pgp/win32/EudoraPluginV4/MapF¶
9970b5 ile.c
f95ed0 231d255b7c462e0f62abd4ca32348ffdec8aacc4 ·clients/pgp/win32/EudoraPluginV4/MapF¶
33941d ile.h
95e0bc 77c193e9a4251cc07bd5cf21006fe52d463dbb1f ·clients/pgp/win32/EudoraPluginV4/MyMI¶
f81fce MEUtils.c
f6faae 332c65b8ca04ff7d4d90ccd484a21e1b9a0fdb08 ·clients/pgp/win32/EudoraPluginV4/MyMI¶
c5fb66 MEUtils.h
4e57ce 4f10fe143b7654d61a0ad2cf578afe9490c519cf ·clients/pgp/win32/EudoraPluginV4/PGPp¶
0fe403 lugin.def
e879c1 ffaf889d76d24b74f2f1140139098c993874c6fc ·clients/pgp/win32/EudoraPluginV4/PGPp¶
c9bb2f lugin.rc
00d282 3ce4f7c552fe2aa2239720ba80051cd958a0f277 ·clients/pgp/win32/EudoraPluginV4/PGPp¶
b79147 luginVer.rc
08c6cf 3157d7b071f7b22d44702de11f9a026cd845a08d ·clients/pgp/win32/EudoraPluginV4/Plug¶
a29e84 inMain.c
e265d3 974355cb7e6fc25a17fa1194360811f3a5d0ab8f ·clients/pgp/win32/EudoraPluginV4/Plug¶
817a2c inMain.h
c2fb25 ae21e2a8d031e4989acb398759085c88c48db4ef ·clients/pgp/win32/EudoraPluginV4/Res/¶
30b489 Key.ico
c82a43 850c5b11a7e65c13acad069881479fe514ac1e9b ·clients/pgp/win32/EudoraPluginV4/Res/¶
861b8a addkey.ico
54c4eb ad38575b529c1f81e23980cb67da01d95d5c1b79 ·clients/pgp/win32/EudoraPluginV4/Res/¶
dbd96e encryptsign.ico
--c507 000d1c64e3740110003 Page 12 of winhashes.asc
0adf76 86fc6893dcfcced4ca12535ec107e08a89fa9473 ·clients/pgp/win32/EudoraPluginV4/Res/¶
e557f9 lock.ico
f85feb f73e0278955604a63310923cbe1a7c39e55039c5 ·clients/pgp/win32/EudoraPluginV4/Res/¶
197c24 pgp50.ico
877397 9ee84b77b4052def7c55551f471a3d17ee7d8269 ·clients/pgp/win32/EudoraPluginV4/Res/¶
c05805 sign.ico
9e9a54 57b8e0fcd16c56883403f798bff9c60da5a23f47 ·clients/pgp/win32/EudoraPluginV4/Res/¶
d67ec2 unlock.ico
34498e 97dad984e179435aecfb03b637ad095faf7a6824 ·clients/pgp/win32/EudoraPluginV4/Res/¶
731e84 verify.ico
9b3258 0fa3740d83911968d8596a48f15b5423ab345b52 ·clients/pgp/win32/EudoraPluginV4/Tran¶
4bc4e7 slatorIDs.h
93e775 5cbeb8f8230629e182092ab18d0d52cedddc9cfa ·clients/pgp/win32/EudoraPluginV4/Tran¶
bfad74 slatorUtils.c
d14d56 f5a0cdf5928ece8bd321bb48a958a1b32db94d13 ·clients/pgp/win32/EudoraPluginV4/Tran¶
0649dc slatorUtils.h
165e57 94bcdadbd4b5ba6d80131f057087f7bcd819b30f ·clients/pgp/win32/EudoraPluginV4/Tran¶
4b1388 slators.c
ded2f4 33a995b94f444e3777fcecdc19514f4957f0bdaa ·clients/pgp/win32/EudoraPluginV4/Tran¶
57f720 slators.h
615e76 2745d327e52806e6f1e110ddfb7d895c94a62ffc ·clients/pgp/win32/EudoraPluginV4/emss¶
9bb23e dk/BUFTYPE.CPP
9110af 6bcf01e0070a3eab0fdaacbc20677b53647d5a91 ·clients/pgp/win32/EudoraPluginV4/emss¶
0d943e dk/BUFTYPE.H
f1a726 a71c8df72054f0a3e118988f8a78cdf0ed326f04 ·clients/pgp/win32/EudoraPluginV4/emss¶
e9f70b dk/ENCODING.CPP
3098f6 ae8627010d5246e0281c89bc2e085a990947bf2a ·clients/pgp/win32/EudoraPluginV4/emss¶
35eba7 dk/ENCODING.H
e577f6 b9d24a095c8dbe58bf3a4e9640c6ea74f4ed3905 ·clients/pgp/win32/EudoraPluginV4/emss¶
33bf13 dk/MIMETYPE.CPP
74d6b2 2bc8c2e18e30ba08c7eb2934213f5753883f6477 ·clients/pgp/win32/EudoraPluginV4/emss¶
fdb267 dk/Mimetype.h
b14742 ea95a9f60dae3830e55af9f1a36d88b78d831ddb ·clients/pgp/win32/EudoraPluginV4/emss¶
9f83f3 dk/RFC1847.CPP
cca22b cb9bb2088c9c5ea1eedb8b2e271545109a7eb335 ·clients/pgp/win32/EudoraPluginV4/emss¶
04c0b2 dk/RFC1847.H
97af24 93473840e6b60e5dacf659c0bd5754ca0be63b1d ·clients/pgp/win32/EudoraPluginV4/emss¶
e0fe32 dk/RFC822.CPP
3b6d55 52d3685fc1ec069bd5871331fe6040a9b274e34e ·clients/pgp/win32/EudoraPluginV4/emss¶
f6e5f5 dk/RFC822.H
bcadc6 06586436211a2483a7253d8f9414b2c4287b86ba ·clients/pgp/win32/EudoraPluginV4/emss¶
94f487 dk/ems-win.h
416a04 9f43cf1f61dd22239f69cd5ccec23fed56107704 ·clients/pgp/win32/EudoraPluginV4/emss¶
758131 dk/file1847.cpp
5a106f 4003b7781578cc41c8e9c62028f0589b1e6431aa ·clients/pgp/win32/EudoraPluginV4/emss¶
d66e04 dk/file1847.h
41897e f91ee97a030ca56213c29a43832410e37f61101e ·clients/pgp/win32/EudoraPluginV4/reso¶
e6709b urce.h
fc61be 37fd8a45bb6b18233326fc95d071b6127ee62c48 ·clients/pgp/win32/EudoraPluginV4/strs¶
6b4516 tri.c
0c36b8 e258b90eb51472f99ee44becc8eb0f94b04f5433 ·clients/pgp/win32/EudoraPluginV4/strs¶
56a1be tri.h
f0f5c6 8257b857c612a9fd271df359a69dab63f6f0ef29 ·clients/pgp/win32/INCLUDE/Help/PGPclH¶
039b29 lp.h
ac1d10 d8ada73df64f73956a4db1150ea3d42ce0766437 ·clients/pgp/win32/INCLUDE/Help/PGPpkH¶
ef9b29 lp.h
a7c570 f9a152e2a3cf04783775b98e44cef6d0d71f23c3 ·clients/pgp/win32/INCLUDE/Help/RDhelp¶
ca17ef .h
2cdfb3 0b19541f3a356d0238a5391473e424b6ecb59528 ·clients/pgp/win32/INCLUDE/PGPcl.h
d6d4aa f7978f05e9d1696d5050dafdb38573208d746dd5 ·clients/pgp/win32/INCLUDE/PGPgm.h
9e8ade 8be8d747c761d051fde40714af89cba74a534f2b ·clients/pgp/win32/INCLUDE/PGPhk.h
e3ae1a 5722d01a8444f680ed663ff6005d14db56634a09 ·clients/pgp/win32/INCLUDE/PGPkm.h
f14917 c26216439fb89811ac62dae39a2a3d351472f47a ·clients/pgp/win32/INCLUDE/PGPpk.h
ca60a9 7aadbedfdcd0fcc02d10b577cf25987c189311ed ·clients/pgp/win32/INCLUDE/PGPsc.h
f9ec30 7ac170397a4c622fc9ad7978a9b4d585af67e0ee ·clients/pgp/win32/INCLUDE/TreeList.h
a9da00 938acd6d6ae8c4ce40db7c3c12d22620bbbb07c8 ·clients/pgp/win32/INCLUDE/pgpImage.h
e59c48 273981cc39b8098e7578fc0c832666b37d60c061 ·clients/pgp/win32/INCLUDE/pgpVersion.h
1e5688 d4747666775a266331786f7601328c1e2ca72bb6 ·clients/pgp/win32/INCLUDE/pgpWerr.h
1bdca2 4f72f328fac6d85cc3eaa5c92bb76a6c7ee39d86 ·clients/pgp/win32/Installer/Disk1/set¶
cc4d01 up.ini
2990c8 462ae0150b05c54d731612d953758d07a617aff0 ·clients/pgp/win32/Installer/Extras/ad¶
d1014f obe.url
--d7e7 000d5513d9a40110003 Page 13 of winhashes.asc
05222d c0c7f16a5bb74800d98797a2fe6b54f351cdbc4c ·clients/pgp/win32/Installer/Extras/eu¶
a88a95 dora.url
c240e5 7ea49e4e859df42b80bda7ebf8424e9ea2004b16 ·clients/pgp/win32/Installer/Extras/wh¶
32f6e1 atsnew.doc
64873d 0cc748217838ca7c361138999ff305c8f0ff4637 ·clients/pgp/win32/Installer/Uninstall¶
0cf6db er/BUILD.BAT
321afb 4d4ace365a8b247c711a424a4ee44ece1c4a7fab ·clients/pgp/win32/Installer/Uninstall¶
9d3a85 er/Disk1/SETUP.INI
e765a5 912103ce79851fb3b2bf79bcd168d70531f1563f ·clients/pgp/win32/Installer/Uninstall¶
13da0b er/Uninstall/SETUP.LST
4a68dd 9117622170afda2d3f598e4f0e0f921c35d67f1b ·clients/pgp/win32/Installer/Uninstall¶
e19ea4 er/Uninstall/setup.rul
6348ae 0b1decfd14da4858c81a4b27564d210218e89f12 ·clients/pgp/win32/Installer/bmps/busi¶
f94068 ness/setup.bmp
c42a2f ca0ec80660bd2251394db410de36a7e9fd059cac ·clients/pgp/win32/Installer/bmps/busi¶
d21a12 ness/sidebar.bmp
a67f0a a20767c8c552d603c0ec0d2adde8eebdd1c13035 ·clients/pgp/win32/Installer/bmps/busi¶
1cb7fd ness/sidebarx.bmp
8ee015 67b5cc0ccda816ff4ab9b38cbbb18bf1aa0230e1 ·clients/pgp/win32/Installer/bmps/free¶
051fd5 ware/setup.bmp
4cc643 de9e148011aadbd08be20bd815e2b869bb7fbcb4 ·clients/pgp/win32/Installer/bmps/free¶
f53a76 ware/sidebar.bmp
dc4489 2557c3e07a1fe3bdebbb449f3743a7e22c637036 ·clients/pgp/win32/Installer/bmps/free¶
fb92ff ware/sidebarx.bmp
4016ba 213c67c76412b0351be2b065836a0a7a33e27f64 ·clients/pgp/win32/Installer/bmps/pers¶
aba839 onal/setup.bmp
725622 9e2549d186b3d3fb8181141a58f9be65ce9afcc4 ·clients/pgp/win32/Installer/bmps/pers¶
07bb7b onal/sidebar.bmp
c0f673 bac01c55773dec15e5e515acfa46647c4eab3f38 ·clients/pgp/win32/Installer/bmps/pers¶
ab499b onal/sidebarx.bmp
3deb24 edd7d4574b475366f8010544c901972217e065ed ·clients/pgp/win32/Installer/build.bat
0b097c e82b285be521a504631ebf7e2e2cfd390e08cf7f ·clients/pgp/win32/Installer/docs/DSRe¶
26b463 adMe.txt
3c988c 5072cc53405d9eac7fe885353dba16693a053309 ·clients/pgp/win32/Installer/docs/Free¶
0ea58e wareReadMe.txt
9a0f3a 73ecc0e83554373e36087f13d122588b699c9b8f ·clients/pgp/win32/Installer/docs/Intr¶
c9d5dc oToCrypto.pdf
99abbb 2618cfc5256028f727ac2c9d063e9c84c75e0a6a ·clients/pgp/win32/Installer/docs/PGP6¶
2ceaee 0.HLP
f84a26 056ebe28108f97e4cfef6a22930a295fca72e0d9 ·clients/pgp/win32/Installer/docs/PGPA¶
0dab7c dministratorsGuide.pdf
07a079 fdc5210f032cc7127cc1f78484cb4ef1efcb8c3b ·clients/pgp/win32/Installer/docs/PGPI¶
a03ebd nstallGuide.pdf
f0a4fa 267b0a7163c3380174d2b69b1596c521eea9756a ·clients/pgp/win32/Installer/docs/PGPW¶
c37a7b inUsersGuide.pdf
54c1f4 1129f2d36e3eb31f6e6002781874ec9985bb6719 ·clients/pgp/win32/Installer/docs/PGPd¶
15fc1c isk.cnt
bdc1be 5d8614204115ec7b8c7287b66c3c992c88482518 ·clients/pgp/win32/Installer/docs/PGPd¶
07eed1 isk.hlp
5046ac e82b285be521a504631ebf7e2e2cfd390e08cf7f ·clients/pgp/win32/Installer/docs/PPRe¶
f3b463 adMe.txt
2b6848 d2db8852c7a75d61cf0ce46a7ae49655ed513f24 ·clients/pgp/win32/Installer/docs/Pgp6¶
1c5778 0.cnt
e1abf2 c2863d332775fbb9a53dc7dbd8b14520efa2ba42 ·clients/pgp/win32/Installer/keyrings/¶
8fb67d DSpubring.pkr
08a9d4 e6e69211779d9965fa1822d05b394b6cc7896816 ·clients/pgp/win32/Installer/keyrings/¶
559de4 PPpubring.pkr
8eb409 8f079dae1dc879f4f92f0e2c806acbc3c640249e ·clients/pgp/win32/Installer/keyrings/¶
8da3c0 WhatIsThis.txt
fba101 c2b322ff665617c7849212132888d1f02be54424 ·clients/pgp/win32/Installer/keyrings/¶
a77715 samplekeys.asc
af6210 c6ea0669bfd688cf496414fc43a0c29ad12f35f8 ·clients/pgp/win32/Installer/licenses/¶
90c78e fieldlic.txt
c12fd2 21d4553339bd244250dd122af6c2f09fdf7b39b4 ·clients/pgp/win32/Installer/licenses/¶
2e5db5 freelic.txt
e005b4 870f084acb14848dcbe93423130f39b3dcbec183 ·clients/pgp/win32/Installer/licenses/¶
94c167 license.txt
ce2c48 f95d859654cd401dd1de0055a64b09c28f1a6b3c ·clients/pgp/win32/Installer/licenses/¶
6ebd52 reglic.txt
350614 20f67d3645b9fb3a39291720bd5dbbf5bfe64f5b ·clients/pgp/win32/Installer/licenses/¶
816679 triallic.txt
d53d4d ef05297430791036389b9d5cb47ce9c9f07406e8 ·clients/pgp/win32/Installer/setup/SET¶
--7e19 00085dc9e4840110003 Page 14 of winhashes.asc
8235ed UP.LST
295b51 f6e195ab74fa7ae28d79bc6d675192faf7dd2bb6 ·clients/pgp/win32/Installer/setup/set¶
624d01 up.ini
e0e336 34713a328fa33508e4e7e43aa809fc82a5d2a9ac ·clients/pgp/win32/Installer/setup/set¶
859c3e up.rul
ed8149 d31a0018aa4f4828d73eb66da647ada9f3292ef2 ·clients/pgp/win32/Installer/setupinst¶
3c3730 all.bat
eaf2c8 ebd0d3925be3de2cfd3e3cb7af6c66cbb739aedd ·clients/pgp/win32/Installer/tempstuff¶
f67631 /neta.bmp
678d0e 17350371bbe575ff67a708f85bcfafcc8445dc9b ·clients/pgp/win32/OEloader.dsp
59ac3a 6a05a91c0782ca4a808c5bd6109fef4ad75beb7c ·clients/pgp/win32/OEloader.dsw
22d07e 4d7c7ea21e6e6766f9a1d45a82d0dd5fa66624b2 ·clients/pgp/win32/OEloader/Res/envelo¶
99403a pe.ico
fc6a59 2604dee8d04814531138bb232dc5fc364636699c ·clients/pgp/win32/OEloader/Res/letter¶
b7c240 .ico
8c7373 579b1eea688cdbf395cad87d5d229d1e39cf4121 ·clients/pgp/win32/OEloader/Res/msimn.¶
fac369 ico
0d3463 4f3c75216341d24e2018642112d22188bc98e7bc ·clients/pgp/win32/OEloader/Res/news.i¶
19a3ee co
d42aa3 579b1eea688cdbf395cad87d5d229d1e39cf4121 ·clients/pgp/win32/OEloader/Res/packag¶
395176 e.ico
76602d b2da526e7e610843e03d6b078140d0fcc7892289 ·clients/pgp/win32/OEloader/main.cpp
2bdf19 72160b7df0678fc6e28372aa265cc9bd702bb538 ·clients/pgp/win32/OEloader/msimn.rc
717c4f 12b63ac3ec6466a28c29bdcc4dcc493780155e2f ·clients/pgp/win32/OEloader/msimnVer.rc
a34d27 4a907751af1cc89c2028ebbdf21c62a8c25187c5 ·clients/pgp/win32/OEloader/resource.h
fd3bec 9b443571aafea0a15e2c74d930874d37da514674 ·clients/pgp/win32/OutlookExpress.dsp
16e012 a89086cc8570a2015b56f48aa13230e32a74b227 ·clients/pgp/win32/OutlookExpress.dsw
f861ff 05b1f770ae44f7acf36e7f9d5b6b5622c763d47e ·clients/pgp/win32/OutlookExpress/CBTP¶
e4d7ed roc.cpp
90d6d7 744aa003e0450a856888148b3a34a996ad5ea938 ·clients/pgp/win32/OutlookExpress/Comm¶
c4ba79 onWndProc.cpp
3ca7a3 84157891e01bb27eacb503bc680a66379cf49186 ·clients/pgp/win32/OutlookExpress/Hook¶
ee765e Procs.h
321fc8 33483a8486e1980b6eaadca9bc62c5aa4e16c6fb ·clients/pgp/win32/OutlookExpress/Main¶
ef253a WndProc.cpp
2fe1f8 2d4c5e3a673e5a87eb3b7f6eaae243525bbd9785 ·clients/pgp/win32/OutlookExpress/PGP5¶
36ef20 5oe.rc
d1f25e 5d203d67a2f792fb5411a3e46db27ed56ad004bd ·clients/pgp/win32/OutlookExpress/PGP5¶
b26f17 5oeVer.rc
e32c6a e33374dc33b9600d9381c109249211f3a8ddd9fa ·clients/pgp/win32/OutlookExpress/Plug¶
6fa9ef inInfo.cpp
02b167 96574215c932fc6f7dc748686f7c25a6bf3ca89f ·clients/pgp/win32/OutlookExpress/Plug¶
ee5e94 inInfo.h
60fe8c 71f75968ae47056692e9424977ba12ceb16100e7 ·clients/pgp/win32/OutlookExpress/Read¶
37f2e2 MsgWndProc.cpp
1d7f33 118dc54446f7a5cc1ca44db9e372993538fc5bdf ·clients/pgp/win32/OutlookExpress/Reci¶
60b344 pients.cpp
449f9d 6b383c383374961383a37151fd0ca1b26f3c77da ·clients/pgp/win32/OutlookExpress/Reci¶
192b7d pients.h
96a529 f8dcb992d52731313329dad1e7326e5e6b1be3f7 ·clients/pgp/win32/OutlookExpress/Res/¶
13dddd addkey.bmp
31d5eb f60adedee739c61b978450758aa8fcc221109a85 ·clients/pgp/win32/OutlookExpress/Res/¶
8645f2 decrypt.bmp
13a4e8 a9aa7aff9114a9304bcb4aeab15ad59c230538ac ·clients/pgp/win32/OutlookExpress/Res/¶
3882be encrypt.bmp
2c13c4 bd5540a3e6df0ed6289f4694598bb5a67c67ea60 ·clients/pgp/win32/OutlookExpress/Res/¶
7ba814 pgpkeys.bmp
9699c0 63d64abe940167d1600a43a371e50aea669f3187 ·clients/pgp/win32/OutlookExpress/Res/¶
cf8065 pgpkeysl.bmp
08e0cf 92c15a2f14b1c71ca401f3aacb8fdbb9d8525567 ·clients/pgp/win32/OutlookExpress/Res/¶
238c18 pgpkeyso.bmp
849493 a9b592bfe5a0e2b53e2b40de5da1105fa4c2b951 ·clients/pgp/win32/OutlookExpress/Res/¶
3c5cd7 pkl4.bmp
c16976 8f982d7f11bfb2dd3f2647bec59593e1ac2f680c ·clients/pgp/win32/OutlookExpress/Res/¶
8cf4b9 pko4.bmp
8a98cb 878d6ba9ec25532f5c53f531084a3cfbbdda516b ·clients/pgp/win32/OutlookExpress/Res/¶
9a9e52 sign.bmp
c45177 7f2109a4662525c9267226b756cadf6e62d3393c ·clients/pgp/win32/OutlookExpress/Send¶
23f2e2 MsgWndProc.cpp
4e2daa 9663301b3f54b8b17b3b67610e7da5e6dd298993 ·clients/pgp/win32/OutlookExpress/Text¶
acdb21 IO.cpp
8504cb 6fd87690023dd56d68d7d699c544413440f9b4b4 ·clients/pgp/win32/OutlookExpress/Text¶
--f14f 00068b2fe3140110003 Page 15 of winhashes.asc
e923e7 IO.h
1c446f ad6b6dc7a5698c3dff68c2076bf6318893e93f26 ·clients/pgp/win32/OutlookExpress/UIut¶
abc127 ils.cpp
aac2bc 188fd57270e8ced0324c265470e1f97f9da753ae ·clients/pgp/win32/OutlookExpress/UIut¶
121c26 ils.h
8a4353 7032b6c88a11b1c7d4cbd64bfa91e70e15aa8ea7 ·clients/pgp/win32/OutlookExpress/Unkn¶
43f413 ownWndProc.cpp
8b5de3 ba1fe35c96b55a435174f6a6e116f6ae9b36f949 ·clients/pgp/win32/OutlookExpress/main¶
c36246 .cpp
118703 34a9430aa60afd021070967be0ddab67b61fdb05 ·clients/pgp/win32/OutlookExpress/reso¶
11709b urce.h
a7d62b 3b2f2e597af4eb9ec629ed795df011975318c69c ·clients/pgp/win32/PGP55.DSP
1b59e7 b085b1e7453519ba867a128c2170b54a89f8e385 ·clients/pgp/win32/PGP55.DSW
9c5770 ed7514485732403b9f1fe26b75ec820d6422dbd9 ·clients/pgp/win32/PGP55/main.c
e1a9b4 73ef184ea223d2d93c029b42ebdba198a71cd4f8 ·clients/pgp/win32/PGPWCTX/CTXMENU.DEF
5bb90c 81a793e39ec1beef511a73b8d265c3d29c33a9d4 ·clients/pgp/win32/PGPWCTX/Ctxmenu.cpp
7c9af2 794472292df6f0ff040890ddcf202548660abbb0 ·clients/pgp/win32/PGPWCTX/FolderConte¶
a0c3e0 xt.reg
67e8d3 fc9f8bd6222394b3413b5d8e39f9d2ee6f3d2d53 ·clients/pgp/win32/PGPWCTX/PGPwctx.reg
90f28e 2da5d74db2477d570489d560a210de72d1ac67f1 ·clients/pgp/win32/PGPWCTX/PGPwctxVer.¶
49d507 rc
1e9d69 9e860ca0706834da0dce671b60af19f8fc28ce80 ·clients/pgp/win32/PGPWCTX/PRECOMP.H
917e1e 3fc139253a7e818e741ff709718b5bc073db2434 ·clients/pgp/win32/PGPWCTX/Pgpwctx.cpp
509ea1 150336a3f835909c6212d4262e996cb17b5757d0 ·clients/pgp/win32/PGPWCTX/Pgpwctx.hpp
96a7fb 8d4f9b26f6cc4dfd4aff68a656c057780ba94ce5 ·clients/pgp/win32/PGPWCTX/Priv.h
e8a49e 1495945545bc5b6aac495a246496c2298612e5f0 ·clients/pgp/win32/PGPWCTX/RESOURCE.H
3712bf 1cfc68f958a016b3152397451acef54ff6f02acd ·clients/pgp/win32/PGPWCTX/SClink.cpp
c5496b aeb7709f661c10b6359168482df2fda108b4018f ·clients/pgp/win32/PGPWCTX/Shexinit.cpp
c5be41 ba56363a3a65f936b852fef6f86bd8397c1e0120 ·clients/pgp/win32/PGPWCTX/pgpCodes.hpp
cb4c5e 5f1f97a1a9349bc9e8db64630fac29f99305fc18 ·clients/pgp/win32/PGPWCTX/pgpwctx.rc
c23fae fe436c6f99fb52d1ce7d6045170a041750900c61 ·clients/pgp/win32/PGPadmin.dsp
8e4246 dc8effe52493281cda87eea60b2108e6f7c04175 ·clients/pgp/win32/PGPadmin.dsw
eeeca0 ff12d4b363de944637caeb1447b13707895c999e ·clients/pgp/win32/PGPadmin/Additional¶
1f3c5d Decryption.cpp
19fe02 42845d8a56f59c13a4661dc8032053a89c646fdd ·clients/pgp/win32/PGPadmin/ClientPref¶
a7ab3a s.cpp
d05664 f2bcf160e110a55c1b7ca8d423b29c836e7873af ·clients/pgp/win32/PGPadmin/CopyInstal¶
961354 ler.cpp
30ae7d 80800f1a1d1f039920fa60f7c780dc1a4647e118 ·clients/pgp/win32/PGPadmin/CopyInstal¶
73457e ler.h
975b5b dc01c59f06c09152bd7fabecf05082b47dbeef2e ·clients/pgp/win32/PGPadmin/CorpKey.cpp
a7f7b3 2242846988f8aab1018091d73f66224b14541ab7 ·clients/pgp/win32/PGPadmin/CreateWiz.¶
5a636f cpp
951fc1 a56f1c8886590b2ff1105d8518a69a4db1e7c6ac ·clients/pgp/win32/PGPadmin/CreateWiz.h
93a328 9c056793109aacecb890917eda34f7beb0e6ddaa ·clients/pgp/win32/PGPadmin/DefaultKey¶
28ab3a s.cpp
e7d2dc 9e539e6aa7784be6fe6e3765b5b9aa1b46d9fbff ·clients/pgp/win32/PGPadmin/FindInstal¶
e71354 ler.cpp
e01059 8e338d693e0a5fd2ed7ad9caa86976270178cc8b ·clients/pgp/win32/PGPadmin/FindInstal¶
73457e ler.h
a1e028 8f48c0d81ad4ea121b8c858fe9db701bfa85ece7 ·clients/pgp/win32/PGPadmin/Finish.cpp
938005 9598381c1d1e11e58c4cfb5718c14b7011d08420 ·clients/pgp/win32/PGPadmin/InstallOpt¶
8ac840 ions.cpp
06f993 1fb8a0381530698f0830267f91155e3f22a232ca ·clients/pgp/win32/PGPadmin/Intro.cpp
dc15bb e0538347dc4af312443fa86f305329efd7d72f6d ·clients/pgp/win32/PGPadmin/KeyGen.cpp
60a8ab 416500184f57490b5dcd34cb5149c1830baa9289 ·clients/pgp/win32/PGPadmin/License.cpp
e2b776 f97758879137621dabab385f41cd8fe7c33cc65f ·clients/pgp/win32/PGPadmin/Misc.cpp
a287f9 d63f24e291254a2b3a5cae8807938f16baa0b1d9 ·clients/pgp/win32/PGPadmin/PGPadmin.c¶
50df46 pp
1875e4 0c5339830577aff27f75059afe3edbb9749da1ff ·clients/pgp/win32/PGPadmin/PGPadmin.h
ca9265 c01b03ab6d9bd4c40f8040fc8d1076e6091a2d59 ·clients/pgp/win32/PGPadmin/PGPadmin.rc
9e0779 fabc45d5af938e958c78ecc848c58b9609564b49 ·clients/pgp/win32/PGPadmin/PGPadminVe¶
d4f76d r.rc
91318f 5c11df054f0ed50d5948ecafcc604f9193e412d5 ·clients/pgp/win32/PGPadmin/PassPhrase¶
f16246 .cpp
6bc1c8 4905849b6867dd5ed0712675a41326c892b5dcfb ·clients/pgp/win32/PGPadmin/Res/AdminW¶
b97177 iz1bit.bmp
b22ef7 192729c14e4ae9f5c22f4e6418327dba4e29c48e ·clients/pgp/win32/PGPadmin/Res/AdminW¶
dc47a2 iz24bit.bmp
f24460 a7b7d5c843e6bc1fa3c3a86640d38b7964e0cd08 ·clients/pgp/win32/PGPadmin/Res/AdminW¶
5e036f iz4bit.bmp
688672 1e1d3432c292cecc203b258fbc1c55d0d03b4b54 ·clients/pgp/win32/PGPadmin/Res/AdminW¶
--8743 0009618649340110003 Page 16 of winhashes.asc
234340 iz8bit.bmp
30e74e 62ce2b3d91aa287819518a5acc6b8f977247fba8 ·clients/pgp/win32/PGPadmin/Res/DSAkey¶
d30417 .bmp
64171f 0858e7ab192c38f08cbdcae49c1fc51f1d41ef06 ·clients/pgp/win32/PGPadmin/Res/DSAkey¶
d45997 mask.bmp
d35c1c a41f5a03f3a465bcdeda7fbc4aac8a030660de00 ·clients/pgp/win32/PGPadmin/Res/RSAkey¶
050417 .bmp
243592 b620924dae55d7adbab53a1cd91112f950db024e ·clients/pgp/win32/PGPadmin/Res/RSAkey¶
e05997 mask.bmp
251d60 b3ff3f07e99a75180a82907b4dcc42a46f3ca283 ·clients/pgp/win32/PGPadmin/Res/admin.¶
dfc369 ico
29eac7 cb105fdda62b4fede673963fcc9947dcdf26c224 ·clients/pgp/win32/PGPadmin/Review.cpp
6fca8b 66a7977e2e86edecfa50fdde683d2ed883074f91 ·clients/pgp/win32/PGPadmin/Revoker.cpp
2c22cd 99e799d82ded63a3b1b066e70df9bc3c3a972ce0 ·clients/pgp/win32/PGPadmin/ServerUpda¶
5c61bb tes.cpp
9cd25f 8b30f15adc2d02eb2bf3d78d75a6c28c24011240 ·clients/pgp/win32/PGPadmin/Utils.cpp
6961c0 c0cdd2bd86ebb2866d12deec1606aa333fc0c9d8 ·clients/pgp/win32/PGPadmin/Utils.h
b84de2 eb8936e4fd30bd1b91400acd9d3def6b3aa4d8d6 ·clients/pgp/win32/PGPadmin/resource.h
bfcd16 9c54ff866ae6f0142b210eeeb5f8c8b3fa7696c8 ·clients/pgp/win32/PGPcl.dsp
bb49c6 abbe31dfa6caab1ab962716c713be42c04d6c324 ·clients/pgp/win32/PGPcl.dsw
af8f4f 6cd5d4babd43742dbfcd94ff605b1627bc1eb3ea ·clients/pgp/win32/PGPcl/CLabout.c
bd2a43 b047416b484c67b5f42ca753224f4bb343e73031 ·clients/pgp/win32/PGPcl/CLcache.c
6419e2 2c13b8afd6ae9c32232b647fc7723c90073f3b37 ·clients/pgp/win32/PGPcl/CLerror.c
a05286 bcaff96b36cee5fe21876d447222c9457f0257a9 ·clients/pgp/win32/PGPcl/CLexpire.c
76a56a a2e7556ad3f754bd510be46c4085fa0988763ad9 ·clients/pgp/win32/PGPcl/CLgroups.c
506926 1958c8bcd98cea1b6629debffb02e316afe3c883 ·clients/pgp/win32/PGPcl/CLkspref.c
7c0395 549e969d94f1e30cfcd37783b7507b6e095e791c ·clients/pgp/win32/PGPcl/CLmisc.c
a13293 80f25e00d8175f0a8b6ae4ed36c49fdb01483363 ·clients/pgp/win32/PGPcl/CLnag.rc
e5b1e5 581c41d896e100d7989d658fd37f3cec24ba696a ·clients/pgp/win32/PGPcl/CLphrase.c
92e17e 0b2953948895f58cf7c1a3326eaf517feb57f085 ·clients/pgp/win32/PGPcl/CLprefs.c
1dcda4 324441d22c8eee298d216adc94b97dfd1c32dd57 ·clients/pgp/win32/PGPcl/CLquery.c
0888ff c6b6c040b85e51a9c3a402e57f6402d80e9d6451 ·clients/pgp/win32/PGPcl/CLrand.c
d8cd16 37efa605af084454d6a39c29f88887a79c3c100d ·clients/pgp/win32/PGPcl/CLrecip.c
9c864a 5a29a925d8c10d7b966c7ef47e35030d317ca088 ·clients/pgp/win32/PGPcl/CLrecon.c
136e0e c7ccdce34cdef910caa532b7cfe9d0bc16154cef ·clients/pgp/win32/PGPcl/CLsdksrv.c
173d7f 9b9eb3d781f637ba44126812a9094d345e3d0682 ·clients/pgp/win32/PGPcl/CLselect.c
4a31ab 9aa9229e89e6e85b5e1dc66474fcc4059a59ff54 ·clients/pgp/win32/PGPcl/CLsend.c
a36a9f ba321e2a28fb7bc8ecf7b2217e02d512319d1465 ·clients/pgp/win32/PGPcl/CLserver.c
67b6a3 e9b82ccee2172a4fbd9bdaf5fa54fa435fdd2383 ·clients/pgp/win32/PGPcl/CLsplash.c
598872 305d5ce7ac2b82b55976644459c010587bba16ad ·clients/pgp/win32/PGPcl/CLsplash.rc
19c4f1 1443779ba225b43e0a2cb47c6107719418826509 ·clients/pgp/win32/PGPcl/CLsrvprf.c
ca4680 bd9d1f6916f86c37ff156c00a848117b0309d7f5 ·clients/pgp/win32/PGPcl/CLwarn.c
34c0be a1d6f496ee6ec461969850d8a4458f5b6763558a ·clients/pgp/win32/PGPcl/KMAddUsr.c
5c2565 d548987e6d5a2d38849019b6af5f7099786ed661 ·clients/pgp/win32/PGPcl/KMChange.c
8361dd 89b18ae55966fe55eb791c9729848151c702ee84 ·clients/pgp/win32/PGPcl/KMColumn.c
b7223f da4414b82241b044def705ba836c61338bde8b07 ·clients/pgp/win32/PGPcl/KMConvrt.c
72b1f7 10800ad566106a5dbf5238c4bb229f9fb9d7cdbe ·clients/pgp/win32/PGPcl/KMFocus.c
f43f0d 0c2cd91fe17cb415bdec68c2f0556659f25d49f3 ·clients/pgp/win32/PGPcl/KMIDataObject¶
546246 .cpp
f1df3e 597180e5220abe5bf03798af4cf75e8f346950bc ·clients/pgp/win32/PGPcl/KMIDataObject¶
7317ef .h
5292c2 1af2ebab2256e27268dad7968408793e468f76de ·clients/pgp/win32/PGPcl/KMIDropSource¶
626246 .cpp
4f4922 de60e1fe6c5d7ba83f0acf1281b6e2a8958dd59f ·clients/pgp/win32/PGPcl/KMIDropSource¶
6817ef .h
8402fe 02bf617647e2bcdd29b2af24f4ff5d499cbabeb4 ·clients/pgp/win32/PGPcl/KMIDropTarget¶
516246 .cpp
ca34d4 6b9837e8c67dc1989524c2958b9140485956f630 ·clients/pgp/win32/PGPcl/KMIDropTarget¶
c017ef .h
38b157 5ec034d06bf7a600befc742773c5cb09f2531407 ·clients/pgp/win32/PGPcl/KMIEnumFormat¶
456520 Etc.cpp
539e85 6f6bda8c1a80cfccd90ebe67417b0f95e7262b29 ·clients/pgp/win32/PGPcl/KMIEnumFormat¶
dc8573 Etc.h
d0b122 46f55d93222c34c667c85bc88ce7adb5b1e25e91 ·clients/pgp/win32/PGPcl/KMKeyIO.c
b8e983 59f0fc68d65555d03994b7736c8eb20a6b346ca0 ·clients/pgp/win32/PGPcl/KMKeyOps.c
8a6e1f 8e738f4462e768fdb21c8044f658ff7b9dbec470 ·clients/pgp/win32/PGPcl/KMMenu.c
696db0 05667bd8b0ad010bb43e615764ee2b5e5b6d5ad2 ·clients/pgp/win32/PGPcl/KMMisc.c
53861a c17dee96ced8528ae64dd1eeeadef49f0bfdc002 ·clients/pgp/win32/PGPcl/KMNotPrc.c
6537ed 9f3e7b1919541619b7c8b5cacbb138f7c68f1b2b ·clients/pgp/win32/PGPcl/KMPhoto.c
6865c3 49a70ac2f9b15e301fc4f953848d3fe719e29d9d ·clients/pgp/win32/PGPcl/KMProps.c
166e9c 1e4397c7ad1610180b1fe94bbf49dd240e563dfd ·clients/pgp/win32/PGPcl/KMRevoke.c
96cd94 3c8951753be6d0873c342df3d58faf895db77e33 ·clients/pgp/win32/PGPcl/KMShare.c
--dbf1 0009d18a0b140110003 Page 17 of winhashes.asc
2b7c1d 9d748e52c03fe9ed1dc8a9f1265c4de499c7997b ·clients/pgp/win32/PGPcl/KMTree.c
737023 d6e515012f130b47f256f5a3e0b100f349dbb39a ·clients/pgp/win32/PGPcl/KMUser.c
373e61 e8eaafcf38a0d62883abeef7e3c3fd9734d42fb4 ·clients/pgp/win32/PGPcl/KMserver.c
c9dce1 a2fd111831e134596ec78aec425e05d15c576759 ·clients/pgp/win32/PGPcl/PGPcl.c
074f12 088d0a8b864076f4f8188eb23749f93aa59543be ·clients/pgp/win32/PGPcl/PGPcl.def
ead58e f33b9941f177e4160ea1ba083ded66247171f47c ·clients/pgp/win32/PGPcl/PGPcl.rc
3e8f6d 0ce5e3f4ed3986fb93cdb83141b913380cc38d15 ·clients/pgp/win32/PGPcl/PGPclVer.rc
97d5d4 87b85a6d0ad0418a8ca0523b0f6d3b00664d11b7 ·clients/pgp/win32/PGPcl/PGPclx.h
9c52c6 492db9120f765b5b99f0b122ed0e988d36c7fa3e ·clients/pgp/win32/PGPcl/PGPkm.c
5652e3 a3896b132f6a27e9a0bd9f3c2f7d9a127ec52d2f ·clients/pgp/win32/PGPcl/PGPkmx.h
95c0a7 054bd927e9e65ae17c9b048edd0821a23183ac32 ·clients/pgp/win32/PGPcl/Res/CLimag24.¶
f7053e bmp
e14ce6 5610952fa50a5c119e69fc416b6654ac1c75b1e3 ·clients/pgp/win32/PGPcl/Res/CLimag4.b¶
0da5ac mp
cbade7 12518bb01331c2014ab178274526865db084bd5f ·clients/pgp/win32/PGPcl/Res/Key.ico
265aca 97454f1dbc959ba05baced2b5e4e7ed9b0f7739f ·clients/pgp/win32/PGPcl/Res/bizsplash¶
70a938 1bit.bmp
dd8b22 aa9380cb23234bfae0891f4037c1ec8b8053f2df ·clients/pgp/win32/PGPcl/Res/bizsplash¶
fcdb20 4bit.bmp
0fdf27 7d53ceb950e24b0cfdf257aa41c706adf4f8659f ·clients/pgp/win32/PGPcl/Res/bizsplash¶
f79b0f 8bit.bmp
98f769 6be60e5290605acae313d69d8b0c8a53cc832701 ·clients/pgp/win32/PGPcl/Res/credits1b¶
ce3406 it.bmp
93751a 2b4bdc6ec7010b85bba3f5e02e2c51a4ccc3136c ·clients/pgp/win32/PGPcl/Res/credits4b¶
ef3406 it.bmp
3a3164 a484bcd3badbfb38125f607964457aad75339198 ·clients/pgp/win32/PGPcl/Res/credits8b¶
2f3406 it.bmp
84be39 be21cd4baa1ab95563a54ec30a4b941fee6f3563 ·clients/pgp/win32/PGPcl/Res/eval1bit.¶
60053e bmp
a76ee9 65e3b5a41459501f79880f1e8727564da7a93ae9 ·clients/pgp/win32/PGPcl/Res/eval4bit.¶
7c053e bmp
9bd939 3e596bf02a1f318c90d2adc8727c82c4f623d590 ·clients/pgp/win32/PGPcl/Res/eval8bit.¶
ce053e bmp
ce4cd2 e6e0e8dc9fa921b1522e89a1bda9e11db152a00f ·clients/pgp/win32/PGPcl/Res/expired.b¶
e6a5ac mp
644b4e 45ffddf86daa0740f186fe7559e320c71d9076f1 ·clients/pgp/win32/PGPcl/Res/freesplas¶
539284 h1bit.BMP
a3882a f69ac3af401d3b125c9e9cda26d2e381cde82bda ·clients/pgp/win32/PGPcl/Res/freesplas¶
12e09c h4bit.BMP
38c238 5c9dead3b74490aa6719cfa3cb5a971a971fa0d1 ·clients/pgp/win32/PGPcl/Res/freesplas¶
9ea0b3 h8bit.BMP
687f5d 1c4168df45ac81b9346964778728ce2719e70364 ·clients/pgp/win32/PGPcl/Res/qmark.bmp
6c508e 8b07a808902b178b13e6372e19f0143fc24bc5d3 ·clients/pgp/win32/PGPcl/Res/revoked.b¶
7ea5ac mp
d79668 23c3239c02ad8b1ef50030e71f44a2adf49a0e55 ·clients/pgp/win32/PGPcl/Res/rsacredit¶
87f2cd s1bit.bmp
50857e 02f2b611e40eb3b04ae1f3a8a4f672bf2efa1b36 ·clients/pgp/win32/PGPcl/Res/rsacredit¶
6e80d5 s4bit.bmp
6cdba4 2234f3f8360f945095191f0d610f32be90c197c7 ·clients/pgp/win32/PGPcl/Res/rsacredit¶
ecc0fa s8bit.bmp
ec1a2e cd5cabefe6d14aad7d8ba58590c197223780ba8c ·clients/pgp/win32/PGPcl/Res/splash1bi¶
3ed1ba t.bmp
bc80f0 58fa22b82acfa783bf9bc7860c9decd31bdeb073 ·clients/pgp/win32/PGPcl/Res/splash4bi¶
bad1ba t.bmp
95b5c7 f86689ef244e79a471fe4dc3d0dce0bb9ad0c8c5 ·clients/pgp/win32/PGPcl/Res/splash8bi¶
5ad1ba t.bmp
23b0c7 0c1a7b37858cd84162fb117908abdd2b638569cb ·clients/pgp/win32/PGPcl/resource.h
0f6688 5875906695fda888125f24924e8d267409b231af ·clients/pgp/win32/PGPhk.dsp
52ee90 9d28e27ff69705f20dd81c9ee8dac9bbe4cd0128 ·clients/pgp/win32/PGPhk.dsw
29e29b 691973e69d761c96bdfcbfa6efe2086321a91f5f ·clients/pgp/win32/PGPhk/PGPhk.rc
95a8ad 823ff828bddb2106a0d7ad5f004c90aa31618a3d ·clients/pgp/win32/PGPhk/PGPhkVer.rc
9820d0 f1d121b9cfee34be7ec19bd3c56388ba280b7db5 ·clients/pgp/win32/PGPhk/hook.c
2987bc 86b9517097c1879cf8c91fe2e616c3121aa93011 ·clients/pgp/win32/PGPhk/pgphk.def
8e465a c255984bde2d88ed32d7e98ca6753063a8fc3c05 ·clients/pgp/win32/PGPhk/resource.h
2fcd48 9e381411212ffac06b2e25e379b877987543fefc ·clients/pgp/win32/PGPkeys.dsp
6f6ede 6bfca33e7df7e3a028e0e2c93884d507b2ed97d0 ·clients/pgp/win32/PGPkeys.dsw
23dfa5 f8d2b0cd375391a360c582a47ed60cfeb390124c ·clients/pgp/win32/PGPkeys/Choice.c
79155a c6355e43bb8d19cf5d0da9b34fa21e2a129faf1a ·clients/pgp/win32/PGPkeys/Choice.h
5c6c00 ce405921c7329f36dee91dfe297b44532a69a383 ·clients/pgp/win32/PGPkeys/ChoiceProc.c
cd2f75 b9073ff2d561c38d445f5322fd0ba9e2b4af49b3 ·clients/pgp/win32/PGPkeys/ChoiceProc.h
e54c4b f4b2f683ee32cdf1142063d1ff282fdc67dda4b3 ·clients/pgp/win32/PGPkeys/GMIDropTarg¶
9de3cd et.cpp
--e268 0006a7ebb6c40110003 Page 18 of winhashes.asc
6d5f30 187b546d3a9a49bdf6d401d09dda5706f7bf756d ·clients/pgp/win32/PGPkeys/GMIDropTarg¶
d9b8a1 et.h
c76110 9de8208a745c66993df5fee682aa418d31aef504 ·clients/pgp/win32/PGPkeys/GMMenu.c
ebda38 21aebaf007fc58e9385673c45d64552d0ac35cd6 ·clients/pgp/win32/PGPkeys/GMMisc.c
9c05e3 740dc668fb52fea08af3b2a3b64210e1b27ce3a0 ·clients/pgp/win32/PGPkeys/GMNewGrp.c
ea7bae 0f4679d010d9c6d82b96bd7beaece920df50724b ·clients/pgp/win32/PGPkeys/GMNotPrc.c
18d5c9 ae909a98e7fd9f2f7ed0021ba82342b9d1eb1708 ·clients/pgp/win32/PGPkeys/GMOps.c
aedbfc 7074bd3b67fd3848be26da08a69fc0b3920b7cb0 ·clients/pgp/win32/PGPkeys/GMTree.c
633684 f9f80a96c053784c3966bb93e11667361efdcc88 ·clients/pgp/win32/PGPkeys/PGPgmx.h
4e8974 6622908c950f63c8bf8b6bca988cbca07995c32e ·clients/pgp/win32/PGPkeys/PGPkeys.c
788cbd a700dc77c4a133e6b9ca7ac39f3ed8d3344d3a0c ·clients/pgp/win32/PGPkeys/PGPkeys.rc
a80d3d ef5f1bd5a83655bb5a2696f53395b00148c647f5 ·clients/pgp/win32/PGPkeys/PGPkeysx.h
93ae08 e6f74ad33d5fd98418505ccb13edabb368a3060a ·clients/pgp/win32/PGPkeys/PKMenu.c
b588e4 57fe4b7186891168a08d72a4de0ff2482e8184ef ·clients/pgp/win32/PGPkeys/PKMisc.c
b6c61f 90c114d8e1f5d181750dd820bf4ac5ba3ccfcc42 ·clients/pgp/win32/PGPkeys/PKMsgPrc.c
d27df8 74c4a31c1f23367875afe2c07050dad9801683f6 ·clients/pgp/win32/PGPkeys/PKTool.c
452686 faafc18686da9942dff33415206194d9d7afd6cc ·clients/pgp/win32/PGPkeys/PKUser.c
1b9662 a9d512e74e3f125345597c5a1d5c2230a1c4b504 ·clients/pgp/win32/PGPkeys/PKVer.rc
625003 88c705e49df8c0311540a6a9dd964d554e41ce6e ·clients/pgp/win32/PGPkeys/PKgenwiz.c
5329da 430fece144b8ea8fe36277178909a6b30f02da60 ·clients/pgp/win32/PGPkeys/Res/Key.ico
552e57 94b807de098fdd0bfaff138af36e0d9bc58c4de7 ·clients/pgp/win32/PGPkeys/Res/Toolbar¶
65fd89 24bit.bmp
835a3b 369a9c71c3b975d55797f6478d9888e2b1bb699b ·clients/pgp/win32/PGPkeys/Res/Toolbar¶
11db20 4bit.bmp
e71b2f 813edef353acfe36676e4243faa485729465d421 ·clients/pgp/win32/PGPkeys/Res/arrowco¶
37ad4a p.cur
a178ea cd3554220c1c7c8d245460ee539e88e05b74ea69 ·clients/pgp/win32/PGPkeys/Res/kgwiz1b¶
f23406 it.bmp
85efb3 bc9d9535fdd299f1095105dd1cfc551ee217fafb ·clients/pgp/win32/PGPkeys/Res/kgwiz4b¶
5d3406 it.bmp
8a9132 e2c35d709fcd484f2ba0ee92c2ab3f78c64f16c6 ·clients/pgp/win32/PGPkeys/Res/kgwiz8b¶
6b3406 it.bmp
7d7826 3bf92510a1b2acd684b0e693b1c7d2042270c9a6 ·clients/pgp/win32/PGPkeys/Search.c
6ae017 a9aeaef8b055ff0157e6be8b5856ecdc6a54f7d1 ·clients/pgp/win32/PGPkeys/Search.h
d1b0aa 5da74d3ea99ff871af6781651ae823ecbedcaa80 ·clients/pgp/win32/PGPkeys/SearchCommo¶
b7c4e1 n.c
a4f0d6 cecc9695f6a688c8e46e84c8c0b4f18f132c0f9e ·clients/pgp/win32/PGPkeys/SearchCommo¶
8d2049 n.h
53ee3d b42b57ea51f912601ae832500908c61c60c61a7e ·clients/pgp/win32/PGPkeys/SearchFilte¶
f29074 r.c
03c5c9 9bcac36a5ac0498b6184e13e707408106f87724f ·clients/pgp/win32/PGPkeys/SearchFilte¶
5274dc r.h
7aae31 dafdbb56cc784d2992d3afea2b4c207b43b0a324 ·clients/pgp/win32/PGPkeys/SearchProc.c
9ddf23 2a6ec35a55817c92d2afb3db1c18a362a8ee9aed ·clients/pgp/win32/PGPkeys/SearchProc.h
043bd8 5dbdbbf421cff4f42bdde3b5f03927b28baf6763 ·clients/pgp/win32/PGPkeys/resource.h
2e00fe 638040dee2c65835ad999e9d9e1aac7741d1567f ·clients/pgp/win32/PGPlog.dsp
829a7e 31bcd3e094c5a8f5ca28a0fd370140026de9845c ·clients/pgp/win32/PGPlog.dsw
8f43df 0a0dc88e948ff727f1ba8a87b405e9aafdd597ff ·clients/pgp/win32/PGPlog/ListMng.c
d70fa4 c9aa277378d46d2439cabe1ea8044d9c693ac783 ·clients/pgp/win32/PGPlog/ListMng.h
7189e1 c69cf8e98a73b31e5a2ad28835a6a36c73813385 ·clients/pgp/win32/PGPlog/OwnDraw.c
ade54d eefa1ae4c0dc15faac485364975cd5787a72c564 ·clients/pgp/win32/PGPlog/OwnDraw.h
ea5d90 1e4ba32bcac0d447fd5b2610d76c0c892d46c92a ·clients/pgp/win32/PGPlog/PGPlgVer.rc
5bb25f 70a2b361afff080aab78ecf968bc2e66c24cb614 ·clients/pgp/win32/PGPlog/PGPlog.rc
86123a 075f5970830dd338816532a1aa9ad5bcac141dca ·clients/pgp/win32/PGPlog/Precomp.h
af8320 e04d15fff33fe7af6e127b71f5e5cee3252b461e ·clients/pgp/win32/PGPlog/main.c
e94d9a 850b01516d7810dd257c0f35dd69819d35767eb1 ·clients/pgp/win32/PGPlog/res/badsig.i¶
d0a3ee co
9ee0da 56221605b1ee525b76a133cbe62d7c2b0bf77806 ·clients/pgp/win32/PGPlog/res/goodsig.¶
edc369 ico
28fb42 d405a31095c24fe46e8a199457b04ecc8a8f8706 ·clients/pgp/win32/PGPlog/res/logicon.¶
1cc369 ico
d9017f d241ea64b09951d0db04650d2db9fb31d2f06818 ·clients/pgp/win32/PGPlog/res/pgperror¶
97c240 .ico
d6a962 1dac325e5363c6f0744ab6610b23c44a84974437 ·clients/pgp/win32/PGPlog/resource.h
f4b85d ea90d9c886227a0644b30d218445d84dba058db5 ·clients/pgp/win32/PGPsc.dsp
dc0236 1984a4bd5d18dd7f3b9828f92abe28b4d2d121a9 ·clients/pgp/win32/PGPsc.dsw
5808fe 8fb17905f2e41213472aedfd8df317b7d520ffeb ·clients/pgp/win32/PGPsc/AddKey.c
77a103 646f43576124878772e3ef62c8ab74363e65ec3d ·clients/pgp/win32/PGPsc/ClVwClip.c
6d71e6 4a167ff0d50eec45481c6413652d8566c17930b2 ·clients/pgp/win32/PGPsc/ClVwClip.h
3823b2 82a87550a6b10cba6c96c69f67ab73bb3ddda7b6 ·clients/pgp/win32/PGPsc/Clipbrd.c
cc0107 3adfcab41985bf840eaf8ffc76f94f38595010e9 ·clients/pgp/win32/PGPsc/Clipbrd.h
6aceb5 2a8ba99bef207d5d3c10fe7e730ac17f0aad28a2 ·clients/pgp/win32/PGPsc/DDElog.c
--4729 000d1a16d2140110003 Page 19 of winhashes.asc
b591f5 c0cac5d64bec92376095d68d576e1e05a7913f7f ·clients/pgp/win32/PGPsc/PGPsc.rc
e36788 32ad17b24ad62ca4153c34dd371053dd9443edae ·clients/pgp/win32/PGPsc/PGPscVer.rc
94db0b 1626671f8447a1b2ff43906c4588a06965bb6ce5 ·clients/pgp/win32/PGPsc/Precomp.h
0b4132 98a3cc31fe370dee7658a779c95bfbf44413643d ·clients/pgp/win32/PGPsc/ProgVal.c
292467 5dc38e85849e241a79de27b7b734c8ca4cc840ec ·clients/pgp/win32/PGPsc/ProgVal.h
ab1ea7 18f1d49d234be1a0f3da482765ab8233c3113749 ·clients/pgp/win32/PGPsc/SaveOpen.c
a5e5ea 6177d11ae2bcb4a7ae012418f70c7cc01ab181ef ·clients/pgp/win32/PGPsc/Tempest.c
15bfb7 78c4cc634450177789f8977449c776b0a30429d2 ·clients/pgp/win32/PGPsc/Utils.c
015910 210de40f99fabd6bb98e59e5af0ab8b2f6b04c51 ·clients/pgp/win32/PGPsc/WFfat.c
b8a61b 4bdd87025c6b82e50276994e9a1fcd6a99431df1 ·clients/pgp/win32/PGPsc/WFfat.h
505049 2f2021fb22db0bc84ec5c13f7ea8366a125066a2 ·clients/pgp/win32/PGPsc/WFnt.c
f8107a 9a9388deebe6662f2d9d86d798dc84e3cde7d10b ·clients/pgp/win32/PGPsc/WFnt.h
937a53 f0d5e13dae3eb79a867f458bbf42764aadacca83 ·clients/pgp/win32/PGPsc/WFwiz.c
f66f4f 53f26609dddbe4123df4527adbfc0b726c25fdcc ·clients/pgp/win32/PGPsc/WFwiz.h
e6e14e d9746d11704e5b3b41da981c2fd74fe08d82e60c ·clients/pgp/win32/PGPsc/decrypt.c
9e5b4b 3702b750ad980cc9a0aff71a666866729e3f7f62 ·clients/pgp/win32/PGPsc/encrypt.c
dedf25 1802b1596c468b416352a67e18c149eacfb5e634 ·clients/pgp/win32/PGPsc/events.c
9e09e5 c453779a8356d7ed6da5c2f52773856d8c33a906 ·clients/pgp/win32/PGPsc/events.h
d4f3fc fd691191113d9aec73a1ac707ef6312653cc7589 ·clients/pgp/win32/PGPsc/main.c
9f6135 5069edf8bbb7c0134b21bf6759b498e8110eb025 ·clients/pgp/win32/PGPsc/pgpsc.def
82e45b 9a415a75c291ab1c288df77d33f37b795df614fa ·clients/pgp/win32/PGPsc/recpass.c
f4d377 8a2ef2fd38cd9229a35800470bc252d85359bf82 ·clients/pgp/win32/PGPsc/recpass.h
b3bb21 816cf1c3b9ccc86450e6c9d14f86d7d61adba24c ·clients/pgp/win32/PGPsc/res/aexpk.ico
413ae5 d0302fdec99bdbace9b106d8be7a2e4313f087a3 ·clients/pgp/win32/PGPsc/res/asc.ico
976d7f 462a9f14786b5256455571b2d10279f1f893b5fd ·clients/pgp/win32/PGPsc/res/fyeo.ico
aee420 51ce003a10b86ed0400483c315b8ddc7519c5f4c ·clients/pgp/win32/PGPsc/res/ma13x24.b¶
5da5ac mp
bec672 f45189609cbabf072d765f39d99b5c348be8a716 ·clients/pgp/win32/PGPsc/res/ma8x14.bmp
56a0c0 8b742402dfdd0832a7090cbdb8bf27c0a0cc110f ·clients/pgp/win32/PGPsc/res/mb13x24.b¶
b9a5ac mp
f84a6f 9fce2b4e97201b912cbd33d4e5d2214c71eb7be1 ·clients/pgp/win32/PGPsc/res/mb8x14.bmp
c9f46a d31bd134c3ad8a4845f0e775fa9754e71dfdb010 ·clients/pgp/win32/PGPsc/res/mc13x24.b¶
3aa5ac mp
3f493e 4fa92a6ec2dac6a1829eec8772d6c048e4e6e65b ·clients/pgp/win32/PGPsc/res/mc8x14.bmp
238b8b 1202e5f587ca0313299123848577535674bf02b6 ·clients/pgp/win32/PGPsc/res/md13x24.b¶
8ba5ac mp
50445f e7fc46057a722a83897d234010f6133f36937ba0 ·clients/pgp/win32/PGPsc/res/md8x14.bmp
a5cf8e 7fbc3461112fcca056ce067e28cbfe7c68203fae ·clients/pgp/win32/PGPsc/res/pgp.ico
e3293b 86ca4e78bb8544bc038367f2374793c9fcd41baa ·clients/pgp/win32/PGPsc/res/pgr.ico
800e9d e9f0d91119a16b935743136e27bdccd09aa655a3 ·clients/pgp/win32/PGPsc/res/prvkr.ico
5aa63e 4356dd8bef60c3cf9708c2adc643a0d5221b245a ·clients/pgp/win32/PGPsc/res/pubkr.ico
597635 2dac6a3f96a4a72f17d600005b1ad91ec758ff6a ·clients/pgp/win32/PGPsc/res/rnd.ico
a34e56 f49b2e064da536f12214a02083bd0ba8edb459be ·clients/pgp/win32/PGPsc/res/shf.ico
a75fde 563a7fabf93304c3bc518d8d840ce0a792cdb7ee ·clients/pgp/win32/PGPsc/res/sig.ico
40b974 8b8ee7cf6d32b8d7e247776060b9c07eafc8c497 ·clients/pgp/win32/PGPsc/res/wipesideb¶
c0b3a5 ar1.bmp
a732c4 1aab6158e9db43b08f182b25f2e49abc307d9c56 ·clients/pgp/win32/PGPsc/res/wipesideb¶
95ed2b ar24.bmp
d4ef2f f60b6b5680f1e66d48873204bba54b657556993a ·clients/pgp/win32/PGPsc/res/wipesideb¶
83a722 ar4.bmp
135c11 e609638cc4463894ed21536f175617498b7653cf ·clients/pgp/win32/PGPsc/res/wipesideb¶
9e96d6 ar8.bmp
df60a8 36a2e25b71240f8588e74ed0804f3544a0d9fcf8 ·clients/pgp/win32/PGPsc/resource.h
c7c97a 4b07ed5181a4ae73d07f8f0d13bfee57cb652880 ·clients/pgp/win32/PGPsc/saveopen.h
398ed8 cde0eb7f282b81c3e72e439e2063deb530dee093 ·clients/pgp/win32/PGPsc/wipe.c
0a369f a2b1cfa10ee6e8049719c92fcedf0c68cb65b9b3 ·clients/pgp/win32/PGPsc/working.c
8c2da0 7ee21b6d9d085a5fecd4871258f5f92350aff6ff ·clients/pgp/win32/PGPsc/working.h
fc70b1 de62d9e65dfb2e9725e041d1d82f444227addb98 ·clients/pgp/win32/PGPtools.dsp
2e3198 1338f97227999c92ae5769b7bb94b5a322748265 ·clients/pgp/win32/PGPtools.dsw
d19182 aba59ddf043609a213efff5d1f6e6f13eb5c3d59 ·clients/pgp/win32/PGPtools/PGPtlVer.rc
b75442 e034601014c8dde2197bae60364762d5fb9e0751 ·clients/pgp/win32/PGPtools/PGPtools.rc
14d4e5 8e0e5b2c526438478aa0afaf56850d313d74b90b ·clients/pgp/win32/PGPtools/Precomp.h
e0649d 1849d992c5ade1bb7addcf6b5d5bcb5203477e8d ·clients/pgp/win32/PGPtools/main.c
73b532 7856b30fefbfe93b51b8210b5d0724c47c18cff6 ·clients/pgp/win32/PGPtools/openfile.c
d96cdc e255069ef86009b3f095b843b7cff29c78b891a3 ·clients/pgp/win32/PGPtools/openfile.h
1ff076 f20f01797764e89d1fc84a46eba443e08dfbf2d7 ·clients/pgp/win32/PGPtools/proc.c
777c14 66072acb0b8c42ad0a1a9331e3d3e2fb3a532ab8 ·clients/pgp/win32/PGPtools/proc.h
662323 53150f708ab3fd91c101259226b110e192783bbc ·clients/pgp/win32/PGPtools/res/TOOLSI¶
973d2b CO.ICO
a7bc66 9f01914171edc353ebc4ab27c433772000694149 ·clients/pgp/win32/PGPtools/res/l4decv¶
b65b31 er.ico
d1bfb1 40a4be9b0caac4b7a57ef4b02ba6415f8b205f89 ·clients/pgp/win32/PGPtools/res/l4enc.¶
--08e2 000cf2ee11540110003 Page 20 of winhashes.asc
0ec369 ico
52873d 955cfcf8cf21b47f4df0ffb2f035805e0b54fbdd ·clients/pgp/win32/PGPtools/res/l4encs¶
38bc9c ig.ico
44251e aad01b6a8df035bdad34a9dac73917aaa97b2f66 ·clients/pgp/win32/PGPtools/res/l4keys¶
c1c240 .ico
70b4f0 94d1ac2fbffed5faa2c17e413bee86ae5475914f ·clients/pgp/win32/PGPtools/res/l4sig.¶
7bc369 ico
329c81 fa59b06324ec371ab18fd1c70836a14b1a605cdb ·clients/pgp/win32/PGPtools/res/l4wipe¶
5dc240 .ico
2fb3c0 4ca3105d8deba527ef607efc87b029639a10b1e0 ·clients/pgp/win32/PGPtools/res/l4wipe¶
9f1fbb v.ico
b29aca 5730d7e39e64f1bab01a2904dea66dfe97be1488 ·clients/pgp/win32/PGPtools/res/l8decv¶
705b31 er.ico
e44e26 f7de89bbb46797321a6bfd3b7f0c2ebe395b7073 ·clients/pgp/win32/PGPtools/res/l8enc.¶
14c369 ico
390a17 81f23929487625ecd8bb146dd4d528d7d1ecc8b1 ·clients/pgp/win32/PGPtools/res/l8encs¶
73bc9c ig.ico
990e3f 8e64c5212737fe645a073ceb1622b5991a797603 ·clients/pgp/win32/PGPtools/res/l8keys¶
30c240 .ico
23728a ad24697902fc367795d7b2a3fbb7b8316e2a2b26 ·clients/pgp/win32/PGPtools/res/l8sig.¶
c7c369 ico
a20e47 cb4c14571d9e41eeb4310341439afa326d418b5e ·clients/pgp/win32/PGPtools/res/l8wipe¶
f4c240 .ico
101add 4a1773c85f0754446050c8b19557adb5144177ec ·clients/pgp/win32/PGPtools/res/l8wipe¶
121fbb v.ico
48d330 e58d5f81eef698483c573c2f5e3e5ca5edd32e53 ·clients/pgp/win32/PGPtools/res/s4decv¶
855b31 er.ico
db9f13 4f8a6412f01c2861f675c5ee41f1b42f331a2584 ·clients/pgp/win32/PGPtools/res/s4enc.¶
efc369 ico
564a77 f34295921e84bd0eb8575c50e71d6293556a1cb2 ·clients/pgp/win32/PGPtools/res/s4encs¶
a5bc9c ig.ico
8ad966 8c21e0121984dc48957cd6b1197f9bf6c85281a8 ·clients/pgp/win32/PGPtools/res/s4keys¶
58c240 .ico
ddc810 6e611a35617f27a6c54b6a066a1b1f456909558d ·clients/pgp/win32/PGPtools/res/s4sig.¶
c6c369 ico
bc5bfa 01bf8d136325643dd109ec1db6f99a78d19f8fb3 ·clients/pgp/win32/PGPtools/res/s4wipe¶
0fc240 .ico
e2e8de ff0c49597ab4a976ec85f61617de4599daed0367 ·clients/pgp/win32/PGPtools/res/s4wipe¶
e91fbb v.ico
fe3a1e 75bdb6333876062f3045bd410914887741b1292e ·clients/pgp/win32/PGPtools/res/s8decv¶
d05b31 er.ico
8fc67c d94042276459f314d5ae58e443b620776b9c8c24 ·clients/pgp/win32/PGPtools/res/s8enc.¶
27c369 ico
716a9d 320d1885668a6e287d13cc74b957e4f2177e0fba ·clients/pgp/win32/PGPtools/res/s8encs¶
0ebc9c ig.ico
c1815a b1be3a8cd5dcffd7092ea780696af201d0bae120 ·clients/pgp/win32/PGPtools/res/s8keys¶
3fc240 .ico
a30bd2 7e25cf3108c1f9af8b307a74b8bca00f94f3f23a ·clients/pgp/win32/PGPtools/res/s8sig.¶
bec369 ico
1b165f 1e3b016130223cf609e64ad49726f77118ad4ba9 ·clients/pgp/win32/PGPtools/res/s8wipe¶
c8c240 .ico
2771eb 795ea62f7e62d733cb4647d0e6733cadb5fd4337 ·clients/pgp/win32/PGPtools/res/s8wipe¶
041fbb v.ico
d5d914 a3557800a3c5bf47441910b1174e1f8692284d30 ·clients/pgp/win32/PGPtools/resource.h
e7c12c 5c6816b4e69da2d953831a92eb1bedac131823bf ·clients/pgp/win32/PGPtray.dsp
b23814 ec9cbfc2e75934c5d0e364f20347390bd7ca4c11 ·clients/pgp/win32/PGPtray.dsw
7c9ec1 5e0032041ee4cf24dfe38fb6e00ac591d2d648bf ·clients/pgp/win32/PGPtray/EnclyptorPr¶
428421 oc.c
8de9c3 33f5dbea6938395e50f0b1db13e13d8c34e51c6f ·clients/pgp/win32/PGPtray/EnclyptorPr¶
a86089 oc.h
34b83d c4c28022b3fc2bb8060d4dad2cfc362455cc1f0e ·clients/pgp/win32/PGPtray/Main.c
9f10ab 3862eb66e3d457352ef6ec3e5cb7a98421e31380 ·clients/pgp/win32/PGPtray/PGPTrayVer.¶
3dd507 rc
449b80 7817aa7edd2ef1828d7f9bfd674174e49e3b70d1 ·clients/pgp/win32/PGPtray/PGPtray.rc
30e0da ba3e857fb1fcd5f39609813f6eefed1b45518173 ·clients/pgp/win32/PGPtray/Precomp.h
b88f89 4e54d8fc592ddaec464138adfe3622aa88124a82 ·clients/pgp/win32/PGPtray/RESOURCE.H
e270a3 35dfef9cf7156c8743a544cd4a649da32bfba83a ·clients/pgp/win32/PGPtray/Res/TASKBAR¶
ce6d1b .ICO
54a099 4611fad2c5f5c2478908dae4e77578f47f8aca38 ·clients/pgp/win32/PGPtray/Taskbar.c
57bc50 e451c3ada8cd85ead749d52649c48fa77b588212 ·clients/pgp/win32/PGPtray/Taskbar.h
140f86 71cf8e0bb7a8f584d7f8926da080a4aec56f27c8 ·clients/pgp/win32/Pgpwctx.dsp
cf179b c9ddd251e9a60622328bf220b8b2aea9d37d5486 ·clients/pgp/win32/Pgpwctx.dsw
--0224 00082030abc40110003 Page 21 of winhashes.asc
f7c11b 28cd5f9b118b881163df5239eb69f18d92bb9c52 ·clients/pgp/win32/TreeList.dsp
4c26ca 2fc301b82d191427ab9e719372781a2af4fedee3 ·clients/pgp/win32/TreeList.dsw
6b5ca8 ebb6fdaf34d4f93ba61e78b21bc3d3a7ca46b631 ·clients/pgp/win32/TreeList/TLMisc.c
38e097 f0cc58cd4d2e6602508d5804bce40713e83f9669 ·clients/pgp/win32/TreeList/TLMouse.c
89f0c3 21758bc3f28508157757e109ce9df37d9c850154 ·clients/pgp/win32/TreeList/TLMsgPrc.c
4bc03a 8f2dc209eb6b026f70e800fe55f7d258456022f4 ·clients/pgp/win32/TreeList/TLPaint.c
7727fc 1297d58ed8dd4fdb0ac63884c5c58a2bad936bfb ·clients/pgp/win32/TreeList/TLTree.c
79da4f 3821fd47004e8bc0c5d2c5f75ab6d40aa8ef03d3 ·clients/pgp/win32/TreeList/TLintern.h
73829f 3a63c5408432fc87b29cf86047090adf09f13c49 ·clients/pgp/win32/TreeList/TreeList.c
4e5445 967e54f43a71372bb52b0cd294a03b8bfbf7c5c0 ·clients/pgp/win32/pgpExch.dsp
7d121f 4d24d81ce671ae983e4eece21a70da68ea298109 ·clients/pgp/win32/pgpExch.dsw
b99dc0 f7a8bceb05e541741762c41fe876f06fcd7dd151 ·clients/pgp/win32/pgpExch/Attachments¶
766246 .cpp
4140b8 c0274a9af1b5bc7369dcfaa4a35b68a848be530e ·clients/pgp/win32/pgpExch/Commands.cpp
b05804 e966d02476d2d7b3f50855c94d52c9adfbdee197 ·clients/pgp/win32/pgpExch/Exchange.h
9c9816 0965837f54be4f9acfb1e5d04b07afd35d0fe8df ·clients/pgp/win32/pgpExch/GUIDS.CPP
d8fde9 cb4926e65e89204d3edc93fb62c1ea901e4bfc3a ·clients/pgp/win32/pgpExch/GUIDS.H
44699c 641299e3706e2c5383501a439d4f3b15563f1e7e ·clients/pgp/win32/pgpExch/Main.cpp
652b91 5c6d892d3b4e9087395df1f59fff7d1bead9b019 ·clients/pgp/win32/pgpExch/MessageEven¶
96d500 ts.cpp
b01a2b cba68949841cb620b0824cd07665cdf8e3da4189 ·clients/pgp/win32/pgpExch/MsgProps.cpp
16ea5e 1bdc978c4a11086c235dc8203aeef2fdec8ef293 ·clients/pgp/win32/pgpExch/PropertyShe¶
399160 ets.cpp
6814ee 89f164ec7e6b2d9b92b32a9293067e88b88804dc ·clients/pgp/win32/pgpExch/Recipients.¶
a8636f cpp
8141fa cf363c87bed76e55c7aa3b6b157db542cc64a6f6 ·clients/pgp/win32/pgpExch/Recipients.h
14dc5b 70f027c92d1c41c97c3cb2d85dfcffa97f581458 ·clients/pgp/win32/pgpExch/Res/BUTTON.¶
6baa65 BMP
a4b733 4ec56fa95e23840e438bdd4c6b4b13942a78ce1c ·clients/pgp/win32/pgpExch/Res/Tboth.b¶
e4a5ac mp
e91a51 9356617e6230817de68c6d4bf7989f0292bf0a21 ·clients/pgp/win32/pgpExch/Res/Tdecryp¶
ffd1ba t.bmp
3bf992 a9aa7aff9114a9304bcb4aeab15ad59c230538ac ·clients/pgp/win32/pgpExch/Res/Tencryp¶
24d1ba t.bmp
eaa0fc bd5540a3e6df0ed6289f4694598bb5a67c67ea60 ·clients/pgp/win32/pgpExch/Res/Tpgpkey¶
d6cd6b s.bmp
0d5677 b6e0a0db5a6b43511f1b3e7d4711d91c406e475c ·clients/pgp/win32/pgpExch/Res/Tsign.b¶
d0a5ac mp
300be6 fa7146118873b609ea41919dd492368ea44fbf4f ·clients/pgp/win32/pgpExch/Res/addkey.¶
fb053e bmp
4e9774 e413435139d728e72bf7a7a30b2c9cb9760e34a1 ·clients/pgp/win32/pgpExch/Res/both.bmp
473b53 6a70a1e6e17d9d172e9c20b482d59ac8b0a06ce3 ·clients/pgp/win32/pgpExch/Res/decrypt¶
280417 .bmp
ce8112 c29cdb42a4abecd4bc648bde79243505def41971 ·clients/pgp/win32/pgpExch/Res/encrypt¶
240417 .bmp
036b9a 0e4b2cb8956bdbf646064ac6811f0eaebc34bf8b ·clients/pgp/win32/pgpExch/Res/pgpkeys¶
310417 .bmp
6d7dbf ac5d0da292ffa6bcd19ccc2730dc7e1856fabd1f ·clients/pgp/win32/pgpExch/Res/pgpnow.¶
29053e bmp
e9a043 8206444f699157234bb1be48e0f5a4b39fe2bb9a ·clients/pgp/win32/pgpExch/Res/read.bmp
631cf8 0004609fe876369ce0dab9e8438f873f80e3b619 ·clients/pgp/win32/pgpExch/Res/send.bmp
c8a2db a0bc10e824f1a8fb792330c9374d09f0624174c1 ·clients/pgp/win32/pgpExch/Res/sign.bmp
340ab7 140df7b84ac84b28bdaddedce20359e001b42f03 ·clients/pgp/win32/pgpExch/STDINC.H
a4e261 79f44470b267f5c4fc5cd7824b7a4e2dcaebbc06 ·clients/pgp/win32/pgpExch/STDNOTE.CPP
584fd8 dabc116979c3a63e3d96aa39f227ccb595c8500f ·clients/pgp/win32/pgpExch/UIutils.cpp
03ed6e 22eb47113409c88be16f2fbd25efc3169c9cd52d ·clients/pgp/win32/pgpExch/UIutils.h
21442f 6e4e36852710523084a082f515a60aedda5a352f ·clients/pgp/win32/pgpExch/outlook.h
2e2af7 2370b48997a7ca1ebaba1a369b6752e0fb02c44b ·clients/pgp/win32/pgpExch/pgpExch.DEF
306765 d5771cfd5a851e024b62c78737c7ee66f3769295 ·clients/pgp/win32/pgpExch/pgpExch.RC
562811 b850ae433233fca331404e06f11758dec1a0f47b ·clients/pgp/win32/pgpExch/pgpExch.reg
515116 318f891e75a9f68a2e8548eb56e9a32f8cf4dcbc ·clients/pgp/win32/pgpExch/pgpExchVer.¶
21d507 rc
6f6495 ef84871144effeac801de0a7ce35c475397b71e7 ·clients/pgp/win32/pgpExch/readme.txt
7c7420 5ad8481d168b1c0720cbd8cead6c9243f8c46fc2 ·clients/pgp/win32/pgpExch/resource.h
dacd1d 25927ce383777e46aa5d2e819d8ecf2c88baca17 ·clients/pgp/win32/shared/AddKey.c
04b996 a05e82fcb5a993f0cb610aefabe02d87bc883db3 ·clients/pgp/win32/shared/AddKey.h
8a0946 55565c38e3ba1cdd9a81b7ddb575fe2a02166965 ·clients/pgp/win32/shared/BlockUtils.c
603ae5 be008a957917413797161c1f87943b644a3d2eba ·clients/pgp/win32/shared/BlockUtils.h
d37367 313f9f8d0b387e3d7a437f3642ce8eaeaf044ec4 ·clients/pgp/win32/shared/DecryptVerif¶
225061 y.c
78009b 172169bbd1650fbe599b9a688e38dae6e32101f7 ·clients/pgp/win32/shared/DecryptVerif¶
82b4c9 y.h
--d370 00064e3249940110003 Page 22 of winhashes.asc
0d23e0 af8e9b282aee3c422f5dffe700774879cb476b86 ·clients/pgp/win32/shared/EncryptSign.c
c9b739 e2ff3d47bc36cc9f4e94434bd00b11b001661955 ·clients/pgp/win32/shared/EncryptSign.h
22b333 b6de0b1b35e2f0e45b4d4d4f420b2f7418362cfe ·clients/pgp/win32/shared/Prefs.c
491d39 c8b969c833feef7f4599f121d300895179e02e51 ·clients/pgp/win32/shared/Prefs.h
0c606d 2fc27b91a93da3ff465eb9227ed6072008c5ae89 ·clients/pgp/win32/shared/RichEdit_IO.c
472617 3905025b22351f5e79d9efd16744e8856cbb35a1 ·clients/pgp/win32/shared/RichEdit_IO.h
e8a9b4 fb13fb86f22c56776fe4e0e681955fad490e942f ·clients/pgp/win32/shared/SharedString¶
6f6867 s.h
8b4a48 efb85f09cbe7ce56c18db3da0b3fddea8f3eee36 ·clients/pgp/win32/shared/SharedString¶
85fc29 s.rc
760c3b 84975d65455706566495b54e8f4d1b616c0daa5a ·clients/pgp/win32/shared/SigEvent.c
0b5409 a93e9d3edbb478ed95b66d6687f7f4df99b265b2 ·clients/pgp/win32/shared/SigEvent.h
8fbf19 f151b0af1e6a1d119377a39657a95b78cbf352e1 ·clients/pgp/win32/shared/Verification¶
81d770 Block.c
96bdff 1115424826d5c1e37fd9df556d2fdb308132ce85 ·clients/pgp/win32/shared/Verification¶
c633d8 Block.h
afae6c 2f9495caa8fecaa4d65f48c158dec20a4cacbf00 ·clients/pgp/win32/shared/Working.c
3a47b2 600b04486b28dd4d19969dcfa27da48ee74d03a7 ·clients/pgp/win32/shared/Working.h
5d8638 a86d32c60a3103e7a4d4c0c81043c5a44924b4cb ·clients/pgp/win32/shared/Working.rc
12876a 415e03f29d29e2236910dc2dc157ebab7524dd02 ·clients/pgp/win32/shared/WorkingResou¶
d59174 rce.h
8c542d 2aa8d0aa67344b21a41ff43824a0397e5108739b ·clients/pgp/win32/shared/images24.bmp
0f0a3c fb544f1c9502bf3795b3c2993b30536ac34fe764 ·clients/pgp/win32/shared/images4.bmp
f884a8 98c7effebb51787f3fc2456a46380041d5ec5b6e ·libs/network/ldaplib/win32/liblber.dsp
73b9b6 62a0a832c7ad1deb3a6b0734aeab294e395a03d3 ·libs/network/ldaplib/win32/libldap.dsp
49e58a ddf335b4f7651c14dedab9e84af363f0540a0791 ·libs/pfl/win32/InstallDll/install.cpp
b67ac9 f5e103f637e5ac7b9d4aa0f92d8e0fdc4dcb5d5c ·libs/pfl/win32/InstallDll/install.def
a0a0ba 7471af7477cdf271f7ae03d7ed44d05bcbafe615 ·libs/pfl/win32/InstallDll/install.dsp
349f65 a86a8175a6be77663bc68f414d4234d16947756d ·libs/pfl/win32/InstallDll/install.dsw
1af6f8 57c8569bee86437fa781eb5ca7f0cd15690eca1a ·libs/pfl/win32/SecureMemory/win95/Ins¶
50f141 tall/PGPml95_Install.txt
6013d9 b741e555546bd4d8b02b27e4d8901f8caaab134e ·libs/pfl/win32/SecureMemory/win95/PGP¶
1f95b2 memlock.dsp
0bb497 85c181df3b1a9b47c22bbde7b120c3361fb33f1c ·libs/pfl/win32/SecureMemory/win95/PGP¶
73d8ba memlock.dsw
6dfc7a cdfd10a2165a3ea1934e144d93d75dde3593fe5d ·libs/pfl/win32/SecureMemory/win95/PGP¶
2c2dc5 memlock.mak
c7c368 50abdf07f1f7831fe707d2ab3edfdabc41b0bf6f ·libs/pfl/win32/SecureMemory/win95/Sou¶
ea9ce0 rce/pgpML.rc
acb56a e2b3d9929bca240da2d327cca3b4c8d17397c72f ·libs/pfl/win32/SecureMemory/win95/Sou¶
b0ddc7 rce/pgpMLdevdcl.asm
55f64c 830930fb9bae5eaee8387d62f9a068302c422f82 ·libs/pfl/win32/SecureMemory/win95/Sou¶
2d8981 rce/pgpMemLock.c
780d7d 67a0dde5107f19e91c6a7eee8065240b3474e5c2 ·libs/pfl/win32/SecureMemory/win95/Sou¶
9f0aa9 rce/pgpMemLock.def
280cad 20c0d7cf3825994701a7181e86db44e90fac42eb ·libs/pfl/win32/SecureMemory/win95/Sou¶
f8424a rce/pgpVer.h
0f87d2 6b96a1f9140a856269a96f49469f19e778024d63 ·libs/pfl/win32/SecureMemory/winNT/DIRS
ed1add d07e7ae3c6a273b101aede709bac5a53b624c34b ·libs/pfl/win32/SecureMemory/winNT/Ins¶
365300 tall/PGPmemlock.ini
0a25a4 fdc18df606c36af14f563a3247a0fa5a57ce2c0e ·libs/pfl/win32/SecureMemory/winNT/Ins¶
32ed33 tall/PGPmlNT_Install.txt
42d894 107c94a244cebdf463ebbd962a2bb7431df11af6 ·libs/pfl/win32/SecureMemory/winNT/Sou¶
0fd075 rce/MAKEFILE
74d32d 266c27e0369165ea696222c6ccc5ef5b8c9ea2ae ·libs/pfl/win32/SecureMemory/winNT/Sou¶
9abd38 rce/SOURCES
1563f0 47d10252d2d95f850397c0dc64e4aa7459ae2fb8 ·libs/pfl/win32/SecureMemory/winNT/Sou¶
018981 rce/pgpMemLock.c
5047ec 2bec856fa7e76f4c20f33b8e469c0bd35f13fcd0 ·libs/pfl/win32/SecureMemory/winNT/Sou¶
815756 rce/pgpMemLock.rc
8b27ca a70e0a0cb406948b10c059885d5f7077d8966f23 ·libs/pfl/win32/SecureMemory/winNT/Sou¶
9b424a rce/pgpVer.h
116d00 d226b91da91b09316b4d770f16a863cb89ac189b ·libs/pfl/win32/pflCommon/pflCommon.dsp
9846dd c19269d37eab6c311c079b37f35a544e9f2aa280 ·libs/pfl/win32/pflCommon/pflCommon.dsw
7e15cb 9ed9af6e4dc923e64e8a6d404318584722ff4fb4 ·libs/pfl/win32/pgpAsyncDNS/pgpAsyncDN¶
8c039c S.c
d71684 dd01c22ef7e3be6a548a526e7ee56cb059c03d89 ·libs/pfl/win32/pgpAsyncDNS/pgpAsyncDN¶
bbe734 S.h
a2defe 9be0e2ddf8fa2c72f09a0b90127ca8d7e5379724 ·libs/pfl/win32/pgpMemLockWin32.h
0ed955 df5e05dc024854e9aa1c7939afd13a9979fbe159 ·libs/pfl/win32/pgpPFLConfig.h
3c36b4 c45e4017c8fba1476d5ff3fdcf7b89d0de02fc38 ·libs/pgpcdk/priv/networklib/pgpsocket¶
64423a s/win/src/Makefile
--5297 000ac72a5ab40110003 Page 23 of winhashes.asc
5c15eb 8873269ca7f8a9030242c7c10d3043e8ee35abbd ·libs/pgpcdk/priv/networklib/win32/PGP¶
2fc0e4 sdkNetworkLibDLLMain.c
608fa6 7e1864485a3ea59b3a8ea81451dd394ebd9f6d88 ·libs/pgpcdk/priv/networklib/win32/PGP¶
e2244c sdkNetworkLibDLLMain.h
b80ae5 a33473abfb91ab4bec1b1d9e6949eb0367ba4651 ·libs/pgpcdk/win32/PGPcdk/PGPcdk.def
ac84bf ef579b4fd161ba01aa6447dac15a7a3d1087dd0f ·libs/pgpcdk/win32/PGPcdk/PGPcdk.dsp
848852 6f09b86b7224903409075d299b6443b54a0c9360 ·libs/pgpcdk/win32/PGPcdk/PGPcdk.dsw
68699b 36269ab2fd183f6c38290ecf43916c0f520ca894 ·libs/pgpcdk/win32/PGPcdk/pgpsdk.rc
089841 7e45fd617d988caccf97bc31b6fc37bb44dee484 ·libs/pgpcdk/win32/PGPcdk/resource.h
7859c3 56c9cd3a94d8212b6124db3054572b1a15abda2a ·libs/pgpcdk/win32/PGPsdkNetworkLib/PG¶
2ed9fc PsdkNetworkLib.def
b95fbb 0727ba73b2c777b69f93425597fda03fae1b32cc ·libs/pgpcdk/win32/PGPsdkNetworkLib/PG¶
704bf1 PsdkNetworkLib.dsp
fe03c7 188c13eccb062c562b4f4b70f545f94feec7f1a7 ·libs/pgpcdk/win32/PGPsdkNetworkLib/PG¶
c706f9 PsdkNetworkLib.dsw
01868d ef37efbe5e0d1df8a8da41b5c5a21f2eee339d09 ·libs/pgpcdk/win32/PGPsdkNetworkLib/PG¶
4ba7d3 PsdkNetworkLib.rc
33961f 0951ae21652287ec6edacf39e72a89d570de9205 ·libs/pgpcdk/win32/PGPsdkNetworkLib/re¶
1d2ae1 source.h
4d1e1c 0e5784874b5f9c598e66ca5a08dc53ba5cee4ad4 ·libs/pgpcdk/win32/PGPsdkUI/PGPCL.h
7773f0 7dbfdea168ed79cafdce41280ea30a1c3d13f1da ·libs/pgpcdk/win32/PGPsdkUI/PGPCollect¶
c89817 RandomDataCL.cpp
8f65e5 9717964e0b9635da645b229c51da25f5f3a412d4 ·libs/pgpcdk/win32/PGPsdkUI/PGPCollect¶
8d5698 RandomDataDialog.cpp
927958 79a09267b430b3bf442e99d502e27a0c0e5f05c1 ·libs/pgpcdk/win32/PGPsdkUI/PGPKeyServ¶
5752d2 erDialogs.cpp
36c3f2 6b1a91b696d5d6f5ff995b3c90b2ab90c6b88405 ·libs/pgpcdk/win32/PGPsdkUI/PGPOptions¶
badb03 Dialog.cpp
06bea6 ff206b57efbdb122ecd97138efd21415641b22b0 ·libs/pgpcdk/win32/PGPsdkUI/PGPPassphr¶
24934b aseCL.cpp
0a2368 5c322b19c10accfb32f54432b103b60e07690aaa ·libs/pgpcdk/win32/PGPsdkUI/PGPPassphr¶
653d1c aseDialog.cpp
eb5b60 7d16821858faa5d34e2fa4fbd9a8336cdba3b1d7 ·libs/pgpcdk/win32/PGPsdkUI/PGPRecipie¶
c9510a ntDialog.cpp
69a389 60a01d45cb277ee4279a95026685820f578100ad ·libs/pgpcdk/win32/PGPsdkUI/PGPsdkUI.d¶
55a22f ef
a22c53 24c369d52ad84880f726c6d6ec910b2ff4465a56 ·libs/pgpcdk/win32/PGPsdkUI/PGPsdkUI.d¶
673022 sp
5c5323 f29011ea008b3ca9d185f0e4ad75d58c976342ba ·libs/pgpcdk/win32/PGPsdkUI/PGPsdkUI.d¶
b67d2a sw
d9f8e6 bf5421adab83a6bc716c74b38c3607be47226aed ·libs/pgpcdk/win32/PGPsdkUI/PGPui.rc
7f6653 d95643ac643b4e1131facc60ed33e78edce86341 ·libs/pgpcdk/win32/PGPsdkUI/PGPui32.h
02a4ca df09d0e074fc0ca0f6d4b4486ad81bf04aa0490e ·libs/pgpcdk/win32/PGPsdkUI/PGPuiVer.rc
614196 88e737d185fe57aa76f728881ad4c4295eb267a0 ·libs/pgpcdk/win32/PGPsdkUI/RDdrag.c
41f241 4392c9c12a68e184634aa7ca18c55af000bc897f ·libs/pgpcdk/win32/PGPsdkUI/RDdrag.h
157411 ea63fd112ad0d7da20e2e53771d94e8d660def72 ·libs/pgpcdk/win32/PGPsdkUI/RDdraw.c
77924d 0fab71560d46a98327e740fed045f6c2ce992a6f ·libs/pgpcdk/win32/PGPsdkUI/RDdraw.h
c127e1 6056e5a68911aad2ffa52d566f115c2a91abf1c9 ·libs/pgpcdk/win32/PGPsdkUI/RDkeyDB.c
5d4c7c efed3b56a1cc79965a8d8ab7f43d779049c27871 ·libs/pgpcdk/win32/PGPsdkUI/RDkeyDB.h
d23af9 f8bf200f2e5834edf69d864a379f3ea48ef79e9b ·libs/pgpcdk/win32/PGPsdkUI/RDlstmng.c
ffe795 41f3e2f02c5ca70caff7cb69e65f9f00db643df1 ·libs/pgpcdk/win32/PGPsdkUI/RDlstmng.h
1e613c f4ceab6acb85293d3ccc960f56594eb2f23af326 ·libs/pgpcdk/win32/PGPsdkUI/RDlstsrt.c
1cf924 65a1fefeb049e67e0b951573bf0a5076174ce283 ·libs/pgpcdk/win32/PGPsdkUI/RDlstsrt.h
c4d822 4d7be6f2812455b8b8bdb1ee925e83c5051d915a ·libs/pgpcdk/win32/PGPsdkUI/RDlstsub.c
9a0de3 1eb2669076eab5beb32c78a97f468f7b57a0940f ·libs/pgpcdk/win32/PGPsdkUI/RDlstsub.h
2893b3 bb3268849e6e1d8a85d4964eebdc2f77921d99b5 ·libs/pgpcdk/win32/PGPsdkUI/RDmain.c
ee9f7d 70a7b299c37cbc5768411fc311754eddcb8b5f8d ·libs/pgpcdk/win32/PGPsdkUI/RDmove.c
a61e49 dbd2ecbed38084ce9751bee1d1a3f21ccf999f83 ·libs/pgpcdk/win32/PGPsdkUI/RDmove.h
fa4bd9 5f71dcdd0d476ca8b5a6e17c440314d85a54c527 ·libs/pgpcdk/win32/PGPsdkUI/RDprecmp.h
3bf601 1cdba72b20fdbbd33d97aee57ddf130e9bcfa225 ·libs/pgpcdk/win32/PGPsdkUI/RDproc.c
881d48 4c5bce613c25faeebd07d9198c2ca2a67ca26aba ·libs/pgpcdk/win32/PGPsdkUI/RDproc.h
edde3c 84ca425ef1ff98b85ea18f504a6acebd6b801da7 ·libs/pgpcdk/win32/PGPsdkUI/RDserver.c
98fe02 e99a8dcd4fb8a7ad6319b2083ef37827e7ca72a9 ·libs/pgpcdk/win32/PGPsdkUI/RDserver.h
1219bf d385e54f8ef4b4f88c75874bd9ecbe30c6831c50 ·libs/pgpcdk/win32/PGPsdkUI/RDstruct.h
86f4ee 53150f708ab3fd91c101259226b110e192783bbc ·libs/pgpcdk/win32/PGPsdkUI/Res/dlgico¶
ab7c53 n.ico
c67ab6 1eff36b0af7e9e8ae53542f4b21fe699dd13b977 ·libs/pgpcdk/win32/PGPsdkUI/Res/images¶
94329a 24.bmp
396532 3c7cb5f1d47cbd3cb1478df57ba5b731d6c4db6a ·libs/pgpcdk/win32/PGPsdkUI/Res/images¶
5ad36b 4.bmp
49fe72 1bb2b5976816fae20990b1a12e86a32973d125e2 ·libs/pgpcdk/win32/PGPsdkUI/UIhelp.h
ace39b 2bd8315b8b0a217835c5a250f3181e3b492b08da ·libs/pgpcdk/win32/PGPsdkUI/pgpCLUtils¶
--7b92 001d33bd7b640110003 Page 24 of winhashes.asc
9cf347 .c
565078 683cf7094693f9701ccce870a53409823d7df84b ·libs/pgpcdk/win32/PGPsdkUI/pgpCLUtils¶
3c17ef .h
edb308 b3a412cb38b72127bf738c2b3025b3b5a965ea38 ·libs/pgpcdk/win32/PGPsdkUI/pgpImage.h
ae955b cbba6eb173a2292d416c85fb584bc665a90cade3 ·libs/pgpcdk/win32/PGPsdkUI/pgpKB.h
22996f 353493641d0161f0f3ee158df96e7fb09cc59b30 ·libs/pgpcdk/win32/PGPsdkUI/pgpKBNT.c
f9407f faacfe5a35c116cf39bdea1a0445a9ec444e8ad6 ·libs/pgpcdk/win32/PGPsdkUI/resource.h
b76ff1 cf461724411f62b7a0a90d34abcad720e8d2f1b4 ·libs/pgpcdk/win32/pgpConfig.h
fa2940 c6b5c49af48c6096bd52475fa69332363030fd37 ·test-file
3daf5a
32e38f -----BEGIN PGP SIGNATURE-----
e4d11c Version: PGP 6.0.2
1eaf5a
467f15 iQA/AwUBNk314ROghfzXeyCUEQJVawCfcom/WAkAYbFjNqNUb4GMaAGwbM8Anipg
80e05a OXYrtHk48UYEBuEKILic/ouX
fe0660 =Uv1O
d3e726 -----END PGP SIGNATURE-----
--649e 001f85379ef40110004 Page 1 of Makefile
3f8202 LIBTARGET = libpgpsockets.a
5c106d OBJS = PGPsockets.o
24af5a
45509a LIBS = -lsocket -lnsl·
adaf5a
ded65c CC= gcc
18afd5 OPT= -O -g
d64488 DEFINES=-DPGP_DEBUG=1 -DPROTOTYPES -D_REENTRANT
74401b LOCALINCLUDES= -I../../../../../pub/include\
3f6d19 -I../../../../../unix\
5eb31c -I../../../../../../pfl/common\
3efd2e -I../../../../../../pfl/unix
9caf5a
75af8b CFLAGS=¤$(OPT) $(OSDEF) -W -Wshadow -Wpointer-arith -Wmissing-prototypes\
f7c572 ¤   -Wwrite-strings -DHAVE_CONFIG_H $(DEFINES) $(LOCALDEFINES) \
dcc181 ¤   $(LOCALINCLUDES) $(CCOPTS)
c1af5a
ef66d7 all:: $(LIBTARGET) DONE
61af5a
e01f9c $(LIBTARGET): $(OBJS)
8d6182 ¤   $(AR) ruv $(LIBTARGET) $(OBJS)
1daf5a
6fda15 DONE:
22c786 ¤   @set -x; echo $(OBJS) > $@
f3af5a
9449c8 clean:
b7c47a ¤   rm -f $(OBJS) $(LIBTARGET)
04af5a
af89be # These empty targets are to keep the sdk build happy
1ee95d headers:
31661d depend:
f8af5a

--f359 0016ff4daf040110005 Page 1 of PGPsdkNetworkLibDLLMain.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
0767c5 ¤
93750e ¤   $Id: PGPsdkNetworkLibDLLMain.c,v 1.2.10.1 1998/11/12 03:22:55 heller Exp $
32f7f7 ____________________________________________________________________________*/
dfaf5a
3f5655 #include <windows.h>
3caf5a
5cd8f9 #include "PGPsdkNetworkLibDLLMain.h"
83af5a
78af5a
36af5a
860b4b CRITICAL_SECTION¤   ¤   gKeyServerInitMutex;
cc345a CRITICAL_SECTION¤   ¤   gSocketsInitMutex;
f8af5a
e5af5a
08aedf ¤   BOOL APIENTRY
258e7b DllMain(
b768ba ¤   HANDLE¤ hModule,·
2f2eb4 ¤   DWORD¤  ul_reason_for_call,·
91a6df ¤   LPVOID¤ lpReserved)
74bb36 {
b59935 ¤   switch (ul_reason_for_call)¤{
127e00 ¤   ¤   case DLL_PROCESS_ATTACH:
2b5b34 ¤   ¤   {
e0398b ¤   ¤   ¤   InitializeCriticalSection(&gKeyServerInitMutex);
a20b15 ¤   ¤   ¤   InitializeCriticalSection(&gSocketsInitMutex);
e70fe4 ¤   ¤   }
402f68 ¤   ¤   break;
67af5a
4baf5a
f7c37d ¤   ¤   case DLL_PROCESS_DETACH:
f05b34 ¤   ¤   {
05c6dd ¤   ¤   ¤   DeleteCriticalSection(&gKeyServerInitMutex);
679258 ¤   ¤   ¤   DeleteCriticalSection(&gSocketsInitMutex);
760fe4 ¤   ¤   }
242f68 ¤   ¤   break;
1b6fe7 ····}
62af5a
a98011 ····return TRUE;
6fefe6 }
--59b6 001fadcab2040110006 Page 1 of PGPsdkNetworkLibDLLMain.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
0767c5 ¤
4a6fbf ¤   $Id: PGPsdkNetworkLibDLLMain.h,v 1.2.10.1 1998/11/12 03:22:56 heller Exp $
1ef7f7 ____________________________________________________________________________*/
61af5a
381092 #ifndef Included_PGPsdkNetworkLibDLLMain_h
25ae98 #define Included_PGPsdkNetworkLibDLLMain_h
5baf5a
84c5d5 #include "pgpBase.h"
3baf5a
8299c6 PGP_BEGIN_C_DECLARATIONS
facbcf #if PRAGMA_IMPORT_SUPPORTED
5db981 #pragma import on
517454 #endif
e7af5a
4f01f7 extern CRITICAL_SECTION¤¤   gKeyServerInitMutex;
9ac801 extern CRITICAL_SECTION¤¤   gSocketsInitMutex;
e9af5a
93cbcf #if PRAGMA_IMPORT_SUPPORTED
eb2ced #pragma import reset
d67454 #endif
341254 PGP_END_C_DECLARATIONS
1caf5a
fa7454 #endif

--e8cd 000919f452340110007 Page 1 of pgpConfig.h
bc38e5 /*
489c11 ·* pgpConfig.h -- Configuration for the PGPsdk. ·This file contains
4073e3 ·* the configuration information for the PGPsdk, and it should be
cbad69 ·* included in all PGPsdk source files.
e8775e ·*
cff2f6 ·* $Id: pgpConfig.h,v 1.13 1997/09/30 21:03:13 lloyd Exp $
43495d ·*/
31af5a
361f84 /* Define to empty if the compiler does not support 'const' variables. */
245ef0 /* #undef const */
dbaf5a
619e5c /* Define to `long' if <sys/types.h> doesn't define. ·*/
01d8a4 /* #undef off_t */
5caf5a
5a9bfa /* Define to `unsigned' if <sys/types.h> doesn't define. ·*/
3dc6cb /* #undef size_t */
bdaf5a
c5af5a
55ae33 #ifndef Included_pgpConfig_h¤   /* [ */
1ed3cd #define Included_pgpConfig_h
3aaf5a
76e610 #include "pgpPFLConfig.h"
17af5a
80af5a
62af5a
c9af5a
39af5a
14ebfc #ifndef Included_pgpPFLConfig_h¤/* [ */
d3af5a
0301a3 #define HAVE_STDARG_H¤  1
a23509 #define HAVE_STDLIB_H¤  1
020ba7 #define HAVE_UNISTD_H¤  0
3ec0d0 #define HAVE_USHORT¤¤   0
541ef0 #define HAVE_UINT¤  ¤   0
fef6c1 #define HAVE_ULONG¤ ¤   0
77a26e #define NO_LIMITS_H¤¤   0
ce45ad #define NO_POPEN¤   ¤   1
3caf5a
0dc32f #if defined( _MSC_VER )
354725 #define PGP_HAVE64¤ ¤   1
919b9c typedef __int64¤¤   ¤   ¤   PGPInt64;
6a6263 typedef unsigned __int64¤   PGPUInt64;
3caf5a
433d96 #elif ·defined( __MWERKS__ )
ebaf5a
165efd #define PGP_HAVE64¤ ¤   0
0a67c5 ¤
3d7454 #endif
58af5a
d2af5a
e1af5a
d62574 #endif /*Included_pgpPFLConfig_h*/¤ /* ] */
50af5a
e6af5a
89249f /* Checks for various types */
331196 #define HAVE_UCHAR 0
54af5a
e1e87a /* Define if you have the ANSI C header files. ·*/
992483 #define STDC_HEADERS 1
adaf5a
004595 /* Checks for various specific header files */
b87984 #define HAVE_FCNTL_H 1
2f5370 #define HAVE_LIMITS_H 1
084911 #define HAVE_SYS_IOCTL_H 0
cc9777 #define HAVE_SYS_TIME_H 0
fff0a5 #define HAVE_SYS_TIMEB_H 1
ab9e1e #define HAVE_SYS_PARAM_H 0
08af5a
76a3c4 /* Check if <sys/time.h> is broken and #includes <time.h> wrong */
21f220 #define TIME_WITH_SYS_TIME 0
f5af5a
91175d /* Checks for various functions */
--4e4b 00173c8f31c40110007 Page 2 of pgpConfig.h
d6ac4d #define HAVE_GETHRTIME 0
1e6e78 #define HAVE_CLOCK_GETTIME 0
9f2326 #define HAVE_CLOCK_GETRES 0
2fc188 #define HAVE_GETTIMEOFDAY 0
fcb98b #define HAVE_GETITIMER 0
90a925 #define HAVE_SETITIMER 0
584cac #define HAVE_FTIME 1
0342b1 #define HAVE_MKSTEMP 0
9daf5a
1baf5a
66174a #if ·defined( __MWERKS__ )
5faf5a
2baf70 #define PGPTTYE¤ /* nothing */
ea67c5 ¤
c351d8 #elif defined( _MSC_VER )
5aaf5a
4f0146 /* Tags for exported functions, needed for dynamic linking on some platforms */
2aaf70 #define PGPTTYE¤ /* nothing */
0daf5a
307454 #endif
29af5a
e0af5a
abaf5a
73ab8f #endif /* ] Included_pgpConfig_h */
--fc27 0005f5ff4d640110008 Page 1 of PGPcdk.def
9265af ; PGPsdk.def : Declares the module parameters for the DLL.
eeaf5a
3240a4 DESCRIPTION ·'PGP Software Development Kit'
f1af5a
9cef2b EXPORTS
cb2b71 ¤   PGPCompareKeys
014df4 ¤   PGPCompareUserIDStrings
405daa ¤   PGPGetIndexedAdditionalRecipientRequestKey
8dc54a ¤   PGPGetIndexedRevocationKey
da5f87 ¤   PGPGetTime
824a1d ¤   PGPGetStdTimeFromPGPTime
0c9ff8 ¤   PGPGetPGPTimeFromStdTime
84197c ¤   PGPGetYMDFromPGPTime
2baf5a
e6d0ed ¤   PGPNewKeySet
a4e06a ¤   PGPNewEmptyKeySet
4026ef ¤   PGPUnionKeySets
6c09a3 ¤   PGPNewSingletonKeySet
424a64 ¤   PGPOpenDefaultKeyRings
9ef4e6 ¤   PGPOpenKeyRingPair
6ea178 ¤   PGPCommitKeyRingChanges
1db884 ¤   PGPRevertKeyRingChanges
9aae3e ¤   PGPReloadKeyRings
c6b794 ¤   PGPCountKeys
c997b4 ¤   PGPIncKeySetRefCount
ddd3d5 ¤   PGPFreeKeySet
f5f54d ¤   PGPKeySetIsMutable
49e6c1 ¤   PGPKeySetNeedsCommit
71f16e ¤   PGPAddKeys
b6e371 ¤   PGPRemoveKeys
aa3a93 ¤   PGPRevokeKey
6faf5a
52a808 ¤   PGPDisableKey
967011 ¤   PGPEnableKey
7c2529 ¤   PGPChangePassphrase
01fc10 ¤   PGPChangeSubKeyPassphrase
9bedae ¤   PGPRemoveUserID
9ec864 ¤   PGPAddUserID
77d3c9 ¤   PGPSetPrimaryUserID
217006 ¤   PGPGetSigCertifierKey
1bb6c8 ¤   PGPRevokeSig
6f3db3 ¤   PGPRemoveSig
c09d0d ¤   PGPCountAdditionalRecipientRequests
d2d32e ¤   PGPCountRevocationKeys
2ac4dc ¤   PGPSetKeyTrust
3e987e ¤   PGPGetKeyBoolean
7a6f63 ¤   PGPGetKeyNumber
deebb4 ¤   PGPGetKeyPropertyBuffer
5df4a3 ¤   PGPGetKeyTime
8b5b24 ¤   PGPGetSubKeyBoolean
1b11f6 ¤   PGPGetSubKeyNumber
8d7b22 ¤   PGPGetSubKeyPropertyBuffer
e5964a ¤   PGPGetSubKeyTime
dd7099 ¤   PGPGetUserIDNumber
5e531c ¤   PGPGetUserIDStringBuffer
88a865 ¤   PGPGetSigBoolean
ccff42 ¤   PGPGetSigNumber
a348ef ¤   PGPGetSigTime
5dda89 ¤   PGPGetKeyIDOfCertifier
f99b14 ¤   PGPGetPrimaryUserID
7bd3a1 ¤   PGPGetPrimaryUserIDNameBuffer
b93350 ¤   PGPGetPrimaryUserIDValidity
7635bd ¤   PGPGetHashAlgUsed
d2fefd ¤   PGPGetKeyByKeyID
561826 ¤   PGPSetKeyAxiomatic
23984e ¤   PGPUnsetKeyAxiomatic
67c496 ¤   PGPOrderKeySet
de81f0 ¤   PGPFreeKeyList
8c55de ¤   PGPNewKeyIter
435f4c ¤   PGPCopyKeyIter
d0e816 ¤   PGPFreeKeyIter
5f533e ¤   PGPKeyIterIndex
--98d0 000d140eff140110008 Page 2 of PGPcdk.def
8d0b2b ¤   PGPKeyIterRewind
f2d836 ¤   PGPKeyIterRewindSubKey
351bef ¤   PGPKeyIterSeek
c1e258 ¤   PGPKeyIterMove
15bf68 ¤   PGPKeyIterNext
cfb74a ¤   PGPKeyIterPrev
c5a50e ¤   PGPKeyIterNextSubKey
c07218 ¤   PGPKeyIterPrevSubKey
755e66 ¤   PGPKeyIterKey
2ffe30 ¤   PGPKeyIterSubKey
9c9b08 ¤   PGPKeyIterUserID
dfd23d ¤   PGPKeyIterSig
6fc036 ¤   PGPKeyIterNextUserID
421720 ¤   PGPKeyIterPrevUserID
a1bd0e ¤   PGPKeyIterRewindUserID
87dcb5 ¤   PGPKeyIterNextUIDSig
3e0ba3 ¤   PGPKeyIterPrevUIDSig
61a18d ¤   PGPKeyIterRewindUIDSig
7898f3 ¤   PGPGetDefaultPrivateKey
b62bb0 ¤   PGPSetDefaultPrivateKey
24d013 ¤   PGPGetTrustModel
17d84c ¤   PGPSetKeyUserVal
0ced35 ¤   PGPSetUserIDUserVal
49e857 ¤   PGPSetSigUserVal
44fd22 ¤   PGPGetKeyUserVal
15a5e8 ¤   PGPGetUserIDUserVal
99cd39 ¤   PGPGetSigUserVal
fa312b ¤   PGPCheckKeyRingSigs
31af5a
baa645 ¤   PGPCopyFileSpec
b05b2d ¤   PGPFreeFileSpec
505e52 ¤   PGPGetFullPathFromFileSpec
e32c0e ¤   PGPNewFileSpecFromFullPath
8c0e3f ¤   PGPMacBinaryToLocal
89af5a
8196d1 ¤   PGPNewContext
7706b7 ¤   PGPNewContextCustom
a72b19 ¤   PGPFreeContext
478c8b ¤   PGPGetContextUserValue
e8745d ¤   PGPSetContextUserValue
d8dab1 ¤   PGPGetContextMemoryMgr
670c76 ¤   PGPContextGetRandomBytes
ea67c5 ¤
2aeda4 ¤   PGPNewMemoryMgr
ce852e ¤   PGPNewMemoryMgrCustom
ce87a0 ¤   PGPFreeMemoryMgr
4df8c0 ¤   PGPGetMemoryMgrCustomValue
d001d4 ¤   PGPSetMemoryMgrCustomValue
97d08a ¤   PGPNewData
4cece1 ¤   PGPNewSecureData
aeb295 ¤   PGPReallocData
66e9bb ¤   PGPFreeData
e9f1d7 ¤   PGPGetMemoryMgrDataInfo
5d470c ¤   PGPCheckMemoryMgrIntegrity
4d5418 ¤   PGPMemoryMgrIsValid
f0aee1 ¤   PGPGetDefaultMemoryMgr
485637 ¤   PGPSetDefaultMemoryMgr
441b52 ¤   ¤
03938d ¤   pgpContextMemAlloc
fc4c4a ¤   pgpContextMemRealloc
95fe7b ¤   pgpContextMemFree
a3af5a
d3af5a
2c9770 ¤   PGPNewSymmetricCipherContext
a2f543 ¤   PGPFreeSymmetricCipherContext
f08802 ¤   PGPCopySymmetricCipherContext
6d8991 ¤   PGPInitSymmetricCipher
a10429 ¤   PGPWipeSymmetricCipher
3d6f56 ¤   PGPWashSymmetricCipher
49d985 ¤   PGPSymmetricCipherEncrypt
732eb8 ¤   PGPSymmetricCipherDecrypt
d173ba ¤   PGPGetSymmetricCipherSizes
--6138 0009e37a6c440110008 Page 3 of PGPcdk.def
e0af5a
aa5191 ¤   PGPNewCFBContext
7f17df ¤   PGPFreeCFBContext
cf9020 ¤   PGPCopyCFBContext
be19ad ¤   PGPInitCFB
bf9da2 ¤   PGPCFBEncrypt
806a9f ¤   PGPCFBDecrypt
a3f8b0 ¤   PGPCFBGetSymmetricCipher
bf1557 ¤   PGPCFBSync
4eb563 ¤   PGPCFBGetRandom
d96e59 ¤   PGPCFBRandomCycle
58f19a ¤   PGPCFBRandomWash
58af5a
4dacf0 ¤   PGPNewCBCContext
7ceabe ¤   PGPFreeCBCContext
0f6d41 ¤   PGPCopyCBCContext
f96314 ¤   PGPInitCBC
6760c3 ¤   PGPCBCEncrypt
5097fe ¤   PGPCBCDecrypt
50fa56 ¤   PGPCBCGetSymmetricCipher
56af5a
fa7d9d ¤   PGPNewPublicKeyContext
6ebc54 ¤   PGPFreePublicKeyContext
bc450c ¤   PGPGetPublicKeyOperationSizes
f69456 ¤   PGPPublicKeyEncrypt
f6a4d0 ¤   PGPPublicKeyVerifySignature
149719 ¤   PGPPublicKeyVerifyRaw
18bfa9 ¤   PGPNewPrivateKeyContext
ede4a5 ¤   PGPFreePrivateKeyContext
d8fedb ¤   PGPGetPrivateKeyOperationSizes
a51b6b ¤   PGPPrivateKeyDecrypt
1d2fa6 ¤   PGPPrivateKeySign
c5043c ¤   PGPPrivateKeySignRaw
01c9e8 ¤   PGPDiscreteLogExponentBits
13af5a
30a8f5 ¤   PGPNewHashContext
b003c9 ¤   PGPFreeHashContext
ce0c36 ¤   PGPCopyHashContext
d0ab81 ¤   PGPResetHash
21f9f2 ¤   PGPContinueHash
0e542d ¤   PGPFinalizeHash
7724cf ¤   PGPGetHashSize
07af5a
add0dd ¤   PGPNewHMACContext
6b7be1 ¤   PGPFreeHMACContext
33476b ¤   PGPResetHMAC
db1518 ¤   PGPContinueHMAC
7cb8c7 ¤   PGPFinalizeHMAC
2caf5a
521979 ¤   PGPGlobalRandomPoolAddKeystroke
9c92e1 ¤   PGPGlobalRandomPoolAddMouse
277b92 ¤   PGPGlobalRandomPoolGetEntropy
55163d ¤   PGPGlobalRandomPoolGetSize
ebdd1c ¤   PGPGlobalRandomPoolGetMinimumEntropy
902abb ¤   PGPGlobalRandomPoolHasMinimumEntropy
f1af5a
a74ce8 ¤   PGPsdkLoadPrefs
51286d ¤   PGPsdkLoadDefaultPrefs
81b010 ¤   PGPsdkSavePrefs
430439 ¤   PGPsdkPrefSetFileSpec
351497 ¤   PGPsdkPrefGetFileSpec
53297e ¤   PGPsdkPrefSetData
f164d8 ¤   PGPsdkPrefGetData
66af5a
fb5fe6 ¤   PGPGetErrorString
81af5a
a48830 ¤   PGPGetKeyIDFromString
b9608c ¤   PGPGetKeyIDFromKey
5ba859 ¤   PGPGetKeyIDFromSubKey
eb3d3b ¤   PGPGetKeyIDString
ffae7c ¤   PGPExportKeyID
9edb67 ¤   PGPImportKeyID
--3784 0001e07a27540110008 Page 4 of PGPcdk.def
7a850a ¤   PGPCompareKeyIDs
84af5a
11d2d8 ¤   PGPFreeFilter
e22791 ¤   PGPNewKeyEncryptAlgorithmFilter
a5db6f ¤   PGPNewKeyEncryptKeySizeFilter
81fa7e ¤   PGPNewKeyRevokedFilter
2119fb ¤   PGPNewKeyDisabledFilter
519c47 ¤   PGPNewKeyExpirationTimeFilter
852911 ¤   PGPIntersectFilters
509c04 ¤   PGPNewKeyCreationTimeFilter
e547c8 ¤   PGPNewKeyIDFilter
fa30f2 ¤   PGPNewSubKeyIDFilter
d25b5a ¤   PGPNewUserIDStringFilter
18a926 ¤   PGPNegateFilter
ad3b28 ¤   PGPNewUserIDNameFilter
83eed4 ¤   PGPNewKeyFingerPrintFilter
d9d7f5 ¤   PGPNewKeySigAlgorithmFilter
bef9ea ¤   PGPNewKeySigKeySizeFilter
080c71 ¤   PGPNewUserIDEmailFilter
d2e9e6 ¤   PGPNewSigKeyIDFilter
a4fd0b ¤   PGPUnionFilters
e9f336 ¤   PGPFilterKeySet
d4af5a
7b33af ¤   PGPHKSQueryFromFilter
dd2816 ¤   PGPLDAPQueryFromFilter
e467c5 ¤
a71c4d ¤   PGPOpenKeyRing
a0f18b ¤   PGPPropagateTrust
f58896 ¤   PGPRemoveSubKey
2d498c ¤   PGPRevokeSubKey
dbf3ce ¤   PGPIncKeyListRefCount
1676a5 ¤   PGPSetSubKeyUserVal
dd3e78 ¤   PGPGetSubKeyUserVal
86b2bc ¤   PGPIncFilterRefCount
bb48f4 ¤   PGPKeySetIsMember
52af5a
affa83 ¤   pgpEventNull
6ea4d6 ¤   pgpEventKeyServer
201f0d ¤   pgpEventKeyServerTLS
b64282 ¤   pgpEventKeyServerSign
2daf5a
64af5a
2b84d3 ¤   PGPPassphraseIsValid
beb780 ¤   PGPGenerateKey
b71fc9 ¤   PGPGenerateSubKey
ef73d0 ¤   PGPSignUserID
07cfb0 ¤   PGPGetKeyEntropyNeeded
523a23 ¤   PGPExportKeySet
f69404 ¤   PGPImportKeySet
7335d7 ¤   PGPVerifyX509CertificateChain
7becb6 ¤   PGPAddAttributeUserID
70b621 ¤   PGPGetPrimaryAttributeUserID
f3af5a
3b182f ¤   PGPGetKeyListContext
667a39 ¤   PGPGetKeySetContext
70c0b8 ¤   PGPGetKeyIterContext
ee82e0 ¤   PGPGetKeyContext
9f41ba ¤   PGPGetSubKeyContext
84da2a ¤   PGPGetUserIDContext
67af5a
13d22c ¤   PGPEncode
e860dc ¤   PGPDecode
56af5a
dc29a9 ¤   PGPNewOptionList
9e5868 ¤   PGPAddJobOptions
3db072 ¤   PGPAppendOptionList
120b9c ¤   PGPBuildOptionList
e7e818 ¤   PGPCopyOptionList
6c6fe7 ¤   PGPFreeOptionList
4b0af7 ¤   PGPOLastOption
f5dc63 ¤   PGPONullOption
1e144b ¤   PGPOInputFile
--e540 000b56cf9a440110008 Page 5 of PGPcdk.def
b6a298 ¤   PGPOInputBuffer
798f92 ¤   PGPOOutputFile
9c00e1 ¤   PGPOOutputBuffer
58f34b ¤   PGPOAllocatedOutputBuffer
dcac4d ¤   PGPODiscardOutput
9ddfc9 ¤   PGPOEncryptToKey
7c620c ¤   PGPOEncryptToKeySet
f74b0c ¤   PGPOEncryptToUserID
9ef3c9 ¤   PGPOSignWithKey
d07696 ¤   PGPOConventionalEncrypt
c4b3cb ¤   PGPOPassphrase
6eb9f9 ¤   PGPOPassphraseBuffer
5f6f16 ¤   PGPODetachedSig
4c0d24 ¤   PGPOCipherAlgorithm
f5202b ¤   PGPOHashAlgorithm
822031 ¤   PGPOFailBelowValidity
91d560 ¤   PGPOWarnBelowValidity
2a2309 ¤   PGPOEventHandler
688f6e ¤   PGPOSendNullEvents
a5cfe2 ¤   PGPOArmorOutput
416a53 ¤   PGPODataIsASCII
31ef90 ¤   PGPOClearSign
71301c ¤   PGPOForYourEyesOnly
9355f3 ¤   PGPOSendEventIfKeyFound
9cccd6 ¤   PGPOKeySetRef
f04dcb ¤   PGPOKeyGenParams
9c4492 ¤   PGPOKeyGenName
8ecbed ¤   PGPOCreationDate
b5fdac ¤   PGPOExpiration
931a61 ¤   PGPOAdditionalRecipientRequestKeySet
d5a251 ¤   PGPOKeyGenMasterKey
3c0775 ¤   PGPOKeyGenFast
39d307 ¤   PGPOPreferredAlgorithms
91efe7 ¤   PGPOExportable
42a466 ¤   PGPOExportPrivateKeys
561bde ¤   PGPOExportPrivateSubkeys
a2fa86 ¤   PGPOSigTrust
1ed6b7 ¤   PGPOCommentString
ede7d6 ¤   PGPOVersionString
096e0d ¤   PGPOFileNameString
fff6db ¤   PGPOLocalEncoding
9ac29c ¤   PGPOOutputLineEndType
333af3 ¤   PGPOPGPMIMEEncoding
c9435a ¤   PGPOImportKeysTo
557445 ¤   PGPOPassThroughIfUnrecognized
25e053 ¤   PGPORecursivelyDecode
9e3ab9 ¤   PGPOAskUserForEntropy
cf778a ¤   PGPORawPGPInput
570493 ¤   PGPOOmitMIMEVersion
e0a50e ¤   PGPOSigRegularExpression
b064f0 ¤   PGPOCompression
a5c643 ¤   PGPOPasskeyBuffer
3636db ¤   PGPOPassThroughClearSigned
330079 ¤   PGPOPassThroughKeys
871627 ¤   PGPOX509Encoding
c7ef4c ¤   PGPORevocationKeySet
e90e19 ¤   PGPOExportFormat
c7af5a
60cc59 ¤   PGPGetSDKVersion
58cbb0 ¤   PGPGetSDKString
8b64d2 ¤   PGPGetFeatureFlags
deae4a ¤   PGPCountPublicKeyAlgorithms
3cc603 ¤   PGPGetIndexedPublicKeyAlgorithmInfo
2e7594 ¤   PGPCountSymmetricCiphers
cf6e5d ¤   PGPGetIndexedSymmetricCipherInfo
75af5a
6caf5a
593400 ¤   PGPsdkInit
886eb9 ¤   PGPsdkCleanup
74af5a
c445b9 ¤   PGPNewGroupSet
b519ed ¤   PGPNewGroupSetFromFile
--d125 000ffb171f540110008 Page 6 of PGPcdk.def
bed59e ¤   PGPSaveGroupSetToFile
760f40 ¤   PGPFreeGroupSet
3654c5 ¤   PGPGroupSetNeedsCommit
916548 ¤   PGPGetGroupSetContext
94af5a
6fc9dd ¤   PGPNewGroup
25c653 ¤   PGPCountGroupsInSet
4383d5 ¤   PGPGetIndGroupID
56fae4 ¤   PGPDeleteGroup
e80e8e ¤   PGPDeleteIndItemFromGroup
6376b6 ¤   PGPDeleteItemFromGroup
ea421e ¤   PGPGetGroupInfo
7c5889 ¤   PGPSetGroupName
81c78e ¤   PGPSetGroupUserValue
1ac520 ¤   PGPSetGroupDescription
d88c8d ¤   PGPAddItemToGroup
0a7adf ¤   PGPMergeGroupIntoDifferentSet
4d5924 ¤   PGPMergeGroupSets
05f228 ¤   PGPCopyGroupSet
edaf5a
5214a9 ¤   PGPCountGroupItems
9eee1f ¤   PGPGetIndGroupItem
dd92cb ¤   PGPSetIndGroupItemUserValue
75ed01 ¤   PGPSortGroupItems
e4f648 ¤   PGPSortGroupSet
f9af5a
43ef2e ¤   PGPNewGroupItemIter
e3ebf5 ¤   PGPFreeGroupItemIter
f74a99 ¤   PGPGroupItemIterNext
c0af5a
c89002 ¤   PGPGetGroupLowestValidity
b0e82a ¤   PGPNewKeySetFromGroup
9fbbc9 ¤   PGPNewFlattenedGroupFromGroup
528acf ¤   PGPSortGroupSetStd
8b6726 ¤   PGPExportGroupSetToBuffer
914cab ¤   PGPImportGroupSetFromBuffer
baaf5a
67af5a
b7faea ¤   PGPNewBigNum
fff9d2 ¤   PGPFreeBigNum
f93840 ¤   PGPCopyBigNum
2f6dd4 ¤   PGPAssignBigNum
77ec14 ¤   PGPSwapBigNum
452f9f ¤   PGPBigNumExtractBigEndianBytes
fa7938 ¤   PGPBigNumInsertBigEndianBytes
4eef0a ¤   PGPBigNumExtractLittleEndianBytes
03ebff ¤   PGPBigNumInsertLittleEndianBytes
b2f125 ¤   PGPBigNumGetLSWord
51a503 ¤   PGPBigNumGetSignificantBits
970cd6 ¤   PGPBigNumAdd
b71daf ¤   PGPBigNumSubtract
85527a ¤   PGPBigNumCompareQ
e01054 ¤   PGPBigNumSetQ
e72bb2 ¤   PGPBigNumAddQ
06c5e5 ¤   PGPBigNumSubtractQ
41130c ¤   PGPBigNumCompare
e54311 ¤   PGPBigNumSquare
1469c6 ¤   PGPBigNumMultiply
443b56 ¤   PGPBigNumMultiplyQ
34f970 ¤   PGPBigNumDivide
bfb244 ¤   PGPBigNumMod
889c97 ¤   PGPBigNumModQ
59d667 ¤   PGPBigNumExpMod
cdc0b2 ¤   PGPBigNumDoubleExpMod
e5ba9a ¤   PGPBigNumTwoExpMod
15eb41 ¤   PGPBigNumGCD
ad3c55 ¤   PGPBigNumInv
a43206 ¤   PGPBigNumLeftShift
5fabbe ¤   PGPBigNumRightShift
86444b ¤   PGPBigNumMakeOdd
7aaf5a
ff8e2e ¤   PGPSecretShareData
--4a67 00152898f2140110008 Page 7 of PGPcdk.def
fa01c2 ¤   PGPSecretReconstructData
faaf5a
c76e81 ¤   pgpContextIsValid
25c0b4 ¤   PGPGetUserIDBoolean
62af5a
4f5dd7 ¤   PGPGetKeyPasskeyBuffer
2faf5a
a76ac7 ¤   PGPAddKeyOptions
4daf5a
b8af5a
b2af5a
1eaf5a
89af5a
63af5a
e1af5a
52af5a
--aa15 000a5177e7a40110009 Page 1 of PGPcdk.dsp
08e9d2 # Microsoft Developer Studio Project File - Name="PGPcdk" - Package Owner=<4>
b8e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
088537 # ** DO NOT EDIT **
23af5a
a7a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
deaf5a
ccfc75 CFG=PGPcdk - Win32 Debug Auth Only
c7894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
c95c35 !MESSAGE use the Export Makefile command and run
5f6309 !MESSAGE·
a80445 !MESSAGE NMAKE /f "PGPcdk.mak".
806309 !MESSAGE·
91cdb3 !MESSAGE You can specify a configuration when running NMAKE
fae013 !MESSAGE by defining the macro CFG on the command line. For example:
3d6309 !MESSAGE·
e1620e !MESSAGE NMAKE /f "PGPcdk.mak" CFG="PGPcdk - Win32 Debug Auth Only"
696309 !MESSAGE·
2e1dd7 !MESSAGE Possible choices for configuration are:
506309 !MESSAGE·
56e9ab !MESSAGE "PGPcdk - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
92c5d1 !MESSAGE "PGPcdk - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
be946e !MESSAGE "PGPcdk - Win32 Release Auth Only" (based on\
c217ca ·"Win32 (x86) Dynamic-Link Library")
d7baa1 !MESSAGE "PGPcdk - Win32 Debug Auth Only" (based on\
dd17ca ·"Win32 (x86) Dynamic-Link Library")
526309 !MESSAGE·
6eaf5a
2a3e63 # Begin Project
15b23f # PROP Scc_ProjName ""
56df4a # PROP Scc_LocalPath ""
bf40a4 CPP=cl.exe
4fa46a MTL=midl.exe
212e1f RSC=rc.exe
beaf5a
cf8ceb !IF ·"$(CFG)" == "PGPcdk - Win32 Release"
a8af5a
a88243 # PROP BASE Use_MFC 0
dfe662 # PROP BASE Use_Debug_Libraries 0
984681 # PROP BASE Output_Dir ".\Release"
42ca0c # PROP BASE Intermediate_Dir ".\Release"
ea4c81 # PROP BASE Target_Dir ""
4e21ad # PROP Use_MFC 0
b3b771 # PROP Use_Debug_Libraries 0
8f64ca # PROP Output_Dir ".\Release"
4e93e1 # PROP Intermediate_Dir ".\Release"
9b9ad5 # PROP Ignore_Export_Lib 0
40b6fa # PROP Target_Dir ""
72c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
8d9f26 ·/c
463cd7 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\pfl\common\util" /I "..\..\..\pf¶
014118 l\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\..\pf¶
68a304 l\common\prefs" /I "..\..\..\pfl\common\lthread" /I ".." /I "..\..\pub\include"¶
18e1aa ·/I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\crypto\b¶
7c4216 ignum" /I "..\..\priv\crypto\cipher" /I "..\..\priv\crypto\compress" /I "..\..\¶
197e57 priv\crypto\hash" /I "..\..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\¶
210be0 file" /I "..\..\priv\crypto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /I "..¶
f4d89a \..\priv\crypto\pipe\text" /I "..\..\priv\crypto\pipe\utils" /I "..\..\priv\cry¶
bb49ca pto\random" /I "..\..\priv\debug" /I "..\..\priv\keys\keydb" /I "..\..\priv\key¶
a1418b s\keys" /I "..\..\priv\keys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\utili¶
4a451b ties\errors" /I "..\..\priv\utilities" /I "..\..\priv\utilities\helper" /I "..\¶
15cecd ..\priv\utilities\utils" /I "..\..\priv\utilities\prefs" /I "..\..\priv\clientl¶
fae691 ib" /I "..\..\priv\encrypt" /I "..\..\..\pfl\common\sorting" /I "..\..\priv\ext¶
c9cd00 ernal\win32\bsafe\include" /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=0 /D PGP_W¶
652ea0 IN32=1 /D BNINCLUDE=bni80386c.h /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
2b592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
f9a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
27b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
e4de84 # ADD RSC /l 0x409 /d "NDEBUG"
cb18fc BSC32=bscmake.exe
b27a24 # ADD BASE BSC32 /nologo
1a4f1b # ADD BSC32 /nologo
a5268f LINK32=link.exe
--dea4 000586787a140110009 Page 2 of PGPcdk.dsp
39cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
13a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
015e3b ·/nologo /subsystem:windows /dll /machine:I386
46abf3 # ADD LINK32 ..\..\..\pfl\win32\pflCommon\Release\pflCommon.lib kernel32.lib us¶
a29db1 er32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib¶
7c9d11 ·oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll ¶
625142 /machine:I386 /def:".\PGPcdk.def" /out:".\Release/PGP_SDK.dll"
ad84a1 # SUBTRACT LINK32 /pdb:none
d0cb10 # Begin Special Build Tool
d8e5f2 SOURCE=$(InputPath)
632d93 PostBuild_Desc=Creating static library .\Release\PGPsdkstatic.lib
b75fe9 PostBuild_Cmds=lib /nologo /out:.\Release\PGPsdkstatic.lib .\Release\*.obj\
eb8aeb ··················.\Release\*.res
87b4b9 # End Special Build Tool
21af5a
58a734 !ELSEIF ·"$(CFG)" == "PGPcdk - Win32 Debug"
b0af5a
288243 # PROP BASE Use_MFC 0
f8ffba # PROP BASE Use_Debug_Libraries 1
c0cc98 # PROP BASE Output_Dir ".\Debug"
69d06b # PROP BASE Intermediate_Dir ".\Debug"
ff4c81 # PROP BASE Target_Dir ""
8b21ad # PROP Use_MFC 0
72aea9 # PROP Use_Debug_Libraries 1
0f42fb # PROP Output_Dir ".\Debug"
b6b04a # PROP Intermediate_Dir ".\Debug"
529ad5 # PROP Ignore_Export_Lib 0
5bb6fa # PROP Target_Dir ""
a36cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
6b8dcb DOWS" /YX /c
71c928 # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\..\..\pfl\common\util" /I "..\..\¶
2bc440 ..\pfl\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\¶
c68418 ..\pfl\common\prefs" /I "..\..\..\pfl\common\lthread" /I ".." /I "..\..\pub\inc¶
46b5fc lude" /I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\cry¶
ff0774 pto\bignum" /I "..\..\priv\crypto\cipher" /I "..\..\priv\crypto\compress" /I ".¶
ee1a59 .\..\priv\crypto\hash" /I "..\..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\¶
8e3862 pipe\file" /I "..\..\priv\crypto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /¶
78d3ef I "..\..\priv\crypto\pipe\text" /I "..\..\priv\crypto\pipe\utils" /I "..\..\pri¶
4f1575 v\crypto\random" /I "..\..\priv\debug" /I "..\..\priv\keys\keydb" /I "..\..\pri¶
acbc3d v\keys\keys" /I "..\..\priv\keys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\¶
670631 utilities\errors" /I "..\..\priv\utilities" /I "..\..\priv\utilities\helper" /I¶
19bf36 ·"..\..\priv\utilities\utils" /I "..\..\priv\utilities\prefs" /I "..\..\priv\cl¶
2ccda4 ientlib" /I "..\..\priv\encrypt" /I "..\..\..\pfl\common\sorting" /I "..\..\pri¶
5ad092 v\external\win32\bsafe\include" /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D ¶
8ebe0e PGP_WIN32=1 /D BNINCLUDE=bni80386c.h /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /¶
4fd0d1 FD /c
4cb3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
a1ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
9b699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
a00443 # ADD RSC /l 0x409 /d "_DEBUG"
4318fc BSC32=bscmake.exe
3a7a24 # ADD BASE BSC32 /nologo
684f1b # ADD BSC32 /nologo
af268f LINK32=link.exe
48cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
daa5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
6ec590 ·/nologo /subsystem:windows /dll /debug /machine:I386
c8260c # ADD LINK32 ..\..\..\pfl\win32\pflCommon\Debug\pflCommon.lib kernel32.lib user¶
bf76b5 32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib o¶
c29573 leaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /d¶
5c474f ebug /machine:I386 /out:".\Debug/PGP_SDK.dll"
b0cb10 # Begin Special Build Tool
0be5f2 SOURCE=$(InputPath)
b9abf4 PostBuild_Desc=Creating static library .\Debug\PGPsdkstatic.lib
b6015f PostBuild_Cmds=lib /nologo /out:.\Debug\PGPsdkstatic.lib .\Debug\*.obj\
7f7f3c ··················.\Debug\*.res
35b4b9 # End Special Build Tool
abaf5a
720bd8 !ELSEIF ·"$(CFG)" == "PGPcdk - Win32 Release Auth Only"
34af5a
778243 # PROP BASE Use_MFC 0
58e662 # PROP BASE Use_Debug_Libraries 0
--5459 0005abe3f4e40110009 Page 3 of PGPcdk.dsp
a5ac7e # PROP BASE Output_Dir "PGPcdk__"
916976 # PROP BASE Intermediate_Dir "PGPcdk__"
28a1ff # PROP BASE Ignore_Export_Lib 0
054c81 # PROP BASE Target_Dir ""
fc21ad # PROP Use_MFC 0
08b771 # PROP Use_Debug_Libraries 0
ab3a0c # PROP Output_Dir ".\Release\Authentication"
ad3887 # PROP Intermediate_Dir ".\Release\Authentication"
ae9ad5 # PROP Ignore_Export_Lib 0
90b6fa # PROP Target_Dir ""
79cee4 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\pfl\common\util" /I "..\..\¶
2cc440 ..\pfl\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\¶
ef8418 ..\pfl\common\prefs" /I "..\..\..\pfl\common\lthread" /I ".." /I "..\..\pub\inc¶
25b5fc lude" /I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\cry¶
310774 pto\bignum" /I "..\..\priv\crypto\cipher" /I "..\..\priv\crypto\compress" /I ".¶
5e1a59 .\..\priv\crypto\hash" /I "..\..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\¶
013862 pipe\file" /I "..\..\priv\crypto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /¶
3ed3ef I "..\..\priv\crypto\pipe\text" /I "..\..\priv\crypto\pipe\utils" /I "..\..\pri¶
dc1575 v\crypto\random" /I "..\..\priv\debug" /I "..\..\priv\keys\keydb" /I "..\..\pri¶
44bc3d v\keys\keys" /I "..\..\priv\keys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\¶
5c0631 utilities\errors" /I "..\..\priv\utilities" /I "..\..\priv\utilities\helper" /I¶
2cbf36 ·"..\..\priv\utilities\utils" /I "..\..\priv\utilities\prefs" /I "..\..\priv\cl¶
589693 ientlib" /I "..\..\priv\encrypt" /I "..\..\..\pfl\common\sorting" /D UNFINISHED¶
4176f5 _CODE_ALLOWED=1 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D BNINCLUDE=bni80386c.h /D "NDEB¶
cb6e00 UG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
613cd7 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\pfl\common\util" /I "..\..\..\pf¶
b04118 l\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\..\pf¶
a4a304 l\common\prefs" /I "..\..\..\pfl\common\lthread" /I ".." /I "..\..\pub\include"¶
44e1aa ·/I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\crypto\b¶
564216 ignum" /I "..\..\priv\crypto\cipher" /I "..\..\priv\crypto\compress" /I "..\..\¶
937e57 priv\crypto\hash" /I "..\..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\¶
3f0be0 file" /I "..\..\priv\crypto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /I "..¶
e4d89a \..\priv\crypto\pipe\text" /I "..\..\priv\crypto\pipe\utils" /I "..\..\priv\cry¶
c649ca pto\random" /I "..\..\priv\debug" /I "..\..\priv\keys\keydb" /I "..\..\priv\key¶
44418b s\keys" /I "..\..\priv\keys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\utili¶
b2451b ties\errors" /I "..\..\priv\utilities" /I "..\..\priv\utilities\helper" /I "..\¶
59cecd ..\priv\utilities\utils" /I "..\..\priv\utilities\prefs" /I "..\..\priv\clientl¶
23e691 ib" /I "..\..\priv\encrypt" /I "..\..\..\pfl\common\sorting" /I "..\..\priv\ext¶
2379d1 ernal\win32\bsafe\include" /D PGP_ENCRYPT_DISABLE=1 /D PGP_DECRYPT_DISABLE=1 /D¶
4e3d92 ·UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D BNINCLUDE=bni80386c¶
a7ede1 .h /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
495fba # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
1ea23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
80b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
a8de84 # ADD RSC /l 0x409 /d "NDEBUG"
9d18fc BSC32=bscmake.exe
517a24 # ADD BASE BSC32 /nologo
7f4f1b # ADD BSC32 /nologo
5e268f LINK32=link.exe
5fcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
29a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
fb1e0b ·..\..\..\pfl\win32\pflCommon\Release\pflCommon.lib /nologo /subsystem:windows ¶
c72160 /dll /machine:I386 /def:".\PGPcdk.def" /out:".\Release/PGP_SDK.dll"
3876be # SUBTRACT BASE LINK32 /pdb:none
d1abf3 # ADD LINK32 ..\..\..\pfl\win32\pflCommon\Release\pflCommon.lib kernel32.lib us¶
629db1 er32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib¶
d89d11 ·oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll ¶
8cc717 /machine:I386 /def:".\PGPcdk.def" /out:".\Release\Authentication/PGP_SDK_LTD.dl¶
c61f37 l"
5884a1 # SUBTRACT LINK32 /pdb:none
cdcb10 # Begin Special Build Tool
cae5f2 SOURCE=$(InputPath)
4e88bd PostBuild_Desc=Creating static library\
bf085a ···.\Release\Authentication\PGPsdkLtdStatic.lib
f58caf PostBuild_Cmds=lib /nologo /out:.\Release\Authentication\PGPsdkLtdStatic.lib\
69d5ed ········.\Release\Authentication\*.obj ··········.\Release\Authentication\*.res
48b4b9 # End Special Build Tool
8eaf5a
c7347e !ELSEIF ·"$(CFG)" == "PGPcdk - Win32 Debug Auth Only"
4daf5a
3c8243 # PROP BASE Use_MFC 0
5affba # PROP BASE Use_Debug_Libraries 1
--93b2 000307651a040110009 Page 4 of PGPcdk.dsp
a5ac7e # PROP BASE Output_Dir "PGPcdk__"
916976 # PROP BASE Intermediate_Dir "PGPcdk__"
28a1ff # PROP BASE Ignore_Export_Lib 0
054c81 # PROP BASE Target_Dir ""
fc21ad # PROP Use_MFC 0
11aea9 # PROP Use_Debug_Libraries 1
3a36c9 # PROP Output_Dir ".\Debug\Authentication"
5de5a6 # PROP Intermediate_Dir ".\Debug\Authentication"
2f9ad5 # PROP Ignore_Export_Lib 0
19b6fa # PROP Target_Dir ""
da75ba # ADD BASE CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\..\..\pfl\common\util" /I ".¶
4661a1 .\..\..\pfl\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\file" /I ".¶
7082c5 .\..\..\pfl\common\prefs" /I "..\..\..\pfl\common\lthread" /I ".." /I "..\..\pu¶
f6f82d b\include" /I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\pri¶
b287ca v\crypto\bignum" /I "..\..\priv\crypto\cipher" /I "..\..\priv\crypto\compress" ¶
d318a6 /I "..\..\priv\crypto\hash" /I "..\..\priv\crypto\pipe\crypt" /I "..\..\priv\cr¶
17bf35 ypto\pipe\file" /I "..\..\priv\crypto\pipe\parser" /I "..\..\priv\crypto\pipe\s¶
b1a79b ig" /I "..\..\priv\crypto\pipe\text" /I "..\..\priv\crypto\pipe\utils" /I "..\.¶
159d7f .\priv\crypto\random" /I "..\..\priv\debug" /I "..\..\priv\keys\keydb" /I "..\.¶
109478 .\priv\keys\keys" /I "..\..\priv\keys\pubkey" /I "..\..\priv\regexp" /I "..\..\¶
18543e priv\utilities\errors" /I "..\..\priv\utilities" /I "..\..\priv\utilities\helpe¶
f030ac r" /I "..\..\priv\utilities\utils" /I "..\..\priv\utilities\prefs" /I "..\..\pr¶
b09e22 iv\clientlib" /I "..\..\priv\encrypt" /I "..\..\..\pfl\common\sorting" /D UNFIN¶
e41033 ISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D BNINCLUDE=bni80386c.h /D ¶
65e5f7 "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
33c928 # ADD CPP /nologo /MTd /W3 /GX /Zi /Od /I "..\..\..\pfl\common\util" /I "..\..\¶
b4c440 ..\pfl\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\¶
dc8418 ..\pfl\common\prefs" /I "..\..\..\pfl\common\lthread" /I ".." /I "..\..\pub\inc¶
98b5fc lude" /I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\cry¶
990774 pto\bignum" /I "..\..\priv\crypto\cipher" /I "..\..\priv\crypto\compress" /I ".¶
e51a59 .\..\priv\crypto\hash" /I "..\..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\¶
ea3862 pipe\file" /I "..\..\priv\crypto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /¶
15d3ef I "..\..\priv\crypto\pipe\text" /I "..\..\priv\crypto\pipe\utils" /I "..\..\pri¶
ac1575 v\crypto\random" /I "..\..\priv\debug" /I "..\..\priv\keys\keydb" /I "..\..\pri¶
c4bc3d v\keys\keys" /I "..\..\priv\keys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\¶
780631 utilities\errors" /I "..\..\priv\utilities" /I "..\..\priv\utilities\helper" /I¶
16bf36 ·"..\..\priv\utilities\utils" /I "..\..\priv\utilities\prefs" /I "..\..\priv\cl¶
c7cda4 ientlib" /I "..\..\priv\encrypt" /I "..\..\..\pfl\common\sorting" /I "..\..\pri¶
797fc7 v\external\win32\bsafe\include" /D PGP_ENCRYPT_DISABLE=1 /D PGP_DECRYPT_DISABLE¶
7f1729 =1 /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D BNINCLUDE=bni8¶
2f1366 0386c.h /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
4b1088 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
b5ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
19699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
5e0443 # ADD RSC /l 0x409 /d "_DEBUG"
6418fc BSC32=bscmake.exe
3d7a24 # ADD BASE BSC32 /nologo
984f1b # ADD BSC32 /nologo
4a268f LINK32=link.exe
64cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
47a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
d1a62f ·..\..\..\pfl\win32\pflCommon\Debug\pflCommon.lib /nologo /subsystem:windows /d¶
a814d8 ll /debug /machine:I386 /out:".\Debug/PGP_SDK.dll"
07260c # ADD LINK32 ..\..\..\pfl\win32\pflCommon\Debug\pflCommon.lib kernel32.lib user¶
2176b5 32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib o¶
529573 leaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /d¶
fb5a99 ebug /machine:I386 /out:".\Debug\Authentication/PGP_SDK_LTD.dll"
ebcb10 # Begin Special Build Tool
22e5f2 SOURCE=$(InputPath)
c188bd PostBuild_Desc=Creating static library\
0dc400 ···.\Debug\Authentication\PGPsdkLtdStatic.lib
833e87 PostBuild_Cmds=lib /nologo /out:.\Debug\Authentication\PGPsdkLtdStatic.lib\
e7fe18 ·······.\Debug\Authentication\*.obj ···········.\Debug\Authentication\*.res
50b4b9 # End Special Build Tool
f4af5a
c330ec !ENDIF·
e1af5a
a8b8a5 # Begin Target
b0af5a
1fda9b # Name "PGPcdk - Win32 Release"
93711d # Name "PGPcdk - Win32 Debug"
3074fd # Name "PGPcdk - Win32 Release Auth Only"
--3c3c 0007ebc75f740110009 Page 5 of PGPcdk.dsp
efa4fa # Name "PGPcdk - Win32 Debug Auth Only"
ea4cc4 # Begin Group "Source Files"
f8af5a
bb7b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
c0df4f # Begin Source File
4daf5a
ca4fd9 SOURCE=..\..\priv\crypto\bignum\bn.c
b26ccd # End Source File
54df4f # Begin Source File
2eaf5a
73b374 SOURCE=..\..\priv\crypto\bignum\bn32.c
886ccd # End Source File
87df4f # Begin Source File
beaf5a
caa27a SOURCE=..\..\priv\crypto\bignum\bngermain.c
466ccd # End Source File
f3df4f # Begin Source File
11af5a
ebe7b0 SOURCE=..\..\priv\crypto\bignum\bni32.c
e26ccd # End Source File
55df4f # Begin Source File
e8af5a
695cd7 SOURCE=..\..\priv\crypto\bignum\bni80386c.c
7f6ccd # End Source File
20df4f # Begin Source File
dfaf5a
515e75 SOURCE=..\..\priv\crypto\bignum\bnimem.c
626ccd # End Source File
bddf4f # Begin Source File
79af5a
72e8aa SOURCE=..\..\priv\crypto\bignum\bninit32.c
506ccd # End Source File
42df4f # Begin Source File
c3af5a
a062f8 SOURCE=..\..\priv\crypto\bignum\bnjacobi.c
a16ccd # End Source File
eedf4f # Begin Source File
aaaf5a
f1d940 SOURCE=..\..\priv\crypto\bignum\bnlegal.c
ef6ccd # End Source File
c2df4f # Begin Source File
0eaf5a
1b7c7a SOURCE=..\..\priv\crypto\bignum\bnprime.c
e26ccd # End Source File
c7df4f # Begin Source File
60af5a
0dbeac SOURCE=..\..\priv\crypto\bignum\bnprint.c
136ccd # End Source File
d8df4f # Begin Source File
62af5a
9ff7b9 SOURCE=..\..\priv\crypto\bignum\bnsieve.c
796ccd # End Source File
b0df4f # Begin Source File
20af5a
5ad09f SOURCE=..\..\priv\crypto\pipe\utils\pgpAddHdr.c
606ccd # End Source File
72df4f # Begin Source File
c1af5a
d28886 SOURCE=..\..\priv\utilities\helper\pgpAnnotate.c
7b6ccd # End Source File
e3df4f # Begin Source File
56af5a
197699 SOURCE=..\..\priv\crypto\pipe\file\pgpArmor.c
316ccd # End Source File
2fdf4f # Begin Source File
4baf5a
dc5734 SOURCE=..\..\priv\crypto\pipe\file\pgpArmrFil.c
9f6ccd # End Source File
d6df4f # Begin Source File
eeaf5a
941f49 SOURCE=..\..\priv\crypto\bignum\pgpBigNum.c
7e6ccd # End Source File
--fdc2 000e42a28ae40110009 Page 6 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
1e7fec SOURCE=..\..\priv\keys\pubkey\pgpBSRSAGlue.c
076ccd # End Source File
17df4f # Begin Source File
23af5a
5530b4 SOURCE=..\..\priv\crypto\pipe\utils\pgpBufMod.c
6d6ccd # End Source File
2edf4f # Begin Source File
3caf5a
ee8988 SOURCE=..\..\priv\utilities\helper\pgpByteFIFO.c
456ccd # End Source File
ebdf4f # Begin Source File
01af5a
23be30 SOURCE=..\..\priv\crypto\cipher\pgpCAST5.c
2c6ccd # End Source File
dbdf4f # Begin Source File
feaf5a
aae209 SOURCE=..\..\priv\crypto\cipher\pgpCBC.c
056ccd # End Source File
c3df4f # Begin Source File
f1af5a
a56219 SOURCE=.\PGPcdk.def
02af5a
288ceb !IF ·"$(CFG)" == "PGPcdk - Win32 Release"
5baf5a
95226a # PROP Exclude_From_Build 1
58af5a
7ea734 !ELSEIF ·"$(CFG)" == "PGPcdk - Win32 Debug"
3aaf5a
f60bd8 !ELSEIF ·"$(CFG)" == "PGPcdk - Win32 Release Auth Only"
feaf5a
bcac09 # PROP BASE Exclude_From_Build 1
a3226a # PROP Exclude_From_Build 1
08af5a
85347e !ELSEIF ·"$(CFG)" == "PGPcdk - Win32 Debug Auth Only"
6daf5a
7f30ec !ENDIF·
16af5a
386ccd # End Source File
52df4f # Begin Source File
eeaf5a
b6d3a2 SOURCE=..\..\priv\crypto\cipher\pgpCFB.c
106ccd # End Source File
11df4f # Begin Source File
66af5a
858f65 SOURCE=..\..\priv\utilities\helper\pgpCharMap.c
466ccd # End Source File
60df4f # Begin Source File
39af5a
cedf89 SOURCE=..\..\priv\crypto\pipe\crypt\pgpCiphrMod.c
716ccd # End Source File
a4df4f # Begin Source File
bdaf5a
55fe27 SOURCE=..\..\priv\clientlib\pgpClientEncode.c
6f6ccd # End Source File
80df4f # Begin Source File
1aaf5a
8c09ef SOURCE=..\..\priv\clientlib\pgpClientKeyDB.c
0a6ccd # End Source File
04df4f # Begin Source File
c0af5a
b895d2 SOURCE=..\..\priv\crypto\pipe\text\pgpCompMod.c
476ccd # End Source File
5bdf4f # Begin Source File
d1af5a
852239 SOURCE=..\..\priv\utilities\utils\pgpConf.c
4f6ccd # End Source File
21df4f # Begin Source File
33af5a
271b9a SOURCE=..\..\priv\utilities\pgpContext.c
e46ccd # End Source File
--9fdc 0000e4094fe40110009 Page 7 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
168141 SOURCE=..\..\priv\crypto\pipe\crypt\pgpConvMod.c
f56ccd # End Source File
dddf4f # Begin Source File
78af5a
cedf34 SOURCE=..\..\priv\crypto\pipe\utils\pgpCopyMod.c
ed6ccd # End Source File
30df4f # Begin Source File
ddaf5a
7b6a37 SOURCE=..\..\priv\crypto\pipe\file\pgpCRC.c
856ccd # End Source File
66df4f # Begin Source File
35af5a
ae3bfd SOURCE=..\..\priv\debug\pgpDEBUGStartup.c
0c6ccd # End Source File
addf4f # Begin Source File
7caf5a
3f964b SOURCE=..\..\priv\encrypt\pgpDecode.c
b46ccd # End Source File
efdf4f # Begin Source File
21af5a
85717a SOURCE=..\..\priv\utilities\utils\pgpDecPipe.c
5a6ccd # End Source File
dbdf4f # Begin Source File
05af5a
b7d3ee SOURCE=..\..\priv\crypto\pipe\text\pgpDefMod.c
5c6ccd # End Source File
d8df4f # Begin Source File
8faf5a
995e9a SOURCE=..\..\priv\crypto\cipher\pgpDES3.c
a76ccd # End Source File
9fdf4f # Begin Source File
b7af5a
5eed8e SOURCE=..\..\priv\crypto\pipe\utils\pgpDevNull.c
236ccd # End Source File
28df4f # Begin Source File
3eaf5a
260248 SOURCE=..\..\priv\keys\pubkey\pgpDSAKey.c
ec6ccd # End Source File
48df4f # Begin Source File
64af5a
c94b42 SOURCE=..\..\priv\keys\pubkey\pgpElGKey.c
976ccd # End Source File
46df4f # Begin Source File
d5af5a
367cda SOURCE=..\..\priv\encrypt\pgpEncode.c
416ccd # End Source File
23df4f # Begin Source File
97af5a
4cf490 SOURCE=..\..\priv\utilities\utils\pgpEncPipe.c
896ccd # End Source File
39df4f # Begin Source File
8eaf5a
44ce00 SOURCE=..\..\priv\encrypt\pgpEncSubr.c
446ccd # End Source File
f1df4f # Begin Source File
10af5a
8dd808 SOURCE=..\..\priv\keys\keydb\pgpEnumeratedSet.c
7c6ccd # End Source File
76df4f # Begin Source File
47af5a
d4deb3 SOURCE=..\..\priv\utilities\utils\pgpEnv.c
436ccd # End Source File
5bdf4f # Begin Source File
d3af5a
60a6b0 SOURCE=..\..\priv\utilities\errors\pgpErrors.c
1c6ccd # End Source File
8bdf4f # Begin Source File
bbaf5a
feb7cd SOURCE=..\..\priv\keys\pubkey\pgpESK.c
0e6ccd # End Source File
--6107 000a99d46ff40110009 Page 8 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
3ab9b6 SOURCE=..\..\priv\encrypt\pgpEvent.c
886ccd # End Source File
55df4f # Begin Source File
f2af5a
e90e07 SOURCE=..\..\priv\utilities\pgpFeatures.c
236ccd # End Source File
e3df4f # Begin Source File
89af5a
e94d44 SOURCE=..\..\priv\utilities\helper\pgpFIFO.c
076ccd # End Source File
59df4f # Begin Source File
fcaf5a
a1b7e0 SOURCE=..\..\priv\utilities\helper\pgpFile.c
1c6ccd # End Source File
89df4f # Begin Source File
aaaf5a
a1e8a5 SOURCE=..\..\priv\keys\keydb\pgpFileDB.c
356ccd # End Source File
f3df4f # Begin Source File
71af5a
e685d1 SOURCE=..\..\priv\utilities\helper\pgpFileFIFO.c
e06ccd # End Source File
e0df4f # Begin Source File
a8af5a
98c593 SOURCE=..\..\priv\crypto\pipe\file\pgpFileMod.c
a36ccd # End Source File
4cdf4f # Begin Source File
e1af5a
6b69a9 SOURCE=..\..\priv\utilities\helper\pgpFileNames.c
506ccd # End Source File
b4df4f # Begin Source File
deaf5a
b84c3d SOURCE=..\..\priv\utilities\helper\pgpFileRef.c
d96ccd # End Source File
52df4f # Begin Source File
2faf5a
c93f24 SOURCE=..\..\priv\utilities\utils\pgpFileType.c
c96ccd # End Source File
18df4f # Begin Source File
5eaf5a
6d0db7 SOURCE=..\..\priv\keys\keydb\pgpFilteredSet.c
f06ccd # End Source File
99df4f # Begin Source File
26af5a
cbbade SOURCE=..\..\priv\keys\pubkey\pgpFixedKey.c
e26ccd # End Source File
35df4f # Begin Source File
14af5a
19caf8 SOURCE=..\..\priv\utilities\helper\pgpFlexFIFO.c
166ccd # End Source File
25df4f # Begin Source File
16af5a
68ac5e SOURCE=..\..\priv\utilities\pgpGroups.c
d06ccd # End Source File
21df4f # Begin Source File
52af5a
f1a967 SOURCE=..\..\priv\utilities\pgpGroupsUtil.c
4f6ccd # End Source File
addf4f # Begin Source File
dcaf5a
528dd6 SOURCE=..\..\priv\crypto\hash\pgpHash.c
096ccd # End Source File
b5df4f # Begin Source File
6eaf5a
bf0870 SOURCE=..\..\priv\crypto\pipe\sig\pgpHashMod.c
a16ccd # End Source File
c8df4f # Begin Source File
0daf5a
9c4260 SOURCE=..\..\priv\crypto\pipe\file\pgpHeader.c
a96ccd # End Source File
--7465 0001688e02940110009 Page 9 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
bdb45d SOURCE=..\..\priv\crypto\hash\pgpHMAC.c
906ccd # End Source File
6cdf4f # Begin Source File
1caf5a
2a9815 SOURCE=..\..\priv\crypto\cipher\pgpIDEA.c
376ccd # End Source File
dcdf4f # Begin Source File
e3af5a
7b7950 SOURCE=..\..\priv\crypto\pipe\text\pgpInfMod.c
ee6ccd # End Source File
2cdf4f # Begin Source File
35af5a
34db09 SOURCE=..\..\priv\crypto\pipe\utils\pgpJoin.c
df6ccd # End Source File
36df4f # Begin Source File
9caf5a
7ce176 SOURCE=..\..\priv\keys\keydb\pgpKeyFilter.c
af6ccd # End Source File
ebdf4f # Begin Source File
c5af5a
3831f3 SOURCE=..\..\priv\keys\keydb\pgpKeyID.c
e56ccd # End Source File
c7df4f # Begin Source File
7caf5a
2c6853 SOURCE=..\..\priv\keys\keydb\pgpKeyIter.c
0e6ccd # End Source File
77df4f # Begin Source File
30af5a
aba8da SOURCE=..\..\priv\keys\keydb\pgpKeyLib.c
b56ccd # End Source File
a0df4f # Begin Source File
64af5a
4361e5 SOURCE=..\..\priv\keys\keydb\pgpKeyMan.c
f66ccd # End Source File
0edf4f # Begin Source File
91af5a
2c53a3 SOURCE=..\..\priv\keys\pubkey\pgpKeyMisc.c
456ccd # End Source File
d4df4f # Begin Source File
73af5a
2728e8 SOURCE=..\..\priv\keys\keydb\pgpKeySet.c
ef6ccd # End Source File
7adf4f # Begin Source File
18af5a
1d8850 SOURCE=..\..\priv\keys\pubkey\pgpKeySpec.c
2d6ccd # End Source File
98df4f # Begin Source File
b8af5a
9d61a7 SOURCE=..\..\priv\keys\keydb\pgpKeyUpd.c
956ccd # End Source File
d7df4f # Begin Source File
abaf5a
4c5968 SOURCE=..\..\..\pfl\common\file\pgpLineEndIO.c
cd6ccd # End Source File
58df4f # Begin Source File
d2af5a
195039 SOURCE=..\..\priv\crypto\pipe\text\pgpLiteral.c
b26ccd # End Source File
28df4f # Begin Source File
27af5a
2eb1ca SOURCE=..\..\priv\utilities\helper\pgpMacBinary.c
336ccd # End Source File
0cdf4f # Begin Source File
6daf5a
c9e3ac SOURCE=..\..\priv\utilities\helper\pgpMacFileMapping.c
e66ccd # End Source File
86df4f # Begin Source File
64af5a
94f8af SOURCE=..\..\priv\crypto\pipe\crypt\pgpMakePKE.c
166ccd # End Source File
--a72f 000d2a77c0640110009 Page 10 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
e50d36 SOURCE=..\..\priv\keys\pubkey\pgpMakeSig.c
8d6ccd # End Source File
d7df4f # Begin Source File
f0af5a
1d162b SOURCE=..\..\priv\crypto\hash\pgpMD2.c
b26ccd # End Source File
85df4f # Begin Source File
dfaf5a
58410a SOURCE=..\..\priv\crypto\hash\pgpMD5.c
9c6ccd # End Source File
47df4f # Begin Source File
a0af5a
ea49b0 SOURCE=..\..\priv\keys\keydb\pgpMemDB.c
be6ccd # End Source File
33df4f # Begin Source File
21af5a
27c55c SOURCE=..\..\priv\utilities\helper\pgpMemFile.c
e06ccd # End Source File
41df4f # Begin Source File
03af5a
4a8b66 SOURCE=..\..\priv\crypto\pipe\utils\pgpMemMod.c
c86ccd # End Source File
2cdf4f # Begin Source File
ccaf5a
7005d3 SOURCE=..\..\..\pfl\common\pgpMemoryMgr.c
d96ccd # End Source File
33df4f # Begin Source File
4eaf5a
5b1458 SOURCE=..\..\priv\keys\keys\pgpMemPool.c
fe6ccd # End Source File
b6df4f # Begin Source File
d1af5a
d34949 SOURCE=..\..\priv\utilities\helper\pgpMsg.c
546ccd # End Source File
64df4f # Begin Source File
baaf5a
b1f798 SOURCE=..\..\priv\keys\pubkey\pgpMSRSAGlue.c
406ccd # End Source File
73df4f # Begin Source File
6faf5a
576b18 SOURCE=..\..\priv\utilities\pgpOptionList.c
416ccd # End Source File
f2df4f # Begin Source File
1faf5a
4e8d93 SOURCE=..\..\priv\utilities\helper\pgpPassCach.c
016ccd # End Source File
bddf4f # Begin Source File
b0af5a
c444fc SOURCE=..\..\priv\utilities\helper\pgpPipeFile.c
f16ccd # End Source File
88df4f # Begin Source File
60af5a
6fdc4f SOURCE=..\..\priv\crypto\pipe\crypt\pgpPKEMod.c
646ccd # End Source File
4ddf4f # Begin Source File
f7af5a
aff6ec SOURCE=..\..\priv\keys\pubkey\pgpPktList.c
076ccd # End Source File
97df4f # Begin Source File
85af5a
bc461f SOURCE=..\..\priv\crypto\pipe\file\pgpPrsAsc.c
026ccd # End Source File
00df4f # Begin Source File
44af5a
ed2590 SOURCE=..\..\priv\crypto\pipe\parser\pgpPrsBin.c
c46ccd # End Source File
22df4f # Begin Source File
76af5a
2ea295 SOURCE=..\..\priv\keys\pubkey\pgpPubKey.c
d26ccd # End Source File
--74e0 0002fa00f2640110009 Page 11 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
7871cd SOURCE=..\..\priv\keys\pubkey\pgpPublicKey.c
846ccd # End Source File
93df4f # Begin Source File
f3af5a
9f66f6 SOURCE=..\..\priv\crypto\pipe\file\pgpRadix64.c
516ccd # End Source File
47df4f # Begin Source File
c1af5a
cf6d4b SOURCE=..\..\priv\crypto\random\pgpRandomPool.c
4e6ccd # End Source File
9cdf4f # Begin Source File
0baf5a
d2eb1e SOURCE=..\..\priv\crypto\random\pgpRandomX9_17.c
476ccd # End Source File
a3df4f # Begin Source File
62af5a
29e75c SOURCE=..\..\priv\crypto\pipe\parser\pgpReadAnn.c
7c6ccd # End Source File
8adf4f # Begin Source File
97af5a
543344 SOURCE=..\..\priv\regexp\pgpRegExp.c
3e6ccd # End Source File
6adf4f # Begin Source File
8aaf5a
8a4495 SOURCE=..\..\priv\crypto\hash\pgpRIPEMD160.c
f06ccd # End Source File
27df4f # Begin Source File
24af5a
b6a6a9 SOURCE=..\..\priv\crypto\random\pgpRndSeed.c
256ccd # End Source File
83df4f # Begin Source File
f6af5a
3f4739 SOURCE=..\..\priv\crypto\random\pgpRndWin32.c
9a6ccd # End Source File
25df4f # Begin Source File
fdaf5a
dd1a51 SOURCE=..\..\priv\keys\keys\pgpRngMnt.c
f06ccd # End Source File
42df4f # Begin Source File
8baf5a
916406 SOURCE=..\..\priv\keys\keys\pgpRngPars.c
776ccd # End Source File
66df4f # Begin Source File
1eaf5a
b74b6a SOURCE=..\..\priv\keys\keys\pgpRngPkt.c
8a6ccd # End Source File
34df4f # Begin Source File
baaf5a
0bb730 SOURCE=..\..\priv\keys\keys\pgpRngPriv.c
036ccd # End Source File
bddf4f # Begin Source File
e3af5a
6b16a9 SOURCE=..\..\priv\keys\keys\pgpRngPub.c
eb6ccd # End Source File
d4df4f # Begin Source File
97af5a
1e7e1d SOURCE=..\..\priv\keys\keys\pgpRngRead.c
9b6ccd # End Source File
3cdf4f # Begin Source File
7faf5a
9525ab SOURCE=..\..\priv\keys\pubkey\pgpRSAGlue.c
186ccd # End Source File
98df4f # Begin Source File
75af5a
5259c3 SOURCE=..\..\priv\keys\pubkey\pgpRSAKey.c
3e6ccd # End Source File
05df4f # Begin Source File
dfaf5a
d3e138 SOURCE=.\pgpsdk.rc
2f6ccd # End Source File
--32ea 00028fa34d740110009 Page 12 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
155a67 SOURCE=..\..\priv\utilities\prefs\pgpSDKPrefs.c
106ccd # End Source File
43df4f # Begin Source File
2caf5a
136581 SOURCE=..\..\priv\crypto\hash\pgpSHA.c
066ccd # End Source File
e3df4f # Begin Source File
a4af5a
a5ddf8 SOURCE=..\..\priv\crypto\secshare\pgpShamir.c
396ccd # End Source File
75df4f # Begin Source File
88af5a
a26d99 SOURCE=..\..\priv\keys\pubkey\pgpSig.c
206ccd # End Source File
7bdf4f # Begin Source File
f4af5a
84cbe6 SOURCE=..\..\priv\crypto\pipe\sig\pgpSigMod.c
8b6ccd # End Source File
ecdf4f # Begin Source File
feaf5a
5f312c SOURCE=..\..\priv\utilities\utils\pgpSigPipe.c
be6ccd # End Source File
5bdf4f # Begin Source File
1eaf5a
19270f SOURCE=..\..\priv\utilities\utils\pgpSigSpec.c
a16ccd # End Source File
13df4f # Begin Source File
eaaf5a
0a0fa1 SOURCE=..\..\priv\crypto\pipe\utils\pgpSplit.c
9c6ccd # End Source File
ccdf4f # Begin Source File
44af5a
1038ab SOURCE=..\..\priv\utilities\helper\pgpStr2Key.c
3f6ccd # End Source File
2ddf4f # Begin Source File
b4af5a
0edbaa SOURCE=..\..\priv\crypto\cipher\pgpSymmetricCipher.c
c96ccd # End Source File
6edf4f # Begin Source File
15af5a
465762 SOURCE=..\..\priv\crypto\pipe\text\pgpTextFilt.c
e16ccd # End Source File
bddf4f # Begin Source File
01af5a
6f743a SOURCE=..\..\priv\utilities\pgpTimeBomb.c
096ccd # End Source File
dcdf4f # Begin Source File
89af5a
a1106c SOURCE=..\..\priv\utilities\helper\pgpTimeDate.c
a86ccd # End Source File
45df4f # Begin Source File
6daf5a
f803c2 SOURCE=..\..\priv\keys\keys\pgpTrstPkt.c
f86ccd # End Source File
72df4f # Begin Source File
e8af5a
618192 SOURCE=..\..\priv\keys\keys\pgpTrust.c
cb6ccd # End Source File
8adf4f # Begin Source File
f2af5a
55be98 SOURCE=..\..\priv\keys\keydb\pgpUnionDB.c
aa6ccd # End Source File
e6df4f # Begin Source File
1daf5a
34fbf5 SOURCE=..\..\priv\keys\keydb\pgpUnionSet.c
eb6ccd # End Source File
3fdf4f # Begin Source File
ebaf5a
cd1758 SOURCE=..\..\priv\utilities\pgpUtilities.c
286ccd # End Source File
--084d 000f8fe8cb140110009 Page 13 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
104c5e SOURCE=..\..\priv\crypto\pipe\parser\pgpVerifyRa.c
bb6ccd # End Source File
2fdf4f # Begin Source File
fbaf5a
faebb8 SOURCE=..\..\priv\crypto\pipe\utils\pgpVMemMod.c
fb6ccd # End Source File
2cdf4f # Begin Source File
80af5a
0ac567 SOURCE=..\..\priv\crypto\pipe\parser\pgpVrfySig.c
9d6ccd # End Source File
1ddf4f # Begin Source File
c7af5a
e40251 SOURCE=..\..\priv\keys\keydb\pgpX509Keys.c
5a6ccd # End Source File
e3df4f # Begin Source File
beaf5a
e7151d SOURCE=..\..\priv\crypto\pipe\text\pgpZBits.c
e56ccd # End Source File
a4df4f # Begin Source File
28af5a
17a68a SOURCE=..\..\priv\crypto\pipe\text\pgpZDeflate.c
566ccd # End Source File
83df4f # Begin Source File
14af5a
d7b84f SOURCE=..\..\priv\crypto\compress\pgpZInflate.c
bb6ccd # End Source File
e9df4f # Begin Source File
6baf5a
983d37 SOURCE=..\..\priv\crypto\pipe\text\pgpZTrees.c
ad6ccd # End Source File
193f5a # End Group
c3ba44 # Begin Group "Header Files"
adaf5a
85561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
77df4f # Begin Source File
d4af5a
f5ab71 SOURCE=..\..\priv\crypto\bignum\bn.h
e06ccd # End Source File
7ddf4f # Begin Source File
2caf5a
3c57dc SOURCE=..\..\priv\crypto\bignum\bn32.h
f36ccd # End Source File
8adf4f # Begin Source File
4daf5a
c046d2 SOURCE=..\..\priv\crypto\bignum\bngermain.h
5d6ccd # End Source File
e9df4f # Begin Source File
0daf5a
e70318 SOURCE=..\..\priv\crypto\bignum\bni32.h
6c6ccd # End Source File
14df4f # Begin Source File
a5af5a
b4badd SOURCE=..\..\priv\crypto\bignum\bnimem.h
216ccd # End Source File
f2df4f # Begin Source File
beaf5a
c48650 SOURCE=..\..\priv\crypto\bignum\bnjacobi.h
556ccd # End Source File
0edf4f # Begin Source File
eaaf5a
0f3de8 SOURCE=..\..\priv\crypto\bignum\bnlegal.h
076ccd # End Source File
c1df4f # Begin Source File
b3af5a
7798d2 SOURCE=..\..\priv\crypto\bignum\bnprime.h
096ccd # End Source File
2edf4f # Begin Source File
91af5a
e45a04 SOURCE=..\..\priv\crypto\bignum\bnprint.h
f86ccd # End Source File
--d515 000dc89061d40110009 Page 14 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
401311 SOURCE=..\..\priv\crypto\bignum\bnsieve.h
056ccd # End Source File
45df4f # Begin Source File
70af5a
9f3437 SOURCE=..\..\priv\crypto\pipe\utils\pgpAddHdr.h
006ccd # End Source File
30df4f # Begin Source File
fdaf5a
a39231 SOURCE=..\..\priv\crypto\pipe\file\pgpArmor.h
af6ccd # End Source File
9ddf4f # Begin Source File
acaf5a
12b39c SOURCE=..\..\priv\crypto\pipe\file\pgpArmrFil.h
c66ccd # End Source File
0edf4f # Begin Source File
d9af5a
93d41c SOURCE=..\..\priv\crypto\pipe\utils\pgpBufMod.h
a36ccd # End Source File
51df4f # Begin Source File
2baf5a
aa6d20 SOURCE=..\..\priv\utilities\helper\pgpByteFIFO.h
396ccd # End Source File
dcdf4f # Begin Source File
e5af5a
ff5a98 SOURCE=..\..\priv\crypto\cipher\pgpCAST5.h
036ccd # End Source File
d9df4f # Begin Source File
19af5a
296bcd SOURCE=..\..\priv\utilities\helper\pgpCharMap.h
0d6ccd # End Source File
7cdf4f # Begin Source File
eaaf5a
103b21 SOURCE=..\..\priv\crypto\pipe\crypt\pgpCiphrMod.h
036ccd # End Source File
00df4f # Begin Source File
89af5a
45717a SOURCE=..\..\priv\crypto\pipe\text\pgpCompMod.h
6e6ccd # End Source File
37df4f # Begin Source File
10af5a
60c691 SOURCE=..\..\priv\utilities\utils\pgpConf.h
116ccd # End Source File
89df4f # Begin Source File
5faf5a
1aff32 SOURCE=..\..\priv\utilities\pgpContext.h
4a6ccd # End Source File
87df4f # Begin Source File
c8af5a
a265e9 SOURCE=..\..\priv\crypto\pipe\crypt\pgpConvMod.h
746ccd # End Source File
39df4f # Begin Source File
d4af5a
643b9c SOURCE=..\..\priv\crypto\pipe\utils\pgpCopyMod.h
3e6ccd # End Source File
75df4f # Begin Source File
0eaf5a
828e9f SOURCE=..\..\priv\crypto\pipe\file\pgpCRC.h
c96ccd # End Source File
c0df4f # Begin Source File
33af5a
f83223 SOURCE=..\..\..\pfl\common\pgpDebug.h
ac6ccd # End Source File
b9df4f # Begin Source File
13af5a
84df55 SOURCE=..\..\priv\debug\pgpDEBUGStartup.h
ff6ccd # End Source File
2bdf4f # Begin Source File
76af5a
ab95d2 SOURCE=..\..\priv\utilities\utils\pgpDecPipe.h
dc6ccd # End Source File
--843f 000c0d98d6340110009 Page 15 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
a73746 SOURCE=..\..\priv\crypto\pipe\text\pgpDefMod.h
276ccd # End Source File
2bdf4f # Begin Source File
95af5a
2bba32 SOURCE=..\..\priv\crypto\cipher\pgpDES3.h
a96ccd # End Source File
46df4f # Begin Source File
3aaf5a
960926 SOURCE=..\..\priv\crypto\pipe\utils\pgpDevNull.h
406ccd # End Source File
a1df4f # Begin Source File
19af5a
36e6e0 SOURCE=..\..\priv\keys\pubkey\pgpDSAKey.h
9c6ccd # End Source File
bcdf4f # Begin Source File
2aaf5a
88afea SOURCE=..\..\priv\keys\pubkey\pgpElGKey.h
6a6ccd # End Source File
76df4f # Begin Source File
8caf5a
571038 SOURCE=..\..\priv\utilities\utils\pgpEncPipe.h
146ccd # End Source File
20df4f # Begin Source File
37af5a
ec3a1b SOURCE=..\..\priv\utilities\utils\pgpEnv.h
cb6ccd # End Source File
e5df4f # Begin Source File
94af5a
1d5365 SOURCE=..\..\priv\keys\pubkey\pgpESK.h
f16ccd # End Source File
7cdf4f # Begin Source File
8daf5a
b2a9ec SOURCE=..\..\priv\utilities\helper\pgpFIFO.h
0a6ccd # End Source File
82df4f # Begin Source File
75af5a
1d5348 SOURCE=..\..\priv\utilities\helper\pgpFile.h
fa6ccd # End Source File
d2df4f # Begin Source File
75af5a
f4213b SOURCE=..\..\priv\crypto\pipe\file\pgpFileMod.h
836ccd # End Source File
badf4f # Begin Source File
1baf5a
0d8d01 SOURCE=..\..\priv\utilities\helper\pgpFileNames.h
4d6ccd # End Source File
b4df4f # Begin Source File
34af5a
cda895 SOURCE=..\..\priv\utilities\helper\pgpFileRef.h
2b6ccd # End Source File
09df4f # Begin Source File
8faf5a
b3db8c SOURCE=..\..\priv\utilities\utils\pgpFileType.h
706ccd # End Source File
e9df4f # Begin Source File
52af5a
0b5e76 SOURCE=..\..\priv\keys\pubkey\pgpFixedKey.h
3a6ccd # End Source File
e2df4f # Begin Source File
2daf5a
0fecd8 SOURCE=..\..\priv\crypto\pipe\sig\pgpHashMod.h
c16ccd # End Source File
1edf4f # Begin Source File
c3af5a
73a6c8 SOURCE=..\..\priv\crypto\pipe\file\pgpHeader.h
f86ccd # End Source File
76df4f # Begin Source File
2baf5a
bd7cbd SOURCE=..\..\priv\crypto\cipher\pgpIDEA.h
c06ccd # End Source File
--7838 000f25c2f2140110009 Page 16 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
0b9df8 SOURCE=..\..\priv\crypto\pipe\text\pgpInfMod.h
4d6ccd # End Source File
09df4f # Begin Source File
2eaf5a
d83fa1 SOURCE=..\..\priv\crypto\pipe\utils\pgpJoin.h
656ccd # End Source File
97df4f # Begin Source File
35af5a
7ab70b SOURCE=..\..\priv\keys\pubkey\pgpKeyMisc.h
686ccd # End Source File
02df4f # Begin Source File
a3af5a
f56cf8 SOURCE=..\..\priv\keys\pubkey\pgpKeySpec.h
046ccd # End Source File
40df4f # Begin Source File
81af5a
e37757 SOURCE=..\..\..\pfl\common\pgpLeaks.h
5a6ccd # End Source File
fbdf4f # Begin Source File
feaf5a
bbb491 SOURCE=..\..\priv\crypto\pipe\text\pgpLiteral.h
686ccd # End Source File
48df4f # Begin Source File
93af5a
011c07 SOURCE=..\..\priv\crypto\pipe\crypt\pgpMakePKE.h
536ccd # End Source File
76df4f # Begin Source File
01af5a
51e99e SOURCE=..\..\priv\keys\pubkey\pgpMakeSig.h
b96ccd # End Source File
85df4f # Begin Source File
f4af5a
9bf283 SOURCE=..\..\priv\crypto\hash\pgpMD2.h
ce6ccd # End Source File
1bdf4f # Begin Source File
afaf5a
28a5a2 SOURCE=..\..\priv\crypto\hash\pgpMD5.h
066ccd # End Source File
c0df4f # Begin Source File
f8af5a
5f3324 SOURCE=..\..\..\pfl\common\pgpMem.h
8e6ccd # End Source File
20df4f # Begin Source File
5faf5a
be6fce SOURCE=..\..\priv\crypto\pipe\utils\pgpMemMod.h
036ccd # End Source File
e4df4f # Begin Source File
32af5a
4af0f0 SOURCE=..\..\priv\keys\keys\pgpMemPool.h
5a6ccd # End Source File
19df4f # Begin Source File
2eaf5a
c88fb0 SOURCE=..\..\priv\utilities\pgpOptionList.h
3d6ccd # End Source File
fedf4f # Begin Source File
1daf5a
4a693b SOURCE=..\..\priv\utilities\helper\pgpPassCach.h
096ccd # End Source File
3bdf4f # Begin Source File
ccaf5a
d638e7 SOURCE=..\..\priv\crypto\pipe\crypt\pgpPKEMod.h
da6ccd # End Source File
80df4f # Begin Source File
e2af5a
671244 SOURCE=..\..\priv\keys\pubkey\pgpPktList.h
c86ccd # End Source File
62df4f # Begin Source File
d8af5a
aca2b7 SOURCE=..\..\priv\crypto\pipe\file\pgpPrsAsc.h
f26ccd # End Source File
--73ef 000fc7fbb0140110009 Page 17 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
2ac138 SOURCE=..\..\priv\crypto\pipe\parser\pgpPrsBin.h
1c6ccd # End Source File
c4df4f # Begin Source File
5baf5a
a4463d SOURCE=..\..\priv\keys\pubkey\pgpPubKey.h
ba6ccd # End Source File
a5df4f # Begin Source File
b8af5a
57825e SOURCE=..\..\priv\crypto\pipe\file\pgpRadix64.h
226ccd # End Source File
e2df4f # Begin Source File
72af5a
890fb6 SOURCE=..\..\priv\crypto\random\pgpRandomX9_17.h
7a6ccd # End Source File
12df4f # Begin Source File
b5af5a
5b03f4 SOURCE=..\..\priv\crypto\pipe\parser\pgpReadAnn.h
a36ccd # End Source File
02df4f # Begin Source File
1daf5a
38a03d SOURCE=..\..\priv\crypto\hash\pgpRIPEMD160.h
4a6ccd # End Source File
73df4f # Begin Source File
47af5a
2f4201 SOURCE=..\..\priv\crypto\random\pgpRndSeed.h
646ccd # End Source File
e0df4f # Begin Source File
96af5a
cdfef9 SOURCE=..\..\priv\keys\keys\pgpRngMnt.h
626ccd # End Source File
bddf4f # Begin Source File
baaf5a
8180ae SOURCE=..\..\priv\keys\keys\pgpRngPars.h
f96ccd # End Source File
39df4f # Begin Source File
b0af5a
b3afc2 SOURCE=..\..\priv\keys\keys\pgpRngPkt.h
196ccd # End Source File
7fdf4f # Begin Source File
b0af5a
b15398 SOURCE=..\..\priv\keys\keys\pgpRngPriv.h
e46ccd # End Source File
01df4f # Begin Source File
96af5a
11f201 SOURCE=..\..\priv\keys\keys\pgpRngPub.h
3f6ccd # End Source File
58df4f # Begin Source File
56af5a
6e9ab5 SOURCE=..\..\priv\keys\keys\pgpRngRead.h
6d6ccd # End Source File
59df4f # Begin Source File
64af5a
cfc103 SOURCE=..\..\priv\keys\pubkey\pgpRSAGlue.h
2d6ccd # End Source File
8adf4f # Begin Source File
d8af5a
b8bd6b SOURCE=..\..\priv\keys\pubkey\pgpRSAKey.h
6a6ccd # End Source File
7bdf4f # Begin Source File
93af5a
358129 SOURCE=..\..\priv\crypto\hash\pgpSHA.h
676ccd # End Source File
d0df4f # Begin Source File
35af5a
b38931 SOURCE=..\..\priv\keys\pubkey\pgpSig.h
5f6ccd # End Source File
d1df4f # Begin Source File
46af5a
2a2f4e SOURCE=..\..\priv\crypto\pipe\sig\pgpSigMod.h
fc6ccd # End Source File
--b755 0014eb4cfdd40110009 Page 18 of PGPcdk.dsp
41df4f # Begin Source File
d0af5a
37d584 SOURCE=..\..\priv\utilities\utils\pgpSigPipe.h
ab6ccd # End Source File
17df4f # Begin Source File
1daf5a
54c3a7 SOURCE=..\..\priv\utilities\utils\pgpSigSpec.h
f36ccd # End Source File
9bdf4f # Begin Source File
faaf5a
19eb09 SOURCE=..\..\priv\crypto\pipe\utils\pgpSplit.h
9b6ccd # End Source File
e4df4f # Begin Source File
11af5a
70dc03 SOURCE=..\..\priv\utilities\helper\pgpStr2Key.h
3a6ccd # End Source File
9ddf4f # Begin Source File
31af5a
04b3ca SOURCE=..\..\priv\crypto\pipe\text\pgpTextFilt.h
066ccd # End Source File
dadf4f # Begin Source File
a2af5a
3cf4c4 SOURCE=..\..\priv\utilities\helper\pgpTimeDate.h
b76ccd # End Source File
59df4f # Begin Source File
90af5a
2ce76a SOURCE=..\..\priv\keys\keys\pgpTrstPkt.h
086ccd # End Source File
f6df4f # Begin Source File
c9af5a
d1653a SOURCE=..\..\priv\keys\keys\pgpTrust.h
626ccd # End Source File
05df4f # Begin Source File
6caf5a
7aa8f6 SOURCE=..\..\priv\crypto\pipe\parser\pgpVerifyRa.h
926ccd # End Source File
ebdf4f # Begin Source File
85af5a
7e0f10 SOURCE=..\..\priv\crypto\pipe\utils\pgpVMemMod.h
296ccd # End Source File
0adf4f # Begin Source File
73af5a
f621cf SOURCE=..\..\priv\crypto\pipe\parser\pgpVrfySig.h
426ccd # End Source File
3cdf4f # Begin Source File
96af5a
355ce7 SOURCE=..\..\priv\crypto\compress\pgpZInflate.h
966ccd # End Source File
2b3f5a # End Group
a28925 # Begin Group "Resource Files"
6aaf5a
3ba92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
583f5a # End Group
4ce5cf # End Target
4ef262 # End Project
--307f 001bbea3c654011000a Page 1 of PGPcdk.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
20dd1a Project: "PGPcdk"=.\PGPcdk.dsp - Package Owner=<4>
48af5a
7fe41b Package=<5>
0b8818 {{{
4c418b }}}
b7af5a
55bec7 Package=<4>
c08818 {{{
8b418b }}}
c3af5a
9a2d94 ###############################################################################
dfaf5a
1020da Global:
f4af5a
76e41b Package=<5>
1a8818 {{{
8a418b }}}
a1af5a
e732c2 Package=<3>
bb8818 {{{
ed418b }}}
e1af5a
e12d94 ###############################################################################
bbaf5a
--5476 00056a5404c4011000b Page 1 of pgpsdk.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
19f860 #ifdef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
66465d //
df5733 // TEXTINCLUDE
a2465d //
99af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
2d4523 BEGIN
70541e ····"resource.h\0"
48e0d1 END
85af5a
467037 2 TEXTINCLUDE DISCARDABLE·
044523 BEGIN
c3eb23 ····"#include ""afxres.h""\r\n"
98db5c ····"\0"
97e0d1 END
5aaf5a
ea227f 3 TEXTINCLUDE DISCARDABLE·
024523 BEGIN
5ee851 ····"\r\n"
b9db5c ····"\0"
4ce0d1 END
42af5a
fd69ab #endif ···// APSTUDIO_INVOKED
57af5a
44af5a
e9e05c #ifndef _MAC
826c0e /////////////////////////////////////////////////////////////////////////////
d6465d //
74c5f2 // Version
f0465d //
24af5a
a88df2 VS_VERSION_INFO VERSIONINFO
a2b865 ·FILEVERSION 1,5,2,0
1996b1 ·PRODUCTVERSION 1,5,2,0
b75996 ·FILEFLAGSMASK 0x3fL
8f1f29 #ifdef _DEBUG
b19279 ·FILEFLAGS 0x21L
4bdb21 #else
b2c8a5 ·FILEFLAGS 0x20L
6d7454 #endif
f5f6e6 ·FILEOS 0x40004L
2634dd ·FILETYPE 0x2L
1fe8a0 ·FILESUBTYPE 0x0L
244523 BEGIN
b52c72 ····BLOCK "StringFileInfo"
7b5574 ····BEGIN
fe70ac ········BLOCK "040904b0"
5652d6 ········BEGIN
--b7c5 0018fc0d6f04011000b Page 2 of pgpsdk.rc
7bb939 ············VALUE "CompanyName", "Network Associates, Inc.\0"
c94f30 ············VALUE "FileDescription", "PGP Software Development Kit Core Library¶
be7b55 \0"
f96b51 ············VALUE "FileVersion", "1.5.2\0"
8e73e0 ············VALUE "InternalName", "PGPsdk\0"
9bd87b ············VALUE "LegalCopyright", "Copyright (C) 1998 Network Associates, Inc¶
cd7a7c .\0"
013e96 ············VALUE "OriginalFilename", "PGP_sdk.dll\0"
6c6164 ············VALUE "ProductName", "PGPsdk\0"
686da0 ············VALUE "ProductVersion", "1.5.2\0"
feeb90 ············VALUE "SpecialBuild", "Installed with PGP602\0"
04f37f ········END
867d01 ····END
d226ab ····BLOCK "VarFileInfo"
2f5574 ····BEGIN
8a4b11 ········VALUE "Translation", 0x409, 1200
127d01 ····END
21e0d1 END
b3af5a
a9e6e6 #endif ···// !_MAC
ecaf5a
821b3a #endif ···// English (U.S.) resources
526c0e /////////////////////////////////////////////////////////////////////////////
eeaf5a
b9af5a
7caf5a
55ce8c #ifndef APSTUDIO_INVOKED
ed6c0e /////////////////////////////////////////////////////////////////////////////
6b465d //
b98464 // Generated from the TEXTINCLUDE 3 resource.
20465d //
f7af5a
d6af5a
f16c0e /////////////////////////////////////////////////////////////////////////////
a58072 #endif ···// not APSTUDIO_INVOKED
8faf5a
--6ba9 0012a39c2cf4011000c Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
de4065 // Used by pgpsdk.rc
80465d //
9faf5a
b411aa // Next default values for new objects
b4ac6a //·
adf860 #ifdef APSTUDIO_INVOKED
173f23 #ifndef APSTUDIO_READONLY_SYMBOLS
f4b0ab #define _APS_NEXT_RESOURCE_VALUE ·······101
c0611c #define _APS_NEXT_COMMAND_VALUE ········40001
2ef6ec #define _APS_NEXT_CONTROL_VALUE ········1000
fa1285 #define _APS_NEXT_SYMED_VALUE ··········101
1a7454 #endif
2a7454 #endif

--6b32 000f269ecfa4011000d Page 1 of PGPsdkNetworkLib.def
f2be5d ; PGPsdkNL.def : Declares the module parameters for the DLL.
e1af5a
df782b DESCRIPTION ·'PGP SDK Network Library'
93af5a
55ef2b EXPORTS
fae5b9 ¤   PGPSetKeyServerIdleEventHandler
fef2a1 ¤   PGPGetKeyServerIdleEventHandler
31b13a ¤   PGPSocketsCreateThreadStorage
d7804e ¤   PGPSocketsDisposeThreadStorage
5c00aa ¤   PGPKeyServerCreateThreadStorage
261476 ¤   PGPKeyServerDisposeThreadStorage
5727d4 ¤   PGPKeyServerInit
353d2e ¤   PGPKeyServerCleanup
1e2cfd ¤   PGPNewKeyServerFromURL
6206fb ¤   PGPNewKeyServerFromHostName
1920eb ¤   PGPNewKeyServerFromHostAddress
6b65d6 ¤   PGPFreeKeyServer
099c85 ¤   PGPCancelKeyServerCall
febf73 ¤   PGPSetKeyServerEventHandler
91e92f ¤   PGPGetKeyServerEventHandler
31bced ¤   PGPKeyServerOpen
7d2150 ¤   PGPKeyServerClose
13bd45 ¤   PGPGetKeyServerTLSSession
fd4053 ¤   PGPGetKeyServerType
fe6b2b ¤   PGPGetKeyServerAccessType
10e382 ¤   PGPGetKeyServerKeySpace
a3dc89 ¤   PGPGetKeyServerPort
e5c6c2 ¤   PGPGetKeyServerHostName
499aa9 ¤   PGPGetKeyServerAddress
99bf55 ¤   PGPQueryKeyServer
1fcd07 ¤   PGPGetLastKeyServerErrorString
d9711d ¤   PGPUploadToKeyServer
e42a7c ¤   PGPUploadPrivateKeysToKeyServer
fd087c ¤   PGPDeleteFromKeyServer
ab983c ¤   PGPDisableFromKeyServer
6e033c ¤   PGPNewTLSContext
354572 ¤   PGPFreeTLSContext
c8b187 ¤   PGPtlsSetCache
c8d800 ¤   PGPtlsClearCache
2100e5 ¤   PGPNewTLSSession
7c46ab ¤   PGPFreeTLSSession
b2bf2d ¤   PGPtlsSetProtocolOptions
ac1e91 ¤   PGPtlsClose
2f7474 ¤   PGPtlsHandshake
261784 ¤   PGPtlsSetPreferredCipherSuite
89291a ¤   PGPtlsSetRemoteUniqueID
2142fc ¤   PGPtlsSetDHPrime
96e8b9 ¤   PGPtlsGetRemoteAuthenticatedKey
d62a91 ¤   PGPtlsSetLocalPrivateKey
fdab86 ¤   PGPtlsGetNegotiatedCipherSuite
1db812 ¤   PGPtlsGetState
52da50 ¤   PGPtlsReceive
c63463 ¤   PGPtlsSend
dd3b64 ¤   PGPtlsSetReceiveCallback
01c4da ¤   PGPtlsSetSendCallback
a034e8 ¤   PGPtlsGetAlert
49671a ¤   PGPtlsSendQueueIdle
6925a4 ¤   PGPSetSocketsIdleEventHandler
b26840 ¤   PGPGetSocketsIdleEventHandler
10e352 ¤   PGPSocketsInit
764ad1 ¤   PGPSocketsCleanup
bed625 ¤   PGPOpenSocket
8d61c0 ¤   PGPCloseSocket
237909 ¤   PGPBindSocket
cb58af ¤   PGPConnect
7060d2 ¤   PGPSend
58fabc ¤   PGPWrite
64d5b2 ¤   PGPSendTo
84be59 ¤   PGPReceive
bf2151 ¤   PGPRead
2056f0 ¤   PGPReceiveFrom
f28644 ¤   PGPListen
--4a65 0013d41e5c14011000d Page 2 of PGPsdkNetworkLib.def
6d3e96 ¤   PGPAccept
dfa413 ¤   PGPSelect
1711db ¤   PGPGetHostByName
21fb49 ¤   PGPGetHostByAddress
9543fa ¤   PGPGetHostName
04594a ¤   PGPGetProtocolByName
7a52cb ¤   PGPGetProtocolByNumber
768a1a ¤   PGPGetServiceByName
dfb2bb ¤   PGPGetServiceByPort
5cb9b8 ¤   PGPHostToNetLong
a91382 ¤   PGPHostToNetShort
cb56c2 ¤   PGPNetToHostLong
61cfb0 ¤   PGPNetToHostShort
457260 ¤   PGPGetLastSocketsError
f6a69d ¤   PGPGetSocketName
241089 ¤   PGPGetPeerName
62de13 ¤   PGPDottedToInternetAddress
cba6da ¤   PGPInternetAddressToDottedString
5f15c6 ¤   PGPIOControlSocket
2da16a ¤   PGPGetSocketOptions
fee9b7 ¤   PGPSetSocketOptions
d0e54e ¤   PGPSocketsEstablishTLSSession
88745a ¤   __PGPSocketsIsSet
301f41 ¤   PGPSendGroupsToServer
5ecd67 ¤   PGPRetrieveGroupsFromServer
cfb1b4 ¤   PGPNewServerMonitor
4cb56f ¤   PGPFreeServerMonitor
3d1725 ¤   PGPIncKeyServerRefCount¶
--d92f 000026f26fb4011000e Page 1 of PGPsdkNetworkLib.dsp
192f10 # Microsoft Developer Studio Project File - Name="PGPsdkNetworkLib" - Package O¶
106815 wner=<4>
50e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
8b8537 # ** DO NOT EDIT **
cfaf5a
20a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
4faf5a
389242 CFG=PGPSDKNETWORKLIB - WIN32 DEBUG
a6894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
f35c35 !MESSAGE use the Export Makefile command and run
f46309 !MESSAGE·
dd1881 !MESSAGE NMAKE /f "PGPsdkNetworkLib.mak".
cc6309 !MESSAGE·
15cdb3 !MESSAGE You can specify a configuration when running NMAKE
c8e013 !MESSAGE by defining the macro CFG on the command line. For example:
796309 !MESSAGE·
6dcb20 !MESSAGE NMAKE /f "PGPsdkNetworkLib.mak" CFG="PGPSDKNETWORKLIB - WIN32 DEBUG"
686309 !MESSAGE·
9a1dd7 !MESSAGE Possible choices for configuration are:
1e6309 !MESSAGE·
2433b6 !MESSAGE "PGPsdkNetworkLib - Win32 Release" (based on\
5017ca ·"Win32 (x86) Dynamic-Link Library")
2c4c69 !MESSAGE "PGPsdkNetworkLib - Win32 Debug" (based on\
af17ca ·"Win32 (x86) Dynamic-Link Library")
3cfe3e !MESSAGE "PGPsdkNetworkLib - Win32 Debug Auth Only" (based on\
9117ca ·"Win32 (x86) Dynamic-Link Library")
9d0adb !MESSAGE "PGPsdkNetworkLib - Win32 Release Auth Only" (based on\
7817ca ·"Win32 (x86) Dynamic-Link Library")
c96309 !MESSAGE·
91af5a
683e63 # Begin Project
28b23f # PROP Scc_ProjName ""
cddf4a # PROP Scc_LocalPath ""
9940a4 CPP=cl.exe
a0a46a MTL=midl.exe
a22e1f RSC=rc.exe
cfaf5a
c0021b !IF ·"$(CFG)" == "PGPsdkNetworkLib - Win32 Release"
dfaf5a
398243 # PROP BASE Use_MFC 0
63e662 # PROP BASE Use_Debug_Libraries 0
a57d73 # PROP BASE Output_Dir "Release"
656180 # PROP BASE Intermediate_Dir "Release"
354c81 # PROP BASE Target_Dir ""
9e21ad # PROP Use_MFC 0
b1b771 # PROP Use_Debug_Libraries 0
3a64ca # PROP Output_Dir ".\Release"
1793e1 # PROP Intermediate_Dir ".\Release"
319ad5 # PROP Ignore_Export_Lib 0
26b6fa # PROP Target_Dir ""
f9c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
3910c2 ·/FD /c
ad6017 # ADD CPP /nologo /MT /W3 /GR /GX /O2 /I ".." /I "..\..\..\pfl\win32" /I "..\..¶
dc835c \..\pfl\win32/pgpAsyncDNS" /I "..\..\pub\include" /I "..\..\priv\utilities" /I ¶
826243 "..\..\priv\networklib\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\¶
7bcf4c prefs" /I "..\..\..\pfl\common\util" /I "..\..\..\pfl\common\lthread" /I "..\..¶
d18e58 \priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\encrypt" /I "..\..¶
ec2ae7 \..\network\ldaplib\include" /I "..\..\priv\crypto\pipe\file" /I "..\..\..\pfl\¶
300585 common\file" /I "..\..\priv\utilities\helper" /I "..\..\priv\crypto\pipe\text" ¶
fa55ca /I "..\..\priv\utilities\utils" /D PGPSOCKETSLDAP=1 /D UNFINISHED_CODE_ALLOWED=¶
49dbea 1 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D "NDEBUG" /D "NEEDPROTOS" /D "WIN32" /D "_WIN¶
9d1fea DOWS" /YX /FD /c
7b1e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
446d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
58b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
19de84 # ADD RSC /l 0x409 /d "NDEBUG"
7618fc BSC32=bscmake.exe
9e7a24 # ADD BASE BSC32 /nologo
1b4f1b # ADD BSC32 /nologo
3e268f LINK32=link.exe
5acadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
02a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
--655a 0006ffdd7444011000e Page 2 of PGPsdkNetworkLib.dsp
825e3b ·/nologo /subsystem:windows /dll /machine:I386
177678 # ADD LINK32 ../pgpcdk/release/pgp_sdk.lib ../../../network/ldaplib/win32/relea¶
72808e se/libldap.lib ../../../network/ldaplib/win32/release/liblber.lib ..\..\..\pfl\¶
f45b59 win32\pflCommon\release\pflCommon.lib kernel32.lib user32.lib gdi32.lib winspoo¶
c420f5 l.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odb¶
37e058 c32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:I386 ¶
8cf312 /out:"./Release/PGPsdkNL.dll"
0baf5a
888a7c !ELSEIF ·"$(CFG)" == "PGPsdkNetworkLib - Win32 Debug"
a5af5a
de8243 # PROP BASE Use_MFC 0
a6ffba # PROP BASE Use_Debug_Libraries 1
dd54b8 # PROP BASE Output_Dir "Debug"
54198a # PROP BASE Intermediate_Dir "Debug"
5b4c81 # PROP BASE Target_Dir ""
7121ad # PROP Use_MFC 0
8eaea9 # PROP Use_Debug_Libraries 1
d542fb # PROP Output_Dir ".\Debug"
92b04a # PROP Intermediate_Dir ".\Debug"
d79ad5 # PROP Ignore_Export_Lib 0
b2b6fa # PROP Target_Dir ""
386cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
8c1fea DOWS" /YX /FD /c
3da1b2 # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /Zi /Od /I ".." /I "..\..\..\pfl\win32" ¶
4b02cf /I "..\..\..\pfl\win32/pgpAsyncDNS" /I "..\..\pub\include" /I "..\..\priv\utili¶
d07e74 ties" /I "..\..\priv\networklib\win32" /I "..\..\..\pfl\common" /I "..\..\..\pf¶
1d8f6c l\common\prefs" /I "..\..\..\pfl\common\util" /I "..\..\..\pfl\common\lthread" ¶
b6e6d1 /I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\encrypt" ¶
c7334f /I "..\..\..\network\ldaplib\include" /I "..\..\priv\crypto\pipe\file" /I "..\.¶
237169 .\..\pfl\common\file" /I "..\..\priv\utilities\helper" /I "..\..\priv\crypto\pi¶
32947f pe\text" /I "..\..\priv\utilities\utils" /D PGPSOCKETSLDAP=1 /D UNFINISHED_CODE¶
76c5ce _ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D "_DEBUG" /D "NEEDPROTOS" /D "WIN32"¶
6c3d3d ·/D "_WINDOWS" /FR /YX /FD /c
8ac0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
6cb3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
9d699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
cf0443 # ADD RSC /l 0x409 /d "_DEBUG"
c218fc BSC32=bscmake.exe
3e7a24 # ADD BASE BSC32 /nologo
8f4f1b # ADD BSC32 /nologo
4f268f LINK32=link.exe
4fcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
41a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
8a17bf ·/nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
6c6d1d # ADD LINK32 ../pgpcdk/debug/pgp_sdk.lib ../../../network/ldaplib/win32/debug/l¶
4e87ae ibldap.lib ../../../network/ldaplib/win32/debug/liblber.lib ..\..\..\pfl\win32\¶
e24422 pflCommon\Debug\pflCommon.lib kernel32.lib user32.lib gdi32.lib winspool.lib co¶
741b5f mdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib ¶
a64f2a odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /¶
cebe26 out:"./Debug/PGPsdkNL.dll"
0d07f5 # SUBTRACT LINK32 /map
72af5a
90f6c7 !ELSEIF ·"$(CFG)" == "PGPsdkNetworkLib - Win32 Debug Auth Only"
70af5a
488243 # PROP BASE Use_MFC 0
02ffba # PROP BASE Use_Debug_Libraries 1
5e3379 # PROP BASE Output_Dir "PGPsdkNe"
22f671 # PROP BASE Intermediate_Dir "PGPsdkNe"
3ba1ff # PROP BASE Ignore_Export_Lib 0
bd4c81 # PROP BASE Target_Dir ""
f321ad # PROP Use_MFC 0
83aea9 # PROP Use_Debug_Libraries 1
7236c9 # PROP Output_Dir ".\Debug\Authentication"
e1e5a6 # PROP Intermediate_Dir ".\Debug\Authentication"
7b9ad5 # PROP Ignore_Export_Lib 0
79b6fa # PROP Target_Dir ""
2713af # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /I "..\..\..\pfl\win32"¶
514546 ·/I "..\..\pub\include" /I "..\..\priv\utilities" /I "..\..\priv\networklib\win¶
1a9a19 32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\prefs" /I "..\..\..\pfl\co¶
3b3175 mmon\util" /I "..\..\..\pfl\common\lthread" /I "..\..\priv\include" /I "..\..\p¶
a50df1 riv\include\opaque" /I "..\..\priv\encrypt" /I "..\..\..\network\ldaplib\includ¶
6fd833 e" /I "..\..\priv\crypto\pipe\file" /I "..\..\..\pfl\common\file" /I "..\..\pri¶
--6e4b 00096fe0cc24011000e Page 3 of PGPsdkNetworkLib.dsp
b9d939 v\utilities\helper" /I "..\..\priv\crypto\pipe\text" /I "..\..\priv\utilities\u¶
ad74c0 tils" /D PGPSOCKETSLDAP=1 /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WI¶
b380b8 N32=1 /D "_DEBUG" /D "NEEDPROTOS" /D "WIN32" /D "_WINDOWS" /FR /YX /FD /c
57a1b2 # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /Zi /Od /I ".." /I "..\..\..\pfl\win32" ¶
1302cf /I "..\..\..\pfl\win32/pgpAsyncDNS" /I "..\..\pub\include" /I "..\..\priv\utili¶
457e74 ties" /I "..\..\priv\networklib\win32" /I "..\..\..\pfl\common" /I "..\..\..\pf¶
1e8f6c l\common\prefs" /I "..\..\..\pfl\common\util" /I "..\..\..\pfl\common\lthread" ¶
31e6d1 /I "..\..\priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\encrypt" ¶
a8334f /I "..\..\..\network\ldaplib\include" /I "..\..\priv\crypto\pipe\file" /I "..\.¶
9e7169 .\..\pfl\common\file" /I "..\..\priv\utilities\helper" /I "..\..\priv\crypto\pi¶
7b947f pe\text" /I "..\..\priv\utilities\utils" /D PGPSOCKETSLDAP=1 /D UNFINISHED_CODE¶
2bc5ce _ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D "_DEBUG" /D "NEEDPROTOS" /D "WIN32"¶
453d3d ·/D "_WINDOWS" /FR /YX /FD /c
dfc0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
40b3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
68699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
ad0443 # ADD RSC /l 0x409 /d "_DEBUG"
ef18fc BSC32=bscmake.exe
b17a24 # ADD BASE BSC32 /nologo
c04f1b # ADD BSC32 /nologo
75268f LINK32=link.exe
7d98b1 # ADD BASE LINK32 ../pgpcdk/debug/pgp_sdk.lib ../../../network/ldaplib/win32/de¶
2724e5 bug/libldap.lib ../../../network/ldaplib/win32/debug/liblber.lib ..\..\..\pfl\w¶
207e1e in32\pflCommon\Debug\pflCommon.lib kernel32.lib user32.lib gdi32.lib winspool.l¶
b1b034 ib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32¶
d22eae .lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I¶
4ab45f 386 /out:"./Debug/PGPsdkNL.dll"
61290f # SUBTRACT BASE LINK32 /map
f0eb49 # ADD LINK32 ../pgpcdk/debug/authentication/pgp_sdk_ltd.lib ../../../network/ld¶
aefd40 aplib/win32/debug/libldap.lib ../../../network/ldaplib/win32/debug/liblber.lib ¶
c94ae0 ..\..\..\pfl\win32\pflCommon\Debug\pflCommon.lib kernel32.lib user32.lib gdi32.¶
252b1e lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib u¶
6e06f9 uid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /de¶
b74841 bug /machine:I386 /out:"./Debug/Authentication/PGPsdkNLLtd.dll"
5b07f5 # SUBTRACT LINK32 /map
5acb10 # Begin Special Build Tool
14e5f2 SOURCE=$(InputPath)
4e88bd PostBuild_Desc=Creating static library\
c0e244 ····.\Debug\Authentication\PGPsdkNLLtdStatic.lib
9ff831 PostBuild_Cmds=lib /nologo /out:.\Debug\Authentication\PGPsdkNLLtdStatic.lib\
cefe18 ·······.\Debug\Authentication\*.obj ···········.\Debug\Authentication\*.res
2fb4b9 # End Special Build Tool
efaf5a
e903b0 !ELSEIF ·"$(CFG)" == "PGPsdkNetworkLib - Win32 Release Auth Only"
9baf5a
ef8243 # PROP BASE Use_MFC 0
60e662 # PROP BASE Use_Debug_Libraries 0
078927 # PROP BASE Output_Dir "PGPsdkN0"
c04c2f # PROP BASE Intermediate_Dir "PGPsdkN0"
70a1ff # PROP BASE Ignore_Export_Lib 0
b44c81 # PROP BASE Target_Dir ""
3b21ad # PROP Use_MFC 0
88b771 # PROP Use_Debug_Libraries 0
913a0c # PROP Output_Dir ".\Release\Authentication"
413887 # PROP Intermediate_Dir ".\Release\Authentication"
fa9ad5 # PROP Ignore_Export_Lib 0
94b6fa # PROP Target_Dir ""
b6befd # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I ".." /I "..\..\..\pfl\win32" /I "..\.¶
69c1ec .\pub\include" /I "..\..\priv\utilities" /I "..\..\priv\networklib\win32" /I ".¶
22c035 .\..\..\pfl\common" /I "..\..\..\pfl\common\prefs" /I "..\..\..\pfl\common\util¶
d93409 " /I "..\..\..\pfl\common\lthread" /I "..\..\priv\include" /I "..\..\priv\inclu¶
b7d971 de\opaque" /I "..\..\priv\encrypt" /I "..\..\..\network\ldaplib\include" /I "..¶
004346 \..\priv\crypto\pipe\file" /I "..\..\..\pfl\common\file" /I "..\..\priv\utiliti¶
ec46b8 es\helper" /I "..\..\priv\crypto\pipe\text" /I "..\..\priv\utilities\utils" /D ¶
dc1792 PGPSOCKETSLDAP=1 /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D ¶
618695 "NDEBUG" /D "NEEDPROTOS" /D "WIN32" /D "_WINDOWS" /YX /FD /c
69c9f2 # SUBTRACT BASE CPP /X
eb6017 # ADD CPP /nologo /MT /W3 /GR /GX /O2 /I ".." /I "..\..\..\pfl\win32" /I "..\..¶
32835c \..\pfl\win32/pgpAsyncDNS" /I "..\..\pub\include" /I "..\..\priv\utilities" /I ¶
8e6243 "..\..\priv\networklib\win32" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\¶
17cf4c prefs" /I "..\..\..\pfl\common\util" /I "..\..\..\pfl\common\lthread" /I "..\..¶
968e58 \priv\include" /I "..\..\priv\include\opaque" /I "..\..\priv\encrypt" /I "..\..¶
--d922 000747609e14011000e Page 4 of PGPsdkNetworkLib.dsp
ce2ae7 \..\network\ldaplib\include" /I "..\..\priv\crypto\pipe\file" /I "..\..\..\pfl\¶
240585 common\file" /I "..\..\priv\utilities\helper" /I "..\..\priv\crypto\pipe\text" ¶
cd7872 /I "..\..\priv\utilities\utils" /D PGP_ENCRYPT_DISABLE=1 /D PGP_DECRYPT_DISABLE¶
101d10 =1 /D PGPSOCKETSLDAP=1 /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=0 /D PGP_WIN32¶
b2b004 =1 /D "NDEBUG" /D "NEEDPROTOS" /D "WIN32" /D "_WINDOWS" /YX /FD /c
b8d3db # SUBTRACT CPP /X
971e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
076d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
bab35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
19de84 # ADD RSC /l 0x409 /d "NDEBUG"
0c18fc BSC32=bscmake.exe
857a24 # ADD BASE BSC32 /nologo
784f1b # ADD BSC32 /nologo
7b268f LINK32=link.exe
9cf4f8 # ADD BASE LINK32 ../pgpcdk/release/pgp_sdk.lib ../../../network/ldaplib/win32/¶
4b794d release/libldap.lib ../../../network/ldaplib/win32/release/liblber.lib ..\..\..¶
ef8ff3 \pfl\win32\pflCommon\release\pflCommon.lib kernel32.lib user32.lib gdi32.lib wi¶
3c20c8 nspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.li¶
a66b5f b odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:¶
229a62 I386 /out:"./Release/PGPsdkNL.dll"
f9d954 # ADD LINK32 ../pgpcdk/release/authentication/pgp_sdk_ltd.lib ../../../network/¶
c9bce8 ldaplib/win32/release/libldap.lib ../../../network/ldaplib/win32/release/liblbe¶
0d064e r.lib ..\..\..\pfl\win32\pflCommon\release\pflCommon.lib kernel32.lib user32.li¶
a6326a b gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut¶
071279 32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows ¶
b3f86a /dll /machine:I386 /out:"./Release/Authentication/PGPsdkNLLtd.dll"
2fcb10 # Begin Special Build Tool
17e5f2 SOURCE=$(InputPath)
cf88bd PostBuild_Desc=Creating static library\
8131ec ····.\Release\Authentication\PGPsdkNLLtdStatic.lib
7f835b PostBuild_Cmds=lib /nologo /out:.\Release\Authentication\PGPsdkNLLtdStatic.lib\
44d5ed ········.\Release\Authentication\*.obj ··········.\Release\Authentication\*.res
3ab4b9 # End Special Build Tool
beaf5a
c930ec !ENDIF·
89af5a
35b8a5 # Begin Target
faaf5a
b8906f # Name "PGPsdkNetworkLib - Win32 Release"
191af8 # Name "PGPsdkNetworkLib - Win32 Debug"
d7dfee # Name "PGPsdkNetworkLib - Win32 Debug Auth Only"
814b58 # Name "PGPsdkNetworkLib - Win32 Release Auth Only"
714cc4 # Begin Group "Source Files"
8daf5a
947b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
c9df4f # Begin Source File
79af5a
9f22b9 SOURCE=..\..\priv\networklib\keyserver\CHTTPKeyServer.cpp
696ccd # End Source File
c8df4f # Begin Source File
4eaf5a
735b8b SOURCE=..\..\priv\networklib\keyserver\CKeyServer.cpp
a46ccd # End Source File
cedf4f # Begin Source File
26af5a
cfd60d SOURCE=..\..\priv\networklib\keyserver\CLDAPKeyServer.cpp
7b6ccd # End Source File
76df4f # Begin Source File
aaaf5a
9582ad SOURCE=..\..\priv\networklib\keyserver\pgpKeyServer.cpp
f56ccd # End Source File
03df4f # Begin Source File
0eaf5a
b46b18 SOURCE=..\..\priv\utilities\pgpOptionList.c
c16ccd # End Source File
abdf4f # Begin Source File
86af5a
0f1bca SOURCE=.\PGPsdkNetworkLib.def
af6ccd # End Source File
9bdf4f # Begin Source File
25af5a
74892c SOURCE=..\..\priv\networklib\win32\PGPsdkNetworkLibDLLMain.c
--3080 0017b272a6e4011000e Page 5 of PGPsdkNetworkLib.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
ac80e3 SOURCE=..\..\priv\networklib\pgpsockets\common\pgpSockets.c
e66ccd # End Source File
69df4f # Begin Source File
29af5a
a7116f SOURCE=..\..\priv\networklib\tls\pgpTLS.c
966ccd # End Source File
9fdf4f # Begin Source File
a7af5a
765f4d SOURCE=..\..\priv\networklib\tls\pgpTLSPrimes.c
af6ccd # End Source File
f63f5a # End Group
ad8925 # Begin Group "Resource Files"
9aaf5a
c2a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
a1df4f # Begin Source File
82af5a
9abd57 SOURCE=.\PGPsdkNetworkLib.rc
f36ccd # End Source File
8c3f5a # End Group
c5e5cf # End Target
7bf262 # End Project
--7155 0006041af584011000f Page 1 of PGPsdkNetworkLib.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
a199a4 Project: "PGPcdk"=..\PGPcdk\PGPcdk.dsp - Package Owner=<4>
b0af5a
4be41b Package=<5>
018818 {{{
d0418b }}}
b4af5a
bcbec7 Package=<4>
cc8818 {{{
fc418b }}}
79af5a
752d94 ###############################################################################
41af5a
db2d2c Project: "PGPsdkNetworkLib"=.\PGPsdkNetworkLib.dsp - Package Owner=<4>
54af5a
1ee41b Package=<5>
568818 {{{
c0418b }}}
beaf5a
41bec7 Package=<4>
ba8818 {{{
582c9f ····Begin Project Dependency
51d307 ····Project_Dep_Name liblber
f804a4 ····End Project Dependency
912c9f ····Begin Project Dependency
35ba3b ····Project_Dep_Name PGPcdk
7504a4 ····End Project Dependency
cf2c9f ····Begin Project Dependency
08c84c ····Project_Dep_Name libldap
2f04a4 ····End Project Dependency
83418b }}}
f6af5a
d52d94 ###############################################################################
f3af5a
2a1260 Project: "liblber"=..\..\..\network\ldaplib\win32\liblber.dsp - Package Owner=<¶
ee6627 4>
6daf5a
d8e41b Package=<5>
408818 {{{
cd418b }}}
e6af5a
a0bec7 Package=<4>
348818 {{{
10418b }}}
e5af5a
3b2d94 ###############################################################################
2faf5a
815a2b Project: "libldap"=..\..\..\network\ldaplib\win32\libldap.dsp - Package Owner=<¶
b56627 4>
3daf5a
6ae41b Package=<5>
198818 {{{
82418b }}}
a3af5a
32bec7 Package=<4>
c98818 {{{
f4418b }}}
afaf5a
fe2d94 ###############################################################################
90af5a
8d20da Global:
f0af5a
a6e41b Package=<5>
fc8818 {{{
e9418b }}}
34af5a
a332c2 Package=<3>
608818 {{{
--4291 00175043f284011000f Page 2 of PGPsdkNetworkLib.dsw
bf418b }}}
deaf5a
6e2d94 ###############################################################################
75af5a
--0208 00056a5404c40110010 Page 1 of PGPsdkNetworkLib.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
19f860 #ifdef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
66465d //
df5733 // TEXTINCLUDE
a2465d //
99af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
2d4523 BEGIN
70541e ····"resource.h\0"
48e0d1 END
85af5a
467037 2 TEXTINCLUDE DISCARDABLE·
044523 BEGIN
c3eb23 ····"#include ""afxres.h""\r\n"
98db5c ····"\0"
97e0d1 END
5aaf5a
ea227f 3 TEXTINCLUDE DISCARDABLE·
024523 BEGIN
5ee851 ····"\r\n"
b9db5c ····"\0"
4ce0d1 END
42af5a
fd69ab #endif ···// APSTUDIO_INVOKED
57af5a
44af5a
e9e05c #ifndef _MAC
826c0e /////////////////////////////////////////////////////////////////////////////
d6465d //
74c5f2 // Version
f0465d //
24af5a
a88df2 VS_VERSION_INFO VERSIONINFO
a2b865 ·FILEVERSION 1,5,2,0
1996b1 ·PRODUCTVERSION 1,5,2,0
b75996 ·FILEFLAGSMASK 0x3fL
8f1f29 #ifdef _DEBUG
b19279 ·FILEFLAGS 0x21L
4bdb21 #else
b2c8a5 ·FILEFLAGS 0x20L
6d7454 #endif
f5f6e6 ·FILEOS 0x40004L
2634dd ·FILETYPE 0x2L
1fe8a0 ·FILESUBTYPE 0x0L
244523 BEGIN
b52c72 ····BLOCK "StringFileInfo"
7b5574 ····BEGIN
fe70ac ········BLOCK "040904b0"
5652d6 ········BEGIN
--af4e 001965adb7540110010 Page 2 of PGPsdkNetworkLib.rc
7bb939 ············VALUE "CompanyName", "Network Associates, Inc.\0"
2c9f05 ············VALUE "FileDescription", "PGP Software Development Kit Networking L¶
1c78b3 ibrary\0"
7d6b51 ············VALUE "FileVersion", "1.5.2\0"
0c83c0 ············VALUE "InternalName", "PGPsdkNetworkLib\0"
62d87b ············VALUE "LegalCopyright", "Copyright (C) 1998 Network Associates, Inc¶
317a7c .\0"
fb7b14 ············VALUE "OriginalFilename", "PGPsdkNL.dll\0"
666164 ············VALUE "ProductName", "PGPsdk\0"
296da0 ············VALUE "ProductVersion", "1.5.2\0"
03eb90 ············VALUE "SpecialBuild", "Installed with PGP602\0"
79f37f ········END
887d01 ····END
8226ab ····BLOCK "VarFileInfo"
455574 ····BEGIN
854b11 ········VALUE "Translation", 0x409, 1200
c97d01 ····END
06e0d1 END
d1af5a
27e6e6 #endif ···// !_MAC
36af5a
8e1b3a #endif ···// English (U.S.) resources
336c0e /////////////////////////////////////////////////////////////////////////////
49af5a
c8af5a
83af5a
11ce8c #ifndef APSTUDIO_INVOKED
996c0e /////////////////////////////////////////////////////////////////////////////
b5465d //
138464 // Generated from the TEXTINCLUDE 3 resource.
29465d //
4aaf5a
bfaf5a
f36c0e /////////////////////////////////////////////////////////////////////////////
538072 #endif ···// not APSTUDIO_INVOKED
96af5a
--fa3a 001d1dfde4740110011 Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
51b5ff // Used by PGPsdkNetworkLib.rc
5d465d //
1daf5a
7e11aa // Next default values for new objects
49ac6a //·
a8f860 #ifdef APSTUDIO_INVOKED
b93f23 #ifndef APSTUDIO_READONLY_SYMBOLS
0bb0ab #define _APS_NEXT_RESOURCE_VALUE ·······101
01611c #define _APS_NEXT_COMMAND_VALUE ········40001
46f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
801285 #define _APS_NEXT_SYMED_VALUE ··········101
2a7454 #endif
d17454 #endif

--bc06 001e4c49c6140110012 Page 1 of PGPCL.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
dd2a1d ¤   $Id: PGPCL.h,v 1.2.10.1 1998/11/12 03:24:14 heller Exp $
6bf7f7 ____________________________________________________________________________*/
d5af5a
706699 #ifndef Included_PGPCL_h
162573 #define Included_PGPCL_h
03af5a
c7c77d PGPError
2d8565 pgpSigningPassphraseCL(PGPContextRef, CPGPSigningPassphraseDialogOptions *);
13af5a
6fc77d PGPError
79a35a pgpCollectRandomDataCL(PGPContextRef, CPGPRandomDataDialogOptions *);
44af5a
60c77d PGPError
cdb85e pgpKeyPassphraseCL(PGPContextRef, CPGPKeyPassphraseDialogOptions *);
4caf5a
9ac77d PGPError
863f94 pgpPassphraseCL(PGPContextRef, CPGPPassphraseDialogOptions *);
e47454 #endif
--e61e 000d70ccc7440110013 Page 1 of PGPCollectRandomDataCL.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
e8046d ¤   $Id: PGPCollectRandomDataCL.cpp,v 1.1.10.2 1998/11/13 19:51:01 heller Exp $
9bf7f7 ____________________________________________________________________________*/
5afeb2 #include <stdio.h>
c3af5a
5dd495 // PGP SDK header files
7ecc06 #include "pgpDialogs.h"
8cc9be #include "pgpRandomPool.h"
92dde9 #include "pgpKB.h"
bbaf5a
bf492e // local globals
8d7d85 static PGPBoolean¤  ¤   ¤   g_bEntropy = FALSE;
a1af5a
a7d4d4 //¤ ______________________________________________
4d465d //
96c12c // ·Entropy collection routine -- posts dialog for·
defe8f // ·mouse/keyboard entropy collection.
f0af5a
7ac77d PGPError
402dae pgpCollectRandomDataCL(
4c284d ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   context,
569fde ¤   CPGPRandomDataDialogOptions ¤   *options)
ddbb36 {
d89919 ¤   PGPInt32 lRandBits = PGPGlobalRandomPoolGetEntropy();
5faf5a
926d02 ¤   (void) context;
2867c5 ¤
6571d7 ¤   if (g_bEntropy)·
b4191c ¤   ¤   return kPGPError_ItemAlreadyExists;
aaaf5a
95faad ¤   g_bEntropy = TRUE;
a778d8 ¤   PGPBoolean bCollectionEnabled = TRUE;
40af5a
53df9c ¤   // if zero passed in, use default
e5196c ¤   PGPInt32 lTotalNeeded;
b6c268 ¤   if (options->mNeededEntropyBits)·
5904a8 ¤   ¤   lTotalNeeded = options->mNeededEntropyBits;
1e4264 ¤   else·
ae07d6 ¤   ¤   lTotalNeeded = PGPGlobalRandomPoolGetMinimumEntropy();
47af5a
98d7fc ¤   // if we have enough already, then just return
cffb0c ¤   if (lTotalNeeded < lRandBits)·
1eb840 ¤   ¤   return kPGPError_NoErr;
d3af5a
c2acf1 ¤   // collect the entropy
86f631 ¤   if (options->mPrompt)
ee5164 ¤   ¤   printf("%s\n", options->mPrompt);
d40e24 ¤   else
9451db ¤   ¤   printf("\n\
c114c1 PGP needs to generate some random data. This is done by measuring\n\
7914c2 the time intervals between your keystrokes. Please enter some\n\
69fc78 random text on your keyboard until the indicator reaches 100%%.\n\
850f67 Press ^D to cancel\n");
7faf5a
7a5717 ¤   // Go into CBreak Mode
8ffd56 ¤   PGPInt32 lStillNeeded = lTotalNeeded - lRandBits;
615ef2 ····kbCbreak(0);
ee67c5 ¤
6ab2ed ¤   double dPercent = 0;
32dca8 ¤   while (bCollectionEnabled) {
9faf5a
d7a4fe ¤   ¤   if (lRandBits > 0)
120eb5 ¤   ¤   ¤   dPercent = ((double) lRandBits / lTotalNeeded) * 100;
c6af5a
8349c1 ¤   ¤   if (dPercent > 100.5)
636a4a ¤   ¤   ¤   dPercent = 100;
cfaf5a
146cec ¤   ¤   if (dPercent >= 99.5 && lStillNeeded > 0)
d7d96d ¤   ¤   ¤   dPercent = 99.0;
--c032 00152c44b5d40110013 Page 2 of PGPCollectRandomDataCL.cpp
e0af5a
a8dee7 ¤   ¤   printf("\r");
1dea54 ¤   ¤   printf("%.0f%% of required data ··", dPercent);
d011e2 ¤   ¤   fflush(stdout);
d91b52 ¤   ¤
d1ac5a ¤   ¤   if (lStillNeeded <= 0) {
42567a ¤   ¤   ¤   bCollectionEnabled = FALSE;
a8da22 ¤   ¤   ¤   printf("\n");
18cdcb ¤   ¤   ¤   break;
f00fe4 ¤   ¤   }
391b52 ¤   ¤
a40485 ¤   ¤   kbFlush(0);
97908b ¤   ¤   int c = kbGet();¤   ¤   // get the key and add to random pool
8ecd61 ¤   ¤   if (c == 0x04) {
90146d ¤   ¤   ¤   g_bEntropy = FALSE;
d004be ¤   ¤   ¤   printf("\a\nUser cancelled collection. \n");
ba62ca ¤   ¤   ¤   kbFlush(1);
6b89a0 ¤   ¤   ¤   kbNorm();
45b1eb ¤   ¤   ¤   return kPGPError_UserAbort;
7a0fe4 ¤   ¤   }
561b52 ¤   ¤
a0c46f ¤   ¤   lRandBits = PGPGlobalRandomPoolGetEntropy();
834719 ¤   ¤   lStillNeeded = lTotalNeeded - lRandBits;
4c9371 ¤   }
a867c5 ¤
3a41e6 ····printf("\aEnough, thank you.\n");;
8067c5 ¤
b78f4d ¤   kbFlush(1);
b99d6f ····kbNorm();
944f56 ¤   g_bEntropy = FALSE;
b4af5a
15151e ¤   return kPGPError_NoErr;
52efe6 }
--5581 000c18c41e540110014 Page 1 of PGPCollectRandomDataDialog.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
8dd2d3 ¤   $Id: PGPCollectRandomDataDialog.cpp,v 1.6.2.1.2.1 1998/11/12 03:24:15 helle¶
0a0b67 r Exp $
ddf7f7 ____________________________________________________________________________*/
bbaf5a
0894d6 #include "PGPui32.h"
e1cc06 #include "pgpDialogs.h"
4fbf43 #include "PGPCL.h"
fbaf5a
93d495 // PGP SDK header files
ddc9be #include "pgpRandomPool.h"
daaf5a
538d55 #define TIMERID¤¤   ¤   4321L
9d2cfd #define DELAYTIME¤  ¤   2000L
2b41d5 #define UPDATETIMER¤¤   4322L
e0b739 #define UPDATETIME¤ ¤   50L
a2af5a
6d4948 typedef struct _RANDSTRUCT {
92eed2 ¤   LONG lOrigNeeded;
17297f ¤   LONG lStillNeeded;
1e8fa4 ¤   LONG lTotalNeeded;·
6ef316 ¤   BOOL bCollectionEnabled;
3cd5de } RANDSTRUCT, *PRANDSTRUCT;
42af5a
7c348a PGPBoolean g_bEntropy¤  = FALSE;
15af5a
b593ed // external globals
f3a009 extern HINSTANCE¤   g_hInst;
0253eb extern HHOOK¤   ¤   hhookKeyboard;
1243b9 extern HHOOK¤   ¤   hhookMouse;
9caf5a
13a3c6 //¤ ___________________________________________
ff465d //
e025df // ·Get Key Randomness Dialog Message procedure
fbaf5a
909993 BOOL CALLBACK·
db48a1 KeyRandDlgProc (
113a3a ¤   ¤   HWND¤   hDlg,·
37eb77 ¤   ¤   UINT¤   uMsg,·
8e0303 ¤   ¤   WPARAM¤ wParam,
7ac0b8 ¤   ¤   LPARAM¤ lParam)·
d4bb36 {
e65c58 ¤   PRANDSTRUCT¤prs;
ab2432 ¤   LONG¤   ¤   l;
bccdba ¤   CHAR¤   ¤   sz[256];
87af5a
01e234 ¤   switch (uMsg)·
06c7a1 ¤   {
c8af5a
532940 ¤   case WM_INITDIALOG:
ef7547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
20b333 ¤   ¤   prs = (PRANDSTRUCT)lParam;
45af5a
eb102b ¤   ¤   prs->lStillNeeded =·
278a59 ¤   ¤   ¤   prs->lTotalNeeded - PGPGlobalRandomPoolGetEntropy ();
64af5a
51bdbb ¤   ¤   if (prs->lStillNeeded <= 0)·
5eab00 ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
c2ee26 ¤   ¤   else·
785b34 ¤   ¤   {
f95309 ¤   ¤   ¤   prs->lOrigNeeded = prs->lStillNeeded;
8dbd55 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_BITSPROGBAR, PBM_SETRANGE,·
98f77a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, MAKELPARAM (0, prs->lOrigNeeded));
cc32f7 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_BITSPROGBAR, PBM_SETPOS, 0, 0);
4c0fe4 ¤   ¤   }
29836c ¤   ¤   return TRUE;
f2af5a
c15122 ¤   case WM_TIMER :
c10150 ¤   ¤   prs = (PRANDSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
--a4ed 000be4d9a7040110014 Page 2 of PGPCollectRandomDataDialog.cpp
e0af5a
473cbd ¤   ¤   if(¤TIMERID == wParam)
aa5b34 ¤   ¤   {
f8ddd2 ¤   ¤   ¤   KillTimer (hDlg, TIMERID);
d9ab00 ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
d90fe4 ¤   ¤   }
abaf5a
f88922 ¤   ¤   if(¤UPDATETIMER == wParam)
0d5b34 ¤   ¤   {
ddab7d ¤   ¤   ¤   prs->lStillNeeded =·
479f7a ¤   ¤   ¤   ¤   prs->lTotalNeeded - PGPGlobalRandomPoolGetEntropy ();
35af5a
a5420c ¤   ¤   ¤   if (prs->lStillNeeded > 0)·
bcf776 ¤   ¤   ¤   {
f323c1 ¤   ¤   ¤   ¤   l = prs->lOrigNeeded - prs->lStillNeeded;
8188e8 ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_BITSPROGBAR, PBM_SETPOS, l, 0);
75a3a6 ¤   ¤   ¤   }
aa6b93 ¤   ¤   ¤   else·
00f776 ¤   ¤   ¤   {
1cfcce ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_BITSPROGBAR, PBM_SETPOS, prs->lOr¶
3cfd3a igNeeded, 0);
e4569b ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_RANDOMDONE, sz, sizeof(sz));
e4024f ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_TEXTPROMPT, sz);·
c052c5 ¤   ¤   ¤   ¤   KillTimer (hDlg, UPDATETIMER);
3c2014 ¤   ¤   ¤   ¤   SetTimer (hDlg, TIMERID, DELAYTIME, NULL);
bca3a6 ¤   ¤   ¤   }
6a0fe4 ¤   ¤   }
8b2f68 ¤   ¤   break;
d5af5a
1a3fcf ¤   case WM_COMMAND:
011807 ¤   ¤   switch(LOWORD (wParam))·
ee5b34 ¤   ¤   {
968eee ¤   ¤   ¤   case IDC_BEGIN :
b09f20 ¤   ¤   ¤   ¤   prs = (PRANDSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
78af5a
a7fed6 ¤   ¤   ¤   ¤   if(!prs->bCollectionEnabled)
e372c3 ¤   ¤   ¤   ¤   {
ed1d3f ¤   ¤   ¤   ¤   ¤   prs->bCollectionEnabled = TRUE;
e8e4ed ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_BEGIN), FALSE);
a8d5d1 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDCANCEL), FALSE);
feaad5 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_STATIC1), TRUE);
845466 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_STATIC2), TRUE);
e501f7 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_STATIC3), TRUE);
6f200c ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TEXTPROMPT), TRUE);
20e350 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_BITSPROGBAR), TRUE);
e38cb3 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_RANDOMPROMPT, sz, sizeof(sz));
ec31a4 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_TEXTPROMPT, sz);
c9bcd5 ¤   ¤   ¤   ¤   ¤   InitRandomKeyHook(&hhookKeyboard,&hhookMouse);
7da963 ¤   ¤   ¤   ¤   ¤   SetTimer (hDlg, UPDATETIMER, UPDATETIME, NULL);
a1bc0f ¤   ¤   ¤   ¤   ¤   SetFocus(hDlg);
782613 ¤   ¤   ¤   ¤   }
49f622 ¤   ¤   ¤   ¤   break;
b5af5a
bb930a ¤   ¤   ¤   case IDCANCEL:
87139d ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_UserAbort);
f5f622 ¤   ¤   ¤   ¤   break;
d30fe4 ¤   ¤   }
0b836c ¤   ¤   return TRUE;
c89371 ¤   }
e0a230 ¤   return FALSE;
d6efe6 }
e7af5a
64d4d4 //¤ ______________________________________________
c1465d //
d7c12c // ·Entropy collection routine -- posts dialog for·
00fe8f // ·mouse/keyboard entropy collection.
40af5a
3cc744 ¤   PGPError
4751fc pgpCollectRandomDataDialogPlatform(
ef284d ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   context,
e39fde ¤   CPGPRandomDataDialogOptions ¤   *options)
bebb36 {
--a312 001e93f03e940110014 Page 3 of PGPCollectRandomDataDialog.cpp
d45a9a ¤   if (options->mTextUI) {
7f6bbc ¤   ¤   return pgpCollectRandomDataCL(context, options);
2cf037 ¤   } else {
18ae53 ¤   ¤   RANDSTRUCT¤ rs;
33d031 ¤   ¤   PGPError¤   err;
911b52 ¤   ¤
9de3a9 ¤   ¤   memset(&rs,0x00,sizeof(RANDSTRUCT));
151b52 ¤   ¤
ccc006 ¤   ¤   if (g_bEntropy)·
88014c ¤   ¤   ¤   return kPGPError_ItemAlreadyExists;
891b52 ¤   ¤
47b880 ¤   ¤   g_bEntropy=TRUE;
791b52 ¤   ¤
02e372 ¤   ¤   // if zero passed in, use default
7ffe86 ¤   ¤   if (options->mNeededEntropyBits)·
8529ed ¤   ¤   ¤   rs.lTotalNeeded = options->mNeededEntropyBits;
11ee26 ¤   ¤   else·
0e9830 ¤   ¤   ¤   rs.lTotalNeeded = PGPGlobalRandomPoolGetMinimumEntropy();
b71b52 ¤   ¤
afc6db ¤   ¤   // if we have enough already, then just return
ac3179 ¤   ¤   if (rs.lTotalNeeded < (LONG)PGPGlobalRandomPoolGetEntropy())·
a033bc ¤   ¤   ¤   return kPGPError_NoErr;
f61b52 ¤   ¤
f9b8d9 ¤   ¤   // collect the entropy
f6dae5 ¤   ¤   err = DialogBoxParam(g_hInst,
4b4e15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·MAKEINTRESOURCE (IDD_KEYRAND),·
c51537 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·options->mHwndParent,
e26aeb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(DLGPROC)KeyRandDlgProc,
450ac2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&rs);
8e1b52 ¤   ¤
4b7576 ¤   ¤   if(rs.bCollectionEnabled)
95342f ¤   ¤   ¤   UninitRandomKeyHook(hhookKeyboard,hhookMouse);
811b52 ¤   ¤
f9b5f3 ¤   ¤   g_bEntropy=FALSE;
e51b52 ¤   ¤
f2c9db ¤   ¤   return err;
6c9371 ¤   }
5cefe6 }
e9af5a
--4fdd 000b4ca3bf840110015 Page 1 of PGPKeyServerDialogs.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
7c47c3 ¤   $Id: PGPKeyServerDialogs.cpp,v 1.19.10.1 1998/11/12 03:24:16 heller Exp $
28f7f7 ____________________________________________________________________________*/
c6af5a
e794d6 #include "PGPui32.h"
becc06 #include "pgpDialogs.h"
d9f76a #include "pgpKeyServerDialogCommon.h"
46eb5b #include "pgpKeyServer.h"
077528 #include "pgpImage.h"
b4af5a
11492e // local globals
c49cad extern HINSTANCE g_hInst;
5baf5a
6e4b19 typedef struct _KEYGBL·
c9bb36 {
088f34 ¤   HWND hwndServerProgress;
d08b25 ¤   UINT mLastKeyServerState;
30599e ¤   PGPKeyServerRef mLastKeyServer;
62b34b ¤   INT iStatusValue;
226702 ¤   INT iStatusDirection;
9664a2 ¤   PGPContextRef context;
b9e170 ¤   CPGPKeyServerDialogOptions *options;
070040 ¤   PGPError err;
cb826e ¤   PGPBoolean bSearch;
2c1c16 ¤   PGPBoolean bCancel;
8a6296 ¤   HANDLE hSemaphore;
0ff5b6 ¤   DWORD dwThreadID;
0d89c6 ¤   char serverStr[255];
c457f7 ¤   HIMAGELIST hIml;
2a0f1a ¤   HANDLE hThread;
b60e5d ¤   PGPBoolean bSecureConnection;
be3da7 } KEYGBL;
51af5a
c7af5a
11c509 //¤ ____________________________________
ca465d //
3ca4ef // ·Draw the "LED" progress indicator
beaf5a
8bb7bd #define LEDTIMER¤   ¤   111L
734cc2 #define LEDTIMERPERIOD¤ 100L
29e2dd #define NUMLEDS¤¤   ¤   10
0b7fd1 #define LEDSPACING¤ ¤   2
4aaf5a
38fe80 VOID
753d36 DrawStatus (
80317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
10e2d4 ¤   ¤   INT¤¤   ¤   ¤   ¤   *iStatusValue,
8ad981 ¤   ¤   INT¤¤   ¤   ¤   ¤   *iStatusDirection)·
e4bb36 {
0c50e1 ¤   HBRUSH¤ ¤   ¤   hBrushLit, hBrushUnlit, hBrushOld;
89df75 ¤   HPEN¤   ¤   ¤   hPen, hPenOld;
0ddfcd ¤   INT¤¤   ¤   ¤   i;
7e648c ¤   INT¤¤   ¤   ¤   itop, ibot, ileft, iright, iwidth;
7fad04 ¤   PAINTSTRUCT¤¤   ps;
658bc2 ¤   HDC¤¤   ¤   ¤   hdc;
431372 ¤   RECT¤   ¤   ¤   rc;
f8af5a
3ee9eb ¤   if (*iStatusValue < -1) return;
97af5a
79079e ¤   hdc = BeginPaint (hwnd, &ps);
91af5a
fbff4c ¤   // draw 3D shadow
7047d1 ¤   GetClientRect (hwnd, &rc);
f69ae0 ¤   itop = rc.top+1;
3bc454 ¤   ibot = rc.bottom-2;
09af5a
2fd3ea ¤   iwidth = (rc.right-rc.left) / NUMLEDS;
c1962e ¤   iwidth -= LEDSPACING;
b4af5a
--97a1 000a575679b40110015 Page 2 of PGPKeyServerDialogs.cpp
9a1566 ¤   ileft = rc.left + 4;
088d6c ¤   for (i=0; i<NUMLEDS; i++) {
4f9e04 ¤   ¤   iright = ileft + iwidth;
45af5a
97855c ¤   ¤   MoveToEx (hdc, ileft, ibot, NULL);
fe99e0 ¤   ¤   LineTo (hdc, iright, ibot);
5cb146 ¤   ¤   LineTo (hdc, iright, itop);
bdaf5a
57efbc ¤   ¤   ileft += iwidth + LEDSPACING;
1b9371 ¤   }
cfaf5a
576cf6 ¤   hPen = CreatePen (PS_SOLID, 0, RGB (128, 128, 128));
16d2d7 ¤   hPenOld = SelectObject (hdc, hPen);
e36d82 ¤   hBrushLit = CreateSolidBrush (RGB (0, 255, 0));
6fee91 ¤   hBrushUnlit = CreateSolidBrush (RGB (0, 128, 0));
9eaf5a
be1566 ¤   ileft = rc.left + 4;
08af5a
6018f3 ¤   // draw "Knight Rider" LEDs
84c18a ¤   if (*iStatusDirection) {
461ae7 ¤   ¤   hBrushOld = SelectObject (hdc, hBrushUnlit);
100690 ¤   ¤   for (i=0; i<NUMLEDS; i++) {
bda36c ¤   ¤   ¤   iright = ileft + iwidth;
d767c5 ¤
541dc4 ¤   ¤   ¤   if (i == *iStatusValue) {
6ebb93 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushLit);
c3844c ¤   ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
111f85 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushUnlit);
e3a3a6 ¤   ¤   ¤   }
479905 ¤   ¤   ¤   else ·{
11844c ¤   ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
72a3a6 ¤   ¤   ¤   }
4367c5 ¤
dbd352 ¤   ¤   ¤   ileft += iwidth + LEDSPACING;
6a0fe4 ¤   ¤   }
ab9371 ¤   }
04af5a
57a806 ¤   // draw "progress bar" LEDs
c4d8f5 ¤   else {·
73df94 ¤   ¤   if (*iStatusValue >= 0)·
e5bb7c ¤   ¤   ¤   hBrushOld = SelectObject (hdc, hBrushLit);
010e1d ¤   ¤   else
aa75d4 ¤   ¤   ¤   hBrushOld = SelectObject (hdc, hBrushUnlit);
dfaf5a
b70690 ¤   ¤   for (i=0; i<NUMLEDS; i++) {
1ea36c ¤   ¤   ¤   iright = ileft + iwidth;
5e67c5 ¤
c3ed35 ¤   ¤   ¤   if (i > *iStatusValue) {
b61f85 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushUnlit);
b1a3a6 ¤   ¤   ¤   }
420b1b ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
e867c5 ¤
96d352 ¤   ¤   ¤   ileft += iwidth + LEDSPACING;
f60fe4 ¤   ¤   }
5d9371 ¤   }
38af5a
818c3c ¤   SelectObject (hdc, hBrushOld);
413570 ¤   SelectObject (hdc, hPenOld);
cd15f5 ¤   DeleteObject (hPen);
62ec46 ¤   DeleteObject (hBrushLit);
30183c ¤   DeleteObject (hBrushUnlit);
e3af5a
6400b1 ¤   EndPaint (hwnd, &ps);
09efe6 }
7aaf5a
b0bb74 void PGPsdkUICreateImageList(HIMAGELIST *hIml)
02bb36 {
0fcade ¤   int iNumBits;
448b3d ¤   HDC hDC;
dd37a3 ¤   HBITMAP hBmp;
9daf5a
a52b93 ¤   // ImageList Init
--0037 000f630e2ae40110015 Page 3 of PGPKeyServerDialogs.cpp
e0af5a
e77f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
b589fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
2de693 ¤   ReleaseDC (NULL, hDC);
77af5a
812be4 ¤   if (iNumBits <= 8) {
0f17b9 ¤   ¤   *hIml =¤ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
348fce ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
499694 ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
13a740 ¤   ¤   ImageList_AddMasked (*hIml, hBmp, RGB(255, 0, 255));
f95c8d ¤   ¤   DeleteObject (hBmp);
d19371 ¤   }
5b665a ¤   else {
6b2e2a ¤   ¤   *hIml =¤ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
f38fce ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
c6bb8b ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
0ba740 ¤   ¤   ImageList_AddMasked (*hIml, hBmp, RGB(255, 0, 255));
d75c8d ¤   ¤   DeleteObject (hBmp);
319371 ¤   }
abefe6 }
ffaf5a
4cc744 ¤   PGPError
e82d23 KeyServerCallbackProc(
8f35f6 ¤   PGPContextRef ¤ context,
af12c1 ¤   struct PGPEvent *event,
6b2e8b ¤   PGPUserValue ¤  userValue)
04bb36 {
897b25 ¤   KEYGBL¤ ¤   *pkg;
10764c ¤   PGPError¤   err ¤   ¤   = kPGPError_NoErr;
2caf5a
d4b227 ¤   pkg=(KEYGBL *)userValue;
daaf5a
50df09 ¤   if(pkg->bCancel)
b3c7a1 ¤   {
090fd8 ¤   ¤   err = kPGPError_UserAbort;
9c9371 ¤   }
7eaf5a
86a505 ¤   switch( event->type )
fac7a1 ¤   {
e3deeb ¤   ¤   case kPGPEvent_KeyServerIdleEvent:
c95b34 ¤   ¤   {
e8cdcb ¤   ¤   ¤   break;
ba0fe4 ¤   ¤   }
4a87c7 ¤   ¤   ¤
eefe34 ¤   ¤   case kPGPEvent_KeyServerEvent:
ea5b34 ¤   ¤   {
509387 ¤   ¤   ¤   if( PGPKeyServerRefIsValid(
773b29 ¤   ¤   ¤   ¤   ¤   ¤   event->data.keyServerData.keyServerRef ) &&
c9b7b1 ¤   ¤   ¤   ¤   event->data.keyServerData.keyServerRef != pkg->mLastKeyServer )
f0f776 ¤   ¤   ¤   {
fbaf00 ¤   ¤   ¤   ¤   const char¤ *hostName ¤ ¤   = NULL;
0676e4 ¤   ¤   ¤   ¤   PGPBoolean¤ freeHostName ¤  = FALSE;
57bd4f ¤   ¤   ¤   ¤   PGPUInt32¤  index;
842b85 ¤   ¤   ¤   ¤
726a79 ¤   ¤   ¤   ¤   pkg->mLastKeyServer = event->data.keyServerData.keyServerRef;
48af5a
16c467 ¤   ¤   ¤   ¤   // Set the server name:
ca2b85 ¤   ¤   ¤   ¤
49eb13 ¤   ¤   ¤   ¤   for( index = 0; index < pkg->options->mServerCount; index++ )
3272c3 ¤   ¤   ¤   ¤   {
d44998 ¤   ¤   ¤   ¤   ¤   if( pkg->options->mServerList[index].server ==·
90a80f ¤   ¤   ¤   ¤   ¤   ¤   ¤   event->data.keyServerData.keyServerRef )
084859 ¤   ¤   ¤   ¤   ¤   {
128f6b ¤   ¤   ¤   ¤   ¤   ¤   hostName = pkg->options->mServerList[index].serverName;
7000eb ¤   ¤   ¤   ¤   ¤   ¤   break;
581c89 ¤   ¤   ¤   ¤   ¤   }
762613 ¤   ¤   ¤   ¤   }
212b85 ¤   ¤   ¤   ¤
ca4528 ¤   ¤   ¤   ¤   if( IsNull( hostName ) )
6672c3 ¤   ¤   ¤   ¤   {
1f4b9e ¤   ¤   ¤   ¤   ¤   if( IsntPGPError( PGPGetKeyServerHostName(
f6bc51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkg->mLastKeyServer, (char **) &hostName ) ) )
--a108 0001726d4d340110015 Page 4 of PGPKeyServerDialogs.cpp
e04859 ¤   ¤   ¤   ¤   ¤   {
0a60ca ¤   ¤   ¤   ¤   ¤   ¤   freeHostName = TRUE;
f91c89 ¤   ¤   ¤   ¤   ¤   }
4d2613 ¤   ¤   ¤   ¤   }
512b85 ¤   ¤   ¤   ¤
c95a18 ¤   ¤   ¤   ¤   if( IsntNull( hostName ) )
6872c3 ¤   ¤   ¤   ¤   {
4aa78b ¤   ¤   ¤   ¤   ¤   strcpy( pkg->serverStr, hostName );
25ae30 ¤   ¤   ¤   ¤   ¤
557b1b ¤   ¤   ¤   ¤   ¤   if( freeHostName )
b99435 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData( (char *) hostName );
0b2613 ¤   ¤   ¤   ¤   }
7ba3a6 ¤   ¤   ¤   }
cd1b52 ¤   ¤
9c6c66 ¤   ¤   ¤   if( event->data.keyServerData.state != pkg->mLastKeyServerState )
daf776 ¤   ¤   ¤   {
72bf12 ¤   ¤   ¤   ¤   DWORD¤  newStateStrIndex = 0;
e4e829 ¤   ¤   ¤   ¤   char¤   szStatusStr[256];
5e87c7 ¤   ¤   ¤
41b56b ¤   ¤   ¤   ¤   switch( event->data.keyServerData.state )
4372c3 ¤   ¤   ¤   ¤   {
aba356 ¤   ¤   ¤   ¤   ¤   case kPGPKeyServerState_Opening:
35ec94 ¤   ¤   ¤   ¤   ¤   ¤   newStateStrIndex = IDS_KSCONNECTING;
37fad3 ¤   ¤   ¤   ¤   ¤   ¤   SetTimer (pkg->hwndServerProgress,·
440f11 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LEDTIMER, LEDTIMERPERIOD, NULL);
51a263 ¤   ¤   ¤   ¤   ¤   ¤   pkg->bSecureConnection=FALSE;
28f8fc ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect(pkg->hwndServerProgress,NULL,TRUE);
9468aa ¤   ¤   ¤   ¤   ¤   ¤   UpdateWindow(pkg->hwndServerProgress);
4c00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
ea94aa ¤   ¤   ¤   ¤   ¤   ¤
24fc99 ¤   ¤   ¤   ¤   ¤   case kPGPKeyServerState_Querying:
cf7bcc ¤   ¤   ¤   ¤   ¤   ¤   newStateStrIndex = IDS_KSSEARCHING;
6700eb ¤   ¤   ¤   ¤   ¤   ¤   break;
f1af5a
2ed0fc ¤   ¤   ¤   ¤   ¤   case kPGPKeyServerState_ProcessingResults:
693064 ¤   ¤   ¤   ¤   ¤   ¤   newStateStrIndex = IDS_KSPROCESSING;
ab00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
04af5a
4beae9 ¤   ¤   ¤   ¤   ¤   case kPGPKeyServerState_Uploading:
91e98a ¤   ¤   ¤   ¤   ¤   ¤   newStateStrIndex = IDS_KSSENDING;
9a00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
dfaf5a
a0a6e9 ¤   ¤   ¤   ¤   ¤   case kPGPKeyServerState_Deleting:
80322d ¤   ¤   ¤   ¤   ¤   ¤   newStateStrIndex = IDS_KSDELETING;
8d00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
45af5a
2989e6 ¤   ¤   ¤   ¤   ¤   case kPGPKeyServerState_Disabling:
474965 ¤   ¤   ¤   ¤   ¤   ¤   newStateStrIndex = IDS_KSDISABLING;
b000eb ¤   ¤   ¤   ¤   ¤   ¤   break;
b0af5a
fb1d5b ¤   ¤   ¤   ¤   ¤   case kPGPKeyServerState_Closing:
2bdfa5 ¤   ¤   ¤   ¤   ¤   ¤   newStateStrIndex = IDS_KSCLOSINGSEND;
7300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
ff2613 ¤   ¤   ¤   ¤   }
12af5a
973ee7 ¤   ¤   ¤   ¤   LoadString(g_hInst,
dc1806 ¤   ¤   ¤   ¤   ¤   newStateStrIndex, szStatusStr, sizeof(szStatusStr));
bfae30 ¤   ¤   ¤   ¤   ¤
6a458d ¤   ¤   ¤   ¤   if((newStateStrIndex == IDS_KSCONNECTING)||
0cdf0a ¤   ¤   ¤   ¤   ¤   (newStateStrIndex == IDS_KSSEARCHING)||
ff1692 ¤   ¤   ¤   ¤   ¤   (newStateStrIndex == IDS_KSPROCESSING)||
c398fd ¤   ¤   ¤   ¤   ¤   (newStateStrIndex == IDS_KSSENDING))
86a2e5 ¤   ¤   ¤   ¤   ¤   strcat(szStatusStr,pkg->serverStr);
f6af5a
16bdb7 ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(pkg->hwndServerProgress,IDC_PROGRESSTE¶
a13254 XT),
4ec964 ¤   ¤   ¤   ¤   ¤   szStatusStr);
1faf5a
b613ae ¤   ¤   ¤   ¤   pkg->mLastKeyServerState = (PGPKeyServerState)
663e32 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   event->data.keyServerData.state;
76a3a6 ¤   ¤   ¤   }
171b52 ¤   ¤
--474a 00002c684f840110015 Page 5 of PGPKeyServerDialogs.cpp
7ecdcb ¤   ¤   ¤   break;
690fe4 ¤   ¤   }
33af5a
5a0ff6 ¤   ¤   case kPGPEvent_KeyServerTLSEvent:
3e5b34 ¤   ¤   {
a66330 ¤   ¤   ¤   PGPEventKeyServerTLSData data = event->data.keyServerTLSData;
6767c5 ¤
2ef330 ¤   ¤   ¤   if(data.state==kPGPKeyServerState_TLSConnectionSecured)
bdf776 ¤   ¤   ¤   {
c89061 ¤   ¤   ¤   ¤   pkg->bSecureConnection=TRUE;
fdaf5a
6c3bdb ¤   ¤   ¤   ¤   InvalidateRect(pkg->hwndServerProgress,NULL,TRUE);
8d6f73 ¤   ¤   ¤   ¤   UpdateWindow(pkg->hwndServerProgress);
02a3a6 ¤   ¤   ¤   }
2f87c7 ¤   ¤   ¤
d6cdcb ¤   ¤   ¤   break;
5b0fe4 ¤   ¤   }
ee1b52 ¤   ¤
939371 ¤   }
2e67c5 ¤
4fdeb7 ¤   return( err );
48efe6 }
6aaf5a
30af5a
2d55b9 DWORD WINAPI
53a5ae KeyServerThread (LPVOID lpvoid)·
5dbb36 {
f57b25 ¤   KEYGBL¤ ¤   *pkg;
0c64a2 ¤   PGPContextRef context;
477baf ¤   PGPKeySetRef mNewKeys,mFailedKeys;
d161ae ¤   PGPKeyServerSpec *serverList;
88fe1e ¤   PGPUInt32 memamt;
faaf5a
90af5a
f4aab4 ¤   mNewKeys=mFailedKeys=NULL;
9caf5a
a59496 ¤   pkg=(KEYGBL *)lpvoid;
db7ea9 ¤   context=pkg->context;
1faf5a
9e4171 ¤   if(pkg->bSearch)
11c7a1 ¤   {
c04ba2 ¤   ¤   CPGPSearchKeyServerDialogOptions *options;
56af5a
a2d409 ¤   ¤   options=(CPGPSearchKeyServerDialogOptions *)pkg->options;
a2af5a
d3552c ¤   ¤   // Make copy of servers in case we're orphaned
42a2b4 ¤   ¤   memamt=(options->mServerCount) * sizeof(PGPKeyServerSpec);
beaf5a
4cc9a3 ¤   ¤   serverList = (PGPKeyServerSpec*)PGPNewData(
3de152 ¤   ¤   ¤   PGPGetContextMemoryMgr (context),
3e18dc ¤   ¤   ¤   memamt,kPGPMemoryMgrFlags_Clear);
94af5a
3b39be ¤   ¤   memcpy(serverList,options->mServerList,memamt);
9daf5a
ee8c5d ¤   ¤   pkg->err = PGPSearchKeyServerDialogCommon( context,
e8a38e ¤   ¤   ¤   serverList, options->mServerCount,
50b343 ¤   ¤   ¤   options->mTLSContext, options->mFilter,
a700b7 ¤   ¤   ¤   KeyServerCallbackProc, (PGPUserValue) pkg,
a79c47 ¤   ¤   ¤   options->mSearchAllServers, &mNewKeys );
a1af5a
fd8eb3 ¤   ¤   PGPFreeData(serverList);
08af5a
46509d ¤   ¤   if(!pkg->bCancel)
389971 ¤   ¤   ¤   *(options->mNewKeys)=mNewKeys;
6e9371 ¤   }
fc0e24 ¤   else
87c7a1 ¤   {
c50966 ¤   ¤   CPGPSendToKeyServerDialogOptions *options;
74af5a
a3147c ¤   ¤   options=(CPGPSendToKeyServerDialogOptions *)pkg->options;
51af5a
02552c ¤   ¤   // Make copy of servers in case we're orphaned
--7183 000009e2ad240110015 Page 6 of PGPKeyServerDialogs.cpp
6fa2b4 ¤   ¤   memamt=(options->mServerCount) * sizeof(PGPKeyServerSpec);
a9af5a
c5c9a3 ¤   ¤   serverList = (PGPKeyServerSpec*)PGPNewData(
bae152 ¤   ¤   ¤   PGPGetContextMemoryMgr (context),
5f18dc ¤   ¤   ¤   memamt,kPGPMemoryMgrFlags_Clear);
6caf5a
3439be ¤   ¤   memcpy(serverList,options->mServerList,memamt);
ccaf5a
834c1d ¤   ¤   pkg->err = PGPSendToKeyServerDialogCommon( context,
f65688 ¤   ¤   ¤   serverList, options->mTLSContext,
e2c057 ¤   ¤   ¤   options->mKeysToSend,
4600b7 ¤   ¤   ¤   KeyServerCallbackProc, (PGPUserValue) pkg,
def767 ¤   ¤   ¤   &mFailedKeys );
95af5a
f28eb3 ¤   ¤   PGPFreeData(serverList);
11af5a
86509d ¤   ¤   if(!pkg->bCancel)
bdf347 ¤   ¤   ¤   *(options->mFailedKeys)=mFailedKeys;
3b9371 ¤   }
b9af5a
68df09 ¤   if(pkg->bCancel)
75c7a1 ¤   {
59ef28 ¤   ¤   // If canceled, we have to free it
6c3b90 ¤   ¤   free(pkg);
639371 ¤   }
470e24 ¤   else
d2c7a1 ¤   {
c4285b ¤   ¤   // Kill the window and let the main thread free it
af1137 ¤   ¤   ReleaseSemaphore(pkg->hSemaphore, 1, NULL);
ad258b ¤   ¤   SendMessage(pkg->hwndServerProgress,WM_DESTROY,0,0);
2e9371 ¤   }
daaf5a
bc3e6b ¤   return 0;
46efe6 }
6caf5a
e5c426 //¤ ______________________________________________________
24465d //
bbad7b // ·Server progress dialog procedure
dfaf5a
d21c29 BOOL CALLBACK
586e34 ServerProgressDlgProc (
b54cfa ¤   ¤   ·HWND¤  hDlg,·
e28347 ¤   ¤   ·UINT¤  uMsg,·
579c37 ¤   ¤   ·WPARAM wParam,
166465 ¤   ¤   ·LPARAM lParam)·
2bbb36 {
a97b25 ¤   KEYGBL¤ ¤   *pkg;
0eaf5a
0be234 ¤   switch (uMsg)·
01c7a1 ¤   {
12df25 ¤   ¤   case WM_INITDIALOG:
315b34 ¤   ¤   {
0220eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
3ca6da ¤   ¤   ¤   pkg=(KEYGBL *)lParam;
39af5a
7a4d9b ¤   ¤   ¤   PGPsdkUICreateImageList(&(pkg->hIml));
68cd71 ¤   ¤   ¤   pkg->hwndServerProgress=hDlg;
d7af5a
2b9c6d ¤   ¤   ¤   pkg->iStatusValue = 0;
fa7978 ¤   ¤   ¤   pkg->iStatusDirection = 1;
fdaf5a
9e04ae ¤   ¤   ¤   pkg->hThread=CreateThread (NULL, 0, KeyServerThread,·
0ad5d8 ¤   ¤   ¤   ¤   (LPVOID)pkg, 0, &(pkg->dwThreadID));
7aaf5a
a732bd ¤   ¤   ¤   return TRUE;
1d0fe4 ¤   ¤   }
45af5a
23ff3e ¤   ¤   case WM_PAINT :
715b34 ¤   ¤   {
9cf63f ¤   ¤   ¤   PAINTSTRUCT¤¤   ps;
3e04c9 ¤   ¤   ¤   HDC¤¤   ¤   ¤   hdc;
00f068 ¤   ¤   ¤   int¤¤   ¤   ¤   LockIcon;
--ada6 00000c624df40110015 Page 7 of PGPKeyServerDialogs.cpp
20a06c ¤   ¤   ¤   int¤¤   ¤   ¤   rst;
3daf5a
d1a78b ¤   ¤   ¤   pkg=(KEYGBL *)GetWindowLong (hDlg, GWL_USERDATA);
c5af5a
0d2f51 ¤   ¤   ¤   // Draw lock for TLS connection
37f9ae ¤   ¤   ¤   if(pkg->bSecureConnection)
4cf5ec ¤   ¤   ¤   ¤   LockIcon=IDX_CLOSEDLOCK;
7ebb8c ¤   ¤   ¤   else
2b5a9e ¤   ¤   ¤   ¤   LockIcon=IDX_OPENLOCK;
66af5a
953736 ¤   ¤   ¤   hdc = BeginPaint (hDlg, &ps);
8caf5a
c73a96 ¤   ¤   ¤   rst=ImageList_Draw(pkg->hIml,LockIcon,
0a7740 ¤   ¤   ¤   ¤   hdc,
8b749c ¤   ¤   ¤   ¤   8,80,
ca7d6e ¤   ¤   ¤   ¤   ILD_TRANSPARENT);
73af5a
7a5dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
4eaf5a
1dd0a4 ¤   ¤   ¤   // Draw star trek progress lights
1e9beb ¤   ¤   ¤   DrawStatus (GetDlgItem (hDlg, IDC_PROGRESS),·
ce21f5 ¤   ¤   ¤   ¤   &(pkg->iStatusValue),
b6cb20 ¤   ¤   ¤   ¤   &(pkg->iStatusDirection));
34cdcb ¤   ¤   ¤   break;
080fe4 ¤   ¤   }
66af5a
432bd6 ¤   ¤   case WM_TIMER :
ee5b34 ¤   ¤   {
eca78b ¤   ¤   ¤   pkg=(KEYGBL *)GetWindowLong (hDlg, GWL_USERDATA);
a9af5a
8fcadf ¤   ¤   ¤   pkg->iStatusValue += pkg->iStatusDirection;
13f802 ¤   ¤   ¤   if (pkg->iStatusValue <= 0)·
7bf776 ¤   ¤   ¤   {
e2dd9e ¤   ¤   ¤   ¤   pkg->iStatusValue = 0;
2f7734 ¤   ¤   ¤   ¤   pkg->iStatusDirection = 1;
d7a3a6 ¤   ¤   ¤   }
123ae1 ¤   ¤   ¤   else if (pkg->iStatusValue >= NUMLEDS-1)·
98f776 ¤   ¤   ¤   {
1728b2 ¤   ¤   ¤   ¤   pkg->iStatusValue = NUMLEDS-1;
92501f ¤   ¤   ¤   ¤   pkg->iStatusDirection = -1;
21a3a6 ¤   ¤   ¤   }
5ff217 ¤   ¤   ¤   InvalidateRect (hDlg, NULL, FALSE);
8ecdcb ¤   ¤   ¤   break;
7a0fe4 ¤   ¤   }
5baf5a
10af5a
cca5e0 ¤   ¤   case WM_NOTIFY :
795b34 ¤   ¤   {
5ecdcb ¤   ¤   ¤   break;
190fe4 ¤   ¤   }
91af5a
acdad9 ¤   ¤   case WM_DESTROY:
2ed725 ¤   ¤   case WM_QUIT:
812c97 ¤   ¤   case WM_CLOSE:
be5b34 ¤   ¤   {
0ea78b ¤   ¤   ¤   pkg=(KEYGBL *)GetWindowLong (hDlg, GWL_USERDATA);
c8af5a
efcd99 ¤   ¤   ¤   DeleteObject(pkg->hIml);
ae93ae ¤   ¤   ¤   EndDialog(hDlg, 0);
cf32bd ¤   ¤   ¤   return TRUE;
6f0fe4 ¤   ¤   }
24af5a
7a1666 ¤   ¤   case WM_COMMAND :
ee5b34 ¤   ¤   {
6c256f ¤   ¤   ¤   switch(LOWORD (wParam))·
4df776 ¤   ¤   ¤   {
53ed80 ¤   ¤   ¤   ¤   case IDCANCEL :
fd72c3 ¤   ¤   ¤   ¤   {
0d0eb1 ¤   ¤   ¤   ¤   ¤   pkg=(KEYGBL *)GetWindowLong (hDlg, GWL_USERDATA);
caaf5a
e9f79f ¤   ¤   ¤   ¤   ¤   // Do the dirty deed
009e45 //¤ ¤   ¤   ¤   ¤   pkg->err=kPGPError_UserAbort;
--541f 000f5bb1e8540110015 Page 8 of PGPKeyServerDialogs.cpp
bad302 //¤ ¤   ¤   ¤   ¤   TerminateThread(pkg->hThread,0);
9eaf5a
f60580 ¤   ¤   ¤   ¤   ¤   pkg->bCancel=TRUE;
faaf5a
620053 ¤   ¤   ¤   ¤   ¤   if (pkg->mLastKeyServer)·
6f4859 ¤   ¤   ¤   ¤   ¤   {
89ac40 ¤   ¤   ¤   ¤   ¤   ¤   PGPError err;
c9af5a
dfebf1 ¤   ¤   ¤   ¤   ¤   ¤   err = PGPCancelKeyServerCall (pkg->mLastKeyServer);
743115 ¤   ¤   ¤   ¤   ¤   ¤   PGPsdkUIErrorBox (hDlg, err);
481c89 ¤   ¤   ¤   ¤   ¤   }
c9af5a
a30fd0 ¤   ¤   ¤   ¤   ¤   ReleaseSemaphore(pkg->hSemaphore, 1, NULL);
07dd07 ¤   ¤   ¤   ¤   ¤   EndDialog(hDlg, 0);
0714c3 ¤   ¤   ¤   ¤   ¤   break;
b02613 ¤   ¤   ¤   ¤   }
64af5a
3aa3a6 ¤   ¤   ¤   }
f532bd ¤   ¤   ¤   return TRUE;
d10fe4 ¤   ¤   }
db9371 ¤   }
acaf5a
eda230 ¤   return FALSE;
9befe6 }
cdaf5a
66c744 ¤   PGPError
8bdef4 pgpSearchKeyServerDialogPlatform(
0a6164 ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   ¤   context,
a4df40 ¤   CPGPSearchKeyServerDialogOptions ¤  *options)
bcbb36 {
0361e0 ¤   PGPError¤   err;
eadcbb ¤   DWORD¤  ¤   dialogID;
3c7b25 ¤   KEYGBL¤ ¤   *pkg;
4967c5 ¤
fca91d ¤   PGPValidatePtr( options );
f51b52 ¤   ¤
0b4ead ¤   err=kPGPError_NoErr;
e1af5a
fe31c8 ¤   pkg=(KEYGBL *)malloc(sizeof(KEYGBL));
474ffb ¤   if(!pkg)
4ec7a1 ¤   {
56dfbd ¤   ¤   err=kPGPError_OutOfMemory;
199371 ¤   }
490e24 ¤   else
c3c7a1 ¤   {
adee75 ¤   ¤   memset(pkg,0x00,sizeof(KEYGBL));
3caf5a
a62383 ¤   ¤   pkg->context=context;
3f2aae ¤   ¤   pkg->options=options;
add37a ¤   ¤   pkg->bSearch=TRUE;
ccaf5a
105a6b ¤   ¤   pkg->hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
48af5a
05783f ¤   ¤   if( options->mKeyDescription[0] == 0 )
4b5b34 ¤   ¤   {
b7b894 ¤   ¤   ¤   dialogID = IDD_SERVERPROGRESS;
ac0fe4 ¤   ¤   }
9b0e1d ¤   ¤   else
335b34 ¤   ¤   {
73b894 ¤   ¤   ¤   dialogID = IDD_SERVERPROGRESS;
8e0fe4 ¤   ¤   }
2d1b52 ¤   ¤
4132ce ¤   ¤   DialogBoxParam (g_hInst,·
ae38c9 ¤   ¤   ¤   MAKEINTRESOURCE(dialogID),
91ed39 ¤   ¤   ¤   options->mHwndParent,·
befaa1 ¤   ¤   ¤   (DLGPROC)ServerProgressDlgProc,·
65b266 ¤   ¤   ¤   (LPARAM)pkg);
2daf5a
40e286 ¤   ¤   WaitForSingleObject (pkg->hSemaphore, INFINITE);
b7590e ¤   ¤   CloseHandle (pkg->hSemaphore);
b497b1 ¤   ¤   CloseHandle (pkg->hThread);
f5af5a
--55fb 0019941bc7440110015 Page 9 of PGPKeyServerDialogs.cpp
e26ed8 ¤   ¤   if(pkg->bCancel)
a15b34 ¤   ¤   {
522853 ¤   ¤   ¤   // Let thread free its own memory after its done
b59768 ¤   ¤   ¤   err=kPGPError_UserAbort;
030fe4 ¤   ¤   }
d20e1d ¤   ¤   else
cd5b34 ¤   ¤   {
009c2e ¤   ¤   ¤   err=pkg->err;
9f0079 ¤   ¤   ¤   free(pkg);
320fe4 ¤   ¤   }
fc9371 ¤   }
7caf5a
b9deb7 ¤   return( err );
22efe6 }
f4af5a
09c744 ¤   PGPError
fc35f0 pgpSendToKeyServerDialogPlatform(
bf6164 ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   ¤   context,
a2c36d ¤   CPGPSendToKeyServerDialogOptions ¤  *options)
48bb36 {
5361e0 ¤   PGPError¤   err;
94dcbb ¤   DWORD¤  ¤   dialogID;
237b25 ¤   KEYGBL¤ ¤   *pkg;
95af5a
5ba91d ¤   PGPValidatePtr( options );
ec1b52 ¤   ¤
824ead ¤   err=kPGPError_NoErr;
17f72b ¤   dialogID = IDD_SERVERPROGRESS;
0267c5 ¤
1d31c8 ¤   pkg=(KEYGBL *)malloc(sizeof(KEYGBL));
334ffb ¤   if(!pkg)
2bc7a1 ¤   {
5ddfbd ¤   ¤   err=kPGPError_OutOfMemory;
d79371 ¤   }
ba0e24 ¤   else
d2c7a1 ¤   {
7cee75 ¤   ¤   memset(pkg,0x00,sizeof(KEYGBL));
1caf5a
522383 ¤   ¤   pkg->context=context;
9c2aae ¤   ¤   pkg->options=options;
62ed4d ¤   ¤   pkg->bSearch=FALSE;
03af5a
4d5a6b ¤   ¤   pkg->hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
a4af5a
7132ce ¤   ¤   DialogBoxParam (g_hInst,·
9a38c9 ¤   ¤   ¤   MAKEINTRESOURCE(dialogID),
18ed39 ¤   ¤   ¤   options->mHwndParent,·
c5faa1 ¤   ¤   ¤   (DLGPROC)ServerProgressDlgProc,·
25b266 ¤   ¤   ¤   (LPARAM)pkg);
68af5a
26e286 ¤   ¤   WaitForSingleObject (pkg->hSemaphore, INFINITE);
6c590e ¤   ¤   CloseHandle (pkg->hSemaphore);
f697b1 ¤   ¤   CloseHandle (pkg->hThread);
f5af5a
356ed8 ¤   ¤   if(pkg->bCancel)
2a5b34 ¤   ¤   {
622853 ¤   ¤   ¤   // Let thread free its own memory after its done
6f9768 ¤   ¤   ¤   err=kPGPError_UserAbort;
630fe4 ¤   ¤   }
150e1d ¤   ¤   else
125b34 ¤   ¤   {
519c2e ¤   ¤   ¤   err=pkg->err;
650079 ¤   ¤   ¤   free(pkg);
960fe4 ¤   ¤   }
669371 ¤   }
6967c5 ¤
fddeb7 ¤   return( err );
99be43 }¶
--a5e3 00098a89f2640110016 Page 1 of PGPOptionsDialog.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
fb29bf ¤   $Id: PGPOptionsDialog.cpp,v 1.16.2.2.2.1 1998/11/12 03:24:17 heller Exp $
72f7f7 ____________________________________________________________________________*/
09af5a
a407ea // Public includes:
14af5a
0794d6 #include "PGPui32.h"
31cc06 #include "pgpDialogs.h"
bcaf5a
5b7b99 #define CHECKWIDTH 19
2b9f64 #define INDENT 19
31252b #define LINESPERCONTROL 1.60
f683c9 #define COMBOSPACER 5
e4bcf5 #define COMBOYADJ 3
73af5a
f89cad extern HINSTANCE g_hInst;
141396 extern HHOOK hhookKeyboard;
2322dc extern HHOOK hhookMouse;
88af5a
1513c8 int NumLines (HDC hdc, char *pText, int Width)
3ebb36 {
83756a ¤   int ·iBreakCount ;
73afbd ¤   PSTR pBegin, pEnd ;
f5207e ¤   SIZE size ;
6850b3 ¤   int numrows;
98af5a
10a6b1 ¤   numrows = 0;
0373ee ¤   do ······························// for each text line
85c7a1 ¤   {
c72acd ¤   ¤   iBreakCount = 0 ;
ff67c5 ¤
ade685 ¤   ¤   pBegin = pText ;
29af5a
00a3cb ¤   ¤   do ··························// until the line is known
d15b34 ¤   ¤   {
461fe8 ¤   ¤   ¤   pEnd = pText ;
b6af5a
10b364 ¤   ¤   ¤   while (*pText != '\0' && *pText++ != ' ') ;
42434e ¤   ¤   ¤   if (*pText == '\0')
84aef5 ¤   ¤   ¤   ¤   break ;
f9fa0c ·····································// for each space, calculate extents
7d53da ¤   ¤   ¤   iBreakCount++ ;
6c080e ¤   ¤   ¤   SetTextJustification (hdc, 0, 0) ;
3d8033 ¤   ¤   ¤   GetTextExtentPoint32 (hdc, pBegin, pText - pBegin - 1, &size) ;
a40fe4 ¤   ¤   }
6a9fba ¤   ¤   while ((int) size.cx < Width) ;
e0af5a
4ad5bd ¤   ¤   iBreakCount-- ;
c20609 ¤   ¤   while (*(pEnd - 1) == ' ') ··// eliminate trailing blanks
0b5b34 ¤   ¤   {
1dbb96 ¤   ¤   ¤   pEnd-- ;
2c23d8 ¤   ¤   ¤   iBreakCount-- ;
ba0fe4 ¤   ¤   }
02af5a
c6b06f ¤   ¤   if (*pText == '\0' || iBreakCount <= 0)
2040d6 ¤   ¤   ¤   pEnd = pText;
a2af5a
d99996 ¤   ¤   SetTextJustification (hdc, 0, 0) ;
e16a9a ¤   ¤   GetTextExtentPoint32 (hdc, pBegin, pEnd - pBegin, &size) ;
23af5a
e23de7 ¤   ¤   numrows++;
17a01f ¤   ¤   pText = pEnd ;
071e60 ¤   } while (*pText);
28af5a
c7722e ¤   return numrows;
89efe6 }
03af5a
d5ad42 int GetClientWidth(HWND hwnd)
98bb36 {
--cfea 000e2de98c140110016 Page 2 of PGPOptionsDialog.cpp
4b5bda ¤   RECT rc;
bcaf5a
561c73 ¤   GetClientRect(hwnd,&rc);
6497f7 ¤   return(rc.right-rc.left-GetSystemMetrics(SM_CXVSCROLL));
93efe6 }
c9af5a
71a6e9 HWND MakeDescription(HWND hwndParent,
2313c9 ¤   ¤   ¤   ¤   ·HDC hdc,
01a19b ¤   ¤   ¤   ¤   ·HFONT hFont,
ed27fa ¤   ¤   ¤   ¤   ·int ID,
f6b562 ¤   ¤   ¤   ¤   ·const char *String,
30e202 ¤   ¤   ¤   ¤   ·int *y,
9f66bc ¤   ¤   ¤   ¤   ·int MaxWidth)
d5bb36 {
fb3cd4 ¤   int NumberOfLines;
726848 ¤   HWND hwndDesc;
e72508 ¤   SIZE size;
01af5a
5ba204 ¤   if(*String==0)
137ed2 ¤   ¤   return NULL;
c7af5a
0627ac ¤   GetTextExtentPoint32(hdc,String,strlen(String),&size);
43af5a
2fa33e ¤   NumberOfLines=NumLines(hdc,(char *)String,MaxWidth-INDENT);
63af5a
11412e ¤   hwndDesc = CreateWindow ("static", String,
ab8ad6 ······························WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT,
a9bddd ······························size.cy+INDENT,*y,
a279ec ······························MaxWidth-INDENT,size.cy*NumberOfLines,
e60b3b ······························hwndParent, (HMENU) ID,
13102c ······························g_hInst, NULL) ;
59af5a
cdd089 ¤   *y=(int)((double)(*y)+
7342d9 ¤   ¤   ((double)LINESPERCONTROL + (double)NumberOfLines - (double)1) * (double¶
36484b )size.cy);
cdaf5a
0e772b ¤   SendMessage(hwndDesc, WM_SETFONT,(WPARAM)hFont, MAKELPARAM(TRUE, 0));
78af5a
21937e ¤   return hwndDesc;
b2efe6 }
86af5a
a4223b HWND MakeCheckBox(HWND hwndParent,
ef13c9 ¤   ¤   ¤   ¤   ·HDC hdc,
61a19b ¤   ¤   ¤   ¤   ·HFONT hFont,
ddce80 ¤   ¤   ¤   ¤   ·PGPOUICheckboxDesc *Descriptor,
28e202 ¤   ¤   ¤   ¤   ·int *y,
b266bc ¤   ¤   ¤   ¤   ·int MaxWidth)
b5bb36 {
7af43a ¤   HWND hwndCheckBox;
282508 ¤   SIZE size;
22af5a
375eb9 ¤   GetTextExtentPoint32(hdc,Descriptor->title,strlen(Descriptor->title),&size);
daaf5a
1b4ff8 ¤   hwndCheckBox = CreateWindow ("button", Descriptor->title,
1685df ¤   ¤   WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_TABSTOP,
de1264 ········size.cy,*y,
27f741 ········size.cx+CHECKWIDTH,size.cy,
609dda ········hwndParent, (HMENU) Descriptor->itemID,
1343e0 ········g_hInst, NULL) ;
9aaf5a
95ff4e ¤   *y=(int)((double)*y + (double)size.cy * (double)LINESPERCONTROL);
daaf5a
f239d5 ¤   SendMessage(hwndCheckBox, WM_SETFONT,
135e12 ¤   ¤   (WPARAM)hFont, MAKELPARAM(TRUE, 0));
f6af5a
fd9441 ¤   Button_SetCheck (hwndCheckBox,*(Descriptor->valuePtr));
4daf5a
822abe ¤   if(Descriptor->description!=NULL)
65e19a ¤   ¤   MakeDescription(hwndParent,hdc,hFont,
a243e6 ¤   ¤   ¤   5000+Descriptor->itemID,Descriptor->description,y,MaxWidth);
4daf5a
e2cc0f ¤   SetWindowLong(hwndCheckBox, GWL_USERDATA, (DWORD)Descriptor->valuePtr); ···
--2aa2 000f197992d40110016 Page 3 of PGPOptionsDialog.cpp
e0af5a
cb56c0 ¤   return hwndCheckBox;
f3efe6 }
3eaf5a
8b89c7 int MeasureComboBox(HDC hdc,PGPOUIPopupListDesc *Descriptor)
79bb36 {
342508 ¤   SIZE size;
f09223 ¤   unsigned int itemIndex;
6e538c ¤   int ComboWidth;
26af5a
3c52c7 ¤   ComboWidth=0;
13af5a
dfe187 ¤   // Find the longest text element
5c7b46 ¤   for(itemIndex = 0; itemIndex < Descriptor->numListItems; itemIndex++)
b6c7a1 ¤   {
0cbfb7 ¤   ¤   if( IsntNull( Descriptor->listItems[itemIndex] ) )
675b34 ¤   ¤   {
886e08 ¤   ¤   ¤   GetTextExtentPoint32(hdc,Descriptor->listItems[itemIndex],
9ad92a ¤   ¤   ¤   ¤   strlen(Descriptor->listItems[itemIndex]),&size);
89714e ¤   ¤   ¤   if(size.cx>ComboWidth)ComboWidth=size.cx;
ea0fe4 ¤   ¤   }
659371 ¤   }
ebaf5a
a4a9c6 ¤   ComboWidth=ComboWidth+2*GetSystemMetrics(SM_CXVSCROLL);
a2af5a
953509 ¤   return ComboWidth;
4eefe6 }
62af5a
fbc9c7 HWND MakeComboBox(HWND hwndParent,
2213c9 ¤   ¤   ¤   ¤   ·HDC hdc,
5ba19b ¤   ¤   ¤   ¤   ·HFONT hFont,
f16b9f ¤   ¤   ¤   ¤   ·PGPOUIPopupListDesc *Descriptor,
e9e202 ¤   ¤   ¤   ¤   ·int *y,
3866bc ¤   ¤   ¤   ¤   ·int MaxWidth)
2dbb36 {
3b9f87 ¤   HWND hwndText,hwndComboBox;
572508 ¤   SIZE size;
019223 ¤   unsigned int itemIndex;
00af5a
185eb9 ¤   GetTextExtentPoint32(hdc,Descriptor->title,strlen(Descriptor->title),&size);
5caf5a
d607fc ¤   hwndText = CreateWindow ("static", Descriptor->title,
1a59e3 ¤   ¤   WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT ,
a4cf1f ¤   ¤   size.cy,*y,
c36680 ¤   ¤   size.cx,size.cy,
1369f9 ¤   ¤   hwndParent, (HMENU) (1000+Descriptor->itemID),
f46208 ¤   ¤   g_hInst, NULL) ;
4eaf5a
d8d67d ¤   SendMessage(hwndText, WM_SETFONT,
8e5e12 ¤   ¤   (WPARAM)hFont, MAKELPARAM(TRUE, 0));
f1af5a
c365dd ¤   hwndComboBox = CreateWindow ("combobox",NULL,
b6542f ¤   ¤   WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_TABSTOP,
49e08b ¤   ¤   size.cy+size.cx+COMBOSPACER,*y-COMBOYADJ,
8205e8 ¤   ¤   MeasureComboBox(hdc,Descriptor),size.cy*6,
e57846 ········hwndParent, (HMENU)Descriptor->itemID,
666208 ¤   ¤   g_hInst, NULL) ;
98af5a
3e8356 ¤   ¤   *y=(int)((double)*y + (double)size.cy * (double)(LINESPERCONTROL));
19af5a
467b46 ¤   for(itemIndex = 0; itemIndex < Descriptor->numListItems; itemIndex++)
e5c7a1 ¤   {
f4bfb7 ¤   ¤   if( IsntNull( Descriptor->listItems[itemIndex] ) )
ba5b34 ¤   ¤   {
d3d7a6 ¤   ¤   ¤   SendMessage (hwndComboBox, CB_ADDSTRING, 0,·
5cdffb ¤   ¤   ¤   ¤   (LPARAM)Descriptor->listItems[itemIndex]);
bf0fe4 ¤   ¤   }
549371 ¤   }
38af5a
74c0ae ¤   SendMessage(hwndComboBox,CB_SETCURSEL,
4335c1 ¤   ¤   (WPARAM)(*Descriptor->valuePtr-1),0);
f1af5a
--10c1 000485d79bc40110016 Page 4 of PGPOptionsDialog.cpp
401fe1 ¤   SendMessage(hwndComboBox, WM_SETFONT,
ad5e12 ¤   ¤   (WPARAM)hFont, MAKELPARAM(TRUE, 0));
4caf5a
482abe ¤   if(Descriptor->description!=NULL)
c3e19a ¤   ¤   MakeDescription(hwndParent,hdc,hFont,
7443e6 ¤   ¤   ¤   5000+Descriptor->itemID,Descriptor->description,y,MaxWidth);
e3af5a
f65849 ¤   SetWindowLong(hwndComboBox, GWL_USERDATA, (DWORD)Descriptor->valuePtr); ···
33af5a
431de7 ¤   return hwndComboBox;
d6efe6 }
1daf5a
a95ac3 int MeasureOptionsControls(HDC hdc,PGPOptionListRef options)
ffbb36 {
7eb6a3 ¤   PGPUInt32¤  optionIndex¤= 0;
751feb ¤   PGPOption¤  optionData;
754a24 ¤   int MaxWidth;
972508 ¤   SIZE size;
22af5a
8cb4bb ¤   if(options==NULL)
6e5565 ¤   ¤   return(0);
55af5a
8d2ded ¤   MaxWidth=0;
feaf5a
d18d1f ¤   /* Build list of checkboxes and/or popups */
a667c5 ¤
4194c7 ¤   while( IsntPGPError( pgpGetIndexedOption( options,
d4892e ¤   ¤   ¤   ¤   ¤   optionIndex, FALSE, &optionData ) ) )
d3c7a1 ¤   {
697015 ¤   ¤   if( optionData.type == kPGPOptionType_Checkbox )
245b34 ¤   ¤   {
3694a2 ¤   ¤   ¤   PGPOUICheckboxDesc¤ ¤   *descriptor;
b987c7 ¤   ¤   ¤
2f8b46 ¤   ¤   ¤   descriptor = (PGPOUICheckboxDesc *) optionData.value.asPtr;
c2af5a
a79acc ¤   ¤   ¤   GetTextExtentPoint32(hdc,descriptor->title,strlen(descriptor->title¶
762291 ),&size);
adaf5a
bd4c5e ¤   ¤   ¤   if(size.cx>MaxWidth)MaxWidth=size.cx;
690fe4 ¤   ¤   }
9dd267 ¤   ¤   else if( optionData.type == kPGPOptionType_PopupList )
025b34 ¤   ¤   {
1f894a ¤   ¤   ¤   PGPOUIPopupListDesc¤¤   *descriptor;
0387c7 ¤   ¤   ¤
cfc965 ¤   ¤   ¤   descriptor = (PGPOUIPopupListDesc *) optionData.value.asPtr;
efaf5a
ba9acc ¤   ¤   ¤   GetTextExtentPoint32(hdc,descriptor->title,strlen(descriptor->title¶
db2291 ),&size);
fd1da3 ¤   ¤   ¤   size.cx=size.cx+COMBOSPACER;
1c30e5 ¤   ¤   ¤   size.cx=size.cx+MeasureComboBox(hdc,descriptor);
10af5a
714c5e ¤   ¤   ¤   if(size.cx>MaxWidth)MaxWidth=size.cx;
8cec70 ¤   ¤   }¤  ¤
4d7af8 ¤   ¤   ++optionIndex;
959371 ¤   }
85af5a
10056a ¤   return MaxWidth;
01efe6 }
28af5a
22c744 ¤   PGPError
83d5a9 CreateOptionsControls(HWND hwndOptionsControl,
89b0f9 ¤   ¤   ¤   ¤   ¤   ··HDC hdc,HFONT hFont,
643bb6 ¤   ¤   ¤   ¤   ¤   ··int *ypos,int MaxWidth,
1132eb ¤   ¤   ¤   ¤   ¤   ··PGPOptionListRef options)
b8bb36 {
31764c ¤   PGPError¤   err ¤   ¤   = kPGPError_NoErr;
cdb6a3 ¤   PGPUInt32¤  optionIndex¤= 0;
3f1feb ¤   PGPOption¤  optionData;
4467c5 ¤
33b4bb ¤   if(options==NULL)
ef5afd ¤   ¤   return( err);
48af5a
--572e 000f9b0863740110016 Page 5 of PGPOptionsDialog.cpp
518d1f ¤   /* Build list of checkboxes and/or popups */
0667c5 ¤
2f94c7 ¤   while( IsntPGPError( pgpGetIndexedOption( options,
81892e ¤   ¤   ¤   ¤   ¤   optionIndex, FALSE, &optionData ) ) )
c0c7a1 ¤   {
137015 ¤   ¤   if( optionData.type == kPGPOptionType_Checkbox )
3f5b34 ¤   ¤   {
9e94a2 ¤   ¤   ¤   PGPOUICheckboxDesc¤ ¤   *descriptor;
beab9e ¤   ¤   ¤   HWND checkboxView;
3087c7 ¤   ¤   ¤
9f8b46 ¤   ¤   ¤   descriptor = (PGPOUICheckboxDesc *) optionData.value.asPtr;
b9af5a
47e2a7 ¤   ¤   ¤   checkboxView = MakeCheckBox(
35fde3 ¤   ¤   ¤   ¤   hwndOptionsControl,
b59472 ¤   ¤   ¤   ¤   hdc,hFont,
0460eb ¤   ¤   ¤   ¤   descriptor,
0f73ae ¤   ¤   ¤   ¤   ypos,MaxWidth);
b70fe4 ¤   ¤   }
2bd267 ¤   ¤   else if( optionData.type == kPGPOptionType_PopupList )
ed5b34 ¤   ¤   {
d7894a ¤   ¤   ¤   PGPOUIPopupListDesc¤¤   *descriptor;
cba8b1 ¤   ¤   ¤   HWND popupView;
3a87c7 ¤   ¤   ¤
82c965 ¤   ¤   ¤   descriptor = (PGPOUIPopupListDesc *) optionData.value.asPtr;
47af5a
f26dc2 ¤   ¤   ¤   popupView = MakeComboBox(
62fde3 ¤   ¤   ¤   ¤   hwndOptionsControl,
e39472 ¤   ¤   ¤   ¤   hdc,hFont,
ab60eb ¤   ¤   ¤   ¤   descriptor,
9673ae ¤   ¤   ¤   ¤   ypos,MaxWidth);
28ec70 ¤   ¤   }¤  ¤
717af8 ¤   ¤   ++optionIndex;
c39371 ¤   }
76af5a
7adeb7 ¤   return( err );
faefe6 }
7faf5a
8a22ab LRESULT CALLBACK CustomOptionsWndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPA¶
43b516 RAM lParam)
6dc7a1 ¤   {
f265d0 ¤   static int ·cxChar, cxCaps, cyChar,MaxWidth,NUMLINES,cxClient,cyClient,
9b27f8 ¤   ¤   iVscrollPos, iVscrollMax, iHscrollPos, iHscrollMax,
2af618 ¤   ¤   iVscrollInc,iHscrollInc;
c8af5a
c70f95 ¤   switch (iMsg)
a0c7a1 ¤   {
73b48e ¤   ¤   case WM_CREATE :
b75b34 ¤   ¤   {
4caa23 ¤   ¤   ¤   PGPOptionListRef options;
3faaf0 ¤   ¤   ¤   LPCREATESTRUCT lpcs;
1a4836 ¤   ¤   ¤   HFONT hFont;
462c5a ¤   ¤   ¤   LOGFONT lf;
35d076 ¤   ¤   ¤   int ypos;
b2f34f ¤   ¤   ¤   HDC hdc;
78d4c9 ¤   ¤   ¤   TEXTMETRIC tm;
de6c10 ¤   ¤   ¤   int HeaderWidths;
0987c7 ¤   ¤   ¤
09ccb2 ¤   ¤   ¤   lpcs=(LPCREATESTRUCT)lParam;
fdb9c1 ¤   ¤   ¤   options=(PGPOptionListRef)lpcs->lpCreateParams;
5bfcbb ¤   ¤   ¤   SetWindowLong(hwnd, GWL_USERDATA, (DWORD)options); ···
d9af5a
41435c ¤   ¤   ¤   SystemParametersInfo (SPI_GETICONTITLELOGFONT,·
74e7c2 ¤   ¤   ¤   ¤   sizeof(LOGFONT), &lf, 0);
6caf5a
97bdfd ¤   ¤   ¤   hFont=CreateFontIndirect (&lf);
efb1bb ¤   ¤   ¤   ¤   ···
dfbb6b ¤   ¤   ¤   hdc=GetDC(hwnd);
51a1f8 ¤   ¤   ¤   SelectObject(hdc,hFont);
92af5a
887f8a ¤   ¤   ¤   GetTextMetrics (hdc, &tm) ;
4a8a5a ¤   ¤   ¤   cxChar = tm.tmAveCharWidth ;
f949ab ¤   ¤   ¤   cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
--83f8 000b0b50c2b40110016 Page 6 of PGPOptionsDialog.cpp
ec2b83 ¤   ¤   ¤   cyChar = tm.tmHeight + tm.tmExternalLeading ;
d9af5a
e02264 ¤   ¤   ¤   MaxWidth = GetClientWidth(hwnd)-2*cyChar;
fbaf5a
cd08d1 ¤   ¤   ¤   HeaderWidths=MeasureOptionsControls(hdc,options);
caaf5a
0c2899 ¤   ¤   ¤   if(HeaderWidths>MaxWidth)MaxWidth=HeaderWidths;
cfaf5a
65549a ¤   ¤   ¤   ypos=cyChar;
0faf5a
62aff4 ¤   ¤   ¤   CreateOptionsControls(hwnd,hdc,hFont,&ypos,MaxWidth,options);
0aaf5a
6856bb ¤   ¤   ¤   ypos+=cyChar; // margin at bottom?
5baf5a
b07eed ¤   ¤   ¤   ReleaseDC(hwnd,hdc);
a2af5a
4974c4 ¤   ¤   ¤   NUMLINES=ypos/cyChar;
4eaf5a
90a8b2 ¤   ¤   ¤   return 0 ;
4f0fe4 ¤   ¤   }
b8af5a
7f8e1e ¤   ¤   case WM_COMMAND:
415b34 ¤   ¤   {
c6a3bb ¤   ¤   ¤   HWND hwndItem;
07af5a
b80e10 ¤   ¤   ¤   hwndItem=(HWND)lParam;
e8af5a
54e50f ¤   ¤   ¤   if(hwndItem!=NULL)
8be39b ¤   ¤   ¤   {¤  ¤   ¤
a7193d ¤   ¤   ¤   ¤   DWORD *Data;
4796fe ¤   ¤   ¤   ¤   char WinClass[255];
08af5a
24957d ¤   ¤   ¤   ¤   Data=(DWORD *)GetWindowLong(hwndItem,GWL_USERDATA);
679dd3 ¤   ¤   ¤   ¤   GetClassName(hwndItem,WinClass,255);
b7af5a
11ebf6 ¤   ¤   ¤   ¤   if(!strcmp(WinClass,"Button"))
2072c3 ¤   ¤   ¤   ¤   {
c9a6de ¤   ¤   ¤   ¤   ¤   *Data=!*Data;
f69d76 ¤   ¤   ¤   ¤   ¤   Button_SetCheck(hwndItem,*Data);
542613 ¤   ¤   ¤   ¤   }
baaf5a
f3b240 ¤   ¤   ¤   ¤   if(!strcmp(WinClass,"ComboBox"))
d272c3 ¤   ¤   ¤   ¤   {
f98763 ¤   ¤   ¤   ¤   ¤   if(HIWORD(wParam)==CBN_SELCHANGE)
1d4859 ¤   ¤   ¤   ¤   ¤   {
e3464a ¤   ¤   ¤   ¤   ¤   ¤   *Data=SendMessage(hwndItem,CB_GETCURSEL,0,0)+1;
cb1c89 ¤   ¤   ¤   ¤   ¤   }
802613 ¤   ¤   ¤   ¤   }
3da3a6 ¤   ¤   ¤   }
a38144 ¤   ¤   ¤   return 0;
170fe4 ¤   ¤   }
a1af5a
1f49e7 ¤   ¤   ¤   case WM_SIZE :
cdf776 ¤   ¤   ¤   {
45c8eb ¤   ¤   ¤   ¤   int x,y;
6aaf5a
faa8ee ···············cxClient = LOWORD (lParam) ;
b3fd7d ···············cyClient = HIWORD (lParam) ;
7eaf5a
1d77a1 ¤   ¤   ¤   ···iVscrollPos=iHscrollPos=0;
11af5a
395f7f ···············iVscrollMax = max (0, NUMLINES - cyClient/ cyChar) ;
ab26c8 ¤   ¤   ¤   ···
fd6e50 ···············x = min (iVscrollPos, iVscrollMax) ;
b357f3 ¤   ¤   ¤   ···y = x - iVscrollPos;
83af5a
14ba80 ···············ScrollWindow (hwnd, 0, -cyChar * y, NULL, NULL) ;
ccaf5a
1fcea7 ¤   ¤   ¤   ···iVscrollPos=x;
672b85 ¤   ¤   ¤   ¤
c84565 ···············SetScrollRange (hwnd, SB_VERT, 0, iVscrollMax, FALSE) ;
b03e8a ···¤¤   ¤   ···SetScrollPos ··(hwnd, SB_VERT, iVscrollPos, TRUE) ; ······
--40ee 000afff986540110016 Page 7 of PGPOptionsDialog.cpp
e0af5a
0b8458 ···············iHscrollMax = max (0, 2 + (MaxWidth + 2*cyChar - cxClient) / cxC¶
4d72d3 har) ;
d8329f ···············x = min (iHscrollPos, iHscrollMax) ;
6c4f0a ¤   ¤   ¤   ···y = x - iHscrollPos;
a6af5a
f1ef60 ¤   ¤   ¤   ···ScrollWindow (hwnd, -cxChar * y, 0, NULL, NULL) ;
44af5a
39f97e ¤   ¤   ¤   ···iHscrollPos=x;
64af5a
4435c0 ···············SetScrollRange (hwnd, SB_HORZ, 0, iHscrollMax, FALSE) ;
2310c0 ···············SetScrollPos ··(hwnd, SB_HORZ, iHscrollPos, TRUE) ;
8837d4 ···············return 0 ;
46a3a6 ¤   ¤   ¤   }
71af5a
5fc696 ··········case WM_VSCROLL :
df45c2 ¤   ¤   ¤   ··{
869963 ···············switch (LOWORD (wParam))
868ae9 ····················{
e1711b ····················case SB_TOP :
dc31c1 ·························iVscrollInc = -iVscrollPos ;
2ebffa ·························break ;
72af5a
c531fd ····················case SB_BOTTOM :
c0bb3f ·························iVscrollInc = iVscrollMax - iVscrollPos ;
98bffa ·························break ;
6aaf5a
ce5d5a ····················case SB_LINEUP :
ac14ec ·························iVscrollInc = -1 ;
4abffa ·························break ;
0baf5a
e36b8d ····················case SB_LINEDOWN :
d497b1 ·························iVscrollInc = 1 ;
9bbffa ·························break ;
cbaf5a
418e64 ····················case SB_PAGEUP :
d09436 ·························iVscrollInc = min (-1, -cyClient / cyChar) ;
47bffa ·························break ;
5caf5a
49a329 ····················case SB_PAGEDOWN :
0975cf ·························iVscrollInc = max (1, cyClient / cyChar) ;
2bbffa ·························break ;
7eaf5a
48b290 ····················case SB_THUMBTRACK :
8f1d97 ·························iVscrollInc = HIWORD (wParam) - iVscrollPos ;
eabffa ·························break ;
66af5a
c91ea9 ····················default :
918b0a ·························iVscrollInc = 0 ;
f3de39 ····················}
d0e9a4 ···············iVscrollInc = max (-iVscrollPos,
24901d ·····························min (iVscrollInc, iVscrollMax - iVscrollPos)) ;
94af5a
541a38 ···············if (iVscrollInc != 0)
3c8ae9 ····················{
c55e08 ····················iVscrollPos += iVscrollInc ;
673950 ····················ScrollWindow (hwnd, 0, -cyChar * iVscrollInc, NULL, NULL) ;
5cc663 ····················SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
17e9e1 ····················UpdateWindow (hwnd) ;
92de39 ····················}
2537d4 ···············return 0 ;
fa1112 ¤   ¤   ¤   ··}
69af5a
59953f ··········case WM_HSCROLL :
3d5b34 ¤   ¤   {
ff9963 ···············switch (LOWORD (wParam))
cc8ae9 ····················{
435d5a ····················case SB_LINEUP :
791f5c ·························iHscrollInc = -1 ;
a8bffa ·························break ;
a3af5a
af6b8d ····················case SB_LINEDOWN :
--1f1e 000e33d9ca040110016 Page 8 of PGPOptionsDialog.cpp
227f0a ·························iHscrollInc = 1 ;
78bffa ·························break ;
deaf5a
fe8e64 ····················case SB_PAGEUP :
5de63f ·························iHscrollInc = -8 ;
d4bffa ·························break ;
3aaf5a
1fa329 ····················case SB_PAGEDOWN :
f58669 ·························iHscrollInc = 8 ;
53bffa ·························break ;
c8af5a
1b053f ····················case SB_THUMBPOSITION :
8b0111 ·························iHscrollInc = HIWORD (wParam) - iHscrollPos ;
03bffa ·························break ;
87af5a
941ea9 ····················default :
8163b1 ·························iHscrollInc = 0 ;
88a3a6 ¤   ¤   ¤   }
7daf5a
20719a ¤   ¤   ¤   iHscrollInc = max (-iHscrollPos,
5aaf6c ¤   ¤   ¤   ¤   min (iHscrollInc, iHscrollMax - iHscrollPos)) ;
27af5a
a4f503 ¤   ¤   ¤   if (iHscrollInc != 0)
36f776 ¤   ¤   ¤   {
bcb35e ¤   ¤   ¤   ¤   iHscrollPos += iHscrollInc ;
b383ed ¤   ¤   ¤   ¤   ScrollWindow (hwnd, -cxChar * iHscrollInc, 0, NULL, NULL) ;
a69741 ¤   ¤   ¤   ¤   SetScrollPos (hwnd, SB_HORZ, iHscrollPos, TRUE) ;
93a3a6 ¤   ¤   ¤   }
d0a8b2 ¤   ¤   ¤   return 0 ;
750fe4 ¤   ¤   }
87af5a
769371 ¤   }
08af5a
4de467 ¤   return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
aaefe6 }
97af5a
d8d36b HWND CreateOptionsControl(HWND hwndParent,
d8aac1 ¤   PGPOptionListRef options,
5f29a2 ¤   int x,int y,int dx,int dy)
35bb36 {
80fc9e ¤   static char szClassName[] = "CustomOptionsControl" ;
514d61 ¤   WNDCLASSEX ·wndclass ;
3e9d1d ¤   HWND hwndOptionsWindow;
efaf5a
0f9e0c ¤   wndclass.cbSize ·······= sizeof (wndclass) ;
7c2ecd ¤   wndclass.style ········= CS_HREDRAW | CS_VREDRAW ;
bb4d2d ¤   wndclass.lpfnWndProc ··= CustomOptionsWndProc ;
a90122 ¤   wndclass.cbClsExtra ···= 0 ;
773fd7 ¤   wndclass.cbWndExtra ···= 0 ;
2fe894 ¤   wndclass.hInstance ····= g_hInst ;
88d96d ¤   wndclass.hIcon ········= LoadIcon (NULL, IDI_APPLICATION) ;
f5141e ¤   wndclass.hCursor ······= LoadCursor (NULL, IDC_ARROW) ;
d21932 ¤   wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;·
b0eed5 ¤   wndclass.lpszMenuName ·= NULL ;
1d0685 ¤   wndclass.lpszClassName = szClassName ;
583e8b ¤   wndclass.hIconSm ······= LoadIcon (NULL, IDI_APPLICATION) ;
d6af5a
a91ec5 ¤   RegisterClassEx (&wndclass) ;
c8af5a
471445 ¤   hwndOptionsWindow = CreateWindowEx (WS_EX_CONTROLPARENT,szClassName, "Custo¶
c17941 mOptionsWindow",
101954 ¤   ¤   WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_DLGFRAME | WS_TABS¶
5f5a16 TOP,
d4329a ¤   ¤   x,y,
37480e ¤   ¤   dx,dy,
0a94d7 ¤   ¤   hwndParent,NULL,g_hInst,(LPVOID)options) ;
8aaf5a
67d558 ¤   return hwndOptionsWindow;
83efe6 }
57af5a
294095 void MoveOptionsControl(HWND hDlg,HWND *hwndChild,
e344fe ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef options,
--11cb 000e825d7d640110016 Page 9 of PGPOptionsDialog.cpp
050e48 ¤   ¤   ¤   ¤   ¤   ···int x,int y,
e12655 ¤   ¤   ¤   ¤   ¤   ···int dx,int dy)
2bbb36 {
7e23b4 ¤   if(*hwndChild!=NULL)
b1c7a1 ¤   {
52bb20 ¤   ¤   InvalidateRect(*hwndChild,NULL,TRUE);
9843e0 ¤   ¤   DestroyWindow(*hwndChild);
059371 ¤   }
fa67c5 ¤
5a5fd0 ¤   *hwndChild=CreateOptionsControl(hDlg,
59d0c7 ¤   ¤   options,
a3329a ¤   ¤   x,y,
e5d0ab ¤   ¤   dx,dy);
22efe6 }
6faf5a
8c9d24 void MoveOptionsDialog(HWND hDlg,HWND *hwndChild,
f5bac9 ¤   ¤   ¤   ¤   ¤   ···CPGPOptionsDialogOptions *options,
884e9b ¤   ¤   ¤   ¤   ¤   ···int cxClient,int cyClient)
d2bb36 {
bb113e ¤   MoveOptionsControl(hDlg,hwndChild,options->mClientOptions,
2d5083 ¤   ¤   10,10,cxClient-20,cyClient-55);
a2af5a
214968 ¤   InvalidateRect(GetDlgItem(hDlg, IDOK),NULL,TRUE);
abaf5a
c16592 ¤   MoveWindow(GetDlgItem(hDlg, IDOK),
b131ca ¤   ¤   cxClient-175,cyClient-35,
2b70b4 ¤   ¤   75,25,TRUE);
4eaf5a
9b5cf1 ¤   InvalidateRect(GetDlgItem(hDlg, IDCANCEL),NULL,TRUE);
a9af5a
40c4a1 ¤   MoveWindow(GetDlgItem(hDlg, IDCANCEL),
0943f8 ¤   ¤   cxClient-85,cyClient-35,
af70b4 ¤   ¤   75,25,TRUE);
60efe6 }
c8af5a
d6af5a
1f9993 BOOL CALLBACK·
321fc7 OptionsDialogProc (HWND hDlg,·
5f8d16 ¤   ¤   ¤   ¤   ··UINT uMsg,·
34b6dd ¤   ¤   ¤   ¤   ··WPARAM wParam,·
d7b254 ¤   ¤   ¤   ¤   ··LPARAM lParam)·
b7bb36 {
6549f2 ¤   static HWND hwndChild;
c4af5a
afe234 ¤   switch (uMsg)·
a5c7a1 ¤   {
e5df25 ¤   ¤   case WM_INITDIALOG:
c950a4 ¤   ¤   { ···
7dafc0 ¤   ¤   ¤   RECT rc;
874bef ¤   ¤   ¤   CPGPOptionsDialogOptions *options;
fdaf5a
8e8940 ¤   ¤   ¤   options=(CPGPOptionsDialogOptions *)lParam;
dd38d2 ¤   ¤   ····SetWindowLong(hDlg,GWL_USERDATA,(long)options);
c0af5a
f4e3bb ¤   ¤   ¤   if(options->mPrompt!=NULL)
e09ea7 ¤   ¤   ¤   ¤   SetWindowText(hDlg,options->mPrompt);
ebaf5a
2881e9 ¤   ¤   ¤   GetClientRect(hDlg,&rc);
2c67c5 ¤
62f571 ¤   ¤   ¤   hwndChild=NULL;
78af5a
69c746 ¤   ¤   ¤   MoveOptionsDialog(hDlg,&hwndChild,options,
66d0bd ¤   ¤   ¤   ¤   rc.right-rc.left,
44f962 ¤   ¤   ¤   ¤   rc.bottom-rc.top);
bd32bd ¤   ¤   ¤   return TRUE;
240fe4 ¤   ¤   }
2eaf5a
4aab06 ¤   ¤   case WM_SIZE :
ad5b34 ¤   ¤   {
572f4c ¤   ¤   ¤   int cxClient, cyClient;
9d4bef ¤   ¤   ¤   CPGPOptionsDialogOptions *options;
e8af5a
--1071 0019852383540110016 Page 10 of PGPOptionsDialog.cpp
bb9c87 ¤   ¤   ¤   options=(CPGPOptionsDialogOptions *)
ce62b6 ¤   ¤   ¤   ¤   GetWindowLong(hDlg,GWL_USERDATA);
b7af5a
053222 ¤   ¤   ¤   cxClient = LOWORD (lParam) ;
ed67b1 ¤   ¤   ¤   cyClient = HIWORD (lParam) ;
7faf5a
3fc746 ¤   ¤   ¤   MoveOptionsDialog(hDlg,&hwndChild,options,
efe2b6 ¤   ¤   ¤   ¤   cxClient,
dfc5e5 ¤   ¤   ¤   ¤   cyClient);
d1d401 ¤   ¤   ¤   break ;
090fe4 ¤   ¤   }
60af5a
128e1e ¤   ¤   case WM_COMMAND:
bf5b34 ¤   ¤   {
0e4afd ¤   ¤   ¤   switch(wParam)
64f776 ¤   ¤   ¤   {
8ee168 ¤   ¤   ¤   ¤   case IDOK:
2472c3 ¤   ¤   ¤   ¤   {
8b46a1 ¤   ¤   ¤   ¤   ¤   EndDialog(hDlg, TRUE);
2314c3 ¤   ¤   ¤   ¤   ¤   break;
b22613 ¤   ¤   ¤   ¤   }
a3af5a
cd8722 ¤   ¤   ¤   ¤   case IDCANCEL:
c872c3 ¤   ¤   ¤   ¤   {
f02fb3 ¤   ¤   ¤   ¤   ¤   EndDialog(hDlg, FALSE);
4314c3 ¤   ¤   ¤   ¤   ¤   break;
992613 ¤   ¤   ¤   ¤   }
93a3a6 ¤   ¤   ¤   }
14cdcb ¤   ¤   ¤   break;
040fe4 ¤   ¤   }
e4af5a
8fd725 ¤   ¤   case WM_QUIT:
e12c97 ¤   ¤   case WM_CLOSE:
16a481 ¤   ¤   case WM_DESTROY :
395b34 ¤   ¤   {
706280 ¤   ¤   ¤   EndDialog(hDlg, FALSE);
55d401 ¤   ¤   ¤   break ;
120fe4 ¤   ¤   }
849371 ¤   }
a0af5a
31a230 ¤   return FALSE;
3defe6 }
53af5a
bdc744 ¤   PGPError
84a95e pgpOptionsDialogPlatform(
0c883c ¤   PGPContextRef¤  ¤   ¤   ¤   context,
28feb3 ¤   CPGPOptionsDialogOptions ¤  *options)
10bb36 {
d7c55b ¤   PGPError err = kPGPError_NoErr;
c8af5a
fd27d7 ¤   InitRandomKeyHook(&hhookKeyboard,&hhookMouse);
35af5a
519de4 ¤   DialogBoxParam(g_hInst,
d9049f ¤   ¤   MAKEINTRESOURCE(IDD_OPTIONSDIALOG),
4a3e26 ¤   ¤   options->mHwndParent,
7a59d7 ¤   ¤   (DLGPROC)OptionsDialogProc,
789a3a ¤   ¤   (LPARAM)options);
48af5a
9f2233 ¤   UninitRandomKeyHook(hhookKeyboard,hhookMouse);
55af5a
7ddeb7 ¤   return( err );
98efe6 }
--64dc 0007648d1e340110017 Page 1 of PGPPassphraseCL.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
55c344 ¤   $Id: PGPPassphraseCL.cpp,v 1.3.10.1 1998/11/12 03:24:17 heller Exp $
edf7f7 ____________________________________________________________________________*/
52af5a
effeb2 #include <stdio.h>
cebea3 #include <stdlib.h>
e2324c #include <string.h>
b1af5a
98cc06 #include "pgpDialogs.h"
a1afa7 #include "pgpPassphraseUtils.h"
f62f8d #include "pgpErrors.h"
a3688a #include "pgpCLUtils.h"
5fa076 #include "pgpKeys.h"
83af5a
8a28df #define MAXDECRYPTIONNAMECHAR¤  ¤   36
92af5a
cb91d1 // global variable structure for re-entrancy
f953ce typedef struct _GPP
01bb36 {
49ddd4 ¤   char *¤ ¤   ¤   ¤   pszPassPhrase;
c08038 ¤   char *¤ ¤   ¤   ¤   pszPassPhraseConf;
b03798 ¤   PGPInt32 iNextTabControl;
1a7448 ¤   PGPBoolean¤ ¤   ¤   ¤   bHideText;
f97925 ¤   PGPContextRef¤  ¤   context;
52f190 ¤   const CPGPPassphraseDialogOptions *options;
7ae038 } GPP;
fdaf5a
5ac795 // internal prototypes
b6d5d3 static PGPError PGPsdkCLError(PGPError);
fd63d7 static void *secAlloc(PGPContextRef, PGPUInt32);
441347 static void secFree(void*);
d1a78f static void FreePassphrases(GPP *gpp);
10583a static void ClearPassphrases(GPP *gpp);
70af5a
33f1ae static PGPError
092f0e PGPsdkUIErrorBox(PGPError error)·
96bb36 {
541398 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
5e7b4c ¤   char¤   ¤   szMessage[512];
8e67c5 ¤
bf96de ¤   if (IsPGPError (error) && (error!=kPGPError_UserAbort)) {
bef549 ¤   ¤   PGPGetErrorString (error, sizeof(szMessage), szMessage);
b0b01e ¤   ¤   printf("%s: PGP Error", szMessage);
ce9371 ¤   }
99af5a
545ea8 ¤   return err;
12efe6 }
adaf5a
fc0b1a //___________________________
91465d //
28c415 // Secure memory allocation routines
e3465d //
c4af5a
8349b1 static void *·
ae0daf secAlloc (PGPContextRef context, PGPUInt32 uBytes)·
95bb36 {
227694 ¤   PGPMemoryMgrRef¤memmgr;
ae67c5 ¤
d144b8 ¤   memmgr = PGPGetContextMemoryMgr (context);
9e3fdc ¤   return (PGPNewSecureData (memmgr, uBytes, 0));
87efe6 }
e0af5a
24daaa static void·
8c57e4 secFree (void* p)·
fdbb36 {
35f191 ¤   if (p) {
bd2fd4 ¤   ¤   memset ((char *)p, '\0', strlen((char *)p));
29be6c ¤   ¤   PGPFreeData ((char *)p);
769371 ¤   }
--2f05 0005c7644af40110017 Page 2 of PGPPassphraseCL.cpp
7aefe6 }
46af5a
5d2978 static void
fe69a8 FreePassphrases(GPP *gpp)
ebbb36 {
9103fa ¤   if (gpp->pszPassPhrase) {
1ac44d ¤   ¤   secFree(gpp->pszPassPhrase);
3b6da0 ¤   ¤   gpp->pszPassPhrase=NULL;
ca9371 ¤   }
7caf5a
572148 ¤   if (gpp->pszPassPhraseConf) {
8ad574 ¤   ¤   secFree(gpp->pszPassPhraseConf);
36614e ¤   ¤   gpp->pszPassPhraseConf=NULL;
129371 ¤   }
36af5a
44efe6 }
54af5a
f72978 static void
23417e ClearPassphrases(GPP *gpp)
60bb36 {
f66ebe ¤   if(gpp->pszPassPhraseConf) {
ffd574 ¤   ¤   secFree(gpp->pszPassPhraseConf);
29614e ¤   ¤   gpp->pszPassPhraseConf=NULL;
049371 ¤   }
87af5a
0aefe6 }
39af5a
1f2978 static void
f0c23d GetKeyString(PGPKeyRef Key,char *szNameFinal)
d3bb36 {
647a75 ¤   char¤   ¤   ¤   sz1[32],sz2[32];
a131f7 ¤   char¤   ¤   ¤   szName[kPGPMaxUserIDSize];
5c3460 ¤   PGPUInt32¤  ¤   uAlgorithm,uKeyBits;
c7d6b3 ¤   PGPUInt32¤  ¤   ¤   u;
cfaf5a
bb5012 ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, (int *)&uAlgorithm);
f2af5a
64e8bf ¤   // get key type / size info to append to name
8cb8dd ¤   strcpy (sz2, " ··(");
428428 ¤   switch (uAlgorithm)·
d7c7a1 ¤   {
f92692 ¤   case kPGPPublicKeyAlgorithm_RSA :
a5c9d7 ¤   ¤   strcat (sz2, "RSA/");
330fbd ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropBits, (int *)&uKeyBits);
de9323 ¤   ¤   sprintf (sz1, "%i", uKeyBits);
9ac78b ¤   ¤   strcat (sz2, sz1);
9c2f68 ¤   ¤   break;
ed1b52 ¤   ¤
847cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
a0c5f8 ¤   ¤   strcat (sz2, "DSS/");
fa0fbd ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropBits, (int *)&uKeyBits);
e89323 ¤   ¤   sprintf (sz1, "%i", uKeyBits);
d8c78b ¤   ¤   strcat (sz2, sz1);
992f68 ¤   ¤   break;
ae1b52 ¤   ¤
9abfad ¤   default :
e421fd ¤   ¤   strcat (sz2, "Unknown/Unknown");
b92f68 ¤   ¤   break;
b49371 ¤   }
3967c5 ¤
9eefe2 ¤   strcat (sz2, ")");
e5af5a
469ffd ¤   // get name on key
893232 ¤   PGPGetPrimaryUserIDNameBuffer (Key, sizeof(szName),szName, &u);
9eaf5a
e7e358 ¤   strcpy(szNameFinal, szName);
f632a1 ¤   strcat(szNameFinal, sz2);
1767c5 ¤
e0054c ¤   //TruncateKeyText (hdc, szName, sz2, iComboWidth, szNameFinal);
94efe6 }
c5af5a
5caf5a
--ac08 000c06abfae40110017 Page 3 of PGPPassphraseCL.cpp
917f37 //¤ ____________________________
7c465d //
5d021c // ·setup keyselection list o' keys
39465d //
d9af5a
0877be PGPBoolean·
6a492f InitSigningKeyComboBox (CPGPKeySetPassphraseDialogOptions *options)·
babb36 {
5da37c ¤   PGPKeyListRef¤  KeyList;
b9b17a ¤   PGPKeyIterRef¤  KeyIter;
627593 ¤   PGPKeyRef¤  ¤   Key;
cb6f4c ¤   PGPBoolean¤ ¤   bSecret, bRevoked, bExpired, bCanSign;
f68667 ¤   PGPBoolean¤ ¤   bAtLeastOneSecretKey;
5f81fe ¤   char¤   ¤   ¤   szNameFinal[kPGPMaxUserIDSize];
6caf5a
e5aa36 ¤   PGPOrderKeySet (options->mKeySet, kPGPValidityOrdering, &KeyList);
881953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
dfaf5a
cc5de9 ¤   bAtLeastOneSecretKey = FALSE;
5daf5a
81800a ¤   PGPKeyIterNext (KeyIter, &Key);
2ca5ad ¤   while (Key) {
238a79 ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
7b6059 ¤   ¤   if (bSecret) {
874363 ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsRevoked,
da4bc0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··(unsigned char *)&bRevoked);
dd11a3 ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsExpired,
f58d9e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··(unsigned char *)&bExpired);
ee2882 ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropCanSign,
c15934 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··(unsigned char *)&bCanSign);
8b6fd1 ¤   ¤   ¤   if (!bRevoked && !bExpired && bCanSign) {
1ceaa2 ¤   ¤   ¤   ¤   bAtLeastOneSecretKey = TRUE;
f0af5a
de5d89 ¤   ¤   ¤   ¤   GetKeyString(Key,szNameFinal);
e9af5a
01cb98 ¤   ¤   ¤   ¤   fprintf(stdout, "\n%s\n", szNameFinal);
4ea3a6 ¤   ¤   ¤   }
470fe4 ¤   ¤   }
1a455f ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
c19371 ¤   }
5211d4 ¤   PGPFreeKeyIter (KeyIter);
06a279 ¤   PGPFreeKeyList (KeyList);
91af5a
b44747 ¤   return (bAtLeastOneSecretKey);
29af5a
a2efe6 }
c1af5a
cd7750 PGPBoolean
88e76c PassphraseLengthAndQualityOK(
f5a03c ¤   CPGPPassphraseDialogOptions¤*options,
d33735 ¤   char ¤  ¤   ¤   ¤   ¤   ¤   *Passphrase)
acbb36 {
0a6c70 ¤   if (options->mMinPassphraseLength != 0) {
c544ef ¤   ¤   if(strlen(Passphrase) < options->mMinPassphraseLength) {
0ba4a5 ¤   ¤   ¤   printf("Passphrase is not of sufficient length. Please choose anoth¶
ba4c08 er.");
da5f1f ¤   ¤   ¤   return FALSE;
ba0fe4 ¤   ¤   }
e19371 ¤   }
5c67c5 ¤
15f455 ¤   if (options->mMinPassphraseQuality != 0) {
61dd94 ¤   ¤   if(PGPEstimatePassphraseQuality(Passphrase) < options->mMinPassphraseQu¶
4a0e7f ality) {
36c707 ¤   ¤   ¤   printf("Passphrase is not of sufficient quality. Please choose anot¶
3eb2b5 her.");
375f1f ¤   ¤   ¤   return FALSE;
a70fe4 ¤   ¤   }
069371 ¤   }
56af5a
73c2e7 ¤   return TRUE;
d0efe6 }
c0af5a
--7732 0001cbf116640110017 Page 4 of PGPPassphraseCL.cpp
917f37 //¤ ____________________________
7c465d //
92d376 // ·search keys for matching phrase
7faf5a
b28de9 PGPError·
b17939 ValidateSigningPhrase (GPP *gpp, char * pszPhrase, PGPKeyRef key)·
55bb36 {
6da5a0 ¤   char¤   szName[kPGPMaxUserIDSize];
5a26da ¤   char¤   sz[128];
c97ae3 ¤   char¤   sz2[kPGPMaxUserIDSize + 128];
926902 ¤   PGPSize¤size;
05a8e6 ¤   CPGPSigningPassphraseDialogOptions *options;
72af5a
ce72a1 ¤   options = (CPGPSigningPassphraseDialogOptions *)gpp->options;
24af5a
528457 ¤   // does phrase match selected key ?
d2fca9 ¤   if (PGPPassphraseIsValid (key,·
e96d51 ¤   ¤   ¤   PGPOPassphrase (gpp->context, pszPhrase),
e22d4f ¤   ¤   ¤   PGPOLastOption (gpp->context))) {
e99986 ¤   ¤   *(options->mPassphraseKeyPtr) = key;
4fb840 ¤   ¤   return kPGPError_NoErr;
d99371 ¤   }
69af5a
581df5 ¤   if (options->mFindMatchingKey) {
037c61 ¤   ¤   // does phrase match any private key ?
1e0386 ¤   ¤   key=GetKeyForPassphrase(options->mKeySet,pszPhrase,TRUE);
8caf5a
1a3360 ¤   ¤   if (key != NULL) {
4f1271 ¤   ¤   ¤   // ask user to use other key
564d54 ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (key, sizeof(szName), szName, &size);
f5b0c6 ¤   ¤   ¤   sprintf (sz2, sz, szName);
6f222a ¤   ¤   ¤   return kPGPError_BadPassphrase;
050fe4 ¤   ¤   }
1a9371 ¤   }
f5af5a
49b2d1 ¤   // phrase doesn't match any key
65620b ¤   printf("Bad Passphrase: Please re-enter\n");
7467c5 ¤
bb6f19 ¤   return kPGPError_BadPassphrase;
b0af5a
18efe6 }
45af5a
9204c9 // ****************************************************************************
8204c9 // ****************************************************************************
22af5a
871b78 #define KEYSIZE 256¤¤   // hard-coded key size XXX
4daf5a
1a9738 // Signer combo box
e5c77d PGPError
455df4 pgpSigningPassphraseCL(
336164 ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   ¤   context,
164d57 ¤   CPGPSigningPassphraseDialogOptions ¤*options)
4ebb36 {
686982 ¤   PGPError err = 0;
b46532 ¤   GPP¤gpp;
00af5a
10965c ¤   memset(&gpp,0x00,sizeof(GPP));
ce6ffb ¤   gpp.context=context;
3566d6 ¤   gpp.options=options;
ffaf5a
f5d8af ¤   /*
b65f8a ¤   ·* XXX
45ade8 ¤   ·* Currently expects to display only *ONE* key.
0f7027 ¤   ·* The caller must set the keyset in the options to consist
713889 ¤   ·* of the signing key that the caller wants this routine
3209b6 ¤   ·* to verify
43a4e3 ¤   ·*/
4667c5 ¤
c21124 ¤   // Initialize stuff
1a6c44 ¤   if (!InitSigningKeyComboBox (options)) {
f8d15f ¤   ¤   return kPGPError_UserAbort; // kPGPError_Win32_NoSecret_Key
1c9371 ¤   }
--9d00 000a1d5c34d40110017 Page 5 of PGPPassphraseCL.cpp
2a67c5 ¤
89f631 ¤   if (options->mPrompt)
73cb07 ¤   ¤   puts(options->mPrompt);
c90e24 ¤   else
58a438 ¤   ¤   printf("Need a pass phrase to use this key\n");
b667c5 ¤
179a9e ¤   // Need to ask and get Passphrase
1167c5 ¤
fba37c ¤   PGPKeyListRef¤  KeyList;
25b17a ¤   PGPKeyIterRef¤  KeyIter;
4b1502 ¤   PGPKeyRef¤  ¤   key;
d5b495 ¤   PGPOrderKeySet (options->mKeySet,kPGPValidityOrdering,&KeyList);
ca1953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
51056a ¤   PGPKeyIterNext (KeyIter, &key);
59af5a
0c19c3 ¤   while (1) {
3e92f6 ¤   ¤   FreePassphrases(&gpp);
0fe8f2 ¤   ¤   gpp.pszPassPhrase = (char *)secAlloc (gpp.context, KEYSIZE);
411003 ¤   ¤   if (gpp.pszPassPhrase) {
edff87 ¤   ¤   ¤   PGPBoolean ·bShared;
3587c7 ¤   ¤   ¤
51302b ¤   ¤   ¤   PGPInt32 len = pgpCLGetPass(stdout, gpp.pszPassPhrase, KEYSIZE);
e7a0ff ¤   ¤   ¤   if (len < 0) {
824067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
9bf622 ¤   ¤   ¤   ¤   break;
10a3a6 ¤   ¤   ¤   }
7287c7 ¤   ¤   ¤
c84352 ¤   ¤   ¤   *(options->mPassphrasePtr) = gpp.pszPassPhrase;
cc87c7 ¤   ¤   ¤
0389f5 ¤   ¤   ¤   // Check Shared status
6404b2 ¤   ¤   ¤   err = PGPGetKeyBoolean(key, kPGPKeyPropIsSecretShared, &bShared);
a987c7 ¤   ¤   ¤
567481 ¤   ¤   ¤   if (IsntPGPError(err) && bShared) {
4c8b43 ¤   ¤   ¤   ¤   // So, they want to do a shared key
7f9800 ¤   ¤   ¤   ¤   *(options->mPassphraseKeyPtr) = key;
625054 ¤   ¤   ¤   ¤   err = kPGPError_KeyUnusableForSignature;
9ef622 ¤   ¤   ¤   ¤   break;
9fa3a6 ¤   ¤   ¤   }
3f87c7 ¤   ¤   ¤
00df8c ¤   ¤   ¤   if (PassphraseLengthAndQualityOK(options,gpp.pszPassPhrase)) {
757052 ¤   ¤   ¤   ¤   if (!options->mVerifyPassphrase) {
e5b37b ¤   ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
8514c3 ¤   ¤   ¤   ¤   ¤   break;
5e2613 ¤   ¤   ¤   ¤   }
9c2b85 ¤   ¤   ¤   ¤
be14a1 ¤   ¤   ¤   ¤   err = ValidateSigningPhrase(&gpp,gpp.pszPassPhrase,key);
a42b85 ¤   ¤   ¤   ¤
fa27e8 ¤   ¤   ¤   ¤   if (IsntPGPError(err)) {
75b37b ¤   ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
9814c3 ¤   ¤   ¤   ¤   ¤   break;
d52613 ¤   ¤   ¤   ¤   }
b9042d ¤   ¤   ¤   } else {
8af6ee ¤   ¤   ¤   ¤   ClearPassphrases(&gpp);
405f7a ¤   ¤   ¤   ¤   FreePassphrases(&gpp);
50f622 ¤   ¤   ¤   ¤   break;
eca3a6 ¤   ¤   ¤   }
7745a6 ¤   ¤   } else {
6fb90c ¤   ¤   ¤   err = kPGPError_OutOfMemory;
6bcdcb ¤   ¤   ¤   break;
0a0fe4 ¤   ¤   }
f39371 ¤   }
c867c5 ¤
16075f ¤   PGPFreeKeyIter(KeyIter);
b3d056 ¤   PGPFreeKeyList(KeyList);
c51519 ¤   ClearPassphrases(&gpp);
f066cc ¤   if (err != kPGPError_NoErr)
ff92f6 ¤   ¤   FreePassphrases(&gpp);
38c7fd ¤   return(err);
8defe6 }
beaf5a
e8c77d PGPError
a14cc4 pgpPassphraseCL(
--1151 000471c12e540110017 Page 6 of PGPPassphraseCL.cpp
eeca71 ¤   PGPContextRef ¤ ¤   ¤   ¤   context,
55de84 ¤   CPGPPassphraseDialogOptions¤*options)
20bb36 {
19942e ¤   PGPError¤   err = 0;
4426a5 ¤   GPP¤¤   ¤   gpp;
50af5a
98f631 ¤   if (options->mPrompt)
fecb07 ¤   ¤   puts(options->mPrompt);
080e24 ¤   else
25d894 ¤   ¤   printf("Please enter pass phrase for secret key\n");
23af5a
9f965c ¤   memset(&gpp,0x00,sizeof(GPP));
0f6ffb ¤   gpp.context=context;
c666d6 ¤   gpp.options=options;
6867c5 ¤
7d19c3 ¤   while (1) {
8692f6 ¤   ¤   FreePassphrases(&gpp);
f5e8f2 ¤   ¤   gpp.pszPassPhrase = (char *)secAlloc (gpp.context, KEYSIZE);
f71003 ¤   ¤   if (gpp.pszPassPhrase) {
e4302b ¤   ¤   ¤   PGPInt32 len = pgpCLGetPass(stdout, gpp.pszPassPhrase, KEYSIZE);
4ba0ff ¤   ¤   ¤   if (len < 0) {
994067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
bdf622 ¤   ¤   ¤   ¤   break;
90a3a6 ¤   ¤   ¤   }
c387c7 ¤   ¤   ¤
0c4352 ¤   ¤   ¤   *(options->mPassphrasePtr) = gpp.pszPassPhrase;
4c87c7 ¤   ¤   ¤
75df8c ¤   ¤   ¤   if (PassphraseLengthAndQualityOK(options,gpp.pszPassPhrase)) {
d8bd37 ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
a7f622 ¤   ¤   ¤   ¤   break;
54042d ¤   ¤   ¤   } else {
6ef6ee ¤   ¤   ¤   ¤   ClearPassphrases(&gpp);
7c5f7a ¤   ¤   ¤   ¤   FreePassphrases(&gpp);
bba3a6 ¤   ¤   ¤   }
0245a6 ¤   ¤   } else {
64b90c ¤   ¤   ¤   err = kPGPError_OutOfMemory;
65cdcb ¤   ¤   ¤   break;
a90fe4 ¤   ¤   }
609371 ¤   }
7daf5a
481519 ¤   ClearPassphrases(&gpp);
f966cc ¤   if (err != kPGPError_NoErr)
6092f6 ¤   ¤   FreePassphrases(&gpp);
80c7fd ¤   return(err);
e2efe6 }
7baf5a
60c77d PGPError
0b1183 pgpKeyPassphraseCL(
ea284d ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   context,
5f3af6 ¤   CPGPKeyPassphraseDialogOptions¤ *options)
23bb36 {
6a0040 ¤   PGPError err;
6c6532 ¤   GPP¤gpp;
3467c5 ¤
f4965c ¤   memset(&gpp,0x00,sizeof(GPP));
646ffb ¤   gpp.context=context;
5e66d6 ¤   gpp.options=options;
e1af5a
c32073 ¤   char szNameFinal[kPGPMaxUserIDSize];
2c1436 ¤   GetKeyString(options->mDefaultKey, szNameFinal);
8e1025 ¤   fprintf(stdout, "\n%s\n", szNameFinal);
62af5a
3c19c3 ¤   while (1) {
a192f6 ¤   ¤   FreePassphrases(&gpp);
07e8f2 ¤   ¤   gpp.pszPassPhrase = (char *)secAlloc (gpp.context, KEYSIZE);
811003 ¤   ¤   if (gpp.pszPassPhrase) {
e1302b ¤   ¤   ¤   PGPInt32 len = pgpCLGetPass(stdout, gpp.pszPassPhrase, KEYSIZE);
5da0ff ¤   ¤   ¤   if (len < 0) {
ae4067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
7cf622 ¤   ¤   ¤   ¤   break;
19a3a6 ¤   ¤   ¤   }
4787c7 ¤   ¤   ¤
--62d7 001a158645440110017 Page 7 of PGPPassphraseCL.cpp
3e4352 ¤   ¤   ¤   *(options->mPassphrasePtr) = gpp.pszPassPhrase;
e987c7 ¤   ¤   ¤
ecdf8c ¤   ¤   ¤   if (PassphraseLengthAndQualityOK(options,gpp.pszPassPhrase)) {
b5317d ¤   ¤   ¤   ¤   PGPBoolean PassValid;
0d7baa ¤   ¤   ¤   ¤   PassValid = PGPPassphraseIsValid(options->mDefaultKey,
5bd4bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase(context, gpp.pszPassPhrase),
c4e09c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
031aa8 ¤   ¤   ¤   ¤   if (PassValid) {
7fb37b ¤   ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
eb14c3 ¤   ¤   ¤   ¤   ¤   break;
2bb5fc ¤   ¤   ¤   ¤   } else {
d38095 ¤   ¤   ¤   ¤   ¤   fprintf(stdout, "Wrong passphrase, reenter\n");
e72613 ¤   ¤   ¤   ¤   }
c8042d ¤   ¤   ¤   } else {
7df6ee ¤   ¤   ¤   ¤   ClearPassphrases(&gpp);
d45f7a ¤   ¤   ¤   ¤   FreePassphrases(&gpp);
75a3a6 ¤   ¤   ¤   }
4545a6 ¤   ¤   } else {
d5b90c ¤   ¤   ¤   err = kPGPError_OutOfMemory;
d5cdcb ¤   ¤   ¤   break;
790fe4 ¤   ¤   }
759371 ¤   }
07af5a
601519 ¤   ClearPassphrases(&gpp);
7a66cc ¤   if (err != kPGPError_NoErr)
d392f6 ¤   ¤   FreePassphrases(&gpp);
b5c7fd ¤   return(err);
89efe6 }
a1af5a
--2f35 0000cc485ce40110018 Page 1 of PGPPassphraseDialog.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
e09f04 ¤   $Id: PGPPassphraseDialog.cpp,v 1.54.2.2.2.1 1998/11/12 03:24:18 heller Exp $
8ef7f7 ____________________________________________________________________________*/
8baf5a
8b912a #include "stdio.h"
03ba0a #include "stdlib.h"
7494d6 #include "PGPui32.h"
6bcc06 #include "pgpDialogs.h"
67afa7 #include "pgpPassphraseUtils.h"
8dbf43 #include "PGPCL.h"
c5af5a
b828df #define MAXDECRYPTIONNAMECHAR¤  ¤   36
0aaf5a
97492e // local globals
49ebb0 HINSTANCE¤  ¤   ¤   g_hInst;
f655f7 HHOOK¤  ¤   ¤   ¤   hhookKeyboard;
88de75 HHOOK¤  ¤   ¤   ¤   hhookMouse;
2aaf5a
dd8467 HHOOK¤  ¤   ¤   ¤   hhookJournalRecord;
929e82 HHOOK¤  ¤   ¤   ¤   hhookCBT;
e4d917 HHOOK¤  ¤   ¤   ¤   hhookGetMessage;
cf1884 HHOOK¤  ¤   ¤   ¤   hhookMsgFilter;
8a59e4 HHOOK¤  ¤   ¤   ¤   hhookSysMsgFilter;
a0af5a
d591d1 // global variable structure for re-entrancy
8953ce typedef struct _GPP
7ebb36 {
9f0378 ¤   LPSTR¤  ¤   ¤   ¤   pszPassPhrase;
262a25 ¤   LPSTR¤  ¤   ¤   ¤   pszPassPhraseConf;
7ec992 ¤   LPSTR¤  ¤   ¤   ¤   szDummy;
2277e4 ¤   WNDPROC¤¤   ¤   ¤   wpOrigPhrase1Proc; ·
d3a1e3 ¤   WNDPROC¤¤   ¤   ¤   wpOrigPhrase2Proc; ·
0cff0d ¤   INT¤¤   ¤   ¤   ¤   iNextTabControl;
bebe80 ¤   BOOL¤   ¤   ¤   ¤   bHideText;
20973f ¤   HWND¤   ¤   ¤   ¤   hwndQuality;
dabc5b ¤   HWND¤   ¤   ¤   ¤   hwndMinQuality;
3f7925 ¤   PGPContextRef¤  ¤   context;
09221f ¤   HWND¤   ¤   ¤   ¤   hwndOptions;
fff190 ¤   const CPGPPassphraseDialogOptions *options;
58e038 } GPP;
75af5a
9165de // Help IDs for passphrase dialogs
9b9907 static DWORD aIds[] =·
82f0f6 {¤  ¤   ¤
2a1d47 ····IDC_HIDETYPING,¤¤   IDH_PGPCLPHRASE_HIDETYPING,·
907dfa ¤   IDC_PHRASE1,¤   ¤   IDH_PGPCLPHRASE_PHRASE,
3a2472 ¤   IDC_PHRASE2,¤   ¤   IDH_PGPCLPHRASE_CONFIRMATION,
d9de65 ¤   IDC_SIGNKEYCOMBO,¤  IDH_PGPCLPHRASE_SIGNINGKEY,
31732f ¤   IDC_KEYLISTBOX,¤¤   IDH_PGPCLPHRASE_KEYLIST,
88a4f3 ¤   IDC_PHRASEQUALITY,¤ IDH_PGPCLPHRASE_QUALITY,
bf1963 ¤   IDC_KEYNAME,¤   ¤   IDH_PGPCLPHRASE_KEYNAME,
345b1e ¤   801,¤   ¤   ¤   ¤   IDH_TEXTOUTPUT, // Hardcoded in ClientLib
fcddb5 ¤   804,¤   ¤   ¤   ¤   IDH_DETACHEDSIG, // Hardcoded in ClientLib
184434 ····0,0·
75a6fe };·
79af5a
25c77d PGPError
5948d1 PGPsdkUIErrorBox (
fd0f64 ¤   ¤   HWND hWnd,
a21751 ¤   ¤   PGPError error)·
e5bb36 {
cb1398 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
db8446 ¤   CHAR¤   ¤   szMessage[512];
8554f9 ¤   char¤   ¤   StrRes[500];
77af5a
b971e3 ¤   if (IsPGPError (error) && (error!=kPGPError_UserAbort))·
07c7a1 ¤   {
72f549 ¤   ¤   PGPGetErrorString (error, sizeof(szMessage), szMessage);
0caf5a
--1fd4 0004e1b8e5e40110018 Page 2 of PGPPassphraseDialog.cpp
505432 ¤   ¤   LoadString (g_hInst, IDS_PGPERROR, StrRes, sizeof(StrRes));
2faf5a
ab69c9 ¤   ¤   MessageBox (hWnd, szMessage, StrRes,·
ab2c85 ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
cd9371 ¤   }
20af5a
f35ea8 ¤   return err;
7cefe6 }
b0af5a
c26e23 // SetCapsLockMessageState shows or hides the caps lock message as needed.
81af5a
cba395 void SetCapsLockMessageState(HWND hdlg)
7dbb36 {
2b33d5 ¤   if (GetKeyState(VK_CAPITAL) & 1)
8fc7a1 ¤   {
1fa8ad ¤   ¤   ShowWindow(GetDlgItem(hdlg,IDC_CAPSWARNING),SW_SHOW);
a99371 ¤   }
420e24 ¤   else
64c7a1 ¤   {
bfd2f6 ¤   ¤   ShowWindow(GetDlgItem(hdlg,IDC_CAPSWARNING),SW_HIDE);
e29371 ¤   }
0fefe6 }
bbaf5a
b0d522 // Help file is located in C:\Windows\System
3813b3 void GetHelpDir(char *szHelp)
4abb36 {
2dabe0 ¤   GetSystemDirectory(szHelp,MAX_PATH);
e70984 ¤   strcat(szHelp,"\\Pgp60.hlp");
86efe6 }
38af5a
70d354 //¤ ________________________________
3c465d //
157bc5 // ·Hook procedure for WH_MOUSE hook
91de7b ··
855b1a LRESULT CALLBACK·
058fd5 MouseHookProc (
3e422d ¤   ¤   INT¤¤   iCode,·
ab17d4 ¤   ¤   WPARAM¤ wParam,·
89c0b8 ¤   ¤   LPARAM¤ lParam)·
497142 {·
4fa097 ¤   MOUSEHOOKSTRUCT* pmhs;
c7af5a
77c617 ····if (iCode >= 0)·
05c7a1 ¤   {
f4f883 ¤   ¤   pmhs = (MOUSEHOOKSTRUCT*) lParam;·
67a418 ¤   ¤   PGPGlobalRandomPoolAddMouse (pmhs->pt.x, pmhs->pt.y);
e69371 ¤   }
b7af5a
c54c69 ¤   return CallNextHookEx (hhookMouse, iCode, wParam, lParam);
9da79b }·
faaf5a
ba18d1 //¤ ___________________________________
15465d //
514c39 // ·Hook procedure for WH_KEYBOARD hook·
52af5a
10d83c ·
365b1a LRESULT CALLBACK·
311fdc GetKBHookProc (
f1422d ¤   ¤   INT¤¤   iCode,·
0b17d4 ¤   ¤   WPARAM¤ wParam,·
6fc0b8 ¤   ¤   LPARAM¤ lParam)·
107142 {·
16c617 ····if (iCode >= 0)·
60c7a1 ¤   {
94cdda ¤   ¤   PGPGlobalRandomPoolAddKeystroke (wParam);
1c9371 ¤   }
4eaf5a
843e6b ¤   return 0;
42a79b }·
bede7b ··
8418d1 //¤ ___________________________________
4e465d //
--cbeb 0004b701def40110018 Page 3 of PGPPassphraseDialog.cpp
50205f // ·Hook procedure for WH_JOURNALRECORD hook·
23af5a
95d83c ·
255b1a LRESULT CALLBACK·
64ce96 GenericHookProc (
a8422d ¤   ¤   INT¤¤   iCode,·
5b17d4 ¤   ¤   WPARAM¤ wParam,·
21c0b8 ¤   ¤   LPARAM¤ lParam)·
797142 {·
e23e6b ¤   return 0;
19a79b }·
88af5a
56af5a
f1257d void InitRandomKeyHook(HHOOK* phhookKeyboard, HHOOK* phhookMouse)
d8bb36 {
ed83a1 ¤   DWORD dwPhraseThreadID;
25af5a
1edd0c ¤   dwPhraseThreadID = GetCurrentThreadId ();
44af5a
b3a15f ¤   // the mouse and keyboard hooks trap entropy
3cd8d9 ¤   *phhookMouse = SetWindowsHookEx (WH_MOUSE,·
94eedb ¤   ¤   (int (__stdcall *)(void))MouseHookProc,·
74a5c7 ¤   ¤   NULL, dwPhraseThreadID);
245e34 ¤   *phhookKeyboard = SetWindowsHookEx (WH_KEYBOARD,·
1c7ed2 ¤   ¤   (int (__stdcall *)(void))GetKBHookProc,·
cea5c7 ¤   ¤   NULL, dwPhraseThreadID);
cbefe6 }
89af5a
07148a void UninitRandomKeyHook(HHOOK hhookKeyboard, HHOOK hhookMouse)
d2bb36 {
21096e ¤   UnhookWindowsHookEx (hhookKeyboard);
c07b4f ¤   UnhookWindowsHookEx (hhookMouse);
caefe6 }
bbaf5a
8ca234 void InstallSecurityHooks(void)
b3bb36 {
f483a1 ¤   DWORD dwPhraseThreadID;
4baf5a
58dd0c ¤   dwPhraseThreadID = GetCurrentThreadId ();
97af5a
0e52d8 ¤   // these are just to prevent sniffers from seeing these messages
088013 ¤   hhookJournalRecord = SetWindowsHookEx (WH_JOURNALRECORD,·
1c3239 ¤   ¤   (int (__stdcall *)(void))GenericHookProc,·
77a5c7 ¤   ¤   NULL, dwPhraseThreadID);
a4c9b9 ¤   hhookCBT = SetWindowsHookEx (WH_CBT,·
aa3239 ¤   ¤   (int (__stdcall *)(void))GenericHookProc,·
58a5c7 ¤   ¤   NULL, dwPhraseThreadID);
90981e ¤   hhookGetMessage = SetWindowsHookEx (WH_GETMESSAGE,·
313239 ¤   ¤   (int (__stdcall *)(void))GenericHookProc,·
d3a5c7 ¤   ¤   NULL, dwPhraseThreadID);
665a36 ¤   hhookMsgFilter = SetWindowsHookEx (WH_MSGFILTER,·
b43239 ¤   ¤   (int (__stdcall *)(void))GenericHookProc,·
63a5c7 ¤   ¤   NULL, dwPhraseThreadID);
76d22e ¤   hhookMsgFilter = SetWindowsHookEx (WH_SYSMSGFILTER,·
c23239 ¤   ¤   (int (__stdcall *)(void))GenericHookProc,·
3aa5c7 ¤   ¤   NULL, dwPhraseThreadID);
03efe6 }
c7af5a
795161 void UninstallSecurityHooks(void)
e8bb36 {
3923dc ¤   UnhookWindowsHookEx (hhookSysMsgFilter);
2d97b5 ¤   UnhookWindowsHookEx (hhookMsgFilter);
8f1aeb ¤   UnhookWindowsHookEx (hhookGetMessage);
fb863f ¤   UnhookWindowsHookEx (hhookCBT);
e0a19a ¤   UnhookWindowsHookEx (hhookJournalRecord);
08efe6 }
6baf5a
ae108d ¤   PGPUInt32
a2035b PGPEstimatePassphraseQuality(const char *passphrase)
dfbb36 {
781b3e ¤   return( pgpEstimatePassphraseQuality( passphrase ) );
4befe6 }
--5ad0 0007599a7de40110018 Page 4 of PGPPassphraseDialog.cpp
e0af5a
970b1a //___________________________
38465d //
65c415 // Secure memory allocation routines
be465d //
a3af5a
b9493a VOID*·
dc1e0a secAlloc (PGPContextRef context, UINT uBytes)·
ebbb36 {
5c7694 ¤   PGPMemoryMgrRef¤memmgr;
2aaf5a
aa44b8 ¤   memmgr = PGPGetContextMemoryMgr (context);
523fdc ¤   return (PGPNewSecureData (memmgr, uBytes, 0));
a9efe6 }
a5af5a
efaf5a
a3a1ba VOID·
fed91b secFree (VOID* p)·
84bb36 {
e6f191 ¤   if (p) {
5b6955 ¤   ¤   FillMemory ((char *)p,lstrlen((char *)p), '\0');
22be6c ¤   ¤   PGPFreeData ((char *)p);
189371 ¤   }
baefe6 }
e7af5a
4ae2b1 //¤ __________________
2e465d //
9c4c93 //¤ Wipe edit box clean
75af5a
99a1ba VOID·
838bc8 WipeEditBox (
d33ad1 ¤   ¤   GPP *gpp,
097de9 ¤   ¤   HWND hDlg,·
6f3408 ¤   ¤   UINT uID)·
67bb36 {
187cd6 ¤   CHAR*¤  p;
3f5c93 ¤   INT¤¤   i;
2eaf5a
de621d ¤   i = SendDlgItemMessage (hDlg, uID, WM_GETTEXTLENGTH, 0, 0);
7b4dd4 ¤   if (i > 0) {
f3a149 ¤   ¤   p = (char *)secAlloc (gpp->context,i+1);
784400 ¤   ¤   if (p) {
1bb668 ¤   ¤   ¤   FillMemory (p, i, ' ');
d67804 ¤   ¤   ¤   SendDlgItemMessage (hDlg, uID, WM_SETTEXT, 0, (LPARAM)p);
aeb1e8 ¤   ¤   ¤   secFree (p);
b30fe4 ¤   ¤   }
0e9371 ¤   }
d0efe6 }
8faf5a
c6951e void FreePassphrases(GPP *gpp)
37bb36 {
976d7f ¤   if(gpp->pszPassPhrase)
4cc7a1 ¤   {
9fc44d ¤   ¤   secFree(gpp->pszPassPhrase);
4f6da0 ¤   ¤   gpp->pszPassPhrase=NULL;
e99371 ¤   }
30af5a
698495 ¤   if(gpp->pszPassPhraseConf)
b9c7a1 ¤   {
96d574 ¤   ¤   secFree(gpp->pszPassPhraseConf);
0a614e ¤   ¤   gpp->pszPassPhraseConf=NULL;
969371 ¤   }
00af5a
72a049 ¤   if(gpp->szDummy)
81c7a1 ¤   {
25f2d0 ¤   ¤   secFree(gpp->szDummy);
eb0804 ¤   ¤   gpp->szDummy=NULL;
c69371 ¤   }
1befe6 }
40af5a
bdde6a void ClearPassphrases(HWND hDlg,GPP *gpp)
75bb36 {
--491a 000f9fd0e2340110018 Page 5 of PGPPassphraseDialog.cpp
85a0a3 ¤   HWND hwndPhrase1,hwndPhrase2;
c3af5a
588495 ¤   if(gpp->pszPassPhraseConf)
9bc7a1 ¤   {
c3d574 ¤   ¤   secFree(gpp->pszPassPhraseConf);
eb614e ¤   ¤   gpp->pszPassPhraseConf=NULL;
0e9371 ¤   }
bbaf5a
a7a049 ¤   if(gpp->szDummy)
3cc7a1 ¤   {
30f2d0 ¤   ¤   secFree(gpp->szDummy);
ee0804 ¤   ¤   gpp->szDummy=NULL;
369371 ¤   }
a0af5a
8a22c1 ¤   hwndPhrase1=GetDlgItem(hDlg,IDC_PHRASE1);
3e9eaa ¤   hwndPhrase2=GetDlgItem(hDlg,IDC_PHRASE2);
e7af5a
85b15f ¤   if(hwndPhrase1)
59c7a1 ¤   {
971a9d ¤   ¤   WipeEditBox (gpp,hDlg, IDC_PHRASE1);
f38929 ¤   ¤   SetWindowText (hwndPhrase1, "");
119371 ¤   }
d8af5a
475e3b ¤   if(hwndPhrase2)
d0c7a1 ¤   {
de3f50 ¤   ¤   WipeEditBox (gpp,hDlg, IDC_PHRASE2);
7103f9 ¤   ¤   SetWindowText (hwndPhrase2, "");
c19371 ¤   }
0eaf5a
dd6baf ¤   SetFocus (hwndPhrase1);
0aefe6 }
1baf5a
9b4265 //¤ ___________________________________________________
80465d //
d49a91 //¤ Message box routine using string table resource IDs
53af5a
db0218 LRESULT·
722f5a PGPsdkUIMessageBox (
723172 ¤   ¤   ·HWND¤  hWnd,·
255442 ¤   ¤   ·INT¤   iCaption,·
8376b8 ¤   ¤   ·INT¤   iMessage,
462954 ¤   ¤   ·ULONG¤ ulFlags)·
e0bb36 {
c001b5 ¤   CHAR szCaption [128];
247951 ¤   CHAR szMessage [256];
75af5a
54c237 ¤   LoadString (g_hInst, iCaption, szCaption, sizeof(szCaption));
fc7e8b ¤   LoadString (g_hInst, iMessage, szMessage, sizeof(szMessage));
03af5a
dc897a ¤   ulFlags |= MB_SETFOREGROUND;
13729f ¤   return (MessageBox (hWnd, szMessage, szCaption, ulFlags));
1aefe6 }
4caf5a
537f37 //¤ ____________________________
24465d //
c5ab44 // ·setup key display list box
64af5a
377efe BOOL·
9845ff AddKeySetToRecipientsTable (HWND hDlg,·
21249b ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPKeySetRef KeySet,
98af2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   CPGPDecryptionPassphraseDialogOptions *options)·
fbbb36 {
5075ee ¤   BOOL¤   ¤   ¤   bAtLeastOneValidSecretKey¤  = FALSE;
a02e18 ¤   UINT¤   ¤   ¤   uUnknownKeys¤   ¤   ¤   ¤   = 0;
6ea37c ¤   PGPKeyListRef¤  KeyList;
1ab17a ¤   PGPKeyIterRef¤  KeyIter;
5f7593 ¤   PGPKeyRef¤  ¤   Key;
ab51cd ¤   PGPSubKeyRef¤   SubKey;
3078fb ¤   UINT¤   ¤   ¤   u, uIndex, uKeyBits, uAlgorithm;
c595bf ¤   INT¤¤   ¤   ¤   iKeyDefault, iKeySelected;
9cb244 ¤   PGPBoolean¤ ¤   bSecret, bCanDecrypt;
f9d9ec ¤   CHAR¤   ¤   ¤   szName[kPGPMaxUserIDSize];
--2b48 000de6df3d740110018 Page 6 of PGPPassphraseDialog.cpp
edb8ac ¤   CHAR¤   ¤   ¤   sz[128];
3caf5a
f41e64 ¤   PGPOrderKeySet (KeySet, kPGPValidityOrdering, &KeyList);
811953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
bdaf5a
6549ee ¤   iKeySelected = -1;
cb4352 ¤   iKeyDefault = -1;
6faf5a
dd800a ¤   PGPKeyIterNext (KeyIter, &Key);
7a91f1 ¤   while (Key)·
ffc7a1 ¤   {
fc8a79 ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
0f5c65 ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropCanDecrypt, &bCanDecrypt);
89da57 ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, (int *)&uAlgorithm);
abdbff ¤   ¤   if (bSecret && bCanDecrypt) bAtLeastOneValidSecretKey = TRUE;
17af5a
e57d1c ¤   ¤   // get name on key
6e5170 ¤   ¤   PGPGetPrimaryUserIDNameBuffer (Key, sizeof(szName),·
c6413c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szName, &u);
54bfc4 ¤   ¤   if (u > MAXDECRYPTIONNAMECHAR)·
3d5b34 ¤   ¤   {
2eaf76 ¤   ¤   ¤   u = MAXDECRYPTIONNAMECHAR;
63b0dd ¤   ¤   ¤   lstrcat (szName, "...");
9c0fe4 ¤   ¤   }
dbee26 ¤   ¤   else·
54914e ¤   ¤   ¤   szName[u] = '\0';
59af5a
0870d5 ¤   ¤   // append key type / size info to name
84cf90 ¤   ¤   lstrcat (szName, " (");
1faf5a
69b075 ¤   ¤   switch (uAlgorithm)·
805b34 ¤   ¤   {
2823b9 ¤   ¤   ¤   case kPGPPublicKeyAlgorithm_RSA :
67a372 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_RSA, sz, sizeof(sz));
bd6ae0 ¤   ¤   ¤   ¤   lstrcat (szName, sz);
f90000 ¤   ¤   ¤   ¤   lstrcat (szName, "/");
010c28 ¤   ¤   ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropBits, (int *)&uKeyBits);
344020 ¤   ¤   ¤   ¤   wsprintf (sz, "%i", uKeyBits);
7a6ae0 ¤   ¤   ¤   ¤   lstrcat (szName, sz);
b0f622 ¤   ¤   ¤   ¤   break;
e8af5a
0c79f3 ¤   ¤   ¤   case kPGPPublicKeyAlgorithm_DSA :
201ad7 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_DH, sz, sizeof(sz));
a26ae0 ¤   ¤   ¤   ¤   lstrcat (szName, sz);
3f0000 ¤   ¤   ¤   ¤   lstrcat (szName, "/");
466143 ¤   ¤   ¤   ¤   PGPKeyIterNextSubKey (KeyIter, &SubKey);
ff23f8 ¤   ¤   ¤   ¤   if (SubKey) {
63c0f1 ¤   ¤   ¤   ¤   ¤   PGPGetSubKeyNumber (SubKey, kPGPKeyPropBits,·
6cd730 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (int *)&uKeyBits);
8f9892 ¤   ¤   ¤   ¤   ¤   wsprintf (sz, "%i", uKeyBits);
fd560e ¤   ¤   ¤   ¤   ¤   lstrcat (szName, sz);
382613 ¤   ¤   ¤   ¤   }
f417bc ¤   ¤   ¤   ¤   else lstrcat (szName, "???");
6af622 ¤   ¤   ¤   ¤   break;
eaaf5a
070082 ¤   ¤   ¤   default :
fe0bcf ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWN, sz, sizeof(sz));
416ae0 ¤   ¤   ¤   ¤   lstrcat (szName, sz);
810000 ¤   ¤   ¤   ¤   lstrcat (szName, "/");
0e6ae0 ¤   ¤   ¤   ¤   lstrcat (szName, sz);
74f622 ¤   ¤   ¤   ¤   break;
680fe4 ¤   ¤   }
14f614 ¤   ¤   lstrcat (szName, ")");
28af5a
52fa39 ¤   ¤   uIndex = SendDlgItemMessage (hDlg, IDC_KEYLISTBOX,·
b6c784 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LB_ADDSTRING, 0, (LPARAM)szName);
9c455f ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
de9371 ¤   }
6511d4 ¤   PGPFreeKeyIter (KeyIter);
00a279 ¤   PGPFreeKeyList (KeyList);
33af5a
de004f ¤   return bAtLeastOneValidSecretKey;
--feb2 000a902daf640110018 Page 7 of PGPPassphraseDialog.cpp
7aefe6 }
46af5a
5d7efe BOOL·
352ac3 InitEncryptedToKeyListBox (HWND hDlg, CPGPDecryptionPassphraseDialogOptions *op¶
0539b9 tions)·
13bb36 {
df5d94 ¤   BOOL bAtLeastOneValidSecretKey;
6eaf5a
91169c ¤   SendMessage(GetDlgItem(hDlg, IDC_KEYLISTBOX),LB_RESETCONTENT,0,0);
caaf5a
432b17 ¤   if(PGPKeySetRefIsValid( options->mKeySet ))
5bffdf ¤   ¤   bAtLeastOneValidSecretKey = AddKeySetToRecipientsTable( hDlg,options->m¶
869c4b KeySet,options );
78af5a
2ac181 ¤   if(PGPKeySetRefIsValid( *(options->mNewKeys) ))
796ca2 ¤   ¤   AddKeySetToRecipientsTable( hDlg,*(options->mNewKeys),options );
49af5a
f2b069 ¤   if( IsntNull( options->mMissingKeyIDList ) )
82c7a1 ¤   {
8be1c0 ¤   ¤   char MsgTxt[255];
9da1c7 ¤   ¤   char StrRes[500];
bdaf5a
9bb82d ¤   ¤   LoadString (g_hInst, IDS_NUMUNKNOWNKEYS, StrRes, sizeof(StrRes));
0167c5 ¤
f65473 ¤   ¤   sprintf(MsgTxt,StrRes,options->mMissingKeyIDCount);
13af5a
b3355f ¤   ¤   SendDlgItemMessage (hDlg, IDC_KEYLISTBOX, LB_INSERTSTRING, -1,·
7c13b3 ¤   ¤   ¤   (LPARAM)MsgTxt);
7c9371 ¤   }
10af5a
6281ca ¤   if(!bAtLeastOneValidSecretKey)
fec7a1 ¤   {
394cbd ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_PHRASE1), FALSE);
23a764 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHRASE1), SW_HIDE);
10f966 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_HIDETYPING), FALSE);
3311f1 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_HIDETYPING), SW_HIDE);
5f7c02 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
5f4e6e ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PROMPTSTRING), SW_HIDE);
3608d8 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_CANNOTDECRYPTTEXT),SW_SHOW);
ff9371 ¤   }
ff0e24 ¤   else
52c7a1 ¤   {
d14ec1 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_PHRASE1), TRUE);
90dd3f ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHRASE1), SW_SHOW);
a31e71 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_HIDETYPING), TRUE);
846baa ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_HIDETYPING), SW_SHOW);
447ae0 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
233435 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PROMPTSTRING), SW_SHOW);
1c7283 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_CANNOTDECRYPTTEXT),SW_HIDE);
609371 ¤   }
98af5a
0e004f ¤   return bAtLeastOneValidSecretKey;
bbefe6 }
bcaf5a
4a7f37 //¤ ____________________________
f1465d //
ec58d0 // ·Truncate text string
c4af5a
18fe80 VOID
e886fc TruncateKeyText (HDC¤   hdc,·
46cfb3 ¤   ¤   ¤   ¤   ·LPSTR¤ pszOrig,·
a31cb9 ¤   ¤   ¤   ¤   ·LPSTR¤ szInfo,·
dff65c ¤   ¤   ¤   ¤   ·INT¤   iXmax,·
41418b ¤   ¤   ¤   ¤   ·LPSTR¤ pszTrunc)·
80bb36 {
1c4acd ¤   SIZE¤   s;
bcfd88 ¤   INT¤¤   l, iW;
f3af5a
a21526 ¤   GetTextExtentPoint32 (hdc, szInfo, lstrlen (szInfo), &s);
2c0990 ¤   iXmax -= s.cx;
18af5a
a9f0a2 ¤   if (iXmax <= 0) {
--fc0f 0007a17ef2c40110018 Page 8 of PGPPassphraseDialog.cpp
1535c5 ¤   ¤   lstrcpy (pszTrunc, "");
0099bf ¤   ¤   return;
fb9371 ¤   }
21af5a
d98fde ¤   lstrcpy (pszTrunc, pszOrig);
71259b ¤   GetTextExtentPoint32 (hdc, pszOrig, lstrlen (pszOrig), &s);
73ff9b ¤   iW = s.cx + 4;
9daf5a
03bced ¤   l = lstrlen (pszOrig);
2f15bb ¤   if (l < 3) {
cc050a ¤   ¤   if (iW > iXmax) lstrcpy (pszTrunc, "");
d09371 ¤   }
7f665a ¤   else {
a4b88a ¤   ¤   l = lstrlen (pszOrig) - 3;
3d7ec2 ¤   ¤   while ((iW > iXmax) && (l >= 0)) {
a44dcb ¤   ¤   ¤   lstrcpy (&pszTrunc[l], "...");
9f1e39 ¤   ¤   ¤   GetTextExtentPoint32 (hdc, pszTrunc, lstrlen (pszTrunc), &s);
322693 ¤   ¤   ¤   iW = s.cx + 4;
3c3afb ¤   ¤   ¤   l--;
8a3b90 ¤   ¤   }¤
01413e ¤   ¤   if (l < 0) lstrcpy (pszTrunc, "");
a19371 ¤   }
7aaf5a
9f62b1 ¤   lstrcat (pszTrunc, szInfo);
8367c5 ¤
d2efe6 }
30af5a
b65a4b void GetKeyString(HDC hdc,INT iComboWidth,PGPKeyRef Key,char *szNameFinal)
c1bb36 {
bef30f ¤   CHAR¤   ¤   ¤   sz1[32],sz2[32];
aed9ec ¤   CHAR¤   ¤   ¤   szName[kPGPMaxUserIDSize];
d63460 ¤   PGPUInt32¤  ¤   uAlgorithm,uKeyBits;
c16e76 ¤   UINT¤   ¤   ¤   u;
75af5a
745012 ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, (int *)&uAlgorithm);
0eaf5a
e2e8bf ¤   // get key type / size info to append to name
021cf1 ¤   lstrcpy (sz2, " ··(");
4b8428 ¤   switch (uAlgorithm)·
cec7a1 ¤   {
3f1a7c ¤   ¤   case kPGPPublicKeyAlgorithm_RSA :
483c4b ¤   ¤   ¤   LoadString (g_hInst, IDS_RSA, sz1, sizeof(sz1));
93c54c ¤   ¤   ¤   lstrcat (sz2, sz1);
ac345c ¤   ¤   ¤   lstrcat (sz2, "/");
301a9e ¤   ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropBits, (int *)&uKeyBits);
5737eb ¤   ¤   ¤   wsprintf (sz1, "%i", uKeyBits);
22c54c ¤   ¤   ¤   lstrcat (sz2, sz1);
06cdcb ¤   ¤   ¤   break;
afaf5a
b64036 ¤   ¤   case kPGPPublicKeyAlgorithm_DSA :
83ec06 ¤   ¤   ¤   LoadString (g_hInst, IDS_DSS, sz1, sizeof(sz1));
1cc54c ¤   ¤   ¤   lstrcat (sz2, sz1);
c4345c ¤   ¤   ¤   lstrcat (sz2, "/");
ac1a9e ¤   ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropBits, (int *)&uKeyBits);
a737eb ¤   ¤   ¤   wsprintf (sz1, "%i", uKeyBits);
cdc54c ¤   ¤   ¤   lstrcat (sz2, sz1);
e2cdcb ¤   ¤   ¤   break;
e4af5a
023a18 ¤   ¤   default :
b5cf73 ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWN, sz1, sizeof(sz1));
3fc54c ¤   ¤   ¤   lstrcat (sz2, sz1);
98345c ¤   ¤   ¤   lstrcat (sz2, "/");
35c54c ¤   ¤   ¤   lstrcat (sz2, sz1);
cccdcb ¤   ¤   ¤   break;
6a9371 ¤   }
151b52 ¤   ¤
dd54ff ¤   lstrcat (sz2, ")");
6eaf5a
d19ffd ¤   // get name on key
003232 ¤   PGPGetPrimaryUserIDNameBuffer (Key, sizeof(szName),szName, &u);
b27982 ¤   TruncateKeyText (hdc, szName, sz2, iComboWidth, szNameFinal);
7aefe6 }
--27a1 0007140562840110018 Page 9 of PGPPassphraseDialog.cpp
e0af5a
1aaf5a
a97f37 //¤ ____________________________
0d465d //
e7e0fe // ·setup keyselection combo box
beaf5a
147efe BOOL·
39c924 InitSigningKeyComboBox (HWND hDlg, CPGPKeySetPassphraseDialogOptions *options)·
80bb36 {
dba37c ¤   PGPKeyListRef¤  KeyList;
ebb17a ¤   PGPKeyIterRef¤  KeyIter;
b47593 ¤   PGPKeyRef¤  ¤   Key;
040c25 ¤   PGPKeyRef¤  ¤   KeyDefault;
33687d ¤   UINT¤   ¤   ¤   uIndex;
9495bf ¤   INT¤¤   ¤   ¤   iKeyDefault, iKeySelected;
b26f4c ¤   PGPBoolean¤ ¤   bSecret, bRevoked, bExpired, bCanSign;
cc6aa8 ¤   BOOL¤   ¤   ¤   bAtLeastOneSecretKey;
4b2300 ¤   CHAR¤   ¤   ¤   szNameFinal[kPGPMaxUserIDSize];
bc8bc2 ¤   HDC¤¤   ¤   ¤   hdc;
171372 ¤   RECT¤   ¤   ¤   rc;
ce6737 ¤   INT¤¤   ¤   ¤   iComboWidth;
5eccf0 ¤   HFONT¤  ¤   ¤   hFont;
f2af5a
5aaa36 ¤   PGPOrderKeySet (options->mKeySet, kPGPValidityOrdering, &KeyList);
031953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
7c8dd2 ¤   PGPGetDefaultPrivateKey (options->mKeySet, &KeyDefault);
ffaf5a
21edeb ¤   SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO, CB_GETDROPPEDCONTROLRECT,
f22526 ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&rc);
5fc1d7 ¤   iComboWidth = rc.right-rc.left - GetSystemMetrics (SM_CXVSCROLL);
2f78e5 ¤   hdc = GetDC (GetDlgItem (hDlg, IDC_SIGNKEYCOMBO));
0182aa ¤   hFont = GetStockObject (DEFAULT_GUI_FONT);
c2ef3e ¤   SelectObject (hdc, hFont);
1aaf5a
7049ee ¤   iKeySelected = -1;
1ef9cb ¤   iKeyDefault = 0;
d6af5a
325de9 ¤   bAtLeastOneSecretKey = FALSE;
abaf5a
aa800a ¤   PGPKeyIterNext (KeyIter, &Key);
aba5ad ¤   while (Key) {
0d8a79 ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
e96059 ¤   ¤   if (bSecret) {
3ed82c ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsRevoked, (unsigned char *)&bRev¶
97197f oked);
28cd15 ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsExpired, (unsigned char *)&bExp¶
ac2671 ired);
bfac8c ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropCanSign, (unsigned char *)&bCanSi¶
16c4bc gn);
dd6fd1 ¤   ¤   ¤   if (!bRevoked && !bExpired && bCanSign) {
02eaa2 ¤   ¤   ¤   ¤   bAtLeastOneSecretKey = TRUE;
2aaf5a
72a34e ¤   ¤   ¤   ¤   GetKeyString(hdc,iComboWidth,Key,szNameFinal);
1eaf5a
ad032a ¤   ¤   ¤   ¤   uIndex = SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO,·
c91570 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_ADDSTRING, 0, (LPARAM)szNameFinal);
c4dff2 ¤   ¤   ¤   ¤   if (uIndex != CB_ERR) {
b9d3fb ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO,·
b10f04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_SETITEMDATA, uIndex, (LPARAM)Key);
756a1f ¤   ¤   ¤   ¤   ¤   if (options->mDefaultKey) {
02a4a5 ¤   ¤   ¤   ¤   ¤   ¤   if (Key == options->mDefaultKey)·
bd1ae3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iKeySelected = uIndex;
3e1c89 ¤   ¤   ¤   ¤   ¤   }
e49f3a ¤   ¤   ¤   ¤   ¤   if (Key == KeyDefault) iKeyDefault = uIndex;
572613 ¤   ¤   ¤   ¤   }
45a3a6 ¤   ¤   ¤   }
f10fe4 ¤   ¤   }
29455f ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
5a9371 ¤   }
7011d4 ¤   PGPFreeKeyIter (KeyIter);
f1a279 ¤   PGPFreeKeyList (KeyList);
71af5a
--4903 000e1e54d8640110018 Page 10 of PGPPassphraseDialog.cpp
eb2807 ¤   if (iKeySelected == -1) iKeySelected = iKeyDefault;
89371e ¤   SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO, CB_SETCURSEL,·
75a53a ¤   ¤   ¤   ¤   ¤   ¤   ¤   iKeySelected, 0);
76af5a
f03bd1 ¤   ReleaseDC (GetDlgItem (hDlg, IDC_SIGNKEYCOMBO), hdc);
88af5a
394747 ¤   return (bAtLeastOneSecretKey);
dbaf5a
36efe6 }
aaaf5a
968558 BOOL PassphraseLengthAndQualityOK(HWND hwnd,
d42a37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··CPGPPassphraseDialogOptions *options,
755987 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··char *Passphrase)
79bb36 {
81fbe1 ¤   if(options->mMinPassphraseLength!=0)
4cc7a1 ¤   {
9a72f5 ¤   ¤   if(strlen(Passphrase)<options->mMinPassphraseLength)
035b34 ¤   ¤   {
e08bc4 ¤   ¤   ¤   PGPsdkUIMessageBox (hwnd,
c85a38 ¤   ¤   ¤   ¤   IDS_PGPERROR,IDS_PASSNOTLONG,
bce840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
2aaf5a
015f1f ¤   ¤   ¤   return FALSE;
c10fe4 ¤   ¤   }
b19371 ¤   }
20af5a
bb6f85 ¤   if(options->mMinPassphraseQuality!=0)
7bc7a1 ¤   {
1b6c8d ¤   ¤   if(PGPEstimatePassphraseQuality(Passphrase)<options->mMinPassphraseQual¶
8e9fc9 ity)
655b34 ¤   ¤   {
c78bc4 ¤   ¤   ¤   PGPsdkUIMessageBox (hwnd,
881350 ¤   ¤   ¤   ¤   IDS_PGPERROR,IDS_PASSNOTQUALITY,
6ae840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
15af5a
245f1f ¤   ¤   ¤   return FALSE;
7d0fe4 ¤   ¤   }
cf9371 ¤   }
4daf5a
01c2e7 ¤   return TRUE;
64efe6 }
fdaf5a
b0391b //¤ ______________________________________________________________
51465d //
b19a2e // ·Enable or disable passphrase edit box on basis of selected key
1baf5a
cda1ba VOID·
d77979 EnablePassPhraseControl (HWND hDlg)·
1abb36 {
eca504 ¤   PGPKeyRef¤  Key;
76260e ¤   PGPBoolean¤ bNeedsPhrase,bShared;
be5e29 ¤   BOOL¤   ¤   bEnabled;
c42aea ¤   INT¤¤   ¤   i;
aeaf5a
18c17e ¤   bEnabled = FALSE;
81af5a
120f83 ¤   i = SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO, CB_GETCURSEL, 0, 0);
0010f0 ¤   if (i != CB_ERR)·
c92ec9 ¤   {¤  ¤   ¤   ¤   ¤
7f91e2 ¤   ¤   Key = (PGPKeyRef)SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO,·
db6334 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_GETITEMDATA, i, 0);
9263c1 ¤   ¤   if (Key)·
d75b34 ¤   ¤   {
984779 ¤   ¤   ¤   PGPGetKeyBoolean(Key, kPGPKeyPropNeedsPassphrase, &bNeedsPhrase);
f0472f ¤   ¤   ¤   PGPGetKeyBoolean(Key, kPGPKeyPropIsSecretShared, &bShared);
81af5a
f815a5 ¤   ¤   ¤   if(bShared)
e5f776 ¤   ¤   ¤   {
0ae587 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_PHRASE1), FALSE);
eb0e5e ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHRASE1), SW_HIDE);
0d7455 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_HIDETYPING), FALSE);
e19cc2 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_HIDETYPING), SW_HIDE);
--3356 000947de14440110018 Page 11 of PGPPassphraseDialog.cpp
a68d49 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PROMPTSTRING), SW_HIDE);
33a3b1 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_SPLITINFO),SW_SHOW);
29a3a6 ¤   ¤   ¤   }
d5bb8c ¤   ¤   ¤   else
dff776 ¤   ¤   ¤   {
fc2045 ¤   ¤   ¤   ¤   if (bNeedsPhrase) bEnabled = TRUE;
beaf5a
8f97ae ¤   ¤   ¤   ¤   if (!bEnabled)·
024193 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PHRASE1, "");
52af5a
8b626b ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_PHRASE1), bEnabled);
c87405 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHRASE1), SW_SHOW);
675859 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_HIDETYPING), bEnabled);
1ee699 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_HIDETYPING), SW_SHOW);
c6f712 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PROMPTSTRING), SW_SHOW);
d4d9ea ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_SPLITINFO),SW_HIDE);
efa3a6 ¤   ¤   ¤   }
9b0fe4 ¤   ¤   }
db9371 ¤   }
c4efe6 }
79af5a
287f37 //¤ ____________________________
b4465d //
74d376 // ·search keys for matching phrase
a8af5a
0f8de9 PGPError·
d78fcb ValidateSigningPhrase (HWND hDlg,·
a73b7a ¤   ¤   ¤   ¤   GPP *gpp,·
e8dbf4 ¤   ¤   ¤   ¤   LPSTR pszPhrase,·
3aa86d ¤   ¤   ¤   ¤   PGPKeyRef key)·
01bb36 {
b9b1dd ¤   CHAR¤   szName[kPGPMaxUserIDSize];
1c947f ¤   CHAR¤   sz[128];
83f7b5 ¤   CHAR¤   sz2[kPGPMaxUserIDSize + 128];
876902 ¤   PGPSize¤size;
28a8e6 ¤   CPGPSigningPassphraseDialogOptions *options;
0faf5a
75b05a ¤   options=(CPGPSigningPassphraseDialogOptions *)gpp->options;
24af5a
198457 ¤   // does phrase match selected key ?
acfca9 ¤   if (PGPPassphraseIsValid (key,·
396d51 ¤   ¤   ¤   PGPOPassphrase (gpp->context, pszPhrase),
792d4f ¤   ¤   ¤   PGPOLastOption (gpp->context))) {
d39986 ¤   ¤   *(options->mPassphraseKeyPtr) = key;
81b840 ¤   ¤   return kPGPError_NoErr;
1e9371 ¤   }
eaaf5a
453a09 ¤   if(options->mFindMatchingKey)
72c7a1 ¤   {
367c61 ¤   ¤   // does phrase match any private key ?
550386 ¤   ¤   key=GetKeyForPassphrase(options->mKeySet,pszPhrase,TRUE);
11af5a
b58a72 ¤   ¤   if (key!=NULL)·
f65b34 ¤   ¤   {
201271 ¤   ¤   ¤   // ask user to use other key
4ba2a1 ¤   ¤   ¤   LoadString (g_hInst, IDS_FOUNDMATCHFORPHRASE, sz, sizeof(sz));
514d54 ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (key, sizeof(szName), szName, &size);
f86f1a ¤   ¤   ¤   wsprintf (sz2, sz, szName);
670893 ¤   ¤   ¤   LoadString (g_hInst, IDS_PGP, sz, sizeof(sz));
b8d414 ¤   ¤   ¤   if (MessageBox (hDlg, sz2, sz, MB_ICONQUESTION|MB_YESNO) == IDYES)·
94f776 ¤   ¤   ¤   {
129800 ¤   ¤   ¤   ¤   *(options->mPassphraseKeyPtr) = key;
86f6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
b0a3a6 ¤   ¤   ¤   }
b8222a ¤   ¤   ¤   return kPGPError_BadPassphrase;
9e0fe4 ¤   ¤   }
589371 ¤   }
71af5a
65b2d1 ¤   // phrase doesn't match any key
c04cb0 ¤   PGPsdkUIMessageBox (hDlg,
345187 ¤   ¤   IDS_PGPERROR,IDS_BADPASSREENTER,
94cee2 ¤   ¤   MB_OK|MB_ICONSTOP);
--bce7 000cb2fcf4640110018 Page 12 of PGPPassphraseDialog.cpp
e0af5a
200130 ¤   LoadString (g_hInst, IDS_WRONGPHRASE, sz, sizeof (sz));
68e27f ¤   SetDlgItemText (hDlg, IDC_PROMPTSTRING, sz);
7867c5 ¤
d56f19 ¤   return kPGPError_BadPassphrase;
64af5a
f5efe6 }
89af5a
4f3867 CommonPhraseMsgProc (
cac2d2 ¤   ¤   HWND¤   hwnd,·
c9eb77 ¤   ¤   UINT¤   uMsg,·
dd17d4 ¤   ¤   WPARAM¤ wParam,·
66c0b8 ¤   ¤   LPARAM¤ lParam)·
62bb36 {
3fabfa ····switch (uMsg)·
cec7a1 ¤   {
074033 ¤   ¤   case WM_CONTEXTMENU:
d75b34 ¤   ¤   {
77e3ff ¤   ¤   ¤   char szHelpFile[MAX_PATH+1];
bfaf5a
61e226 ¤   ¤   ¤   GetHelpDir(szHelpFile);
bcaf5a
cac9d1 ¤   ¤   ¤   WinHelp ((HWND) wParam, szHelpFile, HELP_CONTEXTMENU,·
6836d8 ¤   ¤   ¤   ¤   (DWORD) (LPVOID) aIds);·
5d32bd ¤   ¤   ¤   return TRUE;
5d0fe4 ¤   ¤   }
a7af5a
08af62 ¤   ¤   case WM_KEYUP:
5c5b34 ¤   ¤   {
02e311 ¤   ¤   ¤   SetCapsLockMessageState(GetParent(hwnd));
87cdcb ¤   ¤   ¤   break;
030fe4 ¤   ¤   }
11af5a
2368ff //¤ ¤   case WM_RBUTTONDOWN :
047d66 //¤ ¤   case WM_CONTEXTMENU :
cee447 ¤   ¤   case WM_LBUTTONDBLCLK :
8617a2 ¤   ¤   case WM_MOUSEMOVE :
571e08 ¤   ¤   case WM_COPY :
033654 ¤   ¤   case WM_CUT :
b8b372 ¤   ¤   case WM_PASTE :
03104b ¤   ¤   case WM_CLEAR :
6032bd ¤   ¤   ¤   return TRUE;
a2af5a
4bce0f ¤   ¤   case WM_LBUTTONDOWN :
d30a51 ¤   ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000) return TRUE;
2ecdcb ¤   ¤   ¤   break;
0caf5a
8dff3e ¤   ¤   case WM_PAINT :
cb5b34 ¤   ¤   {
8ed8d2 ¤   ¤   ¤   GPP *gpp;
b3af5a
6fceb8 ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (GetParent(hwnd), GWL_USERDATA);
98af5a
aad7d3 ¤   ¤   ¤   if (wParam)·
40f776 ¤   ¤   ¤   {
c0d07a ¤   ¤   ¤   ¤   SetBkColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
2fac8c ¤   ¤   ¤   ¤   if (gpp->bHideText)·
e2a956 ¤   ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
005109 ¤   ¤   ¤   ¤   else·
aea1ad ¤   ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOWTEXT));
fea3a6 ¤   ¤   ¤   }
b55d5e ¤   ¤   ¤   break;·
ce0fe4 ¤   ¤   }
95af5a
2397c8 ¤   ¤   case WM_KEYDOWN :
a7afb3 ¤   ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000)·
44f776 ¤   ¤   ¤   {
590ea9 ¤   ¤   ¤   ¤   switch (wParam)·
8872c3 ¤   ¤   ¤   ¤   {
0706a5 ¤   ¤   ¤   ¤   ¤   case VK_HOME :
333706 ¤   ¤   ¤   ¤   ¤   case VK_END :
cb53b1 ¤   ¤   ¤   ¤   ¤   case VK_UP :
--aa2d 0004139577240110018 Page 13 of PGPPassphraseDialog.cpp
d58fc2 ¤   ¤   ¤   ¤   ¤   case VK_DOWN :
b7d82b ¤   ¤   ¤   ¤   ¤   case VK_LEFT :
174503 ¤   ¤   ¤   ¤   ¤   case VK_RIGHT :
fd3a68 ¤   ¤   ¤   ¤   ¤   case VK_NEXT :
07cfc3 ¤   ¤   ¤   ¤   ¤   case VK_PRIOR :
e780de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
9a2613 ¤   ¤   ¤   ¤   }
d8a3a6 ¤   ¤   ¤   }
78cdcb ¤   ¤   ¤   break;
3caf5a
32b0ae ¤   ¤   case WM_SETFOCUS :
fcdb5e ¤   ¤   ¤   SendMessage (hwnd, EM_SETSEL, 0xFFFF, 0xFFFF);
eacdcb ¤   ¤   ¤   break;
069371 ¤   }
905da3 ····return FALSE;·
20a79b }·
acaf5a
4b0382 //¤ ______________________________________
f5465d //
6a8b3b // ·Passphrase edit box subclass procedure
bcaf5a
792bb2 LRESULT APIENTRY·
6a6bb4 PhraseSubclassProc (
c447b2 ¤   ¤   HWND¤   hWnd,·
77eb77 ¤   ¤   UINT¤   uMsg,·
0717d4 ¤   ¤   WPARAM¤ wParam,·
d9c0b8 ¤   ¤   LPARAM¤ lParam)·
63bb36 {
f84eee ¤   UINT¤   ¤   ¤   ¤   uQuality;
0a9aa5 ¤   CHAR *¤ ¤   ¤   ¤   szBuf;
5707ef ¤   LRESULT¤¤   ¤   ¤   lResult;
96a199 ¤   BOOL¤   ¤   ¤   ¤   OKactive;
95d037 ¤   GPP¤¤   ¤   ¤   ¤   ·*gpp;
c7af5a
adba64 ¤   gpp=(GPP *)GetWindowLong (GetParent(hWnd), GWL_USERDATA);
7daf5a
c81a3c ¤   if (CommonPhraseMsgProc (hWnd, uMsg, wParam, lParam)) return 0;
a4af5a
a6e234 ¤   switch (uMsg)·
d5c7a1 ¤   {
991d94 ¤   ¤   case WM_GETTEXT :
d75b34 ¤   ¤   {
e16996 ¤   ¤   ¤   if (!gpp->pszPassPhrase) return 0;
0508c9 ¤   ¤   ¤   lParam = (LPARAM)gpp->pszPassPhrase;
b8cdcb ¤   ¤   ¤   break;
eb0fe4 ¤   ¤   }
42af5a
d87dc8 ¤   ¤   case WM_CHAR :
175b34 ¤   ¤   {
709687 ¤   ¤   ¤   if (wParam == VK_TAB)·
acf776 ¤   ¤   ¤   {
d401b2 ¤   ¤   ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000)·
3655a2 ¤   ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd), IDC_HIDETYPING));
0a5109 ¤   ¤   ¤   ¤   else·
b66b1a ¤   ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd), gpp->iNextTabContro¶
3bc2c6 l));
42a3a6 ¤   ¤   ¤   }
256b93 ¤   ¤   ¤   else·
59f776 ¤   ¤   ¤   {
3816c2 ¤   ¤   ¤   ¤   OKactive=TRUE;
84af5a
eba4df ¤   ¤   ¤   ¤   lResult = CallWindowProc ((int (__stdcall *)(void))gpp->wpOrigP¶
0908ee hrase1Proc,·
550c31 ¤   ¤   ¤   ¤   ¤   hWnd, uMsg, wParam, lParam);·
ccaf5a
2ff9df ¤   ¤   ¤   ¤   // Get our passphrase in secure memory
31287f ¤   ¤   ¤   ¤   szBuf=(char *)secAlloc(gpp->context,1024);
26082f ¤   ¤   ¤   ¤   CallWindowProc ((int (__stdcall *)(void))gpp->wpOrigPhrase1Proc¶
427ea4 ,·
41ef07 ¤   ¤   ¤   ¤   ¤   hWnd, WM_GETTEXT, 1024, (LPARAM)szBuf);·
20af5a
41bd31 ¤   ¤   ¤   ¤   // Estimate its quality
--2e9b 0009163d6e440110018 Page 14 of PGPPassphraseDialog.cpp
827d57 ¤   ¤   ¤   ¤   uQuality=pgpEstimatePassphraseQuality(szBuf);
9438e5 /*
227046 ¤   ¤   ¤   ¤   // Check length for setting OK to TRUE
01fcdf ¤   ¤   ¤   ¤   if(options->mMinPassphraseLength!=0)
d072c3 ¤   ¤   ¤   ¤   {
7a723c ¤   ¤   ¤   ¤   ¤   if(strlen(szBuf)<options->mMinPassphraseLength)
844859 ¤   ¤   ¤   ¤   ¤   {
b99ae2 ¤   ¤   ¤   ¤   ¤   ¤   OKactive=FALSE;
821c89 ¤   ¤   ¤   ¤   ¤   }
c82613 ¤   ¤   ¤   ¤   }
767fe0 */
2735bf ¤   ¤   ¤   ¤   // Free the passphrase
a125d8 ¤   ¤   ¤   ¤   memset (szBuf, 0, sizeof(szBuf));
952858 ¤   ¤   ¤   ¤   secFree(szBuf);
84af5a
8d1b97 ¤   ¤   ¤   ¤   // Check Quality for setting OK to TRUE
dab480 ¤   ¤   ¤   ¤   if(gpp->options->mMinPassphraseQuality!=0)
8972c3 ¤   ¤   ¤   ¤   {
7eebf7 ¤   ¤   ¤   ¤   ¤   if(uQuality<gpp->options->mMinPassphraseQuality)
1b4859 ¤   ¤   ¤   ¤   ¤   {
9c9ae2 ¤   ¤   ¤   ¤   ¤   ¤   OKactive=FALSE;
2b1c89 ¤   ¤   ¤   ¤   ¤   }
e42613 ¤   ¤   ¤   ¤   }
b367c5 ¤
9a3ac3 ¤   ¤   ¤   ¤   if(gpp->hwndQuality)
1c72c3 ¤   ¤   ¤   ¤   {
bac144 ¤   ¤   ¤   ¤   ¤   // Set new quality
af7034 ¤   ¤   ¤   ¤   ¤   SendMessage (gpp->hwndQuality, PBM_SETPOS, uQuality, 0);
6f2613 ¤   ¤   ¤   ¤   }
74af5a
3eb1d8 ¤   ¤   ¤   ¤   // Enable/disable OK
ef4317 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (GetParent(hWnd), IDOK), OKactive);
044f7b ¤   ¤   ¤   ¤   return lResult;
8da3a6 ¤   ¤   ¤   }
77cdcb ¤   ¤   ¤   break;
870fe4 ¤   ¤   }
579371 ¤   }
812b5d ····return CallWindowProc ((int (__stdcall *)(void))gpp->wpOrigPhrase1Proc,·
744624 ¤   ¤   hWnd, uMsg, wParam, lParam);·
bba79b }·
06af5a
e40382 //¤ ______________________________________
64465d //
4f8b3b // ·Passphrase edit box subclass procedure
2eaf5a
052bb2 LRESULT APIENTRY·
2b3883 PhraseConfirmSubclassProc (
9247b2 ¤   ¤   HWND¤   hWnd,·
67eb77 ¤   ¤   UINT¤   uMsg,·
4917d4 ¤   ¤   WPARAM¤ wParam,·
a4c0b8 ¤   ¤   LPARAM¤ lParam)·
aebb36 {
0667fd ¤   GPP *gpp;
ebaf5a
74ba64 ¤   gpp=(GPP *)GetWindowLong (GetParent(hWnd), GWL_USERDATA);
e2af5a
bb1a3c ¤   if (CommonPhraseMsgProc (hWnd, uMsg, wParam, lParam)) return 0;
52af5a
d9e234 ¤   switch (uMsg)·
7cc7a1 ¤   {
881d94 ¤   ¤   case WM_GETTEXT :
efcd6d ¤   ¤   ¤   if (!gpp->pszPassPhraseConf) return 0;
767ea4 ¤   ¤   ¤   lParam = (LPARAM)gpp->pszPassPhraseConf;
9ccdcb ¤   ¤   ¤   break;
d6af5a
0d7dc8 ¤   ¤   case WM_CHAR :
f89687 ¤   ¤   ¤   if (wParam == VK_TAB)·
a7f776 ¤   ¤   ¤   {
ac01b2 ¤   ¤   ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000)·
a6bc70 ¤   ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd), IDC_PHRASE2));
ce9e90 ¤   ¤   ¤   ¤   else SetFocus (GetDlgItem (GetParent (hWnd), IDOK));
91a3a6 ¤   ¤   ¤   }
--87df 0009204ce6f40110018 Page 15 of PGPPassphraseDialog.cpp
7ecdcb ¤   ¤   ¤   break;
4b9371 ¤   }
d3af5a
1caeab ····return CallWindowProc((int (__stdcall *)(void))gpp->wpOrigPhrase2Proc,·
f14624 ¤   ¤   hWnd, uMsg, wParam, lParam);·
38a79b }·
e4af5a
fc9993 BOOL CALLBACK·
6094fb DoCommonCalls (
173a3a ¤   ¤   HWND¤   hDlg,·
55eb77 ¤   ¤   UINT¤   uMsg,·
ad0303 ¤   ¤   WPARAM¤ wParam,
07c0b8 ¤   ¤   LPARAM¤ lParam)·
58bb36 {
cc67fd ¤   GPP *gpp;
09af5a
2b7cd1 ¤   switch (uMsg)
d4c7a1 ¤   {
20df25 ¤   ¤   case WM_INITDIALOG:
795b34 ¤   ¤   {
f4c210 ¤   ¤   ¤   CPGPPassphraseDialogOptions *options;
4baf5a
b720eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
c8ac80 ¤   ¤   ¤   gpp=(GPP *)lParam;
ffaf5a
d9fa5d ¤   ¤   ¤   options = (CPGPPassphraseDialogOptions *)gpp->options;
69af5a
23ed5f ¤   ¤   ¤   if(options->mWindowTitle)
e09e8c ¤   ¤   ¤   ¤   SetWindowText(hDlg,options->mWindowTitle);
d6af5a
34c9f5 ¤   ¤   ¤   if(options->mPrompt)
d23527 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PROMPTSTRING, options->mPrompt);
deaf5a
168f07 ¤   ¤   ¤   gpp->bHideText = TRUE;
4f2ebd ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_HIDETYPING, BST_CHECKED);
38af5a
a27ed0 ¤   ¤   ¤   SetCapsLockMessageState(hDlg);
d4af5a
630472 ¤   ¤   ¤   SetForegroundWindow (hDlg);
f7af5a
c1dd31 ¤   ¤   ¤   // Force focus to passphrase box
cb7076 ¤   ¤   ¤   SetFocus(GetDlgItem(hDlg, IDC_PHRASE1));
d3cdcb ¤   ¤   ¤   break;
d40fe4 ¤   ¤   }
b3af5a
cdaf62 ¤   ¤   case WM_KEYUP:
415b34 ¤   ¤   {
b97ed0 ¤   ¤   ¤   SetCapsLockMessageState(hDlg);
26cdcb ¤   ¤   ¤   break;
8f0fe4 ¤   ¤   }
84af5a
3b0990 ¤   ¤   case WM_HELP:
cd5b34 ¤   ¤   {
77e3ff ¤   ¤   ¤   char szHelpFile[MAX_PATH+1];
22af5a
6ce226 ¤   ¤   ¤   GetHelpDir(szHelpFile);
04af5a
3c5542 ¤   ¤   ¤   WinHelp (((LPHELPINFO) lParam)->hItemHandle, szHelpFile,·
5eb16e ¤   ¤   ¤   ·HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
255d5e ¤   ¤   ¤   break;·
f70fe4 ¤   ¤   }
53af5a
094033 ¤   ¤   case WM_CONTEXTMENU:
4e5b34 ¤   ¤   {
1ce3ff ¤   ¤   ¤   char szHelpFile[MAX_PATH+1];
69af5a
9ee226 ¤   ¤   ¤   GetHelpDir(szHelpFile);
26af5a
2fc9d1 ¤   ¤   ¤   WinHelp ((HWND) wParam, szHelpFile, HELP_CONTEXTMENU,·
b636d8 ¤   ¤   ¤   ¤   (DWORD) (LPVOID) aIds);·
bd5d5e ¤   ¤   ¤   break;·
920fe4 ¤   ¤   }
--8bdf 0006697b81c40110018 Page 16 of PGPPassphraseDialog.cpp
e0af5a
84d725 ¤   ¤   case WM_QUIT:
682c97 ¤   ¤   case WM_CLOSE:
266eda ¤   ¤   case WM_DESTROY:·
ea5b34 ¤   ¤   {
5d733e ¤   ¤   ¤   HWND hwndPhrase1,hwndPhrase2;
5daf5a
bbc07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
46af5a
050cd7 ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
9aaf5a
ce2aa4 ¤   ¤   ¤   hwndPhrase1=GetDlgItem(hDlg, IDC_PHRASE1);
33cfcc ¤   ¤   ¤   hwndPhrase2=GetDlgItem(hDlg, IDC_PHRASE2);
97af5a
bc3dce ¤   ¤   ¤   if(hwndPhrase1)
80f776 ¤   ¤   ¤   {
9fe94e ¤   ¤   ¤   ¤   SetWindowLong (hwndPhrase1,
900f0e ¤   ¤   ¤   ¤   ¤   ···GWL_WNDPROC,·
864ded ¤   ¤   ¤   ¤   ¤   ···(LONG)gpp->wpOrigPhrase1Proc);
b4a3a6 ¤   ¤   ¤   }
50af5a
18d2aa ¤   ¤   ¤   if(hwndPhrase2)
c2f776 ¤   ¤   ¤   {
20ab12 ¤   ¤   ¤   ¤   SetWindowLong (hwndPhrase2,·
9f0f0e ¤   ¤   ¤   ¤   ¤   ···GWL_WNDPROC,·
94c73d ¤   ¤   ¤   ¤   ¤   ···(LONG)gpp->wpOrigPhrase2Proc);
83a3a6 ¤   ¤   ¤   }
a1af5a
71e1e4 ¤   ¤   ¤   EndDialog(hDlg,kPGPError_UserAbort);
d7cdcb ¤   ¤   ¤   break;
f40fe4 ¤   ¤   }
8eaf5a
861ca3 ¤   ¤   case WM_CTLCOLOREDIT:
495b34 ¤   ¤   {
5b733e ¤   ¤   ¤   HWND hwndPhrase1,hwndPhrase2;
2caf5a
23c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
f7af5a
ad2aa4 ¤   ¤   ¤   hwndPhrase1=GetDlgItem(hDlg, IDC_PHRASE1);
98cfcc ¤   ¤   ¤   hwndPhrase2=GetDlgItem(hDlg, IDC_PHRASE2);
ffaf5a
444f51 ¤   ¤   ¤   if(lParam==0)
e9f622 ¤   ¤   ¤   ¤   break;
ddaf5a
db39cd ¤   ¤   ¤   if (((HWND)lParam == hwndPhrase1) ||
6b58ae ¤   ¤   ¤   ¤   ((HWND)lParam == hwndPhrase2))·
dcf776 ¤   ¤   ¤   {
05d07a ¤   ¤   ¤   ¤   SetBkColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
6aac8c ¤   ¤   ¤   ¤   if (gpp->bHideText)·
05a956 ¤   ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
aa5109 ¤   ¤   ¤   ¤   else·
44761e ¤   ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam,·
7f78cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··GetSysColor (COLOR_WINDOWTEXT));
002308 ¤   ¤   ¤   ¤   return (BOOL)CreateSolidBrush (GetSysColor (COLOR_WINDOW));
a9a3a6 ¤   ¤   ¤   }
a6cdcb ¤   ¤   ¤   break;
c20fe4 ¤   ¤   }
ffaf5a
cd8e1e ¤   ¤   case WM_COMMAND:
0d5b34 ¤   ¤   {
9bc07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
61af5a
4b256f ¤   ¤   ¤   switch(LOWORD (wParam))·
d6f776 ¤   ¤   ¤   {
248722 ¤   ¤   ¤   ¤   case IDCANCEL:
3e14a6 ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_UserAbort);
4914c3 ¤   ¤   ¤   ¤   ¤   break;
8caf5a
d452b0 ¤   ¤   ¤   ¤   case IDC_HIDETYPING :
3c72c3 ¤   ¤   ¤   ¤   {
e705c5 ¤   ¤   ¤   ¤   ¤   HWND hwndPhrase1,hwndPhrase2;
6667c5 ¤
--fa9c 0000292f09640110018 Page 17 of PGPPassphraseDialog.cpp
1f2d7d ¤   ¤   ¤   ¤   ¤   hwndPhrase1=GetDlgItem(hDlg, IDC_PHRASE1);
3cc815 ¤   ¤   ¤   ¤   ¤   hwndPhrase2=GetDlgItem(hDlg, IDC_PHRASE2);
5baf5a
19e22e ¤   ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_HIDETYPING)
487d6e ¤   ¤   ¤   ¤   ¤   ¤   ¤   == BST_CHECKED)·
045120 ¤   ¤   ¤   ¤   ¤   ¤   gpp->bHideText = TRUE;
2796bc ¤   ¤   ¤   ¤   ¤   else·
8e1010 ¤   ¤   ¤   ¤   ¤   ¤   gpp->bHideText = FALSE;
f7af5a
366865 ¤   ¤   ¤   ¤   ¤   if(hwndPhrase1!=NULL)
048255 ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (hwndPhrase1, NULL, TRUE);
70af5a
0fbe62 ¤   ¤   ¤   ¤   ¤   if(hwndPhrase2!=NULL)
bf1874 ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (hwndPhrase2, NULL, TRUE);
6014c3 ¤   ¤   ¤   ¤   ¤   break;
422613 ¤   ¤   ¤   ¤   }
06a3a6 ¤   ¤   ¤   }
2fe2a7 ¤   ¤   ¤   break;¤
a40fe4 ¤   ¤   }
0a9371 ¤   }
94af5a
8ba230 ¤   return FALSE;
09efe6 }
f4af5a
df3580 void DisplayOptions(HWND hDlg,PGPOptionListRef options,int y)
47bb36 {
b8b4bb ¤   if(options==NULL)
8ac7a1 ¤   {
179371 ¤   }
7c0e24 ¤   else
2cc7a1 ¤   {
b3ee4b ¤   ¤   RECT rc;
bf06c0 ¤   ¤   HWND hwndOptions;
bfaf5a
ed714e ¤   ¤   GetWindowRect(hDlg,&rc);
13af5a
f24985 ¤   ¤   SetWindowPos (hDlg,·
212624 ¤   ¤   ¤   NULL, 0, 0,
906eb6 ¤   ¤   ¤   rc.right-rc.left,rc.bottom-rc.top+45,
d1e6cc ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);
4baf5a
5a0dbe ¤   ¤   hwndOptions=NULL;
0eaf5a
c80a79 ¤   ¤   MoveOptionsControl(hDlg,&hwndOptions,
e8914c ¤   ¤   ¤   options,
af8320 ¤   ¤   ¤   10,y,
223e13 ¤   ¤   ¤   200,71);
e29371 ¤   }
d5efe6 }
e7af5a
8e04c9 // ****************************************************************************
8c04c9 // ****************************************************************************
6caf5a
024a83 //¤ ________________________
27465d //
ac2d24 // ·Dialog Message procedure
7baf5a
3c9993 BOOL CALLBACK·
712679 pgpPassphraseDlgProc (
703a3a ¤   ¤   HWND¤   hDlg,·
06eb77 ¤   ¤   UINT¤   uMsg,·
8a0303 ¤   ¤   WPARAM¤ wParam,
c8c0b8 ¤   ¤   LPARAM¤ lParam)·
07bb36 {
80b4eb ¤   CPGPPassphraseDialogOptions *options;
c9584a ¤   GPP¤¤   ¤   ¤   *gpp;
5adfcd ¤   INT¤¤   ¤   ¤   i;
cc3d73 ¤   BOOL¤   ¤   ¤   Common;
4eaf5a
666122 ¤   Common=DoCommonCalls (hDlg,uMsg,wParam,lParam);·
c1af5a
026222 ¤   if(Common)
--9f2f 000cef876f240110018 Page 18 of PGPPassphraseDialog.cpp
44a5aa ¤   ¤   return Common;
17af5a
e3e234 ¤   switch (uMsg)·
c7c7a1 ¤   {
b1df25 ¤   ¤   case WM_INITDIALOG:
485b34 ¤   ¤   {
79c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
f98927 ¤   ¤   ¤   options = (CPGPPassphraseDialogOptions *)
2a95be ¤   ¤   ¤   ¤   gpp->options;
8c67c5 ¤
cb101b ¤   ¤   ¤   gpp->iNextTabControl = IDOK;
efaf5a
5be2df ¤   ¤   ¤   gpp->wpOrigPhrase1Proc = (WNDPROC) SetWindowLong (
19ee4c ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_PHRASE1),·
8cceaf ¤   ¤   ¤   ¤   GWL_WNDPROC,·
efa40b ¤   ¤   ¤   ¤   (LONG) PhraseSubclassProc);·
17af5a
8f52f6 ¤   ¤   ¤   DisplayOptions(hDlg,options->mDialogOptions,107);
5c5f1f ¤   ¤   ¤   return FALSE;
750fe4 ¤   ¤   }
fcaf5a
fe8e1e ¤   ¤   case WM_COMMAND:
d75b34 ¤   ¤   {
47c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
a38927 ¤   ¤   ¤   options = (CPGPPassphraseDialogOptions *)
0095be ¤   ¤   ¤   ¤   gpp->options;
7f67c5 ¤
3f256f ¤   ¤   ¤   switch(LOWORD (wParam))·
8cf776 ¤   ¤   ¤   {
1acae3 ¤   ¤   ¤   ¤   case IDOK:·
3d72c3 ¤   ¤   ¤   ¤   {
81b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
36af5a
367bd9 ¤   ¤   ¤   ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PHRASE1,·
bc2591 ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) +1;
c2af5a
24f7e4 ¤   ¤   ¤   ¤   ¤   gpp->szDummy = (char *)secAlloc (gpp->context, i);
a1af5a
f7a3fb ¤   ¤   ¤   ¤   ¤   if(gpp->szDummy)
bd4859 ¤   ¤   ¤   ¤   ¤   {
d9601d ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhrase = (char *)secAlloc (gpp->context, i);
4eaf5a
6a0394 ¤   ¤   ¤   ¤   ¤   ¤   if (gpp->pszPassPhrase)·
558fec ¤   ¤   ¤   ¤   ¤   ¤   {
46296b ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PHRASE1, gpp->szDummy, i);
c9af5a
e7e123 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(PassphraseLengthAndQualityOK(hDlg,options,gpp->p¶
1dcc36 szPassPhrase))
ab06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
bdd05b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
b0e8b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
b4cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
405268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
cb6deb ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Passphrase quality not enough
6c5f0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
60c622 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
0d8c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
8adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
3e1c89 ¤   ¤   ¤   ¤   ¤   }
f894aa ¤   ¤   ¤   ¤   ¤   ¤
031ba0 ¤   ¤   ¤   ¤   ¤   // Couldn't allocate passphrases
7b9ce1 ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
c9b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
f72042 ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_OutOfMemory);
f114c3 ¤   ¤   ¤   ¤   ¤   break;
f42613 ¤   ¤   ¤   ¤   }
d2a3a6 ¤   ¤   ¤   }
2ecdcb ¤   ¤   ¤   break;
5a0fe4 ¤   ¤   }
c29371 ¤   }
9ba230 ¤   return FALSE;
ceefe6 }
--5e4c 00053b6aa5340110018 Page 19 of PGPPassphraseDialog.cpp
e0af5a
96c94f // Just a simple decryption
f7c744 ¤   PGPError
835f65 pgpPassphraseDialogPlatform(
a5284d ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   context,
67497f ¤   CPGPPassphraseDialogOptions ¤   *options)
9fbb36 {
285a9a ¤   if (options->mTextUI) {
dc8a6f ¤   ¤   return pgpPassphraseCL(context, options);
7df037 ¤   } else {
443ada ¤   ¤   PGPError err;
d9d0a3 ¤   ¤   GPP¤gpp;
5bd7af ¤   ¤   memset(&gpp,0x00,sizeof(GPP));
555ba6 ¤   ¤   gpp.context=context;
f4528b ¤   ¤   gpp.options=options;
571b52 ¤   ¤
3f4bba ¤   ¤   InitRandomKeyHook(&hhookKeyboard, &hhookMouse);
073b79 ¤   ¤   InstallSecurityHooks();
e41b52 ¤   ¤
052aa5 ¤   ¤   err = DialogBoxParam (g_hInst,·
94fc04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··MAKEINTRESOURCE (IDD_PASSPHRASE),·
519efe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··options->mHwndParent,
d206a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··(DLGPROC)pgpPassphraseDlgProc, (LPARAM)&gpp);
7b1b52 ¤   ¤
10eada ¤   ¤   *(options->mPassphrasePtr)=gpp.pszPassPhrase;
eb1b52 ¤   ¤
69dfab ¤   ¤   UninstallSecurityHooks();
9c5c15 ¤   ¤   UninitRandomKeyHook(hhookKeyboard, hhookMouse);
931b52 ¤   ¤
d18676 ¤   ¤   return(err);
409371 ¤   }
0defe6 }
a2af5a
be4a83 //¤ ________________________
47465d //
4b2d24 // ·Dialog Message procedure
b4af5a
bf3287 static PGPBoolean Working=FALSE;
c8af5a
0a9993 BOOL CALLBACK·
8a3c2f pgpDecryptionPassphraseDlgProc (
e33a3a ¤   ¤   HWND¤   hDlg,·
72eb77 ¤   ¤   UINT¤   uMsg,·
960303 ¤   ¤   WPARAM¤ wParam,
6cc0b8 ¤   ¤   LPARAM¤ lParam)·
f1bb36 {
ceceb8 ¤   CPGPDecryptionPassphraseDialogOptions *options;
dc584a ¤   GPP¤¤   ¤   ¤   *gpp;
f2dfcd ¤   INT¤¤   ¤   ¤   i;
490f68 ¤   DWORD¤  ¤   ¤   Common;
b9af5a
2f6122 ¤   Common=DoCommonCalls (hDlg,uMsg,wParam,lParam);·
32af5a
676222 ¤   if(Common)
87a5aa ¤   ¤   return Common;
49af5a
2be234 ¤   switch (uMsg)·
b5c7a1 ¤   {
cbdf25 ¤   ¤   case WM_INITDIALOG:
155b34 ¤   ¤   {
3ec07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
e83f90 ¤   ¤   ¤   options = (CPGPDecryptionPassphraseDialogOptions *)
3395be ¤   ¤   ¤   ¤   gpp->options;
c7af5a
fb101b ¤   ¤   ¤   gpp->iNextTabControl = IDOK;
56af5a
1e88d6 ¤   ¤   ¤   InitEncryptedToKeyListBox (hDlg, options);
80af5a
45e2df ¤   ¤   ¤   gpp->wpOrigPhrase1Proc = (WNDPROC) SetWindowLong (
ebee4c ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_PHRASE1),·
15ceaf ¤   ¤   ¤   ¤   GWL_WNDPROC,·
53a40b ¤   ¤   ¤   ¤   (LONG) PhraseSubclassProc);·
--6cc3 000e2279b7e40110018 Page 20 of PGPPassphraseDialog.cpp
e0af5a
df09aa ¤   ¤   ¤   DisplayOptions(hDlg,options->mDialogOptions,200);
cfaf5a
295f1f ¤   ¤   ¤   return FALSE;
040fe4 ¤   ¤   }
b1af5a
39af5a
478e1e ¤   ¤   case WM_COMMAND:
c75b34 ¤   ¤   {
11c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
e63f90 ¤   ¤   ¤   options = (CPGPDecryptionPassphraseDialogOptions *)
aa95be ¤   ¤   ¤   ¤   gpp->options;
b5af5a
8e256f ¤   ¤   ¤   switch(LOWORD (wParam))·
abf776 ¤   ¤   ¤   {
36af5a
149085 ¤   ¤   ¤   ¤   case IDC_KEYLISTBOX:
3872c3 ¤   ¤   ¤   ¤   {
4c9aba ¤   ¤   ¤   ¤   ¤   if(HIWORD(wParam)==LBN_DBLCLK)
eb4859 ¤   ¤   ¤   ¤   ¤   {
8ca7be ¤   ¤   ¤   ¤   ¤   ¤   if(!Working)
3d8fec ¤   ¤   ¤   ¤   ¤   ¤   {
5f9a23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   Working=TRUE;
21af5a
ead369 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(IsntNull(options->mMissingKeyIDList))
7606b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
ec339a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPError¤   err;
471e5a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean¤ haveNewKeys;
d0af5a
aa382c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   err=options->SearchForMissingKeys( hDlg, &haveN¶
8ff589 ewKeys );
d4af5a
706118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPsdkUIErrorBox (hDlg,err);
2bda4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
34b4f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( haveNewKeys )
f731b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
b32cf3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   InitEncryptedToKeyListBox (hDlg, options);
486560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
715268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
4dae30 ¤   ¤   ¤   ¤   ¤
bc2240 ¤   ¤   ¤   ¤   ¤   ¤   ¤   Working=FALSE;
9edb3c ¤   ¤   ¤   ¤   ¤   ¤   }
1c1c89 ¤   ¤   ¤   ¤   ¤   }
e314c3 ¤   ¤   ¤   ¤   ¤   break;
6f2613 ¤   ¤   ¤   ¤   }
d3af5a
c6cae3 ¤   ¤   ¤   ¤   case IDOK:·
b772c3 ¤   ¤   ¤   ¤   {
92b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
a4af5a
c67bd9 ¤   ¤   ¤   ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PHRASE1,·
342591 ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) +1;
5caf5a
65f7e4 ¤   ¤   ¤   ¤   ¤   gpp->szDummy = (char *)secAlloc (gpp->context, i);
43af5a
2ca3fb ¤   ¤   ¤   ¤   ¤   if(gpp->szDummy)
f74859 ¤   ¤   ¤   ¤   ¤   {
78601d ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhrase = (char *)secAlloc (gpp->context, i);
5daf5a
400394 ¤   ¤   ¤   ¤   ¤   ¤   if (gpp->pszPassPhrase)·
488fec ¤   ¤   ¤   ¤   ¤   ¤   {
92db58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CHAR sz[256];
d5af5a
23296b ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PHRASE1, gpp->szDummy, i);
4faf5a
dfe123 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(PassphraseLengthAndQualityOK(hDlg,options,gpp->p¶
74cc36 szPassPhrase))
9106b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
1f9866 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!options->mFindMatchingKey)
fb31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
4d1447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
e2fb3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
--ce03 000d5c1db8540110018 Page 21 of PGPPassphraseDialog.cpp
dbc32b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
bc6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
1daf5a
5bed95 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *(options->mPassphraseKeyPtr)=
a12094 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetKeyForPassphrase(options->mKeySet,
a5f455 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhrase,FALSE);
c667c5 ¤
f60caf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (*(options->mPassphraseKeyPtr)!=NULL)
6131b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
8d1447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
f6fb3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
a7c32b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
4b6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
09f9b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
7731b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
113bbf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPsdkUIMessageBox (hDlg, IDS_PGPERROR,·
19ef93 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_BADDECRYPTPHRASE, MB_OK|MB_ICONEXCL¶
bb39e6 AMATION);
be0365 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_WRONGDECRYPTPHRASE¶
137ea4 ,·
d11dd8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz, sizeof (sz));
4460f2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PROMPTSTRING, sz);
af6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
6f5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
4ef0f5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Bad passphrase/quality
205f0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
5ec622 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
c38c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
04db3c ¤   ¤   ¤   ¤   ¤   ¤   }
791c89 ¤   ¤   ¤   ¤   ¤   }
681ba0 ¤   ¤   ¤   ¤   ¤   // Couldn't allocate passphrases
cf9ce1 ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
33b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
552042 ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_OutOfMemory);
1e14c3 ¤   ¤   ¤   ¤   ¤   break;
952613 ¤   ¤   ¤   ¤   }
c5a3a6 ¤   ¤   ¤   }
a1cdcb ¤   ¤   ¤   break;
200fe4 ¤   ¤   }
319371 ¤   }
80a230 ¤   return FALSE;
8fefe6 }
79af5a
2f0918 // Show the recipients
29c744 ¤   PGPError
6fff16 pgpDecryptionPassphraseDialogPlatform(
608d3c ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   ¤   ¤   context,
0921a4 ¤   CPGPDecryptionPassphraseDialogOptions¤  *options)
52bb36 {
ae0040 ¤   PGPError err;
7e6532 ¤   GPP¤gpp;
ffaf5a
ff965c ¤   memset(&gpp,0x00,sizeof(GPP));
ba6ffb ¤   gpp.context=context;
8966d6 ¤   gpp.options=options;
02af5a
881e16 ¤   InitRandomKeyHook(&hhookKeyboard, &hhookMouse);
959627 ¤   InstallSecurityHooks();
0daf5a
9eeff0 ¤   err = DialogBoxParam (g_hInst,·
801860 ¤   ¤   MAKEINTRESOURCE (IDD_PASSPHRASEDECRYPTKEYS),·
363e26 ¤   ¤   options->mHwndParent,
80c6d1 ¤   ¤   (DLGPROC)pgpDecryptionPassphraseDlgProc, (LPARAM)&gpp);
15af5a
7744db ¤   *(options->mPassphrasePtr)=gpp.pszPassPhrase;
ddaf5a
89e8a3 ¤   UninstallSecurityHooks();
2509b9 ¤   UninitRandomKeyHook(hhookKeyboard, hhookMouse);
b1af5a
f6c7fd ¤   return(err);
a1efe6 }
d5af5a
--b354 00064ed076b40110018 Page 22 of PGPPassphraseDialog.cpp
e0af5a
faf528 //¤ _________________________________________________________
af465d //
b26ba3 // ·Dialog Message procedure - get passphrase and signing key
8daf5a
029993 BOOL CALLBACK·
a75ead pgpSigningPassphraseDlgProc (
c93a3a ¤   ¤   HWND¤   hDlg,·
4deb77 ¤   ¤   UINT¤   uMsg,·
870303 ¤   ¤   WPARAM¤ wParam,
81c0b8 ¤   ¤   LPARAM¤ lParam)·
e1bb36 {
3ca8e6 ¤   CPGPSigningPassphraseDialogOptions *options;
03584a ¤   GPP¤¤   ¤   ¤   *gpp;
05dfcd ¤   INT¤¤   ¤   ¤   i;
280f68 ¤   DWORD¤  ¤   ¤   Common;
31af5a
db6122 ¤   Common=DoCommonCalls (hDlg,uMsg,wParam,lParam);·
67af5a
356222 ¤   if(Common)
35a5aa ¤   ¤   return Common;
98af5a
7fe234 ¤   switch (uMsg)·
41c7a1 ¤   {
ccdf25 ¤   ¤   case WM_INITDIALOG:
ed5b34 ¤   ¤   {
e7c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
23b1bc ¤   ¤   ¤   options = (CPGPSigningPassphraseDialogOptions *)
0c95be ¤   ¤   ¤   ¤   gpp->options;
6baf5a
f5101b ¤   ¤   ¤   gpp->iNextTabControl = IDOK;
96af5a
9f356f ¤   ¤   ¤   gpp->wpOrigPhrase1Proc = (WNDPROC) SetWindowLong(
00be5a ¤   ¤   ¤   ¤   GetDlgItem(hDlg, IDC_PHRASE1),·
74ceaf ¤   ¤   ¤   ¤   GWL_WNDPROC,·
5ea40b ¤   ¤   ¤   ¤   (LONG) PhraseSubclassProc);·
1baf5a
9312cd ¤   ¤   ¤   if (InitSigningKeyComboBox (hDlg, options))·
65f776 ¤   ¤   ¤   {
fd32c5 ¤   ¤   ¤   ¤   EnablePassPhraseControl (hDlg);
22a3a6 ¤   ¤   ¤   }
a46b93 ¤   ¤   ¤   else·
8ef776 ¤   ¤   ¤   {
179780 ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_UserAbort);//kPGPError_Win32_NoSecre¶
65e57f tKeys);
66a3a6 ¤   ¤   ¤   }
19af5a
5b181b ¤   ¤   ¤   DisplayOptions(hDlg,options->mDialogOptions,130);
9baf5a
855f1f ¤   ¤   ¤   return FALSE;
d50fe4 ¤   ¤   }
7eaf5a
ed8e1e ¤   ¤   case WM_COMMAND:
795b34 ¤   ¤   {
98c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
22b1bc ¤   ¤   ¤   options = (CPGPSigningPassphraseDialogOptions *)
6695be ¤   ¤   ¤   ¤   gpp->options;
cfaf5a
83d523 ¤   ¤   ¤   switch (LOWORD (wParam))·
72f776 ¤   ¤   ¤   {
d7e168 ¤   ¤   ¤   ¤   case IDOK:
1372c3 ¤   ¤   ¤   ¤   {
1dd71c ¤   ¤   ¤   ¤   ¤   int ComboSelection;
bbaf5a
f5b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
34af5a
40d0aa ¤   ¤   ¤   ¤   ¤   ComboSelection = SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO¶
197ea4 ,·
dd7f55 ¤   ¤   ¤   ¤   ¤   ¤   CB_GETCURSEL, 0, 0);
6baf5a
d93fb7 ¤   ¤   ¤   ¤   ¤   if (ComboSelection == CB_ERR)·
644859 ¤   ¤   ¤   ¤   ¤   {
--62e0 000bac6e4e940110018 Page 23 of PGPPassphraseDialog.cpp
fc1a61 ¤   ¤   ¤   ¤   ¤   ¤   PGPsdkUIMessageBox (hDlg,·
1801cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_PGPERROR, IDS_NOSIGNKEY,·
5f33bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK | MB_ICONEXCLAMATION);
e400eb ¤   ¤   ¤   ¤   ¤   ¤   break;
d01c89 ¤   ¤   ¤   ¤   ¤   }
6baf5a
3c7bd9 ¤   ¤   ¤   ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PHRASE1,·
7a2591 ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) +1;
f2af5a
60f7e4 ¤   ¤   ¤   ¤   ¤   gpp->szDummy = (char *)secAlloc (gpp->context, i);
a3af5a
94a3fb ¤   ¤   ¤   ¤   ¤   if(gpp->szDummy)
054859 ¤   ¤   ¤   ¤   ¤   {
84601d ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhrase = (char *)secAlloc (gpp->context, i);
91af5a
520394 ¤   ¤   ¤   ¤   ¤   ¤   if (gpp->pszPassPhrase)·
298fec ¤   ¤   ¤   ¤   ¤   ¤   {
6bc572 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyRef¤  key;
d66107 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPError¤   err;
f3eb38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean¤ bShared;
38af5a
15296b ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PHRASE1, gpp->szDummy, i);
8eaf5a
bbe407 ¤   ¤   ¤   ¤   ¤   ¤   ¤   key = (PGPKeyRef)SendDlgItemMessage (hDlg,·
5e8cd6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_SIGNKEYCOMBO, CB_GETITEMDATA, ComboSelectio¶
9fd826 n, 0);
f0af5a
d40db2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   err=PGPGetKeyBoolean( key, kPGPKeyPropIsSecretShare¶
b0cb08 d, &bShared);
0867c5 ¤
354692 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(err) && bShared)
4f06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
a447ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // So, they want to do a shared key....
f2d05b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
b16823 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
4681ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *(options->mPassphraseKeyPtr) = key;
3e2a77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_KeyUnusableForSignat¶
ea473b ure);
f1cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
c75268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
30af5a
4ee123 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(PassphraseLengthAndQualityOK(hDlg,options,gpp->p¶
f5cc36 szPassPhrase))
5306b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
e453ec ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!options->mVerifyPassphrase)
d131b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
f81447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
6bfb3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
66c32b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
296560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
bbaf5a
b99728 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   err=ValidateSigningPhrase(hDlg,gpp,gpp->pszPass¶
be292c Phrase,key);
0baf5a
3f7deb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(err))
d431b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
791447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
11fb3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
5bc32b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
a16560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
bc5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
b5af5a
70f0f5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Bad passphrase/quality
8c5f0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
08c622 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
d88c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
20db3c ¤   ¤   ¤   ¤   ¤   ¤   }
491c89 ¤   ¤   ¤   ¤   ¤   }
c4af5a
441ba0 ¤   ¤   ¤   ¤   ¤   // Couldn't allocate passphrases
629ce1 ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
bab0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
--8dea 0007e128da240110018 Page 24 of PGPPassphraseDialog.cpp
9e2042 ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_OutOfMemory);
c514c3 ¤   ¤   ¤   ¤   ¤   break;
972613 ¤   ¤   ¤   ¤   }
8caf5a
6230d5 ¤   ¤   ¤   ¤   case IDC_SIGNKEYCOMBO :
7b72c3 ¤   ¤   ¤   ¤   {
e68763 ¤   ¤   ¤   ¤   ¤   if(HIWORD(wParam)==CBN_SELCHANGE)
eff128 ¤   ¤   ¤   ¤   ¤   ¤   EnablePassPhraseControl (hDlg);
5814c3 ¤   ¤   ¤   ¤   ¤   break;
d62613 ¤   ¤   ¤   ¤   }
dfa3a6 ¤   ¤   ¤   }
d40fe4 ¤   ¤   }
272f68 ¤   ¤   break;
359371 ¤   }
1ea230 ¤   return FALSE;
71efe6 }
42af5a
f59738 // Signer combo box
f0c744 ¤   PGPError
e045d9 pgpSigningPassphraseDialogPlatform(
776164 ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   ¤   context,
c64d57 ¤   CPGPSigningPassphraseDialogOptions ¤*options)
4fbb36 {
5f9358 ¤   // check for UI option if not set the assume Graphical
f3b9bb ¤   // else use command line UI
b35a9a ¤   if (options->mTextUI) {
07630b ¤   ¤   return pgpSigningPassphraseCL(context, options);
b2f037 ¤   } else {
b83ada ¤   ¤   PGPError err;
d9d0a3 ¤   ¤   GPP¤gpp;
d11b52 ¤   ¤
21d7af ¤   ¤   memset(&gpp,0x00,sizeof(GPP));
4f5ba6 ¤   ¤   gpp.context=context;
78528b ¤   ¤   gpp.options=options;
beaf5a
124bba ¤   ¤   InitRandomKeyHook(&hhookKeyboard, &hhookMouse);
dc3b79 ¤   ¤   InstallSecurityHooks();
011b52 ¤   ¤
5e9535 ¤   ¤   err = DialogBoxParam(g_hInst,·
b49aa7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·MAKEINTRESOURCE (IDD_PASSPHRASEOPTIONS),·
ab1537 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·options->mHwndParent,
55d275 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(DLGPROC)pgpSigningPassphraseDlgProc,
8db297 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&gpp);
8d1b52 ¤   ¤
61eada ¤   ¤   *(options->mPassphrasePtr)=gpp.pszPassPhrase;
d71b52 ¤   ¤
a4dfab ¤   ¤   UninstallSecurityHooks();
2d5c15 ¤   ¤   UninitRandomKeyHook(hhookKeyboard, hhookMouse);
3a8676 ¤   ¤   return(err);
3f9371 ¤   }
68efe6 }
f3af5a
b54a83 //¤ ________________________
74465d //
892d24 // ·Dialog Message procedure
7daf5a
9e9993 BOOL CALLBACK·
46ccff pgpConfirmationDlgProc (
4c3a3a ¤   ¤   HWND¤   hDlg,·
9feb77 ¤   ¤   UINT¤   uMsg,·
dd0303 ¤   ¤   WPARAM¤ wParam,
54c0b8 ¤   ¤   LPARAM¤ lParam)·
59bb36 {
899836 ¤   CPGPConfirmationPassphraseDialogOptions *options;
ff584a ¤   GPP¤¤   ¤   ¤   *gpp;
7edfcd ¤   INT¤¤   ¤   ¤   i;
a00f68 ¤   DWORD¤  ¤   ¤   Common;
d1af5a
0b6122 ¤   Common=DoCommonCalls (hDlg,uMsg,wParam,lParam);·
36af5a
f96222 ¤   if(Common)
7ea5aa ¤   ¤   return Common;
--6ffc 00067b472d740110018 Page 25 of PGPPassphraseDialog.cpp
e0af5a
9ae234 ¤   switch (uMsg)·
38c7a1 ¤   {
53df25 ¤   ¤   case WM_INITDIALOG:
e35b34 ¤   ¤   {
09c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
ce41c9 ¤   ¤   ¤   options = (CPGPConfirmationPassphraseDialogOptions *)
bf95be ¤   ¤   ¤   ¤   gpp->options;
85af5a
704a45 ¤   ¤   ¤   gpp->iNextTabControl = IDC_PHRASE2;
609628 ¤   ¤   ¤   gpp->hwndQuality = GetDlgItem (hDlg, IDC_PHRASEQUALITY);
af1d66 ¤   ¤   ¤   gpp->hwndMinQuality = GetDlgItem (hDlg, IDC_MINQUALITY);
7daf5a
9ee2df ¤   ¤   ¤   gpp->wpOrigPhrase1Proc = (WNDPROC) SetWindowLong (
7eee4c ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_PHRASE1),·
52ceaf ¤   ¤   ¤   ¤   GWL_WNDPROC,·
69a40b ¤   ¤   ¤   ¤   (LONG) PhraseSubclassProc);·
0910b8 ¤   ¤   ¤   gpp->wpOrigPhrase2Proc = (WNDPROC) SetWindowLong (
17f380 ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_PHRASE2),·
14ceaf ¤   ¤   ¤   ¤   GWL_WNDPROC,·
c4ac51 ¤   ¤   ¤   ¤   (LONG) PhraseConfirmSubclassProc);·
a0af5a
166cb9 ¤   ¤   ¤   DisplayOptions(hDlg,options->mDialogOptions,215);
4baf5a
876623 ¤   ¤   ¤   // If we aren't showing quality, don't show either bar
f7dc20 ¤   ¤   ¤   if(!options->mShowPassphraseQuality)
21f776 ¤   ¤   ¤   {
45ec80 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_STATICPASSQUAL), FALSE);
a9404d ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATICPASSQUAL), SW_HIDE);
721a33 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_STATICMINQUAL), FALSE);
8e3ac3 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATICMINQUAL), SW_HIDE);
5aaf5a
3f5951 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_MINQUALITY), FALSE);
760145 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_MINQUALITY), SW_HIDE);
cc0f6a ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_PHRASEQUALITY), FALSE);
9b7900 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHRASEQUALITY), SW_HIDE);
2ea3a6 ¤   ¤   ¤   }
d7af5a
200500 ¤   ¤   ¤   // If we don't give a min quality, don't show bar
d4da0e ¤   ¤   ¤   if(options->mMinPassphraseQuality==0)
9ff776 ¤   ¤   ¤   {
991a33 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_STATICMINQUAL), FALSE);
ac3ac3 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATICMINQUAL), SW_HIDE);
0baf5a
235951 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_MINQUALITY), FALSE);
c10145 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_MINQUALITY), SW_HIDE);
eea3a6 ¤   ¤   ¤   }
a7af5a
52cd00 ¤   ¤   ¤   // Set our min quality benchmark
33a2d4 ¤   ¤   ¤   SendMessage (gpp->hwndMinQuality, PBM_SETPOS,·
06274f ¤   ¤   ¤   ¤   options->mMinPassphraseQuality, 0);
28af5a
61382c ¤   ¤   ¤   // Disable OK till we get a good passphrase if mins are active
8f197e ¤   ¤   ¤   if(options->mMinPassphraseQuality!=0)
783a72 //¤ ¤   ¤   ··(options->mMinPassphraseLength!=0))
f77bdb ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
17af5a
905f1f ¤   ¤   ¤   return FALSE;
1a0fe4 ¤   ¤   }
19af5a
948e1e ¤   ¤   case WM_COMMAND:
a35b34 ¤   ¤   {
43c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
5041c9 ¤   ¤   ¤   options = (CPGPConfirmationPassphraseDialogOptions *)
6195be ¤   ¤   ¤   ¤   gpp->options;
0faf5a
32256f ¤   ¤   ¤   switch(LOWORD (wParam))·
daf776 ¤   ¤   ¤   {
6ccae3 ¤   ¤   ¤   ¤   case IDOK:·
5c72c3 ¤   ¤   ¤   ¤   {
69b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
67af5a
--fdad 000e3a01d3f40110018 Page 26 of PGPPassphraseDialog.cpp
e24582 ¤   ¤   ¤   ¤   ¤   // get passphrase
937bd9 ¤   ¤   ¤   ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PHRASE1,·
7f2591 ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) +1;
89af5a
3af7e4 ¤   ¤   ¤   ¤   ¤   gpp->szDummy = (char *)secAlloc (gpp->context, i);
f9af5a
1aa3fb ¤   ¤   ¤   ¤   ¤   if(gpp->szDummy)
b54859 ¤   ¤   ¤   ¤   ¤   {
05601d ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhrase = (char *)secAlloc (gpp->context, i);
66af5a
8c0394 ¤   ¤   ¤   ¤   ¤   ¤   if (gpp->pszPassPhrase)·
b08fec ¤   ¤   ¤   ¤   ¤   ¤   {
a2296b ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PHRASE1, gpp->szDummy, i);
4aaf5a
e40a99 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // get passphrase confirmation
3f2d0d ¤   ¤   ¤   ¤   ¤   ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PHRASE2,·
9dff6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) +1;
58422f ¤   ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhraseConf = (char *)secAlloc (gpp->con¶
22f14a text, i);
8d2cf9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (gpp->pszPassPhraseConf)·
2006b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
72bc7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PHRASE2, gpp->szDummy¶
1bd6f7 , i);
46af5a
6a9396 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(PassphraseLengthAndQualityOK(hDlg,options,gp¶
af2ce2 p->pszPassPhrase))
ea31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
5bae45 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!lstrcmp (gpp->pszPassPhrase, gpp->pszP¶
2a58bf assPhraseConf))
badec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
f52929 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
75957d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(gpp->pszPassPhraseConf)
00e22d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
3a510c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secFree(gpp->pszPassPhraseConf);
b37d01 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhraseConf=NULL;
d5b6fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
432b97 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
7652b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
a48a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
84fc58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
55dec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
d5696f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPsdkUIMessageBox (hDlg, IDS_PGPERROR,·
63564d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_PHRASEMISMATCH, MB_OK|MB_ICONEX¶
75c692 CLAMATION);
1e8a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
076560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
c0c8fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Badpassphrase/quality
53d05b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
3e6823 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
110c63 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage (gpp->hwndQuality, PBM_SETPOS, 0, 0¶
256275 );
a1ff32 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(options->mMinPassphraseQuality!=0)
68ce0e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALS¶
931a95 E);
b6cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
a75268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
64db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e21c89 ¤   ¤   ¤   ¤   ¤   }
20af5a
ec1ba0 ¤   ¤   ¤   ¤   ¤   // Couldn't allocate passphrases
9f9ce1 ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
3ab0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
f42042 ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_OutOfMemory);
6114c3 ¤   ¤   ¤   ¤   ¤   break;
962613 ¤   ¤   ¤   ¤   }
baa3a6 ¤   ¤   ¤   }
decdcb ¤   ¤   ¤   break;
c00fe4 ¤   ¤   }
f19371 ¤   }
79a230 ¤   return FALSE;
c3efe6 }
e3af5a
--2c34 0005c7b2f2e40110018 Page 27 of PGPPassphraseDialog.cpp
cc7a75 // Double edit window
dcc744 ¤   PGPError
bae3bb pgpConfirmationPassphraseDialogPlatform(
7311f0 ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
229c10 ¤   CPGPConfirmationPassphraseDialogOptions ¤   *options)
c1bb36 {
410040 ¤   PGPError err;
2f6532 ¤   GPP¤gpp;
b2af5a
8c965c ¤   memset(&gpp,0x00,sizeof(GPP));
ed6ffb ¤   gpp.context=context;
8b66d6 ¤   gpp.options=options;
4daf5a
dc1e16 ¤   InitRandomKeyHook(&hhookKeyboard, &hhookMouse);
f99627 ¤   InstallSecurityHooks();
1567c5 ¤
36eff0 ¤   err = DialogBoxParam (g_hInst,·
450daa ¤   ¤   MAKEINTRESOURCE (IDD_PASSPHRASEENCRYPT),
8f3e26 ¤   ¤   options->mHwndParent,
923236 ¤   ¤   (DLGPROC)pgpConfirmationDlgProc, (LPARAM)&gpp);
10af5a
4644db ¤   *(options->mPassphrasePtr)=gpp.pszPassPhrase;
aaaf5a
b9e8a3 ¤   UninstallSecurityHooks();
a509b9 ¤   UninitRandomKeyHook(hhookKeyboard, hhookMouse);
cbaf5a
3bc7fd ¤   return(err);
15efe6 }
81af5a
eaf528 //¤ _________________________________________________________
6b465d //
366ba3 // ·Dialog Message procedure - get passphrase and signing key
d4af5a
be9993 BOOL CALLBACK·
7c316f pgpKeyPassphraseDlgProc (
3c3a3a ¤   ¤   HWND¤   hDlg,·
6aeb77 ¤   ¤   UINT¤   uMsg,·
2a0303 ¤   ¤   WPARAM¤ wParam,
95c0b8 ¤   ¤   LPARAM¤ lParam)·
abbb36 {
b070f6 ¤   CPGPKeyPassphraseDialogOptions *options;
ee584a ¤   GPP¤¤   ¤   ¤   *gpp;
e8dfcd ¤   INT¤¤   ¤   ¤   i;
b30f68 ¤   DWORD¤  ¤   ¤   Common;
b5af5a
c36122 ¤   Common=DoCommonCalls (hDlg,uMsg,wParam,lParam);·
b4af5a
2a6222 ¤   if(Common)
73a5aa ¤   ¤   return Common;
bdaf5a
2ae234 ¤   switch (uMsg)·
65c7a1 ¤   {
49df25 ¤   ¤   case WM_INITDIALOG:
e85b34 ¤   ¤   {
42afc0 ¤   ¤   ¤   RECT rc;
1fa3b5 ¤   ¤   ¤   int iTextWidth;
cbf34f ¤   ¤   ¤   HDC hdc;
297456 ¤   ¤   ¤   char szNameFinal[kPGPMaxUserIDSize];
b7af5a
c8c07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
2615b3 ¤   ¤   ¤   options = (CPGPKeyPassphraseDialogOptions *)
4d95be ¤   ¤   ¤   ¤   gpp->options;
f1af5a
ee101b ¤   ¤   ¤   gpp->iNextTabControl = IDOK;
edaf5a
db356f ¤   ¤   ¤   gpp->wpOrigPhrase1Proc = (WNDPROC) SetWindowLong(
67be5a ¤   ¤   ¤   ¤   GetDlgItem(hDlg, IDC_PHRASE1),·
beceaf ¤   ¤   ¤   ¤   GWL_WNDPROC,·
00a40b ¤   ¤   ¤   ¤   (LONG) PhraseSubclassProc);·
2faf5a
c8f00b ¤   ¤   ¤   GetClientRect(GetDlgItem(hDlg,IDC_KEYNAME), &rc);
5caf5a
--c2e3 00094bca38540110018 Page 28 of PGPPassphraseDialog.cpp
c36612 ¤   ¤   ¤   iTextWidth = rc.right-rc.left;
2616f8 ¤   ¤   ¤   hdc = GetDC (GetDlgItem(hDlg,IDC_KEYNAME));
e5bd6e ¤   ¤   ¤   GetKeyString(hdc,iTextWidth,options->mDefaultKey,szNameFinal);
a047b6 ¤   ¤   ¤   SetWindowText(GetDlgItem(hDlg,IDC_KEYNAME),szNameFinal);
301bf0 ¤   ¤   ¤   ReleaseDC (GetDlgItem (hDlg, IDC_KEYNAME), hdc);
f8af5a
7e181b ¤   ¤   ¤   DisplayOptions(hDlg,options->mDialogOptions,130);
6daf5a
ce5f1f ¤   ¤   ¤   return FALSE;
2f0fe4 ¤   ¤   }
3eaf5a
5a8e1e ¤   ¤   case WM_COMMAND:
635b34 ¤   ¤   {
dcc07c ¤   ¤   ¤   gpp=(GPP *)GetWindowLong (hDlg, GWL_USERDATA);
2515b3 ¤   ¤   ¤   options = (CPGPKeyPassphraseDialogOptions *)
0f95be ¤   ¤   ¤   ¤   gpp->options;
86af5a
5bd523 ¤   ¤   ¤   switch (LOWORD (wParam))·
e9f776 ¤   ¤   ¤   {
bfe168 ¤   ¤   ¤   ¤   case IDOK:
7672c3 ¤   ¤   ¤   ¤   {
1a0d93 ¤   ¤   ¤   ¤   ¤   PGPBoolean PassValid;
68af5a
08b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
74af5a
6f7bd9 ¤   ¤   ¤   ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PHRASE1,·
642591 ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) +1;
64af5a
1ff7e4 ¤   ¤   ¤   ¤   ¤   gpp->szDummy = (char *)secAlloc (gpp->context, i);
00af5a
fda3fb ¤   ¤   ¤   ¤   ¤   if(gpp->szDummy)
704859 ¤   ¤   ¤   ¤   ¤   {
ae601d ¤   ¤   ¤   ¤   ¤   ¤   gpp->pszPassPhrase = (char *)secAlloc (gpp->context, i);
98af5a
2e0394 ¤   ¤   ¤   ¤   ¤   ¤   if (gpp->pszPassPhrase)·
a68fec ¤   ¤   ¤   ¤   ¤   ¤   {
be296b ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PHRASE1, gpp->szDummy, i);
3d87c7 ¤   ¤   ¤
ace123 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(PassphraseLengthAndQualityOK(hDlg,options,gpp->p¶
49cc36 szPassPhrase))
f806b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
be8016 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!options->mVerifyPassphrase)
f831b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
e41447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
0bfb3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
8fc32b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
a06560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
56af5a
8b8a0b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PassValid=PGPPassphraseIsValid (options->mDefau¶
e1e3c8 ltKey,·
458494 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (gpp->context, gpp->pszPassP¶
9e1eb0 hrase),
0e0176 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (gpp->context));
ddaf5a
90c48c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(PassValid)
f231b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
8b1447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
c6fb3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
38c32b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
f86560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
86f9b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
4e31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
c991a8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPsdkUIMessageBox (hDlg,
b94825 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_PGPERROR,IDS_BADPASSREENTER,
40f199 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
9c6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
a55268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
c1f0f5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Bad passphrase/quality
955f0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
57c622 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
de8c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
94db3c ¤   ¤   ¤   ¤   ¤   ¤   }
--db2d 0003dfa74e440110018 Page 29 of PGPPassphraseDialog.cpp
b61c89 ¤   ¤   ¤   ¤   ¤   }
f1af5a
401ba0 ¤   ¤   ¤   ¤   ¤   // Couldn't allocate passphrases
009ce1 ¤   ¤   ¤   ¤   ¤   ClearPassphrases(hDlg,gpp);
b2b0d9 ¤   ¤   ¤   ¤   ¤   FreePassphrases(gpp);
642042 ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_OutOfMemory);
b914c3 ¤   ¤   ¤   ¤   ¤   break;
a32613 ¤   ¤   ¤   ¤   }
12a3a6 ¤   ¤   ¤   }
9e0fe4 ¤   ¤   }
5f2f68 ¤   ¤   break;
559371 ¤   }
b6a230 ¤   return FALSE;
62efe6 }
25af5a
ffaf5a
f0c744 ¤   PGPError
0a81b3 pgpKeyPassphraseDialogPlatform(
b7284d ¤   PGPContextRef¤  ¤   ¤   ¤   ¤   context,
2d5d0e ¤   CPGPKeyPassphraseDialogOptions ¤*options)
d4bb36 {
040040 ¤   PGPError err;
b61a6f ¤   PGPBoolean bShared,bNeedsPhrase;
d367c5 ¤
7e844b ¤   err=PGPGetKeyBoolean( options->mDefaultKey,
9d6a0d ¤   ¤   ¤   ¤   ¤   ¤   ··kPGPKeyPropIsSecretShared,
3fafa4 ¤   ¤   ¤   ¤   ¤   ¤   ··&bShared);
2467c5 ¤
2a0dc7 ¤   if(IsntPGPError(err) && bShared)
62c7a1 ¤   {
92bc14 ¤   ¤   // So, they want to do a shared key....
f241fb ¤   ¤   return(kPGPError_KeyUnusableForSignature);
b59371 ¤   }
631b52 ¤   ¤
352045 ¤   err=PGPGetKeyBoolean (options->mDefaultKey,
1dcdbd ¤   ¤   ¤   ¤   ¤   ¤   ··kPGPKeyPropNeedsPassphrase,
228416 ¤   ¤   ¤   ¤   ¤   ¤   ··&bNeedsPhrase);
9567c5 ¤
aca7bf ¤   if(IsntPGPError(err) && !bNeedsPhrase)
dcc7a1 ¤   {
79c83e ¤   ¤   *(options->mPassphrasePtr)=(char *)secAlloc (context, 1);
d876e7 ¤   ¤   if(*(options->mPassphrasePtr)==0)
1b2c5a ¤   ¤   ¤   return(kPGPError_OutOfMemory);
a11b52 ¤   ¤
22fa61 ¤   ¤   // Doesn't need a passphrase
31b288 ¤   ¤   strcpy(*(options->mPassphrasePtr),"");
72c8bd ¤   ¤   return(kPGPError_NoErr);
b19371 ¤   }
f81b52 ¤   ¤
9d5a9a ¤   if (options->mTextUI) {
0b522a ¤   ¤   return pgpKeyPassphraseCL(context, options);
58f037 ¤   } else {
98d0a3 ¤   ¤   GPP¤gpp;
a81b52 ¤   ¤
9ad7af ¤   ¤   memset(&gpp,0x00,sizeof(GPP));
b35ba6 ¤   ¤   gpp.context=context;
c9528b ¤   ¤   gpp.options=options;
531b52 ¤   ¤
104bba ¤   ¤   InitRandomKeyHook(&hhookKeyboard, &hhookMouse);
493b79 ¤   ¤   InstallSecurityHooks();
7c1b52 ¤   ¤
832aa5 ¤   ¤   err = DialogBoxParam (g_hInst,·
b446a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··MAKEINTRESOURCE (IDD_KEYPASSPHRASE),·
7b9efe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··options->mHwndParent,
f16aa3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··(DLGPROC)pgpKeyPassphraseDlgProc, (LPARAM)&gpp);
081b52 ¤   ¤
19eada ¤   ¤   *(options->mPassphrasePtr)=gpp.pszPassPhrase;
dc1b52 ¤   ¤
83dfab ¤   ¤   UninstallSecurityHooks();
c75c15 ¤   ¤   UninitRandomKeyHook(hhookKeyboard, hhookMouse);
041b52 ¤   ¤
3d8676 ¤   ¤   return(err);
--e9f4 001cc000edc40110018 Page 30 of PGPPassphraseDialog.cpp
a19371 ¤   }
c9efe6 }
a0af5a
67af5a
e72163 BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason,LPVOID lpvReserved)
e7bb36 {
1f5a5c ···switch (fdwReason) {
bad340 ······case DLL_PROCESS_ATTACH:
0783fd ·········g_hInst = hinstDll;
9c35cd ·········//vErrorOut(fg_white,"DLL_PROCESS_ATTACH\n");
425180 ·········break;
323ccb ······case DLL_THREAD_ATTACH:
2fd5a1 ··········//vErrorOut(fg_white,"DLL_THREAD_ATTACH\n");
f85180 ·········break;
6081b6 ······case DLL_THREAD_DETACH:
58f4ec ··········//vErrorOut(fg_red,"DLL_THREAD_DETACH\n");
445180 ·········break;
c36e3d ······case DLL_PROCESS_DETACH:
d455c8 ··········//vErrorOut(fg_red,"DLL_PROCESS_DETACH\n");
8a5180 ·········break;
3bb144 ···}
e87921 ···return(TRUE);
0cefe6 }
ccaf5a
--db98 00021a160f840110019 Page 1 of PGPRecipientDialog.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
d4e728 ¤   $Id: PGPRecipientDialog.cpp,v 1.29.2.1.2.1 1998/11/12 03:24:19 heller Exp $
96f7f7 ____________________________________________________________________________*/
7faf5a
a694d6 #include "PGPui32.h"
eecc06 #include "pgpDialogs.h"
024067 #include "RDprecmp.h"
41af5a
d39cad extern HINSTANCE g_hInst;
721396 extern HHOOK hhookKeyboard;
aa22dc extern HHOOK hhookMouse;
6caf5a
1a0a6c // BuildTable
e5465d //
be02bb // This routine takes our PGPRecipientsList and inserts them
6005d2 // into the correct listview.
5caf5a
0bed5a ¤   UINT
9721ea PopDialog(
16883c ¤   PGPContextRef¤  ¤   ¤   ¤   context,
d84108 ¤   CPGPRecipientDialogOptions ¤*options,
34548c ¤   PGPRecipientsList¤  ¤   ¤   *mRecipients)
dbbb36 {
c87d56 ¤   PGPError¤   ¤   ¤   err = kPGPError_NoErr;
6e576f ¤   PGPRecipientKey¤¤   *curKey;
55b095 ¤   PGPRecipientUser¤   *curGroup;
49a522 ¤   PGPRecipientUser¤   *curUser;
6a4256 ¤   PGPBoolean¤ haveRecipients = FALSE;
bc3b38 ¤   UINT ·RetVal = ADDUSER_OK;
60ea54 ¤   PGPInt32¤   minimumValidity;
a22b85 ¤   ¤   ¤   ¤
a06530 ¤   if( options->mIgnoreMarginalValidity )
a4c7a1 ¤   {
a2ddbb ¤   ¤   minimumValidity = (PGPInt32) kPGPValidity_Complete;
9a9371 ¤   }
b20e24 ¤   else
aec7a1 ¤   {
b07d0d ¤   ¤   minimumValidity = (PGPInt32) kPGPValidity_Marginal;
0d9371 ¤   }
742b85 ¤   ¤   ¤   ¤
4fd8af ¤   /*
d2a905 ¤   ** Check to see if the dialog needs to be displayed.
eaee82 ¤   ** Show the dialog there are missing, ambiguous, invalid,
c3b4b0 ¤   ** or no default recipients
5a9faa ¤   */
59af5a
ec50ec ¤   curKey = mRecipients->keys;
66ef78 ¤   while( IsntNull( curKey ) )
2cc7a1 ¤   {
ba791a ¤   ¤   curUser = curKey->users;
917ebc ¤   ¤   while( IsntNull( curUser ) )
005b34 ¤   ¤   {
338c93 ¤   ¤   ¤   if( curUser->location ==·
4db225 ¤   ¤   ¤   ¤   ¤   kPGPRecipientUserLocation_RecipientList )
61f776 ¤   ¤   ¤   {
a630fa ¤   ¤   ¤   ¤   haveRecipients=TRUE;
53af5a
a9032f ¤   ¤   ¤   ¤   if( curUser->multipleMatch )
0f956b ¤   ¤   ¤   ¤   ¤   RetVal=ADDUSER_MULTIPLEMATCH;
522b85 ¤   ¤   ¤   ¤
8c5751 ¤   ¤   ¤   ¤   if(¤curUser->validity < minimumValidity )
d33e0c ¤   ¤   ¤   ¤   ¤   RetVal=ADDUSER_KEYSNOTVALID;
7ca3a6 ¤   ¤   ¤   }
8887c7 ¤   ¤   ¤
ec09b3 ¤   ¤   ¤   curUser = curUser->nextUser;
240fe4 ¤   ¤   }
4167c5 ¤
e0cf46 ¤   ¤   curKey = curKey->nextKey;
219371 ¤   }
--d7ce 000a517d51340110019 Page 2 of PGPRecipientDialog.cpp
2a67c5 ¤
5bed6d ¤   curGroup = mRecipients->groups;
3a64b9 ¤   while( IsntNull( curGroup ) )
dfc7a1 ¤   {
20fa2f ¤   ¤   pgpAssert( curGroup->kind == kPGPRecipientUserKind_Group );
021b52 ¤   ¤
78c74a ¤   ¤   if( curGroup->location ==·
545025 ¤   ¤   ¤   ¤   kPGPRecipientUserLocation_RecipientList )
405b34 ¤   ¤   {
a95c4b ¤   ¤   ¤   haveRecipients = TRUE;
eaaf5a
f488a6 ¤   ¤   ¤   if( curGroup->multipleMatch )
e0da55 ¤   ¤   ¤   ¤   RetVal=ADDUSER_MULTIPLEMATCH;
152b85 ¤   ¤   ¤   ¤
8ff1a6 ¤   ¤   ¤   if(¤curGroup->validity < minimumValidity )
486c91 ¤   ¤   ¤   ¤   RetVal=ADDUSER_KEYSNOTVALID;
4f0fe4 ¤   ¤   }
64af5a
eb908a ¤   ¤   curGroup = curGroup->nextUser;
0c9371 ¤   }
8e67c5 ¤
69bffc ¤   curUser = mRecipients->missingRecipients;
53af5a
ee43d4 ¤   while( IsntNull( curUser ) )
82c7a1 ¤   {
c0be3b ¤   ¤   pgpAssert( curUser->kind ==
fa00cb ¤   ¤   ¤   ¤   kPGPRecipientUserKind_MissingRecipient );
17af5a
2c8804 ¤   ¤   if( curUser->location ==
365025 ¤   ¤   ¤   ¤   kPGPRecipientUserLocation_RecipientList )
205b34 ¤   ¤   {
f35447 ¤   ¤   ¤   RetVal=ADDUSER_KEYSNOTFOUND;
660fe4 ¤   ¤   }
522b85 ¤   ¤   ¤   ¤
c00c5e ¤   ¤   curUser = curUser->nextUser;
2a9371 ¤   }
bfaf5a
9b819b ¤   if(( ! haveRecipients ) || (IsPGPError(err)))
925196 ¤   ¤   RetVal = ADDUSER_NORECIPIENTSTOSEARCH;·
feaf5a
a66c87 ¤   return( RetVal );
bdefe6 }
ed67c5 ¤
0cc744 ¤   PGPError
777205 EventHandler(
8edad6 ¤   PGPRecipientsList ¤ *recipients,
5f00f8 ¤   PGPRecipientEvent ¤ *event,
b03a96 ¤   PGPUserValue ¤  ¤   userValue)
febb36 {
a8764c ¤   PGPError¤   err ¤   ¤   = kPGPError_NoErr;
f0abaf ¤   DWORD¤  ¤   strIndex ¤  = 0;
89667d ¤   const char¤ *userName¤  = NULL;
9cbffb ¤   PRECGBL prg;
7f67c5 ¤
f67507 ¤   (void) recipients;
ed4d52 ¤   (void) userValue;
4467c5 ¤
a784f4 ¤   prg=(PRECGBL)userValue;
14af5a
66a505 ¤   switch( event->type )
74c7a1 ¤   {
12bdb7 ¤   ¤   case kPGPRecipientEvent_MoveUserFailedEvent:
835b34 ¤   ¤   {
59b433 ¤   ¤   ¤   if( event->user->kind == kPGPRecipientUserKind_Key )
99f776 ¤   ¤   ¤   {
6b7b36 ¤   ¤   ¤   ¤   strIndex = IDS_NOKEYADKERR;
c1a3a6 ¤   ¤   ¤   }
f9bb8c ¤   ¤   ¤   else
7ff776 ¤   ¤   ¤   {
e92798 ¤   ¤   ¤   ¤   strIndex = IDS_NOGROUPADKERR;
85a3a6 ¤   ¤   ¤   }
a51b52 ¤   ¤
--51c9 0000395cb2540110019 Page 3 of PGPRecipientDialog.cpp
7b2d0c ¤   ¤   ¤   userName = PGPGetRecipientUserNamePtr( event->user );
56cdcb ¤   ¤   ¤   break;
b90fe4 ¤   ¤   }
4b1b52 ¤   ¤
39bdc9 ¤   ¤   case kPGPRecipientEvent_MoveUserWarningEvent:
c55b34 ¤   ¤   {
bab433 ¤   ¤   ¤   if( event->user->kind == kPGPRecipientUserKind_Key )
44f776 ¤   ¤   ¤   {
030ee1 ¤   ¤   ¤   ¤   strIndex = IDS_NOKEYADKWARN;
83a3a6 ¤   ¤   ¤   }
80bb8c ¤   ¤   ¤   else
e6f776 ¤   ¤   ¤   {
c842c9 ¤   ¤   ¤   ¤   strIndex = IDS_NOGROUPADKWARN;
99a3a6 ¤   ¤   ¤   }
241b52 ¤   ¤
912d0c ¤   ¤   ¤   userName = PGPGetRecipientUserNamePtr( event->user );
cecdcb ¤   ¤   ¤   break;
b50fe4 ¤   ¤   }
d91b52 ¤   ¤
c17a80 ¤   ¤   case kPGPRecipientEvent_MovedARRWarningEvent:
5b5b34 ¤   ¤   {
108189 ¤   ¤   ¤   strIndex = IDS_MOVEDARRWARN;
e02d0c ¤   ¤   ¤   userName = PGPGetRecipientUserNamePtr( event->user );
f187c7 ¤   ¤   ¤
f2cdcb ¤   ¤   ¤   break;
0f0fe4 ¤   ¤   }
4c9371 ¤   }
3767c5 ¤
3c42e8 ¤   if( strIndex != 0 )
ecc7a1 ¤   {
bfe1c0 ¤   ¤   char MsgTxt[255];
67083e ¤   ¤   char DlgTxt[255+kPGPMaxUserIDSize];
33a1c7 ¤   ¤   char StrRes[500];
5faf5a
8d9487 ¤   ¤   LoadString(g_hInst, strIndex, MsgTxt, sizeof(MsgTxt));
ce08df ¤   ¤   LoadString(g_hInst, IDS_RECIPIENTWARNING, StrRes, sizeof(StrRes));
8baf5a
9ffd0d ¤   ¤   sprintf(DlgTxt,MsgTxt,userName);
d3af5a
ee5894 ¤   ¤   MessageBox(prg->hwndRecDlg, DlgTxt,StrRes,·
21c4da ¤   ¤   ¤   MB_OK|MB_ICONWARNING);
859371 ¤   }
6267c5 ¤
7edeb7 ¤   return( err );
e2efe6 }
b7af5a
a03210 PGPError¤
58961d pgpGetMissingRecipientKeyIDStringPlatform(PGPContextRef context,
02a0f1 ¤   ¤   ¤   ¤   ¤   const PGPKeyID¤ *keyID, char keyIDString[256])
66bb36 {
7c61e0 ¤   PGPError¤   err;
c26d02 ¤   (void) context;
db67c5 ¤
ec591f ¤   err = PGPGetKeyIDString( keyID, kPGPKeyIDString_Abbreviated, keyIDString );
c8b1f0 ¤   if( IsntPGPError( err ) )
4ac7a1 ¤   {
3a8b10 ¤   ¤   char¤   pString[255];
f82349 ¤   ¤   char¤   tempStr[255];
551b52 ¤   ¤
7e794e ¤   ¤   strcpy(tempStr,keyIDString);
ada729 ¤   ¤   LoadString(g_hInst, IDS_UNKNOWNKEYIDSTR, pString, sizeof(pString));
b52b54 ¤   ¤   sprintf(keyIDString,pString,tempStr);
6c9371 ¤   }
0f67c5 ¤
e5deb7 ¤   return( err );
beefe6 }
f2af5a
d4c744 ¤   PGPError
9e0a0a pgpRecipientDialogPlatform(
9a883c ¤   PGPContextRef¤  ¤   ¤   ¤   context,
f03fb0 ¤   CPGPRecipientDialogOptions ¤*options)
03bb36 {
--e68f 000b6aada5d40110019 Page 4 of PGPRecipientDialog.cpp
118f52 ¤   PGPError¤   ¤   ¤   err;
37862c ¤   PRECGBL¤¤   ¤   ¤   prg;
fabb31 ¤   UINT¤   ¤   ¤   ¤   RetVal;
f9ff26 ¤   PGPBoolean¤ ¤   ¤   bPopDialog=TRUE;
b6ea99 ¤   PGPBoolean¤ ¤   ¤   haveDefaultARRs;
47af5a
98134e ¤   prg=(PRECGBL)malloc(sizeof(RECGBL));
44af5a
46ba8b ¤   if(prg)
e6c7a1 ¤   {
b26491 ¤   ¤   memset(prg,0x00,sizeof(RECGBL));
b2af5a
b4c96d ¤   ¤   prg->context=context;
9f1582 ¤   ¤   prg->tlsContext=options->mTLSContext;
ddb33d ¤   ¤   prg->ksEntries=options->mServerList;
ec8842 ¤   ¤   prg->numKSEntries=options->mServerCount;
373da6 ¤   ¤   prg->mWindowTitle=options->mWindowTitle;
c2b50a ¤   ¤   prg->mSearchBeforeDisplay=options->mSearchBeforeDisplay;
989ef6 ¤   ¤   prg->mDialogOptions=options->mDialogOptions;
3e699e ¤   ¤   prg->mNumDefaultRecipients=options->mNumDefaultRecipients;
a6748e ¤   ¤   prg->mDefaultRecipients=(struct PGPRecipientSpec *)options->mDefaultRec¶
49a7d0 ipients;
1b7ebf ¤   ¤   prg->mDisplayMarginalValidity=options->mDisplayMarginalValidity;
c1c9e0 ¤   ¤   prg->mIgnoreMarginalValidity=options->mIgnoreMarginalValidity;
9e2087 ¤   ¤   prg->mGroupSet=options->mGroupSet;
b82f4b ¤   ¤   prg->mClientKeySet=options->mClientKeySet;
a0f392 ¤   ¤   prg->mRecipientKeysPtr=options->mRecipientKeysPtr;
ef580f ¤   ¤   prg->mHwndParent=options->mHwndParent;
a974d9 ¤   ¤   prg->mNewKeys=options->mNewKeys;
a4af5a
ec9ba6 ¤   ¤   prg->g_hInst=g_hInst;
6faf5a
caf66a ¤   ¤   err = PGPBuildRecipientsList( options->mHwndParent,
8596cf ¤   ¤   ¤   context, options->mClientKeySet,
89c6f7 ¤   ¤   ¤   options->mGroupSet, options->mNumDefaultRecipients,
1a0259 ¤   ¤   ¤   options->mDefaultRecipients, options->mServerCount,
6c1a0d ¤   ¤   ¤   options->mServerList, options->mTLSContext,
49b5c5 ¤   ¤   ¤   options->mSearchBeforeDisplay, options->mEnforcement,
a78031 ¤   ¤   ¤   EventHandler, prg, &(prg->mRecipients), &haveDefaultARRs );
d6af5a
34a9c7 ¤   ¤   RetVal=¤PopDialog(context,options,&(prg->mRecipients));
e8af5a
6cd6ce ¤   ¤   if(RetVal==ADDUSER_OK)
235b34 ¤   ¤   {
c35241 ¤   ¤   ¤   bPopDialog=FALSE;
7c0fe4 ¤   ¤   }
84af5a
5c35ee ¤   ¤   if((bPopDialog)||(options->mAlwaysDisplay)||
59f214 ¤   ¤   ¤   (haveDefaultARRs && options->mAlwaysDisplayWithARRs))
da5b34 ¤   ¤   {
d6c1a8 ¤   ¤   ¤   prg->AddUserRetVal=RetVal;
10ae30 ¤   ¤   ¤   ¤   ¤
fa31cb ¤   ¤   ¤   InitRandomKeyHook(&hhookKeyboard,&hhookMouse);
86b33f ¤   ¤   ¤   RetVal=newPGPRecipientDialog(prg);
32342f ¤   ¤   ¤   UninitRandomKeyHook(hhookKeyboard,hhookMouse);
bf0fe4 ¤   ¤   }
0c0e1d ¤   ¤   else
695b34 ¤   ¤   {
e4e6bb ¤   ¤   ¤   RetVal=TRUE;
260fe4 ¤   ¤   }
5daf5a
255c15 ¤   ¤   if(RetVal)
d55b34 ¤   ¤   {
852c91 ¤   ¤   ¤   PGPGetRecipientKeys(&(prg->mRecipients),
575e89 ¤   ¤   ¤   ¤   options->mRecipientKeysPtr, options->mNewKeys,
13e28c ¤   ¤   ¤   ¤   options->mRecipientCount, options->mRecipientList);
230fe4 ¤   ¤   }
34af5a
f12a65 ¤   ¤   PGPDisposeRecipientsList(&(prg->mRecipients));
deaf5a
55deb4 ¤   ¤   free(prg);
b69371 ¤   }
--942c 001e76c139940110019 Page 5 of PGPRecipientDialog.cpp
e0af5a
9fbeb6 ¤   if(RetVal)
547af0 ¤   ¤   err=kPGPError_NoErr;
e40e24 ¤   else
88aa00 ¤   ¤   err=kPGPError_UserAbort;
a0af5a
dedeb7 ¤   return( err );
bfefe6 }
b9af5a
d4af5a
ec7e4d /*__Editor_settings____
baaf5a
3c4126 ¤   Local Variables:
727b17 ¤   tab-width: 4
1f0e6c ¤   End:
335f8c ¤   vi: ts=4 sw=4
7b9e9b ¤   vim: si
e7d062 _____________________*/
--e533 0018a0702574011001a Page 1 of PGPsdkUI.def
a44710 ; PGPsdkUI.def : Declares the module parameters for the DLL.
aaaf5a
9a39a0 DESCRIPTION ·'PGP SDK UI Library'
6daf5a
e9ef2b EXPORTS
fe5e48 ¤   PGPRecipientDialog
050ef5 ¤   PGPPassphraseDialog
96be48 ¤   PGPKeyPassphraseDialog
f68020 ¤   PGPConfirmationPassphraseDialog
7bb1fb ¤   PGPSigningPassphraseDialog
e4a571 ¤   PGPConventionalEncryptionPassphraseDialog
b5f23e ¤   PGPConventionalDecryptionPassphraseDialog
d54782 ¤   PGPDecryptionPassphraseDialog
3773b5 ¤   PGPOptionsDialog
dab1a6 ¤   PGPCollectRandomDataDialog
f7fec2 ¤   PGPSearchKeyServerDialog
50ae22 ¤   PGPSendToKeyServerDialog
6daf5a
faa0bc ¤   PGPEstimatePassphraseQuality
0aaf5a
2d9d80 ¤   PGPOUIDialogPrompt
517f52 ¤   PGPOUIWindowTitle
f9c4b7 ¤   PGPOUIOutputPassphrase
4b2453 ¤   PGPOUICheckbox
5ac7f0 ¤   PGPOUIPopupList
de1450 ¤   PGPOUIDialogOptions
9cea71 ¤   PGPOUIMinimumPassphraseLength
d95103 ¤   PGPOUIMinimumPassphraseQuality
6bfc21 ¤   PGPOUIShowPassphraseQuality
934170 ¤   PGPOUIDefaultKey
8ddcf2 ¤   PGPOUIVerifyPassphrase
b5eed4 ¤   PGPOUIFindMatchingKey
a4583d ¤   PGPOUIDefaultRecipients
0fcc15 ¤   PGPOUIDisplayMarginalValidity
6dfdb9 ¤   PGPOUIIgnoreMarginalValidity
77b62a ¤   PGPOUIRecipientGroups
845d73 ¤   PGPOUIParentWindowHandle
fc591c ¤   PGPOUIEnforceAdditionalRecipientRequests
433e0c ¤   PGPOUIKeyServerSearchFilter
863f01 ¤   PGPOUIKeyServerSearchKeySet
bfd7f9 ¤   PGPOUIKeyServerSearchKeyIDList
dc9951 ¤   PGPOUIKeyServerSearchKey
40dc05 ¤   PGPOUIKeyServerUpdateParams
50d69d ¤   PGPOUITextUI
8ac364 ¤   PGPOUIRecipientList
--061f 0008291682b4011001b Page 1 of PGPsdkUI.dsp
ea900e # Microsoft Developer Studio Project File - Name="PGPsdkUI" - Package Owner=<4>
97e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
af8537 # ** DO NOT EDIT **
3baf5a
e2a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
ffaf5a
7d6a38 CFG=PGPsdkUI - Win32 Debug Auth Only
a9894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
1c5c35 !MESSAGE use the Export Makefile command and run
d86309 !MESSAGE·
1b3d89 !MESSAGE NMAKE /f "PGPsdkUI.mak".
306309 !MESSAGE·
07cdb3 !MESSAGE You can specify a configuration when running NMAKE
9ae013 !MESSAGE by defining the macro CFG on the command line. For example:
2a6309 !MESSAGE·
5eeba5 !MESSAGE NMAKE /f "PGPsdkUI.mak" CFG="PGPsdkUI - Win32 Debug Auth Only"
876309 !MESSAGE·
b11dd7 !MESSAGE Possible choices for configuration are:
336309 !MESSAGE·
f82e07 !MESSAGE "PGPsdkUI - Win32 Release" (based on\
3c17ca ·"Win32 (x86) Dynamic-Link Library")
63cacc !MESSAGE "PGPsdkUI - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
2d08ab !MESSAGE "PGPsdkUI - Win32 Release Auth Only" (based on\
2b17ca ·"Win32 (x86) Dynamic-Link Library")
d7c26d !MESSAGE "PGPsdkUI - Win32 Debug Auth Only" (based on\
9d17ca ·"Win32 (x86) Dynamic-Link Library")
486309 !MESSAGE·
9eaf5a
023e63 # Begin Project
7bb23f # PROP Scc_ProjName ""
cedf4a # PROP Scc_LocalPath ""
be40a4 CPP=cl.exe
13a46a MTL=midl.exe
212e1f RSC=rc.exe
4faf5a
1bd29b !IF ·"$(CFG)" == "PGPsdkUI - Win32 Release"
88af5a
b28243 # PROP BASE Use_MFC 0
2fe662 # PROP BASE Use_Debug_Libraries 0
e07d73 # PROP BASE Output_Dir "Release"
d46180 # PROP BASE Intermediate_Dir "Release"
914c81 # PROP BASE Target_Dir ""
8c21ad # PROP Use_MFC 0
49b771 # PROP Use_Debug_Libraries 0
cef310 # PROP Output_Dir "Release"
b001a1 # PROP Intermediate_Dir "Release"
ee9ad5 # PROP Ignore_Export_Lib 0
12b6fa # PROP Target_Dir ""
9ec65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
bc10c2 ·/FD /c
171368 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\pfl\win32" /I "..\..\..\pfl\comm¶
8ee64b on" /I "..\..\..\pfl\common\file" /I "..\..\..\pfl\common\prefs" /I "..\..\..\p¶
46db7e fl\common\util" /I ".." /I "..\..\pub\include" /I "..\..\priv\include" /I "..\.¶
0af33c .\priv\include\opaque" /I "..\..\priv\crypto\bignum" /I "..\..\priv\crypto\ciph¶
b72db5 er" /I "..\..\priv\crypto\compress" /I "..\..\priv\crypto\hash" /I "..\..\priv\¶
4c5b55 crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\file" /I "..\..\priv\crypto\pipe\¶
ea4f5d parser" /I "..\..\priv\crypto\pipe\sig" /I "..\..\priv\crypto\pipe\text" /I "..¶
5abe0b \..\priv\crypto\pipe\utils" /I "..\..\priv\crypto\random" /I "..\..\priv\debug"¶
3a97dc ·/I "..\..\priv\keys\keydb" /I "..\..\priv\keys\keys" /I "..\..\priv\keys\pubke¶
2fa68b y" /I "..\..\priv\regexp" /I "..\..\priv\utilities\errors" /I "..\..\priv\utili¶
97bcd0 ties" /I "..\..\priv\utilities\helper" /I "..\..\priv\utilities\utils" /I "..\.¶
d840e9 .\priv\utilities\prefs" /I "..\..\priv\clientlib" /I "..\..\priv\encrypt" /I ".¶
f34763 .\..\..\pfl\common\sorting" /I "..\..\priv\ui" /D PGP_DEBUG=0 /D PGP_WIN32=1 /D¶
17d975 ·"NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
f51e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
7d6d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
5fb35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
cbde84 # ADD RSC /l 0x409 /d "NDEBUG"
bc18fc BSC32=bscmake.exe
7a7a24 # ADD BASE BSC32 /nologo
b74f1b # ADD BSC32 /nologo
82268f LINK32=link.exe
--3052 000ab4b5c354011001b Page 2 of PGPsdkUI.dsp
39cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
13a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
015e3b ·/nologo /subsystem:windows /dll /machine:I386
11700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
b2edec 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ../p¶
a80f08 gpcdk/release/pgp_sdk.lib ../pgpsdkNetworkLib/release/pgpsdkNL.lib comctl32.lib¶
fe5e3b ·/nologo /subsystem:windows /dll /machine:I386
3faf5a
defc9f !ELSEIF ·"$(CFG)" == "PGPsdkUI - Win32 Debug"
b3af5a
bc8243 # PROP BASE Use_MFC 0
5fffba # PROP BASE Use_Debug_Libraries 1
6a54b8 # PROP BASE Output_Dir "Debug"
4a198a # PROP BASE Intermediate_Dir "Debug"
784c81 # PROP BASE Target_Dir ""
7b21ad # PROP Use_MFC 0
1caea9 # PROP Use_Debug_Libraries 1
2bad22 # PROP Output_Dir "Debug"
99b954 # PROP Intermediate_Dir "Debug"
ee9ad5 # PROP Ignore_Export_Lib 0
e9b6fa # PROP Target_Dir ""
bc6cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
511fea DOWS" /YX /FD /c
025fc7 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\pfl\win32" /I "..\..\..¶
45e00f \pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\..\pfl\common\prefs" /I ".¶
6f6cfe .\..\..\pfl\common\util" /I ".." /I "..\..\pub\include" /I "..\..\priv\include"¶
835769 ·/I "..\..\priv\include\opaque" /I "..\..\priv\crypto\bignum" /I "..\..\priv\cr¶
025fdf ypto\cipher" /I "..\..\priv\crypto\compress" /I "..\..\priv\crypto\hash" /I "..¶
dc079e \..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\file" /I "..\..\priv\cry¶
6dbc00 pto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /I "..\..\priv\crypto\pipe\tex¶
3051fe t" /I "..\..\priv\crypto\pipe\utils" /I "..\..\priv\crypto\random" /I "..\..\pr¶
24b504 iv\debug" /I "..\..\priv\keys\keydb" /I "..\..\priv\keys\keys" /I "..\..\priv\k¶
d0d646 eys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\utilities\errors" /I "..\..\p¶
b0f4e6 riv\utilities" /I "..\..\priv\utilities\helper" /I "..\..\priv\utilities\utils"¶
5acdd5 ·/I "..\..\priv\utilities\prefs" /I "..\..\priv\clientlib" /I "..\..\priv\encry¶
d38c27 pt" /I "..\..\..\pfl\common\sorting" /I "..\..\priv\ui" /D UNFINISHED_CODE_ALLO¶
6e1ade WED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D "_DEBUG" /D "NEEDPROTOS" /D "WIN32" /D "¶
99ec1a _WINDOWS" /YX /FD /c
ecc0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
c7b3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
34699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
e90443 # ADD RSC /l 0x409 /d "_DEBUG"
f818fc BSC32=bscmake.exe
c37a24 # ADD BASE BSC32 /nologo
ed4f1b # ADD BSC32 /nologo
e7268f LINK32=link.exe
a4cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
08a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
bb17bf ·/nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
71700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
c9edec 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ../p¶
3ce721 gpcdk/debug/pgp_sdk.lib ../pgpsdkNetworkLib/debug/pgpsdkNL.lib comctl32.lib /no¶
d4bd97 logo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
40af5a
a9fdf3 !ELSEIF ·"$(CFG)" == "PGPsdkUI - Win32 Release Auth Only"
c7af5a
f78243 # PROP BASE Use_MFC 0
39e662 # PROP BASE Use_Debug_Libraries 0
e39655 # PROP BASE Output_Dir "PGPsdkUI"
44535d # PROP BASE Intermediate_Dir "PGPsdkUI"
bfa1ff # PROP BASE Ignore_Export_Lib 0
e54c81 # PROP BASE Target_Dir ""
7021ad # PROP Use_MFC 0
4bb771 # PROP Use_Debug_Libraries 0
c3dd87 # PROP Output_Dir "Release\Authentication"
e20ee8 # PROP Intermediate_Dir "Release\Authentication"
8b9ad5 # PROP Ignore_Export_Lib 0
63b6fa # PROP Target_Dir ""
9713fd # ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\pfl\win32" /I "..\..\..\pfl¶
a7b84e \common" /I "..\..\..\pfl\common\file" /I "..\..\..\pfl\common\prefs" /I "..\..¶
c61bab \..\pfl\common\util" /I ".." /I "..\..\pub\include" /I "..\..\priv\include" /I ¶
ab658d "..\..\priv\include\opaque" /I "..\..\priv\crypto\bignum" /I "..\..\priv\crypto¶
--86cc 00053f915ff4011001b Page 3 of PGPsdkUI.dsp
4ed344 \cipher" /I "..\..\priv\crypto\compress" /I "..\..\priv\crypto\hash" /I "..\..\¶
129c04 priv\crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\file" /I "..\..\priv\crypto\¶
4d47e7 pipe\parser" /I "..\..\priv\crypto\pipe\sig" /I "..\..\priv\crypto\pipe\text" /¶
d39a3c I "..\..\priv\crypto\pipe\utils" /I "..\..\priv\crypto\random" /I "..\..\priv\d¶
23b40f ebug" /I "..\..\priv\keys\keydb" /I "..\..\priv\keys\keys" /I "..\..\priv\keys\¶
576f54 pubkey" /I "..\..\priv\regexp" /I "..\..\priv\utilities\errors" /I "..\..\priv\¶
c7fc6d utilities" /I "..\..\priv\utilities\helper" /I "..\..\priv\utilities\utils" /I ¶
73b378 "..\..\priv\utilities\prefs" /I "..\..\priv\clientlib" /I "..\..\priv\encrypt" ¶
6f0e84 /I "..\..\..\pfl\common\sorting" /I "..\..\priv\ui" /D PGP_DEBUG=0 /D PGP_WIN32¶
e794b1 =1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c
bd1368 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\pfl\win32" /I "..\..\..\pfl\comm¶
6fe64b on" /I "..\..\..\pfl\common\file" /I "..\..\..\pfl\common\prefs" /I "..\..\..\p¶
27db7e fl\common\util" /I ".." /I "..\..\pub\include" /I "..\..\priv\include" /I "..\.¶
fff33c .\priv\include\opaque" /I "..\..\priv\crypto\bignum" /I "..\..\priv\crypto\ciph¶
e72db5 er" /I "..\..\priv\crypto\compress" /I "..\..\priv\crypto\hash" /I "..\..\priv\¶
955b55 crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\file" /I "..\..\priv\crypto\pipe\¶
aa4f5d parser" /I "..\..\priv\crypto\pipe\sig" /I "..\..\priv\crypto\pipe\text" /I "..¶
8dbe0b \..\priv\crypto\pipe\utils" /I "..\..\priv\crypto\random" /I "..\..\priv\debug"¶
7b97dc ·/I "..\..\priv\keys\keydb" /I "..\..\priv\keys\keys" /I "..\..\priv\keys\pubke¶
18a68b y" /I "..\..\priv\regexp" /I "..\..\priv\utilities\errors" /I "..\..\priv\utili¶
04bcd0 ties" /I "..\..\priv\utilities\helper" /I "..\..\priv\utilities\utils" /I "..\.¶
f240e9 .\priv\utilities\prefs" /I "..\..\priv\clientlib" /I "..\..\priv\encrypt" /I ".¶
4f4bb7 .\..\..\pfl\common\sorting" /I "..\..\priv\ui" /D PGP_ENCRYPT_DISABLE=1 /D PGP_¶
4f23e0 DECRYPT_DISABLE=1 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D "NDEBUG" /D "WIN32" /D "_WIN¶
4c1fea DOWS" /YX /FD /c
6a1e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
ea6d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
67b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
36de84 # ADD RSC /l 0x409 /d "NDEBUG"
8218fc BSC32=bscmake.exe
3e7a24 # ADD BASE BSC32 /nologo
9a4f1b # ADD BSC32 /nologo
61268f LINK32=link.exe
10cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
67a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
c2e7e0 ·../pgpcdk/release/pgp_sdk.lib ../pgpsdkNetworkLib/release/pgpsdkNL.lib comctl3¶
bfd8a8 2.lib /nologo /subsystem:windows /dll /machine:I386
4d700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
a8edec 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ../p¶
395187 gpcdk/release/Authentication/pgp_sdk_ltd.lib ../pgpsdkNetworkLib/release/Authen¶
22acec tication/pgpsdkNLLtd.lib comctl32.lib /nologo /subsystem:windows /dll /machine:¶
24bc6c I386 /out:"Release\Authentication/PGPsdkUILtd.dll"
e6af5a
879747 !ELSEIF ·"$(CFG)" == "PGPsdkUI - Win32 Debug Auth Only"
fcaf5a
298243 # PROP BASE Use_MFC 0
ebffba # PROP BASE Use_Debug_Libraries 1
c49655 # PROP BASE Output_Dir "PGPsdkUI"
07535d # PROP BASE Intermediate_Dir "PGPsdkUI"
17a1ff # PROP BASE Ignore_Export_Lib 0
3c4c81 # PROP BASE Target_Dir ""
d121ad # PROP Use_MFC 0
8faea9 # PROP Use_Debug_Libraries 1
f1d658 # PROP Output_Dir "Debug\Authentication"
d93f54 # PROP Intermediate_Dir "Debug\Authentication"
669ad5 # PROP Ignore_Export_Lib 0
55b6fa # PROP Target_Dir ""
7c61f9 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\pfl\win32" /I "..\¶
40dbfa ..\..\pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\..\pfl\common\prefs" ¶
07df7c /I "..\..\..\pfl\common\util" /I ".." /I "..\..\pub\include" /I "..\..\priv\inc¶
307a14 lude" /I "..\..\priv\include\opaque" /I "..\..\priv\crypto\bignum" /I "..\..\pr¶
89f7ba iv\crypto\cipher" /I "..\..\priv\crypto\compress" /I "..\..\priv\crypto\hash" /¶
abc981 I "..\..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\file" /I "..\..\pri¶
9e7267 v\crypto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /I "..\..\priv\crypto\pip¶
408317 e\text" /I "..\..\priv\crypto\pipe\utils" /I "..\..\priv\crypto\random" /I "..\¶
feb48c ..\priv\debug" /I "..\..\priv\keys\keydb" /I "..\..\priv\keys\keys" /I "..\..\p¶
65c568 riv\keys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\utilities\errors" /I "..¶
04c16d \..\priv\utilities" /I "..\..\priv\utilities\helper" /I "..\..\priv\utilities\u¶
13596f tils" /I "..\..\priv\utilities\prefs" /I "..\..\priv\clientlib" /I "..\..\priv\¶
ac556a encrypt" /I "..\..\..\pfl\common\sorting" /I "..\..\priv\ui" /D UNFINISHED_CODE¶
5ac5ce _ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D "_DEBUG" /D "NEEDPROTOS" /D "WIN32"¶
531239 ·/D "_WINDOWS" /YX /FD /c
--474e 000266c0c3f4011001b Page 4 of PGPsdkUI.dsp
d65fc7 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\pfl\win32" /I "..\..\..¶
9be00f \pfl\common" /I "..\..\..\pfl\common\file" /I "..\..\..\pfl\common\prefs" /I ".¶
ab6cfe .\..\..\pfl\common\util" /I ".." /I "..\..\pub\include" /I "..\..\priv\include"¶
495769 ·/I "..\..\priv\include\opaque" /I "..\..\priv\crypto\bignum" /I "..\..\priv\cr¶
a45fdf ypto\cipher" /I "..\..\priv\crypto\compress" /I "..\..\priv\crypto\hash" /I "..¶
77079e \..\priv\crypto\pipe\crypt" /I "..\..\priv\crypto\pipe\file" /I "..\..\priv\cry¶
6fbc00 pto\pipe\parser" /I "..\..\priv\crypto\pipe\sig" /I "..\..\priv\crypto\pipe\tex¶
0651fe t" /I "..\..\priv\crypto\pipe\utils" /I "..\..\priv\crypto\random" /I "..\..\pr¶
7ab504 iv\debug" /I "..\..\priv\keys\keydb" /I "..\..\priv\keys\keys" /I "..\..\priv\k¶
8ad646 eys\pubkey" /I "..\..\priv\regexp" /I "..\..\priv\utilities\errors" /I "..\..\p¶
2df4e6 riv\utilities" /I "..\..\priv\utilities\helper" /I "..\..\priv\utilities\utils"¶
1dcdd5 ·/I "..\..\priv\utilities\prefs" /I "..\..\priv\clientlib" /I "..\..\priv\encry¶
8c24da pt" /I "..\..\..\pfl\common\sorting" /I "..\..\priv\ui" /D PGP_ENCRYPT_DISABLE=¶
c8e3b7 1 /D PGP_DECRYPT_DISABLE=1 /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D PGP_W¶
cdcf2b IN32=1 /D "_DEBUG" /D "NEEDPROTOS" /D "WIN32" /D "_WINDOWS" /YX /FD /c
6fc0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
6fb3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
0c699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
320443 # ADD RSC /l 0x409 /d "_DEBUG"
1e18fc BSC32=bscmake.exe
367a24 # ADD BASE BSC32 /nologo
624f1b # ADD BSC32 /nologo
78268f LINK32=link.exe
becadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
a6a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
aee68f ·../pgpcdk/debug/pgp_sdk.lib ../pgpsdkNetworkLib/debug/pgpsdkNL.lib comctl32.li¶
47b9f0 b /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
fd700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
6fedec 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ../p¶
3fc38b gpcdk/debug/authentication/pgp_sdk_ltd.lib ../pgpsdkNetworkLib/debug/authentica¶
5725b4 tion/pgpsdkNLLtd.lib comctl32.lib /nologo /subsystem:windows /dll /debug /machi¶
2fde8a ne:I386 /out:"Debug\Authentication/PGPsdkUILtd.dll" /pdbtype:sept
e5af5a
8c30ec !ENDIF·
e6af5a
dfb8a5 # Begin Target
2eaf5a
e015ec # Name "PGPsdkUI - Win32 Release"
dbbb0f # Name "PGPsdkUI - Win32 Debug"
2e2b08 # Name "PGPsdkUI - Win32 Release Auth Only"
05e862 # Name "PGPsdkUI - Win32 Debug Auth Only"
184cc4 # Begin Group "Source Files"
28af5a
41b050 # PROP Default_Filter ""
f2df4f # Begin Source File
9aaf5a
98552c SOURCE=.\pgpCLUtils.c
ec6ccd # End Source File
89df4f # Begin Source File
baaf5a
eef549 SOURCE=.\PGPCollectRandomDataCL.cpp
556ccd # End Source File
3edf4f # Begin Source File
25af5a
7ed7fe SOURCE=.\PGPCollectRandomDataDialog.cpp
0d6ccd # End Source File
95df4f # Begin Source File
73af5a
d1d68b SOURCE=..\..\..\pfl\common\pgpDebug.c
ea6ccd # End Source File
11df4f # Begin Source File
a2af5a
97fd06 SOURCE=..\..\priv\ui\pgpDialogOptions.c
7b6ccd # End Source File
09df4f # Begin Source File
84af5a
15f6f9 SOURCE=..\..\priv\ui\pgpDialogs.cpp
5b6ccd # End Source File
98df4f # Begin Source File
fcaf5a
e33ca8 SOURCE=..\..\priv\ui\pgpDialogs.h
266ccd # End Source File
--d5c3 000e5586b044011001b Page 5 of PGPsdkUI.dsp
41df4f # Begin Source File
d0af5a
d8a074 SOURCE=..\..\..\pfl\common\file\pgpFileSpec.c
3d6ccd # End Source File
c0df4f # Begin Source File
5eaf5a
80fce5 SOURCE=..\..\..\pfl\common\file\pgpFileSpecStd.c
f66ccd # End Source File
68df4f # Begin Source File
35af5a
8ada19 SOURCE=..\..\..\pfl\common\file\pgpFileSpecVTBL.c
f66ccd # End Source File
c4df4f # Begin Source File
a7af5a
ae8f30 SOURCE=..\..\..\pfl\common\file\pgpFileSpecWin32.c
cf6ccd # End Source File
dedf4f # Begin Source File
f6af5a
c0926a SOURCE=.\pgpKBNT.c
d16ccd # End Source File
11df4f # Begin Source File
96af5a
c985e4 SOURCE=..\..\priv\ui\pgpKeyServerDialogCommon.cpp
846ccd # End Source File
90df4f # Begin Source File
7caf5a
0323f8 SOURCE=.\PGPKeyServerDialogs.cpp
7a6ccd # End Source File
6adf4f # Begin Source File
c0af5a
5893ff SOURCE=..\..\..\pfl\common\pgpLeaks.c
e06ccd # End Source File
86df4f # Begin Source File
acaf5a
65d78c SOURCE=..\..\..\pfl\common\pgpMem.c
806ccd # End Source File
aadf4f # Begin Source File
2baf5a
4c6b18 SOURCE=..\..\priv\utilities\pgpOptionList.c
e96ccd # End Source File
e3df4f # Begin Source File
17af5a
d48a06 SOURCE=.\PGPOptionsDialog.cpp
466ccd # End Source File
8cdf4f # Begin Source File
15af5a
cfd504 SOURCE=.\PGPPassphraseCL.cpp
c26ccd # End Source File
a7df4f # Begin Source File
9daf5a
3f49fd SOURCE=.\PGPPassphraseDialog.cpp
6f6ccd # End Source File
28df4f # Begin Source File
d1af5a
39275b SOURCE=..\..\..\pfl\common\util\pgpPassphraseUtils.c
d76ccd # End Source File
d4df4f # Begin Source File
a6af5a
1354c4 SOURCE=.\PGPRecipientDialog.cpp
566ccd # End Source File
89df4f # Begin Source File
fbaf5a
fbf210 SOURCE=..\..\priv\ui\pgpRecipientDialogCommon.cpp
6d6ccd # End Source File
fedf4f # Begin Source File
c6af5a
3a6953 SOURCE=.\PGPsdkUI.def
f36ccd # End Source File
28df4f # Begin Source File
94af5a
a4aff0 SOURCE=..\..\..\pfl\common\util\pgpStrings.c
e56ccd # End Source File
--88a6 000301548b64011001b Page 6 of PGPsdkUI.dsp
41df4f # Begin Source File
d0af5a
d9ac0b SOURCE=..\..\pub\include\pgpUserInterface.h
4e6ccd # End Source File
19df4f # Begin Source File
96af5a
dc4b15 SOURCE=.\RDdrag.c
e76ccd # End Source File
10df4f # Begin Source File
55af5a
db88b4 SOURCE=.\RDdraw.c
216ccd # End Source File
e9df4f # Begin Source File
3faf5a
cc707f SOURCE=.\RDkeyDB.c
cc6ccd # End Source File
07df4f # Begin Source File
efaf5a
53b61c SOURCE=.\RDlstmng.c
366ccd # End Source File
d9df4f # Begin Source File
4baf5a
f3e812 SOURCE=.\RDlstsrt.c
c16ccd # End Source File
0fdf4f # Begin Source File
f7af5a
8a50f5 SOURCE=.\RDlstsub.c
fd6ccd # End Source File
04df4f # Begin Source File
68af5a
7be7a2 SOURCE=.\RDmain.c
f96ccd # End Source File
c7df4f # Begin Source File
faaf5a
d5c0a9 SOURCE=.\RDmove.c
ae6ccd # End Source File
c5df4f # Begin Source File
fbaf5a
1382fe SOURCE=.\RDproc.c
146ccd # End Source File
4fdf4f # Begin Source File
24af5a
92442b SOURCE=.\RDserver.c
da6ccd # End Source File
8a3f5a # End Group
b98925 # Begin Group "Resource Files"
f2af5a
44054e # PROP Default_Filter "*.rc"
e6df4f # Begin Source File
25af5a
81c044 SOURCE=.\Res\dlgicon.ico
666ccd # End Source File
5fdf4f # Begin Source File
c8af5a
cb2655 SOURCE=..\..\..\..\clients\pgp\win32\shared\images24.bmp
486ccd # End Source File
c1df4f # Begin Source File
4faf5a
01bd3f SOURCE=..\..\..\..\clients\pgp\win32\shared\images4.bmp
196ccd # End Source File
16df4f # Begin Source File
d1af5a
766c66 SOURCE=.\PGPui.rc
1eaf5a
55d29b !IF ·"$(CFG)" == "PGPsdkUI - Win32 Release"
48af5a
0efc9f !ELSEIF ·"$(CFG)" == "PGPsdkUI - Win32 Debug"
8faf5a
4dfdf3 !ELSEIF ·"$(CFG)" == "PGPsdkUI - Win32 Release Auth Only"
40af5a
a09747 !ELSEIF ·"$(CFG)" == "PGPsdkUI - Win32 Debug Auth Only"
30af5a
--3651 001615375d94011001b Page 7 of PGPsdkUI.dsp
6230ec !ENDIF·
45af5a
496ccd # End Source File
c63f5a # End Group
cadf4f # Begin Source File
9caf5a
dc8381 SOURCE=.\Res\closelock.ico
ee6ccd # End Source File
bddf4f # Begin Source File
eeaf5a
bf5db5 SOURCE=.\Res\images24.bmp
336ccd # End Source File
cfdf4f # Begin Source File
e1af5a
3d9ac7 SOURCE=.\Res\images4.bmp
646ccd # End Source File
badf4f # Begin Source File
63af5a
cac09f SOURCE=.\Res\openlock.ico
8c6ccd # End Source File
1ce5cf # End Target
61f262 # End Project
--7a24 0017155d6aa4011001c Page 1 of PGPsdkUI.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
b56795 Project: "PGPsdkUI"=.\PGPsdkUI.dsp - Package Owner=<4>
d7af5a
74e41b Package=<5>
978818 {{{
25418b }}}
5aaf5a
20bec7 Package=<4>
878818 {{{
3e418b }}}
cfaf5a
422d94 ###############################################################################
eaaf5a
8220da Global:
41af5a
cae41b Package=<5>
c58818 {{{
28418b }}}
46af5a
1832c2 Package=<3>
1c8818 {{{
03418b }}}
2aaf5a
e42d94 ###############################################################################
71af5a
--9410 0006992cfa24011001d Page 1 of PGPui.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
6d6c0e /////////////////////////////////////////////////////////////////////////////
81465d //
90b090 // Dialog
94465d //
05af5a
e22a55 IDD_RECIPIENTDLG DIALOGEX 0, 0, 328, 236
ca3cfb STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
9c7541 EXSTYLE WS_EX_CONTEXTHELP
ebb167 CAPTION "Recipient Selection Dialog"
f75a4e CLASS "PGPrecipClass"
9c3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
394523 BEGIN
57eb9e ····DEFPUSHBUTTON ··"&OK",IDOK,157,215,50,14
44f2f3 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,214,215,50,14
245c10 ····PUSHBUTTON ·····"&Help",IDHELP,271,215,50,14
0212bd ····LTEXT ··········"Static",IDC_MSGTXT,17,90,296,28
004b13 ····CONTROL ········"",IDC_MSGTXTBORDER,"Static",SS_ETCHEDFRAME,45,19,20,40
2fe0d1 END
45af5a
654b9f IDD_PASSPHRASEOPTIONS DIALOGEX 0, 0, 264, 101
e9e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
f57541 EXSTYLE WS_EX_CONTEXTHELP
0b46cf CAPTION "PGP Enter Passphrase for Selected Key"
5f3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
8e4523 BEGIN
d46fb6 ····LTEXT ··········"&Passphrase of signing key :",IDC_PROMPTSTRING,7,26,187,
14e6e7 ····················8
fbec0a ····EDITTEXT ·······IDC_PHRASE1,7,38,250,27,ES_MULTILINE | WS_VSCROLL
dce2c3 ····DEFPUSHBUTTON ··"&OK",IDOK,151,80,50,14,WS_GROUP
56779b ····PUSHBUTTON ·····"&Cancel",IDCANCEL,207,80,50,14
7c399c ····LTEXT ··········"&Signing key :",IDC_STATIC1,8,7,42,8
5212da ····COMBOBOX ·······IDC_SIGNKEYCOMBO,52,7,205,60,CBS_DROPDOWNLIST |·
93be8a ····················WS_VSCROLL | WS_TABSTOP
8adce1 ····CONTROL ········"Hide T&yping",IDC_HIDETYPING,"Button",BS_AUTOCHECKBOX |·
1cc817 ····················BS_NOTIFY | WS_GROUP | WS_TABSTOP,203,26,54,10
852b0e ····LTEXT ··········"The currently selected key is a Blakely-Shamir split key. ¶
6ca2a7 If you wish to use this key, press OK to proceed to the split key reconstitutio¶
ff7d2c n dialog. Otherwise, select another key to use for signing.",
fb3546 ····················IDC_SPLITINFO,7,31,250,31,NOT WS_VISIBLE
e72525 ····LTEXT ··········"Note: Caps Lock is down. Passphrases are case-sensitive.",
13a0d3 ····················IDC_CAPSWARNING,7,69,250,8
6be0d1 END
f5af5a
49383f IDD_PASSPHRASEENCRYPT DIALOGEX 0, 0, 262, 153
bde659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
137541 EXSTYLE WS_EX_CONTEXTHELP
8cd4e5 CAPTION "PGP Enter Confirmed Passphrase"
603884 FONT 8, "MS Sans Serif", 0, 0, 0x1
694523 BEGIN
--dc20 000b75d055e4011001d Page 2 of PGPui.rc
3951b1 ····CONTROL ········"Progress1",IDC_PHRASEQUALITY,"msctls_progress32",0x0,79,
d472ed ····················56,176,7,WS_EX_CLIENTEDGE
0974a4 ····LTEXT ··········"&Passphrase :",IDC_PROMPTSTRING,7,7,185,8
8167b5 ····EDITTEXT ·······IDC_PHRASE1,7,22,248,28,ES_MULTILINE | WS_VSCROLL
86cd2f ····LTEXT ··········"Con&firmation :",IDC_STATIC1,7,79,44,8
9111da ····EDITTEXT ·······IDC_PHRASE2,7,89,248,28,ES_MULTILINE | WS_VSCROLL
121a9b ····DEFPUSHBUTTON ··"&OK",IDOK,150,132,50,14
d50196 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,205,132,50,14
b7dce1 ····CONTROL ········"Hide T&yping",IDC_HIDETYPING,"Button",BS_AUTOCHECKBOX |·
424f80 ····················BS_NOTIFY | WS_GROUP | WS_TABSTOP,201,7,54,10
122525 ····LTEXT ··········"Note: Caps Lock is down. Passphrases are case-sensitive.",
2217f3 ····················IDC_CAPSWARNING,7,121,248,8
b90a07 ····CONTROL ········"Progress1",IDC_MINQUALITY,"msctls_progress32",0x0,79,66,
d065b9 ····················176,7,WS_EX_CLIENTEDGE
ea665d ····LTEXT ··········"Passphrase Quality:",IDC_STATICPASSQUAL,7,55,66,8
476e6a ····LTEXT ··········"Minimum Quality:",IDC_STATICMINQUAL,7,65,66,8
7ee0d1 END
98af5a
75dd5e IDD_PASSPHRASEDECRYPTKEYS DIALOGEX 0, 0, 261, 143
61e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
4b7541 EXSTYLE WS_EX_CONTEXTHELP
e7a326 CAPTION "PGP Enter Passphrase for a Listed Key"
243884 FONT 8, "MS Sans Serif", 0, 0, 0x1
094523 BEGIN
da9021 ····LTEXT ··········"&Passphrase of decryption key :",IDC_PROMPTSTRING,7,70,
5ec366 ····················183,8
cc02da ····EDITTEXT ·······IDC_PHRASE1,7,81,247,27,ES_MULTILINE | WS_VSCROLL
2a69a6 ····DEFPUSHBUTTON ··"&OK",IDOK,148,123,50,14,WS_GROUP
2b4881 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,204,123,50,14
392c7e ····LTEXT ··········"Message was encrypted to the following public key(s) :",
404009 ····················IDC_STATIC1,7,7,172,8
7297b7 ····LISTBOX ········IDC_KEYLISTBOX,7,18,247,52,LBS_SORT | LBS_NOSEL |·
9cbe8a ····················WS_VSCROLL | WS_TABSTOP
d6dce1 ····CONTROL ········"Hide T&yping",IDC_HIDETYPING,"Button",BS_AUTOCHECKBOX |·
3c590d ····················BS_NOTIFY | WS_GROUP | WS_TABSTOP,200,70,54,10
c30349 ····LTEXT ··········"It is not possible to decrypt this message because your ke¶
196405 yring does not contain usable private key(s) corresponding to any of the above ¶
85ebe0 public key(s).",
1c0e8f ····················IDC_CANNOTDECRYPTTEXT,7,74,247,27,NOT WS_VISIBLE
342525 ····LTEXT ··········"Note: Caps Lock is down. Passphrases are case-sensitive.",
c8f9dd ····················IDC_CAPSWARNING,7,112,247,8
b9e0d1 END
cbaf5a
03d5fb IDD_PASSPHRASE DIALOGEX 0, 0, 267, 87
9fe659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
b67541 EXSTYLE WS_EX_CONTEXTHELP
81c072 CAPTION "PGP Enter Passphrase"
313884 FONT 8, "MS Sans Serif", 0, 0, 0x1
074523 BEGIN
fe340e ····LTEXT ··········"&Passphrase of private key :",IDC_PROMPTSTRING,7,7,175,
96e6e7 ····················8
7f7e92 ····EDITTEXT ·······IDC_PHRASE1,7,19,252,31,ES_MULTILINE | WS_VSCROLL
661635 ····DEFPUSHBUTTON ··"&OK",IDOK,152,66,50,14,WS_GROUP
6df822 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,209,66,50,14
a1dce1 ····CONTROL ········"Hide T&yping",IDC_HIDETYPING,"Button",BS_AUTOCHECKBOX |·
64ff1c ····················BS_NOTIFY | WS_GROUP | WS_TABSTOP,205,7,54,10
1b2525 ····LTEXT ··········"Note: Caps Lock is down. Passphrases are case-sensitive.",
4ff116 ····················IDC_CAPSWARNING,7,52,252,9
1fe0d1 END
efaf5a
c66d08 IDD_OPTIONSDIALOG DIALOG DISCARDABLE ·0, 0, 254, 190
51352f STYLE DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |·
de423d ····WS_THICKFRAME
131dcb CAPTION "PGP Options Dialog"
82309f FONT 8, "MS Sans Serif"
054523 BEGIN
a70459 ····DEFPUSHBUTTON ··"OK",IDOK,134,169,50,14
c91de2 ····PUSHBUTTON ·····"Cancel",IDCANCEL,197,169,50,14
0ce0d1 END
b4af5a
859788 IDD_KEYRAND DIALOG DISCARDABLE ·0, 0, 275, 166
b7e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
--979a 000483d378e4011001d Page 3 of PGPui.rc
bdee05 CAPTION "PGP Random Input"
a7309f FONT 8, "MS Sans Serif"
434523 BEGIN
9e609b ····DEFPUSHBUTTON ··"&Begin Input",IDC_BEGIN,58,81,70,14
57f5f3 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,147,81,70,14
e08e50 ····GROUPBOX ·······"Random Input",IDC_STATIC1,21,108,233,43,WS_DISABLED
443057 ····CTEXT ··········"",IDC_TEXTPROMPT,86,118,103,8,WS_DISABLED
72f252 ····LTEXT ··········"0 %",IDC_STATIC2,30,123,21,8,WS_DISABLED
a55675 ····RTEXT ··········"100 %",IDC_STATIC3,214,122,31,8,WS_DISABLED
78dae4 ····CONTROL ········"Progress1",IDC_BITSPROGBAR,"msctls_progress32",
ff1f0b ····················WS_DISABLED | WS_BORDER,29,135,217,7
baf1d7 ····LTEXT ··········"In order to perform this operation, some random input is n¶
a8411f eeded.",
52f6f8 ····················IDC_STATIC4,35,15,205,11
1be09a ····LTEXT ··········"To enter random input, please do one of the following :",
b84283 ····················IDC_STATIC5,35,33,205,11
187bcc ····LTEXT ··········"- Move your mouse randomly.",IDC_STATIC6,71,45,95,8
8fc64d ····LTEXT ··········"- Type random keys on the keyboard",IDC_STATIC7,71,56,
52e0ee ····················117,8
b0e0d1 END
abaf5a
3e7b65 IDD_KEYPASSPHRASE DIALOGEX 0, 0, 260, 101
63e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
167541 EXSTYLE WS_EX_CONTEXTHELP
afd870 CAPTION "PGP Enter Passphrase for Key"
f43884 FONT 8, "MS Sans Serif", 0, 0, 0x1
c34523 BEGIN
1e1405 ····LTEXT ··········"&Passphrase of private key :",IDC_PROMPTSTRING,7,24,177,
4ce6e7 ····················8
2554ac ····EDITTEXT ·······IDC_PHRASE1,7,39,244,26,ES_MULTILINE | WS_VSCROLL
810679 ····DEFPUSHBUTTON ··"&OK",IDOK,147,80,50,14,WS_GROUP
ef7c5f ····PUSHBUTTON ·····"&Cancel",IDCANCEL,202,80,50,14
19dce1 ····CONTROL ········"Hide T&yping",IDC_HIDETYPING,"Button",BS_AUTOCHECKBOX |·
6b1c63 ····················BS_NOTIFY | WS_GROUP | WS_TABSTOP,197,24,54,10
418aec ····EDITTEXT ·······IDC_KEYNAME,7,7,244,14,ES_AUTOHSCROLL | ES_READONLY
552525 ····LTEXT ··········"Note: Caps Lock is down. Passphrases are case-sensitive.",
f9f5cd ····················IDC_CAPSWARNING,7,67,245,8
4fe0d1 END
4aaf5a
b558a4 IDD_SERVERPROGRESS DIALOGEX 0, 0, 215, 63
4fd973 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION
0f2f93 CAPTION "PGP Keyserver Progress"
fc3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
364523 BEGIN
9e17aa ····DEFPUSHBUTTON ··"&Cancel",IDCANCEL,81,39,50,14
26a745 ····CTEXT ··········"Looking for host...",IDC_PROGRESSTEXT,5,6,204,8
209851 ····LTEXT ··········"",IDC_PROGRESS,43,23,126,8,0,WS_EX_CLIENTEDGE
5ee0d1 END
68af5a
95af5a
e26c0e /////////////////////////////////////////////////////////////////////////////
91465d //
656077 // DESIGNINFO
c9465d //
24af5a
90f860 #ifdef APSTUDIO_INVOKED
f170e4 GUIDELINES DESIGNINFO DISCARDABLE·
164523 BEGIN
c890c3 ····IDD_PASSPHRASEOPTIONS, DIALOG
ad5574 ····BEGIN
4ac975 ········LEFTMARGIN, 7
c22939 ········RIGHTMARGIN, 257
0187e9 ········TOPMARGIN, 7
e367c5 ········BOTTOMMARGIN, 94
3f7d01 ····END
d7af5a
33ae2a ····IDD_PASSPHRASEENCRYPT, DIALOG
d25574 ····BEGIN
c3c975 ········LEFTMARGIN, 7
8d1a89 ········RIGHTMARGIN, 255
5287e9 ········TOPMARGIN, 7
48c446 ········BOTTOMMARGIN, 146
--b647 0007f93f9624011001d Page 4 of PGPui.rc
3e7d01 ····END
94af5a
f6d7fd ····IDD_PASSPHRASEDECRYPTKEYS, DIALOG
855574 ····BEGIN
5fc975 ········LEFTMARGIN, 7
b20351 ········RIGHTMARGIN, 254
f287e9 ········TOPMARGIN, 7
c3519b ········BOTTOMMARGIN, 137
757d01 ····END
feaf5a
334153 ····IDD_PASSPHRASE, DIALOG
195574 ····BEGIN
d0c975 ········LEFTMARGIN, 7
99b329 ········RIGHTMARGIN, 259
1687e9 ········TOPMARGIN, 7
1b5a79 ········BOTTOMMARGIN, 80
377d01 ····END
a0af5a
b38245 ····IDD_OPTIONSDIALOG, DIALOG
2e5574 ····BEGIN
59c975 ········LEFTMARGIN, 7
2473e5 ········RIGHTMARGIN, 247
b187e9 ········TOPMARGIN, 7
f41f5d ········BOTTOMMARGIN, 183
e37d01 ····END
a2af5a
b852a5 ····IDD_KEYPASSPHRASE, DIALOG
095574 ····BEGIN
c3c975 ········LEFTMARGIN, 7
735781 ········RIGHTMARGIN, 252
a287e9 ········TOPMARGIN, 7
8167c5 ········BOTTOMMARGIN, 94
427d01 ····END
ebe0d1 END
4069ab #endif ···// APSTUDIO_INVOKED
84af5a
f9af5a
19f860 #ifdef APSTUDIO_INVOKED
a36c0e /////////////////////////////////////////////////////////////////////////////
e0465d //
c15733 // TEXTINCLUDE
2e465d //
42af5a
1386ef 1 TEXTINCLUDE DISCARDABLE·
4a4523 BEGIN
8b541e ····"resource.h\0"
62e0d1 END
d4af5a
dd7037 2 TEXTINCLUDE DISCARDABLE·
b24523 BEGIN
09eb23 ····"#include ""afxres.h""\r\n"
e5db5c ····"\0"
1be0d1 END
94af5a
cc227f 3 TEXTINCLUDE DISCARDABLE·
4e4523 BEGIN
e2e851 ····"\r\n"
f3db5c ····"\0"
eee0d1 END
92af5a
7269ab #endif ···// APSTUDIO_INVOKED
2eaf5a
0caf5a
806c0e /////////////////////////////////////////////////////////////////////////////
59465d //
bb86c0 // Menu
a1465d //
0daf5a
a01b3f IDR_MENU1 MENU DISCARDABLE·
314523 BEGIN
4e7098 ····POPUP "Server Menu"
7f5574 ····BEGIN
--0d5b 0003c9316fa4011001d Page 5 of PGPui.rc
832a8e ········MENUITEM "&Update Unknown Keys from Server", IDM_LOOKUP
07592d ········MENUITEM SEPARATOR
ced6a3 ········MENUITEM "&What's This?", ··············IDM_WHATSTHIS
067d01 ····END
d4e0d1 END
ecaf5a
95af5a
716c0e /////////////////////////////////////////////////////////////////////////////
91465d //
88ae70 // Bitmap
f0465d //
70af5a
69204c IDB_IMAGES4BIT ·········BITMAP ·DISCARDABLE ····"Res\\images4.bmp"
919bd6 IDB_IMAGES24BIT ········BITMAP ·DISCARDABLE ····"Res\\images24.bmp"
12af5a
576c0e /////////////////////////////////////////////////////////////////////////////
f2465d //
bccbaf // Icon
81465d //
73af5a
512951 // Icon with lowest ID value placed first to ensure application icon
e30f06 // remains consistent on all systems.
e9e52f IDI_DLGICON ············ICON ···DISCARDABLE ····"Res\\dlgicon.ico"
b8af5a
66e05c #ifndef _MAC
186c0e /////////////////////////////////////////////////////////////////////////////
e9465d //
c2c5f2 // Version
52465d //
52af5a
8c8df2 VS_VERSION_INFO VERSIONINFO
1eb865 ·FILEVERSION 1,5,2,0
2796b1 ·PRODUCTVERSION 1,5,2,0
6b5996 ·FILEFLAGSMASK 0x3fL
731f29 #ifdef _DEBUG
d19279 ·FILEFLAGS 0x21L
17db21 #else
3bc8a5 ·FILEFLAGS 0x20L
6a7454 #endif
21f6e6 ·FILEOS 0x40004L
e834dd ·FILETYPE 0x2L
81e8a0 ·FILESUBTYPE 0x0L
064523 BEGIN
432c72 ····BLOCK "StringFileInfo"
b75574 ····BEGIN
2470ac ········BLOCK "040904b0"
8352d6 ········BEGIN
1bb939 ············VALUE "CompanyName", "Network Associates, Inc.\0"
2333b1 ············VALUE "FileDescription", "PGP Software Development Kit UI Library\0"
f36b51 ············VALUE "FileVersion", "1.5.2\0"
80776b ············VALUE "InternalName", "PGPsdkUI\0"
a9d87b ············VALUE "LegalCopyright", "Copyright (C) 1998 Network Associates, Inc¶
007b55 \0"
70c61e ············VALUE "OriginalFilename", "PGPsdkUI.dll\0"
b76164 ············VALUE "ProductName", "PGPsdk\0"
a36da0 ············VALUE "ProductVersion", "1.5.2\0"
52eb90 ············VALUE "SpecialBuild", "Installed with PGP602\0"
b5f37f ········END
a27d01 ····END
a126ab ····BLOCK "VarFileInfo"
6f5574 ····BEGIN
924b11 ········VALUE "Translation", 0x409, 1200
647d01 ····END
09e0d1 END
13af5a
2ee6e6 #endif ···// !_MAC
e6af5a
89af5a
746c0e /////////////////////////////////////////////////////////////////////////////
b3465d //
845e87 // String Table
3c465d //
--874c 000750106e74011001d Page 6 of PGPui.rc
e0af5a
2e6f6c STRINGTABLE DISCARDABLE·
644523 BEGIN
e509fb ····IDS_GENERAL ············"General strings"
95120f ····IDS_NOSIGNKEY ··········"No signing key has been selected. ·Please select a¶
04f8ce ·key\nfrom the dropdown list of signing keys."
e50dab ····IDS_RANDOMPROMPT ·······"Enter random input:"
1afe1d ····IDS_RANDOMDONE ·········"Input complete!"
f8e0d1 END
a9af5a
156f6c STRINGTABLE DISCARDABLE·
184523 BEGIN
8d0f41 ····IDS_RSA ················"RSA"
86d32c ····IDS_DH ·················"DH"
f84e9f ····IDS_UNKNOWN ············"Unknown"
080ad3 ····IDS_RECIPIENTWARNING ···"Recipient Warning"
39421e ····IDS_RSADSAMIXWARNING ···"Signing with a Diffie-Hellman/DSS key when encrypt¶
592f2a ing to\nRSA recipients will result in a message that users of PGP\nversions pri¶
3dcb15 or to 5.0 will not be able to decrypt.\n\nAre you sure you want to do this?\n"
1fe0d1 END
7faf5a
e16f6c STRINGTABLE DISCARDABLE·
394523 BEGIN
bb135b ····IDS_PHRASEMISMATCH ·····"Passphrase entries do not match. ·Please try again¶
0cacf9 ."
c86a3f ····IDS_EMPTYPHRASE ········"You must enter a passphrase or click on ""Cancel""¶
36acf9 ."
97a26d ····IDS_WRONGPHRASE ········"&Re-enter passphrase or select a different key"
5fe0d1 END
3caf5a
686f6c STRINGTABLE DISCARDABLE·
4b4523 BEGIN
018f06 ····IDS_UNKNOWNKEYS ········"%i unknown key(s)"
409027 ····IDS_DSS ················"DSS"
54e0d1 END
c0af5a
526f6c STRINGTABLE DISCARDABLE·
714523 BEGIN
b6abf8 ····IDS_FOUNDMATCHFORPHRASE "The key with user ID\n\n%s\n\nmatches the passphra¶
1dc54b se.\n\nSign with this key instead?"
ec7471 ····IDS_PGP ················"PGP"
bda315 ····IDS_BADDECRYPTPHRASE ···"The passphrase you entered does not match any of t¶
6f7959 he usable listed keys."
6d3fc5 ····IDS_WRONGDECRYPTPHRASE ·"&Re-enter passphrase of your private key"
4ce0d1 END
8eaf5a
fb6f6c STRINGTABLE DISCARDABLE·
9a4523 BEGIN
c75a3b ····IDS_KEYSNOTVALID ·······"Some recipient keys are not valid. Please verify t¶
73019e hat these recipients are correct."
ae2072 ····IDS_KEYSNOTFOUND ·······"Some recipient keys were not found. Please find th¶
bde175 e correct recipient in the list above or double click the item to search for it¶
8c8d5f ·on a server."
980313 ····IDS_MULTIPLEMATCH ······"Multiple matches were found for some recipients. P¶
8ec4c5 lease remove any that do not apply."
b283e4 ····IDS_DEFAULT ············"Drag names from the user list to the recipients li¶
cc8c6f st."
86b298 ····IDS_KEYSNOTCORPSIGNED ··"Some recipient keys are not signed by the Corporat¶
cd5ab2 e Signing Key. Encrypting to these keys may be a violation of corporate securit¶
519344 y policy."
3329c6 ····IDS_ADKMISSING ·········"Missing Additional Decryption Keys prevented a pos¶
49c89f sible match. Please verify that the recipient list is correct.."
86be26 ····IDS_KSCONNECTING ·······"Connecting to "
2b9ee2 ····IDS_KSSEARCHING ········"Searching "
35403d ····IDS_KSPROCESSING ·······"Processing results from "
ff1062 ····IDS_KSDELETING ·········"Deleting key(s)..."
1d3fd5 ····IDS_KSDISABLING ········"Disabling key(s)..."
db6f31 ····IDS_KSCLOSINGSEND ······"Cleaning up..."
268e7e ····IDS_KSSENDING ··········"Sending to "
5a84d8 ····IDS_NOKEYADKERR ········"The user ""%s"" has a missing Additional Decryptio¶
40006e n Key. This user cannot \nbe used for encryption without the Additional Decrypt¶
7518f1 ion Key."
--2542 0011f473dae4011001d Page 7 of PGPui.rc
836ac6 ····IDS_NOGROUPADKERR ······"The group ""%s"" contains one or more keys with mi¶
5eaa7f ssing Additional \nDecryption Keys. This group cannot be used for encryption wi¶
b1b054 thout these \nAdditional Decryption Keys."
2ce0d1 END
52af5a
1a6f6c STRINGTABLE DISCARDABLE·
854523 BEGIN
46ee85 ····IDS_NUMKEYS ············"%d keys"
bce0d1 END
30af5a
c56f6c STRINGTABLE DISCARDABLE·
064523 BEGIN
e50979 ····IDS_NOKEYADKWARN ·······"The user ""%s"" has a missing Additional Decryptio¶
7e8526 n Key. Contact the owner \nof the key to obtain the Additional Decryption Key."
9e4d40 ····IDS_NOGROUPADKWARN ·····"The group ""%s"" contains one or more keys with mi¶
c65e5c ssing Additional \nDecryption Keys. Contact the owners of these keys to obtain ¶
4b8835 the \nAdditional Decryption Keys.\n\n"
1d17b1 ····IDS_MOVEDARRWARN ·······"Removing the Additional Decryption Key ""%s"" from¶
d56b6a ·the recipient list may \nviolate the policy established for other keys in the ¶
6363db recipient list."
f810eb ····IDS_PGPERROR ···········"PGP Error"
9cc3af ····IDS_NUMUNKNOWNKEYS ·····"%d unknown key(s)"
f80219 ····IDS_PASSNOTLONG ········"Passphrase is not of sufficient length. Please cho¶
df0cb0 ose another."
2de5ea ····IDS_PASSNOTQUALITY ·····"Passphrase is not of sufficient quality. Please ch¶
357b6e oose another."
53ec09 ····IDS_BADPASSREENTER ·····"Bad Passphrase: Please re-enter."
3f45c3 ····IDS_NUMOFNUMKEYS ·······"%d of %d keys"
10a9c0 ····IDS_UNKNOWNKEYIDSTR ····"Unknown User (Key ID is 0x%s)"
cde0d1 END
08af5a
6b1b3a #endif ···// English (U.S.) resources
6b6c0e /////////////////////////////////////////////////////////////////////////////
e7af5a
21af5a
48af5a
c7ce8c #ifndef APSTUDIO_INVOKED
b06c0e /////////////////////////////////////////////////////////////////////////////
09465d //
eb8464 // Generated from the TEXTINCLUDE 3 resource.
7a465d //
74af5a
acaf5a
b46c0e /////////////////////////////////////////////////////////////////////////////
9d8072 #endif ···// not APSTUDIO_INVOKED
1faf5a
--b2d4 00041063b864011001e Page 1 of PGPui32.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
0be601 ¤   PGPclx.h - internal header for PGPcl project
2467c5 ¤
44af5a
ed0203 ¤   $Id: PGPui32.h,v 1.13.2.1.2.1 1998/11/12 03:24:21 heller Exp $
9cf7f7 ____________________________________________________________________________*/
e5d51b #ifndef Included_PGPUI32_h¤ /* [ */
b2342a #define Included_PGPUI32_h
e5af5a
a579b0 #define UNFINISHED_CODE_ALLOWED¤¤   1
d52a68 #define WIN32_LEAN_AND_MEAN
19af5a
bad881 // Win32 header files
6a5655 #include <windows.h>
a53d0b #include <windowsx.h>
9290fb #include <commctrl.h>
1a7cab #include <stddef.h>
49af5a
2ee684 #include "pgpUserInterface.h"
4baf5a
85d495 // PGP SDK header files
93c5d5 #include "pgpBase.h"
b00d08 #include "pgpMem.h"
7ba076 #include "pgpKeys.h"
c72f8d #include "pgpErrors.h"
3f4919 #include "pgpUtilities.h"
9604f5 #include "pgpFeatures.h"
7391b9 #include "pgpSDKPrefs.h"
27e8b2 #include "pflPrefs.h"
924720 #include "pflPrefTypes.h"
8f894b #include "pgpFileSpec.h"
b6fbe2 #include "pgpMemoryIO.h"
c26aa0 #include "pgpWordWrap.h"
90c9be #include "pgpRandomPool.h"
9feb5b #include "pgpKeyServer.h"
5eaf5a
024fa9 // Our resource includes
cb3706 #include "UIhelp.h"
908031 #include "resource.h"
41af5a
e73379 #ifdef __cplusplus
496dad extern "C" {
4e7454 #endif
d9af5a
993538 void PGPsdkUICreateImageList(HIMAGELIST *hIml);
9daf5a
0524d9 PGPError PGPsdkUIErrorBox (HWND hWnd,PGPError error);
d4af5a
638723 void GetHelpDir(char *szHelp);
7aaf5a
a3a867 void InitRandomKeyHook(HHOOK* phhookKeyboard, HHOOK* phhookMouse);
d1af5a
fd2b66 void UninitRandomKeyHook(HHOOK hhookKeyboard, HHOOK hhookMouse);
36af5a
a24095 void MoveOptionsControl(HWND hDlg,HWND *hwndChild,
7b44fe ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef options,
760e48 ¤   ¤   ¤   ¤   ¤   ···int x,int y,
41052e ¤   ¤   ¤   ¤   ¤   ···int dx,int dy);
79af5a
143379 #ifdef __cplusplus
24efe6 }
517454 #endif
27af5a
f91b42 #endif /* ] Included_PGPUI32_h */
47af5a
3baf5a
257e4d /*__Editor_settings____
b4af5a
414126 ¤   Local Variables:
--0135 0015b0e3eed4011001e Page 2 of PGPui32.h
2f7b17 ¤   tab-width: 4
030e6c ¤   End:
9e5f8c ¤   vi: ts=4 sw=4
269e9b ¤   vim: si
d0d062 _____________________*/
5baf5a
--09da 00153f939994011001f Page 1 of PGPuiVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
6187d3 ············VALUE "FileDescription", "PGPsdk User Interface Library\0"
5bc1dd ············VALUE "FileVersion", PGPVERSIONSTRING
7c776b ············VALUE "InternalName", "PGPsdkUI\0"
c98ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
b72bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
b4c61e ············VALUE "OriginalFilename", "PGPsdkUI.dll\0"
079317 ············VALUE "ProductName", PGPPRODUCTNAME
05d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
b6f37f ········END
da7d01 ····END
fb26ab ····BLOCK "VarFileInfo"
445574 ····BEGIN
1c4b11 ········VALUE "Translation", 0x409, 1200
017d01 ····END
66e0d1 END
75af5a
4aaf5a
53af5a
--6a2b 000ec4872fa40110020 Page 1 of RDdrag.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
43aa8d ¤   $Id: RDdrag.c,v 1.2.10.1 1998/11/12 03:24:22 heller Exp $
e4f7f7 ____________________________________________________________________________*/
59af5a
914067 #include "RDprecmp.h"
d7af5a
6d38e5 /*
e35632 ·* DragItem.c ·Routines needed to create images for the ListView drag
68775e ·*
5cd20d ·* Since we're using ownerdrawn listboxes, we have to do all this ourselves.
54bd6b ·* These routines build the ImageList used with drag operations.
d2775e ·*
d9bd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
25599a ·* All rights reserved.
61495d ·*/
20af5a
d5de7b ··
ce67ab // OwnerDraw_CreateDragImage
35465d //
ff4149 // This routine replaces ListView_CreateDragImage since that routine
dd3e6b // breaks (doh!) under ownerdraw. It returns an himagelist associated
85c42a // with the selected item and mimics the ListView_CreateDragImage
a11ef2 // routine
eeaf5a
df81e6 HBITMAP OwnerDraw_CreateDragImage(HWND hwnd,int selitem)
c2bb36 {
b193be ····DRAWITEMSTRUCT DrawItem;
db7226 ····HDC hdc,hdcMem;
28a558 ····HBITMAP hBmp;
e68e51 ····RECT rcEntry;
4669d0 ····int dx,dy;
d407e4 ¤   LV_ITEM lvi;
e5bffb ¤   PRECGBL prg;
8baf5a
0b0b20 ¤   prg=(PRECGBL)GetWindowLong(GetParent(hwnd),GWL_USERDATA);
8aaf5a
bd88ea ¤   lvi.mask = LVIF_PARAM;
eaa008 ····lvi.iItem = selitem;
1990a4 ····lvi.iSubItem = 0;
583927 ····if(ListView_GetItem(hwnd, &lvi)==FALSE)
0cae1f ········return 0; // just in case we start drawing while we're half setup
0aaf5a
58b46d ····ListView_GetItemRect(hwnd,selitem,&rcEntry,LVIR_BOUNDS);·
f53cdf ····dx=rcEntry.right-rcEntry.left;
369e06 ····dy=rcEntry.bottom-rcEntry.top;
e0af5a
a9b198 ····hdc=GetDC(hwnd);
6d4ea3 ····hdcMem=CreateCompatibleDC(hdc);
0d82d3 ····hBmp=CreateCompatibleBitmap(hdc,dx,dy);
925f71 ····ReleaseDC(hwnd,hdc);
6eaf5a
cd8959 ····SelectObject(hdcMem,hBmp);
5aaf5a
99570c ····DrawItem.CtlType=ODT_LISTVIEW;·
44f87b ····DrawItem.CtlID=0; // Don't really need this
407e52 ····DrawItem.itemID=selitem;·
df8726 ····DrawItem.itemAction=ODA_DRAWENTIRE;·
d17654 ····DrawItem.itemState=0; ·// No highlights or anything
480fe5 ····DrawItem.hwndItem=hwnd;·
15e391 ····DrawItem.hDC=hdcMem;·
93cc20 ····DrawItem.rcItem.left=0;
97659a ····DrawItem.rcItem.top=0;
f34d30 ····DrawItem.rcItem.right=dx;
c5a187 ····DrawItem.rcItem.bottom=dy;
019800 ····DrawItem.itemData=lvi.lParam;// lParam taken care of in DrawLVitem
06af5a
ecc8ca ····FillRect(hdcMem,&DrawItem.rcItem,
--3760 000b919962240110020 Page 2 of RDdrag.c
d8d59d ¤   ¤   prg->ds.BackBrush);
acd83c ·
6aa1f5 ····DrawListViewItem(&DrawItem);
163cd4 ····DeleteDC(hdcMem);
e3af5a
add44c ····return hBmp;
99efe6 }
9caf5a
277da0 HBITMAP Custom_Merge(HWND hwnd,HBITMAP AccumBmp,HBITMAP NewBmp,
1eea79 ·····················int NewY,int RetX,int RetY,int *AccumY)
96ad39 { ···················
2d0e64 ····RECT bmpRect;
a5900c ····HDC hdc,hdcDest,hdcSrc;
1ea558 ····HBITMAP hBmp;
b68b7c ·¤  PRECGBL prg;
9caf5a
5a0b20 ¤   prg=(PRECGBL)GetWindowLong(GetParent(hwnd),GWL_USERDATA);
bdaf5a
a571f5 ····bmpRect.left=bmpRect.top=0;
440285 ····bmpRect.right=RetX;
4d13bd ····bmpRect.bottom=RetY;
2e869e ····
c1b198 ····hdc=GetDC(hwnd);
aacea0 ····hdcSrc=CreateCompatibleDC(hdc);
f0d495 ····hdcDest=CreateCompatibleDC(hdc);
0fb443 ····hBmp=CreateCompatibleBitmap(hdc,RetX,RetY);
f75f71 ····ReleaseDC(hwnd,hdc);
e3af5a
d652e0 ····SelectObject(hdcDest,hBmp); ·······
f5d83c ·
99c609 ····FillRect(hdcDest,&bmpRect,prg->ds.BackBrush);
e0f36a ····················
1447e0 ····SelectObject(hdcSrc,AccumBmp);
54af5a
b679f0 ····BitBlt(hdcDest,// handle to destination device context·
333697 ···········0, ·····// x-coordinate of destination rectangle's upper-left ·
f73697 ···········0, ·····// x-coordinate of destination rectangle's upper-left ·
b121cf ···········RetX, ··// width of destination rectangle·
1bbc88 ···········*AccumY,// height of destination rectangle·
443279 ···········hdcSrc, // handle to source device context·
a49832 ···········0, ·····// x-coordinate of source rectangle's upper-left ··
668f3e ···········0, ·····// y-coordinate of source rectangle's upper-left·
be4a3e ···········SRCCOPY);
66d83c ·
2e68b2 ····SelectObject(hdcSrc,NewBmp);
26af5a
d479f0 ····BitBlt(hdcDest,// handle to destination device context·
783697 ···········0, ·····// x-coordinate of destination rectangle's upper-left ·
69a79c ···········NewY, ··// x-coordinate of destination rectangle's upper-left ·
8821cf ···········RetX, ··// width of destination rectangle·
a21e2f ···········RetY-NewY,// height of destination rectangle·
7b3279 ···········hdcSrc, // handle to source device context·
348f39 ···········0, ·····// x-coordinate of source rectangle's upper-left
94005f ···········0, ·····// y-coordinate of source rectangle's upper-left
8b4a3e ···········SRCCOPY);
53af5a
c86d18 ····DeleteDC(hdcSrc);
fa6ac0 ····DeleteDC(hdcDest);
0f1398 ···············
a89267 ····DeleteObject(AccumBmp);
ed1a80 ····DeleteObject(NewBmp);
1a869e ····
792c4c ····*AccumY=RetY;
b6869e ····
4bd44c ····return hBmp;
ebefe6 }
78af5a
16af5a
14de7b ··
e528b8 HIMAGELIST MakeDragImage(HWND hwndDragFrom,int *left,int *bottom)
aebb36 {
b9dbcf ····int iCount, i, index, uState, result;
--509d 001aba0780d40110020 Page 3 of RDdrag.c
aae335 ····POINT pnt;
4e807f ····HIMAGELIST hDragImage;·
96ba93 ····HBITMAP NewBmp,AccumBmp;
9f85a8 ····RECT rcItem;
ab441a ····int lastx,lasty;
f271c1 ····int DragXsize,DragYsize;
1caf5a
9a6552 ····hDragImage=0;
87f183 ····index=0;
4daf5a
ea99a4 ····// How many items are there?
22ee60 ····iCount = ListView_GetItemCount(hwndDragFrom);
d8af5a
eced7f ····for( i = 0; i < iCount; i++ ) ·// Loop through each item
17421a ····{ ····
787e12 ········uState = ListView_GetItemState(hwndDragFrom , i, LVIS_SELECTED);
edaf5a
119842 ········if( uState ) // ·If this item is selected we want to move it
052b60 ········{
adbd40 ···············result=ListView_GetItemRect(hwndDragFrom,i,
f6f126 ···········································&rcItem,LVIR_BOUNDS);
7daf5a
ab337b ···············pnt.x=rcItem.left;
a112d4 ···············pnt.y=rcItem.top;
92af5a
1d4bc9 ···············NewBmp = OwnerDraw_CreateDragImage(hwndDragFrom,i);
f8af5a
d576d1 ···············if(index==0)
f05e94 ···············{
0ce0ab ···················AccumBmp=NewBmp;
7c4de1 ···················lastx=rcItem.left;
f56779 ···················lasty=rcItem.top;
4b9ee7 ···················*left=rcItem.left;
65c6e4 ···················*bottom=rcItem.bottom; ··
f43403 ···················DragYsize=rcItem.bottom-rcItem.top;
6d0a44 ···············}
f67f72 ···············else
585e94 ···············{
a1461e ····················AccumBmp=Custom_Merge(hwndDragFrom,AccumBmp,
544c1d ·······················NewBmp,pnt.y-lasty,rcItem.right,rcItem.bottom-lasty,
9cdc28 ·······················&DragYsize);
ca1cc5 ···············} ·····································
301398 ···············
0cd2ea ···············DragXsize=rcItem.right-rcItem.left;
d3db58 ··········index++;
fa6754 ·······}
2e6fe7 ····}
55af5a
789e4d ····hDragImage = ImageList_Create (DragXsize, DragYsize,·
924d88 ···································ILC_MASK|ILC_COLORDDB, 1, 1);
9eccea ····ImageList_AddMasked (hDragImage, AccumBmp, GetSysColor(COLOR_WINDOW));
ff9267 ····DeleteObject(AccumBmp);
0caf5a
b4a4ed ····return hDragImage;
51efe6 }
f7af5a
65af5a
397e4d /*__Editor_settings____
c1af5a
194126 ¤   Local Variables:
407b17 ¤   tab-width: 4
530e6c ¤   End:
af5f8c ¤   vi: ts=4 sw=4
fe9e9b ¤   vim: si
71d062 _____________________*/
abaf5a
--652f 001a401f87940110021 Page 1 of RDdrag.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7b06a3 ¤   $Id: RDdrag.h,v 1.1.12.1 1998/11/12 03:24:22 heller Exp $
d8f7f7 ____________________________________________________________________________*/
226909 #ifndef Included_RDDRAG_h¤  /* [ */
aa652e #define Included_RDDRAG_h
f7af5a
ceaf5a
7838e5 /*
54d3da ·* DragItem.h ·Routines needed to create images for the ListView drag
b9775e ·*
61d20d ·* Since we're using ownerdrawn listboxes, we have to do all this ourselves.
bcbd6b ·* These routines build the ImageList used with drag operations.
af775e ·*
0cbd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
4e599a ·* All rights reserved.
82495d ·*/
a9af5a
0e693f HIMAGELIST MakeDragImage(HWND hwndDragFrom,int *left,int *bottom); ·········
5cd83c ·
64af5a
1a6162 #endif /* ] Included_RDDRAG_h */
a6af5a
b9af5a
057e4d /*__Editor_settings____
5daf5a
f24126 ¤   Local Variables:
c27b17 ¤   tab-width: 4
640e6c ¤   End:
3b5f8c ¤   vi: ts=4 sw=4
459e9b ¤   vim: si
a4d062 _____________________*/
--fad7 000b6711afe40110022 Page 1 of RDdraw.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c776dd ¤   $Id: RDdraw.c,v 1.9.10.1 1998/11/12 03:24:23 heller Exp $
13f7f7 ____________________________________________________________________________*/
8daf5a
b74067 #include "RDprecmp.h"
baaf5a
3e38e5 /*
ca468e ·* OwnDraw.c ·ListView draw routines to accommidate italics/strikeout
47775e ·*
fa8a63 ·* These routines use the ownerdraw characteristic of the standard·
abea7f ·* listview to provide custom drawing routines.
f8775e ·*
6dbd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
fe599a ·* All rights reserved.
10495d ·*/
a6af5a
f8154d void CreateDrawElements(PGPContextRef context,DRAWSTRUCT *ds)
8dbb36 {
bdc1dd ¤   LOGFONT lf;
aaaf5a
058733 ¤   ds->DisplayMarginal=FALSE;
b1af5a
acd6be ····ds->stdbarbrush =·
51da3f ········CreateSolidBrush (GetSysColor (COLOR_3DSHADOW));
5f3d44 ····ds->spcbarbrush =·
911274 ········CreateHatchBrush(HS_BDIAGONAL, GetSysColor (COLOR_WINDOW));
b85e12 ····ds->g_seltextpen =·
b7f007 ········CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOWTEXT));
c3a07f ····ds->g_unseltextpen =
56717a ········CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOW));
3faf5a
e5aba6 ¤   ds->barcolor = GetSysColor (COLOR_3DSHADOW);
ecaf5a
b3a516 ····ds->buttonpen = CreatePen(PS_SOLID, 0, GetSysColor (COLOR_3DSHADOW));
338941 ¤   ds->hilightpen = CreatePen (PS_SOLID, 0,·
828cfd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DHILIGHT));
cfcea1 ¤   ds->shadowpen = CreatePen (PS_SOLID, 0,·
c73dd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DDKSHADOW));
6caf5a
8dc2fd ····ds->barbgbrush = CreateSolidBrush (GetSysColor (COLOR_3DFACE));
7daf5a
c54f7f ····ds->HighBrush=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
0983e0 ····ds->BackBrush=CreateSolidBrush(GetSysColor(COLOR_WINDOW));
17af5a
bf44ab ····SystemParametersInfo (SPI_GETICONTITLELOGFONT,·
59345f ¤   ¤   sizeof(LOGFONT), &lf, 0);
daaf5a
3af7b3 ····ds->hFont=CreateFontIndirect (&lf);
5481c9 ····lf.lfItalic = !lf.lfItalic;
7238b0 ····ds->hItalic=CreateFontIndirect (&lf);
d381c9 ····lf.lfItalic = !lf.lfItalic;
278205 ····lf.lfStrikeOut=TRUE;
70567a ····ds->hStrikeOut = CreateFontIndirect (&lf);
fdaf5a
e32b93 ¤   // ImageList Init
beaf5a
0fbaad ¤   PGPsdkUICreateImageList(&(ds->hIml));
0fefe6 }
a8af5a
d3e647 void DeleteDrawElements(DRAWSTRUCT *ds)
0fbb36 {
f54971 ····DeleteObject(ds->stdbarbrush);
44dd5d ····DeleteObject(ds->spcbarbrush);
deef39 ····DeleteObject(ds->g_seltextpen);
7db78c ····DeleteObject(ds->g_unseltextpen);
1eeff4 ¤   DeleteObject(ds->hilightpen);
b6401d ¤   DeleteObject(ds->shadowpen);
--17d2 0008920263340110022 Page 2 of RDdraw.c
6e5336 ¤   DeleteObject(ds->buttonpen);
2daf5a
f7c5ad ····DeleteObject(ds->barbgbrush);·
f6e855 ····DeleteObject(ds->HighBrush);·
84eeb7 ····DeleteObject(ds->BackBrush);·
18bfdc ¤   DeleteObject(ds->hFont);
8a4b24 ¤   DeleteObject(ds->hItalic);
2cf139 ¤   DeleteObject(ds->hStrikeOut);
901938 ¤   ImageList_Destroy(ds->hIml);
13efe6 }
c1af5a
f379f9 void DrawBar(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
a5a4a9 ·············int DataValue,int MaxValue,BOOL Selected)
40bb36 {
f9c194 ····RECT rc;
c27939 ····HBRUSH oldbrush,barbrush;
8ff069 ····HPEN oldpen;
aaaf32 ····COLORREF oldbkcolor;
1bd6f9 ¤   int cx;
98af5a
85c573 ¤   CopyRect(&rc,ptrBarRect);
e5af5a
1b7de8 ····if(Selected)
f03b37 ····{
a25f33 ········FillRect (hdc, &rc, ds->HighBrush);
14eee2 ········oldpen = SelectObject (hdc, ds->g_unseltextpen);
2b6fe7 ····}
11842c ····else
313b37 ····{
ce8d55 ········FillRect (hdc, &rc, ds->BackBrush);
aabfef ········oldpen = SelectObject (hdc, ds->g_seltextpen);
f06fe7 ····}
b1af5a
3c9228 ····rc.top+=5;
5ae182 ····rc.left+=5;
0829fd ····rc.bottom-=5;
690dda ····rc.right-=5;
04af5a
30eca7 ¤   if(rc.right<=rc.left)
bc99bf ¤   ¤   return;
32af5a
043f87 ¤   cx=rc.right-rc.left;
57af5a
525b7c ¤   oldbrush = SelectObject (hdc, ds->barbgbrush);
e244ef ¤   SelectObject (hdc, ds->buttonpen);
ebaf5a
6e766f ¤   Rectangle (hdc, rc.left - 1, rc.top - 1,·
eed7a3 ¤   ¤   rc.right + 2, rc.bottom + 2);
fcaf5a
7457c4 ¤   SelectObject (hdc, ds->shadowpen);
36eb65 ¤   MoveToEx (hdc, rc.left, rc.bottom, NULL);
a52014 ¤   LineTo (hdc, rc.left, rc.top);
5dd7f7 ¤   LineTo (hdc, rc.right, rc.top);
5faf5a
cda4af ¤   SelectObject (hdc, ds->hilightpen);
9ba783 ¤   LineTo (hdc, rc.right, rc.bottom);
f37046 ¤   LineTo (hdc, rc.left, rc.bottom);
18e624 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
020f63 ¤   if (MaxValue != 0)·
cec7a1 ¤   {
87d224 ¤   ¤   if (DataValue > MaxValue)·
d15b34 ¤   ¤   {
0e9763 ¤   ¤   ¤   barbrush = ds->spcbarbrush;
f640f1 ¤   ¤   ¤   rc.right = rc.left + cx;
e30fe4 ¤   ¤   }
69ee26 ¤   ¤   else·
a95b34 ¤   ¤   {
5232f3 ¤   ¤   ¤   barbrush = ds->stdbarbrush;
66fccf ¤   ¤   ¤   rc.right = rc.left +·
09135e ¤   ¤   ¤   ¤   (int)(((float)DataValue /·
701cbf ¤   ¤   ¤   ¤   (float)MaxValue)
8946cb ¤   ¤   ¤   ¤   * (float)cx);
--f042 00089dd552940110022 Page 3 of RDdraw.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
de4264 ¤   else·
b36cc3 ¤   ¤   rc.right = rc.left;
44af5a
93d34a ¤   rc.top++;
efb27f ¤   rc.left++;
eaaf5a
abba0a ¤   if (rc.right > rc.left)·
19c7a1 ¤   {
6e5974 ¤   ¤   oldbkcolor=SetBkColor (hdc, ds->barcolor);
d25341 ¤   ¤   FillRect (hdc, &rc, barbrush);·
b4af5a
77cbbc ¤   ¤   rc.top--;
16cd9f ¤   ¤   rc.left--;
55af5a
61cdf5 ¤   ¤   // hilight pen already selected·
18b757 ¤   ¤   MoveToEx (hdc, rc.right, rc.top, NULL);
e661e7 ¤   ¤   LineTo (hdc, rc.left, rc.top);
64eaa6 ¤   ¤   LineTo (hdc, rc.left,rc.bottom);
f0af5a
755988 ¤   ¤   SelectObject (hdc, ds->shadowpen);
d4a9cf ¤   ¤   LineTo (hdc, rc.right, rc.bottom);
5212a2 ¤   ¤   LineTo (hdc, rc.right, rc.top);
6e9b70 ¤   ¤   SetBkColor(hdc,oldbkcolor);
099371 ¤   }
3eaf5a
5723c2 ¤   SelectObject (hdc, oldbrush);
e862dc ¤   SelectObject (hdc, oldpen);
c5efe6 }
12af5a
bce23d void DrawNoviceButton(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
1fa4a9 ·············int DataValue,int MaxValue,BOOL Selected)
53bb36 {
915813 ¤   DWORD NoviceIcon;
fc47a3 //¤ HICON hIcon;
a0af5a
377de8 ····if(Selected)
853b37 ····{
2a437c ········FillRect (hdc, ptrBarRect, ds->HighBrush);
7d6fe7 ····}
0b842c ····else
323b37 ····{
f5911a ········FillRect (hdc, ptrBarRect, ds->BackBrush);
ce6fe7 ····}
23af5a
c9feb1 ¤   if((ptrBarRect->right-ptrBarRect->left)>=CX_SMICON)
a7c7a1 ¤   {
0d01c1 ¤   ¤   NoviceIcon=IDX_INVALID;
23af5a
42b1e3 ¤   ¤   if(DataValue>2)
06fcd5 ¤   ¤   ¤   NoviceIcon=IDX_AXIOMATIC;
08af5a
c97023 ¤   ¤   if(DataValue==2)
a17a44 ¤   ¤   ¤   NoviceIcon=IDX_VALID;
92af5a
fd1575 ¤   ¤   if((!ds->MarginalInvalid)&&(DataValue==1))
ff7a44 ¤   ¤   ¤   NoviceIcon=IDX_VALID;
55af5a
1bec08 #ifdef _WIN32
f850bd ¤   ¤   ImageList_Draw(ds->hIml,NoviceIcon,
7f36cb ¤   ¤   ¤   hdc,
908a15 ¤   ¤   ¤   ptrBarRect->left+((ptrBarRect->right-ptrBarRect->left-16)/2),
f24e5f ¤   ¤   ¤   ptrBarRect->top+((ptrBarRect->bottom-ptrBarRect->top-16)/2),
bb4a66 ¤   ¤   ¤   ILD_TRANSPARENT);
41db21 #else
743230 ¤   ¤   hIcon=LoadIcon(g_hinst,MAKEINTRESOURCE(NoviceIcon));
2167c5 ¤
666757 ¤   ¤   DrawIcon(hdc,
ceee0c ¤   ¤   ¤   ptrBarRect->left+((ptrBarRect->right-ptrBarRect->left-32)/2),
2c2a46 ¤   ¤   ¤   ptrBarRect->top+((ptrBarRect->bottom-ptrBarRect->top-32)/2),
89d911 ¤   ¤   ¤   hIcon);
--5c2c 0006410f9e640110022 Page 4 of RDdraw.c
2a67c5 ¤
a840c0 ¤   ¤   DeleteObject(hIcon);
077454 #endif
b59371 ¤   }
a0efe6 }
21af5a
4efe19 LISTSTRUCT *GetListStruct(HWND hwndList)
eebb36 {
82a34e ¤   LISTSTRUCT *lsRet;
ccbffb ¤   PRECGBL prg;

41af5a
96f360 ¤   prg=(PRECGBL)GetWindowLong(GetParent(hwndList),GWL_USERDATA);
47af5a
adb0b2 ¤   lsRet=&(prg->lsUser);
93af5a
9455c4 ¤   if(lsRet->hwndlist==hwndList)
f8d31a ¤   ¤   return lsRet;
0baf5a
b5e512 ¤   lsRet=&(prg->lsRec);
8caf5a
7e55c4 ¤   if(lsRet->hwndlist==hwndList)
01d31a ¤   ¤   return lsRet;
e1af5a
c0cee6 ¤   MessageBox(NULL,"Something's fishy","Ooops",MB_OK);
02af5a
7e3e6b ¤   return 0;
f5efe6 }
33af5a
43bbd0 DRAWSTRUCT *GetDrawStruct(HWND hDlg)
f2bb36 {
3cbffb ¤   PRECGBL prg;
feaf5a
349c17 ¤   prg=(PRECGBL)GetWindowLong(hDlg,GWL_USERDATA);
afaf5a
50fed1 ¤   return &(prg->ds);
fdefe6 }
6eaf5a
f6c0bc void DrawStuff(LPDRAWITEMSTRUCT lpDrawItem)
2bbb36 {
21c6af ¤   PUSERKEYINFO pui;
fa29b8 ¤   DRAWSTRUCT *ds;
9192b8 ¤   LISTSTRUCT *ls;
072715 ¤   int index;
5c5bda ¤   RECT rc;
f7c48c ¤   //HICON hIcon;
2998f5 ¤   HWND hDlg,hwndList;
29d8d0 ¤   int max;
765f44 ¤   BOOL focused;
8faf5a
436f72 ¤   focused=TRUE;
71af5a
f2c486 ¤   if(lpDrawItem->hwndItem!=0)
a0c7a1 ¤   {
c42ac2 ¤   ¤   if(GetFocus()!=lpDrawItem->hwndItem)
01b8b1 ¤   ¤   ¤   focused=FALSE;
c79371 ¤   }
b1af5a
1a02d2 ¤   hwndList=lpDrawItem->hwndItem;
7da701 ¤   hDlg=GetParent(hwndList);
8967c5 ¤
708529 ¤   ls=GetListStruct(hwndList);
87025a ¤   ds=GetDrawStruct(hDlg);
f3af5a
fcaf48 ¤   pui=(PUSERKEYINFO)(lpDrawItem->itemData);
ab71e5 ¤   CopyRect(&rc,&(lpDrawItem->rcItem));
05ec08 #ifdef _WIN32
d7b8c7 ¤   ImageList_Draw(ds->hIml,pui->icon,
7b69ca ¤   ¤   lpDrawItem->hDC,
9bafd5 ¤   ¤   rc.left+((CX_SMICON-16)/2),
e9a25a ¤   ¤   rc.top+((CY_SMICON-16)/2),
47c332 ¤   ¤   ILD_TRANSPARENT);
64db21 #else
--9550 000b2f3105140110022 Page 5 of RDdraw.c
ea3257 ¤   hIcon=LoadIcon(g_hinst,MAKEINTRESOURCE(pui->icon));
e967c5 ¤
5837cc ¤   DrawIcon(lpDrawItem->hDC,
08cbcc ¤   ¤   rc.left+((CX_SMICON-32)/2),
a5c643 ¤   ¤   rc.top+((CY_SMICON-32)/2),
984e62 ¤   ¤   hIcon);
8367c5 ¤
be749d ¤   DeleteObject(hIcon);
597454 #endif
cfa39f ¤   rc.right=rc.left;
4325fc ¤   rc.left=rc.left+16;
33af5a
c039b8 ¤   max=0;
8baf5a
254935 ¤   for(index=0;index<NUMCOLUMNS;index++)
19c7a1 ¤   {
df9510 #if LISTBOX
8c1ea5 ¤   ¤   max=max+ls->colwidth[index];
bedb21 #else
4bb072 ¤   ¤   max=max+
473886 ¤   ¤   ¤   ListView_GetColumnWidth(lpDrawItem->hwndItem,index);
487454 #endif
ec9371 ¤   }
e2af5a
8b4935 ¤   for(index=0;index<NUMCOLUMNS;index++)
67c7a1 ¤   {
879510 #if LISTBOX
f2520d ¤   ¤   rc.right=rc.right+ls->colwidth[index];
cbdb21 #else
440af1 ¤   ¤   rc.right=rc.right+
be3886 ¤   ¤   ¤   ListView_GetColumnWidth(lpDrawItem->hwndItem,index);
1b7454 #endif
e22a2d ¤   ¤   switch(index)
965b34 ¤   ¤   {
8675ac ¤   ¤   ¤   case 0:
2ff776 ¤   ¤   ¤   {
64b613 ¤   ¤   ¤   ¤   HFONT oldFont;
ec6097 ¤   ¤   ¤   ¤   RECT origrc;
11af5a
377778 ¤   ¤   ¤   ¤   // Save original rect
4a11a0 ¤   ¤   ¤   ¤   CopyRect(&origrc,&rc);
72af5a
6d593a ¤   ¤   ¤   ¤   oldFont=SelectObject(lpDrawItem->hDC,
0125e9 ¤   ¤   ¤   ¤   ¤   ¤   ds->hFont);
26af5a
ee1d5f ¤   ¤   ¤   ¤   if(pui->pru->kind==kPGPRecipientUserKind_MissingRecipient)
5ec298 ¤   ¤   ¤   ¤   ¤   SelectObject(lpDrawItem->hDC,
5031dd ¤   ¤   ¤   ¤   ¤   ¤   ds->hStrikeOut);
68af5a
268ae5 ¤   ¤   ¤   ¤   // See if we need the lock icon
194593 ¤   ¤   ¤   ¤   if(pui->pru->lockRefCount!=0)
2172c3 ¤   ¤   ¤   ¤   {
02c134 ¤   ¤   ¤   ¤   ¤   RECT temprc;
e7af5a
8cb911 ¤   ¤   ¤   ¤   ¤   CopyRect(&temprc,&rc);
1bab30 ¤   ¤   ¤   ¤   ¤   temprc.left=temprc.right-16;
8faf5a
990fb1 ¤   ¤   ¤   ¤   ¤   if(temprc.left>rc.left)
044859 ¤   ¤   ¤   ¤   ¤   {
1ab521 ¤   ¤   ¤   ¤   ¤   ¤   // Enough space. Draw Lock
8528b6 ¤   ¤   ¤   ¤   ¤   ¤   if((BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focuse¶
6f3d5d d)
468fec ¤   ¤   ¤   ¤   ¤   ¤   {
45f6dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   FillRect (lpDrawItem->hDC, &temprc, ds->HighBrush);
04db3c ¤   ¤   ¤   ¤   ¤   ¤   }
c07f8b ¤   ¤   ¤   ¤   ¤   ¤   else
d18fec ¤   ¤   ¤   ¤   ¤   ¤   {
1324ba ¤   ¤   ¤   ¤   ¤   ¤   ¤   FillRect (lpDrawItem->hDC, &temprc, ds->BackBrush);
71db3c ¤   ¤   ¤   ¤   ¤   ¤   }
60af5a
69a2c2 ¤   ¤   ¤   ¤   ¤   ¤   ImageList_Draw(ds->hIml,IDX_CLOSEDLOCK,
b2d8fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   lpDrawItem->hDC,
--b374 00088f8240540110022 Page 6 of RDdraw.c
3120f5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   temprc.left+((CX_SMICON-16)/2),
d8d261 ¤   ¤   ¤   ¤   ¤   ¤   ¤   temprc.top+((CY_SMICON-16)/2),
609736 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILD_TRANSPARENT);
c0af5a
bce891 ¤   ¤   ¤   ¤   ¤   ¤   // Make space for lock from text
d9ec90 ¤   ¤   ¤   ¤   ¤   ¤   rc.right=rc.right-16;
e21c89 ¤   ¤   ¤   ¤   ¤   }
562613 ¤   ¤   ¤   ¤   }
35af5a
90decf ¤   ¤   ¤   ¤   DrawItemColumn(lpDrawItem->hDC,pui->UserId,
af08f0 ¤   ¤   ¤   ¤   ¤   &rc);
e8af5a
d25924 ¤   ¤   ¤   ¤   // Set rectangle back to original
c947cf ¤   ¤   ¤   ¤   CopyRect(&rc,&origrc);
03af5a
75bc35 ¤   ¤   ¤   ¤   SelectObject(lpDrawItem->hDC,oldFont);
26f622 ¤   ¤   ¤   ¤   break;
e0a3a6 ¤   ¤   ¤   }
02af5a
be2f70 ¤   ¤   ¤   case 1:
64f776 ¤   ¤   ¤   {
3bebb4 ¤   ¤   ¤   ¤   if(ds->DisplayMarginal)
92d0a1 ¤   ¤   ¤   ¤   ¤   DrawBar(ds,lpDrawItem->hDC,&rc,pui->Validity,
63ae4a ¤   ¤   ¤   ¤   ¤   ¤   2,(BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focused¶
6f6275 );
4ffa07 ¤   ¤   ¤   ¤   else
a05dce ¤   ¤   ¤   ¤   ¤   DrawNoviceButton(ds,lpDrawItem->hDC,&rc,pui->Validity,
0cae4a ¤   ¤   ¤   ¤   ¤   ¤   2,(BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focused¶
a76275 );
7ef622 ¤   ¤   ¤   ¤   break;
cca3a6 ¤   ¤   ¤   }
75af5a
aaa1bf /*¤ ¤   ¤   case 2: // we no longer display trust in rec dlg
6cf776 ¤   ¤   ¤   {
3ea9db ¤   ¤   ¤   ¤   DrawBar(ds,lpDrawItem->hDC,&rc,pui->Trust,
0bf8b1 ¤   ¤   ¤   ¤   ¤   2,(BOOL)(lpDrawItem->itemState & ODS_SELECTED)&&focused);
bcf622 ¤   ¤   ¤   ¤   break;
cda3a6 ¤   ¤   ¤   }
b87fe0 */
76c014 ¤   ¤   ¤   case 2:
eef776 ¤   ¤   ¤   {
d1b613 ¤   ¤   ¤   ¤   HFONT oldFont;
1faf5a
3a593a ¤   ¤   ¤   ¤   oldFont=SelectObject(lpDrawItem->hDC,
6125e9 ¤   ¤   ¤   ¤   ¤   ¤   ds->hFont);
78af5a
192bd2 ¤   ¤   ¤   ¤   DrawItemColumn(lpDrawItem->hDC,pui->szSize,
da08f0 ¤   ¤   ¤   ¤   ¤   &rc);
69af5a
9dbc35 ¤   ¤   ¤   ¤   SelectObject(lpDrawItem->hDC,oldFont);
aff622 ¤   ¤   ¤   ¤   break;
afa3a6 ¤   ¤   ¤   }
690fe4 ¤   ¤   }
2cf6a0 ¤   ¤   rc.left=rc.right;
019371 ¤   }
5eb115 ¤   lpDrawItem->rcItem.right=max;
77efe6 }
69af5a
e7465d //
41728e // ·DrawListViewItem
c5465d //
380917 // ·This routine, given a standard Windows LPDRAWITEMSTRUCT, draws the
9d37a0 // ·elements of our custom listview (adapted from a routine in the Microsoft
61eab2 // ·Knowledge base)
73465d //
e5af5a
5320f4 void DrawListViewItem(LPDRAWITEMSTRUCT lpDrawItem)
e8bb36 {
9a6c54 ····UINT uiFlags;
965f44 ¤   BOOL focused;
85af5a
886f72 ¤   focused=TRUE;
--1e53 00021d59a5440110022 Page 7 of RDdraw.c
e0af5a
b3c486 ¤   if(lpDrawItem->hwndItem!=0)
84c7a1 ¤   {
f72ac2 ¤   ¤   if(GetFocus()!=lpDrawItem->hwndItem)
02b8b1 ¤   ¤   ¤   focused=FALSE;
8b9371 ¤   }
d6af5a
a46c24 ¤   uiFlags=ILD_TRANSPARENT;
79af5a
2ec1c4 ····// Check to see if this item is selected
ceb7e4 ····if ((lpDrawItem->itemState & ODS_SELECTED)&&(focused))
d13b37 ····{
6b2c2d ········// Set the text background and foreground colors
823903 ········SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
896bcd ········SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
dc869e ····
7ce79e ········// Also add the ILD_BLEND50 so the images come out selected
abe937 ········uiFlags |= ILD_BLEND50;
d76fe7 ····}
1b842c ····else
a93b37 ····{
e4cb98 ········// Set the text background and foreground colors to the·
49e1de ········// standard window colors
285e9d ········SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
bfdb7e ········SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
2d6fe7 ····}
87af5a
7b00d8 ¤   DrawStuff(lpDrawItem);
6eaf5a
250f7c ¤   lpDrawItem->rcItem.left=lpDrawItem->rcItem.left+CX_SMICON;
71af5a
e02640 ¤   if(!focused)
c399bf ¤   ¤   return;
a5af5a
b10fbc ····// If we changed the colors for the selected item, undo it
92398f ····if (lpDrawItem->itemState & ODS_SELECTED)
6b3b37 ····{
042c2d ········// Set the text background and foreground colors
0c5e9d ········SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
9ddb7e ········SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
c06fe7 ····}
4aaf5a
96d144 ····// If the item is focused, now draw a focus rect around the entire row
ee3167 ····if (lpDrawItem->itemState & ODS_FOCUS)
a43b37 ····{
f7427b ········// Draw the focus rect
8517a4 ········DrawFocusRect(lpDrawItem->hDC, &(lpDrawItem->rcItem));
d16fe7 ····}
26af5a
af3471 ····return;
24efe6 }
d8af5a
cbaf5a
072019 // DrawItemColumn
d5465d //
c349b8 // Given a clipping rectange and some text, see how well we can fit
c84ee5 // it in there, and tack on ... if we can't
8caf5a
d76622 void DrawItemColumn(HDC hdc, LPTSTR lpsz, LPRECT prcClip)
c0bb36 {
fe8a45 ····TCHAR szString[256];
d4af5a
c3c063 ····// Check to see if the string fits in the clip rect. ·If not, truncate
6b2180 ····// the string and add "...".
e78d35 ····lstrcpy(szString, lpsz);
35ceb8 ····CalcStringEllipsis(hdc, szString, 256, prcClip->right - prcClip->left);
6eaf5a
be2ef3 ····// print the text
9daf5a
8857fd ····ExtTextOut(hdc, prcClip->left + 2, prcClip->top + 1,·
590adf ···············ETO_CLIPPED | ETO_OPAQUE,
217025 ···············prcClip, szString, lstrlen(szString), NULL);
--f0f7 0000ed0dac240110022 Page 8 of RDdraw.c
7aefe6 }
46af5a
8eaf5a
c714ce // CalcStringEllipsis
2d465d //
ce219d // Trial and error routine used to see where to put the ... in our string
cb53b3 // to make it fit within a clipping rectangle.
51af5a
86b7ec BOOL CalcStringEllipsis(HDC hdc, LPTSTR lpszString,·
95f8e7 ························int cchMax, UINT uColWidth)
8ebb36 {
641156 ····const TCHAR szEllipsis[] = TEXT("...");
ea6bf7 ····SIZE ··sizeString;
4ed2ca ····SIZE ··sizeEllipsis;
971111 ····int ···cbString;
3018a5 ····LPTSTR lpszTemp;
d3ff5a ····BOOL ··fSuccess = FALSE;
c3a3ba ····BOOL fOnce = TRUE;
621a5b ····FARPROC pGetTextExtentPoint;
16af5a
dae171 ····if (fOnce)
6a3b37 ····{
701621 ········fOnce = FALSE;
03af5a
7464a2 ········pGetTextExtentPoint = &GetTextExtentPoint;
7f6fe7 ····}
63af5a
eda919 ····// Adjust the column width to take into account the edges
533d61 ····uColWidth -= 4;
30af5a
8c3b37 ····{
147672 ········// Allocate a string for us to work with. ·This way we can mangle the
fd2e34 ········// string and still preserve the return value
e5ed76 ········lpszTemp = (LPTSTR) malloc(cchMax);
a99fee ········lstrcpy(lpszTemp, lpszString);
73af5a
d25e6d ········// Get the width of the string in pixels
db3906 ········cbString = lstrlen(lpszTemp);
47592b ········(pGetTextExtentPoint)(hdc, lpszTemp, cbString, &sizeString);
a9af5a
168633 ········// If the width of the string is greater than the column width shave
2d95d2 ········// the string and add the ellipsis
672348 ········if ((ULONG)sizeString.cx > uColWidth)
ee2b60 ········{
df060c ············(pGetTextExtentPoint)(hdc, szEllipsis, lstrlen(szEllipsis),
40f5ab ·······································&sizeEllipsis);
eeaf5a
e7b699 ············while (cbString > 0)
7a2cc2 ············{
a18868 ················lpszTemp[--cbString] = 0;
a9267c ················!(pGetTextExtentPoint)(hdc, lpszTemp, cbString, &sizeString);
a8af5a
547c83 ················if ((ULONG)(sizeString.cx + sizeEllipsis.cx) <= uColWidth)
483b8c ················{
be82ae ················// The string with the ellipsis finally fits, now make sure
7a563f ················// there is enough room in the string for the ellipsis
c1ac8f ····················if (cchMax >= (cbString + lstrlen(szEllipsis)))
d28ae9 ····················{
f301a9 ····················// Concatenate the two strings and break out of the loop
269168 ························lstrcat(lpszTemp, szEllipsis);
ee2e9c ························lstrcpy(lpszString, lpszTemp);
1ddb42 ························fSuccess = TRUE;
388c7f ························break;
8bde39 ····················}
226f5c ················}
9b7812 ············}
f97fb0 ········}
371e5b ········else
dd2b60 ········{
e19fd4 ············// No need to do anything, everything fits great.
cb9b9b ············fSuccess = TRUE;
0e7fb0 ········}
--13e7 000ea4d19d540110022 Page 9 of RDdraw.c
9f6fe7 ····}
86af5a
e1bf86 ····// Free the memory
5f2d03 ····free(lpszTemp);
fef7c4 ····return (fSuccess);
e2efe6 }
23af5a
21af5a
6a1dd4 // Main_OnDrawItem
28465d //
60b626 // Entry function for the message handler. Basically, we want to draw
76b689 // the whole thing no matter what.
69af5a
1ba2cb BOOL Main_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
0ebb36 {
7daf5a
d78972 ····// Make sure the control is the listview control
dfbe00 ····if ((lpDrawItem->CtlType != ODT_LISTVIEW)&&
132dfb ¤   ¤   (lpDrawItem->CtlType != ODT_LISTBOX))
3281ae ········return FALSE;
1dd83c ·
c4f1c1 ¤   if(!IsWindowEnabled(lpDrawItem->hwndItem))
6498aa ¤   ¤   return FALSE;
c2af5a
8afb0f ····switch (lpDrawItem->itemAction)
783b37 ····{
16beb0 ········case ODA_DRAWENTIRE:
6cd89d ········case ODA_FOCUS:
ac2c3c ········case ODA_SELECT:
27569f ············DrawListViewItem((LPDRAWITEMSTRUCT)lpDrawItem);
d08632 ············break;
ff6fe7 ····}
eaaf5a
988011 ····return TRUE;
17efe6 }
58af5a
79d95e // Main_OnMeasureItem
50465d //
0c4e61 // Entry function for the message handler. We need to get the width and
62d969 // height of the font we're using.
15af5a
c86f5e void Main_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT * lpMeasureItem)
debb36 {
6b440f ····TEXTMETRIC tm;
a29d1b ····HDC hdc;
62d8c8 ····HWND hwndLV;
87fa9a ····HFONT hFont;
4eaf5a
748972 ····// Make sure the control is the listview control
8e3f00 ····if ((lpMeasureItem->CtlType != ODT_LISTVIEW)&&
b39de2 ¤   ¤   (lpMeasureItem->CtlType != ODT_LISTBOX))
17dc81 ········return;
dbaf5a
47b9e9 ····// Get the handle of the ListView control we're using
a2aa71 ····hwndLV = GetDlgItem(hwnd, lpMeasureItem->CtlID);
2faf5a
edf885 ····// Get the font the control is currently using
a266f3 ····hFont = (HFONT)(DWORD) SendMessage(hwndLV, WM_GETFONT, 0, 0L);
fcaf5a
a940b3 ····// Set the font of the DC to the same font the control is using
bd93bb ····hdc = GetDC(hwndLV);
250e12 ····SelectObject(hdc, hFont);
ebaf5a
1e363e ····// Get the height of the font used by the control
63521b ····if (!GetTextMetrics(hdc, &tm))
b7dc81 ········return;
c8af5a
d57b5f ····// Add a little extra space between items
f934c9 ····lpMeasureItem->itemHeight = tm.tmHeight + 1;
2daf5a
5fb2a8 ····// Make sure there is enough room for the images which are CY_SMICON high
ea0de5 ····if (lpMeasureItem->itemHeight < (CY_SMICON + 1))
--691d 001e342f8f740110022 Page 10 of RDdraw.c
24fffd ········lpMeasureItem->itemHeight = CY_SMICON + 1;
45af5a
43bf5f ····// Clean up
fe983e ····ReleaseDC(hwndLV, hdc);
f5efe6 }
c0af5a
3caf5a
ae7e4d /*__Editor_settings____
52af5a
194126 ¤   Local Variables:
bf7b17 ¤   tab-width: 4
9e0e6c ¤   End:
045f8c ¤   vi: ts=4 sw=4
2e9e9b ¤   vim: si
e3d062 _____________________*/
--d1d5 001b4ba12f140110023 Page 1 of RDdraw.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
3449aa ¤   $Id: RDdraw.h,v 1.1.12.1 1998/11/12 03:24:24 heller Exp $
95f7f7 ____________________________________________________________________________*/
44bfde #ifndef Included_RDDRAW_h¤  /* [ */
00a68f #define Included_RDDRAW_h
59af5a
7a38e5 /*
54468e ·* OwnDraw.c ·ListView draw routines to accommidate italics/strikeout
c2775e ·*
4b8a63 ·* These routines use the ownerdraw characteristic of the standard·
f7ea7f ·* listview to provide custom drawing routines.
8d775e ·*
28bd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
6a599a ·* All rights reserved.
3a495d ·*/
02af5a
3e7b18 #define CX_SMICON ··16 ·············// Size of the small images
72c966 #define CY_SMICON ··16
d6af5a
2115af #define PGP_DDERROR 1
dd213f #define PGP_DDTEXT 2
ed7755 #define PGP_DDBAR 3
f4af5a
e37d6c #define MAXCOLS 10
8faf5a
8a99d4 void CreateDrawElements(PGPContextRef context,DRAWSTRUCT *ds);
5a367d void DeleteDrawElements(DRAWSTRUCT *ds);
8679f9 void DrawBar(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
2a384f ·············int DataValue,int MaxValue,BOOL Selected);
26b1ab void DrawListViewItem(LPDRAWITEMSTRUCT lpDrawItem);
d50256 void DrawItemColumn(HDC hdc, LPTSTR lpsz, LPRECT prcClip);
3fb7ec BOOL CalcStringEllipsis(HDC hdc, LPTSTR lpszString,·
b39369 ························int cchMax, UINT uColWidth);
21785d BOOL Main_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem);
24bbb4 void Main_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT * lpMeasureItem);
cfaf5a
89d4ab #endif /* ] Included_RDDRAW_h */
ecaf5a
ebaf5a
637e4d /*__Editor_settings____
76af5a
964126 ¤   Local Variables:
7c7b17 ¤   tab-width: 4
280e6c ¤   End:
f05f8c ¤   vi: ts=4 sw=4
a79e9b ¤   vim: si
b4d062 _____________________*/
--5bdb 000a7c8d20b40110024 Page 1 of RDkeyDB.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e993df ¤   $Id: RDkeyDB.c,v 1.14.10.1 1998/11/12 03:24:25 heller Exp $
fff7f7 ____________________________________________________________________________*/
a2af5a
c94067 #include "RDprecmp.h"
f7af5a
c6a203 UINT KMConvertFromPGPValidity (UINT uPGPValidity) {
ab83f5 ····switch (uPGPValidity) {
c94ede ····case kPGPValidity_Unknown :
8ab843 ····case kPGPValidity_Invalid :
2b82c5 ········return 0;
400548 ····case kPGPValidity_Marginal :
08d819 ········return 1;
10d555 ····case kPGPValidity_Complete :
20377d ········return 2;
a66fe7 ····}
f9efe6 }
1eaf5a
73e5ee UINT KMConvertFromPGPTrust (UINT uPGPTrust) {
c77573 ····switch (uPGPTrust & kPGPKeyTrust_Mask) {
86a7d2 ····case kPGPKeyTrust_Undefined ···:
77bb5e ····case kPGPKeyTrust_Unknown :
c99988 ····case kPGPKeyTrust_Never :
7982c5 ········return 0;
4381b5 ····case kPGPKeyTrust_Marginal :
01d819 ········return 1;
cd51a8 ····case kPGPKeyTrust_Complete :
6d377d ········return 2;
811452 ····case kPGPKeyTrust_Ultimate :
396da1 ········return 3;
916fe7 ····}
deefe6 }
20af5a
e3d928 PUSERKEYINFO AddLink(PUSERKEYINFO head,PUSERKEYINFO pui)
e4bb36 {
6dd0b2 ····pui->next=head;
8baf5a
9ac5ee ····return pui;
e7efe6 }
40af5a
73111e UINT AddToTable(HWND hwndTable,
392400 ¤   ¤   ¤   ¤   PGPGroupSetRef mGroupSet,
08657a ¤   ¤   ¤   ¤   PGPRecipientUser *pru,
12eac7 ¤   ¤   ¤   ¤   PUSERKEYINFO *UserLinkedList)
50bb36 {
40c6af ¤   PUSERKEYINFO pui;
8743d6 ····PGPKeyRef key;
99974c ¤   DWORD image;
a4af5a
8f64e8 ¤   pui=(PUSERKEYINFO)malloc(sizeof(USERKEYINFO));
01aefd ¤   memset(pui,0x00,sizeof(USERKEYINFO));
baaf5a
3cf95d ¤   switch(pru->kind)
a4c7a1 ¤   {
012e57 ¤   ¤   case kPGPRecipientUserKind_Key:
535b34 ¤   ¤   {
d6f269 ¤   ¤   ¤   PGPBoolean bAxiomatic;
ec5e25 ¤   ¤   ¤   PGPRecipientKey *rKey;
f4af5a
66a53a ¤   ¤   ¤   rKey=pru->userInfo.key;
7f851e ¤   ¤   ¤   key=rKey->keyRef;
42af5a
c4c7b2 ¤   ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropIsAxiomatic, &bAxiomatic);
829e86 ¤   ¤   ¤   PGPGetKeyNumber(key, kPGPKeyPropTrust, &(pui->Trust));
30af5a
af56ce ¤   ¤   ¤   PGPGetRecipientUserName(pru,pui->UserId);
a7af5a
--7082 000ff2ff1e540110024 Page 2 of RDkeyDB.c
bb8c47 ¤   ¤   ¤   pui->Validity=pru->validity;
1eaf5a
91e7af ¤   ¤   ¤   pui->Validity= KMConvertFromPGPValidity(pui->Validity);
aba523 ¤   ¤   ¤   pui->Trust= KMConvertFromPGPTrust (pui->Trust);
34af5a
e1dee9 ¤   ¤   ¤   if (bAxiomatic)·
2bf776 ¤   ¤   ¤   {
7e9caa ¤   ¤   ¤   ¤   pui->Trust =·
aa3674 ¤   ¤   ¤   ¤   ¤   KMConvertFromPGPTrust (kPGPKeyTrust_Ultimate) + 1; ·······
d6efdf ¤   ¤   ¤   ¤   pui->Validity =·
1423a3 ¤   ¤   ¤   ¤   ¤   KMConvertFromPGPValidity (kPGPValidity_Complete) + 1;
cca3a6 ¤   ¤   ¤   }
a5af5a
ad03ac ¤   ¤   ¤   pui->Algorithm=rKey->algorithm;
dbaf5a
4ac5fd ············if(rKey->algorithm==kPGPPublicKeyAlgorithm_RSA)
f5f776 ¤   ¤   ¤   {
2b4dc9 ················sprintf(pui->szSize,"%i", rKey->keyBits);
87a3a6 ¤   ¤   ¤   }
fee93c ············else
8df776 ¤   ¤   ¤   {
f5545f ················sprintf(pui->szSize,"%i/%i", rKey->subKeyBits, rKey->keyBits);
13a3a6 ¤   ¤   ¤   }
a8af5a
71cdcb ¤   ¤   ¤   break;
6b0fe4 ¤   ¤   }
c4af5a
aa85c4 ¤   ¤   case kPGPRecipientUserKind_Group:
935b34 ¤   ¤   {
dd739c ¤   ¤   ¤   PGPGroupInfo groupInfo;
f22893 ¤   ¤   ¤   char StrRes[500];
80af5a
29b241 ¤   ¤   ¤   PGPGetGroupInfo(mGroupSet,
ca07da ¤   ¤   ¤   ¤   pru->groupInfo.groupID, &groupInfo);
03af5a
be82b2 ¤   ¤   ¤   strcpy(pui->UserId,groupInfo.name);
04af5a
d38629 ¤   ¤   ¤   if(pru->groupInfo.numMissingKeys==0)
77f776 ¤   ¤   ¤   {
0aaaa3 ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_NUMKEYS, StrRes, sizeof(StrRes));
c5af5a
4e4784 ¤   ¤   ¤   ¤   sprintf(pui->szSize,"%d keys",pru->groupInfo.numKeys);
e5a3a6 ¤   ¤   ¤   }
9ebb8c ¤   ¤   ¤   else
ccf776 ¤   ¤   ¤   {
89ecc4 ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_NUMOFNUMKEYS, StrRes, sizeof(StrRes));
f9af5a
857b46 ¤   ¤   ¤   ¤   sprintf(pui->szSize,"%d of %d keys",
8d8548 ¤   ¤   ¤   ¤   ¤   pru->groupInfo.numKeys-pru->groupInfo.numMissingKeys,
773c75 ¤   ¤   ¤   ¤   ¤   pru->groupInfo.numKeys);
13a3a6 ¤   ¤   ¤   }
a3af5a
d78c47 ¤   ¤   ¤   pui->Validity=pru->validity;
d1fe90 ¤   ¤   ¤   pui->Validity=KMConvertFromPGPValidity(pui->Validity);
cf87c3 ¤   ¤   ¤   pui->Trust=0;
308c80 ¤   ¤   ¤   pui->Algorithm=kPGPPublicKeyAlgorithm_Invalid;
e7cdcb ¤   ¤   ¤   break;
610fe4 ¤   ¤   }
56af5a
06b41f ¤   ¤   case kPGPRecipientUserKind_MissingRecipient:
9d5b34 ¤   ¤   {
a956ce ¤   ¤   ¤   PGPGetRecipientUserName(pru,pui->UserId);
dca0ba ¤   ¤   ¤   strcpy(pui->szSize,"No Match");
e3c6b4 ¤   ¤   ¤   pui->Validity=0;
6f87c3 ¤   ¤   ¤   pui->Trust=0;
be8c80 ¤   ¤   ¤   pui->Algorithm=kPGPPublicKeyAlgorithm_Invalid;
b4cdcb ¤   ¤   ¤   break;
8c0fe4 ¤   ¤   }
dfaf5a
de9ae3 ¤   ¤   default:
115b34 ¤   ¤   {
ff7bc3 ¤   ¤   ¤   free(pui);
--3ab4 00008e74ced40110024 Page 3 of RDkeyDB.c
e05f1f ¤   ¤   ¤   return FALSE;
690fe4 ¤   ¤   }
ca9371 ¤   }
39af5a
ef3fd6 ¤   pui->pru=pru;
96af5a
019f7c ¤   if(pui->Algorithm==kPGPPublicKeyAlgorithm_RSA)
80ac8c ¤   ¤   image=IDX_RSAUSERID;
ae508e ········
7810a4 ¤   if(pui->Algorithm==kPGPPublicKeyAlgorithm_DSA)
7b28be ¤   ¤   image=IDX_DSAUSERID;
49af5a
a4a8ca ¤   if(pru->kind==kPGPRecipientUserKind_MissingRecipient)
4a8492 ¤   ¤   image=IDX_INVALIDUSERID;
0daf5a
0f8412 ¤   if(pru->kind==kPGPRecipientUserKind_Group)
500a5d ¤   ¤   image=IDX_GROUP;
5caf5a
5e6b42 ¤   pui->icon=image;
e3a681 ¤   AddAnItem(hwndTable,pui);
b8af5a
7a24fe ¤   *UserLinkedList=AddLink(*UserLinkedList,pui);
b1af5a
058011 ····return TRUE;
50efe6 }
d9af5a
d90a6c // BuildTable
e8465d //
9002bb // This routine takes our PGPRecipientsList and inserts them
8f05d2 // into the correct listview.
62af5a
26c744 ¤   PGPError
bc752e BuildTable(
97c2ea ¤   HWND¤   ¤   ¤   ¤   ¤   ¤   hwndTable,
a2ae03 ¤   PGPGroupSetRef¤ ¤   ¤   ¤   mGroupSet,
5b8702 ¤   PUSERKEYINFO¤   ¤   ¤   ¤   *UserLinkedList,
782a34 ¤   PGPRecipientsList¤  ¤   ¤   *mRecipients,
f975bf ¤   PGPRecipientUserLocation ¤  location)
5dbb36 {
3f7d56 ¤   PGPError¤   ¤   ¤   err = kPGPError_NoErr;
ea576f ¤   PGPRecipientKey¤¤   *curKey;
e7b095 ¤   PGPRecipientUser¤   *curGroup;
b0a522 ¤   PGPRecipientUser¤   *curUser;
ed1b52 ¤   ¤
1950ec ¤   curKey = mRecipients->keys;
4eef78 ¤   while( IsntNull( curKey ) )
d0c7a1 ¤   {
3d791a ¤   ¤   curUser = curKey->users;
877ebc ¤   ¤   while( IsntNull( curUser ) )
225b34 ¤   ¤   {
28dee7 ¤   ¤   ¤   if( curUser->location == location )
94f776 ¤   ¤   ¤   {
86af26 ¤   ¤   ¤   ¤   AddToTable(hwndTable,mGroupSet,curUser,UserLinkedList);
f7a3a6 ¤   ¤   ¤   }
8387c7 ¤   ¤   ¤
e009b3 ¤   ¤   ¤   curUser = curUser->nextUser;
500fe4 ¤   ¤   }
6a67c5 ¤
56cf46 ¤   ¤   curKey = curKey->nextKey;
4a9371 ¤   }
d867c5 ¤
6eed6d ¤   curGroup = mRecipients->groups;
c564b9 ¤   while( IsntNull( curGroup ) )
6cc7a1 ¤   {
76fa2f ¤   ¤   pgpAssert( curGroup->kind == kPGPRecipientUserKind_Group );
971b52 ¤   ¤
e2f598 ¤   ¤   if( curGroup->location == location )
ef5b34 ¤   ¤   {
bfbb14 ¤   ¤   ¤   AddToTable(hwndTable,mGroupSet,curGroup,UserLinkedList);
f40fe4 ¤   ¤   }
0aaf5a
08908a ¤   ¤   curGroup = curGroup->nextUser;
--5405 001c988f10640110024 Page 4 of RDkeyDB.c
a19371 ¤   }
9967c5 ¤
13bffc ¤   curUser = mRecipients->missingRecipients;
6daf5a
b143d4 ¤   while( IsntNull( curUser ) )
69c7a1 ¤   {
aebe3b ¤   ¤   pgpAssert( curUser->kind ==
7c00cb ¤   ¤   ¤   ¤   kPGPRecipientUserKind_MissingRecipient );
30af5a
77c10e ¤   ¤   // Always in recipients list
eac6b7 ¤   ¤   if( curUser->location == location )
325b34 ¤   ¤   {
99e151 ¤   ¤   ¤   AddToTable(hwndTable,mGroupSet,curUser,UserLinkedList);
f60fe4 ¤   ¤   }
922b85 ¤   ¤   ¤   ¤
c60c5e ¤   ¤   curUser = curUser->nextUser;
2c9371 ¤   }
2bdeb7 ¤   return( err );
37efe6 }
7b67c5 ¤
cb493c void BuildTables(PRECGBL prg)
94bb36 {
008a76 ¤   if(prg->gUserLinkedList)
78c7a1 ¤   {
5fe8bc ¤   ¤   ListView_DeleteAllItems(prg->hwndRecipients);
9a7691 ¤   ¤   ListView_DeleteAllItems(prg->hwndUserIDs);
f2af5a
2fb231 ¤   ¤   FreeLinkedLists(prg->gUserLinkedList);
1b7d0b ¤   ¤   prg->gUserLinkedList=NULL;
099371 ¤   }
e2af5a
70a9d9 ¤   BuildTable(prg->hwndUserIDs,
703c73 ¤   ¤   prg->mGroupSet,
cfed21 ¤   ¤   &(prg->gUserLinkedList),
e01af5 ¤   ¤   &(prg->mRecipients),
1d1efe ¤   ¤   kPGPRecipientUserLocation_UserList);
b5af5a
d6367f ¤   SortEm(prg->hwndUserIDs);
95af5a
046d8b ¤   ListView_SetItemState(prg->hwndUserIDs,0,LVIS_FOCUSED,LVIS_FOCUSED);
c2af5a
33ec02 ¤   BuildTable(prg->hwndRecipients,
9d3c73 ¤   ¤   prg->mGroupSet,
95ed21 ¤   ¤   &(prg->gUserLinkedList),
e81af5 ¤   ¤   &(prg->mRecipients),
dec76c ¤   ¤   kPGPRecipientUserLocation_RecipientList);
e8af5a
67b760 ¤   SortEm(prg->hwndRecipients);
d0af5a
0748c6 ¤   ListView_SetItemState(prg->hwndRecipients,0,LVIS_FOCUSED,LVIS_FOCUSED);
36efe6 }
b8af5a
787e4d /*__Editor_settings____
caaf5a
d54126 ¤   Local Variables:
e27b17 ¤   tab-width: 4
4d0e6c ¤   End:
195f8c ¤   vi: ts=4 sw=4
209e9b ¤   vim: si
c9d062 _____________________*/
--bb88 0015222122040110025 Page 1 of RDkeyDB.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
f9a697 ¤   $Id: RDkeyDB.h,v 1.4.10.1 1998/11/12 03:24:25 heller Exp $
f9f7f7 ____________________________________________________________________________*/
6c8de5 #ifndef Included_RDKEYDB_h¤ /* [ */
e2ce64 #define Included_RDKEYDB_h
8eaf5a
a18515 #define ADDUSER_OK 0
e619a5 #define ADDUSER_NORECIPIENTSTOSEARCH 1
183783 #define ADDUSER_ADKSINCLUDED 2
71af5a
fe6355 // anything keysnotvalid and over gives warning message
cee6de #define ADDUSER_KEYSNOTVALID 4
e2c538 #define ADDUSER_KEYSNOTFOUND 8
b10f29 #define ADDUSER_MULTIPLEMATCH 16
242e3c #define ADDUSER_KEYSNOTCORPSIGNED 32
c7aee9 #define ADDUSER_ADKMISSING 64
bfaf5a
dcc744 ¤   PGPError
a1752e BuildTable(
58c2ea ¤   HWND¤   ¤   ¤   ¤   ¤   ¤   hwndTable,
35ae03 ¤   PGPGroupSetRef¤ ¤   ¤   ¤   mGroupSet,
368702 ¤   PUSERKEYINFO¤   ¤   ¤   ¤   *UserLinkedList,
6e2a34 ¤   PGPRecipientsList¤  ¤   ¤   *mRecipients,
c74d29 ¤   PGPRecipientUserLocation ¤  location);
e8af5a
0efb86 void BuildTables(PRECGBL prg);
5baf5a
f68c57 #endif /* ] Included_RDKEYDB_h */
eaaf5a
b3af5a
597e4d /*__Editor_settings____
d9af5a
714126 ¤   Local Variables:
3a7b17 ¤   tab-width: 4
790e6c ¤   End:
175f8c ¤   vi: ts=4 sw=4
589e9b ¤   vim: si
52d062 _____________________*/
--174e 000408ba9f040110026 Page 1 of RDlstmng.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8f5d73 ¤   $Id: RDlstmng.c,v 1.2.10.1 1998/11/12 03:24:26 heller Exp $
e5f7f7 ____________________________________________________________________________*/
22af5a
d74067 #include "RDprecmp.h"
62af5a
89af5a
dbc540 #define EDGEMARGIN 5
47af5a
b99510 #if LISTBOX
2aaf5a
53cd02 void MoveList(LISTSTRUCT *ls,RECT *rc)
d8bb36 {
78a6f6 ¤   int listwidth;
ea6b72 ¤   int xpos;
c5f7fd ¤   float textfloat,ratio;
cb2715 ¤   int index;
4daf5a
e826bd ¤   listwidth=rc->right-rc->left;
f7af5a
abe612 ¤   MoveWindow(ls->hwndlist,
b1388a ¤   ¤   rc->left,rc->top+20,
cef69a ¤   ¤   rc->right-rc->left,rc->bottom-rc->top-15,
11be2f ¤   ¤   TRUE);
1baf5a
65cf38 ¤   xpos=rc->left;
4eaf5a
b27572 ····for(index=0;index<NUMCOLUMNS;index++)
383b37 ····{
702136 ¤   ¤   ratio=ls->colratio[index];
62af5a
e9885a ¤   ¤   textfloat=(float)listwidth;
00e29a ¤   ¤   ls->colwidth[index]=(int)(ratio*textfloat);
b41b52 ¤   ¤
f36d9e ¤   ¤   MoveWindow(ls->hwndtext[index],
3123b6 ¤   ¤   ¤   xpos,rc->top,
ae58b7 ¤   ¤   ¤   ls->colwidth[index],20,
aa5c8c ¤   ¤   ¤   TRUE);
da67c5 ¤
77f757 ¤   ¤   xpos=xpos+ls->colwidth[index];
899371 ¤   }
cdefe6 }
73af5a
33bd1b BOOL InitList(HWND hwnd,
0c0e64 ¤   ¤   ¤   ··DWORD idc,
d7e237 ¤   ¤   ¤   ··LISTSTRUCT *ls,
304a70 ¤   ¤   ¤   ··char **ColText,
71a8e4 ¤   ¤   ¤   ··float *ColRatio)
06bb36 {
352715 ¤   int index;
bbb86c ¤   HFONT hFont;
dc1849 ¤   DWORD staticFlags;
b5bffb ¤   PRECGBL prg;
80af5a
a36c08 ¤   prg=(PRECGBL)GetWindowLong(hwnd,GWL_USERDATA);
9baf5a
2e4240 ¤   hFont=prg->ds.hFont;
33af5a
b2e6a7 ¤   ls->hwnd=hwnd;
cbf9a6 ¤   ls->colratio=ColRatio;
6daf5a
da57bc ····ls->hwndlist = CreateWindow ("listbox", NULL,
fd51a5 ······················WS_CHILD | WS_VISIBLE | WS_VSCROLL |·
1dab98 ¤   ¤   ¤   ¤   ¤   ··WS_BORDER| LBS_OWNERDRAWFIXED |
35772f ¤   ¤   ¤   ¤   ¤   ··LBS_SORT | LBS_EXTENDEDSEL|WS_TABSTOP,
0216d9 ······················0,0,0,0,
4055b6 ······················hwnd, (HMENU)idc,
--2d47 000e44ba96f40110026 Page 2 of RDlstmng.c
ec65a2 ······················(HINSTANCE) g_hinst,
eaeac6 ······················NULL) ;
dcaf5a
2dcfca ¤   ShowWindow(ls->hwndlist,SW_SHOW);
bdaf5a
eb7572 ····for(index=0;index<NUMCOLUMNS;index++)
d63b37 ····{
dddb7b ¤   ¤   staticFlags=WS_CHILD | WS_VISIBLE;
5eaf5a
e5598b ¤   ¤   if(index!=0)
440157 ¤   ¤   ¤   staticFlags|=SS_CENTER;
5daf5a
115a8d ¤   ¤   ls->hwndtext[index]=CreateWindow ("STATIC",ColText[index],
df1614 ····················staticFlags,
b5a6ed ····················0,0,0,0,
2161d6 ····················hwnd, (HMENU)(2000+index),
e55f68 ····················(HINSTANCE) g_hinst,
3a7d23 ····················NULL) ;
73af5a
5cdfa5 ¤   ¤   SendMessage(ls->hwndtext[index],WM_SETFONT,
7fe6a7 ¤   ¤   ¤   ¤   ···(WPARAM)hFont,(LPARAM)MAKELPARAM(TRUE,0));
a19371 ¤   }
aaaf5a
a1c2e7 ¤   return TRUE;
8eefe6 }
faaf5a
e84a88 int AddAnItem(HWND hwndList,PUSERKEYINFO pui)
dcbb36 {
9e9547 ¤   return SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)pui);
c6efe6 }
aeaf5a
e8c432 int SetListCursor(HWND hwndList,int index)
b7bb36 {
642b89 ¤   return SendMessage(hwndList,LB_SETCURSEL,(WPARAM)index,
0181fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)0);
59efe6 }
a2af5a
597ef4 #else // Listview·
97af5a
0f9d43 int AddListViewItem(HWND hWndLV,int iImage,LPSTR szText,LPARAM lParam)
c0bb36 {
9a29aa ····LV_ITEM ·lvItem;
88af5a
fa18eb ····lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT ;
2caf5a
e8e8f4 ····lvItem.lParam ·······= lParam;
6212ab ····lvItem.iImage ·······= iImage;
2cac06 ¤   lvItem.pszText ······= szText;
456eca ····lvItem.iSubItem ·····= 0;
410c9b ····lvItem.iItem ········= ListView_GetItemCount( hWndLV);
df67c5 ¤
c3ca0f ····return ListView_InsertItem ( hWndLV, &lvItem );
d9efe6 }
1faf5a
0faf5a
de83b0 BOOL AddListViewColumn(HWND hwnd,char **ColText,int *ColWidth,int num)
d7bb36 {
2bf7c3 ····LV_COLUMN lvc;
14cf7d ····RECT rect;
7b18ca ····BOOL ReturnValue = TRUE;
be7312 ····int scrollwidth = GetSystemMetrics(SM_CXVSCROLL);
96c0b0 ····int index;
6baf5a
7d3260 ····GetClientRect(hwnd, &rect);
84af5a
9776c9 ····for(index=0;index<num;index++)
a03b37 ····{
9fdf15 ····lvc.mask ·······= LVCF_WIDTH | LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT;·
ceda84 ····lvc.pszText ····= ColText[index];
e52524 ····lvc.cx ·········= ColWidth[index];
efb151 ····lvc.iSubItem ···= index;·
e49986 ····if(index==0)
--071b 000afea63f940110026 Page 3 of RDlstmng.c
627fc2 ········lvc.fmt ····= LVCFMT_LEFT;
21842c ····else
c0aef6 ········lvc.fmt ····= LVCFMT_CENTER;
dfaf5a
9ef175 ····ListView_InsertColumn(hwnd, index, &lvc);
a46fe7 ····}
91af5a
bddc7e ····return ReturnValue;
a1efe6 }
2aaf5a
1acd02 void MoveList(LISTSTRUCT *ls,RECT *rc)
0dbb36 {
23e612 ¤   MoveWindow(ls->hwndlist,
bb74e9 ¤   ¤   rc->left,rc->top,
af679f ¤   ¤   rc->right-rc->left,rc->bottom-rc->top,
66be2f ¤   ¤   TRUE);
d0efe6 }
25af5a
4bbd1b BOOL InitList(HWND hwnd,
380e64 ¤   ¤   ¤   ··DWORD idc,
72e237 ¤   ¤   ¤   ··LISTSTRUCT *ls,
2e4a70 ¤   ¤   ¤   ··char **ColText,
92a8e4 ¤   ¤   ¤   ··float *ColRatio)
3cbb36 {
e15bda ¤   RECT rc;
512715 ¤   int index;
42a6f6 ¤   int listwidth;
df6b72 ¤   int xpos;
f5c7e6 ¤   float ratio;
cc9c36 ¤   float textfloat;
05af5a
1ae6a7 ¤   ls->hwnd=hwnd;
b5af5a
14ba51 ····GetClientRect(hwnd,&rc);
0baf5a
6c5685 ¤   listwidth=rc.right-rc.left-EDGEMARGIN*2;
a8af5a
14bd82 ¤   ls->hwndlist = CreateWindowEx (
e4b7f1 ¤   ¤   ¤   ¤   ¤   WS_EX_CLIENTEDGE,
45f4e8 ¤   ¤   ¤   ¤   ¤   WC_LISTVIEW,
1106e6 ¤   ¤   ¤   ¤   ¤   "",
472e09 ¤   ¤   ¤   ¤   ¤   WS_VISIBLE|WS_CHILD|LVS_REPORT|
c06d88 ¤   ¤   ¤   ¤   ¤   LVS_OWNERDRAWFIXED|WS_TABSTOP,
30e234 ····················rc.left+EDGEMARGIN,rc.top+EDGEMARGIN,
d51450 ¤   ¤   ¤   ¤   ¤   listwidth,rc.bottom-rc.top-EDGEMARGIN*2,
614494 ····················hwnd, (HMENU)idc,
3b5f68 ····················(HINSTANCE) g_hinst,
d07d23 ····················NULL) ;
2daf5a
40cfca ¤   ShowWindow(ls->hwndlist,SW_SHOW);
a7af5a
5176cc ¤   listwidth=listwidth; // For icon
8c35c2 ¤   xpos=rc.left+10;
90af5a
227572 ····for(index=0;index<NUMCOLUMNS;index++)
b33b37 ····{
cbe608 ¤   ¤   ratio=ColRatio[index];
55af5a
64c845 ¤   ¤   if(ratio>1.0)
2068c0 ¤   ¤   ¤   ls->colwidth[index]=(int)ratio;
e30e1d ¤   ¤   else
515b34 ¤   ¤   {
6b4d0f ¤   ¤   ¤   textfloat=(float)listwidth;
ddb736 ¤   ¤   ¤   ls->colwidth[index]=(int)(ratio*textfloat);
da0fe4 ¤   ¤   }
b69371 ¤   }
50af5a
92b836 ¤   AddListViewColumn(ls->hwndlist,ColText,
22a6f9 ¤   ¤   ¤   ls->colwidth,NUMCOLUMNS);
a6af5a
adc2e7 ¤   return TRUE;
afefe6 }
--0f6e 000f18f02cc40110026 Page 4 of RDlstmng.c
e0af5a
fe4a88 int AddAnItem(HWND hwndList,PUSERKEYINFO pui)
bebb36 {
fb2715 ¤   int index;
58af5a
249c5a ¤   index=AddListViewItem(hwndList,0,pui->UserId,(LPARAM)pui);
7faf5a
4724a6 ¤   return index;
afefe6 }
82af5a
85c432 int SetListCursor(HWND hwndList,int index)
6cbb36 {
016a4a ¤   ListView_EnsureVisible( hwndList,index,FALSE);
aeaf5a
66c2e7 ¤   return TRUE;
3fefe6 }
adaf5a
134bbb #endif // LISTBOX
31af5a
a9af5a
bb339e BOOL ListBx_GetItem(HWND hwnd,LV_ITEM *pitem)
1bbb36 {
2a9510 #if LISTBOX
1dc6af ¤   PUSERKEYINFO pui;
50af5a
a69e50 ¤   pui=(PUSERKEYINFO)SendMessage(hwnd,LB_GETITEMDATA,(WPARAM)pitem->iItem,0);
32af5a
8da417 ····if(pui==0)
351355 ····¤   return FALSE;
05e7c4 ····¤
3fdec7 ¤   if(pitem->mask&LVIF_PARAM)
0f1e2c ¤   ¤   pitem->lParam=(LPARAM)pui;
4867c5 ¤
2846c4 ¤   if(pitem->mask&LVIF_TEXT)
1c1a48 ¤   ¤   strcpy(pitem->pszText,pui->UserId);
a2af5a
64e226 ¤   if(pitem->mask&LVIF_STATE)
aa1b7f ¤   ¤   pitem->state=(UINT)SendMessage(hwnd,
8d3b91 ¤   ¤   ¤   LB_GETSEL,(WPARAM)pitem->iItem,(LPARAM)0);
a7af5a
fac2e7 ¤   return TRUE;
86db21 #else
eb6f10 ¤   return ListView_GetItem(hwnd,pitem);
4f7454 #endif
01efe6 }
4baf5a
6839e6 UINT ListBx_GetSelectedCount(HWND hwnd)
89bb36 {
489510 #if LISTBOX
8d4301 ¤   return (UINT)SendMessage(hwnd,LB_GETSELCOUNT,(WPARAM)0,(LPARAM)0);
d3db21 #else
f0cc82 ¤   return ListView_GetSelectedCount(hwnd);
c97454 #endif
68efe6 }
8faf5a
7bb634 UINT ListBx_GetItemCount(HWND hwnd)
33bb36 {
c79510 #if LISTBOX
993cb2 ¤   return (UINT)SendMessage(hwnd,LB_GETCOUNT,(WPARAM)0,(LPARAM)0);
66db21 #else
155460 ¤   return ListView_GetItemCount(hwnd);
857454 #endif
80efe6 }
86af5a
e3d220 UINT ListBx_GetItemState(HWND hwnd,int i,UINT mask)
25bb36 {
999510 #if LISTBOX
b6ba5c ¤   return (UINT)SendMessage(hwnd,LB_GETSEL,(WPARAM)i,(LPARAM)0);
65db21 #else
a21719 ¤   return ListView_GetItemState(hwnd,i,mask);
3e7454 #endif
f1efe6 }
--2d46 0012af0010040110026 Page 5 of RDlstmng.c
e0af5a
5af07b int ListBx_InsertItem(HWND hwnd,LV_ITEM *pitem)
1dbb36 {
989510 #if LISTBOX
edc6af ¤   PUSERKEYINFO pui;
4973cc ¤   pui=(PUSERKEYINFO)pitem->lParam;
24af5a
56e684 ¤   return (int)SendMessage(hwnd,LB_ADDSTRING,(WPARAM)0,(LPARAM)pui);
d2db21 #else
d453c9 ¤   return ListView_InsertItem(hwnd,pitem);
077454 #endif
20efe6 }
58af5a
1e06e6 BOOL ListBx_DeleteItem(HWND hwnd,int iItem)
72bb36 {
de9510 #if LISTBOX
5c47b4 ¤   return (BOOL)SendMessage(hwnd,LB_DELETESTRING,(WPARAM)iItem,(LPARAM)0);
67db21 #else
0a12c1 ¤   return ListView_DeleteItem(hwnd,iItem);
257454 #endif
71efe6 }
dfaf5a
f1af5a
0cd723 BOOL ListBx_DeleteAllItems(HWND hwnd)
cbbb36 {
409510 #if LISTBOX
b9a55e ¤   return (BOOL)SendMessage(hwnd,LB_RESETCONTENT,(WPARAM)0,(LPARAM)0);
1bdb21 #else
36fecf ¤   return ListView_DeleteAllItems(hwnd);
717454 #endif
62efe6 }
06af5a
36af5a
e97e4d /*__Editor_settings____
c7af5a
124126 ¤   Local Variables:
ef7b17 ¤   tab-width: 4
aa0e6c ¤   End:
835f8c ¤   vi: ts=4 sw=4
199e9b ¤   vim: si
2ad062 _____________________*/
--5a5e 00176de4e0840110027 Page 1 of RDlstmng.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
0eb977 ¤   $Id: RDlstmng.h,v 1.1.12.1 1998/11/12 03:24:27 heller Exp $
bdf7f7 ____________________________________________________________________________*/
1e06b0 #ifndef Included_RDLSTMNG_h¤/* [ */
bf23a6 #define Included_RDLSTMNG_h
19af5a
09af5a
a4b291 #include "RDdraw.h"
deaf5a
2c72c3 #define LISTBOX 0
51af5a
1bbd1b BOOL InitList(HWND hwnd,
c20e64 ¤   ¤   ¤   ··DWORD idc,
56e237 ¤   ¤   ¤   ··LISTSTRUCT *ls,
4b4a70 ¤   ¤   ¤   ··char **ColText,
c3a1a2 ¤   ¤   ¤   ··float *ColRatio);
171275 int SetListCursor(HWND hwndList,int index);
7b082a int AddAnItem(HWND hwndList,PUSERKEYINFO pui);
d423ff void MoveList(LISTSTRUCT *ls,RECT *rc);
1daf5a
df7de4 BOOL ListBx_GetItem(HWND hwnd,LV_ITEM *pitem);
a88221 UINT ListBx_GetSelectedCount(HWND hwnd);
b87731 UINT ListBx_GetItemCount(HWND hwnd);
9021f0 UINT ListBx_GetItemState(HWND hwnd,int i,UINT mask);
11cd84 int ListBx_InsertItem(HWND hwnd,LV_ITEM *pitem);
5a821e BOOL ListBx_DeleteItem(HWND hwnd,int iItem);
5e136e BOOL ListBx_DeleteAllItems(HWND hwnd);
44af5a
53af5a
53e03f #endif /* ] Included_RDLSTMNG_h */
c5af5a
69af5a
167e4d /*__Editor_settings____
92af5a
9c4126 ¤   Local Variables:
1c7b17 ¤   tab-width: 4
0f0e6c ¤   End:
425f8c ¤   vi: ts=4 sw=4
0e9e9b ¤   vim: si
02d062 _____________________*/
76af5a
--898f 0003931c54240110028 Page 1 of RDlstsrt.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
a1caa9 ¤   $Id: RDlstsrt.c,v 1.3.10.1 1998/11/12 03:24:27 heller Exp $
15f7f7 ____________________________________________________________________________*/
eeaf5a
1a4067 #include "RDprecmp.h"
69af5a
a1af5a
9b38e5 /*
bcef0f ·* ListSort.c ·List View sorting routine
1e775e ·*
468f8e ·* Apparently the sorting algorithm used in PGPlib is somehow different than
7befbf ·* Microsoft employs in their standard listview control. This makes things·
99f2c5 ·* sometimes confusing, since PGPkeys follows the PGPlib convention. Albeit
a8d931 ·* bucking PC GUI standards SortEm changes the listview sort to comply with
cea114 ·* PGPlib and PGPkeys.
e3775e ·*
cbbd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
37599a ·* All rights reserved.
ae495d ·*/
b4af5a
fbaf5a
52dfc3 int CALLBACK ListViewCompareProc(LPARAM lParam1,
f7e7fb ·································LPARAM lParam2,LPARAM lParamSort)
95bb36 {
9db8cd ····PUSERKEYINFO pui1,pui2;
b02820 ····int result;
a2da46 ····int *SortSub;
7a2d7a ····BOOL *SortAscending;
f2b26a ····HWND hwnd;
52bffb ¤   PRECGBL prg;
94af5a
dcc437 ····hwnd=(HWND)lParamSort;
94af5a
950b20 ¤   prg=(PRECGBL)GetWindowLong(GetParent(hwnd),GWL_USERDATA);
f8af5a
4765eb ····if(hwnd==prg->hwndRecipients)
5f3b37 ····{
7ec5be ········SortSub=&(prg->RSortSub);
590dfd ········SortAscending=&(prg->RSortAscending);
c76fe7 ····}
3b842c ····else
263b37 ····{
bb6558 ········SortSub=&(prg->USortSub);
577dd0 ········SortAscending=&(prg->USortAscending);
066fe7 ····}
64af5a
f6cfdb ····pui1=(PUSERKEYINFO)lParam1;
582c32 ····pui2=(PUSERKEYINFO)lParam2;
c9af5a
4682ee ····switch(*SortSub)
3b3b37 ····{
aaa50d ········case HEADUSERID:
032b60 ········{
e80ba5 ············if(*SortAscending)
1f09ce ················result=PGPCompareUserIDStrings(pui1->UserId,pui2->UserId);
6fe93c ············else
b882ad ················result=PGPCompareUserIDStrings(pui2->UserId,pui1->UserId);
df8632 ············break;
3c7fb0 ········}
90cb92 ········case HEADVALIDITY:
6f2b60 ········{
8d0ba5 ············if(*SortAscending)
ea249a ················result=(pui2->Validity)-(pui1->Validity);
62e93c ············else
dae0e9 ················result=(pui1->Validity)-(pui2->Validity);
0f8632 ············break;
397fb0 ········}
--6ae3 001af4f70c040110028 Page 2 of RDlstsrt.c
1c1b17 ¤   ¤   /*
f21512 ········case HEADTRUST:
c12b60 ········{
dd0ba5 ············if(*SortAscending)
212375 ················result=(pui2->Trust)-(pui1->Trust);
3be93c ············else
57d14b ················result=(pui1->Trust)-(pui2->Trust);
7b8632 ············break;
14bd84 ········}*/
3d7b41 ········case HEADSIZE:
b02b60 ········{
f20ba5 ············if(*SortAscending)
01b8af ················result=(atoi(pui2->szSize))-(atoi(pui1->szSize));
71e93c ············else
85443f ················result=(atoi(pui1->szSize))-(atoi(pui2->szSize));
378632 ············break;
027fb0 ········}
3baf5a
c36fe7 ····}
52af5a
9914bd ····return result;
0fefe6 }
daaf5a
f67781 void SortEm(HWND hwndLView)
79bb36 {
f4d4aa ····ListView_SortItems(hwndLView,ListViewCompareProc,(LPARAM)hwndLView);
aeefe6 }
a9af5a
95af5a
3b7e4d /*__Editor_settings____
cdaf5a
a94126 ¤   Local Variables:
ed7b17 ¤   tab-width: 4
260e6c ¤   End:
cf5f8c ¤   vi: ts=4 sw=4
9b9e9b ¤   vim: si
45d062 _____________________*/
afaf5a
--a50a 0014142d65b40110029 Page 1 of RDlstsrt.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
92a7e9 ¤   $Id: RDlstsrt.h,v 1.2.10.1 1998/11/12 03:24:28 heller Exp $
8ff7f7 ____________________________________________________________________________*/
cac253 #ifndef Included_RDLSTSRT_h¤/* [ */
b77da8 #define Included_RDLSTSRT_h
51af5a
0038e5 /*
541db2 ·* ListSort.h ·List View sorting routine
6e775e ·*
ba8f8e ·* Apparently the sorting algorithm used in PGPlib is somehow different than
67efbf ·* Microsoft employs in their standard listview control. This makes things·
64f2c5 ·* sometimes confusing, since PGPkeys follows the PGPlib convention. Albeit
3ad931 ·* bucking PC GUI standards SortEm changes the listview sort to comply with
e2a114 ·* PGPlib and PGPkeys.
da775e ·*
83bd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
76599a ·* All rights reserved.
39495d ·*/
a5af5a
d295d6 void SortEm(HWND hwndLView);
1eaf5a
c5dfc3 int CALLBACK ListViewCompareProc(LPARAM lParam1,
f6499b ·································LPARAM lParam2,LPARAM lParamSort);
41f18d #define HEADUSERID 0
aa53ab #define HEADVALIDITY 1
223f93 //#define HEADTRUST 2
74cd63 #define HEADSIZE 2
53af5a
abaf5a
4cb9c3 #endif /* ] Included_RDLSTSRT_h */
22af5a
e0af5a
f67e4d /*__Editor_settings____
a2af5a
704126 ¤   Local Variables:
fe7b17 ¤   tab-width: 4
e20e6c ¤   End:
735f8c ¤   vi: ts=4 sw=4
339e9b ¤   vim: si
41d062 _____________________*/
--be80 0002691a8774011002a Page 1 of RDlstsub.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
664ce5 ¤   $Id: RDlstsub.c,v 1.7.10.1 1998/11/12 03:24:29 heller Exp $
42f7f7 ____________________________________________________________________________*/
64af5a
894067 #include "RDprecmp.h"
61af5a
9faf5a
f638e5 /*
14c510 ·* ListSub.c ·List View helper routines
50775e ·*
1ec7c1 ·* These routines handle the listview subclass operations and also
b4837e ·* do some of the needed operations on the linked list of keys.
c4775e ·*
37bd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
ee599a ·* All rights reserved.
84495d ·*/
d1af5a
bdaf5a
07012b LRESULT WINAPI MyListviewWndProc(HWND hwnd, UINT msg,·
e1ee0e ·································WPARAM wParam, LPARAM lParam)
a3bb36 {
cf6627 ····switch(msg)
ac3b37 ····{
9dc025 ········case WM_LBUTTONDBLCLK:
462b60 ········{
08255c ············HWND hwndUserIds =·
78e429 ················GetDlgItem(GetParent(hwnd), IDC_USER_ID_LIST);
e6286a ············HWND hwndRecpts =·
275ad3 ················GetDlgItem(GetParent(hwnd), IDC_RECIPIENT_LIST);
f8d567 ········································································
4f03d2 ············MoveListViewItems(hwndRecpts, hwndUserIds,
75d4d5 ······························hwnd == hwndRecpts);·
b28632 ············break;
977fb0 ········}
2baf5a
6ec43a ········case WM_CONTEXTMENU:·
102b60 ········{
23ddda ¤   ¤   ¤   POINT pnt;
4ba211 ¤   ¤   ¤   HMENU hMenu=NULL;
eee055 ¤   ¤   ¤   HMENU hSubMenu=NULL;
31af5a
e414ec ¤   ¤   ¤   pnt.x=LOWORD(lParam);
b07c84 ¤   ¤   ¤   pnt.y=HIWORD(lParam);
7367c5 ¤
c00958 ¤   ¤   ¤   hMenu = LoadMenu(g_hinst, MAKEINTRESOURCE(IDR_MENU1));
3d17a6 ¤   ¤   ¤   hSubMenu = GetSubMenu(hMenu,0);
b4af5a
fc4fa8 ¤   ¤   ¤   TrackPopupMenu(hSubMenu,TPM_RIGHTBUTTON,pnt.x,pnt.y,0,hwnd,NULL);
cb1627 ¤   ¤   ¤   DestroyMenu(hMenu);
688144 ¤   ¤   ¤   return 0;
9f7fb0 ········}
62af5a
ca548d ¤   ¤   case WM_SETFOCUS:
e1d94a ¤   ¤   case WM_KILLFOCUS:
a95b34 ¤   ¤   {
36d7ba ¤   ¤   ¤   InvalidateRect(hwnd,NULL,TRUE);
d7cdcb ¤   ¤   ¤   break;
470fe4 ¤   ¤   }
fdaf5a
13aff6 ········case WM_COMMAND:
552b60 ········{
2314e1 ············switch(wParam)
092cc2 ············{
058890 ¤   ¤   ¤   ¤   case IDM_WHATSTHIS:
b072c3 ¤   ¤   ¤   ¤   {
5fc0aa ¤   ¤   ¤   ¤   ¤   PRECGBL prg;
26fa63 ····················char szHelpFile[MAX_PATH];
--ff6d 000b8dc83394011002a Page 2 of RDlstsub.c
e0af5a
4a4192 ····················GetHelpDir(szHelpFile);
9faf5a
d6cde6 ¤   ¤   ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(GetParent(hwnd),GWL_USERDATA);
45af5a
c22a75 ¤   ¤   ¤   ¤   ¤   if(hwnd == prg->hwndRecipients)
5adae4 ¤   ¤   ¤   ¤   ¤   ¤   WinHelp(hwnd, szHelpFile,
6020e9 ¤   ¤   ¤   ¤   ¤   ¤   HELP_CONTEXTPOPUP, IDH_IDC_RECIPIENT_LIST);
531216 ¤   ¤   ¤   ¤   ¤   if(hwnd == prg->hwndUserIDs)
c0dae4 ¤   ¤   ¤   ¤   ¤   ¤   WinHelp(hwnd, szHelpFile,
8692fb ¤   ¤   ¤   ¤   ¤   ¤   HELP_CONTEXTPOPUP, IDH_IDC_USER_ID_LIST);
4ccfa5 ¤   ¤   ¤   ¤   ¤   return 0;
f62613 ¤   ¤   ¤   ¤   }
cfaf5a
cbd9a5 ¤   ¤   ¤   ¤   case IDM_LOOKUP:
8e72c3 ¤   ¤   ¤   ¤   {
16c0aa ¤   ¤   ¤   ¤   ¤   PRECGBL prg;
c605d2 ¤   ¤   ¤   ¤   ¤   HWND hdlg;
1d4333 ¤   ¤   ¤   ¤   ¤   PGPError err;
b5af5a
ffa07f ¤   ¤   ¤   ¤   ¤   hdlg=GetParent(hwnd);
57cde6 ¤   ¤   ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(GetParent(hwnd),GWL_USERDATA);
4eaf5a
3d603a ¤   ¤   ¤   ¤   ¤   err=LookUpUnknownKeys(hdlg,prg);
8414c3 ¤   ¤   ¤   ¤   ¤   break;
6a2613 ¤   ¤   ¤   ¤   }
29a3a6 ¤   ¤   ¤   }
27cdcb ¤   ¤   ¤   break;
ed0fe4 ¤   ¤   }
64af5a
5900cb ¤   ¤   case WM_KEYDOWN:
f02b60 ········{
358a47 ············int nVirtKey = (int) wParam; ···// virtual-key code·
15255c ············HWND hwndUserIds =·
ece429 ················GetDlgItem(GetParent(hwnd), IDC_USER_ID_LIST);
9a286a ············HWND hwndRecpts =·
0f5ad3 ················GetDlgItem(GetParent(hwnd), IDC_RECIPIENT_LIST);
9aaf5a
760e1c ············if( ((nVirtKey == VK_RIGHT)||(nVirtKey == VK_LEFT)||
b66f28 ················(nVirtKey == VK_DELETE)) && (hwnd == hwndRecpts))
df2cc2 ············{
082261 ················MoveListViewItems(hwndRecpts, hwndUserIds,TRUE);
26b228 ················break;
f47812 ············}
a0e65e ············else if( ((nVirtKey == VK_RIGHT)||(nVirtKey == VK_LEFT)||
a8c17b ················(nVirtKey == VK_DELETE)) && (hwnd == hwndUserIds))
5c2cc2 ············{
75e9db ················MoveListViewItems(hwndRecpts, hwndUserIds,FALSE);
e5b228 ················break;
a77812 ············}
b48632 ············break;
cc7fb0 ········}
a1af5a
bc6fe7 ····}
1aaf5a
462207 ····// ·Pass all non-custom messages to old window proc
a790a1 ····return CallWindowProc((FARPROC)origListBoxProc, hwnd,·
857c1e ···························msg, wParam, lParam ) ;
36efe6 }
a9af5a
0fecf6 int LengthOfList(PUSERKEYINFO ListHead)
19bb36 {
b44d50 ····PUSERKEYINFO pui;
0390bd ····int length;
04af5a
ae52b7 ····length=0;
5302c4 ····pui=ListHead;
6caf5a
65c1eb ····while(pui!=0)
ef3b37 ····{
fb1679 ········pui=pui->next;
b861f1 ········length++;
--21dc 001827d37f14011002a Page 3 of RDlstsub.c
9f6fe7 ····}
4cac20 ····return length;
e0efe6 }
a2af5a
33af5a
599b33 void FreeLinkedLists(PUSERKEYINFO ListHead)
b6bb36 {
ecd037 ····PUSERKEYINFO pui,oldpui;
66af5a
5c02c4 ····pui=ListHead;
57af5a
d8c1eb ····while(pui!=0)
4e3b37 ····{
ef87b9 ········oldpui=pui;
251679 ········pui=pui->next;
fcaf5a
21847f ········free(oldpui);
b76fe7 ····}
e2efe6 }
8caf5a
65af5a
1a7e4d /*__Editor_settings____
9baf5a
7b4126 ¤   Local Variables:
1a7b17 ¤   tab-width: 4
330e6c ¤   End:
085f8c ¤   vi: ts=4 sw=4
9a9e9b ¤   vim: si
82d062 _____________________*/
--286f 001495fe4e74011002b Page 1 of RDlstsub.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d1b8f8 ¤   $Id: RDlstsub.h,v 1.2.10.1 1998/11/12 03:24:29 heller Exp $
d9f7f7 ____________________________________________________________________________*/
cec805 #ifndef Included_RDLSTSUB_h¤/* [ */
a3c54f #define Included_RDLSTSUB_h
eaaf5a
0c38e5 /*
2437ad ·* ListSub.h ·List View helper routines
67775e ·*
a2c7c1 ·* These routines handle the listview subclass operations and also
fb837e ·* do some of the needed operations on the linked list of keys.
49775e ·*
c2bd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
3a599a ·* All rights reserved.
91495d ·*/
43af5a
9b012b LRESULT WINAPI MyListviewWndProc(HWND hwnd, UINT msg,·
25e9b0 ·································WPARAM wParam, LPARAM lParam);
efaf5a
5c03a3 void FreeLinkedLists(PUSERKEYINFO ListHead);
629275 int LengthOfList(PUSERKEYINFO ListHead);
cbaf5a
4dc8c9 #endif /* ] Included_RDLSTSUB_h */
dbaf5a
0caf5a
767e4d /*__Editor_settings____
95af5a
c64126 ¤   Local Variables:
5f7b17 ¤   tab-width: 4
7a0e6c ¤   End:
a05f8c ¤   vi: ts=4 sw=4
da9e9b ¤   vim: si
36d062 _____________________*/
49af5a
--e23c 0010b59db3d4011002c Page 1 of RDmain.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c6597a ¤   $Id: RDmain.c,v 1.11.2.1.2.1 1998/11/12 03:24:30 heller Exp $
8bf7f7 ____________________________________________________________________________*/
ddaf5a
084067 #include "RDprecmp.h"
01af5a
ae54b4 // newPGPRecipientDialog
8a465d //
a73250 // Set up our custom dialog class and hook routines
5daf5a
c984df UINT newPGPRecipientDialog(PRECGBL prg)
cbbb36 {
565abb ¤   BOOL ReturnValue = FALSE;
43d9e0 ¤   WNDCLASS wndclass;
a2af5a
74602b ¤   g_hinst=prg->g_hInst;
2eaf5a
f5d08d ¤   memset(&wndclass,0x00,sizeof(WNDCLASS));
32af5a
63c80a ····wndclass.style = CS_HREDRAW | CS_VREDRAW; ····················
362469 ····wndclass.lpfnWndProc = (WNDPROC)DefDlgProc;·
b145f6 ····wndclass.cbClsExtra = 0; ·············
6800e3 ····wndclass.cbWndExtra = DLGWINDOWEXTRA; ·············
b86c53 ····wndclass.hInstance = g_hinst; ······
baa8c9 ····wndclass.hIcon = LoadIcon (g_hinst, MAKEINTRESOURCE(IDI_DLGICON));
865135 ····wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
6b5996 ····wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);·
d3f082 ¤   wndclass.lpszMenuName = NULL;
974d83 ¤   wndclass.lpszClassName = "PGPrecipClass";
ccaf5a
b37405 ¤   RegisterClass (&wndclass);
9aaf5a
4dd765 ¤   ReturnValue = DialogBoxParam(g_hinst,·
f4ba16 ¤   ¤   MAKEINTRESOURCE( IDD_RECIPIENTDLG ),
5316cf ¤   ¤   prg->mHwndParent,·
e08494 ¤   ¤   (DLGPROC) RecipientDlgProc,·
66e3d5 ¤   ¤   (LPARAM) prg);
68d83c ·
98152e ····FreeLinkedLists(prg->gUserLinkedList);
6baf5a
fcdc7e ····return ReturnValue;
aaefe6 }
2eaf5a
0aaf5a
d47e4d /*__Editor_settings____
25af5a
a04126 ¤   Local Variables:
ad7b17 ¤   tab-width: 4
c70e6c ¤   End:
be5f8c ¤   vi: ts=4 sw=4
f89e9b ¤   vim: si
0bd062 _____________________*/
--86cb 0004e86d7f84011002d Page 1 of RDmove.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7a8490 ¤   $Id: RDmove.c,v 1.7.10.1 1998/11/12 03:24:31 heller Exp $
ddf7f7 ____________________________________________________________________________*/
78af5a
594067 #include "RDprecmp.h"
7daf5a
e43f7e // MoveMarkedItems
82465d //
8c97da // Use this routine after you have marked all the items you wish to
577ad0 // move with the PUIF_MOVEME flag
19af5a
8c062f int MoveMarkedItems(HWND src, HWND dest,
c69900 ¤   ¤   ¤   ¤   ¤   PGPRecipientUserLocation destinationList)
51bb36 {
b24512 ····LV_ITEM lvi;
6ea291 ····int iCount, i;
014d50 ····PUSERKEYINFO pui;
84af5a
968f4a ····iCount = ListBx_GetItemCount( src );
afaf5a
bdb496 ····if(iCount==0)
1c81ae ········return FALSE;
96af5a
9c46e9 ¤   // ·Loop through each item and insert
860fc6 ····for( i = 0; i < iCount; i++ ) ··
91421a ····{ ····
456cbe ········char szUserId[kPGPMaxUserIDSize];
43af5a
95871c ········lvi.mask ···= LVIF_IMAGE | LVIF_PARAM | LVIF_TEXT;
c3d8c5 ········lvi.iItem ·······= i; ···························
caf481 ········lvi.iSubItem ···= 0;
35274e ········lvi.pszText ·······= szUserId;
56e954 ········lvi.cchTextMax ···= sizeof(szUserId);·
9af030 ······················
43e5eb ········ListBx_GetItem( src, &lvi );
4faf5a
2ebca8 ········pui=(PUSERKEYINFO)(lvi.lParam);
58af5a
36dc64 ········if(pui->pru->location==destinationList)
482b60 ········{
5cc1f4 ············ListBx_InsertItem ( dest, &lvi );
ad7fb0 ········}
ad6fe7 ····}
21af5a
ee9968 #if !LISTBOX
1fd91c ····SortEm(dest);
447454 #endif
e5af5a
f1118a ¤   ·// ·now delete them
2ab522 ····for( i = iCount-1; i >= 0; i-- ) ··········
9d421a ····{ ····
062363 ········lvi.mask ·······= LVIF_PARAM;
88d8c5 ········lvi.iItem ·······= i; ···························
5df481 ········lvi.iSubItem ···= 0;
95af5a
29e5eb ········ListBx_GetItem( src, &lvi );
03bca8 ········pui=(PUSERKEYINFO)(lvi.lParam);
a9af5a
f67805 ········if((pui->pru->location==destinationList)||
b99250 ¤   ¤   ···(pui->pru->location==kPGPRecipientUserLocation_Hidden))
4c2b60 ········{
e3d999 ············ListBx_DeleteItem(src, i);
cc7fb0 ········}
146fe7 ····}
bbaf5a
ea9968 #if !LISTBOX
4e0ace ····SortEm(src);
--5033 0006f8da5cc4011002d Page 2 of RDmove.c
a07454 #endif
e0af5a
988011 ····return TRUE;
16efe6 }
d8af5a
261feb // MoveListViewItems
ac465d //
bca3c7 // Use this after the user has selected items and you want to move them.
c616ca // Calls the functions above to acheive movement.
f8af5a
6e9754 int MoveListViewItems(HWND left, HWND right, BOOL RecToUser)
bbbb36 {
b94512 ····LV_ITEM lvi;
9b88bd ····int userCount,iCount, i;
6b1698 ····UINT uState;
174d50 ····PUSERKEYINFO pui;
3db34b ····HWND src,dest;
f0cdf4 ····HWND hdlg;
703a36 ¤   PGPRecipientUser **userList;
408db2 ¤   int userIndex;
4dce53 ¤   int memamt;
36bffb ¤   PRECGBL prg;
7f3f69 ¤   PGPRecipientUserLocation destinationList;
7d0f00 ¤   PGPUInt32 numMovedUsers;
7e0040 ¤   PGPError err;
27a556 ¤   PGPBoolean movedARRs;
53af5a
be9137 ····hdlg=GetParent(left);
0daf5a
aa6405 ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
8caf5a
206b43 ····if(RecToUser)
c23b37 ····{
4f62cc ········src=left;
bda751 ········dest=right;
03775f ¤   ¤   destinationList=kPGPRecipientUserLocation_UserList;
046fe7 ····}
bb842c ····else
ed3b37 ····{
541d5e ········src=right;
719e83 ········dest=left;
58bdcc ¤   ¤   destinationList=kPGPRecipientUserLocation_RecipientList;
eb6fe7 ····}
11af5a
25da84 ····userCount=ListBx_GetSelectedCount( src );
9fd0ae ¤   if(userCount==0)
5da430 ········return FALSE; // ·Exit if not
aaaf5a
a7fcd9 ¤   memamt=sizeof(PGPRecipientUser *)*userCount;
81af5a
24b24a ¤   userList=(PGPRecipientUser **)malloc(memamt);
d6c561 ¤   memset(userList,0x00,memamt);
50af5a
6a0b1b ¤   userIndex=0;
cdaf5a
e1d161 ····// ·How many items are there?
8a8f4a ····iCount = ListBx_GetItemCount( src );
46af5a
f9f683 ····for( i = 0; i < iCount; i++ ) ·// ·Loop through each item
8e421a ····{ ····
29cb1e ········uState = ListBx_GetItemState( src, i, LVIS_SELECTED );
76af5a
d5393c ········if( uState ) // ·If this item is selected we wanna move it
1d2b60 ········{
3623ca ············lvi.mask ·······= LVIF_PARAM;
a63382 ············lvi.iItem ·······= i; ···························
5920fc ············lvi.iSubItem ···= 0;
aaf030 ······················
a04ceb ············ListBx_GetItem( src, &lvi );
dcc44f ············pui=(PUSERKEYINFO)(lvi.lParam);
4c97e6 ¤   ¤   ¤   userList[userIndex]=pui->pru;
6fdf49 ¤   ¤   ¤   userIndex++;
--e614 001565246414011002d Page 3 of RDmove.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
ecc160 ¤   err=PGPMoveRecipients(&(prg->mRecipients),
1ee5b5 ¤   ¤   destinationList,
32d8de ¤   ¤   userCount, userList,
ee0fe9 ¤   ¤   &numMovedUsers, &movedARRs);
28af5a
3865dd ¤   free(userList);
2daf5a
4fbd19 ····MoveMarkedItems(src,dest,destinationList);
48af5a
8a8011 ····return TRUE;
baefe6 }
82af5a
bd7e4d /*__Editor_settings____
bfaf5a
904126 ¤   Local Variables:
417b17 ¤   tab-width: 4
850e6c ¤   End:
6e5f8c ¤   vi: ts=4 sw=4
209e9b ¤   vim: si
56d062 _____________________*/
--3642 0016cf6e48e4011002e Page 1 of RDmove.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
b80218 ¤   $Id: RDmove.h,v 1.3.12.1 1998/11/12 03:24:31 heller Exp $
2ff7f7 ____________________________________________________________________________*/
0b01b7 #ifndef Included_RDMOVE_h¤  /* [ */
34ee92 #define Included_RDMOVE_h
b4af5a
6038e5 /*
39e79f ·* MoveItem.h ·List View movement routines that support ADK
75775e ·*
e0ae0a ·* These routines use the algorithm developed by Mark W. to support ADK
93775e ·*
72bd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
2d599a ·* All rights reserved.
11495d ·*/
e8af5a
bf1416 int MoveListViewItems(HWND left, HWND right, BOOL RecToUser);
4daf5a
5626e7 #endif /* ] Included_RDMOVE_h */
09af5a
1aaf5a
a17e4d /*__Editor_settings____
afaf5a
904126 ¤   Local Variables:
f77b17 ¤   tab-width: 4
470e6c ¤   End:
4b5f8c ¤   vi: ts=4 sw=4
019e9b ¤   vim: si
6cd062 _____________________*/
--52fb 001580162884011002f Page 1 of RDprecmp.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
5a19a0 ¤   $Id: RDprecmp.h,v 1.12.10.1 1998/11/12 03:24:32 heller Exp $
baf7f7 ____________________________________________________________________________*/
9bd272 #ifndef Included_RDPRECMP_h¤/* [ */
568750 #define Included_RDPRECMP_h
b4af5a
41feb2 #include <stdio.h>
33bea3 #include <stdlib.h>
e4d42a #include <Ole2.h>
68af5a
fa5e10 // Project headers
072dd0 #include "pgpui32.h"
b1a45e #include "pgpRecipientDialogCommon.h"
73aed1 #include "RDstruct.h"
b3b291 #include "RDdraw.h"
86d27a #include "RDlstmng.h"
7f3b5a #include "RDlstsrt.h"
1897b4 #include "RDserver.h"
a679bd #include "RDmove.h"
07a853 #include "RDlstsub.h"
3a5fc5 #include "RDproc.h"
cbc86f #include "RDkeyDB.h"
ee06d1 #include "RDdrag.h"
5710a7 #include "PGPImage.h"
e905c6 #include "resource.h"·
ebaf5a
233379 #ifdef __cplusplus
d76dad extern "C" {
9c7454 #endif
e4af5a
b60218 LRESULT·
a92f5a PGPsdkUIMessageBox (
433172 ¤   ¤   ·HWND¤  hWnd,·
c55442 ¤   ¤   ·INT¤   iCaption,·
fb76b8 ¤   ¤   ·INT¤   iMessage,
9211d4 ¤   ¤   ·ULONG¤ ulFlags) ;
c0af5a
042ede UINT newPGPRecipientDialog(PRECGBL prg);
32af5a
543379 #ifdef __cplusplus
83efe6 }
e07454 #endif
aaaf5a
4d724d #endif /* ] Included_RDPRECMP_h */
86af5a
f7af5a
7f7e4d /*__Editor_settings____
f9af5a
a94126 ¤   Local Variables:
cf7b17 ¤   tab-width: 4
ad0e6c ¤   End:
f55f8c ¤   vi: ts=4 sw=4
4a9e9b ¤   vim: si
69d062 _____________________*/
58af5a
--ff55 0007758fccb40110030 Page 1 of RDproc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7eccd0 ¤   $Id: RDproc.c,v 1.21.2.2.2.1 1998/11/12 03:24:33 heller Exp $
adf7f7 ____________________________________________________________________________*/
7eaf5a
384067 #include "RDprecmp.h"
ecaf5a
e9af5a
be38e5 /*
56d35b ·* RecProc.c ·Main message loop for the recipient dialog
c5775e ·*
635e95 ·* This message loops handles all the operations of the recipient
8a9472 ·* dialog, except those that are done in the listview subclass.
e3775e ·*
7ebd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
2f599a ·* All rights reserved.
a0495d ·*/
68af5a
01af5a
4c9bf1 // Used for WinHelp
68a000 static DWORD aIds[] = { ···········// Help IDs
b5781f IDC_RECIPIENT_LIST,IDH_IDC_RECIPIENT_LIST,
5997e4 IDC_USER_ID_LIST,IDH_IDC_USER_ID_LIST,
cc267b 801,IDH_TEXTOUTPUT, // Hardcoded in ClientLib
a433e2 802,IDH_CONVENCRYPTION, // Hardcoded in ClientLib
278297 803,IDH_WIPEORIGINAL, // Hardcoded in ClientLib
7cd03d 805,IDH_FYEO, // Hardcoded in ClientLib
399224 0,0·
c182f7 };
c8af5a
e54f91 static float ColRatio[NUMCOLUMNS]={0.65F,0.11F,0.18F};
347b9b static char *RecColText[NUMCOLUMNS]={"Recipients","Validity","Size"};
0fd248 static char *UserColText[NUMCOLUMNS]=
5eb7d4 ···············{"Drag users from this list to the Recipients list",
f02951 ················"Validity","Size"};
2faf5a
5509af // Used for header controls of the listviews
67af5a
2d088c // Used to calculate the placement of GUIs due to a resizing
bc2ea4 #define DLGMARGIN 2
a00279 #define BUTTONWIDTH 75
dfccc9 #define BUTTONHEIGHT 25
ab4ffe #define DIVIDEMARGIN 3
c6b030 #define BUTTONSPACE 10
abf3eb #define MINDLGX 350
04f7c0 #define MINDLGY 350
65af5a
c5ec90 int ResizeEm(HWND hdlg)
06bb36 {
62ad40 ····RECT dlgRect,recipRect,userRect;
52c7c8 ····RECT listareaRect,buttonareaRect,optRect;
c7dd56 ····int divider;
6dd0d8 ¤   int topmsg,bottommsg;
abbffb ¤   PRECGBL prg;
6a63e3 ¤   int ButtOptArea;
9baf5a
fb1604 ¤   prg=(PRECGBL)(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
e9af5a
85f3d4 ¤   ButtOptArea=90; // The height for buttons and options
83af5a
3607ae ····GetClientRect(hdlg, &dlgRect);
d0af5a
4b9e17 ····dlgRect.top+=DLGMARGIN;
229f8d ····dlgRect.bottom-=DLGMARGIN;
33a3e2 ····dlgRect.left+=DLGMARGIN;
0156bd ····dlgRect.right-=DLGMARGIN;
efaf5a
77fe37 ····CopyRect(&listareaRect,&dlgRect);
--7426 000bd72acef40110030 Page 2 of RDproc.c
a60170 ····CopyRect(&buttonareaRect,&dlgRect);
94af5a
10ddde ····listareaRect.bottom=dlgRect.bottom-ButtOptArea-DIVIDEMARGIN;
121cbd ····buttonareaRect.top=dlgRect.bottom-ButtOptArea+DIVIDEMARGIN;
efaf5a
0646c2 ····divider=(int)((float)listareaRect.bottom*(float)0.67);
098fe7 ¤   topmsg=divider;
98e17d ¤   bottommsg=divider;
f5af5a
72d7c4 ····CopyRect(&recipRect,&listareaRect);
44efba ····CopyRect(&userRect,&listareaRect);
88af5a
3059e4 ¤   if(prg->AddUserRetVal>=ADDUSER_KEYSNOTVALID)
f0c7a1 ¤   {
3a354d ¤   ¤   topmsg=divider-20;
c76026 ¤   ¤   bottommsg=divider+20;
82af5a
cac2f3 ¤   ¤   MoveWindow(GetDlgItem(hdlg, IDC_MSGTXTBORDER),
b98eed ¤   ¤   ····userRect.left,topmsg+DIVIDEMARGIN,
7884f1 ¤   ¤   ¤   userRect.right-userRect.left,40-DIVIDEMARGIN*2,TRUE);
61af5a
f510bf ¤   ¤   ShowWindow(GetDlgItem(hdlg, IDC_MSGTXT),SW_SHOW);
0b67c5 ¤
6063a4 ¤   ¤   MoveWindow(GetDlgItem(hdlg, IDC_MSGTXT),
e69ed3 ¤   ¤   ¤   userRect.left+4,topmsg+DIVIDEMARGIN+4,
2fa4fc ¤   ¤   ¤   userRect.right-userRect.left-8,40-DIVIDEMARGIN*2-8,TRUE);
fbaf5a
3296de ¤   ¤   ShowWindow(GetDlgItem(hdlg, IDC_MSGTXTBORDER),SW_SHOW);
8f9371 ¤   }
440e24 ¤   else
5fc7a1 ¤   {
246ae4 ¤   ¤   ShowWindow(GetDlgItem(hdlg, IDC_MSGTXT),SW_HIDE);
8aec85 ¤   ¤   ShowWindow(GetDlgItem(hdlg, IDC_MSGTXTBORDER),SW_HIDE);
039371 ¤   }
18af5a
940e83 ¤   userRect.bottom=topmsg-DIVIDEMARGIN;
289526 ····recipRect.top=bottommsg+DIVIDEMARGIN;
88af5a
412b83 ····CopyRect(&optRect,&buttonareaRect);
959bf1 ····buttonareaRect.left=buttonareaRect.right-3*BUTTONWIDTH-
fda8d6 ········2*BUTTONSPACE;
887e9b ····optRect.right=buttonareaRect.left-BUTTONSPACE;
47af5a
d23b3d ¤   MoveList(&(prg->lsRec),&recipRect);
bd2198 ¤   MoveList(&(prg->lsUser),&userRect);
5eaf5a
2e2d28 ····MoveWindow(GetDlgItem(hdlg, IDOK),
94aa31 ········buttonareaRect.left,buttonareaRect.top,
65499a ········BUTTONWIDTH,BUTTONHEIGHT,TRUE);
1c508e ········
53b927 ····MoveWindow(GetDlgItem(hdlg, IDCANCEL),
dd7510 ········buttonareaRect.left+BUTTONWIDTH+BUTTONSPACE,
c274fc ········buttonareaRect.top,
12499a ········BUTTONWIDTH,BUTTONHEIGHT,TRUE);
c2af5a
096aae ····MoveWindow(GetDlgItem(hdlg, IDHELP),
df83bf ········buttonareaRect.left+2*BUTTONWIDTH+2*BUTTONSPACE,
e874fc ········buttonareaRect.top,
b1499a ········BUTTONWIDTH,BUTTONHEIGHT,TRUE);
a5af5a
c37e4a ····InvalidateRect(hdlg,NULL,TRUE);
42af5a
6abd3a ¤   if(prg->mDialogOptions!=NULL)
66c7a1 ¤   {
a327f3 ¤   ¤   MoveOptionsControl(hdlg,&(prg->hwndOptions),
3e976a ¤   ¤   ¤   prg->mDialogOptions,
b06722 ¤   ¤   ¤   optRect.left,optRect.top,
59e4a8 ¤   ¤   ¤   optRect.right-optRect.left,
7e885d ¤   ¤   ¤   optRect.bottom-optRect.top);
0a9371 ¤   }
68af5a
bd8011 ····return TRUE;
--fc4b 0008196cd6340110030 Page 3 of RDproc.c
7aefe6 }
46af5a
d23688 BOOL WINAPI RecipientDlgProc(HWND hdlg, UINT uMsg,·
08d85e ·····························WPARAM wParam, LPARAM lParam)
d6bb36 {
6e827b ····switch(uMsg)
9a3b37 ····{
122aad ········case WM_INITDIALOG:
9b4661 ········{·
72f807 ············RECT rc;
614d59 ¤   ¤   ¤   char MsgTxt[256];
51a529 ¤   ¤   ¤   DRAWSTRUCT *ds;
f54fa1 ¤   ¤   ¤   PRECGBL prg;
a5af5a
74240d ¤   ¤   ¤   InitCommonControls();
2caf5a
a65d52 ¤   ¤   ¤   // need to save away the pointer to our structure...
9024a9 ¤   ¤   ¤   SetWindowLong(hdlg,GWL_USERDATA,(long)lParam);
beaf5a
3e7219 ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
32af5a
36780b ¤   ¤   ¤   prg->hwndRecDlg=hdlg;
a8af5a
97e25b ¤   ¤   ¤   ds=&(prg->ds);
cdcaf9 ············
fd2fd3 ¤   ¤   ¤   CreateDrawElements(prg->context,ds);
8ffdf8 ¤   ¤   ¤   ds->DisplayMarginal=prg->mDisplayMarginalValidity;
cb14aa ¤   ¤   ¤   ds->MarginalInvalid=prg->mIgnoreMarginalValidity;
f3af5a
7b99ec ¤   ¤   ¤   InitList(hdlg,IDC_USER_ID_LIST,
5a787d ¤   ¤   ¤   ¤   &(prg->lsUser),
bb0f7e ¤   ¤   ¤   ¤   UserColText,
1b0a64 ¤   ¤   ¤   ¤   ColRatio);
faf263 ¤   ¤   ¤   InitList(hdlg,IDC_RECIPIENT_LIST,
9dea9b ¤   ¤   ¤   ¤   &(prg->lsRec),
f305b2 ¤   ¤   ¤   ¤   RecColText,
6e0a64 ¤   ¤   ¤   ¤   ColRatio);
f2af5a
f4fcb1 ¤   ¤   ¤   prg->hwndUserIDs = prg->lsUser.hwndlist;
2f1695 ············prg->hwndRecipients = prg->lsRec.hwndlist;
99cf72 ······
3ddfb9 ············origListBoxProc=
877352 ················SubclassWindow(prg->hwndUserIDs,
d49553 ·······························MyListviewWndProc); ·
a4dfb9 ············origListBoxProc=
cd6b03 ················SubclassWindow(prg->hwndRecipients,
3c9553 ·······························MyListviewWndProc); ·
13508e ········
5bc9ce ············if(prg->mWindowTitle)
392cc2 ············{
adc4ff ················SetWindowText(hdlg, prg->mWindowTitle);
f07812 ············}
d42ffe ············// else they did not provide a title so keep default
5daf5a
390074 ¤   ¤   ¤   // Put necessary warning message up
4c996b ¤   ¤   ¤   strcpy(MsgTxt,"");
56af5a
80fa29 ¤   ¤   ¤   if((prg->AddUserRetVal)&ADDUSER_KEYSNOTCORPSIGNED)
60489e ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_KEYSNOTCORPSIGNED,·
5b1168 ¤   ¤   ¤   ¤   ¤   ¤   MsgTxt, sizeof(MsgTxt));
a1c9b0 ¤   ¤   ¤   if((prg->AddUserRetVal)&ADDUSER_ADKMISSING)
0c2b9d ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_ADKMISSING,·
0d1168 ¤   ¤   ¤   ¤   ¤   ¤   MsgTxt, sizeof(MsgTxt));
84f37d ¤   ¤   ¤   else if((prg->AddUserRetVal)&ADDUSER_KEYSNOTVALID)
a0846c ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_KEYSNOTVALID,·
2a1168 ¤   ¤   ¤   ¤   ¤   ¤   MsgTxt, sizeof(MsgTxt));
b9cd13 ¤   ¤   ¤   else if((prg->AddUserRetVal)&ADDUSER_KEYSNOTFOUND)
1e0e2a ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_KEYSNOTFOUND,·
a41168 ¤   ¤   ¤   ¤   ¤   ¤   MsgTxt, sizeof(MsgTxt));
be61a4 ¤   ¤   ¤   else if((prg->AddUserRetVal)&ADDUSER_MULTIPLEMATCH)
c235e2 ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_MULTIPLEMATCH,·
811168 ¤   ¤   ¤   ¤   ¤   ¤   MsgTxt, sizeof(MsgTxt));
--42e7 0009157ad1440110030 Page 4 of RDproc.c
2a67c5 ¤
a052a8 ¤   ¤   ¤   SetWindowText(GetDlgItem(hdlg, IDC_MSGTXT),MsgTxt);
5caf5a
efc776 ············prg->RSortAscending=TRUE;
4496eb ············prg->RSortSub=0;
a84372 ············prg->USortAscending=TRUE;
fc1473 ············prg->USortSub=0;
00d83c ·
275c09 ¤   ¤   ¤   BuildTables(prg);
0baf5a
078148 ············ResizeEm(hdlg);
c4af5a
e5df69 ¤   ¤   ¤   GetWindowRect (hdlg, &rc);
696d5c ············SetWindowPos (hdlg, NULL,
c816ae ················(GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
9dbe05 ················(GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2,
e93567 ················0, 0, SWP_NOSIZE | SWP_NOZORDER);
7caf5a
9de0dd ¤   ¤   ¤   ·// Go to keyserver for not founds
10314a ············if(prg->mSearchBeforeDisplay) ··
862cc2 ············{
e5743b ¤   ¤   ¤   ¤   PGPError err;
e1af5a
7b598a ················ShowWindow(hdlg,SW_SHOW);
4d34f6 ················SetForegroundWindow(hdlg);
8efc4b ················err=LookUpUnknownKeys(hdlg,prg);
e5a3a6 ¤   ¤   ¤   }
cbbb8c ¤   ¤   ¤   else
86edae ¤   ¤   ¤   ¤   SetForegroundWindow(hdlg);
46af5a
662b7d ¤   ¤   ¤   SetFocus(prg->hwndUserIDs);
54a683 ············return FALSE;
4c7fb0 ········}
38af5a
f32c97 ¤   ¤   case WM_CLOSE:
18ce21 ········case WM_QUIT:
e6fb31 ········case WM_DESTROY:
802b60 ········{
f94fa1 ¤   ¤   ¤   PRECGBL prg;
17af5a
bb7219 ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
5caf5a
f823bc ············DeleteDrawElements(&(prg->ds));
22869e ····
c75da4 ············SubclassWindow(prg->hwndRecipients,origListBoxProc);
95593b ············SubclassWindow(prg->hwndUserIDs,origListBoxProc);
86d720 ¤   ¤   ¤   EndDialog(hdlg, FALSE);
c58632 ············break;
b47fb0 ········}
87af5a
5e4e34 ¤   ¤   case WM_GETMINMAXINFO:
305b34 ¤   ¤   {
5a8590 ¤   ¤   ¤   MINMAXINFO* lpmmi;
f3af5a
70b98a ¤   ¤   ····lpmmi = (MINMAXINFO*) lParam;
043d2d ····¤   ¤   lpmmi->ptMinTrackSize.x = MINDLGX;
b4625c ····¤   ¤   lpmmi->ptMinTrackSize.y = MINDLGY;
278632 ············break;
420fe4 ¤   ¤   }
71af5a
019510 #if LISTBOX
8211dc ¤   ¤   case WM_COMPAREITEM:
77c632 ¤   ¤   { ····
dcef07 ¤   ¤   ¤   COMPAREITEMSTRUCT *comp;
a591fe ¤   ¤   ¤   PUSERKEYINFO pui1,pui2; ··
967904 ¤   ¤   ¤   HWND hwndFrom;
38af5a
7ac25f ¤   ¤   ¤   comp=(COMPAREITEMSTRUCT *)lParam;
dd71ef ¤   ¤   ¤   pui1=(PUSERKEYINFO)comp->itemData1;
24ed6e ¤   ¤   ¤   pui2=(PUSERKEYINFO)comp->itemData2;·
33cd78 ¤   ¤   ¤   hwndFrom=comp->hwndItem;
91af5a
--5abf 00054de248840110030 Page 5 of RDproc.c
c45af0 ¤   ¤   ¤   return ListViewCompareProc((LPARAM)pui1,
b53422 ¤   ¤   ¤   ¤   (LPARAM)pui2,
4c04ff ¤   ¤   ¤   ¤   (LPARAM)hwndFrom); ·
2d0fe4 ¤   ¤   }
ca7454 #endif
94af5a
433c22 ········case WM_SIZE:
562b60 ········{
6e8148 ············ResizeEm(hdlg);
3f8632 ············break;
007fb0 ········}
93af5a
569968 #if !LISTBOX
5e5f09 ········#define ptrNMHDR ······((LPNMHDR)lParam)
8914ae ········#define ptrNM_LISTVIEW ((NM_LISTVIEW *)lParam)
55a8bd ········#define ptrTV_DISPINFO ((TV_DISPINFO *)lParam)
b5af5a
fbaf5a
a159e8 ········case WM_NOTIFY:
ce2b60 ········{
036b3b ············switch (ptrNMHDR->code)
882cc2 ············{
0be182 ················case LVN_BEGINDRAG: // Sent by ListView when user·
673ec3 ················{ ···················// wants to drag an item.
678319 ····················int dx,dy,left,bottom,result;
f74215 ····················POINT pnt;
c2c0aa ¤   ¤   ¤   ¤   ¤   PRECGBL prg;
4daf5a
11ff07 ¤   ¤   ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
dbaf5a
7fa088 ····················prg->hwndDragFrom = ptrNMHDR->hwndFrom;
50af5a
09e1b2 ····················if(!ListView_GetSelectedCount(prg->hwndDragFrom))
118ae9 ····················{
97085e ························break; // ·Exit if not
ccde39 ····················}
45af5a
d05ca6 ····················result=ImageList_DragShowNolock(FALSE);
3eaf5a
8782d9 ····················prg->hDragImage=
7eb857 ························MakeDragImage(prg->hwndDragFrom,
5c35e9 ······································&left,&bottom);
c8af5a
422317 ····················SetCapture(hdlg);
09af5a
817089 ····················pnt.x=((NM_LISTVIEW *)lParam)->ptAction.x;
b760bb ····················pnt.y=((NM_LISTVIEW *)lParam)->ptAction.y;
dcaf5a
fa2808 ····················dx=pnt.x-left;
9981e3 ····················dy=pnt.y-bottom;
a9af5a
4b18a5 ····················result=ImageList_BeginDrag(prg->hDragImage,
d7893a ···············································0,dx,dy);
ab869e ····
fe24b7 ····················MapWindowPoints(prg->hwndDragFrom,hdlg,
23828c ························(LPPOINT)&pnt,(UINT)1);
d6af5a
5df666 ····················ImageList_DragEnter(hdlg,pnt.x,pnt.y);
89af5a
11d4d1 ····················result=ImageList_DragShowNolock(TRUE);
66869e ····
4432b3 ····················prg->bDragging = TRUE;
c748e8 ····················break;
3a6f5c ················}
e9af5a
4a1557 ················case LVN_COLUMNCLICK: // Sent by ListView when user·
440e0d ················{ ····················// clicks header control
626f5a ····················int *SortSub;
0bffdc ····················BOOL *SortAscending;
78c0aa ¤   ¤   ¤   ¤   ¤   PRECGBL prg;
36af5a
54ff07 ¤   ¤   ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
--23e8 0001b10967c40110030 Page 6 of RDproc.c
e0af5a
10fe35 ····················if(ptrNMHDR->hwndFrom==prg->hwndRecipients)
d58ae9 ····················{
06ac4b ························SortSub=&(prg->RSortSub);
9a8ca2 ························SortAscending=&(prg->RSortAscending);
34de39 ····················}
f1388e ····················else
888ae9 ····················{
b30cad ························SortSub=&(prg->USortSub);
73fc8f ························SortAscending=&(prg->USortAscending);
08de39 ····················}
ecaf5a
e2210c ····················if(*SortSub==ptrNM_LISTVIEW->iSubItem)
d18ae9 ····················{
56c0a4 ························*SortAscending=!(*SortAscending);
07de39 ····················}
31388e ····················else
318ae9 ····················{
985fbc ························*SortAscending=TRUE;
c4b6af ························*SortSub=ptrNM_LISTVIEW->iSubItem;
5ede39 ····················}
75af5a
af3204 ····················SortEm(ptrNMHDR->hwndFrom);
7caf5a
4d48e8 ····················break;
e86f5c ················}
7faf5a
92702e ············}// switch
6baf5a
988632 ············break;
d027a5 ········} // case
acaf5a
1a826f #endif // !LISTBOX
c0af5a
def777 ········case WM_SYSCOLORCHANGE:
da2b60 ········{
5f4fa1 ¤   ¤   ¤   PRECGBL prg;
ecaf5a
327219 ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
4baf5a
c223bc ············DeleteDrawElements(&(prg->ds));
e01096 ············CreateDrawElements(prg->context,&(prg->ds));
e0af5a
2f442f ············SendMessage(prg->hwndRecipients,
507d78 ················WM_SYSCOLORCHANGE,0,0);
7ebdd8 ············SendMessage(prg->hwndUserIDs,
077d78 ················WM_SYSCOLORCHANGE,0,0);
118632 ············break;
2e7fb0 ········}
18af5a
212267 ········case WM_DRAWITEM:·
2e2b60 ········{
1d1cd5 ············Main_OnDrawItem(hdlg,(LPDRAWITEMSTRUCT) lParam);
1e51a3 ············return TRUE;
e77fb0 ········}
4eaf5a
4f775f ········case WM_MEASUREITEM:
cc7d6e ············Main_OnMeasureItem(hdlg,(LPMEASUREITEMSTRUCT) lParam);
4351a3 ············return TRUE;
a7af5a
73f7f1 ········case WM_HELP:·
712b60 ········{
1fe3ff ¤   ¤   ¤   char szHelpFile[MAX_PATH+1];
adaf5a
375319 ············GetHelpDir(szHelpFile);
75af5a
2e394b ············WinHelp (((LPHELPINFO) lParam)->hItemHandle, szHelpFile,·
c0f1db ··················HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
d38632 ············break;
427fb0 ········}
9faf5a
1b47df ¤   ¤   // Note, ListView's context are done through subclass
--e65e 0007095777040110030 Page 7 of RDproc.c
0dc43a ········case WM_CONTEXTMENU:·
395b34 ¤   ¤   {
aee3ff ¤   ¤   ¤   char szHelpFile[MAX_PATH+1];
a6af5a
e1e226 ¤   ¤   ¤   GetHelpDir(szHelpFile);
4daf5a
00c9d1 ¤   ¤   ¤   WinHelp ((HWND) wParam, szHelpFile, HELP_CONTEXTMENU,·
a736d8 ¤   ¤   ¤   ¤   (DWORD) (LPVOID) aIds);·
c2cdcb ¤   ¤   ¤   break;
270fe4 ¤   ¤   }
39af5a
433d9e ················
199968 #if !LISTBOX
8fe958 ··········
8255dd ········case WM_MOUSEMOVE:
102b60 ········{
d94fa1 ¤   ¤   ¤   PRECGBL prg;
7aaf5a
687219 ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
1eaf5a
06c72b ············if (prg->bDragging)
a62cc2 ············{
e5e971 ················int result;
08af5a
71fc17 ················// drag the item to the current mouse position
99d8ee ················result=ImageList_DragMove(LOWORD(lParam),
616914 ····················HIWORD(lParam));
2237a5 ············} ····
5dec2c ························
6b8632 ············break;
4f7fb0 ········}
eeaf5a
16d93b ········case WM_LBUTTONUP:
5b2b60 ········{
0d4fa1 ¤   ¤   ¤   PRECGBL prg;
0baf5a
6c7219 ¤   ¤   ¤   prg=(PRECGBL)GetWindowLong(hdlg,GWL_USERDATA);
bcaf5a
2bc72b ············if (prg->bDragging)
492cc2 ············{
d755b5 ················HWND hwndTarget; ···········// window under mouse
2389e3 ················POINT pt;
7ee971 ················int result;
35af5a
538a9b ················// Release the mouse capture
f7dee3 ················ReleaseCapture();
9de1a0 ················// Clear the drag flag
32ce86 ················prg->bDragging = FALSE;
b7320e ················result=ImageList_DragShowNolock(FALSE);
db2499 ················ImageList_DragLeave(hdlg);
824395 ················ImageList_EndDrag();
23af5a
d4d71e ················ImageList_Destroy(prg->hDragImage);
cbaf5a
b79e6e ················pt.x = LOWORD(lParam); ·// horizontal position of cursor·
3e772d ················pt.y = HIWORD(lParam); ·// vertical position of cursor
49af5a
7518aa ················ClientToScreen (hdlg, &pt);
e3af5a
5a6d8e ················// First, check to see if there is a valid drop point.
2e5659 ················hwndTarget = WindowFromPoint( pt );
77af5a
c6ab71 ················// make sure everything is going in the right direction
0b6e0e ················if(((hwndTarget == prg->hwndRecipients) ||
0c4966 ····················(hwndTarget == prg->hwndUserIDs))·
685eb5 ····················&& (hwndTarget != prg->hwndDragFrom))
1f3b8c ················{
8a2825 ····················MoveListViewItems(prg->hwndRecipients,prg->hwndUserIDs,
69edde ························prg->hwndDragFrom==prg->hwndRecipients);
236f5c ················}
edaf5a
707812 ············}
--f9f1 001a77a593340110030 Page 8 of RDproc.c
e0af5a
098632 ············break;
c77fb0 ········}
9caf5a
fd826f #endif // !LISTBOX
e9af5a
40aff6 ········case WM_COMMAND:
e12b60 ········{
0e14e1 ············switch(wParam)
a52cc2 ············{
8058d1 ················case IDOK:
e33b8c ················{
a9ac68 ····················EndDialog(hdlg, TRUE);
7548e8 ····················break;
186f5c ················}
afaf5a
a70981 ················case IDCANCEL:
7d3b8c ················{
b77494 ····················EndDialog(hdlg, FALSE);
9448e8 ····················break;
736f5c ················}
95af5a
bce089 ················case IDHELP:
0e3b8c ················{
07179b ····················char szHelpFile[MAX_PATH+1];
7daf5a
234192 ····················GetHelpDir(szHelpFile);
7eaf5a
1bdac7 ····················WinHelp (hdlg, szHelpFile, HELP_CONTEXT,·
1a4f38 ························IDH_IDD_RECIPIENTDLG);·
1548e8 ····················break;
5a6f5c ················}
f1af5a
a47812 ············}
a151a3 ············return TRUE;
c57fb0 ········}
38af5a
7d6fe7 ····}
e530cb ····return FALSE;
90efe6 }
b1af5a
527e4d /*__Editor_settings____
f0af5a
cf4126 ¤   Local Variables:
597b17 ¤   tab-width: 4
fc0e6c ¤   End:
9e5f8c ¤   vi: ts=4 sw=4
099e9b ¤   vim: si
a7d062 _____________________*/
--30cf 001658f78a140110031 Page 1 of RDproc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
80f589 ¤   $Id: RDproc.h,v 1.4.10.1 1998/11/12 03:24:33 heller Exp $
a0f7f7 ____________________________________________________________________________*/
083bf2 #ifndef Included_RDPROC_h¤  /* [ */
9bacc5 #define Included_RDPROC_h
ccaf5a
6f38e5 /*
e9d35b ·* RecProc.c ·Main message loop for the recipient dialog
b0775e ·*
8d5e95 ·* This message loops handles all the operations of the recipient
eb9472 ·* dialog, except those that are done in the listview subclass.
4e775e ·*
8cbd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
69599a ·* All rights reserved.
5a495d ·*/
33af5a
abfe66 BOOL CALLBACK RecipientDlgProc(HWND hdlg,UINT uMsg, ···
8159f4 ·······························WPARAM wParam,LPARAM lParam);
08af5a
015cd7 #endif /* ] Included_RDPROC_h */
14af5a
d9af5a
297e4d /*__Editor_settings____
4faf5a
294126 ¤   Local Variables:
7b7b17 ¤   tab-width: 4
a40e6c ¤   End:
c25f8c ¤   vi: ts=4 sw=4
4d9e9b ¤   vim: si
65d062 _____________________*/
--33f7 0010937ff2f40110032 Page 1 of RDserver.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
a7df9f ¤   $Id: RDserver.c,v 1.11.10.1 1998/11/12 03:24:34 heller Exp $
a3f7f7 ____________________________________________________________________________*/
28af5a
9f4067 #include "RDprecmp.h"
a4af5a
e58b18 // LookUpUnknownKeys
82465d //
f4d277 // Use common code to do key lookup, then rebuild the tables
9aaf5a
dd2af3 PGPError LookUpUnknownKeys(HWND hdlg,PRECGBL prg)
6a7142 {·
f80040 ¤   PGPError err;
c76df3 ¤   PGPBoolean haveNewKeys;
ffaf5a
a0ebf8 ¤   err = PGPUpdateMissingRecipients( hdlg, &(prg->mRecipients), &haveNewKeys );
dbaf5a
1dbb90 ¤   PGPsdkUIErrorBox (hdlg,err);
d4af5a
7238be ¤   if( IsntPGPError( err ) && haveNewKeys )
65c7a1 ¤   {
b4d55d ¤   ¤   BuildTables(prg);
949371 ¤   }
beaf5a
fd5ea8 ¤   return err;
cbefe6 }
d0af5a
c67e4d /*__Editor_settings____
28af5a
1d4126 ¤   Local Variables:
b57b17 ¤   tab-width: 4
3d0e6c ¤   End:
315f8c ¤   vi: ts=4 sw=4
ce9e9b ¤   vim: si
09d062 _____________________*/
--209d 001ec3f467740110033 Page 1 of RDserver.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
5443ae ¤   $Id: RDserver.h,v 1.4.10.1 1998/11/12 03:24:35 heller Exp $
7af7f7 ____________________________________________________________________________*/
34d7dc #ifndef Included_RDSERVER_h¤/* [ */
0ed191 #define Included_RDSERVER_h
24af5a
1c38e5 /*
a51f0c ·* KeyServe.h ·Routines needed to support the keyserver context menu
62775e ·*
1fec25 ·* All of these routines are used within the listview subclass handler, but
8b3066 ·* since they deal with the keyserver, they are isolated in this file for
7e407f ·* clarity.
4f775e ·*
9cbd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
3e599a ·* All rights reserved.
2d495d ·*/
beaf5a
c5c51e PGPError LookUpUnknownKeys(HWND hdlg,PRECGBL prg);
98af5a
b9a52c #endif /* ] Included_RDSERVER_h */
e2af5a
d4af5a
1c7e4d /*__Editor_settings____
8aaf5a
764126 ¤   Local Variables:
a87b17 ¤   tab-width: 4
7c0e6c ¤   End:
395f8c ¤   vi: ts=4 sw=4
369e9b ¤   vim: si
ecd062 _____________________*/
--1429 0003714ac2740110034 Page 1 of RDstruct.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c8c7b0 ¤   $Id: RDstruct.h,v 1.15.10.1 1998/11/12 03:24:35 heller Exp $
b0f7f7 ____________________________________________________________________________*/
2f6159 #ifndef Included_RDSTRUCT_h¤/* [ */
047729 #define Included_RDSTRUCT_h
31af5a
0ec84d #define KEYIDLENGTH 20 // Formerly 12
943663 #define SIZELENGTH 30
17af5a
1d474a #define ADKCLASS_MOVEWARNING 128
e5af5a
3e6a1b #define NUMCOLUMNS 3
35af5a
fa0027 typedef struct _liststruct
65bb36 {
4755cf ¤   HWND hwnd;
d5b2d0 ¤   HWND hwndlist;
29010f ¤   HWND hwndtext[NUMCOLUMNS];
94bfd3 ¤   int colwidth[NUMCOLUMNS];
b4b4ec ¤   float *colratio;
93d648 } LISTSTRUCT;
36af5a
ca9d21 typedef struct _drawstruct
f4bb36 {
b85641 ¤   PGPBoolean DisplayMarginal;
d478a7 ¤   PGPBoolean MarginalInvalid;
074702 ¤   DWORD barcolor;
77bd45 ¤   HBRUSH stdbarbrush;
e318d5 ¤   HBRUSH spcbarbrush;
027880 ¤   HPEN g_seltextpen;
6d95c8 ¤   HPEN g_unseltextpen;
a3640e ¤   HPEN hilightpen;
c11db9 ¤   HPEN shadowpen;
81af9a ¤   HPEN buttonpen;
52af5a
f4ba96 ¤   HBRUSH barbgbrush;
fe8d41 ¤   HBRUSH HighBrush;
e846d5 ¤   HBRUSH BackBrush;
c7f61b ¤   HFONT¤  hFont;
8acaf3 ¤   HFONT¤  hItalic;
fd6d42 ¤   HFONT¤  hStrikeOut;
1857f7 ¤   HIMAGELIST hIml;
9db3e3 } DRAWSTRUCT;
9baf5a
e18779 typedef struct _USERKEYINFO
2abb36 {
8ce8d2 ¤   DWORD¤  ¤   ¤   icon;
192fa1 ¤   DWORD ······¤   Trust;
1803cc ¤   DWORD¤  ¤   ¤   Validity;
34fb2a ¤   DWORD¤  ¤   ¤   Algorithm;
6eca8c ¤   char ·······¤   UserId[kPGPMaxUserIDSize+1];
166a96 ¤   char ·······¤   szSize[SIZELENGTH];
9a21d2 ¤   struct PGPRecipientUser¤*pru;
09af5a
3e5aa2 ¤   struct _USERKEYINFO *next;
7ce093 } USERKEYINFO, *PUSERKEYINFO;
3baf5a
1b1741 typedef struct
f9bb36 {
017ff7 PGPContextRef¤  ¤   ¤   context;
764cb9 PGPtlsContextRef¤   ¤   tlsContext;
bef592 const PGPKeyServerSpec¤ *ksEntries;
09d429 PGPUInt32¤  ¤   ¤   ¤   numKSEntries;
5b0f4a char¤   ¤   ¤   ¤   ¤   *mWindowTitle;
f472bd PGPBoolean¤ ¤   ¤   ¤   mSearchBeforeDisplay;
671cac PGPKeySetRef¤   ¤   ¤   *mNewKeys;
3708ab PGPOptionListRef¤   ¤   mDialogOptions;
--b8cc 0018e73e89840110034 Page 2 of RDstruct.h
8bc7d3 PGPUInt32¤  ¤   ¤   ¤   mNumDefaultRecipients;
5c0a5d PGPRecipientSpec¤   ¤   *mDefaultRecipients;
444f39 PGPBoolean¤ ¤   ¤   ¤   mDisplayMarginalValidity;
30911f PGPBoolean¤ ¤   ¤   ¤   mIgnoreMarginalValidity;
4becb8 PGPGroupSetRef¤ ¤   ¤   mGroupSet;
181fa3 PGPKeySetRef¤   ¤   ¤   mClientKeySet;
15b84d PGPKeySetRef¤   ¤   ¤   *mRecipientKeysPtr;
d6a26c HWND¤   ¤   ¤   ¤   ¤   mHwndParent;
e69307 HWND¤   ¤   ¤   ¤   ¤   hwndRecDlg;
8e59ef HINSTANCE¤  ¤   ¤   ¤   g_hInst;
b8ac26 HWND¤   ¤   ¤   ¤   ¤   hwndOptions;
e6c360 HIMAGELIST hDragImage;
1d5a28 BOOL bDragging; ·····
12b16c HWND hwndDragFrom;
dc01c8 DRAWSTRUCT ds;
756c4c LISTSTRUCT lsUser;
c7eddf LISTSTRUCT lsRec;
1435d8 int g_ValRSA;
efba00 int g_ValDSA;
15128e int g_Unknown;
74de84 int g_MultRSA;
82515c int g_MultDSA;
39cb68 PUSERKEYINFO gUserLinkedList;·
f36ab2 HWND hwndRecipients;
2027e6 HWND hwndUserIDs;
e9fc53 HWND hwndOptionASCII;
101e73 BOOL RSortAscending;
998bbd int RSortSub;
29ac30 BOOL USortAscending;
964f48 int USortSub;
38dd2f UINT AddUserRetVal;
964d77 BOOL Reloading;
47efdd BOOL Pending;
32e077 HWND hwndRelay;
dc743e PGPRecipientsList¤  mRecipients;
01b1a1 } RECGBL, *PRECGBL;
76af5a
f422ee HINSTANCE g_hinst;
dfce66 UINT PGPM_RELOADKEYRING;
3ed92b WNDPROC origListBoxProc;
6ed83c ·
c91741 typedef struct
abbb36 {
d7eaad int gIDH; ·
18595b BOOL *pWarnCheck;
f009bb char *gWarnText;
7f3211 } WARNGBL, *PWARNGBL;
c8af5a
3aaf5a
c41283 #endif /* ] Included_RDSTRUCT_h */
08af5a
18af5a
da7e4d /*__Editor_settings____
32af5a
234126 ¤   Local Variables:
ae7b17 ¤   tab-width: 4
900e6c ¤   End:
405f8c ¤   vi: ts=4 sw=4
d69e9b ¤   vim: si
8ed062 _____________________*/
--715e 001f0c0575840110035 Page 1 of UIhelp.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c31ea3 ¤   $Id: UIhelp.h,v 1.4.2.1.2.1 1998/11/12 03:24:36 heller Exp $
f9f7f7 ____________________________________________________________________________*/
a631fc #ifndef Included_UIHELP_h¤  /* [ */
18311e #define Included_UIHELP_h
74af5a
227cdc /* defines constants for help file */
cdaf5a
440632 // Passphrase stuff starts at 1000
76af5a
ba0d63 #define IDH_PGPCLPHRASE_HIDETYPING¤ ¤   1010
cb5b32 #define IDH_PGPCLPHRASE_PHRASE¤ ¤   ¤   1011
23a6a8 #define IDH_PGPCLPHRASE_SIGNINGKEY¤ ¤   1012
7012e7 #define IDH_PGPCLPHRASE_KEYLIST¤¤   ¤   1016
1c709d #define IDH_PGPCLPHRASE_CONFIRMATION¤   1017
90e3b7 #define IDH_PGPCLPHRASE_QUALITY¤¤   ¤   1018
9144ad #define IDH_PGPCLPHRASE_KEYNAME¤¤   ¤   1019 // *
caaf5a
5c96ae // Recipient dialog starts at 3000
659220 #define IDH_IDD_RECIPIENTDLG¤   ¤   ¤   3000
940046 #define IDH_IDC_RECIPIENT_LIST¤ ¤   ¤   3006
ebac53 #define IDH_IDC_USER_ID_LIST¤   ¤   ¤   3007
67af5a
d0c0d3 // Also note that the RSADSA encryption warning
d00f33 // has moved to PGPcl. 3009 is the still the help·
f6e8c0 // ID for it.
e17997 // #define IDH_RSADSARECWARNING¤¤   ¤   3009
ceaf5a
f404c7 // ClientLib options that we've hardcoded in·
24d800 // help for.
485169 #define IDH_TEXTOUTPUT¤ ¤   ¤   ¤   ¤   3100
c16ad0 #define IDH_CONVENCRYPTION¤ ¤   ¤   ¤   3101
35a9dc #define IDH_WIPEORIGINAL¤   ¤   ¤   ¤   3102
f8558e #define IDH_DETACHEDSIG¤¤   ¤   ¤   ¤   3103
217979 #define IDH_FYEO¤   ¤   ¤   ¤   ¤   ¤   3104
caaf5a
a4535b #endif /* ] Included_UIHELP_h */
94af5a
33af5a
437e4d /*__Editor_settings____
afaf5a
624126 ¤   Local Variables:
747b17 ¤   tab-width: 4
870e6c ¤   End:
e45f8c ¤   vi: ts=4 sw=4
bd9e9b ¤   vim: si
f0d062 _____________________*/
--f3b1 000a4ed311840110036 Page 1 of pgpCLUtils.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
643485 ¤   $Id: pgpCLUtils.c,v 1.1.10.2 1998/11/13 19:51:02 heller Exp $
cdf7f7 ____________________________________________________________________________*/
abaf5a
52feb2 #include <stdio.h>
3bbea3 #include <stdlib.h>
6c324c #include <string.h>
48af5a
3edde9 #include "pgpKB.h"
80688a #include "pgpCLUtils.h"
5aaf5a
664d2f int
807456 pgpCLGetPass (FILE *fp, char *buffer, int buflen)
61bb36 {
3f4ba4 ¤   int i;
a167c5 ¤
6a8eba ¤   fprintf (fp, "Enter pass phrase (type ^D to cancel): ");
85d810 ¤   fflush (fp);
034eb1 /*¤ i = pgpTtyGetString (buffer, buflen, ui->showpass ? ui->fp : NULL); */
cf2579 ¤   i = pgpCLGetString (buffer, buflen, NULL);
bf5e47 ¤   fprintf (fp, "\n");
cbd810 ¤   fflush (fp);
b92196 ¤   return i;
95efe6 }
f2af5a
984d2f int
b08ecf pgpCLGetString(char *buf, int len, FILE *echo)
8cbb36 {
e638de ¤   int c;
d1472c ¤   int n = 0;
1d67c5 ¤
a91c04 ¤   kbCbreak(0);
d167c5 ¤
7c220e ¤   for (;;) {
c06863 ¤   ¤   if (echo)
53be44 ¤   ¤   ¤   fflush(echo);
7c4c74 ¤   ¤   c = kbGet();
a81b52 ¤   ¤
30c7c2 ¤   ¤   if (c == '\r' || c == '\n') {
0b870e ¤   ¤   ¤   c = '\n';
7fcdcb ¤   ¤   ¤   break;
87126d ¤   ¤   } else if (c == '\b' || c == 7 || c == 127) {
07546c ¤   ¤   ¤   if (n > 0) {
6f6df8 ¤   ¤   ¤   ¤   n--;
11954c ¤   ¤   ¤   ¤   if (echo)
5338ed ¤   ¤   ¤   ¤   ¤   fputs("\b \b", echo);
b9a8fe ¤   ¤   ¤   } else
2af0d3 ¤   ¤   ¤   ¤   fputc('\a', echo ? echo : stderr);
a1f77d ¤   ¤   } else if (c == 0x04) {
e911f0 ¤   ¤   ¤   if (echo) {
3c1be2 ¤   ¤   ¤   ¤   fputc('\n', echo);
3b3710 ¤   ¤   ¤   ¤   fflush(echo);
09a3a6 ¤   ¤   ¤   }
0189a0 ¤   ¤   ¤   kbNorm();
8a3fd5 ¤   ¤   ¤   return -1;
3af812 ¤   ¤   } else if (c == 0x15) {
18b26b ¤   ¤   ¤   fputc('\r', stdout);
cdbb6d ¤   ¤   ¤   n = 0;
efcef9 ¤   ¤   } else if (c < ' ' || c > 256) {
2f2861 ¤   ¤   ¤   fputc('\a', echo ? echo : stderr);
e5bd6b ¤   ¤   } else if (n + 1 >= len) {
1e2861 ¤   ¤   ¤   fputc('\a', echo ? echo : stderr);
7a7e71 ¤   ¤   ¤   kbFlush(0);
d145a6 ¤   ¤   } else {
ee52f9 ¤   ¤   ¤   if (echo)
6e44ec ¤   ¤   ¤   ¤   fputc(c, echo);
8b9cc6 ¤   ¤   ¤   buf[n++] = (char)c;
5c0fe4 ¤   ¤   }
a49371 ¤   }
--15f9 001314ca71140110036 Page 2 of pgpCLUtils.c
06fc77 ¤   if (echo) {
bf83b5 ¤   ¤   fputc('\n', echo);
a179f1 ¤   ¤   fflush(echo);
979371 ¤   }
546b14 ¤   buf[n] = '\0';
3167c5 ¤
d8368f ¤   kbNorm();
2bad93 ¤   return n;
31efe6 }
--35d3 001622f2a5040110037 Page 1 of pgpCLUtils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
c4d787 ¤   $Id: pgpCLUtils.h,v 1.1.10.1 1998/11/12 03:24:37 heller Exp $
8af7f7 ____________________________________________________________________________*/
980c39 #ifndef Included_pgpCLUtils_h
4c580d #define Included_pgpCLUtils_h
f5af5a
f7c5d5 #include "pgpBase.h"
89af5a
3d99c6 PGP_BEGIN_C_DECLARATIONS
b6af5a
f9740f int pgpCLGetPass(FILE *fp, char *buffer, int buflen);
84e81f int pgpCLGetString(char *buf, int len, FILE *echo);
36af5a
db1254 PGP_END_C_DECLARATIONS
dcaf5a
627454 #endif
--9544 00149ba8b4e40110038 Page 1 of pgpImage.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
cfd4ae ¤   pgpImage.h - header for PGP image index definitions
7567c5 ¤
d0af5a
4c87cc ¤   $Id: pgpImage.h,v 1.3.10.1 1998/11/12 03:24:38 heller Exp $
65f7f7 ____________________________________________________________________________*/
08f362 #ifndef Included_pgpImage_h¤/* [ */
d023cc #define Included_pgpImage_h
4aaf5a
bdaf5a
c4870c // bitmap images index definitions
80af5a
d3fe28 #define IDX_NONE¤   ¤   ¤   -1
19b206 #define IDX_INVALID¤¤   ¤   0
b6ecfd #define IDX_PUSHED¤ ¤   ¤   1
374212 #define IDX_VALID¤  ¤   ¤   2
9987d4 #define IDX_VALIDPUSHED¤¤   3
bbc425 #define IDX_AXIOMATIC¤  ¤   4
f6debe #define IDX_AXIOMATICPUSHED¤5
e748fb #define IDX_RSAPUBKEY¤  ¤   6
6e5d7f #define IDX_RSAPUBDISKEY¤   7
92b2e6 #define IDX_RSAPUBREVKEY¤   8
2e1287 #define IDX_RSAPUBEXPKEY¤   9
c267b6 #define IDX_RSASECKEY¤  ¤   10
11e68b #define IDX_RSASECDISKEY¤   11
cd8f83 #define IDX_RSASECREVKEY¤   12
41bea8 #define IDX_RSASECEXPKEY¤   13
8c0a64 #define IDX_RSASECSHRKEY¤   14
7550ad #define IDX_DSAPUBKEY¤  ¤   15
10e220 #define IDX_DSAPUBDISKEY¤   16
8bb898 #define IDX_DSAPUBREVKEY¤   17
7813a3 #define IDX_DSAPUBEXPKEY¤   18
5ebf22 #define IDX_DSASECKEY¤  ¤   19
ec1fbb #define IDX_DSASECDISKEY¤   20
2f4503 #define IDX_DSASECREVKEY¤   21
da4798 #define IDX_DSASECEXPKEY¤   22
55a784 #define IDX_DSASECSHRKEY¤   23
4f7c21 #define IDX_RSAUSERID¤  ¤   24
386a75 #define IDX_DSAUSERID¤  ¤   25
60121b #define IDX_INVALIDUSERID¤  26
6ac4ac #define IDX_PHOTOUSERID¤¤   27
09738c #define IDX_CERT¤   ¤   ¤   28
708b27 #define IDX_REVCERT¤¤   ¤   29
58f08c #define IDX_EXPCERT¤¤   ¤   30
7fb062 #define IDX_BADCERT¤¤   ¤   31
7daf96 #define IDX_EXPORTCERT¤ ¤   32
defaf6 #define IDX_METACERT¤   ¤   33
24b525 #define IDX_EXPORTMETACERT¤ 34
9088a8 #define IDX_GROUP¤  ¤   ¤   35
f36527 #define IDX_NOADK¤  ¤   ¤   36
f22031 #define¤IDX_NOADKPUSHED¤¤   37
553f3c #define IDX_ADK¤¤   ¤   ¤   38
064e65 #define IDX_ADKPUSHED¤  ¤   39
ba0c65 #define IDX_OPENLOCK¤   ¤   40
01b416 #define IDX_CLOSEDLOCK¤ ¤   41
d50d5c #define NUM_BITMAPS¤¤   ¤   42
bcaf5a
179608 #endif /* ] Included_pgpImage_h */
26af5a
2daf5a
827e4d /*__Editor_settings____
d9af5a
cd4126 ¤   Local Variables:
257b17 ¤   tab-width: 4
db0e6c ¤   End:
845f8c ¤   vi: ts=4 sw=4
709e9b ¤   vim: si
d3d062 _____________________*/
49af5a
--fad5 0019c74c47c40110039 Page 1 of pgpKB.h
bc38e5 /*
552219 ·* pgpKB.h -- interface for keyboard I/O
4f1eb6 ·* ···········The implementation is in pgpKBUnix.c, pgpKBMSDOS.c,
98aca1 ·* ···········kbvms.c, etc.
87775e ·*
64a9db ·* Copyright (C) 1993-1997 Network Associates, Inc. and its affiliates. ·All ri¶
a89f23 ghts reserved.
3f775e ·*
d027bf ·* $Id: pgpKB.h,v 1.1.10.2 1998/11/13 04:23:48 heller Exp $
64495d ·*/
d1af5a
f53379 #ifdef __cplusplus
c96dad extern "C" {
7e7454 #endif
1faf5a
fa0d2f int kbOpenKbd(int flags, int InBatchmode);
7eca6d int kbCloseKbd(int fd);
57379f void kbCbreak(int InBatchmode), kbNorm(void);
d3adcb int kbGet(void);
f57593 void kbFlush(int thorough);
66af5a
dd3379 #ifdef __cplusplus
4eefe6 }
f17454 #endif
9cc7a3 ·¶
--b6d5 0007c4b87474011003a Page 1 of pgpKBNT.c
bc38e5 /*
323ee7 ·* MS-DOS non-echoing keyboard routines.
67775e ·*
02833a ·* $Id: pgpKBNT.c,v 1.1 1998/06/16 21:34:21 elowe Exp $
cf495d ·*/
d1af5a
81feb2 #include <stdio.h>
70bea3 #include <stdlib.h>
91998b #include <conio.h>¤ /* For getch() and kbhit() */
c485b4 #include <signal.h>¤/* For raise() */
1aaf5a
80c5d5 #include "pgpBase.h"
aeaf5a
f4036c #ifdef UNITTEST
04327c # define ·PGPGlobalRandomPoolAddKeystroke(c) (void)c
28db21 #else
5c47d9 # include "pgpRandomPool.h"¤/* For PGPGlobalRandomPoolAddKeystroke() */
f97454 #endif
a6af5a
a7dde9 #include "pgpKB.h"
8aaf5a
7deab6 /* These are pretty boring */
19f126 void kbCbreak(int x) { return; }
1dd48a void kbNorm(void) { return; }
72af5a
f4a128 int kbGet(void)
bebb36 {
4d38de ¤   int c;
d1af5a
b16a68 ¤   while (!_kbhit()) ;
629760 ¤   c = _getch();
9e2513 ¤   if (c == 0)
9ffd5d ¤   ¤   c = 0x100 + _getch();
55af5a
a4d8af ¤   /*
a45efb ¤   ·* Borland C's getch() uses int 0x21 function 0x7,
bb5025 ¤   ·* which does not detect break. ·So we do it explicitly.
79a4e3 ¤   ·*/
f6ca77 ¤   if (c == 3)
031005 ¤   ¤   raise(SIGINT);
abaf5a
64301d ¤   ·PGPGlobalRandomPoolAddKeystroke(c);
f6af5a
a152ec ¤   return c;
d2efe6 }
5daf5a
280416 void kbFlush(int thorough)
8dbb36 {
4d43ab ¤   do {
ba9c6a ¤   ¤   while(_kbhit())
9aade4 ¤   ¤   ¤   (void)_getch();
a7b753 ¤   ¤   if (!thorough)
dccdcb ¤   ¤   ¤   break;
459878 ¤   ¤   /* Extra thorough: wait for one second of quiet */
31004a ¤   ¤   _sleep(1000);
b8da59 ¤   } while (_kbhit());
55efe6 }
bdaf5a
aa0c10 #if UNITTEST ···/* Self-contained test driver */
dcaf5a
1ab1cb #include <ctype.h>
fdaf5a
904d2f int
387f68 main(void)
fabb36 {
7cdd4c ····int c;
01af5a
efa1f0 ····puts("Going to cbreak mode...");
db5ef2 ····kbCbreak(0);
e775b0 ····puts("In cbreak mode. ·Please type.");
44c5ab ····for (;;) {
7c81fd ········c = kbGet();
--3151 0012de8c3194011003a Page 2 of pgpKBNT.c
7e447f ········if (c == '\n' || c == '\r')
fa8632 ············break;
2671e1 ········printf("c = %d = '%c'\n", c, c);
3ce977 ········kbFlush(isupper(c));
4a6fe7 ····}
44f02d ····puts("Returning to normal mode...");
a89d6f ····kbNorm();
d963c0 ····puts("Done.");
54958b ····return 0;
17efe6 }
51af5a
eabc6a #endif /* UNITTEST */
2daf5a
--7b51 000a80b37fd4011003b Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
9d1b82 // Used by PGPui.rc
06465d //
b0ad33 #define IDS_GENERAL ····················1
749b23 #define IDHELP ·························9
2db643 #define IDS_NOSIGNKEY ··················13
77112f #define IDS_RANDOMPROMPT ···············14
344801 #define IDS_RANDOMDONE ·················15
fd1507 #define IDS_RSA ························16
378346 #define IDS_DH ·························17
d876c1 #define IDS_UNKNOWN ····················18
ca7911 #define IDS_CAPTION ····················19
d0eb07 #define IDS_RECIPIENTWARNING ···········19
4d49da #define IDS_RSADSAMIXWARNING ···········27
52e859 #define IDS_ERRORMESSAGECAPTION ········57
28d019 #define IDS_NUMKEYS ····················57
58d704 #define IDD_PASSPHRASE ·················103
afe270 #define IDD_PASSPHRASEOPTIONS ··········105
7039e8 #define IDD_PASSPHRASEDECRYPTKEYS ······106
cec3c9 #define IDD_PASSPHRASEENCRYPT ··········107
286317 #define IDD_KEYRAND ····················108
986f50 #define IDS_PHRASEMISMATCH ·············121
e36e3a #define IDS_EMPTYPHRASE ················122
21d150 #define IDD_SERVERPROGRESS ·············126
eab608 #define IDS_WRONGPHRASE ················127
bc8662 #define IDS_UNKNOWNKEYS ················135
a2cf69 #define IDS_DSS ························137
79999c #define IDS_FOUNDMATCHFORPHRASE ········144
f0b568 #define IDS_PGP ························145
2a318f #define IDS_BADDECRYPTPHRASE ···········146
a001fe #define IDS_WRONGDECRYPTPHRASE ·········147
821245 #define IDS_KEYSNOTVALID ···············321
1d1b6b #define IDS_KEYSNOTFOUND ···············322
fd3650 #define IDS_MULTIPLEMATCH ··············323
388b36 #define IDS_DEFAULT ····················324
3b286d #define IDS_KEYSNOTCORPSIGNED ··········325
17bb8a #define IDS_ADKMISSING ·················326
f93761 #define IDS_KSCONNECTING ···············327
167598 #define IDS_KSSEARCHING ················328
9b5cd8 #define IDS_KSPROCESSING ···············329
e9e95f #define IDS_KSDELETING ·················330
b53b2f #define IDS_KSDISABLING ················331
ba9b3d #define IDS_KSCLOSINGSEND ··············332
ff9ee5 #define IDS_KSSENDING ··················333
53a4e5 #define IDS_NOKEYADKERR ················334
5825dc #define IDS_NOGROUPADKERR ··············335
01c129 #define IDS_NOKEYADKWARN ···············336
c9f743 #define IDS_NOGROUPADKWARN ·············337
6e34c9 #define IDS_MOVEDARRWARN ···············338
0bfa8c #define IDS_PGPERROR ···················339
0e4bc5 #define IDS_NUMUNKNOWNKEYS ·············340
f0fe0e #define IDS_PASSNOTLONG ················341
4fb513 #define IDS_PASSNOTQUALITY ·············342
c3fa6d #define IDS_BADPASSREENTER ·············343
1052c3 #define IDS_NUMOFNUMKEYS ···············344
5f5299 #define IDS_UNKNOWNKEYIDSTR ············345
3d2846 #define IDD_OPTIONSDIALOG ··············410
15b386 #define IDD_KEYPASSPHRASE ··············411
5065db #define IDB_IMAGES4BIT ·················412
475581 #define IDB_IMAGES24BIT ················413
24725d #define IDD_RECIPIENTDLG ···············414
6840cf #define IDR_MENU1 ······················416
d7a219 #define IDI_DLGICON ····················417
0ae98d #define IDC_PASSQBORDER ················1000
17120f #define IDC_CAPSWARNING ················1003
e039d9 #define IDC_STATICPASSQUAL ·············1004
d8a067 #define IDC_STATICMINQUAL ··············1005
88b55f #define IDC_BITSPROGBAR ················1011
fa77b8 #define IDC_PHRASE2 ····················1016
547b63 #define IDC_HIDETYPING ·················1021
a82c82 #define IDC_PROMPTSTRING ···············1029
--132c 001265e79854011003b Page 2 of resource.h
f924df #define IDC_PHRASEQUALITY ··············1045
3eb020 #define IDC_MINQUALITY ·················1046
8161f8 #define IDC_PROGRESS ···················1066
423b04 #define IDC_SIGNKEYCOMBO ···············1114
95fb81 #define IDC_BEGIN ······················1117
9b636a #define IDC_STATIC1 ····················1118
948c6a #define IDC_STATIC2 ····················1119
b9e65e #define IDC_STATIC3 ····················1120
5eca2d #define IDC_TEXTPROMPT ·················1121
7646d6 #define IDC_KEYLISTBOX ·················1137
8b8a89 #define IDC_PROGRESSTEXT ···············1138
caf008 #define IDC_CANNOTDECRYPTTEXT ··········1143
538e66 #define IDC_PHRASE1 ····················1239
c3f39d #define IDC_SPLITINFO ··················1242
fa8eeb #define IDC_KEYNAME ····················1243
dcf7d6 #define IDC_MSGTXT ·····················1248
de2f88 #define IDC_MSGTXTBORDER ···············1249
72b361 #define IDC_WARNCHECK ··················1250
4e48f7 #define IDC_WARNINGTEXT ················1251
ee570c #define IDC_ADKLIST ····················1254
143aee #define IDC_ADKQUERY ···················1255
8495e3 #define IDC_USER_ID_LIST ···············1256
8fa0db #define IDC_RECIPIENT_LIST ·············1257
2d36bf #define IDC_STATIC4 ····················1258
f07d2f #define IDC_STATIC5 ····················1259
b8b38b #define IDC_STATIC6 ····················1260
e7f81b #define IDC_STATIC7 ····················1261
f19661 #define IDM_LOOKUP ·····················40002
29d94d #define IDM_WHATSTHIS ··················40003
64af5a
1e11aa // Next default values for new objects
38ac6a //·
92f860 #ifdef APSTUDIO_INVOKED
283f23 #ifndef APSTUDIO_READONLY_SYMBOLS
5cd7cb #define _APS_NEXT_RESOURCE_VALUE ·······105
ac611c #define _APS_NEXT_COMMAND_VALUE ········40001
86a23c #define _APS_NEXT_CONTROL_VALUE ········1006
e71285 #define _APS_NEXT_SYMED_VALUE ··········101
507454 #endif
267454 #endif

--8272 000e59542c84011003c Page 1 of liblber.dsp
7478bf # Microsoft Developer Studio Project File - Name="liblber" - Package Owner=<4>
ade7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
848537 # ** DO NOT EDIT **
c7af5a
a1877a # TARGTYPE "Win32 (x86) Static Library" 0x0104
21af5a
c2b444 CFG=liblber - Win32 Debug
44894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
b65c35 !MESSAGE use the Export Makefile command and run
b96309 !MESSAGE·
d75a00 !MESSAGE NMAKE /f "liblber.mak".
1f6309 !MESSAGE·
b8cdb3 !MESSAGE You can specify a configuration when running NMAKE
bae013 !MESSAGE by defining the macro CFG on the command line. For example:
e66309 !MESSAGE·
896409 !MESSAGE NMAKE /f "liblber.mak" CFG="liblber - Win32 Debug"
a76309 !MESSAGE·
0d1dd7 !MESSAGE Possible choices for configuration are:
e86309 !MESSAGE·
769fe8 !MESSAGE "liblber - Win32 Release" (based on "Win32 (x86) Static Library")
57e796 !MESSAGE "liblber - Win32 Debug" (based on "Win32 (x86) Static Library")
ea6309 !MESSAGE·
ecaf5a
b43e63 # Begin Project
6db23f # PROP Scc_ProjName ""
02df4a # PROP Scc_LocalPath ""
7140a4 CPP=cl.exe
b6af5a
969c34 !IF ·"$(CFG)" == "liblber - Win32 Release"
50af5a
258243 # PROP BASE Use_MFC 0
fbe662 # PROP BASE Use_Debug_Libraries 0
f07d73 # PROP BASE Output_Dir "Release"
b06180 # PROP BASE Intermediate_Dir "Release"
344c81 # PROP BASE Target_Dir ""
5221ad # PROP Use_MFC 0
97b771 # PROP Use_Debug_Libraries 0
e7f310 # PROP Output_Dir "Release"
1e01a1 # PROP Intermediate_Dir "Release"
ecb6fa # PROP Target_Dir ""
554fa4 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD¶
1c9f26 ·/c
ab3643 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\include" /I "..\..\..\pgpcdk\pub\inclu¶
c53b90 de" /I "..\..\..\pgpcdk\priv\networklib\win32" /I "..\..\..\pgpcdk\win32" /I ".¶
3a9c02 .\..\..\pfl\common" /I "..\..\..\pfl\win32" /I "..\..\..\pfl\win32\pgpAsyncDNS"¶
1c7400 ·/I "..\pgpsockets" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "LDAP_DEBUG" /D "NE¶
b59653 EDPROTOS" /D "THREAD_NT_PTHREADS" /D "LDAP_LDBM" /D "LDBM_USE_DBBTREE21" /D UNF¶
4d6d68 INISHED_CODE_ALLOWED=0 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D PGPSOCKETSLDAP=1 /YX /F¶
a2cafa D /c
8118fc BSC32=bscmake.exe
497a24 # ADD BASE BSC32 /nologo
454f1b # ADD BSC32 /nologo
9a7a92 LIB32=link.exe -lib
fb629d # ADD BASE LIB32 /nologo
6157a2 # ADD LIB32 /nologo
6eaf5a
006c63 !ELSEIF ·"$(CFG)" == "liblber - Win32 Debug"
79af5a
0e8243 # PROP BASE Use_MFC 0
66ffba # PROP BASE Use_Debug_Libraries 1
da54b8 # PROP BASE Output_Dir "Debug"
86198a # PROP BASE Intermediate_Dir "Debug"
8f4c81 # PROP BASE Target_Dir ""
3c21ad # PROP Use_MFC 0
6eaea9 # PROP Use_Debug_Libraries 1
17ad22 # PROP Output_Dir "Debug"
0eb253 # PROP Intermediate_Dir "Debug\liblber"
0fb6fa # PROP Target_Dir ""
307248 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX¶
a910c2 ·/FD /c
301ab2 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\include" /I "..\..\..\pgpcdk\pub\¶
e5c17f include" /I "..\..\..\pgpcdk\priv\networklib\win32" /I "..\..\..\pgpcdk\win32" ¶
--efde 001b24d8cec4011003c Page 2 of liblber.dsp
aaff44 /I "..\..\..\pfl\common" /I "..\..\..\pfl\win32" /I "..\..\..\pfl\win32\pgpAsyn¶
ae99d9 cDNS" /I "..\pgpsockets" /D "_DEBUG" /D "LDAP_DEBUG" /D "WIN32" /D "_WINDOWS" /¶
6c39ca D "NEEDPROTOS" /D "THREAD_NT_PTHREADS" /D "LDAP_LDBM" /D "LDBM_USE_DBBTREE21" /¶
ef8e82 D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D PGPSOCKETSLDAP=1 /¶
b0bc4c YX /FD /c
3718fc BSC32=bscmake.exe
3f7a24 # ADD BASE BSC32 /nologo
fb4f1b # ADD BSC32 /nologo
c77a92 LIB32=link.exe -lib
f4629d # ADD BASE LIB32 /nologo
b957a2 # ADD LIB32 /nologo
5baf5a
1130ec !ENDIF·
eeaf5a
26b8a5 # Begin Target
b3af5a
0eefe5 # Name "liblber - Win32 Release"
1ed076 # Name "liblber - Win32 Debug"
96df4f # Begin Source File
32af5a
6d5c06 SOURCE=..\liblber\bprint.c
e86ccd # End Source File
3adf4f # Begin Source File
35af5a
c49554 SOURCE=..\liblber\decode.c
ab6ccd # End Source File
b0df4f # Begin Source File
a7af5a
6c7fc5 SOURCE=..\liblber\encode.c
296ccd # End Source File
a9df4f # Begin Source File
8aaf5a
8f3d3c SOURCE=..\liblber\io.c
466ccd # End Source File
c5df4f # Begin Source File
d7af5a
f567d7 SOURCE=..\liblber\Version.c
ec6ccd # End Source File
82e5cf # End Target
b2f262 # End Project
--f6c5 000d9be60bd4011003d Page 1 of libldap.dsp
9b1f27 # Microsoft Developer Studio Project File - Name="libldap" - Package Owner=<4>
88e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
aa8537 # ** DO NOT EDIT **
17af5a
a2877a # TARGTYPE "Win32 (x86) Static Library" 0x0104
08af5a
50e239 CFG=libldap - Win32 Debug
e6894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
ad5c35 !MESSAGE use the Export Makefile command and run
de6309 !MESSAGE·
468658 !MESSAGE NMAKE /f "libldap.mak".
a06309 !MESSAGE·
37cdb3 !MESSAGE You can specify a configuration when running NMAKE
5be013 !MESSAGE by defining the macro CFG on the command line. For example:
646309 !MESSAGE·
b5f2a0 !MESSAGE NMAKE /f "libldap.mak" CFG="libldap - Win32 Debug"
426309 !MESSAGE·
bf1dd7 !MESSAGE Possible choices for configuration are:
f16309 !MESSAGE·
0f19e6 !MESSAGE "libldap - Win32 Release" (based on "Win32 (x86) Static Library")
64f4e0 !MESSAGE "libldap - Win32 Debug" (based on "Win32 (x86) Static Library")
6b6309 !MESSAGE·
a9af5a
513e63 # Begin Project
c8b23f # PROP Scc_ProjName ""
b0df4a # PROP Scc_LocalPath ""
a840a4 CPP=cl.exe
a1af5a
3664b4 !IF ·"$(CFG)" == "libldap - Win32 Release"
bdaf5a
eb8243 # PROP BASE Use_MFC 0
b2e662 # PROP BASE Use_Debug_Libraries 0
ce7d73 # PROP BASE Output_Dir "Release"
e86180 # PROP BASE Intermediate_Dir "Release"
0b4c81 # PROP BASE Target_Dir ""
7521ad # PROP Use_MFC 0
06b771 # PROP Use_Debug_Libraries 0
2cf310 # PROP Output_Dir "Release"
5a01a1 # PROP Intermediate_Dir "Release"
60b6fa # PROP Target_Dir ""
f24fa4 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD¶
429f26 ·/c
7256b0 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\pgpcdk\priv\networklib\win32" /I¶
9c7a3c ·"..\libldap" /I "..\include" /I "..\pgpsockets" /I "..\..\..\pgpcdk\pub\includ¶
0d56b1 e" /I "..\..\..\pgpcdk\win32" /I "..\..\..\pfl\win32" /I "..\..\..\pfl\win32\pg¶
957108 pAsyncDNS" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\lthread" /I "..\\" ¶
4a6cf7 /I "..\..\..\pgpcdk\priv\networklib\keyserver" /D "WIN32" /D "NDEBUG" /D "_WIND¶
da8bb6 OWS" /D "LDAP_DEBUG" /D "NEEDPROTOS" /D "THREAD_NT_PTHREADS" /D "LDAP_LDBM" /D ¶
d0905a "LDBM_USE_DBBTREE21" /D UNFINISHED_CODE_ALLOWED=0 /D PGP_DEBUG=0 /D PGP_WIN32=1¶
26ff2e ·/D PGPSOCKETSLDAP=1 /D UNFINISHED_CODE_ALLOWED=1 /YX /FD /c
ed18fc BSC32=bscmake.exe
047a24 # ADD BASE BSC32 /nologo
c44f1b # ADD BSC32 /nologo
747a92 LIB32=link.exe -lib
8c629d # ADD BASE LIB32 /nologo
9957a2 # ADD LIB32 /nologo
35af5a
9bc457 !ELSEIF ·"$(CFG)" == "libldap - Win32 Debug"
cdaf5a
128243 # PROP BASE Use_MFC 0
3cffba # PROP BASE Use_Debug_Libraries 1
3354b8 # PROP BASE Output_Dir "Debug"
95198a # PROP BASE Intermediate_Dir "Debug"
6e4c81 # PROP BASE Target_Dir ""
f021ad # PROP Use_MFC 0
5aaea9 # PROP Use_Debug_Libraries 1
3ead22 # PROP Output_Dir "Debug"
264e9f # PROP Intermediate_Dir "Debug\libldap"
57b6fa # PROP Target_Dir ""
567248 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX¶
5610c2 ·/FD /c
d91afa # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\..\pgpcdk\priv\networklib\win3¶
--bb2d 00009082ed24011003d Page 2 of libldap.dsp
8a8333 2" /I "..\libldap" /I "..\include" /I "..\pgpsockets" /I "..\..\..\pgpcdk\pub\i¶
cba05a nclude" /I "..\..\..\pgpcdk\win32" /I "..\..\..\pfl\win32" /I "..\..\..\pfl\win¶
121b13 32\pgpAsyncDNS" /I "..\..\..\pfl\common" /I "..\..\..\pfl\common\lthread" /I ".¶
bdf503 .\\" /I "..\..\..\pgpcdk\priv\networklib\keyserver" /D "_DEBUG" /D "LDAP_DEBUG"¶
d07c44 ·/D "WIN32" /D "_WINDOWS" /D "NEEDPROTOS" /D "THREAD_NT_PTHREADS" /D "LDAP_LDBM¶
a3cf3a " /D "LDBM_USE_DBBTREE21" /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WI¶
915362 N32=1 /D PGPSOCKETSLDAP=1 /YX /FD /c
c418fc BSC32=bscmake.exe
a47a24 # ADD BASE BSC32 /nologo
744f1b # ADD BSC32 /nologo
eb7a92 LIB32=link.exe -lib
d5629d # ADD BASE LIB32 /nologo
cc57a2 # ADD LIB32 /nologo
8caf5a
3630ec !ENDIF·
22af5a
27b8a5 # Begin Target
55af5a
d51765 # Name "libldap - Win32 Release"
e77842 # Name "libldap - Win32 Debug"
7ddf4f # Begin Source File
68af5a
2b51b4 SOURCE=..\libldap\abandon.c
eb6ccd # End Source File
4bdf4f # Begin Source File
b9af5a
906f39 SOURCE=..\libldap\add.c
256ccd # End Source File
32df4f # Begin Source File
8caf5a
84edc3 SOURCE=..\libldap\addentry.c
236ccd # End Source File
09df4f # Begin Source File
1daf5a
5b5333 SOURCE=..\libldap\bind.c
216ccd # End Source File
10df4f # Begin Source File
e3af5a
ce2c4b SOURCE=..\libldap\cache.c
556ccd # End Source File
c6df4f # Begin Source File
9aaf5a
27e45f SOURCE=..\libldap\charset.c
916ccd # End Source File
b7df4f # Begin Source File
95af5a
e6e247 SOURCE=..\libldap\cldap.c
5e6ccd # End Source File
94df4f # Begin Source File
b8af5a
791004 SOURCE=..\libldap\compare.c
536ccd # End Source File
a3df4f # Begin Source File
9baf5a
0aa254 SOURCE=..\libldap\delete.c
dd6ccd # End Source File
d5df4f # Begin Source File
03af5a
6349d9 SOURCE=..\libldap\disptmpl.c
ef6ccd # End Source File
f3df4f # Begin Source File
80af5a
d3e57a SOURCE=..\libldap\dsparse.c
566ccd # End Source File
17df4f # Begin Source File
d5af5a
00ce9a SOURCE=..\libldap\error.c
bb6ccd # End Source File
00df4f # Begin Source File
e0af5a
9f0887 SOURCE=..\libldap\free.c
096ccd # End Source File
--7c30 000b97b98904011003d Page 3 of libldap.dsp
41df4f # Begin Source File
d0af5a
e6ed3f SOURCE=..\libldap\friendly.c
a56ccd # End Source File
eddf4f # Begin Source File
34af5a
9c60e0 SOURCE=..\libldap\getattr.c
636ccd # End Source File
93df4f # Begin Source File
4caf5a
b5bca7 SOURCE=..\libldap\getdn.c
d36ccd # End Source File
96df4f # Begin Source File
a2af5a
7ec59a SOURCE=..\libldap\getdxbyname.c
ad6ccd # End Source File
0adf4f # Begin Source File
45af5a
e7cb07 SOURCE=..\libldap\getentry.c
3d6ccd # End Source File
d0df4f # Begin Source File
c4af5a
a728ee SOURCE=..\libldap\getfilter.c
606ccd # End Source File
f1df4f # Begin Source File
72af5a
92c472 SOURCE=..\libldap\getopt.c
6f6ccd # End Source File
24df4f # Begin Source File
cbaf5a
87e256 SOURCE=..\libldap\getvalues.c
ab6ccd # End Source File
60df4f # Begin Source File
6daf5a
3ba7b4 SOURCE=..\libldap\kbind.c
c06ccd # End Source File
ecdf4f # Begin Source File
42af5a
f4aff5 SOURCE=..\libldap\modify.c
3c6ccd # End Source File
67df4f # Begin Source File
e5af5a
ea4268 SOURCE=..\libldap\modrdn.c
bf6ccd # End Source File
79df4f # Begin Source File
dbaf5a
9781fd SOURCE=..\libldap\open.c
f26ccd # End Source File
eedf4f # Begin Source File
0eaf5a
72cfad SOURCE="..\pgpsockets\pgpSockets-ip.c"
586ccd # End Source File
d0df4f # Begin Source File
eaaf5a
9cbd0c SOURCE=..\libldap\regex.c
fd6ccd # End Source File
9ddf4f # Begin Source File
7caf5a
2d5e0a SOURCE=..\libldap\request.c
046ccd # End Source File
08df4f # Begin Source File
ceaf5a
712628 SOURCE=..\libldap\result.c
fb6ccd # End Source File
3edf4f # Begin Source File
39af5a
18d170 SOURCE=..\libldap\sbind.c
426ccd # End Source File
b2df4f # Begin Source File
bfaf5a
20cb1f SOURCE=..\libldap\search.c
b96ccd # End Source File
--f6ef 001b27d50dd4011003d Page 4 of libldap.dsp
41df4f # Begin Source File
d0af5a
836104 SOURCE=..\libldap\sort.c
1f6ccd # End Source File
81df4f # Begin Source File
c6af5a
db80cd SOURCE=..\libldap\srchpref.c
b16ccd # End Source File
4bdf4f # Begin Source File
a6af5a
12aecb SOURCE=..\libldap\tmplout.c
4a6ccd # End Source File
b0df4f # Begin Source File
6caf5a
f3f703 SOURCE=..\libldap\ufn.c
186ccd # End Source File
19df4f # Begin Source File
27af5a
1be4d7 SOURCE=..\libldap\unbind.c
af6ccd # End Source File
80df4f # Begin Source File
50af5a
f85725 SOURCE=..\libldap\url.c
c36ccd # End Source File
17df4f # Begin Source File
1daf5a
907db5 SOURCE=..\libldap\Version.c
046ccd # End Source File
dce5cf # End Target
b2f262 # End Project

--3591 0017c4876a84011003e Page 1 of pgpMemLockWin32.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
799ed6 ¤   pgpMemLockWin32.h - header for Win32 PGPmemlock drivers
7c67c5 ¤
40af5a
0dbb6f ¤   $Id: pgpMemLockWin32.h,v 1.1.16.1 1998/11/12 03:20:15 heller Exp $
f1f7f7 ____________________________________________________________________________*/
76af5a
fce1fa #if ! PGP_WIN32
ef3306 #error this file should only be used for PGP_WIN32
977454 #endif
deaf5a
1f7551 /* driver-specific error codes */
a349f6 #define kPGPMemLockError_LockError¤ ¤   0x0001
98b371 #define kPGPMemLockError_UnlockError¤   0x0002
e3725a #define kPGPMemLockError_ListError¤ ¤   0x0003
f26bf4 #define kPGPMemLockError_AllocError¤¤   0x0004
46af5a
7f50a1 /* virtual memory paging in Win32 uses 4K byte pages (2^12) */
0bbe74 #define WIN32PAGESIZE¤  12¤
98af5a
c8cc88 /* Define the various device type values. ·Note that values used by Microsoft
7e7d52 ···Corporation are in the range 0-32767, and 32768-65535 are reserved for use
f369d4 ···by customers. */
1aaf5a
cb4534 #define FILE_DEVICE_PGPMEMLOCK ·0x00008000
d6af5a
d140bd /* Macro definition for defining IOCTL and FSCTL function control codes. ·Note
e83a69 ···that function codes 0-2047 are reserved for Microsoft Corporation, and
833b48 ···2048-4095 are reserved for customers. */
49af5a
65a6e7 #define PGPMEMLOCK_IOCTL_INDEX ·0x800
ffaf5a
a2bfff /* Define our own private IOCTL */
dbaf5a
96749b #define CTL_CODE( DeviceType, Function, Method, Access ) ( ················\
8cd68b ····((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
bf5b71 )
5e7596 #define METHOD_BUFFERED ················0
421bfa #define FILE_ANY_ACCESS ················0
81af5a
b1d2f4 #define IOCTL_PGPMEMLOCK_LOCK_MEMORY¤   CTL_CODE(FILE_DEVICE_PGPMEMLOCK, \
058153 ·················································PGPMEMLOCK_IOCTL_INDEX, ·\
83ae3d ·················································METHOD_BUFFERED, ····\
ab1975 ·················································FILE_ANY_ACCESS)
80af5a
a5744c #define IOCTL_PGPMEMLOCK_UNLOCK_MEMORY¤ CTL_CODE(FILE_DEVICE_PGPMEMLOCK, ·\
0bce4a ·················································PGPMEMLOCK_IOCTL_INDEX+1,\
7cae3d ·················································METHOD_BUFFERED, ····\
f31975 ·················································FILE_ANY_ACCESS)
fbaf5a
bc4b06 /* Our user mode app will pass an initialized structure like this
b78aff ···down to the VxD or kernel mode driver */
f4af5a
265475 #pragma pack(8)
0ef0f7 typedef struct {
727f51 ¤   PVOID¤  pMem;
98027d ¤   ULONG¤  ulNumBytes;
1a9725 ¤   ULONG¤  ulError;
5b3b3a } PGPMEMLOCKSTRUCT, *PPGPMEMLOCKSTRUCT;
7c5fec #pragma pack()
--75be 001727bfa124011003f Page 1 of pgpPFLConfig.h
a70335 /*____________________________________________________________________________
03b632 ¤   pgpPFLConfig.h ·(Win32 version)
f967c5 ¤
b1c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
d64b0f ¤   All rights reserved.
e367c5 ¤
a8d220 ¤   This file contains the Win32 version of the configuration file
d7a17a ¤   normally generated by the automatic configure script on Unix.
56af5a
8f9516 ¤   $Id: pgpPFLConfig.h,v 1.7.32.1 1998/11/12 03:20:16 heller Exp $
1ff7f7 ____________________________________________________________________________*/
bbebfc #ifndef Included_pgpPFLConfig_h¤/* [ */
8a0204 #define Included_pgpPFLConfig_h
6baf5a
7c01a3 #define HAVE_STDARG_H¤  1
143509 #define HAVE_STDLIB_H¤  1
d51e64 #define HAVE_SYS_STAT_H¤1
200ba7 #define HAVE_UNISTD_H¤  0
d3c0d0 #define HAVE_USHORT¤¤   0
861ef0 #define HAVE_UINT¤  ¤   0
80f6c1 #define HAVE_ULONG¤ ¤   0
e2a26e #define NO_LIMITS_H¤¤   0
4f45ad #define NO_POPEN¤   ¤   1
0baf5a
5d174a #if ·defined( __MWERKS__ )
42af5a
65d7a9 ¤   #define PGP_HAVE64¤ ¤   0
bf67c5 ¤
c867c5 ¤
2451d8 #elif defined( _MSC_VER )
efce71 ¤   #define PGP_HAVE64¤ ¤   1
86a772 ¤   typedef __int64¤¤   ¤   ¤   PGPInt64;
266c2f ¤   typedef unsigned __int64¤   PGPUInt64;
1767c5 ¤
d967c5 ¤
ab67c5 ¤
677454 #endif
60af5a
7caf5a
adaf5a
57af5a
1d519e #endif /* ] Included_pgpPFLConfig_h */
14af5a
c07e4d /*__Editor_settings____
0caf5a
0c4126 ¤   Local Variables:
567b17 ¤   tab-width: 4
080e6c ¤   End:
fe5f8c ¤   vi: ts=4 sw=4
8b9e9b ¤   vim: si
72d062 _____________________*/

--f36f 000ef69331a40110040 Page 1 of install.cpp
6e3599 /*------------------------------------------
accde4 ···browse32.c -- MyGetOpenFileName in DLL.
ff6d1f ··------------------------------------------*/
31af5a
815655 #include <windows.h>
f618a2 #include <windef.h>
2ff3cf #include <shlobj.h>
ec62da #include <ole2.h>
8daf5a
d7462b // Standard initialization function in 32-bit DLLs.
b36b1a BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
e1bb36 {
d37ac1 ¤   return (1);
03efe6 }
eeaf5a
73eddf extern "C"·
fabb36 {
bdb72b int PGPclStartMemLockDriver (VOID);
fe4c27 BOOL WINAPI MyGetOpenFileName32(HWND, LPSTR, LPSTR, LPSTR, LPSTR);
cee725 BOOL WINAPI MyBrowseForFolder32 (HWND, LPSTR);
2ca6cf UINT CALLBACK CenterOpenFileName (HWND, UINT, WPARAM, LPARAM);
b920ad INT CALLBACK CenterBrowseForFolder (HWND, UINT, LPARAM, LPARAM);
97efe6 }
0a43b9 //Struct for OPENFILENAME·
6d2a9c static OPENFILENAME ofn;
4a640f //Struct for SHBrowseForFolder
c0592f static BROWSEINFO bi;
36b518 BOOL bResult;
63af5a
52f993 //________________________________________
e7465d //
9f7b64 //¤ ¤   Callback function to hook into·
5f11db //¤ ¤   dialogs and position them centered.
9daf5a
82e1b7 UINT CALLBACK CenterOpenFileName (HWND hdlg,UINT uiMsg,
56a476 ¤   ¤   WPARAM wParam,LPARAM lParam)
c0bb36 {
737ea9 ¤   switch(uiMsg)
2dc7a1 ¤   {
1ddf25 ¤   ¤   case WM_INITDIALOG:
1e5b34 ¤   ¤   {
cfafc0 ¤   ¤   ¤   RECT rc;
81af5a
ad015a ¤   ¤   ¤   // center dialog on screen
668713 ¤   ¤   ¤   GetWindowRect(GetParent(hdlg), &rc);
2aa7db ¤   ¤   ¤   SetWindowPos(GetParent(hdlg), NULL,
480971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
e2004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
5b6a71 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW );
5eaf5a
e73337 ¤   ¤   ¤   //szClientInstaller = (char *) lParam;
447f5b ¤   ¤   ¤   //SetWindowText(GetDlgItem(hwndDlg, IDC_CLIENTINSTALL),
603bba ¤   ¤   ¤   //¤ szClientInstaller);
e0af5a
ffcdcb ¤   ¤   ¤   break;
d70fe4 ¤   ¤   }
8d9371 ¤   }
8bc2e7 ¤   return TRUE;
25efe6 }
a1af5a
34ce70 INT CALLBACK CenterBrowseForFolder (HWND hdlg,UINT uiMsg,
59baa8 ¤   ¤   LPARAM lParam,LPARAM lpData)
a2bb36 {
e6c357 int ¤   error;
3daf5a
417ea9 ¤   switch(uiMsg)
a3c7a1 ¤   {
58019b ¤   ¤   case BFFM_INITIALIZED:
da5b34 ¤   ¤   {
e4afc0 ¤   ¤   ¤   RECT rc;
80af5a
ef015a ¤   ¤   ¤   // center dialog on screen
--e6d2 000d0b9c65240110040 Page 2 of install.cpp
f089d2 ¤   ¤   ¤   error = GetWindowRect(hdlg, &rc);
433415 ¤   ¤   ¤   //if (error == 0)
89d37f ¤   ¤   ¤   //¤ MessageBox(NULL, "ERROR", "Test", MB_OK);
87af5a
2fa038 ¤   ¤   ¤   error = SetWindowPos(hdlg, NULL,
6a0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
05004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
a525c6 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
1c87c7 ¤   ¤   ¤
1b3b32 ¤   ¤   ¤   //Error Code Formating
b43415 ¤   ¤   ¤   //if (error == 0)
da016e ¤   ¤   ¤   //{
9ee5e2 ¤   ¤   ¤   //¤ LPVOID lpMessageBuffer;
87d927 ¤   ¤   ¤   //¤ FormatMessage(
7beeaa ¤   ¤   ¤   //¤ FORMAT_MESSAGE_ALLOCATE_BUFFER |
c607e3 ¤   ¤   ¤   //¤ FORMAT_MESSAGE_FROM_SYSTEM,
9e1480 ¤   ¤   ¤   //¤ NULL,
396285 ¤   ¤   ¤   //¤ GetLastError(),
e9b5c0 ¤   ¤   ¤   //¤ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
4a3775 ¤   ¤   ¤   //¤ (LPTSTR) &lpMessageBuffer,
0669df ¤   ¤   ¤   //¤ 0,
7d5c52 ¤   ¤   ¤   //¤ NULL );
38af5a
ceb3d4 ¤   ¤   ¤   ¤   // display this string
de13a4 ·¤  ¤   ¤   //¤ MessageBox(NULL, (char*)lpMessageBuffer, "",
7258c8 ·¤  ¤   ¤   // ·MB_OK|MB_ICONWARNING);
1aaf5a
b895f2 ¤   ¤   ¤   ¤   // Free the buffer allocated by the system
27ae06 ¤   ¤   ¤   //¤ LocalFree( lpMessageBuffer );
3355be ¤   ¤   ¤   //}
71af5a
c8cdcb ¤   ¤   ¤   break;
d40fe4 ¤   ¤   }
4a9371 ¤   }
15c2e7 ¤   return TRUE;
51efe6 }
ebaf5a
29f993 //________________________________________
be465d //
a15203 //¤ ¤   Function to supply us with a 95/NT
30084b //¤ ¤   looking Browse dialog for browseing
297e6d //¤ ¤   to folders in Installshield
e1af5a
e410ed BOOL WINAPI MyBrowseForFolder32 (HWND hwnd, LPSTR lpszTitle)
a3c7a1 ¤   {
9c7503 ¤   LPMALLOC pMalloc;
940b49 ¤   LPITEMIDLIST pidlInstallDir;
173684 ¤   char szInstallDir[MAX_PATH];
34c1a4 ¤   int nDirLength;
c3f3fa ¤   SHGetMalloc(&pMalloc);
feaf5a
169b65 ¤   bi.hwndOwner = hwnd;
898b1e ¤   bi.pidlRoot = NULL;
439d58 ¤   bi.pszDisplayName = szInstallDir;
c3fdca ¤   bi.lpszTitle = lpszTitle;
09565a ¤   bi.ulFlags = 0;
5f555d ¤   bi.lpfn = CenterBrowseForFolder;
f53c28 ¤   bi.lParam = 0;
5367c5 ¤
716d8d ¤   pidlInstallDir = SHBrowseForFolder(&bi);
5eaf5a
e0a2d2 ¤   if (pidlInstallDir != NULL)
025b34 ¤   ¤   {
858c4e ¤   ¤   SHGetPathFromIDList(pidlInstallDir, lpszTitle);
603b25 ¤   ¤   nDirLength = strlen(lpszTitle);
bd1b52 ¤   ¤
12bf0e ¤   ¤   pMalloc->Free(pidlInstallDir);
2c0fe4 ¤   ¤   }
c4c2e7 ¤   return TRUE;
889371 ¤   }
daaf5a
d0f993 //________________________________________
--7a52 0002c65440e40110040 Page 3 of install.cpp
c1465d //
815007 //¤ ¤   Initialize function for
f03738 //¤ ¤   MyGetOpenFileName32.
ceaf5a
c2c40e void MyGetOpenFileNameInit ()
62c7a1 ¤   {
ed499c ¤   UINT uiMsg;
e22a51 ¤   HWND hdlg;
f23755 ¤   WPARAM wParam;
f0e0a9 ¤   LPARAM lParam;
f1af5a
39e95b ¤   static char *szFilter[] = {"All Files", "*.*", ""} ;
06af5a
537ad1 ¤   ofn.lStructSize ······= sizeof (OPENFILENAME) ;
6550ce ¤   ofn.hwndOwner ········= NULL ;
af829c ¤   ofn.hInstance ········= NULL ;
065f16 ¤   ofn.lpstrFilter ······= szFilter [0] ;
e391f5 ¤   ofn.lpstrCustomFilter = NULL ;
654932 ¤   ofn.nMaxCustFilter ···= 0 ;
a13ce3 ¤   ofn.nFilterIndex ·····= 0 ;
cf1e34 ¤   ofn.lpstrFile ········= NULL ; ·········// Set in Open and Close functions
156de1 ¤   ofn.nMaxFile ·········= _MAX_PATH ;
c1f47a ¤   ofn.lpstrFileTitle ···= NULL ; ·········// Set in Open and Close functions
65e948 ¤   ofn.nMaxFileTitle ····= _MAX_FNAME + _MAX_EXT ;
a4da8e ¤   ofn.lpstrInitialDir ··= NULL ;
f7ce82 ¤   ofn.lpstrTitle ·······= NULL ;
4c794c ¤   ofn.Flags ············= 0 ; ············// Set in Open and Close functions
276462 ¤   ofn.nFileOffset ······= 0 ;
2a69c3 ¤   ofn.nFileExtension ···= 0 ;
60c961 ¤   ofn.lpstrDefExt ······= NULL ;
60e1f3 ¤   ofn.lCustData ········= 0L ;
94c58d ¤   ofn.lpfnHook ·········= CenterOpenFileName;
f9e036 ¤   ofn.lpTemplateName ···= NULL ;
b5af5a
cd0c7a ¤   //MessageBox(NULL, "In MyGetOpenFileNameInit", "Test", MB_OK);
369371 ¤   }
5baf5a
54f993 //________________________________________
e0465d //
e55203 //¤ ¤   Function to supply us with a 95/NT
b1084b //¤ ¤   looking Browse dialog for browseing
6ff8a2 //¤ ¤   to files in Installshield.
f1af5a
dbf495 BOOL WINAPI MyGetOpenFileName32(HWND hwnd, LPSTR lpstrFileFilter, \
161426 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPSTR lpstrFileName, LPSTR lpstrDlgTitle, \
57bfb9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPSTR lpstrExt)
1aac78 ·····{
0d1560 ·····MyGetOpenFileNameInit();
57af5a
e4a80a ·····if (hwnd)
aa1e46 ¤   ¤   ofn.hwndOwner = hwnd;
39af5a
0edfd4 ¤   ·if (lpstrFileFilter[0] != '\0')
3f49f8 ·····¤  ofn.lpstrFilter = lpstrFileFilter ;
99af5a
1a3d34 ·····ofn.lpstrFile = lpstrFileName ;
ffaf5a
1041e6 ·····if (lpstrDlgTitle[0] != '\0')
3ab3e0 ·····¤  ofn.lpstrTitle = lpstrDlgTitle ;
45af5a
36ac9b ·····ofn.Flags = OFN_HIDEREADONLY | OFN_ENABLEHOOK | OFN_EXPLORER;
13af5a
ef25ba ·····if (lpstrExt[0] != '\0')
d2e9af ·····¤  ofn.lpstrDefExt = lpstrExt ;
e7af5a
3d7a33 ¤   ·OleInitialize(NULL);·
b4af5a
0c2553 ·····bResult = GetOpenFileName (&ofn) ;
041b52 ¤   ¤
a5b014 ¤   ·OleUninitialize();
20af5a
2c4d9f ¤   ·return bResult;
--59e3 00073b4621040110040 Page 4 of install.cpp
7af8a8 ·····}
5aaf5a
3eaf5a
b8f993 //________________________________________
88465d //
47a655 //¤ ¤   code to start PGPmemlock driver in NT
3865e4 //¤ ¤   driver must already have been copied to·
adce4d //¤ ¤   c:\winnt\system32\drivers directory.
94af5a
517156 #define DRIVERNAME¤ ¤   ¤   ¤   "PGPmemlock"
672e7a #define DRIVER_NO_ERROR¤¤   ¤   0
236b91 #define DRIVER_NOT_WINNT¤   ¤   1
78c10e #define DRIVER_ACCESS_ERROR¤¤   2
fd3e4c #define DRIVER_CREATE_FAIL¤ ¤   3
88b8b7 #define DRIVER_ALREADY_STARTED¤ 4
fe8178 #define DRIVER_MISC_ERROR¤  ¤   5
f3ce6b #define UNKNOWN_ERROR¤  ¤   ¤   6
ceaf5a
3efb27 ·int PGPclStartMemLockDriver (VOID)
7fbb36 {
b4e234 ¤   int¤¤   ¤   ¤   err ········= UNKNOWN_ERROR;
d25232 ¤   SC_HANDLE¤  ¤   schSCMan¤   = NULL;
594e79 ¤   SC_HANDLE¤  ¤   schServ¤¤   = NULL;
4d6bc0 ¤   DWORD¤  ¤   ¤   dwErr;
731be7 ¤   BOOL¤   ¤   ¤   bRet;
033731 ¤   OSVERSIONINFO¤  osid;
9f8345 ¤   SERVICE_STATUS¤ ss;
e7a88e ¤   CHAR¤   ¤   ¤   szPath[MAX_PATH];
7faf5a
01fcd3 ¤   // check if we're running under NT
3ece5f ¤   osid.dwOSVersionInfoSize = sizeof (osid);
be6d53 ¤   GetVersionEx (&osid);
c0af5a
aa72bc ¤   // no => just stop here
ee5486 ¤   if (osid.dwPlatformId != VER_PLATFORM_WIN32_NT) {
fe4aff ¤   ¤   err = DRIVER_NOT_WINNT;
2d262d ¤   ¤   goto done;
879371 ¤   }
b1af5a
6b9b20 ¤   // yes, open service control manager
de06ed ¤   schSCMan = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE);
f2c72c ¤   if (schSCMan == NULL) {
af872a ¤   ¤   dwErr = GetLastError();
c52848 ¤   ¤   if (dwErr == ERROR_ACCESS_DENIED) {
d43518 ¤   ¤   ¤   err = DRIVER_ACCESS_ERROR;
9e1dc4 ¤   ¤   ¤   goto done;
2f0fe4 ¤   ¤   }
9907e0 ¤   ¤   else {
b08d58 ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
301dc4 ¤   ¤   ¤   goto done;
000fe4 ¤   ¤   }
cf9371 ¤   }
b2cc3e ¤   // OK, success open of service control manager
9e665a ¤   else {
5de622 ¤   ¤   // try to open service
f3a511 ¤   ¤   schServ = OpenService (schSCMan, DRIVERNAME,·
8bf6dc ¤   ¤   ¤   ¤   ¤   ¤   SERVICE_START|SERVICE_QUERY_STATUS);
b6af5a
82708c ¤   ¤   if (schServ == NULL) {
43d1be ¤   ¤   ¤   // couldn't open service
15c521 ¤   ¤   ¤   dwErr = GetLastError ();
6e6d25 ¤   ¤   ¤   if (dwErr != ERROR_SERVICE_DOES_NOT_EXIST) {
c188b5 ¤   ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
8dff25 ¤   ¤   ¤   ¤   goto done;
85a3a6 ¤   ¤   ¤   }
f6af5a
58594c ¤   ¤   ¤   // try to create new service ...
c1baf4 ¤   ¤   ¤   GetSystemDirectory (szPath, sizeof(szPath));
440904 ¤   ¤   ¤   if (szPath[lstrlen (szPath) -1] != '\\')
8f4a95 ¤   ¤   ¤   ¤   lstrcat (szPath, "\\");
784502 ¤   ¤   ¤   lstrcat (szPath, "drivers\\");
73e35b ¤   ¤   ¤   lstrcat (szPath, DRIVERNAME);
--fd26 001515b7c9440110040 Page 5 of install.cpp
e43077 ¤   ¤   ¤   lstrcat (szPath, ".sys");
35bbf3 ¤   ¤   ¤   schServ = CreateService (schSCMan, DRIVERNAME, DRIVERNAME,
cd6a14 ¤   ¤   ¤   ¤   ¤   ¤   SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
7acc3f ¤   ¤   ¤   ¤   ¤   ¤   SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
f854d5 ¤   ¤   ¤   ¤   ¤   ¤   szPath, NULL, NULL, NULL, NULL, NULL);
d2af5a
67fcf3 ¤   ¤   ¤   if (schServ == NULL) {
e42de1 ¤   ¤   ¤   ¤   err = DRIVER_CREATE_FAIL;
caff25 ¤   ¤   ¤   ¤   goto done;
d2a3a6 ¤   ¤   ¤   }
d20fe4 ¤   ¤   }
97af5a
c6c9ef ¤   ¤   bRet = QueryServiceStatus (schServ, &ss);
561413 ¤   ¤   if (!bRet) {
478d58 ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
c31dc4 ¤   ¤   ¤   goto done;
d00fe4 ¤   ¤   }
9a9f65 ¤   ¤   if (ss.dwCurrentState == SERVICE_STOPPED) {
d024da ¤   ¤   ¤   bRet = StartService (schServ, 0, NULL);
c0a5c2 ¤   ¤   ¤   if (!bRet) {
a4c0cc ¤   ¤   ¤   ¤   dwErr = GetLastError ();
e388b5 ¤   ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
9eff25 ¤   ¤   ¤   ¤   goto done;
93a3a6 ¤   ¤   ¤   }
540fe4 ¤   ¤   }
5c07e0 ¤   ¤   else {
fa72a7 ¤   ¤   ¤   err = DRIVER_ALREADY_STARTED;
781dc4 ¤   ¤   ¤   goto done;
930fe4 ¤   ¤   }
fd9371 ¤   }
0d4929 ¤   err = DRIVER_NO_ERROR;
ffaf5a
76a1c0 done :
5747a1 ¤   // cleanup service handle
94a967 ¤   if (schServ)
91c0d2 ¤   ¤   CloseServiceHandle (schServ);
cdaf5a
ea5c26 ¤   // clean up service control manager
6a8c55 ¤   if (schSCMan)
c7c14f ¤   ¤   CloseServiceHandle (schSCMan);
0eaf5a
f25ea8 ¤   return err;
51be43 }¶
--da1a 0016b7b4a8140110041 Page 1 of install.def
ef86c0 LIBRARY ········INSTALL
c1fc70 CODE ···········PRELOAD MOVEABLE DISCARDABLE
6be7c2 DATA ···········PRELOAD MOVEABLE SINGLE
f8af5a
24cca8 HEAPSIZE ·······4096
9faf5a
f9ef2b EXPORTS
0c7248 ····MyGetOpenFileName32
d9c4f1 ¤   MyBrowseForFolder32
6bcefe ¤   PGPclStartMemLockDriver¶
--e2d3 000fad2716040110042 Page 1 of install.dsp
01b5ec # Microsoft Developer Studio Project File - Name="install" - Package Owner=<4>
97e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
ea8537 # ** DO NOT EDIT **
29af5a
75a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
7eaf5a
41f4f5 CFG=install - Win32 Debug
fd894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
775c35 !MESSAGE use the Export Makefile command and run
906309 !MESSAGE·
7dbf59 !MESSAGE NMAKE /f "install.mak".
116309 !MESSAGE·
02cdb3 !MESSAGE You can specify a configuration when running NMAKE
b0e013 !MESSAGE by defining the macro CFG on the command line. For example:
986309 !MESSAGE·
67ed6d !MESSAGE NMAKE /f "install.mak" CFG="install - Win32 Debug"
2f6309 !MESSAGE·
9c1dd7 !MESSAGE Possible choices for configuration are:
506309 !MESSAGE·
e8fd8a !MESSAGE "install - Win32 Release" (based on\
c617ca ·"Win32 (x86) Dynamic-Link Library")
6f2f9f !MESSAGE "install - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
636309 !MESSAGE·
c8af5a
f33e63 # Begin Project
76b23f # PROP Scc_ProjName ""
d1df4a # PROP Scc_LocalPath ""
fb40a4 CPP=cl.exe
0ca46a MTL=midl.exe
222e1f RSC=rc.exe
5caf5a
130acc !IF ·"$(CFG)" == "install - Win32 Release"
d2af5a
4a8243 # PROP BASE Use_MFC 0
eae662 # PROP BASE Use_Debug_Libraries 0
977d73 # PROP BASE Output_Dir "Release"
5c6180 # PROP BASE Intermediate_Dir "Release"
ba4c81 # PROP BASE Target_Dir ""
4621ad # PROP Use_MFC 0
b3b771 # PROP Use_Debug_Libraries 0
f6f310 # PROP Output_Dir "Release"
9001a1 # PROP Intermediate_Dir "Release"
57b6fa # PROP Target_Dir ""
c8c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
2b10c2 ·/FD /c
5049f8 # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD ¶
47a99b /c
f11e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
f06d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
d0b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
f5de84 # ADD RSC /l 0x409 /d "NDEBUG"
4518fc BSC32=bscmake.exe
d97a24 # ADD BASE BSC32 /nologo
324f1b # ADD BSC32 /nologo
4e268f LINK32=link.exe
4bcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
00a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
e65e3b ·/nologo /subsystem:windows /dll /machine:I386
c0700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
7d1e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
886226 ogo /subsystem:windows /dll /machine:I386
74af5a
34c821 !ELSEIF ·"$(CFG)" == "install - Win32 Debug"
68af5a
5e8243 # PROP BASE Use_MFC 0
59ffba # PROP BASE Use_Debug_Libraries 1
a354b8 # PROP BASE Output_Dir "Debug"
e8198a # PROP BASE Intermediate_Dir "Debug"
8c4c81 # PROP BASE Target_Dir ""
1f21ad # PROP Use_MFC 0
22aea9 # PROP Use_Debug_Libraries 1
faad22 # PROP Output_Dir "Debug"
--235b 0013d48041e40110042 Page 2 of install.dsp
77b954 # PROP Intermediate_Dir "Debug"
f7b6fa # PROP Target_Dir ""
3a6cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
621fea DOWS" /YX /FD /c
c3a40f # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
da50ba ·/YX /FD /c
99c0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
c8b3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
5b699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
100443 # ADD RSC /l 0x409 /d "_DEBUG"
cc18fc BSC32=bscmake.exe
b07a24 # ADD BASE BSC32 /nologo
824f1b # ADD BSC32 /nologo
2c268f LINK32=link.exe
20cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
dba5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
3717bf ·/nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
54700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
051e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
a5218a ogo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
c2af5a
8d30ec !ENDIF·
27af5a
fdb8a5 # Begin Target
54af5a
14791d # Name "install - Win32 Release"
9f7434 # Name "install - Win32 Debug"
aedf4f # Begin Source File
b3af5a
d594a4 SOURCE=.\install.cpp
ef6ccd # End Source File
eddf4f # Begin Source File
caaf5a
7ebeec SOURCE=.\install.def
a76ccd # End Source File
d5e5cf # End Target
3df262 # End Project
--4e9e 001a85c21fe40110043 Page 1 of install.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
7e8f41 Project: "install"=".\install.dsp" - Package Owner=<4>
0faf5a
24e41b Package=<5>
828818 {{{
cc418b }}}
0aaf5a
46bec7 Package=<4>
878818 {{{
bb418b }}}
91af5a
092d94 ###############################################################################
bbaf5a
3d20da Global:
4daf5a
5ee41b Package=<5>
358818 {{{
c3418b }}}
b7af5a
d032c2 Package=<3>
878818 {{{
51418b }}}
beaf5a
3b2d94 ###############################################################################
a8af5a

--2065 00098b8d90240110044 Page 1 of PGPmemlock.dsp
b6ca34 # Microsoft Developer Studio Project File - Name="PGPmemlock" - Package Owner=<¶
bc6627 4>
92e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
4d8537 # ** DO NOT EDIT **
54af5a
c8669e # TARGTYPE "Win32 (x86) External Target" 0x0106
4eaf5a
5d641b CFG=PGPmemlock - Win32 Debug
81894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
205c35 !MESSAGE use the Export Makefile command and run
eb6309 !MESSAGE·
a0fd1e !MESSAGE NMAKE /f "PGPmemlock.mak".
686309 !MESSAGE·
4ecdb3 !MESSAGE You can specify a configuration when running NMAKE
93e013 !MESSAGE by defining the macro CFG on the command line. For example:
5a6309 !MESSAGE·
7e8c17 !MESSAGE NMAKE /f "PGPmemlock.mak" CFG="PGPmemlock - Win32 Debug"
996309 !MESSAGE·
521dd7 !MESSAGE Possible choices for configuration are:
4f6309 !MESSAGE·
8bcdea !MESSAGE "PGPmemlock - Win32 Release" (based on "Win32 (x86) External Target")
7da60c !MESSAGE "PGPmemlock - Win32 Debug" (based on "Win32 (x86) External Target")
bb6309 !MESSAGE·
39af5a
d73e63 # Begin Project
e0b23f # PROP Scc_ProjName ""
97df4a # PROP Scc_LocalPath ""
e3af5a
7d066f !IF ·"$(CFG)" == "PGPmemlock - Win32 Release"
60af5a
c7e662 # PROP BASE Use_Debug_Libraries 0
987d73 # PROP BASE Output_Dir "Release"
136180 # PROP BASE Intermediate_Dir "Release"
d74746 # PROP BASE Cmd_Line "NMAKE /f PGPmemlock.mak"
ec0e97 # PROP BASE Rebuild_Opt "/a"
52e467 # PROP BASE Target_File "PGPmemlock.vxd"
1f2a6e # PROP BASE Bsc_Name "PGPmemlock.bsc"
d94c81 # PROP BASE Target_Dir ""
5fb771 # PROP Use_Debug_Libraries 0
7df310 # PROP Output_Dir "Release"
9301a1 # PROP Intermediate_Dir "Release"
705fe3 # PROP Cmd_Line "NMAKE /f PGPmemlock.mak CFG="PGPmemlock - Win32 Release""
f32691 # PROP Rebuild_Opt "/a"
93bd8a # PROP Target_File "PGPmemlock.vxd"
80153d # PROP Bsc_Name "PGPmemlock.bsc"
5eb6fa # PROP Target_Dir ""
6baf5a
79a124 !ELSEIF ·"$(CFG)" == "PGPmemlock - Win32 Debug"
dbaf5a
91ffba # PROP BASE Use_Debug_Libraries 1
2f54b8 # PROP BASE Output_Dir "Debug"
e4198a # PROP BASE Intermediate_Dir "Debug"
3c4746 # PROP BASE Cmd_Line "NMAKE /f PGPmemlock.mak"
710e97 # PROP BASE Rebuild_Opt "/a"
fce467 # PROP BASE Target_File "PGPmemlock.vxd"
bc2a6e # PROP BASE Bsc_Name "PGPmemlock.bsc"
7a4c81 # PROP BASE Target_Dir ""
79aea9 # PROP Use_Debug_Libraries 1
f3ad22 # PROP Output_Dir "Debug"
dbb954 # PROP Intermediate_Dir "Debug"
c20866 # PROP Cmd_Line "NMAKE /f PGPmemlock.mak CFG="PGPmemlock - Win32 Debug""
db2691 # PROP Rebuild_Opt "/a"
f0bd8a # PROP Target_File "PGPmemlock.vxd"
4c153d # PROP Bsc_Name "PGPmemlock.bsc"
59b6fa # PROP Target_Dir ""
6daf5a
ec30ec !ENDIF·
01af5a
afb8a5 # Begin Target
28af5a
3d0910 # Name "PGPmemlock - Win32 Release"
988ec2 # Name "PGPmemlock - Win32 Debug"
--645f 0016e71d4ab40110044 Page 2 of PGPmemlock.dsp
e0af5a
5e066f !IF ·"$(CFG)" == "PGPmemlock - Win32 Release"
4baf5a
e7a124 !ELSEIF ·"$(CFG)" == "PGPmemlock - Win32 Debug"
c6af5a
fc30ec !ENDIF·
63af5a
bf1d6b # Begin Group "Source"
b9af5a
f2b050 # PROP Default_Filter ""
d0df4f # Begin Source File
caaf5a
fdd90e SOURCE=.\Source\pgpMemLock.c
3d6ccd # End Source File
4cdf4f # Begin Source File
a5af5a
965728 SOURCE=.\Source\pgpMemLock.def
236ccd # End Source File
addf4f # Begin Source File
33af5a
89481b SOURCE=.\Source\pgpMLdevdcl.asm
aa6ccd # End Source File
463f5a # End Group
4fdf4f # Begin Source File
86af5a
44a36e SOURCE=.\PGPmemlock.mak
f66ccd # End Source File
2ce5cf # End Target
6ef262 # End Project
--c6be 00174812b1e40110045 Page 1 of PGPmemlock.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
3d4c0f Project: "PGPmemlock"=.\PGPmemlock.dsp - Package Owner=<4>
33af5a
32e41b Package=<5>
0b8818 {{{
80418b }}}
e8af5a
7abec7 Package=<4>
d68818 {{{
0a418b }}}
1caf5a
f52d94 ###############################################################################
a4af5a
a420da Global:
c2af5a
7de41b Package=<5>
608818 {{{
de418b }}}
e2af5a
fb32c2 Package=<3>
ad8818 {{{
12418b }}}
80af5a
302d94 ###############################################################################
74af5a
--1a42 0009289cc3f40110046 Page 1 of PGPmemlock.mak
db0416 # PGPmemlock.mak - makefile for VxD driver for secure memory locking
430fdb !IF "$(CFG)" == ""
4e641b CFG=PGPmemlock - Win32 Debug
762409 !MESSAGE No configuration specified. Defaulting to PGPmemlock - Win32 Debug.
2c30ec !ENDIF·
69af5a
1b1992 !IF "$(CFG)" != "PGPmemlock - Win32 Release" && "$(CFG)" != "PGPmemlock - Win32¶
1b349a ·Debug"
16dcc8 !MESSAGE Invalid configuration "$(CFG)" specified.
8ecdb3 !MESSAGE You can specify a configuration when running NMAKE
31e013 !MESSAGE by defining the macro CFG on the command line. For example:
2b6309 !MESSAGE·
508c17 !MESSAGE NMAKE /f "PGPmemlock.mak" CFG="PGPmemlock - Win32 Debug"
3d6309 !MESSAGE·
bb1dd7 !MESSAGE Possible choices for configuration are:
716309 !MESSAGE·
a6e587 !MESSAGE "PGPmemlock - Win32 Release"
77e175 !MESSAGE "PGPmemlock - Win32 Debug"
376309 !MESSAGE·
95582c !ERROR An invalid configuration is specified.
7030ec !ENDIF·
32af5a
67f32b !IF "$(OS)" == "Windows_NT"
8ae393 NULL=
7b4b3e !ELSE·
e5942e NULL=nul
3c30ec !ENDIF·
dcaf5a
b540a4 CPP=cl.exe
abfcba CC=cl.exe
b2268f LINK32=link.exe
50af5a
06c974 DEF_FILE= ¤ .\Source\pgpMemLock.def
3caf5a
af9f82 # edit these two lines to reflect your MASM and DDK installations
0863ca AS=c:\masm611\bin\ml
2b2792 DDKPATH=c:\ddk
eaaf5a
01db6d # edit this line to point to your 16bit version of the resource
7adc6a # compiler. ·MUST BE THE 16BIT VERSION!!! ·The 16bit version comes
cce305 # with the Win32 SDK in the BINW16 directory
84af5a
8a066f !IF ·"$(CFG)" == "PGPmemlock - Win32 Release"
28af5a
ab3ed1 OBJPATH=.\Release
751277 AFLAGS= -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -DMASM6·
3fe5b2 CFLAGS= -c -Gs -Zdpl -Od -D_X86_ -YX -W3 -DBLD_COFF -DIS_32
331e49 CPPFLAGS= -c -Gs -Zdpl -Odb2 -D_X86_ -YX -W3 -DBLD_COFF -DIS_32·
6bccf6 RSCFLAGS= -r·
e502a6 LINK32_FLAGS= \
4df5ca -machine:i386 -def:"$(DEF_FILE)" -out:"$(OBJPATH)\PGPmemlock.vxd" \
67998b -map:"$(OBJPATH)\PGPmemlock.map" \
fb1ae5 -vxd $(DDKPATH)\lib\vxdwraps.clb -nodefaultlib
c1af5a
74a124 !ELSEIF ·"$(CFG)" == "PGPmemlock - Win32 Debug"
eaaf5a
c754f5 OBJPATH=.\Debug
1f2877 AFLAGS= -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -DMASM6 -Zd -DDEBUG
f9cde7 CFLAGS= -c -Gs -Zdpl -Od -D_X86_ -YX -W3 -DDEBLEVEL=1 -DBLD_COFF -DDEBUG -DIS_32
108685 CPPFLAGS= -c -Gs -Zdpl -Odb2 -D_X86_ -YX -W3 -DDEBLEVEL=1 -DBLD_COFF -DDEBUG -D¶
6e57a8 IS_32·
07c40e RSCFLAGS= -r
8e02a6 LINK32_FLAGS= \
d5f5ca -machine:i386 -def:"$(DEF_FILE)" -out:"$(OBJPATH)\PGPmemlock.vxd" \
07d630 -debug -debugtype:map -map:"$(OBJPATH)\PGPmemlock.map" \
831ae5 -vxd $(DDKPATH)\lib\vxdwraps.clb -nodefaultlib
86af5a
5130ec !ENDIF·
ddaf5a
a18879 ALL : "$(OBJPATH)\PGPmemlock.vxd"
0eaf5a
921acb CLEAN :
--e8ad 00014916a5c40110046 Page 2 of PGPmemlock.mak
974ee1 ¤   -@erase "$(OBJPATH)\PGPmemlock.exp"
7251db ¤   -@erase "$(OBJPATH)\pgpMemLock.obj"
a6cf96 ¤   -@erase "$(OBJPATH)\pgpMLdevdcl.obj"
2bb84d ¤   -@erase "$(OBJPATH)\PGPmemlock.pdb"
a2f0b2 ¤   -@erase "$(OBJPATH)\PGPmemlock.lib"
a32e03 ¤   -@erase "$(OBJPATH)\PGPmemlock.map"
419c16 ¤   -@erase "$(OBJPATH)\PGPmemlock.pch"
460199 ¤   -@erase "$(OBJPATH)\PGPmemlock.vxd"
8e0d63 ¤   -@erase "$(OBJPATH)\pgpML.res"
b6af5a
676986 "$(OBJPATH)" :
b04e6a ····if not exist "$(OBJPATH)/$(NULL)" mkdir "$(OBJPATH)"
b8af5a
e4af5a
6364b1 AS_PROJ = $(AFLAGS) -I$(DDKPATH)\inc32 -Fo"$(OBJPATH)\\"
7f497a CC_PROJ = $(CFLAGS) -I$(DDKPATH)\inc32 -I..\.. -Fo"$(OBJPATH)\\" -Fp"$(OBJPATH)¶
f3ef65 \PGPmemlock.pch"
629937 CPP_PROJ = $(CPPFLAGS) -I$(DDKPATH)\inc32 -I..\.. -Fo"$(OBJPATH)\\"¤-Fp"$(OBJPA¶
0ad1fb TH)\PGPmemlock.pch"
b4a310 RSC_PROJ = $(RSCFLAGS) -I$(DDKPATH)\inc16
cfaf5a
8b0be4 LINK32_OBJS= \
e9f092 ¤   "$(OBJPATH)\pgpMLdevdcl.obj" \
5f1c4c ¤   "$(OBJPATH)\pgpMemLock.obj"¤
75af5a
04af5a
07fb29 "$(OBJPATH)\PGPmemlock.vxd" : "$(OBJPATH)" $(DEF_FILE) $(LINK32_OBJS)
57f9a3 ····$(LINK32) @<<
d169df ··$(LINK32_FLAGS) $(LINK32_OBJS)
689355 <<
a2260f !IF "$(RSC)" != ""
75bd24 ¤   copy $(OBJPATH)\PGPmemlock.vxd $(OBJPATH)\PGPml.vxd
c837f6 ¤   $(DDKPATH)\bin\adrc2vxd $(OBJPATH)\PGPml.vxd $(OBJPATH)\pgpML.res
595def ¤   copy $(OBJPATH)\PGPml.vxd $(OBJPATH)\PGPmemlock.vxd
b056d2 ¤   erase $(OBJPATH)\PGPml.vxd
b20945 !ENDIF
11af5a
1b0846 .asm{$(OBJPATH)}.obj::
4f6dc6 ···$(AS) @<<
d426e1 ···$(AS_PROJ) $<·
219355 <<
47af5a
d7410e .c{$(OBJPATH)}.obj::
1dd360 ···$(CC) @<<
123863 ···$(CC_PROJ) $<·
139355 <<
57af5a
bce60f .cpp{$(OBJPATH)}.obj::
aee691 ···$(CPP) @<<
d88e24 ···$(CPP_PROJ) $<·
d59355 <<
4caf5a
df8035 .rc{$(OBJPATH)}.res::
2cc38f ···$(RSC) @<<
fcbad8 ···$(RSC_PROJ) $<·
1a9355 <<
f1af5a
49af5a
b5a201 !IF "$(CFG)" == "PGPmemlock - Win32 Release" || "$(CFG)" == "PGPmemlock - Win32¶
f2349a ·Debug"
17af5a
af481b SOURCE=.\Source\pgpMLdevdcl.asm
0eaf5a
01066f !IF ·"$(CFG)" == "PGPmemlock - Win32 Release"
0daf5a
4007db DEP_CPP_PGPMEMLOCK=
8967c5 ¤
968f02 "$(OBJPATH)\pgpMLdevdcl.obj" : $(SOURCE) $(DEP_CPP_PGPMEMLOCK) "$(OBJPATH)"
920099 ¤   $(AS) $(AS_PROJ) $(SOURCE)
64af5a
90a124 !ELSEIF ·"$(CFG)" == "PGPmemlock - Win32 Debug"
14af5a
--c202 001989196cd40110046 Page 3 of PGPmemlock.mak
5c07db DEP_CPP_PGPMEMLOCK=
f167c5 ¤
8d8f02 "$(OBJPATH)\pgpMLdevdcl.obj" : $(SOURCE) $(DEP_CPP_PGPMEMLOCK) "$(OBJPATH)"
050099 ¤   $(AS) $(AS_PROJ) $(SOURCE)
91af5a
0f30ec !ENDIF·
73af5a
eeaf5a
b6d90e SOURCE=.\Source\pgpMemLock.c
71af5a
6e066f !IF ·"$(CFG)" == "PGPmemlock - Win32 Release"
3baf5a
944024 DEP_CPP_PGPMEMLOCK=\
8c229a ¤   "..\..\pgpMemLockWin32.h"
9667c5 ¤
f98efe "$(OBJPATH)\pgpMemLock.obj" : $(SOURCE) $(DEP_CPP_PGPMEMLOCK) "$(OBJPATH)"
7d4c76 ¤   $(CC) $(CC_PROJ) $(SOURCE)
c8af5a
e2a124 !ELSEIF ·"$(CFG)" == "PGPmemlock - Win32 Debug"
57af5a
e84024 DEP_CPP_PGPMEMLOCK=\
8d229a ¤   "..\..\pgpMemLockWin32.h"
d667c5 ¤
e88efe "$(OBJPATH)\pgpMemLock.obj" : $(SOURCE) $(DEP_CPP_PGPMEMLOCK) "$(OBJPATH)"
e94c76 ¤   $(CC) $(CC_PROJ) $(SOURCE)
06af5a
ee30ec !ENDIF·
86af5a
8e107b !IF ·"$(RSC)" != ""
c5af5a
627224 SOURCE=.\Source\pgpML.rc
19af5a
9b066f !IF ·"$(CFG)" == "PGPmemlock - Win32 Release"
8caf5a
14b871 DEP_RSC_PGPMEMLOCK=\
5ac1f9 ¤   ".\Source\pgpVer.h"
0e67c5 ¤
6e7763 "$(OBJPATH)\pgpML.res" : $(SOURCE) $(DEP_RSC_PGPMEMLOCK) "$(OBJPATH)"
c42785 ¤   $(RSC) $(RSC_PROJ) -Fo"$(OBJPATH)\pgpML.res" $(SOURCE)
13af5a
a0a124 !ELSEIF ·"$(CFG)" == "PGPmemlock - Win32 Debug"
c3af5a
9eb871 DEP_RSC_PGPMEMLOCK=\
f4c1f9 ¤   ".\Source\pgpVer.h"
7f67c5 ¤
ed7763 "$(OBJPATH)\pgpML.res" : $(SOURCE) $(DEP_RSC_PGPMEMLOCK) "$(OBJPATH)"
c12785 ¤   $(RSC) $(RSC_PROJ) -Fo"$(OBJPATH)\pgpML.res" $(SOURCE)
13af5a
2230ec !ENDIF·
e6af5a
c40945 !ENDIF
17af5a
4330ec !ENDIF·
98af5a

--cb72 001ea50e81540110047 Page 1 of PGPml95_Install.txt
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
247b7e ¤   Install.txt - PGPmemlock readme file (Win95 version)
8167c5 ¤
47af5a
42057c ¤   $Id: PGPml95_Install.txt,v 1.3 1998/08/11 13:43:49 pbj Exp $
a4f7f7 ____________________________________________________________________________*/
8eaf5a
3db51c Instructions for the installing the PGPmemlock memory locking driver·
1f5e38 - Windows 95 version
01af5a
6baf5a
4aaf5a
9cef78 Installing :
fdf5b4 ------------
bbaf5a
159d1b - copy PGPmemlock.vxd to your <Windows> directory.¤ ··E.g. :
dfaf5a
30540f ¤   copy PGPmemlock.vxd c:\Windows
d6af5a
dcaf5a
bcaf0b That's it!
0baf5a
fcaf5a
46af5a
2c04c3 Uninstalling :
de4e03 --------------
4faf5a
85bd51 - delete PGPmemlock.vxd from your <Windows> directory.¤
eaaf5a

--fffa 00143227f0d40110048 Page 1 of pgpML.rc
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
b7e95a ¤   PGPmemlock.rc - PGPmemlock version information
4767c5 ¤
35af5a
1fcfd2 ¤   $Id: pgpML.rc,v 1.7 1998/08/11 13:43:50 pbj Exp $
e1f7f7 ____________________________________________________________________________*/
d50380 #include <winver.h>
3baf5a
8e737c #include "pgpver.h"
b0af5a
6caf5a
8a21be /*---------------------------------------------------*/
eb9e09 /* The following values should be modified only by ··*/
daf9e4 /* the official builder, and they should be updated ·*/·
e3738d /* for each build ···································*/
ae21be /*---------------------------------------------------*/
c5af5a
98bdcf #define VER_PRODUCTBUILD¤   ··¤ 0
4ba67a #define VER_PRODUCTVERSION_STR ¤"1.0\0"
86b0cc #define VER_PRODUCTVERSION¤ ··¤ 1,0,VER_PRODUCTBUILD,1
e31051 #define VER_PRODUCTBETA_STR¤ ·¤ "\0"
f1af5a
d4af5a
ff21be /*---------------------------------------------------*/
e1f5ce /* Include product-specific default values ··········*/
1eaff9 /*¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····¤   ¤   ·*/
7221be /*---------------------------------------------------*/
64af5a
5aef8b #define VER_FILEOS¤ ¤   ···¤¤   ¤   VOS_DOS_WINDOWS32
699ea3 #define VER_PRODUCTNAME_STR¤¤   ¤   "PGPmemlock\0"
a2ddcb #define VER_FILETYPE¤   ¤   ¤   ¤   VFT_VXD
ea4450 #define VER_FILESUBTYPE¤¤   ¤   ¤   VFT2_UNKNOWN
fa17ec #define VER_FILEDESCRIPTION_STR¤¤   "Page-locking VxD driver\0"
c61b0b #define VER_INTERNALNAME_STR¤   ¤   "PGPmemlock.vxd\0"
96eaa9 #define VER_ORIGINALFILENAME_STR¤   "PGPmemlock.vxd\0"
faaf5a
6221be /*---------------------------------------------------*/
67e8e7 /* Define the version resource itself ···············*/
4daff9 /*¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····¤   ¤   ·*/
b921be /*---------------------------------------------------*/
c05e37 #include <common.ver>
61af5a
92af5a
4baf5a
43af5a
--a2b8 00187f2a67c40110049 Page 1 of pgpMLdevdcl.asm
86225a ;¤  Copyright (C) 1998 Network Associates, Inc.
00ba49 ;¤  All rights reserved.
47c8cd ;¤
3dd185 ;¤  pgpMLdevdcl.asm - necessary dispatch declarations
54fd50 ;
967587 ;¤  $Id: pgpMLdevdcl.asm,v 1.2 1998/08/11 13:43:51 pbj Exp $
3afd50 ;
28c34b ····.386p
c63be6 ····include vmm.inc
5370c4 ····include vdmad.inc
7cd055 ····include debug.inc
82af5a
ed16d2 Declare_Virtual_Device PGPMLOCK, 0, 1, PGPMEMLOCK_control,\
bda8d0 ····Undefined_Device_ID, Undefined_Init_Order
e3af5a
3dc728 Begin_Control_Dispatch PGPMEMLOCK
3e4074 ····Control_Dispatch Sys_Dynamic_Device_Init, _OnSysDynamicDeviceInit, cCall
afade4 ····Control_Dispatch Sys_Dynamic_Device_Exit, _OnSysDynamicDeviceExit, cCall
287f83 ····Control_Dispatch W32_DeviceIOControl, ····_OnDeviceIoControl, cCall, <esi>
2477c5 End_Control_Dispatch ··PGPMEMLOCK
60af5a
87d25a ····end
--1529 0005630a1ad4011004a Page 1 of pgpMemLock.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
7321c7 ¤   pgpMemLock.c - main C routines for PGPmemlock VxD (Win95)
0f67c5 ¤
e4af5a
7250b2 ¤   $Id: pgpMemLock.c,v 1.6 1998/08/11 13:43:51 pbj Exp $
c0f7f7 ____________________________________________________________________________*/
b60335 /*____________________________________________________________________________
8daf5a
8d20eb ¤   This virtual device driver (VxD) is used to lock memory pages into RAM·
acda98 ¤   so that they will not get copied to the system page file. ·This·
4ac44e ¤   functionality is desired when allocating buffers that will contain
9284f8 ¤   sensitive information (e.g. passwords) which could present a security
7635c7 ¤   hazard if copied to the page file.
88af5a
909c41 ····Usage :
baaf5a
f03d06 ¤   1) memory allocation. ·Memory that is to be locked should be allocated
f5a166 ¤   directly from the OS using the Win32 function VirtualAlloc :
7eaf5a
5545cb ¤   ¤   PVOID¤  pMem;
7ef418 ¤   ¤   ULONG¤  ulNumBytes;
77af5a
ec3341 ¤   ¤   ulNumBytes = number_of_bytes_to_allocate;
4baf5a
03f993 ¤   ¤   pMem = VirtualAlloc ( NULL, ulNumBytes, MEM_COMMIT, PAGE_READWRITE );
3baf5a
98af5a
3fd1a7 ¤   Notes:·
da7233 ¤   NULL¤   ¤   ¤   - the first parameter to VirtualAlloc must be NULL
a5461e ¤   ulNumBytes¤ ¤   - the actual allocation is rounded up by VirtualAlloc
6f75a3 ¤   ¤   ¤   ¤   ¤   ··to the next page boundary
1efb3c ¤   MEM_COMMIT¤ ¤   - this flag causes a region of physical memory to be
c5f6c9 ¤   ¤   ¤   ¤   ¤   ··committed for the allocated block of virtual memory
b286e9 ¤   PAGE_READWRITE¤ - this allows both read and write access to the memory
d3af5a
ceaf5a
cffdb1 ¤   2) memory locking. ·Lock the memory by passing the address and size of
473de0 ¤   the allocated memory to the driver :
61af5a
c643d8 ¤   ¤   PGPMEMLOCKSTRUCT¤   mls;
4eabef ¤   ¤   DWORD¤  ¤   ¤   ¤   dw;
0014bf ¤   ¤   BOOL¤   ¤   ¤   ¤   bDIOreturn;
21a4ab ¤   ·
c66942 ¤   ¤   mls.pMem = pMem;
f9c3b8 ¤   ¤   mls.ulNumBytes = ulNumBytes;
b6f9a8 ¤   ¤   bDIOreturn = DeviceIoControl(¤  hPGPMemLockDriver,·
d49231 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IOCTL_PGPMEMLOCK_LOCK_MEMORY,·
0a8156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
8ba44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
778156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
e8a44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
b97eb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dw,·
68f412 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL );
80ecca ¤   ¤   if ( !bDIOreturn )
aa5b34 ¤   ¤   {
b7af3c ¤   ¤   ¤   // this is an error communicating with the driver
b00fe4 ¤   ¤   }
1faf5a
85ee26 ¤   ¤   else·
735b34 ¤   ¤   {
39a925 ¤   ¤   ¤   if ( mls.ulError != 0 )
23f776 ¤   ¤   ¤   {
2e2cbe ¤   ¤   ¤   ¤   // this is an error internal to the driver
17a3a6 ¤   ¤   ¤   }
476b93 ¤   ¤   ¤   else·
aef776 ¤   ¤   ¤   {
036ee3 ¤   ¤   ¤   ¤   // successfully locked!
c5a3a6 ¤   ¤   ¤   }
560fe4 ¤   ¤   }
--3304 000a2a03c824011004a Page 2 of pgpMemLock.c
e0af5a
1aaf5a
acfba2 ¤   3) unlocking the memory. ·To unlock the memory, the procedure is·
34c088 ¤   similar :
d8af5a
4143d8 ¤   ¤   PGPMEMLOCKSTRUCT¤   mls;
22abef ¤   ¤   DWORD¤  ¤   ¤   ¤   dw;
a314bf ¤   ¤   BOOL¤   ¤   ¤   ¤   bDIOreturn;
f0a4ab ¤   ·
5d6942 ¤   ¤   mls.pMem = pMem;
f5c3b8 ¤   ¤   mls.ulNumBytes = ulNumBytes;
c0f9a8 ¤   ¤   bDIOreturn = DeviceIoControl(¤  hPGPMemLockDriver,·
82193e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IOCTL_PGPMEMLOCK_UNLOCK_MEMORY,·
148156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
11a44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
418156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
43a44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
fb7eb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dw,·
ebf412 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL );
01ecca ¤   ¤   if ( !bDIOreturn )
065b34 ¤   ¤   {
64af3c ¤   ¤   ¤   // this is an error communicating with the driver
f60fe4 ¤   ¤   }
61af5a
ffee26 ¤   ¤   else·
6a5b34 ¤   ¤   {
92a925 ¤   ¤   ¤   if ( mls.ulError != 0 )
3af776 ¤   ¤   ¤   {
962cbe ¤   ¤   ¤   ¤   // this is an error internal to the driver
7ba3a6 ¤   ¤   ¤   }
176b93 ¤   ¤   ¤   else·
f6f776 ¤   ¤   ¤   {
f8db56 ¤   ¤   ¤   ¤   // successfully unlocked!
31a3a6 ¤   ¤   ¤   }
8f0fe4 ¤   ¤   }
02af5a
dcaf5a
1c6a21 ¤   4) freeing the memory. ·Use VirtualFree to free the memory :
70af5a
8b45cb ¤   ¤   PVOID¤  pMem;
b5af5a
30dc6f ¤   ¤   VirtualFree( pMem, 0, MEM_RELEASE );
7267c5 ¤
eff7f7 ____________________________________________________________________________*/
03af5a
52af5a
cefd39 #define WANTVXDWRAPS
f59874 #include <basedef.h>
910a3a #include <vmm.h>
ba3c9d #include <vtd.h>
0b6574 #include <vwin32.h>
82c34e #include <vxdwraps.h>
91af5a
0b43aa #include <debug.h>
85af5a
1f5e1c #include <winerror.h>
c4c737 #include <memory.h>
caaf5a
3eaaf2 #define PGP_WIN32¤  1
b52a59 #include "pgpMemLockWin32.h"
9eaf5a
8d2aaf // instruct compiler to use inline version of function
47778d #pragma intrinsic(memset)
9faf5a
364b8d // constants
42c683 //¤ number of list items that can be held in each internal heap block
c17f9c #define NUMITEMSPERBLOCK¤   64
bfaf5a
d7d1f9 // virtual memory paging in Win32 uses 4K byte pages (2^12)·
fe0ad4 #define WIN32PAGESIZE¤  ¤   12¤
eaaf5a
a23ae8 // macros
--57fb 000ebd6acf04011004a Page 3 of pgpMemLock.c
8d9222 #if DEBUG
6c47ab #define PGPmlPrintf(arg) Debug_Printf arg
3ddb21 #else
197aa9 #define PGPmlPrintf(arg)
3e7454 #endif
3eaf5a
4fad9a #define PGPmlEnterCriticalSection() _EnterMutex (g_mutexHeap, \
43060b ¤   ¤   ¤   BLOCK_THREAD_IDLE|BLOCK_SVC_INTS)
28d403 #define PGPmlLeaveCriticalSection() _LeaveMutex (g_mutexHeap)
d5af5a
665bee // typedefs
86fee8 //¤ elements of list used to keep track of locked blocks
955b72 typedef struct _MEMLOCKITEM {
2914bb ¤   struct _MEMLOCKITEM* next;
bab70a ¤   HANDLE¤ ¤   hProcess;
bc6d42 ¤   DWORD¤  ¤   dwHandle;
47982b ¤   ULONG¤  ¤   ulPage;
9f42e8 ¤   ULONG¤  ¤   ulNumPages;
273979 } PGPMEMLOCKITEM, *PPGPMEMLOCKITEM;
f3af5a
a2b41b //¤ block of such items
3361c3 typedef struct _MEMLOCKBLOCK {
d8cacd ¤   struct _MEMLOCKBLOCK*¤  nextBlock;
cd8292 ¤   PGPMEMLOCKITEM¤ ¤   ¤   item[NUMITEMSPERBLOCK];
b0cb00 } PGPMEMLOCKBLOCK, *PPGPMEMLOCKBLOCK;
06af5a
658e47 // global data·
bcb779 //¤ pointer to local heap
516831 static PPGPMEMLOCKBLOCK¤g_pHeapBlocks;
d0af5a
b46e2e //¤ pointer to head of free list
5ab569 static PPGPMEMLOCKITEM¤ g_pFreeHeapItems;
63af5a
231a3d //¤ pointer to head of used list
3fb271 static PPGPMEMLOCKITEM¤ g_pLockedList;
65af5a
0a69e9 // ·handle of mutex used to protect the heap linked-list code
00b6a2 static PVMMMUTEX¤   ¤   g_mutexHeap;
57af5a
19af5a
96bf56 //----------------------------------------------------|
7532a7 // ·internal item allocation routines
d8465d //
78af5a
0bfe80 VOID
6156d5 PGPmlHeapBlockInit (PPGPMEMLOCKBLOCK pmlb)
2fbb36 {
2adaf3 ¤   ULONG¤  ¤   ¤   i¤  ¤   = 0;
02de3b ¤   PPGPMEMLOCKITEM¤pmli¤   = NULL;
b6af5a
d14eb7 ¤   pmlb->nextBlock = NULL;
36af5a
63e309 ¤   pmli = &(pmlb->item[0]);
4baf5a
cfb558 ¤   for (i=1; i<NUMITEMSPERBLOCK; i++)
1ac7a1 ¤   {
9ce3c9 ¤   ¤   pmli->next = &(pmlb->item[i]);
0f54ec ¤   ¤   pmli = pmli->next;
c79371 ¤   }
e99003 ¤   pmli->next = NULL;
98efe6 }
1caf5a
ceaf5a
b57fc9 BOOL
3e79f3 PGPmlHeapInit ()
75bb36 {
ffaf5a
6b6f82 ¤   g_pHeapBlocks = _HeapAllocate (sizeof(PGPMEMLOCKBLOCK),·
c630f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···HEAPZEROINIT|HEAPLOCKEDIFDP);
88af5a
9960bb ¤   if (g_pHeapBlocks)·
ebc7a1 ¤   {
--2179 00015b398874011004a Page 4 of pgpMemLock.c
c0dd2f ¤   ¤   PGPmlHeapBlockInit (g_pHeapBlocks);
972023 ¤   ¤   g_pFreeHeapItems = &(g_pHeapBlocks->item[0]);
aa836c ¤   ¤   return TRUE;
a79371 ¤   }
51cdfa ¤   else return FALSE;
15efe6 }
b6af5a
f0af5a
c67fc9 BOOL
511665 PGPmlHeapDestroy ()
05bb36 {
b2dd80 ¤   PPGPMEMLOCKBLOCK¤   pmlb¤   ¤   = NULL;
a4ceac ¤   PPGPMEMLOCKBLOCK¤   pmlbNext¤   = NULL;
88af5a
81594f ¤   pmlb = g_pHeapBlocks;
0b67c5 ¤
a99f9f ¤   while (pmlb)·
7ec7a1 ¤   {
15798b ¤   ¤   pmlbNext = pmlb->nextBlock;
a4cf45 ¤   ¤   _HeapFree (pmlb, 0);
17e3c8 ¤   ¤   pmlb = pmlbNext;
af9371 ¤   }
75af5a
b2dc04 ¤   g_pFreeHeapItems = NULL;
64af5a
72c2e7 ¤   return TRUE;
e4efe6 }
d5af5a
5faf5a
d0d892 PPGPMEMLOCKITEM
ac21a3 PGPmlAllocateItem ()
b3bb36 {
bd1792 ¤   PPGPMEMLOCKITEM¤¤   pmli¤   ¤   = NULL;
88dd80 ¤   PPGPMEMLOCKBLOCK¤   pmlb¤   ¤   = NULL;
21ae6b ¤   PPGPMEMLOCKBLOCK¤   pmlbNew¤¤   = NULL;
a8afa2 ¤   ULONG¤  ¤   ¤   ¤   i¤  ¤   ¤   = 0;
4aaf5a
2318ef ¤   // there is an item available
d3b421 ¤   if (g_pFreeHeapItems)
e4c7a1 ¤   {
1d6183 ¤   ¤   // remove item from free list
9df622 ¤   ¤   pmli = g_pFreeHeapItems;
b59adb ¤   ¤   g_pFreeHeapItems = g_pFreeHeapItems->next;
d9af5a
d1bb84 ¤   ¤   return pmli;
009371 ¤   }
c0af5a
21007c ¤   // free list is empty, allocate more memory
6d43f9 ¤   pmlbNew = _HeapAllocate (sizeof(PGPMEMLOCKBLOCK),·
c0645a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·HEAPZEROINIT|HEAPLOCKEDIFDP);
def2c3 ¤   if (pmlbNew)·
3bc7a1 ¤   {
759564 ¤   ¤   // append block to linked list of blocks
31d01b ¤   ¤   pmlb = g_pHeapBlocks;
98cf19 ¤   ¤   while (pmlb->nextBlock) pmlb = pmlb->nextBlock;
ff7374 ¤   ¤   pmlb->nextBlock = pmlbNew;
b3f44c ¤   ¤   pmlbNew->nextBlock = NULL;
75af5a
9a7007 ¤   ¤   // link new items into a list
86e3f7 ¤   ¤   PGPmlHeapBlockInit (pmlbNew);
49af5a
cf4c52 ¤   ¤   // first item will be returned to caller
ecbe3b ¤   ¤   pmli = &(pmlbNew->item[0]);
baaf5a
c31046 ¤   ¤   // add rest of new items to free list
122d5f ¤   ¤   g_pFreeHeapItems = &(pmlbNew->item[1]);
ddaf5a
4bbb84 ¤   ¤   return pmli;
fb9371 ¤   }
0baf5a
5499a7 ¤   // couldn't get an item
153f59 ¤   return NULL;
--a3e7 000ad554a3b4011004a Page 5 of pgpMemLock.c
7aefe6 }
46af5a
8eaf5a
eafe80 VOID
76a92b PGPmlFreeItem (PPGPMEMLOCKITEM pmli)
1abb36 {
121338 ¤   // add item to list of free items
632841 ¤   pmli->next = g_pFreeHeapItems;
441952 ¤   g_pFreeHeapItems = pmli;
a0efe6 }
caaf5a
10af5a
03bf56 //----------------------------------------------------|
1456d5 // ·wipe the specified memory block
e9465d //
23eabd //¤ Arguments:
2d963d //¤ ¤   ulPage¤ ¤   ¤   - initial page being wiped
d3b808 //¤ ¤   ulNumPages¤ ¤   - number of pages in block being wiped
a9465d //
e6af5a
3bfe80 VOID
6b7050 PGPmlWipeBlock (
2afc73 ¤   ULONG¤  ulPage,
01ec4a ¤   ULONG¤  ulNumPages)
07bb36 {
b21fc0 ¤   PVOID¤  pmem;
0ec0f2 ¤   ULONG¤  ulBytes;
8eaf5a
32159b ¤   pmem = (PVOID)(ulPage << WIN32PAGESIZE);
b5d7ef ¤   ulBytes = ulNumPages << WIN32PAGESIZE;
05af5a
181d71 ¤   memset (pmem, 0, ulBytes);
02efe6 }
02af5a
f2af5a
a8bf56 //----------------------------------------------------|
c9cafa // ·add the specified memory block to list of locked blocks
7d465d //
67af5a
7a7fc9 BOOL
980cd4 PGPmlAddBlockToList (
a10ca7 ¤   PDIOCPARAMETERS p,
614831 ¤   ULONG¤  ¤   ¤   ulPage,
932aa8 ¤   ULONG¤  ¤   ¤   ulNumPages)
b6bb36 {
fdb1ab ¤   HANDLE¤ ¤   ¤   hProc¤  ¤   = NULL;
3e46db ¤   DWORD¤  ¤   ¤   dwHandle¤   = NULL;
81ca76 ¤   PPGPMEMLOCKITEM¤pmli¤   ¤   = NULL;
5aaf5a
cdc768 ¤   // allocate new linked-list item
2e6ea2 ¤   pmli = PGPmlAllocateItem ();·
267144 ¤   if (!pmli) return FALSE;
1aaf5a
b22115 ¤   // get process handle of current process
368cca ¤   VxDCall (VWIN32_GetCurrentProcessHandle)
9b6fc4 ¤   _asm mov hProc, eax
3baf5a
0094f6 ¤   // get handle as used by calling app
ec24a9 ¤   dwHandle = p->hDevice;
12af5a
ea602d ¤   // fill in new list element
531b45 ¤   pmli->next = g_pLockedList;
029697 ¤   pmli->hProcess = hProc;
66c24b ¤   pmli->dwHandle = dwHandle;
231804 ¤   pmli->ulPage = ulPage;
7215c9 ¤   pmli->ulNumPages = ulNumPages;
0aaf5a
0bd73b ¤   // insert element at head of list
5c82d0 ¤   g_pLockedList = pmli;
cdaf5a
1ac2e7 ¤   return TRUE;
adefe6 }
--d9ca 000313ea4b34011004a Page 6 of pgpMemLock.c
e0af5a
1aaf5a
aebf56 //----------------------------------------------------|
bee28d // ·remove the specified memory block from list of locked blocks
9a465d //
1faf5a
2d7fc9 BOOL
424fe3 PGPmlRemoveBlockFromList (
7d0ca7 ¤   PDIOCPARAMETERS p,
0c4831 ¤   ULONG¤  ¤   ¤   ulPage,
b22aa8 ¤   ULONG¤  ¤   ¤   ulNumPages)
40bb36 {
75b1ab ¤   HANDLE¤ ¤   ¤   hProc¤  ¤   = NULL;
9e46db ¤   DWORD¤  ¤   ¤   dwHandle¤   = NULL;
84ca76 ¤   PPGPMEMLOCKITEM¤pmli¤   ¤   = NULL;
f3e1b8 ¤   PPGPMEMLOCKITEM¤pPrev¤  ¤   = NULL;
a4af5a
d62115 ¤   // get process handle of current process
248cca ¤   VxDCall (VWIN32_GetCurrentProcessHandle)
5b6fc4 ¤   _asm mov hProc, eax
fdaf5a
d494f6 ¤   // get handle as used by calling app
9224a9 ¤   dwHandle = p->hDevice;
bbaf5a
a3d680 ¤   // search list for specified block
b17029 ¤   pPrev = NULL;
09d9bb ¤   pmli = g_pLockedList;
a55f8a ¤   while (pmli)·
d7c7a1 ¤   {
374029 ¤   ¤   if ((pmli->hProcess == hProc) &&
4a6269 ¤   ¤   ¤   (pmli->dwHandle == dwHandle))
b05b34 ¤   ¤   {
5fc84c ¤   ¤   ¤   if ((pmli->ulPage == ulPage) ·&&·
067f47 ¤   ¤   ¤   ¤   (pmli->ulNumPages == ulNumPages))
7ff776 ¤   ¤   ¤   {
8d4d59 ¤   ¤   ¤   ¤   if (pPrev)
8372c3 ¤   ¤   ¤   ¤   {
d446b3 ¤   ¤   ¤   ¤   ¤   pPrev->next = pmli->next;
c42613 ¤   ¤   ¤   ¤   }
d15109 ¤   ¤   ¤   ¤   else·
d272c3 ¤   ¤   ¤   ¤   {
a660f4 ¤   ¤   ¤   ¤   ¤   g_pLockedList = pmli->next;
e32613 ¤   ¤   ¤   ¤   }
c878e1 ¤   ¤   ¤   ¤   PGPmlWipeBlock (ulPage, ulNumPages);
3623b1 ¤   ¤   ¤   ¤   PGPmlFreeItem (pmli);
ef06e0 ¤   ¤   ¤   ¤   return TRUE;
2fa3a6 ¤   ¤   ¤   }
260fe4 ¤   ¤   }
f38fe5 ¤   ¤   pPrev = pmli;
7d54ec ¤   ¤   pmli = pmli->next;
569371 ¤   }
0eaf5a
3fcd39 ¤   // didn't find specified block, return error
33a230 ¤   return FALSE;
59efe6 }
f5af5a
15af5a
26bf56 //----------------------------------------------------|
72ce04 // ·unlock and remove the memory blocks belonging to this handle
85465d //
e8af5a
9e7fc9 BOOL
9f9033 PGPmlUnlockHandleBlocks (PDIOCPARAMETERS p)
d3bb36 {
b7b1ab ¤   HANDLE¤ ¤   ¤   hProc¤  ¤   = NULL;
5446db ¤   DWORD¤  ¤   ¤   dwHandle¤   = NULL;
deca76 ¤   PPGPMEMLOCKITEM¤pmli¤   ¤   = NULL;
3be1b8 ¤   PPGPMEMLOCKITEM¤pPrev¤  ¤   = NULL;
a194bb ¤   PPGPMEMLOCKITEM¤pNext¤  ¤   = NULL;
15af5a
8a2115 ¤   // get process handle of current process
318cca ¤   VxDCall (VWIN32_GetCurrentProcessHandle)
--6135 000f991859a4011004a Page 7 of pgpMemLock.c
2c6fc4 ¤   _asm mov hProc, eax
a9af5a
5594f6 ¤   // get handle as used by calling app
0e24a9 ¤   dwHandle = p->hDevice;
50af5a
9a8f70 ¤   // search list for block belonging to this process
3c7029 ¤   pPrev = NULL;
47d9bb ¤   pmli = g_pLockedList;
f55f8a ¤   while (pmli)·
28c7a1 ¤   {
434029 ¤   ¤   if ((pmli->hProcess == hProc) &&
1b6269 ¤   ¤   ¤   (pmli->dwHandle == dwHandle))
0e5b34 ¤   ¤   {
7cafb8 ¤   ¤   ¤   if (pPrev)
77f776 ¤   ¤   ¤   {
5d7f76 ¤   ¤   ¤   ¤   pPrev->next = pmli->next;
c3a3a6 ¤   ¤   ¤   }
1f6b93 ¤   ¤   ¤   else·
89f776 ¤   ¤   ¤   {
f078a4 ¤   ¤   ¤   ¤   g_pLockedList = pmli->next;
c3a3a6 ¤   ¤   ¤   }
94c915 ¤   ¤   ¤   pNext = pmli->next;
dd1fa7 ¤   ¤   ¤   PGPmlWipeBlock (pmli->ulPage, pmli->ulNumPages);
76dad6 ¤   ¤   ¤   _LinPageUnlock (pmli->ulPage, pmli->ulNumPages, 0);
fdccc2 ¤   ¤   ¤   PGPmlFreeItem (pmli);
2a0675 ¤   ¤   ¤   pmli = pNext;
8d0fe4 ¤   ¤   }
2fee26 ¤   ¤   else·
a65b34 ¤   ¤   {
3e4850 ¤   ¤   ¤   pPrev = pmli;
8840c4 ¤   ¤   ¤   pmli = pmli->next;
8e0fe4 ¤   ¤   }
489371 ¤   }
bdaf5a
cfc2e7 ¤   return TRUE;
93efe6 }
2eaf5a
09af5a
82bf56 //----------------------------------------------------|
36abfc // ·unlock and remove all blocks in the list
97465d //
68af5a
b47fc9 BOOL
68b0b7 PGPmlUnlockAllBlocks ()
91bb36 {
46de3b ¤   PPGPMEMLOCKITEM¤pmli¤   = NULL;
95a55e ¤   PPGPMEMLOCKITEM¤pNext¤  = NULL;
a1af5a
c2d9bb ¤   pmli = g_pLockedList;
215f8a ¤   while (pmli)·
39c7a1 ¤   {
c2644b ¤   ¤   pNext = pmli->next;
373912 ¤   ¤   PGPmlWipeBlock (pmli->ulPage, pmli->ulNumPages);
4e1eca ¤   ¤   _LinPageUnlock (pmli->ulPage, pmli->ulNumPages, 0);
c9fbca ¤   ¤   PGPmlFreeItem (pmli);
2fc1c0 ¤   ¤   pmli = pNext;
c19371 ¤   }
4baf5a
b44786 ¤   g_pLockedList = NULL;
0daf5a
47c2e7 ¤   return TRUE;
64efe6 }
59af5a
4caf5a
65bf56 //----------------------------------------------------|
b15c68 // ·lock the page(s) specified by structure
62af5a
a90e55 DWORD·
47c72b PGPmlLockPage (PDIOCPARAMETERS p)·
abbb36 {
7222a0 ¤   PPGPMEMLOCKSTRUCT¤  pplsIn¤ ¤   = (PPGPMEMLOCKSTRUCT)(p->lpvInBuffer);
f996f8 ¤   PPGPMEMLOCKSTRUCT¤  pplsOut¤¤   = (PPGPMEMLOCKSTRUCT)(p->lpvOutBuffer);
--895a 00005d8d9284011004a Page 8 of pgpMemLock.c
297cd7 ¤   ULONG¤  ¤   ¤   ¤   ulPage¤ ¤   = 0;
f87994 ¤   ULONG¤  ¤   ¤   ¤   ulNumPages¤ = 0;
fe6391 ¤   ULONG¤  ¤   ¤   ¤   ulError¤¤   = 0;
71af5a
143e42 ¤   PGPmlPrintf (("PGPmemlock: LockPage.\n"));
75af5a
827f3d ¤   // check buffer pointers
8ecacc ¤   if ((!pplsIn) || (!pplsOut))
48c7a1 ¤   {
b19e81 ¤   ¤   return ERROR_INVALID_PARAMETER;
849371 ¤   }
33af5a
0316af ¤   // check buffer lengths
830e97 ¤   if ((p->cbInBuffer < sizeof(PGPMEMLOCKSTRUCT)) ||
5d9cae ¤   ¤   (p->cbOutBuffer < sizeof(PGPMEMLOCKSTRUCT)))
3ec7a1 ¤   {
449e81 ¤   ¤   return ERROR_INVALID_PARAMETER;
8f9371 ¤   }
c1af5a
2ede49 ¤   // assume no error
184629 ¤   pplsOut->pMem = pplsIn->pMem;
80e233 ¤   pplsOut->ulNumBytes = pplsIn->ulNumBytes;
da1450 ¤   pplsOut->ulError = 0;
48af5a
953bc8 ¤   // calculate page numbers
2732a7 ¤   ulPage = ((ULONG)(pplsIn->pMem)) >> WIN32PAGESIZE;
b52721 ¤   ulNumPages = (((pplsIn->ulNumBytes)-1) >> WIN32PAGESIZE ) +1;
18f920 ¤   PGPmlPrintf (("PGPmemlock: locking page(s) %x - %x.\n",·
d8b24b ¤   ¤   ¤   ¤   ¤   ulPage, ulPage+ulNumPages-1));
01af5a
ee9e69 ¤   // add the block to the list of locked pages
783051 ¤   if (PGPmlAddBlockToList (p, ulPage, ulNumPages))
dcc7a1 ¤   {
079901 ¤   ¤   // actually lock the page(s)
92a058 ¤   ¤   ulError = _LinPageLock (ulPage, ulNumPages, 0);
d6b98a ¤   ¤   if (ulError == 0)¤  // error
645b34 ¤   ¤   {
72169b ¤   ¤   ¤   PGPmlPrintf (("PGPmemlock: Err: _LinPageLock error.\n"));
8b77c0 ¤   ¤   ¤   pplsOut->ulError = kPGPMemLockError_LockError;
4e07ec ¤   ¤   ¤   PGPmlRemoveBlockFromList (p, ulPage, ulNumPages);
850fe4 ¤   ¤   }
67ee26 ¤   ¤   else·
6c5b34 ¤   ¤   {
cc8b14 ¤   ¤   ¤   PGPmlPrintf (("PGPmemlock: successfully locked memory.\n"));
ed0fe4 ¤   ¤   }
e09371 ¤   }
6b4264 ¤   else·
a7c7a1 ¤   {
9ed627 ¤   ¤   PGPmlPrintf (("PGPmemlock: Err: PGPmlAddBlockToList error.\n"));
d48d77 ¤   ¤   pplsOut->ulError = kPGPMemLockError_ListError;
6d9371 ¤   }
91af5a
683e6b ¤   return 0;
bb38af } ··
76af5a
59af5a
82bf56 //----------------------------------------------------|
e394ff // ·unlock the page(s) specified by structure
fcaf5a
440e55 DWORD·
ed202d PGPmlUnlockPage (PDIOCPARAMETERS p)·
81bb36 {
f022a0 ¤   PPGPMEMLOCKSTRUCT¤  pplsIn¤ ¤   = (PPGPMEMLOCKSTRUCT)(p->lpvInBuffer);
fb96f8 ¤   PPGPMEMLOCKSTRUCT¤  pplsOut¤¤   = (PPGPMEMLOCKSTRUCT)(p->lpvOutBuffer);
d65ec9 ¤   ULONG¤  ¤   ¤   ¤   ulPage;
e41357 ¤   ULONG¤  ¤   ¤   ¤   ulNumPages;
8384c6 ¤   ULONG¤  ¤   ¤   ¤   ulError;
31af5a
69dcbb ¤   PGPmlPrintf (("PGPmemlock: UnlockPage.\n"));
3caf5a
6e7f3d ¤   // check buffer pointers
05cacc ¤   if ((!pplsIn) || (!pplsOut))
--7489 000c2965d954011004a Page 9 of pgpMemLock.c
f7c7a1 ¤   {
759e81 ¤   ¤   return ERROR_INVALID_PARAMETER;
379371 ¤   }
7baf5a
a816af ¤   // check buffer lengths
350e97 ¤   if ((p->cbInBuffer < sizeof(PGPMEMLOCKSTRUCT)) ||
889cae ¤   ¤   (p->cbOutBuffer < sizeof(PGPMEMLOCKSTRUCT)))
09c7a1 ¤   {
b19e81 ¤   ¤   return ERROR_INVALID_PARAMETER;
c69371 ¤   }
f9af5a
11de49 ¤   // assume no error
3d4629 ¤   pplsOut->pMem = pplsIn->pMem;
2fe233 ¤   pplsOut->ulNumBytes = pplsIn->ulNumBytes;
0c1450 ¤   pplsOut->ulError = 0;
77af5a
983bc8 ¤   // calculate page numbers
bd32a7 ¤   ulPage = ((ULONG)(pplsIn->pMem)) >> WIN32PAGESIZE;
762721 ¤   ulNumPages = (((pplsIn->ulNumBytes)-1) >> WIN32PAGESIZE ) +1;
9967f3 ¤   PGPmlPrintf (("PGPmemlock: unlocking page(s) %x - %x.\n",·
abb24b ¤   ¤   ¤   ¤   ¤   ulPage, ulPage+ulNumPages-1));
7daf5a
bdc41d ¤   // remove the pages from the list of locked pages
ceeb5e ¤   if (PGPmlRemoveBlockFromList (p, ulPage, ulNumPages))
99c7a1 ¤   {
a26613 ¤   ¤   // actually unlock the page(s)
a87ec1 ¤   ¤   ulError = _LinPageUnlock (ulPage, ulNumPages, 0);
2e58b3 ¤   ¤   if (ulError == 0)¤  ¤   // error
b55b34 ¤   ¤   {
33979e ¤   ¤   ¤   PGPmlPrintf (("PGPmemlock: Err: _LinPageUnlock error.\n"));
5448d2 ¤   ¤   ¤   pplsOut->ulError = kPGPMemLockError_UnlockError;
170fe4 ¤   ¤   }
8aee26 ¤   ¤   else·
105b34 ¤   ¤   {
da8812 ¤   ¤   ¤   PGPmlPrintf (("PGPmemlock: successfully unlocked memory.\n"));
7e0fe4 ¤   ¤   }
f79371 ¤   }
394264 ¤   else·
30c7a1 ¤   {
613302 ¤   ¤   PGPmlPrintf (("PGPmemlock: Err: PGPmlRemoveBlockFromList error.\n"));
828d77 ¤   ¤   pplsOut->ulError = kPGPMemLockError_ListError;
8b9371 ¤   }
35af5a
80f8a7 ¤   return 0;·
dc38af } ··
88af5a
98af5a
bfbf56 //----------------------------------------------------|
1ede57 // ·called upon initialization of VxD
daaf5a
fd7efe BOOL·
974c00 OnSysDynamicDeviceInit ()·
147142 {·
0577aa ¤   PGPmlPrintf (("PGPmemlock: OnSysDynamicDeviceInit.\n"));
ecaf5a
038b65 ¤   // initialize critical section mutex
429baa ¤   g_mutexHeap =·
cf435a ¤   ¤   _CreateMutex (CRITICAL_SECTION_BOOST, MUTEX_MUST_COMPLETE);
c64e91 ¤   if (g_mutexHeap == NULL)
8d8449 ¤   ¤   return FALSE;¤  // failure
f8af5a
ae4463 ¤   // initialize heap
52b71c ¤   PGPmlEnterCriticalSection ();
8b4786 ¤   g_pLockedList = NULL;
e0ffd7 ¤   PGPmlHeapInit ();
bc09dd ¤   PGPmlLeaveCriticalSection ();
9baf5a
3d1e76 ¤   return TRUE; ···¤   // success
16efe6 }
49af5a
86af5a
c2bf56 //----------------------------------------------------|
--5e34 0012224eee14011004a Page 10 of pgpMemLock.c
27af5e // ·called upon shutdown of VxD
99af5a
3f7efe BOOL·
804ae6 OnSysDynamicDeviceExit ()·
0ebb36 {
7eaf5a
fffc02 ¤   PGPmlPrintf (("PGPmemlock: OnSysDynamicDeviceExit.\n"));
24af5a
48b71c ¤   PGPmlEnterCriticalSection ();
72f5f9 ¤   PGPmlUnlockAllBlocks ();
5a854c ¤   PGPmlHeapDestroy ();
da09dd ¤   PGPmlLeaveCriticalSection ();
f5af5a
7b8517 ¤   _DestroyMutex (g_mutexHeap);
eaaf5a
1d756a ····return TRUE; ···// success
5638af } ··
b2af5a
7daf5a
a4bf56 //----------------------------------------------------|
bca758 // ·called upon as result of call to DeviceIoControl
50af5a
0f0e55 DWORD·
3147d8 OnDeviceIoControl (PDIOCPARAMETERS p)·
9ebb36 {
d7df2e ¤   DWORD¤  dwReturn;
7faf5a
27fbf5 ····switch (p->dwIoControlCode) {
21e28a ····case DIOC_GETVERSION :
32b68f ········dwReturn = 0;¤  // no error
852f68 ¤   ¤   break;
4caf5a
29dfd7 ¤   case IOCTL_PGPMEMLOCK_LOCK_MEMORY :
0f586f ¤   ¤   PGPmlEnterCriticalSection ();
316b2f ¤   ¤   dwReturn = PGPmlLockPage (p);
74e6ae ¤   ¤   PGPmlLeaveCriticalSection ();
362f68 ¤   ¤   break;
87af5a
b07550 ¤   case IOCTL_PGPMEMLOCK_UNLOCK_MEMORY :
ad586f ¤   ¤   PGPmlEnterCriticalSection ();
2d74cf ¤   ¤   dwReturn = PGPmlUnlockPage (p);
cae6ae ¤   ¤   PGPmlLeaveCriticalSection ();
192f68 ¤   ¤   break;
b8af5a
14fce3 ¤   case DIOC_CLOSEHANDLE :
7fc8d3 ¤   ¤   PGPmlPrintf (("PGPmemlock: DIOC_CLOSEHANDLE.\n"));
85586f ¤   ¤   PGPmlEnterCriticalSection ();
6676f8 ¤   ¤   PGPmlUnlockHandleBlocks (p);
f2e6ae ¤   ¤   PGPmlLeaveCriticalSection ();
163723 ¤   ¤   dwReturn = 0;¤  // no error
452f68 ¤   ¤   break;
1baf5a
24144d ····default :
a22d97 ¤   ¤   PGPmlPrintf (("PGPmemlock: Err: unknown IoControlCode: %X.\n",
8b02b7 ¤   ¤   ¤   ¤   ¤   ¤   p->dwIoControlCode));
26e1d0 ¤   ¤   dwReturn = ERROR_BAD_COMMAND;
a66fe7 ····}
86af5a
dc93a0 ¤   return dwReturn;
26efe6 }
22af5a
--2fa6 001f505beaa4011004b Page 1 of pgpMemLock.def
00383a VXD PGPMEMLOCK DYNAMIC
bcaf5a
a1f504 DESCRIPTION 'PGP secure memory locking VxD driver'
f1af5a
eae3b4 SEGMENTS
9b45bd ¤   _LPTEXT ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
c20f66 ¤   _LTEXT¤ ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
b5a872 ¤   _LDATA¤ ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
a1b5e6 ¤   _TEXT¤  ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
dee3e4 ¤   _DATA¤  ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
1dfbc6 ¤   CONST¤  ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
27ff31 ¤   _TLS¤   ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
86e1dc ¤   _BSS¤   ¤   CLASS 'LCODE' ··PRELOAD NONDISCARDABLE
4f96bd ¤   _MSGTABLE¤  CLASS 'MCODE' ··PRELOAD NONDISCARDABLE IOPL
09e9f3 ¤   _MSGDATA¤   CLASS 'MCODE' ··PRELOAD NONDISCARDABLE IOPL
186806 ¤   _IMSGTABLE¤ CLASS 'MCODE' ··PRELOAD DISCARDABLE IOPL
a28680 ¤   _IMSGDATA¤  CLASS 'MCODE' ··PRELOAD DISCARDABLE IOPL
004020 ¤   _ITEXT¤ ¤   CLASS 'ICODE' ··DISCARDABLE
fd442a ¤   _IDATA¤ ¤   CLASS 'ICODE' ··DISCARDABLE
c6835f ¤   _PTEXT¤ ¤   CLASS 'PCODE' ··NONDISCARDABLE
4e4743 ¤   _PDATA¤ ¤   CLASS 'PDATA' ··NONDISCARDABLE SHARED
1ad712 ¤   _STEXT¤ ¤   CLASS 'SCODE' ··RESIDENT
32bdec ¤   _SDATA¤ ¤   CLASS 'SCODE' ··RESIDENT
ee4f2b ¤   _DBOSTART¤  CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
63639f ¤   _DBOCODE¤   CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
2ab160 ¤   _DBODATA¤   CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
58607e ¤   _16ICODE¤   CLASS '16ICODE' PRELOAD DISCARDABLE
ccfb2d ¤   _RCODE¤ ¤   CLASS 'RCODE'
3cef2b EXPORTS
f58b82 ¤   PGPMLOCK_DDB @1
--8740 00144154aff4011004c Page 1 of pgpVer.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
577c21 ¤   PGPver.h - PGP company-specific version information
4e67c5 ¤
e1af5a
ef8207 ¤   $Id: pgpVer.h,v 1.4 1998/08/11 13:43:52 pbj Exp $
e7f7f7 ____________________________________________________________________________*/
6daf5a
7a82de #define VER_COMPANYNAME_STR¤¤   ¤   "Network Associates, Inc.\0"
93af5a
4222b1 #define VER_LEGALTRADEMARKS_STR¤¤   \
e53c7b "PGP is a trademark of Network Associates, Inc.\0"
37af5a
9fa436 #define VER_LEGALCOPYRIGHT_YEARS ···"1998\0"
5eaf5a
1cb9ce #define VER_LEGALCOPYRIGHT_STR¤ ¤   \
c656e8 "Copyright (c) Network Associates, Inc. " VER_LEGALCOPYRIGHT_YEARS
a5af5a
327ef2 /* default is nodebug */
8c55e7 #if DBG
8f47c4 #define VER_DEBUG¤  ¤   ¤   ¤   ¤   VS_FF_DEBUG
4cdb21 #else
7d1dff #define VER_DEBUG¤  ¤   ¤   ¤   ¤   0
8c7454 #endif
e9af5a
3c05f9 /* default is release */
e19838 #if BETA
3d88e8 #define VER_PRERELEASE¤ ¤   ¤   ¤   VS_FF_PRERELEASE
45db21 #else
06afa1 #define VER_PRERELEASE¤ ¤   ¤   ¤   0
8c7454 #endif
fdaf5a
690efc #define VER_FILEFLAGSMASK ·¤¤   ¤   VS_FFI_FILEFLAGSMASK
667304 #define VER_FILEFLAGS¤  ···¤¤   ¤   (VER_PRERELEASE | VER_DEBUG)
11af5a
44af5a

--cfaa 001dfc38c074011004d Page 1 of DIRS
df5b79 DIRS=Source

--a228 001a4ad1cef4011004e Page 1 of PGPmemlock.ini
6f1f8b \registry\machine\system\currentcontrolset\services\PGPmemlock
b5a3c8 ····Type = REG_DWORD 0x00000001
69b789 ····Start = REG_DWORD 0x00000002
ac0114 ····ErrorControl = REG_DWORD 0x00000001
a4614a ¤   DisplayName = REG_SZ "PGP secure memory driver"
--ed2a 0015dc99d2e4011004f Page 1 of PGPmlNT_Install.txt
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
e5eaf0 ¤   Install.txt - PGPmemlock readme file (WinNT version)
dd67c5 ¤
cbaf5a
430363 ¤   $Id: PGPmlNT_Install.txt,v 1.6 1998/08/11 13:43:54 pbj Exp $
aaf7f7 ____________________________________________________________________________*/
43af5a
cf4081 Instructions for installing the PGPmemlock memory locking driver -·
cbc6dd Windows NT version
61af5a
caaf5a
e4eb16 1. Copy the driver PGPmemlock.sys to the <nt_root>\system32\drivers\·
9509ca ···directory, i.e.:
7eaf5a
e4e2b8 ···copy PGPmemlock.sys c:\winnt\system32\drivers\
f1af5a
ecaf5a
134d57 2. Update the registry by *EITHER* ·
0eaf5a
39c742 ···a) running regini.exe on the PGPmemlock.ini file, i.e.:
8caf5a
2881f4 ···········regini PGPmemlock.ini
a7af5a
093cbd ···*OR*
71af5a
027cf1 ···b) editing the registry manually with REGEDIT. ·You should create
68b192 ······a registry key called·
3bda85 ¤   ··\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PGPmemlock
c6af5a
bb1465 ······in this location, create the following registry entries with the·
53140c ······following types and values :
bcaf5a
fa7689 ······entry¤¤   ¤   type¤   ¤   value
a8eaf2 ······ErrorControl¤ REG_DWORD ¤ 0x00000001
6abca8 ······Type¤ ¤   ¤   REG_DWORD ¤ 0x00000001
b32e5b ······Start¤¤   ¤   REG_DWORD¤  0x00000002
c82897 ¤   ··DisplayName¤  REG_SZ¤ ¤   "PGP secure memory driver"
27af5a
0daf5a
014d49 3. Reboot the computer. ·This will cause the driver to load automatically. ·
0aaf5a
c8af5a
609399 4. Note: ·If you do not want the driver to load automatically everytime·
31b0a4 ···the computer boots, you can control the loading and unloading of the·
ef5fbd ···driver manually. ·To do this, run the "Devices" applet in the Control·
936584 ···Panel. ·Select the PGPmemlock driver and press the "Startup" button.
cbb5ec ···The valid choices for the PGPmemlock driver are "Automatic" (driver
2a7528 ···automatically runs on startup (default)) and "Manual". ·If you select·
43b310 ···"Manual", you must start and stop the driver manually with the "Start"
6acd65 ···and "Stop" buttons in the "Devices" applet.
beaf5a
f1af5a
da2e86 Instructions for uninstalling the driver :
03af5a
4289d8 1. Run the "Devices" applet in the control panel. ·Select the PGPmemlock
9cb5bd ···driver. ·Click on "Stop".
87af5a
9aa196 2. Delete PGPmemlock.sys from the <nt_root>\system32\drivers\ directory.
4aaf5a
ad18c4 3. Delete the·
3d37f1 ···\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PGPmemlock·
577470 ···key and all its entries.
a1af5a
5daf5a

--6cda 001f90fae1a40110050 Page 1 of MAKEFILE
5ea601 #
ac12f9 # DO NOT EDIT THIS FILE!!! ·Edit .\sources. if you want to add a new source
67de86 # file to this component. ·This file merely indirects to the real make file
7aff74 # that is shared by all the driver components of the Windows NT DDK
68a601 #
61af5a
f972ae !INCLUDE $(NTMAKEENV)\makefile.def
--af06 0013141a4eb40110051 Page 1 of SOURCES
f540d9 TARGETNAME=¤¤   PGPmemlock
b0d501 TARGETTYPE= ¤   DRIVER
5aaf5a
cf727a TARGETPATH= ¤   ..\Sys
1637c5 INCLUDES=¤  ¤   $(BASEDIR)\inc;..\..\..;.
1e17d7 LINKER_FLAGS=¤  -MAP:PGPmemlock.map
ecaf5a
f6db59 SOURCES=¤   ¤   pgpMemLock.c \
311b82 ¤   ¤   ¤   ¤   pgpMemLock.rc
--049f 000fa5527c440110052 Page 1 of pgpMemLock.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
2a338f ¤   PGPmemlock.c - PGPmemlock kernel mode device driver for locking memory
1e67c5 ¤
63af5a
e6cc62 ¤   $Id: pgpMemLock.c,v 1.5 1998/08/11 13:43:55 pbj Exp $
98f7f7 ____________________________________________________________________________*/
bd0335 /*____________________________________________________________________________
c7af5a
1d5945 ¤   This kernel mode device driver is used to lock memory pages into RAM·
94da98 ¤   so that they will not get copied to the system page file. ·This·
76c44e ¤   functionality is desired when allocating buffers that will contain
5a84f8 ¤   sensitive information (e.g. passwords) which could present a security
ef35c7 ¤   hazard if copied to the page file.
4daf5a
fa9c41 ····Usage :
93af5a
143d06 ¤   1) memory allocation. ·Memory that is to be locked should be allocated
3da166 ¤   directly from the OS using the Win32 function VirtualAlloc :
9daf5a
8f45cb ¤   ¤   PVOID¤  pMem;
4cf418 ¤   ¤   ULONG¤  ulNumBytes;
b3af5a
7f3341 ¤   ¤   ulNumBytes = number_of_bytes_to_allocate;
adaf5a
1af993 ¤   ¤   pMem = VirtualAlloc ( NULL, ulNumBytes, MEM_COMMIT, PAGE_READWRITE );
3baf5a
25af5a
84d1a7 ¤   Notes:·
097233 ¤   NULL¤   ¤   ¤   - the first parameter to VirtualAlloc must be NULL
78461e ¤   ulNumBytes¤ ¤   - the actual allocation is rounded up by VirtualAlloc
4f75a3 ¤   ¤   ¤   ¤   ¤   ··to the next page boundary
97fb3c ¤   MEM_COMMIT¤ ¤   - this flag causes a region of physical memory to be
1ff6c9 ¤   ¤   ¤   ¤   ¤   ··committed for the allocated block of virtual memory
6186e9 ¤   PAGE_READWRITE¤ - this allows both read and write access to the memory
09af5a
b4af5a
4dfdb1 ¤   2) memory locking. ·Lock the memory by passing the address and size of
b23de0 ¤   the allocated memory to the driver :
7daf5a
c643d8 ¤   ¤   PGPMEMLOCKSTRUCT¤   mls;
43abef ¤   ¤   DWORD¤  ¤   ¤   ¤   dw;
be14bf ¤   ¤   BOOL¤   ¤   ¤   ¤   bDIOreturn;
08a4ab ¤   ·
dc6942 ¤   ¤   mls.pMem = pMem;
d1c3b8 ¤   ¤   mls.ulNumBytes = ulNumBytes;
29f9a8 ¤   ¤   bDIOreturn = DeviceIoControl(¤  hPGPMemLockDriver,·
189231 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IOCTL_PGPMEMLOCK_LOCK_MEMORY,·
b98156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
2fa44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
d48156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
18a44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
697eb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dw,·
41f412 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL );
5becca ¤   ¤   if ( !bDIOreturn )
875b34 ¤   ¤   {
bdaf3c ¤   ¤   ¤   // this is an error communicating with the driver
8f0fe4 ¤   ¤   }
bfaf5a
a5ee26 ¤   ¤   else·
2c5b34 ¤   ¤   {
81a925 ¤   ¤   ¤   if ( mls.ulError != 0 )
d0f776 ¤   ¤   ¤   {
ae2cbe ¤   ¤   ¤   ¤   // this is an error internal to the driver
a8a3a6 ¤   ¤   ¤   }
ab6b93 ¤   ¤   ¤   else·
f4f776 ¤   ¤   ¤   {
076ee3 ¤   ¤   ¤   ¤   // successfully locked!
b8a3a6 ¤   ¤   ¤   }
fa0fe4 ¤   ¤   }
--3a4e 000660ca25240110052 Page 2 of pgpMemLock.c
e0af5a
1aaf5a
acfba2 ¤   3) unlocking the memory. ·To unlock the memory, the procedure is·
34c088 ¤   similar :
d8af5a
4143d8 ¤   ¤   PGPMEMLOCKSTRUCT¤   mls;
22abef ¤   ¤   DWORD¤  ¤   ¤   ¤   dw;
a314bf ¤   ¤   BOOL¤   ¤   ¤   ¤   bDIOreturn;
f0a4ab ¤   ·
5d6942 ¤   ¤   mls.pMem = pMem;
f5c3b8 ¤   ¤   mls.ulNumBytes = ulNumBytes;
c0f9a8 ¤   ¤   bDIOreturn = DeviceIoControl(¤  hPGPMemLockDriver,·
82193e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IOCTL_PGPMEMLOCK_UNLOCK_MEMORY,·
148156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
11a44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
418156 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mls,·
43a44c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof( mls ),·
fb7eb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dw,·
ebf412 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL );
01ecca ¤   ¤   if ( !bDIOreturn )
065b34 ¤   ¤   {
64af3c ¤   ¤   ¤   // this is an error communicating with the driver
f60fe4 ¤   ¤   }
61af5a
ffee26 ¤   ¤   else·
6a5b34 ¤   ¤   {
92a925 ¤   ¤   ¤   if ( mls.ulError != 0 )
3af776 ¤   ¤   ¤   {
962cbe ¤   ¤   ¤   ¤   // this is an error internal to the driver
7ba3a6 ¤   ¤   ¤   }
176b93 ¤   ¤   ¤   else·
f6f776 ¤   ¤   ¤   {
f8db56 ¤   ¤   ¤   ¤   // successfully unlocked!
31a3a6 ¤   ¤   ¤   }
8f0fe4 ¤   ¤   }
02af5a
dcaf5a
1c6a21 ¤   4) freeing the memory. ·Use VirtualFree to free the memory :
70af5a
8b45cb ¤   ¤   PVOID¤  pMem;
b5af5a
30dc6f ¤   ¤   VirtualFree( pMem, 0, MEM_RELEASE );
7267c5 ¤
eff7f7 ____________________________________________________________________________*/
03af5a
52af5a
157ba3 #include "ntddk.h"
72dd84 #include "stdarg.h"
7caf5a
cbaaf2 #define PGP_WIN32¤  1
172a59 #include "pgpMemLockWin32.h"
e9af5a
f64b8d // constants
612dea //¤ number of list items that can be held in internal heap
b07f9c #define NUMITEMSPERBLOCK¤   64
04af5a
1cd1f9 // virtual memory paging in Win32 uses 4K byte pages (2^12)·
720ad4 #define WIN32PAGESIZE¤  ¤   12¤
3baf5a
2c5bee // typedefs
fcfee8 //¤ elements of list used to keep track of locked blocks
845b72 typedef struct _MEMLOCKITEM {
df14bb ¤   struct _MEMLOCKITEM* next;
a5e8ed ¤   PEPROCESS¤  ¤   peProcess;
3b570a ¤   PFILE_OBJECT¤   pfo;
3090a8 ¤   ULONG¤  ¤   ¤   ulPage;
a68c89 ¤   ULONG¤  ¤   ¤   ulNumPages;
fee2f4 ¤   PMDL¤   ¤   ¤   pmdl;
6c3979 } PGPMEMLOCKITEM, *PPGPMEMLOCKITEM;
3eaf5a
15b41b //¤ block of such items
6661c3 typedef struct _MEMLOCKBLOCK {
--8b50 000ca4e9ad940110052 Page 3 of pgpMemLock.c
52cacd ¤   struct _MEMLOCKBLOCK*¤  nextBlock;
278292 ¤   PGPMEMLOCKITEM¤ ¤   ¤   item[NUMITEMSPERBLOCK];
03cb00 } PGPMEMLOCKBLOCK, *PPGPMEMLOCKBLOCK;
d4af5a
8b6f7e //¤ device object extension data structure
80047e typedef struct _DEVEXTENSION {
8a79bf ¤   KSPIN_LOCK¤ ¤   slListLock;
22f3ad ¤   PPGPMEMLOCKITEM¤pLockedList;
512192 } DEVEXTENSION, *PDEVEXTENSION;
8daf5a
b0af5a
883ae8 // macros
e2f44f //¤ DbgPrint prints a message to the kernel debugging console
ee55e7 #if DBG
29e054 #define PGPmlPrint(arg) DbgPrint arg
2cdb21 #else
89587d #define PGPmlPrint(arg)
f27454 #endif
53af5a
70af5a
a30fc2 // globals
10b779 //¤ pointer to local heap
826831 static PPGPMEMLOCKBLOCK¤g_pHeapBlocks;
66af5a
936e2e //¤ pointer to head of free list
2fb569 static PPGPMEMLOCKITEM¤ g_pFreeHeapItems;
9eaf5a
22af5a
62af5a
2abf56 //----------------------------------------------------|
7032a7 // ·internal item allocation routines
b3465d //
5eaf5a
04fe80 VOID
e518d6 PGPmlHeapBlockInit (IN PPGPMEMLOCKBLOCK pmlb)
23bb36 {
bfdaf3 ¤   ULONG¤  ¤   ¤   i¤  ¤   = 0;
3dde3b ¤   PPGPMEMLOCKITEM¤pmli¤   = NULL;
ddaf5a
104eb7 ¤   pmlb->nextBlock = NULL;
69af5a
94e309 ¤   pmli = &(pmlb->item[0]);
9baf5a
edb558 ¤   for (i=1; i<NUMITEMSPERBLOCK; i++)
0ac7a1 ¤   {
d5e3c9 ¤   ¤   pmli->next = &(pmlb->item[i]);
af54ec ¤   ¤   pmli = pmli->next;
889371 ¤   }
889003 ¤   pmli->next = NULL;
8eefe6 }
a2af5a
3d1e8a NTSTATUS
bc79f3 PGPmlHeapInit ()
29bb36 {
97daf3 ¤   ULONG¤  ¤   ¤   i¤  ¤   = 0;
7fde3b ¤   PPGPMEMLOCKITEM¤pmli¤   = NULL;
d6af5a
26fb53 ¤   g_pHeapBlocks = ExAllocatePool (NonPagedPool,·
184b3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····sizeof(PGPMEMLOCKBLOCK));
36af5a
1360bb ¤   if (g_pHeapBlocks)·
afc7a1 ¤   {
6add2f ¤   ¤   PGPmlHeapBlockInit (g_pHeapBlocks);
4e2023 ¤   ¤   g_pFreeHeapItems = &(g_pHeapBlocks->item[0]);
44cdcf ¤   ¤   return STATUS_SUCCESS;
7e9371 ¤   }
7414c3 ¤   else return STATUS_NO_MEMORY;
08efe6 }
a3af5a
951e8a NTSTATUS
8c1665 PGPmlHeapDestroy ()
cabb36 {
--a01d 00050e500c140110052 Page 4 of pgpMemLock.c
acdd80 ¤   PPGPMEMLOCKBLOCK¤   pmlb¤   ¤   = NULL;
c5ceac ¤   PPGPMEMLOCKBLOCK¤   pmlbNext¤   = NULL;
aaaf5a
f7594f ¤   pmlb = g_pHeapBlocks;
c167c5 ¤
c99f9f ¤   while (pmlb)·
f0c7a1 ¤   {
31798b ¤   ¤   pmlbNext = pmlb->nextBlock;
42367b ¤   ¤   ExFreePool (pmlb);
dbe3c8 ¤   ¤   pmlb = pmlbNext;
159371 ¤   }
faaf5a
95dc04 ¤   g_pFreeHeapItems = NULL;
90af5a
2bd9e7 ¤   return STATUS_SUCCESS;
47efe6 }
68af5a
6bd892 PPGPMEMLOCKITEM
d221a3 PGPmlAllocateItem ()
49bb36 {
e41792 ¤   PPGPMEMLOCKITEM¤¤   pmli¤   ¤   = NULL;
dcdd80 ¤   PPGPMEMLOCKBLOCK¤   pmlb¤   ¤   = NULL;
20ae6b ¤   PPGPMEMLOCKBLOCK¤   pmlbNew¤¤   = NULL;
9cafa2 ¤   ULONG¤  ¤   ¤   ¤   i¤  ¤   ¤   = 0;
55af5a
0a18ef ¤   // there is an item available
42b421 ¤   if (g_pFreeHeapItems)
69c7a1 ¤   {
486183 ¤   ¤   // remove item from free list
d6f622 ¤   ¤   pmli = g_pFreeHeapItems;
0a9adb ¤   ¤   g_pFreeHeapItems = g_pFreeHeapItems->next;
d8af5a
e1bb84 ¤   ¤   return pmli;
c09371 ¤   }
62af5a
29007c ¤   // free list is empty, allocate more memory
956d26 ¤   pmlbNew = ExAllocatePool (NonPagedPool,·
60b1ed ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··sizeof(PGPMEMLOCKBLOCK));
fff2c3 ¤   if (pmlbNew)·
76c7a1 ¤   {
859564 ¤   ¤   // append block to linked list of blocks
07d01b ¤   ¤   pmlb = g_pHeapBlocks;
eccf19 ¤   ¤   while (pmlb->nextBlock) pmlb = pmlb->nextBlock;
f97374 ¤   ¤   pmlb->nextBlock = pmlbNew;
0ff44c ¤   ¤   pmlbNew->nextBlock = NULL;
02af5a
b17007 ¤   ¤   // link new items into a list
fde3f7 ¤   ¤   PGPmlHeapBlockInit (pmlbNew);
dbaf5a
6c4c52 ¤   ¤   // first item will be returned to caller
a6be3b ¤   ¤   pmli = &(pmlbNew->item[0]);
87af5a
341046 ¤   ¤   // add rest of new items to free list
2e2d5f ¤   ¤   g_pFreeHeapItems = &(pmlbNew->item[1]);
3caf5a
9abb84 ¤   ¤   return pmli;
589371 ¤   }
aaaf5a
b099a7 ¤   // couldn't get an item
f73f59 ¤   return NULL;
34efe6 }
27af5a
a8fe80 VOID
20264f PGPmlFreeItem (IN PPGPMEMLOCKITEM pmli)
1bbb36 {
431338 ¤   // add item to list of free items
a62841 ¤   pmli->next = g_pFreeHeapItems;
a61952 ¤   g_pFreeHeapItems = pmli;
8fefe6 }
48af5a
efbf56 //----------------------------------------------------|
5056d5 // ·wipe the specified memory block
--0399 000ac5d88a840110052 Page 5 of pgpMemLock.c
c1465d //
e1eabd //¤ Arguments:
db963d //¤ ¤   ulPage¤ ¤   ¤   - initial page being wiped
cab808 //¤ ¤   ulNumPages¤ ¤   - number of pages in block being wiped
80465d //
2baf5a
02fe80 VOID
067050 PGPmlWipeBlock (
b61c26 ¤   IN ULONG¤   ¤   ¤   ulPage,
f15eaa ¤   IN ULONG¤   ¤   ¤   ulNumPages)
75bb36 {
9f1fc0 ¤   PVOID¤  pmem;
cbc0f2 ¤   ULONG¤  ulBytes;
20af5a
8c159b ¤   pmem = (PVOID)(ulPage << WIN32PAGESIZE);
fbd7ef ¤   ulBytes = ulNumPages << WIN32PAGESIZE;
b5af5a
111d71 ¤   memset (pmem, 0, ulBytes);
dfefe6 }
1eaf5a
7faf5a
92bf56 //----------------------------------------------------|
ffb0cf // ·add the specified memory block to list of blocks
d1465d //
c7eabd //¤ Arguments:
12eab2 //¤ ¤   pDevO¤  ¤   ¤   - pointer to a device object
863c4c //¤ ¤   ulPage¤ ¤   ¤   - initial page being locked
3b5a4c //¤ ¤   ulNumPages¤ ¤   - number of pages in block being locked
18b388 //¤ ¤   pmdl¤   ¤   ¤   - pointer to MDL used to lock pages
b7465d //
efaf5a
811e8a NTSTATUS
a30cd4 PGPmlAddBlockToList (
d215ce ····IN PDEVICE_OBJECT¤  pDevO,
3a2396 ····IN PIRP ¤   ¤   ¤   pIrp,
141c26 ¤   IN ULONG¤   ¤   ¤   ulPage,
642012 ¤   IN ULONG¤   ¤   ¤   ulNumPages,
1545a4 ¤   IN PMDL¤¤   ¤   ¤   pmdl)
40bb36 {
4f1792 ¤   PPGPMEMLOCKITEM¤¤   pmli¤   ¤   = NULL;
c1f2b3 ¤   PDEVEXTENSION¤  ¤   pde¤¤   ¤   = NULL;
cefa04 ¤   PEPROCESS¤  ¤   ¤   peProcess¤  = NULL;
0cb9f2 ¤   PFILE_OBJECT¤   ¤   pfo¤¤   ¤   = NULL;
94e881 ¤   NTSTATUS¤   ¤   ¤   ntStatus¤   = STATUS_NO_MEMORY;
b47c75 ¤   KIRQL¤  ¤   ¤   ¤   irql;
a4af5a
db28bc ¤   peProcess = PsGetCurrentProcess ();
0a9394 ¤   pfo = IoGetCurrentIrpStackLocation (pIrp)->FileObject;
5fd9bf ¤   pde = (PDEVEXTENSION)(pDevO->DeviceExtension);
58af5a
2f380d ¤   KeAcquireSpinLock (&pde->slListLock, &irql);
9aaf5a
3ab8e3 ¤   // allocate new item
58a2d9 ¤   pmli = PGPmlAllocateItem ();
d38c58 ¤   if (pmli)·
8ac7a1 ¤   {
9c6422 ¤   ¤   // insert block information into item
70a5d0 ¤   ¤   pmli->peProcess = peProcess;
8bf34f ¤   ¤   pmli->pfo = pfo;
5ece2e ¤   ¤   pmli->ulPage = ulPage;·
d4bbc1 ¤   ¤   pmli->ulNumPages = ulNumPages;·
e523aa ¤   ¤   pmli->pmdl = pmdl;
28af5a
b748fd ¤   ¤   // insert item into list
da990d ¤   ¤   pmli->next = pde->pLockedList;
242b04 ¤   ¤   pde->pLockedList = pmli;
d9af5a
d47f35 ¤   ¤   ntStatus = STATUS_SUCCESS;
879371 ¤   }
48af5a
e1bec4 ¤   KeReleaseSpinLock (&pde->slListLock, irql);
acaf5a
--aa46 000cc3aa11d40110052 Page 6 of pgpMemLock.c
e2afdb ¤   return ntStatus;
2aefe6 }
9daf5a
ffaf5a
b6bf56 //----------------------------------------------------|
fc53ef // ·remove the specified memory block from list of·
c56bf4 //¤ locked blocks and unlock the memory
17465d //
48eabd //¤ Arguments:
75eab2 //¤ ¤   pDevO¤  ¤   ¤   - pointer to a device object
154276 //¤ ¤   ulPage¤ ¤   ¤   - initial page to unlock
95f1eb //¤ ¤   ulNumPages¤ ¤   - number of pages in block to unlock
c0eb6a //¤ ¤   bUnlock¤¤   ¤   - TRUE=>unlock and remove from list
5328eb //¤ ¤   ¤   ¤   ¤   ¤   ··FALSE=>remove from list only
b6465d //
52af5a
a41e8a NTSTATUS
78f954 PGPmlUnlockBlock (
8c15ce ····IN PDEVICE_OBJECT¤  pDevO,
4e2396 ····IN PIRP ¤   ¤   ¤   pIrp,
671c26 ¤   IN ULONG¤   ¤   ¤   ulPage,
a72012 ¤   IN ULONG¤   ¤   ¤   ulNumPages,
944ba9 ¤   IN ULONG¤   ¤   ¤   bUnlock)
78bb36 {
05f2b3 ¤   PDEVEXTENSION¤  ¤   pde¤¤   ¤   = NULL;
c2dc78 ¤   PMDL¤   ¤   ¤   ¤   pmdl¤   ¤   = NULL;
1afa04 ¤   PEPROCESS¤  ¤   ¤   peProcess¤  = NULL;
99b9f2 ¤   PFILE_OBJECT¤   ¤   pfo¤¤   ¤   = NULL;
811792 ¤   PPGPMEMLOCKITEM¤¤   pmli¤   ¤   = NULL;
863c5c ¤   PPGPMEMLOCKITEM¤¤   pPrev¤  ¤   = NULL;
103d85 ¤   NTSTATUS¤   ¤   ¤   ntStatus¤   = STATUS_NOT_LOCKED;
407c75 ¤   KIRQL¤  ¤   ¤   ¤   irql;
84af5a
7c28bc ¤   peProcess = PsGetCurrentProcess ();
049394 ¤   pfo = IoGetCurrentIrpStackLocation (pIrp)->FileObject;
30d9bf ¤   pde = (PDEVEXTENSION)(pDevO->DeviceExtension);
c9af5a
c5380d ¤   KeAcquireSpinLock (&pde->slListLock, &irql);
97af5a
d7d680 ¤   // search list for specified block
647029 ¤   pPrev = NULL;
14bdcb ¤   pmli = pde->pLockedList;
205f8a ¤   while (pmli)·
13c7a1 ¤   {
ed7750 ¤   ¤   if ((pmli->peProcess == peProcess) &&
968950 ¤   ¤   ¤   (pmli->pfo == pfo))
0f5b34 ¤   ¤   {
edc84c ¤   ¤   ¤   if ((pmli->ulPage == ulPage) ·&&·
167f47 ¤   ¤   ¤   ¤   (pmli->ulNumPages == ulNumPages))
27f776 ¤   ¤   ¤   {
ef4d59 ¤   ¤   ¤   ¤   if (pPrev)
0072c3 ¤   ¤   ¤   ¤   {
4046b3 ¤   ¤   ¤   ¤   ¤   pPrev->next = pmli->next;
142613 ¤   ¤   ¤   ¤   }
0e5109 ¤   ¤   ¤   ¤   else·
b072c3 ¤   ¤   ¤   ¤   {
5b17c2 ¤   ¤   ¤   ¤   ¤   pde->pLockedList = pmli->next;
492613 ¤   ¤   ¤   ¤   }
13dc41 ¤   ¤   ¤   ¤   pmdl = pmli->pmdl;
8623b1 ¤   ¤   ¤   ¤   PGPmlFreeItem (pmli);
3a308a ¤   ¤   ¤   ¤   ntStatus = STATUS_SUCCESS;
f1f622 ¤   ¤   ¤   ¤   break;
5fa3a6 ¤   ¤   ¤   }
740fe4 ¤   ¤   }
258fe5 ¤   ¤   pPrev = pmli;
d554ec ¤   ¤   pmli = pmli->next;
939371 ¤   }
6aaf5a
2abec4 ¤   KeReleaseSpinLock (&pde->slListLock, irql);
8daf5a
723955 ¤   // unlock pages and discard MDL
cce163 ¤   if (bUnlock && pmdl)·
--f66f 0007408dfde40110052 Page 7 of pgpMemLock.c
f7c7a1 ¤   {
6f7967 ¤   ¤   PGPmlWipeBlock (ulPage, ulNumPages);
c15d41 ¤   ¤   MmUnlockPages(pmdl);
e5159e ¤   ¤   IoFreeMdl(pmdl);
7f9371 ¤   }
95af5a
8bafdb ¤   return ntStatus;
c3efe6 }
c6af5a
b2af5a
40bf56 //----------------------------------------------------|
2ded61 // ·remove all of this handle's memory blocks from·
f7f1ab //¤ list of blocks and unlock the memory
c7465d //
1deabd //¤ Arguments:
5905bf //¤ ¤   pDevO¤  ¤   ¤   ¤   - pointer to a device object
5c465d //
a1af5a
08fe80 VOID
3e644e PGPmlUnlockHandleBlocks (
2715ce ····IN PDEVICE_OBJECT¤  pDevO,
2c5d2e ····IN PIRP ¤   ¤   ¤   pIrp)
e7bb36 {
c1f2b3 ¤   PDEVEXTENSION¤  ¤   pde¤¤   ¤   = NULL;
02fa04 ¤   PEPROCESS¤  ¤   ¤   peProcess¤  = NULL;
22b9f2 ¤   PFILE_OBJECT¤   ¤   pfo¤¤   ¤   = NULL;
801792 ¤   PPGPMEMLOCKITEM¤¤   pmli¤   ¤   = NULL;
2b3c5c ¤   PPGPMEMLOCKITEM¤¤   pPrev¤  ¤   = NULL;
82495f ¤   PPGPMEMLOCKITEM¤¤   pNext¤  ¤   = NULL;
e77c75 ¤   KIRQL¤  ¤   ¤   ¤   irql;
b1af5a
cf28bc ¤   peProcess = PsGetCurrentProcess ();
fb9394 ¤   pfo = IoGetCurrentIrpStackLocation (pIrp)->FileObject;
43d9bf ¤   pde = (PDEVEXTENSION)(pDevO->DeviceExtension);
81af5a
7871ba ¤   // first wipe any blocks belonging to this handle
60bdcb ¤   pmli = pde->pLockedList;
ae5f8a ¤   while (pmli)·
50c7a1 ¤   {
ec7750 ¤   ¤   if ((pmli->peProcess == peProcess) &&
198950 ¤   ¤   ¤   (pmli->pfo == pfo))
4f5b34 ¤   ¤   {
e21fa7 ¤   ¤   ¤   PGPmlWipeBlock (pmli->ulPage, pmli->ulNumPages);
940fe4 ¤   ¤   }
6a54ec ¤   ¤   pmli = pmli->next;
8f9371 ¤   }
06af5a
0b380d ¤   KeAcquireSpinLock (&pde->slListLock, &irql);
abaf5a
34eaa5 ¤   // search list for block belonging to this handle
6f7029 ¤   pPrev = NULL;
d0bdcb ¤   pmli = pde->pLockedList;
7d5f8a ¤   while (pmli)·
10c7a1 ¤   {
747750 ¤   ¤   if ((pmli->peProcess == peProcess) &&
a18950 ¤   ¤   ¤   (pmli->pfo == pfo))
aa5b34 ¤   ¤   {
46afb8 ¤   ¤   ¤   if (pPrev)
d9f776 ¤   ¤   ¤   {
277f76 ¤   ¤   ¤   ¤   pPrev->next = pmli->next;
8da3a6 ¤   ¤   ¤   }
cb6b93 ¤   ¤   ¤   else·
b8f776 ¤   ¤   ¤   {
cdcf70 ¤   ¤   ¤   ¤   pde->pLockedList = pmli->next;
59a3a6 ¤   ¤   ¤   }
0fc915 ¤   ¤   ¤   pNext = pmli->next;
579a0b ¤   ¤   ¤   MmUnlockPages (pmli->pmdl);
441a0d ¤   ¤   ¤   IoFreeMdl (pmli->pmdl);
88ccc2 ¤   ¤   ¤   PGPmlFreeItem (pmli);
2f0675 ¤   ¤   ¤   pmli = pNext;
0c0fe4 ¤   ¤   }
74ee26 ¤   ¤   else·
--2934 0008e1da48240110052 Page 8 of pgpMemLock.c
e35b34 ¤   ¤   {
db4850 ¤   ¤   ¤   pPrev = pmli;
7340c4 ¤   ¤   ¤   pmli = pmli->next;
8b0fe4 ¤   ¤   }
979371 ¤   }
03af5a
e7bec4 ¤   KeReleaseSpinLock (&pde->slListLock, irql);
80efe6 }
efaf5a
7caf5a
53bf56 //----------------------------------------------------|
e0c183 // ·remove all locked memory blocks from·
64f1ab //¤ list of blocks and unlock the memory
ae465d //
a0eabd //¤ Arguments:
7605bf //¤ ¤   pDevO¤  ¤   ¤   ¤   - pointer to a device object
cf465d //
4baf5a
05fe80 VOID
ad0776 PGPmlUnlockAllBlocks (
366b76 ····IN PDEVICE_OBJECT¤  pDevO)
21bb36 {
c9f2b3 ¤   PDEVEXTENSION¤  ¤   pde¤¤   ¤   = NULL;
7a1792 ¤   PPGPMEMLOCKITEM¤¤   pmli¤   ¤   = NULL;
01495f ¤   PPGPMEMLOCKITEM¤¤   pNext¤  ¤   = NULL;
e27c75 ¤   KIRQL¤  ¤   ¤   ¤   irql;
d1af5a
dcd9bf ¤   pde = (PDEVEXTENSION)(pDevO->DeviceExtension);
2faf5a
f3d9bf ¤   // first wipe all blocks·
3dbdcb ¤   pmli = pde->pLockedList;
935f8a ¤   while (pmli)·
c2c7a1 ¤   {
cd3912 ¤   ¤   PGPmlWipeBlock (pmli->ulPage, pmli->ulNumPages);
4554ec ¤   ¤   pmli = pmli->next;
079371 ¤   }
e3af5a
9b380d ¤   KeAcquireSpinLock (&pde->slListLock, &irql);
0faf5a
c9c10e ¤   // now unlock blocks and destroy list
14bdcb ¤   pmli = pde->pLockedList;
a75f8a ¤   while (pmli)·
44c7a1 ¤   {
a8644b ¤   ¤   pNext = pmli->next;
805f5e ¤   ¤   MmUnlockPages (pmli->pmdl);
7f91f1 ¤   ¤   IoFreeMdl (pmli->pmdl);
dbfbca ¤   ¤   PGPmlFreeItem (pmli);
6fc1c0 ¤   ¤   pmli = pNext;
d19371 ¤   }
3daf5a
2c5504 ¤   pde->pLockedList = NULL;
ddaf5a
4ebec4 ¤   KeReleaseSpinLock (&pde->slListLock, irql);
5eefe6 }
4eaf5a
edaf5a
46bf56 //----------------------------------------------------|
c27257 // ·lock the pages in the specified virtual address range
f1465d //
76eabd //¤ Arguments:
cd05bf //¤ ¤   pDevO¤  ¤   ¤   ¤   - pointer to a device object
3a68f9 //¤ ¤   IoBuffer¤   ¤   ¤   - pointer to the I/O buffer
1dbf41 //¤ ¤   InputBufferLength¤  - input buffer length
a6b1e1 //¤ ¤   OutputBufferLength¤ - output buffer length
f6465d //
5a07c7 //¤ Return Value:
f2a935 //¤ ¤   STATUS_SUCCESS if sucessful, otherwise
bd43eb //¤ ¤   STATUS_*
fc465d //
e2af5a
bd1e8a NTSTATUS
8ef8e4 PGPmlLockTheMemory(
--88ce 00049863bc540110052 Page 9 of pgpMemLock.c
82fd19 ····IN PDEVICE_OBJECT pDevO,
e81425 ¤   IN PIRP¤¤   ¤   ··pIrp,
7ec549 ····IN OUT PVOID ·····IoBuffer,
be37d2 ····IN ULONG ·········InputBufferLength,
a43444 ····IN ULONG ·········OutputBufferLength)
76bb36 {
034e43 ····PPGPMEMLOCKSTRUCT¤  ppmls¤  ¤   ¤   = (PPGPMEMLOCKSTRUCT) IoBuffer;
28b471 ····NTSTATUS¤   ¤   ¤   ntStatus¤   ¤   = 0;
164cb4 ¤   PMDL¤   ¤   ¤   ¤   pmdl¤   ¤   ¤   = NULL;
9849aa ¤   ULONG¤  ¤   ¤   ¤   ulPage¤ ¤   ¤   = 0;
eb436d ¤   ULONG¤  ¤   ¤   ¤   ulNumPages¤ ¤   = 0;
f7af5a
b393b8 ¤   PGPmlPrint (("PGPmemlock: PGPmlLockTheMemory.\n"));
0aaf5a
085600 ¤   if ((InputBufferLength < sizeof (PGPMEMLOCKSTRUCT)) ||
d486af ¤   ¤   (OutputBufferLength < sizeof (PGPMEMLOCKSTRUCT)) ||
1d4bf3 ¤   ¤   (IoBuffer == NULL))
7e3b37 ····{
915fc6 ·······PGPmlPrint (("PGPmemlock: Err: Invalid input parameters.\n"));
2687e8 ·······ntStatus = STATUS_INVALID_PARAMETER;
5614ea ·······goto done;
8b6fe7 ····}
e5af5a
cede49 ¤   // assume no error
9c5a52 ¤   ppmls->ulError = 0;
7eaf5a
490b76 ¤   // allocate and initialize a Memory Descriptor List·
dff240 ¤   pmdl = IoAllocateMdl(ppmls->pMem, ppmls->ulNumBytes, FALSE, FALSE, NULL);·
8cb15c ¤   if (pmdl == NULL) {
a08690 ¤   ¤   PGPmlPrint (("PGPmemlock: Err: IoAllocateMdl failed.\n"));
ede709 ¤   ¤   ntStatus = STATUS_INSUFFICIENT_RESOURCES;
7c4a27 ¤   ¤   ppmls->ulError = kPGPMemLockError_AllocError;
01262d ¤   ¤   goto done;
fa9371 ¤   }
99af5a
b93bc8 ¤   // calculate page numbers
1f2168 ¤   ulPage = ((ULONG)(ppmls->pMem)) >> WIN32PAGESIZE;
7b517d ¤   ulNumPages = (((ppmls->ulNumBytes)-1) >> WIN32PAGESIZE ) +1;
1c79e7 ¤   PGPmlPrint (("PGPmemlock: locking page(s) %x - %x.\n",·
31a36c ¤   ¤   ¤   ¤   ¤   ¤   ulPage, ulPage+ulNumPages-1));
c4af5a
e4a7eb ¤   // add this block to the array of locked blocks
622fd1 ¤   ntStatus = PGPmlAddBlockToList (pDevO, pIrp, ulPage, ulNumPages, pmdl);
5596eb ¤   if (ntStatus != STATUS_SUCCESS)·
65c7a1 ¤   {
0d87ed ¤   ¤   // we couldn't allocate a new list item
dbc7b8 ¤   ¤   PGPmlPrint (("PGPmemlock: Err: PGPmlAddBlockToList failed.\n"));
87be40 ¤   ¤   ppmls->ulError = kPGPMemLockError_ListError;
f5af5a
fc7a01 ¤   ¤   // free the mdl we allocated,
e4159e ¤   ¤   IoFreeMdl(pmdl);
77262d ¤   ¤   goto done;
429371 ¤   }
a5af5a
390238 ¤   // try to lock down the client's area
3f10fd ¤   __try {
f2d3f3 ¤   ¤   MmProbeAndLockPages(pmdl, UserMode, IoModifyAccess);
d3c6e2 ¤   } __except(EXCEPTION_EXECUTE_HANDLER) {
b51b0e ¤   ¤   // client must have passed a bad address, or it exceeded its quota
fa2360 ¤   ¤   PGPmlPrint (("PGPmemlock: Err: MmProbeAndLockPages failed.\n"));
3a75f8 ¤   ¤   ntStatus = GetExceptionCode();
5643cc ¤   ¤   ppmls->ulError = kPGPMemLockError_LockError;
12af5a
e8576c ¤   ¤   // remove block from array and free the MDL we allocated,
fcdfe1 ¤   ¤   PGPmlUnlockBlock (pDevO, pIrp, ulPage, ulNumPages, FALSE);
d2159e ¤   ¤   IoFreeMdl(pmdl);
2f262d ¤   ¤   goto done;
439371 ¤   }
68af5a
39b38c done:
a920a4 ····return ntStatus;
49efe6 }
--dd01 000753a400140110052 Page 10 of pgpMemLock.c
e0af5a
1aaf5a
aebf56 //----------------------------------------------------|
aeda42 // ·unlock the pages in the specified virtual address range
e6465d //
9deabd //¤ Arguments:
b205bf //¤ ¤   pDevO¤  ¤   ¤   ¤   - pointer to a device object
ca68f9 //¤ ¤   IoBuffer¤   ¤   ¤   - pointer to the I/O buffer
3fbf41 //¤ ¤   InputBufferLength¤  - input buffer length
c6b1e1 //¤ ¤   OutputBufferLength¤ - output buffer length
f4465d //
ca07c7 //¤ Return Value:
87a935 //¤ ¤   STATUS_SUCCESS if sucessful, otherwise
127cd2 //¤ ¤   STATUS_*·
55465d //
0faf5a
841e8a NTSTATUS
6dbcd2 PGPmlUnlockTheMemory(
c415ce ····IN PDEVICE_OBJECT¤  pDevO,
34845d ¤   IN PIRP¤¤   ¤   ¤   pIrp,
db438c ····IN OUT PVOID¤   ¤   IoBuffer,
a8c048 ····IN ULONG¤   ¤   ¤   InputBufferLength,
f90f60 ····IN ULONG¤   ¤   ¤   OutputBufferLength)
dcbb36 {
d0e9fa ¤   PPGPMEMLOCKSTRUCT¤  ppmls¤  ¤   ¤   = (PPGPMEMLOCKSTRUCT) IoBuffer;
22b125 ¤   NTSTATUS¤   ¤   ¤   ntStatus¤   ¤   = STATUS_SUCCESS;
2949aa ¤   ULONG¤  ¤   ¤   ¤   ulPage¤ ¤   ¤   = 0;
a5436d ¤   ULONG¤  ¤   ¤   ¤   ulNumPages¤ ¤   = 0;
adaf5a
e51694 ¤   PGPmlPrint (("PGPmemlock: PGPmlUnlockTheMemory.\n"));
69af5a
1f5600 ¤   if ((InputBufferLength < sizeof (PGPMEMLOCKSTRUCT)) ||
eb86af ¤   ¤   (OutputBufferLength < sizeof (PGPMEMLOCKSTRUCT)) ||
9d4bf3 ¤   ¤   (IoBuffer == NULL))
d1c7a1 ¤   {
5eccf0 ¤   ¤   PGPmlPrint (("PGPmemlock: Err: Invalid input parameters.\n"));
ac747b ¤   ¤   ntStatus = STATUS_INVALID_PARAMETER;
6f6fe7 ····}
ab4264 ¤   else·
edc7a1 ¤   {
b73ca8 ¤   ¤   // assume no error
c6ac37 ¤   ¤   ppmls->ulError = 0;
a4af5a
3d0cc0 ¤   ¤   // calculate page numbers
27221f ¤   ¤   ulPage = ((ULONG)(ppmls->pMem)) >> WIN32PAGESIZE;
50db38 ¤   ¤   ulNumPages = (((ppmls->ulNumBytes)-1) >> WIN32PAGESIZE ) +1;
91d840 ¤   ¤   PGPmlPrint (("PGPmemlock: unlocking page(s) %x - %x.\n",·
18a36c ¤   ¤   ¤   ¤   ¤   ¤   ulPage, ulPage+ulNumPages-1));
58af5a
5909e0 ¤   ¤   // unlock the pages·
02c7ab ¤   ¤   ntStatus = PGPmlUnlockBlock (pDevO, pIrp, ulPage, ulNumPages, TRUE);
9f9306 ¤   ¤   if (ntStatus != STATUS_SUCCESS)·
815b34 ¤   ¤   {
379b0f ¤   ¤   ¤   // we couldn't unlock the memory
1557c1 ¤   ¤   ¤   PGPmlPrint (("PGPmemlock: Err: PGPmlUnlockBlock failed.\n"));
9a91ee ¤   ¤   ¤   ppmls->ulError = kPGPMemLockError_UnlockError;
b00fe4 ¤   ¤   }
d99371 ¤   }
b9af5a
14afdb ¤   return ntStatus;
f3efe6 }
84af5a
a4af5a
11bf56 //----------------------------------------------------|
bfc375 // ·delete the associated device
f0465d //
51eabd //¤ Arguments:
fba5b3 //¤ ¤   pDrvO¤  ¤   - pointer to a driver object
a1465d //
86af5a
08fe80 VOID
755e8c PGPmlUnload(
--614b 000ed2b577040110052 Page 11 of pgpMemLock.c
183077 ····IN PDRIVER_OBJECT pDrvO)
457142 {·
416a63 ····WCHAR ··········deviceLinkBuffer[] ·= L"\\DosDevices\\PGPMEMLOCK";
f808db ····UNICODE_STRING¤ deviceLinkUnicodeString;
77dca8 ¤   PDEVICE_OBJECT¤ pDevO¤  ¤   ¤   ¤   = NULL;
9eaf5a
d60b7e ¤   // get first (and only) device object
17acd2 ¤   pDevO = pDrvO->DeviceObject;
2aaf5a
b84e98 ¤   // Unlock all blocks referenced in list and free list
0c5de7 ¤   if (KeGetCurrentIrql () < DISPATCH_LEVEL)·
9fc7a1 ¤   {
c4f097 ¤   ¤   PGPmlUnlockAllBlocks (pDevO);
709371 ¤   }
e7af5a
869fad ····// Delete the symbolic link
b224e9 ····RtlInitUnicodeString (&deviceLinkUnicodeString,
fc86df ··························deviceLinkBuffer);
dcb9d5 ····IoDeleteSymbolicLink (&deviceLinkUnicodeString);
88af5a
3c5ed5 ····// Delete the device object
f8f3a1 ····PGPmlPrint (("PGPmemlock: unloading.\n"));
1ae56d ····IoDeleteDevice (pDrvO->DeviceObject);
d5af5a
76bd73 ¤   // Close down our item allocation system
b7ada1 ¤   PGPmlHeapDestroy ();·
cbefe6 }
baaf5a
ffaf5a
dbbf56 //----------------------------------------------------|
60b6f4 // ·process the IRPs sent to this device
29465d //
baeabd //¤ Arguments:
a19b1e //¤ ¤   pDevO¤  ¤   - pointer to a device object
2c59fb //¤ ¤   pIrp¤   ¤   - pointer to an I/O Request Packet
97465d //
cb07c7 //¤ Return Value:
0b2584 //¤ ¤   STATUS_SUCCESS if successful,
f1ff48 //¤ ¤   STATUS_* otherwise
5c465d //
76af5a
e71e8a NTSTATUS
4c5f49 PGPmlDispatch(
81fd19 ····IN PDEVICE_OBJECT pDevO,
eb2720 ····IN PIRP pIrp)
2cbb36 {
62b0ca ····PIO_STACK_LOCATION pIrpStack¤   ¤   ¤   = NULL;
f308cd ····PVOID ·············ioBuffer¤¤   ¤   ¤   = NULL;
e3fe6f ····ULONG ·············inBufferLength¤  ¤   = 0;
d0ee1e ····ULONG ·············outBufferLength¤ ¤   = 0;
d6ac03 ····ULONG ·············ioControlCode¤   ¤   = 0;
b21bf7 ····NTSTATUS ··········ntStatus¤¤   ¤   ¤   = STATUS_SUCCESS;
53af5a
74bb97 ····// Init to default settings
c52856 ····pIrp->IoStatus.Status ·····= STATUS_SUCCESS;
a141ab ····pIrp->IoStatus.Information = 0;
baaf5a
7f6b57 ····// Get a pointer to the current location in the Irp. This is where
4e8e18 ····// ····the function codes and parameters are located.
38a700 ····pIrpStack = IoGetCurrentIrpStackLocation (pIrp);
d1af5a
6e3707 ····// Get the pointer to the input/output buffer and it's length
6d1bd5 ····ioBuffer ·······=·
649a83 ¤   ¤   ¤   ¤   pIrp->AssociatedIrp.SystemBuffer;
5cd259 ····inBufferLength ·=·
f406de ¤   ¤   ¤   ¤   pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
5d11aa ····outBufferLength =·
a651a8 ¤   ¤   ¤   ¤   pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
5daf5a
643f51 ····switch (pIrpStack->MajorFunction)
b83b37 ····{
ed34ba ¤   // called when user app calls CreateFile
--3d3b 00004a16efd40110052 Page 12 of pgpMemLock.c
5a6fab ····case IRP_MJ_CREATE:
db8101 ········PGPmlPrint (("PGPmemlock: IRP_MJ_CREATE\n"));
ee2d5f ········break;
5faf5a
413dd6 ¤   // called when user app closes handle to driver --
a4f044 ¤   //¤ make sure all locked memory belonging to this handle gets unlocked
ca9d0d ····case IRP_MJ_CLOSE:
ff6158 ¤   ¤   PGPmlPrint (("PGPmemlock: IRP_MJ_CLOSE\n"));
663bf5 ¤   ¤   if (KeGetCurrentIrql () < DISPATCH_LEVEL)
c05b34 ¤   ¤   {
019de8 ¤   ¤   ¤   PGPmlUnlockHandleBlocks (pDevO, pIrp);
0f0fe4 ¤   ¤   }
892f68 ¤   ¤   break;
15af5a
b8a8c7 ¤   // called when user apps calls DeviceIoControl
f398df ····case IRP_MJ_DEVICE_CONTROL:
b50501 ········ioControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
09af5a
7511de ········switch (ioControlCode)
0e2b60 ········{
c514d8 ¤   ¤   // user app wants to lock some memory ...
9710e0 ········case IOCTL_PGPMEMLOCK_LOCK_MEMORY:
70af5a
78eae7 ¤   ¤   ¤   // try locking it
bef369 ············pIrp->IoStatus.Status = PGPmlLockTheMemory (pDevO,
378f64 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pIrp,
e2af63 ························································ioBuffer,
e4cc3d ························································inBufferLength,
a75e68 ························································outBufferLength);
d2af5a
093d26 ············if (NT_SUCCESS(pIrp->IoStatus.Status))
ba2cc2 ············{
42e57f ················pIrp->IoStatus.Information = sizeof(PGPMEMLOCKSTRUCT);
e6f28f ················PGPmlPrint (("PGPmemlock: memory successfully locked.\n"));
197812 ············}
38e93c ············else
692cc2 ············{
beb4cb ················PGPmlPrint (("PGPmemlock: Err: memory lock failed.\n"));
1b7812 ············}
1f8632 ············break;
b4af5a
4c46a3 ¤   ¤   // user app wants to unlock some memory
60815a ········case IOCTL_PGPMEMLOCK_UNLOCK_MEMORY:
23af5a
84ec57 ¤   ¤   ¤   // try unlocking it ...
496173 ············pIrp->IoStatus.Status = PGPmlUnlockTheMemory (pDevO,
b47d7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··pIrp,
2abbef ·········································¤  ¤   ¤   ¤   ··ioBuffer,
a6629a ··························································inBufferLength,
53f0eb ··························································outBufferLength);
b5af5a
503d26 ············if (NT_SUCCESS(pIrp->IoStatus.Status))
7d2cc2 ············{
33dd56 ···············pIrp->IoStatus.Information = sizeof(PGPMEMLOCKSTRUCT);
49c1f8 ···············PGPmlPrint (("PGPmemlock: memory successfully unlocked.\n"));
7f7812 ············}
b5e93c ············else
c22cc2 ············{
601690 ················PGPmlPrint (("PGPmemlock: Err: memory unlock failed.\n"));
f47812 ············}
6f8632 ············break;
e0af5a
5b425b ········default:
ff77f8 ············pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER;
293c49 ············PGPmlPrint (
c144df ¤   ¤   ¤   ¤   ¤   ("PGPmemlock: Err: unknown IRP_MJ_DEVICE_CONTROL.\n"));
2b8632 ············break;
577fb0 ········}
0aaf5a
2a2d5f ········break;
7a6fe7 ····}
04af5a
--94e0 0001f79210b40110052 Page 13 of pgpMemLock.c
575516 ····ntStatus = pIrp->IoStatus.Status;
e40c5d ····IoCompleteRequest(pIrp, IO_NO_INCREMENT);
87af5a
0220a4 ····return ntStatus;
61efe6 }
acaf5a
11af5a
c1bf56 //----------------------------------------------------|
3c8378 // ·called upon initialization of driver
5e465d //
99eafc //¤ Routine Description:
69465d //
34c1f6 //¤ Installable driver initialization entry point.
2efef3 //¤ This entry point is called directly by the I/O system.
16465d //
8ceabd //¤ Arguments:
daa78a //¤ ¤   pDrvO¤  ¤   ·-¤ pointer to the driver object
b56c55 //¤ ¤   RegistryPath -¤ pointer to a unicode string representing the path
76336a //¤ ¤   ¤   ¤   ¤   ¤   to driver-specific key in the registry
87465d //
ba07c7 //¤ Return Value:
da2584 //¤ ¤   STATUS_SUCCESS if successful,
8eff48 //¤ ¤   STATUS_* otherwise
87465d //
7667c5 ¤
3d1e8a NTSTATUS
5873f1 DriverEntry(
3ac0af ····IN PDRIVER_OBJECT ·pDrvO,
e3c6ea ····IN PUNICODE_STRING RegistryPath)
75bb36 {
fcaf5a
1e6149 ····PDEVICE_OBJECT¤ pDevO¤  ¤   ¤   ¤   = NULL;
95d948 ····WCHAR¤  ¤   ¤   deviceNameBuffer[]¤ = L"\\Device\\PGPmemlock";
ad8591 ····UNICODE_STRING¤ deviceNameUnicodeString;
fc765c ····WCHAR¤  ¤   ¤   deviceLinkBuffer[]¤ = L"\\DosDevices\\PGPMEMLOCK";
0408db ····UNICODE_STRING¤ deviceLinkUnicodeString;
bcba95 ····NTSTATUS¤   ¤   ntStatus¤   ¤   ¤   = STATUS_SUCCESS;
acf483 ¤   PDEVEXTENSION¤  pde¤¤   ¤   ¤   ¤   = NULL;
afaf5a
689f49 ····PGPmlPrint (("PGPmemlock: entering DriverEntry.\n"));
daaf5a
e64c1b ¤   // Initialize internal list item allocation routines
4667ac ¤   ntStatus = PGPmlHeapInit ();
4f1ee1 ¤   if (!NT_SUCCESS (ntStatus))·
05c7a1 ¤   {
152bc8 ¤   ¤   PGPmlPrint (("PGPmemlock: Err: PGPmlHeapInit failed.\n"));
f81e0a ¤   ¤   return ntStatus;
f29371 ¤   }
3baf5a
1b7d05 ····// Create an NON exclusive device object (multiple threads
38e950 ····// can make requests to this device at a time)
faa9a3 ····RtlInitUnicodeString (&deviceNameUnicodeString,
eaf821 ··························deviceNameBuffer);
89af5a
fd0512 ¤   ntStatus = IoCreateDevice (pDrvO,
e91344 ·······························sizeof(DEVEXTENSION),
bbe675 ·······························&deviceNameUnicodeString,
256899 ·······························FILE_DEVICE_PGPMEMLOCK,
939086 ·······························0,
b10401 ·······························FALSE,
a1476c ·······························&pDevO);
e6af5a
834fcc ····if (NT_SUCCESS(ntStatus))
bd3b37 ····{
32943a ········// Create dispatch points for device control, create, close.
f63e0f ········pDrvO->MajorFunction[IRP_MJ_CREATE] ········=
b8df0b ········pDrvO->MajorFunction[IRP_MJ_CLOSE] ·········=
61eeec ········pDrvO->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PGPmlDispatch;
dec7a4 ········pDrvO->DriverUnload ························= PGPmlUnload;
afaf5a
1d696a ········// Create a symbolic link, e.g. a name that a Win32 app can specify
1f25cf ········// to open the device
--2311 0010836da0b40110052 Page 14 of pgpMemLock.c
f0d368 ········RtlInitUnicodeString(&deviceLinkUnicodeString,
d4e961 ·····························deviceLinkBuffer);
5118ff ········ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
bd577e ·········································&deviceNameUnicodeString);
2baf5a
eb2000 ········if (!NT_SUCCESS(ntStatus))
bf2b60 ········{
173f54 ············// Symbolic link creation failed- note this & then delete the
b72b21 ············// device object (it's useless if a Win32 app can't get at it).
ce1a22 ············PGPmlPrint (("PGPmemlock: Err: IoCreateSymbolicLink failed.\n"));
13ab37 ············IoDeleteDevice (pDevO);
e37fb0 ········}
12ee26 ¤   ¤   else·
555b34 ¤   ¤   {
d1e581 ¤   ¤   ¤   // initialize the device extension data structure
9ccfa3 ¤   ¤   ¤   pde = (PDEVEXTENSION)(pDevO->DeviceExtension);
b9d967 ¤   ¤   ¤   memset (pde, 0, sizeof(DEVEXTENSION));
ec128b ¤   ¤   ¤   KeInitializeSpinLock (&pde->slListLock);
2a0fe4 ¤   ¤   }
a56fe7 ····}
13842c ····else
073b37 ····{
405883 ········PGPmlPrint (("PGPmemlock: Err: IoCreateDevice failed.\n"));
606fe7 ····}
0faf5a
5720a4 ····return ntStatus;
39efe6 }
5baf5a
08af5a
--995d 0017d1f294b40110053 Page 1 of pgpMemLock.rc
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
b7e95a ¤   PGPmemlock.rc - PGPmemlock version information
4767c5 ¤
35af5a
5da0ab ¤   $Id: pgpMemLock.rc,v 1.5 1998/08/11 13:43:55 pbj Exp $
05f7f7 ____________________________________________________________________________*/
315655 #include <windows.h>
fdaf5a
9d737c #include "pgpver.h"
9daf5a
a0af5a
d021be /*---------------------------------------------------*/
d29e09 /* The following values should be modified only by ··*/
e0f9e4 /* the official builder, and they should be updated ·*/·
6f738d /* for each build ···································*/
ae21be /*---------------------------------------------------*/
5caf5a
51e211 #define VER_PRODUCTBUILD¤   ··0
f53c71 #define VER_PRODUCTVERSION_STR "1.0"
3fdf8e #define VER_PRODUCTVERSION¤ ··1,0,VER_PRODUCTBUILD,1
03aeb9 #define VER_PRODUCTBETA_STR¤ ·""
5baf5a
f0af5a
7721be /*---------------------------------------------------*/
55f5ce /* Include product-specific default values ··········*/
f3aff9 /*¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····¤   ¤   ·*/
a921be /*---------------------------------------------------*/
4eaf5a
379392 #define VER_PRODUCTNAME_STR¤¤   "PGPmemlock"
5f21d0 #define VER_FILETYPE¤   ¤   ¤   VFT_DRV
2f354d #define VER_FILESUBTYPE¤¤   ¤   VFT2_UNKNOWN
fd3ac5 #define VER_FILEDESCRIPTION_STR¤"Page-locking kernel mode driver"
04cbc4 #define VER_INTERNALNAME_STR¤   ¤   "PGPmemlock.sys"
29b409 #define VER_ORIGINALFILENAME_STR¤   "PGPmemlock.sys"
c8af5a
af21be /*---------------------------------------------------*/
e3e8e7 /* Define the version resource itself ···············*/
f0aff9 /*¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····¤   ¤   ·*/
0c21be /*---------------------------------------------------*/
4f5e37 #include <common.ver>
bdaf5a
00af5a
18af5a
7daf5a
--927c 0013f86382740110054 Page 1 of pgpVer.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
577c21 ¤   PGPver.h - PGP company-specific version information
4e67c5 ¤
e1af5a
54cb4e ¤   $Id: pgpVer.h,v 1.3 1998/08/11 13:43:56 pbj Exp $
07f7f7 ____________________________________________________________________________*/
b8af5a
6229e9 #define VER_COMPANYNAME_STR¤¤   "Network Associates, Inc."
dfaf5a
c0dde4 #define VER_LEGALTRADEMARKS_STR¤\
7cbafb "PGP is a trademark of Network Associates, Inc."
24af5a
efe44a #define VER_LEGALCOPYRIGHT_YEARS ···"1998"
0faf5a
e6b9ce #define VER_LEGALCOPYRIGHT_STR¤ ¤   \
63bb2b ¤   "Copyright (c) Network Associates, Inc. " ¤ \
5dd01f ¤   VER_LEGALCOPYRIGHT_YEARS
fcaf5a
05af5a
2d7ef2 /* default is nodebug */
ab55e7 #if DBG
42b415 #define VER_DEBUG¤  ¤   ¤   ¤   VS_FF_DEBUG
51db21 #else
568b4b #define VER_DEBUG¤  ¤   ¤   ¤   0
ed7454 #endif
1eaf5a
7505f9 /* default is release */
399838 #if BETA
0f8714 #define VER_PRERELEASE¤ ¤   ¤   VS_FF_PRERELEASE
93db21 #else
19bc05 #define VER_PRERELEASE¤ ¤   ¤   0
3a7454 #endif
b6af5a
4f5af0 #define VER_FILEFLAGSMASK ·VS_FFI_FILEFLAGSMASK
4a1543 #define VER_FILEOS¤ ¤   ···VOS_NT_WINDOWS32
3dc72d #define VER_FILEFLAGS¤  ···(VER_PRERELEASE | VER_DEBUG)
33af5a
3faf5a

--a831 000c16d954740110055 Page 1 of pflCommon.dsp
88b7ee # Microsoft Developer Studio Project File - Name="pflCommon" - Package Owner=<4>
92e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
668537 # ** DO NOT EDIT **
abaf5a
5a877a # TARGTYPE "Win32 (x86) Static Library" 0x0104
74af5a
d303a4 CFG=pflCommon - Win32 Debug
fa894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
b95c35 !MESSAGE use the Export Makefile command and run
4b6309 !MESSAGE·
6f3de2 !MESSAGE NMAKE /f "pflCommon.mak".
b96309 !MESSAGE·
b0cdb3 !MESSAGE You can specify a configuration when running NMAKE
6ee013 !MESSAGE by defining the macro CFG on the command line. For example:
9f6309 !MESSAGE·
c5e3c9 !MESSAGE NMAKE /f "pflCommon.mak" CFG="pflCommon - Win32 Debug"
486309 !MESSAGE·
831dd7 !MESSAGE Possible choices for configuration are:
f06309 !MESSAGE·
80f625 !MESSAGE "pflCommon - Win32 Release" (based on "Win32 (x86) Static Library")
97dcf9 !MESSAGE "pflCommon - Win32 Debug" (based on "Win32 (x86) Static Library")
dc6309 !MESSAGE·
baaf5a
da3e63 # Begin Project
d6b23f # PROP Scc_ProjName ""
d1df4a # PROP Scc_LocalPath ""
e140a4 CPP=cl.exe
3eaf5a
6d4cae !IF ·"$(CFG)" == "pflCommon - Win32 Release"
f0af5a
ac8243 # PROP BASE Use_MFC 0
d1e662 # PROP BASE Use_Debug_Libraries 0
cf7d73 # PROP BASE Output_Dir "Release"
9a6180 # PROP BASE Intermediate_Dir "Release"
074c81 # PROP BASE Target_Dir ""
9721ad # PROP Use_MFC 0
69b771 # PROP Use_Debug_Libraries 0
d4f310 # PROP Output_Dir "Release"
2101a1 # PROP Intermediate_Dir "Release"
f7b6fa # PROP Target_Dir ""
5e4fa4 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD¶
8c9f26 ·/c
30eb87 # ADD CPP /nologo /MT /W3 /GX /O2 /I "../" /I "../../common" /I "../../common/f¶
c3a6cd ile" /I "../../common/prefs" /I "../../common/util" /I "../../common/lthread" /¶
959826 I "../../../pgpcdk/pub/include" /I "../../../../pgpcdk/pub/include" /I "../../.¶
13b425 ./pgpcdk/win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D PGP_DEBUG=0 /D PGP_WIN3¶
aeedd6 2=1 /YX /FD /c
2318fc BSC32=bscmake.exe
c67a24 # ADD BASE BSC32 /nologo
894f1b # ADD BSC32 /nologo
627a92 LIB32=link.exe -lib
78629d # ADD BASE LIB32 /nologo
fc57a2 # ADD LIB32 /nologo
3daf5a
eb663b !ELSEIF ·"$(CFG)" == "pflCommon - Win32 Debug"
9eaf5a
298243 # PROP BASE Use_MFC 0
b5ffba # PROP BASE Use_Debug_Libraries 1
b554b8 # PROP BASE Output_Dir "Debug"
5b198a # PROP BASE Intermediate_Dir "Debug"
804c81 # PROP BASE Target_Dir ""
8221ad # PROP Use_MFC 0
a4aea9 # PROP Use_Debug_Libraries 1
a0ad22 # PROP Output_Dir "Debug"
69b954 # PROP Intermediate_Dir "Debug"
adb6fa # PROP Target_Dir ""
7e7248 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX¶
5310c2 ·/FD /c
46e0c6 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "../" /I "../../common" /I "../../com¶
d509f6 mon/file" /I "../../common/prefs" /I "../../common/util" /I "../../common/lthre¶
cb4811 ad" /I "../../../pgpcdk/pub/include" /I "../../../../pgpcdk/pub/include" /I "..¶
c12d36 /../../pgpcdk/win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D UNFINISHED_CODE_AL¶
--6f66 0001b5b377440110055 Page 2 of pflCommon.dsp
cc4244 LOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /YX /FD /c
6e18fc BSC32=bscmake.exe
ae7a24 # ADD BASE BSC32 /nologo
6e4f1b # ADD BSC32 /nologo
647a92 LIB32=link.exe -lib
1f629d # ADD BASE LIB32 /nologo
f457a2 # ADD LIB32 /nologo
52af5a
6b30ec !ENDIF·
04af5a
89b8a5 # Begin Target
69af5a
a24b51 # Name "pflCommon - Win32 Release"
98f2f5 # Name "pflCommon - Win32 Debug"
6c4cc4 # Begin Group "Source Files"
b9af5a
df56ed # PROP Default_Filter "c;cpp"
00df4f # Begin Source File
e4af5a
66c1a4 SOURCE=..\..\common\prefs\pflPrefs.c
a56ccd # End Source File
cddf4f # Begin Source File
f0af5a
0916f3 SOURCE=..\..\common\prefs\pflPrefTypes.c
346ccd # End Source File
46df4f # Begin Source File
8daf5a
614a5f SOURCE=..\pgpAsyncDNS\pgpAsyncDNS.c
3b6ccd # End Source File
0fdf4f # Begin Source File
99af5a
cd43db SOURCE=..\..\common\pgpBinaryTree.c
876ccd # End Source File
2adf4f # Begin Source File
d8af5a
1789d2 SOURCE=..\..\common\lthread\pgpCond.c
a16ccd # End Source File
3fdf4f # Begin Source File
a0af5a
cdea8f SOURCE=..\..\common\pgpDebug.c
a96ccd # End Source File
19df4f # Begin Source File
45af5a
2b7759 SOURCE=..\..\common\util\pgpEndianConversion.c
e56ccd # End Source File
addf4f # Begin Source File
c3af5a
0da72f SOURCE=..\..\common\file\pgpFileIO.c
426ccd # End Source File
bbdf4f # Begin Source File
e5af5a
bbd17a SOURCE=..\..\common\file\pgpFileSpec.c
e46ccd # End Source File
92df4f # Begin Source File
edaf5a
7b05e2 SOURCE=..\..\common\file\pgpFileSpecStd.c
e06ccd # End Source File
9cdf4f # Begin Source File
b6af5a
97ae5f SOURCE=..\..\common\file\pgpFileSpecVTBL.c
e26ccd # End Source File
f6df4f # Begin Source File
7aaf5a
37a876 SOURCE=..\..\common\file\pgpFileSpecWin32.c
676ccd # End Source File
25df4f # Begin Source File
0caf5a
78a057 SOURCE=..\..\common\file\pgpFileUtilities.c
ca6ccd # End Source File
12df4f # Begin Source File
16af5a
1b0611 SOURCE=..\..\common\util\pgpHex.c
--9c99 000d688f4ca40110055 Page 3 of pflCommon.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
2fa1cc SOURCE=..\..\common\file\pgpIO.c
706ccd # End Source File
b6df4f # Begin Source File
a5af5a
95db9f SOURCE=..\..\common\file\pgpIOUtilities.c
726ccd # End Source File
6fdf4f # Begin Source File
6aaf5a
feaffb SOURCE=..\..\common\pgpLeaks.c
9c6ccd # End Source File
06df4f # Begin Source File
32af5a
e5b067 SOURCE=..\..\common\file\pgpLineEndIO.c
486ccd # End Source File
a0df4f # Begin Source File
55af5a
9274e4 SOURCE=..\..\common\pgpMem.c
4b6ccd # End Source File
72df4f # Begin Source File
2caf5a
e8f71b SOURCE=..\..\common\file\pgpMemoryIO.c
cf6ccd # End Source File
6bdf4f # Begin Source File
afaf5a
65704d SOURCE=..\..\common\pgpMemoryMgrWin32.c
846ccd # End Source File
5adf4f # Begin Source File
99af5a
b183ed SOURCE=..\..\common\lthread\pgpMutex.c
6c6ccd # End Source File
6edf4f # Begin Source File
b6af5a
ca6050 SOURCE=..\..\common\util\pgpPassphraseUtils.c
256ccd # End Source File
9adf4f # Begin Source File
1baf5a
7a39d4 SOURCE=..\..\common\file\pgpProxyIO.c
556ccd # End Source File
19df4f # Begin Source File
d0af5a
79c761 SOURCE=..\..\common\pgpRMWOLock.c
976ccd # End Source File
b3df4f # Begin Source File
beaf5a
b3d52c SOURCE=..\..\common\lthread\pgpSemaphore.c
f56ccd # End Source File
a2df4f # Begin Source File
dbaf5a
7845bb SOURCE=..\..\common\file\pgpStdFileIO.c
db6ccd # End Source File
0bdf4f # Begin Source File
5baf5a
5636a2 SOURCE=..\..\common\util\pgpStrings.c
4d6ccd # End Source File
91df4f # Begin Source File
71af5a
343e0c SOURCE=..\..\common\lthread\pgpThreads.c
4e6ccd # End Source File
2cdf4f # Begin Source File
f1af5a
055172 SOURCE=..\..\common\util\pgpWordWrap.c
866ccd # End Source File
cb3f5a # End Group
c1ba44 # Begin Group "Header Files"
3daf5a
1d6783 # PROP Default_Filter "h;hpp"
20df4f # Begin Source File
3caf5a
d6250c SOURCE=..\..\common\prefs\pflPrefs.h
--bba7 0002083530740110055 Page 4 of pflCommon.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
80f25b SOURCE=..\..\common\prefs\pflPrefTypes.h
196ccd # End Source File
94df4f # Begin Source File
c1af5a
798d7b SOURCE=..\..\common\pflTypes.h
756ccd # End Source File
c2df4f # Begin Source File
c1af5a
8babea SOURCE=..\..\common\pgpBase.h
6f6ccd # End Source File
bcdf4f # Begin Source File
abaf5a
b1a773 SOURCE=..\..\common\pgpBinaryTree.h
a96ccd # End Source File
1cdf4f # Begin Source File
cbaf5a
0e0e27 SOURCE=..\..\common\pgpDebug.h
4a6ccd # End Source File
89df4f # Begin Source File
1daf5a
7c93f1 SOURCE=..\..\common\util\pgpEndianConversion.h
cf6ccd # End Source File
57df4f # Begin Source File
33af5a
99a7cf SOURCE=..\..\common\pgpException.h
a26ccd # End Source File
1cdf4f # Begin Source File
fcaf5a
024387 SOURCE=..\..\common\file\pgpFileIO.h
936ccd # End Source File
7bdf4f # Begin Source File
2daf5a
08d5c1 SOURCE=..\..\common\file\pgpFileIOPriv.h
756ccd # End Source File
5edf4f # Begin Source File
f7af5a
1735d2 SOURCE=..\..\common\file\pgpFileSpec.h
d46ccd # End Source File
badf4f # Begin Source File
82af5a
ef3881 SOURCE=..\..\common\file\pgpFileSpecPriv.h
ce6ccd # End Source File
2adf4f # Begin Source File
0baf5a
eae14a SOURCE=..\..\common\file\pgpFileSpecStd.h
6f6ccd # End Source File
ecdf4f # Begin Source File
95af5a
06dff8 SOURCE=..\..\common\file\pgpFileSpecStdPriv.h
956ccd # End Source File
4edf4f # Begin Source File
69af5a
5f4af7 SOURCE=..\..\common\file\pgpFileSpecVTBL.h
316ccd # End Source File
b7df4f # Begin Source File
7caf5a
4744ff SOURCE=..\..\common\file\pgpFileUtilities.h
b66ccd # End Source File
76df4f # Begin Source File
4baf5a
601ef8 SOURCE=..\..\common\sorting\pgpHeapSort.h
686ccd # End Source File
2ddf4f # Begin Source File
02af5a
d7e2b9 SOURCE=..\..\common\util\pgpHex.h
3e6ccd # End Source File
dcdf4f # Begin Source File
d8af5a
20a373 SOURCE=..\..\common\sorting\pgpInsertionSort.h
--cf8b 000067cd10540110055 Page 5 of pflCommon.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
cc4564 SOURCE=..\..\common\file\pgpIO.h
426ccd # End Source File
e6df4f # Begin Source File
6baf5a
68925f SOURCE=..\..\common\file\pgpIOPriv.h
036ccd # End Source File
afdf4f # Begin Source File
a7af5a
d83f37 SOURCE=..\..\common\file\pgpIOUtilities.h
ed6ccd # End Source File
02df4f # Begin Source File
7daf5a
8a4b53 SOURCE=..\..\common\pgpLeaks.h
336ccd # End Source File
acdf4f # Begin Source File
18af5a
1c54cf SOURCE=..\..\common\file\pgpLineEndIO.h
b06ccd # End Source File
95df4f # Begin Source File
ecaf5a
ad2f3e SOURCE=..\..\common\file\pgpLineEndIOPriv.h
d76ccd # End Source File
31df4f # Begin Source File
b5af5a
68904c SOURCE=..\..\common\pgpMem.h
b76ccd # End Source File
2cdf4f # Begin Source File
d9af5a
023afd SOURCE=..\pgpMemLockWin32.h
6c6ccd # End Source File
dfdf4f # Begin Source File
c0af5a
7613b3 SOURCE=..\..\common\file\pgpMemoryIO.h
986ccd # End Source File
c7df4f # Begin Source File
2caf5a
da683c SOURCE=..\..\common\file\pgpMemoryIOPriv.h
2a6ccd # End Source File
46df4f # Begin Source File
c2af5a
cbb09a SOURCE=..\..\common\pgpMemoryMgr.h
426ccd # End Source File
4edf4f # Begin Source File
19af5a
e4febf SOURCE=..\..\common\pgpMemoryMgrPriv.h
166ccd # End Source File
90df4f # Begin Source File
6daf5a
bd84f8 SOURCE=..\..\common\util\pgpPassphraseUtils.h
236ccd # End Source File
efdf4f # Begin Source File
01af5a
78ddbd SOURCE=..\pgpPFLConfig.h
396ccd # End Source File
37df4f # Begin Source File
40af5a
58d534 SOURCE=..\..\common\pgpPFLErrors.h
366ccd # End Source File
1bdf4f # Begin Source File
ffaf5a
7ddd7c SOURCE=..\..\common\file\pgpProxyIO.h
d86ccd # End Source File
2fdf4f # Begin Source File
60af5a
4afb9d SOURCE=..\..\common\file\pgpProxyIOPriv.h
be6ccd # End Source File
d2df4f # Begin Source File
0caf5a
06ab16 SOURCE=..\pgpRMWOLock.h
--66b6 001d56d7a2640110055 Page 6 of pflCommon.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
6da113 SOURCE=..\..\common\file\pgpStdFileIO.h
706ccd # End Source File
6cdf4f # Begin Source File
0daf5a
b8f5fb SOURCE=..\..\common\file\pgpStdFileIOPriv.h
7e6ccd # End Source File
07df4f # Begin Source File
b8af5a
10d20a SOURCE=..\..\common\util\pgpStrings.h
376ccd # End Source File
72df4f # Begin Source File
05af5a
4e1ee7 SOURCE=..\..\common\pgpTypes.h
a06ccd # End Source File
45df4f # Begin Source File
3baf5a
20b5da SOURCE=..\..\common\util\pgpWordWrap.h
846ccd # End Source File
713f5a # End Group
3ce5cf # End Target
d5f262 # End Project
--1053 001ac2c07e540110056 Page 1 of pflCommon.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
caac61 Project: "pflCommon"=".\pflCommon.dsp" - Package Owner=<4>
b1af5a
e5e41b Package=<5>
888818 {{{
7f418b }}}
4faf5a
47bec7 Package=<4>
c68818 {{{
16418b }}}
47af5a
c52d94 ###############################################################################
4daf5a
0520da Global:
92af5a
84e41b Package=<5>
bc8818 {{{
5f418b }}}
3eaf5a
c332c2 Package=<3>
928818 {{{
ed418b }}}
e0af5a
902d94 ###############################################################################
acaf5a

--26f3 000c481c83040110057 Page 1 of pgpAsyncDNS.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
d595e0 ¤   pgpAsyncDNS.c¤  -¤  Async calls for dns
c067c5 ¤
dfaf5a
56c545 ¤   $Id: pgpAsyncDNS.c,v 1.3.12.1 1998/11/12 03:20:17 heller Exp $
89f7f7 ____________________________________________________________________________*/
97af5a
1c11a9 #include <process.h>
40af5a
cc51b9 #include "pgpRMWOLock.h"
92a21a #include "pgpAsyncDNS.h"
8daf5a
61af5a
37c4cd #define kMaxNameSize¤   256
b8af5a
2baf5a
25e995 struct PGPAsyncHostEntry {
75b73d ¤   HANDLE¤ ¤   ¤   threadHandle;
51b4d0 ¤   HANDLE¤ ¤   ¤   cancelSemaphore;
a096b5 ¤   PGPRMWOLock¤¤   resultLock;
895caa ¤   PGPError¤   ¤   result;
73c6c0 ¤   PGPUInt32¤  ¤   address;
0479a6 ¤   char¤   ¤   ¤   name[kMaxNameSize];
e182f7 };
75af5a
f2af5a
42af5a
3833c8 ¤   static void
5fed46 sGetHostByNameThread(
81a730 ¤   void *¤ inAsyncHostEntry)
37bb36 {
b7e25a ¤   PGPHostEntry *¤ ¤   ¤   ¤   hostEntry;
321dc5 ¤   PGPError¤   ¤   ¤   ¤   ¤   result = kPGPError_NoErr;
e2de4f ¤   PGPSocketsThreadStorageRef¤ storage;
c467c5 ¤
ba21fa ¤   PGPSocketsInit();
ca032e ¤   PGPSocketsCreateThreadStorage(&storage);
827f46 ¤   hostEntry = PGPGetHostByName(((PGPAsyncHostEntryRef) inAsyncHostEntry)->nam¶
f295c6 e);
44e472 ¤   if (hostEntry == NULL) {
dfb45e ¤   ¤   result = PGPGetLastSocketsError();
7025fe ¤   ¤   if (result == kPGPError_NoErr) {
0047f2 ¤   ¤   ¤   result = kPGPError_UnknownError;
e60fe4 ¤   ¤   }
0c9371 ¤   }
601456 ¤   PGPSocketsDisposeThreadStorage(storage);
2aba95 ¤   PGPSocketsCleanup();
33044a ¤   PGPRMWOLockStartWriting(&((PGPAsyncHostEntryRef) inAsyncHostEntry)->resultL¶
3d3dc3 ock);
366a52 ¤   if (((PGPAsyncHostEntryRef) inAsyncHostEntry)->result != kPGPError_UserAbor¶
d2f6de t) {
d3e400 ¤   ¤   ((PGPAsyncHostEntryRef) inAsyncHostEntry)->result = result;
e2cc9e ¤   ¤   if (hostEntry != NULL) {
cd1861 ¤   ¤   ¤   ((PGPAsyncHostEntryRef) inAsyncHostEntry)->address =·
337e0e ¤   ¤   ¤   ¤   *((PGPUInt32 *)hostEntry->h_addr);
330fe4 ¤   ¤   }
f79371 ¤   }
84e9c8 ¤   PGPRMWOLockStopWriting(&((PGPAsyncHostEntryRef) inAsyncHostEntry)->resultLo¶
3787fb ck);
2f67c5 ¤
113910 ¤   if (result == kPGPError_UserAbort) {
637d73 ¤   ¤   CloseHandle(((PGPAsyncHostEntryRef) inAsyncHostEntry)->cancelSemaphore);
b66ad7 ¤   ¤   DeletePGPRMWOLock(&((PGPAsyncHostEntryRef) inAsyncHostEntry)->resultLoc¶
273b84 k);
c19e2a ¤   ¤   free(inAsyncHostEntry);
ee9371 ¤   }
57efe6 }
e0af5a
c4af5a
--6ff2 000c683720140110057 Page 2 of pgpAsyncDNS.c
e0af5a
1433c8 ¤   static void
48e9fa sGetHostByAddressThread(
35a730 ¤   void *¤ inAsyncHostEntry)
5bbb36 {
66e25a ¤   PGPHostEntry *¤ ¤   ¤   ¤   hostEntry;
d34e64 ¤   PGPInternetAddress¤ ¤   ¤   theAddress;
b21dc5 ¤   PGPError¤   ¤   ¤   ¤   ¤   result = kPGPError_NoErr;
0bde4f ¤   PGPSocketsThreadStorageRef¤ storage;
7b67c5 ¤
e42a03 ¤   theAddress.s_addr = PGPHostToNetLong(
d3440b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ((PGPAsyncHostEntryRef) inAsyncHostEntry)->address);
ac21fa ¤   PGPSocketsInit();
5c032e ¤   PGPSocketsCreateThreadStorage(&storage);
12daf1 ¤   hostEntry = PGPGetHostByAddress(¤   (const char *) &theAddress,
215592 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(PGPInternetAddress),
67accc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPProtocolFamilyInternet);
b5e472 ¤   if (hostEntry == NULL) {
23b45e ¤   ¤   result = PGPGetLastSocketsError();
e725fe ¤   ¤   if (result == kPGPError_NoErr) {
ba47f2 ¤   ¤   ¤   result = kPGPError_UnknownError;
090fe4 ¤   ¤   }
6b9371 ¤   }
f91456 ¤   PGPSocketsDisposeThreadStorage(storage);
79ba95 ¤   PGPSocketsCleanup();
db044a ¤   PGPRMWOLockStartWriting(&((PGPAsyncHostEntryRef) inAsyncHostEntry)->resultL¶
f53dc3 ock);
786a52 ¤   if (((PGPAsyncHostEntryRef) inAsyncHostEntry)->result != kPGPError_UserAbor¶
05f6de t) {
cee400 ¤   ¤   ((PGPAsyncHostEntryRef) inAsyncHostEntry)->result = result;
8ecc9e ¤   ¤   if (hostEntry != NULL) {
5572f2 ¤   ¤   ¤   strcpy(((PGPAsyncHostEntryRef) inAsyncHostEntry)->name, hostEntry->¶
200894 h_name);
200fe4 ¤   ¤   }
d99371 ¤   }
bce9c8 ¤   PGPRMWOLockStopWriting(&((PGPAsyncHostEntryRef) inAsyncHostEntry)->resultLo¶
5687fb ck);
4167c5 ¤
413910 ¤   if (result == kPGPError_UserAbort) {
3b7d73 ¤   ¤   CloseHandle(((PGPAsyncHostEntryRef) inAsyncHostEntry)->cancelSemaphore);
7a6ad7 ¤   ¤   DeletePGPRMWOLock(&((PGPAsyncHostEntryRef) inAsyncHostEntry)->resultLoc¶
7f3b84 k);
c79e2a ¤   ¤   free(inAsyncHostEntry);
6d9371 ¤   }
f2efe6 }
39af5a
ceaf5a
cdc744 ¤   PGPError
148d96 PGPStartAsyncGetHostByName(
094927 ¤   const char *¤   ¤   ¤   inName,
d707d4 ¤   PGPAsyncHostEntryRef *¤ outAsyncHostEntry)
0abb36 {
7ee74b ¤   PGPError¤   ¤   ¤   ¤   result = kPGPError_NoErr;
bb3d45 ¤   PGPAsyncHostEntryRef¤   ref = kPGPInvalidAsyncHostEntryRef;
e467c5 ¤
d69ea9 ¤   PGPValidatePtr(outAsyncHostEntry);
221c87 ¤   *outAsyncHostEntry = kPGPInvalidAsyncHostEntryRef;
a0151a ¤   PGPValidatePtr(inName);
109573 ¤   PGPValidateParam(strlen(inName) < kMaxNameSize);
1b67c5 ¤
560849 ¤   ref = (PGPAsyncHostEntryRef) calloc(1, sizeof(struct PGPAsyncHostEntry));
39967c ¤   if (ref == NULL) {
d35e00 ¤   ¤   result = kPGPError_OutOfMemory;
259371 ¤   }
2a67c5 ¤
fbfe94 ¤   if (IsntPGPError(result)) {
e588e7 ¤   ¤   ref->result = kPGPError_SocketsInProgress;
8a9a1c ¤   ¤   InitializePGPRMWOLock(&ref->resultLock);
679371 ¤   }
6b67c5 ¤
6afe94 ¤   if (IsntPGPError(result)) {
c6ce43 ¤   ¤   ref->cancelSemaphore = CreateSemaphore(NULL, 0, 3, NULL);
--48bd 000e88618c340110057 Page 3 of pgpAsyncDNS.c
bae2b4 ¤   ¤   if (ref->cancelSemaphore == NULL) {
e947f2 ¤   ¤   ¤   result = kPGPError_UnknownError;
f70fe4 ¤   ¤   }
709371 ¤   }
e867c5 ¤
affe94 ¤   if (IsntPGPError(result)) {
ba733d ¤   ¤   strcpy(ref->name, inName);
4b37e4 ¤   ¤   ref->threadHandle = (HANDLE) _beginthread(sGetHostByNameThread, 0, ref);
a83323 ¤   ¤   if (ref->threadHandle == (HANDLE) -1) {
8747f2 ¤   ¤   ¤   result = kPGPError_UnknownError;
260fe4 ¤   ¤   }
ac9371 ¤   }
2967c5 ¤
fcfe94 ¤   if (IsntPGPError(result)) {
19f4b4 ¤   ¤   *outAsyncHostEntry = ref;
22f037 ¤   } else {
10e727 ¤   ¤   if (ref != NULL) {
4d695e ¤   ¤   ¤   if (ref->cancelSemaphore != NULL) {
5cf13e ¤   ¤   ¤   ¤   CloseHandle(ref->cancelSemaphore);
aca3a6 ¤   ¤   ¤   }
f690a8 ¤   ¤   ¤   DeletePGPRMWOLock(&ref->resultLock);
32752c ¤   ¤   ¤   free(ref);
6b0fe4 ¤   ¤   }
c79371 ¤   }
8767c5 ¤
b55d73 ¤   return result;
8eefe6 }
a0af5a
a2af5a
10af5a
6ec744 ¤   PGPError
5e4e60 PGPStartAsyncGetHostByAddress(
f3e0b5 ¤   PGPUInt32¤  ¤   ¤   ¤   inAddress,
9107d4 ¤   PGPAsyncHostEntryRef *¤ outAsyncHostEntry)
8dbb36 {
1ce74b ¤   PGPError¤   ¤   ¤   ¤   result = kPGPError_NoErr;
1a3d45 ¤   PGPAsyncHostEntryRef¤   ref = kPGPInvalidAsyncHostEntryRef;
2467c5 ¤
509ea9 ¤   PGPValidatePtr(outAsyncHostEntry);
ae1c87 ¤   *outAsyncHostEntry = kPGPInvalidAsyncHostEntryRef;
ef67c5 ¤
300849 ¤   ref = (PGPAsyncHostEntryRef) calloc(1, sizeof(struct PGPAsyncHostEntry));
b7967c ¤   if (ref == NULL) {
ef5e00 ¤   ¤   result = kPGPError_OutOfMemory;
769371 ¤   }
9e67c5 ¤
77fe94 ¤   if (IsntPGPError(result)) {
e988e7 ¤   ¤   ref->result = kPGPError_SocketsInProgress;
629a1c ¤   ¤   InitializePGPRMWOLock(&ref->resultLock);
7f9371 ¤   }
b667c5 ¤
acfe94 ¤   if (IsntPGPError(result)) {
b7ce43 ¤   ¤   ref->cancelSemaphore = CreateSemaphore(NULL, 0, 3, NULL);
8fe2b4 ¤   ¤   if (ref->cancelSemaphore == NULL) {
d747f2 ¤   ¤   ¤   result = kPGPError_UnknownError;
eb0fe4 ¤   ¤   }
2a9371 ¤   }
0567c5 ¤
2bfe94 ¤   if (IsntPGPError(result)) {
9b4b52 ¤   ¤   ref->address = inAddress;
22aca5 ¤   ¤   ref->threadHandle = (HANDLE) _beginthread(sGetHostByAddressThread, 0, r¶
7d37ec ef);
fc3323 ¤   ¤   if (ref->threadHandle == (HANDLE) -1) {
6747f2 ¤   ¤   ¤   result = kPGPError_UnknownError;
f90fe4 ¤   ¤   }
059371 ¤   }
7e67c5 ¤
69fe94 ¤   if (IsntPGPError(result)) {
92f4b4 ¤   ¤   *outAsyncHostEntry = ref;
d6f037 ¤   } else {
ffe727 ¤   ¤   if (ref != NULL) {
e8695e ¤   ¤   ¤   if (ref->cancelSemaphore != NULL) {
--f421 000c709145840110057 Page 4 of pgpAsyncDNS.c
35f13e ¤   ¤   ¤   ¤   CloseHandle(ref->cancelSemaphore);
2da3a6 ¤   ¤   ¤   }
c690a8 ¤   ¤   ¤   DeletePGPRMWOLock(&ref->resultLock);
4c752c ¤   ¤   ¤   free(ref);
c00fe4 ¤   ¤   }
1c9371 ¤   }
c467c5 ¤
4d5d73 ¤   return result;
f2efe6 }
e2af5a
a9af5a
81af5a
5fc744 ¤   PGPError
856cab PGPWaitForGetHostByName(
c94acc ¤   PGPAsyncHostEntryRef¤   inAsyncHostEntry,
cb3132 ¤   PGPUInt32 *¤¤   ¤   ¤   outAddress)
70bb36 {
aea8ad ¤   PGPError¤   result;
6367c5 ¤
df82e6 ¤   PGPValidateParam(PGPAsyncHostEntryRefIsValid(inAsyncHostEntry));
9b998d ¤   PGPValidatePtr(outAddress);
dc67c5 ¤
99d3df ¤   WaitForMultipleObjects(2, &inAsyncHostEntry->threadHandle, FALSE, INFINITE);
4ca7db ¤   PGPRMWOLockStartReading(&inAsyncHostEntry->resultLock);
cbfca8 ¤   result = inAsyncHostEntry->result;
0047cd ¤   PGPRMWOLockStopReading(&inAsyncHostEntry->resultLock);
17fb49 ¤   if (result != kPGPError_UserAbort) {
533f27 ¤   ¤   *outAddress = inAsyncHostEntry->address;
e9ec79 ¤   ¤   CloseHandle(inAsyncHostEntry->cancelSemaphore);
008a7d ¤   ¤   DeletePGPRMWOLock(&inAsyncHostEntry->resultLock);
0d9e2a ¤   ¤   free(inAsyncHostEntry);
f29371 ¤   }
2e67c5 ¤
875d73 ¤   return result;
e0efe6 }
1baf5a
dfaf5a
a0af5a
efc744 ¤   PGPError
81c7f0 PGPWaitForGetHostByAddress(
fb4acc ¤   PGPAsyncHostEntryRef¤   inAsyncHostEntry,
bd3342 ¤   char *¤ ¤   ¤   ¤   ¤   outName,
a50b2b ¤   PGPInt32¤   ¤   ¤   ¤   inNameLength)
c2bb36 {
b0a8ad ¤   PGPError¤   result;
2967c5 ¤
b382e6 ¤   PGPValidateParam(PGPAsyncHostEntryRefIsValid(inAsyncHostEntry));
746a33 ¤   PGPValidatePtr(outName);
2e998b ¤   PGPValidateParam(inNameLength > 0);
7367c5 ¤
c9d3df ¤   WaitForMultipleObjects(2, &inAsyncHostEntry->threadHandle, FALSE, INFINITE);
44a7db ¤   PGPRMWOLockStartReading(&inAsyncHostEntry->resultLock);
e8fca8 ¤   result = inAsyncHostEntry->result;
2e47cd ¤   PGPRMWOLockStopReading(&inAsyncHostEntry->resultLock);
18fb49 ¤   if (result != kPGPError_UserAbort) {
bff1ec ¤   ¤   strncpy(outName, inAsyncHostEntry->name, inNameLength);
f14aee ¤   ¤   outName[inNameLength - 1] = 0;
efec79 ¤   ¤   CloseHandle(inAsyncHostEntry->cancelSemaphore);
218a7d ¤   ¤   DeletePGPRMWOLock(&inAsyncHostEntry->resultLock);
a49e2a ¤   ¤   free(inAsyncHostEntry);
519371 ¤   }
f267c5 ¤
745d73 ¤   return result;
98efe6 }
39af5a
45af5a
4daf5a
3fc744 ¤   PGPError
1cbf60 PGPCancelAsyncHostEntryRef(
1f3474 ¤   PGPAsyncHostEntryRef¤   inAsyncHostEntry)
49bb36 {
c744e1 ¤   PGPError¤   result = kPGPError_NoErr;
--4ebc 001a106c8a040110057 Page 5 of pgpAsyncDNS.c
e0af5a
4e82e6 ¤   PGPValidateParam(PGPAsyncHostEntryRefIsValid(inAsyncHostEntry));
b067c5 ¤
716068 ¤   PGPRMWOLockStartWriting(&inAsyncHostEntry->resultLock);
21fb78 ¤   if (inAsyncHostEntry->result == kPGPError_SocketsInProgress) {
1b70a5 ¤   ¤   inAsyncHostEntry->result = kPGPError_UserAbort;
152440 ¤   ¤   ReleaseSemaphore(inAsyncHostEntry->cancelSemaphore, 1, NULL);
fd9371 ¤   }
5f807e ¤   PGPRMWOLockStopWriting(&inAsyncHostEntry->resultLock);
a167c5 ¤
565d73 ¤   return result;
a1efe6 }
--402e 00124d1592b40110058 Page 1 of pgpAsyncDNS.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
da8f45 ¤   pgpAsyncDNS.h¤  -¤  Async calls for dns
bc67c5 ¤
bbaf5a
6e09b0 ¤   $Id: pgpAsyncDNS.h,v 1.2.12.1 1998/11/12 03:20:17 heller Exp $
f1f7f7 ____________________________________________________________________________*/
10af5a
689362 #ifndef Included_pgpAsyncDNS_h¤ /* [ */
15e8f3 #define Included_pgpAsyncDNS_h
68af5a
77af5a
16e1fa #if ! PGP_WIN32
d53306 #error this file should only be used for PGP_WIN32
f77454 #endif
6aaf5a
095519 #include "pgpSockets.h"
33af5a
db99c6 PGP_BEGIN_C_DECLARATIONS
f3af5a
a8dc36 typedef struct PGPAsyncHostEntry *¤ ¤   PGPAsyncHostEntryRef;
42af5a
e14194 #define kPGPInvalidAsyncHostEntryRef¤   ((PGPAsyncHostEntryRef) NULL)
736a0a #define PGPAsyncHostEntryRefIsValid(x)¤ ((x) != kPGPInvalidAsyncHostEntryRef)
d3af5a
fdaf5a
baaf5a
5d3946 PGPError¤   PGPStartAsyncGetHostByName(const char * inName,
09ef33 ¤   ¤   ¤   ¤   PGPAsyncHostEntryRef * outAsyncHostEntry);
692b85 ¤   ¤   ¤   ¤
99ad82 PGPError¤   PGPStartAsyncGetHostByAddress(PGPUInt32 inAddress,
d9ef33 ¤   ¤   ¤   ¤   PGPAsyncHostEntryRef * outAsyncHostEntry);
bd2b85 ¤   ¤   ¤   ¤
c6eff7 PGPError¤   PGPWaitForGetHostByName(PGPAsyncHostEntryRef inAsyncHostEntry,
f64175 ¤   ¤   ¤   ¤   PGPUInt32 * outAddress);
ab2b85 ¤   ¤   ¤   ¤
62ce64 PGPError¤   PGPWaitForGetHostByAddress(PGPAsyncHostEntryRef inAsyncHostEntry,
b3692c ¤   ¤   ¤   ¤   char * outName, PGPInt32 inNameLength);·
9a2b85 ¤   ¤   ¤   ¤
255d50 PGPError¤   PGPCancelAsyncHostEntryRef(PGPAsyncHostEntryRef inAsyncHostEntry);
cdaf5a
451254 PGP_END_C_DECLARATIONS
3eaf5a
ccaf5a
24791c #endif /* ] */¶

--41ea 000db8c453940110059 Page 1 of PGPdisk.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
b349ca Project: "PGPdiskApp"=.\PGPdiskApp.dsp - Package Owner=<4>
76af5a
64e41b Package=<5>
3d8818 {{{
41418b }}}
2aaf5a
fcbec7 Package=<4>
038818 {{{
50418b }}}
94af5a
652d94 ###############################################################################
caaf5a
d48798 Project: "PGPdiskDrvNT"=.\PGPdiskDrvNT.dsp - Package Owner=<4>
85af5a
6be41b Package=<5>
578818 {{{
cb418b }}}
d3af5a
0dbec7 Package=<4>
ca8818 {{{
c4418b }}}
81af5a
222d94 ###############################################################################
2daf5a
6be069 Project: "PGPdiskDrvWin95"=.\PGPdiskDrvWin95.dsp - Package Owner=<4>
76af5a
4be41b Package=<5>
518818 {{{
e0418b }}}
7daf5a
80bec7 Package=<4>
4e8818 {{{
73418b }}}
e5af5a
e22d94 ###############################################################################
01af5a
11dfe4 Project: "PGPdiskInstallHelper"=.\PGPdiskInstallHelper.dsp - Package Owner=<4>
74af5a
5ce41b Package=<5>
a58818 {{{
70418b }}}
54af5a
69bec7 Package=<4>
db8818 {{{
ac418b }}}
81af5a
c22d94 ###############################################################################
9aaf5a
9b95d0 Project: "PGPdiskResident"=.\PGPdiskResident.dsp - Package Owner=<4>
b4af5a
32e41b Package=<5>
d08818 {{{
12418b }}}
46af5a
e4bec7 Package=<4>
a28818 {{{
1c418b }}}
ffaf5a
ec2d94 ###############################################################################
6aaf5a
7162b4 Project: "PGPdiskShellExt"=.\PGPdiskShellExt.dsp - Package Owner=<4>
e4af5a
5de41b Package=<5>
548818 {{{
c3418b }}}
d2af5a
dbbec7 Package=<4>
--8f50 001e8d1514f40110059 Page 2 of PGPdisk.dsw
c88818 {{{
8b418b }}}
12af5a
a52d94 ###############################################################################
f7af5a
6b20da Global:
65af5a
7ae41b Package=<5>
328818 {{{
80418b }}}
39af5a
4632c2 Package=<3>
dd8818 {{{
b2418b }}}
38af5a
692d94 ###############################################################################
e8af5a
--4105 000c90ad21b4011005a Page 1 of PGPdiskApp.dsp
d5f9b5 # Microsoft Developer Studio Project File - Name="PGPdiskApp" - Package Owner=<¶
6a6627 4>
b6e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
828537 # ** DO NOT EDIT **
44af5a
0ee536 # TARGTYPE "Win32 (x86) Application" 0x0101
61af5a
cfeee6 CFG=PGPdiskApp - Win32 Debug
10894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
c65c35 !MESSAGE use the Export Makefile command and run
e86309 !MESSAGE·
ee179d !MESSAGE NMAKE /f "PGPdiskApp.mak".
e26309 !MESSAGE·
b2cdb3 !MESSAGE You can specify a configuration when running NMAKE
0ae013 !MESSAGE by defining the macro CFG on the command line. For example:
eb6309 !MESSAGE·
3d3db1 !MESSAGE NMAKE /f "PGPdiskApp.mak" CFG="PGPdiskApp - Win32 Debug"
356309 !MESSAGE·
1a1dd7 !MESSAGE Possible choices for configuration are:
5f6309 !MESSAGE·
ee72c2 !MESSAGE "PGPdiskApp - Win32 Release" (based on "Win32 (x86) Application")
aec673 !MESSAGE "PGPdiskApp - Win32 Debug" (based on "Win32 (x86) Application")
f16309 !MESSAGE·
c4af5a
ab3e63 # Begin Project
11b23f # PROP Scc_ProjName ""
a1df4a # PROP Scc_LocalPath ""
bf40a4 CPP=cl.exe
1fa46a MTL=midl.exe
7f2e1f RSC=rc.exe
e3af5a
e10498 !IF ·"$(CFG)" == "PGPdiskApp - Win32 Release"
8faf5a
2dd693 # PROP BASE Use_MFC 6
e1e662 # PROP BASE Use_Debug_Libraries 0
8e7d73 # PROP BASE Output_Dir "Release"
c56180 # PROP BASE Intermediate_Dir "Release"
1b4c81 # PROP BASE Target_Dir ""
94757d # PROP Use_MFC 6
b1b771 # PROP Use_Debug_Libraries 0
c8ae27 # PROP Output_Dir "PGPdiskApp/Release"
e22f46 # PROP Intermediate_Dir "PGPdiskApp/Release"
939ad5 # PROP Ignore_Export_Lib 0
31b6fa # PROP Target_Dir ""
ee961c # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D ¶
7f65d4 "_AFXDLL" /Yu"stdafx.h" /FD /c
0a05c7 # ADD CPP /nologo /MD /W3 /WX /GX /O2 /I "..\..\..\libs\pfl\common" /I "..\..\.¶
763f86 .\libs\pfl\common\util" /I "..\..\..\libs\pfl\common\file" /I "..\..\..\libs\pf¶
33a9b7 l\common\prefs" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\¶
7d482d win32" /I "..\..\..\libs\pfl\win32" /I "..\..\pgp\shared" /I "..\..\pgp\win32\P¶
45da22 GPcl" /I "Shared" /I "Encryption" /I "PGPdiskApp\Source" /D "WIN32" /D "NDEBUG"¶
eedb34 ·/D "_WINDOWS" /D PGP_DEBUG=0 /D "PGPDISK_MFC" /D "PGP_INTEL" /D "PGP_WIN32" /D¶
1940f8 ·"_AFXDLL" /YX /FD /c
0c1e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
586d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
5fb1d2 # ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
f28dc5 # ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
1e18fc BSC32=bscmake.exe
b47a24 # ADD BASE BSC32 /nologo
b84f1b # ADD BSC32 /nologo
e9268f LINK32=link.exe
5a3a81 # ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
dbd4f1 # ADD LINK32 ole32.lib mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Release\pflCom¶
205a2d mon.lib ..\..\..\libs\pgpcdk\win32\PGPcdk\Release\PGP_SDK.lib ..\..\..\libs\pgp¶
5b8165 cdk\win32\PGPsdkUI\Release\PGPsdkUI.lib ..\..\pgp\win32\PGPcl\Release\PGP60cl.l¶
d69ce3 ib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefault¶
436617 lib:"libcmt.lib" /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib" /nodefau¶
2a8ba6 ltlib:"msvcrtd.lib" /out:"PGPdiskApp/Release/PGPdisk.exe"
9484a1 # SUBTRACT LINK32 /pdb:none
0aaf5a
068dc4 !ELSEIF ·"$(CFG)" == "PGPdiskApp - Win32 Debug"
c9af5a
--9b91 000b6aaeac24011005a Page 2 of PGPdiskApp.dsp
8bd693 # PROP BASE Use_MFC 6
caffba # PROP BASE Use_Debug_Libraries 1
0054b8 # PROP BASE Output_Dir "Debug"
16198a # PROP BASE Intermediate_Dir "Debug"
b14c81 # PROP BASE Target_Dir ""
e9757d # PROP Use_MFC 6
6caea9 # PROP Use_Debug_Libraries 1
0f6e2e # PROP Output_Dir "PGPdiskApp/Debug"
6aa75d # PROP Intermediate_Dir "PGPdiskApp/Debug"
789ad5 # PROP Ignore_Export_Lib 0
40b6fa # PROP Target_Dir ""
ae32c7 # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
ea4f90 DOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
59404e # ADD CPP /nologo /MDd /W3 /WX /GX /Z7 /Od /I "..\..\..\libs\pfl\common" /I "..¶
d8f9e2 \..\..\libs\pfl\common\util" /I "..\..\..\libs\pfl\common\file" /I "..\..\..\li¶
ea6c6c bs\pfl\common\prefs" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pgpcdk\pub\¶
1dc730 include" /I "..\..\..\libs\pgpcdk\win32" /I "..\..\pgp\shared" /I "..\..\pgp\wi¶
b8294a n32\PGPcl" /I "Shared" /I "Encryption" /I "PGPdiskApp\Source" /D "WIN32" /D "_D¶
2a23cb EBUG" /D "_WINDOWS" /D "DEBUG" /D PGP_DEBUG=1 /D "PGPDISK_MFC" /D "PGP_INTEL" /¶
5a2b55 D "PGP_WIN32" /D "UNFINISHED_CODE_ALLOWED" /D "_AFXDLL" /YX /FD /c
53d3db # SUBTRACT CPP /X
4ec0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
87b3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
d6e84d # ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
03d45a # ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
7f18fc BSC32=bscmake.exe
dd7a24 # ADD BASE BSC32 /nologo
7b4f1b # ADD BSC32 /nologo
12268f LINK32=link.exe
e3267e # ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
29db2b # ADD LINK32 ole32.lib mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Debug\pflCommo¶
ef8a35 n.lib ..\..\..\libs\pgpcdk\win32\PGPcdk\Debug\PGP_SDK.lib ..\..\..\libs\pgpcdk\¶
9d4338 win32\PGPsdkUI\Debug\PGPsdkUI.lib ..\..\pgp\win32\PGPcl\Debug\PGP60cl.lib /nolo¶
37adf6 go /subsystem:windows /debug /machine:I386 /nodefaultlib:"libc.lib" /nodefaultl¶
2d73ae ib:"libcmt.lib" /nodefaultlib:"msvcrt.lib" /nodefaultlib:"libcd.lib" /nodefault¶
be2efd lib:"libcmtd.lib" /out:"PGPdiskApp/Debug/PGPddisk.exe" /pdbtype:sept
3984a1 # SUBTRACT LINK32 /pdb:none
1aaf5a
2c30ec !ENDIF·
19af5a
a1b8a5 # Begin Target
54af5a
980be7 # Name "PGPdiskApp - Win32 Release"
f3a222 # Name "PGPdiskApp - Win32 Debug"
b64cc4 # Begin Group "Source Files"
91af5a
50e96f # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
87ed3f # Begin Group "Custom Classes Source"
0caf5a
51b050 # PROP Default_Filter ""
dfdf4f # Begin Source File
e3af5a
e544ed SOURCE=.\PGPdiskApp\Source\CPGPdiskCmdLine.cpp
d26ccd # End Source File
8fdf4f # Begin Source File
67af5a
c3a7a1 SOURCE=.\PGPdiskApp\Source\File.cpp
216ccd # End Source File
0adf4f # Begin Source File
1aaf5a
376ca9 SOURCE=.\PGPdiskApp\Source\PGPdisk.cpp
2a6ccd # End Source File
22df4f # Begin Source File
8faf5a
ad6b4a SOURCE=.\PGPdiskApp\Source\VolFile.cpp
016ccd # End Source File
28df4f # Begin Source File
71af5a
818c65 SOURCE=.\PGPdiskApp\Source\Volume.cpp
7d6ccd # End Source File
603f5a # End Group
b64840 # Begin Group "App Class Source"
--6fe0 0000678ec734011005a Page 3 of PGPdiskApp.dsp
e0af5a
53b050 # PROP Default_Filter ""
65df4f # Begin Source File
f9af5a
359ddd SOURCE=.\PGPdiskApp\Source\CPGPdiskApp.cpp
8b6ccd # End Source File
77df4f # Begin Source File
b9af5a
9291dd SOURCE=.\PGPdiskApp\Source\CPGPdiskAppACI.cpp
116ccd # End Source File
76df4f # Begin Source File
efaf5a
ceb97c SOURCE=.\PGPdiskApp\Source\CPGPdiskAppPassphrase.cpp
556ccd # End Source File
f0df4f # Begin Source File
67af5a
68427f SOURCE=.\PGPdiskApp\Source\CPGPdiskAppRegistry.cpp
3d6ccd # End Source File
d6df4f # Begin Source File
86af5a
97e0a7 SOURCE=.\PGPdiskApp\Source\CPGPdiskAppVolumes.cpp
9f6ccd # End Source File
afdf4f # Begin Source File
29af5a
48ae81 SOURCE=.\PGPdiskApp\Source\CPGPdiskAppWinutils.cpp
256ccd # End Source File
103f5a # End Group
a913e8 # Begin Group "Dialog Class Source"
71af5a
1bb050 # PROP Default_Filter ""
80df4f # Begin Source File
c7af5a
31b477 SOURCE=.\PGPdiskApp\Source\CAboutBoxDialog.cpp
0d6ccd # End Source File
2edf4f # Begin Source File
ecaf5a
d6f58b SOURCE=.\PGPdiskApp\Source\CConfirmPassphraseDialog.cpp
0d6ccd # End Source File
87df4f # Begin Source File
0eaf5a
f62078 SOURCE=.\PGPdiskApp\Source\CGetUserInfoDialog.cpp
516ccd # End Source File
3cdf4f # Begin Source File
74af5a
4bc678 SOURCE=.\PGPdiskApp\Source\CMainDialog.cpp
866ccd # End Source File
65df4f # Begin Source File
5baf5a
631d69 SOURCE=.\PGPdiskApp\Source\CNagBuyDialog.cpp
c66ccd # End Source File
b1df4f # Begin Source File
5eaf5a
81cd07 SOURCE=.\PGPdiskApp\Source\COpenPGPdiskDialog.cpp
306ccd # End Source File
a1df4f # Begin Source File
fcaf5a
62d2ab SOURCE=.\PGPdiskApp\Source\CPublicKeyDialog.cpp
bf6ccd # End Source File
13df4f # Begin Source File
daaf5a
9a7599 SOURCE=.\PGPdiskApp\Source\CSavePGPdiskDialog.cpp
b06ccd # End Source File
ffdf4f # Begin Source File
56af5a
3ca58a SOURCE=.\PGPdiskApp\Source\CSinglePassphraseDialog.cpp
996ccd # End Source File
dedf4f # Begin Source File
37af5a
0bcf10 SOURCE=.\PGPdiskApp\Source\CSplashScreenDialog.cpp
996ccd # End Source File
cedf4f # Begin Source File
06af5a
--0092 000e638b7524011005a Page 4 of PGPdiskApp.dsp
658ec8 SOURCE=.\PGPdiskApp\Source\CUnmountPGPdiskDialog.cpp
cf6ccd # End Source File
1b3f5a # End Group
831e5d # Begin Group "Thread Class Source"
f5af5a
09b050 # PROP Default_Filter ""
0edf4f # Begin Source File
78af5a
0519ab SOURCE=.\PGPdiskApp\Source\CConvertPGPdiskThread.cpp
596ccd # End Source File
d7df4f # Begin Source File
87af5a
9e5163 SOURCE=.\PGPdiskApp\Source\CCreatePGPdiskThread.cpp
b46ccd # End Source File
7cdf4f # Begin Source File
2baf5a
ee5f42 SOURCE=.\PGPdiskApp\Source\CGlobalCSearchPGPdiskThread.cpp
146ccd # End Source File
683f5a # End Group
0d82ae # Begin Group "Control Class Source"
51af5a
7fb050 # PROP Default_Filter ""
4cdf4f # Begin Source File
64af5a
edb37e SOURCE=.\PGPdiskApp\Source\CDriveLetterCombo.cpp
806ccd # End Source File
eedf4f # Begin Source File
53af5a
508c3f SOURCE=.\PGPdiskApp\Source\CSecureEdit.cpp
db6ccd # End Source File
f1df4f # Begin Source File
ecaf5a
669304 SOURCE=.\PGPdiskApp\Source\CSuperHotKeyControl.cpp
396ccd # End Source File
2f3f5a # End Group
e799bd # Begin Group "PropSheet Source"
83af5a
13b050 # PROP Default_Filter ""
84df4f # Begin Source File
a4af5a
aefa45 SOURCE=.\PGPdiskApp\Source\CPreferencesSheet.cpp
586ccd # End Source File
7ddf4f # Begin Source File
afaf5a
a1414e SOURCE=.\PGPdiskApp\Source\CPrefsAutoUnmountPage.cpp
e56ccd # End Source File
a5df4f # Begin Source File
48af5a
38cea1 SOURCE=.\PGPdiskApp\Source\CPrefsUnmountHotKeyPage.cpp
ff6ccd # End Source File
5f3f5a # End Group
3c75ae # Begin Group "Wizard Source"
75af5a
46b050 # PROP Default_Filter ""
f0df4f # Begin Source File
87af5a
d0ab94 SOURCE=.\PGPdiskApp\Source\CConvertWizardSheet.cpp
ec6ccd # End Source File
fadf4f # Begin Source File
92af5a
4df2a8 SOURCE=.\PGPdiskApp\Source\CConvertWizConvertPage.cpp
e16ccd # End Source File
e0df4f # Begin Source File
2caf5a
cd031e SOURCE=.\PGPdiskApp\Source\CConvertWizDonePage.cpp
6f6ccd # End Source File
6adf4f # Begin Source File
7faf5a
64380c SOURCE=.\PGPdiskApp\Source\CConvertWizIntroPage.cpp
1b6ccd # End Source File
5bdf4f # Begin Source File
e6af5a
--6c1f 000528aa17d4011005a Page 5 of PGPdiskApp.dsp
7653cc SOURCE=.\PGPdiskApp\Source\CConvertWizRandomDataPage.cpp
f96ccd # End Source File
37df4f # Begin Source File
b2af5a
92f864 SOURCE=.\PGPdiskApp\Source\CDiskWizADKPage.cpp
796ccd # End Source File
ecdf4f # Begin Source File
2daf5a
f48a93 SOURCE=.\PGPdiskApp\Source\CDiskWizardSheet.cpp
056ccd # End Source File
4adf4f # Begin Source File
faaf5a
1ded89 SOURCE=.\PGPdiskApp\Source\CDiskWizCreationPage.cpp
136ccd # End Source File
07df4f # Begin Source File
d2af5a
452219 SOURCE=.\PGPdiskApp\Source\CDiskWizDonePage.cpp
f26ccd # End Source File
65df4f # Begin Source File
d7af5a
d94c92 SOURCE=.\PGPdiskApp\Source\CDiskWizIntroPage.cpp
066ccd # End Source File
05df4f # Begin Source File
dfaf5a
50adcc SOURCE=.\PGPdiskApp\Source\CDiskWizPassphrasePage.cpp
d06ccd # End Source File
aadf4f # Begin Source File
aaaf5a
be24c8 SOURCE=.\PGPdiskApp\Source\CDiskWizRandomDataPage.cpp
916ccd # End Source File
47df4f # Begin Source File
29af5a
9219d9 SOURCE=.\PGPdiskApp\Source\CDiskWizVolumeInfoPage.cpp
6c6ccd # End Source File
b5df4f # Begin Source File
60af5a
c69f66 SOURCE=.\PGPdiskApp\Source\CGlobalCWizardSheet.cpp
b36ccd # End Source File
a5df4f # Begin Source File
1aaf5a
2337ec SOURCE=.\PGPdiskApp\Source\CGlobalCWizDonePage.cpp
ec6ccd # End Source File
63df4f # Begin Source File
d9af5a
d2eca5 SOURCE=.\PGPdiskApp\Source\CGlobalCWizIntroPage.cpp
466ccd # End Source File
39df4f # Begin Source File
44af5a
bcf856 SOURCE=.\PGPdiskApp\Source\CGlobalCWizSearchPage.cpp
686ccd # End Source File
b43f5a # End Group
0d1927 # Begin Group "Shared Source"
eaaf5a
0ab050 # PROP Default_Filter ""
1edf4f # Begin Source File
18af5a
05b8e5 SOURCE=.\Shared\CommonStrings.cpp
cc6ccd # End Source File
3adf4f # Begin Source File
56af5a
3439cf SOURCE=.\Shared\DriverComm.cpp
5b6ccd # End Source File
94df4f # Begin Source File
b7af5a
861f6a SOURCE=.\Shared\DualErr.cpp
fa6ccd # End Source File
10df4f # Begin Source File
7caf5a
809dfd SOURCE=.\Shared\Errors.cpp
206ccd # End Source File
e2df4f # Begin Source File
52af5a
--f3d7 000e1a54d934011005a Page 6 of PGPdiskApp.dsp
5c9019 SOURCE=.\Shared\FatUtils.cpp
fe6ccd # End Source File
cbdf4f # Begin Source File
caaf5a
459c92 SOURCE=.\Shared\LinkResolution.cpp
156ccd # End Source File
5fdf4f # Begin Source File
f1af5a
639af7 SOURCE=.\Shared\PGPdiskContainer.cpp
346ccd # End Source File
9bdf4f # Begin Source File
feaf5a
22ab80 SOURCE=.\Shared\PGPdiskHighLevelUtils.cpp
e16ccd # End Source File
abdf4f # Begin Source File
2eaf5a
b8732d SOURCE=.\Shared\PGPdiskLowLevelUtils.cpp
2a6ccd # End Source File
43df4f # Begin Source File
00af5a
f8f5c7 SOURCE=.\Shared\PGPdiskPfl.cpp
3f6ccd # End Source File
cedf4f # Begin Source File
95af5a
906f1c SOURCE=.\Shared\PGPdiskPublicKeyUtils.cpp
f26ccd # End Source File
8adf4f # Begin Source File
1aaf5a
a84c3f SOURCE=.\Shared\PGPdiskRegistry.cpp
f46ccd # End Source File
84df4f # Begin Source File
c1af5a
919c58 SOURCE=.\Shared\SecureMemory.cpp
5a6ccd # End Source File
35df4f # Begin Source File
82af5a
d051f9 SOURCE=.\Shared\SecureString.cpp
7a6ccd # End Source File
c7df4f # Begin Source File
58af5a
e34dfb SOURCE=.\Shared\SharedMemory.cpp
246ccd # End Source File
9adf4f # Begin Source File
59af5a
9af4cd SOURCE=.\Shared\StringAssociation.cpp
f76ccd # End Source File
7ddf4f # Begin Source File
4caf5a
fda0d5 SOURCE=.\Shared\WaitObjectClasses.cpp
0d6ccd # End Source File
4ddf4f # Begin Source File
6eaf5a
8a5a00 SOURCE=.\Shared\Win32Utils.cpp
736ccd # End Source File
9cdf4f # Begin Source File
5aaf5a
4a85f8 SOURCE=.\Shared\WindowsVersion.cpp
a36ccd # End Source File
fb3f5a # End Group
0e6ef3 # Begin Group "Encryption Source"
6faf5a
8bb050 # PROP Default_Filter ""
92df4f # Begin Source File
54af5a
cc70d8 SOURCE=.\Encryption\Cast5.cpp
aa6ccd # End Source File
d0df4f # Begin Source File
8caf5a
c56ab3 SOURCE=.\Encryption\Cast5Box.cpp
e36ccd # End Source File
abdf4f # Begin Source File
e1af5a
--f756 000a7559a464011005a Page 7 of PGPdiskApp.dsp
5b8328 SOURCE=.\Encryption\CipherContext.cpp
c66ccd # End Source File
3cdf4f # Begin Source File
39af5a
9bd7f6 SOURCE=.\Encryption\CipherUtils.cpp
466ccd # End Source File
5fdf4f # Begin Source File
45af5a
b7b8a5 SOURCE=.\Encryption\PGPdiskRandomPool.cpp
1f6ccd # End Source File
89df4f # Begin Source File
64af5a
5684bb SOURCE=.\Encryption\SHA.cpp
2c6ccd # End Source File
293f5a # End Group
d0df4f # Begin Source File
23af5a
63cdc2 SOURCE=.\PGPdiskApp\Source\StdAfx.cpp
ab6ccd # End Source File
e93f5a # End Group
d3ba44 # Begin Group "Header Files"
a6af5a
9d1a9c # PROP Default_Filter "h;hpp;hxx;hm;inl"
3b0d68 # Begin Group "Custom Classes Headers"
c8af5a
87b050 # PROP Default_Filter ""
95df4f # Begin Source File
95af5a
69e12a SOURCE=.\PGPdiskApp\Source\CPGPdiskCmdLine.h
296ccd # End Source File
d0df4f # Begin Source File
b8af5a
994b5b SOURCE=.\PGPdiskApp\Source\File.h
616ccd # End Source File
6ddf4f # Begin Source File
03af5a
7028c4 SOURCE=.\PGPdiskApp\Source\PGPdisk.h
5e6ccd # End Source File
aedf4f # Begin Source File
19af5a
4dbac9 SOURCE=.\PGPdiskApp\Source\VolFile.h
186ccd # End Source File
e6df4f # Begin Source File
8baf5a
4e58e9 SOURCE=.\PGPdiskApp\Source\Volume.h
196ccd # End Source File
dc3f5a # End Group
f586bd # Begin Group "App Class Headers"
1eaf5a
76b050 # PROP Default_Filter ""
91df4f # Begin Source File
81af5a
a6dad9 SOURCE=.\PGPdiskApp\Source\CPGPdiskApp.h
e36ccd # End Source File
a1df4f # Begin Source File
26af5a
1a088a SOURCE=.\PGPdiskApp\Source\CPGPdiskAppACI.h
8a6ccd # End Source File
dfdf4f # Begin Source File
64af5a
20dfa6 SOURCE=.\PGPdiskApp\Source\CPGPdiskAppPassphrase.h
636ccd # End Source File
08df4f # Begin Source File
b1af5a
9bb5fd SOURCE=.\PGPdiskApp\Source\CPGPdiskAppRegistry.h
a86ccd # End Source File
96df4f # Begin Source File
b2af5a
6304c0 SOURCE=.\PGPdiskApp\Source\CPGPdiskAppVolumes.h
db6ccd # End Source File
32df4f # Begin Source File
a7af5a
--0a5f 0006dc806a64011005a Page 8 of PGPdiskApp.dsp
fd8c80 SOURCE=.\PGPdiskApp\Source\CPGPdiskAppWinutils.h
216ccd # End Source File
6f3f5a # End Group
edafa4 # Begin Group "Dialog Class Headers"
55af5a
a9b050 # PROP Default_Filter ""
3cdf4f # Begin Source File
58af5a
8404c6 SOURCE=.\PGPdiskApp\Source\CAboutBoxDialog.h
f66ccd # End Source File
97df4f # Begin Source File
dbaf5a
234151 SOURCE=.\PGPdiskApp\Source\CConfirmPassphraseDialog.h
016ccd # End Source File
72df4f # Begin Source File
58af5a
288c64 SOURCE=.\PGPdiskApp\Source\CGetUserInfoDialog.h
d96ccd # End Source File
51df4f # Begin Source File
1eaf5a
f74d02 SOURCE=.\PGPdiskApp\Source\CMainDialog.h
d46ccd # End Source File
f4df4f # Begin Source File
eaaf5a
52d7c1 SOURCE=.\PGPdiskApp\Source\CNagBuyDialog.h
5b6ccd # End Source File
63df4f # Begin Source File
2caf5a
1cc444 SOURCE=.\PGPdiskApp\Source\COpenPGPdiskDialog.h
c26ccd # End Source File
0bdf4f # Begin Source File
68af5a
1c9663 SOURCE=.\PGPdiskApp\Source\CPublicKeyDialog.h
9d6ccd # End Source File
2cdf4f # Begin Source File
4baf5a
fd5eda SOURCE=.\PGPdiskApp\Source\CSavePGPdiskDialog.h
516ccd # End Source File
0bdf4f # Begin Source File
50af5a
ffbac1 SOURCE=.\PGPdiskApp\Source\CSinglePassphraseDialog.h
736ccd # End Source File
a5df4f # Begin Source File
2baf5a
66de33 SOURCE=.\PGPdiskApp\Source\CSplashScreenDialog.h
f26ccd # End Source File
36df4f # Begin Source File
d3af5a
4cb1d1 SOURCE=.\PGPdiskApp\Source\CUnmountPGPdiskDialog.h
2b6ccd # End Source File
cf3f5a # End Group
904d8f # Begin Group "Thread Class Headers"
c8af5a
39b050 # PROP Default_Filter ""
7cdf4f # Begin Source File
32af5a
9bb574 SOURCE=.\PGPdiskApp\Source\CConvertPGPdiskThread.h
006ccd # End Source File
cadf4f # Begin Source File
4daf5a
c2966c SOURCE=.\PGPdiskApp\Source\CCreatePGPdiskThread.h
536ccd # End Source File
6edf4f # Begin Source File
d6af5a
97e50f SOURCE=.\PGPdiskApp\Source\CGlobalCSearchPGPdiskThread.h
da6ccd # End Source File
5c3f5a # End Group
498807 # Begin Group "Control Class Headers"
50af5a
1bb050 # PROP Default_Filter ""
15df4f # Begin Source File
6daf5a
--cd21 0006f2616d64011005a Page 9 of PGPdiskApp.dsp
c4f0f6 SOURCE=.\PGPdiskApp\Source\CDriveLetterCombo.h
136ccd # End Source File
52df4f # Begin Source File
89af5a
f89d31 SOURCE=.\PGPdiskApp\Source\CSecureEdit.h
f76ccd # End Source File
cedf4f # Begin Source File
a7af5a
875eb5 SOURCE=.\PGPdiskApp\Source\CSuperHotKeyControl.h
e26ccd # End Source File
9d3f5a # End Group
31aa06 # Begin Group "PropSheet Headers"
84af5a
13b050 # PROP Default_Filter ""
26df4f # Begin Source File
25af5a
692dd2 SOURCE=.\PGPdiskApp\Source\CPreferencesSheet.h
1c6ccd # End Source File
9ddf4f # Begin Source File
12af5a
dcc455 SOURCE=.\PGPdiskApp\Source\CPrefsAutoUnmountPage.h
366ccd # End Source File
bcdf4f # Begin Source File
fcaf5a
dd244f SOURCE=.\PGPdiskApp\Source\CPrefsUnmountHotKeyPage.h
2c6ccd # End Source File
503f5a # End Group
3588f0 # Begin Group "Wizard Headers"
5eaf5a
5bb050 # PROP Default_Filter ""
d3df4f # Begin Source File
18af5a
f83a7c SOURCE=.\PGPdiskApp\Source\CConvertWizardSheet.h
986ccd # End Source File
12df4f # Begin Source File
d6af5a
aceffa SOURCE=.\PGPdiskApp\Source\CConvertWizConvertPage.h
696ccd # End Source File
7cdf4f # Begin Source File
9faf5a
953163 SOURCE=.\PGPdiskApp\Source\CConvertWizDonePage.h
fd6ccd # End Source File
10df4f # Begin Source File
59af5a
749fd4 SOURCE=.\PGPdiskApp\Source\CConvertWizIntroPage.h
4e6ccd # End Source File
69df4f # Begin Source File
05af5a
b26f76 SOURCE=.\PGPdiskApp\Source\CConvertWizRandomDataPage.h
496ccd # End Source File
90df4f # Begin Source File
25af5a
2d8ce2 SOURCE=.\PGPdiskApp\Source\CDiskWizADKPage.h
ef6ccd # End Source File
49df4f # Begin Source File
3daf5a
173229 SOURCE=.\PGPdiskApp\Source\CDiskWizardSheet.h
336ccd # End Source File
6cdf4f # Begin Source File
46af5a
0cfdc4 SOURCE=.\PGPdiskApp\Source\CDiskWizCreationPage.h
f76ccd # End Source File
a3df4f # Begin Source File
26af5a
583936 SOURCE=.\PGPdiskApp\Source\CDiskWizDonePage.h
7c6ccd # End Source File
0ddf4f # Begin Source File
feaf5a
6d9af4 SOURCE=.\PGPdiskApp\Source\CDiskWizIntroPage.h
4c6ccd # End Source File
96df4f # Begin Source File
6faf5a
--6265 000173ca9ac4011005a Page 10 of PGPdiskApp.dsp
1602a7 SOURCE=.\PGPdiskApp\Source\CDiskWizPassphrasePage.h
6b6ccd # End Source File
40df4f # Begin Source File
a3af5a
b961b0 SOURCE=.\PGPdiskApp\Source\CDiskWizRandomDataPage.h
9f6ccd # End Source File
a4df4f # Begin Source File
18af5a
e83a15 SOURCE=.\PGPdiskApp\Source\CDiskWizVolumeInfoPage.h
636ccd # End Source File
b2df4f # Begin Source File
26af5a
408297 SOURCE=.\PGPdiskApp\Source\CGlobalCWizardSheet.h
ba6ccd # End Source File
11df4f # Begin Source File
94af5a
b98988 SOURCE=.\PGPdiskApp\Source\CGlobalCWizDonePage.h
876ccd # End Source File
5ddf4f # Begin Source File
45af5a
7fc6b1 SOURCE=.\PGPdiskApp\Source\CGlobalCWizIntroPage.h
f96ccd # End Source File
74df4f # Begin Source File
4eaf5a
0617e1 SOURCE=.\PGPdiskApp\Source\CGlobalCWizSearchPage.h
b66ccd # End Source File
2f3f5a # End Group
4d9155 # Begin Group "Shared Headers"
e5af5a
50b050 # PROP Default_Filter ""
c3df4f # Begin Source File
75af5a
186f63 SOURCE=.\Shared\CommonStrings.h
166ccd # End Source File
1cdf4f # Begin Source File
2baf5a
beeac9 SOURCE=.\Shared\DriverComm.h
066ccd # End Source File
a4df4f # Begin Source File
96af5a
d36ce2 SOURCE=.\Shared\DualErr.h
bc6ccd # End Source File
29df4f # Begin Source File
5faf5a
18d0e8 SOURCE=.\Shared\Errors.h
fd6ccd # End Source File
1ddf4f # Begin Source File
7faf5a
c945e0 SOURCE=.\Shared\FatUtils.h
286ccd # End Source File
24df4f # Begin Source File
daaf5a
29e7cc SOURCE=.\Shared\LinkResolution.h
1a6ccd # End Source File
8adf4f # Begin Source File
98af5a
10a069 SOURCE=.\Shared\Packets.h
996ccd # End Source File
2cdf4f # Begin Source File
93af5a
6d3ceb SOURCE=.\Shared\PGPdiskContainer.h
ab6ccd # End Source File
3edf4f # Begin Source File
f3af5a
6ee8bc SOURCE=.\Shared\PGPdiskDefaults.h
936ccd # End Source File
7bdf4f # Begin Source File
3caf5a
c4b727 SOURCE=.\Shared\PGPdiskFileFormat.h
b26ccd # End Source File
8bdf4f # Begin Source File
17af5a
--09b0 0006ff115eb4011005a Page 11 of PGPdiskApp.dsp
6a9b28 SOURCE=.\Shared\PGPdiskHighLevelUtils.h
766ccd # End Source File
4ddf4f # Begin Source File
73af5a
6a305a SOURCE=.\Shared\PGPdiskLowLevelUtils.h
e16ccd # End Source File
6edf4f # Begin Source File
6faf5a
d935ff SOURCE=.\Shared\PGPdiskPfl.h
ed6ccd # End Source File
24df4f # Begin Source File
ecaf5a
a751ec SOURCE=.\Shared\PGPdiskPublicKeyUtils.h
b76ccd # End Source File
fcdf4f # Begin Source File
31af5a
5dd0dc SOURCE=.\Shared\PGPdiskRegistry.h
5f6ccd # End Source File
eddf4f # Begin Source File
78af5a
814057 SOURCE=.\Shared\PGPdiskResidentDefines.h
0e6ccd # End Source File
6fdf4f # Begin Source File
1baf5a
96d064 SOURCE=.\Shared\PGPdiskVersion.h
176ccd # End Source File
3adf4f # Begin Source File
8eaf5a
842f73 SOURCE=.\Shared\Required.h
fe6ccd # End Source File
20df4f # Begin Source File
feaf5a
638bc0 SOURCE=.\Shared\SecureMemory.h
a06ccd # End Source File
c5df4f # Begin Source File
f0af5a
446f12 SOURCE=.\Shared\SecureString.h
fe6ccd # End Source File
d5df4f # Begin Source File
3eaf5a
959db6 SOURCE=.\Shared\SharedMemory.h
426ccd # End Source File
cfdf4f # Begin Source File
14af5a
82b721 SOURCE=.\Shared\ShlwapiWrapper.h
1b6ccd # End Source File
8ddf4f # Begin Source File
b7af5a
fc34dd SOURCE=.\Shared\StringAssociation.h
7e6ccd # End Source File
f9df4f # Begin Source File
83af5a
c51a46 SOURCE=.\Shared\SystemConstants.h
2d6ccd # End Source File
f7df4f # Begin Source File
efaf5a
067b7c SOURCE=.\Shared\UtilityFunctions.h
3a6ccd # End Source File
26df4f # Begin Source File
a3af5a
ef48f5 SOURCE=.\Shared\WaitObjectClasses.h
cd6ccd # End Source File
7edf4f # Begin Source File
fdaf5a
f9fef6 SOURCE=.\Shared\Win32Utils.h
396ccd # End Source File
6edf4f # Begin Source File
34af5a
11540a SOURCE=.\Shared\WindowsVersion.h
c96ccd # End Source File
843f5a # End Group
6f018b # Begin Group "Encryption Headers"
--5917 000bcc0c9c74011005a Page 12 of PGPdiskApp.dsp
e0af5a
53b050 # PROP Default_Filter ""
65df4f # Begin Source File
f9af5a
845d10 SOURCE=.\Encryption\Cast5.h
cb6ccd # End Source File
d9df4f # Begin Source File
dfaf5a
6b145f SOURCE=.\Encryption\Cast5Box.h
f36ccd # End Source File
4cdf4f # Begin Source File
e5af5a
f4049d SOURCE=.\Encryption\CipherContext.h
2c6ccd # End Source File
38df4f # Begin Source File
8caf5a
567475 SOURCE=.\Encryption\CipherUtils.h
716ccd # End Source File
8adf4f # Begin Source File
22af5a
9e7b01 SOURCE=.\Encryption\PGPdiskRandomPool.h
776ccd # End Source File
61df4f # Begin Source File
feaf5a
9b09d3 SOURCE=.\Encryption\SHA.h
7d6ccd # End Source File
313f5a # End Group
b0df4f # Begin Source File
ffaf5a
f3bdfd SOURCE=.\PGPdiskApp\Source\Globals.h
7d6ccd # End Source File
1ddf4f # Begin Source File
d9af5a
918e01 SOURCE=.\PGPdiskApp\Source\PGPdiskHelpIds.h
6f6ccd # End Source File
aedf4f # Begin Source File
18af5a
a7fc61 SOURCE=.\PGPdiskApp\Source\Resource.h
556ccd # End Source File
f1df4f # Begin Source File
acaf5a
dfd0b7 SOURCE=.\PGPdiskApp\Source\StdAfx.h
906ccd # End Source File
233f5a # End Group
58aa35 # Begin Group "Resources"
63af5a
fdb050 # PROP Default_Filter ""
a3df4f # Begin Source File
48af5a
535b8f SOURCE=.\PGPdiskApp\Res\App.ico
256ccd # End Source File
05df4f # Begin Source File
78af5a
b7cb11 SOURCE=.\PGPdiskApp\Res\Credits1.bmp
406ccd # End Source File
88df4f # Begin Source File
1baf5a
7ddf96 SOURCE=.\PGPdiskApp\Res\Credits4.bmp
fe6ccd # End Source File
d4df4f # Begin Source File
96af5a
4aee62 SOURCE=.\PGPdiskApp\Res\Credits8.bmp
c96ccd # End Source File
86df4f # Begin Source File
2aaf5a
e7e9e2 SOURCE=.\PGPdiskApp\Res\Document.ico
bd6ccd # End Source File
67df4f # Begin Source File
60af5a
70dd35 SOURCE=.\PGPdiskApp\Res\iconBar.ico
1d6ccd # End Source File
bcdf4f # Begin Source File
--eb56 00166ca77e44011005a Page 13 of PGPdiskApp.dsp
e0af5a
cd1745 SOURCE=.\PGPdiskApp\Res\iconCapsLock.ico
276ccd # End Source File
85df4f # Begin Source File
4eaf5a
8e0d05 SOURCE=.\PGPdiskApp\Res\iconMain.ico
506ccd # End Source File
f7df4f # Begin Source File
9faf5a
50b944 SOURCE=.\PGPdiskApp\Res\iconMount.ico
756ccd # End Source File
c7df4f # Begin Source File
62af5a
67368b SOURCE=.\PGPdiskApp\Res\iconMsgBox1.ico
fb6ccd # End Source File
38df4f # Begin Source File
7baf5a
5c3af6 SOURCE=.\PGPdiskApp\Res\iconMsgBox2.ico
746ccd # End Source File
12df4f # Begin Source File
8daf5a
189da6 SOURCE=.\PGPdiskApp\Res\iconNew.ico
906ccd # End Source File
17df4f # Begin Source File
67af5a
758f6e SOURCE=.\PGPdiskApp\Res\iconPGPdisk.ico
2a6ccd # End Source File
f9df4f # Begin Source File
19af5a
baf587 SOURCE=.\PGPdiskApp\Res\iconPrefs.ico
e26ccd # End Source File
43df4f # Begin Source File
86af5a
83a2e1 SOURCE=.\PGPdiskApp\Res\iconUnmount.ico
7d6ccd # End Source File
d4df4f # Begin Source File
0daf5a
ff1387 SOURCE=.\PGPdiskApp\PGPdiskApp.rc
576ccd # End Source File
57df4f # Begin Source File
72af5a
621ec8 SOURCE=.\PGPdiskApp\Res\Prefs.ico
e56ccd # End Source File
9ddf4f # Begin Source File
fdaf5a
748aac SOURCE=.\PGPdiskApp\Res\Sidebar1.bmp
956ccd # End Source File
e9df4f # Begin Source File
e2af5a
c39e2b SOURCE=.\PGPdiskApp\Res\Sidebar4.bmp
486ccd # End Source File
40df4f # Begin Source File
03af5a
b8afdf SOURCE=.\PGPdiskApp\Res\Sidebar8.bmp
016ccd # End Source File
95df4f # Begin Source File
21af5a
4af668 SOURCE=.\PGPdiskApp\Res\SplashScreen1.bmp
1b6ccd # End Source File
0cdf4f # Begin Source File
bbaf5a
81e2ef SOURCE=.\PGPdiskApp\Res\SplashScreen4.bmp
d56ccd # End Source File
05df4f # Begin Source File
a6af5a
90d31b SOURCE=.\PGPdiskApp\Res\SplashScreen8.bmp
ae6ccd # End Source File
f43f5a # End Group
bce5cf # End Target
66f262 # End Project

--1b86 00118a9a93e4011005b Page 1 of PGPdiskApp.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
b349ca Project: "PGPdiskApp"=.\PGPdiskApp.dsp - Package Owner=<4>
76af5a
64e41b Package=<5>
3d8818 {{{
41418b }}}
2aaf5a
fcbec7 Package=<4>
038818 {{{
50418b }}}
94af5a
652d94 ###############################################################################
caaf5a
1a20da Global:
feaf5a
86e41b Package=<5>
d28818 {{{
0e418b }}}
32af5a
b532c2 Package=<3>
178818 {{{
c4418b }}}
f4af5a
1e2d94 ###############################################################################
18af5a
--4e90 000c0393a974011005c Page 1 of PGPdiskDrvNT.dsp
da3e23 # Microsoft Developer Studio Project File - Name="PGPdiskDrvNT" - Package Owner¶
5c1544 =<4>
87e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
bd8537 # ** DO NOT EDIT **
52af5a
2d669e # TARGTYPE "Win32 (x86) External Target" 0x0106
9faf5a
d71227 CFG=PGPdiskDrvNT - Win32 Checked
b6894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
a95c35 !MESSAGE use the Export Makefile command and run
e06309 !MESSAGE·
17ef9f !MESSAGE NMAKE /f "PGPdiskDrvNT.mak".
fd6309 !MESSAGE·
8bcdb3 !MESSAGE You can specify a configuration when running NMAKE
fbe013 !MESSAGE by defining the macro CFG on the command line. For example:
d26309 !MESSAGE·
ff89ab !MESSAGE NMAKE /f "PGPdiskDrvNT.mak" CFG="PGPdiskDrvNT - Win32 Checked"
9f6309 !MESSAGE·
ad1dd7 !MESSAGE Possible choices for configuration are:
366309 !MESSAGE·
3ec587 !MESSAGE "PGPdiskDrvNT - Win32 Free" (based on "Win32 (x86) External Target")
84677d !MESSAGE "PGPdiskDrvNT - Win32 Checked" (based on\
a5f03b ·"Win32 (x86) External Target")
af6309 !MESSAGE·
d5af5a
ac3e63 # Begin Project
e2b23f # PROP Scc_ProjName ""
7bdf4a # PROP Scc_LocalPath ""
d3af5a
6f1523 !IF ·"$(CFG)" == "PGPdiskDrvNT - Win32 Free"
eaaf5a
92ffba # PROP BASE Use_Debug_Libraries 1
7a22f4 # PROP BASE Output_Dir "PGPdiskD"
e8e7fc # PROP BASE Intermediate_Dir "PGPdiskD"
e810ee # PROP BASE Cmd_Line "PGPdiskDrvNT\runbuild checked"
aae878 # PROP BASE Rebuild_Opt "-cf"
a07f9c # PROP BASE Target_File "PGPdiskDrvNT\i386\checked\PGPdisk.sys"
5b4204 # PROP BASE Bsc_Name "PGPdiskDrvNT\i386\checked\PGPdisk.bsc"
744c81 # PROP BASE Target_Dir ""
4daea9 # PROP Use_Debug_Libraries 1
c173e7 # PROP Output_Dir "PGPdiskD"
f0d717 # PROP Intermediate_Dir "PGPdiskD"
0d6d6e # PROP Cmd_Line "PGPdiskDrvNT\RunBuild free"
7e8d66 # PROP Rebuild_Opt "-cf"
a67e9c # PROP Target_File "PGPdiskDrvNT\i386\free\PGPdisk.sys"
d299e2 # PROP Bsc_Name "PGPdiskDrvNT\i386\free\PGPdisk.bsc"
c4b6fa # PROP Target_Dir ""
81af5a
9c4f86 !ELSEIF ·"$(CFG)" == "PGPdiskDrvNT - Win32 Checked"
bbaf5a
c7ffba # PROP BASE Use_Debug_Libraries 1
78c14d # PROP BASE Output_Dir "PGPdisk0"
7f0445 # PROP BASE Intermediate_Dir "PGPdisk0"
5d10ee # PROP BASE Cmd_Line "PGPdiskDrvNT\runbuild checked"
3ce878 # PROP BASE Rebuild_Opt "-cf"
877f9c # PROP BASE Target_File "PGPdiskDrvNT\i386\checked\PGPdisk.sys"
624204 # PROP BASE Bsc_Name "PGPdiskDrvNT\i386\checked\PGPdisk.bsc"
ec4c81 # PROP BASE Target_Dir ""
79aea9 # PROP Use_Debug_Libraries 1
dd905e # PROP Output_Dir "PGPdisk0"
d634ae # PROP Intermediate_Dir "PGPdisk0"
24b59c # PROP Cmd_Line "PGPdiskDrvNT\RunBuild checked"
ee8d66 # PROP Rebuild_Opt "-cf"
8da4ca # PROP Target_File "PGPdiskDrvNT\i386\checked\PGPdisk.sys"
680787 # PROP Bsc_Name "PGPdiskDrvNT\i386\checked\PGPdisk.bsc"
edb6fa # PROP Target_Dir ""
d4af5a
d930ec !ENDIF·
44af5a
a6b8a5 # Begin Target
0aaf5a
c012dc # Name "PGPdiskDrvNT - Win32 Free"
--c202 0006ca6e44d4011005c Page 2 of PGPdiskDrvNT.dsp
faf96a # Name "PGPdiskDrvNT - Win32 Checked"
96af5a
7b1523 !IF ·"$(CFG)" == "PGPdiskDrvNT - Win32 Free"
e7af5a
004f86 !ELSEIF ·"$(CFG)" == "PGPdiskDrvNT - Win32 Checked"
6eaf5a
0c30ec !ENDIF·
85af5a
104cc4 # Begin Group "Source Files"
5faf5a
df7b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
ec1927 # Begin Group "Shared Source"
dbaf5a
33b050 # PROP Default_Filter ""
02df4f # Begin Source File
09af5a
d9b8e5 SOURCE=.\Shared\CommonStrings.cpp
de6ccd # End Source File
8fdf4f # Begin Source File
b1af5a
0a1f6a SOURCE=.\Shared\DualErr.cpp
616ccd # End Source File
dbdf4f # Begin Source File
96af5a
d79dfd SOURCE=.\Shared\Errors.cpp
a96ccd # End Source File
4bdf4f # Begin Source File
dcaf5a
029af7 SOURCE=.\Shared\PGPdiskContainer.cpp
d66ccd # End Source File
f2df4f # Begin Source File
9baf5a
16ab80 SOURCE=.\Shared\PGPdiskHighLevelUtils.cpp
316ccd # End Source File
c8df4f # Begin Source File
01af5a
06732d SOURCE=.\Shared\PGPdiskLowLevelUtils.cpp
7f6ccd # End Source File
c1df4f # Begin Source File
4eaf5a
b8f5c7 SOURCE=.\Shared\PGPdiskPfl.cpp
826ccd # End Source File
65df4f # Begin Source File
2faf5a
559c58 SOURCE=.\Shared\SecureMemory.cpp
c46ccd # End Source File
5bdf4f # Begin Source File
10af5a
9751f9 SOURCE=.\Shared\SecureString.cpp
8a6ccd # End Source File
5bdf4f # Begin Source File
38af5a
ccf4cd SOURCE=.\Shared\StringAssociation.cpp
c86ccd # End Source File
5adf4f # Begin Source File
a3af5a
4aa0d5 SOURCE=.\Shared\WaitObjectClasses.cpp
706ccd # End Source File
973f5a # End Group
ed6ef3 # Begin Group "Encryption Source"
89af5a
d7b050 # PROP Default_Filter ""
94df4f # Begin Source File
fbaf5a
3570d8 SOURCE=.\Encryption\Cast5.cpp
a06ccd # End Source File
70df4f # Begin Source File
31af5a
2f6ab3 SOURCE=.\Encryption\Cast5Box.cpp
266ccd # End Source File
a0df4f # Begin Source File
6caf5a
--e418 000a0955a084011005c Page 3 of PGPdiskDrvNT.dsp
5b8328 SOURCE=.\Encryption\CipherContext.cpp
c66ccd # End Source File
3cdf4f # Begin Source File
39af5a
9bd7f6 SOURCE=.\Encryption\CipherUtils.cpp
466ccd # End Source File
5fdf4f # Begin Source File
45af5a
b7b8a5 SOURCE=.\Encryption\PGPdiskRandomPool.cpp
1f6ccd # End Source File
89df4f # Begin Source File
64af5a
5684bb SOURCE=.\Encryption\SHA.cpp
2c6ccd # End Source File
293f5a # End Group
fbed3f # Begin Group "Custom Classes Source"
57af5a
c4b050 # PROP Default_Filter ""
07df4f # Begin Source File
34af5a
f2ef19 SOURCE=.\PGPdiskDrvNT\Source\File.cpp
8e6ccd # End Source File
60df4f # Begin Source File
71af5a
5ba88f SOURCE=.\PGPdiskDrvNT\Source\PGPdisk.cpp
416ccd # End Source File
1adf4f # Begin Source File
b6af5a
2283c2 SOURCE=.\PGPdiskDrvNT\Source\PGPdiskRequestQueue.cpp
216ccd # End Source File
67df4f # Begin Source File
a4af5a
1113e3 SOURCE=.\PGPdiskDrvNT\Source\PGPdiskWorkerThread.cpp
176ccd # End Source File
7adf4f # Begin Source File
05af5a
bb7e0c SOURCE=.\PGPdiskDrvNT\Source\UserMemoryManager.cpp
906ccd # End Source File
54df4f # Begin Source File
2aaf5a
86af6c SOURCE=.\PGPdiskDrvNT\Source\VolFile.cpp
d86ccd # End Source File
84df4f # Begin Source File
8baf5a
80b687 SOURCE=.\PGPdiskDrvNT\Source\Volume.cpp
196ccd # End Source File
e13f5a # End Group
186cec # Begin Group "Driver Classes Source"
93af5a
5eb050 # PROP Default_Filter ""
badf4f # Begin Source File
cbaf5a
2b8358 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskDriver.cpp
2c6ccd # End Source File
cbdf4f # Begin Source File
1caf5a
f80fe1 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterface.cpp
4f6ccd # End Source File
7ddf4f # Begin Source File
c7af5a
3a071b SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceComm.cpp
2f6ccd # End Source File
7bdf4f # Begin Source File
5aaf5a
6f6a8d SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceErrors.cpp
bc6ccd # End Source File
cddf4f # Begin Source File
c1af5a
ef6cdd SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceHooks.cpp
446ccd # End Source File
9fdf4f # Begin Source File
a0af5a
--01eb 0007867d4f94011005c Page 4 of PGPdiskDrvNT.dsp
a8c833 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceVolumes.cpp
306ccd # End Source File
263f5a # End Group
e5df4f # Begin Source File
86af5a
aea6dd SOURCE=.\PGPdiskDrvNT\Source\CRunTimeExtras.cpp
7f6ccd # End Source File
8edf4f # Begin Source File
adaf5a
cc9f77 SOURCE=.\PGPdiskDrvNT\Source\KernelModeUtils.cpp
5a6ccd # End Source File
eedf4f # Begin Source File
acaf5a
fbc6c8 SOURCE=.\PGPdiskDrvNT\Source\NtThreadSecurity.cpp
af6ccd # End Source File
cf3f5a # End Group
ddba44 # Begin Group "Header Files"
68af5a
d2561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
8c9155 # Begin Group "Shared Headers"
25af5a
1eb050 # PROP Default_Filter ""
34df4f # Begin Source File
6caf5a
6f6f63 SOURCE=.\Shared\CommonStrings.h
856ccd # End Source File
f7df4f # Begin Source File
93af5a
186ce2 SOURCE=.\Shared\DualErr.h
9c6ccd # End Source File
59df4f # Begin Source File
09af5a
15d0e8 SOURCE=.\Shared\Errors.h
8f6ccd # End Source File
28df4f # Begin Source File
abaf5a
7f7cb4 SOURCE=.\Shared\GenericCallback.h
e86ccd # End Source File
9cdf4f # Begin Source File
37af5a
ffa069 SOURCE=.\Shared\Packets.h
456ccd # End Source File
d9df4f # Begin Source File
93af5a
8d3ceb SOURCE=.\Shared\PGPdiskContainer.h
966ccd # End Source File
cedf4f # Begin Source File
5faf5a
07e8bc SOURCE=.\Shared\PGPdiskDefaults.h
fb6ccd # End Source File
cfdf4f # Begin Source File
52af5a
03b727 SOURCE=.\Shared\PGPdiskFileFormat.h
7c6ccd # End Source File
dfdf4f # Begin Source File
deaf5a
ce9b28 SOURCE=.\Shared\PGPdiskHighLevelUtils.h
3d6ccd # End Source File
9edf4f # Begin Source File
5faf5a
0e305a SOURCE=.\Shared\PGPdiskLowLevelUtils.h
676ccd # End Source File
55df4f # Begin Source File
f1af5a
3e35ff SOURCE=.\Shared\PGPdiskPfl.h
516ccd # End Source File
97df4f # Begin Source File
acaf5a
e4d064 SOURCE=.\Shared\PGPdiskVersion.h
6e6ccd # End Source File
60df4f # Begin Source File
78af5a
--4c2e 000d342dc394011005c Page 5 of PGPdiskDrvNT.dsp
fb2f73 SOURCE=.\Shared\Required.h
336ccd # End Source File
e4df4f # Begin Source File
16af5a
828bc0 SOURCE=.\Shared\SecureMemory.h
826ccd # End Source File
acdf4f # Begin Source File
2faf5a
f56f12 SOURCE=.\Shared\SecureString.h
cf6ccd # End Source File
73df4f # Begin Source File
25af5a
1934dd SOURCE=.\Shared\StringAssociation.h
546ccd # End Source File
1edf4f # Begin Source File
e2af5a
2d1a46 SOURCE=.\Shared\SystemConstants.h
f26ccd # End Source File
9fdf4f # Begin Source File
89af5a
9f7b7c SOURCE=.\Shared\UtilityFunctions.h
046ccd # End Source File
4edf4f # Begin Source File
d2af5a
d648f5 SOURCE=.\Shared\WaitObjectClasses.h
b96ccd # End Source File
a93f5a # End Group
e1018b # Begin Group "Encryption Headers"
8baf5a
00b050 # PROP Default_Filter ""
efdf4f # Begin Source File
92af5a
3c5d10 SOURCE=.\Encryption\Cast5.h
1b6ccd # End Source File
bbdf4f # Begin Source File
66af5a
8e145f SOURCE=.\Encryption\Cast5Box.h
1f6ccd # End Source File
b6df4f # Begin Source File
65af5a
8d049d SOURCE=.\Encryption\CipherContext.h
966ccd # End Source File
eadf4f # Begin Source File
8caf5a
057475 SOURCE=.\Encryption\CipherUtils.h
026ccd # End Source File
61df4f # Begin Source File
e0af5a
bb09d3 SOURCE=.\Encryption\SHA.h
f86ccd # End Source File
503f5a # End Group
2a925e # Begin Group "FakeSource"
35af5a
70b050 # PROP Default_Filter ""
e4185e # Begin Group "sys"
5faf5a
8eb050 # PROP Default_Filter ""
32df4f # Begin Source File
4daf5a
de1450 SOURCE=.\PGPdiskDrvNT\FakeSource\sys\Types.h
236ccd # End Source File
723f5a # End Group
bbdf4f # Begin Source File
72af5a
370195 SOURCE=.\PGPdiskDrvNT\FakeSource\Crtdbg.h
306ccd # End Source File
44df4f # Begin Source File
ecaf5a
fe9413 SOURCE=.\PGPdiskDrvNT\FakeSource\Limits.h
c96ccd # End Source File
d83f5a # End Group
d30d68 # Begin Group "Custom Classes Headers"
--b5d4 0005acdb8d24011005c Page 6 of PGPdiskDrvNT.dsp
e0af5a
53b050 # PROP Default_Filter ""
65df4f # Begin Source File
f9af5a
35f700 SOURCE=.\PGPdiskDrvNT\Source\File.h
4b6ccd # End Source File
f1df4f # Begin Source File
81af5a
c25524 SOURCE=.\PGPdiskDrvNT\Source\LockableList.h
986ccd # End Source File
80df4f # Begin Source File
3daf5a
cc7c22 SOURCE=.\PGPdiskDrvNT\Source\LookasideList.h
1d6ccd # End Source File
53df4f # Begin Source File
8aaf5a
2d114f SOURCE=.\PGPdiskDrvNT\Source\PGPdisk.h
df6ccd # End Source File
7fdf4f # Begin Source File
fcaf5a
2962a0 SOURCE=.\PGPdiskDrvNT\Source\PGPdiskRequestQueue.h
226ccd # End Source File
80df4f # Begin Source File
15af5a
15deec SOURCE=.\PGPdiskDrvNT\Source\PGPdiskWorkerThread.h
f06ccd # End Source File
cedf4f # Begin Source File
6faf5a
ddb1a1 SOURCE=.\PGPdiskDrvNT\Source\UserMemoryManager.h
976ccd # End Source File
4bdf4f # Begin Source File
7aaf5a
4e8342 SOURCE=.\PGPdiskDrvNT\Source\VolFile.h
756ccd # End Source File
24df4f # Begin Source File
90af5a
511051 SOURCE=.\PGPdiskDrvNT\Source\Volume.h
306ccd # End Source File
ea3f5a # End Group
8be9ff # Begin Group "Driver Classes Headers"
d1af5a
7cb050 # PROP Default_Filter ""
13df4f # Begin Source File
59af5a
819bde SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskDriver.h
be6ccd # End Source File
b0df4f # Begin Source File
0caf5a
752c48 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterface.h
5b6ccd # End Source File
eedf4f # Begin Source File
e4af5a
ad5707 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceComm.h
646ccd # End Source File
c8df4f # Begin Source File
15af5a
8def90 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceErrors.h
fd6ccd # End Source File
a0df4f # Begin Source File
30af5a
e897c3 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceHooks.h
8a6ccd # End Source File
15df4f # Begin Source File
93af5a
f67098 SOURCE=.\PGPdiskDrvNT\Source\CPGPdiskInterfaceVolumes.h
886ccd # End Source File
3e3f5a # End Group
87df4f # Begin Source File
d4af5a
44e55c SOURCE=.\PGPdiskDrvNT\Source\CRunTimeExtras.h
c86ccd # End Source File
5adf4f # Begin Source File
--0aea 00120b7800f4011005c Page 7 of PGPdiskDrvNT.dsp
e0af5a
5682c4 SOURCE=.\PGPdiskDrvNT\Source\FSCTLCodes.h
eb6ccd # End Source File
03df4f # Begin Source File
d3af5a
1cb580 SOURCE=.\PGPdiskDrvNT\Source\Function.h
8e6ccd # End Source File
13df4f # Begin Source File
baaf5a
978476 SOURCE=.\PGPdiskDrvNT\Source\Globals.h
016ccd # End Source File
47df4f # Begin Source File
3baf5a
f20b96 SOURCE=.\PGPdiskDrvNT\Source\KernelModeUtils.h
6f6ccd # End Source File
62df4f # Begin Source File
3caf5a
90eee7 SOURCE=.\PGPdiskDrvNT\Source\NtThreadSecurity.h
aa6ccd # End Source File
0cdf4f # Begin Source File
abaf5a
5df205 SOURCE=.\PGPdiskDrvNT\Source\OperatorNewFixups.h
3f6ccd # End Source File
d53f5a # End Group
d9df4f # Begin Source File
44af5a
da23e8 SOURCE=.\PGPdiskDrvNT\makefile
266ccd # End Source File
9edf4f # Begin Source File
96af5a
0ac58f SOURCE=.\PGPdiskDrvNT\msglog.mc
316ccd # End Source File
69df4f # Begin Source File
3baf5a
67b3b8 SOURCE=.\PGPdiskDrvNT\RunBuild.bat
ae6ccd # End Source File
3bdf4f # Begin Source File
88af5a
1609be SOURCE=.\PGPdiskDrvNT\RunBuildAux.bat
e26ccd # End Source File
1fdf4f # Begin Source File
1eaf5a
75ae8e SOURCE=.\PGPdiskDrvNT\sources
9c6ccd # End Source File
8ce5cf # End Target
20f262 # End Project
--75bc 001e5dbf6074011005d Page 1 of PGPdiskDrvNT.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
e4320a Project: "PGPdiskDrvNT"=PGPdiskDrvNT.dsp - Package Owner=<4>
3faf5a
50e41b Package=<5>
fa8818 {{{
2f418b }}}
3caf5a
e3bec7 Package=<4>
bd8818 {{{
1a418b }}}
deaf5a
712d94 ###############################################################################
caaf5a
f420da Global:
5caf5a
b9e41b Package=<5>
db8818 {{{
39418b }}}
daaf5a
3032c2 Package=<3>
fd8818 {{{
ab418b }}}
f2af5a
0e2d94 ###############################################################################
e5af5a
--c8dc 0001e457d914011005e Page 1 of PGPdiskDrvWin95.dsp
da3fe2 # Microsoft Developer Studio Project File - Name="PGPdiskDrvWin95" - Package Ow¶
5f6f39 ner=<4>
0ae7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
7a8537 # ** DO NOT EDIT **
a6af5a
01669e # TARGTYPE "Win32 (x86) External Target" 0x0106
ebaf5a
ad8bf6 CFG=PGPdiskDrvWin95 - Win32 Release
48894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
775c35 !MESSAGE use the Export Makefile command and run
3f6309 !MESSAGE·
17ce97 !MESSAGE NMAKE /f "PGPdiskDrvWin95.mak".
5a6309 !MESSAGE·
20cdb3 !MESSAGE You can specify a configuration when running NMAKE
3ce013 !MESSAGE by defining the macro CFG on the command line. For example:
006309 !MESSAGE·
71d539 !MESSAGE NMAKE /f "PGPdiskDrvWin95.mak" CFG="PGPdiskDrvWin95 - Win32 Release"
e16309 !MESSAGE·
561dd7 !MESSAGE Possible choices for configuration are:
146309 !MESSAGE·
ac33e9 !MESSAGE "PGPdiskDrvWin95 - Win32 Release" (based on\
27f03b ·"Win32 (x86) External Target")
0ba1e4 !MESSAGE "PGPdiskDrvWin95 - Win32 Debug" (based on\
9ef03b ·"Win32 (x86) External Target")
6e6309 !MESSAGE·
a4af5a
273e63 # Begin Project
60b23f # PROP Scc_ProjName ""
6adf4a # PROP Scc_LocalPath ""
d8af5a
face0a !IF ·"$(CFG)" == "PGPdiskDrvWin95 - Win32 Release"
8faf5a
c9e662 # PROP BASE Use_Debug_Libraries 0
a37d73 # PROP BASE Output_Dir "Release"
396180 # PROP BASE Intermediate_Dir "Release"
b7c084 # PROP BASE Cmd_Line "NMAKE /f PGPdiskDrvWin95.mak"
390e97 # PROP BASE Rebuild_Opt "/a"
10ef5b # PROP BASE Target_File "PGPdiskDrvWin95.exe"
2f5ab9 # PROP BASE Bsc_Name "PGPdiskDrvWin95.bsc"
1b4c81 # PROP BASE Target_Dir ""
a1b771 # PROP Use_Debug_Libraries 0
79f310 # PROP Output_Dir "Release"
6e01a1 # PROP Intermediate_Dir "Release"
7ddf32 # PROP Cmd_Line "PGPdiskDrvWin95\PGPdiskDrvRelease.bat"
f22691 # PROP Rebuild_Opt "/a"
785d3a # PROP Target_File "PGPdisk.pdr"
dcd1ba # PROP Bsc_Name "PGPdiskDrv.bsc"
7cb6fa # PROP Target_Dir ""
51af5a
01ca3f !ELSEIF ·"$(CFG)" == "PGPdiskDrvWin95 - Win32 Debug"
9baf5a
31ffba # PROP BASE Use_Debug_Libraries 1
1b54b8 # PROP BASE Output_Dir "Debug"
ba198a # PROP BASE Intermediate_Dir "Debug"
bbc084 # PROP BASE Cmd_Line "NMAKE /f PGPdiskDrvWin95.mak"
350e97 # PROP BASE Rebuild_Opt "/a"
9aef5b # PROP BASE Target_File "PGPdiskDrvWin95.exe"
c65ab9 # PROP BASE Bsc_Name "PGPdiskDrvWin95.bsc"
844c81 # PROP BASE Target_Dir ""
68aea9 # PROP Use_Debug_Libraries 1
3ead22 # PROP Output_Dir "Debug"
34b954 # PROP Intermediate_Dir "Debug"
b4d417 # PROP Cmd_Line "PGPdiskDrvWin95\PGPdiskDrvDebug.bat"
9c2691 # PROP Rebuild_Opt "/a"
915d3a # PROP Target_File "PGPdisk.pdr"
1b6d01 # PROP Bsc_Name "PGPdisk.bsc"
a6b6fa # PROP Target_Dir ""
61af5a
0230ec !ENDIF·
07af5a
44b8a5 # Begin Target
1eaf5a
--051c 000e37cb20a4011005e Page 2 of PGPdiskDrvWin95.dsp
6a03fc # Name "PGPdiskDrvWin95 - Win32 Release"
cce7eb # Name "PGPdiskDrvWin95 - Win32 Debug"
23af5a
6ece0a !IF ·"$(CFG)" == "PGPdiskDrvWin95 - Win32 Release"
a4af5a
55ca3f !ELSEIF ·"$(CFG)" == "PGPdiskDrvWin95 - Win32 Debug"
40af5a
0730ec !ENDIF·
33af5a
2c4cc4 # Begin Group "Source Files"
00af5a
0ab050 # PROP Default_Filter ""
b8ed3f # Begin Group "Custom Classes Source"
6caf5a
23b050 # PROP Default_Filter ""
11df4f # Begin Source File
a8af5a
9dff3e SOURCE=.\PGPdiskDrvWin95\Source\DcbManager.cpp
8a6ccd # End Source File
c5df4f # Begin Source File
2caf5a
1c7cf2 SOURCE=.\PGPdiskDrvWin95\Source\FatParser.cpp
c16ccd # End Source File
19df4f # Begin Source File
d5af5a
954c27 SOURCE=.\PGPdiskDrvWin95\Source\File.cpp
1b6ccd # End Source File
0edf4f # Begin Source File
0caf5a
d95642 SOURCE=.\PGPdiskDrvWin95\Source\FileSystemParser.cpp
9a6ccd # End Source File
78df4f # Begin Source File
eeaf5a
14b598 SOURCE=.\PGPdiskDrvWin95\Source\IopProcessor.cpp
186ccd # End Source File
e1df4f # Begin Source File
7daf5a
6cbbad SOURCE=.\PGPdiskDrvWin95\Source\PGPdisk.cpp
9e6ccd # End Source File
f4df4f # Begin Source File
1faf5a
a8bc4e SOURCE=.\PGPdiskDrvWin95\Source\VolFile.cpp
1a6ccd # End Source File
a2df4f # Begin Source File
3faf5a
9e0da4 SOURCE=.\PGPdiskDrvWin95\Source\Volume.cpp
6a6ccd # End Source File
cf3f5a # End Group
39c0e7 # Begin Group "Driver Class Source"
04af5a
40b050 # PROP Default_Filter ""
dcdf4f # Begin Source File
6caf5a
f9541b SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrv.cpp
dd6ccd # End Source File
5bdf4f # Begin Source File
10af5a
a706db SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvComm.cpp
4b6ccd # End Source File
74df4f # Begin Source File
b7af5a
0d4c7c SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvDebug.cpp
586ccd # End Source File
2bdf4f # Begin Source File
eaaf5a
ddb1ae SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvErrors.cpp
e36ccd # End Source File
83df4f # Begin Source File
d5af5a
20aad0 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvHooks.cpp
fc6ccd # End Source File
e3df4f # Begin Source File
--c831 0005a460bb54011005e Page 3 of PGPdiskDrvWin95.dsp
e0af5a
6f4157 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvIos.cpp
946ccd # End Source File
56df4f # Begin Source File
77af5a
eddb71 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvVolumes.cpp
da6ccd # End Source File
a5df4f # Begin Source File
3eaf5a
6d1d01 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvWinutils.cpp
666ccd # End Source File
7b3f5a # End Group
8d6ef3 # Begin Group "Encryption Source"
c5af5a
82b050 # PROP Default_Filter ""
5edf4f # Begin Source File
20af5a
8070d8 SOURCE=.\Encryption\Cast5.cpp
666ccd # End Source File
39df4f # Begin Source File
28af5a
1d6ab3 SOURCE=.\Encryption\Cast5Box.cpp
7e6ccd # End Source File
05df4f # Begin Source File
18af5a
ba8328 SOURCE=.\Encryption\CipherContext.cpp
6d6ccd # End Source File
9fdf4f # Begin Source File
98af5a
39d7f6 SOURCE=.\Encryption\CipherUtils.cpp
0c6ccd # End Source File
2adf4f # Begin Source File
afaf5a
0d84bb SOURCE=.\Encryption\SHA.cpp
ba6ccd # End Source File
fb3f5a # End Group
7c1927 # Begin Group "Shared Source"
80af5a
d5b050 # PROP Default_Filter ""
28df4f # Begin Source File
41af5a
51b8e5 SOURCE=.\Shared\CommonStrings.cpp
a16ccd # End Source File
8bdf4f # Begin Source File
ffaf5a
e71f6a SOURCE=.\Shared\DualErr.cpp
456ccd # End Source File
b9df4f # Begin Source File
b7af5a
169dfd SOURCE=.\Shared\Errors.cpp
e46ccd # End Source File
92df4f # Begin Source File
51af5a
bd9019 SOURCE=.\Shared\FatUtils.cpp
256ccd # End Source File
26df4f # Begin Source File
81af5a
649af7 SOURCE=.\Shared\PGPdiskContainer.cpp
fc6ccd # End Source File
e6df4f # Begin Source File
72af5a
b8ab80 SOURCE=.\Shared\PGPdiskHighLevelUtils.cpp
f06ccd # End Source File
38df4f # Begin Source File
1caf5a
87732d SOURCE=.\Shared\PGPdiskLowLevelUtils.cpp
1d6ccd # End Source File
97df4f # Begin Source File
e9af5a
10f5c7 SOURCE=.\Shared\PGPdiskPfl.cpp
f66ccd # End Source File
5adf4f # Begin Source File
--167c 0003fc33ede4011005e Page 4 of PGPdiskDrvWin95.dsp
e0af5a
c19c58 SOURCE=.\Shared\SecureMemory.cpp
ae6ccd # End Source File
05df4f # Begin Source File
74af5a
8f51f9 SOURCE=.\Shared\SecureString.cpp
c56ccd # End Source File
47df4f # Begin Source File
3eaf5a
b6f4cd SOURCE=.\Shared\StringAssociation.cpp
d86ccd # End Source File
46df4f # Begin Source File
beaf5a
afa0d5 SOURCE=.\Shared\WaitObjectClasses.cpp
eb6ccd # End Source File
583f5a # End Group
893f5a # End Group
4eba44 # Begin Group "Header Files"
09af5a
e4b050 # PROP Default_Filter ""
dd0d68 # Begin Group "Custom Classes Headers"
ddaf5a
efb050 # PROP Default_Filter ""
8edf4f # Begin Source File
c7af5a
68f593 SOURCE=.\PGPdiskDrvWin95\Source\DcbManager.h
436ccd # End Source File
fcdf4f # Begin Source File
57af5a
60d5d8 SOURCE=.\PGPdiskDrvWin95\Source\FatParser.h
da6ccd # End Source File
bcdf4f # Begin Source File
d3af5a
001144 SOURCE=.\PGPdiskDrvWin95\Source\File.h
366ccd # End Source File
6bdf4f # Begin Source File
36af5a
ea28e5 SOURCE=.\PGPdiskDrvWin95\Source\FileSystemParser.h
726ccd # End Source File
d9df4f # Begin Source File
18af5a
6a1b26 SOURCE=.\PGPdiskDrvWin95\Source\IopProcessor.h
b06ccd # End Source File
10df4f # Begin Source File
08af5a
43c911 SOURCE=.\PGPdiskDrvWin95\Source\PGPdisk.h
116ccd # End Source File
91df4f # Begin Source File
00af5a
655b1c SOURCE=.\PGPdiskDrvWin95\Source\VolFile.h
466ccd # End Source File
f4df4f # Begin Source File
1baf5a
b1b36f SOURCE=.\PGPdiskDrvWin95\Source\Volume.h
3c6ccd # End Source File
f63f5a # End Group
c45780 # Begin Group "Driver Class Headers"
3caf5a
f6b050 # PROP Default_Filter ""
09df4f # Begin Source File
96af5a
80561e SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrv.h
6e6ccd # End Source File
4bdf4f # Begin Source File
aeaf5a
4e3a29 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvComm.h
0d6ccd # End Source File
c8df4f # Begin Source File
08af5a
62dc8d SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvDebug.h
206ccd # End Source File
3fdf4f # Begin Source File
--dbb6 000137325a24011005e Page 5 of PGPdiskDrvWin95.dsp
e0af5a
16ee50 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvErrors.h
2d6ccd # End Source File
42df4f # Begin Source File
27af5a
aa5fd2 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvHooks.h
066ccd # End Source File
e8df4f # Begin Source File
63af5a
d10ddc SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvIos.h
706ccd # End Source File
7fdf4f # Begin Source File
67af5a
b4b695 SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvVolumes.h
d36ccd # End Source File
7fdf4f # Begin Source File
6daf5a
e1891a SOURCE=.\PGPdiskDrvWin95\Source\CPGPdiskDrvWinutils.h
386ccd # End Source File
983f5a # End Group
b89755 # Begin Group "Fake Headers"
efaf5a
95b050 # PROP Default_Filter ""
70185e # Begin Group "sys"
b6af5a
96b050 # PROP Default_Filter ""
aedf4f # Begin Source File
6aaf5a
9fc884 SOURCE=.\PGPdiskDrvWin95\FakeSource\sys\Types.h
d16ccd # End Source File
363f5a # End Group
f4df4f # Begin Source File
a1af5a
520396 SOURCE=.\PGPdiskDrvWin95\FakeSource\Crtdbg.h
a06ccd # End Source File
28df4f # Begin Source File
46af5a
2a9610 SOURCE=.\PGPdiskDrvWin95\FakeSource\Limits.h
f26ccd # End Source File
8fdf4f # Begin Source File
d9af5a
89f4bd SOURCE=.\PGPdiskDrvWin95\FakeSource\Stdarg.h
556ccd # End Source File
78df4f # Begin Source File
f9af5a
a5781d SOURCE=.\PGPdiskDrvWin95\FakeSource\Stddef.h
036ccd # End Source File
80df4f # Begin Source File
70af5a
4f5c99 SOURCE=.\PGPdiskDrvWin95\FakeSource\Stdlib.h
b56ccd # End Source File
5edf4f # Begin Source File
52af5a
e7fb91 SOURCE=.\PGPdiskDrvWin95\FakeSource\String.h
276ccd # End Source File
653f5a # End Group
53018b # Begin Group "Encryption Headers"
e1af5a
25b050 # PROP Default_Filter ""
2ddf4f # Begin Source File
44af5a
ab5d10 SOURCE=.\Encryption\Cast5.h
b96ccd # End Source File
1edf4f # Begin Source File
8aaf5a
dd145f SOURCE=.\Encryption\Cast5Box.h
6c6ccd # End Source File
1adf4f # Begin Source File
beaf5a
28049d SOURCE=.\Encryption\CipherContext.h
a46ccd # End Source File
13df4f # Begin Source File
--0fb5 000735f6ee54011005e Page 6 of PGPdiskDrvWin95.dsp
e0af5a
2f7475 SOURCE=.\Encryption\CipherUtils.h
1d6ccd # End Source File
0edf4f # Begin Source File
b9af5a
1c09d3 SOURCE=.\Encryption\SHA.h
bb6ccd # End Source File
c33f5a # End Group
d69155 # Begin Group "Shared Headers"
cdaf5a
7bb050 # PROP Default_Filter ""
b2df4f # Begin Source File
d9af5a
f56f63 SOURCE=.\Shared\CommonStrings.h
446ccd # End Source File
d8df4f # Begin Source File
69af5a
ad6ce2 SOURCE=.\Shared\DualErr.h
b36ccd # End Source File
bddf4f # Begin Source File
e0af5a
03d0e8 SOURCE=.\Shared\Errors.h
0c6ccd # End Source File
86df4f # Begin Source File
82af5a
ea45e0 SOURCE=.\Shared\FatUtils.h
ca6ccd # End Source File
35df4f # Begin Source File
58af5a
d57cb4 SOURCE=.\Shared\GenericCallback.h
1b6ccd # End Source File
0fdf4f # Begin Source File
e5af5a
1ba069 SOURCE=.\Shared\Packets.h
f16ccd # End Source File
e3df4f # Begin Source File
a5af5a
273ceb SOURCE=.\Shared\PGPdiskContainer.h
716ccd # End Source File
cbdf4f # Begin Source File
70af5a
d4e8bc SOURCE=.\Shared\PGPdiskDefaults.h
bc6ccd # End Source File
42df4f # Begin Source File
c9af5a
35b727 SOURCE=.\Shared\PGPdiskFileFormat.h
a36ccd # End Source File
aadf4f # Begin Source File
80af5a
ac9b28 SOURCE=.\Shared\PGPdiskHighLevelUtils.h
166ccd # End Source File
9bdf4f # Begin Source File
f6af5a
36305a SOURCE=.\Shared\PGPdiskLowLevelUtils.h
fe6ccd # End Source File
31df4f # Begin Source File
1baf5a
5f35ff SOURCE=.\Shared\PGPdiskPfl.h
916ccd # End Source File
f7df4f # Begin Source File
90af5a
63d064 SOURCE=.\Shared\PGPdiskVersion.h
946ccd # End Source File
79df4f # Begin Source File
91af5a
ce2f73 SOURCE=.\Shared\Required.h
2c6ccd # End Source File
4bdf4f # Begin Source File
0faf5a
a08bc0 SOURCE=.\Shared\SecureMemory.h
696ccd # End Source File
73df4f # Begin Source File
--b465 0018c1177af4011005e Page 7 of PGPdiskDrvWin95.dsp
e0af5a
e06f12 SOURCE=.\Shared\SecureString.h
136ccd # End Source File
5cdf4f # Begin Source File
deaf5a
b31b42 SOURCE=.\Shared\SimpleQueue.h
586ccd # End Source File
2ddf4f # Begin Source File
e2af5a
d434dd SOURCE=.\Shared\StringAssociation.h
896ccd # End Source File
e3df4f # Begin Source File
3faf5a
811a46 SOURCE=.\Shared\SystemConstants.h
2f6ccd # End Source File
27df4f # Begin Source File
9aaf5a
3c7b7c SOURCE=.\Shared\UtilityFunctions.h
8d6ccd # End Source File
d7df4f # Begin Source File
d9af5a
c948f5 SOURCE=.\Shared\WaitObjectClasses.h
186ccd # End Source File
d33f5a # End Group
54df4f # Begin Source File
dfaf5a
3d5c28 SOURCE=.\PGPdiskDrvWin95\Source\Globals.h
6e6ccd # End Source File
7bdf4f # Begin Source File
05af5a
b65829 SOURCE=.\PGPdiskDrvWin95\Source\PlacementNew.h
766ccd # End Source File
c3df4f # Begin Source File
72af5a
e3779a SOURCE=.\PGPdiskDrvWin95\Source\Wrappers.h
286ccd # End Source File
ab3f5a # End Group
a4df4f # Begin Source File
c0af5a
6b1cb5 SOURCE=.\PGPdiskDrvWin95\PGPdiskDrvDebug.bat
536ccd # End Source File
70df4f # Begin Source File
4baf5a
abb815 SOURCE=.\PGPdiskDrvWin95\PGPdiskDrvDebug.mak
ee6ccd # End Source File
58df4f # Begin Source File
c9af5a
25daf6 SOURCE=.\PGPdiskDrvWin95\PGPdiskDrvDebugAux.bat
b76ccd # End Source File
6bdf4f # Begin Source File
b7af5a
d29851 SOURCE=.\PGPdiskDrvWin95\PGPdiskDrvRelease.bat
346ccd # End Source File
eedf4f # Begin Source File
67af5a
4a3cf1 SOURCE=.\PGPdiskDrvWin95\PGPdiskDrvRelease.mak
7f6ccd # End Source File
e5df4f # Begin Source File
5baf5a
5c5b9a SOURCE=.\PGPdiskDrvWin95\PGPdiskDrvReleaseAux.bat
5d6ccd # End Source File
b0e5cf # End Target
8cf262 # End Project
--4d88 001b4a8651c4011005f Page 1 of PGPdiskDrvWin95.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
04e069 Project: "PGPdiskDrvWin95"=.\PGPdiskDrvWin95.dsp - Package Owner=<4>
bdaf5a
3de41b Package=<5>
e98818 {{{
df418b }}}
dbaf5a
7dbec7 Package=<4>
558818 {{{
96418b }}}
c0af5a
6f2d94 ###############################################################################
d0af5a
5a20da Global:
49af5a
1ae41b Package=<5>
328818 {{{
af418b }}}
a4af5a
5b32c2 Package=<3>
ce8818 {{{
3b418b }}}
8baf5a
a32d94 ###############################################################################
b4af5a
--8002 0002c4dc8fd40110060 Page 1 of PGPdiskInstallHelper.dsp
9d4419 # Microsoft Developer Studio Project File - Name="PGPdiskInstallHelper" - Packa¶
9a4479 ge Owner=<4>
d0e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
5e8537 # ** DO NOT EDIT **
97af5a
68a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
ceaf5a
ac62a7 CFG=PGPdiskInstallHelper - Win32 Debug
09894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
c95c35 !MESSAGE use the Export Makefile command and run
276309 !MESSAGE·
0e644c !MESSAGE NMAKE /f "PGPdiskInstallHelper.mak".
816309 !MESSAGE·
a2cdb3 !MESSAGE You can specify a configuration when running NMAKE
71e013 !MESSAGE by defining the macro CFG on the command line. For example:
a86309 !MESSAGE·
99a738 !MESSAGE NMAKE /f "PGPdiskInstallHelper.mak"\
a60c2e ·CFG="PGPdiskInstallHelper - Win32 Debug"
446309 !MESSAGE·
221dd7 !MESSAGE Possible choices for configuration are:
a36309 !MESSAGE·
34741a !MESSAGE "PGPdiskInstallHelper - Win32 Release" (based on\
9617ca ·"Win32 (x86) Dynamic-Link Library")
5a71ad !MESSAGE "PGPdiskInstallHelper - Win32 Debug" (based on\
0617ca ·"Win32 (x86) Dynamic-Link Library")
c86309 !MESSAGE·
9caf5a
a53e63 # Begin Project
51b23f # PROP Scc_ProjName ""
b4df4a # PROP Scc_LocalPath ""
b440a4 CPP=cl.exe
2ea46a MTL=midl.exe
9f2e1f RSC=rc.exe
2eaf5a
b70908 !IF ·"$(CFG)" == "PGPdiskInstallHelper - Win32 Release"
22af5a
44fcfb # PROP BASE Use_MFC 5
14e662 # PROP BASE Use_Debug_Libraries 0
957d73 # PROP BASE Output_Dir "Release"
716180 # PROP BASE Intermediate_Dir "Release"
a04c81 # PROP BASE Target_Dir ""
df5f15 # PROP Use_MFC 5
5db771 # PROP Use_Debug_Libraries 0
c07734 # PROP Output_Dir "PGPdiskInstallHelper\Release"
452ff7 # PROP Intermediate_Dir "PGPdiskInstallHelper\Release"
cc9ad5 # PROP Ignore_Export_Lib 0
f1b6fa # PROP Target_Dir ""
d2c868 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D ¶
935b25 "_WINDLL" /Yu"stdafx.h" /FD /c
e64670 # ADD CPP /nologo /MT /W3 /WX /GX /O2 /I "..\..\..\libs\pfl\common" /I "..\..\.¶
ed1dfa .\libs\pfl\win32" /I "Shared" /I "Encryption" /I "PGPdiskInstallHelper\Source" ¶
f0ff63 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOWS" /D PGP_DEBUG=0 /D "PGPDISK_¶
2c4c34 MFC" /D "PGPDISK_INSTALL_DLL" /D "PGP_INTEL" /D "_USRDLL" /D "_WINDLL" /YX /FD ¶
49a99b /c
b31e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
006d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
61b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
7ade84 # ADD RSC /l 0x409 /d "NDEBUG"
6418fc BSC32=bscmake.exe
eb7a24 # ADD BASE BSC32 /nologo
da4f1b # ADD BSC32 /nologo
95268f LINK32=link.exe
284a30 # ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386
f3587f # ADD LINK32 mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Release\pflCommon.lib /n¶
63e8e2 ologo /subsystem:windows /dll /machine:I386 /out:"PGPdiskInstallHelper\Release/¶
e1cf34 PGPdskIH.dll"
be05c8 # SUBTRACT LINK32 /verbose
40af5a
f2b99e !ELSEIF ·"$(CFG)" == "PGPdiskInstallHelper - Win32 Debug"
d7af5a
c1fcfb # PROP BASE Use_MFC 5
2cffba # PROP BASE Use_Debug_Libraries 1
--5367 00094b896c140110060 Page 2 of PGPdiskInstallHelper.dsp
c954b8 # PROP BASE Output_Dir "Debug"
bb198a # PROP BASE Intermediate_Dir "Debug"
4c4c81 # PROP BASE Target_Dir ""
725f15 # PROP Use_MFC 5
7daea9 # PROP Use_Debug_Libraries 1
4447df # PROP Output_Dir "PGPdiskInstallHelper\Debug"
890ca9 # PROP Intermediate_Dir "PGPdiskInstallHelper\Debug"
6d9ad5 # PROP Ignore_Export_Lib 0
0db6fa # PROP Target_Dir ""
276cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
0d7161 DOWS" /D "_WINDLL" /Yu"stdafx.h" /FD /c
f4a1ed # ADD CPP /nologo /MTd /W3 /WX /Gm /GX /Zi /Od /I "..\..\..\libs\pfl\common" /I¶
4d1004 ·"..\..\..\libs\pfl\win32" /I "Shared" /I "Encryption" /I "PGPdiskInstallHelper¶
038ea6 \Source" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D PGP_WIN32=1 /D PGP_DEBUG=1 /D ¶
2eb22a "PGPDISK_MFC" /D "PGPDISK_INSTALL_DLL" /D "PGP_INTEL" /D "UNFINISHED_CODE_ALLOW¶
e51a25 ED" /D "_USRDLL" /D "_WINDLL" /YX /FD /c
7bc0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
07b3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
68699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
df0443 # ADD RSC /l 0x409 /d "_DEBUG"
ce18fc BSC32=bscmake.exe
497a24 # ADD BASE BSC32 /nologo
974f1b # ADD BSC32 /nologo
a4268f LINK32=link.exe
7c63a4 # ADD BASE LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype¶
54a974 :sept
7414f3 # ADD LINK32 mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Debug\pflCommon.lib /nol¶
e37544 ogo /subsystem:windows /dll /debug /machine:I386 /out:"PGPdiskInstallHelper\Deb¶
f5c316 ug/PGPdskIH.dll" /pdbtype:sept
2caf5a
2530ec !ENDIF·
1baf5a
aab8a5 # Begin Target
61af5a
461d60 # Name "PGPdiskInstallHelper - Win32 Release"
3f6f65 # Name "PGPdiskInstallHelper - Win32 Debug"
db4cc4 # Begin Group "Source Files"
ecaf5a
34e96f # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
251927 # Begin Group "Shared Source"
8baf5a
47b050 # PROP Default_Filter ""
69df4f # Begin Source File
36af5a
e4b8e5 SOURCE=.\Shared\CommonStrings.cpp
8e6ccd # End Source File
68df4f # Begin Source File
1aaf5a
6939cf SOURCE=.\Shared\DriverComm.cpp
436ccd # End Source File
d2df4f # Begin Source File
aeaf5a
701f6a SOURCE=.\Shared\DualErr.cpp
466ccd # End Source File
4bdf4f # Begin Source File
82af5a
379dfd SOURCE=.\Shared\Errors.cpp
166ccd # End Source File
ffdf4f # Begin Source File
fdaf5a
769c92 SOURCE=.\Shared\LinkResolution.cpp
6c6ccd # End Source File
58df4f # Begin Source File
92af5a
14f5c7 SOURCE=.\Shared\PGPdiskPfl.cpp
436ccd # End Source File
ccdf4f # Begin Source File
d7af5a
044c3f SOURCE=.\Shared\PGPdiskRegistry.cpp
fd6ccd # End Source File
dcdf4f # Begin Source File
94af5a
--3a97 000688fc20340110060 Page 3 of PGPdiskInstallHelper.dsp
e14dfb SOURCE=.\Shared\SharedMemory.cpp
e36ccd # End Source File
49df4f # Begin Source File
74af5a
08f4cd SOURCE=.\Shared\StringAssociation.cpp
8f6ccd # End Source File
4cdf4f # Begin Source File
33af5a
eb5a00 SOURCE=.\Shared\Win32Utils.cpp
046ccd # End Source File
12df4f # Begin Source File
e3af5a
6085f8 SOURCE=.\Shared\WindowsVersion.cpp
e16ccd # End Source File
e93f5a # End Group
32df4f # Begin Source File
c1af5a
4c4505 SOURCE=.\PGPdiskInstallHelper\Source\CPGPdiskInstallHelperDll.cpp
566ccd # End Source File
2edf4f # Begin Source File
ebaf5a
954672 SOURCE=.\PGPdiskInstallHelper\PGPdiskInstallHelper.rc
5c6ccd # End Source File
5ddf4f # Begin Source File
1eaf5a
7f56ab SOURCE=.\PGPdiskInstallHelper\Source\StdAfx.cpp
e56ccd # End Source File
1b3f5a # End Group
7aba44 # Begin Group "Header Files"
feaf5a
2e1a9c # PROP Default_Filter "h;hpp;hxx;hm;inl"
109155 # Begin Group "Shared Headers"
7daf5a
a0b050 # PROP Default_Filter ""
dcdf4f # Begin Source File
55af5a
e16f63 SOURCE=.\Shared\CommonStrings.h
fa6ccd # End Source File
cddf4f # Begin Source File
ceaf5a
9aeac9 SOURCE=.\Shared\DriverComm.h
426ccd # End Source File
10df4f # Begin Source File
73af5a
b46ce2 SOURCE=.\Shared\DualErr.h
986ccd # End Source File
5fdf4f # Begin Source File
c1af5a
6ad0e8 SOURCE=.\Shared\Errors.h
c96ccd # End Source File
a6df4f # Begin Source File
fdaf5a
62e7cc SOURCE=.\Shared\LinkResolution.h
656ccd # End Source File
89df4f # Begin Source File
ebaf5a
17a069 SOURCE=.\Shared\Packets.h
476ccd # End Source File
d2df4f # Begin Source File
65af5a
05e8bc SOURCE=.\Shared\PGPdiskDefaults.h
5b6ccd # End Source File
68df4f # Begin Source File
b4af5a
d735ff SOURCE=.\Shared\PGPdiskPfl.h
706ccd # End Source File
f6df4f # Begin Source File
03af5a
9fd0dc SOURCE=.\Shared\PGPdiskRegistry.h
b16ccd # End Source File
52df4f # Begin Source File
68af5a
--0645 0010cfcac4d40110060 Page 4 of PGPdiskInstallHelper.dsp
45d064 SOURCE=.\Shared\PGPdiskVersion.h
466ccd # End Source File
c4df4f # Begin Source File
41af5a
ed2f73 SOURCE=.\Shared\Required.h
646ccd # End Source File
bddf4f # Begin Source File
b9af5a
aa9db6 SOURCE=.\Shared\SharedMemory.h
ba6ccd # End Source File
b2df4f # Begin Source File
5aaf5a
c034dd SOURCE=.\Shared\StringAssociation.h
836ccd # End Source File
dfdf4f # Begin Source File
32af5a
2e1a46 SOURCE=.\Shared\SystemConstants.h
746ccd # End Source File
6edf4f # Begin Source File
6caf5a
8a7b7c SOURCE=.\Shared\UtilityFunctions.h
7a6ccd # End Source File
4bdf4f # Begin Source File
1aaf5a
3dfef6 SOURCE=.\Shared\Win32Utils.h
086ccd # End Source File
193f5a # End Group
91df4f # Begin Source File
d0af5a
99c6bd SOURCE=.\PGPdiskInstallHelper\Source\CPGPdiskInstallHelperDll.h
0c6ccd # End Source File
8cdf4f # Begin Source File
d4af5a
826708 SOURCE=.\PGPdiskInstallHelper\Source\Resource.h
326ccd # End Source File
51df4f # Begin Source File
a8af5a
ec56eb SOURCE=.\PGPdiskInstallHelper\Source\StdAfx.h
1c6ccd # End Source File
7e3f5a # End Group
b48925 # Begin Group "Resource Files"
33af5a
b5a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
1fdf4f # Begin Source File
aeaf5a
12ca8a SOURCE=.\res\PGPdiskInstallHelper.rc2
226ccd # End Source File
2e3f5a # End Group
c5df4f # Begin Source File
91af5a
8f6d9e SOURCE=.\PGPdiskInstallHelper\PGPdiskInstallHelper.def
986ccd # End Source File
b9e5cf # End Target
0cf262 # End Project
--03bb 001e658c1ab40110061 Page 1 of PGPdiskInstallHelper.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
3adfe4 Project: "PGPdiskInstallHelper"=.\PGPdiskInstallHelper.dsp - Package Owner=<4>
beaf5a
ace41b Package=<5>
408818 {{{
c1418b }}}
24af5a
0ebec7 Package=<4>
ef8818 {{{
c1418b }}}
fdaf5a
0f2d94 ###############################################################################
eaaf5a
4120da Global:
0caf5a
c7e41b Package=<5>
e28818 {{{
61418b }}}
b9af5a
1232c2 Package=<3>
688818 {{{
7f418b }}}
e1af5a
3b2d94 ###############################################################################
e6af5a
--6668 000d2f8d3aa40110062 Page 1 of PGPdiskResident.dsp
952c9c # Microsoft Developer Studio Project File - Name="PGPdiskResident" - Package Ow¶
bc6f39 ner=<4>
78e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
a18537 # ** DO NOT EDIT **
d2af5a
0ae536 # TARGTYPE "Win32 (x86) Application" 0x0101
1aaf5a
2541ef CFG=PGPdiskResident - Win32 Debug
33894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
055c35 !MESSAGE use the Export Makefile command and run
3c6309 !MESSAGE·
1beceb !MESSAGE NMAKE /f "PGPdiskResident.mak".
0d6309 !MESSAGE·
b0cdb3 !MESSAGE You can specify a configuration when running NMAKE
1be013 !MESSAGE by defining the macro CFG on the command line. For example:
806309 !MESSAGE·
f9cf31 !MESSAGE NMAKE /f "PGPdiskResident.mak" CFG="PGPdiskResident - Win32 Debug"
526309 !MESSAGE·
5f1dd7 !MESSAGE Possible choices for configuration are:
5a6309 !MESSAGE·
9210d4 !MESSAGE "PGPdiskResident - Win32 Release" (based on "Win32 (x86) Application")
d276eb !MESSAGE "PGPdiskResident - Win32 Debug" (based on "Win32 (x86) Application")
196309 !MESSAGE·
a1af5a
833e63 # Begin Project
f1b23f # PROP Scc_ProjName ""
77df4a # PROP Scc_LocalPath ""
3a40a4 CPP=cl.exe
eaa46a MTL=midl.exe
122e1f RSC=rc.exe
abaf5a
7086c4 !IF ·"$(CFG)" == "PGPdiskResident - Win32 Release"
e1af5a
b1d693 # PROP BASE Use_MFC 6
1fe662 # PROP BASE Use_Debug_Libraries 0
ca7d73 # PROP BASE Output_Dir "Release"
296180 # PROP BASE Intermediate_Dir "Release"
ed4c81 # PROP BASE Target_Dir ""
f3757d # PROP Use_MFC 6
efb771 # PROP Use_Debug_Libraries 0
bcd64e # PROP Output_Dir "PGPdiskResident/Release"
5a4d6c # PROP Intermediate_Dir "PGPdiskResident/Release"
439ad5 # PROP Ignore_Export_Lib 0
d0b6fa # PROP Target_Dir ""
f9961c # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D ¶
7365d4 "_AFXDLL" /Yu"stdafx.h" /FD /c
9905c7 # ADD CPP /nologo /MD /W3 /WX /GX /O2 /I "..\..\..\libs\pfl\common" /I "..\..\.¶
7f3f86 .\libs\pfl\common\util" /I "..\..\..\libs\pfl\common\file" /I "..\..\..\libs\pf¶
b924f2 l\common\prefs" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pgpcdk\pub\inclu¶
a3a904 de" /I "..\..\..\libs\pgpcdk\win32" /I "..\..\pgp\shared" /I "..\..\pgp\win32\P¶
26844d GPcl" /I "Shared" /I "Encryption" /I "PGPdiskResident\Source" /D "NDEBUG" /D PG¶
e515fe P_WIN32=1 /D "WIN32" /D "_WINDOWS" /D PGP_DEBUG=0 /D "PGPDISK_MFC" /D "PGP_INTE¶
5d7b6a L" /D "_AFXDLL" /YX /FD /c
a51e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
f36d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
6db1d2 # ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
f58dc5 # ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
8718fc BSC32=bscmake.exe
627a24 # ADD BASE BSC32 /nologo
ba4f1b # ADD BSC32 /nologo
be268f LINK32=link.exe
a03a81 # ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
b742b2 # ADD LINK32 mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Release\pflCommon.lib ..¶
95f304 \..\..\libs\pgpcdk\win32\PGPcdk\Release\PGP_SDK.lib /nologo /subsystem:windows ¶
4c5e7f /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcmt.lib" /nodefaultlib¶
206a84 :"libcd.lib" /nodefaultlib:"libcmtd.lib" /nodefaultlib:"msvcrtd.lib"
dcaf5a
ecd941 !ELSEIF ·"$(CFG)" == "PGPdiskResident - Win32 Debug"
12af5a
01d693 # PROP BASE Use_MFC 6
e4ffba # PROP BASE Use_Debug_Libraries 1
d254b8 # PROP BASE Output_Dir "Debug"
--6c86 000400cea9540110062 Page 2 of PGPdiskResident.dsp
6d198a # PROP BASE Intermediate_Dir "Debug"
964c81 # PROP BASE Target_Dir ""
5a757d # PROP Use_MFC 6
fbaea9 # PROP Use_Debug_Libraries 1
8436ad # PROP Output_Dir "PGPdiskResident/Debug"
1ffc28 # PROP Intermediate_Dir "PGPdiskResident/Debug"
1e9ad5 # PROP Ignore_Export_Lib 0
64b6fa # PROP Target_Dir ""
d932c7 # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
bc4f90 DOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
5ae25a # ADD CPP /nologo /MDd /W3 /WX /Gm /GX /Zi /Od /I "..\..\..\libs\pfl\common" /I¶
030457 ·"..\..\..\libs\pfl\common\util" /I "..\..\..\libs\pfl\common\file" /I "..\..\.¶
76a76a .\libs\pfl\common\prefs" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pgpcdk\¶
f83781 pub\include" /I "..\..\..\libs\pgpcdk\win32" /I "..\..\pgp\shared" /I "..\..\pg¶
3d6474 p\win32\PGPcl" /I "Shared" /I "Encryption" /I "PGPdiskResident\Source" /D "WIN3¶
4f8552 2" /D "_DEBUG" /D "_WINDOWS" /D "DEBUG" /D PGP_DEBUG=1 /D "PGPDISK_MFC" /D "PGP¶
561735 _INTEL" /D "PGP_WIN32" /D "UNFINISHED_CODE_ALLOWED" /D "_AFXDLL" /YX /FD /c
f7c0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
5ab3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
20e84d # ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
49d45a # ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
c318fc BSC32=bscmake.exe
f67a24 # ADD BASE BSC32 /nologo
a14f1b # ADD BSC32 /nologo
c0268f LINK32=link.exe
9b267e # ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
350b0b # ADD LINK32 mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Debug\pflCommon.lib ..\.¶
bf1f1f .\..\libs\pgpcdk\win32\PGPcdk\Debug\PGP_SDK.lib /nologo /subsystem:windows /deb¶
c2be9f ug /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcmt.lib" /nodefault¶
52943e lib:"msvcrt.lib" /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib" /pdbtype¶
e1a974 :sept
a3af5a
2e30ec !ENDIF·
90af5a
9cb8a5 # Begin Target
78af5a
db4b32 # Name "PGPdiskResident - Win32 Release"
cbf495 # Name "PGPdiskResident - Win32 Debug"
594cc4 # Begin Group "Source Files"
ccaf5a
96e96f # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
081927 # Begin Group "Shared Source"
0eaf5a
ccb050 # PROP Default_Filter ""
4edf4f # Begin Source File
42af5a
e4b8e5 SOURCE=.\Shared\CommonStrings.cpp
366ccd # End Source File
69df4f # Begin Source File
23af5a
9939cf SOURCE=.\Shared\DriverComm.cpp
616ccd # End Source File
8cdf4f # Begin Source File
bdaf5a
001f6a SOURCE=.\Shared\DualErr.cpp
1d6ccd # End Source File
0fdf4f # Begin Source File
f7af5a
189dfd SOURCE=.\Shared\Errors.cpp
226ccd # End Source File
28df4f # Begin Source File
5faf5a
919c92 SOURCE=.\Shared\LinkResolution.cpp
906ccd # End Source File
5fdf4f # Begin Source File
88af5a
ecf5c7 SOURCE=.\Shared\PGPdiskPfl.cpp
906ccd # End Source File
c6df4f # Begin Source File
f2af5a
234c3f SOURCE=.\Shared\PGPdiskRegistry.cpp
406ccd # End Source File
--6bfc 000e146102840110062 Page 3 of PGPdiskResident.dsp
41df4f # Begin Source File
d0af5a
164dfb SOURCE=.\Shared\SharedMemory.cpp
396ccd # End Source File
a4df4f # Begin Source File
b2af5a
6af4cd SOURCE=.\Shared\StringAssociation.cpp
546ccd # End Source File
badf4f # Begin Source File
17af5a
495a00 SOURCE=.\Shared\Win32Utils.cpp
026ccd # End Source File
cadf4f # Begin Source File
85af5a
fb85f8 SOURCE=.\Shared\WindowsVersion.cpp
2b6ccd # End Source File
a73f5a # End Group
1ddf4f # Begin Source File
72af5a
1fbdd2 SOURCE=.\PGPdiskResident\Source\CHiddenWindow.cpp
4abca8 # ADD CPP /I ".."
d46ccd # End Source File
5ddf4f # Begin Source File
75af5a
b67e7c SOURCE=.\PGPdiskResident\Source\CPGPdiskResidentApp.cpp
386ccd # End Source File
d9df4f # Begin Source File
c0af5a
366339 SOURCE=.\PGPdiskResident\Source\StdAfx.cpp
f56ccd # End Source File
313f5a # End Group
19ba44 # Begin Group "Header Files"
3baf5a
631a9c # PROP Default_Filter "h;hpp;hxx;hm;inl"
a29155 # Begin Group "Shared Headers"
6faf5a
78b050 # PROP Default_Filter ""
4adf4f # Begin Source File
4daf5a
c66f63 SOURCE=.\Shared\CommonStrings.h
a56ccd # End Source File
52df4f # Begin Source File
cdaf5a
8deac9 SOURCE=.\Shared\DriverComm.h
936ccd # End Source File
7bdf4f # Begin Source File
f6af5a
c76ce2 SOURCE=.\Shared\DualErr.h
4d6ccd # End Source File
addf4f # Begin Source File
e2af5a
89d0e8 SOURCE=.\Shared\Errors.h
fb6ccd # End Source File
b5df4f # Begin Source File
acaf5a
8aa069 SOURCE=.\Shared\Packets.h
c46ccd # End Source File
39df4f # Begin Source File
93af5a
8ce8bc SOURCE=.\Shared\PGPdiskDefaults.h
366ccd # End Source File
dedf4f # Begin Source File
8baf5a
b735ff SOURCE=.\Shared\PGPdiskPfl.h
356ccd # End Source File
e2df4f # Begin Source File
f5af5a
17d0dc SOURCE=.\Shared\PGPdiskRegistry.h
ef6ccd # End Source File
f2df4f # Begin Source File
8caf5a
e14057 SOURCE=.\Shared\PGPdiskResidentDefines.h
--5b2e 0007f123c2040110062 Page 4 of PGPdiskResident.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
58d064 SOURCE=.\Shared\PGPdiskVersion.h
9e6ccd # End Source File
3ddf4f # Begin Source File
69af5a
3e2f73 SOURCE=.\Shared\Required.h
8f6ccd # End Source File
f3df4f # Begin Source File
40af5a
809db6 SOURCE=.\Shared\SharedMemory.h
5b6ccd # End Source File
bddf4f # Begin Source File
01af5a
be34dd SOURCE=.\Shared\StringAssociation.h
526ccd # End Source File
48df4f # Begin Source File
4daf5a
741a46 SOURCE=.\Shared\SystemConstants.h
0c6ccd # End Source File
25df4f # Begin Source File
adaf5a
587b7c SOURCE=.\Shared\UtilityFunctions.h
826ccd # End Source File
5ddf4f # Begin Source File
0faf5a
7ffef6 SOURCE=.\Shared\Win32Utils.h
696ccd # End Source File
853f5a # End Group
b8df4f # Begin Source File
90af5a
07c38c SOURCE=.\PGPdiskResident\Source\CHiddenWindow.h
dc6ccd # End Source File
61df4f # Begin Source File
99af5a
342ee2 SOURCE=.\PGPdiskResident\Source\CPGPdiskResidentApp.h
656ccd # End Source File
bbdf4f # Begin Source File
a1af5a
0014e6 SOURCE=.\PGPdiskResident\Source\Globals.h
db6ccd # End Source File
93df4f # Begin Source File
9baf5a
33529a SOURCE=.\PGPdiskResident\Source\Resource.h
846ccd # End Source File
e9df4f # Begin Source File
fdaf5a
62a1db SOURCE=.\PGPdiskResident\Source\StdAfx.h
936ccd # End Source File
b73f5a # End Group
3f8925 # Begin Group "Resource Files"
f0af5a
dfa92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
d3df4f # Begin Source File
fbaf5a
533095 SOURCE=.\PGPdiskResident\res\PGPdiskResident.ico
fa6ccd # End Source File
5ddf4f # Begin Source File
7eaf5a
0287e5 SOURCE=.\res\PGPdiskResident.ico
c76ccd # End Source File
bbdf4f # Begin Source File
8aaf5a
bbe7de SOURCE=.\res\PGPdiskResident.rc2
626ccd # End Source File
6adf4f # Begin Source File
98af5a
fa7ed8 SOURCE=.\PGPdiskResident\res\PGPdiskResidentDoc.ico
b76ccd # End Source File
78df4f # Begin Source File
7faf5a
--054d 00128ab3dee40110062 Page 5 of PGPdiskResident.dsp
508966 SOURCE=.\res\PGPdiskResidentDoc.ico
096ccd # End Source File
1c3f5a # End Group
45df4f # Begin Source File
8aaf5a
22c3a4 SOURCE=.\PGPdiskResident\PGPdiskResident.rc
776ccd # End Source File
4de5cf # End Target
28f262 # End Project
--e671 001f2d9e1e640110063 Page 1 of PGPdiskResident.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
9595d0 Project: "PGPdiskResident"=.\PGPdiskResident.dsp - Package Owner=<4>
98af5a
3ee41b Package=<5>
688818 {{{
01418b }}}
4aaf5a
e0bec7 Package=<4>
378818 {{{
38418b }}}
dfaf5a
e92d94 ###############################################################################
f2af5a
9120da Global:
daaf5a
a9e41b Package=<5>
6c8818 {{{
6e418b }}}
04af5a
1d32c2 Package=<3>
748818 {{{
9e418b }}}
4eaf5a
bb2d94 ###############################################################################
f2af5a
--b961 0007b4321ec40110064 Page 1 of PGPdiskShellExt.dsp
42a17b # Microsoft Developer Studio Project File - Name="PGPdiskShellExt" - Package Ow¶
e66f39 ner=<4>
8de7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
c68537 # ** DO NOT EDIT **
88af5a
8fa99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
6baf5a
c68220 CFG=PGPdiskShellExt - Win32 Release
dd894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
b65c35 !MESSAGE use the Export Makefile command and run
986309 !MESSAGE·
764a78 !MESSAGE NMAKE /f "PGPdiskShellExt.mak".
fa6309 !MESSAGE·
09cdb3 !MESSAGE You can specify a configuration when running NMAKE
8de013 !MESSAGE by defining the macro CFG on the command line. For example:
3d6309 !MESSAGE·
824db5 !MESSAGE NMAKE /f "PGPdiskShellExt.mak" CFG="PGPdiskShellExt - Win32 Release"
166309 !MESSAGE·
051dd7 !MESSAGE Possible choices for configuration are:
196309 !MESSAGE·
a63167 !MESSAGE "PGPdiskShellExt - Win32 Release" (based on\
d617ca ·"Win32 (x86) Dynamic-Link Library")
525ade !MESSAGE "PGPdiskShellExt - Win32 Debug" (based on\
b917ca ·"Win32 (x86) Dynamic-Link Library")
8f6309 !MESSAGE·
71af5a
433e63 # Begin Project
79b23f # PROP Scc_ProjName ""
25df4a # PROP Scc_LocalPath ""
d740a4 CPP=cl.exe
7fa46a MTL=midl.exe
c92e1f RSC=rc.exe
10af5a
007db8 !IF ·"$(CFG)" == "PGPdiskShellExt - Win32 Release"
aeaf5a
be8243 # PROP BASE Use_MFC 0
bce662 # PROP BASE Use_Debug_Libraries 0
2e4681 # PROP BASE Output_Dir ".\Release"
7dca0c # PROP BASE Intermediate_Dir ".\Release"
014c81 # PROP BASE Target_Dir ""
8a3875 # PROP Use_MFC 1
4eb771 # PROP Use_Debug_Libraries 0
ed1089 # PROP Output_Dir "PGPdiskShellExt\Release"
278bab # PROP Intermediate_Dir "PGPdiskShellExt\Release"
5d9ad5 # PROP Ignore_Export_Lib 0
5db6fa # PROP Target_Dir ""
57c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
db9f26 ·/c
a04670 # ADD CPP /nologo /MT /W3 /WX /GX /O2 /I "..\..\..\libs\pfl\common" /I "..\..\.¶
b03f86 .\libs\pfl\common\util" /I "..\..\..\libs\pfl\common\file" /I "..\..\..\libs\pf¶
3e24f2 l\common\prefs" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pgpcdk\pub\inclu¶
0ca904 de" /I "..\..\..\libs\pgpcdk\win32" /I "..\..\pgp\shared" /I "..\..\pgp\win32\P¶
a3f1b0 GPcl" /I "Shared" /I "Encryption" /I "PGPdiskShellExt\Source" /D "NDEBUG" /D PG¶
4d15fe P_WIN32=1 /D "WIN32" /D "_WINDOWS" /D PGP_DEBUG=0 /D "PGPDISK_MFC" /D "PGP_INTE¶
0b19da L" /D "_USRDLL" /D "_WINDLL" /YX /FD /c
56592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
d7a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
e5b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
d3de84 # ADD RSC /l 0x409 /d "NDEBUG"
db18fc BSC32=bscmake.exe
087a24 # ADD BASE BSC32 /nologo
984f1b # ADD BSC32 /nologo
9d268f LINK32=link.exe
10cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
27a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
575e3b ·/nologo /subsystem:windows /dll /machine:I386
bc42b2 # ADD LINK32 mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Release\pflCommon.lib ..¶
12f304 \..\..\libs\pgpcdk\win32\PGPcdk\Release\PGP_SDK.lib /nologo /subsystem:windows ¶
4518c7 /dll /map /machine:I386 /out:"PGPdiskShellExt\Release\PGPdskSE.dll"
1baf5a
f254a6 !ELSEIF ·"$(CFG)" == "PGPdiskShellExt - Win32 Debug"
7baf5a
--a771 00052bb80fe40110064 Page 2 of PGPdiskShellExt.dsp
dd8243 # PROP BASE Use_MFC 0
03ffba # PROP BASE Use_Debug_Libraries 1
49cc98 # PROP BASE Output_Dir ".\Debug"
ead06b # PROP BASE Intermediate_Dir ".\Debug"
704c81 # PROP BASE Target_Dir ""
8f3875 # PROP Use_MFC 1
7faea9 # PROP Use_Debug_Libraries 1
f192b0 # PROP Output_Dir "PGPdiskShellExt\Debug"
af5835 # PROP Intermediate_Dir "PGPdiskShellExt\Debug"
d89ad5 # PROP Ignore_Export_Lib 0
1eb6fa # PROP Target_Dir ""
586cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
2b8dcb DOWS" /YX /c
71a1ed # ADD CPP /nologo /MTd /W3 /WX /Gm /GX /Zi /Od /I "..\..\..\libs\pfl\common" /I¶
af0457 ·"..\..\..\libs\pfl\common\util" /I "..\..\..\libs\pfl\common\file" /I "..\..\.¶
f7a76a .\libs\pfl\common\prefs" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pgpcdk\¶
133781 pub\include" /I "..\..\..\libs\pgpcdk\win32" /I "..\..\pgp\shared" /I "..\..\pg¶
229a59 p\win32\PGPcl" /I "Shared" /I "Encryption" /I "PGPdiskShellExt\Source" /D "_DEB¶
02f21d UG" /D "WIN32" /D "_WINDOWS" /D PGP_WIN32=1 /D PGP_DEBUG=1 /D "PGPDISK_MFC" /D ¶
016322 "PGP_INTEL" /D "UNFINISHED_CODE_ALLOWED" /D "_USRDLL" /D "_WINDLL" /YX /FD /c
06b3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
33ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
4d699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
8e0443 # ADD RSC /l 0x409 /d "_DEBUG"
ca18fc BSC32=bscmake.exe
9c7a24 # ADD BASE BSC32 /nologo
234f1b # ADD BSC32 /nologo
56268f LINK32=link.exe
18cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
dba5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
cdc590 ·/nologo /subsystem:windows /dll /debug /machine:I386
250b0b # ADD LINK32 mpr.lib ..\..\..\libs\pfl\win32\pflCommon\Debug\pflCommon.lib ..\.¶
a3f667 .\..\libs\pgpcdk\win32\PGPcdk\Debug\PGP_SDK.lib /nologo /subsystem:windows /dll¶
e278b4 ·/incremental:no /debug /machine:I386 /out:"PGPdiskShellExt\Debug\PGPdskSE.dll"
1a84a1 # SUBTRACT LINK32 /pdb:none
3caf5a
7d30ec !ENDIF·
c8af5a
3db8a5 # Begin Target
3baf5a
34b04e # Name "PGPdiskShellExt - Win32 Release"
527972 # Name "PGPdiskShellExt - Win32 Debug"
104cc4 # Begin Group "Source Files"
abaf5a
fb7b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
cd1927 # Begin Group "Shared Source"
a7af5a
ebb050 # PROP Default_Filter ""
badf4f # Begin Source File
3baf5a
60b8e5 SOURCE=.\Shared\CommonStrings.cpp
2e6ccd # End Source File
dedf4f # Begin Source File
1baf5a
7f39cf SOURCE=.\Shared\DriverComm.cpp
b66ccd # End Source File
0adf4f # Begin Source File
acaf5a
571f6a SOURCE=.\Shared\DualErr.cpp
e16ccd # End Source File
68df4f # Begin Source File
29af5a
949dfd SOURCE=.\Shared\Errors.cpp
b06ccd # End Source File
b7df4f # Begin Source File
80af5a
2e9c92 SOURCE=.\Shared\LinkResolution.cpp
266ccd # End Source File
50df4f # Begin Source File
9caf5a
5ff5c7 SOURCE=.\Shared\PGPdiskPfl.cpp
526ccd # End Source File
--8b3b 00035a7038940110064 Page 3 of PGPdiskShellExt.dsp
41df4f # Begin Source File
d0af5a
284c3f SOURCE=.\Shared\PGPdiskRegistry.cpp
576ccd # End Source File
6ddf4f # Begin Source File
d9af5a
f7f4cd SOURCE=.\Shared\StringAssociation.cpp
b36ccd # End Source File
79df4f # Begin Source File
6faf5a
755a00 SOURCE=.\Shared\Win32Utils.cpp
556ccd # End Source File
14df4f # Begin Source File
e2af5a
8685f8 SOURCE=.\Shared\WindowsVersion.cpp
456ccd # End Source File
5d3f5a # End Group
48df4f # Begin Source File
c0af5a
207d7f SOURCE=.\PGPdiskShellExt\Source\CPGPdiskShellExtDll.cpp
726ccd # End Source File
26df4f # Begin Source File
f0af5a
b10898 SOURCE=.\PGPdiskShellExt\Source\CShellExt.cpp
116ccd # End Source File
8edf4f # Begin Source File
51af5a
e8748f SOURCE=.\PGPdiskShellExt\Source\CShellExtClassFactory.cpp
8c6ccd # End Source File
e7df4f # Begin Source File
99af5a
bcda29 SOURCE=.\PGPdiskShellExt\Source\StdAfx.cpp
e36ccd # End Source File
723f5a # End Group
82ba44 # Begin Group "Header Files"
5eaf5a
93561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
2d9155 # Begin Group "Shared Headers"
f1af5a
91b050 # PROP Default_Filter ""
d0df4f # Begin Source File
abaf5a
df6f63 SOURCE=.\Shared\CommonStrings.h
556ccd # End Source File
9cdf4f # Begin Source File
f0af5a
a8eac9 SOURCE=.\Shared\DriverComm.h
016ccd # End Source File
fedf4f # Begin Source File
94af5a
ab6ce2 SOURCE=.\Shared\DualErr.h
a46ccd # End Source File
97df4f # Begin Source File
93af5a
a2d0e8 SOURCE=.\Shared\Errors.h
4e6ccd # End Source File
1ddf4f # Begin Source File
e8af5a
d3a069 SOURCE=.\Shared\Packets.h
1e6ccd # End Source File
23df4f # Begin Source File
90af5a
f7e8bc SOURCE=.\Shared\PGPdiskDefaults.h
8e6ccd # End Source File
2bdf4f # Begin Source File
44af5a
b235ff SOURCE=.\Shared\PGPdiskPfl.h
796ccd # End Source File
10df4f # Begin Source File
c5af5a
80d0dc SOURCE=.\Shared\PGPdiskRegistry.h
356ccd # End Source File
--576b 00186a0247840110064 Page 4 of PGPdiskShellExt.dsp
41df4f # Begin Source File
d0af5a
b2d064 SOURCE=.\Shared\PGPdiskVersion.h
9c6ccd # End Source File
29df4f # Begin Source File
87af5a
712f73 SOURCE=.\Shared\Required.h
286ccd # End Source File
82df4f # Begin Source File
63af5a
4034dd SOURCE=.\Shared\StringAssociation.h
336ccd # End Source File
c4df4f # Begin Source File
25af5a
521a46 SOURCE=.\Shared\SystemConstants.h
6d6ccd # End Source File
a6df4f # Begin Source File
69af5a
ac7b7c SOURCE=.\Shared\UtilityFunctions.h
456ccd # End Source File
9bdf4f # Begin Source File
e7af5a
37fef6 SOURCE=.\Shared\Win32Utils.h
9b6ccd # End Source File
413f5a # End Group
c1df4f # Begin Source File
20af5a
e5c449 SOURCE=.\PGPdiskShellExt\Source\CPGPdiskShellExtDll.h
f36ccd # End Source File
f0df4f # Begin Source File
50af5a
86473b SOURCE=.\PGPdiskShellExt\Source\CShellExt.h
7c6ccd # End Source File
f3df4f # Begin Source File
e7af5a
92be24 SOURCE=.\PGPdiskShellExt\Source\CShellExtClassFactory.h
b56ccd # End Source File
77df4f # Begin Source File
14af5a
60ef9a SOURCE=.\PGPdiskShellExt\Source\Globals.h
dc6ccd # End Source File
62df4f # Begin Source File
e7af5a
12eb8a SOURCE=.\PGPdiskShellExt\Source\Resource.h
f96ccd # End Source File
4edf4f # Begin Source File
22af5a
1832e7 SOURCE=.\PGPdiskShellExt\Source\StdAfx.h
e06ccd # End Source File
973f5a # End Group
458925 # Begin Group "Resource Files"
3caf5a
daa92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
2d3f5a # End Group
55df4f # Begin Source File
feaf5a
5dd0ae SOURCE=.\PGPdiskShellExt\PGPdiskShellExt.def
c16ccd # End Source File
48df4f # Begin Source File
20af5a
91bd4a SOURCE=.\PGPdiskShellExt\PGPdiskShellExt.rc
986ccd # End Source File
f5e5cf # End Target
86f262 # End Project
--ff92 001e19763df40110065 Page 1 of PGPdiskShellExt.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
0462b4 Project: "PGPdiskShellExt"=.\PGPdiskShellExt.dsp - Package Owner=<4>
f5af5a
9fe41b Package=<5>
908818 {{{
74418b }}}
3caf5a
f0bec7 Package=<4>
bc8818 {{{
af418b }}}
a5af5a
eb2d94 ###############################################################################
2faf5a
9620da Global:
93af5a
c3e41b Package=<5>
b78818 {{{
19418b }}}
d0af5a
1732c2 Package=<3>
2b8818 {{{
b6418b }}}
9baf5a
992d94 ###############################################################################
e1af5a

--6429 0005c25441740110066 Page 1 of Cast5.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
6075f2 // Cast5.cpp
e6465d //
37630c // Functions for implementing the CAST5 cipher.
081bc3 //////////////////////////////////////////////////////////////////////////////
b6af5a
b70a89 // $Id: Cast5.cpp,v 1.1.2.11 1998/07/06 08:56:32 nryan Exp $
89af5a
697758 // Portions Copyright (C) 1998 by Network Associates, Inc.
1271ae // All rights reserved.
74af5a
826931 #if defined(PGPDISK_MFC)
ebaf5a
c29e12 #include "StdAfx.h"
04af5a
f34268 #elif defined(PGPDISK_95DRIVER)
c7af5a
7006a9 #include <vtoolscp.h>
2586d2 #include LOCKED_CODE_SEGMENT
f55269 #include LOCKED_DATA_SEGMENT
c5af5a
95f5a6 #elif defined(PGPDISK_NTDRIVER)
1caf5a
20d7a1 #include <vdw.h>
f4feb2 #include <stdio.h>
1ebea3 #include <stdlib.h>
dfaf5a
c6db21 #else
ec112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
4005d6 #endif¤ // PGPDISK_MFC
b7af5a
f89bcf #include "Required.h"
af69ea #include "Cast5.h"
a9797b #include "Cast5Box.h"
508f51 #include "CipherUtils.h"
ffaf5a
e7af5a
63d43e /////////
96596b // Macros
4fd43e /////////
a9af5a
8844d8 #define ROL(x,r) ((x)<<(r) | (x)>>(32-(r)))
82af5a
834b22 #define B0(x) ((x) >> 24 & 255)
172d78 #define B1(x) ((x) >> 16 & 255)
c50798 #define B2(x) ((x) >> 8 & 255)
b54e6f #define B3(x) ((x) & 255)
3eaf5a
74c62a #define F1(x,xkey,i) (ROL((xkey)[2*(i)] + (x), (xkey)[2*(i)+1]))
c2c599 #define F2(x,xkey,i) (ROL((xkey)[2*(i)] ^ (x), (xkey)[2*(i)+1]))
9250f6 #define F3(x,xkey,i) (ROL((xkey)[2*(i)] - (x), (xkey)[2*(i)+1]))
eeaf5a
2f08e5 #define G1(x) (((S1[B0(x)] ^ S2[B1(x)]) - S3[B2(x)]) + S4[B3(x)])
b03005 #define G2(x) (((S1[B0(x)] - S2[B1(x)]) + S3[B2(x)]) ^ S4[B3(x)])
e52000 #define G3(x) (((S1[B0(x)] + S2[B1(x)]) ^ S3[B2(x)]) - S4[B3(x)])
08af5a
8828db #define x0 B0(x0123)
7be073 #define x1 B1(x0123)
72b19a #define x2 B2(x0123)
707932 #define x3 B3(x0123)
ca019c #define x4 B0(x4567)
d2c934 #define x5 B1(x4567)
5798dd #define x6 B2(x4567)
3b5075 #define x7 B3(x4567)
05fcc3 #define x8 B0(x89AB)
b6346b #define x9 B1(x89AB)
5c8188 #define xA B2(x89AB)
ed4b9b #define xB B3(x89AB)
3b88e7 #define xC B0(xCDEF)
d34782 #define xD B1(xCDEF)
2814d0 #define xE B2(xCDEF)
5cdec3 #define xF B3(xCDEF)
--0c5f 000334c7fe440110066 Page 2 of Cast5.cpp
02143a #define z0 B0(z0123)
57dc92 #define z1 B1(z0123)
d78d7b #define z2 B2(z0123)
0345d3 #define z3 B3(z0123)
563d7d #define z4 B0(z4567)
8df5d5 #define z5 B1(z4567)
b2a43c #define z6 B2(z4567)
b06c94 #define z7 B3(z4567)
89c022 #define z8 B0(z89AB)
ed088a #define z9 B1(z89AB)
cdbd69 #define zA B2(z89AB)
0c777a #define zB B3(z89AB)
47b406 #define zC B0(zCDEF)
e57b63 #define zD B1(zCDEF)
822831 #define zE B2(zCDEF)
75e222 #define zF B3(zCDEF)
2baf5a
c3af5a
cf9f73 /////////////////////////
72a4b1 // CAST5 Cipher Functions
779f73 /////////////////////////
efaf5a
eab1f4 // This expands a 128-bit key to a 32-word scheduled key, where each round
91ecaf // uses two words: a 32-bit XOR mask and a 5-bit rotate amount. ·Shorter keys
0e6120 // are just padded with zeros, and if they are 80 bits or less, the cipher
691e2e // is reduced to 12 rounds (not implemented here).
9d465d //
082d09 // The feed-forward used with x0123 through yCDEF prevent any weak keys,
306548 // and the substitution to set up the xkey tables ensure that the subround
931c4b // keys are not easily derivable from each other, so linear cryptanalysis
6c503b // won't do very well against CAST.
d5af5a
b4c823 void·
edfa9b CAST5schedule(PGPUInt32 xkey[32], const PGPUInt8 *k)
46bb36 {
95710d ¤   PGPUInt32¤  x0123, x4567, x89AB, xCDEF;
fa4197 ¤   PGPUInt32¤  z0123, z4567, z89AB, zCDEF;
87af5a
43e0e7 ¤   // Initialize x0123456789ABCDEF with input key
88d519 ¤   x0123¤  = (PGPUInt32) k[0]<<24 | (PGPUInt32) k[1]<<16 |·
e895df ¤   ¤   (PGPUInt32) k[2]<<8 | k[3];
0eaf5a
1c1b28 ¤   x4567¤  = (PGPUInt32) k[4]<<24 | (PGPUInt32) k[5]<<16 |·
d5148a ¤   ¤   (PGPUInt32) k[6]<<8 | k[7];
8daf5a
85bed9 ¤   x89AB¤  = (PGPUInt32) k[8]<<24 | (PGPUInt32) k[9]<<16 |·
4a7b3e ¤   ¤   (PGPUInt32) k[10]<<8 | k[11];
83af5a
187879 ¤   xCDEF¤  = (PGPUInt32) k[12]<<24 | (PGPUInt32) k[13]<<16 |·
73216b ¤   ¤   (PGPUInt32) k[14]<<8 | k[15];
edaf5a
8ecfe4 ¤   // Now set up the key table
113f2d ¤   for (PGPUInt8 i=0; i<4; i++)·
b0c7a1 ¤   {
e23ebe ¤   ¤   z0123¤  = x0123 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
e3d051 ¤   ¤   z4567¤  = x89AB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
c2a7c8 ¤   ¤   z89AB¤  = xCDEF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
c7c815 ¤   ¤   zCDEF¤  = x4567 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
60b095 ¤   ¤   x0123¤  = z89AB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
b1a1f0 ¤   ¤   x4567¤  = z0123 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
01c57a ¤   ¤   x89AB¤  = z4567 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
d90981 ¤   ¤   xCDEF¤  = zCDEF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
08af5a
bd17f9 ¤   ¤   switch (i)
605b34 ¤   ¤   {
9bc69c ¤   ¤   case 0:¤¤   ¤   // Masking keys, rounds 0..7
70d144 ¤   ¤   ¤   xkey[0]¤¤   = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2];
4ddb67 ¤   ¤   ¤   xkey[2]¤¤   = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6];
721fde ¤   ¤   ¤   xkey[4]¤¤   = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9];
90f702 ¤   ¤   ¤   xkey[6]¤¤   = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC];
8587c7 ¤   ¤   ¤
33704c ¤   ¤   ¤   xkey[8]¤¤   = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8];
--3909 00068dcad2d40110066 Page 3 of Cast5.cpp
443f43 ¤   ¤   ¤   xkey[10]¤   = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD];
6275c8 ¤   ¤   ¤   xkey[12]¤   = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3];
98a69a ¤   ¤   ¤   xkey[14]¤   = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7];
67cdcb ¤   ¤   ¤   break;
48af5a
be4f21 ¤   ¤   ·case 1:¤   ¤   ¤   // Masking keys, rounds 8..15
ca1fb4 ¤   ¤   ¤   xkey[16]¤   = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9];
a2a4e5 ¤   ¤   ¤   xkey[18]¤   = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC];
23f9a7 ¤   ¤   ¤   xkey[20]¤   = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2];
4bdd6c ¤   ¤   ¤   xkey[22]¤   = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6];
3087c7 ¤   ¤   ¤
2b16b2 ¤   ¤   ¤   xkey[24]¤   = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3];
6f6382 ¤   ¤   ¤   xkey[26]¤   = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7];
86c12d ¤   ¤   ¤   xkey[28]¤   = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8];
34c1fc ¤   ¤   ¤   xkey[30]¤   = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD];
64cdcb ¤   ¤   ¤   break;
9eaf5a
894117 ¤   ¤   ·case 2:¤   ¤   ¤   // Rotation keys, rounds 0..7
79bd69 ¤   ¤   ¤   xkey[1]¤¤   = (S5[z8]^S6[z9]^S7[z7]^S8[z6]^S5[z2]) & 31;
719e56 ¤   ¤   ¤   xkey[3]¤¤   = (S5[zA]^S6[zB]^S7[z5]^S8[z4]^S6[z6]) & 31;
4e5eca ¤   ¤   ¤   xkey[5]¤¤   = (S5[zC]^S6[zD]^S7[z3]^S8[z2]^S7[z9]) & 31;
8778b2 ¤   ¤   ¤   xkey[7]¤¤   = (S5[zE]^S6[zF]^S7[z1]^S8[z0]^S8[zC]) & 31;
d687c7 ¤   ¤   ¤
ff2e09 ¤   ¤   ¤   xkey[9]¤¤   = (S5[x3]^S6[x2]^S7[xC]^S8[xD]^S5[x8]) & 31;
b0af94 ¤   ¤   ¤   xkey[11]¤   = (S5[x1]^S6[x0]^S7[xE]^S8[xF]^S6[xD]) & 31;
9cd0dc ¤   ¤   ¤   xkey[13]¤   = (S5[x7]^S6[x6]^S7[x8]^S8[x9]^S7[x3]) & 31;
fa40cb ¤   ¤   ¤   xkey[15]¤   = (S5[x5]^S6[x4]^S7[xA]^S8[xB]^S8[x7]) & 31;
b8cdcb ¤   ¤   ¤   break;
2baf5a
3ea2c5 ¤   ¤   ··case 3:¤  ¤   ¤   // Rotation keys, rounds 8..15
9d6b99 ¤   ¤   ¤   xkey[17]¤   = (S5[z3]^S6[z2]^S7[zC]^S8[zD]^S5[z9]) & 31;
346792 ¤   ¤   ¤   xkey[19]¤   = (S5[z1]^S6[z0]^S7[zE]^S8[zF]^S6[zC]) & 31;
4956b6 ¤   ¤   ¤   xkey[21]¤   = (S5[z7]^S6[z6]^S7[z8]^S8[z9]^S7[z2]) & 31;
43d051 ¤   ¤   ¤   xkey[23]¤   = (S5[z5]^S6[z4]^S7[zA]^S8[zB]^S8[z6]) & 31;
441b52 ¤   ¤
589484 ¤   ¤   ¤   xkey[25]¤   = (S5[x8]^S6[x9]^S7[x7]^S8[x6]^S5[x3]) & 31;
964307 ¤   ¤   ¤   xkey[27]¤   = (S5[xA]^S6[xB]^S7[x5]^S8[x4]^S6[x7]) & 31;
9abbae ¤   ¤   ¤   xkey[29]¤   = (S5[xC]^S6[xD]^S7[x3]^S8[x2]^S7[x8]) & 31;
f5d8c2 ¤   ¤   ¤   xkey[31]¤   = (S5[xE]^S6[xF]^S7[x1]^S8[x0]^S8[xD]) & 31;
a5cdcb ¤   ¤   ¤   break;
750fe4 ¤   ¤   }
cd9371 ¤   }
a4af5a
6e8751 ¤   x0123 = x4567 = x89AB = xCDEF = 0;
99bc12 ¤   z0123 = z4567 = z89AB = zCDEF = 0;
a2efe6 }
44af5a
f92c99 // CAST5encrypt encrypts a block using the CAST5 cipher.
d4af5a
9ec823 void·
9e58e4 CAST5encrypt(const PGPUInt8 *in, PGPUInt8 *out, const PGPUInt32 *xkey)
01bb36 {
d1fb87 ¤   PGPUInt32 l, r, t;
afaf5a
e9afdd ¤   l = (PGPUInt32) (in[0]<<24) | (PGPUInt32) (in[1]<<16) |·
902cab ¤   ¤   (PGPUInt32) (in[2]<<8) | in[3];
114f13 ¤   r = (PGPUInt32) (in[4]<<24) | (PGPUInt32) (in[5]<<16) |·
947625 ¤   ¤   (PGPUInt32) (in[6]<<8) | in[7];
52af5a
5ffe6a ¤   t = F1(r, xkey, ·0); l ^= G1(t);
c26e25 ¤   t = F2(l, xkey, ·1); r ^= G2(t);
cc7620 ¤   t = F3(r, xkey, ·2); l ^= G3(t);
802c5a ¤   t = F1(l, xkey, ·3); r ^= G1(t);
868046 ¤   t = F2(r, xkey, ·4); l ^= G2(t);
1f8c72 ¤   t = F3(l, xkey, ·5); r ^= G3(t);
b6c239 ¤   t = F1(r, xkey, ·6); l ^= G1(t);
765276 ¤   t = F2(l, xkey, ·7); r ^= G2(t);
f932d5 ¤   t = F3(r, xkey, ·8); l ^= G3(t);
4968af ¤   t = F1(l, xkey, ·9); r ^= G1(t);
fd8f0e ¤   t = F2(r, xkey, 10); l ^= G2(t);
f5833a ¤   t = F3(l, xkey, 11); r ^= G3(t);
68f606 ¤   // Stop here if only doing 12 rounds
--b93a 0001849ce6840110066 Page 4 of Cast5.cpp
aecd71 ¤   t = F1(r, xkey, 12); l ^= G1(t);
0e5d3e ¤   t = F2(l, xkey, 13); r ^= G2(t);
586d59 ¤   t = F3(r, xkey, 14); l ^= G3(t);
a53723 ¤   t = F1(l, xkey, 15); r ^= G1(t);
80af5a
8a87ca ¤   out[0]¤ = (PGPUInt8) B0(r);
f7d8a5 ¤   out[1]¤ = (PGPUInt8) B1(r);
213914 ¤   out[2]¤ = (PGPUInt8) B2(r);
f8667b ¤   out[3]¤ = (PGPUInt8) B3(r);
538f28 ¤   out[4]¤ = (PGPUInt8) B0(l);
eed047 ¤   out[5]¤ = (PGPUInt8) B1(l);
b931f6 ¤   out[6]¤ = (PGPUInt8) B2(l);
466e99 ¤   out[7]¤ = (PGPUInt8) B3(l);
e1efe6 }
d1af5a
17a13c // CAST5decrypt decrypts a block using the CAST5 cipher.
30af5a
a0c823 void·
d09165 CAST5decrypt(const PGPUInt8 *in, PGPUInt8 *out, const PGPUInt32 *xkey)
64bb36 {
5dfb87 ¤   PGPUInt32 l, r, t;
b2af5a
1de818 ¤   r = (PGPUInt32) (in[0]<<24) | (PGPUInt32) (in[1]<<16) |·
ff2cab ¤   ¤   (PGPUInt32) (in[2]<<8) | in[3];
42af5a
e808d6 ¤   l = (PGPUInt32) (in[4]<<24) | (PGPUInt32) (in[5]<<16) |·
be7625 ¤   ¤   (PGPUInt32) (in[6]<<8) | in[7];
daaf5a
b03723 ¤   t = F1(l, xkey, 15); r ^= G1(t);
5b6d59 ¤   t = F3(r, xkey, 14); l ^= G3(t);
515d3e ¤   t = F2(l, xkey, 13); r ^= G2(t);
99cd71 ¤   t = F1(r, xkey, 12); l ^= G1(t);
2add9a ¤   // Start here if only doing 12 rounds
d3833a ¤   t = F3(l, xkey, 11); r ^= G3(t);
c98f0e ¤   t = F2(r, xkey, 10); l ^= G2(t);
8c68af ¤   t = F1(l, xkey, ·9); r ^= G1(t);
6a32d5 ¤   t = F3(r, xkey, ·8); l ^= G3(t);
485276 ¤   t = F2(l, xkey, ·7); r ^= G2(t);
1ec239 ¤   t = F1(r, xkey, ·6); l ^= G1(t);
ed8c72 ¤   t = F3(l, xkey, ·5); r ^= G3(t);
038046 ¤   t = F2(r, xkey, ·4); l ^= G2(t);
462c5a ¤   t = F1(l, xkey, ·3); r ^= G1(t);
057620 ¤   t = F3(r, xkey, ·2); l ^= G3(t);
f16e25 ¤   t = F2(l, xkey, ·1); r ^= G2(t);
e6fe6a ¤   t = F1(r, xkey, ·0); l ^= G1(t);
6caf5a
edea29 ¤   out[0]¤ = (PGPUInt8) B0(l);
bab546 ¤   out[1]¤ = (PGPUInt8) B1(l);
c054f7 ¤   out[2]¤ = (PGPUInt8) B2(l);
710b98 ¤   out[3]¤ = (PGPUInt8) B3(l);
a7e2cb ¤   out[4]¤ = (PGPUInt8) B0(r);
3cbda4 ¤   out[5]¤ = (PGPUInt8) B1(r);
9b5c15 ¤   out[6]¤ = (PGPUInt8) B2(r);
ed037a ¤   out[7]¤ = (PGPUInt8) B3(r);
31efe6 }
32af5a
61aa80 // CAST5encryptCFBdbl encrypts the specified number of blocks in CFB mode.
f2af5a
19c823 void·
3d8995 CAST5encryptCFBdbl(
b1e620 ¤   const PGPUInt32*¤   xkey,·
d54e27 ¤   PGPUInt32¤  ¤   ¤   iv0,·
fd529c ¤   PGPUInt32¤  ¤   ¤   iv1,·
ff7751 ¤   PGPUInt32¤  ¤   ¤   iv2,·
7c6bea ¤   PGPUInt32¤  ¤   ¤   iv3,·
f58ca5 ¤   const PGPUInt32*¤   src,·
cb2ac6 ¤   PGPUInt32*¤ ¤   ¤   dest,·
0f0090 ¤   PGPUInt32¤  ¤   ¤   len)
41bb36 {
2dfdda ¤   PGPUInt32 iv[4] = {iv0, iv1, iv2, iv3};
adbf5d ¤   while (len--)·
18c7a1 ¤   {
--d504 000efc2a7ca40110066 Page 5 of Cast5.cpp
e60140 ¤   ¤   CAST5encrypt((const PGPUInt8*) iv, (PGPUInt8*) iv, xkey);
8af511 ¤   ¤   *dest++¤= iv[0]¤^= *src++;
558bfb ¤   ¤   *dest++¤= iv[1]¤^= *src++;
2baf5a
941346 ¤   ¤   CAST5encrypt((const PGPUInt8*) (iv+2), (PGPUInt8*) (iv+2), xkey);
db08c5 ¤   ¤   *dest++¤= iv[2]¤^= *src++;
27762f ¤   ¤   *dest++¤= iv[3]¤^= *src++;
6e9371 ¤   }
43efe6 }
9aaf5a
ab9cae // CAST5decryptCFBdbl decrypts the specified number of blocks in CFB mode.
41af5a
11c823 void·
26ade2 CAST5decryptCFBdbl(
62e620 ¤   const PGPUInt32*¤   xkey,·
794e27 ¤   PGPUInt32¤  ¤   ¤   iv0,·
05529c ¤   PGPUInt32¤  ¤   ¤   iv1,·
247751 ¤   PGPUInt32¤  ¤   ¤   iv2,·
1f6bea ¤   PGPUInt32¤  ¤   ¤   iv3,·
348ca5 ¤   const PGPUInt32*¤   src,·
e82ac6 ¤   PGPUInt32*¤ ¤   ¤   dest,·
700090 ¤   PGPUInt32¤  ¤   ¤   len)
a8bb36 {
2bead9 ¤   PGPUInt32¤  iv[4]¤  = {iv0, iv1, iv2, iv3};
00119d ¤   PGPUInt32¤  out[4];
cee87e ¤   while (len--)
7cc7a1 ¤   {
a8000f ¤   ¤   CAST5encrypt((const PGPUInt8*) iv, (PGPUInt8*) out, xkey);
5329e9 ¤   ¤   *dest++¤= out[0] ^ (iv[0] = *src++);
73deca ¤   ¤   *dest++¤= out[1] ^ (iv[1] = *src++);
68af5a
0574aa ¤   ¤   CAST5encrypt((const PGPUInt8*) (iv+2), (PGPUInt8*) (out+2), xkey);
1fcfbe ¤   ¤   *dest++¤= out[2] ^ (iv[2] = *src++);
77389d ¤   ¤   *dest++¤= out[3] ^ (iv[3] = *src++);
3d9371 ¤   }
3eefe6 }
fdaf5a
5faf5a
f6b352 //////////////////////////
ddf7f5 // CAST Assembly Functions
21b352 //////////////////////////
c4af5a
c8cf41 #if defined(PGP_INTEL)
51af5a
51cdb6 #define¤NAKED¤  __declspec(naked)
f5af5a
3f2414 /* NOTE: This expects the rotate amounts to be pre-incremented by 16! */
bcaf5a
9538e5 /*
d4a201 ·* high-speed x86 CAST implementation. ·Optimized for Intel P5 and P6.
abc5f3 ·* (Pentium, PPro, Pentium II).
24775e ·*
9a8c71 ·* The pentium is a fairly straightforward dual-issue machine with a
ad8ab6 ·* number of issue restrictions (but the only false hazard that causes
2612bb ·* a stall is WAW). ·The one significant pipeline hazard is that while
1da60f ·* loads are complete the cycle after they execute, they require that
e82140 ·* the address be available the cycle before they execute. ·One notable
b0edd2 ·* point is that the Pentium can execute two loads in parallel, as long
21935d ·* as they hit in different banks of its 8-way-interleaved L1 cache.
8f775e ·*
0f3a27 ·* The PPro is an out-of-order superscalar system which can dispatch 3
9e3298 ·* instructions per cycle (subject to significant limitations) and has
aed6e2 ·* two integer and one load/store unit. ·After decoding x86 instructions
6bb69f ·* to a series of R-ops, it's pretty straightforward out-of-order engine,
f5ef86 ·* executing instructions as their operands become available (register
96466a ·* renaming ensures that false sharing doesn't block issue) except for
17b217 ·* one thing. ·The P6 is prone to an evil thing called a "partial register
110fa2 ·* stall", when you write to a partial register and read a larger part.
7214e3 ·* this overlap is resolved by retiring the partial write before the
870600 ·* next instruction can be dispatched. ·This amounts to a *long* time.
71775e ·*
ef2f80 ·* Unfortunately, precisely this operation is the best way to extract the
--2fd0 000c5263eb340110066 Page 6 of Cast5.cpp
786f14 ·* bytes from the words in the CAST S-box lookup, so it's very important
fee8ea ·* for an efficient CAST implementation.
e3f959 ·* Fortunately, the processor has an exception built in. ·The
942ba8 ·* instructions "xor reg,reg" and "sub reg,reg" sets a magic "clear"
d8a426 ·* flag on the register, following which the merge of the high zero
02c144 ·* bits causes no delay.
4ee2b5 ·* The only problem is that a context switch or interrupt will save
cb8d0a ·* and restore the register, and a mov does *not* set the flag.
f5607e ·* Thus, you should explicitly re-clear the register occasionally,
6eb138 ·* so that the stall won't happen.
dc775e ·*
84a735 ·* Each block encrypted seems like a good value for "occasionally".
84775e ·*
bd8ca0 ·* Also, loop labels whould not be within 7 bytes of a 16-byte boundary.
39495d ·*/
c9af5a
2c38e5 /*
99723c ·* Do round n from x into y, with op1/op2/op3
d475b2 ·* This also loads in the next round's keys into
a3bdb2 ·* eax and ecx.
45775e ·*
e00bfe ·* The minimum length dependency chain is 9 cycles for
d9ef3a ·* a round, but achieving that would require issuing
9e017a ·* three instructions per cycle - perhaps the PPro can
f3eba2 ·* manage that. ·Issuing two instructions per cycle,
052c7e ·* a round can be done in 10 cycles. ·Unfortunately,
594a1a ·* the processor does not have enough register to use more
c6dab3 ·* parallelism than that.
b5775e ·*
635136 ·* Dependency chain:
e8521a ·* op3 x,%eax/xor %edx,%edx
794547 ·* rol %cl,%eax
4947d2 ·* mov %ah,%bl/mov %al,%dl
aa64ca ·* shr $16,%eax/XXX/AGI
cb563f ·* mov S1[%ebx],%ecx/mov %ah,%ebx¤  \ Could be mult-issued
c95180 ·* mov S2[%edx],%edx/and $255,%eax¤ / if we had the bandwidth
00f609 ·* op1 %edx,%ecx/mov S3[%ebx],%edx
dc60e5 ·* op2 %edx,%ecx/mov S4[%eax],%eax
d26646 ·* op3 %eax,%ecx/mov key,%eax
66b263 ·* xor %ecx,y/mov shift,%ecx
aa775e ·*
02495d ·*/
0638e5 /*
bcfdda ·* This requires that %ebx be kept "clear" in the P6 sense.
5b775e ·*
21e9f9 ·* NOTE that the NOP *saves* a cycle on the Pentium! ·Without it,
2afe2f ·* the following mov is paired with the shr, and suffers an AGI stall,
84c06b ·* which stalls the shr as well and thus loses two issue slots instead
766e88 ·* of one. ·We have a spare issue slot, but the shr is on the critical
60c3b9 ·* path and delaying it adds a cycle.
5a495d ·*/
11af5a
5c53e0 #define ROUND(x,y,op1,op2,op3,n)¤   ¤   ¤   ¤   ¤   \
6052b6 ¤   __asm¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   \
943bf3 ¤   {¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   \
31de2c ¤   ¤   __asm op3 eax, x¤   ¤   ¤   ¤   /* 1 U ·*/¤ \
5d6632 ¤   ¤   __asm xor edx, edx¤ ¤   ¤   ¤   /* ···V */¤ \
6ef47e ¤   ¤   __asm rol eax, cl¤  ¤   ¤   ¤   /*2-5NP */¤ \
7760b9 ¤   ¤   __asm mov bl, ah¤   ¤   ¤   ¤   /* 6 U ·*/¤ \
fcc163 ¤   ¤   __asm mov dl, al¤   ¤   ¤   ¤   /* ···V */¤ \
09c2c1 ¤   ¤   __asm shr eax, 16¤  ¤   ¤   ¤   /* 7 Ux */¤ \
624def ¤   ¤   __asm nop /* !!! */¤¤   ¤   ¤   /* AGI ·*/¤ \
0319ff ¤   ¤   __asm mov ecx, S1[ebx*4]¤   ¤   /* 8 U ·*/¤ \
583c11 ¤   ¤   __asm mov bl, ah¤   ¤   ¤   ¤   /* ···V */¤ \
45eb75 ¤   ¤   __asm mov edx, S2[edx*4]¤   ¤   /* 9 U ·*/¤ \
c025ef ¤   ¤   __asm and eax, 255¤ ¤   ¤   ¤   /* ···V */¤ \
849f76 ¤   ¤   __asm op1 ecx, edx¤ ¤   ¤   ¤   /*10 U ·*/¤ \
5c6ec3 ¤   ¤   __asm mov edx, S3[ebx*4]¤   ¤   /* ···V */¤ \
e43dae ¤   ¤   __asm op2 ecx, edx¤ ¤   ¤   ¤   /*11 U ·*/¤ \
057ac2 ¤   ¤   __asm mov edx, S4[eax*4]¤   ¤   /* ···V */¤ \
1d69d5 ¤   ¤   __asm op3 ecx, edx¤ ¤   ¤   ¤   /*12 U ·*/¤ \
c543a0 ¤   ¤   __asm mov eax, 8+[esi+8*n]¤ ¤   /* ···V */¤ \
--352b 000649abb0140110066 Page 7 of Cast5.cpp
ae3d8d ¤   ¤   __asm xor y, ecx¤   ¤   ¤   ¤   /*13 U ·*/¤ \
9e9285 ¤   ¤   __asm mov ecx, 12+[esi+8*n]¤¤   /* ···V */¤ \
3c9371 ¤   }
5baf5a
1e39bc /* void
88f1e9 ·* CAST5encrypt(byte const *in, byte *out, word32 const *xkey)
f28aab ·* ·························4 ········8 ·················12
68775e ·*
984bc0 ·* Register usage:
60451c ·* esi points to key schedule
8124aa ·* eax is used as a temporary, and used for the primary round subkey
843828 ·* ebx is all-zero in the high 24 bits, and is used for indexing
fb97b1 ·* ecx is used as a temporary, and for the rotate round subkey (PLUS 16)
0601b1 ·* edx is all-zero in the high 24 bits, and is used for indexing
27f89b ·* esi points to the key schedule
cc07fd ·* edi is the right half of the current block
d50dbe ·* ebp is the left half of the current block
ce495d ·*/
59af5a
1325cb #define¤left¤   ebp
b9c401 #define¤right¤  edi
acaf5a
9004d8 NAKED·
cdc823 void·
aed80e __cdecl·
63d4b6 CAST5encryptAsm(const PGPUInt8 *in, PGPUInt8 *out, const PGPUInt32 *xkey)
fbbb36 {
196e77 ¤   __asm
e5c7a1 ¤   {
d86609 ¤   ¤   ALIGN 16
faaf5a
1dc6af ¤   ¤   push esi¤   ¤   ¤   ¤   /* ··U ·*/
1cc77b ¤   ¤   push right¤ ¤   ¤   ¤   /* ···V */
6faf5a
dcd2dc ¤   ¤   mov right, 8+[esp+4]¤   /* ··U ·*/
34900a ¤   ¤   mov esi, 8+[esp+12]¤¤   /* ···V */
d8cc3f ¤   ¤   push left¤  ¤   ¤   ¤   /* ··U ·*/
fe8683 ¤   ¤   push ebx¤   ¤   ¤   ¤   /* ···V */
cfb4b8 ¤   ¤   mov left, [right]¤  ¤   /* ··U ·*/
f33179 ¤   ¤   mov right, [right+4]¤   /* ···V */
9baf5a
d1fceb ¤   ¤   bswap right¤¤   ¤   ¤   /* ·NP ·*/
24c99d ¤   ¤   bswap left¤ ¤   ¤   ¤   /* ·NP ·*/
57af5a
91d5e1 ¤   ¤   mov eax, [esi]¤ ¤   ¤   /* ··U ·*/
670058 ¤   ¤   xor ebx,ebx¤¤   ¤   ¤   /* ···V */
16880d ¤   ¤   mov ecx, [esi+4]¤   ¤   /* ··U ·*/
0baf5a
d7bda1 ¤   ¤   ROUND(right, left, xor, sub, add, 0)
baf4f4 ¤   ¤   ROUND(left, right, sub, add, xor, 1)
eaf928 ¤   ¤   ROUND(right, left, add, xor, sub, 2)
6959f7 ¤   ¤   ROUND(left, right, xor, sub, add, 3)
79c67b ¤   ¤   ROUND(right, left, sub, add, xor, 4)
ff7e1f ¤   ¤   ROUND(left, right, add, xor, sub, 5)
9f6b78 ¤   ¤   ROUND(right, left, xor, sub, add, 6)
f8222d ¤   ¤   ROUND(left, right, sub, add, xor, 7)
9e8a52 ¤   ¤   ROUND(right, left, add, xor, sub, 8)
bc2a8d ¤   ¤   ROUND(left, right, xor, sub, add, 9)
f87a00 ¤   ¤   ROUND(right, left, sub, add, xor,10)
1dc264 ¤   ¤   ROUND(left, right, add, xor, sub,11)
fbd703 ¤   ¤   ROUND(right, left, xor, sub, add,12)
ad9e56 ¤   ¤   ROUND(left, right, sub, add, xor,13)
69f0eb ¤   ¤   ROUND(right, left, add, xor, sub,14)
2631d4 ¤   /*¤ ROUND(left, right, xor, sub, add,15)
4e1800 ¤   ·* Last round: omit loading of keys for next round
18a9af ¤   ·* Fetch out pointer and store data there instead
41a4e3 ¤   ·*/
2e4218 ¤   ¤   add eax, left¤  ¤   ¤   /* 1 U ·*/
cc76c5 ¤   ¤   xor edx, edx¤   ¤   ¤   /* ···V */
3ba80a ¤   ¤   rol eax, cl¤¤   ¤   ¤   /*2-5NP */
e164e2 ¤   ¤   mov bl, ah¤ ¤   ¤   ¤   /* 6 U ·*/
64645a ¤   ¤   mov dl, al¤ ¤   ¤   ¤   /* ···V */
--a775 0003faae3ae40110066 Page 8 of Cast5.cpp
be378f ¤   ¤   shr eax, 16¤¤   ¤   ¤   /* 7 Ux */
ae51d8 ¤   ¤   mov esi, 16+[esp+8]¤¤   /* ···V */
80cea0 ¤   ¤   mov ecx, S1[ebx*4]¤ ¤   /* 8 U ·*/
b1c7b3 ¤   ¤   mov bl, ah¤ ¤   ¤   ¤   /* ···V */
3a4eb6 ¤   ¤   mov edx, S2[edx*4]¤ ¤   /* 9 U ·*/
5d5d0e ¤   ¤   and eax, 255¤   ¤   ¤   /* ···V */
cd9895 ¤   ¤   xor ecx, edx¤   ¤   ¤   /*10 U ·*/
5bb7d3 ¤   ¤   mov edx, S3[ebx*4]¤ ¤   /* ···V */
a34928 ¤   ¤   sub ecx, edx¤   ¤   ¤   /*11 U ·*/
dbfa7b ¤   ¤   mov eax, S4[eax*4]¤ ¤   /* ···V */
d4f28e ¤   ¤   add ecx, eax¤   ¤   ¤   /*12 U ·*/
2a05a7 ¤   ¤   pop ebx¤¤   ¤   ¤   ¤   /* ···V */
e55363 ¤   ¤   bswap left¤ ¤   ¤   ¤   /*13 NP */
dc2dbf ¤   ¤   xor right, ecx¤ ¤   ¤   /*14 U ·*/
f0af5a
831907 ¤   ¤   mov [esi+4], left¤  ¤   /* ···V */
88fd8c ¤   ¤   bswap right¤¤   ¤   ¤   /* ··NP */
0d8642 ¤   ¤   pop left¤   ¤   ¤   ¤   /* ··U ·*/
6d5f96 ¤   ¤   mov [esi], right¤   ¤   /* ···V */
ef4478 ¤   ¤   pop right¤  ¤   ¤   ¤   /* ··U ·*/
922898 ¤   ¤   pop esi¤¤   ¤   ¤   ¤   /* ···V */
9b4458 ¤   ¤   ret¤¤   ¤   ¤   ¤   ¤   /* ··NP */
749371 ¤   }
52efe6 }
fbaf5a
9795d7 /*·
232b69 ·* asm void
1df753 ·* CAST5encryptCFBdbl(
214523 ·* ¤register word32 const *xkey,¤   // esp+pushes+ 4
bf72a1 ·* ¤register word32 in0,¤   ¤   // esp+pushes+ 8
ab02d0 ·* ¤register word32 in1,¤   ¤   // esp+pushes+12
e49368 ·* ¤register word32 in2,¤   ¤   // esp+pushes+16
fb7a94 ·* ¤register word32 in3,¤   ¤   // esp+pushes+20
d28037 ·* ¤register word32 const *src,¤// esp+pushes+24
5760c8 ·* ¤register word32 *dest,¤ ¤   // esp+pushes+28
0c4222 ·* ¤register word32 len)¤   ¤   // esp+pushes+32
57775e ·*
a0345e ·* Note that "len" is the number of 16-byte units to encrypt.
4e585a ·* Since this function only encrypts one block per time
348ec0 ·* around the loop, it has to be doubled.
b7775e ·*
10e1c9 ·* Doing the dbl part...
2e10ec ·* We use the srgument slots on the stack as IV registers, but
84c6f8 ·* actually only use one IV, in the in2/in3 slots.
4689f0 ·* Each iteration, we fetch from them the data to be encrypted
ace496 ·* for the next iteration before storing the current
ef1214 ·* ciphertext for the ineration after the next, thus achieving the
fb7834 ·* necessary interleaving.
d2495d ·*/
c8af5a
0d25cb #define¤left¤   ebp
9dc401 #define¤right¤  edi
74af5a
2604d8 NAKED·
12c823 void·
85d80e __cdecl·
81007a CAST5encryptCFBdblAsm(
95ef88 ¤   const PGPUInt32¤*xkey,·
64fd9e ¤   PGPUInt32¤  ¤   iv0,·
11e125 ¤   PGPUInt32¤  ¤   iv1,·
e7c4e8 ¤   PGPUInt32¤  ¤   iv2,·
d5d853 ¤   PGPUInt32¤  ¤   iv3,·
7c6c3c ¤   const PGPUInt32¤*src,·
e19ac6 ¤   PGPUInt32¤  ¤   *dest,·
5a0246 ¤   PGPUInt32¤  ¤   len)
52bb36 {
f16e77 ¤   __asm
1dc7a1 ¤   {
e36609 ¤   ¤   ALIGN 16
c2af5a
ccbe3c ¤   ¤   push esi
3fc337 ¤   ¤   push right
--b13a 0006bdaf3b640110066 Page 9 of Cast5.cpp
e0af5a
5c1875 ¤   ¤   mov esi, 8+[esp+4]¤ ¤   /* ··U ·- load key schedule pointer */
49d1ff ¤   ¤   push left¤  ¤   ¤   ¤   /* ···V */
cf28a6 ¤   ¤   mov left, 12+[esp+8]¤   /* ··U ·- load in0 as left */
acb5b6 ¤   ¤   mov right, 12+[esp+12]¤ /* ···V - load in1 as right */
c9af5a
549b43 ¤   ¤   push ebx¤   ¤   ¤   ¤   /* ··U ·*/
a60058 ¤   ¤   xor ebx,ebx¤¤   ¤   ¤   /* ···V */
beaf5a
8a1eb3 ¤   ¤   shl dword ptr 16+[esp+32], 1¤   /* ··NP - double loop counter */
e8af5a
c0bf9b ¤   encryptloop:
97f545 ¤   ¤   mov eax, [esi]¤ ¤   ¤   /* ··U ·- preload key material */
9711b5 ¤   ¤   mov ecx, [esi+4]¤   ¤   /* ···V - preload key material */
47af5a
dee0b5 ¤   ¤   bswap right¤¤   ¤   ¤   /* ··NP ·*/
3ff631 ¤   ¤   bswap left¤ ¤   ¤   ¤   /* ··NP ·*/
2eaf5a
62bda1 ¤   ¤   ROUND(right, left, xor, sub, add, 0)
4ef4f4 ¤   ¤   ROUND(left, right, sub, add, xor, 1)
1df928 ¤   ¤   ROUND(right, left, add, xor, sub, 2)
5059f7 ¤   ¤   ROUND(left, right, xor, sub, add, 3)
4ac67b ¤   ¤   ROUND(right, left, sub, add, xor, 4)
c67e1f ¤   ¤   ROUND(left, right, add, xor, sub, 5)
fc6b78 ¤   ¤   ROUND(right, left, xor, sub, add, 6)
79222d ¤   ¤   ROUND(left, right, sub, add, xor, 7)
fe8a52 ¤   ¤   ROUND(right, left, add, xor, sub, 8)
f62a8d ¤   ¤   ROUND(left, right, xor, sub, add, 9)
957a00 ¤   ¤   ROUND(right, left, sub, add, xor,10)
8ec264 ¤   ¤   ROUND(left, right, add, xor, sub,11)
d5d703 ¤   ¤   ROUND(right, left, xor, sub, add,12)
979e56 ¤   ¤   ROUND(left, right, sub, add, xor,13)
d5f0eb ¤   ¤   ROUND(right, left, add, xor, sub,14)
7331d4 ¤   /*¤ ROUND(left, right, xor, sub, add,15)
ac1800 ¤   ·* Last round: omit loading of keys for next round
278bcf ¤   ·* Instead, start the CFB operations. ·Including the
6a4681 ¤   ·* swap of the halves, that ends up as:
429714 ¤   ·*
0acdf8 ¤   ·* %eax = src[0] ^ bswap(right)
606e76 ¤   ·* %ecx = src[1] ^ bswap(left)
3da055 ¤   ·* src += 8bytes
8b6d2c ¤   ·* left = bswap(in2)
999afd ¤   ·* right = bswap(in3)
7f255c ¤   ·* in2 = %eax
b2fe69 ¤   ·* dest[0] = %eax
51dd19 ¤   ·* in3 = %ecx
0ed24e ¤   ·* dest[1] = %eax
a89c57 ¤   ·* dest += 8bytes
6c9714 ¤   ·*
5a0e4d ¤   ·* For the '486, we can just use bswap. ·For the '386, it's
64cd2d ¤   ·* xchg ah,al
ab53f0 ¤   ·* rol $16,eax
a5cd2d ¤   ·* xchg ah,al
a19714 ¤   ·*
eebd58 ¤   ·* Annoyingly, this really *sucks* on a PPro, due to fierce
c567ba ¤   ·* partial-register stalls. ·So it pretty much has to go two ways.
8b0c41 ¤   ·* Options are:
a631b4 ¤   ·* - Duplicate the entire encryption loop?
333989 ¤   ·* - Do it in a pre-pass and a post-pass. ·Makes life easy, but we
0b15c1 ¤   ·* ··end up being memory bound.
b31a43 ¤   ·* - Something truly wierd?
47a4e3 ¤   ·*/
d44218 ¤   ¤   add eax, left¤  ¤   ¤   /* 1 U ·*/
a876c5 ¤   ¤   xor edx, edx¤   ¤   ¤   /* ···V */
b2a80a ¤   ¤   rol eax, cl¤¤   ¤   ¤   /*2-5NP */
3164e2 ¤   ¤   mov bl, ah¤ ¤   ¤   ¤   /* 6 U ·*/
ae645a ¤   ¤   mov dl, al¤ ¤   ¤   ¤   /* ···V */
31378f ¤   ¤   shr eax, 16¤¤   ¤   ¤   /* 7 Ux */
932041 ¤   ¤   nop¤¤   ¤   ¤   ¤   ¤   /* ···V */
85cea0 ¤   ¤   mov ecx, S1[ebx*4]¤ ¤   /* 8 U ·*/
84c7b3 ¤   ¤   mov bl, ah¤ ¤   ¤   ¤   /* ···V */
6b4eb6 ¤   ¤   mov edx, S2[edx*4]¤ ¤   /* 9 U ·*/
--28f2 0000b7849a840110066 Page 10 of Cast5.cpp
295d0e ¤   ¤   and eax, 255¤   ¤   ¤   /* ···V */
4e9895 ¤   ¤   xor ecx, edx¤   ¤   ¤   /*10 U ·*/
42b7d3 ¤   ¤   mov edx, S3[ebx*4]¤ ¤   /* ···V */
964928 ¤   ¤   sub ecx, edx¤   ¤   ¤   /*11 U ·*/
085944 ¤   ¤   mov edx, S4[eax*4]¤ ¤   /* ···V */
7ae719 ¤   ¤   add ecx, edx¤   ¤   ¤   /*12 U ·*/
f730e5 ¤   ¤   mov ebx, 16+[esp+24]¤   /* ···V - fetch src pointer */
4cb1b1 ¤   ¤   xor right, ecx¤ ¤   ¤   /*13 U ·*/
a8c340 ¤   ¤   add ebx, 8¤ ¤   ¤   ¤   /* ···V - increment src ptr */
6457a5 ¤   ¤   bswap left
9fe099 ··¤ ¤   bswap right
ed5400 ¤   ¤   mov eax, [ebx-8]¤   ¤   /* ··U ·- get src word */
86c1f7 ¤   ¤   mov ecx, [ebx-4]¤   ¤   /* ···V - other src word */
47536e ¤   ¤   mov 16+[esp+24], ebx¤   /* ··U ·- store src pointer back */
5b8379 ¤   ¤   mov edx, 16+[esp+28]¤   /* ···V - fetch dest pointer */
6bc9e2 ¤   ¤   xor eax, right¤ ¤   ¤   /* ··U ·*/
ec4842 ¤   ¤   xor ecx, left¤  ¤   ¤   /* ···V */
764b7e ¤   ¤   mov left, 16+[esp+16]¤  /* ··U ·- fetch in2 for new left */
3ffc4e ¤   ¤   mov right, 16+[esp+20]¤ /* ···V - fetch in3 for new right */
ff68b8 ¤   ¤   mov 16+[esp+16], eax¤   /* ··U ·- store ciphertext for next time */
15df94 ¤   ¤   mov 16+[esp+20], ecx¤   /* ···V - store ciphertext for next time */
d42fc3 ¤   ¤   mov [edx+0], eax¤   ¤   /* ··U ·- store result */
b10412 ¤   ¤   mov [edx+4], ecx¤   ¤   /* ···V - store result */
bce1e1 ¤   ¤   add edx, 8¤ ¤   ¤   ¤   /* ··U ·- increment dest ptr */
92fb11 ¤   ¤   xor ebx, ebx¤   ¤   ¤   /* ···V - clear %ebx for next iteration */
728fa0 ¤   ¤   dec dword ptr 16+[esp+32]¤  /* ··U ·- decrement loop counter (set ZF) */
096a90 ¤   ¤   mov 16+[esp+28], edx¤   /* ···V - store dest pointer back */
417586 ¤   ¤   /* Pairing opportunity lost, sigh */
bf4abf ¤   ¤   jnz encryptloop¤
f6af5a
e43153 ¤   ¤   /* And we're done! ·Pop registers and return */
a3af5a
ac1867 ¤   ¤   pop ebx¤¤   ¤   ¤   ¤   /* ··U ·*/
549b82 ¤   ¤   pop left¤   ¤   ¤   ¤   /* ···V */
3c4478 ¤   ¤   pop right¤  ¤   ¤   ¤   /* ··U ·*/
482898 ¤   ¤   pop esi¤¤   ¤   ¤   ¤   /* ···V */
6d4458 ¤   ¤   ret¤¤   ¤   ¤   ¤   ¤   /* ··NP */
ff9371 ¤   }
77efe6 }
e9af5a
f738e5 /*
6a5da4 ·* dbl decode... plain[i] = cipher[i] ^ CRYPT(cipher[i-2])
c72f5b ·* Can we do this with only one temporary (and still allow in-place)?
34af5a
944699 ·* Crypt cipher[i-2] -> plain[i]
e80930 ·* Load cipher[i-1] from temp
d8c492 ·* Load cipher[i]
81fe29 ·* Store cipher[i] into temp, plain[i] ^= cipher[i] (or vice-versa)
8cfe0b ·* Store plain[i]·
8d796b ·* i++
00a0c5 ·* Um... do we have enough regs? ·It seems that we have cipher[i],
e221d0 ·* cipher[i-1] and plain[i] in registers at the same time.
bdaf5a
bf8e0d ·* Try this order of operations:
4b4699 ·* Crypt cipher[i-2] -> plain[i]
88c492 ·* Load cipher[i]
f5d560 ·* plain[i] ^= cipher[i]
77efd4 ·* store plain[i]
e7d4e3 ·* load temp into plain[i], which is now cipher[i-1] (cipher[i-2] after i++)
a0d327 ·* store cipher[i] into temp
84e09d ·* increment i
3a4ffc ·* That works, and doesn't use an excessive number of registers.
91775e ·*
673e12 ·* Written out in full,
74a728 ·* %eax = src[0];
bab0c9 ·* %ecx = src[1];
f6e1de ·* src += 8bytes
5701bf ·* BSWAP(left)
23ca2d ·* BSWAP(right)
ba56c0 ·* right ^= %eax
0f4f60 ·* left ^= %ecx
0be5d1 ·* dest[0] = right
--0323 0007f4e5d9640110066 Page 11 of Cast5.cpp
085d37 ·* dest[1] = left
77a6cd ·* dest += 8bytes
361470 ·* left = in2
30f170 ·* right = in3
f8a0e9 ·* in2 = %eax
cb58ac ·* in3 = %ecx
64495d ·*/
9eaf5a
6304d8 NAKED·
b2c823 void·
e4d80e __cdecl·
be48f4 CAST5decryptCFBdblAsm(
6bef88 ¤   const PGPUInt32¤*xkey,·
26fd9e ¤   PGPUInt32¤  ¤   iv0,·
24e125 ¤   PGPUInt32¤  ¤   iv1,·
11c4e8 ¤   PGPUInt32¤  ¤   iv2,·
add853 ¤   PGPUInt32¤  ¤   iv3,·
286c3c ¤   const PGPUInt32¤*src,·
8f9ac6 ¤   PGPUInt32¤  ¤   *dest,·
230246 ¤   PGPUInt32¤  ¤   len)
a0bb36 {
ea6e77 ¤   __asm
5fc7a1 ¤   {
b36609 ¤   ¤   ALIGN 16
4eaf5a
aabe3c ¤   ¤   push esi
fec337 ¤   ¤   push right
94af5a
3d1875 ¤   ¤   mov esi, 8+[esp+4]¤ ¤   /* ··U ·- load key schedule pointer */
dbd1ff ¤   ¤   push left¤  ¤   ¤   ¤   /* ···V */
3528a6 ¤   ¤   mov left, 12+[esp+8]¤   /* ··U ·- load in0 as left */
48b5b6 ¤   ¤   mov right, 12+[esp+12]¤ /* ···V - load in1 as right */
25af5a
f19b43 ¤   ¤   push ebx¤   ¤   ¤   ¤   /* ··U ·*/
170058 ¤   ¤   xor ebx,ebx¤¤   ¤   ¤   /* ···V */
53af5a
1d1eb3 ¤   ¤   shl dword ptr 16+[esp+32], 1¤   /* ··NP - double loop counter */
eaaf5a
7f3734 ¤   decryptloop:
93f545 ¤   ¤   mov eax, [esi]¤ ¤   ¤   /* ··U ·- preload key material */
1d11b5 ¤   ¤   mov ecx, [esi+4]¤   ¤   /* ···V - preload key material */
91af5a
c7e0b5 ¤   ¤   bswap right¤¤   ¤   ¤   /* ··NP ·*/
86f631 ¤   ¤   bswap left¤ ¤   ¤   ¤   /* ··NP ·*/
17af5a
37bda1 ¤   ¤   ROUND(right, left, xor, sub, add, 0)
1af4f4 ¤   ¤   ROUND(left, right, sub, add, xor, 1)
0af928 ¤   ¤   ROUND(right, left, add, xor, sub, 2)
be59f7 ¤   ¤   ROUND(left, right, xor, sub, add, 3)
cec67b ¤   ¤   ROUND(right, left, sub, add, xor, 4)
797e1f ¤   ¤   ROUND(left, right, add, xor, sub, 5)
e96b78 ¤   ¤   ROUND(right, left, xor, sub, add, 6)
87222d ¤   ¤   ROUND(left, right, sub, add, xor, 7)
9e8a52 ¤   ¤   ROUND(right, left, add, xor, sub, 8)
2c2a8d ¤   ¤   ROUND(left, right, xor, sub, add, 9)
d37a00 ¤   ¤   ROUND(right, left, sub, add, xor,10)
2ec264 ¤   ¤   ROUND(left, right, add, xor, sub,11)
e9d703 ¤   ¤   ROUND(right, left, xor, sub, add,12)
f29e56 ¤   ¤   ROUND(left, right, sub, add, xor,13)
4df0eb ¤   ¤   ROUND(right, left, add, xor, sub,14)
ec31d4 ¤   /*¤ ROUND(left, right, xor, sub, add,15)
071800 ¤   ·* Last round: omit loading of keys for next round
718bcf ¤   ·* Instead, start the CFB operations. ·Including the
024681 ¤   ·* swap of the halves, that ends up as:
509714 ¤   ·*
229db2 ¤   ·* %eax = src[0];
3f8a53 ¤   ·* %ecx = src[1];
04a055 ¤   ·* src += 8bytes
92e31c ¤   ·* BSWAP(left)
2b5d5e ¤   ·* BSWAP(right)
83174b ¤   ·* right ^= %eax
7fd813 ¤   ·* left ^= %ecx
--75f4 00095ae6e8f40110066 Page 12 of Cast5.cpp
1bde38 ¤   ·* dest[0] = right
2967ad ¤   ·* dest[1] = left
719c57 ¤   ·* dest += 8bytes
0091c5 ¤   ·* left = in2
c813d3 ¤   ·* right = in3
af255c ¤   ·* in2 = %eax
b5dd19 ¤   ·* in3 = %ecx
3da4e3 ¤   ·*/
854218 ¤   ¤   add eax, left¤  ¤   ¤   /* 1 U ·*/
3d76c5 ¤   ¤   xor edx, edx¤   ¤   ¤   /* ···V */
17a80a ¤   ¤   rol eax, cl¤¤   ¤   ¤   /*2-5NP */
0d64e2 ¤   ¤   mov bl, ah¤ ¤   ¤   ¤   /* 6 U ·*/
49645a ¤   ¤   mov dl, al¤ ¤   ¤   ¤   /* ···V */
7f378f ¤   ¤   shr eax, 16¤¤   ¤   ¤   /* 7 Ux */
6d2041 ¤   ¤   nop¤¤   ¤   ¤   ¤   ¤   /* ···V */
6ecea0 ¤   ¤   mov ecx, S1[ebx*4]¤ ¤   /* 8 U ·*/
5ec7b3 ¤   ¤   mov bl, ah¤ ¤   ¤   ¤   /* ···V */
a74eb6 ¤   ¤   mov edx, S2[edx*4]¤ ¤   /* 9 U ·*/
625d0e ¤   ¤   and eax, 255¤   ¤   ¤   /* ···V */
7f9895 ¤   ¤   xor ecx, edx¤   ¤   ¤   /*10 U ·*/
0eb7d3 ¤   ¤   mov edx, S3[ebx*4]¤ ¤   /* ···V */
764928 ¤   ¤   sub ecx, edx¤   ¤   ¤   /*11 U ·*/
f75944 ¤   ¤   mov edx, S4[eax*4]¤ ¤   /* ···V */
07e719 ¤   ¤   add ecx, edx¤   ¤   ¤   /*12 U ·*/
4130e5 ¤   ¤   mov ebx, 16+[esp+24]¤   /* ···V - fetch src pointer */
86b1b1 ¤   ¤   xor right, ecx¤ ¤   ¤   /*13 U ·*/
a6c340 ¤   ¤   add ebx, 8¤ ¤   ¤   ¤   /* ···V - increment src ptr */
af57a5 ¤   ¤   bswap left
c4e099 ··¤ ¤   bswap right
d35400 ¤   ¤   mov eax, [ebx-8]¤   ¤   /* ··U ·- get src word */
6bc1f7 ¤   ¤   mov ecx, [ebx-4]¤   ¤   /* ···V - other src word */
0b536e ¤   ¤   mov 16+[esp+24], ebx¤   /* ··U ·- store src pointer back */
948379 ¤   ¤   mov edx, 16+[esp+28]¤   /* ···V - fetch dest pointer */
f031ab ¤   ¤   xor right, eax¤ ¤   ¤   /* ··U ·*/
978bbd ¤   ¤   xor left, ecx¤  ¤   ¤   /* ···V */
fb9c44 ¤   ¤   mov [edx+0], right¤ ¤   /* ··U ·- store result */
60543b ¤   ¤   mov [edx+4], left¤  ¤   /* ···V - store result */
b84b7e ¤   ¤   mov left, 16+[esp+16]¤  /* ··U ·- fetch in2 for new left */
0afc4e ¤   ¤   mov right, 16+[esp+20]¤ /* ···V - fetch in3 for new right */
c468b8 ¤   ¤   mov 16+[esp+16], eax¤   /* ··U ·- store ciphertext for next time */
52df94 ¤   ¤   mov 16+[esp+20], ecx¤   /* ···V - store ciphertext for next time */
74e1e1 ¤   ¤   add edx, 8¤ ¤   ¤   ¤   /* ··U ·- increment dest ptr */
75fb11 ¤   ¤   xor ebx, ebx¤   ¤   ¤   /* ···V - clear %ebx for next iteration */
b48fa0 ¤   ¤   dec dword ptr 16+[esp+32]¤  /* ··U ·- decrement loop counter (set ZF) */
c56a90 ¤   ¤   mov 16+[esp+28], edx¤   /* ···V - store dest pointer back */
b77586 ¤   ¤   /* Pairing opportunity lost, sigh */
afc210 ¤   ¤   jnz decryptloop¤
24af5a
ba3153 ¤   ¤   /* And we're done! ·Pop registers and return */
a4af5a
c51867 ¤   ¤   pop ebx¤¤   ¤   ¤   ¤   /* ··U ·*/
1d9b82 ¤   ¤   pop left¤   ¤   ¤   ¤   /* ···V */
d44478 ¤   ¤   pop right¤  ¤   ¤   ¤   /* ··U ·*/
7d2898 ¤   ¤   pop esi¤¤   ¤   ¤   ¤   /* ···V */
bf4458 ¤   ¤   ret¤¤   ¤   ¤   ¤   ¤   /* ··NP */
839371 ¤   }
e1efe6 }
eaaf5a
808552 #endif¤ // PGP_INTEL
b8af5a
24af5a
039f73 /////////////////////////
8d487d // CAST Testing Functions
889f73 /////////////////////////
79af5a
3a20b5 // VerifyCastSBoxesValid verifies that the CAST S-boxes haven't become
10ff59 // corrupted in memory.
6d67c5 ¤
9077be PGPBoolean·
9021f3 VerifyCastSBoxesValid()
aebb36 {
95656c ¤   PGPBoolean¤ valid¤  = TRUE;
--28f3 000282f25fb40110066 Page 13 of Cast5.cpp
5e1831 ¤   CRC32¤  ¤   crc¤¤   = 0;
65af5a
1405e7 ¤   pgpAssert(((PGPUInt32) &S1[0] & 0x3) == 0);
adb82d ¤   pgpAssert(((PGPUInt32) &S2[0] & 0x3) == 0);
302b64 ¤   pgpAssert(((PGPUInt32) &S3[0] & 0x3) == 0);
6ccba8 ¤   pgpAssert(((PGPUInt32) &S4[0] & 0x3) == 0);
e758e1 ¤   pgpAssert(((PGPUInt32) &S5[0] & 0x3) == 0);
cde52b ¤   pgpAssert(((PGPUInt32) &S6[0] & 0x3) == 0);
677662 ¤   pgpAssert(((PGPUInt32) &S7[0] & 0x3) == 0);
582ca2 ¤   pgpAssert(((PGPUInt32) &S8[0] & 0x3) == 0);
e9af5a
f65061 ¤   crc¤= ContinueCRC32(S1, sizeof(S1) / sizeof(S1[0]), crc);
8bc787 ¤   crc¤= ContinueCRC32(S2, sizeof(S2) / sizeof(S2[0]), crc);
0fb525 ¤   crc¤= ContinueCRC32(S3, sizeof(S3) / sizeof(S3[0]), crc);
5ee05a ¤   crc¤= ContinueCRC32(S4, sizeof(S4) / sizeof(S4[0]), crc);
a392f8 ¤   crc¤= ContinueCRC32(S5, sizeof(S5) / sizeof(S5[0]), crc);
6f051e ¤   crc¤= ContinueCRC32(S6, sizeof(S6) / sizeof(S6[0]), crc);
d077bc ¤   crc¤= ContinueCRC32(S7, sizeof(S7) / sizeof(S7[0]), crc);
51afe0 ¤   crc¤= ContinueCRC32(S8, sizeof(S8) / sizeof(S8[0]), crc);
b8af5a
cfd425 ¤   valid = (crc == 0xD8D4C8D7);
92af5a
b55830 ¤   return valid;
c5efe6 }
28af5a
1aaf5a
90ed6f #if 0¤  // KEEP [
ae38e5 /*
1c57d0 ·* Appendix C.
1a7288 ·* This appendix provides test vectors for the CAST-128 cipher described
55805e ·* in Section 5 and in Appendices A and B.
40e225 ·* C.1. Single Key-Plaintext-Ciphertext Set
5b7567 ·* 128-bit key ······= 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A (hex)
0e35d5 ·* 64-bit plaintext ·= 01 23 45 67 89 AB CD EF (hex)
bf1d41 ·* 64-bit ciphertext = 23 8B 4F E5 84 7E 44 B2 (hex)
ee0c84 ·* C.2. Full Maintenance Test
850835 ·* A maintenance test for CAST-128 has been defined to verify the correctness
cee4ac ·* of implementations. ·It is defined in pseudo-code as follows, where a and
bd42ac ·* b are 128-bit vectors, aL and aR are the leftmost and rightmost halves of
48ac57 ·* a, bL and bR are the leftmost and rightmost halves of b, and encrypt(d,
8ad4c6 ·* k) is the encryption in ECB mode of block d under key k.
0d9ec0 ·*·
0b28e7 ·* .
8c4194 ·* Initial·
164f73 ·* a = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A (hex)
b74194 ·* Initial·
b558bc ·* b = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A (hex)
cc334e ·* do 1,000,000 times
cf85a8 ·* {
43ac69 ·* ····aL = encrypt( aL , b)
def16b ·* ····aR = encrypt( aR , b)
bb3a2b ·* ····bL = encrypt( bL , a)
b96729 ·* ····bR = encrypt( bR , a)
21d178 ·* }
9c97c3 ·* Verify·
6de5a5 ·* a == EE A9 D0 A2 49 FD 3B A6 B3 43 6F B8 9D 6D CA 92 (hex)
0b97c3 ·* Verify·
fa23df ·* b == B2 C9 5E B0 0C 31 AD 71 80 AC 05 B8 E8 3D 69 6E (hex)
8b595b ·* ¤
319ec0 ·*·
61495d ·*/
27af5a
1efeb2 #include <stdio.h>
4af7c3 #include <strings.h>
b8af5a
abc823 void·
0273ef printhex(const char *msg, const PGPUInt8 *num, int len)
eabb36 {
c54ba4 ¤   int i;
8faf5a
2d5c97 ¤   printf(msg);
28af5a
--f9f6 0009d319d8c40110066 Page 14 of Cast5.cpp
ed54c8 ¤   for (i=0; i<len; i++)
0c1ac6 ¤   ¤   printf("%X", num[i]);
78af5a
46270d ¤   printf("\n");
81efe6 }
03af5a
b24d2f int
637f68 main(void)
34bb36 {
849c9c ¤   PGPUInt8 a[16] =·
76c7a1 ¤   {
fa20b9 ¤   ¤   0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
2f4bf2 ¤   ¤   0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A
ec62bd ¤   };
614a9b ¤   PGPUInt8 b[16] =·
a8c7a1 ¤   {
e320b9 ¤   ¤   0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
ae4bf2 ¤   ¤   0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A
bc62bd ¤   };
b66339 ¤   PGPUInt8 test[8] =
6dc7a1 ¤   {
8b9ced ¤   ¤   0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
9b62bd ¤   };
d8dd38 ¤   static PGPUInt8 const expect1[8] =
84c7a1 ¤   {
807379 ¤   ¤   ·0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2
ac62bd ¤   };
bcbf63 ¤   static PGPUInt8 const expecta[16] =
45c7a1 ¤   {
28052e ¤   ¤   0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6,
adb14f ¤   ¤   0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92
2d62bd ¤   };
6235b3 ¤   static PGPUInt8 const expectb[16] =
49c7a1 ¤   {
1c30f0 ¤   ¤   0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71,
9bee3a ¤   ¤   0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E
1b62bd ¤   };
dd65d2 ¤   PGPUInt32¤  xkey[32];
5d438b ¤   long¤   count;
290049 ¤   printf("Simple sanity check...\n");
6c67c5 ¤
2dd2a5 ¤   printhex(" ······Key =", a, sizeof(a));
614e94 ¤   CAST5schedule(xkey, a);
a2868e ¤   printhex(" Plaintext =", test, sizeof(test));
b844ea ¤   CAST5encrypt(test, test, xkey);
0ce491 ¤   printhex("Ciphertext =", test, sizeof(test));
77d369 ¤   printhex(" ···Expect =", expect1, sizeof(expect1));
9e02c3 ¤   if (memcmp(test, expect1, sizeof(test)) != 0)
ab07df ¤   ¤   printf("¤   ¤   ***** ERROR *****\n");
db67c5 ¤
284371 ¤   printf("Full maintenance test (4,000,000 encryptions)...\n");
b7a36b ¤   for (count = 0 ;count < 1000000; count++) {
f5c607 ¤   ¤   CAST5schedule(xkey, b);
368656 ¤   ¤   CAST5encrypt(a, a, xkey);
9e99d0 ¤   ¤   CAST5encrypt(a+8, a+8, xkey);
44e3ca ¤   ¤   CAST5schedule(xkey, a);
4efcc8 ¤   ¤   CAST5encrypt(b, b, xkey);
4f2e2f ¤   ¤   CAST5encrypt(b+8, b+8, xkey);
6c9371 ¤   }
eafcd7 ¤   printhex(" ····a =", a, sizeof(a));
24d8c3 ¤   printhex("Expect =", expecta, sizeof(expecta));
96318e ¤   if (memcmp(a, expecta, sizeof(a)) != 0)
9c07df ¤   ¤   printf("¤   ¤   ***** ERROR *****\n");
7860d1 ¤   printhex(" ····b =", b, sizeof(b));
439cbb ¤   printhex("Expect =", expectb, sizeof(expectb));
ca2f4e ¤   if (memcmp(b, expectb, sizeof(b)) != 0)
b307df ¤   ¤   printf("¤   ¤   ***** ERROR *****\n");
64c7a1 ¤   {
4fa926 ¤   ¤   char bob[1];
be85a7 ¤   ¤   gets(bob);
e39371 ¤   }
9daf5a
--9a1b 00140a19cac40110066 Page 15 of Cast5.cpp
303e6b ¤   return 0;
06efe6 }
aeaf5a
40a5ee #endif¤ // ] KEEP
--4d32 00080c0f40540110067 Page 1 of Cast5.h
541bc3 //////////////////////////////////////////////////////////////////////////////
931832 // Cast5.h
1e465d //
a4e946 // Contains declarations Cast5.cpp.
5e1bc3 //////////////////////////////////////////////////////////////////////////////
23af5a
0d6e12 // $Id: Cast5.h,v 1.1.2.6 1998/07/06 08:56:33 nryan Exp $
86af5a
cf7758 // Portions Copyright (C) 1998 by Network Associates, Inc.
dc71ae // All rights reserved.
34af5a
2d2d03 /*****************************************************************************
09a890 ·*¤ ¤   ¤   ¤   ¤   C A S T 5 ··S Y M M E T R I C ··C I P H E R
0f49e9 ·*¤ ¤   Copyright (c) 1996 Northern Telecom Ltd. All rights reserved.
46489b ·*****************************************************************************
94775e ·*
52327e ·* FILE:¤   ¤   cast5.h
4e775e ·*
4987ff ·* AUTHOR(S):¤  R.T.Lockhart, Dept. 9C40, Nortel Ltd.
e07851 ·*¤ ¤   ¤   ¤   C. Adams, Dept 9C21, Nortel Ltd.
f8775e ·*
85b6f4 ·* DESCRIPTION: CAST5 header file. This file defines the interface for
5232d9 ·* the CAST5 symmetric-key encryption/decryption/MACing code. The code
f94ab5 ·* supports key lengths from 8 through 128 bits, in multiples of 8.
2a775e ·*
24775e ·*
d9e121 ·* Error handling:
38f55c ·* Most functions return an int that indicates the success or failure of the
b85864 ·* operation. See the C5E_xxx #defines for a list of error conditions.
b12139 ·*¤
77175e ·* Data size assumptions: ¤ BYTE¤   - unsigned 8 bits
b8cbce ·*¤ ¤   ¤   ¤   UINT32¤ - unsigned 32 bits
3a775e ·*
943623 ·****************************************************************************/
d4af5a
b42d9e #ifndef Included_Cast5_h¤   // [
a501a3 #define Included_Cast5_h
b1af5a
40af5a
1bd557 ////////
dd02c9 // Types
80d557 ////////
2eaf5a
84e79f // Align to 1.
1afcdb #pragma pack(push, 1)
e0af5a
b654bd typedef union ExpandedCASTKey
7dbb36 {
8a7df2 ¤   PGPUInt8 ·keyBytes[32*sizeof(PGPUInt32)];
4100cd ¤   PGPUInt32 keyDWords[32];
91af5a
46664a } ExpandedCASTKey;
1f67c5 ¤
49debc typedef struct CASTCFBContext
01bb36 {
45a31f ¤   ExpandedCASTKey expandedKey;
a9af5a
7ab8c6 } CASTCFBContext;
8faf5a
48be31 typedef union CASTKey
84bb36 {
c80570 ¤   PGPUInt8¤   keyBytes[16];
0458c2 ¤   PGPUInt32¤  keyDWords[16/sizeof(PGPUInt32)];
7eaf5a
dac769 } CASTKey, EncryptedCASTKey;
27af5a
e00d00 // PassphraseSalt contains salt bytes for use in a CipherContext.
31af5a
f8d7f3 typedef union PassphraseSalt
63bb36 {
4f67e4 ¤   PGPUInt8¤   saltBytes[8];
8057b3 ¤   PGPUInt32¤  saltDWords[8/sizeof(PGPUInt32)];
--7da4 0016fe8b0c140110067 Page 2 of Cast5.h
e0af5a
97d56b } PassphraseSalt;
1faf5a
e41cb1 // Restore alignment.
94f421 #pragma pack(pop)
5caf5a
a0af5a
0d6cc2 /////////////////////
6ebf67 // Exported Functions
d76cc2 /////////////////////
deaf5a
16169d void¤   CAST5schedule(PGPUInt32 xkey[32], const PGPUInt8 *k);
caaf5a
af69ef void¤   CAST5encrypt(const PGPUInt8 *in, PGPUInt8 *out,·
e02ec9 ¤   ¤   ¤   const PGPUInt32 *xkey);
aa3ff7 void¤   CAST5decrypt(const PGPUInt8 *in, PGPUInt8 *out,·
752ec9 ¤   ¤   ¤   const PGPUInt32 *xkey);
9daf5a
7779af void¤   CAST5encryptCFBdbl(const PGPUInt32 *xkey, PGPUInt32 iv0,·
37bd2b ¤   ¤   ¤   PGPUInt32 iv1, PGPUInt32 iv2, PGPUInt32 iv3,·
e5756f ¤   ¤   ¤   const PGPUInt32 *src, PGPUInt32 *dest, PGPUInt32 len);
fcdac9 void¤   CAST5decryptCFBdbl(const PGPUInt32 *xkey, PGPUInt32 iv0,·
a3bd2b ¤   ¤   ¤   PGPUInt32 iv1, PGPUInt32 iv2, PGPUInt32 iv3,·
4a756f ¤   ¤   ¤   const PGPUInt32 *src, PGPUInt32 *dest, PGPUInt32 len);
16af5a
a2cf41 #if defined(PGP_INTEL)
3aaf5a
41663e void __cdecl¤   CAST5encryptAsm(const PGPUInt8 *in, PGPUInt8 *out,·
ac63fa ¤   ¤   ¤   ¤   ¤   const PGPUInt32 *xkey);
e4af5a
7a38e4 void __cdecl¤   CAST5encryptCFBdblAsm(const PGPUInt32 *xkey, PGPUInt32 iv0,·
9de332 ¤   ¤   ¤   ¤   ¤   PGPUInt32 iv1, PGPUInt32 iv2, PGPUInt32 iv3,·
ccb648 ¤   ¤   ¤   ¤   ¤   const PGPUInt32 *src, PGPUInt32 *dest, PGPUInt32 len);
c96ee7 void __cdecl¤   CAST5decryptCFBdblAsm(const PGPUInt32 *xkey, PGPUInt32 iv0,·
68e332 ¤   ¤   ¤   ¤   ¤   PGPUInt32 iv1, PGPUInt32 iv2, PGPUInt32 iv3,·
37b648 ¤   ¤   ¤   ¤   ¤   const PGPUInt32 *src, PGPUInt32 *dest, PGPUInt32 len);
3faf5a
ca8552 #endif¤ // PGP_INTEL
7eaf5a
c60fe3 PGPBoolean¤ VerifyCastSBoxesValid();
81af5a
6f73d2 #endif¤ // ] Included_Cast5_h
--5abe 000e6f00d4640110068 Page 1 of Cast5Box.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
d1644a // Cast5Box.cpp
55465d //
cff253 // Definitions for the CAST5 S-boxes.
651bc3 //////////////////////////////////////////////////////////////////////////////
52af5a
540b42 // $Id: Cast5Box.cpp,v 1.1.2.9 1998/07/06 08:56:34 nryan Exp $
94af5a
147758 // Portions Copyright (C) 1998 by Network Associates, Inc.
0471ae // All rights reserved.
1eaf5a
b76931 #if defined(PGPDISK_MFC)
41af5a
cf9e12 #include "StdAfx.h"
6caf5a
6e4268 #elif defined(PGPDISK_95DRIVER)
48af5a
a906a9 #include <vtoolscp.h>
6286d2 #include LOCKED_CODE_SEGMENT
545269 #include LOCKED_DATA_SEGMENT
c9af5a
b6f5a6 #elif defined(PGPDISK_NTDRIVER)
f4af5a
c7d7a1 #include <vdw.h>
f9af5a
28db21 #else
a7112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
3e05d6 #endif¤ // PGPDISK_MFC
aeaf5a
d19bcf #include "Required.h"
14797b #include "Cast5Box.h"
ccaf5a
73af5a
ecca3a ////////////////////
96f648 // The CAST5 S-Boxes
caca3a ////////////////////
13af5a
457876 // The new CAST5 S-boxes, each mapping 8 input bits to 32 output bits.
86dbf5 // These boxes are at the heart of CAST's security. ·Random boxes
5fe715 // would not do nearly as well!
c9af5a
6340bc const PGPUInt32 S1[256] = {
45b948 ¤   0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3,
4b7ff0 ¤   0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
b10ab9 ¤   0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059,
09ee18 ¤   0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
27332d ¤   0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b,
091642 ¤   0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de,
515626 ¤   0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159,
984ca1 ¤   0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
bd515b ¤   0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f,
cd9a21 ¤   0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
4e20b9 ¤   0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2, 0x0c6e4f38,
07ac40 ¤   0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
c1cec4 ¤   0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493,
ad5661 ¤   0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
2416d0 ¤   0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb,
764468 ¤   0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
88080d ¤   0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14,
e73cd7 ¤   0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,
8d9cd7 ¤   0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8,
4ed886 ¤   0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
a3576b ¤   0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495,
dd0054 ¤   0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,
1bd435 ¤   0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426,
771fc4 ¤   0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
5ebf73 ¤   0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98,
bfb500 ¤   0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,
cd418f ¤   0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, 0x7b5a41f0, 0xd37cfbad,
3a3694 ¤   0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
a05d2b ¤   0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464,
e67a9e ¤   0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
--7922 000460ab95640110068 Page 2 of Cast5Box.cpp
d478cf ¤   0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f, 0x6188b153,
8abfda ¤   0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
3927cc ¤   0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274,
b7e131 ¤   0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
09a13d ¤   0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1,
4c2f6f ¤   0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
2cc87c ¤   0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1,
0d41e0 ¤   0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,
c9714c ¤   0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, 0x474d6ad7, 0x7c0c5e5c,
e44230 ¤   0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
b3ad7b ¤   0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff,
23cdc5 ¤   0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d,
598280 ¤   0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf };
c5af5a
94be0f const PGPUInt32 S2[256] = {
a87c67 ¤   0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a,
de6e56 ¤   0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
515544 ¤   0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605,
7fc2ec ¤   0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
68401b ¤   0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b,
76382b ¤   0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
7c3748 ¤   0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083,
0d46ce ¤   0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
9bd1ce ¤   0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f,
8ff855 ¤   0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
46359b ¤   0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e,
6e8e5c ¤   0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
5a270f ¤   0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366,
90e413 ¤   0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
c48372 ¤   0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064,
4c43f0 ¤   0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
0edb95 ¤   0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6,
86637d ¤   0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
d71cdd ¤   0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364,
eda1b1 ¤   0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0f0729 ¤   0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b,
93da80 ¤   0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
6d6f3f ¤   0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c,
d16715 ¤   0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
0dad2d ¤   0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741,
4d0219 ¤   0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
d3788d ¤   0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b,
9de52a ¤   0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
deea29 ¤   0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa,
ca1cc8 ¤   0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
c7a873 ¤   0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028,
605857 ¤   0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
47be7e ¤   0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6,
8531e1 ¤   0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
f62e6d ¤   0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1,
4a525b ¤   0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
1f5bdf ¤   0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb,
bb53c0 ¤   0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
8e9754 ¤   0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d,
228440 ¤   0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
e05ef9 ¤   0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e,
53bf12 ¤   0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
d1d004 ¤   0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 };
ffaf5a
e7eb9e const PGPUInt32 S3[256] = {
b1ea5b ¤   0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b,
aaa650 ¤   0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
443f35 ¤   0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9,
ade748 ¤   0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
6b69f6 ¤   0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,
bc7f5b ¤   0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
372404 ¤   0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264,
575628 ¤   0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0654ce ¤   0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e,
fce9ec ¤   0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
3d79cb ¤   0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e,
464d5c ¤   0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
--9460 000a9c9f13540110068 Page 3 of Cast5Box.cpp
481643 ¤   0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790,
436a71 ¤   0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
c6000b ¤   0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e,
cff5d8 ¤   0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
663b89 ¤   0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8,
be6491 ¤   0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
98c2a2 ¤   0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240,
0423e6 ¤   0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
dcb251 ¤   0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c,
526d45 ¤   0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
cfde09 ¤   0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788,
ace698 ¤   0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
5baf4a ¤   0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa,
ee4955 ¤   0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
4a4c67 ¤   0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f,
87c4ad ¤   0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
dd710a ¤   0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae,
f855ec ¤   0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
d44990 ¤   0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9,
1c530e ¤   0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
db17d1 ¤   0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888,
29d4c6 ¤   0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
293174 ¤   0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2,
ba681c ¤   0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
28c1c1 ¤   0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2,
527711 ¤   0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
d90aaf ¤   0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d,
753cb6 ¤   0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
a830c6 ¤   0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00,
2415d9 ¤   0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
e1725d ¤   0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 };
35af5a
ff4b78 const PGPUInt32 S4[256] = {
e87851 ¤   0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57,
ec847f ¤   0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
7d8355 ¤   0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd,
7e1ee7 ¤   0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
914cfb ¤   0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe,
531ad7 ¤   0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
3b602d ¤   0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801,
2fea2a ¤   0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
cf98ce ¤   0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1,
2c964a ¤   0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
682361 ¤   0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3,
42f21b ¤   0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
f84ccb ¤   0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c,
e1e947 ¤   0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
7384a0 ¤   0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16,
6ed494 ¤   0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
77baa3 ¤   0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7,
140a1b ¤   0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
f36854 ¤   0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002,
44243e ¤   0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
51fd3e ¤   0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7,
75a991 ¤   0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
893778 ¤   0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff,
2c053c ¤   0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
dcf504 ¤   0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035,
f32fb9 ¤   0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
c943f4 ¤   0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec,
ec5f3b ¤   0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
dcadeb ¤   0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e,
4ec2a2 ¤   0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
d90b03 ¤   0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6,
440a1f ¤   0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
75ba2c ¤   0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f,
b13dd5 ¤   0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
4d1fd0 ¤   0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6,
7f76fd ¤   0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
530127 ¤   0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2,
e0cf57 ¤   0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
a98dc0 ¤   0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda,
--1fb7 000fb73560a40110068 Page 4 of Cast5Box.cpp
efef9f ¤   0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
4e16c7 ¤   0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6,
081560 ¤   0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
c720df ¤   0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 };
8baf5a
c91ee9 const PGPUInt32 S5[256] = {
6dbe7a ¤   0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5,
7325a4 ¤   0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00,
e0520b ¤   0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, 0xe6a2e77f, 0xf0c720cd,
f093da ¤   0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
a91c6a ¤   0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb,
383f6c ¤   0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725,
da671e ¤   0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, 0xf2f3f763, 0x68af8040,
3e53ed ¤   0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
e92ebc ¤   0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2,
69e4a9 ¤   0x2261be02, 0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
9c05ba ¤   0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900, 0xfe38d399,
cc3039 ¤   0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
277dfd ¤   0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966,
df089b ¤   0xdfdd55bc, 0x29de0655, 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468,
f48ae6 ¤   0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9,
e4bddb ¤   0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
fdff3d ¤   0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616,
a9eec9 ¤   0xf24766e3, 0x8eca36c1, 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4,
4960a0 ¤   0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419,
524a4b ¤   0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
453ec3 ¤   0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9,
04e0b7 ¤   0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6,
95a11a ¤   0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, 0x0ab378d5, 0xd951fb0c,
9c3080 ¤   0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
8bb558 ¤   0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715,
50242b ¤   0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6,
fb99f0 ¤   0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, 0x76f0ae02, 0x083be84d,
d2490c ¤   0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
e27ee9 ¤   0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba,
2af6e8 ¤   0x9cad9010, 0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
1f3ef4 ¤   0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382, 0x175683f4,
7446ef ¤   0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
804a55 ¤   0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c,
4c288d ¤   0x1ad2fff3, 0x8c25404e, 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78,
ae3915 ¤   0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87,
a47efe ¤   0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
886cf5 ¤   0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110,
863103 ¤   0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58,
c76be6 ¤   0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3,
944ce6 ¤   0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
3e518f ¤   0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d,
08b1b8 ¤   0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55,
662738 ¤   0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4 };
3daf5a
3ce05a const PGPUInt32 S6[256] = {
7343df ¤   0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4,
a99ff7 ¤   0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9,
56bab3 ¤   0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, 0x33f14961, 0xc01937bd,
6d6c26 ¤   0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
e4494b ¤   0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f,
30d958 ¤   0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c,
828b9d ¤   0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, 0xfd41197e, 0x9305a6b0,
452633 ¤   0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
319a8b ¤   0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941,
772aba ¤   0x2c0e636a, 0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
a1ee62 ¤   0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89, 0xaa928223,
f48ae0 ¤   0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
d6e1f2 ¤   0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6,
2cf1b2 ¤   0x9a69a02f, 0x68818a54, 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a,
72f8dc ¤   0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7,
840e51 ¤   0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
64bae6 ¤   0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89,
38f9f3 ¤   0xfd339fed, 0xb87834bf, 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be,
4db0b1 ¤   0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0,
9e18e8 ¤   0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
fb896c ¤   0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4,
--4f78 000d85c57e240110068 Page 5 of Cast5Box.cpp
e4b185 ¤   0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853,
a2844d ¤   0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, 0x36f73523, 0x4cfb6e87,
b3e85c ¤   0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
78c506 ¤   0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585,
168ca8 ¤   0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751,
1e57d0 ¤   0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, 0xbf32679d, 0xd45b5b75,
137273 ¤   0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
3eae39 ¤   0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283,
6cb360 ¤   0x3cc2acfb, 0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
b5a6ec ¤   0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e, 0x74719eef,
009879 ¤   0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
b3c4bf ¤   0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0,
4e21d0 ¤   0xbc60b42a, 0x953498da, 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb,
6d31d8 ¤   0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200,
80ca87 ¤   0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
7dd2ae ¤   0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf,
9f6821 ¤   0x3a479c3a, 0x5302da25, 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b,
7d5fd1 ¤   0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869,
e52f9d ¤   0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
5a109f ¤   0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb,
b09fbb ¤   0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454,
d0f24e ¤   0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f };
d7af5a
31b5cb const PGPUInt32 S7[256] = {
a98806 ¤   0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912,
7a653e ¤   0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82,
c027fe ¤   0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, 0xa05fbcf6, 0xcd4181e9,
cbda17 ¤   0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
971260 ¤   0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4,
af7566 ¤   0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9,
a74b1c ¤   0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, 0x107789be, 0xb3b2e9ce,
ddf80f ¤   0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
47e288 ¤   0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7,
d7c67e ¤   0xd0d854c0, 0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
0d66f0 ¤   0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288, 0xe1a5c06e,
f00cad ¤   0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
4abac2 ¤   0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9,
c9ddad ¤   0xc6e6fa14, 0xbae8584a, 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b,
a70198 ¤   0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3,
66b8bb ¤   0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
cd5c22 ¤   0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c,
d0ecdb ¤   0x16746233, 0x3c034c28, 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802,
385359 ¤   0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778,
5da3c3 ¤   0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
e1a723 ¤   0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be,
045a96 ¤   0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858,
c09ed6 ¤   0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, 0xf28ebfb0, 0xf5b9c310,
840c09 ¤   0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
0c02cc ¤   0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476,
32439b ¤   0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df,
2dd400 ¤   0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, 0xf22b017d, 0xa4173f70,
5b0aa5 ¤   0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
500ed8 ¤   0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a,
98e7de ¤   0x058745b9, 0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
9a7664 ¤   0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c, 0x7154c24c,
70a14f ¤   0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
9ec40c ¤   0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e,
ae59e9 ¤   0xe4f2dfa6, 0x693ed285, 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378,
9f7254 ¤   0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e,
ab04c4 ¤   0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
7d5d9a ¤   0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301,
35ceaa ¤   0xcfd2a87f, 0x60aeb767, 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2,
63bddf ¤   0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4,
8aebc7 ¤   0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
b7b38b ¤   0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021,
7d8685 ¤   0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada,
41c059 ¤   0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3 };
ebaf5a
85a987 const PGPUInt32 S8[256] = {
6ece51 ¤   0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b,
3223a5 ¤   0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174,
d85ce8 ¤   0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, 0xde9adeb1, 0x0a0cc32c,
--fd70 0013f77a17440110068 Page 6 of Cast5Box.cpp
7cb7c0 ¤   0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
1cd74d ¤   0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7,
a630ba ¤   0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164,
15bea3 ¤   0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, 0x12a8ddec, 0xfdaa335d,
a3692d ¤   0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
f087cd ¤   0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8,
a5efeb ¤   0x57e8726e, 0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
a33822 ¤   0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049, 0x2998df04,
9b4010 ¤   0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
f11e7f ¤   0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38,
cabe70 ¤   0x424f7618, 0x35856039, 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8,
2b64a7 ¤   0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354,
c16482 ¤   0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
dc180c ¤   0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160,
28060a ¤   0x7895cda5, 0x859c15a5, 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab,
334b9d ¤   0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2,
4944ac ¤   0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
c4b20a ¤   0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98,
f636ae ¤   0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441,
1bdd09 ¤   0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, 0xa842eedf, 0xfdba60b4,
e382cc ¤   0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
4b39ba ¤   0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5,
1a9702 ¤   0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c,
c66bc6 ¤   0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, 0x77853b53, 0x37effcb5,
994212 ¤   0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
de8107 ¤   0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b,
53321c ¤   0xc4248289, 0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
f7a5cb ¤   0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4, 0xe98ea084,
3c9c70 ¤   0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
79a23b ¤   0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a,
5fa7bb ¤   0xe0779695, 0xf9c17a8f, 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf,
ba2608 ¤   0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77,
d0756f ¤   0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
ccf3b6 ¤   0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f,
611e8b ¤   0xdf09822b, 0xbd691a6c, 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819,
1fbc82 ¤   0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3,
3616f6 ¤   0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
95c113 ¤   0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1,
ac49ee ¤   0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d,
3fbe53 ¤   0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e };
--c84e 001e2c39fe440110069 Page 1 of Cast5Box.h
541bc3 //////////////////////////////////////////////////////////////////////////////
ac9a02 // Cast5Box.h
e7465d //
d72fa9 // Exports for the CAST5 S-boxes.
7d1bc3 //////////////////////////////////////////////////////////////////////////////
f8af5a
055e94 // $Id: Cast5Box.h,v 1.1.2.3 1998/07/06 08:56:34 nryan Exp $
11af5a
227758 // Portions Copyright (C) 1998 by Network Associates, Inc.
9a71ae // All rights reserved.
2daf5a
dc8760 #ifndef Included_Cast5Box_h¤// [
691000 #define Included_Cast5Box_h
f6af5a
08ca3a ////////////////////
5ff648 // The CAST5 S-Boxes
3aca3a ////////////////////
2eaf5a
3478af extern const PGPUInt32 S1[256];
c2f27f extern const PGPUInt32 S2[256];
9b73c0 extern const PGPUInt32 S3[256];
d5efce extern const PGPUInt32 S4[256];
a06e71 extern const PGPUInt32 S5[256];
9ee4a1 extern const PGPUInt32 S6[256];
3c651e extern const PGPUInt32 S7[256];
39d4ac extern const PGPUInt32 S8[256];
9daf5a
e20970 #endif¤ // ] Included_Cast5Box_h
--f321 00043b7d77c4011006a Page 1 of CipherContext.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
00e3a8 // CipherContext.cpp
8c465d //
1903dd // Implementation of Class CipherContext.
931bc3 //////////////////////////////////////////////////////////////////////////////
d2af5a
a998fe // $Id: CipherContext.cpp,v 1.1.2.13.2.2 1998/10/22 00:41:41 nryan Exp $
2baf5a
44cbce // Copyright (C) 1998 by Network Associates, Inc.
1671ae // All rights reserved.
a6af5a
e36931 #if defined(PGPDISK_MFC)
f5af5a
209e12 #include "StdAfx.h"
5faf5a
a34268 #elif defined(PGPDISK_95DRIVER)
a5af5a
5e06a9 #include <vtoolscp.h>
3686d2 #include LOCKED_CODE_SEGMENT
605269 #include LOCKED_DATA_SEGMENT
4eaf5a
43f5a6 #elif defined(PGPDISK_NTDRIVER)
14af5a
53d7a1 #include <vdw.h>
28af5a
eedb21 #else
08112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
c605d6 #endif¤ // PGPDISK_MFC
23af5a
af9bcf #include "Required.h"
0cbfe9 #include "UtilityFunctions.h"
008c21 #include "CipherContext.h"
fdaf5a
a2af5a
5009b7 ////////////
dae738 // Constants
b809b7 ////////////
31af5a
d8d4f7 #define¤PGP_USE_ASSEMBLY 1
2caf5a
bb1313 const PGPUInt16¤kCipherBlockSize¤   = 512;
5d257d const PGPUInt32¤kBlockSizeIn32¤ ¤   = kCipherBlockSize / sizeof(PGPUInt32);
fbaf5a
0aaf5a
989bef //////////////////////////////////////////////
989f9a // Class CipherContext public member functions
729bef //////////////////////////////////////////////
b9af5a
6fde73 // Class CipherContext default constructor.
80af5a
13b194 CipherContext::CipherContext()
71bb36 {
ad0174 ¤   mAlgorithm¤ ¤   = kInvalidEncryptionAlgorithm;
b80e76 ¤   mInitialized¤   = FALSE;
d33598 ¤   mIsFlipped¤ ¤   = FALSE;
beefe6 }
d6af5a
52b5ce // operator= copies one CipherContext to another.
f8af5a
effeb8 CipherContext &·
19caed CipherContext::operator=(const CipherContext& from)
e2bb36 {
0b4615 ¤   PGPUInt32 i = 0;
a4af5a
bb8ffb ¤   if (this == &from)
65316c ¤   ¤   return (* this);
33af5a
8e3918 ¤   mAlgorithm¤ ¤   = from.mAlgorithm;
ff93d5 ¤   mSalt¤  ¤   ¤   = from.mSalt;
c818b4 ¤   mInitialized¤   = from.mInitialized;
de5e07 ¤   mCastCFB¤   ¤   = from.mCastCFB;
43af5a
--388b 0005b685f984011006a Page 2 of CipherContext.cpp
1280bd ¤   return (* this);
7fefe6 }
b7af5a
813fa9 // IsFlipped returns TRUE if the key is in a flipped state, FALSE otherwise.
b7af5a
3877be PGPBoolean·
842d74 CipherContext::IsFlipped()
33bb36 {
dfc601 ¤   pgpAssert(mInitialized);
2ec181 ¤   return mIsFlipped;
2eefe6 }
7baf5a
5b97b0 // FlipContext flips the bits of the key. Encryption/decryption cannot be
0f72fd // performed while the key is flipped.
a0af5a
0ac823 void·
45da07 CipherContext::FlipContext()
d7bb36 {
63c601 ¤   pgpAssert(mInitialized);
cbaf5a
141246 ¤   if (mAlgorithm == kCASTEncryptionAlgorithm)
4d9814 ¤   ¤   FlipBytes((PGPUInt8 *) &mCastCFB, sizeof(mCastCFB));
bbaf5a
9669f0 ¤   mIsFlipped = !mIsFlipped;
1defe6 }
99af5a
cf6744 // InitContext prepares the CiperContext for encryption and decryption. The
5dd0dd // 'salt' and 'key' parameters are only used for BEAs that require them.
02af5a
dac823 void·
107e83 CipherContext::InitContext(
f4627a ¤   PGPdiskEncryptionAlgorithm¤ algorithm,·
263b1a ¤   const PGPUInt8¤ ¤   ¤   ¤   *key,·
5f1e78 ¤   const PGPUInt8¤ ¤   ¤   ¤   *salt)
8dbb36 {
3951fc ¤   PGPUInt32 i;
7faf5a
3dd95d ¤   pgpAssert(algorithm != kInvalidEncryptionAlgorithm);
72af5a
95a485 ¤   DestroyContext();
dcaccf ¤   mAlgorithm = algorithm;
3faf5a
a251d0 ¤   switch (mAlgorithm)
ccc7a1 ¤   {
25af5a
60733b ¤   case kBrokenCASTEncryptionAlgorithm:
01d2cf ¤   ¤   pgpAssertAddrValid(salt, PGPUInt8);
278f0d ¤   ¤   pgpAssertAddrValid(key, PGPUInt8);
f7af5a
6edd15 ¤   ¤   pgpCopyMemory(salt, mSalt.saltBytes, sizeof(mSalt.saltBytes));
7c8d37 ¤   ¤   pgpCopyMemory(key, mCastCFB.expandedKey.keyBytes, 16);
45af5a
5120d1 #if PGP_USE_ASSEMBLY
d6af5a
ce49a1 ¤   ¤   // The key schedule for assembly must be slightly different. The
2efb9b ¤   ¤   // rotate subkeys (every second word) must be XORed with 16. This
3137b3 ¤   ¤   // swaps the halves of some words internally in a way that the code
7a68bc ¤   ¤   // expects. Don't forget this!
f6af5a
ba0867 ¤   ¤   for (i=0; i<32; i+=2)
325b34 ¤   ¤   {
94fb0e ¤   ¤   ¤   mCastCFB.expandedKey.keyDWords[i+1] =·
622f09 ¤   ¤   ¤   ¤   mCastCFB.expandedKey.keyDWords[i+1] ^ 16;
070fe4 ¤   ¤   }
34af5a
ef338f #else¤  // ] !PGP_USE_ASSEMBLY
2daf5a
c3e6cc ¤   ¤   i;¤ // get rid of unreferenced local variable error
37af5a
513d41 #endif¤ // ] PGP_USE_ASSEMBLY
95af5a
5b4a2d ¤   ¤   mInitialized = TRUE;
--e924 000117914ae4011006a Page 3 of CipherContext.cpp
4f2f68 ¤   ¤   break;
92af5a
5aa5e2 ¤   case kCASTEncryptionAlgorithm:
d7d2cf ¤   ¤   pgpAssertAddrValid(salt, PGPUInt8);
378f0d ¤   ¤   pgpAssertAddrValid(key, PGPUInt8);
b3af5a
d0dd15 ¤   ¤   pgpCopyMemory(salt, mSalt.saltBytes, sizeof(mSalt.saltBytes));
cbaf5a
413504 ¤   ¤   // Expand the key.
cb23ed ¤   ¤   CAST5schedule(mCastCFB.expandedKey.keyDWords, key);
2faf5a
c120d1 #if PGP_USE_ASSEMBLY
f8af5a
bf49a1 ¤   ¤   // The key schedule for assembly must be slightly different. The
98fb9b ¤   ¤   // rotate subkeys (every second word) must be XORed with 16. This
cf37b3 ¤   ¤   // swaps the halves of some words internally in a way that the code
9368bc ¤   ¤   // expects. Don't forget this!
1baf5a
830867 ¤   ¤   for (i=0; i<32; i+=2)
e55b34 ¤   ¤   {
0bfb0e ¤   ¤   ¤   mCastCFB.expandedKey.keyDWords[i+1] =·
4f2f09 ¤   ¤   ¤   ¤   mCastCFB.expandedKey.keyDWords[i+1] ^ 16;
a20fe4 ¤   ¤   }
eeaf5a
d6338f #else¤  // ] !PGP_USE_ASSEMBLY
04af5a
7be6cc ¤   ¤   i;¤ // get rid of unreferenced local variable error
26af5a
eb3d41 #endif¤ // ] PGP_USE_ASSEMBLY
ffaf5a
104a2d ¤   ¤   mInitialized = TRUE;
c42f68 ¤   ¤   break;
ecaf5a
300a83 ¤   case kCopyDataEncryptionAlgorithm:
bc4a2d ¤   ¤   mInitialized = TRUE;
1e2f68 ¤   ¤   break;
cbaf5a
de2f72 ¤   default:
168f52 ¤   ¤   pgpAssert(FALSE);
022f68 ¤   ¤   break;
189371 ¤   }
4defe6 }
43af5a
002ce1 // DestroyContext clears any variables used by the current cipher algorithm,
9c00e6 // then marks the context as unitialized.
fbaf5a
9f314a void
4440cd CipherContext::DestroyContext()
58bb36 {
0b8a85 ¤   if (!mInitialized)
e099bf ¤   ¤   return;
eaaf5a
3cf66c ¤   pgpAssert(mAlgorithm != kInvalidEncryptionAlgorithm);
63af5a
da51d0 ¤   switch (mAlgorithm)
81c7a1 ¤   {
3caf5a
96aa6f ¤   case kBrokenCASTEncryptionAlgorithm:·
6da5e2 ¤   case kCASTEncryptionAlgorithm:
a6db0d ¤   ¤   pgpClearMemory(&mSalt, sizeof(mSalt));
503f61 ¤   ¤   pgpClearMemory(&mCastCFB, sizeof(mCastCFB));
5aaf5a
9fcbee ¤   ¤   mInitialized = FALSE;
692f68 ¤   ¤   break;
1aaf5a
ec0a83 ¤   case kCopyDataEncryptionAlgorithm:
b7cbee ¤   ¤   mInitialized = FALSE;
d72f68 ¤   ¤   break;
13af5a
c22f72 ¤   default:
758f52 ¤   ¤   pgpAssert(FALSE);
112f68 ¤   ¤   break;
--c100 0002e1a3f114011006a Page 4 of CipherContext.cpp
a19371 ¤   }
c9efe6 }
a0af5a
938e42 // ValidateContext makes sure the context isn't damaged.
30af5a
5e2292 DualErr·
2c262b CipherContext::ValidateContext()
e0bb36 {
bf7d36 ¤   DualErr derr;
e3af5a
638a85 ¤   if (!mInitialized)
ee5a4a ¤   ¤   derr = DualErr(kPGDMinorError_ContextNotInitialized);
e4af5a
9e2361 ¤   if (derr.IsntError())
12c7a1 ¤   {
53a7b5 ¤   ¤   switch (mAlgorithm)
5b5b34 ¤   ¤   {
04af5a
a393aa ¤   ¤   case kBrokenCASTEncryptionAlgorithm:·
7ee411 ¤   ¤   case kCASTEncryptionAlgorithm:
4bbb2b ¤   ¤   ¤   if (!VerifyCastSBoxesValid())
095371 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidSBoxes);
74cdcb ¤   ¤   ¤   break;
06af5a
7604cf ¤   ¤   case kCopyDataEncryptionAlgorithm:
7fcdcb ¤   ¤   ¤   break;
0eaf5a
f59ae3 ¤   ¤   default:
0330d2 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidAlgorithm);¤   // no assert
5ccdcb ¤   ¤   ¤   break;
2b0fe4 ¤   ¤   }
c49371 ¤   }
98af5a
4a33e3 ¤   return derr;
92efe6 }
58af5a
50bd22 // CipherBlocks performs a cipher operation on the given blocks using the
853df0 // object's context.
65af5a
1bc823 void·
b35b32 CipherContext::CipherBlocks(
ffe330 ¤   PGPUInt64¤  startBlockIndex,
a716cb ¤   PGPUInt32¤  numBlocks,
ff7e7e ¤   const void¤ *src,
fdc01e ¤   void¤   ¤   *dest,
3f9985 ¤   CipherOp¤   op)
7cbb36 {
59f73b ¤   PGPUInt32¤  ¤   blockIndex;
f81b32 ¤   const PGPUInt8¤ *curSrc¤¤   = (const PGPUInt8 *) src;
b0c303 ¤   PGPUInt8¤   ¤   *curDest¤   = (PGPUInt8 *) dest;
baaf5a
f68fa5 ¤   pgpAssertAddrValid(src, VoidAlign);
211383 ¤   pgpAssertAddrValid(dest, VoidAlign);
93c601 ¤   pgpAssert(mInitialized);
a69936 ¤   pgpAssert(!mIsFlipped);
de5800 ¤   pgpAssert(numBlocks != 0);
a1af5a
cfdf90 ¤   for (blockIndex = 0; blockIndex < numBlocks; blockIndex++)
87c7a1 ¤   {
d0fbf6 ¤   ¤   PGPUInt64 seedValue = startBlockIndex + blockIndex;
17af5a
7c983f ¤   ¤   switch (op)
63d901 ¤   ¤   {¤  ¤   ¤
8b2220 ¤   ¤   case kCipherOp_Decrypt:
300c01 ¤   ¤   ¤   DecryptBlock512(seedValue, (const PGPUInt32 *) curSrc,·
fc6d9a ¤   ¤   ¤   ¤   (PGPUInt32 *) curDest);
b5cdcb ¤   ¤   ¤   break;
24af5a
dcc8b1 ¤   ¤   case kCipherOp_Encrypt:
c75a02 ¤   ¤   ¤   EncryptBlock512(seedValue, (const PGPUInt32 *) curSrc,·
f46d9a ¤   ¤   ¤   ¤   (PGPUInt32 *) curDest);
2ecdcb ¤   ¤   ¤   break;
--22ef 000ac4c438e4011006a Page 5 of CipherContext.cpp
e0af5a
c6e55a ¤   ¤   case kCipherOp_NoOp:
19cdcb ¤   ¤   ¤   break;
10af5a
fe9ae3 ¤   ¤   default:
3c0606 ¤   ¤   ¤   pgpAssert(FALSE);
1bcdcb ¤   ¤   ¤   break;
fc0fe4 ¤   ¤   }
75af5a
4f332e ¤   ¤   curSrc¤ += kCipherBlockSize;
eef8b9 ¤   ¤   curDest¤+= kCipherBlockSize;
ff9371 ¤   }
1befe6 }
acaf5a
46af5a
16edb3 ///////////////////////////////////////////////
6339b7 // Class CipherContext private member functions
44edb3 ///////////////////////////////////////////////
70af5a
7cc568 // EncryptBlock512 encrypts the given blocks using the object's context.
b3af5a
c3314a void
31259e CipherContext::EncryptBlock512(
5b60d1 ¤   PGPUInt64¤  ¤   blockNumber,
142cfb ¤   const PGPUInt32¤*src,
ef2fa2 ¤   PGPUInt32¤  ¤   *dest)
b2bb36 {
27dfc9 ¤   pgpAssertAddrValid(src, PGPUInt32);
9a43ef ¤   pgpAssertAddrValid(dest, PGPUInt32);
57c601 ¤   pgpAssert(mInitialized);
879936 ¤   pgpAssert(!mIsFlipped);
c7f66c ¤   pgpAssert(mAlgorithm != kInvalidEncryptionAlgorithm);
8667c5 ¤
cf51d0 ¤   switch (mAlgorithm)
bdc7a1 ¤   {
0caf5a
d6aa6f ¤   case kBrokenCASTEncryptionAlgorithm:·
75a5e2 ¤   case kCASTEncryptionAlgorithm:
f75b34 ¤   ¤   {
607d16 ¤   ¤   PGPUInt32 iv0, iv1, sum0, sum1;
f0af5a
113c1c ¤   ¤   pgpAssert(sizeof(mSalt.saltDWords[0]) == sizeof(PGPUInt32));
86af5a
363415 ¤   ¤   sum0 = mSalt.saltDWords[0] + GetHighDWord(blockNumber) +·
12fb9d ¤   ¤   ¤   GetLowDWord(blockNumber);
daaf5a
b0aadd ¤   ¤   sum1 = mSalt.saltDWords[1] + GetHighDWord(blockNumber) +·
d5fb9d ¤   ¤   ¤   GetLowDWord(blockNumber);
08af5a
f58dbb ¤   ¤   for (PGPUInt32 i = 0; i < kBlockSizeIn32 - 2; i++)
645b34 ¤   ¤   {
0799a5 ¤   ¤   ¤   sum1¤   += src[i];
841653 ¤   ¤   ¤   sum0¤   += sum1;¤   ¤   // simple Fletcher checksum of block
500fe4 ¤   ¤   }
5367c5 ¤
7aa5a7 ¤   ¤   iv0¤= sum0 ^ src[kBlockSizeIn32 - 2];
bfd514 ¤   ¤   iv1¤= sum1 ^ src[kBlockSizeIn32 - 1];
aa67c5 ¤
9f9100 ¤   #if PGP_USE_ASSEMBLY
82af5a
584b3f ¤   ¤   CAST5encryptCFBdblAsm(mCastCFB.expandedKey.keyDWords, iv0, iv1,·
ad7575 ¤   ¤   ¤   ~iv0, ~iv1, src, dest, kCipherBlockSize / (8+8));
5baf5a
7a933d ¤   #else¤  // !PGP_USE_ASSEMBLY
44af5a
229a68 ¤   ¤   CAST5encryptCFBdbl(mCastCFB.expandedKey.keyDWords, iv0, iv1, ~iv0,·
b3dfe1 ¤   ¤   ¤   ~iv1, src, dest, kCipherBlockSize / (8+8));
feaf5a
a909ad ¤   #endif¤ // PGP_USE_ASSEMBLY
faaf5a
de8cf3 ¤   ¤   dest[kBlockSizeIn32 - 2] ^= sum0;
ac51c1 ¤   ¤   dest[kBlockSizeIn32 - 1] ^= sum1;
--ca1d 00087e9ff924011006a Page 6 of CipherContext.cpp
b50fe4 ¤   ¤   }
892f68 ¤   ¤   break;
11af5a
870a83 ¤   case kCopyDataEncryptionAlgorithm:
571b9b ¤   ¤   pgpCopyMemory(src, dest, kCipherBlockSize);
0c2f68 ¤   ¤   break;
8eaf5a
b92f72 ¤   default:
938f52 ¤   ¤   pgpAssert(FALSE);
3a2f68 ¤   ¤   break;
cf9371 ¤   }
29efe6 }
51af5a
7a64aa // DecryptBlock512 decrypts the given blocks using the object's context.
85af5a
aa314a void
29ff74 CipherContext::DecryptBlock512(
5160d1 ¤   PGPUInt64¤  ¤   blockNumber,
762cfb ¤   const PGPUInt32¤*src,
e42fa2 ¤   PGPUInt32¤  ¤   *dest)
73bb36 {
7fdfc9 ¤   pgpAssertAddrValid(src, PGPUInt32);
2443ef ¤   pgpAssertAddrValid(dest, PGPUInt32);
45c601 ¤   pgpAssert(mInitialized);
549936 ¤   pgpAssert(!mIsFlipped);
b5f66c ¤   pgpAssert(mAlgorithm != kInvalidEncryptionAlgorithm);
71af5a
b251d0 ¤   switch (mAlgorithm)
d5c7a1 ¤   {
10af5a
adaa6f ¤   case kBrokenCASTEncryptionAlgorithm:·
2ae1f5 ¤   case kCASTEncryptionAlgorithm:·
e15b34 ¤   ¤   {
7bde6a ¤   ¤   PGPUInt32¤  iv0, iv1;
d29c97 ¤   ¤   PGPUInt32¤  kSplitPointIn32;
2bd4ce ¤   ¤   size_t¤ ¤   kBytesBeforeSplit;
2f717a ¤   ¤   size_t¤ ¤   kBytesAfterSplit;
71af5a
032f4a ¤   ¤   kSplitPointIn32¤¤   = kBlockSizeIn32/2;
8ff9d0 ¤   ¤   kBytesBeforeSplit¤  = kSplitPointIn32 * sizeof(PGPUInt32);
2148f2 ¤   ¤   kBytesAfterSplit¤   = (kBlockSizeIn32-kSplitPointIn32) *·
d6edfd ¤   ¤   ¤   sizeof(PGPUInt32);
c9af5a
5d9100 ¤   #if PGP_USE_ASSEMBLY
45af5a
6eaa11 ¤   ¤   // This must be done in two halves to recover the IV.
ca9cc2 ¤   ¤   CAST5decryptCFBdblAsm(mCastCFB.expandedKey.keyDWords,
9c96ee ¤   ¤   ¤   src[kSplitPointIn32 - 4], src[kSplitPointIn32 - 3],
bb6db2 ¤   ¤   ¤   src[kSplitPointIn32 - 2], src[kSplitPointIn32 - 1],
a89138 ¤   ¤   ¤   src + kSplitPointIn32, dest + kSplitPointIn32,·
3130a6 ¤   ¤   ¤   kBytesAfterSplit/(8+8));
afaf5a
ce5707 ¤   ¤   iv0¤= dest[kBlockSizeIn32 - 2];
a85239 ¤   ¤   iv1¤= dest[kBlockSizeIn32 - 1];
e6af5a
9f3bc8 ¤   ¤   CAST5decryptCFBdblAsm(mCastCFB.expandedKey.keyDWords, iv0, iv1,·
492f89 ¤   ¤   ¤   ~iv0, ~iv1, src, dest, kBytesBeforeSplit/(8+8));
16af5a
cb6358 ¤   #else¤  // PGP_USE_ASSEMBLY
f7af5a
7caa11 ¤   ¤   // This must be done in two halves to recover the IV.
dccf7c ¤   ¤   CAST5decryptCFBdbl(mCastCFB.expandedKey.keyDWords,
8f96ee ¤   ¤   ¤   src[kSplitPointIn32 - 4], src[kSplitPointIn32 - 3],
ac6db2 ¤   ¤   ¤   src[kSplitPointIn32 - 2], src[kSplitPointIn32 - 1],
149138 ¤   ¤   ¤   src + kSplitPointIn32, dest + kSplitPointIn32,·
9d30a6 ¤   ¤   ¤   kBytesAfterSplit/(8+8));
28af5a
065707 ¤   ¤   iv0¤= dest[kBlockSizeIn32 - 2];
295239 ¤   ¤   iv1¤= dest[kBlockSizeIn32 - 1];
2daf5a
306a9d ¤   ¤   CAST5decryptCFBdbl(mCastCFB.expandedKey.keyDWords, iv0, iv1, ~iv0,·
87c9d6 ¤   ¤   ¤   ~iv1, src, dest, kBytesBeforeSplit/(8+8));
--cd4c 001e27529144011006a Page 7 of CipherContext.cpp
e0af5a
bd09ad ¤   #endif¤ // PGP_USE_ASSEMBLY
1eaf5a
a6529a ¤   ¤   // Undo the checksum.
4c19d9 ¤   ¤   iv0 = mSalt.saltDWords[0] + GetHighDWord(blockNumber) +·
7afb9d ¤   ¤   ¤   GetLowDWord(blockNumber);
6baf5a
9e8711 ¤   ¤   iv1 = mSalt.saltDWords[1] + GetHighDWord(blockNumber) +·
d2fb9d ¤   ¤   ¤   GetLowDWord(blockNumber);
47af5a
788dbb ¤   ¤   for (PGPUInt32 i = 0; i < kBlockSizeIn32 - 2; i++)
505b34 ¤   ¤   {
614750 ¤   ¤   ¤   iv1¤+= dest[i];
5271dc ¤   ¤   ¤   iv0¤+= iv1;
0d0fe4 ¤   ¤   }
23af5a
651016 ¤   ¤   dest[kBlockSizeIn32 - 2]¤   ^= iv0;
35c9f4 ¤   ¤   dest[kBlockSizeIn32 - 1]¤   ^= iv1;
060fe4 ¤   ¤   }
e02f68 ¤   ¤   break;
d4af5a
820a83 ¤   case kCopyDataEncryptionAlgorithm:
471b9b ¤   ¤   pgpCopyMemory(src, dest, kCipherBlockSize);
da2f68 ¤   ¤   break;
8caf5a
712f72 ¤   default:
7f8f52 ¤   ¤   pgpAssert(FALSE);
142f68 ¤   ¤   break;
849371 ¤   }
e2efe6 }
--8454 000b6b002574011006b Page 1 of CipherContext.h
541bc3 //////////////////////////////////////////////////////////////////////////////
9c8ea7 // CipherContext.h
1d465d //
34fe47 // Declaration of class CipherContext.
221bc3 //////////////////////////////////////////////////////////////////////////////
c6af5a
3c4ce4 // $Id: CipherContext.h,v 1.1.2.9 1998/07/06 08:56:36 nryan Exp $
35af5a
3dcbce // Copyright (C) 1998 by Network Associates, Inc.
f971ae // All rights reserved.
49af5a
bd5fd3 #ifndef Included_CipherContext_h¤   // [
20ba2d #define Included_CipherContext_h
6baf5a
aac16a #include "PGPdiskFileFormat.h"
6170d4 #include "SecureMemory.h"
e1af5a
e869ea #include "Cast5.h"
24af5a
75e79f // Align to 1.
08fcdb #pragma pack(push, 1)
88af5a
f6d557 ////////
6a02c9 // Types
b6d557 ////////
68af5a
0a8193 // A CipherOp specifies which cipher operation should be performed.
02af5a
495fb3 enum CipherOp
a9bb36 {
7f5c79 ¤   kCipherOp_NoOp¤ ¤   = 0,
be6784 ¤   kCipherOp_Encrypt¤  = 1,
959107 ¤   kCipherOp_Decrypt¤  = 2
ae82f7 };
dfaf5a
35af5a
5417a3 //////////////////////
901bb3 // Class CipherContext
9017a3 //////////////////////
3daf5a
af28a7 class CipherContext
bdbb36 {
935ed4 public:
a236f2 ¤   ¤   ¤   ¤   ¤   CipherContext();
144bd8 ¤   ¤   ¤   ¤   ¤   ~CipherContext() {DestroyContext();};
e3af5a
ad60d1 ¤   CipherContext &¤operator=(const CipherContext& from);
a8af5a
cd486a ¤   PGPBoolean¤ ¤   IsFlipped();
12ab4f ¤   void¤   ¤   ¤   FlipContext();
16af5a
fc82c8 ¤   void¤   ¤   ¤   InitContext(PGPdiskEncryptionAlgorithm algorithm,·
b8bae3 ¤   ¤   ¤   ¤   ¤   ¤   const PGPUInt8 *key, const PGPUInt8 *salt);
acb200 ¤   void¤   ¤   ¤   DestroyContext();
ed2d23 ¤   DualErr¤¤   ¤   ValidateContext();
95af5a
28e5fd ¤   void¤   ¤   ¤   CipherBlocks(PGPUInt64 startBlockIndex,·
6e7e28 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 numBlocks, const void *src, void *dest,·
5e4aac ¤   ¤   ¤   ¤   ¤   ¤   CipherOp op);
54af5a
570fb9 private:
5db8ef ¤   PGPdiskEncryptionAlgorithm¤ mAlgorithm;¤¤   // encryption algorithm used
314af0 ¤   PassphraseSalt¤ ¤   ¤   ¤   mSalt;¤ ¤   ¤   // random salt data
4b8a72 ¤   PGPBoolean¤ ¤   ¤   ¤   ¤   mInitialized;¤  // initialized context?
5cf173 ¤   PGPBoolean¤ ¤   ¤   ¤   ¤   mIsFlipped;¤¤   // is the key flipped?
9faf5a
195fce ¤   CASTCFBContext¤ ¤   ¤   ¤   mCastCFB;¤  ¤   // context for CAST cipher
1caf5a
6e02d0 ¤   void¤   EncryptBlock512(PGPUInt64 blockNumber, const PGPUInt32 *src,·
d72413 ¤   ¤   ¤   ¤   PGPUInt32 *dest);
ba4057 ¤   void¤   DecryptBlock512(PGPUInt64 blockNumber, const PGPUInt32 *src,·
b62413 ¤   ¤   ¤   ¤   PGPUInt32 *dest);
--679f 00190fe72d34011006b Page 2 of CipherContext.h
8082f7 };
abaf5a
d51cb1 // Restore alignment.
50f421 #pragma pack(pop)
21af5a
90951c #endif¤ // ] Included_CipherContext_h
--6fb8 00097b7ff514011006c Page 1 of CipherUtils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
8d5dcc // CipherUtils.cpp
e1465d //
01f63e // Various cipher utility functions.
991bc3 //////////////////////////////////////////////////////////////////////////////
e7af5a
cae5d6 // $Id: CipherUtils.cpp,v 1.1.2.15 1998/07/20 08:20:33 nryan Exp $
f1af5a
e2cbce // Copyright (C) 1998 by Network Associates, Inc.
6271ae // All rights reserved.
efaf5a
2a6931 #if defined(PGPDISK_MFC)
3eaf5a
eb9e12 #include "StdAfx.h"
fab8af #include <new.h>
2baf5a
764268 #elif defined(PGPDISK_95DRIVER)
d7af5a
9a06a9 #include <vtoolscp.h>
413a08 #include "PlacementNew.h"
28af5a
5086d2 #include LOCKED_CODE_SEGMENT
875269 #include LOCKED_DATA_SEGMENT
57af5a
fcf5a6 #elif defined(PGPDISK_NTDRIVER)
d1af5a
5fd7a1 #include <vdw.h>
51feb2 #include <stdio.h>
b7bea3 #include <stdlib.h>
6daf5a
39db21 #else
f7112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
9c05d6 #endif¤ // PGPDISK_MFC
f4af5a
2f9bcf #include "Required.h"
19c16a #include "PGPdiskFileFormat.h"
1870d4 #include "SecureMemory.h"
8caf5a
3b69ea #include "Cast5.h"
cb8f51 #include "CipherUtils.h"
584818 #include "SHA.h"
0faf5a
31af5a
28b352 //////////////////////////
16f78b // Ciper utility functions
deb352 //////////////////////////
c5af5a
c8ddf0 // ContinueCRC32 generates a CRC.
48af5a
181dbe CRC32
8de5b2 ComputeCRC32(const PGPUInt32 *theDWords, PGPUInt32 nDWords)
0cbb36 {
e82230 ¤   return (ContinueCRC32(theDWords, nDWords, 0));
6aefe6 }
0caf5a
94d5ae // ContinueCRC32 continues a CRC.
4d67c5 ¤
6279a4 CRC32·
fa31f7 ContinueCRC32(
023bca ¤   const PGPUInt32 *theDWords,·
ae96d0 ¤   PGPUInt32¤  ¤   nDWords,·
8f0269 ¤   CRC32¤  ¤   ¤   startCRC)
ccbb36 {
950e4a ¤   PGPUInt32¤  ¤   k4C11DB7¤   = 0x04C11DB7;
e66e03 ¤   CRC32¤  ·¤  ¤   crc¤¤   ¤   = startCRC;
cbabf9 ¤   PGPUInt32 const¤*curDWord ¤ = theDWords;
43a878 ¤   PGPUInt32 const¤*lastDWord¤ = theDWords + (nDWords - 1);
d7af5a
434052 ¤   while (curDWord <= lastDWord )
02c7a1 ¤   {
5ad49f ¤   ¤   PGPUInt8¤   ¤   bytes[4];
976309 ¤   ¤   const PGPUInt8¤ *curByte;
--301c 0005e6de81c4011006c Page 2 of CipherUtils.cpp
4a9450 ¤   ¤   PGPInt32¤   ¤   remaining;
712975 ¤   ¤   PGPUInt32¤  ¤   theDWord;
171b52 ¤   ¤
b2b239 ¤   ¤   // We want an endian-independent CRC - place the bytes in big-endian
73d750 ¤   ¤   // order.
1eaf5a
045471 ¤   ¤   theDWord = (* curDWord++);
bcaf5a
56fe73 ¤   ¤   bytes[0]¤   = (PGPUInt8) (theDWord >> 24) & 0xFF;
7e52f8 ¤   ¤   bytes[1]¤   = (PGPUInt8) (theDWord >> 16) & 0xFF;
dd775c ¤   ¤   bytes[2]¤   = (PGPUInt8) (theDWord >> 8) & 0xFF;
d01cb1 ¤   ¤   bytes[3]¤   = (PGPUInt8) theDWord & 0xFF;
721b52 ¤   ¤
9ee463 ¤   ¤   remaining = 4;
48af8f ¤   ¤   curByte = bytes;
2baf5a
bf680c ¤   ¤   while (remaining-- != 0)
8f5b34 ¤   ¤   {
868701 ¤   ¤   ¤   PGPInt32 check;
59af5a
f7e109 ¤   ¤   ¤   crc ^= ((PGPInt32 ) (* curByte)) << 8;
11f03d ¤   ¤   ¤   ++curByte;
73af5a
b87577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
d77577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
227577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
7f7577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
f47577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
cf7577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
437577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
3e7577 ¤   ¤   ¤   check = crc; crc <<= 1; if (check < 0) crc ^= k4C11DB7;
0d0fe4 ¤   ¤   }
b39371 ¤   }
25af5a
11ba79 ¤   return crc;
93efe6 }
bcaf5a
5b86a6 // HashBuf hashes the given buffer in locked memory and stores the result in
e949bf // the key parameter.
13af5a
d8e677 DualErr
6ec758 HashBuf(const PGPUInt8 *buf, PGPUInt16 length, EncryptedCASTKey *key)
6fbb36 {
029a95 ¤   DualErr¤¤   ¤   derr;
c0ab38 ¤   SHA¤¤   ¤   ¤   *hash¤  = NULL;
cca12e ¤   SHA::Digest¤¤   hashResult;
e762dd ¤   SecureMemory¤   smHash(sizeof(SHA));
dcaf5a
d2b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
1ade54 ¤   pgpAssertAddrValid(key, EncryptedCASTKey);
a8af5a
cf5eb1 ¤   // Did we get our memory?
b39273 ¤   derr = smHash.mInitErr;
23af5a
272361 ¤   if (derr.IsntError())
49c7a1 ¤   {
6b96f8 ¤   ¤   hash = new (smHash.GetPtr()) SHA;¤  ¤   // <new.h>
47af5a
2b0211 ¤   ¤   hash->Update(buf, length);
ea7782 ¤   ¤   hash->Final(&hashResult);
4aaf5a
183b56 ¤   ¤   pgpCopyMemory(hashResult.bytes, key->keyBytes, sizeof(key->keyBytes));
eb9371 ¤   }
b7af5a
ab4130 ¤   if (hash)
26c7a1 ¤   {
521198 ¤   ¤   hash->~SHA();
469371 ¤   }
c8af5a
6f33e3 ¤   return derr;
b3efe6 }
5eaf5a
--689f 00085d7b6b44011006c Page 3 of CipherUtils.cpp
e5a23b // SaltPassphrase hashes a passphrase with the given salt bytes in a locked
7a5a64 // memory buffer.
68af5a
ebe677 DualErr
219c8e SaltPassphrase(
18fe3e ¤   const EncryptedCASTKey¤ *keyin,
7b40b7 ¤   EncryptedCASTKey¤   ¤   *keyout,
cd9f98 ¤   const PassphraseSalt¤   *salt,
6bb10d ¤   PGPUInt16¤  ¤   ¤   ¤   *hashReps)
54bb36 {
869a95 ¤   DualErr¤¤   ¤   derr;
e1be60 ¤   PGPUInt8¤   ¤   j;
f5cb07 ¤   PGPUInt16¤  ¤   i, k;
04ab38 ¤   SHA¤¤   ¤   ¤   *hash¤  = NULL;
a5a12e ¤   SHA::Digest¤¤   hashResult;
a062dd ¤   SecureMemory¤   smHash(sizeof(SHA));
ffaf5a
385f84 ¤   pgpAssertAddrValid(keyin, EncryptedCASTKey);
2c2f3e ¤   pgpAssertAddrValid(keyout, EncryptedCASTKey);
14f904 ¤   pgpAssertAddrValid(salt, PassphraseSalt);
b4c091 ¤   pgpAssertAddrValid(hashReps, PGPUInt16);
eaaf5a
f9c13e ¤   // Did we get our locked memory?
8f9273 ¤   derr = smHash.mInitErr;
29af5a
bb2361 ¤   if (derr.IsntError())
1bc7a1 ¤   {
1b5a36 ¤   ¤   hash = new (smHash.GetPtr()) SHA;¤  ¤   // placement new
fb4a39 ¤   ¤   hash->Update(salt->saltBytes, sizeof(salt->saltBytes));
1baf5a
14178c ¤   ¤   if ((* hashReps) != 0)
885b34 ¤   ¤   {
78867b ¤   ¤   ¤   // Hash the passphrase and a rotating byte counter the specified
2e2ff7 ¤   ¤   ¤   // number of times into the hash field with the 8 bytes of salt
7331b0 ¤   ¤   ¤   // from above in order to form the session key to decrypt the
f5a247 ¤   ¤   ¤   // master key.
d8af5a
8e4522 ¤   ¤   ¤   k = (* hashReps);
0daf5a
c37446 ¤   ¤   ¤   for (i=0, j=0; i<k; i++, j++)
9df776 ¤   ¤   ¤   {
89c4a9 ¤   ¤   ¤   ¤   hash->Update(keyin->keyBytes, sizeof(keyin->keyBytes));
e3b39e ¤   ¤   ¤   ¤   hash->Update(&j, 1);
31a3a6 ¤   ¤   ¤   }
9f0fe4 ¤   ¤   }
2e0e1d ¤   ¤   else
bd5b34 ¤   ¤   {
ddb421 ¤   ¤   ¤   PGPUInt64 endTicks;
72af5a
6e9b24 ¤   ¤   ¤   // This is a new disk or we are changing the passphrase. ·We hash
a0741a ¤   ¤   ¤   // the passphrase in with a rotating counter byte an arbitrary
ece341 ¤   ¤   ¤   // number of times based on the processing power of the computer
5eed7b ¤   ¤   ¤   // we're running on up to a maximum of 16000.
8aaf5a
f6a24d ¤   ¤   ¤   endTicks = PGPdiskGetTicks() + 500;¤// 500 ms
f6af5a
7d2231 ¤   ¤   ¤   for (i=0, j=0; (PGPdiskGetTicks() < endTicks) && (i < 16000);·
63a7b8 ¤   ¤   ¤   ¤   i++, j++)
0df776 ¤   ¤   ¤   {
96c4a9 ¤   ¤   ¤   ¤   hash->Update(keyin->keyBytes, sizeof(keyin->keyBytes));
8ab39e ¤   ¤   ¤   ¤   hash->Update(&j, 1);
afa3a6 ¤   ¤   ¤   }
4daf5a
9d0108 ¤   ¤   ¤   (* hashReps) = i;
c30fe4 ¤   ¤   }
ab9371 ¤   }
22af5a
f12361 ¤   if (derr.IsntError())
17c7a1 ¤   {
fc7782 ¤   ¤   hash->Final(&hashResult);
3faf5a
85c295 ¤   ¤   pgpCopyMemory(hashResult.bytes, keyout->keyBytes,·
--ed78 0009772a9934011006c Page 4 of CipherUtils.cpp
2f19cf ¤   ¤   ¤   sizeof(keyout->keyBytes));
a89371 ¤   }
88af5a
c54130 ¤   if (hash)
94c7a1 ¤   {
041198 ¤   ¤   hash->~SHA();
d29371 ¤   }
ecaf5a
a033e3 ¤   return derr;
68efe6 }
0daf5a
989877 // HashSaltAndSchedule hashes, salts, and expands the given passphrase.
9daf5a
f2e677 DualErr
2f9ff7 HashSaltAndSchedule(
acd0d9 ¤   const SecureString¤ ¤   *passphrase,·
7b2422 ¤   ExpandedCASTKey¤¤   ¤   *expandedKey,·
943d12 ¤   const PassphraseSalt¤   *salt,·
2fc7a5 ¤   PGPUInt16¤  ¤   ¤   ¤   *hashReps,·
a1d998 ¤   EncryptedCASTKey¤   ¤   *outKey)
06bb36 {
92705b ¤   DualErr¤¤   ¤   ¤   derr;
eed65d ¤   EncryptedCASTKey¤   *key;
68feab ¤   PGPUInt8¤   ¤   ¤   *secureBuf;
5baf5a
30fa73 ¤   SecureMemory¤   smKey(sizeof(EncryptedCASTKey));
d51ed1 ¤   SecureMemory¤   smSecureBuf(kMaxPassphraseLength);
f2af5a
d9c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
1918d7 ¤   pgpAssertAddrValid(expandedKey, ExpandedCASTKey);
aef904 ¤   pgpAssertAddrValid(salt, PassphraseSalt);
23c091 ¤   pgpAssertAddrValid(hashReps, PGPUInt16);
c7af5a
92c13e ¤   // Did we get our locked memory?
046d26 ¤   derr = smKey.mInitErr;
2baf5a
782361 ¤   if (derr.IsntError())
a4c7a1 ¤   {
a076f9 ¤   ¤   derr = smSecureBuf.mInitErr;
4b9371 ¤   }
49af5a
d65b2f ¤   // Set up our pointers.
602361 ¤   if (derr.IsntError())
32c7a1 ¤   {
c94ef9 ¤   ¤   key¤¤   ¤   = (EncryptedCASTKey *) smKey.GetPtr();
0e5a6d ¤   ¤   secureBuf¤  = (PGPUInt8 *) smSecureBuf.GetPtr();
06af5a
b5ef2d ¤   ¤   // Hash the passphrase.
48f9f9 ¤   ¤   passphrase->GetString((LPSTR) secureBuf, kMaxStringSize);
4f0d98 ¤   ¤   derr = HashBuf(secureBuf, (PGPUInt16) passphrase->GetLength(), key);
3f9371 ¤   }
a9af5a
3712e3 ¤   // Salt the passphrase.
cb2361 ¤   if (derr.IsntError())
4ec7a1 ¤   {
a77dc4 ¤   ¤   derr = SaltPassphrase(key, key, salt, hashReps);
329371 ¤   }
b2af5a
7f2361 ¤   if (derr.IsntError())
2ac7a1 ¤   {
b23504 ¤   ¤   // Expand the key.
6d3274 ¤   ¤   CAST5schedule(expandedKey->keyDWords, key->keyBytes);
e2af5a
81cc9f ¤   ¤   // Feed the caller the encrypted key if he provided a pointer.
dceb64 ¤   ¤   if (IsntNull(outKey))
f95b34 ¤   ¤   {
86ba0d ¤   ¤   ¤   (* outKey) = (* key);
9b0fe4 ¤   ¤   }
639371 ¤   }
f3af5a
7a33e3 ¤   return derr;
97efe6 }
--748c 00031fe58564011006c Page 5 of CipherUtils.cpp
e0af5a
f76e35 // DecryptPassphraseKey decrypts a header key using a passphrase.
7baf5a
212292 DualErr·
41cf05 DecryptPassphraseKey(
e0789d ¤   const PassphraseKey¤¤   *passKey,
0641bc ¤   const PassphraseSalt ¤  *salt,
3ff8c5 ¤   SecureString¤   ¤   ¤   *passphrase,
0589fa ¤   CASTKey¤¤   ¤   ¤   ¤   *decryptedKey)
dbbb36 {
a2b03b ¤   CheckBytes¤ ¤   ¤   checkBytes;
0f705b ¤   DualErr¤¤   ¤   ¤   derr;
21d65d ¤   EncryptedCASTKey¤   *key;
150f09 ¤   ExpandedCASTKey¤¤   *expandedKey;
5688b8 ¤   PGPUInt16¤  ¤   ¤   hashReps;
60af5a
32b8a7 ¤   SecureMemory¤   smEncryptionKey(sizeof(CASTKey));
1d5500 ¤   SecureMemory¤   smExpandedKey(sizeof(ExpandedCASTKey));
e1af5a
1153e7 ¤   pgpAssertAddrValid(passKey, PassphraseKey);
ebf904 ¤   pgpAssertAddrValid(salt, PassphraseSalt);
34c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
fa448c ¤   pgpAssertAddrValid(decryptedKey, CASTKey);
b4af5a
77c13e ¤   // Did we get our locked memory?
048287 ¤   derr = smEncryptionKey.mInitErr;¤
7daf5a
e82361 ¤   if (derr.IsntError())
ecc7a1 ¤   {
1618c0 ¤   ¤   derr = smExpandedKey.mInitErr;
af9371 ¤   }
eaaf5a
4e2361 ¤   if (derr.IsntError())
36c7a1 ¤   {
f0c762 ¤   ¤   // Initialize pointer to our locked memory.
b072f1 ¤   ¤   key¤¤   ¤   = (EncryptedCASTKey *) smEncryptionKey.GetPtr();
e12327 ¤   ¤   expandedKey = (ExpandedCASTKey *) smExpandedKey.GetPtr();
3faf5a
155a28 ¤   ¤   hashReps = passKey->hashReps;
6baf5a
f7b6cf ¤   ¤   // Hash, salt, and expand the passphrase.
937259 ¤   ¤   derr = HashSaltAndSchedule(passphrase, expandedKey, salt, &hashReps,·
9a5942 ¤   ¤   ¤   key);
7a9371 ¤   }
15af5a
372361 ¤   if (derr.IsntError())
dac7a1 ¤   {
dcff1c ¤   ¤   (* decryptedKey) = passKey->encryptedKey;
a887c7 ¤   ¤   ¤
5dc46c ¤   ¤   // Decrypt the encrypted key.
300cf2 ¤   ¤   CAST5decrypt(&decryptedKey->keyBytes[0],·
1403f2 ¤   ¤   ¤   &decryptedKey->keyBytes[0], expandedKey->keyDWords);
3daf5a
ba56d2 ¤   ¤   CAST5decrypt(&decryptedKey->keyBytes[8],·
f1f20d ¤   ¤   ¤   &decryptedKey->keyBytes[8], expandedKey->keyDWords);
56af5a
9ae908 ¤   ¤   // Get the ckeck bytes
adc58d ¤   ¤   checkBytes = passKey->checkBytes;
ff67c5 ¤
ec0767 ¤   ¤   // Decrypt the check bytes using the expanded key
21738a ¤   ¤   CAST5decrypt(checkBytes.theBytes, checkBytes.theBytes,·
2cee65 ¤   ¤   ¤   expandedKey->keyDWords);
3baf5a
d46bde ¤   ¤   // Compare the check bytes against the encrypted key for equality.
3af5a5 ¤   ¤   if (!pgpMemoryEqual(&checkBytes.theBytes[0], &key->keyBytes[0],·
cf8918 ¤   ¤   ¤   sizeof(checkBytes)))
165b34 ¤   ¤   {
fb5fa1 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IncorrectPassphrase);
260fe4 ¤   ¤   }
4f9371 ¤   }
8867c5 ¤
3133e3 ¤   return derr;
--bd1b 001ac40e9ba4011006c Page 6 of CipherUtils.cpp
7aefe6 }
46af5a
b641f8 // EncryptPassphraseKey encrypts a header key using a passphrase.
e1af5a
4d2292 DualErr·
148c9d EncryptPassphraseKey(
f2f742 ¤   CASTKey¤¤   ¤   ¤   ¤   *decryptedKey,
3a41bc ¤   const PassphraseSalt ¤  *salt,
95f8c5 ¤   SecureString¤   ¤   ¤   *passphrase,
e9019b ¤   PassphraseKey¤  ¤   ¤   *passKey)
18bb36 {
2a705b ¤   DualErr¤¤   ¤   ¤   derr;
e0d65d ¤   EncryptedCASTKey¤   *key;
330f09 ¤   ExpandedCASTKey¤¤   *expandedKey;
b6af5a
2eb8a7 ¤   SecureMemory¤   smEncryptionKey(sizeof(CASTKey));
d05500 ¤   SecureMemory¤   smExpandedKey(sizeof(ExpandedCASTKey));
3caf5a
0a53e7 ¤   pgpAssertAddrValid(passKey, PassphraseKey);
95f904 ¤   pgpAssertAddrValid(salt, PassphraseSalt);
45c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
99448c ¤   pgpAssertAddrValid(decryptedKey, CASTKey);
e0af5a
6bc13e ¤   // Did we get our locked memory?
058287 ¤   derr = smEncryptionKey.mInitErr;¤
ffaf5a
a32361 ¤   if (derr.IsntError())
5cc7a1 ¤   {
c418c0 ¤   ¤   derr = smExpandedKey.mInitErr;
569371 ¤   }
d0af5a
fc2361 ¤   if (derr.IsntError())
85c7a1 ¤   {
b7c762 ¤   ¤   // Initialize pointer to our locked memory.
f072f1 ¤   ¤   key¤¤   ¤   = (EncryptedCASTKey *) smEncryptionKey.GetPtr();
452327 ¤   ¤   expandedKey = (ExpandedCASTKey *) smExpandedKey.GetPtr();
a3af5a
4b1113 ¤   ¤   passKey->hashReps = 0;
16af5a
4eb6cf ¤   ¤   // Hash, salt, and expand the passphrase.
134109 ¤   ¤   derr = HashSaltAndSchedule(passphrase, expandedKey, salt,·
2b5e76 ¤   ¤   ¤   &passKey->hashReps, key);
4e9371 ¤   }
b5af5a
fc2361 ¤   if (derr.IsntError())
25c7a1 ¤   {
a0ae1b ¤   ¤   passKey->encryptedKey = (* decryptedKey);
14af5a
0fde01 ¤   ¤   // Encrypt the key with the new salted passphrase.
abbda3 ¤   ¤   CAST5encrypt(&passKey->encryptedKey.keyBytes[0],·
b2f775 ¤   ¤   ¤   &passKey->encryptedKey.keyBytes[0], expandedKey->keyDWords);
ddaf5a
42e783 ¤   ¤   CAST5encrypt(&passKey->encryptedKey.keyBytes[8],·
0c068a ¤   ¤   ¤   &passKey->encryptedKey.keyBytes[8], expandedKey->keyDWords);
f8af5a
df77bc ¤   ¤   // Encrypt the new key itself for checkbytes purposes.
77e090 ¤   ¤   CAST5encrypt(key->keyBytes, key->keyBytes, expandedKey->keyDWords);
3caf5a
814f20 ¤   ¤   for (PGPUInt16 i=0; i < sizeof(passKey->checkBytes); i++)
6f5b34 ¤   ¤   {
a26db5 ¤   ¤   ¤   passKey->checkBytes.theBytes[i] = key->keyBytes[i];
b00fe4 ¤   ¤   }
9c9371 ¤   }
d2af5a
a933e3 ¤   return derr;
acefe6 }
--d08f 001590d7d364011006d Page 1 of CipherUtils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
651e35 // CipherUtils.h
f7465d //
d6eb68 // Declarations for CipherUtils.cpp.
431bc3 //////////////////////////////////////////////////////////////////////////////
20af5a
cab8fb // $Id: CipherUtils.h,v 1.1.2.6 1998/07/06 08:56:37 nryan Exp $
eaaf5a
a5cbce // Copyright (C) 1998 by Network Associates, Inc.
4171ae // All rights reserved.
cfaf5a
9b9cdd #ifndef Included_CipherUtils_h¤ // [
f8c11f #define Included_CipherUtils_h
e8af5a
d885af #include "SecureString.h"
6caf5a
d369ea #include "Cast5.h"
94af5a
9aaf5a
ccd557 ////////
d102c9 // Types
d0d557 ////////
22af5a
86a888 typedef PGPUInt32 CRC32;
2abc17 typedef struct PassphraseKey PassphraseKey;
ffaf5a
48af5a
f36cc2 /////////////////////
f4bf67 // Exported Functions
ea6cc2 /////////////////////
78af5a
ef367c CRC32¤  ComputeCRC32(const PGPUInt32 *theDWords, PGPUInt32 nDWords);
071a7f CRC32¤  ContinueCRC32(const PGPUInt32 *theDWords, PGPUInt32 nDWords,·
062a92 ¤   ¤   ¤   CRC32 startCRC);
7baf5a
88f87e DualErr¤HashBuf(const PGPUInt8 *buf, PGPUInt16 length, EncryptedCASTKey *key);
92af5a
9aa658 DualErr¤SaltPassphrase(const EncryptedCASTKey *keyin,·
7aa570 ¤   ¤   ¤   EncryptedCASTKey *keyout, const PassphraseSalt *salt,·
c7627a ¤   ¤   ¤   PGPUInt16 *hashReps);
73af5a
16915d DualErr¤HashSaltAndSchedule(const SecureString *passphrase,·
e22e79 ¤   ¤   ¤   ExpandedCASTKey *expandedKey, const PassphraseSalt *salt,·
029a85 ¤   ¤   ¤   PGPUInt16 *hashReps, EncryptedCASTKey *outKey = NULL);
1eaf5a
2a8efd DualErr¤DecryptPassphraseKey(const PassphraseKey *passKey,·
5d4d9e ¤   ¤   ¤   const PassphraseSalt *salt, SecureString *passphrase,·
5ecdcd ¤   ¤   ¤   CASTKey *decryptedKey);
02af5a
80a3cd DualErr¤EncryptPassphraseKey(CASTKey *decryptedKey,·
e14d9e ¤   ¤   ¤   const PassphraseSalt *salt, SecureString *passphrase,·
2f062c ¤   ¤   ¤   PassphraseKey *passKey);
e5af5a
59034e #endif¤ // ] Included_CipherUtils_h
--85c8 000679fdf824011006e Page 1 of PGPdiskRandomPool.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
369086 // PGPdiskRandomPool.cpp
bc465d //
d5efe6 // Implementation of class PGPdiskRandomPool.
ec1bc3 //////////////////////////////////////////////////////////////////////////////
a2af5a
2dcf83 // $Id: PGPdiskRandomPool.cpp,v 1.1.2.11.2.1 1998/10/28 01:42:33 nryan Exp $
e0af5a
5fcbce // Copyright (C) 1998 by Network Associates, Inc.
e571ae // All rights reserved.
0daf5a
7f6931 #if defined(PGPDISK_MFC)
23af5a
1e9e12 #include "StdAfx.h"
0faf5a
344268 #elif defined(PGPDISK_95DRIVER)
2aaf5a
3006a9 #include <vtoolscp.h>
ec86d2 #include LOCKED_CODE_SEGMENT
f65269 #include LOCKED_DATA_SEGMENT
89af5a
3ef5a6 #elif defined(PGPDISK_NTDRIVER)
8faf5a
a1d7a1 #include <vdw.h>
2baf5a
f4db21 #else
b4112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
dd05d6 #endif¤ // PGPDISK_MFC
36af5a
a59bcf #include "Required.h"
e7bfe9 #include "UtilityFunctions.h"
4baf5a
25b1e1 #include "PGPdiskRandomPool.h"
ee4818 #include "SHA.h"
2faf5a
d8af5a
e09b9e //////////////////////////////////////////////////
804f9c // Class PGPdiskRandomPool public member functions
4d9b9e //////////////////////////////////////////////////
2aaf5a
331961 // The PGPdiskRandomPool default constructor.
c6af5a
369772 PGPdiskRandomPool::PGPdiskRandomPool(PGPUInt32 poolBits)
4abb36 {
54afaf ¤   // The pool must be a multiple of the 16-byte (128-bit) SHA1 block size.
67ff8c ¤   pgpAssert(poolBits%128 == 0);
0daf5a
a13f43 ¤   mRandomPoolBits = poolBits;
afdbed ¤   mRandomKeyAddPos = 0;
8caf5a
faaa37 ¤   mRandomPoolDWords = (poolBits+127 & ~127) >> 5;
5b4c49 ¤   mRandomPoolGetPos = mRandomPoolDWords/4;
76af5a
08e9b1 ¤   pgpAssert(mRandomPoolDWords > kRandomKeyDWords);
c9af5a
1e9ac2 ¤   mInitErr = GetByteBuffer(mRandomPoolDWords*4, (PGPUInt8 **) &mRandomPool);
53efe6 }
0daf5a
099aed // The PGPdiskRandomPool destructor.
ddaf5a
2566da PGPdiskRandomPool::~PGPdiskRandomPool()
a4bb36 {
c0362d ¤   if (mRandomPool)
8e44d7 ¤   ¤   FreeByteBuffer((PGPUInt8 *) mRandomPool);
1fefe6 }
9daf5a
08c5b2 // AddMouseEntropy adds entropy to the pool. Data from the mouse position and
cafd68 // the system clock is used. Pass in values for 'x' and 'y'.
21af5a
5ec823 void·
279c5f PGPdiskRandomPool::AddMouseEntropy(PGPUInt32 x, PGPUInt32 y)
67bb36 {
--a6e5 000ac96d0894011006e Page 2 of PGPdiskRandomPool.cpp
a3acbb ¤   PGPUInt64 sysTime;
62af5a
8ccc6f ¤   AddBytes((PGPUInt8 *) &x, sizeof(PGPUInt32));
6a45a6 ¤   AddBytes((PGPUInt8 *) &y, sizeof(PGPUInt32));
2967c5 ¤
d9a96a ¤   // Add current ms since system startup.
27af5a
11f8d0 ¤   sysTime = PGPdiskGetTicks();
3867c5 ¤
69ee26 ¤   AddBytes((PGPUInt8 *) &sysTime, sizeof(PGPUInt32));
46efe6 }
eeaf5a
fa880f // Stir "stirs in" any random seed material before removing any random bytes.
4cc884 // This also ensures that no sensitive data remains in memory that can be
d5bf2b // recovered later.
fbaf5a
73314a void
64df7b PGPdiskRandomPool::Stir()
bebb36 {
930721 ¤   PGPUInt32¤  i;
79e917 ¤   PGPUInt32¤  iv[4];
8eaf5a
9d1856 ¤   // Start IV from last block of the random pool.
6cc0ba ¤   pgpCopyMemory(mRandomPool+mRandomPoolDWords - 4, iv, sizeof(iv));
55af5a
0d779c ¤   // CFB pass.
46129a ¤   for (i=0; i<mRandomPoolDWords; i+=4)
aac7a1 ¤   {
e8a44b ¤   ¤   SHA¤¤   ¤   sha;
40e91d ¤   ¤   SHA::Digest¤digest;
2b1b52 ¤   ¤
d6179b ¤   ¤   sha.Update((const PGPUInt8 *) iv, sizeof(iv));
9dd47e ¤   ¤   sha.Update((const PGPUInt8 *) &mRandomKey[0], sizeof(mRandomKey));
298236 ¤   ¤   sha.Final(&digest);
f3e7a4 ¤   ¤   pgpCopyMemory(&digest, iv, sizeof(iv));
97af5a
9fa667 ¤   ¤   iv[0] = mRandomPool[i ·] ^= iv[0];
397aaf ¤   ¤   iv[1] = mRandomPool[i+1] ^= iv[1];
88c833 ¤   ¤   iv[2] = mRandomPool[i+2] ^= iv[2];
4ba647 ¤   ¤   iv[3] = mRandomPool[i+3] ^= iv[3];
7f9371 ¤   }
e4af5a
c106f1 ¤   // Wipe iv from memory.
7bebd5 ¤   for(i=0; i<4; i++)
b5c833 ¤   ¤   iv[i] = 0;
b3af5a
039a65 ¤   // Get new key.
d8eeb5 ¤   pgpCopyMemory(mRandomPool, mRandomKey, sizeof(mRandomKey));
56af5a
949a55 ¤   // Set up pointers for future addition or removal of random bytes.
c5dbed ¤   mRandomKeyAddPos = 0;
7eab05 ¤   mRandomPoolGetPos = sizeof(mRandomKey);
39efe6 }
68af5a
f53a28 // GetByte gets a single byte.
faaf5a
545540 PGPUInt8
246a0c PGPdiskRandomPool::GetByte()
24bb36 {
83268a ¤   if (mRandomPoolGetPos == mRandomPoolDWords*4)
954094 ¤   ¤   Stir();
13af5a
cf84c9 ¤   return ((const PGPUInt8 *) mRandomPool)[mRandomPoolGetPos++];
bbefe6 }
cdaf5a
b647ce // AddByte adds one byte to the entropy pool.
3daf5a
f6314a void
12bd2d PGPdiskRandomPool::AddByte(PGPUInt8 byte)
c0bb36 {
461402 ¤   AddBytes(&byte, sizeof(PGPUInt8));
acefe6 }
--fc3c 0010d0ae8a04011006e Page 3 of PGPdiskRandomPool.cpp
e0af5a
59ca59 // GetBytes withdraws some bits from the pool. Regardless of the distribution
5bd626 // of the input bits, the bits returned are uniformly distributed, although
d08ed1 // they cannot, of course, contain more Shannon entropy than the input bits.
23af5a
73314a void
29bb57 PGPdiskRandomPool::GetBytes(PGPUInt8 *buf, PGPUInt32 len)
4cbb36 {
952b16 ¤   PGPUInt32 t;
7daf5a
dced76 ¤   while (len > (t = mRandomPoolDWords*4 - mRandomPoolGetPos))
f8c7a1 ¤   {
d957be ¤   ¤   pgpCopyMemory(((const PGPUInt8 *) mRandomPool) + mRandomPoolGetPos,·
39030a ¤   ¤   ¤   buf, t);
62af5a
9cc5a3 ¤   ¤   buf¤+= t;
4a8e8a ¤   ¤   len¤-= t;
06af5a
804094 ¤   ¤   Stir();
019371 ¤   }
60af5a
819cad ¤   pgpCopyMemory(((const PGPUInt8 *) mRandomPool)+mRandomPoolGetPos, buf,·
9a54a6 ¤   ¤   len);
7b3a56 ¤   mRandomPoolGetPos += len;
9defe6 }
aaaf5a
182039 // AddBytes makes a deposit of information (entropy) into the pool. This is
e88017 // done by XORing the data into the key which used to encrypt the pool.
e1c3b1 // Before any bytes are retrieved from the pool, the altered key will be used
bf05fe // to encrypt the whole pool, causing all bits in the pool to depend on the
9115a5 // new information.
77465d //
583c4b // The bits deposited need not have any particular distribution; the stirring
7b47b4 // operation transforms them into uniformly-distributed bits.
32af5a
b9314a void
0f298f PGPdiskRandomPool::AddBytes(const PGPUInt8 *buf, PGPUInt32 len)
b3bb36 {
7d9a9b ¤   PGPUInt8¤   *p¤ = ((PGPUInt8 *) mRandomKey) + mRandomKeyAddPos;
d8c24f ¤   PGPUInt32¤  t¤  = sizeof(mRandomKey) - mRandomKeyAddPos;
f3af5a
bbaf10 ¤   while (len > t)
29c7a1 ¤   {
f767e1 ¤   ¤   len -= t;
bb0412 ¤   ¤   while (t--)
5fa22c ¤   ¤   ¤   (* p++) ^= (* buf++);
d9af5a
3900a4 ¤   ¤   Stir();¤¤   // sets mRandomKeyPos to 0
40af5a
cc6579 ¤   ¤   p = (PGPUInt8 *) mRandomKey;
b7819f ¤   ¤   t = sizeof(mRandomKey);
479371 ¤   }
f1af5a
884548 ¤   if (len)
c1c7a1 ¤   {
43ef41 ¤   ¤   mRandomKeyAddPos += len;
4e0c19 ¤   ¤   do
85a22c ¤   ¤   ¤   (* p++) ^= (* buf++);
b4fc52 ¤   ¤   while (--len);
daaf5a
e7d2ac ¤   ¤   mRandomPoolGetPos = mRandomPoolDWords*4;¤   // Force stir on get
5f9371 ¤   }
0defe6 }
--5447 001aa5842844011006f Page 1 of PGPdiskRandomPool.h
541bc3 //////////////////////////////////////////////////////////////////////////////
4c94cb // PGPdiskRandomPool.h
02465d //
11d91f // Contains declarations for class PGPdiskRandomPool.
d81bc3 //////////////////////////////////////////////////////////////////////////////
d6af5a
c95c16 // $Id: PGPdiskRandomPool.h,v 1.1.2.5.2.1 1998/10/28 01:42:34 nryan Exp $
7baf5a
abcbce // Copyright (C) 1998 by Network Associates, Inc.
fe71ae // All rights reserved.
caaf5a
53bc7a #ifndef Included_PGPdiskRandomPool_h¤   // [
3fd459 #define Included_PGPdiskRandomPool_h
a3af5a
a4af5a
5809b7 ////////////
1fe738 // Constants
da09b7 ////////////
84af5a
0a2889 const PGPUInt32¤kDefaultRandomPoolBits¤ = 1024;¤¤   // default size of pool
ecc164 const PGPUInt32 kRandomKeyDWords ···¤   = 16;
50af5a
a52af8 //////////
184f83 // Classes
5e2af8 //////////
3daf5a
7d04ad class PGPdiskRandomPool
24bb36 {
b05ed4 public:
711603 ¤   DualErr mInitErr;
70af5a
0f6801 ¤   ¤   ¤   ¤   PGPdiskRandomPool(
705f7b ¤   ¤   ¤   ¤   ¤   PGPUInt32 poolBits = kDefaultRandomPoolBits);
5db5b5 ¤   ¤   ¤   ¤   ~PGPdiskRandomPool();
d4af5a
923a75 ¤   void¤   ¤   AddMouseEntropy(PGPUInt32 x, PGPUInt32 y);
f72983 ¤   void¤   ¤   Stir();
06af5a
219268 ¤   PGPUInt8¤   GetByte();
4e2018 ¤   void¤   ¤   AddByte(PGPUInt8 byte);
dfaf5a
86d1b1 ¤   void¤   ¤   GetBytes(PGPUInt8 *buf, PGPUInt32 nBytes);
f8b129 ¤   void¤   ¤   AddBytes(const PGPUInt8 *buf, PGPUInt32 nBytes);
5daf5a
b30fb9 private:
70e770 ¤   PGPUInt32¤  *mRandomPool;¤  ¤   ¤   ¤   ¤   // the pool itself
da7ace ¤   PGPUInt32¤  mRandomKey[kRandomKeyDWords];¤  // next stirring key
52af5a
c296a4 ¤   PGPUInt32¤  mRandomPoolGetPos;¤ ¤   ¤   ¤   // position to get from
a32ec2 ¤   PGPUInt32¤  mRandomKeyAddPos;¤  ¤   ¤   ¤   // position to add from
5baf5a
209038 ¤   PGPUInt32¤  mRandomPoolBits;¤   ¤   ¤   ¤   // size of pool in bits
ff998d ¤   PGPUInt32¤  mRandomPoolDWords;¤ ¤   ¤   ¤   // size of pool in dwords
a982f7 };
80af5a
aacdec #endif¤ // ] Included_PGPdiskRandomPool_h
--ff1a 00067573c5940110070 Page 1 of SHA.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
84c199 // SHA.cpp
e1465d //
ae79ba // Implementation of class SHA.
a01bc3 //////////////////////////////////////////////////////////////////////////////
01af5a
4d588f // $Id: SHA.cpp,v 1.1.2.10 1998/07/06 08:56:39 nryan Exp $
1daf5a
3d7758 // Portions Copyright (C) 1998 by Network Associates, Inc.
fd71ae // All rights reserved.
bbaf5a
026931 #if defined(PGPDISK_MFC)
44af5a
499e12 #include "StdAfx.h"
4eaf5a
554268 #elif defined(PGPDISK_95DRIVER)
85af5a
4006a9 #include <vtoolscp.h>
4b86d2 #include LOCKED_CODE_SEGMENT
ff5269 #include LOCKED_DATA_SEGMENT
a8af5a
52f5a6 #elif defined(PGPDISK_NTDRIVER)
aaaf5a
0ed7a1 #include <vdw.h>
c2af5a
cfdb21 #else
a59cb8 #error Define PGPDISK_MFC, PGPDISK_95DRIVER or PGPDISK_NTDRIVER.
4205d6 #endif¤ // PGPDISK_MFC
e4af5a
6d9bcf #include "Required.h"
af4818 #include "SHA.h"
feaf5a
e1af5a
e709b7 ////////////
d4e738 // Constants
6709b7 ////////////
e0af5a
695a1b // The SHS Mysterious Constants
5aaf5a
d94f3c const PGPUInt32¤K1¤ = 0x5A827999L;¤ ¤   // Rounds ·0-19
35b372 const PGPUInt32¤K2¤ = 0x6ED9EBA1L;¤ ¤   // Rounds 20-39
22793b const PGPUInt32¤K3¤ = 0x8F1BBCDCL;¤ ¤   // Rounds 40-59
be4c94 const PGPUInt32¤K4¤ = 0xCA62C1D6L;¤ ¤   // Rounds 60-79
73af5a
2ae030 // SHS initial values
13af5a
63588d const PGPUInt32¤h0init¤ = 0x67452301L;
c09b08 const PGPUInt32¤h1init¤ = 0xEFCDAB89L;
0bed82 const PGPUInt32¤h2init¤ = 0x98BADCFEL;
1606b0 const PGPUInt32¤h3init¤ = 0x10325476L;
10965b const PGPUInt32¤h4init¤ = 0xC3D2E1F0L;
66af5a
a9af5a
08d43e /////////
38596b // Macros
9ad43e /////////
4aaf5a
f79206 #define¤f1(x,y,z)¤  (z ^ (x & (y ^ z)))¤¤   ¤   ¤   // Rounds ·0-19
102b40 #define¤f2(x,y,z)¤  (x ^ y ^ z)¤¤   ¤   ¤   ¤   ¤   // Rounds 20-39
eb434c #define¤f3(x,y,z)¤  ((x & y) | (z & (x | y)))¤  ¤   // Rounds 40-59
992555 #define¤f4(x,y,z)¤  (x ^ y ^ z)¤¤   ¤   ¤   ¤   ¤   // Rounds 60-79
69af5a
9d4bb5 // 32-bit rotate left - kludged with shifts
6caf5a
cf8def #define¤ROTL(n,X)¤  ((X << n) | (X >> (32-n)))
bdaf5a
1a0d72 // The hash function is defined over an 80-word expanded input array W,
44f1d7 // where the first 16 are copies of the input data, and the remaining 64
df4b9b // are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. ·This
040c42 // implementation generates these values on the fly in a circular buffer.
d0af5a
67420d // The new (corrected) SHA
--40a6 0008fcae7d940110070 Page 2 of SHA.cpp
e0af5a
9a89c1 #define¤expand(W,i)¤(W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15], \
d1878e ¤   ¤   ¤   ¤   ¤   W[i&15] = ROTL(1, W[i&15]))
d1af5a
df548f // The fundamental sub-round is
2dc79d // a' = e + ROTL(5,a) + f(b, c, d) + k + data;
db7434 // b' = a;
6e5399 // c' = ROTL(30,b);
81dc3d // d' = c;
c9d187 // e' = d;
24240b // ... but this is implemented by unrolling the loop 5 times and renaming
1dcfe4 // the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration.
41af5a
e77bbe #define¤subRound(a, b, c, d, e, f, k, data) \
1dcb7c ¤   ¤   (e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b))
a8af5a
23af5a
73fc6a ////////////////////////////////////
90c1de // Class SHA public member functions
35fc6a ////////////////////////////////////
a4af5a
90cbef // The class SHA default constructor.
c0af5a
fd66e3 SHA::SHA()
94bb36 {
464089 ¤   Init();
feefe6 }
c3af5a
27d0de // Init initializes class data members.
01af5a
97c823 void·
5a90b9 SHA::Init()
edbb36 {
305150 ¤   // Set the h-vars to their initial values
dbfa9a ¤   mDigest.dwords[0]¤  = h0init;
d32d65 ¤   mDigest.dwords[1]¤  = h1init;
465d75 ¤   mDigest.dwords[2]¤  = h2init;
be8a8a ¤   mDigest.dwords[3]¤  = h3init;
b6bd55 ¤   mDigest.dwords[4]¤  = h4init;
76af5a
b492ae ¤   // Initialise bit count
487c85 ¤   mCountLo = mCountHi = 0;
48efe6 }
edaf5a
38dcb1 // Update performs an SHA update.
70af5a
53314a void
64e29e SHA::Update(const PGPUInt8 *buf, PGPUInt16 len)
f0bb36 {
ac7dcb ¤   PGPUInt32¤  t;
58af5a
a67d4d ¤   // Update bitcount
14ab4b ¤   t = mCountLo;
e0e034 ¤   if ((mCountLo = t + len) < t)
37b5c1 ¤   ¤   mCountHi++;¤¤   ¤   // Carry from low to high
30af5a
a70893 ¤   t &= 0x3f;¤ ¤   // Bytes already in mData
3aaf5a
432275 ¤   // Handle any leading odd-sized chunks
ab0b9d ¤   if (t)
b9c7a1 ¤   {
9c3f0d ¤   ¤   PGPUInt8 *p = ((PGPUInt8 *) mData) + t;
f8af5a
2049c6 ¤   ¤   t = 64-t;
fe708e ¤   ¤   if (len < t)
335b34 ¤   ¤   {
36bd1e ¤   ¤   ¤   pgpCopyMemory(buf, p, len);
780ecc ¤   ¤   ¤   return;
ad0fe4 ¤   ¤   }
10af5a
0f73d1 ¤   ¤   pgpCopyMemory(buf, p, t);
8f5cc4 ¤   ¤   ByteReverse(mData, kSHS_BLOCKSIZE);
--7581 0007c8cb3f340110070 Page 3 of SHA.cpp
37e5d1 ¤   ¤   Transform();
c6af5a
10c5a3 ¤   ¤   buf¤+= t;
7369fa ¤   ¤   len¤-= (PGPUInt16) t;
439371 ¤   }
fcaf5a
4a1181 ¤   // Process data in kSHS_BLOCKSIZE chunks
7f73fb ¤   while (len >= kSHS_BLOCKSIZE)
c5c7a1 ¤   {
906673 ¤   ¤   pgpCopyMemory(buf, mData, kSHS_BLOCKSIZE);
8f5cc4 ¤   ¤   ByteReverse(mData, kSHS_BLOCKSIZE);
c3e5d1 ¤   ¤   Transform();
75af5a
c9541f ¤   ¤   buf¤+= kSHS_BLOCKSIZE;
641318 ¤   ¤   len¤-= kSHS_BLOCKSIZE;
ad9371 ¤   }
34af5a
4526d2 ¤   // Handle any remaining bytes of data.
9ab6f1 ¤   pgpCopyMemory(buf, mData, len);
f0efe6 }
08af5a
6f1ddb // Final outputs the result of the hash.
11af5a
a8c823 void·
5d135e SHA::Final(Digest *hash)
68bb36 {
ec8828 ¤   PGPUInt32¤  len;
aae18b ¤   PGPUInt8¤   *p;
21af5a
250c7f ¤   pgpAssert(sizeof(mDigest) == kSHS_DIGESTSIZE);
9367c5 ¤
dfef10 ¤   // Compute number of bytes mod 64
632f23 ¤   len = ((PGPUInt32) mCountLo) & 0x3F;
b4af5a
8ef1bd ¤   // Set the first char of padding to 0x80. This is safe since there is
6c0c2b ¤   // always at least one byte free
50af5a
f3f13c ¤   p¤  ¤   = ((PGPUInt8 *) mData) + len;
8ca447 ¤   (* p++)¤= 0x80;
d0af5a
32d739 ¤   // Bytes of padding needed to make 64 bytes
90458b ¤   len¤= kSHS_BLOCKSIZE - 1 - len;
50af5a
041ad5 ¤   // Pad out to 56 mod 64
6b92d0 ¤   if (len < 8)
f5c7a1 ¤   {
be9b63 ¤   ¤   // Two lots of padding: ·Pad the first block to 64 bytes
f37740 ¤   ¤   pgpClearMemory(p, len);
725cc4 ¤   ¤   ByteReverse(mData, kSHS_BLOCKSIZE);
93e5d1 ¤   ¤   Transform();
99af5a
a48d8b ¤   ¤   // Now fill the next block with 56 bytes
1097a0 ¤   ¤   pgpClearMemory(mData, kSHS_BLOCKSIZE-8);
509371 ¤   }
870e24 ¤   else
34c7a1 ¤   {
2a378c ¤   ¤   // Pad block to 56 bytes
24588c ¤   ¤   pgpClearMemory(p, len-8);
319371 ¤   }
371534 ¤   ByteReverse(mData, kSHS_BLOCKSIZE-8);
19af5a
044115 ¤   // Append length in *bits* and transform
383168 ¤   mData[14]¤  = mCountHi << 3 | mCountLo >> 29;
511234 ¤   mData[15]¤  = mCountLo << 3;
b0af5a
c4a45a ¤   Transform();
92af5a
107df2 ¤   // Store output hash in buffer
628a39 ¤   ByteReverse(&mDigest.dwords[0], sizeof(mDigest));
798788 ¤   (* hash) = mDigest;
ad67c5 ¤
7cd148 ¤   pgpClearMemory(mData, sizeof(mData));
--8faa 000a8ce6ce340110070 Page 4 of SHA.cpp
5c3ab5 ¤   pgpClearMemory(&mDigest, sizeof(mDigest));
f2af5a
ab7c85 ¤   mCountLo = mCountHi = 0;
82efe6 }
4daf5a
34d100 // Clone duplicates a SHA object.
f9af5a
fe1460 SHA *·
e2b845 SHA::Clone()
21bb36 {
17b227 ¤   SHA¤¤   ¤   *clone;
9a5a8e ¤   PGPUInt16¤  inx;
74af5a
7d6931 #if defined(PGPDISK_MFC)
d6af5a
a578f1 ¤   try
e2c7a1 ¤   {
ce503f ¤   ¤   clone = new SHA();
969371 ¤   }
bf3c88 ¤   catch (CMemoryException *ex)
26c7a1 ¤   {
c16adc ¤   ¤   ex->Delete();
507ed2 ¤   ¤   return NULL;
559371 ¤   }
8aaf5a
1e8c8d #elif defined(PGPDISK_95DRIVER) || defined(PGPDISK_NTDRIVER)
f5af5a
724272 ¤   if (!(clone = new SHA()))
697ed2 ¤   ¤   return NULL;
57af5a
d605d6 #endif¤ // PGPDISK_MFC
f867c5 ¤
e473bb ¤   for (inx=0; inx<16; inx++)
78c7a1 ¤   {
f5b6e0 ¤   ¤   clone->mData[inx] = mData[inx];
539371 ¤   }
9567c5 ¤
06bac2 ¤   clone->mDigest = mDigest;
6667c5 ¤
d2f936 ¤   clone->mCountHi¤= mCountHi;
1c7bd7 ¤   clone->mCountLo¤= mCountLo;
daaf5a
2138b4 ¤   return clone;
fdefe6 }
efaf5a
53af5a
5f04c6 ///////////////////////////////////////
e0dd30 // Class SHA protected member functions
8904c6 ///////////////////////////////////////
3baf5a
9eaeae // ByteReverse reverses the bytes in each 32bit uints in an array of 32bit·
6504c2 // uints.
c4af5a
31c823 void·
9f5835 SHA::ByteReverse(PGPUInt32 *buf, PGPUInt32 byteCount)
fbbb36 {
108450 ¤   static PGPUInt8¤bytes[4];
ce9be6 ¤   PGPUInt32¤  ¤   value;
30af5a
1c78e4 ¤   byteCount /= sizeof(PGPUInt32);
e96650 ¤   while (byteCount--)
6bc7a1 ¤   {
c61230 ¤   ¤   value¤  ¤   = (* buf);
e9f9c7 ¤   ¤   bytes[0]¤   = (PGPUInt8) (value >> 24);
698ca0 ¤   ¤   bytes[1]¤   = (PGPUInt8) (value >> 16);
4c98bd ¤   ¤   bytes[2]¤   = (PGPUInt8) (value >> 8);
a8b014 ¤   ¤   bytes[3]¤   = (PGPUInt8) (value);
cf414e ¤   ¤   (* buf++)¤  = (* ((ulong*) bytes));
5d9371 ¤   }
ffefe6 }
f7af5a
a84240 // The above code is replicated 20 times for each of the 4 functions,
--a992 0003869569c40110070 Page 5 of SHA.cpp
928ac5 // using the next 20 values from the W[] array each time.
82af5a
43c655 // Transforms performs an SHA transformation.
4caf5a
27c823 void·
28c4b6 SHA::Transform()
f7bb36 {
937f5f ¤   register PGPUInt32¤ A, B, C, D, E;
74af5a
f225de ¤   // Set up first buffer
2002ae ¤   A¤  = mDigest.dwords[0];
eb1298 ¤   B¤  = mDigest.dwords[1];
15332e ¤   C¤  = mDigest.dwords[2];
b532f4 ¤   D¤  = mDigest.dwords[3];
ec61ae ¤   E¤  = mDigest.dwords[4];
48af5a
e7780b ¤   // Heavy mangling, in 4 sub-rounds of 20 interations each.
c5124b ¤   subRound(A, B, C, D, E, f1, K1, mData[0]);
566b05 ¤   subRound(E, A, B, C, D, f1, K1, mData[1]);
87331f ¤   subRound(D, E, A, B, C, f1, K1, mData[2]);
4bc5f6 ¤   subRound(C, D, E, A, B, f1, K1, mData[3]);
00c35d ¤   subRound(B, C, D, E, A, f1, K1, mData[4]);
49341f ¤   subRound(A, B, C, D, E, f1, K1, mData[5]);
895bd9 ¤   subRound(E, A, B, C, D, f1, K1, mData[6]);
a2154b ¤   subRound(D, E, A, B, C, f1, K1, mData[7]);
af821a ¤   subRound(C, D, E, A, B, f1, K1, mData[8]);
61bf29 ¤   subRound(B, C, D, E, A, f1, K1, mData[9]);
193d8d ¤   subRound(A, B, C, D, E, f1, K1, mData[10]);
ed99e1 ¤   subRound(E, A, B, C, D, f1, K1, mData[11]);
4137d3 ¤   subRound(D, E, A, B, C, f1, K1, mData[12]);
fa4285 ¤   subRound(C, D, E, A, B, f1, K1, mData[13]);
6d7557 ¤   subRound(B, C, D, E, A, f1, K1, mData[14]);
cf1bd9 ¤   subRound(A, B, C, D, E, f1, K1, mData[15]);
6484d8 ¤   subRound(E, A, B, C, D, f1, K1, expand(mData, 16));
520433 ¤   subRound(D, E, A, B, C, f1, K1, expand(mData, 17));
2ca9b5 ¤   subRound(C, D, E, A, B, f1, K1, expand(mData, 18));
8155e4 ¤   subRound(B, C, D, E, A, f1, K1, expand(mData, 19));
15af5a
01b089 ¤   subRound(A, B, C, D, E, f2, K2, expand(mData, 20));
0edceb ¤   subRound(E, A, B, C, D, f2, K2, expand(mData, 21));
194a88 ¤   subRound(D, E, A, B, C, f2, K2, expand(mData, 22));
c086b6 ¤   subRound(C, D, E, A, B, f2, K2, expand(mData, 23));
2d417f ¤   subRound(B, C, D, E, A, f2, K2, expand(mData, 24));
0996dd ¤   subRound(A, B, C, D, E, f2, K2, expand(mData, 25));
68ec37 ¤   subRound(E, A, B, C, D, f2, K2, expand(mData, 26));
956cdc ¤   subRound(D, E, A, B, C, f2, K2, expand(mData, 27));
efc15a ¤   subRound(C, D, E, A, B, f2, K2, expand(mData, 28));
023d0b ¤   subRound(B, C, D, E, A, f2, K2, expand(mData, 29));
b1b4a2 ¤   subRound(A, B, C, D, E, f2, K2, expand(mData, 30));
f9d8c0 ¤   subRound(E, A, B, C, D, f2, K2, expand(mData, 31));
494ea3 ¤   subRound(D, E, A, B, C, f2, K2, expand(mData, 32));
57829d ¤   subRound(C, D, E, A, B, f2, K2, expand(mData, 33));
a94554 ¤   subRound(B, C, D, E, A, f2, K2, expand(mData, 34));
5c92f6 ¤   subRound(A, B, C, D, E, f2, K2, expand(mData, 35));
b2e81c ¤   subRound(E, A, B, C, D, f2, K2, expand(mData, 36));
8068f7 ¤   subRound(D, E, A, B, C, f2, K2, expand(mData, 37));
c0c571 ¤   subRound(C, D, E, A, B, f2, K2, expand(mData, 38));
0d3920 ¤   subRound(B, C, D, E, A, f2, K2, expand(mData, 39));
f9af5a
c073f2 ¤   subRound(A, B, C, D, E, f3, K3, expand(mData, 40));
611f90 ¤   subRound(E, A, B, C, D, f3, K3, expand(mData, 41));
b589f3 ¤   subRound(D, E, A, B, C, f3, K3, expand(mData, 42));
9a45cd ¤   subRound(C, D, E, A, B, f3, K3, expand(mData, 43));
9a8204 ¤   subRound(B, C, D, E, A, f3, K3, expand(mData, 44));
9055a6 ¤   subRound(A, B, C, D, E, f3, K3, expand(mData, 45));
fe2f4c ¤   subRound(E, A, B, C, D, f3, K3, expand(mData, 46));
77afa7 ¤   subRound(D, E, A, B, C, f3, K3, expand(mData, 47));
b00221 ¤   subRound(C, D, E, A, B, f3, K3, expand(mData, 48));
bffe70 ¤   subRound(B, C, D, E, A, f3, K3, expand(mData, 49));
d177d9 ¤   subRound(A, B, C, D, E, f3, K3, expand(mData, 50));
811bbb ¤   subRound(E, A, B, C, D, f3, K3, expand(mData, 51));
388dd8 ¤   subRound(D, E, A, B, C, f3, K3, expand(mData, 52));
--5f8c 00195bb2ae040110070 Page 6 of SHA.cpp
8541e6 ¤   subRound(C, D, E, A, B, f3, K3, expand(mData, 53));
64862f ¤   subRound(B, C, D, E, A, f3, K3, expand(mData, 54));
ec518d ¤   subRound(A, B, C, D, E, f3, K3, expand(mData, 55));
372b67 ¤   subRound(E, A, B, C, D, f3, K3, expand(mData, 56));
a6ab8c ¤   subRound(D, E, A, B, C, f3, K3, expand(mData, 57));
28060a ¤   subRound(C, D, E, A, B, f3, K3, expand(mData, 58));
8dfa5b ¤   subRound(B, C, D, E, A, f3, K3, expand(mData, 59));
9daf5a
a76901 ¤   subRound(A, B, C, D, E, f4, K4, expand(mData, 60));
b00563 ¤   subRound(E, A, B, C, D, f4, K4, expand(mData, 61));
db9300 ¤   subRound(D, E, A, B, C, f4, K4, expand(mData, 62));
be5f3e ¤   subRound(C, D, E, A, B, f4, K4, expand(mData, 63));
5298f7 ¤   subRound(B, C, D, E, A, f4, K4, expand(mData, 64));
fe4f55 ¤   subRound(A, B, C, D, E, f4, K4, expand(mData, 65));
e635bf ¤   subRound(E, A, B, C, D, f4, K4, expand(mData, 66));
d6b554 ¤   subRound(D, E, A, B, C, f4, K4, expand(mData, 67));
e018d2 ¤   subRound(C, D, E, A, B, f4, K4, expand(mData, 68));
1de483 ¤   subRound(B, C, D, E, A, f4, K4, expand(mData, 69));
a26d2a ¤   subRound(A, B, C, D, E, f4, K4, expand(mData, 70));
cc0148 ¤   subRound(E, A, B, C, D, f4, K4, expand(mData, 71));
30972b ¤   subRound(D, E, A, B, C, f4, K4, expand(mData, 72));
3a5b15 ¤   subRound(C, D, E, A, B, f4, K4, expand(mData, 73));
0a9cdc ¤   subRound(B, C, D, E, A, f4, K4, expand(mData, 74));
fa4b7e ¤   subRound(A, B, C, D, E, f4, K4, expand(mData, 75));
143194 ¤   subRound(E, A, B, C, D, f4, K4, expand(mData, 76));
23b17f ¤   subRound(D, E, A, B, C, f4, K4, expand(mData, 77));
6b1cf9 ¤   subRound(C, D, E, A, B, f4, K4, expand(mData, 78));
8ee0a8 ¤   subRound(B, C, D, E, A, f4, K4, expand(mData, 79));
61af5a
54cfd5 ¤   // Build message digest
b27d81 ¤   mDigest.dwords[0]¤  += A;
b7c774 ¤   mDigest.dwords[1]¤  += B;
29631b ¤   mDigest.dwords[2]¤  += C;
52ba8f ¤   mDigest.dwords[3]¤  += D;
bb40b5 ¤   mDigest.dwords[4]¤  += E;
95efe6 }
--dec3 0019b8d602940110071 Page 1 of SHA.h
541bc3 //////////////////////////////////////////////////////////////////////////////
7bcf2d // SHA.h
30465d //
d21beb // Contains declarations for class SHA.
9e1bc3 //////////////////////////////////////////////////////////////////////////////
fbaf5a
05d02f // $Id: SHA.h,v 1.1.2.4 1998/07/06 08:56:40 nryan Exp $
01af5a
437758 // Portions Copyright (C) 1998 by Network Associates, Inc.
2671ae // All rights reserved.
72af5a
a29c71 #ifndef Included_SHA_h¤ // [
5e2bdd #define Included_SHA_h
eeaf5a
a2575e /* NIST proposed Secure Hash Standard.
7faf5a
e8f203 ···Written 2 September 1992, Peter C. Gutmann.
734445 ···This implementation placed in the public domain.
4caf5a
3b12a6 ···Modified 1 June 1993, Colin Plumb.
7d4863 ···These modifications placed in the public domain.
beaf5a
a0ca94 ···Modified 22 October 1998, Network Associates, Inc.
a6c52d ···Modifications copyright Network Associates, Inc.
f8af5a
545cd4 ···Comments to pgut1@cs.aukuni.ac.nz */
1eaf5a
73af5a
5e09b7 ////////////
f73758 // Class SHA
f709b7 ////////////
64af5a
8b5a28 class SHA
09bb36 {
4a5ed4 public:
3d797c ¤   enum¤   {kSHS_BLOCKSIZE = 64};
5dfafc ¤   enum¤   {kSHS_DIGESTSIZE = 20};
d467c5 ¤
0d1441 ¤   typedef union Digest
51c7a1 ¤   {
40aa26 ¤   ¤   PGPUInt8¤   bytes[kSHS_DIGESTSIZE];
96395b ¤   ¤   PGPUInt32¤  dwords[kSHS_DIGESTSIZE / sizeof(PGPUInt32)];
796a00 ¤   } Digest;
0067c5 ¤
70a219 ¤   ¤   ¤   ¤   ¤   SHA();
493e78 ¤   virtual¤¤   ¤   ~SHA()¤ { };
72af5a
100876 ¤   virtual void¤   Init();
b4bba3 ¤   virtual void¤   Update(const PGPUInt8 *buf, PGPUInt16 len);
b1e24b ¤   virtual void¤   Final(Digest *digest);
d0af5a
061229 ¤   virtual SHA *¤  Clone();
4baf5a
daa2d3 protected:
420d13 ¤   Digest¤ ¤   mDigest;
7382f7 ¤   PGPUInt32¤  mCountHi;¤  ¤   ¤   // 64-bit byte count
3d5acc ¤   PGPUInt32¤  mCountLo;¤  ¤   ¤   // 64-bit byte count
fcdb13 ¤   PGPUInt32¤  mData[16];¤ ¤   ¤   // SHS data buffer
13af5a
4a1b06 ¤   void¤   ByteReverse(PGPUInt32 *buf, PGPUInt32 byteCount);
02c00d ¤   void¤   Transform();
a382f7 };
acaf5a
9b8db4 #endif¤ // ] Included_SHA_h

--3716 0000b9d199340110072 Page 1 of PGPdiskApp.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
2229f7 #include "Source\Resource.h"
28af5a
2be1bf #define APSTUDIO_READONLY_SYMBOLS
196c0e /////////////////////////////////////////////////////////////////////////////
2f465d //
d00131 // Generated from the TEXTINCLUDE 2 resource.
19465d //
58897a #include "afxres.h"
2daf5a
8d6c0e /////////////////////////////////////////////////////////////////////////////
287b93 #undef APSTUDIO_READONLY_SYMBOLS
ceaf5a
cb6c0e /////////////////////////////////////////////////////////////////////////////
04f930 // English (U.S.) resources
2baf5a
cd1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
d4ec08 #ifdef _WIN32
ebe912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
e59c1c #pragma code_page(1252)
e21f8e #endif //_WIN32
e5af5a
9cf860 #ifdef APSTUDIO_INVOKED
5d6c0e /////////////////////////////////////////////////////////////////////////////
12465d //
895733 // TEXTINCLUDE
91465d //
e0af5a
ea86ef 1 TEXTINCLUDE DISCARDABLE·
414523 BEGIN
b1df56 ····"Source\\Resource.h\0"
6ae0d1 END
a4af5a
417037 2 TEXTINCLUDE DISCARDABLE·
1b4523 BEGIN
01eb23 ····"#include ""afxres.h""\r\n"
f8db5c ····"\0"
f6e0d1 END
f1af5a
ce227f 3 TEXTINCLUDE DISCARDABLE·
c74523 BEGIN
36e37a ····"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
e71b0b ····"#define _AFX_NO_OLE_RESOURCES\r\n"
636e56 ····"#define _AFX_NO_TRACKER_RESOURCES\r\n"
8f8342 ····"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
1ae851 ····"\r\n"
765690 ····"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
6ef0ea ····"#ifdef _WIN32\r\n"
1f3b39 ····"LANGUAGE 9, 1\r\n"
eadeb2 ····"#pragma code_page(1252)\r\n"
798a0b ····"#endif\r\n"
0bace2 ····"#include ""res\\PGPdiskApp.rc2"" ·// non-Microsoft Visual C++ edited resou¶
f7d78e rces\r\n"
c8a502 ····"#include ""afxres.rc"" ·········// Standard components\r\n"
618a0b ····"#endif\r\n"
08e851 ····"\r\n"
0d645e ····"#include ""PGPdiskAppVer.rc""\0"
e3e0d1 END
c5af5a
5969ab #endif ···// APSTUDIO_INVOKED
6faf5a
e7af5a
996c0e /////////////////////////////////////////////////////////////////////////////
8a465d //
1acbaf // Icon
be465d //
b6af5a
742951 // Icon with lowest ID value placed first to ensure application icon
340f06 // remains consistent on all systems.
3678ce IDI_NEW ················ICON ···DISCARDABLE ····"res\\iconNew.ico"
0b5ca4 IDI_MOUNT ··············ICON ···DISCARDABLE ····"res\\iconMount.ico"
--176b 00038641f2940110072 Page 2 of PGPdiskApp.rc
092b2c IDI_PREFS ··············ICON ···DISCARDABLE ····"res\\iconPrefs.ico"
fa825d IDI_UNMOUNT ············ICON ···DISCARDABLE ····"res\\iconUnmount.ico"
96f2f3 IDI_CAPSLOCK ···········ICON ···DISCARDABLE ····"res\\iconCapsLock.ico"
de5bc9 IDI_MAINFRAME ··········ICON ···DISCARDABLE ····"res\\iconMain.ico"
7197eb IDI_PGPDISK ············ICON ···DISCARDABLE ····"res\\iconPGPdisk.ico"
feaf5a
326c0e /////////////////////////////////////////////////////////////////////////////
7b465d //
25b090 // Dialog
82465d //
dcaf5a
c3715d IDD_MAIN_DLG DIALOGEX 0, 0, 178, 41
85cf74 STYLE WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
dc19c3 EXSTYLE WS_EX_APPWINDOW
6d07c2 CAPTION "PGPdisk"
ea3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
294523 BEGIN
1caac8 ····PUSHBUTTON ·····"&New",IDC_NEWPGPDISK,1,1,44,40,BS_ICON | BS_BOTTOM
424b83 ····PUSHBUTTON ·····"&Mount",IDC_MOUNTPGPDISK,45,1,44,40,BS_ICON | BS_BOTTOM
9c737a ····PUSHBUTTON ·····"&Unmount",IDC_UNMOUNTPGPDISK,89,1,44,40,BS_ICON |·
ca6120 ····················BS_BOTTOM
ac1a44 ····PUSHBUTTON ·····"P&refs",IDC_PREFERENCES,133,1,44,40,BS_ICON | BS_BOTTOM
5fe0d1 END
30af5a
560c12 IDD_PROP_AUTO DIALOG DISCARDABLE ·0, 0, 216, 55
816b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
41ef81 CAPTION "Auto Unmount"
81309f FONT 8, "MS Sans Serif"
024523 BEGIN
77cd0f ····CONTROL ········"Auto un&mount after",IDC_CHECK_UNMOUNT,"Button",
877ddd ····················BS_AUTOCHECKBOX | WS_TABSTOP,8,10,73,8
3c558f ····EDITTEXT ·······IDC_EDIT_UNMOUNT,84,8,28,12,ES_AUTOHSCROLL | ES_NUMBER
eafdf3 ····CONTROL ········"Spin1",IDC_EDIT_SPIN,"msctls_updown32",UDS_SETBUDDYINT |·
54808f ····················UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |·
2f0f8f ····················UDS_NOTHOUSANDS,113,7,10,14
3e090d ····CONTROL ········"Auto unmount on computer &sleep",IDC_CHECK_SLEEP,"Button",
1b4281 ····················BS_AUTOCHECKBOX | WS_TABSTOP,8,27,120,10
36ebee ····CONTROL ········"&Prevent sleep if any PGPdisks could not be unmounted",
d172c0 ····················IDC_CHECK_PREVENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
f0f029 ····················20,39,189,10
17e73c ····LTEXT ··········"minutes of inactivity",IDC_MINUTETEXT,115,10,64,8,NOT·
f81efd ····················WS_GROUP
d1e0d1 END
51af5a
7e43d0 IDD_SINGLEPASS1_DLG DIALOGEX 0, 0, 226, 114
894300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
dc7541 EXSTYLE WS_EX_CONTEXTHELP
a5846f CAPTION "Passphrase"
203884 FONT 8, "MS Sans Serif", 0, 0, 0x1
4f4523 BEGIN
284ab2 ····CONTROL ········"Please enter a passphase for ""MySecretDisk.pgd"":",
b1a4b7 ····················IDC_SINGLEPASSMSG_TEXT,"Static",SS_LEFTNOWORDWRAP,6,6,
d7223b ····················214,9,WS_EX_TRANSPARENT
e60c46 ····LTEXT ··········"&Passphrase:",IDC_STATIC,6,27,40,8,NOT WS_GROUP,
d31db1 ····················WS_EX_TRANSPARENT
ef3fd0 ····EDITTEXT ·······IDC_PASSPHRASE_EDIT,6,37,214,35,ES_MULTILINE |·
7390de ····················WS_VSCROLL
10a934 ····CONTROL ········"&Hide Typing",IDC_HIDETYPE_CHECK,"Button",
699ed4 ····················BS_AUTOCHECKBOX | WS_TABSTOP,162,26,54,8
05c798 ····CONTROL ········"&Read-only",IDC_RO_CHECK,"Button",BS_AUTOCHECKBOX |·
9e628b ····················WS_TABSTOP,27,82,48,10
16fb1c ····LTEXT ··········"&Drive letter",IDC_STATIC,39,98,38,8,NOT WS_GROUP
2242df ····COMBOBOX ·······IDC_DRIVE_COMBO,6,96,29,71,CBS_DROPDOWNLIST | CBS_SORT |·
b6be8a ····················WS_VSCROLL | WS_TABSTOP
3389ad ····DEFPUSHBUTTON ··"&OK",IDOK,114,95,50,14
b5818e ····PUSHBUTTON ·····"&Cancel",IDCANCEL,170,95,50,14
52808f ····ICON ···········IDI_CAPSLOCK,IDC_CAPSLOCK_TEXT,127,75,20,20,
ef6653 ····················SS_REALSIZEIMAGE | NOT WS_VISIBLE
7de0d1 END
12af5a
b71fb3 IDD_UNMOUNT_DLG DIALOGEX 0, 0, 160, 50
384300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
--c10f 000af281d0c40110072 Page 3 of PGPdiskApp.rc
b07541 EXSTYLE WS_EX_CONTEXTHELP
7123d8 CAPTION "Unmount PGPdisk"
4a3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
074523 BEGIN
7a517d ····LTEXT ··········"Unmount &PGPdisk:",IDC_STATIC,6,9,61,8,NOT WS_GROUP
06577f ····COMBOBOX ·······IDC_DRIVE_COMBO,76,7,78,53,CBS_DROPDOWNLIST | WS_VSCROLL |·
a1c64d ····················WS_TABSTOP
d93bde ····DEFPUSHBUTTON ··"&Unmount",IDC_UNMOUNT,47,31,50,14
8dafad ····PUSHBUTTON ·····"&Cancel",IDCANCEL,104,31,50,14
6fe0d1 END
e9af5a
5929eb IDD_PROP_HOTKEY DIALOG DISCARDABLE ·0, 0, 216, 55
896b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
584678 CAPTION "Unmount HotKey"
14309f FONT 8, "MS Sans Serif"
794523 BEGIN
adc57b ····LTEXT ··········"If you type a key combination in the box below, you will b¶
13a78c e able to unmount all PGPdisks in the system with a single touch.",
8ee6ac ····················IDC_STATIC,6,6,204,17,NOT WS_GROUP
2314e8 ····CONTROL ········"&Enable Unmount HotKey",IDC_HOTKEY_CHECK,"Button",
050208 ····················BS_AUTOCHECKBOX | WS_TABSTOP,6,37,93,10
c40195 ····EDITTEXT ·······IDC_HOTKEY_EDIT,121,34,82,14,ES_AUTOHSCROLL
56e0d1 END
edaf5a
9efe4d IDD_CONFIRMPASS1_DLG DIALOGEX 0, 0, 226, 194
854300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
dc7541 EXSTYLE WS_EX_CONTEXTHELP
f3ee7f CAPTION "Add Passphrase"
d93884 FONT 8, "MS Sans Serif", 0, 0, 0x1
cf4523 BEGIN
5e73c5 ····CONTROL ········"Please enter a passphrase for ""MySecretDisk.pgd"".",
eed793 ····················IDC_NEWPASSMSG_TEXT,"Static",SS_LEFTNOWORDWRAP,6,6,214,9
222eda ····LTEXT ··········"Your passphrase must be at least 8 characters long and sho¶
3ce5b4 uld contain one or more non-alphabetic characters.",
17ff24 ····················IDC_STATIC,6,20,214,17,NOT WS_GROUP,WS_EX_TRANSPARENT
b8e3a2 ····LTEXT ··········"&Passphrase:",IDC_STATIC,6,49,40,8,NOT WS_GROUP,
2f1db1 ····················WS_EX_TRANSPARENT
f2bad0 ····EDITTEXT ·······IDC_PASSPHRASE_EDIT,6,59,214,35,ES_MULTILINE |·
6490de ····················WS_VSCROLL
e94be5 ····LTEXT ··········"&Confirmation:",IDC_STATIC,6,121,42,8,NOT WS_GROUP,
be1db1 ····················WS_EX_TRANSPARENT
c74c49 ····EDITTEXT ·······IDC_CONFIRM_EDIT,6,131,214,35,ES_MULTILINE | WS_VSCROLL
e7a934 ····CONTROL ········"&Hide Typing",IDC_HIDETYPE_CHECK,"Button",
820544 ····················BS_AUTOCHECKBOX | WS_TABSTOP,162,48,54,8
4fc798 ····CONTROL ········"&Read-only",IDC_RO_CHECK,"Button",BS_AUTOCHECKBOX |·
8d46cf ····················WS_TABSTOP,7,178,48,10
2ca2fa ····DEFPUSHBUTTON ··"&OK",IDOK,113,176,50,14
ff33f3 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,170,176,50,14
d2cfbc ····ICON ···········IDI_CAPSLOCK,IDC_CAPSLOCK_TEXT,127,115,20,20,
3a6653 ····················SS_REALSIZEIMAGE | NOT WS_VISIBLE
12b77e ····LTEXT ··········"Passphrase Quality:",IDC_STATIC,6,98,63,8,NOT WS_GROUP
bd5dd8 ····CONTROL ········"Progress1",IDC_QUALITY_BAR,"msctls_progress32",
206172 ····················WS_BORDER,72,99,147,8
7be0d1 END
06af5a
3c06a1 IDD_SINGLEPASS2_DLG DIALOGEX 0, 0, 226, 101
3e4300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
a87541 EXSTYLE WS_EX_CONTEXTHELP
f966a8 CAPTION "Master Passphrase"
243884 FONT 8, "MS Sans Serif", 0, 0, 0x1
774523 BEGIN
b89737 ····CONTROL ········"Please enter the master passphase for ""MySecretDisk"":",
a6a4b7 ····················IDC_SINGLEPASSMSG_TEXT,"Static",SS_LEFTNOWORDWRAP,6,6,
9f223b ····················214,9,WS_EX_TRANSPARENT
e30c46 ····LTEXT ··········"&Passphrase:",IDC_STATIC,6,27,40,8,NOT WS_GROUP,
891db1 ····················WS_EX_TRANSPARENT
6e3fd0 ····EDITTEXT ·······IDC_PASSPHRASE_EDIT,6,37,214,35,ES_MULTILINE |·
3890de ····················WS_VSCROLL
b0a934 ····CONTROL ········"&Hide Typing",IDC_HIDETYPE_CHECK,"Button",
519ed4 ····················BS_AUTOCHECKBOX | WS_TABSTOP,162,26,54,8
40d28e ····DEFPUSHBUTTON ··"&OK",IDOK,114,81,50,14
afdaad ····PUSHBUTTON ·····"&Cancel",IDCANCEL,170,81,50,14
--0a09 0009e7a929940110072 Page 4 of PGPdiskApp.rc
5b37db ····ICON ···········IDI_CAPSLOCK,IDC_CAPSLOCK_TEXT,7,75,21,20,
3c6653 ····················SS_REALSIZEIMAGE | NOT WS_VISIBLE
49e0d1 END
18af5a
5ae352 IDD_DISKWIZ_RANDOM DIALOG DISCARDABLE ·0, 0, 316, 167
ad6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
037b63 CAPTION "New PGPdisk Wizard"
f6309f FONT 8, "MS Sans Serif"
9d4523 BEGIN
73006e ····LTEXT ··········"In order to generate an encryption key, PGPdisk needs a ce¶
8789ba rtain amount of random data.",
b65474 ····················IDC_STATIC,96,4,214,17,NOT WS_GROUP
833cf5 ····LTEXT ··········"Please type or move your mouse around inside this window u¶
061c9f ntil the progress bar below fills up.",
9ed0ca ····················IDC_STATIC,96,26,214,17,NOT WS_GROUP
925d04 ····CTEXT ··········"Collecting Random Data:",IDC_STATIC,96,66,214,8,NOT·
d11efd ····················WS_GROUP
ebe627 ····CONTROL ········"Progress1",IDC_RANDOM_BAR,"msctls_progress32",WS_BORDER,
26c1ab ····················96,78,214,11
ad8729 ····LTEXT ··········"0%",IDC_STATIC,96,93,10,8,NOT WS_GROUP
69ce6c ····RTEXT ··········"100%",IDC_STATIC,292,93,18,8,NOT WS_GROUP
7b0be0 ····LTEXT ··········"Press ""Next"" to begin the creation process.",
e01fb5 ····················IDC_STATIC,96,155,214,8,NOT WS_GROUP
186cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
15e53f ····················160
67e0d1 END
b0af5a
b15579 IDD_DISKWIZ_VOLINFO DIALOG DISCARDABLE ·0, 0, 316, 167
df6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
e77b63 CAPTION "New PGPdisk Wizard"
49309f FONT 8, "MS Sans Serif"
764523 BEGIN
3f83cc ····LTEXT ··········"You must now enter a size and a default drive letter for t¶
45588f he new PGPdisk volume.",
791c5e ····················IDC_STATIC,96,4,214,16,NOT WS_GROUP
f09dd1 ····LTEXT ··········"You have 100 MB of free space available. Note that the act¶
a47dee ual amount of free space on the PGPdisk you create will be somewhat less that t¶
64a6ce he size you choose below.",
1715be ····················IDC_FREESIZE_TEXT,96,25,214,24,NOT WS_GROUP
075531 ····GROUPBOX ·······"PGPdisk &Size",IDC_STATIC,96,56,214,45,BS_LEFT
2ec9b7 ····EDITTEXT ·······IDC_SIZE_EDIT,186,68,33,13,ES_AUTOHSCROLL | ES_NUMBER
e89d58 ····CONTROL ········"Spin1",IDC_SIZE_SPIN,"msctls_updown32",UDS_SETBUDDYINT |·
58808f ····················UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |·
bb32b8 ····················UDS_NOTHOUSANDS,220,68,9,13
059518 ····CONTROL ········"&KB",IDC_KB_CHECK,"Button",BS_AUTORADIOBUTTON |·
8f8881 ····················WS_TABSTOP,160,86,25,10
731689 ····CONTROL ········"&MB",IDC_MB_CHECK,"Button",BS_AUTORADIOBUTTON |·
015564 ····················WS_TABSTOP,191,86,25,10
349a2b ····CONTROL ········"&GB",IDC_GB_CHECK,"Button",BS_AUTORADIOBUTTON |·
de2822 ····················WS_TABSTOP,222,86,25,10
fa6cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
70e53f ····················160
9ae67e ····LTEXT ··········"Press ""Next"" when you're ready to choose a passphrase.",
581fb5 ····················IDC_STATIC,96,155,214,8,NOT WS_GROUP
0ca288 ····GROUPBOX ·······"PGPdisk &Drive Letter",IDC_STATIC,96,110,213,37
3760c2 ····COMBOBOX ·······IDC_DRIVE_COMBO,186,124,31,72,CBS_DROPDOWNLIST |·
4325e3 ····················CBS_SORT | WS_VSCROLL | WS_TABSTOP
48e0d1 END
d0af5a
25180a IDD_DISKWIZ_PASSPHRASE DIALOG DISCARDABLE ·0, 0, 316, 167
ee6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
347b63 CAPTION "New PGPdisk Wizard"
3e309f FONT 8, "MS Sans Serif"
6d4523 BEGIN
add087 ····LTEXT ··········"Your PGPdisk will be protected by a passphrase. ·It is imp¶
04889b ortant that you do not write this passphrase down.",
1451df ····················IDC_STATIC,96,4,214,17
8f2eda ····LTEXT ··········"Your passphrase must be at least 8 characters long and sho¶
c2e5b4 uld contain one or more non-alphabetic characters.",
fed0ca ····················IDC_STATIC,96,26,214,17,NOT WS_GROUP
7b39e0 ····LTEXT ··········"&Passphrase:",IDC_STATIC,96,51,40,8,NOT WS_GROUP
9ea1af ····EDITTEXT ·······IDC_PASSPHRASE_EDIT,96,61,214,35,ES_MULTILINE |·
--ea8b 000166a0efb40110072 Page 5 of PGPdiskApp.rc
c590de ····················WS_VSCROLL
2198e5 ····LTEXT ··········"&Confirmation:",IDC_STATIC,96,117,42,8,NOT WS_GROUP
9ed6fa ····EDITTEXT ·······IDC_CONFIRM_EDIT,96,127,214,35,ES_MULTILINE | WS_VSCROLL
eca934 ····CONTROL ········"&Hide Typing",IDC_HIDETYPE_CHECK,"Button",
06234a ····················BS_AUTOCHECKBOX | WS_TABSTOP,252,50,54,8
cd7d1e ····ICON ···········IDI_CAPSLOCK,IDC_CAPSLOCK_TEXT,217,112,20,20,
ef6653 ····················SS_REALSIZEIMAGE | NOT WS_VISIBLE
878cfe ····LTEXT ··········"Passphrase Quality:",IDC_STATIC,96,100,63,8,NOT·
691efd ····················WS_GROUP
a15dd8 ····CONTROL ········"Progress1",IDC_QUALITY_BAR,"msctls_progress32",
4e3054 ····················WS_BORDER,162,101,147,8
af6cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
0ae53f ····················160
cbe0d1 END
f3af5a
aa4778 IDD_DISKWIZ_CREATION DIALOG DISCARDABLE ·0, 0, 316, 167
c86b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
687b63 CAPTION "New PGPdisk Wizard"
64309f FONT 8, "MS Sans Serif"
094523 BEGIN
3403b7 ····LTEXT ··········"Your new PGPdisk must now be initialized and prepared for ¶
491d2f use.",
06b254 ····················IDC_STATIC,96,4,214,9,NOT WS_GROUP
93a0ac ····LTEXT ··········"Depending on the size of the PGPdisk, this can take severa¶
5f6d80 l minutes to complete.",
43cfc0 ····················IDC_STATIC,96,18,214,17,NOT WS_GROUP
79bb3e ····LTEXT ··········"Press ""Next"" to mount your new PGPdisk.",IDC_STATIC,
1431e4 ····················96,155,214,8,NOT WS_GROUP
9bd37a ····CTEXT ··········"Preparing: Untitled.pgd",IDC_DISKNAME_TEXT,96,66,214,8,
d69294 ····················NOT WS_GROUP
664832 ····CONTROL ········"Progress1",IDC_PROGRESS_BAR,"msctls_progress32",
5f6969 ····················WS_BORDER,96,78,214,11
dd8729 ····LTEXT ··········"0%",IDC_STATIC,96,93,10,8,NOT WS_GROUP
bace6c ····RTEXT ··········"100%",IDC_STATIC,292,93,18,8,NOT WS_GROUP
226cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
a4e53f ····················160
f1e0d1 END
a8af5a
8a788d IDD_DISKWIZ_INTRO DIALOG DISCARDABLE ·0, 0, 316, 167
e86b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
c37b63 CAPTION "New PGPdisk Wizard"
f0309f FONT 8, "MS Sans Serif"
164523 BEGIN
2e0455 ····LTEXT ··········"PGPdisk lets you store your files securely in encrypted vo¶
b19bc7 lumes that can be mounted and unmounted at any time. These volumes are actually¶
1f8776 ·files, called ""PGPdisks,"" that you can move, copy, and delete just like any ¶
ce4d4a other document.",
5981b0 ····················IDC_STATIC,98,4,214,34,NOT WS_GROUP
43e661 ····LTEXT ··········"To create a new PGPdisk volume, you must enter a desired s¶
7694fd ize, drive letter, and passphrase. Later on, if you like, you can add additiona¶
00402f l passphrases to the volume.",
32088d ····················IDC_STATIC,98,43,214,26,NOT WS_GROUP
0aa36e ····LTEXT ··········"You can change the directory and filename you selected by ¶
f9c2f1 using the controls below.",
70afd9 ····················IDC_STATIC,98,74,214,18,NOT WS_GROUP
e12572 ····LTEXT ··········"Press ""Next"" to choose a name and location for your PGPd¶
ce78c4 isk.",
50f352 ····················IDC_STATIC,98,97,214,8,NOT WS_GROUP
e86cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
6be53f ····················160
4ee0d1 END
0eaf5a
ebd352 IDD_DISKWIZ_DONE DIALOG DISCARDABLE ·0, 0, 316, 167
6e6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
4a7b63 CAPTION "New PGPdisk Wizard"
5b309f FONT 8, "MS Sans Serif"
2f4523 BEGIN
ed4597 ····LTEXT ··········"Your new PGPdisk volume has been created and mounted, but ¶
3e958c before it can be used it must be formatted. Just click Finish below to begin th¶
76a548 e formatting process and then you'll be all set.",
43867f ····················IDC_STATIC,96,4,214,26,NOT WS_GROUP
16963f ····LTEXT ··········"Afterward, to unmount your PGPdisk, you can either right-c¶
--9faf 000fad9727140110072 Page 6 of PGPdiskApp.rc
ff26a7 lick on its drive letter within the Explorer, or click on the ""Unmount"" butto¶
4adb07 n from within the PGPdisk application.",
f9e8aa ····················IDC_STATIC,96,35,214,24,NOT WS_GROUP
c36cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
3be53f ····················160
b14dee ····LTEXT ··········"To mount it again, simply double-click the PGPdisk file, o¶
7d3e10 r click on the ""Mount"" button.",
f1a36b ····················IDC_STATIC,95,66,214,16,NOT WS_GROUP
1ce0d1 END
fdaf5a
579f58 IDD_CONFIRMPASS2_DLG DIALOGEX 0, 0, 226, 194
064300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
fc7541 EXSTYLE WS_EX_CONTEXTHELP
42113b CAPTION "New Passphrase"
e53884 FONT 8, "MS Sans Serif", 0, 0, 0x1
904523 BEGIN
41c7eb ····CONTROL ········"Please enter a new passphrase for ""MySecretDisk.pgd"".",
307e7c ····················IDC_NEWPASSMSG_TEXT,"Static",SS_LEFTNOWORDWRAP,6,6,214,9,
031db1 ····················WS_EX_TRANSPARENT
a22eda ····LTEXT ··········"Your passphrase must be at least 8 characters long and sho¶
f2e5b4 uld contain one or more non-alphabetic characters.",
56ff24 ····················IDC_STATIC,6,20,214,17,NOT WS_GROUP,WS_EX_TRANSPARENT
05e3a2 ····LTEXT ··········"&Passphrase:",IDC_STATIC,6,49,40,8,NOT WS_GROUP,
bc1db1 ····················WS_EX_TRANSPARENT
72bad0 ····EDITTEXT ·······IDC_PASSPHRASE_EDIT,6,59,214,35,ES_MULTILINE |·
2e90de ····················WS_VSCROLL
644be5 ····LTEXT ··········"&Confirmation:",IDC_STATIC,6,121,42,8,NOT WS_GROUP,
a21db1 ····················WS_EX_TRANSPARENT
9f4c49 ····EDITTEXT ·······IDC_CONFIRM_EDIT,6,131,214,35,ES_MULTILINE | WS_VSCROLL
a1a934 ····CONTROL ········"&Hide Typing",IDC_HIDETYPE_CHECK,"Button",
940544 ····················BS_AUTOCHECKBOX | WS_TABSTOP,162,48,54,8
95a2fa ····DEFPUSHBUTTON ··"&OK",IDOK,113,176,50,14
f133f3 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,170,176,50,14
bacfbc ····ICON ···········IDI_CAPSLOCK,IDC_CAPSLOCK_TEXT,127,115,20,20,
0d6653 ····················SS_REALSIZEIMAGE | NOT WS_VISIBLE
5fb77e ····LTEXT ··········"Passphrase Quality:",IDC_STATIC,6,98,63,8,NOT WS_GROUP
ab5dd8 ····CONTROL ········"Progress1",IDC_QUALITY_BAR,"msctls_progress32",
ac6172 ····················WS_BORDER,72,99,147,8
78e0d1 END
fdaf5a
ccbe69 IDD_GETUSERINFO_DLG DIALOGEX 0, 0, 181, 100
944300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
257541 EXSTYLE WS_EX_CONTEXTHELP
67ea76 CAPTION "PGPdisk User Information"
0b3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
ba4523 BEGIN
448e7a ····DEFPUSHBUTTON ··"OK",IDOK,65,78,50,14,WS_DISABLED
b1c045 ····PUSHBUTTON ·····"Cancel",IDCANCEL,123,78,50,14
bf9f50 ····LTEXT ··········"Your PGPdisk user information has been lost. Please re-ent¶
f6ca3e er your name and organization.",
2d4d66 ····················IDC_STATIC,7,6,167,19
03ab0e ····EDITTEXT ·······IDC_USER_EDIT,60,33,112,13,ES_AUTOHSCROLL
0be8f5 ····RTEXT ··········"&User Name:",IDC_STATIC,8,35,47,8
044fc5 ····RTEXT ··········"&Organization:",IDC_STATIC,8,53,47,8
f91494 ····EDITTEXT ·······IDC_ORG_EDIT,60,51,112,13,ES_AUTOHSCROLL
63e0d1 END
a7af5a
9bfed5 IDD_SPLASH_DLG DIALOG DISCARDABLE ·0, 0, 312, 197
9e73ce STYLE WS_POPUP
1d309f FONT 8, "MS Sans Serif"
a24523 BEGIN
90e0d1 END
eaaf5a
aaeb1a IDD_ABOUTBOX_DLG DIALOG DISCARDABLE ·0, 0, 312, 197
27fce7 STYLE WS_POPUP | WS_BORDER
3b309f FONT 8, "MS Sans Serif"
584523 BEGIN
5f7d76 ····PUSHBUTTON ·····"&Credits",IDC_CREDITS,142,180,50,14
9027df ····PUSHBUTTON ·····"&www.pgp.com",IDC_PGP_LINK,197,180,57,14
6fa994 ····PUSHBUTTON ·····"&OK",IDOK,258,180,50,14
d6e0d1 END
faaf5a
--c2c2 000d377d08640110072 Page 7 of PGPdiskApp.rc
727946 IDD_NAGBUY_DLG DIALOG DISCARDABLE ·0, 0, 298, 68
8c4300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
ee07c2 CAPTION "PGPdisk"
45309f FONT 8, "MS Sans Serif"
444523 BEGIN
933037 ····DEFPUSHBUTTON ··"OK",IDOK,241,48,50,14
2eeb62 ····PUSHBUTTON ·····"Cancel",IDCANCEL,185,48,50,14
ba98c0 ····DEFPUSHBUTTON ··"Buy Now!",IDC_BUYNOW_BUTTON,129,48,50,14
6e5499 ····LTEXT ··········"Static",IDC_NAGBUYMSG_TEXT,43,7,246,32
16c082 ····ICON ···········IDI_MAINFRAME,IDC_STATIC,8,5,20,20
08e0d1 END
97af5a
10df13 IDD_DISKWIZ_ADK DIALOG DISCARDABLE ·0, 0, 316, 167
5c6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
6c7b63 CAPTION "New PGPdisk Wizard"
c1309f FONT 8, "MS Sans Serif"
2b4523 BEGIN
8e6cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
1ae53f ····················160
9aa76c ····LTEXT ··········"This copy of PGP Desktop Security has been configured to u¶
45e37f se an Additional Decryption Key.",
68258b ····················IDC_STATIC,96,7,207,21
8bd69c ····LTEXT ··········"This means that everything encrypted on the disk which you¶
555d8b ·are creating will also be encrypted to the Additional Decryption Key.",
485102 ····················IDC_STATIC,96,33,207,24
d3dc1d ····LTEXT ··········"Additional Decryption Key :",IDC_STATIC,96,68,159,8
1f622b ····EDITTEXT ·······IDC_ADK,96,80,196,14,ES_AUTOHSCROLL | ES_READONLY
1b4435 ····LTEXT ··········"The Additional Decryption Key cannot be changed.",
7b1053 ····················IDC_STATIC,96,120,207,8
12e0d1 END
bfaf5a
425fe8 IDD_RANDDATA_DLG DIALOG DISCARDABLE ·0, 0, 291, 182
3a7844 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
d81081 CAPTION "Collecting Random Data"
a9309f FONT 8, "MS Sans Serif"
654523 BEGIN
d16a32 ····CTEXT ··········"Collecting Random Data:",IDC_DISKNAME_TEXT,39,100,214,8,
639294 ····················NOT WS_GROUP
cd4832 ····CONTROL ········"Progress1",IDC_PROGRESS_BAR,"msctls_progress32",
708c75 ····················WS_BORDER,39,113,214,11
4dbe00 ····LTEXT ··········"0%",IDC_STATIC,39,127,10,8,NOT WS_GROUP
d11ed5 ····RTEXT ··········"100%",IDC_STATIC,235,127,18,8,NOT WS_GROUP
10e8f2 ····LTEXT ··········"Converting PGPdisk to new CAST format.",IDC_STATIC,21,
cfc5db ····················15,211,17
2be0d1 END
beaf5a
8b461c IDD_CVRTWIZ_INTRO DIALOG DISCARDABLE ·0, 0, 316, 167
6a6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
0a197d CAPTION "PGPdisk Conversion Wizard"
bf309f FONT 8, "MS Sans Serif"
ae4523 BEGIN
216b3e ····LTEXT ··········"PGPdisks created with versions of PGPdisk prior to 6.0.2 c¶
6a8835 ontain an error and are not secure. This wizard allows you to convert the chose¶
072aab n PGPdisk from its current format to a newer, secure format.",
547177 ····················IDC_STATIC,98,4,214,33,NOT WS_GROUP
4d6cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
c4e53f ····················160
092e08 ····LTEXT ··········"Press ""Next"" to begin the conversion.",IDC_STATIC,98,
8a930c ····················79,214,8,NOT WS_GROUP
fae50c ····LTEXT ··········"Your main passphrase (and any PGPdisk ADKs) will remain th¶
a2a750 e same, but unfortunately any additional passphrases on the PGPdisk will be rem¶
1d86fc oved.",
d879ae ····················IDC_STATIC,98,42,214,25,NOT WS_GROUP
c0e0d1 END
6aaf5a
0fb99d IDD_CVRTWIZ_DONE DIALOG DISCARDABLE ·0, 0, 316, 167
0c6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
c3197d CAPTION "PGPdisk Conversion Wizard"
2d309f FONT 8, "MS Sans Serif"
454523 BEGIN
236cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
d3e53f ····················160
--b830 000db35fe2540110072 Page 8 of PGPdiskApp.rc
69d9b0 ····LTEXT ··········"Your PGPdisk has been successfully converted. You can now ¶
b8ee88 use it as you normally would.",
ee2719 ····················IDC_STATIC,98,4,214,20,NOT WS_GROUP
e7e0d1 END
9caf5a
c8666c IDD_CVRTWIZ_RANDOM DIALOG DISCARDABLE ·0, 0, 316, 167
ea6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
f8197d CAPTION "PGPdisk Conversion Wizard"
29309f FONT 8, "MS Sans Serif"
564523 BEGIN
af006e ····LTEXT ··········"In order to generate an encryption key, PGPdisk needs a ce¶
2189ba rtain amount of random data.",
0f5474 ····················IDC_STATIC,96,4,214,17,NOT WS_GROUP
ba3cf5 ····LTEXT ··········"Please type or move your mouse around inside this window u¶
fe1c9f ntil the progress bar below fills up.",
3bd0ca ····················IDC_STATIC,96,26,214,17,NOT WS_GROUP
bc5d04 ····CTEXT ··········"Collecting Random Data:",IDC_STATIC,96,66,214,8,NOT·
db1efd ····················WS_GROUP
f2e627 ····CONTROL ········"Progress1",IDC_RANDOM_BAR,"msctls_progress32",WS_BORDER,
9fc1ab ····················96,78,214,11
ca8729 ····LTEXT ··········"0%",IDC_STATIC,96,93,10,8,NOT WS_GROUP
e7ce6c ····RTEXT ··········"100%",IDC_STATIC,292,93,18,8,NOT WS_GROUP
0c25d5 ····LTEXT ··········"Press ""Next"" to begin the conversion process.",
c81fb5 ····················IDC_STATIC,96,155,214,8,NOT WS_GROUP
0c6cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
c8e53f ····················160
e9e0d1 END
caaf5a
4e0ad5 IDD_CVRTWIZ_CONVERT DIALOG DISCARDABLE ·0, 0, 316, 167
a06b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
b4197d CAPTION "PGPdisk Conversion Wizard"
ef309f FONT 8, "MS Sans Serif"
334523 BEGIN
b3e71d ····LTEXT ··········"Your new PGPdisk must now be converted.",IDC_STATIC,96,
9ca997 ····················4,214,9,NOT WS_GROUP
84a0ac ····LTEXT ··········"Depending on the size of the PGPdisk, this can take severa¶
b3a3bd l minutes to complete. If you choose to cancel the process, you can restart it ¶
512ec9 any time in the future by just attempting a mount. Until then, however, you won¶
d663fa 't be able to use the PGPdisk.",
85f348 ····················IDC_STATIC,96,18,214,33,NOT WS_GROUP
3cdeab ····LTEXT ··········"Press ""Next"" to finish the process.",IDC_STATIC,96,
225125 ····················155,214,8,NOT WS_GROUP
3e1f84 ····CTEXT ··········"Converting: Untitled.pgd",IDC_DISKNAME_TEXT,96,66,214,8,
ce9294 ····················NOT WS_GROUP
314832 ····CONTROL ········"Progress1",IDC_PROGRESS_BAR,"msctls_progress32",
326969 ····················WS_BORDER,96,78,214,11
d68729 ····LTEXT ··········"0%",IDC_STATIC,96,93,10,8,NOT WS_GROUP
2dce6c ····RTEXT ··········"100%",IDC_STATIC,292,93,18,8,NOT WS_GROUP
096cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
47e53f ····················160
32e0d1 END
67af5a
29f549 IDD_GLOBWIZ_INTRO DIALOG DISCARDABLE ·0, 0, 316, 167
0c6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
03f1b6 CAPTION "PGPdisk Global Conversion Wizard"
77309f FONT 8, "MS Sans Serif"
a94523 BEGIN
dd6b3e ····LTEXT ··········"PGPdisks created with versions of PGPdisk prior to 6.0.2 c¶
1969ef ontain an error and are not secure. This wizard will search your computer for o¶
d703a3 ld PGPdisks and convert them to a newer, secure format. Your data will not be m¶
35a4ec odified in any way.",
6c81b0 ····················IDC_STATIC,98,4,214,34,NOT WS_GROUP
c96cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
52e53f ····················160
e97c86 ····LTEXT ··········"Press ""Next"" to begin searching.",IDC_STATIC,98,121,
3e268f ····················214,8,NOT WS_GROUP
a58ae4 ····LTEXT ··········"The wizard will now search for old PGPdisks and display a ¶
730ffa list of those that it finds. You will then have the opportunity to select the P¶
69eb5b GPdisks you wish to convert before continuing.",
0fbddb ····················IDC_STATIC,98,47,214,26,NOT WS_GROUP
28d54c ····LTEXT ··········"Please note that the wizard cannot search network drives o¶
dbb8eb r removable media, so PGPdisks contained on those devices must be selected manu¶
--d4c5 000d0ca2d6340110072 Page 9 of PGPdiskApp.rc
790728 ally.",
f95187 ····················IDC_STATIC,98,83,214,26,NOT WS_GROUP
63e0d1 END
b0af5a
8a574b IDD_GLOBWIZ_DONE DIALOG DISCARDABLE ·0, 0, 316, 167
c66b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
e0f1b6 CAPTION "PGPdisk Global Conversion Wizard"
c9309f FONT 8, "MS Sans Serif"
d44523 BEGIN
cc6cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
cfe53f ····················160
110235 ····LTEXT ··········"The global conversion wizard is now complete. Remember, yo¶
6ccb18 u can always invoke it again by choosing ""Convert pre-v6.02 PGPdisks..."" from¶
133255 ·the ""File"" menu of the main PGPdisk application.",
949ff4 ····················IDC_STATIC,98,4,214,26,NOT WS_GROUP
dae0d1 END
2baf5a
f34f94 IDD_GLOBWIZ_SEARCH DIALOG DISCARDABLE ·0, 0, 316, 167
936b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
d6f1b6 CAPTION "PGPdisk Global Conversion Wizard"
46309f FONT 8, "MS Sans Serif"
e84523 BEGIN
87ec97 ····CTEXT ··········"Unconverted PGPdisks found:",-1,96,4,214,9,NOT WS_GROUP
4e7c0e ····LTEXT ··········"When finished, press ""Next"" to convert the selected PGPd¶
4fd6d0 isks.",
096997 ····················-1,96,155,214,8,NOT WS_GROUP
3e93a9 ····CTEXT ··········"Searching:",IDC_SEARCHSTATUS_TEXT,96,128,214,8,NOT·
cd1efd ····················WS_GROUP
e56cec ····CONTROL ········"",IDC_SIDEBAR,"Static",SS_BLACKFRAME | SS_SUNKEN,4,3,80,
69e53f ····················160
44d119 ····LTEXT ··········"C:\\",IDC_DIRNAME_TEXT,96,141,214,8,NOT WS_GROUP
e9c93d ····LISTBOX ········IDC_PGPDISKS_LIST,96,20,214,101,LBS_SORT |·
d5e0e2 ····················LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL |·
ae0f7e ····················LBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP
13e0d1 END
11af5a
d72652 IDD_SINGLEPASS3_DLG DIALOGEX 0, 0, 226, 101
c04300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
707541 EXSTYLE WS_EX_CONTEXTHELP
c61dc7 CAPTION "Public Key Passphrase"
ef3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
1a4523 BEGIN
4bd3f3 ····CONTROL ········"Please enter a public key passphase for ""MySecretDisk"":",
97a4b7 ····················IDC_SINGLEPASSMSG_TEXT,"Static",SS_LEFTNOWORDWRAP,6,6,
75223b ····················214,9,WS_EX_TRANSPARENT
ab0c46 ····LTEXT ··········"&Passphrase:",IDC_STATIC,6,27,40,8,NOT WS_GROUP,
8b1db1 ····················WS_EX_TRANSPARENT
493fd0 ····EDITTEXT ·······IDC_PASSPHRASE_EDIT,6,37,214,35,ES_MULTILINE |·
9c90de ····················WS_VSCROLL
1aa934 ····CONTROL ········"&Hide Typing",IDC_HIDETYPE_CHECK,"Button",
ce9ed4 ····················BS_AUTOCHECKBOX | WS_TABSTOP,162,26,54,8
0bd28e ····DEFPUSHBUTTON ··"&OK",IDOK,114,81,50,14
03daad ····PUSHBUTTON ·····"&Cancel",IDCANCEL,170,81,50,14
3433f0 ····ICON ···········IDI_CAPSLOCK,IDC_CAPSLOCK_TEXT,7,75,20,20,
666653 ····················SS_REALSIZEIMAGE | NOT WS_VISIBLE
73e0d1 END
a5af5a
74af5a
a66c0e /////////////////////////////////////////////////////////////////////////////
f6465d //
ef6077 // DESIGNINFO
83465d //
cfaf5a
0ff860 #ifdef APSTUDIO_INVOKED
4170e4 GUIDELINES DESIGNINFO DISCARDABLE·
bb4523 BEGIN
a5bd9a ····IDD_MAIN_DLG, DIALOG
425574 ····BEGIN
00d0ad ········LEFTMARGIN, 6
71b94c ········RIGHTMARGIN, 177
e687e9 ········TOPMARGIN, 7
d014bf ········BOTTOMMARGIN, 34
--2c02 000b9021c5940110072 Page 10 of PGPdiskApp.rc
3e7d01 ····END
94af5a
d9bdcf ····IDD_PROP_AUTO, DIALOG
5c5574 ····BEGIN
7fc975 ········LEFTMARGIN, 7
de8a94 ········RIGHTMARGIN, 209
fd87e9 ········TOPMARGIN, 7
a3311a ········BOTTOMMARGIN, 48
987d01 ····END
e3af5a
87d4c8 ····IDD_SINGLEPASS1_DLG, DIALOG
7e5574 ····BEGIN
2dc975 ········LEFTMARGIN, 7
64d048 ········RIGHTMARGIN, 219
ec87e9 ········TOPMARGIN, 7
51beff ········BOTTOMMARGIN, 107
527d01 ····END
76af5a
d6eb3e ····IDD_UNMOUNT_DLG, DIALOG
295574 ····BEGIN
84c975 ········LEFTMARGIN, 7
926b94 ········RIGHTMARGIN, 153
c487e9 ········TOPMARGIN, 7
ced5b2 ········BOTTOMMARGIN, 43
f17d01 ····END
24af5a
9a9c80 ····IDD_PROP_HOTKEY, DIALOG
355574 ····BEGIN
66c975 ········LEFTMARGIN, 7
a88a94 ········RIGHTMARGIN, 209
f187e9 ········TOPMARGIN, 7
16311a ········BOTTOMMARGIN, 48
0d7d01 ····END
c0af5a
a3fec5 ····IDD_CONFIRMPASS1_DLG, DIALOG
235574 ····BEGIN
1fc975 ········LEFTMARGIN, 7
50d048 ········RIGHTMARGIN, 219
7f87e9 ········TOPMARGIN, 7
e9783d ········BOTTOMMARGIN, 187
2b7d01 ····END
67af5a
a557f6 ····IDD_SINGLEPASS2_DLG, DIALOG
2a5574 ····BEGIN
2dc975 ········LEFTMARGIN, 7
c4d048 ········RIGHTMARGIN, 219
8687e9 ········TOPMARGIN, 7
7f67c5 ········BOTTOMMARGIN, 94
2c7d01 ····END
69af5a
b49eed ····IDD_DISKWIZ_RANDOM, DIALOG
bc5574 ····BEGIN
3e71fe ········BOTTOMMARGIN, 166
257d01 ····END
86af5a
aa3c1e ····IDD_DISKWIZ_VOLINFO, DIALOG
0c5574 ····BEGIN
b371fe ········BOTTOMMARGIN, 166
537d01 ····END
b4af5a
b1d4b0 ····IDD_DISKWIZ_PASSPHRASE, DIALOG
0b5574 ····BEGIN
2771fe ········BOTTOMMARGIN, 166
f07d01 ····END
6daf5a
b61dda ····IDD_DISKWIZ_CREATION, DIALOG
805574 ····BEGIN
0f962f ········RIGHTMARGIN, 309
e171fe ········BOTTOMMARGIN, 166
047d01 ····END
c3af5a
b9d22f ····IDD_DISKWIZ_INTRO, DIALOG
--5032 0002f6fbee440110072 Page 11 of PGPdiskApp.rc
5c5574 ····BEGIN
8b962f ········RIGHTMARGIN, 309
d271fe ········BOTTOMMARGIN, 166
8e7d01 ····END
2daf5a
df2229 ····IDD_DISKWIZ_DONE, DIALOG
b85574 ····BEGIN
ec962f ········RIGHTMARGIN, 309
8a71fe ········BOTTOMMARGIN, 166
0d7d01 ····END
16af5a
737dfb ····IDD_CONFIRMPASS2_DLG, DIALOG
085574 ····BEGIN
22c975 ········LEFTMARGIN, 7
fed048 ········RIGHTMARGIN, 219
7387e9 ········TOPMARGIN, 7
0a783d ········BOTTOMMARGIN, 187
c17d01 ····END
5aaf5a
b5ef9d ····IDD_GETUSERINFO_DLG, DIALOG
b65574 ····BEGIN
d4c975 ········LEFTMARGIN, 7
769324 ········RIGHTMARGIN, 174
4387e9 ········TOPMARGIN, 7
8c2acd ········BOTTOMMARGIN, 93
cc7d01 ····END
2faf5a
86ec97 ····IDD_SPLASH_DLG, DIALOG
ed5574 ····BEGIN
e4c975 ········LEFTMARGIN, 7
8e3f8f ········RIGHTMARGIN, 305
bb87e9 ········TOPMARGIN, 7
1c6fe9 ········BOTTOMMARGIN, 190
ec7d01 ····END
cbaf5a
eeb45e ····IDD_ABOUTBOX_DLG, DIALOG
ea5574 ····BEGIN
70c975 ········LEFTMARGIN, 7
323f8f ········RIGHTMARGIN, 305
ce87e9 ········TOPMARGIN, 7
ef6fe9 ········BOTTOMMARGIN, 190
5e7d01 ····END
44af5a
9dd02d ····IDD_NAGBUY_DLG, DIALOG
e45574 ····BEGIN
edc975 ········LEFTMARGIN, 7
36d84a ········RIGHTMARGIN, 291
7a87e9 ········TOPMARGIN, 7
7d53ba ········BOTTOMMARGIN, 61
bc7d01 ····END
c0af5a
79e251 ····IDD_DISKWIZ_ADK, DIALOG
bd5574 ····BEGIN
e8962f ········RIGHTMARGIN, 309
2571fe ········BOTTOMMARGIN, 166
767d01 ····END
50af5a
a189a5 ····IDD_RANDDATA_DLG, DIALOG
9d5574 ····BEGIN
47c975 ········LEFTMARGIN, 7
6cfc2e ········RIGHTMARGIN, 284
a787e9 ········TOPMARGIN, 7
4f014a ········BOTTOMMARGIN, 175
c67d01 ····END
85af5a
723496 ····IDD_CVRTWIZ_INTRO, DIALOG
5b5574 ····BEGIN
72962f ········RIGHTMARGIN, 309
a271fe ········BOTTOMMARGIN, 166
2d7d01 ····END
28af5a
2f9dd8 ····IDD_CVRTWIZ_DONE, DIALOG
--00b5 000013042d740110072 Page 12 of PGPdiskApp.rc
5c5574 ····BEGIN
8b962f ········RIGHTMARGIN, 309
d271fe ········BOTTOMMARGIN, 166
8e7d01 ····END
2daf5a
34b641 ····IDD_CVRTWIZ_RANDOM, DIALOG
bb5574 ····BEGIN
8871fe ········BOTTOMMARGIN, 166
ce7d01 ····END
4baf5a
75ab85 ····IDD_CVRTWIZ_CONVERT, DIALOG
9b5574 ····BEGIN
80962f ········RIGHTMARGIN, 309
cb71fe ········BOTTOMMARGIN, 166
697d01 ····END
7caf5a
37d040 ····IDD_GLOBWIZ_INTRO, DIALOG
ec5574 ····BEGIN
52962f ········RIGHTMARGIN, 309
cd71fe ········BOTTOMMARGIN, 166
4e7d01 ····END
d4af5a
935d0b ····IDD_GLOBWIZ_DONE, DIALOG
b85574 ····BEGIN
c8962f ········RIGHTMARGIN, 309
bb71fe ········BOTTOMMARGIN, 166
e87d01 ····END
b1af5a
30e7f7 ····IDD_GLOBWIZ_SEARCH, DIALOG
bf5574 ····BEGIN
67962f ········RIGHTMARGIN, 309
4271fe ········BOTTOMMARGIN, 166
657d01 ····END
1faf5a
ca291c ····IDD_SINGLEPASS3_DLG, DIALOG
7d5574 ····BEGIN
83c975 ········LEFTMARGIN, 7
29d048 ········RIGHTMARGIN, 219
2a87e9 ········TOPMARGIN, 7
fb67c5 ········BOTTOMMARGIN, 94
607d01 ····END
5be0d1 END
0069ab #endif ···// APSTUDIO_INVOKED
84af5a
f0af5a
566c0e /////////////////////////////////////////////////////////////////////////////
de465d //
b8ae70 // Bitmap
fe465d //
5daf5a
c05e92 IDB_SIDEBAR1 ···········BITMAP ·DISCARDABLE ····"Res\\Sidebar1.bmp"
828f07 IDB_SPLASHSCREEN1 ······BITMAP ·DISCARDABLE ····"Res\\SplashScreen1.bmp"
43e50d IDB_SPLASHSCREEN4 ······BITMAP ·DISCARDABLE ····"Res\\SplashScreen4.bmp"
1f3498 IDB_SIDEBAR4 ···········BITMAP ·DISCARDABLE ····"Res\\Sidebar4.bmp"
f58f02 IDB_CREDITS1 ···········BITMAP ·DISCARDABLE ····"Res\\Credits1.bmp"
6f851a IDB_SPLASHSCREEN8 ······BITMAP ·DISCARDABLE ····"Res\\SplashScreen8.bmp"
21548f IDB_SIDEBAR8 ···········BITMAP ·DISCARDABLE ····"Res\\Sidebar8.bmp"
d2e508 IDB_CREDITS4 ···········BITMAP ·DISCARDABLE ····"Res\\Credits4.bmp"
48851f IDB_CREDITS8 ···········BITMAP ·DISCARDABLE ····"Res\\Credits8.bmp"
30af5a
7c6c0e /////////////////////////////////////////////////////////////////////////////
34465d //
2386c0 // Menu
88465d //
e1af5a
62ed7e IDR_MAIN_MENU MENU DISCARDABLE·
c94523 BEGIN
4cb474 ····POPUP "&File"
195574 ····BEGIN
87c015 ········MENUITEM "&New PGPdisk...\tCtrl+N", ····IDM_NEWPGPDISK
3712bc ········MENUITEM "&Mount PGPdisk...\tCtrl+M", ··IDM_MOUNTPGPDISK
01330d ········MENUITEM "&Unmount PGPdisk...\tCtrl+U", IDM_UNMOUNTPGPDISK
--9679 0012eaf11fd40110072 Page 13 of PGPdiskApp.rc
77592d ········MENUITEM SEPARATOR
2ea26f ········MENUITEM "&Add Passphrase...", ·········IDM_ADDPASS
b7afaf ········MENUITEM "&Change Passphrase...", ······IDM_CHANGEPASS
3d3be6 ········MENUITEM "&Remove Passphrase...", ······IDM_REMOVEPASS
2ab115 ········MENUITEM "Add/Remove Public &Keys...", ·IDM_PUBLICKEYS
7c7ad9 ········MENUITEM "Convert pre-v6.02 PGPdisks...", IDM_GLOBALCONVERT
bd592d ········MENUITEM SEPARATOR
6681a5 ········MENUITEM "&Preferences...\tCtrl+R", ····IDM_PREFS
4c592d ········MENUITEM SEPARATOR
dcd6bc ········MENUITEM "E&xit\tCtrl+Q", ··············IDM_EXIT
fc7d01 ····END
c046ce ····POPUP "&Help"
345574 ····BEGIN
c6fc27 ········MENUITEM "&Contents", ··················IDM_HELPCONTENTS
541eb9 ········MENUITEM "&About PGPdisk...", ··········IDM_ABOUT
827d01 ····END
f7e0d1 END
c3af5a
8aaf5a
066c0e /////////////////////////////////////////////////////////////////////////////
ea465d //
155a93 // Accelerator
fb465d //
5faf5a
e6ed0f IDR_MAINDLG_ACCEL ACCELERATORS DISCARDABLE·
374523 BEGIN
e8633b ····"M", ···········IDM_MOUNTPGPDISK, ······VIRTKEY, NOINVERT
bd28c2 ····"M", ···········IDM_MOUNTPGPDISK, ······VIRTKEY, CONTROL, NOINVERT
85b8ec ····"M", ···········IDM_MOUNTPGPDISK, ······VIRTKEY, ALT, NOINVERT
44ac04 ····"N", ···········IDM_NEWPGPDISK, ········VIRTKEY, NOINVERT
07a9e6 ····"N", ···········IDM_NEWPGPDISK, ········VIRTKEY, CONTROL, NOINVERT
2e8fe1 ····"N", ···········IDM_NEWPGPDISK, ········VIRTKEY, ALT, NOINVERT
16dd37 ····"Q", ···········IDM_EXIT, ··············VIRTKEY, CONTROL, NOINVERT
a61aa7 ····"R", ···········IDM_PREFS, ·············VIRTKEY, NOINVERT
e777d4 ····"R", ···········IDM_PREFS, ·············VIRTKEY, CONTROL, NOINVERT
5d52ef ····"R", ···········IDM_PREFS, ·············VIRTKEY, ALT, NOINVERT
9799d5 ····"U", ···········IDM_UNMOUNTPGPDISK, ····VIRTKEY, NOINVERT
b743d2 ····"U", ···········IDM_UNMOUNTPGPDISK, ····VIRTKEY, CONTROL, NOINVERT
245937 ····"U", ···········IDM_UNMOUNTPGPDISK, ····VIRTKEY, ALT, NOINVERT
8fe0d1 END
eeaf5a
541b3a #endif ···// English (U.S.) resources
d76c0e /////////////////////////////////////////////////////////////////////////////
c5af5a
8eaf5a
53af5a
74ce8c #ifndef APSTUDIO_INVOKED
3b6c0e /////////////////////////////////////////////////////////////////////////////
e4465d //
678464 // Generated from the TEXTINCLUDE 3 resource.
3f465d //
adab42 #define _AFX_NO_SPLITTER_RESOURCES
b3fc7b #define _AFX_NO_OLE_RESOURCES
541ee7 #define _AFX_NO_TRACKER_RESOURCES
4596c6 #define _AFX_NO_PROPERTY_RESOURCES
aeaf5a
181201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
17ec08 #ifdef _WIN32
c36f14 LANGUAGE 9, 1
cb9c1c #pragma code_page(1252)
967454 #endif
10922c #include "res\PGPdiskApp.rc2" ·// non-Microsoft Visual C++ edited resources
ffbb63 #include "afxres.rc" ·········// Standard components
ba7454 #endif
c7af5a
981efa #include "PGPdiskAppVer.rc"
3f6c0e /////////////////////////////////////////////////////////////////////////////
1b8072 #endif ···// not APSTUDIO_INVOKED
2eaf5a
--0a87 0015e46238540110073 Page 1 of PGPdiskAppVer.rc
b3eddb // VERSIONINFO structure which automatically include version
f014b6 // string from PGPdiskVersion.h
a6465d //
ed0380 #include <winver.h>
7b5a72 #include "..\Shared\PGPdiskVersion.h"
2aaf5a
016c0e /////////////////////////////////////////////////////////////////////////////
64465d //
29c5f2 // Version
f4465d //
5faf5a
0a8df2 VS_VERSION_INFO VERSIONINFO
e75e85 ·FILEVERSION kPGPdiskFileVerData
e16589 ·PRODUCTVERSION kPGPdiskProductVerData
29a381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
4b1f29 #ifdef _DEBUG
637c0e ·FILEFLAGS VS_FF_DEBUG
6cdb21 #else
db12ca ·FILEFLAGS 0x0L
e57454 #endif
e003bb ·FILEOS VOS__WINDOWS32
df2042 ·FILETYPE VFT_APP
5a7247 ·FILESUBTYPE VFT2_UNKNOWN
6c4523 BEGIN
102c72 ····BLOCK "StringFileInfo"
e85574 ····BEGIN
4e70ac ········BLOCK "040904b0"
ef52d6 ········BEGIN
a8f777 ············VALUE "CompanyName", kPGPdiskCompanyName
96ff97 ············VALUE "FileDescription", "PGPdisk Application\0"
3b126d ············VALUE "FileVersion", kPGPdiskFileVerString
6774fa ············VALUE "InternalName", "PGPdisk.exe\0"
1ef2bf ············VALUE "LegalCopyright", kPGPdiskCopyright
ec613b ············VALUE "OriginalFilename", "PGPdisk.exe\0"
7d1fa9 ············VALUE "ProductName", kPGPdiskProductVerName
517b64 ············VALUE "ProductVersion", kPGPdiskProductVerString
e9f37f ········END
757d01 ····END
7226ab ····BLOCK "VarFileInfo"
9d5574 ····BEGIN
514b11 ········VALUE "Translation", 0x409, 1200
ff7d01 ····END
5ee0d1 END

--5ca3 0011d779f9240110074 Page 1 of PGPdiskApp.rc2
c1465d //
563d62 // PGPdiskApp.RC2 - resources Microsoft Visual C++ does not edit directly
0c465d //
98af5a
2af860 #ifdef APSTUDIO_INVOKED
3580ec ¤   #error this file is not editable by Microsoft Visual C++
da4e5a #endif //APSTUDIO_INVOKED
d1af5a
70af5a
e76c0e /////////////////////////////////////////////////////////////////////////////
895eca // Add manually edited resources here...
5aaf5a
1d6c0e /////////////////////////////////////////////////////////////////////////////
--2fc6 0004760fd6540110075 Page 1 of CAboutBoxDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
cb1bbb // CAboutBoxDialog.cpp
bd465d //
93a0ab // Implementation of the CAboutBoxDialog class.
e01bc3 //////////////////////////////////////////////////////////////////////////////
3daf5a
591b31 // $Id: CAboutBoxDialog.cpp,v 1.1.2.8 1998/07/06 08:56:41 nryan Exp $
09af5a
abcbce // Copyright (C) 1998 by Network Associates, Inc.
e471ae // All rights reserved.
1daf5a
c29e12 #include "StdAfx.h"
8faf5a
859bcf #include "Required.h"
ea993c #include "StringAssociation.h"
77bfe9 #include "UtilityFunctions.h"
d3af5a
8b8fed #include "CAboutBoxDialog.h"
693646 #include "CMainDialog.h"
765e8f #include "CPGPdiskApp.h"
ddc411 #include "Globals.h"
9e4713 #include "PGPdiskHelpIds.h"
41af5a
24af5a
7909b7 ////////////
0fe738 // Constants
3609b7 ////////////
d5af5a
e2cfe9 const PGPUInt32 kAboutBoxVersionTextX¤  = 433;
d8ad8b const PGPUInt32 kAboutBoxVersionTextY¤  = 208;
34af5a
407fdd const PGPUInt32 kAboutBoxRegTextX¤  = 296;
16f6e2 const PGPUInt32 kAboutBoxRegTextY¤  = 236;
f7af5a
f2af5a
786cc2 /////////////////////
fb3a71 // Context help array
c46cc2 /////////////////////
89af5a
5f77bf static PGPUInt32 HelpIds[] =
1ebb36 {
72a622 ¤   IDOK,¤  ¤   ¤   ¤   IDH_PGPDISKAPP_ABOUTBOXOK,·
0f55cf ¤   IDC_CREDITS,¤   ¤   IDH_PGPDISKAPP_ABOUTBOXCREDITS,·
1b3d2d ¤   IDC_PGP_LINK,¤  ¤   IDH_PGPDISKAPP_ABOUTBOXPGPLINK,·
c14434 ····0,0·
7e82f7 };
f6af5a
6eaf5a
8f83f5 ///////////////////////////
7bb249 // MFC specific definitions
5d83f5 ///////////////////////////
72af5a
d9627d BEGIN_MESSAGE_MAP(CAboutBoxDialog, CDialog)
e6a1b5 ¤   //{{AFX_MSG_MAP(CAboutBoxDialog)
6bdb65 ¤   ON_WM_HELPINFO()
0a2fa5 ¤   ON_WM_PAINT()
09c08c ¤   ON_BN_CLICKED(IDC_CREDITS, OnCreditsButton)
74c410 ¤   ON_BN_CLICKED(IDC_PGP_LINK, OnPGPLinkButton)
c0044a ¤   //}}AFX_MSG_MAP
28af28 END_MESSAGE_MAP()
08af5a
26af5a
5e7cc3 ///////////////////////////////////////////////////////////////////////////
05b03f // CAboutBoxDialog public custom functions and non-default message handlers
407cc3 ///////////////////////////////////////////////////////////////////////////
a6af5a
d868d1 // The CAboutBoxDialog default constructor.
baaf5a
0d3e98 CAboutBoxDialog::CAboutBoxDialog(CWnd *pParent)·
3345b6 ¤   : CDialog(CAboutBoxDialog::IDD, pParent)
22bb36 {
4778f1 ¤   try
--ddde 0001aaedd3b40110075 Page 2 of CAboutBoxDialog.cpp
f7c7a1 ¤   {
204f75 ¤   ¤   //{{AFX_DATA_INIT(CAboutBoxDialog)
fd765d ¤   ¤   //}}AFX_DATA_INIT
8faf5a
cb141b ¤   ¤   mShowingCredits = FALSE;
189371 ¤   }
113c88 ¤   catch (CMemoryException *ex)
43c7a1 ¤   {
e56adc ¤   ¤   ex->Delete();
889371 ¤   }
7eefe6 }
fbaf5a
350031 // DisplayAboutBox is a wrapper around DoModal.
99af5a
0b2292 DualErr·
18314c CAboutBoxDialog::DisplayAboutBox()
55bb36 {
fbbe41 ¤   DualErr¤¤   derr;
abe319 ¤   PGPInt32¤   result;
9867c5 ¤
2d0acb ¤   result = DoModal();
63af5a
28cff3 ¤   switch (result)
e2c7a1 ¤   {
b2e379 ¤   case -1:
b0fdbb ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
ab2f68 ¤   ¤   break;
eb9371 ¤   }
55af5a
6c33e3 ¤   return derr;
aeefe6 }
cfaf5a
60af5a
551bc3 //////////////////////////////////////////////////////////////////////////////
42d0b9 // CAboutBoxDialog protected custom functions and non-default message handlers
bd1bc3 //////////////////////////////////////////////////////////////////////////////
32af5a
ba9a64 // The CAboutBoxDialog default data-exchange function.
5aaf5a
18c823 void·
2878d5 CAboutBoxDialog::DoDataExchange(CDataExchange *pDX)
cfbb36 {
8478f1 ¤   try
a8c7a1 ¤   {
f6f4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
5faf5a
a8d96f ¤   ¤   //{{AFX_DATA_MAP(CAboutBoxDialog)
a2d578 ¤   ¤   DDX_Control(pDX, IDC_PGP_LINK, mPGPLinkButton);
25dff4 ¤   ¤   DDX_Control(pDX, IDC_CREDITS, mCreditsButton);
b13376 ¤   ¤   //}}AFX_DATA_MAP
4a9371 ¤   }
513c88 ¤   catch (CMemoryException *ex)
89c7a1 ¤   {
c36adc ¤   ¤   ex->Delete();
d59371 ¤   }
7fefe6 }
1aaf5a
1d51f4 // OnCreditsButton is called when the credits button is clicked. Switch
6de3d1 // between the credits and graphics screen.
93af5a
d4c823 void·
c4516a CAboutBoxDialog::OnCreditsButton()·
f1bb36 {
542add ¤   if (mShowingCredits)
d2c7a1 ¤   {
cb141b ¤   ¤   mShowingCredits = FALSE;
0f32b3 ¤   ¤   mCreditsButton.SetWindowText("&Credits");
f29371 ¤   }
f80e24 ¤   else
50c7a1 ¤   {
7d7a64 ¤   ¤   mShowingCredits = TRUE;
1a68bb ¤   ¤   mCreditsButton.SetWindowText("&Info");
--4f3e 0000d89ab3740110075 Page 3 of CAboutBoxDialog.cpp
a19371 ¤   }
93af5a
9eec1e ¤   InvalidateRect(NULL);
dcefe6 }
ffaf5a
f78a56 // OnPGPLinkButton is called when the user clicks on the "www.pgp.com" button.
ef3c2a // We go to PGP's web site.
15af5a
23c823 void·
703073 CAboutBoxDialog::OnPGPLinkButton()·
03bb36 {
a65608 ¤   ShellExecute(App->mMainDialog->GetSafeHwnd(), "open",·
2a0123 ¤   ¤   GetCommonString(kPGPdiskURL), NULL, "C:\\", SW_SHOWNORMAL);
89af5a
78bfc0 ¤   EndDialog(IDOK);
dfefe6 }
07af5a
62af5a
b2c3ce /////////////////////////////////////////////////////
165b0a // CAboutBoxDialog protected default message handlers
24c3ce /////////////////////////////////////////////////////
d0af5a
038cca // OnHelpInfo handles context-sensitive help.
17af5a
fb7efe BOOL·
14397e CAboutBoxDialog::OnHelpInfo(HELPINFO *pHelpInfo)
c7bb36 {
3229b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
54e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
f3c7a1 ¤   {
31ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
026b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
b69371 ¤   }
3caf5a
31c2e7 ¤   return TRUE;
98efe6 }
54af5a
d55252 // OnInitDialog is called when the dialog box is created.
71af5a
057efe BOOL·
43e228 CAboutBoxDialog::OnInitDialog()
07bb36 {
af18a8 ¤   HDC¤¤   ¤   hDC;
e91b02 ¤   PGPBoolean¤ loadedBitmap;
c72e01 ¤   PGPUInt32¤  numBits;
a3af5a
58c799 ¤   CDialog::OnInitDialog();
6baf5a
9a9c14 ¤   // Get screen depth.
39ff18 ¤   hDC = ::GetDC(NULL);¤   ¤   // DC for desktop
533968 ¤   numBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
306ec2 ¤   ::ReleaseDC(NULL, hDC);
08af5a
9f83bc ¤   // Load the bitmaps and create palettes for them.
364932 ¤   if (numBits <= 1)
8dc7a1 ¤   {
e8b46f ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SPLASHSCREEN1,·
d80ea2 ¤   ¤   ¤   &mAboutBitmap, &mAboutPalette);
61af5a
86dbb2 ¤   ¤   if (loadedBitmap)
495b34 ¤   ¤   {
38154c ¤   ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_CREDITS1,·
f56402 ¤   ¤   ¤   ¤   &mCreditsBitmap, &mCreditsPalette);
6d0fe4 ¤   ¤   }
53af5a
350a8d ¤   ¤   mRegTextColor¤  ¤   = RGB(255, 255, 255);
b19bfe ¤   ¤   mVersionTextColor¤  = RGB(255, 255, 255);
b89371 ¤   }
39d872 ¤   else if (numBits <= 4)
22c7a1 ¤   {
b4da38 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SPLASHSCREEN4,·
0d0ea2 ¤   ¤   ¤   &mAboutBitmap, &mAboutPalette);
--ff18 00077a55ffd40110075 Page 4 of CAboutBoxDialog.cpp
e0af5a
12dbb2 ¤   ¤   if (loadedBitmap)
0c5b34 ¤   ¤   {
0e7b1b ¤   ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_CREDITS4,·
996402 ¤   ¤   ¤   ¤   &mCreditsBitmap, &mCreditsPalette);
310fe4 ¤   ¤   }
caaf5a
fd0a8d ¤   ¤   mRegTextColor¤  ¤   = RGB(255, 255, 255);
639bfe ¤   ¤   mVersionTextColor¤  = RGB(255, 255, 255);
cd9371 ¤   }
bf0e24 ¤   else
dec7a1 ¤   {
914d0c ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SPLASHSCREEN8,·
b50ea2 ¤   ¤   ¤   &mAboutBitmap, &mAboutPalette);
2caf5a
82dbb2 ¤   ¤   if (loadedBitmap)
ba5b34 ¤   ¤   {
a0ec2f ¤   ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_CREDITS8,·
036402 ¤   ¤   ¤   ¤   &mCreditsBitmap, &mCreditsPalette);
620fe4 ¤   ¤   }
67af5a
ad0a8d ¤   ¤   mRegTextColor¤  ¤   = RGB(255, 255, 255);
529bfe ¤   ¤   mVersionTextColor¤  = RGB(255, 255, 255);
7a9371 ¤   }
f8af5a
26009c ¤   // Determine its width and height.
a75ea3 ¤   if (!loadedBitmap || !mAboutBitmap.GetBitmap(&mBitmapInfo))
eec7a1 ¤   {
636611 ¤   ¤   EndDialog(IDCANCEL);
e29371 ¤   }
4567c5 ¤
e8d564 ¤   // Center on screen.
7850f9 ¤   CenterWindow(GetDesktopWindow());
41af5a
d7afdc ¤   // Put us in front.
ed9974 ¤   SetForegroundWindow();
c0af5a
ed54ed ¤   // Put on top if necessary.
f1c3a9 ¤   App->TweakOnTopAttribute(this);
6daf5a
b39b5a ¤   // Show now to thwart evil MFC auto-centering.
16c56d ¤   ShowWindow(SW_SHOW);
46af5a
20c2e7 ¤   return TRUE;
5fefe6 }
abaf5a
f7c7f0 // We override OnPaint to paint our graphics.
37af5a
1dc823 void·
bcc76e CAboutBoxDialog::OnPaint()·
f8bb36 {
cb0575 ¤   CDC¤¤   ¤   memDC;
48c943 ¤   CPaintDC¤   DC(this);
cee3a1 ¤   HBITMAP¤¤   oldBitmap;
36af5a
662add ¤   if (mShowingCredits)
f3c7a1 ¤   {
f3dae1 ¤   ¤   DC.SelectPalette(&mCreditsPalette, FALSE);
eefb55 ¤   ¤   DC.RealizePalette();
a1af5a
d68fa6 ¤   ¤   memDC.CreateCompatibleDC(&DC);
9dfbd7 ¤   ¤   memDC.SelectPalette(&mCreditsPalette, FALSE);
1016dd ¤   ¤   memDC.RealizePalette();
16af5a
a2936e ¤   ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
f1f54a ¤   ¤   // don't fool with it.
52af5a
814cdd ¤   ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mCreditsBitmap);
f29371 ¤   }
af0e24 ¤   else
40c7a1 ¤   {
77d156 ¤   ¤   DC.SelectPalette(&mAboutPalette, FALSE);
--430c 0017ae0691540110075 Page 5 of CAboutBoxDialog.cpp
92fb55 ¤   ¤   DC.RealizePalette();
86af5a
258fa6 ¤   ¤   memDC.CreateCompatibleDC(&DC);
485a33 ¤   ¤   memDC.SelectPalette(&mAboutPalette, FALSE);
1316dd ¤   ¤   memDC.RealizePalette();
85af5a
ce936e ¤   ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
69f54a ¤   ¤   // don't fool with it.
3baf5a
b286fb ¤   ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mAboutBitmap);
1a9371 ¤   }
8faf5a
4fcd8a ¤   // Draw the user and version strings.
7bc3fa ¤   App->PaintRegistrationInfo(&memDC, kAboutBoxRegTextX,·
7142d0 ¤   ¤   kAboutBoxRegTextY, mRegTextColor, this);
68af5a
d327b6 ¤   if (!mShowingCredits)
9cc7a1 ¤   {
320564 ¤   ¤   App->PaintVersionInfo(&memDC, kAboutBoxVersionTextX,·
f0e61d ¤   ¤   ¤   kAboutBoxVersionTextY, mVersionTextColor, this);
2b9371 ¤   }
9caf5a
466156 ¤   DC.BitBlt(0, 0, mBitmapInfo.bmWidth, mBitmapInfo.bmHeight, &memDC, 0, 0,·
a3d8c9 ¤   ¤   SRCCOPY);
4eaf5a
86ac4f ¤   memDC.SelectObject(oldBitmap);
5663a9 ¤   memDC.DeleteDC();
7aefe6 }
--e647 00148e5e91940110076 Page 1 of CAboutBoxDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
2f9774 // CAboutBoxDialog.h
c1465d //
cd2c9c // Declaration of class CAboutBoxDialog.
d21bc3 //////////////////////////////////////////////////////////////////////////////
a8af5a
86f899 // $Id: CAboutBoxDialog.h,v 1.1.2.3 1998/07/06 08:56:42 nryan Exp $
47af5a
9acbce // Copyright (C) 1998 by Network Associates, Inc.
6f71ae // All rights reserved.
59af5a
0c9308 #ifndef Included_CAboutBoxDialog_h¤ // [
c755dc #define Included_CAboutBoxDialog_h
48af5a
e4ab81 #include "Resource.h"
8faf5a
49af5a
1fd48e ////////////////////////
4984ea // Class CAboutBoxDialog
cbd48e ////////////////////////
46af5a
40ad1a class CAboutBoxDialog : public CDialog
81bb36 {
095ed4 public:
2439c7 ¤   ¤   ¤   CAboutBoxDialog(CWnd *pParent = NULL);
80af5a
a9aff9 ¤   DualErr¤DisplayAboutBox();
9eaf5a
6a278c ¤   //{{AFX_DATA(CAboutBoxDialog)
38eef8 ¤   enum { IDD = IDD_ABOUTBOX_DLG };
c85b3f ¤   CButton¤mPGPLinkButton;
4d61c0 ¤   CButton¤mCreditsButton;
c65139 ¤   //}}AFX_DATA
74af5a
2e9cd2 ¤   //{{AFX_VIRTUAL(CAboutBoxDialog)
38c369 ¤   protected:
243e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
c3af53 ¤   //}}AFX_VIRTUAL
fdaf5a
63a2d3 protected:
f6e27f ¤   PGPBoolean¤ mShowingCredits;¤   // showing credits or graphics?
a8af5a
3b7006 ¤   BITMAP¤ ¤   mBitmapInfo;¤   ¤   // info for the bitmap
c44d7e ¤   CBitmap¤¤   mAboutBitmap;¤  ¤   // about graphic
aa114b ¤   CBitmap¤¤   mCreditsBitmap;¤¤   // credits graphic
e1e890 ¤   CPalette¤   mAboutPalette;¤ ¤   // about palette
2095b8 ¤   CPalette¤   mCreditsPalette;¤   // credits palette
bcaf5a
f63bdf ¤   COLORREF¤   mRegTextColor;¤ ¤   // color for registration text
0bcfef ¤   COLORREF¤   mVersionTextColor;¤ // color for version text
7aaf5a
67ab07 ¤   //{{AFX_MSG(CAboutBoxDialog)
c9698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
3af17a ¤   virtual BOOL OnInitDialog();
f6c5f3 ¤   afx_msg void OnPaint();
fb12b9 ¤   afx_msg void OnCreditsButton();
fb73a0 ¤   afx_msg void OnPGPLinkButton();
7d2e09 ¤   //}}AFX_MSG
26af5a
3c2409 ¤   DECLARE_MESSAGE_MAP()
3282f7 };
ceaf5a
6cc18c //{{AFX_INSERT_LOCATION}}
69af5a
482353 #endif¤ // ] Included_CAboutBoxDialog_h
--1fe5 0008ba469b940110077 Page 1 of CConfirmPassphraseDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
905bb0 // CConfirmPassphraseDialog.cpp
26465d //
af110e // Implementation of the CConfirmPassphraseDialog class.
481bc3 //////////////////////////////////////////////////////////////////////////////
36af5a
792969 // $Id: CConfirmPassphraseDialog.cpp,v 1.1.2.11 1998/07/14 03:59:28 nryan Exp $
6baf5a
ebcbce // Copyright (C) 1998 by Network Associates, Inc.
f071ae // All rights reserved.
6daf5a
4e9e12 #include "StdAfx.h"
18af5a
cb9bcf #include "Required.h"
647414 #include "PGPdiskHighLevelUtils.h"
202229 #include "PGPdiskLowLevelUtils.h"
75993c #include "StringAssociation.h"
2caf5a
3de816 #include "CConfirmPassphraseDialog.h"
d5c411 #include "Globals.h"
364713 #include "PGPdiskHelpIds.h"
c8af5a
38af5a
0009b7 ////////////
ede738 // Constants
6809b7 ////////////
6aaf5a
1b163b // Hide typing by default?
c3a96a const PGPBoolean kDefaultConfirmPassHideTyping = TRUE;
14af5a
fcaf5a
f16cc2 /////////////////////
5d3a71 // Context help array
426cc2 /////////////////////
58af5a
d277bf static PGPUInt32 HelpIds[] =
b4bb36 {
ea85fa ¤   IDOK,¤  ¤   ¤   ¤   ¤   IDH_PGPDISKAPP_CONFIRMPASSOK,·
2de3aa ¤   IDCANCEL,¤  ¤   ¤   ¤   IDH_PGPDISKAPP_CONFIRMPASSCANCEL,·
1dbad9 ¤   IDC_HIDETYPE_CHECK,¤¤   IDH_PGPDISKAPP_CONFIRMPASSHIDECHECK,·
b3a467 ¤   IDC_PASSPHRASE_EDIT,¤   IDH_PGPDISKAPP_CONFIRMPASSEDIT1,·
40c9fc ¤   IDC_QUALITY_BAR,¤   ¤   IDH_PGPDISKAPP_CONFIRMPASSQUALITY,·
75af8b ¤   IDC_CONFIRM_EDIT,¤  ¤   IDH_PGPDISKAPP_CONFIRMPASSEDIT2,·
34e1ff ¤   IDC_RO_CHECK,¤  ¤   ¤   IDH_PGPDISKAPP_CONFIRMPASSROCHECK,·
04f09e ¤   IDC_NEWPASSMSG_TEXT,¤   ((PGPUInt32) -1),·
684434 ····0,0·
7082f7 };
88af5a
40af5a
ac83f5 ///////////////////////////
cbb249 // MFC specific definitions
3983f5 ///////////////////////////
deaf5a
069f92 BEGIN_MESSAGE_MAP(CConfirmPassphraseDialog, CDialog)
193f28 ¤   //{{AFX_MSG_MAP(CConfirmPassphraseDialog)
9b2725 ¤   ON_BN_CLICKED(IDC_HIDETYPE_CHECK, OnHideTypeCheck)
45138c ¤   ON_EN_CHANGE(IDC_PASSPHRASE_EDIT, OnChangePassphrase)
7a0b9e ¤   ON_EN_KILLFOCUS(IDC_PASSPHRASE_EDIT, OnKillFocusPassphrase)
de50f7 ¤   ON_EN_KILLFOCUS(IDC_CONFIRM_EDIT, OnKillFocusConfirmation)
98177a ¤   ON_BN_CLICKED(IDC_RO_CHECK, OnROCheck)
64db65 ¤   ON_WM_HELPINFO()
15044a ¤   //}}AFX_MSG_MAP
73af28 END_MESSAGE_MAP()
ceaf5a
dfaf5a
d5063a ////////////////////////////////////////////////////////////////////////////
06c0a1 // CConfirmPassphraseDialog public custom functions and non-default handlers
99063a ////////////////////////////////////////////////////////////////////////////
e4af5a
f609ab // The CConfirmPassphraseDialog default constructor.
fcaf5a
8b0347 CConfirmPassphraseDialog::CConfirmPassphraseDialog(
--22a2 0004248b8fe40110077 Page 2 of CConfirmPassphraseDialog.cpp
e3b5bc ¤   ConfirmPassDialogType dlgType)
39af5a
02a013 ¤   : CDialog(CConfirmPassphraseDialog::IDD, NULL)
47bb36 {
1878f1 ¤   try
0dc7a1 ¤   {
da3572 ¤   ¤   //{{AFX_DATA_INIT(CConfirmPassphraseDialog)
da94e5 ¤   ¤   mHideTypeValue = FALSE;
0906e3 ¤   ¤   mMessageValue = _T("");
df765d ¤   ¤   //}}AFX_DATA_INIT
79af5a
b941de ¤   ¤   mIHadFocus¤ ¤   ¤   ¤   = NULL;
a0db44 ¤   ¤   mConfirmPassDialogType¤ = dlgType;
0b79a9 ¤   ¤   mReadOnlyValue¤ ¤   ¤   = FALSE;
b29371 ¤   }
bf3c88 ¤   catch (CMemoryException *ex)
22c7a1 ¤   {
ba9a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
126adc ¤   ¤   ex->Delete();
de9371 ¤   }
93af5a
beb561 ¤   // Did the secure edit controls initialize properly?
789c32 ¤   if (mInitErr.IsntError())
07c7a1 ¤   {
68dc02 ¤   ¤   mInitErr = mPassphraseEdit.mInitErr;
b09371 ¤   }
23af5a
659c32 ¤   if (mInitErr.IsntError())
55c7a1 ¤   {
1e65c9 ¤   ¤   mInitErr = mConfirmationEdit.mInitErr;
2f9371 ¤   }
8eaf5a
f5c0d5 ¤   // Adjust for the correct resource template.
239c32 ¤   if (mInitErr.IsntError())
36c7a1 ¤   {
4ee164 ¤   ¤   if (mConfirmPassDialogType == kCPDT_Add)
735b34 ¤   ¤   {
57022e ¤   ¤   ¤   m_lpszTemplateName = (LPCTSTR) IDD_CONFIRMPASS1_DLG;
570fe4 ¤   ¤   }
9ce9c4 ¤   ¤   else if (mConfirmPassDialogType == kCPDT_Change)
385b34 ¤   ¤   {
16aa40 ¤   ¤   ¤   m_lpszTemplateName = (LPCTSTR) IDD_CONFIRMPASS2_DLG;
e60fe4 ¤   ¤   }
f9af5a
a9b88a ¤   ¤   // Stolen from MFC.
a68f42 ¤   ¤   if (HIWORD(m_lpszTemplateName) == 0)
985b34 ¤   ¤   {
8ecde4 ¤   ¤   ¤   m_nIDHelp = LOWORD((DWORD) m_lpszTemplateName);
5b0fe4 ¤   ¤   }
979371 ¤   }
e3efe6 }
dfaf5a
73489d // The CConfirmPassphraseDialog destructor.
0aaf5a
22ca34 CConfirmPassphraseDialog::~CConfirmPassphraseDialog()
e4bb36 {
6eefe6 }
3caf5a
08f392 // AskForPassphrase is a wrapper around DoModal. It asks for a passphrase for
16de71 // the specified PGPdisk.
86af5a
ca2292 DualErr·
b35cd8 CConfirmPassphraseDialog::AskForPassphrase(LPCSTR path)
39bb36 {
3fbe41 ¤   DualErr¤¤   derr;
49e319 ¤   PGPInt32¤   result;
8d67c5 ¤
ff639f ¤   pgpAssertStrValid(path);
ffaf5a
f678f1 ¤   try
23c7a1 ¤   {
42d5dc ¤   ¤   mPath = path;
--35a0 000dc0b4ccb40110077 Page 3 of CConfirmPassphraseDialog.cpp
a19371 ¤   }
833c88 ¤   catch (CMemoryException *ex)
2fc7a1 ¤   {
42ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
486adc ¤   ¤   ex->Delete();
b59371 ¤   }
38af5a
f72361 ¤   if (derr.IsntError())
f6c7a1 ¤   {
76aa5b ¤   ¤   derr = ValidatePGPdisk(mPath);
8e9371 ¤   }
17af5a
fc2361 ¤   if (derr.IsntError())
adc7a1 ¤   {
06fcae ¤   ¤   result = DoModal();
4baf5a
86b507 ¤   ¤   switch (result)
235b34 ¤   ¤   {
da56e8 ¤   ¤   case -1:
5f39a7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
d4cdcb ¤   ¤   ¤   break;
0aaf5a
0d71eb ¤   ¤   case IDCANCEL:
c096de ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
77cdcb ¤   ¤   ¤   break;
020fe4 ¤   ¤   }
1d9371 ¤   }
d5af5a
5c33e3 ¤   return derr;
89efe6 }
40af5a
61cad7 // DisableReadOnly can be called to disable the read-only button. This is only
2fe9d4 // useful for kSPDT_Add dialogs, because in all other types the button is
f78213 // hidden no matter what.
ceaf5a
87c823 void·
7400e3 CConfirmPassphraseDialog::DisableReadOnlyButton()
a3bb36 {
a70530 ¤   pgpAssert(mConfirmPassDialogType == kCPDT_Add);
867399 ¤   mReadOnlyButton.EnableWindow(FALSE);
07efe6 }
d4af5a
828331 // SetReadOnlyValue can be called to set the value of the read-only checkbox
353d4a // before displaying the dialog. This is only useful for kSPDT_Add dialogs.
baaf5a
dcc823 void·
a6277b CConfirmPassphraseDialog::SetReadOnlyValue(PGPBoolean readOnly)
9fbb36 {
b70530 ¤   pgpAssert(mConfirmPassDialogType == kCPDT_Add);
e2af5a
109387 ¤   mReadOnlyButton.SetCheck(readOnly ? 1 : 0);
b30506 ¤   mReadOnlyValue = (mReadOnlyButton.GetCheck() == 1 ? TRUE : FALSE);
53efe6 }
84af5a
d2819a // PreTranslateMessage sees all messages before MFC filters them. We need to
547bb9 // check for the caps lock key.
b4af5a
2c7efe BOOL·
71348a CConfirmPassphraseDialog::PreTranslateMessage(MSG* pMsg)·
6cbb36 {
8df87e ¤   switch (pMsg->message)
31c7a1 ¤   {
4f948b ¤   case WM_KEYUP:
d7e270 ¤   ¤   SetCapsLockMessageState();
3d2f68 ¤   ¤   break;
e59371 ¤   }
9faf5a
76ed5a ¤   return CDialog::PreTranslateMessage(pMsg);
84efe6 }
c9af5a
f6af5a
dc1bc3 //////////////////////////////////////////////////////////////////////////////
--bbe0 000ec8e682440110077 Page 4 of CConfirmPassphraseDialog.cpp
e0e71d // CConfirmPassphraseDialog protected custom functions and non-default handlrs
8c1bc3 //////////////////////////////////////////////////////////////////////////////
e8af5a
546e23 // SetCapsLockMessageState shows or hides the caps lock message as needed.
02af5a
01c823 void·
f0dc24 CConfirmPassphraseDialog::SetCapsLockMessageState()
4fbb36 {
54c0f1 ¤   PGPUInt16 bob = GetKeyState(VK_CAPITAL);
b8af5a
d933d5 ¤   if (GetKeyState(VK_CAPITAL) & 1)
07c7a1 ¤   {
65ac4a ¤   ¤   mCapsLockStatic.ShowWindow(SW_SHOW);
c69371 ¤   }
c20e24 ¤   else
ffc7a1 ¤   {
88d611 ¤   ¤   mCapsLockStatic.ShowWindow(SW_HIDE);
379371 ¤   }
b1efe6 }
7aaf5a
3fe230 // The CConfirmPassphraseDialog data exchange function.
0daf5a
75c823 void·
acf78e CConfirmPassphraseDialog::DoDataExchange(CDataExchange *pDX)
06bb36 {
3878f1 ¤   try
e9c7a1 ¤   {
33f4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
ebaf5a
79a3fd ¤   ¤   //{{AFX_DATA_MAP(CConfirmPassphraseDialog)
45d415 ¤   ¤   DDX_Control(pDX, IDC_NEWPASSMSG_TEXT, mMessageStatic);
39e5d1 ¤   ¤   DDX_Control(pDX, IDC_CAPSLOCK_TEXT, mCapsLockStatic);
249795 ¤   ¤   DDX_Control(pDX, IDOK, mOKButton);
70a1d5 ¤   ¤   DDX_Control(pDX, IDCANCEL, mCancelButton);
0ad337 ¤   ¤   DDX_Control(pDX, IDC_PASSPHRASE_EDIT, mPassphraseEdit);
753689 ¤   ¤   DDX_Control(pDX, IDC_CONFIRM_EDIT, mConfirmationEdit);
20f4c2 ¤   ¤   DDX_Control(pDX, IDC_QUALITY_BAR, mQualityBar);
0d6868 ¤   ¤   DDX_Check(pDX, IDC_HIDETYPE_CHECK, mHideTypeValue);
588815 ¤   ¤   DDX_Text(pDX, IDC_NEWPASSMSG_TEXT, mMessageValue);
be3376 ¤   ¤   //}}AFX_DATA_MAP
089371 ¤   }
d93c88 ¤   catch (CMemoryException *ex)
eec7a1 ¤   {
ad6adc ¤   ¤   ex->Delete();
b29371 ¤   }
aeefe6 }
19af5a
4a72c3 // OnChangePassphrase is called whenever the user types a letter into the
d21fbf // passphrase edit box. We adjust the "Password Quality" progress bar.
ebaf5a
e6c823 void·
323b7a CConfirmPassphraseDialog::OnChangePassphrase()·
06bb36 {
3d9097 ¤   PGPUInt16 quality = App->CalcPassphraseQuality(mPassphraseEdit.mContents);
19af5a
0d9c0a ¤   mQualityBar.SetPos(quality);
19efe6 }
3caf5a
6300d8 // We override OnHideTypeCheck to set the 'hide typing' behavior of the edit
c1b7e3 // boxes
a6af5a
aec823 void·
80af64 CConfirmPassphraseDialog::OnHideTypeCheck()·
7cbb36 {
10364d ¤   UpdateData(TRUE);
bbaf5a
d2da1e ¤   mPassphraseEdit.SetHideTypingPref(mHideTypeValue);
f9db3d ¤   mConfirmationEdit.SetHideTypingPref(mHideTypeValue);
87af5a
839d2e ¤   mIHadFocus->SetFocus();
edefe6 }
ecaf5a
--c958 000c5cec88a40110077 Page 5 of CConfirmPassphraseDialog.cpp
3cb27e // OnKillFocusConfirmation is called when the confirmation box is losing
486150 // focus.
0caf5a
69c823 void·
da4481 CConfirmPassphraseDialog::OnKillFocusConfirmation()·
b4bb36 {
65a27c ¤   mIHadFocus = &mConfirmationEdit;
dcefe6 }
4baf5a
75f769 // OnKillFocusPassphrase is called when the passphrase box is losing focus.
e8af5a
82c823 void·
4c68c4 CConfirmPassphraseDialog::OnKillFocusPassphrase()·
f4bb36 {
9c3f93 ¤   mIHadFocus = &mPassphraseEdit;
8befe6 }
cbaf5a
e26a61 // OnROCheck is called when the read-only check box is clicked.
07af5a
b2c823 void·
6120b8 CConfirmPassphraseDialog::OnROCheck()·
fbbb36 {
1b0506 ¤   mReadOnlyValue = (mReadOnlyButton.GetCheck() == 1 ? TRUE : FALSE);
bcefe6 }
40af5a
60af5a
8d38fb //////////////////////////////////////////////////////////////
0d79c9 // CConfirmPassphraseDialog protected default message handlers
6038fb //////////////////////////////////////////////////////////////
04af5a
0f8cca // OnHelpInfo handles context-sensitive help.
23af5a
8c7efe BOOL·
90841e CConfirmPassphraseDialog::OnHelpInfo(HELPINFO *pHelpInfo)
c6bb36 {
0729b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
2de5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
1bc7a1 ¤   {
adae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
1e6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
059371 ¤   }
1baf5a
8dc2e7 ¤   return TRUE;
82efe6 }
b8af5a
204b0d // OnInitDialog performs dialog box initialization.
94af5a
ee7efe BOOL·
2c2b48 CConfirmPassphraseDialog::OnInitDialog()·
6bcebb {¤
3178f1 ¤   try
d4c7a1 ¤   {
e31781 ¤   ¤   CString¤bareName, dialogMsg;
3daec7 ¤   ¤   DualErr¤derr;
43af5a
6b6570 ¤   ¤   pgpAssert(!mPath.IsEmpty());
5eaf5a
2d7ccf ¤   ¤   CDialog::OnInitDialog();
03af5a
662328 ¤   ¤   // Prepare the passphrase quality bar.
33e8ea ¤   ¤   mQualityBar.SetRange(0, 100);
cf7e13 ¤   ¤   mQualityBar.SetPos(0);
e2af5a
53b0b3 ¤   ¤   // Prepare the dialog message text.
02fa0d ¤   ¤   GetBareName(mPath, &bareName);
e4af5a
748e56 ¤   ¤   switch (mConfirmPassDialogType)
995b34 ¤   ¤   {
2a8842 ¤   ¤   case kCPDT_Add:
b4ce8b ¤   ¤   ¤   mReadOnlyButton.SubclassWindow(
ccf927 ¤   ¤   ¤   ¤   GetDlgItem(IDC_RO_CHECK)->GetSafeHwnd());
c50272 ¤   ¤   ¤   dialogMsg = GetCommonString(kPGPdiskCPDTAddPassMsg);
--afcd 00057a080e340110077 Page 6 of CConfirmPassphraseDialog.cpp
7ecdcb ¤   ¤   ¤   break;
f8af5a
57cdd1 ¤   ¤   case kCPDT_Change:
727304 ¤   ¤   ¤   dialogMsg = GetCommonString(kPGPdiskCPDTChangePassMsg);
fccdcb ¤   ¤   ¤   break;
5faf5a
0c9ae3 ¤   ¤   default:
e50606 ¤   ¤   ¤   pgpAssert(FALSE);
5dcdcb ¤   ¤   ¤   break;
8f0fe4 ¤   ¤   }
b787c7 ¤   ¤   ¤
3aa0e0 ¤   ¤   // Format and truncate the message if necessary.
3132a5 ¤   ¤   App->FormatFitStringToWindow(dialogMsg, bareName, &mMessageValue,·
071012 ¤   ¤   ¤   &mMessageStatic);
f2af5a
cf4b3e ¤   ¤   // Show the caps lock message if necessary.
c5e270 ¤   ¤   SetCapsLockMessageState();
4aaf5a
7423a7 ¤   ¤   // Set the hide-typing checkbox.
71190e ¤   ¤   mHideTypeValue = kDefaultConfirmPassHideTyping;
abaf5a
4396cc ¤   ¤   // Set the hide-typing pref of the edit boxes.
eadd25 ¤   ¤   mPassphraseEdit.SetHideTypingPref(mHideTypeValue);
4afd88 ¤   ¤   mConfirmationEdit.SetHideTypingPref(mHideTypeValue);
64af5a
474b82 ¤   ¤   // Set the maximum text length of the edit boxes.
536d5c ¤   ¤   mPassphraseEdit.SetMaxSizeContents(kMaxPassphraseLength);
0c23ed ¤   ¤   mConfirmationEdit.SetMaxSizeContents(kMaxPassphraseLength);
0de040 ¤   ¤   UpdateData(FALSE);
64af5a
f37d40 ¤   ¤   // Set the focus to the topmost box.
d75755 ¤   ¤   mPassphraseEdit.SetFocus();
3c7e60 ¤   ¤   mIHadFocus = &mPassphraseEdit;
c0af5a
94e139 ¤   ¤   // Center on screen.
126c17 ¤   ¤   CenterWindow(GetDesktopWindow());
1eaf5a
cc59b9 ¤   ¤   // Put us in front.
3b8d5c ¤   ¤   SetForegroundWindow();
49af5a
24df11 ¤   ¤   // Put on top if necessary.
5d06fc ¤   ¤   App->TweakOnTopAttribute(this);
c6af5a
f68a7d ¤   ¤   // Show now to thwart evil MFC auto-centering.
1cf130 ¤   ¤   ShowWindow(SW_SHOW);
799371 ¤   }
883c88 ¤   catch (CMemoryException *ex)
ecc7a1 ¤   {
e39a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
306adc ¤   ¤   ex->Delete();
5f9371 ¤   }
c4af5a
511094 ¤   return FALSE;¤  ············
e0efe6 }
59af5a
0e6279 // OnOK handles the OK button. We verify that the passphrase matches the
4dbac5 // confirmation.
f1af5a
e4c823 void·
ff7fb2 CConfirmPassphraseDialog::OnOK()·
74bb36 {
f9b895 ¤   PGPBoolean¤ failThis¤   = FALSE;
dc3b06 ¤   PGPBoolean¤ lengthBelowMin;
b1af5a
d14fd5 ¤   // Make sure the passphrase equals the confirmation.
57d202 ¤   if ((* mPassphraseEdit.mContents) != (* mConfirmationEdit.mContents))
86c7a1 ¤   {
9b894e ¤   ¤   failThis = TRUE;
621445 ¤   ¤   ReportError(kPGDMajorError_PassphraseNotConfirmed);
fb9371 ¤   }
5aaf5a
57f705 ¤   // Check if the passphrase is above the legal length.
--f835 001cfb3760840110077 Page 7 of CConfirmPassphraseDialog.cpp
053a78 ¤   if (!failThis)
86c7a1 ¤   {
c1af37 ¤   ¤   lengthBelowMin = (mPassphraseEdit.mContents->GetLength() <·
45833f ¤   ¤   ¤   kMinPassphraseLength);
95af5a
ee44da ¤   ¤   if (lengthBelowMin)¤¤   ¤   ¤   // below the minimum legal size?
535b34 ¤   ¤   {
febd13 ¤   ¤   ¤   failThis = TRUE;
877aa8 ¤   ¤   ¤   ReportError(kPGDMajorError_PassphraseTooSmall);
6c0fe4 ¤   ¤   }
7d9371 ¤   }
7eaf5a
a3af24 ¤   // Make sure the new passphrase doesn't already exist.
c33a78 ¤   if (!failThis)
2fc7a1 ¤   {
7ac2d6 ¤   ¤   CWaitCursor¤waitCursor;
3679f4 ¤   ¤   DualErr¤¤   derr;
7caf5a
280ee3 ¤   ¤   derr = VerifyNormalPassphrase(mPath, mPassphraseEdit.mContents);
66af5a
efaa35 ¤   ¤   if (derr.IsntError())
b25b34 ¤   ¤   {
98bd13 ¤   ¤   ¤   failThis = TRUE;
7f1f65 ¤   ¤   ¤   ReportError(kPGDMajorError_PassphraseAlreadyExists);
9d0fe4 ¤   ¤   }
3a9371 ¤   }
17af5a
4d90d1 ¤   if (failThis)
0dc7a1 ¤   {
10788b ¤   ¤   mPassphraseEdit.ClearEditContents();
4ac710 ¤   ¤   mConfirmationEdit.ClearEditContents();
495755 ¤   ¤   mPassphraseEdit.SetFocus();
d89371 ¤   }
3f0e24 ¤   else
f2c7a1 ¤   {
c378d4 ¤   ¤   CDialog::OnOK();
559371 ¤   }
cfefe6 }
--c78b 0003f19833740110078 Page 1 of CConfirmPassphraseDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
020c9b // CConfirmPassphraseDialog.h
23465d //
1666f7 // Declaration of class CConfirmPassphraseDialog.
cf1bc3 //////////////////////////////////////////////////////////////////////////////
c0af5a
800df4 // $Id: CConfirmPassphraseDialog.h,v 1.1.2.6 1998/07/06 08:56:43 nryan Exp $
0baf5a
44cbce // Copyright (C) 1998 by Network Associates, Inc.
5d71ae // All rights reserved.
29af5a
4aaca3 #ifndef Included_CConfirmPassphraseDialog_h¤// [
ead39a #define Included_CConfirmPassphraseDialog_h
25af5a
3a358e #include "CSecureEdit.h"
e8ab81 #include "Resource.h"
1eaf5a
50af5a
f0d557 ////////
bc02c9 // Types
0cd557 ////////
acaf5a
6161c7 // ConfirmPassDialogType specifies the type of confirmation passphrase dialog
4dae8c // being shown. This influences the wording of the dialog box message and the
b8a1a1 // presence of certain options.
f2af5a
34f63a enum ConfirmPassDialogType {kCPDT_Add, kCPDT_Change};
ffaf5a
47af5a
a819ee /////////////////////////////////
e3d360 // Class CConfirmPassphraseDialog
df19ee /////////////////////////////////
5aaf5a
a8beca class CConfirmPassphraseDialog : public CDialog
97bb36 {
7a5ed4 public:
ba6399 ¤   CButton¤¤   mReadOnlyButton;
92fe99 ¤   DualErr¤¤   mInitErr;
11dc1a ¤   PGPBoolean¤ mReadOnlyValue;
38af5a
603db5 ¤   ¤   ¤   CConfirmPassphraseDialog(ConfirmPassDialogType dlgType);
93f38a ¤   ¤   ¤   ~CConfirmPassphraseDialog();
cdaf5a
f11d2d ¤   DualErr¤AskForPassphrase(LPCSTR path);
d23c46 ¤   void¤   DisableReadOnlyButton();
e6c022 ¤   void¤   SetReadOnlyValue(PGPBoolean readOnly);
a6af5a
2ed3e1 ¤   //{{AFX_DATA(CConfirmPassphraseDialog)
1f9759 ¤   enum { IDD = IDD_CONFIRMPASS1_DLG };
77ef8a ¤   CStatic¤mMessageStatic;
1606f5 ¤   CStatic¤mCapsLockStatic;
58b204 ¤   CButton¤mOKButton;
e35b03 ¤   CButton¤mCancelButton;
769d94 ¤   CSecureEdit¤mPassphraseEdit;
7d696c ¤   CSecureEdit¤mConfirmationEdit;
cb3625 ¤   CProgressCtrl¤  mQualityBar;
fde23b ¤   BOOL¤   mHideTypeValue;
6bdc10 ¤   CString¤mMessageValue;
055139 ¤   //}}AFX_DATA
0eaf5a
5290c5 ¤   //{{AFX_VIRTUAL(CConfirmPassphraseDialog)
d667d4 ¤   public:
a0a0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
81c369 ¤   protected:
7c3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
94af53 ¤   //}}AFX_VIRTUAL
b6af5a
ada2d3 protected:
6916d2 ¤   ConfirmPassDialogType¤  mConfirmPassDialogType;¤¤   // dialog type
024594 ¤   CSecureEdit¤¤   ¤   ¤   *mIHadFocus;¤   ¤   ¤   ¤   // edit that had focus
acc2b4 ¤   CString¤¤   ¤   ¤   ¤   mPath;¤ ¤   ¤   ¤   ¤   ¤   // path of PGPdisk
3faf5a
--f2f9 001dcb5c3a740110078 Page 2 of CConfirmPassphraseDialog.h
8f219a ¤   void SetCapsLockMessageState();
dcaf5a
c84e7b ¤   //{{AFX_MSG(CConfirmPassphraseDialog)
54c354 ¤   afx_msg void OnHideTypeCheck();
04a928 ¤   afx_msg void OnChangePassphrase();
2fac7b ¤   afx_msg void OnKillFocusPassphrase();
d4e239 ¤   afx_msg void OnKillFocusConfirmation();
845762 ¤   virtual void OnOK();
62698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
216a34 ¤   afx_msg void OnROCheck();
0cf17a ¤   virtual BOOL OnInitDialog();
352e09 ¤   //}}AFX_MSG
75af5a
852409 ¤   DECLARE_MESSAGE_MAP()
1a82f7 };
11af5a
30c18c //{{AFX_INSERT_LOCATION}}
c4af5a
dcb6aa #endif /* ] Included_CConfirmPassphraseDialog_h */
--e5c8 00025a7077140110079 Page 1 of CConvertPGPdiskThread.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
d6af14 // CConvertPGPdiskThread.cpp
6b465d //
47b642 // Implementation of class CConvertPGPdiskThread.
d21bc3 //////////////////////////////////////////////////////////////////////////////
73af5a
750a66 // $Id: CConvertPGPdiskThread.cpp,v 1.1.2.3 1998/10/22 22:27:23 nryan Exp $
92af5a
58cbce // Copyright (C) 1998 by Network Associates, Inc.
2271ae // All rights reserved.
81af5a
b19e12 #include "StdAfx.h"
43af5a
8e9bcf #include "Required.h"
ddbfe9 #include "UtilityFunctions.h"
edaf5a
ea5bbb #include "CConvertPGPdiskThread.h"
dbc411 #include "Globals.h"
15af5a
bfaf5a
a709b7 ////////////
f0e738 // Constants
1f09b7 ////////////
a4af5a
ebdb2d // Custom windows messages
01af5a
b14a72 const PGPUInt16 WM_CONVERT_PGPDISK = WM_USER + 243;
3faf5a
60af5a
6b83f5 ///////////////////////////
7bb249 // MFC specific definitions
8c83f5 ///////////////////////////
b2af5a
ffe099 BEGIN_MESSAGE_MAP(CConvertPGPdiskThread, CWinThread)
afe1ee ¤   //{{AFX_MSG_MAP(CConvertPGPdiskThread)
a70e4a ¤   ON_THREAD_MESSAGE(WM_CONVERT_PGPDISK, OnConvertPGPdisk)
6e044a ¤   //}}AFX_MSG_MAP
98af28 END_MESSAGE_MAP()
a5af5a
d6af5a
2b186d /////////////////////////////////////////////////////////////////////////
10db45 // CConvertPGPdiskThread public custom functions and non-default handlers
dc186d /////////////////////////////////////////////////////////////////////////
74af5a
189b69 // The CConvertPGPdiskThread default constructor.
adaf5a
c8bb79 CConvertPGPdiskThread::CConvertPGPdiskThread()
babb36 {
0ee3e1 ¤   mIsConversionOngoing¤   = FALSE;
8726c0 ¤   mUserCancelFlag¤¤   ¤   = FALSE;
dbaf5a
320be9 ¤   // The thread will not delete itself.
b698cb ¤   m_bAutoDelete = FALSE;
29efe6 }
37af5a
0aa307 // The CConvertPGPdiskThread default destructor.
1caf5a
dc46c6 CConvertPGPdiskThread::~CConvertPGPdiskThread()
b0bb36 {
9defe6 }
06af5a
9e8ca2 // CallPGPdiskConvert sends a message to the thread asking it to convert a
b0a32f // new PGPdisk using the specified parameters. When finished, a message is
d57b3d // sent to the calling window.
dfaf5a
152292 DualErr·
e55a67 CConvertPGPdiskThread::CallPGPdiskConvert(ConvertPGPdiskInfo *pCPI)
71bb36 {
3b7d36 ¤   DualErr derr;
c4af5a
c8aee0 ¤   pgpAssert(!mIsConversionOngoing);
25af5a
--61c7 0000124d2f840110079 Page 2 of CConvertPGPdiskThread.cpp
411b5f ¤   pgpAssertAddrValid(pCPI, ConvertPGPdiskInfo);
ef20de ¤   mCPI = (* pCPI);
28af5a
013926 ¤   pgpAssertStrValid(mCPI.path);
31dca9 ¤   pgpAssertAddrValid(mCPI.passphrase, SecureString);
dd8a73 ¤   pgpAssert(IsntNull(mCPI.callerHwnd));
f9af5a
a1d81a ¤   // Create the thread
d00de2 ¤   if (!CreateThread())
73c7a1 ¤   {
9541de ¤   ¤   derr = DualErr(kPGDMinorError_ThreadCreationFailed);
f99371 ¤   }
73af5a
2343db ¤   mIsConversionOngoing = derr.IsntError();
3eaf5a
3f44ea ¤   // Send the convert command to the thread.
f62361 ¤   if (derr.IsntError())
88c7a1 ¤   {
fe47d7 ¤   ¤   if (!PostThreadMessage(WM_CONVERT_PGPDISK, kPGPdiskMessageMagic,·
f8a6a5 ¤   ¤   ¤   NULL))
b85b34 ¤   ¤   {
6a55e8 ¤   ¤   ¤   mIsConversionOngoing = FALSE;
1daad8 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PostThreadMessageFailed);
b70fe4 ¤   ¤   }
b49371 ¤   }
c5af5a
b533e3 ¤   return derr;
91efe6 }
daaf5a
aa5d7d // CancelPGPdiskConvert can be called to cancel PGPdisk conversion.
98af5a
b0c823 void·
f420fa CConvertPGPdiskThread::CancelPGPdiskConvert()
9abb36 {
8f2b93 ¤   pgpAssert(mIsConversionOngoing);
239f15 ¤   mUserCancelFlag = TRUE;
94efe6 }
74af5a
74af5a
b75d1a ////////////////////////////////////////////////////////
f15bf8 // CConvertPGPdiskThread public default message handlers
b95d1a ////////////////////////////////////////////////////////
54af5a
3e60ae IMPLEMENT_DYNCREATE(CConvertPGPdiskThread, CWinThread)
8daf5a
b68ddb // InitInstance is called to initialize the thread.
50af5a
bb7efe BOOL·
ded201 CConvertPGPdiskThread::InitInstance()
82bb36 {
19c2e7 ¤   return TRUE;
eaefe6 }
1faf5a
bfaf5a
67063a ////////////////////////////////////////////////////////////////////////////
5e96a0 // CConvertPGPdiskThread protected custom functions and non-default handlers
da063a ////////////////////////////////////////////////////////////////////////////
53af5a
2c5dbf // OnConvertPGPdisk is called when the thread recieves a WM_CONVERT_PGPDISK
0f2ba1 // message. The function converts the PGPdisk using data from the thread's
5d1b02 // initialized parameters.
77af5a
ebc823 void·
fca3f0 CConvertPGPdiskThread::OnConvertPGPdisk(WPARAM wParam, LPARAM lParam)
bcbb36 {
3b6f9f ¤   PGPdisk *pPGD = NULL;
f3af5a
0310db ¤   if (wParam != kPGPdiskMessageMagic)¤¤   // prevent collisions
0399bf ¤   ¤   return;
adaf5a
ff2b93 ¤   pgpAssert(mIsConversionOngoing);
01af5a
--3f9a 0011998df3140110079 Page 3 of CConvertPGPdiskThread.cpp
2d3926 ¤   pgpAssertStrValid(mCPI.path);
9ddca9 ¤   pgpAssertAddrValid(mCPI.passphrase, SecureString);
87af5a
71f9fa ¤   // Convert a new PGPdisk object.
9178f1 ¤   try
5ec7a1 ¤   {
e1adaa ¤   ¤   pPGD = new PGPdisk();
b29371 ¤   }
b43c88 ¤   catch (CMemoryException *ex)
c6c7a1 ¤   {
0eac92 ¤   ¤   mDerr = DualErr(kPGDMinorError_OutOfMemory);
046adc ¤   ¤   ex->Delete();
149371 ¤   }
a0af5a
140489 ¤   if (mDerr.IsntError())
b0c7a1 ¤   {
4c1e76 ¤   ¤   mDerr = pPGD->mInitErr;
8a9371 ¤   }
2baf5a
dfdbac ¤   // Set progress window information.
0a869f ¤   if (mCPI.progressHwnd)
99c7a1 ¤   {
decaa5 ¤   ¤   pPGD->SetProgressBarInfo(mCPI.progressHwnd, &mUserCancelFlag);
259371 ¤   }
e6af5a
3139c0 ¤   // Convert the PGPdisk.
210489 ¤   if (mDerr.IsntError())
09c7a1 ¤   {
acb358 ¤   ¤   mDerr = pPGD->ConvertPGPdisk(mCPI.path, mCPI.passphrase,·
bf9975 ¤   ¤   ¤   mCPI.randomPool);
1d9371 ¤   }
ddaf5a
971730 ¤   // Delete the temporary PGPdisk object.
ee65cb ¤   if (pPGD)
c1fbd3 ¤   ¤   delete pPGD;
7aaf5a
2a8675 ¤   mIsConversionOngoing = FALSE;
adaf5a
b8db61 ¤   // Notify caller window we're done.
5f301e ¤   PostMessage(mCPI.callerHwnd, WM_FINISHED_CONVERT, kPGPdiskMessageMagic,·
99dd06 ¤   ¤   (LPARAM) this);
96af5a
f2a2c9 ¤   // Quit the thread.
3d1de5 ¤   PostQuitMessage(0);
19efe6 }
--1fa3 00055bc4cd34011007a Page 1 of CConvertPGPdiskThread.h
541bc3 //////////////////////////////////////////////////////////////////////////////
7b5c89 // CConvertPGPdiskThread.h
b4465d //
4366da // Declaration of class CConvertPGPdiskThread.
2e1bc3 //////////////////////////////////////////////////////////////////////////////
1daf5a
86573a // $Id: CConvertPGPdiskThread.h,v 1.1.2.1 1998/10/21 01:35:02 nryan Exp $
54af5a
66cbce // Copyright (C) 1998 by Network Associates, Inc.
4f71ae // All rights reserved.
d9af5a
31e50f #ifndef Included_CConvertPGPdiskThread_h¤   // [
f2d9db #define Included_CConvertPGPdiskThread_h
01af5a
033a85 #include "DualErr.h"
6d68c6 #include "PGPdisk.h"
a0af5a
69af5a
1409b7 ////////////
35e738 // Constants
ca09b7 ////////////
eeaf5a
d408dc const PGPUInt16 WM_FINISHED_CONVERT = WM_USER + 243;
e2af5a
33af5a
37d557 ////////
e602c9 // Types
78d557 ////////
bcaf5a
2eedae // A ConvertPGPdiskInfo structure contains information for a PGPdisk
7aee80 // conversion.
04af5a
faeff3 typedef struct ConvertPGPdiskInfo
2bbb36 {
f0c6a9 ¤   LPCSTR¤ ¤   ¤   ¤   path;¤  ¤   ¤   // path to PGPdisk
d9ca27 ¤   PGPdiskRandomPool¤  *randomPool;¤   // pointer to random pool
5532d6 ¤   SecureString¤   ¤   *passphrase;¤   // pointer to passphrase
3f467f ¤   HWND¤   ¤   ¤   ¤   callerHwnd;¤¤   // HWND of caller window
03c965 ¤   HWND¤   ¤   ¤   ¤   progressHwnd;¤  // HWND of progress bar
9baf5a
ce09c5 } ConvertPGPdiskInfo;
d3af5a
f1af5a
b1b474 //////////////////////////////
f2ebf8 // Class CConvertPGPdiskThread
ebb474 //////////////////////////////
c9af5a
5a08cb class CConvertPGPdiskThread : public CWinThread
c0bb36 {
d9b08f ¤   DECLARE_DYNCREATE(CConvertPGPdiskThread)
c0af5a
f55ed4 public:
876afe ¤   DualErr¤mDerr;¤ ¤   ¤   ¤   // holds error
f5af5a
4dc3e9 ¤   ¤   ¤   CConvertPGPdiskThread();
b63c9d ¤   virtual¤~CConvertPGPdiskThread();
07af5a
9ad267 ¤   DualErr¤CallPGPdiskConvert(ConvertPGPdiskInfo *pCPI);·
67796f ¤   void¤   CancelPGPdiskConvert();
63af5a
fcd22b ¤   //{{AFX_VIRTUAL(CConvertPGPdiskThread)
a267d4 ¤   public:
d9019a ¤   virtual BOOL InitInstance();
0caf53 ¤   //}}AFX_VIRTUAL
30af5a
c8a2d3 protected:
6cdab4 ¤   ConvertPGPdiskInfo¤ mCPI;¤  ¤   ¤   ¤   ¤   // info for the conversion
0cca00 ¤   PGPBoolean¤ ¤   ¤   mIsConversionOngoing;¤  // conversion happening now?
0be52d ¤   PGPBoolean¤ ¤   ¤   mUserCancelFlag;¤   ¤   // TRUE to cancel
eaaf5a
666762 ¤   //{{AFX_MSG(CConvertPGPdiskThread)
550c30 ¤   afx_msg void OnConvertPGPdisk(WPARAM wParam, LPARAM lParam);
--fd2a 001db6e97144011007a Page 2 of CConvertPGPdiskThread.h
d42e09 ¤   //}}AFX_MSG
a0af5a
da2409 ¤   DECLARE_MESSAGE_MAP()
bd82f7 };
46af5a
52c18c //{{AFX_INSERT_LOCATION}}
2eaf5a
dbcf9b #endif¤ // ] Included_CConvertPGPdiskThread_h
--6f8d 0006901ed164011007b Page 1 of CConvertWizConvertPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
79bf62 // CConvertWizConvertPage.cpp
ff465d //
40550e // Implementation of the CConvertWizConvertPage class.
c01bc3 //////////////////////////////////////////////////////////////////////////////
0caf5a
cc4ef9 // $Id: CConvertWizConvertPage.cpp,v 1.1.2.4 1998/10/22 22:27:24 nryan Exp $
61af5a
48cbce // Copyright (C) 1998 by Network Associates, Inc.
3271ae // All rights reserved.
7faf5a
789e12 #include "StdAfx.h"
14af5a
899bcf #include "Required.h"
a6993c #include "StringAssociation.h"
c9af5a
fb68c5 #include "CConvertWizardSheet.h"
ec5c9b #include "CConvertWizConvertPage.h"
53c411 #include "Globals.h"
5e4713 #include "PGPdiskHelpIds.h"
bdaf5a
89af5a
226cc2 /////////////////////
d73a71 // Context help array
376cc2 /////////////////////
e1af5a
cc77bf static PGPUInt32 HelpIds[] =
0dbb36 {
987238 ¤   IDC_PROGRESS_BAR,¤  ¤   IDH_PGPDISKAPP_DISKWIZCREATIONPROGRESS,·
9e2a05 ¤   IDC_DISKNAME_TEXT,¤ ¤   ((PGPUInt32) -1),·
9de4f0 ····IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
83ce3c ¤   0,0·
e482f7 };
7faf5a
80af5a
b583f5 ///////////////////////////
2eb249 // MFC specific definitions
9483f5 ///////////////////////////
fdaf5a
d401d1 BEGIN_MESSAGE_MAP(CConvertWizConvertPage, CPropertyPage)
807721 ¤   //{{AFX_MSG_MAP(CConvertWizConvertPage)
c911c3 ¤   ON_MESSAGE(WM_FINISHED_CONVERT, OnFinishedConvert)
99db65 ¤   ON_WM_HELPINFO()
c72fa5 ¤   ON_WM_PAINT()
03044a ¤   //}}AFX_MSG_MAP
9eaf28 END_MESSAGE_MAP()
63af5a
34af5a
854a2a //////////////////////////////////////////////////////////////////////////
8441bf // CConvertWizConvertPage public custom functions and non-default handlers
244a2a //////////////////////////////////////////////////////////////////////////
e9af5a
1216ee IMPLEMENT_DYNCREATE(CConvertWizConvertPage, CPropertyPage)
cfaf5a
6f7158 // The CConvertWizConvertPage default constructor.
9faf5a
9549f0 CConvertWizConvertPage::CConvertWizConvertPage()
40e2f4 ¤   ·: CPropertyPage(CConvertWizConvertPage::IDD)
04bb36 {
7fc2b5 ¤   //{{AFX_DATA_INIT(CConvertWizConvertPage)
50d12f ¤   mProgressText = _T("");
9db1e8 ¤   //}}AFX_DATA_INIT
d0af5a
41fa69 ¤   mParentConvertWiz = NULL;
25af5a
b605d6 ¤   mIsThreadActive¤¤   = FALSE;
c8535b ¤   mSkipConfirmCancel¤ = FALSE;
f5af5a
ab218f ¤   // Exorcise the big help button.
f16a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
c2af5a
693b76 ¤   // Create the thread object we will use.
--d31a 000bbe9124f4011007b Page 2 of CConvertWizConvertPage.cpp
8a78f1 ¤   try
bbc7a1 ¤   {
dfcb9a ¤   ¤   mConversionThread = new CConvertPGPdiskThread;
f8af5a
f256b7 ¤   ¤   // Don't auto-delete.
70bade ¤   ¤   mConversionThread->m_bAutoDelete = FALSE;
ad2792 ¤   ¤   mIsCTAutoDelete = FALSE;
ed9371 ¤   }
b13c88 ¤   catch (CMemoryException *ex)
20c7a1 ¤   {
7b9a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
6f6adc ¤   ¤   ex->Delete();
599371 ¤   }
7aefe6 }
26af5a
e9af6e // The CConvertWizConvertPage destructor.
f3af5a
c83799 CConvertWizConvertPage::~CConvertWizConvertPage()
6fbb36 {
e91d21 ¤   if (!mIsCTAutoDelete)
6bc7a1 ¤   {
453ad3 ¤   ¤   delete mConversionThread;
e89371 ¤   }
f4efe6 }
fbaf5a
b1af5a
4e4d57 /////////////////////////////////////////////////////////
f27cbc // CConvertWizConvertPage public default message handlers
e24d57 /////////////////////////////////////////////////////////
4daf5a
a43692 // OnFinishedConvert is called when the thread has finished converting the
6341a0 // PGPdisk.
cbaf5a
15c823 void·
93b2b7 CConvertWizConvertPage::OnFinishedConvert(WPARAM wParam, LPARAM lParam)
30bb36 {
217d36 ¤   DualErr derr;
1baf5a
08db8b ¤   pgpAssertAddrValid(mConversionThread, CConvertPGPdiskThread);
d4af5a
d7221c ¤   mIsThreadActive = FALSE;
078fa5 ¤   derr = mConversionThread->mDerr;
80af5a
842361 ¤   if (derr.IsntError())
ddc7a1 ¤   {
86e921 ¤   ¤   // Enable the next button and disable the cancel button.
7533c8 ¤   ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_NEXT);
ee0cf2 ¤   ¤   mParentConvertWiz->GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
06af5a
229f99 ¤   ¤   // Set the progress string.
5ef77c ¤   ¤   SetProgressString(GetCommonString(kPGPdiskConversionDoneMsgString));
ad9371 ¤   }
72af5a
664bb3 ¤   if (derr.IsError())
87c7a1 ¤   {
ddc49a ¤   ¤   mParentConvertWiz->mDerr = derr;
51af5a
99bb4d ¤   ¤   mSkipConfirmCancel = TRUE;
e664df ¤   ¤   mParentConvertWiz->PressButton(PSBTN_CANCEL);¤  // NOT EndDialog
f59371 ¤   }
c9efe6 }
ffaf5a
59477b // OnQueryCancel confirms that the user really does want to cancel.
3aaf5a
ca7efe BOOL·
d2ecdf CConvertWizConvertPage::OnQueryCancel()·
43bb36 {
fc6887 ¤   // Confirm cancellation of creation.
fa7858 ¤   if (!mSkipConfirmCancel)
e2c7a1 ¤   {
e01ce2 ¤   ¤   if (DisplayMessage(kPGPdiskConfirmCancelConversion, kPMBS_YesNo,·
bb3286 ¤   ¤   ¤   kPMBF_NoButton) == kUR_No)
--2bf9 00063917dc14011007b Page 3 of CConvertWizConvertPage.cpp
e35b34 ¤   ¤   {
db5f1f ¤   ¤   ¤   return FALSE;
a80fe4 ¤   ¤   }
e49371 ¤   }
acaf5a
64158c ¤   return CPropertyPage::OnQueryCancel();
4fefe6 }
79af5a
9ec57f // OnSetActive is called when this page is made active. We make sure the
58cb18 // correct buttons are enabled/disabled, and begin PGPdisk conversion.
a0af5a
fa7efe BOOL·
bbc673 CConvertWizConvertPage::OnSetActive()·
8ebb36 {
8ef4bc ¤   pgpAssertAddrValid(mParentConvertWiz, CConvertWizardSheet);
acf2e5 ¤   mParentConvertWiz->SetWizardButtons(NULL);
4daf5a
ffeba8 ¤   // Ask a separate thread to create the PGPdisk.
f4a238 ¤   if (!mIsThreadActive)
54c7a1 ¤   {
ae277c ¤   ¤   ConvertPGPdiskInfo¤ CPI;
e54753 ¤   ¤   DualErr¤¤   ¤   ¤   derr;
a4af5a
6acea8 ¤   ¤   pgpAssertAddrValid(mConversionThread, CConvertPGPdiskThread);
a8af5a
707594 ¤   ¤   CPI.path¤   ¤   = mParentConvertWiz->mPath;
b2632b ¤   ¤   CPI.passphrase¤ = mParentConvertWiz->mPassphrase;
2eaf5a
7ba83b ¤   ¤   CPI.callerHwnd¤ ¤   = GetSafeHwnd();
2fbc91 ¤   ¤   CPI.progressHwnd¤   = mProgressBar.GetSafeHwnd();
b7af5a
c95449 ¤   ¤   if (mParentConvertWiz->mRestartingConversion)
7fa29d ¤   ¤   ¤   CPI.randomPool = NULL;
740e1d ¤   ¤   else
ec69fb ¤   ¤   ¤   CPI.randomPool¤ = &mParentConvertWiz->mRandomDataPage.mRandomPool;
8aaf5a
b35fea ¤   ¤   // Start the conversion thread.
636b7d ¤   ¤   mIsThreadActive = TRUE;
f5ec20 ¤   ¤   derr = mConversionThread->CallPGPdiskConvert(&CPI);
c8af5a
0fad1f ¤   ¤   // Set the progress message.
7caa35 ¤   ¤   if (derr.IsntError())
965b34 ¤   ¤   {
f5e9b2 ¤   ¤   ¤   SetProgressString(
31eb70 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskConversionConvertMsgString));
e8af5a
c7fc98 ¤   ¤   ¤   mParentConvertWiz->SendDlgItemMessage(IDCANCEL, WM_KILLFOCUS,·
54062d ¤   ¤   ¤   ¤   NULL, NULL);
630fe4 ¤   ¤   }
efaf5a
2dbdd6 ¤   ¤   if (derr.IsError())
115b34 ¤   ¤   {
3da422 ¤   ¤   ¤   mIsThreadActive = FALSE;
5caf5a
80c222 ¤   ¤   ¤   mParentConvertWiz->mDerr = derr;
c87977 ¤   ¤   ¤   mParentConvertWiz->EndDialog(IDCANCEL);
8b0fe4 ¤   ¤   }
7b9371 ¤   }
b4af5a
86bfaa ¤   return CPropertyPage::OnSetActive();
81efe6 }
54af5a
79af5a
936c0e /////////////////////////////////////////////////////////////////////////////
be8dc3 // CConvertWizConvertPage protected custom functions and non-default handlers
ad6c0e /////////////////////////////////////////////////////////////////////////////
76af5a
1b1d87 // SetProgressString updates the progress string with the specified message,
1cfcc1 // inserting the PGPdisk name where appropriate.
bbaf5a
0cc823 void·
63c394 CConvertWizConvertPage::SetProgressString(LPCSTR message)
--e392 00029e6d2064011007b Page 4 of CConvertWizConvertPage.cpp
2cbb36 {
73b35f ¤   CString bareName;
72af5a
19a350 ¤   pgpAssertStrValid(message);
17af5a
a938d5 ¤   // Prepare the dialog message text.
effb7c ¤   GetBareName(mParentConvertWiz->mPath, &bareName);
cbaf5a
a5cfd3 ¤   // Format and truncate the message if necessary.
c3cf2f ¤   App->FormatFitStringToWindow(message, bareName, &mProgressText,·
783aeb ¤   ¤   &mProgressStatic);
eeaf5a
9c02a1 ¤   UpdateData(FALSE);
33efe6 }
a0af5a
2ebf64 // The CConvertWizConvertPage data exchange function.
0daf5a
0ec823 void·
9b48b0 CConvertWizConvertPage::DoDataExchange(CDataExchange *pDX)
47bb36 {
b078f1 ¤   try
dbc7a1 ¤   {
f722a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
1eaf5a
df8efd ¤   ¤   //{{AFX_DATA_MAP(CConvertWizConvertPage)
886c81 ¤   ¤   DDX_Control(pDX, IDC_DISKNAME_TEXT, mProgressStatic);
dbf698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
5088f1 ¤   ¤   DDX_Control(pDX, IDC_PROGRESS_BAR, mProgressBar);
714a5a ¤   ¤   DDX_Text(pDX, IDC_DISKNAME_TEXT, mProgressText);
bb3376 ¤   ¤   //}}AFX_DATA_MAP
0d9371 ¤   }
573c88 ¤   catch (CMemoryException *ex)
3fc7a1 ¤   {
6b6adc ¤   ¤   ex->Delete();
0f9371 ¤   }
deefe6 }
1faf5a
0faf5a
b65ea1 ////////////////////////////////////////////////////////////
58ab4d // CConvertWizConvertPage protected default message handlers
7f5ea1 ////////////////////////////////////////////////////////////
93af5a
1618db // OnCancel is called when the cancel button is pressed.
afaf5a
5ac823 void·
c1f6c8 CConvertWizConvertPage::OnCancel()·
f4cebb {¤
07af53 ¤   if (mIsThreadActive)
6bc7a1 ¤   {
a2d6e7 ¤   ¤   // Tell it to delete itself since we may be gone by the time it
85dbed ¤   ¤   // finishes the cancel.
8daf5a
23cea8 ¤   ¤   pgpAssertAddrValid(mConversionThread, CConvertPGPdiskThread);
31af5a
056076 ¤   ¤   mIsCTAutoDelete = TRUE;
4aed7f ¤   ¤   mConversionThread->m_bAutoDelete = TRUE;
18af5a
b86f95 ¤   ¤   mConversionThread->CancelPGPdiskConvert();
899371 ¤   }
4caf5a
9f63f3 ¤   CPropertyPage::OnCancel();
01efe6 }
50af5a
ab8cca // OnHelpInfo handles context-sensitive help.
c8af5a
737efe BOOL·
89665a CConvertWizConvertPage::OnHelpInfo(HELPINFO *pHelpInfo)
d7bb36 {
8b29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
67e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
34c7a1 ¤   {
29ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
--698a 0018cb4cd144011007b Page 5 of CConvertWizConvertPage.cpp
0a6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
939371 ¤   }
42af5a
c2c2e7 ¤   return TRUE;
5befe6 }
c4af5a
1c9c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
fdaf5a
f7c823 void·
a7f81f CConvertWizConvertPage::OnPaint()·
f0bb36 {
050575 ¤   CDC¤¤   ¤   memDC;
6bc943 ¤   CPaintDC¤   DC(this);
e0e3a1 ¤   HBITMAP¤¤   oldBitmap;
f7b2e4 ¤   RECT¤   ¤   sidebarRect;
c1af5a
44fa18 ¤   DC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
2ecf08 ¤   DC.RealizePalette();
baaf5a
34ce55 ¤   memDC.CreateCompatibleDC(&DC);
66023b ¤   memDC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
47bb83 ¤   memDC.RealizePalette();
4baf5a
267fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
307564 ¤   ScreenToClient(&sidebarRect);
7b67c5 ¤
b10eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
fde162 ¤   // don't fool with it.
f0af5a
a8ed0e ¤   oldBitmap = (HBITMAP) SelectObject(memDC,·
1fe507 ¤   ¤   mParentConvertWiz->mSidebarBitmap);
08af5a
3896b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
0feefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
8eaf5a
9dac4f ¤   memDC.SelectObject(oldBitmap);
6c63a9 ¤   memDC.DeleteDC();
8cefe6 }
--a9e4 000f8637f984011007c Page 1 of CConvertWizConvertPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
2bc379 // CConvertWizConvertPage.h
06465d //
efc10c // Declaration of class CConvertWizConvertPage.
fd1bc3 //////////////////////////////////////////////////////////////////////////////
27af5a
4bb554 // $Id: CConvertWizConvertPage.h,v 1.1.2.1 1998/10/21 01:35:05 nryan Exp $
1caf5a
05cbce // Copyright (C) 1998 by Network Associates, Inc.
ef71ae // All rights reserved.
3faf5a
1b01f4 #ifndef Included_CConvertWizConvertPage_h¤  // [
7d2e91 #define Included_CConvertWizConvertPage_h
6eaf5a
813a85 #include "DualErr.h"
8caf5a
705bbb #include "CConvertPGPdiskThread.h"
2eab81 #include "Resource.h"
f0af5a
2faf5a
44d557 ////////
7502c9 // Types
45d557 ////////
56af5a
222cb0 class CConvertWizardSheet;
13af5a
ddaf5a
31c7c6 ///////////////////////////////
f7a964 // Class CConvertWizConvertPage
43c7c6 ///////////////////////////////
9caf5a
de08ab class CConvertWizConvertPage : public CPropertyPage
9fbb36 {
bf05ff ¤   DECLARE_DYNCREATE(CConvertWizConvertPage)
16af5a
035ed4 public:
fae78d ¤   CConvertWizardSheet¤*mParentConvertWiz;¤// pointer to parent sheet
1ffb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
d35875 ¤   PGPBoolean¤ ¤   ¤   mIsThreadActive;¤   // is the thread active?
f0af5a
4b8849 ¤   CConvertWizConvertPage();
5554dd ¤   ~CConvertWizConvertPage();
3eaf5a
e3fd0a ¤   //{{AFX_DATA(CConvertWizConvertPage)
3a0a59 ¤   enum { IDD = IDD_CVRTWIZ_CONVERT };
34345c ¤   CStatic¤mProgressStatic;
3c45be ¤   CStatic¤mSidebarGraphic;
e2027a ¤   CProgressCtrl¤  mProgressBar;
b821eb ¤   CString¤mProgressText;
755139 ¤   //}}AFX_DATA
b0af5a
c7e6b3 ¤   //{{AFX_VIRTUAL(CConvertWizConvertPage)
4467d4 ¤   public:
b96e36 ¤   virtual BOOL OnSetActive();
b2d8cf ¤   virtual void OnCancel();
086275 ¤   virtual BOOL OnQueryCancel();
41c369 ¤   protected:
013e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
e3af53 ¤   //}}AFX_VIRTUAL
f1af5a
21a2d3 protected:
4022dc ¤   CConvertPGPdiskThread¤  *mConversionThread;¤// thread to convert PGPdisk
a3504f ¤   PGPBoolean¤ ¤   ¤   ¤   mIsCTAutoDelete;¤   // will it delete itself?
10f4ec ¤   PGPBoolean¤ ¤   ¤   ¤   mSkipConfirmCancel;¤// to skip confirm cancel
d4af5a
f1974a ¤   void SetProgressString(LPCSTR message);
3eaf5a
7e39c3 ¤   //{{AFX_MSG(CConvertWizConvertPage)
281f67 ¤   afx_msg void OnFinishedConvert(WPARAM wParam, LPARAM lParam);
79698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
09c5f3 ¤   afx_msg void OnPaint();
f82e09 ¤   //}}AFX_MSG
--5af5 001c0f6eeb44011007c Page 2 of CConvertWizConvertPage.h
e0af5a
352409 ¤   DECLARE_MESSAGE_MAP()
ab82f7 };
e9af5a
0bc18c //{{AFX_INSERT_LOCATION}}
feaf5a
c06c83 #endif¤ // ] Included_CConvertWizConvertPage_h
--ceef 000c462a8d64011007d Page 1 of CConvertWizDonePage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
0feae3 // CConvertWizDonePage.cpp
52465d //
733b9f // Implementation of class CConvertWizDonePage.
7d1bc3 //////////////////////////////////////////////////////////////////////////////
b6af5a
b7fdde // $Id: CConvertWizDonePage.cpp,v 1.1.2.3 1998/10/22 22:27:24 nryan Exp $
a2af5a
f0cbce // Copyright (C) 1998 by Network Associates, Inc.
4171ae // All rights reserved.
3baf5a
ae9e12 #include "StdAfx.h"
63af5a
ea9bcf #include "Required.h"
4780b8 #include "CConvertWizDonePage.h"
da68c5 #include "CConvertWizardSheet.h"
73c411 #include "Globals.h"
094713 #include "PGPdiskHelpIds.h"
8eaf5a
4caf5a
4d6cc2 /////////////////////
5e3a71 // Context help array
f66cc2 /////////////////////
62af5a
d377bf static PGPUInt32 HelpIds[] =
90bb36 {
3ecec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
7ace3c ¤   0,0·
e582f7 };
b1af5a
27af5a
1683f5 ///////////////////////////
59b249 // MFC specific definitions
dc83f5 ///////////////////////////
e6af5a
54e682 BEGIN_MESSAGE_MAP(CConvertWizDonePage, CPropertyPage)
987b81 ¤   //{{AFX_MSG_MAP(CConvertWizDonePage)
51db65 ¤   ON_WM_HELPINFO()
9a2fa5 ¤   ON_WM_PAINT()
37044a ¤   //}}AFX_MSG_MAP
6baf28 END_MESSAGE_MAP()
dbaf5a
82af5a
7da6b9 ///////////////////////////////////////////////////////////////////////
ea7ddf // CConvertWizDonePage public custom functions and non-default handlers
c5a6b9 ///////////////////////////////////////////////////////////////////////
49af5a
c3a33e IMPLEMENT_DYNCREATE(CConvertWizDonePage, CPropertyPage)
c1af5a
88992a // The CConvertWizDonePage default constructor.
01af5a
404ea1 CConvertWizDonePage::CConvertWizDonePage()
e4ef74 ¤   ·: CPropertyPage(CConvertWizDonePage::IDD)
7abb36 {
08c87a ¤   //{{AFX_DATA_INIT(CConvertWizDonePage)
30b1e8 ¤   //}}AFX_DATA_INIT
90af5a
d2fa69 ¤   mParentConvertWiz = NULL;
f5af5a
f3218f ¤   // Exorcise the big help button.
006a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
cbefe6 }
43af5a
ea7d79 // The CConvertWizDonePage destructor.
57af5a
f5085c CConvertWizDonePage::~CConvertWizDonePage()
76bb36 {
e3efe6 }
63af5a
7caf5a
b9dd60 //////////////////////////////////////////////////////
c4b77e // CConvertWizDonePage public default message handlers
--35bf 0007be7ead24011007d Page 2 of CConvertWizDonePage.cpp
92dd60 //////////////////////////////////////////////////////
c2af5a
04c57f // OnSetActive is called when this page is made active. We make sure the
dcfdfc // correct buttons are enabled/disabled.
53af5a
157efe BOOL·
c5e280 CConvertWizDonePage::OnSetActive()·
acbb36 {
3ef4bc ¤   pgpAssertAddrValid(mParentConvertWiz, CConvertWizardSheet);
e6af5a
f2613a ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_FINISH);
be19d1 ¤   mParentConvertWiz->GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
55af5a
4fbfaa ¤   return CPropertyPage::OnSetActive();
6eefe6 }
9baf5a
efaf5a
a44a2a //////////////////////////////////////////////////////////////////////////
e2978c // CConvertWizDonePage protected custom functions and non-default handlers
404a2a //////////////////////////////////////////////////////////////////////////
0caf5a
bdad5d // The CConvertWizDonePage data exchange function.
8daf5a
24c823 void·
0881e3 CConvertWizDonePage::DoDataExchange(CDataExchange *pDX)
a7bb36 {
0e78f1 ¤   try
60c7a1 ¤   {
0222a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
21af5a
e1194d ¤   ¤   //{{AFX_DATA_MAP(CConvertWizDonePage)
99f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
db3376 ¤   ¤   //}}AFX_DATA_MAP
c89371 ¤   }
b63c88 ¤   catch (CMemoryException *ex)
f0c7a1 ¤   {
da6adc ¤   ¤   ex->Delete();
4a9371 ¤   }
73efe6 }
27af5a
4baf5a
534d57 /////////////////////////////////////////////////////////
ba3a6d // CConvertWizDonePage protected default message handlers
794d57 /////////////////////////////////////////////////////////
32af5a
f48cca // OnHelpInfo handles context-sensitive help.
72af5a
297efe BOOL·
4b4887 CConvertWizDonePage::OnHelpInfo(HELPINFO *pHelpInfo)
87bb36 {
9429b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
55e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
f4c7a1 ¤   {
77ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
9a6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
7f9371 ¤   }
c3af5a
cdc2e7 ¤   return TRUE;
3aefe6 }
cdaf5a
3e9c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
2caf5a
b7c823 void·
2e0468 CConvertWizDonePage::OnPaint()·
11bb36 {
5e0575 ¤   CDC¤¤   ¤   memDC;
e0c943 ¤   CPaintDC¤   DC(this);
60e3a1 ¤   HBITMAP¤¤   oldBitmap;
e2b2e4 ¤   RECT¤   ¤   sidebarRect;
f9af5a
fafa18 ¤   DC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
7bcf08 ¤   DC.RealizePalette();
--760f 0015d9f1a9d4011007d Page 3 of CConvertWizDonePage.cpp
e0af5a
eece55 ¤   memDC.CreateCompatibleDC(&DC);
6a023b ¤   memDC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
ecbb83 ¤   memDC.RealizePalette();
35af5a
0e7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
297564 ¤   ScreenToClient(&sidebarRect);
fc67c5 ¤
5b0eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
f8e162 ¤   // don't fool with it.
d9af5a
32ed0e ¤   oldBitmap = (HBITMAP) SelectObject(memDC,·
69e507 ¤   ¤   mParentConvertWiz->mSidebarBitmap);
c9af5a
5296b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
b9eefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
41af5a
2fac4f ¤   memDC.SelectObject(oldBitmap);
6363a9 ¤   memDC.DeleteDC();
5defe6 }
--151d 0010efa7d334011007e Page 1 of CConvertWizDonePage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
dd0f94 // CConvertWizDonePage.h
cb465d //
b1affb // Declaration of class CConvertWizDonePage.
421bc3 //////////////////////////////////////////////////////////////////////////////
26af5a
26c9c0 // $Id: CConvertWizDonePage.h,v 1.1.2.2 1998/10/22 22:27:25 nryan Exp $
21af5a
87cbce // Copyright (C) 1998 by Network Associates, Inc.
7a71ae // All rights reserved.
fcaf5a
1e227a #ifndef Included_CConvertWizDonePage_h¤ // [
59a3ce #define Included_CConvertWizDonePage_h
6eaf5a
bfab81 #include "Resource.h"
99af5a
5daf5a
08d557 ////////
6f02c9 // Types
26d557 ////////
47af5a
4f2cb0 class CConvertWizardSheet;
b1af5a
05af5a
6f5270 ////////////////////////////
43f6e9 // Class CConvertWizDonePage
355270 ////////////////////////////
f6af5a
10aa2b class CConvertWizDonePage : public CPropertyPage
3dbb36 {
51cfca ¤   DECLARE_DYNCREATE(CConvertWizDonePage)
d8af5a
cb5ed4 public:
a31fe9 ¤   CConvertWizardSheet *mParentConvertWiz;¤¤   // pointer to parent sheet
6baf5a
a9ed4c ¤   CConvertWizDonePage();
3f2c1b ¤   ~CConvertWizDonePage();
b5af5a
f01425 ¤   //{{AFX_DATA(CConvertWizDonePage)
bd376a ¤   enum { IDD = IDD_CVRTWIZ_DONE };
b845be ¤   CStatic¤mSidebarGraphic;
245139 ¤   //}}AFX_DATA
b8af5a
34cc95 ¤   //{{AFX_VIRTUAL(CConvertWizDonePage)
8167d4 ¤   public:
f06e36 ¤   virtual BOOL OnSetActive();
41c369 ¤   protected:
da3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
b2af53 ¤   //}}AFX_VIRTUAL
feaf5a
a4a2d3 protected:
9c5011 ¤   //{{AFX_MSG(CConvertWizDonePage)
bd698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
37c5f3 ¤   afx_msg void OnPaint();
0c2e09 ¤   //}}AFX_MSG
73af5a
f32409 ¤   DECLARE_MESSAGE_MAP()
5482f7 };
96af5a
81c18c //{{AFX_INSERT_LOCATION}}
09af5a
0e6a58 #endif¤ // ] Included_CConvertWizDonePage_h
--2424 0000601881a4011007f Page 1 of CConvertWizIntroPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
9f148f // CConvertWizIntroPage.cpp
55465d //
66e1ac // Implementation of class CConvertWizIntroPage.
d31bc3 //////////////////////////////////////////////////////////////////////////////
37af5a
17e08e // $Id: CConvertWizIntroPage.cpp,v 1.1.2.2 1998/10/25 23:31:23 nryan Exp $
1baf5a
98cbce // Copyright (C) 1998 by Network Associates, Inc.
0471ae // All rights reserved.
21af5a
0c9e12 #include "StdAfx.h"
70af5a
ff9bcf #include "Required.h"
fff4f6 #include "PGPdiskPublicKeyUtils.h"
7d993c #include "StringAssociation.h"
bdaf5a
fabc62 #include "CConvertWizIntroPage.h"
1068c5 #include "CConvertWizardSheet.h"
8d1998 #include "CSinglePassphraseDialog.h"
55c411 #include "Globals.h"
3a4713 #include "PGPdiskHelpIds.h"
c2af5a
1baf5a
ce6cc2 /////////////////////
4c3a71 // Context help array
816cc2 /////////////////////
c5af5a
9477bf static PGPUInt32 HelpIds[] =
7bbb36 {
bacec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
6bce3c ¤   0,0·
e582f7 };
d4af5a
e6af5a
d183f5 ///////////////////////////
01b249 // MFC specific definitions
8683f5 ///////////////////////////
c2af5a
389785 BEGIN_MESSAGE_MAP(CConvertWizIntroPage, CPropertyPage)
86d91e ¤   //{{AFX_MSG_MAP(CConvertWizIntroPage)
cbdb65 ¤   ON_WM_HELPINFO()
f62fa5 ¤   ON_WM_PAINT()
c1044a ¤   //}}AFX_MSG_MAP
19af28 END_MESSAGE_MAP()
50af5a
9caf5a
8fda3d ////////////////////////////////////////////////////////////////////////
ebd727 // CConvertWizIntroPage public custom functions and non-default handlers
d0da3d ////////////////////////////////////////////////////////////////////////
67af5a
fde827 IMPLEMENT_DYNCREATE(CConvertWizIntroPage, CPropertyPage)
90af5a
98d591 // The CConvertWizIntroPage default constructor.
f2af5a
a23d11 CConvertWizIntroPage::CConvertWizIntroPage()
cd6849 ¤   ·: CPropertyPage(CConvertWizIntroPage::IDD)
3ebb36 {
2d90f1 ¤   //{{AFX_DATA_INIT(CConvertWizIntroPage)
40b1e8 ¤   //}}AFX_DATA_INIT
40af5a
ebfa69 ¤   mParentConvertWiz = NULL;
8baf5a
72218f ¤   // Exorcise the big help button.
2e6a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
abefe6 }
54af5a
56ea75 // The CConvertWizIntroPage destructor.
18af5a
100d03 CConvertWizIntroPage::~CConvertWizIntroPage()
80bb36 {
06efe6 }
--2105 000486cd30f4011007f Page 2 of CConvertWizIntroPage.cpp
e0af5a
1aaf5a
70910a ///////////////////////////////////////////////////////
58ee38 // CConvertWizIntroPage public default message handlers
f8910a ///////////////////////////////////////////////////////
43af5a
a0c57f // OnSetActive is called when this page is made active. We make sure the
dafdfc // correct buttons are enabled/disabled.
d6af5a
de7efe BOOL·
f84038 CConvertWizIntroPage::OnSetActive()·
d7bb36 {
c1f4bc ¤   pgpAssertAddrValid(mParentConvertWiz, CConvertWizardSheet);
1a30bf ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_NEXT);
43af5a
2abfaa ¤   return CPropertyPage::OnSetActive();
a9efe6 }
5faf5a
4c4893 // OnWizardNext is called when the user clicks on the 'Next' button.
20af5a
bf0218 LRESULT·
f47955 CConvertWizIntroPage::OnWizardNext()·
a5bb36 {
6e7d36 ¤   DualErr derr;
89af5a
a452c0 ¤   if (CPropertyPage::OnWizardNext() == -1)
b8043c ¤   ¤   return -1;
89af5a
80cc5f ¤   // Ask for the passphrase for the PGPdisk.
1aa821 ¤   if (ArePGPdiskPassesWiped(mParentConvertWiz->mPath))
5bc7a1 ¤   {
b33672 ¤   ¤   DisplayMessage(kPGPdiskConversionWipedMsgString);
52666d ¤   ¤   derr = AskForPublicKeyPassphrase();
179371 ¤   }
350e24 ¤   else
7bc7a1 ¤   {
372597 ¤   ¤   derr = AskForMasterPassphrase();
629371 ¤   }
f8af5a
364bb3 ¤   if (derr.IsError())
edc7a1 ¤   {
fbc49a ¤   ¤   mParentConvertWiz->mDerr = derr;
6964df ¤   ¤   mParentConvertWiz->PressButton(PSBTN_CANCEL);¤  // NOT EndDialog
359371 ¤   }
2eaf5a
dc293b ¤   return (derr.IsntError() ? 0 : 1);
91efe6 }
91af5a
feaf5a
c47cc3 ///////////////////////////////////////////////////////////////////////////
908ff5 // CConvertWizIntroPage protected custom functions and non-default handlers
217cc3 ///////////////////////////////////////////////////////////////////////////
88af5a
70e17f // The CConvertWizIntroPage data exchange function.
16af5a
acc823 void·
a306a5 CConvertWizIntroPage::DoDataExchange(CDataExchange *pDX)
b9bb36 {
c278f1 ¤   try
65c7a1 ¤   {
7322a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
0eaf5a
55d51c ¤   ¤   //{{AFX_DATA_MAP(CConvertWizIntroPage)
82f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
b53376 ¤   ¤   //}}AFX_DATA_MAP
8c9371 ¤   }
923c88 ¤   catch (CMemoryException *ex)
77c7a1 ¤   {
2c6adc ¤   ¤   ex->Delete();
049371 ¤   }
deefe6 }
48af5a
--b7e4 00084790b694011007f Page 3 of CConvertWizIntroPage.cpp
7f391b // AskForMasterPassphrase asks the user for the master passphrase for the
7e020d // specified PGPdisk.
38af5a
be2292 DualErr·
971bba CConvertWizIntroPage::AskForMasterPassphrase()
9ebb36 {
72d513 ¤   CSinglePassphraseDialog¤masterPassDlg(kSPDT_Master);
ee9f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
5eaf5a
f088d8 ¤   // Did our dialog initialize correctly?
437beb ¤   derr = masterPassDlg.mInitErr;
43af5a
c81ec3 ¤   // Display the master passphrase dialog.
cd2361 ¤   if (derr.IsntError())
bfc7a1 ¤   {
9ad1b5 ¤   ¤   derr = masterPassDlg.AskForPassphrase(mParentConvertWiz->mPath);
a99371 ¤   }
5caf5a
89fdef ¤   // Save the passphrase
7d2361 ¤   if (derr.IsntError())
edc7a1 ¤   {
ffeb8b ¤   ¤   (* mParentConvertWiz->mPassphrase) =·
b3b0d5 ¤   ¤   ¤   (* masterPassDlg.mPassphraseEdit.mContents);
3e9371 ¤   }
dd67c5 ¤
3c33e3 ¤   return derr;
a1efe6 }
4aaf5a
f3e8ba // AskForPublicKeyPassphrase asks the user for the master passphrase for the
be020d // specified PGPdisk.
cdaf5a
5a2292 DualErr·
77eafd CConvertWizIntroPage::AskForPublicKeyPassphrase()
22bb36 {
052940 ¤   CSinglePassphraseDialog¤publicKeyPassDlg(kSPDT_PublicKey);
6d9f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
f6af5a
8888d8 ¤   // Did our dialog initialize correctly?
776edb ¤   derr = publicKeyPassDlg.mInitErr;
88af5a
0cea7b ¤   // Display the public key passphrase dialog.
6a2361 ¤   if (derr.IsntError())
3ac7a1 ¤   {
03fccf ¤   ¤   derr = publicKeyPassDlg.AskForPassphrase(mParentConvertWiz->mPath);
ea9371 ¤   }
24af5a
f2fdef ¤   // Save the passphrase
752361 ¤   if (derr.IsntError())
5fc7a1 ¤   {
c9eb8b ¤   ¤   (* mParentConvertWiz->mPassphrase) =·
a33828 ¤   ¤   ¤   (* publicKeyPassDlg.mPassphraseEdit.mContents);
ae9371 ¤   }
6d67c5 ¤
1133e3 ¤   return derr;
0fefe6 }
67af5a
9faf5a
44d4a6 //////////////////////////////////////////////////////////
07ee2d // CConvertWizIntroPage protected default message handlers
a7d4a6 //////////////////////////////////////////////////////////
a7af5a
038cca // OnHelpInfo handles context-sensitive help.
23af5a
317efe BOOL·
08edf1 CConvertWizIntroPage::OnHelpInfo(HELPINFO *pHelpInfo)
81bb36 {
2529b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
36e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
e2c7a1 ¤   {
83ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
8b6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
849371 ¤   }
--0048 0015df33a634011007f Page 4 of CConvertWizIntroPage.cpp
e0af5a
c4c2e7 ¤   return TRUE;
14efe6 }
baaf5a
8f9c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
1baf5a
05c823 void·
74a50d CConvertWizIntroPage::OnPaint()·
3dbb36 {
a60575 ¤   CDC¤¤   ¤   memDC;
f3c943 ¤   CPaintDC¤   DC(this);
3be3a1 ¤   HBITMAP¤¤   oldBitmap;
2db2e4 ¤   RECT¤   ¤   sidebarRect;
f2af5a
40fa18 ¤   DC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
04cf08 ¤   DC.RealizePalette();
acaf5a
2dce55 ¤   memDC.CreateCompatibleDC(&DC);
80023b ¤   memDC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
fcbb83 ¤   memDC.RealizePalette();
c3af5a
ed7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
d07564 ¤   ScreenToClient(&sidebarRect);
9e67c5 ¤
ce0eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
bde162 ¤   // don't fool with it.
ecaf5a
86ed0e ¤   oldBitmap = (HBITMAP) SelectObject(memDC,·
03e507 ¤   ¤   mParentConvertWiz->mSidebarBitmap);
6daf5a
cc96b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
c9eefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
4daf5a
32ac4f ¤   memDC.SelectObject(oldBitmap);
4563a9 ¤   memDC.DeleteDC();
5defe6 }
--8543 0015d7596f840110080 Page 1 of CConvertWizIntroPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d21cda // CConvertWizIntroPage.h
70465d //
47c41a // Declaration of class CConvertWizIntroPage.
6e1bc3 //////////////////////////////////////////////////////////////////////////////
37af5a
cecc6d // $Id: CConvertWizIntroPage.h,v 1.1.2.2 1998/10/25 23:31:24 nryan Exp $
dbaf5a
4fcbce // Copyright (C) 1998 by Network Associates, Inc.
2f71ae // All rights reserved.
5eaf5a
7f0d78 #ifndef Included_CConvertWizIntroPage_h¤// [
f97d53 #define Included_CConvertWizIntroPage_h
b0af5a
763a85 #include "DualErr.h"
11ab81 #include "Resource.h"
49af5a
1caf5a
57d557 ////////
cb02c9 // Types
b7d557 ////////
c8af5a
5b2cb0 class CConvertWizardSheet;
45af5a
a9af5a
3e8104 /////////////////////////////
a75f05 // Class CConvertWizIntroPage
188104 /////////////////////////////
18af5a
eec4b4 class CConvertWizIntroPage : public CPropertyPage
f2bb36 {
1e257d ¤   DECLARE_DYNCREATE(CConvertWizIntroPage)
a6af5a
285ed4 public:
bc1fe9 ¤   CConvertWizardSheet *mParentConvertWiz;¤¤   // pointer to parent sheet
32af5a
9d7002 ¤   CConvertWizIntroPage();
0756f9 ¤   ~CConvertWizIntroPage();
0caf5a
de3a5f ¤   //{{AFX_DATA(CConvertWizIntroPage)
be07a0 ¤   enum { IDD = IDD_CVRTWIZ_INTRO };
0a45be ¤   CStatic¤mSidebarGraphic;
e05139 ¤   //}}AFX_DATA
edaf5a
208f0c ¤   //{{AFX_VIRTUAL(CConvertWizIntroPage)
ec67d4 ¤   public:
1d6e36 ¤   virtual BOOL OnSetActive();
3fa2ce ¤   virtual LRESULT OnWizardNext();
92c369 ¤   protected:
7d3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
fdaf53 ¤   //}}AFX_VIRTUAL
d2af5a
03a2d3 protected:
704dbc ¤   //{{AFX_MSG(CConvertWizIntroPage)
e4698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
7fc5f3 ¤   afx_msg void OnPaint();
b92e09 ¤   //}}AFX_MSG
41af5a
a337ce ¤   DualErr AskForMasterPassphrase();
91dfb1 ¤   DualErr AskForPublicKeyPassphrase();
26af5a
932409 ¤   DECLARE_MESSAGE_MAP()
ed82f7 };
dfaf5a
b7c18c //{{AFX_INSERT_LOCATION}}
c0af5a
5d8c25 #endif¤ // ] Included_CConvertWizIntroPage_h
--2f13 000ef89c67a40110081 Page 1 of CConvertWizRandomDataPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
e6dc32 // CConvertWizRandomDataPage.cpp
e1465d //
70ef12 // Implementation of class CConvertWizRandomDataPage.
e41bc3 //////////////////////////////////////////////////////////////////////////////
93af5a
9488a7 // $Id: CConvertWizRandomDataPage.cpp,v 1.1.2.2 1998/10/21 07:12:11 nryan Exp $
f9af5a
2ecbce // Copyright (C) 1998 by Network Associates, Inc.
7071ae // All rights reserved.
e9af5a
5f9e12 #include "StdAfx.h"
58af5a
0a9bcf #include "Required.h"
b98003 #include "CConvertWizRandomDataPage.h"
3a68c5 #include "CConvertWizardSheet.h"
0cc411 #include "Globals.h"
c44713 #include "PGPdiskHelpIds.h"
16af5a
7eaf5a
d209b7 ////////////
80e738 // Constants
cc09b7 ////////////
84af5a
2e8754 const PGPUInt32 kPGPdiskRandomDataNeeded = 300;¤¤   // 300 bits
a0af5a
16af5a
766cc2 /////////////////////
263a71 // Context help array
666cc2 /////////////////////
18af5a
6777bf static PGPUInt32 HelpIds[] =
f0bb36 {
fc6cd7 ¤   IDC_RANDOM_BAR,¤¤   IDH_PGPDISKAPP_DISKWIZRANDOMBAR,·
d9d5d0 ¤   IDC_SIDEBAR,¤   ¤   ((PGPUInt32) -1),·
b5ce3c ¤   0,0·
3c82f7 };
8eaf5a
65af5a
bb83f5 ///////////////////////////
e4b249 // MFC specific definitions
1383f5 ///////////////////////////
0caf5a
b735f7 BEGIN_MESSAGE_MAP(CConvertWizRandomDataPage, CPropertyPage)
d28424 ¤   //{{AFX_MSG_MAP(CConvertWizRandomDataPage)
b3db65 ¤   ON_WM_HELPINFO()
2e5f6d ¤   ON_WM_MOUSEMOVE()
b28c56 ¤   ON_WM_LBUTTONDOWN()
212fa5 ¤   ON_WM_PAINT()
b7044a ¤   //}}AFX_MSG_MAP
a5af28 END_MESSAGE_MAP()
a1af5a
d5af5a
ed6c0e /////////////////////////////////////////////////////////////////////////////
30c6f8 // CConvertWizRandomDataPage public custom functions and non-default handlers
5e6c0e /////////////////////////////////////////////////////////////////////////////
6faf5a
de2107 IMPLEMENT_DYNCREATE(CConvertWizRandomDataPage, CPropertyPage)
d8af5a
4f57af // The CConvertWizRandomDataPage default constructor.
5baf5a
ba3c25 CConvertWizRandomDataPage::CConvertWizRandomDataPage()
e8e65a ¤   ·: CPropertyPage(CConvertWizRandomDataPage::IDD)
95bb36 {
4d2aea ¤   //{{AFX_DATA_INIT(CConvertWizRandomDataPage)
2360e1 ¤   mRandomMessage = _T("");
11b1e8 ¤   //}}AFX_DATA_INIT
22af5a
0c2fb9 ¤   mParentConvertWiz¤  = NULL;
d2a1e6 ¤   mIsDoneCollecting¤  = FALSE;
31d7bf ¤   mRequiredDataCount¤ = kPGPdiskRandomDataNeeded;
ef6b41 ¤   mProcessedDataCount¤= 0;
--f019 0002ff7e81c40110081 Page 2 of CConvertWizRandomDataPage.cpp
e0af5a
70218f ¤   // Exorcise the big help button.
546a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
d8af5a
a4ebe7 ¤   mInitErr = mRandomPool.mInitErr;
18efe6 }
ddaf5a
b3200f // The CConvertWizRandomDataPage destructor.
dcaf5a
1863b5 CConvertWizRandomDataPage::~CConvertWizRandomDataPage()
47bb36 {
8defe6 }
1caf5a
687380 // PreTranslateMessage is overridden so we can process all keystrokes as data.
15af5a
5e7efe BOOL·
63e465 CConvertWizRandomDataPage::PreTranslateMessage(MSG *pMsg)·
e3bb36 {
1a5ac8 ¤   if (pMsg->message == WM_KEYDOWN)
52c7a1 ¤   {
0d05d5 ¤   ¤   ProcessChar(MapVirtualKey(pMsg->wParam, 2));
6e836c ¤   ¤   return TRUE;
b79371 ¤   }
ebaf5a
f2f5d8 ¤   return CPropertyPage::PreTranslateMessage(pMsg);
1eefe6 }
4eaf5a
7aaf5a
135ea1 ////////////////////////////////////////////////////////////
a73524 // CConvertWizRandomDataPage public default message handlers
f85ea1 ////////////////////////////////////////////////////////////
d2af5a
1dc57f // OnSetActive is called when this page is made active. We make sure the
1dfdfc // correct buttons are enabled/disabled.
abaf5a
077efe BOOL·
791d40 CConvertWizRandomDataPage::OnSetActive()·
b7bb36 {
fb1cb4 ¤   pgpAssertAddrValid(mParentConvertWiz, CDiskWizardSheet);
3caf5a
2c371e ¤   if (mIsDoneCollecting)
91cb2e ¤   ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
cd0e24 ¤   else
fa100a ¤   ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_BACK);
0faf5a
abfa48 ¤   if (mParentConvertWiz->mRestartingConversion)
d598aa ¤   ¤   return FALSE;
130e24 ¤   else
02b912 ¤   ¤   return CPropertyPage::OnSetActive();
03efe6 }
8eaf5a
64af5a
1a3924 ////////////////////////////////////////////////////////////////////
9ee1d2 // CConvertWizRandomDataPage protected custom functions and handlers
373924 ////////////////////////////////////////////////////////////////////
4faf5a
db77a9 // ProcessChar is called when the user hits a key. We add entropy to the pool
d8b966 // if the key isn't too 'repetitive'.
07af5a
8cc823 void·
469822 CConvertWizRandomDataPage::ProcessChar(PGPUInt8 nChar)·
34bb36 {
8b65fb ¤   static PGPBoolean¤  initedHistory¤  = FALSE;
9f6e0f ¤   PGPBoolean¤ ¤   ¤   isKeyOk;
0ee0fa ¤   static PGPUInt8¤¤   hist[4];
06ae17 ¤   static PGPUInt32¤   histSize¤   ¤   = sizeof(hist);
455cd5 ¤   PGPUInt32¤  ¤   ¤   i, numTimes;
2aaf5a
e13bf6 ¤   // Clear the history array if this is the first time.
74ae9e ¤   if (!initedHistory)
adc7a1 ¤   {
2fce0b ¤   ¤   for (i=0; i < histSize; i++)
--a6ad 0001b04bda140110081 Page 3 of CConvertWizRandomDataPage.cpp
e35b34 ¤   ¤   {
7d7ba3 ¤   ¤   ¤   hist[i] = NULL;
0e0fe4 ¤   ¤   }
b6af5a
7791af ¤   ¤   initedHistory = TRUE;
8a9371 ¤   }
1caf5a
909a25 ¤   // Calculate the frequency of appearence of the current keystroke.
a9893b ¤   numTimes = 0;
2baf5a
04f363 ¤   for (i=0; i < histSize; i++)
3ac7a1 ¤   {
7b4ff8 ¤   ¤   if (hist[i] == nChar)
890bcc ¤   ¤   ¤   numTimes++;
319371 ¤   }
0eaf5a
9152dc ¤   // Has it appeared in more than 1/4 of last 'histSize' keystrokes?
4ab396 ¤   isKeyOk = (numTimes <= histSize/4);
12af5a
a3dd27 ¤   // Update the history.
268f7e ¤   for (i=0; i < histSize-1; i++)
e9c7a1 ¤   {
45e1a1 ¤   ¤   hist[i] = hist[i+1];
fc9371 ¤   }
4baf5a
3bb463 ¤   hist[histSize-1] = i;
2daf5a
6ff794 ¤   // If it hasn't appeared too often, add the keystroke to the pool.
bf839b ¤   if (isKeyOk)
dec7a1 ¤   {
f1c389 ¤   ¤   mRandomPool.AddByte(nChar);
9aaf5a
3fae1f ¤   ¤   if (++mProcessedDataCount >= mRequiredDataCount)
4e5b34 ¤   ¤   {
d27652 ¤   ¤   ¤   mIsDoneCollecting = TRUE;
79d027 ¤   ¤   ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
370fe4 ¤   ¤   }
591b52 ¤   ¤
b02355 ¤   ¤   mRandomDataBar.SetPos(mProcessedDataCount*100 / mRequiredDataCount);
8b9371 ¤   }
e1efe6 }
b4af5a
7bc8b6 // The CConvertWizRandomDataPage data exchange function.
baaf5a
e2c823 void·
96f40c CConvertWizRandomDataPage::DoDataExchange(CDataExchange *pDX)
3dbb36 {
2278f1 ¤   try
78c7a1 ¤   {
b322a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
48af5a
bb0598 ¤   ¤   //{{AFX_DATA_MAP(CConvertWizRandomDataPage)
4df698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
94d201 ¤   ¤   DDX_Control(pDX, IDC_RANDOM_BAR, mRandomDataBar);
7c3376 ¤   ¤   //}}AFX_DATA_MAP
4e9371 ¤   }
c23c88 ¤   catch (CMemoryException *ex)
67c7a1 ¤   {
716adc ¤   ¤   ex->Delete();
269371 ¤   }
6aefe6 }
30af5a
56af5a
39bbb5 ///////////////////////////////////////////////////////////////
237588 // CConvertWizRandomDataPage protected default message handlers
74bbb5 ///////////////////////////////////////////////////////////////
14af5a
628cca // OnHelpInfo handles context-sensitive help.
83af5a
9d7efe BOOL·
189612 CConvertWizRandomDataPage::OnHelpInfo(HELPINFO *pHelpInfo)
1bbb36 {
--2ffb 000cd0bf08e40110081 Page 4 of CConvertWizRandomDataPage.cpp
2029b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
50e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
08c7a1 ¤   {
b3ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
be6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
9a9371 ¤   }
51af5a
59c2e7 ¤   return TRUE;
3cefe6 }
14af5a
ea360f // OnInitDialog is overwritten to perform property page initialization.
74af5a
d17efe BOOL·
a56b9b CConvertWizRandomDataPage::OnInitDialog()·
21bb36 {
494541 ¤   CPropertyPage::OnInitDialog();
ccaf5a
c42b52 ¤   // This must be called first to make MFC happy.
8a02a1 ¤   UpdateData(FALSE);
9baf5a
7e574c ¤   // Initialize the entropy bar range and position.
4e1153 ¤   mRandomDataBar.SetRange(0, 100);
f5d46a ¤   mRandomDataBar.SetPos(0);
dfaf5a
6702a1 ¤   UpdateData(FALSE);
aaaf5a
6fc2e7 ¤   return TRUE;
1defe6 }
e8af5a
2be2f1 // OnLButtonDown is overridden to provide a quick exit in debug mode.
f7af5a
a4c823 void·
5ff0ef CConvertWizRandomDataPage::OnLButtonDown(UINT nFlags, CPoint point)·
f9bb36 {
5f5c98 #if PGP_DEBUG
79ae29 ¤   mIsDoneCollecting = TRUE;
513899 ¤   mRandomDataBar.SetPos(100);
e68559 ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
bf1e67 #endif¤ // PGP_DEBUG
3aaf5a
4a46a2 ¤   CPropertyPage::OnLButtonDown(nFlags, point);
c5efe6 }
2baf5a
763b0a // OnMouseMove is called whenever the mouse moves within our window. We add
285a64 // another entry to the random pool.
c2af5a
62c823 void·
fe5291 CConvertWizRandomDataPage::OnMouseMove(UINT nFlags, CPoint point)·
4ebb36 {
de6d06 ¤   if (!mIsDoneCollecting)
81c7a1 ¤   {
108e2f ¤   ¤   mRandomPool.AddMouseEntropy(point.x, point.y);
8eaf5a
2eae1f ¤   ¤   if (++mProcessedDataCount >= mRequiredDataCount)
4a5b34 ¤   ¤   {
2f7652 ¤   ¤   ¤   mIsDoneCollecting = TRUE;
5ed027 ¤   ¤   ¤   mParentConvertWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
0c0fe4 ¤   ¤   }
ad1b52 ¤   ¤
092355 ¤   ¤   mRandomDataBar.SetPos(mProcessedDataCount*100 / mRequiredDataCount);
d89371 ¤   }
2caf5a
f1a844 ¤   CPropertyPage::OnMouseMove(nFlags, point);
7befe6 }
ceaf5a
b59c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
3baf5a
22c823 void·
c4cb10 CConvertWizRandomDataPage::OnPaint()·
efbb36 {
eb0575 ¤   CDC¤¤   ¤   memDC;
cdc943 ¤   CPaintDC¤   DC(this);
--6397 001d00e220840110081 Page 5 of CConvertWizRandomDataPage.cpp
e0e3a1 ¤   HBITMAP¤¤   oldBitmap;
b5b2e4 ¤   RECT¤   ¤   sidebarRect;
6caf5a
2efa18 ¤   DC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
e5cf08 ¤   DC.RealizePalette();
99af5a
cfce55 ¤   memDC.CreateCompatibleDC(&DC);
63023b ¤   memDC.SelectPalette(&mParentConvertWiz->mSidebarPalette, FALSE);
01bb83 ¤   memDC.RealizePalette();
3baf5a
a57fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
217564 ¤   ScreenToClient(&sidebarRect);
a667c5 ¤
b5d6ed ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so·
3be162 ¤   // don't fool with it.
c6af5a
96ed0e ¤   oldBitmap = (HBITMAP) SelectObject(memDC,·
53e507 ¤   ¤   mParentConvertWiz->mSidebarBitmap);
d7af5a
3e96b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
f5eefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
99af5a
48ac4f ¤   memDC.SelectObject(oldBitmap);
5f63a9 ¤   memDC.DeleteDC();
d0efe6 }
--14b0 000883817d240110082 Page 1 of CConvertWizRandomDataPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
a1066d // CConvertWizRandomDataPage.h
a0465d //
c36b0a // Declaration of class CConvertWizRandomDataPage.
461bc3 //////////////////////////////////////////////////////////////////////////////
28af5a
e470d3 // $Id: CConvertWizRandomDataPage.h,v 1.1.2.1 1998/10/21 01:35:11 nryan Exp $
15af5a
d1cbce // Copyright (C) 1998 by Network Associates, Inc.
2971ae // All rights reserved.
1daf5a
06ed2a #ifndef Included_CConvertWizRandomDataPage_h¤   // [
0a8bc1 #define Included_CConvertWizRandomDataPage_h
51af5a
8e3a85 #include "DualErr.h"
aab1e1 #include "PGPdiskRandomPool.h"
09af5a
d5ab81 #include "Resource.h"
eeaf5a
0faf5a
69d557 ////////
5802c9 // Types
f1d557 ////////
78af5a
192cb0 class CConvertWizardSheet;
3faf5a
7eaf5a
59fcb8 //////////////////////////////////
15c5ef // Class CConvertWizRandomDataPage
dafcb8 //////////////////////////////////
21af5a
87bf15 class CConvertWizRandomDataPage : public CPropertyPage
8cbb36 {
b8d844 ¤   DECLARE_DYNCREATE(CConvertWizRandomDataPage)
4eaf5a
b25ed4 public:
10e78d ¤   CConvertWizardSheet¤*mParentConvertWiz;¤// pointer to parent sheet
83fb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
293cf5 ¤   PGPBoolean¤ ¤   ¤   mIsDoneCollecting;¤ // got all we need?
71e51f ¤   PGPdiskRandomPool¤  mRandomPool;¤   ¤   // our pool for random data
ceaf5a
9b6c45 ¤   CConvertWizRandomDataPage();
ff70c6 ¤   ~CConvertWizRandomDataPage();
a6af5a
51df05 ¤   //{{AFX_DATA(CConvertWizRandomDataPage)
333f49 ¤   enum { IDD = IDD_CVRTWIZ_RANDOM };
9745be ¤   CStatic¤mSidebarGraphic;
3d9fa6 ¤   CProgressCtrl¤  mRandomDataBar;
d44af0 ¤   CString¤mRandomMessage;
365139 ¤   //}}AFX_DATA
34af5a
7fb860 ¤   //{{AFX_VIRTUAL(CConvertWizRandomDataPage)
7f67d4 ¤   public:
6a6e36 ¤   virtual BOOL OnSetActive();
17a0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
f9c369 ¤   protected:
9a3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
c5af53 ¤   //}}AFX_VIRTUAL
3daf5a
43a2d3 protected:
3e7234 ¤   PGPUInt32¤  mRequiredDataCount;¤¤   // entropy still needed
4d9274 ¤   PGPUInt32¤  mProcessedDataCount;¤   // total entropy required
0caf5a
037aae ¤   void ProcessChar(PGPUInt8 nChar);
70af5a
4fe44b ¤   //{{AFX_MSG(CConvertWizRandomDataPage)
1ef17a ¤   virtual BOOL OnInitDialog();
bd698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
760e54 ¤   afx_msg void OnMouseMove(UINT nFlags, CPoint point);
1e4322 ¤   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
58c5f3 ¤   afx_msg void OnPaint();
882e09 ¤   //}}AFX_MSG
--1b6c 001a542c68b40110082 Page 2 of CConvertWizRandomDataPage.h
e0af5a
352409 ¤   DECLARE_MESSAGE_MAP()
ab82f7 };
e9af5a
0bc18c //{{AFX_INSERT_LOCATION}}
feaf5a
a5ce3a #endif¤ // ] Included_CConvertWizRandomDataPage_h
--73b4 00010151c2140110083 Page 1 of CConvertWizardSheet.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
fa4269 // CConvertWizardSheet.cpp
ef465d //
d37c24 // Implementation of class CConvertWizardSheet.
7e1bc3 //////////////////////////////////////////////////////////////////////////////
92af5a
b82937 // $Id: CConvertWizardSheet.cpp,v 1.1.2.3 1998/10/22 22:27:26 nryan Exp $
f5af5a
63cbce // Copyright (C) 1998 by Network Associates, Inc.
9571ae // All rights reserved.
7aaf5a
179e12 #include "StdAfx.h"
afb8af #include <new.h>
44af5a
d99bcf #include "Required.h"
d8993c #include "StringAssociation.h"
86af5a
82ea4b #if PGPDISK_PUBLIC_KEY
79f4f6 #include "PGPdiskPublicKeyUtils.h"
b138e4 #endif¤ // PGPDISK_PUBLIC_KEY
2daf5a
4a68c5 #include "CConvertWizardSheet.h"
d5c411 #include "Globals.h"
054713 #include "PGPdiskHelpIds.h"
01af5a
63af5a
0a6cc2 /////////////////////
683a71 // Context help array
806cc2 /////////////////////
b8af5a
7577bf static PGPUInt32 HelpIds[] =
5cbb36 {
1e8515 ¤   IDCANCEL,¤  ¤   IDH_PGPDISKAPP_DISKWIZSHEETCANCEL,·
c56cf9 ¤   ID_WIZBACK,¤¤   IDH_PGPDISKAPP_DISKWIZSHEETBACK,·
86d0c1 ¤   ID_WIZNEXT,¤¤   IDH_PGPDISKAPP_DISKWIZSHEETNEXT,·
dd0232 ¤   ID_WIZFINISH,¤  IDH_PGPDISKAPP_DISKWIZSHEETFINISH,·
f14434 ····0,0·
9f82f7 };
60af5a
b6af5a
fa83f5 ///////////////////////////
27b249 // MFC specific definitions
2c83f5 ///////////////////////////
74af5a
0989f8 BEGIN_MESSAGE_MAP(CConvertWizardSheet, CPropertySheet)
633c3a ¤   //{{AFX_MSG_MAP(CConvertWizardSheet)
91db65 ¤   ON_WM_HELPINFO()
f79e4e ¤   ON_BN_CLICKED(IDHELP, OnHelp)
2bdfd1 ¤   ON_WM_SYSCOMMAND()
db044a ¤   //}}AFX_MSG_MAP
e0af28 END_MESSAGE_MAP()
02af5a
2caf5a
aca6b9 ///////////////////////////////////////////////////////////////////////
28f025 // CConvertWizardSheet public custom functions and non-default handlers
9da6b9 ///////////////////////////////////////////////////////////////////////
faaf5a
88072e IMPLEMENT_DYNAMIC(CConvertWizardSheet, CPropertySheet)
66af5a
a5b75e // The CConvertWizardSheet constructor adds the wizard pages we implement
214370 // to the wizard sheet.
0baf5a
2aa70d CConvertWizardSheet::CConvertWizardSheet() :
fc8468 ¤   ¤   mLockedMem(sizeof(SecureString)),·
c94cee ¤   ¤   CPropertySheet(GetCommonString(kPGPdiskConvertWizSheetTitleString),·
2960e9 ¤   ¤   ¤   NULL, 0)
adbb36 {
b178f1 ¤   try
92c7a1 ¤   {
ae8337 ¤   ¤   // Make sure our locked memory initialized correctly.
cfa484 ¤   ¤   mInitErr = mLockedMem.mInitErr;
10af5a
--6b0b 0003f610c7640110083 Page 2 of CConvertWizardSheet.cpp
792623 ¤   ¤   // Construct the secure string object.
40ab3a ¤   ¤   if (mInitErr.IsntError())
4b5b34 ¤   ¤   {
227ac8 ¤   ¤   ¤   mPassphrase = new (mLockedMem.GetPtr()) SecureString;¤  // <new.h>
5d4e94 ¤   ¤   ¤   mPassphrase->ClearString();
2c0fe4 ¤   ¤   }
fb1b52 ¤   ¤
81cbf9 ¤   ¤   // Did our pages initialize correctly?
79ab3a ¤   ¤   if (mInitErr.IsntError())
295b34 ¤   ¤   {
c8e88b ¤   ¤   ¤   mInitErr = mConvertPage.mInitErr;
c30fe4 ¤   ¤   }
07af5a
37ab3a ¤   ¤   if (mInitErr.IsntError())
155b34 ¤   ¤   {
80aa2d ¤   ¤   ¤   mInitErr = mRandomDataPage.mInitErr;
9d0fe4 ¤   ¤   }
8eaf5a
6bab3a ¤   ¤   if (mInitErr.IsntError())
db5b34 ¤   ¤   {
357669 ¤   ¤   ¤   mConvertPage.mParentConvertWiz¤ ¤   = this;
87a26b ¤   ¤   ¤   mDonePage.mParentConvertWiz¤¤   ¤   = this;
0c23a4 ¤   ¤   ¤   mIntroPage.mParentConvertWiz¤   ¤   = this;
7d248d ¤   ¤   ¤   mRandomDataPage.mParentConvertWiz¤  = this;
c3af5a
a1a0fa ¤   ¤   ¤   AddPage(&mIntroPage);
d9a361 ¤   ¤   ¤   AddPage(&mRandomDataPage);
b92a30 ¤   ¤   ¤   AddPage(&mConvertPage);
5bb431 ¤   ¤   ¤   AddPage(&mDonePage);
ccaf5a
d722da ¤   ¤   ¤   // Exorcise the big help button.
4466e8 ¤   ¤   ¤   m_psh.dwFlags &= ~PSH_HASHELP;
8d0fe4 ¤   ¤   }
879371 ¤   }
d03c88 ¤   catch (CMemoryException *ex)
fdc7a1 ¤   {
029a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
2e6adc ¤   ¤   ex->Delete();
1b9371 ¤   }
1eefe6 }
b4af5a
0bab3a // The CConvertWizardSheet destructor.
32af5a
ea08e1 CConvertWizardSheet::~CConvertWizardSheet()
b0bb36 {
053b4c ¤   if (mPassphrase)
e5e27c ¤   ¤   mPassphrase->~SecureString();¤  ¤   // we used placement new
cfefe6 }
d7af5a
53ccb2 // ExecuteWizard displays the wizard and converts the PGPdisk after asking
8d5555 // the user for input.
eaaf5a
962292 DualErr·
133dd1 CConvertWizardSheet::ExecuteWizard(
bcf2f8 ¤   LPCSTR¤ ¤   path,·
31662d ¤   PGPBoolean¤ restartingConversion)
d3bb36 {
487d36 ¤   DualErr derr;
72af5a
5f78f1 ¤   try
22c7a1 ¤   {
4f1ff9 ¤   ¤   PGPInt32 result;
bbaf5a
c7d8c9 ¤   ¤   pgpAssertStrValid(path);
a4af5a
6eea4b #if PGPDISK_PUBLIC_KEY
66af5a
1a2c4d ¤   ¤   PGPBoolean adkKeyOnKeyring;
5baf5a
c0c0fb ¤   ¤   derr = CheckIfLockedKeysOnKeyring(path, &adkKeyOnKeyring);
eeaf5a
3faa35 ¤   ¤   if (derr.IsntError())
--add4 00089d218a340110083 Page 3 of CConvertWizardSheet.cpp
e35b34 ¤   ¤   {
e12605 ¤   ¤   ¤   if (!adkKeyOnKeyring)
0af776 ¤   ¤   ¤   {
f20011 ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskConversionFailed,·
9e8a4d ¤   ¤   ¤   ¤   ¤   kPGDMinorError_NoADKWhenConverting);
e9af5a
bec38f ¤   ¤   ¤   ¤   ShowReadOnlyListOfPublicKeys(path);
2257ef ¤   ¤   ¤   ¤   derr = kPGDMinorError_FailSilently;
12a3a6 ¤   ¤   ¤   }
8aaf5a
0e0fe4 ¤   ¤   }
c9af5a
5f38e4 #endif¤ // PGPDISK_PUBLIC_KEY
84af5a
37aa35 ¤   ¤   if (derr.IsntError())
9f5b34 ¤   ¤   {
c91269 ¤   ¤   ¤   mPath = path;
f65b46 ¤   ¤   ¤   mRestartingConversion = restartingConversion;
3daf5a
0edb4a ¤   ¤   ¤   SetWizardMode();
7eaf5a
0224a1 ¤   ¤   ¤   // Invoke the wizard.
0551f0 ¤   ¤   ¤   result = DoModal();
66af5a
0e4362 ¤   ¤   ¤   switch (result)
def776 ¤   ¤   ¤   {
9e1763 ¤   ¤   ¤   case -1:
3c04c9 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
eef622 ¤   ¤   ¤   ¤   break;
cdaf5a
16930a ¤   ¤   ¤   case IDCANCEL:
b2af5a
36147d ¤   ¤   ¤   ¤   derr = mDerr;
ceaf5a
75724e ¤   ¤   ¤   ¤   if (derr.IsntError())
e177a9 ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
e5af5a
0af622 ¤   ¤   ¤   ¤   break;
82af5a
32db68 ¤   ¤   ¤   default:
d9147d ¤   ¤   ¤   ¤   derr = mDerr;
a6f622 ¤   ¤   ¤   ¤   break;
e7a3a6 ¤   ¤   ¤   }
200fe4 ¤   ¤   }
719371 ¤   }
dc3c88 ¤   catch (CMemoryException *ex)
0bc7a1 ¤   {
4f6adc ¤   ¤   ex->Delete();
80ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
9d9371 ¤   }
dbaf5a
1f33e3 ¤   return derr;
0befe6 }
04af5a
15cc90 // PreTranslateMessage gets to see all messages before MFC does. We check
82fada // for keydown messages and if the random data page is open and active, pass
2237eb // them to that page.
10af5a
da7efe BOOL·
77f76b CConvertWizardSheet::PreTranslateMessage(MSG* pMsg)·
18bb36 {
8689f2 ¤   PGPBoolean¤ weProcessed¤= FALSE;
717387 ¤   PGPUInt8¤   vCode;
4c66cb ¤   PGPUInt32¤  activeIndex, randomIndex;
1eaf5a
faf87e ¤   switch (pMsg->message)
9ec7a1 ¤   {
d7b11a ¤   case WM_KEYDOWN:
ba4eb3 ¤   ¤   vCode = pMsg->wParam & 0x7F;
43af5a
73249c ¤   ¤   activeIndex¤= GetActiveIndex();
89cda7 ¤   ¤   randomIndex¤= GetPageIndex(&mRandomDataPage);
--65da 0000663b7ea40110083 Page 4 of CConvertWizardSheet.cpp
e0af5a
b54dec ¤   ¤   if ((activeIndex == randomIndex) &&·
de8f26 ¤   ¤   ¤   !mRandomDataPage.mIsDoneCollecting)
345b34 ¤   ¤   {
731d2d ¤   ¤   ¤   // Punt key messages down for random data collection.
90bb22 ¤   ¤   ¤   mRandomDataPage.PostMessage(pMsg->message, pMsg->wParam,·
40ef27 ¤   ¤   ¤   ¤   pMsg->lParam);
72af5a
d6d337 ¤   ¤   ¤   weProcessed = TRUE;
c90fe4 ¤   ¤   }
4b2f68 ¤   ¤   break;
a09371 ¤   }
8caf5a
6dc950 ¤   return (weProcessed ? TRUE : CPropertySheet::PreTranslateMessage(pMsg));
70efe6 }
aeaf5a
00af5a
8d19ca /////////////////////////////////////////////////
9c9f2c // CConvertWizardSheet protected default handlers
9019ca /////////////////////////////////////////////////
2baf5a
ac8cca // OnHelpInfo handles context-sensitive help.
b9af5a
837efe BOOL·
4d47ff CConvertWizardSheet::OnHelpInfo(HELPINFO *pHelpInfo)
94bb36 {
3b29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
96e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
33c7a1 ¤   {
a0ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
806b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
bf9371 ¤   }
6daf5a
05c2e7 ¤   return TRUE;
c2efe6 }
50af5a
4f7e66 // OnInitDialog is called during dialog initialization. We take the
a7479b // opportunity to add a context help button to the title bar.
d9af5a
6e7efe BOOL·
59c264 CConvertWizardSheet::OnInitDialog()·
dabb36 {
c5f334 ¤   CMenu¤  ¤   *pSysMenu;
cf18a8 ¤   HDC¤¤   ¤   hDC;
5b1b02 ¤   PGPBoolean¤ loadedBitmap;
c22e01 ¤   PGPUInt32¤  numBits;
71af5a
921450 ¤   CPropertySheet::OnInitDialog();
caaf5a
619c14 ¤   // Get screen depth.
dcff18 ¤   hDC = ::GetDC(NULL);¤   ¤   // DC for desktop
983968 ¤   numBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
336ec2 ¤   ::ReleaseDC(NULL, hDC);
18af5a
46ec20 ¤   // Load the bitmap and create a palette for it.
7d4932 ¤   if (numBits <= 1)
e0c7a1 ¤   {
18c154 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR1,·
f27869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
ec9371 ¤   }
06d872 ¤   else if (numBits <= 4)
07c7a1 ¤   {
b1af03 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR4,·
a67869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
0a9371 ¤   }
2d0e24 ¤   else
54c7a1 ¤   {
4b3837 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR8,·
ed7869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
ef9371 ¤   }
2aaf5a
065720 ¤   // Need to give the dialog a close box if we want a help box as well.
--bc2b 00149ca789240110083 Page 5 of CConvertWizardSheet.cpp
59a616 ¤   ModifyStyle(NULL, WS_SYSMENU, NULL);
96af5a
a25d47 ¤   // Show the context help button.
457f87 ¤   ModifyStyleEx(NULL, WS_EX_CONTEXTHELP, NULL);
1caf5a
df0475 ¤   // Alter the system menu.
164645 ¤   pSysMenu = GetSystemMenu(FALSE);
e9e9f0 ¤   pgpAssertAddrValid(pSysMenu, CMenu);
31af5a
e752ba ¤   pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
5c6825 ¤   pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
7cd6e9 ¤   pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
39e0bf ¤   pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
e2af5a
01129c ¤   DrawMenuBar();
5faf5a
7fd564 ¤   // Center on screen.
1a50f9 ¤   CenterWindow(GetDesktopWindow());
51af5a
65afdc ¤   // Put us in front.
409974 ¤   SetForegroundWindow();
40af5a
1454ed ¤   // Put on top if necessary.
18c3a9 ¤   App->TweakOnTopAttribute(this);
67af5a
b2c2e7 ¤   return TRUE;
1eefe6 }
b7af5a
0e915f // OnSysCommand is handled to trap close requests.
b4af5a
a2c823 void·
2c5b88 CConvertWizardSheet::OnSysCommand(UINT nID, LPARAM lParam)·
7abb36 {
0d1f71 ¤   if (nID == SC_CLOSE)
0cf5fa ¤   ¤   mDerr = DualErr(kPGDMinorError_UserAbort);
7567c5 ¤
83cc0b ¤   CPropertySheet::OnSysCommand(nID, lParam);
49efe6 }
--d8e7 000efe6e6a240110084 Page 1 of CConvertWizardSheet.h
541bc3 //////////////////////////////////////////////////////////////////////////////
bc048b // CConvertWizardSheet.h
fe465d //
0ae840 // Declaration of class CConvertWizardSheet.
dc1bc3 //////////////////////////////////////////////////////////////////////////////
eaaf5a
19549f // $Id: CConvertWizardSheet.h,v 1.1.2.3 1998/10/22 22:27:26 nryan Exp $
3eaf5a
2ecbce // Copyright (C) 1998 by Network Associates, Inc.
9871ae // All rights reserved.
74af5a
b21aaf #ifndef Included_CConvertWizardSheet_h¤ // [
53a8d1 #define Included_CConvertWizardSheet_h
52af5a
b23a85 #include "DualErr.h"
6470d4 #include "SecureMemory.h"
59af5a
1b5c9b #include "CConvertWizConvertPage.h"
2580b8 #include "CConvertWizDonePage.h"
a9bc62 #include "CConvertWizIntroPage.h"
508003 #include "CConvertWizRandomDataPage.h"
d2af5a
67af5a
e05270 ////////////////////////////
8961fc // Class CConvertWizardSheet
665270 ////////////////////////////
b9af5a
713538 class CConvertWizardSheet : public CPropertySheet
2abb36 {
5932e2 ¤   DECLARE_DYNAMIC(CConvertWizardSheet)
75af5a
ddcd5f ¤   friend class CConvertWizConvertPage;
9dae5f ¤   friend class CConvertWizDonePage;
627034 ¤   friend class CConvertWizIntroPage;
3fd710 ¤   friend class CConvertWizRandomDataPage;
fdaf5a
a75ed4 public:
56da4d ¤   DualErr¤mInitErr;
f3af5a
ab9d66 ¤   ¤   ¤   CConvertWizardSheet();
dd1e38 ¤   virtual¤~CConvertWizardSheet();
74af5a
9ac071 ¤   DualErr¤ExecuteWizard(LPCSTR path, PGPBoolean restartingConversion);
ddaf5a
418b2e ¤   //{{AFX_VIRTUAL(CConvertWizardSheet)
a467d4 ¤   public:
eef17a ¤   virtual BOOL OnInitDialog();
1fa0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
36af53 ¤   //}}AFX_VIRTUAL
58af5a
41a2d3 protected:
b1ea6b ¤   CConvertWizConvertPage¤ ¤   mConvertPage;¤  ¤   // disk conversion page
0a488c ¤   CConvertWizDonePage¤¤   ¤   mDonePage;¤ ¤   ¤   // convert done page
6d5710 ¤   CConvertWizIntroPage¤   ¤   mIntroPage;¤¤   ¤   // convert intro page
104bbe ¤   CConvertWizRandomDataPage¤  mRandomDataPage;¤   // random data page
78af5a
9976cc ¤   DualErr¤¤   ¤   mDerr;¤ ¤   ¤   ¤   // pages report¤errors here
54af5a
18fe4a ¤   LPCSTR¤ ¤   ¤   mPath;
e0e9da ¤   PGPBoolean¤ ¤   mRestartingConversion;
31af5a
47d3a5 ¤   SecureMemory¤   mLockedMem;
8ef8d8 ¤   SecureString¤   *mPassphrase;
c1af5a
6230a6 ¤   CBitmap¤¤   ¤   mSidebarBitmap;¤¤   // sidebar graphic
8eab29 ¤   CPalette¤   ¤   mSidebarPalette;¤   // sidebar palette
79af5a
1117aa ¤   //{{AFX_MSG(CConvertWizardSheet)
f85d0f ¤   afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
314d01 ¤   afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
332e09 ¤   //}}AFX_MSG
efaf5a
--0993 001cd7cb9f940110084 Page 2 of CConvertWizardSheet.h
2a2409 ¤   DECLARE_MESSAGE_MAP()
eb82f7 };
83af5a
ffc18c //{{AFX_INSERT_LOCATION}}
50af5a
cd8128 #endif // ] Included_CConvertWizardSheet_h
--3bfa 000f2ec0bd440110085 Page 1 of CCreatePGPdiskThread.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
f37de0 // CCreatePGPdiskThread.cpp
18465d //
451135 // Implementation of class CCreatePGPdiskThread.
4b1bc3 //////////////////////////////////////////////////////////////////////////////
faaf5a
713ffb // $Id: CCreatePGPdiskThread.cpp,v 1.1.2.10.2.2 1998/10/22 22:27:27 nryan Exp $
e3af5a
21cbce // Copyright (C) 1998 by Network Associates, Inc.
a071ae // All rights reserved.
64af5a
899e12 #include "StdAfx.h"
71af5a
f59bcf #include "Required.h"
21bfe9 #include "UtilityFunctions.h"
3aaf5a
c785a8 #include "CCreatePGPdiskThread.h"
ecc411 #include "Globals.h"
d4af5a
f3af5a
c409b7 ////////////
bae738 // Constants
5a09b7 ////////////
6faf5a
7bdb2d // Custom windows messages
0eaf5a
4a69b2 const PGPUInt16 WM_CREATE_PGPDISK = WM_USER + 196;
7daf5a
55af5a
0983f5 ///////////////////////////
30b249 // MFC specific definitions
3d83f5 ///////////////////////////
8faf5a
6c2502 BEGIN_MESSAGE_MAP(CCreatePGPdiskThread, CWinThread)
d82987 ¤   //{{AFX_MSG_MAP(CCreatePGPdiskThread)
fab46d ¤   ON_THREAD_MESSAGE(WM_CREATE_PGPDISK, OnCreatePGPdisk)
0c044a ¤   //}}AFX_MSG_MAP
2faf28 END_MESSAGE_MAP()
16af5a
63af5a
66da3d ////////////////////////////////////////////////////////////////////////
69cd6e // CCreatePGPdiskThread public custom functions and non-default handlers
beda3d ////////////////////////////////////////////////////////////////////////
75af5a
a81455 // The CCreatePGPdiskThread default constructor.
aaaf5a
ec8e20 CCreatePGPdiskThread::CCreatePGPdiskThread()
72bb36 {
151dae ¤   mIsCreationOngoing¤ = FALSE;
00c6ea ¤   mUserCancelFlag¤¤   = FALSE;
65af5a
950be9 ¤   // The thread will not delete itself.
3898cb ¤   m_bAutoDelete = FALSE;
bdefe6 }
e5af5a
6ecf3c // The CCreatePGPdiskThread default destructor.
09af5a
111dc8 CCreatePGPdiskThread::~CCreatePGPdiskThread()
35bb36 {
0eefe6 }
a3af5a
7373ce // CallPGPdiskCreate sends a message to the thread asking it to create a new
25a931 // PGPdisk using the specified parameters. When finished, a message is
3c7b3d // sent to the calling window.
10af5a
df2292 DualErr·
0bf849 CCreatePGPdiskThread::CallPGPdiskCreate(CreatePGPdiskInfo *pCPI)
74bb36 {
4e7d36 ¤   DualErr derr;
2baf5a
8e5e73 ¤   pgpAssert(!mIsCreationOngoing);
f2af5a
--d40c 0004886562d40110085 Page 2 of CCreatePGPdiskThread.cpp
839b18 ¤   pgpAssertAddrValid(pCPI, CreatePGPdiskInfo);
4f20de ¤   mCPI = (* pCPI);
ceaf5a
1f3926 ¤   pgpAssertStrValid(mCPI.path);
a24a5e ¤   pgpAssert(mCPI.blocksDisk > 0);
4533c0 ¤   pgpAssertAddrValid(mCPI.randomPool, PGPdiskRandomPool);
55dca9 ¤   pgpAssertAddrValid(mCPI.passphrase, SecureString);
85a801 ¤   pgpAssert(IsLegalDriveNumber(mCPI.drive));
128a73 ¤   pgpAssert(IsntNull(mCPI.callerHwnd));
62af5a
47d81a ¤   // Create the thread
310de2 ¤   if (!CreateThread())
a9c7a1 ¤   {
6241de ¤   ¤   derr = DualErr(kPGDMinorError_ThreadCreationFailed);
f09371 ¤   }
34af5a
8f1e1a ¤   mIsCreationOngoing = derr.IsntError();
23af5a
d07877 ¤   // Send the create command to the thread.
882361 ¤   if (derr.IsntError())
62c7a1 ¤   {
0a02a2 ¤   ¤   if (!PostThreadMessage(WM_CREATE_PGPDISK, kPGPdiskMessageMagic,·
23a6a5 ¤   ¤   ¤   NULL))
ba5b34 ¤   ¤   {
67fcc0 ¤   ¤   ¤   mIsCreationOngoing = FALSE;
9eaad8 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PostThreadMessageFailed);
010fe4 ¤   ¤   }
ec9371 ¤   }
c2af5a
b733e3 ¤   return derr;
9defe6 }
dcaf5a
c2704c // CancelPGPdiskCreate can be called to cancel PGPdisk creation.
8baf5a
8bc823 void·
c5c8d4 CCreatePGPdiskThread::CancelPGPdiskCreate()
1bbb36 {
574803 ¤   pgpAssert(mIsCreationOngoing);
3b9f15 ¤   mUserCancelFlag = TRUE;
4befe6 }
51af5a
97af5a
9b910a ///////////////////////////////////////////////////////
7d30d9 // CCreatePGPdiskThread public default message handlers
82910a ///////////////////////////////////////////////////////
c2af5a
ec3ac6 IMPLEMENT_DYNCREATE(CCreatePGPdiskThread, CWinThread)
fbaf5a
208ddb // InitInstance is called to initialize the thread.
5eaf5a
5b7efe BOOL·
ea8b63 CCreatePGPdiskThread::InitInstance()
c8bb36 {
b7c2e7 ¤   return TRUE;
8befe6 }
34af5a
3baf5a
757cc3 ///////////////////////////////////////////////////////////////////////////
7c7d7c // CCreatePGPdiskThread protected custom functions and non-default handlers
d47cc3 ///////////////////////////////////////////////////////////////////////////
66af5a
092225 // OnCreatePGPdisk is called when the thread recieves a WM_CREATE_PGPDISK
b62b60 // message. The function creates the PGPdisk using data from the thread's
bf1b02 // initialized parameters.
32af5a
2bc823 void·
0ac3ca CCreatePGPdiskThread::OnCreatePGPdisk(WPARAM wParam, LPARAM lParam)
d0bb36 {
8a6f9f ¤   PGPdisk *pPGD = NULL;
efaf5a
0310db ¤   if (wParam != kPGPdiskMessageMagic)¤¤   // prevent collisions
4899bf ¤   ¤   return;
--a79c 001bf539cf140110085 Page 3 of CCreatePGPdiskThread.cpp
e0af5a
3e4803 ¤   pgpAssert(mIsCreationOngoing);
93af5a
553926 ¤   pgpAssertStrValid(mCPI.path);
d14a5e ¤   pgpAssert(mCPI.blocksDisk > 0);
ab33c0 ¤   pgpAssertAddrValid(mCPI.randomPool, PGPdiskRandomPool);
43dca9 ¤   pgpAssertAddrValid(mCPI.passphrase, SecureString);
6da801 ¤   pgpAssert(IsLegalDriveNumber(mCPI.drive));
418a73 ¤   pgpAssert(IsntNull(mCPI.callerHwnd));
acaf5a
ba9296 ¤   // Create a new PGPdisk object.
3478f1 ¤   try
a8c7a1 ¤   {
59adaa ¤   ¤   pPGD = new PGPdisk();
b49371 ¤   }
593c88 ¤   catch (CMemoryException *ex)
aac7a1 ¤   {
7fac92 ¤   ¤   mDerr = DualErr(kPGDMinorError_OutOfMemory);
e16adc ¤   ¤   ex->Delete();
729371 ¤   }
35af5a
a20489 ¤   if (mDerr.IsntError())
31c7a1 ¤   {
951e76 ¤   ¤   mDerr = pPGD->mInitErr;
9c9371 ¤   }
39af5a
7cdbac ¤   // Set progress window information.
f8869f ¤   if (mCPI.progressHwnd)
f6c7a1 ¤   {
08caa5 ¤   ¤   pPGD->SetProgressBarInfo(mCPI.progressHwnd, &mUserCancelFlag);
5f9371 ¤   }
e3af5a
912ae1 ¤   // Create the PGPdisk.
ab0489 ¤   if (mDerr.IsntError())
f6c7a1 ¤   {
83b6a7 ¤   ¤   mDerr = pPGD->CreatePGPdisk(mCPI.path, mCPI.blocksDisk,·
0860be ¤   ¤   ¤   kDefaultEncryptionAlgorithm, mCPI.passphrase, mCPI.randomPool,·
ee035b ¤   ¤   ¤   mCPI.drive);
ae9371 ¤   }
b0af5a
f91730 ¤   // Delete the temporary PGPdisk object.
8265cb ¤   if (pPGD)
cdfbd3 ¤   ¤   delete pPGD;
2baf5a
3bb269 ¤   mIsCreationOngoing = FALSE;
c6af5a
b5db61 ¤   // Notify caller window we're done.
94c3af ¤   PostMessage(mCPI.callerHwnd, WM_FINISHED_CREATE, kPGPdiskMessageMagic,·
4edd06 ¤   ¤   (LPARAM) this);
fcaf5a
17a2c9 ¤   // Quit the thread.
2e1de5 ¤   PostQuitMessage(0);
bfefe6 }
--32c3 00043a96c2e40110086 Page 1 of CCreatePGPdiskThread.h
541bc3 //////////////////////////////////////////////////////////////////////////////
c41562 // CCreatePGPdiskThread.h
47465d //
1f3483 // Declaration of class CCreatePGPdiskThread.
ba1bc3 //////////////////////////////////////////////////////////////////////////////
13af5a
61eeac // $Id: CCreatePGPdiskThread.h,v 1.1.2.7.2.1 1998/10/21 01:35:15 nryan Exp $
a4af5a
2ccbce // Copyright (C) 1998 by Network Associates, Inc.
9371ae // All rights reserved.
a8af5a
5df0bf #ifndef Included_CCreatePGPdiskThread_h¤// [
b974eb #define Included_CCreatePGPdiskThread_h
c6af5a
903a85 #include "DualErr.h"
b9af5a
0f68c6 #include "PGPdisk.h"
b2af5a
eaaf5a
2209b7 ////////////
71e738 // Constants
7a09b7 ////////////
36af5a
b6f605 const PGPUInt16 WM_FINISHED_CREATE = WM_USER + 197;
31af5a
94af5a
1dd557 ////////
e602c9 // Types
fad557 ////////
ffaf5a
a21eca // A CreatePGPdiskInfo structure contains information for a PGPdisk create.
a0af5a
0bc79b typedef struct CreatePGPdiskInfo
e8bb36 {
75c6a9 ¤   LPCSTR¤ ¤   ¤   ¤   path;¤  ¤   ¤   // path to PGPdisk
8c708f ¤   PGPUInt64¤  ¤   ¤   blocksDisk;¤¤   // size in blocks
abca27 ¤   PGPdiskRandomPool¤  *randomPool;¤   // pointer to random pool
fc32d6 ¤   SecureString¤   ¤   *passphrase;¤   // pointer to passphrase
5efb8d ¤   PGPUInt8¤   ¤   ¤   drive;¤ ¤   ¤   // preferred drive number
01467f ¤   HWND¤   ¤   ¤   ¤   callerHwnd;¤¤   // HWND of caller window
6dc965 ¤   HWND¤   ¤   ¤   ¤   progressHwnd;¤  // HWND of progress bar
24af5a
9768d7 } CreatePGPdiskInfo;
d3af5a
4eaf5a
f48104 /////////////////////////////
d27182 // Class CCreatePGPdiskThread
088104 /////////////////////////////
67af5a
42676c // A CCreatePGPdiskThread will simply call PGPdisk::Create in a separate
23d512 // thread context, using the specified PGPdisk object pointer and the
cfb214 // specified parameters.
72af5a
712add class CCreatePGPdiskThread : public CWinThread
84bb36 {
5bd5e4 ¤   DECLARE_DYNCREATE(CCreatePGPdiskThread)
5eaf5a
e95ed4 public:
a46afe ¤   DualErr¤mDerr;¤ ¤   ¤   ¤   // holds error
46af5a
7b6f6a ¤   ¤   ¤   CCreatePGPdiskThread();
91d412 ¤   virtual¤~CCreatePGPdiskThread();
feaf5a
a43105 ¤   DualErr¤CallPGPdiskCreate(CreatePGPdiskInfo *pCPI);·
0fc3f9 ¤   void¤   CancelPGPdiskCreate();
e0af5a
aa7f95 ¤   //{{AFX_VIRTUAL(CCreatePGPdiskThread)
0c67d4 ¤   public:
c2019a ¤   virtual BOOL InitInstance();
41af53 ¤   //}}AFX_VIRTUAL
4aaf5a
43a2d3 protected:
--5741 001a0c4995940110086 Page 2 of CCreatePGPdiskThread.h
bbbe3c ¤   CreatePGPdiskInfo¤  mCPI;¤  ¤   ¤   ¤   ¤   // info for the create
b4d68f ¤   PGPBoolean¤ ¤   ¤   mIsCreationOngoing;¤¤   // creation happening now?
1de52d ¤   PGPBoolean¤ ¤   ¤   mUserCancelFlag;¤   ¤   // TRUE to cancel
52af5a
f0bd25 ¤   //{{AFX_MSG(CCreatePGPdiskThread)
6ad8e0 ¤   afx_msg void OnCreatePGPdisk(WPARAM wParam, LPARAM lParam);
f12e09 ¤   //}}AFX_MSG
b1af5a
952409 ¤   DECLARE_MESSAGE_MAP()
8182f7 };
29af5a
12c18c //{{AFX_INSERT_LOCATION}}
0aaf5a
a0859d #endif¤ // ] Included_CCreatePGPdiskThread_h
--c784 000d6237cfb40110087 Page 1 of CDiskWizADKPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
e057a8 // CDiskWizADKPage.cpp
bc465d //
2918b6 // Implementation of class CDiskWizADKPage.
011bc3 //////////////////////////////////////////////////////////////////////////////
7baf5a
c6e59e // $Id: CDiskWizADKPage.cpp,v 1.1.2.6.2.2 1998/09/01 22:12:10 nryan Exp $
a2af5a
f2cbce // Copyright (C) 1998 by Network Associates, Inc.
2071ae // All rights reserved.
8caf5a
d19e12 #include "StdAfx.h"
3faf5a
189bcf #include "Required.h"
1eaf5a
9fea4b #if PGPDISK_PUBLIC_KEY
a1af5a
66b2b1 #include "PGPclx.h"
14e8b2 #include "pflPrefs.h"
f74720 #include "pflPrefTypes.h"
1b3991 #include "pgpAdminPrefs.h"
c02f8d #include "pgpErrors.h"
654919 #include "pgpUtilities.h"
48af5a
59f4f6 #include "PGPdiskPublicKeyUtils.h"
ddaf5a
06dafd #undef IDB_CREDITS1
c4a445 #undef IDB_CREDITS4
040de5 #undef IDB_CREDITS8
24b361 #undef IDC_CREDITS
1daf5a
7c38e4 #endif¤ // PGPDISK_PUBLIC_KEY
ddaf5a
924b7a #include "CommonStrings.h"
35af5a
d6e843 #include "CDiskWizADKPage.h"
db22eb #include "CDiskWizardSheet.h"
11c411 #include "Globals.h"
d64713 #include "PGPdiskHelpIds.h"
aaaf5a
24af5a
356cc2 /////////////////////
e43a71 // Context help array
7b6cc2 /////////////////////
faaf5a
c377bf static PGPUInt32 HelpIds[] =
63bb36 {
17cec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
b0ce3c ¤   0,0·
6482f7 };
6faf5a
29af5a
1c83f5 ///////////////////////////
a6b249 // MFC specific definitions
1883f5 ///////////////////////////
16af5a
15fadc BEGIN_MESSAGE_MAP(CDiskWizADKPage, CPropertyPage)
ffedf9 ¤   //{{AFX_MSG_MAP(CDiskWizADKPage)
10db65 ¤   ON_WM_HELPINFO()
672fa5 ¤   ON_WM_PAINT()
ae044a ¤   //}}AFX_MSG_MAP
81af28 END_MESSAGE_MAP()
0eaf5a
e5af5a
9e911d ///////////////////////////////////////////////////////////////////
2d31a9 // CDiskWizADKPage public custom functions and non-default handlers
5e911d ///////////////////////////////////////////////////////////////////
b2af5a
21f620 IMPLEMENT_DYNCREATE(CDiskWizADKPage, CPropertyPage)
26af5a
f5be85 // The CDiskWizADKPage default constructor.
d6af5a
--a02b 0002e9dd84340110087 Page 2 of CDiskWizADKPage.cpp
a89822 CDiskWizADKPage::CDiskWizADKPage()
591318 ¤   ·: CPropertyPage(CDiskWizADKPage::IDD)
a5bb36 {
df0d75 ¤   //{{AFX_DATA_INIT(CDiskWizADKPage)
d16899 ¤   mADKString = _T("");
d3b1e8 ¤   //}}AFX_DATA_INIT
0eaf5a
2a3010 ¤   mParentDiskWiz = NULL;
ba4ca3 ¤   mUseADK = FALSE;
5aaf5a
38218f ¤   // Exorcise the big help button.
c46a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
2befe6 }
cdaf5a
694900 // The CDiskWizADKPage destructor.
0baf5a
06fc0e CDiskWizADKPage::~CDiskWizADKPage()
babb36 {
d1efe6 }
29af5a
e6af5a
649b9e //////////////////////////////////////////////////
915b85 // CDiskWizADKPage public default message handlers
bb9b9e //////////////////////////////////////////////////
5faf5a
7c477b // OnQueryCancel confirms that the user really does want to cancel.
d7af5a
e47efe BOOL·
719ebc CDiskWizADKPage::OnQueryCancel()·
56bb36 {
9c6887 ¤   // Confirm cancellation of creation.
5e7858 ¤   if (!mSkipConfirmCancel)
e0c7a1 ¤   {
f837c5 ¤   ¤   if (DisplayMessage(kPGPdiskConfirmCancelCreation, kPMBS_YesNo,·
f73286 ¤   ¤   ¤   kPMBF_NoButton) == kUR_No)
915b34 ¤   ¤   {
bd5f1f ¤   ¤   ¤   return FALSE;
7e0fe4 ¤   ¤   }
f59371 ¤   }
5baf5a
26158c ¤   return CPropertyPage::OnQueryCancel();
c4efe6 }
e9af5a
b8c57f // OnSetActive is called when this page is made active. We make sure the
26fdfc // correct buttons are enabled/disabled.
99af5a
e67efe BOOL·
c5f128 CDiskWizADKPage::OnSetActive()·
8ebb36 {
e3422e ¤   PGPBoolean skipThisPage = TRUE;
c8af5a
bed3ad ¤   pgpAssertAddrValid(mParentDiskWiz, CDiskWizardSheet);
ba0c42 ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
b2af5a
01b42e #if PGPDISK_PUBLIC_KEY && PGP_BUSINESS_SECURITY
aaaf5a
eac7a1 ¤   {
23293c ¤   ¤   char¤   ¤   ¤   ¤   ¤   userID[kMaxStringSize];
9771ab ¤   ¤   DualErr¤¤   ¤   ¤   ¤   fatalDerr, notFatalDerr;
401bf5 ¤   ¤   PGPBoolean¤ ¤   ¤   ¤   gotAllKeys, gotNewContext, isThereADK;
054772 ¤   ¤   PGPContextRef¤  ¤   ¤   context;
83ab7a ¤   ¤   PGPKeySetRef¤   ¤   ¤   allKeys;
edaf5a
8582a9 ¤   ¤   gotAllKeys = gotNewContext = isThereADK = FALSE;
3daf5a
e0459d ¤   ¤   // Create new PGP context.
10461f ¤   ¤   notFatalDerr = PGPNewContext(kPGPsdkAPIVersion, &context);
231181 ¤   ¤   gotNewContext = notFatalDerr.IsntError();
92af5a
d06f26 ¤   ¤   // Is there an ADK?
b23eee ¤   ¤   if (notFatalDerr.IsntError())
2e5b34 ¤   ¤   {
--a254 0001447e5ba40110087 Page 3 of CDiskWizADKPage.cpp
3b8082 ¤   ¤   ¤   notFatalDerr = IsTherePGPdiskADK(context, &isThereADK);
0a0fe4 ¤   ¤   }
88af5a
686879 ¤   ¤   // Load default key ring if ADK.
548f4a ¤   ¤   if (notFatalDerr.IsntError() && isThereADK)
f65b34 ¤   ¤   {
72174e ¤   ¤   ¤   fatalDerr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
1d9db5 ¤   ¤   ¤   gotAllKeys = fatalDerr.IsntError();
800fe4 ¤   ¤   }
84af5a
450346 ¤   ¤   // Get ADK user ID.
729b34 ¤   ¤   if (fatalDerr.IsntError() && isThereADK)
d65b34 ¤   ¤   {
c3e877 ¤   ¤   ¤   fatalDerr = GetADKUserID(context, allKeys,userID,·
a1fbb1 ¤   ¤   ¤   ¤   kMaxStringSize);
630fe4 ¤   ¤   }
67af5a
7817a3 ¤   ¤   // Show ADK user ID.
0a9b34 ¤   ¤   if (fatalDerr.IsntError() && isThereADK)
b85b34 ¤   ¤   {
8a343f ¤   ¤   ¤   skipThisPage = FALSE;
c49b0f ¤   ¤   ¤   mUseADK = TRUE;
9aaf5a
4b3285 ¤   ¤   ¤   mADKString = userID;
6caf5a
75f468 ¤   ¤   ¤   UpdateData(FALSE);
980fe4 ¤   ¤   }
38af5a
d184bd ¤   ¤   if (fatalDerr.IsError())
a65b34 ¤   ¤   {
4308fc ¤   ¤   ¤   mParentDiskWiz->mDerr = DualErr(kPGDMinorError_CantGetADK);
36af5a
075455 ¤   ¤   ¤   skipThisPage = TRUE;
64fabe ¤   ¤   ¤   mSkipConfirmCancel = TRUE;
71af5a
8ce020 ¤   ¤   ¤   mParentDiskWiz->PostMessage(WM_CLOSE);
450fe4 ¤   ¤   }
64af5a
988630 ¤   ¤   if (gotAllKeys)
63ca6e ¤   ¤   ¤   PGPFreeKeySet(allKeys);
26af5a
22aa1f ¤   ¤   if (gotNewContext)
3003e4 ¤   ¤   ¤   PGPFreeContext(context);
679371 ¤   }
b9af5a
5ca252 #endif¤ // PGPDISK_PUBLIC_KEY && PGP_BUSINESS_SECURITY
f9af5a
2d2cdf ¤   if (skipThisPage)
5e98aa ¤   ¤   return FALSE;
a50e24 ¤   else
3fb912 ¤   ¤   return CPropertyPage::OnSetActive();
13efe6 }
a4af5a
faaf5a
3ddd36 //////////////////////////////////////////////////////////////////////
a92e4b // CDiskWizADKPage protected custom functions and non-default handlers
3edd36 //////////////////////////////////////////////////////////////////////
52af5a
8f8676 // The CDiskWizADKPage data exchange function.
e7af5a
afc823 void·
af7431 CDiskWizADKPage::DoDataExchange(CDataExchange *pDX)
03bb36 {
0178f1 ¤   try
fbc7a1 ¤   {
0422a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
c9af5a
519523 ¤   ¤   //{{AFX_DATA_MAP(CDiskWizADKPage)
6ff698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
2cd207 ¤   DDX_Text(pDX, IDC_ADK, mADKString);
3682a7 ¤   //}}AFX_DATA_MAP
149371 ¤   }
--aa34 0012f1d0a6140110087 Page 4 of CDiskWizADKPage.cpp
213c88 ¤   catch (CMemoryException *ex)
35c7a1 ¤   {
f66adc ¤   ¤   ex->Delete();
159371 ¤   }
14efe6 }
0eaf5a
05af5a
f5c3ce /////////////////////////////////////////////////////
2fdfc6 // CDiskWizADKPage protected default message handlers
82c3ce /////////////////////////////////////////////////////
d6af5a
de8cca // OnHelpInfo handles context-sensitive help.
7caf5a
597efe BOOL·
aea59c CDiskWizADKPage::OnHelpInfo(HELPINFO *pHelpInfo)
3ebb36 {
7429b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
4fe5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
0fc7a1 ¤   {
51ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
d46b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
b19371 ¤   }
2caf5a
b9c2e7 ¤   return TRUE;
4defe6 }
6aaf5a
329c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
10af5a
96c823 void·
a6605a CDiskWizADKPage::OnPaint()·
57bb36 {
d30575 ¤   CDC¤¤   ¤   memDC;
68c943 ¤   CPaintDC¤   DC(this);
bce3a1 ¤   HBITMAP¤¤   oldBitmap;
2fb2e4 ¤   RECT¤   ¤   sidebarRect;
6daf5a
abcf3b ¤   DC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
4dcf08 ¤   DC.RealizePalette();
ffaf5a
b9ce55 ¤   memDC.CreateCompatibleDC(&DC);
0d84cd ¤   memDC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
a5bb83 ¤   memDC.RealizePalette();
eeaf5a
347fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
197564 ¤   ScreenToClient(&sidebarRect);
6c67c5 ¤
130eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
89e162 ¤   // don't fool with it.
16af5a
e2366b ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mParentDiskWiz->mSidebarBitmap);
c2af5a
9d96b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
5ceefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
35af5a
07ac4f ¤   memDC.SelectObject(oldBitmap);
7163a9 ¤   memDC.DeleteDC();
2fefe6 }
--6741 0013181b8c240110088 Page 1 of CDiskWizADKPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
921f50 // CDiskWizADKPage.h
c2465d //
dc60d0 // Declaration of class CDiskWizADKPage.
8e1bc3 //////////////////////////////////////////////////////////////////////////////
27af5a
c3a87b // $Id: CDiskWizADKPage.h,v 1.1.2.2 1998/07/22 18:28:48 nryan Exp $
17af5a
38cbce // Copyright (C) 1998 by Network Associates, Inc.
ed71ae // All rights reserved.
3daf5a
b3d6b1 #ifndef Included_CDiskWizADKPage_h¤ // [
f7ddf8 #define Included_CDiskWizADKPage_h
a6af5a
af3a85 #include "DualErr.h"
c7ab81 #include "Resource.h"
06af5a
24af5a
31d557 ////////
cc02c9 // Types
e0d557 ////////
33af5a
867725 class CDiskWizardSheet;
15af5a
e6af5a
e9d48e ////////////////////////
95bc44 // Class CDiskWizADKPage
82d48e ////////////////////////
53af5a
82fe52 class CDiskWizADKPage : public CPropertyPage
75bb36 {
fa69c5 ¤   DECLARE_DYNCREATE(CDiskWizADKPage)
8baf5a
175ed4 public:
2ad540 ¤   CDiskWizardSheet¤   *mParentDiskWiz;¤   // pointer to parent sheet
faa0b1 ¤   PGPBoolean¤ ¤   ¤   mSkipConfirmCancel;¤// to skip confirm cancel
7eaf5a
d328de ¤   PGPBoolean¤ ¤   ¤   mUseADK;¤   ¤   ¤   // use ADK key?
e7af5a
bb0163 ¤   CDiskWizADKPage();
14917e ¤   ~CDiskWizADKPage();
08af5a
3f6bc0 ¤   //{{AFX_DATA(CDiskWizADKPage)
b2bae8 ¤   enum { IDD = IDD_DISKWIZ_ADK };
1345be ¤   CStatic¤mSidebarGraphic;
fac7fb ¤   CString¤mADKString;
6d5139 ¤   //}}AFX_DATA
93af5a
32d09e ¤   //{{AFX_VIRTUAL(CDiskWizADKPage)
2267d4 ¤   public:
156e36 ¤   virtual BOOL OnSetActive();
de6275 ¤   virtual BOOL OnQueryCancel();
2fc369 ¤   protected:
3f3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
b0af53 ¤   //}}AFX_VIRTUAL
51af5a
49a2d3 protected:
cbe74b ¤   //{{AFX_MSG(CDiskWizADKPage)
68698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
83c5f3 ¤   afx_msg void OnPaint();
ee2e09 ¤   //}}AFX_MSG
f5af5a
292409 ¤   DECLARE_MESSAGE_MAP()
fe82f7 };
59af5a
f5c18c //{{AFX_INSERT_LOCATION}}
ecaf5a
31ab77 #endif¤ // ] Included_CDiskWizADKPage_h
--9f2b 000bee32dda40110089 Page 1 of CDiskWizCreationPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
cbc10a // CDiskWizCreationPage.cpp
62465d //
9effdd // Implementation of class CDiskWizCreationPage.
1a1bc3 //////////////////////////////////////////////////////////////////////////////
bcaf5a
fd5571 // $Id: CDiskWizCreationPage.cpp,v 1.2.2.22.2.1 1998/10/22 22:27:28 nryan Exp $
1daf5a
31cbce // Copyright (C) 1998 by Network Associates, Inc.
0d71ae // All rights reserved.
78af5a
d79e12 #include "StdAfx.h"
1aaf5a
de9bcf #include "Required.h"
99993c #include "StringAssociation.h"
0faf5a
2eea4b #if PGPDISK_PUBLIC_KEY
48af5a
2cb2b1 #include "PGPclx.h"
54f4f6 #include "PGPdiskPublicKeyUtils.h"
92af5a
1edafd #undef IDB_CREDITS1
b8a445 #undef IDB_CREDITS4
8c0de5 #undef IDB_CREDITS8
55b361 #undef IDC_CREDITS
f8af5a
3538e4 #endif¤ // PGPDISK_PUBLIC_KEY
cfaf5a
c4ac81 #include "CDiskWizCreationPage.h"
4d22eb #include "CDiskWizardSheet.h"
4ec411 #include "Globals.h"
694713 #include "PGPdiskHelpIds.h"
67af5a
4eaf5a
676cc2 /////////////////////
003a71 // Context help array
bc6cc2 /////////////////////
5eaf5a
ce77bf static PGPUInt32 HelpIds[] =
8fbb36 {
747238 ¤   IDC_PROGRESS_BAR,¤  ¤   IDH_PGPDISKAPP_DISKWIZCREATIONPROGRESS,·
882a05 ¤   IDC_DISKNAME_TEXT,¤ ¤   ((PGPUInt32) -1),·
84e4f0 ····IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
57ce3c ¤   0,0·
6482f7 };
49af5a
edaf5a
b283f5 ///////////////////////////
6eb249 // MFC specific definitions
f083f5 ///////////////////////////
dcaf5a
2c9cf9 BEGIN_MESSAGE_MAP(CDiskWizCreationPage, CPropertyPage)
f4c76f ¤   //{{AFX_MSG_MAP(CDiskWizCreationPage)
409d0f ¤   ON_MESSAGE(WM_FINISHED_CREATE, OnFinishedCreate)
52db65 ¤   ON_WM_HELPINFO()
952fa5 ¤   ON_WM_PAINT()
f5044a ¤   //}}AFX_MSG_MAP
4daf28 END_MESSAGE_MAP()
9caf5a
52af5a
f5da3d ////////////////////////////////////////////////////////////////////////
fc0449 // CDiskWizCreationPage public custom functions and non-default handlers
48da3d ////////////////////////////////////////////////////////////////////////
c0af5a
13e35b IMPLEMENT_DYNCREATE(CDiskWizCreationPage, CPropertyPage)
7daf5a
db7747 // The CDiskWizCreationPage default constructor.
eeaf5a
af9a98 CDiskWizCreationPage::CDiskWizCreationPage()
531b1d ¤   ·: CPropertyPage(CDiskWizCreationPage::IDD)
42bb36 {
be8e80 ¤   //{{AFX_DATA_INIT(CDiskWizCreationPage)
--15fa 000608cf7a240110089 Page 2 of CDiskWizCreationPage.cpp
ddd12f ¤   mProgressText = _T("");
56b1e8 ¤   //}}AFX_DATA_INIT
9caf5a
373010 ¤   mParentDiskWiz = NULL;
d0af5a
1105d6 ¤   mIsThreadActive¤¤   = FALSE;
3e535b ¤   mSkipConfirmCancel¤ = FALSE;
bcaf5a
c8218f ¤   // Exorcise the big help button.
9e6a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
2eaf5a
3b3b76 ¤   // Create the thread object we will use.
1178f1 ¤   try
83c7a1 ¤   {
8da7c8 ¤   ¤   mCreationThread = new CCreatePGPdiskThread;
e2af5a
5656b7 ¤   ¤   // Don't auto-delete.
58b794 ¤   ¤   mCreationThread->m_bAutoDelete = FALSE;
272792 ¤   ¤   mIsCTAutoDelete = FALSE;
bb9371 ¤   }
ea3c88 ¤   catch (CMemoryException *ex)
38c7a1 ¤   {
c39a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
8a6adc ¤   ¤   ex->Delete();
c49371 ¤   }
b7efe6 }
39af5a
cab287 // The CDiskWizCreationPage destructor.
50af5a
17669e CDiskWizCreationPage::~CDiskWizCreationPage()
abbb36 {
cb1d21 ¤   if (!mIsCTAutoDelete)
68c7a1 ¤   {
7ad624 ¤   ¤   delete mCreationThread;
cc9371 ¤   }
74efe6 }
75af5a
58af5a
52910a ///////////////////////////////////////////////////////
7c6319 // CDiskWizCreationPage public default message handlers
3d910a ///////////////////////////////////////////////////////
f3af5a
67c4f0 // OnFinishedCreate is called when the thread has finished creating the
a541a0 // PGPdisk.
a4af5a
0dc823 void·
1f1a32 CDiskWizCreationPage::OnFinishedCreate(WPARAM wParam, LPARAM lParam)
88bb36 {
9a7d36 ¤   DualErr derr;
baaf5a
9b0d05 ¤   pgpAssertAddrValid(mCreationThread, CCreatePGPdiskThread);
f5af5a
ae221c ¤   mIsThreadActive = FALSE;
18b5f9 ¤   derr = mCreationThread->mDerr;
eeaf5a
0bb42e #if PGPDISK_PUBLIC_KEY && PGP_BUSINESS_SECURITY
cdaf5a
bc2361 ¤   if (derr.IsntError())
02c7a1 ¤   {
3de6a3 ¤   ¤   if (mParentDiskWiz->mADKPage.mUseADK)
ff5b34 ¤   ¤   {
4fd2e4 ¤   ¤   ¤   derr = AddADKToPGPdisk(mParentDiskWiz->mPath,·
eff379 ¤   ¤   ¤   ¤   mParentDiskWiz->mPassphrasePage.mPassphraseEdit.mContents);
560fe4 ¤   ¤   }
8b9371 ¤   }
c5af5a
fca252 #endif¤ // PGPDISK_PUBLIC_KEY && PGP_BUSINESS_SECURITY
edaf5a
e92361 ¤   if (derr.IsntError())
abc7a1 ¤   {
1ccbff ¤   ¤   // Enable the next button.
60b1fc ¤   ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_NEXT);
--5a25 000c3ba645040110089 Page 3 of CDiskWizCreationPage.cpp
e0af5a
5d9f99 ¤   ¤   // Set the progress string.
e97029 ¤   ¤   SetProgressString(GetCommonString(kPGPdiskCreationDoneMsgString));
af9371 ¤   }
d3af5a
4e4bb3 ¤   if (derr.IsError())
9cc7a1 ¤   {
64500c ¤   ¤   mParentDiskWiz->mDerr = derr;
aaaf5a
8ebb4d ¤   ¤   mSkipConfirmCancel = TRUE;
28f2b0 ¤   ¤   mParentDiskWiz->PressButton(PSBTN_CANCEL);¤ // NOT EndDialog (MFC bug)
e29371 ¤   }
01efe6 }
6eaf5a
c9477b // OnQueryCancel confirms that the user really does want to cancel.
9aaf5a
af7efe BOOL·
704898 CDiskWizCreationPage::OnQueryCancel()·
a7bb36 {
666887 ¤   // Confirm cancellation of creation.
fc7858 ¤   if (!mSkipConfirmCancel)
6ac7a1 ¤   {
a337c5 ¤   ¤   if (DisplayMessage(kPGPdiskConfirmCancelCreation, kPMBS_YesNo,·
283286 ¤   ¤   ¤   kPMBF_NoButton) == kUR_No)
cf5b34 ¤   ¤   {
695f1f ¤   ¤   ¤   return FALSE;
980fe4 ¤   ¤   }
549371 ¤   }
c0af5a
58158c ¤   return CPropertyPage::OnQueryCancel();
03efe6 }
88af5a
70c57f // OnSetActive is called when this page is made active. We make sure the
99d861 // correct buttons are enabled/disabled, and begin PGPdisk creation.
acaf5a
097efe BOOL·
604b44 CDiskWizCreationPage::OnSetActive()·
d7bb36 {
90d3ad ¤   pgpAssertAddrValid(mParentDiskWiz, CDiskWizardSheet);
18aed7 ¤   mParentDiskWiz->SetWizardButtons(NULL);
96af5a
f1e6c4 ¤   // Ask a separate thread to convert the PGPdisk.
bfa238 ¤   if (!mIsThreadActive)
17c7a1 ¤   {
6ab96f ¤   ¤   CreatePGPdiskInfo¤  CPI;
f54753 ¤   ¤   DualErr¤¤   ¤   ¤   derr;
07af5a
5680f9 ¤   ¤   pgpAssertAddrValid(mCreationThread, CCreatePGPdiskThread);
fcaf5a
70e622 ¤   ¤   CPI.path¤   ¤   = mParentDiskWiz->mPath;
037c98 ¤   ¤   CPI.blocksDisk¤ = mParentDiskWiz->mVolumeInfoPage.mBlocksDisk;
32e1de ¤   ¤   CPI.randomPool¤ = &mParentDiskWiz->mRandomDataPage.mRandomPool;
53af5a
03cd46 ¤   ¤   CPI.passphrase =·
b2803e ¤   ¤   ¤   mParentDiskWiz->mPassphrasePage.mPassphraseEdit.mContents;
1daf5a
cceec3 ¤   ¤   CPI.drive =·
f0b63e ¤   ¤   ¤   mParentDiskWiz->mVolumeInfoPage.mDriveCombo.mDriveNumber;
aeaf5a
aca83b ¤   ¤   CPI.callerHwnd¤ ¤   = GetSafeHwnd();
3fbc91 ¤   ¤   CPI.progressHwnd¤   = mProgressBar.GetSafeHwnd();
1eaf5a
28d431 ¤   ¤   // Start the creation thread.
476b7d ¤   ¤   mIsThreadActive = TRUE;
9647ab ¤   ¤   derr = mCreationThread->CallPGPdiskCreate(&CPI);
b0af5a
55a1e2 ¤   ¤   // Close our 'stolen' handle.
756d51 ¤   ¤   if (mParentDiskWiz->mStolenFile.Opened())
c2989a ¤   ¤   ¤   mParentDiskWiz->mStolenFile.Close();
8daf5a
3bad1f ¤   ¤   // Set the progress message.
c3aa35 ¤   ¤   if (derr.IsntError())
--73e9 000381b0eab40110089 Page 4 of CDiskWizCreationPage.cpp
e35b34 ¤   ¤   {
3ce9b2 ¤   ¤   ¤   SetProgressString(
446891 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskCreationCreateMsgString));
6faf5a
acb0bc ¤   ¤   ¤   mParentDiskWiz->SendDlgItemMessage(IDCANCEL, WM_KILLFOCUS, NULL,·
b03b6d ¤   ¤   ¤   ¤   NULL);
f50fe4 ¤   ¤   }
f7af5a
13bdd6 ¤   ¤   if (derr.IsError())
825b34 ¤   ¤   {
68a422 ¤   ¤   ¤   mIsThreadActive = FALSE;
71af5a
686ce2 ¤   ¤   ¤   mParentDiskWiz->mDerr = derr;
ff810c ¤   ¤   ¤   mParentDiskWiz->EndDialog(IDCANCEL);
910fe4 ¤   ¤   }
0b9371 ¤   }
09af5a
72bfaa ¤   return CPropertyPage::OnSetActive();
1defe6 }
a2af5a
d88fb6 // OnWizardNext is called when the user clicks on the 'Next' button. We mount
e8a595 // the newly created PGPdisk.
03af5a
ed0218 LRESULT·
1ec0b5 CDiskWizCreationPage::OnWizardNext()·
abbb36 {
2f44a6 ¤   AppCommandInfo ACI;
17af5a
9d52c0 ¤   if (CPropertyPage::OnWizardNext() == -1)
31043c ¤   ¤   return -1;
83af5a
4255fd ¤   // Mount the unformatted PGPdisk.
d179be ¤   ACI.op¤ ¤   = kAppOp_Mount;
3b671a ¤   ACI.flags¤  = kACF_MountWithNoDialog;
cb5cb5 ¤   ACI.drive¤  = mParentDiskWiz->mVolumeInfoPage.mDriveCombo.mDriveNumber;
d08432 ¤   strcpy(ACI.path, mParentDiskWiz->mPath);
03af5a
e0a6ee ¤   ACI.data[0]¤= (PGPUInt32)·
d193b2 ¤   ¤   mParentDiskWiz->mPassphrasePage.mPassphraseEdit.mContents;
01af5a
53aeb5 ¤   App->DispatchAppCommandInfo(&ACI);
38af5a
843e6b ¤   return 0;
adefe6 }
acaf5a
3baf5a
0a7cc3 ///////////////////////////////////////////////////////////////////////////
beeff0 // CDiskWizCreationPage protected custom functions and non-default handlers
067cc3 ///////////////////////////////////////////////////////////////////////////
1caf5a
2c1d87 // SetProgressString updates the progress string with the specified message,
f8fcc1 // inserting the PGPdisk name where appropriate.
27af5a
4dc823 void·
16d74b CDiskWizCreationPage::SetProgressString(LPCSTR message)
febb36 {
2bb35f ¤   CString bareName;
87af5a
61a350 ¤   pgpAssertStrValid(message);
d4af5a
2c38d5 ¤   // Prepare the dialog message text.
8cf1e4 ¤   GetBareName(mParentDiskWiz->mPath, &bareName);
76af5a
58cfd3 ¤   // Format and truncate the message if necessary.
26cf2f ¤   App->FormatFitStringToWindow(message, bareName, &mProgressText,·
5e3aeb ¤   ¤   &mProgressStatic);
a2af5a
8e02a1 ¤   UpdateData(FALSE);
83efe6 }
c7af5a
c324e6 // The CDiskWizCreationPage data exchange function.
38af5a
--7832 000592054bc40110089 Page 5 of CDiskWizCreationPage.cpp
84c823 void·
7f66de CDiskWizCreationPage::DoDataExchange(CDataExchange *pDX)
b6bb36 {
2778f1 ¤   try
c0c7a1 ¤   {
2822a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
83af5a
83cb6d ¤   ¤   //{{AFX_DATA_MAP(CDiskWizCreationPage)
306c81 ¤   ¤   DDX_Control(pDX, IDC_DISKNAME_TEXT, mProgressStatic);
88f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
6488f1 ¤   ¤   DDX_Control(pDX, IDC_PROGRESS_BAR, mProgressBar);
264a5a ¤   ¤   DDX_Text(pDX, IDC_DISKNAME_TEXT, mProgressText);
733376 ¤   ¤   //}}AFX_DATA_MAP
cf9371 ¤   }
393c88 ¤   catch (CMemoryException *ex)
efc7a1 ¤   {
b66adc ¤   ¤   ex->Delete();
089371 ¤   }
3aefe6 }
b7af5a
5baf5a
f7d4a6 //////////////////////////////////////////////////////////
a28b7e // CDiskWizCreationPage protected default message handlers
99d4a6 //////////////////////////////////////////////////////////
4faf5a
6a18db // OnCancel is called when the cancel button is pressed.
deaf5a
9cc823 void·
7111c3 CDiskWizCreationPage::OnCancel()·
dacebb {¤
f4af53 ¤   if (mIsThreadActive)
68c7a1 ¤   {
88d6e7 ¤   ¤   // Tell it to delete itself since we may be gone by the time it
dbdbed ¤   ¤   // finishes the cancel.
cfaf5a
aa80f9 ¤   ¤   pgpAssertAddrValid(mCreationThread, CCreatePGPdiskThread);
7caf5a
bc6076 ¤   ¤   mIsCTAutoDelete = TRUE;
a7cfa2 ¤   ¤   mCreationThread->m_bAutoDelete = TRUE;
3baf5a
1085c5 ¤   ¤   mCreationThread->CancelPGPdiskCreate();
129371 ¤   }
f1af5a
32aa1e ¤   DeleteFile(mParentDiskWiz->mPath);
f763f3 ¤   CPropertyPage::OnCancel();
1cefe6 }
a1af5a
f78cca // OnHelpInfo handles context-sensitive help.
93af5a
277efe BOOL·
d8ddf7 CDiskWizCreationPage::OnHelpInfo(HELPINFO *pHelpInfo)
a0bb36 {
e629b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
bee5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
00c7a1 ¤   {
98ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
ff6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
b79371 ¤   }
7caf5a
99c2e7 ¤   return TRUE;
b5efe6 }
deaf5a
899c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
82af5a
7bc823 void·
97fdff CDiskWizCreationPage::OnPaint()·
d2bb36 {
7d0575 ¤   CDC¤¤   ¤   memDC;
eac943 ¤   CPaintDC¤   DC(this);
e1e3a1 ¤   HBITMAP¤¤   oldBitmap;
93b2e4 ¤   RECT¤   ¤   sidebarRect;
59af5a
--bdd9 0011e10d93d40110089 Page 6 of CDiskWizCreationPage.cpp
4ccf3b ¤   DC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
4ccf08 ¤   DC.RealizePalette();
5eaf5a
12ce55 ¤   memDC.CreateCompatibleDC(&DC);
1584cd ¤   memDC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
02bb83 ¤   memDC.RealizePalette();
ebaf5a
ee7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
397564 ¤   ScreenToClient(&sidebarRect);
3567c5 ¤
97e586 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so don't
a78f6e ¤   // fool with it.
05af5a
2b366b ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mParentDiskWiz->mSidebarBitmap);
c5af5a
e196b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
fceefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
bfaf5a
1aac4f ¤   memDC.SelectObject(oldBitmap);
2a63a9 ¤   memDC.DeleteDC();
1eefe6 }
--b397 000b3a5452b4011008a Page 1 of CDiskWizCreationPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
a27eca // CDiskWizCreationPage.h
0d465d //
9ada6b // Declaration of class CDiskWizCreationPage.
131bc3 //////////////////////////////////////////////////////////////////////////////
efaf5a
a3a7dc // $Id: CDiskWizCreationPage.h,v 1.1.2.7 1998/07/06 08:56:46 nryan Exp $
e8af5a
26cbce // Copyright (C) 1998 by Network Associates, Inc.
5a71ae // All rights reserved.
97af5a
7b19aa #ifndef Included_CDiskWizCreationPage_h¤// [
621f43 #define Included_CDiskWizCreationPage_h
2eaf5a
0a85a8 #include "CCreatePGPdiskThread.h"
e7ab81 #include "Resource.h"
9baf5a
8aaf5a
efd557 ////////
0e02c9 // Types
73d557 ////////
c8af5a
dd7725 class CDiskWizardSheet;
beaf5a
79af5a
de8104 /////////////////////////////
28dffb // Class CDiskWizCreationPage
818104 /////////////////////////////
06af5a
ef4947 class CDiskWizCreationPage : public CPropertyPage
15bb36 {
093b0c ¤   DECLARE_DYNCREATE(CDiskWizCreationPage)
b8af5a
f75ed4 public:
41d540 ¤   CDiskWizardSheet¤   *mParentDiskWiz;¤   // pointer to parent sheet
59fb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
1f5875 ¤   PGPBoolean¤ ¤   ¤   mIsThreadActive;¤   // is the thread active?
d6af5a
1a60e1 ¤   CDiskWizCreationPage();
cd461a ¤   ~CDiskWizCreationPage();
cbaf5a
4e242e ¤   //{{AFX_DATA(CDiskWizCreationPage)
ea104d ¤   enum { IDD = IDD_DISKWIZ_CREATION };
8f345c ¤   CStatic¤mProgressStatic;
ef45be ¤   CStatic¤mSidebarGraphic;
0f027a ¤   CProgressCtrl¤  mProgressBar;
d021eb ¤   CString¤mProgressText;
5a5139 ¤   //}}AFX_DATA
58af5a
2a917d ¤   //{{AFX_VIRTUAL(CDiskWizCreationPage)
2e67d4 ¤   public:
636e36 ¤   virtual BOOL OnSetActive();
aaa2ce ¤   virtual LRESULT OnWizardNext();
66d8cf ¤   virtual void OnCancel();
256275 ¤   virtual BOOL OnQueryCancel();
2cc369 ¤   protected:
a03e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
2caf53 ¤   //}}AFX_VIRTUAL
90af5a
3ea2d3 protected:
e22d4d ¤   CCreatePGPdiskThread¤   *mCreationThread;¤  // thread to create PGPdisk
ea504f ¤   PGPBoolean¤ ¤   ¤   ¤   mIsCTAutoDelete;¤   // will it delete itself?
e4f4ec ¤   PGPBoolean¤ ¤   ¤   ¤   mSkipConfirmCancel;¤// to skip confirm cancel
c8af5a
b1974a ¤   void SetProgressString(LPCSTR message);
f4af5a
4553cd ¤   //{{AFX_MSG(CDiskWizCreationPage)
e2de15 ¤   afx_msg void OnFinishedCreate(WPARAM wParam, LPARAM lParam);
3b698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
b8c5f3 ¤   afx_msg void OnPaint();
c32e09 ¤   //}}AFX_MSG
b3af5a
--5405 0010874bb364011008a Page 2 of CDiskWizCreationPage.h
2a2409 ¤   DECLARE_MESSAGE_MAP()
eb82f7 };
83af5a
ffc18c //{{AFX_INSERT_LOCATION}}
50af5a
08ee35 #endif¤ // ] Included_CDiskWizCreationPage_h
--f2c6 000b623286d4011008b Page 1 of CDiskWizDonePage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
092ed6 // CDiskWizDonePage.cpp
c8465d //
e5105e // Implementation of class CDiskWizDonePage.
0a1bc3 //////////////////////////////////////////////////////////////////////////////
afaf5a
151bb3 // $Id: CDiskWizDonePage.cpp,v 1.2.2.5.2.2 1998/10/22 22:27:29 nryan Exp $
6baf5a
dfcbce // Copyright (C) 1998 by Network Associates, Inc.
7e71ae // All rights reserved.
61af5a
8c9e12 #include "StdAfx.h"
8aaf5a
ab9bcf #include "Required.h"
e8ca96 #include "CDiskWizDonePage.h"
3d22eb #include "CDiskWizardSheet.h"
a2c411 #include "Globals.h"
224713 #include "PGPdiskHelpIds.h"
66af5a
ebaf5a
aa6cc2 /////////////////////
c63a71 // Context help array
846cc2 /////////////////////
dbaf5a
1877bf static PGPUInt32 HelpIds[] =
bebb36 {
cccec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
eece3c ¤   0,0·
9782f7 };
60af5a
f3af5a
8a83f5 ///////////////////////////
5bb249 // MFC specific definitions
1583f5 ///////////////////////////
ddaf5a
053f8d BEGIN_MESSAGE_MAP(CDiskWizDonePage, CPropertyPage)
346b55 ¤   //{{AFX_MSG_MAP(CDiskWizDonePage)
94db65 ¤   ON_WM_HELPINFO()
562fa5 ¤   ON_WM_PAINT()
78044a ¤   //}}AFX_MSG_MAP
87af28 END_MESSAGE_MAP()
83af5a
88af5a
6f3924 ////////////////////////////////////////////////////////////////////
b322a0 // CDiskWizDonePage public custom functions and non-default handlers
c73924 ////////////////////////////////////////////////////////////////////
95af5a
b40262 IMPLEMENT_DYNCREATE(CDiskWizDonePage, CPropertyPage)
deaf5a
582f3d // The CDiskWizDonePage default constructor.
8daf5a
e1484c CDiskWizDonePage::CDiskWizDonePage()
7cfe2f ¤   ·: CPropertyPage(CDiskWizDonePage::IDD)
e9bb36 {
1125d1 ¤   //{{AFX_DATA_INIT(CDiskWizDonePage)
3eb1e8 ¤   //}}AFX_DATA_INIT
4aaf5a
0c3010 ¤   mParentDiskWiz = NULL;
eaaf5a
0a218f ¤   // Exorcise the big help button.
4f6a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
82efe6 }
f5af5a
027a89 // The CDiskWizDonePage destructor.
f3af5a
31ec74 CDiskWizDonePage::~CDiskWizDonePage()
f2bb36 {
05efe6 }
8faf5a
56af5a
698fbd ///////////////////////////////////////////////////
b6c683 // CDiskWizDonePage public default message handlers
--856a 000a7b398ac4011008b Page 2 of CDiskWizDonePage.cpp
298fbd ///////////////////////////////////////////////////
f9af5a
79c57f // OnSetActive is called when this page is made active. We make sure the
d1fdfc // correct buttons are enabled/disabled.
faaf5a
a77efe BOOL·
727a86 CDiskWizDonePage::OnSetActive()·
f5bb36 {
fdd3ad ¤   pgpAssertAddrValid(mParentDiskWiz, CDiskWizardSheet);
b3af5a
a0f786 ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_FINISH);
678329 ¤   mParentDiskWiz->GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
caaf5a
9bbfaa ¤   return CPropertyPage::OnSetActive();
eeefe6 }
deaf5a
c2fa3f // OnWizardFinish is called when the user selects the "Finish" button. We
7af85b // display the new mounted PGPdisk in an Explorer window.
59af5a
ac7efe BOOL·
7ea9bc CDiskWizDonePage::OnWizardFinish()·
1cbb36 {
3c85e5 ¤   if (!CPropertyPage::OnWizardFinish())
a898aa ¤   ¤   return FALSE;
3e67c5 ¤
43c2e7 ¤   return TRUE;
d0efe6 }
fbaf5a
b8af5a
a8a6b9 ///////////////////////////////////////////////////////////////////////
fa0dac // CDiskWizDonePage protected custom functions and non-default handlers
44a6b9 ///////////////////////////////////////////////////////////////////////
eaaf5a
2dca73 // The CDiskWizDonePage data exchange function.
d5af5a
88c823 void·
4c6c4b CDiskWizDonePage::DoDataExchange(CDataExchange *pDX)
ecbb36 {
1c78f1 ¤   try
77c7a1 ¤   {
3322a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
57af5a
6e12fa ¤   ¤   //{{AFX_DATA_MAP(CDiskWizDonePage)
6ef698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
b33376 ¤   ¤   //}}AFX_DATA_MAP
af9371 ¤   }
c03c88 ¤   catch (CMemoryException *ex)
1ac7a1 ¤   {
886adc ¤   ¤   ex->Delete();
209371 ¤   }
0eefe6 }
f0af5a
aeaf5a
dbdd60 //////////////////////////////////////////////////////
b9a03a // CDiskWizDonePage protected default message handlers
2cdd60 //////////////////////////////////////////////////////
bbaf5a
788cca // OnHelpInfo handles context-sensitive help.
96af5a
3c7efe BOOL·
6efdfc CDiskWizDonePage::OnHelpInfo(HELPINFO *pHelpInfo)
edbb36 {
8c29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
f6e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
0bc7a1 ¤   {
eaae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
056b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
429371 ¤   }
64af5a
fdc2e7 ¤   return TRUE;
d4efe6 }
a7af5a
--76bb 0018f1a42c54011008b Page 3 of CDiskWizDonePage.cpp
479c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
15af5a
d9c823 void·
98c976 CDiskWizDonePage::OnPaint()·
94bb36 {
2e0575 ¤   CDC¤¤   ¤   memDC;
6cc943 ¤   CPaintDC¤   DC(this);
7ce3a1 ¤   HBITMAP¤¤   oldBitmap;
36b2e4 ¤   RECT¤   ¤   sidebarRect;
6faf5a
32cf3b ¤   DC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
a8cf08 ¤   DC.RealizePalette();
75af5a
bcce55 ¤   memDC.CreateCompatibleDC(&DC);
4a84cd ¤   memDC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
cfbb83 ¤   memDC.RealizePalette();
42af5a
3f7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
de7564 ¤   ScreenToClient(&sidebarRect);
0167c5 ¤
d5e586 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so don't
248f6e ¤   // fool with it.
5eaf5a
16366b ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mParentDiskWiz->mSidebarBitmap);
85af5a
2896b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
7ceefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
69af5a
6aac4f ¤   memDC.SelectObject(oldBitmap);
b663a9 ¤   memDC.DeleteDC();
8fefe6 }
--1f13 0013b6091eb4011008c Page 1 of CDiskWizDonePage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
84af3c // CDiskWizDonePage.h
d8465d //
bf1616 // Declaration of class CDiskWizDonePage.
5c1bc3 //////////////////////////////////////////////////////////////////////////////
78af5a
f70326 // $Id: CDiskWizDonePage.h,v 1.1.2.4 1998/07/06 08:56:47 nryan Exp $
cbaf5a
5acbce // Copyright (C) 1998 by Network Associates, Inc.
3671ae // All rights reserved.
ebaf5a
a10e03 #ifndef Included_CDiskWizDonePage_h¤// [
e41a46 #define Included_CDiskWizDonePage_h
edaf5a
daab81 #include "Resource.h"
e5af5a
f6af5a
88d557 ////////
b302c9 // Types
44d557 ////////
27af5a
a67725 class CDiskWizardSheet;
c2af5a
5caf5a
ca9f73 /////////////////////////
454f1f // Class CDiskWizDonePage
279f73 /////////////////////////
b8af5a
2b5f07 class CDiskWizDonePage : public CPropertyPage
d5bb36 {
4e903e ¤   DECLARE_DYNCREATE(CDiskWizDonePage)
0eaf5a
7d5ed4 public:
653eea ¤   CDiskWizardSheet *mParentDiskWiz;¤  // pointer to parent sheet
d6af5a
0196db ¤   CDiskWizDonePage();
395d2f ¤   ~CDiskWizDonePage();
98af5a
ebc791 ¤   //{{AFX_DATA(CDiskWizDonePage)
679769 ¤   enum { IDD = IDD_DISKWIZ_DONE };
4f45be ¤   CStatic¤mSidebarGraphic;
145139 ¤   //}}AFX_DATA
77af5a
2a7cd1 ¤   //{{AFX_VIRTUAL(CDiskWizDonePage)
9767d4 ¤   public:
b56e36 ¤   virtual BOOL OnSetActive();
da0906 ¤   virtual BOOL OnWizardFinish();
5bc369 ¤   protected:
ce3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
81af53 ¤   //}}AFX_VIRTUAL
ccaf5a
06a2d3 protected:
f6fdc6 ¤   //{{AFX_MSG(CDiskWizDonePage)
e7698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
32c5f3 ¤   afx_msg void OnPaint();
412e09 ¤   //}}AFX_MSG
b7af5a
b92409 ¤   DECLARE_MESSAGE_MAP()
fe82f7 };
abaf5a
24c18c //{{AFX_INSERT_LOCATION}}
55af5a
3b66cf #endif¤ // ] Included_CDiskWizDonePage_h
--bbe5 000918f7c374011008d Page 1 of CDiskWizIntroPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
8c7265 // CDiskWizIntroPage.cpp
83465d //
c93602 // Implementation of class CDiskWizIntroPage.
a11bc3 //////////////////////////////////////////////////////////////////////////////
79af5a
a517bf // $Id: CDiskWizIntroPage.cpp,v 1.2.2.12 1998/08/10 23:31:51 nryan Exp $
16af5a
f8cbce // Copyright (C) 1998 by Network Associates, Inc.
1071ae // All rights reserved.
41af5a
119e12 #include "StdAfx.h"
e9af5a
789bcf #include "Required.h"
647454 #include "CDiskWizIntroPage.h"
0f22eb #include "CDiskWizardSheet.h"
4537c7 #include "CSavePGPdiskDialog.h"
47c411 #include "Globals.h"
8b4713 #include "PGPdiskHelpIds.h"
abaf5a
78af5a
966cc2 /////////////////////
fe3a71 // Context help array
7c6cc2 /////////////////////
3eaf5a
e477bf static PGPUInt32 HelpIds[] =
65bb36 {
39cec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
01ce3c ¤   0,0·
1782f7 };
eaaf5a
d0af5a
db83f5 ///////////////////////////
acb249 // MFC specific definitions
dd83f5 ///////////////////////////
f1af5a
306fab BEGIN_MESSAGE_MAP(CDiskWizIntroPage, CPropertyPage)
8549a7 ¤   //{{AFX_MSG_MAP(CDiskWizIntroPage)
dedb65 ¤   ON_WM_HELPINFO()
e32fa5 ¤   ON_WM_PAINT()
58044a ¤   //}}AFX_MSG_MAP
dfaf28 END_MESSAGE_MAP()
28af5a
dfaf5a
8b95ce /////////////////////////////////////////////////////////////////////
155c08 // CDiskWizIntroPage public custom functions and non-default handlers
4195ce /////////////////////////////////////////////////////////////////////
09af5a
1e706f IMPLEMENT_DYNCREATE(CDiskWizIntroPage, CPropertyPage)
a9af5a
8eb119 // The CDiskWizIntroPage default constructor.
92af5a
000ba0 CDiskWizIntroPage::CDiskWizIntroPage()
f8840e ¤   ·: CPropertyPage(CDiskWizIntroPage::IDD)
c2bb36 {
6e8bc5 ¤   //{{AFX_DATA_INIT(CDiskWizIntroPage)
b7b1e8 ¤   //}}AFX_DATA_INIT
eaaf5a
0e3010 ¤   mParentDiskWiz = NULL;
18af5a
b9218f ¤   // Exorcise the big help button.
356a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
5befe6 }
14af5a
c41dfd // The CDiskWizIntroPage destructor.
5daf5a
07384e CDiskWizIntroPage::~CDiskWizIntroPage()
f4bb36 {
1befe6 }
ccaf5a
c0af5a
919c30 ////////////////////////////////////////////////////
--b9ec 000df3bee924011008d Page 2 of CDiskWizIntroPage.cpp
48c223 // CDiskWizIntroPage public default message handlers
0f9c30 ////////////////////////////////////////////////////
28af5a
41c57f // OnSetActive is called when this page is made active. We make sure the
4bfdfc // correct buttons are enabled/disabled.
4eaf5a
767efe BOOL·
8e2596 CDiskWizIntroPage::OnSetActive()·
5ebb36 {
99d3ad ¤   pgpAssertAddrValid(mParentDiskWiz, CDiskWizardSheet);
05a0db ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_NEXT);
99af5a
9e8048 ¤   // Unsteal the handle if stolen.
91226f ¤   if (mParentDiskWiz->mStolenFile.Opened())
42c7a1 ¤   {
9eca07 ¤   ¤   mParentDiskWiz->mStolenFile.Close();
47af5a
2f7176 ¤   ¤   if (!mParentDiskWiz->mAreWeReplacing)
e835ca ¤   ¤   ¤   DeleteFile(mParentDiskWiz->mPath);
b79371 ¤   }
dfaf5a
ccbfaa ¤   return CPropertyPage::OnSetActive();
8fefe6 }
efaf5a
754893 // OnWizardNext is called when the user clicks on the 'Next' button.
45af5a
3d0218 LRESULT·
433544 CDiskWizIntroPage::OnWizardNext()·
5ebb36 {
a57d36 ¤   DualErr derr;
65af5a
a152c0 ¤   if (CPropertyPage::OnWizardNext() == -1)
45043c ¤   ¤   return -1;
39af5a
6d7aab ¤   // Ask for a path and filename.
73a7cf ¤   derr = AskForPath();
2daf5a
944bb3 ¤   if (derr.IsError())
f4c7a1 ¤   {
54500c ¤   ¤   mParentDiskWiz->mDerr = derr;
80f2b0 ¤   ¤   mParentDiskWiz->PressButton(PSBTN_CANCEL);¤ // NOT EndDialog (MFC bug)
ed9371 ¤   }
00af5a
ec293b ¤   return (derr.IsntError() ? 0 : 1);
a3efe6 }
1caf5a
47af5a
dada3d ////////////////////////////////////////////////////////////////////////
4dae6d // CDiskWizIntroPage protected custom functions and non-default handlers
0eda3d ////////////////////////////////////////////////////////////////////////
3aaf5a
be2964 // The CDiskWizIntroPage data exchange function.
18af5a
d2c823 void·
092f0a CDiskWizIntroPage::DoDataExchange(CDataExchange *pDX)
2ebb36 {
e878f1 ¤   try
d9c7a1 ¤   {
9422a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
6eaf5a
8a1423 ¤   ¤   //{{AFX_DATA_MAP(CDiskWizIntroPage)
91f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
153376 ¤   ¤   //}}AFX_DATA_MAP
629371 ¤   }
393c88 ¤   catch (CMemoryException *ex)
7dc7a1 ¤   {
9b6adc ¤   ¤   ex->Delete();
cb9371 ¤   }
9defe6 }
1eaf5a
b8a8c3 // AskForPath allows the user to select a directory and filename for the
df0285 // destination PGPdisk.
--b49f 000ef4290b14011008d Page 3 of CDiskWizIntroPage.cpp
e0af5a
6f2292 DualErr·
b9a2a6 CDiskWizIntroPage::AskForPath()·
d6bb36 {
778400 ¤   CSavePGPdiskDialog¤ newPGPdiskDlg(kSDT_Create, mParentDiskWiz);
f8705b ¤   DualErr¤¤   ¤   ¤   derr;
91991b ¤   File¤   ¤   ¤   ¤   existingFile;
c8af5a
b7a683 ¤   // Get a filename and new location from the user.
0c2361 ¤   if (derr.IsntError())
aec7a1 ¤   {
4a1dc4 ¤   ¤   derr = newPGPdiskDlg.AskForPath(&mParentDiskWiz->mPath,·
126d7d ¤   ¤   ¤   mParentDiskWiz->mPath);
639371 ¤   }
46af5a
122361 ¤   if (derr.IsntError())
37c7a1 ¤   {
b61a07 ¤   ¤   // Replacing an existing file?
c6e974 ¤   ¤   mParentDiskWiz->mAreWeReplacing =·
b44bec ¤   ¤   ¤   App->IsFileValid(mParentDiskWiz->mPath);
dbaf5a
1a3d9a ¤   ¤   // Steal the handle.
6741a7 ¤   ¤   derr = mParentDiskWiz->mStolenFile.Open(mParentDiskWiz->mPath);
ab9371 ¤   }
0baf5a
c333e3 ¤   return derr;
2aefe6 }
72af5a
daaf5a
43910a ///////////////////////////////////////////////////////
05c88d // CDiskWizIntroPage protected default message handlers
3c910a ///////////////////////////////////////////////////////
a7af5a
2c8cca // OnHelpInfo handles context-sensitive help.
20af5a
f87efe BOOL·
a42010 CDiskWizIntroPage::OnHelpInfo(HELPINFO *pHelpInfo)
9abb36 {
ac29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
6ce5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
83c7a1 ¤   {
f8ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
cd6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
e29371 ¤   }
e8af5a
34c2e7 ¤   return TRUE;
e0efe6 }
59af5a
979c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
93af5a
92c823 void·
c55c3f CDiskWizIntroPage::OnPaint()·
10bb36 {
0a0575 ¤   CDC¤¤   ¤   memDC;
3ac943 ¤   CPaintDC¤   DC(this);
e0e3a1 ¤   HBITMAP¤¤   oldBitmap;
27b2e4 ¤   RECT¤   ¤   sidebarRect;
ccaf5a
15cf3b ¤   DC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
28cf08 ¤   DC.RealizePalette();
abaf5a
5dce55 ¤   memDC.CreateCompatibleDC(&DC);
a384cd ¤   memDC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
7bbb83 ¤   memDC.RealizePalette();
5caf5a
147fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
9d7564 ¤   ScreenToClient(&sidebarRect);
4067c5 ¤
a40eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
dae162 ¤   // don't fool with it.
bdaf5a
ef366b ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mParentDiskWiz->mSidebarBitmap);
--3209 00153fedc334011008d Page 4 of CDiskWizIntroPage.cpp
e0af5a
5196b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
d9eefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
09af5a
68ac4f ¤   memDC.SelectObject(oldBitmap);
fd63a9 ¤   memDC.DeleteDC();
53efe6 }
--3893 0013b1349cf4011008e Page 1 of CDiskWizIntroPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
c03538 // CDiskWizIntroPage.h
0e465d //
4cf848 // Declaration of class CDiskWizIntroPage.
2d1bc3 //////////////////////////////////////////////////////////////////////////////
92af5a
51b0b3 // $Id: CDiskWizIntroPage.h,v 1.1.2.6.2.1 1998/10/21 01:35:16 nryan Exp $
15af5a
75cbce // Copyright (C) 1998 by Network Associates, Inc.
0a71ae // All rights reserved.
95af5a
1b0f7a #ifndef Included_CDiskWizIntroPage_h¤   // [
4375aa #define Included_CDiskWizIntroPage_h
1baf5a
0a3a85 #include "DualErr.h"
5fab81 #include "Resource.h"
a2af5a
9faf5a
66d557 ////////
a502c9 // Types
f0d557 ////////
2aaf5a
c47725 class CDiskWizardSheet;
03af5a
05af5a
f8b352 //////////////////////////
81cd05 // Class CDiskWizIntroPage
ebb352 //////////////////////////
eeaf5a
902f2f class CDiskWizIntroPage : public CPropertyPage
c0bb36 {
349489 ¤   DECLARE_DYNCREATE(CDiskWizIntroPage)
f8af5a
5c5ed4 public:
973eea ¤   CDiskWizardSheet *mParentDiskWiz;¤  // pointer to parent sheet
2daf5a
bd904f ¤   CDiskWizIntroPage();
b6212f ¤   ~CDiskWizIntroPage();
c0af5a
b0c923 ¤   //{{AFX_DATA(CDiskWizIntroPage)
35359b ¤   enum { IDD = IDD_DISKWIZ_INTRO };
9d45be ¤   CStatic¤mSidebarGraphic;
8d5139 ¤   //}}AFX_DATA
87af5a
128b9c ¤   //{{AFX_VIRTUAL(CDiskWizIntroPage)
6967d4 ¤   public:
5f6e36 ¤   virtual BOOL OnSetActive();
afa2ce ¤   virtual LRESULT OnWizardNext();
0bc369 ¤   protected:
c23e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
3daf53 ¤   //}}AFX_VIRTUAL
20af5a
eaa2d3 protected:
1aef23 ¤   //{{AFX_MSG(CDiskWizIntroPage)
29698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
4dc5f3 ¤   afx_msg void OnPaint();
822e09 ¤   //}}AFX_MSG
03af5a
7676bb ¤   DualErr AskForPath();
63af5a
0a2409 ¤   DECLARE_MESSAGE_MAP()
6782f7 };
19af5a
afc18c //{{AFX_INSERT_LOCATION}}
beaf5a
3b6c1f #endif¤ // ] Included_CDiskWizIntroPage_h
--2178 000be273db04011008f Page 1 of CDiskWizPassphrasePage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
f9e006 // CDiskWizPassphrasePage.cpp
91465d //
83da57 // Implementation of class CDiskWizPassphrasePage.
e61bc3 //////////////////////////////////////////////////////////////////////////////
44af5a
3922d2 // $Id: CDiskWizPassphrasePage.cpp,v 1.2.2.6 1998/07/06 08:56:49 nryan Exp $
58af5a
4dcbce // Copyright (C) 1998 by Network Associates, Inc.
bb71ae // All rights reserved.
36af5a
789e12 #include "StdAfx.h"
a9af5a
d39bcf #include "Required.h"
04d516 #include "CDiskWizPassphrasePage.h"
e822eb #include "CDiskWizardSheet.h"
59c411 #include "Globals.h"
c14713 #include "PGPdiskHelpIds.h"
45af5a
5caf5a
6c09b7 ////////////
cce738 // Constants
9f09b7 ////////////
0faf5a
db163b // Hide typing by default?
3cbc9f const PGPBoolean kDefaultDiskWizPassHideTyping = TRUE;
dcaf5a
55af5a
456cc2 /////////////////////
8c3a71 // Context help array
d16cc2 /////////////////////
66af5a
e077bf static PGPUInt32 HelpIds[] =
c1bb36 {
78dba5 ¤   IDC_PASSPHRASE_EDIT,¤   IDH_PGPDISKAPP_DISKWIZPASSEDIT1,·
1ad049 ¤   IDC_CONFIRM_EDIT,¤  ¤   IDH_PGPDISKAPP_DISKWIZPASSEDIT2,·
727269 ¤   IDC_HIDETYPE_CHECK,¤¤   IDH_PGPDISKAPP_DISKWIZPASSHIDECHECK,·
65bb96 ¤   IDC_QUALITY_BAR,¤   ¤   IDH_PGPDISKAPP_DISKWIZPASSQUALITY,·
a3f04c ····IDC_CAPSLOCK_TEXT,¤ ¤   ((PGPUInt32) -1),·
1ecec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
47ce3c ¤   0,0·
7282f7 };
e3af5a
4faf5a
d383f5 ///////////////////////////
58b249 // MFC specific definitions
3483f5 ///////////////////////////
42af5a
a1d87b BEGIN_MESSAGE_MAP(CDiskWizPassphrasePage, CPropertyPage)
48746b ¤   //{{AFX_MSG_MAP(CDiskWizPassphrasePage)
d0db65 ¤   ON_WM_HELPINFO()
31138c ¤   ON_EN_CHANGE(IDC_PASSPHRASE_EDIT, OnChangePassphrase)
f32725 ¤   ON_BN_CLICKED(IDC_HIDETYPE_CHECK, OnHideTypeCheck)
4ff730 ¤   ON_EN_KILLFOCUS(IDC_CONFIRM_EDIT, OnKillFocusConfirmEdit)
57c72a ¤   ON_EN_KILLFOCUS(IDC_PASSPHRASE_EDIT, OnKillFocusPassphraseEdit)
ad2fa5 ¤   ON_WM_PAINT()
e2044a ¤   //}}AFX_MSG_MAP
04af28 END_MESSAGE_MAP()
e5af5a
baaf5a
b04a2a //////////////////////////////////////////////////////////////////////////
fb6cdb // CDiskWizPassphrasePage public custom functions and non-default handlers
de4a2a //////////////////////////////////////////////////////////////////////////
65af5a
e7cf44 IMPLEMENT_DYNCREATE(CDiskWizPassphrasePage, CPropertyPage)
eeaf5a
18d62f // The CDiskWizPassphrasePage default constructor.
2daf5a
64749e CDiskWizPassphrasePage::CDiskWizPassphrasePage()
aa4ab3 ¤   ·: CPropertyPage(CDiskWizPassphrasePage::IDD)
7fbb36 {
bec1ff ¤   //{{AFX_DATA_INIT(CDiskWizPassphrasePage)
--9692 0004caba5b44011008f Page 2 of CDiskWizPassphrasePage.cpp
6639bb ¤   mHideTypeValue = FALSE;
00b1e8 ¤   //}}AFX_DATA_INIT
5caf5a
1fb5d0 ¤   mParentDiskWiz¤ = NULL;
7cd9c4 ¤   mIHadFocus¤ ¤   = NULL;
24af5a
25218f ¤   // Exorcise the big help button.
0f6a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
cbaf5a
aeb561 ¤   // Did the secure edit controls initialize properly?
d0daba ¤   mInitErr = mPassphraseEdit.mInitErr;
f4af5a
4e9c32 ¤   if (mInitErr.IsntError())
b0c7a1 ¤   {
4c65c9 ¤   ¤   mInitErr = mConfirmationEdit.mInitErr;
999371 ¤   }
fcefe6 }
c0af5a
ec018a // The CDiskWizPassphrasePage destructor.
02af5a
66d90c CDiskWizPassphrasePage::~CDiskWizPassphrasePage()
63bb36 {
5eefe6 }
5faf5a
c8819a // PreTranslateMessage sees all messages before MFC filters them. We need to
cff6fb // check for the caps lock key and the return key.
23af5a
837efe BOOL·
a4ed29 CDiskWizPassphrasePage::PreTranslateMessage(MSG* pMsg)·
76bb36 {
0ff87e ¤   switch (pMsg->message)
adc7a1 ¤   {
5ab11a ¤   case WM_KEYDOWN:
b4a806 ¤   ¤   if ((pMsg->wParam & 0x7F) == VK_RETURN)
3c5b34 ¤   ¤   {
d9312a ¤   ¤   ¤   mParentDiskWiz->PressButton(PSBTN_NEXT);
eb32bd ¤   ¤   ¤   return TRUE;
c30fe4 ¤   ¤   }
fe2f68 ¤   ¤   break;
efaf5a
d2948b ¤   case WM_KEYUP:
7fe270 ¤   ¤   SetCapsLockMessageState();
632f68 ¤   ¤   break;
689371 ¤   }
00af5a
c5f5d8 ¤   return CPropertyPage::PreTranslateMessage(pMsg);
c3efe6 }
caaf5a
20af5a
d04d57 /////////////////////////////////////////////////////////
1b4826 // CDiskWizPassphrasePage public default message handlers
5e4d57 /////////////////////////////////////////////////////////
f3af5a
5bc57f // OnSetActive is called when this page is made active. We make sure the
9ffdfc // correct buttons are enabled/disabled.
36af5a
e57efe BOOL·
651fd9 CDiskWizPassphrasePage::OnSetActive()·
7ebb36 {
e1d3ad ¤   pgpAssertAddrValid(mParentDiskWiz, CDiskWizardSheet);
3f0c42 ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
01af5a
1cbfaa ¤   return CPropertyPage::OnSetActive();
97efe6 }
3daf5a
ee5d86 // OnWizardNext is called when the 'Next' button is pressed. We perform
7e022f // data validation.
8daf5a
c50218 LRESULT·
168f8d CDiskWizPassphrasePage::OnWizardNext()·
0fbb36 {
4cb895 ¤   PGPBoolean¤ failThis¤   = FALSE;
--4568 0002a49b9964011008f Page 3 of CDiskWizPassphrasePage.cpp
bc3b06 ¤   PGPBoolean¤ lengthBelowMin;
e7af5a
d652c0 ¤   if (CPropertyPage::OnWizardNext() == -1)
33043c ¤   ¤   return -1;
d7af5a
824fd5 ¤   // Make sure the passphrase equals the confirmation.
d2d202 ¤   if ((* mPassphraseEdit.mContents) != (* mConfirmationEdit.mContents))
80c7a1 ¤   {
20894e ¤   ¤   failThis = TRUE;
7d1445 ¤   ¤   ReportError(kPGDMajorError_PassphraseNotConfirmed);
6b9371 ¤   }
32af5a
7ef705 ¤   // Check if the passphrase is above the legal length.
863a78 ¤   if (!failThis)
4cc7a1 ¤   {
92af37 ¤   ¤   lengthBelowMin = (mPassphraseEdit.mContents->GetLength() <·
d6833f ¤   ¤   ¤   kMinPassphraseLength);
6eaf5a
f844da ¤   ¤   if (lengthBelowMin)¤¤   ¤   ¤   // below the minimum legal size?
f15b34 ¤   ¤   {
afbd13 ¤   ¤   ¤   failThis = TRUE;
f37aa8 ¤   ¤   ¤   ReportError(kPGDMajorError_PassphraseTooSmall);
cb0fe4 ¤   ¤   }
e99371 ¤   }
63af5a
d990d1 ¤   if (failThis)
94c7a1 ¤   {
f5788b ¤   ¤   mPassphraseEdit.ClearEditContents();
61c710 ¤   ¤   mConfirmationEdit.ClearEditContents();
cd5755 ¤   ¤   mPassphraseEdit.SetFocus();
7faf5a
17043c ¤   ¤   return -1;
2c9371 ¤   }
e60e24 ¤   else
c1c7a1 ¤   {
7fbbde ¤   ¤   return 0;
cd9371 ¤   }
abefe6 }
a4af5a
3caf5a
a46c0e /////////////////////////////////////////////////////////////////////////////
1e78a4 // CDiskWizPassphrasePage protected custom functions and non-default handlers
2d6c0e /////////////////////////////////////////////////////////////////////////////
4aaf5a
bd6e23 // SetCapsLockMessageState shows or hides the caps lock message as needed.
8baf5a
9fc823 void·
093dda CDiskWizPassphrasePage::SetCapsLockMessageState()
cbbb36 {
2dc0f1 ¤   PGPUInt16 bob = GetKeyState(VK_CAPITAL);
f2af5a
7e33d5 ¤   if (GetKeyState(VK_CAPITAL) & 1)
3bc7a1 ¤   {
09ac4a ¤   ¤   mCapsLockStatic.ShowWindow(SW_SHOW);
539371 ¤   }
2d0e24 ¤   else
4ec7a1 ¤   {
7bd611 ¤   ¤   mCapsLockStatic.ShowWindow(SW_HIDE);
5a9371 ¤   }
4cefe6 }
4faf5a
10514e // The CDiskWizPassphrasePage data exchange function.
51af5a
ebc823 void·
0b9f1e CDiskWizPassphrasePage::DoDataExchange(CDataExchange *pDX)
edbb36 {
f478f1 ¤   try
09c7a1 ¤   {
5c22a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
d4af5a
b58db7 ¤   ¤   //{{AFX_DATA_MAP(CDiskWizPassphrasePage)
2af698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
--a120 0000d3b45bb4011008f Page 4 of CDiskWizPassphrasePage.cpp
6df4c2 ¤   ¤   DDX_Control(pDX, IDC_QUALITY_BAR, mQualityBar);
4ed337 ¤   ¤   DDX_Control(pDX, IDC_PASSPHRASE_EDIT, mPassphraseEdit);
613689 ¤   ¤   DDX_Control(pDX, IDC_CONFIRM_EDIT, mConfirmationEdit);
ebe5d1 ¤   ¤   DDX_Control(pDX, IDC_CAPSLOCK_TEXT, mCapsLockStatic);
646868 ¤   ¤   DDX_Check(pDX, IDC_HIDETYPE_CHECK, mHideTypeValue);
e63376 ¤   ¤   //}}AFX_DATA_MAP
cf9371 ¤   }
c13c88 ¤   catch (CMemoryException *ex)
66c7a1 ¤   {
6c6adc ¤   ¤   ex->Delete();
089371 ¤   }
4aefe6 }
7eaf5a
2472c3 // OnChangePassphrase is called whenever the user types a letter into the
631fbf // passphrase edit box. We adjust the "Password Quality" progress bar.
7baf5a
6bc823 void·
0dc95d CDiskWizPassphrasePage::OnChangePassphrase()·
bfbb36 {
f74c7e ¤   PGPUInt16 quality ;
4067c5 ¤
59b210 ¤   quality = App->CalcPassphraseQuality(mPassphraseEdit.mContents);
e3af5a
7c9c0a ¤   mQualityBar.SetPos(quality);
9befe6 }
8aaf5a
f500d8 // We override OnHideTypeCheck to set the 'hide typing' behavior of the edit
e5b7e3 // boxes
62af5a
ddc823 void·
2c2b7d CDiskWizPassphrasePage::OnHideTypeCheck()·
efbb36 {
8c364d ¤   UpdateData(TRUE);
6caf5a
32da1e ¤   mPassphraseEdit.SetHideTypingPref(mHideTypeValue);
44db3d ¤   mConfirmationEdit.SetHideTypingPref(mHideTypeValue);
5baf5a
0e9d2e ¤   mIHadFocus->SetFocus();
c0efe6 }
36af5a
a047ec // OnKillFocusConfirmEdit is called when the confirmation box is losing focus.
baaf5a
16c823 void·
6a584b CDiskWizPassphrasePage::OnKillFocusConfirmEdit()·
c1bb36 {
f423fc ¤   mIHadFocus = &mConfirmationEdit;¤
c8efe6 }
10af5a
2e68c4 // OnKillFocusPassphraseEdit is called when the passphrase box is losing
406150 // focus.
a8af5a
25c823 void·
3343f9 CDiskWizPassphrasePage::OnKillFocusPassphraseEdit()·
a4bb36 {
3c3f93 ¤   mIHadFocus = &mPassphraseEdit;
cfefe6 }
6eaf5a
7faf5a
bc5ea1 ////////////////////////////////////////////////////////////
1d808c // CDiskWizPassphrasePage protected default message handlers
5a5ea1 ////////////////////////////////////////////////////////////
30af5a
3f8cca // OnHelpInfo handles context-sensitive help.
43af5a
c47efe BOOL·
345dbd CDiskWizPassphrasePage::OnHelpInfo(HELPINFO *pHelpInfo)
57bb36 {
6329b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
50e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
5ec7a1 ¤   {
99ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
0d6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
--429c 0005c209bf64011008f Page 5 of CDiskWizPassphrasePage.cpp
a19371 ¤   }
93af5a
07c2e7 ¤   return TRUE;
77efe6 }
32af5a
89360f // OnInitDialog is overwritten to perform property page initialization.
10af5a
867efe BOOL·
f962d1 CDiskWizPassphrasePage::OnInitDialog()·
8cbb36 {
2d78f1 ¤   try
e4c7a1 ¤   {
4ce4c1 ¤   ¤   CString¤bareName, temp;
9baf5a
1b04b2 ¤   ¤   CPropertyPage::OnInitDialog();
50af5a
c37efe ¤   ¤   // This must be called first to make MFC happy.
d6e040 ¤   ¤   UpdateData(FALSE);
9caf5a
ff2328 ¤   ¤   // Prepare the passphrase quality bar.
42e8ea ¤   ¤   mQualityBar.SetRange(0, 100);
f57e13 ¤   ¤   mQualityBar.SetPos(0);
0eaf5a
45b0b3 ¤   ¤   // Prepare the dialog message text.
1aa748 ¤   ¤   temp = mParentDiskWiz->mPath;
c123c6 ¤   ¤   bareName = temp.Right(temp.GetLength() - temp.ReverseFind('\\') - 1);
7eaf5a
b14b3e ¤   ¤   // Show the caps lock message if necessary.
98e270 ¤   ¤   SetCapsLockMessageState();
c7af5a
f123a7 ¤   ¤   // Set the hide-typing checkbox.
d129ac ¤   ¤   mHideTypeValue = kDefaultDiskWizPassHideTyping;
c6af5a
7496cc ¤   ¤   // Set the hide-typing pref of the edit boxes.
a2dd25 ¤   ¤   mPassphraseEdit.SetHideTypingPref(mHideTypeValue);
bcfd88 ¤   ¤   mConfirmationEdit.SetHideTypingPref(mHideTypeValue);
e8af5a
f04b82 ¤   ¤   // Set the maximum text length of the edit boxes.
a86d5c ¤   ¤   mPassphraseEdit.SetMaxSizeContents(kMaxPassphraseLength);
7223ed ¤   ¤   mConfirmationEdit.SetMaxSizeContents(kMaxPassphraseLength);
28af5a
497d40 ¤   ¤   // Set the focus to the topmost box.
745755 ¤   ¤   mPassphraseEdit.SetFocus();
a37e60 ¤   ¤   mIHadFocus = &mPassphraseEdit;
ccaf5a
47e040 ¤   ¤   UpdateData(FALSE);
b89371 ¤   }
af3c88 ¤   catch (CMemoryException *ex)
78c7a1 ¤   {
ab6adc ¤   ¤   ex->Delete();
279371 ¤   }
daaf5a
e1c2e7 ¤   return TRUE;
97efe6 }
50af5a
ad9c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
f1af5a
48c823 void·
eb56fb CDiskWizPassphrasePage::OnPaint()·
64bb36 {
f90575 ¤   CDC¤¤   ¤   memDC;
60c943 ¤   CPaintDC¤   DC(this);
98e3a1 ¤   HBITMAP¤¤   oldBitmap;
4bb2e4 ¤   RECT¤   ¤   sidebarRect;
49af5a
61cf3b ¤   DC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
39cf08 ¤   DC.RealizePalette();
a1af5a
07ce55 ¤   memDC.CreateCompatibleDC(&DC);
8084cd ¤   memDC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
93bb83 ¤   memDC.RealizePalette();
5caf5a
--230a 001ae523b854011008f Page 6 of CDiskWizPassphrasePage.cpp
e77fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
c57564 ¤   ScreenToClient(&sidebarRect);
4467c5 ¤
f4e586 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so don't
4d8f6e ¤   // fool with it.
e8af5a
f0366b ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mParentDiskWiz->mSidebarBitmap);
40af5a
6a96b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
d0eefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
cbaf5a
65ac4f ¤   memDC.SelectObject(oldBitmap);
8263a9 ¤   memDC.DeleteDC();
aeefe6 }
--db76 000f558f21a40110090 Page 1 of CDiskWizPassphrasePage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
332e24 // CDiskWizPassphrasePage.h
de465d //
8dc246 // Declaration of class CDiskWizPassphrasePage.
f11bc3 //////////////////////////////////////////////////////////////////////////////
97af5a
117ddb // $Id: CDiskWizPassphrasePage.h,v 1.1.2.5 1998/07/06 08:56:50 nryan Exp $
4baf5a
becbce // Copyright (C) 1998 by Network Associates, Inc.
d971ae // All rights reserved.
72af5a
1feab8 #ifndef Included_CDiskWizPassphrasePage_h¤  // [
edc3cc #define Included_CDiskWizPassphrasePage_h
0aaf5a
3d3a85 #include "DualErr.h"
47358e #include "CSecureEdit.h"
a2af5a
8aab81 #include "Resource.h"
3daf5a
a7af5a
76d557 ////////
0702c9 // Types
5ed557 ////////
12af5a
e67725 class CDiskWizardSheet;
e3af5a
f1af5a
1f8104 /////////////////////////////
c0fb57 // Class CDiskWizPassphrasePage
408104 /////////////////////////////
26af5a
3264d2 class CDiskWizPassphrasePage : public CPropertyPage
3abb36 {
2906b5 ¤   DECLARE_DYNCREATE(CDiskWizPassphrasePage)
95af5a
e35ed4 public:
d2d540 ¤   CDiskWizardSheet¤   *mParentDiskWiz;¤   // pointer to parent sheet
ccfb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
a8af5a
d601c4 ¤   CDiskWizPassphrasePage();
53dd50 ¤   ~CDiskWizPassphrasePage();
00af5a
aafe40 ¤   //{{AFX_DATA(CDiskWizPassphrasePage)
479fa7 ¤   enum { IDD = IDD_DISKWIZ_PASSPHRASE };
7945be ¤   CStatic¤mSidebarGraphic;
603625 ¤   CProgressCtrl¤  mQualityBar;
ad9d94 ¤   CSecureEdit¤mPassphraseEdit;
37696c ¤   CSecureEdit¤mConfirmationEdit;
a406f5 ¤   CStatic¤mCapsLockStatic;
44e23b ¤   BOOL¤   mHideTypeValue;
935139 ¤   //}}AFX_DATA
b5af5a
0fe5f9 ¤   //{{AFX_VIRTUAL(CDiskWizPassphrasePage)
5c67d4 ¤   public:
8aa2ce ¤   virtual LRESULT OnWizardNext();
376e36 ¤   virtual BOOL OnSetActive();
74a0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
6dc369 ¤   protected:
f03e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
15af53 ¤   //}}AFX_VIRTUAL
82af5a
d9a2d3 protected:
a61788 ¤   CSecureEdit *mIHadFocus;¤   // edit that had focus
f4af5a
c9219a ¤   void SetCapsLockMessageState();
1caf5a
393a89 ¤   //{{AFX_MSG(CDiskWizPassphrasePage)
52f17a ¤   virtual BOOL OnInitDialog();
35698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
82a928 ¤   afx_msg void OnChangePassphrase();
13c354 ¤   afx_msg void OnHideTypeCheck();
f5782e ¤   afx_msg void OnKillFocusConfirmEdit();
--5a9c 0011b3180f340110090 Page 2 of CDiskWizPassphrasePage.h
5f8433 ¤   afx_msg void OnKillFocusPassphraseEdit();
a7c5f3 ¤   afx_msg void OnPaint();
ea2e09 ¤   //}}AFX_MSG
57af5a
aa2409 ¤   DECLARE_MESSAGE_MAP()
0982f7 };
0eaf5a
cac18c //{{AFX_INSERT_LOCATION}}
29af5a
1b81de #endif¤ // ] Included_CDiskWizPassphrasePage_h
--d055 0005173c20240110091 Page 1 of CDiskWizRandomDataPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
806902 // CDiskWizRandomDataPage.cpp
9b465d //
71cb37 // Implementation of class CDiskWizRandomDataPage.
4c1bc3 //////////////////////////////////////////////////////////////////////////////
f8af5a
a3503f // $Id: CDiskWizRandomDataPage.cpp,v 1.2.2.6 1998/07/06 08:56:51 nryan Exp $
d0af5a
62cbce // Copyright (C) 1998 by Network Associates, Inc.
e771ae // All rights reserved.
75af5a
419e12 #include "StdAfx.h"
ecaf5a
929bcf #include "Required.h"
4ab14b #include "CDiskWizRandomDataPage.h"
0722eb #include "CDiskWizardSheet.h"
acc411 #include "Globals.h"
9f4713 #include "PGPdiskHelpIds.h"
57af5a
05af5a
8809b7 ////////////
b5e738 // Constants
fb09b7 ////////////
2faf5a
568754 const PGPUInt32 kPGPdiskRandomDataNeeded = 300;¤¤   // 300 bits
8faf5a
f1af5a
786cc2 /////////////////////
f23a71 // Context help array
df6cc2 /////////////////////
87af5a
9f77bf static PGPUInt32 HelpIds[] =
d0bb36 {
6c3d9e ¤   IDC_RANDOM_BAR,¤¤   ¤   IDH_PGPDISKAPP_DISKWIZRANDOMBAR,·
21cec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
c5ce3c ¤   0,0·
4782f7 };
f7af5a
7baf5a
6983f5 ///////////////////////////
3eb249 // MFC specific definitions
4d83f5 ///////////////////////////
e5af5a
95a62d BEGIN_MESSAGE_MAP(CDiskWizRandomDataPage, CPropertyPage)
59650b ¤   //{{AFX_MSG_MAP(CDiskWizRandomDataPage)
0edb65 ¤   ON_WM_HELPINFO()
755f6d ¤   ON_WM_MOUSEMOVE()
b28c56 ¤   ON_WM_LBUTTONDOWN()
c72fa5 ¤   ON_WM_PAINT()
04044a ¤   //}}AFX_MSG_MAP
56af28 END_MESSAGE_MAP()
e2af5a
cdaf5a
ab4a2a //////////////////////////////////////////////////////////////////////////
3521ee // CDiskWizRandomDataPage public custom functions and non-default handlers
a04a2a //////////////////////////////////////////////////////////////////////////
68af5a
25b112 IMPLEMENT_DYNCREATE(CDiskWizRandomDataPage, CPropertyPage)
04af5a
9a6cd2 // The CDiskWizRandomDataPage default constructor.
b6af5a
cf4969 CDiskWizRandomDataPage::CDiskWizRandomDataPage()
6a341a ¤   ·: CPropertyPage(CDiskWizRandomDataPage::IDD)
6fbb36 {
ded09f ¤   //{{AFX_DATA_INIT(CDiskWizRandomDataPage)
6f60e1 ¤   mRandomMessage = _T("");
a1b1e8 ¤   //}}AFX_DATA_INIT
eeaf5a
fa9202 ¤   mParentDiskWiz¤ ¤   = NULL;
3da1e6 ¤   mIsDoneCollecting¤  = FALSE;
f4d7bf ¤   mRequiredDataCount¤ = kPGPdiskRandomDataNeeded;
516b41 ¤   mProcessedDataCount¤= 0;
--e0b8 0006a2a673f40110091 Page 2 of CDiskWizRandomDataPage.cpp
e0af5a
70218f ¤   // Exorcise the big help button.
546a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
d8af5a
a4ebe7 ¤   mInitErr = mRandomPool.mInitErr;
18efe6 }
ddaf5a
e8d070 // The CDiskWizRandomDataPage destructor.
7aaf5a
0a5d4b CDiskWizRandomDataPage::~CDiskWizRandomDataPage()
c5bb36 {
83efe6 }
62af5a
847380 // PreTranslateMessage is overridden so we can process all keystrokes as data.
d8af5a
af7efe BOOL·
f17491 CDiskWizRandomDataPage::PreTranslateMessage(MSG *pMsg)·
37bb36 {
dd5ac8 ¤   if (pMsg->message == WM_KEYDOWN)
44c7a1 ¤   {
3605d5 ¤   ¤   ProcessChar(MapVirtualKey(pMsg->wParam, 2));
a8836c ¤   ¤   return TRUE;
8f9371 ¤   }
d9af5a
c3f5d8 ¤   return CPropertyPage::PreTranslateMessage(pMsg);
a3efe6 }
1daf5a
75af5a
b14d57 /////////////////////////////////////////////////////////
14deef // CDiskWizRandomDataPage public default message handlers
8d4d57 /////////////////////////////////////////////////////////
79af5a
abc57f // OnSetActive is called when this page is made active. We make sure the
4bfdfc // correct buttons are enabled/disabled.
1baf5a
4c7efe BOOL·
d7618f CDiskWizRandomDataPage::OnSetActive()·
0cbb36 {
27d3ad ¤   pgpAssertAddrValid(mParentDiskWiz, CDiskWizardSheet);
59af5a
bb371e ¤   if (mIsDoneCollecting)
4d8607 ¤   ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
240e24 ¤   else
a1923e ¤   ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK);
7faf5a
49bfaa ¤   return CPropertyPage::OnSetActive();
29efe6 }
2caf5a
ddaf5a
366c0e /////////////////////////////////////////////////////////////////////////////
b431a9 // CDiskWizRandomDataPage protected custom functions and non-default handlers
186c0e /////////////////////////////////////////////////////////////////////////////
aaaf5a
9d77a9 // ProcessChar is called when the user hits a key. We add entropy to the pool
ceb966 // if the key isn't too 'repetitive'.
48af5a
e7c823 void·
6a758a CDiskWizRandomDataPage::ProcessChar(PGPUInt8 nChar)·
c5bb36 {
9165fb ¤   static PGPBoolean¤  initedHistory¤  = FALSE;
4a6e0f ¤   PGPBoolean¤ ¤   ¤   isKeyOk;
c6e0fa ¤   static PGPUInt8¤¤   hist[4];
adae17 ¤   static PGPUInt32¤   histSize¤   ¤   = sizeof(hist);
fc5cd5 ¤   PGPUInt32¤  ¤   ¤   i, numTimes;
c2af5a
c43bf6 ¤   // Clear the history array if this is the first time.
79ae9e ¤   if (!initedHistory)
f3c7a1 ¤   {
e2ce0b ¤   ¤   for (i=0; i < histSize; i++)
305b34 ¤   ¤   {
8f7ba3 ¤   ¤   ¤   hist[i] = NULL;
6a0fe4 ¤   ¤   }
--4561 000e8378bb440110091 Page 3 of CDiskWizRandomDataPage.cpp
e0af5a
1691af ¤   ¤   initedHistory = TRUE;
ea9371 ¤   }
f5af5a
d39a25 ¤   // Calculate the frequency of appearence of the current keystroke.
77893b ¤   numTimes = 0;
84af5a
e4f363 ¤   for (i=0; i < histSize; i++)
2ac7a1 ¤   {
f94ff8 ¤   ¤   if (hist[i] == nChar)
dd0bcc ¤   ¤   ¤   numTimes++;
729371 ¤   }
4eaf5a
7e52dc ¤   // Has it appeared in more than 1/4 of last 'histSize' keystrokes?
6cb396 ¤   isKeyOk = (numTimes <= histSize/4);
2aaf5a
28dd27 ¤   // Update the history.
418f7e ¤   for (i=0; i < histSize-1; i++)
efc7a1 ¤   {
cae1a1 ¤   ¤   hist[i] = hist[i+1];
659371 ¤   }
d1af5a
8fb463 ¤   hist[histSize-1] = i;
a3af5a
80f794 ¤   // If it hasn't appeared too often, add the keystroke to the pool.
f5839b ¤   if (isKeyOk)
09c7a1 ¤   {
8ec389 ¤   ¤   mRandomPool.AddByte(nChar);
b0af5a
49ae1f ¤   ¤   if (++mProcessedDataCount >= mRequiredDataCount)
6f5b34 ¤   ¤   {
5e7652 ¤   ¤   ¤   mIsDoneCollecting = TRUE;
be8171 ¤   ¤   ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
300fe4 ¤   ¤   }
a01b52 ¤   ¤
a92355 ¤   ¤   mRandomDataBar.SetPos(mProcessedDataCount*100 / mRequiredDataCount);
599371 ¤   }
f4efe6 }
90af5a
83e51b // The CDiskWizRandomDataPage data exchange function.
edaf5a
48c823 void·
750204 CDiskWizRandomDataPage::DoDataExchange(CDataExchange *pDX)
e3bb36 {
b378f1 ¤   try
44c7a1 ¤   {
8022a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
44af5a
859cd7 ¤   ¤   //{{AFX_DATA_MAP(CDiskWizRandomDataPage)
eff698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
c7d201 ¤   ¤   DDX_Control(pDX, IDC_RANDOM_BAR, mRandomDataBar);
693376 ¤   ¤   //}}AFX_DATA_MAP
0d9371 ¤   }
503c88 ¤   catch (CMemoryException *ex)
f5c7a1 ¤   {
1e6adc ¤   ¤   ex->Delete();
d69371 ¤   }
11efe6 }
44af5a
9caf5a
a35ea1 ////////////////////////////////////////////////////////////
1c5b85 // CDiskWizRandomDataPage protected default message handlers
b95ea1 ////////////////////////////////////////////////////////////
17af5a
3b8cca // OnHelpInfo handles context-sensitive help.
2faf5a
5d7efe BOOL·
d006e6 CDiskWizRandomDataPage::OnHelpInfo(HELPINFO *pHelpInfo)
babb36 {
af29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
36e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
e8c7a1 ¤   {
--c769 000447be10740110091 Page 4 of CDiskWizRandomDataPage.cpp
41ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
716b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
d19371 ¤   }
b6af5a
e2c2e7 ¤   return TRUE;
01efe6 }
6eaf5a
8e360f // OnInitDialog is overwritten to perform property page initialization.
f3af5a
117efe BOOL·
aa551c CDiskWizRandomDataPage::OnInitDialog()·
f0bb36 {
024541 ¤   CPropertyPage::OnInitDialog();
27af5a
512b52 ¤   // This must be called first to make MFC happy.
0502a1 ¤   UpdateData(FALSE);
98af5a
4d574c ¤   // Initialize the entropy bar range and position.
531153 ¤   mRandomDataBar.SetRange(0, 100);
03d46a ¤   mRandomDataBar.SetPos(0);
a9af5a
0f02a1 ¤   UpdateData(FALSE);
8caf5a
63c2e7 ¤   return TRUE;
b9efe6 }
b5af5a
e5e2f1 // OnLButtonDown is overridden to provide a quick exit in debug mode.
73af5a
68c823 void·
b7f65a CDiskWizRandomDataPage::OnLButtonDown(UINT nFlags, CPoint point)·
11bb36 {
675c98 #if PGP_DEBUG
24ae29 ¤   mIsDoneCollecting = TRUE;
533899 ¤   mRandomDataBar.SetPos(100);
e90c42 ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
aa1e67 #endif¤ // PGP_DEBUG
6faf5a
a046a2 ¤   CPropertyPage::OnLButtonDown(nFlags, point);
05efe6 }
5baf5a
ba3b0a // OnMouseMove is called whenever the mouse moves within our window. We add
ff5a64 // another entry to the random pool.
54af5a
d0c823 void·
5f3400 CDiskWizRandomDataPage::OnMouseMove(UINT nFlags, CPoint point)·
6dbb36 {
8c6d06 ¤   if (!mIsDoneCollecting)
66c7a1 ¤   {
0d8e2f ¤   ¤   mRandomPool.AddMouseEntropy(point.x, point.y);
68af5a
82ae1f ¤   ¤   if (++mProcessedDataCount >= mRequiredDataCount)
e75b34 ¤   ¤   {
897652 ¤   ¤   ¤   mIsDoneCollecting = TRUE;
148171 ¤   ¤   ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
490fe4 ¤   ¤   }
261b52 ¤   ¤
282355 ¤   ¤   mRandomDataBar.SetPos(mProcessedDataCount*100 / mRequiredDataCount);
fb9371 ¤   }
95af5a
0ca844 ¤   CPropertyPage::OnMouseMove(nFlags, point);
6eefe6 }
6eaf5a
209c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
74af5a
9cc823 void·
948701 CDiskWizRandomDataPage::OnPaint()·
b8bb36 {
390575 ¤   CDC¤¤   ¤   memDC;
b0c943 ¤   CPaintDC¤   DC(this);
bae3a1 ¤   HBITMAP¤¤   oldBitmap;
7fb2e4 ¤   RECT¤   ¤   sidebarRect;
44af5a
--7574 0011e10d93d40110091 Page 5 of CDiskWizRandomDataPage.cpp
4ccf3b ¤   DC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
4ccf08 ¤   DC.RealizePalette();
5eaf5a
12ce55 ¤   memDC.CreateCompatibleDC(&DC);
1584cd ¤   memDC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
02bb83 ¤   memDC.RealizePalette();
ebaf5a
ee7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
397564 ¤   ScreenToClient(&sidebarRect);
3567c5 ¤
97e586 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so don't
a78f6e ¤   // fool with it.
05af5a
2b366b ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mParentDiskWiz->mSidebarBitmap);
c5af5a
e196b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
fceefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
bfaf5a
1aac4f ¤   memDC.SelectObject(oldBitmap);
2a63a9 ¤   memDC.DeleteDC();
1eefe6 }
--3b75 000a1d5f60240110092 Page 1 of CDiskWizRandomDataPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
774d33 // CDiskWizRandomDataPage.h
32465d //
57d326 // Declaration of class CDiskWizRandomDataPage.
be1bc3 //////////////////////////////////////////////////////////////////////////////
a7af5a
a79166 // $Id: CDiskWizRandomDataPage.h,v 1.1.2.6 1998/07/06 08:56:51 nryan Exp $
37af5a
90cbce // Copyright (C) 1998 by Network Associates, Inc.
d671ae // All rights reserved.
bbaf5a
1813a5 #ifndef Included_CDiskWizRandomDataPage_h¤  // [
24a0db #define Included_CDiskWizRandomDataPage_h
c0af5a
b83a85 #include "DualErr.h"
33b1e1 #include "PGPdiskRandomPool.h"
9faf5a
29ab81 #include "Resource.h"
62af5a
daaf5a
10d557 ////////
6402c9 // Types
e2d557 ////////
c1af5a
237725 class CDiskWizardSheet;
d6af5a
a8af5a
49c7c6 ///////////////////////////////
e31256 // Class CDiskWizRandomDataPage
c8c7c6 ///////////////////////////////
56af5a
a3b273 class CDiskWizRandomDataPage : public CPropertyPage
c3bb36 {
5317d5 ¤   DECLARE_DYNCREATE(CDiskWizRandomDataPage)
1faf5a
045ed4 public:
dbd540 ¤   CDiskWizardSheet¤   *mParentDiskWiz;¤   // pointer to parent sheet
72fb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
d13cf5 ¤   PGPBoolean¤ ¤   ¤   mIsDoneCollecting;¤ // got all we need?
eae51f ¤   PGPdiskRandomPool¤  mRandomPool;¤   ¤   // our pool for random data
93af5a
fd6599 ¤   CDiskWizRandomDataPage();
7bb90d ¤   ~CDiskWizRandomDataPage();
fcaf5a
12ef20 ¤   //{{AFX_DATA(CDiskWizRandomDataPage)
f0b02b ¤   enum { IDD = IDD_DISKWIZ_RANDOM };
4645be ¤   CStatic¤mSidebarGraphic;
f19fa6 ¤   CProgressCtrl¤  mRandomDataBar;
c04af0 ¤   CString¤mRandomMessage;
f35139 ¤   //}}AFX_DATA
b6af5a
0cf499 ¤   //{{AFX_VIRTUAL(CDiskWizRandomDataPage)
b167d4 ¤   public:
f66e36 ¤   virtual BOOL OnSetActive();
f8a0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
a2c369 ¤   protected:
d63e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
d4af53 ¤   //}}AFX_VIRTUAL
d0af5a
d7a2d3 protected:
3c7234 ¤   PGPUInt32¤  mRequiredDataCount;¤¤   // entropy still needed
469274 ¤   PGPUInt32¤  mProcessedDataCount;¤   // total entropy required
2baf5a
d17aae ¤   void ProcessChar(PGPUInt8 nChar);
5baf5a
9b2be9 ¤   //{{AFX_MSG(CDiskWizRandomDataPage)
1ef17a ¤   virtual BOOL OnInitDialog();
1a698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
600e54 ¤   afx_msg void OnMouseMove(UINT nFlags, CPoint point);
314322 ¤   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
41c5f3 ¤   afx_msg void OnPaint();
a12e09 ¤   //}}AFX_MSG
--afd9 0019c780eef40110092 Page 2 of CDiskWizRandomDataPage.h
e0af5a
352409 ¤   DECLARE_MESSAGE_MAP()
ab82f7 };
e9af5a
0bc18c //{{AFX_INSERT_LOCATION}}
feaf5a
9ce2c9 #endif¤ // ] Included_CDiskWizRandomDataPage_h
--7911 000014c9e9940110093 Page 1 of CDiskWizVolumeInfoPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
aa5413 // CDiskWizVolumeInfoPage.cpp
d9465d //
38a3fe // Implementation of class CDiskWizVolumeInfoPage.
1c1bc3 //////////////////////////////////////////////////////////////////////////////
f2af5a
f47120 // $Id: CDiskWizVolumeInfoPage.cpp,v 1.1.2.10.2.1 1998/10/08 18:44:11 nryan Exp¶
6fed4e ·$
81af5a
10cbce // Copyright (C) 1998 by Network Associates, Inc.
9271ae // All rights reserved.
9caf5a
ce9e12 #include "StdAfx.h"
0038ab #include <math.h>
09af5a
fc9bcf #include "Required.h"
d6993c #include "StringAssociation.h"
17bfe9 #include "UtilityFunctions.h"
80af5a
a422eb #include "CDiskWizardSheet.h"
cb43b7 #include "CDiskWizVolumeInfoPage.h"
3cf037 #include "File.h"
a7c411 #include "Globals.h"
4b4713 #include "PGPdiskHelpIds.h"
cdaf5a
09af5a
e86cc2 /////////////////////
ae3a71 // Context help array
2a6cc2 /////////////////////
c2af5a
f177bf static PGPUInt32 HelpIds[] =
f0bb36 {
dc815b ¤   IDC_SIZE_EDIT,¤ ¤   ¤   IDH_PGPDISKAPP_DISKWIZVOLSIZEEDIT,·
5a3d59 ¤   IDC_SIZE_SPIN,¤ ¤   ¤   IDH_PGPDISKAPP_DISKWIZVOLSIZESPIN,·
16eefb ¤   IDC_DRIVE_COMBO,¤   ¤   IDH_PGPDISKAPP_DISKWIZVOLDRIVECOMBO,·
6784f5 ¤   IDC_GB_CHECK,¤  ¤   ¤   IDH_PGPDISKAPP_DISKWIZVOLGBCHECK,·
c56b67 ¤   IDC_MB_CHECK,¤  ¤   ¤   IDH_PGPDISKAPP_DISKWIZVOLMBCHECK,·
2031e9 ¤   IDC_KB_CHECK,¤  ¤   ¤   IDH_PGPDISKAPP_DISKWIZVOLKBCHECK,·
a0d192 ····IDC_FREESIZE_TEXT,¤ ¤   ((PGPUInt32) -1),·
d8cec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
edce3c ¤   0,0·
9a82f7 };
d6af5a
2caf5a
2683f5 ///////////////////////////
2cb249 // MFC specific definitions
e883f5 ///////////////////////////
e6af5a
101201 BEGIN_MESSAGE_MAP(CDiskWizVolumeInfoPage, CPropertyPage)
7c0dc2 ¤   //{{AFX_MSG_MAP(CDiskWizVolumeInfoPage)
9bdb65 ¤   ON_WM_HELPINFO()
6a4cf1 ¤   ON_BN_CLICKED(IDC_KB_CHECK, OnKbCheck)
bf5b86 ¤   ON_BN_CLICKED(IDC_MB_CHECK, OnMbCheck)
062fa5 ¤   ON_WM_PAINT()
12621f ¤   ON_BN_CLICKED(IDC_GB_CHECK, OnGbCheck)
2e044a ¤   //}}AFX_MSG_MAP
17af28 END_MESSAGE_MAP()
2caf5a
8caf5a
994a2a //////////////////////////////////////////////////////////////////////////
8c125b // CDiskWizVolumeInfoPage public custom functions and non-default handlers
564a2a //////////////////////////////////////////////////////////////////////////
a0af5a
9d053e IMPLEMENT_DYNCREATE(CDiskWizVolumeInfoPage, CPropertyPage)
ddaf5a
2d6803 // The CDiskWizVolumeInfoPage default constructor.
6eaf5a
739453 CDiskWizVolumeInfoPage::CDiskWizVolumeInfoPage()
455235 ¤   ·: CPropertyPage(CDiskWizVolumeInfoPage::IDD)
4bbb36 {
acb856 ¤   //{{AFX_DATA_INIT(CDiskWizVolumeInfoPage)
0127aa ¤   mSizeValue = 0;
--a08a 000e976a6db40110093 Page 2 of CDiskWizVolumeInfoPage.cpp
0328b1 ¤   mFreeSizeText = _T("");
dcb1e8 ¤   //}}AFX_DATA_INIT
a0af5a
c53010 ¤   mParentDiskWiz = NULL;
51af5a
3e218f ¤   // Exorcise the big help button.
156a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
8befe6 }
e1af5a
35f2b2 // The CDiskWizVolumeInfoPage destructor.
26af5a
4b6a16 CDiskWizVolumeInfoPage::~CDiskWizVolumeInfoPage()
26bb36 {
11efe6 }
30af5a
c0af5a
b94d57 /////////////////////////////////////////////////////////
3615b9 // CDiskWizVolumeInfoPage public default message handlers
b44d57 /////////////////////////////////////////////////////////
b5af5a
f3c57f // OnSetActive is called when this page is made active. We make sure the
65fdfc // correct buttons are enabled/disabled.
c8af5a
eb7efe BOOL·
40d5a3 CDiskWizVolumeInfoPage::OnSetActive()·
ddbb36 {
12d3ad ¤   pgpAssertAddrValid(mParentDiskWiz, CDiskWizardSheet);
200c42 ¤   mParentDiskWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
7267c5 ¤
8bbfaa ¤   return CPropertyPage::OnSetActive();
daefe6 }
b6af5a
0d5d86 // OnWizardNext is called when the 'Next' button is pressed. We perform
1f022f // data validation.
82af5a
690218 LRESULT·
a0539a CDiskWizVolumeInfoPage::OnWizardNext()·
d0bb36 {
2678f1 ¤   try
fec7a1 ¤   {
e0bd78 ¤   ¤   PGPBoolean¤ failThis¤   = FALSE;
eb979f ¤   ¤   PGPUInt32¤  kbDisk;
8daf5a
11005d ¤   ¤   if (CPropertyPage::OnWizardNext() == -1)
c23fd5 ¤   ¤   ¤   return -1;
2caf5a
d53ab3 ¤   ¤   // Get the size value in kilobytes.
fad593 ¤   ¤   kbDisk = GetSizeValueInKb();
e6af5a
37d38b ¤   ¤   // Verify that the space being asked is not too big or small.
7872a3 ¤   ¤   if (kbDisk < mLocalMinKbSize)
9c5b34 ¤   ¤   {
6fbd13 ¤   ¤   ¤   failThis = TRUE;
b9b121 ¤   ¤   ¤   SetPGPdiskSize(mLocalMinKbSize);
e4af5a
51426f ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskTooSmall);
3c0fe4 ¤   ¤   }
3f025e ¤   ¤   else if (kbDisk > App->mPlatformMaxKbSize)
3b5b34 ¤   ¤   {
02bd13 ¤   ¤   ¤   failThis = TRUE;
3d370b ¤   ¤   ¤   SetPGPdiskSize(mLocalMaxKbSize);
72af5a
039e6f ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskTooBig);
f50fe4 ¤   ¤   }
590e81 ¤   ¤   else if (kbDisk > mLocalMaxKbSize)
b85b34 ¤   ¤   {
debd13 ¤   ¤   ¤   failThis = TRUE;
4e370b ¤   ¤   ¤   SetPGPdiskSize(mLocalMaxKbSize);
a8af5a
7a973c ¤   ¤   ¤   ReportError(kPGDMajorError_NotEnoughDiskSpace);
150fe4 ¤   ¤   }
e9af5a
--c56e 0007cb1259440110093 Page 3 of CDiskWizVolumeInfoPage.cpp
1928f6 ¤   ¤   // Handle special case where we can't be sure of the amount of free
9ef5bb ¤   ¤   // space on the host drive.
94af5a
df40d7 ¤   ¤   if (mAreWeFailingDiskFree && !failThis)
a75b34 ¤   ¤   {
962da3 ¤   ¤   ¤   CString¤¤   dir;
fe9d30 ¤   ¤   ¤   DualErr¤¤   dummyErr;
7ba47b ¤   ¤   ¤   PGPBoolean¤ isEnoughSpace;
97af5a
35f043 ¤   ¤   ¤   // Get the directory to test.
cc7ae8 ¤   ¤   ¤   dummyErr = GetDirectory(mParentDiskWiz->mPath, &dir);
76af5a
231ac8 ¤   ¤   ¤   // Test if there really is enough space available. If we can't
c08761 ¤   ¤   ¤   // tell then don't fail.
7caf5a
099a97 ¤   ¤   ¤   if (dummyErr.IsntError())
51f776 ¤   ¤   ¤   {
571266 ¤   ¤   ¤   ¤   dummyErr = App->BruteForceTestIfEnoughSpace(dir, kbDisk,·
c64d83 ¤   ¤   ¤   ¤   ¤   &isEnoughSpace);
8ca3a6 ¤   ¤   ¤   }
e5af5a
379a97 ¤   ¤   ¤   if (dummyErr.IsntError())
e1f776 ¤   ¤   ¤   {
85bda5 ¤   ¤   ¤   ¤   if (!isEnoughSpace)
3b72c3 ¤   ¤   ¤   ¤   {
753b2d ¤   ¤   ¤   ¤   ¤   failThis = TRUE;
6d6e4e ¤   ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_NotEnoughDiskSpace);
d62613 ¤   ¤   ¤   ¤   }
b9a3a6 ¤   ¤   ¤   }
070fe4 ¤   ¤   }
bfaf5a
b1aa4b ¤   ¤   if (failThis)
625b34 ¤   ¤   {
0ebbd6 ¤   ¤   ¤   CString text;
99af5a
10b32a ¤   ¤   ¤   // Point out the incorrect size entered by the user.
283218 ¤   ¤   ¤   mSizeEditBox.SetFocus();
2ca283 ¤   ¤   ¤   mSizeEditBox.GetWindowText(text);
bf93b8 ¤   ¤   ¤   mSizeEditBox.SetSel(0, text.GetLength(), FALSE);
b5af5a
ea3fd5 ¤   ¤   ¤   return -1;
670fe4 ¤   ¤   }
560e1d ¤   ¤   else
845b34 ¤   ¤   {
4a9933 ¤   ¤   ¤   // Remember disk size.
b3fc21 ¤   ¤   ¤   SetPGPdiskSizeInRegistry();
ceaf5a
559248 ¤   ¤   ¤   mBlocksDisk = ((PGPUInt64) kbDisk * kBytesPerKb) /·
92eb05 ¤   ¤   ¤   ¤   kDefaultBlockSize;
c6af5a
b78144 ¤   ¤   ¤   return 0;
fc0fe4 ¤   ¤   }
a29371 ¤   }
713c88 ¤   catch (CMemoryException *ex)
b9c7a1 ¤   {
ee6adc ¤   ¤   ex->Delete();
bebbde ¤   ¤   return 0;
359371 ¤   }
b0efe6 }
ebaf5a
c3af5a
c86c0e /////////////////////////////////////////////////////////////////////////////
141e9c // CDiskWizVolumeInfoPage protected custom functions and non-default handlers
8d6c0e /////////////////////////////////////////////////////////////////////////////
5daf5a
2457eb // ConvertControlsAux is a utility function for the 'ConvertControls'
913235 // functions.
b9af5a
7dc823 void·
8dea29 CDiskWizVolumeInfoPage::ConvertControlsAux(
c8f073 ¤   PGPUInt32¤  nMin,·
7c2268 ¤   PGPUInt32¤  nMax,·
--c816 000680baa4940110093 Page 4 of CDiskWizVolumeInfoPage.cpp
ae4ea0 ¤   PGPUInt32¤  kbPerUnit)
53bb36 {
617fc4 ¤   // If current size is out of range, change it.
78364d ¤   UpdateData(TRUE);
cbaf5a
4a94a8 ¤   if (mSizeValue < nMin)
c4c7a1 ¤   {
0cf3f0 ¤   ¤   mSizeValue = nMin;
df9371 ¤   }
b58d64 ¤   else if (mSizeValue > nMax)
fcc7a1 ¤   {
7c4564 ¤   ¤   mSizeValue = nMax;
fc9371 ¤   }
49af5a
d33669 ¤   // Set ranges of controls.
d7910e ¤   mSizeSpin.SetRange(nMin, nMax);
f1af5a
0002a1 ¤   UpdateData(FALSE);
9befe6 }
79af5a
70496f // ConvertControlsToKb converts the dialog's controls to KB.
7eaf5a
0ac823 void·
247c5d CDiskWizVolumeInfoPage::ConvertControlsToKb()
2dbb36 {
ee225f ¤   mSizeScale = kLCS_KbScale;
d6af5a
8b6a59 ¤   mKbButton.SetCheck(1);
71991f ¤   mMbButton.SetCheck(0);
d3a109 ¤   mGbButton.SetCheck(0);
b5af5a
eefc78 ¤   ConvertControlsAux(mLocalMinKbSize, min(kKbPerMeg*2, mLocalMaxKbSize), 1);
8cefe6 }
2aaf5a
465c34 // ConvertControlsToMb converts the dialog's controls to MB.
85af5a
7ac823 void·
fa47c5 CDiskWizVolumeInfoPage::ConvertControlsToMb()
fabb36 {
6f8640 ¤   mSizeScale = kLCS_MbScale;
b1af5a
9e76e2 ¤   mKbButton.SetCheck(0);
a585a4 ¤   mMbButton.SetCheck(1);
15a109 ¤   mGbButton.SetCheck(0);
bbaf5a
0532c0 ¤   ConvertControlsAux(1, min(kMbPerGig*2, mLocalMaxKbSize/kKbPerMeg),·
5031b4 ¤   ¤   kKbPerMeg);
5eefe6 }
93af5a
b763d9 // ConvertControlsToGb converts the dialog's controls to GB.
31af5a
8ac823 void·
b40b6d CDiskWizVolumeInfoPage::ConvertControlsToGb()
83bb36 {
706270 ¤   mSizeScale = kLCS_GbScale;
c3af5a
2976e2 ¤   mKbButton.SetCheck(0);
97991f ¤   mMbButton.SetCheck(0);
43bdb2 ¤   mGbButton.SetCheck(1);
7daf5a
c98028 ¤   ConvertControlsAux(1, mLocalMaxKbSize/kKbPerGig, kKbPerGig);
cdefe6 }
f4af5a
38a358 // GetSizeValueInKb returns the current size entered in KB.
b9af5a
481b0b PGPUInt32·
e135b7 CDiskWizVolumeInfoPage::GetSizeValueInKb()
adbb36 {
e5364d ¤   UpdateData(TRUE);
e6af5a
6330fb ¤   switch (mSizeScale)
68c7a1 ¤   {
--70b9 000f1f3c3f440110093 Page 5 of CDiskWizVolumeInfoPage.cpp
36b187 ¤   case kLCS_KbScale:
ac9131 ¤   ¤   return mSizeValue;
24af5a
8b1598 ¤   case kLCS_MbScale:
6d9173 ¤   ¤   return mSizeValue*kKbPerMeg;
d0af5a
96f1a8 ¤   case kLCS_GbScale:
974aef ¤   ¤   return mSizeValue*kKbPerGig;
5eaf5a
f22f72 ¤   default:
f68f52 ¤   ¤   pgpAssert(FALSE);
e7bbde ¤   ¤   return 0;
e89371 ¤   }
14efe6 }
a7af5a
7f1822 // SetPGPdiskSize sets the size edit box and the slider to the given size.
19af5a
02c823 void·
17c302 CDiskWizVolumeInfoPage::SetPGPdiskSize(
affd13 ¤   PGPUInt32¤  ¤   ¤   kbSize,·
f591cc ¤   PGPdiskCreateScale¤ scale)
ffbb36 {
34b71c ¤   if (scale == kLCS_InvalidScale)
f4597a ¤   ¤   scale = mSizeScale;
afaf5a
8eb806 ¤   // Set size to legal value.
9a42f1 ¤   if (kbSize < mLocalMinKbSize)
d6c7a1 ¤   {
b16c9e ¤   ¤   kbSize = mLocalMinKbSize;
7e9371 ¤   }
71dfec ¤   else if (kbSize > mLocalMaxKbSize)
89c7a1 ¤   {
a65e3c ¤   ¤   kbSize = mLocalMaxKbSize;
9d9371 ¤   }
57af5a
5e647e ¤   // What scale do we use?
41447e ¤   switch (scale)
49c7a1 ¤   {
fbb187 ¤   case kLCS_KbScale:
4aaf5a
6b32de ¤   ¤   mSizeValue = kbSize;
c0e040 ¤   ¤   UpdateData(FALSE);
51e9c7 ¤   ¤   ConvertControlsToKb();
402f68 ¤   ¤   break;
a7af5a
9e1598 ¤   case kLCS_MbScale:
87af5a
76065d ¤   ¤   mSizeValue = kbSize/kKbPerMeg;
12e040 ¤   ¤   UpdateData(FALSE);
08f13d ¤   ¤   ConvertControlsToMb();
362f68 ¤   ¤   break;
ffaf5a
6af1a8 ¤   case kLCS_GbScale:
30af5a
59ddc1 ¤   ¤   mSizeValue = kbSize/kKbPerGig;
5ae040 ¤   ¤   UpdateData(FALSE);
0fd833 ¤   ¤   ConvertControlsToGb();
d32f68 ¤   ¤   break;
66af5a
1c2f72 ¤   default:
d08f52 ¤   ¤   pgpAssert(FALSE);
df2f68 ¤   ¤   break;
2a9371 ¤   }
82efe6 }
d3af5a
ce7144 // GetPGPdiskSizeFromRegistry initializes the size from the value we
d037f6 // previously stored in the registry.
15af5a
fdc823 void·
c834ae CDiskWizVolumeInfoPage::GetPGPdiskSizeFromRegistry()
88bb36 {
f1530b ¤   PGPdiskCreateScale¤ createScale;
--7ceb 000453a74a040110093 Page 6 of CDiskWizVolumeInfoPage.cpp
9d7aa7 ¤   PGPUInt32¤  ¤   ¤   kbSize;
70af5a
090a4e ¤   kbSize = PGPdiskGetPrefDWord(kRegistryLastCreateSizeKey,·
d8f9d7 ¤   ¤   kInvalidRegDWordValue);
65af5a
923f9b ¤   if (kbSize == kInvalidRegDWordValue)
4270ed ¤   ¤   kbSize = kDefaultPGPdiskMbSize * kKbPerMeg;
5eaf5a
2f0f8b ¤   createScale = (PGPdiskCreateScale)·
92479f ¤   ¤   PGPdiskGetPrefDWord(kRegistryLastCreateScaleKey, kLCS_MbScale);
25af5a
0510a5 ¤   SetPGPdiskSize(kbSize, createScale);
0defe6 }
37af5a
4f4236 // SetPGPdiskSizeInRegistry stores the current PGPdisk size in the registry.
e9af5a
5b2292 DualErr·
3725cb CDiskWizVolumeInfoPage::SetPGPdiskSizeInRegistry()
53bb36 {
b17d36 ¤   DualErr derr;
63af5a
1e54e0 ¤   derr = PGPdiskSetPrefDWord(kRegistryLastCreateSizeKey,·
c24d85 ¤   ¤   GetSizeValueInKb());
fbaf5a
e52361 ¤   if (derr.IsntError())
c2c7a1 ¤   {
22528c ¤   ¤   derr = PGPdiskSetPrefDWord(kRegistryLastCreateScaleKey,·
68882e ¤   ¤   ¤   (PGPUInt32) mSizeScale);
839371 ¤   }
7daf5a
7933e3 ¤   return derr;
a4efe6 }
b0af5a
3257a8 // The CDiskWizVolumeInfoPage data exchange function.
5aaf5a
98c823 void·
a8bfb4 CDiskWizVolumeInfoPage::DoDataExchange(CDataExchange *pDX)
30bb36 {
4478f1 ¤   try
44c7a1 ¤   {
3bbb57 ¤   ¤   CString¤¤   text;
440195 ¤   ¤   PGPBoolean¤ skipDDX¤= FALSE;
5eaf5a
8d22a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
a3af5a
f7b22c ¤   ¤   // Our goal is to coax MFC into accepting NULL fields for our size
0a17a0 ¤   ¤   // box.
75af5a
fa427b ¤   ¤   if (mSizeEditBox.GetSafeHwnd())
4fa283 ¤   ¤   ¤   mSizeEditBox.GetWindowText(text);
1aaf5a
1088e2 ¤   ¤   // Don't overwrite a null field with a 0.
0bbd81 ¤   ¤   if (!pDX->m_bSaveAndValidate && text.IsEmpty() && (mSizeValue == 0))
335b34 ¤   ¤   {
9ffb03 ¤   ¤   ¤   skipDDX = TRUE;
1a0fe4 ¤   ¤   }
b2af5a
f83962 ¤   ¤   // Note the way the second 'if' statement ends within the
42914a ¤   ¤   // AFX_DATA_MAP. This is done so our variable will still appear in
26b585 ¤   ¤   // the ClassWizard, but allows us to skip the DDX_Text when we want
a27157 ¤   ¤   // to.
c9af5a
619a07 ¤   ¤   if (pDX->m_bSaveAndValidate && text.IsEmpty())
2b5b34 ¤   ¤   {
30fb03 ¤   ¤   ¤   skipDDX = TRUE;
9cab3b ¤   ¤   ¤   mSizeValue = 0;
230fe4 ¤   ¤   }
6caf5a
9513d0 ¤   ¤   if (!skipDDX)¤  ¤
0ef41e ¤   ¤   //{{AFX_DATA_MAP(CDiskWizVolumeInfoPage)
03d420 ¤   ¤   ¤   DDX_Text(pDX, IDC_SIZE_EDIT, mSizeValue);
459a27 ¤   ¤   DDX_Control(pDX, IDC_DRIVE_COMBO, mDriveCombo);
--4a1f 000b135497140110093 Page 7 of CDiskWizVolumeInfoPage.cpp
f8f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
d43dfb ¤   ¤   DDX_Control(pDX, IDC_SIZE_SPIN, mSizeSpin);
3f23d5 ¤   ¤   DDX_Control(pDX, IDC_SIZE_EDIT, mSizeEditBox);
3c191f ¤   ¤   DDX_Text(pDX, IDC_FREESIZE_TEXT, mFreeSizeText);
a23376 ¤   ¤   //}}AFX_DATA_MAP
f89371 ¤   }
523c88 ¤   catch (CMemoryException *ex)
d8c7a1 ¤   {
b26adc ¤   ¤   ex->Delete();
6e9371 ¤   }
71efe6 }
c0af5a
96334e // OnKbCheck is called when the kB button is clicked.
14af5a
56c823 void·
20e1ff CDiskWizVolumeInfoPage::OnKbCheck()·
b2bb36 {
4d85b1 ¤   ConvertControlsToKb();¤
1cefe6 }
86af5a
778514 // OnMbCheck is called when the MB button is clicked.
4faf5a
e6c823 void·
511488 CDiskWizVolumeInfoPage::OnMbCheck()·
aabb36 {
09dd7c ¤   ConvertControlsToMb();¤
1cefe6 }
cfaf5a
b9bd02 // OnMbCheck is called when the GB button is clicked.
0aaf5a
56c823 void·
c30300 CDiskWizVolumeInfoPage::OnGbCheck()·
15bb36 {
2e342b ¤   ConvertControlsToGb();¤
51efe6 }
dcaf5a
94af5a
345ea1 ////////////////////////////////////////////////////////////
9a20bd // CDiskWizVolumeInfoPage protected default message handlers
2a5ea1 ////////////////////////////////////////////////////////////
f9af5a
c08cca // OnHelpInfo handles context-sensitive help.
1caf5a
157efe BOOL·
2b319e CDiskWizVolumeInfoPage::OnHelpInfo(HELPINFO *pHelpInfo)
afbb36 {
2029b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
7ae5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
f5c7a1 ¤   {
04ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
976b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
1d9371 ¤   }
c3af5a
64c2e7 ¤   return TRUE;
0eefe6 }
a4af5a
b0360f // OnInitDialog is overwritten to perform property page initialization.
88af5a
1a7efe BOOL·
acbec6 CDiskWizVolumeInfoPage::OnInitDialog()·
efbb36 {
f4236c ¤   DualErr¤¤   dummyErr;
c3e9e0 ¤   File¤   ¤   existingFile;
dd726d ¤   PGPUInt64¤  bytesFile, bytesFree;
6caf5a
584541 ¤   CPropertyPage::OnInitDialog();
2eaf5a
062b52 ¤   // This must be called first to make MFC happy.
a702a1 ¤   UpdateData(FALSE);
66af5a
911856 ¤   // Classwizard won't subclasss our radio buttons (sniff).
b113fd ¤   mKbButton.SubclassWindow(GetDlgItem(IDC_KB_CHECK)->GetSafeHwnd());
--dd96 0004c22a55a40110093 Page 8 of CDiskWizVolumeInfoPage.cpp
922cbc ¤   mMbButton.SubclassWindow(GetDlgItem(IDC_MB_CHECK)->GetSafeHwnd());
816d7f ¤   mGbButton.SubclassWindow(GetDlgItem(IDC_GB_CHECK)->GetSafeHwnd());
7daf5a
4cc4ca ¤   // Any drive letters free?
e23cc3 ¤   if (!App->AreAnyDriveLettersFree())
19c7a1 ¤   {
5d5d53 ¤   ¤   mParentDiskWiz->mDerr =·
234579 ¤   ¤   ¤   DualErr(kPGDMinorError_NoDriveLettersFree);
39e553 ¤   ¤   mParentDiskWiz->PressButton(PSBTN_CANCEL);¤ // NOT EndDialog (bug)
8baf5a
8198aa ¤   ¤   return FALSE;
0e9371 ¤   }
e8af5a
9d78af ¤   // Initialize the combo box.
6a9d6e ¤   mDriveCombo.InitDriveLetters();
19af5a
cb1f4a ¤   // How much space do we have available?
4f0001 ¤   dummyErr = App->HowMuchFreeSpace(mParentDiskWiz->mPath, &bytesFree);
08af5a
f1219e ¤   // Don't fail if the disk free call fails, but make note of it.
2842ec ¤   if (dummyErr.IsntError())
f3c7a1 ¤   {
6aba98 ¤   ¤   mAreWeFailingDiskFree = FALSE;
d3a13c ¤   ¤   mKbFree = (PGPUInt32) (bytesFree / kBytesPerKb) - 10;
a69371 ¤   }
0a0e24 ¤   else
21c7a1 ¤   {
f6ab7f ¤   ¤   mAreWeFailingDiskFree = TRUE;
081054 ¤   ¤   mKbFree = App->mPlatformMaxKbSize*2;¤   // fake max amount of space
669371 ¤   }
9eaf5a
9c73d8 ¤   // If the pathname contains the name of an existing file, the user wants
3925fc ¤   // to replace it, so add its size to the amount of free space.
b7af5a
8d58d3 ¤   dummyErr = existingFile.Open(mParentDiskWiz->mPath,·
72f22e ¤   ¤   kOF_MustExist | kOF_ReadOnly);
91af5a
2d42ec ¤   if (dummyErr.IsntError())
49c7a1 ¤   {
c13058 ¤   ¤   existingFile.GetLength(&bytesFile);
d49371 ¤   }
95af5a
d142ec ¤   if (dummyErr.IsntError())
55c7a1 ¤   {
269b7a ¤   ¤   mKbFree += (PGPUInt32) (bytesFile/kBytesPerKb);
c59371 ¤   }
34af5a
7712c1 ¤   if (existingFile.Opened())
4c1af7 ¤   ¤   existingFile.Close();
97af5a
9d8093 ¤   // Calculate max and min PGPdisk sizes we can create.
f841f2 ¤   mLocalMaxKbSize¤= min(mKbFree, App->mPlatformMaxKbSize);
6f3fab ¤   mLocalMinKbSize¤= min(mKbFree, App->mPlatformMinKbSize);
71af5a
6f7520 ¤   // If max size is less than one meg, disable the Mb button.
5f043f ¤   if (mLocalMaxKbSize < kKbPerMeg)
84f633 ¤   ¤   mMbButton.EnableWindow(FALSE);
faaf5a
8f7540 ¤   // If max size is less than one gig, disable the Gb button.
cbdfa3 ¤   if (mLocalMaxKbSize < kKbPerGig)
95b85c ¤   ¤   mGbButton.EnableWindow(FALSE);
1daf5a
45bd7c ¤   pgpAssert(mLocalMaxKbSize >= mLocalMinKbSize);
f2af5a
32bffa ¤   // Set PGPdisk size to what we remember it as in the registry.
1fc571 ¤   GetPGPdiskSizeFromRegistry();
a1af5a
1478f1 ¤   try
8cc7a1 ¤   {
bac2ea ¤   ¤   CString freeSpaceStr, maxPGPdiskStr;
2aaf5a
4c359b ¤   ¤   FormatSizeString(mKbFree, freeSpaceStr.GetBuffer(kMaxStringSize),·
--5d69 00127cd776240110093 Page 9 of CDiskWizVolumeInfoPage.cpp
d140e7 ¤   ¤   ¤   kMaxStringSize);
19af5a
0038ce ¤   ¤   freeSpaceStr.ReleaseBuffer();
65af5a
4637aa ¤   ¤   FormatSizeString(mLocalMaxKbSize,·
b46507 ¤   ¤   ¤   maxPGPdiskStr.GetBuffer(kMaxStringSize), kMaxStringSize);
83af5a
11f7b8 ¤   ¤   maxPGPdiskStr.ReleaseBuffer();
b8d83c ·
44b312 ¤   ¤   // Update the contents of the free size message shown to the user.
3adffa ¤   ¤   if (mAreWeFailingDiskFree)
2a5b34 ¤   ¤   {
d8fbf0 ¤   ¤   ¤   mFreeSizeText.Format(GetCommonString(kPGPdiskFreeSize3MsgString),·
8f473d ¤   ¤   ¤   ¤   maxPGPdiskStr);
330fe4 ¤   ¤   }
522d34 ¤   ¤   else if (mLocalMaxKbSize == App->mPlatformMaxKbSize)
185b34 ¤   ¤   {
6f851a ¤   ¤   ¤   mFreeSizeText.Format(GetCommonString(kPGPdiskFreeSize2MsgString),·
edb609 ¤   ¤   ¤   ¤   freeSpaceStr, maxPGPdiskStr);
dd0fe4 ¤   ¤   }
3a0e1d ¤   ¤   else
fc5b34 ¤   ¤   {
ae0624 ¤   ¤   ¤   mFreeSizeText.Format(GetCommonString(kPGPdiskFreeSize1MsgString),·
e8fc4b ¤   ¤   ¤   ¤   freeSpaceStr);
090fe4 ¤   ¤   }
cd9371 ¤   }
de3c88 ¤   catch (CMemoryException *ex)
9fc7a1 ¤   {
516adc ¤   ¤   ex->Delete();
b39371 ¤   }
7eaf5a
2d02a1 ¤   UpdateData(FALSE);
86af5a
49c2e7 ¤   return TRUE;
14efe6 }
f4af5a
189c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
acaf5a
fec823 void·
2da5c3 CDiskWizVolumeInfoPage::OnPaint()·
2dbb36 {
060575 ¤   CDC¤¤   ¤   memDC;
c9c943 ¤   CPaintDC¤   DC(this);
4ce3a1 ¤   HBITMAP¤¤   oldBitmap;
26b2e4 ¤   RECT¤   ¤   sidebarRect;
a6af5a
78cf3b ¤   DC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
6ecf08 ¤   DC.RealizePalette();
f7af5a
b5ce55 ¤   memDC.CreateCompatibleDC(&DC);
a684cd ¤   memDC.SelectPalette(&mParentDiskWiz->mSidebarPalette, FALSE);
f5bb83 ¤   memDC.RealizePalette();
d0af5a
8e7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
7a7564 ¤   ScreenToClient(&sidebarRect);
c967c5 ¤
67e586 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so don't
fb8f6e ¤   // fool with it.
73af5a
f0366b ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mParentDiskWiz->mSidebarBitmap);
4daf5a
5796b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
e8eefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
07af5a
a1ac4f ¤   memDC.SelectObject(oldBitmap);
8c63a9 ¤   memDC.DeleteDC();
27efe6 }
--7168 0003a61efce40110094 Page 1 of CDiskWizVolumeInfoPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
bc1696 // CDiskWizVolumeInfoPage.h
17465d //
8abbef // Declaration of class CDiskWizVolumeInfoPage.
741bc3 //////////////////////////////////////////////////////////////////////////////
c7af5a
37ccee // $Id: CDiskWizVolumeInfoPage.h,v 1.1.2.8 1998/07/31 21:36:47 nryan Exp $
4eaf5a
5dcbce // Copyright (C) 1998 by Network Associates, Inc.
8971ae // All rights reserved.
c8af5a
4f6bdc #ifndef Included_CDiskWizVolumeInfoPage_h¤  // [
58fb7e #define Included_CDiskWizVolumeInfoPage_h
4faf5a
ffbabe #include "PGPdiskRegistry.h"
5eaf5a
83572c #include "CDriveLetterCombo.h"
26ab81 #include "Resource.h"
39af5a
12af5a
dcd557 ////////
c802c9 // Types
9dd557 ////////
c8af5a
0d7725 class CDiskWizardSheet;
70af5a
ecaf5a
46c7c6 ///////////////////////////////
d9858d // Class CDiskWizVolumeInfoPage
0ac7c6 ///////////////////////////////
96af5a
b0b2b4 class CDiskWizVolumeInfoPage : public CPropertyPage
afbb36 {
757f1c ¤   DECLARE_DYNCREATE(CDiskWizVolumeInfoPage)
3aaf5a
035ed4 public:
4cd540 ¤   CDiskWizardSheet¤   *mParentDiskWiz;¤   // pointer to parent sheet
632c3c ¤   PGPUInt64¤  ¤   ¤   mBlocksDisk;¤   ¤   // user wants disk this big
efaf5a
739765 ¤   CDiskWizVolumeInfoPage();
114bf1 ¤   ~CDiskWizVolumeInfoPage();
75af5a
4987e9 ¤   //{{AFX_DATA(CDiskWizVolumeInfoPage)
d29641 ¤   enum { IDD = IDD_DISKWIZ_VOLINFO };
197914 ¤   CDriveLetterCombo¤  mDriveCombo;
d345be ¤   CStatic¤mSidebarGraphic;
d72f4a ¤   CSpinButtonCtrl¤mSizeSpin;
1f0da3 ¤   CEdit¤  mSizeEditBox;
8d6c10 ¤   UINT¤   mSizeValue;
c1db9e ¤   CString¤mFreeSizeText;
ae5139 ¤   //}}AFX_DATA
89af5a
ee9c50 ¤   //{{AFX_VIRTUAL(CDiskWizVolumeInfoPage)
0b67d4 ¤   public:
1f6e36 ¤   virtual BOOL OnSetActive();
b8a2ce ¤   virtual LRESULT OnWizardNext();
bcc369 ¤   protected:
0e3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
0daf53 ¤   //}}AFX_VIRTUAL
f4af5a
00a2d3 protected:
71bb19 ¤   CButton¤¤   ¤   ¤   mKbButton;¤ ¤   ¤   // KB radio button
3161c9 ¤   CButton¤¤   ¤   ¤   mMbButton;¤ ¤   ¤   // MB radio button
0d06a8 ¤   CButton¤¤   ¤   ¤   mGbButton;¤ ¤   ¤   // GB radio button
64af5a
7a38b7 ¤   PGPUInt32¤  ¤   ¤   mLocalMaxKbSize;¤   // max size PGPdisk we can make
e675c5 ¤   PGPUInt32¤  ¤   ¤   mLocalMinKbSize;¤   // min size PGPdisk we can make
fd2d9b ¤   PGPUInt32¤  ¤   ¤   mKbFree;¤   ¤   ¤   // KB free on PGPdisk host
a9af5a
eef077 ¤   PGPBoolean¤ ¤   ¤   mAreWeFailingDiskFree;¤ // disk free calls failing?
d4250c ¤   PGPdiskCreateScale¤ mSizeScale;¤¤   ¤   // scale of displayed size
3aaf5a
--977e 001fa94180840110094 Page 2 of CDiskWizVolumeInfoPage.h
ab5dfe ¤   void¤   ¤   ConvertControlsAux(PGPUInt32 nMin, PGPUInt32 nMax,·
673b6f ¤   ¤   ¤   ¤   ¤   PGPUInt32 kbPerUnit);
deaf5a
33ccbd ¤   void¤   ¤   ConvertControlsToKb();
35d447 ¤   void¤   ¤   ConvertControlsToMb();
cbfd49 ¤   void¤   ¤   ConvertControlsToGb();
eeaf5a
9685f1 ¤   PGPUInt32¤  GetSizeValueInKb();
7ccf17 ¤   void¤   ¤   SetPGPdiskSize(PGPUInt32 kbSize,·
0269f4 ¤   ¤   ¤   ¤   ¤   PGPdiskCreateScale scale = kLCS_InvalidScale);
b0af5a
2843fe ¤   void¤   ¤   GetPGPdiskSizeFromRegistry();
83cb9e ¤   DualErr¤¤   SetPGPdiskSizeInRegistry();
51af5a
104320 ¤   //{{AFX_MSG(CDiskWizVolumeInfoPage)
a3f17a ¤   virtual BOOL OnInitDialog();
db698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
26ab6d ¤   afx_msg void OnKbCheck();
f25e1a ¤   afx_msg void OnMbCheck();
cbc5f3 ¤   afx_msg void OnPaint();
034992 ¤   afx_msg void OnGbCheck();
8d2e09 ¤   //}}AFX_MSG
74af5a
842409 ¤   DECLARE_MESSAGE_MAP()
4882f7 };
4aaf5a
fec18c //{{AFX_INSERT_LOCATION}}
b7af5a
fab96c #endif¤ // ] Included_CDiskWizVolumeInfoPage_h
--9c46 000650d3f3540110095 Page 1 of CDiskWizardSheet.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
fc865c // CDiskWizardSheet.cpp
75465d //
6957e5 // Implementation of class CDiskWizardSheet.
941bc3 //////////////////////////////////////////////////////////////////////////////
4aaf5a
262ec2 // $Id: CDiskWizardSheet.cpp,v 1.2.2.22.2.3 1998/10/21 01:35:16 nryan Exp $
67af5a
25cbce // Copyright (C) 1998 by Network Associates, Inc.
1371ae // All rights reserved.
e8af5a
3f9e12 #include "StdAfx.h"
16af5a
bb9bcf #include "Required.h"
72993c #include "StringAssociation.h"
c9af5a
b43646 #include "CMainDialog.h"
7522eb #include "CDiskWizardSheet.h"
09c411 #include "Globals.h"
134713 #include "PGPdiskHelpIds.h"
66af5a
28af5a
f46cc2 /////////////////////
263a71 // Context help array
c46cc2 /////////////////////
48af5a
9277bf static PGPUInt32 HelpIds[] =
0abb36 {
af8515 ¤   IDCANCEL,¤  ¤   IDH_PGPDISKAPP_DISKWIZSHEETCANCEL,·
d76cf9 ¤   ID_WIZBACK,¤¤   IDH_PGPDISKAPP_DISKWIZSHEETBACK,·
00d0c1 ¤   ID_WIZNEXT,¤¤   IDH_PGPDISKAPP_DISKWIZSHEETNEXT,·
870232 ¤   ID_WIZFINISH,¤  IDH_PGPDISKAPP_DISKWIZSHEETFINISH,·
3d4434 ····0,0·
9c82f7 };
ffaf5a
60af5a
9583f5 ///////////////////////////
98b249 // MFC specific definitions
8183f5 ///////////////////////////
e3af5a
8c71d6 BEGIN_MESSAGE_MAP(CDiskWizardSheet, CPropertySheet)
e62cee ¤   //{{AFX_MSG_MAP(CDiskWizardSheet)
7bdb65 ¤   ON_WM_HELPINFO()
129e4e ¤   ON_BN_CLICKED(IDHELP, OnHelp)
abdfd1 ¤   ON_WM_SYSCOMMAND()
4f044a ¤   //}}AFX_MSG_MAP
ebaf28 END_MESSAGE_MAP()
4baf5a
84af5a
943924 ////////////////////////////////////////////////////////////////////
acaf5a // CDiskWizardSheet public custom functions and non-default handlers
7d3924 ////////////////////////////////////////////////////////////////////
95af5a
4cd4b7 IMPLEMENT_DYNAMIC(CDiskWizardSheet, CPropertySheet)
edaf5a
b88c68 // The CDiskWizardSheet constructor adds the wizard pages we implement
e14370 // to the wizard sheet.
56af5a
91006d CDiskWizardSheet::CDiskWizardSheet()
54af5a
ad3bf5 ¤   : CPropertySheet(GetCommonString(kPGPdiskDiskWizSheetTitleString), NULL,·
eefe2d ¤   ¤   0)
dfbb36 {
ff78f1 ¤   try
f9c7a1 ¤   {
0acbf9 ¤   ¤   // Did our pages initialize correctly?
b6332d ¤   ¤   mInitErr = mPassphrasePage.mInitErr;
9eaf5a
d6ab3a ¤   ¤   if (mInitErr.IsntError())
965b34 ¤   ¤   {
3daa2d ¤   ¤   ¤   mInitErr = mRandomDataPage.mInitErr;
650fe4 ¤   ¤   }
--2167 000d01ef3fd40110095 Page 2 of CDiskWizardSheet.cpp
e0af5a
13ab3a ¤   ¤   if (mInitErr.IsntError())
a95b34 ¤   ¤   {
2ed019 ¤   ¤   ¤   mInitErr = mCreationPage.mInitErr;
b00fe4 ¤   ¤   }
75af5a
77ab3a ¤   ¤   if (mInitErr.IsntError())
025b34 ¤   ¤   {
1c43c2 ¤   ¤   ¤   mCreationPage.mParentDiskWiz¤   = this;
10b281 ¤   ¤   ¤   mDonePage.mParentDiskWiz¤   ¤   = this;
f18946 ¤   ¤   ¤   mIntroPage.mParentDiskWiz¤  ¤   = this;
07777d ¤   ¤   ¤   mPassphrasePage.mParentDiskWiz¤ = this;
4aa7b3 ¤   ¤   ¤   mADKPage.mParentDiskWiz¤¤   ¤   = this;
d9c328 ¤   ¤   ¤   mRandomDataPage.mParentDiskWiz¤ = this;
71719b ¤   ¤   ¤   mVolumeInfoPage.mParentDiskWiz¤ = this;
7daf5a
52a0fa ¤   ¤   ¤   AddPage(&mIntroPage);
25f8c4 ¤   ¤   ¤   AddPage(&mVolumeInfoPage);
7cc076 ¤   ¤   ¤   AddPage(&mPassphrasePage);
db9377 ¤   ¤   ¤   AddPage(&mADKPage);
a5a361 ¤   ¤   ¤   AddPage(&mRandomDataPage);
90a7e8 ¤   ¤   ¤   AddPage(&mCreationPage);
fbb431 ¤   ¤   ¤   AddPage(&mDonePage);
56af5a
0922da ¤   ¤   ¤   // Exorcise the big help button.
6d66e8 ¤   ¤   ¤   m_psh.dwFlags &= ~PSH_HASHELP;
4f0fe4 ¤   ¤   }
a99371 ¤   }
943c88 ¤   catch (CMemoryException *ex)
91c7a1 ¤   {
bd9a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
926adc ¤   ¤   ex->Delete();
229371 ¤   }
3defe6 }
2aaf5a
12acca // The CDiskWizardSheet destructor.
8aaf5a
b03fd5 CDiskWizardSheet::~CDiskWizardSheet()
a7bb36 {
02efe6 }
a4af5a
bbb084 // ExecuteWizard displays the wizard and creates the PGPdisk after asking the
932427 // user for input.
bbaf5a
542292 DualErr·
b74292 CDiskWizardSheet::ExecuteWizard(LPCSTR path)
d4bb36 {
4e7d36 ¤   DualErr derr;
8baf5a
4b78f1 ¤   try
8bc7a1 ¤   {
149214 ¤   ¤   PGPdisk¤¤   *pPGD;
2a157c ¤   ¤   PGPInt32¤   result;
41af5a
0dd8c9 ¤   ¤   pgpAssertStrValid(path);
2ad5dc ¤   ¤   mPath = path;
deaf5a
4bef17 ¤   ¤   SetWizardMode();
f4af5a
6113a9 ¤   ¤   // Invoke the wizard.
21fcae ¤   ¤   result = DoModal();
6baf5a
26b507 ¤   ¤   switch (result)
df5b34 ¤   ¤   {
9856e8 ¤   ¤   case -1:
8f39a7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
f1cdcb ¤   ¤   ¤   break;
63af5a
7871eb ¤   ¤   case IDCANCEL:
81af5a
7e9d29 ¤   ¤   ¤   derr = mDerr;
d0af5a
--852c 0003ca3a22140110095 Page 3 of CDiskWizardSheet.cpp
729d3d ¤   ¤   ¤   if (derr.IsntError())
1b95a9 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
38af5a
bbcdcb ¤   ¤   ¤   break;
43af5a
1b9ae3 ¤   ¤   default:
d09d29 ¤   ¤   ¤   derr = mDerr;
8bcdcb ¤   ¤   ¤   break;
d30fe4 ¤   ¤   }
91af5a
154081 ¤   ¤   // If the PGPdisk was created and mounted successfully, format it and
731ed0 ¤   ¤   // show it in an Explorer window.
6daf5a
fbaa35 ¤   ¤   if (derr.IsntError())
1a5b34 ¤   ¤   {
e69b6f ¤   ¤   ¤   if (IsntNull(pPGD = App->mPGPdisks.FindPGPdisk(mPath)))
30f776 ¤   ¤   ¤   {
ed298f ¤   ¤   ¤   ¤   derr = pPGD->HighLevelFormatPGPdisk();
dbaf5a
a5724e ¤   ¤   ¤   ¤   if (derr.IsntError())
c372c3 ¤   ¤   ¤   ¤   {
a3b621 ¤   ¤   ¤   ¤   ¤   // Must unmount and remount on Win95 (Q134560).
bc9968 ¤   ¤   ¤   ¤   ¤   if (IsWin95CompatibleMachine() &&·
2f3e69 ¤   ¤   ¤   ¤   ¤   ¤   !IsWin98CompatibleMachine())
3e4859 ¤   ¤   ¤   ¤   ¤   {
f6d9bd ¤   ¤   ¤   ¤   ¤   ¤   UnmountAndRemountPGPdisk(pPGD->GetDrive());
19af5a
77dad5 ¤   ¤   ¤   ¤   ¤   ¤   if (IsntNull(pPGD =·
9726ec ¤   ¤   ¤   ¤   ¤   ¤   ¤   App->mPGPdisks.FindPGPdisk(mPath)))
508fec ¤   ¤   ¤   ¤   ¤   ¤   {
a300f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPGD->BrowseToVolume();
80db3c ¤   ¤   ¤   ¤   ¤   ¤   }
2e1c89 ¤   ¤   ¤   ¤   ¤   }
6f4bd6 ¤   ¤   ¤   ¤   ¤   else
7b4859 ¤   ¤   ¤   ¤   ¤   {
8796b8 ¤   ¤   ¤   ¤   ¤   ¤   pPGD->BrowseToVolume();
8d1c89 ¤   ¤   ¤   ¤   ¤   }
3b2613 ¤   ¤   ¤   ¤   }
42a3a6 ¤   ¤   ¤   }
640fe4 ¤   ¤   }
10af5a
d07fe9 ¤   ¤   // If error, unsteal the handle if stolen.
a4a3dc ¤   ¤   if (derr.IsError() && mStolenFile.Opened())
1b5b34 ¤   ¤   {
a2c4d1 ¤   ¤   ¤   mStolenFile.Close();
54af5a
9bf1e1 ¤   ¤   ¤   if (!mAreWeReplacing)
9769e1 ¤   ¤   ¤   ¤   DeleteFile(mPath);
b90fe4 ¤   ¤   }
a29371 ¤   }
a43c88 ¤   catch (CMemoryException *ex)
1bc7a1 ¤   {
3e6adc ¤   ¤   ex->Delete();
7aecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
e19371 ¤   }
fbaf5a
a233e3 ¤   return derr;
36efe6 }
59af5a
e9cc90 // PreTranslateMessage gets to see all messages before MFC does. We check
64fada // for keydown messages and if the random data page is open and active, pass
2037eb // them to that page.
6caf5a
b97efe BOOL·
4f4210 CDiskWizardSheet::PreTranslateMessage(MSG* pMsg)·
71bb36 {
de89f2 ¤   PGPBoolean¤ weProcessed¤= FALSE;
ef7387 ¤   PGPUInt8¤   vCode;
5e66cb ¤   PGPUInt32¤  activeIndex, randomIndex;
a8af5a
2bf87e ¤   switch (pMsg->message)
3cc7a1 ¤   {
--f176 00005caddb540110095 Page 4 of CDiskWizardSheet.cpp
fcb11a ¤   case WM_KEYDOWN:
c84eb3 ¤   ¤   vCode = pMsg->wParam & 0x7F;
e2af5a
ce249c ¤   ¤   activeIndex¤= GetActiveIndex();
01cda7 ¤   ¤   randomIndex¤= GetPageIndex(&mRandomDataPage);
c6af5a
754dec ¤   ¤   if ((activeIndex == randomIndex) &&·
d28f26 ¤   ¤   ¤   !mRandomDataPage.mIsDoneCollecting)
235b34 ¤   ¤   {
db1d2d ¤   ¤   ¤   // Punt key messages down for random data collection.
81bb22 ¤   ¤   ¤   mRandomDataPage.PostMessage(pMsg->message, pMsg->wParam,·
10ef27 ¤   ¤   ¤   ¤   pMsg->lParam);
9eaf5a
1cd337 ¤   ¤   ¤   weProcessed = TRUE;
350fe4 ¤   ¤   }
c82f68 ¤   ¤   break;
f59371 ¤   }
15af5a
06c950 ¤   return (weProcessed ? TRUE : CPropertySheet::PreTranslateMessage(pMsg));
47efe6 }
acaf5a
82af5a
64a6b9 ///////////////////////////////////////////////////////////////////////
00ce56 // CDiskWizardSheet protected custom functions and non-default handlers
78a6b9 ///////////////////////////////////////////////////////////////////////
67af5a
b8f77f // UnmountAndRemountPGPdisk quickly unmounts and remounts the PGPdisk after
b2e17a // formatting.
0faf5a
81c823 void·
9452ce CDiskWizardSheet::UnmountAndRemountPGPdisk(PGPUInt8 drive)
e8bb36 {
5d44a6 ¤   AppCommandInfo ACI;
72af5a
d0aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
3faf5a
f4d309 ¤   // Unmount the sucker.
c3fd41 ¤   ACI.op¤ ¤   = kAppOp_Unmount;
13b2f7 ¤   ACI.flags¤  = NULL;
8c86d6 ¤   ACI.drive¤  = drive;
35df35 ¤   ACI.path[0]¤= '\0';
e21b52 ¤   ¤
63aeb5 ¤   App->DispatchAppCommandInfo(&ACI);
bdaf5a
48f03b ¤   // Re-mount that bad boy.
a779be ¤   ACI.op¤ ¤   = kAppOp_Mount;
3e671a ¤   ACI.flags¤  = kACF_MountWithNoDialog;
2bf686 ¤   ACI.drive¤  = mVolumeInfoPage.mDriveCombo.mDriveNumber;
1c5608 ¤   strcpy(ACI.path, mPath);
2faf5a
148ad4 ¤   ACI.data[0]¤= (PGPUInt32) mPassphrasePage.mPassphraseEdit.mContents;
2eaf5a
9daeb5 ¤   App->DispatchAppCommandInfo(&ACI);
0cefe6 }
33af5a
99af5a
ed9bef //////////////////////////////////////////////
97eee1 // CDiskWizardSheet protected default handlers
729bef //////////////////////////////////////////////
f3af5a
eb8cca // OnHelpInfo handles context-sensitive help.
45af5a
a87efe BOOL·
c1f284 CDiskWizardSheet::OnHelpInfo(HELPINFO *pHelpInfo)
87bb36 {
9829b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
52e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
c4c7a1 ¤   {
c1ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
0e6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
ca9371 ¤   }
05af5a
--a622 0008a677f8e40110095 Page 5 of CDiskWizardSheet.cpp
d6c2e7 ¤   return TRUE;
43efe6 }
7baf5a
f27e66 // OnInitDialog is called during dialog initialization. We take the
4d479b // opportunity to add a context help button to the title bar.
bcaf5a
ee7efe BOOL·
7da7ca CDiskWizardSheet::OnInitDialog()·
b1bb36 {
d8f334 ¤   CMenu¤  ¤   *pSysMenu;
dd18a8 ¤   HDC¤¤   ¤   hDC;
7b1b02 ¤   PGPBoolean¤ loadedBitmap;
bd2e01 ¤   PGPUInt32¤  numBits;
bfaf5a
371450 ¤   CPropertySheet::OnInitDialog();
d2af5a
b89c14 ¤   // Get screen depth.
2dff18 ¤   hDC = ::GetDC(NULL);¤   ¤   // DC for desktop
833968 ¤   numBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
316ec2 ¤   ::ReleaseDC(NULL, hDC);
feaf5a
61ec20 ¤   // Load the bitmap and create a palette for it.
964932 ¤   if (numBits <= 1)
15c7a1 ¤   {
1cc154 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR1,·
f57869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
189371 ¤   }
e2d872 ¤   else if (numBits <= 4)
ebc7a1 ¤   {
06af03 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR4,·
b67869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
089371 ¤   }
7b0e24 ¤   else
fac7a1 ¤   {
4d3837 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR8,·
a47869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
a09371 ¤   }
6faf5a
655720 ¤   // Need to give the dialog a close box if we want a help box as well.
30a616 ¤   ModifyStyle(NULL, WS_SYSMENU, NULL);
0faf5a
f65d47 ¤   // Show the context help button.
c97f87 ¤   ModifyStyleEx(NULL, WS_EX_CONTEXTHELP, NULL);
e6af5a
6b0475 ¤   // Alter the system menu.
734645 ¤   pSysMenu = GetSystemMenu(FALSE);
8fe9f0 ¤   pgpAssertAddrValid(pSysMenu, CMenu);
34af5a
2152ba ¤   pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
a76825 ¤   pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
9ad6e9 ¤   pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
77e0bf ¤   pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
53af5a
c1129c ¤   DrawMenuBar();
9daf5a
2cd564 ¤   // Center on screen.
0d50f9 ¤   CenterWindow(GetDesktopWindow());
d3af5a
19afdc ¤   // Put us in front.
f59974 ¤   SetForegroundWindow();
8faf5a
6454ed ¤   // Put on top if necessary.
69c3a9 ¤   App->TweakOnTopAttribute(this);
ffaf5a
97c2e7 ¤   return TRUE;
fbefe6 }
39af5a
af915f // OnSysCommand is handled to trap close requests.
1baf5a
00c823 void·
dbeab3 CDiskWizardSheet::OnSysCommand(UINT nID, LPARAM lParam)·
8abb36 {
--2672 001b640b45a40110095 Page 6 of CDiskWizardSheet.cpp
691f71 ¤   if (nID == SC_CLOSE)
7ff5fa ¤   ¤   mDerr = DualErr(kPGDMinorError_UserAbort);
d067c5 ¤
40cc0b ¤   CPropertySheet::OnSysCommand(nID, lParam);
b6efe6 }
--c80b 000afa4a7c640110096 Page 1 of CDiskWizardSheet.h
541bc3 //////////////////////////////////////////////////////////////////////////////
e5a423 // CDiskWizardSheet.h
ed465d //
ac51ad // Declaration of class CDiskWizardSheet.
951bc3 //////////////////////////////////////////////////////////////////////////////
d0af5a
4fa811 // $Id: CDiskWizardSheet.h,v 1.2.2.11.2.1 1998/08/23 03:01:48 nryan Exp $
2caf5a
37cbce // Copyright (C) 1998 by Network Associates, Inc.
da71ae // All rights reserved.
9eaf5a
e410aa #ifndef Included_CDiskWizardSheet_h¤// [
b71159 #define Included_CDiskWizardSheet_h
7faf5a
293a85 #include "DualErr.h"
3caf5a
aaac81 #include "CDiskWizCreationPage.h"
b8ca96 #include "CDiskWizDonePage.h"
fa7454 #include "CDiskWizIntroPage.h"
77d516 #include "CDiskWizPassphrasePage.h"
77e843 #include "CDiskWizADKPage.h"
5eb14b #include "CDiskWizRandomDataPage.h"
3943b7 #include "CDiskWizVolumeInfoPage.h"
cfaf5a
60af5a
319f73 /////////////////////////
cfd80a // Class CDiskWizardSheet
b59f73 /////////////////////////
f3af5a
14dea3 class CDiskWizardSheet : public CPropertySheet
fdbb36 {
3d19e6 ¤   DECLARE_DYNAMIC(CDiskWizardSheet)
ddaf5a
1c6e45 ¤   friend class CDiskWizCreationPage;
cc5c7e ¤   friend class CDiskWizDonePage;
aa404d ¤   friend class CDiskWizIntroPage;
88ce15 ¤   friend class CDiskWizPassphrasePage;
5ce01d ¤   friend class CDiskWizADKPage;
53df75 ¤   friend class CDiskWizRandomDataPage;
75b7bc ¤   friend class CDiskWizVolumeInfoPage;
30af5a
e55ed4 public:
66da4d ¤   DualErr¤mInitErr;
11af5a
53259d ¤   ¤   ¤   CDiskWizardSheet();
7879d0 ¤   virtual¤~CDiskWizardSheet();
7baf5a
319cff ¤   DualErr¤ExecuteWizard(LPCSTR path = kEmptyString);
78af5a
ef3b6a ¤   //{{AFX_VIRTUAL(CDiskWizardSheet)
b867d4 ¤   public:
5bf17a ¤   virtual BOOL OnInitDialog();
92a0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
68af53 ¤   //}}AFX_VIRTUAL
20af5a
23a2d3 protected:
dac0b1 ¤   CDiskWizCreationPage¤   mCreationPage;¤ ¤   // disk creation wizard page
6adef5 ¤   CDiskWizDonePage¤   ¤   mDonePage;¤ ¤   ¤   // done message page
732bfe ¤   CDiskWizIntroPage¤  ¤   mIntroPage;¤¤   ¤   // intro message page
fd4d09 ¤   CDiskWizPassphrasePage¤ mPassphrasePage;¤   // passphrase page
f3051d ¤   CDiskWizADKPage¤¤   ¤   mADKPage;¤  ¤   ¤   // ADK page
056bc1 ¤   CDiskWizRandomDataPage¤ mRandomDataPage;¤   // random data page
daac05 ¤   CDiskWizVolumeInfoPage¤ mVolumeInfoPage;¤   // volume information page
acaf5a
67a2e8 ¤   DualErr¤¤   ¤   ¤   ¤   mDerr;¤ ¤   ¤   ¤   // pages report¤errors here
a1af5a
585957 ¤   CString¤¤   ¤   ¤   ¤   mPath;¤ ¤   ¤   ¤   // path to new PGPdisk
7d3372 ¤   File¤   ¤   ¤   ¤   ¤   mStolenFile;¤   ¤   // hold file handle
f7c922 ¤   PGPBoolean¤ ¤   ¤   ¤   mAreWeReplacing;¤   // replacing existing file?
fbaf5a
358b74 ¤   CBitmap¤¤   ¤   ¤   ¤   mSidebarBitmap;¤¤   // sidebar graphic
af0dfe ¤   CPalette¤   ¤   ¤   ¤   mSidebarPalette;¤   // sidebar palette
--95bc 001eedc002d40110096 Page 2 of CDiskWizardSheet.h
e0af5a
0bf2a2 ¤   void UnmountAndRemountPGPdisk(PGPUInt8 drive);
ceaf5a
2eba7d ¤   //{{AFX_MSG(CDiskWizardSheet)
285d0f ¤   afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
284d01 ¤   afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
d12e09 ¤   //}}AFX_MSG
b5af5a
202409 ¤   DECLARE_MESSAGE_MAP()
cb82f7 };
75af5a
e1c18c //{{AFX_INSERT_LOCATION}}
46af5a
eec218 #endif // ] Included_CDiskWizardSheet_h
--0764 0007229844140110097 Page 1 of CDriveLetterCombo.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
788d89 // CDriveLetterCombo.cpp
2b465d //
cd7afb // Implementation of class CDriveLetterCombo.
ac1bc3 //////////////////////////////////////////////////////////////////////////////
deaf5a
9390b9 // $Id: CDriveLetterCombo.cpp,v 1.1.2.5 1998/07/06 08:56:55 nryan Exp $
80af5a
57cbce // Copyright (C) 1998 by Network Associates, Inc.
5e71ae // All rights reserved.
6caf5a
709e12 #include "StdAfx.h"
d8af5a
9e9bcf #include "Required.h"
0dbfe9 #include "UtilityFunctions.h"
d0af5a
53572c #include "CDriveLetterCombo.h"
47af5a
d2af5a
0f83f5 ///////////////////////////
01b249 // MFC specific definitions
dd83f5 ///////////////////////////
a4af5a
de714f BEGIN_MESSAGE_MAP(CDriveLetterCombo, CComboBox)
7a055e ¤   //{{AFX_MSG_MAP(CDriveLetterCombo)
66ce9f ¤   ON_WM_CHAR()
06c9c4 ¤   ON_CONTROL_REFLECT(CBN_SELENDOK, OnSelEndOk)
c3044a ¤   //}}AFX_MSG_MAP
c1af28 END_MESSAGE_MAP()
f1af5a
93af5a
886c0e /////////////////////////////////////////////////////////////////////////////
9b9738 // CDriveLetterCombo public custom functions and non-default message handlers
176c0e /////////////////////////////////////////////////////////////////////////////
ecaf5a
71be0a // The CDriveLetterCombo default constructor.
ccaf5a
9f6eb1 CDriveLetterCombo::CDriveLetterCombo()
b4bb36 {
afefe6 }
04af5a
92e263 // The CDriveLetterCombo default destructor.
0eaf5a
177059 CDriveLetterCombo::~CDriveLetterCombo()
d1bb36 {
37efe6 }
8eaf5a
4ffa31 // InitDriveLetters fills the control with a list of free drive letters.
c8af5a
23c823 void·
d3a559 CDriveLetterCombo::InitDriveLetters()·
6ecebb {¤
3778f1 ¤   try
a4c7a1 ¤   {
d2bb26 ¤   ¤   CString¤¤   driveString;
22e5b3 ¤   ¤   PGPUInt8¤   i;
47368b ¤   ¤   PGPUInt32¤  drives;
64af5a
4aa432 ¤   ¤   // Fill the combo box with available drive letters.
9b6ab5 ¤   ¤   drives = GetLogicalDrives();
261b52 ¤   ¤
06258a ¤   ¤   for (i = 2; i < kMaxDrives; i++)
595b34 ¤   ¤   {
df2d37 ¤   ¤   ¤   if (!(drives & (1 << i)))
93f776 ¤   ¤   ¤   {
389786 ¤   ¤   ¤   ¤   driveString.Format("%c:", DriveNumToLet(i));
ae13d5 ¤   ¤   ¤   ¤   AddString(driveString);
cfa3a6 ¤   ¤   ¤   }
f00fe4 ¤   ¤   }
fdaf5a
dcc6a5 ¤   ¤   // Initialize us to point to the first drive on the list.
72b796 ¤   ¤   SetCurSel(0);
--1a65 0008b58818c40110097 Page 2 of CDriveLetterCombo.cpp
d84303 ¤   ¤   GetLBText(GetCurSel(), driveString);
feaf5a
bdfe06 ¤   ¤   mDriveNumber = DriveLetToNum(driveString[0]);
6c9371 ¤   }
a83c88 ¤   catch (CMemoryException *ex)
1ec7a1 ¤   {
8c6adc ¤   ¤   ex->Delete();
bb9371 ¤   }
66efe6 }
d7af5a
9fab52 // SetDriveLetter sets the current selection to the drive letter corresponding
3cd96a // to the given drive letter.
d6af5a
73c823 void·
678660 CDriveLetterCombo::SetDriveLetter(PGPUInt8 drive)
9ebb36 {
7678f1 ¤   try
29c7a1 ¤   {
e4bb26 ¤   ¤   CString¤¤   driveString;
ec2145 ¤   ¤   PGPInt32¤   prefDriveIndex;
36af5a
5093d3 ¤   ¤   pgpAssert(IsLegalDriveNumber(drive));
ddaf5a
662421 ¤   ¤   driveString.Format("%c:", DriveNumToLet(drive));
5eb79a ¤   ¤   prefDriveIndex = FindString(-1, driveString);
2baf5a
cceb5e ¤   ¤   if (prefDriveIndex == CB_ERR)
5aa98c ¤   ¤   ¤   prefDriveIndex = 0;
38af5a
043d2e ¤   ¤   SetCurSel(prefDriveIndex);
2de99f ¤   ¤   GetLBText(prefDriveIndex, driveString);
1daf5a
dffe06 ¤   ¤   mDriveNumber = DriveLetToNum(driveString[0]);
059371 ¤   }
d23c88 ¤   catch (CMemoryException *ex)
81c7a1 ¤   {
2c6adc ¤   ¤   ex->Delete();
e89371 ¤   }
28efe6 }
e9af5a
8d9c30 ////////////////////////////////////////////////////
fde009 // CDriveLetterCombo public default message handlers
b19c30 ////////////////////////////////////////////////////
84af5a
c3c7c5 // We override OnChar so we can implement type-selection correctly.
28af5a
2ec823 void·
0246e7 CDriveLetterCombo::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)·
e1bb36 {
afb089 ¤   char¤   ¤   driveString[2];
c26214 ¤   PGPInt32¤   newDriveIndex;
deaf5a
efff40 ¤   driveString[0]¤ = toupper(nChar);
301567 ¤   driveString[1]¤ = '\0';
9eaf5a
28a5d7 ¤   newDriveIndex = FindString(-1, driveString);
52af5a
b9526e ¤   if (newDriveIndex != CB_ERR)
03c7a1 ¤   {
6787ae ¤   ¤   SetCurSel(newDriveIndex);
2decbb ¤   ¤   mDriveNumber = DriveLetToNum(nChar);
769371 ¤   }
baefe6 }
eeaf5a
87084b // We override OnSelEndOk to update the drive letter variable after the user
303db1 // makes a new choice.
63af5a
48c823 void·
7b3f50 CDriveLetterCombo::OnSelEndOk()·
dcbb36 {
9178f1 ¤   try
8bc7a1 ¤   {
--1eb7 001f1ed88d540110097 Page 3 of CDriveLetterCombo.cpp
d719b8 ¤   ¤   CString driveString;
43af5a
234303 ¤   ¤   GetLBText(GetCurSel(), driveString);
96fe06 ¤   ¤   mDriveNumber = DriveLetToNum(driveString[0]);
f99371 ¤   }
b93c88 ¤   catch (CMemoryException *ex)
2ac7a1 ¤   {
fa6adc ¤   ¤   ex->Delete();
699371 ¤   }
f1efe6 }
--f33e 00114a224f040110098 Page 1 of CDriveLetterCombo.h
541bc3 //////////////////////////////////////////////////////////////////////////////
495f3a // CDriveLetterCombo.h
be465d //
dcb4b1 // Declaration of class CDriveLetterCombo.
f01bc3 //////////////////////////////////////////////////////////////////////////////
50af5a
3fca06 // $Id: CDriveLetterCombo.h,v 1.1.2.3 1998/07/06 08:56:56 nryan Exp $
c8af5a
7ccbce // Copyright (C) 1998 by Network Associates, Inc.
1271ae // All rights reserved.
77af5a
df49c7 #ifndef Included_CDriveLetterCombo_h¤   // [
dc1fa8 #define Included_CDriveLetterCombo_h
02af5a
d8ab81 #include "Resource.h"
aeaf5a
45af5a
bcb352 //////////////////////////
f640ab // Class CDriveLetterCombo
3bb352 //////////////////////////
25af5a
4dd315 class CDriveLetterCombo : public CComboBox
79bb36 {
115ed4 public:
d068c6 ¤   PGPUInt8 mDriveNumber;¤ ¤   // drive number currently selected
2caf5a
a83c3c ¤   ¤   ¤   CDriveLetterCombo();
dda581 ¤   virtual¤~CDriveLetterCombo();
00af5a
636098 ¤   void¤   InitDriveLetters();
dfd18b ¤   void¤   SetDriveLetter(PGPUInt8 drive);
3eaf5a
76c765 ¤   //{{AFX_VIRTUAL(CDriveLetterCombo)
9daf53 ¤   //}}AFX_VIRTUAL
beaf5a
45a2d3 protected:
82a3da ¤   //{{AFX_MSG(CDriveLetterCombo)
a19ea8 ¤   afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
f5f9f8 ¤   afx_msg void OnSelEndOk();
ac2e09 ¤   //}}AFX_MSG
3aaf5a
312409 ¤   DECLARE_MESSAGE_MAP()
1482f7 };
e6af5a
acc18c //{{AFX_INSERT_LOCATION}}
ffaf5a
14061d #endif¤ // ] Included_CDriveLetterCombo_h
--e2d3 000d8ce913540110099 Page 1 of CGetUserInfoDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
9da376 // CGetUserInfoDialog.cpp
d7465d //
a00862 // Implementation of the CGetUserInfoDialog class.
a71bc3 //////////////////////////////////////////////////////////////////////////////
47af5a
cd875c // $Id: CGetUserInfoDialog.cpp,v 1.1.2.6 1998/07/22 23:37:55 nryan Exp $
f3af5a
eecbce // Copyright (C) 1998 by Network Associates, Inc.
cd71ae // All rights reserved.
beaf5a
a79e12 #include "StdAfx.h"
d1af5a
069bcf #include "Required.h"
576be0 #include "CGetUserInfoDialog.h"
80c411 #include "Globals.h"
3c4713 #include "PGPdiskHelpIds.h"
25af5a
baaf5a
586cc2 /////////////////////
8e3a71 // Context help array
d36cc2 /////////////////////
85af5a
1577bf static PGPUInt32 HelpIds[] =
8bbb36 {
dd1977 ¤   IDOK,¤  ¤   ¤   ¤   IDH_PGPDISKAPP_GETUSERINFOOK,·
bbc7f9 ¤   IDCANCEL,¤  ¤   ¤   IDH_PGPDISKAPP_GETUSERINFOCANCEL,·
a134bf ¤   IDC_USER_EDIT,¤ ¤   IDH_PGPDISKAPP_GETUSERUSEREDIT,·
c14e9e ¤   IDC_ORG_EDIT,¤  ¤   IDH_PGPDISKAPP_GETUSERORGEDIT,·
aa4434 ····0,0·
6d82f7 };
d7af5a
23af5a
0c83f5 ///////////////////////////
ecb249 // MFC specific definitions
af83f5 ///////////////////////////
2aaf5a
f5834f BEGIN_MESSAGE_MAP(CGetUserInfoDialog, CDialog)
d91fac ¤   //{{AFX_MSG_MAP(CGetUserInfoDialog)
d1db65 ¤   ON_WM_HELPINFO()
e56e1b ¤   ON_EN_CHANGE(IDC_USER_EDIT, OnChangeNameEdit)
1ebd29 ¤   ON_EN_CHANGE(IDC_ORG_EDIT, OnChangeOrgEdit)
ff044a ¤   //}}AFX_MSG_MAP
73af28 END_MESSAGE_MAP()
b2af5a
11af5a
b11bc3 //////////////////////////////////////////////////////////////////////////////
916d89 // CGetUserInfoDialog public custom functions and non-default message handlers
7e1bc3 //////////////////////////////////////////////////////////////////////////////
4baf5a
2b0648 // The CGetUserInfoDialog default constructor.
d0af5a
48d8f9 CGetUserInfoDialog::CGetUserInfoDialog(CWnd *pParent)·
043728 ¤   : CDialog(CGetUserInfoDialog::IDD, pParent)
35bb36 {
4978f1 ¤   try
6fc7a1 ¤   {
2b66bf ¤   ¤   //{{AFX_DATA_INIT(CGetUserInfoDialog)
f484a2 ¤   ¤   mUserText = _T("");
b8a22c ¤   ¤   mOrgText = _T("");
d0765d ¤   ¤   //}}AFX_DATA_INIT
669371 ¤   }
b03c88 ¤   catch (CMemoryException *ex)
02c7a1 ¤   {
f46adc ¤   ¤   ex->Delete();
f19371 ¤   }
ebefe6 }
bbaf5a
e52395 // AskForUserInfo is a wrapper around DoModal.
74af5a
f82292 DualErr·
d848da CGetUserInfoDialog::AskForUserInfo()
--40e0 000076c692940110099 Page 2 of CGetUserInfoDialog.cpp
2cbb36 {
4bbe41 ¤   DualErr¤¤   derr;
bbe319 ¤   PGPInt32¤   result;
1467c5 ¤
dc0acb ¤   result = DoModal();
9eaf5a
72cff3 ¤   switch (result)
e5c7a1 ¤   {
97e379 ¤   case -1:
fafdbb ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
7a2f68 ¤   ¤   break;
9daf5a
b64a02 ¤   case IDCANCEL:
8838df ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
1a2f68 ¤   ¤   break;
da9371 ¤   }
fdaf5a
1533e3 ¤   return derr;
aeefe6 }
88af5a
efaf5a
8b186d /////////////////////////////////////////////////////////////////////////
a2032a // CGetUserInfoDialog protected custom functions and non-default handlers
ca186d /////////////////////////////////////////////////////////////////////////
70af5a
3be90a // UpdateOkButton enables the OK button if at least one of the edit boxes has
7d770c // text it in, otherwise the OK button is disabled.
51af5a
44c823 void·
df81a3 CGetUserInfoDialog::UpdateOkButton()
b9bb36 {
a5364d ¤   UpdateData(TRUE);
fcaf5a
dea80f ¤   if (mUserText.IsEmpty() && mOrgText.IsEmpty())
b9bf1b ¤   ¤   mOkButton.EnableWindow(FALSE);
610e24 ¤   else
ab4775 ¤   ¤   mOkButton.EnableWindow(TRUE);
67efe6 }
b9af5a
81ec34 // The CGetUserInfoDialog default data-exchange function.
8daf5a
0ac823 void·
7e9fe4 CGetUserInfoDialog::DoDataExchange(CDataExchange *pDX)
12bb36 {
2778f1 ¤   try
59c7a1 ¤   {
a0f4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
8faf5a
68dddd ¤   ¤   //{{AFX_DATA_MAP(CGetUserInfoDialog)
57e082 ¤   ¤   DDX_Control(pDX, IDC_USER_EDIT, mUserStatic);
a86c53 ¤   ¤   DDX_Control(pDX, IDC_ORG_EDIT, mOrgStatic);
a2a1d5 ¤   ¤   DDX_Control(pDX, IDCANCEL, mCancelButton);
173b20 ¤   ¤   DDX_Control(pDX, IDOK, mOkButton);
33c83b ¤   ¤   DDX_Text(pDX, IDC_USER_EDIT, mUserText);
b7cfad ¤   ¤   DDV_MaxChars(pDX, mUserText, 64);
a2b644 ¤   ¤   DDX_Text(pDX, IDC_ORG_EDIT, mOrgText);
a27184 ¤   ¤   DDV_MaxChars(pDX, mOrgText, 64);
de3376 ¤   ¤   //}}AFX_DATA_MAP
bd9371 ¤   }
923c88 ¤   catch (CMemoryException *ex)
13c7a1 ¤   {
fd6adc ¤   ¤   ex->Delete();
b19371 ¤   }
beefe6 }
39af5a
8ce6e6 // OnChangeNameEdit is called when the user types in the user name edit box.
8d07e4 // We enable or disable the OK button as necessary.
d3af5a
8bc823 void·
49d8a9 CGetUserInfoDialog::OnChangeNameEdit()·
59bb36 {
07efb2 ¤   UpdateOkButton();
--b9a4 001e3da6b0140110099 Page 3 of CGetUserInfoDialog.cpp
7aefe6 }
46af5a
7bd6ad // OnChangeOrgEdit is called when the user types in the organization edit box.
9207e4 // We enable or disable the OK button as necessary.
a8af5a
4ac823 void·
41013e CGetUserInfoDialog::OnChangeOrgEdit()·
b7bb36 {
8defb2 ¤   UpdateOkButton();
c1efe6 }
14af5a
b2af5a
845d1a ////////////////////////////////////////////////////////
380775 // CGetUserInfoDialog protected default message handlers
6c5d1a ////////////////////////////////////////////////////////
62af5a
c08cca // OnHelpInfo handles context-sensitive help.
05af5a
bb7efe BOOL·
4a7e5d CGetUserInfoDialog::OnHelpInfo(HELPINFO *pHelpInfo)
90bb36 {
7829b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
37e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
c5c7a1 ¤   {
b9ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
3a6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
989371 ¤   }
44af5a
96c2e7 ¤   return TRUE;
c9efe6 }
c9af5a
355252 // OnInitDialog is called when the dialog box is created.
fcaf5a
407efe BOOL·
a8187f CGetUserInfoDialog::OnInitDialog()
96bb36 {
91c799 ¤   CDialog::OnInitDialog();
25af5a
9d2675 ¤   // This will disable the OK button since no text is present yet.
46efb2 ¤   UpdateOkButton();
64af5a
8ad564 ¤   // Center on screen.
f150f9 ¤   CenterWindow(GetDesktopWindow());
25af5a
08afdc ¤   // Put us in front.
059974 ¤   SetForegroundWindow();
b2af5a
6c54ed ¤   // Put on top if necessary.
69c3a9 ¤   App->TweakOnTopAttribute(this);
09af5a
489a27 ¤   // Set focus to the user edit box.
45d2f0 ¤   mUserStatic.SetFocus();
33af5a
3d9b5a ¤   // Show now to thwart evil MFC auto-centering.
92c56d ¤   ShowWindow(SW_SHOW);
61af5a
06a230 ¤   return FALSE;
e3efe6 }
--7f3a 001a341ddc44011009a Page 1 of CGetUserInfoDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
7380ab // CGetUserInfoDialog.h
3e465d //
40c1e9 // Declaration of class CGetUserInfoDialog.
f31bc3 //////////////////////////////////////////////////////////////////////////////
7caf5a
099e7a // $Id: CGetUserInfoDialog.h,v 1.1.2.4 1998/07/22 23:37:59 nryan Exp $
4aaf5a
85cbce // Copyright (C) 1998 by Network Associates, Inc.
bb71ae // All rights reserved.
90af5a
d0642d #ifndef Included_CGetUserInfoDialog_h¤  // [
1dab8a #define Included_CGetUserInfoDialog_h
46af5a
bb3a85 #include "DualErr.h"
31af5a
3aab81 #include "Resource.h"
f3af5a
b0af5a
5d83f5 ///////////////////////////
17feba // Class CGetUserInfoDialog
9083f5 ///////////////////////////
08af5a
96173b class CGetUserInfoDialog : public CDialog
3abb36 {
6f5ed4 public:
75fa21 ¤   ¤   ¤   CGetUserInfoDialog(CWnd *pParent = NULL);
58af5a
d64567 ¤   DualErr¤AskForUserInfo();
e8af5a
50dd00 ¤   //{{AFX_DATA(CGetUserInfoDialog)
721b11 ¤   enum { IDD = IDD_GETUSERINFO_DLG };
7ab796 ¤   CEdit¤  mUserStatic;
898d16 ¤   CEdit¤  mOrgStatic;
af5b03 ¤   CButton¤mCancelButton;
86453d ¤   CButton¤mOkButton;
9874a5 ¤   CString¤mUserText;
36fd8b ¤   CString¤mOrgText;
2b5139 ¤   //}}AFX_DATA
35af5a
ae903e ¤   //{{AFX_VIRTUAL(CGetUserInfoDialog)
dfc369 ¤   protected:
0d3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
27af53 ¤   //}}AFX_VIRTUAL
15af5a
8aa2d3 protected:
7796e7 ¤   void UpdateOkButton();
d9af5a
abdd26 ¤   //{{AFX_MSG(CGetUserInfoDialog)
96698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
faf17a ¤   virtual BOOL OnInitDialog();
f75ee4 ¤   afx_msg void OnChangeNameEdit();
273f94 ¤   afx_msg void OnChangeOrgEdit();
f52e09 ¤   //}}AFX_MSG
9caf5a
c62409 ¤   DECLARE_MESSAGE_MAP()
f382f7 };
99af5a
79c18c //{{AFX_INSERT_LOCATION}}
ffaf5a
a349b5 #endif¤ // ] Included_CGetUserInfoDialog_h
--dec8 000ac8335bf4011009b Page 1 of CGlobalCSearchPGPdiskThread.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
f8c5a5 // CGlobalCSearchPGPdiskThread.cpp
f0465d //
d3b35f // Implementation of class CGlobalCSearchPGPdiskThread.
0a1bc3 //////////////////////////////////////////////////////////////////////////////
c6af5a
69b354 // $Id: CGlobalCSearchPGPdiskThread.cpp,v 1.1.2.3 1998/10/23 23:37:24 nryan Exp¶
ceed4e ·$
46af5a
accbce // Copyright (C) 1998 by Network Associates, Inc.
0571ae // All rights reserved.
8eaf5a
929e12 #include "StdAfx.h"
07af5a
8b9bcf #include "Required.h"
537414 #include "PGPdiskHighLevelUtils.h"
fabfe9 #include "UtilityFunctions.h"
28af5a
59bdb6 #include "CGlobalCSearchPGPdiskThread.h"
5fc411 #include "Globals.h"
25af5a
05af5a
d909b7 ////////////
bfe738 // Constants
3309b7 ////////////
13af5a
efdb2d // Custom windows messages
b1af5a
9e27ce const PGPUInt16 WM_SEARCH_PGPDISK = WM_USER + 245;
cbaf5a
4eaf5a
1783f5 ///////////////////////////
a5b249 // MFC specific definitions
fd83f5 ///////////////////////////
51af5a
2ea9b6 BEGIN_MESSAGE_MAP(CGlobalCSearchPGPdiskThread, CWinThread)
b396d1 ¤   //{{AFX_MSG_MAP(CGlobalCSearchPGPdiskThread)
52fc0b ¤   ON_THREAD_MESSAGE(WM_SEARCH_PGPDISK, OnSearchPGPdisk)
17044a ¤   //}}AFX_MSG_MAP
7eaf28 END_MESSAGE_MAP()
46af5a
f9af5a
67911d ///////////////////////////////////////////////////////////////////
d9247a // CGlobalCSearchPGPdiskThread public custom functions and handlers
eb911d ///////////////////////////////////////////////////////////////////
87af5a
6e6f43 // The CGlobalCSearchPGPdiskThread default constructor.
61af5a
d216c5 CGlobalCSearchPGPdiskThread::CGlobalCSearchPGPdiskThread()
30bb36 {
6300fb ¤   mIsSearchingOngoing¤= FALSE;
1d26c0 ¤   mUserCancelFlag¤¤   ¤   = FALSE;
b2af5a
bf0be9 ¤   // The thread will not delete itself.
2098cb ¤   m_bAutoDelete = FALSE;
b7efe6 }
bbaf5a
641ec4 // The CGlobalCSearchPGPdiskThread default destructor.
4eaf5a
7a4e43 CGlobalCSearchPGPdiskThread::~CGlobalCSearchPGPdiskThread()
9cbb36 {
c3efe6 }
74af5a
130bbd // CallPGPdiskSearch sends a message to the thread asking it to search for
dac98b // unconverted PGPdisks using the specified parameters. When finished, a
8c33d5 // message is sent to the calling window.
faaf5a
a82292 DualErr·
7218ed CGlobalCSearchPGPdiskThread::CallPGPdiskSearch(SearchPGPdiskInfo *pSPI)
b1bb36 {
3f7d36 ¤   DualErr derr;
acaf5a
--fccc 000397cbd944011009b Page 2 of CGlobalCSearchPGPdiskThread.cpp
a52758 ¤   pgpAssert(!mIsSearchingOngoing);
49af5a
4a3ca5 ¤   pgpAssertAddrValid(pSPI, SearchPGPdiskInfo);
56c3e6 ¤   mSPI = (* pSPI);
d6af5a
8c7cfc ¤   pgpAssert(IsntNull(mSPI.callerHwnd));
1baf5a
85d81a ¤   // Create the thread
3a0de2 ¤   if (!CreateThread())
30c7a1 ¤   {
c941de ¤   ¤   derr = DualErr(kPGDMinorError_ThreadCreationFailed);
d39371 ¤   }
dcaf5a
7f6022 ¤   mIsSearchingOngoing = derr.IsntError();
32af5a
9544ea ¤   // Send the convert command to the thread.
182361 ¤   if (derr.IsntError())
e5c7a1 ¤   {
7c3b35 ¤   ¤   if (!PostThreadMessage(WM_SEARCH_PGPDISK, kPGPdiskMessageMagic, NULL))
7a5b34 ¤   ¤   {
f72a14 ¤   ¤   ¤   mIsSearchingOngoing = FALSE;
59aad8 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PostThreadMessageFailed);
620fe4 ¤   ¤   }
869371 ¤   }
61af5a
f133e3 ¤   return derr;
26efe6 }
7daf5a
cf9e4d // CancelPGPdiskSearch can be called to cancel PGPdisk searching.
1aaf5a
07c823 void·
55ce7f CGlobalCSearchPGPdiskThread::CancelPGPdiskSearch()
94bb36 {
6854c9 ¤   pgpAssert(mIsSearchingOngoing);
ab9f15 ¤   mUserCancelFlag = TRUE;
12efe6 }
beaf5a
73af5a
f838fb //////////////////////////////////////////////////////////////
363bab // CGlobalCSearchPGPdiskThread public default message handlers
f038fb //////////////////////////////////////////////////////////////
33af5a
94f8e2 IMPLEMENT_DYNCREATE(CGlobalCSearchPGPdiskThread, CWinThread)
9caf5a
d48ddb // InitInstance is called to initialize the thread.
45af5a
a57efe BOOL·
f8a53b CGlobalCSearchPGPdiskThread::InitInstance()
96bb36 {
70c2e7 ¤   return TRUE;
53efe6 }
bdaf5a
4caf5a
67dd36 //////////////////////////////////////////////////////////////////////
191da3 // CGlobalCSearchPGPdiskThread protected custom functions and handlers
41dd36 //////////////////////////////////////////////////////////////////////
16af5a
11430a // OnSearchPGPdisk is called when the thread recieves a WM_SEARCH_PGPDISK
f1e96f // message. The function searches for unconverted PGPdisks using data from
ad6f7d // the thread's initialized parameters.
cdaf5a
28c823 void·
ae28a4 CGlobalCSearchPGPdiskThread::OnSearchPGPdisk(WPARAM wParam, LPARAM lParam)
e7bb36 {
d210db ¤   if (wParam != kPGPdiskMessageMagic)¤¤   // prevent collisions
9a99bf ¤   ¤   return;
98af5a
6f54c9 ¤   pgpAssert(mIsSearchingOngoing);
99af5a
eb78f1 ¤   try
fec7a1 ¤   {
3979f4 ¤   ¤   DualErr¤¤   derr;
--768a 000e86ad0844011009b Page 3 of CGlobalCSearchPGPdiskThread.cpp
e411a0 ¤   ¤   PGPUInt8¤   drive;
707289 ¤   ¤   PGPUInt32¤  logicalDrives;
051b52 ¤   ¤
f85783 ¤   ¤   logicalDrives = GetLogicalDrives();
f4af5a
719f14 ¤   ¤   for (drive = 2; drive < kMaxDrives; drive++)
805b34 ¤   ¤   {
80cedb ¤   ¤   ¤   // For every drive letter...
1df4b8 ¤   ¤   ¤   if (logicalDrives & (1 << drive))
2cf776 ¤   ¤   ¤   {
e5f250 ¤   ¤   ¤   ¤   CString root;
caaf5a
0a26bc ¤   ¤   ¤   ¤   derr = MakeRoot(drive, &root);
d2af5a
d62289 ¤   ¤   ¤   ¤   // If it's a local drive, search it for bad PGPdisks.
a1724e ¤   ¤   ¤   ¤   if (derr.IsntError())
4272c3 ¤   ¤   ¤   ¤   {
bb0655 ¤   ¤   ¤   ¤   ¤   if ((GetDriveType(root) == DRIVE_REMOVABLE) ||·
b003f9 ¤   ¤   ¤   ¤   ¤   ¤   (GetDriveType(root) == DRIVE_FIXED))
514859 ¤   ¤   ¤   ¤   ¤   {
663b02 ¤   ¤   ¤   ¤   ¤   ¤   SearchForPGPdisksInDirectory(root);
ed1c89 ¤   ¤   ¤   ¤   ¤   }
d32613 ¤   ¤   ¤   ¤   }
50a3a6 ¤   ¤   ¤   }
150fe4 ¤   ¤   }
bfaf5a
5248f5 ¤   ¤   mDerr = derr;
0f9371 ¤   }
6b3c88 ¤   catch (CMemoryException *ex)
b9c7a1 ¤   {
44ac92 ¤   ¤   mDerr = DualErr(kPGDMinorError_OutOfMemory);
616adc ¤   ¤   ex->Delete();
599371 ¤   }
75af5a
871291 ¤   mIsSearchingOngoing = FALSE;
a2af5a
92db61 ¤   // Notify caller window we're done.
ef81a7 ¤   PostMessage(mSPI.callerHwnd, WM_FINISHED_SEARCH, kPGPdiskMessageMagic,·
49dd06 ¤   ¤   (LPARAM) this);
8eaf5a
08a2c9 ¤   // Quit the thread.
4e1de5 ¤   PostQuitMessage(0);
78efe6 }
f6af5a
35f099 // SearchForPGPdisksInDirectory searches for non-converted PGPdisks in the
dc98c4 // specified directory, and in all sub-directories.
ebaf5a
a2c823 void·
204433 CGlobalCSearchPGPdiskThread::SearchForPGPdisksInDirectory(LPCSTR dir)
51bb36 {
c00d30 ¤   CFileFind¤  dirWalker;
38e6d9 ¤   CString¤¤   wildDirPath;
dbaf5a
42d77b ¤   if (mUserCancelFlag)
2a99bf ¤   ¤   return;
a6af5a
69e55e ¤   wildDirPath = dir;
adaf5a
f0a6f7 ¤   ::SetWindowText(mSPI.dirStaticHwnd, dir);
69af5a
3d673b ¤   if (wildDirPath[wildDirPath.GetLength() - 1] == '\\')
1db04d ¤   ¤   wildDirPath += "*.*";
580e24 ¤   else
3c6029 ¤   ¤   wildDirPath += "\\*.*";
c4af5a
894ac7 ¤   if (dirWalker.FindFile(wildDirPath))
b8c7a1 ¤   {
57652f ¤   ¤   PGPBoolean moreFiles = TRUE;
e5af5a
afbd6b ¤   ¤   // For every file or directory in the directory...
75e652 ¤   ¤   while (moreFiles)
e85b34 ¤   ¤   {
--e442 001d2a220a24011009b Page 4 of CGlobalCSearchPGPdiskThread.cpp
b73168 ¤   ¤   ¤   CString path;
47af5a
6b2ed7 ¤   ¤   ¤   moreFiles = dirWalker.FindNextFile();
7aeefb ¤   ¤   ¤   path = dirWalker.GetFilePath();
20af5a
e9ec1c ¤   ¤   ¤   if (dirWalker.IsDirectory())
3ff776 ¤   ¤   ¤   {
83a166 ¤   ¤   ¤   ¤   // If it's a directory, recurse.
69b89a ¤   ¤   ¤   ¤   if (!dirWalker.IsDots())
e11d75 ¤   ¤   ¤   ¤   ¤   SearchForPGPdisksInDirectory(path);
72a3a6 ¤   ¤   ¤   }
67bb8c ¤   ¤   ¤   else
0bf776 ¤   ¤   ¤   {
a25bcf ¤   ¤   ¤   ¤   PGPBoolean hasExtension, isPGPdisk;
4aaf5a
d33dca ¤   ¤   ¤   ¤   hasExtension = (path.Right(4).CompareNoCase(
df2a5b ¤   ¤   ¤   ¤   ¤   kPGPdiskFileExtension) == 0);
e187c7 ¤   ¤   ¤
826dc7 ¤   ¤   ¤   ¤   isPGPdisk = hasExtension && ValidatePGPdisk(path).IsntError();
b8af5a
e8f3a9 ¤   ¤   ¤   ¤   // If it's a file, check if it's a bad PGPdisk.
b29429 ¤   ¤   ¤   ¤   if (isPGPdisk && DoesPGPdiskHaveBadCAST(path))
b072c3 ¤   ¤   ¤   ¤   {
89fc99 ¤   ¤   ¤   ¤   ¤   SendMessage(mSPI.listBoxHwnd, LB_ADDSTRING, 0,·
32dfca ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) (LPCSTR) path);
382613 ¤   ¤   ¤   ¤   }
a0a3a6 ¤   ¤   ¤   }
3b0fe4 ¤   ¤   }
af9371 ¤   }
d2efe6 }
--ead5 000bcc938114011009c Page 1 of CGlobalCSearchPGPdiskThread.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d26af1 // CGlobalCSearchPGPdiskThread.h
ba465d //
d62a22 // Declaration of class CGlobalCSearchPGPdiskThread.
bb1bc3 //////////////////////////////////////////////////////////////////////////////
04af5a
ab565c // $Id: CGlobalCSearchPGPdiskThread.h,v 1.1.2.2 1998/10/23 02:18:54 nryan Exp $
2baf5a
1bcbce // Copyright (C) 1998 by Network Associates, Inc.
8371ae // All rights reserved.
dcaf5a
ad0337 #ifndef Included_CGlobalCSearchPGPdiskThread_h¤ // [
89f7f0 #define Included_CGlobalCSearchPGPdiskThread_h
d6af5a
283a85 #include "DualErr.h"
4baf5a
58af5a
6009b7 ////////////
7ee738 // Constants
d909b7 ////////////
7daf5a
8f0d0c const PGPUInt16 WM_FINISHED_SEARCH = WM_USER + 244;
c0af5a
66af5a
72d557 ////////
bd02c9 // Types
45d557 ////////
dcaf5a
bdaa64 // A SearchPGPdiskInfo structure contains information for searching for
f7163a // old, bad CAST PGPdisks.
9daf5a
f18301 typedef struct SearchPGPdiskInfo
71bb36 {
571284 ¤   HWND¤   callerHwnd;¤¤   // HWND of caller window
7fc688 ¤   HWND¤   listBoxHwnd;¤   // HWND of list box
7b7fb8 ¤   HWND¤   dirStaticHwnd;¤ // HWND of directory static
12af5a
0b5340 } SearchPGPdiskInfo;
f9af5a
eeaf5a
49fc6a ////////////////////////////////////
75d65c // Class CGlobalCSearchPGPdiskThread
78fc6a ////////////////////////////////////
1caf5a
5bf126 class CGlobalCSearchPGPdiskThread : public CWinThread
49bb36 {
676b6d ¤   DECLARE_DYNCREATE(CGlobalCSearchPGPdiskThread)
80af5a
ce5ed4 public:
4c6afe ¤   DualErr¤mDerr;¤ ¤   ¤   ¤   // holds error
a5af5a
db703a ¤   ¤   ¤   CGlobalCSearchPGPdiskThread();
6450cd ¤   virtual¤~CGlobalCSearchPGPdiskThread();
2daf5a
9a5af3 ¤   DualErr¤CallPGPdiskSearch(SearchPGPdiskInfo *pSPI);·
8d2eb1 ¤   void¤   CancelPGPdiskSearch();
51af5a
254c38 ¤   //{{AFX_VIRTUAL(CGlobalCSearchPGPdiskThread)
6367d4 ¤   public:
a1019a ¤   virtual BOOL InitInstance();
c6af53 ¤   //}}AFX_VIRTUAL
f5af5a
a1a2d3 protected:
d83687 ¤   SearchPGPdiskInfo¤  mSPI;¤  ¤   ¤   ¤   ¤   // info for the conversion
995d60 ¤   PGPBoolean¤ ¤   ¤   mIsSearchingOngoing;¤   // searching happening now?
afe52d ¤   PGPBoolean¤ ¤   ¤   mUserCancelFlag;¤   ¤   // TRUE to cancel
deaf5a
39772a ¤   void SearchForPGPdisksInDirectory(LPCSTR dir);
15af5a
8e134a ¤   //{{AFX_MSG(CGlobalCSearchPGPdiskThread)
c07e0e ¤   afx_msg void OnSearchPGPdisk(WPARAM wParam, LPARAM lParam);
bc2e09 ¤   //}}AFX_MSG
--6937 0014e1eae234011009c Page 2 of CGlobalCSearchPGPdiskThread.h
e0af5a
352409 ¤   DECLARE_MESSAGE_MAP()
ab82f7 };
e9af5a
0bc18c //{{AFX_INSERT_LOCATION}}
feaf5a
4e7af9 #endif¤ // ] Included_CGlobalCSearchPGPdiskThread_h
--d836 000236d5b624011009d Page 1 of CGlobalCWizDonePage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
c0de11 // CGlobalCWizDonePage.cpp
12465d //
ea33f2 // Implementation of class CGlobalCWizDonePage.
c31bc3 //////////////////////////////////////////////////////////////////////////////
5daf5a
687c5a // $Id: CGlobalCWizDonePage.cpp,v 1.1.2.1 1998/10/22 22:27:32 nryan Exp $
beaf5a
54cbce // Copyright (C) 1998 by Network Associates, Inc.
5571ae // All rights reserved.
49af5a
749e12 #include "StdAfx.h"
e9af5a
2b9bcf #include "Required.h"
53d9dd #include "CGlobalCWizDonePage.h"
ef31a0 #include "CGlobalCWizardSheet.h"
d2c411 #include "Globals.h"
a24713 #include "PGPdiskHelpIds.h"
05af5a
e6af5a
836cc2 /////////////////////
7e3a71 // Context help array
ca6cc2 /////////////////////
1faf5a
0f77bf static PGPUInt32 HelpIds[] =
32bb36 {
accec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
e6ce3c ¤   0,0·
e282f7 };
17af5a
81af5a
6e83f5 ///////////////////////////
c2b249 // MFC specific definitions
f183f5 ///////////////////////////
d3af5a
53ee6b BEGIN_MESSAGE_MAP(CGlobalCWizDonePage, CPropertyPage)
7873ec ¤   //{{AFX_MSG_MAP(CGlobalCWizDonePage)
09db65 ¤   ON_WM_HELPINFO()
9c2fa5 ¤   ON_WM_PAINT()
d2044a ¤   //}}AFX_MSG_MAP
eeaf28 END_MESSAGE_MAP()
55af5a
a0af5a
8ba6b9 ///////////////////////////////////////////////////////////////////////
85632c // CGlobalCWizDonePage public custom functions and non-default handlers
92a6b9 ///////////////////////////////////////////////////////////////////////
bbaf5a
63abd7 IMPLEMENT_DYNCREATE(CGlobalCWizDonePage, CPropertyPage)
57af5a
080670 // The CGlobalCWizDonePage default constructor.
45af5a
ecb4b3 CGlobalCWizDonePage::CGlobalCWizDonePage()
69d76b ¤   ·: CPropertyPage(CGlobalCWizDonePage::IDD)
36bb36 {
cbc017 ¤   //{{AFX_DATA_INIT(CGlobalCWizDonePage)
9ab1e8 ¤   //}}AFX_DATA_INIT
85af5a
16d7e1 ¤   mParentGlobalCWiz = NULL;
40af5a
a5218f ¤   // Exorcise the big help button.
d06a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
b4efe6 }
75af5a
628cb1 // The CGlobalCWizDonePage destructor.
ddaf5a
d5dabb CGlobalCWizDonePage::~CGlobalCWizDonePage()
cdbb36 {
e3efe6 }
93af5a
62af5a
19dd60 //////////////////////////////////////////////////////
23c1ce // CGlobalCWizDonePage public default message handlers
--68e9 000142688674011009d Page 2 of CGlobalCWizDonePage.cpp
92dd60 //////////////////////////////////////////////////////
c2af5a
04c57f // OnSetActive is called when this page is made active. We make sure the
dcfdfc // correct buttons are enabled/disabled.
53af5a
157efe BOOL·
22ea69 CGlobalCWizDonePage::OnSetActive()·
73bb36 {
7be5df ¤   pgpAssertAddrValid(mParentGlobalCWiz, CGlobalCWizardSheet);
e1af5a
f404c6 ¤   mParentGlobalCWiz->SetWizardButtons(PSWIZB_FINISH);
e62e4c ¤   mParentGlobalCWiz->GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
50af5a
b8bfaa ¤   return CPropertyPage::OnSetActive();
fdefe6 }
e5af5a
f0af5a
574a2a //////////////////////////////////////////////////////////////////////////
8bfb5d // CGlobalCWizDonePage protected custom functions and non-default handlers
f84a2a //////////////////////////////////////////////////////////////////////////
ceaf5a
e2c751 // The CGlobalCWizDonePage data exchange function.
d7af5a
73c823 void·
5bb67e CGlobalCWizDonePage::DoDataExchange(CDataExchange *pDX)
36bb36 {
5378f1 ¤   try
1ec7a1 ¤   {
1822a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
70af5a
021120 ¤   ¤   //{{AFX_DATA_MAP(CGlobalCWizDonePage)
a0f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
903376 ¤   ¤   //}}AFX_DATA_MAP
0e9371 ¤   }
a53c88 ¤   catch (CMemoryException *ex)
bfc7a1 ¤   {
926adc ¤   ¤   ex->Delete();
b99371 ¤   }
dcefe6 }
d8af5a
bbaf5a
914d57 /////////////////////////////////////////////////////////
0d143b // CGlobalCWizDonePage protected default message handlers
ea4d57 /////////////////////////////////////////////////////////
22af5a
408cca // OnHelpInfo handles context-sensitive help.
a8af5a
5f7efe BOOL·
d9fd7a CGlobalCWizDonePage::OnHelpInfo(HELPINFO *pHelpInfo)
4bbb36 {
1b29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
e6e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
d7c7a1 ¤   {
72ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
c16b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
b29371 ¤   }
5eaf5a
48c2e7 ¤   return TRUE;
56efe6 }
4eaf5a
459c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
6aaf5a
03c823 void·
61f5a0 CGlobalCWizDonePage::OnPaint()·
1fbb36 {
aa0575 ¤   CDC¤¤   ¤   memDC;
02c943 ¤   CPaintDC¤   DC(this);
a0e3a1 ¤   HBITMAP¤¤   oldBitmap;
1eb2e4 ¤   RECT¤   ¤   sidebarRect;
20af5a
e748d1 ¤   DC.SelectPalette(&mParentGlobalCWiz->mSidebarPalette, FALSE);
14cf08 ¤   DC.RealizePalette();
--16a3 0016a8e9e084011009d Page 3 of CGlobalCWizDonePage.cpp
e0af5a
eece55 ¤   memDC.CreateCompatibleDC(&DC);
b5b0f2 ¤   memDC.SelectPalette(&mParentGlobalCWiz->mSidebarPalette, FALSE);
30bb83 ¤   memDC.RealizePalette();
31af5a
687fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
577564 ¤   ScreenToClient(&sidebarRect);
7767c5 ¤
b00eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
89e162 ¤   // don't fool with it.
d4af5a
e3ed0e ¤   oldBitmap = (HBITMAP) SelectObject(memDC,·
f1d433 ¤   ¤   mParentGlobalCWiz->mSidebarBitmap);
a3af5a
0c96b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
6ceefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
7daf5a
d1ac4f ¤   memDC.SelectObject(oldBitmap);
d063a9 ¤   memDC.DeleteDC();
6aefe6 }
--e156 0018e2ae1c84011009e Page 1 of CGlobalCWizDonePage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
70b77f // CGlobalCWizDonePage.h
c1465d //
aea796 // Declaration of class CGlobalCWizDonePage.
fc1bc3 //////////////////////////////////////////////////////////////////////////////
f2af5a
c43672 // $Id: CGlobalCWizDonePage.h,v 1.1.2.1 1998/10/22 22:27:34 nryan Exp $
eaaf5a
e7cbce // Copyright (C) 1998 by Network Associates, Inc.
5a71ae // All rights reserved.
beaf5a
dc89e8 #ifndef Included_CGlobalCWizDonePage_h¤ // [
9b1b25 #define Included_CGlobalCWizDonePage_h
4aaf5a
a3ab81 #include "Resource.h"
c4af5a
d3af5a
8bd557 ////////
be02c9 // Types
ebd557 ////////
b6af5a
7624dd class CGlobalCWizardSheet;
26af5a
89af5a
9c5270 ////////////////////////////
51db61 // Class CGlobalCWizDonePage
ab5270 ////////////////////////////
11af5a
c7e8d2 class CGlobalCWizDonePage : public CPropertyPage
a1bb36 {
c2c7a7 ¤   DECLARE_DYNCREATE(CGlobalCWizDonePage)
37af5a
ab5ed4 public:
4dda7a ¤   CGlobalCWizardSheet *mParentGlobalCWiz;¤¤   // pointer to parent sheet
c7af5a
60b429 ¤   CGlobalCWizDonePage();
ad757e ¤   ~CGlobalCWizDonePage();
d4af5a
4b1c48 ¤   //{{AFX_DATA(CGlobalCWizDonePage)
bd8f13 ¤   enum { IDD = IDD_GLOBWIZ_DONE };
a345be ¤   CStatic¤mSidebarGraphic;
fd5139 ¤   //}}AFX_DATA
26af5a
29c4f8 ¤   //{{AFX_VIRTUAL(CGlobalCWizDonePage)
db67d4 ¤   public:
0c6e36 ¤   virtual BOOL OnSetActive();
d6c369 ¤   protected:
a13e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
dcaf53 ¤   //}}AFX_VIRTUAL
77af5a
0ea2d3 protected:
23587c ¤   //{{AFX_MSG(CGlobalCWizDonePage)
a3698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
ffc5f3 ¤   afx_msg void OnPaint();
d12e09 ¤   //}}AFX_MSG
19af5a
572409 ¤   DECLARE_MESSAGE_MAP()
7f82f7 };
61af5a
4cc18c //{{AFX_INSERT_LOCATION}}
9caf5a
8ed2b3 #endif¤ // ] Included_CGlobalCWizDonePage_h
--966c 0003b9ad9384011009f Page 1 of CGlobalCWizIntroPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
95c026 // CGlobalCWizIntroPage.cpp
a2465d //
4b5947 // Implementation of class CGlobalCWizIntroPage.
7a1bc3 //////////////////////////////////////////////////////////////////////////////
a0af5a
395853 // $Id: CGlobalCWizIntroPage.cpp,v 1.1.2.1 1998/10/22 22:27:35 nryan Exp $
92af5a
24cbce // Copyright (C) 1998 by Network Associates, Inc.
db71ae // All rights reserved.
4baf5a
849e12 #include "StdAfx.h"
c0af5a
159bcf #include "Required.h"
1f8890 #include "CGlobalCWizIntroPage.h"
ed31a0 #include "CGlobalCWizardSheet.h"
00c411 #include "Globals.h"
f54713 #include "PGPdiskHelpIds.h"
48af5a
f1af5a
736cc2 /////////////////////
073a71 // Context help array
426cc2 /////////////////////
3eaf5a
d677bf static PGPUInt32 HelpIds[] =
8dbb36 {
86cec8 ¤   IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
4ece3c ¤   0,0·
9382f7 };
e9af5a
7daf5a
0583f5 ///////////////////////////
fbb249 // MFC specific definitions
cd83f5 ///////////////////////////
11af5a
a2ed42 BEGIN_MESSAGE_MAP(CGlobalCWizIntroPage, CPropertyPage)
f261f5 ¤   //{{AFX_MSG_MAP(CGlobalCWizIntroPage)
36db65 ¤   ON_WM_HELPINFO()
7e2fa5 ¤   ON_WM_PAINT()
7b044a ¤   //}}AFX_MSG_MAP
f1af28 END_MESSAGE_MAP()
96af5a
e1af5a
08da3d ////////////////////////////////////////////////////////////////////////
20122d // CGlobalCWizIntroPage public custom functions and non-default handlers
25da3d ////////////////////////////////////////////////////////////////////////
f3af5a
4092e0 IMPLEMENT_DYNCREATE(CGlobalCWizIntroPage, CPropertyPage)
06af5a
a028d1 // The CGlobalCWizIntroPage default constructor.
47af5a
19ae72 CGlobalCWizIntroPage::CGlobalCWizIntroPage()
508007 ¤   ·: CPropertyPage(CGlobalCWizIntroPage::IDD)
e7bb36 {
3a281a ¤   //{{AFX_DATA_INIT(CGlobalCWizIntroPage)
01b1e8 ¤   //}}AFX_DATA_INIT
20af5a
f5d7e1 ¤   mParentGlobalCWiz = NULL;
fcaf5a
c9218f ¤   // Exorcise the big help button.
d36a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
b7efe6 }
9aaf5a
23a0c0 // The CGlobalCWizIntroPage destructor.
29af5a
c7319a CGlobalCWizIntroPage::~CGlobalCWizIntroPage()
a3bb36 {
b4efe6 }
9baf5a
9baf5a
23910a ///////////////////////////////////////////////////////
3b5bc5 // CGlobalCWizIntroPage public default message handlers
--1863 00091dd9a6c4011009f Page 2 of CGlobalCWizIntroPage.cpp
2a910a ///////////////////////////////////////////////////////
efaf5a
e4c57f // OnSetActive is called when this page is made active. We make sure the
f9fdfc // correct buttons are enabled/disabled.
16af5a
897efe BOOL·
a73aff CGlobalCWizIntroPage::OnSetActive()·
29bb36 {
18e5df ¤   pgpAssertAddrValid(mParentGlobalCWiz, CGlobalCWizardSheet);
785ab3 ¤   mParentGlobalCWiz->SetWizardButtons(PSWIZB_NEXT);
feaf5a
45bfaa ¤   return CPropertyPage::OnSetActive();
1befe6 }
bcaf5a
c3af5a
627cc3 ///////////////////////////////////////////////////////////////////////////
9f489d // CGlobalCWizIntroPage protected custom functions and non-default handlers
f47cc3 ///////////////////////////////////////////////////////////////////////////
faaf5a
cb2b79 // The CGlobalCWizIntroPage data exchange function.
e3af5a
50c823 void·
5749fe CGlobalCWizIntroPage::DoDataExchange(CDataExchange *pDX)
5fbb36 {
f078f1 ¤   try
2bc7a1 ¤   {
d022a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
cdaf5a
3d6df7 ¤   ¤   //{{AFX_DATA_MAP(CGlobalCWizIntroPage)
15f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
843376 ¤   ¤   //}}AFX_DATA_MAP
f99371 ¤   }
6c3c88 ¤   catch (CMemoryException *ex)
9bc7a1 ¤   {
606adc ¤   ¤   ex->Delete();
169371 ¤   }
44efe6 }
21af5a
aeaf5a
62d4a6 //////////////////////////////////////////////////////////
64d9b0 // CGlobalCWizIntroPage protected default message handlers
39d4a6 //////////////////////////////////////////////////////////
cbaf5a
218cca // OnHelpInfo handles context-sensitive help.
b9af5a
d57efe BOOL·
c4c12e CGlobalCWizIntroPage::OnHelpInfo(HELPINFO *pHelpInfo)
e5bb36 {
5629b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
ebe5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
ccc7a1 ¤   {
39ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
b66b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
6e9371 ¤   }
f7af5a
abc2e7 ¤   return TRUE;
7fefe6 }
68af5a
139c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
0eaf5a
3dc823 void·
8defb8 CGlobalCWizIntroPage::OnPaint()·
debb36 {
c70575 ¤   CDC¤¤   ¤   memDC;
f4c943 ¤   CPaintDC¤   DC(this);
cfe3a1 ¤   HBITMAP¤¤   oldBitmap;
35b2e4 ¤   RECT¤   ¤   sidebarRect;
a7af5a
f048d1 ¤   DC.SelectPalette(&mParentGlobalCWiz->mSidebarPalette, FALSE);
cccf08 ¤   DC.RealizePalette();
7daf5a
91ce55 ¤   memDC.CreateCompatibleDC(&DC);
--31e6 00103891aea4011009f Page 3 of CGlobalCWizIntroPage.cpp
dab0f2 ¤   memDC.SelectPalette(&mParentGlobalCWiz->mSidebarPalette, FALSE);
d1bb83 ¤   memDC.RealizePalette();
bdaf5a
2d7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
2b7564 ¤   ScreenToClient(&sidebarRect);
fc67c5 ¤
aa0eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
5ce162 ¤   // don't fool with it.
81af5a
f4ed0e ¤   oldBitmap = (HBITMAP) SelectObject(memDC,·
2fd433 ¤   ¤   mParentGlobalCWiz->mSidebarBitmap);
96af5a
9c96b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
2ceefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
faaf5a
22ac4f ¤   memDC.SelectObject(oldBitmap);
4d63a9 ¤   memDC.DeleteDC();
03efe6 }
--e828 0013124b222401100a0 Page 1 of CGlobalCWizIntroPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
3b45bf // CGlobalCWizIntroPage.h
29465d //
607cf1 // Declaration of class CGlobalCWizIntroPage.
661bc3 //////////////////////////////////////////////////////////////////////////////
d8af5a
8a2e3c // $Id: CGlobalCWizIntroPage.h,v 1.1.2.1 1998/10/22 22:27:36 nryan Exp $
bbaf5a
54cbce // Copyright (C) 1998 by Network Associates, Inc.
1971ae // All rights reserved.
c1af5a
8ca6ea #ifndef Included_CGlobalCWizIntroPage_h¤// [
242436 #define Included_CGlobalCWizIntroPage_h
71af5a
343a85 #include "DualErr.h"
64ab81 #include "Resource.h"
8aaf5a
1daf5a
19d557 ////////
9802c9 // Types
a9d557 ////////
99af5a
6024dd class CGlobalCWizardSheet;
f8af5a
0faf5a
d68104 /////////////////////////////
185768 // Class CGlobalCWizIntroPage
398104 /////////////////////////////
c5af5a
91aeb8 class CGlobalCWizIntroPage : public CPropertyPage
07bb36 {
c79d96 ¤   DECLARE_DYNCREATE(CGlobalCWizIntroPage)
4eaf5a
e95ed4 public:
99da7a ¤   CGlobalCWizardSheet *mParentGlobalCWiz;¤¤   // pointer to parent sheet
29af5a
9244f0 ¤   CGlobalCWizIntroPage();
2a620b ¤   ~CGlobalCWizIntroPage();
eeaf5a
c782b4 ¤   //{{AFX_DATA(CGlobalCWizIntroPage)
66e95e ¤   enum { IDD = IDD_GLOBWIZ_INTRO };
8245be ¤   CStatic¤mSidebarGraphic;
cc5139 ¤   //}}AFX_DATA
34af5a
ce37e7 ¤   //{{AFX_VIRTUAL(CGlobalCWizIntroPage)
4867d4 ¤   public:
8c6e36 ¤   virtual BOOL OnSetActive();
a9c369 ¤   protected:
aa3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
09af53 ¤   //}}AFX_VIRTUAL
58af5a
c1a2d3 protected:
4cf557 ¤   //{{AFX_MSG(CGlobalCWizIntroPage)
cc698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
7ac5f3 ¤   afx_msg void OnPaint();
7d2e09 ¤   //}}AFX_MSG
38af5a
282409 ¤   DECLARE_MESSAGE_MAP()
8482f7 };
d9af5a
dcc18c //{{AFX_INSERT_LOCATION}}
5caf5a
31d540 #endif¤ // ] Included_CGlobalCWizIntroPage_h
--3cdf 000d97ca13a401100a1 Page 1 of CGlobalCWizSearchPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
5b4ee9 // CGlobalCWizSearchPage.cpp
ae465d //
b4538e // Implementation of the CGlobalCWizSearchPage class.
be1bc3 //////////////////////////////////////////////////////////////////////////////
b9af5a
196771 // $Id: CGlobalCWizSearchPage.cpp,v 1.1.2.5 1998/11/06 18:57:02 nryan Exp $
67af5a
5fcbce // Copyright (C) 1998 by Network Associates, Inc.
1071ae // All rights reserved.
77af5a
629e12 #include "StdAfx.h"
a4af5a
d89bcf #include "Required.h"
95993c #include "StringAssociation.h"
e9af5a
76983d #include "CGlobalCWizSearchPage.h"
5e31a0 #include "CGlobalCWizardSheet.h"
b1c411 #include "Globals.h"
a34713 #include "PGPdiskHelpIds.h"
11af5a
e0af5a
f66cc2 /////////////////////
833a71 // Context help array
316cc2 /////////////////////
beaf5a
e777bf static PGPUInt32 HelpIds[] =
bcbb36 {
c8e4f0 ····IDC_SIDEBAR,¤   ¤   ¤   ((PGPUInt32) -1),·
dece3c ¤   0,0·
5082f7 };
86af5a
c8af5a
1683f5 ///////////////////////////
41b249 // MFC specific definitions
f583f5 ///////////////////////////
d4af5a
f8145a BEGIN_MESSAGE_MAP(CGlobalCWizSearchPage, CPropertyPage)
874639 ¤   //{{AFX_MSG_MAP(CGlobalCWizSearchPage)
eb7840 ¤   ON_MESSAGE(WM_FINISHED_SEARCH, OnFinishedSearch)
07db65 ¤   ON_WM_HELPINFO()
cd2fa5 ¤   ON_WM_PAINT()
de044a ¤   //}}AFX_MSG_MAP
01af28 END_MESSAGE_MAP()
79af5a
43af5a
7c186d /////////////////////////////////////////////////////////////////////////
aa074c // CGlobalCWizSearchPage public custom functions and non-default handlers
5f186d /////////////////////////////////////////////////////////////////////////
2caf5a
32923d IMPLEMENT_DYNCREATE(CGlobalCWizSearchPage, CPropertyPage)
06af5a
6d418b // The CGlobalCWizSearchPage default constructor.
0eaf5a
a86865 CGlobalCWizSearchPage::CGlobalCWizSearchPage()
b10804 ¤   ·: CPropertyPage(CGlobalCWizSearchPage::IDD)
37bb36 {
d55989 ¤   //{{AFX_DATA_INIT(CGlobalCWizSearchPage)
240c0f ¤   mDirNameText = _T("");
4e71e9 ¤   mSearchStatusText = _T("");
82b1e8 ¤   //}}AFX_DATA_INIT
3faf5a
7bd7e1 ¤   mParentGlobalCWiz = NULL;
3caf5a
f1535b ¤   mSkipConfirmCancel¤ = FALSE;
6f1276 ¤   mFinishedSearch¤¤   = FALSE;
4805d6 ¤   mIsThreadActive¤¤   = FALSE;
05af5a
92218f ¤   // Exorcise the big help button.
346a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
18af5a
d93b76 ¤   // Create the thread object we will use.
--5020 00062f5cfcf401100a1 Page 2 of CGlobalCWizSearchPage.cpp
8a78f1 ¤   try
bbc7a1 ¤   {
76f972 ¤   ¤   mSearchThread = new CGlobalCSearchPGPdiskThread;
15af5a
a256b7 ¤   ¤   // Don't auto-delete.
80be21 ¤   ¤   mSearchThread->m_bAutoDelete = FALSE;
682792 ¤   ¤   mIsCTAutoDelete = FALSE;
a29371 ¤   }
5d3c88 ¤   catch (CMemoryException *ex)
80c7a1 ¤   {
469a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
f66adc ¤   ¤   ex->Delete();
f09371 ¤   }
b8efe6 }
b3af5a
f45745 // The CGlobalCWizSearchPage destructor.
86af5a
fbfdeb CGlobalCWizSearchPage::~CGlobalCWizSearchPage()
f3bb36 {
6f1d21 ¤   if (!mIsCTAutoDelete)
f8c7a1 ¤   {
641e41 ¤   ¤   delete mSearchThread;
0e9371 ¤   }
94efe6 }
f8af5a
40af5a
835d1a ////////////////////////////////////////////////////////
925df6 // CGlobalCWizSearchPage public default message handlers
245d1a ////////////////////////////////////////////////////////
f7af5a
18e630 // OnFinishedSearch is called when the thread has finished searching the
4641a0 // PGPdisk.
07af5a
9ac823 void·
0fd643 CGlobalCWizSearchPage::OnFinishedSearch(WPARAM wParam, LPARAM lParam)
c4bb36 {
887d36 ¤   DualErr derr;
83af5a
6554bb ¤   pgpAssertAddrValid(mSearchThread, CGlobalCSearchPGPdiskThread);
67af5a
051262 ¤   mSearchStatusText = GetCommonString(kPGPdiskSearchingDoneMsgString);
435207 ¤   mDirNameText.Empty();
0502a1 ¤   UpdateData(FALSE);
40af5a
2c0c4a ¤   mFinishedSearch = TRUE;
15221c ¤   mIsThreadActive = FALSE;
ceaf5a
98d083 ¤   derr = mSearchThread->mDerr;
b3af5a
0d2361 ¤   if (derr.IsntError())
10c7a1 ¤   {
accbff ¤   ¤   // Enable the next button.
ac2737 ¤   ¤   mParentGlobalCWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
b0af5a
4b97d3 ¤   ¤   // Select all items.
dfa094 ¤   ¤   mPGPdisksList.SelItemRange(TRUE, 0, mPGPdisksList.GetCount());
619371 ¤   }
81af5a
6e4bb3 ¤   if (derr.IsError())
9fc7a1 ¤   {
402cd4 ¤   ¤   mParentGlobalCWiz->mDerr = derr;
67af5a
93bb4d ¤   ¤   mSkipConfirmCancel = TRUE;
00e973 ¤   ¤   mParentGlobalCWiz->PressButton(PSBTN_CANCEL);¤  // NOT EndDialog
699371 ¤   }
33efe6 }
81af5a
47477b // OnQueryCancel confirms that the user really does want to cancel.
ecaf5a
6d7efe BOOL·
d07099 CGlobalCWizSearchPage::OnQueryCancel()·
62bb36 {
--2d9e 0000c73dc56401100a1 Page 3 of CGlobalCWizSearchPage.cpp
dc6887 ¤   // Confirm cancellation of creation.
f87858 ¤   if (!mSkipConfirmCancel)
adc7a1 ¤   {
cdc2e6 ¤   ¤   if (DisplayMessage(kPGPdiskConfirmCancelSearching, kPMBS_YesNo,·
1b3286 ¤   ¤   ¤   kPMBF_NoButton) == kUR_No)
b05b34 ¤   ¤   {
5c5f1f ¤   ¤   ¤   return FALSE;
b30fe4 ¤   ¤   }
4e9371 ¤   }
aaaf5a
c9158c ¤   return CPropertyPage::OnQueryCancel();
1aefe6 }
71af5a
9ec57f // OnSetActive is called when this page is made active. We make sure the
b4c7fb // correct buttons are enabled/disabled, and begin PGPdisk searching.
a5af5a
377efe BOOL·
598e48 CGlobalCWizSearchPage::OnSetActive()·
2cbb36 {
17e5df ¤   pgpAssertAddrValid(mParentGlobalCWiz, CGlobalCWizardSheet);
9daf5a
46c139 ¤   // Ask a separate thread to search for PGPdisks.
bda834 ¤   if (!mFinishedSearch && !mIsThreadActive)
e3c7a1 ¤   {
61c5d1 ¤   ¤   SearchPGPdiskInfo¤  SPI;
764753 ¤   ¤   DualErr¤¤   ¤   ¤   derr;
f4af5a
391acc ¤   ¤   pgpAssertAddrValid(mSearchThread, CGlobalCSearchPGPdiskThread);
b85090 ¤   ¤   mParentGlobalCWiz->SetWizardButtons(NULL);
1faf5a
fd0a60 ¤   ¤   mSearchStatusText = GetCommonString(kPGPdiskSearchingSearchMsgString);
e0e040 ¤   ¤   UpdateData(FALSE);
a1af5a
01372d ¤   ¤   SPI.callerHwnd¤ = GetSafeHwnd();
89f3c1 ¤   ¤   SPI.listBoxHwnd¤= mPGPdisksList.GetSafeHwnd();
17085c ¤   ¤   SPI.dirStaticHwnd = mDirNameStatic.GetSafeHwnd();
96af5a
574447 ¤   ¤   // Start the search thread.
776b7d ¤   ¤   mIsThreadActive = TRUE;
ebcbd4 ¤   ¤   derr = mSearchThread->CallPGPdiskSearch(&SPI);
15af5a
32ad1f ¤   ¤   // Set the progress message.
5baa35 ¤   ¤   if (derr.IsntError())
605b34 ¤   ¤   {
b2b3c3 ¤   ¤   ¤   mParentGlobalCWiz->SendDlgItemMessage(IDCANCEL, WM_KILLFOCUS,·
68062d ¤   ¤   ¤   ¤   NULL, NULL);
220fe4 ¤   ¤   }
fcaf5a
4fbdd6 ¤   ¤   if (derr.IsError())
475b34 ¤   ¤   {
14a422 ¤   ¤   ¤   mIsThreadActive = FALSE;
3aaf5a
fc2a6c ¤   ¤   ¤   mParentGlobalCWiz->mDerr = derr;
029b1b ¤   ¤   ¤   mParentGlobalCWiz->EndDialog(IDCANCEL);
a60fe4 ¤   ¤   }
7a9371 ¤   }
62257f ¤   else if (mFinishedSearch)
b4c7a1 ¤   {
ea2737 ¤   ¤   mParentGlobalCWiz->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
489371 ¤   }
37af5a
34bfaa ¤   return CPropertyPage::OnSetActive();
eeefe6 }
56af5a
a94893 // OnWizardNext is called when the user clicks on the 'Next' button.
75af5a
490218 LRESULT·
980a1c CGlobalCWizSearchPage::OnWizardNext()·
40bb36 {
3c7d36 ¤   DualErr derr;
b8af5a
0c52c0 ¤   if (CPropertyPage::OnWizardNext() == -1)
--3632 000c40d1d43401100a1 Page 4 of CGlobalCWizSearchPage.cpp
e0043c ¤   ¤   return -1;
deaf5a
034cfd ¤   // Convert all selected PGPdisks.
d509d4 ¤   ConvertSelectedPGPdisks();
95af5a
923e6b ¤   return 0;
04efe6 }
7daf5a
b2af5a
41063a ////////////////////////////////////////////////////////////////////////////
78fc25 // CGlobalCWizSearchPage protected custom functions and non-default handlers
32063a ////////////////////////////////////////////////////////////////////////////
77af5a
9c69ad // The CGlobalCWizSearchPage data exchange function.
d4af5a
e6c823 void·
cb0762 CGlobalCWizSearchPage::DoDataExchange(CDataExchange *pDX)
b3bb36 {
a478f1 ¤   try
1ac7a1 ¤   {
4822a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
26af5a
ea6527 ¤   ¤   //{{AFX_DATA_MAP(CGlobalCWizSearchPage)
29f698 ¤   ¤   DDX_Control(pDX, IDC_SIDEBAR, mSidebarGraphic);
790036 ¤   ¤   DDX_Control(pDX, IDC_DIRNAME_TEXT, mDirNameStatic);
126644 ¤   ¤   DDX_Control(pDX, IDC_PGPDISKS_LIST, mPGPdisksList);
71b34e ¤   ¤   DDX_Text(pDX, IDC_DIRNAME_TEXT, mDirNameText);
82cca3 ¤   ¤   DDX_Text(pDX, IDC_SEARCHSTATUS_TEXT, mSearchStatusText);
843376 ¤   ¤   //}}AFX_DATA_MAP
1c9371 ¤   }
493c88 ¤   catch (CMemoryException *ex)
fec7a1 ¤   {
bd6adc ¤   ¤   ex->Delete();
e09371 ¤   }
a9efe6 }
6caf5a
6daf5a
9e5ea1 ////////////////////////////////////////////////////////////
ece4aa // CGlobalCWizSearchPage protected default message handlers
055ea1 ////////////////////////////////////////////////////////////
5baf5a
df18db // OnCancel is called when the cancel button is pressed.
b6af5a
c7c823 void·
bd12c0 CGlobalCWizSearchPage::OnCancel()·
1ecebb {¤
ccaf53 ¤   if (mIsThreadActive)
45c7a1 ¤   {
a2d6e7 ¤   ¤   // Tell it to delete itself since we may be gone by the time it
b9dbed ¤   ¤   // finishes the cancel.
82af5a
5b1acc ¤   ¤   pgpAssertAddrValid(mSearchThread, CGlobalCSearchPGPdiskThread);
deaf5a
a16076 ¤   ¤   mIsCTAutoDelete = TRUE;
63323b ¤   ¤   mSearchThread->m_bAutoDelete = TRUE;
e4af5a
886138 ¤   ¤   mSearchThread->CancelPGPdiskSearch();
879371 ¤   }
47af5a
8863f3 ¤   CPropertyPage::OnCancel();
edefe6 }
4baf5a
bd8cca // OnHelpInfo handles context-sensitive help.
3baf5a
0c7efe BOOL·
8a09d6 CGlobalCWizSearchPage::OnHelpInfo(HELPINFO *pHelpInfo)
34bb36 {
2329b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
a0e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
b3c7a1 ¤   {
e4ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
c46b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
--11ff 0003324b734401100a1 Page 5 of CGlobalCWizSearchPage.cpp
a19371 ¤   }
93af5a
07c2e7 ¤   return TRUE;
77efe6 }
32af5a
129c68 // We override OnPaint to draw the sidebar graphic at the correct depth.
7baf5a
91c823 void·
dde6cc CGlobalCWizSearchPage::OnPaint()·
92bb36 {
050575 ¤   CDC¤¤   ¤   memDC;
adc943 ¤   CPaintDC¤   DC(this);
ffe3a1 ¤   HBITMAP¤¤   oldBitmap;
30b2e4 ¤   RECT¤   ¤   sidebarRect;
bbaf5a
d848d1 ¤   DC.SelectPalette(&mParentGlobalCWiz->mSidebarPalette, FALSE);
91cf08 ¤   DC.RealizePalette();
58af5a
82ce55 ¤   memDC.CreateCompatibleDC(&DC);
3bb0f2 ¤   memDC.SelectPalette(&mParentGlobalCWiz->mSidebarPalette, FALSE);
47bb83 ¤   memDC.RealizePalette();
19af5a
dd7fc5 ¤   mSidebarGraphic.GetWindowRect(&sidebarRect);
d27564 ¤   ScreenToClient(&sidebarRect);
5267c5 ¤
900eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
ece162 ¤   // don't fool with it.
96af5a
a9ed0e ¤   oldBitmap = (HBITMAP) SelectObject(memDC,·
d9d433 ¤   ¤   mParentGlobalCWiz->mSidebarBitmap);
eaaf5a
cc96b7 ¤   DC.BitBlt(sidebarRect.left, sidebarRect.top, sidebarRect.right,·
c1eefb ¤   ¤   sidebarRect.bottom, &memDC, 0, 0, SRCCOPY);
b6af5a
65ac4f ¤   memDC.SelectObject(oldBitmap);
e763a9 ¤   memDC.DeleteDC();
7befe6 }
5aaf5a
5d64b7 // ConvertSelectedPGPdisks converts all selected PGPdisks.
37af5a
ddc823 void·
202ab2 CGlobalCWizSearchPage::ConvertSelectedPGPdisks()
d8bb36 {
9978f1 ¤   try
bdc7a1 ¤   {
c514e6 ¤   ¤   PGPUInt32 numSelected = mPGPdisksList.GetSelCount();
49af5a
f91014 ¤   ¤   // If there are any PGPdisk selected...
d9d509 ¤   ¤   if (numSelected > 0)
e25b34 ¤   ¤   {
17d18e ¤   ¤   ¤   int¤¤   ¤   *indexArray;
7dde29 ¤   ¤   ¤   PGPUInt32¤  i;
1aaf5a
5aab81 ¤   ¤   ¤   indexArray = new int[numSelected];
6a1dac ¤   ¤   ¤   mPGPdisksList.GetSelItems(numSelected, indexArray);
e9af5a
96570e ¤   ¤   ¤   // ... for each PGPdisk selected..
b0f203 ¤   ¤   ¤   for (i = 0; i < numSelected; i++)
f0f776 ¤   ¤   ¤   {
1b8fb5 ¤   ¤   ¤   ¤   CString¤¤   path;
c9c7a8 ¤   ¤   ¤   ¤   DualErr¤¤   derr;
3f5f7b ¤   ¤   ¤   ¤   PGPBoolean¤ userSaysCancel¤ = FALSE;
17af5a
e18ed3 ¤   ¤   ¤   ¤   mPGPdisksList.GetText(indexArray[i], path);
b3af5a
0bdcac ¤   ¤   ¤   ¤   // ... convert it.
e6d6aa ¤   ¤   ¤   ¤   derr = App->ConvertPGPdiskFromGlobalWizard(path,·
02be6d ¤   ¤   ¤   ¤   ¤   &userSaysCancel);
4eaf5a
18724e ¤   ¤   ¤   ¤   if (derr.IsntError())
1272c3 ¤   ¤   ¤   ¤   {
33859e ¤   ¤   ¤   ¤   ¤   if (userSaysCancel)
--ebd2 001b183fb65401100a1 Page 6 of CGlobalCWizSearchPage.cpp
d300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
cd2613 ¤   ¤   ¤   ¤   }
a3af5a
809b74 ¤   ¤   ¤   ¤   if (derr.IsError())
5572c3 ¤   ¤   ¤   ¤   {
aa1487 ¤   ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskConversionFailed, derr);
c82613 ¤   ¤   ¤   ¤   }
45a3a6 ¤   ¤   ¤   }
c3af5a
aebef4 ¤   ¤   ¤   delete[] indexArray;
6b0fe4 ¤   ¤   }
a89371 ¤   }
153c88 ¤   catch (CMemoryException *ex)
f5c7a1 ¤   {
536adc ¤   ¤   ex->Delete();
1a9371 ¤   }
b1efe6 }
--dd41 0004fd49fcc401100a2 Page 1 of CGlobalCWizSearchPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
dffe1c // CGlobalCWizSearchPage.h
0d465d //
c0c10d // Declaration of class CGlobalCWizSearchPage.
0a1bc3 //////////////////////////////////////////////////////////////////////////////
03af5a
91d4d4 // $Id: CGlobalCWizSearchPage.h,v 1.1.2.3 1998/10/26 00:07:01 nryan Exp $
dbaf5a
40cbce // Copyright (C) 1998 by Network Associates, Inc.
0871ae // All rights reserved.
e1af5a
1530d1 #ifndef Included_CGlobalCWizSearchPage_h¤   // [
637b4e #define Included_CGlobalCWizSearchPage_h
e2af5a
3a3a85 #include "DualErr.h"
72af5a
5cbdb6 #include "CGlobalCSearchPGPdiskThread.h"
b0ab81 #include "Resource.h"
47af5a
bfaf5a
edd557 ////////
9b02c9 // Types
7ad557 ////////
6baf5a
1124dd class CGlobalCWizardSheet;
26af5a
88af5a
03c7c6 ///////////////////////////////
b5267a // Class CGlobalCWizSearchPage
44c7c6 ///////////////////////////////
f4af5a
e65eca class CGlobalCWizSearchPage : public CPropertyPage
37bb36 {
881758 ¤   DECLARE_DYNCREATE(CGlobalCWizSearchPage)
f4af5a
ed5ed4 public:
0fda7a ¤   CGlobalCWizardSheet *mParentGlobalCWiz;¤¤   // pointer to parent sheet
05fb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
e5af5a
068651 ¤   CGlobalCWizSearchPage();
e3cf2b ¤   ~CGlobalCWizSearchPage();
76af5a
7d1557 ¤   //{{AFX_DATA(CGlobalCWizSearchPage)
d67982 ¤   enum { IDD = IDD_GLOBWIZ_SEARCH };
c345be ¤   CStatic¤mSidebarGraphic;
7f6a65 ¤   CStatic¤mDirNameStatic;
fdf615 ¤   CListBox¤   mPGPdisksList;
25b522 ¤   CString¤mDirNameText;
861a85 ¤   CString¤mSearchStatusText;
875139 ¤   //}}AFX_DATA
6eaf5a
1575fc ¤   //{{AFX_VIRTUAL(CGlobalCWizSearchPage)
5267d4 ¤   public:
d46e36 ¤   virtual BOOL OnSetActive();
dea2ce ¤   virtual LRESULT OnWizardNext();
f2d8cf ¤   virtual void OnCancel();
c46275 ¤   virtual BOOL OnQueryCancel();
adc369 ¤   protected:
8a3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
fbaf53 ¤   //}}AFX_VIRTUAL
0baf5a
87a2d3 protected:
ba2448 ¤   CGlobalCSearchPGPdiskThread¤*mSearchThread;¤¤   // PGPdisk search thread
67ee54 ¤   PGPBoolean¤ ¤   ¤   ¤   ¤   mIsCTAutoDelete;¤   // will it delete itself?
9c4af7 ¤   PGPBoolean¤ ¤   ¤   ¤   ¤   mSkipConfirmCancel;¤// to skip confirm cancel
c5af5a
9c7848 ¤   PGPBoolean¤ ¤   ¤   ¤   ¤   mIsThreadActive;¤   // is the thread active?
0f35c6 ¤   PGPBoolean¤ ¤   ¤   ¤   ¤   mFinishedSearch;¤   // done with search?
ecaf5a
764641 ¤   void ConvertSelectedPGPdisks();
85af5a
4fc0b5 ¤   //{{AFX_MSG(CGlobalCWizSearchPage)
--604e 0015edda6d5401100a2 Page 2 of CGlobalCWizSearchPage.h
1e575c ¤   afx_msg void OnFinishedSearch(WPARAM wParam, LPARAM lParam);
d5698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
8dc5f3 ¤   afx_msg void OnPaint();
822e09 ¤   //}}AFX_MSG
9aaf5a
692409 ¤   DECLARE_MESSAGE_MAP()
1982f7 };
33af5a
ffc18c //{{AFX_INSERT_LOCATION}}
0daf5a
5e6d0e #endif¤ // ] Included_CGlobalCWizSearchPage_h
--121c 000920ee98b401100a3 Page 1 of CGlobalCWizardSheet.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
35769b // CGlobalCWizardSheet.cpp
af465d //
4a7449 // Implementation of class CGlobalCWizardSheet.
c01bc3 //////////////////////////////////////////////////////////////////////////////
79af5a
fc5874 // $Id: CGlobalCWizardSheet.cpp,v 1.1.2.1 1998/10/22 22:27:40 nryan Exp $
14af5a
e1cbce // Copyright (C) 1998 by Network Associates, Inc.
4571ae // All rights reserved.
24af5a
9a9e12 #include "StdAfx.h"
35b8af #include <new.h>
40af5a
d49bcf #include "Required.h"
cb993c #include "StringAssociation.h"
d5af5a
8a31a0 #include "CGlobalCWizardSheet.h"
22c411 #include "Globals.h"
924713 #include "PGPdiskHelpIds.h"
94af5a
0daf5a
116cc2 /////////////////////
133a71 // Context help array
d66cc2 /////////////////////
69af5a
fc77bf static PGPUInt32 HelpIds[] =
8dbb36 {
2f8515 ¤   IDCANCEL,¤  ¤   IDH_PGPDISKAPP_DISKWIZSHEETCANCEL,·
e26cf9 ¤   ID_WIZBACK,¤¤   IDH_PGPDISKAPP_DISKWIZSHEETBACK,·
34d0c1 ¤   ID_WIZNEXT,¤¤   IDH_PGPDISKAPP_DISKWIZSHEETNEXT,·
910232 ¤   ID_WIZFINISH,¤  IDH_PGPDISKAPP_DISKWIZSHEETFINISH,·
574434 ····0,0·
ab82f7 };
d1af5a
cfaf5a
6083f5 ///////////////////////////
cbb249 // MFC specific definitions
ae83f5 ///////////////////////////
a0af5a
c3f33f BEGIN_MESSAGE_MAP(CGlobalCWizardSheet, CPropertySheet)
383457 ¤   //{{AFX_MSG_MAP(CGlobalCWizardSheet)
c9db65 ¤   ON_WM_HELPINFO()
139e4e ¤   ON_BN_CLICKED(IDHELP, OnHelp)
a6dfd1 ¤   ON_WM_SYSCOMMAND()
86044a ¤   //}}AFX_MSG_MAP
2caf28 END_MESSAGE_MAP()
14af5a
5baf5a
90a6b9 ///////////////////////////////////////////////////////////////////////
3eeed6 // CGlobalCWizardSheet public custom functions and non-default handlers
68a6b9 ///////////////////////////////////////////////////////////////////////
d3af5a
c97de9 IMPLEMENT_DYNAMIC(CGlobalCWizardSheet, CPropertySheet)
85af5a
2c597c // The CGlobalCWizardSheet constructor adds the wizard pages we implement
d74370 // to the wizard sheet.
46af5a
e059f9 CGlobalCWizardSheet::CGlobalCWizardSheet() :
273b78 ¤   ¤   CPropertySheet(GetCommonString(kPGPdiskGlobalCWizSheetTitleString),·
f260e9 ¤   ¤   ¤   NULL, 0)
92bb36 {
9178f1 ¤   try
d8c7a1 ¤   {
21d5fd ¤   ¤   mDonePage.mParentGlobalCWiz¤¤   = this;
fa3627 ¤   ¤   mIntroPage.mParentGlobalCWiz¤   = this;
b32e98 ¤   ¤   mSearchPage.mParentGlobalCWiz¤  = this;
d6af5a
4a97f2 ¤   ¤   AddPage(&mIntroPage);
212913 ¤   ¤   AddPage(&mSearchPage);
dc0f67 ¤   ¤   AddPage(&mDonePage);
92af5a
--55e3 000f97f85c4401100a3 Page 2 of CGlobalCWizardSheet.cpp
fb2462 ¤   ¤   // Exorcise the big help button.
d868a4 ¤   ¤   m_psh.dwFlags &= ~PSH_HASHELP;
979371 ¤   }
903c88 ¤   catch (CMemoryException *ex)
e9c7a1 ¤   {
729a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
a46adc ¤   ¤   ex->Delete();
5e9371 ¤   }
b3efe6 }
16af5a
5f5af2 // The CGlobalCWizardSheet destructor.
5aaf5a
cfda06 CGlobalCWizardSheet::~CGlobalCWizardSheet()
21bb36 {
7cefe6 }
45af5a
1afbd7 // ExecuteWizard displays the wizard and searches for unconverted PGPdisks.
7eaf5a
fa2292 DualErr·
241bff CGlobalCWizardSheet::ExecuteWizard()
28bb36 {
027d36 ¤   DualErr derr;
abaf5a
1078f1 ¤   try
9dc7a1 ¤   {
381ff9 ¤   ¤   PGPInt32 result;
73af5a
08ef17 ¤   ¤   SetWizardMode();
30af5a
6413a9 ¤   ¤   // Invoke the wizard.
b8fcae ¤   ¤   result = DoModal();
2baf5a
86b507 ¤   ¤   switch (result)
f95b34 ¤   ¤   {
a956e8 ¤   ¤   case -1:
7839a7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
0fcdcb ¤   ¤   ¤   break;
a6af5a
2d71eb ¤   ¤   case IDCANCEL:
01af5a
2b9d29 ¤   ¤   ¤   derr = mDerr;
c5af5a
fa9d3d ¤   ¤   ¤   if (derr.IsntError())
d295a9 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
96af5a
c5cdcb ¤   ¤   ¤   break;
12af5a
539ae3 ¤   ¤   default:
709d29 ¤   ¤   ¤   derr = mDerr;
6bcdcb ¤   ¤   ¤   break;
c70fe4 ¤   ¤   }
e91b52 ¤   ¤
a09371 ¤   }
763c88 ¤   catch (CMemoryException *ex)
bfc7a1 ¤   {
4d6adc ¤   ¤   ex->Delete();
0becf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
159371 ¤   }
4daf5a
ed33e3 ¤   return derr;
56efe6 }
95af5a
38af5a
ce19ca /////////////////////////////////////////////////
a5a2aa // CGlobalCWizardSheet protected default handlers
3c19ca /////////////////////////////////////////////////
f0af5a
f18cca // OnHelpInfo handles context-sensitive help.
c0af5a
cd7efe BOOL·
56f202 CGlobalCWizardSheet::OnHelpInfo(HELPINFO *pHelpInfo)
f9bb36 {
--dcfc 0000a2a51d8401100a3 Page 3 of CGlobalCWizardSheet.cpp
2029b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
50e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
08c7a1 ¤   {
b3ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
be6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
9a9371 ¤   }
51af5a
59c2e7 ¤   return TRUE;
3cefe6 }
14af5a
f37e66 // OnInitDialog is called during dialog initialization. We take the
94479b // opportunity to add a context help button to the title bar.
99af5a
757efe BOOL·
deb8a3 CGlobalCWizardSheet::OnInitDialog()·
b6bb36 {
a9f334 ¤   CMenu¤  ¤   *pSysMenu;
e018a8 ¤   HDC¤¤   ¤   hDC;
3b1b02 ¤   PGPBoolean¤ loadedBitmap;
4f2e01 ¤   PGPUInt32¤  numBits;
54af5a
ee1450 ¤   CPropertySheet::OnInitDialog();
9faf5a
7f9c14 ¤   // Get screen depth.
5aff18 ¤   hDC = ::GetDC(NULL);¤   ¤   // DC for desktop
823968 ¤   numBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
d76ec2 ¤   ::ReleaseDC(NULL, hDC);
2faf5a
b2ec20 ¤   // Load the bitmap and create a palette for it.
e44932 ¤   if (numBits <= 1)
73c7a1 ¤   {
a9c154 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR1,·
087869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
d79371 ¤   }
f6d872 ¤   else if (numBits <= 4)
e8c7a1 ¤   {
5faf03 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR4,·
177869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
aa9371 ¤   }
030e24 ¤   else
72c7a1 ¤   {
303837 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SIDEBAR8,·
d57869 ¤   ¤   ¤   &mSidebarBitmap, &mSidebarPalette);
ca9371 ¤   }
60af5a
1c5720 ¤   // Need to give the dialog a close box if we want a help box as well.
00a616 ¤   ModifyStyle(NULL, WS_SYSMENU, NULL);
8daf5a
635d47 ¤   // Show the context help button.
fb7f87 ¤   ModifyStyleEx(NULL, WS_EX_CONTEXTHELP, NULL);
89af5a
c50475 ¤   // Alter the system menu.
fa4645 ¤   pSysMenu = GetSystemMenu(FALSE);
a8e9f0 ¤   pgpAssertAddrValid(pSysMenu, CMenu);
a8af5a
e252ba ¤   pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
d16825 ¤   pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
25d6e9 ¤   pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
48e0bf ¤   pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
3aaf5a
32129c ¤   DrawMenuBar();
64af5a
13d564 ¤   // Center on screen.
9350f9 ¤   CenterWindow(GetDesktopWindow());
d3af5a
a8afdc ¤   // Put us in front.
519974 ¤   SetForegroundWindow();
fcaf5a
4c54ed ¤   // Put on top if necessary.
94c3a9 ¤   App->TweakOnTopAttribute(this);
8baf5a
0ac2e7 ¤   return TRUE;
--397a 00148376e85401100a3 Page 4 of CGlobalCWizardSheet.cpp
7aefe6 }
46af5a
74915f // OnSysCommand is handled to trap close requests.
2caf5a
a6c823 void·
223463 CGlobalCWizardSheet::OnSysCommand(UINT nID, LPARAM lParam)·
29bb36 {
e11f71 ¤   if (nID == SC_CLOSE)
09f5fa ¤   ¤   mDerr = DualErr(kPGDMinorError_UserAbort);
8767c5 ¤
3dcc0b ¤   CPropertySheet::OnSysCommand(nID, lParam);
48efe6 }
--c7db 0017a8a69a1401100a4 Page 1 of CGlobalCWizardSheet.h
541bc3 //////////////////////////////////////////////////////////////////////////////
11bc60 // CGlobalCWizardSheet.h
f4465d //
15e02d // Declaration of class CGlobalCWizardSheet.
621bc3 //////////////////////////////////////////////////////////////////////////////
3eaf5a
c08764 // $Id: CGlobalCWizardSheet.h,v 1.1.2.1 1998/10/22 22:27:42 nryan Exp $
f4af5a
8dcbce // Copyright (C) 1998 by Network Associates, Inc.
9671ae // All rights reserved.
74af5a
b4b13d #ifndef Included_CGlobalCWizardSheet_h¤ // [
74103a #define Included_CGlobalCWizardSheet_h
66af5a
093a85 #include "DualErr.h"
41af5a
89d9dd #include "CGlobalCWizDonePage.h"
508890 #include "CGlobalCWizIntroPage.h"
5b983d #include "CGlobalCWizSearchPage.h"
4eaf5a
93af5a
225270 ////////////////////////////
294c74 // Class CGlobalCWizardSheet
3f5270 ////////////////////////////
a7af5a
8a5f34 class CGlobalCWizardSheet : public CPropertySheet
59bb36 {
f53a8f ¤   DECLARE_DYNAMIC(CGlobalCWizardSheet)
33af5a
3fa632 ¤   friend class CGlobalCWizDonePage;
cec8df ¤   friend class CGlobalCWizIntroPage;
775ec4 ¤   friend class CGlobalCWizSearchPage;
1faf5a
055ed4 public:
4eda4d ¤   DualErr¤mInitErr;
8daf5a
15c403 ¤   ¤   ¤   CGlobalCWizardSheet();
98475d ¤   virtual¤~CGlobalCWizardSheet();
86af5a
26cc0f ¤   DualErr¤ExecuteWizard();
afaf5a
d68343 ¤   //{{AFX_VIRTUAL(CGlobalCWizardSheet)
2467d4 ¤   public:
88f17a ¤   virtual BOOL OnInitDialog();
55af53 ¤   //}}AFX_VIRTUAL
b1af5a
27a2d3 protected:
2d567f ¤   CGlobalCWizDonePage¤¤   ¤   mDonePage;¤ ¤   ¤   // convert done page
97921a ¤   CGlobalCWizIntroPage¤   ¤   mIntroPage;¤¤   ¤   // convert intro page
ed6117 ¤   CGlobalCWizSearchPage¤  ¤   mSearchPage;¤   ¤   // search page
27af5a
1c76cc ¤   DualErr¤¤   ¤   mDerr;¤ ¤   ¤   ¤   // pages report¤errors here
c7af5a
ad30a6 ¤   CBitmap¤¤   ¤   mSidebarBitmap;¤¤   // sidebar graphic
88ab29 ¤   CPalette¤   ¤   mSidebarPalette;¤   // sidebar palette
4caf5a
ec1fc7 ¤   //{{AFX_MSG(CGlobalCWizardSheet)
025d0f ¤   afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
b34d01 ¤   afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
b02e09 ¤   //}}AFX_MSG
e2af5a
5f2409 ¤   DECLARE_MESSAGE_MAP()
b382f7 };
f8af5a
7fc18c //{{AFX_INSERT_LOCATION}}
27af5a
7a39c3 #endif // ] Included_CGlobalCWizardSheet_h
--634c 0002394da4f401100a5 Page 1 of CMainDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
6d394b // CMainDialog.cpp
66465d //
c2f3ba // Implementation of the CMainDialog class.
7e1bc3 //////////////////////////////////////////////////////////////////////////////
67af5a
f7124b // $Id: CMainDialog.cpp,v 1.1.2.16.2.2 1998/10/25 23:31:25 nryan Exp $
27af5a
b2cbce // Copyright (C) 1998 by Network Associates, Inc.
a271ae // All rights reserved.
b6af5a
6e9e12 #include "StdAfx.h"
94af5a
2e9bcf #include "Required.h"
80babe #include "PGPdiskRegistry.h"
a4af5a
2c3646 #include "CMainDialog.h"
53c411 #include "Globals.h"
404713 #include "PGPdiskHelpIds.h"
b4af5a
33af5a
4109b7 ////////////
a8e738 // Constants
2a09b7 ////////////
adaf5a
e0270a // Size constants for the main window.
6b4a1f const PGPUInt32¤kWidthLargeMainDialog¤  = 268;
0d561d const PGPUInt32¤kHeightLargeMainDialog¤ = 69;
f1c7f0 const PGPUInt32¤kWidthSmallMainDialog¤  = 132;
d90f01 const PGPUInt32¤kHeightSmallMainDialog¤ = 36;
05af5a
42e10b // Horizontal bias constants for the main window buttons.
3c57b7 const PGPUInt32¤kBigButtonXBias¤¤   ¤   = 1;
f7c4fe const PGPUInt32¤kBigButtonYBias¤¤   ¤   = 1;
31e844 const PGPUInt32¤kSmallButtonXBias¤  ¤   = 1;
33172f const PGPUInt32¤kSmallButtonYBias¤  ¤   = 2;
10af5a
821292 // Size constants for the main window buttons
d04fa9 const PGPUInt32¤kSideLengthBigButton¤   = 66;
a42280 const PGPUInt32¤kSideLengthSmallButton¤ = 32;
99af5a
b35bde // Size constants for the main window button icons.
007f8e const PGPUInt32¤kSideLengthBigIcon¤ ¤   = 60;
42690d const PGPUInt32¤kSideLengthSmallIcon¤   = 25;
24af5a
85af5a
b86cc2 /////////////////////
343a71 // Context help array
c86cc2 /////////////////////
44af5a
3e77bf static PGPUInt32 HelpIds[] =
60bb36 {
3c5346 ¤   IDC_NEWPGPDISK,¤¤   ¤   IDH_PGPDISKAPP_MAINNEW,·
5ffe3c ¤   IDC_MOUNTPGPDISK,¤  ¤   IDH_PGPDISKAPP_MAINMOUNT,·
5f9002 ¤   IDC_UNMOUNTPGPDISK,¤¤   IDH_PGPDISKAPP_MAINUNMOUNT,·
0dd96d ¤   IDC_PREFERENCES,¤   ¤   IDH_PGPDISKAPP_MAINPREFS,·
4d4434 ····0,0·
0982f7 };
b7af5a
a9af5a
1983f5 ///////////////////////////
b2b249 // MFC specific definitions
7383f5 ///////////////////////////
83af5a
115450 BEGIN_MESSAGE_MAP(CMainDialog, CDialog)
82c0eb ¤   //{{AFX_MSG_MAP(CMainDialog)
ab4a8e ¤   ON_WM_DESTROY()
b42fa5 ¤   ON_WM_PAINT()
2d2f9d ¤   ON_WM_QUERYDRAGICON()
40c0da ¤   ON_COMMAND(IDM_ABOUT, OnAboutBox)
8d8c13 ¤   ON_COMMAND(IDM_ADDPASS, OnAddPassphrase)
232157 ¤   ON_COMMAND(IDM_CHANGEPASS, OnChangePassphrase)
--4638 0002b448edc401100a5 Page 2 of CMainDialog.cpp
78eba1 ¤   ON_WM_DROPFILES()
b9b94b ¤   ON_COMMAND(IDM_REMOVEALL, OnRemoveAlternates)
e0b4a7 ¤   ON_COMMAND(IDM_REMOVEPASS, OnRemovePassphrase)
216965 ¤   ON_COMMAND(IDM_EXIT, OnExit)
6ed539 ¤   ON_BN_CLICKED(IDC_MOUNTPGPDISK, OnMountPGPdisk)
9005ef ¤   ON_COMMAND(IDM_UNMOUNTPGPDISK, OnUnmountPGPdisk)
90b776 ¤   ON_BN_CLICKED(IDC_NEWPGPDISK, OnNewPGPdisk)
4e8fe4 ¤   ON_BN_CLICKED(IDC_PREFERENCES, OnPreferences)
8eca3b ¤   ON_COMMAND(IDM_HELPCONTENTS, OnHelpContents)
bedf96 ¤   ON_WM_CLOSE()
2ef00e ¤   ON_WM_INITMENU()
62db65 ¤   ON_WM_HELPINFO()
efdfd1 ¤   ON_WM_SYSCOMMAND()
ac276d ¤   ON_WM_SIZING()
7d1851 ¤   ON_WM_SIZE()
89e279 ¤   ON_COMMAND(IDM_MOUNTPGPDISK, OnMountPGPdisk)
a205ef ¤   ON_COMMAND(IDM_UNMOUNTPGPDISK, OnUnmountPGPdisk)
b0e5af ¤   ON_COMMAND(IDM_NEWPGPDISK, OnNewPGPdisk)
74f684 ¤   ON_COMMAND(IDM_PREFS, OnPreferences)
a48cf7 ¤   ON_COMMAND(IDM_PUBLICKEYS, OnAddRemovePublicKeys)
222447 ¤   ON_COMMAND(IDM_GLOBALCONVERT, OnGlobalConvert)
c619f3 ¤   ON_BN_CLICKED(IDC_UNMOUNTPGPDISK, OnUnmountPGPdisk)
7d044a ¤   //}}AFX_MSG_MAP
aaaf5a
20af28 END_MESSAGE_MAP()
38af5a
49af5a
0aa6b9 ///////////////////////////////////////////////////////////////////////
ba0441 // CMainDialog public custom functions and non-default message handlers
a0a6b9 ///////////////////////////////////////////////////////////////////////
c9af5a
e18b49 // The CMainDialog constructor.
14af5a
887b5e CMainDialog::CMainDialog(CWnd *pParent) : CDialog(CMainDialog::IDD, pParent)
99bb36 {
d140b9 ¤   //{{AFX_DATA_INIT(CMainDialog)
e3b1e8 ¤   //}}AFX_DATA_INIT
79af5a
5ed7ff ¤   mAccelTable = NULL;
435416 ¤   mHIcon = App->LoadIcon(IDI_MAINFRAME);
e7af5a
df2793 ¤   mArePastInitDialog = FALSE;
56af5a
8defe6 }
d2af5a
c60217 // The CMainDialog destructor.
9ea992 CMainDialog::~CMainDialog()
72bb36 {
8e113c ¤   if (IsntNull(m_hWnd))
0f9855 ¤   ¤   DestroyWindow();
92efe6 }
c2af5a
24e5ca // We override PreTranslateMessage so we can handle accelerators, the escape
81393c // key, and the return key properly.
13af5a
097efe BOOL·
825c90 CMainDialog::PreTranslateMessage(MSG *pMsg)·
b2bb36 {
0762d7 ¤   PGPBoolean weProcessed = FALSE;
02af5a
6e2497 ¤   if (mAccelTable && TranslateAccelerator(m_hWnd, mAccelTable, pMsg))
75c7a1 ¤   {
df7e69 ¤   ¤   weProcessed = TRUE;
de9371 ¤   }
94ecd1 ¤   else if (pMsg->message == WM_KEYDOWN)
98c7a1 ¤   {
cf7189 ¤   ¤   PGPUInt8 vCode = pMsg->wParam & 0x7F;
dbaf5a
848e34 ¤   ¤   switch (vCode)
615b34 ¤   ¤   {
7401f8 ¤   ¤   case VK_ESCAPE:
2b81e3 ¤   ¤   ¤   // Ignore the escape key.
--8ab3 0006027123b401100a5 Page 3 of CMainDialog.cpp
f1d337 ¤   ¤   ¤   weProcessed = TRUE;
d1cdcb ¤   ¤   ¤   break;
85af5a
1dfc6b ¤   ¤   case VK_RETURN:
c39db4 ¤   ¤   ¤   // Letting MFC handle return results in main dialog going away.
f14ae0 ¤   ¤   ¤   if (HasFocus(&mNewButton))
bdc1d9 ¤   ¤   ¤   ¤   PostMessage(WM_COMMAND, IDM_NEWPGPDISK, NULL);
5927a3 ¤   ¤   ¤   else if (HasFocus(&mMountButton))
9e44f6 ¤   ¤   ¤   ¤   PostMessage(WM_COMMAND, IDM_MOUNTPGPDISK, NULL);
8e75a8 ¤   ¤   ¤   else if (HasFocus(&mUnmountButton))
7db620 ¤   ¤   ¤   ¤   PostMessage(WM_COMMAND, IDM_UNMOUNTPGPDISK, NULL);
a79a62 ¤   ¤   ¤   else if (HasFocus(&mPrefsButton))
75fe3e ¤   ¤   ¤   ¤   PostMessage(WM_COMMAND, IDM_PREFS, NULL);
c6af5a
b2d337 ¤   ¤   ¤   weProcessed = TRUE;
81cdcb ¤   ¤   ¤   break;
9a0fe4 ¤   ¤   }
589371 ¤   }
49af5a
8b27c4 ¤   if (weProcessed)
6f836c ¤   ¤   return TRUE;
620e24 ¤   else
f735e8 ¤   ¤   return CDialog::PreTranslateMessage(pMsg);
32efe6 }
5faf5a
76af5a
544a2a //////////////////////////////////////////////////////////////////////////
8e1d74 // CMainDialog protected custom functions and non-default message handlers
724a2a //////////////////////////////////////////////////////////////////////////
5caf5a
b72c07 // ShowMainMenu shows the main menu, loading it if necessary.
d6af5a
ac2292 DualErr·
6dc1b8 CMainDialog::ShowMainMenu()
c5bb36 {
297d36 ¤   DualErr derr;
7aaf5a
81461a ¤   // Load the main menu if it's not loaded already
bb598d ¤   if (IsNull(mMainMenu.GetSafeHmenu()))
61c7a1 ¤   {
810cea ¤   ¤   if (!mMainMenu.LoadMenu(IDR_MAIN_MENU))
3e5b34 ¤   ¤   {
22d525 ¤   ¤   ¤   mInitErr = kPGDMinorError_DialogDisplayFailed;
e00fe4 ¤   ¤   }
819371 ¤   }
05af5a
7c7391 ¤   // Show the main menu if it's not shown already.
e32361 ¤   if (derr.IsntError())
c1c7a1 ¤   {
00e2f1 ¤   ¤   if (IsNull(GetMenu()))
745b34 ¤   ¤   {
3e34d8 ¤   ¤   ¤   // Display the main menu.
7ea19c ¤   ¤   ¤   if (!SetMenu(&mMainMenu))
24f776 ¤   ¤   ¤   {
881627 ¤   ¤   ¤   ¤   derr = kPGDMinorError_DialogDisplayFailed;
c6a3a6 ¤   ¤   ¤   }
28af5a
428aa5 ¤   ¤   #if !PGPDISK_PUBLIC_KEY
ae2a13 ¤   ¤   ¤   GetMenu()->DeleteMenu(IDM_PUBLICKEYS, MF_BYCOMMAND);
e3413d ¤   ¤   #endif¤ // !PGPDISK_PUBLIC_KEY
290fe4 ¤   ¤   }
c89371 ¤   }
01af5a
7b33e3 ¤   return derr;
66efe6 }
05af5a
403ce2 // HideMainMenu hides the main menu.
75af5a
0ec823 void·
dea046 CMainDialog::HideMainMenu()
d8bb36 {
6077d4 ¤   pgpAssert(IsntNull(mMainMenu.GetSafeHmenu()));
--c68c 0001f5f21e0401100a5 Page 4 of CMainDialog.cpp
e0af5a
b430f3 ¤   SetMenu(NULL);
0cefe6 }
ffaf5a
07d107 // ConvertMainDialogToLarge enlarges the dialog and its buttons, and shows the
524b00 // menubar.
dbaf5a
33c823 void·
1d60ec CMainDialog::ConvertMainDialogToLarge()
a5bb36 {
7cc9a5 ¤   PGPInt32¤   edgeX¤  ¤   = GetSystemMetrics(SM_CXFIXEDFRAME);
198174 ¤   PGPInt32¤   edgeY¤  ¤   = GetSystemMetrics(SM_CYFIXEDFRAME);
66edb6 ¤   PGPInt32¤   captionY¤   = GetSystemMetrics(SM_CYCAPTION);
9d4306 ¤   PGPInt32¤   menuY¤  ¤   = GetSystemMetrics(SM_CYMENU);
2d469c ¤   PGPInt32¤   largeSizeX, largeSizeY;
1faf5a
a3d8d9 ¤   mAreWeInLargeMode = TRUE;
25af5a
7d1562 ¤   // Show the main menu.
f18b29 ¤   ShowMainMenu();
56af5a
61fce8 ¤   // Resize the dialog.
64d035 ¤   largeSizeX¤ = kWidthLargeMainDialog + edgeX * 2;
fd800d ¤   largeSizeY¤ = kHeightLargeMainDialog + edgeY * 2 + captionY + menuY;
d6af5a
aec5f5 ¤   SetWindowPos(NULL, 0, 0, largeSizeX, largeSizeY,·
2b838b ¤   ¤   SWP_NOMOVE | SWP_NOZORDER);
1faf5a
7adc89 ¤   // Move and resize the buttons.
25c8d4 ¤   mNewButton.MoveWindow(kBigButtonXBias, kBigButtonYBias,·
ac8878 ¤   ¤   kSideLengthBigButton, kSideLengthBigButton);
9dfaa3 ¤   mMountButton.MoveWindow(kSideLengthBigButton + kBigButtonXBias,·
827277 ¤   ¤   kBigButtonYBias, kSideLengthBigButton, kSideLengthBigButton);
b4cade ¤   mUnmountButton.MoveWindow(kSideLengthBigButton*2 + kBigButtonXBias,·
ff7277 ¤   ¤   kBigButtonYBias, kSideLengthBigButton, kSideLengthBigButton);
3592fd ¤   mPrefsButton.MoveWindow(kSideLengthBigButton*3 + kBigButtonXBias,·
ab7277 ¤   ¤   kBigButtonYBias, kSideLengthBigButton, kSideLengthBigButton);
21af5a
93b52a ¤   // Load the big icons.
f11251 ¤   mMountButton.SetIcon(mMountBigIcon);
361696 ¤   mNewButton.SetIcon(mNewBigIcon);
99ff4a ¤   mPrefsButton.SetIcon(mPrefsBigIcon);
ad993b ¤   mUnmountButton.SetIcon(mUnmountBigIcon);
3cefe6 }
40af5a
1abea1 // ConvertMainDialogToSmall shrinks the dialog and its buttons, and hides the
b93eb5 // the menubar.
a2af5a
c9c823 void·
7fcbfe CMainDialog::ConvertMainDialogToSmall()
c1bb36 {
77c9a5 ¤   PGPInt32¤   edgeX¤  ¤   = GetSystemMetrics(SM_CXFIXEDFRAME);
208174 ¤   PGPInt32¤   edgeY¤  ¤   = GetSystemMetrics(SM_CYFIXEDFRAME);
ddedb6 ¤   PGPInt32¤   captionY¤   = GetSystemMetrics(SM_CYCAPTION);
63d423 ¤   PGPInt32¤   smallSizeX, smallSizeY;
c0af5a
427ad7 ¤   mAreWeInLargeMode = FALSE;
70af5a
ed3484 ¤   // Load the small icons.
3db540 ¤   mMountButton.SetIcon(mMountSmallIcon);
1674c6 ¤   mNewButton.SetIcon(mNewSmallIcon);
18f892 ¤   mPrefsButton.SetIcon(mPrefsSmallIcon);
3217be ¤   mUnmountButton.SetIcon(mUnmountSmallIcon);
28af5a
1ddc89 ¤   // Move and resize the buttons.
3506b3 ¤   mNewButton.MoveWindow(kSmallButtonXBias, kSmallButtonYBias,·
f37ec3 ¤   ¤   kSideLengthSmallButton, kSideLengthSmallButton);
4683d5 ¤   mMountButton.MoveWindow(kSideLengthSmallButton + kSmallButtonXBias,·
2442ce ¤   ¤   kSmallButtonYBias, kSideLengthSmallButton, kSideLengthSmallButton);
15d482 ¤   mUnmountButton.MoveWindow(kSideLengthSmallButton*2 + kSmallButtonXBias,·
2242ce ¤   ¤   kSmallButtonYBias, kSideLengthSmallButton, kSideLengthSmallButton);
1fad29 ¤   mPrefsButton.MoveWindow(kSideLengthSmallButton*3 + kSmallButtonXBias,·
--8efa 0003fb57aa4401100a5 Page 5 of CMainDialog.cpp
f342ce ¤   ¤   kSmallButtonYBias, kSideLengthSmallButton, kSideLengthSmallButton);
6daf5a
236e23 ¤   // Hide the main menu.
6c95b9 ¤   HideMainMenu();
c4af5a
81fce8 ¤   // Resize the dialog.
1b940a ¤   smallSizeX¤ = kWidthSmallMainDialog + edgeX * 2;
0aa4e8 ¤   smallSizeY¤ = kHeightSmallMainDialog + edgeY * 2 + captionY;
caaf5a
46881b ¤   SetWindowPos(NULL, 0, 0, smallSizeX, smallSizeY,·
e8838b ¤   ¤   SWP_NOMOVE | SWP_NOZORDER);
c1efe6 }
baaf5a
6374b7 // RecallMainWndOnTop recalls the 'window on top' position of the main window
dbd578 // from the registry and checks the menu item to reflect this.
9daf5a
a1c823 void·
439d24 CMainDialog::RecallMainWndOnTop()
90bb36 {
63f334 ¤   CMenu¤  ¤   *pSysMenu;
20c3be ¤   PGPUInt32¤  checkState;
e367c5 ¤
f04645 ¤   pSysMenu = GetSystemMenu(FALSE);
e0e9f0 ¤   pgpAssertAddrValid(pSysMenu, CMenu);
8faf5a
316090 ¤   checkState = PGPdiskGetPrefDWord(kRegistryMainStayOnTopKey,·
d59b1d ¤   ¤   MF_UNCHECKED);
ffaf5a
043ce5 ¤   pSysMenu->CheckMenuItem(IDM_STAYONTOP, MF_BYCOMMAND | checkState);
eeaf5a
a257a2 ¤   if (checkState == MF_CHECKED)
5ecf1f ¤   ¤   SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
39efe6 }
ccaf5a
41c6c3 // SaveMainWndOnTop saves the 'window on top' position of the main window in
ca05a6 // the registry.
beaf5a
bec823 void·
14865c CMainDialog::SaveMainWndOnTop()
52bb36 {
b1f334 ¤   CMenu¤  ¤   *pSysMenu;
65c3be ¤   PGPUInt32¤  checkState;
36af5a
304645 ¤   pSysMenu = GetSystemMenu(FALSE);
9be9f0 ¤   pgpAssertAddrValid(pSysMenu, CMenu);
b6af5a
5af546 ¤   checkState = pSysMenu->GetMenuState(IDM_STAYONTOP, MF_BYCOMMAND);
6daf5a
d75d15 ¤   PGPdiskSetPrefDWord(kRegistryMainStayOnTopKey, checkState);
62efe6 }
2daf5a
fc9e2a // The CMainDialog data exchange function.
20af5a
9bc823 void·
fdb52b CMainDialog::DoDataExchange(CDataExchange *pDX)
b7bb36 {
6278f1 ¤   try
b7c7a1 ¤   {
0df4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
eeaf5a
d4a313 ¤   ¤   //{{AFX_DATA_MAP(CMainDialog)
a2f41e ¤   ¤   DDX_Control(pDX, IDC_UNMOUNTPGPDISK, mUnmountButton);
71c008 ¤   ¤   DDX_Control(pDX, IDC_MOUNTPGPDISK, mMountButton);
fe49d2 ¤   ¤   DDX_Control(pDX, IDC_PREFERENCES, mPrefsButton);
4ecb9f ¤   ¤   DDX_Control(pDX, IDC_NEWPGPDISK, mNewButton);
a93376 ¤   ¤   //}}AFX_DATA_MAP
8c9371 ¤   }
173c88 ¤   catch (CMemoryException *ex)
ecc7a1 ¤   {
c46adc ¤   ¤   ex->Delete();
7c9371 ¤   }
3fefe6 }
--9ed6 0005beb9722401100a5 Page 6 of CMainDialog.cpp
e0af5a
513bba // OnAboutBox displays the about box.
44af5a
58c823 void·
aceef6 CMainDialog::OnAboutBox()
b8bb36 {
f5229c ¤   App->CallShowAboutBox();
aaefe6 }
a9af5a
495e27 // OnAddPassphrase adds a passphrase to a PGPdisk.
57af5a
57c823 void·
d6415b CMainDialog::OnAddPassphrase()
81bb36 {
cd2b40 ¤   App->AskUserAddPassphrase();
8defe6 }
83af5a
d87d5c // OnChangePassphrase changes a passphrase on a PGPdisk.
40af5a
c0c823 void·
93ca12 CMainDialog::OnChangePassphrase()
a7bb36 {
78b806 ¤   App->AskUserChangePassphrase();
fbefe6 }
d8af5a
8e97c6 // OnExit is called when the user chooses Exit.
aaaf5a
e9c823 void·
8387c7 CMainDialog::OnExit()·
23bb36 {
854250 ¤   PostMessage(WM_CLOSE);
0befe6 }
60af5a
2e6f8c // OnHelpContents displays the PGPdisk help file.
3caf5a
89c823 void·
0cbc93 CMainDialog::OnHelpContents()
07bb36 {
4c5214 ¤   App->CallShowHelp();
63efe6 }
7aaf5a
0bea4b #if PGPDISK_PUBLIC_KEY
7eaf5a
da69ff // OnAddRemovePublicKeys is called when the user selects the "Manage Public
c8d87b // Keys" menu option.
96af5a
edc823 void·
acd006 CMainDialog::OnAddRemovePublicKeys()
3cbb36 {
e0c7bd ¤   App->AskUserAddRemovePublicKeys();
f5efe6 }
8caf5a
3a38e4 #endif¤ // PGPDISK_PUBLIC_KEY
ddaf5a
42960f // OnGlobalConvert is called when the user selects the "Convert Old PGPdisks"
365f39 // menu item.
fbaf5a
dbc823 void·
46686a CMainDialog::OnGlobalConvert()
cabb36 {
b76c91 ¤   App->AskUserGlobalConvertPGPdisks();
f5efe6 }
50af5a
145546 // OnMountPGPdisk is called when the user presses the "Mount PGPdisk" button.
73af5a
b7c823 void·
10b4c8 CMainDialog::OnMountPGPdisk()
76bb36 {
9e3901 ¤   App->AskUserMountPGPdisk();
68efe6 }
05af5a
5b0a67 // OnNewPGPdisk is called when the user presses the New PGPdisk button. We
--c969 00010fe7500401100a5 Page 7 of CMainDialog.cpp
09ad94 // display the "Create New PGPdisk" dialog box.
4aaf5a
5bc823 void·
ae22e3 CMainDialog::OnNewPGPdisk()
42bb36 {
7a0083 ¤   App->AskUserNewPGPdisk();
a5efe6 }
bdaf5a
2c1552 // OnPreferences handles the 'Preferences' button.
e1af5a
69c823 void·
e9be78 CMainDialog::OnPreferences()·
87bb36 {
d21494 ¤   App->CallShowPrefs();
8aefe6 }
70af5a
26830c // OnRemoveAlternates removes all alternate passphrases from a PGPdisk.
c0af5a
7dc823 void·
e1f823 CMainDialog::OnRemoveAlternates()
8bbb36 {
942a2e ¤   App->AskUserRemovePassphrase(TRUE);
92efe6 }
eeaf5a
a56f1d // OnRemovePassphrase removes a passphrase from a PGPdisk.
b6af5a
6cc823 void·
b87dcf CMainDialog::OnRemovePassphrase()
5bbb36 {
10b5d9 ¤   App->AskUserRemovePassphrase();
61efe6 }
47af5a
e67d7c // OnUnmountPGPdisk is called when the user selects the "Unmount PGPdisk" menu
fe8409 // item.
5caf5a
88c823 void·
eacd27 CMainDialog::OnUnmountPGPdisk()
6dbb36 {
1452af ¤   App->AskUserUnmountPGPdisk();
6cefe6 }
79af5a
2aaf5a
3519ca /////////////////////////////////////////////////
ef2a1d // CMainDialog protected default message handlers
b319ca /////////////////////////////////////////////////
4eaf5a
7c39e4 // OnClose is called before the window is destroyed.
7faf5a
e0c823 void·
bc0252 CMainDialog::OnClose()·
8bbb36 {
83a07c ¤   // Save the big/small window pref in the registry.
ee53b2 ¤   PGPdiskSetPrefDWord(kRegistryWasDialogSmallKey, !mAreWeInLargeMode);
39af5a
24019f ¤   // Save the window coords in the registry.
deba1e ¤   SaveWindowPos(this, kRegistryMainCoordsKey);
3eaf5a
b12984 ¤   DestroyWindow();
5defe6 }
72af5a
2a7c32 // OnCommand is overridden so we can make sure that spurious commands aren't
a6ce1e // executed in command-line mode.
ffaf5a
a37efe BOOL·
5eec62 CMainDialog::OnCommand(WPARAM wParam, LPARAM lParam)·
62bb36 {
aeae38 ¤   if (App->mCommandLineMode)¤ ¤   ¤   // ignore if in command line mode
7c836c ¤   ¤   return TRUE;
9b67c5 ¤
f21f13 ¤   return CDialog::OnCommand(wParam, lParam);
24efe6 }
10af5a
--c8b3 000829f9157401100a5 Page 8 of CMainDialog.cpp
507280 // OnDestroy is called when the dialog is going away.
b3af5a
59c823 void·
253f63 CMainDialog::OnDestroy()
59bb36 {
35e6b7 ¤   CDialog::OnDestroy();
fdefe6 }
feaf5a
42fcdd // OnDropFiles is called to handle files dropped on the dialog which the user
2f0094 // dragged there from the desktop.
e7af5a
10c823 void·
1e08bf CMainDialog::OnDropFiles(HDROP hDrop)
a8bb36 {
2bb1a7 ¤   PGPUInt32 numDropped;
c4af5a
598339 ¤   numDropped = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, NULL);
b9af5a
50ff34 ¤   for (PGPUInt32 i=0; i < numDropped; i++)
30c7a1 ¤   {
1a61b2 ¤   ¤   AppCommandInfo¤ ACI;
fb4526 ¤   ¤   CString¤¤   ¤   path;
9313c1 ¤   ¤   DualErr¤¤   ¤   derr;
61af5a
6741f1 ¤   ¤   try
af5b34 ¤   ¤   {
abf9ad ¤   ¤   ¤   DragQueryFile(hDrop, i, path.GetBuffer(kMaxStringSize),·
e4fbb1 ¤   ¤   ¤   ¤   kMaxStringSize);
63af5a
0ff7fa ¤   ¤   ¤   path.ReleaseBuffer();
1baf5a
683717 ¤   ¤   ¤   ACI.op¤ ¤   = kAppOp_Mount;
52e9cc ¤   ¤   ¤   ACI.flags¤  = NULL;
aff6c8 ¤   ¤   ¤   ACI.drive¤  = kInvalidDrive;
accfc1 ¤   ¤   ¤   strcpy(ACI.path, path);
e1af5a
7f3161 ¤   ¤   ¤   App->DispatchAppCommandInfo(&ACI);
670fe4 ¤   ¤   }
7a01e0 ¤   ¤   catch (CMemoryException *ex)
7b5b34 ¤   ¤   {
3fad69 ¤   ¤   ¤   ex->Delete();
5e0fe4 ¤   ¤   }
dc9371 ¤   }
4cefe6 }
aaaf5a
3f8cca // OnHelpInfo handles context-sensitive help.
cfaf5a
ec7efe BOOL·
742ee7 CMainDialog::OnHelpInfo(HELPINFO *pHelpInfo)
91bb36 {
c529b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
c5e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
06c7a1 ¤   {
10ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
746b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
559371 ¤   }
4faf5a
c8c2e7 ¤   return TRUE;
72efe6 }
48af5a
919e72 // OnInitDialog is called to perform dialog initialization for CMainDialog.
57af5a
437efe BOOL·
ccb4ff CMainDialog::OnInitDialog()
28bb36 {
aec799 ¤   CDialog::OnInitDialog();
6faf5a
871562 ¤   // Show the main menu.
b2b50d ¤   mInitErr = ShowMainMenu();
d8af5a
339c32 ¤   if (mInitErr.IsntError())
82c7a1 ¤   {
--7115 00025384fd0401100a5 Page 9 of CMainDialog.cpp
a0fe8f ¤   ¤   // Recall where the user last put this window.
bf8a77 ¤   ¤   RecallWindowPos(this, kRegistryMainCoordsKey);
04af5a
15ddf0 ¤   ¤   // Load our accelerator table.
ecf659 ¤   ¤   mAccelTable = LoadAccelerators(AfxGetResourceHandle(),·
082667 ¤   ¤   ¤   MAKEINTRESOURCE(IDR_MAINDLG_ACCEL));
b0af5a
5e8c66 ¤   ¤   // Set the icon for this dialog.
1e3a8e ¤   ¤   SetIcon(mHIcon, TRUE);¤ ¤   ¤   // Set big icon
35f912 ¤   ¤   SetIcon(mHIcon, FALSE);¤¤   ¤   // Set small icon
02af5a
84e1a9 ¤   ¤   // Load the big icons for the four main buttons.
304595 ¤   ¤   mMountBigIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
9a42d3 ¤   ¤   ¤   MAKEINTRESOURCE(IDI_MOUNT), IMAGE_ICON, kSideLengthBigIcon,·
0e486b ¤   ¤   ¤   kSideLengthBigIcon, NULL);
6598cc ¤   ¤   mNewBigIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
0aa56b ¤   ¤   ¤   MAKEINTRESOURCE(IDI_NEW), IMAGE_ICON, kSideLengthBigIcon,·
18486b ¤   ¤   ¤   kSideLengthBigIcon, NULL);
655a3a ¤   ¤   mPrefsBigIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
99afd2 ¤   ¤   ¤   MAKEINTRESOURCE(IDI_PREFS), IMAGE_ICON, kSideLengthBigIcon,·
9a486b ¤   ¤   ¤   kSideLengthBigIcon, NULL);
8a4a4b ¤   ¤   mUnmountBigIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
b34984 ¤   ¤   ¤   MAKEINTRESOURCE(IDI_UNMOUNT), IMAGE_ICON, kSideLengthBigIcon,·
9a486b ¤   ¤   ¤   kSideLengthBigIcon, NULL);
ecaf5a
aaa0e0 ¤   ¤   // Load the small icons for the four main buttons.
3fa434 ¤   ¤   mMountSmallIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
bfd866 ¤   ¤   ¤   MAKEINTRESOURCE(IDI_MOUNT), IMAGE_ICON, kSideLengthSmallIcon,·
d110e3 ¤   ¤   ¤   kSideLengthSmallIcon, NULL);
28adb3 ¤   ¤   mNewSmallIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
2cbf79 ¤   ¤   ¤   MAKEINTRESOURCE(IDI_NEW), IMAGE_ICON, kSideLengthSmallIcon,·
1d10e3 ¤   ¤   ¤   kSideLengthSmallIcon, NULL);
176075 ¤   ¤   mPrefsSmallIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
68fd55 ¤   ¤   ¤   MAKEINTRESOURCE(IDI_PREFS), IMAGE_ICON, kSideLengthSmallIcon,·
4810e3 ¤   ¤   ¤   kSideLengthSmallIcon, NULL);
1599e8 ¤   ¤   mUnmountSmallIcon = (HICON) LoadImage(AfxGetInstanceHandle(),·
ddf84a ¤   ¤   ¤   MAKEINTRESOURCE(IDI_UNMOUNT), IMAGE_ICON, kSideLengthSmallIcon,·
e010e3 ¤   ¤   ¤   kSideLengthSmallIcon, NULL);
f6af5a
13dd67 ¤   ¤   if (!mMountBigIcon || !mNewBigIcon || !mPrefsBigIcon ||·
6a2f06 ¤   ¤   ¤   !mUnmountBigIcon || !mMountSmallIcon || !mNewSmallIcon ||
57ce64 ¤   ¤   ¤   !mPrefsSmallIcon || !mUnmountSmallIcon)
eb5b34 ¤   ¤   {
e2d525 ¤   ¤   ¤   mInitErr = kPGDMinorError_DialogDisplayFailed;
260fe4 ¤   ¤   }
599371 ¤   }
bbaf5a
939c32 ¤   if (mInitErr.IsntError())
9bc7a1 ¤   {
e5cd99 ¤   ¤   CMenu *pSysMenu;
42af5a
164c6c ¤   ¤   // Were we large or small?
ca457a ¤   ¤   if (PGPdiskGetPrefDWord(kRegistryWasDialogSmallKey, FALSE))
f57747 ¤   ¤   ¤   ConvertMainDialogToSmall();
490e1d ¤   ¤   else
db447f ¤   ¤   ¤   ConvertMainDialogToLarge();
f2af5a
72337d ¤   ¤   // Alter the system menu.
7243a8 ¤   ¤   pSysMenu = GetSystemMenu(FALSE);
fbef48 ¤   ¤   pgpAssertAddrValid(pSysMenu, CMenu);
42af5a
a00716 ¤   ¤   pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
dcaf5a
2db531 ¤   ¤   pSysMenu->AppendMenu(MF_SEPARATOR);
34b8ca ¤   ¤   pSysMenu->AppendMenu(MF_STRING, IDM_STAYONTOP, "Stay On &Top");
54af5a
712975 ¤   ¤   DrawMenuBar();
a9af5a
db131c ¤   ¤   // Accept dragged files.
a5f1bd ¤   ¤   DragAcceptFiles();
35af5a
253a0d ¤   ¤   // Recall the window on top preference.
--face 000b539349b401100a5 Page 10 of CMainDialog.cpp
418be6 ¤   ¤   RecallMainWndOnTop();
dfaf5a
efb5c4 ¤   ¤   // Focus on the new PGPdisk button.
5962df ¤   ¤   mNewButton.SetFocus();
c39371 ¤   }
62af5a
fa6176 ¤   mArePastInitDialog = TRUE;
f0af5a
f893bc ¤   return FALSE;¤  ¤   ¤   ¤   ¤
6cefe6 }
4a67c5 ¤
5318a3 // OnInitMenu is called when the File menu is displayed.
e9af5a
4bc823 void·
7f0014 CMainDialog::OnInitMenu(CMenu *pMenu)
c6bb36 {
a6337c ¤   PGPBoolean haveWeTimedOut = FALSE;
9baf5a
2f4881 ¤   CDialog::OnInitMenu(pMenu);
e6af5a
6fb08a ¤   // If the shift key is help down, show "Remove Alternate Passphrases" and
5442b8 ¤   // "Convert Old PGPdisks".
d1af5a
929910 ¤   if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
b9c7a1 ¤   {
08dbee ¤   ¤   pMenu->ModifyMenu(IDM_REMOVEPASS, MF_BYCOMMAND | MF_STRING,·
5bcc47 ¤   ¤   ¤   IDM_REMOVEALL, "Remove Alternate Passphrases...");
c39371 ¤   }
ba0e24 ¤   else
0ec7a1 ¤   {
0e35f5 ¤   ¤   pMenu->ModifyMenu(IDM_REMOVEALL, MF_BYCOMMAND | MF_STRING,·
09c0ee ¤   ¤   ¤   IDM_REMOVEPASS, "Remove Passphrase...");
e79371 ¤   }
c6af5a
30554b ¤   // Disable certain menu commands if we've timed out.
04af5a
da8ed5 #if PGPDISK_BETAVERSION
6eaf5a
b85f07 ¤   haveWeTimedOut = App->HasBetaTimedOut();
77af5a
185766 #elif PGPDISK_DEMOVERSION
beaf5a
82148c ¤   haveWeTimedOut = App->HasDemoTimedOut();
a4af5a
45e121 #endif // PGPDISK_BETAVERSION
05af5a
3cac8a ¤   if (haveWeTimedOut)
c2c7a1 ¤   {
53653d ¤   ¤   pMenu->EnableMenuItem(IDM_NEWPGPDISK, MF_GRAYED);
d8aad1 ¤   ¤   pMenu->EnableMenuItem(IDM_ADDPASS, MF_GRAYED);
33c95c ¤   ¤   pMenu->EnableMenuItem(IDM_CHANGEPASS, MF_GRAYED);
f37ca2 ¤   ¤   pMenu->EnableMenuItem(IDM_REMOVEPASS, MF_GRAYED);
ca9633 ¤   ¤   pMenu->EnableMenuItem(IDM_REMOVEALL, MF_GRAYED);
359371 ¤   }
54efe6 }
4faf5a
08c215 // OnPaint is called when part of the dialog must be repainted.
8faf5a
4bc823 void·
5101ba CMainDialog::OnPaint()·
76bb36 {
6a6e20 ¤   CRect rect;
7faf5a
60dff7 ¤   if (IsIconic())¤¤   ¤   // MFC iconic stuff
8bc7a1 ¤   {
5e16f8 ¤   ¤   CPaintDC dc(this);
60af5a
5f4e8a ¤   ¤   SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
abaf5a
fee5ee ¤   ¤   // Center icon in client rectangle
0e8948 ¤   ¤   int¤cxIcon¤ = GetSystemMetrics(SM_CXICON);
b5a23f ¤   ¤   int¤cyIcon¤ = GetSystemMetrics(SM_CYICON);
--f11d 000dface4b3401100a5 Page 11 of CMainDialog.cpp
e0af5a
6f8fc7 ¤   ¤   GetClientRect(&rect);
5a87c7 ¤   ¤   ¤
eda0c3 ¤   ¤   int¤x¤  = (rect.Width() - cxIcon + 1)/2;
bdc7b1 ¤   ¤   int¤y¤  = (rect.Height() - cyIcon + 1)/2;
4baf5a
a6c498 ¤   ¤   // Draw the icon
a38428 ¤   ¤   dc.DrawIcon(x, y, mHIcon);
929371 ¤   }
bf0e24 ¤   else
e3c7a1 ¤   {
1612a8 ¤   ¤   CDialog::OnPaint();
4d9371 ¤   }
cdefe6 }
67af5a
711193 // OnSize is called when the dialog has been resized. We alter the buttons and
11f525 // the menu as needed.
89af5a
1bc823 void·
14335b CMainDialog::OnSize(UINT nType, int cx, int cy)·
25bb36 {
1c3430 ¤   CDialog::OnSize(nType, cx, cy);
a0af5a
46464d ¤   if (mArePastInitDialog)
7ec7a1 ¤   {
cfda13 ¤   ¤   if (mAreWeInLargeMode)
46447f ¤   ¤   ¤   ConvertMainDialogToLarge();
a20e1d ¤   ¤   else
367747 ¤   ¤   ¤   ConvertMainDialogToSmall();
a69371 ¤   }
b9efe6 }
73af5a
b5eccb // OnSizing is called when the user is resizing the dialog.
0faf5a
72c823 void·
d57c3a CMainDialog::OnSizing(UINT fwSide, LPRECT pRect)·
88bb36 {
59464d ¤   if (mArePastInitDialog)
e5c7a1 ¤   {
e443e0 ¤   ¤   PGPInt32¤   edgeX¤  ¤   = GetSystemMetrics(SM_CXFIXEDFRAME);
050b31 ¤   ¤   PGPInt32¤   edgeY¤  ¤   = GetSystemMetrics(SM_CYFIXEDFRAME);
4b51af ¤   ¤   PGPInt32¤   captionY¤   = GetSystemMetrics(SM_CYCAPTION);
3443e4 ¤   ¤   PGPInt32¤   menuY¤  ¤   = GetSystemMetrics(SM_CYMENU);
2601b0 ¤   ¤   PGPInt32¤   smallSizeX, smallSizeY, largeSizeX, largeSizeY;
c0af5a
21bf06 ¤   ¤   largeSizeX¤ = kWidthLargeMainDialog + edgeX * 2;
9d1dd7 ¤   ¤   largeSizeY¤ = kHeightLargeMainDialog + edgeY * 2 + captionY + menuY;
82af5a
25fb39 ¤   ¤   smallSizeX¤ = kWidthSmallMainDialog + edgeX * 2;
f22ead ¤   ¤   smallSizeY¤ = kHeightSmallMainDialog + edgeY * 2 + captionY;
5faf5a
ff41d3 ¤   ¤   // There are only two allowable positions for the drag rectangle.
323517 ¤   ¤   // Enforce this.
99af5a
190652 ¤   ¤   switch (fwSide)
d75b34 ¤   ¤   {
bcaf5a
fb8ea0 ¤   ¤   case WMSZ_BOTTOM:
95799f ¤   ¤   ¤   if ((pRect->bottom - pRect->top) < largeSizeY - 5)
58f776 ¤   ¤   ¤   {
66db67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
657932 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + smallSizeX;
9daf5a
cdb917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
32a3a6 ¤   ¤   ¤   }
7eaf5a
4778d3 ¤   ¤   ¤   if ((pRect->bottom - pRect->top) > smallSizeY + 5)
6ff776 ¤   ¤   ¤   {
b607c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
efa594 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + largeSizeX;
e4af5a
df3c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
--6e05 00055194a57401100a5 Page 12 of CMainDialog.cpp
cfa3a6 ¤   ¤   ¤   }
45cdcb ¤   ¤   ¤   break;
9caf5a
bf91c8 ¤   ¤   case WMSZ_BOTTOMLEFT:
42799f ¤   ¤   ¤   if ((pRect->bottom - pRect->top) < largeSizeY - 5)
90f776 ¤   ¤   ¤   {
18db67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
38511d ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - smallSizeX;
47af5a
44b917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
97a3a6 ¤   ¤   ¤   }
b6af5a
7378d3 ¤   ¤   ¤   if ((pRect->bottom - pRect->top) > smallSizeY + 5)
66f776 ¤   ¤   ¤   {
e107c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
fd8dbb ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - largeSizeX;
23af5a
1f3c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
52a3a6 ¤   ¤   ¤   }
91af5a
818b58 ¤   ¤   ¤   if ((pRect->right - pRect->left) < largeSizeX - 5)
b4f776 ¤   ¤   ¤   {
e4511d ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - smallSizeX;
29db67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
bcaf5a
e1b917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
f0a3a6 ¤   ¤   ¤   }
1aaf5a
ff8a14 ¤   ¤   ¤   if ((pRect->right - pRect->left) > smallSizeX + 5)
79f776 ¤   ¤   ¤   {
4b8dbb ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - largeSizeX;
3807c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
51af5a
fc3c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
8da3a6 ¤   ¤   ¤   }
6ecdcb ¤   ¤   ¤   break;
a6af5a
641bb6 ¤   ¤   case WMSZ_BOTTOMRIGHT:
1f799f ¤   ¤   ¤   if ((pRect->bottom - pRect->top) < largeSizeY - 5)
4af776 ¤   ¤   ¤   {
efdb67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
507932 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + smallSizeX;
ebaf5a
76b917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
bfa3a6 ¤   ¤   ¤   }
a6af5a
0878d3 ¤   ¤   ¤   if ((pRect->bottom - pRect->top) > smallSizeY + 5)
14f776 ¤   ¤   ¤   {
2b07c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
cfa594 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + largeSizeX;
c6af5a
383c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
98a3a6 ¤   ¤   ¤   }
a1af5a
298b58 ¤   ¤   ¤   if ((pRect->right - pRect->left) < largeSizeX - 5)
faf776 ¤   ¤   ¤   {
387932 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + smallSizeX;
fedb67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
4caf5a
dcb917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
b3a3a6 ¤   ¤   ¤   }
97af5a
d18a14 ¤   ¤   ¤   if ((pRect->right - pRect->left) > smallSizeX + 5)
0df776 ¤   ¤   ¤   {
64a594 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + largeSizeX;
f207c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
7caf5a
b93c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
e7a3a6 ¤   ¤   ¤   }
a5cdcb ¤   ¤   ¤   break;
59af5a
55e02f ¤   ¤   case WMSZ_LEFT:
--08b2 000fec7713e401100a5 Page 13 of CMainDialog.cpp
3a8b58 ¤   ¤   ¤   if ((pRect->right - pRect->left) < largeSizeX - 5)
e5f776 ¤   ¤   ¤   {
b5511d ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - smallSizeX;
57db67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
22af5a
9eb917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
9fa3a6 ¤   ¤   ¤   }
d7af5a
7f8a14 ¤   ¤   ¤   if ((pRect->right - pRect->left) > smallSizeX + 5)
3af776 ¤   ¤   ¤   {
e78dbb ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - largeSizeX;
ee07c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
1eaf5a
923c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
94a3a6 ¤   ¤   ¤   }
04cdcb ¤   ¤   ¤   break;
c6af5a
ed8876 ¤   ¤   case WMSZ_RIGHT:
608b58 ¤   ¤   ¤   if ((pRect->right - pRect->left) < largeSizeX - 5)
d4f776 ¤   ¤   ¤   {
627932 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + smallSizeX;
56db67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
a5af5a
a4b917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
16a3a6 ¤   ¤   ¤   }
a4af5a
a18a14 ¤   ¤   ¤   if ((pRect->right - pRect->left) > smallSizeX + 5)
acf776 ¤   ¤   ¤   {
cea594 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + largeSizeX;
7107c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
fcaf5a
003c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
70a3a6 ¤   ¤   ¤   }
ebcdcb ¤   ¤   ¤   break;
c2af5a
b2b6d9 ¤   ¤   case WMSZ_TOP:
9d799f ¤   ¤   ¤   if ((pRect->bottom - pRect->top) < largeSizeY - 5)
d3f776 ¤   ¤   ¤   {
8c2f13 ¤   ¤   ¤   ¤   pRect->top¤ ¤   = pRect->bottom - smallSizeY;
9c7932 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + smallSizeX;
cbaf5a
f1b917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
49a3a6 ¤   ¤   ¤   }
14af5a
3378d3 ¤   ¤   ¤   if ((pRect->bottom - pRect->top) > smallSizeY + 5)
75f776 ¤   ¤   ¤   {
f1f3b5 ¤   ¤   ¤   ¤   pRect->top¤ ¤   = pRect->bottom - largeSizeY;
b8a594 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + largeSizeX;
43af5a
013c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
2ca3a6 ¤   ¤   ¤   }
f4cdcb ¤   ¤   ¤   break;
28af5a
427282 ¤   ¤   case WMSZ_TOPLEFT:
cd799f ¤   ¤   ¤   if ((pRect->bottom - pRect->top) < largeSizeY - 5)
b5f776 ¤   ¤   ¤   {
1ae8f3 ¤   ¤   ¤   ¤   pRect->top¤ = pRect->bottom - smallSizeY;
de494b ¤   ¤   ¤   ¤   pRect->left¤= pRect->right - smallSizeX;
75af5a
a5b917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
1ba3a6 ¤   ¤   ¤   }
73af5a
d378d3 ¤   ¤   ¤   if ((pRect->bottom - pRect->top) > smallSizeY + 5)
c8f776 ¤   ¤   ¤   {
933455 ¤   ¤   ¤   ¤   pRect->top¤ = pRect->bottom - largeSizeY;
8c95ed ¤   ¤   ¤   ¤   pRect->left¤= pRect->right - largeSizeX;
97af5a
653c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
caa3a6 ¤   ¤   ¤   }
91af5a
198b58 ¤   ¤   ¤   if ((pRect->right - pRect->left) < largeSizeX - 5)
fef776 ¤   ¤   ¤   {
--bf78 000eeb59b69401100a5 Page 14 of CMainDialog.cpp
a0511d ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - smallSizeX;
97db67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
0eaf5a
0cb917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
01a3a6 ¤   ¤   ¤   }
07af5a
808a14 ¤   ¤   ¤   if ((pRect->right - pRect->left) > smallSizeX + 5)
c4f776 ¤   ¤   ¤   {
bd8dbb ¤   ¤   ¤   ¤   pRect->left¤¤   = pRect->right - largeSizeX;
b507c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
45af5a
753c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
1ea3a6 ¤   ¤   ¤   }
6bcdcb ¤   ¤   ¤   break;
a3af5a
9ff60b ¤   ¤   case WMSZ_TOPRIGHT:
85799f ¤   ¤   ¤   if ((pRect->bottom - pRect->top) < largeSizeY - 5)
56f776 ¤   ¤   ¤   {
612f13 ¤   ¤   ¤   ¤   pRect->top¤ ¤   = pRect->bottom - smallSizeY;
b27932 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + smallSizeX;
b9af5a
4cb917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
2ea3a6 ¤   ¤   ¤   }
dfaf5a
bf78d3 ¤   ¤   ¤   if ((pRect->bottom - pRect->top) > smallSizeY + 5)
aef776 ¤   ¤   ¤   {
aaf3b5 ¤   ¤   ¤   ¤   pRect->top¤ ¤   = pRect->bottom - largeSizeY;
9ea594 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + largeSizeX;
1faf5a
f13c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
9ea3a6 ¤   ¤   ¤   }
edaf5a
248b58 ¤   ¤   ¤   if ((pRect->right - pRect->left) < largeSizeX - 5)
6bf776 ¤   ¤   ¤   {
b77932 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + smallSizeX;
64db67 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + smallSizeY;
38af5a
45b917 ¤   ¤   ¤   ¤   mAreWeInLargeMode = FALSE;
88a3a6 ¤   ¤   ¤   }
25af5a
a98a14 ¤   ¤   ¤   if ((pRect->right - pRect->left) > smallSizeX + 5)
caf776 ¤   ¤   ¤   {
7da594 ¤   ¤   ¤   ¤   pRect->right¤   = pRect->left + largeSizeX;
8207c1 ¤   ¤   ¤   ¤   pRect->bottom¤  = pRect->top + largeSizeY;
cfaf5a
b53c4c ¤   ¤   ¤   ¤   mAreWeInLargeMode = TRUE;
f3a3a6 ¤   ¤   ¤   }
6dcdcb ¤   ¤   ¤   break;
8aaf5a
769ae3 ¤   ¤   default:
d90606 ¤   ¤   ¤   pgpAssert(FALSE);
9bcdcb ¤   ¤   ¤   break;
bc0fe4 ¤   ¤   }
e49371 ¤   }
15af5a
7e79d5 ¤   CDialog::OnSizing(fwSide, pRect);¤
b5efe6 }
84af5a
d837e5 // OnSysCommand is called when the user makes a choice from the system menu
3115bc // and also in other circumstances.
e9af5a
78c823 void·
891d5c CMainDialog::OnSysCommand(UINT nId, LONG lParam)
bbbb36 {
dbf334 ¤   CMenu¤  ¤   *pSysMenu;
c8c3be ¤   PGPUInt32¤  checkState;
ebaf5a
048760 ¤   // Did the user select the "Stay On Top" menu item?
0d69ba ¤   switch (nId)
3ac7a1 ¤   {
83bf5b ¤   case IDM_STAYONTOP:
ee43a8 ¤   ¤   pSysMenu = GetSystemMenu(FALSE);
--1489 00145293491401100a5 Page 15 of CMainDialog.cpp
8bef48 ¤   ¤   pgpAssertAddrValid(pSysMenu, CMenu);
b3af5a
4ce3f0 ¤   ¤   checkState = pSysMenu->GetMenuState(IDM_STAYONTOP, MF_BYCOMMAND);
93af5a
1eb8d1 ¤   ¤   if (checkState == MF_CHECKED)
625b34 ¤   ¤   {
c9c90d ¤   ¤   ¤   pSysMenu->CheckMenuItem(IDM_STAYONTOP,·
7ddaaf ¤   ¤   ¤   ¤   MF_BYCOMMAND | MF_UNCHECKED);
9faf5a
f875d4 ¤   ¤   ¤   SetWindowPos(&CWnd::wndNoTopMost, 0, 0, 0, 0,·
09cb9a ¤   ¤   ¤   ¤   SWP_NOMOVE | SWP_NOSIZE);
d80fe4 ¤   ¤   }
bc0e1d ¤   ¤   else
755b34 ¤   ¤   {
521c9a ¤   ¤   ¤   pSysMenu->CheckMenuItem(IDM_STAYONTOP, MF_BYCOMMAND | MF_CHECKED);
13af5a
3402c9 ¤   ¤   ¤   SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0,·
78cb9a ¤   ¤   ¤   ¤   SWP_NOMOVE | SWP_NOSIZE);
bb0fe4 ¤   ¤   }
feaf5a
a70e40 ¤   ¤   // Save the window on top position in the registry.
8b91c5 ¤   ¤   SaveMainWndOnTop();
452f68 ¤   ¤   break;
82af5a
5a2f72 ¤   default:
d0d49f ¤   ¤   CWnd::OnSysCommand(nId, lParam);
422f68 ¤   ¤   break;
589371 ¤   }
31efe6 }
55af5a
a210f7 // OnQueryDragIcon is called to obtain the cursor to display when dragging a
4b9744 // minimized window.
7daf5a
a59e54 HCURSOR·
4c6217 CMainDialog::OnQueryDragIcon()
e5bb36 {
d17e7a ¤   return (HCURSOR) mHIcon;
45efe6 }
--8442 00070269fca401100a6 Page 1 of CMainDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
cae249 // CMainDialog.h
fc465d //
b63a07 // Declaration of class CMainDialog.
a71bc3 //////////////////////////////////////////////////////////////////////////////
fcaf5a
1b8405 // $Id: CMainDialog.h,v 1.1.2.10.2.1 1998/10/22 22:27:43 nryan Exp $
19af5a
d4cbce // Copyright (C) 1998 by Network Associates, Inc.
0271ae // All rights reserved.
f8af5a
8080be #ifndef Included_CMainDialog_h¤ // [
083d63 #define Included_CMainDialog_h
77af5a
423a85 #include "DualErr.h"
7aaf5a
45ab81 #include "Resource.h"
cdaf5a
deaf5a
9b09b7 ////////////
a5e738 // Constants
4509b7 ////////////
9faf5a
d8f005 const PGPUInt16 IDM_STAYONTOP¤  = 4243; ¤   ¤   // extra menu item
fe6ccb const PGPUInt16 IDM_REMOVEALL¤  = 4242; ¤   ¤   // extra menu item
67af5a
32af5a
19ca3a ////////////////////
c0f287 // Class CMainDialog
78ca3a ////////////////////
b3af5a
92a3b5 // Class CMainDialog is the class that displays and handles the main dialog
c5b31e // box for the dialog-box based Umbra application.
4aaf5a
314673 class CMainDialog : public CDialog
56bb36 {
5a5ed4 public:
c01603 ¤   DualErr mInitErr;
b6af5a
5b5403 ¤   CMainDialog(CWnd *pParent = NULL);
c20519 ¤   ~CMainDialog();
57af5a
ce25c9 ¤   //{{AFX_DATA(CMainDialog)
45adf1 ¤   enum { IDD = IDD_MAIN_DLG };
fd8ff7 ¤   CButton mUnmountButton;
46d7a6 ¤   CButton mMountButton;
6bdd9e ¤   CButton mPrefsButton;
9a2fd0 ¤   CButton mNewButton;
125139 ¤   //}}AFX_DATA
24af5a
11ba8c ¤   //{{AFX_VIRTUAL(CMainDialog)
9767d4 ¤   public:
1d6257 ¤   virtual BOOL PreTranslateMessage(MSG *pMsg);
fcc369 ¤   protected:
f83e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
b4af39 ¤   virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
deaf53 ¤   //}}AFX_VIRTUAL
b6af5a
2ea2d3 protected:
7667b3 ¤   CMenu¤  ¤   mMainMenu;¤ ¤   ¤   ¤   // main menu
daaf5a
95d92d ¤   #if PGP_DEBUG
0e76d9 ¤   #if PGPDISK_ENABLEDEBUGMENU
39af5a
9aad1b ¤   CMenu¤  ¤   mDebugMenu; ¤   ¤   ¤   // special debug menu
f2af5a
07db42 ¤   #endif¤ // PGPDISK_ENABLEDEBUGMENU
6dafb6 ¤   #endif¤ // PGP_DEBUG
00af5a
94a24c ¤   CPalette¤   mMainLogoPalette;¤  ¤   // palette for main logo
1eaf5a
70fbcf ¤   HACCEL¤ ¤   mAccelTable;¤   ¤   ¤   // accelerator table
--be93 0017dce5928401100a6 Page 2 of CMainDialog.h
c354cd ¤   HICON¤  ¤   mHIcon; ¤   ¤   ¤   ¤   // an icon
a2af5a
f5eefc ¤   HICON¤  ¤   mMountBigIcon;¤ ¤   ¤   // big mount button icon
0770df ¤   HICON¤  ¤   mNewBigIcon;¤   ¤   ¤   // big new button icon
0394ba ¤   HICON¤  ¤   mPrefsBigIcon;¤ ¤   ¤   // big prefs button icon
544b6f ¤   HICON¤  ¤   mUnmountBigIcon;¤   ¤   // big unmount button icon
02af5a
1b3ec1 ¤   HICON¤  ¤   mMountSmallIcon;¤   ¤   // small mount button icon
4878dd ¤   HICON¤  ¤   mNewSmallIcon;¤ ¤   ¤   // small new button icon
c6835d ¤   HICON¤  ¤   mPrefsSmallIcon;¤   ¤   // small prefs button icon
922a98 ¤   HICON¤  ¤   mUnmountSmallIcon;¤ ¤   // small unmount button icon
eeaf5a
f6a1f0 ¤   PGPBoolean¤ mAreWeInLargeMode;¤ ¤   // large main window?
553123 ¤   PGPBoolean¤ mArePastInitDialog; ¤   // received WM_INITDIALOG yet?
c1af5a
677038 ¤   inline PGPBoolean¤  HasFocus(CButton *button)
15aa84 ¤   ¤   {return (button->GetState() & 0x0008 ? TRUE : FALSE);};
daaf5a
3b5ad6 ¤   DualErr ¤   ¤   ¤   ShowMainMenu();
db4852 ¤   void¤   ¤   ¤   ¤   HideMainMenu();·
70af5a
abcd99 ¤   void¤   ¤   ¤   ¤   ConvertMainDialogToLarge();
4efea1 ¤   void¤   ¤   ¤   ¤   ConvertMainDialogToSmall();
d0af5a
d93a61 ¤   void¤   ¤   ¤   ¤   RecallMainWndOnTop();
060f38 ¤   void¤   ¤   ¤   ¤   SaveMainWndOnTop();
90af5a
4a17b1 ¤   //{{AFX_MSG(CMainDialog)
28fa8e ¤   afx_msg void OnDestroy();
10c5f3 ¤   afx_msg void OnPaint();
e79bb8 ¤   afx_msg HCURSOR OnQueryDragIcon();
1158b0 ¤   afx_msg void OnAboutBox();
bb70eb ¤   afx_msg void OnAddPassphrase();
53a928 ¤   afx_msg void OnChangePassphrase();
c57efa ¤   afx_msg void OnDropFiles(HDROP hDrop);
538910 ¤   afx_msg void OnRemoveAlternates();
46a4f7 ¤   afx_msg void OnRemovePassphrase();
75b92d ¤   afx_msg void OnExit();
535fc8 ¤   afx_msg void OnMountPGPdisk();
a1492d ¤   afx_msg void OnUnmountPGPdisk();
ec3b63 ¤   afx_msg void OnNewPGPdisk();
4f2a51 ¤   afx_msg void OnPreferences();
dc58d4 ¤   afx_msg void OnAddRemovePublicKeys();
1f50c8 ¤   afx_msg void OnGlobalConvert();
dfb396 ¤   afx_msg void OnHelpContents();
4bc61b ¤   afx_msg void OnClose();
4e652b ¤   afx_msg void OnInitMenu(CMenu *pMenu);
03698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
5cab16 ¤   afx_msg void OnSysCommand(UINT nId, LONG lParam);
25f17a ¤   virtual BOOL OnInitDialog();
8e6a94 ¤   afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
764725 ¤   afx_msg void OnSize(UINT nType, int cx, int cy);
962e09 ¤   //}}AFX_MSG
19af5a
c62409 ¤   DECLARE_MESSAGE_MAP()
1482f7 };
aeaf5a
f7c18c //{{AFX_INSERT_LOCATION}}
6faf5a
7d326d #endif // ] Included_CMainDialog_h
--3dbb 00052b02929401100a7 Page 1 of CNagBuyDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
a08edb // CNagBuyDialog.cpp
5d465d //
4ed655 // Implementation of the CNagBuyDialog class.
831bc3 //////////////////////////////////////////////////////////////////////////////
deaf5a
c1e76d // $Id: CNagBuyDialog.cpp,v 1.1.2.7 1998/07/06 23:26:40 nryan Exp $
5baf5a
40cbce // Copyright (C) 1998 by Network Associates, Inc.
fe71ae // All rights reserved.
9caf5a
619e12 #include "StdAfx.h"
7baf5a
a99bcf #include "Required.h"
d9993c #include "StringAssociation.h"
00af5a
a93646 #include "CMainDialog.h"
2b89af #include "CNagBuyDialog.h"
15c411 #include "Globals.h"
8c4713 #include "PGPdiskHelpIds.h"
78af5a
adaf5a
806cc2 /////////////////////
2e3a71 // Context help array
046cc2 /////////////////////
92af5a
a277bf static PGPUInt32 HelpIds[] =
92bb36 {
6caf96 ¤   IDOK,¤  ¤   ¤   ¤   IDH_PGPDISKAPP_NAGBUYOK,·
b6f05a ¤   IDCANCEL,¤  ¤   ¤   IDH_PGPDISKAPP_NAGBUYCANCEL,·
75b632 ¤   IDC_BUYNOW_BUTTON,¤ IDH_PGPDISKAPP_NAGBUYBUYNOWBUTTON,·
e9fa9a ¤   IDC_NAGBUYMSG_TEXT,¤((PGPUInt32) -1),·
f84434 ····0,0·
c682f7 };
c6af5a
93af5a
7483f5 ///////////////////////////
01b249 // MFC specific definitions
8e83f5 ///////////////////////////
d9af5a
6ccc9b BEGIN_MESSAGE_MAP(CNagBuyDialog, CDialog)
1dbb11 ¤   //{{AFX_MSG_MAP(CNagBuyDialog)
e0db65 ¤   ON_WM_HELPINFO()
183d29 ¤   ON_BN_CLICKED(IDC_BUYNOW_BUTTON, OnBuyNowButton)
ab044a ¤   //}}AFX_MSG_MAP
5faf28 END_MESSAGE_MAP()
e3af5a
14af5a
c9186d /////////////////////////////////////////////////////////////////////////
732ac5 // CNagBuyDialog public custom functions and non-default message handlers
65186d /////////////////////////////////////////////////////////////////////////
4daf5a
8e2d61 // The CNagBuyDialog default constructor.
15af5a
d1c1a2 CNagBuyDialog::CNagBuyDialog(CWnd *pParent)·
f90eda ¤   : CDialog(CNagBuyDialog::IDD, pParent)
94bb36 {
a178f1 ¤   try
ccc7a1 ¤   {
addab3 ¤   ¤   //{{AFX_DATA_INIT(CNagBuyDialog)
333630 ¤   ¤   mNagMessageText = _T("");
44765d ¤   ¤   //}}AFX_DATA_INIT
2a9371 ¤   }
2e3c88 ¤   catch (CMemoryException *ex)
0bc7a1 ¤   {
a26adc ¤   ¤   ex->Delete();
ea9371 ¤   }
d0efe6 }
deaf5a
b89320 // DisplayDialog is a wrapper around DoModal.
45af5a
522292 DualErr·
--9020 0001beeebf4401100a7 Page 2 of CNagBuyDialog.cpp
ba2830 CNagBuyDialog::DisplayDialog(LPCSTR message)
8ebb36 {
6cbe41 ¤   DualErr¤¤   derr;
6ce319 ¤   PGPInt32¤   result;
c167c5 ¤
2a6c10 ¤   // Set the nag message.
a078f1 ¤   try
02c7a1 ¤   {
a87911 ¤   ¤   mNagMessageText = message;
309371 ¤   }
df3c88 ¤   catch (CMemoryException *ex)
60c7a1 ¤   {
a8ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
756adc ¤   ¤   ex->Delete();
989371 ¤   }
b7af5a
ee2361 ¤   if (derr.IsntError())
09c7a1 ¤   {
18827d ¤   ¤   // Show the dialog.
82fcae ¤   ¤   result = DoModal();
b3af5a
72b31e ¤   ¤   // Return an appropriate value.
58b507 ¤   ¤   switch (result)
175b34 ¤   ¤   {
4d56e8 ¤   ¤   case -1:
b239a7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
7ecdcb ¤   ¤   ¤   break;
a2af5a
e871eb ¤   ¤   case IDCANCEL:
a796de ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
d3cdcb ¤   ¤   ¤   break;
e70fe4 ¤   ¤   }
469371 ¤   }
7baf5a
5733e3 ¤   return derr;
beefe6 }
3aaf5a
fcaf5a
9e3924 ////////////////////////////////////////////////////////////////////
0a968e // CNagBuyDialog protected custom functions and non-default handlers
b33924 ////////////////////////////////////////////////////////////////////
60af5a
235670 // The CNagBuyDialog default data-exchange function.
a6af5a
28c823 void·
41079a CNagBuyDialog::DoDataExchange(CDataExchange *pDX)
3ebb36 {
f178f1 ¤   try
7ec7a1 ¤   {
bcf4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
14af5a
485844 ¤   ¤   //{{AFX_DATA_MAP(CNagBuyDialog)
e13b20 ¤   ¤   DDX_Control(pDX, IDOK, mOkButton);
82a1d5 ¤   ¤   DDX_Control(pDX, IDCANCEL, mCancelButton);
430f13 ¤   ¤   DDX_Control(pDX, IDC_BUYNOW_BUTTON, mBuyNowButton);
b0d8bd ¤   ¤   DDX_Text(pDX, IDC_NAGBUYMSG_TEXT, mNagMessageText);
1b3376 ¤   ¤   //}}AFX_DATA_MAP
c29371 ¤   }
353c88 ¤   catch (CMemoryException *ex)
57c7a1 ¤   {
f06adc ¤   ¤   ex->Delete();
799371 ¤   }
72efe6 }
3baf5a
66af5a
ec8fbd ///////////////////////////////////////////////////
e3b69f // CNagBuyDialog protected default message handlers
0b8fbd ///////////////////////////////////////////////////
9faf5a
9f8cca // OnHelpInfo handles context-sensitive help.
5eaf5a
1b7efe BOOL·
--7582 0015a06e4f5401100a7 Page 3 of CNagBuyDialog.cpp
f68926 CNagBuyDialog::OnHelpInfo(HELPINFO *pHelpInfo)
74bb36 {
ac29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
eee5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
6fc7a1 ¤   {
baae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
3d6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
d29371 ¤   }
c2af5a
cac2e7 ¤   return TRUE;
1befe6 }
25af5a
b55252 // OnInitDialog is called when the dialog box is created.
d4af5a
607efe BOOL·
c8155e CNagBuyDialog::OnInitDialog()
14bb36 {
91c799 ¤   CDialog::OnInitDialog();
c6af5a
57afdc ¤   // Put us in front.
b59974 ¤   SetForegroundWindow();
15af5a
b754ed ¤   // Put on top if necessary.
c1c3a9 ¤   App->TweakOnTopAttribute(this);
c9af5a
ffa230 ¤   return FALSE;
beefe6 }
86af5a
1baec9 // OnBuyNowButton goes to the "Buy PGPdisk Now" web site.
69af5a
1fc823 void·
3ef26d CNagBuyDialog::OnBuyNowButton()·
d8bb36 {
035608 ¤   ShellExecute(App->mMainDialog->GetSafeHwnd(), "open",·
cf90e1 ¤   ¤   GetCommonString(kPGPdiskBuyNowURL), NULL, "C:\\", SW_SHOWNORMAL);
6eaf5a
8dbfc0 ¤   EndDialog(IDOK);
5aefe6 }
--df84 00191a3fcaa401100a8 Page 1 of CNagBuyDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
e128f2 // CNagBuyDialog.h
f9465d //
53b9d4 // Declaration of class CNagBuyDialog.
911bc3 //////////////////////////////////////////////////////////////////////////////
baaf5a
cef19d // $Id: CNagBuyDialog.h,v 1.2.2.4.2.1 1998/10/21 01:35:17 nryan Exp $
07af5a
8acbce // Copyright (C) 1998 by Network Associates, Inc.
5171ae // All rights reserved.
12af5a
284b68 #ifndef Included_CNagBuyDialog_h¤   // [
ca1c78 #define Included_CNagBuyDialog_h
2eaf5a
e93a85 #include "DualErr.h"
c8ab81 #include "Resource.h"
85af5a
2faf5a
a317a3 //////////////////////
8aa4a6 // Class CNagBuyDialog
9417a3 //////////////////////
24af5a
320e19 class CNagBuyDialog : public CDialog
b9bb36 {
525ed4 public:
8eba9a ¤   ¤   ¤   CNagBuyDialog(CWnd *pParent = NULL);
67af5a
c626c2 ¤   DualErr¤DisplayDialog(LPCSTR message);
9eaf5a
d41b31 ¤   //{{AFX_DATA(CNagBuyDialog)
d0113d ¤   enum { IDD = IDD_NAGBUY_DLG };
95453d ¤   CButton¤mOkButton;
f35b03 ¤   CButton¤mCancelButton;
42cc17 ¤   CButton¤mBuyNowButton;
3ab3f3 ¤   CString¤mNagMessageText;
055139 ¤   //}}AFX_DATA
f9af5a
fd4f91 ¤   //{{AFX_VIRTUAL(CNagBuyDialog)
d2c369 ¤   protected:
503e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
53af53 ¤   //}}AFX_VIRTUAL
89af5a
92a2d3 protected:
0996e7 ¤   void UpdateOkButton();
19af5a
2637a4 ¤   //{{AFX_MSG(CNagBuyDialog)
6b698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
ccf17a ¤   virtual BOOL OnInitDialog();
3d2135 ¤   afx_msg void OnBuyNowButton();
8b2e09 ¤   //}}AFX_MSG
bcaf5a
692409 ¤   DECLARE_MESSAGE_MAP()
9f82f7 };
00af5a
2fc18c //{{AFX_INSERT_LOCATION}}
6daf5a
913349 #endif¤ // ] Included_CNagBuyDialog_h
--e539 00086602139401100a9 Page 1 of COpenPGPdiskDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
9e4e09 // COpenPGPdiskDialog.cpp
a1465d //
a09b9c // Implementation of the COpenPGPdiskDialog class.
911bc3 //////////////////////////////////////////////////////////////////////////////
1daf5a
8a63ca // $Id: COpenPGPdiskDialog.cpp,v 1.1.2.8 1998/07/06 23:26:42 nryan Exp $
08af5a
13cbce // Copyright (C) 1998 by Network Associates, Inc.
4171ae // All rights reserved.
aaaf5a
3f9e12 #include "StdAfx.h"
08af5a
fe9bcf #include "Required.h"
a5babe #include "PGPdiskRegistry.h"
beaf5a
c64aaa #include "COpenPGPdiskDialog.h"
6ac411 #include "Globals.h"
c368c6 #include "PGPdisk.h"
6caf5a
6caf5a
6b09b7 ////////////
4ce738 // Constants
f409b7 ////////////
98af5a
fe0aa1 static LPCSTR¤  kODTMountDialogTitle¤   = "Mount PGPdisk";
da1d96 static LPCSTR¤  kODTSelectDialogTitle¤  = "Select PGPdisk";
9baf5a
4bafb0 static LPCSTR kODTOpenFilter =·
63d0e7 ¤   "PGPdisk Files (*.pgd)|*.pgd|All Files (*.*)|*.*||";
acaf5a
68af5a
0883f5 ///////////////////////////
71b249 // MFC specific definitions
a383f5 ///////////////////////////
a4af5a
a10ffc BEGIN_MESSAGE_MAP(COpenPGPdiskDialog, CFileDialog)
3f6b46 ¤   //{{AFX_MSG_MAP(COpenPGPdiskDialog)
8b044a ¤   //}}AFX_MSG_MAP
fbaf28 END_MESSAGE_MAP()
7caf5a
faaf5a
f0dd36 //////////////////////////////////////////////////////////////////////
5bd27c // COpenPGPdiskDialog public custom functions and non-default handlers
f4dd36 //////////////////////////////////////////////////////////////////////
55af5a
b2645c IMPLEMENT_DYNAMIC(COpenPGPdiskDialog, CFileDialog)
bcaf5a
7ec31a // The COpenPGPdiskDialog default constructor.
69af5a
977654 COpenPGPdiskDialog::COpenPGPdiskDialog(OpenDialogType dlgType, CWnd *pParent)
86af5a
3eb421 ¤   : CFileDialog(TRUE, &kPGPdiskFileExtension[1], NULL,·
9420f6 ¤   ¤   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, kODTOpenFilter, pParent)
1abb36 {
d990bb ¤   mOpenDialogType¤= dlgType;
85af5a
12d4b6 ¤   m_ofn.Flags¤|= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
062144 ¤   m_ofn.Flags¤&= ~OFN_SHAREAWARE;
c8af5a
419b12 ¤   // Initialize the title according to the dialog type.
f27b2a ¤   switch (mOpenDialogType)
fbc7a1 ¤   {
e75a09 ¤   case kODT_Mount:
461a09 ¤   ¤   m_ofn.lpstrTitle = kODTMountDialogTitle;
c82f68 ¤   ¤   break;
03af5a
f6a483 ¤   case kODT_Select:
480cea ¤   ¤   m_ofn.lpstrTitle = kODTSelectDialogTitle;
202f68 ¤   ¤   break;
29af5a
862f72 ¤   default:
--67b9 0002708d05c401100a9 Page 2 of COpenPGPdiskDialog.cpp
b18f52 ¤   ¤   pgpAssert(FALSE);
a42f68 ¤   ¤   break;
399371 ¤   }
43efe6 }
dcaf5a
103b4c // AskForPath is a wrapper around DoModal.
cdaf5a
2a2292 DualErr·
e863cb COpenPGPdiskDialog::AskForPath(CString *path)
41bb36 {
75dedc ¤   CString¤¤   initialDir;
88be41 ¤   DualErr¤¤   derr;
40e319 ¤   PGPInt32¤   result;
2c67c5 ¤
b8f6da ¤   pgpAssertAddrValid(path, CString);
53af5a
245de9 ¤   // Get default directory from registry.
614e57 ¤   PGPdiskGetPrefString(kRegistryLastOpenDirKey, kEmptyString, &initialDir);
7aaf5a
0c4702 ¤   // Is it legal?
f43ad3 ¤   if (App->IsDirectoryValid(initialDir))
b4a04f ¤   ¤   m_ofn.lpstrInitialDir = initialDir;
040e24 ¤   else
084ac0 ¤   ¤   m_ofn.lpstrInitialDir = NULL;
00af5a
ff7418 ¤   // Show the dialog.
da0acb ¤   result = DoModal();
72af5a
02764b ¤   // Return an appropriate value.
cdcff3 ¤   switch (result)
b6c7a1 ¤   {
a4dac3 ¤   case IDOK:
d241f1 ¤   ¤   try
095b34 ¤   ¤   {
612a90 ¤   ¤   ¤   (* path) = GetPathName();
a00fe4 ¤   ¤   }
6a01e0 ¤   ¤   catch (CMemoryException *ex)
d15b34 ¤   ¤   {
5db95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
30ad69 ¤   ¤   ¤   ex->Delete();
9b0fe4 ¤   ¤   }
df2f68 ¤   ¤   break;
0eaf5a
4de379 ¤   case -1:
d0fdbb ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
ce2f68 ¤   ¤   break;
6eaf5a
af4a02 ¤   case IDCANCEL:
3738df ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
2b2f68 ¤   ¤   break;
af9371 ¤   }
46af5a
8433e3 ¤   return derr;
3eefe6 }
1faf5a
0faf5a
65186d /////////////////////////////////////////////////////////////////////////
285b08 // COpenPGPdiskDialog protected custom functions and non-default handlers
4f186d /////////////////////////////////////////////////////////////////////////
86af5a
776fd8 // UpdateOpenDialogPrefs stores the location of the chosen directory.
d9af5a
32c823 void·
1d365e COpenPGPdiskDialog::UpdateOpenDialogPrefs()
e8bb36 {
b8cb47 ¤   // Update the last open directory in the registry.
9178f1 ¤   try
b6c7a1 ¤   {
9cbd3e ¤   ¤   CString dir, path;
7eaf5a
a72d5a ¤   ¤   path = GetPathName();
271b52 ¤   ¤
--94d4 001cf9212bd401100a9 Page 3 of COpenPGPdiskDialog.cpp
51132f ¤   ¤   GetDirectory(path, &dir);
539d52 ¤   ¤   PGPdiskSetPrefString(kRegistryLastOpenDirKey, dir);
9b9371 ¤   }
2b3c88 ¤   catch (CMemoryException *ex)
edc7a1 ¤   {
b66adc ¤   ¤   ex->Delete();
da9371 ¤   }
edefe6 }
20af5a
db9460 // The COpenPGPdiskDialog default data-exchange function.
00af5a
d8c823 void·
d67e04 COpenPGPdiskDialog::DoDataExchange(CDataExchange *pDX)
ddbb36 {
5f78f1 ¤   try
d6c7a1 ¤   {
57f4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
17af5a
cca937 ¤   ¤   //{{AFX_DATA_MAP(COpenPGPdiskDialog)
a03376 ¤   ¤   //}}AFX_DATA_MAP
319371 ¤   }
293c88 ¤   catch (CMemoryException *ex)
36c7a1 ¤   {
b36adc ¤   ¤   ex->Delete();
d29371 ¤   }
54efe6 }
1daf5a
742e39 // OnFileNameOK is called when the user hits the OK button. We update registry
dbcf8a // information.
8eaf5a
997efe BOOL·
e59468 COpenPGPdiskDialog::OnFileNameOK()
3bbb36 {
6bdfe9 ¤   if (CFileDialog::OnFileNameOK() == 1)
dae102 ¤   ¤   return 1;
c7af5a
edd876 ¤   UpdateOpenDialogPrefs();
3a3e6b ¤   return 0;
5eefe6 }
b7af5a
9ad08e // OnInitDone is called when initialization is done. We override it to stop
928c91 // MFC from centering the window.
50af5a
54c823 void·
80c44d COpenPGPdiskDialog::OnInitDone()
30bb36 {
d4d564 ¤   // Center on screen.
430aed ¤   GetParent()->CenterWindow(GetDesktopWindow());
28af5a
79afdc ¤   // Put us in front.
a77a64 ¤   GetParent()->SetForegroundWindow();
dcaf5a
0154ed ¤   // Put on top if necessary.
85b5e8 ¤   App->TweakOnTopAttribute(GetParent());
cfefe6 }
--729e 001d93d7a39401100aa Page 1 of COpenPGPdiskDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
eac88b // COpenPGPdiskDialog.h
40465d //
88b503 // Declaration of class COpenPGPdiskDialog.
391bc3 //////////////////////////////////////////////////////////////////////////////
37af5a
77abe2 // $Id: COpenPGPdiskDialog.h,v 1.1.2.5 1998/07/06 08:57:01 nryan Exp $
faaf5a
9bcbce // Copyright (C) 1998 by Network Associates, Inc.
0a71ae // All rights reserved.
bfaf5a
c52427 #ifndef Included_COpenPGPdiskDialog_h¤  // [
91e3aa #define Included_COpenPGPdiskDialog_h
13af5a
273a85 #include "DualErr.h"
dfaf5a
84af5a
b3d557 ////////
5302c9 // Types
0fd557 ////////
9faf5a
613371 // OpenDialogType specifies the type of Open dialog being created. kODT_Mount
cb97bf // is for mounts, kODT_SelectPGPdisk is for choosing a PGPdisk for passphrase
8e6e2e // additions/changes/removals. For now, the only difference between the types
d3baa4 // is in the title of the dialog box.
f5af5a
86324a enum OpenDialogType {kODT_Mount, kODT_Select};
89af5a
65af5a
b783f5 ///////////////////////////
18abbd // Class COpenPGPdiskDialog
e783f5 ///////////////////////////
0faf5a
9f4677 class COpenPGPdiskDialog : public CFileDialog
d1bb36 {
71c3a8 ¤   DECLARE_DYNAMIC(COpenPGPdiskDialog)
b0af5a
295ed4 public:
b3c872 ¤   ¤   ¤   COpenPGPdiskDialog(OpenDialogType dlgType, CWnd *pParent = NULL);
5faf5a
f35a1c ¤   DualErr¤AskForPath(CString *path);
bfaf5a
d9a9ea ¤   //{{AFX_DATA(COpenPGPdiskDialog)
055139 ¤   //}}AFX_DATA
e5af5a
5ae4d4 ¤   //{{AFX_VIRTUAL(COpenPGPdiskDialog)
aec369 ¤   protected:
3b3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
86741d ¤   virtual BOOL OnFileNameOK();
aaaf53 ¤   //}}AFX_VIRTUAL
01af5a
39a2d3 protected:
1c0abb ¤   OpenDialogType mOpenDialogType;¤¤   // open dialog type
41af5a
75698c ¤   void¤   UpdateOpenDialogPrefs();
b7b123 ¤   void¤   OnInitDone();
2daf5a
96a9cc ¤   //{{AFX_MSG(COpenPGPdiskDialog)
c52e09 ¤   //}}AFX_MSG
a8af5a
772409 ¤   DECLARE_MESSAGE_MAP()
7a82f7 };
79af5a
78c18c //{{AFX_INSERT_LOCATION}}
0daf5a
d90195 #endif¤ // ] Included_COpenPGPdiskDialog_h
--0cf9 0002fbae117401100ab Page 1 of CPGPdiskApp.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
8f62ee // CPGPdiskApp.cpp
34465d //
a5ee81 // Implementation of class CPGPdiskApp.
921bc3 //////////////////////////////////////////////////////////////////////////////
b4af5a
1f9866 // $Id: CPGPdiskApp.cpp,v 1.2.2.43.2.1 1998/10/25 23:31:26 nryan Exp $
90af5a
66cbce // Copyright (C) 1998 by Network Associates, Inc.
bf71ae // All rights reserved.
88af5a
a69e12 #include "StdAfx.h"
98af5a
bd9bcf #include "Required.h"
feac00 #include "DriverComm.h"
82babe #include "PGPdiskRegistry.h"
59cd22 #include "PGPdiskResidentDefines.h"
88bfe9 #include "UtilityFunctions.h"
72af5a
c98fed #include "CAboutBoxDialog.h"
ab3646 #include "CMainDialog.h"
1b89af #include "CNagBuyDialog.h"
505e8f #include "CPGPdiskApp.h"
ffa26a #include "CPGPdiskCmdLine.h"
2430d7 #include "CPreferencesSheet.h"
67d2d2 #include "CSplashScreenDialog.h"
68af5a
00af5a
bd09b7 ////////////
2fe738 // Constants
5709b7 ////////////
46af5a
5d849e static LPCSTR kPGPdiskMainWndTitle¤ = kPGPdiskAppName;
37c7c9 static LPCSTR kSharedMemNamePrefix¤ = "PGPdiskSharedMem";
28af5a
01af5a
0783f5 ///////////////////////////
5caeb4 // Global variables for MFC
9583f5 ///////////////////////////
54af5a
cb2af0 CPGPdiskApp theApp;
a3af5a
eeaf5a
d504c6 ///////////////////////////////////////
2d6aed // Global variables for the application
d004c6 ///////////////////////////////////////
67af5a
bfb05d CPGPdiskApp *App;¤  ¤   // pointer to application object
31af5a
a1af5a
9883f5 ///////////////////////////
1fb249 // MFC specific definitions
e683f5 ///////////////////////////
a7af5a
ad0455 // MFC message map
20af5a
9f7a97 BEGIN_MESSAGE_MAP(CPGPdiskApp, CWinApp)
bc8a48 ¤   //{{AFX_MSG_MAP(CPGPdiskApp)
05a0cc ¤   ON_COMMAND(ID_CONTEXT_HELP, OnContextHelp)·
689254 ¤   ON_COMMAND(ID_HELP, OnHelp)
eb2e09 ¤   //}}AFX_MSG
dcaf28 END_MESSAGE_MAP()
41af5a
83af5a
e5a6b9 ///////////////////////////////////////////////////////////////////////
831ba9 // CPGPdiskApp public custom functions and non-default message handlers
baa6b9 ///////////////////////////////////////////////////////////////////////
9eaf5a
80535a // The CPGPdiskApp constructor.
52af5a
fdbdd9 CPGPdiskApp::CPGPdiskApp()
2fbb36 {
--ff47 0007c77a341401100ab Page 2 of CPGPdiskApp.cpp
f8eacc ¤   mPAII¤  ¤   = NULL;
17feb4 ¤   mMainDialog¤= NULL;
3daf5a
fdd0a5 ¤   mCommandLineMode = FALSE;
9aaf5a
375dcb ¤   mAutoUnmount¤   ¤   ¤   = FALSE;
d145cf ¤   mHotKeyEnabled¤ ¤   ¤   = FALSE;
d89a93 ¤   mHotKeyCode¤¤   ¤   ¤   = 0;
e958b2 ¤   mUnmountOnSleep¤¤   ¤   = FALSE;
d8ac24 ¤   mNoSleepIfUnmountFail¤  = kDefaultNoSleepIfUnmountFail;
1f5028 ¤   mUnmountTimeout¤¤   ¤   = kDefaultUnmountTimeout;
b9af5a
db2734 ¤   if (IsWin95CompatibleMachine())
5cc7a1 ¤   {
bb07f0 ¤   ¤   mPlatformMaxKbSize = kPGPdiskMaxKbSizeWin95;
623eaa ¤   ¤   mPlatformMinKbSize = kPGPdiskMinKbSizeWin95;
f79371 ¤   }
4a0e24 ¤   else
c1c7a1 ¤   {
4d5505 ¤   ¤   mPlatformMaxKbSize = kPGPdiskMaxKbSizeWinNT;
746c5f ¤   ¤   mPlatformMinKbSize = kPGPdiskMinKbSizeWinNT;
559371 ¤   }
31efe6 }
47af5a
0af987 typedef int __stdcall NetReviewFunc¤
a09bb0 (HWND hwndParent,·
5b7ae1 DWORD dwBindFlags);
2aaf5a
dcfd0a // AbortPGPdiskApp is the correct way to abort.
e7af5a
1ac823 void·
3daa4c CPGPdiskApp::AbortPGPdiskApp()
6abb36 {
21d7ea ¤   exit(-1);
37efe6 }
73af5a
85eead // CallShowAboutBox displays the PGPdisk about box.
e5af5a
90c823 void·
a8745a CPGPdiskApp::CallShowAboutBox()
0ccebb {¤
9d44a6 ¤   AppCommandInfo ACI;
6aaf5a
6e622c ¤   ACI.op¤ ¤   = kAppOp_ShowAboutBox;
4eb2f7 ¤   ACI.flags¤  = NULL;
b5ce4d ¤   ACI.drive¤  = kInvalidDrive;
42df35 ¤   ACI.path[0]¤= '\0';
0faf5a
f9a66d ¤   DispatchAppCommandInfo(&ACI);
e7efe6 }
40af5a
b779b6 // CallShowHelp displays the PGPdisk help file.
cfaf5a
78c823 void·
cf397c CPGPdiskApp::CallShowHelp()
78cebb {¤
3344a6 ¤   AppCommandInfo ACI;
5daf5a
e8c39d ¤   ACI.op¤ ¤   = kAppOp_ShowHelp;
3cb2f7 ¤   ACI.flags¤  = NULL;
f5ce4d ¤   ACI.drive¤  = kInvalidDrive;
52df35 ¤   ACI.path[0]¤= '\0';
04af5a
04a66d ¤   DispatchAppCommandInfo(&ACI);
0eefe6 }
b2af5a
a79d1f // CallShowPrefs displays the PGPdisk preferences.
75af5a
6ec823 void·
62feb2 CPGPdiskApp::CallShowPrefs()
97cebb {¤
7c44a6 ¤   AppCommandInfo ACI;
--3406 00009790d99401100ab Page 3 of CPGPdiskApp.cpp
e0af5a
356320 ¤   ACI.op¤ ¤   = kAppOp_ShowPrefs;
fab2f7 ¤   ACI.flags¤  = NULL;
b7ce4d ¤   ACI.drive¤  = kInvalidDrive;
3fdf35 ¤   ACI.path[0]¤= '\0';
5faf5a
bfa66d ¤   DispatchAppCommandInfo(&ACI);
3defe6 }
bfaf5a
b0a8bc // SetDriverPrefsFromApp informs the driver of the state of the application's
420ef8 // preferences.
44af5a
2c2292 DualErr·
804789 CPGPdiskApp::SetDriverPrefsFromApp()
d4bb36 {
1e7c21 ¤   return SetDriverPrefs(mAutoUnmount, mUnmountTimeout);
1defe6 }
a3af5a
210273 // CreatePGPdiskResidentApp starts a normal PGPdisk resident application.
5faf5a
032292 DualErr·
2f20ce CPGPdiskApp::CreatePGPdiskResidentApp()
83bb36 {
70705b ¤   DualErr¤¤   ¤   ¤   derr;
f974d8 ¤   PROCESS_INFORMATION¤PI;
80035d ¤   STARTUPINFO¤¤   ¤   SI;
7caf5a
aa9a57 ¤   pgpClearMemory(&SI, sizeof(SI));
f28957 ¤   SI.cb = sizeof(SI);
64af5a
f14142 ¤   if (!CreateProcess(NULL, (LPSTR) kPGPdiskResAppName, NULL, NULL, FALSE,·
6fa6c0 ¤   ¤   0, NULL, NULL, &SI, &PI))
4ac7a1 ¤   {
dcadec ¤   ¤   derr = DualErr(kPGDMinorError_CreateProcessFailed, GetLastError());
ed9371 ¤   }
f7af5a
5233e3 ¤   return derr;
49efe6 }
c5af5a
451a94 // UpdatePGPdiskResident starts and/or updates the PGPdiskResident
af6c14 // application.
a3af5a
6a77be PGPBoolean·
77454d CPGPdiskApp::UpdatePGPdiskResident()
6dbb36 {
049a95 ¤   DualErr¤¤   ¤   derr;
fbe29b ¤   PGPBoolean¤ ¤   succeeded¤  = FALSE;
dcebfc ¤   PGPdiskResInfo¤ *pgpDiskResInfo;
bb52c1 ¤   SharedMemory¤   pgpDiskResInfoMem;
2aaf5a
a8a500 ¤   // Try to find an existing PGPdiskResident application.
f4cfcc ¤   derr = pgpDiskResInfoMem.Attach(kPGPdiskResSharedMemName);
a5af5a
54aca1 ¤   // If found, update it. If not, spawn another one.
552361 ¤   if (derr.IsntError())
48c7a1 ¤   {
1ea3a5 ¤   ¤   pgpDiskResInfo = (PGPdiskResInfo *)·
52a4a7 ¤   ¤   ¤   pgpDiskResInfoMem.GetMemPointer();
fdaf5a
c44169 ¤   ¤   PostMessage(pgpDiskResInfo->hiddenWindowHwnd, WM_PGPDISKRES_NEWPREFS,·
b45639 ¤   ¤   ¤   kPGPdiskMessageMagic, NULL);
feaf5a
6839fd ¤   ¤   succeeded = TRUE;
1b9371 ¤   }
2b0e24 ¤   else
dfc7a1 ¤   {
180fcd ¤   ¤   succeeded = CreatePGPdiskResidentApp().IsntError();
179371 ¤   }
2daf5a
a873c3 ¤   if (pgpDiskResInfoMem.IsMemAttached())
cf81dd ¤   ¤   pgpDiskResInfoMem.Detach();
09af5a
--29c7 000c9eac206401100ab Page 4 of CPGPdiskApp.cpp
9c9af0 ¤   return succeeded;
22efe6 }
a0af5a
8afd0e // FindAndShowNonCommandLinePGPdiskApp looks for and shows a pre-existing
23dfb9 // non-command-line PGPdisk application. TRUE is returned if a match is
55e4ac // found.
00af5a
8277be PGPBoolean·
bc1972 CPGPdiskApp::FindAndShowNonCommandLinePGPdiskApp()
d7bb36 {
03b44e ¤   PGPBoolean foundApp = FALSE;;
47af5a
ff78f1 ¤   try
73c7a1 ¤   {
9cdb23 ¤   ¤   CString¤¤   ¤   ¤   memName;
754753 ¤   ¤   DualErr¤¤   ¤   ¤   derr;
8ea5b0 ¤   ¤   PAppInstanceInfo¤   pAII;
ede2ad ¤   ¤   PGPUInt32¤  ¤   ¤   i;
b4a842 ¤   ¤   SharedMemory¤   ¤   sharedMem;
32af5a
0641de ¤   ¤   // Step through all running apps.
856f19 ¤   ¤   for (i = 0; i < kMaxPGPdiskApps; i++)
035b34 ¤   ¤   {
0db6a7 ¤   ¤   ¤   memName.Format("%s%d", kSharedMemNamePrefix, i);
b6af5a
3065f9 ¤   ¤   ¤   if (mSharedAppInfoMem.IsMemAttached() &&·
de2b15 ¤   ¤   ¤   ¤   (memName == mSharedAppInfoMem.GetMemName()))
36f776 ¤   ¤   ¤   {
46d040 ¤   ¤   ¤   ¤   continue;
53a3a6 ¤   ¤   ¤   }
b7af5a
0edf71 ¤   ¤   ¤   // Try to attach the shared memory.
3142d3 ¤   ¤   ¤   derr = sharedMem.Attach(memName);
b1af5a
b06559 ¤   ¤   ¤   // If succeeded, examine the memory.
889d3d ¤   ¤   ¤   if (derr.IsntError())
7af776 ¤   ¤   ¤   {
7a6776 ¤   ¤   ¤   ¤   pAII = (PAppInstanceInfo) sharedMem.GetMemPointer();
1caf5a
b3c6a5 ¤   ¤   ¤   ¤   // If it's a non-command-line app, show it.
f5f7c8 ¤   ¤   ¤   ¤   if (!pAII->commandLineMode)
c072c3 ¤   ¤   ¤   ¤   {
b1d62f ¤   ¤   ¤   ¤   ¤   foundApp = TRUE;
e091b9 ¤   ¤   ¤   ¤   ¤   BringThisPGPdiskAppToFront(pAII->mainDialogHwnd);
23af5a
2014c3 ¤   ¤   ¤   ¤   ¤   break;
4b2613 ¤   ¤   ¤   ¤   }
c7a3a6 ¤   ¤   ¤   }
c7af5a
03a05f ¤   ¤   ¤   if (sharedMem.IsMemAttached())
b11702 ¤   ¤   ¤   ¤   sharedMem.Detach();
920fe4 ¤   ¤   }
609371 ¤   }
333c88 ¤   catch (CMemoryException *ex)
6ac7a1 ¤   {
676adc ¤   ¤   ex->Delete();
029371 ¤   }
8faf5a
a00045 ¤   return foundApp;
24efe6 }
80af5a
9dc6f2 // FindAndShowSimilarPGPdiskApp looks for a pre-existing PGPdisk
b05fe4 // application that is currently performing the same function that this
7fc49f // application is performing now. If one is found, its frontmost window is
587a76 // shown and TRUE is returned.
83af5a
e377be PGPBoolean·
dac138 CPGPdiskApp::FindAndShowSimilarPGPdiskApp(PAppCommandInfo pACI)
57bb36 {
3aeda1 ¤   PGPBoolean foundApp = FALSE;
f5af5a
c978f1 ¤   try
--a4a5 00099afcd59401100ab Page 5 of CPGPdiskApp.cpp
f7c7a1 ¤   {
9ddb23 ¤   ¤   CString¤¤   ¤   ¤   memName;
a64753 ¤   ¤   DualErr¤¤   ¤   ¤   derr;
42a5b0 ¤   ¤   PAppInstanceInfo¤   pAII;
cee2ad ¤   ¤   PGPUInt32¤  ¤   ¤   i;
45a842 ¤   ¤   SharedMemory¤   ¤   sharedMem;
e4af5a
e5d178 ¤   ¤   pgpAssertAddrValid(pACI, AppCommandInfo);
7eaf5a
e8d0c7 ¤   ¤   // Compare current command to commands of all running apps.
526f19 ¤   ¤   for (i = 0; i < kMaxPGPdiskApps; i++)
0e5b34 ¤   ¤   {
dab6a7 ¤   ¤   ¤   memName.Format("%s%d", kSharedMemNamePrefix, i);
3aaf5a
51711f ¤   ¤   ¤   // Don't consider ourselves.
fc65f9 ¤   ¤   ¤   if (mSharedAppInfoMem.IsMemAttached() &&·
c92b15 ¤   ¤   ¤   ¤   (memName == mSharedAppInfoMem.GetMemName()))
9bf776 ¤   ¤   ¤   {
5bd040 ¤   ¤   ¤   ¤   continue;
49a3a6 ¤   ¤   ¤   }
91af5a
26df71 ¤   ¤   ¤   // Try to attach the shared memory.
bc42d3 ¤   ¤   ¤   derr = sharedMem.Attach(memName);
21af5a
0a6559 ¤   ¤   ¤   // If succeeded, examine the memory.
ae9d3d ¤   ¤   ¤   if (derr.IsntError())
cef776 ¤   ¤   ¤   {
7f6776 ¤   ¤   ¤   ¤   pAII = (PAppInstanceInfo) sharedMem.GetMemPointer();
77af5a
f787b7 ¤   ¤   ¤   ¤   // Compare commands.
46eabc ¤   ¤   ¤   ¤   if (AreAppCommandsSimilar(pACI, &pAII->ACI))
7972c3 ¤   ¤   ¤   ¤   {
3ad62f ¤   ¤   ¤   ¤   ¤   foundApp = TRUE;
1b91b9 ¤   ¤   ¤   ¤   ¤   BringThisPGPdiskAppToFront(pAII->mainDialogHwnd);
89af5a
8214c3 ¤   ¤   ¤   ¤   ¤   break;
502613 ¤   ¤   ¤   ¤   }
07a3a6 ¤   ¤   ¤   }
e7af5a
a1a05f ¤   ¤   ¤   if (sharedMem.IsMemAttached())
621702 ¤   ¤   ¤   ¤   sharedMem.Detach();
a30fe4 ¤   ¤   }
f39371 ¤   }
8d3c88 ¤   catch (CMemoryException *ex)
11c7a1 ¤   {
b06adc ¤   ¤   ex->Delete();
059371 ¤   }
3eaf5a
a40045 ¤   return foundApp;
bfefe6 }
36af5a
154e9f // SetSharedMemoryCommandInfo sets the ACI structure.
0baf5a
e0c823 void·
83e140 CPGPdiskApp::SetSharedMemoryCommandInfo(AppCommandInfo *pACI)
eebb36 {
b09e46 ¤   pgpAssertAddrValid(pACI, AppCommandInfo);
ccaf5a
5da83e ¤   mPAII->ACI = (* pACI);
b1efe6 }
6aaf5a
7f9a3c // ClearSharedMemoryCommandInfo sets the ACI structure in the app's shared
2fd2e4 // memory object to a NULL op.
36af5a
ddc823 void·
9110c4 CPGPdiskApp::ClearSharedMemoryCommandInfo()
f5bb36 {
219209 ¤   pgpAssertAddrValid(mPAII, AppInstanceInfo);
0aaf5a
b4618f ¤   mPAII->ACI.op¤  ¤   = kAppOp_InvalidRequest;
43c7a2 ¤   mPAII->ACI.flags¤   = NULL;
99b2f5 ¤   mPAII->ACI.drive¤   = kInvalidDrive;
--158d 00021535707401100ab Page 6 of CPGPdiskApp.cpp
c6d92c ¤   mPAII->ACI.path[0]¤ = NULL;
11efe6 }
8aaf5a
7c10fb // ExitPGPdiskApp is the correct way to exit normally.
19af5a
55c823 void·
7b21df CPGPdiskApp::ExitPGPdiskApp()
9cbb36 {
ece660 ¤   // This works even when called from other threads.
cc884f ¤   ::PostThreadMessage(App->m_nThreadID, WM_QUIT, NULL, NULL);
b9efe6 }
56af5a
8baf5a
b49bef //////////////////////////////////////////////
72fd77 // CPGPdiskApp public default message handlers
129bef //////////////////////////////////////////////
28af5a
293838 // ExitInstance is called right before the application dies.
2faf5a
89fcf4 int·
8fb903 CPGPdiskApp::ExitInstance()
40bb36 {
e17d36 ¤   DualErr derr;
25af5a
dc1256 ¤   // Close our handle to the driver.
ee5536 ¤   derr = ClosePGPdiskDriver();
2a3afe ¤   pgpAssert(derr.IsntError());
96af5a
6f0d53 ¤   // Release our shared memory.
b3219b ¤   derr = DeleteAppInfoStruct();
f33afe ¤   pgpAssert(derr.IsntError());
f2af5a
b0bc90 ¤   // Delete the main dialog.
85d51f ¤   DeleteMainDialog();
a7af5a
90a2cc ¤   // Unintialize OLE.
3f9ef3 ¤   OleUninitialize();
e2af5a
997e73 ¤   // Clear the PGPdisk container.
cfc711 ¤   mPGPdisks.ClearContainerWithDelete();
b5af5a
e0c23f ¤   // Cleanup explicit linkage.
431c25 ¤   CleanupExplicitLinkage();
44af5a
efecec ¤   return CWinApp::ExitInstance();
63efe6 }
56af5a
d55627 // InitInstance is called during application initialization.
f4af5a
807efe BOOL·
131872 CPGPdiskApp::InitInstance()
e7bb36 {
527d36 ¤   DualErr derr;
ccaf5a
6ca669 ¤   App = this;
adaf5a
02ecdc ¤   // If there is a command line, we are in command-line mode.
8e9c31 ¤   mCommandLineMode = (m_lpCmdLine[0] != NULL);
78af5a
de4bb6 ¤   // Quit if we're not running correct Windows version.
fda255 ¤   CheckWindowsVersion();
7caf5a
69f91e ¤   // Switch to another non-command-line PGPdisk if one exists.
3d0b40 ¤   EnforceUniquePGPdiskGUI();
15af5a
288ed5 #if PGPDISK_BETAVERSION
16af5a
9919ad ¤   // Set beta timeout (once).
010dbd ¤   SetPGPdiskBetaTimeout();
8daf5a
7bbb3d ¤   // Check if the beta has timed out.
21a3b9 ¤   CheckBetaTimeout();
--a626 000e3cd6627401100ab Page 7 of CPGPdiskApp.cpp
e0af5a
1d5766 #elif PGPDISK_DEMOVERSION
81af5a
d97996 ¤   // Check if the demo has timed out.
746460 ¤   CheckDemoTimeout();
5eaf5a
9fe121 #endif // PGPDISK_BETAVERSION
46af5a
453d5e ¤   // Resolve APIs unique to a platform.
f7f1de ¤   derr = ExplicitlyLinkAPIsForPlatform();
c7af5a
690a22 ¤   // If there is a command line, we will not show the main window and we
352a94 ¤   // will be sure to exit after all commands are processed.
61af5a
db2361 ¤   if (derr.IsntError())
fbc7a1 ¤   {
1af3ba #ifdef _AFXDLL
ad9aa9 ¤   ¤   // Call when using MFC in shared DLL.
3db195 ¤   ¤   Enable3dControls();
47db21 #else
f15119 ¤   ¤   // Call when linking to MFC statically.
5cb9d8 ¤   ¤   Enable3dControlsStatic();
037454 #endif
b5af5a
455aad ¤   ¤   // Intialize OLE.
052195 ¤   ¤   if (OleInitialize(NULL) != S_OK)
592f43 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OleInitFailed);
129371 ¤   }
61af5a
6d741a ¤   // Open a handle to the driver.
4c2361 ¤   if (derr.IsntError())
e1c7a1 ¤   {
8f46c3 ¤   ¤   derr = OpenPGPdiskDriver();
b79371 ¤   }
dcaf5a
d42626 ¤   // Prepare PGPdisk registry settings.
0e2361 ¤   if (derr.IsntError())
08c7a1 ¤   {
ae6158 ¤   ¤   derr = InitRegistryKeys();
b99371 ¤   }
ddaf5a
e2e26e ¤   // Get personalization info from registry.
4e2361 ¤   if (derr.IsntError())
72c7a1 ¤   {
4ccad4 ¤   ¤   derr = GetPersonalizationInfo();
559371 ¤   }
1faf5a
a58139 ¤   // Start and/or update the PGPdiskResident application.
522361 ¤   if (derr.IsntError())
97c7a1 ¤   {
fbd972 ¤   ¤   if (!UpdatePGPdiskResident())
9c9c4c ¤   ¤   ¤   ReportError(kPGDMajorError_CouldntFindResidentApp);
8a9371 ¤   }
f3af5a
282361 ¤   if (derr.IsntError())
eac7a1 ¤   {
23aa09 ¤   ¤   // Show splash screen if not in command-line mode.
c5cdf7 ¤   ¤   if (!mCommandLineMode)
365069 ¤   ¤   ¤   ShowSplashScreen();
e61b52 ¤   ¤
b249e6 ¤   ¤   // Create and hide main dialog.
fb37d3 ¤   ¤   derr = CreateMainDialog();
ff9371 ¤   }
ebaf5a
4c2175 ¤   // Allocate our shared memory.
3a2361 ¤   if (derr.IsntError())
c0c7a1 ¤   {
990908 ¤   ¤   derr = CreateAppInfoStruct();
5c9371 ¤   }
70af5a
10bc02 ¤   // Check version numbers of the driver.
e32361 ¤   if (derr.IsntError())
--2caf 0004af48ecb401100ab Page 8 of CPGPdiskApp.cpp
f7c7a1 ¤   {
7eb0a1 ¤   ¤   derr = CheckDriverVersion();
b09371 ¤   }
0eaf5a
43304d ¤   // Notify the driver of our preferences.
332361 ¤   if (derr.IsntError())
a3c7a1 ¤   {
adc544 ¤   ¤   derr = SetDriverPrefsFromApp();
939371 ¤   }
aaaf5a
75b6db ¤   // Get PGPdisk info.
c62361 ¤   if (derr.IsntError())
01c7a1 ¤   {
70630f ¤   ¤   derr = UpdateAppPGPdiskInfo();
c49371 ¤   }
1faf5a
3660b5 ¤   // If there is a command line, process it now, else show the main window.
7c2361 ¤   if (derr.IsntError())
bec7a1 ¤   {
c58d53 ¤   ¤   if (mCommandLineMode)
465b34 ¤   ¤   {
55c6c4 ¤   ¤   ¤   CPGPdiskCmdLine cmdInfo;
00af5a
07d8c9 ¤   ¤   ¤   cmdInfo.ParseCommandLine();
44fe12 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);¤   // will quit app
c90fe4 ¤   ¤   }
7c0e1d ¤   ¤   else
5e5b34 ¤   ¤   {
9e65d2 ¤   ¤   ¤   mMainDialog->ShowWindow(SW_SHOWNORMAL);
4c65ae ¤   ¤   ¤   mMainDialog->SetForegroundWindow();¤
ed0fe4 ¤   ¤   }
2b9371 ¤   }
86af5a
784bb3 ¤   if (derr.IsError())
eec7a1 ¤   {
8f75c7 ¤   ¤   ReportError(kPGDMajorError_AppInitFailed, derr);
f07025 ¤   ¤   ExitPGPdiskApp();
359371 ¤   }
c9af5a
80c2e7 ¤   return TRUE;
a8efe6 }
fbaf5a
2faf5a
d9da3d ////////////////////////////////////////////////////////////////////////
eaba51 // CPGPdiskApp private custom functions and non-default message handlers
08da3d ////////////////////////////////////////////////////////////////////////
1caf5a
b46df8 // EnforceUniquePGPdiskGUI ensures there is only one non-command-line
67b73a // instance of PGPdisk.
bbaf5a
9cc823 void·
32f5d9 CPGPdiskApp::EnforceUniquePGPdiskGUI()
87bb36 {
bac2e4 ¤   if (!mCommandLineMode && FindAndShowNonCommandLinePGPdiskApp())
3fc7a1 ¤   {
be3347 ¤   ¤   AbortPGPdiskApp();
e19371 ¤   }
03efe6 }
7daf5a
0ad6d3 // CheckWindowsVersion exits if we are running an incompatible version of
4274f7 // Windows.
62af5a
6bc823 void·
2c262f CPGPdiskApp::CheckWindowsVersion()
15bb36 {
78e20f ¤   if (!IsWin95CompatibleMachine() && !IsWinNT4CompatibleMachine())
2fc7a1 ¤   {
99f77b ¤   ¤   ReportError(kPGDMajorError_NotCompatibleWindows);
053347 ¤   ¤   AbortPGPdiskApp();
6f9371 ¤   }
2befe6 }
4aaf5a
--6684 0004a1160e7401100ab Page 9 of CPGPdiskApp.cpp
138ed5 #if PGPDISK_BETAVERSION
34af5a
4d94a8 // CheckBetaTimeout checks if we are running an expired beta and warns or
931918 // exits as appropriate.
25af5a
c5c823 void·
28fa82 CPGPdiskApp::CheckBetaTimeout()
a9bb36 {
284c2b ¤   if (!mCommandLineMode && HasBetaTimedOut())
8ac7a1 ¤   {
78b5ca ¤   ¤   DisplayMessage(kPGPdiskBetaTimeoutWarning);
3e9371 ¤   }
e9efe6 }
20af5a
605766 #elif PGPDISK_DEMOVERSION
e7af5a
7d7640 // CheckDemoTimeout checks if we are running an expired demo and warns or
661918 // exits as appropriate.
7aaf5a
42c823 void·
682753 CPGPdiskApp::CheckDemoTimeout()
e8bb36 {
a407a0 ¤   if (!mCommandLineMode && HasDemoTimedOut())
7fc7a1 ¤   {
a2fd98 ¤   ¤   CNagBuyDialog nagBuyDialog;
c0af5a
86a64d ¤   ¤   nagBuyDialog.DisplayDialog(kPGPdiskDemoTimeoutWarning);
179371 ¤   }
9cefe6 }
efaf5a
1de121 #endif // PGPDISK_BETAVERSION
b3af5a
6857e4 // BringThisPGPdiskAppToFront displays the frontmost window of the PGPdisk
6f7b44 // app specified by the given main dialog handle.
73af5a
fec823 void·
fe3094 CPGPdiskApp::BringThisPGPdiskAppToFront(HWND mainDialogHwnd)
86bb36 {
6afe41 ¤   HWND frontmostWindow;
eaaf5a
b3baa0 ¤   pgpAssert(IsntNull(mainDialogHwnd));
15af5a
ad22e6 ¤   frontmostWindow = GetLastActivePopup(mainDialogHwnd);
ecaf5a
3caf76 ¤   ShowWindow(frontmostWindow, SW_RESTORE);
2dd304 ¤   SetForegroundWindow(frontmostWindow);
1befe6 }
bcaf5a
d70d76 // InitRegistryKeys prepares the registry with necessary PGPdisk
f5931b // initialization values, and acquires other values from the registry as
c527cf // needed.
2daf5a
522292 DualErr·
708972 CPGPdiskApp::InitRegistryKeys()
7dbb36 {
0e945d ¤   DualErr¤derr;
99af5a
c3c85d ¤   // Update PGPdiskApp pathnames in the registry.
f3cf4a ¤   SetRegistryPaths();
eaaf5a
3dbb51 ¤   // Now get the application preferences from the registry.
9a2361 ¤   if (derr.IsntError())
12c7a1 ¤   {
30c097 ¤   ¤   derr = GetRegistryPrefs();
bb9371 ¤   }
1eaf5a
0633e3 ¤   return derr;
45efe6 }
69af5a
44784f // CreateMainDialog creates the main dialog and display it.
4caf5a
4a2292 DualErr·
--a335 0008587e9b0401100ab Page 10 of CPGPdiskApp.cpp
3ea766 CPGPdiskApp::CreateMainDialog()
16bb36 {
42be41 ¤   DualErr¤¤   derr;
632e34 ¤   PGPBoolean¤ createdMainDialog¤  = FALSE;
a0af5a
5cbd41 ¤   // Allocate the dialog.
1578f1 ¤   try
10c7a1 ¤   {
8b3d3b ¤   ¤   mMainDialog = new CMainDialog;
859371 ¤   }
433c88 ¤   catch (CMemoryException *ex)
08c7a1 ¤   {
42ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
fb6adc ¤   ¤   ex->Delete();
d19371 ¤   }
e8af5a
bca83d ¤   createdMainDialog = derr.IsntError();
e8af5a
6a4aff ¤   // Create the actual dialog.
d52361 ¤   if (derr.IsntError())
00c7a1 ¤   {
03dc57 ¤   ¤   if (!mMainDialog->Create(IDD_MAIN_DLG))
c439a7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
499371 ¤   }
5caf5a
352361 ¤   if (derr.IsntError())
f9c7a1 ¤   {
2766cc ¤   ¤   m_pMainWnd = mMainDialog;
54ec55 ¤   ¤   RegisterPGPdiskMsgBoxParent(mMainDialog);
48af5a
079b2f ¤   ¤   // Set its title.
cc83d3 ¤   ¤   mMainDialog->SetWindowText(kPGPdiskMainWndTitle);
299371 ¤   }
eeaf5a
794bb3 ¤   if (derr.IsError())
cdc7a1 ¤   {
2b319d ¤   ¤   if (createdMainDialog)
aa5b34 ¤   ¤   {
3d78bb ¤   ¤   ¤   delete mMainDialog;
b45ebd ¤   ¤   ¤   mMainDialog = NULL;
cb0fe4 ¤   ¤   }
db9371 ¤   }
c1af5a
9b33e3 ¤   return derr;
52efe6 }
51af5a
01b5a8 // DeleteMainDialog destroys the main dialog.
75af5a
42c823 void·
f0f3a7 CPGPdiskApp::DeleteMainDialog()
f9bb36 {
a6ad6d ¤   if (IsntNull(mMainDialog))
a1c7a1 ¤   {
5bd5e5 ¤   ¤   delete mMainDialog;
81f3e3 ¤   ¤   mMainDialog = NULL;
719371 ¤   }
86efe6 }
dfaf5a
446196 // CreateAppInfoStruct allocates our shared application info structure.
f5af5a
c82292 DualErr·
8a42a6 CPGPdiskApp::CreateAppInfoStruct()
0cbb36 {
8b10d7 ¤   DualErr¤¤   derr, memError;
bc3af5 ¤   PGPBoolean¤ foundNameForMem¤= FALSE;
13af5a
142a42 ¤   pgpAssertAddrValid(mMainDialog, CMainDialog);
4caf5a
ea78f1 ¤   try
46c7a1 ¤   {
a18198 ¤   ¤   CString¤¤   memName;
853cc8 ¤   ¤   PGPUInt32¤  i;
--1d25 000db8e0859401100ab Page 11 of CPGPdiskApp.cpp
e0af5a
eb9aa7 ¤   ¤   // Find an untaken name for our shared memory.
b86f19 ¤   ¤   for (i = 0; i < kMaxPGPdiskApps; i++)
455b34 ¤   ¤   {
56b6a7 ¤   ¤   ¤   memName.Format("%s%d", kSharedMemNamePrefix, i);
31af5a
f1791c ¤   ¤   ¤   memError = mSharedAppInfoMem.CreateAndAttach(memName,·
6ac438 ¤   ¤   ¤   ¤   sizeof(AppInstanceInfo));
d8af5a
98bddd ¤   ¤   ¤   if (memError.IsntError())
2ff622 ¤   ¤   ¤   ¤   break;
040fe4 ¤   ¤   }
2faf5a
15cc49 ¤   ¤   if (memError.IsError())
2bd6aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_TooManyAppsRegistered);
0caf5a
89aa35 ¤   ¤   if (derr.IsntError())
655b34 ¤   ¤   {
423da9 ¤   ¤   ¤   // Get shared memory pointer.
c3bd72 ¤   ¤   ¤   mPAII = (PAppInstanceInfo) mSharedAppInfoMem.GetMemPointer();
5eaf5a
6e9d31 ¤   ¤   ¤   // Initialize the shared memory object.
295f93 ¤   ¤   ¤   mPAII->commandLineMode = mCommandLineMode;
19331d ¤   ¤   ¤   mPAII->mainDialogHwnd = mMainDialog->m_hWnd;
aaaf5a
7375cf ¤   ¤   ¤   ClearSharedMemoryCommandInfo();
d50fe4 ¤   ¤   }
e79371 ¤   }
233c88 ¤   catch (CMemoryException *ex)
e6c7a1 ¤   {
79ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
c96adc ¤   ¤   ex->Delete();
8e9371 ¤   }
2aaf5a
e133e3 ¤   return derr;
15efe6 }
2baf5a
b27a3b // DeleteAppInfoStruct deletes our shared application info structure.
bfaf5a
be2292 DualErr·
0ba677 CPGPdiskApp::DeleteAppInfoStruct()
ecbb36 {
9b7d36 ¤   DualErr derr;
70af5a
ceebf6 ¤   if (IsntNull(mPAII))
95c7a1 ¤   {
490448 ¤   ¤   pgpAssertAddrValid(mPAII, AppInstanceInfo);
ecaf5a
e30147 ¤   ¤   derr = mSharedAppInfoMem.Detach();
da949c ¤   ¤   mPAII = NULL;
079371 ¤   }
bbaf5a
df33e3 ¤   return derr;
c3efe6 }
15af5a
f551ab // ShowPGPdiskAboutBox displays the PGPdisk about box.
68af5a
122292 DualErr·
94deec CPGPdiskApp::ShowPGPdiskAboutBox()
71bb36 {
e8a4b6 ¤   CAboutBoxDialog¤aboutBox;
e39a95 ¤   DualErr¤¤   ¤   derr;
3faf5a
92fc7f ¤   derr = aboutBox.DisplayAboutBox();
bbaf5a
4f33e3 ¤   return derr;
d4efe6 }
03af5a
605278 // ShowPGPdiskHelp displays the PGPdisk help file.
d6af5a
3b314a void
db2e05 CPGPdiskApp::ShowPGPdiskHelp()
--f1b6 0014b69916b401100ab Page 12 of CPGPdiskApp.cpp
2cbb36 {
d785f8 ¤   ::WinHelp(mMainDialog->GetSafeHwnd(), m_pszHelpFilePath, HELP_FINDER,·
ede227 ¤   ¤   NULL);
27efe6 }
dfaf5a
214005 // ShowPGPdiskPrefs displays the PGPdisk preferences.
86af5a
e82292 DualErr·
c710e3 CPGPdiskApp::ShowPGPdiskPrefs()
36bb36 {
81d201 ¤   CPreferencesSheet¤  prefsSheet;
6c705b ¤   DualErr¤¤   ¤   ¤   derr;
c9af5a
f26e37 ¤   derr = prefsSheet.mInitErr;
c5af5a
a12361 ¤   if (derr.IsntError())
39c7a1 ¤   {
d6a7b7 ¤   ¤   derr = prefsSheet.DisplayPreferences();
b99371 ¤   }
0aaf5a
c733e3 ¤   return derr;
0befe6 }
c5af5a
cc3e96 // ShowSplashScreen displays the splash screen once a day.
5baf5a
7bc823 void·
6773ff CPGPdiskApp::ShowSplashScreen()
66bb36 {
e94fa6 ¤   CSplashScreenDialog¤splashDialog;
4833e6 ¤   PGPUInt32¤  ¤   ¤   currentDayIndex, lastDayIndex;
3accc1 ¤   PGPUInt64¤  ¤   ¤   currentTime, lastDateSplashed;
62af5a
ef5cc9 ¤   // Get the current time.
81d77a ¤   currentTime = GetSecondsSince1970();
184e0f ¤   currentDayIndex = (PGPUInt32) (currentTime / kSecondsInADay);
2daf5a
540242 ¤   // Get the last time we splashed the user.
ddaa11 ¤   lastDateSplashed = PGPdiskGetPrefQWord(kRegistryLastDateSplashKey,·
59b01e ¤   ¤   kInvalidRegQWordValue);
1eaf5a
d6de5f ¤   lastDayIndex = (PGPUInt32) (lastDateSplashed / kSecondsInADay);
33af5a
523360 ¤   // If the key doesn't exists or if we are on a different day than the
0275df ¤   // last time we splashed, splash now.
0aaf5a
a1e57a ¤   if ((lastDateSplashed == kInvalidRegQWordValue) ||·
d33b69 ¤   ¤   (currentDayIndex > lastDayIndex))
3cc7a1 ¤   {
a4bdd3 ¤   ¤   splashDialog.ShowSplashScreen();
cdaf5a
417a6e ¤   ¤   // Remember that we splashed.
34bb8d ¤   ¤   PGPdiskSetPrefQWord(kRegistryLastDateSplashKey, currentTime);
989371 ¤   }
4befe6 }
--47c4 000cbd3fa1b401100ac Page 1 of CPGPdiskApp.h
541bc3 //////////////////////////////////////////////////////////////////////////////
247592 // CPGPdiskApp.h
2f465d //
ad70a4 // Declaration of class CPGPdiskApp.
041bc3 //////////////////////////////////////////////////////////////////////////////
caaf5a
a82863 // $Id: CPGPdiskApp.h,v 1.3.2.39.2.6 1998/10/28 00:13:27 nryan Exp $
96af5a
6fcbce // Copyright (C) 1998 by Network Associates, Inc.
6a71ae // All rights reserved.
adaf5a
1de691 #ifndef Included_CPGPdiskApp_h¤ // [
3caab8 #define Included_CPGPdiskApp_h
9baf5a
403a85 #include "DualErr.h"
e47efd #include "LinkResolution.h"
045f98 #include "PGPdiskContainer.h"
7485af #include "SecureString.h"
476673 #include "SharedMemory.h"
166560 #include "Win32Utils.h"
43dd74 #include "WindowsVersion.h"
beaf5a
577d4e #include "CPGPdiskAppACI.h"
525590 #include "CPGPdiskAppWinutils.h"
34af5a
d0af5a
94d557 ////////
3402c9 // Types
96d557 ////////
a5af5a
787777 class CMainDialog;
65af5a
6837e6 // AppInstanceInfo stores information about a currently running instance of
76131c // the PGPdisk application.
95af5a
fd9648 typedef struct AppInstanceInfo·
91bb36 {
5fae1d ¤   PGPBoolean¤ commandLineMode;
6f2208 ¤   HWND¤   ¤   mainDialogHwnd;
e4af5a
dc55ef ¤   AppCommandInfo¤ ACI;
23af5a
e3a6a1 } AppInstanceInfo, *PAppInstanceInfo;
deaf5a
7baf5a
0bca3a ////////////////////
09154f // Class CPGPdiskApp
8fca3a ////////////////////
96af5a
e92c6c // Class CPGPdiskApp is the MFC-required class representing the PGPdisk
781562 // application itself.
4daf5a
728d9e class CPGPdiskApp : public CWinApp
81bb36 {
5a5ed4 public:
00bf31 ¤   // Public data members
46af5a
84555c ¤   PAppInstanceInfo¤   mPAII;¤ ¤   ¤   ¤   ¤   // shared info about app
fefb32 ¤   CMainDialog¤¤   ¤   *mMainDialog;¤  ¤   ¤   // the main dialog
f241e8 ¤   PGPdiskContainer¤   mPGPdisks;¤ ¤   ¤   ¤   // PGPdisks container
96af5a
2b7121 ¤   PGPBoolean¤ ¤   ¤   mCommandLineMode;¤  ¤   // have a command line?
13af5a
f7260a ¤   CString¤¤   ¤   ¤   mUserText;¤ ¤   ¤   ¤   // user name
1e0375 ¤   CString¤¤   ¤   ¤   mOrgText;¤  ¤   ¤   ¤   // organization name
e6af5a
d10f94 ¤   PGPBoolean¤ ¤   ¤   mAutoUnmount;¤  ¤   ¤   // auto-unmount enabled?
c1a4cb ¤   PGPBoolean¤ ¤   ¤   mHotKeyEnabled;¤¤   ¤   // unmount hotkey enabled?
511096 ¤   PGPUInt16¤  ¤   ¤   mHotKeyCode;¤   ¤   ¤   // hot key codes
c7f365 ¤   PGPBoolean¤ ¤   ¤   mUnmountOnSleep;¤   ¤   // unmount on sleep?
f4af78 ¤   PGPBoolean¤ ¤   ¤   mNoSleepIfUnmountFail;¤ // no sleep unmount fails?
cb8e09 ¤   PGPUInt32¤  ¤   ¤   mUnmountTimeout;¤   ¤   // mins b4 auto-unmount
--7674 000cdee6cdd401100ac Page 2 of CPGPdiskApp.h
e0af5a
80e9e9 ¤   PGPUInt32¤  ¤   ¤   mPlatformMaxKbSize;¤¤   // max size PGPdisk
8b92c1 ¤   PGPUInt32¤  ¤   ¤   mPlatformMinKbSize;¤¤   // min size PGPdisk
93af5a
c94943 ¤   ¤   ¤   ¤   ¤   CPGPdiskApp();
c6af5a
1da216 ¤   // From CPGPdiskApp.cpp
79af5a
cb0215 ¤   void¤   ¤   ¤   AbortPGPdiskApp();
22a115 ¤   void¤   ¤   ¤   ExitPGPdiskApp();
6caf5a
9a7e31 ¤   void¤   ¤   ¤   CallShowAboutBox();
8a793d ¤   void¤   ¤   ¤   CallShowHelp();
36a87c ¤   void¤   ¤   ¤   CallShowPrefs();
a6af5a
b1e14d ¤   DualErr¤¤   ¤   SetDriverPrefsFromApp();
3c7b7f ¤   DualErr¤¤   ¤   CreatePGPdiskResidentApp();
b9ec16 ¤   PGPBoolean¤ ¤   UpdatePGPdiskResident();
93af5a
956249 ¤   PGPBoolean¤ ¤   FindAndShowNonCommandLinePGPdiskApp();
955e3b ¤   PGPBoolean¤ ¤   FindAndShowSimilarPGPdiskApp(AppCommandInfo *pACI);
e3af5a
8cb141 ¤   void¤   ¤   ¤   SetSharedMemoryCommandInfo(AppCommandInfo *pACI);
7c744f ¤   void¤   ¤   ¤   ClearSharedMemoryCommandInfo();
feaf5a
44878b ¤   // From CPGPdiskAppACI.cpp
4caf5a
4b0186 ¤   void¤   ¤   ¤   DispatchAppCommandInfo(PAppCommandInfo pACI);
46af5a
eac934 ¤   // From CPGPdiskAppPassphrase.cpp
71af5a
eb24b2 ¤   void¤   ¤   ¤   AskUserAddPassphrase();
960242 ¤   void¤   ¤   ¤   AskUserChangePassphrase();
4ea802 ¤   void¤   ¤   ¤   AskUserRemovePassphrase(PGPBoolean removeAll = FALSE);
77af5a
58ea4b #if PGPDISK_PUBLIC_KEY
3965b4 ¤   void¤   ¤   ¤   AskUserAddRemovePublicKeys();
9238e4 #endif¤ // PGPDISK_PUBLIC_KEY
d8af5a
95310d ¤   PGPUInt16¤  ¤   CalcPassphraseQuality(SecureString *passphrase);
e6af5a
7f84be ¤   // From CPGPdiskAppRegistry.cpp
b5af5a
835731 ¤   DualErr¤¤   ¤   GetPersonalizationInfo();
3ccf8e ¤   DualErr¤¤   ¤   SetPersonalizationInfo();
9faf5a
48c579 ¤   DualErr¤¤   ¤   GetRegistryPrefs();
fe3daf ¤   DualErr¤¤   ¤   SetRegistryPrefs();
09af5a
16ffb9 ¤   DualErr¤¤   ¤   SetRegistryPaths();
2faf5a
812d67 ¤   // From CPGPdiskAppVolumes.cpp
ecaf5a
21b3fe ¤   void¤   ¤   ¤   AskUserMountPGPdisk();
82863d ¤   void¤   ¤   ¤   AskUserUnmountPGPdisk();
907e30 ¤   void¤   ¤   ¤   AskUserNewPGPdisk();
4c3d91 ¤   void¤   ¤   ¤   AskUserGlobalConvertPGPdisks();
7aaf5a
d5407a ¤   DualErr¤¤   ¤   UpdateAppPGPdiskInfo();
57af5a
aa6f88 ¤   DualErr¤¤   ¤   ConvertPGPdiskPriorToMount(LPCSTR path,·
fcabb2 ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean *pUserSaysNo);
718454 ¤   DualErr¤¤   ¤   ConvertPGPdiskFromGlobalWizard(LPCSTR path,·
aa8589 ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean *pUserSaysCancel);
992316 ¤   DualErr¤¤   ¤   ConvertPGPdisk(LPCSTR path);
ceaf5a
186840 ¤   // From CPGPdiskAppWinutils.cpp
0eaf5a
e220c1 ¤   PGPBoolean¤ ¤   AreAnyDriveLettersFree();
b0af5a
57eba8 ¤   PGPBoolean¤ ¤   IsDirectoryValid(LPCSTR path);
cdb53f ¤   PGPBoolean¤ ¤   IsFileValid(LPCSTR path);
--afd4 00038ce3440401100ac Page 3 of CPGPdiskApp.h
4a6ac5 ¤   PGPBoolean¤ ¤   IsPathValid(LPCSTR path);
b2c97e ¤   PGPBoolean¤ ¤   IsVolumeValid(PGPUInt8 drive);
3baf5a
be8460 ¤   PGPBoolean¤ ¤   IsVolumeFormatted(PGPUInt8 drive);
b6af5a
8f2fdb ¤   PGPBoolean¤ ¤   IsDirectoryReadOnly(LPCSTR path);
2d6340 ¤   PGPBoolean¤ ¤   IsFileReadOnly(LPCSTR path);
ebaf5a
d158e3 ¤   PGPBoolean¤ ¤   IsFileInUseByReader(LPCSTR path);
7d6f81 ¤   PGPBoolean¤ ¤   IsFileInUseByWriter(LPCSTR path);
ed86ab ¤   PGPBoolean¤ ¤   IsFileInUse(LPCSTR path);
76af5a
f76b87 ¤   DualErr¤¤   ¤   BruteForceTestIfEnoughSpace(LPCSTR dir,·
928863 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 kbLength, PGPBoolean *isEnoughSpace);
e80e0e ¤   DualErr¤¤   ¤   HowMuchFreeSpace(LPCSTR path, PGPUInt64 *bytesFree);
7caf5a
5ae43c ¤   static int¤ ¤   ExceptionFilter(int exception);
de3fe2 ¤   DualErr¤¤   ¤   ShowWindowsFormatDialog(PGPUInt8 drive);
65af5a
6e0118 ¤   void¤   ¤   ¤   TweakOnTopAttribute(CWnd *pWnd);
93af5a
ac1211 ¤   BOOL¤   ¤   ¤   GetBitmapAndPalette(UINT nIDResource, CBitmap *bitmap,·
ef872e ¤   ¤   ¤   ¤   ¤   ¤   CPalette *pal);
52af5a
6546e2 ¤   void¤   ¤   ¤   PaintRegistrationInfo(CDC *pDC, PGPUInt32 x, PGPUInt32 y,·
ab7ff1 ¤   ¤   ¤   ¤   ¤   ¤   COLORREF textColor, CWnd *pWnd);
2bd2b4 ¤   void¤   ¤   ¤   PaintVersionInfo(CDC *pDC, PGPUInt32 x, PGPUInt32 y,·
de7ff1 ¤   ¤   ¤   ¤   ¤   ¤   COLORREF textColor, CWnd *pWnd);
63af5a
d83463 ¤   void¤   ¤   ¤   GetTextRect(LPCSTR text, CWnd *pWnd, RECT *pRect);
4aaf5a
0388c4 ¤   void¤   ¤   ¤   TruncateDisplayString(LPCSTR inString,·
6dfe24 ¤   ¤   ¤   ¤   ¤   ¤   CString *outString, CDC *pDC,·
1ca7f4 ¤   ¤   ¤   ¤   ¤   ¤   PGPInt32 maxPixelLength);
7fe008 ¤   void¤   ¤   ¤   FitStringToWindow(LPCSTR inString, CString *outString,·
6b12be ¤   ¤   ¤   ¤   ¤   ¤   CWnd *pWnd);
9829be ¤   void¤   ¤   ¤   FormatFitStringToWindow(LPCSTR inStr, LPCSTR subStr,·
8370cd ¤   ¤   ¤   ¤   ¤   ¤   CString *outString, CWnd *pWnd);
c1af5a
6df02f ¤   //{{AFX_VIRTUAL(CPGPdiskApp)
7767d4 ¤   public:
97019a ¤   virtual BOOL InitInstance();
041c2f ¤   virtual int ExitInstance();
cdaf53 ¤   //}}AFX_VIRTUAL
66af5a
9f5d12 ¤   //{{AFX_MSG(CPGPdiskApp)
b12e09 ¤   //}}AFX_MSG
0daf5a
d10fb9 private:
3fd1f9 ¤   // Private data members
feaf5a
0e783a ¤   SharedMemory mSharedAppInfoMem;¤¤   // shared app info memory
20af5a
91af5a
6aa216 ¤   // From CPGPdiskApp.cpp
4eaf5a
384c2c ¤   void¤   ¤   ¤   ¤   ¤   EnforceUniquePGPdiskGUI();
d4fdac ¤   void¤   ¤   ¤   ¤   ¤   CheckWindowsVersion();
8caf5a
358ed5 #if PGPDISK_BETAVERSION
d59d44 ¤   void¤   ¤   ¤   ¤   ¤   CheckBetaTimeout();
ec5766 #elif PGPDISK_DEMOVERSION
f65a9d ¤   void¤   ¤   ¤   ¤   ¤   CheckDemoTimeout();
a1e121 #endif // PGPDISK_BETAVERSION
b1af5a
fc169b ¤   void¤   ¤   ¤   ¤   ¤   BringThisPGPdiskAppToFront(HWND mainDialogHwnd);
9eaf5a
e2107f ¤   DualErr¤¤   ¤   ¤   ¤   InitRegistryKeys();
feaf5a
5146f4 ¤   DualErr¤¤   ¤   ¤   ¤   CreateMainDialog();
16ebe2 ¤   void¤   ¤   ¤   ¤   ¤   DeleteMainDialog();
38af5a
--90ea 001c74d14df401100ac Page 4 of CPGPdiskApp.h
ba6f2a ¤   DualErr¤¤   ¤   ¤   ¤   CreateAppInfoStruct();
29a8ca ¤   DualErr¤¤   ¤   ¤   ¤   DeleteAppInfoStruct();
3daf5a
f482e8 ¤   DualErr¤¤   ¤   ¤   ¤   ShowPGPdiskAboutBox();
9e0828 ¤   void¤   ¤   ¤   ¤   ¤   ShowPGPdiskHelp();
be95e6 ¤   DualErr¤¤   ¤   ¤   ¤   ShowPGPdiskPrefs();
d335af ¤   void¤   ¤   ¤   ¤   ¤   ShowSplashScreen();
cfaf5a
ec878b ¤   // From CPGPdiskAppACI.cpp
07af5a
c391f6 ¤   PGPBoolean¤ ¤   ¤   ¤   AreAppCommandsSimilar(PAppCommandInfo pACI1,·
de1a65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PAppCommandInfo pACI2);
02af5a
1c8ed5 #if PGPDISK_BETAVERSION
baff17 ¤   DualErr¤¤   ¤   ¤   ¤   CheckACIBetaWarnings(PAppCommandInfo pACI);
c05766 #elif PGPDISK_DEMOVERSION
156e75 ¤   DualErr¤¤   ¤   ¤   ¤   CheckACIDemoWarnings(PAppCommandInfo pACI);
95e121 #endif // PGPDISK_BETAVERSION
62af5a
5a5d8e ¤   DualErr¤¤   ¤   ¤   ¤   CanonicalizeAppCommandInfo(PAppCommandInfo pACI);¤
a3af5a
9264da ¤   DualErr¤¤   ¤   ¤   ¤   PerformPGPdiskConversionCheck(
669ea8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PAppCommandInfo pACI);
caaf5a
b2c934 ¤   // From CPGPdiskAppPassphrase.cpp
c7af5a
c50bfd ¤   DualErr¤¤   ¤   ¤   ¤   AddPGPdiskPassphrase(LPCSTR path);
8afe90 ¤   DualErr¤¤   ¤   ¤   ¤   ChangePGPdiskPassphrase(LPCSTR path);
24af5a
408f5d ¤   DualErr¤¤   ¤   ¤   ¤   RemovePGPdiskPassphrase(LPCSTR path,·
9cf89a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean removeAll = FALSE);
42af5a
a6ea4b #if PGPDISK_PUBLIC_KEY
4daf5a
86b957 ¤   DualErr¤¤   ¤   ¤   ¤   AddRemovePGPdiskPublicKeys(LPCSTR path);
72af5a
e979f2 #if PGPDISK_WIPE_FUNCS
5aaf5a
9352b6 ¤   DualErr¤¤   ¤   ¤   ¤   WipePassesOnAllPGPdisks(
d51648 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean doSilentWiping = FALSE);
283a10 ¤   DualErr¤¤   ¤   ¤   ¤   WipePassesOnThisPGPdisk(LPCSTR path,·
dc1648 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean doSilentWiping = FALSE);
a4af5a
d4eb5e #endif // PGPDISK_WIPE_FUNCS
0faf5a
1438e4 #endif¤ // PGPDISK_PUBLIC_KEY
39af5a
6f2d67 ¤   // From CPGPdiskAppVolumes.cpp
b9af5a
d8a394 ¤   DualErr¤¤   ¤   ¤   ¤   GlobalConvertPGPdisks();
6e67c4 ¤   DualErr¤¤   ¤   ¤   ¤   CreatePGPdisk(LPCSTR defaultPath = "");
cf8519 ¤   DualErr¤¤   ¤   ¤   ¤   MountPGPdisk(LPCSTR path,·
7eb08a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean forceReadOnly = FALSE,·
e65dd0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean useDialog = TRUE,·
17e453 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean needMaster = FALSE,·
14a755 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive,·
a61fe0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SecureString *passphrase = NULL);
2a36fa ¤   DualErr¤¤   ¤   ¤   ¤   UnmountPGPdisk(PGPUInt8 drive,·
a8cf24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean isThisEmergency = FALSE);
c4f69c ¤   DualErr¤¤   ¤   ¤   ¤   UnmountAllPGPdisks(
63cf24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean isThisEmergency = FALSE);
fdaf5a
9f6840 ¤   // From CPGPdiskAppWinutils.cpp
87af5a
5f4670 ¤   HPALETTE¤   ¤   ¤   ¤   CreateDIBPalette(LPBITMAPINFO lpbmi,·
fe6cf8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPINT lpiNumColors);
14af5a
af2409 ¤   DECLARE_MESSAGE_MAP()
0b82f7 };
0eaf5a
c768e9 #endif¤ // ] Included_CPGPdiskApp_h
--05c0 0007d982f84401100ad Page 1 of CPGPdiskAppACI.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
4a07d7 // CPGPdiskAppACI.cpp
64465d //
0ba21e // Functions for processing AppCommandInfo structures.
c51bc3 //////////////////////////////////////////////////////////////////////////////
10af5a
09a974 // $Id: CPGPdiskAppACI.cpp,v 1.1.2.18.2.6 1998/10/28 00:13:28 nryan Exp $
f9af5a
1fcbce // Copyright (C) 1998 by Network Associates, Inc.
1671ae // All rights reserved.
38af5a
0f9e12 #include "StdAfx.h"
6faf5a
6f9bcf #include "Required.h"
3e7414 #include "PGPdiskHighLevelUtils.h"
0abfe9 #include "UtilityFunctions.h"
40af5a
2b3646 #include "CMainDialog.h"
af89af #include "CNagBuyDialog.h"
325e8f #include "CPGPdiskApp.h"
267d4e #include "CPGPdiskAppACI.h"
0268c6 #include "PGPdisk.h"
f2af5a
78af5a
a05270 ////////////////////////////
02bd35 // AppCommandInfo Processing
205270 ////////////////////////////
32af5a
2d1a6e // AreAppCommandsSimilar returns TRUE if the two specified ACI's are similar.
47af5a
7677be PGPBoolean·
5283e2 CPGPdiskApp::AreAppCommandsSimilar(
296867 ¤   PAppCommandInfo¤pACI1,·
70c663 ¤   PAppCommandInfo¤pACI2)
e4bb36 {
dfbe41 ¤   DualErr¤¤   derr;
5ad781 ¤   PGPBoolean¤ areCommandsSimilar¤ = FALSE;
bdaf5a
ec78f1 ¤   try
6fc7a1 ¤   {
603767 ¤   ¤   AppOp¤  ¤   op1, op2;
5e3181 ¤   ¤   CString¤¤   path1, path2;
111b8b ¤   ¤   PGPUInt8¤   drive1, drive2;
2faf5a
eeb84c ¤   ¤   pgpAssertAddrValid(pACI1, AppCommandInfo);
59d1a7 ¤   ¤   pgpAssertAddrValid(pACI2, AppCommandInfo);
f3af5a
96df19 ¤   ¤   // Canonicalize the commands.
cddfda ¤   ¤   derr = CanonicalizeAppCommandInfo(pACI1);
6eaf5a
45aa35 ¤   ¤   if (derr.IsntError())
ab5b34 ¤   ¤   {
f45416 ¤   ¤   ¤   derr = CanonicalizeAppCommandInfo(pACI2);
fd0fe4 ¤   ¤   }
daaf5a
7299ae ¤   ¤   // Extract the parameters.
00aa35 ¤   ¤   if (derr.IsntError())
145b34 ¤   ¤   {
ada7b0 ¤   ¤   ¤   path1¤  = pACI1->path;
a1d6ac ¤   ¤   ¤   drive1¤ = pACI1->drive;
eea595 ¤   ¤   ¤   op1¤¤   = pACI1->op;
49af5a
01cc7d ¤   ¤   ¤   path2¤  = pACI2->path;
301f0f ¤   ¤   ¤   drive2¤ = pACI2->drive;
dab031 ¤   ¤   ¤   op2¤¤   = pACI2->op;
95af5a
26d643 ¤   ¤   ¤   // Compare the commands.
989d6b ¤   ¤   ¤   switch (op1)
e7f776 ¤   ¤   ¤   {
b18594 ¤   ¤   ¤   case kAppOp_Mount:
ac0915 ¤   ¤   ¤   case kAppOp_AddPassphrase:
7dbf70 ¤   ¤   ¤   case kAppOp_ChangePassphrase:
--dee9 00050989b46401100ad Page 2 of CPGPdiskAppACI.cpp
14f9e2 ¤   ¤   ¤   case kAppOp_RemovePassphrase:
751573 ¤   ¤   ¤   case kAppOp_RemoveAlternates:
0f8321 ¤   ¤   ¤   case kAppOp_AddRemovePublicKeys:
2ee7f8 ¤   ¤   ¤   case kAppOp_WipePassesThisDisk:
61af5a
956434 ¤   ¤   ¤   ¤   // 'op2' must be one of the above as well.
504652 ¤   ¤   ¤   ¤   switch (op2)
fe72c3 ¤   ¤   ¤   ¤   {
cd09eb ¤   ¤   ¤   ¤   case kAppOp_Mount:
a80759 ¤   ¤   ¤   ¤   case kAppOp_AddPassphrase:
0486b5 ¤   ¤   ¤   ¤   case kAppOp_ChangePassphrase:
bec027 ¤   ¤   ¤   ¤   case kAppOp_RemovePassphrase:
882cb6 ¤   ¤   ¤   ¤   case kAppOp_RemoveAlternates:
3cd1bc ¤   ¤   ¤   ¤   case kAppOp_AddRemovePublicKeys:
c8ffa8 ¤   ¤   ¤   ¤   case kAppOp_WipePassesThisDisk:
75af5a
818cdd ¤   ¤   ¤   ¤   ¤   // Also the paths must match.
8b2d82 ¤   ¤   ¤   ¤   ¤   if (path1 == path2)
52cba6 ¤   ¤   ¤   ¤   ¤   ¤   areCommandsSimilar = TRUE;
6f14c3 ¤   ¤   ¤   ¤   ¤   break;
d42613 ¤   ¤   ¤   ¤   }
88f622 ¤   ¤   ¤   ¤   break;
a4af5a
ca1b82 ¤   ¤   ¤   case kAppOp_Unmount:
520565 ¤   ¤   ¤   ¤   // For 'unmount' the drive letters must be equal.
c37597 ¤   ¤   ¤   ¤   if (drive1 == drive2)
ae1314 ¤   ¤   ¤   ¤   ¤   areCommandsSimilar = TRUE;
bcf622 ¤   ¤   ¤   ¤   break;
dbaf5a
cbdb68 ¤   ¤   ¤   default:
a2a722 ¤   ¤   ¤   ¤   // All others match by default.
133a50 ¤   ¤   ¤   ¤   if (op1 == op2)
e81314 ¤   ¤   ¤   ¤   ¤   areCommandsSimilar = TRUE;
77f622 ¤   ¤   ¤   ¤   break;
11a3a6 ¤   ¤   ¤   }
570fe4 ¤   ¤   }
b39371 ¤   }
5f3c88 ¤   catch (CMemoryException *ex)
65c7a1 ¤   {
76ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
a26adc ¤   ¤   ex->Delete();
e59371 ¤   }
48af5a
514bb3 ¤   if (derr.IsError())
7998aa ¤   ¤   return FALSE;
410e24 ¤   else
409b34 ¤   ¤   return areCommandsSimilar;
63efe6 }
3faf5a
618ed5 #if PGPDISK_BETAVERSION
6faf5a
ff37db // CheckACIBetaWarnings checks if the beta has timed out and if so performs
0f373c // command filtering.
42af5a
4a2292 DualErr·
6a0fba CPGPdiskApp::CheckACIBetaWarnings(PAppCommandInfo pACI)
25bb36 {
187d36 ¤   DualErr derr;
acaf5a
059e46 ¤   pgpAssertAddrValid(pACI, AppCommandInfo);
66af5a
3a9c7c ¤   if (HasBetaTimedOut())
81c7a1 ¤   {
a3cb6a ¤   ¤   switch (pACI->op)
a65b34 ¤   ¤   {
932c6d ¤   ¤   case kAppOp_Create:
6348e6 ¤   ¤   case kAppOp_AddPassphrase:
ab839e ¤   ¤   case kAppOp_ChangePassphrase:
f1c50c ¤   ¤   case kAppOp_RemovePassphrase:
f2299d ¤   ¤   case kAppOp_RemoveAlternates:
9d8599 ¤   ¤   case kAppOp_AddRemovePublicKeys:
50af5a
--d267 000ca765cf5401100ad Page 3 of CPGPdiskAppACI.cpp
df27b7 ¤   ¤   ¤   // We can't run these commands after beta timeout.
54bd88 ¤   ¤   ¤   ReportError(kPGDMajorError_BadCommandAfterBetaTimeout);
290710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
05cdcb ¤   ¤   ¤   break;
dfaf5a
8c9ae3 ¤   ¤   default:
a1af5a
d6f7c2 ¤   ¤   ¤   // Otherwise just warn.
12ba5b ¤   ¤   ¤   if (mCommandLineMode)
d1734f ¤   ¤   ¤   ¤   ReportError(kPGPdiskBetaTimeoutWarning);
1acdcb ¤   ¤   ¤   break;
650fe4 ¤   ¤   }
179371 ¤   }
b8af5a
2733e3 ¤   return derr;
85efe6 }
79af5a
fb5766 #elif PGPDISK_DEMOVERSION
b0af5a
76101b // CheckACIDemoWarnings checks if the demo has timed out and if so performs
73373c // command filtering.
cbaf5a
2e2292 DualErr·
bacc7f CPGPdiskApp::CheckACIDemoWarnings(PAppCommandInfo pACI)
eebb36 {
567d36 ¤   DualErr derr;
70af5a
ed9e46 ¤   pgpAssertAddrValid(pACI, AppCommandInfo);
b7af5a
2ad7f7 ¤   if (HasDemoTimedOut())
dac7a1 ¤   {
7bfd98 ¤   ¤   CNagBuyDialog nagBuyDialog;
b2af5a
b0cb6a ¤   ¤   switch (pACI->op)
855b34 ¤   ¤   {
822c6d ¤   ¤   case kAppOp_Create:
7848e6 ¤   ¤   case kAppOp_AddPassphrase:
0f839e ¤   ¤   case kAppOp_ChangePassphrase:
e6c50c ¤   ¤   case kAppOp_RemovePassphrase:
36299d ¤   ¤   case kAppOp_RemoveAlternates:
a68599 ¤   ¤   case kAppOp_AddRemovePublicKeys:
1baf5a
bafa66 ¤   ¤   ¤   // We can't run these commands after demo timeout.
259d6c ¤   ¤   ¤   nagBuyDialog.DisplayDialog(kPGPdiskDemoBadCommandWarning);
220710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
01cdcb ¤   ¤   ¤   break;
4eaf5a
f19ae3 ¤   ¤   default:
3caf5a
18f7c2 ¤   ¤   ¤   // Otherwise just warn.
71ba5b ¤   ¤   ¤   if (mCommandLineMode)
18d554 ¤   ¤   ¤   ¤   nagBuyDialog.DisplayDialog(kPGPdiskDemoTimeoutWarning);
0ecdcb ¤   ¤   ¤   break;
7a0fe4 ¤   ¤   }
ad9371 ¤   }
48af5a
9b33e3 ¤   return derr;
2defe6 }
daaf5a
7de121 #endif // PGPDISK_BETAVERSION
b9af5a
b06786 // CanonicalizeAppCommandInfo takes an ACI structure and makes it acceptable
baca8c // for processing by lower-level functions.
b3af5a
ee2292 DualErr·
0ca281 CPGPdiskApp::CanonicalizeAppCommandInfo(PAppCommandInfo pACI)
2abb36 {
f77d36 ¤   DualErr derr;
06af5a
2e78f1 ¤   try
57c7a1 ¤   {
ca400c ¤   ¤   AppOp¤  ¤   op;
--1f5c 0007af56f31401100ad Page 4 of CPGPdiskAppACI.cpp
6931e9 ¤   ¤   CString¤¤   path;
4f9214 ¤   ¤   PGPdisk¤¤   *pPGD;
8b11a0 ¤   ¤   PGPUInt8¤   drive;
54af5a
cfd178 ¤   ¤   pgpAssertAddrValid(pACI, AppCommandInfo);
04af5a
4312fb ¤   ¤   op¤ ¤   = pACI->op;
5e4ee3 ¤   ¤   path¤   = pACI->path;
5ffd70 ¤   ¤   drive¤  = pACI->drive;
7aaf5a
c76740 ¤   ¤   // Only some commands need pre-processing.
9f983f ¤   ¤   switch (op)
c95b34 ¤   ¤   {
b691bc ¤   ¤   case kAppOp_Mount:
5daf5a
68c014 ¤   ¤   ¤   // Resolve any shortcut.
c83e28 ¤   ¤   ¤   if (IsShortCut(path))
e8ccde ¤   ¤   ¤   ¤   derr = ResolveShortcut(path, &path);
c1af5a
959d3d ¤   ¤   ¤   if (derr.IsntError())
1df776 ¤   ¤   ¤   {
7b8dd2 ¤   ¤   ¤   ¤   // Resolve 'root' forms to the corresponding PGPdisk.
83f1ff ¤   ¤   ¤   ¤   if (IsPlainLocalRoot(path))
f372c3 ¤   ¤   ¤   ¤   {
2e29c2 ¤   ¤   ¤   ¤   ¤   pPGD = mPGPdisks.FindPGPdisk(DriveFromPath(path));
2eaf5a
d5b0f1 ¤   ¤   ¤   ¤   ¤   if (IsntNull(pPGD))
588c91 ¤   ¤   ¤   ¤   ¤   ¤   path = pPGD->GetPath();
802613 ¤   ¤   ¤   ¤   }
0daf5a
78f43e ¤   ¤   ¤   ¤   // Pretty the path.
bbd190 ¤   ¤   ¤   ¤   derr = VerifyAndCanonicalizePath(path, &path);
5da3a6 ¤   ¤   ¤   }
0fcdcb ¤   ¤   ¤   break;
77af5a
7748e6 ¤   ¤   case kAppOp_AddPassphrase:
23839e ¤   ¤   case kAppOp_ChangePassphrase:
c0c50c ¤   ¤   case kAppOp_RemovePassphrase:
dd299d ¤   ¤   case kAppOp_RemoveAlternates:
5b8599 ¤   ¤   case kAppOp_AddRemovePublicKeys:
8b6f9e ¤   ¤   case kAppOp_WipePassesThisDisk:
2aaf5a
2cc014 ¤   ¤   ¤   // Resolve any shortcut.
083e28 ¤   ¤   ¤   if (IsShortCut(path))
3cccde ¤   ¤   ¤   ¤   derr = ResolveShortcut(path, &path);
aaaf5a
949d3d ¤   ¤   ¤   if (derr.IsntError())
9ff776 ¤   ¤   ¤   {
9bf43e ¤   ¤   ¤   ¤   // Pretty the path.
afd190 ¤   ¤   ¤   ¤   derr = VerifyAndCanonicalizePath(path, &path);
dea3a6 ¤   ¤   ¤   }
eecdcb ¤   ¤   ¤   break;
43af5a
42a0d4 ¤   ¤   case kAppOp_Unmount:
78af5a
834504 ¤   ¤   ¤   // If we don't have a drive, check for path.
b77ecc ¤   ¤   ¤   if (!IsLegalDriveNumber(drive))
def776 ¤   ¤   ¤   {
e8faba ¤   ¤   ¤   ¤   pgpAssert(!path.IsEmpty());
36af5a
16c5f9 ¤   ¤   ¤   ¤   // Resolve any shortcut.
99d15b ¤   ¤   ¤   ¤   if (IsShortCut(path))
22a3ed ¤   ¤   ¤   ¤   ¤   derr = ResolveShortcut(path, &path);
e6af5a
2d22b3 ¤   ¤   ¤   ¤   // Extract the drive letter.
1d724e ¤   ¤   ¤   ¤   if (derr.IsntError())
2672c3 ¤   ¤   ¤   ¤   {
15e9af ¤   ¤   ¤   ¤   ¤   if (IsPlainLocalRoot(path))
1b4859 ¤   ¤   ¤   ¤   ¤   {
d134dc ¤   ¤   ¤   ¤   ¤   ¤   // We have a root to a PGPdisk volume.
34337c ¤   ¤   ¤   ¤   ¤   ¤   drive = DriveLetToNum(path[0]);
7a1c89 ¤   ¤   ¤   ¤   ¤   }
--7d3f 000387e1464401100ad Page 5 of CPGPdiskAppACI.cpp
f54bd6 ¤   ¤   ¤   ¤   ¤   else
744859 ¤   ¤   ¤   ¤   ¤   {
83635a ¤   ¤   ¤   ¤   ¤   ¤   // We have a path to a PGPdisk file.
b34fe0 ¤   ¤   ¤   ¤   ¤   ¤   derr = VerifyAndCanonicalizePath(path, &path);
efaf5a
fd7765 ¤   ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
818fec ¤   ¤   ¤   ¤   ¤   ¤   {
d3f16d ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPGD = mPGPdisks.FindPGPdisk(path);
c0af5a
d120c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (IsntNull(pPGD))
689eef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   drive = pPGD->GetDrive();
c4db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e81c89 ¤   ¤   ¤   ¤   ¤   }
e62613 ¤   ¤   ¤   ¤   }
e5a3a6 ¤   ¤   ¤   }
bdcdcb ¤   ¤   ¤   break;
210fe4 ¤   ¤   }
aaaf5a
fdde7d ¤   ¤   // Update the ACI with the modified values.
a6aa35 ¤   ¤   if (derr.IsntError())
065b34 ¤   ¤   {
d0702d ¤   ¤   ¤   strcpy(pACI->path, path);
e0fed0 ¤   ¤   ¤   pACI->drive = drive;
880fe4 ¤   ¤   }
1a9371 ¤   }
6d3c88 ¤   catch (CMemoryException *ex)
59c7a1 ¤   {
43ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
a76adc ¤   ¤   ex->Delete();
4d9371 ¤   }
95af5a
3d33e3 ¤   return derr;
68efe6 }
92af5a
6f789a // PerformPGPdiskConversionCheck checks if the current PGPdisk needs a CAST
9f3003 // conversion, and if so, asks the user.
16af5a
b92292 DualErr·
352283 CPGPdiskApp::PerformPGPdiskConversionCheck(PAppCommandInfo pACI)
5bbb36 {
31be41 ¤   DualErr¤¤   derr;
20a5ef ¤   PGPBoolean¤ userSaidNo;
eeaf5a
c30cdf ¤   switch (pACI->op)
73c7a1 ¤   {
1e735d ¤   case kAppOp_Mount:
2daf5a
3f8741 ¤   ¤   if (IsntNull(mPGPdisks.FindPGPdisk(pACI->path)))
4fcdcb ¤   ¤   ¤   break;
f7af5a
242d71 ¤   ¤   if (DoesPGPdiskHaveBadCAST(pACI->path))
6a5b34 ¤   ¤   {
f00730 ¤   ¤   ¤   derr = ConvertPGPdiskPriorToMount(pACI->path, &userSaidNo);
80af5a
5c9d3d ¤   ¤   ¤   if (derr.IsntError())
e8f776 ¤   ¤   ¤   {
0db6ef ¤   ¤   ¤   ¤   if (userSaidNo)
554351 ¤   ¤   ¤   ¤   ¤   pACI->flags |= kACF_ForceReadOnly;
06fa07 ¤   ¤   ¤   ¤   else
c087e8 ¤   ¤   ¤   ¤   ¤   pACI->flags |= kACF_NeedMaster;
aba3a6 ¤   ¤   ¤   }
c50fe4 ¤   ¤   }
93af5a
072f68 ¤   ¤   break;
dcaf5a
ffc499 ¤   case kAppOp_AddPassphrase:
6d6ced ¤   case kAppOp_ChangePassphrase:
262a7f ¤   case kAppOp_RemovePassphrase:
8ac6ee ¤   case kAppOp_RemoveAlternates:
2e8074 ¤   case kAppOp_AddRemovePublicKeys:
95af5a
382d71 ¤   ¤   if (DoesPGPdiskHaveBadCAST(pACI->path))
--791e 000aab5f8bd401100ad Page 6 of CPGPdiskAppACI.cpp
e35b34 ¤   ¤   {
8ef607 ¤   ¤   ¤   derr = ConvertPGPdisk(pACI->path);
750fe4 ¤   ¤   }
0caf5a
112f68 ¤   ¤   break;
f3af5a
562f72 ¤   default:
5e2f68 ¤   ¤   break;
009371 ¤   }
0eaf5a
2b33e3 ¤   return derr;
73efe6 }
f1af5a
e76303 // DispatchAppCommandInfo takes the address of an AppCommandInfo structure
203d59 // and executes the command contained within.
78af5a
e8c823 void·
3c4d6d CPGPdiskApp::DispatchAppCommandInfo(PAppCommandInfo pACI)
edbb36 {
41be41 ¤   DualErr¤¤   derr;
3dc4d0 ¤   PGPBoolean¤ doSilentWiping, forceReadOnly, isThisEmergency, needMaster;
dbd1a0 ¤   PGPBoolean¤ noMountDialog;
b0af5a
799e46 ¤   pgpAssertAddrValid(pACI, AppCommandInfo);
95af5a
41b6db ¤   // Get PGPdisk info.
5a22fc ¤   derr = UpdateAppPGPdiskInfo();
76af5a
f4b6f8 ¤   // Prepare the ACI.
622361 ¤   if (derr.IsntError())
2ac7a1 ¤   {
c1da3f ¤   ¤   derr = CanonicalizeAppCommandInfo(pACI);
bb9371 ¤   }
e0af5a
8b400c ¤   // Display timeout warnings as necessary.
2c2361 ¤   if (derr.IsntError())
a7c7a1 ¤   {
f678b0 ¤   #if PGPDISK_BETAVERSION
a16d65 ¤   ¤   derr = CheckACIBetaWarnings(pACI);
9ede32 ¤   #elif PGPDISK_DEMOVERSION
20afce ¤   ¤   derr = CheckACIDemoWarnings(pACI);
8ed629 ¤   #endif // PGPDISK_BETAVERSION
b09371 ¤   }
ce67c5 ¤
f8bd1f ¤   // If any other apps are doing the same thing, switch to them.
212361 ¤   if (derr.IsntError())
e9c7a1 ¤   {
cdbd67 ¤   ¤   if (FindAndShowSimilarPGPdiskApp(pACI))
030710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
d29371 ¤   }
3c67c5 ¤
1d2361 ¤   if (derr.IsntError())
9bc7a1 ¤   {
6ac737 ¤   ¤   // Update shared memory with current command info.
ffedd1 ¤   ¤   SetSharedMemoryCommandInfo(pACI);
29af5a
bacf4e ¤   ¤   // Check if PGPdisk needs conversion.
1fdcb4 ¤   ¤   derr = PerformPGPdiskConversionCheck(pACI);
389371 ¤   }
05af5a
6d4c5e ¤   // Resolve flags.
7f2361 ¤   if (derr.IsntError())
cbc7a1 ¤   {
4274ac ¤   ¤   isThisEmergency¤= (pACI->flags & kACF_EmergencyUnmount ? TRUE :·
add54e ¤   ¤   ¤   FALSE);
eaaf5a
83f962 ¤   ¤   noMountDialog¤  = (pACI->flags & kACF_MountWithNoDialog ? TRUE :·
4dd54e ¤   ¤   ¤   FALSE);
31af5a
5478a8 ¤   ¤   forceReadOnly¤  = (pACI->flags & kACF_ForceReadOnly ? TRUE : FALSE);
f70d5e ¤   ¤   doSilentWiping¤ = (pACI->flags & kACF_SilentWiping ? TRUE : FALSE);
aa5426 ¤   ¤   needMaster¤ ¤   = (pACI->flags & kACF_NeedMaster ? TRUE : FALSE);
--ec5c 0002e645cf8401100ad Page 7 of CPGPdiskAppACI.cpp
a19371 ¤   }
93af5a
6e0cdf ¤   switch (pACI->op)
e5c7a1 ¤   {
4bd577 ¤   case kAppOp_GlobalConvert:¤ ¤   ¤   // Invoke global conversion wizard.
e0af5a
f0aa35 ¤   ¤   if (derr.IsntError())
915b34 ¤   ¤   {
d03d41 ¤   ¤   ¤   derr = GlobalConvertPGPdisks();
3b0fe4 ¤   ¤   }
62af5a
9cbdd6 ¤   ¤   if (derr.IsError())
405b34 ¤   ¤   {
853f27 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskGlobalConversionFailed, derr);
2a0fe4 ¤   ¤   }
002f68 ¤   ¤   break;
a067c5 ¤
126a00 ¤   case kAppOp_Create:¤¤   ¤   ¤   // Create a new PGPdisk
46af5a
0549c7 ¤   ¤   // Show splash screen if command-line mode and create.
2daa35 ¤   ¤   if (derr.IsntError())
005b34 ¤   ¤   {
1fba5b ¤   ¤   ¤   if (mCommandLineMode)
07db95 ¤   ¤   ¤   ¤   ShowSplashScreen();
0f0fe4 ¤   ¤   }
1eaf5a
1faa35 ¤   ¤   if (derr.IsntError())
e35b34 ¤   ¤   {
a2502e ¤   ¤   ¤   derr = CreatePGPdisk(pACI->path);
e20fe4 ¤   ¤   }
bfaf5a
70bdd6 ¤   ¤   if (derr.IsError())
865b34 ¤   ¤   {
8f7260 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskCreationFailed, derr);
200fe4 ¤   ¤   }
502f68 ¤   ¤   break;
9eaf5a
9ff598 ¤   case kAppOp_Mount:¤ ¤   ¤   ¤   ¤   // Mount a PGPdisk
6eaf5a
70aa35 ¤   ¤   if (derr.IsntError())
ae5b34 ¤   ¤   {
c8a6e7 ¤   ¤   ¤   derr = MountPGPdisk(pACI->path, forceReadOnly, !noMountDialog,·
6ba86e ¤   ¤   ¤   ¤   needMaster, pACI->drive, (SecureString *) pACI->data[0]);
bf0fe4 ¤   ¤   }
55af5a
21bdd6 ¤   ¤   if (derr.IsError())
ac5b34 ¤   ¤   {
74ee38 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskMountFailed, derr);
950fe4 ¤   ¤   }
ef2f68 ¤   ¤   break;
d5af5a
f5d419 ¤   case kAppOp_Unmount:¤   ¤   ¤   ¤   // Unmount a PGPdisk
3eaf5a
a5aa35 ¤   ¤   if (derr.IsntError())
1d5b34 ¤   ¤   {
14f4cb ¤   ¤   ¤   derr = UnmountPGPdisk(pACI->drive, isThisEmergency);
cf0fe4 ¤   ¤   }
45af5a
663950 ¤   ¤   if (derr.IsError() && !isThisEmergency)
a85b34 ¤   ¤   {
933e51 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskUnmountFailed, derr,·
59239d ¤   ¤   ¤   ¤   pACI->drive);
730fe4 ¤   ¤   }
b52f68 ¤   ¤   break;
97af5a
d54c0a ¤   case kAppOp_UnmountAll:¤¤   ¤   ¤   // Unmount all PGPdisks
34af5a
17aa35 ¤   ¤   if (derr.IsntError())
6a5b34 ¤   ¤   {
8aefbd ¤   ¤   ¤   derr = UnmountAllPGPdisks(isThisEmergency);
d00fe4 ¤   ¤   }
2eaf5a
--6e72 0002f31cf89401100ad Page 8 of CPGPdiskAppACI.cpp
923950 ¤   ¤   if (derr.IsError() && !isThisEmergency)
7c5b34 ¤   ¤   {
34326a ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskUnmountAllFailed, derr);
9b0fe4 ¤   ¤   }
032f68 ¤   ¤   break;
fcaf5a
a2c438 ¤   case kAppOp_AddPassphrase:¤ ¤   ¤   // Add a passphrase to a PGPdisk
6daf5a
16aa35 ¤   ¤   if (derr.IsntError())
9e5b34 ¤   ¤   {
5e11c4 ¤   ¤   ¤   derr = AddPGPdiskPassphrase(pACI->path);
f40fe4 ¤   ¤   }
e1af5a
fbbdd6 ¤   ¤   if (derr.IsError())
565b34 ¤   ¤   {
552397 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskAddPassFailed, derr);
1a0fe4 ¤   ¤   }
022f68 ¤   ¤   break;
0daf5a
08ff4d ¤   case kAppOp_ChangePassphrase:¤  ¤   // Change a passphrase on a PGPdisk
15af5a
cdaa35 ¤   ¤   if (derr.IsntError())
285b34 ¤   ¤   {
db2a61 ¤   ¤   ¤   derr = ChangePGPdiskPassphrase(pACI->path);
ae0fe4 ¤   ¤   }
9baf5a
fcbdd6 ¤   ¤   if (derr.IsError())
5b5b34 ¤   ¤   {
c017a8 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskChangePassFailed, derr);
0b0fe4 ¤   ¤   }
332f68 ¤   ¤   break;
74af5a
12816f ¤   case kAppOp_RemovePassphrase:¤  ¤   // Remove a passphrase from a PGPdisk
fdaf5a
77aa35 ¤   ¤   if (derr.IsntError())
895b34 ¤   ¤   {
17b401 ¤   ¤   ¤   derr = RemovePGPdiskPassphrase(pACI->path, FALSE);
180fe4 ¤   ¤   }
5daf5a
51bdd6 ¤   ¤   if (derr.IsError())
785b34 ¤   ¤   {
52d60a ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskRemoveOnePassFailed, derr);
880fe4 ¤   ¤   }
742f68 ¤   ¤   break;
a3af5a
1354f6 ¤   case kAppOp_RemoveAlternates:¤  ¤   // Remove all alternate passphrases
56af5a
a9aa35 ¤   ¤   if (derr.IsntError())
b75b34 ¤   ¤   {
3d05ce ¤   ¤   ¤   derr = RemovePGPdiskPassphrase(pACI->path, TRUE);
e20fe4 ¤   ¤   }
52af5a
99bdd6 ¤   ¤   if (derr.IsError())
db5b34 ¤   ¤   {
d87df5 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskRemoveAllPassesFailed, derr);
0e0fe4 ¤   ¤   }
8b2f68 ¤   ¤   break;
17af5a
69ea4b #if PGPDISK_PUBLIC_KEY
74af5a
cab95d ¤   case kAppOp_AddRemovePublicKeys:¤   // Manage PGPdisk public keys
f6af5a
06aa35 ¤   ¤   if (derr.IsntError())
e95b34 ¤   ¤   {
c1d01b ¤   ¤   ¤   derr = AddRemovePGPdiskPublicKeys(pACI->path);
bc0fe4 ¤   ¤   }
55af5a
78bdd6 ¤   ¤   if (derr.IsError())
c35b34 ¤   ¤   {
aa4752 ¤   ¤   ¤   ReportError(kPGDMajorError_AddRemovePublicKeysFailed, derr);
e60fe4 ¤   ¤   }
2f2f68 ¤   ¤   break;
--1a3c 00082363a64401100ad Page 9 of CPGPdiskAppACI.cpp
e0af5a
fe79f2 #if PGPDISK_WIPE_FUNCS
20af5a
498e9e ¤   case kAppOp_WipePassesAllMounted:¤  // Wipe passes on all mounted disks
3daf5a
12aa35 ¤   ¤   if (derr.IsntError())
595b34 ¤   ¤   {
855969 ¤   ¤   ¤   derr = WipePassesOnAllPGPdisks(doSilentWiping);
ce0fe4 ¤   ¤   }
48af5a
a1bdd6 ¤   ¤   if (derr.IsError())
4f5b34 ¤   ¤   {
f1443c ¤   ¤   ¤   ReportError(kPGDMajorError_WipePassesFailed, derr);
6f0fe4 ¤   ¤   }
0e2f68 ¤   ¤   break;
ceaf5a
9b79ee ¤   case kAppOp_WipePassesThisDisk:¤¤   // Wipe passes on one disk
96af5a
ccaa35 ¤   ¤   if (derr.IsntError())
285b34 ¤   ¤   {
2d5765 ¤   ¤   ¤   derr = WipePassesOnThisPGPdisk(pACI->path, doSilentWiping);
4c0fe4 ¤   ¤   }
85af5a
99bdd6 ¤   ¤   if (derr.IsError())
fe5b34 ¤   ¤   {
a8443c ¤   ¤   ¤   ReportError(kPGDMajorError_WipePassesFailed, derr);
3d0fe4 ¤   ¤   }
382f68 ¤   ¤   break;
65af5a
80eb5e #endif // PGPDISK_WIPE_FUNCS
7faf5a
0338e4 #endif¤ // PGPDISK_PUBLIC_KEY
cb67c5 ¤
542a83 ¤   case kAppOp_ShowAboutBox:¤  ¤   ¤   // Show the about box
7aaf5a
aeaa35 ¤   ¤   if (derr.IsntError())
dc5b34 ¤   ¤   {
44d824 ¤   ¤   ¤   derr = ShowPGPdiskAboutBox();
680fe4 ¤   ¤   }
06af5a
e1bdd6 ¤   ¤   if (derr.IsError())
265b34 ¤   ¤   {
2b0e3e ¤   ¤   ¤   ReportError(kPGDMajorError_AboutBoxDisplayFailed, derr);
800fe4 ¤   ¤   }
b42f68 ¤   ¤   break;
86af5a
bbae43 ¤   case kAppOp_ShowHelp:¤  ¤   ¤   ¤   // Show PGPdisk help
24af5a
e6aa35 ¤   ¤   if (derr.IsntError())
845b34 ¤   ¤   {
08f82e ¤   ¤   ¤   ShowPGPdiskHelp();
a80fe4 ¤   ¤   }
332f68 ¤   ¤   break;
b6af5a
e551ae ¤   case kAppOp_ShowPrefs:¤ ¤   ¤   ¤   // Show the PGPdisk preferences
4aaf5a
b1aa35 ¤   ¤   if (derr.IsntError())
755b34 ¤   ¤   {
71a532 ¤   ¤   ¤   derr = ShowPGPdiskPrefs();
1a0fe4 ¤   ¤   }
b9af5a
fabdd6 ¤   ¤   if (derr.IsError())
f25b34 ¤   ¤   {
d8482d ¤   ¤   ¤   ReportError(kPGDMajorError_PreferencesAccessFailed, derr);
0a0fe4 ¤   ¤   }
ca2f68 ¤   ¤   break;
4faf5a
b82f72 ¤   default:
e58f52 ¤   ¤   pgpAssert(FALSE);
7e2f68 ¤   ¤   break;
3e9371 ¤   }
82af5a
--7ae7 001991c5667401100ad Page 10 of CPGPdiskAppACI.cpp
edf76d ¤   // Clear shared memory command info.
dd38fc ¤   ClearSharedMemoryCommandInfo();
99efe6 }
--185c 001cf08203a401100ae Page 1 of CPGPdiskAppACI.h
541bc3 //////////////////////////////////////////////////////////////////////////////
570b6d // CPGPdiskAppACI.h
68465d //
6cc6dc // Declarations for CPGPdiskAppACI.cpp.
081bc3 //////////////////////////////////////////////////////////////////////////////
0faf5a
2a2973 // $Id: CPGPdiskAppACI.h,v 1.1.2.9.2.3 1998/10/28 00:13:29 nryan Exp $
2baf5a
d1cbce // Copyright (C) 1998 by Network Associates, Inc.
a571ae // All rights reserved.
c1af5a
9b0228 #ifndef Included_CPGPdiskAppACI_h¤  // [
9fbcf1 #define Included_CPGPdiskAppACI_h
88af5a
54af5a
f2af5a
c009b7 ////////////
cee738 // Constants
b009b7 ////////////
acaf5a
8191f9 // Flags for AppCommandInfo.
fdaf5a
368358 const PGPUInt32¤kACF_EmergencyUnmount¤  = 0x0001;¤  // emergency unmount
f567f5 const PGPUInt32¤kACF_MountWithNoDialog¤ = 0x0002;¤  // use given pass info
b61c12 const PGPUInt32¤kACF_ForceReadOnly¤ ¤   = 0x0004;¤  // force read only mount
956cd4 const PGPUInt32¤kACF_SilentWiping¤  ¤   = 0x0008;¤  // silent wiping
ce96e5 const PGPUInt32¤kACF_NeedMaster¤¤   ¤   = 0x0010;¤  // mount with master
ffaf5a
dcaf5a
05d557 ////////
6c02c9 // Types
3ad557 ////////
0daf5a
2c1c21 // Application operation identifiers.
40af5a
40f1af enum AppOp¤ {kAppOp_GlobalConvert, kAppOp_Create, kAppOp_Mount,·
151ad4 ¤   ¤   ¤   ·kAppOp_Unmount, kAppOp_UnmountAll, kAppOp_AddPassphrase,·
72616a ¤   ¤   ¤   ·kAppOp_ChangePassphrase, kAppOp_RemovePassphrase,·
7681e4 ¤   ¤   ¤   ·kAppOp_RemoveAlternates, kAppOp_AddRemovePublicKeys,·
b6f64f ¤   ¤   ¤   ·kAppOp_ShowAboutBox, kAppOp_ShowHelp, kAppOp_ShowPrefs,·
7d7ab1 ¤   ¤   ¤   ·kAppOp_WipePassesAllMounted, kAppOp_WipePassesThisDisk,·
e823e9 ¤   ¤   ¤   ·kAppOp_InvalidRequest};
e0af5a
368746 // An AppCommandInfo structure is used to encapsulate volume operation
f43067 // requests within the PGPdisk application.
7eaf5a
ee38af typedef struct AppCommandInfo
9cbb36 {
e4f140 ¤   AppOp¤  ¤   op;¤¤   ¤   ¤   ¤   ¤   ¤   // operation to perform
a26792 ¤   PGPUInt32¤  flags;¤ ¤   ¤   ¤   ¤   ¤   // flags
09e3d0 ¤   PGPUInt8¤   drive;¤ ¤   ¤   ¤   ¤   ¤   // drive number
a7a952 ¤   char¤   ¤   path[kMaxStringSize];¤  ¤   // pathname of file/volume
0c6438 ¤   PGPUInt32¤  data[10];¤  ¤   ¤   ¤   ¤   // extra data
bbaf5a
fd69b5 } AppCommandInfo, *PAppCommandInfo;
e6af5a
cf9cd4 #endif¤ // ] Included_CPGPdiskAppACI_h
--7137 0005721d3be401100af Page 1 of CPGPdiskAppPassphrase.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
c50fc3 // CPGPdiskAppPassphrase.cpp
72465d //
f9e404 // Functions for adding, changing, and removing passphrases.
451bc3 //////////////////////////////////////////////////////////////////////////////
b5af5a
bba6d4 // $Id: CPGPdiskAppPassphrase.cpp,v 1.1.2.21.2.3 1998/10/22 22:27:47 nryan Exp $
12af5a
11cbce // Copyright (C) 1998 by Network Associates, Inc.
c971ae // All rights reserved.
c8af5a
ff9e12 #include "StdAfx.h"
2438ab #include <math.h>
d3af5a
a49bcf #include "Required.h"
b07414 #include "PGPdiskHighLevelUtils.h"
78993c #include "StringAssociation.h"
3baf5a
0ae816 #include "CConfirmPassphraseDialog.h"
433646 #include "CMainDialog.h"
5d4aaa #include "COpenPGPdiskDialog.h"
b25e8f #include "CPGPdiskApp.h"
60ae4e #include "CPGPdiskAppPassphrase.h"
c4af5a
3eea4b #if PGPDISK_PUBLIC_KEY
69af5a
9191b9 #include "pgpSDKPrefs.h"
704919 #include "pgpUtilities.h"
43af5a
f2cf11 #include "CPublicKeyDialog.h"
b7f4f6 #include "PGPdiskPublicKeyUtils.h"
95af5a
7838e4 #endif¤ // PGPDISK_PUBLIC_KEY
5faf5a
a91998 #include "CSinglePassphraseDialog.h"
e2c411 #include "Globals.h"
ef68c6 #include "PGPdisk.h"
22af5a
a1af5a
60d557 ////////
9002c9 // Types
34d557 ////////
5baf5a
d40dde // ScoreStruct/Range is used by the CalcPassphraseQuality routine.
d4af5a
cb0f9a typedef struct ScoreStruct
96bb36 {
f3f845 ¤   PGPUInt8¤   firstChar;
b06495 ¤   PGPUInt8¤   lastChar;
75af5a
e35c6c } Range;
19af5a
c9af5a
0cbbb5 ///////////////////////////////////////////////////////////////
795b53 // High-Level Passphrase Addition, Change, and Removal Routines
99bbb5 ///////////////////////////////////////////////////////////////
18af5a
43cb75 // AskUserAddPassphrase asks to user to pick the PGPdisk for which he wants
27b5d5 // to add a passphrase.
50af5a
92c823 void·
7fe7e9 CPGPdiskApp::AskUserAddPassphrase()
f4bb36 {
bc1acc ¤   AppCommandInfo¤ ¤   ACI;
53fcfd ¤   COpenPGPdiskDialog¤ selectPGPdiskDlg(kODT_Select);
5418b7 ¤   CString¤¤   ¤   ¤   path;
29705b ¤   DualErr¤¤   ¤   ¤   derr;
f636c6 ¤   PGPBoolean¤ ¤   ¤   wasMainEnabled;
4eaf5a
277bba ¤   // Forcibly disable main window so it doesn't flicker between dialogs.
73023f ¤   if (mMainDialog)
57e14e ¤   ¤   wasMainEnabled = !mMainDialog->EnableWindow(FALSE);
--94fb 00063ccbe3b401100af Page 2 of CPGPdiskAppPassphrase.cpp
2a67c5 ¤
c37418 ¤   // Show the dialog.
fd3005 ¤   derr = selectPGPdiskDlg.AskForPath(&path);
25af5a
812361 ¤   if (derr.IsntError())
c5c7a1 ¤   {
03d656 ¤   ¤   // Now dispatch the command.
610264 ¤   ¤   ACI.op¤ ¤   = kAppOp_AddPassphrase;
bf4492 ¤   ¤   ACI.flags¤  = NULL;
6df325 ¤   ¤   ACI.drive¤  = kInvalidDrive;
f3443d ¤   ¤   strcpy(ACI.path, path);
45af5a
bf491e ¤   ¤   DispatchAppCommandInfo(&ACI);
ae9371 ¤   }
10af5a
fa4bb3 ¤   if (derr.IsError())
fec7a1 ¤   {
ce1ef9 ¤   ¤   ReportError(kPGDMajorError_PGPdiskAddPassFailed, derr);
cc9371 ¤   }
14af5a
842488 ¤   // Re-enable main dialog if it was disabled.
2b839a ¤   if (IsntNull(mMainDialog) && wasMainEnabled)
bc35a5 ¤   ¤   mMainDialog->EnableWindow(TRUE);
3befe6 }
c0af5a
b49cb6 // AskUserChangePassphrase asks to user to pick the PGPdisk for which he
fcd088 // wants to change a passphrase.
08af5a
cbc823 void·
f90ec7 CPGPdiskApp::AskUserChangePassphrase()
56bb36 {
5e1acc ¤   AppCommandInfo¤ ¤   ACI;
f5fcfd ¤   COpenPGPdiskDialog¤ selectPGPdiskDlg(kODT_Select);
2818b7 ¤   CString¤¤   ¤   ¤   path;
1a705b ¤   DualErr¤¤   ¤   ¤   derr;
4f36c6 ¤   PGPBoolean¤ ¤   ¤   wasMainEnabled;
ffaf5a
ff7bba ¤   // Forcibly disable main window so it doesn't flicker between dialogs.
07023f ¤   if (mMainDialog)
24e14e ¤   ¤   wasMainEnabled = !mMainDialog->EnableWindow(FALSE);
6aaf5a
667418 ¤   // Show the dialog.
ae3005 ¤   derr = selectPGPdiskDlg.AskForPath(&path);
74af5a
022361 ¤   if (derr.IsntError())
f9c7a1 ¤   {
dad656 ¤   ¤   // Now dispatch the command.
589340 ¤   ¤   ACI.op¤ ¤   = kAppOp_ChangePassphrase;
8d4492 ¤   ¤   ACI.flags¤  = NULL;
13f325 ¤   ¤   ACI.drive¤  = kInvalidDrive;
d0443d ¤   ¤   strcpy(ACI.path, path);
74af5a
ef491e ¤   ¤   DispatchAppCommandInfo(&ACI);
c89371 ¤   }
34af5a
214bb3 ¤   if (derr.IsError())
a2c7a1 ¤   {
fe0424 ¤   ¤   ReportError(kPGDMajorError_PGPdiskChangePassFailed, derr);
a99371 ¤   }
e1af5a
292488 ¤   // Re-enable main dialog if it was disabled.
04839a ¤   if (IsntNull(mMainDialog) && wasMainEnabled)
9135a5 ¤   ¤   mMainDialog->EnableWindow(TRUE);
b3efe6 }
6eaf5a
1f03c4 // AskUserRemovePassphrase asks to user to pick the PGPdisk for which he wants
00f632 // to remove a passphrase.
76af5a
d0c823 void·
4b5ba9 CPGPdiskApp::AskUserRemovePassphrase(PGPBoolean removeAll)
14bb36 {
631acc ¤   AppCommandInfo¤ ¤   ACI;
--c4cb 000f59ab7e0401100af Page 3 of CPGPdiskAppPassphrase.cpp
a1fcfd ¤   COpenPGPdiskDialog¤ selectPGPdiskDlg(kODT_Select);
4c18b7 ¤   CString¤¤   ¤   ¤   path;
e1705b ¤   DualErr¤¤   ¤   ¤   derr;
4d36c6 ¤   PGPBoolean¤ ¤   ¤   wasMainEnabled;
c5af5a
b47bba ¤   // Forcibly disable main window so it doesn't flicker between dialogs.
ed023f ¤   if (mMainDialog)
8ce14e ¤   ¤   wasMainEnabled = !mMainDialog->EnableWindow(FALSE);
6aaf5a
027418 ¤   // Show the dialog.
143005 ¤   derr = selectPGPdiskDlg.AskForPath(&path);
29af5a
e22361 ¤   if (derr.IsntError())
8dc7a1 ¤   {
0dd656 ¤   ¤   // Now dispatch the command.
9aa93f ¤   ¤   ACI.op¤ ¤   = (removeAll ?·
973f69 ¤   ¤   ¤   kAppOp_RemoveAlternates : kAppOp_RemovePassphrase);
984492 ¤   ¤   ACI.flags¤  = NULL;
c5f325 ¤   ¤   ACI.drive¤  = kInvalidDrive;
fa443d ¤   ¤   strcpy(ACI.path, path);
2eaf5a
f9491e ¤   ¤   DispatchAppCommandInfo(&ACI);
099371 ¤   }
15af5a
1e4bb3 ¤   if (derr.IsError())
84c7a1 ¤   {
e16500 ¤   ¤   if (removeAll)
377df5 ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskRemoveAllPassesFailed, derr);
0c0e1d ¤   ¤   else
c8d60a ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskRemoveOnePassFailed, derr);
d29371 ¤   }
66af5a
292488 ¤   // Re-enable main dialog if it was disabled.
c5839a ¤   if (IsntNull(mMainDialog) && wasMainEnabled)
ec35a5 ¤   ¤   mMainDialog->EnableWindow(TRUE);
4aefe6 }
33af5a
c0ea4b #if PGPDISK_PUBLIC_KEY
01af5a
aea189 // AskUserAddRemovePublicKeys asks the user for a PGPdisk from which to add
b1c509 // or remove public keys.
4caf5a
39c823 void·
10cb7e CPGPdiskApp::AskUserAddRemovePublicKeys()
18bb36 {
101acc ¤   AppCommandInfo¤ ¤   ACI;
06fcfd ¤   COpenPGPdiskDialog¤ selectPGPdiskDlg(kODT_Select);
2e18b7 ¤   CString¤¤   ¤   ¤   path;
22705b ¤   DualErr¤¤   ¤   ¤   derr;
9836c6 ¤   PGPBoolean¤ ¤   ¤   wasMainEnabled;
e5af5a
017bba ¤   // Forcibly disable main window so it doesn't flicker between dialogs.
4c023f ¤   if (mMainDialog)
2be14e ¤   ¤   wasMainEnabled = !mMainDialog->EnableWindow(FALSE);
3faf5a
ee7418 ¤   // Show the dialog.
8a3005 ¤   derr = selectPGPdiskDlg.AskForPath(&path);
5faf5a
bc2361 ¤   if (derr.IsntError())
55c7a1 ¤   {
5cd656 ¤   ¤   // Now dispatch the command.
2e9d80 ¤   ¤   ACI.op¤ ¤   = kAppOp_AddRemovePublicKeys;
ea4492 ¤   ¤   ACI.flags¤  = NULL;
34f325 ¤   ¤   ACI.drive¤  = kInvalidDrive;
85443d ¤   ¤   strcpy(ACI.path, path);
15af5a
43491e ¤   ¤   DispatchAppCommandInfo(&ACI);
029371 ¤   }
f7af5a
a84bb3 ¤   if (derr.IsError())
66c7a1 ¤   {
f54024 ¤   ¤   ReportError(kPGDMajorError_AddRemovePublicKeysFailed, derr);
--cdda 00053af9439401100af Page 4 of CPGPdiskAppPassphrase.cpp
a19371 ¤   }
93af5a
962488 ¤   // Re-enable main dialog if it was disabled.
8d839a ¤   if (IsntNull(mMainDialog) && wasMainEnabled)
d135a5 ¤   ¤   mMainDialog->EnableWindow(TRUE);
fdefe6 }
2baf5a
4238e4 #endif¤ // PGPDISK_PUBLIC_KEY
cfaf5a
67af5a
ad38fb //////////////////////////////////////////////////////////////
fb56eb // Low-Level Passphrase Addition, Change, and Removal Routines
ec38fb //////////////////////////////////////////////////////////////
e8af5a
6e9677 // AddPGPdiskPassphrase adds a new passphrase to the specified PGPdisk.
97af5a
4a22ab ¤   DualErr·
6826bb CPGPdiskApp::AddPGPdiskPassphrase(LPCSTR path)
15bb36 {
0f1f8d ¤   CConfirmPassphraseDialog¤   addPassDlg(kCPDT_Add);
b077ca ¤   CSinglePassphraseDialog¤¤   masterPassDlg(kSPDT_Master);
56caca ¤   DualErr¤¤   ¤   ¤   ¤   ¤   derr;
889f52 ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   numAlts;
c8af5a
7a639f ¤   pgpAssertStrValid(path);
eeaf5a
b50949 ¤   // Did our dialogs initialize correctly?
41d2ca ¤   derr = addPassDlg.mInitErr;
16af5a
f62361 ¤   if (derr.IsntError())
78c7a1 ¤   {
433a18 ¤   ¤   derr = masterPassDlg.mInitErr;
d69371 ¤   }
bd67c5 ¤
ea4cc7 ¤   // Make sure this PGPdisk isn't mounted already.
d12361 ¤   if (derr.IsntError())
f6c7a1 ¤   {
dc5964 ¤   ¤   if (mPGPdisks.FindPGPdisk(path))
105b34 ¤   ¤   {
8b7bc2 ¤   ¤   ¤   ReportError(kPGDMajorError_TriedPassOpOnMountedPGPdisk);
340710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
2c0fe4 ¤   ¤   }
119371 ¤   }
71af5a
b08730 ¤   // Validate the PGPdisk.
162361 ¤   if (derr.IsntError())
8bc7a1 ¤   {
5c6d28 ¤   ¤   derr = ValidatePGPdisk(path);
b39371 ¤   }
5b67c5 ¤
91320c ¤   // Can't add passphrases to read-only PGPdisks.
822361 ¤   if (derr.IsntError())
dbc7a1 ¤   {
f8a495 ¤   ¤   if (IsFileReadOnly(path))
24b246 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskIsWriteProtected);
de9371 ¤   }
afaf5a
a51ec3 ¤   // Display the master passphrase dialog.
d12361 ¤   if (derr.IsntError())
abc7a1 ¤   {
fc9832 ¤   ¤   derr = masterPassDlg.AskForPassphrase(path);
839371 ¤   }
f9af5a
7e0e59 ¤   // Verify that there is space for another passphrase.
e92361 ¤   if (derr.IsntError())
e9c7a1 ¤   {
f8778c ¤   ¤   derr = HowManyAlternatePassphrases(path, &numAlts);
cc9371 ¤   }
82af5a
ea2361 ¤   if (derr.IsntError())
e7c7a1 ¤   {
5392c7 ¤   ¤   if (numAlts == kMaxAlternatePassphrases)
--4a78 00075bc4b06401100af Page 5 of CPGPdiskAppPassphrase.cpp
e35b34 ¤   ¤   {
2736a4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_AllAlternatesTaken);
c70fe4 ¤   ¤   }
139371 ¤   }
4caf5a
7756ca ¤   // Display the new passphrase dialog.
e42361 ¤   if (derr.IsntError())
a2c7a1 ¤   {
f00485 ¤   ¤   derr = addPassDlg.AskForPassphrase(path);
099371 ¤   }
f6af5a
da2361 ¤   if (derr.IsntError())
6fc7a1 ¤   {
476232 ¤   ¤   // Add the passphrase.
fc1e31 ¤   ¤   derr = AddPassphrase(path,·
e267ca ¤   ¤   ¤   masterPassDlg.mPassphraseEdit.mContents,·
152f3f ¤   ¤   ¤   addPassDlg.mPassphraseEdit.mContents,·
60aee0 ¤   ¤   ¤   addPassDlg.mReadOnlyValue);
569371 ¤   }
85af5a
7133e3 ¤   return derr;
3eefe6 }
35af5a
4ce6e7 // ChangePGPdiskPassphrase changes a passphrase on the specified PGPdisk.
f9af5a
e12292 DualErr·
e7f2fe CPGPdiskApp::ChangePGPdiskPassphrase(LPCSTR path)
75bb36 {
8ebd1d ¤   CConfirmPassphraseDialog¤   newPassDlg(kCPDT_Change);
6ddbdb ¤   CSinglePassphraseDialog¤¤   changePassDlg(kSPDT_Change);
b3caca ¤   DualErr¤¤   ¤   ¤   ¤   ¤   derr;
00af5a
6f639f ¤   pgpAssertStrValid(path);
c8af5a
e3c08d ¤   // Make sure our passphrase dialog initialized correctly.
85fb2a ¤   derr = newPassDlg.mInitErr;
9daf5a
ef2361 ¤   if (derr.IsntError())
b0c7a1 ¤   {
83c2a5 ¤   ¤   derr = changePassDlg.mInitErr;
dd9371 ¤   }
4faf5a
8e4cc7 ¤   // Make sure this PGPdisk isn't mounted already.
4e2361 ¤   if (derr.IsntError())
e5c7a1 ¤   {
245964 ¤   ¤   if (mPGPdisks.FindPGPdisk(path))
555b34 ¤   ¤   {
637bc2 ¤   ¤   ¤   ReportError(kPGDMajorError_TriedPassOpOnMountedPGPdisk);
540710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
6b0fe4 ¤   ¤   }
a69371 ¤   }
b5af5a
978730 ¤   // Validate the PGPdisk.
1e2361 ¤   if (derr.IsntError())
09c7a1 ¤   {
736d28 ¤   ¤   derr = ValidatePGPdisk(path);
139371 ¤   }
0067c5 ¤
ebe66a ¤   // Can't change passphrases on read-only PGPdisks.
9e2361 ¤   if (derr.IsntError())
c1c7a1 ¤   {
dca495 ¤   ¤   if (IsFileReadOnly(path))
3ab246 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskIsWriteProtected);
789371 ¤   }
7daf5a
afeee7 ¤   // Display the dialogs.
1d2361 ¤   if (derr.IsntError())
29c7a1 ¤   {
a2685f ¤   ¤   derr = changePassDlg.AskForPassphrase(path);
ab9371 ¤   }
22af5a
752361 ¤   if (derr.IsntError())
--5938 000b598a034401100af Page 6 of CPGPdiskAppPassphrase.cpp
f7c7a1 ¤   {
def9ee ¤   ¤   derr = newPassDlg.AskForPassphrase(path);
0b9371 ¤   }
5167c5 ¤
702361 ¤   if (derr.IsntError())
10c7a1 ¤   {
9e1e1a ¤   ¤   // Change the passphrase.
7e687f ¤   ¤   derr = ChangePassphrase(path,·
94f995 ¤   ¤   ¤   changePassDlg.mPassphraseEdit.mContents,·
691954 ¤   ¤   ¤   newPassDlg.mPassphraseEdit.mContents);
e09371 ¤   }
c4af5a
fe33e3 ¤   return derr;
87efe6 }
2daf5a
6c82bc // RemovePGPdiskPassphrase removes a passphrase from the specified PGPdisk.
f2af5a
1b2292 DualErr·
9e7870 CPGPdiskApp::RemovePGPdiskPassphrase(LPCSTR path, PGPBoolean removeAll)
f3bb36 {
be8ad6 ¤   CSinglePassphraseDialog¤removePassDlg(kSPDT_Remove);
759f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
a4af5a
b0639f ¤   pgpAssertStrValid(path);
76af5a
0e88d8 ¤   // Did our dialog initialize correctly?
3536a8 ¤   derr = removePassDlg.mInitErr;
31af5a
694cc7 ¤   // Make sure this PGPdisk isn't mounted already.
8e2361 ¤   if (derr.IsntError())
41c7a1 ¤   {
395964 ¤   ¤   if (mPGPdisks.FindPGPdisk(path))
435b34 ¤   ¤   {
997bc2 ¤   ¤   ¤   ReportError(kPGDMajorError_TriedPassOpOnMountedPGPdisk);
a40710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
f20fe4 ¤   ¤   }
d59371 ¤   }
10af5a
b28730 ¤   // Validate the PGPdisk.
412361 ¤   if (derr.IsntError())
b7c7a1 ¤   {
7a6d28 ¤   ¤   derr = ValidatePGPdisk(path);
5e9371 ¤   }
03af5a
cec34a ¤   // Can't remove passphrases from read-only PGPdisks.
542361 ¤   if (derr.IsntError())
aac7a1 ¤   {
4da495 ¤   ¤   if (IsFileReadOnly(path))
b5b246 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskIsWriteProtected);
299371 ¤   }
f8af5a
27a5da ¤   // Display the dialog.
582361 ¤   if (derr.IsntError())
42c7a1 ¤   {
0e6500 ¤   ¤   if (removeAll)
3f5b34 ¤   ¤   {
52cc07 ¤   ¤   ¤   PGPUInt32 numAlts;
38af5a
7360f0 ¤   ¤   ¤   // Verify that there are alternates to remove.
c6b390 ¤   ¤   ¤   derr = HowManyAlternatePassphrases(path, &numAlts);
20af5a
469d3d ¤   ¤   ¤   if (derr.IsntError())
a4f776 ¤   ¤   ¤   {
bd0c24 ¤   ¤   ¤   ¤   if (numAlts == 0)
8f50dc ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_NoAlternatesToRemove);
d4a3a6 ¤   ¤   ¤   }
c1af5a
0a3e07 ¤   ¤   ¤   // Confirm the removal.
ff9d3d ¤   ¤   ¤   if (derr.IsntError())
69f776 ¤   ¤   ¤   {
e65037 ¤   ¤   ¤   ¤   if (DisplayMessage(kPGPdiskVerifyRemoveAlternates,·
b59119 ¤   ¤   ¤   ¤   ¤   kPMBS_YesNo, kPMBF_YesButton) == kUR_Yes)
--a930 0003b320fcc401100af Page 7 of CPGPdiskAppPassphrase.cpp
d072c3 ¤   ¤   ¤   ¤   {
87ea94 ¤   ¤   ¤   ¤   ¤   // Remove all alternate passphrases.
f1d147 ¤   ¤   ¤   ¤   ¤   derr = RemoveAlternatePassphrases(path);
1aaf5a
104ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
214859 ¤   ¤   ¤   ¤   ¤   {
427056 ¤   ¤   ¤   ¤   ¤   ¤   DisplayMessage(kPGPdiskRemoveAltsSuccessString);
7f1c89 ¤   ¤   ¤   ¤   ¤   }
a02613 ¤   ¤   ¤   ¤   }
a0a3a6 ¤   ¤   ¤   }
1d0fe4 ¤   ¤   }
8d0e1d ¤   ¤   else
6b5b34 ¤   ¤   {
556a70 ¤   ¤   ¤   derr = removePassDlg.AskForPassphrase(path);
ceaf5a
199d3d ¤   ¤   ¤   if (derr.IsntError())
35f776 ¤   ¤   ¤   {
bf6bb7 ¤   ¤   ¤   ¤   // Remove one passphrase.
e44255 ¤   ¤   ¤   ¤   derr = RemovePassphrase(path,·
eeaa94 ¤   ¤   ¤   ¤   ¤   removePassDlg.mPassphraseEdit.mContents);
a8a3a6 ¤   ¤   ¤   }
7e0fe4 ¤   ¤   }
999371 ¤   }
8baf5a
8c33e3 ¤   return derr;
8defe6 }
2daf5a
cdea4b #if PGPDISK_PUBLIC_KEY
71af5a
e9e84b // AddRemovePGPdiskPublicKeys displays a dialog allowing users to add or
756f1a // remove keys from a PGPdisk.
d6af5a
e22292 DualErr·
276b74 CPGPdiskApp::AddRemovePGPdiskPublicKeys(LPCSTR path)
9ebb36 {
dce27a ¤   CPublicKeyDialog¤   ¤   ¤   publicKeyDialog;
2077ca ¤   CSinglePassphraseDialog¤¤   masterPassDlg(kSPDT_Master);
1fcaca ¤   DualErr¤¤   ¤   ¤   ¤   ¤   derr;
4952dc ¤   PGPBoolean¤ ¤   ¤   ¤   ¤   gotContext, gotAllKeys, gotExistingKeys;
2150a5 ¤   PGPContextRef¤  ¤   ¤   ¤   context;
aae703 ¤   PGPKeySetRef¤   ¤   ¤   ¤   allKeys;
fcb2e6 ¤   PGPRecipientSpec¤   ¤   ¤   *existRecipKeys;
f39faa ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   numRecipKeys;
fcaf5a
e115fe ¤   gotContext = gotAllKeys = gotExistingKeys = FALSE;
0faf5a
78639f ¤   pgpAssertStrValid(path);
3caf5a
8b0d1b ¤   // Did our passphrase dialog initialize correctly?
6a7beb ¤   derr = masterPassDlg.mInitErr;
b6af5a
d34cc7 ¤   // Make sure this PGPdisk isn't mounted already.
225c89 ¤   if (mPGPdisks.FindPGPdisk(path))
45c7a1 ¤   {
acf187 ¤   ¤   ReportError(kPGDMajorError_TriedPassOpOnMountedPGPdisk);
a36823 ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
c59371 ¤   }
31af5a
7a8730 ¤   // Validate the PGPdisk.
d62361 ¤   if (derr.IsntError())
64c7a1 ¤   {
166d28 ¤   ¤   derr = ValidatePGPdisk(path);
f19371 ¤   }
a4af5a
2ce5ba ¤   // Can't alter passphrases on read-only PGPdisks.
9f2361 ¤   if (derr.IsntError())
aac7a1 ¤   {
9da495 ¤   ¤   if (IsFileReadOnly(path))
78b246 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskIsWriteProtected);
ce9371 ¤   }
98af5a
3b1ec3 ¤   // Display the master passphrase dialog.
--24c5 00013c59296401100af Page 8 of CPGPdiskAppPassphrase.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
ad9832 ¤   ¤   derr = masterPassDlg.AskForPassphrase(path);
f59371 ¤   }
3967c5 ¤
3d1493 ¤   // Initialize PGP context.
1c2361 ¤   if (derr.IsntError())
6ac7a1 ¤   {
7ae0ff ¤   ¤   derr = PGPNewContext(kPGPsdkAPIVersion, &context);
318a50 ¤   ¤   gotContext = derr.IsntError();
e39371 ¤   }
bdaf5a
ad2896 ¤   // Load SDK prefs.
082361 ¤   if (derr.IsntError())
90c7a1 ¤   {
c51637 ¤   ¤   derr = PGPsdkLoadDefaultPrefs(context);
7c9371 ¤   }
08af5a
14a6c2 ¤   // Open default key rings.
672361 ¤   if (derr.IsntError())
d4c7a1 ¤   {
189a25 ¤   ¤   derr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
3d4314 ¤   ¤   gotAllKeys = derr.IsntError();
3e9371 ¤   }
57af5a
1820f7 ¤   // Retrieve already existing keys from the PGPdisk.
802361 ¤   if (derr.IsntError())
5cc7a1 ¤   {
b2644b ¤   ¤   derr = GetPGPdiskRecipKeys(path, context, allKeys, &existRecipKeys,·
c73bb3 ¤   ¤   ¤   &numRecipKeys);
62af5a
13f4bb ¤   ¤   gotExistingKeys = derr.IsntError();
af9371 ¤   }
90af5a
c6a5da ¤   // Display the dialog.
1b2361 ¤   if (derr.IsntError())
04c7a1 ¤   {
3276c5 ¤   ¤   derr = publicKeyDialog.AskForKeys(context, allKeys, existRecipKeys,·
856ca8 ¤   ¤   ¤   numRecipKeys);
269371 ¤   }
a7af5a
543fa4 ¤   // Alter keys on the PGPdisk.
d52361 ¤   if (derr.IsntError())
56c7a1 ¤   {
c5d552 ¤   ¤   derr = UpdatePGPdiskPublicKeys(path,·
10e17a ¤   ¤   ¤   masterPassDlg.mPassphraseEdit.mContents, context, allKeys,·
ea72da ¤   ¤   ¤   publicKeyDialog.mNewRecipKeys, publicKeyDialog.mNumNewKeys,·
fb0092 ¤   ¤   ¤   publicKeyDialog.mNewKeysReadOnly);
cd9371 ¤   }
86af5a
de2176 ¤   if (gotExistingKeys)
74e090 ¤   ¤   FreeRecipientSpecList(existRecipKeys, numRecipKeys);
f3af5a
7dfcc4 ¤   if (gotAllKeys)
2b4192 ¤   ¤   PGPFreeKeySet(allKeys);
a7af5a
97b0b2 ¤   if (gotContext)
50c7a1 ¤   {
a43ac6 ¤   ¤   publicKeyDialog.CleanUp();
b93e8c ¤   ¤   PGPFreeContext(context);
899371 ¤   }
dfaf5a
f333e3 ¤   return derr;
ebefe6 }
55af5a
7379f2 #if PGPDISK_WIPE_FUNCS
deaf5a
188b72 // WipePassesOnAllPGPdisks wipes the master and alternate passphrases on all
dfb26c // mounted PGPdisks (unmounting them in the process).
a6af5a
4e2292 DualErr·
1360e4 CPGPdiskApp::WipePassesOnAllPGPdisks(PGPBoolean doSilentWiping)
--1597 0005324c589401100af Page 9 of CPGPdiskAppPassphrase.cpp
2cbb36 {
fe9f96 ¤   DualErr derr, storedDerr;
a2af5a
6578f1 ¤   try
acc7a1 ¤   {
e431e9 ¤   ¤   CString¤¤   path;
3a9214 ¤   ¤   PGPdisk¤¤   *pPGD;
8cf75e ¤   ¤   PGPUInt32¤  i¤  = 0;
1faf5a
12e370 ¤   ¤   // Confirm wipe.
d06210 ¤   ¤   if (!doSilentWiping &&·
4c6539 ¤   ¤   ¤   (DisplayMessage(kPGPdiskConfirmWipeAllPasses, kPMBS_YesNo,·
eecf6b ¤   ¤   ¤   ¤   kPMBF_NoButton) == kUR_No))
fb5b34 ¤   ¤   {
5896de ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
9d0fe4 ¤   ¤   }
e3af5a
b3a0d7 ¤   ¤   // For each mounted PGPdisk...
45868d ¤   ¤   while (derr.IsntError() &&·
683fdd ¤   ¤   ¤   IsntNull(pPGD = mPGPdisks.EnumPGPdisks(i)))
805b34 ¤   ¤   {
685a4d ¤   ¤   ¤   PGPBoolean unmountedDisk = FALSE;
90af5a
7dd9f2 ¤   ¤   ¤   path = pPGD->GetPath();
16af5a
9a53d9 ¤   ¤   ¤   // Emergency unmount it.
224400 ¤   ¤   ¤   if (pPGD->Mounted())
ae7d4e ¤   ¤   ¤   ¤   derr = UnmountPGPdisk(pPGD->GetDrive(), TRUE);
00af5a
e51557 ¤   ¤   ¤   unmountedDisk = derr.IsntError();
c1af5a
df07c0 ¤   ¤   ¤   // If it has a public key, wipe the master and alternate passes.
159d3d ¤   ¤   ¤   if (derr.IsntError())
e3f776 ¤   ¤   ¤   {
2729d1 ¤   ¤   ¤   ¤   if (DoesPGPdiskHavePublicKey(path))
484663 ¤   ¤   ¤   ¤   ¤   derr = WipeMasterAndAlternatePasses(path);
6ca3a6 ¤   ¤   ¤   }
90af5a
951088 ¤   ¤   ¤   if (derr.IsError())
baf776 ¤   ¤   ¤   {
831fdd ¤   ¤   ¤   ¤   // Store the first error we see.
0577e5 ¤   ¤   ¤   ¤   if (storedDerr.IsntError())
0c916a ¤   ¤   ¤   ¤   ¤   storedDerr = derr;
6aaf5a
280670 ¤   ¤   ¤   ¤   // Clear error so we can keep going.
e4a601 ¤   ¤   ¤   ¤   derr = DualErr::NoError;
1eaf5a
ef1599 ¤   ¤   ¤   ¤   // Increment enumerator on unmount failure.
83bad5 ¤   ¤   ¤   ¤   if (!unmountedDisk)
2571b6 ¤   ¤   ¤   ¤   ¤   i++;
73a3a6 ¤   ¤   ¤   }
1d0fe4 ¤   ¤   }
ef9371 ¤   }
7f3c88 ¤   catch (CMemoryException *ex)
f4c7a1 ¤   {
eeecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
466adc ¤   ¤   ex->Delete();
9a9371 ¤   }
eeaf5a
2233e3 ¤   return derr;
fbefe6 }
57af5a
4abbac // WipePassesOnThisPGPdisk wipes the master and alternate passphrases on a
306a2b // single PGPdisk (unmounting it if mounted).
d1af5a
962292 DualErr·
7c1c34 CPGPdiskApp::WipePassesOnThisPGPdisk(LPCSTR path, PGPBoolean doSilentWiping)
debb36 {
f77d36 ¤   DualErr derr;
19af5a
97639f ¤   pgpAssertStrValid(path);
53af5a
--7b2f 000c1a367db401100af Page 10 of CPGPdiskAppPassphrase.cpp
8a78f1 ¤   try
bbc7a1 ¤   {
393d4a ¤   ¤   CString csPath = path;
5baf5a
9b707a ¤   ¤   // Is this an actual PGPdisk file?
38edd0 ¤   ¤   derr = ValidatePGPdisk(csPath);
b5af5a
e2e370 ¤   ¤   // Confirm wipe.
7eaa35 ¤   ¤   if (derr.IsntError())
6a5b34 ¤   ¤   {
afe9ec ¤   ¤   ¤   if (!doSilentWiping &&·
f4856c ¤   ¤   ¤   ¤   (DisplayMessage(kPGPdiskConfirmWipeIndPasses, kPMBS_YesNo,·
41d73b ¤   ¤   ¤   ¤   ¤   kPMBF_NoButton) == kUR_No))
d2f776 ¤   ¤   ¤   {
7895a9 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
98a3a6 ¤   ¤   ¤   }
df0fe4 ¤   ¤   }
7caf5a
beaa35 ¤   ¤   if (derr.IsntError())
d45b34 ¤   ¤   {
1bdc4e ¤   ¤   ¤   PGPdisk¤*pPGD;
67af5a
de7884 ¤   ¤   ¤   pPGD = mPGPdisks.FindPGPdisk(csPath);
6aaf5a
3d0917 ¤   ¤   ¤   // If mounted, emergency unmount it.
ec1c19 ¤   ¤   ¤   if (IsntNull(pPGD) && pPGD->Mounted())
f27d4e ¤   ¤   ¤   ¤   derr = UnmountPGPdisk(pPGD->GetDrive(), TRUE);
04af5a
ad07c0 ¤   ¤   ¤   // If it has a public key, wipe the master and alternate passes.
519d3d ¤   ¤   ¤   if (derr.IsntError())
f9f776 ¤   ¤   ¤   {
d029d1 ¤   ¤   ¤   ¤   if (DoesPGPdiskHavePublicKey(path))
3d4663 ¤   ¤   ¤   ¤   ¤   derr = WipeMasterAndAlternatePasses(path);
9ea3a6 ¤   ¤   ¤   }
b10fe4 ¤   ¤   }
969371 ¤   }
283c88 ¤   catch (CMemoryException *ex)
dec7a1 ¤   {
b1ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
cb6adc ¤   ¤   ex->Delete();
7c9371 ¤   }
7eaf5a
7033e3 ¤   return derr;
8befe6 }
93af5a
83eb5e #endif // PGPDISK_WIPE_FUNCS
5aaf5a
5f38e4 #endif¤ // PGPDISK_PUBLIC_KEY
99af5a
1eaf5a
f63e71 /////////////////////////////////////
2e3143 // Miscellaneous passphrase functions
833e71 /////////////////////////////////////
65af5a
000957 // CalcPassphraseQuality computes the "quality" of a passphrase in the range
3e2c22 // 0 - 100. Based on the function from the PGP 5.5 source code, rewritten to
fec118 // work with SecureStrings.
7faf5a
8b411c PGPUInt16·
5873bd CPGPdiskApp::CalcPassphraseQuality(SecureString* passphrase)
0acebb {¤
993b49 ¤   PGPUInt32¤  ¤   quality;
1a0475 ¤   PGPUInt16¤  ¤   charIndex, rangeIndex, span;
3eaf5a
0c758d ¤   static Range¤   sRanges[]¤  =
114859 ¤   ¤   ¤   ¤   ¤   {
e4016c ¤   ¤   ¤   ¤   ¤   ¤   { 0,¤   ¤   ' ' - 1},
c76af8 ¤   ¤   ¤   ¤   ¤   ¤   { ' ',¤ ¤   'A' - 1},
dc0334 ¤   ¤   ¤   ¤   ¤   ¤   { 'A',¤ ¤   'Z'},
723e86 ¤   ¤   ¤   ¤   ¤   ¤   { 'Z' + 1,¤ 'a' - 1},
3b2e7c ¤   ¤   ¤   ¤   ¤   ¤   { 'a',¤ ¤   'z'},
c183ee ¤   ¤   ¤   ¤   ¤   ¤   { '0',¤ ¤   '9'},
--ed1b 0012290f595401100af Page 11 of CPGPdiskAppPassphrase.cpp
a56b19 ¤   ¤   ¤   ¤   ¤   ¤   { 'z' + 1,¤ 127},
501c82 ¤   ¤   ¤   ¤   ¤   ¤   { 128,¤ ¤   255},
e819f5 ¤   ¤   ¤   ¤   ¤   };
7daf5a
c65f94 ¤   const PGPUInt16¤kNumRanges¤ = sizeof(sRanges)/sizeof(sRanges[0]);
2604ae ¤   PGPBoolean¤ ¤   haveRange[kNumRanges];
2167c5 ¤
2dc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
df67c5 ¤
fb541a ¤   pgpClearMemory(haveRange, sizeof(haveRange));
d7dcb8 ¤   for (charIndex = 1; charIndex < passphrase->GetLength(); ++charIndex)
2fc7a1 ¤   {
7ebe6d ¤   ¤   for (rangeIndex = 0; rangeIndex < kNumRanges; ++rangeIndex)
455b34 ¤   ¤   {
383bd5 ¤   ¤   ¤   PGPUInt8¤   theChar;
429193 ¤   ¤   ¤   Range*¤ ¤   theRange;
e787c7 ¤   ¤   ¤
a2d494 ¤   ¤   ¤   theChar = passphrase->GetAt(charIndex);
a89677 ¤   ¤   ¤   theRange = &sRanges[rangeIndex];
5d87c7 ¤   ¤   ¤
c18159 ¤   ¤   ¤   if (theChar >= theRange->firstChar &&·
4cc068 ¤   ¤   ¤   ¤   theChar <= theRange->lastChar)·
b5f776 ¤   ¤   ¤   {
0d54ec ¤   ¤   ¤   ¤   haveRange[rangeIndex] = TRUE;
0af622 ¤   ¤   ¤   ¤   break;
c7a3a6 ¤   ¤   ¤   }
860fe4 ¤   ¤   }
bc9371 ¤   }
9a67c5 ¤
7931cb ¤   // Determine the total span.
9cb00b ¤   span = 0;
468303 ¤   for (rangeIndex = 0; rangeIndex < kNumRanges; ++rangeIndex)
11c7a1 ¤   {
5e66ae ¤   ¤   if (haveRange[rangeIndex])
b25b34 ¤   ¤   {
77abb5 ¤   ¤   ¤   span += 1 + (sRanges[rangeIndex].lastChar -·
ff3cd2 ¤   ¤   ¤   ¤   sRanges[rangeIndex].firstChar);
5c0fe4 ¤   ¤   }
7f9371 ¤   }
5a67c5 ¤
b1797e ¤   if (span != 0)
41c7a1 ¤   {
a62ef7 ¤   ¤   double¤ ¤   bitsPerChar;
c8234e ¤   ¤   PGPUInt32¤  totalBits;
7287c7 ¤   ¤   ¤
ee10cc ¤   ¤   bitsPerChar = log (span) / log (2.0); ·// log2 of span
5462f8 ¤   ¤   totalBits = (PGPUInt32) (bitsPerChar * passphrase->GetLength());
be1b52 ¤   ¤
3062bd ¤   ¤   // Assume a maximum quality of 128 bits.
42dfc1 ¤   ¤   quality = (totalBits * 100) / 128;
db70c4 ¤   ¤   if (quality > 100) quality = 100;
429371 ¤   }
980e24 ¤   else
42c7a1 ¤   {
afeb01 ¤   ¤   quality¤= 0;
ae9371 ¤   }
a8af5a
31bc35 ¤   return quality;
22efe6 }
--23e9 001a2840f87401100b0 Page 1 of CPGPdiskAppPassphrase.h
541bc3 //////////////////////////////////////////////////////////////////////////////
07365b // CPGPdiskAppPassphrase.h
3b465d //
2d0522 // Declarations for CPGPdiskAppPassphrase.cpp.
b51bc3 //////////////////////////////////////////////////////////////////////////////
95af5a
c53936 // $Id: CPGPdiskAppPassphrase.h,v 1.1.2.3 1998/07/06 08:57:06 nryan Exp $
daaf5a
76cbce // Copyright (C) 1998 by Network Associates, Inc.
de71ae // All rights reserved.
b4af5a
9b56d9 #ifndef Included_CPGPdiskAppPassphrase_h¤   // [
11b309 #define Included_CPGPdiskAppPassphrase_h
23af5a
551cb9 // Nothing needed here.
cfaf5a
a2a549 #endif¤ // ] Included_CPGPdiskAppPassphrase_h
--8d7e 00097564a32401100b1 Page 1 of CPGPdiskAppRegistry.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
b6ab82 // CPGPdiskAppRegistry.cpp
c8465d //
0bd85c // Registry functions specific to the app.
a91bc3 //////////////////////////////////////////////////////////////////////////////
b0af5a
a597a4 // $Id: CPGPdiskAppRegistry.cpp,v 1.1.2.22.2.1 1998/10/05 18:28:22 nryan Exp $
07af5a
19cbce // Copyright (C) 1998 by Network Associates, Inc.
8d71ae // All rights reserved.
37af5a
2e9e12 #include "StdAfx.h"
56af5a
c39bcf #include "Required.h"
24babe #include "PGPdiskRegistry.h"
42bfe9 #include "UtilityFunctions.h"
6eaf5a
103646 #include "CMainDialog.h"
e85e8f #include "CPGPdiskApp.h"
e0fdcb #include "CPGPdiskAppRegistry.h"
4b6be0 #include "CGetUserInfoDialog.h"
7caf5a
e6af5a
5209b7 ////////////
07e738 // Constants
d509b7 ////////////
44af5a
354e5c static LPCSTR kNoInfoString = "None";
5daf5a
3983b5 // Places in the registry where the application path needs to go.
90af5a
e37eba const HKEY kRegistryAppPathRoot = HKEY_LOCAL_MACHINE;
50af5a
0d894a static LPCSTR kRegistryAppPathSection =·
811df0 ¤   "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\PGPdisk.exe";
7daf5a
174d6e static LPCSTR¤  kRegistryAppPathCommandKey¤ ¤   = "";
4cb2c5 static LPCSTR¤  kRegistryAppPathCommandValue¤   = "%s";
3aaf5a
5269c7 const HKEY¤ ¤   kRegistryShellNewRoot¤  ¤   ¤   = HKEY_CLASSES_ROOT;
3b84e7 static LPCSTR¤  kRegistryShellNewSection¤   ¤   = ".pgd\\ShellNew";
9eb614 static LPCSTR¤  kRegistryShellNewCommandKey¤¤   = "Command";
268c51 static LPCSTR¤  kRegistryShellNewCommandValue¤  = "%s create \"%%2\"";
d7af5a
476173 const HKEY¤ ¤   kRegistryIconRoot¤  ¤   = HKEY_CLASSES_ROOT;
9a9b5a static LPCSTR¤  kRegistryIconSection¤   = "PGPdisk Volume\\DefaultIcon";
37df56 static LPCSTR¤  kRegistryIconValue¤ ¤   = "%s,5";
c3af5a
08b210 const HKEY kRegistryShellOpenRoot = HKEY_CLASSES_ROOT;
adaf5a
383bdc static LPCSTR kRegistryShellOpenSection =·
79133d ¤   "PGPdisk Volume\\shell\\open\\command";
aeaf5a
8a4f15 static LPCSTR kRegistryShellOpenValue = "%s open \"%%1\"";
faaf5a
23af5a
f809b7 ////////////
a1659a // Functions
7009b7 ////////////
30af5a
1e3b0d // GetPersonalizationInfo retrieves the user nam and org from the registry,·
66263d // and if any of this info is missing, the user is asked to re-enter it.
26af5a
d42292 DualErr·
9744e6 CPGPdiskApp::GetPersonalizationInfo()
ffbb36 {
817d36 ¤   DualErr derr;
16af5a
1f78f1 ¤   try
f3c7a1 ¤   {
84ea4b #if PGPDISK_PUBLIC_KEY
97af5a
--2335 00004d07b62401100b1 Page 2 of CPGPdiskAppRegistry.cpp
fd970e ¤   ¤   // Get the licensing name.
7b0f7c ¤   ¤   PGPdiskGetPrefString(kRegistryPGP60LicenseUserKey, kNoInfoString,·
487c09 ¤   ¤   ¤   &mUserText, kPRL_PGP60CurrentUser);
22af5a
9beac7 ¤   ¤   // Get and set the licensing org.
6e340e ¤   ¤   PGPdiskGetPrefString(kRegistryPGP60LicenseOrgKey, kNoInfoString,·
e746c4 ¤   ¤   ¤   &mOrgText, kPRL_PGP60CurrentUser);
80af5a
f8a11d #else¤  // !PGPDISK_PUBLIC_KEY
e4af5a
5b970e ¤   ¤   // Get the licensing name.
3b239a ¤   ¤   PGPdiskGetPrefString(kRegistryLicenseUserKey, kNoInfoString,·
2d9c3f ¤   ¤   ¤   &mUserText);
d8af5a
f1eac7 ¤   ¤   // Get and set the licensing org.
95b8f3 ¤   ¤   PGPdiskGetPrefString(kRegistryLicenseOrgKey, kNoInfoString,·
1b0eb7 ¤   ¤   ¤   &mOrgText);
8eaf5a
5b38e4 #endif¤ // PGPDISK_PUBLIC_KEY
99af5a
ec6275 ¤   ¤   // If any of these keys have been lost, ask the user to re-enter all
ec3834 ¤   ¤   // of the information.
e4af5a
655282 ¤   ¤   if ((mUserText == kNoInfoString) ||·
9898b2 ¤   ¤   ¤   (mOrgText == kNoInfoString))
d75b34 ¤   ¤   {
c9e4d9 ¤   ¤   ¤   CGetUserInfoDialog¤ getUserInfoDialog;
7c44b6 ¤   ¤   ¤   DualErr¤¤   ¤   ¤   dialogError;
76af5a
65fd5f ¤   ¤   ¤   dialogError = getUserInfoDialog.AskForUserInfo();
68af5a
c942ad ¤   ¤   ¤   // The user is only allowed to hit OK if he entered something.
cbc835 ¤   ¤   ¤   if (dialogError.IsntError())
dbf776 ¤   ¤   ¤   {
fddb8b ¤   ¤   ¤   ¤   mUserText¤  = getUserInfoDialog.mUserText;
f40c16 ¤   ¤   ¤   ¤   mOrgText¤   = getUserInfoDialog.mOrgText;
31af5a
38064e ¤   ¤   ¤   ¤   derr = SetPersonalizationInfo();
f5a3a6 ¤   ¤   ¤   }
71af5a
2f4760 ¤   ¤   ¤   // If he cancelled or the set failed, show 'None' to the user in
3e8353 ¤   ¤   ¤   // all fields, not just the one that had the missing key. Don't
b35930 ¤   ¤   ¤   // set them in the registry, however, since we want PGPdisk to
e3a49a ¤   ¤   ¤   // ask him again next time it starts.
29af5a
47da4b ¤   ¤   ¤   if (dialogError.IsError() || derr.IsError())
30f776 ¤   ¤   ¤   {
9ea8a7 ¤   ¤   ¤   ¤   mUserText¤  = kNoInfoString;
dd9dab ¤   ¤   ¤   ¤   mOrgText¤   = kNoInfoString;
9aa3a6 ¤   ¤   ¤   }
a50fe4 ¤   ¤   }
a79371 ¤   }
7d3c88 ¤   catch (CMemoryException *ex)
f2c7a1 ¤   {
aeecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
656adc ¤   ¤   ex->Delete();
159371 ¤   }
61af5a
d833e3 ¤   return derr;
27efe6 }
21af5a
7ae47e // SetPersonalizationInfo updates the registry with new registration
30cf8a // information.
2baf5a
3a2292 DualErr·
6c12ba CPGPdiskApp::SetPersonalizationInfo()
1fbb36 {
1b7d36 ¤   DualErr derr;
d1af5a
5dea4b #if PGPDISK_PUBLIC_KEY
f2af5a
04e265 ¤   // Set the licensing name.
--1562 0001e395a34401100b1 Page 3 of CPGPdiskAppRegistry.cpp
437204 ¤   derr = PGPdiskSetPrefString(kRegistryPGP60LicenseUserKey, mUserText,·
747d20 ¤   ¤   kPRL_PGP60CurrentUser);
09af5a
f9cfb4 ¤   // Set the organization name.
fe2361 ¤   if (derr.IsntError())
89c7a1 ¤   {
3d0976 ¤   ¤   derr = PGPdiskSetPrefString(kRegistryPGP60LicenseOrgKey, mOrgText,·
30f6dc ¤   ¤   ¤   kPRL_PGP60CurrentUser);
959371 ¤   }
4eaf5a
6aa11d #else¤  // !PGPDISK_PUBLIC_KEY
61af5a
00e265 ¤   // Set the licensing name.
04201a ¤   derr = PGPdiskSetPrefString(kRegistryLicenseUserKey, mUserText);
7aaf5a
35cfb4 ¤   // Set the organization name.
292361 ¤   if (derr.IsntError())
6cc7a1 ¤   {
25eb6c ¤   ¤   derr = PGPdiskSetPrefString(kRegistryLicenseOrgKey, mOrgText);
639371 ¤   }
cdaf5a
0438e4 #endif¤ // PGPDISK_PUBLIC_KEY
bbaf5a
b133e3 ¤   return derr;
11efe6 }
5daf5a
da471e // GetRegistryPrefs retrieves the PGPdisk preferences from the registry,
2e9bd6 // validates them, and writes them out again.
4eaf5a
132292 DualErr·
776c96 CPGPdiskApp::GetRegistryPrefs()
5dbb36 {
14be41 ¤   DualErr¤¤   derr;
51c417 ¤   PGPUInt32¤  temp;
69af5a
1181da ¤   // Get the value for the 'Auto-Unmount' key.
a5ebac ¤   temp = PGPdiskGetPrefDWord(kRegistryAutoUnmountKey,·
c5f9d7 ¤   ¤   kInvalidRegDWordValue);
62af5a
3aeaf3 ¤   if (temp == FALSE)
a3f266 ¤   ¤   mAutoUnmount = FALSE;
ae6842 ¤   else if (temp == TRUE)
770195 ¤   ¤   mAutoUnmount = TRUE;
510e24 ¤   else
392d7d ¤   ¤   mAutoUnmount = kDefaultAutoUnmount;
c6af5a
8145fc ¤   // Get the value for the 'HotKeyCode' key.
24007a ¤   mHotKeyCode = (PGPUInt16) PGPdiskGetPrefDWord(kRegistryHotKeyCodeKey,·
3af9d7 ¤   ¤   kInvalidRegDWordValue);
39af5a
7d00c5 ¤   // Get the value for the 'HotKeyEnabled' key.
ac191d ¤   temp = PGPdiskGetPrefDWord(kRegistryHotKeyEnabledKey,·
e9f9d7 ¤   ¤   kInvalidRegDWordValue);
4a67c5 ¤
86eaf3 ¤   if (temp == FALSE)
ca77aa ¤   ¤   mHotKeyEnabled = FALSE;
146842 ¤   else if (temp == TRUE)
c7cd04 ¤   ¤   mHotKeyEnabled = TRUE;
100e24 ¤   else
50c6af ¤   ¤   mHotKeyEnabled = kDefaultHotKeyEnabled;
abaf5a
7f0d6f ¤   // Get the value for the 'UnmountOnSleep' key.
9375a2 ¤   temp = PGPdiskGetPrefDWord(kRegistryUnmountOnSleepKey,·
bff9d7 ¤   ¤   kInvalidRegDWordValue);
6b67c5 ¤
8aeaf3 ¤   if (temp == FALSE)
f15db2 ¤   ¤   mUnmountOnSleep = FALSE;
516842 ¤   else if (temp == TRUE)
bd8f9f ¤   ¤   mUnmountOnSleep = TRUE;
b60e24 ¤   else
38c611 ¤   ¤   mUnmountOnSleep = kDefaultUnmountOnSleep;
1eaf5a
--90e8 000bfff1cda401100b1 Page 4 of CPGPdiskAppRegistry.cpp
f1009c ¤   // Get the value for the 'NoSleepIfUnmountFail' key.
9939ea ¤   temp = PGPdiskGetPrefDWord(kRegistryNoSleepIfFailKey,·
2af9d7 ¤   ¤   kInvalidRegDWordValue);
e967c5 ¤
37eaf3 ¤   if (temp == FALSE)
dfa63c ¤   ¤   mNoSleepIfUnmountFail = FALSE;
c26842 ¤   else if (temp == TRUE)
74eea3 ¤   ¤   mNoSleepIfUnmountFail = TRUE;
240e24 ¤   else
0b6749 ¤   ¤   mNoSleepIfUnmountFail = kDefaultNoSleepIfUnmountFail;
17af5a
bad3b0 ¤   // Previous two options not available on NT4.
a47408 ¤   if (IsWinNT4CompatibleMachine() && !IsWinNT5CompatibleMachine())
45c7a1 ¤   {
586428 ¤   ¤   mUnmountOnSleep = mNoSleepIfUnmountFail = FALSE;
d99371 ¤   }
16af5a
d1adf9 ¤   // Get the value for the 'UnmountTimeout' key.
0dc157 ¤   temp = PGPdiskGetPrefDWord(kRegistryUnmountTimeoutKey,·
a0ff30 ¤   ¤   kMaxUnmountTimeout + 1);
b667c5 ¤
e182ad ¤   if ((temp == FALSE) || (temp > kMaxUnmountTimeout))
ae1698 ¤   ¤   mUnmountTimeout = kDefaultUnmountTimeout;
680e24 ¤   else
60104c ¤   ¤   mUnmountTimeout = temp;
8eaf5a
0dd050 ¤   // Now write out the preferences to the registry.
1eb43e ¤   derr = SetRegistryPrefs();
f3af5a
ac33e3 ¤   return derr;
23efe6 }
4faf5a
cc4431 // SetRegistryPrefs updates the registry with the value of the app's user-
ad98dc // defined preferences.
50af5a
072292 DualErr·
5a4d99 CPGPdiskApp::SetRegistryPrefs()
40bb36 {
fa945d ¤   DualErr¤derr;
d1af5a
0a78b8 ¤   derr = PGPdiskSetPrefDWord(kRegistryAutoUnmountKey, mAutoUnmount);
a7af5a
0c2361 ¤   if (derr.IsntError())
ffc7a1 ¤   {
9b1259 ¤   ¤   derr = PGPdiskSetPrefDWord(kRegistryHotKeyCodeKey, mHotKeyCode);
029371 ¤   }
73af5a
f02361 ¤   if (derr.IsntError())
60c7a1 ¤   {
b039a3 ¤   ¤   derr = PGPdiskSetPrefDWord(kRegistryHotKeyEnabledKey, mHotKeyEnabled);
4f9371 ¤   }
b0af5a
f12361 ¤   if (derr.IsntError())
74c7a1 ¤   {
ef9654 ¤   ¤   derr = PGPdiskSetPrefDWord(kRegistryUnmountOnSleepKey,·
04aed9 ¤   ¤   ¤   mUnmountOnSleep);
949371 ¤   }
f8af5a
402361 ¤   if (derr.IsntError())
77c7a1 ¤   {
ace14e ¤   ¤   derr = PGPdiskSetPrefDWord(kRegistryNoSleepIfFailKey,·
742115 ¤   ¤   ¤   mNoSleepIfUnmountFail);
a59371 ¤   }
45af5a
c02361 ¤   if (derr.IsntError())
72c7a1 ¤   {
cd22a1 ¤   ¤   derr = PGPdiskSetPrefDWord(kRegistryUnmountTimeoutKey,·
69fb37 ¤   ¤   ¤   mUnmountTimeout);
df9371 ¤   }
f1af5a
e990d6 #if¤PGP_DEBUG
bfe7c9 #if¤PGPDISK_ENABLEDEBUGMENU
--5495 0008cf6c744401100b1 Page 5 of CPGPdiskAppRegistry.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
755ba7 ¤   ¤   derr = PGPdiskSetPrefDWord(kRegistryUseAsyncIOKey, mUseAsyncIO);
4c9371 ¤   }
849ab1 #endif¤ // PGPDISK_ENABLEDEBUGMENU
8f1e67 #endif¤ // PGP_DEBUG
28af5a
a233e3 ¤   return derr;
c1efe6 }
41af5a
7bb0af // SetRegistryPaths updates all the places in the registry where the path to
851093 // the PGPdisk application is stored.
e4af5a
5f2292 DualErr·
6d771d CPGPdiskApp::SetRegistryPaths()
b2bb36 {
a1ab5f ¤   CString¤appPath, newValue;
ca945d ¤   DualErr¤derr;
fcaf5a
d278f1 ¤   try
abc7a1 ¤   {
6e7234 ¤   ¤   // Get the pathname of the application.
e3a9ba ¤   ¤   if (!::GetModuleFileName(NULL, appPath.GetBuffer(kMaxStringSize),·
fae6c6 ¤   ¤   ¤   kMaxStringSize))
0c5b34 ¤   ¤   {
a4f13c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FindAppPathFailed, GetLastError());
aa0fe4 ¤   ¤   }
7daf5a
3bd605 ¤   ¤   appPath.ReleaseBuffer();
4aaf5a
5caa35 ¤   ¤   if (derr.IsntError())
a45b34 ¤   ¤   {
36dfbe ¤   ¤   ¤   CString temp = appPath;
8faf5a
2e82cc ¤   ¤   ¤   // Must change the path to "short" form.
49f48a ¤   ¤   ¤   GetShortPathName(temp, appPath.GetBuffer(kMaxStringSize),·
17fbb1 ¤   ¤   ¤   ¤   kMaxStringSize);
e2af5a
b9eb6d ¤   ¤   ¤   appPath.ReleaseBuffer();
81af5a
97daa9 ¤   ¤   ¤   // Update the application path key.
0c7fa1 ¤   ¤   ¤   newValue.Format(kRegistryAppPathCommandValue, appPath);
92af5a
63a989 ¤   ¤   ¤   derr = PGPdiskCreateAndSetRawKey(kRegistryAppPathRoot,·
8d43ee ¤   ¤   ¤   ¤   kRegistryAppPathSection, kRegistryAppPathCommandKey,·
2a4b63 ¤   ¤   ¤   ¤   (const PGPUInt8 *) (LPCSTR) newValue,·
711f4d ¤   ¤   ¤   ¤   newValue.GetLength() + 1, REG_SZ);
650fe4 ¤   ¤   }
16af5a
a8908a ¤   ¤   // Update the "ShellNew" key.
b4aa35 ¤   ¤   if (derr.IsntError())
055b34 ¤   ¤   {
0f977e ¤   ¤   ¤   newValue.Format(kRegistryShellNewCommandValue, appPath);
82af5a
890006 ¤   ¤   ¤   derr = PGPdiskCreateAndSetRawKey(kRegistryShellNewRoot,·
1e3da5 ¤   ¤   ¤   ¤   kRegistryShellNewSection, kRegistryShellNewCommandKey,·
994b63 ¤   ¤   ¤   ¤   (const PGPUInt8 *) (LPCSTR) newValue,·
2c1f4d ¤   ¤   ¤   ¤   newValue.GetLength() + 1, REG_SZ);
090fe4 ¤   ¤   }
7b1b52 ¤   ¤
677918 ¤   ¤   // Update the "IconSection" key.
2faa35 ¤   ¤   if (derr.IsntError())
fa5b34 ¤   ¤   {
c17178 ¤   ¤   ¤   newValue.Format(kRegistryIconValue, appPath);
5aaf5a
27eeda ¤   ¤   ¤   derr = PGPdiskCreateAndSetRawKey(kRegistryIconRoot,·
e6f281 ¤   ¤   ¤   ¤   kRegistryIconSection, NULL,·
464b63 ¤   ¤   ¤   ¤   (const PGPUInt8 *) (LPCSTR) newValue,·
b91f4d ¤   ¤   ¤   ¤   newValue.GetLength() + 1, REG_SZ);
580fe4 ¤   ¤   }
35af5a
8cc3ca ¤   ¤   // Update the "ShellOpen" key.
--0024 0014dbb40f2401100b1 Page 6 of CPGPdiskAppRegistry.cpp
08aa35 ¤   ¤   if (derr.IsntError())
e95b34 ¤   ¤   {
83a548 ¤   ¤   ¤   newValue.Format(kRegistryShellOpenValue, appPath);
11af5a
2e723e ¤   ¤   ¤   derr = PGPdiskCreateAndSetRawKey(kRegistryShellOpenRoot,·
45265a ¤   ¤   ¤   ¤   kRegistryShellOpenSection, NULL,·
704b63 ¤   ¤   ¤   ¤   (const PGPUInt8 *) (LPCSTR) newValue,·
981f4d ¤   ¤   ¤   ¤   newValue.GetLength() + 1, REG_SZ);
9a0fe4 ¤   ¤   }
cf9371 ¤   }
eb3c88 ¤   catch (CMemoryException *ex)
4bc7a1 ¤   {
96ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
086adc ¤   ¤   ex->Delete();
ba9371 ¤   }
f9af5a
9733e3 ¤   return derr;
4defe6 }
--34d0 00193bf2daf401100b2 Page 1 of CPGPdiskAppRegistry.h
541bc3 //////////////////////////////////////////////////////////////////////////////
5bdda7 // CPGPdiskAppRegistry
38465d //
75f8c9 // Declarations for CPGPdiskAppRegistry.cpp.
131bc3 //////////////////////////////////////////////////////////////////////////////
89af5a
6b5be8 // $Id: CPGPdiskAppRegistry.h,v 1.1.2.7 1998/07/06 08:57:08 nryan Exp $
01af5a
22cbce // Copyright (C) 1998 by Network Associates, Inc.
4b71ae // All rights reserved.
d1af5a
c2fb8f #ifndef Included_CPGPdiskAppRegistry_h¤ // [
302750 #define Included_CPGPdiskAppRegistry_h
73af5a
861cb9 // Nothing needed here.
c7af5a
93eec6 #endif¤ // ] Included_CPGPdiskAppRegistry_h
--9b41 00057ac30de401100b3 Page 1 of CPGPdiskAppVolumes.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
9e63a9 // CPGPdiskAppVolumes.cpp
88465d //
049a1b // Helper functions for volume management.
971bc3 //////////////////////////////////////////////////////////////////////////////
16af5a
2eb95e // $Id: CPGPdiskAppVolumes.cpp,v 1.1.2.26.2.9 1998/10/28 00:13:30 nryan Exp $
d9af5a
22cbce // Copyright (C) 1998 by Network Associates, Inc.
5d71ae // All rights reserved.
74af5a
459e12 #include "StdAfx.h"
3faf5a
759bcf #include "Required.h"
c9ac00 #include "DriverComm.h"
c57414 #include "PGPdiskHighLevelUtils.h"
9bbabe #include "PGPdiskRegistry.h"
04993c #include "StringAssociation.h"
09bfe9 #include "UtilityFunctions.h"
24af5a
97ea4b #if PGPDISK_PUBLIC_KEY
1ff4f6 #include "PGPdiskPublicKeyUtils.h"
a238e4 #endif¤ // PGPDISK_PUBLIC_KEY
0daf5a
a168c5 #include "CConvertWizardSheet.h"
db22eb #include "CDiskWizardSheet.h"
3f31a0 #include "CGlobalCWizardSheet.h"
023646 #include "CMainDialog.h"
d289af #include "CNagBuyDialog.h"
284aaa #include "COpenPGPdiskDialog.h"
355e8f #include "CPGPdiskApp.h"
d88846 #include "CPGPdiskAppVolumes.h"
1637c7 #include "CSavePGPdiskDialog.h"
5e1998 #include "CSinglePassphraseDialog.h"
01a918 #include "CUnmountPGPdiskDialog.h"
3a68c6 #include "PGPdisk.h"
cfaf5a
39af5a
18ed79 /////////////////////////////////////////
6e4a72 // High-Level Mount and Creation Routines
02ed79 /////////////////////////////////////////
19af5a
5fe268 // AskUserMountPGPdisk asks the user to select a PGPdisk to mount.
49af5a
77c823 void·
55145b CPGPdiskApp::AskUserMountPGPdisk()
18bb36 {
bb1acc ¤   AppCommandInfo¤ ¤   ACI;
26caf7 ¤   COpenPGPdiskDialog¤ mountPGPdiskDlg(kODT_Mount);
9e18b7 ¤   CString¤¤   ¤   ¤   path;
f9705b ¤   DualErr¤¤   ¤   ¤   derr;
00af5a
2cc4ca ¤   // Any drive letters free?
b6d229 ¤   if (!AreAnyDriveLettersFree())
68c7a1 ¤   {
383c30 ¤   ¤   derr = DualErr(kPGDMinorError_NoDriveLettersFree);
ca9371 ¤   }
ecaf5a
ab7418 ¤   // Show the dialog.
542361 ¤   if (derr.IsntError())
d5c7a1 ¤   {
826cc9 ¤   ¤   derr = mountPGPdiskDlg.AskForPath(&path);
e89371 ¤   }
d4af5a
5a2361 ¤   if (derr.IsntError())
18c7a1 ¤   {
c01ce8 ¤   ¤   // Now attempt the mount.
cdf242 ¤   ¤   ACI.op¤ ¤   = kAppOp_Mount;
cd4492 ¤   ¤   ACI.flags¤  = NULL;
8ff325 ¤   ¤   ACI.drive¤  = kInvalidDrive;
c4443d ¤   ¤   strcpy(ACI.path, path);
57af5a
--9cc6 0008fe3a4c7401100b3 Page 2 of CPGPdiskAppVolumes.cpp
876303 ¤   ¤   DispatchAppCommandInfo(&ACI);¤
a49371 ¤   }
e5af5a
054bb3 ¤   if (derr.IsError())
2cc7a1 ¤   {
f25221 ¤   ¤   ReportError(kPGDMajorError_PGPdiskMountFailed, derr);
a79371 ¤   }
8fefe6 }
76af5a
6145dd // AskUserUnmountPGPdisk asks the user to select a PGPdisk to unmount.
c7af5a
5ac823 void·
1f5b18 CPGPdiskApp::AskUserUnmountPGPdisk()
fbbb36 {
74a26a ¤   CUnmountPGPdiskDialog¤  unmountPGPdiskDlg;
e69f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
2aaf5a
b4b6db ¤   // Get PGPdisk info.
0922fc ¤   derr = UpdateAppPGPdiskInfo();
a0af5a
1f0127 ¤   // Complain if there are no PGPdisks to unmount.
9e2361 ¤   if (derr.IsntError())
8fc7a1 ¤   {
8367c8 ¤   ¤   if (mPGPdisks.GetNumPGPdisks() == 0)
a85b34 ¤   ¤   {
a1e965 ¤   ¤   ¤   DisplayMessage(kPGPdiskNoPGPdisksToUnmountString);
f80ecc ¤   ¤   ¤   return;
c60fe4 ¤   ¤   }
5c9371 ¤   }
eeaf5a
8b7418 ¤   // Show the dialog.
582361 ¤   if (derr.IsntError())
d2c7a1 ¤   {
a3cf63 ¤   ¤   derr = unmountPGPdiskDlg.AskForDriveLetter();
339371 ¤   }
deaf5a
feec1e ¤   // Attempt the unmount.
692361 ¤   if (derr.IsntError())
6ac7a1 ¤   {
1bb2c3 ¤   ¤   AppCommandInfo ACI;
88af5a
161232 ¤   ¤   ACI.op¤ ¤   = kAppOp_Unmount;
3c4492 ¤   ¤   ACI.flags¤  = NULL;
c3b6b6 ¤   ¤   ACI.drive¤  = unmountPGPdiskDlg.mDriveToUnmount;
652950 ¤   ¤   ACI.path[0]¤= '\0';
5daf5a
59491e ¤   ¤   DispatchAppCommandInfo(&ACI);
059371 ¤   }
23af5a
8b4bb3 ¤   if (derr.IsError())
44c7a1 ¤   {
8f5221 ¤   ¤   ReportError(kPGDMajorError_PGPdiskMountFailed, derr);
f99371 ¤   }
56efe6 }
05af5a
f73354 // AskUserNewPGPdisk calls down to begin the PGPdisk creation process.
18af5a
59c823 void·
bf7c17 CPGPdiskApp::AskUserNewPGPdisk()
24bb36 {
ed44a6 ¤   AppCommandInfo ACI;
d9af5a
2f9102 ¤   // We don't ask for the path here.
944c93 ¤   ACI.op¤ ¤   = kAppOp_Create;
9fb2f7 ¤   ACI.flags¤  = NULL;
fcce4d ¤   ACI.drive¤  = kInvalidDrive;
fedf35 ¤   ACI.path[0]¤= '\0';
14af5a
dca66d ¤   DispatchAppCommandInfo(&ACI);
66efe6 }
20af5a
8fad38 // AskUserGlobalConvertPGPdisks starts the global PGPdisk conversion process.
--1e3f 000fed26188401100b3 Page 3 of CPGPdiskAppVolumes.cpp
e0af5a
20c823 void·
2b923f CPGPdiskApp::AskUserGlobalConvertPGPdisks()
b8bb36 {
0244a6 ¤   AppCommandInfo ACI;
28af5a
0ef9aa ¤   ACI.op¤ ¤   = kAppOp_GlobalConvert;
37b2f7 ¤   ACI.flags¤  = NULL;
edce4d ¤   ACI.drive¤  = kInvalidDrive;
aadf35 ¤   ACI.path[0]¤= '\0';
20af5a
20a66d ¤   DispatchAppCommandInfo(&ACI);
9fefe6 }
7daf5a
6daf5a
3e19ca /////////////////////////////////////////////////
d5f02e // Low-Level Mount, Unmount and Creation Routines
2819ca /////////////////////////////////////////////////
0baf5a
936efb // UpdateAppPGPdiskInfo asks the driver for info on all mounted PGPdisks and
a3c123 // makes sure we are current.
d1af5a
822292 DualErr·
9be036 CPGPdiskApp::UpdateAppPGPdiskInfo()
2bbb36 {
2bbe41 ¤   DualErr¤¤   derr;
4bdb4b ¤   PGPBoolean¤ createdPDIArray;
5888b8 ¤   PGPdiskInfo¤*pPDIArray;
85af5a
ce3b83 ¤   pgpAssert(IsDriverOpen());
7caf5a
e61825 ¤   // Allocate space for the PGPdiskInfo array.
3678f1 ¤   try
92c7a1 ¤   {
834c21 ¤   ¤   pPDIArray = new PGPdiskInfo[kMaxDrives];
f49371 ¤   }
863c88 ¤   catch (CMemoryException *ex)
83c7a1 ¤   {
25ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
cf6adc ¤   ¤   ex->Delete();
c39371 ¤   }
31af5a
76652c ¤   createdPDIArray = derr.IsntError();
c9af5a
e5883a ¤   // Ask the driver to fill in our array.
3d2361 ¤   if (derr.IsntError())
6ec7a1 ¤   {
fbb660 ¤   ¤   derr = GetPGPdiskInfo(pPDIArray, kMaxDrives);
469371 ¤   }
c5af5a
523ba2 ¤   // Update our list of PGPdisks accordingly.
0b2361 ¤   if (derr.IsntError())
25c7a1 ¤   {
319214 ¤   ¤   PGPdisk¤¤   *pPGD;
bb4c31 ¤   ¤   PGPdiskInfo¤*pPDI;
373cc8 ¤   ¤   PGPUInt32¤  i;
26af5a
b4f82b ¤   ¤   // Empty the container.
e4fed4 ¤   ¤   mPGPdisks.ClearContainerWithDelete();
73af5a
9ac4eb ¤   ¤   // Parse the array.
c19302 ¤   ¤   for (i = 0; i < kMaxDrives; i++)
c25b34 ¤   ¤   {
d3522b ¤   ¤   ¤   pPDI = &pPDIArray[i];
a1af5a
fd24b7 ¤   ¤   ¤   // Legal drive letters represent PGPdisks.
cd729b ¤   ¤   ¤   if (IsLegalDriveNumber(pPDI->drive))
b0f776 ¤   ¤   ¤   {
b04fc6 ¤   ¤   ¤   ¤   PGPBoolean createdPGPdiskObject = FALSE;
24af5a
94c7f5 ¤   ¤   ¤   ¤   // Create a new PGPdisk object.
fecc32 ¤   ¤   ¤   ¤   try
--a01a 000fb430dd4401100b3 Page 4 of CPGPdiskAppVolumes.cpp
d072c3 ¤   ¤   ¤   ¤   {
a22593 ¤   ¤   ¤   ¤   ¤   pPGD = new PGPdisk(pPDI->path, pPDI->drive,·
10823d ¤   ¤   ¤   ¤   ¤   ¤   pPDI->sessionId);
f52613 ¤   ¤   ¤   ¤   }
4b02b5 ¤   ¤   ¤   ¤   catch (CMemoryException *ex)
af72c3 ¤   ¤   ¤   ¤   {
f5f217 ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
971335 ¤   ¤   ¤   ¤   ¤   ex->Delete();
1b2613 ¤   ¤   ¤   ¤   }
59af5a
c57798 ¤   ¤   ¤   ¤   createdPGPdiskObject = derr.IsntError();
f2af5a
5086c3 ¤   ¤   ¤   ¤   // Check if created successfully.
e6724e ¤   ¤   ¤   ¤   if (derr.IsntError())
c672c3 ¤   ¤   ¤   ¤   {
a0646f ¤   ¤   ¤   ¤   ¤   derr = pPGD->mInitErr;
e62613 ¤   ¤   ¤   ¤   }
cdaf5a
54fa82 ¤   ¤   ¤   ¤   // Put the PGPdisk in the global list.
45724e ¤   ¤   ¤   ¤   if (derr.IsntError())
fa72c3 ¤   ¤   ¤   ¤   {
045073 ¤   ¤   ¤   ¤   ¤   mPGPdisks.AddPGPdisk(pPGD);
b22613 ¤   ¤   ¤   ¤   }
00af5a
e19b74 ¤   ¤   ¤   ¤   if (derr.IsError())
3472c3 ¤   ¤   ¤   ¤   {
eedf1d ¤   ¤   ¤   ¤   ¤   if (createdPGPdiskObject)
d4f861 ¤   ¤   ¤   ¤   ¤   ¤   delete pPGD;
e12613 ¤   ¤   ¤   ¤   }
07a3a6 ¤   ¤   ¤   }
55af5a
0d1088 ¤   ¤   ¤   if (derr.IsError())
c4f776 ¤   ¤   ¤   {
e4f622 ¤   ¤   ¤   ¤   break;
f469c5 ¤   ¤   ¤   }¤  ¤
170fe4 ¤   ¤   }
dd9371 ¤   }
95af5a
22ab17 ¤   if (createdPDIArray)
243baf ¤   ¤   delete[] pPDIArray;
9baf5a
b833e3 ¤   return derr;
cdefe6 }
27af5a
c552c1 // GlobalConvertPGPdisks invokes the global PGPdisk conversion wizard.
baaf5a
f02292 DualErr·
06bbca CPGPdiskApp::GlobalConvertPGPdisks()
78bb36 {
e6705b ¤   DualErr¤¤   ¤   ¤   derr;
ab43b2 ¤   CGlobalCWizardSheet¤globalCPGPdiskSheet;
67af5a
302535 ¤   derr = globalCPGPdiskSheet.mInitErr;
e0af5a
4c2361 ¤   if (derr.IsntError())
5fc7a1 ¤   {
2068c4 ¤   ¤   derr = globalCPGPdiskSheet.ExecuteWizard();
a39371 ¤   }
83af5a
9633e3 ¤   return derr;
5cefe6 }
5baf5a
3269df // ConvertPGPdiskPriorToMount attempts to convert a PGPdisk with bad CAST to
4f4163 // one with good CAST.
a3af5a
a92292 DualErr·
f5b5de CPGPdiskApp::ConvertPGPdiskPriorToMount(LPCSTR path, PGPBoolean *pUserSaysNo)
25bb36 {
8ebe41 ¤   DualErr¤¤   derr;
c3614e ¤   PGPBoolean¤ userSaysNo¤ = FALSE;
02af5a
fb639f ¤   pgpAssertStrValid(path);
--5739 0003e9f072e401100b3 Page 5 of CPGPdiskAppVolumes.cpp
1a31b0 ¤   pgpAssertAddrValid(pUserSaysNo, PGPBoolean);
2baf5a
13939d ¤   if (IsFileReadOnly(path))
adc7a1 ¤   {
6fd8dd ¤   ¤   DisplayMessage(kPGPdiskBadCASTReadOnly);
b3dfd9 ¤   ¤   userSaysNo = TRUE;
209371 ¤   }
4c0e24 ¤   else
89c7a1 ¤   {
e19e40 ¤   ¤   PGPBoolean¤ ¤   restartingConversion;
318b5e ¤   ¤   UserResponse¤   response;
1eaf5a
05a854 ¤   ¤   // Is this PGPdisk partially converted already?
83e590 ¤   ¤   restartingConversion = WasPGPdiskConversionInterrupted(path);
f7af5a
8a8b40 ¤   ¤   if (restartingConversion)
565b34 ¤   ¤   {
9bc6e7 ¤   ¤   ¤   response = DisplayMessage(kPGPdiskBadCASTAskContinuePM,·
96987d ¤   ¤   ¤   ¤   kPMBS_YesNo, kPMBF_YesButton);
e40fe4 ¤   ¤   }
090e1d ¤   ¤   else
745b34 ¤   ¤   {
8d3d8b ¤   ¤   ¤   response = DisplayMessage(kPGPdiskBadCASTAskConvertPM,·
601b3f ¤   ¤   ¤   ¤   kPMBS_YesNoCancel, kPMBF_YesButton);
c80fe4 ¤   ¤   }
c4af5a
3f17e4 ¤   ¤   // Do what the user wants in regards to conversion.
fdb65b ¤   ¤   switch (response)
635b34 ¤   ¤   {
17d952 ¤   ¤   ¤   case kUR_Yes:
9c72c3 ¤   ¤   ¤   ¤   {
dd82e3 ¤   ¤   ¤   ¤   ¤   CConvertWizardSheet convertPGPdiskSheet;
97af5a
863aae ¤   ¤   ¤   ¤   ¤   derr = convertPGPdiskSheet.mInitErr;
b3af5a
444ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
6b4859 ¤   ¤   ¤   ¤   ¤   {
c263e2 ¤   ¤   ¤   ¤   ¤   ¤   derr = convertPGPdiskSheet.ExecuteWizard(path,·
ff320f ¤   ¤   ¤   ¤   ¤   ¤   ¤   restartingConversion);
6a1c89 ¤   ¤   ¤   ¤   ¤   }
d82613 ¤   ¤   ¤   ¤   }
18f622 ¤   ¤   ¤   ¤   break;
bbaf5a
73e022 ¤   ¤   ¤   case kUR_No:
27478e ¤   ¤   ¤   ¤   userSaysNo = TRUE;
45af5a
1158dd ¤   ¤   ¤   ¤   if (restartingConversion)
5e4d03 ¤   ¤   ¤   ¤   ¤   derr = kPGDMinorError_UserAbort;
3bf622 ¤   ¤   ¤   ¤   break;
dcaf5a
2590b7 ¤   ¤   ¤   case kUR_Cancel:
ed1e18 ¤   ¤   ¤   ¤   derr = kPGDMinorError_UserAbort;
6cf622 ¤   ¤   ¤   ¤   break;
e80fe4 ¤   ¤   }
f29371 ¤   }
e4af5a
fa00df ¤   (* pUserSaysNo) = userSaysNo;
b4af5a
4533e3 ¤   return derr;
1aefe6 }
19af5a
7d2c03 // ConvertPGPdiskFromGlobalWizard attempts to convert a PGPdisk with bad CAST
d6ceaa // to one with good CAST.
efaf5a
e42292 DualErr·
8b357e CPGPdiskApp::ConvertPGPdiskFromGlobalWizard(
82f2f8 ¤   LPCSTR¤ ¤   path,·
e8b812 ¤   PGPBoolean¤ *pUserSaysCancel)
b8bb36 {
f2be41 ¤   DualErr¤¤   derr;
f15845 ¤   PGPBoolean¤ userSaysCancel¤ = FALSE;
3eaf5a
--8025 0003f6690a0401100b3 Page 6 of CPGPdiskAppVolumes.cpp
a3639f ¤   pgpAssertStrValid(path);
387381 ¤   pgpAssertAddrValid(pUserSaysCancel, PGPBoolean);
42af5a
1d939d ¤   if (IsFileReadOnly(path))
16c7a1 ¤   {
75d8dd ¤   ¤   DisplayMessage(kPGPdiskBadCASTReadOnly);
2d9371 ¤   }
d60e24 ¤   else
32c7a1 ¤   {
079e40 ¤   ¤   PGPBoolean¤ ¤   restartingConversion;
a08b5e ¤   ¤   UserResponse¤   response;
00af5a
e7a854 ¤   ¤   // Is this PGPdisk partially converted already?
e8e590 ¤   ¤   restartingConversion = WasPGPdiskConversionInterrupted(path);
c6af5a
248b40 ¤   ¤   if (restartingConversion)
105b34 ¤   ¤   {
438e77 ¤   ¤   ¤   response = DisplayMessage(kPGPdiskBadCASTAskContinuePNM,·
be1b3f ¤   ¤   ¤   ¤   kPMBS_YesNoCancel, kPMBF_YesButton);
e00fe4 ¤   ¤   }
3c0e1d ¤   ¤   else
015b34 ¤   ¤   {
3f27e6 ¤   ¤   ¤   response = DisplayMessage(kPGPdiskBadCASTAskConvertPNM,·
fe1b3f ¤   ¤   ¤   ¤   kPMBS_YesNoCancel, kPMBF_YesButton);
5d0fe4 ¤   ¤   }
92af5a
1d17e4 ¤   ¤   // Do what the user wants in regards to conversion.
d7b65b ¤   ¤   switch (response)
815b34 ¤   ¤   {
20d952 ¤   ¤   ¤   case kUR_Yes:
a672c3 ¤   ¤   ¤   ¤   {
ac82e3 ¤   ¤   ¤   ¤   ¤   CConvertWizardSheet convertPGPdiskSheet;
f2af5a
0f3aae ¤   ¤   ¤   ¤   ¤   derr = convertPGPdiskSheet.mInitErr;
43af5a
e14ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
a04859 ¤   ¤   ¤   ¤   ¤   {
fd63e2 ¤   ¤   ¤   ¤   ¤   ¤   derr = convertPGPdiskSheet.ExecuteWizard(path,·
7e320f ¤   ¤   ¤   ¤   ¤   ¤   ¤   restartingConversion);
881c89 ¤   ¤   ¤   ¤   ¤   }
422613 ¤   ¤   ¤   ¤   }
56f622 ¤   ¤   ¤   ¤   break;
a9af5a
80e022 ¤   ¤   ¤   case kUR_No:
971e18 ¤   ¤   ¤   ¤   derr = kPGDMinorError_UserAbort;
57f622 ¤   ¤   ¤   ¤   break;
8faf5a
2690b7 ¤   ¤   ¤   case kUR_Cancel:
a827fe ¤   ¤   ¤   ¤   userSaysCancel = TRUE;
29f622 ¤   ¤   ¤   ¤   break;
130fe4 ¤   ¤   }
ff9371 ¤   }
06af5a
6bf9bc ¤   (* pUserSaysCancel) = userSaysCancel;
d0af5a
6d33e3 ¤   return derr;
6befe6 }
ffaf5a
b8456b // ConvertPGPdisk attempts to convert a PGPdisk with bad CAST to one
997d14 // with good CAST.
0aaf5a
8e2292 DualErr·
0e700f CPGPdiskApp::ConvertPGPdisk(LPCSTR path)
f4bb36 {
0b7d36 ¤   DualErr derr;
a9af5a
ce639f ¤   pgpAssertStrValid(path);
ceaf5a
17939d ¤   if (IsFileReadOnly(path))
11c7a1 ¤   {
24d8dd ¤   ¤   DisplayMessage(kPGPdiskBadCASTReadOnly);
3f9371 ¤   }
--674d 00010ad3a62401100b3 Page 7 of CPGPdiskAppVolumes.cpp
060e24 ¤   else
c2c7a1 ¤   {
b19e40 ¤   ¤   PGPBoolean¤ ¤   restartingConversion;
ef8b5e ¤   ¤   UserResponse¤   response;
06af5a
e3a854 ¤   ¤   // Is this PGPdisk partially converted already?
16e590 ¤   ¤   restartingConversion = WasPGPdiskConversionInterrupted(path);
a9af5a
578b40 ¤   ¤   if (restartingConversion)
a75b34 ¤   ¤   {
c58e77 ¤   ¤   ¤   response = DisplayMessage(kPGPdiskBadCASTAskContinuePNM,·
c8987d ¤   ¤   ¤   ¤   kPMBS_YesNo, kPMBF_YesButton);
a90fe4 ¤   ¤   }
920e1d ¤   ¤   else
e85b34 ¤   ¤   {
9a27e6 ¤   ¤   ¤   response = DisplayMessage(kPGPdiskBadCASTAskConvertPNM,·
b9987d ¤   ¤   ¤   ¤   kPMBS_YesNo, kPMBF_YesButton);
8b0fe4 ¤   ¤   }
83af5a
8017e4 ¤   ¤   // Do what the user wants in regards to conversion.
05b65b ¤   ¤   switch (response)
415b34 ¤   ¤   {
7dd952 ¤   ¤   ¤   case kUR_Yes:
4e72c3 ¤   ¤   ¤   ¤   {
ba82e3 ¤   ¤   ¤   ¤   ¤   CConvertWizardSheet convertPGPdiskSheet;
0eaf5a
ec3aae ¤   ¤   ¤   ¤   ¤   derr = convertPGPdiskSheet.mInitErr;
dcaf5a
b04ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
6f4859 ¤   ¤   ¤   ¤   ¤   {
4f63e2 ¤   ¤   ¤   ¤   ¤   ¤   derr = convertPGPdiskSheet.ExecuteWizard(path,·
2c320f ¤   ¤   ¤   ¤   ¤   ¤   ¤   restartingConversion);
0d1c89 ¤   ¤   ¤   ¤   ¤   }
c02613 ¤   ¤   ¤   ¤   }
77f622 ¤   ¤   ¤   ¤   break;
8baf5a
0fe022 ¤   ¤   ¤   case kUR_No:
db1e18 ¤   ¤   ¤   ¤   derr = kPGDMinorError_UserAbort;
5ff622 ¤   ¤   ¤   ¤   break;
a70fe4 ¤   ¤   }
ff9371 ¤   }
15af5a
6f33e3 ¤   return derr;
85efe6 }
39af5a
35c63b // CreatePGPdisk asks the user to specify a location for a new PGPdisk and
75ec13 // then displays the wizard.
02af5a
512292 DualErr·
2df261 CPGPdiskApp::CreatePGPdisk(LPCSTR defaultPath)
d5bb36 {
724b91 ¤   CDiskWizardSheet¤   newPGPdiskWizard;
55705b ¤   DualErr¤¤   ¤   ¤   derr;
f536c6 ¤   PGPBoolean¤ ¤   ¤   wasMainEnabled;
c5af5a
db7bba ¤   // Forcibly disable main window so it doesn't flicker between dialogs.
a4023f ¤   if (mMainDialog)
a4e14e ¤   ¤   wasMainEnabled = !mMainDialog->EnableWindow(FALSE);
3baf5a
ed3eec ¤   // Did our wizard initialize correctly?
e8dbec ¤   derr = newPGPdiskWizard.mInitErr;
22af5a
98c4ca ¤   // Any drive letters free?
fd2361 ¤   if (derr.IsntError())
fec7a1 ¤   {
6893da ¤   ¤   if (!AreAnyDriveLettersFree())
345b34 ¤   ¤   {
723cd2 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_NoDriveLettersFree);
840fe4 ¤   ¤   }
339371 ¤   }
fbaf5a
102321 ¤   // Fire up the wizard.
--56ab 000219a67e4401100b3 Page 8 of CPGPdiskAppVolumes.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
7ab2cd ¤   ¤   derr = newPGPdiskWizard.ExecuteWizard(defaultPath);
ad9371 ¤   }
61af5a
5d2488 ¤   // Re-enable main dialog if it was disabled.
c8e85a ¤   if (mMainDialog && wasMainEnabled)
3035a5 ¤   ¤   mMainDialog->EnableWindow(TRUE);
d5af5a
d333e3 ¤   return derr;
16efe6 }
aeaf5a
dddd76 // MountPGPdisk first determines if we can mount the PGPdisk specified by
7ce1ad // 'path', and then creates an associated PGPdisk object and asks it to mount
808c08 // itself.
afaf5a
7b2292 DualErr·
e772df CPGPdiskApp::MountPGPdisk(
9e20cd ¤   LPCSTR¤ ¤   ¤   path,·
9437f3 ¤   PGPBoolean¤ ¤   forceReadOnly,·
c2af26 ¤   PGPBoolean¤ ¤   useDialog,·
9a604f ¤   PGPBoolean¤ ¤   needMaster,·
64f4ef ¤   PGPUInt8¤   ¤   drive,·
62b9c0 ¤   SecureString¤   *passphrase)
7abb36 {
77298c ¤   CSinglePassphraseDialog¤mountPassDlg(kSPDT_Mount);
fe9f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
f0d3f9 ¤   PGPBoolean¤ ¤   ¤   ¤   createdPGPdiskObject¤   = FALSE;
a382dc ¤   PGPdisk¤¤   ¤   ¤   ¤   *pPGD;
73af5a
f206c6 ¤   if (useDialog)
0ec7a1 ¤   {
a97c94 ¤   ¤   // Make sure our passphrase dialog initialized correctly.
b26314 ¤   ¤   derr = mountPassDlg.mInitErr;
0d9371 ¤   }
ad0e24 ¤   else
86c7a1 ¤   {
9493d3 ¤   ¤   pgpAssert(IsLegalDriveNumber(drive));
986ff3 ¤   ¤   pgpAssertAddrValid(passphrase, SecureString);
c69371 ¤   }
f6af5a
148c26 ¤   // If the PGPdisk file is mounted already, show its window.
052361 ¤   if (derr.IsntError())
12c7a1 ¤   {
ee619b ¤   ¤   pPGD = mPGPdisks.FindPGPdisk(path);
a4af5a
525306 ¤   ¤   if (IsntNull(pPGD))
245b34 ¤   ¤   {
64c3db ¤   ¤   ¤   pPGD->BrowseToVolume();
3a0710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
b80fe4 ¤   ¤   }
c89371 ¤   }
9eaf5a
628730 ¤   // Validate the PGPdisk.
612361 ¤   if (derr.IsntError())
fcc7a1 ¤   {
f66d28 ¤   ¤   derr = ValidatePGPdisk(path);
629371 ¤   }
cdaf5a
4cc89f ¤   // If the PGPdisk is opened by someone else with write access, fail.
552361 ¤   if (derr.IsntError())
5dc7a1 ¤   {
14bc8f ¤   ¤   if (IsFileInUseByWriter(path))
42f979 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskAlreadyInUse);
1b9371 ¤   }
02af5a
64c4ca ¤   // Any drive letters free?
e62361 ¤   if (derr.IsntError())
5ec7a1 ¤   {
ef93da ¤   ¤   if (!AreAnyDriveLettersFree())
e45b34 ¤   ¤   {
213cd2 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_NoDriveLettersFree);
--9eee 0005a791abd401100b3 Page 9 of CPGPdiskAppVolumes.cpp
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
23e7eb ¤   // Check if there is room to mount another volume.
df2361 ¤   if (derr.IsntError())
1dc7a1 ¤   {
6746d2 ¤   ¤   if (mPGPdisks.GetNumPGPdisks() >= kMaxMountedPGPdisks)
480c9a ¤   ¤   ¤   derr = DualErr(kPGDMinorError_MaxPGPdisksMounted);
2a9371 ¤   }
37af5a
ae9296 ¤   // Create a new PGPdisk object.
d12361 ¤   if (derr.IsntError())
26c7a1 ¤   {
a441f1 ¤   ¤   try
a45b34 ¤   ¤   {
6f9aa2 ¤   ¤   ¤   pPGD = new PGPdisk();
fc0fe4 ¤   ¤   }
fd01e0 ¤   ¤   catch (CMemoryException *ex)
6a5b34 ¤   ¤   {
5bb95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
59ad69 ¤   ¤   ¤   ex->Delete();
f40fe4 ¤   ¤   }
0caf5a
d24bb0 ¤   ¤   createdPGPdiskObject = derr.IsntError();
7f9371 ¤   }
39af5a
f92361 ¤   if (derr.IsntError())
21c7a1 ¤   {
81a7af ¤   ¤   derr = pPGD->mInitErr;
049371 ¤   }
7aaf5a
bac00a ¤   // Get the passphrase.
850bd6 ¤   if (derr.IsntError() && useDialog)
59c7a1 ¤   {
0b00bd ¤   ¤   derr = mountPassDlg.AskForPassphrase(path, forceReadOnly, needMaster);
b49371 ¤   }
feaf5a
d32361 ¤   if (derr.IsntError())
8dc7a1 ¤   {
fdff9b ¤   ¤   // If the PGPdisk is marked as being mounted, warn.
199fd9 ¤   ¤   if (GetPGPdiskMountedFlag(path))
deb30a ¤   ¤   ¤   DisplayMessage(kPGPdiskNotifyMountMaybeCorrupt);
7daf5a
54f061 ¤   ¤   // Attempt the actual mount.
db3d2f ¤   ¤   if (useDialog)
905b34 ¤   ¤   {
d18d4d ¤   ¤   ¤   passphrase = mountPassDlg.mPassphraseEdit.mContents;
5a6645 ¤   ¤   ¤   drive = mountPassDlg.mDriveCombo.mDriveNumber;
c7af5a
3c7b14 ¤   ¤   ¤   if (!forceReadOnly)
9c5ae2 ¤   ¤   ¤   ¤   forceReadOnly = mountPassDlg.mReadOnlyValue;
e90fe4 ¤   ¤   }
3eaf5a
307c6f ¤   ¤   derr = pPGD->Mount(path, passphrase, drive, forceReadOnly);
de9371 ¤   }
96af5a
54c591 #if PGPDISK_DEMOVERSION
51af5a
c02361 ¤   if (derr.IsntError())
01c7a1 ¤   {
3da5be ¤   ¤   // Set demo timeout after (first) successful mount.
ed7132 ¤   ¤   SetPGPdiskDemoTimeout();
af9371 ¤   }
f5af5a
28aa65 #endif // PGPDISK_DEMOVERSION
09af5a
7b2361 ¤   if (derr.IsntError())
8ec7a1 ¤   {
2b292f ¤   ¤   CString dir;
82af5a
b49e31 ¤   ¤   // Add the PGPdisk to the global list.
5a0510 ¤   ¤   mPGPdisks.AddPGPdisk(pPGD);
--24a9 0009576fe75401100b3 Page 10 of CPGPdiskAppVolumes.cpp
e0af5a
73f86c ¤   ¤   // Update the last used directory registy key.
ee132f ¤   ¤   GetDirectory(path, &dir);
109d52 ¤   ¤   PGPdiskSetPrefString(kRegistryLastOpenDirKey, dir);
38af5a
b6b37e ¤   ¤   // If not formatted, offer user chance to format.
7ac15c ¤   ¤   if (useDialog && !IsVolumeFormatted(pPGD->GetDrive()))
fa5b34 ¤   ¤   {
e511cd ¤   ¤   ¤   UserResponse button;
2aaf5a
54bb34 ¤   ¤   ¤   button = DisplayMessage(kPGPdiskConfirmFormat, kPMBS_YesNo,·
e47eae ¤   ¤   ¤   ¤   kPMBF_YesButton);
60af5a
13e400 ¤   ¤   ¤   if (button == kUR_Yes)
e6b265 ¤   ¤   ¤   ¤   pPGD->HighLevelFormatPGPdisk();
fb0fe4 ¤   ¤   }
d69371 ¤   }
e9af5a
3bb877 ¤   // Cleanup if error.
0f4bb3 ¤   if (derr.IsError())
08c7a1 ¤   {
b33545 ¤   ¤   if (createdPGPdiskObject)
355b34 ¤   ¤   {
924a02 ¤   ¤   ¤   delete pPGD;
e00fe4 ¤   ¤   }
6e9371 ¤   }
6267c5 ¤
4733e3 ¤   return derr;
00efe6 }
abaf5a
1fb2ef // UnmountPGPdisk unmounts the specified PGPdisk volume.
d4af5a
992292 DualErr·
7d1ad3 CPGPdiskApp::UnmountPGPdisk(PGPUInt8 drive, PGPBoolean isThisEmergency)
fbbb36 {
7a75c5 ¤   DualErr¤¤   afterFact, derr;
107d26 ¤   PGPBoolean¤ removedPGPdisk, unmountedChildren;
51c303 ¤   PGPUInt32¤  i¤  = 0;
7370f5 ¤   PGPdisk¤¤   *pPGD;
93af5a
0c4299 ¤   removedPGPdisk = unmountedChildren = FALSE;
aaaf5a
a8aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
f7af5a
be5d0d ¤   // Find the associated PGPdisk object.
236f9b ¤   pPGD = mPGPdisks.FindPGPdisk(drive);
66af5a
48ae1d ¤   if (IsNull(pPGD))
1b5039 ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskNotMounted);
49af5a
4af94f ¤   // If this PGPdisk has other PGPdisks mounted on it, we must perform a
7fd34f ¤   // depth-first unmount of all those PGPdisks first.
73af5a
60f3ae ¤   while (derr.IsntError())
53c7a1 ¤   {
7130c1 ¤   ¤   PGPdisk *pClient;
41af5a
77e134 ¤   ¤   pClient = mPGPdisks.EnumPGPdisks(i++);
e6af5a
23fc13 ¤   ¤   if (IsNull(pClient))
cccdcb ¤   ¤   ¤   break;
c9af5a
68c61d ¤   ¤   if (!pClient->IsHostNetworked() &&·
c0875d ¤   ¤   ¤   (pClient->GetLocalHostDrive() == drive))
285b34 ¤   ¤   {
d47c75 ¤   ¤   ¤   i = 0;
11ac6c ¤   ¤   ¤   derr = UnmountPGPdisk(pClient->GetDrive(), isThisEmergency);
95af5a
ae1927 ¤   ¤   ¤   if (isThisEmergency)
2ca601 ¤   ¤   ¤   ¤   derr = DualErr::NoError;
15af5a
950081 ¤   ¤   ¤   unmountedChildren = derr.IsntError();
--f20e 00003721b97401100b3 Page 11 of CPGPdiskAppVolumes.cpp
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
6606c3 ¤   // Check if the PGPdisk has open files.
632361 ¤   if (derr.IsntError())
83c7a1 ¤   {
106861 ¤   ¤   // If we unmounted any children, we may have to wait a little while
d0e43f ¤   ¤   // for the system to flush its cache. Try about 10 times.
0eaf5a
793022 ¤   ¤   if (unmountedChildren)
6d5b34 ¤   ¤   {
3d7c75 ¤   ¤   ¤   i = 0;
93af5a
87bf7d ¤   ¤   ¤   while (pPGD->HasOpenFiles() && (i++ < kMaxCheckOpenFilesAttempts))
091754 ¤   ¤   ¤   ¤   Sleep(500);
be0fe4 ¤   ¤   }
e9af5a
7dcab7 ¤   ¤   if (pPGD->HasOpenFiles())
11ad7c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FilesOpenOnDrive);
1aaf5a
e4a271 ¤   ¤   if (isThisEmergency)
cfa3ec ¤   ¤   ¤   derr = DualErr::NoError;
cb9371 ¤   }
c8af5a
614660 ¤   // Now we are safe to unmount. Remove it from the global list and unmount.
9e2361 ¤   if (derr.IsntError())
eac7a1 ¤   {
1717c3 ¤   ¤   mPGPdisks.RemovePGPdisk(pPGD);
b3b47f ¤   ¤   removedPGPdisk = TRUE;
16af5a
32040c ¤   ¤   derr = pPGD->Unmount(isThisEmergency);
7caf5a
ada271 ¤   ¤   if (isThisEmergency)
f6a3ec ¤   ¤   ¤   derr = DualErr::NoError;
f69371 ¤   }
47af5a
424f0c ¤   // Delete the PGPdisk object.
622361 ¤   if (derr.IsntError())
f8c7a1 ¤   {
e5fbd3 ¤   ¤   delete pPGD;
f59371 ¤   }
b0af5a
61b877 ¤   // Cleanup if error.
b44bb3 ¤   if (derr.IsError())
0bc7a1 ¤   {
70f1d6 ¤   ¤   if (removedPGPdisk && pPGD->Mounted())
75c045 ¤   ¤   ¤   mPGPdisks.AddPGPdisk(pPGD);
bd9371 ¤   }
8aaf5a
b033e3 ¤   return derr;
cfefe6 }
d7af5a
f38e5d // UnmountAllPGPdisks unmounts all mounted PGPdisks on the system.
58af5a
952292 DualErr·
a6f87b CPGPdiskApp::UnmountAllPGPdisks(PGPBoolean isThisEmergency)
48bb36 {
b7d5ab ¤   DualErr¤¤   derr, storedDerr;
40c303 ¤   PGPUInt32¤  i¤  = 0;
0770f5 ¤   PGPdisk¤¤   *pPGD;
edaf5a
1710ca ¤   // Note how we enumerate on position 0, and increase this only when we
e78730 ¤   // find a drive we can't unmount for whatever reason. This is because
ff18a5 ¤   // if a drive can't be unmounted it won't be removed, and thus 'sticks'
ab86ea ¤   // at position 0, 1, etc.
55af5a
c73dbb ¤   pPGD = mPGPdisks.EnumPGPdisks(i);
65af5a
e79c02 ¤   while (IsntNull(pPGD))
21c7a1 ¤   {
c4c848 ¤   ¤   PGPUInt8 drive;
03af5a
--e6ba 0011bdb5096401100b3 Page 12 of CPGPdiskAppVolumes.cpp
27132e ¤   ¤   pgpAssert(pPGD->Mounted());
f796ff ¤   ¤   drive = pPGD->GetDrive();
a3af5a
210812 ¤   ¤   // Now attempt the unmount.
fffe6b ¤   ¤   derr = UnmountPGPdisk(drive, isThisEmergency);
66af5a
75a271 ¤   ¤   if (isThisEmergency)
fca3ec ¤   ¤   ¤   derr = DualErr::NoError;
5aaf5a
391016 ¤   ¤   // If there is an error, note that we saw an error and continue
060adb ¤   ¤   // unmounting.
40af5a
83bdd6 ¤   ¤   if (derr.IsError())
e75b34 ¤   ¤   {
2eff83 ¤   ¤   ¤   if (storedDerr.IsntError())
0dd099 ¤   ¤   ¤   ¤   storedDerr = derr;
16af5a
aaa3ec ¤   ¤   ¤   derr = DualErr::NoError;
b281ec ¤   ¤   ¤   i++;
390fe4 ¤   ¤   }
d3af5a
e90155 ¤   ¤   pPGD = mPGPdisks.EnumPGPdisks(i);
de9371 ¤   }
4daf5a
95c19e ¤   return storedDerr;
1befe6 }
--61e2 0011f770557401100b4 Page 1 of CPGPdiskAppVolumes.h
541bc3 //////////////////////////////////////////////////////////////////////////////
9c080f // CPGPdiskAppVolumes.h
2a465d //
58b2b3 // Contains declarations for CPGPdiskAppVolumes.cpp.
461bc3 //////////////////////////////////////////////////////////////////////////////
57af5a
bc7934 // $Id: CPGPdiskAppVolumes.h,v 1.1.2.3 1998/07/06 08:57:09 nryan Exp $
f8af5a
d4cbce // Copyright (C) 1998 by Network Associates, Inc.
4c71ae // All rights reserved.
e4af5a
9dca3f #ifndef Included_CPGPdiskAppVolumes_h¤  // [
f6232e #define Included_CPGPdiskAppVolumes_h
39af5a
a81cb9 // Nothing needed here.
68af5a
1fc111 #endif¤ // ] Included_CPGPdiskAppVolumes_h
--32c0 00097beaabb401100b5 Page 1 of CPGPdiskAppWinutils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
fd477c // CPGPdiskAppWinutils.cpp
ca465d //
25c7c0 // Wrapper functions around useful system calls.
d21bc3 //////////////////////////////////////////////////////////////////////////////
c1af5a
81868a // $Id: CPGPdiskAppWinutils.cpp,v 1.2.2.29 1998/08/12 01:50:28 nryan Exp $
a5af5a
1bcbce // Copyright (C) 1998 by Network Associates, Inc.
4171ae // All rights reserved.
69af5a
429e12 #include "StdAfx.h"
5eaf5a
809bcf #include "Required.h"
c5ac00 #include "DriverComm.h"
4dbabe #include "PGPdiskRegistry.h"
3a5788 #include "PGPdiskVersion.h"
12993c #include "StringAssociation.h"
0ebfe9 #include "UtilityFunctions.h"
1f6560 #include "Win32Utils.h"
2faf5a
883646 #include "CMainDialog.h"
005e8f #include "CPGPdiskApp.h"
205590 #include "CPGPdiskAppWinutils.h"
4ec411 #include "Globals.h"
3b68c6 #include "PGPdisk.h"
e1ab81 #include "Resource.h"
11af5a
35af5a
ed09b7 ////////////
b5e738 // Constants
fe09b7 ////////////
caaf5a
fe317f const¤  PGPUInt32¤  kRegTextInc¤¤   = 16;
438752 const¤  PGPUInt32¤  kLicenseToGap¤  = 8;
88af5a
fbaf5a
49fc6a ////////////////////////////////////
47e491 // File and Volume Utility Functions
6ffc6a ////////////////////////////////////
81af5a
2879cd // AreAnyDriveLettersFree returns TRUE if there are any drive letters free
6bbea9 // for mounting PGPdisks, otherwise FALSE.
c8af5a
676d0e ¤   PGPBoolean·
6b9ea3 CPGPdiskApp::AreAnyDriveLettersFree()
26bb36 {
898eda ¤   PGPUInt32 drives = GetLogicalDrives();
8faf5a
aed0a5 ¤   // Mask off drives A and B and anything over Z.
75614c ¤   return ((drives &= 0x3FFFFFC) != 0x3FFFFFC);
4eefe6 }
c6af5a
0100c6 // IsDirectoryValid returns TRUE if the specified directory exists, FALSE
d54da2 // otherwise.
73af5a
6b77be PGPBoolean·
fafaa3 CPGPdiskApp::IsDirectoryValid(LPCSTR path)
b6bb36 {
d8bc6b ¤   PGPUInt32 attribs;
a0af5a
e9639f ¤   pgpAssertStrValid(path);
54af5a
7131f9 ¤   attribs = GetFileAttributes(path);
28af5a
08b78a ¤   if (attribs == 0xFFFFFFFF)
cf98aa ¤   ¤   return FALSE;
b90e24 ¤   else
ff5119 ¤   ¤   return (attribs & FILE_ATTRIBUTE_DIRECTORY ? TRUE : FALSE);
44efe6 }
4eaf5a
9775a5 // IsFileValid returns TRUE if the specified file exists, FALSE otherwise.
--a313 000096fea8c401100b5 Page 2 of CPGPdiskAppWinutils.cpp
e0af5a
6077be PGPBoolean·
02e122 CPGPdiskApp::IsFileValid(LPCSTR path)
22bb36 {
08bc6b ¤   PGPUInt32 attribs;
daaf5a
3f639f ¤   pgpAssertStrValid(path);
9caf5a
da31f9 ¤   attribs = GetFileAttributes(path);
6daf5a
7fb78a ¤   if (attribs == 0xFFFFFFFF)
d398aa ¤   ¤   return FALSE;
410e24 ¤   else
b441ca ¤   ¤   return (attribs & FILE_ATTRIBUTE_DIRECTORY ? FALSE : TRUE);
75efe6 }
2caf5a
93a109 // IsPathValid returns TRUE if the specified path exists, FALSE otherwise.
eeaf5a
4777be PGPBoolean·
26de6b CPGPdiskApp::IsPathValid(LPCSTR path)
a8bb36 {
8108a5 ¤   return (IsFileValid(path) || IsDirectoryValid(path));
2aefe6 }
14af5a
7a54aa // IsVolumeValid returns TRUE if the specified volume is valid, FALSE
b04da2 // otherwise.
48af5a
6c77be PGPBoolean·
8436b0 CPGPdiskApp::IsVolumeValid(PGPUInt8 drive)
e6bb36 {
24862b ¤   CString root;
5aaf5a
ecaa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
c5af5a
0b1033 ¤   return ((GetLogicalDrives() & (1 << drive)) ? TRUE : FALSE);
dfefe6 }
8eaf5a
d32396 // IsVolumeFormatted returns TRUE if the specified volume is formatted, FALSE
f54da2 // otherwise.
cdaf5a
9877be PGPBoolean·
d1f721 CPGPdiskApp::IsVolumeFormatted(PGPUInt8 drive)
4cbb36 {
00862b ¤   CString root;
f1af5a
bbaa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
26af5a
d95b19 ¤   if (MakeRoot(drive, &root).IsntError())
d3c7a1 ¤   {
33b010 ¤   ¤   return GetVolumeInformation(root, NULL, 0, NULL, NULL, NULL, NULL, 0);
9d9371 ¤   }
410e24 ¤   else
88c7a1 ¤   {
64836c ¤   ¤   return TRUE;
3a9371 ¤   }
afefe6 }
65af5a
01d5e7 // IsDirectoryReadOnly returns TRUE if the directory specified by path is
97302c // read-only, FALSE otherwise.
b3af5a
3577be PGPBoolean·
abf3d4 CPGPdiskApp::IsDirectoryReadOnly(LPCSTR path)
97bb36 {
c006b3 ¤   CString¤¤   dir, csPath, temp;
b5be41 ¤   DualErr¤¤   derr;
fc6468 ¤   PGPBoolean¤ isDirReadOnly;
41f7e2 ¤   PGPUInt32¤  result;
5caf5a
b7639f ¤   pgpAssertStrValid(path);
eeaf5a
b62469 ¤   // Attempt to create a temporary file.
0978f1 ¤   try
--11b5 0007e3ec93e401100b5 Page 3 of CPGPdiskAppWinutils.cpp
f7c7a1 ¤   {
648a75 ¤   ¤   csPath = path;
afe138 ¤   ¤   dir = csPath.Left(csPath.ReverseFind('\\') + 1);
f4af5a
5e6ad2 ¤   ¤   result = GetTempFileName(dir, "pgp", 0,·
bebb83 ¤   ¤   ¤   temp.GetBuffer(kMaxStringSize));
54af5a
b7e62c ¤   ¤   temp.ReleaseBuffer();
c69371 ¤   }
273c88 ¤   catch (CMemoryException *ex)
9ec7a1 ¤   {
0eecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
1b6adc ¤   ¤   ex->Delete();
ab9371 ¤   }
0baf5a
6ded88 ¤   // If failure, we assume read-only.
032361 ¤   if (derr.IsntError())
c2c7a1 ¤   {
c0789f ¤   ¤   if (result == 0)
0b5b34 ¤   ¤   {
60949d ¤   ¤   ¤   isDirReadOnly = TRUE;
880fe4 ¤   ¤   }
b80e1d ¤   ¤   else
ea5b34 ¤   ¤   {
c97ebb ¤   ¤   ¤   isDirReadOnly = FALSE;
427832 ¤   ¤   ¤   DeleteFile(temp);
f40fe4 ¤   ¤   }
219371 ¤   }
55af5a
bb2361 ¤   if (derr.IsntError())
914abd ¤   ¤   return isDirReadOnly;
c90e24 ¤   else
5a836c ¤   ¤   return TRUE;
93efe6 }
f2af5a
870f73 // IsFileReadOnly returns TRUE if the file specified by path is read-only,
b39a91 // FALSE otherwise.
67af5a
4877be PGPBoolean·
cdd4dd CPGPdiskApp::IsFileReadOnly(LPCSTR path)
11bb36 {
c7be41 ¤   DualErr¤¤   derr;
fdd9a8 ¤   File¤   ¤   theFile;
09585a ¤   PGPUInt8¤   firstByte¤  = 0;
345bab ¤   PGPUInt64¤  length;
c1af5a
6f976e ¤   // Open a read/write handle to the file and try to write a byte. If
02cb81 ¤   // anything fails, we aren't going to be doing any writing. Handle
5e49d9 ¤   // 0-length files as a special case.
a0af5a
efab17 ¤   derr = theFile.Open(path, kOF_MustExist);
40af5a
e32361 ¤   if (derr.IsntError())
8bc7a1 ¤   {
69fb61 ¤   ¤   derr = theFile.GetLength(&length);
9b9371 ¤   }
b8af5a
7d2361 ¤   if (derr.IsntError())
adc7a1 ¤   {
a1e866 ¤   ¤   if (length > 0)
fa1f9e ¤   ¤   ¤   derr = theFile.Read((PGPUInt8 *) &firstByte, 0, 1);
f29371 ¤   }
18af5a
762361 ¤   if (derr.IsntError())
dcc7a1 ¤   {
6b5d52 ¤   ¤   derr = theFile.Write((PGPUInt8 *) &firstByte, 0, 1);
939371 ¤   }
ffaf5a
1a2361 ¤   if (derr.IsntError())
f8c7a1 ¤   {
dfbeba ¤   ¤   if (length == 0)
7e8ae6 ¤   ¤   ¤   theFile.SetLength(0);
--8cc5 000ebc6af6e401100b5 Page 4 of CPGPdiskAppWinutils.cpp
a19371 ¤   }
93af5a
7de74a ¤   if (theFile.Opened())
205b94 ¤   ¤   theFile.Close();
75af5a
cc8864 ¤   return derr.IsError();
9defe6 }
94af5a
2d0bc9 // IsFileInUseByReader returns TRUE if someone has opened the specified file
59476d // with read access, FALSE otherwise.
c2af5a
9077be PGPBoolean·
4a6ce0 CPGPdiskApp::IsFileInUseByReader(LPCSTR path)
acbb36 {
58fec2 ¤   File¤   existingFile;
c4945d ¤   DualErr¤derr;
2caf5a
99639f ¤   pgpAssertStrValid(path);
64af5a
d3862d ¤   derr = existingFile.Open(path,·
2f71ac ¤   ¤   kOF_ReadOnly | kOF_DenyRead | kOF_MustExist);
ebaf5a
4812c1 ¤   if (existingFile.Opened())
eec7a1 ¤   {
1c1af7 ¤   ¤   existingFile.Close();
3c9371 ¤   }
16af5a
788864 ¤   return derr.IsError();
f6efe6 }
acaf5a
3a2939 // IsFileInUseByWriter returns TRUE if someone has opened the specified file
30ad9f // with write access, FALSE otherwise.
b9af5a
9377be PGPBoolean·
cbbdb6 CPGPdiskApp::IsFileInUseByWriter(LPCSTR path)
15bb36 {
b0fec2 ¤   File¤   existingFile;
8e945d ¤   DualErr¤derr;
9faf5a
e7639f ¤   pgpAssertStrValid(path);
54af5a
a9862d ¤   derr = existingFile.Open(path,·
d55c1e ¤   ¤   kOF_ReadOnly | kOF_DenyWrite | kOF_MustExist);
03af5a
9712c1 ¤   if (existingFile.Opened())
8ec7a1 ¤   {
c91af7 ¤   ¤   existingFile.Close();
949371 ¤   }
07af5a
e68864 ¤   return derr.IsError();
2aefe6 }
9eaf5a
f674d2 // IsFileInUseByWriter returns TRUE if someone has opened the specified file,
999a91 // FALSE otherwise.
79af5a
6777be PGPBoolean·
afe630 CPGPdiskApp::IsFileInUse(LPCSTR path)
28bb36 {
76807e ¤   return (IsFileInUseByReader(path) || IsFileInUseByWriter(path));
70efe6 }
19af5a
cf5e82 // BruteForceTestIfEnoughSpace tests if the desired directory has enough
8f870a // space to hold a file of the specified size. It does this by creating a
2b65a6 // temporary file of the desired size.
9daf5a
305828 DualErr ¤   ¤
66e32f CPGPdiskApp::BruteForceTestIfEnoughSpace(
37ea85 ¤   LPCSTR¤ ¤   dir,·
8f18f1 ¤   PGPUInt32¤  kbLength,·
975757 ¤   PGPBoolean¤ *isEnoughSpace)
7cbb36 {
eb7d36 ¤   DualErr derr;
--508e 000f719ac73401100b5 Page 5 of CPGPdiskAppWinutils.cpp
e0af5a
1f78f1 ¤   try
dcc7a1 ¤   {
7cfa20 ¤   ¤   File¤   ¤   tempFile;
9cd801 ¤   ¤   CString¤¤   tempPath;
b3897b ¤   ¤   DualErr¤¤   setLengthErr;
8b6889 ¤   ¤   PGPBoolean¤ createdTemp¤= FALSE;
e4470c ¤   ¤   PGPUInt64¤  tempSize;
deaf5a
dcad13 ¤   ¤   pgpAssertStrValid(dir);
5f93ab ¤   ¤   pgpAssertAddrValid(isEnoughSpace, PGPBoolean);
acaf5a
4fd02b ¤   ¤   // Open a temporary file in the desired directory.
322420 ¤   ¤   GetTempFileName(dir, "pgp", 0, tempPath.GetBuffer(kMaxStringSize));
43a2c8 ¤   ¤   tempPath.ReleaseBuffer();
f8af5a
4b55a5 ¤   ¤   derr = tempFile.Open(tempPath, kOF_Trunc);
b62074 ¤   ¤   createdTemp = derr.IsntError();
17af5a
fb16a6 ¤   ¤   // Set the file to the desired length.
9caa35 ¤   ¤   if (derr.IsntError())
7d5b34 ¤   ¤   {
2d22d5 ¤   ¤   ¤   setLengthErr = tempFile.SetLength(kbLength * kBytesPerKb);
c7af5a
2175fc ¤   ¤   ¤   // Did we fail to set the size of the file?
a9d4dd ¤   ¤   ¤   if (setLengthErr.IsError())
87f776 ¤   ¤   ¤   {
146267 ¤   ¤   ¤   ¤   (* isEnoughSpace) = FALSE;
6aa3a6 ¤   ¤   ¤   }
b00fe4 ¤   ¤   }
59af5a
74a3c5 ¤   ¤   // Verify the set succeeded by closing and re-opening the file.
f3a064 ¤   ¤   if (derr.IsntError() && setLengthErr.IsntError())
685b34 ¤   ¤   {
82897e ¤   ¤   ¤   tempFile.Close();
34b8d9 ¤   ¤   ¤   derr = tempFile.Open(tempPath, kOF_MustExist);
910fe4 ¤   ¤   }
f1af5a
baa064 ¤   ¤   if (derr.IsntError() && setLengthErr.IsntError())
0a5b34 ¤   ¤   {
930558 ¤   ¤   ¤   derr = tempFile.GetLength(&tempSize);
7c0fe4 ¤   ¤   }
7caf5a
a4ad6c ¤   ¤   // Do the sizes match?
f1a064 ¤   ¤   if (derr.IsntError() && setLengthErr.IsntError())
745b34 ¤   ¤   {
84aa6f ¤   ¤   ¤   (* isEnoughSpace) = (tempSize == kbLength*kBytesPerKb);
030fe4 ¤   ¤   }
3daf5a
2b3d68 ¤   ¤   if (tempFile.Opened())
0e5b34 ¤   ¤   {
fb897e ¤   ¤   ¤   tempFile.Close();
a90fe4 ¤   ¤   }
f4af5a
2db279 ¤   ¤   if (createdTemp)
775b34 ¤   ¤   {
e66086 ¤   ¤   ¤   DeleteFile(tempPath);
a20fe4 ¤   ¤   }
d29371 ¤   }
f23c88 ¤   catch (CMemoryException *ex)
e2c7a1 ¤   {
4c6adc ¤   ¤   ex->Delete();
1becf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
ec9371 ¤   }
edaf5a
3133e3 ¤   return derr;
12efe6 }
21af5a
7f9054 // HowMuchFreeSpace returns the amount of free space on the specified drive,
0ec0a3 // in bytes.
50af5a
f72292 DualErr·
--2508 00003c25172401100b5 Page 6 of CPGPdiskAppWinutils.cpp
d529e4 CPGPdiskApp::HowMuchFreeSpace(LPCSTR path, PGPUInt64 *bytesFree)
06bb36 {
f8861e ¤   CString¤¤   ¤   root;
bb9a95 ¤   DualErr¤¤   ¤   derr;
a67914 ¤   ULARGE_INTEGER¤ freeAvail;
faaf5a
e6fe29 ¤   pgpAssertAddrValid(bytesFree, PGPUInt64);
3daf5a
d9d9d6 ¤   // We must pass the root, not the path, to the system.
70f1ff ¤   derr = GetRoot(path, &root);
dcaf5a
6b7dbc ¤   // There are two different functions for OSR1 and OSR2.
922361 ¤   if (derr.IsntError())
e3c7a1 ¤   {
052f0c ¤   ¤   if (IsWin95OSR2CompatibleMachine() || IsWinNT4CompatibleMachine())
3c5b34 ¤   ¤   {
1a1762 ¤   ¤   ¤   PGPUInt32¤  ¤   result;
95798a ¤   ¤   ¤   ULARGE_INTEGER¤ freeBytes, totalBytes;
65af5a
99bed5 ¤   ¤   ¤   result = GetDiskFreeSpaceEx(root, &freeAvail, &totalBytes,·
3b2446 ¤   ¤   ¤   ¤   &freeBytes);
20af5a
31c6c3 ¤   ¤   ¤   if (!result)
f5f776 ¤   ¤   ¤   {
6c84bf ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetFreeSpaceFailed,·
743177 ¤   ¤   ¤   ¤   ¤   GetLastError());
28a3a6 ¤   ¤   ¤   }
5b0fe4 ¤   ¤   }
830e1d ¤   ¤   else
4d5b34 ¤   ¤   {
a0985f ¤   ¤   ¤   unsigned long spc, bps, freeClust, totalClust;
baaf5a
19072c ¤   ¤   ¤   if (!::GetDiskFreeSpace(root, &spc, &bps, &freeClust,·
8d7b54 ¤   ¤   ¤   ¤   &totalClust))
6cf776 ¤   ¤   ¤   {
3baf5a
e184bf ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetFreeSpaceFailed,·
9b3177 ¤   ¤   ¤   ¤   ¤   GetLastError());
aaa3a6 ¤   ¤   ¤   }
d6af5a
469d3d ¤   ¤   ¤   if (derr.IsntError())
70f776 ¤   ¤   ¤   {
58a880 ¤   ¤   ¤   ¤   freeAvail.QuadPart = (bps*spc*freeClust);
68a3a6 ¤   ¤   ¤   }
ed0fe4 ¤   ¤   }
2a9371 ¤   }
48af5a
712361 ¤   if (derr.IsntError())
17c7a1 ¤   {
e8dfcb ¤   ¤   (* bytesFree) = freeAvail.QuadPart;
f09371 ¤   }
e0af5a
9833e3 ¤   return derr;
b0efe6 }
14af5a
b090ba // ExceptionFilter determines whether to handle the Windows exception passed
cbe75c // to it.
9baf5a
444d2f int
d856f1 CPGPdiskApp::ExceptionFilter(int exception)
ccbb36 {
ad0458 ¤   switch (exception)
08c7a1 ¤   {
3a0a66 ¤   case STATUS_BREAKPOINT:
f5fb6c ¤   case STATUS_DATATYPE_MISALIGNMENT:
80d8e7 ¤   case STATUS_SINGLE_STEP:
0ee5ac ¤   ¤   return EXCEPTION_CONTINUE_SEARCH;
a8af5a
2c2f72 ¤   default:
aa1b03 ¤   ¤   return EXCEPTION_EXECUTE_HANDLER;
029371 ¤   }
03efe6 }
--2726 00026aaebe9401100b5 Page 7 of CPGPdiskAppWinutils.cpp
e0af5a
b1622a // ShowWindowsFormatDialog brings up the Windows formatting dialog for the
db7929 // specified drive letter.
d1af5a
cc2292 DualErr·
d55904 CPGPdiskApp::ShowWindowsFormatDialog(PGPUInt8 drive)
1abb36 {
49be41 ¤   DualErr¤¤   derr;
ba64b6 ¤   HINSTANCE¤  shell32Handle;
73549e ¤   PGPBoolean¤ loadedShell32¤  = FALSE;
9265ab ¤   PVOID¤  ¤   SHFormatDriveFunc;
84af5a
433703 ¤   pgpAssert(IsWin95CompatibleMachine() || IsWinNT4CompatibleMachine());
44af5a
f75fe5 ¤   // Open handle to shell32.dll
5c158f ¤   shell32Handle = LoadLibrary("shell32.dll");
761d88 ¤   loadedShell32 = IsntNull(shell32Handle);
36af5a
dde94d ¤   if (!loadedShell32)
619759 ¤   ¤   derr = DualErr(kPGDMinorError_LoadLibraryFailed, GetLastError());
86af5a
847416 ¤   // Get procedure address for the formatting function.
222361 ¤   if (derr.IsntError())
65c7a1 ¤   {
5b6ca1 ¤   ¤   SHFormatDriveFunc = GetProcAddress(shell32Handle,·
af4a68 ¤   ¤   ¤   "SHFormatDrive");
bbaf5a
2dd102 ¤   ¤   if (IsNull(SHFormatDriveFunc))
d55b34 ¤   ¤   {
94c7d5 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetProcAddrFailed,·
3f0c1f ¤   ¤   ¤   ¤   GetLastError());
450fe4 ¤   ¤   }
719371 ¤   }
52af5a
748aa3 ¤   // Attempt to call the function, catching all crashes in the process.
cf2361 ¤   if (derr.IsntError())
05c7a1 ¤   {
8bc750 ¤   ¤   HWND¤   ¤   parentHwnd¤ = mMainDialog->GetSafeHwnd();
a52b18 ¤   ¤   PGPUInt32¤  largeDrive¤ = drive;
37af5a
9bc7ee ¤   ¤   __try
2d5b34 ¤   ¤   {
f74780 ¤   ¤   ¤   __asm
33f776 ¤   ¤   ¤   {
19cc9a ¤   ¤   ¤   ¤   push 1
5b562a ¤   ¤   ¤   ¤   push 0x0000FFFF
895c88 ¤   ¤   ¤   ¤   push largeDrive
47da1a ¤   ¤   ¤   ¤   push parentHwnd
e5ecfc ¤   ¤   ¤   ¤   call [SHFormatDriveFunc]
616954 ¤   ¤   ¤   ¤   sub esp, 0x10
8fa3a6 ¤   ¤   ¤   }
210fe4 ¤   ¤   }
0b45eb ¤   ¤   __except(ExceptionFilter(GetExceptionCode()))
305b34 ¤   ¤   {
ea549c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_SHFormatDriveFailed);
040fe4 ¤   ¤   }
049371 ¤   }
79af5a
ab2c7e ¤   if (loadedShell32)
f1fa86 ¤   ¤   FreeLibrary(shell32Handle);
77af5a
df33e3 ¤   return derr;
d3efe6 }
f8af5a
e1af5a
0ab474 //////////////////////////////
ff7a3b // Interface Utility Functions
e9b474 //////////////////////////////
6daf5a
4220bc // TweakOnTopAttribute makes the selected window "on top" if the main window's
732625 // "on-top" preference is set.
26af5a
--6441 000dac945de401100b5 Page 8 of CPGPdiskAppWinutils.cpp
84c823 void·
82c446 CPGPdiskApp::TweakOnTopAttribute(CWnd *pWnd)
32bb36 {
5d3074 ¤   PGPUInt32 checkState;
bdaf5a
5ed027 ¤   pgpAssertAddrValid(pWnd, CWnd);
6aaf5a
243257 ¤   checkState = PGPdiskGetPrefDWord(kRegistryMainStayOnTopKey, MF_UNCHECKED);
36af5a
6b57a2 ¤   if (checkState == MF_CHECKED)
c6c7a1 ¤   {
2ebdff ¤   ¤   pWnd->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0,·
bbf774 ¤   ¤   ¤   SWP_NOMOVE | SWP_NOSIZE);
b29371 ¤   }
98efe6 }
03af5a
73972c // CreateDIBPalette is a helper function for GetBitmapAndPalette.
adaf5a
f8bd5e HPALETTE·
e4c0f3 CPGPdiskApp::CreateDIBPalette(LPBITMAPINFO lpbmi, LPINT lpiNumColors)·
cdbb36 {
6eb04a ¤   LPBITMAPINFOHEADER¤ lpbi;
bfa52a ¤   LPLOGPALETTE¤   ¤   lpPal;
e3795c ¤   HANDLE¤ ¤   ¤   ¤   hLogPal;
e91fa8 ¤   HPALETTE¤   ¤   ¤   hPal¤   = NULL;
bea1e6 ¤   PGPInt32¤   ¤   ¤   i;
fcd83c ·
b74a86 ¤   lpbi = (LPBITMAPINFOHEADER) lpbmi;
b9af5a
c1335b ¤   if (lpbi->biBitCount <= 8)
72c7a1 ¤   {
19c6c8 ¤   ¤   (* lpiNumColors) = (1 << lpbi->biBitCount);
b59371 ¤   }
d00e24 ¤   else
15c7a1 ¤   {
eb5740 ¤   ¤   (* lpiNumColors = 0); ·// No palette needed for 24 BPP DIB
6d9371 ¤   }
b4af5a
f0a962 ¤   if (* lpiNumColors)
17c7a1 ¤   {
2180a2 ¤   ¤   hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +·
f40f2e ¤   ¤   ¤   sizeof(PALETTEENTRY) * (* lpiNumColors));
99af5a
c02e1f ¤   ¤   lpPal = (LPLOGPALETTE) GlobalLock(hLogPal);
555442 ¤   ¤   lpPal->palVersion = 0x300;
f34b35 ¤   ¤   lpPal->palNumEntries = *lpiNumColors;
1ad83c ·
b01451 ¤   ¤   for (i = 0; ·i < (* lpiNumColors); ·i++)
5c5b34 ¤   ¤   {
d1d118 ¤   ¤   ¤   lpPal->palPalEntry[i].peRed ··= lpbmi->bmiColors[i].rgbRed;
28dc94 ¤   ¤   ¤   lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
a61adf ¤   ¤   ¤   lpPal->palPalEntry[i].peBlue ·= lpbmi->bmiColors[i].rgbBlue;
45089b ¤   ¤   ¤   lpPal->palPalEntry[i].peFlags = 0;
330fe4 ¤   ¤   }
fcaf5a
338e7b ¤   ¤   hPal = CreatePalette(lpPal);
06af5a
a0b7d7 ¤   ¤   GlobalUnlock(hLogPal);
717780 ¤   ¤   GlobalFree(hLogPal);
15b144 ···}
acaf5a
adef80 ···return hPal;
8fefe6 }
bdaf5a
d8f4cc // GetBitmapAndPalette loads a 256-color bitmap as a resource and constructs
fde089 // the necessary palette to draw it with.
dfaf5a
997efe BOOL·
abc23d CPGPdiskApp::GetBitmapAndPalette(
1344a5 ¤   UINT¤   ¤   nIDResource,·
6fdc28 ¤   CBitmap¤¤   *bitmap,·
dacc90 ¤   CPalette¤   *pal)
--e7f6 0002f43beb9401100b5 Page 9 of CPGPdiskAppWinutils.cpp
2cbb36 {
f9646d ¤   HRSRC¤  ¤   ¤   ¤   hRsrc;
c11755 ¤   HGLOBAL¤¤   ¤   ¤   hGlobal;
26ea2b ¤   HBITMAP¤¤   ¤   ¤   hBitmapFinal¤   = NULL;
deb04a ¤   LPBITMAPINFOHEADER¤ lpbi;
e47de6 ¤   HDC¤¤   ¤   ¤   ¤   hdc;
6358f4 ····INT¤¤   ¤   ¤   ¤   iNumColors;
75d83c ·
d7cb43 ¤   hRsrc = FindResource(AfxGetInstanceHandle(),·
ea850a ¤   ¤   MAKEINTRESOURCE(nIDResource), RT_BITMAP);
41af5a
bc446a ¤   if (IsntNull(hRsrc))
05c7a1 ¤   {
32b72b ¤   ¤   hGlobal = LoadResource(AfxGetInstanceHandle(), hRsrc);
e30bf8 ¤   ¤   lpbi = (LPBITMAPINFOHEADER) LockResource(hGlobal);
e1af5a
6b002d ¤   ¤   hdc = GetDC(NULL);
deaf5a
400093 ¤   ¤   if (pal->Attach(CreateDIBPalette((LPBITMAPINFO) lpbi, &iNumColors)))
fd5b34 ¤   ¤   {
a62bd5 ¤   ¤   ¤   SelectPalette(hdc, (* pal), FALSE);
69ac42 ¤   ¤   ¤   RealizePalette(hdc);
9a0fe4 ¤   ¤   }
0ad83c ·
5d1ec7 ¤   ¤   hBitmapFinal = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)lpbi,
9b5fd5 ¤   ¤   ¤   (LONG) CBM_INIT,
38b10e ¤   ¤   ¤   (LPSTR) lpbi + lpbi->biSize + iNumColors * sizeof(RGBQUAD),
da1276 ¤   ¤   ¤   (LPBITMAPINFO) lpbi, DIB_RGB_COLORS);
6caf5a
bfc38b ¤   ¤   bitmap->Attach(hBitmapFinal);
5baf5a
ebd132 ¤   ¤   ReleaseDC(NULL,hdc);
c9f671 ¤   ¤   UnlockResource(hGlobal);
6a5689 ¤   ¤   FreeResource(hGlobal);
89af5a
d5836c ¤   ¤   return TRUE;
0b9371 ¤   }
410e24 ¤   else
afc7a1 ¤   {
5798aa ¤   ¤   return FALSE;
9c9371 ¤   }
46efe6 }
5baf5a
5efa92 // PaintRegistrationInfo paints the user registration info on an about box or
2c552c // splash screen of the given size using the given DC in the given window.
a2af5a
ddc823 void·
b47f0a CPGPdiskApp::PaintRegistrationInfo(
f55f6e ¤   CDC¤¤   ¤   *pDC,·
34c34a ¤   PGPUInt32¤  x,·
b3dff1 ¤   PGPUInt32¤  y,·
c8140a ¤   COLORREF¤   textColor,·
0035ee ¤   CWnd¤   ¤   *pWnd)
f4bb36 {
3578f1 ¤   try
3cc7a1 ¤   {
a0f4fd ¤   ¤   CSize¤  ¤   licenseToSize;
4e2602 ¤   ¤   CString¤¤   orgText, userText;
71355c ¤   ¤   HFONT¤  ¤   oldFont;
041072 ¤   ¤   LPSTR¤  ¤   licenseToText;
791121 ¤   ¤   PGPInt32¤   maxPixelLength, widthLicenseTo;
931265 ¤   ¤   RECT¤   ¤   windowRect;
85af5a
d0ccb9 ¤   ¤   pgpAssertAddrValid(pDC, CDC);
b21572 ¤   ¤   pgpAssertAddrValid(pWnd, CWnd);
b2af5a
ef9699 ¤   ¤   pDC->SetTextColor(textColor);
acf9e8 ¤   ¤   pDC->SetBkMode(TRANSPARENT);
15af5a
37936e ¤   ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
2cf54a ¤   ¤   // don't fool with it.
2faf5a
--a5b0 000a616b6c2401100b5 Page 10 of CPGPdiskAppWinutils.cpp
e24142 ¤   ¤   oldFont = (HFONT) SelectObject(pDC->GetSafeHdc(),·
7982d1 ¤   ¤   ¤   GetStockObject(DEFAULT_GUI_FONT));
91af5a
51a1b2 ¤   ¤   // Determine the maximum pixel string width we can draw.
a39d4a ¤   ¤   pWnd->GetClientRect(&windowRect);
6faf5a
2b866f ¤   ¤   maxPixelLength = windowRect.right - x - 5;
549f0c ¤   ¤   pgpAssert(maxPixelLength > 0);
85af5a
900132 ¤   ¤   // Truncate the strings with periods if they are too long.
d8de42 ¤   ¤   TruncateDisplayString(App->mOrgText, &orgText, pDC, maxPixelLength);
51af5a
8e04ea ¤   ¤   TruncateDisplayString(App->mUserText, &userText, pDC, maxPixelLength);
bdaf5a
5b9ddb ¤   ¤   licenseToText = (LPSTR) GetCommonString(kPGPdiskLicenseToText);
31af5a
9eaa61 ¤   ¤   // Draw the static string.
096e85 ¤   ¤   licenseToSize = pDC->GetOutputTextExtent(licenseToText,·
9a5694 ¤   ¤   ¤   strlen(licenseToText));
22af5a
9964eb ¤   ¤   pDC->LPtoDP(&licenseToSize);
ceaf5a
cdcbbf ¤   ¤   widthLicenseTo = licenseToSize.cx;
0e0aea ¤   ¤   pgpAssert(x > widthLicenseTo + kLicenseToGap);
edaf5a
697889 ¤   ¤   pDC->TextOut(x - widthLicenseTo - kLicenseToGap, y, licenseToText,·
fa5694 ¤   ¤   ¤   strlen(licenseToText));
81af5a
53c0be ¤   ¤   // Draw the variable strings.
22e3b3 ¤   ¤   if (!userText.IsEmpty())
4d5b34 ¤   ¤   {
d585a1 ¤   ¤   ¤   pDC->TextOut(x, y, userText, userText.GetLength());
8a29e2 ¤   ¤   ¤   y += kRegTextInc;
c40fe4 ¤   ¤   }
baaf5a
f838e1 ¤   ¤   if (!orgText.IsEmpty())
405b34 ¤   ¤   {
1d4482 ¤   ¤   ¤   pDC->TextOut(x, y, orgText, orgText.GetLength());
c329e2 ¤   ¤   ¤   y += kRegTextInc;
1a0fe4 ¤   ¤   }
33af5a
d37523 ¤   ¤   pDC->SelectObject(oldFont);
d99371 ¤   }
a33c88 ¤   catch (CMemoryException *ex)
0fc7a1 ¤   {
976adc ¤   ¤   ex->Delete();
549371 ¤   }
46efe6 }
18af5a
cd4ff8 // PaintVersionInfo paints the PGPdisk version info on an about box or splash
989e27 // screen of the given size using the given DC in the given window at the
e7578d // given location.
a6af5a
dec823 void·
61672a CPGPdiskApp::PaintVersionInfo(
835f6e ¤   CDC¤¤   ¤   *pDC,·
c1c34a ¤   PGPUInt32¤  x,·
b0dff1 ¤   PGPUInt32¤  y,·
e1140a ¤   COLORREF¤   textColor,·
0e35ee ¤   CWnd¤   ¤   *pWnd)
50bb36 {
a97b33 ¤   HFONT oldFont;
02af5a
ad23ca ¤   pgpAssertAddrValid(pDC, CDC);
72d027 ¤   pgpAssertAddrValid(pWnd, CWnd);
2aaf5a
2d79ea ¤   pDC->SetTextColor(textColor);
c1c480 ¤   pDC->SetBkMode(TRANSPARENT);
2eaf5a
c8e586 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so don't
aa8f6e ¤   // fool with it.
a6af5a
--2ef8 0002816324c401100b5 Page 11 of CPGPdiskAppWinutils.cpp
594679 ¤   oldFont = (HFONT) SelectObject(pDC->GetSafeHdc(),·
c11349 ¤   ¤   GetStockObject(DEFAULT_GUI_FONT));
51af5a
5f2c51 ¤   pDC->TextOut(x, y, kVersionTextString, strlen(kVersionTextString));
c6fedf ¤   pDC->SelectObject(oldFont);
3fefe6 }
21af5a
a4281a // GetTextRect returns the size of the rectangle the given text would occupy
8909af // if drawn in the given window.
aeaf5a
d5c823 void·
b01be1 CPGPdiskApp::GetTextRect(LPCSTR text, CWnd *pWnd, RECT *pRect)
ddbb36 {
918b83 ¤   CDC¤¤   memDC;
a69b5a ¤   CDC¤¤   *pDC;
ee4f95 ¤   CSize¤  textSize;
c96d85 ¤   HFONT¤  oldFont;
d9af5a
493fe0 ¤   pgpAssertStrValid(text);
d6d027 ¤   pgpAssertAddrValid(pWnd, CWnd);
c97102 ¤   pgpAssertAddrValid(pRect, RECT);
5867c5 ¤
90c712 ¤   pDC = pWnd->GetDC();
0096ce ¤   memDC.CreateCompatibleDC(pDC);
1aaf5a
f50eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
96e162 ¤   // don't fool with it.
8baf5a
958271 ¤   oldFont = (HFONT) SelectObject(memDC.GetSafeHdc(),·
a61349 ¤   ¤   GetStockObject(DEFAULT_GUI_FONT));
06af5a
0a362d ¤   // Get dimensions of text.
86bee9 ¤   textSize = memDC.GetOutputTextExtent(text, strlen(text));
02a384 ¤   memDC.LPtoDP(&textSize);
1eaf5a
d82fbe ¤   pRect->left¤¤   = 0;
55f2c6 ¤   pRect->right¤   = textSize.cx;
b01e1c ¤   pRect->top¤ ¤   = 0;
144e1f ¤   pRect->bottom¤  = textSize.cy;
06af5a
0c9fa3 ¤   memDC.SelectObject(oldFont);
d563a9 ¤   memDC.DeleteDC();
2a44ea ¤   pWnd->ReleaseDC(pDC);
2fefe6 }
6faf5a
1279b4 // TruncateDisplayString will, given a string, a DC, and a maximum length
2fddce // (in pixels), return a string truncated with dots that will fit within that
ce66f0 // length.
7eaf5a
99c823 void·
bb2be4 CPGPdiskApp::TruncateDisplayString(
ed5451 ¤   LPCSTR¤ ¤   inString,·
4e7553 ¤   CString¤¤   *outString,·
455f6e ¤   CDC¤¤   ¤   *pDC,·
129c0a ¤   PGPInt32¤   maxPixelLength)
70bb36 {
4278f1 ¤   try
29c7a1 ¤   {
f1876f ¤   ¤   PGPBoolean¤ didWeTruncateString¤= FALSE;
df86d0 ¤   ¤   PGPUInt32¤  i, numInputChars;
8baf5a
edac7d ¤   ¤   pgpAssertStrValid(inString);
b07a2b ¤   ¤   pgpAssertAddrValid(outString, CString);
1dccb9 ¤   ¤   pgpAssertAddrValid(pDC, CDC);
f09f0c ¤   ¤   pgpAssert(maxPixelLength > 0);
d3af5a
94b4c2 ¤   ¤   numInputChars = strlen(inString);
61af5a
4c4734 ¤   ¤   // Calculate the length of each substring that begins at position 0.
c9e8bf ¤   ¤   // Once we reach a substring that exceeds our maximum pixel length,
14cbc6 ¤   ¤   // we truncate it with dots.
28af5a
--e52d 0007801ff47401100b5 Page 12 of CPGPdiskAppWinutils.cpp
f79c96 ¤   ¤   for (i=0; i < numInputChars; i++)
be5b34 ¤   ¤   {
a6cb51 ¤   ¤   ¤   CSize¤  stringRect;
98d9bf ¤   ¤   ¤   CString¤csInString;
c5af5a
1874c5 ¤   ¤   ¤   csInString = inString;
8faf5a
f772dc ¤   ¤   ¤   // Calculate pixel width of string.
f94dac ¤   ¤   ¤   stringRect = pDC->GetOutputTextExtent(inString, i);
28a0ef ¤   ¤   ¤   pDC->LPtoDP(&stringRect);
fdaf5a
d155ec ¤   ¤   ¤   // If too large, ditch last two chars and tack on 3 dots.
52ee2c ¤   ¤   ¤   if (stringRect.cx > maxPixelLength)
ddf776 ¤   ¤   ¤   {
e1d221 ¤   ¤   ¤   ¤   didWeTruncateString = TRUE;
bcaf5a
ae8d91 ¤   ¤   ¤   ¤   if (i > 3)
d972c3 ¤   ¤   ¤   ¤   {
fbda93 ¤   ¤   ¤   ¤   ¤   (* outString)¤  = csInString.Left(i - 3);
e2d63b ¤   ¤   ¤   ¤   ¤   (* outString)¤  += "...";
c12613 ¤   ¤   ¤   ¤   }
17fa07 ¤   ¤   ¤   ¤   else
c572c3 ¤   ¤   ¤   ¤   {
6262f4 ¤   ¤   ¤   ¤   ¤   (* outString) = csInString.Left(i - 1);
632613 ¤   ¤   ¤   ¤   }
40af5a
70f622 ¤   ¤   ¤   ¤   break;
72a3a6 ¤   ¤   ¤   }
f00fe4 ¤   ¤   }
bfaf5a
d3058f ¤   ¤   if (!didWeTruncateString)
9a5b34 ¤   ¤   {
76db68 ¤   ¤   ¤   (* outString) = inString;
370fe4 ¤   ¤   }
a69371 ¤   }
703c88 ¤   catch (CMemoryException *ex)
f8c7a1 ¤   {
d16adc ¤   ¤   ex->Delete();
469371 ¤   }
11efe6 }
47af5a
a059b7 // FitStringToWindow truncates the string so it fits within the given window
19cad3 // using the default display font.
5daf5a
81c823 void·
842be9 CPGPdiskApp::FitStringToWindow(
9b8664 ¤   LPCSTR¤ inString,·
3e2da1 ¤   CString¤*outString,·
6018a9 ¤   CWnd¤   *pWnd)
91bb36 {
8b0575 ¤   CDC¤¤   ¤   memDC;
fb3570 ¤   CDC¤¤   ¤   *pDC;
d8967d ¤   CSize¤  ¤   messageSize;
df0101 ¤   HFONT¤  ¤   oldFont;
aa578a ¤   PGPUInt32¤  widthMessage, xWindow;
b5bf3b ¤   RECT¤   ¤   windowRect;
a1af5a
c09115 ¤   pgpAssertStrValid(inString);
c9627b ¤   pgpAssertAddrValid(outString, CString);
84d027 ¤   pgpAssertAddrValid(pWnd, CWnd);
2caf5a
f2716c ¤   // Get dimensions of window.
ae9b2b ¤   pWnd->GetWindowRect(&windowRect);
4face2 ¤   pgpAssert(windowRect.right - windowRect.left > 3);
9baf5a
1312b6 ¤   xWindow = windowRect.right - windowRect.left - 3;
ab67c5 ¤
2ac712 ¤   pDC = pWnd->GetDC();
5896ce ¤   memDC.CreateCompatibleDC(pDC);
65af5a
9b0eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
78e162 ¤   // don't fool with it.
--5c22 000b13f4eee401100b5 Page 13 of CPGPdiskAppWinutils.cpp
e0af5a
cb8271 ¤   oldFont = (HFONT) SelectObject(memDC.GetSafeHdc(),·
151349 ¤   ¤   GetStockObject(DEFAULT_GUI_FONT));
d8af5a
0286c3 ¤   // Get dimensions of text to be written.
3a0628 ¤   messageSize = memDC.GetOutputTextExtent(inString, strlen(inString));
f0984e ¤   memDC.LPtoDP(&messageSize);
0eaf5a
41b694 ¤   widthMessage = messageSize.cx;
20af5a
67d5cd ¤   // If too big truncate string.
7472cf ¤   if (widthMessage > xWindow)
e26c3e ¤   ¤   TruncateDisplayString(inString, outString, &memDC, xWindow);
f1af5a
cf9fa3 ¤   memDC.SelectObject(oldFont);
6e63a9 ¤   memDC.DeleteDC();
d144ea ¤   pWnd->ReleaseDC(pDC);
70efe6 }
58af5a
3b9beb // FormatFitStringToWindow takes a string of the form "...%s..." and a
692ef5 // substring and truncates the substring so the entire formatted message will
1282d4 // fit inside the specified window.
daaf5a
6fc823 void·
394c76 CPGPdiskApp::FormatFitStringToWindow(
598664 ¤   LPCSTR¤ inString,·
cf8712 ¤   LPCSTR¤ subString,·
852da1 ¤   CString¤*outString,·
8f18a9 ¤   CWnd¤   *pWnd)
41bb36 {
e60575 ¤   CDC¤¤   ¤   memDC;
793570 ¤   CDC¤¤   ¤   *pDC;
8cfa4e ¤   CSize¤  ¤   messageSizeWoSub, substringSize;
a3b275 ¤   CString¤¤   temp;
2b0101 ¤   HFONT¤  ¤   oldFont;
ea0586 ¤   PGPUInt32¤  widthSubString, widthMessageWoSub, xForSubstring, xWindow;
7ebf3b ¤   RECT¤   ¤   windowRect;
03af5a
849115 ¤   pgpAssertStrValid(inString);
493ec2 ¤   pgpAssertStrValid(subString);
aa627b ¤   pgpAssertAddrValid(outString, CString);
78d027 ¤   pgpAssertAddrValid(pWnd, CWnd);
c4af5a
3b716c ¤   // Get dimensions of window.
ae9b2b ¤   pWnd->GetWindowRect(&windowRect);
7eace2 ¤   pgpAssert(windowRect.right - windowRect.left > 3);
16af5a
af12b6 ¤   xWindow = windowRect.right - windowRect.left - 3;
d667c5 ¤
7ec712 ¤   pDC = pWnd->GetDC();
1b96ce ¤   memDC.CreateCompatibleDC(pDC);
02af5a
f30eb4 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so
86e162 ¤   // don't fool with it.
a0af5a
5c8271 ¤   oldFont = (HFONT) SelectObject(memDC.GetSafeHdc(),·
f41349 ¤   ¤   GetStockObject(DEFAULT_GUI_FONT));
32af5a
f245dc ¤   // Get dimensions of text without the substring.
4e78f1 ¤   try
88c7a1 ¤   {
738b8e ¤   ¤   temp.Format(inString, "");
1d9371 ¤   }
0a3c88 ¤   catch (CMemoryException *ex)
afc7a1 ¤   {
9c6adc ¤   ¤   ex->Delete();
899371 ¤   }
a3af5a
9139c4 ¤   messageSizeWoSub = memDC.GetOutputTextExtent(temp, temp.GetLength());
fe9a12 ¤   memDC.LPtoDP(&messageSizeWoSub);
daaf5a
b1d26a ¤   widthMessageWoSub = messageSizeWoSub.cx;
--3535 001fc3e4e2d401100b5 Page 14 of CPGPdiskAppWinutils.cpp
e0af5a
00add3 ¤   if (widthMessageWoSub < xWindow)
2dc7a1 ¤   {
2d0c47 ¤   ¤   // Get dimensions of substring.
8ef3b1 ¤   ¤   substringSize = memDC.GetOutputTextExtent(subString,·
31e1af ¤   ¤   ¤   strlen(subString));
b0fe04 ¤   ¤   memDC.LPtoDP(&substringSize);
2baf5a
60c0e0 ¤   ¤   widthSubString = substringSize.cx;
34ad92 ¤   ¤   xForSubstring = xWindow - widthMessageWoSub;
88af5a
7dc5c3 ¤   ¤   TruncateDisplayString(subString, &temp, &memDC, xForSubstring);
bce585 ¤   ¤   outString->Format(inString, temp);
5f9371 ¤   }
c60e24 ¤   else
05c7a1 ¤   {
04ffc6 ¤   ¤   TruncateDisplayString(temp, outString, &memDC, xWindow);
c99371 ¤   }
a9af5a
ad9fa3 ¤   memDC.SelectObject(oldFont);
5463a9 ¤   memDC.DeleteDC();
ce44ea ¤   pWnd->ReleaseDC(pDC);
fcefe6 }
--caee 0019922f33d401100b6 Page 1 of CPGPdiskAppWinutils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
1fb277 // CPGPdiskAppWinutils.h
2b465d //
556157 // Contains declarations for CPGPdiskAppWinutils.cpp.
341bc3 //////////////////////////////////////////////////////////////////////////////
39af5a
1012b5 // $Id: CPGPdiskAppWinutils.h,v 1.2.2.5 1998/07/06 08:57:11 nryan Exp $
93af5a
a6cbce // Copyright (C) 1998 by Network Associates, Inc.
a871ae // All rights reserved.
80af5a
8e8ee4 #ifndef Included_CPGPdiskAppWinutils_h¤ // [
361e2d #define Included_CPGPdiskAppWinutils_h
6daf5a
f31cb9 // Nothing needed here.
93af5a
99d7bb #endif¤ // ] Included_CPGPdiskAppWinutils_h
--1e5b 000fdce8732401100b7 Page 1 of CPGPdiskCmdLine.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
f2eb21 // CPGPdiskCmdLine.cpp
ec465d //
39a638 // Implementation of class CPGPdiskCmdLine.
931bc3 //////////////////////////////////////////////////////////////////////////////
e8af5a
2d9621 // $Id: CPGPdiskCmdLine.cpp,v 1.1.2.19.2.2 1998/10/22 22:27:48 nryan Exp $
4eaf5a
37cbce // Copyright (C) 1998 by Network Associates, Inc.
f471ae // All rights reserved.
f1af5a
e59e12 #include "StdAfx.h"
19af5a
ec9bcf #include "Required.h"
9d993c #include "StringAssociation.h"
e1af5a
9fa26a #include "CPGPdiskCmdLine.h"
d1c411 #include "Globals.h"
d1af5a
12af5a
58752c ////////////////////////////////////////////////
3f9d6e // Class CPGPdiskCmdLine public member functions
99752c ////////////////////////////////////////////////
f2af5a
e5dfc0 // The CPGPdiskCmdLine default constructor.
64af5a
333aab CPGPdiskCmdLine::CPGPdiskCmdLine()
23bb36 {
441430 ¤   ClearData();
e9efe6 }
01af5a
668f75 // ParseCommandLine parses the entire application's command line. It would
c264c5 // been nice to use MFC's ParseCommandLine but in their infinite wisdom they
8c08f2 // made that function take a reference to a CCommandLineInfo structure,
6f3886 // making it impossible to use derived classes due to 'slicing'.
97af5a
352292 DualErr·
de94f2 CPGPdiskCmdLine::ParseCommandLine()
b6bb36 {
3d720f ¤   DualErr ¤   derr;
725241 ¤   LPCTSTR ¤   param;
c2f43a ¤   PGPBoolean¤ isFlag;
0ff4e7 ¤   PGPBoolean¤ commandReady¤   = FALSE;
4e0604 ¤   PGPBoolean¤ stopParsing ¤   = FALSE;
cdaf5a
f659b7 ¤   // Iterate through all the arguments and construct the ACI packet.
22e685 ¤   for (PGPInt32 i=1; i < __argc; i++)
08c7a1 ¤   {
1d58a0 ¤   ¤   param = __targv[i];
01af5a
9e963b ¤   ¤   isFlag = FALSE;
4caf5a
18f84e ¤   ¤   if (param[0] == '-' || param[0] == '/')
6b5b34 ¤   ¤   {
c18063 ¤   ¤   ¤   isFlag = TRUE;
bc733b ¤   ¤   ¤   ++param;¤   ¤   ¤   // remove flag specifier
640fe4 ¤   ¤   }
61af5a
7b6817 ¤   ¤   // Parse the parameter. Stop if we are told to.
44e334 ¤   ¤   derr = ParseParam(param, isFlag, &stopParsing, &commandReady);
0baf5a
b42c96 ¤   ¤   // Process the ACI only if refCommandReady is TRUE.
6daa35 ¤   ¤   if (derr.IsntError())
1b5b34 ¤   ¤   {
e6b764 ¤   ¤   ¤   if (commandReady)
69f776 ¤   ¤   ¤   {
e7e9d3 ¤   ¤   ¤   ¤   App->DispatchAppCommandInfo(&ACI);
10af5a
01d037 ¤   ¤   ¤   ¤   ClearData();
2dc767 ¤   ¤   ¤   ¤   commandReady = FALSE;
aca3a6 ¤   ¤   ¤   }
fdaf5a
--e656 0003e47faca401100b7 Page 2 of CPGPdiskCmdLine.cpp
08c31e ¤   ¤   ¤   if (stopParsing)
97f622 ¤   ¤   ¤   ¤   break;
2c0fe4 ¤   ¤   }
afaf5a
71bdd6 ¤   ¤   if (derr.IsError())
cb5b34 ¤   ¤   {
facdcb ¤   ¤   ¤   break;
860fe4 ¤   ¤   }
cb9371 ¤   }
aeaf5a
4b33e3 ¤   return derr;
acefe6 }
58af5a
5eaf5a
8719ca /////////////////////////////////////////////////
70881e // Class CPGPdiskCmdLine private member functions
6f19ca /////////////////////////////////////////////////
09af5a
9eb9a7 // ClearData clears the object's request data.
53af5a
e6c823 void·
72e4c6 CPGPdiskCmdLine::ClearData()
14bb36 {
daee1f ¤   ACI.op¤ ¤   = kAppOp_InvalidRequest;
23b2f7 ¤   ACI.flags¤  = NULL;
fbce4d ¤   ACI.drive¤  = kInvalidDrive;
20363b ¤   ACI.path[0] = NULL;
22af5a
3a849e ¤   mEmergencyUnmount = FALSE;
33d7e5 ¤   mSilentWiping = FALSE;
a4efe6 }
9baf5a
2fd26c // ParseParam is called once for every parameter on the command line. We
aeefa6 // construct the ACI packet as we process each parameter, signalling
74969f // refCommandReady when the packet is ready or refStopParsing when the
5e668f // command line is not going to result in an operation.
18af5a
7a2292 DualErr·
49b315 CPGPdiskCmdLine::ParseParam(
96bd34 ¤   LPCSTR¤ ¤   param,·
62b2f1 ¤   PGPBoolean¤ isFlag,·
2f6254 ¤   PGPBoolean¤ *stopParsing,·
5c30fd ¤   PGPBoolean¤ *commandReady)
a1bb36 {
fc7d36 ¤   DualErr derr;
39af5a
4e60c8 ¤   pgpAssertAddrValid(stopParsing, PGPBoolean);
5cfa93 ¤   pgpAssertAddrValid(commandReady, PGPBoolean);
37af5a
b378f1 ¤   try
0dc7a1 ¤   {
8fd9a9 ¤   ¤   // Each parameter can either be a flag, a command, or a pathname.
8cce0e ¤   ¤   // Flags can appear anywhere but the command has to come before the
898e2c ¤   ¤   // pathname.
51af5a
6cd573 ¤   ¤   if (isFlag)¤¤   // it's a flag
1c5b34 ¤   ¤   {
e55bf5 ¤   ¤   ¤   char¤   ¤   curFlag;
ee4c08 ¤   ¤   ¤   PGPUInt32¤  i¤  = 0;
4aaf5a
e720e6 ¤   ¤   ¤   curFlag = param[i];
9caf5a
b9e81d ¤   ¤   ¤   while (IsntNull(curFlag))
ebf776 ¤   ¤   ¤   {
9f5bf2 ¤   ¤   ¤   ¤   switch (curFlag)
b272c3 ¤   ¤   ¤   ¤   {
e9af5a
968931 ¤   ¤   ¤   ¤   case '?':¤  ¤   ¤   ¤   ¤   ¤   ¤   // print out help
b71b33 ¤   ¤   ¤   ¤   ¤   DisplayMessage(kPGPdiskCmdLineHelpString);
be14c3 ¤   ¤   ¤   ¤   ¤   break;
35af5a
3e6ae5 ¤   ¤   ¤   ¤   case 'e':¤  ¤   ¤   ¤   ¤   ¤   ¤   // emergency unmount
--2bdc 000e3716f67401100b7 Page 3 of CPGPdiskCmdLine.cpp
6a8be0 ¤   ¤   ¤   ¤   ¤   mEmergencyUnmount = TRUE;
1c14c3 ¤   ¤   ¤   ¤   ¤   break;
06af5a
f6c873 ¤   ¤   ¤   ¤   case 's':¤  ¤   ¤   ¤   ¤   ¤   ¤   // silent wiping
b7cd30 ¤   ¤   ¤   ¤   ¤   mSilentWiping = TRUE;
9914c3 ¤   ¤   ¤   ¤   ¤   break;
b6af5a
16a3a4 ¤   ¤   ¤   ¤   default:¤   ¤   ¤   ¤   ¤   ¤   ¤   // invalid option
151068 ¤   ¤   ¤   ¤   ¤   (* stopParsing) = TRUE;
02f477 ¤   ¤   ¤   ¤   ¤   DisplayMessage(kPGPdiskBadCmdLineString);
8614c3 ¤   ¤   ¤   ¤   ¤   break;
822613 ¤   ¤   ¤   ¤   }
1caf5a
346c44 ¤   ¤   ¤   ¤   curFlag = param[i++];
56a3a6 ¤   ¤   ¤   }
0d0fe4 ¤   ¤   }
c86a25 ¤   ¤   else if (ACI.op == kAppOp_InvalidRequest)¤  ¤   // it's a command
385b34 ¤   ¤   {
6ab808 ¤   ¤   ¤   CString command = param;
50af5a
81b94b ¤   ¤   ¤   // Figure out which command it is and prepare the ACI accordingly.
02af5a
318a34 ¤   ¤   ¤   if (command == GetCommonString(kPGPdiskOpenCmdString))
49f776 ¤   ¤   ¤   {
f0fd6d ¤   ¤   ¤   ¤   ACI.op = kAppOp_Mount;
dfa3a6 ¤   ¤   ¤   }
00d95a ¤   ¤   ¤   else if (command ==·
66dc73 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskGlobalConvertCmdString))
5af776 ¤   ¤   ¤   {
ef6f7a ¤   ¤   ¤   ¤   ACI.op = kAppOp_GlobalConvert;
f81fbe ¤   ¤   ¤   ¤   (* commandReady) = TRUE;¤   // doesn't require a path
c9a3a6 ¤   ¤   ¤   }
05a631 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskCreateCmdString))
1df776 ¤   ¤   ¤   {
04a801 ¤   ¤   ¤   ¤   ACI.op = kAppOp_Create;
c6a3a6 ¤   ¤   ¤   }
0e5b7b ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskMountCmdString))
94f776 ¤   ¤   ¤   {
9afd6d ¤   ¤   ¤   ¤   ACI.op = kAppOp_Mount;
15a3a6 ¤   ¤   ¤   }
36043c ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskUnmountCmdString))
88f776 ¤   ¤   ¤   {
544a3e ¤   ¤   ¤   ¤   ACI.op = kAppOp_Unmount;
05af5a
b915d6 ¤   ¤   ¤   ¤   if (mEmergencyUnmount)
2ed836 ¤   ¤   ¤   ¤   ¤   ACI.flags |= kACF_EmergencyUnmount;
38a3a6 ¤   ¤   ¤   }
56c1d1 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskUnmountAllCmdString))
e0f776 ¤   ¤   ¤   {
15fb38 ¤   ¤   ¤   ¤   ACI.op = kAppOp_UnmountAll;
e9af5a
9d15d6 ¤   ¤   ¤   ¤   if (mEmergencyUnmount)
41d836 ¤   ¤   ¤   ¤   ¤   ACI.flags |= kACF_EmergencyUnmount;
5aaf5a
8e1fbe ¤   ¤   ¤   ¤   (* commandReady) = TRUE;¤   // doesn't require a path
16a3a6 ¤   ¤   ¤   }
049d23 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskAddPassCmdString))
f7f776 ¤   ¤   ¤   {
4b1cd2 ¤   ¤   ¤   ¤   ACI.op = kAppOp_AddPassphrase;
a1a3a6 ¤   ¤   ¤   }
8ed381 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskChangePassCmdString))
d8f776 ¤   ¤   ¤   {
b8c05a ¤   ¤   ¤   ¤   ACI.op = kAppOp_ChangePassphrase;
63a3a6 ¤   ¤   ¤   }
44d497 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskRemovePassCmdString))
aaf776 ¤   ¤   ¤   {
b986c8 ¤   ¤   ¤   ¤   ACI.op = kAppOp_RemovePassphrase;
d5a3a6 ¤   ¤   ¤   }
b0ba69 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskRemoveAltsCmdString))
89f776 ¤   ¤   ¤   {
de6a59 ¤   ¤   ¤   ¤   ACI.op = kAppOp_RemoveAlternates;
e3a3a6 ¤   ¤   ¤   }
--b842 0010247ab73401100b7 Page 4 of CPGPdiskCmdLine.cpp
594d4a ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskPubKeysCmdString))
acf776 ¤   ¤   ¤   {
cf92f0 ¤   ¤   ¤   ¤   ACI.op = kAppOp_AddRemovePublicKeys;
bca3a6 ¤   ¤   ¤   }
07af5a
934503 ¤   ¤   #if PGPDISK_PUBLIC_KEY && PGPDISK_WIPE_FUNCS
08af5a
bb019f ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskWipeAllCmdString))
f6f776 ¤   ¤   ¤   {
7f0b28 ¤   ¤   ¤   ¤   ACI.op = kAppOp_WipePassesAllMounted;
34af5a
35251f ¤   ¤   ¤   ¤   if (mSilentWiping)
dfb818 ¤   ¤   ¤   ¤   ¤   ACI.flags |= kACF_SilentWiping;
97af5a
6c1fbe ¤   ¤   ¤   ¤   (* commandReady) = TRUE;¤   // doesn't require a path
49a3a6 ¤   ¤   ¤   }
81af5a
ec8051 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskWipeIndCmdString))
acf776 ¤   ¤   ¤   {
20b7a8 ¤   ¤   ¤   ¤   ACI.op = kAppOp_WipePassesThisDisk;
3daf5a
fc251f ¤   ¤   ¤   ¤   if (mSilentWiping)
29b818 ¤   ¤   ¤   ¤   ¤   ACI.flags |= kACF_SilentWiping;
42a3a6 ¤   ¤   ¤   }
33af5a
7473a1 ¤   ¤   #endif // PGPDISK_PUBLIC_KEY && PGPDISK_WIPE_FUNCS
c9af5a
19b4c1 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskAboutCmdString))
37f776 ¤   ¤   ¤   {
0a2b9e ¤   ¤   ¤   ¤   ACI.op = kAppOp_ShowAboutBox;
ca1fbe ¤   ¤   ¤   ¤   (* commandReady) = TRUE;¤   // doesn't require a path
4ea3a6 ¤   ¤   ¤   }
459e94 ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskHelpCmdString))
59f776 ¤   ¤   ¤   {
f0485a ¤   ¤   ¤   ¤   ACI.op = kAppOp_ShowHelp;
ed1fbe ¤   ¤   ¤   ¤   (* commandReady) = TRUE;¤   // doesn't require a path
eca3a6 ¤   ¤   ¤   }
7a812b ¤   ¤   ¤   else if (command == GetCommonString(kPGPdiskPrefsCmdString))
6af776 ¤   ¤   ¤   {
e1d118 ¤   ¤   ¤   ¤   ACI.op = kAppOp_ShowPrefs;
de1fbe ¤   ¤   ¤   ¤   (* commandReady) = TRUE;¤   // doesn't require a path
aba3a6 ¤   ¤   ¤   }
1cbb8c ¤   ¤   ¤   else
b4f776 ¤   ¤   ¤   {
54e025 ¤   ¤   ¤   ¤   // It's not a recognized command, assume "mount" and that
f377b8 ¤   ¤   ¤   ¤   // this is a path to a PGPdisk.
80af5a
33fd6d ¤   ¤   ¤   ¤   ACI.op = kAppOp_Mount;
98cf6f ¤   ¤   ¤   ¤   strcpy(ACI.path, param);
ccaf5a
15d4ab ¤   ¤   ¤   ¤   (* commandReady) = TRUE;
f4a3a6 ¤   ¤   ¤   }
ea0fe4 ¤   ¤   }
040390 ¤   ¤   else¤   ¤   // it's a pathname
e65b34 ¤   ¤   {
c2ca82 ¤   ¤   ¤   strcpy(ACI.path, param);
1daf5a
b0d146 ¤   ¤   ¤   (* commandReady) = TRUE;
690fe4 ¤   ¤   }
339371 ¤   }
5e3c88 ¤   catch (CMemoryException *ex)
44c7a1 ¤   {
2a6adc ¤   ¤   ex->Delete();
069371 ¤   }
95af5a
5733e3 ¤   return derr;
02efe6 }
--89dd 0010c7ecae3401100b8 Page 1 of CPGPdiskCmdLine.h
541bc3 //////////////////////////////////////////////////////////////////////////////
317298 // CPGPdiskCmdLine.h
cf465d //
35de5e // Declaration of class CPGPdiskCmdLine.
a71bc3 //////////////////////////////////////////////////////////////////////////////
cbaf5a
c9e8a9 // $Id: CPGPdiskCmdLine.h,v 1.1.2.6 1998/08/04 01:19:49 nryan Exp $
3eaf5a
d9cbce // Copyright (C) 1998 by Network Associates, Inc.
0a71ae // All rights reserved.
9daf5a
28f0bb #ifndef Included_CPGpdiskCmdLine_h¤ // [
00b030 #define Included_CPGPdiskCmdLine_h
28af5a
fa3a85 #include "DualErr.h"
34af5a
6a7d4e #include "CPGPdiskAppACI.h"
8daf5a
8faf5a
f6d48e ////////////////////////
46e14f // Class CPGPdiskCmdLine
97d48e ////////////////////////
8daf5a
95d9a8 // CPGPdiskCmdLine is responsible for parsing the PGPDisk command line. It is
d099be // NOT derived from CCommandLineInfo due to some MFC idiocy. It parses only
498ace // one command.
08af5a
fc10a6 class CPGPdiskCmdLine
e5bb36 {
c15ed4 public:
66bd83 ¤   ¤   ¤   CPGPdiskCmdLine();
5c2218 ¤   ¤   ¤   ~CPGPdiskCmdLine()¤ { };
b6af5a
f9e717 ¤   DualErr¤ParseCommandLine();
d5af5a
6b0fb9 private:
840d4f ¤   AppCommandInfo¤ ACI;¤   ¤   ¤   ¤   // we fill this in as we parse
0aeef9 ¤   PGPBoolean¤ ¤   mEmergencyUnmount;¤ // emergency unmount?
d89ccb ¤   PGPBoolean¤ ¤   mSilentWiping;¤ ¤   // don't confirm wiping?
8caf5a
807067 ¤   void¤   ClearData();
cbbecf ¤   DualErr¤ParseParam(LPCSTR param, PGPBoolean isFlag,·
bca2cf ¤   ¤   ¤   ¤   PGPBoolean *stopParsing, PGPBoolean *commandReady);
0e82f7 };
deaf5a
0cc6bf #endif¤ // ] Included_CPGPdiskCmdLine_h
--5967 000e3838870401100b9 Page 1 of CPreferencesSheet.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
bec4b2 // CPreferencesSheet.cpp
27465d //
078b90 // Implementation of class CPreferencesSheet.
9a1bc3 //////////////////////////////////////////////////////////////////////////////
e5af5a
afe40e // $Id: CPreferencesSheet.cpp,v 1.1.2.9 1998/07/06 08:57:13 nryan Exp $
6caf5a
7bcbce // Copyright (C) 1998 by Network Associates, Inc.
1b71ae // All rights reserved.
3baf5a
3a9e12 #include "StdAfx.h"
a4af5a
df9bcf #include "Required.h"
ce993c #include "StringAssociation.h"
94af5a
913646 #include "CMainDialog.h"
b430d7 #include "CPreferencesSheet.h"
9cc411 #include "Globals.h"
744713 #include "PGPdiskHelpIds.h"
cbaf5a
08af5a
626cc2 /////////////////////
2c3a71 // Context help array
586cc2 /////////////////////
47af5a
ca77bf static PGPUInt32 HelpIds[] =
babb36 {
9c8558 ¤   IDOK,¤  ¤   ¤   IDH_PGPDISKAPP_PREFSHEETOK,·
1949e9 ¤   IDCANCEL,¤  ¤   IDH_PGPDISKAPP_PREFSHEETCANCEL,·
06fcd4 ¤   ID_APPLY_NOW,¤  IDH_PGPDISKAPP_PREFSHEETAPPLY,·
244434 ····0,0·
5382f7 };
8eaf5a
feaf5a
f29f73 /////////////////////////
8af338 // Class global variables
6e9f73 /////////////////////////
bdaf5a
881c5c // Keep track of the page the user was last looking at.
638d64 PGPUInt8 CPreferencesSheet::mLastPageViewed = 0;
4faf5a
a7af5a
8b83f5 ///////////////////////////
1db249 // MFC specific definitions
ce83f5 ///////////////////////////
c9af5a
2d2abb BEGIN_MESSAGE_MAP(CPreferencesSheet, CPropertySheet)
0cf435 ¤   //{{AFX_MSG_MAP(CPreferencesSheet)
3bdb65 ¤   ON_WM_HELPINFO()
f59e4e ¤   ON_BN_CLICKED(IDHELP, OnHelp)
c8dfd1 ¤   ON_WM_SYSCOMMAND()
b7044a ¤   //}}AFX_MSG_MAP
c2af28 END_MESSAGE_MAP()
4baf5a
84af5a
8095ce /////////////////////////////////////////////////////////////////////
706457 // CPreferencesSheet public custom functions and non-default handlers
8995ce /////////////////////////////////////////////////////////////////////
e0af5a
825891 IMPLEMENT_DYNAMIC(CPreferencesSheet, CPropertySheet)
27af5a
232a48 // The CPreferencesSheet constructor adds the two property pages we implement
82a674 // to the property sheet.
f9af5a
4b5209 CPreferencesSheet::CPreferencesSheet()
4a9fe8 ¤   : CPropertySheet(GetCommonString(kPGPdiskPrefsSheetTitleString), NULL, 0)
91bb36 {
d178f1 ¤   try
02c7a1 ¤   {
9f0adc ¤   ¤   AddPage(&mAutoUnmountPage);
e367bb ¤   ¤   AddPage(&mHotKeyPage);
--912f 0006d618b89401100b9 Page 2 of CPreferencesSheet.cpp
e0af5a
6b2462 ¤   ¤   // Exorcise the big help button.
db68a4 ¤   ¤   m_psh.dwFlags &= ~PSH_HASHELP;
789371 ¤   }
3a3c88 ¤   catch (CMemoryException *ex)
acc7a1 ¤   {
a59a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
fc6adc ¤   ¤   ex->Delete();
3d9371 ¤   }
7aefe6 }
84af5a
fd7c02 // The CPreferencesSheet destructor.
8eaf5a
64f379 CPreferencesSheet::~CPreferencesSheet()
3abb36 {
16efe6 }
f3af5a
7d1f78 // DestroyWindow is called when the dialog is about to go away.
70af5a
f57efe BOOL·
58fd67 CPreferencesSheet::DestroyWindow()·
dabb36 {
6e051c ¤   // Save the index of the last page viewed.
b94c92 ¤   mLastPageViewed = GetActiveIndex();
3c2385 ¤   return CPropertySheet::DestroyWindow();
c4efe6 }
aaaf5a
c3e096 // DisplayPreferences is a wrapper around DoModal.
a7af5a
442292 DualErr·
f1a135 CPreferencesSheet::DisplayPreferences()
58bb36 {
06be41 ¤   DualErr¤¤   derr;
1ae319 ¤   PGPInt32¤   result;
5967c5 ¤
5e310c ¤   m_psh.nStartPage = mLastPageViewed;
8c0acb ¤   result = DoModal();
02af5a
bfcff3 ¤   switch (result)
b7c7a1 ¤   {
8be379 ¤   case -1:
9ffdbb ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
442f68 ¤   ¤   break;
6e9371 ¤   }
55af5a
5a33e3 ¤   return derr;
4cefe6 }
c5af5a
42af5a
49edb3 ///////////////////////////////////////////////
f3f3cc // CPreferencesSheet protected default handlers
c9edb3 ///////////////////////////////////////////////
ceaf5a
cd8cca // OnHelpInfo handles context-sensitive help.
2caf5a
a57efe BOOL·
d0f2ed CPreferencesSheet::OnHelpInfo(HELPINFO *pHelpInfo)
d7bb36 {
d029b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
78e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
0dc7a1 ¤   {
46ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
146b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
c39371 ¤   }
33af5a
83c2e7 ¤   return TRUE;
11efe6 }
dcaf5a
927e66 // OnInitDialog is called during dialog initialization. We take the
a2479b // opportunity to add a context help button to the title bar.
48af5a
6d7efe BOOL·
--7b69 001c07e5509401100b9 Page 3 of CPreferencesSheet.cpp
40a81d CPreferencesSheet::OnInitDialog()·
babb36 {
a31450 ¤   CPropertySheet::OnInitDialog();
7faf5a
715d47 ¤   // Show the context help button.
617f87 ¤   ModifyStyleEx(NULL, WS_EX_CONTEXTHELP, NULL);
23af5a
f4d564 ¤   // Center on screen.
8850f9 ¤   CenterWindow(GetDesktopWindow());
85af5a
4eafdc ¤   // Put us in front.
0c9974 ¤   SetForegroundWindow();
7baf5a
e554ed ¤   // Put on top if necessary.
25c3a9 ¤   App->TweakOnTopAttribute(this);
edaf5a
cba230 ¤   return FALSE;
6eefe6 }
3eaf5a
394e48 // OnSysCommand is overridden so we can handle close operations. Confirm in
b1734b // certain cases.
efaf5a
2dc823 void·
260f0f CPreferencesSheet::OnSysCommand(UINT nID, LPARAM lParam)·
afbb36 {
60e1e5 ¤   PGPBoolean skipCommand = FALSE;
d9af5a
fd6608 ¤   // If apply button is enabled, there are pending changes.
b11f71 ¤   if (nID == SC_CLOSE)
a1c7a1 ¤   {
f4ffdd ¤   ¤   if (GetDlgItem(ID_APPLY_NOW)->IsWindowEnabled())
055b34 ¤   ¤   {
ff07d3 ¤   ¤   ¤   switch (DisplayMessage(kPGPdiskAskToSavePrefs,·
a2bd1e ¤   ¤   ¤   ¤   kPMBS_YesNoCancel, kPMBF_YesButton))
cbf776 ¤   ¤   ¤   {
c1d952 ¤   ¤   ¤   case kUR_Yes:
d914aa ¤   ¤   ¤   ¤   PressButton(PSBTN_APPLYNOW);
5ef622 ¤   ¤   ¤   ¤   break;
a5af5a
0ee022 ¤   ¤   ¤   case kUR_No:
61f622 ¤   ¤   ¤   ¤   break;
58af5a
3f90b7 ¤   ¤   ¤   case kUR_Cancel:
555a3c ¤   ¤   ¤   ¤   skipCommand = TRUE;
78f622 ¤   ¤   ¤   ¤   break;
a0a3a6 ¤   ¤   ¤   }
da0fe4 ¤   ¤   }
6f9371 ¤   }
73af5a
6794fa ¤   if (!skipCommand)
5814b9 ¤   ¤   CPropertySheet::OnSysCommand(nID, lParam);
c0efe6 }
--081e 0015fed88ba401100ba Page 1 of CPreferencesSheet.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b6821e // CPreferencesSheet.h
d0465d //
8545da // Declaration of class CPreferencesSheet.
2c1bc3 //////////////////////////////////////////////////////////////////////////////
77af5a
5b8bda // $Id: CPreferencesSheet.h,v 1.1.2.5 1998/07/06 08:57:14 nryan Exp $
23af5a
82cbce // Copyright (C) 1998 by Network Associates, Inc.
b371ae // All rights reserved.
42af5a
c13374 #ifndef Included_CPreferencesSheet_h¤   // [
38c28c #define Included_CPreferencesSheet_h
42af5a
f43a85 #include "DualErr.h"
90af5a
ea6b41 #include "CPrefsAutoUnmountPage.h"
bf7470 #include "CPrefsUnmountHotKeyPage.h"
32af5a
f9af5a
57b352 //////////////////////////
5e943d // Class CPreferencesSheet
7eb352 //////////////////////////
58af5a
ac4d99 class CPreferencesSheet : public CPropertySheet
47bb36 {
aa7848 ¤   DECLARE_DYNAMIC(CPreferencesSheet)
14af5a
025ed4 public:
8d1603 ¤   DualErr mInitErr;
92af5a
4a5bc7 ¤   ¤   ¤   CPreferencesSheet();
fbc27a ¤   virtual¤~CPreferencesSheet();
dfaf5a
508139 ¤   DualErr¤DisplayPreferences();
d8af5a
bd360e ¤   //{{AFX_VIRTUAL(CPreferencesSheet)
5367d4 ¤   public:
c366a4 ¤   virtual BOOL DestroyWindow();
9df17a ¤   virtual BOOL OnInitDialog();
3baf53 ¤   //}}AFX_VIRTUAL
20af5a
99a2d3 protected:
5d08a5 ¤   static PGPUInt8¤¤   ¤   mLastPageViewed;¤   ¤   // last page viewed
c7af5a
6d178b ¤   CPrefsAutoUnmountPage¤  mAutoUnmountPage;¤  ¤   // the Auto-Unmount page
f0f472 ¤   CPrefsUnmountHotKeyPage¤mHotKeyPage;¤   ¤   ¤   // the HotKey page
0d67c5 ¤
f152b1 ¤   //{{AFX_MSG(CPreferencesSheet)
3d698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
664d01 ¤   afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
6f2e09 ¤   //}}AFX_MSG
3faf5a
652409 ¤   DECLARE_MESSAGE_MAP()
3b82f7 };
c5af5a
49c18c //{{AFX_INSERT_LOCATION}}
56af5a
5f91d2 #endif // ] Included_CPreferencesSheet_h
--f575 0004d139b21401100bb Page 1 of CPrefsAutoUnmountPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
38f7f1 // CPrefsAutoUnmountPage.cpp
0f465d //
8e0010 // Implementation of class CPrefsAutoUnmountPage.
8a1bc3 //////////////////////////////////////////////////////////////////////////////
96af5a
e7f00a // $Id: CPrefsAutoUnmountPage.cpp,v 1.1.2.11 1998/07/31 21:36:48 nryan Exp $
99af5a
adcbce // Copyright (C) 1998 by Network Associates, Inc.
1571ae // All rights reserved.
53af5a
529e12 #include "StdAfx.h"
f6af5a
1a9bcf #include "Required.h"
ce6b41 #include "CPrefsAutoUnmountPage.h"
7ec411 #include "Globals.h"
b74713 #include "PGPdiskHelpIds.h"
d5af5a
adaf5a
066cc2 /////////////////////
843a71 // Context help array
256cc2 /////////////////////
8baf5a
3e77bf static PGPUInt32 HelpIds[] =
d7bb36 {
a39e47 ¤   IDC_CHECK_SLEEP,¤   ¤   IDH_PGPDISKAPP_PREFSAUTOSLEEPCHECK,·
78e6b3 ¤   IDC_CHECK_PREVENT,¤ ¤   IDH_PGPDISKAPP_PREFSPREVENTSLEEPCHECK,·
abe060 ¤   IDC_CHECK_UNMOUNT,¤ ¤   IDH_PGPDISKAPP_PREFSAUTOUNMOUNTCHECK,·
7f3c82 ¤   IDC_EDIT_SPIN,¤ ¤   ¤   IDH_PGPDISKAPP_PREFSAUTOUNMOUNTSPIN,·
8a5497 ¤   IDC_EDIT_UNMOUNT,¤  ¤   IDH_PGPDISKAPP_PREFSAUTOUNMOUNTEDIT,·
1b67c2 ¤   IDC_MINUTETEXT,¤¤   ¤   IDH_PGPDISKAPP_PREFSAUTOUNMOUNTCHECK,·
094434 ····0,0·
5282f7 };
a4af5a
01af5a
f883f5 ///////////////////////////
26b249 // MFC specific definitions
4683f5 ///////////////////////////
e3af5a
f8e381 BEGIN_MESSAGE_MAP(CPrefsAutoUnmountPage, CPropertyPage)
8357bc ¤   //{{AFX_MSG_MAP(CPrefsAutoUnmountPage)
04fbe4 ¤   ON_BN_CLICKED(IDC_CHECK_SLEEP, OnCheckSleep)
33f19b ¤   ON_BN_CLICKED(IDC_CHECK_UNMOUNT, OnCheckAutoUnmount)
fe7580 ¤   ON_EN_CHANGE(IDC_EDIT_UNMOUNT, OnChangeTimeout)
62db65 ¤   ON_WM_HELPINFO()
8a8c56 ¤   ON_WM_LBUTTONDOWN()
8facf7 ¤   ON_BN_CLICKED(IDC_CHECK_PREVENT, OnCheckPrevent)
9c044a ¤   //}}AFX_MSG_MAP
67af28 END_MESSAGE_MAP()
09af5a
abaf5a
d8186d /////////////////////////////////////////////////////////////////////////
799dd7 // CPrefsAutoUnmountPage public custom functions and non-default handlers
85186d /////////////////////////////////////////////////////////////////////////
12af5a
d665e6 IMPLEMENT_DYNCREATE(CPrefsAutoUnmountPage, CPropertyPage)
7baf5a
f5d95a // The CPrefsAutoUnmountPage default constructor.
91af5a
a710a9 CPrefsAutoUnmountPage::CPrefsAutoUnmountPage()
327b1f ¤   ·: CPropertyPage(CPrefsAutoUnmountPage::IDD)
50bb36 {
98480c ¤   //{{AFX_DATA_INIT(CPrefsAutoUnmountPage)
f26e51 ¤   mTimeoutValue = 0;
72f2c9 ¤   mSleepValue = FALSE;
617eec ¤   mAutoUnmountValue = FALSE;
19ffe3 ¤   mPreventSleepValue = FALSE;
fdb1e8 ¤   //}}AFX_DATA_INIT
55af5a
f2218f ¤   // Exorcise the big help button.
2b6a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
4defe6 }
--b81d 000e4648c4d401100bb Page 2 of CPrefsAutoUnmountPage.cpp
e0af5a
6d30ef // The CPrefsAutoUnmountPage destructor.
e9af5a
cad13b CPrefsAutoUnmountPage::~CPrefsAutoUnmountPage()
d8bb36 {
4befe6 }
dfaf5a
c2d37a // We override OnSetActive to handle some dialog control initialization.
18af5a
8e7efe BOOL·
af7993 CPrefsAutoUnmountPage::OnSetActive()·
69bb36 {
38ff21 ¤   // Disable sleep options on NT4.
c17408 ¤   if (IsWinNT4CompatibleMachine() && !IsWinNT5CompatibleMachine())
36c7a1 ¤   {
3081d9 ¤   ¤   mCheckSleepButton.EnableWindow(FALSE);
0932c1 ¤   ¤   mCheckPreventButton.EnableWindow(FALSE);
9e9371 ¤   }
bc0e24 ¤   else
70c7a1 ¤   {
fe8edc ¤   ¤   // Disable the prevent sleep box if unmount on sleep is unchecked.
bd38eb ¤   ¤   mCheckPreventButton.EnableWindow(mSleepValue);
b79371 ¤   }
66af5a
883512 ¤   // Set the range of the spin control.
d47fae ¤   mMinutesSpin.SetRange(1, kMaxUnmountTimeout);
5267c5 ¤
6ebfaa ¤   return CPropertyPage::OnSetActive();
42efe6 }
1caf5a
91af5a
0b063a ////////////////////////////////////////////////////////////////////////////
a1b8d7 // CPrefsAutoUnmountPage protected custom functions and non-default handlers
71063a ////////////////////////////////////////////////////////////////////////////
89af5a
fe310f // ValidateTimeoutValue checks if the user has entered an invalid timeout
7b61ce // value, and if so, prompts the user to re-enter. Returns TRUE if a valid
028960 // timeout value was detected, FALSE otherwise.
8faf5a
9477be PGPBoolean·
8c8543 CPrefsAutoUnmountPage::ValidateTimeoutValue()
15bb36 {
15af92 ¤   CString¤text;
0aaf5a
74e29a ¤   // Verify that the user entered an acceptable timeout value.
44364d ¤   UpdateData(TRUE);
10af5a
f9ce5f ¤   if ((mTimeoutValue > 0) && (mTimeoutValue <= kMaxUnmountTimeout))
fcc7a1 ¤   {
49836c ¤   ¤   return TRUE;
f29371 ¤   }
f90e24 ¤   else
7fc7a1 ¤   {
8c91f1 ¤   ¤   if (mTimeoutValue > kMaxUnmountTimeout)
2d5b34 ¤   ¤   {
9c568a ¤   ¤   ¤   mTimeoutValue = kMaxUnmountTimeout;
0ff468 ¤   ¤   ¤   UpdateData(FALSE);
feaf5a
6b4f1b ¤   ¤   ¤   ReportError(kPGDMajorError_TimeoutValueTooBig);
120fe4 ¤   ¤   }
7f0e1d ¤   ¤   else
c65b34 ¤   ¤   {
d4c244 ¤   ¤   ¤   mTimeoutValue = 1;
4cf468 ¤   ¤   ¤   UpdateData(FALSE);
c8af5a
f312cf ¤   ¤   ¤   ReportError(kPGDMajorError_TimeoutValueTooSmall);
4f0fe4 ¤   ¤   }
38af5a
4dc8a5 ¤   ¤   mAutoUnmountValue = 1;
9baf5a
da41f1 ¤   ¤   try
e45b34 ¤   ¤   {
--adf4 00021343cc1401100bb Page 3 of CPrefsAutoUnmountPage.cpp
e89c58 ¤   ¤   ¤   // Highlight the offending numeral.
f0b522 ¤   ¤   ¤   mTimeoutBox.SetFocus();
3619f2 ¤   ¤   ¤   mTimeoutBox.GetWindowText(text);
ee36f6 ¤   ¤   ¤   mTimeoutBox.SetSel(0, text.GetLength(), FALSE);
fa0fe4 ¤   ¤   }
eb01e0 ¤   ¤   catch (CMemoryException *ex)
3c5b34 ¤   ¤   {
10ad69 ¤   ¤   ¤   ex->Delete();
e70fe4 ¤   ¤   }
16af5a
3598aa ¤   ¤   return FALSE;
c19371 ¤   }
93efe6 }
b1af5a
006be3 // The CPrefsAutoUnmountPage data exchange function.
26af5a
a4c823 void·
fcf601 CPrefsAutoUnmountPage::DoDataExchange(CDataExchange *pDX)
babb36 {
f178f1 ¤   try
bcc7a1 ¤   {
dcbb57 ¤   ¤   CString¤¤   text;
e50195 ¤   ¤   PGPBoolean¤ skipDDX¤= FALSE;
e8af5a
6c22a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
f3af5a
3a1b01 ¤   ¤   // Our goal is to coax MFC into accepting NULL fields for our timeout
6d17a0 ¤   ¤   // box.
c0af5a
e0e195 ¤   ¤   if (mTimeoutBox.GetSafeHwnd())
3119f2 ¤   ¤   ¤   mTimeoutBox.GetWindowText(text);
48af5a
2388e2 ¤   ¤   // Don't overwrite a null field with a 0.
101c87 ¤   ¤   if (!pDX->m_bSaveAndValidate && text.IsEmpty() &&·
a2dc23 ¤   ¤   ¤   (mTimeoutValue == 0))
165b34 ¤   ¤   {
3efb03 ¤   ¤   ¤   skipDDX = TRUE;
980fe4 ¤   ¤   }
37af5a
ea3962 ¤   ¤   // Note the way the second 'if' statement ends within the
e0914a ¤   ¤   // AFX_DATA_MAP. This is done so our variable will still appear in
83b585 ¤   ¤   // the ClassWizard, but allows us to skip the DDX_Text when we want
497157 ¤   ¤   // to.
f1af5a
c19a07 ¤   ¤   if (pDX->m_bSaveAndValidate && text.IsEmpty())
f25b34 ¤   ¤   {
8efb03 ¤   ¤   ¤   skipDDX = TRUE;
309898 ¤   ¤   ¤   mTimeoutValue = 0;
c30fe4 ¤   ¤   }
9caf5a
770c4b ¤   ¤   if (!skipDDX)
c174a2 ¤   ¤   //{{AFX_DATA_MAP(CPrefsAutoUnmountPage)
88462b ¤   ¤   ¤   DDX_Text(pDX, IDC_EDIT_UNMOUNT, mTimeoutValue);
0392ef ¤   ¤   DDX_Control(pDX, IDC_CHECK_SLEEP, mCheckSleepButton);
23e032 ¤   ¤   DDX_Control(pDX, IDC_CHECK_PREVENT, mCheckPreventButton);
6602d4 ¤   ¤   DDX_Control(pDX, IDC_EDIT_SPIN, mMinutesSpin);
e963d1 ¤   ¤   DDX_Control(pDX, IDC_MINUTETEXT, mMinuteText);
5ea8d9 ¤   ¤   DDX_Control(pDX, IDC_EDIT_UNMOUNT, mTimeoutBox);
ac3f2d ¤   ¤   DDX_Check(pDX, IDC_CHECK_SLEEP, mSleepValue);
66e7a2 ¤   ¤   DDX_Check(pDX, IDC_CHECK_UNMOUNT, mAutoUnmountValue);
6cefcf ¤   ¤   DDX_Check(pDX, IDC_CHECK_PREVENT, mPreventSleepValue);
a13376 ¤   ¤   //}}AFX_DATA_MAP
669371 ¤   }
8b3c88 ¤   catch (CMemoryException *ex)
57c7a1 ¤   {
a06adc ¤   ¤   ex->Delete();
b39371 ¤   }
2aefe6 }
dcaf5a
655084 // OnCheckSleep is overridden so we can enable the 'Apply' button and enable
80bfe3 // or disable the prevent sleep checkbox as appropriate.
21af5a
--b38b 000e791c08a401100bb Page 4 of CPrefsAutoUnmountPage.cpp
84c823 void·
06e50b CPrefsAutoUnmountPage::OnCheckSleep()·
8cbb36 {
97d5f9 ¤   SetModified(TRUE);
cb364d ¤   UpdateData(TRUE);
96af5a
1229cc ¤   mCheckPreventButton.EnableWindow(mSleepValue);
23efe6 }
e8af5a
7ec9ed // OnCheckAutoUnmount is overridden so we can enable the 'Apply' button.
10af5a
3ac823 void·
b8f03f CPrefsAutoUnmountPage::OnCheckAutoUnmount()·
d6bb36 {
8a364d ¤   UpdateData(TRUE);
5daf5a
8ab7a2 ¤   if (ValidateTimeoutValue())
95c7a1 ¤   {
45dd9e ¤   ¤   if (mAutoUnmountValue == 1)
485b34 ¤   ¤   {
4d8bb4 ¤   ¤   ¤   mTimeoutBox.EnableWindow(TRUE);
6a44ff ¤   ¤   ¤   mMinutesSpin.EnableWindow(TRUE);
6e0fe4 ¤   ¤   }
5e0e1d ¤   ¤   else
ce5b34 ¤   ¤   {
fe6852 ¤   ¤   ¤   mTimeoutBox.EnableWindow(FALSE);
d1944a ¤   ¤   ¤   mMinutesSpin.EnableWindow(FALSE);
a90fe4 ¤   ¤   }
f5af5a
a83718 ¤   ¤   SetModified(TRUE);
559371 ¤   }
8befe6 }
19af5a
2bde6f // OnChangeTimeout is overridden so we can enable the 'Apply' button.
83af5a
b5c823 void·
d26578 CPrefsAutoUnmountPage::OnChangeTimeout()·
eebb36 {
d3f02e ¤   SetModified(TRUE);¤
40efe6 }
95af5a
721eda // OnCheckPrevent is overridden so we can enable the 'Apply' button.
8eaf5a
73c823 void·
bb16bb CPrefsAutoUnmountPage::OnCheckPrevent()·
f6bb36 {
b0f02e ¤   SetModified(TRUE);¤
74efe6 }
21af5a
aaaf5a
043239 ///////////////////////////////////////////////////////////
fe383c // CPrefsAutoUnmountPage protected default message handlers
8f3239 ///////////////////////////////////////////////////////////
8eaf5a
c33074 // OnApply is overridden to apply the changes the user made to the application,
9bc094 // but we don't save them to the registry.
4daf5a
bc7efe BOOL·
12691a CPrefsAutoUnmountPage::OnApply()·
85bb36 {
20945d ¤   DualErr¤derr;
a6af5a
96364d ¤   UpdateData(TRUE);
ebaf5a
6afa32 ¤   // If the user entered an invalid timeout value, make him change it.
b0b7a2 ¤   if (ValidateTimeoutValue())
1bc7a1 ¤   {
75a7aa ¤   ¤   // Update the application's variables.
8f5bf9 ¤   ¤   App->mAutoUnmount¤  ¤   ¤   = mAutoUnmountValue;
505c24 ¤   ¤   App->mUnmountOnSleep¤   ¤   = mSleepValue;
49afb6 ¤   ¤   App->mNoSleepIfUnmountFail¤ = mPreventSleepValue;
e73f11 ¤   ¤   App->mUnmountTimeout¤   ¤   = mTimeoutValue;
--a0db 000ca17d446401100bb Page 5 of CPrefsAutoUnmountPage.cpp
e0af5a
4e1c6f ¤   ¤   // Tell the driver.
4738c0 ¤   ¤   App->SetDriverPrefsFromApp();
60af5a
f5eef2 ¤   ¤   return CPropertyPage::OnApply();
9f9371 ¤   }
a70e24 ¤   else
bdc7a1 ¤   {
c298aa ¤   ¤   return FALSE;
1d9371 ¤   }
75efe6 }
c2af5a
298cca // OnHelpInfo handles context-sensitive help.
fbaf5a
257efe BOOL·
fc3f0f CPrefsAutoUnmountPage::OnHelpInfo(HELPINFO *pHelpInfo)
98bb36 {
4329b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
1fe5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
1bc7a1 ¤   {
62ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
546b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
ba9371 ¤   }
07af5a
5cc2e7 ¤   return TRUE;
07efe6 }
42af5a
06360f // OnInitDialog is overwritten to perform property page initialization.
c8af5a
e37efe BOOL·
c48fe9 CPrefsAutoUnmountPage::OnInitDialog()·
18bb36 {
ac4541 ¤   CPropertyPage::OnInitDialog();
9caf5a
330980 ¤   // Initialize the three check boxes.
c45766 ¤   mSleepValue¤¤   ¤   = App->mUnmountOnSleep;
a773db ¤   mAutoUnmountValue¤  = App->mAutoUnmount;
3546c6 ¤   mPreventSleepValue¤ = App->mNoSleepIfUnmountFail;
41af5a
77ae99 ¤   // Fill in the edit box with the timeout value.
f93bd4 ¤   mTimeoutValue = App->mUnmountTimeout;
8caf5a
ad02a1 ¤   UpdateData(FALSE);
35af5a
685662 ¤   if (mAutoUnmountValue == 1)
cec7a1 ¤   {
d503d2 ¤   ¤   mTimeoutBox.EnableWindow(TRUE);
074247 ¤   ¤   mMinutesSpin.EnableWindow(TRUE);
069371 ¤   }
0a0e24 ¤   else
27c7a1 ¤   {
6e6eea ¤   ¤   mTimeoutBox.EnableWindow(FALSE);
b1ad8f ¤   ¤   mMinutesSpin.EnableWindow(FALSE);
199371 ¤   }
35af5a
fec2e7 ¤   return TRUE;
42efe6 }
5daf5a
0d8906 // OnKillActive is overridden to perform data validation.
b5af5a
f47efe BOOL·
4b12c8 CPrefsAutoUnmountPage::OnKillActive()·
0ebb36 {
b6fa32 ¤   // If the user entered an invalid timeout value, make him change it.
68507a ¤   if (!ValidateTimeoutValue())
2198aa ¤   ¤   return FALSE;
b00e24 ¤   else
e80baa ¤   ¤   return CPropertyPage::OnKillActive();
44efe6 }
f8af5a
17d403 // OnLButtonDown is called when the user presses the left mouse button. We
ca1e03 // see if he is clicking in the 'minutes of inactivity' text and then alter
--24dd 001388f366b401100bb Page 6 of CPrefsAutoUnmountPage.cpp
548d83 // the appropriate check box.
1eaf5a
14c823 void·
48d6f6 CPrefsAutoUnmountPage::OnLButtonDown(UINT nFlags, CPoint point)·
19bb36 {
58b5ff ¤   PGPBoolean pointInMinuteText;
eaaf5a
89c20b ¤   pointInMinuteText = ChildWindowFromPoint(point)->GetSafeHwnd() ==
62bc66 ¤   ¤   mMinuteText.GetSafeHwnd();
2faf5a
845d3c ¤   if (pointInMinuteText)
bfc7a1 ¤   {
30f1f8 ¤   ¤   UpdateData(TRUE);
83ad13 ¤   ¤   mAutoUnmountValue = !mAutoUnmountValue;
b3e040 ¤   ¤   UpdateData(FALSE);
5d9371 ¤   }
16af5a
ff46a2 ¤   CPropertyPage::OnLButtonDown(nFlags, point);
eaefe6 }
ddaf5a
1e0285 // OnOK is overridden to save the new value to the registry. It is always
700f5a // called right after OnApply.
b7af5a
e8c823 void·
5e6db8 CPrefsAutoUnmountPage::OnOK()·
d3bb36 {
5c945d ¤   DualErr¤derr;
3caf5a
334c7c ¤   // Update the registry.
0df9f6 ¤   derr = App->SetRegistryPrefs();
22af5a
744bb3 ¤   if (derr.IsError())
85c7a1 ¤   {
1a5ba1 ¤   ¤   ReportError(kPGDMajorError_PreferencesAccessFailed, derr);
539371 ¤   }
330e24 ¤   else
5dc7a1 ¤   {
91b8ea ¤   ¤   App->UpdatePGPdiskResident();
1b9371 ¤   }
07af5a
9c2e36 ¤   CPropertyPage::OnOK();
38efe6 }
--4bc4 00106168227401100bc Page 1 of CPrefsAutoUnmountPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b92da8 // CPrefsAutoUnmountPage.h
75465d //
2ed088 // Declaration of class CPrefsAutoUnmountPage.
b51bc3 //////////////////////////////////////////////////////////////////////////////
ceaf5a
0f8d01 // $Id: CPrefsAutoUnmountPage.h,v 1.1.2.5 1998/07/06 08:57:15 nryan Exp $
c9af5a
f1cbce // Copyright (C) 1998 by Network Associates, Inc.
da71ae // All rights reserved.
5caf5a
b95cd9 #ifndef Included_CPrefsAutoUnmountPage_h¤   // [
a9a8fa #define Included_CPrefsAutoUnmountPage_h
9baf5a
5fab81 #include "Resource.h"
c3af5a
ecaf5a
13b474 //////////////////////////////
c82a7b // Class CPrefsAutoUnmountPage
12b474 //////////////////////////////
38af5a
7300e8 class CPrefsAutoUnmountPage : public CPropertyPage
1ebb36 {
c506dd ¤   DECLARE_DYNCREATE(CPrefsAutoUnmountPage)
42af5a
4b5ed4 public:
3b752d ¤   CPrefsAutoUnmountPage();
a23c57 ¤   ~CPrefsAutoUnmountPage();
b2af5a
6104d2 ¤   //{{AFX_DATA(CPrefsAutoUnmountPage)
c7dee7 ¤   enum { IDD = IDD_PROP_AUTO };
663f65 ¤   CButton¤mCheckSleepButton;
ce2963 ¤   CButton¤mCheckPreventButton;
f2ec51 ¤   CSpinButtonCtrl¤mMinutesSpin;
803fd1 ¤   CStatic¤mMinuteText;
303cb9 ¤   CEdit¤  mTimeoutBox;
499418 ¤   UINT¤   mTimeoutValue;
ebfd9e ¤   BOOL¤   mSleepValue;
52e1b7 ¤   BOOL¤   mAutoUnmountValue;
f512ac ¤   BOOL¤   mPreventSleepValue;
565139 ¤   //}}AFX_DATA
1aaf5a
906479 ¤   //{{AFX_VIRTUAL(CPrefsAutoUnmountPage)
0767d4 ¤   public:
dcba9c ¤   virtual BOOL OnApply();
b46c5b ¤   virtual BOOL OnKillActive();
7e5762 ¤   virtual void OnOK();
0a6e36 ¤   virtual BOOL OnSetActive();
bbc369 ¤   protected:
8d3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
05af53 ¤   //}}AFX_VIRTUAL
ffaf5a
50a2d3 protected:
6b9418 ¤   PGPBoolean ValidateTimeoutValue();
58af5a
87d130 ¤   //{{AFX_MSG(CPrefsAutoUnmountPage)
49f17a ¤   virtual BOOL OnInitDialog();
da8bfa ¤   afx_msg void OnCheckSleep();
9d2150 ¤   afx_msg void OnCheckAutoUnmount();
2e94dc ¤   afx_msg void OnChangeTimeout();
3d698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
474322 ¤   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
156625 ¤   afx_msg void OnCheckPrevent();
d12e09 ¤   //}}AFX_MSG
d3af5a
c22409 ¤   DECLARE_MESSAGE_MAP()
c682f7 };
4daf5a
40c18c //{{AFX_INSERT_LOCATION}}
afaf5a
06beba #endif¤ // ] Included_CPrefsAutoUnmountPage_h
--0433 0002453ecdd401100bd Page 1 of CPrefsUnmountHotKeyPage.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
eaa7ba // CPrefsUnmountHotKeyPage.cpp
23465d //
75f893 // Implementation of class CPrefsUnmountHotKeyPage.
941bc3 //////////////////////////////////////////////////////////////////////////////
08af5a
1c347d // $Id: CPrefsUnmountHotKeyPage.cpp,v 1.1.2.8 1998/07/06 08:57:16 nryan Exp $
4caf5a
c9cbce // Copyright (C) 1998 by Network Associates, Inc.
3471ae // All rights reserved.
d6af5a
f99e12 #include "StdAfx.h"
40af5a
ad9bcf #include "Required.h"
25bfe9 #include "UtilityFunctions.h"
78af5a
56fdcb #include "CPGPdiskAppRegistry.h"
c87470 #include "CPrefsUnmountHotKeyPage.h"
59c411 #include "Globals.h"
b44713 #include "PGPdiskHelpIds.h"
30af5a
94af5a
066cc2 /////////////////////
b33a71 // Context help array
236cc2 /////////////////////
f8af5a
1677bf static PGPUInt32 HelpIds[] =
a4bb36 {
e5498c ¤   IDC_HOTKEY_CHECK,¤  ¤   IDH_PGPDISKAPP_PREFSHKHOTKEYCHECK,·
2d2a1d ¤   IDC_HOTKEY_EDIT,¤   ¤   IDH_PGPDISKAPP_PREFSHKHOTKEYEDIT,·
f6ce3c ¤   0,0·
3c82f7 };
fcaf5a
26af5a
5883f5 ///////////////////////////
20b249 // MFC specific definitions
a185ed ///////////////////////////·
4eaf5a
12b7c4 BEGIN_MESSAGE_MAP(CPrefsUnmountHotKeyPage, CPropertyPage)
2fc2df ¤   //{{AFX_MSG_MAP(CPrefsUnmountHotKeyPage)
505534 ¤   ON_BN_CLICKED(IDC_HOTKEY_CHECK, OnHotKeyCheck)
d4f89c ¤   ON_EN_CHANGE(IDC_HOTKEY_EDIT, OnHotKeyChange)
08db65 ¤   ON_WM_HELPINFO()
4d044a ¤   //}}AFX_MSG_MAP
aeaf28 END_MESSAGE_MAP()
5eaf5a
eeaf5a
b97cc3 ///////////////////////////////////////////////////////////////////////////
f6c747 // CPrefsUnmountHotKeyPage public custom functions and non-default handlers
af7cc3 ///////////////////////////////////////////////////////////////////////////
f6af5a
e87ea7 IMPLEMENT_DYNCREATE(CPrefsUnmountHotKeyPage, CPropertyPage)
f4af5a
0e97ff // The CPrefsUnmountHotKeyPage default constructor.
77af5a
3bc020 CPrefsUnmountHotKeyPage::CPrefsUnmountHotKeyPage()
345839 ¤   ·: CPropertyPage(CPrefsUnmountHotKeyPage::IDD)
37bb36 {
f410c7 ¤   //{{AFX_DATA_INIT(CPrefsUnmountHotKeyPage)
44b085 ¤   mHotKeyEnabledValue = FALSE;
75b1e8 ¤   //}}AFX_DATA_INIT
12af5a
77218f ¤   // Exorcise the big help button.
246a0f ¤   m_psp.dwFlags &= ~PSP_HASHELP;
e3efe6 }
7faf5a
492c8b // The CPrefsUnmountHotKeyPage destructor.
a0af5a
576ba0 CPrefsUnmountHotKeyPage::~CPrefsUnmountHotKeyPage()
34bb36 {
e7efe6 }
24af5a
--cf36 000155f53ce401100bd Page 2 of CPrefsUnmountHotKeyPage.cpp
e0af5a
8d1bc3 //////////////////////////////////////////////////////////////////////////////
951f29 // CPrefsUnmountHotKeyPage protected custom functions and non-default handlers
c51bc3 //////////////////////////////////////////////////////////////////////////////
fcaf5a
c981ff // The CPrefsUnmountHotKeyPage data exchange function.
51af5a
22c823 void·
7e37eb CPrefsUnmountHotKeyPage::DoDataExchange(CDataExchange *pDX)
dabb36 {
d278f1 ¤   try
28c7a1 ¤   {
9922a9 ¤   ¤   CPropertyPage::DoDataExchange(pDX);
9caf5a
85dec7 ¤   ¤   //{{AFX_DATA_MAP(CPrefsUnmountHotKeyPage)
e24e73 ¤   ¤   DDX_Control(pDX, IDC_HOTKEY_EDIT, mHotKeyBox);
cd2306 ¤   ¤   DDX_Check(pDX, IDC_HOTKEY_CHECK, mHotKeyEnabledValue);
ba3376 ¤   ¤   //}}AFX_DATA_MAP
4b9371 ¤   }
873c88 ¤   catch (CMemoryException *ex)
91c7a1 ¤   {
236adc ¤   ¤   ex->Delete();
249371 ¤   }
83efe6 }
bcaf5a
086645 // OnHotKeyChange is called when the user changes the hot key.
3eaf5a
f2c823 void·
0c11fc CPrefsUnmountHotKeyPage::OnHotKeyChange()·
04bb36 {
efd5f9 ¤   SetModified(TRUE);
42efe6 }
c3af5a
f6e430 // OnHotKeyCheck is called when the user hits the hot key enabled check box.
64ca06 // We disable or enable the hot key control as necessary.
6faf5a
9bc823 void·
2a7255 CPrefsUnmountHotKeyPage::OnHotKeyCheck()·
b6bb36 {
99f02e ¤   SetModified(TRUE);¤
35364d ¤   UpdateData(TRUE);
16af5a
52cce5 ¤   if (mHotKeyEnabledValue)
14d424 ¤   ¤   mHotKeyBox.EnableWindow(TRUE);
e00e24 ¤   else
e1fc84 ¤   ¤   mHotKeyBox.EnableWindow(FALSE);
5eefe6 }
91af5a
30af5a
0b460c /////////////////////////////////////////////////////////////
74cbdd // CPrefsUnmountHotKeyPage protected default message handlers
4e460c /////////////////////////////////////////////////////////////
9caf5a
181655 // OnApply is overridden to apply the changes the user made to the
64a353 // application, but we don't save them to the registry.
2faf5a
547efe BOOL·
dfe8a7 CPrefsUnmountHotKeyPage::OnApply()·
30bb36 {
b3364d ¤   UpdateData(TRUE);
63af5a
e010ba ¤   App->mHotKeyCode¤   = mHotKeyBox.GetHotKey();
e30dde ¤   App->mHotKeyEnabled¤= mHotKeyEnabledValue;
03af5a
2af1ed ¤   SetModified(FALSE);
eaaf5a
aeea0a ¤   // Tell the driver.
85d7b3 ¤   App->SetDriverPrefsFromApp();
7eaf5a
b6eb1f ¤   return CPropertyPage::OnApply();
85efe6 }
15af5a
--3020 00151aff363401100bd Page 3 of CPrefsUnmountHotKeyPage.cpp
2a8cca // OnHelpInfo handles context-sensitive help.
9aaf5a
877efe BOOL·
d2a8e6 CPrefsUnmountHotKeyPage::OnHelpInfo(HELPINFO *pHelpInfo)
06bb36 {
5529b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
94e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
c0c7a1 ¤   {
58ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
5e6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
e39371 ¤   }
2eaf5a
5fc2e7 ¤   return TRUE;
21efe6 }
16af5a
12360f // OnInitDialog is overwritten to perform property page initialization.
cbaf5a
767efe BOOL·
dd9ccc CPrefsUnmountHotKeyPage::OnInitDialog()·
c3bb36 {
ab4541 ¤   CPropertyPage::OnInitDialog();
47af5a
b4356b ¤   // Initialize the check box and hot key control.
1f721d ¤   mHotKeyBox.SetHotKey(App->mHotKeyCode);
bd1c1d ¤   mHotKeyEnabledValue = App->mHotKeyEnabled;
5aaf5a
696a6b ¤   if (!mHotKeyEnabledValue)
e9fc84 ¤   ¤   mHotKeyBox.EnableWindow(FALSE);
63af5a
9102a1 ¤   UpdateData(FALSE);
01af5a
d7c2e7 ¤   return TRUE;
5defe6 }
a5af5a
3fea63 // OnOK is overridden to save the new value to the registry.
ffaf5a
eac823 void·
62c5ec CPrefsUnmountHotKeyPage::OnOK()·
75bb36 {
7a7d36 ¤   DualErr derr;
65af5a
7e364d ¤   UpdateData(TRUE);
a3af5a
8a10ba ¤   App->mHotKeyCode¤   = mHotKeyBox.GetHotKey();
ab0dde ¤   App->mHotKeyEnabled¤= mHotKeyEnabledValue;
c1af5a
2ff9f6 ¤   derr = App->SetRegistryPrefs();
3faf5a
114bb3 ¤   if (derr.IsError())
5dc7a1 ¤   {
4f5ba1 ¤   ¤   ReportError(kPGDMajorError_PreferencesAccessFailed, derr);
309371 ¤   }
e20e24 ¤   else
7bc7a1 ¤   {
64b8ea ¤   ¤   App->UpdatePGPdiskResident();
849371 ¤   }
b4af5a
422e36 ¤   CPropertyPage::OnOK();
51efe6 }
--8edc 00154f727be401100be Page 1 of CPrefsUnmountHotKeyPage.h
541bc3 //////////////////////////////////////////////////////////////////////////////
7292f0 // CPrefsUnmountHotKeyPage.h
a7465d //
94f983 // Declaration of class CPrefsUnmountHotKeyPage.
c21bc3 //////////////////////////////////////////////////////////////////////////////
10af5a
cb2ada // $Id: CPrefsUnmountHotKeyPage.h,v 1.1.2.4 1998/07/06 08:57:16 nryan Exp $
91af5a
fecbce // Copyright (C) 1998 by Network Associates, Inc.
fa71ae // All rights reserved.
91af5a
ad0bca #ifndef Included_CPrefsUnmountHotKeyPage_h¤ // ]
dc65a1 #define Included_CPrefsUnmountHotKeyPage_h
8faf5a
58336c #include "CSuperHotKeyControl.h"
38ab81 #include "Resource.h"
b3af5a
67af5a
6e512c ////////////////////////////////
9514bc // Class CPrefsUnmountHotKeyPage
9d512c ////////////////////////////////
59af5a
26cc74 class CPrefsUnmountHotKeyPage : public CPropertyPage
40bb36 {
3cfd5e ¤   DECLARE_DYNCREATE(CPrefsUnmountHotKeyPage)
b3af5a
5d5ed4 public:
5cfc9d ¤   CPrefsUnmountHotKeyPage();
1c2eec ¤   ~CPrefsUnmountHotKeyPage();
24af5a
b25d84 ¤   //{{AFX_DATA(CPrefsUnmountHotKeyPage)
138630 ¤   enum { IDD = IDD_PROP_HOTKEY };
54c476 ¤   CSuperHotKeyControl¤mHotKeyBox;
56ec69 ¤   BOOL¤   mHotKeyEnabledValue;
b55139 ¤   //}}AFX_DATA
23af5a
9b75d5 ¤   //{{AFX_VIRTUAL(CPrefsUnmountHotKeyPage)
3267d4 ¤   public:
4c5762 ¤   virtual void OnOK();
2aba9c ¤   virtual BOOL OnApply();
adc369 ¤   protected:
623e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
dbaf53 ¤   //}}AFX_VIRTUAL
8eaf5a
21a2d3 protected:
68068d ¤   //{{AFX_MSG(CPrefsUnmountHotKeyPage)
dbf17a ¤   virtual BOOL OnInitDialog();
e21ef3 ¤   afx_msg void OnHotKeyChange();
2b6ea2 ¤   afx_msg void OnHotKeyCheck();
e8698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
782e09 ¤   //}}AFX_MSG
daaf5a
c62409 ¤   DECLARE_MESSAGE_MAP()
4f82f7 };
40af5a
00c18c //{{AFX_INSERT_LOCATION}}
8caf5a
545670 #endif¤ // ] Included_CPrefsUnmountHotKeyPage_h
--cce3 00066571e93401100bf Page 1 of CPublicKeyDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
1ade64 // CPublicKeyDialog.cpp
9e465d //
c4df38 // Implementation of the CPublicKeyDialog class.
a41bc3 //////////////////////////////////////////////////////////////////////////////
c4af5a
2c892a // $Id: CPublicKeyDialog.cpp,v 1.1.2.7 1998/07/22 01:19:25 nryan Exp $
e0af5a
accbce // Copyright (C) 1998 by Network Associates, Inc.
8571ae // All rights reserved.
45af5a
ca9e12 #include "StdAfx.h"
d3af5a
ca9bcf #include "Required.h"
aaaf5a
59ea4b #if PGPDISK_PUBLIC_KEY
a8af5a
3bb2b1 #include "PGPclx.h"
b6e8b2 #include "pflPrefs.h"
8e4720 #include "pflPrefTypes.h"
713991 #include "pgpAdminPrefs.h"
832f8d #include "pgpErrors.h"
624919 #include "pgpUtilities.h"
b3af5a
3df4f6 #include "PGPdiskPublicKeyUtils.h"
99cf11 #include "CPublicKeyDialog.h"
e8af5a
ceaf5a
f109b7 ////////////
7be738 // Constants
d709b7 ////////////
75af5a
6a25a3 PGPUInt32 kPGPdiskRecipReadOnlyCheckID = 1;
8faf5a
c7ea0a static LPCSTR kPGPdiskRecipReadOnlyCheckTitle = "Read-only";
85af5a
93af5a
ff19ca /////////////////////////////////////////////////
341291 // Class CPublicKeyDialog public member functions
db19ca /////////////////////////////////////////////////
ddaf5a
1ce2dd // The CPublicKeyDialog constructor.
92764e CPublicKeyDialog::CPublicKeyDialog()
e0bb36 {
bb0e7a ¤   mGotNewKeys = FALSE;
d4af5a
fac532 ¤   mNewRecipKeys = NULL;
6ff3ae ¤   mNumNewKeys = 0;
3cefe6 }
c2af5a
15c0dd // The CPublicKeyDialog destructor.
4b658a CPublicKeyDialog::~CPublicKeyDialog()
fdbb36 {
932cc4 ¤   CleanUp();
53efe6 }
cfaf5a
bc0506 // CleanUp frees the associated keys if allocated.
2eaf5a
3cc823 void·
af0eb2 CPublicKeyDialog::CleanUp()
12bb36 {
fa042e ¤   if (mGotNewKeys)
57c7a1 ¤   {
93d545 ¤   ¤   PGPFreeData(mNewRecipKeys);
eef4c7 ¤   ¤   PGPFreeKeySet(mNewKeySet);
9eaf5a
204c66 ¤   ¤   mNewRecipKeys = NULL;
59427f ¤   ¤   mNumNewKeys = 0;
0aaf5a
173a27 ¤   ¤   mGotNewKeys = FALSE;
fb9371 ¤   }
66efe6 }
--db82 00014c85681401100bf Page 2 of CPublicKeyDialog.cpp
e0af5a
f11f89 // AskForKeys displays the recipient dialog.
e5af5a
f79d6b DualErr¤
ede9cc CPublicKeyDialog::AskForKeys(
975a0a ¤   PGPContextRef¤  ¤   context,·
0ff2f7 ¤   PGPKeySetRef¤   ¤   allKeys,·
d0d4b3 ¤   PGPRecipientSpec¤   *oldRecipKeys,·
5ac183 ¤   PGPUInt32¤  ¤   ¤   numRecipKeys)
4dbb36 {
32705b ¤   DualErr¤¤   ¤   ¤   derr;
7f8e95 ¤   PGPBoolean¤ ¤   ¤   gotClientPrefs, gotOptionsList, marginalIsInvalid;
3b4b5d ¤   PGPBoolean¤ ¤   ¤   showMarginalValidity, warnOnADKs;
2ef7f4 ¤   PGPMemoryMgrRef¤¤   memoryMgr;
6b2323 ¤   PGPPrefRef¤ ¤   ¤   clientPrefsRef¤ = kInvalidPGPPrefRef;
343015 ¤   PGPOptionListRef¤   recipientOptions;
64afd1 ¤   PGPUInt32¤  ¤   ¤   newKeysReadOnly;
6faf5a
f3be29 #if PGP_BUSINESS_SECURITY
6daf5a
a7b051 ¤   PGPBoolean¤ ¤   ¤   gotAdminPrefs¤  = FALSE;
87af01 ¤   PGPPrefRef¤ ¤   ¤   adminPrefsRef¤  = kInvalidPGPPrefRef;¤
1aaf5a
7797b2 #endif¤ // PGP_BUSINESS_SECURITY
bfaf5a
d2df69 ¤   gotClientPrefs = gotOptionsList = FALSE;
d5af5a
1b4326 ¤   pgpAssert(PGPContextRefIsValid(context));
75bf3a ¤   pgpAssert(PGPKeySetRefIsValid(allKeys));
21af5a
718604 ¤   // Cleanup.
722cc4 ¤   CleanUp();
b6af5a
d68a4a ¤   // Get memory manager ref.
dfcc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
f5af5a
c6e1bf ¤   // Open client prefs.
f84580 ¤   derr = PGPclOpenClientPrefs(memoryMgr, &clientPrefsRef);
3eb0fe ¤   gotClientPrefs = derr.IsntError();
61af5a
21be29 #if PGP_BUSINESS_SECURITY
73af5a
a24cc4 ¤   // Open admin prefs.
712361 ¤   if (derr.IsntError())
9fc7a1 ¤   {
96b4e0 ¤   ¤   derr = PGPclOpenAdminPrefs(memoryMgr, &adminPrefsRef, TRUE);
eeb785 ¤   ¤   gotAdminPrefs = derr.IsntError();
d29371 ¤   }
f2af5a
2597b2 #endif¤ // PGP_BUSINESS_SECURITY
35af5a
3ca917 ¤   // Build option list for the recipient dialog.
4b2361 ¤   if (derr.IsntError())
fac7a1 ¤   {
069df8 ¤   ¤   PGPOptionListRef defRecipOption;
e5af5a
2190d2 ¤   ¤   PGPGetPrefBoolean(clientPrefsRef, kPGPPrefDisplayMarginalValidity,·
09bda3 ¤   ¤   ¤   &showMarginalValidity);
84a776 ¤   ¤   PGPGetPrefBoolean(clientPrefsRef, kPGPPrefMarginalIsInvalid,
2b024e ¤   ¤   ¤   &marginalIsInvalid);
974b0d ¤   ¤   PGPGetPrefBoolean(clientPrefsRef, kPGPPrefWarnOnADK, &warnOnADKs);
f9af5a
fc5a87 ¤   ¤   if (numRecipKeys > 0)
f55b34 ¤   ¤   {
d8cbfb ¤   ¤   ¤   defRecipOption = PGPOUIDefaultRecipients(context, numRecipKeys,·
165f31 ¤   ¤   ¤   ¤   oldRecipKeys);
380fe4 ¤   ¤   }
7d0e1d ¤   ¤   else
d05b34 ¤   ¤   {
9ba33d ¤   ¤   ¤   defRecipOption = PGPONullOption(context);
c90fe4 ¤   ¤   }
14af5a
--6114 00188458c00401100bf Page 3 of CPublicKeyDialog.cpp
d784eb ¤   ¤   derr = PGPBuildOptionList(context, &recipientOptions, defRecipOption,·
a527bc ¤   ¤   ¤   PGPOUIDisplayMarginalValidity(context, showMarginalValidity),·
20bdb5 ¤   ¤   ¤   PGPOUIIgnoreMarginalValidity(context, marginalIsInvalid),·
2eec07 ¤   ¤   ¤   PGPOUIRecipientList(context, &mNumNewKeys, &mNewRecipKeys),·
21af5a
fcc066 ¤   ¤   ¤   PGPOUIDialogOptions(context,·
3093ca ¤   ¤   ¤   ¤   PGPOUICheckbox(context, kPGPdiskRecipReadOnlyCheckID,·
b8433e ¤   ¤   ¤   ¤   ¤   kPGPdiskRecipReadOnlyCheckTitle, kEmptyString, 0,·
5a764f ¤   ¤   ¤   ¤   ¤   &newKeysReadOnly),·
a12d0d ¤   ¤   ¤   ¤   PGPOLastOption(context)),·
e4af5a
8ce5ff ¤   ¤   ¤   PGPOLastOption(context));
8baf5a
4ff13a ¤   ¤   gotOptionsList = derr.IsntError();
1f9371 ¤   }
caaf5a
a52361 ¤   if (derr.IsntError())
31c7a1 ¤   {
098ca6 ¤   ¤   PGPAdditionalRecipientRequestEnforcement arrEnforcement;
10af5a
bec201 ¤   ¤   // Check enforcement.
71d5d8 ¤   ¤   arrEnforcement = kPGPARREnforcement_Warn;
77af5a
45377d ¤   #if PGP_BUSINESS_SECURITY
91af5a
fc5b34 ¤   ¤   {
6d9d30 ¤   ¤   ¤   DualErr¤¤   dummyErr;
f35577 ¤   ¤   ¤   PGPBoolean¤ enforceRemoteADKClass;
8a87c7 ¤   ¤   ¤
410b83 ¤   ¤   ¤   dummyErr = PGPGetPrefBoolean(adminPrefsRef,·
216128 ¤   ¤   ¤   ¤   kPGPPrefEnforceRemoteADKClass, &enforceRemoteADKClass);
e02b85 ¤   ¤   ¤   ¤
52ed78 ¤   ¤   ¤   if (dummyErr.IsntError() && enforceRemoteADKClass)
04f776 ¤   ¤   ¤   {
f6f415 ¤   ¤   ¤   ¤   arrEnforcement = kPGPARREnforcement_Strict;
7ba3a6 ¤   ¤   ¤   }
4f0fe4 ¤   ¤   }
23af5a
b0b54c ¤   #endif // PGP_BUSINESS_SECURITY
7caf5a
0abe58 ¤   ¤   // Show the recipient dialog.
77898f ¤   ¤   derr = PGPRecipientDialog(context, allKeys, TRUE, &mNewKeySet,
e4b96f ¤   ¤   ¤   recipientOptions, PGPOUIEnforceAdditionalRecipientRequests(
6e528b ¤   ¤   ¤   context, arrEnforcement, warnOnADKs), PGPOLastOption(context));
56af5a
78511d ¤   ¤   mGotNewKeys = derr.IsntError();
489371 ¤   }
86af5a
642361 ¤   if (derr.IsntError())
59c7a1 ¤   {
c77bbd ¤   ¤   mNewKeysReadOnly = (newKeysReadOnly == 1);
139371 ¤   }
8caf5a
64b83d ¤   if (gotOptionsList)
bd77af ¤   ¤   PGPFreeOptionList(recipientOptions);
34af5a
08be29 #if PGP_BUSINESS_SECURITY
6eaf5a
2f4def ¤   if (gotAdminPrefs)
93db34 ¤   ¤   PGPclCloseAdminPrefs(adminPrefsRef, FALSE);
f0af5a
ab97b2 #endif¤ // PGP_BUSINESS_SECURITY
24af5a
16d537 ¤   if (gotClientPrefs)
7897cc ¤   ¤   PGPclCloseClientPrefs(clientPrefsRef, FALSE);
4eaf5a
3733e3 ¤   return derr;
acefe6 }
a0af5a
8838e4 #endif¤ // PGPDISK_PUBLIC_KEY
--1295 00114a71d81401100c0 Page 1 of CPublicKeyDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
200069 // CPublicKeyDialog.h
e0465d //
0e191c // Declaration of class CPublicKeyDialog.
511bc3 //////////////////////////////////////////////////////////////////////////////
4daf5a
63fad1 // $Id: CPublicKeyDialog.h,v 1.1.2.5 1998/07/22 01:19:26 nryan Exp $
a1af5a
94cbce // Copyright (C) 1998 by Network Associates, Inc.
2071ae // All rights reserved.
b3af5a
524df1 #ifndef Included_CPublicKeyDialog_h¤// [
9cb513 #define Included_CPublicKeyDialog_h
8faf5a
36ea4b #if PGPDISK_PUBLIC_KEY
15af5a
741970 #include "PGPKeys.h"
9fcbc9 #include "PGPUserInterface.H"
a9af5a
2b3a85 #include "DualErr.h"
cfaf5a
7eaf5a
319f73 /////////////////////////
c43de0 // Class CPublicKeyDialog
0d9f73 /////////////////////////
7eaf5a
df47de class CPublicKeyDialog
8bbb36 {
d7af5a
bb5ed4 public:
daed19 ¤   PGPBoolean¤ ¤   ¤   mGotNewKeys, mNewKeysReadOnly;
e9d611 ¤   PGPKeySetRef¤   ¤   mNewKeySet;
3f959e ¤   PGPRecipientSpec¤   *mNewRecipKeys;
f83355 ¤   PGPUInt32¤  ¤   ¤   mNumNewKeys;
4baf5a
27c867 ¤   ¤   ¤   CPublicKeyDialog();
18d7a3 ¤   ¤   ¤   ~CPublicKeyDialog();
ffaf5a
8a6d0e ¤   void¤   CleanUp();
4baf5a
c5d03c ¤   DualErr¤AskForKeys(PGPContextRef context, PGPKeySetRef allKeys,·
523e38 ¤   ¤   ¤   ¤   PGPRecipientSpec *oldRecipKeys, PGPUInt32 numRecipKeys);
26af5a
8782f7 };
0faf5a
6238e4 #endif¤ // PGPDISK_PUBLIC_KEY
9aaf5a
1456c6 #endif¤ // Included_CPublicKeyDialog_h
--cbe5 0008a5dea86401100c1 Page 1 of CSavePGPdiskDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
e3f697 // CSavePGPdiskDialog.cpp
27465d //
26f650 // Implementation of the CSavePGPdiskDialog class.
0e1bc3 //////////////////////////////////////////////////////////////////////////////
afaf5a
a6c0fe // $Id: CSavePGPdiskDialog.cpp,v 1.2.2.17.2.1 1998/08/22 01:55:36 nryan Exp $
21af5a
5dcbce // Copyright (C) 1998 by Network Associates, Inc.
2371ae // All rights reserved.
14af5a
e79e12 #include "StdAfx.h"
d8af5a
6b9bcf #include "Required.h"
db3db7 #include "FatUtils.h"
f6c16a #include "PGPdiskFileFormat.h"
e4babe #include "PGPdiskRegistry.h"
60993c #include "StringAssociation.h"
a2bfe9 #include "UtilityFunctions.h"
d4af5a
cd37c7 #include "CSavePGPdiskDialog.h"
7ff037 #include "File.h"
fac411 #include "Globals.h"
a14713 #include "PGPdiskHelpIds.h"
70af5a
47af5a
2a83f5 ///////////////////////////
5cb249 // MFC specific definitions
9183f5 ///////////////////////////
caaf5a
434d13 BEGIN_MESSAGE_MAP(CSavePGPdiskDialog, CFileDialog)
820c38 ¤   //{{AFX_MSG_MAP(CSavePGPdiskDialog)
64044a ¤   //}}AFX_MSG_MAP
54af28 END_MESSAGE_MAP()
32af5a
85af5a
53dd36 //////////////////////////////////////////////////////////////////////
54b811 // CSavePGPdiskDialog public custom functions and non-default handlers
84dd36 //////////////////////////////////////////////////////////////////////
9caf5a
c226b3 IMPLEMENT_DYNAMIC(CSavePGPdiskDialog, CFileDialog)
11af5a
21f2f1 // The CSavePGPdiskDialog default constructor.
8aaf5a
81e6dd CSavePGPdiskDialog::CSavePGPdiskDialog(SaveDialogType dlgType, CWnd *pParent)
76af5a
f38bde ¤   : CFileDialog(FALSE, &kPGPdiskFileExtension[1], NULL,·
7c0cb9 ¤   ¤   OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,·
e88234 ¤   ¤   GetCommonString(kPGPdiskSDTSaveFilter), pParent)
9cbb36 {
ea3700 ¤   mSaveDialogType = dlgType;
5aaf5a
6871ab ¤   m_ofn.Flags |= OFN_PATHMUSTEXIST | OFN_NOTESTFILECREATE;
75af5a
2db6e2 ¤   // Finally initialize the title according to the dialog type.
2b3ebc ¤   switch (mSaveDialogType)
30c7a1 ¤   {
99d4c2 ¤   case kSDT_Create:
838920 ¤   ¤   m_ofn.lpstrTitle = GetCommonString(kPGPdiskSDTCreateDialogTitle);
5d2f68 ¤   ¤   break;
1baf5a
552f72 ¤   default:
688f52 ¤   ¤   pgpAssert(FALSE);
d42f68 ¤   ¤   break;
479371 ¤   }
49efe6 }
97af5a
b53b4c // AskForPath is a wrapper around DoModal.
eaaf5a
9a2292 DualErr·
fba344 CSavePGPdiskDialog::AskForPath(CString *path, LPCSTR defaultPath)
8abb36 {
--7711 0008991b1f4401100c1 Page 2 of CSavePGPdiskDialog.cpp
507d36 ¤   DualErr derr;
c4af5a
ccf6da ¤   pgpAssertAddrValid(path, CString);
f7af5a
0278f1 ¤   try
38c7a1 ¤   {
5436c7 ¤   ¤   CString¤¤   initialDir, initialName;
b90645 ¤   ¤   DualErr¤¤   dirValidErr;
7c2e7f ¤   ¤   PGPBoolean¤ gotDirFromRegistry¤ = FALSE;
3c0187 ¤   ¤   PGPUInt32¤  result;
87af5a
fad7be ¤   ¤   // If default path is not provided, get default info from registry.
ead0ed ¤   ¤   if (defaultPath && (strlen(defaultPath) > 0))
705b34 ¤   ¤   {
018bef ¤   ¤   ¤   // Extract the initial directory.
d8591f ¤   ¤   ¤   GetDirectory(defaultPath, &initialDir);
030661 ¤   ¤   ¤   GetBareName(defaultPath, &initialName, kBNE_ShowExt);
7d0fe4 ¤   ¤   }
ac0e1d ¤   ¤   else
765b34 ¤   ¤   {
890b49 ¤   ¤   ¤   gotDirFromRegistry = TRUE;
62af5a
c891fb ¤   ¤   ¤   PGPdiskGetPrefString(kRegistryLastSaveDirKey, kEmptyString,·
2e0b4d ¤   ¤   ¤   ¤   &initialDir);
5e0fe4 ¤   ¤   }
8eaf5a
c2ac7b ¤   ¤   // Is the directory OK to use?
592bbf ¤   ¤   if (!App->IsDirectoryValid(initialDir))
db5b34 ¤   ¤   {
756fb1 ¤   ¤   ¤   dirValidErr = DualErr(kPGDMinorError_DirectoryNotFound);
010fe4 ¤   ¤   }
1b3c70 ¤   ¤   else if (App->IsDirectoryReadOnly(initialDir))
0d5b34 ¤   ¤   {
b3f876 ¤   ¤   ¤   dirValidErr = DualErr(kPGDMinorError_DirectoryWriteProtected);
0e0fe4 ¤   ¤   }
a10e1d ¤   ¤   else
bb5b34 ¤   ¤   {
df2663 ¤   ¤   ¤   PGPUInt64 bytesFree;
89af5a
0f944c ¤   ¤   ¤   // Fail if not enough space for any PGPdisk.
f4c519 ¤   ¤   ¤   if (App->HowMuchFreeSpace(initialDir, &bytesFree).IsntError())
12f776 ¤   ¤   ¤   {
b4cab2 ¤   ¤   ¤   ¤   PGPUInt32 kbFree = (PGPUInt32) (bytesFree/kBytesPerKb);
4aaf5a
06f286 ¤   ¤   ¤   ¤   if (kbFree < App->mPlatformMinKbSize)
a69f67 ¤   ¤   ¤   ¤   ¤   dirValidErr = DualErr(kPGDMinorError_DirectoryTooSmall);
fba3a6 ¤   ¤   ¤   }
410fe4 ¤   ¤   }
5baf5a
40e397 ¤   ¤   // If the directory isn't valid and it was user specified, fail.
8201c2 ¤   ¤   // Otherwise let the system choose a directory.
12c88f ¤   ¤   if (dirValidErr.IsError())
cc5b34 ¤   ¤   {
d6c5b6 ¤   ¤   ¤   if (gotDirFromRegistry)
a185f9 ¤   ¤   ¤   ¤   initialDir = kEmptyString;
8fbb8c ¤   ¤   ¤   else
cf7129 ¤   ¤   ¤   ¤   derr = dirValidErr;
b00fe4 ¤   ¤   }
d1af5a
2768c5 ¤   ¤   // If OK initialize the default directory and default filename.
57aa35 ¤   ¤   if (derr.IsntError())
5b5b34 ¤   ¤   {
30a921 ¤   ¤   ¤   // Don't use system default name.
c0a893 ¤   ¤   ¤   if (initialName.IsEmpty() ||·
87be5d ¤   ¤   ¤   ¤   (initialName.Find("New PGPdisk Volume") != -1))
6bf776 ¤   ¤   ¤   {
96300e ¤   ¤   ¤   ¤   GetInitialPGPdiskName(initialDir, &initialName);
aaa3a6 ¤   ¤   ¤   }
0baf5a
59b81f ¤   ¤   ¤   m_ofn.lpstrInitialDir = initialDir;
4228b1 ¤   ¤   ¤   m_ofn.lpstrFile = initialName.GetBuffer(kMaxStringSize);
89af5a
--6c37 0006a1bdeb3401100c1 Page 3 of CSavePGPdiskDialog.cpp
702f23 ¤   ¤   ¤   // Show the dialog.
9951f0 ¤   ¤   ¤   result = DoModal();
0baf5a
841b96 ¤   ¤   ¤   // Return an appropriate result.
6d4362 ¤   ¤   ¤   switch (result)
5df776 ¤   ¤   ¤   {
900389 ¤   ¤   ¤   case IDOK:
01167e ¤   ¤   ¤   ¤   (* path) = GetPathName();
78f622 ¤   ¤   ¤   ¤   break;
ceaf5a
141763 ¤   ¤   ¤   case -1:
de04c9 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
81f622 ¤   ¤   ¤   ¤   break;
f9af5a
18930a ¤   ¤   ¤   case IDCANCEL:
2f95a9 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
8ef622 ¤   ¤   ¤   ¤   break;
3ba3a6 ¤   ¤   ¤   }
42af5a
e14357 ¤   ¤   ¤   initialName.ReleaseBuffer();
dd0fe4 ¤   ¤   }
349371 ¤   }
2d3c88 ¤   catch (CMemoryException *ex)
4dc7a1 ¤   {
f9ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
a76adc ¤   ¤   ex->Delete();
a99371 ¤   }
cbaf5a
3733e3 ¤   return derr;
4defe6 }
b0af5a
9baf5a
01186d /////////////////////////////////////////////////////////////////////////
0f391f // CSavePGPdiskDialog protected custom functions and non-default handlers
5d186d /////////////////////////////////////////////////////////////////////////
2eaf5a
8477db // GetInitialPGPdiskName constructs an appropriate initial PGPdisk name.
20af5a
5dc823 void·
47db8e CSavePGPdiskDialog::GetInitialPGPdiskName(
e41d29 ¤   LPCSTR¤ initialDir,·
bb64fe ¤   CString¤*initialName)
cbbb36 {
791f1a ¤   pgpAssertAddrValid(initialName, CString);
92af5a
e778f1 ¤   try
c1c7a1 ¤   {
d91128 ¤   ¤   CString¤¤   fullPath, csInitialDir, postfixString;
97ad82 ¤   ¤   PGPUInt32¤  i¤  = 1;
b7af5a
042283 ¤   ¤   initialName->Format(kDefaultNewDiskName, "");
6b657e ¤   ¤   csInitialDir = initialDir;
8eaf5a
723a0b ¤   ¤   if (csInitialDir.IsEmpty())
71f3a4 ¤   ¤   ¤   GetCurrentDirectory(&csInitialDir);
581b52 ¤   ¤
044f53 ¤   ¤   if (!csInitialDir.IsEmpty() &&·
dc63a3 ¤   ¤   ¤   (csInitialDir.GetAt(csInitialDir.GetLength() - 1) != '\\'))
565b34 ¤   ¤   {
09e86c ¤   ¤   ¤   csInitialDir += "\\";
c00fe4 ¤   ¤   }
05af5a
be708a ¤   ¤   while (TRUE)
205b34 ¤   ¤   {
cd0019 ¤   ¤   ¤   initialName->Format(kDefaultNewDiskName, postfixString);
f879de ¤   ¤   ¤   fullPath = csInitialDir + (* initialName);¤
5c67c5 ¤
cb8ab9 ¤   ¤   ¤   if (!App->IsFileValid(fullPath))
56f622 ¤   ¤   ¤   ¤   break;
9aaf5a
16498e ¤   ¤   ¤   postfixString.Format("%d", i++);
6a0fe4 ¤   ¤   }
--9ad7 000048a05fe401100c1 Page 4 of CSavePGPdiskDialog.cpp
a19371 ¤   }
833c88 ¤   catch (CMemoryException *ex)
2fc7a1 ¤   {
736adc ¤   ¤   ex->Delete();
b69371 ¤   }
88efe6 }
e2af5a
c0ee62 // UpdateSaveDialogPrefs stores the location of the chosen directory.
bdaf5a
afc823 void·
02c697 CSavePGPdiskDialog::UpdateSaveDialogPrefs()
dbbb36 {
8089a8 ¤   // Update the last save directory in the registry.
6178f1 ¤   try
62c7a1 ¤   {
8cbd3e ¤   ¤   CString dir, path;
15af5a
a92d5a ¤   ¤   path = GetPathName();
211b52 ¤   ¤
88132f ¤   ¤   GetDirectory(path, &dir);
d4c576 ¤   ¤   PGPdiskSetPrefString(kRegistryLastSaveDirKey, dir);
279371 ¤   }
7d3c88 ¤   catch (CMemoryException *ex)
63c7a1 ¤   {
dd6adc ¤   ¤   ex->Delete();
bf9371 ¤   }
c2efe6 }
e6af5a
4d392d // The CSavePGPdiskDialog default data-exchange function.
27af5a
1fc823 void·
d61394 CSavePGPdiskDialog::DoDataExchange(CDataExchange *pDX)
65bb36 {
9b78f1 ¤   try
d0c7a1 ¤   {
82f4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
6faf5a
ddce49 ¤   ¤   //{{AFX_DATA_MAP(CSavePGPdiskDialog)
ed3376 ¤   ¤   //}}AFX_DATA_MAP
319371 ¤   }
7e3c88 ¤   catch (CMemoryException *ex)
98c7a1 ¤   {
5f6adc ¤   ¤   ex->Delete();
b89371 ¤   }
c4efe6 }
0eaf5a
b93951 // OnFileNameOK is called when the user hits the OK button. We perform sanity
509cad // checking.
1aaf5a
547efe BOOL·
529f2f CSavePGPdiskDialog::OnFileNameOK()
13bb36 {
6ece5e ¤   PGPBoolean failThis = FALSE;
29af5a
b1dfe9 ¤   if (CFileDialog::OnFileNameOK() == 1)
98e102 ¤   ¤   return 1;
8faf5a
7978f1 ¤   try
7cc7a1 ¤   {
a3bd3e ¤   ¤   CString dir, path;
77af5a
052d5a ¤   ¤   path = GetPathName();
9e383e ¤   ¤   ·
d0132f ¤   ¤   GetDirectory(path, &dir);
03af5a
28715c ¤   ¤   // Is dir read-only?
e6c0ac ········if (App->IsDirectoryReadOnly(dir))
985b34 ¤   ¤   {
c0bd13 ¤   ¤   ¤   failThis = TRUE;
cd6de4 ¤   ¤   ¤   ReportError(kPGDMajorError_ChoseReadOnlyDirInCreate);
510fe4 ¤   ¤   }
04af5a
--eb0a 0006eba646a401100c1 Page 5 of CSavePGPdiskDialog.cpp
6e08b2 ¤   ¤   // If user is replacing a file, is that file in use?
370191 ¤   ¤   if (!failThis)
595b34 ¤   ¤   {
5b881c ¤   ¤   ¤   if (App->IsFileValid(path) && App->IsFileInUse(path))
92f776 ¤   ¤   ¤   {
3f0645 ¤   ¤   ¤   ¤   failThis = TRUE;
72a360 ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_ChoseReplaceFileInUse);
52a3a6 ¤   ¤   ¤   }
940fe4 ¤   ¤   }
99af5a
ca81a0 ¤   ¤   // Is there enough space?
340191 ¤   ¤   if (!failThis)
b75b34 ¤   ¤   {
b19d30 ¤   ¤   ¤   DualErr¤¤   dummyErr;
6d591b ¤   ¤   ¤   PGPUInt32¤  kbFree;
db7746 ¤   ¤   ¤   PGPUInt64¤  bytesFile, bytesFree;
37af5a
79678c ¤   ¤   ¤   // Get amount of free space on disk.
dfa045 ¤   ¤   ¤   dummyErr = App->HowMuchFreeSpace(dir, &bytesFree);
50af5a
679a97 ¤   ¤   ¤   if (dummyErr.IsntError())
8af776 ¤   ¤   ¤   {
c3dc20 ¤   ¤   ¤   ¤   kbFree = (PGPUInt32) (bytesFree / kBytesPerKb);
bdaf5a
05eb66 ¤   ¤   ¤   ¤   // If we are overwriting a file, add its size to free space.
c4374c ¤   ¤   ¤   ¤   if (App->IsFileValid(path))
b272c3 ¤   ¤   ¤   ¤   {
d7efb4 ¤   ¤   ¤   ¤   ¤   File existingFile;
dcaf5a
a3d2a6 ¤   ¤   ¤   ¤   ¤   dummyErr = existingFile.Open(path,·
1ea46f ¤   ¤   ¤   ¤   ¤   ¤   kOF_MustExist | kOF_ReadOnly);
e2af5a
759fbc ¤   ¤   ¤   ¤   ¤   if (dummyErr.IsntError())
1e4859 ¤   ¤   ¤   ¤   ¤   {
dc64b2 ¤   ¤   ¤   ¤   ¤   ¤   existingFile.GetLength(&bytesFile);
bd1c89 ¤   ¤   ¤   ¤   ¤   }
86af5a
b19fbc ¤   ¤   ¤   ¤   ¤   if (dummyErr.IsntError())
5e4859 ¤   ¤   ¤   ¤   ¤   {
7ef440 ¤   ¤   ¤   ¤   ¤   ¤   kbFree += (PGPUInt32) (bytesFile/kBytesPerKb);
8e1c89 ¤   ¤   ¤   ¤   ¤   }
5baf5a
714099 ¤   ¤   ¤   ¤   ¤   if (existingFile.Opened())
48c7a7 ¤   ¤   ¤   ¤   ¤   ¤   existingFile.Close();
df2613 ¤   ¤   ¤   ¤   }
09a3a6 ¤   ¤   ¤   }
4caf5a
d9ae0e ¤   ¤   ¤   // Finally check if we have enough size.
2c9a97 ¤   ¤   ¤   if (dummyErr.IsntError())
95f776 ¤   ¤   ¤   {
7b92fc ¤   ¤   ¤   ¤   if (App->mPlatformMinKbSize > kbFree)
c572c3 ¤   ¤   ¤   ¤   {
213b2d ¤   ¤   ¤   ¤   ¤   failThis = TRUE;
dc0f00 ¤   ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_ChoseTooSmallDirInCreate);
af2613 ¤   ¤   ¤   ¤   }
eaa3a6 ¤   ¤   ¤   }
830fe4 ¤   ¤   }
c19371 ¤   }
603c88 ¤   catch (CMemoryException *ex)
02c7a1 ¤   {
8e6adc ¤   ¤   ex->Delete();
ac9371 ¤   }
f4af5a
3390d1 ¤   if (failThis)
fcc7a1 ¤   {
57e102 ¤   ¤   return 1;
d39371 ¤   }
350e24 ¤   else
eec7a1 ¤   {
95045e ¤   ¤   UpdateSaveDialogPrefs();
6ebbde ¤   ¤   return 0;
6e9371 ¤   }
--d1e0 001705abe5d401100c1 Page 6 of CSavePGPdiskDialog.cpp
7aefe6 }
46af5a
a2d08e // OnInitDone is called when initialization is done. We override it to stop
65e964 // MFC from centering the window on the parent.
a6af5a
e1c823 void·
5986a2 CSavePGPdiskDialog::OnInitDone()
9abb36 {
9ad564 ¤   // Center on screen.
280aed ¤   GetParent()->CenterWindow(GetDesktopWindow());
63af5a
0bafdc ¤   // Put us in front.
597a64 ¤   GetParent()->SetForegroundWindow();
76af5a
b454ed ¤   // Put on top if necessary.
ffb5e8 ¤   App->TweakOnTopAttribute(GetParent());
70efe6 }
--9f58 0016695d86c401100c2 Page 1 of CSavePGPdiskDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
6c5215 // CSavePGPdiskDialog.h
fd465d //
29d27d // Declaration of class CSavePGPdiskDialog.
451bc3 //////////////////////////////////////////////////////////////////////////////
20af5a
99f475 // $Id: CSavePGPdiskDialog.h,v 1.1.2.7 1998/07/31 21:36:49 nryan Exp $
3daf5a
d7cbce // Copyright (C) 1998 by Network Associates, Inc.
2271ae // All rights reserved.
adaf5a
f3ffce #ifndef Included_CSavePGPdiskDialog_h¤  // [
697934 #define Included_CSavePGPdiskDialog_h
12af5a
93af5a
96d557 ////////
1b02c9 // Types
c4d557 ////////
17af5a
47f670 // SaveDialogType specifies the type of Save dialog being created. So far
02292b // there is only one type, kSDT_Create, for PGPdisk creation.
22af5a
86a833 enum SaveDialogType¤{kSDT_Create};
07af5a
d7af5a
4083f5 ///////////////////////////
f2f399 // Class CSavePGPdiskDialog
6983f5 ///////////////////////////
f3af5a
5b779c class CSavePGPdiskDialog : public CFileDialog
96bb36 {
8ea4d6 ¤   DECLARE_DYNAMIC(CSavePGPdiskDialog)
52af5a
f45ed4 public:
07d560 ¤   ¤   ¤   CSavePGPdiskDialog(SaveDialogType dlgType, CWnd *pParent = NULL);
11af5a
44a4ae ¤   DualErr¤AskForPath(CString *path, LPCSTR defaultPath = NULL);
2faf5a
4ece94 ¤   //{{AFX_DATA(CSavePGPdiskDialog)
af5139 ¤   //}}AFX_DATA
87af5a
1483aa ¤   //{{AFX_VIRTUAL(CSavePGPdiskDialog)
83c369 ¤   protected:
4c3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
97741d ¤   virtual BOOL OnFileNameOK();
f7af53 ¤   //}}AFX_VIRTUAL
83af5a
45a2d3 protected:
080313 ¤   SaveDialogType mSaveDialogType;¤¤   // save dialog type
c1af5a
63cd57 ¤   void¤   GetInitialPGPdiskName(LPCSTR initialDir, CString *initialName);
4a0ef2 ¤   void¤   UpdateSaveDialogPrefs();
a8b123 ¤   void¤   OnInitDone();
ddaf5a
40ceb2 ¤   //{{AFX_MSG(CSavePGPdiskDialog)
062e09 ¤   //}}AFX_MSG
77af5a
272409 ¤   DECLARE_MESSAGE_MAP()
8b82f7 };
efaf5a
2ec18c //{{AFX_INSERT_LOCATION}}
81af5a
669b0b #endif¤ // ] Included_CSavePGPdiskDialog_h
--bd6b 000e856f37d401100c3 Page 1 of CSecureEdit.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
aa730c // CSecureEdit.cpp
bc465d //
392a94 // Implementation of class CSecureEdit.
b51bc3 //////////////////////////////////////////////////////////////////////////////
dbaf5a
207846 // $Id: CSecureEdit.cpp,v 1.1.2.6 1998/07/28 23:46:37 nryan Exp $
feaf5a
34cbce // Copyright (C) 1998 by Network Associates, Inc.
5571ae // All rights reserved.
9daf5a
c49e12 #include "StdAfx.h"
f3b8af #include <new.h>
0baf5a
a89bcf #include "Required.h"
73bfe9 #include "UtilityFunctions.h"
b1af5a
cb358e #include "CSecureEdit.h"
68c411 #include "Globals.h"
45af5a
81af5a
8709b7 ////////////
dfe738 // Constants
dc09b7 ////////////
9aaf5a
8b163b // Hide typing by default?
e9af5a
1350c3 const PGPBoolean kDefaultCSecureEditHideTyping = TRUE;
85af5a
7aaf5a
d183f5 ///////////////////////////
d6b249 // MFC specific definitions
5683f5 ///////////////////////////
adaf5a
3fa4d0 // These defines are needed because ClassWizard is intelligent enough to
a7ed5d // realize I'm mapping to the same function but too dumb to outsmart the
b0249d // preprocessor.
caaf5a
e0367c #define¤DontClear¤  DoNothing
473f1c #define¤DontCopy¤   DoNothing
d2883b #define¤DontCut¤¤   DoNothing
aae87c #define¤DontPaste¤  DoNothing
9f480f #define¤DontUndo¤   DoNothing
3eaf5a
8f62f4 BEGIN_MESSAGE_MAP(CSecureEdit, CEdit)
f84e5d ¤   //{{AFX_MSG_MAP(CSecureEdit)
cd79c7 ¤   ON_WM_KEYDOWN()
79ce9f ¤   ON_WM_CHAR()
eb8c56 ¤   ON_WM_LBUTTONDOWN()
2d44c9 ¤   ON_WM_LBUTTONDBLCLK()
1b5f6d ¤   ON_WM_MOUSEMOVE()
08aeb3 ¤   ON_MESSAGE(WM_CLEAR, DontClear)
b15cd6 ¤   ON_MESSAGE(WM_COPY, DontCopy)
c692e9 ¤   ON_MESSAGE(WM_CUT, DontCut)
cc7375 ¤   ON_MESSAGE(WM_PASTE, DontPaste)
d85878 ¤   ON_MESSAGE(WM_UNDO, DontUndo)
097e27 ¤   ON_CONTROL_REFLECT(EN_SETFOCUS, OnSetFocus)
af044a ¤   //}}AFX_MSG_MAP
adaf28 END_MESSAGE_MAP()
64af5a
e1af5a
40a6b9 ///////////////////////////////////////////////////////////////////////
8ecb32 // CSecureEdit public custom functions and non-default message handlers
55a6b9 ///////////////////////////////////////////////////////////////////////
e5af5a
61eb30 // The CSecureEdit default constructor.
7caf5a
97bc3a CSecureEdit::CSecureEdit() : mLockedMem(sizeof(SecureString))
62bb36 {
981a8e ¤   mCurCharPos¤¤   ¤   = 0;
8b7cab ¤   mCurNumSpaces¤  ¤   = 0;
e8a738 ¤   mHideTyping¤¤   ¤   = kDefaultCSecureEditHideTyping;
--62e0 000e59acf13401100c3 Page 2 of CSecureEdit.cpp
ed4c77 ¤   mMaxSizeContents¤   = kMaxStringSize;
f8af5a
f21fa5 ¤   // Pick from 1-3 random spaces to be used for each character.
9da0bd ¤   srand((PGPUInt32) PGPdiskGetTicks());
06af5a
d1b824 ¤   for (PGPUInt32 i=0; i<kMaxStringSize; i++)
d5c7a1 ¤   {
d8410a ¤   ¤   PGPUInt32 num = rand();¤¤   // rand roolz!
3caf5a
2c3b86 ¤   ¤   if (num < RAND_MAX/3)
531a9b ¤   ¤   ¤   mSpacesPerChar[i] = 1;
b2977a ¤   ¤   else if (num < RAND_MAX*2/3)
ccf5ff ¤   ¤   ¤   mSpacesPerChar[i] = 2;
4a0e1d ¤   ¤   else
99af23 ¤   ¤   ¤   mSpacesPerChar[i] = 3;
f59371 ¤   }
01af5a
fc6137 ¤   // Make sure our locked memory initialized correctly.
aa61d1 ¤   mInitErr = mLockedMem.mInitErr;
9faf5a
d4b7bb ¤   // Construct the secure string object.
8f9c32 ¤   if (mInitErr.IsntError())
82c7a1 ¤   {
724e83 ¤   ¤   mContents = new (mLockedMem.GetPtr()) SecureString;¤¤   // <new.h>
22a467 ¤   ¤   mContents->ClearString();
6a9371 ¤   }
65efe6 }
76af5a
679d2b // The CSecureEdit destructor destructs the SecureString we constructed in our
a10676 // locked memory.
edaf5a
6e76d4 CSecureEdit::~CSecureEdit()
18bb36 {
43b93f ¤   if (mContents)
3b5f8b ¤   ¤   mContents->~SecureString();¤¤   // we used placement new
95efe6 }
6caf5a
673c22 // ClearEditContents erases the contents of the edit box.
c8af5a
5ac823 void·
8dfab6 CSecureEdit::ClearEditContents()
4bbb36 {
a7936f ¤   mContents->ClearString();
f39812 ¤   SetWindowText(kEmptyString);
b6af5a
dd7b32 ¤   mCurCharPos = 0;
e5af5a
980897 ¤   // Notify parent of the edit box change.
fdbd92 ¤   WPARAM wParam = (WPARAM) MakeLong(GetDlgCtrlID(), EN_CHANGE);
24e45c ¤   LPARAM lParam = (LPARAM) GetSafeHwnd();
30af5a
d67bfa ¤   GetParent()->PostMessage(WM_COMMAND, wParam, lParam);
53efe6 }
a8af5a
28babe // SetHideTypingPref shows or hides the text the user is typing. It returns
19a41d // the previous value of the preference.
49af5a
7877be PGPBoolean·
e8eeb4 CSecureEdit::SetHideTypingPref(PGPBoolean newHideValue)
52bb36 {
e67ce2 ¤   CString¤¤   text;
a8adec ¤   PGPBoolean¤ oldHideValue¤   = mHideTyping;
30af5a
1e6fb6 ¤   mHideTyping = newHideValue;
78af5a
eb78f1 ¤   try
9ec7a1 ¤   {
5967db ¤   ¤   // If hiding the text, replace it with all spaces. If showing the
e7f5a3 ¤   ¤   // text, extract the contents from mContents and set the edit box.
65af5a
6ec8d6 ¤   ¤   if (!oldHideValue && newHideValue)
e55b34 ¤   ¤   {
--2cb4 0000c4d507b401100c3 Page 3 of CSecureEdit.cpp
b7e604 ¤   ¤   ¤   FillEditBoxWithSpaces();
940fe4 ¤   ¤   }
62dbb1 ¤   ¤   else if (oldHideValue && !newHideValue)
595b34 ¤   ¤   {
0f0299 ¤   ¤   ¤   FillEditBoxWithContents();
010fe4 ¤   ¤   }
ba9371 ¤   }
623c88 ¤   catch (CMemoryException *ex)
e2c7a1 ¤   {
ad6adc ¤   ¤   ex->Delete();
099371 ¤   }
95af5a
fee1fc ¤   return oldHideValue;
15efe6 }
b4af5a
35c210 // SetMaxSizeContents sets the maximum size of the edit box. It returns the
e00331 // value of the old size. Nothing is changed if there is already this much
3aa3cc // or more text in the edit box.
b2af5a
ae1b0b PGPUInt32·
2b1144 CSecureEdit::SetMaxSizeContents(PGPUInt32 maxSize)
23bb36 {
87bb51 ¤   PGPUInt32 oldSize = mMaxSizeContents;
a2af5a
33525a ¤   if (maxSize > mContents->GetLength())
8c516b ¤   ¤   mMaxSizeContents = maxSize;
edaf5a
0feb81 ¤   return oldSize;
d3efe6 }
24af5a
7f4a2a //////////////////////////////////////////////////////////////////////////
193baa // CSecureEdit protected custom functions and non-default message handlers
4d4a2a //////////////////////////////////////////////////////////////////////////
67af5a
fc6c05 // FillEditBoxWithContents fills the edit box with the actual string
125077 // contents.
e8af5a
26c823 void·
d6c34b CSecureEdit::FillEditBoxWithContents()
b1bb36 {
ca1c70 ¤   pgpAssert(!mHideTyping);
02af5a
dc78f1 ¤   try
33c7a1 ¤   {
3b7c63 ¤   ¤   CString text;
ceaf5a
9160bc ¤   ¤   // Get real contents.
68efe9 ¤   ¤   mContents->GetString(text.GetBuffer(kMaxStringSize),·
9140e7 ¤   ¤   ¤   kMaxStringSize);
1b9caa ¤   ¤   text.ReleaseBuffer();
eb1b52 ¤   ¤
2a2733 ¤   ¤   // Put the contents in the edit box.
c186dc ¤   ¤   SetWindowText(text);
303024 ¤   ¤   SetSel(mCurCharPos, mCurCharPos);
86af5a
1c5a0a ¤   ¤   // Notify parent of the edit box change.
5e7202 ¤   ¤   NotifyParentOfEditChange();
929371 ¤   }
fc3c88 ¤   catch (CMemoryException *ex)
83c7a1 ¤   {
9f6adc ¤   ¤   ex->Delete();
d39371 ¤   }
bbefe6 }
79af5a
821b51 // FillEditBoxWithSpaces fills the edit box with predetermined amount of
1c86ae // spaces instead of characters.
d0af5a
0fc823 void·
12e9b7 CSecureEdit::FillEditBoxWithSpaces()
90bb36 {
fb6b08 ¤   pgpAssert(mHideTyping);
0caf5a
--84ca 000d05fb8d3401100c3 Page 4 of CSecureEdit.cpp
8a78f1 ¤   try
bbc7a1 ¤   {
81562f ¤   ¤   CString spaces;
9daf5a
37e28e ¤   ¤   mCurNumSpaces = 0;
52af5a
6b2840 ¤   ¤   // Construct string of spaces.
d79b4f ¤   ¤   for (PGPUInt32 i = 0; i < mContents->GetLength(); i++)
e45b34 ¤   ¤   {
47621e ¤   ¤   ¤   mCurNumSpaces += mSpacesPerChar[i];
100fe4 ¤   ¤   }
e3af5a
38e041 ¤   ¤   pgpFillMemory(spaces.GetBuffer(mCurNumSpaces), mCurNumSpaces, ' ');
a093ca ¤   ¤   spaces.ReleaseBuffer(mCurNumSpaces);
26af5a
acdfa3 ¤   ¤   // Put the spaces in the edit box.
14ccbd ¤   ¤   SetWindowText(spaces);
b52e1d ¤   ¤   SetSel(mCurNumSpaces, mCurNumSpaces);
04af5a
545a0a ¤   ¤   // Notify parent of the edit box change.
d87202 ¤   ¤   NotifyParentOfEditChange();
2a9371 ¤   }
e13c88 ¤   catch (CMemoryException *ex)
0ec7a1 ¤   {
c76adc ¤   ¤   ex->Delete();
129371 ¤   }
f3efe6 }
9daf5a
7b07c2 // NotifyParentOfEditChange sends a message to the parent dialog telling it
1feae2 // that the edit box contents have changed.
c5af5a
86c823 void·
d5123f CSecureEdit::NotifyParentOfEditChange()
61bb36 {
d354db ¤   CWnd¤   *pParent;
ea3617 ¤   LPARAM¤ lParam;
4ba16e ¤   WPARAM¤ wParam;
14af5a
70e4d7 ¤   wParam = (WPARAM) MakeLong(GetDlgCtrlID(), EN_CHANGE);
95840e ¤   lParam = (LPARAM) GetSafeHwnd();
06af5a
dd56a0 ¤   pParent = GetParent();
9c7f25 ¤   pgpAssert(pParent);
0faf5a
583967 ¤   if (pParent)
b79264 ¤   ¤   pParent->PostMessage(WM_COMMAND, wParam, lParam);
feefe6 }
dfaf5a
1faf5a
9819ca /////////////////////////////////////////////////
5d9da4 // CSecureEdit protected default message handlers
dc19ca /////////////////////////////////////////////////
afaf5a
638759 // DoNothing is a dummy message handler used to prevent certain "unsafe"
336829 // messages from reaching the framework.
d2af5a
0dc823 void·
29d940 CSecureEdit::DoNothing(WPARAM wParam, LPARAM lParam)
3abb36 {
e2efe6 }
dfaf5a
f9dc38 // OnChar is overriden so we can implement our hidden typing routine.
9cabc3 // Instead of placing the character in the edit box, we place a space
6da075 // there instead and update only the secure mContents variable with the
af675b // new character.
4faf5a
5bc823 void·
eedd8a CSecureEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)·
22bb36 {
950db6 ¤   PGPBoolean isPrintable;
e2af5a
d05586 ¤   isPrintable = (nChar >=32);
--7ec6 000ba8ded5e401100c3 Page 5 of CSecureEdit.cpp
e0af5a
e03824 ¤   if (isPrintable)¤   // printable character?
32c7a1 ¤   {
06f495 ¤   ¤   if (mContents->GetLength() == mMaxSizeContents)¤// overflow?
bf5b34 ¤   ¤   {
48daba ¤   ¤   ¤   MessageBeep(MB_ICONHAND);
550fe4 ¤   ¤   }
ab0e1d ¤   ¤   else
9f5b34 ¤   ¤   {
475e4f ¤   ¤   ¤   // Insert the new character in the contents.
33acd4 ¤   ¤   ¤   mContents->InsertAt(mCurCharPos++, nChar);
ecaf5a
bf19a0 ¤   ¤   ¤   // If hiding typing, fill the edit box with spaces, else show the
7b624c ¤   ¤   ¤   // real contents.
6baf5a
ea75a0 ¤   ¤   ¤   if (mHideTyping)
0fe3e9 ¤   ¤   ¤   ¤   FillEditBoxWithSpaces();
fcbb8c ¤   ¤   ¤   else
620cd5 ¤   ¤   ¤   ¤   FillEditBoxWithContents();
f40fe4 ¤   ¤   }
e39371 ¤   }
e0efe6 }
a9af5a
3cb885 // OnLButtonDown is overidden so we can stop the user from making a selection
db515d // or changing the position of the caret by clicking.
52af5a
e4c823 void·
7b4fa8 CSecureEdit::OnLButtonDown(UINT nFlags, CPoint point)·
04bb36 {
be63bb ¤   // Set us to have the focus!
4999ce ¤   SetFocus();
26efe6 }
ddaf5a
5de938 // OnLButtonDblClk is overidden so we can stop the user from making a
d844da // selection.
35af5a
72c823 void·
1c0d08 CSecureEdit::OnLButtonDblClk(UINT nFlags, CPoint point)·
7fbb36 {
9063bb ¤   // Set us to have the focus!
a899ce ¤   SetFocus();
a3af5a
df830f ¤   return;
37efe6 }
6caf5a
db2221 // OnKeyDown is overriden so we can handle character deletion and selection.
d5af5a
8ec823 void·
4e8428 CSecureEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)·
f3bb36 {
2289e3 ¤   switch (nChar)
bac7a1 ¤   {
c575c2 ¤   case VK_DELETE:
258f7d ¤   case VK_HOME:
d0936f ¤   case VK_END:
cad395 ¤   case VK_UP:
0f8820 ¤   case VK_DOWN:
e5cc25 ¤   case VK_LEFT:
da2700 ¤   case VK_RIGHT:
dca990 ¤   case VK_NEXT:
cb9f6e ¤   case VK_PRIOR:
c1539c ¤   ¤   // Disallow caret movement.
c72f68 ¤   ¤   break;
adaf5a
427992 ¤   case VK_BACK:
4d5d89 ¤   ¤   // Delete the current character.
d28ac7 ¤   ¤   if (mCurCharPos > 0)
1d5b34 ¤   ¤   {
9d9a66 ¤   ¤   ¤   // Remove the character from the contents.
e3becf ¤   ¤   ¤   mContents->RemoveAt(--mCurCharPos);
d5af5a
ba19a0 ¤   ¤   ¤   // If hiding typing, fill the edit box with spaces, else show the
--1746 00161b49cc5401100c3 Page 6 of CSecureEdit.cpp
3f624c ¤   ¤   ¤   // real contents.
1aaf5a
2f75a0 ¤   ¤   ¤   if (mHideTyping)
f0e3e9 ¤   ¤   ¤   ¤   FillEditBoxWithSpaces();
d0bb8c ¤   ¤   ¤   else
fd0cd5 ¤   ¤   ¤   ¤   FillEditBoxWithContents();
a40fe4 ¤   ¤   }
342f68 ¤   ¤   break;
f2af5a
5a2f72 ¤   default:
badd07 ¤   ¤   CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
252f68 ¤   ¤   break;
4c9371 ¤   }
cdefe6 }
86af5a
772b6c // OnMouseMove is overidden so we can stop the user from making a selection.
50af5a
2ac823 void·
368189 CSecureEdit::OnMouseMove(UINT nFlags, CPoint point)·
ebbb36 {
b0830f ¤   return;
feefe6 }
28af5a
446c46 // OnSetFocus is called when we are recieving the focus. Stop any text
ffc030 // selections from being made.
48af5a
7dc823 void·
1730c9 CSecureEdit::OnSetFocus()·
fabb36 {
03a00d ¤   SetSel(-1, -1);¤
61efe6 }
--b867 0015b60a102401100c4 Page 1 of CSecureEdit.h
541bc3 //////////////////////////////////////////////////////////////////////////////
aa327a // CSecureEdit.h
ad465d //
1eb4b1 // Declaration of class CSecureEdit.
dd1bc3 //////////////////////////////////////////////////////////////////////////////
69af5a
844b6e // $Id: CSecureEdit.h,v 1.1.2.5 1998/07/06 08:57:21 nryan Exp $
6eaf5a
27cbce // Copyright (C) 1998 by Network Associates, Inc.
bb71ae // All rights reserved.
87af5a
0fb424 #ifndef Included_CSecureEdit_h¤ // [
e9ed50 #define Included_CSecureEdit_h
71af5a
2f3a85 #include "DualErr.h"
f570d4 #include "SecureMemory.h"
7785af #include "SecureString.h"
47af5a
43ab81 #include "Resource.h"
6baf5a
07af5a
acca3a ////////////////////
a11cad // Class CSecureEdit
23ca3a ////////////////////
2eaf5a
20876e class CSecureEdit : public CEdit
babb36 {
4c5ed4 public:
171457 ¤   DualErr¤¤   ¤   mInitErr;
dd31e2 ¤   SecureString¤   *mContents;¤¤   ¤   ¤   ¤   // string contents
94af5a
6bae3d ¤   ¤   ¤   ¤   CSecureEdit();
15a24f ¤   virtual¤¤   ~CSecureEdit();
f7af5a
7af1bc ¤   void¤   ¤   ClearEditContents();
2baf5a
d3aa43 ¤   PGPBoolean¤ SetHideTypingPref(PGPBoolean newHideValue);
4157e7 ¤   PGPUInt32¤  SetMaxSizeContents(PGPUInt32 maxSize);
4baf5a
b8343a ¤   //{{AFX_VIRTUAL(CSecureEdit)
74af53 ¤   //}}AFX_VIRTUAL
8baf5a
13a2d3 protected:
712bfe ¤   PGPBoolean¤ ¤   mHideTyping;¤   ¤   ¤   ¤   // hide keystrokes?
2fd4ba ¤   SecureMemory¤   mLockedMem;¤¤   ¤   ¤   ¤   // our locked memory
27af5a
8865a1 ¤   PGPUInt8¤   ¤   mSpacesPerChar[kMaxStringSize];¤¤   // spaces per char
9899aa ¤   PGPInt32¤   ¤   mCurCharPos;¤   ¤   ¤   ¤   // caret at which character?
f72a6a ¤   PGPInt32¤   ¤   mCurNumSpaces;¤ ¤   ¤   ¤   // current number spaces
ccc459 ¤   PGPUInt32¤  ¤   mMaxSizeContents;¤  ¤   ¤   // max characters
31af5a
1cea6f ¤   void¤   FillEditBoxWithContents();
64d1c0 ¤   void¤   FillEditBoxWithSpaces();
eaaf5a
cd2506 ¤   void¤   NotifyParentOfEditChange();
41af5a
3e9907 ¤   //{{AFX_MSG(CSecureEdit)
32e655 ¤   afx_msg void DoNothing(WPARAM wParam, LPARAM lParam);
2186ac ¤   afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
719ea8 ¤   afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
f24322 ¤   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
7629ee ¤   afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
850e54 ¤   afx_msg void OnMouseMove(UINT nFlags, CPoint point);
bfd29d ¤   afx_msg void OnSetFocus();
162e09 ¤   //}}AFX_MSG
f7af5a
0c2409 ¤   DECLARE_MESSAGE_MAP()
5482f7 };
d0af5a
69c18c //{{AFX_INSERT_LOCATION}}
c6af5a
5b2f01 #endif¤ // ] Included_CSecureEdit_h
--ff9a 000d546349b401100c5 Page 1 of CSinglePassphraseDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
fccc91 // CSinglePassphraseDialog.cpp
32465d //
2a536f // Implementation of the CSinglePassphraseDialog class.
2d1bc3 //////////////////////////////////////////////////////////////////////////////
afaf5a
7e5223 // $Id: CSinglePassphraseDialog.cpp,v 1.1.2.17.2.2 1998/10/28 00:13:30 nryan Ex¶
8ab277 p $
c9af5a
14cbce // Copyright (C) 1998 by Network Associates, Inc.
7a71ae // All rights reserved.
39af5a
b69e12 #include "StdAfx.h"
27af5a
f29bcf #include "Required.h"
9d7414 #include "PGPdiskHighLevelUtils.h"
a92229 #include "PGPdiskLowLevelUtils.h"
e7af5a
7eea4b #if PGPDISK_PUBLIC_KEY
00f4f6 #include "PGPdiskPublicKeyUtils.h"
c178e7 #endif // PGPDISK_PUBLIC_KEY
13af5a
c7993c #include "StringAssociation.h"
8faf5a
c41998 #include "CSinglePassphraseDialog.h"
b0c411 #include "Globals.h"
cb4713 #include "PGPdiskHelpIds.h"
75af5a
a0af5a
b709b7 ////////////
50e738 // Constants
6709b7 ////////////
e4af5a
aa163b // Hide typing by default?
e6af5a
7635a4 const PGPBoolean kDefaultSinglePassHideTyping = TRUE;
2baf5a
5eaf5a
b56cc2 /////////////////////
a83a71 // Context help array
186cc2 /////////////////////
caaf5a
c277bf static PGPUInt32 HelpIds[] =
85bb36 {
e1cf98 ¤   IDOK,¤  ¤   ¤   ¤   ¤   IDH_PGPDISKAPP_SINGLEPASSOK,·
8e10b2 ¤   IDCANCEL,¤  ¤   ¤   ¤   IDH_PGPDISKAPP_SINGLEPASSCANCEL,·
4ecd32 ¤   IDC_HIDETYPE_CHECK,¤¤   IDH_PGPDISKAPP_SINGLEPASSHIDECHECK,·
8818c7 ¤   IDC_PASSPHRASE_EDIT,¤   IDH_PGPDISKAPP_SINGLEPASSEDIT,·
2955de ¤   IDC_RO_CHECK,¤  ¤   ¤   IDH_PGPDISKAPP_SINGLEPASSROCHECK,·
5351d2 ¤   IDC_DRIVE_COMBO,¤   ¤   IDH_PGPDISKAPP_SINGLEPASSDRIVECOMBO,·
6a8ab4 ¤   IDC_SINGLEPASSMSG_TEXT,¤((PGPUInt32) -1),·
844434 ····0,0·
bd82f7 };
29af5a
b2af5a
c683f5 ///////////////////////////
1bb249 // MFC specific definitions
6483f5 ///////////////////////////
beaf5a
193e73 BEGIN_MESSAGE_MAP(CSinglePassphraseDialog, CDialog)
f995e5 ¤   //{{AFX_MSG_MAP(CSinglePassphraseDialog)
752725 ¤   ON_BN_CLICKED(IDC_HIDETYPE_CHECK, OnHideTypeCheck)
5ddb65 ¤   ON_WM_HELPINFO()
d2177a ¤   ON_BN_CLICKED(IDC_RO_CHECK, OnROCheck)
d1044a ¤   //}}AFX_MSG_MAP
f8af28 END_MESSAGE_MAP()
73af5a
8daf5a
9c7cc3 ///////////////////////////////////////////////////////////////////////////
e4eb60 // CSinglePassphraseDialog public custom functions and non-default handlers
267cc3 ///////////////////////////////////////////////////////////////////////////
d5af5a
--548f 000e98f3fc1401100c5 Page 2 of CSinglePassphraseDialog.cpp
445b2c // The CSinglePassphraseDialog default constructor. You can pass 'dialogMsg'
ab33d0 // to set the dialog box message.
f9af5a
cbad00 CSinglePassphraseDialog::CSinglePassphraseDialog(SinglePassDialogType dlgType)
3aaf5a
74ba9d ¤   : CDialog(CSinglePassphraseDialog::IDD, NULL)
03bb36 {
8e78f1 ¤   try
f2c7a1 ¤   {
ac9f4f ¤   ¤   //{{AFX_DATA_INIT(CSinglePassphraseDialog)
f394e5 ¤   ¤   mHideTypeValue = FALSE;
7506e3 ¤   ¤   mMessageValue = _T("");
37765d ¤   ¤   //}}AFX_DATA_INIT
22af5a
047250 ¤   ¤   mSinglePassDialogType = dlgType;
f9af5a
2f969b ¤   ¤   // Did the secure edit control initialize properly?
65ab3a ¤   ¤   if (mInitErr.IsntError())
d65b34 ¤   ¤   {
e98e9f ¤   ¤   ¤   mInitErr = mPassphraseEdit.mInitErr;
8f0fe4 ¤   ¤   }
dcaf5a
4c93ce ¤   ¤   // Adjust for the correct resource template.
04ab3a ¤   ¤   if (mInitErr.IsntError())
645b34 ¤   ¤   {
2ab917 ¤   ¤   ¤   switch (mSinglePassDialogType)
e7f776 ¤   ¤   ¤   {
4b1110 ¤   ¤   ¤   case kSPDT_Mount:
2bfae6 ¤   ¤   ¤   ¤   m_lpszTemplateName = (LPCTSTR) IDD_SINGLEPASS1_DLG;
61f622 ¤   ¤   ¤   ¤   break;
22af5a
801fe0 ¤   ¤   ¤   case kSPDT_PublicKey:
30cd5d ¤   ¤   ¤   ¤   m_lpszTemplateName = (LPCTSTR) IDD_SINGLEPASS3_DLG;
a5f622 ¤   ¤   ¤   ¤   break;
a5af5a
5fdb68 ¤   ¤   ¤   default:
105288 ¤   ¤   ¤   ¤   m_lpszTemplateName = (LPCTSTR) IDD_SINGLEPASS2_DLG;
47f622 ¤   ¤   ¤   ¤   break;
f0a3a6 ¤   ¤   ¤   }
bbaf5a
b315d4 ¤   ¤   ¤   // Stolen from MFC.
dedddf ¤   ¤   ¤   if (HIWORD(m_lpszTemplateName) == 0)
acf776 ¤   ¤   ¤   {
ef09f8 ¤   ¤   ¤   ¤   m_nIDHelp = LOWORD((DWORD) m_lpszTemplateName);
d2a3a6 ¤   ¤   ¤   }
1f0fe4 ¤   ¤   }
eb9371 ¤   }
483c88 ¤   catch (CMemoryException *ex)
2ec7a1 ¤   {
779a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
3b6adc ¤   ¤   ex->Delete();
f79371 ¤   }
66efe6 }
d8af5a
b7ef10 // The CSinglePassphraseDialog destructor.
91af5a
15c6ef CSinglePassphraseDialog::~CSinglePassphraseDialog()
c1bb36 {
05efe6 }
d1af5a
4fc94e // AskForPassphrase is a wrapper around DoModal. It asks for a passphrase
501689 // from the specified PGPdisk.
9eaf5a
e22292 DualErr·
bb0cdb CSinglePassphraseDialog::AskForPassphrase(
77f2f8 ¤   LPCSTR¤ ¤   path,·
783629 ¤   PGPBoolean¤ forceReadOnly,·
d8c58a ¤   PGPBoolean¤ needMaster)
76bb36 {
98be41 ¤   DualErr¤¤   derr;
f9e319 ¤   PGPInt32¤   result;
e967c5 ¤
--9844 0000fc5f883401100c5 Page 3 of CSinglePassphraseDialog.cpp
a3639f ¤   pgpAssertStrValid(path);
2baf5a
a478f1 ¤   try
a6c7a1 ¤   {
ffd5dc ¤   ¤   mPath = path;
f19371 ¤   }
293c88 ¤   catch (CMemoryException *ex)
23c7a1 ¤   {
96ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
926adc ¤   ¤   ex->Delete();
739371 ¤   }
d2af5a
162361 ¤   if (derr.IsntError())
35c7a1 ¤   {
6aaa5b ¤   ¤   derr = ValidatePGPdisk(mPath);
eb9371 ¤   }
d7af5a
782361 ¤   if (derr.IsntError())
67c7a1 ¤   {
25e66d ¤   ¤   mNeedMaster = needMaster;
bf79bb ¤   ¤   mReadOnlyValue = forceReadOnly;
1baf5a
8afcae ¤   ¤   result = DoModal();
05af5a
2db507 ¤   ¤   switch (result)
1d5b34 ¤   ¤   {
cc56e8 ¤   ¤   case -1:
1b39a7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
fdcdcb ¤   ¤   ¤   break;
dfaf5a
0471eb ¤   ¤   case IDCANCEL:
3896de ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
39cdcb ¤   ¤   ¤   break;
5a0fe4 ¤   ¤   }
9b9371 ¤   }
a1af5a
6333e3 ¤   return derr;
99efe6 }
05af5a
a3819a // PreTranslateMessage sees all messages before MFC filters them. We need to
177bb9 // check for the caps lock key.
95af5a
187efe BOOL·
f7317e CSinglePassphraseDialog::PreTranslateMessage(MSG* pMsg)·
a0bb36 {
d6f87e ¤   switch (pMsg->message)
d0c7a1 ¤   {
6f948b ¤   case WM_KEYUP:
84e270 ¤   ¤   SetCapsLockMessageState();
d42f68 ¤   ¤   break;
c49371 ¤   }
c6af5a
2fed5a ¤   return CDialog::PreTranslateMessage(pMsg);
8befe6 }
30af5a
148331 // SetReadOnlyValue can be called to set the value of the read-only checkbox
c24c8c // before displaying the dialog. This is only useful for kSPDT_Mount dialogs.
3daf5a
a4c823 void·
7fd120 CSinglePassphraseDialog::SetReadOnlyValue(PGPBoolean readOnly)
8bbb36 {
7dd9ad ¤   pgpAssert(mSinglePassDialogType == kSPDT_Mount);
cdaf5a
ed9387 ¤   mReadOnlyButton.SetCheck(readOnly ? 1 : 0);
470506 ¤   mReadOnlyValue = (mReadOnlyButton.GetCheck() == 1 ? TRUE : FALSE);
c9efe6 }
04af5a
43cad7 // DisableReadOnly can be called to disable the read-only button. This is only
391c33 // useful for kSPDT_Mount dialogs, because in all other types the button is
e98213 // hidden no matter what.
bfaf5a
0fc823 void·
--168a 000a788d946401100c5 Page 4 of CSinglePassphraseDialog.cpp
158b33 CSinglePassphraseDialog::DisableReadOnlyButton()
a9bb36 {
d5d9ad ¤   pgpAssert(mSinglePassDialogType == kSPDT_Mount);
547399 ¤   mReadOnlyButton.EnableWindow(FALSE);
a0efe6 }
75af5a
dbaf5a
5d1bc3 //////////////////////////////////////////////////////////////////////////////
771a84 // CSinglePassphraseDialog protected custom functions and non-default handlers
801bc3 //////////////////////////////////////////////////////////////////////////////
b5af5a
ff6e23 // SetCapsLockMessageState shows or hides the caps lock message as needed.
73af5a
b6c823 void·
f3b9c4 CSinglePassphraseDialog::SetCapsLockMessageState()
8cbb36 {
b2c0f1 ¤   PGPUInt16 bob = GetKeyState(VK_CAPITAL);
2faf5a
db33d5 ¤   if (GetKeyState(VK_CAPITAL) & 1)
30ac4a ¤   ¤   mCapsLockStatic.ShowWindow(SW_SHOW);
900e24 ¤   else
02d611 ¤   ¤   mCapsLockStatic.ShowWindow(SW_HIDE);
3aefe6 }
11af5a
c11648 // The CSinglePassphraseDialog data exchange function.
2aaf5a
c2c823 void·
046663 CSinglePassphraseDialog::DoDataExchange(CDataExchange *pDX)
3bbb36 {
f278f1 ¤   try
54c7a1 ¤   {
cbf4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
08af5a
f389fd ¤   ¤   //{{AFX_DATA_MAP(CSinglePassphraseDialog)
ebee82 ¤   ¤   DDX_Control(pDX, IDC_SINGLEPASSMSG_TEXT, mMessageStatic);
19e5d1 ¤   ¤   DDX_Control(pDX, IDC_CAPSLOCK_TEXT, mCapsLockStatic);
369795 ¤   ¤   DDX_Control(pDX, IDOK, mOKButton);
faa1d5 ¤   ¤   DDX_Control(pDX, IDCANCEL, mCancelButton);
8cd337 ¤   ¤   DDX_Control(pDX, IDC_PASSPHRASE_EDIT, mPassphraseEdit);
856868 ¤   ¤   DDX_Check(pDX, IDC_HIDETYPE_CHECK, mHideTypeValue);
161baa ¤   ¤   DDX_Text(pDX, IDC_SINGLEPASSMSG_TEXT, mMessageValue);
9f3376 ¤   ¤   //}}AFX_DATA_MAP
7f9371 ¤   }
a93c88 ¤   catch (CMemoryException *ex)
49c7a1 ¤   {
446adc ¤   ¤   ex->Delete();
fc9371 ¤   }
5eefe6 }
faaf5a
6e00d8 // We override OnHideTypeCheck to set the 'hide typing' behavior of the edit
483410 // box.
8caf5a
1ac823 void·
47690c CSinglePassphraseDialog::OnHideTypeCheck()·
e1bb36 {
28364d ¤   UpdateData(TRUE);
68af5a
71da1e ¤   mPassphraseEdit.SetHideTypingPref(mHideTypeValue);
19dca9 ¤   mPassphraseEdit.SetFocus();
eaefe6 }
9caf5a
3d6a61 // OnROCheck is called when the read-only check box is clicked.
e4af5a
51c823 void·
928032 CSinglePassphraseDialog::OnROCheck()·
babb36 {
0a0506 ¤   mReadOnlyValue = (mReadOnlyButton.GetCheck() == 1 ? TRUE : FALSE);
71efe6 }
5aaf5a
87af5a
3bc3ce /////////////////////////////////////////////////////
a7b31a // CSinglePassphraseDialog protected default handlers
--fade 0002fc98f5d401100c5 Page 5 of CSinglePassphraseDialog.cpp
2cc3ce /////////////////////////////////////////////////////
7aaf5a
d58cca // OnHelpInfo handles context-sensitive help.
cfaf5a
ea7efe BOOL·
0b81ea CSinglePassphraseDialog::OnHelpInfo(HELPINFO *pHelpInfo)
79bb36 {
7729b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
23e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
dcc7a1 ¤   {
36ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
ef6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
6d9371 ¤   }
ddaf5a
53c2e7 ¤   return TRUE;
d2efe6 }
ecaf5a
734b0d // OnInitDialog performs dialog box initialization.
99af5a
d37efe BOOL·
31fb21 CSinglePassphraseDialog::OnInitDialog()·
51bb36 {
5b2ae9 ¤   CString¤bareName, dialogMsg;
03945d ¤   DualErr¤derr;
a1af5a
b15818 ¤   pgpAssert(!mPath.IsEmpty());
1daf5a
4dc799 ¤   CDialog::OnInitDialog();
8a67c5 ¤
2738d5 ¤   // Prepare the dialog message text.
5dbbfe ¤   GetBareName(mPath, &bareName);
3aaf5a
cef6a8 ¤   switch (mSinglePassDialogType)
f6c7a1 ¤   {
2475e0 ¤   case kSPDT_Change:
5cd3d7 ¤   ¤   dialogMsg = GetCommonString(kPGPdiskSPDTChangePassMsg);
a62f68 ¤   ¤   break;
afaf5a
99863c ¤   case kSPDT_Master:
1a22e1 ¤   ¤   dialogMsg = GetCommonString(kPGPdiskSPDTMasterPassMsg);
dc2f68 ¤   ¤   break;
02af5a
0d5ff1 ¤   case kSPDT_Mount:
bae13f ¤   ¤   if (mNeedMaster)
6a1f8f ¤   ¤   ¤   dialogMsg = GetCommonString(kPGPdiskSPDTMasterPassMsg);
990e1d ¤   ¤   else
6038f2 ¤   ¤   ¤   dialogMsg = GetCommonString(kPGPdiskSPDTMountPassMsg);
702f68 ¤   ¤   break;
83af5a
99a1bc ¤   case kSPDT_PublicKey:
b0dc05 ¤   ¤   dialogMsg = GetCommonString(kPGPdiskSPDTPublicKeyPassMsg);
c42f68 ¤   ¤   break;
f9af5a
0164c2 ¤   case kSPDT_Remove:
024454 ¤   ¤   dialogMsg = GetCommonString(kPGPdiskSPDTRemovePassMsg);
d52f68 ¤   ¤   break;
aeaf5a
b22f72 ¤   default:
f78f52 ¤   ¤   pgpAssert(FALSE);
692f68 ¤   ¤   break;
6d9371 ¤   }
5baf5a
b9cfd3 ¤   // Format and truncate the message if necessary.
7ae20e ¤   App->FormatFitStringToWindow(dialogMsg, bareName, &mMessageValue,·
e49946 ¤   ¤   &mMessageStatic);
0267c5 ¤
5d7458 ¤   // Initialize controls for the mount dialog.
3a17c2 ¤   if (mSinglePassDialogType == kSPDT_Mount)
cfc7a1 ¤   {
81a8c5 ¤   ¤   PGPBoolean¤ forceReadOnly;
a6fec7 ¤   ¤   PGPUInt8¤   prefDrive;
2faf5a
--38fd 000b64512f7401100c5 Page 6 of CSinglePassphraseDialog.cpp
b846ed ¤   ¤   mReadOnlyButton.SubclassWindow(
26fa50 ¤   ¤   ¤   GetDlgItem(IDC_RO_CHECK)->GetSafeHwnd());
feaf5a
badfa9 ¤   ¤   mDriveCombo.SubclassWindow(
4683bb ¤   ¤   ¤   GetDlgItem(IDC_DRIVE_COMBO)->GetSafeHwnd());
36af5a
2a48b5 ¤   ¤   // Any drive letters free?
53b4a5 ¤   ¤   if (!App->AreAnyDriveLettersFree())
ae5b34 ¤   ¤   {
5add47 ¤   ¤   ¤   EndDialog(IDCANCEL);
9d0fe4 ¤   ¤   }
74af5a
6a45c7 ¤   ¤   // Initialize the combo box.
8b583b ¤   ¤   mDriveCombo.InitDriveLetters();
16af5a
69baa8 ¤   ¤   // Get the preferred drive letter from the PGPdisk and set the
f2f5d9 ¤   ¤   // combo box to it.
cdaf5a
eaeeaf ¤   ¤   prefDrive = GetDriveLetterPref(mPath);
a528c7 ¤   ¤   mDriveCombo.SetDriveLetter(prefDrive);
ffaf5a
4c1376 ¤   ¤   // Check if we must force a read-only mount.
c2b838 ¤   ¤   forceReadOnly = mReadOnlyValue;
05af5a
67d64a ¤   ¤   if (!forceReadOnly)
ec5b34 ¤   ¤   {
4c8ed5 #if PGPDISK_BETAVERSION
c5af5a
f8e3a5 ¤   ¤   ¤   forceReadOnly = App->IsFileInUse(mPath) ||·
411e68 ¤   ¤   ¤   ¤   App->IsFileReadOnly(mPath) ||
e4f080 ¤   ¤   ¤   ¤   App->HasBetaTimedOut();
5faf5a
225766 #elif PGPDISK_DEMOVERSION
69af5a
ede3a5 ¤   ¤   ¤   forceReadOnly = App->IsFileInUse(mPath) ||·
551e68 ¤   ¤   ¤   ¤   App->IsFileReadOnly(mPath) ||
6dbb0b ¤   ¤   ¤   ¤   App->HasDemoTimedOut();
09af5a
f2b8d4 #else // !PGPDISK_BETAVERSION && !PGPDISK_DEMOVERSION
a6af5a
b2e3a5 ¤   ¤   ¤   forceReadOnly = App->IsFileInUse(mPath) ||·
0e72b9 ¤   ¤   ¤   ¤   App->IsFileReadOnly(mPath);
10af5a
04e121 #endif // PGPDISK_BETAVERSION
ce0fe4 ¤   ¤   }
e7af5a
82d64a ¤   ¤   if (!forceReadOnly)
a85b34 ¤   ¤   {
7f5edf ¤   ¤   ¤   if (IsPGPdiskNotEncrypted(mPath))
d8f776 ¤   ¤   ¤   {
bdba56 ¤   ¤   ¤   ¤   forceReadOnly = TRUE;
ffa297 ¤   ¤   ¤   ¤   DisplayMessage(kPGPdiskPGPdiskIsNotEncrypted);
13a3a6 ¤   ¤   ¤   }
300fe4 ¤   ¤   }
90af5a
73b90c ¤   ¤   // If path is UNC and server name is local computer, force
32f537 ¤   ¤   // read-only at this point (should have been resolved on Admin
c4364a ¤   ¤   // accounts by the path canonicalizer.)
06af5a
6fd64a ¤   ¤   if (!forceReadOnly)
df5b34 ¤   ¤   {
cea1da ¤   ¤   ¤   if (IsUNCPath(mPath) && IsWinNT4CompatibleMachine())
c0f776 ¤   ¤   ¤   {
5f2704 ¤   ¤   ¤   ¤   CString localCompName, server;
caaf5a
5c5b12 ¤   ¤   ¤   ¤   GetServer(mPath, &server);
c93f4a ¤   ¤   ¤   ¤   GetLocalComputerName(&localCompName);
81af5a
2c059c ¤   ¤   ¤   ¤   if (server.CompareNoCase(localCompName) == 0)
6472c3 ¤   ¤   ¤   ¤   {
6069ac ¤   ¤   ¤   ¤   ¤   DisplayMessage(kPGPdiskForceROOnLoopbackString);
b686b8 ¤   ¤   ¤   ¤   ¤   forceReadOnly = TRUE;
--1646 0009108c656401100c5 Page 7 of CSinglePassphraseDialog.cpp
862613 ¤   ¤   ¤   ¤   }
2ba3a6 ¤   ¤   ¤   }
590fe4 ¤   ¤   }
e6af5a
5c07fd ¤   ¤   if (forceReadOnly)
2e5b34 ¤   ¤   {
7e6085 ¤   ¤   ¤   SetReadOnlyValue(TRUE);
d00b82 ¤   ¤   ¤   DisableReadOnlyButton();
a70fe4 ¤   ¤   }
750e1d ¤   ¤   else
015b34 ¤   ¤   {
cf48b3 ¤   ¤   ¤   SetReadOnlyValue(FALSE);
6b0fe4 ¤   ¤   }
f99371 ¤   }
41af5a
79be7a ¤   // Show or hide the caps lock text.
326e0f ¤   SetCapsLockMessageState();
c7af5a
11264a ¤   // Set the hide-typing checkbox.
771480 ¤   mHideTypeValue = kDefaultSinglePassHideTyping;
67af5a
1d1a9a ¤   // Set the hide-typing pref of the edit box.
c0da1e ¤   mPassphraseEdit.SetHideTypingPref(mHideTypeValue);
5eaf5a
8a8642 ¤   // Set the maximum text length of the edit box.
d1d145 ¤   mPassphraseEdit.SetMaxSizeContents(kMaxPassphraseLength);
e902a1 ¤   UpdateData(FALSE);
8faf5a
9fb1fe ¤   // Set the focus to the edit box.
0cdca9 ¤   mPassphraseEdit.SetFocus();
ccaf5a
a2d564 ¤   // Center on screen.
be50f9 ¤   CenterWindow(GetDesktopWindow());
51af5a
59afdc ¤   // Put us in front.
4d9974 ¤   SetForegroundWindow();
8daf5a
6b54ed ¤   // Put on top if necessary.
8dc3a9 ¤   App->TweakOnTopAttribute(this);
87af5a
d19b5a ¤   // Show now to thwart evil MFC auto-centering.
bdc56d ¤   ShowWindow(SW_SHOW);
2eaf5a
bca230 ¤   return FALSE;
37efe6 }
09af5a
a378cf // OnOK handles the OK button. We verify that the passphrase entered is valid
a05229 // for this PGPdisk.
15af5a
59c823 void·
71bb60 CSinglePassphraseDialog::OnOK()·
00bb36 {
976f88 ¤   CWaitCursor¤waitCursor;
b89624 ¤   DualErr¤¤   derr, dummyErr;
0bb895 ¤   PGPBoolean¤ failThis¤   = FALSE;
12e3f6 ¤   PGPBoolean¤ isValidPassphrase;
cfaf5a
06f6a8 ¤   switch (mSinglePassDialogType)
65c7a1 ¤   {
a0863c ¤   case kSPDT_Master:
2ba89a ¤   ¤   // We MUST have a master passphrase. Fail otherwise.
07f720 ¤   ¤   derr = VerifyMasterPassphrase(mPath, mPassphraseEdit.mContents);
c02428 ¤   ¤   isValidPassphrase = derr.IsntError();
f2af5a
af4196 ¤   ¤   if (!isValidPassphrase)
bf5b34 ¤   ¤   {
2ebd13 ¤   ¤   ¤   failThis = TRUE;
3a2c7b ¤   ¤   ¤   ReportError(kPGDMajorError_IncorrectMasterPassphrase);
e80fe4 ¤   ¤   }
ec2f68 ¤   ¤   break;
3baf5a
9164c2 ¤   case kSPDT_Remove:
--d23b 0002a34a0a0401100c5 Page 8 of CSinglePassphraseDialog.cpp
d62af3 ¤   ¤   // We CAN'T have a master passphrase. Fail if we see one.
53f720 ¤   ¤   derr = VerifyMasterPassphrase(mPath, mPassphraseEdit.mContents);
d72428 ¤   ¤   isValidPassphrase = derr.IsntError();
aaaf5a
f9a2f8 ¤   ¤   if (isValidPassphrase)
e15b34 ¤   ¤   {
90bd13 ¤   ¤   ¤   failThis = TRUE;
57c9b8 ¤   ¤   ¤   ReportError(kPGDMajorError_TriedRemoveMasterPass);
f50fe4 ¤   ¤   }
110e1d ¤   ¤   else
d55b34 ¤   ¤   {
689939 ¤   ¤   ¤   // OK, it isn't a master, check if it is an alternate.
d99339 ¤   ¤   ¤   derr = VerifyNormalPassphrase(mPath, mPassphraseEdit.mContents);
676b16 ¤   ¤   ¤   isValidPassphrase = derr.IsntError();
83af5a
9dca6a ¤   ¤   ¤   if (!isValidPassphrase)
53f776 ¤   ¤   ¤   {
b30645 ¤   ¤   ¤   ¤   failThis = TRUE;
9b1bda ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_IncorrectAlternatePassphrase);
8fa3a6 ¤   ¤   ¤   }
050fe4 ¤   ¤   }
462f68 ¤   ¤   break;
ccaf5a
cc75e0 ¤   case kSPDT_Change:
bc1c8b ¤   ¤   // Passphrase can be either a master or an alternate.
73af5a
970ee3 ¤   ¤   derr = VerifyNormalPassphrase(mPath, mPassphraseEdit.mContents);
e12428 ¤   ¤   isValidPassphrase = derr.IsntError();
47af5a
ad4196 ¤   ¤   if (!isValidPassphrase)
ae5b34 ¤   ¤   {
05bd13 ¤   ¤   ¤   failThis = TRUE;
e79f43 ¤   ¤   ¤   ReportError(kPGDMajorError_IncorrectPassphrase);
410fe4 ¤   ¤   }
cf2f68 ¤   ¤   break;
ecaf5a
8e5ff1 ¤   case kSPDT_Mount:
008745 ¤   ¤   // Passphrase can be either a master or an alternate or a public key.
57e13f ¤   ¤   if (mNeedMaster)
936afa ¤   ¤   ¤   derr = VerifyMasterPassphrase(mPath, mPassphraseEdit.mContents);
a30e1d ¤   ¤   else
ec9339 ¤   ¤   ¤   derr = VerifyNormalPassphrase(mPath, mPassphraseEdit.mContents);
5eaf5a
e72428 ¤   ¤   isValidPassphrase = derr.IsntError();
92af5a
fd08aa ¤   #if PGPDISK_PUBLIC_KEY
4caf5a
5b4196 ¤   ¤   if (!isValidPassphrase)
a75b34 ¤   ¤   {
a3386c ¤   ¤   ¤   derr = VerifyPublicKeyPassphrase(mPath,·
0397a0 ¤   ¤   ¤   ¤   mPassphraseEdit.mContents);
75af5a
ec6b16 ¤   ¤   ¤   isValidPassphrase = derr.IsntError();
500fe4 ¤   ¤   }
9faf5a
e94196 ¤   ¤   if (!isValidPassphrase)
c35b34 ¤   ¤   {
51f113 ¤   ¤   ¤   if (ArePGPdiskPassesWiped(mPath))
7dc1ea ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskPassesWiped);
1c0fe4 ¤   ¤   }
f7af5a
1b0fec ¤   #endif¤ // PGPDISK_PUBLIC_KEY
c6af5a
054196 ¤   ¤   if (!isValidPassphrase)
275b34 ¤   ¤   {
13bd13 ¤   ¤   ¤   failThis = TRUE;
57af5a
86bf2c ¤   ¤   ¤   switch (derr.mMinorError)
46f776 ¤   ¤   ¤   {
4dfbfa ¤   ¤   ¤   case kPGDMinorError_IncPassAndKeyNotInRing:
1fecbd ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_IncPassAndKeyNotInRing);
2af622 ¤   ¤   ¤   ¤   break;
--7993 0017e21217d401100c5 Page 9 of CSinglePassphraseDialog.cpp
e0af5a
710270 ¤   ¤   ¤   case kPGDMinorError_PGPdiskPassesWiped:
9656ac ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_PGPdiskPassesWiped);
f4af5a
517b40 ¤   ¤   ¤   ¤   ShowReadOnlyListOfPublicKeys(mPath);
a5f622 ¤   ¤   ¤   ¤   break;
7baf5a
aadb68 ¤   ¤   ¤   default:
21456a ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_IncorrectPassphrase);
c7f622 ¤   ¤   ¤   ¤   break;
f0a3a6 ¤   ¤   ¤   }
b10fe4 ¤   ¤   }
83af5a
8f2f68 ¤   ¤   break;
f4af5a
f5a1bc ¤   case kSPDT_PublicKey:
77af5a
fc08aa ¤   #if PGPDISK_PUBLIC_KEY
1daf5a
52ac17 ¤   ¤   // Passphrase MUST be a public key passphrase.
3d6b81 ¤   ¤   derr = VerifyPublicKeyPassphrase(mPath, mPassphraseEdit.mContents);
482428 ¤   ¤   isValidPassphrase = derr.IsntError();
25af5a
754196 ¤   ¤   if (!isValidPassphrase)
2e5b34 ¤   ¤   {
fbbd13 ¤   ¤   ¤   failThis = TRUE;
2b1b0f ¤   ¤   ¤   ReportError(kPGDMajorError_IncorrectPublicKeyPassphrase);
040fe4 ¤   ¤   }
57af5a
582d62 ¤   #else¤  // !PGPDISK_PUBLIC_KEY
0eaf5a
1d8f52 ¤   ¤   pgpAssert(FALSE);
aeaf5a
e00fec ¤   #endif¤ // PGPDISK_PUBLIC_KEY
b2af5a
502f68 ¤   ¤   break;
9eaf5a
0e2f72 ¤   default:
ff8f52 ¤   ¤   pgpAssert(FALSE);
3b2f68 ¤   ¤   break;
0f9371 ¤   }
aeaf5a
3e90d1 ¤   if (failThis)
7dc7a1 ¤   {
2c788b ¤   ¤   mPassphraseEdit.ClearEditContents();
c85755 ¤   ¤   mPassphraseEdit.SetFocus();
f89371 ¤   }
d30e24 ¤   else
58c7a1 ¤   {
9a78d4 ¤   ¤   CDialog::OnOK();
e29371 ¤   }
7eefe6 }
--f808 000c4e2fd5f401100c6 Page 1 of CSinglePassphraseDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
ca0c7e // CSinglePassphraseDialog.h
0a465d //
4aaeb9 // Declaration of class CSinglePassphraseDialog.
1d1bc3 //////////////////////////////////////////////////////////////////////////////
99af5a
0b2b68 // $Id: CSinglePassphraseDialog.h,v 1.1.2.5.2.2 1998/10/28 00:13:31 nryan Exp $
aaaf5a
00cbce // Copyright (C) 1998 by Network Associates, Inc.
7771ae // All rights reserved.
57af5a
1b3cb7 #ifndef Included_CSinglePassphraseDialog_h¤ // [
eefb2f #define Included_CSinglePassphraseDialog_h
2eaf5a
383a85 #include "DualErr.h"
72c16a #include "PGPdiskFileFormat.h"
4daf5a
65572c #include "CDriveLetterCombo.h"
7f358e #include "CSecureEdit.h"
55ab81 #include "Resource.h"
f8af5a
41af5a
25d557 ////////
6f02c9 // Types
b9d557 ////////
caaf5a
86300c // SinglePassDialogType specifies the type of single passphrase dialog being
d6b57c // shown. This influences the wording of the dialog box message and the
57a1a1 // presence of certain options.
fdaf5a
0496d3 enum SinglePassDialogType {kSPDT_Change, kSPDT_Master, kSPDT_Mount,·
449817 ¤   kSPDT_PublicKey, kSPDT_Remove};
95af5a
2aaf5a
23512c ////////////////////////////////
9383b9 // Class CSinglePassphraseDialog
cf512c ////////////////////////////////
d3af5a
3b91f1 // CSinglePassphraseDialog handles all single-passphrase dialog boxes.
dbaf5a
e8f3da class CSinglePassphraseDialog : public CDialog
08bb36 {
19af5a
d55ed4 public:
c3d797 ¤   CButton¤¤   ¤   ¤   mReadOnlyButton;¤   // MFC object for read-only button
3d144c ¤   CDriveLetterCombo¤  mDriveCombo;¤   ¤   // MFC object for drive combo
e5fb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
773b9e ¤   PGPBoolean¤ ¤   ¤   mReadOnlyValue;¤¤   // read-only button checked?
11af5a
def0b7 ¤   ¤   ¤   CSinglePassphraseDialog(SinglePassDialogType dlgType);
100dad ¤   ¤   ¤   ~CSinglePassphraseDialog();
87af5a
daa8d9 ¤   DualErr¤AskForPassphrase(LPCSTR path, PGPBoolean forceReadOnly = FALSE,·
6ee012 ¤   ¤   PGPBoolean needMaster = FALSE);
9aaf5a
57c022 ¤   void¤   SetReadOnlyValue(PGPBoolean readOnly);
d63c46 ¤   void¤   DisableReadOnlyButton();
98af5a
3f0abe ¤   //{{AFX_DATA(CSinglePassphraseDialog)
fe9cfe ¤   enum { IDD = IDD_SINGLEPASS1_DLG };
e4ef8a ¤   CStatic¤mMessageStatic;
5706f5 ¤   CStatic¤mCapsLockStatic;
c3b204 ¤   CButton¤mOKButton;
cf5b03 ¤   CButton¤mCancelButton;
fe9d94 ¤   CSecureEdit¤mPassphraseEdit;
dee23b ¤   BOOL¤   mHideTypeValue;
08dc10 ¤   CString¤mMessageValue;
3a5139 ¤   //}}AFX_DATA
7caf5a
4d22ef ¤   //{{AFX_VIRTUAL(CSinglePassphraseDialog)
cd67d4 ¤   public:
c4a0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
--ebfb 0017cce49ca401100c6 Page 2 of CSinglePassphraseDialog.h
50c369 ¤   protected:
bb3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
2aaf53 ¤   //}}AFX_VIRTUAL
28af5a
a6a2d3 protected:
2fc2b4 ¤   CString¤¤   ¤   ¤   ¤   mPath;¤ ¤   ¤   ¤   ¤   ¤   // path of PGPdisk
a05cb3 ¤   SinglePassDialogType¤   mSinglePassDialogType;¤ ¤   // dialog type
81188b ¤   PGPBoolean¤ ¤   ¤   ¤   mNeedMaster;¤   ¤   ¤   ¤   // need master?
e7af5a
294b75 ¤   void¤   SetCapsLockMessageState();
72af20 ¤   DualErr TellUserAboutUnpurgablePass();
2caf5a
7551b7 ¤   //{{AFX_MSG(CSinglePassphraseDialog)
d4f17a ¤   virtual BOOL OnInitDialog();
5fc354 ¤   afx_msg void OnHideTypeCheck();
d25762 ¤   virtual void OnOK();
80698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
a56a34 ¤   afx_msg void OnROCheck();
7c2e09 ¤   //}}AFX_MSG
94af5a
442409 ¤   DECLARE_MESSAGE_MAP()
0482f7 };
38af5a
46c18c //{{AFX_INSERT_LOCATION}}
32af5a
7c7130 #endif¤ // Included_CSinglePassphraseDialog_h
--f519 00002bd9aa2401100c7 Page 1 of CSplashScreenDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
fa26ed // CSplashScreenDialog.cpp
64465d //
545ab1 // Implementation of the CSplashScreenDialog class.
2a1bc3 //////////////////////////////////////////////////////////////////////////////
41af5a
8c016c // $Id: CSplashScreenDialog.cpp,v 1.1.2.6 1998/07/29 00:45:07 nryan Exp $
ecaf5a
80cbce // Copyright (C) 1998 by Network Associates, Inc.
5071ae // All rights reserved.
1daf5a
099e12 #include "StdAfx.h"
60af5a
a79bcf #include "Required.h"
bd5e8f #include "CPGPdiskApp.h"
b6d2d2 #include "CSplashScreenDialog.h"
48c411 #include "Globals.h"
e5af5a
6eaf5a
b709b7 ////////////
57e738 // Constants
a409b7 ////////////
ffaf5a
a80eff const PGPUInt32 kSplashScreenLifeMs = 2000;¤¤   // show for this long
9caf5a
4572d7 const PGPUInt32 kSplashScreenVersionTextX¤  = 433;
c110b5 const PGPUInt32 kSplashScreenVersionTextY¤  = 208;
afaf5a
4381f3 const PGPUInt32 kSplashScreenRegTextX¤  = 296;
1d3c8c const PGPUInt32 kSplashScreenRegTextY¤  = 242;
6aaf5a
7faf5a
b483f5 ///////////////////////////
f3b249 // MFC specific definitions
6f83f5 ///////////////////////////
e3af5a
cb2741 BEGIN_MESSAGE_MAP(CSplashScreenDialog, CDialog)
1765e9 ¤   //{{AFX_MSG_MAP(CSplashScreenDialog)
618c56 ¤   ON_WM_LBUTTONDOWN()
bd79c7 ¤   ON_WM_KEYDOWN()
46fb4d ¤   ON_WM_TIMER()
142fa5 ¤   ON_WM_PAINT()
fa044a ¤   //}}AFX_MSG_MAP
83af28 END_MESSAGE_MAP()
30af5a
f0af5a
9aa6b9 ///////////////////////////////////////////////////////////////////////
1e6fdd // CSplashScreenDialog public custom functions and non-default handlers
10a6b9 ///////////////////////////////////////////////////////////////////////
4daf5a
11b3c1 // The CSplashScreenDialog default constructor.
80af5a
11f757 CSplashScreenDialog::CSplashScreenDialog(CWnd *pParent)·
82702d ¤   : CDialog(CSplashScreenDialog::IDD, pParent)
0cbb36 {
d578f1 ¤   try
a5c7a1 ¤   {
e9478a ¤   ¤   //{{AFX_DATA_INIT(CSplashScreenDialog)
08765d ¤   ¤   //}}AFX_DATA_INIT
e3af5a
6b77df ¤   ¤   mTimer = NULL;
1b9371 ¤   }
f83c88 ¤   catch (CMemoryException *ex)
e4c7a1 ¤   {
6d6adc ¤   ¤   ex->Delete();
8c9371 ¤   }
51efe6 }
f8af5a
605717 // ShowSplashScreen is a wrapper around DoModal. The dialog times out after a
87432c // certain number of seconds.
c9af5a
022292 DualErr·
--c2ed 00028c04568401100c7 Page 2 of CSplashScreenDialog.cpp
57b5ff CSplashScreenDialog::ShowSplashScreen()
45bb36 {
27be41 ¤   DualErr¤¤   derr;
fae319 ¤   PGPInt32¤   result;
f067c5 ¤
aa0acb ¤   result = DoModal();
71af5a
2ecff3 ¤   switch (result)
32c7a1 ¤   {
fee379 ¤   case -1:
1afdbb ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
9e2f68 ¤   ¤   break;
a59371 ¤   }
baaf5a
0533e3 ¤   return derr;
15efe6 }
a9af5a
31af5a
5f4a2a //////////////////////////////////////////////////////////////////////////
518415 // CSplashScreenDialog protected custom functions and non-default handlers
384a2a //////////////////////////////////////////////////////////////////////////
f5af5a
9dd7be // The CSplashScreenDialog default data-exchange function.
96af5a
15c823 void·
db56f9 CSplashScreenDialog::DoDataExchange(CDataExchange *pDX)
28bb36 {
9178f1 ¤   try
41c7a1 ¤   {
faf4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
0aaf5a
510725 ¤   ¤   //{{AFX_DATA_MAP(CSplashScreenDialog)
103376 ¤   ¤   //}}AFX_DATA_MAP
239371 ¤   }
6f3c88 ¤   catch (CMemoryException *ex)
53c7a1 ¤   {
1b6adc ¤   ¤   ex->Delete();
cb9371 ¤   }
bbefe6 }
31af5a
90af5a
774d57 /////////////////////////////////////////////////////////
2ea5ac // CSplashScreenDialog protected default message handlers
754d57 /////////////////////////////////////////////////////////
32af5a
955252 // OnInitDialog is called when the dialog box is created.
89af5a
fbe26b ¤   BOOL·
67fc8c CSplashScreenDialog::OnInitDialog()
a0bb36 {
0418a8 ¤   HDC¤¤   ¤   hDC;
9d1b02 ¤   PGPBoolean¤ loadedBitmap;
5a2e01 ¤   PGPUInt32¤  numBits;
dfaf5a
36c799 ¤   CDialog::OnInitDialog();
b1af5a
9a9c14 ¤   // Get screen depth.
1cff18 ¤   hDC = ::GetDC(NULL);¤   ¤   // DC for desktop
7f3968 ¤   numBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
166ec2 ¤   ::ReleaseDC(NULL, hDC);
82af5a
23ec20 ¤   // Load the bitmap and create a palette for it.
554932 ¤   if (numBits <= 1)
37c7a1 ¤   {
8ab46f ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SPLASHSCREEN1,·
cd37df ¤   ¤   ¤   &mSplashBitmap, &mSplashPalette);
a3af5a
8c0a8d ¤   ¤   mRegTextColor¤  ¤   = RGB(255, 255, 255);
9b9bfe ¤   ¤   mVersionTextColor¤  = RGB(255, 255, 255);
589371 ¤   }
d4d872 ¤   else if (numBits <= 4)
28c7a1 ¤   {
--28d4 00049f966ca401100c7 Page 3 of CSplashScreenDialog.cpp
8eda38 ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SPLASHSCREEN4,·
7737df ¤   ¤   ¤   &mSplashBitmap, &mSplashPalette);
3caf5a
270a8d ¤   ¤   mRegTextColor¤  ¤   = RGB(255, 255, 255);
5975be ¤   ¤   mVersionTextColor¤  = RGB(0, 0, 0);
8f9371 ¤   }
110e24 ¤   else
4bc7a1 ¤   {
064d0c ¤   ¤   loadedBitmap = App->GetBitmapAndPalette(IDB_SPLASHSCREEN8,·
e037df ¤   ¤   ¤   &mSplashBitmap, &mSplashPalette);
4faf5a
450a8d ¤   ¤   mRegTextColor¤  ¤   = RGB(255, 255, 255);
0d75be ¤   ¤   mVersionTextColor¤  = RGB(0, 0, 0);
dd9371 ¤   }
2caf5a
bc009c ¤   // Determine its width and height.
f0ac98 ¤   if (!loadedBitmap || !mSplashBitmap.GetBitmap(&mBitmapInfo))
f6c7a1 ¤   {
426611 ¤   ¤   EndDialog(IDCANCEL);
cf9371 ¤   }
91af5a
9ccb9a ¤   // Make ourselves same size as bitmap and put ourselves on top.
8f7156 ¤   SetWindowPos(&CWnd::wndTopMost, 0, 0, mBitmapInfo.bmWidth,·
48a977 ¤   ¤   mBitmapInfo.bmHeight, SWP_NOMOVE);
81af5a
63d564 ¤   // Center on screen.
0450f9 ¤   CenterWindow(GetDesktopWindow());
57af5a
53afdc ¤   // Put us in front.
199974 ¤   SetForegroundWindow();
36af5a
479b5a ¤   // Show now to thwart evil MFC auto-centering.
a6c56d ¤   ShowWindow(SW_SHOW);
04af5a
811045 ¤   // Create our timeout.
3aef3f ¤   mTimer = SetTimer(1, kSplashScreenLifeMs, NULL);
00af5a
11efb8 ¤   if (mTimer == 0)
00c7a1 ¤   {
b26611 ¤   ¤   EndDialog(IDCANCEL);
b69371 ¤   }
92af5a
0ac2e7 ¤   return TRUE;
93efe6 }
d7af5a
807168 // OnKeyDown is overridden so we can close the dialog on a keystroke.
79af5a
71c823 void·
0bc1a8 CSplashScreenDialog::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)·
69bb36 {
8f1408 ¤   KillTimer(mTimer);
7abfc0 ¤   EndDialog(IDOK);
7567c5 ¤
b2dffc ¤   CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
5eefe6 }
f4af5a
8515ce // OnLButtonDown is overridden so we can close the dialog on a click.
69af5a
18c823 void·
db1f89 CSplashScreenDialog::OnLButtonDown(UINT nFlags, CPoint point)·
86bb36 {
481408 ¤   KillTimer(mTimer);
e5bfc0 ¤   EndDialog(IDOK);
1767c5 ¤
62775f ¤   CDialog::OnLButtonDown(nFlags, point);
ddefe6 }
7eaf5a
357b5f // We override OnPaint to paint our splash screen.
96af5a
8fc823 void·
9ec4e4 CSplashScreenDialog::OnPaint()·
49bb36 {
--ed5d 001040a5f58401100c7 Page 4 of CSplashScreenDialog.cpp
f40575 ¤   CDC¤¤   ¤   memDC;
f8c943 ¤   CPaintDC¤   DC(this);
23e3a1 ¤   HBITMAP¤¤   oldBitmap;
63af5a
2e67b6 ¤   DC.SelectPalette(&mSplashPalette, FALSE);
e1cf08 ¤   DC.RealizePalette();
46af5a
76ce55 ¤   memDC.CreateCompatibleDC(&DC);
ee4fb3 ¤   memDC.SelectPalette(&mSplashPalette, FALSE);
0dbb83 ¤   memDC.RealizePalette();
5aaf5a
69e586 ¤   // MFC bug - CDC::SelectObject returns incorrect pointers/handles so don't
3a8f6e ¤   // fool with it.
41af5a
6b1634 ¤   oldBitmap = (HBITMAP) SelectObject(memDC, mSplashBitmap);
a1af5a
65cd8a ¤   // Draw the user and version strings.
d2f64a ¤   App->PaintRegistrationInfo(&memDC, kSplashScreenRegTextX,·
a1abfd ¤   ¤   kSplashScreenRegTextY, mRegTextColor, this);
faa461 ¤   App->PaintVersionInfo(&memDC, kSplashScreenVersionTextX,·
2faf24 ¤   ¤   kSplashScreenVersionTextY, mVersionTextColor, this);
f9af5a
266156 ¤   DC.BitBlt(0, 0, mBitmapInfo.bmWidth, mBitmapInfo.bmHeight, &memDC, 0, 0,·
e5d8c9 ¤   ¤   SRCCOPY);
7eaf5a
f4ac4f ¤   memDC.SelectObject(oldBitmap);
7463a9 ¤   memDC.DeleteDC();
17efe6 }
97af5a
a8d4a2 // OnTimer is overridden so we can kill the dialog when its time runs out.
f4af5a
5ec823 void·
60a2ed CSplashScreenDialog::OnTimer(UINT nIDEvent)·
45bb36 {
921408 ¤   KillTimer(mTimer);
f9bfc0 ¤   EndDialog(IDOK);
a4af5a
c295a5 ¤   CDialog::OnTimer(nIDEvent);
04efe6 }
--f509 00119e3f5e0401100c8 Page 1 of CSplashScreenDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
5fe0c4 // CSplashScreenDialog.h
d8465d //
dcb193 // Declaration of class CSplashScreenDialog.
5d1bc3 //////////////////////////////////////////////////////////////////////////////
53af5a
ab9161 // $Id: CSplashScreenDialog.h,v 1.1.2.3 1998/07/06 08:57:23 nryan Exp $
c5af5a
b5cbce // Copyright (C) 1998 by Network Associates, Inc.
2771ae // All rights reserved.
bcaf5a
1e2301 #ifndef Included_CSplashScreenDialog_h¤ // [
3a4c9e #define Included_CSplashScreenDialog_h
c8af5a
7f3a85 #include "DualErr.h"
81af5a
b2ab81 #include "Resource.h"
a2af5a
7daf5a
8a5270 ////////////////////////////
c06f17 // Class CSplashScreenDialog
045270 ////////////////////////////
7baf5a
0f5fcd class CSplashScreenDialog : public CDialog
30bb36 {
1a5ed4 public:
f0d756 ¤   ¤   ¤   CSplashScreenDialog(CWnd *pParent = NULL);
a9af5a
bd21f5 ¤   DualErr¤ShowSplashScreen();
74af5a
6f0a4d ¤   //{{AFX_DATA(CSplashScreenDialog)
a3d3ad ¤   enum { IDD = IDD_SPLASH_DLG };
a15139 ¤   //}}AFX_DATA
e1af5a
a0d2fd ¤   //{{AFX_VIRTUAL(CSplashScreenDialog)
7cc369 ¤   protected:
f73e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
4caf53 ¤   //}}AFX_VIRTUAL
fdaf5a
2aa2d3 protected:
107006 ¤   BITMAP¤ ¤   mBitmapInfo;¤   ¤   // info for the bitmap
b85516 ¤   CBitmap¤¤   mSplashBitmap;¤ ¤   // splash graphic
72ea82 ¤   CPalette¤   mSplashPalette;¤¤   // splash palette
0eaf5a
a23bdf ¤   COLORREF¤   mRegTextColor;¤ ¤   // color for registration text
32cfef ¤   COLORREF¤   mVersionTextColor;¤ // color for version text
d567c5 ¤
edf64f ¤   PGPUInt32¤  mTimer;¤¤   ¤   ¤   // timer ID
34af5a
9a4e79 ¤   //{{AFX_MSG(CSplashScreenDialog)
02f17a ¤   virtual BOOL OnInitDialog();
c84322 ¤   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
b886ac ¤   afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
7506f9 ¤   afx_msg void OnTimer(UINT nIDEvent);
b2c5f3 ¤   afx_msg void OnPaint();
a72e09 ¤   //}}AFX_MSG
28af5a
f12409 ¤   DECLARE_MESSAGE_MAP()
4082f7 };
caaf5a
40c18c //{{AFX_INSERT_LOCATION}}
a3af5a
198508 #endif¤ // ] Included_CSplashScreenDialog_h
--6b05 0007e387d04401100c9 Page 1 of CSuperHotKeyControl.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
0e7af9 // CSuperHotKeyControl.cpp
a5465d //
8d8b33 // Implementation of class CSuperHotKeyControl.
bc1bc3 //////////////////////////////////////////////////////////////////////////////
afaf5a
4ef093 // $Id: CSuperHotKeyControl.cpp,v 1.1.2.5 1998/07/06 08:57:24 nryan Exp $
3faf5a
e4cbce // Copyright (C) 1998 by Network Associates, Inc.
3871ae // All rights reserved.
03af5a
6f9e12 #include "StdAfx.h"
92af5a
2a9bcf #include "Required.h"
04babe #include "PGPdiskRegistry.h"
b4bfe9 #include "UtilityFunctions.h"
3daf5a
e4336c #include "CSuperHotKeyControl.h"
0faf5a
2aaf5a
9009b7 ////////////
bae738 // Constants
fd09b7 ////////////
e4af5a
faaac1 // Flags for GetKeyNameText.
e613c0 const PGPUInt32¤kExtendedKeyFlag¤   = 1 << 24;¤ ¤   // handle extended keys
acee89 const PGPUInt32¤kDontCareFlag¤  ¤   = 1 << 25;¤ ¤   // who cares left/right
58af5a
90af5a
3783f5 ///////////////////////////
44b249 // MFC specific definitions
d083f5 ///////////////////////////
72af5a
1228d1 BEGIN_MESSAGE_MAP(CSuperHotKeyControl, CEdit)
cdcb2d ¤   //{{AFX_MSG_MAP(CSuperHotKeyControl)
a25f6d ¤   ON_WM_MOUSEMOVE()
b6044a ¤   //}}AFX_MSG_MAP
60af28 END_MESSAGE_MAP()
66af5a
5eaf5a
fba6b9 ///////////////////////////////////////////////////////////////////////
b7a0f9 // CSuperHotKeyControl public custom functions and non-default handlers
1aa6b9 ///////////////////////////////////////////////////////////////////////
3faf5a
d9b430 // The CSuperHotKeyControl default constructor.
feaf5a
40b371 CSuperHotKeyControl::CSuperHotKeyControl()
43bb36 {
7e3f1a ¤   mPrimaryVKey = NULL;
7bf3a9 ¤   mModKeyState = NULL;
62efe6 }
d9af5a
c388c9 // The CSuperHotKeyControl default destructor.
a0af5a
a9022e CSuperHotKeyControl::~CSuperHotKeyControl()
efbb36 {
14efe6 }
a6af5a
154ef6 // GetHotKey returns the current hotkey. The low-order byte is the virtual key
28ed24 // code, the high-order byte is the modifier flags.
dcaf5a
ee411c PGPUInt16·
70432f CSuperHotKeyControl::GetHotKey()
4ebb36 {
0f52cd ¤   return MakeWord(mPrimaryVKey, mModKeyState);
23efe6 }
e1af5a
116a38 // SetHotKey sets the current hotkey. The low-order byte is the virtual key
1ced24 // code, the high-order byte is the modifier flags.
95af5a
69c823 void·
7e4305 CSuperHotKeyControl::SetHotKey(PGPUInt16 code)
--a031 000a6aad4d2401100c9 Page 2 of CSuperHotKeyControl.cpp
2cbb36 {
08c809 ¤   mPrimaryVKey = GetLowByte(code);
3a6cf4 ¤   mModKeyState = GetHighByte(code);
47af5a
4c13c8 ¤   UpdateHotKeyDisplay();
caefe6 }
8daf5a
e2c005 // PreTranslateMessage is overridden so we can get at the key-code messages
79b6a8 // at the earliest possible moment.
54af5a
c27efe BOOL·
b9b078 CSuperHotKeyControl::PreTranslateMessage(MSG* pMsg)·
ebbb36 {
1af87e ¤   switch (pMsg->message)
e5c7a1 ¤   {
d2b11a ¤   case WM_KEYDOWN:
a0e8bf ¤   case WM_SYSKEYDOWN:
463750 ¤   ¤   ProcessKeyDown((PGPUInt8) pMsg->wParam, pMsg->lParam);
1c836c ¤   ¤   return TRUE;
27af5a
ca948b ¤   case WM_KEYUP:
7ea040 ¤   case WM_SYSKEYUP:
e0836c ¤   ¤   return TRUE;
c79371 ¤   }
4eaf5a
e20426 ¤   return CEdit::PreTranslateMessage(pMsg);
5defe6 }
bdaf5a
74af5a
ae4a2a //////////////////////////////////////////////////////////////////////////
ffad2d // CSuperHotKeyControl protected custom functions and non-default handlers
ea4a2a //////////////////////////////////////////////////////////////////////////
b4af5a
85598d // ProcessKeyDown performs hot-key processing relating to key presses.
85af5a
2cc823 void·
8a6fab CSuperHotKeyControl::ProcessKeyDown(PGPUInt8 vKey, PGPUInt32 wmKeyData)·
94bb36 {
2ad6ef ¤   PGPUInt8 primaryVKey, modKeyState;
b0af5a
be8368 ¤   primaryVKey = vKey & 0x7F;
2a3c71 ¤   modKeyState = NULL;
eaaf5a
706f15 ¤   switch (primaryVKey)
b2c7a1 ¤   {
b0e158 ¤   case VK_CONTROL:¤   // we take care of modifier keys separately
82770a ¤   case VK_MENU:
a47304 ¤   case VK_SHIFT:
522f68 ¤   ¤   break;
99af5a
4f0a3d ¤   case VK_CANCEL:¤¤   // these keys don't work for whatever reason
4c4fd6 ¤   case VK_PAUSE:
2c67a4 ¤   case VK_SCROLL:
862f68 ¤   ¤   break;
06af5a
debbf4 ¤   case VK_F1:¤¤   ¤   // don't do F1 since it shows help
912f68 ¤   ¤   break;
adaf5a
ffa6e7 ¤   default:¤   ¤   ¤   // all other keys we can handle
fad6fd ¤   ¤   if (wmKeyData & kExtendedKeyFlag)
6384e1 ¤   ¤   ¤   modKeyState |= kSHK_Extended;
b4af5a
41efbc ¤   ¤   if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
bb7fa8 ¤   ¤   ¤   modKeyState |= kSHK_Control;
06af5a
af3c0b ¤   ¤   if (GetAsyncKeyState(VK_MENU) & 0x8000)
28c37d ¤   ¤   ¤   modKeyState |= kSHK_Alt;
44af5a
e3cb8d ¤   ¤   if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
b4ddcb ¤   ¤   ¤   modKeyState |= kSHK_Shift;
32af5a
a6f23e ¤   ¤   mPrimaryVKey = primaryVKey;
--0f3a 0012412d375401100c9 Page 3 of CSuperHotKeyControl.cpp
207841 ¤   ¤   mModKeyState = modKeyState;
99af5a
dc07e0 ¤   ¤   UpdateHotKeyDisplay();
9eaf5a
722f68 ¤   ¤   break;
9d9371 ¤   }
74efe6 }
44af5a
cd9c0f // UpdateHotKeyDisplay is the heart of this control. It updates the edit box
6bfe13 // display and the mCurrentCombo member variable according to the current
f285a4 // hotkey.
bbaf5a
6fc823 void·
af9fce CSuperHotKeyControl::UpdateHotKeyDisplay()
9bbb36 {
6078f1 ¤   try
14c7a1 ¤   {
78dc83 ¤   ¤   CString¤¤   keyText, temp;
e65227 ¤   ¤   PGPUInt8¤   scanCode;
01b5a3 ¤   ¤   PGPUInt32¤  keyNameData;
cbaf5a
fa0f2d ¤   ¤   if (mModKeyState & kSHK_Control)
715b34 ¤   ¤   {
bc40f4 ¤   ¤   ¤   keyText += "Ctrl+";
8b0fe4 ¤   ¤   }
41af5a
d01a5d ¤   ¤   if (mModKeyState & kSHK_Alt)
c55b34 ¤   ¤   {
b530a8 ¤   ¤   ¤   keyText += "Alt+";
e70fe4 ¤   ¤   }
7daf5a
5de942 ¤   ¤   if (mModKeyState & kSHK_Shift)
075b34 ¤   ¤   {
873b76 ¤   ¤   ¤   keyText += "Shift+";
100fe4 ¤   ¤   }
acaf5a
74e56e ¤   ¤   // Gather data about the key.
dabc66 ¤   ¤   scanCode¤   = MapVirtualKey(mPrimaryVKey, 0);
060625 ¤   ¤   keyNameData = MakeLong(0, scanCode) | kDontCareFlag;
cdaf5a
8dc138 ¤   ¤   if (mModKeyState & kSHK_Extended)
75bcfd ¤   ¤   ¤   keyNameData |= kExtendedKeyFlag;
adaf5a
833b24 ¤   ¤   // Get the name of the key.
1a7135 ¤   ¤   GetKeyNameText(keyNameData, temp.GetBuffer(kMaxStringSize),·
b640e7 ¤   ¤   ¤   kMaxStringSize);
0ae62c ¤   ¤   temp.ReleaseBuffer();
9faf5a
175f7f ¤   ¤   keyText += temp;
9a16bb ¤   ¤   SetWindowText(keyText);
bc9371 ¤   }
f03c88 ¤   catch (CMemoryException *ex)
73c7a1 ¤   {
d46adc ¤   ¤   ex->Delete();
949371 ¤   }
0cefe6 }
f8af5a
0daf5a
0519ca /////////////////////////////////////////////////
cab6b0 // CSuperHotKeyControl protected default handlers
7519ca /////////////////////////////////////////////////
93af5a
e336bc // OnMouseMove is called when the mouse moves within the control.
9baf5a
6ec823 void·
1e4a1e CSuperHotKeyControl::OnMouseMove(UINT nFlags, CPoint point)·
d3bb36 {
cc158e ¤   // Disallow selections.
24efe6 }
--c9a5 0013ec6241c401100ca Page 1 of CSuperHotKeyControl.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d96042 // CSuperHotKeyControl.h
75465d //
221f57 // Declaration of class CSuperHotKeyControl.
481bc3 //////////////////////////////////////////////////////////////////////////////
0aaf5a
2439ab // $Id: CSuperHotKeyControl.h,v 1.1.2.4 1998/07/06 08:57:25 nryan Exp $
38af5a
7dcbce // Copyright (C) 1998 by Network Associates, Inc.
8471ae // All rights reserved.
47af5a
77b40c #ifndef Included_CSuperHotKeyControl_h¤ // [
03cc18 #define Included_CSuperHotKeyControl_h
45af5a
b2af5a
9b5270 ////////////////////////////
aaefd9 // Class CSuperHotKeyControl·
0d5270 ////////////////////////////
96af5a
452297 // A CSuperHotKeyControl is like a CHotKeyCtrl except it handles many more key
64886b // combinations.
e6af5a
44d129 class CSuperHotKeyControl : public CEdit
fcbb36 {
fc5ed4 public:
2d873c ¤   ¤   ¤   ¤   CSuperHotKeyControl();
95b5b0 ¤   virtual¤¤   ~CSuperHotKeyControl();
19af5a
724267 ¤   PGPUInt16¤  GetHotKey();
b92a86 ¤   void¤   ¤   SetHotKey(PGPUInt16 code);
46af5a
e37c39 ¤   //{{AFX_VIRTUAL(CSuperHotKeyControl)
3c67d4 ¤   public:
fba0b4 ¤   virtual BOOL PreTranslateMessage(MSG* pMsg);
82af53 ¤   //}}AFX_VIRTUAL
60af5a
0fa2d3 protected:
f71ce6 ¤   PGPUInt8¤   mPrimaryVKey;¤  ¤   // the primary (non-mod) key
2df99c ¤   PGPUInt8¤   mModKeyState;¤  ¤   // state of alt, control, shift
e0af5a
675fe8 ¤   void¤   ProcessKeyDown(PGPUInt8 vKey, PGPUInt32 wmKeyData);
b27aab ¤   void¤   UpdateHotKeyDisplay();
dbaf5a
6ae0bd ¤   //{{AFX_MSG(CSuperHotKeyControl)
aa0e54 ¤   afx_msg void OnMouseMove(UINT nFlags, CPoint point);
642e09 ¤   //}}AFX_MSG
f2af5a
f52409 ¤   DECLARE_MESSAGE_MAP()
5282f7 };
f4af5a
d5c18c //{{AFX_INSERT_LOCATION}}
acaf5a
3e058e #endif¤ // ] Included_CSuperHotKeyControl_h
--b384 0002cfb3abf401100cb Page 1 of CUnmountPGPdiskDialog.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
703877 // CUnmountPGPdiskDialog.cpp
da465d //
956ef8 // Implementation of the CUnmountPGPdiskDialog class.
ba1bc3 //////////////////////////////////////////////////////////////////////////////
1caf5a
000304 // $Id: CUnmountPGPdiskDialog.cpp,v 1.1.2.5 1998/07/29 00:45:10 nryan Exp $
00af5a
6bcbce // Copyright (C) 1998 by Network Associates, Inc.
0e71ae // All rights reserved.
9baf5a
669e12 #include "StdAfx.h"
a3af5a
c39bcf #include "Required.h"
6ca918 #include "CUnmountPGPdiskDialog.h"
e3c411 #include "Globals.h"
f868c6 #include "PGPdisk.h"
554713 #include "PGPdiskHelpIds.h"
64af5a
4faf5a
386cc2 /////////////////////
473a71 // Context help array
c76cc2 /////////////////////
afaf5a
5a77bf static PGPUInt32 HelpIds[] =
f2bb36 {
58ac5a ¤   IDCANCEL,¤  ¤   ¤   ¤   IDH_PGPDISKAPP_UNMOUNTCANCEL,·
e372d8 ¤   IDC_UNMOUNT,¤   ¤   ¤   IDH_PGPDISKAPP_UNMOUNTUNMOUNT,·
010253 ¤   IDC_DRIVE_COMBO,¤   ¤   IDH_PGPDISKAPP_UNMOUNTDRIVE,·
a899f9 ¤   IDC_STATIC,¤¤   ¤   ¤   -1,·
bf4434 ····0,0·
ef82f7 };
71af5a
d4af5a
1483f5 ///////////////////////////
1fb249 // MFC specific definitions
1b83f5 ///////////////////////////
27af5a
60197a BEGIN_MESSAGE_MAP(CUnmountPGPdiskDialog, CDialog)
a264aa ¤   //{{AFX_MSG_MAP(CUnmountPGPdiskDialog)
d46973 ¤   ON_BN_CLICKED(IDC_UNMOUNT, OnUnmount)
77db65 ¤   ON_WM_HELPINFO()
d4044a ¤   //}}AFX_MSG_MAP
7faf28 END_MESSAGE_MAP()
e1af5a
e9af5a
a2186d /////////////////////////////////////////////////////////////////////////
127aef // CUnmountPGPdiskDialog public custom functions and non-default handlers
d6186d /////////////////////////////////////////////////////////////////////////
14af5a
64aee0 // The CUnmountPGPdiskDialog default constructor.
0baf5a
4c6922 CUnmountPGPdiskDialog::CUnmountPGPdiskDialog(CWnd *pParent)
3cf670 ¤   : CDialog(CUnmountPGPdiskDialog::IDD, pParent)
f7bb36 {
327b1a ¤   //{{AFX_DATA_INIT(CUnmountPGPdiskDialog)
e1b1e8 ¤   //}}AFX_DATA_INIT
f0af5a
6a125f ¤   mDriveToUnmount = kInvalidDrive;
a8efe6 }
d6af5a
c7be53 // The CUnmountPGPdiskDialog destructor.
82af5a
61bbf7 CUnmountPGPdiskDialog::~CUnmountPGPdiskDialog()
a1bb36 {
c6efe6 }
ccaf5a
74d2bb // AskForDriveLetter is a wrapper around DoModal.
9caf5a
712292 DualErr·
a6a04d CUnmountPGPdiskDialog::AskForDriveLetter()
2cbb36 {
--9abd 0002edcc31c401100cb Page 2 of CUnmountPGPdiskDialog.cpp
8bbe41 ¤   DualErr¤¤   derr;
3ee319 ¤   PGPInt32¤   result;
1767c5 ¤
640acb ¤   result = DoModal();
baaf5a
5ccff3 ¤   switch (result)
c3c7a1 ¤   {
40e379 ¤   case -1:
eefdbb ¤   ¤   derr = DualErr(kPGDMinorError_DialogDisplayFailed);
4f2f68 ¤   ¤   break;
32af5a
aa4a02 ¤   case IDCANCEL:
0638df ¤   ¤   derr = DualErr(kPGDMinorError_UserAbort);
d22f68 ¤   ¤   break;
a19371 ¤   }
2faf5a
0b33e3 ¤   return derr;
f8efe6 }
18af5a
e7af5a
91063a ////////////////////////////////////////////////////////////////////////////
a85c2a // CUnmountPGPdiskDialog protected custom functions and non-default handlers
8c063a ////////////////////////////////////////////////////////////////////////////
15af5a
932f17 // The CUnmountPGPdiskDialog data exchange function.
15af5a
10c823 void·
61a7ef CUnmountPGPdiskDialog::DoDataExchange(CDataExchange *pDX)
6cbb36 {
3c78f1 ¤   try
23c7a1 ¤   {
14f4b3 ¤   ¤   CDialog::DoDataExchange(pDX);
a5af5a
8947b4 ¤   ¤   //{{AFX_DATA_MAP(CUnmountPGPdiskDialog)
7f98b3 ¤   ¤   DDX_Control(pDX, IDC_DRIVE_COMBO, mDriveComboBox);
3d3376 ¤   ¤   //}}AFX_DATA_MAP
459371 ¤   }
373c88 ¤   catch (CMemoryException *ex)
29c7a1 ¤   {
a76adc ¤   ¤   ex->Delete();
6c9371 ¤   }
77efe6 }
97af5a
1d2214 // OnUnmount is called when the user pressed the 'Unmount' button.
3daf5a
dbc823 void·
49a643 CUnmountPGPdiskDialog::OnUnmount()·
aebb36 {
e18d47 ¤   PGPInt16 index = mDriveComboBox.GetCurSel();
e2af5a
e79d89 ¤   // If the user made a selection, then...
4ffcdc ¤   if (index != CB_ERR)
b9c7a1 ¤   {
736da8 ¤   ¤   PGPUInt8 comboIndex, drive;
22af5a
a95488 ¤   ¤   comboIndex = 0;
92af5a
d27d87 ¤   ¤   // ...for each drive letter...
b371d0 ¤   ¤   for (drive = 0; drive < kMaxDrives; drive++)
fb5b34 ¤   ¤   {
4f0172 ¤   ¤   ¤   PGPdisk *pPGD;
51af5a
899bd3 ¤   ¤   ¤   // ...if it's a mounted PGPdisk...
2871f6 ¤   ¤   ¤   pPGD = App->mPGPdisks.FindPGPdisk(drive);
caaf5a
bbfe58 ¤   ¤   ¤   if (IsntNull(pPGD))
25f776 ¤   ¤   ¤   {
936f21 ¤   ¤   ¤   ¤   // ... and it corresponds to the user's selection...
d5350e ¤   ¤   ¤   ¤   if (comboIndex == index)
9b72c3 ¤   ¤   ¤   ¤   {
69e5a5 ¤   ¤   ¤   ¤   ¤   // ... mark it for unmount.
2e6456 ¤   ¤   ¤   ¤   ¤   mDriveToUnmount = drive;
--782e 00003f76ed6401100cb Page 3 of CUnmountPGPdiskDialog.cpp
f014c3 ¤   ¤   ¤   ¤   ¤   break;
092613 ¤   ¤   ¤   ¤   }
5baf5a
bced9f ¤   ¤   ¤   ¤   comboIndex++;
bea3a6 ¤   ¤   ¤   }
210fe4 ¤   ¤   }
519371 ¤   }
c1af5a
7ebfc0 ¤   EndDialog(IDOK);
a0efe6 }
02af5a
b3af5a
e78fbd ///////////////////////////////////////////////////
7973ef // CUnmountPGPdiskDialog protected default handlers
d48fbd ///////////////////////////////////////////////////
53af5a
028cca // OnHelpInfo handles context-sensitive help.
85af5a
db7efe BOOL·
4959dc CUnmountPGPdiskDialog::OnHelpInfo(HELPINFO *pHelpInfo)
28bb36 {
ae29b0 ¤   if ((pHelpInfo->iContextType == HELPINFO_WINDOW) &&
12e5bd ¤   ¤   (pHelpInfo->iCtrlId != ((PGPUInt16) IDC_STATIC)))
c0c7a1 ¤   {
f6ae78 ¤   ¤   ::WinHelp((HWND) pHelpInfo->hItemHandle, App->m_pszHelpFilePath,·
4e6b1a ¤   ¤   ¤   HELP_WM_HELP, (PGPUInt32) HelpIds);
3d9371 ¤   }
5daf5a
64c2e7 ¤   return TRUE;
19efe6 }
9baf5a
d44b0d // OnInitDialog performs dialog box initialization.
36af5a
e97efe BOOL·
d92571 CUnmountPGPdiskDialog::OnInitDialog()·
75bb36 {
60b667 ¤   PGPUInt8 drive = 0;
1daf5a
a0c799 ¤   CDialog::OnInitDialog();
e8af5a
e37e32 ¤   // For each mounted PGPdisk, insert an entry for it in the combo box.
27cc0f ¤   for (drive = 2; drive < kMaxDrives; drive++)
27c7a1 ¤   {
12e393 ¤   ¤   PGPdisk *pPGD;
b7af5a
c7dff7 ¤   ¤   pPGD = App->mPGPdisks.FindPGPdisk(drive);
81af5a
f95306 ¤   ¤   if (IsntNull(pPGD))
d05b34 ¤   ¤   {
d91af1 ¤   ¤   ¤   char¤   label[kMaxStringSize];
9ec1fa ¤   ¤   ¤   CString¤driveChoice;
9daf5a
7e89da ¤   ¤   ¤   pPGD->GetVolumeLabel(label, kMaxStringSize);
e5af5a
0c5780 ¤   ¤   ¤   // Convert all but first letter of volume label to lowercase.
9541b9 ¤   ¤   ¤   if (strlen(label) > 1)
beac1b ¤   ¤   ¤   ¤   _strlwr(label + 1);
afaf5a
4167ad ¤   ¤   ¤   driveChoice.Format("%s (%c:)", label, DriveNumToLet(drive));
3987c7 ¤   ¤   ¤
08677a ¤   ¤   ¤   if (mDriveComboBox.AddString(driveChoice) == CB_ERR)
07e02f ¤   ¤   ¤   ¤   EndDialog(IDCANCEL);
590fe4 ¤   ¤   }
879371 ¤   }
92af5a
9fc31c ¤   if (App->mPGPdisks.GetNumPGPdisks() == 0)
ec7d7a ¤   ¤   mDriveComboBox.EnableWindow(FALSE);
740e24 ¤   else
059023 ¤   ¤   mDriveComboBox.SetCurSel(0);
46af5a
b8d564 ¤   // Center on screen.
0350f9 ¤   CenterWindow(GetDesktopWindow());
--3a5a 00153cf4ae3401100cb Page 4 of CUnmountPGPdiskDialog.cpp
e0af5a
6fafdc ¤   // Put us in front.
719974 ¤   SetForegroundWindow();
b0af5a
4454ed ¤   // Put on top if necessary.
f1c3a9 ¤   App->TweakOnTopAttribute(this);
79af5a
b29b5a ¤   // Show now to thwart evil MFC auto-centering.
88c56d ¤   ShowWindow(SW_SHOW);
c1af5a
f8065a ¤   // Set focus to the combo box.
10d471 ¤   mDriveComboBox.SetFocus();
7aaf5a
05a230 ¤   return FALSE;
53efe6 }
--3d6c 001001c4cf7401100cc Page 1 of CUnmountPGPdiskDialog.h
541bc3 //////////////////////////////////////////////////////////////////////////////
7e582c // CUnmountPGPdiskDialog.h
1a465d //
c6e39e // Declaration of class CUnmountPGPdiskDialog.
8b1bc3 //////////////////////////////////////////////////////////////////////////////
3eaf5a
2cff6a // $Id: CUnmountPGPdiskDialog.h,v 1.1.2.3 1998/07/06 08:57:26 nryan Exp $
b7af5a
efcbce // Copyright (C) 1998 by Network Associates, Inc.
8d71ae // All rights reserved.
70af5a
80600a #ifndef Included_CUnmountPGPdiskDialog_h¤   // [
30dd7e #define Included_CUnmountPGPdiskDialog_h
a0af5a
0d3a85 #include "DualErr.h"
03af5a
b0ab81 #include "Resource.h"
0baf5a
a6af5a
e6b474 //////////////////////////////
63af69 // Class CUnmountPGPdiskDialog
e2b474 //////////////////////////////
13af5a
a70e7a // CUnmountPGPdiskDialog handles all single-passphrase dialog boxes.
28af5a
e57fee class CUnmountPGPdiskDialog : public CDialog
90bb36 {
39af5a
a05ed4 public:
67b41d ¤   PGPUInt8 mDriveToUnmount;¤  ¤   // specifies the PGPdisk to unmount
ecaf5a
df472e ¤   ¤   ¤   CUnmountPGPdiskDialog(CWnd* pParent = NULL);
b12675 ¤   ¤   ¤   ~CUnmountPGPdiskDialog();
64af5a
c471e3 ¤   DualErr¤AskForDriveLetter();
b6af5a
f337c4 ¤   //{{AFX_DATA(CUnmountPGPdiskDialog)
7c5d48 ¤   enum { IDD = IDD_UNMOUNT_DLG };
0b114f ¤   CComboBox¤  mDriveComboBox;
165139 ¤   //}}AFX_DATA
d2af5a
3b576f ¤   //{{AFX_VIRTUAL(CUnmountPGPdiskDialog)
34c369 ¤   protected:
2c3e26 ¤   virtual void DoDataExchange(CDataExchange *pDX);
ddaf53 ¤   //}}AFX_VIRTUAL
75af5a
65a2d3 protected:
bce226 ¤   //{{AFX_MSG(CUnmountPGPdiskDialog)
acf17a ¤   virtual BOOL OnInitDialog();
35a408 ¤   afx_msg void OnUnmount();
70698a ¤   afx_msg BOOL OnHelpInfo(HELPINFO *pHelpInfo);
db2e09 ¤   //}}AFX_MSG
c1af5a
2d2409 ¤   DECLARE_MESSAGE_MAP()
d382f7 };
33af5a
c1c18c //{{AFX_INSERT_LOCATION}}
c5af5a
00cb3e #endif¤ // ] Included_CUnmountPGPdiskDialog_h
--fdfa 000b336cacb401100cd Page 1 of File.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
e328a6 // File.cpp
c5465d //
73e74f // Implementation of class File.
281bc3 //////////////////////////////////////////////////////////////////////////////
a2af5a
79bc2e // $Id: File.cpp,v 1.1.2.16.2.1 1998/09/01 00:31:36 nryan Exp $
02af5a
8ccbce // Copyright (C) 1998 by Network Associates, Inc.
ac71ae // All rights reserved.
04af5a
0a9e12 #include "StdAfx.h"
86af5a
959bcf #include "Required.h"
d3bfe9 #include "UtilityFunctions.h"
44af5a
5ff037 #include "File.h"
2ec411 #include "Globals.h"
94af5a
fdaf5a
4d3e71 /////////////////////////////////////
ad6d9e // Class File public member functions
c73e71 /////////////////////////////////////
d2af5a
73bde2 // The Class File default constructor.
e0af5a
df84a4 File::File()
93bb36 {
2cefc6 ¤   mHandle = INVALID_HANDLE_VALUE;
25efe6 }
9aaf5a
9675e0 // The Class File destructor.
b1af5a
ba7def File::~File()
23bb36 {
9d8984 ¤   if (Opened())
fa96bb ¤   ¤   Close();
79af5a
c908f2 ¤   ClearPath();
bdefe6 }
7baf5a
035958 // IsHostNetworked returns TRUE if the file's host drive is remote.
5faf5a
7277be PGPBoolean·
863f67 File::IsHostNetworked()
97bb36 {
f73a7b ¤   return mIsHostNetworked;
2cefe6 }
60af5a
61d00b // IsPathSet returns TRUE if a path is set, FALSE otherwise.
3daf5a
4077be PGPBoolean·
56e7b4 File::IsPathSet()
e9bb36 {
a75fb3 ¤   return (!mPath.IsEmpty());
22efe6 }
a8af5a
ff275f // Opened returns TRUE if the file is open, FALSE otherwise.
1aaf5a
9777be PGPBoolean·
106e7f File::Opened()
03bb36 {
521f00 ¤   return (mHandle != INVALID_HANDLE_VALUE);
4defe6 }
6baf5a
a5b5bf // GetLocalHostDrive returns the drive number of the volume that hosts this
b0700f // file, but only if it is a local host.
6aaf5a
cf5540 PGPUInt8
ad3387 File::GetLocalHostDrive()
8ebb36 {
b30062 ¤   pgpAssert(!IsHostNetworked());
--7239 000d43e79a9401100cd Page 2 of File.cpp
e0af5a
b5a141 ¤   return DriveLetToNum(mPath[0]);
9cefe6 }
66af5a
82c906 // GetPath returns a constant pointer to to the path of the attached pathname.
69af5a
b003c3 LPCSTR·
8fab91 File::GetPath()
8ebb36 {
e3a07a ¤   return (LPCSTR) mPath;
b4efe6 }
7daf5a
564c95 // SetPath sets the attached filename to 'path' without opening the file.
18af5a
e82292 DualErr·
13f2a8 File::SetPath(LPCSTR path)
65bb36 {
a97d36 ¤   DualErr derr;
a2af5a
b2639f ¤   pgpAssertStrValid(path);
4be7de ¤   pgpAssert(!Opened());
8eaf5a
4478f1 ¤   try
69c7a1 ¤   {
674212 ¤   ¤   mIsHostNetworked = IsNetworkedPath(path);
ebaf5a
dd4979 ¤   ¤   ClearPath();
7bd5dc ¤   ¤   mPath = path;
1c9371 ¤   }
c43c88 ¤   catch (CMemoryException *ex)
e3c7a1 ¤   {
ffecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
b96adc ¤   ¤   ex->Delete();
5d9371 ¤   }
abaf5a
7233e3 ¤   return derr;
2aefe6 }
1aaf5a
3680b1 // ClearPath frees the attached pathname.
53af5a
4fc823 void·
2551b6 File::ClearPath()
f9bb36 {
5de7de ¤   pgpAssert(!Opened());
56af5a
d0e4f7 ¤   mPath.Empty();
3eefe6 }
3daf5a
d64235 // ComparePaths returns TRUE if the passed pathname represents the same file
c668c0 // as the attached pathname.
b8af5a
5d77be PGPBoolean·
ddb3e1 File::ComparePaths(LPCSTR path)
a4bb36 {
5d639f ¤   pgpAssertStrValid(path);
39af5a
c0865a ¤   return (mPath.CompareNoCase(path) == 0);
09efe6 }
63af5a
4c75f0 // GetLength returns the length of the file in bytes.
76af5a
e42292 DualErr·
1e6be5 File::GetLength(PGPUInt64 *pLength)
d1bb36 {
f89a95 ¤   DualErr¤¤   ¤   derr;
e3f02f ¤   ULARGE_INTEGER¤ liLength;
abb859 ¤   PGPBoolean¤ ¤   weOpened¤   = FALSE;
44af5a
0b1963 ¤   pgpAssertAddrValid(pLength, PGPUInt64);
941d6a ¤   pgpAssert(IsPathSet());
0caf5a
d4232d ¤   if (!Opened())
--f3fb 00009155301401100cd Page 3 of File.cpp
f7c7a1 ¤   {
b78f9e ¤   ¤   derr = Open(NULL, kOF_MustExist | kOF_ReadOnly);
c3d5d3 ¤   ¤   weOpened = derr.IsntError();
549371 ¤   }
26af5a
7c2361 ¤   if (derr.IsntError())
24c7a1 ¤   {
19e7ab ¤   ¤   liLength.LowPart = GetFileSize(mHandle, &liLength.HighPart);
37af5a
181487 ¤   ¤   if ((liLength.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
dcff5f ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetFileSizeFailed, GetLastError());
a89371 ¤   }
40af5a
b39894 ¤   if (weOpened)
7196bb ¤   ¤   Close();
16af5a
8d2361 ¤   if (derr.IsntError())
2ec7a1 ¤   {
b28885 ¤   ¤   (* pLength) = liLength.QuadPart;
cb9371 ¤   }
12af5a
3633e3 ¤   return derr;
48efe6 }
67af5a
c19a65 // SetLength sets the length of the open file to the specified value.
0eaf5a
3f2292 DualErr·
7e4889 File::SetLength(PGPInt64 length)
28bb36 {
e29a95 ¤   DualErr¤¤   ¤   derr;
6c865d ¤   LARGE_INTEGER¤  liLength;
a5af5a
cc1148 ¤   pgpAssert(Opened());
02af5a
ae6a9c ¤   liLength.QuadPart = length;
dcaf5a
5f8301 ¤   liLength.LowPart = SetFilePointer(mHandle, liLength.LowPart,·
ad6372 ¤   ¤   &liLength.HighPart, FILE_BEGIN);
ba67c5 ¤
756dcd ¤   if ((liLength.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
b43d80 ¤   ¤   derr = DualErr(kPGDMinorError_SetFilePosFailed, GetLastError());
c8af5a
ed2361 ¤   if (derr.IsntError())
d7c7a1 ¤   {
b5f34e ¤   ¤   if (SetEndOfFile(mHandle) == 0)
5788a4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_SetEOFFailed, GetLastError());
a49371 ¤   }
09af5a
8c33e3 ¤   return derr;
26efe6 }
5caf5a
3cc322 // Open will attach 'path' to the File object and open the specified file
e2999f // with the specified flags.
70af5a
1c2292 DualErr·
660858 File::Open(LPCSTR path, PGPUInt16 flags)
56bb36 {
98be41 ¤   DualErr¤¤   derr;
6f39dd ¤   PGPBoolean¤ denyRead, denyWrite, mustExist, openReadOnly, weOpened;
c0cd74 ¤   PGPBoolean¤ truncateFile, weSetPath;
296cc8 ¤   PGPUInt32¤  accessFlags, openFlags, shareFlags;
76af5a
ddef80 ¤   weOpened = weSetPath = FALSE;
21af5a
1ae7de ¤   pgpAssert(!Opened());
3caf5a
f1af55 ¤   mustExist¤  ¤   = (flags & kOF_MustExist¤   ? TRUE : FALSE);
0a0362 ¤   openReadOnly¤   = (flags & kOF_ReadOnly¤¤   ? TRUE : FALSE);
515f45 ¤   truncateFile¤   = (flags & kOF_Trunc¤   ¤   ? TRUE : FALSE);
e326eb ·¤  denyRead¤   ¤   = (flags & kOF_DenyRead¤¤   ? TRUE : FALSE);
a305b4 ¤   denyWrite¤  ¤   = (flags & kOF_DenyWrite¤   ? TRUE : FALSE);
09af5a
--aa64 000c2c0aace401100cd Page 4 of File.cpp
d475f9 ¤   if (path)
d2c7a1 ¤   {
434d20 ¤   ¤   derr = SetPath(path);
591537 ¤   ¤   weSetPath = derr.IsntError();
0d9371 ¤   }
02af5a
942361 ¤   if (derr.IsntError())
05c7a1 ¤   {
5a7720 ¤   ¤   shareFlags = FILE_SHARE_READ | FILE_SHARE_WRITE;
daaf5a
9b20a1 ¤   ¤   if (openReadOnly)
1a5984 ¤   ¤   ¤   accessFlags¤= GENERIC_READ;
840e1d ¤   ¤   else
d1927b ¤   ¤   ¤   accessFlags = GENERIC_READ | GENERIC_WRITE;
c5af5a
939c42 ¤   ¤   if (denyRead)
17130d ¤   ¤   ¤   shareFlags &= ~FILE_SHARE_READ;
83af5a
fb531d ¤   ¤   if (denyWrite)
2f7c56 ¤   ¤   ¤   shareFlags &= ~FILE_SHARE_WRITE;
18af5a
8b03fb ¤   ¤   if (mustExist)
cb3ac4 ¤   ¤   ¤   openFlags = OPEN_EXISTING;
e30e1d ¤   ¤   else
a50792 ¤   ¤   ¤   openFlags = OPEN_ALWAYS;
69af5a
0a1f43 ¤   ¤   mHandle = CreateFile(mPath, accessFlags, shareFlags, NULL,·
0bfbf0 ¤   ¤   ¤   openFlags, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
87af5a
5b7e46 ¤   ¤   if (mHandle == INVALID_HANDLE_VALUE)
d76be3 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FileOpenFailed, GetLastError());
d7af5a
71d5d3 ¤   ¤   weOpened = derr.IsntError();
2d9371 ¤   }
e3af5a
222361 ¤   if (derr.IsntError())
d2c7a1 ¤   {
ba8fd9 ¤   ¤   if (truncateFile)
16e0f2 ¤   ¤   ¤   derr = SetLength(0);
f09371 ¤   }
92af5a
1a4bb3 ¤   if (derr.IsError())
e9c7a1 ¤   {
30a20e ¤   ¤   if (weOpened)
16d730 ¤   ¤   ¤   Close();
7daf5a
995a0a ¤   ¤   if (weSetPath)
96f8a8 ¤   ¤   ¤   ClearPath();
db9371 ¤   }
92af5a
4533e3 ¤   return derr;
08efe6 }
36af5a
982f89 // Close closes an opened file.
13af5a
012292 DualErr·
936628 File::Close()
bebb36 {
78945d ¤   DualErr¤derr;
01af5a
871148 ¤   pgpAssert(Opened());
29af5a
fa379e ¤   if (!CloseHandle(mHandle))
6c2093 ¤   ¤   derr = DualErr(kPGDMinorError_CloseHandleFailed, GetLastError());
5daf5a
742361 ¤   if (derr.IsntError())
5ec7a1 ¤   {
1b2a93 ¤   ¤   mHandle = INVALID_HANDLE_VALUE;
f99371 ¤   }
70af5a
e233e3 ¤   return derr;
c2efe6 }
--9f9a 001e3ca0baa401100cd Page 5 of File.cpp
e0af5a
478f33 // Read reads 'nBytes' bytes from position 'pos' into buffer 'buf'.
3faf5a
fc2292 DualErr·
232a44 File::Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
63bb36 {
549a95 ¤   DualErr¤¤   ¤   derr;
fddf61 ¤   LARGE_INTEGER¤  li;
77af5a
a9b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
581148 ¤   pgpAssert(Opened());
5caf5a
6101c5 ¤   li.QuadPart = pos;
a7af5a
cd124b ¤   li.LowPart = SetFilePointer(mHandle, li.LowPart, &li.HighPart,·
533264 ¤   ¤   FILE_BEGIN);
4967c5 ¤
695d89 ¤   if ((li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
873d80 ¤   ¤   derr = DualErr(kPGDMinorError_SetFilePosFailed, GetLastError());
d4af5a
812361 ¤   if (derr.IsntError())
6bc7a1 ¤   {
f27219 ¤   ¤   unsigned long numRead;
9eaf5a
22fa2c ¤   ¤   if (!ReadFile(mHandle, buf, nBytes, &numRead, NULL))
80922a ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FileReadFailed, GetLastError());
e19371 ¤   }
89af5a
d933e3 ¤   return derr;
b3efe6 }
75af5a
329888 // Write writes 'nBytes' bytes from buffer 'buf' into position 'pos'.
58af5a
f82292 DualErr·
4e33ea File::Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
8dbb36 {
0f9a95 ¤   DualErr¤¤   ¤   derr;
2ddf61 ¤   LARGE_INTEGER¤  li;
8faf5a
b0b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
061148 ¤   pgpAssert(Opened());
65af5a
9f01c5 ¤   li.QuadPart = pos;
38af5a
9d124b ¤   li.LowPart = SetFilePointer(mHandle, li.LowPart, &li.HighPart,·
373264 ¤   ¤   FILE_BEGIN);
ac67c5 ¤
9b5d89 ¤   if ((li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
183d80 ¤   ¤   derr = DualErr(kPGDMinorError_SetFilePosFailed, GetLastError());
6daf5a
c52361 ¤   if (derr.IsntError())
9fc7a1 ¤   {
8c9b08 ¤   ¤   unsigned long numWritten;
beaf5a
a8d16a ¤   ¤   if (!WriteFile(mHandle, buf, nBytes, &numWritten, NULL))
582586 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FileWriteFailed, GetLastError());
1c9371 ¤   }
6eaf5a
bc33e3 ¤   return derr;
e3efe6 }
--af85 001951ffed9401100ce Page 1 of File.h
541bc3 //////////////////////////////////////////////////////////////////////////////
ebdd5e // File.h
fb465d //
8329fa // Declaration of class File.
da1bc3 //////////////////////////////////////////////////////////////////////////////
d4af5a
aa65ff // $Id: File.h,v 1.1.2.12 1998/08/08 01:22:05 nryan Exp $
8aaf5a
2bcbce // Copyright (C) 1998 by Network Associates, Inc.
1171ae // All rights reserved.
89af5a
bb9f22 #ifndef Included_File_h¤// [
00b6cf #define Included_File_h
b6af5a
9c3a85 #include "DualErr.h"
c9af5a
30af5a
cf09b7 ////////////
00e738 // Constants
3709b7 ////////////
caaf5a
2bf624 // These are the flags for File::Open.
d2ce63 const PGPUInt16¤kOF_MustExist¤  ¤   = 0x0001;
724354 const PGPUInt16¤kOF_NoTrunc¤¤   ¤   = 0x0002;
aef69c const PGPUInt16¤kOF_Trunc¤  ¤   ¤   = 0x0004;
5e0a74 const PGPUInt16¤kOF_ReadOnly¤   ¤   = 0x0008;
76bdbf const PGPUInt16¤kOF_DenyRead¤   ¤   = 0x0010;
a36982 const PGPUInt16¤kOF_DenyWrite¤  ¤   = 0x0020;
33af5a
ceaf5a
db33ec /////////////
a06a85 // Class File
fa33ec /////////////
f4af5a
07fe6c // File represents a file on disk. File objects allow the user to attach a
448a2e // pathname to the object and open the specified path at different times.
cdaf5a
73196f class File
ffbb36 {
d95ed4 public:
ab6a97 ¤   ¤   ¤   ¤   File();
99edbc ¤   virtual¤¤   ~File();
2caf5a
421de3 ¤   PGPBoolean¤ IsHostNetworked();
d795cc ¤   PGPBoolean¤ IsPathSet();
7e9981 ¤   PGPBoolean¤ Opened();
4caf5a
417bab ¤   PGPUInt8¤   GetLocalHostDrive();
48af5a
fbb57c ¤   LPCSTR¤ ¤   GetPath();
50ad62 ¤   void¤   ¤   ClearPath();
b51b41 ¤   DualErr¤¤   SetPath(LPCSTR path);
dfaf5a
c4edd3 ¤   PGPBoolean¤ ComparePaths(LPCSTR path);
e6af5a
94c6d2 ¤   DualErr¤¤   GetLength(PGPUInt64 *pLength);
019a10 ¤   DualErr¤¤   SetLength(PGPInt64 length);
b4af5a
a6863e ¤   DualErr¤¤   Open(LPCSTR path = NULL, PGPUInt16 flags = kOF_NoTrunc);
e7112b ¤   DualErr¤¤   Close();
caaf5a
e8b825 ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
e0b00c ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
91af5a
350fb9 private:
5bcdf0 ¤   CString¤¤   mPath;¤ ¤   ¤   ¤   // pathname
fcc3fa ¤   HANDLE¤ ¤   mHandle;¤   ¤   ¤   // win32 file handle
51ae4f ¤   PGPBoolean¤ mIsHostNetworked;¤  // is the host a networked drive?
d082f7 };
eeaf5a
9548ae #endif¤ // ] Included_File_h
--4dad 0019463f80e401100cf Page 1 of Globals.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b6c9cd // Globals.h
73465d //
6e3be4 // Contains extern declarations for global variables.
221bc3 //////////////////////////////////////////////////////////////////////////////
54af5a
cc52d6 // $Id: Globals.h,v 1.1.2.5 1998/07/06 08:57:28 nryan Exp $
ceaf5a
51cbce // Copyright (C) 1998 by Network Associates, Inc.
d571ae // All rights reserved.
8faf5a
2e7e7c #ifndef Included_Globals_h¤ // [
8580bb #define Included_Globals_h
51af5a
995e8f #include "CPGPdiskApp.h"
9faf5a
c4af5a
4dc7c6 ///////////////////////////////
58269b // Global variable declarations
dbc7c6 ///////////////////////////////
43af5a
c23f89 // All of the global variables are defined in CPGPdiskApp.cpp.
faaf5a
ae21ae extern CPGPdiskApp *App;¤   ¤   // pointer to application object
efaf5a
943932 #endif¤ // ] Included_Globals_h
--746b 00092c704a7401100d0 Page 1 of PGPdisk.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
21efa8 // PGPdisk.cpp
ae465d //
4a6784 // Class PGPdisk definition.
e91bc3 //////////////////////////////////////////////////////////////////////////////
bdaf5a
fcd7c0 // $Id: PGPdisk.cpp,v 1.1.2.26.2.7 1998/10/25 23:31:31 nryan Exp $
b4af5a
7bcbce // Copyright (C) 1998 by Network Associates, Inc.
9a71ae // All rights reserved.
caaf5a
6f9e12 #include "StdAfx.h"
06b8af #include <new.h>
2caf5a
109bcf #include "Required.h"
2a4b7a #include "CommonStrings.h"
cac16a #include "PGPdiskFileFormat.h"
657414 #include "PGPdiskHighLevelUtils.h"
a82229 #include "PGPdiskLowLevelUtils.h"
8daf5a
fdea4b #if PGPDISK_PUBLIC_KEY
88f4f6 #include "PGPdiskPublicKeyUtils.h"
e438e4 #endif¤ // PGPDISK_PUBLIC_KEY
29af5a
4470d4 #include "SecureMemory.h"
6ebfe9 #include "UtilityFunctions.h"
7f6560 #include "Win32Utils.h"
c7af5a
fa8c21 #include "CipherContext.h"
d54818 #include "SHA.h"
3aaf5a
c7c411 #include "Globals.h"
6668c6 #include "PGPdisk.h"
f6af5a
8faf5a
9209b7 ////////////
f9e738 // Constants
1409b7 ////////////
2aaf5a
ee024d const PGPUInt32 kNumBlocksToConvertAtATime = 128;
05af5a
52f02b const PGPUInt32 kOffsetToCCIStruct = kDefaultBlockSize -·
0887c5 ¤   sizeof(PGPdiskCASTConvertInfo);
25af5a
e0af5a
d451ef ////////////////////////////////////////
2de872 // Class PGPdisk public member functions
8251ef ////////////////////////////////////////
efaf5a
237a41 // The (LPCSTR, PGPUInt8) overloaded constructor attaches a drive and a
1dbca9 // pathname for an already mounted PGPdisk.
b9af5a
cc1faf PGPdisk::PGPdisk(LPCSTR path, PGPUInt8 drive, PGPUInt64 sessionId)
cec861 ¤   ·: VolFile(path, drive)
7bbb36 {
ff868a ¤   mProgressBarHwnd¤   = NULL;
0bd84b ¤   mPCancelFlag¤   ¤   = NULL;
84af5a
97fbfa ¤   mInitErr = VolFile::mInitErr;
96af5a
785b69 ¤   // Read the session ID.
b69c32 ¤   if (mInitErr.IsntError())
05c7a1 ¤   {
d84187 ¤   ¤   if (IsntNull(path))
1d5b34 ¤   ¤   {
0530f8 ¤   ¤   ¤   pgpAssert(sessionId != kInvalidSessionId);
f057cb ¤   ¤   ¤   mUniqueSessionId = sessionId;
020fe4 ¤   ¤   }
049371 ¤   }
34efe6 }
b7af5a
92f7af // BestGuessComparePaths uses a number of methods to determine if the
--7410 0007ac3ab31401100d0 Page 2 of PGPdisk.cpp
77a819 // specified file is the same as the current mounted PGPdisk.
08af5a
b477be PGPBoolean·
1550b9 PGPdisk::BestGuessComparePaths(LPCSTR path)
a8bb36 {
a57777 ¤   File¤   ¤   testFile;
e2d9c7 ¤   CString¤¤   csPath, PGPdiskBareName, testBareName;
9dbe41 ¤   DualErr¤¤   derr;
6aa399 ¤   PGPBoolean¤ failedTest¤ = FALSE;
450f75 ¤   PGPUInt32¤  i, indexLastPGPdiskPathSlash, indexLastTestFilePathSlash;
fb48a1 ¤   PGPUInt32¤  numPGPdiskPathElems, numTestFilePathElems;
b36b16 ¤   CString¤¤   diskPath;
32463f ¤   CString¤¤   checkPath;
61af5a
803ec3 ¤   pgpAssert(Mounted());
3aaf5a
2af905 ¤   // First try the easy case.
24a27e ¤   if (ComparePaths(path))
f3836c ¤   ¤   return TRUE;
9caf5a
64d846 ¤   // Convert paths to canonical form.
2bdf9a ¤   if (VerifyAndCanonicalizePath(path, &csPath).IsError())
668a75 ¤   ¤   csPath = path;
6faf5a
87d1e6 ¤   // See if the number of path elements in each path is the same.
31cce3 ¤   numPGPdiskPathElems = 0;
5aaf5a
ee3cc8 ¤   for (i=0; i<strlen(diskPath); i++)
b5c7a1 ¤   {
edb7a8 ¤   ¤   if ((diskPath.GetAt(i) == '\\') ||
03d9b1 ¤   ¤   ¤   (diskPath.GetAt(i) == '/'))
905b34 ¤   ¤   {
426b65 ¤   ¤   ¤   indexLastPGPdiskPathSlash = i;
0d5fcf ¤   ¤   ¤   numPGPdiskPathElems++;
680fe4 ¤   ¤   }
059371 ¤   }
43af5a
2ea4d8 ¤   numTestFilePathElems = 0;
33af5a
9c9ce8 ¤   for (i=0; i<strlen(checkPath); i++)
fac7a1 ¤   {
92c1e5 ¤   ¤   if ((checkPath.GetAt(i) == '\\') ||
e56ae4 ¤   ¤   ¤   (checkPath.GetAt(i) == '/'))
145b34 ¤   ¤   {
b01ffc ¤   ¤   ¤   indexLastTestFilePathSlash = i;
d50c3c ¤   ¤   ¤   numTestFilePathElems++;
ae0fe4 ¤   ¤   }
839371 ¤   }
bdaf5a
962e75 ¤   if (numPGPdiskPathElems != numTestFilePathElems)
beb4e5 ¤   ¤   failedTest = TRUE;
3faf5a
68cdac ¤   // Compare the file names.
bc25f4 ¤   if (_stricmp(diskPath.Mid(indexLastPGPdiskPathSlash + 1),·
4b45cc ¤   ¤   checkPath.Mid(indexLastTestFilePathSlash + 1)) != 0)
d9c7a1 ¤   {
6db4e5 ¤   ¤   failedTest = TRUE;
a09371 ¤   }
efaf5a
d55121 ¤   // Check if the test file is in use (which must be the case with any
740d41 ¤   // mounted PGPdisk.
32af5a
598cd9 ¤   if (derr.IsntError() && !failedTest)
f3c7a1 ¤   {
3c946d ¤   ¤   if (!App->IsFileInUse(checkPath))
0fa0cd ¤   ¤   ¤   failedTest = TRUE;
949371 ¤   }
97af5a
f2444c ¤   // Finally return false if there was an error.
094bb3 ¤   if (derr.IsError())
49c7a1 ¤   {
7ab4e5 ¤   ¤   failedTest = TRUE;
--1da4 00051bd81d6401100d0 Page 3 of PGPdisk.cpp
a19371 ¤   }
93af5a
d51907 ¤   return !failedTest;
92efe6 }
92af5a
b6b967 // GetUniqueSessionId returns the unique session ID for the PGPdisk.
a2af5a
56a385 PGPUInt64·
6765e0 PGPdisk::GetUniqueSessionId()
e8bb36 {
f33ec3 ¤   pgpAssert(Mounted());
f8af5a
6b322f ¤   return mUniqueSessionId;
87efe6 }
e0af5a
0c6e62 // ReadInUniqueSessionId reads in the unique session ID from the PGPdisk.
c4af5a
7ac823 void·
e6df70 PGPdisk::ReadInUniqueSessionId(LPCSTR path)
6cbb36 {
2988f6 ¤   mUniqueSessionId = GetPGPdiskUniqueSessionId(path);
b6efe6 }
0daf5a
0ebfa0 // MakeUniqueSessionId makes a unique session ID for the PGPdisk.
56af5a
f42292 DualErr·
b0c0b9 PGPdisk::MakeUniqueSessionId(LPCSTR path)
36bb36 {
895fac ¤   FILETIME¤   fileTime;
868afa ¤   PGPUInt64¤  tenthMsSince1601;
95af5a
c4cf5a ¤   GetSystemTimeAsFileTime(&fileTime);
f4af5a
385107 ¤   tenthMsSince1601 = MakeQWord(fileTime.dwLowDateTime,·
ad7f16 ¤   ¤   fileTime.dwHighDateTime);
7faf5a
d659bd ¤   return SetPGPdiskUniqueSessionId(path, tenthMsSince1601);
39efe6 }
7baf5a
747f50 // Mount asks the driver to mount the PGPdisk specified by 'path' with the
de7620 // specified password.
daaf5a
d22292 DualErr·
1d6b3a PGPdisk::Mount(
7920cd ¤   LPCSTR¤ ¤   ¤   path,·
86da44 ¤   SecureString¤   *passphrase,·
12f4ef ¤   PGPUInt8¤   ¤   drive,·
136fde ¤   PGPBoolean¤ ¤   mountReadOnly)
2fbb36 {
1216da ¤   AD_Mount¤   ¤   ¤   MNT;
348b07 ¤   CASTKey¤¤   ¤   ¤   *decryptedKey;
e3e0d0 ¤   CipherContext¤  ¤   *pContext¤  = NULL;
f9705b ¤   DualErr¤¤   ¤   ¤   derr;
24e881 ¤   const PassphraseKey *userInfo;
fad957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
4c8fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
3a2a7b ¤   PGPUInt16¤  ¤   ¤   index;
d5af5a
17ad5f ¤   SecureMemory¤   smDecryptedKey(sizeof(CASTKey));
2e5ce0 ¤   SecureMemory¤   smContext(sizeof(CipherContext));
8caf5a
9b639f ¤   pgpAssertStrValid(path);
cbc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
b6af5a
76aeca ¤   pgpAssert(Unmounted());
bde7de ¤   pgpAssert(!Opened());
5367c5 ¤
b0c13e ¤   // Did we get our locked memory?
5877cd ¤   derr = smDecryptedKey.mInitErr;
7caf5a
182361 ¤   if (derr.IsntError())
51c7a1 ¤   {
--1a07 000ca562770401100d0 Page 4 of PGPdisk.cpp
ad3863 ¤   ¤   derr = smContext.mInitErr;
eb9371 ¤   }
b3af5a
902361 ¤   if (derr.IsntError())
35c7a1 ¤   {
f75a40 ¤   ¤   // Initialize the pointers to our locked memory.
3e96a5 ¤   ¤   decryptedKey¤   = (CASTKey *) smDecryptedKey.GetPtr();
c92419 ¤   ¤   pContext¤   ¤   = new (smContext.GetPtr()) CipherContext;¤  // <new.h>
07af5a
244798 ¤   ¤   // Set and get the session ID and the drive letter preference.
06e91e ¤   ¤   if (!mountReadOnly)
785b34 ¤   ¤   {
2caf9a ¤   ¤   ¤   MakeUniqueSessionId(path);
5c620f ¤   ¤   ¤   SetDriveLetterPref(path, drive);
d20fe4 ¤   ¤   }
40af5a
5c3c1f ¤   ¤   ReadInUniqueSessionId(path);
af9371 ¤   }
73af5a
1e9e89 ¤   // Read the header.
dc2361 ¤   if (derr.IsntError())
aac7a1 ¤   {
ae92bd ¤   ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
b6e17d ¤   ¤   readHeader = derr.IsntError();
a89371 ¤   }
e2af5a
6f2361 ¤   if (derr.IsntError())
24c7a1 ¤   {
47b595 ¤   ¤   // Look for corresponding normal passphrase key.
1cc097 ¤   ¤   derr = FindMatchingPassphrase(fileHeader, passphrase, &index);
40af5a
c4aa35 ¤   ¤   if (derr.IsntError())
ec5b34 ¤   ¤   {
021f01 ¤   ¤   ¤   // Get a pointer to the passphrase info.
02fc4a ¤   ¤   ¤   userInfo = GetPassphraseKeyPtr(fileHeader, index);
12af5a
199ebf ¤   ¤   ¤   // Force read-only if the key is read-only.
22b8a0 ¤   ¤   ¤   if (userInfo->readOnly)
155db6 ¤   ¤   ¤   ¤   mountReadOnly = TRUE;
82af5a
70f882 ¤   ¤   ¤   // Decrypt the encrypted key.
7a318d ¤   ¤   ¤   derr = DecryptPassphraseKey(userInfo, &fileHeader->salt,·
439058 ¤   ¤   ¤   ¤   passphrase, decryptedKey);
450fe4 ¤   ¤   }
b808aa ¤   #if PGPDISK_PUBLIC_KEY
44af5a
150e1d ¤   ¤   else
b45b34 ¤   ¤   {
766e9f ¤   ¤   ¤   PGPBoolean¤ ¤   ¤   ¤   gotPubKeyHdr¤   = FALSE;
640d9a ¤   ¤   ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr;
b9af5a
486a88 ¤   ¤   ¤   // Look for corresponding public key header.
a4a655 ¤   ¤   ¤   derr = FindPublicPGPdiskKeyHeader(path, passphrase, &pubKeyHdr);
ad679f ¤   ¤   ¤   gotPubKeyHdr = derr.IsntError();
c8af5a
ca9d3d ¤   ¤   ¤   if (derr.IsntError())
faf776 ¤   ¤   ¤   {
a611e8 ¤   ¤   ¤   ¤   // Force read-only if the key is read-only.
6b6274 ¤   ¤   ¤   ¤   if (pubKeyHdr->readOnly)
926158 ¤   ¤   ¤   ¤   ¤   mountReadOnly = TRUE;
94af5a
a39ab3 ¤   ¤   ¤   ¤   // Get decrypted key.
b3c173 ¤   ¤   ¤   ¤   derr = GetDecryptedKeyUsingPublicKey(passphrase, pubKeyHdr,·
1d2a8d ¤   ¤   ¤   ¤   ¤   decryptedKey);
6ca3a6 ¤   ¤   ¤   }
1caf5a
3ba5fb ¤   ¤   ¤   if (gotPubKeyHdr)
692391 ¤   ¤   ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) pubKeyHdr);
5e0fe4 ¤   ¤   }
4baf5a
920fec ¤   #endif¤ // PGPDISK_PUBLIC_KEY
ca9371 ¤   }
--7e92 000c2294f58401100d0 Page 5 of PGPdisk.cpp
e0af5a
6a2361 ¤   if (derr.IsntError())
cbc7a1 ¤   {
624e35 ¤   ¤   // Initialize the cipher context.
ea4796 ¤   ¤   pContext->InitContext(fileHeader->algorithm, decryptedKey->keyBytes,·
c4d85e ¤   ¤   ¤   fileHeader->salt.saltBytes);
7baf5a
dc0173 ¤   ¤   // Will it mount on this computer?
d84765 ¤   ¤   derr = CheckFileSystemCompatibility(path, mountReadOnly, pContext);
b99371 ¤   }
99af5a
232361 ¤   if (derr.IsntError())
fec7a1 ¤   {
df0ea6 ¤   ¤   // Prepare the mount request packet; base classes will do the rest.
b47d58 ¤   ¤   MNT.pContext = pContext;
71af5a
24438e ¤   ¤   // Call the request down.
230f38 ¤   ¤   derr = VolFile::Mount(path, drive, mountReadOnly, &MNT);
319371 ¤   }
33af5a
29fd0b ¤   if (readHeader)
303fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
c0af5a
76b48b ¤   if (IsntNull(pContext))
543f49 ¤   ¤   pContext->~CipherContext();
1aaf5a
b933e3 ¤   return derr;
35efe6 }
1aaf5a
a97498 // Unmount asks the driver to unmount us.
afaf5a
af2292 DualErr·
742545 PGPdisk::Unmount(PGPBoolean isThisEmergency)
16bb36 {
657d36 ¤   DualErr derr;
feaf5a
d53ec3 ¤   pgpAssert(Mounted());
4faf5a
be7486 ¤   // Call the request down.
2bbcc2 ¤   derr = VolFile::Unmount(isThisEmergency);
a8af5a
b733e3 ¤   return derr;
f9efe6 }
a3af5a
a404a3 // CreatePGPdisk creates a new PGPdisk at the location specified by 'path'
409fa4 // and with the desired free space specified in 'blocksData'.
3eaf5a
7f2292 DualErr·
30329e PGPdisk::CreatePGPdisk(
28ba6d ¤   LPCSTR¤ ¤   ¤   ¤   ¤   ¤   path,·
2c0912 ¤   PGPUInt64¤  ¤   ¤   ¤   ¤   blocksDisk,·
14627a ¤   PGPdiskEncryptionAlgorithm¤ algorithm,·
d0bb32 ¤   SecureString¤   ¤   ¤   ¤   *passphrase,·
0fa5bf ¤   PGPdiskRandomPool¤  ¤   ¤   *randomPool,·
4afd61 ¤   PGPUInt8¤   ¤   ¤   ¤   ¤   drive)
c8bb36 {
10705b ¤   DualErr¤¤   ¤   ¤   derr;
e98fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
ae1420 ¤   SecureMemory¤   ¤   smFileHeader(sizeof(PGPdiskFileHeader));
d1af5a
93c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
4c4960 ¤   pgpAssertAddrValid(randomPool, PGPdiskRandomPool);
c9639f ¤   pgpAssertStrValid(path);
b7af5a
c4d95d ¤   pgpAssert(algorithm != kInvalidEncryptionAlgorithm);
e3e50f ¤   pgpAssert(blocksDisk > 0);
ccaf5a
5ac13e ¤   // Did we get our locked memory?
974eee ¤   derr = smFileHeader.mInitErr;
ecaf5a
cc2361 ¤   if (derr.IsntError())
c2c7a1 ¤   {
--1b80 000c6fcef48401100d0 Page 6 of PGPdisk.cpp
3a7ea6 ¤   ¤   // Get a pointer to the locked memory.
734dcc ¤   ¤   fileHeader = (PGPdiskFileHeader *) smFileHeader.GetPtr();
f6af5a
f372c6 ¤   ¤   // Create the file.
754de1 ¤   ¤   DeleteFile(path);
38c86d ¤   ¤   derr = Open(path, kOF_Trunc);
189371 ¤   }
b2af5a
b7343f ¤   // Set its length.
982361 ¤   if (derr.IsntError())
fec7a1 ¤   {
8fcbb6 ¤   ¤   PGPUInt64 blocksLength;
e6af5a
3681a5 ¤   ¤   blocksLength = kPGPdiskReservedHeaderBlocks + blocksDisk +·
6af70c ¤   ¤   ¤   kPGPdiskAlternateHeaderBlocks;
b5af5a
26781c ¤   ¤   derr = SetLength(blocksLength*kDefaultBlockSize);
1d9371 ¤   }
bfaf5a
6f2361 ¤   if (derr.IsntError())
93c7a1 ¤   {
d6c87f ¤   ¤   // Initialize the PGPdisk file header.
d7ca5c ¤   ¤   InitPGPdiskFileHeader(fileHeader, blocksDisk, algorithm, passphrase,·
6f8b9f ¤   ¤   ¤   randomPool, drive);
c79371 ¤   }
ddaf5a
a4b137 ¤   // Encrypt the disk.
d52361 ¤   if (derr.IsntError())
8cc7a1 ¤   {
040ae0 ¤   ¤   derr = FirstTimeEncryptDiskFile(fileHeader, passphrase);
179371 ¤   }
04af5a
f44433 ¤   // Write the header out to the PGPdisk file. Need to do this
b32361 ¤   if (derr.IsntError())
95c7a1 ¤   {
637ec9 ¤   ¤   derr = FirstTimeWriteHeaderDiskFile(fileHeader);
639371 ¤   }
7caf5a
65b380 ¤   // Close the file.
db8984 ¤   if (Opened())
fa96bb ¤   ¤   Close();
4baf5a
9de5ff ¤   // Cleanup in case of error.
1a4bb3 ¤   if (derr.IsError())
aec7a1 ¤   {
724de1 ¤   ¤   DeleteFile(path);
3c9371 ¤   }
7faf5a
dc3c30 ¤   MessageBeep(MB_OK);
e3af5a
2733e3 ¤   return derr;
c1efe6 }
80af5a
92ed6e // ConvertPGPdisk attempts to re-encrypt a broken CAST PGPdisk using the
cd1baf // correct implementation of CAST.
56af5a
612292 DualErr·
4448b0 PGPdisk::ConvertPGPdisk(
b338df ¤   LPCSTR¤ ¤   ¤   ¤   path,·
b267c9 ¤   SecureString¤   ¤   *passphrase,·
62c228 ¤   PGPdiskRandomPool¤  *randomPool)
92bb36 {
c49f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
217fb2 ¤   CASTKey¤¤   ¤   ¤   ¤   *newSessionKey;
bff5e8 ¤   PGPBoolean¤ ¤   ¤   ¤   conversionRestarting, readHeader;
0841ac ¤   PGPdiskCASTConvertInfo¤ CCI;
999271 ¤   PGPdiskFileHeader¤  ¤   *fileHeader;
c2af5a
cf4587 ¤   SecureMemory¤   smFileHeader(sizeof(PGPdiskFileHeader));
5f0332 ¤   SecureMemory¤   smNewSessionKey(sizeof(CASTKey));
fcaf5a
c6ca19 ¤   conversionRestarting = readHeader = FALSE;
--eee4 0002593b3a1401100d0 Page 7 of PGPdisk.cpp
e0af5a
e3639f ¤   pgpAssertStrValid(path);
58c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
65af5a
c2c13e ¤   // Did we get our locked memory?
1f4eee ¤   derr = smFileHeader.mInitErr;
a1af5a
b92361 ¤   if (derr.IsntError())
12c7a1 ¤   {
56c206 ¤   ¤   derr = smNewSessionKey.mInitErr;
839371 ¤   }
d6af5a
e22361 ¤   if (derr.IsntError())
2dc7a1 ¤   {
112861 ¤   ¤   // Set up secure pointers.
aa1327 ¤   ¤   fileHeader¤ ¤   = (PGPdiskFileHeader *) smFileHeader.GetPtr();
ce0dac ¤   ¤   newSessionKey¤  = (CASTKey *) smNewSessionKey.GetPtr();
44af5a
eeaa3a ¤   ¤   // Open the PGPdisk.
1317e5 ¤   ¤   derr = Open(path, kOF_MustExist);
7a9371 ¤   }
c7af5a
fccb49 ¤   // Read in main header.
1e2361 ¤   if (derr.IsntError())
ffc7a1 ¤   {
5c6c93 ¤   ¤   derr = ReadPGPdiskFileMainHeader(this, &fileHeader);
a7e17d ¤   ¤   readHeader = derr.IsntError();
cd9371 ¤   }
b1af5a
432361 ¤   if (derr.IsntError())
68c7a1 ¤   {
12af8a ¤   ¤   // Are we restarting an already begun conversion?
a02e3f ¤   ¤   conversionRestarting = (fileHeader->majorVersion ==·
079171 ¤   ¤   ¤   kPGPdiskConvertInProgressMajorVersion);
16af5a
7e574d ¤   ¤   if (conversionRestarting)
635b34 ¤   ¤   {
3d1653 ¤   ¤   ¤   // Read CCI struct.
b87ded ¤   ¤   ¤   derr = File::Read((PGPUInt8 *) &CCI, kOffsetToCCIStruct,·
89620b ¤   ¤   ¤   ¤   sizeof(CCI));
e7af5a
0ca368 ¤   ¤   ¤   // Verify the stored conversion information.
1c9d3d ¤   ¤   ¤   if (derr.IsntError())
31f776 ¤   ¤   ¤   {
d2a620 ¤   ¤   ¤   ¤   if (strncmp(CCI.convertInfoMagic, kPGPdiskBadCASTInfoMagic,·
fa44f5 ¤   ¤   ¤   ¤   ¤   4) != 0)
8372c3 ¤   ¤   ¤   ¤   {
1544bd ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_BadHeaderMagic);
842613 ¤   ¤   ¤   ¤   }
89a3a6 ¤   ¤   ¤   }
d9af5a
c713cc ¤   ¤   ¤   // Retrieve the new session key.
229d3d ¤   ¤   ¤   if (derr.IsntError())
67f776 ¤   ¤   ¤   {
62d663 ¤   ¤   ¤   ¤   derr = DecryptPassphraseKey(GetPassphraseKeyPtr(fileHeader,·
c4b903 ¤   ¤   ¤   ¤   ¤   kMasterPassphraseIndex), &fileHeader->salt, passphrase,·
c5409f ¤   ¤   ¤   ¤   ¤   newSessionKey);
f1a3a6 ¤   ¤   ¤   }
880fe4 ¤   ¤   }
ae0e1d ¤   ¤   else
195b34 ¤   ¤   {
2e4eb9 ¤   ¤   ¤   pgpAssertAddrValid(randomPool, PGPdiskRandomPool);
c0af5a
19f61c ¤   ¤   ¤   // Prepare the main header for conversion.
84cfdf ¤   ¤   ¤   fileHeader->majorVersion =·
6847c3 ¤   ¤   ¤   ¤   kPGPdiskConvertInProgressMajorVersion;
ecaf5a
6ea9fe ¤   ¤   ¤   // Clear alternate passphrases.
da0988 ¤   ¤   ¤   pgpClearMemory(fileHeader->otherPassphrases,·
d8c5d0 ¤   ¤   ¤   ¤   sizeof(fileHeader->otherPassphrases));
14af5a
25a14c ¤   ¤   ¤   // Prepare conversion info structure.
--83cb 000f3d87d60401100d0 Page 8 of PGPdisk.cpp
59893b ¤   ¤   ¤   strncpy(CCI.convertInfoMagic, kPGPdiskBadCASTInfoMagic, 4);
89af5a
25a038 ¤   ¤   ¤   CCI.lastConvertedBlock = fileHeader->numHeaderBlocks - 1;
2d45fb ¤   ¤   ¤   CCI.oldSalt = fileHeader->salt;
9eaf5a
778b5b ¤   ¤   ¤   // Retrieve and save the old session key.
d6dcae ¤   ¤   ¤   derr = GetOldSessionKey(path, fileHeader, passphrase,·
e1acbf ¤   ¤   ¤   ¤   &CCI.oldSessionKey);
cbaf5a
edf82c ¤   ¤   ¤   // Put a new session key in the header.
769d3d ¤   ¤   ¤   if (derr.IsntError())
808cf3 ¤   ¤   ¤   {¤
84e229 ¤   ¤   ¤   ¤   derr = InitHeaderWithNewSessionKey(fileHeader,·
9681e9 ¤   ¤   ¤   ¤   ¤   kCASTEncryptionAlgorithm, passphrase, randomPool);
9da3a6 ¤   ¤   ¤   }
b6af5a
d9892d ¤   ¤   ¤   // Retrieve the new session key from the header.
2e9d3d ¤   ¤   ¤   if (derr.IsntError())
78f776 ¤   ¤   ¤   {
c6d663 ¤   ¤   ¤   ¤   derr = DecryptPassphraseKey(GetPassphraseKeyPtr(fileHeader,·
9cb903 ¤   ¤   ¤   ¤   ¤   kMasterPassphraseIndex), &fileHeader->salt, passphrase,·
03409f ¤   ¤   ¤   ¤   ¤   newSessionKey);
65a3a6 ¤   ¤   ¤   }
3eaf5a
8dd34c ¤   ¤   ¤   // Update main header.
3b9d3d ¤   ¤   ¤   if (derr.IsntError())
eaf776 ¤   ¤   ¤   {
adb192 ¤   ¤   ¤   ¤   derr = WritePGPdiskFileMainHeader(this, fileHeader);
67a3a6 ¤   ¤   ¤   }
adaf5a
669d3d ¤   ¤   ¤   if (derr.IsntError())
8ef776 ¤   ¤   ¤   {
2b9b99 ¤   ¤   ¤   ¤   // Remove other headers (non-fatal).
1e94ed ¤   ¤   ¤   ¤   NukeAllNonADKHeaders(this, newSessionKey);
9caf5a
d61771 ¤   ¤   ¤   ¤   // Write out CCI.
7e8e2b ¤   ¤   ¤   ¤   derr = File::Write((PGPUInt8 *) &CCI, kOffsetToCCIStruct,·
c65503 ¤   ¤   ¤   ¤   ¤   sizeof(CCI));
01a3a6 ¤   ¤   ¤   }
33af5a
934891 ¤   ¤   ¤   // Read in main header again.
969d3d ¤   ¤   ¤   if (derr.IsntError())
f2f776 ¤   ¤   ¤   {
35a515 ¤   ¤   ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
d6af5a
af3cff ¤   ¤   ¤   ¤   derr = ReadPGPdiskFileMainHeader(this, &fileHeader);
7b7ea9 ¤   ¤   ¤   ¤   readHeader = derr.IsntError();
98a3a6 ¤   ¤   ¤   }
4c0fe4 ¤   ¤   }
889371 ¤   }
a9af5a
06e4f9 ¤   // Convert all non-converted blocks.
992361 ¤   if (derr.IsntError())
de58c8 ¤   {¤  ¤
639fbb ¤   ¤   PGPUInt32 numBlocks;
f2af5a
b02efb ¤   ¤   numBlocks = fileHeader->numDataBlocks -·
fd8f42 ¤   ¤   ¤   (CCI.lastConvertedBlock - fileHeader->numHeaderBlocks + 1);
92af5a
85a728 ¤   ¤   derr = ConvertBlocks(fileHeader, &CCI, &CCI.oldSessionKey,·
510701 ¤   ¤   ¤   &CCI.oldSalt, newSessionKey, &fileHeader->salt,·
3e0fe4 ¤   ¤   ¤   CCI.lastConvertedBlock + 1, numBlocks);
4d9371 ¤   }
d9af5a
d66a99 ¤   // Mark the PGPdisk as finished with the conversion process.
df2361 ¤   if (derr.IsntError())
e1c7a1 ¤   {
b5e108 ¤   ¤   fileHeader->majorVersion = kPGPdiskPrimaryHeaderMajorVersion;
a02009 ¤   ¤   fileHeader->minorVersion = kPGPdiskPrimaryHeaderMinorVersion;
21af5a
610542 ¤   ¤   fileHeader->algorithm = kCASTEncryptionAlgorithm;
f3af5a
--8007 0005aa69026401100d0 Page 9 of PGPdisk.cpp
2fe1fe ¤   ¤   derr = WritePGPdiskFileMainHeader(this, fileHeader);
409371 ¤   }
f0af5a
ff2361 ¤   if (derr.IsntError())
80c7a1 ¤   {
ddca55 ¤   ¤   MessageBeep(MB_OK);
a49371 ¤   }
a5af5a
d2fd0b ¤   if (readHeader)
ca3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
a4af5a
3d8984 ¤   if (Opened())
0496bb ¤   ¤   Close();
eaaf5a
da33e3 ¤   return derr;
36efe6 }
98af5a
1e63d0 // HighLevelFormatPGPdisk displays the format dialog. Failing that, it
b60977 // formats using our own algorithm.
f1af5a
2c2292 DualErr·
d137e0 PGPdisk::HighLevelFormatPGPdisk()
2cbb36 {
ff7d36 ¤   DualErr derr;
73af5a
523ec3 ¤   pgpAssert(Mounted());
8aaf5a
8f153d ¤   // Display the format dialog.
6fc17b ¤   derr = App->ShowWindowsFormatDialog(GetDrive());
00af5a
7396f5 ¤   // If failed, warn user and format using our own algorithm if we can.
2b4bb3 ¤   if (derr.IsError())
77c7a1 ¤   {
c09d1e ¤   ¤   ReportError(kPGDMajorError_WindowsFormatFailed, derr);
ecb754 ¤   ¤   derr = Format();
91af5a
28fef8 ¤   ¤   // Set the volume label.
bcaa35 ¤   ¤   if (derr.IsntError())
5b5b34 ¤   ¤   {
5648aa ¤   ¤   ¤   SetVolumeLabel(kPGPdiskDefaultVolLabel);
c10fe4 ¤   ¤   }
6c9371 ¤   }
13af5a
8a33e3 ¤   return derr;
26efe6 }
a8af5a
b152f9 // SetProgressBarInfo is called to specify the window handle of a progress
bdf58e // bar slider control to be used during disk creation, and also to specify
1b8b26 // a pointer to a shared boolean that will be polled to determine if the user
32637d // has canceled the operation.
0baf5a
25c823 void·
7dbb9e PGPdisk::SetProgressBarInfo(HWND hWnd, PGPBoolean *pCancelFlag)
b3bb36 {
f439af ¤   pgpAssertAddrValid(pCancelFlag, PGPBoolean);
46af5a
b2808b ¤   mProgressBarHwnd = hWnd;
7db945 ¤   mPCancelFlag = pCancelFlag;
bcaf5a
f62a90 ¤   SetProgressBarRange(0, 100);
acab71 ¤   SetProgressBarPos(0);
33efe6 }
02af5a
adaf5a
38ed79 /////////////////////////////////////////
d15286 // Class PGPdisk private member functions
6ced79 /////////////////////////////////////////
fbaf5a
c1f6c6 // HasUserCanceled checks the shared cancel variable to determine if the user
b62fa0 // has canceled the request.
a5af5a
5a77be PGPBoolean·
--5dee 00085e44858401100d0 Page 10 of PGPdisk.cpp
11f2ff PGPdisk::HasUserCanceled()
fbbb36 {
63773f ¤   if (mProgressBarHwnd && mPCancelFlag)
4dc7a1 ¤   {
30c67e ¤   ¤   pgpAssertAddrValid(mPCancelFlag, PGPBoolean);
261b52 ¤   ¤
8dc581 ¤   ¤   return (* mPCancelFlag);
759371 ¤   }
930e24 ¤   else
6ec7a1 ¤   {
f498aa ¤   ¤   return FALSE;
d49371 ¤   }
24efe6 }
d3af5a
c07285 // SetProgressBarPos sets the position of the disk creation progress bar.
09af5a
c9c823 void·
8a6bdd PGPdisk::SetProgressBarPos(PGPUInt32 nPos)
dcbb36 {
29d395 ¤   if (mProgressBarHwnd)
26e10b ¤   ¤   PostMessage(mProgressBarHwnd, PBM_SETPOS, nPos, 0);
dcefe6 }
4aaf5a
e5c8d5 // SetProgressBarRange sets the range of the disk creation progress bar.
e9af5a
a0c823 void·
361ffe PGPdisk::SetProgressBarRange(PGPUInt32 nMin, PGPUInt32 nMax)
9abb36 {
98d395 ¤   if (mProgressBarHwnd)
39c7a1 ¤   {
fa3e0a ¤   ¤   PostMessage(mProgressBarHwnd, PBM_SETRANGE, 0,·
b67c7f ¤   ¤   ¤   MAKELPARAM(nMin, nMax));
5b9371 ¤   }
7befe6 }
03af5a
41c7eb // CheckFileSystemCompatibility makes sure this PGPdisk will mount on this
fe8a4f // computer.
a7af5a
172292 DualErr·
d33f7e PGPdisk::CheckFileSystemCompatibility(
e020cd ¤   LPCSTR¤ ¤   ¤   path,·
9d236d ¤   PGPBoolean¤ ¤   mountReadOnly,·
3ae9af ¤   CipherContext¤  *pContext)
30bb36 {
66be41 ¤   DualErr¤¤   derr;
7725d1 ¤   PGPUInt8¤   *bootBlock;
2daf5a
f7639f ¤   pgpAssertStrValid(path);
5393e3 ¤   pgpAssertAddrValid(pContext, CipherContext);
4eaf5a
7578f1 ¤   try
2bc7a1 ¤   {
89b38c ¤   ¤   bootBlock = new PGPUInt8[kDefaultBlockSize];
1faf5a
a2aa3a ¤   ¤   // Open the PGPdisk.
8fdbe9 ¤   ¤   derr = Open(path, kOF_MustExist | kOF_ReadOnly);
9caf5a
717419 ¤   ¤   // Read on the boot block.
d6aa35 ¤   ¤   if (derr.IsntError())
6b5b34 ¤   ¤   {
7873e1 ¤   ¤   ¤   derr = File::Read(bootBlock,·
2a4f27 ¤   ¤   ¤   ¤   kPGPdiskReservedHeaderBlocks*kDefaultBlockSize,·
98674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
b50fe4 ¤   ¤   }
0aaf5a
8caa35 ¤   ¤   if (derr.IsntError())
bd5b34 ¤   ¤   {
f0c7bf ¤   ¤   ¤   // Decrypt it.
f3c9b3 ¤   ¤   ¤   pContext->CipherBlocks(0, 1, bootBlock, bootBlock,·
b1280f ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
d9af5a
852a67 ¤   ¤   ¤   // If NTFS perform checks.
--6931 000c17eb031401100d0 Page 11 of PGPdisk.cpp
10c199 ¤   ¤   ¤   if (strncmp((LPCSTR) &bootBlock[3], "NTFS", 4) == 0)
c4f776 ¤   ¤   ¤   {
ac7257 ¤   ¤   ¤   ¤   if (IsWin95CompatibleMachine())
4372c3 ¤   ¤   ¤   ¤   {
a08089 ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_TriedNTFSOnWin95);
d52613 ¤   ¤   ¤   ¤   }
07157d ¤   ¤   ¤   ¤   else if (mountReadOnly)
4f72c3 ¤   ¤   ¤   ¤   {
a44bdb ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_TriedReadOnlyNTFS);
a32613 ¤   ¤   ¤   ¤   }
53a3a6 ¤   ¤   ¤   }
630fe4 ¤   ¤   }
82af5a
4bb440 ¤   ¤   // Close the PGPdisk.
1eb31e ¤   ¤   if (Opened())
7ad730 ¤   ¤   ¤   Close();
acaf5a
192941 ¤   ¤   delete[] bootBlock;
329371 ¤   }
273c88 ¤   catch (CMemoryException *ex)
35c7a1 ¤   {
c8ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
506adc ¤   ¤   ex->Delete();
deaf5a
dcb31e ¤   ¤   if (Opened())
9bd730 ¤   ¤   ¤   Close();
709371 ¤   }
42af5a
2b33e3 ¤   return derr;
e2efe6 }
86af5a
466686 // InitHeaderWithNewSessionKey initializes the header with a new session
a249bf // key generated from the specified master passphrase and random data.
b1af5a
012292 DualErr·
301ecb PGPdisk::InitHeaderWithNewSessionKey(
531e2f ¤   PGPdiskFileHeader¤  ¤   ¤   *fileHeader,·
d6627a ¤   PGPdiskEncryptionAlgorithm¤ algorithm,·
18bb32 ¤   SecureString¤   ¤   ¤   ¤   *passphrase,·
e3a57c ¤   PGPdiskRandomPool¤  ¤   ¤   *randomPool)
13bb36 {
0e705b ¤   DualErr¤¤   ¤   ¤   derr;
78d65d ¤   EncryptedCASTKey¤   *key;
7a0f09 ¤   ExpandedCASTKey¤¤   *expandedKey;
27feab ¤   PGPUInt8¤   ¤   ¤   *secureBuf;
9eb347 ¤   PGPUInt32¤  ¤   ¤   i, index;
7eaf5a
c4fa73 ¤   SecureMemory¤   smKey(sizeof(EncryptedCASTKey));
5b5500 ¤   SecureMemory¤   smExpandedKey(sizeof(ExpandedCASTKey));
2a1ed1 ¤   SecureMemory¤   smSecureBuf(kMaxPassphraseLength);
28af5a
1de0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
42c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
0c4960 ¤   pgpAssertAddrValid(randomPool, PGPdiskRandomPool);
0eaf5a
3672ff ¤   // Make sure we got our locked memory.
8e6d26 ¤   derr = smKey.mInitErr;
68af5a
482361 ¤   if (derr.IsntError())
e7c7a1 ¤   {
cb18c0 ¤   ¤   derr = smExpandedKey.mInitErr;
d69371 ¤   }
b5af5a
172361 ¤   if (derr.IsntError())
96c7a1 ¤   {
9c76f9 ¤   ¤   derr = smSecureBuf.mInitErr;
149371 ¤   }
eaaf5a
582361 ¤   if (derr.IsntError())
4cc7a1 ¤   {
825a40 ¤   ¤   // Initialize the pointers to our locked memory.
c14ef9 ¤   ¤   key¤¤   ¤   = (EncryptedCASTKey *) smKey.GetPtr();
--6174 0000ba13589401100d0 Page 12 of PGPdisk.cpp
847e68 ¤   ¤   expandedKey¤= (ExpandedCASTKey *) smExpandedKey.GetPtr();
785a6d ¤   ¤   secureBuf¤  = (PGPUInt8 *) smSecureBuf.GetPtr();
85af5a
23c3e0 ¤   ¤   // Initialize the salt with random data.
7cec27 ¤   ¤   for¤(index = 0; index < sizeof(fileHeader->salt); index++)
105b34 ¤   ¤   {
ed2dd7 ¤   ¤   ¤   fileHeader->salt.saltBytes[index] = randomPool->GetByte();
560fe4 ¤   ¤   }
f21b52 ¤   ¤
1ee9be ¤   ¤   // Initialize the master passphrase with random data.
c9a89f ¤   ¤   for (index=0;·
6d97a4 ¤   ¤   ¤   index < sizeof(fileHeader->masterPassphrase.encryptedKey);·
721dfe ¤   ¤   ¤   index++)
725b34 ¤   ¤   {
0f17f3 ¤   ¤   ¤   fileHeader->masterPassphrase.encryptedKey.keyBytes[index] =·
134594 ¤   ¤   ¤   ¤   randomPool->GetByte();
bd0fe4 ¤   ¤   }
0e1b52 ¤   ¤
eeedda ¤   ¤   // Hash, salt, and schedule the passphrase. Ask for the unexpanded
91a880 ¤   ¤   // key since we will need it later.
75af5a
6259cf ¤   ¤   derr = HashSaltAndSchedule(passphrase, expandedKey,·
edf814 ¤   ¤   ¤   &fileHeader->salt, &fileHeader->masterPassphrase.hashReps, key);
949371 ¤   }
b6af5a
b32361 ¤   if (derr.IsntError())
22c7a1 ¤   {
92423c ¤   ¤   // Encrypt the random key twice
a2b86f ¤   ¤   for (i = 0; i < 2; i++)
805b34 ¤   ¤   {
9fe518 ¤   ¤   ¤   CAST5encrypt(
574255 ¤   ¤   ¤   ¤   &fileHeader->masterPassphrase.encryptedKey.keyBytes[0],·
1d4255 ¤   ¤   ¤   ¤   &fileHeader->masterPassphrase.encryptedKey.keyBytes[0],·
62eb88 ¤   ¤   ¤   ¤   expandedKey->keyDWords);
43af5a
2ee518 ¤   ¤   ¤   CAST5encrypt(
f1dafc ¤   ¤   ¤   ¤   &fileHeader->masterPassphrase.encryptedKey.keyBytes[8],
52dafc ¤   ¤   ¤   ¤   &fileHeader->masterPassphrase.encryptedKey.keyBytes[8],
08eb88 ¤   ¤   ¤   ¤   expandedKey->keyDWords);
8f0fe4 ¤   ¤   }
a1af5a
43de9d ¤   ¤   // Encrypt the key itself for checkbytes purposes.
c6e090 ¤   ¤   CAST5encrypt(key->keyBytes, key->keyBytes, expandedKey->keyDWords);
faaf5a
8c9023 ¤   ¤   for (index = 0;·
d2a803 ¤   ¤   ¤   index < sizeof(fileHeader->masterPassphrase.checkBytes);·
a61dfe ¤   ¤   ¤   index++)
e35b34 ¤   ¤   {
b64812 ¤   ¤   ¤   fileHeader->masterPassphrase.checkBytes.theBytes[index] =·
7eed47 ¤   ¤   ¤   ¤   key->keyBytes[index];
2e0fe4 ¤   ¤   }
2eaf5a
7d7c4b ¤   ¤   // Must mark as in use.
4f842e ¤   ¤   fileHeader->masterPassphrase.inUse = TRUE;
809371 ¤   }
5aaf5a
d533e3 ¤   return derr;
65efe6 }
90af5a
2a08e5 // InitPGPdiskFileHeader initializes a brand new PGPdisk file header.
46af5a
fe2292 DualErr·
32bc66 PGPdisk::InitPGPdiskFileHeader(
d71e2f ¤   PGPdiskFileHeader¤  ¤   ¤   *fileHeader,·
b80912 ¤   PGPUInt64¤  ¤   ¤   ¤   ¤   blocksDisk,·
ba627a ¤   PGPdiskEncryptionAlgorithm¤ algorithm,·
fcbb32 ¤   SecureString¤   ¤   ¤   ¤   *passphrase,·
d2a5bf ¤   PGPdiskRandomPool¤  ¤   ¤   *randomPool,·
ecfd61 ¤   PGPUInt8¤   ¤   ¤   ¤   ¤   drive)
15bb36 {
7a7d36 ¤   DualErr derr;
0baf5a
--7b62 000eeb7790e401100d0 Page 13 of PGPdisk.cpp
e7e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
82c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
954960 ¤   pgpAssertAddrValid(randomPool, PGPdiskRandomPool);
69af5a
96d95d ¤   pgpAssert(algorithm != kInvalidEncryptionAlgorithm);
27af5a
06e50f ¤   pgpAssert(blocksDisk > 0);
1e4d30 ¤   pgpAssert(blocksDisk < 0xFFFFFFFF);¤// header doesn't do 64-bit yet
51af5a
1a6051 ¤   // Initialize the default fields of the header.
95b906 ¤   pgpClearMemory(fileHeader, sizeof(PGPdiskFileHeader));¤
dbaf5a
41787b ¤   strncpy(fileHeader->headerInfo.headerMagic, kPGPdiskHeaderMagic, 4);
04dd2f ¤   strncpy(fileHeader->headerInfo.headerType, kPGPdiskPrimaryHeaderType, 4);
afd5fa ¤   fileHeader->headerInfo.headerSize = sizeof(PGPdiskFileHeader);
85af5a
d73060 ¤   fileHeader->majorVersion¤   = kPGPdiskPrimaryHeaderMajorVersion;
42e9ad ¤   fileHeader->minorVersion¤   = kPGPdiskPrimaryHeaderMinorVersion;
c7af5a
c44587 ¤   fileHeader->algorithm = algorithm;
c7af5a
f1cdc8 ¤   fileHeader->numHeaderBlocks¤= kPGPdiskReservedHeaderBlocks;
c732f7 ¤   fileHeader->numDataBlocks¤  = (PGPUInt32) blocksDisk;
edaf5a
c100f1 ¤   fileHeader->numFileBlocks = kPGPdiskReservedHeaderBlocks +·
88ea4b ¤   ¤   fileHeader->numDataBlocks + kPGPdiskAlternateHeaderBlocks;
1aaf5a
60a0fd ¤   fileHeader->drive¤  ¤   ¤   = drive;
60b9b2 ¤   fileHeader->mountedFlag¤¤   = FALSE;
d0c6e7 ¤   fileHeader->uniqueSessionId¤= kInvalidSessionId;
21af5a
31c961 ¤   // Initialize the header with a new session key.
fba2fa ¤   derr = InitHeaderWithNewSessionKey(fileHeader, algorithm, passphrase,·
af2057 ¤   ¤   randomPool);
b5af5a
742361 ¤   if (derr.IsntError())
45c7a1 ¤   {
7c7c38 ¤   ¤   // Update the CRC.
862f7f ¤   ¤   UpdatePGPdiskFileHeaderCRC((PGPdiskFileHeaderInfo *) fileHeader);
9d9371 ¤   }
7aaf5a
9d33e3 ¤   return derr;
a6efe6 }
7aaf5a
11a53c // FirstTimeEncryptDiskFile wipes the non-FAT blocks and encrypts all of the
e44364 // non-header blocks in a new, open PGPdisk.
3baf5a
bf2292 DualErr·
b8175c PGPdisk::FirstTimeEncryptDiskFile(
e18d79 ¤   PGPdiskFileHeader¤  *fileHeader,·
e6fff8 ¤   SecureString¤   ¤   *passphrase)
0ebb36 {
4a1e85 ¤   CASTKey¤¤   ¤   *decryptedKey;
a4ad29 ¤   CipherContext¤  *pContext¤  ¤   = NULL;
019a95 ¤   DualErr¤¤   ¤   derr;
b6197a ¤   PGPBoolean¤ ¤   createdWriteBuffer¤ = FALSE;
25c540 ¤   PGPUInt8¤   ¤   *dataBuf;
f631ff ¤   PGPUInt32¤  ¤   blocksBuf;
7baf5a
c7ad5f ¤   SecureMemory¤   smDecryptedKey(sizeof(CASTKey));
405ce0 ¤   SecureMemory¤   smContext(sizeof(CipherContext));
35af5a
cb1148 ¤   pgpAssert(Opened());
f8e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
5ec1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
1baf5a
a072ff ¤   // Make sure we got our locked memory.
4877cd ¤   derr = smDecryptedKey.mInitErr;
d7af5a
542361 ¤   if (derr.IsntError())
cbc7a1 ¤   {
ee3863 ¤   ¤   derr = smContext.mInitErr;
--7b6b 000dc705682401100d0 Page 14 of PGPdisk.cpp
a19371 ¤   }
93af5a
cf2361 ¤   if (derr.IsntError())
69c7a1 ¤   {
a95a40 ¤   ¤   // Initialize the pointers to our locked memory.
c296a5 ¤   ¤   decryptedKey¤   = (CASTKey *) smDecryptedKey.GetPtr();
f22419 ¤   ¤   pContext¤   ¤   = new (smContext.GetPtr()) CipherContext;¤  // <new.h>
4d1b52 ¤   ¤
4bc46c ¤   ¤   // Decrypt the encrypted key.
776f26 ¤   ¤   derr = DecryptPassphraseKey(&fileHeader->masterPassphrase,·
f9bb85 ¤   ¤   ¤   &fileHeader->salt, passphrase, decryptedKey);
869371 ¤   }
74af5a
112361 ¤   if (derr.IsntError())
82c7a1 ¤   {
ae4e35 ¤   ¤   // Initialize the cipher context.
ae4796 ¤   ¤   pContext->InitContext(fileHeader->algorithm, decryptedKey->keyBytes,·
40d85e ¤   ¤   ¤   fileHeader->salt.saltBytes);
edaf5a
8b9299 ¤   ¤   // Get the memory for our data buffer.
7638cf ¤   ¤   derr = CreateReasonableWriteBuffer(fileHeader->numDataBlocks,·
c852ef ¤   ¤   ¤   &dataBuf, &blocksBuf);
b4af5a
3abd05 ¤   ¤   createdWriteBuffer = derr.IsntError();
b29371 ¤   }
a8af5a
e2b9fe ¤   // Format the PGPdisk.
7b31cb ¤   if (derr.IsntError() && !HasUserCanceled())
6dc7a1 ¤   {
cc05c2 ¤   ¤   PGPUInt32¤  blocksThisTime, endBlock, startBlock;
c5a8ba ¤   ¤   PGPUInt32¤  totalWrites, writesDone, writesPerUpdate;
47af5a
ea4794 ¤   ¤   // Calculate the starting and ending blocks.
65f9d7 ¤   ¤   startBlock¤ = fileHeader->numHeaderBlocks;
ed6fe6 ¤   ¤   endBlock¤   = startBlock + fileHeader->numDataBlocks;
2faf5a
483ed4 ¤   ¤   // Calculate information used for progress bar updates.
2e3388 ¤   ¤   totalWrites = (PGPUInt32)·
dc32d9 ¤   ¤   ¤   CeilDiv(endBlock - startBlock, blocksBuf);
3baf5a
ee7e05 ¤   ¤   writesDone = 0;
891913 ¤   ¤   writesPerUpdate = (PGPUInt32) CeilDiv(totalWrites, 100);
3faf5a
8dabd8 ¤   ¤   // Encrypt the PGPdisk.
dc400e ¤   ¤   for (PGPUInt32 i = startBlock; i < endBlock; i += blocksBuf)
a45b34 ¤   ¤   {
847200 ¤   ¤   ¤   blocksThisTime = min(blocksBuf, endBlock - i);
84af5a
2ff746 ¤   ¤   ¤   // Encrypt the blocks and output them.
1f9d3d ¤   ¤   ¤   if (derr.IsntError())
e5f776 ¤   ¤   ¤   {
8872cd ¤   ¤   ¤   ¤   pgpClearMemory(dataBuf, blocksThisTime*kDefaultBlockSize);
f6af5a
b7ae51 ¤   ¤   ¤   ¤   pContext->CipherBlocks(i - fileHeader->numHeaderBlocks,·
885c4d ¤   ¤   ¤   ¤   ¤   blocksThisTime, dataBuf, dataBuf, kCipherOp_Encrypt);
69af5a
656552 ¤   ¤   ¤   ¤   derr = File::Write(dataBuf, i*kDefaultBlockSize,·
52f509 ¤   ¤   ¤   ¤   ¤   blocksThisTime*kDefaultBlockSize);
b0a3a6 ¤   ¤   ¤   }
48af5a
309263 ¤   ¤   ¤   // Update the progress dialog.
729d3d ¤   ¤   ¤   if (derr.IsntError())
b3f776 ¤   ¤   ¤   {
fa82c2 ¤   ¤   ¤   ¤   if (writesDone++ % writesPerUpdate == 0)
5cb50f ¤   ¤   ¤   ¤   ¤   SetProgressBarPos(writesDone*100/totalWrites);
95a3a6 ¤   ¤   ¤   }
36af5a
16e92d ¤   ¤   ¤   if (derr.IsError() || HasUserCanceled())
a9f776 ¤   ¤   ¤   {
02f622 ¤   ¤   ¤   ¤   break;
9ca3a6 ¤   ¤   ¤   }
dc0fe4 ¤   ¤   }
--46a1 0001eb1e2c6401100d0 Page 15 of PGPdisk.cpp
a19371 ¤   }
93af5a
799e33 ¤   // If the user cancelled the creation, fail but don't be noisy.
db2e9a ¤   if (HasUserCanceled())
f26823 ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
63af5a
e8d35d ¤   if (createdWriteBuffer)
e39877 ¤   ¤   FreeByteBuffer(dataBuf);
7baf5a
6ab48b ¤   if (IsntNull(pContext))
ae3f49 ¤   ¤   pContext->~CipherContext();
d9af5a
2433e3 ¤   return derr;
c3efe6 }
b6af5a
54a772 // FirstTimeWriteHeaderDiskFile clears the reserved headers blocks and writes
f534d2 // out the header to the specified PGPdisk.
f1af5a
f72292 DualErr·
68c134 PGPdisk::FirstTimeWriteHeaderDiskFile(PGPdiskFileHeader* fileHeader)
29bb36 {
e0be41 ¤   DualErr¤¤   derr;
52a9f5 ¤   PGPUInt8¤   blanks[kDefaultBlockSize];
b40721 ¤   PGPUInt32¤  i;
05af5a
44e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
bc1148 ¤   pgpAssert(Opened());
c2af5a
a71300 ¤   pgpClearMemory(blanks, kDefaultBlockSize);
edaf5a
f91438 ¤   // Clear the main header blocks.
887dc1 ¤   for (i = 0; i < fileHeader->numHeaderBlocks; i++)
cac7a1 ¤   {
7bf2f4 ¤   ¤   derr = File::Write(blanks, i*kDefaultBlockSize,·
0cecb7 ¤   ¤   ¤   kDefaultBlockSize);
4baf5a
9abdd6 ¤   ¤   if (derr.IsError())
d7cdcb ¤   ¤   ¤   break;
009371 ¤   }
f3af5a
2aa670 ¤   // Clear the alternate header blocks.
ee2361 ¤   if (derr.IsntError())
6ec7a1 ¤   {
706d8d ¤   ¤   PGPUInt32 altStart;
73af5a
1195bb ¤   ¤   altStart = fileHeader->numHeaderBlocks + fileHeader->numDataBlocks;
7eaf5a
20646c ¤   ¤   for (i=0; i<kPGPdiskAlternateHeaderBlocks; i++)
dc5b34 ¤   ¤   {
b649c3 ¤   ¤   ¤   derr = File::Write(blanks, (altStart+i)*kDefaultBlockSize,·
09674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
5aaf5a
c71088 ¤   ¤   ¤   if (derr.IsError())
9bf622 ¤   ¤   ¤   ¤   break;
a90fe4 ¤   ¤   }
0c9371 ¤   }
58af5a
4fb646 ¤   // Write out the header.
f22361 ¤   if (derr.IsntError())
96c7a1 ¤   {
8be1fe ¤   ¤   derr = WritePGPdiskFileMainHeader(this, fileHeader);
079371 ¤   }
9faf5a
8733e3 ¤   return derr;
b3efe6 }
69af5a
d78a49 // GetOldSessionKey extracts the old session key from a PGPdisk.
0faf5a
782292 DualErr·
09f1e1 PGPdisk::GetOldSessionKey(
2138df ¤   LPCSTR¤ ¤   ¤   ¤   path,·
1e8d79 ¤   PGPdiskFileHeader¤  *fileHeader,·
--e2c4 00088c00940401100d0 Page 16 of PGPdisk.cpp
c067c9 ¤   SecureString¤   ¤   *passphrase,·
ee4852 ¤   CASTKey¤¤   ¤   ¤   *oldSessionKey)
71bb36 {
c37d36 ¤   DualErr derr;
7eaf5a
4a639f ¤   pgpAssertStrValid(path);
6be0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
77c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
0da2e7 ¤   pgpAssertAddrValid(oldSessionKey, CASTKey);
b01148 ¤   pgpAssert(Opened());
a5af5a
4ba324 ¤   // Must close file first.
171ef5 ¤   derr = Close();
a8af5a
e02361 ¤   if (derr.IsntError())
36c7a1 ¤   {
227beb ¤   ¤   if (ArePGPdiskPassesWiped(path))
165b34 ¤   ¤   {
286e9f ¤   ¤   ¤   PGPBoolean¤ ¤   ¤   ¤   gotPubKeyHdr¤   = FALSE;
4a0d9a ¤   ¤   ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr;
08af5a
526a88 ¤   ¤   ¤   // Look for corresponding public key header.
ada655 ¤   ¤   ¤   derr = FindPublicPGPdiskKeyHeader(path, passphrase, &pubKeyHdr);
57679f ¤   ¤   ¤   gotPubKeyHdr = derr.IsntError();
6aaf5a
6c9d3d ¤   ¤   ¤   if (derr.IsntError())
45f776 ¤   ¤   ¤   {
289ab3 ¤   ¤   ¤   ¤   // Get decrypted key.
ddc173 ¤   ¤   ¤   ¤   derr = GetDecryptedKeyUsingPublicKey(passphrase, pubKeyHdr,·
6d823e ¤   ¤   ¤   ¤   ¤   oldSessionKey);
b7a3a6 ¤   ¤   ¤   }
a1af5a
46a5fb ¤   ¤   ¤   if (gotPubKeyHdr)
202391 ¤   ¤   ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) pubKeyHdr);
7a0fe4 ¤   ¤   }
3e0e1d ¤   ¤   else
435b34 ¤   ¤   {
39c2ce ¤   ¤   ¤   // Get old session key from master passphrase.
654bb9 ¤   ¤   ¤   derr = DecryptPassphraseKey(GetPassphraseKeyPtr(fileHeader,·
b424d9 ¤   ¤   ¤   ¤   kMasterPassphraseIndex), &fileHeader->salt, passphrase,·
2a09c2 ¤   ¤   ¤   ¤   oldSessionKey);
000fe4 ¤   ¤   }
c99371 ¤   }
e8af5a
152361 ¤   if (derr.IsntError())
44c7a1 ¤   {
da17e5 ¤   ¤   derr = Open(path, kOF_MustExist);
339371 ¤   }
b7af5a
bc33e3 ¤   return derr;
21efe6 }
ddaf5a
df3d93 // ConvertBlocks converts the specified blocks in the PGPdisk to the new
6e98b5 // session key.
66af5a
ec2292 DualErr·
de3c1b PGPdisk::ConvertBlocks(
204e40 ¤   PGPdiskFileHeader¤  ¤   *fileHeader,·
03dfef ¤   PGPdiskCASTConvertInfo¤ *pCCI,·
7cfff6 ¤   const CASTKey¤  ¤   ¤   *oldSessionKey,·
abbc93 ¤   const PassphraseSalt¤   *oldSalt,·
f03d57 ¤   const CASTKey¤  ¤   ¤   *newSessionKey,·
49732b ¤   const PassphraseSalt¤   *newSalt,·
26f0fc ¤   PGPUInt32¤  ¤   ¤   ¤   startingBlock,·
1659cc ¤   PGPUInt32¤  ¤   ¤   ¤   numBlocks)
c2bb36 {
fce5c5 ¤   CipherContext¤  *pNewContext, *pOldContext;
e09a95 ¤   DualErr¤¤   ¤   derr;
ba197a ¤   PGPBoolean¤ ¤   createdWriteBuffer¤ = FALSE;
4ac540 ¤   PGPUInt8¤   ¤   *dataBuf;
64af5a
880946 ¤   SecureMemory¤   smNewContext(sizeof(CipherContext));
--2ea8 000e9c5aae3401100d0 Page 17 of PGPdisk.cpp
412db9 ¤   SecureMemory¤   smOldContext(sizeof(CipherContext));
ffaf5a
25201d ¤   pNewContext = pOldContext = NULL;
37af5a
491148 ¤   pgpAssert(Opened());
e0e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
c4c1ca ¤   pgpAssertAddrValid(pCCI, PGPdiskCASTConvertInfo);
31a2e7 ¤   pgpAssertAddrValid(oldSessionKey, CASTKey);
cd7988 ¤   pgpAssertAddrValid(newSessionKey, CASTKey);
1daf5a
4b72ff ¤   // Make sure we got our locked memory.
83ba69 ¤   derr = smNewContext.mInitErr;
b1af5a
772361 ¤   if (derr.IsntError())
a9c7a1 ¤   {
97b635 ¤   ¤   derr = smOldContext.mInitErr;
bc9371 ¤   }
52af5a
762361 ¤   if (derr.IsntError())
60c7a1 ¤   {
7e5a40 ¤   ¤   // Initialize the pointers to our locked memory.
fb58a3 ¤   ¤   pNewContext¤¤   = new (smNewContext.GetPtr()) CipherContext;
f6cfdf ¤   ¤   pOldContext¤¤   = new (smOldContext.GetPtr()) CipherContext;
abaf5a
c1f1f5 ¤   ¤   // Initialize the cipher contexts.
a8bfb0 ¤   ¤   pNewContext->InitContext(kCASTEncryptionAlgorithm,·
cf3945 ¤   ¤   ¤   newSessionKey->keyBytes, newSalt->saltBytes);
feaf5a
c3d59d ¤   ¤   pOldContext->InitContext(kBrokenCASTEncryptionAlgorithm,·
9416de ¤   ¤   ¤   oldSessionKey->keyBytes, oldSalt->saltBytes);
32af5a
5d9299 ¤   ¤   // Get the memory for our data buffer.
4e004e ¤   ¤   derr = GetByteBuffer(kNumBlocksToConvertAtATime * kDefaultBlockSize,·
8e9224 ¤   ¤   ¤   &dataBuf);
e5af5a
87bd05 ¤   ¤   createdWriteBuffer = derr.IsntError();
569371 ¤   }
25af5a
8b5c5f ¤   // Convert the blocks.
f231cb ¤   if (derr.IsntError() && !HasUserCanceled())
5ac7a1 ¤   {
572321 ¤   ¤   PGPUInt32¤  blocksBuf, blocksThisTime, endBlock, startBlock;
9ea8ba ¤   ¤   PGPUInt32¤  totalWrites, writesDone, writesPerUpdate;
06af5a
2261eb ¤   ¤   blocksBuf = kNumBlocksToConvertAtATime;
02af5a
0f4794 ¤   ¤   // Calculate the starting and ending blocks.
97802b ¤   ¤   startBlock¤ = startingBlock;
9c9524 ¤   ¤   endBlock¤   = startBlock + numBlocks;
2daf5a
ef3ed4 ¤   ¤   // Calculate information used for progress bar updates.
1b3388 ¤   ¤   totalWrites = (PGPUInt32)·
9632d9 ¤   ¤   ¤   CeilDiv(endBlock - startBlock, blocksBuf);
99af5a
df7e05 ¤   ¤   writesDone = 0;
b61913 ¤   ¤   writesPerUpdate = (PGPUInt32) CeilDiv(totalWrites, 100);
34af5a
b8abd8 ¤   ¤   // Encrypt the PGPdisk.
33400e ¤   ¤   for (PGPUInt32 i = startBlock; i < endBlock; i += blocksBuf)
c25b34 ¤   ¤   {
6d7200 ¤   ¤   ¤   blocksThisTime = min(blocksBuf, endBlock - i);
17af5a
015fb8 ¤   ¤   ¤   // Read the blocks.
cad922 ¤   ¤   ¤   derr = File::Read(dataBuf, i*kDefaultBlockSize,·
9ae42e ¤   ¤   ¤   ¤   blocksThisTime*kDefaultBlockSize);
33af5a
a09d3d ¤   ¤   ¤   if (derr.IsntError())
c0f776 ¤   ¤   ¤   {
9de8b5 ¤   ¤   ¤   ¤   // Decrypt the blocks.
effb08 ¤   ¤   ¤   ¤   pOldContext->CipherBlocks(i - fileHeader->numHeaderBlocks,·
a6d9a7 ¤   ¤   ¤   ¤   ¤   blocksThisTime, dataBuf, dataBuf, kCipherOp_Decrypt);
e9af5a
--0a3a 001ae24e994401100d0 Page 18 of PGPdisk.cpp
6f3025 ¤   ¤   ¤   ¤   // Encrypt the blocks.
263254 ¤   ¤   ¤   ¤   pNewContext->CipherBlocks(i - fileHeader->numHeaderBlocks,·
2d5c4d ¤   ¤   ¤   ¤   ¤   blocksThisTime, dataBuf, dataBuf, kCipherOp_Encrypt);
75af5a
2a3377 ¤   ¤   ¤   ¤   // Write the blocks.
e16552 ¤   ¤   ¤   ¤   derr = File::Write(dataBuf, i*kDefaultBlockSize,·
94f509 ¤   ¤   ¤   ¤   ¤   blocksThisTime*kDefaultBlockSize);
20a3a6 ¤   ¤   ¤   }
11af5a
67f86b ¤   ¤   ¤   // Write the updated block counter.
d79d3d ¤   ¤   ¤   if (derr.IsntError())
70f776 ¤   ¤   ¤   {
315105 ¤   ¤   ¤   ¤   pCCI->lastConvertedBlock = i + blocksThisTime - 1;
16af5a
85540b ¤   ¤   ¤   ¤   derr = File::Write((PGPUInt8 *) pCCI, kOffsetToCCIStruct,·
bca3f8 ¤   ¤   ¤   ¤   ¤   sizeof(PGPdiskCASTConvertInfo));
9ba3a6 ¤   ¤   ¤   }
4faf5a
2f9263 ¤   ¤   ¤   // Update the progress dialog.
1a9d3d ¤   ¤   ¤   if (derr.IsntError())
26f776 ¤   ¤   ¤   {
d482c2 ¤   ¤   ¤   ¤   if (writesDone++ % writesPerUpdate == 0)
ccb50f ¤   ¤   ¤   ¤   ¤   SetProgressBarPos(writesDone*100/totalWrites);
27a3a6 ¤   ¤   ¤   }
4faf5a
72e92d ¤   ¤   ¤   if (derr.IsError() || HasUserCanceled())
75f776 ¤   ¤   ¤   {
00f622 ¤   ¤   ¤   ¤   break;
f0a3a6 ¤   ¤   ¤   }
9c0fe4 ¤   ¤   }
cd9371 ¤   }
d7af5a
419e33 ¤   // If the user cancelled the creation, fail but don't be noisy.
bb2e9a ¤   if (HasUserCanceled())
1a6823 ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
2daf5a
6ed35d ¤   if (createdWriteBuffer)
869877 ¤   ¤   FreeByteBuffer(dataBuf);
7eaf5a
e5b645 ¤   if (IsntNull(pOldContext))
1d1bf4 ¤   ¤   pOldContext->~CipherContext();
35af5a
ceb3a7 ¤   if (IsntNull(pNewContext))
8ee8d6 ¤   ¤   pNewContext->~CipherContext();
ebaf5a
8c33e3 ¤   return derr;
aeefe6 }
--341d 00016bd2594401100d1 Page 1 of PGPdisk.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d75cf4 // PGPdisk.h
2f465d //
dcdda2 // Declaration of class PGPdisk.
a11bc3 //////////////////////////////////////////////////////////////////////////////
92af5a
75ed35 // $Id: PGPdisk.h,v 1.1.2.12.2.4 1998/10/25 23:31:32 nryan Exp $
61af5a
9bcbce // Copyright (C) 1998 by Network Associates, Inc.
9e71ae // All rights reserved.
85af5a
29849e #ifndef Included_PGPdisk_h¤ // [
b11582 #define Included_PGPdisk_h
71af5a
9f3a85 #include "DualErr.h"
8bc16a #include "PGPdiskFileFormat.h"
f485af #include "SecureString.h"
b2af5a
15b1e1 #include "PGPdiskRandomPool.h"
7eb3b1 #include "VolFile.h"
d9af5a
57af5a
889791 ////////////////
8d0e4d // Class PGPdisk
599791 ////////////////
0eaf5a
b1b7f8 // Class PGPdisk represents a PGPdisk volume file.
b3af5a
35d265 class PGPdisk : public VolFile
34bb36 {
df5ed4 public:
191603 ¤   DualErr mInitErr;
92af5a
40e8f4 ¤   ¤   ¤   PGPdisk(LPCSTR path = NULL, PGPUInt8 drive = kInvalidDrive,·
918b2d ¤   ¤   ¤   ¤   PGPUInt64 sessionId = kInvalidSessionId);
87079c ¤   ¤   ¤   ~PGPdisk() { };
17af5a
a21410 ¤   PGPBoolean¤ BestGuessComparePaths(LPCSTR path);
aeaf5a
fb7110 ¤   PGPUInt64¤  GetUniqueSessionId();
4d6eec ¤   void¤   ¤   ReadInUniqueSessionId(LPCSTR path);
4f494b ¤   DualErr¤¤   MakeUniqueSessionId(LPCSTR path);
d7af5a
b040ea ¤   DualErr¤¤   Mount(LPCSTR path, SecureString *passphrase,·
0a34fa ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive,·
f95c56 ¤   ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly = FALSE);
3f499b ¤   DualErr¤¤   Unmount(PGPBoolean isThisEmergency = FALSE);
68af5a
22c30e ¤   DualErr¤¤   CreatePGPdisk(LPCSTR path, PGPUInt64 blocksDisk,·
64cb1d ¤   ¤   ¤   ¤   ¤   PGPdiskEncryptionAlgorithm algorithm,·
736c74 ¤   ¤   ¤   ¤   ¤   SecureString *passphrase, PGPdiskRandomPool *randomPool,·
a0282b ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive);
edaf5a
335140 ¤   DualErr¤¤   ConvertPGPdisk(LPCSTR path, SecureString *passphrase,·
73c550 ¤   ¤   ¤   ¤   ¤   PGPdiskRandomPool *randomPool);
d1af5a
2a16ce ¤   DualErr¤¤   HighLevelFormatPGPdisk();
b0af5a
4cf093 ¤   void¤   ¤   SetProgressBarInfo(HWND hWnd, PGPBoolean *pCancelFlag = NULL);
deaf5a
050fb9 private:
c25b51 ¤   HWND¤   ¤   mProgressBarHwnd;¤  ¤   // handle of progress bar
03c229 ¤   PGPBoolean¤ *mPCancelFlag;¤ ¤   ¤   // points to user cancel indicator
e223ee ¤   PGPUInt64¤  mUniqueSessionId;¤  ¤   // unique session ID
57af5a
7f7bbc ¤   PGPBoolean¤ HasUserCanceled();
c470ee ¤   void¤   ¤   SetProgressBarPos(PGPUInt32 nPos);
0d4625 ¤   void¤   ¤   SetProgressBarRange(PGPUInt32 nMin, PGPUInt32 nMax);
c8af5a
c3896e ¤   DualErr¤¤   CheckFileSystemCompatibility(LPCSTR path,·
d1f6ed ¤   ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly, CipherContext *pContext);
16af5a
--2e70 0016271d59c401100d1 Page 2 of PGPdisk.h
26f604 ¤   DualErr¤¤   InitHeaderWithNewSessionKey(PGPdiskFileHeader *fileHeader,·
01cb1d ¤   ¤   ¤   ¤   ¤   PGPdiskEncryptionAlgorithm algorithm,·
1270a5 ¤   ¤   ¤   ¤   ¤   SecureString *passphrase, PGPdiskRandomPool *randomPool);
35af5a
a0f433 ¤   DualErr¤¤   InitPGPdiskFileHeader(PGPdiskFileHeader *fileHeader,·
5a1817 ¤   ¤   ¤   ¤   ¤   PGPUInt64 blocksDisk,·
b9cb1d ¤   ¤   ¤   ¤   ¤   PGPdiskEncryptionAlgorithm algorithm,·
316c74 ¤   ¤   ¤   ¤   ¤   SecureString *passphrase, PGPdiskRandomPool *randomPool,·
25282b ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive);
6faf5a
95e067 ¤   DualErr¤¤   FirstTimeEncryptDiskFile(PGPdiskFileHeader *fileHeader,·
7f9ada ¤   ¤   ¤   ¤   ¤   SecureString *passphrase);
7a0093 ¤   DualErr¤¤   FirstTimeWriteHeaderDiskFile(PGPdiskFileHeader* fileHeader);
ecaf5a
345632 ¤   DualErr¤¤   GetOldSessionKey(LPCSTR path, PGPdiskFileHeader *fileHeader,·
47c316 ¤   ¤   ¤   ¤   ¤   SecureString *passphrase, CASTKey *oldSessionKey);
c0af5a
abbf64 ¤   DualErr¤¤   ConvertBlocks(PGPdiskFileHeader *fileHeader,·
0ad2c7 ¤   ¤   ¤   ¤   ¤   PGPdiskCASTConvertInfo *pCCI,·
7bfbb0 ¤   ¤   ¤   ¤   ¤   const CASTKey *oldSessionKey,·
0c2e9a ¤   ¤   ¤   ¤   ¤   const PassphraseSalt *oldSalt,·
cc3911 ¤   ¤   ¤   ¤   ¤   const CASTKey *newSessionKey,·
97e122 ¤   ¤   ¤   ¤   ¤   const PassphraseSalt *newSalt,·
0f3e49 ¤   ¤   ¤   ¤   ¤   PGPUInt32 startingBlock, PGPUInt32 numBlocks);
6e82f7 };
c9af5a
62ac0b #endif¤ // ] Included_PGPdisk_h
--9c61 00071a2b582401100d2 Page 1 of PGPdiskHelpIds.h
541bc3 //////////////////////////////////////////////////////////////////////////////
808de6 // PGPdiskHelpIds.h
71465d //
58858e // Contains context help ids for the PGPdisk application.
981bc3 //////////////////////////////////////////////////////////////////////////////
1aaf5a
f8aa08 // $Id: PGPdiskHelpIds.h,v 1.1.2.5 1998/06/22 08:03:10 nryan Exp $
a9af5a
45cbce // Copyright (C) 1998 by Network Associates, Inc.
d771ae // All rights reserved.
06af5a
82efef #ifndef Included_PGPdiskHelpIds_h¤  // [
dc3a7a #define Included_PGPdiskHelpIds_h
d5af5a
76af5a
cb83f5 ///////////////////////////
de4f20 // PGPdisk context help IDs
8d83f5 ///////////////////////////
8caf5a
72134e // Base ID for PGPdisk is 5000
a7af5a
40bfa1 #define¤IDH_PGPDISKAPP_ABOUTBOXOK¤  ¤   ¤   0x5000
9f5618 #define¤IDH_PGPDISKAPP_ABOUTBOXCREDITS¤ ¤   0x5001
1c15a9 #define¤IDH_PGPDISKAPP_ABOUTBOXPGPLINK¤ ¤   0x5002
62af5a
d5d036 #define¤IDH_PGPDISKAPP_CONFIRMPASSOK¤   ¤   0x5100
23b62b #define¤IDH_PGPDISKAPP_CONFIRMPASSCANCEL¤   0x5101
1faf34 #define¤IDH_PGPDISKAPP_CONFIRMPASSHIDECHECK¤0x5102
e85735 #define¤IDH_PGPDISKAPP_CONFIRMPASSEDIT1¤¤   0x5103
611aea #define¤IDH_PGPDISKAPP_CONFIRMPASSQUALITY¤  0x5104
ab0d12 #define¤IDH_PGPDISKAPP_CONFIRMPASSEDIT2¤¤   0x5105
9804a7 #define¤IDH_PGPDISKAPP_CONFIRMPASSROCHECK¤  0x5106·
2faf5a
559387 #define¤IDH_PGPDISKAPP_DISKWIZSHEETCANCEL¤  0x5200
f7af5a
29256e #define¤IDH_PGPDISKAPP_DISKWIZSHEETBACK¤¤   0x5202
d9b9d8 #define¤IDH_PGPDISKAPP_DISKWIZSHEETNEXT¤¤   0x5203
0d6995 #define¤IDH_PGPDISKAPP_DISKWIZSHEETFINISH¤  0x5204
adaf5a
f8d712 #define IDH_PGPDISKAPP_DISKWIZCREATIONPROGRESS 0x5300
a9af5a
1adadf #define¤IDH_PGPDISKAPP_DISKWIZVOLSIZEEDIT¤  0x5400
943114 #define¤IDH_PGPDISKAPP_DISKWIZVOLSIZESPIN¤  0x5401
aa5044 #define IDH_PGPDISKAPP_DISKWIZVOLDRIVECOMBO¤0x5402
fbc700 #define¤IDH_PGPDISKAPP_DISKWIZVOLGBCHECK¤   0x5403
a58c98 #define¤IDH_PGPDISKAPP_DISKWIZVOLMBCHECK¤   0x5404
d79730 #define¤IDH_PGPDISKAPP_DISKWIZVOLKBCHECK¤   0x5405
04af5a
a48c25 #define IDH_PGPDISKAPP_DISKWIZPASSEDIT1¤¤   0x5600
619b0a #define IDH_PGPDISKAPP_DISKWIZPASSEDIT2¤¤   0x5601
c45e4c #define IDH_PGPDISKAPP_DISKWIZPASSHIDECHECK¤0x5602
14a69a #define IDH_PGPDISKAPP_DISKWIZPASSQUALITY¤  0x5603
85af5a
baefab #define IDH_PGPDISKAPP_DISKWIZRANDOMBAR 0x5700
21af5a
6f0aff #define¤IDH_PGPDISKAPP_MAINNEW¤ ¤   0x5800
efefeb #define¤IDH_PGPDISKAPP_MAINMOUNT¤   0x5801
d90b87 #define¤IDH_PGPDISKAPP_MAINUNMOUNT¤ 0x5802
456147 #define¤IDH_PGPDISKAPP_MAINPREFS¤   0x5803
1faf5a
cbbe20 #define¤IDH_PGPDISKAPP_PREFSHEETOK¤ ¤   ¤   0x5900
1b5f40 #define¤IDH_PGPDISKAPP_PREFSHEETCANCEL¤ ¤   0x5901
01dbab #define¤IDH_PGPDISKAPP_PREFSHEETAPPLY¤  ¤   0x5902
e2af5a
a0c256 #define¤IDH_PGPDISKAPP_PREFSAUTOSLEEPCHECK¤ ¤   0x5A00
d335c4 #define¤IDH_PGPDISKAPP_PREFSAUTOUNMOUNTCHECK¤   0x5A01
3d5e19 #define¤IDH_PGPDISKAPP_PREFSAUTOUNMOUNTEDIT¤¤   0x5A02
4ca7e5 #define¤IDH_PGPDISKAPP_PREFSPREVENTSLEEPCHECK¤  0x5A03
5a61ad #define¤IDH_PGPDISKAPP_PREFSAUTOUNMOUNTSPIN¤¤   0x5A04
c4af5a
130380 #define IDH_PGPDISKAPP_PREFSCOMPATFAT32CHECK 0x5B00
71af5a
--9f3f 001b10e32d4401100d2 Page 2 of PGPdiskHelpIds.h
fcf379 #define¤IDH_PGPDISKAPP_PREFSHKHOTKEYCHECK¤  0x5C00
b951b8 #define¤IDH_PGPDISKAPP_PREFSHKHOTKEYEDIT¤   0x5C01
edaf5a
567522 #define¤IDH_PGPDISKAPP_SINGLEPASSOK¤¤   ¤   ¤   0x5D00
ea406f #define¤IDH_PGPDISKAPP_SINGLEPASSCANCEL¤¤   ¤   0x5D01
9731db #define¤IDH_PGPDISKAPP_SINGLEPASSHIDECHECK¤ ¤   0x5D02
594b26 #define¤IDH_PGPDISKAPP_SINGLEPASSEDIT¤  ¤   ¤   0x5D03
70ce00 #define¤IDH_PGPDISKAPP_SINGLEPASSROCHECK¤   ¤   0x5D04
5e88a6 #define¤IDH_PGPDISKAPP_SINGLEPASSDRIVECOMBO¤¤   0x5D05
84af5a
95eaee #define¤IDH_PGPDISKAPP_UNMOUNTCANCEL¤   0x5E00
5c3b06 #define¤IDH_PGPDISKAPP_UNMOUNTUNMOUNT¤  0x5E01
05e165 #define¤IDH_PGPDISKAPP_UNMOUNTDRIVE¤¤   0x5E02
a7af5a
fcb0c1 #define IDH_PGPDISKAPP_GETUSERINFOCANCEL¤   0x6100
1bd6dc #define IDH_PGPDISKAPP_GETUSERINFOOK¤   ¤   0x6101
262f24 #define IDH_PGPDISKAPP_GETUSERUSEREDIT¤ ¤   0x6102
566b18 #define IDH_PGPDISKAPP_GETUSERORGEDIT¤  ¤   0x6103
aeef72 #define IDH_PGPDISKAPP_GETUSERSERIALEDIT¤   0x6104
b2af5a
98ff1e #define IDH_PGPDISKAPP_NAGBUYCANCEL¤¤   ¤   0x6200
a9ca53 #define IDH_PGPDISKAPP_NAGBUYOK¤¤   ¤   ¤   0x6201
0b5eba #define IDH_PGPDISKAPP_NAGBUYBUYNOWBUTTON¤  0x6202
88af5a
b11a5f #endif¤ // ] Included_PGPdiskHelpIds_h
--6070 00033b1e8ac401100d3 Page 1 of Resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
20a60d // Used by E:\Source\CLIENTS\DISK\win32\PGPdiskApp\PGPdiskApp.rc
1f465d //
edc829 #define IDC_BUYNOW_BUTTON ··············3
d10900 #define IDD_MAIN_DLG ···················102
a0717b #define IDI_MAINFRAME ··················128
4fa056 #define IDD_UNMOUNT_DLG ················130
8cad79 #define IDI_NEW ························136
c2d83d #define IDI_MOUNT ······················137
3f6372 #define IDI_PREFS ······················138
dfe0e4 #define IDR_MAINDLG_ACCEL ··············149
1a0b34 #define IDD_ABOUTBOX_DLG ···············150
fcfb67 #define IDD_PROP_AUTO ··················162
5a3041 #define IDD_SINGLEPASS1_DLG ············165
d4348e #define IDD_PROP_HOTKEY ················168
f827d2 #define IDD_CONFIRMPASS1_DLG ···········169
81e7d3 #define IDD_SINGLEPASS2_DLG ············170
784e1a #define IDD_GETUSERINFO_DLG ············181
584a28 #define IDR_MAIN_MENU ··················186
a6d2b3 #define IDB_SPLASHSCREEN8 ··············190
30c452 #define IDD_SPLASH_DLG ·················191
4884d2 #define IDI_UNMOUNT ····················193
58174d #define IDI_PGPDISK ····················194
d7ea39 #define IDI_CAPSLOCK ···················198
b3d0fb #define IDB_SIDEBAR1 ···················201
e25488 #define IDB_SPLASHSCREEN1 ··············203
b4ba50 #define IDB_SIDEBAR8 ···················206
8e89d5 #define IDB_SPLASHSCREEN4 ··············207
7e0bac #define IDB_SIDEBAR4 ···················209
1f8713 #define IDB_CREDITS4 ···················212
ab8b5c #define IDB_CREDITS1 ···················213
20cb9f #define IDB_CREDITS8 ···················217
875046 #define IDD_NAGBUY_DLG ·················252
39ef14 #define IDC_SIZE_EDIT ··················1003
68d62d #define IDC_KB_CHECK ···················1014
5646ae #define IDC_MB_CHECK ···················1015
acff3a #define IDC_GB_CHECK ···················1016
9ba08b #define IDC_NEWPGPDISK ·················1020
8b125a #define IDC_MOUNTPGPDISK ···············1023
3b0ba8 #define IDC_PREFERENCES ················1024
8acd0d #define IDC_UNMOUNTPGPDISK ·············1025
fd472d #define IDC_CHECK_UNMOUNT ··············1026
ec1965 #define IDC_EDIT_UNMOUNT ···············1027
6554a3 #define IDC_CHECK_SLEEP ················1029
8c6a92 #define IDC_CHECK_PREVENT ··············1030
c1d119 #define IDC_HOTKEY_EDIT ················1052
9b1609 #define IDC_CONFIRM_EDIT ···············1054
bfd861 #define IDC_RO_CHECK ···················1055
3a2854 #define IDC_PASSPHRASE_EDIT ············1056
2433b2 #define IDC_HIDETYPE_CHECK ·············1057
24f36e #define IDC_QUALITY_BAR ················1066
b3830d #define IDC_ADK ························1066
bf8c8c #define IDC_DRIVE_COMBO ················1077
f7eeee #define IDC_HOTKEY_CHECK ···············1082
5e1c7a #define IDM_ADDPASS ····················1083
71e918 #define IDM_CHANGEPASS ·················1084
0ab007 #define IDM_REMOVEPASS ·················1085
cbc727 #define IDC_NEWPASSMSG_TEXT ············1091
15008b #define IDC_SINGLEPASSMSG_TEXT ·········1092
b41908 #define IDC_MINUTETEXT ·················1094
af80ce #define IDM_ABOUT ······················1097
e3b05f #define IDC_CAPSLOCK_TEXT ··············1098
87182e #define IDC_DISKNAME_TEXT ··············1099
6d4ed6 #define IDM_NEWPGPDISK ·················1100
29cdf7 #define IDC_SIZE_SPIN ··················1100
6d0a2b #define IDC_DIRNAME_TEXT ···············1100
28cfb7 #define IDM_MOUNTPGPDISK ···············1101
d76e58 #define IDM_UNMOUNTPGPDISK ·············1102
3c1cfe #define IDC_FREESIZE_TEXT ··············1102
985546 #define IDM_PREFS ······················1103
3342fd #define IDC_UNMOUNT ····················1103
--bb3e 00127365338401100d3 Page 2 of Resource.h
a4236f #define IDM_EXIT ·······················1104
fb4f40 #define IDC_EDIT_SPIN ··················1104
224dfd #define IDM_HELPCONTENTS ···············1105
f4b1bb #define IDC_USER_EDIT ··················1105
1adc40 #define IDC_ORG_EDIT ···················1106
44920b #define IDM_PUBLICKEYS ·················1106
606e59 #define IDC_SERIAL_EDIT ················1107
d6b971 #define IDC_SIDEBAR ····················1107
bfec00 #define IDM_GLOBALCONVERT ··············1107
304254 #define IDC_CREDITS ····················1108
e2bb2c #define IDC_PGP_LINK ···················1109
5cedcc #define IDC_NAGBUYMSG_TEXT ·············1110
671ba8 #define IDC_SEARCHSTATUS_TEXT ··········1115
d95d48 #define IDC_PGPDISKS_LIST ··············1118
5f3bfe #define IDD_DISKWIZ_RANDOM ·············1119
ff67c0 #define IDD_DISKWIZ_PASSPHRASE ·········1121
8a3c3b #define IDD_DISKWIZ_CREATION ···········1122
bd4745 #define IDC_PROGRESS_BAR ···············1123
4ceddf #define IDC_RANDOM_BAR ·················1123
9b0a19 #define IDD_DISKWIZ_VOLINFO ············1123
228c30 #define IDD_DISKWIZ_INTRO ··············1124
4fd771 #define IDD_DISKWIZ_DONE ···············1125
ddc891 #define IDD_CONFIRMPASS2_DLG ···········1126
ec7e3e #define IDD_DISKWIZ_ADK ················1127
92ed03 #define IDD_RANDDATA_DLG ···············1129
47ee89 #define IDD_CVRTWIZ_INTRO ··············1130
d4b5c8 #define IDD_CVRTWIZ_DONE ···············1131
2a35eb #define IDD_CVRTWIZ_RANDOM ·············1132
f7cedf #define IDD_CVRTWIZ_CONVERT ············1133
a5bd61 #define IDD_GLOBWIZ_INTRO ··············1134
0ae620 #define IDD_GLOBWIZ_DONE ···············1135
c33242 #define IDD_GLOBWIZ_SEARCH ·············1136
c26046 #define IDD_SINGLEPASS3_DLG ············1137
17af5a
0911aa // Next default values for new objects
93ac6a //·
2ef860 #ifdef APSTUDIO_INVOKED
223f23 #ifndef APSTUDIO_READONLY_SYMBOLS
5db103 #define _APS_3D_CONTROLS ····················1
379f6b #define _APS_NEXT_RESOURCE_VALUE ·······253
e97137 #define _APS_NEXT_COMMAND_VALUE ········1108
606793 #define _APS_NEXT_CONTROL_VALUE ········1119
8b1285 #define _APS_NEXT_SYMED_VALUE ··········101
347454 #endif
277454 #endif
--57bb 001bfac38b7401100d4 Page 1 of StdAfx.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
77fc35 // StdAfx.cpp
06465d //
c0afe4 // MFC source.
d41bc3 //////////////////////////////////////////////////////////////////////////////
36af5a
5bc5d5 // $Id: StdAfx.cpp,v 1.1.2.2 1998/05/08 18:29:22 nryan Exp $
56af5a
11d221 // Not really Copyright (C) 1998 by Network Associates, Inc.
b9af5a
bf9e12 #include "StdAfx.h"
--1079 0017fc07f65401100d5 Page 1 of StdAfx.h
541bc3 //////////////////////////////////////////////////////////////////////////////
465fb0 // StdAfx.h
01465d //
7120f8 // Contains global MFC includes.
081bc3 //////////////////////////////////////////////////////////////////////////////
82af5a
871219 // $Id: StdAfx.h,v 1.1.2.3 1998/05/29 00:43:39 nryan Exp $
19af5a
9cd221 // Not really Copyright (C) 1998 by Network Associates, Inc.
cb71ae // All rights reserved.
4daf5a
0296d7 #ifndef Included_StdAfx_h¤  // [
cb4653 #define Included_StdAfx_h
08af5a
f46b7d #include <afxwin.h> ········// MFC core and standard components
bcbe9b #include <afxext.h> ········// MFC extensions
b17e9c #include <afxdisp.h> ·······// MFC OLE automation classes
f3aef9 #ifndef _AFX_NO_AFXCMN_SUPPORT
5deb71 #include <afxcmn.h>¤¤   ¤   // MFC support for Windows Common Controls
889db5 #endif // _AFX_NO_AFXCMN_SUPPORT
beaf5a
6ec18c //{{AFX_INSERT_LOCATION}}
62af5a
7f242f #endif¤ // ] Included_StdAfx_h
--5788 000a68aa722401100d6 Page 1 of VolFile.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
87e84b // VolFile.cpp
05465d //
818a11 // Implementation of class VolFile.
c41bc3 //////////////////////////////////////////////////////////////////////////////
7caf5a
2a02bf // $Id: VolFile.cpp,v 1.1.2.12 1998/07/06 08:57:32 nryan Exp $
79af5a
eecbce // Copyright (C) 1998 by Network Associates, Inc.
6c71ae // All rights reserved.
84af5a
b19e12 #include "StdAfx.h"
3aaf5a
da9bcf #include "Required.h"
25bfe9 #include "UtilityFunctions.h"
02af5a
7cc411 #include "Globals.h"
20b3b1 #include "VolFile.h"
9faf5a
55af5a
a651ef ////////////////////////////////////////
c9f944 // Class VolFile public member functions
1a51ef ////////////////////////////////////////
55af5a
ca9b9c // The VolFile constructor attaches a drive and a pathname for an already
3cc343 // mounted VolFile.
68af5a
b4441b VolFile::VolFile(LPCSTR path, PGPUInt8 drive) : File(), Volume(drive)
f3bb36 {
0ab7e2 ¤   if (IsntNull(path))
afb959 ¤   ¤   mInitErr = File::SetPath(path);
11efe6 }
66af5a
ed0813 // Mount asks the driver to mount the volume file specified by 'path'. If
cbbcbd // 'pMNT' exists, it must use this packet passed to it from a derived class,
1db112 // instead of its own packet. This allows extensions to be made to the MNT
3568e0 // structure without breaking base classes.
56af5a
522292 DualErr·
507678 VolFile::Mount(
bff2f8 ¤   LPCSTR¤ ¤   path,·
eb7fa2 ¤   PGPUInt8¤   drive,·
c622b7 ¤   PGPBoolean¤ mountReadOnly,·
151908 ¤   PAD_Mount¤  useThisPMNT)
3cbb36 {
2e33d0 ¤   AD_Mount¤   MNT, *pMNT;
88be41 ¤   DualErr¤¤   derr;
93af5a
f457f3 ¤   pMNT = (useThisPMNT ? useThisPMNT : &MNT);
fdaf5a
edbccc ¤   pgpAssertAddrValid(pMNT, AD_Mount);
aaaeca ¤   pgpAssert(Unmounted());
53e7de ¤   pgpAssert(!Opened());
df67c5 ¤
2fc474 ¤   derr = SetPath(path);
acaf5a
deb24c ¤   // Set the fields we are responsible for and call down.
472361 ¤   if (derr.IsntError())
b6c7a1 ¤   {
8490fc ¤   ¤   pMNT->path¤ ¤   = path;
d1b44a ¤   ¤   pMNT->sizePath¤ = strlen(path) + 1;
4ac589 ¤   ¤   pMNT->drive¤¤   = drive;
b4af5a
d7408b ¤   ¤   derr = Volume::Mount(mountReadOnly, pMNT);
209371 ¤   }
7caf5a
d54bb3 ¤   if (derr.IsError())
dcc7a1 ¤   {
484979 ¤   ¤   ClearPath();
f29371 ¤   }
73af5a
a633e3 ¤   return derr;
--2601 001f5b752ba401100d6 Page 2 of VolFile.cpp
7aefe6 }
46af5a
a3ec98 // Unmount asks the driver to unmount a volume. If 'pUMNT' exists, it must
affe1d // use this packet passed to it from a derived class, instead of its own
c7b81a // packet. This allows extensions to be made to the UMNT structure without
5c35da // breaking base classes.
79af5a
5a2292 DualErr·
6cc26c VolFile::Unmount(PGPBoolean isThisEmergency, PAD_Unmount useThisPUNMNT)
9abb36 {
fab51e ¤   AD_Unmount¤ UNMNT, *pUNMNT;
26be41 ¤   DualErr¤¤   derr;
a7af5a
e291dd ¤   pUNMNT = (useThisPUNMNT ? useThisPUNMNT : &UNMNT);
1baf5a
17de3b ¤   pgpAssertAddrValid(pUNMNT, AD_Unmount);
093ec3 ¤   pgpAssert(Mounted());
11af5a
a885a4 ¤   // We aren't responsible for any fields, so just call down.
e49537 ¤   derr = Volume::Unmount(isThisEmergency, pUNMNT);
1aaf5a
ab2361 ¤   if (derr.IsntError())
cdc7a1 ¤   {
924979 ¤   ¤   ClearPath();
539371 ¤   }
e3af5a
2b33e3 ¤   return derr;
f5efe6 }
--a859 001d887bf2e401100d7 Page 1 of VolFile.h
541bc3 //////////////////////////////////////////////////////////////////////////////
6bcef9 // VolFile.h
0d465d //
126954 // Declaration of class VolFile.
bf1bc3 //////////////////////////////////////////////////////////////////////////////
99af5a
ba2e16 // $Id: VolFile.h,v 1.1.2.6 1998/07/06 08:57:32 nryan Exp $
b7af5a
4fcbce // Copyright (C) 1998 by Network Associates, Inc.
b771ae // All rights reserved.
faaf5a
2799dc #ifndef Included_VolFile_h¤ // [
19878f #define Included_VolFile_h
00af5a
da3a85 #include "DualErr.h"
ceaf5a
52f037 #include "File.h"
fb2561 #include "Volume.h"
20af5a
b4af5a
539791 ////////////////
c57bec // Class VolFile
f29791 ////////////////
2aaf5a
d3aac3 // Class VolFile represents volume files.
eeaf5a
b7a0bb class VolFile : public Volume, public File
4dbb36 {
b35ed4 public:
b4da4d ¤   DualErr¤mInitErr;
1faf5a
3f89b3 ¤   ¤   ¤   VolFile(LPCSTR path = NULL, PGPUInt8 drive = kInvalidDrive);
f3ac51 ¤   ¤   ¤   ~VolFile() { };
fdaf5a
4120b2 ¤   DualErr¤Mount(LPCSTR path, PGPUInt8 drive = kInvalidDrive,·
3751a0 ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly = FALSE,·
df727d ¤   ¤   ¤   ¤   PAD_Mount useThisPMNT = NULL);
976cc4 ¤   DualErr¤Unmount(PGPBoolean isThisEmergency = FALSE,·
0d73a7 ¤   ¤   ¤   ¤   PAD_Unmount useThisPUNMNT = NULL);
a782f7 };
8faf5a
d83e06 #endif¤ // ] Included_VolFile_h
--5b41 000728b2903401100d8 Page 1 of Volume.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
debd92 // Volume.cpp
ea465d //
b08b63 // Implementation of class Volume.
c11bc3 //////////////////////////////////////////////////////////////////////////////
8eaf5a
be741f // $Id: Volume.cpp,v 1.2.2.19 1998/07/30 18:23:15 nryan Exp $
46af5a
2fcbce // Copyright (C) 1998 by Network Associates, Inc.
5671ae // All rights reserved.
0faf5a
c89e12 #include "StdAfx.h"
133366 #include <Dbt.h>
5a5f7a #include <Shlobj.h>
9caf5a
d79bcf #include "Required.h"
97ac00 #include "DriverComm.h"
edbfe9 #include "UtilityFunctions.h"
80dd74 #include "WindowsVersion.h"
84af5a
63c411 #include "Globals.h"
562561 #include "Volume.h"
f8af5a
f1af5a
8e09b7 ////////////
c3e738 // Constants
c409b7 ////////////
20af5a
0133f7 const PGPUInt32¤kSHNotifySleepDelayMs = 500;
64cb7e const PGPUInt64¤kMaxBlocksDiskWeFormat =·
926738 ¤   (2047*kBytesPerMeg)/kDefaultBlockSize;
c0af5a
9620ad static LPCSTR¤  kVWin32DriverString¤= "\\\\.\\VWIN32";
a94909 static LPCSTR¤  kVolumeOpenString¤  = "\\\\.\\%c:";
b4af5a
afc9b9 const PGPUInt32¤kMaxBlocksPerWrite = 2000;
827a77 const PGPUInt32¤kMinBlocksPerWrite = 10;
48af5a
bc8806 const PGPUInt32¤kIdealNumWritesPerData = 10;
9daf5a
2faf5a
2e04c6 ///////////////////////////////////////
346848 // Class Volume public member functions
6404c6 ///////////////////////////////////////
f6af5a
f7c266 // The Class Volume constructor.
7aaf5a
0f07a5 Volume::Volume(PGPUInt8 drive)
6ebb36 {
8336e1 ¤   if (drive != kInvalidDrive)
881bb7 ¤   ¤   mMountState = kVol_Mounted;
8e0e24 ¤   else
bfacff ¤   ¤   mMountState = kVol_Unmounted;
c9af5a
d86b5d ¤   mLockState = kLock_None;
2d4f92 ¤   mDrive = drive;
caaf5a
2afeec ¤   mAttachedToLocalVol¤= FALSE;
ebaf5a
55cf91 ¤   mBlockSize = 0;
48efe6 }
d8af5a
b94ea5 // The Volume destructor unmounted the volume if was mounted by us.
98af5a
4bb773 Volume::~Volume()
6bbb36 {
cc7d36 ¤   DualErr derr;
04af5a
8bcb02 ¤   if (Mounted())
21c7a1 ¤   {
282527 ¤   ¤   if (AttachedToLocalVolume())
7261a4 ¤   ¤   ¤   DetachLocalVolume();
--928d 00090d8347b401100d8 Page 2 of Volume.cpp
a19371 ¤   }
c9efe6 }
a0af5a
0cd10b // GetDrive returns the drive number the volume is mounted on.
00af5a
bf671d PGPUInt8·
03e319 Volume::GetDrive()
a8bb36 {
974cf2 ¤   return mDrive;
77efe6 }
a8af5a
459cb0 // GetBlockSize returns the block size of the mounted volume.
43af5a
92411c PGPUInt16·
94afd6 Volume::GetBlockSize()
62bb36 {
423ec3 ¤   pgpAssert(Mounted());
5eaf5a
19f8ac ¤   return mBlockSize;
6eefe6 }
19af5a
78c5fd // GetTotalBlocks returns the total number of blocks on the volume.
5daf5a
9da385 PGPUInt64·
44376a Volume::GetTotalBlocks()
64bb36 {
b23ec3 ¤   pgpAssert(Mounted());
7aaf5a
654cf3 ¤   return mTotalBlocks;
63efe6 }
57af5a
95c727 // Mounted returns TRUE if the Volume is mounted.
22af5a
e877be PGPBoolean·
468fc7 Volume::Mounted()
65bb36 {
b0b86d ¤   return (mMountState == kVol_Mounted);
35efe6 }
ccaf5a
940114 // Unmounted returns TRUE if the Volume is unmounted.
d1af5a
4977be PGPBoolean·
cf3f6f Volume::Unmounted()
52bb36 {
a025b2 ¤   return (mMountState == kVol_Unmounted);
adefe6 }
0caf5a
2c8972 // AttachedToLocalVolume returns TRUE if the Volume object is attached to a
b7110f // local volume, FALSE if not.
dcaf5a
8377be PGPBoolean·
c8235c Volume::AttachedToLocalVolume()
c5bb36 {
3051f9 ¤   return mAttachedToLocalVol;
a6efe6 }
e2af5a
3b1501 // HasOpenFiles returns TRUE if the volume has open files, FALSE otherwise.
b3af5a
787750 PGPBoolean
28b169 Volume::HasOpenFiles()
63bb36 {
bbbe41 ¤   DualErr¤¤   derr;
2c7a9f ¤   PGPBoolean¤ hasOpenFiles;
7baf5a
a53ec3 ¤   pgpAssert(Mounted());
67af5a
12290f ¤   derr = AreFilesOpenOnDrive(mDrive, &hasOpenFiles);
fdaf5a
832361 ¤   if (derr.IsntError())
5fd540 ¤   ¤   return hasOpenFiles;
b80e24 ¤   else
90836c ¤   ¤   return TRUE;
--4bed 0008a8defac401100d8 Page 3 of Volume.cpp
7aefe6 }
46af5a
4ecb87 // LockedForReadWrite returns TRUE if the volume is mounted and locked for
ae2364 // read/write access, FALSE otherwise.
3daf5a
9677be PGPBoolean·
cd4ddc Volume::LockedForReadWrite()
e3bb36 {
8fcc45 ¤   return (Mounted() && (mLockState == kLock_ReadWrite));
b5efe6 }
faaf5a
f6cb87 // LockedForReadWrite returns TRUE if the volume is mounted and locked for
a50b82 // format access, FALSE otherwise.
42af5a
9577be PGPBoolean·
2f93fa Volume::LockedForFormat()
a6bb36 {
b11acd ¤   return (Mounted() && (mLockState == kLock_Format));
0defe6 }
02af5a
2fe33d // BrowseToVolume opens a view to the volume in an explorer window.
88af5a
d4c823 void·
a96f3e Volume::BrowseToVolume()
00bb36 {
dc862b ¤   CString root;
b1af5a
d23ec3 ¤   pgpAssert(Mounted());
6faf5a
2dc5a3 ¤   if (MakeRoot(mDrive, &root).IsntError())
2cc7a1 ¤   {
49c90c ¤   ¤   ShellExecute(NULL, "explore", root, NULL, NULL, SW_SHOWNORMAL);
f19371 ¤   }
a0efe6 }
8caf5a
84f98a // GetVolumeLabel retrieves the volume label associated with a mounted volume.
4aaf5a
c52292 DualErr·
7e7dbb Volume::GetVolumeLabel(LPSTR label, PGPUInt32 size)
c7bb36 {
91945d ¤   DualErr¤derr;
2f862b ¤   CString root;
34af5a
7a1c89 ¤   pgpAssertAddrValid(label, LPSTR);
9b3ec3 ¤   pgpAssert(Mounted());
12af5a
93939c ¤   derr = MakeRoot(mDrive, &root);
c6af5a
f82361 ¤   if (derr.IsntError())
acc7a1 ¤   {
bba0b9 ¤   ¤   if (GetVolumeInformation(root, label, size, NULL, NULL, NULL, NULL,·
8d46a8 ¤   ¤   ¤   0))
045b34 ¤   ¤   {
5ef4ce ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetVolumeInfoFailed,·
bb0c1f ¤   ¤   ¤   ¤   GetLastError());
0e0fe4 ¤   ¤   }
919371 ¤   }
52af5a
d833e3 ¤   return derr;
deefe6 }
1eaf5a
63f16d // SetVolumeLabel sets the 11-character label of the mounted volume.
21af5a
152292 DualErr·
1de276 Volume::SetVolumeLabel(LPCSTR label)
cebb36 {
cc945d ¤   DualErr¤derr;
ddb8ed ¤   CString¤volName, root;
96af5a
2e62d4 ¤   pgpAssertStrValid(label);
e83ec3 ¤   pgpAssert(Mounted());
8aaf5a
--bc44 000ada097fb401100d8 Page 4 of Volume.cpp
8e79d9 ¤   derr = CanonicalizeVolumeName(label, &volName);
7faf5a
8c2361 ¤   if (derr.IsntError())
66c7a1 ¤   {
5456c9 ¤   ¤   derr = MakeRoot(mDrive, &root);
079371 ¤   }
4caf5a
4d2361 ¤   if (derr.IsntError())
afc7a1 ¤   {
088b3e ¤   ¤   if (!::SetVolumeLabel(root, volName))
065b34 ¤   ¤   {
8a68c3 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_SetVolumeLabelFailed,·
0d0c1f ¤   ¤   ¤   ¤   GetLastError());
f40fe4 ¤   ¤   }
8a9371 ¤   }
05af5a
a933e3 ¤   return derr;
38efe6 }
07af5a
1cfff6 // AttachLocalVolume initializes this Volume object for access to an already
713bc5 // mounted volume on the local computer.
ffaf5a
532292 DualErr·
97b0d2 Volume::AttachLocalVolume(PGPUInt8 drive)
d1bb36 {
057d36 ¤   DualErr derr;
a0af5a
3faa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
68cf8a ¤   pgpAssert(!Mounted());
05227d ¤   pgpAssert(!AttachedToLocalVolume());
a3af5a
da18bd ¤   if (!App->IsVolumeValid(drive))
74d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
44af5a
6a2361 ¤   if (derr.IsntError())
4bc7a1 ¤   {
f51c83 ¤   ¤   mMountState¤= kVol_Mounted;
81cebe ¤   ¤   mLockState¤ = kLock_None;
e08846 ¤   ¤   mDrive¤ ¤   = drive;
eeaf5a
6f9b97 ¤   ¤   mAttachedToLocalVol = TRUE;
e0af5a
ada2ab ¤   ¤   if (FillInVolInfo().IsError())
415b34 ¤   ¤   {
21201c ¤   ¤   ¤   mBlockSize = kDefaultBlockSize;
bbc943 ¤   ¤   ¤   mTotalBlocks = 0;
b00fe4 ¤   ¤   }
e49371 ¤   }
e5af5a
5933e3 ¤   return derr;
5befe6 }
deaf5a
d0bdfa // DetachLocalVolume marks this Volume object as no longer being associated
a567e5 // with a local volume.
27af5a
d0c823 void·
2d463a Volume::DetachLocalVolume()
c4bb36 {
3f3ec3 ¤   pgpAssert(Mounted());
0fbfb5 ¤   pgpAssert(AttachedToLocalVolume());
a0af5a
b4e6f1 ¤   mMountState¤= kVol_Unmounted;
1df9b6 ¤   mLockState¤ = kLock_None;
7ee59e ¤   mDrive¤ ¤   = kInvalidDrive;
13af5a
d6ec86 ¤   mAttachedToLocalVol = FALSE;
cbefe6 }
c7af5a
7c2a09 // LockVolumeForReadWrite locks the mounted volume for direct read/write
305ca5 // access.
62af5a
ad2292 DualErr·
--9951 000e19fc86f401100d8 Page 5 of Volume.cpp
917551 Volume::LockVolumeForReadWrite()
52bb36 {
c47d36 ¤   DualErr derr;
1367c5 ¤
a33ec3 ¤   pgpAssert(Mounted());
e4f283 ¤   pgpAssert(!LockedForReadWrite() && !LockedForFormat());
80af5a
301467 ¤   derr = LockUnlockVolume(mDrive, kLO_LockReadWrite);
50af5a
2e2361 ¤   if (derr.IsntError())
57c7a1 ¤   {
07e246 ¤   ¤   mLockState = kLock_ReadWrite;
9b9371 ¤   }
f2af5a
0133e3 ¤   return derr;
9eefe6 }
33af5a
cb5eeb // LockVolumeForFormat locks the mounted volume for formatting.
71af5a
2c2292 DualErr·
cdd7e3 Volume::LockVolumeForFormat()
b2bb36 {
a57d36 ¤   DualErr derr;
dc67c5 ¤
083ec3 ¤   pgpAssert(Mounted());
3bf283 ¤   pgpAssert(!LockedForReadWrite() && !LockedForFormat());
e8af5a
685cf5 ¤   derr = LockUnlockVolume(mDrive, kLO_LockFormat);
45af5a
862361 ¤   if (derr.IsntError())
6ec7a1 ¤   {
ae52d6 ¤   ¤   mLockState = kLock_Format;
cc9371 ¤   }
ccaf5a
cf33e3 ¤   return derr;
15efe6 }
02af5a
affb18 // UnlockVolume removes any outstanding locks on the volume;
1eaf5a
f72292 DualErr·
48df21 Volume::UnlockVolume()
55bb36 {
d77d36 ¤   DualErr derr;
04af5a
ed3ec3 ¤   pgpAssert(Mounted());
dfe241 ¤   pgpAssert(LockedForReadWrite() || LockedForFormat());
87af5a
b29077 ¤   derr = LockUnlockVolume(mDrive, (LockedForReadWrite() ?·
f0ea25 ¤   ¤   kLO_UnlockReadWrite : kLO_UnlockFormat));
13af5a
992361 ¤   if (derr.IsntError())
92c7a1 ¤   {
bfd00b ¤   ¤   mLockState = kLock_None;
959371 ¤   }
c9af5a
bc33e3 ¤   return derr;
53efe6 }
4daf5a
7661d0 // Read reads blocks from the locked mounted volume.
73af5a
052292 DualErr·
8aefef Volume::Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks)
22bb36 {
587d36 ¤   DualErr derr;
b9af5a
d5b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
c33ec3 ¤   pgpAssert(Mounted());
95e241 ¤   pgpAssert(LockedForReadWrite() || LockedForFormat());
5baf5a
4f7132 ¤   derr = DirectDiskRead(mDrive, buf, nBlocks * GetBlockSize(), pos,·
910d27 ¤   ¤   nBlocks);
e1af5a
--e3ec 000f2a32dc7401100d8 Page 6 of Volume.cpp
dd33e3 ¤   return derr;
a2efe6 }
c9af5a
d1db1a // Write writes blocks to the locked mounted volume.
9aaf5a
b12292 DualErr·
1778f6 Volume::Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks)
20bb36 {
4c7d36 ¤   DualErr derr;
4faf5a
bbb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
6e3ec3 ¤   pgpAssert(Mounted());
21e241 ¤   pgpAssert(LockedForReadWrite() || LockedForFormat());
e2af5a
5f14ba ¤   derr = DirectDiskWrite(mDrive, buf, nBlocks * GetBlockSize(), pos,·
0c0d27 ¤   ¤   nBlocks);
b0af5a
e733e3 ¤   return derr;
aeefe6 }
77af5a
ddcf6f // Format formats the mounted volume using our own algorithms.
cbaf5a
b32292 DualErr·
051103 Volume::Format()
c9bb36 {
b5be41 ¤   DualErr¤¤   derr;
7f9bb8 ¤   FatData¤¤   fat;
c727ae ¤   PGPBoolean¤ allocedBlockBuf, lockedForFormat;
b523cd ¤   PGPUInt8¤   *blockBuf;
ea60a0 ¤   PGPUInt64¤  megsDisk;
cdaf5a
693ec3 ¤   pgpAssert(Mounted());
a5b3ae ¤   pgpAssert(!LockedForReadWrite() || !LockedForFormat());
09af5a
4bf1e3 ¤   allocedBlockBuf = lockedForFormat = FALSE;
3230db ¤   megsDisk = (GetTotalBlocks() * kDefaultBlockSize) / kBytesPerMeg;
a9af5a
0c6b89 ¤   // Can only format drives with standard block sizes.
993e27 ¤   if (GetBlockSize() != kDefaultBlockSize)
dd5193 ¤   ¤   derr = DualErr(kPGDMinorError_CantFormatDrive);
98af5a
a26727 ¤   // Too big for format?
d52361 ¤   if (derr.IsntError())
20c7a1 ¤   {
65097e ¤   ¤   if (GetBlockSize() > kMaxBlocksDiskWeFormat)
c8281b ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DiskTooBigToFormat);
829371 ¤   }
29af5a
db39fd ¤   // Get block buffer.
622361 ¤   if (derr.IsntError())
47c7a1 ¤   {
02e9be ¤   ¤   derr = GetByteBuffer(kDefaultBlockSize, &blockBuf);
cbee21 ¤   ¤   allocedBlockBuf = derr.IsntError();
979371 ¤   }
e4af5a
f92d92 ¤   // Lock the volume for format.
4d2361 ¤   if (derr.IsntError())
99c7a1 ¤   {
6f8184 ¤   ¤   derr = LockVolumeForFormat();
d393ff ¤   ¤   lockedForFormat = derr.IsntError();
a69371 ¤   }
b8af5a
3d2361 ¤   if (derr.IsntError())
f4c7a1 ¤   {
1b308d ¤   ¤   // Initialize FAT data.
c3fbf9 ¤   ¤   fat.fdFsId = kFS_FAT16;
93af5a
9314e1 ¤   ¤   if (megsDisk < 2)
715b34 ¤   ¤   {
891364 ¤   ¤   ¤   fat.fdFsId = kFS_FAT12;
ed0fe4 ¤   ¤   }
f28404 ¤   ¤   else if ((megsDisk >= kMinFat32Megs) &&·
--4923 000a17ef0e7401100d8 Page 7 of Volume.cpp
9202d1 ¤   ¤   ¤   IsWin95OSR2CompatibleMachine())
7b5b34 ¤   ¤   {
722a12 ¤   ¤   ¤   fat.fdFsId = kFS_FAT32;
b40fe4 ¤   ¤   }
96af5a
85ada6 ¤   ¤   InitFatData(&fat, GetBlockSize());
a3af5a
0629d5 ¤   ¤   derr = ClearBlocks(0, fat.fdFirstSecData);
0f9371 ¤   }
d6af5a
e88337 ¤   // Write out the FAT data structures.
702361 ¤   if (derr.IsntError())
92c7a1 ¤   {
f33cf6 ¤   ¤   BigFatBootFSInfo¤   bfInfo;
387a42 ¤   ¤   BootSector12¤   ¤   bb12;
21319a ¤   ¤   BootSector16¤   ¤   bb16;
f45705 ¤   ¤   BootSector32¤   ¤   bb32;
bd437f ¤   ¤   PGPUInt32¤  ¤   ¤   fat16Sig;
f21bb9 ¤   ¤   PGPUInt64¤  ¤   ¤   pos;
45af5a
625259 ¤   ¤   pgpAssert(sizeof(bb12) == kDefaultBlockSize);
217f2a ¤   ¤   pgpAssert(sizeof(bb16) == kDefaultBlockSize);
67f6c9 ¤   ¤   pgpAssert(sizeof(bb32) == kDefaultBlockSize);
b5af5a
5097cf ¤   ¤   pgpClearMemory(blockBuf, kDefaultBlockSize);
03af5a
ab599f ¤   ¤   pos = 0;
a3af5a
2761d6 ¤   ¤   switch (fat.fdFsId)
225b34 ¤   ¤   {
c4af5a
a5bbe5 ¤   ¤   case kFS_FAT12:
1d2d77 ¤   ¤   ¤   // Init the boot block.
5d9ee2 ¤   ¤   ¤   InitFAT12BootBlock(GetBlockSize(), &fat, &bb12);
f7af5a
096adc ¤   ¤   ¤   // Write the boot block.
bc5c4b ¤   ¤   ¤   derr = Write((PGPUInt8 *) &bb12, pos, 1);
6baf5a
080579 ¤   ¤   ¤   // Write the first FAT.
4f9d3d ¤   ¤   ¤   if (derr.IsntError())
9ef776 ¤   ¤   ¤   {
241983 ¤   ¤   ¤   ¤   pgpCopyMemory((PGPUInt8 *) &kFat12Sig, blockBuf,·
6b5778 ¤   ¤   ¤   ¤   ¤   sizeof(kFat12Sig));
50af5a
35d68b ¤   ¤   ¤   ¤   pos += fat.fdReservedSecs;
6e37ff ¤   ¤   ¤   ¤   derr = Write(blockBuf, pos, 1);
a5a3a6 ¤   ¤   ¤   }
faaf5a
df1798 ¤   ¤   ¤   // Write the second FAT.
259d3d ¤   ¤   ¤   if (derr.IsntError())
04f776 ¤   ¤   ¤   {
a20d12 ¤   ¤   ¤   ¤   pos += fat.fdFatSize;
1837ff ¤   ¤   ¤   ¤   derr = Write(blockBuf, pos, 1);
a7a3a6 ¤   ¤   ¤   }
02cdcb ¤   ¤   ¤   break;
6aaf5a
6ed884 ¤   ¤   case kFS_FAT16:
622d77 ¤   ¤   ¤   // Init the boot block.
db8770 ¤   ¤   ¤   InitFAT16BootBlock(GetBlockSize(), &fat, &bb16);
38af5a
a274d0 ¤   ¤   ¤   // Decide on a FAT signature.
9a96bb ¤   ¤   ¤   fat16Sig = (megsDisk < 16 ? kUnder16MbFat16Sig :·
581454 ¤   ¤   ¤   ¤   kOver16MbFat16Sig);
49af5a
7f6adc ¤   ¤   ¤   // Write the boot block.
5b593d ¤   ¤   ¤   derr = Write((PGPUInt8 *) &bb16, pos, 1);
0caf5a
d90579 ¤   ¤   ¤   // Write the first FAT.
2a9d3d ¤   ¤   ¤   if (derr.IsntError())
45f776 ¤   ¤   ¤   {
856c0b ¤   ¤   ¤   ¤   pgpCopyMemory((PGPUInt8 *) &fat16Sig, blockBuf,·
a1d1d8 ¤   ¤   ¤   ¤   ¤   sizeof(fat16Sig));
--1282 000ccbbd3a6401100d8 Page 8 of Volume.cpp
e0af5a
8ad68b ¤   ¤   ¤   ¤   pos += fat.fdReservedSecs;
e437ff ¤   ¤   ¤   ¤   derr = Write(blockBuf, pos, 1);
35a3a6 ¤   ¤   ¤   }
4eaf5a
6a1798 ¤   ¤   ¤   // Write the second FAT.
1f9d3d ¤   ¤   ¤   if (derr.IsntError())
2df776 ¤   ¤   ¤   {
eb0d12 ¤   ¤   ¤   ¤   pos += fat.fdFatSize;
c537ff ¤   ¤   ¤   ¤   derr = Write(blockBuf, pos, 1);
13a3a6 ¤   ¤   ¤   }
3dcdcb ¤   ¤   ¤   break;
88af5a
388293 ¤   ¤   case kFS_FAT32:
172d77 ¤   ¤   ¤   // Init the boot block.
85714c ¤   ¤   ¤   InitFAT32BootBlock(GetBlockSize(), &fat, &bb32, &bfInfo);
bfaf5a
c46adc ¤   ¤   ¤   // Write the boot block.
905711 ¤   ¤   ¤   derr = Write((PGPUInt8 *) &bb32, pos, 1);
efaf5a
03d03d ¤   ¤   ¤   // Write the BigFatBootInfo structure.
239d3d ¤   ¤   ¤   if (derr.IsntError())
d7f776 ¤   ¤   ¤   {
cd0127 ¤   ¤   ¤   ¤   pgpCopyMemory((PGPUInt8 *) &bfInfo, blockBuf,·
70e847 ¤   ¤   ¤   ¤   ¤   sizeof(bfInfo));
8daf5a
d050b5 ¤   ¤   ¤   ¤   pos += bb32.bsFsInfoSec;
6637ff ¤   ¤   ¤   ¤   derr = Write(blockBuf, pos, 1);
3ca3a6 ¤   ¤   ¤   }
caaf5a
e19d3d ¤   ¤   ¤   if (derr.IsntError())
b8f776 ¤   ¤   ¤   {
62e6c7 ¤   ¤   ¤   ¤   PGPUInt32 threeClusts[3];
69af5a
c42219 ¤   ¤   ¤   ¤   threeClusts[0] = kFat32Clust1;
e05e34 ¤   ¤   ¤   ¤   threeClusts[1] = kFat32Clust2;
a2b922 ¤   ¤   ¤   ¤   threeClusts[2] = kFat32Clust3;
1eaf5a
bcde49 ¤   ¤   ¤   ¤   pgpClearMemory(blockBuf, kDefaultBlockSize);
e3425d ¤   ¤   ¤   ¤   pgpCopyMemory((PGPUInt8 *) &threeClusts, blockBuf,·
fef956 ¤   ¤   ¤   ¤   ¤   sizeof(threeClusts));
e4af5a
cbc02c ¤   ¤   ¤   ¤   // Write the first FAT.
8e4f5c ¤   ¤   ¤   ¤   pos = fat.fdReservedSecs;
b837ff ¤   ¤   ¤   ¤   derr = Write(blockBuf, pos, 1);
30af5a
811275 ¤   ¤   ¤   ¤   // Write the second FAT.
02724e ¤   ¤   ¤   ¤   if (derr.IsntError())
9172c3 ¤   ¤   ¤   ¤   {
0e31fc ¤   ¤   ¤   ¤   ¤   pos += fat.fdFatSize;
76a1be ¤   ¤   ¤   ¤   ¤   derr = Write(blockBuf, pos, 1);
272613 ¤   ¤   ¤   ¤   }
7da3a6 ¤   ¤   ¤   }
40cdcb ¤   ¤   ¤   break;
b2af5a
369ae3 ¤   ¤   default:
cf0606 ¤   ¤   ¤   pgpAssert(FALSE);
87cdcb ¤   ¤   ¤   break;
890fe4 ¤   ¤   }
459371 ¤   }
fcaf5a
3428e9 ¤   // Unlock the volume.
b73ffc ¤   if (lockedForFormat)
c8c7a1 ¤   {
f01481 ¤   ¤   UnlockVolume();
e29371 ¤   }
8faf5a
dbc565 ¤   // Free our block buffer.
b4cc48 ¤   if (allocedBlockBuf)
6fc7a1 ¤   {
529e07 ¤   ¤   FreeByteBuffer(blockBuf);
cc9371 ¤   }
--ce8a 000b0537513401100d8 Page 9 of Volume.cpp
e0af5a
cf33e3 ¤   return derr;
f5efe6 }
08af5a
489ed7 // Mount asks the driver to mount a volume. If 'pMNT' exists, it must use
8ae68f // this packet passed to it from a derived class, instead of its own packet.
f62ba4 // This allows extensions to be made to the MNT structure without breaking
10f0d3 // base classes.
ebaf5a
432292 DualErr·
b03e38 Volume::Mount(PGPBoolean mountReadOnly, PAD_Mount useThisPMNT)
28bb36 {
4f33d0 ¤   AD_Mount¤   MNT, *pMNT;
bbbe41 ¤   DualErr¤¤   derr;
27f341 ¤   PGPUInt8¤   drive;
0daf5a
4a57f3 ¤   pMNT = (useThisPMNT ? useThisPMNT : &MNT);
66af5a
f0bccc ¤   pgpAssertAddrValid(pMNT, AD_Mount);
10aeca ¤   pgpAssert(Unmounted());
0faf5a
42e74d ¤   // Initialize the fields we are responsible for.
a05238 ¤   pMNT->readOnly¤ = mountReadOnly;¤   ¤   // TRUE if read-only
797eb5 ¤   pMNT->pDrive¤   = &drive;¤  ¤   ¤   ¤   // will be drive mounted on
99af5a
7b69da ¤   // Send the packet to the driver.
104a0c ¤   derr = SendMountRequest(pMNT);
97af5a
442361 ¤   if (derr.IsntError())
44c7a1 ¤   {
21bcb1 ¤   ¤   CString root;
ccaf5a
673791 ¤   ¤   mDrive = (* pMNT->pDrive);
a31bb7 ¤   ¤   mMountState = kVol_Mounted;
3eaf5a
15940a ¤   ¤   // Tell the system about the new volume.
6d973e ¤   ¤   if (MakeRoot(mDrive, &root).IsntError())
585b34 ¤   ¤   {
7a9713 ¤   ¤   ¤   BroadcastDriveMessage(mDrive, DBT_DEVICEARRIVAL);
96260d ¤   ¤   ¤   SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATH, root, NULL);
300fe4 ¤   ¤   }
27af5a
06a2ab ¤   ¤   if (FillInVolInfo().IsError())
ce5b34 ¤   ¤   {
ed201c ¤   ¤   ¤   mBlockSize = kDefaultBlockSize;
19c943 ¤   ¤   ¤   mTotalBlocks = 0;
fc0fe4 ¤   ¤   }
ca9371 ¤   }
51af5a
e233e3 ¤   return derr;
ebefe6 }
c1af5a
f2ec98 // Unmount asks the driver to unmount a volume. If 'pUMNT' exists, it must
06fe1d // use this packet passed to it from a derived class, instead of its own
67b81a // packet. This allows extensions to be made to the UMNT structure without
9e35da // breaking base classes.
d4af5a
2c2292 DualErr·
3589bc Volume::Unmount(PGPBoolean isThisEmergency, PAD_Unmount useThisPUNMNT)
70bb36 {
61b51e ¤   AD_Unmount¤ UNMNT, *pUNMNT;
30be41 ¤   DualErr¤¤   derr;
4faf5a
9a91dd ¤   pUNMNT = (useThisPUNMNT ? useThisPUNMNT : &UNMNT);
a9af5a
27de3b ¤   pgpAssertAddrValid(pUNMNT, AD_Unmount);
df3ec3 ¤   pgpAssert(Mounted());
32af5a
848279 ¤   // Tell the system the volume is going away.
289e1d ¤   if (IsWinNT4CompatibleMachine())
1bc7a1 ¤   {
b0be1e ¤   ¤   BroadcastDriveMessage(mDrive, DBT_DEVICEREMOVEPENDING);
--cf6e 000cac9d4ce401100d8 Page 10 of Volume.cpp
a19371 ¤   }
93af5a
1fe74d ¤   // Initialize the fields we are responsible for.
6a3bf6 ¤   pUNMNT->drive = mDrive;¤¤   ¤   ¤   ¤   ¤   // drive number to unmount
f3e6f8 ¤   pUNMNT->isThisEmergency = isThisEmergency;¤ // emergency unmount?
b1af5a
a269da ¤   // Send the packet to the driver.
e771f2 ¤   derr = SendUnmountRequest(pUNMNT);
56af5a
892361 ¤   if (derr.IsntError())
2ec7a1 ¤   {
6bbcb1 ¤   ¤   CString root;
1caf5a
fe0fd2 ¤   ¤   // Tell the system the volume has gone away.
9e973e ¤   ¤   if (MakeRoot(mDrive, &root).IsntError())
0c5b34 ¤   ¤   {
ea278b ¤   ¤   ¤   SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, root, NULL);
b00fe4 ¤   ¤   }
90af5a
3e101e ¤   ¤   mDrive = kInvalidDrive;
c0acff ¤   ¤   mMountState = kVol_Unmounted;
af9371 ¤   }
7aaf5a
d933e3 ¤   return derr;
b6efe6 }
3daf5a
89af5a
6c1c7a //////////////////////////////////////////
b3fa77 // Class Volume protected member functions
9a1c7a //////////////////////////////////////////
b1af5a
9d7ff0 // CreateReasonableWriteBuffer creates a buffer of a size that's reasonable
3fbb02 // given that it will be used to write out data of size 'blocksData'.
a7af5a
ce2292 DualErr·
30aef1 Volume::CreateReasonableWriteBuffer(
cf1c4a ¤   PGPUInt32 blocksData,·
81bf72 ¤   PGPUInt8 **buf,·
0e7792 ¤   PGPUInt32 *pBlocksSizeBuf)
43bb36 {
6ebe41 ¤   DualErr¤¤   derr;
8d7c26 ¤   PGPUInt32¤  blocksSizeBuf;
a3af5a
924317 ¤   pgpAssert(blocksData > 0);
e81908 ¤   pgpAssertAddrValid(buf, PGPUInt8 *);
bd2e49 ¤   pgpAssertAddrValid(pBlocksSizeBuf, PGPUInt32);
c4af5a
850644 ¤   // Calculate the ideal size of the buffer to create.
6c7a7b ¤   blocksSizeBuf = blocksData/kIdealNumWritesPerData;
f3af5a
c28a57 ¤   if (blocksSizeBuf < kMinBlocksPerWrite)
5bc7a1 ¤   {
c61787 ¤   ¤   blocksSizeBuf = kMinBlocksPerWrite;
c09371 ¤   }
6e6908 ¤   else if (blocksSizeBuf > kMaxBlocksPerWrite)
10c7a1 ¤   {
49800b ¤   ¤   blocksSizeBuf = kMaxBlocksPerWrite;
0e9371 ¤   }
1aaf5a
8d35d4 ¤   // Create the largest buffer we can that's closest to our ideal size.
073101 ¤   while (TRUE)
e0c7a1 ¤   {
69f90b ¤   ¤   derr = GetByteBuffer(blocksSizeBuf*kDefaultBlockSize, buf);
42af5a
dbaa35 ¤   ¤   if (derr.IsntError())
da5b34 ¤   ¤   {
65447c ¤   ¤   ¤   (* pBlocksSizeBuf) = blocksSizeBuf;
1ccdcb ¤   ¤   ¤   break;
5c0fe4 ¤   ¤   }
280e1d ¤   ¤   else
7b5b34 ¤   ¤   {
ca7a55 ¤   ¤   ¤   blocksSizeBuf /= 2;
--3845 0007c258ea4401100d8 Page 11 of Volume.cpp
e0af5a
020446 ¤   ¤   ¤   if (blocksSizeBuf < kMinBlocksPerWrite)
b5f622 ¤   ¤   ¤   ¤   break;
f50fe4 ¤   ¤   }
119371 ¤   }
cdaf5a
9733e3 ¤   return derr;
00efe6 }
23af5a
69af5a
ca51ef ////////////////////////////////////////
04ccdf // Class Volume private member functions
7051ef ////////////////////////////////////////
d0af5a
3741d5 // FillInVolInfo asks the driver for some extra volume information.
37af5a
ba2292 DualErr·
9e16c4 Volume::FillInVolInfo()
c8bb36 {
8f3ec3 ¤   pgpAssert(Mounted());
d2af5a
d890ac ¤   return QueryVolInfo(mDrive, &mBlockSize, &mTotalBlocks);
f0efe6 }
4faf5a
c29636 // ClearBlocks will clear the specified blocks of the Volume.
9caf5a
4a2292 DualErr·
dfad24 Volume::ClearBlocks(PGPUInt32 startBlock, PGPUInt32 endBlock)
48bb36 {
85be41 ¤   DualErr¤¤   derr;
eccf51 ¤   PGPBoolean¤ allocedBlanks¤  = FALSE;
5521ca ¤   PGPUInt8¤   *blanks;
041906 ¤   PGPUInt32¤  blocksBuf;
e5af5a
1e3ec3 ¤   pgpAssert(Mounted());
51bce4 ¤   pgpAssert(LockedForFormat());
fcaf5a
2dd376 ¤   // Allocate our block buffer.
9977c1 ¤   derr = CreateReasonableWriteBuffer(endBlock - startBlock, &blanks,·
1e3c64 ¤   ¤   &blocksBuf);
0faf5a
66c0dd ¤   allocedBlanks = derr.IsntError();
7daf5a
93780e ¤   // Clear the blocks.
bf2361 ¤   if (derr.IsntError())
33c7a1 ¤   {
688834 ¤   ¤   PGPUInt32 blocksThisTime;
a1af5a
3a4a9b ¤   ¤   pgpClearMemory(blanks, blocksBuf*kDefaultBlockSize);
f1af5a
93892b ¤   ¤   for (PGPUInt32 i = startBlock; i <= endBlock; i += blocksBuf)
c85b34 ¤   ¤   {
ff28ec ¤   ¤   ¤   blocksThisTime = min(blocksBuf, endBlock - i + 1);
c4af5a
2d9df2 ¤   ¤   ¤   derr = Write(blanks, i, blocksThisTime);
4eaf5a
c11088 ¤   ¤   ¤   if (derr.IsError())
98f776 ¤   ¤   ¤   {
91f622 ¤   ¤   ¤   ¤   break;
43a3a6 ¤   ¤   ¤   }
3b0fe4 ¤   ¤   }
a29371 ¤   }
e8af5a
18c565 ¤   // Free our block buffer.
d28be4 ¤   if (allocedBlanks)
a84882 ¤   ¤   FreeByteBuffer(blanks);
0faf5a
8033e3 ¤   return derr;
f0efe6 }
9faf5a
f97d7e // InitFAT12BootBlock fills a FAT12 boot block structure.
7caf5a
--0b49 000cf55b6e6401100d8 Page 12 of Volume.cpp
84c823 void·
beac86 Volume::InitFAT12BootBlock(
ad11fc ¤   PGPUInt64¤  ¤   blocksDisk,·
76c987 ¤   FatData¤¤   ¤   *fat,·
74a0aa ¤   BootSector12¤   *bb12)
f1bb36 {
283940 ¤   Geometry¤   geom;
df08c4 ¤   PartEntry¤  part;
c060a0 ¤   PGPUInt64¤  megsDisk;
98af5a
7cd626 ¤   pgpAssertAddrValid(fat, FatData);
bfa8ac ¤   pgpAssertAddrValid(bb12, BootSector12);
b9e50f ¤   pgpAssert(blocksDisk > 0);
88af5a
31b0b6 ¤   pgpClearMemory(bb12, sizeof(BootSector12));
39af5a
1b11cf ¤   megsDisk = (blocksDisk*kDefaultBlockSize) / kBytesPerMeg;
b49045 ¤   CalcGeometry(blocksDisk, kDefaultBlockSize, &geom);
1daf5a
fa0a90 ¤   // First we fill in the fields of the kBootBlock structure so our VolFile
f2ddd8 ¤   // will look like a real hard disk to Windows when it is mounted.
b2af5a
275a0d ¤   bb12->bsJump[0]¤= 0xEB;¤¤   // fill in jmp instruction to look real
9b46f3 ¤   bb12->bsJump[1]¤= 0x3C;
7d0b52 ¤   bb12->bsJump[2]¤= 0x90;
89af5a
924b03 ¤   pgpCopyMemory(kDefaultOEMName, bb12->bsOemName, 8);¤// can be anything
a6af5a
bde564 ¤   bb12->bsBytesPerSec¤¤   = kDefaultBlockSize;¤   // bytes per sector
30af16 ¤   bb12->bsSecPerClust¤¤   = 1;¤   ¤   ¤   ¤   ¤   // sectors per cluster
969e89 ¤   bb12->bsResSectors¤ ¤   = fat->fdReservedSecs;¤ // reserved sectors
c672c8 ¤   bb12->bsFats¤   ¤   ¤   = fat->fdFatCount;¤ ¤   // number of FATs
13891d ¤   bb12->bsRootDirEnts¤¤   = fat->fdRootDirEnts;¤  // entries in root dir
02ef33 ¤   bb12->bsSectors¤¤   ¤   = (PGPUInt16) geom.geSecsDisk;
7728a2 ¤   bb12->bsMedia¤  ¤   ¤   = kMediaByte;¤  ¤   ¤   // 0xF8 for hard disks
4441c3 ¤   bb12->bsFatSecs¤¤   ¤   = (PGPUInt16) fat->fdFatSize;¤  // secs per FAT
4434b1 ¤   bb12->bsSecPerTrack¤¤   = geom.geSpt;¤  ¤   ¤   // sectors per track
033e10 ¤   bb12->bsHeads¤  ¤   ¤   = geom.geHeads;¤¤   ¤   // number of heads
47de56 ¤   bb12->bsHiddenSecs¤ ¤   = 0;¤   ¤   ¤   ¤   ¤   // no hidden sectors
525bda ¤   bb12->bsHugeSectors¤¤   = 0;
73068e ¤   bb12->bsDriveNumber¤¤   = kHardDriveId;¤¤   ¤   // 0x80 since hard drive
362385 ¤   bb12->bsBootSignature¤  = kFirstBootSig;¤   ¤   // 0x29 needs to go here
462e43 ¤   bb12->bsVolumeId¤   ¤   = (PGPUInt32) &bb12;¤   // address as volume ID
65255d ¤   bb12->bsSignature¤  ¤   = kSecondBootSig;¤  ¤   // boot sector signature
b0af5a
8ccaa4 ¤   pgpCopyMemory(kDefaultVolLabel, bb12->bsVolumeLabel, 11);¤  // vol name
996755 ¤   pgpCopyMemory(kFat12IdStr, bb12->bsFileSysType, 8);¤¤   ¤   // FS type
77af5a
ae93ee ¤   // Fill in our local partition entry structure with the necessary values
d0b8f6 ¤   // to simulate a single partition covering the entire disk.
01af5a
b7f7fb ¤   part.peBootable¤¤   ¤   = kHardDriveId;¤¤   ¤   // 0x80 for bootable vols
3591c5 ¤   part.peBeginHead¤   ¤   = 0;¤   ¤   ¤   ¤   ¤   // starts at vector 0
5fcd69 ¤   part.peBeginSector¤ ¤   = 1;
cb9578 ¤   part.peBeginCylinder¤   = 0;
0bcf08 ¤   part.peFileSystem¤  ¤   = kFat12PartId;
351eed ¤   part.peEndHead¤ ¤   ¤   = geom.geHeads;¤¤   ¤   // end at this vector
4927e9 ¤   part.peEndSector¤   ¤   = geom.geSpt;
84e587 ¤   part.peEndCylinder¤ ¤   = geom.geCyls;
218dd4 ¤   part.peStartSector¤ ¤   = 1;¤   ¤   ¤   ¤   ¤   // no bias to start
df695e ¤   part.peSectors¤ ¤   ¤   = (PGPUInt32) geom.geSecsDisk;¤ // total sectors
acaf5a
b9ad85 ¤   // Copy the partition information into the first entry.
20a798 ¤   bb12->bsPartEnts[0] = part;¤¤   // simple memberwise copy
6eefe6 }
39af5a
580283 // InitFAT16BootBlock fills a FAT16 boot block structure.
32af5a
0cc823 void·
4ea9f0 Volume::InitFAT16BootBlock(
fc11fc ¤   PGPUInt64¤  ¤   blocksDisk,·
cfc987 ¤   FatData¤¤   ¤   *fat,·
--50c6 000cd34086a401100d8 Page 13 of Volume.cpp
c7c6bd ¤   BootSector16¤   *bb16)
6cf0f6 {¤  ¤   ¤
443940 ¤   Geometry¤   geom;
9308c4 ¤   PartEntry¤  part;
cb60a0 ¤   PGPUInt64¤  megsDisk;
cfaf5a
8ed626 ¤   pgpAssertAddrValid(fat, FatData);
0221ef ¤   pgpAssertAddrValid(bb16, BootSector16);
1be50f ¤   pgpAssert(blocksDisk > 0);
22af5a
b9b0d5 ¤   pgpClearMemory(bb16, sizeof(BootSector16));
97af5a
5111cf ¤   megsDisk = (blocksDisk*kDefaultBlockSize) / kBytesPerMeg;
b89045 ¤   CalcGeometry(blocksDisk, kDefaultBlockSize, &geom);
e5af5a
c90a90 ¤   // First we fill in the fields of the kBootBlock structure so our VolFile
ccc9d4 ¤   // will look like a real hard disk to Windows95 when it is mounted.
1eaf5a
8fabea ¤   bb16->bsJump[0]¤= 0xEB;¤¤   // fill in jmp instruction to look real
e39b43 ¤   bb16->bsJump[1]¤= 0x3C;
e1d6e2 ¤   bb16->bsJump[2]¤= 0x90;
b9af5a
eeb25d ¤   pgpCopyMemory(kDefaultOEMName, bb16->bsOemName, 8);¤// can be anything
07af5a
871483 ¤   bb16->bsBytesPerSec¤¤   = kDefaultBlockSize;¤   // bytes per sector
9bf611 ¤   bb16->bsSecPerClust¤¤   = (PGPUInt8) fat->fdSpc;¤   // secs per cluster
dc6f6e ¤   bb16->bsResSectors¤ ¤   = fat->fdReservedSecs;¤ // reserved sectors
5e3132 ¤   bb16->bsFats¤   ¤   ¤   = fat->fdFatCount;¤ ¤   // number of FATs
b06969 ¤   bb16->bsRootDirEnts¤¤   = fat->fdRootDirEnts;¤  // entries in root dir
f39456 ¤   bb16->bsSectors¤¤   ¤   = (PGPUInt16) (megsDisk<32 ? geom.geSecsDisk : 0);
49c8d6 ¤   bb16->bsMedia¤  ¤   ¤   = kMediaByte;¤  ¤   ¤   // 0xF8 for hard disks
6b7480 ¤   bb16->bsFatSecs¤¤   ¤   = (PGPUInt16) fat->fdFatSize;¤  // secs per FAT
e6a7f1 ¤   bb16->bsSecPerTrack¤¤   = geom.geSpt;¤  ¤   ¤   // sectors per track
886686 ¤   bb16->bsHeads¤  ¤   ¤   = geom.geHeads;¤¤   ¤   // number of heads
844d16 ¤   bb16->bsHiddenSecs¤ ¤   = 0;¤   ¤   ¤   ¤   ¤   // no hidden sectors
ed6dda ¤   bb16->bsHugeSectors¤¤   = (PGPUInt32) (megsDisk >= 32 ?·
18e166 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   geom.geSecsDisk : 0);
8f7624 ¤   bb16->bsDriveNumber¤¤   = kHardDriveId;¤¤   ¤   // 0x80 since hard drive
d8532f ¤   bb16->bsBootSignature¤  = kFirstBootSig;¤   ¤   // 0x29 needs to go here
aa98cc ¤   bb16->bsVolumeId¤   ¤   = (PGPUInt32) &bb16;¤   // address as volume ID
5055f7 ¤   bb16->bsSignature¤  ¤   = kSecondBootSig;¤  ¤   // boot sector signature
53af5a
8533fa ¤   pgpCopyMemory(kDefaultVolLabel, bb16->bsVolumeLabel, 11);¤  // vol name
c6fbb2 ¤   pgpCopyMemory(kFat16IdStr, bb16->bsFileSysType, 8);¤¤   ¤   // FS type
1d67c5 ¤
a693ee ¤   // Fill in our local partition entry structure with the necessary values
71b8f6 ¤   // to simulate a single partition covering the entire disk.
7baf5a
8ef7fb ¤   part.peBootable¤¤   ¤   = kHardDriveId;¤¤   ¤   // 0x80 for bootable vols
2b91c5 ¤   part.peBeginHead¤   ¤   = 0;¤   ¤   ¤   ¤   ¤   // starts at vector 0
e4cd69 ¤   part.peBeginSector¤ ¤   = 1;
129578 ¤   part.peBeginCylinder¤   = 0;
eb163a ¤   part.peFileSystem¤  ¤   = (megsDisk >= 32 ? kBigFat16PartId :·
5d564f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kSmallFat16PartId);
981eed ¤   part.peEndHead¤ ¤   ¤   = geom.geHeads;¤¤   ¤   // end at this vector
4827e9 ¤   part.peEndSector¤   ¤   = geom.geSpt;
58e587 ¤   part.peEndCylinder¤ ¤   = geom.geCyls;
a38dd4 ¤   part.peStartSector¤ ¤   = 1;¤   ¤   ¤   ¤   ¤   // no bias to start
9b695e ¤   part.peSectors¤ ¤   ¤   = (PGPUInt32) geom.geSecsDisk;¤ // total sectors
bb67c5 ¤
4bad85 ¤   // Copy the partition information into the first entry.
1283ff ¤   bb16->bsPartEnts[0] = part;¤¤   // simple memberwise copy
dcefe6 }
9eaf5a
3be770 // InitFAT32BootBlock fills a FAT32 boot block structure. It also fills in a
23171f // FAT32 BigFatBootFSInfo structure.
feaf5a
44c823 void·
5da7dc Volume::InitFAT32BootBlock(
6a98c7 ¤   PGPUInt64¤  ¤   ¤   blocksDisk,·
cfa41a ¤   FatData¤¤   ¤   ¤   *fat,·
cd2080 ¤   BootSector32¤   ¤   *bb32,·
--2521 0003b1dfaa4401100d8 Page 14 of Volume.cpp
d6269c ¤   BigFatBootFSInfo¤   *bfInfo)
4bf0f6 {¤  ¤   ¤
713940 ¤   Geometry¤   geom;
c608c4 ¤   PartEntry¤  part;
ff12c2 ¤   PGPUInt64¤  bytesData, megsDisk;
20af5a
dad626 ¤   pgpAssertAddrValid(fat, FatData);
eb90a7 ¤   pgpAssertAddrValid(bb32, BootSector32);
7cc517 ¤   pgpAssertAddrValid(bfInfo, BigFatBootFSInfo);
5be50f ¤   pgpAssert(blocksDisk > 0);
1baf5a
826669 ¤   bytesData = blocksDisk * kDefaultBlockSize;
8f4586 ¤   megsDisk = (blocksDisk*kDefaultBlockSize)/kBytesPerMeg;
dcaf5a
f89045 ¤   CalcGeometry(blocksDisk, kDefaultBlockSize, &geom);
d0af5a
c71c70 ¤   pgpClearMemory(bb32, sizeof(BootSector32));
d3ebb3 ¤   pgpClearMemory(bfInfo, sizeof(BigFatBootFSInfo));
f6af5a
1e0a90 ¤   // First we fill in the fields of the kBootBlock structure so our VolFile
b9c9d4 ¤   // will look like a real hard disk to Windows95 when it is mounted.
42af5a
1613ad ¤   bb32->bsJump[0]¤= 0xEB;¤¤   // fill in jmp instruction to look real
121c58 ¤   bb32->bsJump[1]¤= 0x3C;
9451f9 ¤   bb32->bsJump[2]¤= 0x90;
d6af5a
f41682 ¤   pgpCopyMemory(kDefaultOEMName, bb32->bsOemName, 8);¤// can be anything
51af5a
e0acc4 ¤   bb32->bsBytesPerSec¤¤   = kDefaultBlockSize;¤   // bytes per sector
0038c1 ¤   bb32->bsSecPerClust¤¤   = (PGPUInt8) fat->fdSpc;¤   // sectors per cluster
acd729 ¤   bb32->bsResSectors¤ ¤   = fat->fdReservedSecs;¤ // reserved sectors
c35e83 ¤   bb32->bsFats¤   ¤   ¤   = fat->fdFatCount;¤ ¤   // number of FATs
87d2fb ¤   bb32->bsRootDirEnts¤¤   = 0;¤   ¤   ¤   ¤   ¤   // 0 in FAT32
e7105a ¤   bb32->bsSectors¤¤   ¤   = 0;¤   ¤   ¤   ¤   ¤   // FAT32 must be > 255 Mb
d3b60b ¤   bb32->bsMedia¤  ¤   ¤   = kMediaByte;¤  ¤   ¤   // 0xF8 for hard disks
63cd26 ¤   bb32->bsFatSecs¤¤   ¤   = 0;¤   ¤   ¤   ¤   ¤   // 0 in FAT32
4491f2 ¤   bb32->bsSecPerTrack¤¤   = geom.geSpt;¤  ¤   ¤   // sectors per track
e8c2eb ¤   bb32->bsHeads¤  ¤   ¤   = geom.geHeads;¤¤   ¤   // number of heads
567b15 ¤   bb32->bsHiddenSecs¤ ¤   = 0;¤   ¤   ¤   ¤   ¤   // no hidden sectors
10b774 ¤   bb32->bsHugeSectors¤¤   = (PGPUInt32) geom.geSecsDisk;
28af5a
c7a6d1 ¤   bb32->bsBigSectorsPerFat¤   = fat->fdFatSize;¤  // total sectors per FAT
e3bb23 ¤   bb32->bsExtFlags¤   ¤   = NULL;¤¤   ¤   ¤   ¤   // extended flags
d041c9 ¤   bb32->bsFS_Version¤ ¤   = NULL;¤¤   ¤   ¤   ¤   // filesystem version
362509 ¤   bb32->bsRootDirStrtClus¤= kDefaultRootDirStart;¤// first clust of root dir
071294 ¤   bb32->bsFsInfoSec¤  ¤   = kDefaultBigFatStart;¤ // sector of Bigfat
e0859d ¤   bb32->bsBkUpBootSec¤¤   = -1;¤  ¤   ¤   ¤   ¤   // no backup boot sec
65af5a
9a039e ¤   bb32->bsDriveNumber¤¤   = kHardDriveId;¤¤   ¤   // 0x80 since hard drive
9c2695 ¤   bb32->bsBootSignature¤  = kFirstBootSig;¤   ¤   // 0x29 needs to go here
b3b9d6 ¤   bb32->bsVolumeId¤   ¤   = (PGPUInt32) &bb32;¤   // use address as ID
b0204d ¤   bb32->bsSignature¤  ¤   = kSecondBootSig;¤  ¤   // boot sector signature
b6af5a
999725 ¤   pgpCopyMemory(kDefaultVolLabel, bb32->bsVolumeLabel, 11);¤  // vol name
a9aacb ¤   pgpCopyMemory(kFat32IdStr, bb32->bsFileSysType, 8);¤¤   ¤   // FS type
8b67c5 ¤
1393ee ¤   // Fill in our local partition entry structure with the necessary values
07b8f6 ¤   // to simulate a single partition covering the entire disk.
73af5a
08a39e ¤   part.peBootable¤¤   ¤   = 0x80;¤¤   ¤   ¤   ¤   // 0x80 for bootable vols
4291c5 ¤   part.peBeginHead¤   ¤   = 0;¤   ¤   ¤   ¤   ¤   // starts at vector 0
7dcd69 ¤   part.peBeginSector¤ ¤   = 1;
6d9578 ¤   part.peBeginCylinder¤   = 0;
cf9746 ¤   part.peFileSystem¤  ¤   = kFat32PartId;
171eed ¤   part.peEndHead¤ ¤   ¤   = geom.geHeads;¤¤   ¤   // end at this vector
4327e9 ¤   part.peEndSector¤   ¤   = geom.geSpt;
c8e587 ¤   part.peEndCylinder¤ ¤   = geom.geCyls;
5b8dd4 ¤   part.peStartSector¤ ¤   = 1;¤   ¤   ¤   ¤   ¤   // no bias to start
b2695e ¤   part.peSectors¤ ¤   ¤   = (PGPUInt32) geom.geSecsDisk;¤ // total sectors
d067c5 ¤
59ad85 ¤   // Copy the partition information into the first entry.
3b285e ¤   bb32->bsPartEnts[0] = part;¤¤   // simple memberwise copy
--27e4 0015c0757e7401100d8 Page 15 of Volume.cpp
e0af5a
b059f2 ¤   // Finally initialize the BigFatBootInfo structure.
5685ae ¤   bfInfo->bfSecSig¤   ¤   ¤   ¤   = kBigFatSecSig;
1ae450 ¤   bfInfo->bfFSInf_Sig¤¤   ¤   ¤   = kBigFatSig;
d077e0 ¤   bfInfo->bfFSInf_next_free_clus¤ = kDefaultRootDirStart;
17ff90 ¤   bfInfo->bsSignature¤¤   ¤   ¤   = kSecondBootSig;
4daf5a
cdf5f9 ¤   bfInfo->bfFSInf_free_clus_cnt = (PGPUInt32)
3607ce ¤   ¤   (bytesData / (fat->fdSpc * kDefaultBlockSize) + 2);
5cefe6 }
--e8dc 0006dd74c08401100d9 Page 1 of Volume.h
541bc3 //////////////////////////////////////////////////////////////////////////////
54d7ee // Volume.h
2f465d //
5be0c7 // Declaration of class Volume.
921bc3 //////////////////////////////////////////////////////////////////////////////
c9af5a
cf34dc // $Id: Volume.h,v 1.1.2.11 1998/07/06 08:57:34 nryan Exp $
81af5a
34cbce // Copyright (C) 1998 by Network Associates, Inc.
d771ae // All rights reserved.
80af5a
ce46c3 #ifndef Included_Volume_h¤  // [
d7ce0d #define Included_Volume_h
c1af5a
683db7 #include "FatUtils.h"
ca0092 #include "Packets.h"
ddaf5a
9caf5a
c97606 ///////////////
596d45 // Class Volume
757606 ///////////////
79af5a
27576c // Class Volume represent a local volume. This class's purpose is to serve as
10402c // one of the two base classes for class VolFile.
c4af5a
4638b0 class Volume
92bb36 {
b25ed4 public:
86fe31 ¤   ¤   ¤   ¤   Volume(PGPUInt8 drive = kInvalidDrive);
313b86 ¤   virtual¤¤   ~Volume();
7aaf5a
33a804 ¤   PGPUInt8¤   GetDrive();
713431 ¤   PGPUInt16¤  GetBlockSize();
e9bda3 ¤   PGPUInt64¤  GetTotalBlocks();
79af5a
be0ab3 ¤   PGPBoolean¤ Mounted();
418e1a ¤   PGPBoolean¤ Unmounted();
7520d5 ¤   PGPBoolean¤ AttachedToLocalVolume();
c7fa2a ¤   PGPBoolean¤ HasOpenFiles();
2baf5a
b2c569 ¤   PGPBoolean¤ LockedForReadWrite();
351a7d ¤   PGPBoolean¤ LockedForFormat();
75af5a
0f88ee ¤   void¤   ¤   BrowseToVolume();
11af5a
3459e6 ¤   DualErr¤¤   GetVolumeLabel(LPSTR label, PGPUInt32 size);
234e99 ¤   DualErr¤¤   SetVolumeLabel(LPCSTR label);
91af5a
1da28f ¤   DualErr¤¤   AttachLocalVolume(PGPUInt8 drive);
456b08 ¤   void¤   ¤   DetachLocalVolume();
6aaf5a
4b43eb ¤   DualErr¤¤   LockVolumeForReadWrite();
fea9b4 ¤   DualErr¤¤   LockVolumeForFormat();
403e26 ¤   DualErr¤¤   UnlockVolume();
94af5a
3cb66a ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks);
ee0aa1 ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks);
74af5a
863979 ¤   DualErr¤¤   Format();
a1af5a
b57f00 ¤   DualErr¤¤   Mount(PGPBoolean mountReadOnly = FALSE,·
3eaacf ¤   ¤   ¤   ¤   ¤   PAD_Mount useThisPMNT = NULL);
8d554a ¤   DualErr¤¤   Unmount(PGPBoolean isThisEmergency = FALSE,·
34769b ¤   ¤   ¤   ¤   ¤   PAD_Unmount useThisPUNMT = NULL);
17af5a
c4a2d3 protected:
5a2c5b ¤   DualErr¤¤   CreateReasonableWriteBuffer(PGPUInt32 blocksData,·
29cf65 ¤   ¤   ¤   ¤   ¤   PGPUInt8 **buf, PGPUInt32 *pBlocksSizeBuf);
91af5a
5c0fb9 private:
0e2ca6 ¤   enum LockState¤ {kLock_None, kLock_ReadWrite, kLock_Format};
6d6d60 ¤   enum MountState¤{kVol_Mounted, kVol_Unmounted};
--b980 001f2fa04d8401100d9 Page 2 of Volume.h
e0af5a
d9f1ea ¤   MountState¤ mMountState;¤   ¤   // mount status of the volume
677871 ¤   LockState¤  mLockState;¤¤   ¤   // lock status of the volume
265ef6 ¤   PGPUInt8¤   mDrive;¤¤   ¤   ¤   // drive # of the volume
d3af5a
3c2340 ¤   PGPBoolean¤ mAttachedToLocalVol;¤   // attached to local volume?
06c1cf ¤   PGPUInt16¤  mBlockSize;¤¤   ¤   // block size
b0e0be ¤   PGPUInt64¤  mTotalBlocks;¤  ¤   // block size
dcaf5a
b6ffef ¤   DualErr¤FillInVolInfo();
5daf5a
71237f ¤   DualErr ClearBlocks(PGPUInt32 startBlock, PGPUInt32 endBlock);
c6af5a
8943f2 ¤   void¤   InitFAT12BootBlock(PGPUInt64 blocksDisk, FatData *fat,·
1e4b0c ¤   ¤   ¤   ¤   BootSector12 *bb12);
ca7e0b ¤   void¤   InitFAT16BootBlock(PGPUInt64 blocksDisk, FatData *fat,·
d9897c ¤   ¤   ¤   ¤   BootSector16 *bb16);
f2f2c3 ¤   void¤   InitFAT32BootBlock(PGPUInt64 blocksDisk, FatData *fat,·
878f99 ¤   ¤   ¤   ¤   BootSector32 *bb32, BigFatBootFSInfo *bfInfo);
d782f7 };
0caf5a
f2ac71 #endif¤ // ] Included_Volume_h
--abef 001a163cb79401100da Page 1 of PGPdisk.rc
bc38e5 /*
ae5d62 ¤   PGPdisk.rc - version resources
72bb72 ¤   Copyright Notice (c)
0f495d ·*/
28af5a
1c0380 #include <winver.h>
2c5a72 #include "..\Shared\PGPdiskVersion.h"
81af5a
96db66 #define VER_FILEFLAGSMASK¤  VS_FFI_FILEFLAGSMASK
fd86e1 #define VER_FILEOS ·········VOS_NT_WINDOWS32
6fd050 #define VER_FILEFLAGS¤  ¤   0
a5af5a
8f51c7 #define VER_PRODUCTVERSION_STR kPGPdiskFileVerString
c9af5a
3c82a5 #define VER_COMPANYNAME_STR ¤   ¤   kPGPdiskCompanyName
1096f5 #define VER_PRODUCTNAME_STR ¤   ¤   kPGPdiskProductVerName
4572e6 #define VER_LEGALCOPYRIGHT_STR¤ ¤   kPGPdiskCopyright
b9d378 #define VER_PRODUCTVERSION_DW ······(0x01000000 | VER_PRODUCTBUILD)
42af5a
d8527a #define VER_FILETYPE ···¤   ¤   VFT_DRV
c0e2f1 #define VER_FILESUBTYPE ¤   ¤   VFT2_DRV_SYSTEM
89078b #define VER_FILEDESCRIPTION_STR "PGPdisk Driver for Windows NT"
75692d #define VER_INTERNALNAME_STR¤   "PGPdisk.sys"
98af5a
d40850 #include "common.ver"
a1c8cc #include "msglog.rc"
--b83a 001b75a24ed401100db Page 1 of RunBuild.bat
0cb205 set PGPDISKSOURCEDRIVE=C
789650 set PGPDISKSOURCEPATH=C:\PGP60\Clients\Disk\Win32
bbaf5a
b7d48c call %PGPDISKSOURCEPATH%\PGPdiskDrvNT\RunBuildAux.bat %1 %2
--67f3 00076a78a86401100dc Page 1 of RunBuildAux.bat
aaad7e @echo off
aeaf5a
1a941b set NTVERSION=400
0eaf5a
37dd09 rem Batch file to build Driver::Works projects
3a25b4 rem
937bd5 rem¤¤   Arguments are:
e6addf rem¤¤   ¤   ¤   arg 1¤  ¤   checked or free
90a7bb rem¤¤   ¤   ¤   arg 2¤  ¤   passed to BUILD program
b8af5a
89f13a rem ensure that environment is set up correctly
12d698 if "%BASEDIR%"=="" goto NeedEnvironment
40b91e if "%DRIVERWORKS%"=="" goto NeedVDW
37af5a
3a84ab rem check arguments
9adb7f if "%1"=="free" goto argok
25eac8 if "%1"=="checked" goto argok
cac836 goto badarg
c71014 :argok
2daf5a
386dd4 del %basedir%\build.dat
9bd89d call %basedir%\bin\setenv %basedir% %1
91af5a
15456d %PGPDISKSOURCEDRIVE%:
05af5a
30ac6c cd %PGPDISKSOURCEPATH%\PGPdiskDrvNT\Source
07379f copy *.cpp ..
9209c2 copy Function.h ..
03af5a
045450 cd %PGPDISKSOURCEPATH%\Shared
9a4bac copy *.cpp %PGPDISKSOURCEPATH%\PGPdiskDrvNT
75af5a
7f9f98 cd %PGPDISKSOURCEPATH%\Encryption
d64bac copy *.cpp %PGPDISKSOURCEPATH%\PGPdiskDrvNT
02af5a
440b01 cd %PGPDISKSOURCEPATH%\..\..\..\libs\pfl\common
9caf5a
c7d6a5 copy pgpDebug.c %PGPDISKSOURCEPATH%\PGPdiskDrvNT\pgpDebug.cpp
9b6973 copy pgpLeaks.c %PGPDISKSOURCEPATH%\PGPdiskDrvNT\pgpLeaks.cpp
575cb0 copy pgpMem.c %PGPDISKSOURCEPATH%\PGPdiskDrvNT\pgpMem.cpp
70af5a
24f88e cd %PGPDISKSOURCEPATH%\PGPdiskDrvNT
3baf5a
b48465 if NOT EXIST %cpu% mkdir %cpu%
16b7c3 if NOT EXIST %cpu%\checked mkdir %cpu%\checked
c07a7f if NOT EXIST %cpu%\free mkdir %cpu%\free
43af5a
dea1f4 path %basedir%\bin;%path%
07c0c2 %basedir%\bin\build.exe -m -w -z %2
34af5a
7a1ea0 goto done
66af5a
e18c74 :NeedEnvironment
e804c8 @echo DDK environment (BASEDIR) must be set up before building driver
777e31 goto Done
c1af5a
b538ec :NeedVDW
3cbef3 @echo DRIVERWORKS environment variable must be defined before building driver
427e31 goto Done
f2af5a
f9ff4d :NeedNTVersion
ce8811 @echo NTVERSION environment variable must be defined before building driver
c07e31 goto Done
05af5a
cc6064 :badarg
c749e2 @echo Must specify "checked" or "free" to VDW.BAT
347e31 goto Done
a4af5a
38e881 :done
07af5a
d76bd8 del *.cpp
767c39 del Function.h
--c8a9 001370e4e1e401100dc Page 2 of RunBuildAux.bat
e0af5a
90f3c9 if NOT EXIST MC_RAN.### goto no_MC_RAN
c71423 echo *** If you see exactly one _error_ message, you can safely ignore it.
1f73f6 echo *** Developer Studio is mistaking the normal output of MC (message
fb2867 echo *** compiler) for a real _error_.
45c8f6 echo ***
68adce echo *** If you build again, Studio should report no _errors_ since MC will
46347c echo *** not be invoked.
c0c8f6 echo ***
6c34c5 del MC_RAN.###
79cba6 :no_MC_RAN
e8af5a
37c845 @echo End of RUNBUILD.BAT
--ecef 00138343702401100dd Page 1 of makefile
0f44a3 # MAKEFILE for PGPdisk
1ea601 #
c712f9 # DO NOT EDIT THIS FILE!!! ·Edit .\sources. if you want to add a new source
2cde86 # file to this component. ·This file merely indirects to the real make file
1fff74 # that is shared by all the driver components of the Windows NT DDK
f2a601 #
05af5a
3872ae !INCLUDE $(NTMAKEENV)\makefile.def
--724a 00119642c81401100de Page 1 of makefile.inc
57b428 PGPdisk.rc: msglog.rc
d7af5a
510e35 msglog.h msglog.rc msg00001.bin: msglog.mc
fd455f ····mc -v msglog.mc
193408 ¤   copy msglog.mc MC_RAN.###
--20b2 0018126ac71401100df Page 1 of msglog.mc
dcfd50 ;
c44fa9 ;//File Name: msglog.mc
43caba ;//
e91077 ;// ·Note: comments in the .mc file must use both ";" and "//".
8acaba ;//
a6dc2f ;// ·Status values are 32 bit values layed out as follows:
4fcaba ;//
8402fa ;// ··3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
2fe6af ;// ··1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
fdca35 ;// ·+---+-+-------------------------+-------------------------------+
66e7eb ;// ·|Sev|C| ······Facility ·········| ··············Code ···········|
50ca35 ;// ·+---+-+-------------------------+-------------------------------+
1ccaba ;//
7bc436 ;// ·where
a8caba ;//
9638a1 ;// ·····Sev - is the severity code
9dcaba ;//
9b9124 ;// ·········00 - Success
be1000 ;// ·········01 - Informational
747d28 ;// ·········10 - Warning
e790a4 ;// ·········11 - Error
36caba ;//
216a1b ;// ·····C - is the Customer code flag
a1caba ;//
485031 ;// ·····Facility - is the facility code
56caba ;//
5e2850 ;// ·····Code - is the facility's status code
9ecaba ;//
2cfd50 ;
81cdfd MessageIdTypedef=NTSTATUS
26af5a
0323e0 SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
313d9a ···············Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
4d6975 ···············Warning=0x2:STATUS_SEVERITY_WARNING
6cb86a ···············Error=0x3:STATUS_SEVERITY_ERROR
a190d5 ··············)
17af5a
d13d7d FacilityNames=(System=0x0
d27e5a ···············RpcRuntime=0x2:FACILITY_RPC_RUNTIME
1d2415 ···············RpcStubs=0x3:FACILITY_RPC_STUBS
72a1a3 ···············Io=0x4:FACILITY_IO_ERROR_CODE
fc0d6e ¤   ¤   ¤   ···PGPDISK=0x7:FACILITY_PGPDISK_ERROR_CODE
7090d5 ··············)
31af5a
f6fd50 ;
5dcaba ;//
64bb90 ;// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
3abeb0 ;// called with a device, the name of the device will be inserted into
29409b ;// the message at %1. Otherwise, the place of %1 will be left empty.
9f496e ;// In either case, the insertion strings from the driver's error log
61f00d ;// entry starts at %2. In other words, the first insertion string goes
dfeabd ;// to %2, the second to %3 and so on.
bccaba ;//
c9fd50 ;
54af5a
36df08 MessageId=0x0001
ec04cc Facility=PGPDISK
a4f251 Severity=Error
45fa16 SymbolicName=PGPDISK_ERROR_CODE
5a028d Language=English
68a48c PGPdisk: %2.
811679 .
--4ec6 0019dda4af6401100e0 Page 1 of pgpsym.bat
6a4e60 SET SOURCE=C:\SOURCE\LIBS\PFL\COMMON
3f54eb SET SOURCE=C:\SOURCE\CLIENTS\DISK\WIN32\SHARED;%SOURCE%
530580 SET SOURCE=C:\SOURCE\CLIENTS\DISK\WIN32\ENCRYPTION;%SOURCE%
d7c29d SET SOURCE=C:\SOURCE\CLIENTS\DISK\WIN32\PGPDISKDRVNT\SOURCE;%SOURCE%
1baf5a
6a15b8 SET PGPDISKDRV=C:\SOURCE\CLIENTS\DISK\WIN32\PGPDISKDRVNT\I386\CHECKED\PGPDISK.S¶
7c4938 YS
70af5a
9d605c C:\NTICE\NMSYM /LOAD /TRANSLATE:ALWAYS,PACKAGE /SOURCE:%SOURCE% %PGPDISKDRV%
--abe0 00071ea7810401100e1 Page 1 of sources
df2836 # SOURCES
1caf5a
b3fbbc MAKEDIR=.
e1b137 TARGETNAME=PGPdisk
e67340 TARGETPATH=.
f6998a TARGETTYPE=DRIVER
a71128 TARGETLIBS=$(DRIVERWORKS)\lib\*\$(DDKBUILDENV)\vdw.lib
caaabb BROWSER_INFO=FALSE
245eea RCNOFONTMAP=1
b5af5a
2943b5 !IF $(FREEBUILD)
deaf5a
0e8b8c LINKER_FLAGS = -ignore:4049
552f58 USER_C_FLAGS = /W3 /WX
55af5a
e76226 C_DEFINES=/DNTVERSION=$(NTVERSION) /DUCHAR_MAX=0xFF /DUSHRT_MAX=0xFFFF \
36bf28 ¤   ¤   ¤   /DULONG_MAX=0xFFFFFFFF /DINT_MAX=0xFFFFFFFF /D_CRT_ASSERT=0 \
3445fd ¤   ¤   ¤   /D_MSC_VER=5000 /DPGP_DEBUG=0 /DPGPDISK_NTDRIVER /DPGP_INTEL \
5f2938 ¤   ¤   ¤   /DPGP_WIN32
d5af5a
4d1cbd !ELSE
dcaf5a
9a8b8c LINKER_FLAGS = -ignore:4049
0d2f58 USER_C_FLAGS = /W3 /WX
b3af5a
576226 C_DEFINES=/DNTVERSION=$(NTVERSION) /DUCHAR_MAX=0xFF /DUSHRT_MAX=0xFFFF \
65bf28 ¤   ¤   ¤   /DULONG_MAX=0xFFFFFFFF /DINT_MAX=0xFFFFFFFF /D_CRT_ASSERT=0 \
022f3e ¤   ¤   ¤   /D_MSC_VER=5000 /DDEBUG /DPGP_DEBUG=1 /DPGPDISK_NTDRIVER \
def901 ¤   ¤   ¤   /DPGP_INTEL /DPGP_WIN32 /DUNFINISHED_CODE_ALLOWED /D_CRTIMP=""
7aaf5a
160945 !ENDIF
e9af5a
85c7d3 INCLUDES=$(DRIVERWORKS)\include;$(DRIVERWORKS)\source;$(BASEDIR)\inc;\
f6ee14 ¤   $(PGPDISKSOURCEPATH)\PGPdiskDrvNT\Source;\
506cda ¤   $(PGPDISKSOURCEPATH)\PGPdiskDrvNT\FakeSource;\
0252fe ¤   $(PGPDISKSOURCEPATH)\PGPdiskDrvNT\FakeSource\sys;\
d0adb6 ¤   $(PGPDISKSOURCEPATH)\Shared;$(PGPDISKSOURCEPATH)\Encryption;\
640fa9 ¤   $(PGPDISKSOURCEPATH)\..\..\..\libs\pfl\common;\
637645 ¤   $(PGPDISKSOURCEPATH)\..\..\..\libs\pfl\win32
1baf5a
1d89b7 SOURCES=¤   PGPdisk.rc \
6ba2b8 ¤   ¤   ¤   pgpDebug.cpp \
9ab5da ¤   ¤   ¤   pgpLeaks.cpp \
0930f1 ¤   ¤   ¤   pgpMem.cpp \
03d8bd ¤   ¤   ¤   CRunTimeExtras.cpp \
1f5c66 ¤   ¤   ¤   CPGPdiskDriver.cpp \
b4514a ¤   ¤   ¤   CPGPdiskInterface.cpp \
64e8c1 ¤   ¤   ¤   CPGPdiskInterfaceComm.cpp \
497f40 ¤   ¤   ¤   CPGPdiskInterfaceErrors.cpp \
bd5dfe ¤   ¤   ¤   CPGPdiskInterfaceHooks.cpp \
5dd2c2 ¤   ¤   ¤   CPGPdiskInterfaceVolumes.cpp \
64dab9 ¤   ¤   ¤   File.cpp \
8519da ¤   ¤   ¤   KernelModeUtils.cpp \
156557 ¤   ¤   ¤   NtThreadSecurity.cpp \
83a6d8 ¤   ¤   ¤   PGPdisk.cpp \
6eed48 ¤   ¤   ¤   PGPdiskRequestQueue.cpp \
9d432a ¤   ¤   ¤   PGPdiskWorkerThread.cpp \
b36aa5 ¤   ¤   ¤   UserMemoryManager.cpp \
241196 ¤   ¤   ¤   VolFile.cpp \
654451 ¤   ¤   ¤   Volume.cpp \
a11db1 ¤   ¤   ¤   CommonStrings.cpp \
f6af8d ¤   ¤   ¤   DualErr.cpp \
157bb9 ¤   ¤   ¤   Errors.cpp \
4ca18c ¤   ¤   ¤   PGPdiskContainer.cpp \
ec816c ¤   ¤   ¤   PGPdiskLowLevelUtils.cpp \
f63597 ¤   ¤   ¤   PGPdiskHighLevelUtils.cpp \
46f270 ¤   ¤   ¤   PGPdiskPFL.cpp \
f448e8 ¤   ¤   ¤   SecureMemory.cpp \
34e326 ¤   ¤   ¤   SecureString.cpp \
ec4c21 ¤   ¤   ¤   StringAssociation.cpp \
4403d1 ¤   ¤   ¤   WaitObjectClasses.cpp \
715a7e ¤   ¤   ¤   Cast5.cpp \
--eaa6 001a02a6bcf401100e1 Page 2 of sources
274a92 ¤   ¤   ¤   Cast5Box.cpp \
a23056 ¤   ¤   ¤   CipherContext.cpp \
6adce1 ¤   ¤   ¤   CipherUtils.cpp \
747dcc ¤   ¤   ¤   SHA.cpp
d7af5a
a0af1a NTTARGETFILE0=msglog.h
--7541 001e1ebc101401100e2 Page 1 of Crtdbg.h
541bc3 //////////////////////////////////////////////////////////////////////////////
e1c5f3 // Crtdbg.h
1f465d //
a27822 // A fake source file designed to pacify the PFL.
da1bc3 //////////////////////////////////////////////////////////////////////////////
72af5a
356113 // $Id: Crtdbg.h,v 1.1.2.4 1998/05/08 18:29:37 nryan Exp $
1daf5a
18cbce // Copyright (C) 1998 by Network Associates, Inc.
4a71ae // All rights reserved.
9aaf5a
f297a3 #ifndef Included_Crtdbg_h¤  // [
bbdc10 #define Included_Crtdbg_h
5eaf5a
e2d7a1 #include <vdw.h>
42af5a
e1be6c #endif¤ // ] Included_Crtdbg_h
--8cc9 0014d5094a3401100e3 Page 1 of Limits.h
541bc3 //////////////////////////////////////////////////////////////////////////////
615075 // Limits.h
e3465d //
327822 // A fake source file designed to pacify the PFL.
6b1bc3 //////////////////////////////////////////////////////////////////////////////
0daf5a
b5602d // $Id: Limits.h,v 1.1.2.5 1998/05/22 08:35:28 nryan Exp $
43af5a
63cbce // Copyright (C) 1998 by Network Associates, Inc.
0f71ae // All rights reserved.
2aaf5a
ae1ae6 #ifndef Included_Limits_h¤  // [
6a4996 #define Included_Limits_h
62af5a
10d7a1 #include <vdw.h>
f13714 //#include "CRunTimeExtras.h"
2aaf5a
c3b9d8 // Stuff to get the PFL to work.
35af5a
38ffb5 #undef¤ alignof
68cdd2 #define¤alignof(type) (1)
efaf5a
fc4cdb // We need to 'roll our own' _CrtDbgReport.
978be7 int _CrtDbgReport(int arg1, int arg2, int arg3, int arg4, const char *format,·
ed946d ¤   ¤   const char* message);
3eaf5a
c22870 // We need to 'roll our own' _CrtDbgBreak.
195cd0 int¤_CrtDbgBreak();
ceaf5a
4d2bea #endif¤ // ] Included_Limits_h
--8fdf 0005580b041401100e4 Page 1 of CPGPdiskDriver.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
7239c3 // CPGPdiskDriver.cpp
fe465d //
4c918f // Definition of class CPGPdiskDriver.
fb1bc3 //////////////////////////////////////////////////////////////////////////////
65af5a
c41fe8 // $Id: CPGPdiskDriver.cpp,v 1.1.2.17 1998/08/04 01:19:54 nryan Exp $
14af5a
17cbce // Copyright (C) 1998 by Network Associates, Inc.
e271ae // All rights reserved.
76af5a
19d52a #define VDW_MAIN
02af5a
1c6b7a #pragma warning(disable:4244)
10d7a1 #include <vdw.h>
5e093d #pragma warning(default:4244)
d2af5a
319bcf #include "Required.h"
bd5788 #include "PGPdiskVersion.h"
59bfe9 #include "UtilityFunctions.h"
c9af5a
949281 #include "CPGPdiskDriver.h"
eee0ee #include "CPGPdiskInterface.h"
77c411 #include "Globals.h"
6a9969 #include "Function.h"
93f1f6 #include "KernelModeUtils.h"
a7af5a
748321 DECLARE_DRIVER_CLASS(CPGPdiskDriver, NULL)
76af5a
8aaf5a
fcfcb8 //////////////////////////////////
f2a58c // Global variables for the driver
3bfcb8 //////////////////////////////////
5caf5a
83fb63 CPGPdiskInterface *Interface;¤  ¤   // pointer to the interface object
08af5a
38af5a
2cedb3 ///////////////////////////////////////////////
71688f // Class CPGPdiskDriver public member functions
8eedb3 ///////////////////////////////////////////////
ceaf5a
de4d7d // DriverEntry is called when the driver is started.
f9af5a
910e00 NTSTATUS·
761cb9 CPGPdiskDriver::DriverEntry(PUNICODE_STRING RegistryPath)
bebb36 {
238909 ¤   NTSTATUS¤   status¤ ¤   ¤   ¤   = STATUS_SUCCESS;
7b1492 ¤   PGPBoolean¤ createdInterface¤   = FALSE;
15af5a
f46bac ¤   __try
29c7a1 ¤   {
c4c9fb ¤   ¤   // Disable unloads on release builds (long story).
194a53 ¤   #if !PGP_DEBUG
9fa99c ¤   ¤   DisableUnload();
3e52c8 ¤   #endif // PGP_DEBUG
caaf5a
a4015e ¤   ¤   // Set default pool tag for all 'new' allocations.
dd6ce6 ¤   ¤   SetPoolTag(kPGPdiskMemPoolTag);
d2af5a
a6a3ed ¤   ¤   // Create interface object for app communication.
c361bd ¤   ¤   Interface = new CPGPdiskInterface(this);
48596e ¤   ¤   createdInterface = IsntNull(Interface);
25af5a
44455f ¤   ¤   if (!createdInterface)
d65b34 ¤   ¤   {
e415da ¤   ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
2bad85 ¤   ¤   ¤   status = STATUS_INSUFFICIENT_RESOURCES;
380fe4 ¤   ¤   }
bbaf5a
b5041a ¤   ¤   // Did it construct successfully?
d5ab3a ¤   ¤   if (mInitErr.IsntError())
555b34 ¤   ¤   {
--4dcf 000b3779a05401100e4 Page 2 of CPGPdiskDriver.cpp
a0d06d ¤   ¤   ¤   mInitErr = Interface->mInitErr;
9daf5a
e41f5d ¤   ¤   ¤   if (mInitErr.IsError())
70f829 ¤   ¤   ¤   ¤   status = STATUS_INSUFFICIENT_RESOURCES;
a40fe4 ¤   ¤   }
caaf5a
dedc12 ¤   ¤   // All code from here on refers to the interface class object.
c7ab3a ¤   ¤   if (mInitErr.IsntError())
985b34 ¤   ¤   {
2e8c98 ¤   ¤   ¤   EnableDispatchFilter(TRUE);
e5af5a
42d120 ¤   ¤   ¤   DebugOut("PGPdisk Driver v%s loaded.\n", kVersionTextString);
dba244 ¤   ¤   ¤   DebugOut("Copyright (C) 1998 Network Associates, Inc.\n\n");
2f0fe4 ¤   ¤   }
2b0e1d ¤   ¤   else
a55b34 ¤   ¤   {
10c030 ¤   ¤   ¤   DebugOut("PGPdisk Driver v%s failed to load.\n\n",·
b127d7 ¤   ¤   ¤   ¤   kVersionTextString);
cfaf5a
c032f3 ¤   ¤   ¤   if (createdInterface)
2cf776 ¤   ¤   ¤   {
ae6090 ¤   ¤   ¤   ¤   delete Interface;
c78d75 ¤   ¤   ¤   ¤   Interface = NULL;
e9a3a6 ¤   ¤   ¤   }
350fe4 ¤   ¤   }
379371 ¤   }
acbc2f ¤   __except(EXCEPTION_EXECUTE_HANDLER)·
3bc7a1 ¤   {
568775 ¤   ¤   Interface->ReportError(kPGDMajorError_KModeExceptionOccured);
20af5a
503497 ¤   ¤   // Don't leave this hanging if we refuse to unload.
ea05fb ¤   ¤   if (createdInterface)
db5b34 ¤   ¤   {
a55798 ¤   ¤   ¤   delete Interface;
caba7d ¤   ¤   ¤   Interface = NULL;
2b0fe4 ¤   ¤   }
32af5a
ee16d9 ¤   ¤   mInitErr = DualErr(kPGDMinorError_KModeExceptionOccured);
383bc4 ¤   ¤   status = STATUS_INSUFFICIENT_RESOURCES;
729371 ¤   }
3baf5a
6b01b5 ¤   return status;
9defe6 }
48af5a
78d9eb // Unload is called when the driver is being unloaded.
79af5a
0fa1ba VOID·
196fd0 CPGPdiskDriver::Unload()
ebbb36 {
acd9be ¤   // DON'T call base class Unload(), it has a bug because it assumes all
aea816 ¤   // devices created by the driver were created only by class KDevice, and
ccf365 ¤   // makes things blow up if that isn't so.
52af5a
d46bac ¤   __try
9bc7a1 ¤   {
20dab2 ¤   ¤   DebugOut("PGPdisk Driver v%s unloading.\n\n", kVersionTextString);
b0af5a
0a3dce ¤   ¤   Interface->UnmountAllPGPdisks();
6baf5a
62d19f ¤   ¤   // Delete interface object.
0272d1 ¤   ¤   if (IsntNull(Interface))
ed5b34 ¤   ¤   {
a35798 ¤   ¤   ¤   delete Interface;
0cba7d ¤   ¤   ¤   Interface = NULL;
7e0fe4 ¤   ¤   }
1b9371 ¤   }
eebc2f ¤   __except(EXCEPTION_EXECUTE_HANDLER)·
27c7a1 ¤   {
868775 ¤   ¤   Interface->ReportError(kPGDMajorError_KModeExceptionOccured);
2e9371 ¤   }
11efe6 }
b3af5a
--7eba 0006a7c4fdc401100e4 Page 3 of CPGPdiskDriver.cpp
a99758 // DispatchPGPdiskRequest dispatches an IRP destined for a PGPdisk.
5eaf5a
be0e00 NTSTATUS·
c0e875 CPGPdiskDriver::DispatchPGPdiskRequest(
7a4d42 ¤   KIrp¤   ¤   I,·
f58c8e ¤   PGPdisk¤¤   *pPGD,·
bd728c ¤   PGPBoolean¤ *irpNeedsCompletion)
31bb36 {
16be41 ¤   DualErr¤¤   derr;
ec48b3 ¤   NTSTATUS¤   status¤ = STATUS_SUCCESS;
feaf5a
6f5b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
3130ed ¤   pgpAssertAddrValid(irpNeedsCompletion, PGPBoolean);
30af5a
9a71da ¤   (* irpNeedsCompletion) = TRUE;
66af5a
8989dd ¤   DebugOut("\nPGPdisk: Seeing IRP %X which is an %s\n",·
bf0426 ¤   ¤   (PIRP) I, GetIRPMajorFunctionName(I.MajorFunction()));
a7af5a
f4a217 ¤   switch (I.MajorFunction())
47c7a1 ¤   {
ec92fe ¤   case IRP_MJ_CLOSE:
1caab0 ¤   case IRP_MJ_CREATE:
058b2b ¤   case IRP_MJ_FLUSH_BUFFERS:
cd7a36 ¤   case IRP_MJ_SHUTDOWN:
39af5a
65dc03 ¤   ¤   DebugOut("PGPdisk: Acknowledging an %s\n",·
99a632 ¤   ¤   ¤   GetIRPMajorFunctionName(I.MajorFunction()));
f1af5a
989610 ¤   ¤   status = STATUS_SUCCESS;
482f68 ¤   ¤   break;
74af5a
fab55e ¤   case IRP_MJ_READ:
345fea ¤   case IRP_MJ_WRITE:
368ad2 ¤   case IRP_MJ_CLEANUP:
9bd573 ¤   case IRP_MJ_DEVICE_CONTROL:
6faf5a
cd17e8 ¤   ¤   DebugOut("PGPdisk: Scheduling an %s\n",·
52a632 ¤   ¤   ¤   GetIRPMajorFunctionName(I.MajorFunction()));
40af5a
09e576 ¤   ¤   // Reset inactivity timer on reads/writes.
bef8aa ¤   ¤   if ((I.MajorFunction() == IRP_MJ_READ) ||·
c0ce74 ¤   ¤   ¤   (I.MajorFunction() == IRP_MJ_WRITE))
185b34 ¤   ¤   {
5db692 ¤   ¤   ¤   Interface->mSecondsInactive = 0;
470fe4 ¤   ¤   }
01af5a
d321bb ¤   ¤   // Queue the IRP to the thread.
05a7b8 ¤   ¤   derr = pPGD->GetThread()->QueueIrpForProcessing(I);
a6af5a
97aa35 ¤   ¤   if (derr.IsntError())
f55b34 ¤   ¤   {
910b26 ¤   ¤   ¤   // If succeeded, report pending.
2ccd73 ¤   ¤   ¤   status = STATUS_PENDING;
150fe4 ¤   ¤   }
640e1d ¤   ¤   else
885b34 ¤   ¤   {
def850 ¤   ¤   ¤   // If failed, report error.
7bad85 ¤   ¤   ¤   status = STATUS_INSUFFICIENT_RESOURCES;
550fe4 ¤   ¤   }
862f68 ¤   ¤   break;
98af5a
202f72 ¤   default:
286c95 ¤   ¤   DebugOut("\nPGPdisk: Rejecting a %s\n",·
57a632 ¤   ¤   ¤   GetIRPMajorFunctionName(I.MajorFunction()));
8faf5a
0d2f68 ¤   ¤   break;
cb9371 ¤   }
3caf5a
d752e2 ¤   // Complete if not pending.
c1f4c6 ¤   if (status != STATUS_PENDING)
6ac7a1 ¤   {
--39d8 0015d3420c6401100e4 Page 4 of CPGPdiskDriver.cpp
301d26 ¤   ¤   I.Information() = 0;
5f44c0 ¤   ¤   I.Complete(status);
dcaf5a
7a8db0 ¤   ¤   (* irpNeedsCompletion) = FALSE;
ea9371 ¤   }
1baf5a
0e01b5 ¤   return status;
8eefe6 }
8daf5a
33af26 // DispatchFilter is called so we can route IRPs correctly.
03af5a
9d0e00 NTSTATUS·
66946e CPGPdiskDriver::DispatchFilter(
df4f1c ¤   KDevice¤¤   ¤   ¤   ¤   *pDevice,·
10af09 ¤   KIrp¤   ¤   ¤   ¤   ¤   I,·
eb917a ¤   NTSTATUS(KDevice::*func)(KIrp))
d1bb36 {
fa1c6c ¤   NTSTATUS¤   ¤   status¤ ¤   ¤   ¤   = STATUS_SUCCESS;
605710 ¤   PDEVICE_OBJECT¤ pDevObj;
e42f74 ¤   PGPBoolean¤ ¤   irpNeedsCompletion¤ = TRUE;
f0af5a
826bac ¤   __try
bbc7a1 ¤   {
91aa94 ¤   ¤   pDevObj = I.DeviceObject();
90d307 ¤   ¤   pgpAssertAddrValid(pDevObj, DEVICE_OBJECT);
7aaf5a
e660c1 ¤   ¤   // PGPdisk device objects are dispatched separately from class
0fb338 ¤   ¤   // KDevice device objects. This routine assumes all the
bc4218 ¤   ¤   // FILE_VIRTUAL_VOLUME type objects created in this driver will be
edc757 ¤   ¤   // PGPdisks only.
43af5a
3f6616 ¤   ¤   if (pDevObj->Characteristics & FILE_VIRTUAL_VOLUME)
545b34 ¤   ¤   {
0b5f34 ¤   ¤   ¤   if (IsntNull(pDevice))
49f776 ¤   ¤   ¤   {
922722 ¤   ¤   ¤   ¤   status = DispatchPGPdiskRequest(I, (PGPdisk *) pDevice,·
233d08 ¤   ¤   ¤   ¤   ¤   &irpNeedsCompletion);
0ba3a6 ¤   ¤   ¤   }
06bb8c ¤   ¤   ¤   else
17f776 ¤   ¤   ¤   {
69fe5c ¤   ¤   ¤   ¤   status = STATUS_VOLUME_DISMOUNTED;
24a3a6 ¤   ¤   ¤   }
810fe4 ¤   ¤   }
b40e1d ¤   ¤   else
f65b34 ¤   ¤   {
291a39 ¤   ¤   ¤   status = (pDevice->*func)(I);
170fe4 ¤   ¤   }
099371 ¤   }
5cbc2f ¤   __except(EXCEPTION_EXECUTE_HANDLER)·
3ec7a1 ¤   {
4a8775 ¤   ¤   Interface->ReportError(kPGDMajorError_KModeExceptionOccured);
11af5a
204901 ¤   ¤   // We don't exit with uncompleted IRPs.
912198 ¤   ¤   if (irpNeedsCompletion)
accfe9 ¤   ¤   ¤   status = I.Complete(STATUS_DEVICE_DATA_ERROR);
a59371 ¤   }
b6af5a
8801b5 ¤   return status;
5defe6 }
--7de4 00142dddd5a401100e5 Page 1 of CPGPdiskDriver.h
541bc3 //////////////////////////////////////////////////////////////////////////////
dd8a05 // CPGPdiskDriver.h
ac465d //
2a7c2d // Declaration of class CPGPdiskDriver.
d21bc3 //////////////////////////////////////////////////////////////////////////////
e5af5a
c32ac5 // $Id: CPGPdiskDriver.h,v 1.1.2.10 1998/07/06 08:57:39 nryan Exp $
a0af5a
6ccbce // Copyright (C) 1998 by Network Associates, Inc.
c471ae // All rights reserved.
d3af5a
e279c8 #ifndef Included_CPGPdiskDriver_h¤  // [
fa3d99 #define Included_CPGPdiskDriver_h
8baf5a
d93a85 #include "DualErr.h"
4caf5a
51af5a
4d09b7 ////////////
3be738 // Constants
3f09b7 ////////////
47af5a
5ff0e4 const PGPUInt32 kPGPdiskMemPoolTag = 'dPGP';
7aaf5a
a7af5a
cbd557 ////////
9b02c9 // Types
1bd557 ////////
c9af5a
7f9e57 class PGPdisk;
e2af5a
35af5a
926557 ///////////////////////
d827e6 // Class CPGPdiskDriver
466557 ///////////////////////
2ae8c6 ···
34109b class CPGPdiskDriver : public KDriver
83bb36 {
085ed4 public:
fa1603 ¤   DualErr mInitErr;
41af5a
6ef2e1 ¤   virtual NTSTATUS¤   DriverEntry(PUNICODE_STRING RegistryPath);
0a5c6d ¤   virtual VOID¤   ¤   Unload();
c2af5a
487803 ¤   NTSTATUS¤   ¤   ¤   DispatchFilter(KDevice *pDevice, KIrp I,·
939739 ¤   ¤   ¤   ¤   ¤   ¤   ¤   NTSTATUS(KDevice::*func)(KIrp));
feaf5a
0f0fb9 private:
bbc325 ¤   SAFE_DESTRUCTORS
edaf5a
b34294 ¤   NTSTATUS DispatchPGPdiskRequest(KIrp I, PGPdisk *pPGD,·
75a5f4 ¤   ¤   ¤   ¤   PGPBoolean *irpNeedsCompletion);
7782f7 };
37af5a
42dc1a #endif // Included_CPGPdiskDriver_h
--d70d 000ce631469401100e6 Page 1 of CPGPdiskInterface.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
ce6820 // CPGPdiskInterface.cpp
c9465d //
8e18d4 // Definition of class CPGPdiskInterface.
ae1bc3 //////////////////////////////////////////////////////////////////////////////
3faf5a
6ad7bb // $Id: CPGPdiskInterface.cpp,v 1.1.2.28 1998/07/30 18:23:22 nryan Exp $
2faf5a
dccbce // Copyright (C) 1998 by Network Associates, Inc.
8471ae // All rights reserved.
d2af5a
c0d7a1 #include <vdw.h>
eeaf5a
989bcf #include "Required.h"
5a0092 #include "Packets.h"
7aaf5a
b59281 #include "CPGPdiskDriver.h"
bae0ee #include "CPGPdiskInterface.h"
13f037 #include "File.h"
b1c411 #include "Globals.h"
67af5a
4faf5a
3c09b7 ////////////
04e738 // Constants
6a09b7 ////////////
68af5a
1642a6 const PGPUInt32¤kContextToggleSeconds¤  = 5;
076624 const PGPUInt32¤kContextVerifySeconds¤  = 5;
9aaf5a
31af5a
94bbb5 ///////////////////////////////////////////////////////////////
946d5c // Class CPGPdiskInterface initialization and cleanup functions
51bbb5 ///////////////////////////////////////////////////////////////
68af5a
c9687f // The CPGPdiskInterface constructor creates a 'device object' named PGPdisk.
449c3d // The app communicates with the driver using this object.
9faf5a
5becf8 CPGPdiskInterface::CPGPdiskInterface(CPGPdiskDriver *pDriver)
fbcb8e ¤   : KDevice(L"PGPdisk", FILE_DEVICE_UNKNOWN, L"PGPdisk", 0, DO_DIRECT_IO)
58af5a
30bb36 {
0ced4f ¤   NTSTATUS status;
9faf5a
cfabcb ¤   pgpAssertAddrValid(pDriver, CPGPdiskDriver);
10af5a
a5f15d ¤   mSecondsInactive = 0;
24af5a
4b4713 ¤   mPGPdiskDriver = pDriver;
6caf5a
33f8a4 ¤   mTimerStarted¤  = FALSE;
254cde ¤   mUnmountAllMode¤= FALSE;
f2af5a
ef79d8 ¤   mAutoUnmount¤   = kDefaultAutoUnmount;
2c7e3f ¤   mUnmountTimeout¤= kDefaultUnmountTimeout;
5eaf5a
8aaa22 ¤   mKeyboardFilter = NULL;
5b9bfd ¤   mMouseFilter = NULL;
beaf5a
89efeb ¤   mCreatedKeyboardFilter¤ = FALSE;
89ec01 ¤   mCreatedMouseFilter¤¤   = FALSE;
d8af5a
45812c ¤   if (!NT_SUCCESS(m_ConstructorStatus))
80c7a1 ¤   {
a49437 ¤   ¤   mInitErr = DualErr(kPGDMinorError_DeviceConstructFailed,·
0b8b96 ¤   ¤   ¤   m_ConstructorStatus);
479371 ¤   }
94af5a
b69c32 ¤   if (mInitErr.IsntError())
acc7a1 ¤   {
e2dfe8 ¤   ¤   mInitErr = mUserMemManager.mInitErr;
029371 ¤   }
ceaf5a
--db31 000478e90fb401100e6 Page 2 of CPGPdiskInterface.cpp
03a692 ¤   // Start our utility thread.
7a9c32 ¤   if (mInitErr.IsntError())
a3c7a1 ¤   {
b9b4cc ¤   ¤   mInitErr = mUtilityThread.StartThread();
e09371 ¤   }
05af5a
eeda3e ¤   // Setup our system hooks.
789c32 ¤   if (mInitErr.IsntError())
dac7a1 ¤   {
c65efd ¤   ¤   mInitErr = SetupSystemHooks();
c19371 ¤   }
71af5a
ae04b1 ¤   // Start our one-second timer.
499c32 ¤   if (mInitErr.IsntError())
37c7a1 ¤   {
ed508d ¤   ¤   status = IoInitializeTimer(m_pDeviceObject, EverySecondCallback,·
1c0084 ¤   ¤   ¤   NULL);
ffaf5a
a26412 ¤   ¤   if (!NT_SUCCESS(status))
e25b34 ¤   ¤   {
a1e3fd ¤   ¤   ¤   mInitErr = DualErr(kPGDMinorError_IoInitializeTimerFailed,·
db233b ¤   ¤   ¤   ¤   status);
4a0fe4 ¤   ¤   }
7d9371 ¤   }
6baf5a
729c32 ¤   if (mInitErr.IsntError())
65c7a1 ¤   {
edc391 ¤   ¤   IoRegisterShutdownNotification(m_pDeviceObject);
deaf5a
79bdf1 ¤   ¤   IoStartTimer(m_pDeviceObject);
78d7f6 ¤   ¤   mTimerStarted = TRUE;
1b9371 ¤   }
26efe6 }
03af5a
d9b3f3 // The CPGPdiskInterface destructor.
e4af5a
0c621e CPGPdiskInterface::~CPGPdiskInterface()
3cbb36 {
d0b298 ¤   if (mTimerStarted)
660e9a ¤   ¤   IoStopTimer(m_pDeviceObject);
8baf5a
599c94 ¤   DeleteSystemHooks();
05efe6 }
d7af5a
93af5a
c53e71 /////////////////////////////////////
222317 // Miscellaneous dispatcher functions
313e71 /////////////////////////////////////
deaf5a
502ad6 // CleanUp is called to cancel all pending IRPs targeted to the same file
203011 // object as the given IRP.
20af5a
2a0e00 NTSTATUS·
8d122d CPGPdiskInterface::CleanUp(KIrp I)
b9bb36 {
6ff158 ¤   return I.Complete(STATUS_SUCCESS);
b6efe6 }
0faf5a
559032 // Close is called when a handle is closed to the driver.
95af5a
320e00 NTSTATUS·
0d9099 CPGPdiskInterface::Close(KIrp I)
7bbb36 {
31f158 ¤   return I.Complete(STATUS_SUCCESS);
61efe6 }
15af5a
205b67 // Create is called when a handle is opened to the driver.
0daf5a
4a0e00 NTSTATUS·
d95d68 CPGPdiskInterface::Create(KIrp I)
84bb36 {
47f158 ¤   return I.Complete(STATUS_SUCCESS);
--c9b6 000bf4abbb4401100e6 Page 3 of CPGPdiskInterface.cpp
7aefe6 }
46af5a
4146a6 // Read is not implemented by CPGPdiskInterface.
1caf5a
710e00 NTSTATUS·
22fc4f CPGPdiskInterface::Read(KIrp I)
70bb36 {
28297b ¤   I.Information() = 0;
1c07b7 ¤   return I.Complete(STATUS_NOT_IMPLEMENTED);
cdefe6 }
2aaf5a
b30f98 // Write is not implemented by CPGPdiskInterface.
d1af5a
aa0e00 NTSTATUS·
bc788a CPGPdiskInterface::Write(KIrp I)
cfbb36 {
c1297b ¤   I.Information() = 0;
d307b7 ¤   return I.Complete(STATUS_NOT_IMPLEMENTED);
bfefe6 }
34af5a
54af5a
f79f73 /////////////////////////
22e01a // Miscellaneous routines
e79f73 /////////////////////////
57af5a
38f4a0 // EverySecondCallback schedules EverySecondCallbackAux for callback at a
f26fce // safe time.
4caf5a
b3a1ba VOID·
610dbe CPGPdiskInterface::EverySecondCallback(
d6dcbe ¤   PDEVICE_OBJECT¤ DeviceObject,·
8f57e6 ¤   PVOID¤  ¤   ¤   Context)
bdbb36 {
f203f1 ¤   // Call at a safe time in our utility thread.
6f168f ¤   Interface->mUtilityThread.ScheduleAsyncCallback(EverySecondCallbackAux);
78efe6 }
7faf5a
59a6a1 // EverySecondCallbackAux is called once per second so we can perform various
d6374d // time-related tasks.
d2af5a
b7c823 void·
01da3f CPGPdiskInterface::EverySecondCallbackAux(PGPUInt32 refData)
74bb36 {
ed51fe ¤   static PGPUInt32¤   lastToggleTime¤ = 0;
a52a1c ¤   static PGPUInt32¤   lastVerifyTime¤ = 0;
c4af5a
9d23d6 ¤   // Increase the inactivity timer.
edb22c ¤   Interface->mSecondsInactive++;
b4af5a
2d0809 ¤   // If we are in 'unmount all mode', keep trying to unmount all until we
ba4bf0 ¤   // succeed.
53af5a
f6ad10 ¤   if (Interface->mUnmountAllMode)
acc7a1 ¤   {
7b47ac ¤   ¤   DualErr derr;
06af5a
a3e2c9 ¤   ¤   derr = Interface->UnmountAllPGPdisks();
9825cd ¤   ¤   Interface->mUnmountAllMode = !derr.IsntError();
5c9371 ¤   }
0aaf5a
259462 ¤   // Flip contexts on all PGPdisks if this is the time to do so.
9e2c2d ¤   if (lastToggleTime++ > kContextToggleSeconds)
80c7a1 ¤   {
3fdc4b ¤   ¤   lastToggleTime = 0;
4984e2 ¤   ¤   Interface->mPGPdisks.FlipAllContexts();
fb9371 ¤   }
18af5a
9ceb9f ¤   // Verify cipher contexts on all PGPdisks if this is the time to do so.
9df23c ¤   if (lastVerifyTime++ > kContextVerifySeconds)
1ac7a1 ¤   {
c9f9b3 ¤   ¤   lastVerifyTime = 0;
bfe7d7 ¤   ¤   Interface->mPGPdisks.ValidateAllCipherContexts();
--f9ba 001e665e75f401100e6 Page 4 of CPGPdiskInterface.cpp
a19371 ¤   }
93af5a
eb076a ¤   // If it is time to auto-unmount, we do so. We schedule the unmounts to
6b3c2a ¤   // occur during an appy-time callback.
45af5a
e51a21 ¤   if ((Interface->mAutoUnmount) &&·
2bb17b ¤   ¤   (Interface->mSecondsInactive > Interface->mUnmountTimeout*60))
cdc7a1 ¤   {
deb02a ¤   ¤   Interface->mSecondsInactive = 0;
373dce ¤   ¤   Interface->UnmountAllPGPdisks();
0d9371 ¤   }
e6efe6 }
--7466 000cbf95aa3401100e7 Page 1 of CPGPdiskInterface.h
541bc3 //////////////////////////////////////////////////////////////////////////////
6006a8 // CPGPdiskInterface.h
b2465d //
d5fb5a // Declaration of class CPGPdiskInterface.
891bc3 //////////////////////////////////////////////////////////////////////////////
58af5a
a73dd5 // $Id: CPGPdiskInterface.h,v 1.1.2.32 1998/07/06 08:57:40 nryan Exp $
b5af5a
69e1c4 #ifndef Included_CPGPdiskInterface_h¤   // [
f0463a #define Included_CPGPdiskInterface_h
0daf5a
843a85 #include "DualErr.h"
720092 #include "Packets.h"
0a5f98 #include "PGPdiskContainer.h"
56af5a
6c9281 #include "CPGPdiskDriver.h"
45e834 #include "CPGPdiskInterfaceHooks.h"
d24ead #include "LookasideList.h"
629abc #include "UserMemoryManager.h"
b5af5a
8aaf5a
80d557 ////////
0902c9 // Types
3ad557 ////////
65af5a
c64188 class PGPdiskWorkerThread;
79af5a
b4af5a
78b352 //////////////////////////
c4c736 // Class CPGPdiskInterface
11b352 //////////////////////////
b1af5a
902a49 class CPGPdiskInterface : public KDevice
51bb36 {
c25ed4 public:
4cfb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
74af5a
c65ce7 ¤   PGPUInt32¤  ¤   ¤   mPGPdiskAppVersion;¤¤   // application version
a89fcc ¤   PGPUInt32¤  ¤   ¤   mSecondsInactive;¤  ¤   // seconds user inactive
55af5a
f9d71a ¤   CPGPdiskDriver¤ ¤   *mPGPdiskDriver;¤   ¤   // pointer to driver
58a55a ¤   PGPUInt32¤  ¤   ¤   mCallerProcId;¤ ¤   ¤   // caller process ID
b6af5a
7d08c4 ¤   PGPdiskContainer¤   mPGPdisks;¤ ¤   ¤   ¤   // holds PGPdisk objects
12af5a
edc2ac ¤   // From CPGPdiskInterface.cpp
6faf5a
49464f ¤   CPGPdiskInterface(CPGPdiskDriver *pDriver);
2cb595 ¤   ~CPGPdiskInterface();
6baf5a
4e4116 ¤   DEVMEMBER_DISPATCHERS
86af5a
886a80 ¤   // From CPGPdiskInterfaceErrors.cpp
d7af5a
05a17a ¤   void¤   ReportError(PGDMajorError perr, DualErr derr = DualErr::NoError,·
057b30 ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive);
e1af5a
a813d6 ¤   // From CPGPdiskInterfaceVolumes.cpp
48af5a
87ce1a ¤   DualErr¤¤   MountPGPdisk(LPCSTR path, CipherContext *pContext,·
2c87af ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive, PGPBoolean mountReadOnly);
db0768 ¤   DualErr¤¤   UnmountPGPdisk(PGPUInt8 drive,·
7db9fd ¤   ¤   ¤   ¤   ¤   PGPBoolean isThisEmergency = FALSE);
2708c1 ¤   DualErr¤¤   UnmountAllPGPdisks(PGPBoolean isThisEmergency = FALSE);
95af5a
970fb9 private:
50bfce ¤   PGPBoolean¤ ¤   ¤   ¤   mTimerStarted;¤ ¤   // unmount timer started?
37ad03 ¤   PGPBoolean¤ ¤   ¤   ¤   mUnmountAllMode;¤   // unmount all per sec
d7af5a
d2a5fb ¤   PGPBoolean¤ ¤   ¤   ¤   mAutoUnmount;¤  ¤   // auto-unmount enabled?
983ed9 ¤   PGPUInt32¤  ¤   ¤   ¤   mUnmountTimeout;¤   // unmount timeout in mins
cbaf5a
--ba31 00030579553401100e7 Page 2 of CPGPdiskInterface.h
cef7cb ¤   KeyboardFilterDevice¤   *mKeyboardFilter;¤  // mouse interceptor
602f31 ¤   MouseFilterDevice¤  ¤   *mMouseFilter;¤ ¤   // keyboard interceptor
01af5a
19028a ¤   PGPBoolean¤ ¤   ¤   ¤   mCreatedKeyboardFilter;¤// made mouse filter?
b9322d ¤   PGPBoolean¤ ¤   ¤   ¤   mCreatedMouseFilter;¤   // made keyboard filter?
6baf5a
ff2245 ¤   PGPdiskWorkerThread¤¤   mUtilityThread;¤¤   // thread for mounts/unmounts
7ef9be ¤   UserMemoryManager¤  ¤   mUserMemManager;¤   // manages user memory
9caf5a
14c325 ¤   SAFE_DESTRUCTORS
f3af5a
6ec2ac ¤   // From CPGPdiskInterface.cpp
90af5a
c712e2 ¤   static VOID¤EverySecondCallback(PDEVICE_OBJECT DeviceObject,·
45059d ¤   ¤   ¤   ¤   ¤   PVOID Context);
a00490 ¤   static void¤EverySecondCallbackAux(PGPUInt32 refData);
8faf5a
956fc6 ¤   // From CPGPdiskInterfaceComm.cpp
4eaf5a
ba35f7 ¤   static void¤ProcessMountCallback(PGPUInt32 refData);
3df18a ¤   DualErr¤¤   ProcessMount(PAD_Mount pMNT,·
20ae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
f3af5a
45c730 ¤   static void¤ProcessUnmountCallback(PGPUInt32 refData);
7528fa ¤   DualErr¤¤   ProcessUnmount(PAD_Unmount pUNMNT,·
efae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
eaaf5a
02088a ¤   DualErr¤¤   ProcessQueryVersion(PAD_QueryVersion pQV,·
85ae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
aaaf5a
27bb93 ¤   DualErr¤¤   ProcessQueryMounted(PAD_QueryMounted pQM,·
7bae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
75af5a
d89ab5 ¤   static void¤ProcessQueryOpenFilesCallback(PGPUInt32 refData);
38af5a
df1fdf ¤   DualErr¤¤   ProcessQueryOpenFiles(PAD_QueryOpenFiles pQOF,·
d6ae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
02af5a
e5a8a1 ¤   DualErr¤¤   ProcessChangePrefs(PAD_ChangePrefs pCP,·
a7ae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
e4af5a
c4860e ¤   DualErr¤¤   ProcessLockUnlockMem(PAD_LockUnlockMem pLUM,·
faae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
08af5a
84faed ¤   DualErr¤¤   ProcessGetPGPdiskInfo(PAD_GetPGPdiskInfo pGPI,·
74ae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
8daf5a
54a2c3 ¤   static void¤ProcessLockUnlockVolCallback(PGPUInt32 refData);
6255dd ¤   DualErr¤¤   ProcessLockUnlockVol(PAD_LockUnlockVol pLUV,·
baae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
85af5a
d5e19d ¤   static void¤ProcessReadWriteVolCallback(PGPUInt32 refData);
fad5cf ¤   DualErr¤¤   ProcessReadWriteVol(PAD_ReadWriteVol pRWV,·
3fae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
03af5a
1e839e ¤   static void¤ProcessQueryVolInfoCallback(PGPUInt32 refData);
13ae11 ¤   DualErr¤¤   ProcessQueryVolInfo(PAD_QueryVolInfo pQVI,·
47ae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
0aaf5a
88ba8f ¤   DualErr¤¤   ProcessNotifyUserLogoff(PAD_NotifyUserLogoff pNUL,·
8eae0e ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
28af5a
7d0b6c ¤   NTSTATUS¤   ProcessADPacket(PADPacketHeader pPacket, PGPUInt32 size);
3baf5a
f06a80 ¤   // From CPGPdiskInterfaceErrors.cpp
92af5a
16de93 ¤   PGPBoolean¤ DoesDriverErrTakeDriveLetter(PGDMajorError perr);
1db7da ¤   LPCWSTR¤¤   GetErrorString(PGDMajorError perr);
8eaf5a
5c61dd ¤   // From CPGPdiskInterfaceHooks.cpp
79af5a
30073c ¤   DualErr¤¤   SetupSystemHooks();
--776b 0018f29f027401100e7 Page 3 of CPGPdiskInterface.h
031933 ¤   void¤   ¤   DeleteSystemHooks();
05af5a
2b82f7 };
85af5a
8f55f3 #endif // Included_CPGPdiskInterface_h
--9553 0000abdbd82401100e8 Page 1 of CPGPdiskInterfaceComm.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
c9a931 // CPGPdiskInterfaceComm.cpp
e6465d //
e69634 // Functions for driver/application communication.
2e1bc3 //////////////////////////////////////////////////////////////////////////////
45af5a
958075 // $Id: CPGPdiskInterfaceComm.cpp,v 1.1.2.30 1998/07/06 08:57:42 nryan Exp $
7aaf5a
80cbce // Copyright (C) 1998 by Network Associates, Inc.
f471ae // All rights reserved.
edaf5a
9cd7a1 #include <vdw.h>
1faf5a
409bcf #include "Required.h"
be0092 #include "Packets.h"
ea5788 #include "PGPdiskVersion.h"
fbbfe9 #include "UtilityFunctions.h"
5faf5a
dce0ee #include "CPGPdiskInterface.h"
b54edd #include "CPGPdiskInterfaceComm.h"
fbc411 #include "Globals.h"
28f1f6 #include "KernelModeUtils.h"
fb8869 #include "NtThreadSecurity.h"
c468c6 #include "PGPdisk.h"
29af5a
1baf5a
33b474 //////////////////////////////
a9e95e // Packet processing functions
3fb474 //////////////////////////////
c3af5a
86852e // ProcessMountCallback mounts a PGPdisk in the context of our utility
1453e2 // thread.
86af5a
fec823 void·
cf4faa CPGPdiskInterface::ProcessMountCallback(PGPUInt32 refData)
f6bb36 {
28be41 ¤   DualErr¤¤   derr;
41a295 ¤   HANDLE¤ ¤   token;
dfcde6 ¤   PAD_Mount¤  pMNT;
4eaf5a
a098a4 ¤   pMNT = (PAD_Mount) refData;
25bccc ¤   pgpAssertAddrValid(pMNT, AD_Mount);
6caf5a
1e8a09 ¤   // Make copy of security token of calling process.
7b0cd5 ¤   if (!IsImpersonationTokenSet())
5332b8 ¤   ¤   derr = SetImpersonationToken(Interface->mCallerProcId);
4faf5a
c32361 ¤   if (derr.IsntError())
38c7a1 ¤   {
216986 ¤   ¤   // Mount the PGPdisk.
a26f3c ¤   ¤   derr = Interface->MountPGPdisk(pMNT->path, pMNT->pContext,·
c40bee ¤   ¤   ¤   pMNT->drive, pMNT->readOnly);
fb9371 ¤   }
a8af5a
584164 ¤   (* pMNT->header.pDerr) = derr;
52efe6 }
86af5a
10aaae // ProcessMount processes a kAD_Mount request.
3aaf5a
382292 DualErr·
c6c28b CPGPdiskInterface::ProcessMount(PAD_Mount pMNT, PGPUInt32 size)
0bbb36 {
99be41 ¤   DualErr¤¤   derr;
64cf4a ¤   PGPBoolean¤ mappedContext, mappedPath, mappedOutDrive;
7caf5a
d4918e ¤   mappedContext = mappedPath = mappedOutDrive = FALSE;
01af5a
f4b533 ¤   // Check packet size.
88829e ¤   if (size < sizeof(AD_Mount))
ead287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
3caf5a
0a581f ¤   // Check desired drive letter.
--872b 0005c5f2126401100e8 Page 2 of CPGPdiskInterfaceComm.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
1193a1 ¤   ¤   if (!IsLegalDriveNumber(pMNT->drive))
acf432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
a39371 ¤   }
09af5a
959ad6 ¤   // Map embedded pointers.
772361 ¤   if (derr.IsntError())
25c7a1 ¤   {
3c7812 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pMNT->pContext,·
5baa28 ¤   ¤   ¤   sizeof(CipherContext));
8faf5a
430260 ¤   ¤   mappedContext = derr.IsntError();
a29371 ¤   }
9daf5a
422361 ¤   if (derr.IsntError())
14c7a1 ¤   {
a99df4 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pMNT->path,·
e8b378 ¤   ¤   ¤   pMNT->sizePath);
35af5a
3eaf5e ¤   ¤   mappedPath = derr.IsntError();
469371 ¤   }
d1af5a
7d2361 ¤   if (derr.IsntError())
96c7a1 ¤   {
59dc69 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pMNT->pDrive,·
eba9a5 ¤   ¤   ¤   sizeof(PGPUInt8));
d7af5a
4b0372 ¤   ¤   mappedOutDrive = derr.IsntError();
159371 ¤   }
74af5a
a81aec ¤   // Perform the mount.
b52361 ¤   if (derr.IsntError())
66c7a1 ¤   {
e255e6 ¤   ¤   // Save process ID of current process.
e28d85 ¤   ¤   mCallerProcId = (PGPUInt32) PsGetCurrentProcessId();
33af5a
7a93b8 ¤   ¤   // Perform the mount.
4da7ef ¤   ¤   derr = mUtilityThread.ScheduleSyncCallback(ProcessMountCallback,·
d4a5cb ¤   ¤   ¤   (PGPUInt32) pMNT);
209371 ¤   }
f4af5a
df2361 ¤   if (derr.IsntError())
d6c7a1 ¤   {
169bcc ¤   ¤   derr = (* pMNT->header.pDerr);
f69371 ¤   }
a1af5a
fac1db ¤   // Find the drive of the mounted PGPdisk.
772361 ¤   if (derr.IsntError())
69c7a1 ¤   {
92171d ¤   ¤   PGPdisk *pPGD = mPGPdisks.FindPGPdisk(pMNT->path);
0eaf5a
ad55cb ¤   ¤   pgpAssertAddrValid(pPGD, PGPdisk);
a83101 ¤   ¤   (* pMNT->pDrive) = pPGD->GetDrive();
cf9371 ¤   }
9baf5a
d5b6dd ¤   // Unmap embedded pointers.
fda45d ¤   if (mappedOutDrive)
26c7a1 ¤   {
f7bd49 ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pMNT->pDrive,·
d7a9a5 ¤   ¤   ¤   sizeof(PGPUInt8));
ab9371 ¤   }
d6af5a
1e5f54 ¤   if (mappedPath)
05c7a1 ¤   {
fa64b3 ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pMNT->path,·
fab378 ¤   ¤   ¤   pMNT->sizePath);
fb9371 ¤   }
6467c5 ¤
7feb10 ¤   if (mappedContext)
2cc7a1 ¤   {
5c29ae ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pMNT->pContext,·
--076f 000124759ae401100e8 Page 3 of CPGPdiskInterfaceComm.cpp
43aa28 ¤   ¤   ¤   sizeof(CipherContext));
fb9371 ¤   }
ecaf5a
a033e3 ¤   return derr;
d0efe6 }
11af5a
d9af5a
509915 // ProcessUnmountCallback unmounts a PGPdisk in the context of our utility
7653e2 // thread.
2aaf5a
39c823 void·
685eaa CPGPdiskInterface::ProcessUnmountCallback(PGPUInt32 refData)
f3bb36 {
21be41 ¤   DualErr¤¤   derr;
4ef420 ¤   PAD_Unmount¤pUNMNT;
fdaf5a
a004e5 ¤   pUNMNT = (PAD_Unmount) refData;
5cde3b ¤   pgpAssertAddrValid(pUNMNT, AD_Unmount);
d5af5a
bde459 ¤   derr = Interface->UnmountPGPdisk(pUNMNT->drive, pUNMNT->isThisEmergency);
81af5a
b5b3e7 ¤   (* pUNMNT->header.pDerr) = derr;
6defe6 }
9faf5a
ddd7a7 // ProcessUnmount processes a kAD_Unmount request.
c0af5a
2e2292 DualErr·
24d12c CPGPdiskInterface::ProcessUnmount(PAD_Unmount pUNMNT, PGPUInt32 size)
6bbb36 {
de7d36 ¤   DualErr derr;
adaf5a
f4b533 ¤   // Check packet size.
1027a2 ¤   if (size < sizeof(AD_Unmount))
8ad287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
31af5a
bcf283 ¤   // Check drive letter.
fc2361 ¤   if (derr.IsntError())
09c7a1 ¤   {
c82dda ¤   ¤   if (!IsLegalDriveNumber(pUNMNT->drive))
7ef432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
919371 ¤   }
94af5a
cc0a44 ¤   // Perform the unmount.
8c2361 ¤   if (derr.IsntError())
11c7a1 ¤   {
c56e46 ¤   ¤   derr = mUtilityThread.ScheduleSyncCallback(ProcessUnmountCallback,·
7966df ¤   ¤   ¤   (PGPUInt32) pUNMNT);
a09371 ¤   }
47af5a
c12361 ¤   if (derr.IsntError())
b3c7a1 ¤   {
21e58e ¤   ¤   derr = (* pUNMNT->header.pDerr);
0b9371 ¤   }
70af5a
d433e3 ¤   return derr;
daefe6 }
33af5a
36102d // ProcessQueryVersion processes a kAD_QueryVersion request.
6faf5a
022292 DualErr·
3f1cd4 CPGPdiskInterface::ProcessQueryVersion(PAD_QueryVersion pQV, PGPUInt32 size)
15bb36 {
0fbe41 ¤   DualErr¤¤   derr;
a1599a ¤   PGPBoolean¤ mappedVerBool¤  = FALSE;
81af5a
36b533 ¤   // Check packet size.
48f226 ¤   if (size < sizeof(AD_QueryVersion))
46d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
14af5a
679ad6 ¤   // Map embedded pointers.
d72361 ¤   if (derr.IsntError())
12c7a1 ¤   {
--7166 0008d3da9b6401100e8 Page 4 of CPGPdiskInterfaceComm.cpp
19c046 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pQV->pDriverVersion,·
871c8a ¤   ¤   ¤   sizeof(PGPUInt32));
f8af5a
e3fa61 ¤   ¤   mappedVerBool = derr.IsntError();
f99371 ¤   }
91af5a
d26aab ¤   // Perform the query.
162361 ¤   if (derr.IsntError())
e5c7a1 ¤   {
a640d3 ¤   ¤   mPGPdiskAppVersion = pQV->appVersion;
2fcf76 ¤   ¤   (* pQV->pDriverVersion) = kPGPdiskDriverVersion;
1b9371 ¤   }
12af5a
f3b6dd ¤   // Unmap embedded pointers.
360049 ¤   if (mappedVerBool)
60c7a1 ¤   {
3a205f ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pQV->pDriverVersion,·
f11c8a ¤   ¤   ¤   sizeof(PGPUInt32));
bd9371 ¤   }
7baf5a
7633e3 ¤   return derr;
41efe6 }
38af5a
226806 // ProcessQueryMounted processes a kAD_QueryMounted request.
40af5a
e02292 DualErr·
7ad1e0 CPGPdiskInterface::ProcessQueryMounted(PAD_QueryMounted pQM, PGPUInt32 size)
c4bb36 {
edbe41 ¤   DualErr¤¤   derr;
7db8ad ¤   PGPBoolean¤ mappedIsDiskBool, mappedPath;
7eaf5a
0d673d ¤   mappedIsDiskBool = mappedPath = FALSE;
44af5a
29b533 ¤   // Check packet size.
2c39e5 ¤   if (size < sizeof(AD_QueryMounted))
38d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
dfaf5a
db44e7 ¤   // Map embedded pointers and check parameters.
122361 ¤   if (derr.IsntError())
6bc7a1 ¤   {
4580f2 ¤   ¤   if (pQM->trueIfUsePath)
655b34 ¤   ¤   {
cf6275 ¤   ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pQM->path,·
0ea354 ¤   ¤   ¤   ¤   pQM->sizePath);
17af5a
d5a112 ¤   ¤   ¤   mappedPath = derr.IsntError();
4a0fe4 ¤   ¤   }
f38a95 ¤   ¤   else if (!IsLegalDriveNumber(pQM->drive))
7d5b34 ¤   ¤   {
b6f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
e30fe4 ¤   ¤   }
839371 ¤   }
03af5a
ec2361 ¤   if (derr.IsntError())
79c7a1 ¤   {
3cb314 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pQM->pIsPGPdisk,·
cd225e ¤   ¤   ¤   sizeof(PGPBoolean));
6eaf5a
cfbc5f ¤   ¤   mappedIsDiskBool = derr.IsntError();
2d9371 ¤   }
faaf5a
136aab ¤   // Perform the query.
782361 ¤   if (derr.IsntError())
d6c7a1 ¤   {
2f80f2 ¤   ¤   if (pQM->trueIfUsePath)
e85b34 ¤   ¤   {
2c0e24 ¤   ¤   ¤   if (IsntNull(Interface->mPGPdisks.FindPGPdisk(pQM->path)))
090447 ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = TRUE;
babb8c ¤   ¤   ¤   else
7307fc ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = FALSE;
e20fe4 ¤   ¤   }
8d0e1d ¤   ¤   else
--f0e8 000d0304429401100e8 Page 5 of CPGPdiskInterfaceComm.cpp
e35b34 ¤   ¤   {
2e8676 ¤   ¤   ¤   if (IsntNull(Interface->mPGPdisks.FindPGPdisk(pQM->drive)))
520447 ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = TRUE;
97bb8c ¤   ¤   ¤   else
b107fc ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = FALSE;
350fe4 ¤   ¤   }
839371 ¤   }
28af5a
1eb6dd ¤   // Unmap embedded pointers.
f45f54 ¤   if (mappedPath)
60c7a1 ¤   {
235f27 ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pQM->path, pQM->sizePath);
0e9371 ¤   }
52af5a
9d0e0f ¤   if (mappedIsDiskBool)
77c7a1 ¤   {
85cca2 ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pQM->pIsPGPdisk,·
ff225e ¤   ¤   ¤   sizeof(PGPBoolean));
1e9371 ¤   }
f3af5a
8933e3 ¤   return derr;
82efe6 }
daaf5a
175b3b // ProcessQueryOpenFilesCallback queries about open files on a volume in the
f33125 // context of our utility thread.
6caf5a
b6c823 void·
5e206f CPGPdiskInterface::ProcessQueryOpenFilesCallback(PGPUInt32 refData)
8dbb36 {
de705b ¤   DualErr¤¤   ¤   ¤   derr;
5d4e01 ¤   PAD_QueryOpenFiles¤ pQOF;
62689d ¤   Volume¤ ¤   ¤   ¤   vol;
dbaf5a
e84c07 ¤   pQOF = (PAD_QueryOpenFiles) refData;
6132b7 ¤   pgpAssertAddrValid(pQOF, AD_QueryOpenFiles);
9aaf5a
8cce34 ¤   derr = vol.AttachLocalVolume(pQOF->drive);
59af5a
682361 ¤   if (derr.IsntError())
83c7a1 ¤   {
9c92c0 ¤   ¤   (* pQOF->pHasOpenFiles) = vol.HasOpenFiles();
af9371 ¤   }
9caf5a
21fcf3 ¤   if (vol.AttachedToLocalVolume())
238b31 ¤   ¤   vol.DetachLocalVolume();
9caf5a
990cf4 ¤   (* pQOF->header.pDerr) = derr;
04efe6 }
a6af5a
29bc6c // ProcessQueryOpenFiles processes a kAD_QueryOpenFiles request.
95af5a
132292 DualErr·
dd724a CPGPdiskInterface::ProcessQueryOpenFiles(
173d1b ¤   PAD_QueryOpenFiles¤ pQOF,·
48cde6 ·¤  PGPUInt32¤  ¤   ¤   size)
b2bb36 {
0ebe41 ¤   DualErr¤¤   derr;
f7ffb7 ¤   PGPBoolean¤ mappedOpenBool¤ = FALSE;
20af5a
55b533 ¤   // Check packet size.
dbf822 ¤   if (size < sizeof(AD_QueryOpenFiles))
59d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
1eaf5a
469ad6 ¤   // Map embedded pointers.
4a2361 ¤   if (derr.IsntError())
bbc7a1 ¤   {
2ef736 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pQOF->pHasOpenFiles,·
f3225e ¤   ¤   ¤   sizeof(PGPBoolean));
ddaf5a
4ff300 ¤   ¤   mappedOpenBool = derr.IsntError();
509371 ¤   }
d0af5a
--4dca 000201a8a68401100e8 Page 6 of CPGPdiskInterfaceComm.cpp
2ef283 ¤   // Check drive letter.
3d2361 ¤   if (derr.IsntError())
1fc7a1 ¤   {
faad9f ¤   ¤   if (!IsLegalDriveNumber(pQOF->drive))
bbf432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
fb9371 ¤   }
e7af5a
146aab ¤   // Perform the query.
c52361 ¤   if (derr.IsntError())
b1c7a1 ¤   {
2c2adf ¤   ¤   derr = mUtilityThread.ScheduleSyncCallback(
abcdbc ¤   ¤   ¤   ProcessQueryOpenFilesCallback, (PGPUInt32) pQOF);
7b9371 ¤   }
85af5a
812361 ¤   if (derr.IsntError())
a6c7a1 ¤   {
0135d5 ¤   ¤   derr = (* pQOF->header.pDerr);
4a9371 ¤   }
e9af5a
07b6dd ¤   // Unmap embedded pointers.
28dcc2 ¤   if (mappedOpenBool)
cec7a1 ¤   {
92172f ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pQOF->pHasOpenFiles,·
de225e ¤   ¤   ¤   sizeof(PGPBoolean));
349371 ¤   }
baaf5a
b933e3 ¤   return derr;
ddefe6 }
8eaf5a
246b1a // ProcessChangePrefs processes a DA_ChangePrefs request.
f3af5a
622292 DualErr·
5e7912 CPGPdiskInterface::ProcessChangePrefs(PAD_ChangePrefs pCP, PGPUInt32 size)
c6bb36 {
367d36 ¤   DualErr derr;
53af5a
af198c ¤   File dude;
6baf5a
aa2c7c ¤   if (dude.Opened())
4a66ce ¤   ¤   dude.Close();
20af5a
93b533 ¤   // Check packet size.
e552e2 ¤   if (size < sizeof(AD_ChangePrefs))
57d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
e0af5a
1cfad4 ¤   // Check params.
802361 ¤   if (derr.IsntError())
2ec7a1 ¤   {
686947 ¤   ¤   if ((pCP->unmountTimeout == 0) ||·
feb57b ¤   ¤   ¤   (pCP->unmountTimeout > kMaxUnmountTimeout))
4f5b34 ¤   ¤   {
57f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
4e0fe4 ¤   ¤   }
969371 ¤   }
40af5a
548803 ¤   // Update preferences.
562361 ¤   if (derr.IsntError())
8ec7a1 ¤   {
c22aed ¤   ¤   mAutoUnmount = pCP->autoUnmount;
fe16ac ¤   ¤   mUnmountTimeout = pCP->unmountTimeout;
9d9371 ¤   }
b0af5a
3433e3 ¤   return derr;
6befe6 }
5eaf5a
fe73c8 // ProcessLockUnlockMem processes a DA_LockUnlockMem request.
e0af5a
ae2292 DualErr·
35d591 CPGPdiskInterface::ProcessLockUnlockMem(
eb4eba ¤   PAD_LockUnlockMem¤  pLUM,·
65cde6 ·¤  PGPUInt32¤  ¤   ¤   size)
20bb36 {
--ad78 000e6afe6d0401100e8 Page 7 of CPGPdiskInterfaceComm.cpp
507d36 ¤   DualErr derr;
c4af5a
14b533 ¤   // Check packet size.
66d406 ¤   if (size < sizeof(AD_LockUnlockMem))
40d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
f6af5a
020a3c ¤   // Lock/unlock the user memory.
9e2361 ¤   if (derr.IsntError())
94c7a1 ¤   {
a73227 ¤   ¤   if (pLUM->trueForLock)
965b34 ¤   ¤   {
d174e6 ¤   ¤   ¤   derr = Interface->mUserMemManager.LockUserMem(pLUM->pMem,·
e7e2a5 ¤   ¤   ¤   ¤   pLUM->nBytes);
0e0fe4 ¤   ¤   }
c00e1d ¤   ¤   else
cd5b34 ¤   ¤   {
ac8e46 ¤   ¤   ¤   derr = Interface->mUserMemManager.UnlockUnmapUserMem(pLUM->pMem,·
dce2a5 ¤   ¤   ¤   ¤   pLUM->nBytes);
e40fe4 ¤   ¤   }
149371 ¤   }
69af5a
d333e3 ¤   return derr;
02efe6 }
b3af5a
66ddd6 // ProcessGetPGPdiskInfo processes a kAD_GetPGPdiskInfo request.
51af5a
1e2292 DualErr·
111d69 CPGPdiskInterface::ProcessGetPGPdiskInfo(
d97ac1 ¤   PAD_GetPGPdiskInfo¤ pGPI,·
07cde6 ·¤  PGPUInt32¤  ¤   ¤   size)
6cbb36 {
17be41 ¤   DualErr¤¤   derr;
a59151 ¤   PGPBoolean¤ mappedArray¤= FALSE;
cf835f ¤   PGPUInt32¤  arraySize, i;
24af5a
6bb533 ¤   // Check packet size.
17ebd4 ¤   if (size < sizeof(AD_GetPGPdiskInfo))
f7d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
55af5a
c59ad6 ¤   // Map embedded pointers.
802361 ¤   if (derr.IsntError())
d7c7a1 ¤   {
327a43 ¤   ¤   arraySize = pGPI->arrayElems * sizeof(PGPdiskInfo);
0caf5a
7760bf ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pGPI->pPDIArray,·
ea40ab ¤   ¤   ¤   arraySize);
c0af5a
47eca0 ¤   ¤   mappedArray = derr.IsntError();
3e9371 ¤   }
e8af5a
c98cac ¤   // Fill in the array entries.
ef2361 ¤   if (derr.IsntError())
03c7a1 ¤   {
a5ef91 ¤   ¤   for (i = 0; i < pGPI->arrayElems; i++)
005b34 ¤   ¤   {
fa863c ¤   ¤   ¤   PGPdisk¤¤   *pPGD;
2f5819 ¤   ¤   ¤   PGPdiskInfo¤*pPDI;
11af5a
21e890 ¤   ¤   ¤   pPDI = &pGPI->pPDIArray[i];
dfaf5a
cd9aa5 ¤   ¤   ¤   if (IsNull(pPGD = mPGPdisks.EnumPGPdisks(i)))
daf776 ¤   ¤   ¤   {
ede23f ¤   ¤   ¤   ¤   pPDI->drive = kInvalidDrive;
a3a3a6 ¤   ¤   ¤   }
56bb8c ¤   ¤   ¤   else
d5f776 ¤   ¤   ¤   {
257ec7 ¤   ¤   ¤   ¤   pPDI->drive = pPGD->GetDrive();
2f513a ¤   ¤   ¤   ¤   pPDI->sessionId = pPGD->GetUniqueSessionId();
beaf5a
163779 ¤   ¤   ¤   ¤   strcpy(pPDI->path, pPGD->GetPath());
41a3a6 ¤   ¤   ¤   }
e60fe4 ¤   ¤   }
--45ef 000c8713451401100e8 Page 8 of CPGPdiskInterfaceComm.cpp
a19371 ¤   }
93af5a
48b6dd ¤   // Unmap embedded pointers.
049736 ¤   if (mappedArray)
6ac7a1 ¤   {
d71f09 ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pGPI->pPDIArray,·
ae40ab ¤   ¤   ¤   arraySize);
269371 ¤   }
ffaf5a
2033e3 ¤   return derr;
36efe6 }
27af5a
7fce1c // ProcessLockUnlockVolCallback locks or unlocks a volume in the context of
3931f5 // our utility thread.
8aaf5a
dec823 void·
f3b479 CPGPdiskInterface::ProcessLockUnlockVolCallback(PGPUInt32 refData)
53bb36 {
34705b ¤   DualErr¤¤   ¤   ¤   derr;
df6737 ¤   PAD_LockUnlockVol¤  pLUV;
81689d ¤   Volume¤ ¤   ¤   ¤   vol;
2aaf5a
c98fcd ¤   pLUV = (PAD_LockUnlockVol) refData;
758381 ¤   pgpAssertAddrValid(pLUV, AD_LockUnlockVol);
3eaf5a
3fc65f ¤   derr = vol.AttachLocalVolume(pLUV->drive);
0aaf5a
402361 ¤   if (derr.IsntError())
42c7a1 ¤   {
9eff39 ¤   ¤   switch (pLUV->lockOp)
9c5b34 ¤   ¤   {
0d5b9d ¤   ¤   case kLO_LockReadWrite:
7de5d9 ¤   ¤   ¤   derr = vol.LockVolumeForReadWrite();
3dcdcb ¤   ¤   ¤   break;
97af5a
f5e4fe ¤   ¤   case kLO_LockFormat:
5979f9 ¤   ¤   ¤   derr = vol.LockVolumeForFormat();
56cdcb ¤   ¤   ¤   break;
bcaf5a
616173 ¤   ¤   case kLO_UnlockReadWrite:
b2da47 ¤   ¤   case kLO_UnlockFormat:
226455 ¤   ¤   ¤   derr = vol.UnlockVolume();
75cdcb ¤   ¤   ¤   break;
82af5a
be9ae3 ¤   ¤   default:
7df432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
e5cdcb ¤   ¤   ¤   break;
9b0fe4 ¤   ¤   }
a99371 ¤   }
90af5a
3cfcf3 ¤   if (vol.AttachedToLocalVolume())
5c8b31 ¤   ¤   vol.DetachLocalVolume();
42af5a
d8ab11 ¤   (* pLUV->header.pDerr) = derr;
f8efe6 }
a9af5a
7b1014 // ProcessLockUnlockVol processes a kAD_LockUnlockVol request.
18af5a
108e09 // *************************************************************************
75e731 // NOTE: Implementation of this function is currently broken because the
ea47fd // lock goes away when 'vol' goes out of context. Will be fixed in v2.0.
bf8e09 // *************************************************************************
65af5a
3f2292 DualErr·
3fa04f CPGPdiskInterface::ProcessLockUnlockVol(
3b6987 ¤   PAD_LockUnlockVol¤  pLUV,·
082819 ¤   PGPUInt32¤  ¤   ¤   size)
55bb36 {
eb945d ¤   DualErr¤derr;
9714a5 ¤   Volume¤ vol;
78af5a
c8b533 ¤   // Check packet size.
--49c8 0002bdd9347401100e8 Page 9 of CPGPdiskInterfaceComm.cpp
7beb80 ¤   if (size < sizeof(AD_LockUnlockVol))
1ed287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
42af5a
7ef283 ¤   // Check drive letter.
952361 ¤   if (derr.IsntError())
39c7a1 ¤   {
d1a5f4 ¤   ¤   if (!IsLegalDriveNumber(pLUV->drive))
e4f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
669371 ¤   }
3caf5a
f904d2 ¤   // Fail for security reasons if volume isn't a PGPdisk.
7e2361 ¤   if (derr.IsntError())
bdc7a1 ¤   {
3e3e4d ¤   ¤   if (IsNull(mPGPdisks.FindPGPdisk(pLUV->drive)))
755cce ¤   ¤   ¤   derr = DualErr(kPGDMinorError_AccessDeniedToVolume);
dc9371 ¤   }
acaf5a
c14fb6 ¤   // Perform the lock/unlock.
ce2361 ¤   if (derr.IsntError())
54c7a1 ¤   {
c82adf ¤   ¤   derr = mUtilityThread.ScheduleSyncCallback(
03cddf ¤   ¤   ¤   ProcessLockUnlockVolCallback, (PGPUInt32) pLUV);
7a9371 ¤   }
ccaf5a
c22361 ¤   if (derr.IsntError())
d5c7a1 ¤   {
87c68a ¤   ¤   derr = (* pLUV->header.pDerr);
b79371 ¤   }
d7af5a
2533e3 ¤   return derr;
78efe6 }
c0af5a
5237c2 // ProcessReadWriteVolCallback reads from or writes to a volume in the
d03125 // context of our utility thread.
9faf5a
39c823 void·
6d1b80 CPGPdiskInterface::ProcessReadWriteVolCallback(PGPUInt32 refData)
fabb36 {
4a705b ¤   DualErr¤¤   ¤   ¤   derr;
efbf2f ¤   PAD_ReadWriteVol¤   pRWV;
db689d ¤   Volume¤ ¤   ¤   ¤   vol;
2daf5a
59e048 ¤   pRWV = (PAD_ReadWriteVol) refData;
5932b6 ¤   pgpAssertAddrValid(pRWV, AD_ReadWriteVol);
8faf5a
e1aeb2 ¤   derr = vol.AttachLocalVolume(pRWV->drive);
46af5a
5b04d2 ¤   // Fail for security reasons if volume isn't a PGPdisk.
a92361 ¤   if (derr.IsntError())
53c7a1 ¤   {
5fefe5 ¤   ¤   if (IsNull(Interface->mPGPdisks.FindPGPdisk(pRWV->drive)))
405cce ¤   ¤   ¤   derr = DualErr(kPGDMinorError_AccessDeniedToVolume);
9a9371 ¤   }
d167c5 ¤
942361 ¤   if (derr.IsntError())
dec7a1 ¤   {
436b7d ¤   ¤   if (pRWV->trueIfRead)
fb2110 ¤   ¤   ¤   derr = vol.Read(pRWV->buf, pRWV->pos, pRWV->nBlocks);
8f0e1d ¤   ¤   else
ebfaf1 ¤   ¤   ¤   derr = vol.Write(pRWV->buf, pRWV->pos, pRWV->nBlocks);
c59371 ¤   }
09af5a
28fcf3 ¤   if (vol.AttachedToLocalVolume())
2d8b31 ¤   ¤   vol.DetachLocalVolume();
3aaf5a
2852b6 ¤   (* pRWV->header.pDerr) = derr;
c7efe6 }
83af5a
65455c // ProcessReadWriteVol processes a kAD_ReadWriteVol request.
d5af5a
cf2292 DualErr·
2bcc6c CPGPdiskInterface::ProcessReadWriteVol(PAD_ReadWriteVol pRWV, PGPUInt32 size)
--d9b5 000c22efc73401100e8 Page 10 of CPGPdiskInterfaceComm.cpp
2cbb36 {
4bbe41 ¤   DualErr¤¤   derr;
594b5e ¤   PGPBoolean¤ mappedBuf¤  = FALSE;
37af5a
9fb533 ¤   // Check packet size.
583ce5 ¤   if (size < sizeof(AD_ReadWriteVol))
2ad287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
67af5a
20f283 ¤   // Check drive letter.
012361 ¤   if (derr.IsntError())
50c7a1 ¤   {
cacd19 ¤   ¤   if (!IsLegalDriveNumber(pRWV->drive))
79f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
269371 ¤   }
1eaf5a
819ad6 ¤   // Map embedded pointers.
db2361 ¤   if (derr.IsntError())
abc7a1 ¤   {
0b8b41 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pRWV->buf,·
60374e ¤   ¤   ¤   pRWV->bufSize);
abaf5a
3e8fb5 ¤   ¤   mappedBuf = derr.IsntError();
a39371 ¤   }
9baf5a
fcf3be ¤   // Perform the read/write.
212361 ¤   if (derr.IsntError())
4ec7a1 ¤   {
9f2adf ¤   ¤   derr = mUtilityThread.ScheduleSyncCallback(
bf6f1c ¤   ¤   ¤   ProcessReadWriteVolCallback, (PGPUInt32) pRWV);
419371 ¤   }
f1af5a
df2361 ¤   if (derr.IsntError())
0cc7a1 ¤   {
676cb4 ¤   ¤   derr = (* pRWV->header.pDerr);
b39371 ¤   }
72af5a
a3b6dd ¤   // Unmap embedded pointers.
bad608 ¤   if (mappedBuf)
823f28 ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pRWV->buf, pRWV->bufSize);
21af5a
7033e3 ¤   return derr;
eaefe6 }
5daf5a
5a12b6 // ProcessQueryVolInfoCallback gets info about a volume in the context of our
ba7a55 // utility thread.
88af5a
e4c823 void·
9616f1 CPGPdiskInterface::ProcessQueryVolInfoCallback(PGPUInt32 refData)
02bb36 {
63705b ¤   DualErr¤¤   ¤   ¤   derr;
2d0a94 ¤   PAD_QueryVolInfo¤   pQVI;
81689d ¤   Volume¤ ¤   ¤   ¤   vol;
92af5a
288e8b ¤   pQVI = (PAD_QueryVolInfo) refData;
6c7fb2 ¤   pgpAssertAddrValid(pQVI, AD_QueryVolInfo);
3baf5a
c14819 ¤   derr = vol.AttachLocalVolume(pQVI->drive);
26af5a
b72361 ¤   if (derr.IsntError())
49c7a1 ¤   {
a25bbf ¤   ¤   (* pQVI->pBlockSize) = vol.GetBlockSize();
3b0d49 ¤   ¤   (* pQVI->pTotalBlocks) = vol.GetTotalBlocks();
5f9371 ¤   }
97af5a
a3fcf3 ¤   if (vol.AttachedToLocalVolume())
d18b31 ¤   ¤   vol.DetachLocalVolume();
63af5a
161037 ¤   (* pQVI->header.pDerr) = derr;
9cefe6 }
87af5a
f9c00b // ProcessQueryVolInfo processes a kAD_QueryVolInfo request.
c2af5a
--3557 0008ae2882a401100e8 Page 11 of CPGPdiskInterfaceComm.cpp
782292 DualErr·
2f7f8a CPGPdiskInterface::ProcessQueryVolInfo(PAD_QueryVolInfo pQVI, PGPUInt32 size)
0abb36 {
c1be41 ¤   DualErr¤¤   derr;
d53284 ¤   PGPBoolean¤ mappedBlockSize, mappedTotalBlocks;
a1af5a
eb9e3b ¤   mappedBlockSize = mappedTotalBlocks = FALSE;
5baf5a
c6b533 ¤   // Check packet size.
011370 ¤   if (size < sizeof(AD_QueryVolInfo))
ffd287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
e7af5a
37f283 ¤   // Check drive letter.
d02361 ¤   if (derr.IsntError())
51c7a1 ¤   {
f4a700 ¤   ¤   pgpAssertAddrValid(pQVI, AD_QueryVolInfo);
36af5a
492bb2 ¤   ¤   if (!IsLegalDriveNumber(pQVI->drive))
e3f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
b19371 ¤   }
65af5a
d59ad6 ¤   // Map embedded pointers.
022361 ¤   if (derr.IsntError())
a1c7a1 ¤   {
afe5d8 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pQVI->pBlockSize,·
1b39cc ¤   ¤   ¤   sizeof(PGPUInt16));
60af5a
bd6045 ¤   ¤   mappedBlockSize = derr.IsntError();
9e9371 ¤   }
30af5a
972361 ¤   if (derr.IsntError())
c8c7a1 ¤   {
decd95 ¤   ¤   derr = mUserMemManager.MapUserMem((void **) &pQVI->pTotalBlocks,·
963395 ¤   ¤   ¤   sizeof(PGPUInt64));
35af5a
95858e ¤   ¤   mappedTotalBlocks = derr.IsntError();
219371 ¤   }
7aaf5a
b46aab ¤   // Perform the query.
702361 ¤   if (derr.IsntError())
b2c7a1 ¤   {
0d2adf ¤   ¤   derr = mUtilityThread.ScheduleSyncCallback(
807b7e ¤   ¤   ¤   ProcessQueryVolInfoCallback, (PGPUInt32) pQVI);
459371 ¤   }
31af5a
362361 ¤   if (derr.IsntError())
f2c7a1 ¤   {
1f6541 ¤   ¤   derr = (* pQVI->header.pDerr);
d89371 ¤   }
21af5a
cfb6dd ¤   // Unmap embedded pointers.
d69c98 ¤   if (mappedTotalBlocks)
2fc7a1 ¤   {
ece202 ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pQVI->pTotalBlocks,·
043395 ¤   ¤   ¤   sizeof(PGPUInt64));
869371 ¤   }
23af5a
5d654f ¤   if (mappedBlockSize)
c6c7a1 ¤   {
fd351a ¤   ¤   mUserMemManager.UnlockUnmapUserMem((void *) pQVI->pBlockSize,·
8339cc ¤   ¤   ¤   sizeof(PGPUInt16));
469371 ¤   }
51af5a
0f33e3 ¤   return derr;
dcefe6 }
54af5a
4b4225 // ProcessNotifyUserLogoff processes a kAD_NotifyUserLogoff request.
d6af5a
dee677 DualErr
9f124c CPGPdiskInterface::ProcessNotifyUserLogoff(
be6cf4 ¤   PAD_NotifyUserLogoff¤   pNUL,·
8ad5c0 ¤   PGPUInt32¤  ¤   ¤   ¤   size)
--8fe9 0006f371027401100e8 Page 12 of CPGPdiskInterfaceComm.cpp
2cbb36 {
d07d36 ¤   DualErr derr;
e5af5a
d0fa86 ¤   // Begin attempts every second to unmount all PGPdisks.
8891ac ¤   mUnmountAllMode = TRUE;
70af5a
b633e3 ¤   return derr;
b6efe6 }
0aaf5a
99bb6c // ProcessADPacket is called to process an AD (application to driver) packet.
3aaf5a
110e00 NTSTATUS·
730798 CPGPdiskInterface::ProcessADPacket(PADPacketHeader pPacket, PGPUInt32 size)
26bb36 {
1dbe41 ¤   DualErr¤¤   derr;
344efb ¤   PGPBoolean¤ mappedDerr¤ = FALSE;
68af5a
b363f0 ¤   // Validate the packet. Note that the packet has already been buffered in
6db28a ¤   // non-paged memory by the system.
53af5a
1fcc19 ¤   if (IsNull(pPacket))
50c7a1 ¤   {
e59ff6 ¤   ¤   return STATUS_INVALID_PARAMETER;
829371 ¤   }
d5fc2f ¤   if (size < sizeof(ADPacketHeader))
19c7a1 ¤   {
a69b50 ¤   ¤   return STATUS_BUFFER_TOO_SMALL;
bd9371 ¤   }
ad8cec ¤   else if (pPacket->magic != kPGPdiskADPacketMagic)
e5c7a1 ¤   {
509ff6 ¤   ¤   return STATUS_INVALID_PARAMETER;
589371 ¤   }
07af5a
dab099 ¤   DebugOut("PGPdisk: %s received\n", GetADPacketName(pPacket->code));
faaf5a
63c459 ¤   // Map embedded error pointer.
26a8ee ¤   derr = mUserMemManager.MapUserMem((void **) &pPacket->pDerr,·
2ceb27 ¤   ¤   sizeof(DualErr));
8eaf5a
b10c19 ¤   mappedDerr = derr.IsntError();
0caf5a
63abc8 ¤   // Was there an error during driver initialization?
a12361 ¤   if (derr.IsntError())
45c7a1 ¤   {
6f516c ¤   ¤   derr = mPGPdiskDriver->mInitErr;
f89371 ¤   }
ebaf5a
95cdf1 ¤   // Process the query.
9d2361 ¤   if (derr.IsntError())
a3c7a1 ¤   {
70c034 ¤   ¤   switch (pPacket->code)
cc5b34 ¤   ¤   {
b8b38e ¤   ¤   case kAD_Mount:¤¤   ¤   ¤   // mount a PGPdisk
19c31f ¤   ¤   ¤   derr = ProcessMount((PAD_Mount) pPacket, size);
34cdcb ¤   ¤   ¤   break;
e2af5a
db0fa7 ¤   ¤   case kAD_Unmount:¤  ¤   ¤   // unmount a PGPdisk
765ffb ¤   ¤   ¤   derr = ProcessUnmount((PAD_Unmount) pPacket, size);
63cdcb ¤   ¤   ¤   break;
eaaf5a
a5c659 ¤   ¤   case kAD_QueryVersion:¤ ¤   // exchange version numbers
9e5a83 ¤   ¤   ¤   derr = ProcessQueryVersion((PAD_QueryVersion) pPacket, size);
6acdcb ¤   ¤   ¤   break;
56af5a
7c3e5e ¤   ¤   case kAD_QueryMounted:¤ ¤   // ask if drive/path is PGPdisk
278440 ¤   ¤   ¤   derr = ProcessQueryMounted((PAD_QueryMounted) pPacket, size);
cacdcb ¤   ¤   ¤   break;
d9af5a
902057 ¤   ¤   case kAD_QueryOpenFiles:¤   // app asks if drive has open files
34b563 ¤   ¤   ¤   derr = ProcessQueryOpenFiles((PAD_QueryOpenFiles) pPacket, size);
87cdcb ¤   ¤   ¤   break;
6faf5a
--5727 000a0bf8cd6401100e8 Page 13 of CPGPdiskInterfaceComm.cpp
5f94ff ¤   ¤   case kAD_ChangePrefs:¤  ¤   // app changes preferences
b95d65 ¤   ¤   ¤   derr = ProcessChangePrefs((PAD_ChangePrefs) pPacket, size);
abcdcb ¤   ¤   ¤   break;
a4af5a
818e74 ¤   ¤   case kAD_LockUnlockMem:¤¤   // app wants to lock or unlock memory
f3fe5c ¤   ¤   ¤   derr = ProcessLockUnlockMem((PAD_LockUnlockMem) pPacket, size);
6ecdcb ¤   ¤   ¤   break;
23af5a
57e100 ¤   ¤   case kAD_GetPGPdiskInfo:¤   // fill in array with PGPdisk info
f97cdd ¤   ¤   ¤   derr = ProcessGetPGPdiskInfo((PAD_GetPGPdiskInfo) pPacket, size);
a6cdcb ¤   ¤   ¤   break;
8daf5a
99fe99 ¤   ¤   case kAD_LockUnlockVol:¤¤   // lock/unlock volume
ca6d30 ¤   ¤   ¤   derr = ProcessLockUnlockVol((PAD_LockUnlockVol) pPacket, size);
9bcdcb ¤   ¤   ¤   break;
08af5a
f6317b ¤   ¤   case kAD_ReadWriteVol:¤ ¤   // read/write to volume
d3abe8 ¤   ¤   ¤   derr = ProcessReadWriteVol((PAD_ReadWriteVol) pPacket, size);
d2cdcb ¤   ¤   ¤   break;
55af5a
08b0a6 ¤   ¤   case kAD_QueryVolInfo:¤ ¤   // get extra info about a volume
674b38 ¤   ¤   ¤   derr = ProcessQueryVolInfo((PAD_QueryVolInfo) pPacket, size);
e5cdcb ¤   ¤   ¤   break;
88af5a
1567b4 ¤   ¤   case kAD_NotifyUserLogoff:¤ // user logging off, unmount PGPdisks
5a832c ¤   ¤   ¤   derr = ProcessNotifyUserLogoff((PAD_NotifyUserLogoff) pPacket,·
1cac35 ¤   ¤   ¤   ¤   size);
4fcdcb ¤   ¤   ¤   break;
9caf5a
4e9ae3 ¤   ¤   default:
c4f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
80cdcb ¤   ¤   ¤   break;
1a0fe4 ¤   ¤   }
b39371 ¤   }
b7af5a
9c9bd2 ¤   // Unmap embedded error pointer.
419d2d ¤   if (mappedDerr)
19c7a1 ¤   {
3615c6 ¤   ¤   (* pPacket->pDerr) = derr;
1daf5a
cfaec7 ¤   ¤   mUserMemManager.UnlockUnmapUserMem(pPacket->pDerr, sizeof(DualErr));
3daf5a
37cdcf ¤   ¤   return STATUS_SUCCESS;
449371 ¤   }
e40e24 ¤   else
9ec7a1 ¤   {
4e9ff6 ¤   ¤   return STATUS_INVALID_PARAMETER;
999371 ¤   }
5eefe6 }
0baf5a
69af5a
e76557 ///////////////////////
6a8076 // Dispatcher functions
1e6557 ///////////////////////
0caf5a
bd71a0 // DeviceControl handles communications from the app.
38af5a
1d0e00 NTSTATUS·
55010c CPGPdiskInterface::DeviceControl(KIrp I)
5cbb36 {
7ddea4 ¤   NTSTATUS status = STATUS_SUCCESS;
d4af5a
7ada9a ¤   switch (I.IoctlCode())
02c7a1 ¤   {
588993 ¤   case IOCTL_PGPDISK_SENDPACKET:
7aaf5a
1d9087 ¤   ¤   status = ProcessADPacket((PADPacketHeader) I.IoctlBuffer(),·
bbdf5f ¤   ¤   ¤   I.IoctlInputBufferSize());
682f68 ¤   ¤   break;
ffaf5a
3e2f72 ¤   default:
a0a3cf ¤   ¤   status = STATUS_INVALID_PARAMETER;
--3111 001dee295b4401100e8 Page 14 of CPGPdiskInterfaceComm.cpp
4f2f68 ¤   ¤   break;
d99371 ¤   }
68af5a
b8e7fb ¤   return I.Complete(status);
deefe6 }
--cd4e 001ac3cb8a2401100e9 Page 1 of CPGPdiskInterfaceComm.h
541bc3 //////////////////////////////////////////////////////////////////////////////
7993cc // CPGPdiskInterfaceComm.h
3b465d //
9bd119 // Declarations for CPGPdiskInterfaceComm.cpp.
741bc3 //////////////////////////////////////////////////////////////////////////////
0aaf5a
a9973f // $Id: CPGPdiskInterfaceComm.h,v 1.1.2.3 1998/07/06 08:57:42 nryan Exp $
4caf5a
52cbce // Copyright (C) 1998 by Network Associates, Inc.
5e71ae // All rights reserved.
4daf5a
6d4f70 #ifndef Included_CPGPdiskInterfaceComm_h¤   // [
73169e #define Included_CPGPdiskInterfaceComm_h
52af5a
fd1cb9 // Nothing needed here.
e9af5a
ac00de #endif¤ // ] Included_CPGPdiskInterfaceComm_h
--1ef3 001b6111d84401100ea Page 1 of CPGPdiskInterfaceErrors.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
cdf8ba // CPGPdiskInterfaceErrors.cpp
a5465d //
7d22fa // Error handling functions.
381bc3 //////////////////////////////////////////////////////////////////////////////
96af5a
a4ee32 // $Id: CPGPdiskInterfaceErrors.cpp,v 1.1.2.8 1998/07/06 23:26:58 nryan Exp $
23af5a
40cbce // Copyright (C) 1998 by Network Associates, Inc.
0571ae // All rights reserved.
c0af5a
85d7a1 #include <vdw.h>
8daf5a
9a9bcf #include "Required.h"
bc3a85 #include "DualErr.h"
bb993c #include "StringAssociation.h"
6fbfe9 #include "UtilityFunctions.h"
a0af5a
62e0ee #include "CPGPdiskInterface.h"
1d99fd #include "CPGPdiskInterfaceErrors.h"
54c411 #include "Globals.h"
d2f1f6 #include "KernelModeUtils.h"
21b43f #include "msglog.h"
36af5a
39af5a
11893c ///////////
4ed8ac // Constant
10893c ///////////
a7af5a
fe3add const LPCSTR kPGPdiskKernelErrString =·
31df79 ¤   "Error code is (%d, %d, %d)";
feaf5a
1daf5a
ef83f5 ///////////////////////////
98873f // Error handling functions
0083f5 ///////////////////////////
9aaf5a
0f6d7a // ReportError reports certain errors to the global event log..
99af5a
3dc823 void·
4dd1aa CPGPdiskInterface::ReportError(
3bae93 ¤   PGDMajorError¤  perr,·
76ef62 ¤   DualErr¤¤   ¤   derr,·
2a681f ¤   PGPUInt8¤   ¤   drive)
f7bb36 {
6204d9 ¤   static char¤¤   ¤   ¤   errString[kMaxStringSize];
f1f8a2 ¤   KErrorLogEntry¤ ¤   ¤   errEntry;
744a9a ¤   KUstring¤   ¤   ¤   ¤   uniErrString;
64e13e ¤   PIO_ERROR_LOG_PACKET¤   pErrPacket;
a7b60b ¤   static PGPUInt32¤   ¤   uniqueCode¤ = 0;
39af5a
ec9bf0 ¤   pErrPacket = errEntry;
23af5a
80b5dd ¤   // Prepare the error log entry.
77097e ¤   pErrPacket->FinalStatus¤¤   ¤   = STATUS_SUCCESS;
f98f1d ¤   pErrPacket->ErrorCode¤  ¤   ¤   = PGPDISK_ERROR_CODE;
17e320 ¤   pErrPacket->UniqueErrorValue¤   = uniqueCode++;
12af5a
4f2349 ¤   // Prepare the error string and post it.
24527f ¤   sprintf(errString, kPGPdiskKernelErrString, (PGPUInt32) perr,·
e07ced ¤   ¤   (PGPUInt32) derr.mMinorError, derr.mExternalError);
09af5a
bbf83b ¤   if (AssignToUni(&uniErrString, errString).IsntError())
92c7a1 ¤   {
622995 ¤   ¤   errEntry.InsertString(uniErrString.UnicodeString().Buffer);
c49374 ¤   ¤   errEntry.Post();
379371 ¤   }
b6efe6 }
--cd79 0013c9b5e5d401100eb Page 1 of CPGPdiskInterfaceErrors.h
541bc3 //////////////////////////////////////////////////////////////////////////////
c841ba // CPGPdiskInterfaceErrors.h
97465d //
8eac92 // Ddeclarations for CPGPdiskInterfaceErrors.cpp.
741bc3 //////////////////////////////////////////////////////////////////////////////
a0af5a
b0341a // $Id: CPGPdiskInterfaceErrors.h,v 1.1.2.2 1998/07/06 08:57:43 nryan Exp $
25af5a
1bcbce // Copyright (C) 1998 by Network Associates, Inc.
3b71ae // All rights reserved.
0aaf5a
3d963e #ifndef Included_CPGPdiskInterfaceErrors_h¤ // [
3db6eb #define Included_CPGPdiskInterfaceErrors_h
d7af5a
131cb9 // Nothing needed here.
b2af5a
3c853a #endif¤ // ] Included_CPGPdiskInterfaceErrors_h
--8068 0002850b757401100ec Page 1 of CPGPdiskInterfaceHooks.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
99e22b // CPGPdiskInterfaceHooks.cpp
21465d //
7879cf // Functions for hooking system devices and services.
df1bc3 //////////////////////////////////////////////////////////////////////////////
bdaf5a
57c07e // $Id: CPGPdiskInterfaceHooks.cpp,v 1.1.2.4 1998/07/06 08:57:44 nryan Exp $
48af5a
4fcbce // Copyright (C) 1998 by Network Associates, Inc.
5471ae // All rights reserved.
5daf5a
0bd7a1 #include <vdw.h>
b5ac83 #include <kfilter.cpp>
68af5a
5f9bcf #include "Required.h"
c4af5a
fde0ee #include "CPGPdiskInterface.h"
c4e834 #include "CPGPdiskInterfaceHooks.h"
ecc411 #include "Globals.h"
29af5a
a8af5a
5c09b7 ////////////
e5e738 // Constants
da09b7 ////////////
beaf5a
8dacc6 static LPCWSTR¤ kKeyboardDeviceName¤= L"\\Device\\KeyboardClass0";
38eeaf static LPCWSTR¤ kMouseDeviceName¤   = L"\\Device\\PointerClass0";
f2af5a
ffaf5a
ebc3ce /////////////////////////////////////////////////////
ffbcb4 // Class KeyboardFilterDevice public member functions
22c3ce /////////////////////////////////////////////////////
aaaf5a
1c2af4 // The KeyboardFilterDevice default constructor.
b3af5a
be5f1b KeyboardFilterDevice::KeyboardFilterDevice() :
e63cf0 ¤   KFilterDevice(kKeyboardDeviceName, FILE_DEVICE_KEYBOARD, DO_BUFFERED_IO)
dbbb36 {
63fbff ¤   mCurrentStackLocation = NULL;
e524b2 ¤   mNumOutstandingIrps = 0;
32af5a
66812c ¤   if (!NT_SUCCESS(m_ConstructorStatus))
6ec7a1 ¤   {
b79437 ¤   ¤   mInitErr = DualErr(kPGDMinorError_DeviceConstructFailed,·
108b96 ¤   ¤   ¤   m_ConstructorStatus);
479371 ¤   }
1eefe6 }
c4af5a
5e52b6 // The KeyboardFilterDevice destructor.
9caf5a
614ce1 KeyboardFilterDevice::~KeyboardFilterDevice()
8abb36 {
7d9506 ¤   // If we have one outstanding IRP, we are OK. If we have more than one,·
b616bc ¤   // we're screwed. Bugcheck. This could be fixed with a lot of work, but
ab291b ¤   // unloading is only allowed on debug builds, so who cares?
11af5a
0f645c ¤   if (mNumOutstandingIrps == 1)
35c7a1 ¤   {
179fe4 ¤   ¤   mNumOutstandingIrps = 0;
acaf5a
78cd06 ¤   ¤   mCurrentStackLocation->CompletionRoutine = NULL;
25f640 ¤   ¤   mCurrentStackLocation->Control &= ~SL_INVOKE_ON_CANCEL &·
f2584f ¤   ¤   ¤   ~SL_INVOKE_ON_SUCCESS & ~SL_INVOKE_ON_ERROR;
ccaf5a
14148c ¤   ¤   mCurrentStackLocation = NULL;
149371 ¤   }
b3bcab ¤   else if (mNumOutstandingIrps > 1)
eac7a1 ¤   {
54d828 ¤   ¤   KeBugCheck(kPGPdiskBugCheckCode);
f69371 ¤   }
52efe6 }
28af5a
--e1a3 000bfccc5b1401100ec Page 2 of CPGPdiskInterfaceHooks.cpp
c21694 // Read is called to read keypresses. Zero the inactivity timer.
bcaf5a
410e00 NTSTATUS·
331c76 KeyboardFilterDevice::Read(KIrp I)
42bb36 {
d1b60d ¤   mCurrentStackLocation = I.NextStackLocation();
07eade ¤   mNumOutstandingIrps++;
06af5a
f360d0 ¤   return PassThrough(I, TRUE, NULL);
85efe6 }
62af5a
db172c // OnIrpComplete is called after the keyboard returns data.
5daf5a
120e00 NTSTATUS·
c73d2e KeyboardFilterDevice::OnIrpComplete(KIrp I, PVOID Context)
6ebb36 {
13779d ¤   mNumOutstandingIrps--;
07fbff ¤   mCurrentStackLocation = NULL;
baaf5a
58b5c7 ¤   Interface->mSecondsInactive = 0;
66af5a
78ecc5 ¤   return KFilterDevice::OnIrpComplete(I, Context);
b2efe6 }
8eaf5a
51af5a
ff9b9e //////////////////////////////////////////////////
6f4eae // Class MouseFilterDevice public member functions
919b9e //////////////////////////////////////////////////
c5af5a
4afe6d // The MouseFilterDevice default constructor.
eeaf5a
7cac30 MouseFilterDevice::MouseFilterDevice() :
ef3c01 ¤   KFilterDevice(kMouseDeviceName, FILE_DEVICE_MOUSE, DO_BUFFERED_IO)
ffbb36 {
c4fbff ¤   mCurrentStackLocation = NULL;
5324b2 ¤   mNumOutstandingIrps = 0;
3baf5a
80812c ¤   if (!NT_SUCCESS(m_ConstructorStatus))
c3c7a1 ¤   {
ee9437 ¤   ¤   mInitErr = DualErr(kPGDMinorError_DeviceConstructFailed,·
588b96 ¤   ¤   ¤   m_ConstructorStatus);
aa9371 ¤   }
77efe6 }
9daf5a
2fb206 // The MouseFilterDevice destructor.
e6af5a
f47b75 MouseFilterDevice::~MouseFilterDevice()
c8bb36 {
829506 ¤   // If we have one outstanding IRP, we are OK. If we have more than one,·
4d16bc ¤   // we're screwed. Bugcheck. This could be fixed with a lot of work, but
43291b ¤   // unloading is only allowed on debug builds, so who cares?
e4af5a
05645c ¤   if (mNumOutstandingIrps == 1)
98c7a1 ¤   {
e99fe4 ¤   ¤   mNumOutstandingIrps = 0;
2eaf5a
d2cd06 ¤   ¤   mCurrentStackLocation->CompletionRoutine = NULL;
0cf640 ¤   ¤   mCurrentStackLocation->Control &= ~SL_INVOKE_ON_CANCEL &·
78584f ¤   ¤   ¤   ~SL_INVOKE_ON_SUCCESS & ~SL_INVOKE_ON_ERROR;
68af5a
cb148c ¤   ¤   mCurrentStackLocation = NULL;
fc9371 ¤   }
e1bcab ¤   else if (mNumOutstandingIrps > 1)
35c7a1 ¤   {
1ad828 ¤   ¤   KeBugCheck(kPGPdiskBugCheckCode);
6d9371 ¤   }
9befe6 }
e4af5a
1d1694 // Read is called to read keypresses. Zero the inactivity timer.
2caf5a
6c0e00 NTSTATUS·
bfef76 MouseFilterDevice::Read(KIrp I)
--2d46 0010f98544a401100ec Page 3 of CPGPdiskInterfaceHooks.cpp
2cbb36 {
88b60d ¤   mCurrentStackLocation = I.NextStackLocation();
b2eade ¤   mNumOutstandingIrps++;
50af5a
b560d0 ¤   return PassThrough(I, TRUE, NULL);
54efe6 }
96af5a
fb5d27 // OnIrpComplete is called after the mouse returns data. Look for button
92877c // presses.
20af5a
c60e00 NTSTATUS·
357ba8 MouseFilterDevice::OnIrpComplete(KIrp I, PVOID Context)
afbb36 {
68f435 ¤   PMOUSE_INPUT_DATA pMID;
e1af5a
35779d ¤   mNumOutstandingIrps--;
78fbff ¤   mCurrentStackLocation = NULL;
4daf5a
77a48b ¤   pMID = (PMOUSE_INPUT_DATA) I.IoctlBuffer();
add8f9 ¤   pgpAssertAddrValid(pMID, MOUSE_INPUT_DATA);
f6af5a
96bb20 ¤   if (pMID->Buttons != 0)
b1b02a ¤   ¤   Interface->mSecondsInactive = 0;
a5af5a
ddecc5 ¤   return KFilterDevice::OnIrpComplete(I, Context);
faefe6 }
e2af5a
98af5a
e904c6 ///////////////////////////////////////
7992c5 // Initialization and cleanup functions
1b04c6 ///////////////////////////////////////
01af5a
2e55af // SetupSystemHooks installs our system hooks.
c2af5a
652292 DualErr·
6ee8ce CPGPdiskInterface::SetupSystemHooks()
6ebb36 {
6c7d36 ¤   DualErr derr;
f0af5a
d931d8 ¤   // Neither of these hooks are critical so don't report errors on a
98c780 ¤   // failure to create.
0baf5a
d52e3b ¤   mKeyboardFilter = new KeyboardFilterDevice();
734bb4 ¤   mCreatedKeyboardFilter = IsntNull(mKeyboardFilter);
78af5a
883964 ¤   mMouseFilter = new MouseFilterDevice();
cdb1f6 ¤   mCreatedMouseFilter = IsntNull(mMouseFilter);
27af5a
9e33e3 ¤   return derr;
cfefe6 }
c7af5a
9c8397 // DeleteSystemHooks deletes our system hooks.
49af5a
c4c823 void·
2c26a6 CPGPdiskInterface::DeleteSystemHooks()
dfbb36 {
8e8c48 ¤   if (mCreatedMouseFilter)
0ec7a1 ¤   {
a33ad5 ¤   ¤   delete mMouseFilter;
18afa0 ¤   ¤   mMouseFilter = NULL;
e09371 ¤   }
7eaf5a
e0c19c ¤   if (mCreatedKeyboardFilter)
91c7a1 ¤   {
23ddcd ¤   ¤   delete mKeyboardFilter;
08077c ¤   ¤   mKeyboardFilter = NULL;
7f9371 ¤   }
0fefe6 }
--1dbc 000d963ba8e401100ed Page 1 of CPGPdiskInterfaceHooks.h
541bc3 //////////////////////////////////////////////////////////////////////////////
55efd8 // CPGPdiskInterfaceHooks.h
d0465d //
39f330 // Declarations for CPGPdiskInterfaceHooks.cpp.
791bc3 //////////////////////////////////////////////////////////////////////////////
2daf5a
2ee4ff // $Id: CPGPdiskInterfaceHooks.h,v 1.1.2.4 1998/07/06 08:57:45 nryan Exp $
87af5a
37cbce // Copyright (C) 1998 by Network Associates, Inc.
7a71ae // All rights reserved.
1aaf5a
cacf2b #ifndef Included_CPGPdiskInterfaceHooks_h¤  // [
750230 #define Included_CPGPdiskInterfaceHooks_h
86af5a
3caf5a
9b09b7 ////////////
60e738 // Constants
0309b7 ////////////
afaf5a
a86dc2 #define MOUSE_LEFT_BUTTON_DOWN¤ ·0x0001 ·// Left Button changed to down.
e5425f #define MOUSE_LEFT_BUTTON_UP¤   ·0x0002 ·// Left Button changed to up.
9690a5 #define MOUSE_RIGHT_BUTTON_DOWN ·0x0004 ·// Right Button changed to down.
ee865b #define MOUSE_RIGHT_BUTTON_UP¤  ·0x0008 ·// Right Button changed to up.
5ae678 #define MOUSE_MIDDLE_BUTTON_DOWN 0x0010 ·// Middle Button changed to down.
7c63b7 #define MOUSE_MIDDLE_BUTTON_UP¤ ·0x0020 ·// Middle Button changed to up.
10af5a
d0cf6f #define MOUSE_BUTTON_1_DOWN ¤   MOUSE_LEFT_BUTTON_DOWN
6a3a2d #define MOUSE_BUTTON_1_UP¤  ¤   MOUSE_LEFT_BUTTON_UP
39bcbe #define MOUSE_BUTTON_2_DOWN ¤   MOUSE_RIGHT_BUTTON_DOWN
cb9d93 #define MOUSE_BUTTON_2_UP¤  ¤   MOUSE_RIGHT_BUTTON_UP
bc6bd3 #define MOUSE_BUTTON_3_DOWN ¤   MOUSE_MIDDLE_BUTTON_DOWN
2320ae #define MOUSE_BUTTON_3_UP¤  ¤   MOUSE_MIDDLE_BUTTON_UP
00af5a
df2cb3 #define MOUSE_BUTTON_4_DOWN ¤   0x0040
a97649 #define MOUSE_BUTTON_4_UP¤  ¤   0x0080
f8ab8e #define MOUSE_BUTTON_5_DOWN ¤   0x0100
4e711a #define MOUSE_BUTTON_5_UP¤  ¤   0x0200
b0af5a
285c71 #define MOUSE_WHEEL ¤   ¤   ¤   0x0400
5faf5a
a7af5a
55d557 ////////
2902c9 // Types
54d557 ////////
0caf5a
072bc1 typedef struct _MOUSE_INPUT_DATA {
adaf5a
e393e0 ¤   USHORT¤ UnitId;
fb7db1 ¤   USHORT¤ Flags;
3eaf5a
e18ae4 ¤   union·
b0c7a1 ¤   {
bab544 ¤   ¤   ULONG Buttons;
61af5a
89267f ¤   ¤   struct·
aa5b34 ¤   ¤   {
d150ee ¤   ¤   ¤   USHORT¤ ButtonFlags;
6edcd9 ¤   ¤   ¤   USHORT¤ ButtonData;
73a105 ¤   ¤   };
6262bd ¤   };
7baf5a
4f38b8 ¤   ULONG¤  RawButtons;
f2f427 ¤   LONG¤   LastX;
c6aefb ¤   LONG¤   LastY;
6efa16 ¤   ULONG¤  ExtraInformation;
99af5a
022c09 } MOUSE_INPUT_DATA, *PMOUSE_INPUT_DATA;
33af5a
ebaf5a
c18104 /////////////////////////////
c9fff9 // Class KeyboardFilterDevice
d98104 /////////////////////////////
--d88a 0017bb50e00401100ed Page 2 of CPGPdiskInterfaceHooks.h
e0af5a
c0d637 class KeyboardFilterDevice : public KFilterDevice
a0bb36 {
4b5ed4 public:
971603 ¤   DualErr mInitErr;
94af5a
d985ab ¤   ¤   ¤   ¤   ¤   ¤   KeyboardFilterDevice();
d90767 ¤   ¤   ¤   ¤   ¤   ¤   ~KeyboardFilterDevice();
00af5a
c75f74 ¤   virtual NTSTATUS¤   Read(KIrp I);
f5da05 ¤   virtual NTSTATUS¤   OnIrpComplete(KIrp I, PVOID Context);
44af5a
6b0fb9 private:
eb0d80 ¤   PGPUInt32¤  ¤   ¤   mNumOutstandingIrps;¤   // # of IRPs outstanding
945005 ¤   PIO_STACK_LOCATION¤ mCurrentStackLocation;¤ // current stack location
bbaf5a
8cc325 ¤   SAFE_DESTRUCTORS
7482f7 };
93af5a
b5af5a
0cb352 //////////////////////////
5037ce // Class MouseFilterDevice
e5b352 //////////////////////////
a4af5a
f2046e class MouseFilterDevice : public KFilterDevice
63bb36 {
f95ed4 public:
011603 ¤   DualErr mInitErr;
c4af5a
ac833d ¤   ¤   ¤   ¤   ¤   ¤   MouseFilterDevice();
74d76f ¤   ¤   ¤   ¤   ¤   ¤   ~MouseFilterDevice();
d2af5a
0e5f74 ¤   virtual NTSTATUS¤   Read(KIrp I);
f3da05 ¤   virtual NTSTATUS¤   OnIrpComplete(KIrp I, PVOID Context);
1aaf5a
e70fb9 private:
660d80 ¤   PGPUInt32¤  ¤   ¤   mNumOutstandingIrps;¤   // # of IRPs outstanding
2a5005 ¤   PIO_STACK_LOCATION¤ mCurrentStackLocation;¤ // current stack location
d1af5a
42c325 ¤   SAFE_DESTRUCTORS
8982f7 };
50af5a
7b4022 #endif¤ // ] Included_CPGPdiskInterfaceHooks_h
--39fb 0001afcf7b2401100ee Page 1 of CPGPdiskInterfaceVolumes.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
538d9d // CPGPdiskInterfaceVolumes.cpp
f1465d //
b73e3a // Functions for PGPdisk volume mounting and unmounting.
151bc3 //////////////////////////////////////////////////////////////////////////////
a1af5a
721691 // $Id: CPGPdiskInterfaceVolumes.cpp,v 1.1.2.15 1998/07/06 08:57:45 nryan Exp $
51af5a
38cbce // Copyright (C) 1998 by Network Associates, Inc.
a471ae // All rights reserved.
a3af5a
d1d7a1 #include <vdw.h>
35af5a
6a9bcf #include "Required.h"
f90092 #include "Packets.h"
ec7414 #include "PGPdiskHighLevelUtils.h"
c15788 #include "PGPdiskVersion.h"
7bbfe9 #include "UtilityFunctions.h"
c8af5a
11e0ee #include "CPGPdiskInterface.h"
5648c6 #include "CPGPdiskInterfaceVolumes.h"
b6c411 #include "Globals.h"
15f1f6 #include "KernelModeUtils.h"
1468c6 #include "PGPdisk.h"
f4af5a
5aaf5a
2d90e1 //////////////////////////////////////
3a14d3 // Mount and unmount utility functions
9e90e1 //////////////////////////////////////
07af5a
2cdc63 // MountPGPdisk mounts the PGPdisk file specified by 'path' and returns the
5c4e85 // drive number it was mounted on.
7aaf5a
5b2292 DualErr·
4de4c9 CPGPdiskInterface::MountPGPdisk(
c420cd ¤   LPCSTR¤ ¤   ¤   path,·
0141e5 ¤   CipherContext¤  *pContext,·
7df4ef ¤   PGPUInt8¤   ¤   drive,·
6f6fde ¤   PGPBoolean¤ ¤   mountReadOnly)
62bb36 {
74be41 ¤   DualErr¤¤   derr;
898941 ¤   PGPBoolean¤ createdPGPdisk¤ = FALSE;
9d70f5 ¤   PGPdisk¤¤   *pPGD;
77af5a
22639f ¤   pgpAssertStrValid(path);
1493e3 ¤   pgpAssertAddrValid(pContext, CipherContext);
07af5a
208534 ¤   // We must first check if we have space for another PGPdisk.
877570 ·¤  if (mPGPdisks.GetNumPGPdisks() >= kMaxMountedPGPdisks)
530c78 ¤   ¤   derr = DualErr(kPGDMinorError_MaxPGPdisksMounted);
81af5a
bb3da7 ¤   // Search for any pre-existing PGPdisks corresponding to the path.
d52361 ¤   if (derr.IsntError())
a6c7a1 ¤   {
be5964 ¤   ¤   if (mPGPdisks.FindPGPdisk(path))
b61bec ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskAlreadyMounted);
c49371 ¤   }
91af5a
268730 ¤   // Validate the PGPdisk.
832361 ¤   if (derr.IsntError())
4cc7a1 ¤   {
cb6d28 ¤   ¤   derr = ValidatePGPdisk(path);
789371 ¤   }
bfaf5a
41c89f ¤   // If the PGPdisk is opened by someone else with write access, fail.
5f2361 ¤   if (derr.IsntError())
c8c7a1 ¤   {
ddbc8f ¤   ¤   if (IsFileInUseByWriter(path))
7cf979 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskAlreadyInUse);
a39371 ¤   }
03af5a
1a9296 ¤   // Create a new PGPdisk object.
--1743 000aa0a82b1401100ee Page 2 of CPGPdiskInterfaceVolumes.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
b7b8cc ¤   ¤   pPGD = new PGPdisk;
6daf5a
b369a8 ¤   ¤   if (IsNull(pPGD))
f3b95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
2aaf5a
1bdc69 ¤   ¤   createdPGPdisk = derr.IsntError();
639371 ¤   }
b4af5a
b02361 ¤   if (derr.IsntError())
36c7a1 ¤   {
2da7af ¤   ¤   derr = pPGD->mInitErr;
279371 ¤   }
9eaf5a
6c1cb8 ¤   // Attempt our mount.
152361 ¤   if (derr.IsntError())
41c7a1 ¤   {
224556 ¤   ¤   derr = pPGD->Mount(path, pContext, drive, mountReadOnly);
459371 ¤   }
a4af5a
70d9e3 ¤   // Attach the object to the global list.
832361 ¤   if (derr.IsntError())
77c7a1 ¤   {
880510 ¤   ¤   mPGPdisks.AddPGPdisk(pPGD);
4a9371 ¤   }
4faf5a
4e1501 ¤   // Cleanup if an error occurred.
5b4bb3 ¤   if (derr.IsError())
8cc7a1 ¤   {
4028e5 ¤   ¤   if (createdPGPdisk)
355b34 ¤   ¤   {
7a4400 ¤   ¤   ¤   if (pPGD->Mounted())
4ea391 ¤   ¤   ¤   ¤   pPGD->Unmount(TRUE);
05af5a
4c4a02 ¤   ¤   ¤   delete pPGD;
710fe4 ¤   ¤   }
7f9371 ¤   }
30af5a
bb33e3 ¤   return derr;
68efe6 }
9faf5a
df41ad // UnmountPGPdisk unmounts the PGPdisk specified by 'drive'.
7faf5a
8d2292 DualErr·
88bf71 CPGPdiskInterface::UnmountPGPdisk(PGPUInt8 drive, PGPBoolean isThisEmergency)
81bb36 {
03be41 ¤   DualErr¤¤   derr;
937d26 ¤   PGPBoolean¤ removedPGPdisk, unmountedChildren;
8770f5 ¤   PGPdisk¤¤   *pPGD;
46c303 ¤   PGPUInt32¤  i¤  = 0;
12af5a
e94299 ¤   removedPGPdisk = unmountedChildren = FALSE;
f7af5a
88aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
3aaf5a
a20a31 ¤   // Verify that the PGPdisk exists and is mounted.
291495 ¤   if (IsNull(pPGD = mPGPdisks.FindPGPdisk(drive)))
375039 ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskNotMounted);
84af5a
fdf94f ¤   // If this PGPdisk has other PGPdisks mounted on it, we must perform a
d5d34f ¤   // depth-first unmount of all those PGPdisks first.
8daf5a
9ef3ae ¤   while (derr.IsntError())
b9c7a1 ¤   {
b730c1 ¤   ¤   PGPdisk *pClient;
51af5a
80f36d ¤   ¤   if (!(pClient = Interface->mPGPdisks.EnumPGPdisks(i++)))
71cdcb ¤   ¤   ¤   break;
e3af5a
7f86f9 ¤   ¤   if (!IsUNCPath(pClient->GetPath()) &&
aa875d ¤   ¤   ¤   (pClient->GetLocalHostDrive() == drive))
--ef9e 00089ad71ee401100ee Page 3 of CPGPdiskInterfaceVolumes.cpp
e35b34 ¤   ¤   {
ac7c75 ¤   ¤   ¤   i = 0;
2cac6c ¤   ¤   ¤   derr = UnmountPGPdisk(pClient->GetDrive(), isThisEmergency);
f7af5a
b91927 ¤   ¤   ¤   if (isThisEmergency)
8ea601 ¤   ¤   ¤   ¤   derr = DualErr::NoError;
c0af5a
3a0081 ¤   ¤   ¤   unmountedChildren = derr.IsntError();
1c0fe4 ¤   ¤   }
429371 ¤   }
c6af5a
f006c3 ¤   // Check if the PGPdisk has open files.
432361 ¤   if (derr.IsntError())
03c7a1 ¤   {
8f6861 ¤   ¤   // If we unmounted any children, we may have to wait a little while
08e43f ¤   ¤   // for the system to flush its cache. Try about 10 times.
cbaf5a
633022 ¤   ¤   if (unmountedChildren)
ec5b34 ¤   ¤   {
027c75 ¤   ¤   ¤   i = 0;
93af5a
b9bf7d ¤   ¤   ¤   while (pPGD->HasOpenFiles() && (i++ < kMaxCheckOpenFilesAttempts))
80f776 ¤   ¤   ¤   {
65b31e ¤   ¤   ¤   ¤   KeDelayExecutionThread(KernelMode, FALSE,·
76e570 ¤   ¤   ¤   ¤   ¤   &RtlConvertLongToLargeInteger(-500 * 10000));
aba3a6 ¤   ¤   ¤   }
270fe4 ¤   ¤   }
64af5a
cecab7 ¤   ¤   if (pPGD->HasOpenFiles())
69ad7c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FilesOpenOnDrive);
55af5a
3aa271 ¤   ¤   if (isThisEmergency)
c2a3ec ¤   ¤   ¤   derr = DualErr::NoError;
339371 ¤   }
dfaf5a
a992df ¤   // Remove the object from the global list and attempt the unmount.
0f2361 ¤   if (derr.IsntError())
13c7a1 ¤   {
a217c3 ¤   ¤   mPGPdisks.RemovePGPdisk(pPGD);
8db47f ¤   ¤   removedPGPdisk = TRUE;
9aaf5a
26040c ¤   ¤   derr = pPGD->Unmount(isThisEmergency);
289371 ¤   }
78af5a
294f0c ¤   // Delete the PGPdisk object.
972361 ¤   if (derr.IsntError())
1bc7a1 ¤   {
f3fbd3 ¤   ¤   delete pPGD;
cb9371 ¤   }
e4af5a
adfe28 ¤   // Cleanup if an error occurred;
354bb3 ¤   if (derr.IsError())
25c7a1 ¤   {
71f1d6 ¤   ¤   if (removedPGPdisk && pPGD->Mounted())
2ac045 ¤   ¤   ¤   mPGPdisks.AddPGPdisk(pPGD);
7d9371 ¤   }
e6af5a
0f33e3 ¤   return derr;
52efe6 }
d4af5a
e620f7 // UnmountAllPGPdisks unmounts all PGPdisks in the system.
16af5a
4f2292 DualErr·
df40c4 CPGPdiskInterface::UnmountAllPGPdisks(PGPBoolean isThisEmergency)
05bb36 {
3ad5ab ¤   DualErr¤¤   derr, storedDerr;
06f341 ¤   PGPUInt8¤   drive;
2ac303 ¤   PGPUInt32¤  i¤  = 0;
0070f5 ¤   PGPdisk¤¤   *pPGD;
36af5a
5410ca ¤   // Note how we enumerate on position 0, and increase this only when we
898730 ¤   // find a drive we can't unmount for whatever reason. This is because
--2299 001355d1b21401100ee Page 4 of CPGPdiskInterfaceVolumes.cpp
7518a5 ¤   // if a drive can't be unmounted it won't be removed, and thus 'sticks'
5086ea ¤   // at position 0, 1, etc.
40af5a
76ae82 ¤   while (pPGD = mPGPdisks.EnumPGPdisks(i))
cfc7a1 ¤   {
f8132e ¤   ¤   pgpAssert(pPGD->Mounted());
8d96ff ¤   ¤   drive = pPGD->GetDrive();
9eaf5a
870812 ¤   ¤   // Now attempt the unmount.
d3aa35 ¤   ¤   if (derr.IsntError())
995b34 ¤   ¤   {
5cf950 ¤   ¤   ¤   derr = UnmountPGPdisk(drive, isThisEmergency);
7c0fe4 ¤   ¤   }
ecaf5a
fdbfd5 ¤   ¤   // Remember only the first error we see.
3cbdd6 ¤   ¤   if (derr.IsError())
bc5b34 ¤   ¤   {
88ff83 ¤   ¤   ¤   if (storedDerr.IsntError())
0ff776 ¤   ¤   ¤   {
d9d099 ¤   ¤   ¤   ¤   storedDerr = derr;
f4a3a6 ¤   ¤   ¤   }
0faf5a
8ca3ec ¤   ¤   ¤   derr = DualErr::NoError;
dd81ec ¤   ¤   ¤   i++;
e60fe4 ¤   ¤   }
999371 ¤   }
70af5a
0bc19e ¤   return storedDerr;
35efe6 }
--9fe0 001be40e5fb401100ef Page 1 of CPGPdiskInterfaceVolumes.h
541bc3 //////////////////////////////////////////////////////////////////////////////
bbfe6e // CPGPdiskInterfaceVolumes.h
de465d //
f0a92f // Declarations for CPGPdiskInterfaceVolumes.cpp.
c91bc3 //////////////////////////////////////////////////////////////////////////////
fdaf5a
0b4144 // $Id: CPGPdiskInterfaceVolumes.h,v 1.1.2.3 1998/07/06 08:57:46 nryan Exp $
aeaf5a
7acbce // Copyright (C) 1998 by Network Associates, Inc.
0671ae // All rights reserved.
68af5a
8c5b0c #ifndef Included_CPGPdiskInterfaceVolumes_h¤// [
b6216f #define Included_CPGPdiskInterfaceVolumes_h
3eaf5a
aa1cb9 // Nothing needed here.
0baf5a
bee658 #endif¤ // ] Included_CPGPdiskInterfaceVolumes_h
--9b94 000b1c4f24f401100f0 Page 1 of CRunTimeExtras.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
101c46 // CRunTimeExtras.cpp
48465d //
68bd5a // Definitions of extra C run-time functions we define.
221bc3 //////////////////////////////////////////////////////////////////////////////
73af5a
39def9 // $Id: CRunTimeExtras.cpp,v 1.1.2.6 1998/06/11 08:53:57 nryan Exp $
efaf5a
bd7758 // Portions Copyright (C) 1998 by Network Associates, Inc.
b371ae // All rights reserved.
a2af5a
00d7a1 #include <vdw.h>
3d35e5 #include "CRunTimeExtras.h"
f5af5a
1eaf5a
48c7c6 ///////////////////////////////
03cefb // C run time library functions
cfc7c6 ///////////////////////////////
b1af5a
c6eddf extern "C"·
7f314a void
6ed80e __cdecl·
51c21a free(void *memBlock)
48bb36 {
292e42 ¤   delete[] memBlock;
ebefe6 }
23af5a
5eeddf extern "C"·
fb21f6 void *·
27d80e __cdecl·
5eef25 malloc(size_t size)
19bb36 {
f72b99 ¤   unsigned char *newBlock;
5caf5a
a7b6df ¤   newBlock = new unsigned char[size + sizeof(size_t)];
83af5a
60512f ¤   if (newBlock == NULL)
987ed2 ¤   ¤   return NULL;
28af5a
f3d0b1 ¤   ((size_t *) newBlock)[0] = size;
e5af5a
abafee ¤   return (newBlock + sizeof(size_t));
65efe6 }
68af5a
1deddf extern "C"·
ae21f6 void *·
09d80e __cdecl·
67b30f realloc(void *oldBlock, size_t size)
51bb36 {
57d090 ¤   size_t¤ ¤   ¤   oldSize;
5989ad ¤   unsigned char¤  *actualOldBlock;
5876c4 ¤   void¤   ¤   ¤   *newBlock;
ce67c5 ¤
510216 ¤   if (oldBlock == NULL)
2323ff ¤   ¤   return malloc(size);
5baf5a
0aad55 ¤   actualOldBlock = ((unsigned char *) oldBlock) - sizeof(size_t);
92b75d ¤   oldSize = ((size_t *) actualOldBlock)[0];
e8af5a
666c53 ¤   if (size == 0)
cbc7a1 ¤   {
e7c24a ¤   ¤   free(actualOldBlock);
a07ed2 ¤   ¤   return NULL;
8a9371 ¤   }
e1af5a
298a27 ¤   newBlock = malloc(size);
8caf5a
e2512f ¤   if (newBlock == NULL)
087ed2 ¤   ¤   return NULL;
37af5a
cf0fe6 ¤   memmove(newBlock, oldBlock, (size < oldSize ? size : oldSize));
b1af5a
--7d85 001257c9d56401100f0 Page 2 of CRunTimeExtras.cpp
233e04 ¤   return newBlock;
25efe6 }
--38fc 001fe46a241401100f1 Page 1 of CRunTimeExtras.h
541bc3 //////////////////////////////////////////////////////////////////////////////
edf487 // CRunTimeExtras.h
a4465d //
ccc42e // Declarations of extra C run-time functions we define.
d51bc3 //////////////////////////////////////////////////////////////////////////////
cdaf5a
2b2018 // $Id: CRunTimeExtras.h,v 1.1.2.7 1998/06/18 20:09:24 nryan Exp $
4caf5a
887758 // Portions Copyright (C) 1998 by Network Associates, Inc.
6171ae // All rights reserved.
1faf5a
5834cd #ifndef Included_CRunTimeExtras_h¤  // [
62431b #define Included_CRunTimeExtras_h
36af5a
c5e418 // Nothing needed here. The functions defined in CRunTimeExtras.cpp are
ef7df9 // already declared in the standard header files.
61af5a
fe633e #endif¤ // ] Included_CRunTimeExtras_h
--f493 00159b3157f401100f2 Page 1 of FSCTLCodes.h
541bc3 //////////////////////////////////////////////////////////////////////////////
2cd73e // FSCTLCodes.h
14465d //
3a3d3f // Definitions for FSCTL codes not available in kernel-mode headers.
2d1bc3 //////////////////////////////////////////////////////////////////////////////
8baf5a
d25910 // $Id: FSCTLCodes.h,v 1.1.2.1 1998/05/23 01:43:28 nryan Exp $
96af5a
a77758 // Portions Copyright (C) 1998 by Network Associates, Inc.
e471ae // All rights reserved.
a4af5a
a37ea0 #ifndef Included_FSCTLCodes_h¤  // [
650b6f #define Included_FSCTLCodes_h
d6af5a
48af5a
0109b7 ////////////
dde738 // Constants
5209b7 ////////////
a9af5a
08176f // Ripped from winioctl.h.
07af5a
d1ae47 const PGPUInt32 FSCTL_LOCK_VOLUME =·
59da87 ¤   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS);
b2af5a
add6ed const PGPUInt32 FSCTL_UNLOCK_VOLUME =·
4d704f ¤   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS);
40af5a
032bba const PGPUInt32 FSCTL_DISMOUNT_VOLUME =·
b74211 ¤   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS);
a8af5a
2838b8 const PGPUInt32 FSCTL_MOUNT_DBLS_VOLUME¤=·
1e0f07 ¤   CTL_CODE(FILE_DEVICE_FILE_SYSTEM,13, METHOD_BUFFERED, FILE_ANY_ACCESS);
9faf5a
50eee3 const PGPUInt32 FSCTL_GET_COMPRESSION =·
dce984 ¤   CTL_CODE(FILE_DEVICE_FILE_SYSTEM,15, METHOD_BUFFERED, FILE_ANY_ACCESS);
7faf5a
82cfec const PGPUInt32 FSCTL_SET_COMPRESSION =·
0084e7 ¤   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 16, METHOD_BUFFERED,·
053be5 ¤   FILE_READ_DATA | FILE_WRITE_DATA);
f6af5a
5976eb #endif¤ // ] Included_FSCTLCodes_h
--5d7c 000121149b2401100f3 Page 1 of File.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
e328a6 // File.cpp
c5465d //
73e74f // Implementation of class File.
281bc3 //////////////////////////////////////////////////////////////////////////////
a2af5a
53daf2 // $Id: File.cpp,v 1.1.2.26 1998/08/07 01:20:04 nryan Exp $
0baf5a
0fcbce // Copyright (C) 1998 by Network Associates, Inc.
0e71ae // All rights reserved.
b0af5a
dbd7a1 #include <vdw.h>
6eaf5a
289bcf #include "Required.h"
3cbfe9 #include "UtilityFunctions.h"
6baf5a
def037 #include "File.h"
82f1f6 #include "KernelModeUtils.h"
a08869 #include "NtThreadSecurity.h"
812561 #include "Volume.h"
43af5a
bfaf5a
b13e71 /////////////////////////////////////
5a6d9e // Class File public member functions
b03e71 /////////////////////////////////////
16af5a
6ebde2 // The Class File default constructor.
41af5a
9b84a4 File::File()
b4bb36 {
825276 ¤   mHandle¤= NULL;
b907de ¤   mPath¤  = NULL;
09af5a
5fc199 ¤   mBlockBuf = NULL;
1aefe6 }
24af5a
e52045 // The destructor for class File will close the file.
05af5a
767def File::~File()
eabb36 {
42945d ¤   DualErr¤derr;
38af5a
2d8984 ¤   if (Opened())
eec7a1 ¤   {
376401 ¤   ¤   derr = Close();
c90796 ¤   ¤   pgpAssert(derr.IsntError());
6c9371 ¤   }
65af5a
9e08f2 ¤   ClearPath();
07efe6 }
d3af5a
745958 // IsHostNetworked returns TRUE if the file's host drive is remote.
8eaf5a
c877be PGPBoolean·
c93f67 File::IsHostNetworked()
17bb36 {
c21d6a ¤   pgpAssert(IsPathSet());
19af5a
2d8b30 ¤   return IsNetworkedPath(mPath);
b8efe6 }
64af5a
efd00b // IsPathSet returns TRUE if a path is set, FALSE otherwise.
abaf5a
3e77be PGPBoolean·
03e7b4 File::IsPathSet()
1abb36 {
1bddb6 ¤   return (IsntNull(mPath));
35efe6 }
17af5a
11126b // IsReadOnly returns TRUE if the file has been opened in read-only mode,
a69a91 // FALSE otherwise.
12af5a
--caf1 000802ae5ed401100f3 Page 2 of File.cpp
5a77be PGPBoolean·
b2ac7e File::IsReadOnly()
6cbb36 {
e51148 ¤   pgpAssert(Opened());
65af5a
31d939 ¤   return mIsReadOnly;
fbefe6 }
2eaf5a
5a9d6c // Opened returns TRUE if the file is opened, FALSE if not.
5eaf5a
4d77be PGPBoolean·
1e6e7f File::Opened()
69bb36 {
126575 ¤   return IsntNull(mHandle);
7eefe6 }
90af5a
3475f0 // GetLength returns the length of the file in bytes.
dfaf5a
362292 DualErr·
1c6be5 File::GetLength(PGPUInt64 *pLength)
13bb36 {
d9caca ¤   DualErr¤¤   ¤   ¤   ¤   ¤   derr;
8826d4 ¤   FILE_STANDARD_INFORMATION¤  fileInfo;
39adb5 ¤   IO_STATUS_BLOCK¤¤   ¤   ¤   ioStatus;
e6581a ¤   NTSTATUS¤   ¤   ¤   ¤   ¤   status;
03af5a
5a74ad ¤   pgpAssertAddrValid(pLength, PGPUInt32);
6c1148 ¤   pgpAssert(Opened());
61af5a
4292b6 ¤   status = ZwQueryInformationFile(mHandle, &ioStatus, &fileInfo,·
58164f ¤   ¤   sizeof(fileInfo), FileStandardInformation);
94af5a
6cdf44 ¤   if (!NT_SUCCESS(status))
c4889e ¤   ¤   derr = DualErr(kPGDMinorError_ZwQueryInfoFileFailed, status);
7faf5a
fc2361 ¤   if (derr.IsntError())
02c7a1 ¤   {
d95c99 ¤   ¤   (* pLength) = fileInfo.EndOfFile.QuadPart;
229371 ¤   }
34af5a
e133e3 ¤   return derr;
bdefe6 }
b0af5a
df9a65 // SetLength sets the length of the open file to the specified value.
12af5a
c92292 DualErr·
664889 File::SetLength(PGPInt64 length)
edbb36 {
e09457 ¤   DualErr¤¤   ¤   ¤   ¤   ¤   ¤   derr;
e3f14e ¤   FILE_END_OF_FILE_INFORMATION¤   eofInfo;
57ea98 ¤   IO_STATUS_BLOCK¤¤   ¤   ¤   ¤   ioStatus;
8aece6 ¤   NTSTATUS¤   ¤   ¤   ¤   ¤   ¤   status;
6eaf5a
a41148 ¤   pgpAssert(Opened());
56af5a
7b5594 ¤   eofInfo.EndOfFile.QuadPart = length;
7aaf5a
d38674 ¤   status = ZwSetInformationFile(mHandle, &ioStatus, &eofInfo,·
26a73b ¤   ¤   sizeof(eofInfo), FileEndOfFileInformation);
c6af5a
82df44 ¤   if (!NT_SUCCESS(status))
80c7a1 ¤   {
27d315 ¤   ¤   derr = DualErr(kPGDMinorError_ZwSetInfoFileFailed, status);
df9371 ¤   }
27af5a
5f33e3 ¤   return derr;
ceefe6 }
4baf5a
a2b5bf // GetLocalHostDrive returns the drive number of the volume that hosts this
85700f // file, but only if it is a local host.
a6af5a
805540 PGPUInt8
--a5b8 00019b38031401100f3 Page 3 of File.cpp
933387 File::GetLocalHostDrive()
09bb36 {
080fca ¤   pgpAssert(!IsUNCPath(mPath));
3eaf5a
3aa141 ¤   return DriveLetToNum(mPath[0]);
a0efe6 }
c5af5a
2939cd // GetPath returns a constant pointer to the pathname string.
f5af5a
0c03c3 LPCSTR·
abab91 File::GetPath()
3dbb36 {
87a07a ¤   return (LPCSTR) mPath;
faefe6 }
a2af5a
258a17 // SetPath sets the filename path variable.
bcaf5a
012292 DualErr·
d5f2a8 File::SetPath(LPCSTR path)
8bbb36 {
c87d36 ¤   DualErr derr;
44af5a
bee7de ¤   pgpAssert(!Opened());
69af5a
4a08f2 ¤   ClearPath();
b6f1f9 ¤   derr = DupeString(path, &mPath);
90af5a
db33e3 ¤   return derr;
d7efe6 }
89af5a
4f4588 // ClearPath clears the filename path variable.
beaf5a
e3c823 void·
e451b6 File::ClearPath()
fbbb36 {
f2e7de ¤   pgpAssert(!Opened());
bbaf5a
c10e6c ¤   if (mPath)
b5935f ¤   ¤   delete[] mPath;
53af5a
3f2185 ¤   mPath = NULL;
37efe6 }
8faf5a
21d143 // ComparePaths compares the passed pathname with the path of the opened File
1fa8d1 // object, returning TRUE if they refer to the same file.
0faf5a
ff77be PGPBoolean·
49b3e1 File::ComparePaths(LPCSTR path)
4abb36 {
dc1148 ¤   pgpAssert(Opened());
636b61 ¤   pgpAssertStrValid(mPath);
85639f ¤   pgpAssertStrValid(path);
2daf5a
0dc301 ¤   return (_stricmp(mPath, path) ? FALSE : TRUE);
1defe6 }
49af5a
90b285 // Open opens the file specified by 'path' with the flags specified by
8bc0f9 // 'flags'.
45af5a
812292 DualErr·
470858 File::Open(LPCSTR path, PGPUInt16 flags)
14bb36 {
6fbe41 ¤   DualErr¤¤   derr;
749429 ¤   KUstring¤   uniPath;
28fc8d ¤   NTSTATUS¤   status;
a7de96 ¤   PGPBoolean¤ allocedBlockBuf, denyRead, denyWrite, mustExist;
55af5a
ee1051 ¤   allocedBlockBuf = denyRead = denyWrite = mustExist = mWeSetPath = FALSE;
38af5a
37af55 ¤   mustExist¤  ¤   = (flags & kOF_MustExist¤   ? TRUE : FALSE);
e0a3f1 ¤   mIsReadOnly¤¤   = (flags & kOF_ReadOnly¤¤   ? TRUE : FALSE);
1926eb ·¤  denyRead¤   ¤   = (flags & kOF_DenyRead¤¤   ? TRUE : FALSE);
--81ae 00015e5f023401100f3 Page 4 of File.cpp
8b05b4 ¤   denyWrite¤  ¤   = (flags & kOF_DenyWrite¤   ? TRUE : FALSE);
ef30a4 ¤   mNoBuffering¤   = (flags & kOF_NoBuffering¤ ? TRUE : FALSE);
45af5a
a15d03 ¤   // Set the path.
d7b7e2 ¤   if (IsntNull(path))
9ac7a1 ¤   {
8cd8c9 ¤   ¤   pgpAssertStrValid(path);
80af5a
b04d20 ¤   ¤   derr = SetPath(path);
2b47dd ¤   ¤   mWeSetPath = derr.IsntError();
579371 ¤   }
6faf5a
c4ba4d ¤   // Convert path to unicode.
f12361 ¤   if (derr.IsntError())
08c7a1 ¤   {
978e01 ¤   ¤   if (IsUNCPath(mPath))
145b34 ¤   ¤   {
53d701 ¤   ¤   ¤   derr = AssignToUni(&uniPath, mPath + 2);
18af5a
899d3d ¤   ¤   ¤   if (derr.IsntError())
65f776 ¤   ¤   ¤   {
b7a825 ¤   ¤   ¤   ¤   derr = PrependToUni(&uniPath, kNTUNCLinkPathPrefix);
5fa3a6 ¤   ¤   ¤   }
930fe4 ¤   ¤   }
7d0e1d ¤   ¤   else
9b5b34 ¤   ¤   {
8eeace ¤   ¤   ¤   derr = AssignToUni(&uniPath, mPath);
7caf5a
459d3d ¤   ¤   ¤   if (derr.IsntError())
2af776 ¤   ¤   ¤   {
88f057 ¤   ¤   ¤   ¤   derr = PrependToUni(&uniPath, kNTLinkPathPrefix);
e5a3a6 ¤   ¤   ¤   }
ae0fe4 ¤   ¤   }
609371 ¤   }
f1af5a
9bfaa3 ¤   // Get block size of host if needed.
f52361 ¤   if (derr.IsntError())
30c7a1 ¤   {
1ad916 ¤   ¤   if (mNoBuffering)
725b34 ¤   ¤   {
e4347f ¤   ¤   ¤   if (!IsHostNetworked())
56f776 ¤   ¤   ¤   {
4f2f1b ¤   ¤   ¤   ¤   Volume vol;
47af5a
28ae89 ¤   ¤   ¤   ¤   derr = vol.AttachLocalVolume(DriveFromPath(mPath));
4faf5a
1d724e ¤   ¤   ¤   ¤   if (derr.IsntError())
c372c3 ¤   ¤   ¤   ¤   {
94cf31 ¤   ¤   ¤   ¤   ¤   mBlockSize = vol.GetBlockSize();
a4af5a
3104af ¤   ¤   ¤   ¤   ¤   // Can't be greater than PAGE_SIZE.
25a092 ¤   ¤   ¤   ¤   ¤   if (mBlockSize > PAGE_SIZE)
c92817 ¤   ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_BlockSizeNotSupported);
b92613 ¤   ¤   ¤   ¤   }
78af5a
3fad3b ¤   ¤   ¤   ¤   if (vol.AttachedToLocalVolume())
6bb50c ¤   ¤   ¤   ¤   ¤   vol.DetachLocalVolume();
1fa3a6 ¤   ¤   ¤   }
70bb8c ¤   ¤   ¤   else
d0f776 ¤   ¤   ¤   {
b2384c ¤   ¤   ¤   ¤   mBlockSize = kDefaultBlockSize;
58a3a6 ¤   ¤   ¤   }
ac0fe4 ¤   ¤   }
f59371 ¤   }
22af5a
f42b0f ¤   // Create block buffer if needed.
0e2361 ¤   if (derr.IsntError())
1fc7a1 ¤   {
a3d916 ¤   ¤   if (mNoBuffering)
015b34 ¤   ¤   {
db866a ¤   ¤   ¤   derr = GetByteBuffer(PAGE_SIZE, (PGPUInt8 **) &mBlockBuf);
15f671 ¤   ¤   ¤   allocedBlockBuf = derr.IsntError();
--a59b 0002395ed38401100f3 Page 5 of File.cpp
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
d42361 ¤   if (derr.IsntError())
b7c7a1 ¤   {
457b8f ¤   ¤   ACCESS_MASK¤¤   ¤   accessMask;
3e0298 ¤   ¤   IO_STATUS_BLOCK¤¤   ioStatus;
34a257 ¤   ¤   OBJECT_ATTRIBUTES¤  objAttribs;
39d306 ¤   ¤   PGPUInt32¤  ¤   ¤   createDisp, createOpts, shareAccess;
67af5a
795ced ¤   ¤   if (IsHostNetworked())
c99b05 ¤   ¤   ¤   ImpersonateToken();
3baf5a
3a5bae ¤   ¤   // Initialize object attributes
e56eb3 ¤   ¤   InitializeObjectAttributes(&objAttribs, uniPath,·
591af1 ¤   ¤   ¤   OBJ_CASE_INSENSITIVE, NULL, NULL);
72af5a
6238c5 ¤   ¤   // Set create options.
d9f3d8 ¤   ¤   createOpts = FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT;
4faf5a
79d916 ¤   ¤   if (mNoBuffering)
329890 ¤   ¤   ¤   createOpts |= FILE_NO_INTERMEDIATE_BUFFERING;
c5af5a
6e31b2 ¤   ¤   // Set access flags.
c967c7 ¤   ¤   accessMask = SYNCHRONIZE | FILE_READ_ACCESS | FILE_WRITE_ACCESS;
e1af5a
cbb342 ¤   ¤   if (mIsReadOnly)
1ff15c ¤   ¤   ¤   accessMask &= ~FILE_WRITE_ACCESS;
96af5a
55dc93 ¤   ¤   // Set share flags.
5e3d1d ¤   ¤   shareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
23af5a
f29c42 ¤   ¤   if (denyRead)
3dfa36 ¤   ¤   ¤   shareAccess &= ~FILE_SHARE_READ;
7caf5a
e6531d ¤   ¤   if (denyWrite)
b1f3ef ¤   ¤   ¤   shareAccess &= ~FILE_SHARE_WRITE;
08af5a
8e1e4f ¤   ¤   // Set the create disposition.
e303fb ¤   ¤   if (mustExist)
ec4773 ¤   ¤   ¤   createDisp = FILE_OPEN;
a80e1d ¤   ¤   else
65f6f4 ¤   ¤   ¤   createDisp = FILE_OPEN_IF;
1baf5a
a1764b ¤   ¤   // Open the file.
d7e7d8 ¤   ¤   status = ZwCreateFile(&mHandle, accessMask, &objAttribs, &ioStatus,·
438ab3 ¤   ¤   ¤   0, FILE_ATTRIBUTE_NORMAL, shareAccess, createDisp, createOpts,·
3e7a8f ¤   ¤   ¤   NULL, 0);
b0af5a
646412 ¤   ¤   if (!NT_SUCCESS(status))
9d99cf ¤   ¤   ¤   derr = DualErr(kPGDMinorError_ZwCreateFileFailed, status);
57af5a
9d5ced ¤   ¤   if (IsHostNetworked())
2e6e27 ¤   ¤   ¤   RevertToSelf();
6f9371 ¤   }
93af5a
2c4bb3 ¤   if (derr.IsError())
bbc7a1 ¤   {
37f815 ¤   ¤   if (allocedBlockBuf)
5c5b34 ¤   ¤   {
3fcb7f ¤   ¤   ¤   FreeByteBuffer(mBlockBuf);
1a0fe4 ¤   ¤   }
0daf5a
119906 ¤   ¤   if (mWeSetPath)
055b34 ¤   ¤   {
cef8a8 ¤   ¤   ¤   ClearPath();
02c3f4 ¤   ¤   ¤   mWeSetPath = FALSE;
390fe4 ¤   ¤   }
8c9371 ¤   }
b8af5a
e333e3 ¤   return derr;
23efe6 }
--b217 0001c449265401100f3 Page 6 of File.cpp
e0af5a
944a07 // Close closes a previously opened File object.
b9af5a
5e2292 DualErr·
7e6628 File::Close()
3abb36 {
0cbe41 ¤   DualErr¤¤   derr;
21fc8d ¤   NTSTATUS¤   status;
f7af5a
eb1148 ¤   pgpAssert(Opened());
92af5a
1d832d ¤   status = ZwClose(mHandle);
39af5a
20df44 ¤   if (!NT_SUCCESS(status))
f48ef4 ¤   ¤   derr = DualErr(kPGDMinorError_ZwCloseFailed, status);
03af5a
332361 ¤   if (derr.IsntError())
47c7a1 ¤   {
52d3b0 ¤   ¤   mHandle = NULL;
3baf5a
fbd916 ¤   ¤   if (mNoBuffering)
27cb7f ¤   ¤   ¤   FreeByteBuffer(mBlockBuf);
f2af5a
ff9906 ¤   ¤   if (mWeSetPath)
a25b34 ¤   ¤   {
eaf8a8 ¤   ¤   ¤   ClearPath();
57c3f4 ¤   ¤   ¤   mWeSetPath = FALSE;
5b0fe4 ¤   ¤   }
409371 ¤   }
6daf5a
6433e3 ¤   return derr;
89efe6 }
c8af5a
09555d // Read reads nBytes from the opened file at position pos (in bytes).
0baf5a
bb2292 DualErr·
cb2a44 File::Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
a8bb36 {
087d36 ¤   DualErr derr;
96af5a
b01148 ¤   pgpAssert(Opened());
0aaf5a
3848c5 ¤   if (IsHostNetworked())
9c365b ¤   ¤   ImpersonateToken();
3367c5 ¤
bc1ea3 ¤   if (mNoBuffering)
7b518b ¤   ¤   derr = ReadNoBuf(buf, pos, nBytes);
c50e24 ¤   else
dbd0f6 ¤   ¤   derr = ReadBuf(buf, pos, nBytes);
58af5a
d048c5 ¤   if (IsHostNetworked())
3a9842 ¤   ¤   RevertToSelf();
b9af5a
d933e3 ¤   return derr;
12efe6 }
a4af5a
0ca531 // Write writes nBytes from the opened file at position pos (in bytes).
31af5a
802292 DualErr·
e133ea File::Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
5bbb36 {
0c7d36 ¤   DualErr derr;
3aaf5a
651148 ¤   pgpAssert(Opened());
e151fe ¤   pgpAssert(!mIsReadOnly);
0baf5a
dd48c5 ¤   if (IsHostNetworked())
03365b ¤   ¤   ImpersonateToken();
7daf5a
7f2361 ¤   if (derr.IsntError())
e6c7a1 ¤   {
1cd916 ¤   ¤   if (mNoBuffering)
--4612 000e198d105401100f3 Page 7 of File.cpp
cdb6ff ¤   ¤   ¤   derr = WriteNoBuf(buf, pos, nBytes);
f50e1d ¤   ¤   else
bdff1f ¤   ¤   ¤   derr = WriteBuf(buf, pos, nBytes);
4a9371 ¤   }
5faf5a
de48c5 ¤   if (IsHostNetworked())
9e9842 ¤   ¤   RevertToSelf();
28af5a
e633e3 ¤   return derr;
69efe6 }
cdaf5a
68af5a
7090e1 //////////////////////////////////////
3a7f61 // Class File private member functions
6890e1 //////////////////////////////////////
20af5a
0c0cdc // ReadBuf reads nBytes from the opened file at position pos (in bytes),
952da4 // assuming the file is NOT opened in no-buffering mode.
cfaf5a
be2292 DualErr·
8bad83 File::ReadBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
16bb36 {
a39a95 ¤   DualErr¤¤   ¤   derr;
86671f ¤   IO_STATUS_BLOCK¤ioStatus;
6e8134 ¤   LARGE_INTEGER¤  bigPos;
e039be ¤   NTSTATUS¤   ¤   status;
25af5a
6db442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
44b27a ¤   pgpAssert(nBytes > 0);
281148 ¤   pgpAssert(Opened());
79af5a
220363 ¤   bigPos.QuadPart = pos;
17af5a
ec179e ¤   status = ZwReadFile(mHandle, NULL, NULL, NULL, &ioStatus, buf, nBytes,·
eb0e4c ¤   ¤   &bigPos, NULL);
8faf5a
07df44 ¤   if (!NT_SUCCESS(status))
426435 ¤   ¤   derr = DualErr(kPGDMinorError_ZwReadFileFailed, status);
60af5a
4f33e3 ¤   return derr;
07efe6 }
f4af5a
4839e5 // WriteBuf writes nBytes from the opened file at position pos (in bytes),·
3e2da4 // assuming the file is NOT opened in no-buffering mode.
aeaf5a
912292 DualErr·
b3f0c6 File::WriteBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
80bb36 {
ea9a95 ¤   DualErr¤¤   ¤   derr;
f6671f ¤   IO_STATUS_BLOCK¤ioStatus;
f18134 ¤   LARGE_INTEGER¤  bigPos;
5539be ¤   NTSTATUS¤   ¤   status;
1eaf5a
3ab442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
2db27a ¤   pgpAssert(nBytes > 0);
06af5a
bd1148 ¤   pgpAssert(Opened());
3351fe ¤   pgpAssert(!mIsReadOnly);
38af5a
150363 ¤   bigPos.QuadPart = pos;
d9af5a
fe4c28 ¤   status = ZwWriteFile(mHandle, NULL, NULL, NULL, &ioStatus, buf, nBytes,·
b90e4c ¤   ¤   &bigPos, NULL);
2aaf5a
e4df44 ¤   if (!NT_SUCCESS(status))
09cd55 ¤   ¤   derr = DualErr(kPGDMinorError_ZwWriteFileFailed, status);
4eaf5a
7133e3 ¤   return derr;
f5efe6 }
e2af5a
7f772a // ReadNoBuf reads nBytes from the opened file at position pos (in bytes),
e12d69 // assuming the file IS opened in no-buffering mode.
--b957 000dba9a69d401100f3 Page 8 of File.cpp
e0af5a
6f2292 DualErr·
5e8068 File::ReadNoBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
d9bb36 {
1f9a95 ¤   DualErr¤¤   ¤   derr;
07671f ¤   IO_STATUS_BLOCK¤ioStatus;
278134 ¤   LARGE_INTEGER¤  bigPos;
0939be ¤   NTSTATUS¤   ¤   status;
45d276 ¤   PGPUInt32¤  ¤   blocksInMiddle, bufPos;
2fd9cb ¤   PGPUInt64¤  ¤   blockFile;
b9af5a
04b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
04b27a ¤   pgpAssert(nBytes > 0);
0baf5a
511148 ¤   pgpAssert(Opened());
674792 ¤   pgpAssert(mNoBuffering);
1caf5a
c202d5 ¤   // The position (pos) and size (nBytes) variables are in bytes, but we
36b963 ¤   // are reading in blocks. What we have to do is handle the request in at
ba099d ¤   // most three separate pieces - a head, middle, and end.
edaf5a
e03fc7 ¤   bufPos = 0;
d4af5a
a22c38 ¤   if (pos%mBlockSize > 0)¤¤   ¤   // is there a head?
66c7a1 ¤   {
27cf6a ¤   ¤   PGPUInt32 headOffset, headSize;
84af5a
213423 ¤   ¤   // Now read in the head.
fe65af ¤   ¤   //
f834c7 ¤   ¤   // blockFile = block in the file containing the head.
69267e ¤   ¤   // headOffset = byte offset into blockFile where head starts
92a924 ¤   ¤   // headSize = size of the head, in bytes
0aaf5a
2a1afa ¤   ¤   blockFile¤  = pos/mBlockSize;
ce3cd8 ¤   ¤   headOffset¤ = (PGPUInt32) (pos%mBlockSize);
d62204 ¤   ¤   headSize¤   = min(nBytes, mBlockSize - headOffset);
c8af5a
5a554a ¤   ¤   derr = ReadBuf(mBlockBuf, blockFile*mBlockSize, mBlockSize);
c8af5a
43aa35 ¤   ¤   if (derr.IsntError())
4d5b34 ¤   ¤   {
83ac5c ¤   ¤   ¤   pgpCopyMemory(mBlockBuf + headOffset, buf, headSize);
d7af5a
104bf3 ¤   ¤   ¤   bufPos¤ = headSize;
481e59 ¤   ¤   ¤   pos¤¤   += headSize;
f1cc39 ¤   ¤   ¤   nBytes¤ -= headSize;
d20fe4 ¤   ¤   }
029371 ¤   }
41af5a
112061 ¤   // Read in the middle.
122361 ¤   if (derr.IsntError())
b8c7a1 ¤   {
289c6f ¤   ¤   blocksInMiddle = nBytes/mBlockSize;
b9af5a
bbf439 ¤   ¤   if (blocksInMiddle > 0)¤¤   // is there a middle?
fc5b34 ¤   ¤   {
2dcb6a ¤   ¤   ¤   // Read in all of the middle.
2e0415 ¤   ¤   ¤   //
48d7af ¤   ¤   ¤   // blockFile = block in the PGPdisk where this read begins
05af5a
0c7c59 ¤   ¤   ¤   blockFile = pos/mBlockSize;
e6af5a
fd34dd ¤   ¤   ¤   derr = ReadBuf(buf + bufPos, blockFile*mBlockSize,·
c14a8b ¤   ¤   ¤   ¤   blocksInMiddle*mBlockSize);
11af5a
079d3d ¤   ¤   ¤   if (derr.IsntError())
b9f776 ¤   ¤   ¤   {
c607f9 ¤   ¤   ¤   ¤   bufPos¤ += blocksInMiddle * mBlockSize;
59cdf5 ¤   ¤   ¤   ¤   nBytes¤ -= blocksInMiddle * mBlockSize;
358c82 ¤   ¤   ¤   ¤   pos¤¤   += blocksInMiddle * mBlockSize;
21a3a6 ¤   ¤   ¤   }
db0fe4 ¤   ¤   }
--9e5a 000972d41ef401100f3 Page 9 of File.cpp
a19371 ¤   }
9967c5 ¤
72e34f ¤   // Read in the tail.
352361 ¤   if (derr.IsntError())
09c7a1 ¤   {
7aa63d ¤   ¤   if (nBytes)¤¤   ¤   ¤   ¤   // is there a tail?¤
1b5b34 ¤   ¤   {
01ee47 ¤   ¤   ¤   // This read is very simple because we know the tail begins on a
150137 ¤   ¤   ¤   // block boundary.
780415 ¤   ¤   ¤   //
8df590 ¤   ¤   ¤   // blockFile = block in the file containing the tail.
22af5a
357c59 ¤   ¤   ¤   blockFile = pos/mBlockSize;
34af5a
8d523c ¤   ¤   ¤   derr = ReadBuf(mBlockBuf, blockFile*mBlockSize, mBlockSize);
d1af5a
269d3d ¤   ¤   ¤   if (derr.IsntError())
31f776 ¤   ¤   ¤   {
c65a04 ¤   ¤   ¤   ¤   pgpCopyMemory(mBlockBuf, buf + bufPos, nBytes);
efa3a6 ¤   ¤   ¤   }
880fe4 ¤   ¤   }
c69371 ¤   }
eeaf5a
3133e3 ¤   return derr;
83efe6 }
20af5a
56c894 // WriteNoBuf writes nBytes from the opened file at position pos (in bytes).
c82d69 // assuming the file IS opened in no-buffering mode.
b1af5a
932292 DualErr·
6d31d6 File::WriteNoBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
d4bb36 {
549a95 ¤   DualErr¤¤   ¤   derr;
89671f ¤   IO_STATUS_BLOCK¤ioStatus;
978134 ¤   LARGE_INTEGER¤  bigPos;
7f39be ¤   NTSTATUS¤   ¤   status;
5ed276 ¤   PGPUInt32¤  ¤   blocksInMiddle, bufPos;
0cd9cb ¤   PGPUInt64¤  ¤   blockFile;
74af5a
d6b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
00b27a ¤   pgpAssert(nBytes > 0);
a2af5a
b61148 ¤   pgpAssert(Opened());
4d51fe ¤   pgpAssert(!mIsReadOnly);
ed4792 ¤   pgpAssert(mNoBuffering);
d7af5a
b202d5 ¤   // The position (pos) and size (nBytes) variables are in bytes, but we
5290e0 ¤   // are writing in blocks. What we have to do is handle the request in at
ec099d ¤   // most three separate pieces - a head, middle, and end.
c1af5a
813fc7 ¤   bufPos = 0;
89af5a
9dbad0 ¤   if (pos%mBlockSize > 0)¤¤   // is there a head?
97c7a1 ¤   {
fecf6a ¤   ¤   PGPUInt32 headOffset, headSize;
e3af5a
305b1f ¤   ¤   // Now write out the head.
b165af ¤   ¤   //
126dbd ¤   ¤   // blockFile = block in the file file containing the head.
91267e ¤   ¤   // headOffset = byte offset into blockFile where head starts
52a924 ¤   ¤   // headSize = size of the head, in bytes
09af5a
3a1afa ¤   ¤   blockFile¤  = pos/mBlockSize;
d43cd8 ¤   ¤   headOffset¤ = (PGPUInt32) (pos%mBlockSize);
ac2204 ¤   ¤   headSize¤   = min(nBytes, mBlockSize - headOffset);
24af5a
82554a ¤   ¤   derr = ReadBuf(mBlockBuf, blockFile*mBlockSize, mBlockSize);
77af5a
1aaa35 ¤   ¤   if (derr.IsntError())
b75b34 ¤   ¤   {
ffe847 ¤   ¤   ¤   pgpCopyMemory(buf, mBlockBuf + headOffset, headSize);
97af5a
--a74d 0017c5f0a5a401100f3 Page 10 of File.cpp
a182cb ¤   ¤   ¤   derr = WriteBuf(mBlockBuf, blockFile*mBlockSize, mBlockSize);
e387c7 ¤   ¤   ¤
b74bf3 ¤   ¤   ¤   bufPos¤ = headSize;
831e59 ¤   ¤   ¤   pos¤¤   += headSize;
4acc39 ¤   ¤   ¤   nBytes¤ -= headSize;
e20fe4 ¤   ¤   }
f69371 ¤   }
c3af5a
4c74c9 ¤   // Write out the middle.
af0b22 ¤   if (derr.IsntError())¤  ¤   // is there a middle?
fac7a1 ¤   {
279c6f ¤   ¤   blocksInMiddle = nBytes/mBlockSize;
17af5a
b48fa7 ¤   ¤   if (blocksInMiddle > 0)
695b34 ¤   ¤   {
0b3e7b ¤   ¤   ¤   // Write out all of the middle.
080415 ¤   ¤   ¤   //
08128c ¤   ¤   ¤   // blockFile = block in the file where this write begins
a2af5a
c47c59 ¤   ¤   ¤   blockFile = pos/mBlockSize;
13af5a
53bdf1 ¤   ¤   ¤   derr = WriteBuf(buf + bufPos, blockFile*mBlockSize,·
194a8b ¤   ¤   ¤   ¤   blocksInMiddle*mBlockSize);
faaf5a
b19d3d ¤   ¤   ¤   if (derr.IsntError())
f3f776 ¤   ¤   ¤   {
6007f9 ¤   ¤   ¤   ¤   bufPos¤ += blocksInMiddle * mBlockSize;
dacdf5 ¤   ¤   ¤   ¤   nBytes¤ -= blocksInMiddle * mBlockSize;
a78c82 ¤   ¤   ¤   ¤   pos¤¤   += blocksInMiddle * mBlockSize;
d9a3a6 ¤   ¤   ¤   }
0d0fe4 ¤   ¤   }
389371 ¤   }
8d67c5 ¤
533c82 ¤   // Write out the tail.
202361 ¤   if (derr.IsntError())
2cc7a1 ¤   {
98ffb6 ¤   ¤   if (nBytes)¤¤   ¤   ¤   // is there a tail?¤
145b34 ¤   ¤   {
d7ee1d ¤   ¤   ¤   // This write is very simple because we know the tail begins on a
d90137 ¤   ¤   ¤   // block boundary.
490415 ¤   ¤   ¤   //
95fc4b ¤   ¤   ¤   // blockFile = the block in the file containing the tail.
6baf5a
4e523c ¤   ¤   ¤   derr = ReadBuf(mBlockBuf, blockFile*mBlockSize, mBlockSize);
6eaf5a
f89d3d ¤   ¤   ¤   if (derr.IsntError())
b1f776 ¤   ¤   ¤   {
e933f9 ¤   ¤   ¤   ¤   pgpCopyMemory(buf, mBlockBuf, nBytes);
12af5a
bbfb81 ¤   ¤   ¤   ¤   derr = WriteBuf(mBlockBuf, blockFile*mBlockSize, mBlockSize);
34a3a6 ¤   ¤   ¤   }
a40fe4 ¤   ¤   }
649371 ¤   }
81af5a
3633e3 ¤   return derr;
7cefe6 }
--ffbc 000abceb620401100f4 Page 1 of File.h
541bc3 //////////////////////////////////////////////////////////////////////////////
ebdd5e // File.h
fb465d //
8329fa // Declaration of class File.
da1bc3 //////////////////////////////////////////////////////////////////////////////
d4af5a
4c22be // $Id: File.h,v 1.1.2.9 1998/08/07 01:20:04 nryan Exp $
3eaf5a
d0cbce // Copyright (C) 1998 by Network Associates, Inc.
2671ae // All rights reserved.
cdaf5a
069f22 #ifndef Included_File_h¤// [
13b6cf #define Included_File_h
35af5a
7a3a85 #include "DualErr.h"
f5af5a
91af5a
fd09b7 ////////////
65e738 // Constants
3809b7 ////////////
33af5a
46f624 // These are the flags for File::Open.
de5cea const PGPUInt16¤kOF_MustExist¤  = 0x0001;
bda164 const PGPUInt16¤kOF_ReadOnly¤   = 0x0002;
054c74 const PGPUInt16¤kOF_DenyRead¤   = 0x0004;
230b3e const PGPUInt16¤kOF_DenyWrite¤  = 0x0008;
c2c11c const PGPUInt16¤kOF_NoBuffering¤= 0x00010;
92af5a
00af5a
a333ec /////////////
bf6a85 // Class File
4d33ec /////////////
61af5a
7d5c0c // Class File must process all requests in its own separate thread due to the
e40f0b // fact that handles are only valid within a single thread context.
d3af5a
64196f class File
8ebb36 {
b05ed4 public:
f56a97 ¤   ¤   ¤   ¤   File();
13edbc ¤   virtual¤¤   ~File();
38af5a
1f1de3 ¤   PGPBoolean¤ IsHostNetworked();
b695cc ¤   PGPBoolean¤ IsPathSet();
02793d ¤   PGPBoolean¤ IsReadOnly();
3d9981 ¤   PGPBoolean¤ Opened();
48af5a
96c6d2 ¤   DualErr¤¤   GetLength(PGPUInt64 *pLength);
c69a10 ¤   DualErr¤¤   SetLength(PGPInt64 length);
a0af5a
907bab ¤   PGPUInt8¤   GetLocalHostDrive();
52af5a
beb57c ¤   LPCSTR¤ ¤   GetPath();
221b41 ¤   DualErr¤¤   SetPath(LPCSTR path);
78ad62 ¤   void¤   ¤   ClearPath();
cbaf5a
28edd3 ¤   PGPBoolean¤ ComparePaths(LPCSTR path);
b2af5a
ccb043 ¤   DualErr¤¤   Open(LPCSTR path = NULL, PGPUInt16 flags = NULL);
52112b ¤   DualErr¤¤   Close();
f5af5a
c9b825 ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
b3b00c ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
36af5a
e80fb9 private:
068ae0 ¤   HANDLE¤ ¤   mHandle;¤   ¤   ¤   // handle for the file
a0d31b ¤   LPSTR¤  ¤   mPath;¤ ¤   ¤   ¤   // pathname to the file
27af5a
6e340f ¤   PGPBoolean¤ mNoBuffering;¤  ¤   // opened with no buffering?
bf4e31 ¤   PGPUInt16¤  mBlockSize;¤¤   ¤   // block size of host
1f661c ¤   PGPUInt8¤   *mBlockBuf;¤¤   ¤   // block buffer
abaf5a
--b277 001e7495dea401100f4 Page 2 of File.h
b6b1de ¤   PGPBoolean¤ mIsReadOnly;¤   ¤   // opened in read-only mode?
9dbe68 ¤   PGPBoolean¤ mWeSetPath;¤¤   ¤   // set path in Open()?
79af5a
946f17 ¤   DualErr¤¤   ReadBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
b23ef2 ¤   DualErr¤¤   WriteBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
6eaf5a
5f73ba ¤   DualErr¤¤   ReadNoBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
e5a797 ¤   DualErr¤¤   WriteNoBuf(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
1b82f7 };
f7af5a
e748ae #endif¤ // ] Included_File_h
--7a8c 001e7523afa401100f5 Page 1 of Function.h
541bc3 //////////////////////////////////////////////////////////////////////////////
22be95 // Function.h
77465d //
9b86f3 // Defines driver functions to be handled by PGPdisk.
211bc3 //////////////////////////////////////////////////////////////////////////////
2daf5a
5acc1d // $Id: Function.h,v 1.1.4.6 1998/07/23 00:49:07 nryan Exp $
d2af5a
cbcbce // Copyright (C) 1998 by Network Associates, Inc.
3371ae // All rights reserved.
61af5a
218264 #ifndef Included_Functions_h¤   // [
b10b71 #define Included_Functions_h
7faf5a
28af5a
0209b7 ////////////
5fe738 // Constants
2009b7 ////////////
a7af5a
5bbbb3 #define DRIVER_FUNCTION_UNLOAD
d05e7f #define DRIVER_FUNCTION_CLEANUP
d9cd77 #define DRIVER_FUNCTION_CLOSE
677f25 #define DRIVER_FUNCTION_CREATE
0129a6 #define DRIVER_FUNCTION_DEVICE_CONTROL
0b1767 #define DRIVER_FUNCTION_READ
188d0c #define DRIVER_FUNCTION_WRITE
eb9cc2 #define DRIVER_FUNCTION_DISPATCH_FILTERING
78af5a
e75d0e #endif // Included_Functions_h
--3a11 0017e3ceded401100f6 Page 1 of Globals.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b6c9cd // Globals.h
73465d //
ca8398 // Declarations for global variables used by the driver.
4a1bc3 //////////////////////////////////////////////////////////////////////////////
59af5a
c7185c // $Id: Globals.h,v 1.1.2.6 1998/07/06 08:57:48 nryan Exp $
41af5a
72cbce // Copyright (C) 1998 by Network Associates, Inc.
d171ae // All rights reserved.
8caf5a
af7e7c #ifndef Included_Globals_h¤ // [
c280bb #define Included_Globals_h
d7af5a
76e0ee #include "CPGPdiskInterface.h"
9daf5a
0aaf5a
75c7c6 ///////////////////////////////
32269b // Global variable declarations
45c7c6 ///////////////////////////////
a6af5a
50812d // All of the global variables are defined in CPGPdiskDriver.cpp.
9daf5a
1db77b extern CPGPdiskInterface *Interface;¤   // pointer to the interface object
02af5a
7e3932 #endif¤ // ] Included_Globals_h
--026a 0001bed444a401100f7 Page 1 of KernelModeUtils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
30b597 // KernelModeUtils.cpp
98465d //
a44681 // Kernel-Mode utility functions.
d21bc3 //////////////////////////////////////////////////////////////////////////////
cbaf5a
be086d // $Id: KernelModeUtils.cpp,v 1.1.2.17 1998/08/10 07:41:58 nryan Exp $
5daf5a
55cbce // Copyright (C) 1998 by Network Associates, Inc.
1471ae // All rights reserved.
d2af5a
4ed7a1 #include <vdw.h>
9c8fe5 #include <Devioctl.h>
6eaf5a
939bcf #include "Required.h"
60bfe9 #include "UtilityFunctions.h"
feaf5a
d7f1f6 #include "KernelModeUtils.h"
74f037 #include "File.h"
b9c411 #include "Globals.h"
602561 #include "Volume.h"
0eaf5a
48af5a
b583f5 ///////////////////////////
35fab6 // String utility functions
3783f5 ///////////////////////////
f1af5a
749acc // UniToAnsi converts a Unicode string to an ANSI string.
5aaf5a
c82292 DualErr·
4b3d5e UniToAnsi(KUstring *uniString, LPSTR *string)
78bb36 {
e41432 ¤   ANSI_STRING¤ansiString;
18be41 ¤   DualErr¤¤   derr;
6bfc8d ¤   NTSTATUS¤   status;
cf0d12 ¤   PGPBoolean¤ allocedString;
c74153 ¤   PGPUInt16¤  length;
8baf5a
46ff17 ¤   pgpAssertAddrValid(uniString, KUstring);
efb744 ¤   pgpAssertAddrValid(string, char);
fdaf5a
ef6d2f ¤   length = uniString->Length() + 1;
f4af5a
369665 ¤   // Get space for new string.
1fb95a ¤   ansiString.Buffer = new char[length];
0daf5a
db2962 ¤   if (IsNull(ansiString.Buffer))
9aecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
cbaf5a
bd7c79 ¤   allocedString = derr.IsntError();
34af5a
fc20b1 ¤   // Perform the conversion.
bf2361 ¤   if (derr.IsntError())
b7c7a1 ¤   {
e8b1e9 ¤   ¤   ansiString.MaximumLength¤   = length;
1670d2 ¤   ¤   ansiString.Length¤  ¤   ¤   = length - 1;
95af5a
9c9a0d ¤   ¤   status = RtlUnicodeStringToAnsiString(&ansiString, (* uniString),·
8ad54e ¤   ¤   ¤   FALSE);
5caf5a
436412 ¤   ¤   if (!NT_SUCCESS(status))
25c8f4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RtlUniToAnsiFailed, status);
ed9371 ¤   }
4baf5a
942c06 ¤   // Output the string.
7c2361 ¤   if (derr.IsntError())
c6c7a1 ¤   {
6d9ae2 ¤   ¤   (* string) = ansiString.Buffer;
859371 ¤   }
3faf5a
d94bb3 ¤   if (derr.IsError())
1bc7a1 ¤   {
--c905 000bf7df616401100f7 Page 2 of KernelModeUtils.cpp
d72e55 ¤   ¤   if (allocedString)
134a8d ¤   ¤   ¤   delete[] ansiString.Buffer;
f69371 ¤   }
e2af5a
3933e3 ¤   return derr;
d7efe6 }
c7af5a
2eddf8 // AssignToUni (... PUNICODE_STRING inUniString) assigns one unicode string
7068d1 // to another.
acaf5a
b32292 DualErr·
e293fc AssignToUni(
e9c860 ¤   KUstring¤   ¤   *outUniString,·
65059e ¤   PUNICODE_STRING¤inUniString)
c9bb36 {
0ebe41 ¤   DualErr¤¤   derr;
6dfc8d ¤   NTSTATUS¤   status;
554153 ¤   PGPUInt16¤  length;
16af5a
7f8865 ¤   pgpAssertAddrValid(outUniString, KUstring);
99a4d9 ¤   pgpAssertAddrValid(inUniString, UNICODE_STRING);
56af5a
3b7e5a ¤   length = inUniString->Length/sizeof(WCHAR) + 1;
84af5a
14efa9 ¤   // Allocate more space if necessary.
dcb991 ¤   if (length > outUniString->MaximumLength())
6bc7a1 ¤   {
9578aa ¤   ¤   status =·
33a346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
540af0 ¤   ¤   ¤   ¤   NonPagedPool);
ddaf5a
726412 ¤   ¤   if (!NT_SUCCESS(status))
8952aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
a79371 ¤   }
d9af5a
fe1686 ¤   // Perform the assignment.
5c2361 ¤   if (derr.IsntError())
2bc7a1 ¤   {
f73e44 ¤   ¤   status = outUniString->Assign(KUstring(inUniString, FALSE));
65af5a
9a6412 ¤   ¤   if (!NT_SUCCESS(status))
1dd2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
4e9371 ¤   }
74af5a
4a33e3 ¤   return derr;
f7efe6 }
8caf5a
4cf6e7 // AssignToUni (... LPCWSTR inUniString) assigns one unicode string to
9e09f9 // another.
c4af5a
9b2292 DualErr·
e393fc AssignToUni(
69d275 ¤   KUstring¤   *outUniString,·
b87abd ¤   LPCWSTR¤¤   inUniString)
46bb36 {
9ebe41 ¤   DualErr¤¤   derr;
77fc8d ¤   NTSTATUS¤   status;
524153 ¤   PGPUInt16¤  length;
e0af5a
838865 ¤   pgpAssertAddrValid(outUniString, KUstring);
5393a5 ¤   pgpAssertAddrValid(inUniString, WCHAR);
52af5a
1ece71 ¤   length = wcslen(inUniString) + 1;
c1af5a
4eefa9 ¤   // Allocate more space if necessary.
33b991 ¤   if (length > outUniString->MaximumLength())
94c7a1 ¤   {
c778aa ¤   ¤   status =·
a8a346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
6a1ed8 ¤   ¤   ¤   NonPagedPool);
08af5a
bf6412 ¤   ¤   if (!NT_SUCCESS(status))
--5cc2 00027d8ba53401100f7 Page 3 of KernelModeUtils.cpp
dc52aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
2f9371 ¤   }
74af5a
e71686 ¤   // Perform the assignment.
b12361 ¤   if (derr.IsntError())
92c7a1 ¤   {
a9e4b1 ¤   ¤   status = outUniString->Assign(inUniString);
19af5a
d36412 ¤   ¤   if (!NT_SUCCESS(status))
f8d2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
c59371 ¤   }
14af5a
ed33e3 ¤   return derr;
6aefe6 }
b8af5a
c11e26 // AssignToUni (... LPCSTR inString) assigns an ANSI string to a unicode
a3e112 // string.
64af5a
a52292 DualErr·
0593fc AssignToUni(
acd275 ¤   KUstring¤   *outUniString,·
eff4ea ¤   LPCSTR¤ ¤   inString)
0ebb36 {
3f1432 ¤   ANSI_STRING¤ansiString;
ffbe41 ¤   DualErr¤¤   derr;
82fc8d ¤   NTSTATUS¤   status;
eb4153 ¤   PGPUInt16¤  length;
a2af5a
f79115 ¤   pgpAssertStrValid(inString);
ac8865 ¤   pgpAssertAddrValid(outUniString, KUstring);
7daf5a
88b1a6 ¤   length = strlen(inString) + 1;
aeaf5a
abefa9 ¤   // Allocate more space if necessary.
d4b991 ¤   if (length > outUniString->MaximumLength())
6bc7a1 ¤   {
1578aa ¤   ¤   status =·
e6a346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
e10af0 ¤   ¤   ¤   ¤   NonPagedPool);
97af5a
816412 ¤   ¤   if (!NT_SUCCESS(status))
c152aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
1d9371 ¤   }
4caf5a
5d20b1 ¤   // Perform the conversion.
732361 ¤   if (derr.IsntError())
b0c7a1 ¤   {
05de1d ¤   ¤   RtlInitAnsiString(&ansiString, inString);
bdaf5a
22d297 ¤   ¤   status = RtlAnsiStringToUnicodeString((* outUniString), &ansiString,·
acd54e ¤   ¤   ¤   FALSE);
74af5a
026412 ¤   ¤   if (!NT_SUCCESS(status))
7102a4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RtlAnsiToUniFailed, status);
f09371 ¤   }
54af5a
1833e3 ¤   return derr;
71efe6 }
17af5a
1269fd // AppendToUni (... PUNICODE_STRING inUniString) appends one unicode string
2668d1 // to another.
dcaf5a
cf2292 DualErr·
e127f0 AppendToUni(
b8c860 ¤   KUstring¤   ¤   *outUniString,·
68059e ¤   PUNICODE_STRING¤inUniString)
81bb36 {
cbbe41 ¤   DualErr¤¤   derr;
79fc8d ¤   NTSTATUS¤   status;
de4153 ¤   PGPUInt16¤  length;
0daf5a
278865 ¤   pgpAssertAddrValid(outUniString, KUstring);
--46b0 00095f5c047401100f7 Page 4 of KernelModeUtils.cpp
00a4d9 ¤   pgpAssertAddrValid(inUniString, UNICODE_STRING);
b0af5a
22c8b0 ¤   length = outUniString->Length() + inUniString->Length/sizeof(WCHAR) + 1;
8baf5a
58efa9 ¤   // Allocate more space if necessary.
4cb991 ¤   if (length > outUniString->MaximumLength())
c6c7a1 ¤   {
a278aa ¤   ¤   status =·
b3a346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
a70af0 ¤   ¤   ¤   ¤   NonPagedPool);
96af5a
166412 ¤   ¤   if (!NT_SUCCESS(status))
f052aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
ff9371 ¤   }
65af5a
196846 ¤   // Perform the append.
aa2361 ¤   if (derr.IsntError())
bec7a1 ¤   {
0105b3 ¤   ¤   status = outUniString->Append(KUstring(inUniString, FALSE));
ebaf5a
1f6412 ¤   ¤   if (!NT_SUCCESS(status))
61d2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
919371 ¤   }
06af5a
1333e3 ¤   return derr;
a8efe6 }
5daf5a
1451f7 // AppendToUni (... LPCWSTR inUniString) appends one unicode string to
8009f9 // another.
36af5a
cc2292 DualErr·
8727f0 AppendToUni(
34d275 ¤   KUstring¤   *outUniString,·
397abd ¤   LPCWSTR¤¤   inUniString)
d1bb36 {
16be41 ¤   DualErr¤¤   derr;
0efc8d ¤   NTSTATUS¤   status;
a94153 ¤   PGPUInt16¤  length;
cbaf5a
c98865 ¤   pgpAssertAddrValid(outUniString, KUstring);
0993a5 ¤   pgpAssertAddrValid(inUniString, WCHAR);
05af5a
e30b71 ¤   length = outUniString->Length() + wcslen(inUniString) + 1;
c0af5a
97efa9 ¤   // Allocate more space if necessary.
1ab991 ¤   if (length > outUniString->MaximumLength())
33c7a1 ¤   {
4a78aa ¤   ¤   status =·
a6a346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
880af0 ¤   ¤   ¤   ¤   NonPagedPool);
4eaf5a
db6412 ¤   ¤   if (!NT_SUCCESS(status))
9552aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
039371 ¤   }
ceaf5a
126846 ¤   // Perform the append.
7f2361 ¤   if (derr.IsntError())
d9c7a1 ¤   {
a7e0f2 ¤   ¤   status = outUniString->Append(inUniString);
dbaf5a
276412 ¤   ¤   if (!NT_SUCCESS(status))
53d2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
859371 ¤   }
7caf5a
9f33e3 ¤   return derr;
19efe6 }
63af5a
e0695d // AppendToUni (... LPCSTR inString) appends an ANSI string to a unicode
1ce112 // string.
b3af5a
2c2292 DualErr·
9527f0 AppendToUni(
--d386 000c5b70e25401100f7 Page 5 of KernelModeUtils.cpp
17d275 ¤   KUstring¤   *outUniString,·
daf4ea ¤   LPCSTR¤ ¤   inString)
febb36 {
75be41 ¤   DualErr¤¤   derr;
4dded9 ¤   KUstring¤   tempUniString;
a1fc8d ¤   NTSTATUS¤   status;
064153 ¤   PGPUInt16¤  length;
f4af5a
fb9115 ¤   pgpAssertStrValid(inString);
5a8865 ¤   pgpAssertAddrValid(outUniString, KUstring);
c8af5a
6060f6 ¤   length = outUniString->Length() + strlen(inString) + 1;
bdaf5a
7fefa9 ¤   // Allocate more space if necessary.
1bb991 ¤   if (length > outUniString->MaximumLength())
29c7a1 ¤   {
ae78aa ¤   ¤   status =·
6fa346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
780af0 ¤   ¤   ¤   ¤   NonPagedPool);
e9af5a
d56412 ¤   ¤   if (!NT_SUCCESS(status))
2352aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
c69371 ¤   }
f7af5a
0020b1 ¤   // Perform the conversion.
882361 ¤   if (derr.IsntError())
c9c7a1 ¤   {
aea507 ¤   ¤   derr = AssignToUni(&tempUniString, inString);
049371 ¤   }
04af5a
4d7ff7 ¤   // Perform the append
f52361 ¤   if (derr.IsntError())
fec7a1 ¤   {
4c7609 ¤   ¤   status = outUniString->Append(tempUniString);
faaf5a
7b6412 ¤   ¤   if (!NT_SUCCESS(status))
a8d2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
959371 ¤   }
9faf5a
e933e3 ¤   return derr;
d8efe6 }
01af5a
b4e081 // PrependToUni (... PUNICODE_STRING inUniString) prepends one unicode string
4e68d1 // to another.
45af5a
252292 DualErr·
3ec634 PrependToUni(
bbc860 ¤   KUstring¤   ¤   *outUniString,·
e0059e ¤   PUNICODE_STRING¤inUniString)
16bb36 {
68be41 ¤   DualErr¤¤   derr;
d9ded9 ¤   KUstring¤   tempUniString;
b5fc8d ¤   NTSTATUS¤   status;
ef4153 ¤   PGPUInt16¤  length;
7baf5a
5f8865 ¤   pgpAssertAddrValid(outUniString, KUstring);
85a4d9 ¤   pgpAssertAddrValid(inUniString, UNICODE_STRING);
c7af5a
20c8b0 ¤   length = outUniString->Length() + inUniString->Length/sizeof(WCHAR) + 1;
c7af5a
6befa9 ¤   // Allocate more space if necessary.
9cb991 ¤   if (length > outUniString->MaximumLength())
68c7a1 ¤   {
9a78aa ¤   ¤   status =·
2ca346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
880af0 ¤   ¤   ¤   ¤   NonPagedPool);
5aaf5a
2f6412 ¤   ¤   if (!NT_SUCCESS(status))
2e52aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
579371 ¤   }
b8af5a
c5804e ¤   // Prepare temp variable.
--b714 00008c2d04b401100f7 Page 6 of KernelModeUtils.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
328c28 ¤   ¤   derr = AssignToUni(&tempUniString, (* outUniString));
939371 ¤   }
b7af5a
e85138 ¤   // Prepare output variable.
072361 ¤   if (derr.IsntError())
c7c7a1 ¤   {
1e68f7 ¤   ¤   derr = AssignToUni(outUniString, inUniString);
b49371 ¤   }
d7af5a
2a8846 ¤   // Perform the prepend.
6d2361 ¤   if (derr.IsntError())
8fc7a1 ¤   {
5b7f49 ¤   ¤   status = outUniString->Append(KUstring(tempUniString, FALSE));
f9af5a
136412 ¤   ¤   if (!NT_SUCCESS(status))
6dd2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
5d9371 ¤   }
18af5a
6f33e3 ¤   return derr;
00efe6 }
deaf5a
0dde5a // PrependToUni (... LPCWSTR inUniString) prepends one unicode string to
7a09f9 // another.
96af5a
182292 DualErr·
7bc634 PrependToUni(
45d275 ¤   KUstring¤   *outUniString,·
fe7abd ¤   LPCWSTR¤¤   inUniString)
f8bb36 {
eabe41 ¤   DualErr¤¤   derr;
ddded9 ¤   KUstring¤   tempUniString;
e2fc8d ¤   NTSTATUS¤   status;
964153 ¤   PGPUInt16¤  length;
e2af5a
828865 ¤   pgpAssertAddrValid(outUniString, KUstring);
e393a5 ¤   pgpAssertAddrValid(inUniString, WCHAR);
62af5a
530b71 ¤   length = outUniString->Length() + wcslen(inUniString) + 1;
29af5a
bdefa9 ¤   // Allocate more space if necessary.
e1b991 ¤   if (length > outUniString->MaximumLength())
fac7a1 ¤   {
a30123 ¤   ¤   status = outUniString->GrowMaxBy(length -·
7316fe ¤   ¤   ¤   outUniString->MaximumLength(), NonPagedPool);
89af5a
ba6412 ¤   ¤   if (!NT_SUCCESS(status))
b452aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
009371 ¤   }
27af5a
36804e ¤   // Prepare temp variable.
b52361 ¤   if (derr.IsntError())
dac7a1 ¤   {
cd8c28 ¤   ¤   derr = AssignToUni(&tempUniString, (* outUniString));
df9371 ¤   }
65af5a
ee5138 ¤   // Prepare output variable.
6d2361 ¤   if (derr.IsntError())
15c7a1 ¤   {
5c68f7 ¤   ¤   derr = AssignToUni(outUniString, inUniString);
b09371 ¤   }
0daf5a
b48846 ¤   // Perform the prepend.
782361 ¤   if (derr.IsntError())
f6c7a1 ¤   {
667609 ¤   ¤   status = outUniString->Append(tempUniString);
d1af5a
aa6412 ¤   ¤   if (!NT_SUCCESS(status))
4ed2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
af9371 ¤   }
08af5a
--47a6 0001f1cbc57401100f7 Page 7 of KernelModeUtils.cpp
dd33e3 ¤   return derr;
a2efe6 }
c9af5a
1232c6 // PrependToUni (... LPCSTR inString) prepends an ANSI string to a unicode
1be112 // string.
5baf5a
492292 DualErr·
68c634 PrependToUni(
6dd275 ¤   KUstring¤   *outUniString,·
64f4ea ¤   LPCSTR¤ ¤   inString)
43bb36 {
e4be41 ¤   DualErr¤¤   derr;
ccded9 ¤   KUstring¤   tempUniString;
44fc8d ¤   NTSTATUS¤   status;
db4153 ¤   PGPUInt16¤  length;
3caf5a
1a9115 ¤   pgpAssertStrValid(inString);
5e8865 ¤   pgpAssertAddrValid(outUniString, KUstring);
51af5a
a360f6 ¤   length = outUniString->Length() + strlen(inString) + 1;
e6af5a
c2efa9 ¤   // Allocate more space if necessary.
4ab991 ¤   if (length > outUniString->MaximumLength())
8fc7a1 ¤   {
6d78aa ¤   ¤   status =·
26a346 ¤   ¤   ¤   outUniString->GrowMaxBy(length - outUniString->MaximumLength(),·
250af0 ¤   ¤   ¤   ¤   NonPagedPool);
8eaf5a
6e6412 ¤   ¤   if (!NT_SUCCESS(status))
f552aa ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory, status);
b09371 ¤   }
d1af5a
5a5138 ¤   // Prepare output variable.
0a2361 ¤   if (derr.IsntError())
4cc7a1 ¤   {
fc1e92 ¤   ¤   derr = AssignToUni(outUniString, inString);
329371 ¤   }
07af5a
53804e ¤   // Prepare temp variable.
ae2361 ¤   if (derr.IsntError())
62c7a1 ¤   {
798c28 ¤   ¤   derr = AssignToUni(&tempUniString, (* outUniString));
499371 ¤   }
a6af5a
e87ff7 ¤   // Perform the append
c12361 ¤   if (derr.IsntError())
e7c7a1 ¤   {
bc7609 ¤   ¤   status = outUniString->Append(tempUniString);
ebaf5a
b66412 ¤   ¤   if (!NT_SUCCESS(status))
1ad2a9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UniStringOpFailed, status);
639371 ¤   }
45af5a
a233e3 ¤   return derr;
ddefe6 }
48af5a
c3af5a
5319ee /////////////////////////////////
7c7246 // Device/drive utility functions
9b19ee /////////////////////////////////
1baf5a
208b10 // MakePathToDrive returns a link pathname corresponding to the given
4f1bad // drive.
c5af5a
6a2292 DualErr·
a6be62 MakePathToDrive(PGPUInt8 drive, KUstring *outPath)
4ebb36 {
cf945d ¤   DualErr¤derr;
eadbb1 ¤   char¤   driveLet[3];
89af5a
d3aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
1f49d8 ¤   pgpAssertAddrValid(outPath, KUstring);
--3391 0002adfc4d0401100f7 Page 8 of KernelModeUtils.cpp
e0af5a
f3fccc ¤   // Initialize the pathname.
c7157b ¤   driveLet[0] = DriveNumToLet(drive);
672dfc ¤   driveLet[1] = ':';
63edc0 ¤   driveLet[2] = '\0';
ccaf5a
82e0f4 ¤   derr = AssignToUni(outPath, driveLet);
dcaf5a
7be81b ¤   // Prepend the link qualifier.
d22361 ¤   if (derr.IsntError())
f1c7a1 ¤   {
c4b6e4 ¤   ¤   derr = PrependToUni(outPath, kNTLinkPathPrefix);
aa9371 ¤   }
18af5a
dc33e3 ¤   return derr;
12efe6 }
9baf5a
4d2e2b // IsValidDeviceName returns TRUE if the specified string refers to a valid
8aff02 // device, FALSE otherwise.
8baf5a
4177be PGPBoolean·
626a48 IsValidDeviceName(PUNICODE_STRING deviceName)
b7bb36 {
b27038 ¤   PDEVICE_OBJECT¤ deviceObject;
d5e7c3 ¤   PFILE_OBJECT¤   fileObject;
b039be ¤   NTSTATUS¤   ¤   status;
85af5a
2904a2 ¤   pgpAssertAddrValid(deviceName, UNICODE_STRING);
1eaf5a
b297e0 ¤   status = IoGetDeviceObjectPointer(deviceName, FILE_READ_DATA,·
16df6e ¤   ¤   &fileObject, &deviceObject);
c3af5a
f043d7 ¤   if (NT_SUCCESS(status))
9dc7a1 ¤   {
0c4b76 ¤   ¤   ObDereferenceObject(fileObject);
ed836c ¤   ¤   return TRUE;
c29371 ¤   }
6a0e24 ¤   else
c0c7a1 ¤   {
4bdb6c ¤   ¤   return (status != STATUS_OBJECT_NAME_NOT_FOUND);
ee9371 ¤   }
2befe6 }
1caf5a
8e0bc9 // IsFileInUseByReader returns TRUE if someone has opened the specified file
7b476d // with read access, FALSE otherwise.
01af5a
ff77be PGPBoolean·
36f01a IsFileInUseByReader(LPCSTR path)
bcbb36 {
11fec2 ¤   File¤   existingFile;
e0945d ¤   DualErr¤derr;
0caf5a
c6639f ¤   pgpAssertStrValid(path);
13af5a
5d862d ¤   derr = existingFile.Open(path,·
5f71ac ¤   ¤   kOF_ReadOnly | kOF_DenyRead | kOF_MustExist);
c4af5a
1a12c1 ¤   if (existingFile.Opened())
f8c7a1 ¤   {
511af7 ¤   ¤   existingFile.Close();
259371 ¤   }
69af5a
7f8864 ¤   return derr.IsError();
1cefe6 }
53af5a
062939 // IsFileInUseByWriter returns TRUE if someone has opened the specified file
b2ad9f // with write access, FALSE otherwise.
feaf5a
3d77be PGPBoolean·
dc214c IsFileInUseByWriter(LPCSTR path)
f1bb36 {
2afec2 ¤   File¤   existingFile;
--5f82 000d4799ac8401100f7 Page 9 of KernelModeUtils.cpp
2c945d ¤   DualErr¤derr;
13af5a
f3639f ¤   pgpAssertStrValid(path);
4faf5a
76862d ¤   derr = existingFile.Open(path,·
115c1e ¤   ¤   kOF_ReadOnly | kOF_DenyWrite | kOF_MustExist);
85af5a
1112c1 ¤   if (existingFile.Opened())
a8c7a1 ¤   {
151af7 ¤   ¤   existingFile.Close();
4e9371 ¤   }
b4af5a
718864 ¤   return derr.IsError();
baefe6 }
9faf5a
7a74d2 // IsFileInUseByWriter returns TRUE if someone has opened the specified file,
de9a91 // FALSE otherwise.
c1af5a
7977be PGPBoolean·
c3e416 IsFileInUse(LPCSTR path)
7cbb36 {
3d639f ¤   pgpAssertStrValid(path);
e8af5a
75807e ¤   return (IsFileInUseByReader(path) || IsFileInUseByWriter(path));
d7efe6 }
e4af5a
63af5a
4b5270 ////////////////////////////
c32fa4 // Error/Debugging functions
245270 ////////////////////////////
01af5a
e0eb3a // GetName parses a nametable and determines which string is associated with
b71a9b // which constant, and returns it.
02af5a
3503c3 LPCSTR·
4a37b4 GetName(NameAssoc nameTable[], PGPUInt32 n, PGPUInt32 func)
5abb36 {
6751fc ¤   PGPUInt32 i;
5daf5a
ab10da ¤   for (i = 0; i < n; i++)
c2c7a1 ¤   {
a3a7a8 ¤   ¤   if (func == nameTable[i].func)
6a9722 ¤   ¤   ¤   return nameTable[i].name;
889371 ¤   }
bbaf5a
d66a8f ¤   return "<Unknown>";
8eefe6 }
dfaf5a
ae6952 // GetADPacketName returns a string with the name of the AD packet passed in
2876ec // 'code'.
33af5a
1003c3 LPCSTR·
65392b GetADPacketName(PGPUInt32 code)
14bb36 {
82e31a ¤   static NameAssoc nameTable[] =
2ec7a1 ¤   {
43e569 ¤   ¤   {kAD_Mount,¤¤   ¤   ¤   ¤   "kAD_Mount"},
83f53b ¤   ¤   {kAD_Unmount,¤  ¤   ¤   ¤   "kAD_Unmount"},
2273a8 ¤   ¤   {kAD_QueryVersion,¤ ¤   ¤   "kAD_QueryVersion"},
397325 ¤   ¤   {kAD_QueryMounted,¤ ¤   ¤   "kAD_QueryMounted"},
c6a5d2 ¤   ¤   {kAD_QueryOpenFiles,¤   ¤   "kAD_QueryOpenFiles"},
a79607 ¤   ¤   {kAD_ChangePrefs,¤  ¤   ¤   "kAD_ChangePrefs"},
a64693 ¤   ¤   {kAD_LockUnlockMem,¤¤   ¤   "kAD_LockUnlockMem"},·
fe55dd ¤   ¤   {kAD_GetPGPdiskInfo,¤   ¤   "kAD_GetPGPdiskInfo"},·
75572b ¤   ¤   {kAD_LockUnlockVol,¤¤   ¤   "kAD_LockUnlockVol"},·
3301fb ¤   ¤   {kAD_ReadWriteVol,¤ ¤   ¤   "kAD_ReadWriteVol"},·
cd2ad3 ¤   ¤   {kAD_QueryVolInfo,¤ ¤   ¤   "kAD_QueryVolInfo"},·
9c677e ¤   ¤   {kAD_NotifyUserLogoff,¤ ¤   "kAD_NotifyUserLogoff"}
3caf5a
9762bd ¤   };
ecaf5a
d4a53f ¤   return GetName(nameTable, (sizeof(nameTable) / sizeof(NameAssoc)), code);
--730a 0011a3216a2401100f7 Page 10 of KernelModeUtils.cpp
7aefe6 }
46af5a
a30cbf // GetIOCTLFunctionName returns a string with the name of the IOCTL function
af60b9 // passed in 'ioctlCode'.
58af5a
e703c3 LPCSTR·
ad6963 GetIOCTLFunctionName(PGPUInt32 ioctlCode)
debb36 {
9be31a ¤   static NameAssoc nameTable[] =
86c7a1 ¤   {
f2c492 ¤   ¤   {IOCTL_DISK_FORMAT_TRACKS,¤ ¤   ¤   "IOCTL_DISK_FORMAT_TRACKS"},·
7c532c ¤   ¤   {IOCTL_DISK_FORMAT_TRACKS_EX,¤  ¤   "IOCTL_DISK_FORMAT_TRACKS_EX"},·
67e993 ¤   ¤   {IOCTL_DISK_VERIFY,¤¤   ¤   ¤   ¤   "IOCTL_DISK_VERIFY"},·
1d6376 ¤   ¤   {IOCTL_DISK_GET_DRIVE_GEOMETRY,¤¤   "IOCTL_DISK_GET_DRIVE_GEOMETRY"},·
8cce92 ¤   ¤   {IOCTL_DISK_GET_MEDIA_TYPES,¤   ¤   "IOCTL_DISK_GET_MEDIA_TYPES"},·
7186ac ¤   ¤   {IOCTL_DISK_CHECK_VERIFY,¤  ¤   ¤   "IOCTL_DISK_CHECK_VERIFY"},·
211aba ¤   ¤   {IOCTL_STORAGE_CHECK_VERIFY,¤   ¤   "IOCTL_STORAGE_CHECK_VERIFY"},·
a43f79 ¤   ¤   {IOCTL_DISK_GET_PARTITION_INFO,¤¤   "IOCTL_DISK_GET_PARTITION_INFO"},·
8dd0a6 ¤   ¤   {IOCTL_DISK_SET_PARTITION_INFO,¤¤   "IOCTL_DISK_SET_PARTITION_INFO"},·
1346be ¤   ¤   {IOCTL_DISK_GET_DRIVE_LAYOUT,¤  ¤   "IOCTL_DISK_GET_DRIVE_LAYOUT"},·
978f7b ¤   ¤   {IOCTL_DISK_SET_DRIVE_LAYOUT,¤  ¤   "IOCTL_DISK_SET_DRIVE_LAYOUT"},·
b64010 ¤   ¤   {IOCTL_DISK_IS_WRITABLE,¤   ¤   ¤   "IOCTL_DISK_IS_WRITABLE"},·
9987db ¤   ¤   {IOCTL_DISK_REASSIGN_BLOCKS,¤   ¤   "IOCTL_DISK_REASSIGN_BLOCKS"},·
7c8f36 ¤   ¤   {IOCTL_DISK_FIND_NEW_DEVICES,¤  ¤   "IOCTL_DISK_FIND_NEW_DEVICES"},·
46ab9e ¤   ¤   {IOCTL_DISK_MEDIA_REMOVAL,¤ ¤   ¤   "IOCTL_DISK_MEDIA_REMOVAL"},·
b8af5a
e6cb94 ¤   ¤   {IOCTL_STORAGE_FIND_NEW_DEVICES,·
57a6d1 ¤   ¤   ¤   "IOCTL_STORAGE_FIND_NEW_DEVICES"},·
cbaf5a
35aa6f ¤   ¤   {IOCTL_DISK_PERFORMANCE,¤   ¤   ¤   "IOCTL_DISK_PERFORMANCE"},·
fea9c7 ¤   ¤   {SMART_GET_VERSION,¤¤   ¤   ¤   ¤   "SMART_GET_VERSION"},·
50ae37 ¤   ¤   {SMART_RCV_DRIVE_DATA,¤ ¤   ¤   ¤   "SMART_RCV_DRIVE_DATA"},·
c5643e ¤   ¤   {SMART_SEND_DRIVE_COMMAND,¤ ¤   ¤   "SMART_SEND_DRIVE_COMMAND"},·
f9af5a
f392f2 ¤   ¤   {IOCTL_DISK_INTERNAL_SET_VERIFY,·
db5810 ¤   ¤   ¤   "IOCTL_DISK_INTERNAL_SET_VERIFY"},·
95af5a
8c572f ¤   ¤   {IOCTL_DISK_INTERNAL_CLEAR_VERIFY,·
975bcc ¤   ¤   ¤   "IOCTL_DISK_INTERNAL_CLEAR_VERIFY"}
41af5a
c062bd ¤   };
1baf5a
174d14 ¤   return GetName(nameTable, (sizeof(nameTable) / sizeof(NameAssoc)),·
9e31b3 ¤   ¤   ioctlCode);
14efe6 }
1aaf5a
3cd621 // GetIRPMajorFunctionName returns a string with the name of the IRP major
8f98b3 // function passed in 'majorFunc'.
27af5a
d303c3 LPCSTR·
335d82 GetIRPMajorFunctionName(PGPUInt8 majorFunc)
2fbb36 {
0ee31a ¤   static NameAssoc nameTable[] =
69c7a1 ¤   {
36a76c ¤   ¤   {IRP_MJ_CREATE,¤¤   ¤   ¤   ¤   ¤   "IRP_MJ_CREATE"},·
683536 ¤   ¤   {IRP_MJ_CLEANUP,¤   ¤   ¤   ¤   ¤   "IRP_MJ_CLEANUP"},·
6f3588 ¤   ¤   {IRP_MJ_CLOSE,¤ ¤   ¤   ¤   ¤   ¤   "IRP_MJ_CLOSE"},·
7a1170 ¤   ¤   {IRP_MJ_READ,¤  ¤   ¤   ¤   ¤   ¤   "IRP_MJ_READ"},·
cb5ac0 ¤   ¤   {IRP_MJ_WRITE,¤ ¤   ¤   ¤   ¤   ¤   "IRP_MJ_WRITE"},·
120bd5 ¤   ¤   {IRP_MJ_FLUSH_BUFFERS,¤ ¤   ¤   ¤   "IRP_MJ_FLUSH_BUFFERS"},·
a3a484 ¤   ¤   {IRP_MJ_DEVICE_CONTROL,¤¤   ¤   ¤   "IRP_MJ_DEVICE_CONTROL"},·
007164 ¤   ¤   {IRP_MJ_INTERNAL_DEVICE_CONTROL,¤   "IRP_MJ_INTERNAL_DEVICE_CONTROL"}
a1af5a
2b62bd ¤   };
afaf5a
ee4d14 ¤   return GetName(nameTable, (sizeof(nameTable) / sizeof(NameAssoc)),·
7a9915 ¤   ¤   majorFunc);
1aefe6 }
--b93c 0016903d2a9401100f8 Page 1 of KernelModeUtils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
4763d9 // KernelModeUtils.h
83465d //
00ec0b // Declarations for KernelModeUtils.cpp.
e01bc3 //////////////////////////////////////////////////////////////////////////////
b3af5a
e5fcdd // $Id: KernelModeUtils.h,v 1.1.2.7 1998/07/06 08:57:49 nryan Exp $
f6af5a
cdcbce // Copyright (C) 1998 by Network Associates, Inc.
a271ae // All rights reserved.
23af5a
9d94a3 #ifndef Included_KernelModeUtils_h¤ // [
b5a171 #define Included_KernelModeUtils_h
73af5a
923a85 #include "DualErr.h"
c3af5a
f8af5a
55d557 ////////
fc02c9 // Types
f0d557 ////////
35af5a
1d1956 // NameAssoc is used by the debug routines to associate strings to constants.
faaf5a
d2f155 typedef struct NameAssoc
41bb36 {
00758d ¤   PGPUInt32¤  func;
6757f7 ¤   LPCSTR¤ ¤   name;
ceaf5a
dc31cd } NameAssoc;
7baf5a
1eaf5a
506cc2 /////////////////////
6b13d2 // Exported functions
5d6cc2 /////////////////////
d1af5a
0cba1d DualErr¤¤   UniToAnsi(KUstring *uniString, LPSTR *string);
2daf5a
bf60c6 DualErr¤¤   AssignToUni(KUstring *outUniString,·
628046 ¤   ¤   ¤   ¤   PUNICODE_STRING inUniString);
9d60c6 DualErr¤¤   AssignToUni(KUstring *outUniString,·
f5fe34 ¤   ¤   ¤   ¤   LPCWSTR inUniString);
4060c6 DualErr¤¤   AssignToUni(KUstring *outUniString,·
683fc0 ¤   ¤   ¤   ¤   LPCSTR inString);
e5af5a
3d445c DualErr¤¤   AppendToUni(KUstring *outUniString,·
ba8046 ¤   ¤   ¤   ¤   PUNICODE_STRING inUniString);
08445c DualErr¤¤   AppendToUni(KUstring *outUniString,·
08fe34 ¤   ¤   ¤   ¤   LPCWSTR inUniString);
4b445c DualErr¤¤   AppendToUni(KUstring *outUniString,·
7f3fc0 ¤   ¤   ¤   ¤   LPCSTR inString);
0aaf5a
535d4b DualErr¤¤   PrependToUni(KUstring *outUniString,·
678046 ¤   ¤   ¤   ¤   PUNICODE_STRING inUniString);
775d4b DualErr¤¤   PrependToUni(KUstring *outUniString,·
f1fe34 ¤   ¤   ¤   ¤   LPCWSTR inUniString);
0a5d4b DualErr¤¤   PrependToUni(KUstring *outUniString,·
363fc0 ¤   ¤   ¤   ¤   LPCSTR inString);
53af5a
67963a LPCSTR¤ ¤   GetName(NameAssoc nameTable[], PGPUInt32 n, PGPUInt32 func);
b225e7 LPCSTR¤ ¤   GetADPacketName(PGPUInt32 code);
2778f7 LPCSTR¤ ¤   GetIOCTLFunctionName(PGPUInt32 ioctlCode);
b112ff LPCSTR¤ ¤   GetIRPMajorFunctionName(PGPUInt8 majorFunc);
1baf5a
d6847b DualErr¤¤   MakePathToDrive(PGPUInt8 drive, KUstring *outPath);
6271d6 PGPBoolean¤ IsValidDeviceName(PUNICODE_STRING deviceName);
c3af5a
33b9cd PGPBoolean¤ IsFileInUseByReader(LPCSTR path);
7e8eaf PGPBoolean¤ IsFileInUseByWriter(LPCSTR path);
2ee700 PGPBoolean¤ IsFileInUse(LPCSTR path);
03af5a
f2af5a
69d7fe #endif¤ // ] Included_KernelModeUtils_h
--a7ac 00039520961401100f9 Page 1 of LockableList.h
541bc3 //////////////////////////////////////////////////////////////////////////////
94d174 // LockableList.h
a7465d //
37b929 // Declaration and definition of class LockableList.
561bc3 //////////////////////////////////////////////////////////////////////////////
69af5a
57f788 // $Id: LockableList.h,v 1.1.2.5 1998/07/06 08:57:50 nryan Exp $
5eaf5a
58cbce // Copyright (C) 1998 by Network Associates, Inc.
3a71ae // All rights reserved.
7baf5a
1f163f #ifndef Included_Lockable_h¤// [
7555d2 #define Included_Lockable_h
d7af5a
9b3a85 #include "DualErr.h"
c7af5a
85af5a
af6cc2 /////////////////////
b6ca1e // Class LockableList
da6cc2 /////////////////////
c3af5a
84612d template <class T> class LockableList : public KList<T>
1ebb36 {
995ed4 public:
be6a47 ¤   ¤   ¤   LockableList();
aa6f5f ¤   ¤   ¤   ~LockableList();
1267c5 ¤
81e362 ¤   void¤   PublicLock();
728828 ¤   void¤   PublicUnlock();
64af5a
340fb9 private:
d416b5 ¤   KIRQL ·····mOldIrql;
b92719 ¤   KSPIN_LOCK mSpinLock;
6082f7 };
1caf5a
c1af5a
e09c30 ////////////////////////////////////////////////////
5dac41 // Class LockableList inline public member functions
419c30 ////////////////////////////////////////////////////
74af5a
edec9e // The LockableList constructor.
e9af5a
d19641 template <class T>·
8fc85e inline·
ea0c27 LockableList<T>::LockableList() : KList<T>()
e8bb36 {
33efe6 }
f6af5a
6ff333 // The LockableList destructor.
caaf5a
b79641 template <class T>·
01c85e inline·
ba990e LockableList<T>::~LockableList()
3abb36 {
9cefe6 }
77af5a
a884aa // PublicLock locks the list.
7daf5a
bc9641 template <class T>·
a7c823 void·
8da111 LockableList<T>::PublicLock()·
3fbb36 {
54cff9 ¤   KIRQL oldIrql;
61af5a
1b0101 ¤   KeAcquireSpinLock(&mSpinLock, &oldIrql);
27af5a
809bdf ¤   mOldIrql = oldIrql;
e6efe6 }
97af5a
02e673 // PublicUnlock unlocks the list.
37af5a
399641 template <class T>·
--4a95 0014c03adad401100f9 Page 2 of LockableList.h
84c823 void·
05aca4 LockableList<T>::PublicUnlock()·
e4bb36 {
557d15 ¤   KeReleaseSpinLock(&mSpinLock, mOldIrql);
beefe6 }
a5af5a
4c4ca2 #endif¤ // ] Included_Lockable_h
--d831 0001f970f06401100fa Page 1 of LookasideList.h
541bc3 //////////////////////////////////////////////////////////////////////////////
632e23 // LookasideList.h
a4465d //
fc8d70 // Declaration and definition of class LookasideList.
d11bc3 //////////////////////////////////////////////////////////////////////////////
88af5a
a67f36 // $Id: LookasideList.h,v 1.1.2.4 1998/07/06 08:57:50 nryan Exp $
0aaf5a
b0cbce // Copyright (C) 1998 by Network Associates, Inc.
5771ae // All rights reserved.
6aaf5a
2b6771 #ifndef Included_LookasideList_h¤   // [
e21aa9 #define Included_LookasideList_h
3aaf5a
3b3a85 #include "DualErr.h"
1aaf5a
45af5a
4817a3 //////////////////////
b1fc20 // Class LookasideList
7217a3 //////////////////////
86af5a
47258f template <class T> class LookasideList
d1bb36 {
745ed4 public:
011603 ¤   DualErr mInitErr;
56af5a
8addf0 ¤   ¤   ¤   LookasideList(PGPUInt16 depth);
c6ee8c ¤   ¤   ¤   ~LookasideList();
5aaf5a
7238c5 ¤   DualErr¤Allocate(T **ppObj);
4f3a76 ¤   void¤   Free(T *pObj);
a0af5a
ee0fb9 private:
d2740c ¤   PNPAGED_LOOKASIDE_LIST mPListHeader;
0f82f7 };
93af5a
f6af5a
e3c3ce /////////////////////////////////////////////////////
098c95 // Class LookasideList inline public member functions
a4c3ce /////////////////////////////////////////////////////
36af5a
56ab00 // The LookasideList constructor.
38af5a
859641 template <class T>·
a9c85e inline·
7e511f LookasideList<T>::LookasideList(PGPUInt16 depth)
b7bb36 {
587ebd ¤   // Get memory for list header.
f316b5 ¤   mPListHeader = new NPAGED_LOOKASIDE_LIST;
06af5a
f1fbb8 ¤   if (IsNull(mPListHeader))
2a9a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
01af5a
7b9c32 ¤   if (mInitErr.IsntError())
57c7a1 ¤   {
392d15 ¤   ¤   ExInitializeNPagedLookasideList(mPListHeader, NULL, NULL, NULL,·
5af7fa ¤   ¤   ¤   sizeof(T), kPGPdiskMemPoolTag, depth);
d39371 ¤   }
13efe6 }
bcaf5a
bd4126 // The LookasideList destructor.
e7af5a
989641 template <class T>·
38c85e inline·
402a90 LookasideList<T>::~LookasideList()
81bb36 {
52354e ¤   if (IsntNull(mPListHeader))
7bc7a1 ¤   {
5637ba ¤   ¤   ExDeleteNPagedLookasideList(mPListHeader);
0eaf5a
f8d3f1 ¤   ¤   delete mPListHeader;
1f0435 ¤   ¤   mPListHeader = NULL;
--5cee 0019b22b1ae401100fa Page 2 of LookasideList.h
a19371 ¤   }
c9efe6 }
a0af5a
9b7d8e // Allocate allocates an object from the lookaside list.
aeaf5a
5c9641 template <class T>·
d0c85e inline·
1d9d6b DualErr¤
300020 LookasideList<T>::Allocate(T **ppObj)
c1bb36 {
18945d ¤   DualErr¤derr;
ccb1c2 ¤   T¤  ¤   *pObj;
03af5a
274721 ¤   pgpAssertAddrValid(ppObj, T *);
95849d ¤   pgpAssertAddrValid(mPListHeader, NPAGED_LOOKASIDE_LIST);
d3af5a
2e0a4b ¤   pObj = (T *) ExAllocateFromNPagedLookasideList(mPListHeader);
f7af5a
babd8e ¤   if (IsntNull(pObj))
d9262a ¤   ¤   (* ppObj) = pObj;
d30e24 ¤   else
99ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
b4af5a
9133e3 ¤   return derr;
e9efe6 }
25af5a
d00692 // Free returns an object to the lookaside list.
12af5a
6b9641 template <class T>·
c6c85e inline·
cec823 void·
cd26e8 LookasideList<T>::Free(T *pObj)
2fbb36 {
a46777 ¤   pgpAssertAddrValid(pObj, T);
3f849d ¤   pgpAssertAddrValid(mPListHeader, NPAGED_LOOKASIDE_LIST);
bcaf5a
18d94d ¤   ExFreeToNPagedLookasideList(mPListHeader, pObj);
eaefe6 }
73af5a
9b3598 #endif¤ // ] Included_LookasideList_h
--7e38 000e1af37d0401100fb Page 1 of NtThreadSecurity.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
7a21ec // NtThreadSecurity.cpp
98465d //
f7eda6 // Thread security functions.
aa1bc3 //////////////////////////////////////////////////////////////////////////////
e4af5a
fcccc7 // $Id: NtThreadSecurity.cpp,v 1.1.2.3 1998/07/06 08:57:51 nryan Exp $
12af5a
78cbce // Copyright (C) 1998 by Network Associates, Inc.
b871ae // All rights reserved.
02af5a
d7d7a1 #include <vdw.h>
28af5a
0f9bcf #include "Required.h"
a78869 #include "NtThreadSecurity.h"
a0af5a
84af5a
222af8 //////////
1bb932 // Globals
a52af8 //////////
2caf5a
9c659f HANDLE¤ ¤   mImpersonationToken;
4befbc PGPUInt32¤  mAppropriateProcId;
1eaf5a
f6af5a
dfc7c6 ///////////////////////////////
5d29e1 // Token manipulation functions
4dc7c6 ///////////////////////////////
b5af5a
e0ac5d // DuplicateProcessToken returns a copy of the token of the specified
a82b78 // process.
1aaf5a
3e9d6b DualErr¤
171320 DuplicateProcessToken(PGPUInt32 procId, PHANDLE pDupedToken)
37bb36 {
9f4d34 ¤   CLIENT_ID¤  ¤   ¤   clientId;
70705b ¤   DualErr¤¤   ¤   ¤   derr;
8f333e ¤   HANDLE¤ ¤   ¤   ¤   procHandle, token;
0263a6 ¤   NTSTATUS¤   ¤   ¤   status;
6a6702 ¤   OBJECT_ATTRIBUTES¤  objAttribs;
39d412 ¤   PGPBoolean¤ ¤   ¤   openedProcess, openedToken;
e7af5a
9abef4 ¤   openedProcess = openedToken = FALSE;
ffaf5a
235bae ¤   pgpAssertAddrValid(pDupedToken, HANDLE);
8daf5a
f8ba7e ¤   InitializeObjectAttributes(&objAttribs, NULL, 0, NULL, NULL);
29af5a
a00dca ¤   clientId.UniqueThread = NULL;
e42b1b ¤   clientId.UniqueProcess = (PVOID) procId;
33af5a
4dfa0a ¤   // Open a handle to the process.
ae2335 ¤   status = ZwOpenProcess(&procHandle, PROCESS_ALL_ACCESS, &objAttribs,·
96ddc6 ¤   ¤   &clientId);
4eaf5a
b3df44 ¤   if (!NT_SUCCESS(status))
72c7a1 ¤   {
84d3df ¤   ¤   derr = DualErr(kPGDMinorError_ZwOpenProcessFailed, status);
ed9371 ¤   }
d3af5a
8cd8e9 ¤   openedProcess = derr.IsntError();
1daf5a
9df59b ¤   // Open a handle to the process token.
672361 ¤   if (derr.IsntError())
f0c7a1 ¤   {
c5b9b0 ¤   ¤   status = ZwOpenProcessToken(procHandle, TOKEN_ALL_ACCESS, &token);
2eaf5a
7c6412 ¤   ¤   if (!NT_SUCCESS(status))
e55b34 ¤   ¤   {
55bc41 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_ZwOpenProcessTokenFailed, status);
a10fe4 ¤   ¤   }
e1af5a
--9b6f 000287f2d6b401100fb Page 2 of NtThreadSecurity.cpp
56c9fa ¤   ¤   openedToken = derr.IsntError();
479371 ¤   }
cfaf5a
c9ff34 ¤   // Duplicate the token.
f12361 ¤   if (derr.IsntError())
e6c7a1 ¤   {
e6b683 ¤   ¤   SECURITY_QUALITY_OF_SERVICE SQOS;
2eaf5a
43e275 ¤   ¤   SQOS.Length = sizeof(SQOS);
b54f37 ¤   ¤   SQOS.ImpersonationLevel = SecurityImpersonation;
e11371 ¤   ¤   SQOS.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
f0a492 ¤   ¤   SQOS.EffectiveOnly = FALSE;
93af5a
0f9682 ¤   ¤   objAttribs.SecurityQualityOfService = (PVOID) &SQOS;
01af5a
30ecb9 ¤   ¤   status = ZwDuplicateToken(token, TOKEN_QUERY | TOKEN_IMPERSONATE,·
53b32d ¤   ¤   ¤   &objAttribs, SecurityAnonymous, TokenImpersonation, pDupedToken);
a7af5a
fb6412 ¤   ¤   if (!NT_SUCCESS(status))
7d5b34 ¤   ¤   {
d0db9b ¤   ¤   ¤   derr = DualErr(kPGDMinorError_ZwDuplicateTokenFailed, status);
d10fe4 ¤   ¤   }
f69371 ¤   }
84af5a
ca8994 ¤   if (openedToken)
83d1e1 ¤   ¤   ZwClose(token);
a8af5a
25c7db ¤   if (openedProcess)
ee9f14 ¤   ¤   ZwClose(procHandle);
b6af5a
c433e3 ¤   return derr;
37efe6 }
8aaf5a
056b4f // IsImpersonationTokenSet returns TRUE if an impersonation token is set,·
ab9a91 // FALSE otherwise.
61af5a
3977be PGPBoolean·
23014e IsImpersonationTokenSet()
0bbb36 {
1b84da ¤   return (IsntNull(mImpersonationToken));
42efe6 }
f9af5a
8ba388 // ClearImpersonationToken frees the current impersonation token.
0eaf5a
aac823 void·
646158 ClearImpersonationToken(HANDLE token)
6cbb36 {
f42471 ¤   pgpAssert(IsImpersonationTokenSet());
5caf5a
bf168b ¤   ZwClose(mImpersonationToken);
d6a013 ¤   mImpersonationToken = NULL;
f8efe6 }
3eaf5a
81b683 // SetImpersonationToken creates a copy of the token of the specified process
9b1ac3 // to be used for future impersonations.
dfaf5a
692292 DualErr·
e263db SetImpersonationToken(PGPUInt32 procId)
59bb36 {
137d36 ¤   DualErr derr;
92af5a
5a6f77 ¤   pgpAssert(!IsImpersonationTokenSet());
d5af5a
e7056e ¤   derr = DuplicateProcessToken(procId, &mImpersonationToken);
e5af5a
682361 ¤   if (derr.IsntError())
0ec7a1 ¤   {
a3d7b3 ¤   ¤   mAppropriateProcId = (PGPUInt32) PsGetCurrentProcessId();
3c9371 ¤   }
06af5a
9233e3 ¤   return derr;
28efe6 }
--2312 001bdf5431e401100fb Page 3 of NtThreadSecurity.cpp
e0af5a
4f50db // ImpersonateToken impersonates the specified token.
b0af5a
5cc823 void·
a1194f ImpersonateToken()
bdbb36 {
b92471 ¤   pgpAssert(IsImpersonationTokenSet());
8faf5a
296b52 ¤   if (mAppropriateProcId != (PGPUInt32) PsGetCurrentProcessId())
0699bf ¤   ¤   return;
36af5a
a523a8 ¤   ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken,·
93b1f3 ¤   ¤   &mImpersonationToken, sizeof(mImpersonationToken));
6eefe6 }
55af5a
33d3af // RevertToSelf stops impersonation.
93af5a
7dc823 void·
0f5216 RevertToSelf()
e1bb36 {
1fb3a1 ¤   HANDLE nullToken = NULL;
69af5a
fb6b52 ¤   if (mAppropriateProcId != (PGPUInt32) PsGetCurrentProcessId())
5299bf ¤   ¤   return;
adaf5a
2723a8 ¤   ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken,·
031b35 ¤   ¤   &nullToken, sizeof(nullToken));
bdefe6 }
--6c26 000cd2fb7bb401100fc Page 1 of NtThreadSecurity.h
541bc3 //////////////////////////////////////////////////////////////////////////////
04547c // NtThreadSecurity.h
49465d //
1e6ea5 // Kernel-mode thread security functions.
981bc3 //////////////////////////////////////////////////////////////////////////////
1baf5a
5991ce // $Id: NtThreadSecurity.h,v 1.1.2.3 1998/07/06 08:57:52 nryan Exp $
95af5a
37cbce // Copyright (C) 1998 by Network Associates, Inc.
0171ae // All rights reserved.
bdaf5a
aa781f #ifndef Included_NtThreadSecurity_h¤// [
f5e106 #define Included_NtThreadSecurity_h
40af5a
593a85 #include "DualErr.h"
50af5a
adaf5a
6209b7 ////////////
2ce738 // Constants
9609b7 ////////////
ffaf5a
f0d0e5 // From Winnt.h.
b4af5a
723e2c #define TOKEN_ASSIGN_PRIMARY ···(0x0001)
aff150 #define TOKEN_DUPLICATE ········(0x0002)
39d15c #define TOKEN_IMPERSONATE ······(0x0004)
4aeddf #define TOKEN_QUERY ············(0x0008)
562857 #define TOKEN_QUERY_SOURCE ·····(0x0010)
0beac4 #define TOKEN_ADJUST_PRIVILEGES (0x0020)
06cdec #define TOKEN_ADJUST_GROUPS ····(0x0040)
78022f #define TOKEN_ADJUST_DEFAULT ···(0x0080)
87af5a
97ffc0 #define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED ·|\
3088c2 ··························TOKEN_ASSIGN_PRIMARY ·····|\
58fcd2 ··························TOKEN_DUPLICATE ··········|\
db856f ··························TOKEN_IMPERSONATE ········|\
04413c ··························TOKEN_QUERY ··············|\
98e6a8 ··························TOKEN_QUERY_SOURCE ·······|\
2de45b ··························TOKEN_ADJUST_PRIVILEGES ··|\
4615d7 ··························TOKEN_ADJUST_GROUPS ······|\
35c75e ··························TOKEN_ADJUST_DEFAULT)
d9af5a
4baf5a
93cb7d #define TOKEN_READ ······(STANDARD_RIGHTS_READ ·····|\
ae0064 ··························TOKEN_QUERY)
a5af5a
a3af5a
86de54 #define TOKEN_WRITE ·····(STANDARD_RIGHTS_WRITE ····|\
4be45b ··························TOKEN_ADJUST_PRIVILEGES ··|\
5115d7 ··························TOKEN_ADJUST_GROUPS ······|\
c9c75e ··························TOKEN_ADJUST_DEFAULT)
5faf5a
8beaab #define TOKEN_EXECUTE ···(STANDARD_RIGHTS_EXECUTE)
26af5a
51af5a
3ed557 ////////
6902c9 // Types
26d557 ////////
72af5a
8ad0e5 // From Winnt.h.
0aaf5a
e8fb8d typedef enum _TOKEN_TYPE·
d9bb36 {
e252aa ····TokenPrimary = 1,
81b510 ····TokenImpersonation
5eaf5a
c03340 } TOKEN_TYPE, *PTOKEN_TYPE;
e0af5a
81af5a
b76cc2 /////////////////////
cdadaa // Imported Functions
cd6cc2 /////////////////////
--3980 00156496684401100fc Page 2 of NtThreadSecurity.h
e0af5a
4526a9 #define EZNTAPI extern "C" NTSYSAPI NTSTATUS NTAPI
86af5a
f56e51 EZNTAPI¤ZwOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess,·
e9fa9c ¤   ¤   ¤   POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
09af5a
65d51b EZNTAPI¤ZwOpenProcessToken(HANDLE ProcessHandle, PGPUInt32 DesiredAccess,·
728f8d ¤   ¤   ¤   PHANDLE TokenHandle);
c8af5a
ec0d20 EZNTAPI¤ZwDuplicateToken(HANDLE TokenHandle, PGPUInt32 DesiredAccess,·
18c1ae ¤   ¤   ¤   POBJECT_ATTRIBUTES ObjectAttributes,·
6884f7 ¤   ¤   ¤   SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,·
e2045e ¤   ¤   ¤   TOKEN_TYPE TokenType, PHANDLE phNewToken);
27af5a
edaf5a
f66cc2 /////////////////////
c613d2 // Exported functions
e86cc2 /////////////////////
64af5a
97ead5 PGPBoolean¤ IsImpersonationTokenSet();
2ea019 DualErr¤¤   SetImpersonationToken(PGPUInt32 procId);
9f0234 void¤   ¤   ClearImpersonationToken();
a4af5a
7bec53 void¤   ¤   ImpersonateToken();
be17d6 void¤   ¤   RevertToSelf();
afaf5a
15af5a
569d8f #endif¤ // ] Included_NtThreadSecurity_h
--53a2 0016e7acc46401100fd Page 1 of OperatorNewFixups.h
541bc3 //////////////////////////////////////////////////////////////////////////////
51d8e5 // OperatorNewFixups.h
76465d //
b243e0 // Extra definitions for operator new.
c31bc3 //////////////////////////////////////////////////////////////////////////////
eeaf5a
fdf649 // $Id: OperatorNewFixups.h,v 1.1.2.3 1998/07/06 08:57:52 nryan Exp $
cbaf5a
b7cbce // Copyright (C) 1998 by Network Associates, Inc.
fc71ae // All rights reserved.
a0af5a
114c1b #ifndef Included_OperatorNewFixups_h¤   // [
889877 #define Included_OperatorNewFixups_h
31af5a
45af5a
ce2af8 //////////
de647f // Externs
db2af8 //////////
22af5a
db855c extern ULONG __Pool_Tag__;
60af5a
f1af5a
558104 /////////////////////////////
6e7f3c // New without pool specifier
b58104 /////////////////////////////
81af5a
578e30 // Why not provide a default specifier and save everyone from rewriting their
d16408 // shared code Vireo? What the dil-e-o?
ccaf5a
85c85e inline·
4821f6 void *·
b1d80e __cdecl·
a45b57 operator new(unsigned int nSize)
b0bb36 {
ee55e7 #if DBG
2a187a ¤   ¤   return ExAllocatePoolWithTag(NonPagedPool, nSize, __Pool_Tag__);
1adb21 #else
bfc759 ¤   ¤   return ExAllocatePool(NonPagedPool, nSize);
537454 #endif
cb82f7 };
acaf5a
01af5a
5a9791 ////////////////
836d72 // Placement New
799791 ////////////////
eeaf5a
aac85e inline·
0421f6 void *·
17d80e __cdecl·
28f942 operator new(unsigned int nSize, void *pMem)
f8bb36 {
44303d ¤   return pMem;¤   ¤   ¤   // all too easy!
acefe6 }
09af5a
6ecb29 #endif // ] Included_OperatorNewFixups_h
--f04e 000a31ecc0b401100fe Page 1 of PGPdisk.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
21efa8 // PGPdisk.cpp
ae465d //
b53ee7 // Implementation of class PGPdisk.
ec1bc3 //////////////////////////////////////////////////////////////////////////////
efaf5a
86edc6 // $Id: PGPdisk.cpp,v 1.1.4.29 1998/07/30 00:50:24 nryan Exp $
67af5a
26cbce // Copyright (C) 1998 by Network Associates, Inc.
bf71ae // All rights reserved.
f5af5a
b6d7a1 #include <vdw.h>
f6af5a
379bcf #include "Required.h"
617414 #include "PGPdiskHighLevelUtils.h"
8b2229 #include "PGPdiskLowLevelUtils.h"
47bfe9 #include "UtilityFunctions.h"
b0af5a
9ec411 #include "Globals.h"
94f1f6 #include "KernelModeUtils.h"
7968c6 #include "PGPdisk.h"
5daf5a
45af5a
4a09b7 ////////////
d4e738 // Constants
8109b7 ////////////
b7af5a
f5a79d static LPCSTR kPGPdiskDeviceName = "PGPdiskVolume";
2faf5a
346e4d const PGPUInt32 kPGDBlocksPerOp = 32;¤  // cipher this many blocks at a time
86af5a
52af5a
4251ef ////////////////////////////////////////
f7e872 // Class PGPdisk public member functions
6f51ef ////////////////////////////////////////
c5af5a
ad3d96 // The PGPdisk default constructor.
acaf5a
dde06c PGPdisk::PGPdisk() : VolFile(), mContextMutex(0),·
834575 ¤   mSmContextA(sizeof(CipherContext)), mSmContextB(sizeof(CipherContext))
92bb36 {
c30db0 ¤   mDevExtInfo = (PGPUInt32) this;
95af5a
5b6991 ¤   mContextA¤  = NULL;
dcee7f ¤   mContextB¤  = NULL;
74af5a
5f4dad ¤   mInitErr = mWorkerThread.mInitErr;
29af5a
469c32 ¤   if (mInitErr.IsntError())
c4c7a1 ¤   {
619a60 ¤   ¤   mInitErr = mSmContextA.mInitErr;
829371 ¤   }
d2af5a
6c9c32 ¤   if (mInitErr.IsntError())
ddc7a1 ¤   {
f11d8e ¤   ¤   mInitErr = mSmContextB.mInitErr;
9b9371 ¤   }
65af5a
199c32 ¤   if (mInitErr.IsntError())
4cc7a1 ¤   {
cf0cd4 ¤   ¤   PGPUInt32 sizeBuf;
8eaf5a
cf5ea9 ¤   ¤   // Use placement new.
338b78 ¤   ¤   mContextA¤  = new (mSmContextA.GetPtr()) CipherContext;¤
cf6557 ¤   ¤   mContextB¤  = new (mSmContextB.GetPtr()) CipherContext;
84af5a
127cfe ¤   ¤   // Get our data buffer. MUST be PAGE_SIZE or greater so that we get
402872 ¤   ¤   // it page-aligned for non-buffered file access calls.
63af5a
276048 ¤   ¤   sizeBuf = kPGDBlocksPerOp * kDefaultBlockSize;
5faf5a
a33c24 ¤   ¤   if (sizeBuf < PAGE_SIZE)
--4a54 0006bd791b5401100fe Page 2 of PGPdisk.cpp
6143d6 ¤   ¤   ¤   sizeBuf = PAGE_SIZE;
81af5a
74e1a8 ¤   ¤   mInitErr = GetByteBuffer(sizeBuf, (PGPUInt8 **) &mDataBuf);
b69371 ¤   }
45efe6 }
94af5a
430125 // The PGPdisk destructor cleans up.
25af5a
867cff PGPdisk::~PGPdisk()
86bb36 {
facb02 ¤   if (Mounted())
50e404 ¤   ¤   Unmount(TRUE);
32af5a
515a88 ¤   if (IsntNull(mContextB))
bfc7a1 ¤   {
32b5d1 ¤   ¤   mContextB->~CipherContext();
f62d79 ¤   ¤   mContextB = NULL;
c19371 ¤   }
c5af5a
217f45 ¤   if (IsntNull(mContextA))
0fc7a1 ¤   {
c2ec65 ¤   ¤   mContextA->~CipherContext();
f65910 ¤   ¤   mContextA = NULL;
9a9371 ¤   }
02af5a
924a53 ¤   if (IsntNull(mDataBuf))
1bc7a1 ¤   {
fab223 ¤   ¤   FreeByteBuffer(mDataBuf);
4343f1 ¤   ¤   mDataBuf = NULL;
d39371 ¤   }
3eefe6 }
1caf5a
2ef7af // BestGuessComparePaths uses a number of methods to determine if the
34a819 // specified file is the same as the current mounted PGPdisk.
07af5a
db77be PGPBoolean·
be50b9 PGPdisk::BestGuessComparePaths(LPCSTR path)
91bb36 {
457777 ¤   File¤   ¤   testFile;
30be41 ¤   DualErr¤¤   derr;
35a399 ¤   PGPBoolean¤ failedTest¤ = FALSE;
1aab82 ¤   PGPUInt32¤  i, numPGPdiskPathElems, numTestFilePathElems;
9ced18 ¤   PGPUInt64¤  PGPdiskLength, testFileLength;
39af5a
f33ec3 ¤   pgpAssert(Mounted());
4aaf5a
1cf905 ¤   // First try the easy case.
98a27e ¤   if (ComparePaths(path))
d2836c ¤   ¤   return TRUE;
9faf5a
93d1e6 ¤   // See if the number of path elements in each path is the same.
67cce3 ¤   numPGPdiskPathElems = 0;
90af5a
f731f5 ¤   for (i=0; i<strlen(GetPath()); i++)
fbc7a1 ¤   {
9c9ef3 ¤   ¤   if ((GetPath()[i] == '\\') || (GetPath()[i] == '/'))
1f5fcf ¤   ¤   ¤   numPGPdiskPathElems++;
fa9371 ¤   }
6aaf5a
95a4d8 ¤   numTestFilePathElems = 0;
1faf5a
c01a71 ¤   for (i=0; i<strlen(path); i++)
7bc7a1 ¤   {
65c573 ¤   ¤   if ((path[i] == '\\') || (path[i] == '/'))
650c3c ¤   ¤   ¤   numTestFilePathElems++;
ff9371 ¤   }
76af5a
7c2e75 ¤   if (numPGPdiskPathElems != numTestFilePathElems)
5cb4e5 ¤   ¤   failedTest = TRUE;
ccaf5a
636e71 ¤   // Make sure the files are the same size.
6bc2ad ¤   if (!failedTest)
--2fce 000d2562fb9401100fe Page 3 of PGPdisk.cpp
f7c7a1 ¤   {
36a9a6 ¤   ¤   derr = GetLength(&PGPdiskLength);
9f9371 ¤   }
66af5a
8c8cd9 ¤   if (derr.IsntError() && !failedTest)
4bc7a1 ¤   {
dbc9cb ¤   ¤   derr = testFile.Open(path, kOF_MustExist | kOF_ReadOnly);
c69371 ¤   }
6aaf5a
e78cd9 ¤   if (derr.IsntError() && !failedTest)
56c7a1 ¤   {
e6a7ac ¤   ¤   derr = testFile.GetLength(&testFileLength);
cb9371 ¤   }
60af5a
28695e ¤   if (!failedTest && testFile.Opened())
5fc7a1 ¤   {
99e58c ¤   ¤   testFile.Close();
679371 ¤   }
f0af5a
b78cd9 ¤   if (derr.IsntError() && !failedTest)
17c7a1 ¤   {
7c9003 ¤   ¤   if (PGPdiskLength != testFileLength)
c7a0cd ¤   ¤   ¤   failedTest = TRUE;
f09371 ¤   }
3faf5a
fe5121 ¤   // Check if the test file is in use (which must be the case with any
b20d41 ¤   // mounted PGPdisk.
58af5a
ce8cd9 ¤   if (derr.IsntError() && !failedTest)
98c7a1 ¤   {
a73434 ¤   ¤   if (IsFileInUse(path))
63a0cd ¤   ¤   ¤   failedTest = TRUE;
8c9371 ¤   }
b2af5a
8a444c ¤   // Finally return false if there was an error.
184bb3 ¤   if (derr.IsError())
fac7a1 ¤   {
c7b4e5 ¤   ¤   failedTest = TRUE;
859371 ¤   }
4aaf5a
191907 ¤   return !failedTest;
9aefe6 }
e9af5a
56b967 // GetUniqueSessionId returns the unique session ID for the PGPdisk.
d4af5a
41a385 PGPUInt64·
9b65e0 PGPdisk::GetUniqueSessionId()
51bb36 {
213ec3 ¤   pgpAssert(Mounted());
40af5a
a0322f ¤   return mUniqueSessionId;
19efe6 }
e3af5a
c8d6e5 // GetThread returns the PGPdisk's worker thread.
ceaf5a
cc0881 PGPdiskWorkerThread *·
ec8020 PGPdisk::GetThread()
10bb36 {
37dadc ¤   return &mWorkerThread;
00efe6 }
8daf5a
430e7f // FlipContexts flips the key bits on each context.
8eaf5a
1cc823 void·
7715b8 PGPdisk::FlipContexts()
f0bb36 {
65d909 ¤   pgpAssertAddrValid(mContextA, CipherContext);
c264c3 ¤   pgpAssertAddrValid(mContextB, CipherContext);
063ec3 ¤   pgpAssert(Mounted());
3faf5a
5bc569 ¤   mContextMutex.Enter();
d2af5a
--5464 0006f42f9d5401100fe Page 4 of PGPdisk.cpp
5fd9dc ¤   mContextA->FlipContext();
4ad8e4 ¤   mContextB->FlipContext();
6daf5a
bddf09 ¤   mContextMutex.Leave();
b6efe6 }
60af5a
f780a9 // ValidateContexts makes sure the cipher procs aren't damaged.
8faf5a
7a2292 DualErr·
7199ca PGPdisk::ValidateContexts()
9fbb36 {
6d7d36 ¤   DualErr derr;
90af5a
37d909 ¤   pgpAssertAddrValid(mContextA, CipherContext);
3164c3 ¤   pgpAssertAddrValid(mContextB, CipherContext);
e53ec3 ¤   pgpAssert(Mounted());
12af5a
69c569 ¤   mContextMutex.Enter();
60af5a
9e231e ¤   derr = mContextA->ValidateContext();
dfaf5a
512361 ¤   if (derr.IsntError())
54c7a1 ¤   {
b6d650 ¤   ¤   derr = mContextB->ValidateContext();
619371 ¤   }
c0af5a
4ddf09 ¤   mContextMutex.Leave();
c5af5a
9d33e3 ¤   return derr;
98efe6 }
91af5a
8a79b2 // Mount reads in the PGPdisk-specific header and asks VolFile to continue
527baa // with the mount, passing along header and disk size information.
daaf5a
992292 DualErr·
516b3a PGPdisk::Mount(
b520cd ¤   LPCSTR¤ ¤   ¤   path,·
8841e5 ¤   CipherContext¤  *pContext,·
fbf4ef ¤   PGPUInt8¤   ¤   drive,·
f36fde ¤   PGPBoolean¤ ¤   mountReadOnly)
3bbb36 {
e5705b ¤   DualErr¤¤   ¤   ¤   derr;
54e1a0 ¤   File¤   ¤   ¤   ¤   diskFile;
7dc24c ¤   KUstring¤   ¤   ¤   deviceName;
b5d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
2b8fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
ffaf5a
39639f ¤   pgpAssertStrValid(path);
9493e3 ¤   pgpAssertAddrValid(pContext, CipherContext);
fcaf5a
2bc332 ¤   // Mark the PGPdisk as mounted.
581f7b ¤   if (!mountReadOnly)
8e7c22 ¤   ¤   SetPGPdiskMountedFlag(path, TRUE);
c7af5a
945b69 ¤   // Read the session ID.
fb88f6 ¤   mUniqueSessionId = GetPGPdiskUniqueSessionId(path);
32af5a
bbe2ee ¤   // Read in the header.
35b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
c6a08e ¤   readHeader = derr.IsntError();
80af5a
806247 ¤   // Initialize the contexts and flip context B.
032361 ¤   if (derr.IsntError())
58c7a1 ¤   {
df7708 ¤   ¤   pgpAssertAddrValid(mContextA, CipherContext);
43cac2 ¤   ¤   pgpAssertAddrValid(mContextB, CipherContext);
42af5a
a09f85 ¤   ¤   (* mContextA) = (* mContextB) = (* pContext);
b0af5a
53efec ¤   ¤   mContextB->FlipContext();
f29371 ¤   }
6faf5a
--3c67 000f0df649a401100fe Page 5 of PGPdisk.cpp
282db1 ¤   // Start the worker thread.
9a2361 ¤   if (derr.IsntError())
a3c7a1 ¤   {
a49687 ¤   ¤   derr = mWorkerThread.StartThread();
679371 ¤   }
8a67c5 ¤
62e494 ¤   // Finish the mount by calling down.
f92361 ¤   if (derr.IsntError())
61c7a1 ¤   {
b98b12 ¤   ¤   derr = VolFile::Mount(path, kPGPdiskDeviceName,·
982ec4 ¤   ¤   ¤   fileHeader->numHeaderBlocks, fileHeader->numDataBlocks, drive,·
6ce88a ¤   ¤   ¤   mountReadOnly);
689371 ¤   }
0faf5a
074bb3 ¤   if (derr.IsError())
48c7a1 ¤   {
c2e91e ¤   ¤   if (!mountReadOnly)
f6814a ¤   ¤   ¤   SetPGPdiskMountedFlag(path, FALSE);
739371 ¤   }
8daf5a
5cfd0b ¤   if (readHeader)
943fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
f1af5a
f333e3 ¤   return derr;
63efe6 }
6aaf5a
537f5f // Unmount unmounts a mounted PGPdisk.
49af5a
4d2292 DualErr·
3f2545 PGPdisk::Unmount(PGPBoolean isThisEmergency)
5bbb36 {
5fbe41 ¤   DualErr¤¤   derr;
c913e7 ¤   LPSTR¤  ¤   pathCopy;
ccef0c ¤   PGPBoolean¤ dupedPath, wasReadOnly;
e3af5a
173ec3 ¤   pgpAssert(Mounted());
08af5a
5cb0ed ¤   dupedPath = FALSE;
f25c43 ¤   wasReadOnly = IsReadOnly();
65af5a
804cef ¤   // Copy path.
3b5b57 ¤   derr = DupeString(GetPath(), &pathCopy);
998a1a ¤   dupedPath = derr.IsntError();
8aaf5a
698af0 ¤   // Unmount the PGPdisk volume.
e12361 ¤   if (derr.IsntError())
46c7a1 ¤   {
3ff3fc ¤   ¤   derr = VolFile::Unmount(isThisEmergency);
689371 ¤   }
72af5a
352361 ¤   if (derr.IsntError())
d6c7a1 ¤   {
c350ae ¤   ¤   // Mark as not mounted.
0159de ¤   ¤   if (!wasReadOnly)
80775a ¤   ¤   ¤   SetPGPdiskMountedFlag(pathCopy, FALSE);
55af5a
e6b1f6 ¤   ¤   // Stop the thread.
af3d8b ¤   ¤   mWorkerThread.KillThread();
84af5a
48e959 ¤   ¤   // Unflip the contexts and destroy them.
62ddef ¤   ¤   (mContextA->IsFlipped() ? mContextA->FlipContext() :·
8d5c73 ¤   ¤   ¤   mContextB->FlipContext());
a8af5a
ca2a01 ¤   ¤   mContextA->DestroyContext();
1373b5 ¤   ¤   mContextB->DestroyContext();
279371 ¤   }
b3af5a
98a8b0 ¤   if (dupedPath)
39c781 ¤   ¤   delete[] pathCopy;
f2af5a
9733e3 ¤   return derr;
f0efe6 }
--1d90 00082e81be7401100fe Page 6 of PGPdisk.cpp
e0af5a
0ef3d6 // Read performs a read request on the mounted PGPdisk.
d7af5a
992292 DualErr·
ba529f PGPdisk::Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
a7bb36 {
edbe41 ¤   DualErr¤¤   derr;
30698c ¤   PGPUInt32¤  blocksChunk, blocksToRead, bufPos;
986431 ¤   PGPUInt64¤  blockPGPdisk;
f2af5a
0eb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
4e3ec3 ¤   pgpAssert(Mounted());
d4af5a
6a9a60 ¤   DebugOut("PGPdisk: Reading PGPdisk %u at pos %u nBlocks %u\n",·
9baaab ¤   ¤   GetDrive(), (PGPUInt32) (pos/kDefaultBlockSize),·
0f63c8 ¤   ¤   (PGPUInt32) (nBytes/kDefaultBlockSize));
56af5a
f802d5 ¤   // The position (pos) and size (nBytes) variables are in bytes, but we
830520 ¤   // can only perform encryption in blocks. What we have to do is handle
bedb45 ¤   // the request in at most three separate pieces - a head, middle, and
340141 ¤   // end.
4baf5a
7c3fc7 ¤   bufPos = 0;
8daf5a
499f70 ¤   if (pos%kDefaultBlockSize > 0)¤ // is there a head?
67c7a1 ¤   {
66cf6a ¤   ¤   PGPUInt32 headOffset, headSize;
b9af5a
ee3423 ¤   ¤   // Now read in the head.
ab65af ¤   ¤   //
60f029 ¤   ¤   // blockPGPdisk = block on PGPdisk containing the head.
4f3c6d ¤   ¤   // headOffset = byte offset into blockPGPdisk where head starts
81a924 ¤   ¤   // headSize = size of the head, in bytes
dcaf5a
84b99d ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
d3a0b8 ¤   ¤   headOffset¤ ¤   = (PGPUInt32) (pos%kDefaultBlockSize);
408ad4 ¤   ¤   headSize¤   ¤   = min(nBytes, kDefaultBlockSize - headOffset);
89af5a
f07acd ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
f1ecb7 ¤   ¤   ¤   kDefaultBlockSize);
6eaf5a
bcaa35 ¤   ¤   if (derr.IsntError())
ba5b34 ¤   ¤   {
e17970 ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
8f280f ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
2daf5a
db0760 ¤   ¤   ¤   pgpCopyMemory(mDataBuf + headOffset, buf, headSize);
f8af5a
f54bf3 ¤   ¤   ¤   bufPos¤ = headSize;
f21e59 ¤   ¤   ¤   pos¤¤   += headSize;
95cc39 ¤   ¤   ¤   nBytes¤ -= headSize;
2f0fe4 ¤   ¤   }
689371 ¤   }
8caf5a
d2325c ¤   // Read in the middle, in 'kPGDBlocksPerOp' chunks.
372361 ¤   if (derr.IsntError())
74c7a1 ¤   {
cf0110 ¤   ¤   blocksToRead = nBytes/kDefaultBlockSize;
96af5a
fa1424 ¤   ¤   while (derr.IsntError() && (blocksToRead > 0))¤ // is there a middle?
a05b34 ¤   ¤   {
6e7eb3 ¤   ¤   ¤   // Determine exactly how many blocks to read this iteration.
b80415 ¤   ¤   ¤   //
40488d ¤   ¤   ¤   // blockPGPdisk = block on the PGPdisk where this read begins
86bdea ¤   ¤   ¤   // blocksChunk = the most blocks we can read in this iteration
60af5a
17ea86 ¤   ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
5770b2 ¤   ¤   ¤   blocksChunk¤¤   = min(blocksToRead, kPGDBlocksPerOp);
e8af5a
8161c4 ¤   ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
e0a838 ¤   ¤   ¤   ¤   blocksChunk*kDefaultBlockSize);
82af5a
--eea8 000153f6c0b401100fe Page 7 of PGPdisk.cpp
729d3d ¤   ¤   ¤   if (derr.IsntError())
45f776 ¤   ¤   ¤   {
61a8e1 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, blocksChunk, mDataBuf,·
44aa4a ¤   ¤   ¤   ¤   ¤   buf + bufPos, kCipherOp_Decrypt);
c3af5a
29288b ¤   ¤   ¤   ¤   bufPos¤ ¤   ¤   += blocksChunk * kDefaultBlockSize;
8b87b7 ¤   ¤   ¤   ¤   nBytes¤ ¤   ¤   -= blocksChunk * kDefaultBlockSize;
951c83 ¤   ¤   ¤   ¤   pos¤¤   ¤   ¤   += blocksChunk * kDefaultBlockSize;
c3933a ¤   ¤   ¤   ¤   blocksToRead¤   -= blocksChunk;
60a3a6 ¤   ¤   ¤   }
730fe4 ¤   ¤   }
b69371 ¤   }
3467c5 ¤
21e34f ¤   // Read in the tail.
032361 ¤   if (derr.IsntError())
4fc7a1 ¤   {
afa63d ¤   ¤   if (nBytes)¤¤   ¤   ¤   ¤   // is there a tail?¤
ad5b34 ¤   ¤   {
3fee47 ¤   ¤   ¤   // This read is very simple because we know the tail begins on a
f60137 ¤   ¤   ¤   // block boundary.
740415 ¤   ¤   ¤   //
189913 ¤   ¤   ¤   // blockPGPdisk = the block in the PGPdisk containing the tail.
1daf5a
8e5b3c ¤   ¤   ¤   blockPGPdisk = pos/kDefaultBlockSize;
d7af5a
5a61c4 ¤   ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
f5674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
64af5a
679d3d ¤   ¤   ¤   if (derr.IsntError())
5bf776 ¤   ¤   ¤   {
363707 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
f0ed5a ¤   ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
8faf5a
8cbec9 ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf, buf + bufPos, nBytes);
eca3a6 ¤   ¤   ¤   }
940fe4 ¤   ¤   }
bf9371 ¤   }
d6af5a
8133e3 ¤   return derr;
5aefe6 }
e3af5a
7b9a91 // Write performs a write request on the mounted PGPdisk.
43af5a
f82292 DualErr·
c25bcc PGPdisk::Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
04bb36 {
2cbe41 ¤   DualErr¤¤   derr;
1a1fbb ¤   PGPUInt32¤  blocksChunk, blocksToWrite, bufPos;
ac6431 ¤   PGPUInt64¤  blockPGPdisk;
fcaf5a
0bb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
b63ec3 ¤   pgpAssert(Mounted());
c4af5a
f7b5d0 ¤   DebugOut("PGPdisk: Writing PGPdisk %u at pos %u nBlocks %u\n",·
32aaab ¤   ¤   GetDrive(), (PGPUInt32) (pos/kDefaultBlockSize),·
5563c8 ¤   ¤   (PGPUInt32) (nBytes/kDefaultBlockSize));
0caf5a
e802d5 ¤   // The position (pos) and size (nBytes) variables are in bytes, but we
020520 ¤   // can only perform encryption in blocks. What we have to do is handle
0adb45 ¤   // the request in at most three separate pieces - a head, middle, and
e40141 ¤   // end.
f7af5a
b23fc7 ¤   bufPos = 0;
cfaf5a
e29f70 ¤   if (pos%kDefaultBlockSize > 0)¤ // is there a head?
c1c7a1 ¤   {
bdcf6a ¤   ¤   PGPUInt32 headOffset, headSize;
feaf5a
3b328c ¤   ¤   // Now write the head.
8a65af ¤   ¤   //
0ff029 ¤   ¤   // blockPGPdisk = block on PGPdisk containing the head.
153c6d ¤   ¤   // headOffset = byte offset into blockPGPdisk where head starts
--11d9 000650c5369401100fe Page 8 of PGPdisk.cpp
84a924 ¤   ¤   // headSize = size of the head, in bytes
98af5a
39b99d ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
60a0b8 ¤   ¤   headOffset¤ ¤   = (PGPUInt32) (pos%kDefaultBlockSize);
f38ad4 ¤   ¤   headSize¤   ¤   = min(nBytes, kDefaultBlockSize - headOffset);
86af5a
ce7acd ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
35ecb7 ¤   ¤   ¤   kDefaultBlockSize);
d8af5a
58aa35 ¤   ¤   if (derr.IsntError())
935b34 ¤   ¤   {
6f7970 ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
dc280f ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
76af5a
edbb98 ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf + headOffset, headSize);
a8af5a
907970 ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
50ade5 ¤   ¤   ¤   ¤   kCipherOp_Encrypt);
31af5a
a2cc78 ¤   ¤   ¤   derr = VolFile::Write(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
64674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
670fe4 ¤   ¤   }
abaf5a
29aa35 ¤   ¤   if (derr.IsntError())
455b34 ¤   ¤   {
504bf3 ¤   ¤   ¤   bufPos¤ = headSize;
741e59 ¤   ¤   ¤   pos¤¤   += headSize;
d2cc39 ¤   ¤   ¤   nBytes¤ -= headSize;
4d0fe4 ¤   ¤   }
7f9371 ¤   }
baaf5a
78eea7 ¤   // Write the middle, in 'kPGDBlocksPerOp' chunks.
132361 ¤   if (derr.IsntError())
ebc7a1 ¤   {
aea377 ¤   ¤   blocksToWrite = nBytes/kDefaultBlockSize;
90af5a
963ee4 ¤   ¤   while (derr.IsntError() && (blocksToWrite > 0))¤// is there a middle?
6e5b34 ¤   ¤   {
f9d041 ¤   ¤   ¤   // Determine exactly how many blocks to write this iteration.
510415 ¤   ¤   ¤   //
40445a ¤   ¤   ¤   // blockPGPdisk = block on the PGPdisk where this write begins
357d91 ¤   ¤   ¤   // blocksChunk = the most blocks we can write in this iteration
4daf5a
7aea86 ¤   ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
5ad7f8 ¤   ¤   ¤   blocksChunk¤¤   = min(blocksToWrite, kPGDBlocksPerOp);
e6af5a
46071c ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, blocksChunk, buf + bufPos,·
243115 ¤   ¤   ¤   ¤   mDataBuf, kCipherOp_Encrypt);
ecaf5a
3acc78 ¤   ¤   ¤   derr = VolFile::Write(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
82a838 ¤   ¤   ¤   ¤   blocksChunk*kDefaultBlockSize);
48af5a
299d3d ¤   ¤   ¤   if (derr.IsntError())
ebf776 ¤   ¤   ¤   {
81288b ¤   ¤   ¤   ¤   bufPos¤ ¤   ¤   += blocksChunk * kDefaultBlockSize;
b087b7 ¤   ¤   ¤   ¤   nBytes¤ ¤   ¤   -= blocksChunk * kDefaultBlockSize;
d11c83 ¤   ¤   ¤   ¤   pos¤¤   ¤   ¤   += blocksChunk * kDefaultBlockSize;
960934 ¤   ¤   ¤   ¤   blocksToWrite¤  -= blocksChunk;
97a3a6 ¤   ¤   ¤   }
620fe4 ¤   ¤   }
249371 ¤   }
8567c5 ¤
5103fc ¤   // Write in the tail.
7e2361 ¤   if (derr.IsntError())
e5c7a1 ¤   {
aca63d ¤   ¤   if (nBytes)¤¤   ¤   ¤   ¤   // is there a tail?¤
565b34 ¤   ¤   {
8aee47 ¤   ¤   ¤   // This read is very simple because we know the tail begins on a
110137 ¤   ¤   ¤   // block boundary.
340415 ¤   ¤   ¤   //
bc9913 ¤   ¤   ¤   // blockPGPdisk = the block in the PGPdisk containing the tail.
65af5a
--1c59 001dbe42de1401100fe Page 9 of PGPdisk.cpp
245b3c ¤   ¤   ¤   blockPGPdisk = pos/kDefaultBlockSize;
24af5a
2761c4 ¤   ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
98674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
65af5a
a49d3d ¤   ¤   ¤   if (derr.IsntError())
b4f776 ¤   ¤   ¤   {
133707 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
3ded5a ¤   ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
1baf5a
9e75af ¤   ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf, nBytes);
b1af5a
b73707 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
3468b0 ¤   ¤   ¤   ¤   ¤   kCipherOp_Encrypt);
b3af5a
30e950 ¤   ¤   ¤   ¤   derr = VolFile::Write(mDataBuf,·
a2401c ¤   ¤   ¤   ¤   ¤   blockPGPdisk*kDefaultBlockSize, kDefaultBlockSize);
7da3a6 ¤   ¤   ¤   }
710fe4 ¤   ¤   }
1f9371 ¤   }
3baf5a
5033e3 ¤   return derr;
afefe6 }
0faf5a
59af5a
92ed79 /////////////////////////////////////////
1a5286 // Class PGPdisk private member functions
b0ed79 /////////////////////////////////////////
47af5a
cad4f9 // SmartCipherBlocks performs the given cipher operation using whichever
74d739 // cipher context isn't flipped.
4baf5a
95c823 void·
3933c0 PGPdisk::SmartCipherBlocks(
e6142c ¤   PGPUInt64¤  startBlockIndex,·
b9e7f5 ¤   PGPUInt32¤  nBlocks,·
32bfcb ¤   const void¤ *src,·
35dc73 ¤   void¤   ¤   *dest,·
a99985 ¤   CipherOp¤   op)
35bb36 {
add909 ¤   pgpAssertAddrValid(mContextA, CipherContext);
1864c3 ¤   pgpAssertAddrValid(mContextB, CipherContext);
1487c7 ¤   ¤   ¤
5ac569 ¤   mContextMutex.Enter();
d3af5a
3cd50c ¤   if (mContextA->IsFlipped())
094ad9 ¤   ¤   mContextB->CipherBlocks(startBlockIndex, nBlocks, src, dest, op);
5f0e24 ¤   else
2c5d16 ¤   ¤   mContextA->CipherBlocks(startBlockIndex, nBlocks, src, dest, op);
25af5a
e1df09 ¤   mContextMutex.Leave();
dbefe6 }
--765b 0000925aa1c401100ff Page 1 of PGPdisk.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d75cf4 // PGPdisk.h
2f465d //
dcdda2 // Declaration of class PGPdisk.
a11bc3 //////////////////////////////////////////////////////////////////////////////
92af5a
20ee23 // $Id: PGPdisk.h,v 1.1.4.15 1998/07/30 00:50:24 nryan Exp $
88af5a
c3cbce // Copyright (C) 1998 by Network Associates, Inc.
7c71ae // All rights reserved.
57af5a
c2849e #ifndef Included_PGPdisk_h¤ // [
301582 #define Included_PGPdisk_h
90af5a
4f3a85 #include "DualErr.h"
25555c #include "GenericCallback.h"
04c16a #include "PGPdiskFileFormat.h"
b3af5a
1b8c21 #include "CipherContext.h"
5caf5a
6fa844 #include "PGPdiskWorkerThread.h"
bdb3b1 #include "VolFile.h"
87af5a
14af5a
b09791 ////////////////
ee0e4d // Class PGPdisk
429791 ////////////////
0daf5a
2ed155 // Class PGPdisk represents a PGPdisk file. In the future it will handle
2a56d2 // encryption and decryption of the data area but for now it just handles
c53377 // parsing of the file header.
3caf5a
7cd265 class PGPdisk : public VolFile
16bb36 {
9a5ed4 public:
4fda4d ¤   DualErr¤mInitErr;
3baf5a
aab432 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdisk();
40b10b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ~PGPdisk();
c4af5a
de3e50 ¤   PGPBoolean¤ ¤   ¤   ¤   BestGuessComparePaths(LPCSTR path);
a11d37 ¤   PGPUInt64¤  ¤   ¤   ¤   GetUniqueSessionId();
50c8f4 ¤   PGPdiskWorkerThread *¤  GetThread();
4aaf5a
126b69 ¤   void¤   ¤   ¤   ¤   ¤   FlipContexts();
7b7945 ¤   DualErr¤¤   ¤   ¤   ¤   ValidateContexts();
73af5a
6c214c ¤   DualErr¤¤   ¤   ¤   ¤   Mount(LPCSTR path, CipherContext *pContext,·
fea755 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive,·
b0d673 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly = FALSE);
86db69 ¤   DualErr¤¤   ¤   ¤   ¤   ¤   Unmount(PGPBoolean isThisEmergency = FALSE);
7caf5a
8edfbd ¤   DualErr¤¤   ¤   ¤   ¤   Read(PGPUInt8 *buf, PGPUInt64 pos,·
61c85f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 nBytes);
7b3c7a ¤   DualErr¤¤   ¤   ¤   ¤   Write(PGPUInt8 *buf, PGPUInt64 pos,·
cec85f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 nBytes);
82af5a
f50fb9 private:
b74523 ¤   CipherContext¤  ¤   *mContextA;¤¤   ¤   // cipher context A
472806 ¤   CipherContext¤  ¤   *mContextB;¤¤   ¤   // cipher context B
b4af5a
4cd547 ¤   PGPdiskWorkerThread¤mWorkerThread;¤ ¤   // thread for PGPdisk
03af5a
78aaa2 ¤   PGPUInt64¤  ¤   ¤   mUniqueSessionId;¤  // unique session ID
1e33f5 ¤   PGPUInt8¤   ¤   ¤   *mDataBuf;¤ ¤   ¤   // data buffer
71af5a
254828 ¤   PGPdiskMutex¤   ¤   mContextMutex;¤ ¤   // mutex for context use
bdaf5a
416d9d ¤   SecureMemory¤   ¤   mSmContextA;¤   ¤   // secure mem for context A
6cb0bc ¤   SecureMemory¤   ¤   mSmContextB;¤   ¤   // secure mem for context B
09af5a
090667 ¤   void¤   SmartCipherBlocks(PGPUInt64 startBlockIndex, PGPUInt32 nBlocks,·
--3b0a 001987a2168401100ff Page 2 of PGPdisk.h
325ad3 ¤   ¤   ¤   ¤   const void *src, void *dest, CipherOp op);
5182f7 };
caaf5a
98ac0b #endif¤ // ] Included_PGPdisk_h
--92d2 0001b687a2a40110100 Page 1 of PGPdiskRequestQueue.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
044709 // PGPdiskRequestQueue.cpp
31465d //
6ac918 // Definition of class PGPdiskRequestQueue.
a71bc3 //////////////////////////////////////////////////////////////////////////////
7caf5a
54af12 // $Id: PGPdiskRequestQueue.cpp,v 1.1.2.14 1998/07/06 08:57:54 nryan Exp $
1daf5a
e2cbce // Copyright (C) 1998 by Network Associates, Inc.
c371ae // All rights reserved.
68af5a
22d7a1 #include <vdw.h>
f0af5a
7b9bcf #include "Required.h"
f9af5a
77c411 #include "Globals.h"
392090 #include "PGPdiskRequestQueue.h"
09a844 #include "PGPdiskWorkerThread.h"
3468c6 #include "PGPdisk.h"
e0af5a
adaf5a
6409b7 ////////////
58e738 // Constants
3909b7 ////////////
c1af5a
9f5b0d const PGPUInt16 kPGPdiskDefaultPRQDepth = 32;
acaf5a
f3af5a
429c30 ////////////////////////////////////////////////////
ae5734 // Class PGPdiskRequestQueue public member functions
f29c30 ////////////////////////////////////////////////////
36af5a
39d5a0 // The PGPdiskRequestQueue default constructor.
aeaf5a
8ea1f9 PGPdiskRequestQueue::PGPdiskRequestQueue()·
178cc7 ¤   : mPRQAllocator(kPGPdiskDefaultPRQDepth)
40bb36 {
9eabf4 ¤   mInitErr = mPRQAllocator.mInitErr;
88efe6 }
58af5a
fd8898 // The PGPdiskRequestQueue destructor.
d0af5a
9292f9 PGPdiskRequestQueue::~PGPdiskRequestQueue()
b2bb36 {
53efe6 }
d5af5a
f9d296 // Count returns the number of request in the queue.
4caf5a
c81b0b PGPUInt32·
fb64dd PGPdiskRequestQueue::Count()
2ebb36 {
6cce1b ¤   return mPRQList.Count();
6fefe6 }
e8af5a
411890 // QueueIrpForProcessing queues an IRP for processing.
f1af5a
dd2292 DualErr·
01374f PGPdiskRequestQueue::QueueIrpForProcessing(PIRP pIrp)
78bb36 {
75be41 ¤   DualErr¤¤   derr;
93efa8 ¤   KIrp¤   ¤   I(pIrp);
dc88df ¤   PRQRequest¤ *pReq;
04af5a
e2fb7a ¤   pgpAssertAddrValid(pIrp, IRP);
85af5a
17ac54 ¤   // Get memory for request structure.
7ecc2b ¤   derr = mPRQAllocator.Allocate(&pReq);
8eaf5a
2343b1 ¤   // Initialize the request and place it in the queue.
8a2361 ¤   if (derr.IsntError())
56c7a1 ¤   {
1b68d0 ¤   ¤   pReq->op¤   = kPRQOp_ProcessIrp;
--b638 000640d6ce640110100 Page 2 of PGPdiskRequestQueue.cpp
9623fd ¤   ¤   pReq->pIrp¤ = pIrp;
73af5a
a830a4 ¤   ¤   I.MarkPending();
0204a8 ¤   ¤   I.SetCancelRoutine(Cancel);
f1af5a
fbce4b ¤   ¤   Push(pReq);
4e9371 ¤   }
3baf5a
f533e3 ¤   return derr;
5befe6 }
f0af5a
42a2cd // QueueAsyncCallback queues an async callback request.
c7af5a
082292 DualErr·
82ace1 PGPdiskRequestQueue::QueueAsyncCallback(
db65ec ¤   PEZCALLBACK¤callback,·
296896 ¤   PGPUInt32¤  refData)
babb36 {
6ebe41 ¤   DualErr¤¤   derr;
c588df ¤   PRQRequest¤ *pReq;
aeaf5a
39f8bc ¤   pgpAssertAddrValid(callback, VoidAlign);
a4af5a
58ac54 ¤   // Get memory for request structure.
01cc2b ¤   derr = mPRQAllocator.Allocate(&pReq);
0aaf5a
8843b1 ¤   // Initialize the request and place it in the queue.
fd2361 ¤   if (derr.IsntError())
9cc7a1 ¤   {
33d1af ¤   ¤   pReq->op¤   ¤   = kPRQOp_AsyncCallback;
09d980 ¤   ¤   pReq->callback¤ = callback;
5ef545 ¤   ¤   pReq->refData¤  = refData;
c6af5a
c1ce4b ¤   ¤   Push(pReq);
b69371 ¤   }
1aaf5a
3c33e3 ¤   return derr;
9cefe6 }
abaf5a
eab217 // QueueSyncCallback queues a ssync callback request.
6caf5a
c72292 DualErr·
964143 PGPdiskRequestQueue::QueueSyncCallback(
9f65ec ¤   PEZCALLBACK¤callback,·
dfed26 ¤   PGPUInt32¤  refData,·
2de628 ¤   PKEVENT¤¤   pEvent)
66bb36 {
a2be41 ¤   DualErr¤¤   derr;
1088df ¤   PRQRequest¤ *pReq;
70af5a
7bf8bc ¤   pgpAssertAddrValid(callback, VoidAlign);
d1f71f ¤   pgpAssertAddrValid(pEvent, KEVENT);
daaf5a
3cac54 ¤   // Get memory for request structure.
cfcc2b ¤   derr = mPRQAllocator.Allocate(&pReq);
2faf5a
6a43b1 ¤   // Initialize the request and place it in the queue.
682361 ¤   if (derr.IsntError())
32c7a1 ¤   {
a45ad6 ¤   ¤   pReq->op¤   ¤   ¤   = kPRQOp_SyncCallback;
989fde ¤   ¤   pReq->callback¤ ¤   = callback;
44bfc0 ¤   ¤   pReq->refData¤  ¤   = refData;
eec3ff ¤   ¤   pReq->pSyncEvent¤   = pEvent;
0caf5a
e2ce4b ¤   ¤   Push(pReq);
2b9371 ¤   }
5caf5a
8633e3 ¤   return derr;
d2efe6 }
42af5a
662dc1 // ReturnPRQ is called to return a processed PRQRequest to the memory pool.
64af5a
--4e2b 000296796af40110100 Page 3 of PGPdiskRequestQueue.cpp
84c823 void·
d2af24 PGPdiskRequestQueue::ReturnPRQ(PRQRequest *pReq)
2dbb36 {
7f23ec ¤   pgpAssertAddrValid(pReq, PRQRequest);
87af5a
a31c03 ¤   mPRQAllocator.Free(pReq);
0befe6 }
e6af5a
91982a // CancelIRPs cancels all outstanding IRPs in the queue for a given drive.
32af5a
28c823 void·
665928 PGPdiskRequestQueue::CancelIRPs(PGPUInt8 drive)
e3bb36 {
048842 ¤   KIrp¤   ¤   I;
c488df ¤   PRQRequest¤ *pReq;
0d0721 ¤   PGPUInt32¤  i;
53af5a
e5aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
c2af5a
13303d ¤   mPRQList.PublicLock();
18af5a
a32352 ¤   pReq = mPRQList.Head();
78af5a
bf8d52 ¤   // For every request in the queue...
9939b8 ¤   for (i = 0; i < mPRQList.Count(); i++)
cdc7a1 ¤   {
903542 ¤   ¤   if (IsNull(pReq))
14cdcb ¤   ¤   ¤   break;
85af5a
020a9f ¤   ¤   // ... if it is an IRP request...
4a4f53 ¤   ¤   if (pReq->op == kPRQOp_ProcessIrp)
bb5b34 ¤   ¤   {
0ed12e ¤   ¤   ¤   PDEVICE_OBJECT¤ pDevObj;
c01596 ¤   ¤   ¤   PGPdisk¤¤   ¤   *pPGD;
5fcc36 ¤   ¤   ¤   PGPUInt8¤   ¤   irpDrive;
83af5a
c6cec1 ¤   ¤   ¤   // ... and matches the drive letter we are cancelling...
0e5c60 ¤   ¤   ¤   I = KIrp(pReq->pIrp);
e4af5a
ff6fc1 ¤   ¤   ¤   pDevObj = I.DeviceObject();
8e86ab ¤   ¤   ¤   pgpAssertAddrValid(pDevObj, DEVICE_OBJECT);
75af5a
f2c3e8 ¤   ¤   ¤   pPGD = (PGPdisk *) pDevObj->DeviceExtension;
4fc453 ¤   ¤   ¤   pgpAssertAddrValid(pPGD, PGPdisk);
9aaf5a
cf8586 ¤   ¤   ¤   irpDrive = pPGD->GetDrive();
04dced ¤   ¤   ¤   pgpAssert(IsLegalDriveNumber(drive));
cbaf5a
0eebf8 ¤   ¤   ¤   // ... then cancel it and remove it from the queue.
14208f ¤   ¤   ¤   if (irpDrive == drive)
d3f776 ¤   ¤   ¤   {
bf041f ¤   ¤   ¤   ¤   mPRQList.Remove(pReq);
d74ac5 ¤   ¤   ¤   ¤   ReturnPRQ(pReq);
5eaf5a
6869d9 ¤   ¤   ¤   ¤   I.SetCancelRoutine(NULL);
259b18 ¤   ¤   ¤   ¤   I.Information() = 0;
6d4b3a ¤   ¤   ¤   ¤   I.Complete(STATUS_CANCELLED);
4caf5a
77c0a5 ¤   ¤   ¤   ¤   pReq = mPRQList.Head();
cda3a6 ¤   ¤   ¤   }
bdbb8c ¤   ¤   ¤   else
30f776 ¤   ¤   ¤   {
58d705 ¤   ¤   ¤   ¤   pReq = mPRQList.Next(pReq);
33a3a6 ¤   ¤   ¤   }
810fe4 ¤   ¤   }
470e1d ¤   ¤   else
765b34 ¤   ¤   {
215f63 ¤   ¤   ¤   pReq = mPRQList.Next(pReq);
570fe4 ¤   ¤   }
b49371 ¤   }
52af5a
293c01 ¤   mPRQList.PublicUnlock();
--db8c 000ff585c2140110100 Page 4 of PGPdiskRequestQueue.cpp
7aefe6 }
46af5a
01270c // Pop pops a request from the bottom of the queue. TRUE if successful, FALSE
764da2 // otherwise.
4ad83c ·
942825 PRQRequest *·
31a227 PGPdiskRequestQueue::Pop()
64bb36 {
6afa60 ¤   PRQRequest *pReq;
36af5a
7cf83b ¤   // If list is empty, bail.
6afadb ¤   if (mPRQList.IsEmpty())
3b7ed2 ¤   ¤   return NULL;
82af5a
2bf8f3 ¤   // Pop an item off the queue.
09303d ¤   mPRQList.PublicLock();
afd41c ¤   pReq = mPRQList.RemoveTail();
6b3c01 ¤   mPRQList.PublicUnlock();
9caf5a
da49e8 ¤   // Clear cancel routine for IRP requests.
4f411f ¤   if (pReq->op == kPRQOp_ProcessIrp)
5bc7a1 ¤   {
323743 ¤   ¤   KIrp I = pReq->pIrp;
85af5a
469e2f ¤   ¤   I.SetCancelRoutine(NULL);¤
aa9371 ¤   }
ebaf5a
88fe16 ¤   return pReq;
e2efe6 }
8daf5a
ddaf5a
aac3ce /////////////////////////////////////////////////////
d5750b // Class PGPdiskRequestQueue private member functions
63c3ce /////////////////////////////////////////////////////
a1af5a
677f60 // Push pushes a new request on top of the queue. TRUE if successful, FALSE
564da2 // otherwise.
55af5a
7ec823 void·
102bc6 PGPdiskRequestQueue::Push(PRQRequest *pReq)
7abb36 {
6923ec ¤   pgpAssertAddrValid(pReq, PRQRequest);
03af5a
c45d4c ¤   // Insert the request into the queue.
b3303d ¤   mPRQList.PublicLock();
6864cd ¤   mPRQList.InsertHead(pReq);
3b3c01 ¤   mPRQList.PublicUnlock();
ddefe6 }
0faf5a
fef9f5 // CancelAux looks for and cancels an IRP in the queue.
7caf5a
2ac823 void·
371482 PGPdiskRequestQueue::CancelAux()
0dbb36 {
0f8842 ¤   KIrp¤   ¤   I;
dc88df ¤   PRQRequest¤ *pReq;
622f41 ¤   PGPBoolean¤ foundIrpToCancel¤   = FALSE;
530721 ¤   PGPUInt32¤  i;
11af5a
b3303d ¤   mPRQList.PublicLock();
1caf5a
c62352 ¤   pReq = mPRQList.Head();
ddaf5a
473da0 ¤   // Find an IRP in need of a cancel.
1639b8 ¤   for (i = 0; i < mPRQList.Count(); i++)
86c7a1 ¤   {
583542 ¤   ¤   if (IsNull(pReq))
36cdcb ¤   ¤   ¤   break;
2aaf5a
334f53 ¤   ¤   if (pReq->op == kPRQOp_ProcessIrp)
085b34 ¤   ¤   {
ff5c60 ¤   ¤   ¤   I = KIrp(pReq->pIrp);
--a5db 001a932b2d440110100 Page 5 of PGPdiskRequestQueue.cpp
e0af5a
2ac02e ¤   ¤   ¤   foundIrpToCancel = TRUE;
55cdcb ¤   ¤   ¤   break;
cb0fe4 ¤   ¤   }
94af5a
059a36 ¤   ¤   pReq = mPRQList.Next(pReq);
499371 ¤   }
3daf5a
e2ccb0 ¤   // If we found one, complete it and remove it from the queue.
a62851 ¤   if (foundIrpToCancel)
e5c7a1 ¤   {
10c993 ¤   ¤   mPRQList.Remove(pReq);
968757 ¤   ¤   mPRQList.PublicUnlock();
4caf5a
f9c5ce ¤   ¤   ReturnPRQ(pReq);
2aaf5a
2b1d26 ¤   ¤   I.Information() = 0;
d34e11 ¤   ¤   I.Complete(STATUS_CANCELLED);
b89371 ¤   }
290e24 ¤   else
d0c7a1 ¤   {
eb8757 ¤   ¤   mPRQList.PublicUnlock();
ff9371 ¤   }
04efe6 }
f7af5a
0db49b // Cancel is the static member function set as the cancel routine for all
e72554 // IRPs put into the queue.
34af5a
b6a1ba VOID·
d5bafa PGPdiskRequestQueue::Cancel(PDEVICE_OBJECT pDevObj, PIRP pIrp)
aabb36 {
6ff0dd ¤   KIrp¤   ¤   ¤   ¤   I(pIrp);
31c094 ¤   PGPdisk¤¤   ¤   ¤   *pPGD;
8d94de ¤   PGPdiskRequestQueue¤*pPRQ;
f4af5a
9a0f53 ¤   CancelSpinLock::Release(I.CancelIrql());
75af5a
b79c99 ¤   // Extract PGPdisk pointer.
afffc0 ¤   pPGD = (PGPdisk *) pDevObj->DeviceExtension;
255b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
82af5a
025e68 ¤   // Call the associated request queue cancel function.
00be71 ¤   pPRQ = pPGD->GetThread()->GetRequestQueue();
d3df72 ¤   pgpAssertAddrValid(pPRQ, PGPdiskRequestQueue);
e3af5a
a21177 ¤   pPRQ->CancelAux();
a9efe6 }
--acef 0008e62aadf40110101 Page 1 of PGPdiskRequestQueue.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d50561 // PGPdiskRequestQueue.h
36465d //
e60a51 // Declaration of class PGPdiskRequestQueue.
3e1bc3 //////////////////////////////////////////////////////////////////////////////
19af5a
2a6647 // $Id: PGPdiskRequestQueue.h,v 1.1.2.12 1998/07/06 08:57:55 nryan Exp $
48af5a
12cbce // Copyright (C) 1998 by Network Associates, Inc.
c071ae // All rights reserved.
9baf5a
99baf6 #ifndef Included_PGPdiskRequestQueue_h¤ // [
aaa93b #define Included_PGPdiskRequestQueue_h
a4af5a
d53a85 #include "DualErr.h"
6a555c #include "GenericCallback.h"
00af5a
c18c21 #include "CipherContext.h"
f4af5a
fe9281 #include "CPGPdiskDriver.h"
933d34 #include "LockableList.h"
b94ead #include "LookasideList.h"
fcaf5a
2daf5a
8809b7 ////////////
3ae738 // Constants
e609b7 ////////////
08af5a
cffa42 const PGPUInt32¤kPRQMaxRequests = 100;¤ ¤   // max requests in queue
55af5a
87af5a
a0d557 ////////
bd02c9 // Types
e2d557 ////////
13af5a
a69e57 class PGPdisk;
ccaf5a
177284 // PRQOp describes the operation embedded in a PRQRequest.
eeaf5a
829158 enum PRQOp {kPRQOp_ProcessIrp, kPRQOp_AsyncCallback, kPRQOp_SyncCallback,·
75f8e9 ¤   kPRQOp_InvalidRequest};
2daf5a
cccc1e // A PRQRequest request structure describes requests that can be stored in
6f16c9 // the queue.
ddaf5a
bead45 typedef struct PRQRequest
0cbb36 {
9373d5 ¤   // Common members:
f1af5a
5f4f3a ¤   LIST_ENTRY¤ m_ListEntry;
4613b8 ¤   PRQOp¤  ¤   op;
80af5a
27f5eb ¤   // For kPRQOp_ProcessIrp:
3aaf5a
735d74 ¤   PIRP pIrp;
b1af5a
a5add4 ¤   // For kPRQOp_AsyncCallback and kPRQOp_SyncCallback.
98af5a
c9a0b5 ¤   PEZCALLBACK callback;
8cf051 ¤   PGPUInt32 refData;
36af5a
5df351 ¤   PKEVENT pSyncEvent;
6eaf5a
3e62b7 } PRQRequest;
48af5a
9a73db typedef LookasideList<PRQRequest> PRQRequestAllocator;
c80dfa typedef LockableList<PRQRequest> PRQRequestList;
9caf5a
caaf5a
215270 ////////////////////////////
2f5649 // Class PGPdiskRequestQueue
8e5270 ////////////////////////////
--c659 001d560a19340110101 Page 2 of PGPdiskRequestQueue.h
e0af5a
eacd48 class PGPdiskRequestQueue
5ebb36 {
225ed4 public:
0b1603 ¤   DualErr mInitErr;
6faf5a
ad9a8c ¤   ¤   ¤   ¤   ¤   PGPdiskRequestQueue();
afe7a2 ¤   ¤   ¤   ¤   ¤   ~PGPdiskRequestQueue();
35af5a
530ea9 ¤   PGPUInt32¤  ¤   Count();
ccaf5a
3a4fb0 ¤   DualErr¤¤   ¤   QueueIrpForProcessing(PIRP pIrp);
b0f7c8 ¤   DualErr¤¤   ¤   QueueAsyncCallback(PEZCALLBACK callback,·
2bee05 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 refData);
2fea35 ¤   DualErr¤¤   ¤   QueueSyncCallback(PEZCALLBACK callback,·
b6ffc3 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 refData, PKEVENT pEvent);
9aaf5a
a19ead ¤   void¤   ¤   ¤   CancelIRPs(PGPUInt8 drive);
b6af5a
b31a6d ¤   void¤   ¤   ¤   ReturnPRQ(PRQRequest *pReq);
df7a9b ¤   PRQRequest *¤   Pop();
c6af5a
fb0fb9 private:
a341b7 ¤   PRQRequestAllocator¤mPRQAllocator;¤ ¤   // request allocator
cba331 ¤   PRQRequestList¤ ¤   mPRQList;¤  ¤   ¤   // linked list of requests
b0af5a
493458 ¤   void¤   ¤   Push(PRQRequest *pReq);
82af5a
702e8e ¤   void¤   ¤   CancelAux();
c463a2 ¤   static VOID¤Cancel(PDEVICE_OBJECT pDevObj, PIRP pIrp);
cb82f7 };
70af5a
d560ad #endif¤ // ] Included_PGPdiskRequestQueue_h
--53a4 00047beb6f640110102 Page 1 of PGPdiskWorkerThread.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
0dd728 // PGPdiskWorkerThread.cpp
62465d //
24111c // Implementation of class PGPdiskWorkerThread.
dc1bc3 //////////////////////////////////////////////////////////////////////////////
6aaf5a
a4c2f7 // $Id: PGPdiskWorkerThread.cpp,v 1.1.2.22 1998/07/28 21:07:48 nryan Exp $
0aaf5a
6ecbce // Copyright (C) 1998 by Network Associates, Inc.
9171ae // All rights reserved.
92af5a
d6d7a1 #include <vdw.h>
5faf5a
d99bcf #include "Required.h"
02bfe9 #include "UtilityFunctions.h"
1daf5a
60c411 #include "Globals.h"
9bf1f6 #include "KernelModeUtils.h"
4368c6 #include "PGPdisk.h"
5da844 #include "PGPdiskWorkerThread.h"
14af5a
07af5a
3b9c30 ////////////////////////////////////////////////////
743f7b // Class PGPdiskWorkerThread public member functions
d99c30 ////////////////////////////////////////////////////
6baf5a
0451f0 // The PGPdiskWorkerThread default constructor.
e5af5a
1c4162 PGPdiskWorkerThread::PGPdiskWorkerThread()·
171022 ¤   : KSystemThread(), mIoSem(0, kInfiniteKernelSemLimit)
d9bb36 {
3edc71 ¤   mExitThread = FALSE;
0c19ad ¤   mThreadRunning = FALSE;
d9af5a
94f2f3 ¤   mInitErr = mRequestQueue.mInitErr;
09af5a
3f9c32 ¤   if (mInitErr.IsntError())
26c7a1 ¤   {
2ebd2c ¤   ¤   mInitErr = mIoSem.mInitErr;
4d9371 ¤   }
82efe6 }
86af5a
528c03 // The PGPdiskWorkerThread destructor.
96af5a
5f46fa PGPdiskWorkerThread::~PGPdiskWorkerThread()
42bb36 {
b38a47 ¤   // Kill the thread.
fd5619 ¤   if (mThreadRunning)
df5dc1 ¤   ¤   KillThread();
f6efe6 }
deaf5a
618959 // IsThreadRunning returns TRUE if the thread is currently running, FALSE
3d4da2 // otherwise.
acaf5a
5077be PGPBoolean·
48c0cf PGPdiskWorkerThread::IsThreadRunning()
a6bb36 {
d895ce ¤   return mThreadRunning;
f8efe6 }
64af5a
aca7f1 // GetRequestQueue returns a pointer to the request queue for the thread.
ffaf5a
208055 PGPdiskRequestQueue *·
6e3612 PGPdiskWorkerThread::GetRequestQueue()
14bb36 {
5155f5 ¤   return &mRequestQueue;
ebefe6 }
a1af5a
564da5 // StartThread starts the thread.
4baf5a
fd2292 DualErr·
47dec2 PGPdiskWorkerThread::StartThread()
--3a21 0005af08b7240110102 Page 2 of PGPdiskWorkerThread.cpp
2cbb36 {
4bbe41 ¤   DualErr¤¤   derr;
fdfc8d ¤   NTSTATUS¤   status;
8caf5a
37dc71 ¤   mExitThread = FALSE;
b1af5a
e398fd ¤   status = Start(LinkTo(ProcessIo), this);
e7af5a
89df44 ¤   if (!NT_SUCCESS(status))
5a9237 ¤   ¤   derr = DualErr(kPGDMinorError_CreateSystemThreadFailed, status);
d3af5a
890c52 ¤   mThreadRunning = derr.IsntError();
08af5a
a633e3 ¤   return derr;
dbefe6 }
fdaf5a
061510 // KillThread kills the thread.
2aaf5a
dfc823 void·
d7cac5 PGPdiskWorkerThread::KillThread()
d1bb36 {
037d2d ¤   pgpAssert(IsThreadRunning());
c5af5a
9d6c17 ¤   // Ask thread to terminate.
636c4a ¤   mExitThread = TRUE;
98f6c9 ¤   mIoSem.Signal();
9eaf5a
5eacd5 ¤   // Wait for thread termination.
6c3208 ¤   Wait();
92af5a
9019ad ¤   mThreadRunning = FALSE;
beefe6 }
bcaf5a
7e1890 // QueueIrpForProcessing queues an IRP for processing.
44af5a
1d2292 DualErr·
6ca578 PGPdiskWorkerThread::QueueIrpForProcessing(PIRP pIrp)
6abb36 {
527d36 ¤   DualErr derr;
613a62 ¤   KIrp I(pIrp);
0baf5a
0f7d2d ¤   pgpAssert(IsThreadRunning());
1aaf5a
1af542 ¤   // Fire off the request.
692361 ¤   if (derr.IsntError())
41c7a1 ¤   {
8d5be6 ¤   ¤   derr = mRequestQueue.QueueIrpForProcessing(pIrp);
939371 ¤   }
aaaf5a
01a46a ¤   // Signal the thread that there is work waiting.
a82361 ¤   if (derr.IsntError())
89c7a1 ¤   {
954718 ¤   ¤   mIoSem.Signal();
339371 ¤   }
12af5a
ee33e3 ¤   return derr;
7fefe6 }
2eaf5a
c01225 // ScheduleAsyncCallback schedules a callback to occur in the context of the
4d8f4c // thread, and return immediately.
2faf5a
7b2292 DualErr·
aa3af3 PGPdiskWorkerThread::ScheduleAsyncCallback(
3165ec ¤   PEZCALLBACK¤callback,·
166896 ¤   PGPUInt32¤  refData)
25bb36 {
137d36 ¤   DualErr derr;
e1af5a
9af8bc ¤   pgpAssertAddrValid(callback, VoidAlign);
7c7d2d ¤   pgpAssert(IsThreadRunning());
a7af5a
5af542 ¤   // Fire off the request.
--240c 000d6da140840110102 Page 3 of PGPdiskWorkerThread.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
7ba59c ¤   ¤   derr = mRequestQueue.QueueAsyncCallback(callback, refData);
949371 ¤   }
f1af5a
9ca46a ¤   // Signal the thread that there is work waiting.
852361 ¤   if (derr.IsntError())
d1c7a1 ¤   {
244718 ¤   ¤   mIoSem.Signal();
109371 ¤   }
d3af5a
8c33e3 ¤   return derr;
6befe6 }
0eaf5a
395065 // ScheduleSyncCallback schedules a callback to occur in the context of the
07f9d3 // thread, and doesn't return until the callback is complete.
2eaf5a
222292 DualErr·
bfcaf1 PGPdiskWorkerThread::ScheduleSyncCallback(
9765ec ¤   PEZCALLBACK¤callback,·
066896 ¤   PGPUInt32¤  refData)
85bb36 {
a4945d ¤   DualErr¤derr;
cee7ee ¤   KEVENT¤ event;
c7af5a
b9f8bc ¤   pgpAssertAddrValid(callback, VoidAlign);
b27d2d ¤   pgpAssert(IsThreadRunning());
70af5a
922361 ¤   if (derr.IsntError())
69c7a1 ¤   {
e21c02 ¤   ¤   // Initialize the event.
65eb95 ¤   ¤   KeInitializeEvent(&event, NotificationEvent, FALSE);
9baf5a
cf4e14 ¤   ¤   // Fire off the request.
4b186f ¤   ¤   derr = mRequestQueue.QueueSyncCallback(callback, refData, &event);
729371 ¤   }
75af5a
1e2361 ¤   if (derr.IsntError())
b4c7a1 ¤   {
4acb59 ¤   ¤   // Signal the thread that there is work waiting.
f34718 ¤   ¤   mIoSem.Signal();
ccaf5a
e56095 ¤   ¤   // Wait for completion.
160a87 ¤   ¤   KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
6e9371 ¤   }
a1af5a
4833e3 ¤   return derr;
51efe6 }
7baf5a
94af5a
77c3ce /////////////////////////////////////////////////////
19cf90 // Class PGPdiskWorkerThread private member functions
84c3ce /////////////////////////////////////////////////////
4eaf5a
df52aa // OpenAndCloseToPreventHang quickly opens and closes the specified PGPdisk
5c9a0e // to prevent a hang under NT. Why this works is a mystery.
17af5a
bec823 void·
043895 PGPdiskWorkerThread::OpenAndCloseToPreventHang(PGPdisk *pPGD)
0bbb36 {
fddeec ¤   File diskFile;
7baf5a
e9a02c ¤   diskFile.Open(pPGD->GetPath(), kOF_MustExist | kOF_ReadOnly);
26af5a
53d27f ¤   if (diskFile.Opened())
75d016 ¤   ¤   diskFile.Close();
1cefe6 }
2eaf5a
24cac8 // GetPGPdiskFromIrp extracts the address of the PGPdisk object that the
4fecee // given IRP is directed to.
1aaf5a
d61857 PGPdisk *·
--f12b 000953e0a6a40110102 Page 4 of PGPdiskWorkerThread.cpp
3bdbcb PGPdiskWorkerThread::GetPGPdiskFromIrp(KIrp I)
1bbb36 {
d65710 ¤   PDEVICE_OBJECT¤ pDevObj;
6a8dc1 ¤   PGPdisk¤¤   ¤   *pPGD;
69af5a
d42168 ¤   pDevObj = I.DeviceObject();
0f4546 ¤   pgpAssertAddrValid(pDevObj, DEVICE_OBJECT);
b5af5a
c8ffc0 ¤   pPGD = (PGPdisk *) pDevObj->DeviceExtension;
a95b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
f7af5a
2fe1a8 ¤   return pPGD;
a6efe6 }
75af5a
e33784 // ProcessIrpMjRead processes an IRP_MJ_READ request.
f7af5a
3c0e00 NTSTATUS·
b9de79 PGPdiskWorkerThread::ProcessIrpMjRead(KIrp I)
7cbb36 {
30be41 ¤   DualErr¤¤   derr;
9248b3 ¤   NTSTATUS¤   status¤ = STATUS_SUCCESS;
1270f5 ¤   PGPdisk¤¤   *pPGD;
2cd960 ¤   PGPUInt8¤   *buf;
c6af5a
eddd8f ¤   pgpAssert(I.MajorFunction() == IRP_MJ_READ);
87af5a
9259aa ¤   // Locate the corresponding PGPdisk object.
03594b ¤   pPGD = GetPGPdiskFromIrp(I);
42af5a
92628a ¤   // Extract the buffer.
550b2a ¤   buf = (PGPUInt8 *) KMemory(I.Mdl()).MapToSystemSpace();
8cb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
c5af5a
2985b7 ¤   // Perform the read.
16d39c ¤   derr = pPGD->Read(buf, I.ReadOffset().QuadPart, I.ReadSize());
82af5a
9b4bb3 ¤   if (derr.IsError())
bf6aa5 ¤   ¤   status = STATUS_DEVICE_DATA_ERROR;
34af5a
432361 ¤   if (derr.IsntError())
b0c7a1 ¤   {
9979c0 ¤   ¤   I.Information() = I.ReadSize();
a89371 ¤   }
aa0e24 ¤   else
10c7a1 ¤   {
d51d26 ¤   ¤   I.Information() = 0;
f19371 ¤   }
63af5a
be4bb3 ¤   if (derr.IsError())
10c7a1 ¤   {
e37a7b ¤   ¤   Interface->ReportError(kPGDMajorError_PGPdiskReadError, derr,·
111ef5 ¤   ¤   ¤   pPGD->GetDrive());
729371 ¤   }
ebaf5a
d701b5 ¤   return status;
a6efe6 }
5caf5a
021b8d // ProcessIrpMjWrite processes an IRP_MJ_WRITE request.
4aaf5a
730e00 NTSTATUS·
652c1d PGPdiskWorkerThread::ProcessIrpMjWrite(KIrp I)
7dbb36 {
f6be41 ¤   DualErr¤¤   derr;
8a48b3 ¤   NTSTATUS¤   status¤ = STATUS_SUCCESS;
3670f5 ¤   PGPdisk¤¤   *pPGD;
13d960 ¤   PGPUInt8¤   *buf;
a4af5a
123257 ¤   pgpAssert(I.MajorFunction() == IRP_MJ_WRITE);
e0af5a
0a59aa ¤   // Locate the corresponding PGPdisk object.
81594b ¤   pPGD = GetPGPdiskFromIrp(I);
95af5a
--9a40 00012f5496640110102 Page 5 of PGPdiskWorkerThread.cpp
99e226 ¤   if (pPGD->IsReadOnly())
c959f0 ¤   ¤   return STATUS_MEDIA_WRITE_PROTECTED;
ffaf5a
f4f399 ¤   // Prevent hang.
4b312c ¤   OpenAndCloseToPreventHang(pPGD);
e9af5a
c2628a ¤   // Extract the buffer.
e10b2a ¤   buf = (PGPUInt8 *) KMemory(I.Mdl()).MapToSystemSpace();
feb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
0faf5a
89322b ¤   // Perform the write.
fa1384 ¤   derr = pPGD->Write(buf, I.WriteOffset().QuadPart, I.WriteSize());
36af5a
9a4bb3 ¤   if (derr.IsError())
d66aa5 ¤   ¤   status = STATUS_DEVICE_DATA_ERROR;
5f67c5 ¤
ad2361 ¤   if (derr.IsntError())
efc7a1 ¤   {
3cb843 ¤   ¤   I.Information() = I.WriteSize();
7d9371 ¤   }
ca0e24 ¤   else
bec7a1 ¤   {
ec1d26 ¤   ¤   I.Information() = 0;
8a9371 ¤   }
66af5a
d14bb3 ¤   if (derr.IsError())
b5c7a1 ¤   {
ea3722 ¤   ¤   Interface->ReportError(kPGDMajorError_PGPdiskWriteError, derr,·
f51ef5 ¤   ¤   ¤   pPGD->GetDrive());
d69371 ¤   }
dfaf5a
4b01b5 ¤   return status;
f8efe6 }
96af5a
a01cb9 // ProcessIrpMjCleanup processes an IRP_MJ_CLEANUP request.
aeaf5a
ef0e00 NTSTATUS·
0ab053 PGPdiskWorkerThread::ProcessIrpMjCleanup(KIrp I)
c0bb36 {
1ebe41 ¤   DualErr¤¤   derr;
bc48b3 ¤   NTSTATUS¤   status¤ = STATUS_SUCCESS;
6270f5 ¤   PGPdisk¤¤   *pPGD;
4baf5a
8ab3f1 ¤   pgpAssert(I.MajorFunction() == IRP_MJ_CLEANUP);
99af5a
b459aa ¤   // Locate the corresponding PGPdisk object.
0c594b ¤   pPGD = GetPGPdiskFromIrp(I);
3aaf5a
8e3724 ¤   // Cancel all IRPs for the PGPdisk.
3b3e3c ¤   mRequestQueue.CancelIRPs(pPGD->GetDrive());
462d46 ¤   status = STATUS_SUCCESS;
f5af5a
6e4bb3 ¤   if (derr.IsError())
98c7a1 ¤   {
ba3741 ¤   ¤   Interface->ReportError(kPGDMajorError_PGPdiskIrpCleanupError, derr,·
2f1ef5 ¤   ¤   ¤   pPGD->GetDrive());
b79371 ¤   }
aaaf5a
40297b ¤   I.Information() = 0;
9aaf5a
5e01b5 ¤   return status;
78efe6 }
b1af5a
fcbf7d // ProcessIrpMjDeviceControl processes an IRP_MJ_DEVICE_CONTROL request.
daaf5a
4c0e00 NTSTATUS·
ec1021 PGPdiskWorkerThread::ProcessIrpMjDeviceControl(KIrp I)
75bb36 {
829f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
e34b37 ¤   NTSTATUS¤   ¤   ¤   ¤   status¤ = STATUS_SUCCESS;
146385 ¤   PDISK_GEOMETRY¤ ¤   ¤   pGeom;
12f49b ¤   PPARTITION_INFORMATION¤ pPartInfo;
--8c51 00089367fb740110102 Page 6 of PGPdiskWorkerThread.cpp
0382dc ¤   PGPdisk¤¤   ¤   ¤   ¤   *pPGD;
34af5a
b4b965 ¤   pgpAssert(I.MajorFunction() == IRP_MJ_DEVICE_CONTROL);
0caf5a
5e59aa ¤   // Locate the corresponding PGPdisk object.
c4594b ¤   pPGD = GetPGPdiskFromIrp(I);
56af5a
724bd3 ¤   DebugOut("PGPdisk: Processing an %s\n",·
a7ce2d ¤   ¤   GetIOCTLFunctionName(I.IoctlCode()));
70af5a
48ac00 ¤   // Perform the IOCTL.
bd2361 ¤   if (derr.IsntError())
c6c7a1 ¤   {
c3ceb2 ¤   ¤   switch (I.IoctlCode())
455b34 ¤   ¤   {
4dfd94 ¤   ¤   case IOCTL_DISK_CHECK_VERIFY:
3729fd ¤   ¤   case IOCTL_DISK_SET_PARTITION_INFO:·
780d5f ¤   ¤   case IOCTL_DISK_VERIFY:
29af5a
90a670 ¤   ¤   ¤   I.Information() = 0;
27ab78 ¤   ¤   ¤   status = STATUS_SUCCESS;
1acdcb ¤   ¤   ¤   break;
21af5a
fe160b ¤   ¤   case IOCTL_DISK_IS_WRITABLE:
b1af5a
25a670 ¤   ¤   ¤   I.Information() = 0;
6daf5a
3ec484 ¤   ¤   ¤   if (pPGD->IsReadOnly())
9106f9 ¤   ¤   ¤   ¤   status = STATUS_MEDIA_WRITE_PROTECTED;
60bb8c ¤   ¤   ¤   else
8bae95 ¤   ¤   ¤   ¤   status = STATUS_SUCCESS;
abcdcb ¤   ¤   ¤   break;
411b52 ¤   ¤
8c6b22 ¤   ¤   case IOCTL_DISK_GET_DRIVE_GEOMETRY:
099fe0 ¤   ¤   case IOCTL_DISK_GET_MEDIA_TYPES:
7caf5a
be08d4 ¤   ¤   ¤   // Return drive geometry.
06151a ¤   ¤   ¤   if (I.IoctlOutputBufferSize() < sizeof(DISK_GEOMETRY))
68f776 ¤   ¤   ¤   {
46eae5 ¤   ¤   ¤   ¤   status = STATUS_INVALID_PARAMETER;
082e1b ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
30a3a6 ¤   ¤   ¤   }
6caf5a
069d3d ¤   ¤   ¤   if (derr.IsntError())
99f776 ¤   ¤   ¤   {
5e6183 ¤   ¤   ¤   ¤   pGeom = (PDISK_GEOMETRY) I.IoctlBuffer();
869ea1 ¤   ¤   ¤   ¤   pPGD->GetGeometry(pGeom);
faa3a6 ¤   ¤   ¤   }
e7af5a
923752 ¤   ¤   ¤   I.Information() = sizeof(DISK_GEOMETRY);
9fab78 ¤   ¤   ¤   status = STATUS_SUCCESS;
d3cdcb ¤   ¤   ¤   break;
4aaf5a
779abe ¤   ¤   case IOCTL_DISK_GET_PARTITION_INFO:·
1daf5a
c2d146 ¤   ¤   ¤   // Return information about the partition.
a88b61 ¤   ¤   ¤   if (I.IoctlOutputBufferSize() < sizeof(PARTITION_INFORMATION))
31f776 ¤   ¤   ¤   {
28eae5 ¤   ¤   ¤   ¤   status = STATUS_INVALID_PARAMETER;
7d2e1b ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
38a3a6 ¤   ¤   ¤   }
7faf5a
669d3d ¤   ¤   ¤   if (derr.IsntError())
5cf776 ¤   ¤   ¤   {
e7fbf9 ¤   ¤   ¤   ¤   pPartInfo = (PPARTITION_INFORMATION) I.IoctlBuffer();
d98973 ¤   ¤   ¤   ¤   pPGD->GetPartitionInfo(pPartInfo);
16a3a6 ¤   ¤   ¤   }
b0af5a
9bbb29 ¤   ¤   ¤   I.Information() = sizeof(PARTITION_INFORMATION);
2eab78 ¤   ¤   ¤   status = STATUS_SUCCESS;
e5cdcb ¤   ¤   ¤   break;
89af5a
--7527 000c4f612d940110102 Page 7 of PGPdiskWorkerThread.cpp
d39ae3 ¤   ¤   default:
16af5a
36a670 ¤   ¤   ¤   I.Information() = 0;
6bb49c ¤   ¤   ¤   status = STATUS_INVALID_DEVICE_REQUEST;
4bcdcb ¤   ¤   ¤   break;
470fe4 ¤   ¤   }
4b9371 ¤   }
83af5a
c701b5 ¤   return status;
cfefe6 }
4baf5a
9d7ffa // ProcessIrp processes a kPRQOp_ProcessIrp request.
37af5a
13c823 void·
5c4f36 PGPdiskWorkerThread::ProcessIrp(
996126 ¤   PRQRequest¤ *pPRQ,·
07728c ¤   PGPBoolean¤ *irpNeedsCompletion)
ccbb36 {
5b8842 ¤   KIrp¤   ¤   I;
b2d27c ¤   NTSTATUS¤   status¤ ¤   ¤   = STATUS_SUCCESS;
49a0ef ¤   PGPBoolean¤ completedIrp¤   = FALSE;
fadaff ¤   PGPUInt8¤   majorFunc;
09af5a
b6f83c ¤   pgpAssertAddrValid(pPRQ, PRQRequest);
0a98cb ¤   pgpAssertAddrValid(pPRQ->pIrp, PIRP);
5130ed ¤   pgpAssertAddrValid(irpNeedsCompletion, PGPBoolean);
11af5a
c35012 ¤   ( * irpNeedsCompletion) = TRUE;
7daf5a
157f1b ¤   I = KIrp(pPRQ->pIrp);
ee8e96 ¤   majorFunc = I.MajorFunction();
e5af5a
ac4bd3 ¤   DebugOut("PGPdisk: Processing an %s\n",·
28f568 ¤   ¤   GetIRPMajorFunctionName(majorFunc));
d3af5a
6ffe83 ¤   // Process the IRP according to function.
c6e3c3 ¤   switch (majorFunc)
c0c7a1 ¤   {
b3af5a
6a8ad2 ¤   case IRP_MJ_CLEANUP:
d0b372 ¤   ¤   status = ProcessIrpMjCleanup(pPRQ->pIrp);
c52f68 ¤   ¤   break;
4baf5a
6dd573 ¤   case IRP_MJ_DEVICE_CONTROL:
cb39e0 ¤   ¤   status = ProcessIrpMjDeviceControl(pPRQ->pIrp);
ac2f68 ¤   ¤   break;
6faf5a
46b55e ¤   case IRP_MJ_READ:
284097 ·¤  ¤   status = ProcessIrpMjRead(pPRQ->pIrp);
312f68 ¤   ¤   break;
84af5a
9b5fea ¤   case IRP_MJ_WRITE:
de1ae4 ¤   ¤   status = ProcessIrpMjWrite(pPRQ->pIrp);
372f68 ¤   ¤   break;
59af5a
2b2f72 ¤   default:
8fca52 ¤   ¤   // All others should have been handled already in the dispatch
aec33c ¤   ¤   // filter, even IRPs we don't know about.
27af5a
ec8f52 ¤   ¤   pgpAssert(FALSE);
91af5a
971d26 ¤   ¤   I.Information() = 0;
18b803 ¤   ¤   status = STATUS_NOT_IMPLEMENTED;
f62f68 ¤   ¤   break;
b89371 ¤   }
6baf5a
22b2a5 ¤   I.Complete(status);
1b0280 ¤   ( * irpNeedsCompletion) = FALSE;
3daf5a
6143a3 ¤   DebugOut("PGPdisk: Completed an %s\n",·
8af568 ¤   ¤   GetIRPMajorFunctionName(majorFunc));
c4efe6 }
--bd3f 0005556a6ba40110102 Page 8 of PGPdiskWorkerThread.cpp
e0af5a
dc4372 // ProcessAsyncCallback processes a kPRQOp_AsyncCallback request.
37af5a
abc823 void·
de8139 PGPdiskWorkerThread::ProcessAsyncCallback(PRQRequest *pPRQ)
71bb36 {
8e7d36 ¤   DualErr derr;
ebaf5a
fff83c ¤   pgpAssertAddrValid(pPRQ, PRQRequest);
97be12 ¤   pgpAssertAddrValid(pPRQ->callback, VoidAlign);
80af5a
e5f58c ¤   // Perform the callback.
4a4fa1 ¤   pPRQ->callback(pPRQ->refData);
8befe6 }
11af5a
353bdd // ProcessSyncCallback processes a kPRQOp_SyncCallback request.
48af5a
66c823 void·
2e45a5 PGPdiskWorkerThread::ProcessSyncCallback(PRQRequest *pPRQ)
0dbb36 {
487d36 ¤   DualErr derr;
a2af5a
11f83c ¤   pgpAssertAddrValid(pPRQ, PRQRequest);
ffaf5a
3fbe12 ¤   pgpAssertAddrValid(pPRQ->callback, VoidAlign);
5bd3e5 ¤   pgpAssertAddrValid(pPRQ->pSyncEvent, KEVENT);
55af5a
0ef58c ¤   // Perform the callback.
cf4fa1 ¤   pPRQ->callback(pPRQ->refData);
22af5a
d55702 ¤   // Tell the caller we're done.
6f7884 ¤   KeSetEvent(pPRQ->pSyncEvent, 0, FALSE);
79efe6 }
5caf5a
d20cdc // ProcessIo is the main loop of the worker thread.
73af5a
c1c823 void·
715be1 PGPdiskWorkerThread::ProcessIo()
0dbb36 {
012aec ¤   KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
71af5a
793101 ¤   while (TRUE)
10c7a1 ¤   {
9fb3ab ¤   ¤   KIrp¤   ¤   I;
cd2387 ¤   ¤   PGPBoolean¤ ifIrpItNeedsCompletion¤ = TRUE;
f4645e ¤   ¤   PRQRequest¤ *pPRQ;
d7af5a
2d2bfb ¤   ¤   __try·
645b34 ¤   ¤   {
8a85b3 ¤   ¤   ¤   // Wait for input.
a523b8 ¤   ¤   ¤   mIoSem.Wait();
a6af5a
0503fe ¤   ¤   ¤   // Are we unloading?
9994a7 ¤   ¤   ¤   if (mExitThread)
38f622 ¤   ¤   ¤   ¤   break;
b7af5a
6df4a7 ¤   ¤   ¤   // Get next request.
946914 ¤   ¤   ¤   pPRQ = mRequestQueue.Pop();
6caf5a
f2df1e ¤   ¤   ¤   if (IsNull(pPRQ))
eed040 ¤   ¤   ¤   ¤   continue;
f5af5a
138ec7 ¤   ¤   ¤   pgpAssertAddrValid(pPRQ, PRQRequest);
fcaf5a
0e894a ¤   ¤   ¤   // Dispatch the request.
5241b5 ¤   ¤   ¤   switch (pPRQ->op)
04f776 ¤   ¤   ¤   {
7336ed ¤   ¤   ¤   case kPRQOp_ProcessIrp:
21f55d ¤   ¤   ¤   ¤   ProcessIrp(pPRQ, &ifIrpItNeedsCompletion);
27f622 ¤   ¤   ¤   ¤   break;
70af5a
556072 ¤   ¤   ¤   case kPRQOp_AsyncCallback:
--61f5 0014d6ad83d40110102 Page 9 of PGPdiskWorkerThread.cpp
f23ed7 ¤   ¤   ¤   ¤   ProcessAsyncCallback(pPRQ);
d5f622 ¤   ¤   ¤   ¤   break;
d0af5a
541b9b ¤   ¤   ¤   case kPRQOp_SyncCallback:
435aa5 ¤   ¤   ¤   ¤   ProcessSyncCallback(pPRQ);
3df622 ¤   ¤   ¤   ¤   break;
8aaf5a
c1db68 ¤   ¤   ¤   default:
e2310e ¤   ¤   ¤   ¤   pgpAssert(FALSE);
0cf622 ¤   ¤   ¤   ¤   break;
97a3a6 ¤   ¤   ¤   }
63af5a
59e803 ¤   ¤   ¤   // Return the PRQ to the memory pool.
ceb3c6 ¤   ¤   ¤   mRequestQueue.ReturnPRQ(pPRQ);
178469 ¤   ¤   }·
e8ba97 ¤   ¤   __except(EXCEPTION_EXECUTE_HANDLER)·
3d5b34 ¤   ¤   {
2291c3 ¤   ¤   ¤   Interface->ReportError(kPGDMajorError_KModeExceptionOccured);
b2af5a
c7df40 ¤   ¤   ¤   // We don't exit with uncompleted IRPs.
0955d1 ¤   ¤   ¤   if (ifIrpItNeedsCompletion && (pPRQ->op == kPRQOp_ProcessIrp))
41f776 ¤   ¤   ¤   {
872e34 ¤   ¤   ¤   ¤   I = KIrp(pPRQ->pIrp);
29313b ¤   ¤   ¤   ¤   I.Complete(STATUS_DEVICE_DATA_ERROR);
f1a3a6 ¤   ¤   ¤   }
e30fe4 ¤   ¤   }
a29371 ¤   }
9caf5a
e9e8d2 ¤   // Terminated.
b44f77 ¤   Terminate(STATUS_SUCCESS);
4defe6 }
--7f71 0019678696840110103 Page 1 of PGPdiskWorkerThread.h
a4b5f2 ///////////////////////////////////////////////////////////////////////////////¶
75465d //
ceb92d // PGPdiskWorkerThread.h
e6465d //
e48578 // Declaration of class PGPdiskWorkerThread.
a4b5f2 ///////////////////////////////////////////////////////////////////////////////¶
fd465d //
b1af5a
3fc537 // $Id: PGPdiskWorkerThread.h,v 1.1.2.17 1998/07/28 21:07:48 nryan Exp $
78af5a
95cbce // Copyright (C) 1998 by Network Associates, Inc.
2471ae // All rights reserved.
47af5a
8ca067 #ifndef Included_PGPdiskWorkerThread_h¤ // [
271577 #define Included_PGPdiskWorkerThread_h
c2af5a
753a85 #include "DualErr.h"
df340a #include "WaitObjectClasses.h"
faaf5a
cb2090 #include "PGPdiskRequestQueue.h"
2caf5a
15af5a
5b5270 ////////////////////////////
ee2f72 // Class PGPdiskWorkerThread
475270 ////////////////////////////
13af5a
b6e0a4 class PGPdiskWorkerThread : private KSystemThread
27bb36 {
605ed4 public:
4b1603 ¤   DualErr mInitErr;
69af5a
635b72 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskWorkerThread();
ece167 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ~PGPdiskWorkerThread();
81af5a
5e0e3d ¤   PGPBoolean¤ ¤   ¤   ¤   IsThreadRunning();
c8ad80 ¤   PGPdiskRequestQueue *¤  GetRequestQueue();
d2af5a
73f96d ¤   DualErr¤¤   ¤   ¤   ¤   StartThread();
1c8a01 ¤   void¤   ¤   ¤   ¤   ¤   KillThread();
f0af5a
8f811d ¤   DualErr¤¤   ¤   ¤   ¤   QueueIrpForProcessing(PIRP pIrp);
62af5a
50274d ¤   DualErr¤¤   ¤   ¤   ¤   ScheduleAsyncCallback(PEZCALLBACK callback,·
f96c19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 refData = NULL);
a0d283 ¤   DualErr¤¤   ¤   ¤   ¤   ScheduleSyncCallback(PEZCALLBACK callback,·
f86c19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 refData = NULL);
dbaf5a
e30fb9 private:
048a52 ¤   PGPdiskRequestQueue¤mRequestQueue;¤ ¤   // queue for requests
066a19 ¤   PGPdiskSemaphore¤   mIoSem;¤¤   ¤   ¤   // signalled to indicate I/O
42af5a
7277fc ¤   PGPBoolean¤ ¤   ¤   mExitThread;¤   ¤   // exit at next opportunity
7f30ad ¤   PGPBoolean¤ ¤   ¤   mThreadRunning;¤¤   // thread running?
94af5a
f431b9 ¤   MEMBER_THREAD(PGPdiskWorkerThread, ProcessIo);
d3af5a
b039e9 ¤   PGPdisk *¤  GetPGPdiskFromIrp(KIrp I);
75af5a
bba6ea ¤   void¤   ¤   OpenAndCloseToPreventHang(PGPdisk *pPGD);
efaf5a
7ea918 ¤   NTSTATUS¤   ProcessIrpMjRead(KIrp I);
fe6e25 ¤   NTSTATUS¤   ProcessIrpMjWrite(KIrp I);
266437 ¤   NTSTATUS¤   ProcessIrpMjCleanup(KIrp I);
0bfaaa ¤   NTSTATUS¤   ProcessIrpMjDeviceControl(KIrp I);
11af5a
6f1494 ¤   void¤   ¤   ProcessIrp(PRQRequest *pPRQ, PGPBoolean *irpNeedsCompletion);
ff9c74 ¤   void¤   ¤   ProcessAsyncCallback(PRQRequest *pPRQ);
87eee3 ¤   void¤   ¤   ProcessSyncCallback(PRQRequest *pPRQ);
c882f7 };
03af5a
96dce1 #endif¤ // ] Included_PGPdiskWorkerThread_h
--5313 000d1197ef040110104 Page 1 of UserMemoryManager.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
f119cd // UserMemoryManager.cpp
24465d //
9230dd // Definition of class UserMemoryManager.
d31bc3 //////////////////////////////////////////////////////////////////////////////
70af5a
a3231c // $Id: UserMemoryManager.cpp,v 1.1.2.3 1998/07/06 08:57:57 nryan Exp $
58af5a
37cbce // Copyright (C) 1998 by Network Associates, Inc.
b471ae // All rights reserved.
6baf5a
17d7a1 #include <vdw.h>
d6af5a
019bcf #include "Required.h"
649abc #include "UserMemoryManager.h"
e6af5a
3faf5a
c309b7 ////////////
e1e738 // Constants
9209b7 ////////////
28af5a
aabea9 const PGPUInt16 kPGPdiskDefaultLMIDepth = 32;
05af5a
15af5a
819b9e //////////////////////////////////////////////////
8c5b49 // Class UserMemoryManager public member functions
449b9e //////////////////////////////////////////////////
d5af5a
f6704d // The UserMemoryManager default constructor.
06af5a
137ac5 UserMemoryManager::UserMemoryManager()·
15475a ¤   : mLMIAllocator(kPGPdiskDefaultLMIDepth)
c4bb36 {
641203 ¤   mInitErr = mLMIAllocator.mInitErr;
d0efe6 }
2daf5a
c79f54 // The UserMemoryManager destructor.
03af5a
678257 UserMemoryManager::~UserMemoryManager()
51bb36 {
e7efe6 }
a9af5a
de16a6 // LockUserMem locks memory passed in from User-Mode.
93af5a
382292 DualErr·
8d5ce5 UserMemoryManager::LockUserMem(void *pMem, PGPUInt32 nBytes)
6ebb36 {
8a9a95 ¤   DualErr¤¤   ¤   derr;
1c44f9 ¤   LockedMemInfo¤  *pLMI;
ebaf5a
28bd26 ¤   derr = InternalLockUserMem(pMem, nBytes, &pLMI);
67af5a
df33e3 ¤   return derr;
3cefe6 }
49af5a
85e843 // MapUserMem locks memory passed in from User-Mode and maps it to a system
39e844 // address
31af5a
ac2292 DualErr·
3e41cf UserMemoryManager::MapUserMem(void **pMem, PGPUInt32 nBytes)
a2bb36 {
2a9a95 ¤   DualErr¤¤   ¤   derr;
9544f9 ¤   LockedMemInfo¤  *pLMI;
b2af5a
406128 ¤   // Lock the memory.
bc6390 ¤   derr = InternalLockUserMem((* pMem), nBytes, &pLMI);
28af5a
487f9b ¤   // Return mapped address.
d22361 ¤   if (derr.IsntError())
a3c7a1 ¤   {
24f9e3 ¤   ¤   (* pMem) = pLMI->pSysMem;
d19371 ¤   }
--6e47 0006c7c356140110104 Page 2 of UserMemoryManager.cpp
e0af5a
cf33e3 ¤   return derr;
f5efe6 }
08af5a
18c9af // UnlockUnmapUserMem unlocks user memory previously locked and mapped.
f7af5a
c42292 DualErr·
f6ceca UserMemoryManager::UnlockUnmapUserMem(void *pMem, PGPUInt32 nBytes)
eabb36 {
147d36 ¤   DualErr derr;
10af5a
c1d98b ¤   derr = InternalUnlockUnmapUserMem(pMem, nBytes);
cfaf5a
d633e3 ¤   return derr;
30efe6 }
87af5a
23af5a
d48fbd ///////////////////////////////////////////////////
80dd65 // Class UserMemoryManager private member functions
6d8fbd ///////////////////////////////////////////////////
9aaf5a
c3e0a7 // InternalLockUserMem locks and maps user memory.
a5af5a
f82292 DualErr·
bfbe76 UserMemoryManager::InternalLockUserMem(
aee459 ¤   void¤   ¤   ¤   *pMem,·
48949d ¤   PGPUInt32¤  ¤   nBytes,·
f2a75d ¤   LockedMemInfo¤  **ppLMI)
d4bb36 {
249a95 ¤   DualErr¤¤   ¤   derr;
3144f9 ¤   LockedMemInfo¤  *pLMI;
2dbde2 ¤   PGPBoolean¤ ¤   allocedLMI, allocedMdl;
8eaf5a
1326f6 ¤   allocedLMI = allocedMdl = FALSE;
02af5a
307b37 ¤   pgpAssertAddrValid(ppLMI, LockedMemInfo);
0caf5a
b69175 ¤   // Get memory for locked mem info structure.
d793ea ¤   derr = mLMIAllocator.Allocate(&pLMI);
3b9fee ¤   allocedLMI = derr.IsntError();
75af5a
6497d1 ¤   // Allocate and initialize an MDL.
142361 ¤   if (derr.IsntError())
3fc7a1 ¤   {
9db216 ¤   ¤   pLMI->pMem¤ ¤   = pMem;
264050 ¤   ¤   pLMI->nBytes¤   = nBytes;
677ecf ¤   ¤   pLMI->pMdl¤ ¤   = IoAllocateMdl(pMem, nBytes, FALSE, FALSE, NULL);·
ffaf5a
05d8b4 ¤   ¤   if (IsNull(pLMI->pMdl))
723ce4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoAllocateMdlFailed);
bbaf5a
3b4c53 ¤   ¤   allocedMdl = derr.IsntError();
519371 ¤   }
dfaf5a
fb7665 ¤   // Try to lock down the client's area.
dc2361 ¤   if (derr.IsntError())
3dc7a1 ¤   {
b12bfb ¤   ¤   __try·
b25b34 ¤   ¤   {
bfad32 ¤   ¤   ¤   MmProbeAndLockPages(pLMI->pMdl, UserMode, IoModifyAccess);
8a8469 ¤   ¤   }·
72ba97 ¤   ¤   __except(EXCEPTION_EXECUTE_HANDLER)·
165b34 ¤   ¤   {
f7f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
770fe4 ¤   ¤   }
229371 ¤   }
daaf5a
fd082f ¤   // Add the memory info to the global list.
a32361 ¤   if (derr.IsntError())
35c7a1 ¤   {
7a1f06 ¤   ¤   pLMI->pSysMem = MmGetSystemAddressForMdl(pLMI->pMdl);
6caf5a
--2578 000e3bfea5740110104 Page 3 of UserMemoryManager.cpp
d33869 ¤   ¤   mLMIList.PublicLock();
98ed7c ¤   ¤   mLMIList.InsertHead(pLMI);
7404de ¤   ¤   mLMIList.PublicUnlock();
9b9371 ¤   }
21af5a
de4bb3 ¤   if (derr.IsError())
1fc7a1 ¤   {
2e5a84 ¤   ¤   if (allocedLMI)
f535bb ¤   ¤   ¤   mLMIAllocator.Free(pLMI);
acaf5a
7e1d76 ¤   ¤   if (allocedMdl)
e27216 ¤   ¤   ¤   IoFreeMdl(pLMI->pMdl);
2b9371 ¤   }
afaf5a
f12361 ¤   if (derr.IsntError())
90c7a1 ¤   {
195b19 ¤   ¤   (* ppLMI) = pLMI;
cb9371 ¤   }
4baf5a
544f13 ¤   return derr;¤
bfefe6 }
deaf5a
ea66e4 // InternalUnlockUnmapUserMem unlocks user memory previously locked and
bc0d0e // mapped.
24af5a
1a2292 DualErr·
fe83e4 UserMemoryManager::InternalUnlockUnmapUserMem(void *pMem, PGPUInt32 nBytes)
28bb36 {
499a95 ¤   DualErr¤¤   ¤   derr;
4c44f9 ¤   LockedMemInfo¤  *pLMI;
ca569f ¤   PGPBoolean¤ ¤   foundMemInfo¤   = FALSE;
9cd845 ¤   PGPUInt32¤  ¤   i;
75af5a
d62c41 ¤   mLMIList.PublicLock();
c1af5a
f8be34 ¤   pLMI = mLMIList.Head();
75af5a
068a52 ¤   // Find the info structure for this memory.
7825c4 ¤   for (i = 0; i < mLMIList.Count(); i++)
cec7a1 ¤   {
dee765 ¤   ¤   if (IsntNull(pLMI))
c55b34 ¤   ¤   {
206a25 ¤   ¤   ¤   // Check BOTH original user address and mapped system address.
a2024b ¤   ¤   ¤   if (((pLMI->pMem == pMem) || (pLMI->pSysMem == pMem)) &&·
18958b ¤   ¤   ¤   ¤   (pLMI->nBytes == nBytes))
86f776 ¤   ¤   ¤   {
463c1f ¤   ¤   ¤   ¤   foundMemInfo = TRUE;
7ef622 ¤   ¤   ¤   ¤   break;
b4a3a6 ¤   ¤   ¤   }
adbb8c ¤   ¤   ¤   else
a5f776 ¤   ¤   ¤   {
0f9bf4 ¤   ¤   ¤   ¤   pLMI = mLMIList.Next(pLMI);
7fa3a6 ¤   ¤   ¤   }
010fe4 ¤   ¤   }
d00e1d ¤   ¤   else
ed5b34 ¤   ¤   {
2f367a ¤   ¤   ¤   foundMemInfo = FALSE;
facdcb ¤   ¤   ¤   break;
d10fe4 ¤   ¤   }
919371 ¤   }
2caf5a
1af574 ¤   if (!foundMemInfo)
86d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
3baf5a
c994b1 ¤   // Unlock the memory and free the list entry.
692361 ¤   if (derr.IsntError())
69c7a1 ¤   {
dd1d21 ¤   ¤   MmUnlockPages(pLMI->pMdl);
a8fe69 ¤   ¤   IoFreeMdl(pLMI->pMdl);
11af5a
663d66 ¤   ¤   mLMIList.Remove(pLMI);
e3dac8 ¤   ¤   mLMIAllocator.Free(pLMI);
--25ff 0017a70bff140110104 Page 4 of UserMemoryManager.cpp
a19371 ¤   }
93af5a
53bf88 ¤   mLMIList.PublicUnlock();
55af5a
3f4f13 ¤   return derr;¤
7aefe6 }
--a37a 001219613a140110105 Page 1 of UserMemoryManager.h
541bc3 //////////////////////////////////////////////////////////////////////////////
909b41 // UserMemoryManager.h
e9465d //
a0d353 // Declaration of class UserMemoryManager.
fa1bc3 //////////////////////////////////////////////////////////////////////////////
6eaf5a
c06d35 // $Id: UserMemoryManager.h,v 1.1.2.3 1998/07/06 08:57:58 nryan Exp $
60af5a
dacbce // Copyright (C) 1998 by Network Associates, Inc.
ab71ae // All rights reserved.
92af5a
b248bf #ifndef Included_UserMemoryManager_h¤   // [
f7dbd3 #define Included_UserMemoryManager_h
14af5a
a53a85 #include "DualErr.h"
43af5a
663d34 #include "LockableList.h"
f64ead #include "LookasideList.h"
2268c6 #include "PGPdisk.h"
8eaf5a
82af5a
95d557 ////////
6702c9 // Types
77d557 ////////
81af5a
f89233 typedef struct LockedMemInfo
6abb36 {
2efb8f ¤   LIST_ENTRY m_ListEntry;¤// required by the list templates
63af5a
ba4de9 ¤   void¤   ¤   *pMem;¤ ¤   // pointer to locked memory
bbc5d3 ¤   void¤   ¤   *pSysMem;¤  // mapped to system memory
9cad41 ¤   PGPUInt32¤  nBytes;¤¤   // size of memory locked;
ec2306 ¤   PMDL¤   ¤   pMdl;¤  ¤   // MDL
e0af5a
04d87b } LockedMemInfo;
8eaf5a
11203a typedef LookasideList<LockedMemInfo> LockedMemInfoAllocator;
de594a typedef LockableList<LockedMemInfo> LockedMemInfoList;
5daf5a
40af5a
f3b352 //////////////////////////
66848f // Class UserMemoryManager
22b352 //////////////////////////
7faf5a
f05c08 class UserMemoryManager
73bb36 {
7c5ed4 public:
ab1603 ¤   DualErr mInitErr;
deaf5a
89ccc4 ¤   ¤   ¤   ¤   UserMemoryManager();
539ee8 ¤   ¤   ¤   ¤   ~UserMemoryManager();
84af5a
936c92 ¤   DualErr¤¤   LockUserMem(void *pMem, PGPUInt32 nBytes);
e1e2d7 ¤   DualErr¤¤   MapUserMem(void **pMem, PGPUInt32 nBytes);
9aaf5a
4cf4c6 ¤   DualErr¤¤   UnlockUnmapUserMem(void *pMem, PGPUInt32 nBytes);
44af5a
740fb9 private:
1226f4 ¤   LockedMemInfoAllocator¤ mLMIAllocator;¤ ¤   // locked mem info maker
bf055f ¤   LockedMemInfoList¤  ¤   mLMIList;¤  ¤   ¤   // locked mem info list
07af5a
251a0b ¤   DualErr¤InternalLockUserMem(void *pMem, PGPUInt32 nBytes,·
83f61a ¤   ¤   LockedMemInfo **ppLMI);
7caf5a
2e4393 ¤   DualErr¤InternalUnlockUnmapUserMem(void *pMem, PGPUInt32 nBytes);
4d82f7 };
5caf5a
21c266 #endif¤ // ] Included_UserMemoryManager_h
--59c2 000d63da24540110106 Page 1 of VolFile.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
87e84b // VolFile.cpp
05465d //
818a11 // Implementation of class VolFile.
c41bc3 //////////////////////////////////////////////////////////////////////////////
7caf5a
dcea54 // $Id: VolFile.cpp,v 1.1.2.14 1998/08/04 01:20:05 nryan Exp $
dfaf5a
a6cbce // Copyright (C) 1998 by Network Associates, Inc.
1c71ae // All rights reserved.
f6af5a
14d7a1 #include <vdw.h>
68af5a
be9bcf #include "Required.h"
61bfe9 #include "UtilityFunctions.h"
fbaf5a
24b3b1 #include "VolFile.h"
28af5a
c8af5a
7951ef ////////////////////////////////////////
7bf944 // Class VolFile public member functions
a951ef ////////////////////////////////////////
a7af5a
f80f09 // The Class VolFile default constructor.
f4af5a
3fc41f VolFile::VolFile() : File(), Volume()
b9bb36 {
030db0 ¤   mDevExtInfo = (PGPUInt32) this;
12efe6 }
d3af5a
f2fb34 // The VolFile destructor unmounts the VolFile.
ccaf5a
78bbd9 VolFile::~VolFile()
f9bb36 {
1bcb02 ¤   if (Mounted())
625972 ¤   ¤   Unmount();
5defe6 }
c2af5a
f2c8f7 // GetGeometry returns fake geometry for the drive.
1caf5a
03c823 void·
760fdc VolFile::GetGeometry(PDISK_GEOMETRY pGeom)
27bb36 {
082732 ¤   pgpAssertAddrValid(pGeom, DISK_GEOMETRY);
4faf5a
e5f6bc ¤   pGeom->MediaType¤   ¤   ¤   = FixedMedia;
9c9dbc ¤   pGeom->Cylinders.QuadPart¤  = mBlocksDisk;
8f5b5c ¤   pGeom->TracksPerCylinder¤   = 1;
2a555b ¤   pGeom->SectorsPerTrack¤ ¤   = 1;
334cb3 ¤   pGeom->BytesPerSector¤  ¤   = kDefaultBlockSize;
02efe6 }
0aaf5a
020e53 // GetPartitionInfo returns fake partition information for the drive.
e3af5a
38c823 void·
8b0bda VolFile::GetPartitionInfo(PPARTITION_INFORMATION pPartInfo)
c3bb36 {
315b52 ¤   pgpAssertAddrValid(pPartInfo, PARTITION_INFORMATION);
a9af5a
fc1128 ¤   pPartInfo->StartingOffset¤  ¤   ¤   = RtlConvertUlongToLargeInteger(0);
c24edc ¤   pPartInfo->PartitionLength.QuadPart¤= mBlocksDisk * kDefaultBlockSize;
a10fbb ¤   pPartInfo->HiddenSectors¤   ¤   ¤   = 0;
34aa35 ¤   pPartInfo->PartitionNumber¤ ¤   ¤   = 1;
625e50 ¤   pPartInfo->PartitionType¤   ¤   ¤   = PARTITION_ENTRY_UNUSED;
2df74d ¤   pPartInfo->BootIndicator¤   ¤   ¤   = FALSE;
749791 ¤   pPartInfo->RecognizedPartition¤ ¤   = TRUE;
019e65 ¤   pPartInfo->RewritePartition¤¤   ¤   = FALSE;
02efe6 }
e2af5a
e88f40 // Mount will mount the volume file specified by 'path'.
8daf5a
d62292 DualErr·
--49f8 0001263637a40110106 Page 2 of VolFile.cpp
997678 VolFile::Mount(
7af2f8 ¤   LPCSTR¤ ¤   path,·
6757b7 ¤   LPCSTR¤ ¤   deviceName,·
9b48c9 ¤   PGPUInt64¤  blocksHeader,·
3bdbaf ¤   PGPUInt64¤  blocksDisk,·
487fa2 ¤   PGPUInt8¤   drive,·
bebdcf ¤   PGPBoolean¤ mountReadOnly)
abbb36 {
8f7d36 ¤   DualErr derr;
17af5a
6e639f ¤   pgpAssertStrValid(path);
5067cf ¤   pgpAssertStrValid(deviceName);
c9af5a
86e50f ¤   pgpAssert(blocksDisk > 0);
e8aeca ¤   pgpAssert(Unmounted());
59af5a
040bd5 ¤   // Initialize our data members.
24f480 ¤   mBlocksDisk¤¤   = blocksDisk;
98825c ¤   mBlocksHeader¤  = blocksHeader;
e9af5a
84b1fe ¤   // Open the file.
45f424 ¤   derr = Open(path, kOF_MustExist | kOF_DenyWrite | kOF_NoBuffering |·
a7b317 ¤   ¤   (mountReadOnly ? kOF_ReadOnly : NULL));
dbaf5a
5a1e52 ¤   // Attempt the mount.
ae2361 ¤   if (derr.IsntError())
54c7a1 ¤   {
980212 ¤   ¤   derr = Volume::Mount(deviceName, drive, mountReadOnly);
c49371 ¤   }
5caf5a
46e5ff ¤   // Cleanup in case of error.
ab4bb3 ¤   if (derr.IsError())
eac7a1 ¤   {
0db31e ¤   ¤   if (Opened())
1dd730 ¤   ¤   ¤   Close();
dd9371 ¤   }
deaf5a
5833e3 ¤   return derr;
eeefe6 }
98af5a
ac0603 // Unmount unmounts a mounted volume file. It calls down to Volume::Unmount
9c3d33 // to do the job, then closes the file.
1baf5a
eb2292 DualErr·
704756 VolFile::Unmount(PGPBoolean isThisEmergency)
6cbb36 {
2b7d36 ¤   DualErr derr;
fdaf5a
293ec3 ¤   pgpAssert(Mounted());
b6af5a
7e070a ¤   derr = Volume::Unmount(isThisEmergency);
4faf5a
822361 ¤   if (derr.IsntError())
60c7a1 ¤   {
de78ff ¤   ¤   DualErr afterFact = Close();
c2e9ee ¤   ¤   pgpAssert(afterFact.IsntError());
fb9371 ¤   }
21af5a
5033e3 ¤   return derr;
14efe6 }
f6af5a
4958e8 // Read performs a read request on the mounted volume.
feaf5a
772292 DualErr·
e9a35d VolFile::Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
72bb36 {
d77d36 ¤   DualErr derr;
a2af5a
4eb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
d7b27a ¤   pgpAssert(nBytes > 0);
d43ec3 ¤   pgpAssert(Mounted());
12af5a
--348d 001ec56ea8b40110106 Page 3 of VolFile.cpp
a3fd5d ¤   // Out of bounds?
1e103f ¤   if (pos + nBytes > mBlocksDisk * kDefaultBlockSize)
4d0df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
2aaf5a
69d055 ¤   // Call down the request.
962361 ¤   if (derr.IsntError())
c8c7a1 ¤   {
87f20b ¤   ¤   derr = File::Read(buf, pos + mBlocksHeader*kDefaultBlockSize, nBytes);
999371 ¤   }
ccaf5a
e133e3 ¤   return derr;
a0efe6 }
4daf5a
a68349 // Write performs a write request on the mounted volume. Note how Write
6fc376 // accounts for the bias introduced by the size of the volume file header.
69af5a
802292 DualErr·
b8be23 VolFile::Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
eebb36 {
137d36 ¤   DualErr derr;
8aaf5a
85b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
f7b27a ¤   pgpAssert(nBytes > 0);
a53ec3 ¤   pgpAssert(Mounted());
daaf5a
35fd5d ¤   // Out of bounds?
70103f ¤   if (pos + nBytes > mBlocksDisk * kDefaultBlockSize)
a50df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
47af5a
b2d055 ¤   // Call down the request.
4b2361 ¤   if (derr.IsntError())
cfc7a1 ¤   {
d9b160 ¤   ¤   derr = File::Write(buf, pos + mBlocksHeader*kDefaultBlockSize,·
4d4ff0 ¤   ¤   ¤   nBytes);
919371 ¤   }
b4af5a
ad33e3 ¤   return derr;
ecefe6 }
--b96e 00184c4621540110107 Page 1 of VolFile.h
541bc3 //////////////////////////////////////////////////////////////////////////////
6bcef9 // VolFile.h
0d465d //
126954 // Declaration of class VolFile.
bf1bc3 //////////////////////////////////////////////////////////////////////////////
99af5a
0419cf // $Id: VolFile.h,v 1.1.2.7 1998/08/04 01:20:08 nryan Exp $
eeaf5a
07cbce // Copyright (C) 1998 by Network Associates, Inc.
4871ae // All rights reserved.
96af5a
f899dc #ifndef Included_VolFile_h¤ // [
2a878f #define Included_VolFile_h
b9af5a
1a3a85 #include "DualErr.h"
7aaf5a
b9f037 #include "File.h"
392561 #include "Volume.h"
e0af5a
0faf5a
ee9791 ////////////////
d07bec // Class VolFile
779791 ////////////////
90af5a
f6091a // Class VolFile objects represent volumes associated with a file on a host
551e8d // drive. These files can be mounted and unmounted at will, and all I/O
498706 // requests will be routed to the appropriate location on these files just
64c5c7 // like they were hard disks themselves.
a7af5a
b7f0ed class VolFile : public File, public Volume
08bb36 {
045ed4 public:
bfb6e1 ¤   ¤   ¤   ¤   VolFile();
e25db8 ¤   virtual¤¤   ~VolFile();
e5af5a
ba7c72 ¤   void¤   ¤   GetGeometry(PDISK_GEOMETRY pGeom);
153a90 ¤   void¤   ¤   GetPartitionInfo(PPARTITION_INFORMATION pPartInfo);
8eaf5a
e54de0 ¤   DualErr¤¤   Mount(LPCSTR path, LPCSTR deviceName, PGPUInt64 blocksHeader,·
839c21 ¤   ¤   ¤   ¤   ¤   PGPUInt64 blocksDisk, PGPUInt8 drive = kInvalidDrive,·
901a89 ¤   ¤   ¤   ¤   ¤   PGPBoolean readOnly = FALSE);
02499b ¤   DualErr¤¤   Unmount(PGPBoolean isThisEmergency = FALSE);
84af5a
9db825 ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
a2b00c ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
15af5a
4e0fb9 private:
9faa66 ¤   PGPBoolean¤ mFailAllIo;¤¤   ¤   // fail all input/output?
7caf5a
d38795 ¤   PGPUInt64¤  mBlocksDisk;¤   ¤   // size of volume
593728 ¤   PGPUInt64¤  mBlocksHeader;¤ ¤   // size of file header
7d82f7 };
98af5a
843e06 #endif¤ // ] Included_VolFile_h
--a15d 0003f54a08b40110108 Page 1 of Volume.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
debd92 // Volume.cpp
ea465d //
b08b63 // Implementation of class Volume.
c11bc3 //////////////////////////////////////////////////////////////////////////////
8eaf5a
e33ed2 // $Id: Volume.cpp,v 1.1.2.28.2.1 1998/10/21 07:12:28 nryan Exp $
9baf5a
f3cbce // Copyright (C) 1998 by Network Associates, Inc.
fd71ae // All rights reserved.
8caf5a
6fd7a1 #include <vdw.h>
9daf5a
049bcf #include "Required.h"
22bfe9 #include "UtilityFunctions.h"
71af5a
a59281 #include "CPGPdiskDriver.h"
a5c411 #include "Globals.h"
59f1f6 #include "KernelModeUtils.h"
d72090 #include "PGPdiskRequestQueue.h"
a32561 #include "Volume.h"
6aaf5a
54af5a
6d04c6 ///////////////////////////////////////
c66848 // Class Volume public member functions
9304c6 ///////////////////////////////////////
a8af5a
58c266 // The Class Volume constructor.
3faf5a
6e16bd Volume::Volume()
26bb36 {
680db0 ¤   mDevExtInfo = (PGPUInt32) this;
44af5a
90e6f1 ¤   mMountState¤= kVol_Unmounted;
21f9b6 ¤   mLockState¤ = kLock_None;
97e59e ¤   mDrive¤ ¤   = kInvalidDrive;
21af5a
0fec86 ¤   mAttachedToLocalVol = FALSE;
e5af5a
10f656 ¤   mDeviceObject = NULL;
6baf5a
2b9e9e ¤   mVHDeviceObject¤= NULL;
1e02a2 ¤   mVHFileObject¤  = NULL;
ab7e18 ¤   mVolumeHandle¤  = NULL;
c0efe6 }
5faf5a
384ea5 // The Volume destructor unmounted the volume if was mounted by us.
37af5a
16b773 Volume::~Volume()
42bb36 {
fd7d36 ¤   DualErr derr;
a1af5a
2acb02 ¤   if (Mounted())
83c7a1 ¤   {
6c2527 ¤   ¤   if (AttachedToLocalVolume())
ea5b34 ¤   ¤   {
3f61a4 ¤   ¤   ¤   DetachLocalVolume();
150fe4 ¤   ¤   }
260e1d ¤   ¤   else
b15b34 ¤   ¤   {
a9c3a5 ¤   ¤   ¤   derr = Unmount();
d5027b ¤   ¤   ¤   pgpAssert(derr.IsntError());
090fe4 ¤   ¤   }
619371 ¤   }
5befe6 }
afaf5a
f1af5c // Mounted returns TRUE if the volume is mounted, FALSE if not.
83af5a
8477be PGPBoolean·
f18fc7 Volume::Mounted()
a6bb36 {
3fb86d ¤   return (mMountState == kVol_Mounted);
--2aef 000c177be6640110108 Page 2 of Volume.cpp
7aefe6 }
46af5a
4204ce // Unmounted returns TRUE if the volume is unmounted, FALSE if not.
ccaf5a
1877be PGPBoolean·
0b3f6f Volume::Unmounted()
00bb36 {
fe25b2 ¤   return (mMountState == kVol_Unmounted);
e0efe6 }
e5af5a
e11501 // HasOpenFiles returns TRUE if the volume has open files, FALSE otherwise.
62af5a
3f7750 PGPBoolean
88b169 Volume::HasOpenFiles()
32bb36 {
f37d36 ¤   DualErr derr;
d4af5a
993ec3 ¤   pgpAssert(Mounted());
e4af5a
db5965 ¤   // If lock fails, then the volume has open files.
e72d5b ¤   derr = LockVolumeForReadWrite();
37af5a
b0b92d ¤   if (LockedForReadWrite())
bb1481 ¤   ¤   UnlockVolume();
25af5a
f38864 ¤   return derr.IsError();
19efe6 }
d5af5a
3fcb87 // LockedForReadWrite returns TRUE if the volume is mounted and locked for
9a2364 // read/write access, FALSE otherwise.
76af5a
a477be PGPBoolean·
b44ddc Volume::LockedForReadWrite()
80bb36 {
67cc45 ¤   return (Mounted() && (mLockState == kLock_ReadWrite));
89efe6 }
d4af5a
38cb87 // LockedForReadWrite returns TRUE if the volume is mounted and locked for
8f0b82 // format access, FALSE otherwise.
3eaf5a
5577be PGPBoolean·
4a93fa Volume::LockedForFormat()
0fbb36 {
b91acd ¤   return (Mounted() && (mLockState == kLock_Format));
7eefe6 }
cbaf5a
6d8972 // AttachedToLocalVolume returns TRUE if the Volume object is attached to a
46110f // local volume, FALSE if not.
dbaf5a
7477be PGPBoolean·
9a235c Volume::AttachedToLocalVolume()
1cbb36 {
bc51f9 ¤   return mAttachedToLocalVol;
30efe6 }
f3af5a
d4a362 // GetDrive returns the drive number of the volume.
73af5a
05671d PGPUInt8·
b1e319 Volume::GetDrive()
f9bb36 {
633ec3 ¤   pgpAssert(Mounted());
ecaf5a
d24cf2 ¤   return mDrive;
e6efe6 }
f4af5a
4e9c21 // GetBlockSize returns the block size of the volume.
e9af5a
76411c PGPUInt16·
01afd6 Volume::GetBlockSize()
6cbb36 {
167d36 ¤   DualErr derr;
c1af5a
--1e86 000c9c4a13740110108 Page 3 of Volume.cpp
a03ec3 ¤   pgpAssert(Mounted());
ecaf5a
407476 ¤   derr = GetDriveGeometry();
feaf5a
832361 ¤   if (derr.IsntError())
2c3af5 ¤   ¤   return (PGPUInt16) mGeometry.BytesPerSector;
880e24 ¤   else
7c459c ¤   ¤   return kDefaultBlockSize;
29efe6 }
feaf5a
5dc5fd // GetTotalBlocks returns the total number of blocks on the volume.
7caf5a
b3a385 PGPUInt64·
f6376a Volume::GetTotalBlocks()
babb36 {
757d36 ¤   DualErr derr;
5daf5a
0f3ec3 ¤   pgpAssert(Mounted());
a7af5a
5a7476 ¤   derr = GetDriveGeometry();
65af5a
d22361 ¤   if (derr.IsntError())
98c7a1 ¤   {
b0699f ¤   ¤   return (mGeometry.Cylinders.QuadPart * mGeometry.TracksPerCylinder *·
de75fc ¤   ¤   ¤   mGeometry.SectorsPerTrack);
c79371 ¤   }
950e24 ¤   else
2ec7a1 ¤   {
bfbbde ¤   ¤   return 0;
b59371 ¤   }
86efe6 }
2daf5a
00fd1b // GetDeviceObject returns the device object associated with the volume.
deaf5a
512431 PDEVICE_OBJECT·
50e045 Volume::GetDeviceObject()
a0bb36 {
f63ec3 ¤   pgpAssert(Mounted());
f9af5a
43e13f ¤   return mDeviceObject;
ceefe6 }
baaf5a
cdfff6 // AttachLocalVolume initializes this Volume object for access to an already
c83bc5 // mounted volume on the local computer.
2baf5a
742292 DualErr·
c2b0d2 Volume::AttachLocalVolume(PGPUInt8 drive)
79bb36 {
217d36 ¤   DualErr derr;
85af5a
cdaa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
3ecf8a ¤   pgpAssert(!Mounted());
87227d ¤   pgpAssert(!AttachedToLocalVolume());
9eaf5a
4d3b3a ¤   if (LockedForReadWrite() || LockedForFormat())
c01481 ¤   ¤   UnlockVolume();
edaf5a
aa977f ¤   mMountState¤= kVol_Mounted;
d5f9b6 ¤   mLockState¤ = kLock_None;
42bc1b ¤   mDrive¤ ¤   = drive;
8faf5a
07106b ¤   mAttachedToLocalVol = TRUE;
0faf5a
ef33e3 ¤   return derr;
d0efe6 }
0baf5a
a0bdfa // DetachLocalVolume marks this Volume object as no longer being associated
c567e5 // with a local volume.
20af5a
4cc823 void·
56463a Volume::DetachLocalVolume()
c9bb36 {
--1715 0000a04347440110108 Page 4 of Volume.cpp
a03ec3 ¤   pgpAssert(Mounted());
02bfb5 ¤   pgpAssert(AttachedToLocalVolume());
a9af5a
cb563f ¤   if (VolumeHandleOpened())
4ec3f7 ¤   ¤   CloseVolumeHandle();
57af5a
68e6f1 ¤   mMountState¤= kVol_Unmounted;
c4f9b6 ¤   mLockState¤ = kLock_None;
18e59e ¤   mDrive¤ ¤   = kInvalidDrive;
2daf5a
1dec86 ¤   mAttachedToLocalVol = FALSE;
2fefe6 }
4faf5a
3d0b65 // Mount creates a device and links it to the specified drive letter.
54af5a
c82292 DualErr·
4c84a6 Volume::Mount(LPCSTR deviceName, PGPUInt8 drive, PGPBoolean mountReadOnly)
5ebb36 {
18be41 ¤   DualErr¤¤   derr;
237e07 ¤   KUstring¤   uniDeviceName, drivePath;
f7fc8d ¤   NTSTATUS¤   status;
b274dd ¤   PGPBoolean¤ createdDevice, foundDrive;
20de5a ¤   PGPUInt8¤   i;
eaaf5a
4a67cf ¤   pgpAssertStrValid(deviceName);
66aeca ¤   pgpAssert(Unmounted());
39227d ¤   pgpAssert(!AttachedToLocalVolume());
abaf5a
fbccd3 ¤   createdDevice = foundDrive = FALSE;
51af5a
334342 ¤   // If preferred drive letter is specified, is it available?
24dea3 ¤   if (IsLegalDriveNumber(drive))
22c7a1 ¤   {
1cc3a2 ¤   ¤   derr = MakePathToDrive(drive, &drivePath);
4aaf5a
55aa35 ¤   ¤   if (derr.IsntError())
455b34 ¤   ¤   {
d2a0e4 ¤   ¤   ¤   foundDrive = !IsValidDeviceName(drivePath);
3d0fe4 ¤   ¤   }
619371 ¤   }
48af5a
c41e37 ¤   // Find a drive letter we can use.
b8ec91 ¤   if (derr.IsntError() && !foundDrive)
efc7a1 ¤   {
67258a ¤   ¤   for (i = 2; i < kMaxDrives; i++)
ec5b34 ¤   ¤   {
4253b5 ¤   ¤   ¤   derr = MakePathToDrive(i, &drivePath);
abaf5a
d59d3d ¤   ¤   ¤   if (derr.IsntError())
1bf776 ¤   ¤   ¤   {
7ca0fa ¤   ¤   ¤   ¤   if (!IsValidDeviceName(drivePath))
3c72c3 ¤   ¤   ¤   ¤   {
a7f31a ¤   ¤   ¤   ¤   ¤   foundDrive = TRUE;
f66c27 ¤   ¤   ¤   ¤   ¤   drive = i;
c814c3 ¤   ¤   ¤   ¤   ¤   break;
f92613 ¤   ¤   ¤   ¤   }
4ea3a6 ¤   ¤   ¤   }
a787c7 ¤   ¤   ¤
041088 ¤   ¤   ¤   if (derr.IsError())
95f622 ¤   ¤   ¤   ¤   break;
620fe4 ¤   ¤   }
319371 ¤   }
7aaf5a
0718c6 ¤   // Die if no free drive found.
ae2361 ¤   if (derr.IsntError())
57c7a1 ¤   {
cf1334 ¤   ¤   if (!foundDrive)
4a3cd2 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_NoDriveLettersFree);
cb9371 ¤   }
07af5a
be7ba6 ¤   // Prepare device name.
0a2361 ¤   if (derr.IsntError())
--add8 00023f8f2f440110108 Page 5 of Volume.cpp
f7c7a1 ¤   {
0daf18 ¤   ¤   derr = AssignToUni(&uniDeviceName, deviceName);
499371 ¤   }
a7af5a
d5a1d4 ¤   // Prepend device prefix.
302361 ¤   if (derr.IsntError())
92c7a1 ¤   {
0f0201 ¤   ¤   derr = PrependToUni(&uniDeviceName, kNTDevicePathPrefix);
0c9371 ¤   }
45af5a
0284c2 ¤   // Append driver letter.
cc2361 ¤   if (derr.IsntError())
4ac7a1 ¤   {
aaabce ¤   ¤   char driveLet[2];
85af5a
3d9d1d ¤   ¤   driveLet[0] = DriveNumToLet(drive);
44e516 ¤   ¤   driveLet[1] = '\0';
f2af5a
435f9d ¤   ¤   derr = AppendToUni(&uniDeviceName, driveLet);
f69371 ¤   }
7aaf5a
eb4a37 ¤   // Create a new device object.
c92361 ¤   if (derr.IsntError())
19c7a1 ¤   {
cb2979 ¤   ¤   PGPUInt32 attribs = FILE_VIRTUAL_VOLUME;
4baf5a
d438a9 ¤   ¤   if (mountReadOnly)
ef0c53 ¤   ¤   ¤   attribs |= FILE_READ_ONLY_DEVICE;
edaf5a
a32e42 ¤   ¤   status = IoCreateDevice(Interface->mPGPdiskDriver->DriverObject(),·
346f6d ¤   ¤   ¤   0, uniDeviceName, FILE_DEVICE_DISK, attribs, FALSE,·
991457 ¤   ¤   ¤   &mDeviceObject);
02af5a
f26412 ¤   ¤   if (!NT_SUCCESS(status))
f4708d ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoCreateDeviceFailed, status);
89af5a
8db9ca ¤   ¤   createdDevice = derr.IsntError();
179371 ¤   }
b9af5a
0349a2 ¤   // Assign the link name.
712361 ¤   if (derr.IsntError())
cac7a1 ¤   {
9030cb ¤   ¤   derr = AssignToUni(&mLinkName, drivePath);
d29371 ¤   }
bcaf5a
1984c0 ¤   // Create the link.
9c2361 ¤   if (derr.IsntError())
2ec7a1 ¤   {
aeb054 ¤   ¤   mDeviceObject->Flags |= DO_DIRECT_IO;
e14915 ¤   ¤   mDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
8eaf5a
4e2378 ¤   ¤   mDeviceObject->DeviceExtension = (void *) mDevExtInfo;
beaf5a
f867d8 ¤   ¤   status = IoCreateSymbolicLink(mLinkName, uniDeviceName);
d4af5a
006412 ¤   ¤   if (!NT_SUCCESS(status))
e6d18b ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoCreateSymbolicLinkFailed, status);
759371 ¤   }
1daf5a
ae05bb ¤   // Initialize variables on success.
ff2361 ¤   if (derr.IsntError())
b0c7a1 ¤   {
351c83 ¤   ¤   mMountState¤= kVol_Mounted;
41cebe ¤   ¤   mLockState¤ = kLock_None;
828846 ¤   ¤   mDrive¤ ¤   = drive;
46af5a
07d1ee ¤   ¤   mAttachedToLocalVol = FALSE;
9e9371 ¤   }
40af5a
3b2f6f ¤   // Cleanup on error.
1d4bb3 ¤   if (derr.IsError())
23c7a1 ¤   {
--123b 0000673cc3440110108 Page 6 of Volume.cpp
e6be6e ¤   ¤   if (createdDevice)
5e5b34 ¤   ¤   {
ef5f6a ¤   ¤   ¤   IoDeleteDevice(mDeviceObject);
e8480a ¤   ¤   ¤   mDeviceObject = NULL;
9e0fe4 ¤   ¤   }
3d9371 ¤   }
87af5a
3233e3 ¤   return derr;
c6efe6 }
18af5a
592f10 // Unmount unmounts a mounted Volume.
faaf5a
8e2292 DualErr·
e023d4 Volume::Unmount(PGPBoolean isThisEmergency)
0dbb36 {
6dbe41 ¤   DualErr¤¤   derr;
06fc8d ¤   NTSTATUS¤   status;
a8af5a
a73ec3 ¤   pgpAssert(Mounted());
33227d ¤   pgpAssert(!AttachedToLocalVolume());
d9af5a
323b3a ¤   if (LockedForReadWrite() || LockedForFormat())
7f1481 ¤   ¤   UnlockVolume();
a1af5a
afd9c6 ¤   // Lock the volume.
d72d5b ¤   derr = LockVolumeForReadWrite();
9aaf5a
88e408 ¤   // Dismount the volume.
2b2361 ¤   if (derr.IsntError())
50c7a1 ¤   {
e93452 ¤   ¤   derr = SendUserFSCTLRequest(FSCTL_DISMOUNT_VOLUME);
179371 ¤   }
5daf5a
cf962c ¤   if (isThisEmergency)
b99e84 ¤   ¤   derr = DualErr::NoError;
6baf5a
aefa52 ¤   // Delete the symbolic link.
852361 ¤   if (derr.IsntError())
4ac7a1 ¤   {
f97b7e ¤   ¤   status = IoDeleteSymbolicLink(mLinkName);
82af5a
8b6412 ¤   ¤   if (!NT_SUCCESS(status))
41fc63 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoDeleteSymbolicLinkFailed, status);
5baf5a
9ba271 ¤   ¤   if (isThisEmergency)
d7a3ec ¤   ¤   ¤   derr = DualErr::NoError;
519371 ¤   }
b2af5a
534ffc ¤   // Delete the device object and finish up.
962361 ¤   if (derr.IsntError())
f0c7a1 ¤   {
1d6a81 ¤   ¤   if (!isThisEmergency || (isThisEmergency && LockedForReadWrite()))
21e2e4 ¤   ¤   ¤   UnlockVolume();
d4af5a
275df2 ¤   ¤   mDeviceObject->DeviceExtension = NULL;
3daf5a
455126 ¤   ¤   IoDeleteDevice(mDeviceObject);
3a7f02 ¤   ¤   mDeviceObject = NULL;
c1af5a
2e0982 ¤   ¤   mMountState¤= kVol_Unmounted;
c7cebe ¤   ¤   mLockState¤ = kLock_None;
fbd8f6 ¤   ¤   mDrive¤ ¤   = kInvalidDrive;
099371 ¤   }
70af5a
ff4bb3 ¤   if (derr.IsError())
e3c7a1 ¤   {
538e25 ¤   ¤   if (LockedForReadWrite())
38e2e4 ¤   ¤   ¤   UnlockVolume();
959371 ¤   }
21af5a
c333e3 ¤   return derr;
06efe6 }
--c8ce 000d439f6d240110108 Page 7 of Volume.cpp
e0af5a
be2a09 // LockVolumeForReadWrite locks the mounted volume for direct read/write
d15ca5 // access.
57af5a
242292 DualErr·
d87551 Volume::LockVolumeForReadWrite()
e0bb36 {
317d36 ¤   DualErr derr;
ed67c5 ¤
ff3ec3 ¤   pgpAssert(Mounted());
81f283 ¤   pgpAssert(!LockedForReadWrite() && !LockedForFormat());
40af5a
3d575b ¤   derr = OpenVolumeHandle();
fa67c5 ¤
3d2361 ¤   if (derr.IsntError())
4dc7a1 ¤   {
f6baa2 ¤   ¤   derr = SendUserFSCTLRequest(FSCTL_LOCK_VOLUME);
d89371 ¤   }
40af5a
e22361 ¤   if (derr.IsntError())
fbc7a1 ¤   {
1fe246 ¤   ¤   mLockState = kLock_ReadWrite;
b09371 ¤   }
29af5a
c94bb3 ¤   if (derr.IsError())
27c7a1 ¤   {
846137 ¤   ¤   if (VolumeHandleOpened())
0078a1 ¤   ¤   ¤   CloseVolumeHandle();
379371 ¤   }
4baf5a
9e33e3 ¤   return derr;
d9efe6 }
06af5a
eb5eeb // LockVolumeForFormat locks the mounted volume for formatting.
dbaf5a
032292 DualErr·
2dd7e3 Volume::LockVolumeForFormat()
2ebb36 {
8d7d36 ¤   DualErr derr;
5067c5 ¤
3d3ec3 ¤   pgpAssert(Mounted());
94f283 ¤   pgpAssert(!LockedForReadWrite() && !LockedForFormat());
01af5a
ca575b ¤   derr = OpenVolumeHandle();
09af5a
9c2361 ¤   if (derr.IsntError())
36c7a1 ¤   {
e2baa2 ¤   ¤   derr = SendUserFSCTLRequest(FSCTL_LOCK_VOLUME);
7e9371 ¤   }
c9af5a
512361 ¤   if (derr.IsntError())
c3c7a1 ¤   {
6452d6 ¤   ¤   mLockState = kLock_Format;
8b9371 ¤   }
05af5a
514bb3 ¤   if (derr.IsError())
fac7a1 ¤   {
fa6137 ¤   ¤   if (VolumeHandleOpened())
0878a1 ¤   ¤   ¤   CloseVolumeHandle();
e09371 ¤   }
2aaf5a
5b33e3 ¤   return derr;
9defe6 }
90af5a
c0fb18 // UnlockVolume removes any outstanding locks on the volume;
e6af5a
152292 DualErr·
29df21 Volume::UnlockVolume()
22bb36 {
f97d36 ¤   DualErr derr;
66af5a
d43ec3 ¤   pgpAssert(Mounted());
--2423 000990844db40110108 Page 8 of Volume.cpp
68e241 ¤   pgpAssert(LockedForReadWrite() || LockedForFormat());
a5af5a
cbe735 ¤   derr = SendUserFSCTLRequest(FSCTL_UNLOCK_VOLUME);
773afe ¤   pgpAssert(derr.IsntError());
6eaf5a
a62361 ¤   if (derr.IsntError())
3fc7a1 ¤   {
31d00b ¤   ¤   mLockState = kLock_None;
5ac3f7 ¤   ¤   CloseVolumeHandle();
929371 ¤   }
acaf5a
2d33e3 ¤   return derr;
47efe6 }
d7af5a
2509ec // Read reads 'nBlocks' sectors from the logical mounted volume from sector
dfdf22 // position 'pos'.
94af5a
de2292 DualErr·
d3efef Volume::Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks)
c9bb36 {
9a9a95 ¤   DualErr¤¤   ¤   derr;
9ccd5d ¤   IO_STATUS_BLOCK¤ioStatus;·
141e6c ¤   KEVENT¤ ¤   ¤   event;·
4990e8 ¤   KIrp¤   ¤   ¤   pIrp;
3e0062 ¤   LARGE_INTEGER¤  liPos;
4739be ¤   NTSTATUS¤   ¤   status;
42335b ¤   PGPBoolean¤ ¤   openedVolHandle¤= FALSE;
e3af5a
f8b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
5d3ec3 ¤   pgpAssert(Mounted());
c5af5a
0c9e29 ¤   // Open handle to the volume.
513bef ¤   if (!VolumeHandleOpened())
96c7a1 ¤   {
01db24 ¤   ¤   derr = OpenVolumeHandle();
52e3e6 ¤   ¤   openedVolHandle = derr.IsntError();
439371 ¤   }
73af5a
af2361 ¤   if (derr.IsntError())
65c7a1 ¤   {
6d1c02 ¤   ¤   // Initialize the event.
5eeb95 ¤   ¤   KeInitializeEvent(&event, NotificationEvent, FALSE);
9daf5a
a46eda ¤   ¤   // Build the request.
e3cec7 ¤   ¤   liPos.QuadPart = pos * GetBlockSize();
ceaf5a
d77665 ¤   ¤   pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, mVHDeviceObject,·
5228bd ¤   ¤   ¤   buf, nBlocks * GetBlockSize(), &liPos, &event, &ioStatus);
6baf5a
d33b4d ¤   ¤   if (IsNull((PIRP) pIrp))
4ded23 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoBuildSynchFsdRequestFailed);
359371 ¤   }
12af5a
15ecea ¤   // Send the request.
572361 ¤   if (derr.IsntError())
47c7a1 ¤   {
eecac8 ¤   ¤   pIrp.NextStackLocation()->FileObject = mVHFileObject;
a5af5a
2e1eaa ¤   ¤   status = IoCallDriver(mVHDeviceObject, pIrp);
5ed83c ·
5d80b6 ¤   ¤   if (status == STATUS_PENDING)
615b34 ¤   ¤   {
53e7a0 ¤   ¤   ¤   KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
1334ec ¤   ¤   ¤   status = ioStatus.Status;
630fe4 ¤   ¤   }
56af5a
766412 ¤   ¤   if (!NT_SUCCESS(status))
9cf2d7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoCallDriverFailed, status);
d19371 ¤   }
37af5a
a0a2a1 ¤   // Close volume handle.
99ec92 ¤   if (openedVolHandle)
--2c77 0007913a91540110108 Page 9 of Volume.cpp
c3c3f7 ¤   ¤   CloseVolumeHandle();
b8af5a
7d33e3 ¤   return derr;
00efe6 }
58af5a
162bf4 // Write reads 'nBlocks' sectors from the logical mounted volume from sector
e1df22 // position 'pos'.
41af5a
912292 DualErr·
1078f6 Volume::Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks)
52bb36 {
279a95 ¤   DualErr¤¤   ¤   derr;
c6cd5d ¤   IO_STATUS_BLOCK¤ioStatus;·
e01e6c ¤   KEVENT¤ ¤   ¤   event;·
0d90e8 ¤   KIrp¤   ¤   ¤   pIrp;
c60062 ¤   LARGE_INTEGER¤  liPos;
ac39be ¤   NTSTATUS¤   ¤   status;
34335b ¤   PGPBoolean¤ ¤   openedVolHandle¤= FALSE;
12af5a
54b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
c73ec3 ¤   pgpAssert(Mounted());
2eaf5a
ce9e29 ¤   // Open handle to the volume.
2f3bef ¤   if (!VolumeHandleOpened())
4ec7a1 ¤   {
36db24 ¤   ¤   derr = OpenVolumeHandle();
e6e3e6 ¤   ¤   openedVolHandle = derr.IsntError();
5f9371 ¤   }
d3af5a
062361 ¤   if (derr.IsntError())
27c7a1 ¤   {
851c02 ¤   ¤   // Initialize the event.
51eb95 ¤   ¤   KeInitializeEvent(&event, NotificationEvent, FALSE);
7baf5a
0d6eda ¤   ¤   // Build the request.
f1cec7 ¤   ¤   liPos.QuadPart = pos * GetBlockSize();
aaaf5a
2d9268 ¤   ¤   pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, mVHDeviceObject,·
f228bd ¤   ¤   ¤   buf, nBlocks * GetBlockSize(), &liPos, &event, &ioStatus);
f5af5a
1a3b4d ¤   ¤   if (IsNull((PIRP) pIrp))
4b3ad2 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoBuildIOCTLRequestFailed);
929371 ¤   }
f7af5a
09ecea ¤   // Send the request.
5a2361 ¤   if (derr.IsntError())
0fc7a1 ¤   {
77cac8 ¤   ¤   pIrp.NextStackLocation()->FileObject = mVHFileObject;
38af5a
421eaa ¤   ¤   status = IoCallDriver(mVHDeviceObject, pIrp);
9cd83c ·
cb80b6 ¤   ¤   if (status == STATUS_PENDING)
0d5b34 ¤   ¤   {
8fe7a0 ¤   ¤   ¤   KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
4a34ec ¤   ¤   ¤   status = ioStatus.Status;
fa0fe4 ¤   ¤   }
27af5a
656412 ¤   ¤   if (!NT_SUCCESS(status))
f5f2d7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoCallDriverFailed, status);
8a9371 ¤   }
cfaf5a
05a2a1 ¤   // Close volume handle.
8cec92 ¤   if (openedVolHandle)
54c3f7 ¤   ¤   CloseVolumeHandle();
70af5a
2e33e3 ¤   return derr;
b9efe6 }
dfaf5a
40af5a
7751ef ////////////////////////////////////////
aaccdf // Class Volume private member functions
7951ef ////////////////////////////////////////
--e4c1 0004c6f0b3240110108 Page 10 of Volume.cpp
e0af5a
b18be3 // VolumeHandleOpened returns TRUE if a handle to the volume has been opened,
db9a91 // FALSE otherwise.
a2af5a
5677be PGPBoolean·
7f11b4 Volume::VolumeHandleOpened()
1cbb36 {
22fa09 ¤   return (IsntNull(mVolumeHandle));
aaefe6 }
18af5a
5f543f // GetDriveGeometry gets the geometry of the specified drive.
b4af5a
74e677 DualErr
8c7340 Volume::GetDriveGeometry()
bbbb36 {
afbe41 ¤   DualErr¤¤   derr;
099cce ¤   PGPBoolean¤ openedVolHandle;
94af5a
093ec3 ¤   pgpAssert(Mounted());
c4af5a
e23bef ¤   if (!VolumeHandleOpened())
a5c7a1 ¤   {
7fdb24 ¤   ¤   derr = OpenVolumeHandle();
2de3e6 ¤   ¤   openedVolHandle = derr.IsntError();
ac9371 ¤   }
dbaf5a
061d15 ¤   // Send down the request.
a62361 ¤   if (derr.IsntError())
0fc7a1 ¤   {
dfc377 ¤   ¤   derr = SendIOCTLRequest(IRP_MJ_DEVICE_CONTROL, 0,·
f43331 ¤   ¤   ¤   IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &mGeometry,·
a2f584 ¤   ¤   ¤   sizeof(mGeometry));
829371 ¤   }
1daf5a
c3ec92 ¤   if (openedVolHandle)
55c3f7 ¤   ¤   CloseVolumeHandle();
cfaf5a
4333e3 ¤   return derr;
73efe6 }
47af5a
213be9 // OpenVolumeHandle opens a handle to the actual volume and references the
a6f74b // associated file object.
d3af5a
6f9d6b DualErr¤
3a4c42 Volume::OpenVolumeHandle()
5ebb36 {
c09a95 ¤   DualErr¤¤   ¤   derr;
f4671f ¤   IO_STATUS_BLOCK¤ioStatus;
c54db4 ¤   KUstring¤   ¤   drivePath;
a639be ¤   NTSTATUS¤   ¤   status;
71d379 ¤   PGPBoolean¤ ¤   openedVol, reffedFileObj;
3faf5a
121b26 ¤   openedVol = reffedFileObj = FALSE;
5eaf5a
26eff6 ¤   pgpAssert(!VolumeHandleOpened());
ffaf5a
a4be12 ¤   // Get path to volume.
2be5f0 ¤   derr = MakePathToDrive(mDrive, &drivePath);
f9af5a
eea582 ¤   // Get handle to volume;
ae2361 ¤   if (derr.IsntError())
95c7a1 ¤   {
42c5ea ¤   ¤   OBJECT_ATTRIBUTES objectAttributes;
64af5a
927b34 ¤   ¤   InitializeObjectAttributes(&objectAttributes, drivePath,·
431af1 ¤   ¤   ¤   OBJ_CASE_INSENSITIVE, NULL, NULL);
03af5a
ef1de8 ¤   ¤   status = ZwCreateFile(&mVolumeHandle,·
806106 ¤   ¤   ¤   SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,·
830864 ¤   ¤   ¤   &objectAttributes, &ioStatus, NULL, 0,·
f66df5 ¤   ¤   ¤   FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,·
4c7cd1 ¤   ¤   ¤   FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
--8a41 0003cc7487640110108 Page 11 of Volume.cpp
e0af5a
7c6412 ¤   ¤   if (!NT_SUCCESS(status))
4199cf ¤   ¤   ¤   derr = DualErr(kPGDMinorError_ZwCreateFileFailed, status);
66af5a
96b077 ¤   ¤   openedVol = derr.IsntError();
6f9371 ¤   }
18af5a
f0c275 ¤   // Get file object from this handle.
0d2361 ¤   if (derr.IsntError())
88c7a1 ¤   {
02c1d7 ¤   ¤   status = ObReferenceObjectByHandle(mVolumeHandle, FILE_READ_DATA,·
c8f963 ¤   ¤   ¤   NULL, KernelMode, (void **) &mVHFileObject, NULL);
72af5a
de6412 ¤   ¤   if (!NT_SUCCESS(status))
1ece70 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_ObRefObjByHandleFailed, status);
83af5a
b0a23e ¤   ¤   reffedFileObj = derr.IsntError();
2e9371 ¤   }
6baf5a
1105bb ¤   // Initialize variables on success.
8d2361 ¤   if (derr.IsntError())
68c7a1 ¤   {
896f09 ¤   ¤   mVHDeviceObject = IoGetRelatedDeviceObject(mVHFileObject);
159371 ¤   }
68af5a
fcfa3f ¤   // Cleaup on error.
064bb3 ¤   if (derr.IsError())
1ec7a1 ¤   {
d21403 ¤   ¤   if (reffedFileObj)
dc5b34 ¤   ¤   {
3d6694 ¤   ¤   ¤   ObDereferenceObject(mVHFileObject);
a77fef ¤   ¤   ¤   mVHFileObject = NULL;
46430e ¤   ¤   ¤   mVHDeviceObject = NULL;
b20fe4 ¤   ¤   }
8daf5a
8fab6a ¤   ¤   if (openedVol)
b85b34 ¤   ¤   {
16fb61 ¤   ¤   ¤   ZwClose(mVolumeHandle);
c7ccd8 ¤   ¤   ¤   mVolumeHandle = NULL;
c70fe4 ¤   ¤   }
3c9371 ¤   }
ddaf5a
0533e3 ¤   return derr;
c9efe6 }
4baf5a
56273e // CloseVolumeHandle closes a handle opened with OpenVolumeHandle.
fdaf5a
cdc823 void·
838ab3 Volume::CloseVolumeHandle()
85bb36 {
5e6a85 ¤   pgpAssert(VolumeHandleOpened());
74af5a
9306f6 ¤   // Dereference file object pointer taken before.
fef6a2 ¤   ObDereferenceObject(mVHFileObject);
37c1b3 ¤   mVHFileObject = NULL;
d565ac ¤   mVHDeviceObject = NULL;
9daf5a
15a2a1 ¤   // Close volume handle.
f2ddc3 ¤   ZwClose(mVolumeHandle);
69af5a
f27284 ¤   mVolumeHandle = NULL;
9befe6 }
7eaf5a
ff0ab7 // SendIOCTLRequest sends an IOCTL request to the mounted volume.
a5af5a
512292 DualErr·
767ef6 Volume::SendIOCTLRequest(
b7237e ¤   PGPUInt8¤   majorFunc,·
9d2f48 ¤   PGPUInt8¤   minorFunc,·
3095b3 ¤   PGPUInt32¤  ioctlCode,·
b60734 ¤   PVOID¤  ¤   inBuf,·
3c1e55 ¤   PGPUInt32¤  sizeInBuf,·
--6b8f 001db8a775040110108 Page 12 of Volume.cpp
ae9c2b ¤   PVOID¤  ¤   outBuf,·
07eba5 ¤   PGPUInt32¤  sizeOutBuf)
fcbb36 {
70705b ¤   DualErr¤¤   ¤   ¤   derr;
7d0ed0 ¤   KEVENT¤ ¤   ¤   ¤   event;
1eedeb ¤   IO_STATUS_BLOCK¤¤   ioStatus;
e2c08d ¤   KIrp¤   ¤   ¤   ¤   pIrp;
1563a6 ¤   NTSTATUS¤   ¤   ¤   status;
deaf5a
2a3ec3 ¤   pgpAssert(Mounted());
1e6a85 ¤   pgpAssert(VolumeHandleOpened());
aeaf5a
72a754 ¤   // Initialize the event.
a1cd20 ¤   KeInitializeEvent(&event, NotificationEvent, FALSE);
39af5a
94e78e ¤   // Build the request.
5b5b27 ¤   pIrp = IoBuildDeviceIoControlRequest(ioctlCode, mVHDeviceObject, inBuf,·
3b6b2f ¤   ¤   sizeInBuf, outBuf, sizeOutBuf, FALSE, &event, &ioStatus);
b2af5a
7d801b ¤   if (IsNull((PIRP) pIrp))
5a2ff1 ¤   ¤   derr = DualErr(kPGDMinorError_IoBuildIOCTLRequestFailed);
0faf5a
ffd055 ¤   // Call down the request.
d62361 ¤   if (derr.IsntError())
99c7a1 ¤   {
5072a4 ¤   ¤   pIrp.MajorFunction(NEXT) = majorFunc;
148ba8 ¤   ¤   pIrp.MinorFunction(NEXT) = minorFunc;
32af5a
bbcac8 ¤   ¤   pIrp.NextStackLocation()->FileObject = mVHFileObject;
62861c ¤   ¤   pIrp.IoctlCode(NEXT) = ioctlCode;
a5af5a
b71eaa ¤   ¤   status = IoCallDriver(mVHDeviceObject, pIrp);
b3af5a
8880b6 ¤   ¤   if (status == STATUS_PENDING)
325b34 ¤   ¤   {
e0e7a0 ¤   ¤   ¤   KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
8e34ec ¤   ¤   ¤   status = ioStatus.Status;
670fe4 ¤   ¤   }
0caf5a
c46412 ¤   ¤   if (!NT_SUCCESS(status))
0ef2d7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IoCallDriverFailed, status);
799371 ¤   }
04af5a
1933e3 ¤   return derr;
45efe6 }
72af5a
79cbc9 // SendUserFSCTLRequest is a wrapper around SendIOCTLRequest.
04af5a
932292 DualErr·
aa17aa Volume::SendUserFSCTLRequest(PGPUInt32 fsctlCode)
b1bb36 {
4d3ec3 ¤   pgpAssert(Mounted());
bd6a85 ¤   pgpAssert(VolumeHandleOpened());
97af5a
25ea30 ¤   return SendIOCTLRequest(IRP_MJ_FILE_SYSTEM_CONTROL,·
d07f95 ¤   ¤   IRP_MN_USER_FS_REQUEST, fsctlCode);
dbefe6 }
--3f2b 000d05cee6b40110109 Page 1 of Volume.h
541bc3 //////////////////////////////////////////////////////////////////////////////
54d7ee // Volume.h
2f465d //
5be0c7 // Declaration of class Volume.
921bc3 //////////////////////////////////////////////////////////////////////////////
c9af5a
93a02b // $Id: Volume.h,v 1.1.2.15 1998/07/06 08:58:00 nryan Exp $
5caf5a
d1cbce // Copyright (C) 1998 by Network Associates, Inc.
3171ae // All rights reserved.
1caf5a
0a46c3 #ifndef Included_Volume_h¤  // [
ebce0d #define Included_Volume_h
5daf5a
186d2e #include <ntdddisk.h>
4e3a85 #include "DualErr.h"
e6af5a
bb9281 #include "CPGPdiskDriver.h"
1128cd #include "FSCTLCodes.h"
bfaf5a
75af5a
027606 ///////////////
de6d45 // Class Volume
8b7606 ///////////////
99af5a
0ec450 // Class Volume can be used to represent any local volume on the system. It
f19577 // can also be used to mount and unmount new volumes.
92af5a
eb38b0 class Volume
30bb36 {
a05ed4 public:
9a85fe ¤   ¤   ¤   ¤   ¤   Volume();
57d0cd ¤   virtual¤¤   ¤   ~Volume();
4caf5a
640733 ¤   PGPBoolean¤ ¤   Mounted();
88d933 ¤   PGPBoolean¤ ¤   Unmounted();
74987a ¤   PGPBoolean¤ ¤   AttachedToLocalVolume();
3ffbf0 ¤   PGPBoolean¤ ¤   HasOpenFiles();
f5af5a
76a2e0 ¤   PGPBoolean¤ ¤   LockedForReadWrite();
4fffd0 ¤   PGPBoolean¤ ¤   LockedForFormat();
0baf5a
581076 ¤   PGPUInt8¤   ¤   GetDrive();
19f63c ¤   PGPUInt16¤  ¤   GetBlockSize();
f5327a ¤   PGPUInt64¤  ¤   GetTotalBlocks();
ea0dfd ¤   PDEVICE_OBJECT¤ GetDeviceObject();
95af5a
544f15 ¤   DualErr¤¤   ¤   AttachLocalVolume(PGPUInt8 drive);
c61abf ¤   void¤   ¤   ¤   DetachLocalVolume();
dbaf5a
aff07e ¤   DualErr¤¤   ¤   Mount(LPCSTR deviceName, PGPUInt8 drive = kInvalidDrive,·
b05b6d ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly = FALSE);
3cd007 ¤   DualErr¤¤   ¤   Unmount(PGPBoolean isThisEmergency = FALSE);
dbaf5a
07b553 ¤   DualErr¤¤   ¤   LockVolumeForReadWrite();
c6e686 ¤   DualErr¤¤   ¤   LockVolumeForFormat();
4a67b9 ¤   DualErr¤¤   ¤   UnlockVolume();
29af5a
5e160f ¤   DualErr¤¤   ¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks);
8b3eaa ¤   DualErr¤¤   ¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks);
a6af5a
87a2d3 protected:
944b3a ¤   PDEVICE_OBJECT¤ mDeviceObject;¤ // device object for volume
3e01f5 ¤   PGPUInt32¤  ¤   mDevExtInfo;¤   // value to put in device extension
ecaf5a
a40fb9 private:
2d6d60 ¤   enum MountState¤{kVol_Mounted, kVol_Unmounted};
742ca6 ¤   enum LockState¤ {kLock_None, kLock_ReadWrite, kLock_Format};
c4af5a
b85f0a ¤   MountState¤ ¤   mMountState;¤   // holds mount status of volume
1ba834 ¤   LockState¤  ¤   mLockState;¤¤   // lock status of the volume
d01841 ¤   PGPUInt8¤   ¤   mDrive;¤¤   ¤   // mounted drive number
--4290 001f4603f6940110109 Page 2 of Volume.h
e0af5a
a3cb76 ¤   PGPBoolean¤ ¤   mAttachedToLocalVol;¤   // attached to local volume?
53af5a
7d7c17 ¤   PDEVICE_OBJECT¤ mVHDeviceObject;¤   // device object for handle
dc14d5 ¤   PFILE_OBJECT¤   mVHFileObject;¤ ¤   // file object for handle
5e0795 ¤   HANDLE¤ ¤   ¤   mVolumeHandle;¤ ¤   // handle to volume
6eaf5a
801cbe ¤   KUstring¤   ¤   mDeviceName;¤   // device name
df07e2 ¤   KUstring¤   ¤   mLinkName;¤ ¤   // link name
05af5a
32c65b ¤   DISK_GEOMETRY¤  mGeometry;¤ ¤   // geometry of drive
f7af5a
444df2 ¤   PGPBoolean¤ ¤   VolumeHandleOpened();
a7fde7 ¤   DualErr¤¤   ¤   GetDriveGeometry();
afaf5a
1fdeca ¤   DualErr¤¤   ¤   OpenVolumeHandle();
c703ba ¤   void¤   ¤   ¤   CloseVolumeHandle();
cfaf5a
ac8b16 ¤   DualErr¤¤   ¤   SendIOCTLRequest(PGPUInt8 majorFunc, PGPUInt8 minorFunc,·
f33d35 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 ioctlCode, PVOID inBuf = NULL,·
8ddb16 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 sizeInBuf = 0, PVOID outBuf = NULL,·
67b3f2 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 sizeOutBuf = 0);
65af5a
d5cecc ¤   DualErr¤¤   ¤   SendUserFSCTLRequest(PGPUInt32 fsctlCode);
7a82f7 };
81af5a
f4ac71 #endif¤ // ] Included_Volume_h
--c6e5 001c056ca874011010a Page 1 of PGPdiskDrvDebug.bat
05e79f set DEVSTUDIO=C:\Program Files\Devstudio
6ba36b set SOURCEPATH=C:\PGP60\Clients\Disk\Win32
c2af5a
c0fee2 call %SOURCEPATH%\PGPdiskDrvWin95\PGPdiskDrvDebugAux.bat %1 %2
--3fd4 000cb82ccfb4011010b Page 1 of PGPdiskDrvDebug.mak
001db9 # PGPdiskDrvDebug.mak - makefile for port driver PGPdisk
86af5a
0e71c0 DEVICENAME¤ ¤   = PGPDISK
0e7d3b DEVICETYPE¤ ¤   = PORTDRIVER
1bf51e DYNAMIC¤¤   ¤   = 1
f2622f FRAMEWORK¤  ¤   = CPP
46a0d1 USER_COMMENT¤   = "PGPdisk Volume Driver"
22af5a
410bd2 DEBUG¤  ¤   ¤   = 1
8e6b39 DEBUGGER¤   ¤   = SOFTICE3
18af5a
8ec187 _MSC_VER¤   ¤   = 5000
9f6eb4 SOURCEPATH¤ ¤   = ../Source
9aaf5a
639dd3 USER_LIB¤   ¤   = Llmul.obj Llshl.obj Ullrem.obj Ulldiv.obj Ullshr.obj
1eaf5a
81dbe0 PGPDIRS¤¤   ¤   = /I "..\..\..\..\..\libs\pfl\common" \
4c72d6 ¤   ¤   ¤   ¤   ¤   /I "..\..\..\..\..\libs\pfl\win32" /I "..\FakeSource" \
489072 ¤   ¤   ¤   ¤   ¤   /I "..\..\Shared" /I "..\..\Encryption" \
b991d2 ¤   ¤   ¤   ¤   ¤   /I "$(DEVSTUDIO)\VC\Include"
b5af5a
7d0735 COPTFLAGS¤  =·
a1867d OBJPATH¤¤   = ../Debug/
0daf5a
f683c5 XFLAGS = $(PGPDIRS) /W3 /WX /DUCHAR_MAX=0xFF /DUSHRT_MAX=0xFFFF \
4ebf28 ¤   ¤   ¤   /DULONG_MAX=0xFFFFFFFF /DINT_MAX=0xFFFFFFFF /D_CRT_ASSERT=0 \
5200fb ¤   ¤   ¤   /D_MSC_VER=5000 /DDEBUG /DPGP_DEBUG=1 /DPGPDISK_95DRIVER \
d96e83 ¤   ¤   ¤   /DPGP_INTEL /DPGP_WIN32 /DUNFINISHED_CODE_ALLOWED
17af5a
10f2b2 OBJECTS =¤  $(OBJPATH)pgpDebug.OBJ \
0b4d30 ¤   ¤   ¤   $(OBJPATH)pgpLeaks.OBJ \
97500e ¤   ¤   ¤   $(OBJPATH)pgpMem.OBJ \
b07acd ¤   ¤   ¤   $(OBJPATH)DcbManager.OBJ \
aabe34 ¤   ¤   ¤   $(OBJPATH)FatParser.OBJ \
9d310d ¤   ¤   ¤   $(OBJPATH)File.OBJ \
9f959d ¤   ¤   ¤   $(OBJPATH)FileSystemParser.OBJ \
dc6bf6 ¤   ¤   ¤   $(OBJPATH)IopProcessor.OBJ \
26cab7 ¤   ¤   ¤   $(OBJPATH)PGPdisk.OBJ \
8b7df9 ¤   ¤   ¤   $(OBJPATH)VolFile.OBJ \
be24ae ¤   ¤   ¤   $(OBJPATH)Volume.OBJ \
475f88 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrv.OBJ \
5f31e8 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvComm.OBJ \
2c06f4 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvDebug.OBJ \
39a40b ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvErrors.OBJ \
d88293 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvHooks.OBJ \
c45c96 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvIos.OBJ \
dc4db9 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvVolumes.OBJ \
7cd5da ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvWinutils.OBJ \
15c4dc ¤   ¤   ¤   $(OBJPATH)CommonStrings.OBJ \
a7c3e2 ¤   ¤   ¤   $(OBJPATH)DualErr.OBJ \
1d1b46 ¤   ¤   ¤   $(OBJPATH)Errors.OBJ \
493c47 ¤   ¤   ¤   $(OBJPATH)FatUtils.OBJ \
bb5be0 ¤   ¤   ¤   $(OBJPATH)PGPdiskContainer.OBJ \
8c6441 ¤   ¤   ¤   $(OBJPATH)PGPdiskHighLevelUtils.OBJ \
29bb6f ¤   ¤   ¤   $(OBJPATH)PGPdiskLowLevelUtils.OBJ \
61b8bb ¤   ¤   ¤   $(OBJPATH)PGPdiskPfl.OBJ \
06a1a7 ¤   ¤   ¤   $(OBJPATH)SecureMemory.OBJ \
7b0a69 ¤   ¤   ¤   $(OBJPATH)SecureString.OBJ \
7e86c6 ¤   ¤   ¤   $(OBJPATH)StringAssociation.OBJ \
0bc936 ¤   ¤   ¤   $(OBJPATH)WaitObjectClasses.OBJ \
f7ca4d ¤   ¤   ¤   $(OBJPATH)Cast5.OBJ \
5fb278 ¤   ¤   ¤   $(OBJPATH)Cast5Box.OBJ \
65e93b ¤   ¤   ¤   $(OBJPATH)CipherContext.OBJ \
089c8f ¤   ¤   ¤   $(OBJPATH)CipherUtils.OBJ \
c6888b ¤   ¤   ¤   $(OBJPATH)SHA.OBJ
2aaf5a
000099 !include $(VTOOLSD)\include\vtoolsd.mak
6e800a !include $(VTOOLSD)\include\vxdtarg.mak
efaf5a
345d9c pgpDebug.OBJ:¤  ¤   ¤   ¤   pgpDebug.c
1e8779 pgpLeaks.OBJ:¤  ¤   ¤   ¤   pgpLeaks.c
cb21da pgpMem.OBJ:¤¤   ¤   ¤   ¤   pgpMem.c
--3880 001f27cf3c24011010b Page 2 of PGPdiskDrvDebug.mak
9361e3 CommonStrings.OBJ:¤ ¤   ¤   CommonStrings.cpp
3c8bae DcbManager.OBJ:¤¤   ¤   ¤   DcbManager.cpp
713b0e DualErr.OBJ:¤   ¤   ¤   ¤   DualErr.cpp
7663c8 Errors.OBJ:¤¤   ¤   ¤   ¤   Errors.cpp
bebcc2 FatParser.OBJ:¤ ¤   ¤   ¤   FatParser.cpp
d54457 File.OBJ:¤  ¤   ¤   ¤   ¤   File.cpp
ddc85c FileSystemParser.OBJ:¤  ¤   FileSystemParser.cpp
bde3fc IopProcessor.OBJ:¤  ¤   ¤   IopProcessor.cpp
00fe9d PGPdisk.OBJ:¤   ¤   ¤   ¤   PGPdisk.cpp
06235b VolFile.OBJ:¤   ¤   ¤   ¤   VolFile.cpp
ebea42 Volume.OBJ:¤¤   ¤   ¤   ¤   Volume.cpp
5ecd61 CPGPdiskDrv.OBJ:¤   ¤   ¤   CPGPdiskDrv.cpp
e03dbc CPGPdiskDrvComm.OBJ:¤   ¤   CPGPdiskDrvComm.cpp
1b87d0 CPGPdiskDrvDebug.OBJ:¤  ¤   CPGPdiskDrvDebug.cpp
297c5e CPGPdiskDrvErrors.OBJ:¤ ¤   CPGPdiskDrvErrors.cpp
7e8b3b CPGPdiskDrvHooks.OBJ:¤  ¤   CPGPdiskDrvHooks.cpp
d72bc4 CPGPdiskDrvIos.OBJ:¤¤   ¤   CPGPdiskDrvIos.cpp
4edd1a CPGPdiskDrvVolumes.OBJ:¤¤   CPGPdiskDrvVolumes.cpp
d7e87b CPGPdiskDrvWinutils.OBJ:¤   CPGPdiskDrvWinutils.cpp
b6a67f FatUtils.OBJ:¤  ¤   ¤   ¤   FatUtils.cpp
88a94f PGPdiskContainer.OBJ:¤  ¤   PGPdiskContainer.cpp
d5b1d2 PGPdiskHighLevelUtils.OBJ:¤ PGPdiskHighLevelUtils.cpp
9fe7e6 PGPdiskLowLevelUtils.OBJ:¤  PGPdiskLowLevelUtils.cpp
585766 PGPdiskPfl.OBJ:¤¤   ¤   ¤   PGPdiskPfl.cpp
23a3d3 SecureMemory.OBJ:¤  ¤   ¤   SecureMemory.cpp
1d47e6 SecureString.OBJ:¤  ¤   ¤   SecureString.cpp
3b96eb StringAssociation.OBJ:¤ ¤   StringAssociation.cpp
707df9 WaitObjectClasses.OBJ:¤ ¤   WaitObjectClasses.cpp
95de18 Cast5.OBJ:¤ ¤   ¤   ¤   ¤   Cast5.cpp
f9430a Cast5Box.OBJ:¤  ¤   ¤   ¤   Cast5Box.cpp
556461 CipherContext.OBJ:¤ ¤   ¤   CipherContext.cpp
700f0f CipherUtils.OBJ:¤   ¤   ¤   CipherUtils.cpp
cc1e22 PGPdiskRandomPool.OBJ:¤ ¤   PGPdiskRandomPool.cpp
f229e5 SHA.OBJ:¤   ¤   ¤   ¤   ¤   SHA.cpp
--6538 00101f091644011010c Page 1 of PGPdiskDrvDebugAux.bat
2e6ec8 rem Makefile wrapper for PGPdiskDrv.
9aaf5a
f93f3c cd PGPdiskDrvWin95
d1af5a
3f3446 copy ..\..\..\..\libs\pfl\common\*.c Source
44518b copy ..\Shared\*.cpp Source
c38371 copy ..\Encryption\*.cpp Source
b6af5a
521e49 mkdir Debug
88af5a
8e0d5a copy PGPdiskDrvDebug.mak Debug
24af5a
716a6b cd Debug
11af5a
dc323d NMAKE %1 /s /f PGPdiskDrvDebug.mak
6faf5a
b529f0 cd ..\Source
00af5a
46a955 cl /P /EP PGPdiskVrcSource.cpp
66af5a
5b4813 del ..\Debug\PGPdisk.vrc
6d2b6e move PGPdiskVrcSource.i ..\Debug\PGPdisk.vrc
74af5a
45447f cd ..\Debug
72af5a
130597 %VTOOLSD%\bin\vxdver PGPdisk.vrc PGPdisk.res
dff3d0 %VTOOLSD%\bin\sethdr -r PGPdisk.res PGPdisk.pdr
13af5a
2f29f0 cd ..\Source
92af5a
a888d6 del pgpBinaryTree.c
da7c38 del pgpDebug.c
17394c del pgpLeaks.c
79bc3b del pgpMem.c
8c3d2f del pgpMemoryMgr.c
4f41a2 del pgpMemoryMgrMac.c
82ff85 del pgpMemoryMgrStd.c
43d8fe del pgpMemoryMgrWin32.c
d18cab del pgpRMWOLock.c
c77c18 del pgpTemplate.c
b0af5a
785418 del CommonStrings.cpp
f475ef del DriverComm.cpp
d0f0c1 del DualErr.cpp
de7895 del Errors.cpp
928b2f del FatUtils.cpp
aeb014 del LinkResolution.cpp
fba985 del PGPdiskContainer.cpp
24c1c4 del PGPdiskHighLevelUtils.cpp
b479d4 del PGPdiskLowLevelUtils.cpp
62b9e7 del PGPdiskPfl.cpp
380558 del PGPdiskPublicKeyUtils.cpp
17ad2d del PGPdiskRegistry.cpp
f83703 del SecureMemory.cpp
95faa2 del SecureString.cpp
d0e6a0 del SharedMemory.cpp
63a46b del StringAssociation.cpp
d4f073 del WaitObjectClasses.cpp
c01620 del Win32Utils.cpp
66a97e del WindowsVersion.cpp
dcaf5a
13f576 del Cast5.cpp
96870b del Cast5Box.cpp
70b889 del CipherContext.cpp
33c297 del CipherUtils.cpp
8fa92b del PGPdiskRandomPool.cpp
0147a0 del SHA.cpp
--45b4 0016fb32a1b4011010d Page 1 of PGPdiskDrvRelease.bat
05e79f set DEVSTUDIO=C:\Program Files\Devstudio
6ba36b set SOURCEPATH=C:\PGP60\Clients\Disk\Win32
c2af5a
6f3e82 call %SOURCEPATH%\PGPdiskDrvWin95\PGPdiskDrvReleaseAux.bat %1 %2
--3dbc 00020aaab774011010e Page 1 of PGPdiskDrvRelease.mak
57605e # PGPdiskDrvRelease.mak - makefile for port driver PGPdisk
f7af5a
6371c0 DEVICENAME¤ ¤   = PGPDISK
327d3b DEVICETYPE¤ ¤   = PORTDRIVER
3af51e DYNAMIC¤¤   ¤   = 1
c0622f FRAMEWORK¤  ¤   = CPP
78a0d1 USER_COMMENT¤   = "PGPdisk Volume Driver"
cfaf5a
cc120a DEBUG¤  ¤   ¤   = 0
471cdf DEBUGGER¤   ¤   =·
35af5a
32c187 _MSC_VER¤   ¤   = 5000
e46eb4 SOURCEPATH¤ ¤   = ../Source
13af5a
d39dd3 USER_LIB¤   ¤   = Llmul.obj Llshl.obj Ullrem.obj Ulldiv.obj Ullshr.obj
7aaf5a
60dbe0 PGPDIRS¤¤   ¤   = /I "..\..\..\..\..\libs\pfl\common" \
8c72d6 ¤   ¤   ¤   ¤   ¤   /I "..\..\..\..\..\libs\pfl\win32" /I "..\FakeSource" \
649072 ¤   ¤   ¤   ¤   ¤   /I "..\..\Shared" /I "..\..\Encryption" \
0591d2 ¤   ¤   ¤   ¤   ¤   /I "$(DEVSTUDIO)\VC\Include"
5faf5a
df7b2f COPTFLAGS¤  = /O2
ca0709 OBJPATH¤¤   = ../Release/
6daf5a
0683c5 XFLAGS = $(PGPDIRS) /W3 /WX /DUCHAR_MAX=0xFF /DUSHRT_MAX=0xFFFF \
11bf28 ¤   ¤   ¤   /DULONG_MAX=0xFFFFFFFF /DINT_MAX=0xFFFFFFFF /D_CRT_ASSERT=0 \
86c2b8 ¤   ¤   ¤   /D_MSC_VER=5000 /DPGP_DEBUG=0 /DPGPDISK_95DRIVER /DPGP_INTEL \
642938 ¤   ¤   ¤   /DPGP_WIN32
37af5a
4bf2b2 OBJECTS =¤  $(OBJPATH)pgpDebug.OBJ \
584d30 ¤   ¤   ¤   $(OBJPATH)pgpLeaks.OBJ \
b8500e ¤   ¤   ¤   $(OBJPATH)pgpMem.OBJ \
257acd ¤   ¤   ¤   $(OBJPATH)DcbManager.OBJ \
64be34 ¤   ¤   ¤   $(OBJPATH)FatParser.OBJ \
86310d ¤   ¤   ¤   $(OBJPATH)File.OBJ \
1b959d ¤   ¤   ¤   $(OBJPATH)FileSystemParser.OBJ \
3b6bf6 ¤   ¤   ¤   $(OBJPATH)IopProcessor.OBJ \
85cab7 ¤   ¤   ¤   $(OBJPATH)PGPdisk.OBJ \
407df9 ¤   ¤   ¤   $(OBJPATH)VolFile.OBJ \
9e24ae ¤   ¤   ¤   $(OBJPATH)Volume.OBJ \
b55f88 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrv.OBJ \
5a31e8 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvComm.OBJ \
ad06f4 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvDebug.OBJ \
c8a40b ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvErrors.OBJ \
828293 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvHooks.OBJ \
5a5c96 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvIos.OBJ \
d34db9 ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvVolumes.OBJ \
7ad5da ¤   ¤   ¤   $(OBJPATH)CPGPdiskDrvWinutils.OBJ \
aac4dc ¤   ¤   ¤   $(OBJPATH)CommonStrings.OBJ \
f3c3e2 ¤   ¤   ¤   $(OBJPATH)DualErr.OBJ \
d71b46 ¤   ¤   ¤   $(OBJPATH)Errors.OBJ \
703c47 ¤   ¤   ¤   $(OBJPATH)FatUtils.OBJ \
385be0 ¤   ¤   ¤   $(OBJPATH)PGPdiskContainer.OBJ \
dc6441 ¤   ¤   ¤   $(OBJPATH)PGPdiskHighLevelUtils.OBJ \
09bb6f ¤   ¤   ¤   $(OBJPATH)PGPdiskLowLevelUtils.OBJ \
42b8bb ¤   ¤   ¤   $(OBJPATH)PGPdiskPfl.OBJ \
c6a1a7 ¤   ¤   ¤   $(OBJPATH)SecureMemory.OBJ \
210a69 ¤   ¤   ¤   $(OBJPATH)SecureString.OBJ \
ec86c6 ¤   ¤   ¤   $(OBJPATH)StringAssociation.OBJ \
67c936 ¤   ¤   ¤   $(OBJPATH)WaitObjectClasses.OBJ \
44ca4d ¤   ¤   ¤   $(OBJPATH)Cast5.OBJ \
c5b278 ¤   ¤   ¤   $(OBJPATH)Cast5Box.OBJ \
93e93b ¤   ¤   ¤   $(OBJPATH)CipherContext.OBJ \
139c8f ¤   ¤   ¤   $(OBJPATH)CipherUtils.OBJ \
ad888b ¤   ¤   ¤   $(OBJPATH)SHA.OBJ
7faf5a
9a0099 !include $(VTOOLSD)\include\vtoolsd.mak
5e800a !include $(VTOOLSD)\include\vxdtarg.mak
9daf5a
895d9c pgpDebug.OBJ:¤  ¤   ¤   ¤   pgpDebug.c
188779 pgpLeaks.OBJ:¤  ¤   ¤   ¤   pgpLeaks.c
2021da pgpMem.OBJ:¤¤   ¤   ¤   ¤   pgpMem.c
--621e 001f27cf3c24011010e Page 2 of PGPdiskDrvRelease.mak
9361e3 CommonStrings.OBJ:¤ ¤   ¤   CommonStrings.cpp
3c8bae DcbManager.OBJ:¤¤   ¤   ¤   DcbManager.cpp
713b0e DualErr.OBJ:¤   ¤   ¤   ¤   DualErr.cpp
7663c8 Errors.OBJ:¤¤   ¤   ¤   ¤   Errors.cpp
bebcc2 FatParser.OBJ:¤ ¤   ¤   ¤   FatParser.cpp
d54457 File.OBJ:¤  ¤   ¤   ¤   ¤   File.cpp
ddc85c FileSystemParser.OBJ:¤  ¤   FileSystemParser.cpp
bde3fc IopProcessor.OBJ:¤  ¤   ¤   IopProcessor.cpp
00fe9d PGPdisk.OBJ:¤   ¤   ¤   ¤   PGPdisk.cpp
06235b VolFile.OBJ:¤   ¤   ¤   ¤   VolFile.cpp
ebea42 Volume.OBJ:¤¤   ¤   ¤   ¤   Volume.cpp
5ecd61 CPGPdiskDrv.OBJ:¤   ¤   ¤   CPGPdiskDrv.cpp
e03dbc CPGPdiskDrvComm.OBJ:¤   ¤   CPGPdiskDrvComm.cpp
1b87d0 CPGPdiskDrvDebug.OBJ:¤  ¤   CPGPdiskDrvDebug.cpp
297c5e CPGPdiskDrvErrors.OBJ:¤ ¤   CPGPdiskDrvErrors.cpp
7e8b3b CPGPdiskDrvHooks.OBJ:¤  ¤   CPGPdiskDrvHooks.cpp
d72bc4 CPGPdiskDrvIos.OBJ:¤¤   ¤   CPGPdiskDrvIos.cpp
4edd1a CPGPdiskDrvVolumes.OBJ:¤¤   CPGPdiskDrvVolumes.cpp
d7e87b CPGPdiskDrvWinutils.OBJ:¤   CPGPdiskDrvWinutils.cpp
b6a67f FatUtils.OBJ:¤  ¤   ¤   ¤   FatUtils.cpp
88a94f PGPdiskContainer.OBJ:¤  ¤   PGPdiskContainer.cpp
d5b1d2 PGPdiskHighLevelUtils.OBJ:¤ PGPdiskHighLevelUtils.cpp
9fe7e6 PGPdiskLowLevelUtils.OBJ:¤  PGPdiskLowLevelUtils.cpp
585766 PGPdiskPfl.OBJ:¤¤   ¤   ¤   PGPdiskPfl.cpp
23a3d3 SecureMemory.OBJ:¤  ¤   ¤   SecureMemory.cpp
1d47e6 SecureString.OBJ:¤  ¤   ¤   SecureString.cpp
3b96eb StringAssociation.OBJ:¤ ¤   StringAssociation.cpp
707df9 WaitObjectClasses.OBJ:¤ ¤   WaitObjectClasses.cpp
95de18 Cast5.OBJ:¤ ¤   ¤   ¤   ¤   Cast5.cpp
f9430a Cast5Box.OBJ:¤  ¤   ¤   ¤   Cast5Box.cpp
556461 CipherContext.OBJ:¤ ¤   ¤   CipherContext.cpp
700f0f CipherUtils.OBJ:¤   ¤   ¤   CipherUtils.cpp
cc1e22 PGPdiskRandomPool.OBJ:¤ ¤   PGPdiskRandomPool.cpp
f229e5 SHA.OBJ:¤   ¤   ¤   ¤   ¤   SHA.cpp
--c0be 0011fa3b3ea4011010f Page 1 of PGPdiskDrvReleaseAux.bat
2e6ec8 rem Makefile wrapper for PGPdiskDrv.
9aaf5a
f93f3c cd PGPdiskDrvWin95
d1af5a
3f3446 copy ..\..\..\..\libs\pfl\common\*.c Source
44518b copy ..\Shared\*.cpp Source
c38371 copy ..\Encryption\*.cpp Source
b6af5a
654041 mkdir Release
e3af5a
e92abb copy PGPdiskDrvRelease.mak Release
b8af5a
4d6561 cd Release
fdaf5a
ebfa50 NMAKE %1 /s /f PGPdiskDrvRelease.mak
9faf5a
7f29f0 cd ..\Source
01af5a
3ca955 cl /P /EP PGPdiskVrcSource.cpp
80af5a
e985b4 del ..\Release\PGPdisk.vrc
419495 move PGPdiskVrcSource.i ..\Release\PGPdisk.vrc
3eaf5a
cb5fec cd ..\Release
4aaf5a
6c0597 %VTOOLSD%\bin\vxdver PGPdisk.vrc PGPdisk.res
fff3d0 %VTOOLSD%\bin\sethdr -r PGPdisk.res PGPdisk.pdr
e5af5a
4c29f0 cd ..\Source
36af5a
a788d6 del pgpBinaryTree.c
127c38 del pgpDebug.c
f6394c del pgpLeaks.c
d9bc3b del pgpMem.c
d23d2f del pgpMemoryMgr.c
ff41a2 del pgpMemoryMgrMac.c
6eff85 del pgpMemoryMgrStd.c
1ad8fe del pgpMemoryMgrWin32.c
c48cab del pgpRMWOLock.c
037c18 del pgpTemplate.c
c5af5a
735418 del CommonStrings.cpp
4d75ef del DriverComm.cpp
f1f0c1 del DualErr.cpp
5e7895 del Errors.cpp
688b2f del FatUtils.cpp
9fb014 del LinkResolution.cpp
6fa985 del PGPdiskContainer.cpp
fcc1c4 del PGPdiskHighLevelUtils.cpp
5079d4 del PGPdiskLowLevelUtils.cpp
f6b9e7 del PGPdiskPfl.cpp
f10558 del PGPdiskPublicKeyUtils.cpp
e9ad2d del PGPdiskRegistry.cpp
cb3703 del SecureMemory.cpp
bdfaa2 del SecureString.cpp
26e6a0 del SharedMemory.cpp
d1a46b del StringAssociation.cpp
e7f073 del WaitObjectClasses.cpp
511620 del Win32Utils.cpp
8ca97e del WindowsVersion.cpp
6aaf5a
7ff576 del Cast5.cpp
8b870b del Cast5Box.cpp
5eb889 del CipherContext.cpp
e1c297 del CipherUtils.cpp
d5a92b del PGPdiskRandomPool.cpp
1f47a0 del SHA.cpp
--6ec1 001f8170c1340110110 Page 1 of Crtdbg.h
541bc3 //////////////////////////////////////////////////////////////////////////////
e1c5f3 // Crtdbg.h
1f465d //
a27822 // A fake source file designed to pacify the PFL.
da1bc3 //////////////////////////////////////////////////////////////////////////////
72af5a
90c0f6 // $Id: Crtdbg.h,v 1.1.2.2 1998/05/08 18:30:05 nryan Exp $
7faf5a
0ecbce // Copyright (C) 1998 by Network Associates, Inc.
4f71ae // All rights reserved.
cfaf5a
2e97a3 #ifndef Included_Crtdbg_h¤  // [
1edc10 #define Included_Crtdbg_h
eeaf5a
64e976 // Don't include both vtoolscp and vtoolsc.
53ed14 #ifndef __vtoolscp_h_
08c217 #include <vtoolsc.h>
9ab724 #endif¤ // __vtoolscp_h_
81af5a
a586d2 #include LOCKED_CODE_SEGMENT
ac5269 #include LOCKED_DATA_SEGMENT
d1af5a
f8be6c #endif¤ // ] Included_Crtdbg_h
--87b4 00154aae56a40110111 Page 1 of Limits.h
541bc3 //////////////////////////////////////////////////////////////////////////////
615075 // Limits.h
e3465d //
327822 // A fake source file designed to pacify the PFL.
6b1bc3 //////////////////////////////////////////////////////////////////////////////
0daf5a
eb76c7 // $Id: Limits.h,v 1.1.2.2 1998/05/08 18:30:07 nryan Exp $
fbaf5a
cfcbce // Copyright (C) 1998 by Network Associates, Inc.
de71ae // All rights reserved.
d6af5a
f71ae6 #ifndef Included_Limits_h¤  // [
e54996 #define Included_Limits_h
eeaf5a
54e976 // Don't include both vtoolscp and vtoolsc.
9aed14 #ifndef __vtoolscp_h_
27c217 #include <vtoolsc.h>
61b724 #endif¤ // __vtoolscp_h_
dbaf5a
2a86d2 #include LOCKED_CODE_SEGMENT
3a5269 #include LOCKED_DATA_SEGMENT
d2af5a
542bea #endif¤ // ] Included_Limits_h
--9f42 00173727ab540110112 Page 1 of Stdarg.h
541bc3 //////////////////////////////////////////////////////////////////////////////
dc32d8 // Stdarg.h
ea465d //
b47822 // A fake source file designed to pacify the PFL.
c71bc3 //////////////////////////////////////////////////////////////////////////////
c1af5a
315c8f // $Id: Stdarg.h,v 1.1.2.2 1998/05/08 18:30:09 nryan Exp $
d0af5a
7ecbce // Copyright (C) 1998 by Network Associates, Inc.
2971ae // All rights reserved.
f3af5a
2d5ed0 #ifndef Included_Stdarg_h¤  // [
ce2b3b #define Included_Stdarg_h
86af5a
28e976 // Don't include both vtoolscp and vtoolsc.
cded14 #ifndef __vtoolscp_h_
9ac217 #include <vtoolsc.h>
11b724 #endif¤ // __vtoolscp_h_
e5af5a
0786d2 #include LOCKED_CODE_SEGMENT
405269 #include LOCKED_DATA_SEGMENT
06af5a
734947 #endif¤ // ] Included_Stdarg_h
--7961 00168cea61d40110113 Page 1 of Stddef.h
541bc3 //////////////////////////////////////////////////////////////////////////////
e6be78 // Stddef.h
70465d //
e37822 // A fake source file designed to pacify the PFL.
5e1bc3 //////////////////////////////////////////////////////////////////////////////
72af5a
857eee // $Id: Stddef.h,v 1.1.2.2 1998/05/08 18:30:11 nryan Exp $
d5af5a
e7cbce // Copyright (C) 1998 by Network Associates, Inc.
0e71ae // All rights reserved.
feaf5a
8b8f18 #ifndef Included_Stddef_h¤  // [
40a79b #define Included_Stddef_h
5daf5a
c3e976 // Don't include both vtoolscp and vtoolsc.
afed14 #ifndef __vtoolscp_h_
a3c217 #include <vtoolsc.h>
53b724 #endif¤ // __vtoolscp_h_
4baf5a
8286d2 #include LOCKED_CODE_SEGMENT
965269 #include LOCKED_DATA_SEGMENT
daaf5a
68c5e7 #endif¤ // ] Included_Stddef_h
--f0c2 001385fb2c440110114 Page 1 of Stdlib.h
541bc3 //////////////////////////////////////////////////////////////////////////////
409afc // Stdlib.h
68465d //
b67822 // A fake source file designed to pacify the PFL.
e41bc3 //////////////////////////////////////////////////////////////////////////////
aaaf5a
3e8af1 // $Id: Stdlib.h,v 1.1.2.2 1998/05/08 18:30:14 nryan Exp $
0caf5a
7ccbce // Copyright (C) 1998 by Network Associates, Inc.
7671ae // All rights reserved.
94af5a
4af3bf #ifndef Included_Stdlib_h¤  // [
b8831f #define Included_Stdlib_h
e7af5a
bfe976 // Don't include both vtoolscp and vtoolsc.
36ed14 #ifndef __vtoolscp_h_
a8c217 #include <vtoolsc.h>
2bb724 #endif¤ // __vtoolscp_h_
a6af5a
de86d2 #include LOCKED_CODE_SEGMENT
c05269 #include LOCKED_DATA_SEGMENT
b7af5a
38e163 #endif¤ // ] Included_Stdlib_h
--84c2 0017e57a73d40110115 Page 1 of String.h
541bc3 //////////////////////////////////////////////////////////////////////////////
913df4 // String.h
50465d //
3c7822 // A fake source file designed to pacify the PFL.
171bc3 //////////////////////////////////////////////////////////////////////////////
b6af5a
7f2fd6 // $Id: String.h,v 1.1.2.2 1998/05/08 18:30:18 nryan Exp $
43af5a
a8cbce // Copyright (C) 1998 by Network Associates, Inc.
5471ae // All rights reserved.
bbaf5a
c6b140 #ifndef Included_String_h¤  // [
602417 #define Included_String_h
2aaf5a
d5e976 // Don't include both vtoolscp and vtoolsc.
14ed14 #ifndef __vtoolscp_h_
e8c217 #include <vtoolsc.h>
42b724 #endif¤ // __vtoolscp_h_
3daf5a
46dce7 // Get rid of certain harmless warnings.
5ae900 #pragma warning(disable: 4013 4022 4090)
78af5a
ae86d2 #include LOCKED_CODE_SEGMENT
1e5269 #include LOCKED_DATA_SEGMENT
b2af5a
7e466b #endif¤ // ] Included_String_h
--8365 001cf4b7d2940110116 Page 1 of Types.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d45a35 // Types.h
03465d //
947822 // A fake source file designed to pacify the PFL.
441bc3 //////////////////////////////////////////////////////////////////////////////
14af5a
92d6c1 // $Id: Types.h,v 1.1.2.2 1998/05/08 18:30:21 nryan Exp $
54af5a
f3cbce // Copyright (C) 1998 by Network Associates, Inc.
c771ae // All rights reserved.
0daf5a
e8412d #ifndef Included_Types_h¤   // [
c043a4 #define Included_Types_h
15af5a
efe976 // Don't include both vtoolscp and vtoolsc.
18ed14 #ifndef __vtoolscp_h_
8ec217 #include <vtoolsc.h>
64b724 #endif¤ // __vtoolscp_h_
1aaf5a
6686d2 #include LOCKED_CODE_SEGMENT
7d5269 #include LOCKED_DATA_SEGMENT
f1af5a
cf31d5 #endif¤ // ] Included_Types_h
--3dd8 000e409796b40110117 Page 1 of CPGPdiskDrv.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
86dace // CPGPdiskDrv.cpp
32465d //
4f34e3 // Holds the entrance and exit routines for the driver.
601bc3 //////////////////////////////////////////////////////////////////////////////
b9af5a
736441 // $Id: CPGPdiskDrv.cpp,v 1.1.2.24.2.1 1998/09/01 00:31:43 nryan Exp $
9aaf5a
85cbce // Copyright (C) 1998 by Network Associates, Inc.
4071ae // All rights reserved.
c9af5a
8f9391 #define¤DEVICE_MAIN
7706a9 #include <vtoolscp.h>
0eaf5a
409bcf #include "Required.h"
945788 #include "PGPdiskVersion.h"
58bfe9 #include "UtilityFunctions.h"
ecaf5a
af9de2 #include "CPGPdiskDrv.h"
49c411 #include "Globals.h"
2b8b8d #undef DEVICE_MAIN
1aaf5a
a8c3c4 // Declare_Port_Driver is a VToolsD macro that sets up our DRP (driver
933593 // registration packet) for use in registering with the IOS.
4faf5a
3e27b4 Declare_Port_Driver(PGPDISK, DRP_MISC_PD, PGPDISK_NAME, PGPDISK_REV,·
f5f0a4 ¤   PGPDISK_FEATURE, PGPDISK_IFR, DRP_BT_ESDI, 0)
97af5a
c0af5a
c4fcb8 //////////////////////////////////
2ca58c // Global variables for the driver
e6fcb8 //////////////////////////////////
7eaf5a
736d79 CPGPdiskDrv *Driver;¤   ¤   ¤   ¤   // pointer to the driver object
4caf5a
0eaf5a
0938fb //////////////////////////////////////////////////////////////
19a9c5 // Initialization and cleanup routines for class PGPdiskDevice
5d38fb //////////////////////////////////////////////////////////////
dfaf5a
62f0f7 // ClearVariables initializes many variables to default values.
9eaf5a
d5c823 void·
c48fbc CPGPdiskDrv::ClearVariables()
0ebb36 {
4c51fc ¤   PGPUInt32 i;
58af5a
1b40a9 ¤   Driver = this;
a1af5a
06ddad ¤   mTheDDB = NULL;
06af5a
f5f15d ¤   mSecondsInactive = 0;
61a81d ¤   mPGPdiskAppVersion¤ = 0;
0daf5a
51e4d6 ¤   for (i=0; i<kMaxDrives; i++)
78ad00 ¤   ¤   mIsEjectHooked[i] = FALSE;
deaf5a
6375b3 ¤   mBroadcastHookHandle = FALSE;
ee5eb4 ¤   mUnmountAllMode = FALSE;
1eaf5a
ef946a ¤   mHookedVKD = mHookedVMD = mHookedSystemBroadcast = FALSE;
a2af5a
ad76c6 ¤   mLockInProgress = FALSE;
500584 ¤   mDriveBeingLocked = kInvalidDrive;
afaf5a
34a51b ¤   mAutoUnmount = kDefaultAutoUnmount;
cd59a6 ¤   mUnmountTimeout = kDefaultUnmountTimeout;
cdaf5a
ff75c4 ¤   for (i=0; i<kNumErrPackets; i++)
0ac7a1 ¤   {
11d4ef ¤   ¤   mErrPackets[i].isInUse¤ ¤   = FALSE;
e44986 ¤   ¤   mErrPackets[i].perr¤¤   ¤   = kPGDMajorError_NoErr;
--9ff1 0011c7de65d40110117 Page 2 of CPGPdiskDrv.cpp
09d7c4 ¤   ¤   mErrPackets[i].drive¤   ¤   = kInvalidDrive;
89c8b3 ¤   ¤   mErrPackets[i].errString¤   = NULL;
0d9371 ¤   }
25af5a
32ff49 ¤   mIsErrorCallbackBusy = FALSE;
abefe6 }
e1af5a
c6deba // OnSysDynamicDeviceInit is called when the driver is being loaded. We
fdc645 // register with the IOS subsystem and remain resident if everything went OK.
f3af5a
4a7efe BOOL·
40383f CPGPdiskDrv::OnSysDynamicDeviceInit()
f8bb36 {
2441a7 ¤   DebugOut("PGPdisk Port Driver v%s loaded.", kVersionTextString);
50c30a ¤   DebugOut("Copyright (C) 1998 Network Associates, Inc.\n");
dfaf5a
bf4550 ¤   // Init variables.
8ab1af ¤   ClearVariables();
96af5a
e1241a ¤   // Register with the IOS.
2e82e5 ¤   PGPDISK_Drp.DRP_feature_code |= DRP_FC_1_SEC;
6782a5 ¤   ::IOS_Register(&PGPDISK_Drp);
baaf5a
2bdf7a ¤   if (PGPDISK_Drp.DRP_reg_result != DRP_REMAIN_RESIDENT)
b66a2f ¤   ¤   mInitErr = DualErr(kPGDMinorError_IosRegistrationFailed);
20af5a
65c2e7 ¤   return TRUE;
05efe6 }
6daf5a
934b1c // OnInitComplete is called after all devices have initialized. We perform
f7b481 // additional initialization.
f0af5a
a17efe BOOL·
f43258 CPGPdiskDrv::OnInitComplete(VMHANDLE hVM, PCHAR CommandTail)
9fbb36 {
cbf2d6 ¤   // Install our system hooks.
697404 ¤   SetupSystemHooks();
a6af5a
04c2e7 ¤   return TRUE;
6eefe6 }
12af5a
6da757 // OnSysDynamicDeviceExit is called when the driver is about to be unloaded,
2d4db3 // which only occurs on system shutdown since we are a port driver.
63af5a
207efe BOOL·
17d3ef CPGPdiskDrv::OnSysDynamicDeviceExit()
4ebb36 {
ffb7e7 ¤   DebugOut("PGPdisk Driver v%s unloading.\n", kVersionTextString);
78af5a
3a8604 ¤   // Cleanup.
63f4c8 ¤   RemoveSystemHooks();
18af5a
f8c2e7 ¤   return TRUE;
89efe6 }
cfaf5a
c2e6e7 // OnSystemExit is called right before the system shuts down. Unmount all
c703cb // PGPdisks at this point.
a7af5a
dba1ba VOID·
42ea5b CPGPdiskDrv::OnSystemExit(VMHANDLE hVM)
71bb36 {
867cb9 ¤   UnmountAllPGPdisks();
1cefe6 }
--d7b2 0001cb24c9440110118 Page 1 of CPGPdiskDrv.h
541bc3 //////////////////////////////////////////////////////////////////////////////
2b3c07 // CPGPdiskDrv.h
44465d //
f0b95f // Declaration of class CPGPdiskDrv.
3a1bc3 //////////////////////////////////////////////////////////////////////////////
b9af5a
f8a38f // $Id: CPGPdiskDrv.h,v 1.3.2.34.2.1 1998/09/01 00:31:44 nryan Exp $
93af5a
d5cbce // Copyright (C) 1998 by Network Associates, Inc.
6771ae // All rights reserved.
aaaf5a
6a2542 #ifndef Included_CPGPdiskDrv_h¤ // [
dbe32d #define Included_CPGPdiskDrv_h
37af5a
813a85 #include "DualErr.h"
a30092 #include "Packets.h"
d75f98 #include "PGPdiskContainer.h"
3f4e67 #include "SimpleQueue.h"
2aaf5a
2ba64e #include "CPGPdiskDrvComm.h"
dae43f #include "CPGPdiskDrvDebug.h"
c6c18e #include "CPGPdiskDrvErrors.h"
a94ece #include "CPGPdiskDrvHooks.h"
86d539 #include "CPGPdiskDrvWinutils.h"
c03c19 #include "DcbManager.h"
b1c2bc #include "IopProcessor.h"
7168c6 #include "PGPdisk.h"
d23552 #include "Wrappers.h"
91af5a
6baf5a
ed09b7 ////////////
47e738 // Constants
1d09b7 ////////////
f1af5a
8ad671 // VToolsD-required device driver constants.
3caf5a
ccccc8 #define¤DEVICE_CLASS¤   ¤   CPGPdiskDrv
a07596 #define¤PGPDISK_DeviceID¤   UNDEFINED_DEVICE_ID¤
f73ad7 #define¤PGPDISK_Init_Order¤ UNDEFINED_INIT_ORDER
52812d #define¤PGPDISK_Major¤  ¤   1
e6b0eb #define¤PGPDISK_Minor¤  ¤   0
9c0749 #define¤PGPDISK_NAME¤   ¤   "PGPDISK ·······"
0075c0 #define¤PGPDISK_REV¤¤   ¤   1
fb6b95 #define¤PGPDISK_FEATURE¤¤   0
39dd13 #define¤PGPDISK_IFR¤¤   ¤   0
c6af5a
46af5a
872af8 //////////
974f83 // Classes
482af8 //////////
48af5a
47a3ff // There is only one CPGPdiskDrv object, and it represents the driver itself.
d1af5a
514703 class CPGPdiskDrv : public VDevice
48bb36 {
af5ed4 public:
24fb17 ¤   DualErr¤¤   ¤   ¤   mInitErr;
91af5a
7f9316 ¤   DcbManager¤ ¤   ¤   mDcbs;¤ ¤   ¤   ¤   // container for driver's DCBs
e66db1 ¤   IopProcessor¤   ¤   mIopProcessor;¤ ¤   // processes IOPs
519fdf ¤   PGPdiskContainer¤   mPGPdisks;¤ ¤   ¤   // container for PGPdisks
93af5a
4a5e42 ¤   PGPUInt32¤  ¤   ¤   mSecondsInactive;¤  // # seconds PC inactive
9baf5a
2ae86c ¤   // From CPGPdiskDrvDebug.cpp
e2af5a
bcb808 ¤   LPCSTR¤ ¤   ¤   ¤   GetName(NameAssoc nameTable[], PGPUInt32 n,·
9349bf ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 func);
8a763c ¤   LPCSTR¤ ¤   ¤   ¤   GetADPacketName(PGPUInt32 code);
0459b0 ¤   LPCSTR¤ ¤   ¤   ¤   GetAEPFunctionName(PGPUInt32 func);
de8514 ¤   LPCSTR¤ ¤   ¤   ¤   GetIORFunctionName(PGPUInt32 func);
1caf5a
--0e8d 00072a8f16140110118 Page 2 of CPGPdiskDrv.h
696165 ¤   // From CPGPdiskDrvIos.cpp
08af5a
5e3f97 ¤   static VOID __cdecl¤PGPDISK_Aer(PAEP pAep);
09af5a
49a18b ¤   // From CPGPdiskDrvErrors.cpp
ddaf5a
b96d61 ¤   void¤   ¤   ¤   ¤   ReportError(PGDMajorError perr,·
864bb6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DualErr derr = DualErr::NoError,·
e961ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive);
53af5a
50adce ¤   // From CPGPdiskDrvVolumes.cpp
c4af5a
55ec9d ¤   DualErr¤¤   ¤   ¤   MountPGPdisk(LPCSTR path, CipherContext *context,·
da7d7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive,·
b55b8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly = FALSE);
d17b42 ¤   DualErr¤¤   ¤   ¤   UnmountPGPdisk(PGPUInt8 drive,·
c34561 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean isThisEmergency = FALSE);
29908b ¤   DualErr¤¤   ¤   ¤   UnmountAllPGPdisks(
124561 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean isThisEmergency = FALSE);
4df8ec ¤   void¤   ¤   ¤   ¤   UnmountAllPGPdisksSafely(
0fa08f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean warnIfUnmountsFail = FALSE);
dcaf5a
5f500b ¤   // From CPGPdiskDrvWinutils.cpp
74af5a
96bf77 ¤   PGPBoolean¤ ¤   ¤   DoWinInt(PGPUInt8 interrupt, ALLREGS *pAllRegs);
43af5a
e94176 ¤   LockLevel¤  ¤   ¤   GetLockLevel(PGPUInt8 drive);
3e63ec ¤   DualErr¤¤   ¤   ¤   AcquireLogicalVolLock(PGPUInt8 drive,·
577951 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LockLevel lock, PGPUInt8 permissions = 0x01);
d1d5e3 ¤   DualErr¤¤   ¤   ¤   GetFormatLockOnDrive(PGPUInt8 drive);
ee4018 ¤   DualErr¤¤   ¤   ¤   ReleaseFormatLockOnDrive(PGPUInt8 drive);
f3af5a
5f848e ¤   PGPBoolean¤ ¤   ¤   IsFileInUseByReader(LPCSTR path);
75b3ec ¤   PGPBoolean¤ ¤   ¤   IsFileInUseByWriter(LPCSTR path);
ed82d7 ¤   PGPBoolean¤ ¤   ¤   IsFileInUse(LPCSTR path);
00b143 ¤   PGPBoolean¤ ¤   ¤   IsFileValid(LPCSTR path);
b2af5a
f551b1 ¤   DualErr¤¤   ¤   ¤   GetFirstClustFile(LPCSTR path, PGPUInt32 *firstClust);
46d124 ¤   DualErr¤¤   ¤   ¤   HasOpenFiles(PGPUInt8 drive,·
d08405 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean *hasOpenFiles);
c6af5a
cad52d ¤   DualErr¤¤   ¤   ¤   Int21OpenFile(LPCSTR path, PGPUInt16 mode,·
d98e33 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt16 attribs, PGPUInt16 action,·
813b7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt16 *pHandle);
d23dca ¤   DualErr¤¤   ¤   ¤   Int21CloseFile(PGPUInt16 handle);
9caf5a
f2485f ¤   DualErr¤¤   ¤   ¤   Int21GetFileLength(PGPUInt16 handle,·
f690b7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 *pLength);
a2080b ¤   DualErr¤¤   ¤   ¤   Int21SetFilePos(PGPUInt16 handle, PGPUInt32 pos);
3aaf5a
7a9cf7 ¤   DualErr¤¤   ¤   ¤   Int21ReadFileAux(PGPUInt16 handle, PGPUInt8 *buf,·
894c03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt16 nBytes);
31b3ac ¤   DualErr¤¤   ¤   ¤   Int21WriteFileAux(PGPUInt16 handle, PGPUInt8 *buf,·
d74c03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt16 nBytes);
7eaf5a
6872be ¤   DualErr¤¤   ¤   ¤   Int21ReadFile(PGPUInt16 handle, PGPUInt8 *buf,·
70209f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 pos, PGPUInt32 nBytes);
7392b6 ¤   DualErr¤¤   ¤   ¤   Int21WriteFile(PGPUInt16 handle, PGPUInt8 *buf,·
7b209f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 pos, PGPUInt32 nBytes);
79af5a
a2e956 ¤   DualErr¤¤   ¤   ¤   LockUserBuffer(void *pMem, PGPUInt32 nBytes);
32000d ¤   DualErr¤¤   ¤   ¤   UnlockUserBuffer(void *pMem, PGPUInt32 nBytes);
8aaf5a
ea0fb9 private:
8f2413 ¤   PDDB¤   ¤   ¤   ¤   ¤   mTheDDB;¤   ¤   ¤   ¤   // the driver's DDB
f2af5a
26e989 ¤   PGPUInt32¤  ¤   ¤   ¤   mPGPdiskAppVersion;¤¤   // application version
36af5a
cdeb61 ¤   DeviceService_THUNK¤¤   mKeyboard_Thunk;¤   ¤   // keyboard hook thunk
9e3f9a ¤   DeviceService_THUNK¤¤   mMouse_Thunk;¤  ¤   ¤   // mouse hook thunk
25af5a
72819d ¤   PGPBoolean¤ ¤   ¤   ¤   mIsEjectHooked[kMaxDrives];¤¤   // hooked whom?
--8c53 00093bea1e940110118 Page 3 of CPGPdiskDrv.h
34a117 ¤   SYSBHOOK_HANDLE¤¤   ¤   mBroadcastHookHandle;¤  // handle for msg hook
65af5a
1b74e9 ¤   PGPBoolean¤ ¤   ¤   ¤   mUnmountAllMode;¤   ¤   // unmount all per sec
caaf5a
a2575b ¤   PGPBoolean¤ ¤   ¤   ¤   mHookedVKD;¤¤   ¤   ¤   // hooked VKD?
cb925b ¤   PGPBoolean¤ ¤   ¤   ¤   mHookedVMD;¤¤   ¤   ¤   // hooked VMD?
8f7a4b ¤   PGPBoolean¤ ¤   ¤   ¤   mHookedSystemBroadcast;¤// hooked sysbroadcast?
91af5a
f59423 ¤   PGPBoolean¤ ¤   ¤   ¤   mLockInProgress;¤   ¤   // next lock is ours
66043c ¤   PGPUInt8¤   ¤   ¤   ¤   mDriveBeingLocked;¤ ¤   // drive we're locking
85af5a
96c79f ¤   PGPBoolean¤ ¤   ¤   ¤   mAutoUnmount;¤  ¤   ¤   // auto-unmount enabled?
bc5695 ¤   PGPUInt32¤  ¤   ¤   ¤   mUnmountTimeout;¤   ¤   // unmount timeout in mins
f5af5a
1bd455 ¤   ErrorCell¤  ¤   ¤   ¤   mErrPackets[kNumErrPackets];¤   // error packets
9761c2 ¤   PGPBoolean¤ ¤   ¤   ¤   mIsErrorCallbackBusy;¤  // callback busy?
47c891 ¤   SimpleQueue¤¤   ¤   ¤   mErrorQueue;¤   ¤   ¤   // queue for errors
d1af5a
351a36 ¤   // From CPGPdiskDrv.cpp
0faf5a
b64ec9 ¤   void¤   ¤   ¤   ¤   ¤   ClearVariables();
ccaf5a
a474e4 ¤   BOOL¤   ¤   ¤   ¤   ¤   OnSysDynamicDeviceInit();
7c42ea ¤   BOOL¤   ¤   ¤   ¤   ¤   OnInitComplete(VMHANDLE hVM, PCHAR CommandTail);
eba282 ¤   BOOL¤   ¤   ¤   ¤   ¤   OnSysDynamicDeviceExit();
76441b ¤   VOID¤   ¤   ¤   ¤   ¤   OnSystemExit(VMHANDLE hVM);
eaaf5a
3f146a ¤   // From CPGPdiskDrvComm.cpp
59af5a
93488b ¤   DualErr¤¤   ¤   ¤   ¤   ProcessMount(PAD_Mount pMNT,·
faffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
482331 ¤   DualErr¤¤   ¤   ¤   ¤   ProcessUnmount(PAD_Unmount pUNMNT,·
a9ffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
191236 ¤   DualErr¤¤   ¤   ¤   ¤   ProcessQueryVersion(PAD_QueryVersion pQV,·
95ffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
49a12f ¤   DualErr¤¤   ¤   ¤   ¤   ProcessQueryMounted(PAD_QueryMounted pQM,·
98ffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
3f2964 ¤   DualErr¤¤   ¤   ¤   ¤   ProcessQueryOpenFiles(PAD_QueryOpenFiles pQOF,·
abffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
b5642f ¤   DualErr¤¤   ¤   ¤   ¤   ProcessChangePrefs(PAD_ChangePrefs pCP,·
acffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
8fc10e ¤   DualErr¤¤   ¤   ¤   ¤   ProcessLockUnlockMem(PAD_LockUnlockMem pLUM,·
d7ffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
94cc56 ¤   DualErr¤¤   ¤   ¤   ¤   ProcessGetPGPdiskInfo(PAD_GetPGPdiskInfo pGPI,·
28ffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
0a12dd ¤   DualErr¤¤   ¤   ¤   ¤   ProcessLockUnlockVol(PAD_LockUnlockVol pLUV,·
9effc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
64aa32 ¤   DualErr¤¤   ¤   ¤   ¤   ProcessReadWriteVol(PAD_ReadWriteVol pRWV,·
8effc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
1ad1ec ¤   DualErr¤¤   ¤   ¤   ¤   ProcessQueryVolInfo(PAD_QueryVolInfo pQVI,·
8cffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
10af5a
c0c451 ¤   DualErr¤¤   ¤   ¤   ¤   ProcessNotifyUserLogoff(
39c567 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PAD_NotifyUserLogoff pNUL, PGPUInt32 size);
3faf5a
9107b4 ¤   PGPUInt32¤  ¤   ¤   ¤   ProcessADPacket(PADPacketHeader pPacket,·
86ffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 size);
85d2e7 ¤   virtual DWORD¤  ¤   ¤   OnW32DeviceIoControl(PIOCTLPARAMS p);
90af5a
53a18b ¤   // From CPGPdiskDrvErrors.cpp
1faf5a
b812d3 ¤   static VOID __stdcall¤  ReportErrorEndCallback(DWORD ResponseCode,·
fb18a4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PVOID Refdata);
d9c533 ¤   static VOID __stdcall¤  ReportErrorStartCallback(VMHANDLE hVM,·
53f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
556ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
6daf5a
f5aa9e ¤   void¤   ¤   ¤   ¤   ¤   ScheduleErrorCallback();
13af5a
4c0ec0 ¤   // From CPGPdiskDrvHooks.cpp
34af5a
93a606 ¤   static ·int _cdecl¤ ¤   FilesystemHook(pIFSFunc pfn, int func, int drive,·
--8313 000f878e15740110118 Page 4 of CPGPdiskDrv.h
d61fdf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   int resType, int codePage, pioreq pir);
66af5a
7e5177 ¤   static BOOL __cdecl¤¤   BroadcastMessageHook(DWORD uMsg, DWORD wParam,·
59bda8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DWORD lParam, DWORD dwRef);
1faf5a
61b59f ¤   void¤   ¤   ¤   ¤   ¤   ScheduleTryToUnmountCallback(
f63b3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean delayExecution = FALSE);
ebaf5a
9fce2c ¤   static VOID __stdcall¤  KeepTryingToUnmountCallbackStub(VMHANDLE hVM,·
cf4fbd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pcrs, PVOID RefData,·
3ed91e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DWORD extra);
97af5a
46473c ¤   static VOID __stdcall¤  KeepTryingToUnmountCallback(VMHANDLE hVM,·
26f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
696ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
5faf5a
2ee438 ¤   static VOID __stdcall¤  KeyboardHook(PDSFRAME regs);
d87291 ¤   static VOID __stdcall¤  MouseHook(PDSFRAME regs);
82af5a
f619ce ¤   DualErr¤¤   ¤   ¤   ¤   HookEjectionFilter(PGPUInt8 drive);
3da76c ¤   static VOID __cdecl¤¤   PGPDISK_EjectHandlerStub(PIOP pIop);
db7ee5 ¤   static VOID¤¤   ¤   ¤   PGPDISK_EjectHandler(PIOP pIop);
8190b3 ¤   static VOID __stdcall¤  SetupSystemHooksCallback(VMHANDLE hVM,·
32f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
a06ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
a84af9 ¤   void¤   ¤   ¤   ¤   ¤   SetupSystemHooks();
3dd89c ¤   void¤   ¤   ¤   ¤   ¤   RemoveSystemHooks();
05af5a
136165 ¤   // From CPGPdiskDrvIos.cpp
3caf5a
a8aaec ¤   PGPUInt16¤  ¤   ¤   ¤   AepInitialize(PAEP_bi_init pAep);
7307b1 ¤   PGPUInt16¤  ¤   ¤   ¤   AepDeviceInquiry(PAEP_inquiry_device pAEP);
78d5d7 ¤   PGPUInt16¤  ¤   ¤   ¤   AepConfigDcb(PAEP_dcb_config pAep);
e5c9fb ¤   PGPUInt16¤  ¤   ¤   ¤   AepIopTimeout(PAEP_iop_timeout_occurred pAep);
e0e921 ¤   static VOID __stdcall¤  AepOneSecondCallback(VMHANDLE hVM,·
53f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
826ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
39a36b ¤   PGPUInt16¤  ¤   ¤   ¤   AepOneSecond();
1faf5a
db236f ¤   static VOID __cdecl¤¤   PGPDISK_RequestHandlerStub(PIOP pIop);
b56657 ¤   static void¤¤   ¤   ¤   PGPDISK_RequestHandler(PIOP pIop);
55af5a
c0adce ¤   // From CPGPdiskDrvVolumes.cpp
a1af5a
6c4910 ¤   static VOID __stdcall¤  UnmountAllPGPdisksCallback(VMHANDLE hVM,·
a3f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
346ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
fc82f7 };
faaf5a
e1af5a
34d43e /////////
bb596b // Macros
58d43e /////////
1faf5a
b7f9cb // It was necessary to rewrite some of the VToolsD included macros, which
81e26c // wouldn't work properly with port drivers.
90af5a
1e76af // Declare_Virtual_Device_Ex is a utility function for Declare_Port_Driver.
7daf5a
f298fc #define Declare_Virtual_Device_Ex(devName, RefData) extern "C" VDevice* \
de799d ¤   __cdecl _CreateDevice(); \
ee764b ¤   extern "C" VOID __stdcall v86_api_entry();¤ ··············\
737e56 ¤   extern "C" VOID __stdcall pm_api_entry();¤  ¤   ······\
c9b63e ¤   extern "C" VOID __stdcall localControlDispatcher();¤ ·····\
3c87c8 ¤   extern "C" DDB The_DDB;¤¤   ¤   ¤   ¤   ······\
95b79b ¤   extern "C" void (*VXD_SERVICE_TABLE[])(); ¤ ¤   ······\
0878d6 ¤   DDB The_DDB = {¤¤   ······¤ ······¤ ¤   ¤   ······\
8f34af ¤   ¤   0,¤ ¤   ¤   ¤   ¤   ¤   ······\
0badee ¤   ¤   DDK_VERSION,¤   ¤   ¤   ¤   ¤   ······\
02ba0d ¤   ¤   devName##_DeviceID,¤¤   ¤   ¤   ······\
25ca5c ¤   ¤   devName##_Major,¤   ¤   ¤   ¤   ······\
f81be8 ¤   ¤   devName##_Minor,¤   ¤   ¤   ¤   ······\
--fb79 001154c8e8840110118 Page 5 of CPGPdiskDrv.h
ed34af ¤   ¤   0,¤ ¤   ¤   ¤   ¤   ¤   ······\
9ce96b ¤   ¤   {' ',' ',' ',' ',' ',' ',' ',' '},¤ ¤   ······\
aa95aa ¤   ¤   devName##_Init_Order,¤  ¤   ¤   ¤   ······\
80f61d ¤   ¤   (PGPUInt32)localControlDispatcher,¤ ¤   ¤   ······\
aa94c2 ¤   ¤   (PGPUInt32)v86_api_entry,¤  ······¤ ¤   ¤   ······\
a97356 ¤   ¤   (PGPUInt32)pm_api_entry,¤   ¤   ¤   ¤   ······\
d1e41d ¤   ¤   0,0,RefData,¤   ¤   ·¤  ·¤  ¤   ¤   ······\
308b2f ¤   ¤   (PGPUInt32)VXD_SERVICE_TABLE,¤  ¤   ¤   ······\
ae1be0 ¤   ¤   0,¤ ¤   ¤   ¤   ¤   ······¤ ······\
f71be0 ¤   ¤   0,¤ ¤   ¤   ¤   ¤   ······¤ ······\
ad7610 ¤   ¤   __SIG__,¤   ¤   ¤   ¤   ······¤ ······\
8c542b ¤   };¤ ¤   ¤   ¤   ¤   ¤   ¤   ······\
4c5874 ¤   VDevice* __cdecl _CreateDevice()¤   ¤   ¤   ······\
677bf7 ¤   {¤  ¤   ¤   ¤   ¤   ¤   ¤   ······\
48ab93 ¤   ¤   return (VDevice*)new DEVICE_CLASS;¤ ¤   ······\
1d9371 ¤   }
57af5a
6fda23 // Declare_Port_Driver defines many important system-required fields for the
95b3bd // driver.
99af5a
150b77 #define Declare_Port_Driver(VName, _lgn, _asc, _rev, _fc, _ifr, _bt, _rd) \
7a7cb0 ¤   VOID __cdecl VName##_Aer(AEP*);¤\
b8fde6 ¤   ILB VName##_Ilb;¤   \
4cdb6b ¤   DRP VName##_Drp={ ··\
f6499a ¤   ¤   {'X','X','X','X','X','X','X','X'}, \
152cae ¤   ¤   _lgn, \
96bbe8 ¤   ¤   Driver->VName##_Aer, \
3687ce ¤   ¤   &VName##_Ilb, \
6d2c89 ¤   ¤   _asc, \
59f970 ¤   ¤   _rev, \
4d90b7 ¤   ¤   _fc, ·\
681b56 ¤   ¤   _ifr, \
4ea1a0 ¤   ¤   _bt, ·\
1c12ee ¤   ¤   0, ···\
792e37 ¤   ¤   _rd}; \
370fe7 ¤   Declare_Virtual_Device_Ex(VName, (PGPUInt32)&VName##_Drp)
97af5a
15217c #endif¤ // ] Included_CPGPdiskDrv_h
--7a6f 000a6c488e440110119 Page 1 of CPGPdiskDrvComm.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
5c8c03 // CPGPdiskDrvComm.cpp
59465d //
a09634 // Functions for driver/application communication.
711bc3 //////////////////////////////////////////////////////////////////////////////
47af5a
598a82 // $Id: CPGPdiskDrvComm.cpp,v 1.1.2.28 1998/07/06 08:58:04 nryan Exp $
66af5a
12cbce // Copyright (C) 1998 by Network Associates, Inc.
1e71ae // All rights reserved.
5caf5a
0006a9 #include <vtoolscp.h>
16af5a
ca9bcf #include "Required.h"
625788 #include "PGPdiskVersion.h"
f7bfe9 #include "UtilityFunctions.h"
8daf5a
5ea64e #include "CPGPdiskDrvComm.h"
f5c411 #include "Globals.h"
75af5a
bc86d2 #include LOCKED_CODE_SEGMENT
b95269 #include LOCKED_DATA_SEGMENT
5caf5a
88af5a
98b474 //////////////////////////////
4ee95e // Packet processing functions
96b474 //////////////////////////////
11af5a
e6aaae // ProcessMount processes a kAD_Mount request.
c0af5a
5e2292 DualErr·
4c992a CPGPdiskDrv::ProcessMount(PAD_Mount pMNT, PGPUInt32 size)
90bb36 {
a37d36 ¤   DualErr derr;
07af5a
f2b533 ¤   // Check packet size.
24829e ¤   if (size < sizeof(AD_Mount))
6ad287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
edaf5a
32581f ¤   // Check desired drive letter.
072361 ¤   if (derr.IsntError())
0cc7a1 ¤   {
4a34aa ¤   ¤   pgpAssertAddrValid(pMNT, AD_Mount);
2faf5a
f493a1 ¤   ¤   if (!IsLegalDriveNumber(pMNT->drive))
94f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
9b9371 ¤   }
38af5a
f61aec ¤   // Perform the mount.
e02361 ¤   if (derr.IsntError())
a1c7a1 ¤   {
577587 ¤   ¤   pgpAssertStrValid(pMNT->path);
a33d04 ¤   ¤   pgpAssertAddrValid(pMNT->pContext, CipherContext);
49af5a
f6621e ¤   ¤   derr = MountPGPdisk(pMNT->path, pMNT->pContext, pMNT->drive,·
274874 ¤   ¤   ¤   pMNT->readOnly);
dc9371 ¤   }
20af5a
f82361 ¤   if (derr.IsntError())
1ac7a1 ¤   {
b0171d ¤   ¤   PGPdisk *pPGD = mPGPdisks.FindPGPdisk(pMNT->path);
60af5a
ab55cb ¤   ¤   pgpAssertAddrValid(pPGD, PGPdisk);
423101 ¤   ¤   (* pMNT->pDrive) = pPGD->GetDrive();
c29371 ¤   }
96af5a
a033e3 ¤   return derr;
82efe6 }
7faf5a
65d7a7 // ProcessUnmount processes a kAD_Unmount request.
bfaf5a
a62292 DualErr·
--84e1 000f918c7d340110119 Page 2 of CPGPdiskDrvComm.cpp
d6674b CPGPdiskDrv::ProcessUnmount(PAD_Unmount pUNMNT, PGPUInt32 size)
1dbb36 {
d97d36 ¤   DualErr derr;
83af5a
a0b533 ¤   // Check packet size.
7627a2 ¤   if (size < sizeof(AD_Unmount))
c3d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
e9af5a
bdf283 ¤   // Check drive letter.
c22361 ¤   if (derr.IsntError())
a0c7a1 ¤   {
44c66b ¤   ¤   pgpAssertAddrValid(pUNMNT, AD_Unmount);
14af5a
4b2dda ¤   ¤   if (!IsLegalDriveNumber(pUNMNT->drive))
75f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
e89371 ¤   }
c5af5a
470a44 ¤   // Perform the unmount.
562361 ¤   if (derr.IsntError())
eac7a1 ¤   {
5babe3 ¤   ¤   derr = UnmountPGPdisk(pUNMNT->drive, pUNMNT->isThisEmergency);
229371 ¤   }
2567c5 ¤
2833e3 ¤   return derr;
dcefe6 }
9aaf5a
5f102d // ProcessQueryVersion processes a kAD_QueryVersion request.
a7af5a
822292 DualErr·
c1a5c1 CPGPdiskDrv::ProcessQueryVersion(PAD_QueryVersion pQV, PGPUInt32 size)
5cbb36 {
617d36 ¤   DualErr derr;
01af5a
7db533 ¤   // Check packet size.
06f226 ¤   if (size < sizeof(AD_QueryVersion))
b2d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
31af5a
d06aab ¤   // Perform the query.
2d2361 ¤   if (derr.IsntError())
36c7a1 ¤   {
da6988 ¤   ¤   pgpAssertAddrValid(pQV, AD_QueryVersion);
fd8f6d ¤   ¤   pgpAssertAddrValid(pQV->pDriverVersion, PGPBoolean);
1caf5a
ff40d3 ¤   ¤   mPGPdiskAppVersion = pQV->appVersion;
25cf76 ¤   ¤   (* pQV->pDriverVersion) = kPGPdiskDriverVersion;
8a9371 ¤   }
8daf5a
7f33e3 ¤   return derr;
8eefe6 }
dbaf5a
706806 // ProcessQueryMounted processes a kAD_QueryMounted request.
07af5a
482292 DualErr·
b468f5 CPGPdiskDrv::ProcessQueryMounted(PAD_QueryMounted pQM, PGPUInt32 size)
8abb36 {
a17d36 ¤   DualErr derr;
0aaf5a
b4b533 ¤   // Check packet size.
3239e5 ¤   if (size < sizeof(AD_QueryMounted))
8ad287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
a9af5a
bc2008 ¤   // Check parameters.
1f2361 ¤   if (derr.IsntError())
0ec7a1 ¤   {
af267d ¤   ¤   pgpAssertAddrValid(pQM, AD_QueryMounted);
5e0786 ¤   ¤   pgpAssertAddrValid(pQM->pIsPGPdisk, PGPBoolean);
a5af5a
ae80f2 ¤   ¤   if (pQM->trueIfUsePath)
1c5b34 ¤   ¤   {
66fdcc ¤   ¤   ¤   pgpAssertStrValid(pQM->path);
d50fe4 ¤   ¤   }
f98a95 ¤   ¤   else if (!IsLegalDriveNumber(pQM->drive))
--f6c7 000b51e912340110119 Page 3 of CPGPdiskDrvComm.cpp
e35b34 ¤   ¤   {
6ff432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
d90fe4 ¤   ¤   }
4e9371 ¤   }
93af5a
436aab ¤   // Perform the query.
a22361 ¤   if (derr.IsntError())
86c7a1 ¤   {
2b80f2 ¤   ¤   if (pQM->trueIfUsePath)
b95b34 ¤   ¤   {
abdd32 ¤   ¤   ¤   if (IsntNull(Driver->mPGPdisks.FindPGPdisk(pQM->path)))
c80447 ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = TRUE;
67bb8c ¤   ¤   ¤   else
2a07fc ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = FALSE;
560fe4 ¤   ¤   }
f40e1d ¤   ¤   else
dd5b34 ¤   ¤   {
baf312 ¤   ¤   ¤   if (IsntNull(Driver->mPGPdisks.FindPGPdisk(pQM->drive)))
470447 ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = TRUE;
85bb8c ¤   ¤   ¤   else
a207fc ¤   ¤   ¤   ¤   (* pQM->pIsPGPdisk) = FALSE;
390fe4 ¤   ¤   }
539371 ¤   }
ccaf5a
a433e3 ¤   return derr;
89efe6 }
01af5a
d7bc6c // ProcessQueryOpenFiles processes a kAD_QueryOpenFiles request.
63af5a
7e2292 DualErr·
582e1a CPGPdiskDrv::ProcessQueryOpenFiles(PAD_QueryOpenFiles pQOF, PGPUInt32 size)
39bb36 {
a17d36 ¤   DualErr derr;
98af5a
bab533 ¤   // Check packet size.
05f822 ¤   if (size < sizeof(AD_QueryOpenFiles))
61d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
a8af5a
99f283 ¤   // Check drive letter.
6c2361 ¤   if (derr.IsntError())
f7c7a1 ¤   {
3bb47a ¤   ¤   pgpAssertAddrValid(pQOF, AD_QueryMounted);
f6af5a
01ad9f ¤   ¤   if (!IsLegalDriveNumber(pQOF->drive))
d3f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
fb9371 ¤   }
53af5a
026aab ¤   // Perform the query.
bf2361 ¤   if (derr.IsntError())
0ac7a1 ¤   {
4ba38a ¤   ¤   Volume vol;
0caf5a
2f951d ¤   ¤   // Prepare for the read/write.
f81686 ¤   ¤   derr = vol.AttachLocalVolume(pQOF->drive);
fdaf5a
48aa35 ¤   ¤   if (derr.IsntError())
2b5b34 ¤   ¤   {
2391b7 ¤   ¤   ¤   (* pQOF->pHasOpenFiles) = vol.HasOpenFiles();
190fe4 ¤   ¤   }
9eaf5a
91f91e ¤   ¤   if (vol.AttachedToLocalVolume())
4fb659 ¤   ¤   ¤   vol.DetachLocalVolume();
239371 ¤   }
c3af5a
5033e3 ¤   return derr;
a6efe6 }
3faf5a
3f6b1a // ProcessChangePrefs processes a DA_ChangePrefs request.
7faf5a
352292 DualErr·
3fc27b CPGPdiskDrv::ProcessChangePrefs(PAD_ChangePrefs pCP, PGPUInt32 size)
b5bb36 {
--fd31 000ea98d4d140110119 Page 4 of CPGPdiskDrvComm.cpp
507d36 ¤   DualErr derr;
c4af5a
14b533 ¤   // Check packet size.
1e52e2 ¤   if (size < sizeof(AD_ChangePrefs))
cad287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
71af5a
8bfad4 ¤   // Check params.
022361 ¤   if (derr.IsntError())
82c7a1 ¤   {
764bc2 ¤   ¤   pgpAssertAddrValid(pCP, AD_ChangePrefs);
e6af5a
cc6947 ¤   ¤   if ((pCP->unmountTimeout == 0) ||·
33b57b ¤   ¤   ¤   (pCP->unmountTimeout > kMaxUnmountTimeout))
eb5b34 ¤   ¤   {
23f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
ae0fe4 ¤   ¤   }
4d9371 ¤   }
45af5a
c28803 ¤   // Update preferences.
1f2361 ¤   if (derr.IsntError())
7ec7a1 ¤   {
802919 ¤   ¤   mAutoUnmount¤   = pCP->autoUnmount;
e6b341 ¤   ¤   mUnmountTimeout¤= pCP->unmountTimeout;
ec9371 ¤   }
22af5a
7b33e3 ¤   return derr;
a5efe6 }
d4af5a
b673c8 // ProcessLockUnlockMem processes a DA_LockUnlockMem request.
30af5a
452292 DualErr·
a6ed45 CPGPdiskDrv::ProcessLockUnlockMem(PAD_LockUnlockMem pLUM, PGPUInt32 size)
36bb36 {
a87d36 ¤   DualErr derr;
6aaf5a
88b533 ¤   // Check packet size.
4dd406 ¤   if (size < sizeof(AD_LockUnlockMem))
17d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
4daf5a
9c596e ¤   // Lock the memory
132361 ¤   if (derr.IsntError())
47c7a1 ¤   {
017e77 ¤   ¤   pgpAssertAddrValid(pLUM, AD_LockUnlockMem);
49536d ¤   ¤   pgpAssertAddrValid(pLUM->pMem, PGPUInt8);
40af5a
303227 ¤   ¤   if (pLUM->trueForLock)
0aec88 ¤   ¤   ¤   derr = LockUserBuffer(pLUM->pMem, pLUM->nBytes);
1a0e1d ¤   ¤   else
eb3f23 ¤   ¤   ¤   derr = UnlockUserBuffer(pLUM->pMem, pLUM->nBytes);
a49371 ¤   }
f6af5a
f933e3 ¤   return derr;
9defe6 }
3baf5a
9dddd6 // ProcessGetPGPdiskInfo processes a kAD_GetPGPdiskInfo request.
47af5a
4c2292 DualErr·
a9bc2e CPGPdiskDrv::ProcessGetPGPdiskInfo(PAD_GetPGPdiskInfo pGPI, PGPUInt32 size)
a3bb36 {
7bbe41 ¤   DualErr¤¤   derr;
9c0721 ¤   PGPUInt32¤  i;
5faf5a
32b533 ¤   // Check packet size.
d6ebd4 ¤   if (size < sizeof(AD_GetPGPdiskInfo))
26d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
f7af5a
758cac ¤   // Fill in the array entries.
892361 ¤   if (derr.IsntError())
ddc7a1 ¤   {
07396a ¤   ¤   pgpAssertAddrValid(pGPI, AD_GetPGPdiskInfo);
6caf5a
eaef91 ¤   ¤   for (i = 0; i < pGPI->arrayElems; i++)
--05c7 000ee7429b540110119 Page 5 of CPGPdiskDrvComm.cpp
e35b34 ¤   ¤   {
0f863c ¤   ¤   ¤   PGPdisk¤¤   *pPGD;
c15819 ¤   ¤   ¤   PGPdiskInfo¤*pPDI;
4baf5a
9ae890 ¤   ¤   ¤   pPDI = &pGPI->pPDIArray[i];
f427db ¤   ¤   ¤   pgpAssertAddrValid(pPDI, PGPdiskInfo);
6daf5a
489aa5 ¤   ¤   ¤   if (IsNull(pPGD = mPGPdisks.EnumPGPdisks(i)))
fff776 ¤   ¤   ¤   {
c9e23f ¤   ¤   ¤   ¤   pPDI->drive = kInvalidDrive;
97a3a6 ¤   ¤   ¤   }
66bb8c ¤   ¤   ¤   else
09f776 ¤   ¤   ¤   {
297ec7 ¤   ¤   ¤   ¤   pPDI->drive = pPGD->GetDrive();
7a513a ¤   ¤   ¤   ¤   pPDI->sessionId = pPGD->GetUniqueSessionId();
8baf5a
833779 ¤   ¤   ¤   ¤   strcpy(pPDI->path, pPGD->GetPath());
b8a3a6 ¤   ¤   ¤   }
cc0fe4 ¤   ¤   }
469371 ¤   }
93af5a
8c33e3 ¤   return derr;
d8efe6 }
9daf5a
1b1014 // ProcessLockUnlockVol processes a kAD_LockUnlockVol request.
30af5a
e32292 DualErr·
b0a340 CPGPdiskDrv::ProcessLockUnlockVol(PAD_LockUnlockVol pLUV, PGPUInt32 size)
72bb36 {
897d36 ¤   DualErr derr;
2caf5a
40b533 ¤   // Check packet size.
58eb80 ¤   if (size < sizeof(AD_LockUnlockVol))
75d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
fbaf5a
54f283 ¤   // Check drive letter.
152361 ¤   if (derr.IsntError())
01c7a1 ¤   {
dd15c0 ¤   ¤   pgpAssertAddrValid(pLUV, AD_LockUnlockVol);
84af5a
40a5f4 ¤   ¤   if (!IsLegalDriveNumber(pLUV->drive))
abf432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
ee9371 ¤   }
54af5a
fe4fb6 ¤   // Perform the lock/unlock.
ff2361 ¤   if (derr.IsntError())
16c7a1 ¤   {
a0a38a ¤   ¤   Volume vol;
d8af5a
e1951d ¤   ¤   // Prepare for the read/write.
fb1eed ¤   ¤   derr = vol.AttachLocalVolume(pLUV->drive);
a3af5a
bdaa35 ¤   ¤   if (derr.IsntError())
7f5b34 ¤   ¤   {
42c831 ¤   ¤   ¤   switch (pLUV->lockOp)
abf776 ¤   ¤   ¤   {
2cd061 ¤   ¤   ¤   case kLO_LockReadWrite:
89b6c2 ¤   ¤   ¤   ¤   derr = vol.LockVolumeForReadWrite();
2ef622 ¤   ¤   ¤   ¤   break;
08af5a
155fa8 ¤   ¤   ¤   case kLO_LockFormat:
9c36c7 ¤   ¤   ¤   ¤   derr = vol.LockVolumeForFormat();
21f622 ¤   ¤   ¤   ¤   break;
6eaf5a
558e00 ¤   ¤   ¤   case kLO_UnlockReadWrite:
4e5638 ¤   ¤   ¤   case kLO_UnlockFormat:
9a6a19 ¤   ¤   ¤   ¤   derr = vol.UnlockVolume();
9ef622 ¤   ¤   ¤   ¤   break;
7caf5a
61db68 ¤   ¤   ¤   default:
112e1b ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
eef622 ¤   ¤   ¤   ¤   break;
--2b8a 000284fc50a40110119 Page 6 of CPGPdiskDrvComm.cpp
cfa3a6 ¤   ¤   ¤   }
ccaf5a
31ffa6 ¤   ¤   ¤   if (vol.AttachedToLocalVolume())
81b3b4 ¤   ¤   ¤   ¤   vol.DetachLocalVolume();
210fe4 ¤   ¤   }
479371 ¤   }
4eaf5a
4d33e3 ¤   return derr;
56efe6 }
b7af5a
a4455c // ProcessReadWriteVol processes a kAD_ReadWriteVol request.
e3af5a
4b2292 DualErr·
f08bf9 CPGPdiskDrv::ProcessReadWriteVol(PAD_ReadWriteVol pRWV, PGPUInt32 size)
b6bb36 {
5d7d36 ¤   DualErr derr;
d9af5a
7ab533 ¤   // Check packet size.
533ce5 ¤   if (size < sizeof(AD_ReadWriteVol))
f4d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
04af5a
56f283 ¤   // Check drive letter.
872361 ¤   if (derr.IsntError())
fec7a1 ¤   {
d5ea04 ¤   ¤   pgpAssertAddrValid(pRWV, AD_ReadWriteVol);
d1af5a
14cd19 ¤   ¤   if (!IsLegalDriveNumber(pRWV->drive))
f2f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
da9371 ¤   }
78af5a
abf3be ¤   // Perform the read/write.
582361 ¤   if (derr.IsntError())
cbc7a1 ¤   {
0aa38a ¤   ¤   Volume vol;
74af5a
32951d ¤   ¤   // Prepare for the read/write.
9b7600 ¤   ¤   derr = vol.AttachLocalVolume(pRWV->drive);
eaaf5a
ae7fc1 ¤   ¤   // Perform the read/write.
99aa35 ¤   ¤   if (derr.IsntError())
4f5b34 ¤   ¤   {
655c75 ¤   ¤   ¤   if (pRWV->trueIfRead)
043433 ¤   ¤   ¤   ¤   derr = vol.Read(pRWV->buf, pRWV->pos, pRWV->nBlocks);
f5bb8c ¤   ¤   ¤   else
53e97d ¤   ¤   ¤   ¤   derr = vol.Write(pRWV->buf, pRWV->pos, pRWV->nBlocks);
e70fe4 ¤   ¤   }
cdaf5a
e7f91e ¤   ¤   if (vol.AttachedToLocalVolume())
a2b659 ¤   ¤   ¤   vol.DetachLocalVolume();
359371 ¤   }
e5af5a
5c33e3 ¤   return derr;
7fefe6 }
a0af5a
55c00b // ProcessQueryVolInfo processes a kAD_QueryVolInfo request.
96af5a
f62292 DualErr·
d73f2b CPGPdiskDrv::ProcessQueryVolInfo(PAD_QueryVolInfo pQVI,¤PGPUInt32 size)
b0bb36 {
a07d36 ¤   DualErr derr;
c0af5a
e3b533 ¤   // Check packet size.
9a1370 ¤   if (size < sizeof(AD_QueryVolInfo))
16d287 ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
a1af5a
b8f283 ¤   // Check drive letter.
402361 ¤   if (derr.IsntError())
bbc7a1 ¤   {
cca700 ¤   ¤   pgpAssertAddrValid(pQVI, AD_QueryVolInfo);
b8af5a
102bb2 ¤   ¤   if (!IsLegalDriveNumber(pQVI->drive))
28f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
--07fa 000f206cf2140110119 Page 7 of CPGPdiskDrvComm.cpp
a19371 ¤   }
93af5a
0d6aab ¤   // Perform the query.
432361 ¤   if (derr.IsntError())
fcc7a1 ¤   {
15a38a ¤   ¤   Volume vol;
5aaf5a
b5b5c9 ¤   ¤   pgpAssertAddrValid(pQVI->pBlockSize, PGPUInt16);
812216 ¤   ¤   pgpAssertAddrValid(pQVI->pTotalBlocks, PGPUInt16);
82af5a
3d90ab ¤   ¤   derr = vol.AttachLocalVolume(pQVI->drive);
02af5a
91aa35 ¤   ¤   if (derr.IsntError())
045b34 ¤   ¤   {
594a98 ¤   ¤   ¤   (* pQVI->pBlockSize) = vol.GetBlockSize();
cb0a72 ¤   ¤   ¤   (* pQVI->pTotalBlocks) = vol.GetTotalBlocks();
990fe4 ¤   ¤   }
f2af5a
ccf91e ¤   ¤   if (vol.AttachedToLocalVolume())
04b659 ¤   ¤   ¤   vol.DetachLocalVolume();
809371 ¤   }
70af5a
0133e3 ¤   return derr;
39efe6 }
0daf5a
f64225 // ProcessNotifyUserLogoff processes a kAD_NotifyUserLogoff request.
19af5a
c1e677 DualErr
a9e322 CPGPdiskDrv::ProcessNotifyUserLogoff(
fa6cf4 ¤   PAD_NotifyUserLogoff¤   pNUL,·
fbd5c0 ¤   PGPUInt32¤  ¤   ¤   ¤   size)
aebb36 {
e87d36 ¤   DualErr derr;
e2af5a
93fa86 ¤   // Begin attempts every second to unmount all PGPdisks.
1a91ac ¤   mUnmountAllMode = TRUE;
65af5a
f333e3 ¤   return derr;
61efe6 }
81af5a
dabb6c // ProcessADPacket is called to process an AD (application to driver) packet.
55af5a
1e1b0b PGPUInt32·
bff9e4 CPGPdiskDrv::ProcessADPacket(PADPacketHeader pPacket, PGPUInt32 size)
02bb36 {
a97d36 ¤   DualErr derr;
0aaf5a
eb489f ¤   // Validate the packet.
06cc19 ¤   if (IsNull(pPacket))
eec7a1 ¤   {
b39e81 ¤   ¤   return ERROR_INVALID_PARAMETER;
f49371 ¤   }
d7fc2f ¤   if (size < sizeof(ADPacketHeader))
83c7a1 ¤   {
65865f ¤   ¤   return ERROR_INSUFFICIENT_BUFFER;
fe9371 ¤   }
478cec ¤   else if (pPacket->magic != kPGPdiskADPacketMagic)
b7c7a1 ¤   {
1e9e81 ¤   ¤   return ERROR_INVALID_PARAMETER;
ab9371 ¤   }
8faf5a
3aabc8 ¤   // Was there an error during driver initialization?
912361 ¤   if (derr.IsntError())
42c7a1 ¤   {
d9a5c8 ¤   ¤   derr = Driver->mInitErr;
789371 ¤   }
28af5a
4f287b ¤   // Process the request.
b62361 ¤   if (derr.IsntError())
2ec7a1 ¤   {
a3c682 ¤   ¤   pgpAssertAddrValid(pPacket, ADPacketHeader);
f2ab90 ¤   ¤   DebugOut("PGPdisk: %s received\n", GetADPacketName(pPacket->code));
--f8d4 0002f02fb9c40110119 Page 8 of CPGPdiskDrvComm.cpp
e0af5a
bbc034 ¤   ¤   switch (pPacket->code)
d65b34 ¤   ¤   {
a7b38e ¤   ¤   case kAD_Mount:¤¤   ¤   ¤   // mount a PGPdisk
44c31f ¤   ¤   ¤   derr = ProcessMount((PAD_Mount) pPacket, size);
abcdcb ¤   ¤   ¤   break;
58af5a
bb0fa7 ¤   ¤   case kAD_Unmount:¤  ¤   ¤   // unmount a PGPdisk
2b5ffb ¤   ¤   ¤   derr = ProcessUnmount((PAD_Unmount) pPacket, size);
85cdcb ¤   ¤   ¤   break;
d5af5a
eec659 ¤   ¤   case kAD_QueryVersion:¤ ¤   // exchange version numbers
d05a83 ¤   ¤   ¤   derr = ProcessQueryVersion((PAD_QueryVersion) pPacket, size);
74cdcb ¤   ¤   ¤   break;
04af5a
ce3e5e ¤   ¤   case kAD_QueryMounted:¤ ¤   // ask if drive/path is PGPdisk
208440 ¤   ¤   ¤   derr = ProcessQueryMounted((PAD_QueryMounted) pPacket, size);
e5cdcb ¤   ¤   ¤   break;
20af5a
db2057 ¤   ¤   case kAD_QueryOpenFiles:¤   // app asks if drive has open files
7fb563 ¤   ¤   ¤   derr = ProcessQueryOpenFiles((PAD_QueryOpenFiles) pPacket, size);
17cdcb ¤   ¤   ¤   break;
c9af5a
6894ff ¤   ¤   case kAD_ChangePrefs:¤  ¤   // app changes preferences
8b5d65 ¤   ¤   ¤   derr = ProcessChangePrefs((PAD_ChangePrefs) pPacket, size);
33cdcb ¤   ¤   ¤   break;
75af5a
878e74 ¤   ¤   case kAD_LockUnlockMem:¤¤   // app wants to lock or unlock memory
b4fe5c ¤   ¤   ¤   derr = ProcessLockUnlockMem((PAD_LockUnlockMem) pPacket, size);
88cdcb ¤   ¤   ¤   break;
a3af5a
c5e100 ¤   ¤   case kAD_GetPGPdiskInfo:¤   // fill in array with PGPdisk info
8c7cdd ¤   ¤   ¤   derr = ProcessGetPGPdiskInfo((PAD_GetPGPdiskInfo) pPacket, size);
7ccdcb ¤   ¤   ¤   break;
0aaf5a
adfe99 ¤   ¤   case kAD_LockUnlockVol:¤¤   // lock/unlock volume
896d30 ¤   ¤   ¤   derr = ProcessLockUnlockVol((PAD_LockUnlockVol) pPacket, size);
28cdcb ¤   ¤   ¤   break;
d5af5a
54317b ¤   ¤   case kAD_ReadWriteVol:¤ ¤   // read/write to volume
a8abe8 ¤   ¤   ¤   derr = ProcessReadWriteVol((PAD_ReadWriteVol) pPacket, size);
42cdcb ¤   ¤   ¤   break;
aaaf5a
f4b0a6 ¤   ¤   case kAD_QueryVolInfo:¤ ¤   // get extra info about a volume
4c4b38 ¤   ¤   ¤   derr = ProcessQueryVolInfo((PAD_QueryVolInfo) pPacket, size);
e5cdcb ¤   ¤   ¤   break;
daaf5a
b867b4 ¤   ¤   case kAD_NotifyUserLogoff:¤ // user logging off, unmount PGPdisks
d5832c ¤   ¤   ¤   derr = ProcessNotifyUserLogoff((PAD_NotifyUserLogoff) pPacket,·
5eac35 ¤   ¤   ¤   ¤   size);
aecdcb ¤   ¤   ¤   break;
d8af5a
779ae3 ¤   ¤   default:
75f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
c1cdcb ¤   ¤   ¤   break;
120fe4 ¤   ¤   }
139371 ¤   }
5caf5a
1799b9 ¤   (* pPacket->pDerr) = derr;
6aaf5a
933b49 ¤   return ERROR_SUCCESS;
66efe6 }
cfaf5a
c1af5a
c76557 ///////////////////////
098076 // Dispatcher functions
cf6557 ///////////////////////
72af5a
69fbbe // OnW32DeviceIoControl is a member function of PGPdiskDevice that has been
993ae6 // overridden to handle DeviceIoControl calls. These calls are made by the
6d27a8 // application in order to pass messages and/or packets on to the driver.
2faf5a
--abea 001e6bc91f540110119 Page 9 of CPGPdiskDrvComm.cpp
260e55 DWORD·
fdb8ee CPGPdiskDrv::OnW32DeviceIoControl(PIOCTLPARAMS p)
f1bb36 {
37ea2d ¤   PGPUInt32 result;
ebaf5a
ecd469 ¤   switch (p->dioc_IOCtlCode)
11c7a1 ¤   {
b83699 ¤   case DIOC_OPEN:¤¤   ¤   ¤   ¤   ¤   // called when handle is opened
9e5566 ¤   ¤   result = DEVIOCTL_NOERROR;
022f68 ¤   ¤   break;
deaf5a
6154ec ¤   case DIOC_CLOSEHANDLE:¤ ¤   ¤   ¤   // called when handle is closed
3d5566 ¤   ¤   result = DEVIOCTL_NOERROR;
ca2f68 ¤   ¤   break;
07af5a
453fc4 ¤   case IOCTL_PGPDISK_SENDPACKET:¤ ¤   // called to send packet to driver
2d3ed6 ¤   ¤   result = ProcessADPacket((PADPacketHeader) p->dioc_InBuf,·
ecb27a ¤   ¤   ¤   p->dioc_cbInBuf);
c02f68 ¤   ¤   break;
78af5a
442f72 ¤   default:
30d1dc ¤   ¤   result = ERROR_INVALID_PARAMETER;
192f68 ¤   ¤   break;
f79371 ¤   }
d7af5a
ad5d73 ¤   return result;
e6efe6 }
--b2f2 0014c9d67e44011011a Page 1 of CPGPdiskDrvComm.h
541bc3 //////////////////////////////////////////////////////////////////////////////
3c76dc // CPGPdiskDrvComm.h
05465d //
173e9f // Declarations for CPGPdiskDrvComm.cpp.
141bc3 //////////////////////////////////////////////////////////////////////////////
04af5a
1a1ff0 // $Id: CPGPdiskDrvComm.h,v 1.1.2.3 1998/07/06 08:58:05 nryan Exp $
09af5a
22cbce // Copyright (C) 1998 by Network Associates, Inc.
3271ae // All rights reserved.
54af5a
051230 #ifndef Included_CPGPdiskDrvComm_h¤ // [
1db474 #define Included_CPGPdiskDrvComm_h
b0af5a
d01cb9 // Nothing needed here.
a0af5a
4cc2fb #endif¤ // ] Included_CPGPdiskDrvComm_h
--4825 0006f484d714011011b Page 1 of CPGPdiskDrvDebug.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
1c1633 // CPGPdiskDrvDebug.cpp
8c465d //
b933bf // Contains debugging helper routines.
5b1bc3 //////////////////////////////////////////////////////////////////////////////
82af5a
862bd6 // $Id: CPGPdiskDrvDebug.cpp,v 1.1.2.19 1998/07/06 08:58:06 nryan Exp $
c3af5a
31cbce // Copyright (C) 1998 by Network Associates, Inc.
3371ae // All rights reserved.
82af5a
c806a9 #include <vtoolscp.h>
cdaf5a
ba9bcf #include "Required.h"
079de2 #include "CPGPdiskDrv.h"
7fe43f #include "CPGPdiskDrvDebug.h"
5daf5a
dd86d2 #include LOCKED_CODE_SEGMENT
545269 #include LOCKED_DATA_SEGMENT
66af5a
8faf5a
3509b7 ////////////
d8e738 // Constants
3909b7 ////////////
01af5a
a2e07f #define PGPDISK_DEBUGMEMORYLEAKS 0
44af5a
b5d82a const PGPUInt32 kGuardDWord = 0xF926A4E9;
94af5a
53af5a
009ba8 #if PGP_DEBUG¤  // [
38af5a
cacbee ///////////////////////////////////
d39454 // Debug memory allocation routines
e5cbee ///////////////////////////////////
4eaf5a
b96bbe #if PGPDISK_DEBUGMEMORYLEAKS
b9436e static PGPUInt32 totalBytesAllocated = 0;
3f3f4a #endif¤ // PGPDISK_DEBUGMEMORYLEAKS
bbaf5a
2c98b7 // __default_nh is the default error handler for new.
48af5a
6faad3 int _cdecl·
8d38ab __default_nh(size_t)
56bb36 {
6a54c7 ¤   pgpDebugMsg("Couldn't allocate memory in operator new");
37af5a
e13e6b ¤   return 0;
7782f7 };
8baf5a
50f573 _PNH __newhandler = __default_nh;
92af5a
1dc6b6 // _set_new_handler sets the operator new error handler.
85af5a
165270 _PNH _cdecl·
64fb94 _set_new_handler(_PNH pHandler)
24bb36 {
7b0f43 ¤   _PNH old = __newhandler;
26495a ¤   __newhandler = pHandler;
19af5a
3b2caf ¤   return old;
f2efe6 }
abaf5a
4d6ece // DebugNewHelper is the implementation of our debug new function.
daaf5a
f2ed74 void * _cdecl·
ae3d28 DebugNewHelper(size_t n)
b6bb36 {
3ee18b ¤   PGPUInt8¤   *p;
5787ea ¤   PGPUInt32¤  dataSize, totalSize;
34af5a
6fdb2e ¤   dataSize¤   = n;
--4253 000345cb9624011011b Page 2 of CPGPdiskDrvDebug.cpp
00b3d1 ¤   totalSize¤  = dataSize + 3*sizeof(PGPUInt32);
94af5a
1fcfa1 ¤   do
bd2ef1 ¤   {¤
a337cd ¤   ¤   p = (PGPUInt8 *) _HeapAllocate(totalSize, 0);
d99371 ¤   }
3188d7 ¤   while ((!p) && __newhandler(totalSize));
36af5a
0f7c9b ¤   if (IsntNull(p))
3ec7a1 ¤   {
5275a9 ¤   ¤   PGPUInt8 *returnMe, *temp;
11af5a
078e36 ¤   ¤   pgpDebugWhackMemory(p, totalSize);¤ ¤   // upside the head
d0af5a
f100e7 ¤   ¤   temp = (PGPUInt8 *) p;
cf5d07 ¤   ¤   returnMe = temp + 2*sizeof(PGPUInt32);
90af5a
795419 ¤   ¤   ((PGPUInt32 *) temp)[0]¤= dataSize;
ddfa5b ¤   ¤   ((PGPUInt32 *) temp)[1]¤= kGuardDWord;
16af5a
3a3d58 ¤   ¤   temp += 2*sizeof(PGPUInt32) + dataSize;
a9af5a
9302bc ¤   ¤   ((PGPUInt32 *) temp)[0]¤= kGuardDWord;
15af5a
4bed80 ¤   ¤   #if PGPDISK_DEBUGMEMORYLEAKS
6eaf5a
8798fd ¤   ¤   totalBytesAllocated += n;
2d5c59 ¤   ¤   DebugOut("PGPdisk New: Alloced %d bytes, have %d total allocated\n",·
6594ec ¤   ¤   ¤   n, totalBytesAllocated);
32af5a
087279 ¤   ¤   #endif¤ // PGPDISK_DEBUGMEMORYLEAKS
87af5a
965eec ¤   ¤   return returnMe;
109371 ¤   }
da0e24 ¤   else
eac7a1 ¤   {
db7ed2 ¤   ¤   return NULL;
359371 ¤   }
1defe6 }
dbaf5a
d8d923 // DebugDeleteHelper is the implementation of our debug delete function.
68af5a
b04e65 void _cdecl·
aa107a DebugDeleteHelper(void *p)
8ebb36 {
1c7c69 ¤   static char¤¤   ¤   msg[kMaxStringSize];¤   // don't waste stack space!
94198d ¤   static PGPUInt32¤   numDelete¤  = 0;
29af5a
f77c9b ¤   if (IsntNull(p))
e7c7a1 ¤   {
f5822f ¤   ¤   PGPBoolean¤ firstGuardWasValid, secondGuardWasValid;
c83a78 ¤   ¤   PGPUInt8¤   *freeMe, *temp;
dc2a95 ¤   ¤   PGPUInt32¤  dataSize, firstGuard, secondGuard, totalSize;
061b52 ¤   ¤
8f9786 ¤   ¤   numDelete++;
b1af5a
24a8f5 ¤   ¤   temp = freeMe = (PGPUInt8 *) p - 2*sizeof(PGPUInt32);
0faf5a
557b62 ¤   ¤   dataSize¤   = ((PGPUInt32 *) temp)[0];
241dd0 ¤   ¤   totalSize¤  = dataSize + 3*sizeof(PGPUInt32);
12af5a
761fc9 ¤   ¤   firstGuard = ((PGPUInt32 *) temp)[1];
c5bf32 ¤   ¤   firstGuardWasValid = (firstGuard == kGuardDWord);
a8af5a
51f52f ¤   ¤   if (!firstGuardWasValid)
775b34 ¤   ¤   {
e9a2c8 ¤   ¤   ¤   sprintf(msg, "Beginning guard dword trashed on memory block at "
c9da91 ¤   ¤   ¤   ¤   "pointer address %x delete number %d", p, numDelete);
57af5a
cc80d4 ¤   ¤   ¤   pgpDebugMsg(msg);
af0fe4 ¤   ¤   }
340e1d ¤   ¤   else
--78e4 0001bc1d6fe4011011b Page 3 of CPGPdiskDrvDebug.cpp
e35b34 ¤   ¤   {
8fab19 ¤   ¤   ¤   temp += 2*sizeof(PGPUInt32) + dataSize;
f33b2f ¤   ¤   ¤   secondGuard = ((PGPUInt32 *) temp)[0];
f4af5a
d995a0 ¤   ¤   ¤   secondGuardWasValid = (secondGuard == kGuardDWord);
51af5a
de0db4 ¤   ¤   ¤   if (!secondGuardWasValid)
90f776 ¤   ¤   ¤   {
c8aedc ¤   ¤   ¤   ¤   sprintf(msg, "Ending guard dword trashed on memory block with "
53757e ¤   ¤   ¤   ¤   ¤   "size %d and pointer address %x delete number %d",·
7557a7 ¤   ¤   ¤   ¤   ¤   dataSize, p, numDelete);
50af5a
1bb7dc ¤   ¤   ¤   ¤   pgpDebugMsg(msg);
3aa3a6 ¤   ¤   ¤   }
e10fe4 ¤   ¤   }
acaf5a
fa442b ¤   ¤   // Don't whack unless we are sure of the correct size.
bb7fb4 ¤   ¤   if (firstGuardWasValid)
d9ba3e ¤   ¤   ¤   pgpDebugWhackMemory(freeMe, totalSize);¤¤   // upside the head
34af5a
910a6d ¤   ¤   _HeapFree((void *) freeMe, 0);
d1af5a
d1ed80 ¤   ¤   #if PGPDISK_DEBUGMEMORYLEAKS
1eaf5a
b476be ¤   ¤   totalBytesAllocated -= dataSize;
213182 ¤   ¤   DebugOut("PGPdisk Delete: Freed %d bytes, have %d total allocated\n",·
8378e9 ¤   ¤   ¤   dataSize, totalBytesAllocated);
daaf5a
517279 ¤   ¤   #endif¤ // PGPDISK_DEBUGMEMORYLEAKS
eb9371 ¤   }
6aefe6 }
a2af5a
3a432a // A debug version of new with guard bytes.
9baf5a
3221f6 void *·
f657d1 _cdecl·
5f8cff operator new(size_t n)
44bb36 {
f90464 ¤   return DebugNewHelper(n);
cfefe6 }
6daf5a
4f69cf // A debug version of operation new[] with guard bytes.
adaf5a
dd21f6 void *·
fe57d1 _cdecl·
774785 operator new[](size_t n)
0cbb36 {
e60464 ¤   return DebugNewHelper(n);
0eefe6 }
60af5a
9bf8b5 // A debug version of operation delete with guard bytes.
08af5a
9dc823 void·
6a57d1 _cdecl·
9fc99f operator delete(void *p)
3cbb36 {
ac9f83 ¤   DebugDeleteHelper(p);
c4efe6 }
bdaf5a
ddf72c // A debug version of operation delete[] with guard bytes.
1daf5a
85c823 void·
4f57d1 _cdecl·
d49143 operator delete[](void *p)
75bb36 {
c59f83 ¤   DebugDeleteHelper(p);
f4efe6 }
48af5a
12ea9f #endif¤ // ] PGP_DEBUG
f2af5a
f99bef //////////////////////////////////////////////
1bd195 // Functions for associating values with names
--cf5e 000ac2569c04011011b Page 4 of CPGPdiskDrvDebug.cpp
149bef //////////////////////////////////////////////
a1af5a
35eb3a // GetName parses a nametable and determines which string is associated with
e61a9b // which constant, and returns it.
83af5a
6603c3 LPCSTR·
dd5077 CPGPdiskDrv::GetName(NameAssoc nameTable[], PGPUInt32 n, PGPUInt32 func)
bebb36 {
ac51fc ¤   PGPUInt32 i;
f9af5a
8210da ¤   for (i = 0; i < n; i++)
20c7a1 ¤   {
aba7a8 ¤   ¤   if (func == nameTable[i].func)
319722 ¤   ¤   ¤   return nameTable[i].name;
539371 ¤   }
44af5a
3b6a8f ¤   return "<Unknown>";
e3efe6 }
1baf5a
886952 // GetADPacketName returns a string with the name of the AD packet passed in
c0eac3 // 'func'.
08af5a
9a03c3 LPCSTR·
5ad133 CPGPdiskDrv::GetADPacketName(PGPUInt32 func)
32bb36 {
5ae31a ¤   static NameAssoc nameTable[] =
5cc7a1 ¤   {
ade569 ¤   ¤   {kAD_Mount,¤¤   ¤   ¤   ¤   "kAD_Mount"},
01f53b ¤   ¤   {kAD_Unmount,¤  ¤   ¤   ¤   "kAD_Unmount"},
eb73a8 ¤   ¤   {kAD_QueryVersion,¤ ¤   ¤   "kAD_QueryVersion"},
977325 ¤   ¤   {kAD_QueryMounted,¤ ¤   ¤   "kAD_QueryMounted"},
87a5d2 ¤   ¤   {kAD_QueryOpenFiles,¤   ¤   "kAD_QueryOpenFiles"},
229607 ¤   ¤   {kAD_ChangePrefs,¤  ¤   ¤   "kAD_ChangePrefs"},
324693 ¤   ¤   {kAD_LockUnlockMem,¤¤   ¤   "kAD_LockUnlockMem"},·
2055dd ¤   ¤   {kAD_GetPGPdiskInfo,¤   ¤   "kAD_GetPGPdiskInfo"},·
16572b ¤   ¤   {kAD_LockUnlockVol,¤¤   ¤   "kAD_LockUnlockVol"},·
6001fb ¤   ¤   {kAD_ReadWriteVol,¤ ¤   ¤   "kAD_ReadWriteVol"},·
6d2ad3 ¤   ¤   {kAD_QueryVolInfo,¤ ¤   ¤   "kAD_QueryVolInfo"},·
40677e ¤   ¤   {kAD_NotifyUserLogoff,¤ ¤   "kAD_NotifyUserLogoff"}
d3af5a
5862bd ¤   };
4faf5a
f95a7a ¤   return GetName(nameTable, (sizeof(nameTable)/sizeof(NameAssoc)), func);
b5efe6 }
cdaf5a
fb8f06 // GetAEPFunctionName returns a string with the name of the AEP function
b371ba // passed in 'func'.
4baf5a
b003c3 LPCSTR·
69b65c CPGPdiskDrv::GetAEPFunctionName(PGPUInt32 func)
6ebb36 {
ece31a ¤   static NameAssoc nameTable[] =
21c7a1 ¤   {
4d31ad ¤   ¤   {AEP_INITIALIZE,¤   ¤   ¤   "AEP_INITIALIZE"},
f6b49f ¤   ¤   {AEP_SYSTEM_CRIT_SHUTDOWN,¤ "AEP_SYSTEM_CRIT_SHUTDOWN"},
fbb2da ¤   ¤   {AEP_BOOT_COMPLETE,¤¤   ¤   "AEP_BOOT_COMPLETE"},
a8230e ¤   ¤   {AEP_CONFIG_DCB,¤   ¤   ¤   "AEP_CONFIG_DCB"},
c22a4a ¤   ¤   {AEP_UNCONFIG_DCB,¤ ¤   ¤   "AEP_UNCONFIG_DCB"},
fcaccb ¤   ¤   {AEP_IOP_TIMEOUT,¤  ¤   ¤   "AEP_IOP_TIMEOUT"},
6f5da4 ¤   ¤   {AEP_DEVICE_INQUIRY,¤   ¤   "AEP_DEVICE_INQUIRY"},
6e9758 ¤   ¤   {AEP_HALF_SEC,¤ ¤   ¤   ¤   "AEP_HALF_SEC"},
a92dec ¤   ¤   {AEP_1_SEC,¤¤   ¤   ¤   ¤   "AEP_1_SEC"},
0a3e46 ¤   ¤   {AEP_2_SECS,¤   ¤   ¤   ¤   "AEP_2_SECS"},
343017 ¤   ¤   {AEP_4_SECS,¤   ¤   ¤   ¤   "AEP_4_SECS"},
6da777 ¤   ¤   {AEP_DBG_DOT_CMD,¤  ¤   ¤   "AEP_DBG_DOT_CMD"},
558ee6 ¤   ¤   {AEP_ASSOCIATE_DCB,¤¤   ¤   "AEP_ASSOCIATE_DCB"},
b819bd ¤   ¤   {AEP_REAL_MODE_HANDOFF,¤¤   "AEP_REAL_MODE_HANDOFF"},
6415b8 ¤   ¤   {AEP_SYSTEM_SHUTDOWN,¤  ¤   "AEP_SYSTEM_SHUTDOWN"},
f238e9 ¤   ¤   {AEP_UNINITIALIZE,¤ ¤   ¤   "AEP_UNINITIALIZE"},
430891 ¤   ¤   {AEP_DCB_LOCK,¤ ¤   ¤   ¤   "AEP_DCB_LOCK"},
cf928a ¤   ¤   {AEP_MOUNT_NOTIFY,¤ ¤   ¤   "AEP_MOUNT_NOTIFY"},
ac4dbb ¤   ¤   {AEP_CREATE_VRP,¤   ¤   ¤   "AEP_CREATE_VRP"},
--2cf5 0016a5d7a484011011b Page 5 of CPGPdiskDrvDebug.cpp
45b69f ¤   ¤   {AEP_DESTROY_VRP,¤  ¤   ¤   "AEP_DESTROY_VRP"},
9c1ac0 ¤   ¤   {AEP_REFRESH_DRIVE,¤¤   ¤   "AEP_REFRESH_DRIVE"},
2634c9 ¤   ¤   {AEP_PEND_UNCONFIG_DCB,¤¤   "AEP_PEND_UNCONFIG_DCB"},
eff81e ¤   ¤   {AEP_1E_VEC_UPDATE,¤¤   ¤   "AEP_1E_VEC_UPDATE"},
b52e7a ¤   ¤   {AEP_CHANGE_RPM,¤   ¤   ¤   "AEP_CHANGE_RPM"}
2daf5a
3262bd ¤   };
45af5a
193910 ¤   return GetName(nameTable, (sizeof(nameTable) / sizeof(NameAssoc)), func);
e9efe6 }
70af5a
4e2a2b // GetIORFunctionName returns a string with the name of the IOR function·
4171ba // passed in 'func'.
a1af5a
d503c3 LPCSTR·
cbcf26 CPGPdiskDrv::GetIORFunctionName(PGPUInt32 func)
43bb36 {
a8e31a ¤   static NameAssoc nameTable[] =
40c7a1 ¤   {
a45c47 ¤   ¤   {IOR_READ,¤ ¤   ¤   ¤   ¤   ¤   "IOR_READ"},
bd60d5 ¤   ¤   {IOR_WRITE,¤¤   ¤   ¤   ¤   ¤   "IOR_WRITE"},
d09d76 ¤   ¤   {IOR_VERIFY,¤   ¤   ¤   ¤   ¤   "IOR_VERIFY"},
f1e361 ¤   ¤   {IOR_CANCEL,¤   ¤   ¤   ¤   ¤   "IOR_CANCEL"},
7173a2 ¤   ¤   {IOR_WRITEV,¤   ¤   ¤   ¤   ¤   "IOR_WRITEV"},
11861d ¤   ¤   {IOR_MEDIA_CHECK,¤  ¤   ¤   ¤   "IOR_MEDIA_CHECK"},
2e2974 ¤   ¤   {IOR_MEDIA_CHECK_RESET,¤¤   ¤   "IOR_MEDIA_CHECK_RESET"},
fd7faa ¤   ¤   {IOR_LOAD_MEDIA,¤   ¤   ¤   ¤   "{IOR_IOR_LOAD_MEDIA"},
14567a ¤   ¤   {IOR_EJECT_MEDIA,¤  ¤   ¤   ¤   "IOR_EJECT_MEDIA"},
92181b ¤   ¤   {IOR_LOCK_MEDIA,¤   ¤   ¤   ¤   "IOR_LOCK_MEDIA"},
0351ab ¤   ¤   {IOR_UNLOCK_MEDIA,¤ ¤   ¤   ¤   "IOR_UNLOCK_MEDIA"},
121a03 ¤   ¤   {IOR_REQUEST_SENSE,¤¤   ¤   ¤   "IOR_REQUEST_SENSE"},
e7d62c ¤   ¤   {IOR_COMPUTE_GEOM,¤ ¤   ¤   ¤   "IOR_COMPUTE_GEOM"},
5729d7 ¤   ¤   {IOR_GEN_IOCTL,¤¤   ¤   ¤   ¤   "IOR_GEN_IOCTL"},
89eba0 ¤   ¤   {IOR_FORMAT,¤   ¤   ¤   ¤   ¤   "IOR_FORMAT"},
c3684d ¤   ¤   {IOR_SCSI_PASS_THROUGH,¤¤   ¤   "IOR_SCSI_PASS_THROUGH"},
540fc1 ¤   ¤   {IOR_CLEAR_QUEUE,¤  ¤   ¤   ¤   "IOR_CLEAR_QUEUE"},
e8ecc3 ¤   ¤   {IOR_DOS_RESET,¤¤   ¤   ¤   ¤   "IOR_DOS_RESET"},
8ce04c ¤   ¤   {IOR_SCSI_REQUEST,¤ ¤   ¤   ¤   "IOR_SCSI_REQUEST"},
1d2502 ¤   ¤   {IOR_SET_WRITE_STATUS,¤ ¤   ¤   "IOR_SET_WRITE_STATUS"},
b1bbe9 ¤   ¤   {IOR_RESTART_QUEUE,¤¤   ¤   ¤   "IOR_RESTART_QUEUE"},
1a2393 ¤   ¤   {IOR_ABORT_QUEUE,¤  ¤   ¤   ¤   "IOR_ABORT_QUEUE"},
1c279d ¤   ¤   {IOR_SPIN_DOWN,¤¤   ¤   ¤   ¤   "IOR_SPIN_DOWN"},
fda69e ¤   ¤   {IOR_SPIN_UP,¤  ¤   ¤   ¤   ¤   "IOR_SPIN_UP"},
cd5f07 ¤   ¤   {IOR_FLUSH_DRIVE,¤  ¤   ¤   ¤   "IOR_FLUSH_DRIVE"},
860f19 ¤   ¤   {IOR_FLUSH_DRIVE_AND_DISCARD,¤  "IOR_FLUSH_DRIVE_AND_DISCARD"},
b708dc ¤   ¤   {IOR_FSD_EXT,¤  ¤   ¤   ¤   ¤   "IOR_FSD_EXT"}
ddaf5a
8e62bd ¤   };
0eaf5a
e23910 ¤   return GetName(nameTable, (sizeof(nameTable) / sizeof(NameAssoc)), func);
6aefe6 }
--3d48 001243ec8724011011c Page 1 of CPGPdiskDrvDebug.h
541bc3 //////////////////////////////////////////////////////////////////////////////
e17ce3 // CPGPdiskDrvDebug.h
c6465d //
a97d61 // Declarations for CPGPdiskDrvDebug.cpp.
2c1bc3 //////////////////////////////////////////////////////////////////////////////
acaf5a
479ec5 // $Id: CPGPdiskDrvDebug.h,v 1.1.2.3 1998/07/06 08:58:06 nryan Exp $
d2af5a
58cbce // Copyright (C) 1998 by Network Associates, Inc.
5571ae // All rights reserved.
82af5a
f3467d #ifndef Included_CPGPdiskDrvDebug_h¤// [
9ec999 #define Included_CPGPdiskDrvDebug_h
8caf5a
69af5a
efd557 ////////
2602c9 // Types
02d557 ////////
e4af5a
f31956 // NameAssoc is used by the debug routines to associate strings to constants.
0caf5a
4cf155 typedef struct NameAssoc
7cbb36 {
88758d ¤   PGPUInt32¤  func;
c457f7 ¤   LPCSTR¤ ¤   name;
05af5a
3031cd } NameAssoc;
70af5a
24b510 #endif¤ // ] Included_CPGPdiskDrvDebug_h
--8e10 000f09428ee4011011d Page 1 of CPGPdiskDrvErrors.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
cd0b07 // CPGPdiskDrvErrors.cpp
b5465d //
2f22fa // Error handling functions.
5b1bc3 //////////////////////////////////////////////////////////////////////////////
5daf5a
fb927e // $Id: CPGPdiskDrvErrors.cpp,v 1.1.2.10 1998/07/06 08:58:07 nryan Exp $
58af5a
a1cbce // Copyright (C) 1998 by Network Associates, Inc.
4a71ae // All rights reserved.
cdaf5a
f806a9 #include <vtoolscp.h>
f1af5a
9f9bcf #include "Required.h"
eb4e67 #include "SimpleQueue.h"
14993c #include "StringAssociation.h"
5faf5a
959de2 #include "CPGPdiskDrv.h"
ddc18e #include "CPGPdiskDrvErrors.h"
a0c411 #include "Globals.h"
ceaf5a
ee86d2 #include LOCKED_CODE_SEGMENT
545269 #include LOCKED_DATA_SEGMENT
94af5a
e6af5a
8383f5 ///////////////////////////
1e873f // Error handling functions
8183f5 ///////////////////////////
10af5a
69b0cc // ReportErrorEndCallback is called when the user has closed the error
19dc8f // reporting message box.
3daf5a
fea1ba VOID·
bfb45d __stdcall·
0571c2 CPGPdiskDrv::ReportErrorEndCallback(DWORD ResponseCode, PVOID Refdata)
65bb36 {
64971b ¤   ErrorCell¤  *pErrPacket;
cb901a ¤   LPSTR¤  ¤   errString;
2caf5a
b5bb93 ¤   pErrPacket = (ErrorCell *) Refdata;
d5d8a4 ¤   pgpAssertAddrValid(pErrPacket, ErrorCell);
2aaf5a
fd8439 ¤   // If an I/O error, unmount the PGPdisk if user specified 'Yes', else
f2f379 ¤   // re-enable I/O to the PGPdisk.
3daf5a
e27bdb ¤   switch (pErrPacket->perr)
85c7a1 ¤   {
c6fc9b ¤   case kPGDMajorError_PGPdiskReadError:
43136f ¤   case kPGDMajorError_PGPdiskWriteError:
5e5b34 ¤   ¤   {
4a9214 ¤   ¤   PGPdisk¤¤   *pPGD;
25bd99 ¤   ¤   PGPUInt8¤   drive¤  = pErrPacket->drive;
8eaf5a
d193d3 ¤   ¤   pgpAssert(IsLegalDriveNumber(drive));
e9af5a
987371 ¤   ¤   if (ResponseCode == IDYES)
845b34 ¤   ¤   {
4928cc ¤   ¤   ¤   Driver->UnmountPGPdisk(drive, TRUE);
060fe4 ¤   ¤   }
2e0e1d ¤   ¤   else
4a5b34 ¤   ¤   {
aebbf7 ¤   ¤   ¤   pPGD = Driver->mPGPdisks.FindPGPdisk(drive);
49af5a
fffe58 ¤   ¤   ¤   if (IsntNull(pPGD))
68d0af ¤   ¤   ¤   ¤   pPGD->EnableIO(TRUE);
9a0fe4 ¤   ¤   }
820fe4 ¤   ¤   }
372f68 ¤   ¤   break;
4b9371 ¤   }
d8af5a
c3f756 ¤   // Free the error string.
f01b68 ¤   errString = pErrPacket->errString;
--fe91 000b2ab0bbc4011011d Page 2 of CPGPdiskDrvErrors.cpp
7d5e63 ¤   pgpAssertStrValid(errString);
2faf5a
ff609b ¤   delete[] errString;
74af5a
ed54bf ¤   // Mark the packet as unused.
f7a5e7 ¤   pErrPacket->isInUse = FALSE;
55af5a
fbc949 ¤   // If more errors in queue, then schedule another callback.
efb75f ¤   if (!Driver->mErrorQueue.IsEmpty())
3f0d1b ¤   ¤   Driver->ScheduleErrorCallback();
700e24 ¤   else
c50dd4 ¤   ¤   Driver->mIsErrorCallbackBusy = FALSE;
31efe6 }
22af5a
2831e6 // ReportErrorStartCallback begins the process of reporting an error at a
846fce // safe time.
d8af5a
bba1ba VOID·
66b45d __stdcall·
0b51dc CPGPdiskDrv::ReportErrorStartCallback(
4dbfb0 ¤   VMHANDLE¤   ¤   hVM,·
63518d ¤   THREADHANDLE¤   hThread,·
8ad6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
7b58d6 ¤   PCLIENT_STRUCT¤ pRegs)
f0bb36 {
b5caca ¤   DualErr¤¤   ¤   ¤   ¤   ¤   derr;
7c205f ¤   ErrorCell¤  ¤   ¤   ¤   ¤   *pErrPacket;
48e556 ¤   LPSTR¤  ¤   ¤   ¤   ¤   ¤   errString;
ba7881 ¤   static SHELLMessage_THUNK¤  callbackThunk;
75af5a
7391ad ¤   // Pop an error off the queue.
c103c8 ¤   if (!Driver->mErrorQueue.Pop((PGPUInt32 *) &pErrPacket))
40c7a1 ¤   {
068f52 ¤   ¤   pgpAssert(FALSE);
6299bf ¤   ¤   return;
2e9371 ¤   }
f2af5a
b0d8a4 ¤   pgpAssertAddrValid(pErrPacket, ErrorCell);
67af5a
617cf1 ¤   // Allocate scratch space for the error string.
992896 ¤   if (IsNull(errString = new char[kMaxStringSize]))
2decf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
49af5a
484cb4 ¤   // Format and display the error message.
322361 ¤   if (derr.IsntError())
14c7a1 ¤   {
387b2a ¤   ¤   FormatErrorString(pErrPacket->perr, pErrPacket->derr,·
578d71 ¤   ¤   ¤   pErrPacket->drive, errString, kMaxStringSize);
a0af5a
465100 ¤   ¤   pErrPacket->errString = errString;
89af5a
ba4cd3 ¤   ¤   switch (pErrPacket->perr)
225b34 ¤   ¤   {
dac55e ¤   ¤   case kPGDMajorError_PGPdiskReadError:
cd82f7 ¤   ¤   case kPGDMajorError_PGPdiskWriteError:
3d7dc2 ¤   ¤   ¤   SHELL_Message(Get_Sys_VM_Handle(), MB_ICONEXCLAMATION | MB_YESNO,·
3375d8 ¤   ¤   ¤   ¤   errString, "PGPdisk Error", ReportErrorEndCallback,·
3fd236 ¤   ¤   ¤   ¤   pErrPacket, &callbackThunk);
3ccdcb ¤   ¤   ¤   break;
48af5a
799ae3 ¤   ¤   default:
f62546 ¤   ¤   ¤   SHELL_Message(Get_Sys_VM_Handle(), MB_ICONEXCLAMATION | MB_OK,·
2f75d8 ¤   ¤   ¤   ¤   errString, "PGPdisk Error", ReportErrorEndCallback,·
2ad236 ¤   ¤   ¤   ¤   pErrPacket, &callbackThunk);
91cdcb ¤   ¤   ¤   break;
a40fe4 ¤   ¤   }
a69371 ¤   }
b2efe6 }
94af5a
5cf0ea // ScheduleErrorCallback schedules a callback that pops and reports errors on
1658fd // the error queue.
b2af5a
--3854 00146fd54674011011d Page 3 of CPGPdiskDrvErrors.cpp
84c823 void·
791243 CPGPdiskDrv::ScheduleErrorCallback()
70bb36 {
898883 ¤   static RestrictedEvent_THUNK callbackThunk;
f2af5a
bf872f ¤   Call_Restricted_Event(0, NULL,·
346340 ¤   ¤   PEF_WAIT_NOT_NESTED_EXEC | PEF_WAIT_NOT_CRIT, NULL,·
7a4cb8 ¤   ¤   ReportErrorStartCallback, 0, &callbackThunk);
c0efe6 }
c1af5a
f98951 // ReportError reports certain errors to the user.
29af5a
d6c823 void·
29cc5c CPGPdiskDrv::ReportError(PGDMajorError perr, DualErr derr, PGPUInt8 drive)
1fbb36 {
baf021 ¤   PGPBoolean¤ foundErrPacket¤ ¤   = FALSE;
7a0721 ¤   PGPUInt32¤  i;
e3af5a
69873c ¤   // Find a not-in-use error packet.
f9f535 ¤   for (i = 0; i < kNumErrPackets; i++)
d4c7a1 ¤   {
ad2e16 ¤   ¤   if (!mErrPackets[i].isInUse)
505b34 ¤   ¤   {
97d74f ¤   ¤   ¤   foundErrPacket = TRUE;
3e3ab7 ¤   ¤   ¤   mErrPackets[i].isInUse = TRUE;
8ccdcb ¤   ¤   ¤   break;
df0fe4 ¤   ¤   }
2f9371 ¤   }
cbaf5a
98691e ¤   if (!foundErrPacket)
9899bf ¤   ¤   return;
1daf5a
f404be ¤   // Fill in the error info.
6877e6 ¤   mErrPackets[i].perr¤¤   = perr;
156d27 ¤   mErrPackets[i].derr¤¤   = derr;
fd996a ¤   mErrPackets[i].drive¤   = drive;
54af5a
9f28f0 ¤   // Stick it in the queue.
7f95df ¤   mErrorQueue.Push((PGPUInt32) &mErrPackets[i]);
28af5a
72aa1e ¤   // If callback is not busy, then schedule it.
67dfa2 ¤   if (!mIsErrorCallbackBusy)
4ec7a1 ¤   {
147b20 ¤   ¤   mIsErrorCallbackBusy = TRUE;
4a10aa ¤   ¤   ScheduleErrorCallback();
8e9371 ¤   }
46efe6 }
--d18e 00108ebb8af4011011e Page 1 of CPGPdiskDrvErrors.h
541bc3 //////////////////////////////////////////////////////////////////////////////
5d6488 // CPGPdiskDrvErrors.h
28465d //
00835a // Ddeclarations for CPGPdiskDrvErrors.cpp.
bb1bc3 //////////////////////////////////////////////////////////////////////////////
3caf5a
d2778e // $Id: CPGPdiskDrvErrors.h,v 1.1.2.7 1998/07/06 08:58:08 nryan Exp $
56af5a
d3cbce // Copyright (C) 1998 by Network Associates, Inc.
7c71ae // All rights reserved.
90af5a
d0c40a #ifndef Included_CPGPdiskDrvErrors_h¤   // [
fc241a #define Included_CPGPdiskDrvErrors_h
93af5a
393a85 #include "DualErr.h"
db0092 #include "Packets.h"
1faf5a
42af5a
4c09b7 ////////////
48e738 // Constants
c109b7 ////////////
85af5a
d8aaf4 const PGPUInt32 kNumErrPackets = 30;¤   // # of prealloc'd error packets
caaf5a
51af5a
fed557 ////////
1a02c9 // Types
c2d557 ////////
6daf5a
d1ec03 // An ErrorCell is a simple holding place for error data.
7caf5a
ff3df0 typedef struct ErrorCell
0bbb36 {
a306b3 ¤   PGPBoolean¤ ¤   isInUse;¤   // cell in use?
79fa47 ¤   PGDMajorError¤  perr;¤  ¤   // major error
9847f7 ¤   DualErr¤¤   ¤   derr;¤  ¤   // minor error
3cdca5 ¤   PGPUInt8¤   ¤   drive;¤ ¤   // drive data field
1d1b36 ¤   LPSTR¤  ¤   ¤   errString;¤ // error string
a3af5a
91c3a6 } ErrorCell;
46af5a
083daf #endif¤ // ] Included_CPGPdiskDrvErrors_h
--86e3 000ada84b924011011f Page 1 of CPGPdiskDrvHooks.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
a7f09f // CPGPdiskDrvHooks.cpp
ff465d //
a9de89 // Functions for hooking system services.
d21bc3 //////////////////////////////////////////////////////////////////////////////
b1af5a
1d81ee // $Id: CPGPdiskDrvHooks.cpp,v 1.3.2.27.2.1 1998/10/21 07:12:31 nryan Exp $
d1af5a
1acbce // Copyright (C) 1998 by Network Associates, Inc.
9971ae // All rights reserved.
46af5a
9606a9 #include <vtoolscp.h>
69af5a
619bcf #include "Required.h"
65bfe9 #include "UtilityFunctions.h"
1daf5a
a24ece #include "CPGPdiskDrvHooks.h"
dec411 #include "Globals.h"
07af5a
4b86d2 #include LOCKED_CODE_SEGMENT
f25269 #include LOCKED_DATA_SEGMENT
f2af5a
8faf5a
0909b7 ////////////
b2e738 // Constants
0009b7 ////////////
80af5a
a407c7 const PGPUInt8¤ kButtonStatusMask¤  = 0x3C;¤¤   // all but button bits mask
13b718 const PGPUInt8¤ kSharedModeMask¤¤   = 0x0F;¤¤   // file open share bits mask
b6af5a
26af5a
4083f5 ///////////////////////////
35e46f // Hooking helper functions
6683f5 ///////////////////////////
15af5a
5bcaf3 // BroadcastMessageHook checks for unsafe volume locking requests.
5eaf5a
b67efe BOOL·
45d80e __cdecl·
615596 CPGPdiskDrv::BroadcastMessageHook(
3ea017 ¤   DWORD¤  uMsg,·
1f47d7 ¤   DWORD¤  wParam,·
5a118e ¤   DWORD¤  lParam,·
9dc037 ¤   DWORD¤  dwRef)
21bb36 {
fcbe41 ¤   DualErr¤¤   derr;
d2da2b ¤   PGPBoolean¤ denyThisMessage¤= FALSE;
dfaf5a
64c2b4 ¤   switch (GetLowWord(uMsg))
58c7a1 ¤   {
61117b ¤   case WM_DEVICECHANGE:
926277 ¤   ¤   if (wParam == DBT_VOLLOCKQUERYLOCK)
295b34 ¤   ¤   {
6b92df ¤   ¤   ¤   PGPUInt8¤   ¤   ¤   drive;
8702a4 ¤   ¤   ¤   VolLockBroadcast¤   *pVLB;
25af5a
206ef5 ¤   ¤   ¤   pVLB = (VolLockBroadcast *) lParam;
b99221 ¤   ¤   ¤   pgpAssertAddrValid(pVLB, VolLockBroadcast);
3daf5a
5b014e ¤   ¤   ¤   drive = pVLB->vlb_drive;
bdaf5a
cd7a7c ¤   ¤   ¤   // Deny lock request on host drives of PGPdisks as long as the
9e6bef ¤   ¤   ¤   // request did not come from PGPdisk itself.
48af5a
3cf046 ¤   ¤   ¤   if (Driver->mPGPdisks.IsLocalDriveAPGPdiskHost(drive))
3ef776 ¤   ¤   ¤   {
afd403 ¤   ¤   ¤   ¤   if (Driver->mLockInProgress &&·
836561 ¤   ¤   ¤   ¤   ¤   (Driver->mDriveBeingLocked == drive))
ef72c3 ¤   ¤   ¤   ¤   {
1bd71f ¤   ¤   ¤   ¤   ¤   Driver->mLockInProgress = FALSE;
442613 ¤   ¤   ¤   ¤   }
adfa07 ¤   ¤   ¤   ¤   else
--bfd8 000b1996acb4011011f Page 2 of CPGPdiskDrvHooks.cpp
d072c3 ¤   ¤   ¤   ¤   {
933fb3 ¤   ¤   ¤   ¤   ¤   denyThisMessage = TRUE;
fe2613 ¤   ¤   ¤   ¤   }
70a3a6 ¤   ¤   ¤   }
290fe4 ¤   ¤   }
5f2f68 ¤   ¤   break;
be9371 ¤   }
87af5a
b307f2 ¤   return !denyThisMessage;
29efe6 }
f7af5a
419f93 // KeyboardHook hooks all input from the keyboard.
58af5a
27c823 void·
98b45d __stdcall·
c13ff1 CPGPdiskDrv::KeyboardHook(PDSFRAME pRegs)
63bb36 {
3e7957 ¤   // Reset the inactivity timer.
cface2 ¤   Driver->mSecondsInactive = 0;
aaaf5a
dd60c4 ¤   // Clear the carry flag, meaning don't destroy any input.
a31855 ¤   pRegs->RFLAGS &= ~1;
6922bf ¤   Call_Previous_Hook_Proc(pRegs, &Driver->mKeyboard_Thunk);
a2efe6 }
90af5a
caae0d // MouseHook hooks all input from the mouse.
1eaf5a
01c823 void·
3bb45d __stdcall·
28594a CPGPdiskDrv::MouseHook(PDSFRAME regs)
febb36 {
24a24d ¤   PGPUInt8 buttonStatus;
a9af5a
3386a0 ¤   buttonStatus = GetLowByte(GetLowWord(regs->REAX));
71af5a
b87957 ¤   // Reset the inactivity timer.
004de1 ¤   if ((buttonStatus & kButtonStatusMask) != 0)
bf4391 ¤   ¤   Driver->mSecondsInactive = 0;
1daf5a
b3a6ef ¤   Call_Previous_Hook_Proc(regs, &Driver->mMouse_Thunk);
6aefe6 }
77af5a
a0eae0 // Due to an incredibly obscure interaction involving MSVC an optimization and
87cb97 // an IOS bug (it passes IOP address on the stack, expected that value to be
5adb7f // unaltered when the function returns - within local parameter storage no
15d48e // less!), IOS request handlers have to be called using a stub function.
08af5a
c6a1ba VOID·
6bd80e __cdecl·
6965b3 CPGPdiskDrv::PGPDISK_EjectHandlerStub(PIOP pIop)
88bb36 {
df1836 ¤   PGPDISK_EjectHandler(pIop);
e5efe6 }
caaf5a
ace36e // PGPDISK_EjectHandler is an IOP request handler that is installed for every
5c914a // drive that hosts a PGPdisk. It makes sure that the system can't eject a
32125e // removable volume that has a mounted PGPdisk on it. However, the user can
632318 // still eject such volumes manually, which is totally outside of Win95's
6d3da1 // control.
13af5a
4ca1ba VOID·
eb2017 CPGPdiskDrv::PGPDISK_EjectHandler(PIOP pIop)
b0bb36 {
b157f3 ¤   PGPBoolean¤ DenyIOP¤= FALSE;
00f341 ¤   PGPUInt8¤   drive;
40e6d3 ¤   PIOR¤   ¤   pIor;
99af5a
73148e ¤   pgpAssertAddrValid(pIop, IOP);
a1af5a
6ceccf ¤   pIor = &pIop->IOP_ior;
92b602 ¤   pgpAssertAddrValid(pIor, IOR);
b1af5a
--c3ef 000448fd62c4011011f Page 3 of CPGPdiskDrvHooks.cpp
12b737 ¤   // Is this an eject request directed at a PGPdisk host?
125062 ¤   drive = pIor->IOR_vol_designtr;
efaf5a
614050 ¤   if (pIor->IOR_func == IOR_EJECT_MEDIA)¤ ¤   ¤   // is this an eject?
8bc7a1 ¤   {
667dba ¤   ¤   if (Driver->mPGPdisks.IsLocalDriveAPGPdiskHost(drive))
98b3eb ¤   ¤   ¤   DenyIOP = TRUE;
d99371 ¤   }
31af5a
ad9118 ¤   // Are we denying the IOP?
daa404 ¤   if (DenyIOP)
1bc7a1 ¤   {
174433 ¤   ¤   DebugOut("PGPdisk: Denying eject request for PGPdisk host %d", drive);
c0af5a
d63b87 ¤   ¤   pIor->IOR_status = IORS_VOL_IN_USE;
3cb7a4 ¤   ¤   --pIop->IOP_callback_ptr;¤
0e754d ¤   ¤   pIop->IOP_callback_ptr->IOP_CB_address(pIop);
2c9371 ¤   }
ac0e24 ¤   else
71c7a1 ¤   {
303d86 ¤   ¤   pIop->IOP_calldown_ptr = pIop->IOP_calldown_ptr->DCB_cd_next;
952050 ¤   ¤   ((PFNIOP) pIop->IOP_calldown_ptr->DCB_cd_io_address)(pIop);
419371 ¤   }
e9efe6 }
08af5a
6aaf5a
6e1c7a //////////////////////////////////////////
f6a4ea // Hook installation and cleanup functions
df1c7a //////////////////////////////////////////
d7af5a
41102b // HookEjectionFilter hooks an ejection filter for the specified drive.
a5af5a
f52292 DualErr·
2362a7 CPGPdiskDrv::HookEjectionFilter(PGPUInt8 drive)
75bb36 {
fd945d ¤   DualErr¤derr;
3e9b89 ¤   PDCB¤   hostDcb¤= NULL;
4faf5a
bfaa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
59af5a
3fb1ab ¤   // If we haven't already hooked this drive and if it is NOT a PGPdisk,
5a0997 ¤   // then hook it. (PGPdisks have no eject buttons).
c4af5a
130b68 ¤   if (!mIsEjectHooked[drive] && !mPGPdisks.FindPGPdisk(drive))
fbc7a1 ¤   {
d715ef ¤   ¤   if (!(hostDcb = IspGetDcb(drive)))
d88115 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IspGetDcbFailed);
30af5a
8eaa35 ¤   ¤   if (derr.IsntError())
6e5b34 ¤   ¤   {
71dc2a ¤   ¤   ¤   if (!IspInsertCalldown(hostDcb, PGPDISK_EjectHandlerStub,·
55bad2 ¤   ¤   ¤   ¤   mTheDDB, 0, hostDcb->DCB_cmn.DCB_dmd_flags, DRP_FSD_EXT_1))
65f776 ¤   ¤   ¤   {
3cc073 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IspInsertCalldownFailed);
2aa3a6 ¤   ¤   ¤   }
340fe4 ¤   ¤   }
7baf5a
59aa35 ¤   ¤   if (derr.IsntError())
ff5b34 ¤   ¤   {
064f8d ¤   ¤   ¤   mIsEjectHooked[drive] = TRUE;
840fe4 ¤   ¤   }
769371 ¤   }
c5af5a
2933e3 ¤   return derr;
81efe6 }
1daf5a
365277 // SetupSystemHooksCallback installs the default system hooks required by the
3eb3bd // driver.
f6af5a
33a1ba VOID·
0db45d __stdcall·
44bb0b CPGPdiskDrv::SetupSystemHooksCallback(
--844a 001bfcf30d44011011f Page 4 of CPGPdiskDrvHooks.cpp
17bfb0 ¤   VMHANDLE¤   ¤   hVM,·
6c518d ¤   THREADHANDLE¤   hThread,·
64d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
e958d6 ¤   PCLIENT_STRUCT¤ pRegs)
9fbb36 {
4e314c ¤   // We need a mouse hook to monitor mouse activity.
504c94 ¤   Driver->mHookedVKD = IsntNull(
a812aa ¤   ¤   ::Hook_Device_Service(__VKD_Filter_Keyboard_Input, KeyboardHook,·
6fa8b6 ¤   ¤   &Driver->mKeyboard_Thunk));
e3af5a
b15a47 ¤   // We need a keyboard hook to monitor keyboard activity.
9df479 ¤   Driver->mHookedVMD = IsntNull(
5bbfd8 ¤   ¤   ::Hook_Device_Service(__VMD_Manipulate_Pointer_Message, MouseHook,·
805f36 ¤   ¤   &Driver->mMouse_Thunk));
93af5a
4c3470 ¤   // Install our broadcast hook so we can prevent certain volume locks.
b1b40d ¤   Driver->mBroadcastHookHandle =·
e68545 ¤   ¤   ::SHELL_HookSystemBroadcast(BroadcastMessageHook, NULL, 0);
31af5a
707d90 ¤   Driver->mHookedSystemBroadcast = IsntNull(Driver->mBroadcastHookHandle);
42efe6 }
c5af5a
f241a2 // SetupSystemHooks schedules SetupSystemHooksCallback for execution at a
a16fce // safe time.
8caf5a
04c823 void·
b90878 CPGPdiskDrv::SetupSystemHooks()
d4bb36 {
598883 ¤   static RestrictedEvent_THUNK callbackThunk;
19af5a
ec2161 ¤   ::Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED | PEF_WAIT_NOT_CRIT,·
0a4b2b ¤   ¤   NULL, SetupSystemHooksCallback, 0, &callbackThunk);
b7efe6 }
c0af5a
7f72eb // RemoveSystemHooks unhooks as many of our hooks as is possible.
8eaf5a
98c823 void·
1ef420 CPGPdiskDrv::RemoveSystemHooks()
46bb36 {
b3853e ¤   if (mHookedSystemBroadcast)
d4c7a1 ¤   {
d2782d ¤   ¤   ::SHELL_UnhookSystemBroadcast(mBroadcastHookHandle);
1b4b94 ¤   ¤   mHookedSystemBroadcast = FALSE;
579371 ¤   }
1eaf5a
c1c2bd ¤   if (Driver->mHookedVKD)
eec7a1 ¤   {
129883 ¤   ¤   Unhook_Device_Service(__VKD_Filter_Keyboard_Input, KeyboardHook,·
1a56f2 ¤   ¤   ¤   &mKeyboard_Thunk);
0f9371 ¤   }
68af5a
df8927 ¤   if (Driver->mHookedVMD)
67c7a1 ¤   {
7a60a1 ¤   ¤   Unhook_Device_Service(__VMD_Manipulate_Pointer_Message, MouseHook,·
5b9670 ¤   ¤   ¤   &mMouse_Thunk);
8b9371 ¤   }
bfefe6 }
--8044 0015b30cdfe40110120 Page 1 of CPGPdiskDrvHooks.h
541bc3 //////////////////////////////////////////////////////////////////////////////
aeffbc // CPGPdiskDrvHooks.h
d0465d //
f512e1 // Declarations for CPGPdiskDrvHooks.cpp.
b81bc3 //////////////////////////////////////////////////////////////////////////////
4aaf5a
41b9de // $Id: CPGPdiskDrvHooks.h,v 1.1.2.6 1998/07/06 08:58:10 nryan Exp $
04af5a
39cbce // Copyright (C) 1998 by Network Associates, Inc.
8971ae // All rights reserved.
c5af5a
935140 #ifndef Included_CPGPdiskDrvHooks_h¤// [
714ac6 #define Included_CPGPdiskDrvHooks_h
96af5a
b1af5a
1009b7 ////////////
0ae738 // Constants
dc09b7 ////////////
8caf5a
530b30 // From Winuser.h.
9eaf5a
c9001b #define WM_DEVICECHANGE 0x0219
ddaf5a
9a8bd1 // From "Dbt.h".
89af5a
873e6d #define DBT_VOLLOCKQUERYLOCK 0x8041
a4af5a
08af5a
f0d557 ////////
a102c9 // Types
39d557 ////////
61af5a
598bd1 // From "Dbt.h".
e2af5a
749d0f typedef struct _DEV_BROADCAST_HDR
f2bb36 {
6da505 ¤   DWORD¤  dbch_size;
6390a9 ¤   DWORD¤  dbch_devicetype;
d3b198 ¤   DWORD¤  dbch_reserved;
9daf5a
a73045 } DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR;
50af5a
4beee6 typedef struct VolLockBroadcast
52bb36 {
5cb1f4 ¤   struct¤ _DEV_BROADCAST_HDR vlb_dbh;
c5dfe8 ¤   DWORD¤  vlb_owner;¤ ¤   // thread on which lock request is being issued
6a6577 ¤   BYTE¤   vlb_perms;¤ ¤   // lock permission flags defined below
ed5ea8 ¤   BYTE¤   vlb_lockType;¤  // type of lock
874025 ¤   BYTE¤   vlb_drive;¤ ¤   // drive on which lock is issued
657b9b ¤   BYTE¤   vlb_flags;¤ ¤   // miscellaneous flags
eaaf5a
26b30e } VolLockBroadcast, *pVolLockBroadcast;
f5af5a
5b364f #endif¤ // ] Included_CPGPdiskDrvHooks_h
--9cea 000a5331be540110121 Page 1 of CPGPdiskDrvIos.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
32e139 // CPGPdiskDrvIos.cpp
3b465d //
81e6ca // Contains the AEP and IOS request handling routines for the driver.
f71bc3 //////////////////////////////////////////////////////////////////////////////
26af5a
f0777d // $Id: CPGPdiskDrvIos.cpp,v 1.2.2.14.2.1 1998/10/30 22:49:17 nryan Exp $
5eaf5a
50cbce // Copyright (C) 1998 by Network Associates, Inc.
4971ae // All rights reserved.
07af5a
a906a9 #include <vtoolscp.h>
13af5a
799bcf #include "Required.h"
b295bf #include "CPGPdiskDrvIos.h"
95555c #include "GenericCallback.h"
a7c411 #include "Globals.h"
3fc2bc #include "IopProcessor.h"
f12561 #include "Volume.h"
feaf5a
9386d2 #include LOCKED_CODE_SEGMENT
db5269 #include LOCKED_DATA_SEGMENT
9faf5a
84af5a
e109b7 ////////////
2be738 // Constants
8409b7 ////////////
cfaf5a
8eb601 // The following three constants are used to initialize three fields of each
b199e3 // DCB during initialization.
51af5a
4c08d7 static LPCSTR¤  kVendorId¤  = "PGP ····";¤  ¤   ¤   ¤   // vendor ID
9946a6 static LPCSTR¤  kProductId¤ = "PGPdisk ········";¤  ¤   // product ID
61b655 static LPCSTR¤  kRevLevel¤  = "0001";¤  ¤   ¤   ¤   ¤   // revision level
61af5a
49c58e const PGPUInt32¤kSizeVendorId¤  ¤   = 8;¤   // must be 8 bytes
709555 const PGPUInt32¤kSizeProductId¤ ¤   = 16;¤  // must be 16 bytes
5aeea5 const PGPUInt32¤kSizeRevLevel¤  ¤   = 4;¤   // must be 4 bytes
d1bb32 const PGPUInt32¤kDefaultIopTimeout¤ = 15;¤  // seconds for IOP to timeout
d5af5a
1a42a6 const PGPUInt32¤kContextToggleSeconds¤  = 5;
956624 const PGPUInt32¤kContextVerifySeconds¤  = 5;
61af5a
a3af5a
35512c ////////////////////////////////
fd5045 // AEP message handling routines
40512c ////////////////////////////////
e6af5a
4a4a2f // The AepInitialize packet is recieved once during IOS registration for the
785d24 // driver. It is responsible for creating a DDB for the driver (which the IOS
f0e00e // requires).
33af5a
17411c PGPUInt16·
261c14 CPGPdiskDrv::AepInitialize(PAEP_bi_init pAep)
fcbb36 {
25b35f ¤   if (mTheDDB = IspCreateDdb(sizeof(IOSDDB), NULL))
0b2cad ¤   ¤   return AEP_SUCCESS;
d50e24 ¤   else
eac3ee ¤   ¤   return AEP_FAILURE;
22efe6 }
81af5a
540479 // AepDeviceInquiry is called a number of times during IOS registration, an
166444 // each time we respond with AEP_SUCCESS the IOS allocates a DCB for us. We
896a21 // want as many DCBs as there can be PGPdisks mounted at one time.
48af5a
c9411c PGPUInt16·
9b4d58 CPGPdiskDrv::AepDeviceInquiry(PAEP_inquiry_device pAEP)
57bb36 {
acd9db ¤   PDCB pDcb;
48af5a
fb2691 ¤   pDcb = (PDCB) pAEP->AEP_i_d_dcb;
a5a603 ¤   pgpAssertAddrValid(pDcb, DCB);
--b371 000148bdc4d40110121 Page 2 of CPGPdiskDrvIos.cpp
e0af5a
35bc3d ¤   if (pDcb->DCB_unit_on_ctl >= kMaxMountedPGPdisks)
768f78 ¤   ¤   return AEP_NO_MORE_DEVICES;
1caf5a
a5e581 ¤   // The following three statements copy several required identification
1153f7 ¤   // strings into the appropriate fields of the DCB.
06af5a
f9161e ¤   pgpCopyMemory(kVendorId, pDcb->DCB_vendor_id, kSizeVendorId);
ff7aa5 ¤   pgpCopyMemory(kProductId, pDcb->DCB_product_id, kSizeProductId);
a1741a ¤   pgpCopyMemory(kRevLevel, pDcb->DCB_rev_level, kSizeRevLevel);
f2af5a
9fdac8 ¤   return AEP_SUCCESS;
cfefe6 }
90af5a
64fa43 // AepConfigDcb is called the same number of times AepDeviceInquiry is called,
68d16b // once for each DCB. The driver takes this opportunity to add the DCB to the
2af13f // global list, initialize it, and add the I/O request routine to the DCB's
e29fca // calldown table. That means that we will be responsible for any I/O
568f13 // involving any volume we mount using this DCB at any time in the future.
fcaf5a
22411c PGPUInt16·
ad4635 CPGPdiskDrv::AepConfigDcb(PAEP_dcb_config pAep)
a9bb36 {
c8d9db ¤   PDCB pDcb;
11af5a
ceb698 ¤   pDcb = (PDCB) pAep->AEP_d_c_dcb;
1ea603 ¤   pgpAssertAddrValid(pDcb, DCB);
c8af5a
d555b8 ¤   // Before we configure the DCB we must check to make sure it is actually
f5344c ¤   // one of ours. We do this by checking that it is a physical, not logical,
8abf13 ¤   // DCB, and that the vendor ID matches ours.
9aaf5a
08e66f ¤   if (IsPhysical(pDcb) &&
d0a3cf ¤   ¤   (!strncmp((LPCSTR) pDcb->DCB_vendor_id, kVendorId, kSizeVendorId)))
0dc7a1 ¤   {
a58644 ¤   ¤   // Add the DCB to the global list and initialize it.
ac88ac ¤   ¤   mDcbs.AddDcb(pDcb);
97af5a
7e5eb3 ¤   ¤   // Now we insert the driver's IO request handler routines into the
1003ca ¤   ¤   // calldown table for this DCB. In short, that means we are saying we
a43ed4 ¤   ¤   // wish to intercept and possibly handle all IO requests for this
d8c17a ¤   ¤   // potential volume.
14af5a
4e6d36 ¤   ¤   if (!IspInsertCalldown(pDcb, PGPDISK_RequestHandlerStub,·
0a09a7 ¤   ¤   ¤   (PDDB) pAep->AEP_d_c_hdr.AEP_ddb, 0, pDcb->DCB_cmn.DCB_dmd_flags,·
8e0c78 ¤   ¤   ¤   pAep->AEP_d_c_hdr.AEP_lgn))
fc5b34 ¤   ¤   {
f552ca ¤   ¤   ¤   pgpDebugMsg("PGPdisk: IspInsertCalldown failed in AepDcbConfig");
976eb0 ¤   ¤   ¤   return AEP_FAILURE;
fd0fe4 ¤   ¤   }
559371 ¤   }
dfaf5a
786fd2 ¤   return AEP_SUCCESS;·
faefe6 }
1caf5a
46bbfe // AepIopTimeout is called whenever a timeout is issued on an IOP. If it is
93bb15 // one of ours, we just reset the timer (assuming that it's just waiting in
0a7481 // our queue).
5caf5a
0d411c PGPUInt16·
39683a CPGPdiskDrv::AepIopTimeout(PAEP_iop_timeout_occurred pAep)
52bb36 {
eef341 ¤   PGPUInt8¤   drive;
9fc33f ¤   PIOP¤   ¤   pIop;
22e6d3 ¤   PIOR¤   ¤   pIor;
6cc614 ¤   PGPdisk¤¤   *pPGD¤  = NULL;
bcaf5a
6b5050 ¤   pIop = (PIOP) pAep->AEP_i_t_o_iop;
de148e ¤   pgpAssertAddrValid(pIop, IOP);
0daf5a
deeccf ¤   pIor = &pIop->IOP_ior;
14b602 ¤   pgpAssertAddrValid(pIor, IOR);
--5f32 0003cccdf6140110121 Page 3 of CPGPdiskDrvIos.cpp
e0af5a
16d3ba ¤   // First see if this request is coming FROM a PGPdisk.
19bc6d ¤   if (pIor->IOR_private_client == kPGPdiskIopMagic)
f6ba93 ¤   ¤   DebugOut("PGPdisk: I/O from PGPdisk to a host drive timed-out.");
c7af5a
7aa753 ¤   // Now see if this request is going TO a PGPdisk.
f544aa ¤   drive = pIop->IOP_ior.IOR_vol_designtr;
45af5a
200a5c ¤   if (drive < kMaxDrives)
cac7a1 ¤   {
8e6923 ¤   ¤   pPGD = mPGPdisks.FindPGPdisk(drive);
129371 ¤   }
14af5a
82c8f6 ¤   // If so, reset the timer.
b165cb ¤   if (pPGD)
29c7a1 ¤   {
8467ab ¤   ¤   DebugOut("PGPdisk: Resetting timed-out I/O to a PGPdisk.");
29af5a
f9ddab ¤   ¤   pIop->IOP_timer = pIop->IOP_timer_orig;
412cad ¤   ¤   return AEP_SUCCESS;
539371 ¤   }
4f0e24 ¤   else
cec7a1 ¤   {
d7c3ee ¤   ¤   return AEP_FAILURE;
bf9371 ¤   }
3befe6 }
66af5a
2c25ac // AepOneSecondCallback performs certain operations that must occur each
96c375 // second at a safe time.
d6af5a
16a1ba VOID·
e6b45d __stdcall·
7522bf CPGPdiskDrv::AepOneSecondCallback(
b0bfb0 ¤   VMHANDLE¤   ¤   hVM,·
72518d ¤   THREADHANDLE¤   hThread,·
70d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
7b58d6 ¤   PCLIENT_STRUCT¤ pRegs)
57bb36 {
7451fe ¤   static PGPUInt32¤   lastToggleTime¤ = 0;
412a1c ¤   static PGPUInt32¤   lastVerifyTime¤ = 0;
fbaf5a
0823d6 ¤   // Increase the inactivity timer.
636d77 ¤   Driver->mSecondsInactive++;
7c67c5 ¤
0b0809 ¤   // If we are in 'unmount all mode', keep trying to unmount all until we
244bf0 ¤   // succeed.
1faf5a
18339f ¤   if (Driver->mUnmountAllMode)
83c7a1 ¤   {
2347ac ¤   ¤   DualErr derr;
f3af5a
7837f6 ¤   ¤   derr = Driver->UnmountAllPGPdisks(FALSE);
87496e ¤   ¤   Driver->mUnmountAllMode = !derr.IsntError();
ad9371 ¤   }
74af5a
e09462 ¤   // Flip contexts on all PGPdisks if this is the time to do so.
582c2d ¤   if (lastToggleTime++ > kContextToggleSeconds)
bcc7a1 ¤   {
71dc4b ¤   ¤   lastToggleTime = 0;
b36ee9 ¤   ¤   Driver->mPGPdisks.FlipAllContexts();
db9371 ¤   }
90af5a
88eb9f ¤   // Verify cipher contexts on all PGPdisks if this is the time to do so.
b7f23c ¤   if (lastVerifyTime++ > kContextVerifySeconds)
64c7a1 ¤   {
8af9b3 ¤   ¤   lastVerifyTime = 0;
4ccb2a ¤   ¤   Driver->mPGPdisks.ValidateAllCipherContexts();
679371 ¤   }
b5af5a
d1076a ¤   // If it is time to auto-unmount, we do so. We schedule the unmounts to
cf3c2a ¤   // occur during an appy-time callback.
3caf5a
--b90e 000a165bea340110121 Page 4 of CPGPdiskDrvIos.cpp
2cdde6 ¤   if ((Driver->mAutoUnmount) &&·
56a289 ¤   ¤   (Driver->mSecondsInactive > Driver->mUnmountTimeout*60))
0fc7a1 ¤   {
ff4391 ¤   ¤   Driver->mSecondsInactive = 0;
5dce75 ¤   ¤   Driver->UnmountAllPGPdisks();
709371 ¤   }
5defe6 }
28af5a
794a61 // AepOneSecond is called every one second. We schedule a callback to perform
2fd037 // necessary tasks at a safe time.
0faf5a
4e4846 PGPUInt16 ·····································································¶
ec6f47 ··············
f65361 CPGPdiskDrv::AepOneSecond()
bebb36 {
288883 ¤   static RestrictedEvent_THUNK callbackThunk;
ccaf5a
0c0b07 ¤   Call_Restricted_Event(0, NULL, PEF_WAIT_NOT_CRIT, NULL,·
c4cd9d ¤   ¤   AepOneSecondCallback, 0, &callbackThunk);
baaf5a
f0dac8 ¤   return AEP_SUCCESS;
0aefe6 }
b0af5a
63ba9d // PGPDISK_Aer is the asynchronous event handler for the driver. It is called
91dd6a // to handle AEP packets sent by the system that represent various events and
f1b2d9 // occurences, most importantly the sequence of events that result in
1d2bba // initialization of the DCBs needed for volume mounting.
2baf5a
4ca1ba VOID·
03d80e __cdecl·
28dae7 CPGPdiskDrv::PGPDISK_Aer(PAEP pAep)
f5bb36 {
7af4b3 ¤   pgpAssertAddrValid(pAep, AEP);
47af5a
d01131 ¤   if ((pAep->AEP_func != AEP_HALF_SEC) &&·
0dd71f ¤   ¤   (pAep->AEP_func != AEP_1_SEC))
46c7a1 ¤   {
c647bf ¤   ¤   DebugOut("PGPdisk: %s", Driver->GetAEPFunctionName(pAep->AEP_func));
a09371 ¤   }
d1af5a
8cb8e2 ¤   switch (pAep->AEP_func)
cac7a1 ¤   {
d881b0 ¤   case AEP_INITIALIZE:¤   ¤   ¤   // recieved during IOS registration
78c63b ¤   ¤   pAep->AEP_result = Driver->AepInitialize((PAEP_bi_init) pAep);
b42f68 ¤   ¤   break;
21af5a
25fd6e ¤   case AEP_CONFIG_DCB:¤   ¤   ¤   // recieved for each DCB we want allocated
e678fd ¤   ¤   pAep->AEP_result = Driver->AepConfigDcb((PAEP_dcb_config) pAep);
ad2f68 ¤   ¤   break;
64af5a
6fba46 ¤   case AEP_DEVICE_INQUIRY:¤   ¤   // rcvd to determine how many DCBs we want
bfba9d ¤   ¤   pAep->AEP_result = Driver->AepDeviceInquiry((PAEP_inquiry_device)·
34e8c0 ¤   ¤   ¤   pAep);
952f68 ¤   ¤   break;
a1af5a
5787ae ¤   case AEP_IOP_TIMEOUT:¤  ¤   ¤   // rcvd to notify driver of IOP timeout
b3d830 ¤   ¤   pAep->AEP_result = Driver->AepIopTimeout((PAEP_iop_timeout_occurred)·
ace8c0 ¤   ¤   ¤   pAep);
792f68 ¤   ¤   break;
98af5a
29e6f8 ¤   case AEP_1_SEC:¤¤   ¤   ¤   ¤   // notify us every half second
0d1cec ¤   ¤   pAep->AEP_result = Driver->AepOneSecond();
31af5a
dfc186 ¤   default:¤   ¤   ¤   ¤   ¤   ¤   // default by returning success
c5d488 ¤   ¤   pAep->AEP_result = AEP_SUCCESS;
932f68 ¤   ¤   break;
d59371 ¤   }
00efe6 }
4caf5a
65af5a
c5512c ////////////////////////////////
a1c489 // I/O request handling routines
--168f 001fe5dc8d140110121 Page 5 of CPGPdiskDrvIos.cpp
7d512c ////////////////////////////////
deaf5a
bceae0 // Due to an incredibly obscure interaction involving MSVC an optimization and
d6cb97 // an IOS bug (it passes IOP address on the stack, expected that value to be
58db7f // unaltered when the function returns - within local parameter storage no
04d48e // less!), IOS request handlers have to be called using a stub function.
c7af5a
0ba1ba VOID·
b4d80e __cdecl·
ecf160 CPGPdiskDrv::PGPDISK_RequestHandlerStub(PIOP pIop)
6ebb36 {
2b4d42 ¤   PGPDISK_RequestHandler(pIop);
d2efe6 }
30af5a
a3bcce // PGPDISK_RequestHandler passes the IOP to our IopProcessor for - you
7176e0 // guessed it - processing.
87af5a
f83361 void ·
ff3111 CPGPdiskDrv::PGPDISK_RequestHandler(PIOP pIop)
09bb36 {
00f97e ¤   Driver->mIopProcessor.ProcessIop(pIop);
feefe6 }
--002b 001e389849140110122 Page 1 of CPGPdiskDrvIos.h
541bc3 //////////////////////////////////////////////////////////////////////////////
4b8c72 // CPGPdiskDrvIos.h
bc465d //
bac84a // Declarations for CPGPdiskDrvIos.cpp.
e51bc3 //////////////////////////////////////////////////////////////////////////////
d1af5a
d5728e // $Id: CPGPdiskDrvIos.h,v 1.1.2.3 1998/07/06 08:58:11 nryan Exp $
8baf5a
46cbce // Copyright (C) 1998 by Network Associates, Inc.
af71ae // All rights reserved.
08af5a
69b766 #ifndef Included_CPGPdiskDrvIos_h¤  // [
793bee #define Included_CPGPdiskDrvIos_h
6aaf5a
911cb9 // Nothing needed here.
81af5a
e31bcb #endif¤ // ] Included_CPGPdiskDrvIos_h
--d4c0 000a331ce4440110123 Page 1 of CPGPdiskDrvVolumes.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
ece300 // CPGPdiskDrvVolumes.cpp
eb465d //
45f3f5 // Contains high-level functions for working with PGPdisks.
e51bc3 //////////////////////////////////////////////////////////////////////////////
89af5a
1e7aa7 // $Id: CPGPdiskDrvVolumes.cpp,v 1.2.2.17 1998/07/06 08:58:12 nryan Exp $
05af5a
22cbce // Copyright (C) 1998 by Network Associates, Inc.
9771ae // All rights reserved.
2caf5a
b306a9 #include <vtoolscp.h>
d5af5a
0c9bcf #include "Required.h"
2a7414 #include "PGPdiskHighLevelUtils.h"
6ebfe9 #include "UtilityFunctions.h"
96af5a
dc0982 #include "CPGPdiskDrvVolumes.h"
e5d539 #include "CPGPdiskDrvWinutils.h"
abc411 #include "Globals.h"
7aaf5a
3186d2 #include LOCKED_CODE_SEGMENT
bf5269 #include LOCKED_DATA_SEGMENT
9caf5a
eeaf5a
c890e1 //////////////////////////////////////
5414d3 // Mount and unmount utility functions
f090e1 //////////////////////////////////////
c7af5a
1cdc63 // MountPGPdisk mounts the PGPdisk file specified by 'path' and returns the
2e4e85 // drive number it was mounted on.
caaf5a
362292 DualErr·
98256d CPGPdiskDrv::MountPGPdisk(
6a20cd ¤   LPCSTR¤ ¤   ¤   path,·
45fa54 ¤   CipherContext¤  *context,·
94f4ef ¤   PGPUInt8¤   ¤   drive,·
146fde ¤   PGPBoolean¤ ¤   mountReadOnly)
13bb36 {
73be41 ¤   DualErr¤¤   derr;
b9b4f5 ¤   PDCB¤   ¤   newDcb;
40ff2a ¤   PGPBoolean¤ addedPGPdisk, claimedDcb, createdPGPdiskObject, isPathLooped;
8d70f5 ¤   PGPdisk¤¤   *pPGD;
53af5a
84639f ¤   pgpAssertStrValid(path);
13d189 ¤   pgpAssertAddrValid(context, CipherContext);
9daf5a
81b87b ¤   addedPGPdisk = claimedDcb = createdPGPdiskObject = isPathLooped = FALSE;
67af5a
758534 ¤   // We must first check if we have space for another PGPdisk.
607570 ·¤  if (mPGPdisks.GetNumPGPdisks() >= kMaxMountedPGPdisks)
050c78 ¤   ¤   derr = DualErr(kPGDMinorError_MaxPGPdisksMounted);
f0af5a
213da7 ¤   // Search for any pre-existing PGPdisks corresponding to the path.
902361 ¤   if (derr.IsntError())
44c7a1 ¤   {
475964 ¤   ¤   if (mPGPdisks.FindPGPdisk(path))
a21bec ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskAlreadyMounted);
769371 ¤   }
4eaf5a
428730 ¤   // Validate the PGPdisk.
f72361 ¤   if (derr.IsntError())
f7c7a1 ¤   {
506d28 ¤   ¤   derr = ValidatePGPdisk(path);
269371 ¤   }
9daf5a
0fc89f ¤   // If the PGPdisk is opened by someone else with write access, fail.
6d2361 ¤   if (derr.IsntError())
cbc7a1 ¤   {
5dbc8f ¤   ¤   if (IsFileInUseByWriter(path))
b0f979 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskAlreadyInUse);
a39371 ¤   }
--2eb8 00096d094f940110123 Page 2 of CPGPdiskDrvVolumes.cpp
e0af5a
419296 ¤   // Create a new PGPdisk object.
e92361 ¤   if (derr.IsntError())
c4c7a1 ¤   {
c477f2 ¤   ¤   if (!(pPGD = new PGPdisk()))
5cb95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
10af5a
1a4bb0 ¤   ¤   createdPGPdiskObject = derr.IsntError();
9a9371 ¤   }
b167c5 ¤
ef2361 ¤   if (derr.IsntError())
b3c7a1 ¤   {
5aa7af ¤   ¤   derr = pPGD->mInitErr;
319371 ¤   }
e2af5a
fe1413 ¤   // We now claim a new DCB.
f22361 ¤   if (derr.IsntError())
d6c7a1 ¤   {
09a6c3 ¤   ¤   newDcb = mDcbs.ClaimDcb();
b4af5a
e73984 ¤   ¤   if (!newDcb)
15f680 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DcbClaimFailed);
5faf5a
cc50fc ¤   ¤   claimedDcb = derr.IsntError();
299371 ¤   }
ae67c5 ¤
a11cb8 ¤   // Attempt our mount.
422361 ¤   if (derr.IsntError())
12c7a1 ¤   {
d01d9e ¤   ¤   derr = pPGD->Mount(path, context, newDcb, drive, mountReadOnly);
359371 ¤   }
31af5a
f82361 ¤   if (derr.IsntError())
8dc7a1 ¤   {
688b7e ¤   ¤   // Attach the object to the global list.
170510 ¤   ¤   mPGPdisks.AddPGPdisk(pPGD);
2ad490 ¤   ¤   addedPGPdisk = TRUE;
00af5a
1f19d3 ¤   ¤   // Hook an ejection filter to the host.
c3b3ac ¤   ¤   if (!IsUNCPath(pPGD->GetPath()))
e9f91f ¤   ¤   ¤   derr = HookEjectionFilter(pPGD->GetLocalHostDrive());
ed9371 ¤   }
02af5a
681501 ¤   // Cleanup if an error occurred.
ef4bb3 ¤   if (derr.IsError())
cdc7a1 ¤   {
526d96 ¤   ¤   if (addedPGPdisk)
795b34 ¤   ¤   {
f8198f ¤   ¤   ¤   mPGPdisks.RemovePGPdisk(pPGD);
460fe4 ¤   ¤   }
caaf5a
723545 ¤   ¤   if (createdPGPdiskObject)
925b34 ¤   ¤   {
e74400 ¤   ¤   ¤   if (pPGD->Mounted())
1ecb2c ¤   ¤   ¤   ¤   pPGD->Unmount();
99af5a
ef4a02 ¤   ¤   ¤   delete pPGD;
4a0fe4 ¤   ¤   }
36af5a
476813 ¤   ¤   if (claimedDcb)
7a5b34 ¤   ¤   {
36ff8f ¤   ¤   ¤   mDcbs.ReleaseDcb(newDcb);
e70fe4 ¤   ¤   }
219371 ¤   }
b8af5a
4533e3 ¤   return derr;
14efe6 }
12af5a
5a41ad // UnmountPGPdisk unmounts the PGPdisk specified by 'drive'.
29af5a
212292 DualErr·
96f8e4 CPGPdiskDrv::UnmountPGPdisk(PGPUInt8 drive, PGPBoolean isThisEmergency)
--5b39 000c49c3fed40110123 Page 3 of CPGPdiskDrvVolumes.cpp
2cbb36 {
4bbe41 ¤   DualErr¤¤   derr;
953abe ¤   PDCB¤   ¤   oldDcb;
1253c6 ¤   PGPBoolean¤ removedPGPdisk¤ = FALSE;
f270f5 ¤   PGPdisk¤¤   *pPGD;
73c303 ¤   PGPUInt32¤  i¤  = 0;
83af5a
31aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
84af5a
276cf9 ¤   // First we verify that the PGPdisk exists and is mounted.
fd1495 ¤   if (IsNull(pPGD = mPGPdisks.FindPGPdisk(drive)))
795039 ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskNotMounted);
74af5a
c0699f ¤   // If IO is disabled to the drive, make this an emergency automatically.
2c2361 ¤   if (derr.IsntError())
40c7a1 ¤   {
286a22 ¤   ¤   if (!pPGD->IsIOEnabled())
f80a9a ¤   ¤   ¤   isThisEmergency = TRUE;
0a9371 ¤   }
3caf5a
07eeee ¤   // If I/O to this drive is in process, don't unmount. This OVERRIDES
1f9fcc ¤   // 'isThisEmergency'.
76af5a
392361 ¤   if (derr.IsntError())
50c7a1 ¤   {
277885 ¤   ¤   if (pPGD->IsUnmountPending())
3c0710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
ca9522 ¤   ¤   else if (mIopProcessor.IsDriveBusy(drive))
1935a3 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskIsBusy);
830e1d ¤   ¤   else
d1fcb6 ¤   ¤   ¤   pPGD->MarkUnmountPending(TRUE);
b39371 ¤   }
2faf5a
1cf94f ¤   // If this PGPdisk has other PGPdisks mounted on it, we must perform a
0fd34f ¤   // depth-first unmount of all those PGPdisks first.
beaf5a
edf3ae ¤   while (derr.IsntError())
40c7a1 ¤   {
4430c1 ¤   ¤   PGPdisk *pClient;
adaf5a
342663 ¤   ¤   if (!(pClient = Driver->mPGPdisks.EnumPGPdisks(i++)))
a8cdcb ¤   ¤   ¤   break;
37af5a
bc86f9 ¤   ¤   if (!IsUNCPath(pClient->GetPath()) &&
d4875d ¤   ¤   ¤   (pClient->GetLocalHostDrive() == drive))
c75b34 ¤   ¤   {
cc7c75 ¤   ¤   ¤   i = 0;
d3ac6c ¤   ¤   ¤   derr = UnmountPGPdisk(pClient->GetDrive(), isThisEmergency);
850fe4 ¤   ¤   }
d39371 ¤   }
b6af5a
4b06c3 ¤   // Check if the PGPdisk has open files.
d52361 ¤   if (derr.IsntError())
50c7a1 ¤   {
cecab7 ¤   ¤   if (pPGD->HasOpenFiles())
89ad7c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FilesOpenOnDrive);
63af5a
7ea271 ¤   ¤   if (isThisEmergency)
9ba3ec ¤   ¤   ¤   derr = DualErr::NoError;
d89371 ¤   }
abaf5a
db92df ¤   // Remove the object from the global list and attempt the unmount.
bc2361 ¤   if (derr.IsntError())
23c7a1 ¤   {
d817c3 ¤   ¤   mPGPdisks.RemovePGPdisk(pPGD);
4cb47f ¤   ¤   removedPGPdisk = TRUE;
20af5a
4adec3 ¤   ¤   oldDcb = pPGD->GetDcb();
3a040c ¤   ¤   derr = pPGD->Unmount(isThisEmergency);
849371 ¤   }
37af5a
c4996f ¤   // Release the previously claimed DCB.
--3126 0005252f1f740110123 Page 4 of CPGPdiskDrvVolumes.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
bfeca5 ¤   ¤   mDcbs.ReleaseDcb(oldDcb);
dffbd3 ¤   ¤   delete pPGD;
829371 ¤   }
bfaf5a
e6fe28 ¤   // Cleanup if an error occurred;
b74bb3 ¤   if (derr.IsError())
44c7a1 ¤   {
3b4d8f ¤   ¤   pPGD->MarkUnmountPending(FALSE);
cfaf5a
e5f1d6 ¤   ¤   if (removedPGPdisk && pPGD->Mounted())
d0c045 ¤   ¤   ¤   mPGPdisks.AddPGPdisk(pPGD);
879371 ¤   }
4aaf5a
f933e3 ¤   return derr;
59efe6 }
49af5a
4420f7 // UnmountAllPGPdisks unmounts all PGPdisks in the system.
79af5a
b02292 DualErr·
551ab5 CPGPdiskDrv::UnmountAllPGPdisks(PGPBoolean isThisEmergency)
a7bb36 {
add5ab ¤   DualErr¤¤   derr, storedDerr;
75f341 ¤   PGPUInt8¤   drive;
f7c303 ¤   PGPUInt32¤  i¤  = 0;
3c70f5 ¤   PGPdisk¤¤   *pPGD;
79af5a
6010ca ¤   // Note how we enumerate on position 0, and increase this only when we
548730 ¤   // find a drive we can't unmount for whatever reason. This is because
1118a5 ¤   // if a drive can't be unmounted it won't be removed, and thus 'sticks'
3886ea ¤   // at position 0, 1, etc.
0faf5a
2aae82 ¤   while (pPGD = mPGPdisks.EnumPGPdisks(i))
5dc7a1 ¤   {
c2132e ¤   ¤   pgpAssert(pPGD->Mounted());
5c96ff ¤   ¤   drive = pPGD->GetDrive();
14af5a
410812 ¤   ¤   // Now attempt the unmount.
4faa35 ¤   ¤   if (derr.IsntError())
fd5b34 ¤   ¤   {
f1f950 ¤   ¤   ¤   derr = UnmountPGPdisk(drive, isThisEmergency);
1c0fe4 ¤   ¤   }
97af5a
6dbfd5 ¤   ¤   // Remember only the first error we see.
14bdd6 ¤   ¤   if (derr.IsError())
7a5b34 ¤   ¤   {
b7ff83 ¤   ¤   ¤   if (storedDerr.IsntError())
6cf776 ¤   ¤   ¤   {
73d099 ¤   ¤   ¤   ¤   storedDerr = derr;
23a3a6 ¤   ¤   ¤   }
56af5a
07a3ec ¤   ¤   ¤   derr = DualErr::NoError;
9d81ec ¤   ¤   ¤   i++;
390fe4 ¤   ¤   }
609371 ¤   }
8faf5a
7cc19e ¤   return storedDerr;
a3efe6 }
15af5a
d24501 // UnmountAllPGPdisksCallback is scheduled to unmount all PGPdisk at a safe
2b1848 // time.
b4af5a
57a1ba VOID·
7cb45d __stdcall·
8137fd CPGPdiskDrv::UnmountAllPGPdisksCallback(
3cbfb0 ¤   VMHANDLE¤   ¤   hVM,·
d8518d ¤   THREADHANDLE¤   hThread,·
57d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
0458d6 ¤   PCLIENT_STRUCT¤ pRegs)
0cbb36 {
52be41 ¤   DualErr¤¤   derr;
--74c6 00140f20aa940110123 Page 5 of CPGPdiskDrvVolumes.cpp
a0c400 ¤   PGPBoolean¤ warnIfUnmountsFail¤ = (PGPBoolean) Refdata;
baaf5a
4b78c8 ¤   derr = Driver->UnmountAllPGPdisks(FALSE);
acaf5a
22fb0f ¤   if (derr.IsError() && warnIfUnmountsFail)
99c7a1 ¤   {
bff63d ¤   ¤   Driver->ReportError(kPGDMajorError_PGPdiskUnmountAllFailed, derr);
289371 ¤   }
4befe6 }
d2af5a
71b93b // UnmountAllPGPdisksSafely schedules a callback to unmount all PGPdisks at a
7e6fce // safe time.
dcaf5a
fac823 void·
ff1b73 CPGPdiskDrv::UnmountAllPGPdisksSafely(PGPBoolean warnIfUnmountsFail)
a5bb36 {
0e8883 ¤   static RestrictedEvent_THUNK callbackThunk;
52af5a
e0257c ¤   Call_Restricted_Event(0, NULL, PEF_WAIT_NOT_CRIT,·
9df843 ¤   ¤   (PVOID) warnIfUnmountsFail, UnmountAllPGPdisksCallback, 0,·
03028c ¤   ¤   &callbackThunk);
40efe6 }
--b11a 001e30b630d40110124 Page 1 of CPGPdiskDrvVolumes.h
541bc3 //////////////////////////////////////////////////////////////////////////////
85ecda // CPGPdiskDrvVolumes.h
00465d //
48194b // Declarations for CPGPdiskDrvVolumes.cpp.
f51bc3 //////////////////////////////////////////////////////////////////////////////
55af5a
921354 // $Id: CPGPdiskDrvVolumes.h,v 1.1.2.3 1998/07/06 08:58:13 nryan Exp $
ebaf5a
c2cbce // Copyright (C) 1998 by Network Associates, Inc.
2471ae // All rights reserved.
93af5a
a45cf1 #ifndef Included_CPGPdiskDrvVolumes_h¤  // [
f9c7fb #define Included_CPGPdiskDrvVolumes_h
1eaf5a
951cb9 // Nothing needed here.
3caf5a
e325c4 #endif¤ // ] Included_CPGPdiskDrvVolumes_h
--3fcb 000995673ea40110125 Page 1 of CPGPdiskDrvWinutils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
d77f37 // CPGPdiskDrvWinutils.cpp
56465d //
703cac // Contains utility functions for making interrupt calls to Windows/DOS.
661bc3 //////////////////////////////////////////////////////////////////////////////
3aaf5a
83f737 // $Id: CPGPdiskDrvWinutils.cpp,v 1.1.2.16.2.1 1998/09/01 00:31:46 nryan Exp $
8aaf5a
6dcbce // Copyright (C) 1998 by Network Associates, Inc.
f671ae // All rights reserved.
13af5a
1c06a9 #include <vtoolscp.h>
35af5a
f99bcf #include "Required.h"
61bfe9 #include "UtilityFunctions.h"
e2af5a
5e9de2 #include "CPGPdiskDrv.h"
39d539 #include "CPGPdiskDrvWinutils.h"
02af5a
aa86d2 #include LOCKED_CODE_SEGMENT
9f5269 #include LOCKED_DATA_SEGMENT
08af5a
2aaf5a
5d09b7 ////////////
abe738 // Constants
ae09b7 ////////////
34af5a
180402 // The following are file attribute flags returned by R0_GetFileAttributes.
bdaf5a
89e020 const PGPUInt16 _A_NORMAL¤  = 0x0000;¤  ¤   // normal file
83a23a const PGPUInt16 _A_RDONLY¤  = 0x0001;¤  ¤   // read-only
bea5c6 const PGPUInt16 _A_HIDDEN¤  = 0x0002;¤  ¤   // hidden
cd6275 const PGPUInt16 _A_SYSTEM¤  = 0x0004;¤  ¤   // system
bfc671 const PGPUInt16 _A_ARCH¤¤   = 0x0020;¤  ¤   // special OS file (?)
acaf5a
b12369 // The following are from the DDK.
bfaf5a
519d32 #define LOCKP_ALLOW_WRITES¤ ¤   0x01¤   // Bit 0 set - allow writes
3883b1 #define LOCKP_FAIL_WRITES¤  ¤   0x00¤   // Bit 0 clear - fail writes
ac36c2 #define LOCKP_FAIL_MEM_MAPPING¤ 0x02¤   // Bit 1 set - fail memory mappings
f25c05 #define LOCKP_ALLOW_MEM_MAPPING¤0x00¤   // Bit 1 clear - allow memory mappings
3996aa #define LOCKP_USER_MASK¤¤   ¤   0x03¤   // Mask for user lock flags
47cdd4 #define LOCKP_LOCK_FOR_FORMAT¤  0x04¤   // Level 0 lock for format
70af5a
1daf5a
6190e1 //////////////////////////////////////
aef830 // Functions for performing interrupts
d590e1 //////////////////////////////////////
b6af5a
4b857d // DoWinInt simulates a DOS interrupt.
2eaf5a
a477be PGPBoolean·
4da2e7 CPGPdiskDrv::DoWinInt(PGPUInt8 interrupt, ALLREGS *pAllRegs)
e0bb36 {
a7942e ¤   pgpAssertAddrValid(pAllRegs, ALLREGS);
d2af5a
6d573f ¤   // Execute the interrupt.
2f2549 ¤   Exec_VxD_Int(interrupt, pAllRegs);
b3af5a
1ddcaa ¤   return (pAllRegs->RFLAGS & 0x0001 ? FALSE : TRUE);
5fefe6 }
18af5a
40af5a
afb352 //////////////////////////
ee6e7e // Drive locking functions
5bb352 //////////////////////////
6aaf5a
3a2311 // GetLockLevel returns the level of the lock on the given drive.
a1af5a
218878 LockLevel·
273f1b CPGPdiskDrv::GetLockLevel(PGPUInt8 drive)
99bb36 {
--0384 00014e9724640110125 Page 2 of CPGPdiskDrvWinutils.cpp
e4b308 ¤   PGPInt32¤   pLockType;
940052 ¤   PGPUInt32¤  pLockFlags, pLockOwner;
80af5a
1295fb ¤   pgpAssert(drive < kMaxDrives);
a2af5a
8570f3 ¤   IFSMgr_GetLockState(drive, (PGPUInt32 *) &pLockType, &pLockFlags,·
69f870 ¤   ¤   &pLockOwner);
aaaf5a
e547a9 ¤   switch (pLockType)
6cc7a1 ¤   {
a8e379 ¤   case -1:
9a0921 ¤   ¤   return kLock_None;
dbf86f ¤   case 0:
c86610 ¤   ¤   return (pLockFlags & LOCKP_LOCK_FOR_FORMAT ? kLock_L0MR : kLock_L0);
33a2b3 ¤   case 1:
7759c1 ¤   ¤   return kLock_L1;
3b4dd7 ¤   case 2:
96b6a5 ¤   ¤   return kLock_L2;
c1170b ¤   case 3:
0dec79 ¤   ¤   return kLock_L3;
1caf5a
412f72 ¤   default:
bd8f52 ¤   ¤   pgpAssert(FALSE);
5a0921 ¤   ¤   return kLock_None;
ff9371 ¤   }
b6efe6 }
21af5a
25bb70 // AcquireLogicalVolLock gets a lock of the specified level on the specified
67c60c // drive, increasing or decreasing the lock level as needed. It doesn't
bc8ffb // handle L0 locks.
f2af5a
fd2292 DualErr·
7863cb CPGPdiskDrv::AcquireLogicalVolLock(
2a7fa2 ¤   PGPUInt8¤   drive,·
d1f112 ¤   LockLevel¤  lock,·
3e910b ¤   PGPUInt8¤   permissions)
9ebb36 {
5d7a76 ¤   ALLREGS¤¤   allRegs;
d7be41 ¤   DualErr¤¤   derr;
57ecb2 ¤   LockLevel¤  curLock;
9daf5a
296144 ¤   pgpAssert(lock != kLock_L0);
77aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
acaf5a
0348bc ¤   // Make sure we aren't trying to alter a level-0 lock.
30aed3 ¤   curLock = GetLockLevel(drive);
11af5a
d2b10b ¤   if (curLock == kLock_L0)
20d52d ¤   ¤   derr = DualErr(kPGDMinorError_LockVolumeFailed);
2faf5a
7dbe3b ¤   DebugOut("PGPdisk: Want lock %d on drive %u curlock %d", lock, drive,·
bcf4cf ¤   ¤   curLock);
12af5a
678430 ¤   // Since there is a special call to acquire a L1 lock, we do this first
3347dc ¤   // before anything else.
7daf5a
882361 ¤   if (derr.IsntError())
93c7a1 ¤   {
d5031c ¤   ¤   if ((curLock == kLock_None) && (lock != kLock_None))
385b34 ¤   ¤   {
6c01c8 ¤   ¤   ¤   curLock = kLock_L1;
b8af5a
53d046 ¤   ¤   ¤   allRegs.REAX¤   = 0x440D;¤  ¤   ¤   ¤   // function 440D
09c457 ¤   ¤   ¤   allRegs.REBX¤   = 0x0100 + drive + 1;¤  // first get L1 lock
4aca49 ¤   ¤   ¤   allRegs.RECX¤   = 0x084A;¤  ¤   ¤   ¤   // (Lock Volume)
8a4ae8 ¤   ¤   ¤   allRegs.REDX¤   = permissions;¤ ¤   ¤   // locking permissions
84bee2 ¤   ¤   ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   ¤   // carry cleared if error
85af5a
ea8fb7 ¤   ¤   ¤   mLockInProgress = TRUE;
331a50 ¤   ¤   ¤   mDriveBeingLocked = drive;
4aaf5a
14cd0d ¤   ¤   ¤   if (!DoWinInt(0x21, &allRegs))
--19aa 0000487005f40110125 Page 3 of CPGPdiskDrvWinutils.cpp
554d9f ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);
5caf5a
4df0f8 ¤   ¤   ¤   mLockInProgress = FALSE;
bc0fe4 ¤   ¤   }
409371 ¤   }
24af5a
fbaab1 ¤   // Now we calculate how many lock levels we need to go up or down.
832361 ¤   if (derr.IsntError())
acc7a1 ¤   {
75dfef ¤   ¤   PGPUInt8¤   locksUp¤¤   = 0;
e06c65 ¤   ¤   PGPUInt8¤   locksDown¤  = 0;
3faf5a
d6893f ¤   ¤   if (curLock != lock)
195b34 ¤   ¤   {
af48b3 ¤   ¤   ¤   switch (curLock)
dbf776 ¤   ¤   ¤   {
0c15c2 ¤   ¤   ¤   case kLock_L1:
e87f72 ¤   ¤   ¤   ¤   switch (lock)
fb72c3 ¤   ¤   ¤   ¤   {
0e1514 ¤   ¤   ¤   ¤   case kLock_None:
1d2f37 ¤   ¤   ¤   ¤   ¤   locksDown = 1;
ce14c3 ¤   ¤   ¤   ¤   ¤   break;
76ee8e ¤   ¤   ¤   ¤   case kLock_L2:
21e122 ¤   ¤   ¤   ¤   ¤   locksUp = 1;
d914c3 ¤   ¤   ¤   ¤   ¤   break;
86b452 ¤   ¤   ¤   ¤   case kLock_L3:
510e46 ¤   ¤   ¤   ¤   ¤   locksUp = 2;
bf14c3 ¤   ¤   ¤   ¤   ¤   break;
e36ab9 ¤   ¤   ¤   ¤   default:
69de7d ¤   ¤   ¤   ¤   ¤   pgpAssert(FALSE);
9e14c3 ¤   ¤   ¤   ¤   ¤   break;
322613 ¤   ¤   ¤   ¤   }
28f622 ¤   ¤   ¤   ¤   break;
41af5a
a5faa6 ¤   ¤   ¤   case kLock_L2:
8f7f72 ¤   ¤   ¤   ¤   switch (lock)
7872c3 ¤   ¤   ¤   ¤   {
811514 ¤   ¤   ¤   ¤   case kLock_None:
56c053 ¤   ¤   ¤   ¤   ¤   locksDown = 2;
d514c3 ¤   ¤   ¤   ¤   ¤   break;
a901ea ¤   ¤   ¤   ¤   case kLock_L1:
f92f37 ¤   ¤   ¤   ¤   ¤   locksDown = 1;
7114c3 ¤   ¤   ¤   ¤   ¤   break;
b7b452 ¤   ¤   ¤   ¤   case kLock_L3:
b8e122 ¤   ¤   ¤   ¤   ¤   locksUp = 1;
2514c3 ¤   ¤   ¤   ¤   ¤   break;
856ab9 ¤   ¤   ¤   ¤   default:
c7de7d ¤   ¤   ¤   ¤   ¤   pgpAssert(FALSE);
5314c3 ¤   ¤   ¤   ¤   ¤   break;
4b2613 ¤   ¤   ¤   ¤   }
22f622 ¤   ¤   ¤   ¤   break;
c6af5a
a1a07a ¤   ¤   ¤   case kLock_L3:
f37f72 ¤   ¤   ¤   ¤   switch (lock)
0272c3 ¤   ¤   ¤   ¤   {
951514 ¤   ¤   ¤   ¤   case kLock_None:
0b9a8f ¤   ¤   ¤   ¤   ¤   locksDown = 3;
2214c3 ¤   ¤   ¤   ¤   ¤   break;
e301ea ¤   ¤   ¤   ¤   case kLock_L1:
ccc053 ¤   ¤   ¤   ¤   ¤   locksDown = 2;
7014c3 ¤   ¤   ¤   ¤   ¤   break;
7aee8e ¤   ¤   ¤   ¤   case kLock_L2:
192f37 ¤   ¤   ¤   ¤   ¤   locksDown = 1;
0014c3 ¤   ¤   ¤   ¤   ¤   break;
a26ab9 ¤   ¤   ¤   ¤   default:
33de7d ¤   ¤   ¤   ¤   ¤   pgpAssert(FALSE);
1014c3 ¤   ¤   ¤   ¤   ¤   break;
532613 ¤   ¤   ¤   ¤   }
60f622 ¤   ¤   ¤   ¤   break;
71af5a
f66ab9 ¤   ¤   ¤   ¤   default:
04de7d ¤   ¤   ¤   ¤   ¤   pgpAssert(FALSE);
--da21 000d51412c840110125 Page 4 of CPGPdiskDrvWinutils.cpp
f014c3 ¤   ¤   ¤   ¤   ¤   break;
caa3a6 ¤   ¤   ¤   }
0c0fe4 ¤   ¤   }
03af5a
84b000 ¤   ¤   // If we need to get locks, we do that here.
251828 ¤   ¤   while (derr.IsntError() && (locksUp != 0))
ed5b34 ¤   ¤   {
b41450 ¤   ¤   ¤   PGPUInt16 lockValue;
c1af5a
6f6b5d ¤   ¤   ¤   locksUp--;
18af5a
386de9 ¤   ¤   ¤   if (curLock == kLock_L1)
f9f776 ¤   ¤   ¤   {
f56550 ¤   ¤   ¤   ¤   curLock = kLock_L2;
803e86 ¤   ¤   ¤   ¤   lockValue = 2;
b1a3a6 ¤   ¤   ¤   }
62bb8c ¤   ¤   ¤   else
98f776 ¤   ¤   ¤   {
7f3f8c ¤   ¤   ¤   ¤   curLock = kLock_L3;
8f645a ¤   ¤   ¤   ¤   lockValue = 3;
61a3a6 ¤   ¤   ¤   }
49af5a
17d046 ¤   ¤   ¤   allRegs.REAX¤   = 0x440D;¤  ¤   ¤   ¤   // function 440D
bdff31 ¤   ¤   ¤   allRegs.REBX¤   = (lockValue << 8) + drive + 1;¤// get next lock
3fca49 ¤   ¤   ¤   allRegs.RECX¤   = 0x084A;¤  ¤   ¤   ¤   // (Lock Volume)
215d3b ¤   ¤   ¤   allRegs.REDX¤   = 0;¤   ¤   ¤   ¤   ¤   // > L1s expect zero here
4bbee2 ¤   ¤   ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   ¤   // carry cleared if error
f5af5a
fb8fb7 ¤   ¤   ¤   mLockInProgress = TRUE;
991a50 ¤   ¤   ¤   mDriveBeingLocked = drive;
43af5a
87cd0d ¤   ¤   ¤   if (!DoWinInt(0x21, &allRegs))
164d9f ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);
e3af5a
c2f0f8 ¤   ¤   ¤   mLockInProgress = FALSE;
d20fe4 ¤   ¤   }
b0af5a
b7c48c ¤   ¤   // If we need to release locks, we do that here.
bcad44 ¤   ¤   while (derr.IsntError() && (locksDown !=0))
c75b34 ¤   ¤   {
fe8774 ¤   ¤   ¤   locksDown--;
aeaf5a
7ad851 ¤   ¤   ¤   if (curLock == kLock_L3)
6d6550 ¤   ¤   ¤   ¤   curLock = kLock_L2;
52cfaa ¤   ¤   ¤   else if (curLock == kLock_L2)
8e8a34 ¤   ¤   ¤   ¤   curLock = kLock_L1;
5620ce ¤   ¤   ¤   else if (curLock == kLock_L1)
1fef87 ¤   ¤   ¤   ¤   curLock = kLock_None;
0daf5a
cfb576 ¤   ¤   ¤   allRegs.REAX¤   = 0x440D;¤  ¤   // function 440D
e7194d ¤   ¤   ¤   allRegs.REBX¤   = drive + 1;¤   // decrement lock level
b8739a ¤   ¤   ¤   allRegs.RECX¤   = 0x086A;¤  ¤   // code 6A (Unlock Volume)
c4d7f5 ¤   ¤   ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   // carry flag cleared on err
f4af5a
95cd0d ¤   ¤   ¤   if (!DoWinInt(0x21, &allRegs))
33f776 ¤   ¤   ¤   {
f417fc ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UnlockVolumeFailed,·
c40222 ¤   ¤   ¤   ¤   ¤   allRegs.REAX);
83a3a6 ¤   ¤   ¤   }
a40fe4 ¤   ¤   }
be9371 ¤   }
fcaf5a
d7e29e ¤   DebugOut("PGPdisk: Lock on drive %u is now %d", drive,·
80ee26 ¤   ¤   GetLockLevel(drive));
6faf5a
9733e3 ¤   return derr;
7befe6 }
03af5a
91b108 // GetFormatLockOnDrive locks the specified drive for formatting.
f7af5a
122292 DualErr·
d563f5 CPGPdiskDrv::GetFormatLockOnDrive(PGPUInt8 drive)
--0500 0003133081140110125 Page 5 of CPGPdiskDrvWinutils.cpp
2cbb36 {
5e7a76 ¤   ALLREGS¤¤   allRegs;
25be41 ¤   DualErr¤¤   derr;
eb4535 ¤   PGPUInt32¤  locksTaken¤ = 0;
34af5a
84aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
25af5a
b4c05e ¤   // Make sure we aren't already locked;
569ffa ¤   if (GetLockLevel(drive) != kLock_None)
3cd52d ¤   ¤   derr = DualErr(kPGDMinorError_LockVolumeFailed);
d2af5a
c08f66 ¤   // First get a 'normal' level-0 lock.
eb2361 ¤   if (derr.IsntError())
46c7a1 ¤   {
065a03 ¤   ¤   allRegs.REAX¤   = 0x440D;¤  ¤   ¤   ¤   // function 440D
05e23f ¤   ¤   allRegs.REBX¤   = 0x0000 + drive + 1;¤  // L0 lock
85400c ¤   ¤   allRegs.RECX¤   = 0x084A;¤  ¤   ¤   ¤   // (Lock Volume)
c02921 ¤   ¤   allRegs.REDX¤   = 0;¤   ¤   ¤   ¤   ¤   // must be 0
7b9765 ¤   ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   ¤   // carry set if error
4daf5a
cd044b ¤   ¤   mLockInProgress = TRUE;
755ba3 ¤   ¤   mDriveBeingLocked = drive;
80af5a
c9c341 ¤   ¤   if (!DoWinInt(0x21, &allRegs))
f0a0b8 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);
2d0e1d ¤   ¤   else
00c10a ¤   ¤   ¤   locksTaken++;
a5af5a
7bcd90 ¤   ¤   mLockInProgress = FALSE;
4c9371 ¤   }
54af5a
87dc10 ¤   // Now get a 'more restrictive' level-0 lock.
862361 ¤   if (derr.IsntError())
15c7a1 ¤   {
3b5a03 ¤   ¤   allRegs.REAX¤   = 0x440D;¤  ¤   ¤   ¤   // function 440D
aae23f ¤   ¤   allRegs.REBX¤   = 0x0000 + drive + 1;¤  // L0 lock
4f400c ¤   ¤   allRegs.RECX¤   = 0x084A;¤  ¤   ¤   ¤   // (Lock Volume)
257aa5 ¤   ¤   allRegs.REDX¤   = 4;¤   ¤   ¤   ¤   ¤   // must be 4
fe9765 ¤   ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   ¤   // carry set if error
01af5a
dd044b ¤   ¤   mLockInProgress = TRUE;
555ba3 ¤   ¤   mDriveBeingLocked = drive;
e5af5a
74c341 ¤   ¤   if (!DoWinInt(0x21, &allRegs))
6aa0b8 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LockVolumeFailed, allRegs.REAX);
1e0e1d ¤   ¤   else
2dc10a ¤   ¤   ¤   locksTaken++;
13af5a
efcd90 ¤   ¤   mLockInProgress = FALSE;
0e9371 ¤   }
21af5a
82555b ¤   // Undo what we did on error.
c34bb3 ¤   if (derr.IsError())
54c7a1 ¤   {
733de3 ¤   ¤   while (locksTaken-- > 0)
c45b34 ¤   ¤   {
5fb576 ¤   ¤   ¤   allRegs.REAX¤   = 0x440D;¤  ¤   // function 440D
00194d ¤   ¤   ¤   allRegs.REBX¤   = drive + 1;¤   // decrement lock level
c4739a ¤   ¤   ¤   allRegs.RECX¤   = 0x086A;¤  ¤   // code 6A (Unlock Volume)
eac49a ¤   ¤   ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   // carry flag set on error
95af5a
a9d2ad ¤   ¤   ¤   DoWinInt(0x21, &allRegs);
dd0fe4 ¤   ¤   }
5f9371 ¤   }
4caf5a
5933e3 ¤   return derr;
6cefe6 }
eeaf5a
661804 // ReleaseFormatLockOnDrive release a formatting lock on the specified drive.
dcaf5a
e12292 DualErr·
311b4a CPGPdiskDrv::ReleaseFormatLockOnDrive(PGPUInt8 drive)
--266b 0008925dd0540110125 Page 6 of CPGPdiskDrvWinutils.cpp
2cbb36 {
5e7a76 ¤   ALLREGS¤¤   allRegs;
25be41 ¤   DualErr¤¤   derr;
e8f08d ¤   PGPUInt32¤  locksTaken¤ = 2;
9eaf5a
7baa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
f7af5a
7fd493 ¤   // Make sure we are already locked;
522807 ¤   if (GetLockLevel(drive) != kLock_L0MR)
ac8633 ¤   ¤   derr = DualErr(kPGDMinorError_UnlockVolumeFailed);
3caf5a
2564b1 ¤   // Release locks.
f8f0ae ¤   while (derr.IsntError() && (locksTaken-- > 0))
57c7a1 ¤   {
9993c3 ¤   ¤   allRegs.REAX¤   = 0x440D;¤  ¤   // function 440D
332423 ¤   ¤   allRegs.REBX¤   = drive + 1;¤   // decrement lock level
0d6016 ¤   ¤   allRegs.RECX¤   = 0x086A;¤  ¤   // code 6A (Unlock Volume)
4ed716 ¤   ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   // carry flag set on error
a2af5a
84c341 ¤   ¤   if (!DoWinInt(0x21, &allRegs))
53ed66 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UnlockVolumeFailed, allRegs.REAX);
b19371 ¤   }
59af5a
0333e3 ¤   return derr;
4eefe6 }
49af5a
beaf5a
bd9f73 /////////////////////////
fa3849 // File utility functions
7c9f73 /////////////////////////
c9af5a
4c0bc9 // IsFileInUseByReader returns TRUE if someone has opened the specified file
b0476d // with read access, FALSE otherwise.
27af5a
e277be PGPBoolean·
b8f014 CPGPdiskDrv::IsFileInUseByReader(LPCSTR path)
a9bb36 {
70fec2 ¤   File¤   existingFile;
15945d ¤   DualErr¤derr;
dfaf5a
93639f ¤   pgpAssertStrValid(path);
72af5a
95862d ¤   derr = existingFile.Open(path,·
a671ac ¤   ¤   kOF_ReadOnly | kOF_DenyRead | kOF_MustExist);
8caf5a
5812c1 ¤   if (existingFile.Opened())
00c7a1 ¤   {
971af7 ¤   ¤   existingFile.Close();
df9371 ¤   }
90af5a
fd8864 ¤   return derr.IsError();
7fefe6 }
88af5a
e22939 // IsFileInUseByWriter returns TRUE if someone has opened the specified file
32ad9f // with write access, FALSE otherwise.
6aaf5a
5877be PGPBoolean·
3f2142 CPGPdiskDrv::IsFileInUseByWriter(LPCSTR path)
e9bb36 {
0bfec2 ¤   File¤   existingFile;
ed945d ¤   DualErr¤derr;
60af5a
d9639f ¤   pgpAssertStrValid(path);
45af5a
59862d ¤   derr = existingFile.Open(path,·
185c1e ¤   ¤   kOF_ReadOnly | kOF_DenyWrite | kOF_MustExist);
7baf5a
f512c1 ¤   if (existingFile.Opened())
82c7a1 ¤   {
dd1af7 ¤   ¤   existingFile.Close();
f69371 ¤   }
89af5a
--7785 00035f8700640110125 Page 7 of CPGPdiskDrvWinutils.cpp
9b8864 ¤   return derr.IsError();
9cefe6 }
b6af5a
2e74d2 // IsFileInUseByWriter returns TRUE if someone has opened the specified file,
1e9a91 // FALSE otherwise.
33af5a
d577be PGPBoolean·
bc0b1a CPGPdiskDrv::IsFileInUse(LPCSTR path)
67bb36 {
ec639f ¤   pgpAssertStrValid(path);
d8af5a
27807e ¤   return (IsFileInUseByReader(path) || IsFileInUseByWriter(path));
a1efe6 }
0aaf5a
be8d67 // IsFileValid returns TRUE if the specified file exists.
a7af5a
6777be PGPBoolean·
a00c08 CPGPdiskDrv::IsFileValid(LPCSTR path)
2ebb36 {
dfd5b6 ¤   WORD attribs, error;
69af5a
3e639f ¤   pgpAssertStrValid(path);
30af5a
4d9ce0 ¤   if (R0_GetFileAttributes((LPSTR) path, &attribs, &error))
1c836c ¤   ¤   return TRUE;
160e24 ¤   else
1d98aa ¤   ¤   return FALSE;
63efe6 }
6baf5a
b57cc2 // GetFirstClustFile performs an IOCTL call to ask the system for the index
5a957e // of the first cluster corresponding to the given file on the given FAT
891bad // drive.
f7af5a
7b2292 DualErr·
b0285b CPGPdiskDrv::GetFirstClustFile(LPCSTR path, PGPUInt32 *firstClust)
d0bb36 {
317a76 ¤   ALLREGS¤¤   allRegs;
50be41 ¤   DualErr¤¤   derr;
35b6e2 ¤   LockLevel¤  oldLock;
d1b240 ¤   PGPBoolean¤ lockedDown¤ = FALSE;
eef341 ¤   PGPUInt8¤   drive;
55af5a
ed639f ¤   pgpAssertStrValid(path);
d7c676 ¤   pgpAssertAddrValid(firstClust, PGPBoolean);
0eaf5a
3ca5f2 ¤   drive = DriveLetToNum(path[0]);
1d66f5 ¤   oldLock = GetLockLevel(drive);
ddaf5a
682b11 ¤   allRegs.REAX¤   = 0x440D;¤  ¤   ¤   // function 440D
1d674f ¤   allRegs.REBX¤   = BCS_WANSI;¤   ¤   // character set of path
dce2db ¤   allRegs.RECX¤   = 0x0871;¤  ¤   ¤   // minor code 71 (Get First Cluster)
ad0e0e ¤   allRegs.REDX¤   = (PGPUInt32) path;¤// file path
ba78ff ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   // carry flag cleared on error
a167c5 ¤
2075b0 ¤   AcquireLogicalVolLock(drive, kLock_L3);
0fc276 ¤   lockedDown = TRUE;
14af5a
9c82b2 ¤   if (!DoWinInt(0x21, &allRegs))
2a23dd ¤   ¤   derr = DualErr(kPGDMinorError_GetFirstClustFailed, allRegs.REAX);
4faf5a
e6a30e ¤   if (lockedDown)
3517c1 ¤   ¤   AcquireLogicalVolLock(drive, oldLock);
bfaf5a
b02361 ¤   if (derr.IsntError())
1fc7a1 ¤   {
3f7553 ¤   ¤   (* firstClust) = MakeLong((PGPUInt16) allRegs.REAX, (PGPUInt16) allRegs¶
216b56 .REDX);
6e9371 ¤   }
ae67c5 ¤
2d33e3 ¤   return derr;
4defe6 }
35af5a
--5316 000c00a498b40110125 Page 8 of CPGPdiskDrvWinutils.cpp
a22483 // HasOpenFiles returns TRUE if the specified drive has open file handles,
ee9a91 // FALSE otherwise.
99af5a
462292 DualErr·
a1c9d0 CPGPdiskDrv::HasOpenFiles(PGPUInt8 drive, PGPBoolean *hasOpenFiles)
3ebb36 {
607a76 ¤   ALLREGS¤¤   allRegs;
4014f8 ¤   static char¤path[kMaxStringSize];
8bbe41 ¤   DualErr¤¤   derr;
9faf5a
1f3ede ¤   pgpAssertAddrValid(hasOpenFiles, PGPBoolean);
e9aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
4caf5a
932b11 ¤   allRegs.REAX¤   = 0x440D;¤  ¤   ¤   // function 440D
790476 ¤   allRegs.REBX¤   = drive + 1;¤   ¤   // drive to enumerate on
44a572 ¤   allRegs.RECX¤   = 0x086D;¤  ¤   ¤   // minor code 6D (Enum Open Files)
490e0e ¤   allRegs.REDX¤   = (PGPUInt32) path;¤// file path
abe653 ¤   allRegs.RESI¤   = 0;¤   ¤   ¤   ¤   // set index to 0 to get first file
16b65c ¤   allRegs.REDI¤   = 0;¤   ¤   ¤   ¤   // enumerate all kinds of files (0)
1b78ff ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   // carry flag cleared on error
a6af5a
79e5da ¤   // It is OK for this function to return an error since this is its
3d08f4 ¤   // documented behavior if there are no open files on the drive.
baaf5a
ba0ad6 ¤   DoWinInt(0x21, &allRegs);
eeaf5a
0c9acd ¤   // Note that FALSE is returned if the carry flag is sent, since this
32dd59 ¤   // means that there are no open files on the drive.
34af5a
5a2361 ¤   if (derr.IsntError())
34c7a1 ¤   {
16f6b8 ¤   ¤   (* hasOpenFiles) = ((allRegs.RFLAGS & 0x0001) ? FALSE : TRUE);
739371 ¤   }
2967c5 ¤
8d33e3 ¤   return derr;
78efe6 }
2eaf5a
e5af5a
42b474 //////////////////////////////
6b888a // Int21 file access functions
16b474 //////////////////////////////
bbaf5a
bb690d // Int21OpenFile opens a file using the Int21 interface.
7caf5a
fe2292 DualErr·
463c54 CPGPdiskDrv::Int21OpenFile(
9cf2f8 ¤   LPCSTR¤ ¤   path,·
1835a4 ¤   PGPUInt16¤  mode,·
b0105e ¤   PGPUInt16¤  attribs,·
e781ea ¤   PGPUInt16¤  action,·
1fe7f9 ¤   PGPUInt16¤  *pHandle)
69bb36 {
b67d0f ¤   ALLREGS¤allRegs;
8e945d ¤   DualErr¤derr;
d8af5a
0d639f ¤   pgpAssertStrValid(path);
89d818 ¤   pgpAssertAddrValid(pHandle, PGPUInt16);
6daf5a
812c06 ¤   mode |= OPEN_FLAGS_NOCRITERR;
79af5a
89cd46 ¤   allRegs.REAX¤   = 0x716C;¤  ¤   ¤   // function 716C
0f1926 ¤   allRegs.REBX¤   = mode;¤¤   ¤   ¤   // sharing and mode flags
3e17dd ¤   allRegs.RECX¤   = attribs;¤ ¤   ¤   // attribute flags
053918 ¤   allRegs.REDX¤   = action;¤  ¤   ¤   // action to take
382ad3 ¤   allRegs.RESI¤   = (PGPUInt32) path;¤// file path
2dbf2c ¤   allRegs.REDI¤   = 0;
d278ff ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   // carry flag cleared on error
6467c5 ¤
2682b2 ¤   if (!DoWinInt(0x21, &allRegs))
3f2d09 ¤   ¤   derr = DualErr(kPGDMinorError_R0OpenFailed, allRegs.REAX);
58af5a
c02361 ¤   if (derr.IsntError())
--24dd 0001d7670ba40110125 Page 9 of CPGPdiskDrvWinutils.cpp
f7c7a1 ¤   {
53dcd1 ¤   ¤   (* pHandle) = (PGPUInt16) allRegs.REAX;
7e9371 ¤   }
e467c5 ¤
2333e3 ¤   return derr;
1eefe6 }
a7af5a
eab198 // Int21CloseFile closes a file using the Int21 interface.
beaf5a
222292 DualErr·
019640 CPGPdiskDrv::Int21CloseFile(PGPUInt16 handle)
24bb36 {
4a7d0f ¤   ALLREGS¤allRegs;
3d945d ¤   DualErr¤derr;
8faf5a
a74a75 ¤   allRegs.REAX¤   = 0x3E00;¤  ¤   // function 3E
7f1f05 ¤   allRegs.REBX¤   = handle;¤  ¤   // handle to close
b2337b ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   // carry flag cleared on error
c6af5a
2682b2 ¤   if (!DoWinInt(0x21, &allRegs))
2965a4 ¤   ¤   derr = DualErr(kPGDMinorError_R0CloseFailed, allRegs.REAX);
bc67c5 ¤
7533e3 ¤   return derr;
a0efe6 }
51af5a
922e91 // Int21GetFileLength gets the length of a file.
62af5a
042292 DualErr·
55df30 CPGPdiskDrv::Int21GetFileLength(PGPUInt16 handle, PGPUInt32 *pLength)
a0bb36 {
657a76 ¤   ALLREGS¤¤   allRegs;
c1be41 ¤   DualErr¤¤   derr;
98af5a
fb1918 ¤   allRegs.REAX¤   = 0x4202;¤  ¤   // function 42
1fe009 ¤   allRegs.REBX¤   = handle;¤  ¤   // file handle
25e1bf ¤   allRegs.RECX¤   = 0;
ca4159 ¤   allRegs.REDX¤   = 0;
6f337b ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   // carry flag cleared on error
0baf5a
6682b2 ¤   if (!DoWinInt(0x21, &allRegs))
242d1d ¤   ¤   derr = DualErr(kPGDMinorError_R0GetFileSize, allRegs.REAX);
37af5a
122361 ¤   if (derr.IsntError())
71c7a1 ¤   {
cb9d71 ¤   ¤   (* pLength) = (allRegs.REDX << 16) | (allRegs.REAX & 0xFFFF);
9a9371 ¤   }
50af5a
0033e3 ¤   return derr;
20efe6 }
61af5a
68bf39 // Int21SetFilePos sets the position in a file.
aeaf5a
f82292 DualErr·
c3e196 CPGPdiskDrv::Int21SetFilePos(PGPUInt16 handle, PGPUInt32 pos)
67bb36 {
707a76 ¤   ALLREGS¤¤   allRegs;
d2be41 ¤   DualErr¤¤   derr;
caaf5a
ecaf90 ¤   allRegs.REAX¤   = 0x4200;¤  ¤   // function 42
3be009 ¤   allRegs.REBX¤   = handle;¤  ¤   // file handle
ac22ee ¤   allRegs.RECX¤   = pos >> 16;¤   // high word of pos
0c7d0b ¤   allRegs.REDX¤   = pos & 0xFFFF;¤// low word of pos
f2337b ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   // carry flag cleared on error
e0af5a
6282b2 ¤   if (!DoWinInt(0x21, &allRegs))
1ea1ed ¤   ¤   derr = DualErr(kPGDMinorError_R0SetFilePosFailed, allRegs.REAX);
4267c5 ¤
9933e3 ¤   return derr;
41efe6 }
15af5a
c135e3 // Int21ReadFileAux is a helper function for Int21ReadFile.
1daf5a
--735c 000139d2dec40110125 Page 10 of CPGPdiskDrvWinutils.cpp
782292 DualErr·
307d30 CPGPdiskDrv::Int21ReadFileAux(
4f0c2a ¤   PGPUInt16¤  handle,·
664f03 ¤   PGPUInt8¤   *buf,·
26cc42 ¤   PGPUInt16¤  nBytes)
8dbb36 {
cb7d0f ¤   ALLREGS¤allRegs;
78945d ¤   DualErr¤derr;
b0af5a
f9b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
53af5a
a4b537 ¤   allRegs.REAX¤   = 0x3F00;¤  ¤   ¤   // function 3F
6115d4 ¤   allRegs.REBX¤   = handle;¤  ¤   ¤   // file handle
68e0eb ¤   allRegs.RECX¤   = nBytes;¤  ¤   ¤   // number of bytes to read
c5e585 ¤   allRegs.REDX¤   = (PGPUInt32) buf;¤ // buffer
5678ff ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   // carry flag cleared on error
a2af5a
4482b2 ¤   if (!DoWinInt(0x21, &allRegs))
00884e ¤   ¤   derr = DualErr(kPGDMinorError_R0ReadFailed, allRegs.REAX);
01af5a
f433e3 ¤   return derr;
c3efe6 }
19af5a
1e81cb // Int21WriteFileAux is a helper function for Int21WriteFile.
58af5a
c12292 DualErr·
d531ba CPGPdiskDrv::Int21WriteFileAux(
2b0c2a ¤   PGPUInt16¤  handle,·
8a4f03 ¤   PGPUInt8¤   *buf,·
aacc42 ¤   PGPUInt16¤  nBytes)
acbb36 {
d47d0f ¤   ALLREGS¤allRegs;
8a945d ¤   DualErr¤derr;
33af5a
2db442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
07af5a
e849dc ¤   allRegs.REAX¤   = 0x4000;¤  ¤   ¤   // function 40
1115d4 ¤   allRegs.REBX¤   = handle;¤  ¤   ¤   // file handle
f5e0ac ¤   allRegs.RECX¤   = nBytes;¤  ¤   ¤   // number of bytes to write
52e585 ¤   allRegs.REDX¤   = (PGPUInt32) buf;¤ // buffer
3178ff ¤   allRegs.RFLAGS¤ = 0x0001;¤  ¤   ¤   // carry flag cleared on error
dfaf5a
a782b2 ¤   if (!DoWinInt(0x21, &allRegs))
c50d76 ¤   ¤   derr = DualErr(kPGDMinorError_R0WriteFailed, allRegs.REAX);
8e67c5 ¤
df33e3 ¤   return derr;
25efe6 }
51af5a
05797a // Int21ReadFile reads from a file.
ccaf5a
b22292 DualErr·
f86991 CPGPdiskDrv::Int21ReadFile(
750c2a ¤   PGPUInt16¤  handle,·
8f4f03 ¤   PGPUInt8¤   *buf,·
71f6dc ¤   PGPUInt32¤  pos,·
b6c26e ¤   PGPUInt32¤  nBytes)
4bbb36 {
7d7d36 ¤   DualErr derr;
87af5a
f9b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
dcaf5a
c06047 ¤   // Set the file position.
1be5a7 ¤   derr = Int21SetFilePos(handle, pos);
46af5a
9521fb ¤   // We must read in chunks.
6d2361 ¤   if (derr.IsntError())
6bc7a1 ¤   {
1d4a7a ¤   ¤   PGPUInt32 bufPos, bytesLeft;
90af5a
3aa8b4 ¤   ¤   bufPos = 0;
f18a27 ¤   ¤   bytesLeft = nBytes;
13af5a
--75c8 0009e15212940110125 Page 11 of CPGPdiskDrvWinutils.cpp
8fb80e ¤   ¤   while (derr.IsntError() && (bytesLeft > 0))
d85b34 ¤   ¤   {
b3d830 ¤   ¤   ¤   PGPUInt16 bytesToRead;
6887c7 ¤   ¤   ¤
4182d4 ¤   ¤   ¤   bytesToRead = (PGPUInt16) min(0x7000, nBytes - bufPos);
92bac5 ¤   ¤   ¤   derr = Int21ReadFileAux(handle, buf + bufPos, bytesToRead);
3faf5a
7f9d3d ¤   ¤   ¤   if (derr.IsntError())
a1f776 ¤   ¤   ¤   {
eecf3a ¤   ¤   ¤   ¤   bufPos += bytesToRead;
1f4efb ¤   ¤   ¤   ¤   bytesLeft -= bytesToRead;
45a3a6 ¤   ¤   ¤   }
5b0fe4 ¤   ¤   }
489371 ¤   }
9a67c5 ¤
0433e3 ¤   return derr;
dbefe6 }
64af5a
bbe4a4 // Int21WriteFile writes to a file.
4faf5a
0b2292 DualErr·
dc565b CPGPdiskDrv::Int21WriteFile(
3e0c2a ¤   PGPUInt16¤  handle,·
d34f03 ¤   PGPUInt8¤   *buf,·
4df6dc ¤   PGPUInt32¤  pos,·
24c26e ¤   PGPUInt32¤  nBytes)
abbb36 {
1c7d36 ¤   DualErr derr;
d1af5a
29b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
8aaf5a
536047 ¤   // Set the file position.
d4e5a7 ¤   derr = Int21SetFilePos(handle, pos);
a2af5a
6fa174 ¤   // We must write in chunks.
0f2361 ¤   if (derr.IsntError())
15c7a1 ¤   {
4b4a7a ¤   ¤   PGPUInt32 bufPos, bytesLeft;
9eaf5a
a5a8b4 ¤   ¤   bufPos = 0;
a88a27 ¤   ¤   bytesLeft = nBytes;
20af5a
00b80e ¤   ¤   while (derr.IsntError() && (bytesLeft > 0))
335b34 ¤   ¤   {
b395c0 ¤   ¤   ¤   PGPUInt16 bytesToWrite;
4287c7 ¤   ¤   ¤
0719ea ¤   ¤   ¤   bytesToWrite = (PGPUInt16) min(0x7000, nBytes - bufPos);
fc0ea6 ¤   ¤   ¤   derr = Int21WriteFileAux(handle, buf + bufPos, bytesToWrite);
71af5a
549d3d ¤   ¤   ¤   if (derr.IsntError())
5ff776 ¤   ¤   ¤   {
063a8d ¤   ¤   ¤   ¤   bufPos += bytesToWrite;
01ed89 ¤   ¤   ¤   ¤   bytesLeft -= bytesToWrite;
cea3a6 ¤   ¤   ¤   }
190fe4 ¤   ¤   }
029371 ¤   }
fb67c5 ¤
bd33e3 ¤   return derr;
77efe6 }
e9af5a
43af5a
2920a9 ///////////////////
eb2f4a // Memory functions
8d20a9 ///////////////////
8aaf5a
897b14 // LockUserBuffer locks memory passed in from Ring-3.
17af5a
c92292 DualErr·
d7682e CPGPdiskDrv::LockUserBuffer(void *pMem, PGPUInt32 nBytes)
b8bb36 {
27be41 ¤   DualErr¤¤   derr;
9efcff ¤   PGPUInt32¤  numPages, page;
--e9a6 0013b6c5a6c40110125 Page 12 of CPGPdiskDrvWinutils.cpp
e0af5a
0ea97e ¤   pgpAssertAddrValid(pMem, VoidAlign);
77af5a
ca0159 ¤   page = ((PGPUInt32) pMem) >> kWin32Power2PageSize;
7121fb ¤   numPages = ((nBytes - 1) >> kWin32Power2PageSize) + 1;
8caf5a
5fef68 ¤   if (!::LinPageLock(page, numPages, NULL))
8ac7a1 ¤   {
756d53 ¤   ¤   derr = DualErr(kPGDMinorError_LinPageLockFailed);
219371 ¤   }
2eaf5a
f433e3 ¤   return derr;
06efe6 }
30af5a
2d21de // UnlockUserBuffer unlocks memory passed in from Ring-3.
06af5a
b12292 DualErr·
da6d35 CPGPdiskDrv::UnlockUserBuffer(void *pMem, PGPUInt32 nBytes)
84bb36 {
2abe41 ¤   DualErr¤¤   derr;
d7fcff ¤   PGPUInt32¤  numPages, page;
5faf5a
8aa97e ¤   pgpAssertAddrValid(pMem, VoidAlign);
9faf5a
bf0159 ¤   page = ((PGPUInt32) pMem) >> kWin32Power2PageSize;
4521fb ¤   numPages = ((nBytes - 1) >> kWin32Power2PageSize) + 1;
87af5a
868f74 ¤   if (!::LinPageUnLock(page, numPages, NULL))
3ac7a1 ¤   {
47e7a2 ¤   ¤   derr = DualErr(kPGDMinorError_LinPageUnlockFailed);
439371 ¤   }
99af5a
1733e3 ¤   return derr;
3befe6 }
--8bd5 00126bea8ab40110126 Page 1 of CPGPdiskDrvWinutils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
1433b3 // CPGPdiskDrvWinutils.h
7a465d //
a51a3b // Declarations for CPGPdiskDrvWinutils.cpp.
cd1bc3 //////////////////////////////////////////////////////////////////////////////
dfaf5a
68df92 // $Id: CPGPdiskDrvWinutils.h,v 1.1.2.8 1998/08/08 01:22:07 nryan Exp $
59af5a
28cbce // Copyright (C) 1998 by Network Associates, Inc.
aa71ae // All rights reserved.
e0af5a
d4182a #ifndef Included_CPGPdiskDrvWinutils_h¤ // [
439fe9 #define Included_CPGPdiskDrvWinutils_h
ceaf5a
8d340a #include "WaitObjectClasses.h"
6faf5a
38af5a
9c09b7 ////////////
3be738 // Constants
df09b7 ////////////
5daf5a
9d1f3c const PGPUInt16 kSizeShared = 0x1000;¤  // bytes shared memory
9caf5a
04af5a
34d557 ////////
4b02c9 // Types
e8d557 ////////
21af5a
1d282f // Lock level enumeration.
58af5a
ab0104 enum LockLevel {kLock_None, kLock_L1, kLock_L2, kLock_L3, kLock_L0,·
31f740 ¤   kLock_L0MR};
faaf5a
4add18 // Registers is used to store the input and output register values for calls
d9679d // to the interrupt execution routines.
e9af5a
43ca04 typedef struct Registers
d3bb36 {
7fffdc ¤   PGPUInt32¤  EAX;¤   ¤   ¤   // general register EAX
d9cf8a ¤   PGPUInt32¤  EBX;¤   ¤   ¤   // general register EBX
29dfb8 ¤   PGPUInt32¤  ECX;¤   ¤   ¤   // general register ECX
174862 ····PGPUInt32¤  EDX;¤   ¤   ¤   // general register EDX
9d758d ¤   PGPUInt32¤  EDI;¤   ¤   ¤   // general register EDI
180e22 ¤   PGPUInt32¤  ESI;¤   ¤   ¤   // general register ESI
2aaf5a
4be65a ¤   PGPUInt16¤  DS;¤¤   ¤   ¤   // segment register DS
49f668 ¤   PGPUInt16¤  ES;¤¤   ¤   ¤   // segment register ES
a6af5a
11fa47 ¤   PGPUInt16¤  Flags;¤ ¤   ¤   // lower word of EFLAGS register
45af5a
7772fa } Registers;
09af5a
3aec9e // SharedMem is used to store both the linear Ring0 and the Ring3 selector:
c9b9c2 // offset pointer to a given block of memory allocated at Ring0.
53af5a
15b79b typedef struct SharedMem
83bb36 {
787714 ¤   PGPUInt32¤  ¤   nBytes;¤¤   // size of the memory block
a72988 ¤   void¤   ¤   ¤   *linear;¤   // R0 linear address of memory block
13906b ¤   PGPUInt32¤  ¤   segment;¤   // segment or selector
52bcd7 ¤   PGPUInt32¤  ¤   offset;¤¤   // offset
681110 ¤   PGPdiskMutex¤   mutex;¤ ¤   // mutex for access to shared memory
20af5a
841ef9 } SharedMem;
66af5a
26567f #endif¤ // ] Included_CPGPdiskDrvWinutils_h
--3e33 00042f6692340110127 Page 1 of DcbManager.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
287214 // DcbManager.cpp
ea465d //
9be1b6 // Implementation of class DcbManager.
221bc3 //////////////////////////////////////////////////////////////////////////////
caaf5a
730931 // $Id: DcbManager.cpp,v 1.1.2.4 1998/07/06 08:58:15 nryan Exp $
9baf5a
2acbce // Copyright (C) 1998 by Network Associates, Inc.
e271ae // All rights reserved.
0caf5a
9306a9 #include <vtoolscp.h>
1aaf5a
e19bcf #include "Required.h"
b73db7 #include "FatUtils.h"
2bbfe9 #include "UtilityFunctions.h"
bdaf5a
fd3c19 #include "DcbManager.h"
a53552 #include "Wrappers.h"
b4af5a
8886d2 #include LOCKED_CODE_SEGMENT
d25269 #include LOCKED_DATA_SEGMENT
14af5a
e6af5a
242e10 ///////////////////////////////////////////
5e98b6 // Class DcbManager public member functions
272e10 ///////////////////////////////////////////
fcaf5a
a362f0 // The DcbManager constructor.
73af5a
c7df60 DcbManager::DcbManager()
5abb36 {
df2e07 ¤   for (PGPUInt32 i=0; i<kMaxDrives; i++)
35c7a1 ¤   {
7f7d7f ¤   ¤   mDcbArray[i].isInUse = FALSE;
959371 ¤   }
b9efe6 }
f9af5a
638eaa // GetNumDcbs returns the number of DCBs in the container.
e1af5a
2c1b0b PGPUInt32·
25c34b DcbManager::GetNumDcbs()
8cbb36 {
11e965 ¤   return mNumDcbs;
7eefe6 }
bbaf5a
19ff43 // EnumClaimedDcbs is simply an enumeration function for DCBs that have been
2e27d1 // claimed for use.
20af5a
f7f4db PDCB·
6eec9f DcbManager::EnumClaimedDcbs(PGPUInt32 n)
7fbb36 {
6eec86 ¤   PDCB¤   ¤   pDcb¤   = NULL;
5503bb ¤   PGPUInt32¤  i¤  ¤   = 0;
b80d4c ¤   PGPUInt32¤  j¤  ¤   = 0;
c2af5a
9f41f8 ¤   while (i < kMaxDrives)
77c7a1 ¤   {
072ca5 ¤   ¤   if (mDcbArray[i].isInUse && mDcbArray[i].isClaimed)
735b34 ¤   ¤   {
1ccad0 ¤   ¤   ¤   if (j++ == n)
b7f776 ¤   ¤   ¤   {
e80b45 ¤   ¤   ¤   ¤   pDcb = mDcbArray[i].pDcb;
12f622 ¤   ¤   ¤   ¤   break;
cda3a6 ¤   ¤   ¤   }
170fe4 ¤   ¤   }
07af5a
43347d ¤   ¤   i++;
c69371 ¤   }
75af5a
f550a5 ¤   return pDcb;
42efe6 }
--8012 000bd53844640110127 Page 2 of DcbManager.cpp
e0af5a
d3cfbf // AddDcb adds a newly allocated DCB to the container and initializes it.
4faf5a
47c823 void·
deb61d DcbManager::AddDcb(PDCB pDcb)
8fbb36 {
20d66d ¤   PGPUInt8 unitOnCtl;
ddaf5a
5996eb ¤   pgpAssertAddrValid(pDcb, PDCB);
9baf5a
e9d94f ¤   unitOnCtl = pDcb->DCB_unit_on_ctl;
76fff5 ¤   pgpAssert(IsLegalDriveNumber(unitOnCtl));
3daf5a
48e560 ¤   mDcbArray[unitOnCtl].isInUse¤   = TRUE;
dc0462 ¤   mDcbArray[unitOnCtl].isClaimed¤ = FALSE;
d96765 ¤   mDcbArray[unitOnCtl].pDcb¤  ¤   = pDcb;
31af5a
5aa74f ¤   mNumDcbs++;
32836f ¤   InitDcb(pDcb);
8aefe6 }
03af5a
86911e // ClaimDcb finds an unclaimed DCB, marks it as being claimed, and returns a
12880f // pointer to it for use by the client.
79af5a
36f4db PDCB·
4d9bf7 DcbManager::ClaimDcb()
f7bb36 {
9411ff ¤   PDCB pDcb = NULL;
dbaf5a
b22e07 ¤   for (PGPUInt32 i=0; i<kMaxDrives; i++)
e7c7a1 ¤   {
4414f1 ¤   ¤   if (mDcbArray[i].isInUse && !mDcbArray[i].isClaimed)
9f5b34 ¤   ¤   {
288872 ¤   ¤   ¤   mDcbArray[i].isClaimed = TRUE;
9637ab ¤   ¤   ¤   pDcb = mDcbArray[i].pDcb;
e8af5a
e5cdcb ¤   ¤   ¤   break;
bf0fe4 ¤   ¤   }
f59371 ¤   }
1eaf5a
b050a5 ¤   return pDcb;
b1efe6 }
83af5a
220cc3 // ReleaseDcb takes a DCB that has been previously claimed and marks it as
05d0a9 // being not in use.
eaaf5a
2bc823 void·
eb8236 DcbManager::ReleaseDcb(PDCB pDcb)
7fbb36 {
28d66d ¤   PGPUInt8 unitOnCtl;
fdaf5a
bb96eb ¤   pgpAssertAddrValid(pDcb, PDCB);
bcaf5a
5fd94f ¤   unitOnCtl = pDcb->DCB_unit_on_ctl;
78fff5 ¤   pgpAssert(IsLegalDriveNumber(unitOnCtl));
35af5a
65528f ¤   pgpAssert(mDcbArray[unitOnCtl].isInUse && mDcbArray[unitOnCtl].isClaimed);
4fb7e0 ¤   mDcbArray[unitOnCtl].isClaimed = FALSE;
2eefe6 }
b2af5a
a3af5a
a1e27e ////////////////////////////////////////////
21d2de // Class DcbManager private member functions
8ae27e ////////////////////////////////////////////
56af5a
c18cc2 // InitDcb sets the DCB's fields so it is initialized enough that it won't
97d90f // crash the IOS, but virgin enough so Windows won't try to mount it itself.
14e424 // Later on when we claim this DCB we can fill it in with data corresponding
b8899e // to a PGPdisk and mount it.
85af5a
71c823 void·
bdb61d DcbManager::InitDcb(PDCB pDcb)
--a8a3 001caf961bf40110127 Page 3 of DcbManager.cpp
2cbb36 {
80a603 ¤   pgpAssertAddrValid(pDcb, DCB);
9baf5a
6b915e ¤   pDcb->DCB_cmn.DCB_drive_lttr_equiv¤ = 0xFF;
038883 ¤   pDcb->DCB_cmn.DCB_TSD_Flags¤¤   ¤   = DCB_TSD_NO_USER_INT13 |
712558 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DCB_TSD_BAD_MBR;
4af158 ¤   pDcb->DCB_cmn.DCB_vrp_ptr¤  ¤   ¤   = NULL;
d38fc5 ¤   pDcb->DCB_cmn.DCB_device_flags¤ ¤   = DCB_DEV_PHYSICAL |·
3bec1c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DCB_DEV_WRITEABLE;
6c7180 ¤   pDcb->DCB_cmn.DCB_device_flags2¤¤   = 0;
ac60b1 ¤   pDcb->DCB_cmn.DCB_Partition_Start¤  = 0;
01430e ¤   pDcb->DCB_cmn.DCB_track_table_ptr¤  = 0;
5eb223 ¤   pDcb->DCB_cmn.DCB_bds_ptr¤  ¤   ¤   = 0;
50af5a
56a533 ¤   pDcb->DCB_cmn.DCB_apparent_blk_shift¤   = SimpleLog2(kDefaultBlockSize);
8813b2 ¤   pDcb->DCB_cmn.DCB_partition_type¤   ¤   = kBigFat16PartId;
32224c ¤   pDcb->DCB_cmn.DCB_device_type¤  ¤   ¤   = DCB_type_disk;
a5af5a
0fe6b5 ¤   pDcb->DCB_cmn.DCB_cAssoc¤   ¤   = 0;
b274e6 ¤   pDcb->DCB_cmn.DCB_user_drvlet¤  = 0xffff;
a7af5a
720364 ¤   pDcb->DCB_max_xfer_len¤ ¤   ¤   = kMaxHeads*kMaxSpt*kMaxCyls;
ed1572 ¤   pDcb->DCB_actual_sector_cnt[0]¤ = kMaxHeads*kMaxSpt*kMaxCyls;
a78ce1 ¤   pDcb->DCB_actual_sector_cnt[1]¤ = 0;
b3e293 ¤   pDcb->DCB_actual_blk_size¤  ¤   = kDefaultBlockSize;
f0c3eb ¤   pDcb->DCB_actual_head_cnt¤  ¤   = kMaxHeads;
266b50 ¤   pDcb->DCB_actual_cyl_cnt¤   ¤   = kMaxCyls;
5a8f21 ¤   pDcb->DCB_actual_spt¤   ¤   ¤   = kMaxSpt;
f2e245 ¤   pDcb->DCB_bus_type¤ ¤   ¤   ¤   = DCB_BUS_ESDI;
beaf5a
a24430 ¤   // Fill in the BDD fields so older drivers won't become confused.
b0af5a
88b740 ¤   pDcb->DCB_bdd.DCB_BDD_flags¤¤   ¤   ¤   ¤   = 0;
8cd285 ¤   pDcb->DCB_bdd.DCB_apparent_sector_cnt[0]¤   = kMaxHeads*kMaxSpt*kMaxCyls;
e207d4 ¤   pDcb->DCB_bdd.DCB_apparent_sector_cnt[1]¤   = 0;
5f05ee ¤   pDcb->DCB_bdd.DCB_apparent_blk_size¤¤   ¤   = kDefaultBlockSize;
e69eea ¤   pDcb->DCB_bdd.DCB_apparent_head_cnt¤¤   ¤   = kMaxHeads;
6060fb ¤   pDcb->DCB_bdd.DCB_apparent_cyl_cnt¤ ¤   ¤   = kMaxCyls;
caae77 ¤   pDcb->DCB_bdd.DCB_apparent_spt¤ ¤   ¤   ¤   = kMaxSpt;
caefe6 }
--bd21 0012d76c75e40110128 Page 1 of DcbManager.h
541bc3 //////////////////////////////////////////////////////////////////////////////
bba26a // DcbManager.h
76465d //
731d8c // Declaration of class DcbManager.
041bc3 //////////////////////////////////////////////////////////////////////////////
38af5a
c12c64 // $Id: DcbManager.h,v 1.1.2.4 1998/07/06 08:58:16 nryan Exp $
40af5a
b3cbce // Copyright (C) 1998 by Network Associates, Inc.
9671ae // All rights reserved.
46af5a
b0b29f #ifndef Included_DcbManager_h¤  // [
827e3b #define Included_DcbManager_h
1faf5a
153a85 #include "DualErr.h"
1daf5a
71af5a
78d557 ////////
8f02c9 // Types
2fd557 ////////
91af5a
5c6405 // DcbWrapper is used by the DcbManager to keep track of which DCBs are in
cb9ef3 // use.
37af5a
3d2501 typedef struct DcbWrapper
76bb36 {
2ddcd5 ¤   PGPBoolean¤ isInUse;¤   ¤   // wrapper in use?
8ab14d ¤   PGPBoolean¤ isClaimed;¤ ¤   // DCB claimed?
cb108a ¤   PDCB¤   ¤   pDcb;¤  ¤   ¤   // wrapped DCB
0daf5a
c8661f } DcbWrapper;
02af5a
beaf5a
9b20a9 ///////////////////
b17e1a // Class DcbManager
bb20a9 ///////////////////
62af5a
6c28d0 // Class DcbManager keeps track of the DCBs allocated by the IOS subsystem for
5a1335 // the driver's use. The client adds DCBs to the container as they are
81f7e2 // recieved during IOS registration, and can claim and release DCBs later on
4cff12 // as they are needed. A DCB describes a volume either mounted or unmounted,
b37a95 // and the same DCB can be used at different times to represent different
7c250a // volumes. This class is Ring-0 thread-safe.
81af5a
badd38 class DcbManager
11bb36 {
c25ed4 public:
3a2fe8 ¤   ¤   ¤   ¤   DcbManager();
0caf5a
db81e4 ¤   PGPUInt32¤  GetNumDcbs();
48af5a
97d105 ¤   PDCB¤   ¤   EnumClaimedDcbs(PGPUInt32 n);
70af5a
fc0441 ¤   void¤   ¤   AddDcb(PDCB pDcb);
eae167 ¤   PDCB¤   ¤   ClaimDcb();
8e501b ¤   void¤   ¤   ReleaseDcb(PDCB pDcb);
79af5a
d00fb9 private:
a5446a ¤   DcbWrapper¤ mDcbArray[kMaxDrives];¤ // cross-ref unit #s and DCBs
b4444e ¤   PGPUInt32¤  mNumDcbs;¤  ¤   ¤   ¤   // population of the array
01af5a
90a8b5 ¤   void InitDcb(PDCB pDcb);
0582f7 };
5faf5a
2d03bf #endif¤ // ] Included_DcbManager_h
--9317 0009814eaa140110129 Page 1 of FatParser.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
2216eb // FatParser.cpp
40465d //
9c3dd5 // Implementation of class FatParser.
c91bc3 //////////////////////////////////////////////////////////////////////////////
abaf5a
f65d48 // $Id: FatParser.cpp,v 1.1.2.12 1998/07/08 00:40:04 nryan Exp $
f1af5a
08cbce // Copyright (C) 1998 by Network Associates, Inc.
3e71ae // All rights reserved.
8faf5a
0706a9 #include <vtoolscp.h>
36af5a
6f9bcf #include "Required.h"
6dbfe9 #include "UtilityFunctions.h"
52af5a
d7b287 #include "FatParser.h"
bac411 #include "Globals.h"
34af5a
1886d2 #include LOCKED_CODE_SEGMENT
865269 #include LOCKED_DATA_SEGMENT
3aaf5a
23af5a
2209b7 ////////////
47e738 // Constants
ee09b7 ////////////
52af5a
97746b PGPUInt32¤  kFPFragArrayChunkSize¤  = 20;¤  ¤   // frags to allocate at once
2eaf4b PGPUInt32¤  kFPDataBufSize¤ ¤   ¤   = 2;¤   ¤   // # FAT secs at once
25b8c2 PGPUInt32¤  kFPMaxLoops¤¤   ¤   ¤   = 0x500000;¤// max clusters to loop
f8af5a
fdaf5a
621c7a //////////////////////////////////////////
f3f4c9 // Class FatParser public member functions
df1c7a //////////////////////////////////////////
52af5a
db15c2 // The FatParser path and Volume object overloaded constructor prepares for
940d21 // I/O to the specified file on the specified host.
f7af5a
c970b3 FatParser::FatParser(LPCSTR path, PGPUInt8 hostDrive, PGPUInt32 bytesFile)
5900c3 ¤   ·: FileSystemParser(path, hostDrive, bytesFile)
14bb36 {
60401d ¤   pgpAssert(mHost.Mounted());
71807e ¤   pgpAssert(IsFatVolume(mFsId));
d7af5a
848afa ¤   mDataBuf¤   ¤   = NULL;
cfbf1b ¤   mNumFragsInUse¤ = 0;
0aeb9f ¤   mSizeFragArray¤ = 0;
a0be80 ¤   mFragArray¤ ¤   = NULL;
6daf5a
883a70 ¤   mFatParserReq.isInUse = FALSE;
f5af5a
b79ece ¤   mInitErr = FileSystemParser::mInitErr;
c1af5a
390ceb ¤   // Note how we allocate space for one extra sector in the main sector
eb5489 ¤   // buffer. This is because FAT12 sectors can overflow sector boundaries.
baaf5a
359c32 ¤   if (mInitErr.IsntError())
62c7a1 ¤   {
a37a51 ¤   ¤   mInitErr = GetByteBuffer((kFPDataBufSize + 1) * mHost.GetBlockSize(),·
96d237 ¤   ¤   ¤   &mDataBuf);
079371 ¤   }
83af5a
399c32 ¤   if (mInitErr.IsntError())
2bc7a1 ¤   {
3e4f09 ¤   ¤   mInitErr = GetByteBuffer(kFPFragArrayChunkSize*sizeof(FileFrag),·
715dd7 ¤   ¤   ¤   (PGPUInt8 **) &mFragArray);
3daf5a
296792 ¤   ¤   mSizeFragArray = kFPFragArrayChunkSize;
bf9371 ¤   }
01af5a
989c32 ¤   if (mInitErr.IsntError())
--ad90 0006793c1de40110129 Page 2 of FatParser.cpp
f7c7a1 ¤   {
27a9bf ¤   ¤   mInitErr = GetFatData();
cb9371 ¤   }
2daf5a
279c32 ¤   if (mInitErr.IsntError())
b2c7a1 ¤   {
604090 ¤   ¤   mInitErr = MakeFatFrags();
b49371 ¤   }
a9af5a
d65c98 #if PGP_DEBUG
f29c32 ¤   if (mInitErr.IsntError())
42be32 ¤   ¤   DumpFrags();
d41e67 #endif¤ // PGP_DEBUG
d8efe6 }
88af5a
357439 // The FatParser destructor is responsible for deallocating the list of frags
e5f667 // and deleting the sector buffer.
17af5a
085a08 FatParser::~FatParser()
9dbb36 {
523955 ¤   if (mFragArray)
f9f03a ¤   ¤   FreeByteBuffer((PGPUInt8 *) mFragArray);
3eaf5a
5a59fa ¤   if (mDataBuf)
b1033c ¤   ¤   FreeByteBuffer((PGPUInt8 *) mDataBuf);
64efe6 }
4daf5a
684516 // ReadAsync reads nBytes from the file at position pos (in bytes)·
d6f0cc // asynchronously.
a1af5a
a5c823 void·
ae90f5 FatParser::ReadAsync(
0ee311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
593385 ¤   PGPUInt64¤  ¤   ¤   pos,·
f592c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
f0f7c6 ¤   GenericCallbackInfo¤*upInfo)
b0bb36 {
3cbe41 ¤   DualErr¤¤   derr;
e3da0e ¤   PGPUInt16¤  blockSize;
d7af5a
e4b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
72e9ac ¤   pgpAssertAddrValid(upInfo, GenericCallbackInfo);
30a424 ¤   pgpAssertAddrValid(upInfo->callback, PGPUInt8);
e8af5a
bde3bd ¤   pgpAssertAddrValid(mFragArray, FileFrag);
a6401d ¤   pgpAssert(mHost.Mounted());
4ada67 ¤   pgpAssert(mNumFragsInUse > 0);
b1af5a
380aae ¤   pgpAssert(!mFatParserReq.isInUse);
896bbb ¤   mFatParserReq.isInUse = TRUE;
c7af5a
e950cf ¤   blockSize = mHost.GetBlockSize();
0faf5a
cf10ae ¤   if (pos + nBytes > mBytesFile)
a20df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
c1af5a
3fe3e6 ¤   // Prepare the request for execution.
842361 ¤   if (derr.IsntError())
f4c7a1 ¤   {
84003e ¤   ¤   PGPBoolean doneWithRequest;
9eaf5a
80b17a ¤   ¤   mFatParserReq.op = kFPOP_Read;
93e34f ¤   ¤   mFatParserReq.upInfo = upInfo;
55af5a
df00ab ¤   ¤   mFatParserReq.downInfo.callback = FatParserCallback;
9e1e5d ¤   ¤   mFatParserReq.downInfo.refData[0] = (PGPUInt32) this;
4eaf5a
2828ba ¤   ¤   // We start out by initializing the request so that all possible
85fac1 ¤   ¤   // pieces of the request are marked as completed.
141b52 ¤   ¤
892982 ¤   ¤   mFatParserReq.read.readHeader¤  = TRUE;
67de01 ¤   ¤   mFatParserReq.read.readMiddle¤  = TRUE;
--b744 0009963d8f440110129 Page 3 of FatParser.cpp
88f0f1 ¤   ¤   mFatParserReq.read.readTail¤¤   = TRUE;
a4af5a
3ff33d ¤   ¤   // Now we analyze the request and determine what pieces must be
f86cd9 ¤   ¤   // read so that the entire request can be marked as done.
061b52 ¤   ¤
1cb1b6 ¤   ¤   if (pos%blockSize > 0)
7d5b34 ¤   ¤   {
81820c ¤   ¤   ¤   PGPUInt32 bytesInHeader;
1daf5a
4d83b5 ¤   ¤   ¤   // The request has a header - that is, it doesn't begin on a
f50137 ¤   ¤   ¤   // block boundary.
c387c7 ¤   ¤   ¤
b1b89a ¤   ¤   ¤   bytesInHeader = min(nBytes, blockSize - (PGPUInt32)·
6d5a57 ¤   ¤   ¤   ¤   (pos%blockSize));
23af5a
e5c56b ¤   ¤   ¤   mFatParserReq.read.readHeader¤  = FALSE;
62856c ¤   ¤   ¤   mFatParserReq.read.bufHeader¤   = buf;
84b2c2 ¤   ¤   ¤   mFatParserReq.read.posHeader¤   = pos;
95c4e9 ¤   ¤   ¤   mFatParserReq.read.nBytesHeader¤= bytesInHeader;
c0af5a
f508d8 ¤   ¤   ¤   buf¤¤   += bytesInHeader;
35e16b ¤   ¤   ¤   pos¤¤   += bytesInHeader;
2a81d6 ¤   ¤   ¤   nBytes¤ -= bytesInHeader;
060fe4 ¤   ¤   }
2faf5a
ef73a4 ¤   ¤   if (nBytes >= blockSize)
6d5b34 ¤   ¤   {
944083 ¤   ¤   ¤   PGPUInt32 bytesInMiddle;
46af5a
f43e37 ¤   ¤   ¤   // The request has a middle - that is, a section that begins and
1f12f2 ¤   ¤   ¤   // ends on a block boundary and is more than one block in length.
5a87c7 ¤   ¤   ¤
86a19f ¤   ¤   ¤   bytesInMiddle = nBytes - nBytes%blockSize;
feaf5a
a9730f ¤   ¤   ¤   mFatParserReq.read.readMiddle¤  = FALSE;
d772ef ¤   ¤   ¤   mFatParserReq.read.bufMiddle¤   = buf;
7d4541 ¤   ¤   ¤   mFatParserReq.read.posMiddle¤   = pos;
fff467 ¤   ¤   ¤   mFatParserReq.read.nBytesMiddle¤= bytesInMiddle;
10af5a
50ca57 ¤   ¤   ¤   buf¤¤   += bytesInMiddle;
2123e4 ¤   ¤   ¤   pos¤¤   += bytesInMiddle;
204359 ¤   ¤   ¤   nBytes¤ -= bytesInMiddle;
e40fe4 ¤   ¤   }
1caf5a
4c8e09 ¤   ¤   if (nBytes > 0)
745b34 ¤   ¤   {
7fc778 ¤   ¤   ¤   // The request has a tail - that is, it doesn't end on a
720137 ¤   ¤   ¤   // block boundary.
1f87c7 ¤   ¤   ¤
4c84ae ¤   ¤   ¤   mFatParserReq.read.readTail¤¤   = FALSE;
893be7 ¤   ¤   ¤   mFatParserReq.read.bufTail¤ ¤   = buf;
480c49 ¤   ¤   ¤   mFatParserReq.read.posTail¤ ¤   = pos;
9efa59 ¤   ¤   ¤   mFatParserReq.read.nBytesTail¤  = nBytes;
bf0fe4 ¤   ¤   }
c5af5a
994945 ¤   ¤   // Execute the request.
039067 ¤   ¤   ExecuteRequest(&doneWithRequest);
d8af5a
8364ea ¤   ¤   // Should always have stuff to do at this point. But if we don't, then
c0aeb2 ¤   ¤   // don't hang the computer by not calling back.
deaf5a
008d1c ¤   ¤   if (doneWithRequest)
645b34 ¤   ¤   {
8e0606 ¤   ¤   ¤   pgpAssert(FALSE);
bb4b75 ¤   ¤   ¤   ScheduleAsyncCallback();
810fe4 ¤   ¤   }
869371 ¤   }
dcaf5a
53de32 ¤   // Callback on error.
2e4bb3 ¤   if (derr.IsError())
30c7a1 ¤   {
99c030 ¤   ¤   ScheduleAsyncCallback(derr);
--819f 0009e7f638340110129 Page 4 of FatParser.cpp
a19371 ¤   }
c9efe6 }
a0af5a
2ae1ce // WriteAsync writes nBytes to the file at position pos (in bytes)
89f0cc // asynchronously.
12af5a
c8c823 void·
079044 FatParser::WriteAsync(
a1e311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
993385 ¤   PGPUInt64¤  ¤   ¤   pos,·
cc92c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
74f7c6 ¤   GenericCallbackInfo¤*upInfo)
5cbb36 {
96be41 ¤   DualErr¤¤   derr;
f2da0e ¤   PGPUInt16¤  blockSize;
7daf5a
4eb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
cbe9ac ¤   pgpAssertAddrValid(upInfo, GenericCallbackInfo);
b3a424 ¤   pgpAssertAddrValid(upInfo->callback, PGPUInt8);
01af5a
7ae3bd ¤   pgpAssertAddrValid(mFragArray, FileFrag);
a9401d ¤   pgpAssert(mHost.Mounted());
e4da67 ¤   pgpAssert(mNumFragsInUse > 0);
99af5a
430aae ¤   pgpAssert(!mFatParserReq.isInUse);
9d6bbb ¤   mFatParserReq.isInUse = TRUE;
84af5a
3950cf ¤   blockSize = mHost.GetBlockSize();
9aaf5a
7610ae ¤   if (pos + nBytes > mBytesFile)
1e0df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
d5af5a
e8e3e6 ¤   // Prepare the request for execution.
5d2361 ¤   if (derr.IsntError())
8dc7a1 ¤   {
5f003e ¤   ¤   PGPBoolean doneWithRequest;
b6af5a
3678f7 ¤   ¤   mFatParserReq.op = kFPOP_Write;
7de34f ¤   ¤   mFatParserReq.upInfo = upInfo;
faaf5a
ae00ab ¤   ¤   mFatParserReq.downInfo.callback = FatParserCallback;
1d1e5d ¤   ¤   mFatParserReq.downInfo.refData[0] = (PGPUInt32) this;
08af5a
0028ba ¤   ¤   // We start out by initializing the request so that all possible
8afac1 ¤   ¤   // pieces of the request are marked as completed.
241b52 ¤   ¤
d6f716 ¤   ¤   mFatParserReq.write.readHeader¤ = TRUE;
d863d6 ¤   ¤   mFatParserReq.write.wroteHeader¤= TRUE;
48f31a ¤   ¤   mFatParserReq.write.wroteMiddle¤= TRUE;
66bd77 ¤   ¤   mFatParserReq.write.readTail¤   = TRUE;
bb461e ¤   ¤   mFatParserReq.write.wroteTail¤  = TRUE;
5caf5a
11f33d ¤   ¤   // Now we analyze the request and determine what pieces must be
3b8bd4 ¤   ¤   // written so that the entire request can be marked as done.
dd1b52 ¤   ¤
92b1b6 ¤   ¤   if (pos%blockSize > 0)
865b34 ¤   ¤   {
20820c ¤   ¤   ¤   PGPUInt32 bytesInHeader;
7caf5a
6683b5 ¤   ¤   ¤   // The request has a header - that is, it doesn't begin on a
300137 ¤   ¤   ¤   // block boundary.
1a87c7 ¤   ¤   ¤
30b89a ¤   ¤   ¤   bytesInHeader = min(nBytes, blockSize - (PGPUInt32)·
f25a57 ¤   ¤   ¤   ¤   (pos%blockSize));
28af5a
3cbd4e ¤   ¤   ¤   mFatParserReq.write.readHeader¤ ¤   = FALSE;
436a1a ¤   ¤   ¤   mFatParserReq.write.wroteHeader¤¤   = FALSE;
501741 ¤   ¤   ¤   mFatParserReq.write.bufHeader¤  ¤   = buf;
27a876 ¤   ¤   ¤   mFatParserReq.write.posHeader¤  ¤   = pos;
100406 ¤   ¤   ¤   mFatParserReq.write.nBytesHeader¤   = bytesInHeader;
76af5a
9e08d8 ¤   ¤   ¤   buf¤¤   += bytesInHeader;
--2ef3 000650f365440110129 Page 5 of FatParser.cpp
afe16b ¤   ¤   ¤   pos¤¤   += bytesInHeader;
9781d6 ¤   ¤   ¤   nBytes¤ -= bytesInHeader;
890fe4 ¤   ¤   }
ebaf5a
fd73a4 ¤   ¤   if (nBytes >= blockSize)
7e5b34 ¤   ¤   {
124083 ¤   ¤   ¤   PGPUInt32 bytesInMiddle;
caaf5a
043e37 ¤   ¤   ¤   // The request has a middle - that is, a section that begins and
b412f2 ¤   ¤   ¤   // ends on a block boundary and is more than one block in length.
9987c7 ¤   ¤   ¤
e7a19f ¤   ¤   ¤   bytesInMiddle = nBytes - nBytes%blockSize;
e7af5a
46b892 ¤   ¤   ¤   mFatParserReq.write.wroteMiddle¤¤   = FALSE;
17c5c9 ¤   ¤   ¤   mFatParserReq.write.bufMiddle¤  ¤   = buf;
cb7afe ¤   ¤   ¤   mFatParserReq.write.posMiddle¤  ¤   = pos;
b5d3ed ¤   ¤   ¤   mFatParserReq.write.nBytesMiddle¤   = bytesInMiddle;
0eaf5a
c2ca57 ¤   ¤   ¤   buf¤¤   += bytesInMiddle;
7523e4 ¤   ¤   ¤   pos¤¤   += bytesInMiddle;
a34359 ¤   ¤   ¤   nBytes¤ -= bytesInMiddle;
250fe4 ¤   ¤   }
37af5a
4f8e09 ¤   ¤   if (nBytes > 0)
925b34 ¤   ¤   {
fdc778 ¤   ¤   ¤   // The request has a tail - that is, it doesn't end on a
230137 ¤   ¤   ¤   // block boundary.
6a87c7 ¤   ¤   ¤
e865dd ¤   ¤   ¤   mFatParserReq.write.readTail¤   = FALSE;
919be1 ¤   ¤   ¤   mFatParserReq.write.wroteTail¤  = FALSE;
f0e015 ¤   ¤   ¤   mFatParserReq.write.bufTail¤¤   = buf;
ed1bbd ¤   ¤   ¤   mFatParserReq.write.posTail¤¤   = pos;
c7281f ¤   ¤   ¤   mFatParserReq.write.nBytesTail¤ = nBytes;
b00fe4 ¤   ¤   }
dbaf5a
994945 ¤   ¤   // Execute the request.
669067 ¤   ¤   ExecuteRequest(&doneWithRequest);
04af5a
7464ea ¤   ¤   // Should always have stuff to do at this point. But if we don't, then
71aeb2 ¤   ¤   // don't hang the computer by not calling back.
3daf5a
5c8d1c ¤   ¤   if (doneWithRequest)
0d5b34 ¤   ¤   {
b30606 ¤   ¤   ¤   pgpAssert(FALSE);
984b75 ¤   ¤   ¤   ScheduleAsyncCallback();
9c0fe4 ¤   ¤   }
169371 ¤   }
36af5a
44351b ¤   // Callback on error;
524bb3 ¤   if (derr.IsError())
08c7a1 ¤   {
e4c030 ¤   ¤   ScheduleAsyncCallback(derr);
af9371 ¤   }
3fefe6 }
a4af5a
552785 // ReadSync reads nBytes from the file at position pos (in bytes)
86ba59 // synchronously.
b4af5a
a82292 DualErr·
8527bb FatParser::ReadSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
6cbb36 {
c5be41 ¤   DualErr¤¤   derr;
31da0e ¤   PGPUInt16¤  blockSize;
5a240c ¤   PGPUInt32¤  bufPos, i, blocksToRead, sizeChunk;
5134be ¤   PGPUInt64¤  blockVolume;
cdaf5a
45b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
83e3bd ¤   pgpAssertAddrValid(mFragArray, FileFrag);
13401d ¤   pgpAssert(mHost.Mounted());
ecda67 ¤   pgpAssert(mNumFragsInUse > 0);
bfb27a ¤   pgpAssert(nBytes > 0);
65af5a
--2124 00061f4721340110129 Page 6 of FatParser.cpp
b450cf ¤   blockSize = mHost.GetBlockSize();
abaf5a
8810ae ¤   if (pos + nBytes > mBytesFile)
5d0df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
dcaf5a
ccbc09 ¤   // The position (pos) and size (nBytes) variables are in bytes, but we can
842daf ¤   // only read from a volume in sectors. What we have to do is handle the
5dbc43 ¤   // request in at most three separate pieces - a head, middle, and end.
61af5a
4f2361 ¤   if (derr.IsntError())
86c7a1 ¤   {
c9a8b4 ¤   ¤   bufPos = 0;
21af5a
afbad4 ¤   ¤   if (pos%blockSize > 0)¤ ¤   ¤   ¤   // is there a head?
ec5b34 ¤   ¤   {
d6470c ¤   ¤   ¤   PGPUInt32 headOffset, headSize;
a2af5a
8255f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
50af5a
1f094b ¤   ¤   ¤   // Now read in the head.
a00415 ¤   ¤   ¤   //
5e3200 ¤   ¤   ¤   // blockVolume = sector on disk containing the head.
a551d9 ¤   ¤   ¤   // headOffset = byte offset into blockVolume where the head starts
8efa3f ¤   ¤   ¤   // headSize = size of the head, in bytes
deaf5a
0a3250 ¤   ¤   ¤   blockVolume¤= CalcDiskSector(pos, &mFragArray[i], blockSize);
cb6334 ¤   ¤   ¤   headOffset¤ = (PGPUInt32) pos%blockSize;
9f5949 ¤   ¤   ¤   headSize¤   = min(nBytes, blockSize - headOffset);
34af5a
62d71d ¤   ¤   ¤   derr = mHost.Read(mDataBuf, blockVolume, 1);
1baf5a
c09d3d ¤   ¤   ¤   if (derr.IsntError())
c7f776 ¤   ¤   ¤   {
5f8d25 ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf + headOffset, buf, headSize);
33af5a
51c00f ¤   ¤   ¤   ¤   bufPos¤ = headSize;
762331 ¤   ¤   ¤   ¤   pos¤¤   += headSize;
4af151 ¤   ¤   ¤   ¤   nBytes¤ -= headSize;
5da3a6 ¤   ¤   ¤   }
9b0fe4 ¤   ¤   }
c19371 ¤   }
02af5a
f697fb ¤   // Read in the middle. Since the middle may be in any number of fragments
2d337d ¤   // on the disk, we have to use a while loop.
c0af5a
912361 ¤   if (derr.IsntError())
5cc7a1 ¤   {
135e57 ¤   ¤   blocksToRead = nBytes/blockSize;
96af5a
011424 ¤   ¤   while (derr.IsntError() && (blocksToRead > 0))¤ // is there a middle?
085b34 ¤   ¤   {
0055f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
34af5a
befe61 ¤   ¤   ¤   // Determine exactly how many sectors we can read before we must
0022ef ¤   ¤   ¤   // move onto the next file fragment.
e60415 ¤   ¤   ¤   //
658f3e ¤   ¤   ¤   // blockVolume = sector on disk where the current read begins
f5209c ¤   ¤   ¤   // sizeChunk = the most sectors we can read in this iteration
ffaf5a
a7ea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
5389c0 ¤   ¤   ¤   sizeChunk = min(blocksToRead, (PGPUInt32)·
029581 ¤   ¤   ¤   ¤   ((mFragArray[i].fileEnd - pos) / blockSize) + 1);
faaf5a
d7b131 ¤   ¤   ¤   derr = mHost.Read(buf + bufPos, blockVolume, sizeChunk);
48af5a
f89d3d ¤   ¤   ¤   if (derr.IsntError())
d2f776 ¤   ¤   ¤   {
39c9a8 ¤   ¤   ¤   ¤   bufPos¤ ¤   ¤   += sizeChunk * blockSize;
6e5a43 ¤   ¤   ¤   ¤   nBytes¤ ¤   ¤   -= sizeChunk * blockSize;
28e71f ¤   ¤   ¤   ¤   pos¤¤   ¤   ¤   += sizeChunk * blockSize;
168971 ¤   ¤   ¤   ¤   blocksToRead¤   -= sizeChunk;
61a3a6 ¤   ¤   ¤   }
--e4a4 000c52f979840110129 Page 7 of FatParser.cpp
b50fe4 ¤   ¤   }
6b9371 ¤   }
3c67c5 ¤
39d3c5 ¤   // Process the tail.
f22361 ¤   if (derr.IsntError())
4cc7a1 ¤   {
610bc3 ¤   ¤   if (nBytes)¤¤   ¤   ¤   ¤   ¤   ¤   // is there a tail?¤
005b34 ¤   ¤   {
f555f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
caaf5a
00ee47 ¤   ¤   ¤   // This read is very simple because we know the tail begins on a
bf0e88 ¤   ¤   ¤   // sector boundary.
500415 ¤   ¤   ¤   //
17d703 ¤   ¤   ¤   // secsDisk = the sectors in disk containing the tail.
7caf5a
cbea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
bbd71d ¤   ¤   ¤   derr = mHost.Read(mDataBuf, blockVolume, 1);
f1af5a
4a9d3d ¤   ¤   ¤   if (derr.IsntError())
cabec9 ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf, buf + bufPos, nBytes);
2d0fe4 ¤   ¤   }
f29371 ¤   }
bbaf5a
7a33e3 ¤   return derr;
98efe6 }
69af5a
c4962a // WriteSync reads nBytes from the file at position pos (in bytes)
a1ba59 // synchronously.
d1af5a
d42292 DualErr·
07e4e1 FatParser::WriteSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
38bb36 {
edbe41 ¤   DualErr¤¤   derr;
0dda0e ¤   PGPUInt16¤  blockSize;
1911dd ¤   PGPUInt32¤  bufPos, i, blocksToWrite, sizeChunk;
5e34be ¤   PGPUInt64¤  blockVolume;
82af5a
14b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
e8e3bd ¤   pgpAssertAddrValid(mFragArray, FileFrag);
a1401d ¤   pgpAssert(mHost.Mounted());
cbda67 ¤   pgpAssert(mNumFragsInUse > 0);
5cb27a ¤   pgpAssert(nBytes > 0);
b4af5a
3d50cf ¤   blockSize = mHost.GetBlockSize();
0baf5a
f210ae ¤   if (pos + nBytes > mBytesFile)
1f0df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
90af5a
ccae8b ¤   // Process the head.
792361 ¤   if (derr.IsntError())
55c7a1 ¤   {
4da8b4 ¤   ¤   bufPos = 0;
dcaf5a
a9bad4 ¤   ¤   if (pos%blockSize > 0)¤ ¤   ¤   ¤   // is there a head?
ee5b34 ¤   ¤   {
7c470c ¤   ¤   ¤   PGPUInt32 headOffset, headSize;
c5af5a
7f55f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
20af5a
5cd99b ¤   ¤   ¤   // Write out the head.
a50415 ¤   ¤   ¤   //
e7fc2f ¤   ¤   ¤   // blockVolume = sector on disk containing the head
3d8d9c ¤   ¤   ¤   // headOffset = byte offset into secsDisk where the head starts
a7fa3f ¤   ¤   ¤   // headSize = size of the head, in bytes
74af5a
7a3250 ¤   ¤   ¤   blockVolume¤= CalcDiskSector(pos, &mFragArray[i], blockSize);
646334 ¤   ¤   ¤   headOffset¤ = (PGPUInt32) pos%blockSize;
c15949 ¤   ¤   ¤   headSize¤   = min(nBytes, blockSize - headOffset);
15af5a
d7d71d ¤   ¤   ¤   derr = mHost.Read(mDataBuf, blockVolume, 1);
14af5a
c59d3d ¤   ¤   ¤   if (derr.IsntError())
--2a56 0006a5cebcb40110129 Page 8 of FatParser.cpp
99f776 ¤   ¤   ¤   {
a631dd ¤   ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf + headOffset, headSize);
c0e31c ¤   ¤   ¤   ¤   derr = mHost.Write(mDataBuf, blockVolume, 1);
2fa3a6 ¤   ¤   ¤   }
70af5a
5a9d3d ¤   ¤   ¤   if (derr.IsntError())
1bf776 ¤   ¤   ¤   {
00c00f ¤   ¤   ¤   ¤   bufPos¤ = headSize;
3c2331 ¤   ¤   ¤   ¤   pos¤¤   += headSize;
84f151 ¤   ¤   ¤   ¤   nBytes¤ -= headSize;
0ba3a6 ¤   ¤   ¤   }
df0fe4 ¤   ¤   }
009371 ¤   }
97af5a
db0cf9 ¤   // Write out the middle. Since the middle may be in any number of
459f63 ¤   // fragments on the disk, we have to use a while loop.
f0af5a
482361 ¤   if (derr.IsntError())
9fc7a1 ¤   {
188c7f ¤   ¤   blocksToWrite = nBytes / blockSize;
86af5a
c63ee4 ¤   ¤   while (derr.IsntError() && (blocksToWrite > 0))¤// is there a middle?
a35b34 ¤   ¤   {
2b55f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
b4af5a
e72007 ¤   ¤   ¤   // Determine exactly how many sectors we can write before we must
7a22ef ¤   ¤   ¤   // move onto the next file fragment.
160415 ¤   ¤   ¤   //
e5c38d ¤   ¤   ¤   // blockVolume = sector on disk where the current write begins
e96bbd ¤   ¤   ¤   // sizeChunk = the most sectors we can write in this iteration
cfaf5a
31ea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
8ed1b9 ¤   ¤   ¤   sizeChunk = min(blocksToWrite, (PGPUInt32)·
ac9581 ¤   ¤   ¤   ¤   ((mFragArray[i].fileEnd - pos) / blockSize) + 1);
8baf5a
564d72 ¤   ¤   ¤   // Now we perform the write from the output buffer to disk.
7daf5a
f5ef48 ¤   ¤   ¤   derr = mHost.Write(buf + bufPos, blockVolume, sizeChunk);
ebaf5a
349d3d ¤   ¤   ¤   if (derr.IsntError())
7df776 ¤   ¤   ¤   {
22c9a8 ¤   ¤   ¤   ¤   bufPos¤ ¤   ¤   += sizeChunk * blockSize;
b05a43 ¤   ¤   ¤   ¤   nBytes¤ ¤   ¤   -= sizeChunk * blockSize;
85e71f ¤   ¤   ¤   ¤   pos¤¤   ¤   ¤   += sizeChunk * blockSize;
657881 ¤   ¤   ¤   ¤   blocksToWrite¤  -= sizeChunk;
52a3a6 ¤   ¤   ¤   }
710fe4 ¤   ¤   }
639371 ¤   }
63af5a
ded3c5 ¤   // Process the tail.
362361 ¤   if (derr.IsntError())
00c7a1 ¤   {
130bc3 ¤   ¤   if (nBytes)¤¤   ¤   ¤   ¤   ¤   ¤   // is there a tail?¤
085b34 ¤   ¤   {
fd55f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
26af5a
bca4d5 ¤   ¤   ¤   // Write out the tail.
fd0415 ¤   ¤   ¤   //
3a45b1 ¤   ¤   ¤   // blockVolume = sector on disk containing the tail
bbf52d ¤   ¤   ¤   // headSize = size of the tail, in bytes
ddaf5a
d93250 ¤   ¤   ¤   blockVolume¤= CalcDiskSector(pos, &mFragArray[i], blockSize);
86d71d ¤   ¤   ¤   derr = mHost.Read(mDataBuf, blockVolume, 1);
0caf5a
a29d3d ¤   ¤   ¤   if (derr.IsntError())
eaf776 ¤   ¤   ¤   {
a275af ¤   ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf, nBytes);
12e31c ¤   ¤   ¤   ¤   derr = mHost.Write(mDataBuf, blockVolume, 1);
75a3a6 ¤   ¤   ¤   }
d10fe4 ¤   ¤   }
ec9371 ¤   }
6aaf5a
--2fa0 000dc3b82d840110129 Page 9 of FatParser.cpp
dd33e3 ¤   return derr;
a2efe6 }
c9af5a
76adcc // Read reads nBytes from the file at position pos (in bytes). It uses the
7c6420 // previously initialized member variable mFragArray to map locations in the
a03d7b // file to locations on disk, since a file on a FAT volume may be spread out
3096f8 // in many fragments.
caaf5a
6b2292 DualErr·
d74fa0 FatParser::Read(
28e311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
013385 ¤   PGPUInt64¤  ¤   ¤   pos,·
6792c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
c6f7c6 ¤   GenericCallbackInfo¤*upInfo)
04bb36 {
767d36 ¤   DualErr derr;
03af5a
65b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
1daf5a
13381f ¤   if (upInfo)
2e50e3 ¤   ¤   ReadAsync(buf, pos, nBytes, upInfo);
080e24 ¤   else
4d778d ¤   ¤   derr = ReadSync(buf, pos, nBytes);
0aaf5a
6133e3 ¤   return derr;
bfefe6 }
73af5a
00e3d6 // Write writes nBytes to the file at position pos (in bytes). It uses the
3e4057 // previously initialized member variable mPFF to map locations in the file
855158 // to locations on disk, since a file on a FAT volume may be spread out in
c258a0 // many fragments.
90af5a
152292 DualErr·
72d4d6 FatParser::Write(
38e311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
423385 ¤   PGPUInt64¤  ¤   ¤   pos,·
6f92c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
3af7c6 ¤   GenericCallbackInfo¤*upInfo)
f0bb36 {
bb7d36 ¤   DualErr derr;
97af5a
65b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
3eaf5a
54381f ¤   if (upInfo)
00ac43 ¤   ¤   WriteAsync(buf, pos, nBytes, upInfo);
490e24 ¤   else
10153d ¤   ¤   derr = WriteSync(buf, pos, nBytes);
c7af5a
6a33e3 ¤   return derr;
bcefe6 }
66af5a
e8af5a
f62e10 ///////////////////////////////////////////
0b59c2 // Class FatParser private member functions
3b2e10 ///////////////////////////////////////////
20af5a
83c81a // CalcDiskSector calculates the sector on disk containing a certain location
9d6975 // in a file, given that location and a pointer to a single FileFrag.
1caf5a
42a385 PGPUInt64·
074dca FatParser::CalcDiskSector(
1eb13c ¤   PGPUInt64¤  filePos,·
25192b ¤   PFileFrag¤  pFF,·
9d7c2f ¤   PGPUInt16¤  blockSize)
02bb36 {
452f6c ¤   PGPUInt64¤  diskPos;
d4af5a
49003a ¤   pgpAssertAddrValid(pFF, FileFrag);
938bd8 ¤   pgpAssert(filePos >= pFF->fileBegin);
3c28c9 ¤   pgpAssert(filePos <= pFF->fileEnd);
eaaf5a
dc4bf1 ¤   diskPos = pFF->diskBegin + (filePos - pFF->fileBegin);
--5b8d 000f6fdbeb340110129 Page 10 of FatParser.cpp
e0af5a
f242e3 ¤   return (diskPos / blockSize);
99efe6 }
b5af5a
a3d4d5 // ExpandFragArray allocated memory for more file fragments.
c2af5a
382292 DualErr·
487056 FatParser::ExpandFragArray()
f6bb36 {
5dbe41 ¤   DualErr¤¤   derr;
1038b0 ¤   PFileFrag¤  temp;
9caf5a
d21144 ¤   // Get memory for more fragments.
cabc2c ¤   derr = GetByteBuffer(
e5f0c5 ¤   ¤   (mSizeFragArray + kFPFragArrayChunkSize) * sizeof(FileFrag),·
93b612 ¤   ¤   (PGPUInt8 **) &temp);
33af5a
be2361 ¤   if (derr.IsntError())
e8c7a1 ¤   {
b2ef7b ¤   ¤   // Copy the old fragments to the new memory.
09e063 ¤   ¤   pgpCopyMemory(mFragArray, temp, mSizeFragArray*sizeof(FileFrag));
deaf5a
5ce0c0 ¤   ¤   // Delete the old memory.
b7f03a ¤   ¤   FreeByteBuffer((PGPUInt8 *) mFragArray);
7caf5a
453d92 ¤   ¤   mFragArray = temp;
31ea7c ¤   ¤   mSizeFragArray += kFPFragArrayChunkSize;
f69371 ¤   }
51af5a
aa33e3 ¤   return derr;
4defe6 }
dbaf5a
b1e59b // FindFragmentIndex will find and return the index of the file fragment that
e31b24 // contains the file position specified.
e6af5a
131b0b PGPUInt32·
6bcc69 FatParser::FindFragmentIndex(PGPUInt64 pos)
e6bb36 {
63fda5 ¤   PGPBoolean¤ foundFrag¤  = FALSE;
f27132 ¤   PGPUInt32¤  i, j, x;
ccaf5a
b5e3bd ¤   pgpAssertAddrValid(mFragArray, FileFrag);
0c8ee3 ¤   pgpAssert(mSizeFragArray > 0);
25af5a
f3ff6c ¤   i = 0;
b20e17 ¤   j = mNumFragsInUse - 1;
76af5a
c9c464 ¤   // Binary search.
59cfa1 ¤   do
f3c7a1 ¤   {
f2acd9 ¤   ¤   x = (i + j)/2;
b4af5a
888720 ¤   ¤   if ((pos >= mFragArray[x].fileBegin) &&·
e2ac03 ¤   ¤   ¤   (pos <= mFragArray[x].fileEnd))
e25b34 ¤   ¤   {
f3bc47 ¤   ¤   ¤   foundFrag = TRUE;
d3cdcb ¤   ¤   ¤   break;
b80fe4 ¤   ¤   }
580e1d ¤   ¤   else
f15b34 ¤   ¤   {
609230 ¤   ¤   ¤   (pos > mFragArray[x].fileEnd ? i = x + 1: j = x - 1);
4e0fe4 ¤   ¤   }
ec9371 ¤   }
361cae ¤   while (j >= i);
6eaf5a
4c1945 ¤   if (!foundFrag)
f8c7a1 ¤   {
5f2b6b ¤   ¤   pgpDebugMsg("PGPdisk: FindFragment recieved an OOB position");
4e093f ¤   ¤   return 0xFFFFFFFF;
f59371 ¤   }
4c0e24 ¤   else
f6c7a1 ¤   {
--f9f5 00036d79dd440110129 Page 11 of FatParser.cpp
077b6a ¤   ¤   return x;
c39371 ¤   }
91efe6 }
f7af5a
67f05c // InitFileFrag initializes a file fragment. It sets the beginning (and ending,
5f9e37 // since it is zero length) file and disk parameters according to the passed
baad9a // values.
c3af5a
3bc823 void·
0e119f FatParser::InitFileFrag(
89192b ¤   PFileFrag¤  pFF,·
6b79fd ¤   PGPUInt64¤  fileByte,·
0f0ea3 ¤   PGPUInt64¤  diskByte)
a5bb36 {
22003a ¤   pgpAssertAddrValid(pFF, FileFrag);
a8af5a
54fd9c ¤   pFF->fileBegin¤ = pFF->fileEnd¤ = fileByte;
836a3f ¤   pFF->diskBegin¤ = pFF->diskEnd¤ = diskByte;
e8b78d ¤   pFF->next¤  ¤   = pFF->prev¤¤   = NULL;
21efe6 }
83af5a
af5c98 #if PGP_DEBUG
e5af5a
9168e0 // DumpFrags is a debugging procedure that will print out a list of the
f9d84d // fragments in a file to the debugger.
3baf5a
cec823 void·
8f8ed1 FatParser::DumpFrags()
7bbb36 {
8cda0e ¤   PGPUInt16¤  blockSize;
9c338b ¤   PGPUInt64¤  secBegin, secEnd;
9caf5a
3250cf ¤   blockSize = mHost.GetBlockSize();
d3c99a ¤   DebugOut("\nPGPdisk: Frags Dump for %s:\n", GetPath());
87af5a
2d6f1d ¤   if (mNumFragsInUse == 0)
d3c7a1 ¤   {
442216 ¤   ¤   DebugOut("\nPGPdisk: No frags to dump\n");
d09371 ¤   }
7a0e24 ¤   else
15c7a1 ¤   {
872761 ¤   ¤   for (PGPUInt32 i=0; i < mNumFragsInUse; i++)
cb5b34 ¤   ¤   {
814f0e ¤   ¤   ¤   DebugOut("PGPdisk: Frag #%u", i);
1caf5a
006c56 ¤   ¤   ¤   secBegin¤   = mFragArray[i].fileBegin/blockSize;
8a0f50 ¤   ¤   ¤   secEnd¤ ¤   = mFragArray[i].fileEnd/blockSize;
71af5a
bdab09 ¤   ¤   ¤   DebugOut("PGPdisk: File begin: %u to file end: %u", secBegin,·
516a90 ¤   ¤   ¤   ¤   secEnd);
0eaf5a
6506c1 ¤   ¤   ¤   secBegin¤   = (PGPUInt32) (mFragArray[i].diskBegin/blockSize);
85331c ¤   ¤   ¤   secEnd¤ ¤   = (PGPUInt32) (mFragArray[i].diskEnd/blockSize);
b8af5a
b61761 ¤   ¤   ¤   DebugOut("PGPdisk: Disk begin: %u to disk end: %u", secBegin,·
9b6a90 ¤   ¤   ¤   ¤   secEnd);
da0fe4 ¤   ¤   }
4067c5 ¤
d53b51 ¤   ¤   DebugOut("\nPGPdisk: Frag Dump completed\n");
a79371 ¤   }
c8efe6 }
11af5a
d51e67 #endif¤ // PGP_DEBUG
d9af5a
a2b2a0 // GetFatData acquires data specific to the FAT filesystem of the host drive
0d54e0 // and fills in the data member 'mFat'.
d3af5a
d72292 DualErr·
92798b FatParser::GetFatData()
f4bb36 {
d4945d ¤   DualErr¤derr;
36af5a
--5284 000bdb0d8de40110129 Page 12 of FatParser.cpp
ff401d ¤   pgpAssert(mHost.Mounted());
2aaf5a
767dc1 ¤   mFat.fdBlockSize = mHost.GetBlockSize();
cff188 ¤   mFat.fdFsId = mFsId;
9caf5a
1dff61 ¤   switch (mFsId)
bfc7a1 ¤   {
19af5a
acc111 ¤   case kFS_FAT12:
dca270 ¤   case kFS_FAT16:
02c7a1 ¤   {
29baa5 ¤   ¤   DevParams16¤dp16;
ffaf5a
f11430 ¤   ¤   derr = mHost.GetDevParams16(&dp16);
27af5a
28aa35 ¤   ¤   if (derr.IsntError())
125b34 ¤   ¤   {
b0cbc1 ¤   ¤   ¤   mFat.fdActiveFat¤   = 0;¤   ¤   ¤   ¤   ¤   // always 0
e899fe ¤   ¤   ¤   mFat.fdFatCount¤¤   = dp16.dpFats;¤ ¤   ¤   // number of FATs
4ce997 ¤   ¤   ¤   mFat.fdReservedSecs¤= dp16.dpResSectors;¤   // reserved sectors
0efae6 ¤   ¤   ¤   mFat.fdRootDirEnts¤ = dp16.dpRootDirEnts;¤  // root dir entries
e513f0 ¤   ¤   ¤   mFat.fdSpc¤ ¤   ¤   = dp16.dpSecPerClust;¤  // sectors per cluster
03bb43 ¤   ¤   ¤   mFat.fdFatSize¤ ¤   = dp16.dpFatSecs;¤  ¤   // sectors per FAT
4cbde5 ¤   ¤   ¤   mFat.fdFirstSecFat¤ = dp16.dpResSectors;¤   // FATs begin > rsrvd
aaaf5a
33bfad ¤   ¤   ¤   CalcFatDataSec(&mFat);
3b0fe4 ¤   ¤   }
182f68 ¤   ¤   break;
a79371 ¤   }
d4af5a
33f867 ¤   case kFS_FAT32:
fcc7a1 ¤   {
6184fd ¤   ¤   DevParams32 dp32;
97d989 ¤   ¤   PGPUInt8¤   activeFat;
92023e ¤   ¤   PGPUInt32¤  flags;
b4af5a
9c6bea ¤   ¤   derr = mHost.GetDevParams32(&dp32);
e7af5a
b3aa35 ¤   ¤   if (derr.IsntError())
a85b34 ¤   ¤   {
a2f8e2 ¤   ¤   ¤   // Check for mirrored FAT tables in FAT32.
4a2294 ¤   ¤   ¤   flags = dp32.dpExtFlags;
c2e5d2 ¤   ¤   ¤   if (flags & BGBPB_F_NoFATMirror)
73c088 ¤   ¤   ¤   ¤   activeFat = 0;
1cbb8c ¤   ¤   ¤   else
9a5cde ¤   ¤   ¤   ¤   activeFat = (PGPUInt8) (flags & BGBPB_F_ActiveFATMsk);
6b1b52 ¤   ¤
f9eb75 ¤   ¤   ¤   mFat.fdActiveFat¤   = activeFat;¤   ¤   ¤   ¤   // # of active FAT
5bc904 ¤   ¤   ¤   mFat.fdFatCount¤¤   = dp32.dpNumberOfFats;¤ ¤   // number of FATs
b9719e ¤   ¤   ¤   mFat.fdReservedSecs¤= dp32.dpReservedSectors;¤  // reserved seecs
2cff74 ¤   ¤   ¤   mFat.fdSpc¤ ¤   ¤   = dp32.dpSectorsPerClust;¤  // sects per clust
e1fd48 ¤   ¤   ¤   mFat.fdFatSize¤ ¤   = dp32.dpBigSectorsPerFat;¤ // secs per FAT
182fc1 ¤   ¤   ¤   mFat.fdFirstSecFat¤ = dp32.dpReservedSectors;¤  // FATs > reserved
28af5a
a9bfad ¤   ¤   ¤   CalcFatDataSec(&mFat);
d40fe4 ¤   ¤   }
722f68 ¤   ¤   break;
489371 ¤   }
f1af5a
bc2f72 ¤   default:
ce8f52 ¤   ¤   pgpAssert(FALSE);
572f68 ¤   ¤   break;
c29371 ¤   }
58af5a
03999a ¤   // Finally we make a system call to determine the index of the first
fd12c4 ¤   // cluster in the FAT table for our file.
75af5a
232361 ¤   if (derr.IsntError())
60c7a1 ¤   {
db541a ¤   ····derr = Driver->GetFirstClustFile(mPath, &mFat.fdFirstClustFile);
0d9371 ¤   }
bdaf5a
--a74e 000c8af25e040110129 Page 13 of FatParser.cpp
dd33e3 ¤   return derr;
a2efe6 }
c9af5a
935bbd // ParseNextCluster is a helper function for MakeFatFrags. Given a set of
c9e85e // information about a file and its associated FAT table, and the index of
fb2f9d // a cluster in that FAT table, it reads in the next clusters and expands
20bf04 // the file's fragment list as appropriate.
3daf5a
c42292 DualErr·
3f8562 FatParser::ParseNextCluster(ParseNextClusterInfo *pPNCI)
afbb36 {
2dbe41 ¤   DualErr¤¤   derr;
6b34be ¤   PGPUInt64¤  blockVolume;
17af5a
67af04 ¤   pgpAssertAddrValid(pPNCI, ParseNextClusterInfo);
73af5a
34ad26 ¤   // Sanity checks.
2faf5a
37f2a6 ¤   if ((pPNCI->curClust > pPNCI->totalClusts) ||·
e48269 ¤   ¤   ((++pPNCI->overFlow) > kFPMaxLoops))
bcc7a1 ¤   {
012d75 ¤   ¤   derr = DualErr(kPGDMinorError_CorruptFat);
d19371 ¤   }
3eaf5a
f37303 ¤   // Check if we are still within the current fragment - that is, if the
0ca809 ¤   // next cluster is 1 greater than the current cluster. If not, create a
d118b7 ¤   // new file fragment.
37af5a
e22361 ¤   if (derr.IsntError())
b6c7a1 ¤   {
bad29f ¤   ¤   if (pPNCI->nextClust == (pPNCI->curClust + 1))¤ // within fragment?
b65b34 ¤   ¤   {
635478 ¤   ¤   ¤   // We are not at the end of a fragment. First increment curClust
7d3746 ¤   ¤   ¤   // by 1, and expand our fragment by the size (in bytes) of 1
eaed64 ¤   ¤   ¤   // cluster.
6faf5a
9d59fe ¤   ¤   ¤   pPNCI->curClust++;
8bac19 ¤   ¤   ¤   mFragArray[pPNCI->i].fileEnd += pPNCI->spc * pPNCI->blockSize;
81a8a1 ¤   ¤   ¤   mFragArray[pPNCI->i].diskEnd += pPNCI->spc * pPNCI->blockSize;
d7af5a
be5659 ¤   ¤   ¤   // Next update the offset to point to the new current cluster's
02b6d4 ¤   ¤   ¤   // data (which will hold the next cluster's index). If the offset
6c99a8 ¤   ¤   ¤   // runs over our buffer size, we have to read in the next buffer.
8aaf5a
7fd27e ¤   ¤   ¤   pPNCI->bitOffset += pPNCI->bitsClust;
0eaf5a
4486b2 ¤   ¤   ¤   if (pPNCI->bitOffset >=·
f41465 ¤   ¤   ¤   ¤   (PGPUInt32) kFPDataBufSize * pPNCI->blockSize * kBitsPerByte)
47f776 ¤   ¤   ¤   {
cb1e62 ¤   ¤   ¤   ¤   GetClusterInfo(pPNCI->firstSecFat, pPNCI->curClust,·
d578aa ¤   ¤   ¤   ¤   ¤   pPNCI->bitsClust, pPNCI->blockSize, &pPNCI->clustSec,·
6af330 ¤   ¤   ¤   ¤   ¤   &pPNCI->bitOffset);
bbaf5a
9ed11b ¤   ¤   ¤   ¤   derr = mHost.Read(mDataBuf, pPNCI->clustSec,·
d91584 ¤   ¤   ¤   ¤   ¤   kFPDataBufSize + 1);
a9a3a6 ¤   ¤   ¤   }
f80fe4 ¤   ¤   }
260e1d ¤   ¤   else
405b34 ¤   ¤   {
3c420c ¤   ¤   ¤   PGPUInt64 oldSector;
a7af5a
5a624d ¤   ¤   ¤   // OK, we are at the end of a fragment. Set curClust to the index
f37c4a ¤   ¤   ¤   // of the new cluster (which can be any valid cluster index), and
3835d3 ¤   ¤   ¤   // expand the current fragment.
2eaf5a
e807f8 ¤   ¤   ¤   pPNCI->curClust = pPNCI->nextClust;
f8af5a
2fa403 ¤   ¤   ¤   mFragArray[pPNCI->i].fileEnd +=·
41db29 ¤   ¤   ¤   ¤   (pPNCI->spc * pPNCI->blockSize) - 1;
eaaf5a
6702e3 ¤   ¤   ¤   mFragArray[pPNCI->i].diskEnd +=·
c8db29 ¤   ¤   ¤   ¤   (pPNCI->spc * pPNCI->blockSize) - 1;
--0210 0007a83a59440110129 Page 14 of FatParser.cpp
e0af5a
8c9062 ¤   ¤   ¤   oldSector = pPNCI->clustSec;
e1af5a
af1eda ¤   ¤   ¤   // Find the new FAT sector.
6a9427 ¤   ¤   ¤   GetClusterInfo(pPNCI->firstSecFat, pPNCI->curClust,·
3ea801 ¤   ¤   ¤   ¤   pPNCI->bitsClust, pPNCI->blockSize, &pPNCI->clustSec,·
a83665 ¤   ¤   ¤   ¤   &pPNCI->bitOffset);
6daf5a
e8ed29 ¤   ¤   ¤   // If this lies in a different sector, read it in.
73752f ¤   ¤   ¤   if (pPNCI->clustSec != oldSector)
24f776 ¤   ¤   ¤   {
d2d11b ¤   ¤   ¤   ¤   derr = mHost.Read(mDataBuf, pPNCI->clustSec,·
ad1584 ¤   ¤   ¤   ¤   ¤   kFPDataBufSize + 1);
53a3a6 ¤   ¤   ¤   }
dcaf5a
9b642c ¤   ¤   ¤   // Finally we calculate which sector on disk the new curClust
df25f5 ¤   ¤   ¤   // refers to, and then we init a new fragment
00af5a
349d3d ¤   ¤   ¤   if (derr.IsntError())
47f776 ¤   ¤   ¤   {
6b58cb ¤   ¤   ¤   ¤   blockVolume = ClusterToSector(pPNCI->curClust,·
a63613 ¤   ¤   ¤   ¤   ¤   pPNCI->firstSecData, pPNCI->spc, pPNCI->clustBias);
8baf5a
4ebb22 ¤   ¤   ¤   ¤   // See if we have to allocate a new frag.
0c87d8 ¤   ¤   ¤   ¤   if (pPNCI->i + 1 == mSizeFragArray)
20a3f3 ¤   ¤   ¤   ¤   ¤   derr = ExpandFragArray();
3fa3a6 ¤   ¤   ¤   }
beaf5a
693230 ¤   ¤   ¤   // Init a new file fragment.
019d3d ¤   ¤   ¤   if (derr.IsntError())
abf776 ¤   ¤   ¤   {
e726ee ¤   ¤   ¤   ¤   pPNCI->i++;
0be29d ¤   ¤   ¤   ¤   mNumFragsInUse++;
7faf5a
4a5c84 ¤   ¤   ¤   ¤   InitFileFrag(&mFragArray[pPNCI->i],·
9497ad ¤   ¤   ¤   ¤   ¤   mFragArray[pPNCI->i - 1].fileEnd + 1,·
ef5f9c ¤   ¤   ¤   ¤   ¤   blockVolume * pPNCI->blockSize);
67a3a6 ¤   ¤   ¤   }
f90fe4 ¤   ¤   }
029371 ¤   }
05af5a
7a23b9 ¤   // Extract the next cluster.
ebdbe4 ¤   pPNCI->nextClust = ExtractCluster(mDataBuf, pPNCI->bitOffset,·
8c08b4 ¤   ¤   pPNCI->curClust, mFsId);
60af5a
f333e3 ¤   return derr;
cbefe6 }
5eaf5a
8cfdb1 // MakeFATFrags constructs the file fragment array for the File being opened
e5964d // on its FAT host drive with direct disk access mode. This procedure reads
326599 // directly from the FAT table of the host drive.
15af5a
fe2292 DualErr·
9b4e97 FatParser::MakeFatFrags()
80bb36 {
44be41 ¤   DualErr¤¤   derr;
a0bef4 ¤   PGPUInt8¤   bitsClust, clustBias;
beded2 ¤   PGPUInt16¤  blockSize, spc;
d81eba ¤   PGPUInt32¤  bitOffset, clustSec, curClust, fatSize, firstSecFat;
5af6f5 ¤   PGPUInt32¤  firstClustFile, firstSecFile, firstSecData, i, maxClust;
ca98a3 ¤   PGPUInt32¤  minClust, totalClusts;
37af5a
5735be ¤   pgpAssertAddrValid(mDataBuf, PGPUInt8);
3076ed ¤   pgpAssert(mNumFragsInUse == 0);
6faf5a
131854 ¤   // First fill in some filesystem specific data.
0eff61 ¤   switch (mFsId)
70c7a1 ¤   {
fec111 ¤   case kFS_FAT12:
be3acc ¤   ¤   bitsClust¤  = kBitsFat12Clust;
0fd1d4 ¤   ¤   clustBias¤  = kFat12ClustBias;
7a6aab ¤   ¤   maxClust¤   = kMaxFat12Clust;
--0eb9 000ea90192140110129 Page 15 of FatParser.cpp
020643 ¤   ¤   minClust¤   = kMinFat12Clust;
e22f68 ¤   ¤   break;
50af5a
a2a270 ¤   case kFS_FAT16:
9f2c12 ¤   ¤   bitsClust¤  = kBitsFat16Clust;
cfd4a2 ¤   ¤   clustBias¤  = kFat16ClustBias;
067c75 ¤   ¤   maxClust¤   = kMaxFat16Clust;
c5109d ¤   ¤   minClust¤   = kMinFat16Clust;
fa2f68 ¤   ¤   break;
24af5a
9df867 ¤   case kFS_FAT32:
6ea136 ¤   ¤   bitsClust¤  = kBitsFat32Clust;
64da8e ¤   ¤   clustBias¤  = kFat32ClustBias;
e1f151 ¤   ¤   maxClust¤   = kMaxFat32Clust;
b29db9 ¤   ¤   minClust¤   = kMinFat32Clust;
322f68 ¤   ¤   break;
69af5a
2b2f72 ¤   default:
538f52 ¤   ¤   pgpAssert(FALSE);
342f68 ¤   ¤   break;
4a9371 ¤   }
adaf5a
3f69ba ¤   // Then fill in the data specific to this drive.
8eb9c9 ¤   blockSize¤  ¤   = mFat.fdBlockSize;
1fa1d1 ¤   fatSize¤¤   ¤   = mFat.fdFatSize;
ce11a2 ¤   spc¤¤   ¤   ¤   = mFat.fdSpc;¤  ¤
d12f13 ¤   firstSecData¤   = mFat.fdFirstSecData;
60dbd7 ¤   firstClustFile¤ = mFat.fdFirstClustFile;
27cb41 ¤   firstSecFat¤¤   = mFat.fdFirstSecFat + mFat.fdActiveFat*fatSize;
bdaf5a
e0cb92 ¤   totalClusts = TotalClusters(fatSize, bitsClust, blockSize);
60af5a
af8af4 ¤   DebugOut("PGPdisk: blockSize is %u", blockSize);
aeb877 ¤   DebugOut("PGPdisk: fatSize is %u", fatSize);
98d501 ¤   DebugOut("PGPdisk: spc is %u", spc);
d00b38 ¤   DebugOut("PGPdisk: firstSecData is %u", firstSecData);
146f1b ¤   DebugOut("PGPdisk: firstClustFile is %u", firstClustFile);
e17397 ¤   DebugOut("PGPdisk: firstSecFat is %u", firstSecFat);
42af5a
58f6e6 ¤   pgpAssert(firstSecFat < firstSecData);
d0e271 ¤   pgpAssert(firstClustFile <= totalClusts);
eeaf5a
08d206 ¤   // Now we will calculate the index of the first sector on disk holding our
0e6db9 ¤   // file's contents.
67af5a
07306f ¤   firstSecFile = ClusterToSector(firstClustFile, firstSecData, spc,·
634bb1 ¤   ¤   clustBias);
46af5a
765b5d ¤   pgpAssert(firstSecFile >= firstSecData);
54af5a
03d9f3 ¤   // Init the first file fragment structure for the file.
a42361 ¤   if (derr.IsntError())
45c7a1 ¤   {
749ed6 ¤   ¤   i = 0;
bab88a ¤   ¤   mNumFragsInUse = 1;
25af5a
ed94ec ¤   ¤   InitFileFrag(&mFragArray[i], 0, (PGPUInt64) firstSecFile*blockSize);
1f9371 ¤   }
a2af5a
f62949 ¤   // 'curClust' will keep track of the index of the current cluster we are
20ddf6 ¤   // looking at. 'clustSec' and 'bitOffset' keep track of the sector in the
e78828 ¤   // FAT table where this cluster is located, and the offset (in bits) into
badafa ¤   // that sector where the cluster begins.
0daf5a
f42361 ¤   if (derr.IsntError())
30c7a1 ¤   {
041423 ¤   ¤   curClust = firstClustFile;
24af5a
406003 ¤   ¤   GetClusterInfo(firstSecFat, curClust, bitsClust, blockSize, &clustSec,·
878cae ¤   ¤   ¤   &bitOffset);
9daf5a
ea951d ¤   ¤   // Before parsing the FAT table we read the current sector into a
--e739 000604ebc4b40110129 Page 16 of FatParser.cpp
70996a ¤   ¤   // buffer. WE MUST read in the extra sector because FAT12 clusters can
678a56 ¤   ¤   // overrun the boundary.
a5af5a
540c6f ¤   ¤   derr = mHost.Read(mDataBuf, clustSec, kFPDataBufSize + 1);
6d9371 ¤   }
d4af5a
c42361 ¤   if (derr.IsntError())
cec7a1 ¤   {
980a5e ¤   ¤   ParseNextClusterInfo PNCI;
4aaf5a
62bd20 ¤   ¤   PNCI.blockSize¤ = blockSize;
f24b10 ¤   ¤   PNCI.clustBias¤ = clustBias;
e25deb ¤   ¤   PNCI.spc¤   ¤   = spc;
76af5a
0e7fbd ¤   ¤   PNCI.bitsClust¤ ¤   = bitsClust;
ae13a9 ¤   ¤   PNCI.bitOffset¤ ¤   = bitOffset;
39a7c4 ¤   ¤   PNCI.clustSec¤  ¤   = clustSec;
9f99f6 ¤   ¤   PNCI.curClust¤  ¤   = curClust;
b7cf21 ¤   ¤   PNCI.firstSecData¤  = firstSecData;
569e5c ¤   ¤   PNCI.firstSecFat¤   = firstSecFat;
821452 ¤   ¤   PNCI.i¤ ¤   ¤   ¤   = i;
63a2fc ¤   ¤   PNCI.nextClust¤ ¤   =·
fd0739 ¤   ¤   ¤   ExtractCluster(mDataBuf, bitOffset, curClust, mFsId);
b3c275 ¤   ¤   PNCI.overFlow¤  ¤   = 0;
bcfa7a ¤   ¤   PNCI.totalClusts¤   = totalClusts;
ffaf5a
ea78ab ¤   ¤   // We now construct the file fragment list by parsing the FAT table.
f9e2c8 ¤   ¤   // Beginning with the first cluster of the file, we iterate over all
b89c8e ¤   ¤   // remaining clusters until finished.
7165af ¤   ¤   //
1fb315 ¤   ¤   // As long as the cluster two numbers, it refers to a valid cluster
d145af ¤   ¤   // index; else it means the file has ended.
cbaf5a
11ce5c ¤   ¤   while (derr.IsntError() && (PNCI.nextClust >= minClust) &&·
20386e ¤   ¤   ¤   (PNCI.nextClust <= maxClust))
325b34 ¤   ¤   {
80533c ¤   ¤   ¤   derr = ParseNextCluster(&PNCI);
dd0fe4 ¤   ¤   }
a5af5a
c8443a ¤   ¤   i = PNCI.i;
3c9371 ¤   }
23af5a
19273a ¤   // The file has been completely parsed.
622361 ¤   if (derr.IsntError())
72c7a1 ¤   {
0a422c ¤   ¤   mFragArray[i].fileEnd¤  += (spc*blockSize) - 1;
4cd781 ¤   ¤   mFragArray[i].diskEnd¤  += (spc*blockSize) - 1;
2eaf5a
2ea4f7 ¤   ¤   // Does combined size of the fragments agree with the actual file size?
62ef39 ¤   ¤   if ((mFragArray[i].fileEnd < (mBytesFile - spc*blockSize)) ||
4e0c29 ¤   ¤   ¤   (mFragArray[i].fileEnd > (mBytesFile + spc*blockSize)))
da5b34 ¤   ¤   {
d23c52 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_CorruptFat);
a80fe4 ¤   ¤   }
bd9371 ¤   }
3aaf5a
f14bb3 ¤   if (derr.IsError())
05c7a1 ¤   {
8ee256 ¤   ¤   mNumFragsInUse = 0;
329371 ¤   }
bfaf5a
2933e3 ¤   return derr;
56efe6 }
22af5a
e01ce3 // ExecuteRequest executes the next 'piece' of the current request. If there
51e4bc // nothing left to execute, 'doneWithRequest' is set to TRUE, otherwise FALSE.
3caf5a
4cc823 void·
38084d FatParser::ExecuteRequest(PGPBoolean *doneWithRequest)
ebbb36 {
d4d960 ¤   PGPUInt8¤   *buf;
60da0e ¤   PGPUInt16¤  blockSize;
--6c28 000499b917440110129 Page 17 of FatParser.cpp
7ed26d ¤   PGPUInt32¤  i, nBytes, sizeChunk;
5f739f ¤   PGPUInt64¤  blockVolume, pos;
c0af5a
d35072 ¤   pgpAssertAddrValid(doneWithRequest, PGPBoolean);
46e5ac ¤   (* doneWithRequest) = FALSE;
4baf5a
be4b37 ¤   pgpAssert(mFatParserReq.isInUse);
b1af5a
4b23c5 ¤   // Look for the next piece of the request and process it. Read requests
104886 ¤   // can consist of reading the header, the tail, or any number of pieces
8e1199 ¤   // in the middle. Write requests are similar except header and tail
77659c ¤   // processing must be done in two parts.
5d67c5 ¤
ac798e ¤   switch (mFatParserReq.op)
f5c7a1 ¤   {
02af5a
87c546 ¤   case kFPOP_Read:
406c21 ¤   ¤   blockSize = mHost.GetBlockSize();
88af5a
52022a ¤   ¤   if (!mFatParserReq.read.readHeader)
935b34 ¤   ¤   {
000f8f ¤   ¤   ¤   // Read in the header block.
e3af5a
356633 ¤   ¤   ¤   pos = mFatParserReq.read.posHeader;
0155f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
6caf5a
9d3250 ¤   ¤   ¤   blockVolume¤= CalcDiskSector(pos, &mFragArray[i], blockSize);
3aaf5a
40b8b0 ¤   ¤   ¤   mHost.Read(mDataBuf, blockVolume, 1, &mFatParserReq.downInfo);
f00fe4 ¤   ¤   }
a36d6b ¤   ¤   else if (!mFatParserReq.read.readMiddle)
fe5b34 ¤   ¤   {
9e00c9 ¤   ¤   ¤   // Read in as much of the middle as we can. Leave the rest for
70bf29 ¤   ¤   ¤   // later.
6daf5a
61023b ¤   ¤   ¤   buf¤¤   = mFatParserReq.read.bufMiddle;
a7f8fb ¤   ¤   ¤   pos¤¤   = mFatParserReq.read.posMiddle;
7589fc ¤   ¤   ¤   nBytes¤ = mFatParserReq.read.nBytesMiddle;
57ab8f ¤   ¤   ¤   i¤  ¤   = FindFragmentIndex(pos);
5faf5a
c9ea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
975526 ¤   ¤   ¤   sizeChunk = min(nBytes/blockSize, (PGPUInt32)·
279581 ¤   ¤   ¤   ¤   ((mFragArray[i].fileEnd - pos) / blockSize) + 1);
35af5a
27af80 ¤   ¤   ¤   mFatParserReq.read.sizeCurrentRead = sizeChunk*blockSize;
6baf5a
dd359e ¤   ¤   ¤   mHost.Read(buf, blockVolume, sizeChunk, &mFatParserReq.downInfo);
b30fe4 ¤   ¤   }
eabe65 ¤   ¤   else if (!mFatParserReq.read.readTail)
665b34 ¤   ¤   {
2a752b ¤   ¤   ¤   // Read in the tail block.
7aaf5a
0b1d90 ¤   ¤   ¤   pos = mFatParserReq.read.posTail;
c755f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
c1af5a
4dea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
8aaf5a
50b8b0 ¤   ¤   ¤   mHost.Read(mDataBuf, blockVolume, 1, &mFatParserReq.downInfo);
580fe4 ¤   ¤   }
350e1d ¤   ¤   else
175b34 ¤   ¤   {
f03c5b ¤   ¤   ¤   (* doneWithRequest) = TRUE;
b20fe4 ¤   ¤   }
f12f68 ¤   ¤   break;
c3af5a
d8c068 ¤   case kFPOP_Write:
5a6c21 ¤   ¤   blockSize = mHost.GetBlockSize();
41af5a
0e2c75 ¤   ¤   if (!mFatParserReq.write.readHeader)
7a5b34 ¤   ¤   {
1a9334 ¤   ¤   ¤   // Read in the header block. This must be done because we can't
49bded ¤   ¤   ¤   // write in units smaller than one block. Once we've read in
--f142 000e37ab7ab40110129 Page 18 of FatParser.cpp
d29ed8 ¤   ¤   ¤   // the header, we modify it with data from the input buffer,
2e40a1 ¤   ¤   ¤   // and write it out.
8f87c7 ¤   ¤   ¤
877daa ¤   ¤   ¤   pos = mFatParserReq.write.posHeader;
d755f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
d0af5a
13ea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
a2af5a
18b8b0 ¤   ¤   ¤   mHost.Read(mDataBuf, blockVolume, 1, &mFatParserReq.downInfo);
250fe4 ¤   ¤   }
840b32 ¤   ¤   else if (!mFatParserReq.write.wroteHeader)
ec5b34 ¤   ¤   {
579d34 ¤   ¤   ¤   // We read in the header block, now modify it with the changed
b5e87c ¤   ¤   ¤   // data from the input buffer and write it out.
3f87c7 ¤   ¤   ¤
1d4367 ¤   ¤   ¤   buf¤¤   ¤   = mFatParserReq.write.bufHeader;
309ab4 ¤   ¤   ¤   pos¤¤   ¤   = mFatParserReq.write.posHeader;
b2fbdb ¤   ¤   ¤   nBytes¤ ¤   = mFatParserReq.write.nBytesHeader;
8e51d0 ¤   ¤   ¤   i¤  ¤   ¤   = FindFragmentIndex(pos);
383250 ¤   ¤   ¤   blockVolume¤= CalcDiskSector(pos, &mFragArray[i], blockSize);
9eaf5a
a82b96 ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
40a046 ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf + pos%blockSize, nBytes);
ed87c7 ¤   ¤   ¤
288ad4 ¤   ¤   ¤   mHost.Write(mDataBuf, blockVolume, 1, &mFatParserReq.downInfo);
500fe4 ¤   ¤   }
c0c9bd ¤   ¤   else if (!mFatParserReq.write.wroteMiddle)
b85b34 ¤   ¤   {
c1abfc ¤   ¤   ¤   // Encrypt and write out as much of the middle as we can. Leave
afb7bf ¤   ¤   ¤   // the rest for later.
d3af5a
4081e8 ¤   ¤   ¤   buf¤¤   ¤   = mFatParserReq.write.bufMiddle;
e0583b ¤   ¤   ¤   pos¤¤   ¤   = mFatParserReq.write.posMiddle;
fc3954 ¤   ¤   ¤   nBytes¤ ¤   = mFatParserReq.write.nBytesMiddle;
c051d0 ¤   ¤   ¤   i¤  ¤   ¤   = FindFragmentIndex(pos);
adaf5a
4fea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
9d5526 ¤   ¤   ¤   sizeChunk = min(nBytes/blockSize, (PGPUInt32)·
db9581 ¤   ¤   ¤   ¤   ((mFragArray[i].fileEnd - pos) / blockSize) + 1);
3faf5a
69be3e ¤   ¤   ¤   mFatParserReq.write.sizeCurrentWrite = sizeChunk*blockSize;
61af5a
6ad6a0 ¤   ¤   ¤   mHost.Write(buf, blockVolume, sizeChunk, &mFatParserReq.downInfo);
ef0fe4 ¤   ¤   }
8be7a9 ¤   ¤   else if (!mFatParserReq.write.readTail)
305b34 ¤   ¤   {
4011ec ¤   ¤   ¤   // Read in the tail block. This must be done because we can't
92bded ¤   ¤   ¤   // write in units smaller than one block. Once we've read in
b5aea0 ¤   ¤   ¤   // the tail, we modify it with data from the input buffer,
d240a1 ¤   ¤   ¤   // and write it out.
9087c7 ¤   ¤   ¤
29a2f2 ¤   ¤   ¤   pos = mFatParserReq.write.posTail;
5055f6 ¤   ¤   ¤   i = FindFragmentIndex(pos);
c9af5a
2cea82 ¤   ¤   ¤   blockVolume = CalcDiskSector(pos, &mFragArray[i], blockSize);
5caf5a
54b8b0 ¤   ¤   ¤   mHost.Read(mDataBuf, blockVolume, 1, &mFatParserReq.downInfo);
920fe4 ¤   ¤   }
659297 ¤   ¤   else if (!mFatParserReq.write.wroteTail)
a25b34 ¤   ¤   {
b98007 ¤   ¤   ¤   // We read in the tail block, now modify it with the changed
f4e87c ¤   ¤   ¤   // data from the input buffer and write it out.
c2af5a
64d6b5 ¤   ¤   ¤   buf¤¤   ¤   = mFatParserReq.write.bufTail;
675638 ¤   ¤   ¤   nBytes¤ ¤   = mFatParserReq.write.nBytesTail;
c3c3e2 ¤   ¤   ¤   pos¤¤   ¤   = mFatParserReq.write.posTail;
7551d0 ¤   ¤   ¤   i¤  ¤   ¤   = FindFragmentIndex(pos);
103250 ¤   ¤   ¤   blockVolume¤= CalcDiskSector(pos, &mFragArray[i], blockSize);
e6af5a
c32b96 ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
22a046 ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf + pos%blockSize, nBytes);
e387c7 ¤   ¤   ¤
--6835 00086beb62140110129 Page 19 of FatParser.cpp
4c8ad4 ¤   ¤   ¤   mHost.Write(mDataBuf, blockVolume, 1, &mFatParserReq.downInfo);
3a0fe4 ¤   ¤   }
220e1d ¤   ¤   else
c45b34 ¤   ¤   {
e33c5b ¤   ¤   ¤   (* doneWithRequest) = TRUE;
540fe4 ¤   ¤   }
7f2f68 ¤   ¤   break;
1caf5a
da2f72 ¤   default:
0d8f52 ¤   ¤   pgpAssert(FALSE);
612f68 ¤   ¤   break;
cd9371 ¤   }
8aefe6 }
5aaf5a
b4644b // FatParserCallback is called as a callback by the routines who executed our
cffdd9 // read and write requests. We extract the address of the FatParser object in
d86321 // question and pass the callback to it.
85af5a
34c823 void·
48b48e FatParser::FatParserCallback(GenericCallbackInfo *downInfo)
fbbb36 {
dd1710 ¤   FatParser *pFP;
9caf5a
99ac07 ¤   pgpAssertAddrValid(downInfo, GenericCallbackInfo);
9aaf5a
9875d2 ¤   pFP = (FatParser *) downInfo->refData[0];
08aa2a ¤   pgpAssertAddrValid(pFP, FatParser);
0caf5a
de2309 ¤   pFP->FatParserCallbackAux();
8aefe6 }
ebaf5a
17aa54 // FatParserCallbackAux is called by the static callback function
e92c45 // 'FatParserCallback' so we don't have to type 'pFP' before every reference
70afa4 // to an object member or method.
72af5a
4ac823 void·
6f92b7 FatParser::FatParserCallbackAux()
72bb36 {
58be41 ¤   DualErr¤¤   derr;
7ac91d ¤   PGPBoolean¤ doneWithRequest;
65d960 ¤   PGPUInt8¤   *buf;
aada0e ¤   PGPUInt16¤  blockSize;
a5644f ¤   PGPUInt32¤  nBytes;
f9d5b8 ¤   PGPUInt64¤  pos;
76af5a
704b37 ¤   pgpAssert(mFatParserReq.isInUse);
b0a41e ¤   blockSize = mHost.GetBlockSize();¤
b1af5a
0cf5f3 ¤   derr = mFatParserReq.downInfo.derr;
dfaf5a
8a2361 ¤   if (derr.IsntError())
0ac7a1 ¤   {
052555 ¤   ¤   // Before passing the request to 'ExecuteRequest' we perform some pre-
a465b2 ¤   ¤   // processing on the data manipulated by the piece of the request that
6f0ae3 ¤   ¤   // was just processed.
38af5a
bb4e86 ¤   ¤   switch (mFatParserReq.op)
0f5b34 ¤   ¤   {
60af5a
d37497 ¤   ¤   case kFPOP_Read:
051a7a ¤   ¤   ¤   if (!mFatParserReq.read.readHeader)
55e39b ¤   ¤   ¤   {¤  ¤   ¤
d564fb ¤   ¤   ¤   ¤   // We read in the header block. Copy just what the caller needs
c66fdb ¤   ¤   ¤   ¤   // into his buffer.
f72b85 ¤   ¤   ¤   ¤
e39411 ¤   ¤   ¤   ¤   mFatParserReq.read.readHeader = TRUE;
f7af5a
fc9518 ¤   ¤   ¤   ¤   buf¤¤   = mFatParserReq.read.bufHeader;
da6fd8 ¤   ¤   ¤   ¤   pos¤¤   = mFatParserReq.read.posHeader;
e44c48 ¤   ¤   ¤   ¤   nBytes¤ = mFatParserReq.read.nBytesHeader;
06af5a
86f324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
--84de 000ff05330c40110129 Page 20 of FatParser.cpp
e0af5a
ae2bb3 ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf + pos%blockSize, buf, nBytes);
c6a3a6 ¤   ¤   ¤   }
c63e70 ¤   ¤   ¤   else if (!mFatParserReq.read.readMiddle)
09f776 ¤   ¤   ¤   {
977506 ¤   ¤   ¤   ¤   PGPUInt32 bytesRead;
44af5a
f93652 ¤   ¤   ¤   ¤   // We read in a piece of the middle. Copy it into the output
6aaa03 ¤   ¤   ¤   ¤   // buffer, and if there is still more middle left then adjust
db2ecf ¤   ¤   ¤   ¤   // the variables.
182b85 ¤   ¤   ¤   ¤
88f45b ¤   ¤   ¤   ¤   buf¤¤   ¤   = mFatParserReq.read.bufMiddle;
243b0b ¤   ¤   ¤   ¤   pos¤¤   ¤   = mFatParserReq.read.posMiddle;
d9fe24 ¤   ¤   ¤   ¤   nBytes¤ ¤   = mFatParserReq.read.nBytesMiddle;
b15aa5 ¤   ¤   ¤   ¤   bytesRead¤  = mFatParserReq.read.sizeCurrentRead;
f8af5a
a2f324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
faaf5a
11bec6 ¤   ¤   ¤   ¤   if (nBytes - bytesRead > 0)
f572c3 ¤   ¤   ¤   ¤   {
ebd51d ¤   ¤   ¤   ¤   ¤   mFatParserReq.read.bufMiddle¤   ¤   += bytesRead;
00dbbc ¤   ¤   ¤   ¤   ¤   mFatParserReq.read.posMiddle¤   ¤   += bytesRead;
d54457 ¤   ¤   ¤   ¤   ¤   mFatParserReq.read.nBytesMiddle¤¤   -= bytesRead;
d62613 ¤   ¤   ¤   ¤   }
dcfa07 ¤   ¤   ¤   ¤   else
0572c3 ¤   ¤   ¤   ¤   {
b007aa ¤   ¤   ¤   ¤   ¤   mFatParserReq.read.readMiddle = TRUE;
f12613 ¤   ¤   ¤   ¤   }
0ea3a6 ¤   ¤   ¤   }
db66d7 ¤   ¤   ¤   else if (!mFatParserReq.read.readTail)
9ff776 ¤   ¤   ¤   {
e64be4 ¤   ¤   ¤   ¤   // We read in the tail block. Copy just what the caller needs
7b6fdb ¤   ¤   ¤   ¤   // into his buffer.
67af5a
d27382 ¤   ¤   ¤   ¤   mFatParserReq.read.readTail = TRUE;
5baf5a
95c11a ¤   ¤   ¤   ¤   buf = mFatParserReq.read.bufTail;
943140 ¤   ¤   ¤   ¤   nBytes = mFatParserReq.read.nBytesTail;
beaf5a
72f324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
65af5a
5b6b1e ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf, buf, nBytes);
07a3a6 ¤   ¤   ¤   }
74cdcb ¤   ¤   ¤   break;
50af5a
2807dd ¤   ¤   case kFPOP_Write:
697ee8 ¤   ¤   ¤   if (!mFatParserReq.write.readHeader)
32f776 ¤   ¤   ¤   {
62d1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
aca721 ¤   ¤   ¤   ¤   mFatParserReq.write.readHeader = TRUE;
eda3a6 ¤   ¤   ¤   }
671a15 ¤   ¤   ¤   else if (!mFatParserReq.write.wroteHeader)
fef776 ¤   ¤   ¤   {
02d1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
995b09 ¤   ¤   ¤   ¤   mFatParserReq.write.wroteHeader = TRUE;
97a3a6 ¤   ¤   ¤   }
20d89a ¤   ¤   ¤   else if (!mFatParserReq.write.wroteMiddle)
e6f776 ¤   ¤   ¤   {
6e1952 ¤   ¤   ¤   ¤   PGPUInt32 bytesWritten;
8faf5a
db1993 ¤   ¤   ¤   ¤   // We wrote out a piece of the middle. Copy it into the output
5daa03 ¤   ¤   ¤   ¤   // buffer, and if there is still more middle left then adjust
212ecf ¤   ¤   ¤   ¤   // the variables.
c22b85 ¤   ¤   ¤   ¤
e71cea ¤   ¤   ¤   ¤   buf¤¤   ¤   ¤   = mFatParserReq.write.bufMiddle;
4ed989 ¤   ¤   ¤   ¤   pos¤¤   ¤   ¤   = mFatParserReq.write.posMiddle;
769127 ¤   ¤   ¤   ¤   nBytes¤ ¤   ¤   = mFatParserReq.write.nBytesMiddle;
cd1fd5 ¤   ¤   ¤   ¤   bytesWritten¤   = mFatParserReq.write.sizeCurrentWrite;
6baf5a
83f324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
dcaf5a
ff2042 ¤   ¤   ¤   ¤   if (nBytes - bytesWritten > 0)
--1895 00044c6ed2840110129 Page 21 of FatParser.cpp
d072c3 ¤   ¤   ¤   ¤   {
6245ca ¤   ¤   ¤   ¤   ¤   mFatParserReq.write.bufMiddle¤  ¤   += bytesWritten;
021a93 ¤   ¤   ¤   ¤   ¤   mFatParserReq.write.posMiddle¤  ¤   += bytesWritten;
9995b6 ¤   ¤   ¤   ¤   ¤   mFatParserReq.write.nBytesMiddle¤   -= bytesWritten;
cc2613 ¤   ¤   ¤   ¤   }
33fa07 ¤   ¤   ¤   ¤   else
9272c3 ¤   ¤   ¤   ¤   {
224492 ¤   ¤   ¤   ¤   ¤   mFatParserReq.write.wroteMiddle = TRUE;
ab2613 ¤   ¤   ¤   ¤   }
7da3a6 ¤   ¤   ¤   }
e471e8 ¤   ¤   ¤   else if (!mFatParserReq.write.readTail)
b6f776 ¤   ¤   ¤   {
e3d1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
0c5b44 ¤   ¤   ¤   ¤   mFatParserReq.write.readTail = TRUE;
6ea3a6 ¤   ¤   ¤   }
c7c18c ¤   ¤   ¤   else if (!mFatParserReq.write.wroteTail)
8df776 ¤   ¤   ¤   {
c5d1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
dcdf3c ¤   ¤   ¤   ¤   mFatParserReq.write.wroteTail = TRUE;
eaa3a6 ¤   ¤   ¤   }
0dcdcb ¤   ¤   ¤   break;
f4af5a
6f9ae3 ¤   ¤   default:
740606 ¤   ¤   ¤   pgpAssert(FALSE);
a6cdcb ¤   ¤   ¤   break;
2a0fe4 ¤   ¤   }
0faf5a
d5eebc ¤   ¤   // Perform further processing on this request, if needed.
619067 ¤   ¤   ExecuteRequest(&doneWithRequest);
289371 ¤   }
28af5a
717f84 ¤   // Callback if we're done or on error.
515c5f ¤   if (doneWithRequest || derr.IsError())
60c7a1 ¤   {
e8c030 ¤   ¤   ScheduleAsyncCallback(derr);
bb9371 ¤   }
59efe6 }
6faf5a
dff5b3 // ScheduleAsyncCallback schedules a windows event that calls our function
53e5b4 // that will call the asynchronous request up.
7caf5a
0dc823 void·
6c4c5f FatParser::ScheduleAsyncCallback(DualErr derr)
11bb36 {
148883 ¤   static RestrictedEvent_THUNK callbackThunk;
a9af5a
c962fc ¤   pgpAssertAddrValid(mFatParserReq.upInfo, GenericCallbackInfo);
cf31a5 ¤   mFatParserReq.upInfo->derr = derr;
05af5a
ee5424 ¤   Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED, (PVOID) this,·
6f6ef4 ¤   ¤   AsyncExecuteCallback, 0, &callbackThunk);
9fefe6 }
43af5a
371652 // AsyncExecuteCallback was scheduled by 'ScheduleAsyncCallback' for the
e2950e // purpose of calling back up the asynchronous request we received.
69af5a
11a1ba VOID·
92b45d __stdcall·
d6c9af FatParser::AsyncExecuteCallback(
0fbfb0 ¤   VMHANDLE¤   ¤   hVM,·
9f518d ¤   THREADHANDLE¤   hThread,·
42d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
e758d6 ¤   PCLIENT_STRUCT¤ pRegs)
1bbb36 {
471710 ¤   FatParser *pFP;
0aaf5a
3ba291 ¤   pFP = (FatParser *) Refdata;
e3aa2a ¤   pgpAssertAddrValid(pFP, FatParser);
61af5a
3f24bd ¤   pgpAssert(pFP->mFatParserReq.isInUse);
c24130 ¤   pFP->mFatParserReq.isInUse = FALSE;
44af5a
--3ada 001beb943d840110129 Page 22 of FatParser.cpp
f7e5ef ¤   pgpAssertAddrValid(pFP->mFatParserReq.upInfo, GenericCallbackInfo);
ee844c ¤   pFP->mFatParserReq.upInfo->callback(pFP->mFatParserReq.upInfo);
beefe6 }
--a889 0007c252efa4011012a Page 1 of FatParser.h
541bc3 //////////////////////////////////////////////////////////////////////////////
2081dd // FatParser.h
08465d //
2fd09e // Declaration of class FatParser.
ff1bc3 //////////////////////////////////////////////////////////////////////////////
aaaf5a
54918f // $Id: FatParser.h,v 1.1.2.7 1998/07/06 08:58:18 nryan Exp $
19af5a
85cbce // Copyright (C) 1998 by Network Associates, Inc.
fa71ae // All rights reserved.
a5af5a
683a93 #ifndef Included_FatParser_h¤   // [
863ebf #define Included_FatParser_h
2caf5a
0f3a85 #include "DualErr.h"
5a555c #include "GenericCallback.h"
73af5a
7d0b85 #include "FileSystemParser.h"
8baf5a
e8af5a
48d557 ////////
3902c9 // Types
6fd557 ////////
d9af5a
8d1899 enum FatParserOp {kFPOP_Read, kFPOP_Write};
2eaf5a
4704af // A FileFrag describes a FAT file fragment on disk. 'fragBegin' and 'fragEnd'
e41c8c // are expressed in bytes, absolute from beginning of file. 'diskBegin' and
629ddc // 'diskEnd' describe this same portion, also in bytes, but absolute from
6af31d // beginning of the volume itself.
07af5a
450b72 typedef struct FileFrag
c2bb36 {
70a2a3 ¤   PGPUInt64¤  fileBegin;
2fa636 ¤   PGPUInt64¤  fileEnd;
645030 ¤   PGPUInt64¤  diskBegin;
90a853 ¤   PGPUInt64¤  diskEnd;
f2af5a
babce5 ¤   struct FileFrag¤*prev;
99befd ¤   struct FileFrag¤*next;
28af5a
8046db } FileFrag, *PFileFrag;
02af5a
3b0cd7 // FPReadInfo holds information about read requests called down to a class
06ac0e // FatParser object.
afaf5a
9a411c typedef struct FPReadInfo
dbbb36 {
eabc9e ¤   PGPUInt8¤   *bufHeader;¤¤   ¤   // output buffer for header data
d468b9 ¤   PGPUInt64¤  posHeader;¤ ¤   ¤   // transfer position for header
6b5456 ¤   PGPUInt32¤  nBytesHeader;¤  ¤   // size of header
1a076c ¤   PGPBoolean¤ readHeader;¤¤   ¤   // done with header?
ecaf5a
d6226c ¤   PGPUInt8¤   *bufMiddle;¤¤   ¤   // output buffer for middle data
5b757a ¤   PGPUInt64¤  posMiddle;¤ ¤   ¤   // transfer position for middle
4681c3 ¤   PGPUInt32¤  nBytesMiddle;¤  ¤   // size of middle left to read
11ec8c ¤   PGPUInt32¤  sizeCurrentRead;¤   // block size of chunk being read
19053d ¤   PGPBoolean¤ readMiddle;¤¤   ¤   // done with middle?
7caf5a
a6cf17 ¤   PGPUInt8¤   *bufTail;¤  ¤   ¤   // output buffer for tail data
f7a798 ¤   PGPUInt64¤  posTail;¤   ¤   ¤   // transfer position for tail
1d9658 ¤   PGPUInt32¤  nBytesTail;¤¤   ¤   // size of tail
ac36f2 ¤   PGPBoolean¤ readTail;¤  ¤   ¤   // done with tail?
04af5a
32ad1f } FPReadInfo;
04af5a
7d4274 // FPWriteInfo holds information about write requests called down to a class
408f5e // PGPdisk object.
e1af5a
eee1bc typedef struct FPWriteInfo
6bbb36 {
7cbc9e ¤   PGPUInt8¤   *bufHeader;¤¤   ¤   // output buffer for header data
--244c 0004f6bfd0e4011012a Page 2 of FatParser.h
dd68b9 ¤   PGPUInt64¤  posHeader;¤ ¤   ¤   // transfer position for header
2d5456 ¤   PGPUInt32¤  nBytesHeader;¤  ¤   // size of header
503762 ¤   PGPBoolean¤ readHeader;¤¤   ¤   // done with header read?
05631f ¤   PGPBoolean¤ wroteHeader;¤   ¤   // done with header write?
caaf5a
c9226c ¤   PGPUInt8¤   *bufMiddle;¤¤   ¤   // output buffer for middle data
9c757a ¤   PGPUInt64¤  posMiddle;¤ ¤   ¤   // transfer position for middle
e84d87 ¤   PGPUInt32¤  nBytesMiddle;¤  ¤   // size of middle left to write
556c2e ¤   PGPUInt32¤  sizeCurrentWrite;¤  // block size of chunk being written
994a52 ¤   PGPBoolean¤ wroteMiddle;¤   ¤   // done with middle?
a2af5a
62cf17 ¤   PGPUInt8¤   *bufTail;¤  ¤   ¤   // output buffer for tail data
b3a798 ¤   PGPUInt64¤  posTail;¤   ¤   ¤   // transfer position for tail
ce9658 ¤   PGPUInt32¤  nBytesTail;¤¤   ¤   // size of tail
113886 ¤   PGPBoolean¤ readTail;¤  ¤   ¤   // done with tail read?
aa8426 ¤   PGPBoolean¤ wroteTail;¤ ¤   ¤   // done with tail write?
16af5a
d7d943 } FPWriteInfo;
e4af5a
2298aa // FPRequestInfo holds either a read or a write request.
66af5a
b66913 typedef struct FPRequestInfo
ffbb36 {
454084 ¤   PGPBoolean¤ ¤   ¤   isInUse;¤   // this object in use?
e7af4f ¤   FatParserOp¤¤   ¤   op;¤¤   ¤   // what kind of request?
77af5a
6cf214 ¤   GenericCallbackInfo¤downInfo;¤  // info for call down
ce6a97 ¤   GenericCallbackInfo¤*upInfo;¤   // info for call up
8baf5a
5b6a90 ¤   FPReadInfo¤ ¤   ¤   read;¤  ¤   // info for read requests
ca6b62 ¤   FPWriteInfo¤¤   ¤   write;¤ ¤   // info for write requests
0caf5a
70f982 } FPRequestInfo;
24af5a
2ec0a7 // ParseNextClusterInfo is used to pass information between MakeFatFrags and
889024 // ParseNextCluster.
ffaf5a
1bbd3c typedef struct ParseNextClusterInfo
3fbb36 {
3ada0e ¤   PGPUInt16¤  blockSize;
9f751d ¤   PGPUInt16¤  clustBias;
bd63b6 ¤   PGPUInt16¤  spc;
0eaf5a
0bd570 ¤   PGPUInt32¤  bitsClust;
5a0a17 ¤   PGPUInt32¤  bitOffset;
6efcd5 ¤   PGPUInt32¤  clustSec;
c1c278 ¤   PGPUInt32¤  curClust;
2137d5 ¤   PGPUInt32¤  firstSecData;
ba7e59 ¤   PGPUInt32¤  firstSecFat;
e70721 ¤   PGPUInt32¤  i;
03321b ¤   PGPUInt32¤  nextClust;
c0b198 ¤   PGPUInt32¤  overFlow;
a44456 ¤   PGPUInt32¤  totalClusts;
ecaf5a
04f893 } ParseNextClusterInfo;
c6af5a
56af5a
d8d594 //////////////////
784015 // Class FatParser
90d594 //////////////////
1daf5a
cbf2cb // FatParser is a file-system parser for FAT drives. This class is Ring-0
bed7a9 // thread-safe.
4aaf5a
a271de class FatParser : public FileSystemParser
11bb36 {
ca5ed4 public:
a3da4d ¤   DualErr¤mInitErr;
06af5a
8df818 ¤   ¤   ¤   FatParser(LPCSTR path, ·PGPUInt8 hostDrive, PGPUInt32 bytesFile);
b4f324 ¤   virtual¤~FatParser();
4faf5a
--0f18 001a261662c4011012a Page 3 of FatParser.h
80f1e8 ¤   void¤   ReadAsync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
4985fb ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo);
5d87f2 ¤   void¤   WriteAsync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
cc85fb ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo);
11af5a
8dd449 ¤   DualErr¤ReadSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
a8832b ¤   DualErr¤WriteSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
71af5a
cdfa7d ¤   DualErr¤Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
e8c1e1 ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
55b54a ¤   DualErr¤Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
b3c1e1 ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
d0af5a
fa0fb9 private:
6b4d7d ¤   FatData¤¤   ¤   mFat;¤  ¤   ¤   // FAT-specific data regarding the file
3cd090 ¤   PGPUInt8¤   ¤   *mDataBuf;¤ ¤   // block buffer
cbaf5a
90e180 ¤   PGPUInt32¤  ¤   mNumFragsInUse;¤// number of frags in the array in use
3d69e1 ¤   PGPUInt32¤  ¤   mSizeFragArray;¤// size of 'mFragArray'
8d8033 ¤   PFileFrag¤  ¤   mFragArray;¤¤   // array of file fragments on disk
74af5a
7368a7 ¤   FPRequestInfo¤  mFatParserReq;¤ // request information
f6af5a
1dffff ¤   PGPUInt64¤  ¤   ¤   ¤   CalcDiskSector(PGPUInt64 filePos, PFileFrag pFF,·
68f4c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt16 blockSize);
cfaf5a
65f9f9 ¤   DualErr¤¤   ¤   ¤   ¤   ExpandFragArray();
131d1a ¤   PGPUInt32¤  ¤   ¤   ¤   FindFragmentIndex(PGPUInt64 pos);
c61332 ¤   void¤   ¤   ¤   ¤   ¤   InitFileFrag(PFileFrag pFF, PGPUInt64 fileByte,·
d7cc99 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt64 diskByte);
faaf5a
af5c98 #if PGP_DEBUG
2afbf3 ¤   void¤   ¤   ¤   ¤   ¤   DumpFrags();
6c1e67 #endif¤ // PGP_DEBUG
d6af5a
2f826c ¤   DualErr¤¤   ¤   ¤   ¤   GetFatData();
7faf5a
5e2719 ¤   DualErr¤¤   ¤   ¤   ¤   ParseNextCluster(ParseNextClusterInfo *pPNCI);
efaa12 ¤   DualErr¤¤   ¤   ¤   ¤   MakeFatFrags();
d2af5a
d37323 ¤   void¤   ¤   ¤   ¤   ¤   ExecuteRequest(PGPBoolean *doneWithRequest);
83af5a
cc02aa ¤   static void¤¤   ¤   ¤   FatParserCallback(GenericCallbackInfo *downInfo);
2833af ¤   void¤   ¤   ¤   ¤   ¤   FatParserCallbackAux();
c1af5a
1bc4b4 ¤   void¤   ¤   ¤   ¤   ¤   ScheduleAsyncCallback(
15eb7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DualErr derr = DualErr::NoError);
44b204 ¤   static VOID __stdcall¤  AsyncExecuteCallback(VMHANDLE hVM,·
9af733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
ff6ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
2e82f7 };
32af5a
a24d21 #endif¤ // ] Included_FatParser_h
--1f20 000fd39f9454011012b Page 1 of File.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
e328a6 // File.cpp
c5465d //
73e74f // Implementation of class File.
281bc3 //////////////////////////////////////////////////////////////////////////////
a2af5a
bd68e3 // $Id: File.cpp,v 1.1.2.16.2.2 1998/09/01 01:18:16 nryan Exp $
1daf5a
52cbce // Copyright (C) 1998 by Network Associates, Inc.
7071ae // All rights reserved.
f8af5a
da06a9 #include <vtoolscp.h>
8caf5a
d79bcf #include "Required.h"
3bbfe9 #include "UtilityFunctions.h"
d6af5a
baf037 #include "File.h"
55c411 #include "Globals.h"
deaf5a
0886d2 #include LOCKED_CODE_SEGMENT
5c5269 #include LOCKED_DATA_SEGMENT
75af5a
5baf5a
d616f0 CONTEXTHANDLE procContext;
57af5a
d93e71 /////////////////////////////////////
a56d9e // Class File public member functions
0d3e71 /////////////////////////////////////
53af5a
e8bde2 // The Class File default constructor.
6aaf5a
5e84a4 File::File()
2cbb36 {
54f64a ¤   mMode = kAM_Default;
c0eb2f ¤   mOpened = mIsReadOnly = mUseInt21 = FALSE;
17af5a
e715ed ¤   mR0Handle = NULL;
785eb9 ¤   mInt21Handle = NULL;
cfaf5a
bd2185 ¤   mPath = NULL;
8b8285 ¤   mPFatParser = NULL;
b6af5a
13d39c ¤   mIsInUse = FALSE;
ac1127 ¤   mUpInfo = NULL;
8befe6 }
a2af5a
c12045 // The destructor for class File will close the file.
efaf5a
3d7def File::~File()
0dbb36 {
5a945d ¤   DualErr¤derr;
8faf5a
208984 ¤   if (Opened())
8fc7a1 ¤   {
396401 ¤   ¤   derr = Close();
f50796 ¤   ¤   pgpAssert(derr.IsntError());
839371 ¤   }
90af5a
bb08f2 ¤   ClearPath();
ebefe6 }
5daf5a
de5958 // IsHostNetworked returns TRUE if the file's host drive is remote.
5aaf5a
2977be PGPBoolean·
5e3f67 File::IsHostNetworked()
c4bb36 {
0e1148 ¤   pgpAssert(Opened());
6c8b30 ¤   return IsNetworkedPath(mPath);
b6efe6 }
28af5a
5bd00b // IsPathSet returns TRUE if a path is set, FALSE otherwise.
fdaf5a
--e122 000888e03f24011012b Page 2 of File.cpp
5a77be PGPBoolean·
d5e7b4 File::IsPathSet()
c7bb36 {
08ddb6 ¤   return (IsntNull(mPath));
2cefe6 }
19af5a
c6126b // IsReadOnly returns TRUE if the file has been opened in read-only mode,
539a91 // FALSE otherwise.
65af5a
1877be PGPBoolean·
92ac7e File::IsReadOnly()
82bb36 {
a51148 ¤   pgpAssert(Opened());
e2d939 ¤   return mIsReadOnly;
7cefe6 }
06af5a
b9ca25 // Opened returns TRUE if the file is opened, FALSE if not
caaf5a
8b77be PGPBoolean·
176e7f File::Opened()
dabb36 {
bd5296 ¤   return mOpened;
04efe6 }
17af5a
e475f0 // GetLength returns the length of the file in bytes.
bfaf5a
292292 DualErr·
a46be5 File::GetLength(PGPUInt64 *pLength)
14bb36 {
22be41 ¤   DualErr¤¤   derr;
a956c1 ¤   PGPUInt16¤  pError;
a04f7f ¤   PGPUInt32¤  length;
fbaf5a
3374ad ¤   pgpAssertAddrValid(pLength, PGPUInt32);
f91148 ¤   pgpAssert(Opened());
48af5a
485843 ¤   if (mUseInt21)
e9c7a1 ¤   {
56abc6 ¤   ¤   derr = Driver->Int21GetFileLength(mInt21Handle, &length);
ad9371 ¤   }
fb0e24 ¤   else
7ac7a1 ¤   {
cae059 ¤   ¤   length = R0_GetFileSize(mR0Handle, &pError);
20af5a
dab4e8 ¤   ¤   if (pError)
18ff91 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_R0GetFileSize, pError);
e49371 ¤   }
c0af5a
a32361 ¤   if (derr.IsntError())
4bc7a1 ¤   {
d855b6 ¤   ¤   (* pLength) = length;
cb9371 ¤   }
2faf5a
6e33e3 ¤   return derr;
bdefe6 }
f1af5a
e79a65 // SetLength sets the length of the open file to the specified value.
30af5a
a22292 DualErr·
5a4889 File::SetLength(PGPInt64 length)
6ebb36 {
3d7d36 ¤   DualErr derr;
4eaf5a
91298b ¤   // Unable to do this in Ring-0, assert.
c948e7 ¤   pgpAssert(FALSE);
53af5a
0533e3 ¤   return derr;
34efe6 }
12af5a
546e93 // GetLocalHostFileSysId returns an identifier describing the filesystem type
86789e // of the file's host drive.
88af5a
--2d51 000955b2e634011012b Page 3 of File.cpp
8ae677 DualErr
80a57e File::GetLocalHostFileSysId(FileSysId *fsId)
02bb36 {
cdbe41 ¤   DualErr¤¤   derr;
a40b5c ¤   PGPUInt8¤   hostDrive;
e6478c ¤   Volume¤ ¤   hostVol;
29af5a
311caa ¤   pgpAssertAddrValid(fsId, FileSysId);
8d1148 ¤   pgpAssert(Opened());
e9af5a
0e9ae1 ¤   hostDrive = GetLocalHostDrive();
8962fd ¤   pgpAssert(IsLegalDriveNumber(hostDrive));
5daf5a
2760f8 ¤   derr = hostVol.AttachLocalVolume(hostDrive);
95af5a
4e2361 ¤   if (derr.IsntError())
cac7a1 ¤   {
7c5e90 ¤   ¤   derr = hostVol.GetFsId(fsId);
d79371 ¤   }
d1af5a
564f90 ¤   if (hostVol.AttachedToLocalVolume())
92c7a1 ¤   {
015c39 ¤   ¤   hostVol.DetachLocalVolume();
c29371 ¤   }
e9af5a
4933e3 ¤   return derr;
6aefe6 }
c4af5a
82b5bf // GetLocalHostDrive returns the drive number of the volume that hosts this
65700f // file, but only if it is a local host.
58af5a
b15540 PGPUInt8
803387 File::GetLocalHostDrive()
3bbb36 {
8f1148 ¤   pgpAssert(Opened());
f60062 ¤   pgpAssert(!IsHostNetworked());
0aaf5a
a5a141 ¤   return DriveLetToNum(mPath[0]);
f1efe6 }
02af5a
0d39cd // GetPath returns a constant pointer to the pathname string.
36af5a
4203c3 LPCSTR·
a9ab91 File::GetPath()
00bb36 {
06a07a ¤   return (LPCSTR) mPath;
cdefe6 }
97af5a
a08a17 // SetPath sets the filename path variable.
feaf5a
802292 DualErr·
d8f2a8 File::SetPath(LPCSTR path)
f1bb36 {
be7d36 ¤   DualErr derr;
19af5a
09e7de ¤   pgpAssert(!Opened());
31af5a
9108f2 ¤   ClearPath();
08f1f9 ¤   derr = DupeString(path, &mPath);
eaaf5a
3733e3 ¤   return derr;
56efe6 }
f4af5a
914588 // ClearPath clears the filename path variable.
3aaf5a
58c823 void·
ac51b6 File::ClearPath()
53bb36 {
3ae7de ¤   pgpAssert(!Opened());
69af5a
720e6c ¤   if (mPath)
95935f ¤   ¤   delete[] mPath;
--1a31 00013eb945d4011012b Page 4 of File.cpp
e0af5a
db2185 ¤   mPath = NULL;
31efe6 }
0faf5a
a7d143 // ComparePaths compares the passed pathname with the path of the opened File
30a8d1 // object, returning TRUE if they refer to the same file.
e9af5a
e477be PGPBoolean·
1eb3e1 File::ComparePaths(LPCSTR path)
26bb36 {
831d6a ¤   pgpAssert(IsPathSet());
3f6b61 ¤   pgpAssertStrValid(mPath);
7a639f ¤   pgpAssertStrValid(path);
9caf5a
69641b ¤   return (stricmp(mPath, path) ? FALSE : TRUE);
33efe6 }
78af5a
42b285 // Open opens the file specified by 'path' with the flags specified by
d5c0f9 // 'flags'.
3b465d //
53e866 // API access means that read and write calls to the file will be done using
164b77 // the system-provided Ring-0 file access calls. Direct disk access means that
9c8528 // the API calls will be bypassed and the file will be read and written
d5887b // directly on disk. This means the driver must parse the volume's FAT table
a5b2c9 // by itself, and it does this by creating and using a file-system parser
91cf9f // object for the specific filesystem of the host drive.
3caf5a
632292 DualErr·
640858 File::Open(LPCSTR path, PGPUInt16 flags)
21bb36 {
8fbe41 ¤   DualErr¤¤   derr;
6eaa1c ¤   PGPBoolean¤ denyRead, denyWrite, mustExist, enableDirectDisk;
7ff96b ¤   PGPBoolean¤ madeParser, readOnly, weSetPath;
86af5a
ef4e37 ¤   madeParser = weSetPath = FALSE;
89af5a
d8e7de ¤   pgpAssert(!Opened());
5baf5a
28dc04 ¤   mustExist¤  ¤   ¤   = (flags & kOF_MustExist¤   ¤   ? TRUE : FALSE);
a44f5b ¤   readOnly¤   ¤   ¤   = (flags & kOF_ReadOnly¤¤   ¤   ? TRUE : FALSE);
3998f8 ¤   enableDirectDisk¤   = (flags & kOF_EnableDirectDisk¤? TRUE : FALSE);
8188bf ·¤  denyRead¤   ¤   ¤   = (flags & kOF_DenyRead¤¤   ¤   ? TRUE : FALSE);
507e48 ¤   denyWrite¤  ¤   ¤   = (flags & kOF_DenyWrite¤   ¤   ? TRUE : FALSE);
3eaf5a
155d03 ¤   // Set the path.
4ab7e2 ¤   if (IsntNull(path))
29c7a1 ¤   {
b1d8c9 ¤   ¤   pgpAssertStrValid(path);
c5af5a
714d20 ¤   ¤   derr = SetPath(path);
411537 ¤   ¤   weSetPath = derr.IsntError();
649371 ¤   }
63af5a
5a772f ¤   // Grab the file handle.
952361 ¤   if (derr.IsntError())
88c7a1 ¤   {
6ab034 ¤   ¤   pgpAssert(IsPathSet());
aadc07 ¤   ¤   derr = GetFileHandle(mustExist, readOnly, denyRead, denyWrite);
12af5a
5b49c3 ¤   ¤   mOpened = derr.IsntError();
aa9371 ¤   }
b9af5a
872361 ¤   if (derr.IsntError())
4cc7a1 ¤   {
dcca10 ¤   ¤   // Open in API or direct-disk mode?
e60a20 ¤   ¤   if (!enableDirectDisk || IsHostNetworked())
955b34 ¤   ¤   {
1f22c8 ¤   ¤   ¤   // API automatically on networked or forced-API drives.
19f275 ¤   ¤   ¤   mMode = kAM_API;
1f0fe4 ¤   ¤   }
7f0e1d ¤   ¤   else
135b34 ¤   ¤   {
--c31a 000f58d8d334011012b Page 5 of File.cpp
17f9e4 ¤   ¤   ¤   FileSysId fsId;
7aaf5a
33b3cb ¤   ¤   ¤   // Otherwise determine if host is FAT. Don't fail on error.
523636 ¤   ¤   ¤   GetLocalHostFileSysId(&fsId);
87a0db ¤   ¤   ¤   mMode = (IsFatVolume(fsId) ? kAM_DirectDisk : kAM_API);
2b0fe4 ¤   ¤   }
c9af5a
525584 ¤   ¤   // Perform special initialization for direct-disk access.
206326 ¤   ¤   if (mMode == kAM_DirectDisk)
615b34 ¤   ¤   {
f72cac ¤   ¤   ¤   PGPUInt64 bytesFile;
47af5a
10ae80 ¤   ¤   ¤   // Must flush dirty buffers to the PGPdisk file now.
b6347f ¤   ¤   ¤   if (!IsHostNetworked())
1894e1 ¤   ¤   ¤   ¤   VolFlush(GetLocalHostDrive(), NULL);
0eaf5a
fd08a5 ¤   ¤   ¤   derr = GetLength(&bytesFile);
daaf5a
a5c537 ¤   ¤   ¤   // Create the FAT-parser.
a89d3d ¤   ¤   ¤   if (derr.IsntError())
16f776 ¤   ¤   ¤   {
0e7def ¤   ¤   ¤   ¤   if (!(mPFatParser = new FatParser(GetPath(),·
4fbab1 ¤   ¤   ¤   ¤   ¤   GetLocalHostDrive(), (PGPUInt32) bytesFile)))
c972c3 ¤   ¤   ¤   ¤   {
98f217 ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
b22613 ¤   ¤   ¤   ¤   }
7faf5a
79ab78 ¤   ¤   ¤   ¤   madeParser = derr.IsntError();
cca3a6 ¤   ¤   ¤   }
a4af5a
959d3d ¤   ¤   ¤   if (derr.IsntError())
16f776 ¤   ¤   ¤   {
01382b ¤   ¤   ¤   ¤   derr = mPFatParser->mInitErr;
e9a3a6 ¤   ¤   ¤   }
bb0fe4 ¤   ¤   }
ae9371 ¤   }
9aaf5a
00a4ab ¤   // Lots of cleanup to do in case of an error.
584bb3 ¤   if (derr.IsError())
0ec7a1 ¤   {
3146a3 ¤   ¤   if (madeParser)
065b34 ¤   ¤   {
57b4f0 ¤   ¤   ¤   delete mPFatParser;
07d9be ¤   ¤   ¤   mPFatParser = NULL;
e00fe4 ¤   ¤   }
63af5a
c31671 ¤   ¤   if (mOpened)
7a5b34 ¤   ¤   {
e942b3 ¤   ¤   ¤   ReleaseFileHandle();
e32484 ¤   ¤   ¤   mOpened = FALSE;
e70fe4 ¤   ¤   }
2eaf5a
005a0a ¤   ¤   if (weSetPath)
86f8a8 ¤   ¤   ¤   ClearPath();
f09371 ¤   }
2faf5a
f433e3 ¤   return derr;
04efe6 }
52af5a
27a6bf // Close closes a previously opened File object. It releases the R0 file
4d88f1 // handle, and deletes the parser (if any).
d1af5a
8d2292 DualErr·
766628 File::Close()
d5bb36 {
2abe41 ¤   DualErr¤¤   derr;
8bef19 ¤   PGPBoolean¤ wasHostNetworked;
b80b5c ¤   PGPUInt8¤   hostDrive;
cdaf5a
ea1148 ¤   pgpAssert(Opened());
99af5a
f548c5 ¤   if (IsHostNetworked())
--088b 000a0b9b88d4011012b Page 6 of File.cpp
f7c7a1 ¤   {
cb05db ¤   ¤   wasHostNetworked = TRUE;
c49371 ¤   }
c20e24 ¤   else
3bc7a1 ¤   {
a65918 ¤   ¤   wasHostNetworked = FALSE;
f69f0c ¤   ¤   hostDrive = GetLocalHostDrive();
1c9371 ¤   }
4baf5a
3d8d15 ¤   derr = ReleaseFileHandle();
deaf5a
bd2361 ¤   if (derr.IsntError())
8cc7a1 ¤   {
b37fa5 ¤   ¤   if (mPFatParser)
7a5b34 ¤   ¤   {
a0b4f0 ¤   ¤   ¤   delete mPFatParser;
ead9be ¤   ¤   ¤   mPFatParser = NULL;
0a0fe4 ¤   ¤   }
d4af5a
7410d9 ¤   ¤   mOpened = FALSE;
aeaf5a
68f69a ¤   ¤   // We must flush data to local host drives to force the systemwide·
ba221f ¤   ¤   // FSD buffers to refill themselves with good data.
6caf5a
c3287c ¤   ¤   if (!wasHostNetworked)
10a150 ¤   ¤   ¤   VolFlush(hostDrive, VOL_DISCARD_CACHE);
5daf5a
5f4979 ¤   ¤   ClearPath();
269371 ¤   }
28af5a
0433e3 ¤   return derr;
4defe6 }
bcaf5a
3a555d // Read reads nBytes from the opened file at position pos (in bytes).
f9af5a
1f2292 DualErr·
044b6c File::Read(
cde311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
f23385 ¤   PGPUInt64¤  ¤   ¤   pos,·
1f92c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
6bf7c6 ¤   GenericCallbackInfo¤*upInfo)
ccbb36 {
87be41 ¤   DualErr¤¤   derr;
96c02e ¤   PGPBoolean¤ useAsync;
5056c1 ¤   PGPUInt16¤  pError;
a6af5a
bcb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
711148 ¤   pgpAssert(Opened());
3bb27a ¤   pgpAssert(nBytes > 0);
88b299 ¤   pgpAssert(pos <= 0xFFFFFFFF);
3aaf5a
47c2da ¤   useAsync = IsntNull(upInfo);
afaf5a
fcf2e6 ¤   // If the file was opened in kAM_API mode, read directly from the file.
452454 ¤   // Else, call down to the filesystem-specific parser.
e8af5a
0a3252 ¤   if (mMode == kAM_API)
92c7a1 ¤   {
c563aa ¤   ¤   if (mUseInt21)
f25b34 ¤   ¤   {
002128 ¤   ¤   ¤   derr = Driver->Int21ReadFile(mInt21Handle, buf, (PGPUInt32) pos,·
25fe21 ¤   ¤   ¤   ¤   nBytes);
3a0fe4 ¤   ¤   }
ad0e1d ¤   ¤   else
ae5b34 ¤   ¤   {
008e89 ¤   ¤   ¤   R0_ReadFile(FALSE, mR0Handle, (PVOID) buf, nBytes,·
61efbc ¤   ¤   ¤   ¤   (PGPUInt32) pos, &pError);
0daf5a
d2ce1c ¤   ¤   ¤   if (pError)
d47c7e ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_R0ReadFailed, pError);
b30fe4 ¤   ¤   }
a0af5a
--7312 0002c5573914011012b Page 7 of File.cpp
3eeab1 ¤   ¤   if (useAsync)
adc43b ¤   ¤   ¤   ScheduleAsyncCallback(upInfo, derr);
459371 ¤   }
e60e24 ¤   else
cec7a1 ¤   {
18be9a ¤   ¤   DualErr readErr;
98af5a
7ef85d ¤   ¤   pgpAssertAddrValid(mPFatParser, FatParser);
970561 ¤   ¤   readErr = mPFatParser->Read(buf, (PGPUInt32) pos, nBytes, upInfo);
62af5a
2b416b ¤   ¤   if (!useAsync)
5a601b ¤   ¤   ¤   derr = readErr;
839371 ¤   }
c8af5a
1233e3 ¤   return derr;
75efe6 }
f9af5a
25a531 // Write writes nBytes from the opened file at position pos (in bytes).
73af5a
1b2292 DualErr·
36d8b2 File::Write(
2ee311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
123385 ¤   PGPUInt64¤  ¤   ¤   pos,·
5492c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
8cf7c6 ¤   GenericCallbackInfo¤*upInfo)
41bb36 {
88be41 ¤   DualErr¤¤   derr;
77c02e ¤   PGPBoolean¤ useAsync;
6056c1 ¤   PGPUInt16¤  pError;
88af5a
cdb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
301148 ¤   pgpAssert(Opened());
b251fe ¤   pgpAssert(!mIsReadOnly);
ceb27a ¤   pgpAssert(nBytes > 0);
53b299 ¤   pgpAssert(pos <= 0xFFFFFFFF);
8daf5a
54c2da ¤   useAsync = IsntNull(upInfo);
b7af5a
f2df3c ¤   // If the file was opened in kAM_API mode, write directly to the file.
a12454 ¤   // Else, call down to the filesystem-specific parser.
afaf5a
fb3252 ¤   if (mMode == kAM_API)
f2c7a1 ¤   {
7463aa ¤   ¤   if (mUseInt21)
565b34 ¤   ¤   {
613b79 ¤   ¤   ¤   derr = Driver->Int21WriteFile(mInt21Handle, buf, (PGPUInt32) pos,·
65fe21 ¤   ¤   ¤   ¤   nBytes);
210fe4 ¤   ¤   }
6f0e1d ¤   ¤   else
5d5b34 ¤   ¤   {
b1d6d2 ¤   ¤   ¤   R0_WriteFile(FALSE, mR0Handle, (PVOID) buf, nBytes,·
52efbc ¤   ¤   ¤   ¤   (PGPUInt32) pos, &pError);
54af5a
24ce1c ¤   ¤   ¤   if (pError)
f27c7e ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_R0ReadFailed, pError);
300fe4 ¤   ¤   }
dfaf5a
b0eab1 ¤   ¤   if (useAsync)
3ac43b ¤   ¤   ¤   ScheduleAsyncCallback(upInfo, derr);
399371 ¤   }
810e24 ¤   else
1bc7a1 ¤   {
5ed2f0 ¤   ¤   DualErr writeErr;
afaf5a
ecf85d ¤   ¤   pgpAssertAddrValid(mPFatParser, FatParser);
5a97aa ¤   ¤   writeErr = mPFatParser->Write(buf, (PGPUInt32) pos, nBytes, upInfo);
18af5a
e1416b ¤   ¤   if (!useAsync)
e047af ¤   ¤   ¤   derr = writeErr;
2c9371 ¤   }
a7af5a
2c33e3 ¤   return derr;
--6de3 000031c3c944011012b Page 8 of File.cpp
7aefe6 }
46af5a
8eaf5a
5890e1 //////////////////////////////////////
4b57bc // Class File private member functions·
a390e1 //////////////////////////////////////
32af5a
2c94ac // GetFileHandle opens a file handle.
13af5a
862292 DualErr·
b8eeb3 File::GetFileHandle(
15bbb4 ¤   PGPBoolean¤ mustExist,·
d35044 ¤   PGPBoolean¤ readOnly,·
152102 ¤   PGPBoolean¤ denyRead,·
4f0f64 ¤   PGPBoolean¤ denyWrite)
8bbb36 {
c27d36 ¤   DualErr derr;
15af5a
986b61 ¤   pgpAssertStrValid(mPath);
a5af5a
a8eef7 ¤   mUseInt21 = FALSE;
24af5a
fb7f3a ¤   mMustExist¤ = mustExist;
a9b5c4 ¤   mIsReadOnly¤= readOnly;
e324cf ¤   mDenyRead¤  = denyRead;
8f60d9 ¤   mDenyWrite¤ = denyWrite;
c9af5a
7c2cdd ¤   // First try to get a Ring0-file-IO handle.
44a958 ¤   derr = GetR0FileHandle();
2638e5 /*
8713d3 ¤   // If failure, fall back upon int21 file handle.
c54bb3 ¤   if (derr.IsError())
0fc7a1 ¤   {
eb5f9f ¤   ¤   derr = GetInt21FileHandle();
8caf5a
1278dc ¤   ¤   // If this attempt succeeds, we must open upon every read or write
76848b ¤   ¤   // for now. Close the int21 file handle.
31af5a
d7aa35 ¤   ¤   if (derr.IsntError())
1c5b34 ¤   ¤   {
fd3fa8 ¤   ¤   ¤   mUseInt21 = TRUE;
6c8d10 ¤   ¤   ¤   ReleaseInt21FileHandle();
100fe4 ¤   ¤   }
e09371 ¤   }
327fe0 */
b733e3 ¤   return derr;
b7efe6 }
daaf5a
ec5ce9 // ReleaseFileHandle closes the file handle opened earlier.
e2af5a
662292 DualErr·
96f88b File::ReleaseFileHandle()
e6bb36 {
617d36 ¤   DualErr derr;
8caf5a
6b5843 ¤   if (mUseInt21)
65d081 ¤   ¤   derr = ReleaseInt21FileHandle();
4c0e24 ¤   else
d2ffdd ¤   ¤   derr = ReleaseR0FileHandle();
a9af5a
fb33e3 ¤   return derr;
deefe6 }
c9af5a
997fa6 // GetR0FileHandle opens a Ring-0 file-IO file handle.
d2af5a
492292 DualErr·
daa6f8 File::GetR0FileHandle()
ddbb36 {
4abe41 ¤   DualErr¤¤   derr;
599b34 ¤   PGPUInt8¤   action, pAction;
aa3f10 ¤   PGPUInt16¤  mode, pError;
03af5a
--c6b3 000c3104a374011012b Page 9 of File.cpp
ce6b61 ¤   pgpAssertStrValid(mPath);
ceaf5a
f00293 ¤   if (mIsReadOnly)
a84170 ¤   ¤   mode = OPEN_ACCESS_READONLY;
2b0e24 ¤   else
90569f ¤   ¤   mode = OPEN_ACCESS_READWRITE;
77af5a
48b8eb ¤   if (mDenyRead && mDenyWrite)
7892a5 ¤   ¤   mode |= OPEN_SHARE_DENYREADWRITE;
79e607 ¤   else if (mDenyRead)
4d5f7e ¤   ¤   mode |= OPEN_SHARE_DENYREAD;
9f46ce ¤   else if (mDenyWrite)
283d06 ¤   ¤   mode |= OPEN_SHARE_DENYWRITE;
2e0e24 ¤   else
2788b7 ¤   ¤   mode |= OPEN_SHARE_DENYNONE;
99af5a
c7ba03 ¤   if (mMustExist)
b583a7 ¤   ¤   action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_FAIL;
a50e24 ¤   else
3e09de ¤   ¤   action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_CREATE;
e4af5a
123daa ¤   mR0Handle = R0_OpenCreateFile(FALSE, (LPSTR) GetPath(), mode,·
0dc137 ¤   ¤   ATTR_NORMAL, action, NULL, &pError, &pAction);
a7af5a
dc4cbb ¤   if (pError > 0)
8ec7a1 ¤   {
da675a ¤   ¤   derr = DualErr(kPGDMinorError_R0OpenFailed, pError);
a29371 ¤   }
24af5a
e233e3 ¤   return derr;
32efe6 }
01af5a
67e091 // ReleaseR0FileHandle closes the file handle opened earlier.
d1af5a
0f2292 DualErr·
927a10 File::ReleaseR0FileHandle()
bfbb36 {
69be41 ¤   DualErr¤¤   derr;
bf56c1 ¤   PGPUInt16¤  pError;
ccaf5a
821970 ¤   R0_CloseFile(mR0Handle, &pError);
44af5a
22239b ¤   if (pError)
6bd2d7 ¤   ¤   derr = DualErr(kPGDMinorError_R0CloseFailed, pError);
bbaf5a
b62361 ¤   if (derr.IsntError())
58c7a1 ¤   {
63d258 ¤   ¤   mR0Handle = NULL;
f89371 ¤   }
7faf5a
da33e3 ¤   return derr;
3eefe6 }
83af5a
18c624 // GetInt21FileHandle acquires an int21 file handle.
ecaf5a
5e2292 DualErr·
2c6e67 File::GetInt21FileHandle()
dabb36 {
8fbe41 ¤   DualErr¤¤   derr;
e02100 ¤   PGPUInt8¤   action;
0cb189 ¤   PGPUInt16¤  mode;
4daf5a
3d6b61 ¤   pgpAssertStrValid(mPath);
8eaf5a
1b0293 ¤   if (mIsReadOnly)
cf4170 ¤   ¤   mode = OPEN_ACCESS_READONLY;
d50e24 ¤   else
0c569f ¤   ¤   mode = OPEN_ACCESS_READWRITE;
68af5a
6cb8eb ¤   if (mDenyRead && mDenyWrite)
a492a5 ¤   ¤   mode |= OPEN_SHARE_DENYREADWRITE;
c3e607 ¤   else if (mDenyRead)
--58e4 00083c4c07f4011012b Page 10 of File.cpp
095f7e ¤   ¤   mode |= OPEN_SHARE_DENYREAD;
9d46ce ¤   else if (mDenyWrite)
b93d06 ¤   ¤   mode |= OPEN_SHARE_DENYWRITE;
dd0e24 ¤   else
9f88b7 ¤   ¤   mode |= OPEN_SHARE_DENYNONE;
f6af5a
78ba03 ¤   if (mMustExist)
e883a7 ¤   ¤   action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_FAIL;
ee0e24 ¤   else
f609de ¤   ¤   action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_CREATE;
6aaf5a
d4026e ¤   derr = Driver->Int21OpenFile(GetPath(), mode, ATTR_NORMAL, action,·
2e7276 ¤   ¤   &mInt21Handle);
75af5a
ef33e3 ¤   return derr;
ceefe6 }
2daf5a
143432 // ReleaseInt21FileHandle closes an int21 file handle.
0baf5a
8c2292 DualErr·
8f579f File::ReleaseInt21FileHandle()
1fbb36 {
907d36 ¤   DualErr derr;
14af5a
aed078 ¤   derr = Driver->Int21CloseFile(mInt21Handle);
ceaf5a
002361 ¤   if (derr.IsntError())
d5c7a1 ¤   {
e16ae4 ¤   ¤   mInt21Handle = NULL;
de9371 ¤   }
86af5a
5a33e3 ¤   return derr;
12efe6 }
15af5a
d1f5b3 // ScheduleAsyncCallback schedules a windows event that calls our function
30e5b4 // that will call the asynchronous request up.
68af5a
97c823 void·
79298a File::ScheduleAsyncCallback(GenericCallbackInfo *upInfo, DualErr derr)
8fbb36 {
b28883 ¤   static RestrictedEvent_THUNK callbackThunk;
baaf5a
38e29e ¤   pgpAssert(!mIsInUse);
d0f9b5 ¤   mIsInUse = TRUE;
71af5a
c6e9ac ¤   pgpAssertAddrValid(upInfo, GenericCallbackInfo);
564b50 ¤   mUpInfo = upInfo;
2387a4 ¤   mUpInfo->derr = derr;
57af5a
945424 ¤   Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED, (PVOID) this,·
106ef4 ¤   ¤   AsyncExecuteCallback, 0, &callbackThunk);
72efe6 }
e7af5a
d31652 // AsyncExecuteCallback was scheduled by 'ScheduleAsyncCallback' for the
38950e // purpose of calling back up the asynchronous request we received.
ecaf5a
62a1ba VOID·
5bb45d __stdcall·
4c2ba7 File::AsyncExecuteCallback(
c2bfb0 ¤   VMHANDLE¤   ¤   hVM,·
3d518d ¤   THREADHANDLE¤   hThread,·
94d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
9d58d6 ¤   PCLIENT_STRUCT¤ pRegs)
17bb36 {
0ec798 ¤   File *pFile;
d4af5a
df9db1 ¤   pFile = (File *) Refdata;
ede4ca ¤   pgpAssertAddrValid(pFile, File);
79af5a
8872f6 ¤   pgpAssert(pFile->mIsInUse);
175d32 ¤   pFile->mIsInUse = FALSE;
83af5a
--5055 0010d311c324011012b Page 11 of File.cpp
814a02 ¤   pgpAssertAddrValid(pFile->mUpInfo, GenericCallbackInfo);
c55d8d ¤   pFile->mUpInfo->callback(pFile->mUpInfo);
0defe6 }
--f380 000c9335a604011012c Page 1 of File.h
541bc3 //////////////////////////////////////////////////////////////////////////////
ebdd5e // File.h
fb465d //
8329fa // Declaration of class File.
da1bc3 //////////////////////////////////////////////////////////////////////////////
d4af5a
0f4e49 // $Id: File.h,v 1.1.2.13.2.1 1998/09/01 00:31:49 nryan Exp $
20af5a
81cbce // Copyright (C) 1998 by Network Associates, Inc.
4071ae // All rights reserved.
ffaf5a
5f9f22 #ifndef Included_File_h¤// [
f3b6cf #define Included_File_h
ddaf5a
363a85 #include "DualErr.h"
e33db7 #include "FatUtils.h"
62555c #include "GenericCallback.h"
3aaf5a
0cb287 #include "FatParser.h"
d52561 #include "Volume.h"
9baf5a
e5af5a
1309b7 ////////////
94e738 // Constants
9509b7 ////////////
a8af5a
f6f624 // These are the flags for File::Open.
8026af const PGPUInt16¤kOF_MustExist¤  ¤   ¤   = 0x0001;
507589 const PGPUInt16¤kOF_ReadOnly¤   ¤   ¤   = 0x0002;
07689e const PGPUInt16¤kOF_EnableDirectDisk¤   = 0x0004;
c3a42b const PGPUInt16¤kOF_DenyRead¤   ¤   ¤   = 0x0008;
54df91 const PGPUInt16¤kOF_DenyWrite¤  ¤   ¤   = 0x0010;
27af5a
b262e9 // Access mode for the file.
6bd7d8 enum PGDFileAccessMode {kAM_Default, kAM_API, kAM_DirectDisk};
37af5a
29af5a
f133ec /////////////
6e6a85 // Class File
a933ec /////////////
30af5a
192363 // This custom File class provides for read/write access to files on drives
714e6e // using either the normal Win32 API file access functions (the
4d4f2f // IFSMgr_Ring0_FileIO functions) or by direct access to the volume using the
f0cc48 // driver's own filesystem format (FAT drives only for now). FAT volumes are
85218f // opened by default in direct access mode, unless specified otherwise
3b6ba8 // through a flag to 'Open' (not recommended because it will cause crashes).
75bd19 // Direct access is done by passing read and write calls to a file-system
dcfaf5 // parser object.
03af5a
25196f class File
4cbb36 {
6c5ed4 public:
fb6a97 ¤   ¤   ¤   ¤   File();
34edbc ¤   virtual¤¤   ~File();
0eaf5a
3b1de3 ¤   PGPBoolean¤ IsHostNetworked();
a595cc ¤   PGPBoolean¤ IsPathSet();
61793d ¤   PGPBoolean¤ IsReadOnly();
df9981 ¤   PGPBoolean¤ Opened();
46af5a
72c6d2 ¤   DualErr¤¤   GetLength(PGPUInt64 *pLength);
669a10 ¤   DualErr¤¤   SetLength(PGPInt64 length);
9baf5a
8ce329 ¤   DualErr¤¤   GetLocalHostFileSysId(FileSysId *fsId);
2d7bab ¤   PGPUInt8¤   GetLocalHostDrive();
1baf5a
f1b57c ¤   LPCSTR¤ ¤   GetPath();
e21b41 ¤   DualErr¤¤   SetPath(LPCSTR path);
a8ad62 ¤   void¤   ¤   ClearPath();
77af5a
c9edd3 ¤   PGPBoolean¤ ComparePaths(LPCSTR path);
--736b 001f6265c8d4011012c Page 2 of File.h
e0af5a
bcb043 ¤   DualErr¤¤   Open(LPCSTR path = NULL, PGPUInt16 flags = NULL);
46112b ¤   DualErr¤¤   Close();
19af5a
f3a4f4 ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
37aed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
66acdd ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
83aed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
edaf5a
1b0fb9 private:
4a90bd ¤   PGDFileAccessMode¤  mMode;¤ ¤   ¤   ¤   // access mode of the open file
6eaf5a
52908a ¤   PGPBoolean¤ ¤   ¤   mOpened;¤   ¤   ¤   // is file opened?
ff78ba ¤   PGPBoolean¤ ¤   ¤   mUseInt21;¤ ¤   ¤   // use int21 interface?
8faf5a
cdd31c ¤   PGPBoolean¤ ¤   ¤   mMustExist;¤¤   ¤   // must file exist?
fd3963 ¤   PGPBoolean¤ ¤   ¤   mIsReadOnly;¤   ¤   // opened in read-only mode?
eddf4a ¤   PGPBoolean¤ ¤   ¤   mDenyRead;¤ ¤   ¤   // deny read sharing?
7dea17 ¤   PGPBoolean¤ ¤   ¤   mDenyWrite;¤¤   ¤   // deny write sharing?
51af5a
486798 ¤   HANDLE¤ ¤   ¤   ¤   mR0Handle;¤ ¤   ¤   // Ring-0 file handle for the file
6de0e8 ¤   PGPUInt16¤  ¤   ¤   mInt21Handle;¤  ¤   // handle for int21 calls
06af5a
73f2d4 ¤   LPSTR¤  ¤   ¤   ¤   mPath;¤ ¤   ¤   ¤   // pathname to the file
6024a4 ¤   FatParser¤  ¤   ¤   *mPFatParser;¤  ¤   // Parser for FAT volumes
6aaf5a
0cdb87 ¤   PGPBoolean¤ ¤   ¤   mIsInUse;¤  ¤   ¤   // object in use for async calls?
af78bb ¤   GenericCallbackInfo *mUpInfo;¤  ¤   ¤   // for faking async calls
cbaf5a
173661 ¤   DualErr¤¤   ¤   ¤   ¤   GetFileHandle(PGPBoolean mustExist = TRUE,·
24492e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean readOnly = FALSE,·
30bff7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean denyRead = FALSE,·
36fae5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean denyWrite = FALSE);
69af5a
da5325 ¤   DualErr¤¤   ¤   ¤   ¤   ReleaseFileHandle();
42af5a
622e02 ¤   DualErr¤¤   ¤   ¤   ¤   GetR0FileHandle();
7b99ff ¤   DualErr¤¤   ¤   ¤   ¤   ReleaseR0FileHandle();
c9af5a
5153aa ¤   DualErr¤¤   ¤   ¤   ¤   GetInt21FileHandle();
775787 ¤   DualErr¤¤   ¤   ¤   ¤   ReleaseInt21FileHandle();
85af5a
77b830 ¤   void¤   ¤   ¤   ¤   ¤   ScheduleAsyncCallback(GenericCallbackInfo *upInfo,·
f6eb7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DualErr derr = DualErr::NoError);
60b204 ¤   static VOID __stdcall¤  AsyncExecuteCallback(VMHANDLE hVM,·
ecf733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
996ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
4a82f7 };
21af5a
f648ae #endif¤ // ] Included_File_h
--3abb 00098116e554011012d Page 1 of FileSystemParser.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
dc0c0d // FileSystemParser.cpp
98465d //
c59518 // Implementation of class FileSystemParser.
691bc3 //////////////////////////////////////////////////////////////////////////////
89af5a
284254 // $Id: FileSystemParser.cpp,v 1.1.2.5 1998/07/06 08:58:20 nryan Exp $
4caf5a
76cbce // Copyright (C) 1998 by Network Associates, Inc.
1271ae // All rights reserved.
c4af5a
e506a9 #include <vtoolscp.h>
f1af5a
e89bcf #include "Required.h"
c9bfe9 #include "UtilityFunctions.h"
39af5a
b80b85 #include "FileSystemParser.h"
eec411 #include "Globals.h"
8faf5a
0f86d2 #include LOCKED_CODE_SEGMENT
0a5269 #include LOCKED_DATA_SEGMENT
b1af5a
aaaf5a
f219ca /////////////////////////////////////////////////
040068 // Class FileSystemParser public member functions
4219ca /////////////////////////////////////////////////
08af5a
6d8fe4 // The FileSystemParser path and Volume object overloaded constructor sets
9ecc1f // the specified path and the specified host.
8aaf5a
55597b FileSystemParser::FileSystemParser(
40f2f8 ¤   LPCSTR¤ ¤   path,·
0eb43e ¤   PGPUInt8¤   hostDrive,·
24f08f ¤   PGPUInt32¤  bytesFile)
97bb36 {
e2639f ¤   pgpAssertStrValid(path);
6d62fd ¤   pgpAssert(IsLegalDriveNumber(hostDrive));
ebaf5a
f52185 ¤   mPath = NULL;
6c9ac0 ¤   mBytesFile = bytesFile;
3daf5a
6a6056 ¤   mInitErr = mHost.AttachLocalVolume(hostDrive);
9067c5 ¤
149c32 ¤   if (mInitErr.IsntError())
80c7a1 ¤   {
1e2831 ¤   ¤   mInitErr = mHost.GetFsId(&mFsId);
a39371 ¤   }
e3af5a
3d9c32 ¤   if (mInitErr.IsntError())
99c7a1 ¤   {
88fc5c ¤   ¤   mInitErr = SetPath(path);
2f9371 ¤   }
38efe6 }
e2af5a
4c39cd // GetPath returns a constant pointer to the pathname string.
56af5a
a39c66 LPCSTR FileSystemParser::GetPath()
8bbb36 {
bfa07a ¤   return (LPCSTR) mPath;
c0efe6 }
6baf5a
948a17 // SetPath sets the filename path variable.
3faf5a
862292 DualErr·
7f1a77 FileSystemParser::SetPath(LPCSTR path)
95bb36 {
8f7d36 ¤   DualErr derr;
6faf5a
b108f2 ¤   ClearPath();
f3af5a
c4f1f9 ¤   derr = DupeString(path, &mPath);
9833e3 ¤   return derr;
--2db1 001d5e2945d4011012d Page 2 of FileSystemParser.cpp
7aefe6 }
46af5a
cc4588 // ClearPath clears the filename path variable.
0faf5a
c1314a void
040e47 FileSystemParser::ClearPath()
53bb36 {
e80e6c ¤   if (mPath)
e3935f ¤   ¤   delete[] mPath;
43af5a
dd2185 ¤   mPath = NULL;
d5efe6 }
--b767 0011725511c4011012e Page 1 of FileSystemParser.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b7888b // FileSystemParser.h
a9465d //
da9350 // Declaration of class FileSystemParser.
421bc3 //////////////////////////////////////////////////////////////////////////////
11af5a
fd14e4 // $Id: FileSystemParser.h,v 1.1.2.7 1998/07/06 08:58:21 nryan Exp $
e4af5a
29cbce // Copyright (C) 1998 by Network Associates, Inc.
b971ae // All rights reserved.
feaf5a
0db829 #ifndef Included_FileSystemParser_h¤// [
ef3df1 #define Included_FileSystemParser_h
46af5a
cf3a85 #include "DualErr.h"
8b555c #include "GenericCallback.h"
2e3db7 #include "FatUtils.h"
8baf5a
3e2561 #include "Volume.h"
81af5a
e7af5a
f19f73 /////////////////////////
17098e // Class FileSystemParser
b09f73 /////////////////////////
03af5a
8d0189 // The purpose of a FileSystemParser object is to perform direct access (reads
a4fd24 // and writes) to a file on a disk with a particular filesystem. This access
fb3b64 // is done not using the standard system file access functions, but by reading
8644c8 // and parsing the sectors off of the disk raw. For every filesystem you wish
6c8803 // to handle, derive it from this base class. This class is Ring-0
62d7a9 // thread-safe.
6aaf5a
7c73b0 class FileSystemParser
c1bb36 {
675ed4 public:
d0da4d ¤   DualErr¤mInitErr;
f1af5a
9dee50 ¤   ¤   ¤   FileSystemParser(LPCSTR path, PGPUInt8 hostDrive,·
e5deca ¤   ¤   ¤   ¤   PGPUInt32 bytesFile);
eb36a2 ¤   virtual¤~FileSystemParser() {ClearPath();};
f2af5a
e36749 ¤   LPCSTR¤ GetPath();
924e90 ¤   DualErr¤SetPath(LPCSTR path);
566ca5 ¤   void¤   ClearPath();
5faf5a
94fa7d ¤   DualErr¤Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
3b2bae ¤   ¤   ¤   ¤   GenericCallbackInfo *gcInfo = NULL)·
057518 ¤   ¤   ¤   {return DualErr::NoError;};
68af5a
cfb54a ¤   DualErr¤Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
a592ee ¤   ¤   ¤   ¤   GenericCallbackInfo *gcInfo = NULL)
ba7518 ¤   ¤   ¤   {return DualErr::NoError;};
60af5a
afa2d3 protected:
56b742 ¤   FileSysId¤  mFsId;¤ ¤   ¤   // filesystem of the host drive
94160a ¤   LPSTR¤  ¤   mPath;¤ ¤   ¤   // path of file being accessed
ec66e6 ¤   PGPUInt32¤  mBytesFile;¤¤   // size of file
537d81 ¤   Volume¤ ¤   mHost;¤ ¤   ¤   // Volume object for file's host
8582f7 };
51af5a
174178 #endif¤ // ] Included_FileSystemParser_h
--de23 001405daf544011012f Page 1 of Globals.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b6c9cd // Globals.h
73465d //
ca8398 // Declarations for global variables used by the driver.
4a1bc3 //////////////////////////////////////////////////////////////////////////////
59af5a
b8e1e9 // $Id: Globals.h,v 1.1.2.4 1998/07/06 08:58:22 nryan Exp $
c7af5a
73cbce // Copyright (C) 1998 by Network Associates, Inc.
0871ae // All rights reserved.
30af5a
167e7c #ifndef Included_Globals_h¤ // [
5280bb #define Included_Globals_h
67af5a
e29de2 #include "CPGPdiskDrv.h"
3caf5a
baaf5a
f5c7c6 ///////////////////////////////
9d269b // Global variable declarations
1dc7c6 ///////////////////////////////
46af5a
a51e33 // All of the global variables are defined in CPGPdiskDrv.cpp.
fcaf5a
e53bd8 extern CPGPdiskDrv *Driver;¤¤   ¤   ¤   // pointer to the driver object
b1af5a
403932 #endif¤ // ] Included_Globals_h
--27c1 00061649a7e40110130 Page 1 of IopProcessor.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
d13436 // IopProcessor.cpp
36465d //
aaccee // Implementation of class IopProcessor.
d31bc3 //////////////////////////////////////////////////////////////////////////////
c6af5a
534613 // $Id: IopProcessor.cpp,v 1.1.2.17.2.1 1998/09/01 00:31:51 nryan Exp $
23af5a
3ecbce // Copyright (C) 1998 by Network Associates, Inc.
9671ae // All rights reserved.
eeaf5a
2f06a9 #include <vtoolscp.h>
08af5a
fe9bcf #include "Required.h"
41af5a
1e9de2 #include "CPGPdiskDrv.h"
bdc411 #include "Globals.h"
a4c2bc #include "IopProcessor.h"
f468c6 #include "PGPdisk.h"
f2af5a
4186d2 #include LOCKED_CODE_SEGMENT
8c5269 #include LOCKED_DATA_SEGMENT
faaf5a
f9af5a
4a68ca /////////////////////////////////////////////
a8690e // Class IopProcessor public member functions
d268ca /////////////////////////////////////////////
beaf5a
ce9b70 // The IopProcessor constructor.
f2af5a
9b1aca IopProcessor::IopProcessor()
43bb36 {
daa660 ¤   mUseAsyncIO = kDefaultUseAsyncIO;
39af5a
9e2e07 ¤   for (PGPUInt32 i=0; i<kMaxDrives; i++)
41c7a1 ¤   {
302cd9 ¤   ¤   mIopReqs[i].isBusy = FALSE;
1c9371 ¤   }
52efe6 }
a9af5a
4cebb0 // IsDriveBusy returns TRUE if the PGPdisk represented by the given drive
ebef89 // number is busy processing I/O.
72af5a
9777be PGPBoolean·
716946 IopProcessor::IsDriveBusy(PGPUInt8 drive)
cfbb36 {
f6aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
d7af5a
cf56e5 ¤   return mIopReqs[drive].isBusy;
17efe6 }
28af5a
eb6970 // SetDriveBusy marks the given drive as busy or not busy.
3eaf5a
f0c823 void·
b3fafa IopProcessor::SetDriveBusy(PGPUInt8 drive, PGPBoolean isBusy)
ecbb36 {
71aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
68af5a
145058 ¤   mIopReqs[drive].isBusy = isBusy;
1aefe6 }
04af5a
d49cce // IsIOAsync returns TRUE if I/O is currently being processed asynchronously,
9b9a91 // FALSE otherwise.
0daf5a
9977be PGPBoolean·
d6dec9 IopProcessor::IsIOAsync()
98bb36 {
793668 ¤   return mUseAsyncIO;
53efe6 }
ceaf5a
0f8610 // SetIOAsync specifies that I/O be processed either async or sync.
61af5a
--792c 0007d32cbea40110130 Page 2 of IopProcessor.cpp
84c823 void·
bf8268 IopProcessor::SetIOAsync(PGPBoolean isIOAsync)
0dbb36 {
78b1a7 ¤   mUseAsyncIO = isIOAsync;
30efe6 }
1aaf5a
85c451 // ProcessIop schedules later processing, at a safe time, of the given IOP
55664d // request. Validate the IOP and fail silently if validation fails.
25af5a
09c823 void·
e82b07 IopProcessor::ProcessIop(PIOP pIop)
81bb36 {
c5820f ¤   PDCB¤   ¤   pDcb;
ae8fa2 ¤   PGPBoolean¤ failThisRequest¤= FALSE;
72f341 ¤   PGPUInt8¤   drive;
4f023c ¤   PGPUInt16¤  failStatus;
7ee6d3 ¤   PIOR¤   ¤   pIor;
eeaf5a
8d148e ¤   pgpAssertAddrValid(pIop, IOP);
79af5a
f1eccf ¤   pIor = &pIop->IOP_ior;
5ab602 ¤   pgpAssertAddrValid(pIor, IOR);
1aaf5a
257d63 ¤   DebugOut("PGPdisk: Saw an %s\n",·
a437c1 ¤   ¤   Driver->GetIORFunctionName(pIor->IOR_func));
92af5a
1324f4 ¤   // Store a pointer to this object in the IOP itself.
bf58e4 ¤   pIor->IOR_private_port = (PGPUInt32) this;
a0af5a
e5760b ¤   switch (pIor->IOR_func)
51c7a1 ¤   {
fb1df9 ¤   case IOR_GEN_IOCTL:
b457f1 ¤   ¤   // NEVER SCHEDULE IOCTL REQUESTS. ALWAYS PROCESS IN SAME CONTEXT IN
1d0136 ¤   ¤   // WHICH THEY ARE RECEIVED.
31af5a
db9f71 ¤   ¤   IorGenIoctlDispatcher(pIop);
a12f68 ¤   ¤   break;
7faf5a
2ef612 ¤   case IOR_READ:
c8d7c1 ¤   case IOR_WRITE:
68582b ¤   ¤   // Queue the request.
42523e ¤   ¤   pDcb = (PDCB) pIop->IOP_physical_dcb;
64e7f0 ¤   ¤   pgpAssertAddrValid(pDcb, DCB);
a9af5a
757dc6 ¤   ¤   // Validate the drive letter.
9a4ce2 ¤   ¤   drive = pDcb->DCB_cmn.DCB_drive_lttr_equiv;
cbaf5a
8de989 ¤   ¤   if (!IsLegalDriveNumber(drive) ||·
1aa525 ¤   ¤   ¤   IsNull(Driver->mPGPdisks.FindPGPdisk(drive)))
d55b34 ¤   ¤   {
a046a7 ¤   ¤   ¤   failThisRequest = TRUE;
de6ead ¤   ¤   ¤   failStatus = IORS_NO_DEVICE;
230fe4 ¤   ¤   }
30af5a
1d9222 ¤   ¤   if (!failThisRequest)
bd5b34 ¤   ¤   {
ad4a33 ¤   ¤   ¤   IlbEnqueueIop(pIop, pDcb);
31af5a
2c2af1 ¤   ¤   ¤   // We must determine whether or not to schedule dispatching.
cddb9a ¤   ¤   ¤   // If I/O is in process, we don't schedule another callback -·
231cfd ¤   ¤   ¤   // this will be done later on when that I/O is finished.
c59fe4 ¤   ¤   ¤   // Otherwise we schedule a callback right now.
f5af5a
bd9f85 ¤   ¤   ¤   if (!IsDriveBusy(drive))
8bf776 ¤   ¤   ¤   {
2691cf ¤   ¤   ¤   ¤   SetDriveBusy(drive, TRUE);
0bfaa3 ¤   ¤   ¤   ¤   ScheduleIorReadWriteDispatch(drive);
aea3a6 ¤   ¤   ¤   }
c80fe4 ¤   ¤   }
5a2f68 ¤   ¤   break;
6aaf5a
7d2f72 ¤   default:
--e202 000a4d1f04340110130 Page 3 of IopProcessor.cpp
73cd5b ¤   ¤   failThisRequest = TRUE;
cf6024 ¤   ¤   failStatus = IORS_INVALID_COMMAND;
6c2f68 ¤   ¤   break;
289371 ¤   }
5caf5a
89161d ¤   if (failThisRequest)
9ec7a1 ¤   {
9d95b1 ¤   ¤   pIor->IOR_status = failStatus;
f7b7a4 ¤   ¤   --pIop->IOP_callback_ptr;¤
a8754d ¤   ¤   pIop->IOP_callback_ptr->IOP_CB_address(pIop);
439371 ¤   }
d2efe6 }
81af5a
d4af5a
569bef //////////////////////////////////////////////
9bebec // Class IopProcessor private member functions
169bef //////////////////////////////////////////////
9eaf5a
480338 // ScheduleIorReadWriteDispatch asks the system to schedule our IOR_READ and
d45d54 // IOR_WRITE dispatching function for execution at a safer time.
51af5a
42c823 void·
00c6ea IopProcessor::ScheduleIorReadWriteDispatch(PGPUInt8 drive)
d4bb36 {
94aced ¤   static RestrictedEvent_THUNK iopThunk;
e6af5a
e9aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
7daf5a
2c2c87 ¤   Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED, (PVOID) drive,·
9e5acc ¤   ¤   IorReadWriteDispatcher, 0, &iopThunk);
09efe6 }
93af5a
3fd091 // IorGenIoctlDispatcher is called in order to dispatch IOR_GEN_IOCTL
81f719 // requests.
b8af5a
edc823 void·
6724cf IopProcessor::IorGenIoctlDispatcher(PIOP pIop)
14bb36 {
9559cb ¤   PIOR pIor;
57af5a
49148e ¤   pgpAssertAddrValid(pIop, IOP);
57af5a
37eccf ¤   pIor = &pIop->IOP_ior;
f0b602 ¤   pgpAssertAddrValid(pIor, IOR);
66af5a
8cfc10 ¤   DebugOut("PGPdisk: %s initiated\n",·
8b37c1 ¤   ¤   Driver->GetIORFunctionName(pIor->IOR_func));
96af5a
1c9006 ¤   // Switch on the IOR function.
d3760b ¤   switch (pIor->IOR_func)
02c7a1 ¤   {
c33377 ¤   case IOR_GEN_IOCTL:¤¤   ¤   // an ioctl request
96cb35 ¤   ¤   Driver->mIopProcessor.ProcessIorGenIoctl(pIop);
892f68 ¤   ¤   break;
98af5a
36d47e ¤   default:¤   ¤   ¤   ¤   ¤   // otherwise fail
818f52 ¤   ¤   pgpAssert(FALSE);
4a2f68 ¤   ¤   break;
b49371 ¤   }
5defe6 }
c7af5a
490dd0 // IorReadWriteDispatcher is the event callback that is scheduled by the
aa3d20 // I/O request routine in order to dispatch IOR_READ and IOR_WRITE requests.
3eaf5a
69a1ba VOID·
2ab45d __stdcall·
f1e73b IopProcessor::IorReadWriteDispatcher(
78bfb0 ¤   VMHANDLE¤   ¤   hVM,·
bd518d ¤   THREADHANDLE¤   hThread,·
30d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
3458d6 ¤   PCLIENT_STRUCT¤ pRegs)
a4bb36 {
--5b35 00065b5d23d40110130 Page 4 of IopProcessor.cpp
99820f ¤   PDCB¤   ¤   pDcb;
f324a8 ¤   PGPBoolean¤ foundIop¤   = FALSE;
a470f5 ¤   PGPdisk¤¤   *pPGD;
13f341 ¤   PGPUInt8¤   drive;
24c33f ¤   PIOP¤   ¤   pIop;
a5af5a
8121a7 ¤   drive = (PGPUInt8) Refdata;
92aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
63af5a
7987df ¤   pPGD = Driver->mPGPdisks.FindPGPdisk(drive);
2a5b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
c7af5a
270071 ¤   pDcb = pPGD->GetDcb();
72a603 ¤   pgpAssertAddrValid(pDcb, DCB);
ccaf5a
acf800 ¤   // Any outstanding I/O for this PGPdisk?
0e69e3 ¤   if (pIop = IlbDequeueIop(pDcb))
b5c7a1 ¤   {
26bb68 ¤   ¤   PIOR pIor;
95af5a
4a557d ¤   ¤   pgpAssertAddrValid(pIop, IOP);
75af5a
7ff8e7 ¤   ¤   pIor = &pIop->IOP_ior;
4af7f1 ¤   ¤   pgpAssertAddrValid(pIor, IOR);
b1af5a
98faa8 ¤   ¤   DebugOut("PGPdisk: %s initiated\n",·
4658f2 ¤   ¤   ¤   Driver->GetIORFunctionName(pIor->IOR_func));
cfaf5a
bdd1f5 ¤   ¤   // Switch on the IOR function.
efdb55 ¤   ¤   switch (pIor->IOR_func)
4a5b34 ¤   ¤   {
b11f70 ¤   ¤   case IOR_READ:¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // a read request
b299cc ¤   ¤   case IOR_WRITE:¤¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // a write request
657d05 ¤   ¤   ¤   Driver->mIopProcessor.ProcessIorReadWrite(pIop,·
be2979 ¤   ¤   ¤   ¤   Driver->mIopProcessor.mUseAsyncIO);
9ccdcb ¤   ¤   ¤   break;
66af5a
3eb99b ¤   ¤   default:¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // otherwise fail
940606 ¤   ¤   ¤   pgpAssert(FALSE);
26cdcb ¤   ¤   ¤   break;
470fe4 ¤   ¤   }
4b9371 ¤   }
710e24 ¤   else
f9c7a1 ¤   {
eeb756 ¤   ¤   // Allow I/O to the PGPdisk.
a7fa95 ¤   ¤   Driver->mIopProcessor.SetDriveBusy(drive, FALSE);
fa9371 ¤   }
f3efe6 }
02af5a
9d1e47 // ProcessIorGenIoctl processes an IOR_GEN_IOCTL request synchronously. We
7da628 // need to process these so formatting will work on PGPdisks.
91af5a
e7c823 void·
11f92e IopProcessor::ProcessIorGenIoctl(PIOP pIop)
06bb36 {
bebe41 ¤   DualErr¤¤   derr;
97f341 ¤   PGPUInt8¤   drive;
b839fd ¤   PGPUInt16¤  iorsResult;
6fad5d ¤   PGPUInt32¤  ioctlResult;
ede6d3 ¤   PIOR¤   ¤   pIor;
6d70f5 ¤   PGPdisk¤¤   *pPGD;
27af5a
b7148e ¤   pgpAssertAddrValid(pIop, IOP);
06af5a
56eccf ¤   pIor = &pIop->IOP_ior;
bdb602 ¤   pgpAssertAddrValid(pIor, IOR);
fa67c5 ¤
8dc43a ¤   drive = pIor->IOR_ioctl_drive - 1;
8aaf5a
2d7f1d ¤   // Check for invalid drive.
cc2bd9 ¤   if ((drive == 0) || !IsLegalDriveNumber(drive) ||·
65a652 ¤   ¤   IsNull(Driver->mPGPdisks.FindPGPdisk(drive)))
--b3cf 00081cf435c40110130 Page 5 of IopProcessor.cpp
f7c7a1 ¤   {
e04e30 ¤   ¤   ioctlResult = ERROR_INVALID_DRIVE;
b287cc ¤   ¤   iorsResult = IORS_INVALID_COMMAND;
c39371 ¤   }
c30e24 ¤   else
b8c7a1 ¤   {
4bd4c4 ¤   ¤   pPGD = Driver->mPGPdisks.FindPGPdisk(drive);
5155cb ¤   ¤   pgpAssertAddrValid(pPGD, PGPdisk);
a7af5a
1ccec3 ¤   ¤   DebugOut("PGPdisk: Ioctl - drive=%c function=%x minor %x\n",·
2c1b00 ¤   ¤   ¤   DriveNumToLet(drive), pIor->IOR_ioctl_function,·
981c25 ¤   ¤   ¤   pIor->IOR_ioctl_control_param & 0xff);
22af5a
d74884 ¤   ¤   // Now process the IOCTL request. We only process some 440D functions
53e82f ¤   ¤   // and the 4411 function.
4aaf5a
d28c33 ¤   ¤   switch (pIor->IOR_ioctl_function)
ff5b34 ¤   ¤   {
f4af5a
a72254 ¤   ¤   case 0x440D:
e5c9c1 ¤   ¤   ¤   switch (GetLowByte((PGPUInt16) pIor->IOR_ioctl_control_param))
fcf776 ¤   ¤   ¤   {
5baf5a
6f98df ¤   ¤   ¤   case 0x40:¤ ¤   ¤   // Set Device Parameters
edf776 ¤   ¤   ¤   {
c08fd0 ¤   ¤   ¤   ¤   // We don't actually have to 'do' anything here. The system
44749c ¤   ¤   ¤   ¤   // will set these parameters when it writes the boot block,
d6fc74 ¤   ¤   ¤   ¤   // which is where we get them from anyways.
dfaf5a
008f5a ¤   ¤   ¤   ¤   ioctlResult = ERROR_SUCCESS;
efe51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
bbf622 ¤   ¤   ¤   ¤   break;
b7a3a6 ¤   ¤   ¤   }
5caf5a
08b47f ¤   ¤   ¤   case 0x41:¤ ¤   ¤   // Write Track on Logical Drive
63f776 ¤   ¤   ¤   {
fea089 ¤   ¤   ¤   ¤   PGPUInt8¤   *buf;
00c113 ¤   ¤   ¤   ¤   PGPUInt16¤  offset, segment;
58ff7e ¤   ¤   ¤   ¤   PGPUInt32¤  nBlocks;
feeb62 ¤   ¤   ¤   ¤   PGPUInt64¤  pos;
0d22b1 ¤   ¤   ¤   ¤   RwBlock¤¤   *pRWB;
391b52 ¤   ¤
fcf179 ¤   ¤   ¤   ¤   pRWB = (RwBlock *) pIor->IOR_ioctl_buffer_ptr;
dcaf5a
8b5384 ¤   ¤   ¤   ¤   // Calculate the starting sector.
5091d4 ¤   ¤   ¤   ¤   pos¤= pRWB->rwCylinder * kSizeCyl;
dea051 ¤   ¤   ¤   ¤   pos¤+= pRWB->rwHead * kSizeHead;
b48c0e ¤   ¤   ¤   ¤   pos¤+= pRWB->rwFirstSector;
3eaf5a
2c305e ¤   ¤   ¤   ¤   // Calculate the number of blocks to read.
3e55d2 ¤   ¤   ¤   ¤   nBlocks¤= pRWB->rwSectors;
79af5a
8f8b35 ¤   ¤   ¤   ¤   // Calculate the buffer address.
bed7ee ¤   ¤   ¤   ¤   segment = GetHighWord(pRWB->rwBuffer);
472735 ¤   ¤   ¤   ¤   offset = GetLowWord(pRWB->rwBuffer);
acaf5a
7e41e1 ¤   ¤   ¤   ¤   buf = (PGPUInt8 *) Get_Cur_VM_Handle()->CB_High_Linear +
6f015b ¤   ¤   ¤   ¤   ¤   (segment << 4) + offset;
7baf5a
196304 ¤   ¤   ¤   ¤   // Perform the write.
e248d8 ¤   ¤   ¤   ¤   derr = pPGD->Read(buf, pos*kDefaultBlockSize,·
229718 ¤   ¤   ¤   ¤   ¤   nBlocks*kDefaultBlockSize);
04af5a
5e2f21 ¤   ¤   ¤   ¤   ioctlResult = (derr.IsntError() ? ERROR_SUCCESS :
3e7ccf ¤   ¤   ¤   ¤   ¤   ERROR_INVALID_FUNCTION);
e5e51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
4df622 ¤   ¤   ¤   ¤   break;
61a3a6 ¤   ¤   ¤   }
49af5a
f0ae03 ¤   ¤   ¤   case 0x42:¤ ¤   ¤   // Format Track on Logical Drive
a0f776 ¤   ¤   ¤   {
81f889 ¤   ¤   ¤   ¤   FvBlock *pFVB;
--3665 0003fe8be1b40110130 Page 6 of IopProcessor.cpp
e587c7 ¤   ¤   ¤
97580b ¤   ¤   ¤   ¤   // Don't actually do anything, since PGPdisks aren't physical
76e8d1 ¤   ¤   ¤   ¤   // drives that need any special treatment of sectors before
9f55ba ¤   ¤   ¤   ¤   // being written to.
c0af5a
ab5bd5 ¤   ¤   ¤   ¤   pFVB = (FvBlock *) pIor->IOR_ioctl_buffer_ptr;
85af5a
d5ad84 ¤   ¤   ¤   ¤   if (pFVB->fvSpecFunc == 1)
d772c3 ¤   ¤   ¤   ¤   {
c57755 ¤   ¤   ¤   ¤   ¤   pFVB->fvSpecFunc = 0;
272613 ¤   ¤   ¤   ¤   }
62af5a
5d8f5a ¤   ¤   ¤   ¤   ioctlResult = ERROR_SUCCESS;
a1e51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
0af622 ¤   ¤   ¤   ¤   break;
eaa3a6 ¤   ¤   ¤   }
b9af5a
8cb572 ¤   ¤   ¤   case 0x60:¤ ¤   ¤   // Get Device Parameters
31f776 ¤   ¤   ¤   {
dfd88c ¤   ¤   ¤   ¤   switch (
6e2cc6 ¤   ¤   ¤   ¤   ¤   GetHighByte((PGPUInt16) pIor->IOR_ioctl_control_param))
4172c3 ¤   ¤   ¤   ¤   {
fb25fb ¤   ¤   ¤   ¤   case 0x08:
038166 ¤   ¤   ¤   ¤   ¤   derr = pPGD->GetDevParams16(
93c637 ¤   ¤   ¤   ¤   ¤   ¤   (DevParams16 *) pIor->IOR_ioctl_buffer_ptr);
f414c3 ¤   ¤   ¤   ¤   ¤   break;
d7af5a
5d5717 ¤   ¤   ¤   ¤   case 0x48:
e2db71 ¤   ¤   ¤   ¤   ¤   derr = pPGD->GetDevParams32(
6c9320 ¤   ¤   ¤   ¤   ¤   ¤   (DevParams32 *) pIor->IOR_ioctl_buffer_ptr);
ba14c3 ¤   ¤   ¤   ¤   ¤   break;
0c2613 ¤   ¤   ¤   ¤   }
e1af5a
2c2f21 ¤   ¤   ¤   ¤   ioctlResult = (derr.IsntError() ? ERROR_SUCCESS :
8b7ccf ¤   ¤   ¤   ¤   ¤   ERROR_INVALID_FUNCTION);
08e51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
54f622 ¤   ¤   ¤   ¤   break;
eaa3a6 ¤   ¤   ¤   }
b8af5a
556024 ¤   ¤   ¤   case 0x61:¤ ¤   ¤   // Read Track on Logical Drive
a8f776 ¤   ¤   ¤   {
39a089 ¤   ¤   ¤   ¤   PGPUInt8¤   *buf;
a0c113 ¤   ¤   ¤   ¤   PGPUInt16¤  offset, segment;
e2ff7e ¤   ¤   ¤   ¤   PGPUInt32¤  nBlocks;
feeb62 ¤   ¤   ¤   ¤   PGPUInt64¤  pos;
5322b1 ¤   ¤   ¤   ¤   RwBlock¤¤   *pRWB;
f61b52 ¤   ¤
21f179 ¤   ¤   ¤   ¤   pRWB = (RwBlock *) pIor->IOR_ioctl_buffer_ptr;
81af5a
b05384 ¤   ¤   ¤   ¤   // Calculate the starting sector.
5091d4 ¤   ¤   ¤   ¤   pos¤= pRWB->rwCylinder * kSizeCyl;
b2a051 ¤   ¤   ¤   ¤   pos¤+= pRWB->rwHead * kSizeHead;
f28c0e ¤   ¤   ¤   ¤   pos¤+= pRWB->rwFirstSector;
1caf5a
83305e ¤   ¤   ¤   ¤   // Calculate the number of blocks to read.
a055d2 ¤   ¤   ¤   ¤   nBlocks¤= pRWB->rwSectors;
5daf5a
d08b35 ¤   ¤   ¤   ¤   // Calculate the buffer address.
e1d7ee ¤   ¤   ¤   ¤   segment = GetHighWord(pRWB->rwBuffer);
b12735 ¤   ¤   ¤   ¤   offset = GetLowWord(pRWB->rwBuffer);
0baf5a
4e41e1 ¤   ¤   ¤   ¤   buf = (PGPUInt8 *) Get_Cur_VM_Handle()->CB_High_Linear +
ca015b ¤   ¤   ¤   ¤   ¤   (segment << 4) + offset;
a4af5a
dc37d4 ¤   ¤   ¤   ¤   // Perform the read.
6d48d8 ¤   ¤   ¤   ¤   derr = pPGD->Read(buf, pos*kDefaultBlockSize,·
cc9718 ¤   ¤   ¤   ¤   ¤   nBlocks*kDefaultBlockSize);
ccaf5a
042f21 ¤   ¤   ¤   ¤   ioctlResult = (derr.IsntError() ? ERROR_SUCCESS :
537ccf ¤   ¤   ¤   ¤   ¤   ERROR_INVALID_FUNCTION);
93e51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
3ff622 ¤   ¤   ¤   ¤   break;
--f74e 0007ac3a19e40110130 Page 7 of IopProcessor.cpp
cfa3a6 ¤   ¤   ¤   }
ccaf5a
fee82c ¤   ¤   ¤   case 0x66:¤ ¤   ¤   // Get Media ID
198cf3 ¤   ¤   ¤   {¤
bba751 ¤   ¤   ¤   ¤   derr = pPGD->GetMediaId((MID *) pIor->IOR_ioctl_buffer_ptr);
d3af5a
ff2f21 ¤   ¤   ¤   ¤   ioctlResult = (derr.IsntError() ? ERROR_SUCCESS :
f87ccf ¤   ¤   ¤   ¤   ¤   ERROR_INVALID_FUNCTION);
65e51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
c8f622 ¤   ¤   ¤   ¤   break;
39a3a6 ¤   ¤   ¤   }
c6af5a
e5db68 ¤   ¤   ¤   default:
a60512 ¤   ¤   ¤   ¤   ioctlResult = ERROR_INVALID_FUNCTION;
f6cee6 ¤   ¤   ¤   ¤   iorsResult = IORS_INVALID_COMMAND;
83f622 ¤   ¤   ¤   ¤   break;
74a3a6 ¤   ¤   ¤   }
e0cdcb ¤   ¤   ¤   break;
46af5a
82ef6c ¤   ¤   case 0x4411:¤   ¤   // Query if we handle specified 440D code
b3c9c1 ¤   ¤   ¤   switch (GetLowByte((PGPUInt16) pIor->IOR_ioctl_control_param))
d7f776 ¤   ¤   ¤   {
d67334 ¤   ¤   ¤   case 0x40:
a929e8 ¤   ¤   ¤   case 0x41:
27c68c ¤   ¤   ¤   case 0x42:
c44a42 ¤   ¤   ¤   case 0x60:
9b109e ¤   ¤   ¤   case 0x61:
469c9b ¤   ¤   ¤   case 0x66:
338f5a ¤   ¤   ¤   ¤   ioctlResult = ERROR_SUCCESS;
c9e51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
33f622 ¤   ¤   ¤   ¤   break;
46af5a
07db68 ¤   ¤   ¤   default:
260512 ¤   ¤   ¤   ¤   ioctlResult = ERROR_INVALID_FUNCTION;
dfe51a ¤   ¤   ¤   ¤   iorsResult = IORS_SUCCESS;
7cf622 ¤   ¤   ¤   ¤   break;
7fa3a6 ¤   ¤   ¤   }
10cdcb ¤   ¤   ¤   break;
feaf5a
179ae3 ¤   ¤   default:
c5ab13 ¤   ¤   ¤   ioctlResult = ERROR_INVALID_FUNCTION;
711654 ¤   ¤   ¤   iorsResult = IORS_INVALID_COMMAND;
5ccdcb ¤   ¤   ¤   break;
bb0fe4 ¤   ¤   }
d19371 ¤   }
d3af5a
acc52f ¤   pIor->IOR_ioctl_return = ioctlResult;
2c55a0 ¤   ScheduleAsyncCallback(pIop, iorsResult);
25efe6 }
cbaf5a
4929c2 // ProcessIorReadWrite processes an IOR_READ or an IOR_WRITE request
edf0cc // asynchronously.
a4af5a
ffc823 void·
ae2256 IopProcessor::ProcessIorReadWrite(PIOP pIop, PGPBoolean useAsync)
3fbb36 {
babe41 ¤   DualErr¤¤   derr;
76820f ¤   PDCB¤   ¤   pDcb;
dac91d ¤   PGPBoolean¤ doneWithRequest;
1c70f5 ¤   PGPdisk¤¤   *pPGD;
d2c8b1 ¤   PGPUInt8¤   drive, *buf;
32a293 ¤   PGPUInt16¤  blockSize, failSilentStatus;
c9e6d3 ¤   PIOR¤   ¤   pIor;
8baf5a
45148e ¤   pgpAssertAddrValid(pIop, IOP);
57af5a
91eccf ¤   pIor = &pIop->IOP_ior;
e3b602 ¤   pgpAssertAddrValid(pIor, IOR);
1a67c5 ¤
d46bfb ¤   pDcb = (PDCB) pIop->IOP_physical_dcb;
a9a603 ¤   pgpAssertAddrValid(pDcb, DCB);
7aaf5a
--76f5 0004c8372f940110130 Page 8 of IopProcessor.cpp
38daa3 ¤   drive = pDcb->DCB_cmn.DCB_drive_lttr_equiv;
46aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
1167c5 ¤
de87df ¤   pPGD = Driver->mPGPdisks.FindPGPdisk(drive);
775b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
14af5a
0678d8 ¤   blockSize = ExtractBlockSize(pDcb);
81af5a
59a0d7 ¤   pgpAssert(IsDriveBusy(drive));
a8af5a
df7957 ¤   // Reset the inactivity timer.
bdace2 ¤   Driver->mSecondsInactive = 0;
1aaf5a
64d5b4 ¤   // Verify that IO is enabled for this PGPdisk.
b45d2a ¤   if (!pPGD->IsIOEnabled())
d5c7a1 ¤   {
a3d9fe ¤   ¤   derr = kPGDMinorError_FailSilently;
2124ff ¤   ¤   failSilentStatus = IORS_NOT_READY;
0e9371 ¤   }
11af5a
f77f53 ¤   // If this is a write, verify that the volume isn't write-protected.
1e2361 ¤   if (derr.IsntError())
8ec7a1 ¤   {
0c36fa ¤   ¤   if (pIor->IOR_func == IOR_WRITE)
c35b34 ¤   ¤   {
0ec484 ¤   ¤   ¤   if (pPGD->IsReadOnly())
39f776 ¤   ¤   ¤   {
aa57ef ¤   ¤   ¤   ¤   derr = kPGDMinorError_FailSilently;
bb9e99 ¤   ¤   ¤   ¤   failSilentStatus = IORS_WRITE_PROTECT;
5ba3a6 ¤   ¤   ¤   }
a70fe4 ¤   ¤   }
b99371 ¤   }
3baf5a
abe3e6 ¤   // Prepare the request for execution.
ad2361 ¤   if (derr.IsntError())
9ec7a1 ¤   {
644fae ¤   ¤   PGPUInt32¤  i, nBytes;
9b6469 ¤   ¤   PGPUInt64¤  pos;
3daf5a
b4146c ¤   ¤   mIopReqs[drive].useAsync¤   = useAsync;
5de6e6 ¤   ¤   mIopReqs[drive].pIop¤   ¤   = pIop;
2e7340 ¤   ¤   mIopReqs[drive].pIor¤   ¤   = pIor;
6baf5a
771644 ¤   ¤   mIopReqs[drive].downInfo.callback¤  = IorReadWriteCallback;
8adc16 ¤   ¤   mIopReqs[drive].downInfo.refData[0]¤= (PGPUInt32) this;
21a75d ¤   ¤   mIopReqs[drive].downInfo.refData[1]¤= drive;
86af5a
0727c3 ¤   ¤   // Mark all the mini-request stuctures as unused.
d46a5d ¤   ¤   for (i=0; i<kIopProcMaxMinis; i++)
435b34 ¤   ¤   {
bf7fb3 ¤   ¤   ¤   mIopReqs[drive].miniReqs[i].isInUse = FALSE;
810fe4 ¤   ¤   }
a9af5a
31ca88 ¤   ¤   // Calculate the byte offset on the volume where the request begins.
81d090 ¤   ¤   pos = pIor->IOR_start_addr[0] * blockSize;
e5af5a
dd925d ¤   ¤   // Initialize the list of miniReqs that describe the I/O transfers that
93769f ¤   ¤   // make up this request.
27af5a
ec9fe0 ¤   ¤   if (!IsScatterGather(pIor))¤¤   // Just one 'piece'
695b34 ¤   ¤   {
432027 ¤   ¤   ¤   nBytes = pIor->IOR_xfer_count;
a3af5a
0a7fbd ¤   ¤   ¤   // Translate to bytes
644a87 ¤   ¤   ¤   if (!IsInBytes(pIor))
d1f776 ¤   ¤   ¤   {
cf11fd ¤   ¤   ¤   ¤   nBytes *= blockSize;
70a3a6 ¤   ¤   ¤   }
0187c7 ¤   ¤   ¤
dcb205 ¤   ¤   ¤   buf = (PGPUInt8 *) pIor->IOR_buffer_ptr;
ea2b96 ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
4caf5a
--0edd 000390329f340110130 Page 9 of IopProcessor.cpp
9f2238 ¤   ¤   ¤   // Just one minireq at position 0 for this request.
fdc2c7 ¤   ¤   ¤   mIopReqs[drive].miniReqs[0].isInUse¤= TRUE;
322efb ¤   ¤   ¤   mIopReqs[drive].miniReqs[0].buf¤¤   = buf;
f9900d ¤   ¤   ¤   mIopReqs[drive].miniReqs[0].pos¤¤   = pos;
1d54ce ¤   ¤   ¤   mIopReqs[drive].miniReqs[0].nBytes¤ = nBytes;
100fe4 ¤   ¤   }
a3367d ¤   ¤   else¤   ¤   ¤   ¤   ¤   ¤   ¤   // More than one 'piece'
535b34 ¤   ¤   {
436d8a ¤   ¤   ¤   PGPUInt32¤  curMiniReq;
cd0404 ¤   ¤   ¤   PSGD¤   ¤   pSgd;
eaaf5a
dd9744 ¤   ¤   ¤   // We are dealing with scatter/gather requests. The pointer to
408d16 ¤   ¤   ¤   // the first S/G structure will be in IOR_buffer_ptr. Each SGD
ef52ae ¤   ¤   ¤   // describes a number of bytes to transfer and provides a buffer.
35af5a
d23273 ¤   ¤   ¤   pSgd = (PSGD) pIor->IOR_buffer_ptr;
fc1477 ¤   ¤   ¤   pgpAssertAddrValid(pSgd, SGD);
dfaf5a
e16448 ¤   ¤   ¤   curMiniReq = 0;
89af5a
13551e ¤   ¤   ¤   // Initialize a separate mini-request structure for each SGD.
204ac0 ¤   ¤   ¤   while (derr.IsntError && (nBytes = pSgd->bd.SG_buff_size))
def776 ¤   ¤   ¤   {
a44897 ¤   ¤   ¤   ¤   if (curMiniReq >= kIopProcMaxMinis)
d672c3 ¤   ¤   ¤   ¤   {
125d5e ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_MiniRequestOverflow);
582613 ¤   ¤   ¤   ¤   }
4daf5a
84724e ¤   ¤   ¤   ¤   if (derr.IsntError())
2f72c3 ¤   ¤   ¤   ¤   {
3acaa7 ¤   ¤   ¤   ¤   ¤   // Translate to bytes.
7c991a ¤   ¤   ¤   ¤   ¤   if (!IsInBytes(pIor))
584859 ¤   ¤   ¤   ¤   ¤   {
0312a8 ¤   ¤   ¤   ¤   ¤   ¤   nBytes *= blockSize;
d81c89 ¤   ¤   ¤   ¤   ¤   }
b7af5a
804842 ¤   ¤   ¤   ¤   ¤   buf = (PGPUInt8 *) pSgd->bd.SG_buff_ptr;
a8e203 ¤   ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
c3af5a
b4e750 ¤   ¤   ¤   ¤   ¤   mIopReqs[drive].miniReqs[curMiniReq].isInUse¤   = TRUE;
864596 ¤   ¤   ¤   ¤   ¤   mIopReqs[drive].miniReqs[curMiniReq].buf¤   ¤   = buf;
e5e454 ¤   ¤   ¤   ¤   ¤   mIopReqs[drive].miniReqs[curMiniReq].pos¤   ¤   = pos;
a3bb59 ¤   ¤   ¤   ¤   ¤   mIopReqs[drive].miniReqs[curMiniReq].nBytes¤¤   = nBytes;
d0af5a
2370fb ¤   ¤   ¤   ¤   ¤   curMiniReq++;
a3af5a
a1be2a ¤   ¤   ¤   ¤   ¤   pos += nBytes;¤ ¤   // where the next read will begin
805d84 ¤   ¤   ¤   ¤   ¤   pSgd++;¤¤   ¤   ¤   // move on to the next S/G structure
f42613 ¤   ¤   ¤   ¤   }
f2a3a6 ¤   ¤   ¤   }
110fe4 ¤   ¤   }
ca9371 ¤   }
d0af5a
057441 ¤   // Now begin executing the request.
4f2361 ¤   if (derr.IsntError())
2fc7a1 ¤   {
c179eb ¤   ¤   // ExecuteRequest won't fail on async.
cbeab1 ¤   ¤   if (useAsync)
b83e90 ¤   ¤   ¤   ExecuteRequest(drive, &doneWithRequest);
990e1d ¤   ¤   else
0d93f4 ¤   ¤   ¤   derr = ExecuteRequest(drive, &doneWithRequest);
829371 ¤   }
16af5a
7ac983 ¤   // If we are sync, then the request has been completed. If not, then
e95c0f ¤   // doneWithRequest shouldn't be TRUE assuming we were passed valid params.
a2af5a
4b2361 ¤   if (derr.IsntError())
27c7a1 ¤   {
228d1c ¤   ¤   if (doneWithRequest)
5c5b34 ¤   ¤   {
1f0426 ¤   ¤   ¤   pgpAssert(!useAsync);
391a94 ¤   ¤   ¤   ScheduleAsyncCallback(pIop, IORS_SUCCESS);
--a71f 0007cb2608b40110130 Page 10 of IopProcessor.cpp
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
05df27 ¤   // Call back errors now.
f14bb3 ¤   if (derr.IsError())
e5c7a1 ¤   {
ce505f ¤   ¤   switch (derr.mMinorError)
2d5b34 ¤   ¤   {
a34555 ¤   ¤   case kPGDMinorError_IopRequestOverflow:
e2a47f ¤   ¤   case kPGDMinorError_MiniRequestOverflow:
66014d ¤   ¤   ¤   ScheduleAsyncCallback(pIop, IORS_BUSY);
e0cdcb ¤   ¤   ¤   break;
73af5a
43dea9 ¤   ¤   case kPGDMinorError_FailSilently:
5beb2c ¤   ¤   ¤   ScheduleAsyncCallback(pIop, failSilentStatus);
41cdcb ¤   ¤   ¤   break;
1aaf5a
0e9ae3 ¤   ¤   default:
c8fe58 ¤   ¤   ¤   if (IsntNull(pPGD))
3df776 ¤   ¤   ¤   {
5ec65b ¤   ¤   ¤   ¤   pPGD->EnableIO(FALSE);
938822 ¤   ¤   ¤   ¤   ScheduleAsyncCallback(pIop, IORS_MEDIA_ERROR);
d4af5a
eeeccc ¤   ¤   ¤   ¤   // For I/O errors, user will be asked for options.
53fe41 ¤   ¤   ¤   ¤   if (pIor->IOR_func == IOR_READ)
8172c3 ¤   ¤   ¤   ¤   {
2e88d7 ¤   ¤   ¤   ¤   ¤   Driver->ReportError(kPGDMajorError_PGPdiskReadError,·
785961 ¤   ¤   ¤   ¤   ¤   ¤   derr, pPGD->GetDrive());
492613 ¤   ¤   ¤   ¤   }
3bfa07 ¤   ¤   ¤   ¤   else
5972c3 ¤   ¤   ¤   ¤   {
138f38 ¤   ¤   ¤   ¤   ¤   Driver->ReportError(kPGDMajorError_PGPdiskWriteError,·
065961 ¤   ¤   ¤   ¤   ¤   ¤   derr, pPGD->GetDrive());
f02613 ¤   ¤   ¤   ¤   }
34a3a6 ¤   ¤   ¤   }
36bb8c ¤   ¤   ¤   else
eef776 ¤   ¤   ¤   {
0f6f82 ¤   ¤   ¤   ¤   ScheduleAsyncCallback(pIop, IORS_NO_DEVICE);
a7a3a6 ¤   ¤   ¤   }
3fcdcb ¤   ¤   ¤   break;
bb0fe4 ¤   ¤   }
299371 ¤   }
39efe6 }
51af5a
dca6de // ExecuteRequest executes the next 'piece' of the request being processed on
33de54 // the given drive. If there nothing left to execute, 'doneWithRequest' is
0676d7 // set to TRUE, otherwise FALSE.
2faf5a
3d2292 DualErr·
973fcb IopProcessor::ExecuteRequest(PGPUInt8 drive, PGPBoolean *doneWithRequest)
2ebb36 {
cbbe41 ¤   DualErr¤¤   derr;
2b6448 ¤   PGPBoolean¤ foundMiniReq¤   = FALSE;
55970c ¤   PGPBoolean¤ useAsync¤   ¤   = FALSE;
550721 ¤   PGPUInt32¤  i;
7c820f ¤   PDCB¤   ¤   pDcb;
ab70f5 ¤   PGPdisk¤¤   *pPGD;
cec33f ¤   PIOP¤   ¤   pIop;
f0e6d3 ¤   PIOR¤   ¤   pIor;
a3af5a
845072 ¤   pgpAssertAddrValid(doneWithRequest, PGPBoolean);
64e5ac ¤   (* doneWithRequest) = FALSE;
b2af5a
0baa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
26a0d7 ¤   pgpAssert(IsDriveBusy(drive));
42af5a
0b41ab ¤   pIop = mIopReqs[drive].pIop;
e9148e ¤   pgpAssertAddrValid(pIop, IOP);
3baf5a
4366a2 ¤   pIor = mIopReqs[drive].pIor;
6eb602 ¤   pgpAssertAddrValid(pIor, IOR);
7caf5a
--4504 00032a43e3740110130 Page 11 of IopProcessor.cpp
bf6bfb ¤   pDcb = (PDCB) pIop->IOP_physical_dcb;
91a603 ¤   pgpAssertAddrValid(pDcb, DCB);
61af5a
6487df ¤   pPGD = Driver->mPGPdisks.FindPGPdisk(drive);
a75b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
98af5a
8d549a ¤   useAsync = mIopReqs[drive].useAsync;
1faf5a
2b05f6 ¤   // Look for the next piece we need to process, if any are left.
056411 ¤   for (i=0; i<kIopProcMaxMinis; i++)
14c7a1 ¤   {
0f4801 ¤   ¤   if (mIopReqs[drive].miniReqs[i].isInUse)
5e5b34 ¤   ¤   {
c19781 ¤   ¤   ¤   PGPUInt8¤   *buf;
373f74 ¤   ¤   ¤   PGPUInt32¤  nBytes;
275034 ¤   ¤   ¤   PGPUInt64¤  pos;
4faf5a
84d2ca ¤   ¤   ¤   foundMiniReq = TRUE;
b1af5a
4d978d ¤   ¤   ¤   buf¤¤   = mIopReqs[drive].miniReqs[i].buf;
6cdf9a ¤   ¤   ¤   pos¤¤   = mIopReqs[drive].miniReqs[i].pos;
dece5d ¤   ¤   ¤   nBytes¤ = mIopReqs[drive].miniReqs[i].nBytes;
f887c7 ¤   ¤   ¤
642b96 ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
e0af5a
f36934 ¤   ¤   ¤   // Call it down. Don't ask for an error value on async calls since
d8d457 ¤   ¤   ¤   // async errors will be returned using the callback, not here.
ccaf5a
c250a9 ¤   ¤   ¤   switch (pIor->IOR_func)
23f776 ¤   ¤   ¤   {
d22f1a ¤   ¤   ¤   case IOR_READ:
c6a450 ¤   ¤   ¤   ¤   if (useAsync)
fff2d5 ¤   ¤   ¤   ¤   ¤   pPGD->Read(buf, pos, nBytes, &mIopReqs[drive].downInfo);
90fa07 ¤   ¤   ¤   ¤   else
5a8855 ¤   ¤   ¤   ¤   ¤   derr = pPGD->Read(buf, pos, nBytes);
9df622 ¤   ¤   ¤   ¤   break;
baaf5a
335b50 ¤   ¤   ¤   case IOR_WRITE:
05a450 ¤   ¤   ¤   ¤   if (useAsync)
055ac9 ¤   ¤   ¤   ¤   ¤   pPGD->Write(buf, pos, nBytes, &mIopReqs[drive].downInfo);
d9fa07 ¤   ¤   ¤   ¤   else
c505f3 ¤   ¤   ¤   ¤   ¤   derr = pPGD->Write(buf, pos, nBytes);
33f622 ¤   ¤   ¤   ¤   break;
eda3a6 ¤   ¤   ¤   }
b8af5a
af8222 ¤   ¤   ¤   // If we're async we only process one piece at a time.
a692cd ¤   ¤   ¤   if (useAsync || derr.IsError())
84f622 ¤   ¤   ¤   ¤   break;
da0fe4 ¤   ¤   }
6d9371 ¤   }
b7af5a
e3d02b ¤   if (useAsync)
443bc3 ¤   ¤   (* doneWithRequest) = !foundMiniReq;
1e0e24 ¤   else
d1f90e ¤   ¤   (* doneWithRequest) = TRUE;
dcaf5a
3d33e3 ¤   return derr;
a8efe6 }
b3af5a
b9dacb // IorReadWriteCallback is called as a callback by the routines who executed
19b2f4 // our read and write requests. We extract the address of the PGPdisk object
151552 // in question and pass the callback to it.
8baf5a
9ec823 void·
00f3ab IopProcessor::IorReadWriteCallback(GenericCallbackInfo *downInfo)
a4bb36 {
5c8ba9 ¤   IopProcessor¤   *pIP;
eace3e ¤   PGPUInt8¤   ¤   drive;
7faf5a
89ac07 ¤   pgpAssertAddrValid(downInfo, GenericCallbackInfo);
1baf5a
32c782 ¤   pIP = (IopProcessor *) downInfo->refData[0];
--9ab6 000f519528f40110130 Page 12 of IopProcessor.cpp
850a83 ¤   pgpAssertAddrValid(pIP, IopProcessor);
90af5a
5fb2d9 ¤   drive = (PGPUInt8) downInfo->refData[1];
faaa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
e8af5a
63308d ¤   pIP->IorReadWriteCallbackAux(drive);
9cefe6 }
2caf5a
724f52 // IorReadWriteCallbackAux is called by the static callback function
761870 // 'IorReadWriteCallback' so we don't have to type 'pIP' before every
5662f9 // reference to an object member or method.
e2af5a
cfc823 void·
81cf42 IopProcessor::IorReadWriteCallbackAux(PGPUInt8 drive)
19bb36 {
3abe41 ¤   DualErr¤¤   derr;
5ec91d ¤   PGPBoolean¤ doneWithRequest;
f00721 ¤   PGPUInt32¤  i;
08af5a
d1aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
f3a0d7 ¤   pgpAssert(IsDriveBusy(drive));
c9af5a
c17ebc ¤   derr = mIopReqs[drive].downInfo.derr;
15af5a
9d2361 ¤   if (derr.IsntError())
a2c7a1 ¤   {
df7c55 ¤   ¤   // Mark the mini-request structure we just completed as unused.
136a5d ¤   ¤   for (i=0; i<kIopProcMaxMinis; i++)
3a5b34 ¤   ¤   {
f61b1a ¤   ¤   ¤   if (mIopReqs[drive].miniReqs[i].isInUse)
84f776 ¤   ¤   ¤   {
195906 ¤   ¤   ¤   ¤   mIopReqs[drive].miniReqs[i].isInUse = FALSE;
11f622 ¤   ¤   ¤   ¤   break;
92a3a6 ¤   ¤   ¤   }
bb0fe4 ¤   ¤   }
b99371 ¤   }
d9af5a
d152a5 ¤   // Perform further processing on this request, if needed.
be2361 ¤   if (derr.IsntError())
d5c7a1 ¤   {
7e1ca3 ¤   ¤   derr = ExecuteRequest(drive, &doneWithRequest);
a69371 ¤   }
c3af5a
7b7f84 ¤   // Callback if we're done or on error.
745c5f ¤   if (doneWithRequest || derr.IsError())
e32ef1 ¤   {¤
319d10 ¤   ¤   PIOP¤   pIop;
83838a ¤   ¤   PIOR¤   pIor;
f0af5a
7e7cc3 ¤   ¤   pIop = mIopReqs[drive].pIop;
e9557d ¤   ¤   pgpAssertAddrValid(pIop, IOP);
9eaf5a
3df8e7 ¤   ¤   pIor = &pIop->IOP_ior;
bef7f1 ¤   ¤   pgpAssertAddrValid(pIor, IOR);
e8af5a
39aa35 ¤   ¤   if (derr.IsntError())
575b34 ¤   ¤   {
a71a94 ¤   ¤   ¤   ScheduleAsyncCallback(pIop, IORS_SUCCESS);
d60fe4 ¤   ¤   }
c10e1d ¤   ¤   else
045b34 ¤   ¤   {
250172 ¤   ¤   ¤   PGPdisk *pPGD;
e3af5a
8abf2c ¤   ¤   ¤   switch (derr.mMinorError)
0ff776 ¤   ¤   ¤   {
a5d314 ¤   ¤   ¤   case kPGDMinorError_IopRequestOverflow:
44f764 ¤   ¤   ¤   case kPGDMinorError_MiniRequestOverflow:
7354e1 ¤   ¤   ¤   ¤   ScheduleAsyncCallback(pIop, IORS_BUSY);
e4f622 ¤   ¤   ¤   ¤   break;
2aaf5a
82db68 ¤   ¤   ¤   default:
f59d42 ¤   ¤   ¤   ¤   pPGD = Driver->mPGPdisks.FindPGPdisk(drive);
--f0bf 0009b98d59b40110130 Page 13 of IopProcessor.cpp
5b1ce1 ¤   ¤   ¤   ¤   pgpAssertAddrValid(pPGD, PGPdisk);
a5af5a
ee0ad5 ¤   ¤   ¤   ¤   // Disable I/O to the PGPdisk.
50c65b ¤   ¤   ¤   ¤   pPGD->EnableIO(FALSE);
d28822 ¤   ¤   ¤   ¤   ScheduleAsyncCallback(pIop, IORS_MEDIA_ERROR);
0daf5a
94eccc ¤   ¤   ¤   ¤   // For I/O errors, user will be asked for options.
17fe41 ¤   ¤   ¤   ¤   if (pIor->IOR_func == IOR_READ)
f372c3 ¤   ¤   ¤   ¤   {
5488d7 ¤   ¤   ¤   ¤   ¤   Driver->ReportError(kPGDMajorError_PGPdiskReadError,·
868e09 ¤   ¤   ¤   ¤   ¤   ¤   DualErr::NoError, pPGD->GetDrive());
112613 ¤   ¤   ¤   ¤   }
fffa07 ¤   ¤   ¤   ¤   else
c672c3 ¤   ¤   ¤   ¤   {
808f38 ¤   ¤   ¤   ¤   ¤   Driver->ReportError(kPGDMajorError_PGPdiskWriteError,·
d98e09 ¤   ¤   ¤   ¤   ¤   ¤   DualErr::NoError, pPGD->GetDrive());
552613 ¤   ¤   ¤   ¤   }
6df622 ¤   ¤   ¤   ¤   break;
fba3a6 ¤   ¤   ¤   }
f00fe4 ¤   ¤   }
b29371 ¤   }
adefe6 }
5eaf5a
73f5b3 // ScheduleAsyncCallback schedules a windows event that calls our function
e1e5b4 // that will call the asynchronous request up.
68af5a
2dc823 void·
e6c146 IopProcessor::ScheduleAsyncCallback(PIOP pIop, PGPUInt16 status)
4cbb36 {
040ce1 ¤   PIOR¤   ¤   ¤   ¤   ¤   ¤   ¤   pIor;
b7eef9 ¤   static RestrictedEvent_THUNK¤   callbackThunk;
57af5a
78148e ¤   pgpAssertAddrValid(pIop, IOP);
e0af5a
80eccf ¤   pIor = &pIop->IOP_ior;
97b602 ¤   pgpAssertAddrValid(pIor, IOR);
17af5a
049449 ¤   pIor->IOR_status = status;
c2af5a
3aa44c ¤   Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED, (PVOID) pIop,·
306ef4 ¤   ¤   AsyncExecuteCallback, 0, &callbackThunk);
77efe6 }
ffaf5a
451652 // AsyncExecuteCallback was scheduled by 'ScheduleAsyncCallback' for the
82950e // purpose of calling back up the asynchronous request we received.
7aaf5a
eaa1ba VOID·
cbb45d __stdcall·
d0fa7d IopProcessor::AsyncExecuteCallback(
34bfb0 ¤   VMHANDLE¤   ¤   hVM,·
37518d ¤   THREADHANDLE¤   hThread,·
dcd6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
aa58d6 ¤   PCLIENT_STRUCT¤ pRegs)
99bb36 {
388ba9 ¤   IopProcessor¤   *pIP;
acce3e ¤   PGPUInt8¤   ¤   drive;
50aad8 ¤   PIOP¤   ¤   ¤   pIop;
af31e3 ¤   PIOR¤   ¤   ¤   pIor;
e3af5a
2379bd ¤   pIop = (PIOP) Refdata;
b3148e ¤   pgpAssertAddrValid(pIop, IOP);
48af5a
b5eccf ¤   pIor = &pIop->IOP_ior;
38b602 ¤   pgpAssertAddrValid(pIor, IOR);
8faf5a
9abe81 ¤   pIP = (IopProcessor *) pIor->IOR_private_port;
4e0a83 ¤   pgpAssertAddrValid(pIP, IopProcessor);
7eaf5a
151924 ¤   // If the IOR was a read or write request, we must check if there is more
e400a9 ¤   // I/O from that PGPdisk to process. We do this by scheduling the IOP
fce165 ¤   // dispatch function as a callback.
9baf5a
--0260 001087f91bf40110130 Page 14 of IopProcessor.cpp
9ed9db ¤   PDCB pDcb;
4aaf5a
44760b ¤   switch (pIor->IOR_func)
21c7a1 ¤   {
33f612 ¤   case IOR_READ:
d8d7c1 ¤   case IOR_WRITE:
c0523e ¤   ¤   pDcb = (PDCB) pIop->IOP_physical_dcb;
c8e7f0 ¤   ¤   pgpAssertAddrValid(pDcb, DCB);
abaf5a
6d4ce2 ¤   ¤   drive = pDcb->DCB_cmn.DCB_drive_lttr_equiv;
3193d3 ¤   ¤   pgpAssert(IsLegalDriveNumber(drive));
c9af5a
a1b7a4 ¤   ¤   --pIop->IOP_callback_ptr;¤
28754d ¤   ¤   pIop->IOP_callback_ptr->IOP_CB_address(pIop);
88af5a
01f487 ¤   ¤   pIP->ScheduleIorReadWriteDispatch(drive);
182f68 ¤   ¤   break;
89af5a
182f72 ¤   default:
c4b7a4 ¤   ¤   --pIop->IOP_callback_ptr;¤
b4754d ¤   ¤   pIop->IOP_callback_ptr->IOP_CB_address(pIop);
962f68 ¤   ¤   break;
1b9371 ¤   }
08efe6 }
--6d28 000ad713f8140110131 Page 1 of IopProcessor.h
541bc3 //////////////////////////////////////////////////////////////////////////////
aa960c // IopProcessor.h
59465d //
d5badf // Declaration of class IopProcessor.
0c1bc3 //////////////////////////////////////////////////////////////////////////////
9caf5a
a793e1 // $Id: IopProcessor.h,v 1.1.2.6 1998/07/06 08:58:23 nryan Exp $
68af5a
3bcbce // Copyright (C) 1998 by Network Associates, Inc.
5171ae // All rights reserved.
8aaf5a
bbbd5d #ifndef Included_IopProcessor_h¤// [
ce8471 #define Included_IopProcessor_h
4baf5a
363a85 #include "DualErr.h"
f7555c #include "GenericCallback.h"
6f3552 #include "Wrappers.h"
a4af5a
6daf5a
5909b7 ////////////
7ae738 // Constants
3309b7 ////////////
2baf5a
f875af const PGPUInt32 kIopProcMaxMinis = 20;¤ // max minirequests in an IOP
1baf5a
77af5a
7fd557 ////////
1c02c9 // Types
bad557 ////////
e3af5a
cebc7f // MiniRequestWrapper is used in conjunction with IopRequestInfo to keep
efb9e2 // track of which pieces of which request have been processed so far.
03af5a
404140 typedef struct MiniRequestWrapper
7cbb36 {
621f34 ¤   PGPBoolean¤ isInUse;¤   // TRUE if this object is in use
57af5a
b1b9a6 ¤   PGPUInt8¤   *buf;¤  ¤   // the I/O buffer
d190a1 ¤   PGPUInt64¤  pos;¤   ¤   // transfer position
ec203a ¤   PGPUInt32¤  nBytes;¤¤   // size of transfer
f9af5a
f28e7b } MiniRequestWrapper;
76af5a
6e065f // IopRequestInfo holds information about a certain I/O request in progress.
2eaf5a
4ce3ba typedef struct IopRequestInfo
34bb36 {
705315 ¤   PGPBoolean¤ isBusy;¤¤   // TRUE if this object is in use
5aac61 ¤   PGPBoolean¤ useAsync;¤  // process asynchronously?
c9af5a
315fe1 ¤   PIOP¤   pIop;¤  // the IOP itself
dcaac8 ¤   PIOR¤   pIor;¤  // points to IOR in the IOP
02af5a
a4ad66 ¤   GenericCallbackInfo¤downInfo;¤  // information for and from class PGPdisk
b8ecdb ¤   MiniRequestWrapper¤ miniReqs[kIopProcMaxMinis];¤// pieces of the request
00af5a
e7ddcd } IopRequestInfo;
6eaf5a
c4af5a
f36cc2 /////////////////////
f76a28 // Class IopProcessor
346cc2 /////////////////////
5aaf5a
6081aa // An object of class IopProcessor takes an IOP and processes it
da0f12 // asynchronously. It makes sure each SGD in a read/write request has been
00d613 // processed before calling back the entire IOP. This class is Ring-0 thread-
dd9eac // safe.
4faf5a
8ced3a class IopProcessor
3ebb36 {
755ed4 public:
ad3891 ¤   ¤   ¤   ¤   IopProcessor();
--e49c 001364c131a40110131 Page 2 of IopProcessor.h
352b81 ¤   ¤   ¤   ¤   ~IopProcessor();
46af5a
4f52e6 ¤   PGPBoolean¤ IsDriveBusy(PGPUInt8 drive);
e97d25 ¤   void¤   ¤   SetDriveBusy(PGPUInt8 drive, PGPBoolean isBusy);
0aaf5a
1c8530 ¤   PGPBoolean¤ IsIOAsync();
357ab6 ¤   void¤   ¤   SetIOAsync(PGPBoolean isIOAsync);
22af5a
da6116 ¤   void¤   ¤   ProcessIop(PIOP pIop);
05af5a
770fb9 private:
471a70 ¤   IopRequestInfo¤ mIopReqs[kMaxDrives];¤  // requests by drive #
b3e865 ¤   PGPBoolean¤ ¤   mUseAsyncIO;¤   ¤   ¤   // use async I/O?
e5af5a
6d6996 ¤   static void¤¤   ¤   ¤   ScheduleIorReadWriteDispatch(PGPUInt8 drive);
59af5a
50802e ¤   static void¤¤   ¤   ¤   IorGenIoctlDispatcher(PIOP pIop);
e39bd9 ¤   static VOID __stdcall¤  IorReadWriteDispatcher(VMHANDLE hVM,·
a1f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
ab6ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
afaf5a
8c0368 ¤   void¤   ¤   ¤   ¤   ¤   ProcessIorGenIoctl(PIOP pIop);
76b887 ¤   void¤   ¤   ¤   ¤   ¤   ProcessIorReadWrite(PIOP pIop,·
d01b63 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean useAsync = TRUE);
aeaf5a
bb0603 ¤   DualErr¤¤   ¤   ¤   ¤   ExecuteRequest(PGPUInt8 drive,·
732df8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean *doneWithRequest);
c9af5a
360258 ¤   static void¤¤   ¤   ¤   IorReadWriteCallback(
9e28f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *downInfo);
20ec9f ¤   void¤   ¤   ¤   ¤   ¤   IorReadWriteCallbackAux(PGPUInt8 drive);
8daf5a
45f8a1 ¤   void¤   ¤   ¤   ¤   ¤   ScheduleAsyncCallback(PIOP pIop,·
6349ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt16 status);
ccb204 ¤   static VOID __stdcall¤  AsyncExecuteCallback(VMHANDLE hVM,·
35f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
ef6ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
8f82f7 };
8caf5a
36c7bf #endif¤ // ] Included_IopProcessor_h
--0d86 000bf25eb7240110132 Page 1 of PGPdisk.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
21efa8 // PGPdisk.cpp
ae465d //
b53ee7 // Implementation of class PGPdisk.
ec1bc3 //////////////////////////////////////////////////////////////////////////////
efaf5a
d24a8d // $Id: PGPdisk.cpp,v 1.1.2.28 1998/07/22 23:39:15 nryan Exp $
efaf5a
eecbce // Copyright (C) 1998 by Network Associates, Inc.
0471ae // All rights reserved.
1daf5a
2b06a9 #include <vtoolscp.h>
eeaf5a
249bcf #include "Required.h"
777414 #include "PGPdiskHighLevelUtils.h"
942229 #include "PGPdiskLowLevelUtils.h"
3ebfe9 #include "UtilityFunctions.h"
5baf5a
cdc411 #include "Globals.h"
ae68c6 #include "PGPdisk.h"
273a08 #include "PlacementNew.h"
7daf5a
1886d2 #include LOCKED_CODE_SEGMENT
275269 #include LOCKED_DATA_SEGMENT
20af5a
95af5a
d451ef ////////////////////////////////////////
3ee872 // Class PGPdisk public member functions
af51ef ////////////////////////////////////////
63af5a
233d96 // The PGPdisk default constructor.
28af5a
b90bac PGPdisk::PGPdisk() : VolFile(), mSmContextA(sizeof(CipherContext)),·
3e5986 ¤   mSmContextB(sizeof(CipherContext))
96bb36 {
936991 ¤   mContextA¤  = NULL;
6dee7f ¤   mContextB¤  = NULL;
f4af5a
0ff220 ¤   mDataBuf = NULL;
aaaf5a
720d13 ¤   mPGPdiskReq.isInUse = FALSE;
4eaf5a
6afbfa ¤   mInitErr = VolFile::mInitErr;
e5af5a
749c32 ¤   if (mInitErr.IsntError())
eec7a1 ¤   {
9c9a60 ¤   ¤   mInitErr = mSmContextA.mInitErr;
969371 ¤   }
e6af5a
1d9c32 ¤   if (mInitErr.IsntError())
62c7a1 ¤   {
e81d8e ¤   ¤   mInitErr = mSmContextB.mInitErr;
379371 ¤   }
9caf5a
2acf21 ¤   // Get our data buffer.
8a9c32 ¤   if (mInitErr.IsntError())
7dc7a1 ¤   {
78a30e ¤   ¤   mInitErr = GetByteBuffer(kPGDBlocksPerOp*kDefaultBlockSize,·
7bd237 ¤   ¤   ¤   &mDataBuf);
299371 ¤   }
80af5a
ce9c32 ¤   if (mInitErr.IsntError())
6cc7a1 ¤   {
c75ea9 ¤   ¤   // Use placement new.
278b78 ¤   ¤   mContextA¤  = new (mSmContextA.GetPtr()) CipherContext;¤
c46557 ¤   ¤   mContextB¤  = new (mSmContextB.GetPtr()) CipherContext;
129371 ¤   }
c8efe6 }
08af5a
fc0125 // The PGPdisk destructor cleans up.
90af5a
bf7cff PGPdisk::~PGPdisk()
--c038 00011230dd240110132 Page 2 of PGPdisk.cpp
2cbb36 {
65cb02 ¤   if (Mounted())
34e404 ¤   ¤   Unmount(TRUE);
deaf5a
765a88 ¤   if (IsntNull(mContextB))
1ac7a1 ¤   {
a6b5d1 ¤   ¤   mContextB->~CipherContext();
952d79 ¤   ¤   mContextB = NULL;
f09371 ¤   }
2daf5a
be7f45 ¤   if (IsntNull(mContextA))
97c7a1 ¤   {
1fec65 ¤   ¤   mContextA->~CipherContext();
9a5910 ¤   ¤   mContextA = NULL;
fe9371 ¤   }
37af5a
784a53 ¤   if (IsntNull(mDataBuf))
b3c7a1 ¤   {
e6b223 ¤   ¤   FreeByteBuffer(mDataBuf);
7043f1 ¤   ¤   mDataBuf = NULL;
439371 ¤   }
14efe6 }
30af5a
c2f7af // BestGuessComparePaths uses a number of methods to determine if the
83a819 // specified file is the same as the current mounted PGPdisk.
fbaf5a
dc77be PGPBoolean·
8f50b9 PGPdisk::BestGuessComparePaths(LPCSTR path)
00bb36 {
bd7777 ¤   File¤   ¤   testFile;
69be41 ¤   DualErr¤¤   derr;
4aa399 ¤   PGPBoolean¤ failedTest¤ = FALSE;
cfab82 ¤   PGPUInt32¤  i, numPGPdiskPathElems, numTestFilePathElems;
e4ed18 ¤   PGPUInt64¤  PGPdiskLength, testFileLength;
67af5a
243ec3 ¤   pgpAssert(Mounted());
0eaf5a
f6f905 ¤   // First try the easy case.
c0a27e ¤   if (ComparePaths(path))
f6836c ¤   ¤   return TRUE;
fcaf5a
9bd1e6 ¤   // See if the number of path elements in each path is the same.
ffcce3 ¤   numPGPdiskPathElems = 0;
72af5a
3f31f5 ¤   for (i=0; i<strlen(GetPath()); i++)
a0c7a1 ¤   {
289ef3 ¤   ¤   if ((GetPath()[i] == '\\') || (GetPath()[i] == '/'))
035fcf ¤   ¤   ¤   numPGPdiskPathElems++;
909371 ¤   }
5daf5a
11a4d8 ¤   numTestFilePathElems = 0;
b7af5a
f71a71 ¤   for (i=0; i<strlen(path); i++)
2cc7a1 ¤   {
81c573 ¤   ¤   if ((path[i] == '\\') || (path[i] == '/'))
310c3c ¤   ¤   ¤   numTestFilePathElems++;
d29371 ¤   }
d8af5a
af2e75 ¤   if (numPGPdiskPathElems != numTestFilePathElems)
fab4e5 ¤   ¤   failedTest = TRUE;
09af5a
376e71 ¤   // Make sure the files are the same size.
81c2ad ¤   if (!failedTest)
81c7a1 ¤   {
6aa9a6 ¤   ¤   derr = GetLength(&PGPdiskLength);
7f9371 ¤   }
deaf5a
538cd9 ¤   if (derr.IsntError() && !failedTest)
d0c7a1 ¤   {
a7c9cb ¤   ¤   derr = testFile.Open(path, kOF_MustExist | kOF_ReadOnly);
229371 ¤   }
11af5a
--c3c7 000d6f8ba7e40110132 Page 3 of PGPdisk.cpp
e78cd9 ¤   if (derr.IsntError() && !failedTest)
25c7a1 ¤   {
3aa7ac ¤   ¤   derr = testFile.GetLength(&testFileLength);
489371 ¤   }
07af5a
e0695e ¤   if (!failedTest && testFile.Opened())
efc7a1 ¤   {
e3e58c ¤   ¤   testFile.Close();
9e9371 ¤   }
c6af5a
4d8cd9 ¤   if (derr.IsntError() && !failedTest)
e1c7a1 ¤   {
b29003 ¤   ¤   if (PGPdiskLength != testFileLength)
b7a0cd ¤   ¤   ¤   failedTest = TRUE;
449371 ¤   }
8daf5a
8a5121 ¤   // Check if the test file is in use (which must be the case with any
9a0d41 ¤   // mounted PGPdisk.
67af5a
408cd9 ¤   if (derr.IsntError() && !failedTest)
c0c7a1 ¤   {
f268a7 ¤   ¤   if (!Driver->IsFileInUse(path))
74a0cd ¤   ¤   ¤   failedTest = TRUE;
829371 ¤   }
aeaf5a
d6444c ¤   // Finally return false if there was an error.
8e4bb3 ¤   if (derr.IsError())
15c7a1 ¤   {
6db4e5 ¤   ¤   failedTest = TRUE;
a69371 ¤   }
3aaf5a
ea1907 ¤   return !failedTest;
bfefe6 }
3aaf5a
98b967 // GetUniqueSessionId returns the unique session ID for the PGPdisk.
bdaf5a
4ea385 PGPUInt64·
2665e0 PGPdisk::GetUniqueSessionId()
97bb36 {
963ec3 ¤   pgpAssert(Mounted());
c5af5a
9e322f ¤   return mUniqueSessionId;
45efe6 }
73af5a
320e7f // FlipContexts flips the key bits on each context.
0eaf5a
6dc823 void·
0c15b8 PGPdisk::FlipContexts()
9abb36 {
f9d909 ¤   pgpAssertAddrValid(mContextA, CipherContext);
9164c3 ¤   pgpAssertAddrValid(mContextB, CipherContext);
693ec3 ¤   pgpAssert(Mounted());
59af5a
81d9dc ¤   mContextA->FlipContext();
fcd8e4 ¤   mContextB->FlipContext();
15efe6 }
75af5a
9080a9 // ValidateContexts makes sure the cipher procs aren't damaged.
2eaf5a
e72292 DualErr·
3599ca PGPdisk::ValidateContexts()
66bb36 {
857d36 ¤   DualErr derr;
e1af5a
36d909 ¤   pgpAssertAddrValid(mContextA, CipherContext);
ef64c3 ¤   pgpAssertAddrValid(mContextB, CipherContext);
403ec3 ¤   pgpAssert(Mounted());
9aaf5a
e6231e ¤   derr = mContextA->ValidateContext();
d5af5a
552361 ¤   if (derr.IsntError())
d6c7a1 ¤   {
--891b 0006c4f83bb40110132 Page 4 of PGPdisk.cpp
8cd650 ¤   ¤   derr = mContextB->ValidateContext();
429371 ¤   }
e4af5a
2333e3 ¤   return derr;
88efe6 }
05af5a
4179b2 // Mount reads in the PGPdisk-specific header and asks VolFile to continue
987baa // with the mount, passing along header and disk size information.
8baf5a
192292 DualErr·
706b3a PGPdisk::Mount(
df20cd ¤   LPCSTR¤ ¤   ¤   path,·
5bfa54 ¤   CipherContext¤  *context,·
c5f5fc ¤   PDCB¤   ¤   ¤   pDcb,·
44f4ef ¤   PGPUInt8¤   ¤   drive,·
a26fde ¤   PGPBoolean¤ ¤   mountReadOnly)
53bb36 {
ce705b ¤   DualErr¤¤   ¤   ¤   derr;
39e1a0 ¤   File¤   ¤   ¤   ¤   diskFile;
d4d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
ef8fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
67af5a
70639f ¤   pgpAssertStrValid(path);
39d189 ¤   pgpAssertAddrValid(context, CipherContext);
2aaf5a
03c332 ¤   // Mark the PGPdisk as mounted.
261f7b ¤   if (!mountReadOnly)
6d7c22 ¤   ¤   SetPGPdiskMountedFlag(path, TRUE);
1eaf5a
d15b69 ¤   // Read the session ID.
e188f6 ¤   mUniqueSessionId = GetPGPdiskUniqueSessionId(path);
19af5a
0ee2ee ¤   // Read in the header.
75b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
e8a08e ¤   readHeader = derr.IsntError();
0eaf5a
716247 ¤   // Initialize the contexts and flip context B.
2c2361 ¤   if (derr.IsntError())
1cc7a1 ¤   {
e37708 ¤   ¤   pgpAssertAddrValid(mContextA, CipherContext);
97cac2 ¤   ¤   pgpAssertAddrValid(mContextB, CipherContext);
ffaf5a
e57b01 ¤   ¤   (* mContextA) = (* mContextB) = (* context);
32af5a
9cefec ¤   ¤   mContextB->FlipContext();
6b9371 ¤   }
efaf5a
53e494 ¤   // Finish the mount by calling down.
d82361 ¤   if (derr.IsntError())
36c7a1 ¤   {
14e6aa ¤   ¤   derr = VolFile::Mount(path, fileHeader->numHeaderBlocks,·
2ca397 ¤   ¤   ¤   fileHeader->numDataBlocks, pDcb, drive, mountReadOnly);
cb9371 ¤   }
44af5a
254bb3 ¤   if (derr.IsError())
0cc7a1 ¤   {
f6e91e ¤   ¤   if (!mountReadOnly)
2c814a ¤   ¤   ¤   SetPGPdiskMountedFlag(path, FALSE);
a19371 ¤   }
97af5a
78fd0b ¤   if (readHeader)
db3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
0daf5a
e233e3 ¤   return derr;
46efe6 }
2aaf5a
e17f5f // Unmount unmounts a mounted PGPdisk.
a2af5a
e22292 DualErr·
442545 PGPdisk::Unmount(PGPBoolean isThisEmergency)
8cbb36 {
6cbe41 ¤   DualErr¤¤   derr;
--d126 000dbc1ee0040110132 Page 5 of PGPdisk.cpp
2613e7 ¤   LPSTR¤  ¤   pathCopy;
15ef0c ¤   PGPBoolean¤ dupedPath, wasReadOnly;
e1af5a
8a3ec3 ¤   pgpAssert(Mounted());
04af5a
15b0ed ¤   dupedPath = FALSE;
075c43 ¤   wasReadOnly = IsReadOnly();
50af5a
2f4cef ¤   // Copy path.
425b57 ¤   derr = DupeString(GetPath(), &pathCopy);
038a1a ¤   dupedPath = derr.IsntError();
5aaf5a
328af0 ¤   // Unmount the PGPdisk volume.
192361 ¤   if (derr.IsntError())
7fc7a1 ¤   {
18f3fc ¤   ¤   derr = VolFile::Unmount(isThisEmergency);
0f9371 ¤   }
76af5a
e42361 ¤   if (derr.IsntError())
a3c7a1 ¤   {
2150ae ¤   ¤   // Mark as not mounted.
f959de ¤   ¤   if (!wasReadOnly)
e7775a ¤   ¤   ¤   SetPGPdiskMountedFlag(pathCopy, FALSE);
74af5a
59e959 ¤   ¤   // Unflip the contexts and destroy them.
e3ddef ¤   ¤   (mContextA->IsFlipped() ? mContextA->FlipContext() :·
7f5c73 ¤   ¤   ¤   mContextB->FlipContext());
9caf5a
122a01 ¤   ¤   mContextA->DestroyContext();
3e73b5 ¤   ¤   mContextB->DestroyContext();
629371 ¤   }
c4af5a
19a8b0 ¤   if (dupedPath)
84c781 ¤   ¤   delete[] pathCopy;
d1af5a
b833e3 ¤   return derr;
03efe6 }
8aaf5a
da6033 // ReadAsync performs a read request on the mounted PGPdisk asynchronously.
31af5a
a2c823 void·
c1dacf PGPdisk::ReadAsync(
e8e311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
a73385 ¤   PGPUInt64¤  ¤   ¤   pos,·
f192c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
caf7c6 ¤   GenericCallbackInfo¤*upInfo)
7ebb36 {
238bc2 ¤   PGPBoolean doneWithRequest;
6aaf5a
e8e9ac ¤   pgpAssertAddrValid(upInfo, GenericCallbackInfo);
4aa424 ¤   pgpAssertAddrValid(upInfo->callback, PGPUInt8);
0db442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
b6af5a
a53ec3 ¤   pgpAssert(Mounted());
afaf5a
ce57c2 ¤   pgpAssert(!mPGPdiskReq.isInUse);
fdbbed ¤   mPGPdiskReq.isInUse = TRUE;
42af5a
e8e3e6 ¤   // Prepare the request for execution.
d63166 ¤   mPGPdiskReq.op = kPGDOP_Read;
a595df ¤   mPGPdiskReq.upInfo = upInfo;
41af5a
80b16b ¤   mPGPdiskReq.downInfo.callback = PGPdiskCallback;
d9b75a ¤   mPGPdiskReq.downInfo.refData[0] = (PGPUInt32) this;
99af5a
1a2fcc ¤   // We start out by initializing the request so that all possible
7df9b6 ¤   // pieces of the request are marked as completed.
2baf5a
406033 ¤   mPGPdiskReq.read.readHeader¤= TRUE;
78f0ff ¤   mPGPdiskReq.read.readMiddle¤= TRUE;
7a45fb ¤   mPGPdiskReq.read.readTail¤  = TRUE;
dbaf5a
--bb1f 000b251435840110132 Page 6 of PGPdisk.cpp
8bbd4a ¤   // Now we analyze the request and determine what pieces must be
e9d0c0 ¤   // read so that the entire request can be marked as done.
3eaf5a
b52b08 ¤   if (pos%kDefaultBlockSize > 0)
f6c7a1 ¤   {
74bf64 ¤   ¤   PGPUInt32 bytesInHeader;
a0af5a
7284c3 ¤   ¤   // The request has a header - that is, it doesn't begin on a
ba151f ¤   ¤   // block boundary.
18af5a
4c4e91 ¤   ¤   bytesInHeader = min(nBytes, kDefaultBlockSize -·
f6f82a ¤   ¤   ¤   (PGPUInt32) (pos%kDefaultBlockSize));
76af5a
c47fcb ¤   ¤   mPGPdiskReq.read.readHeader¤¤   = FALSE;
052e28 ¤   ¤   mPGPdiskReq.read.bufHeader¤ ¤   = buf;
d424cc ¤   ¤   mPGPdiskReq.read.posHeader¤ ¤   = pos;
bbc106 ¤   ¤   mPGPdiskReq.read.nBytesHeader¤  = bytesInHeader;
d9af5a
5de7ab ¤   ¤   buf¤¤   += bytesInHeader;
4d0e18 ¤   ¤   pos¤¤   += bytesInHeader;
6e6ea5 ¤   ¤   nBytes¤ -= bytesInHeader;
749371 ¤   }
2eaf5a
03ac47 ¤   if (nBytes >= kDefaultBlockSize)
9ac7a1 ¤   {
2a7deb ¤   ¤   PGPUInt32 bytesInMiddle;
47af5a
d7a3ed ¤   ¤   // The request has a middle - that is, a section that begins and
236bb8 ¤   ¤   // ends on a block boundary and is more than one block in length.
41af5a
f80cf8 ¤   ¤   bytesInMiddle = nBytes - nBytes%kDefaultBlockSize;
67af5a
13ad43 ¤   ¤   mPGPdiskReq.read.readMiddle¤¤   = FALSE;
130bbc ¤   ¤   mPGPdiskReq.read.bufMiddle¤ ¤   = buf;
bf0158 ¤   ¤   mPGPdiskReq.read.posMiddle¤ ¤   = pos;
b1cecc ¤   ¤   mPGPdiskReq.read.nBytesMiddle¤  = bytesInMiddle;
b2af5a
412524 ¤   ¤   buf¤¤   += bytesInMiddle;
82cc97 ¤   ¤   pos¤¤   += bytesInMiddle;
7eac2a ¤   ¤   nBytes¤ -= bytesInMiddle;
199371 ¤   }
25af5a
00f4fd ¤   if (nBytes > 0)
1ec7a1 ¤   {
5b4d3d ¤   ¤   // The request has a tail - that is, it doesn't end on a
87151f ¤   ¤   // block boundary.
1daf5a
407ee2 ¤   ¤   mPGPdiskReq.read.readTail¤  = FALSE;
d3dce0 ¤   ¤   mPGPdiskReq.read.bufTail¤   = buf;
ab7d22 ¤   ¤   mPGPdiskReq.read.posTail¤   = pos;
5d3b81 ¤   ¤   mPGPdiskReq.read.nBytesTail¤= nBytes;
bf9371 ¤   }
e3af5a
4ae41b ¤   // Execute the request.
fbac89 ¤   ExecuteRequest(&doneWithRequest);
a5af5a
de89cd ¤   // Should always have stuff to do at this point. But if we don't, then
defb1e ¤   // don't hang the computer by not calling back.
9daf5a
dcb941 ¤   if (doneWithRequest)
f3c7a1 ¤   {
b88f52 ¤   ¤   pgpAssert(FALSE);
df761d ¤   ¤   ScheduleAsyncCallback();
d69371 ¤   }
72efe6 }
9caf5a
e9b8d8 // WriteAsync performs a write request on the mounted PGPdisk asynchronously.
d3af5a
17c823 void·
d80ed7 PGPdisk::WriteAsync(
4be311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
b23385 ¤   PGPUInt64¤  ¤   ¤   pos,·
--a5a0 000ae92718640110132 Page 7 of PGPdisk.cpp
c892c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
08f7c6 ¤   GenericCallbackInfo¤*upInfo)
36bb36 {
8d8bc2 ¤   PGPBoolean doneWithRequest;
8aaf5a
1fe9ac ¤   pgpAssertAddrValid(upInfo, GenericCallbackInfo);
4ea424 ¤   pgpAssertAddrValid(upInfo->callback, PGPUInt8);
10b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
1faf5a
db3ec3 ¤   pgpAssert(Mounted());
16af5a
7657c2 ¤   pgpAssert(!mPGPdiskReq.isInUse);
1abbed ¤   mPGPdiskReq.isInUse = TRUE;
e6af5a
c5e3e6 ¤   // Prepare the request for execution.
2fa29a ¤   mPGPdiskReq.op = kPGDOP_Write;
2495df ¤   mPGPdiskReq.upInfo = upInfo;
7caf5a
9eb16b ¤   mPGPdiskReq.downInfo.callback = PGPdiskCallback;
b1b75a ¤   mPGPdiskReq.downInfo.refData[0] = (PGPUInt32) this;
9faf5a
b62fcc ¤   // We start out by initializing the request so that all possible
a4f9b6 ¤   // pieces of the request are marked as completed.
51af5a
331ea4 ¤   mPGPdiskReq.write.readHeader¤   = TRUE;
b206a3 ¤   mPGPdiskReq.write.wroteHeader¤  = TRUE;
d4f120 ¤   mPGPdiskReq.write.wroteMiddle¤  = TRUE;
8b24c1 ¤   mPGPdiskReq.write.readTail¤ ¤   = TRUE;
d7dfd0 ¤   mPGPdiskReq.write.wroteTail¤¤   = TRUE;
d0af5a
fcbd4a ¤   // Now we analyze the request and determine what pieces must be
860191 ¤   // written so that the entire request can be marked as done.
93af5a
002b08 ¤   if (pos%kDefaultBlockSize > 0)
24c7a1 ¤   {
adbf64 ¤   ¤   PGPUInt32 bytesInHeader;
24af5a
8384c3 ¤   ¤   // The request has a header - that is, it doesn't begin on a
77151f ¤   ¤   // block boundary.
f8af5a
c74e91 ¤   ¤   bytesInHeader = min(nBytes, kDefaultBlockSize -·
b5f82a ¤   ¤   ¤   (PGPUInt32) (pos%kDefaultBlockSize));
8eaf5a
9680ee ¤   ¤   mPGPdiskReq.write.readHeader¤   = FALSE;
57f449 ¤   ¤   mPGPdiskReq.write.wroteHeader¤  = FALSE;
7b7c9a ¤   ¤   mPGPdiskReq.write.bufHeader¤¤   = buf;
0c2ece ¤   ¤   mPGPdiskReq.write.posHeader¤¤   = pos;
69b141 ¤   ¤   mPGPdiskReq.write.nBytesHeader¤ = bytesInHeader;
c1af5a
b0e7ab ¤   ¤   buf¤¤   += bytesInHeader;
d10e18 ¤   ¤   pos¤¤   += bytesInHeader;
896ea5 ¤   ¤   nBytes¤ -= bytesInHeader;
af9371 ¤   }
96af5a
bdac47 ¤   if (nBytes >= kDefaultBlockSize)
22c7a1 ¤   {
657deb ¤   ¤   PGPUInt32 bytesInMiddle;
72af5a
42a3ed ¤   ¤   // The request has a middle - that is, a section that begins and
ce6bb8 ¤   ¤   // ends on a block boundary and is more than one block in length.
63af5a
9b0cf8 ¤   ¤   bytesInMiddle = nBytes - nBytes%kDefaultBlockSize;
adaf5a
ca422d ¤   ¤   mPGPdiskReq.write.wroteMiddle¤  = FALSE;
2fcafe ¤   ¤   mPGPdiskReq.write.bufMiddle¤¤   = buf;
c698aa ¤   ¤   mPGPdiskReq.write.posMiddle¤¤   = pos;
a262b5 ¤   ¤   mPGPdiskReq.write.nBytesMiddle¤ = bytesInMiddle;
1baf5a
3f2524 ¤   ¤   buf¤¤   += bytesInMiddle;
b1cc97 ¤   ¤   pos¤¤   += bytesInMiddle;
b2ac2a ¤   ¤   nBytes¤ -= bytesInMiddle;
ae9371 ¤   }
--22ab 000bd5b1dd340110132 Page 8 of PGPdisk.cpp
e0af5a
9ff4fd ¤   if (nBytes > 0)
a8c7a1 ¤   {
f44d3d ¤   ¤   // The request has a tail - that is, it doesn't end on a
91151f ¤   ¤   // block boundary.
42af5a
b4b47f ¤   ¤   mPGPdiskReq.write.readTail¤ ¤   = FALSE;
4db58c ¤   ¤   mPGPdiskReq.write.wroteTail¤¤   = FALSE;
c4ed49 ¤   ¤   mPGPdiskReq.write.bufTail¤  ¤   = buf;
2ebf1d ¤   ¤   mPGPdiskReq.write.posTail¤  ¤   = pos;
0b216a ¤   ¤   mPGPdiskReq.write.nBytesTail¤   = nBytes;
f49371 ¤   }
40af5a
f1e41b ¤   // Execute the request.
d0ac89 ¤   ExecuteRequest(&doneWithRequest);
f0af5a
3689cd ¤   // Should always have stuff to do at this point. But if we don't, then
88fb1e ¤   // don't hang the computer by not calling back.
c6af5a
adb941 ¤   if (doneWithRequest)
a8c7a1 ¤   {
278f52 ¤   ¤   pgpAssert(FALSE);
d5761d ¤   ¤   ScheduleAsyncCallback();
df9371 ¤   }
0aefe6 }
11af5a
4608bc // ReadSync performs a read request on the mounted PGPdisk synchronously.
43af5a
e82292 DualErr·
aa8a99 PGPdisk::ReadSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
67bb36 {
dcbe41 ¤   DualErr¤¤   derr;
e8698c ¤   PGPUInt32¤  blocksChunk, blocksToRead, bufPos;
286431 ¤   PGPUInt64¤  blockPGPdisk;
eeaf5a
dfb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
c73ec3 ¤   pgpAssert(Mounted());
e8af5a
bf02d5 ¤   // The position (pos) and size (nBytes) variables are in bytes, but we
f40520 ¤   // can only perform encryption in blocks. What we have to do is handle
d9db45 ¤   // the request in at most three separate pieces - a head, middle, and
950141 ¤   // end.
11af5a
1f3fc7 ¤   bufPos = 0;
5daf5a
9c9f70 ¤   if (pos%kDefaultBlockSize > 0)¤ // is there a head?
39c7a1 ¤   {
cfcf6a ¤   ¤   PGPUInt32 headOffset, headSize;
22af5a
633423 ¤   ¤   // Now read in the head.
9c65af ¤   ¤   //
22f029 ¤   ¤   // blockPGPdisk = block on PGPdisk containing the head.
d33c6d ¤   ¤   // headOffset = byte offset into blockPGPdisk where head starts
81a924 ¤   ¤   // headSize = size of the head, in bytes
05af5a
b7b99d ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
2da0b8 ¤   ¤   headOffset¤ ¤   = (PGPUInt32) (pos%kDefaultBlockSize);
238ad4 ¤   ¤   headSize¤   ¤   = min(nBytes, kDefaultBlockSize - headOffset);
23af5a
3c7acd ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
d4ecb7 ¤   ¤   ¤   kDefaultBlockSize);
77af5a
f0aa35 ¤   ¤   if (derr.IsntError())
8d5b34 ¤   ¤   {
a27970 ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
6a280f ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
d2af5a
900760 ¤   ¤   ¤   pgpCopyMemory(mDataBuf + headOffset, buf, headSize);
98af5a
da4bf3 ¤   ¤   ¤   bufPos¤ = headSize;
801e59 ¤   ¤   ¤   pos¤¤   += headSize;
bdcc39 ¤   ¤   ¤   nBytes¤ -= headSize;
--fd87 0000ea7576c40110132 Page 9 of PGPdisk.cpp
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
fd325c ¤   // Read in the middle, in 'kPGDBlocksPerOp' chunks.
5f2361 ¤   if (derr.IsntError())
1ac7a1 ¤   {
ce0110 ¤   ¤   blocksToRead = nBytes/kDefaultBlockSize;
9eaf5a
4f1424 ¤   ¤   while (derr.IsntError() && (blocksToRead > 0))¤ // is there a middle?
7c5b34 ¤   ¤   {
a07eb3 ¤   ¤   ¤   // Determine exactly how many blocks to read this iteration.
ad0415 ¤   ¤   ¤   //
09488d ¤   ¤   ¤   // blockPGPdisk = block on the PGPdisk where this read begins
e4bdea ¤   ¤   ¤   // blocksChunk = the most blocks we can read in this iteration
4daf5a
c8ea86 ¤   ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
3870b2 ¤   ¤   ¤   blocksChunk¤¤   = min(blocksToRead, kPGDBlocksPerOp);
0faf5a
da61c4 ¤   ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
25a838 ¤   ¤   ¤   ¤   blocksChunk*kDefaultBlockSize);
49af5a
819d3d ¤   ¤   ¤   if (derr.IsntError())
9ff776 ¤   ¤   ¤   {
4da8e1 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, blocksChunk, mDataBuf,·
83aa4a ¤   ¤   ¤   ¤   ¤   buf + bufPos, kCipherOp_Decrypt);
2faf5a
d2288b ¤   ¤   ¤   ¤   bufPos¤ ¤   ¤   += blocksChunk * kDefaultBlockSize;
2387b7 ¤   ¤   ¤   ¤   nBytes¤ ¤   ¤   -= blocksChunk * kDefaultBlockSize;
f71c83 ¤   ¤   ¤   ¤   pos¤¤   ¤   ¤   += blocksChunk * kDefaultBlockSize;
ec933a ¤   ¤   ¤   ¤   blocksToRead¤   -= blocksChunk;
afa3a6 ¤   ¤   ¤   }
320fe4 ¤   ¤   }
2f9371 ¤   }
c367c5 ¤
5de34f ¤   // Read in the tail.
3e2361 ¤   if (derr.IsntError())
7cc7a1 ¤   {
92a63d ¤   ¤   if (nBytes)¤¤   ¤   ¤   ¤   // is there a tail?¤
6a5b34 ¤   ¤   {
99ee47 ¤   ¤   ¤   // This read is very simple because we know the tail begins on a
c60137 ¤   ¤   ¤   // block boundary.
fb0415 ¤   ¤   ¤   //
2a9913 ¤   ¤   ¤   // blockPGPdisk = the block in the PGPdisk containing the tail.
51af5a
8c5b3c ¤   ¤   ¤   blockPGPdisk = pos/kDefaultBlockSize;
a4af5a
7d61c4 ¤   ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
83674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
88af5a
d39d3d ¤   ¤   ¤   if (derr.IsntError())
cef776 ¤   ¤   ¤   {
743707 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
1bed5a ¤   ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
33af5a
50bec9 ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf, buf + bufPos, nBytes);
f1a3a6 ¤   ¤   ¤   }
f10fe4 ¤   ¤   }
d59371 ¤   }
00af5a
eb33e3 ¤   return derr;
ffefe6 }
91af5a
b9fa56 // WriteSync performs a write request on the mounted PGPdisk synchronously.
33af5a
262292 DualErr·
5de65c PGPdisk::WriteSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes)
54bb36 {
33be41 ¤   DualErr¤¤   derr;
6a1fbb ¤   PGPUInt32¤  blocksChunk, blocksToWrite, bufPos;
3d6431 ¤   PGPUInt64¤  blockPGPdisk;
bfaf5a
0eb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
--6e38 00074639a4140110132 Page 10 of PGPdisk.cpp
a03ec3 ¤   pgpAssert(Mounted());
ecaf5a
e102d5 ¤   // The position (pos) and size (nBytes) variables are in bytes, but we
f90520 ¤   // can only perform encryption in blocks. What we have to do is handle
38db45 ¤   // the request in at most three separate pieces - a head, middle, and
fd0141 ¤   // end.
0faf5a
6e3fc7 ¤   bufPos = 0;
72af5a
7e9f70 ¤   if (pos%kDefaultBlockSize > 0)¤ // is there a head?
afc7a1 ¤   {
20cf6a ¤   ¤   PGPUInt32 headOffset, headSize;
dbaf5a
ed328c ¤   ¤   // Now write the head.
d565af ¤   ¤   //
d6f029 ¤   ¤   // blockPGPdisk = block on PGPdisk containing the head.
d03c6d ¤   ¤   // headOffset = byte offset into blockPGPdisk where head starts
eda924 ¤   ¤   // headSize = size of the head, in bytes
b2af5a
fab99d ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
1ca0b8 ¤   ¤   headOffset¤ ¤   = (PGPUInt32) (pos%kDefaultBlockSize);
208ad4 ¤   ¤   headSize¤   ¤   = min(nBytes, kDefaultBlockSize - headOffset);
93af5a
047acd ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
8becb7 ¤   ¤   ¤   kDefaultBlockSize);
ecaf5a
9baa35 ¤   ¤   if (derr.IsntError())
2f5b34 ¤   ¤   {
147970 ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
98280f ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
f5af5a
18bb98 ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf + headOffset, headSize);
e8af5a
9f7970 ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
20ade5 ¤   ¤   ¤   ¤   kCipherOp_Encrypt);
5faf5a
99cc78 ¤   ¤   ¤   derr = VolFile::Write(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
70674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
f80fe4 ¤   ¤   }
38af5a
c3aa35 ¤   ¤   if (derr.IsntError())
cf5b34 ¤   ¤   {
894bf3 ¤   ¤   ¤   bufPos¤ = headSize;
a91e59 ¤   ¤   ¤   pos¤¤   += headSize;
c7cc39 ¤   ¤   ¤   nBytes¤ -= headSize;
370fe4 ¤   ¤   }
9a9371 ¤   }
b9af5a
b7eea7 ¤   // Write the middle, in 'kPGDBlocksPerOp' chunks.
2b2361 ¤   if (derr.IsntError())
c3c7a1 ¤   {
7aa377 ¤   ¤   blocksToWrite = nBytes/kDefaultBlockSize;
40af5a
943ee4 ¤   ¤   while (derr.IsntError() && (blocksToWrite > 0))¤// is there a middle?
665b34 ¤   ¤   {
73d041 ¤   ¤   ¤   // Determine exactly how many blocks to write this iteration.
c80415 ¤   ¤   ¤   //
23445a ¤   ¤   ¤   // blockPGPdisk = block on the PGPdisk where this write begins
c77d91 ¤   ¤   ¤   // blocksChunk = the most blocks we can write in this iteration
82af5a
b0ea86 ¤   ¤   ¤   blockPGPdisk¤   = pos/kDefaultBlockSize;
d8d7f8 ¤   ¤   ¤   blocksChunk¤¤   = min(blocksToWrite, kPGDBlocksPerOp);
19af5a
ef071c ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, blocksChunk, buf + bufPos,·
9a3115 ¤   ¤   ¤   ¤   mDataBuf, kCipherOp_Encrypt);
41af5a
dfcc78 ¤   ¤   ¤   derr = VolFile::Write(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
7aa838 ¤   ¤   ¤   ¤   blocksChunk*kDefaultBlockSize);
ffaf5a
959d3d ¤   ¤   ¤   if (derr.IsntError())
d8f776 ¤   ¤   ¤   {
74288b ¤   ¤   ¤   ¤   bufPos¤ ¤   ¤   += blocksChunk * kDefaultBlockSize;
--6fd0 000dff33cf940110132 Page 11 of PGPdisk.cpp
0887b7 ¤   ¤   ¤   ¤   nBytes¤ ¤   ¤   -= blocksChunk * kDefaultBlockSize;
0f1c83 ¤   ¤   ¤   ¤   pos¤¤   ¤   ¤   += blocksChunk * kDefaultBlockSize;
5c0934 ¤   ¤   ¤   ¤   blocksToWrite¤  -= blocksChunk;
80a3a6 ¤   ¤   ¤   }
fe0fe4 ¤   ¤   }
4d9371 ¤   }
4867c5 ¤
e403fc ¤   // Write in the tail.
832361 ¤   if (derr.IsntError())
9cc7a1 ¤   {
dea63d ¤   ¤   if (nBytes)¤¤   ¤   ¤   ¤   // is there a tail?¤
615b34 ¤   ¤   {
41ee47 ¤   ¤   ¤   // This read is very simple because we know the tail begins on a
250137 ¤   ¤   ¤   // block boundary.
640415 ¤   ¤   ¤   //
199913 ¤   ¤   ¤   // blockPGPdisk = the block in the PGPdisk containing the tail.
29af5a
335b3c ¤   ¤   ¤   blockPGPdisk = pos/kDefaultBlockSize;
ffaf5a
1f61c4 ¤   ¤   ¤   derr = VolFile::Read(mDataBuf, blockPGPdisk*kDefaultBlockSize,·
06674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
90af5a
8c9d3d ¤   ¤   ¤   if (derr.IsntError())
66f776 ¤   ¤   ¤   {
f33707 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
bfed5a ¤   ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
15af5a
cf75af ¤   ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf, nBytes);
99af5a
c73707 ¤   ¤   ¤   ¤   SmartCipherBlocks(blockPGPdisk, 1, mDataBuf, mDataBuf,·
5268b0 ¤   ¤   ¤   ¤   ¤   kCipherOp_Encrypt);
1eaf5a
efe950 ¤   ¤   ¤   ¤   derr = VolFile::Write(mDataBuf,·
0e401c ¤   ¤   ¤   ¤   ¤   blockPGPdisk*kDefaultBlockSize, kDefaultBlockSize);
b7a3a6 ¤   ¤   ¤   }
780fe4 ¤   ¤   }
259371 ¤   }
11af5a
3f33e3 ¤   return derr;
82efe6 }
c5af5a
39f3d6 // Read performs a read request on the mounted PGPdisk.
c9af5a
0522ab ¤   DualErr·
88f503 PGPdisk::Read(
dee311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
323385 ¤   PGPUInt64¤  ¤   ¤   pos,·
f392c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
e8f7c6 ¤   GenericCallbackInfo¤*upInfo)
34bb36 {
d77d36 ¤   DualErr derr;
aeaf5a
aab442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
bb3ec3 ¤   pgpAssert(Mounted());
4baf5a
68cb6a ¤   DebugOut("PGPdisk: Reading PGPdisk %u at pos %u nBlocks %u", GetDrive(),·
2293d3 ¤   ¤   (PGPUInt32) (pos/kDefaultBlockSize),·
1b63c8 ¤   ¤   (PGPUInt32) (nBytes/kDefaultBlockSize));
acaf5a
64381f ¤   if (upInfo)
cf50e3 ¤   ¤   ReadAsync(buf, pos, nBytes, upInfo);
420e24 ¤   else
ee778d ¤   ¤   derr = ReadSync(buf, pos, nBytes);
c9af5a
6b33e3 ¤   return derr;
13efe6 }
1baf5a
b19a91 // Write performs a write request on the mounted PGPdisk.
28af5a
f32292 DualErr·
6343fd PGPdisk::Write(
dfe311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
--81ac 000011012c340110132 Page 12 of PGPdisk.cpp
203385 ¤   PGPUInt64¤  ¤   ¤   pos,·
be92c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
3df7c6 ¤   GenericCallbackInfo¤*upInfo)
8abb36 {
047d36 ¤   DualErr derr;
46af5a
b8b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
923ec3 ¤   pgpAssert(Mounted());
aaaf5a
f1766a ¤   DebugOut("PGPdisk: Writing PGPdisk %u at pos %u nBlocks %u", GetDrive(),·
0393d3 ¤   ¤   (PGPUInt32) (pos/kDefaultBlockSize),·
2663c8 ¤   ¤   (PGPUInt32) (nBytes/kDefaultBlockSize));
bfaf5a
3b381f ¤   if (upInfo)
48ac43 ¤   ¤   WriteAsync(buf, pos, nBytes, upInfo);
3a0e24 ¤   else
f9153d ¤   ¤   derr = WriteSync(buf, pos, nBytes);
49af5a
7133e3 ¤   return derr;
a1efe6 }
3daf5a
d0af5a
a8ed79 /////////////////////////////////////////
2b5286 // Class PGPdisk private member functions
95ed79 /////////////////////////////////////////
5baf5a
10d4f9 // SmartCipherBlocks performs the given cipher operation using whichever
8fd739 // cipher context isn't flipped.
a6af5a
4fc823 void·
b833c0 PGPdisk::SmartCipherBlocks(
ce142c ¤   PGPUInt64¤  startBlockIndex,·
4ce7f5 ¤   PGPUInt32¤  nBlocks,·
49bfcb ¤   const void¤ *src,·
c0dc73 ¤   void¤   ¤   *dest,·
cf9985 ¤   CipherOp¤   op)
b8bb36 {
62d909 ¤   pgpAssertAddrValid(mContextA, CipherContext);
ea64c3 ¤   pgpAssertAddrValid(mContextB, CipherContext);
7787c7 ¤   ¤   ¤
21d50c ¤   if (mContextA->IsFlipped())
fa4ad9 ¤   ¤   mContextB->CipherBlocks(startBlockIndex, nBlocks, src, dest, op);
240e24 ¤   else
085d16 ¤   ¤   mContextA->CipherBlocks(startBlockIndex, nBlocks, src, dest, op);
86efe6 }
baaf5a
6a1ce3 // ExecuteRequest executes the next 'piece' of the current request. If there
75e4bc // nothing left to execute, 'doneWithRequest' is set to TRUE, otherwise FALSE.
11af5a
25c823 void·
4f8d87 PGPdisk::ExecuteRequest(PGPBoolean *doneWithRequest)
e5bb36 {
6ed960 ¤   PGPUInt8¤   *buf;
61644f ¤   PGPUInt32¤  nBytes;
d4d5b8 ¤   PGPUInt64¤  pos;
42af5a
795072 ¤   pgpAssertAddrValid(doneWithRequest, PGPBoolean);
cce5ac ¤   (* doneWithRequest) = FALSE;
e5af5a
4a2453 ¤   pgpAssert(mPGPdiskReq.isInUse);
e9af5a
4123c5 ¤   // Look for the next piece of the request and process it. Read requests
4d4886 ¤   // can consist of reading the header, the tail, or any number of pieces
151199 ¤   // in the middle. Write requests are similar except header and tail
19659c ¤   // processing must be done in two parts.
20af5a
db0834 ¤   switch (mPGPdiskReq.op)
e5c7a1 ¤   {
13af5a
6f1d06 ¤   case kPGDOP_Read:
b7c14e ¤   ¤   if (!mPGPdiskReq.read.readHeader)
015b34 ¤   ¤   {
--8937 000c880e8fc40110132 Page 13 of PGPdisk.cpp
9e0f8f ¤   ¤   ¤   // Read in the header block.
04af5a
949f51 ¤   ¤   ¤   pos = mPGPdiskReq.read.posHeader;
75af5a
f17bec ¤   ¤   ¤   VolFile::Read(mDataBuf, pos - pos%kDefaultBlockSize,·
e56515 ¤   ¤   ¤   ¤   kDefaultBlockSize, &mPGPdiskReq.downInfo);
f80fe4 ¤   ¤   }
6f2341 ¤   ¤   else if (!mPGPdiskReq.read.readMiddle)
6f5b34 ¤   ¤   {
14e4b8 ¤   ¤   ¤   PGPUInt32 bytesToRead;
98af5a
7600c9 ¤   ¤   ¤   // Read in as much of the middle as we can. Leave the rest for
d5bf29 ¤   ¤   ¤   // later.
6aaf5a
ba5b9c ¤   ¤   ¤   pos¤¤   ¤   = mPGPdiskReq.read.posMiddle;
eb5204 ¤   ¤   ¤   nBytes¤ ¤   = mPGPdiskReq.read.nBytesMiddle;
0043df ¤   ¤   ¤   bytesToRead¤= min(nBytes, kPGDBlocksPerOp*kDefaultBlockSize);
06af5a
e27c47 ¤   ¤   ¤   VolFile::Read(mDataBuf, pos, bytesToRead, &mPGPdiskReq.downInfo);
630fe4 ¤   ¤   }
2956e9 ¤   ¤   else if (!mPGPdiskReq.read.readTail)
005b34 ¤   ¤   {
cd752b ¤   ¤   ¤   // Read in the tail block.
8bc299 ¤   ¤   ¤   pos = mPGPdiskReq.read.posTail;
08af5a
9b187e ¤   ¤   ¤   VolFile::Read(mDataBuf, pos, kDefaultBlockSize,·
0cd940 ¤   ¤   ¤   ¤   &mPGPdiskReq.downInfo);
3f0fe4 ¤   ¤   }
c80e1d ¤   ¤   else
875b34 ¤   ¤   {
db3c5b ¤   ¤   ¤   (* doneWithRequest) = TRUE;
c60fe4 ¤   ¤   }
7d2f68 ¤   ¤   break;
77af5a
cc82b4 ¤   case kPGDOP_Write:
3c0994 ¤   ¤   if (!mPGPdiskReq.write.readHeader)
695b34 ¤   ¤   {
e59334 ¤   ¤   ¤   // Read in the header block. This must be done because we can't
fe5d48 ¤   ¤   ¤   // encrypt in units smaller than one block. Once we've read in
1c9ed8 ¤   ¤   ¤   // the header, we modify it with data from the input buffer,
6c838f ¤   ¤   ¤   // encrypt the whole block, and write it out.
a4af5a
193d47 ¤   ¤   ¤   pos = mPGPdiskReq.write.posHeader;
57af5a
3d7bec ¤   ¤   ¤   VolFile::Read(mDataBuf, pos - pos%kDefaultBlockSize,·
296515 ¤   ¤   ¤   ¤   kDefaultBlockSize, &mPGPdiskReq.downInfo);
230fe4 ¤   ¤   }
e77e0b ¤   ¤   else if (!mPGPdiskReq.write.wroteHeader)
535b34 ¤   ¤   {
389d34 ¤   ¤   ¤   // We read in the header block, now modify it with the changed
9a6ab4 ¤   ¤   ¤   // data from the input buffer, encrypt it, and write it out.
f2af5a
3441ab ¤   ¤   ¤   buf¤¤   = mPGPdiskReq.write.bufHeader;
818ff9 ¤   ¤   ¤   pos¤¤   = mPGPdiskReq.write.posHeader;
75835d ¤   ¤   ¤   nBytes¤ = mPGPdiskReq.write.nBytesHeader;
a9af5a
5e2b96 ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
cf3236 ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf + pos%kDefaultBlockSize, nBytes);
61af5a
eb8229 ¤   ¤   ¤   SmartCipherBlocks(pos/kDefaultBlockSize, 1, mDataBuf, mDataBuf,·
b9ade5 ¤   ¤   ¤   ¤   kCipherOp_Encrypt);
00af5a
c95706 ¤   ¤   ¤   VolFile::Write(mDataBuf, pos - pos%kDefaultBlockSize,·
566515 ¤   ¤   ¤   ¤   kDefaultBlockSize, &mPGPdiskReq.downInfo);
b70fe4 ¤   ¤   }
93bc84 ¤   ¤   else if (!mPGPdiskReq.write.wroteMiddle)
1c5b34 ¤   ¤   {
199dbc ¤   ¤   ¤   PGPUInt32 bytesToWrite;
79af5a
49abfc ¤   ¤   ¤   // Encrypt and write out as much of the middle as we can. Leave
57b7bf ¤   ¤   ¤   // the rest for later.
c8af5a
--a6db 00012eebd9e40110132 Page 14 of PGPdisk.cpp
118324 ¤   ¤   ¤   buf¤¤   = mPGPdiskReq.write.bufMiddle;
1b4d76 ¤   ¤   ¤   pos¤¤   = mPGPdiskReq.write.posMiddle;
9641d2 ¤   ¤   ¤   nBytes¤ = mPGPdiskReq.write.nBytesMiddle;
17af5a
d21c86 ¤   ¤   ¤   bytesToWrite = min(nBytes, kPGDBlocksPerOp*kDefaultBlockSize);
3daf5a
ee1299 ¤   ¤   ¤   SmartCipherBlocks(pos/kDefaultBlockSize,·
fc3a6a ¤   ¤   ¤   ¤   bytesToWrite/kDefaultBlockSize, buf, mDataBuf,·
afade5 ¤   ¤   ¤   ¤   kCipherOp_Encrypt);
cdaf5a
fe2d9a ¤   ¤   ¤   VolFile::Write(mDataBuf, pos, bytesToWrite,·
9bd940 ¤   ¤   ¤   ¤   &mPGPdiskReq.downInfo);
b30fe4 ¤   ¤   }
ada925 ¤   ¤   else if (!mPGPdiskReq.write.readTail)
655b34 ¤   ¤   {
6011ec ¤   ¤   ¤   // Read in the tail block. This must be done because we can't
f75d48 ¤   ¤   ¤   // encrypt in units smaller than one block. Once we've read in
61aea0 ¤   ¤   ¤   // the tail, we modify it with data from the input buffer,
77838f ¤   ¤   ¤   // encrypt the whole block, and write it out.
91af5a
6c3fec ¤   ¤   ¤   pos = mPGPdiskReq.write.posTail;
96af5a
d67bec ¤   ¤   ¤   VolFile::Read(mDataBuf, pos - pos%kDefaultBlockSize,·
3d6515 ¤   ¤   ¤   ¤   kDefaultBlockSize, &mPGPdiskReq.downInfo);
750fe4 ¤   ¤   }
10dcbd ¤   ¤   else if (!mPGPdiskReq.write.wroteTail)
155b34 ¤   ¤   {
208007 ¤   ¤   ¤   // We read in the tail block, now modify it with the changed
ec6ab4 ¤   ¤   ¤   // data from the input buffer, encrypt it, and write it out.
6baf5a
5929cf ¤   ¤   ¤   buf¤¤   = mPGPdiskReq.write.bufTail;
319031 ¤   ¤   ¤   pos¤¤   = mPGPdiskReq.write.posTail;
1740d3 ¤   ¤   ¤   nBytes¤ = mPGPdiskReq.write.nBytesTail;
e4af5a
512b96 ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
17dbae ¤   ¤   ¤   pgpCopyMemory(buf, mDataBuf, nBytes);
e5af5a
458229 ¤   ¤   ¤   SmartCipherBlocks(pos/kDefaultBlockSize, 1, mDataBuf, mDataBuf,·
23ade5 ¤   ¤   ¤   ¤   kCipherOp_Encrypt);
71af5a
aa94d3 ¤   ¤   ¤   VolFile::Write(mDataBuf, pos, kDefaultBlockSize,·
08d940 ¤   ¤   ¤   ¤   &mPGPdiskReq.downInfo);
870fe4 ¤   ¤   }
770e1d ¤   ¤   else
e75b34 ¤   ¤   {
423c5b ¤   ¤   ¤   (* doneWithRequest) = TRUE;
410fe4 ¤   ¤   }
b42f68 ¤   ¤   break;
d0af5a
8f2f72 ¤   default:
828f52 ¤   ¤   pgpAssert(FALSE);
622f68 ¤   ¤   break;
229371 ¤   }
67efe6 }
81af5a
95f28f // PGPdiskCallback is called as a callback by the routines who executed our
0a26e7 // read and write requests. We extract the address of the PGPdisk object in
b46321 // question and pass the callback to it.
6eaf5a
54c823 void·
b74bcc PGPdisk::PGPdiskCallback(GenericCallbackInfo *downInfo)
9fbb36 {
93d87a ¤   PGPdisk *pPGD;
7aaf5a
bcac07 ¤   pgpAssertAddrValid(downInfo, GenericCallbackInfo);
97af5a
d93b95 ¤   pPGD = (PGPdisk *) downInfo->refData[0];
5c5b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
f7af5a
4b5c0e ¤   pPGD->PGPdiskCallbackAux();
59efe6 }
12af5a
--3ee4 0000944325a40110132 Page 15 of PGPdisk.cpp
7436e2 // PGPdiskCallbackAux is called by the static callback function
4f33d4 // 'PGPdiskCallback' so we don't have to type 'pPGD' before every reference
5cafa4 // to an object member or method.
61af5a
d0c823 void·
ba1a95 PGPdisk::PGPdiskCallbackAux()
f6bb36 {
5ebe41 ¤   DualErr¤¤   derr;
cbc91d ¤   PGPBoolean¤ doneWithRequest;
a1d960 ¤   PGPUInt8¤   *buf;
cd644f ¤   PGPUInt32¤  nBytes;
60d5b8 ¤   PGPUInt64¤  pos;
b9af5a
662453 ¤   pgpAssert(mPGPdiskReq.isInUse);
05af5a
1c6ab3 ¤   derr = mPGPdiskReq.downInfo.derr;
11af5a
a42361 ¤   if (derr.IsntError())
b3c7a1 ¤   {
8b2555 ¤   ¤   // Before passing the request to 'ExecuteRequest' we perform some pre-
a165b2 ¤   ¤   // processing on the data manipulated by the piece of the request that
bf0ae3 ¤   ¤   // was just processed.
68af5a
e6a56a ¤   ¤   switch (mPGPdiskReq.op)
0c5b34 ¤   ¤   {
0daf5a
e8dab3 ¤   ¤   case kPGDOP_Read:
69f88b ¤   ¤   ¤   if (!mPGPdiskReq.read.readHeader)
98f776 ¤   ¤   ¤   {
fe7937 ¤   ¤   ¤   ¤   // We read in the header block. Decrypt and copy just what the
6f872b ¤   ¤   ¤   ¤   // caller needs into his buffer.
74af5a
0f9d76 ¤   ¤   ¤   ¤   mPGPdiskReq.read.readHeader = TRUE;
48af5a
1ccba0 ¤   ¤   ¤   ¤   buf¤¤   = mPGPdiskReq.read.bufHeader;
103c97 ¤   ¤   ¤   ¤   pos¤¤   = mPGPdiskReq.read.posHeader;
bc0ab1 ¤   ¤   ¤   ¤   nBytes¤ = mPGPdiskReq.read.nBytesHeader;
1caf5a
9df324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
61af5a
11725b ¤   ¤   ¤   ¤   SmartCipherBlocks(pos/kDefaultBlockSize, 1, mDataBuf,·
e7fbc1 ¤   ¤   ¤   ¤   ¤   mDataBuf, kCipherOp_Decrypt);
5faf5a
cd8514 ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf + pos%kDefaultBlockSize, buf, nBytes);
a4a3a6 ¤   ¤   ¤   }
66fbf3 ¤   ¤   ¤   else if (!mPGPdiskReq.read.readMiddle)
8df776 ¤   ¤   ¤   {
017506 ¤   ¤   ¤   ¤   PGPUInt32 bytesRead;
f8af5a
cefc75 ¤   ¤   ¤   ¤   // We read in a piece of the middle. Decrypt it, copy it into
591d7d ¤   ¤   ¤   ¤   // the output buffer, and if there is still more middle left
32f1c1 ¤   ¤   ¤   ¤   // then adjust the variables.
e1af5a
bb092f ¤   ¤   ¤   ¤   buf¤¤   = mPGPdiskReq.read.bufMiddle;
43fe18 ¤   ¤   ¤   ¤   pos¤¤   = mPGPdiskReq.read.posMiddle;
abc83e ¤   ¤   ¤   ¤   nBytes¤ = mPGPdiskReq.read.nBytesMiddle;
60af5a
1df324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
f1af5a
1c7713 ¤   ¤   ¤   ¤   bytesRead = min(nBytes, kPGDBlocksPerOp*kDefaultBlockSize);
b4af5a
d611ee ¤   ¤   ¤   ¤   SmartCipherBlocks(pos/kDefaultBlockSize,·
f9639e ¤   ¤   ¤   ¤   ¤   bytesRead/kDefaultBlockSize, mDataBuf, buf,·
7fed5a ¤   ¤   ¤   ¤   ¤   kCipherOp_Decrypt);
27af5a
04bec6 ¤   ¤   ¤   ¤   if (nBytes - bytesRead > 0)
8b72c3 ¤   ¤   ¤   ¤   {
89ac42 ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.read.bufMiddle¤ ¤   += bytesRead;
54f7e5 ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.read.posMiddle¤ ¤   += bytesRead;
9f796e ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.read.nBytesMiddle¤  -= bytesRead;
982613 ¤   ¤   ¤   ¤   }
09fa07 ¤   ¤   ¤   ¤   else
--4db9 0008256987540110132 Page 16 of PGPdisk.cpp
d072c3 ¤   ¤   ¤   ¤   {
115816 ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.read.readMiddle = TRUE;
902613 ¤   ¤   ¤   ¤   }
05a3a6 ¤   ¤   ¤   }
d00474 ¤   ¤   ¤   else if (!mPGPdiskReq.read.readTail)
ddf776 ¤   ¤   ¤   {
e014f9 ¤   ¤   ¤   ¤   // We read in the tail block. Decrypt and copy just what the
23872b ¤   ¤   ¤   ¤   // caller needs into his buffer.
76af5a
19984c ¤   ¤   ¤   ¤   mPGPdiskReq.read.readTail = TRUE;
afaf5a
53c0bf ¤   ¤   ¤   ¤   buf¤¤   = mPGPdiskReq.read.bufTail;
7cd3d2 ¤   ¤   ¤   ¤   pos¤¤   = mPGPdiskReq.read.posTail;
7955db ¤   ¤   ¤   ¤   nBytes¤ = mPGPdiskReq.read.nBytesTail;
67af5a
36f324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
aeaf5a
7e725b ¤   ¤   ¤   ¤   SmartCipherBlocks(pos/kDefaultBlockSize, 1, mDataBuf,·
7ffbc1 ¤   ¤   ¤   ¤   ¤   mDataBuf, kCipherOp_Decrypt);
f4af5a
966b1e ¤   ¤   ¤   ¤   pgpCopyMemory(mDataBuf, buf, nBytes);
e7a3a6 ¤   ¤   ¤   }
37cdcb ¤   ¤   ¤   break;
a6af5a
a56055 ¤   ¤   case kPGDOP_Write:
38980c ¤   ¤   ¤   if (!mPGPdiskReq.write.readHeader)
fdf776 ¤   ¤   ¤   {
2fd1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
ddb091 ¤   ¤   ¤   ¤   mPGPdiskReq.write.readHeader = TRUE;
40a3a6 ¤   ¤   ¤   }
822d10 ¤   ¤   ¤   else if (!mPGPdiskReq.write.wroteHeader)
88f776 ¤   ¤   ¤   {
3bd1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
26ee95 ¤   ¤   ¤   ¤   mPGPdiskReq.write.wroteHeader = TRUE;
2ba3a6 ¤   ¤   ¤   }
7aef9f ¤   ¤   ¤   else if (!mPGPdiskReq.write.wroteMiddle)
0ff776 ¤   ¤   ¤   {
701952 ¤   ¤   ¤   ¤   PGPUInt32 bytesWritten;
7baf5a
8bd755 ¤   ¤   ¤   ¤   // We wrote out a piece of the middle. If there is still more
f6a631 ¤   ¤   ¤   ¤   // middle left to write out then adjust the variables.
aaaf5a
b79203 ¤   ¤   ¤   ¤   buf¤¤   = mPGPdiskReq.write.bufMiddle;
605c51 ¤   ¤   ¤   ¤   pos¤¤   = mPGPdiskReq.write.posMiddle;
2242a5 ¤   ¤   ¤   ¤   nBytes¤ = mPGPdiskReq.write.nBytesMiddle;
0baf5a
3ef324 ¤   ¤   ¤   ¤   pgpAssertAddrValid(buf, PGPUInt8);
55af5a
590ef4 ¤   ¤   ¤   ¤   bytesWritten = min(nBytes, kPGDBlocksPerOp*kDefaultBlockSize);
02af5a
602042 ¤   ¤   ¤   ¤   if (nBytes - bytesWritten > 0)
db72c3 ¤   ¤   ¤   ¤   {
47921a ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.write.bufMiddle¤¤   += bytesWritten;
ff9cbb ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.write.posMiddle¤¤   += bytesWritten;
8edf04 ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.write.nBytesMiddle¤ -= bytesWritten;
bc2613 ¤   ¤   ¤   ¤   }
12fa07 ¤   ¤   ¤   ¤   else
1172c3 ¤   ¤   ¤   ¤   {
757d2e ¤   ¤   ¤   ¤   ¤   mPGPdiskReq.write.wroteMiddle = TRUE;
4b2613 ¤   ¤   ¤   ¤   }
19a3a6 ¤   ¤   ¤   }
2ae61b ¤   ¤   ¤   else if (!mPGPdiskReq.write.readTail)
d4f776 ¤   ¤   ¤   {
4bd1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
ff74dd ¤   ¤   ¤   ¤   mPGPdiskReq.write.readTail = TRUE;
c8a3a6 ¤   ¤   ¤   }
73040f ¤   ¤   ¤   else if (!mPGPdiskReq.write.wroteTail)
52f776 ¤   ¤   ¤   {
28d1eb ¤   ¤   ¤   ¤   // No pre-processing needed here.
26d65b ¤   ¤   ¤   ¤   mPGPdiskReq.write.wroteTail = TRUE;
cba3a6 ¤   ¤   ¤   }
82cdcb ¤   ¤   ¤   break;
--fee5 0012a8e217440110132 Page 17 of PGPdisk.cpp
e0af5a
c19ae3 ¤   ¤   default:
fe0606 ¤   ¤   ¤   pgpAssert(FALSE);
89cdcb ¤   ¤   ¤   break;
7b0fe4 ¤   ¤   }
26af5a
49eebc ¤   ¤   // Perform further processing on this request, if needed.
9e9067 ¤   ¤   ExecuteRequest(&doneWithRequest);
be9371 ¤   }
0aaf5a
117f84 ¤   // Callback if we're done or on error.
085c5f ¤   if (doneWithRequest || derr.IsError())
c2c7a1 ¤   {
8bc030 ¤   ¤   ScheduleAsyncCallback(derr);
de9371 ¤   }
97efe6 }
f7af5a
e0f5b3 // ScheduleAsyncCallback schedules a windows event that calls our function
01e5b4 // that will call the asynchronous request up.
77af5a
73c823 void·
06b35d PGPdisk::ScheduleAsyncCallback(DualErr derr)
bbbb36 {
7a8883 ¤   static RestrictedEvent_THUNK callbackThunk;
d6af5a
e8d326 ¤   pgpAssertAddrValid(mPGPdiskReq.upInfo, GenericCallbackInfo);
e08727 ¤   mPGPdiskReq.upInfo->derr = derr;
30af5a
705424 ¤   Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED, (PVOID) this,·
d06ef4 ¤   ¤   AsyncExecuteCallback, 0, &callbackThunk);
a5efe6 }
1eaf5a
121652 // AsyncExecuteCallback was scheduled by 'ScheduleAsyncCallback' for the
2b950e // purpose of calling back up the asynchronous request we received.
f9af5a
e8a1ba VOID·
2fb45d __stdcall·
3d2df4 PGPdisk::AsyncExecuteCallback(
32bfb0 ¤   VMHANDLE¤   ¤   hVM,·
15518d ¤   THREADHANDLE¤   hThread,·
19d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
0458d6 ¤   PCLIENT_STRUCT¤ pRegs)
61bb36 {
d7d87a ¤   PGPdisk *pPGD;
0daf5a
e2e301 ¤   pPGD = (PGPdisk *) Refdata;
325b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
05af5a
7d4dd7 ¤   pgpAssert(pPGD->mPGPdiskReq.isInUse);
f8d155 ¤   pPGD->mPGPdiskReq.isInUse = FALSE;
9baf5a
853e31 ¤   pgpAssertAddrValid(pPGD->mPGPdiskReq.upInfo, GenericCallbackInfo);
04dbec ¤   pPGD->mPGPdiskReq.upInfo->callback(pPGD->mPGPdiskReq.upInfo);
2aefe6 }
--908e 00008e337c440110133 Page 1 of PGPdisk.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d75cf4 // PGPdisk.h
2f465d //
dcdda2 // Declaration of class PGPdisk.
a11bc3 //////////////////////////////////////////////////////////////////////////////
92af5a
718067 // $Id: PGPdisk.h,v 1.1.2.10 1998/07/06 08:58:25 nryan Exp $
5aaf5a
54cbce // Copyright (C) 1998 by Network Associates, Inc.
be71ae // All rights reserved.
d1af5a
02849e #ifndef Included_PGPdisk_h¤ // [
5d1582 #define Included_PGPdisk_h
66af5a
913a85 #include "DualErr.h"
14555c #include "GenericCallback.h"
9dc16a #include "PGPdiskFileFormat.h"
b070d4 #include "SecureMemory.h"
afaf5a
1f8c21 #include "CipherContext.h"
b8b3b1 #include "VolFile.h"
3eaf5a
a5af5a
b209b7 ////////////
aae738 // Constants
1b09b7 ////////////
34af5a
d58e0a const PGPUInt32 kPGDBlocksPerOp = 8;¤   // cipher this many blocks at a time
71af5a
feaf5a
2ad557 ////////
5302c9 // Types
d3d557 ////////
80af5a
7cdf69 enum PGPdiskOp {kPGDOP_Read, kPGDOP_Write};
86af5a
f41db3 // PGPdiskReadInfo holds information about read requests called down
10fdd4 // to a class PGPdisk object.
2aaf5a
03169a typedef struct PGPdiskReadInfo
d6bb36 {
1cbc9e ¤   PGPUInt8¤   *bufHeader;¤¤   ¤   // output buffer for header data
8468b9 ¤   PGPUInt64¤  posHeader;¤ ¤   ¤   // transfer position for header
935456 ¤   PGPUInt32¤  nBytesHeader;¤  ¤   // size of header
03076c ¤   PGPBoolean¤ readHeader;¤¤   ¤   // done with header?
adaf5a
00226c ¤   PGPUInt8¤   *bufMiddle;¤¤   ¤   // output buffer for middle data
41757a ¤   PGPUInt64¤  posMiddle;¤ ¤   ¤   // transfer position for middle
d181c3 ¤   PGPUInt32¤  nBytesMiddle;¤  ¤   // size of middle left to read
88053d ¤   PGPBoolean¤ readMiddle;¤¤   ¤   // done with middle?
c7af5a
62cf17 ¤   PGPUInt8¤   *bufTail;¤  ¤   ¤   // output buffer for tail data
98a798 ¤   PGPUInt64¤  posTail;¤   ¤   ¤   // transfer position for tail
b49658 ¤   PGPUInt32¤  nBytesTail;¤¤   ¤   // size of tail
7e36f2 ¤   PGPBoolean¤ readTail;¤  ¤   ¤   // done with tail?
74af5a
411558 } PGPdiskReadInfo;
85af5a
8ebb7f // PGPdiskWriteInfo holds information about write requests called down
fdfdd4 // to a class PGPdisk object.
b5af5a
4a00d5 typedef struct PGPdiskWriteInfo
febb36 {
40bc9e ¤   PGPUInt8¤   *bufHeader;¤¤   ¤   // output buffer for header data
e068b9 ¤   PGPUInt64¤  posHeader;¤ ¤   ¤   // transfer position for header
c15456 ¤   PGPUInt32¤  nBytesHeader;¤  ¤   // size of header
cd3762 ¤   PGPBoolean¤ readHeader;¤¤   ¤   // done with header read?
a3631f ¤   PGPBoolean¤ wroteHeader;¤   ¤   // done with header write?
eeaf5a
5c226c ¤   PGPUInt8¤   *bufMiddle;¤¤   ¤   // output buffer for middle data
8f757a ¤   PGPUInt64¤  posMiddle;¤ ¤   ¤   // transfer position for middle
084d87 ¤   PGPUInt32¤  nBytesMiddle;¤  ¤   // size of middle left to write
--6663 000750bdaf140110133 Page 2 of PGPdisk.h
dc4a52 ¤   PGPBoolean¤ wroteMiddle;¤   ¤   // done with middle?
b5af5a
0fcf17 ¤   PGPUInt8¤   *bufTail;¤  ¤   ¤   // output buffer for tail data
f1a798 ¤   PGPUInt64¤  posTail;¤   ¤   ¤   // transfer position for tail
af9658 ¤   PGPUInt32¤  nBytesTail;¤¤   ¤   // size of tail
4f3886 ¤   PGPBoolean¤ readTail;¤  ¤   ¤   // done with tail read?
528426 ¤   PGPBoolean¤ wroteTail;¤ ¤   ¤   // done with tail write?
70af5a
9cef40 } PGPdiskWriteInfo;
77af5a
d5e563 // PGPdiskRequestInfo holds either a read or a write request.
cbaf5a
562dd9 typedef struct PGPdiskRequestInfo
d5bb36 {
b14084 ¤   PGPBoolean¤ ¤   ¤   isInUse;¤   // this object in use?
c4312c ¤   PGPdiskOp¤  ¤   ¤   op;¤¤   ¤   // what kind of request?
94af5a
41f214 ¤   GenericCallbackInfo¤downInfo;¤  // info for call down
9f6a97 ¤   GenericCallbackInfo¤*upInfo;¤   // info for call up
51af5a
79cd18 ¤   PGPdiskReadInfo¤¤   read;¤  ¤   // info for read requests
c4fd09 ¤   PGPdiskWriteInfo¤   write;¤ ¤   // info for write requests
cbaf5a
f0875f } PGPdiskRequestInfo;
1baf5a
94af5a
789791 ////////////////
450e4d // Class PGPdisk
809791 ////////////////
f9af5a
53d155 // Class PGPdisk represents a PGPdisk file. In the future it will handle
2b56d2 // encryption and decryption of the data area but for now it just handles
303377 // parsing of the file header.
5eaf5a
2dd265 class PGPdisk : public VolFile
2cbb36 {
825ed4 public:
fbda4d ¤   DualErr¤mInitErr;
6daf5a
046d96 ¤   ¤   ¤   ¤   PGPdisk();
1552fc ¤   ¤   ¤   ¤   ~PGPdisk();
b3af5a
f01410 ¤   PGPBoolean¤ BestGuessComparePaths(LPCSTR path);
887110 ¤   PGPUInt64¤  GetUniqueSessionId();
2baf5a
bc213b ¤   void¤   ¤   FlipContexts();
e74e47 ¤   DualErr¤¤   ValidateContexts();
ffaf5a
59b26f ¤   DualErr¤¤   Mount(LPCSTR path, CipherContext *context, PDCB pDcb = NULL,·
1e34fa ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive,·
105c56 ¤   ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly = FALSE);
93499b ¤   DualErr¤¤   Unmount(PGPBoolean isThisEmergency = FALSE);
94af5a
950573 ¤   void¤   ¤   ReadAsync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
11cac5 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo);
58ad5c ¤   void¤   ¤   WriteAsync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
92cac5 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo);
88af5a
f593bc ¤   DualErr¤¤   ReadSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
49234e ¤   DualErr¤¤   WriteSync(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes);
c0af5a
32a4f4 ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
45aed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
02acdd ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
65aed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
88af5a
3c0fb9 private:
1e56b4 ¤   CipherContext¤  ¤   *mContextA;¤¤   ¤   ¤   // cipher context A
646b97 ¤   CipherContext¤  ¤   *mContextB;¤¤   ¤   ¤   // cipher context B
47af5a
9ba453 ¤   PGPUInt64¤  ¤   ¤   mUniqueSessionId;¤  ¤   // unique session ID
753cbc ¤   PGPdiskRequestInfo¤ mPGPdiskReq;¤   ¤   ¤   // request info
--f094 001517f221440110133 Page 3 of PGPdisk.h
0c474d ¤   PGPUInt8¤   ¤   ¤   *mDataBuf;¤ ¤   ¤   ¤   // data buffer
a5af5a
83aa1d ¤   SecureMemory¤   ¤   mSmContextA;¤   ¤   ¤   // secure mem for context A
136f90 ¤   SecureMemory¤   ¤   mSmContextB;¤   ¤   ¤   // secure mem for context B
45af5a
e9d97f ¤   void¤   ¤   ¤   ¤   ¤   SmartCipherBlocks(PGPUInt64 startBlockIndex,·
0b3ab2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 nBlocks, const void *src,·
6b4d3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   void *dest,¤CipherOp op);
b9af5a
047323 ¤   void¤   ¤   ¤   ¤   ¤   ExecuteRequest(PGPBoolean *doneWithRequest);
4daf5a
dd08f2 ¤   static void¤¤   ¤   ¤   PGPdiskCallback(GenericCallbackInfo *downInfo);
30da6f ¤   void¤   ¤   ¤   ¤   ¤   PGPdiskCallbackAux();
55af5a
d7c4b4 ¤   void¤   ¤   ¤   ¤   ¤   ScheduleAsyncCallback(
5deb7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DualErr derr = DualErr::NoError);
eab204 ¤   static VOID __stdcall¤  AsyncExecuteCallback(VMHANDLE hVM,·
e9f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
406ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
5c82f7 };
b2af5a
51ac0b #endif¤ // ] Included_PGPdisk_h
--c779 001d40513ff40110134 Page 1 of PGPdiskVrcSource.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
72684d // PGPdiskVrcSource.cpp
f0465d //
58cb9b // Used to create the PGPdisk.vrc file.
141bc3 //////////////////////////////////////////////////////////////////////////////
c3af5a
79cbce // Copyright (C) 1998 by Network Associates, Inc.
be71ae // All rights reserved.
66af5a
69dd28 #include "..\\..\\Shared\\PGPdiskVersion.h"
37af5a
a251c3 CompanyName¤¤   ¤   =¤  kPGPdiskCompanyName
120cd7 FileDescription¤¤   =¤  "PGPdisk Driver for Win95"
7c7b98 FileVersion¤¤   ¤   =¤  kPGPdiskFileVerString
b07c1a InternalName¤   ¤   =¤  "PGPdiskDrv.pdr"
1ef320 LegalCopyright¤ ¤   =¤  kPGPdiskCopyright
b845b6 OriginalFilename¤   =¤  "PGPdiskDrv.pdr"
d13032 ProductName¤¤   ¤   =¤  kPGPdiskProductVerName
d4425f ProductVersion¤ ¤   =¤  kPGPdiskProductVerString
--612f 0015513e03d40110135 Page 1 of PlacementNew.h
541bc3 //////////////////////////////////////////////////////////////////////////////
43d503 // PlacementNew.h
18465d //
1a200c // Definition of placement new.
ae1bc3 //////////////////////////////////////////////////////////////////////////////
b2af5a
8fd9a4 // $Id: PlacementNew.h,v 1.1.2.4 1998/07/06 08:58:26 nryan Exp $
32af5a
4fcbce // Copyright (C) 1998 by Network Associates, Inc.
6071ae // All rights reserved.
1faf5a
25e4db #ifndef Included_PlacementNew_h¤// [
4dc77e #define Included_PlacementNew_h
21af5a
29af5a
7c9791 ////////////////
016d72 // Placement New
df9791 ////////////////
78af5a
61c85e inline·
d221f6 void *·
d7d80e __cdecl·
de8138 operator new(size_t, void *pMem)
8dbb36 {
e1303d ¤   return pMem;¤   ¤   ¤   // all too easy!
29efe6 }
9faf5a
552e0f #endif // ] Included_PlacementNew_h
--6357 0006e1579d640110136 Page 1 of VolFile.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
87e84b // VolFile.cpp
05465d //
818a11 // Implementation of class VolFile.
c41bc3 //////////////////////////////////////////////////////////////////////////////
7caf5a
92f96c // $Id: VolFile.cpp,v 1.1.2.21.2.1 1998/09/01 00:31:53 nryan Exp $
45af5a
09cbce // Copyright (C) 1998 by Network Associates, Inc.
ae71ae // All rights reserved.
27af5a
b506a9 #include <vtoolscp.h>
15af5a
039bcf #include "Required.h"
a83db7 #include "FatUtils.h"
3ebfe9 #include "UtilityFunctions.h"
50af5a
8fb3b1 #include "VolFile.h"
06af5a
5586d2 #include LOCKED_CODE_SEGMENT
b55269 #include LOCKED_DATA_SEGMENT
b4af5a
54af5a
fc51ef ////////////////////////////////////////
caf944 // Class VolFile public member functions
7f51ef ////////////////////////////////////////
c9af5a
620f09 // The Class VolFile default constructor.
35af5a
d2c41f VolFile::VolFile() : File(), Volume()
4fbb36 {
2d80af ¤   mIOEnabled = TRUE;
748277 ¤   mUnmountPending = FALSE;
3aaf5a
b8d39c ¤   mIsInUse = FALSE;
5f1127 ¤   mUpInfo = NULL;
68af5a
cd550c ¤   mBBlock = NULL;
a1af5a
f5cf21 ¤   // Get our data buffer.
556af7 ¤   mInitErr = GetByteBuffer(kDefaultBlockSize, &mBBlock);
f6efe6 }
faaf5a
f5fb34 // The VolFile destructor unmounts the VolFile.
77af5a
c3bbd9 VolFile::~VolFile()
29bb36 {
30cb02 ¤   if (Mounted())
4a5972 ¤   ¤   Unmount();
5eaf5a
328464 ¤   if (IsntNull(mBBlock))
e3c7a1 ¤   {
ba96d9 ¤   ¤   FreeByteBuffer(mBBlock);
a82ff8 ¤   ¤   mBBlock = NULL;
0c9371 ¤   }
2befe6 }
feaf5a
c08273 // IsIOEnabled returns TRUE if I/O to this VolFile is enabled,
709d94 // false otherwise.
99af5a
e877be PGPBoolean·
fab5ca VolFile::IsIOEnabled()
a2bb36 {
ccecc1 ¤   return mIOEnabled;
55efe6 }
0faf5a
43539a // IsUnmountPending returns TRUE if this VolFile is unmounting, FALSE
904da2 // otherwise.
c2af5a
9c77be PGPBoolean·
ceccd2 VolFile::IsUnmountPending()
6ebb36 {
--d55e 000454ddff940110136 Page 2 of VolFile.cpp
6dcd17 ¤   return mUnmountPending;
bdefe6 }
deaf5a
f14905 // EnableIO enables or disables I/O to this VolFile.
3faf5a
e8c823 void·
9443cf VolFile::EnableIO(PGPBoolean isEnabled)
86bb36 {
023ec3 ¤   pgpAssert(Mounted());
76af5a
146050 ¤   mIOEnabled = isEnabled;
12efe6 }
7faf5a
5bd4dd // MarkUnmountPending marks or unmarks a VolFile as being unmounted.
98af5a
a5c823 void·
33fb52 VolFile::MarkUnmountPending(PGPBoolean isUnmountPending)
f2bb36 {
a63ec3 ¤   pgpAssert(Mounted());
63af5a
0d5a7e ¤   mUnmountPending = isUnmountPending;
54efe6 }
07af5a
4f230d // GetDevParams16 will fill out the elements of DevParams16 structure for the
40c343 // mounted VolFile.
27af5a
2e2292 DualErr·
7398f3 VolFile::GetDevParams16(DevParams16 *dp16)
9fbb36 {
8cbe41 ¤   DualErr¤¤   derr;
1644c5 ¤   FileSysId¤  fsId;
f2af5a
953ec3 ¤   pgpAssert(Mounted());
7d1c25 ¤   pgpAssertAddrValid(dp16, DevParams16);
46af5a
1228c7 ¤   // Get the existing file system ID.
fd2fd5 ¤   derr = GetFsId(&fsId);
57af5a
822361 ¤   if (derr.IsntError())
b3c7a1 ¤   {
307dc0 ¤   ¤   // If it appears to be already formatted, take the device params
014723 ¤   ¤   // direct from the bootblock, else invent our own.
82af5a
49e495 ¤   ¤   if (IsFatVolume(fsId))
e15b34 ¤   ¤   {
5766cb ¤   ¤   ¤   derr = Volume::GetDevParams16(dp16);
f60fe4 ¤   ¤   }
a00e1d ¤   ¤   else
025b34 ¤   ¤   {
561e34 ¤   ¤   ¤   FatData¤¤   fat;
5e77a1 ¤   ¤   ¤   Geometry¤   geom;
46defc ¤   ¤   ¤   PGPUInt64¤  megsDisk;
4daf5a
45ea64 ¤   ¤   ¤   megsDisk = (mBlocksDisk * kDefaultBlockSize) / kBytesPerMeg;
207594 ¤   ¤   ¤   fat.fdFsId = (megsDisk < 2 ? kFS_FAT12 : kFS_FAT16);
41af5a
8572dc ¤   ¤   ¤   InitFatData(&fat, mBlocksDisk);
d807a0 ¤   ¤   ¤   CalcGeometry(mBlocksDisk, kDefaultBlockSize, &geom);
6eaf5a
1eda4b ¤   ¤   ¤   pgpClearMemory(dp16, sizeof(DevParams16));
29af5a
a2da3d ¤   ¤   ¤   dp16->dpDevType¤¤   = 0x05;¤¤   ¤   ¤   // we are a hard disk
ea30e7 ¤   ¤   ¤   dp16->dpDevAttr¤¤   = 1;¤   ¤   ¤   ¤   // we are not removable
0be140 ¤   ¤   ¤   dp16->dpCylinders¤  = geom.geCyls;
aa1677 ¤   ¤   ¤   dp16->dpMediaType¤  = kMediaByte;
34af5a
60f878 ¤   ¤   ¤   dp16->dpBytesPerSec¤= kDefaultBlockSize;
b22927 ¤   ¤   ¤   dp16->dpSecPerClust¤= (PGPUInt8) fat.fdSpc;
b67bbf ¤   ¤   ¤   dp16->dpResSectors¤ = fat.fdReservedSecs;
9f7caf ¤   ¤   ¤   dp16->dpFats¤   ¤   = fat.fdFatCount;
a76b8f ¤   ¤   ¤   dp16->dpRootDirEnts¤= fat.fdRootDirEnts;
458ee2 ¤   ¤   ¤   dp16->dpSectors¤¤   = (PGPUInt16) (megsDisk < 32 ?·
--025e 0003bae115440110136 Page 3 of VolFile.cpp
6c938c ¤   ¤   ¤   ¤   mBlocksDisk : 0);
a6a210 ¤   ¤   ¤   dp16->dpMedia¤  ¤   = kMediaByte;
6478e0 ¤   ¤   ¤   dp16->dpFatSecs¤¤   = (PGPUInt16) fat.fdFatSize;
91bca5 ¤   ¤   ¤   dp16->dpSecPerTrack¤= geom.geSpt;
24db51 ¤   ¤   ¤   dp16->dpHeads¤  ¤   = geom.geHeads;
954ebc ¤   ¤   ¤   dp16->dpHiddenSecs¤ = 0;
a553ed ¤   ¤   ¤   dp16->dpHugeSectors¤= (PGPUInt32)·
2f1942 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (megsDisk >= 32 ? mBlocksDisk : 0);
560fe4 ¤   ¤   }
5d9371 ¤   }
d3af5a
ed33e3 ¤   return derr;
68efe6 }
13af5a
b5f4a1 // GetDevParams32 will fill out the elements of DevParams16 structure for the
58c343 // mounted VolFile.
5caf5a
252292 DualErr·
7b2254 VolFile::GetDevParams32(DevParams32 *dp32)
09bb36 {
9abe41 ¤   DualErr¤¤   derr;
9944c5 ¤   FileSysId¤  fsId;
32af5a
d63ec3 ¤   pgpAssert(Mounted());
e1c1a2 ¤   pgpAssertAddrValid(dp32, DevParams32);
19af5a
9228c7 ¤   // Get the existing file system ID.
002fd5 ¤   derr = GetFsId(&fsId);
84af5a
e72361 ¤   if (derr.IsntError())
48c7a1 ¤   {
577dc0 ¤   ¤   // If it appears to be already formatted, take the device params
304723 ¤   ¤   // direct from the bootblock, else invent our own.
39af5a
4ae495 ¤   ¤   if (IsFatVolume(fsId))
8c5b34 ¤   ¤   {
006504 ¤   ¤   ¤   derr = Volume::GetDevParams32(dp32);
630fe4 ¤   ¤   }
970e1d ¤   ¤   else
245b34 ¤   ¤   {
021e34 ¤   ¤   ¤   FatData¤¤   fat;
fb77a1 ¤   ¤   ¤   Geometry¤   geom;
e4defc ¤   ¤   ¤   PGPUInt64¤  megsDisk;
3aaf5a
bdea64 ¤   ¤   ¤   megsDisk = (mBlocksDisk * kDefaultBlockSize) / kBytesPerMeg;
f67594 ¤   ¤   ¤   fat.fdFsId = (megsDisk < 2 ? kFS_FAT12 : kFS_FAT16);
35af5a
5072dc ¤   ¤   ¤   InitFatData(&fat, mBlocksDisk);
4207a0 ¤   ¤   ¤   CalcGeometry(mBlocksDisk, kDefaultBlockSize, &geom);
2aaf5a
8b7c50 ¤   ¤   ¤   pgpClearMemory(dp32, sizeof(DevParams32));
58af5a
510e80 ¤   ¤   ¤   dp32->dpDevType¤¤   = 0x05;¤¤   ¤   // we are a hard disk
9e3afc ¤   ¤   ¤   dp32->dpDevAttr¤¤   = 1;¤   ¤   ¤   // we are not removable
16b41f ¤   ¤   ¤   dp32->dpCylinders¤  = geom.geCyls;
14f450 ¤   ¤   ¤   dp32->dpMediaType¤  = kMediaByte;
a1af5a
d57b87 ¤   ¤   ¤   dp32->dpBytesPerSector¤ ¤   = kDefaultBlockSize;
97ca5f ¤   ¤   ¤   dp32->dpSectorsPerClust¤¤   = (PGPUInt8) fat.fdSpc;
d66565 ¤   ¤   ¤   dp32->dpReservedSectors¤¤   = fat.fdReservedSecs;
1c7b5d ¤   ¤   ¤   dp32->dpNumberOfFats¤   ¤   = fat.fdFatCount;
23f198 ¤   ¤   ¤   dp32->dpRootEntries¤¤   ¤   = fat.fdRootDirEnts;
d921a4 ¤   ¤   ¤   dp32->dpTotalSectors¤   ¤   = (PGPUInt16)·
d58ee3 ¤   ¤   ¤   ¤   (megsDisk < 32 ? mBlocksDisk : 0);
7ea693 ¤   ¤   ¤   dp32->dpMediaDescriptor¤¤   = kMediaByte;
40a7f6 ¤   ¤   ¤   dp32->dpSectorsPerFat¤  ¤   = (PGPUInt16) fat.fdFatSize;
be43ce ¤   ¤   ¤   dp32->dpSectorsPerTrack¤¤   = geom.geSpt;
8a1f50 ¤   ¤   ¤   dp32->dpHeads¤  ¤   ¤   ¤   = geom.geHeads;
0f0868 ¤   ¤   ¤   dp32->dpHiddenSectors¤  ¤   = 0;
be7984 ¤   ¤   ¤   dp32->dpBigTotalSectors¤¤   = (PGPUInt32) (megsDisk >= 32 ?·
a4799c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mBlocksDisk : 0);
3b0fe4 ¤   ¤   }
--a66f 0009fd0d94b40110136 Page 4 of VolFile.cpp
a19371 ¤   }
93af5a
0c33e3 ¤   return derr;
96efe6 }
80af5a
c68f40 // Mount will mount the volume file specified by 'path'.
21af5a
082292 DualErr·
ee7678 VolFile::Mount(
f3f2f8 ¤   LPCSTR¤ ¤   path,·
4148c9 ¤   PGPUInt64¤  blocksHeader,·
87dbaf ¤   PGPUInt64¤  blocksDisk,·
a4d4a9 ¤   PDCB¤   ¤   pDcb,·
587fa2 ¤   PGPUInt8¤   drive,·
88bdcf ¤   PGPBoolean¤ mountReadOnly)
13bb36 {
f87d36 ¤   DualErr derr;
c2af5a
71639f ¤   pgpAssertStrValid(path);
0ae50f ¤   pgpAssert(blocksDisk > 0);
9096eb ¤   pgpAssertAddrValid(pDcb, PDCB);
09af5a
73aeca ¤   pgpAssert(Unmounted());
a7af5a
cd0bd5 ¤   // Initialize our data members.
79f480 ¤   mBlocksDisk¤¤   = blocksDisk;
19825c ¤   mBlocksHeader¤  = blocksHeader;
cdaf5a
25b90a ¤   // Prepare the DCB.
918d27 ¤   SetupDcb(pDcb, mountReadOnly);
a5af5a
5eb1fe ¤   // Open the file.
1e50eb ¤   derr = Open(path, kOF_MustExist | kOF_DenyWrite | kOF_EnableDirectDisk |·
a4b317 ¤   ¤   (mountReadOnly ? kOF_ReadOnly : NULL));
91af5a
25f65e ¤   // Fill the bootblock cache.
192361 ¤   if (derr.IsntError())
8fc7a1 ¤   {
eea279 ¤   ¤   derr = File::Read(mBBlock, blocksHeader*kDefaultBlockSize,·
34ecb7 ¤   ¤   ¤   kDefaultBlockSize);
fb9371 ¤   }
92af5a
d31e52 ¤   // Attempt the mount.
532361 ¤   if (derr.IsntError())
d1c7a1 ¤   {
d1d9e9 ¤   ¤   derr = Volume::Mount(pDcb, drive);
a09371 ¤   }
e7af5a
52e5ff ¤   // Cleanup in case of error.
ad4bb3 ¤   if (derr.IsError())
1bc7a1 ¤   {
0cb31e ¤   ¤   if (Opened())
45d730 ¤   ¤   ¤   Close();
779371 ¤   }
8daf5a
e333e3 ¤   return derr;
edefe6 }
29af5a
bc0603 // Unmount unmounts a mounted volume file. It calls down to Volume::Unmount
3a3d33 // to do the job, then closes the file.
75af5a
f52292 DualErr·
644756 VolFile::Unmount(PGPBoolean isThisEmergency)
fbbb36 {
a47d36 ¤   DualErr derr;
3faf5a
e13ec3 ¤   pgpAssert(Mounted());
7daf5a
f8070a ¤   derr = Volume::Unmount(isThisEmergency);
71af5a
e72361 ¤   if (derr.IsntError())
9fc7a1 ¤   {
--2b9b 0004ba48f3d40110136 Page 5 of VolFile.cpp
8f78ff ¤   ¤   DualErr afterFact = Close();
1be9ee ¤   ¤   pgpAssert(afterFact.IsntError());
eb9371 ¤   }
f9af5a
e533e3 ¤   return derr;
3cefe6 }
55af5a
ff58e8 // Read performs a read request on the mounted volume.
5faf5a
2b2292 DualErr·
2c5ece VolFile::Read(
8ee311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
da3385 ¤   PGPUInt64¤  ¤   ¤   pos,·
5892c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
c6f7c6 ¤   GenericCallbackInfo¤*upInfo)
f4bb36 {
c2be41 ¤   DualErr¤¤   derr;
40c02e ¤   PGPBoolean¤ useAsync;
00af5a
63b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
81b27a ¤   pgpAssert(nBytes > 0);
593ec3 ¤   pgpAssert(Mounted());
16af5a
fcc2da ¤   useAsync = IsntNull(upInfo);
08af5a
cf103f ¤   if (pos + nBytes > mBlocksDisk * kDefaultBlockSize)
a00df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
3caf5a
edde70 ¤   // Verify IO is enabled to this drive.
662361 ¤   if (derr.IsntError())
b3c7a1 ¤   {
c63191 ¤   ¤   if (!IsIOEnabled())
831494 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IOFlagViolation);
d49371 ¤   }
36af5a
b94eb4 ¤   // We now check if the system is reading the boot block only. In this
471d08 ¤   // case, we need to read from our cache because touching the disk may
0a7ddd ¤   // result in a hang.
9aaf5a
e22361 ¤   if (derr.IsntError())
95c7a1 ¤   {
4fcd79 ¤   ¤   if ((pos == 0) && (nBytes == kDefaultBlockSize))
c95b34 ¤   ¤   {
56a43a ¤   ¤   ¤   pgpCopyMemory(mBBlock, buf, kDefaultBlockSize);
c1af5a
e12d04 ¤   ¤   ¤   if (useAsync)
759720 ¤   ¤   ¤   ¤   ScheduleAsyncCallback(upInfo, derr);
bc0fe4 ¤   ¤   }
ab0e1d ¤   ¤   else
485b34 ¤   ¤   {
bd8ac7 ¤   ¤   ¤   DualErr readErr;
8eaf5a
c100cb ¤   ¤   ¤   readErr = File::Read(buf,·
40d683 ¤   ¤   ¤   ¤   pos + mBlocksHeader*kDefaultBlockSize, nBytes, upInfo);
67af5a
e7a38a ¤   ¤   ¤   if (!useAsync)
04cd45 ¤   ¤   ¤   ¤   derr = readErr;
6b0fe4 ¤   ¤   }
699371 ¤   }
c0af5a
ccfd5d ¤   if (useAsync && derr.IsError())
00c7a1 ¤   {
c096a6 ¤   ¤   ScheduleAsyncCallback(upInfo, derr);
629371 ¤   }
a8af5a
b333e3 ¤   return derr;
cbefe6 }
c3af5a
b08349 // Write performs a write request on the mounted volume. Note how Write
49c376 // accounts for the bias introduced by the size of the volume file header.
2daf5a
4b2292 DualErr·
--1e73 000e7707b9c40110136 Page 6 of VolFile.cpp
625ebf VolFile::Write(
d7e311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
013385 ¤   PGPUInt64¤  ¤   ¤   pos,·
be92c7 ¤   PGPUInt32¤  ¤   ¤   nBytes,·
b5f7c6 ¤   GenericCallbackInfo¤*upInfo)
7fbb36 {
cfbe41 ¤   DualErr¤¤   derr;
dac02e ¤   PGPBoolean¤ useAsync;
beaf5a
e6b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
42b27a ¤   pgpAssert(nBytes > 0);
9d3ec3 ¤   pgpAssert(Mounted());
5baf5a
f1c2da ¤   useAsync = IsntNull(upInfo);
4baf5a
57103f ¤   if (pos + nBytes > mBlocksDisk * kDefaultBlockSize)
380df2 ¤   ¤   derr = DualErr(kPGDMinorError_OOBFileRequest);
ffaf5a
00de70 ¤   // Verify IO is enabled to this drive.
a22361 ¤   if (derr.IsntError())
33c7a1 ¤   {
0e3191 ¤   ¤   if (!IsIOEnabled())
671494 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IOFlagViolation);
9c9371 ¤   }
24af5a
80b6bf ¤   // If the system is writing the bootblock, stick it in our cache.
a42361 ¤   if (derr.IsntError())
5cc7a1 ¤   {
32d2f0 ¤   ¤   DualErr writeErr;
50af5a
1f5f33 ¤   ¤   if ((pos == 0) && (nBytes >= kDefaultBlockSize))
b25b34 ¤   ¤   {
011559 ¤   ¤   ¤   pgpCopyMemory(buf, mBBlock, kDefaultBlockSize);
5f0fe4 ¤   ¤   }
14af5a
c07dec ¤   ¤   writeErr = File::Write(buf,·
ba98f4 ¤   ¤   ¤   pos + mBlocksHeader*kDefaultBlockSize, nBytes, upInfo);
dfaf5a
56416b ¤   ¤   if (!useAsync)
d647af ¤   ¤   ¤   derr = writeErr;
9f9371 ¤   }
92af5a
7afd5d ¤   if (useAsync && derr.IsError())
1cc7a1 ¤   {
2696a6 ¤   ¤   ScheduleAsyncCallback(upInfo, derr);
ef9371 ¤   }
bfaf5a
7f33e3 ¤   return derr;
51efe6 }
14af5a
30af5a
31ed79 /////////////////////////////////////////
e40622 // Class VolFile private member functions
3ced79 /////////////////////////////////////////
9faf5a
91c18e // SetupDcb initializes the DCB for the VolFile object prior to mounting.
40af5a
86c823 void·
3776d1 VolFile::SetupDcb(PDCB pDcb, PGPBoolean mountReadOnly)
b2bb36 {
f64eee ¤   Geometry geom;
f8af5a
6496eb ¤   pgpAssertAddrValid(pDcb, PDCB);
87af5a
b5fb3c ¤   CalcGeometry(mBlocksDisk, kDefaultBlockSize, &geom);
94af5a
974368 ¤   // Initialize the fields of the DCB_COMMON structure. The device flags
2c24d7 ¤   // and the actual geometry fields are the "most important". I say that in
47bec9 ¤   // quotes because I'm not sure how important many of these fields are,
30cfc8 ¤   // but I know that many are required.
b6af5a
e7915e ¤   pDcb->DCB_cmn.DCB_drive_lttr_equiv¤ = 0xFF;
--94e6 00024a5342840110136 Page 7 of VolFile.cpp
e0af5a
eddd5b ¤   pDcb->DCB_cmn.DCB_TSD_Flags¤¤   = DCB_TSD_NO_USER_INT13 |DCB_TSD_BAD_MBR;
95aaa6 ¤   pDcb->DCB_cmn.DCB_device_flags¤ = DCB_DEV_LOGICAL;
e0af5a
f91f7b ¤   if (!mountReadOnly)
09843c ¤   ¤   pDcb->DCB_cmn.DCB_device_flags |= DCB_DEV_WRITEABLE;
27af5a
b37180 ¤   pDcb->DCB_cmn.DCB_device_flags2¤¤   = 0;
a460b1 ¤   pDcb->DCB_cmn.DCB_Partition_Start¤  = 0;
53430e ¤   pDcb->DCB_cmn.DCB_track_table_ptr¤  = 0;
48b223 ¤   pDcb->DCB_cmn.DCB_bds_ptr¤  ¤   ¤   = 0;
55af5a
450050 ¤   pDcb->DCB_cmn.DCB_apparent_blk_shift¤   = SimpleLog2(geom.geBlockSize);
f25aa4 ¤   pDcb->DCB_cmn.DCB_partition_type¤   ¤   = NULL;
32224c ¤   pDcb->DCB_cmn.DCB_device_type¤  ¤   ¤   = DCB_type_disk;
24259e ¤   pDcb->DCB_cmn.DCB_cAssoc¤   ¤   ¤   ¤   = 0;
67c1c0 ¤   pDcb->DCB_cmn.DCB_user_drvlet¤  ¤   ¤   = 0xffff;
a3af5a
d8212b ¤   pDcb->DCB_max_xfer_len¤ ¤   ¤   = 0xFFFFFFFF;
6fee2e ¤   pDcb->DCB_actual_sector_cnt[0]¤ = GetLowDWord(geom.geSecsDisk);
b6f861 ¤   pDcb->DCB_actual_sector_cnt[1]¤ = GetHighDWord(geom.geSecsDisk);
73398e ¤   pDcb->DCB_actual_blk_size¤  ¤   = geom.geBlockSize;
58bf9c ¤   pDcb->DCB_actual_head_cnt¤  ¤   = geom.geHeads;
237986 ¤   pDcb->DCB_actual_cyl_cnt¤   ¤   = geom.geCyls;
616e51 ¤   pDcb->DCB_actual_spt¤   ¤   ¤   = geom.geSpt;
f6e245 ¤   pDcb->DCB_bus_type¤ ¤   ¤   ¤   = DCB_BUS_ESDI;
c1af5a
784430 ¤   // Fill in the BDD fields so older drivers won't become confused.
a9a38b ¤   pDcb->DCB_bdd.DCB_BDD_BD_Major_Version¤ = 0;
24e228 ¤   pDcb->DCB_bdd.DCB_BDD_BD_Minor_Version¤ = 0;
2c0f29 ¤   pDcb->DCB_bdd.DCB_BDD_Device_SubType¤   = BDT_FIXED_DISK;
eaaf5a
0f38b3 ¤   pDcb->DCB_bdd.DCB_BDD_flags = BDF_VERSION_002 | BDF_WRITEABLE;
6daf5a
4f0bf0 ¤   pDcb->DCB_bdd.DCB_apparent_sector_cnt[0] = GetLowDWord(geom.geSecsDisk);
d1d167 ¤   pDcb->DCB_bdd.DCB_apparent_sector_cnt[1] = GetHighDWord(geom.geSecsDisk);
36af5a
c24a6e ¤   pDcb->DCB_bdd.DCB_apparent_blk_size¤¤   ¤   = geom.geBlockSize;
5886cf ¤   pDcb->DCB_bdd.DCB_apparent_head_cnt¤¤   ¤   = geom.geHeads;
aebb5f ¤   pDcb->DCB_bdd.DCB_apparent_cyl_cnt¤ ¤   ¤   = geom.geCyls;
8a0180 ¤   pDcb->DCB_bdd.DCB_apparent_spt¤ ¤   ¤   ¤   = geom.geSpt;
75efe6 }
d9af5a
5bf5b3 // ScheduleAsyncCallback schedules a windows event that calls our function
85e5b4 // that will call the asynchronous request up.
ccaf5a
16c823 void·
4dc8cb VolFile::ScheduleAsyncCallback(GenericCallbackInfo *upInfo, DualErr derr)
f8bb36 {
4e8883 ¤   static RestrictedEvent_THUNK callbackThunk;
29af5a
52e29e ¤   pgpAssert(!mIsInUse);
d7f9b5 ¤   mIsInUse = TRUE;
51af5a
87e9ac ¤   pgpAssertAddrValid(upInfo, GenericCallbackInfo);
2b4b50 ¤   mUpInfo = upInfo;
3987a4 ¤   mUpInfo->derr = derr;
3caf5a
755424 ¤   Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED, (PVOID) this,·
566ef4 ¤   ¤   AsyncExecuteCallback, 0, &callbackThunk);
42efe6 }
8baf5a
a61652 // AsyncExecuteCallback was scheduled by 'ScheduleAsyncCallback' for the
ca950e // purpose of calling back up the asynchronous request we received.
b8af5a
81a1ba VOID·
61b45d __stdcall·
7b92f5 VolFile::AsyncExecuteCallback(
e3bfb0 ¤   VMHANDLE¤   ¤   hVM,·
ff518d ¤   THREADHANDLE¤   hThread,·
ead6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
2458d6 ¤   PCLIENT_STRUCT¤ pRegs)
--0376 00177370ddd40110136 Page 8 of VolFile.cpp
2cbb36 {
f5723a ¤   VolFile *pVF;
79af5a
b2f96b ¤   pVF = (VolFile *) Refdata;
70dec6 ¤   pgpAssertAddrValid(pVF, VolFile);
8daf5a
6549d6 ¤   pgpAssert(pVF->mIsInUse);
1f2676 ¤   pVF->mIsInUse = FALSE;
13af5a
11d5c1 ¤   pgpAssertAddrValid(pVF->mUpInfo, GenericCallbackInfo);
882578 ¤   pVF->mUpInfo->callback(pVF->mUpInfo);
77efe6 }
--f1e9 00064063c8040110137 Page 1 of VolFile.h
541bc3 //////////////////////////////////////////////////////////////////////////////
6bcef9 // VolFile.h
0d465d //
126954 // Declaration of class VolFile.
bf1bc3 //////////////////////////////////////////////////////////////////////////////
99af5a
35037b // $Id: VolFile.h,v 1.1.2.12 1998/07/06 08:58:28 nryan Exp $
02af5a
18cbce // Copyright (C) 1998 by Network Associates, Inc.
0171ae // All rights reserved.
18af5a
c999dc #ifndef Included_VolFile_h¤ // [
22878f #define Included_VolFile_h
58af5a
513a85 #include "DualErr.h"
7e555c #include "GenericCallback.h"
1caf5a
6df037 #include "File.h"
552561 #include "Volume.h"
4eaf5a
7daf5a
8f9791 ////////////////
217bec // Class VolFile
549791 ////////////////
ecaf5a
32091a // Class VolFile objects represent volumes associated with a file on a host
a31e8d // drive. These files can be mounted and unmounted at will, and all I/O
738706 // requests will be routed to the appropriate location on these files just
eac5c7 // like they were hard disks themselves.
ceaf5a
7cf0ed class VolFile : public File, public Volume
bfbb36 {
c15ed4 public:
e11603 ¤   DualErr mInitErr;
28af5a
e3b6e1 ¤   ¤   ¤   ¤   VolFile();
e45db8 ¤   virtual¤¤   ~VolFile();
6baf5a
6277ac ¤   PGPBoolean¤ IsUnmountPending();
e0c361 ¤   PGPBoolean¤ IsIOEnabled();
91af5a
7effda ¤   void¤   ¤   EnableIO(PGPBoolean isEnabled);
6bdae3 ¤   void¤   ¤   MarkUnmountPending(PGPBoolean isPending);
90af5a
e12e3b ¤   DualErr¤¤   GetDevParams16(DevParams16 *dp16);
8eff34 ¤   DualErr¤¤   GetDevParams32(DevParams32 *dp32);
e7af5a
41d6ba ¤   DualErr¤¤   Mount(LPCSTR path, PGPUInt64 blocksHeader,·
28b855 ¤   ¤   ¤   ¤   ¤   PGPUInt64 blocksDisk, PDCB pDcb,·
ad34fa ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive,·
421a89 ¤   ¤   ¤   ¤   ¤   PGPBoolean readOnly = FALSE);
24499b ¤   DualErr¤¤   Unmount(PGPBoolean isThisEmergency = FALSE);
0aaf5a
d2a4f4 ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
88aed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
85acdd ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBytes,·
d5aed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
54af5a
b70fb9 private:
f9c81c ¤   PGPBoolean¤ ¤   ¤   mIOEnabled;¤¤   ¤   // I/O to this drive enabled?
f1daf6 ¤   PGPBoolean¤ ¤   ¤   mUnmountPending;¤   // Unmount pending?
9eaf5a
0b3a88 ¤   PGPUInt8¤   ¤   ¤   *mBBlock;¤  ¤   ¤   // anti-crash bb cache
b0b046 ¤   PGPUInt64¤  ¤   ¤   mBlocksDisk;¤   ¤   // size of volume
e4ce00 ¤   PGPUInt64¤  ¤   ¤   mBlocksHeader;¤ ¤   // size of file header
05af5a
41db87 ¤   PGPBoolean¤ ¤   ¤   mIsInUse;¤  ¤   ¤   // object in use for async calls?
4078bb ¤   GenericCallbackInfo *mUpInfo;¤  ¤   ¤   // for faking async calls
b3af5a
095285 ¤   void¤   ¤   ¤   ¤   ¤   SetupDcb(PDCB pDcb,·
6dd673 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean mountReadOnly = FALSE);
64af5a
--10c2 00107eccd0240110137 Page 2 of VolFile.h
5cb830 ¤   void¤   ¤   ¤   ¤   ¤   ScheduleAsyncCallback(GenericCallbackInfo *upInfo,·
68eb7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DualErr derr = DualErr::NoError);
1cb204 ¤   static VOID __stdcall¤  AsyncExecuteCallback(VMHANDLE hVM,·
5ef733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
116ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
7182f7 };
48af5a
073e06 #endif¤ // ] Included_VolFile_h
--2dbd 000ad2dd40340110138 Page 1 of Volume.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
debd92 // Volume.cpp
ea465d //
b08b63 // Implementation of class Volume.
c11bc3 //////////////////////////////////////////////////////////////////////////////
8eaf5a
3df49e // $Id: Volume.cpp,v 1.1.2.18.2.1 1998/08/22 01:55:37 nryan Exp $
2eaf5a
a9cbce // Copyright (C) 1998 by Network Associates, Inc.
2a71ae // All rights reserved.
c9af5a
d706a9 #include <vtoolscp.h>
a9af5a
b29bcf #include "Required.h"
e1bfe9 #include "UtilityFunctions.h"
08af5a
3a9de2 #include "CPGPdiskDrv.h"
cfc411 #include "Globals.h"
502561 #include "Volume.h"
beaf5a
2286d2 #include LOCKED_CODE_SEGMENT
af5269 #include LOCKED_DATA_SEGMENT
feaf5a
40af5a
1604c6 ///////////////////////////////////////
626848 // Class Volume public member functions
c204c6 ///////////////////////////////////////
80af5a
c1c266 // The Class Volume constructor.
86af5a
b316bd Volume::Volume()
fabb36 {
33e6f1 ¤   mMountState¤= kVol_Unmounted;
12f9b6 ¤   mLockState¤ = kLock_None;
bbe59e ¤   mDrive¤ ¤   = kInvalidDrive;
93af5a
edfeec ¤   mAttachedToLocalVol¤= FALSE;
5fe32a ¤   mBBlock¤¤   ¤   ¤   = NULL;·
feaf5a
476ad2 ¤   mPDcb = NULL;
4caf5a
db0177 ¤   mVolumeReq.isInUse = FALSE;
e5efe6 }
88af5a
fa4ea5 // The Volume destructor unmounted the volume if was mounted by us.
adaf5a
a6b773 Volume::~Volume()
c1bb36 {
037d36 ¤   DualErr derr;
74af5a
17cb02 ¤   if (Mounted())
96c7a1 ¤   {
832527 ¤   ¤   if (AttachedToLocalVolume())
9a5b34 ¤   ¤   {
3961a4 ¤   ¤   ¤   DetachLocalVolume();
570fe4 ¤   ¤   }
620e1d ¤   ¤   else
9f5b34 ¤   ¤   {
aec3a5 ¤   ¤   ¤   derr = Unmount();
eb027b ¤   ¤   ¤   pgpAssert(derr.IsntError());
410fe4 ¤   ¤   }
bd9371 ¤   }
caefe6 }
8daf5a
2caf5c // Mounted returns TRUE if the volume is mounted, FALSE if not.
39af5a
7477be PGPBoolean·
c58fc7 Volume::Mounted()
28bb36 {
33b86d ¤   return (mMountState == kVol_Mounted);
4aefe6 }
adaf5a
--5e26 0003857daa140110138 Page 2 of Volume.cpp
5f04ce // Unmounted returns TRUE if the volume is unmounted, FALSE if not.
16af5a
1077be PGPBoolean·
183f6f Volume::Unmounted()
e9bb36 {
8125b2 ¤   return (mMountState == kVol_Unmounted);
a4efe6 }
13af5a
231501 // HasOpenFiles returns TRUE if the volume has open files, FALSE otherwise.
34af5a
e07750 PGPBoolean
35b169 Volume::HasOpenFiles()
33bb36 {
14be41 ¤   DualErr¤¤   derr;
627a9f ¤   PGPBoolean¤ hasOpenFiles;
1eaf5a
893ec3 ¤   pgpAssert(Mounted());
3eaf5a
2c116a ¤   derr = Driver->HasOpenFiles(mDrive, &hasOpenFiles);
b3af5a
e02361 ¤   if (derr.IsntError())
37d540 ¤   ¤   return hasOpenFiles;
be0e24 ¤   else
99836c ¤   ¤   return TRUE;
97efe6 }
27af5a
01cb87 // LockedForReadWrite returns TRUE if the volume is mounted and locked for
5e2364 // read/write access, FALSE otherwise.
dfaf5a
1e77be PGPBoolean·
534ddc Volume::LockedForReadWrite()
19bb36 {
9dcc45 ¤   return (Mounted() && (mLockState == kLock_ReadWrite));
17efe6 }
94af5a
73cb87 // LockedForReadWrite returns TRUE if the volume is mounted and locked for
bf0b82 // format access, FALSE otherwise.
7faf5a
c477be PGPBoolean·
5593fa Volume::LockedForFormat()
56bb36 {
6e1acd ¤   return (Mounted() && (mLockState == kLock_Format));
bcefe6 }
2baf5a
e58972 // AttachedToLocalVolume returns TRUE if the Volume object is attached to a
68110f // local volume, FALSE if not.
1caf5a
6777be PGPBoolean·
57235c Volume::AttachedToLocalVolume()
dfbb36 {
e151f9 ¤   return mAttachedToLocalVol;
c6efe6 }
9caf5a
fba362 // GetDrive returns the drive number of the volume.
88af5a
5f671d PGPUInt8·
60e319 Volume::GetDrive()
51bb36 {
913ec3 ¤   pgpAssert(Mounted());
25af5a
874cf2 ¤   return mDrive;
65efe6 }
08af5a
ca9c21 // GetBlockSize returns the block size of the volume.
4baf5a
94411c PGPUInt16·
83fe6b Volume::GetBlockSize() ·
adbb36 {
a13ec3 ¤   pgpAssert(Mounted());
cb9b37 ¤   pgpAssertAddrValid(mPDcb, DCB);
34af5a
389893 ¤   return ExtractBlockSize(mPDcb);
--9fe4 000829d72e340110138 Page 3 of Volume.cpp
7aefe6 }
46af5a
35c5fd // GetTotalBlocks returns the total number of blocks on the volume.
b2af5a
dfa385 PGPUInt64·
5d376a Volume::GetTotalBlocks()
c8bb36 {
153ec3 ¤   pgpAssert(Mounted());
c99b37 ¤   pgpAssertAddrValid(mPDcb, DCB);
cdaf5a
e9d0ad ¤   return MakeQWord(mPDcb->DCB_actual_sector_cnt[0],·
45f01a ¤   ¤   mPDcb->DCB_actual_sector_cnt[0]);
0cefe6 }
10af5a
a0fe5b // GetDcb returns a pointer to the DCB.
58af5a
4bf4db PDCB·
bd1c40 Volume::GetDcb()
60bb36 {
143ec3 ¤   pgpAssert(Mounted());
549b37 ¤   pgpAssertAddrValid(mPDcb, DCB);
cfaf5a
bb6846 ¤   return mPDcb;
a8efe6 }
6caf5a
8e230d // GetDevParams16 will fill out the elements of DevParams16 structure for the
52e8ed // mounted Volume by reading directly from the boot block.
34af5a
b52292 DualErr·
8a4cda Volume::GetDevParams16(DevParams16 *dp16)
92bb36 {
ba9a95 ¤   DualErr¤¤   ¤   derr;
36f459 ¤   PBootSector16¤  pBS16;
6baf5a
131c25 ¤   pgpAssertAddrValid(dp16, DevParams16);
f26280 ¤   pgpAssertAddrValid(mBBlock, PGPUInt8);
8e3ec3 ¤   pgpAssert(Mounted());
91af5a
57f437 ¤   derr = Read(mBBlock, 0, 1);
8b1ed6 ¤   pBS16 = (PBootSector16) mBBlock;
79af5a
492361 ¤   if (derr.IsntError())
23c7a1 ¤   {
e6cb6c ¤   ¤   pgpClearMemory(dp16, sizeof(DevParams16));
1faf5a
25cc8b ¤   ¤   dp16->dpDevType¤¤   = 0x05;¤¤   ¤   ¤   // we are a hard disk
162bee ¤   ¤   dp16->dpDevAttr¤¤   = 1;¤   ¤   ¤   ¤   // we are not removable
ab4bd3 ¤   ¤   dp16->dpCylinders¤  = (PGPUInt16) mPDcb->DCB_actual_cyl_cnt;
c193fa ¤   ¤   dp16->dpMediaType¤  = pBS16->bsMedia;
09af5a
184a9f ¤   ¤   dp16->dpBytesPerSec¤= pBS16->bsBytesPerSec;
a3bd0d ¤   ¤   dp16->dpSecPerClust¤= pBS16->bsSecPerClust;
c46b0d ¤   ¤   dp16->dpResSectors¤ = pBS16->bsResSectors;
6e8cec ¤   ¤   dp16->dpFats¤   ¤   = pBS16->bsFats;
7d8c27 ¤   ¤   dp16->dpRootDirEnts¤= pBS16->bsRootDirEnts;
6c467d ¤   ¤   dp16->dpSectors¤¤   = pBS16->bsSectors;
c7b41c ¤   ¤   dp16->dpMedia¤  ¤   = pBS16->bsMedia;
fe1225 ¤   ¤   dp16->dpFatSecs¤¤   = pBS16->bsFatSecs;
85f038 ¤   ¤   dp16->dpSecPerTrack¤= pBS16->bsSecPerTrack;
742245 ¤   ¤   dp16->dpHeads¤  ¤   = pBS16->bsHeads;
bb413c ¤   ¤   dp16->dpHiddenSecs¤ = pBS16->bsHiddenSecs;
0b33b5 ¤   ¤   dp16->dpHugeSectors¤= pBS16->bsHugeSectors;
c49371 ¤   }
a0af5a
b333e3 ¤   return derr;
57efe6 }
06af5a
e4ff12 // GetDevParams32 will fill out the elements of DevParams32 structure for the
e1e8ed // mounted Volume by reading directly from the boot block.
d7af5a
042292 DualErr·
82f67d Volume::GetDevParams32(DevParams32 *dp32)
--34dd 000a414cab740110138 Page 4 of Volume.cpp
2cbb36 {
059a95 ¤   DualErr¤¤   ¤   derr;
2af2a0 ¤   PBootSector32¤  pBS32;
81af5a
533ec3 ¤   pgpAssert(Mounted());
78c1a2 ¤   pgpAssertAddrValid(dp32, DevParams32);
386280 ¤   pgpAssertAddrValid(mBBlock, PGPUInt8);
b2af5a
3bf437 ¤   derr = Read(mBBlock, 0, 1);
71af5a
36adeb ¤   pBS32 = (PBootSector32) mBBlock;
84af5a
142361 ¤   if (derr.IsntError())
d8c7a1 ¤   {
1a6d77 ¤   ¤   pgpClearMemory(dp32, sizeof(DevParams32));
5caf5a
521ba3 ¤   ¤   dp32->dpDevType¤¤   = 0x05;¤¤   ¤   // we are a hard disk
36748b ¤   ¤   dp32->dpDevAttr¤¤   = 1;¤   ¤   ¤   // we are not removable
83558f ¤   ¤   dp32->dpCylinders¤  = (PGPUInt16) mPDcb->DCB_actual_cyl_cnt;
45f9bd ¤   ¤   dp32->dpMediaType¤  = pBS32->bsMedia;
7faf5a
3e6e54 ¤   ¤   dp32->dpBytesPerSector¤ ¤   = pBS32->bsBytesPerSec;
de1ae9 ¤   ¤   dp32->dpSectorsPerClust¤¤   = pBS32->bsSecPerClust;
4cbae2 ¤   ¤   dp32->dpReservedSectors¤¤   = pBS32->bsResSectors;
8d27db ¤   ¤   dp32->dpNumberOfFats¤   ¤   = pBS32->bsFats;
362506 ¤   ¤   dp32->dpRootEntries¤¤   ¤   = pBS32->bsRootDirEnts;
d0464f ¤   ¤   dp32->dpTotalSectors¤   ¤   = pBS32->bsSectors;
b99dbb ¤   ¤   dp32->dpMediaDescriptor¤¤   = pBS32->bsMedia;
9f8caa ¤   ¤   dp32->dpSectorsPerFat¤  ¤   = pBS32->bsFatSecs;
3ae81b ¤   ¤   dp32->dpSectorsPerTrack¤¤   = pBS32->bsSecPerTrack;
86f9d0 ¤   ¤   dp32->dpHeads¤  ¤   ¤   ¤   = pBS32->bsHeads;
75e99c ¤   ¤   dp32->dpHiddenSectors¤  ¤   = pBS32->bsHiddenSecs;
6ed1db ¤   ¤   dp32->dpBigTotalSectors¤¤   = pBS32->bsHugeSectors;
92b643 ¤   ¤   dp32->dpBigSectorsPerFat¤   = pBS32->bsBigSectorsPerFat;
cc22a3 ¤   ¤   dp32->dpExtFlags¤   ¤   ¤   = pBS32->bsExtFlags;
f81cfb ¤   ¤   dp32->dpFS_Version¤ ¤   ¤   = pBS32->bsFS_Version;
7da100 ¤   ¤   dp32->dpRootDirStrtClus¤¤   = pBS32->bsRootDirStrtClus;
89ecd8 ¤   ¤   dp32->dpFsInfoSec¤  ¤   ¤   = pBS32->bsFsInfoSec;
a130d0 ¤   ¤   dp32->dpBkUpBootSec¤¤   ¤   = pBS32->bsBkUpBootSec;
bd9371 ¤   }
aaaf5a
4933e3 ¤   return derr;
5fefe6 }
38af5a
000933 // GetMediaId fills in a MID structure with information about the volume.
fdaf5a
2a2292 DualErr·
fd6faf Volume::GetMediaId(MID *pMid)
2fbb36 {
0bbe41 ¤   DualErr¤¤   derr;
38fe65 ¤   PGPBoolean¤ foundRecognizedFileSys¤ = FALSE;
c6af5a
cff801 ¤   pgpAssertAddrValid(pMid, MID);
01af5a
113ec3 ¤   pgpAssert(Mounted());
c06280 ¤   pgpAssertAddrValid(mBBlock, PGPUInt8);
1eaf5a
e3f437 ¤   derr = Read(mBBlock, 0, 1);
ffaf5a
aa2361 ¤   if (derr.IsntError())
f5c7a1 ¤   {
6e1697 ¤   ¤   LPSTR fsStr;
2faf5a
036c25 ¤   ¤   pMid->midInfoLevel = 0;
ccaf5a
7f5e41 ¤   ¤   fsStr = (LPSTR) mBBlock + kFat12Offset;
3c890a ¤   ¤   if (!strncmp(fsStr, "FAT12", 5))¤   ¤   ¤   // is it a FAT12 drive?
885b34 ¤   ¤   {
ddf8d3 ¤   ¤   ¤   PBootSector12 pBS12 = (PBootSector12) mBBlock;
28af5a
ef2deb ¤   ¤   ¤   foundRecognizedFileSys = TRUE;
a4bc2f ¤   ¤   ¤   pMid->midSerialNum = pBS12->bsVolumeId;
--99a2 000c25ca38840110138 Page 5 of Volume.cpp
e0af5a
d6a9cd ¤   ¤   ¤   strncpy((char *) pMid->midVolLabel, pBS12->bsVolumeLabel, 11);
a8d02a ¤   ¤   ¤   strncpy((char *) pMid->midFileSysType, pBS12->bsFileSysType, 8);
720fe4 ¤   ¤   }
81af5a
4561a4 ¤   ¤   fsStr = (LPSTR) mBBlock + kFat16Offset;
0701ee ¤   ¤   if (!strncmp(fsStr, "FAT16", 5))¤   ¤   ¤   // is it a FAT16 drive?
f55b34 ¤   ¤   {
cc35b6 ¤   ¤   ¤   PBootSector16 pBS16 = (PBootSector16) mBBlock;
90af5a
9c2deb ¤   ¤   ¤   foundRecognizedFileSys = TRUE;
5f9496 ¤   ¤   ¤   pMid->midSerialNum = pBS16->bsVolumeId;
6baf5a
7a9ecb ¤   ¤   ¤   strncpy((char *) pMid->midVolLabel, pBS16->bsVolumeLabel, 11);
a9657c ¤   ¤   ¤   strncpy((char *) pMid->midFileSysType, pBS16->bsFileSysType, 8);
d60fe4 ¤   ¤   }
cfaf5a
a5060f ¤   ¤   fsStr = (LPSTR) mBBlock + kFat32Offset;
6ad9db ¤   ¤   if (!strncmp(fsStr, "FAT32", 5))¤   ¤   ¤   // is it a FAT32 drive?
425b34 ¤   ¤   {
81e2e0 ¤   ¤   ¤   PBootSector32 pBS32 = (PBootSector32) mBBlock;
5faf5a
262deb ¤   ¤   ¤   foundRecognizedFileSys = TRUE;
93a81e ¤   ¤   ¤   pMid->midSerialNum = pBS32->bsVolumeId;
e8af5a
571f45 ¤   ¤   ¤   strncpy((char *) pMid->midVolLabel, pBS32->bsVolumeLabel, 11);
19cba9 ¤   ¤   ¤   strncpy((char *) pMid->midFileSysType, pBS32->bsFileSysType, 8);
d80fe4 ¤   ¤   }
58af5a
766ce7 ¤   ¤   // Special case for incorrectly formatted floppy drives. If the
a89167 ¤   ¤   // filesystem is unknown but the media is a floppy, assume FAT12.
19af5a
c15fa8 ¤   ¤   if (!foundRecognizedFileSys)
fd5b34 ¤   ¤   {
acf8d3 ¤   ¤   ¤   PBootSector12 pBS12 = (PBootSector12) mBBlock;
4faf5a
a2a763 ¤   ¤   ¤   if (pBS12->bsMedia == kFloppyMediaId)
44f776 ¤   ¤   ¤   {
0ce983 ¤   ¤   ¤   ¤   pMid->midSerialNum = pBS12->bsVolumeId;
4eaf5a
cf44ea ¤   ¤   ¤   ¤   strncpy((char *) pMid->midVolLabel, pBS12->bsVolumeLabel, 11);
0c907a ¤   ¤   ¤   ¤   strncpy((char *) pMid->midFileSysType, "FAT12 ··", 8);
35a3a6 ¤   ¤   ¤   }
a30fe4 ¤   ¤   }
d69371 ¤   }
feaf5a
9533e3 ¤   return derr;
3eefe6 }
71af5a
6de617 // GetFsId returns the ID of the filesystem of the mounted volume by reading
6b76d2 // the volume's bootsector and then seeing if it can find an identifier
649f49 // describing a known filesystem.
5baf5a
5b2292 DualErr·
d21862 Volume::GetFsId(FileSysId *fsId)
febb36 {
f0945d ¤   DualErr¤derr;
8b67c3 ¤   MID¤¤   mid;
a1af5a
791caa ¤   pgpAssertAddrValid(fsId, FileSysId);
eaaf5a
5f3ec3 ¤   pgpAssert(Mounted());
b76280 ¤   pgpAssertAddrValid(mBBlock, PGPUInt8);
9baf5a
7688b8 ¤   (* fsId) = kFS_Unknown;
9aaf5a
f8f12d ¤   derr = GetMediaId(&mid);
13af5a
662361 ¤   if (derr.IsntError())
9cc7a1 ¤   {
8b8dda ¤   ¤   LPSTR fsStr = (char *) mid.midFileSysType;
c2af5a
--5510 000a374954940110138 Page 6 of Volume.cpp
41411a ¤   ¤   if (!strncmp(fsStr, "FAT12", 5))¤   ¤   // is it a FAT12 drive?
5c8f25 ¤   ¤   ¤   (* fsId) = kFS_FAT12;
66af5a
065d56 ¤   ¤   if (!strncmp(fsStr, "FAT16", 5))¤   ¤   // is it a FAT16 drive?
61ec44 ¤   ¤   ¤   (* fsId) = kFS_FAT16;
50af5a
020520 ¤   ¤   if (!strncmp(fsStr, "FAT32", 5))¤   ¤   // is it a FAT32 drive?
2db653 ¤   ¤   ¤   (* fsId) = kFS_FAT32;
539371 ¤   }
e9af5a
d033e3 ¤   return derr;
d6efe6 }
36af5a
32fff6 // AttachLocalVolume initializes this Volume object for access to an already
ab3bc5 // mounted volume on the local computer.
20af5a
022292 DualErr·
d2b0d2 Volume::AttachLocalVolume(PGPUInt8 drive)
47bb36 {
63945d ¤   DualErr¤derr;
79976b ¤   PDCB¤   pDcb;
35af5a
69aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
75aeca ¤   pgpAssert(Unmounted());
72227d ¤   pgpAssert(!AttachedToLocalVolume());
7aaf5a
f3ecad ¤   // Find the DCB by making a system call.
c7acab ¤   if (!(pDcb = IspGetDcb(drive)))
570e42 ¤   ¤   derr = DualErr(kPGDMinorError_IspGetDcbFailed);
caaf5a
452361 ¤   if (derr.IsntError())
f7c7a1 ¤   {
fbb73d ¤   ¤   derr = InitMountedVars(drive, pDcb);
92a540 ¤   ¤   mAttachedToLocalVol = derr.IsntError();
399371 ¤   }
4caf5a
4c33e3 ¤   return derr;
1befe6 }
1eaf5a
ffbdfa // DetachLocalVolume marks this Volume object as no longer being associated
d067e5 // with a local volume.
9faf5a
55c823 void·
e6463a Volume::DetachLocalVolume()
9fbb36 {
fa3ec3 ¤   pgpAssert(Mounted());
a2bfb5 ¤   pgpAssert(AttachedToLocalVolume());
b4af5a
feec86 ¤   mAttachedToLocalVol = FALSE;
ea3f6b ¤   CleanUpMountedVars();
76efe6 }
57af5a
c714a6 // Mount() mounts the volume on the specified drive letter using the
aa68a8 // specified DCB.
2caf5a
172292 DualErr·
3af2d1 Volume::Mount(PDCB pDcb, PGPUInt8 drive)
2cbb36 {
abbe41 ¤   DualErr¤¤   derr;
7177bc ¤   PGPBoolean¤ assocedDcb¤ = FALSE;
4faf5a
56a603 ¤   pgpAssertAddrValid(pDcb, DCB);
62aeca ¤   pgpAssert(Unmounted());
0a227d ¤   pgpAssert(!AttachedToLocalVolume());
92af5a
2be92d ¤   // If no preferred drive letter is specified, or if the drive is in use,·
a348e8 ¤   // we make a system call to get the next free drive letter.
5faf5a
08828d ¤   if ((drive < 2) || (drive >= kMaxDrives) || (IsntNull(IspGetDcb(drive))))
78c7a1 ¤   {
778362 ¤   ¤   drive = pDcb->DCB_cmn.DCB_drive_lttr_equiv =·
a38e74 ¤   ¤   ¤   IspDriveLetterPick(mPDcb, NULL);
--a181 000fd24b18a40110138 Page 7 of Volume.cpp
e0af5a
094f72 ¤   ¤   if (drive == kInvalidDrive)
b9b1d0 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IspDriveLetterPickFailed);
52f828 ¤   }¤
3aaf5a
ab9108 ¤   // Then we make another call to associate this driver letter with our
ac3c85 ¤   // DCB, thereby mounting the volume.
73af5a
912361 ¤   if (derr.IsntError())
a9c7a1 ¤   {
28196e ¤   ¤   if (!IspAssociateDcb(pDcb, drive, NULL))
efd1d7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IspAssociateDcbFailed);
7daf5a
0ce2fe ¤   ¤   assocedDcb = derr.IsntError();
f69371 ¤   }
7eaf5a
309cf0 ¤   // Initialize some variables for mounted drives.
b42361 ¤   if (derr.IsntError())
c0c7a1 ¤   {
46b73d ¤   ¤   derr = InitMountedVars(drive, pDcb);
5c9371 ¤   }
a4af5a
7b1e99 ¤   // Clean up in case of error.
874bb3 ¤   if (derr.IsError())
9ac7a1 ¤   {
1719af ¤   ¤   if (assocedDcb)
38ff16 ¤   ¤   ¤   IspDisassociateDcb(drive);
749371 ¤   }
82af5a
f133e3 ¤   return derr;
97efe6 }
3baf5a
3c2f10 // Unmount unmounts a mounted Volume.
2faf5a
bd2292 DualErr·
5b23d4 Volume::Unmount(PGPBoolean isThisEmergency)
b2bb36 {
b6be41 ¤   DualErr¤¤   derr;
65b6e2 ¤   LockLevel¤  oldLock;
218d96 ¤   PGPBoolean¤ hasOpenFiles, lockedDown;
b7af5a
443ec3 ¤   pgpAssert(Mounted());
bf227d ¤   pgpAssert(!AttachedToLocalVolume());
bbaf5a
021978 ¤   hasOpenFiles = lockedDown = FALSE;
38af5a
8e9b47 ¤   if (!isThisEmergency)
9bc7a1 ¤   {
4a1a5e ¤   ¤   // Check for open files.
789e3d ¤   ¤   derr = Driver->HasOpenFiles(mDrive, &hasOpenFiles);
a1af5a
41aa35 ¤   ¤   if (derr.IsntError())
b95b34 ¤   ¤   {
13337b ¤   ¤   ¤   if (hasOpenFiles)
987755 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FilesOpenOnDrive);
5d0fe4 ¤   ¤   }
06af5a
adaa35 ¤   ¤   if (derr.IsntError())
245b34 ¤   ¤   {
13ddae ¤   ¤   ¤   // Flush the volume.
822d17 ¤   ¤   ¤   VolFlush(mDrive, NULL);
2daf5a
4d8774 ¤   ¤   ¤   // Get a lock on the drive.
86f802 ¤   ¤   ¤   oldLock = Driver->GetLockLevel(mDrive);
a2c67e ¤   ¤   ¤   derr = Driver->AcquireLogicalVolLock(mDrive, kLock_L3);
8faf5a
1ee8c1 ¤   ¤   ¤   lockedDown = derr.IsntError();
c70fe4 ¤   ¤   }
f99371 ¤   }
81af5a
472361 ¤   if (derr.IsntError())
fdc7a1 ¤   {
--3d31 00054c90d7140110138 Page 8 of Volume.cpp
f6b0c4 ¤   ¤   // Some people tell me this should be done to prevent hangs. (?)
5b173e ¤   ¤   NotifyVolumeRemoval(GetDrive());
5eaf5a
ccd53e ¤   ¤   // We make a system call to disassociate the mounted DCB with its
11692a ¤   ¤   // drive letter, thereby unmounting the volume.
e1af5a
c47248 ¤   ¤   if (!IspDisassociateDcb(GetDrive()))
156b81 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IspDisassocDcbFailed);
d39371 ¤   }
01af5a
ec2361 ¤   if (derr.IsntError())
d9c7a1 ¤   {
0bb63f ¤   ¤   CleanUpMountedVars();
b39371 ¤   }
b5af5a
814bb3 ¤   if (derr.IsError())
7bc7a1 ¤   {
80d9fa ¤   ¤   if (lockedDown)
f48d61 ¤   ¤   ¤   Driver->AcquireLogicalVolLock(mDrive, oldLock);
279371 ¤   }
9aaf5a
5033e3 ¤   return derr;
e6efe6 }
4daf5a
dd2a09 // LockVolumeForReadWrite locks the mounted volume for direct read/write
005ca5 // access.
87af5a
a52292 DualErr·
977551 Volume::LockVolumeForReadWrite()
5ebb36 {
dd7d36 ¤   DualErr derr;
9d67c5 ¤
8b3ec3 ¤   pgpAssert(Mounted());
80f283 ¤   pgpAssert(!LockedForReadWrite() && !LockedForFormat());
c2af5a
fc3f0c ¤   derr = Driver->AcquireLogicalVolLock(mDrive, kLock_L3);
b0af5a
312361 ¤   if (derr.IsntError())
02c7a1 ¤   {
b0e246 ¤   ¤   mLockState = kLock_ReadWrite;
349371 ¤   }
3baf5a
9833e3 ¤   return derr;
6eefe6 }
9faf5a
015eeb // LockVolumeForFormat locks the mounted volume for formatting.
b3af5a
4c2292 DualErr·
68d7e3 Volume::LockVolumeForFormat()
29bb36 {
8b7d36 ¤   DualErr derr;
9f67c5 ¤
cf3ec3 ¤   pgpAssert(Mounted());
66f283 ¤   pgpAssert(!LockedForReadWrite() && !LockedForFormat());
2faf5a
4531df ¤   derr = Driver->GetFormatLockOnDrive(mDrive);
82af5a
f42361 ¤   if (derr.IsntError())
31c7a1 ¤   {
f352d6 ¤   ¤   mLockState = kLock_Format;
af9371 ¤   }
02af5a
3333e3 ¤   return derr;
6eefe6 }
95af5a
7dfb18 // UnlockVolume removes any outstanding locks on the volume;
45af5a
a32292 DualErr·
4bdf21 Volume::UnlockVolume()
c4bb36 {
177d36 ¤   DualErr derr;
54af5a
--88bc 000a1f2295540110138 Page 9 of Volume.cpp
a03ec3 ¤   pgpAssert(Mounted());
d0e241 ¤   pgpAssert(LockedForReadWrite() || LockedForFormat());
44af5a
20b92d ¤   if (LockedForReadWrite())
82b9df ¤   ¤   derr = Driver->AcquireLogicalVolLock(mDrive, ::kLock_None);
7a0e24 ¤   else
29fa94 ¤   ¤   derr = Driver->ReleaseFormatLockOnDrive(mDrive);
2eaf5a
892361 ¤   if (derr.IsntError())
1ac7a1 ¤   {
dcd00b ¤   ¤   mLockState = kLock_None;
eb9371 ¤   }
54af5a
fd33e3 ¤   return derr;
0defe6 }
9aaf5a
9a09ec // Read reads 'nBlocks' sectors from the logical mounted volume from sector
b8df22 // position 'pos'.
10af5a
1b2292 DualErr·
00af19 Volume::Read(
b0e311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
c03385 ¤   PGPUInt64¤  ¤   ¤   pos,·
afa995 ¤   PGPUInt32¤  ¤   ¤   nBlocks,·
c2f7c6 ¤   GenericCallbackInfo¤*upInfo)
a9bb36 {
eeb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
0aaf5a
e071a8 ¤   return DiskAccess(IOR_READ, buf, pos, nBlocks, upInfo);
04efe6 }
e6af5a
bc2bf4 // Write reads 'nBlocks' sectors from the logical mounted volume from sector
cddf22 // position 'pos'.
cdaf5a
292292 DualErr·
25fc7c Volume::Write(
cde311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
183385 ¤   PGPUInt64¤  ¤   ¤   pos,·
8ca995 ¤   PGPUInt32¤  ¤   ¤   nBlocks,·
76f7c6 ¤   GenericCallbackInfo¤*upInfo)
28bb36 {
0eb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
f5af5a
38164c ¤   return DiskAccess(IOR_WRITE, buf, pos, nBlocks, upInfo);
c7efe6 }
94af5a
0caf5a
9c51ef ////////////////////////////////////////
faccdf // Class Volume private member functions
6e51ef ////////////////////////////////////////
efaf5a
52364e // InitMountedVars initializes some variables that describe a mounted volume
a01bd9 // and/or can be used to perform I/O on that volume.
20af5a
072292 DualErr·
da421b Volume::InitMountedVars(PGPUInt8 drive, PDCB pDcb)
d6bb36 {
d07d36 ¤   DualErr derr;
a0af5a
42aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
80aeca ¤   pgpAssert(Unmounted());
f6a603 ¤   pgpAssertAddrValid(pDcb, DCB);
d7af5a
cf49fa ¤   // Allocate a buffer for bootblock and devparam requests.
c02361 ¤   if (derr.IsntError())
35c7a1 ¤   {
dd634e ¤   ¤   derr = GetByteBuffer(ExtractBlockSize(pDcb), (PGPUInt8 **) &mBBlock);
9f9371 ¤   }
4daf5a
0d2361 ¤   if (derr.IsntError())
e7c7a1 ¤   {
a11bb7 ¤   ¤   mMountState = kVol_Mounted;
--fa4c 000b4548f8040110138 Page 10 of Volume.cpp
ad3566 ¤   ¤   mDrive = drive;
28af5a
c23fb4 ¤   ¤   mPDcb = pDcb;
409371 ¤   }
33af5a
c033e3 ¤   return derr;
f3efe6 }
dcaf5a
a510a4 // CleanUpMountedVars cleans up those variables we initialized in
208a97 // InitMountedVars.
74af5a
adc823 void·
1fc8ce Volume::CleanUpMountedVars()
7dbb36 {
953ec3 ¤   pgpAssert(Mounted());
106280 ¤   pgpAssertAddrValid(mBBlock, PGPUInt8);
a6af5a
9d438c ¤   mMountState = kVol_Unmounted;
e5af5a
422d8f ¤   FreeByteBuffer(mBBlock);
d4af5a
00bd40 ¤   mDrive = kInvalidDrive;
f3af5a
89550c ¤   mBBlock = NULL;
d06ad2 ¤   mPDcb = NULL;
61efe6 }
64af5a
1f6698 // DiskAccess performs either an IOR_READ or an IOR_WRITE operation on the
163368 // mounted volume.
e8af5a
f32292 DualErr·
05cf2d Volume::DiskAccess(
5c9ec6 ¤   PGPUInt16¤  ¤   ¤   func,·
4ae311 ¤   PGPUInt8¤   ¤   ¤   *buf,·
443385 ¤   PGPUInt64¤  ¤   ¤   pos,·
78a995 ¤   PGPUInt32¤  ¤   ¤   nBlocks,·
0ff7c6 ¤   GenericCallbackInfo¤*upInfo)
01bb36 {
c1be41 ¤   DualErr¤¤   derr;
6ec33f ¤   PIOP¤   ¤   pIop;
47e6d3 ¤   PIOR¤   ¤   pIor;
b8c02e ¤   PGPBoolean¤ useAsync;
6d5cc3 ¤   PGPUInt16¤  offset, size;
cffa27 ¤   PVRP¤   ¤   pVrp;
56af5a
51b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
4daf5a
64c70d ¤   pgpAssert((func == IOR_READ) || (func == IOR_WRITE));
67af5a
6c2112 ¤   // Is this request asynchronous?
e9c2da ¤   useAsync = IsntNull(upInfo);
9baf5a
1d3ec3 ¤   pgpAssert(Mounted());
a39b37 ¤   pgpAssertAddrValid(mPDcb, DCB);
739b81 ¤   pgpAssert(!mVolumeReq.isInUse);
0caf5a
639f66 ¤   // Prepare the request.
19bf21 ¤   mVolumeReq.isInUse = TRUE;
9067c5 ¤
ddd02b ¤   if (useAsync)
7dc7a1 ¤   {
171247 ¤   ¤   mVolumeReq.upInfo = upInfo;
1588fe ¤   ¤   mVolumeReq.downInfo.refData[0] = (PGPUInt32) this;
239371 ¤   }
b9af5a
5f2f10 ¤   // Make sure we check that the VRP field in the DCB exists; the system
599944 ¤   // has a habit of nullifying it when an I/O error occurs.
a7af5a
15a1aa ¤   if (!(pVrp = (PVRP) mPDcb->DCB_cmn.DCB_vrp_ptr))
268f7f ¤   ¤   derr = DualErr(kPGDMinorError_InvalidVRP);
36af5a
b47316 ¤   // Create our IOP/IOR.
--35f1 0004d055ffe40110138 Page 11 of Volume.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
8eb0c9 ¤   ¤   size = (PGPUInt16) pVrp->VRP_max_req_size +·
3e8f4a ¤   ¤   ¤   pVrp->VRP_max_sgd*sizeof(SGD);
d66590 ¤   ¤   offset = (PGPUInt16) pVrp->VRP_delta_to_ior;
86af5a
a66225 ¤   ¤   pIop = IspCreateIop(size, offset, ISP_M_FL_INTERRUPT_TIME);
7aaf5a
906561 ¤   ¤   if (!pIop)
1a9f03 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IorAllocationFailed);
ac9371 ¤   }
d5af5a
b42cea ¤   // Now we fill in the fields of our IOR structure prior to sending the
7c2081 ¤   // I/O request to the IOS subsystem.
bcaf5a
eb2361 ¤   if (derr.IsntError())
fac7a1 ¤   {
4ef8e7 ¤   ¤   pIor = &pIop->IOP_ior;
7ef7f5 ¤   ¤   pIop->IOP_timer_orig = pIop->IOP_timer = kDefaultIopTimeOut;
7aaf5a
1a8345 ¤   ¤   mVolumeReq.pIor = pIor;
6aaf5a
a47e53 ¤   ¤   pIor->IOR_next¤ ¤   = NULL;¤¤   ¤   ¤   ¤   // must be NULL
277a89 ¤   ¤   pIor->IOR_func¤ ¤   = func;¤¤   ¤   ¤   ¤   // IOR_READ or IOR_WRITE
df63d6 ¤   ¤   pIor->IOR_status¤   = 0;¤   ¤   ¤   ¤   ¤   // result code goes here
4159ed ¤   ¤   pIor->IOR_flags¤¤   = IORF_VERSION_002¤ ¤   // means we are using IOR
672e8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   | IORF_HIGH_PRIORITY¤   ¤   ¤   // high priority
da0143 ¤   ¤   ¤   ¤   ¤   ¤   ¤   | IORF_LOGICAL_START_SECTOR¤¤   // in partition
327da2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   | IORF_DOUBLE_BUFFER;¤  ¤   ¤   // copy buffer
65af5a
001f28 ¤   ¤   // We have to set the start address, transfer count, and buffer fields
8a1359 ¤   ¤   // with the passed information.
4faf5a
eda172 ¤   ¤   pIor->IOR_start_addr[0]¤¤   = GetLowDWord(pos);¤¤   // low sector
d431a9 ¤   ¤   pIor->IOR_start_addr[1]¤¤   = GetHighDWord(pos);¤   // high sector
ed479b ¤   ¤   pIor->IOR_xfer_count¤   ¤   = nBlocks;¤ ¤   ¤   ¤   // # secs
20fb62 ¤   ¤   pIor->IOR_buffer_ptr¤   ¤   = (PGPUInt32) buf;¤ ¤   // buffer
409438 ¤   ¤   pIor->IOR_private_client¤   = kPGPdiskIopMagic;¤¤   // comes from us
c39480 ¤   ¤   pIor->IOR_req_vol_handle¤   = (PGPUInt32) pVrp;¤¤   // vrp pointer
6d0dc0 ¤   ¤   pIor->IOR_sgd_lin_phys¤ ¤   = (PGPUInt32) (pIor + 1);¤  // SGDs here
ab896f ¤   ¤   pIor->IOR_num_sgds¤ ¤   ¤   = 0;¤   ¤   ¤   ¤   ¤   // system fills in
bedb03 ¤   ¤   pIor->IOR_vol_designtr¤ ¤   = GetDrive();
1faf5a
949ead ¤   ¤   // Initialize the callback info.
1feab1 ¤   ¤   if (useAsync)
f75b34 ¤   ¤   {
c43c08 ¤   ¤   ¤   pIor->IOR_callback = (CMDCPLT) VolumeCallback;
8a91c4 ¤   ¤   ¤   pIor->IOR_req_req_handle = (PGPUInt32) &mVolumeReq.downInfo;
4b0fe4 ¤   ¤   }
930e1d ¤   ¤   else
c65b34 ¤   ¤   {
5a932f ¤   ¤   ¤   pIor->IOR_flags |= IORF_SYNC_COMMAND;
21b1b7 ¤   ¤   ¤   pIor->IOR_callback = NULL;
2d0fe4 ¤   ¤   }
8caf5a
21e2f4 ¤   ¤   // The IlbIoCriteria routine must be run on the IOR in order to let
df2f26 ¤   ¤   // the system massage some of the fields in the IOR into a form that
a93530 ¤   ¤   // it likes.
65af5a
ad0566 ¤   ¤   if (!IlbIoCriteria(pIor))
10f4c8 ¤   ¤   ¤   DebugOut("PGPdisk: IlbIoCriteria in DiskAccess failed");
efaf5a
76376f ¤   ¤   DebugOut(
5817ed ¤   ¤   ¤   "PGPdisk: Vol Access IOR %X func %u pos %u nBlocks %u drive %u",·
f7ac63 ¤   ¤   ¤   pIor, func, (PGPUInt32) pos, nBlocks, GetDrive());
1baf5a
992920 ¤   ¤   // Send the request to the IOS for processing synchronously.
e6401f ¤   ¤   __asm push edi
456dd0 ¤   ¤   IOS_SendCommand(pIor, mPDcb);
110350 ¤   ¤   __asm pop edi
f4af5a
4d23c0 ¤   ¤   DebugOut("PGPdisk: Exiting Vol Access IOR %X", pIor);
--9c18 00026214de540110138 Page 12 of Volume.cpp
a19371 ¤   }
93af5a
dc172d ¤   // If we are sync and called down the IOP we need to cleanup now
b65be6 ¤   // since there is no callback.
c4af5a
242361 ¤   if (derr.IsntError())
31c7a1 ¤   {
18416b ¤   ¤   if (!useAsync)
0e5b34 ¤   ¤   {
4c3b8b ¤   ¤   ¤   derr = CleanUpRequest();¤   // extract derr from IOR
834fde ¤   ¤   ¤   mVolumeReq.isInUse = FALSE;
4a0fe4 ¤   ¤   }
0d9371 ¤   }
12af5a
b42332 ¤   // If an error calling down the IOP, we need to callback if we were
21c8bc ¤   // called async.
82af5a
054bb3 ¤   if (derr.IsError())
7cc7a1 ¤   {
c8eab1 ¤   ¤   if (useAsync)
385b34 ¤   ¤   {
0b834b ¤   ¤   ¤   CleanUpRequest();
01c5dd ¤   ¤   ¤   ScheduleAsyncCallback(derr);
7a0fe4 ¤   ¤   }
f99371 ¤   }
2caf5a
1033e3 ¤   return derr;
32efe6 }
2daf5a
55d6f2 // CleanUpRequest performs housekeeping after a request has been completed.
c7af5a
0b2292 DualErr·
c4cfac Volume::CleanUpRequest()
9fbb36 {
ab945d ¤   DualErr¤derr;
58b910 ¤   PIOR¤   pIor;
04af5a
998df1 ¤   pgpAssert(mVolumeReq.isInUse);
879de3 ¤   pIor = mVolumeReq.pIor;
59af5a
dde947 ¤   // Convert possible error value to Windows standard.
8d729c ¤   if (pIor->IOR_status >= IORS_ERROR_DESIGNTR)
8fc7a1 ¤   {
4f6e77 ¤   ¤   if (pIor->IOR_func == IOR_READ)
915b34 ¤   ¤   {
055a1b ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IorReadFailure,·
8ba3af ¤   ¤   ¤   ¤   IOSMapIORSToI21(pIor->IOR_status));
d80fe4 ¤   ¤   }
6c0e1d ¤   ¤   else
bf5b34 ¤   ¤   {
81ca53 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IorWriteFailure,·
aea3af ¤   ¤   ¤   ¤   IOSMapIORSToI21(pIor->IOR_status));
810fe4 ¤   ¤   }
7e9371 ¤   }
c8af5a
116b56 ¤   // De-allocate the IOR if one was allocated.
1eba13 ¤   if (pIor)
89c7a1 ¤   {
f6d2ac ¤   ¤   PGPUInt16¤  offset;
d23d92 ¤   ¤   PVRP¤   ¤   pVrp;
54af5a
ba705a ¤   ¤   pVrp = (PVRP) mPDcb->DCB_cmn.DCB_vrp_ptr;
fb1b52 ¤   ¤
e0f885 ¤   ¤   // Hopefully our volume didn't go away.
ff1c8c ¤   ¤   if (pVrp)
055b34 ¤   ¤   {
d2a6f5 ¤   ¤   ¤   pgpAssertAddrValid(pVrp, VRP);
68af5a
b30aa3 ¤   ¤   ¤   offset = (PGPUInt16) pVrp->VRP_delta_to_ior;
866e9a ¤   ¤   ¤   IspDeallocMem((PGPUInt8 *) pIor - offset);
1a0fe4 ¤   ¤   }
269371 ¤   }
--0c29 0001f26ac0e40110138 Page 13 of Volume.cpp
e0af5a
cf33e3 ¤   return derr;
f5efe6 }
08af5a
5dde0e // VolumeCallback is called by the system after it has finished processing
c7cf1c // the IOP we gave it. We extract the address of the Volume object in question
387269 // and pass the callback to it.
adaf5a
71c823 void·
5607cb Volume::VolumeCallback(GenericCallbackInfo *downInfo)
79bb36 {
ec719c ¤   Volume *pVol;
4caf5a
feac07 ¤   pgpAssertAddrValid(downInfo, GenericCallbackInfo);
eeaf5a
10a2ae ¤   pVol = (Volume *) downInfo->refData[0];
7673ec ¤   pgpAssertAddrValid(pVol, Volume);
22af5a
2431c2 ¤   pVol->VolumeCallbackAux();
e3efe6 }
0eaf5a
bc13f0 // VolumeCallbackAux is called by the static callback function
9b87e8 // 'VolumeCallback' so we don't have to type 'pVol' before every reference to
765486 // an object member or method. (Not needed here but coded so we are parallel
b8e0e6 // to higher classes such as FatParser and PGPdisk in this regard.)
76af5a
e3c823 void·
d4985a Volume::VolumeCallbackAux()
9dbb36 {
f37d36 ¤   DualErr derr;
e1af5a
bf8df1 ¤   pgpAssert(mVolumeReq.isInUse);
3faf5a
238604 ¤   // Cleanup.
d8d1f7 ¤   derr = CleanUpRequest();
46af5a
81e8a5 ¤   // Call up.
03fd58 ¤   ScheduleAsyncCallback(derr);
d8efe6 }
3eaf5a
b4f5b3 // ScheduleAsyncCallback schedules a windows event that calls our function
80e5b4 // that will call the asynchronous request up.
43af5a
a9c823 void·
cfb5cc Volume::ScheduleAsyncCallback(DualErr derr)
81bb36 {
d78883 ¤   static RestrictedEvent_THUNK callbackThunk;
7aaf5a
dd9d50 ¤   pgpAssertAddrValid(mVolumeReq.upInfo, GenericCallbackInfo);
5dc98c ¤   mVolumeReq.upInfo->derr = derr;
b5af5a
f45424 ¤   Call_Restricted_Event(0, NULL, PEF_ALWAYS_SCHED, (PVOID) this,·
876ef4 ¤   ¤   AsyncExecuteCallback, 0, &callbackThunk);
fbefe6 }
65af5a
501652 // AsyncExecuteCallback was scheduled by 'ScheduleAsyncCallback' for the
5b950e // purpose of calling back up the asynchronous request we received.
c2af5a
5c0930 VOID __stdcall·
c930f9 Volume::AsyncExecuteCallback(
2dbfb0 ¤   VMHANDLE¤   ¤   hVM,·
08518d ¤   THREADHANDLE¤   hThread,·
06d6c4 ¤   PVOID¤  ¤   ¤   Refdata,·
5d58d6 ¤   PCLIENT_STRUCT¤ pRegs)
e3bb36 {
56719c ¤   Volume *pVol;
3baf5a
46c77d ¤   pVol = (Volume *) Refdata;
f373ec ¤   pgpAssertAddrValid(pVol, Volume);
ffaf5a
edb678 ¤   pgpAssert(pVol->mVolumeReq.isInUse);
1f5205 ¤   pVol->mVolumeReq.isInUse = FALSE;
--f153 0016afcf23740110138 Page 14 of Volume.cpp
e0af5a
c10a3e ¤   pgpAssertAddrValid(pVol->mVolumeReq.upInfo, GenericCallbackInfo);
bbae3f ¤   pVol->mVolumeReq.upInfo->callback(pVol->mVolumeReq.upInfo);
6aefe6 }
--15ab 00028c8385e40110139 Page 1 of Volume.h
541bc3 //////////////////////////////////////////////////////////////////////////////
54d7ee // Volume.h
2f465d //
5be0c7 // Declaration of class Volume.
921bc3 //////////////////////////////////////////////////////////////////////////////
c9af5a
4e4d29 // $Id: Volume.h,v 1.1.2.13 1998/07/06 08:58:29 nryan Exp $
61af5a
27cbce // Copyright (C) 1998 by Network Associates, Inc.
2d71ae // All rights reserved.
d4af5a
5346c3 #ifndef Included_Volume_h¤  // [
4dce0d #define Included_Volume_h
01af5a
533a85 #include "DualErr.h"
f93db7 #include "FatUtils.h"
bc555c #include "GenericCallback.h"
9aaf5a
10af5a
6109b7 ////////////
a3e738 // Constants
6b09b7 ////////////
eeaf5a
0fc9c4 const PGPUInt32¤kDefaultIopTimeOut¤ = 15;¤  ¤   ¤   // IOP time out in secs
aeae0d const PGPUInt32¤kPGPdiskIopMagic¤   = 0xAB42F61D;¤  // IOP came from us
35af5a
c6af5a
6cd557 ////////
6602c9 // Types
00d557 ////////
f9af5a
093f12 #define IOR_event _ureq._IOR_requestor_usage[0]
5faf5a
601b9d // VolumeRequestInfo holds info for a specific request.
acaf5a
07c492 typedef struct VolumeRequestInfo
05bb36 {
03c7f3 ¤   PGPBoolean isInUse;¤¤   // this object in use?
01af5a
50f214 ¤   GenericCallbackInfo¤downInfo;¤  // info for call down
b96a97 ¤   GenericCallbackInfo¤*upInfo;¤   // info for call up
6baf5a
f72ad7 ¤   PIOR pIor;¤ ¤   ¤   ¤   // IOR
d7af5a
15f515 } VolumeRequestInfo;
64af5a
58af5a
467606 ///////////////
826d45 // Class Volume
ec7606 ///////////////
acaf5a
5f6271 // Class Volume can be used to represent any local volume on the system. If
4c2bc5 // the volume is not already mounted, it cannot be mounted until a DCB is
ce369c // attached to it (DCBs are allocated for the driver by the system upon
21f1ae // startup). It does no DCB initialization itself; that is for the client
452b99 // or for derived classes to do.
80af5a
9038b0 class Volume
a9bb36 {
9e5ed4 public:
400caa ¤   ¤   ¤   ¤   Volume();
a53b86 ¤   virtual¤¤   ~Volume();
e0af5a
b80ab3 ¤   PGPBoolean¤ Mounted();
ce8e1a ¤   PGPBoolean¤ Unmounted();
0120d5 ¤   PGPBoolean¤ AttachedToLocalVolume();
aafa2a ¤   PGPBoolean¤ HasOpenFiles();
1daf5a
78c569 ¤   PGPBoolean¤ LockedForReadWrite();
701a7d ¤   PGPBoolean¤ LockedForFormat();
20af5a
28a804 ¤   PGPUInt8¤   GetDrive();
--72dc 00141c2c8b740110139 Page 2 of Volume.h
413431 ¤   PGPUInt16¤  GetBlockSize();
2bbda3 ¤   PGPUInt64¤  GetTotalBlocks();
706517 ¤   PDCB¤   ¤   GetDcb();
d4af5a
7c2e3b ¤   DualErr¤¤   GetDevParams16(DevParams16 *dp16);
dcff34 ¤   DualErr¤¤   GetDevParams32(DevParams32 *dp32);
752164 ¤   DualErr¤¤   GetMediaId(MID *pMid);
18409e ¤   DualErr¤¤   GetFsId(FileSysId *fsId);
ccaf5a
b7a28f ¤   DualErr¤¤   AttachLocalVolume(PGPUInt8 drive);
696b08 ¤   void¤   ¤   DetachLocalVolume();
1faf5a
d9d637 ¤   DualErr¤¤   Mount(PDCB pDcb, PGPUInt8 drive = kInvalidDrive);
7d499b ¤   DualErr¤¤   Unmount(PGPBoolean isThisEmergency = FALSE);
3daf5a
0f43eb ¤   DualErr¤¤   LockVolumeForReadWrite();
f9a9b4 ¤   DualErr¤¤   LockVolumeForFormat();
073e26 ¤   DualErr¤¤   UnlockVolume();
75af5a
80aabb ¤   DualErr¤¤   Read(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks,·
c4aed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
ff1670 ¤   DualErr¤¤   Write(PGPUInt8 *buf, PGPUInt64 pos, PGPUInt32 nBlocks,·
3faed2 ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
3caf5a
35a2d3 protected:
986c3b ¤   PDCB mPDcb;¤¤   // pointer to the DCB for the volume
e4af5a
e40fb9 private:
686d60 ¤   enum MountState¤{kVol_Mounted, kVol_Unmounted};
0a2ca6 ¤   enum LockState¤ {kLock_None, kLock_ReadWrite, kLock_Format};
10af5a
0c8899 ¤   MountState¤ ¤   ¤   mMountState;¤   // holds mount status of volume
1d55a5 ¤   LockState¤  ¤   ¤   mLockState;¤¤   // lock status of the volume
0ccc12 ¤   PGPUInt8¤   ¤   ¤   mDrive;¤¤   ¤   // mounted drive number
d5af5a
213aee ¤   PGPBoolean¤ ¤   ¤   mAttachedToLocalVol;¤   // attached to a local volume?
83ebc7 ¤   PGPUInt8¤   ¤   ¤   *mBBlock;¤  ¤   // boot block buffer for DevParams
23af5a
8ca7d7 ¤   VolumeRequestInfo¤  mVolumeReq;¤¤   // request info
62af5a
beb79d ¤   DualErr¤¤   ¤   ¤   ¤   InitMountedVars(PGPUInt8 drive, PDCB pDcb);
122be6 ¤   void¤   ¤   ¤   ¤   ¤   CleanUpMountedVars();
5faf5a
72cd9e ¤   DualErr¤¤   ¤   ¤   ¤   DiskAccess(PGPUInt16 func, PGPUInt8 *buf,·
9836fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt64 pos, PGPUInt32 nBlocks,·
0cd80b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GenericCallbackInfo *upInfo = NULL);
2baf5a
c89b44 ¤   DualErr¤¤   ¤   ¤   ¤   CleanUpRequest();
28af5a
c1ffa1 ¤   static void¤¤   ¤   ¤   VolumeCallback(GenericCallbackInfo *downInfo);
08a123 ¤   void¤   ¤   ¤   ¤   ¤   VolumeCallbackAux();
6faf5a
b0c4b4 ¤   void¤   ¤   ¤   ¤   ¤   ScheduleAsyncCallback(
cbeb7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DualErr derr = DualErr::NoError);
acb204 ¤   static VOID __stdcall¤  AsyncExecuteCallback(VMHANDLE hVM,·
78f733 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   THREADHANDLE hThread, PVOID Refdata,·
436ccc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PCLIENT_STRUCT pRegs);
9c82f7 };
68af5a
41ac71 #endif¤ // ] Included_Volume_h
--b532 00006c7db164011013a Page 1 of Wrappers.h
541bc3 //////////////////////////////////////////////////////////////////////////////
3bc7ac // Wrappers.h
ba465d //
6e8672 // Wrappers for many IOS and ILB functions used by the driver.
3b1bc3 //////////////////////////////////////////////////////////////////////////////
45af5a
a73ad8 // $Id: Wrappers.h,v 1.1.2.3.2.1 1998/10/05 18:28:24 nryan Exp $
6faf5a
6ccbce // Copyright (C) 1998 by Network Associates, Inc.
8571ae // All rights reserved.
fcaf5a
3f5285 #ifndef Included_Wrappers_h¤// [
e24dae #define Included_Wrappers_h
03af5a
19c7c7 #include <ddb.h>
c2af5a
23af5a
1f09b7 ////////////
7ae738 // Constants
a109b7 ////////////
a2af5a
0c79f3 #define¤VXDINLINE¤  static __inline
2a8417 #define¤NAKED¤  ¤   __declspec(naked)
2eaf5a
eaaf5a
dbd43e /////////
19596b // Macros
8bd43e /////////
4daf5a
1dc8ff #define FIELDOFFSET(type, field) ((DWORD)(&((type *)0)->field))
40af5a
47af5a
cb2af8 //////////
c8647f // Externs
da2af8 //////////
2caf5a
e686fa extern ILB PGPDISK_Ilb;¤¤   ¤   // the driver's Ilb
c2af5a
19af5a
01d557 ////////
b702c9 // Types
76d557 ////////
f2af5a
0934b7 typedef IOP *PIOP;
ebaf5a
f0af5a
c5cbee ///////////////////////////////////
535972 // Wrappers around ILB system calls
f0cbee ///////////////////////////////////
feaf5a
9112e9 // IlbDequeueIop pops the next IOP off of the IOP queue for the given DCB and
f7b2a1 // returns it.
20af5a
2a0e05 VXDINLINE·
ea2fb6 PIOP·
36e9de IlbDequeueIop(PDCB pDcb)
a8bb36 {
64e71c ¤   PIOP pIop;
f5af5a
e96e77 ¤   __asm
fbc7a1 ¤   {
6d0523 ¤   ¤   push pDcb
396d53 ¤   ¤   call [PGPDISK_Ilb.ILB_dequeue_iop]
9dc177 ¤   ¤   add esp, 4
b53114 ¤   ¤   mov pIop, eax
359371 ¤   }
28af5a
9f8bc8 ¤   return pIop;
21efe6 }
03af5a
4ee07d // IlbEnqueueIop places the given IOP into the IOS IOP queue for later retrieval
0613c9 // and processing. Each DCB has a different queue, of course.
--f2d6 000cd8228374011013a Page 2 of Wrappers.h
e0af5a
1a0e05 VXDINLINE·
82a1ba VOID·
fe290c IlbEnqueueIop(PIOP pIop, PDCB pDcb)
1abb36 {
8d6e77 ¤   __asm
dfc7a1 ¤   {
d30523 ¤   ¤   push pDcb
568d2e ¤   ¤   push pIop
eee5fc ¤   ¤   call [PGPDISK_Ilb.ILB_enqueue_iop]
5c68d7 ¤   ¤   add esp, 8
029371 ¤   }
45efe6 }
27af5a
4191d2 // IlbInternalRequest is like IOS_SendCommand except it is meant for use by
b807fd // IOS layer drivers.
4caf5a
c20e05 VXDINLINE·
35a1ba VOID·
315386 IlbInternalRequest(PIOP pIop, PDCB pDcb, void *calldown)
cdbb36 {
376e77 ¤   __asm
89c7a1 ¤   {
4bd9d8 ¤   ¤   mov edi, pIop
682f0d ¤   ¤   mov ebx, pDcb
bc401d ¤   ¤   mov edx, calldown
2f9371 ¤   }
70af5a
a1b208 ¤   (* (VOID (*)()) PGPDISK_Ilb.ILB_internal_request)();
b2efe6 }
b4af5a
f5505f // IlbIntIoCriteria prepares the given IOR before it should be given to the
93297b // IOS internal request routing for processing.
b4af5a
1f0e05 VXDINLINE·
e577be PGPBoolean·
a5ace7 IlbIntIoCriteria(PIOP pIop)
15bb36 {
26ea2d ¤   PGPUInt32 result;
f4af5a
d76e77 ¤   __asm
60c7a1 ¤   {
c38d2e ¤   ¤   push pIop
c8e0b5 ¤   ¤   call [PGPDISK_Ilb.ILB_int_io_criteria_rtn]
01c177 ¤   ¤   add esp, 4
d4c9dd ¤   ¤   mov result, eax
fb9371 ¤   }
d6af5a
7f553e ¤   return (result == 0);
8aefe6 }
2daf5a
96a376 // IlbIoCriteria prepares the given IOR before it should be given to the IOS
06daeb // for processing.
f1af5a
e00e05 VXDINLINE·
b777be PGPBoolean·
ba11b8 IlbIoCriteria(PIOR pIor)
03bb36 {
f4ea2d ¤   PGPUInt32 result;
4faf5a
746e77 ¤   __asm
21c7a1 ¤   {
29be9e ¤   ¤   push pIor
4e0675 ¤   ¤   call [PGPDISK_Ilb.ILB_io_criteria_rtn]
91c177 ¤   ¤   add esp, 4
5ec9dd ¤   ¤   mov result, eax
bf9371 ¤   }
90af5a
e7553e ¤   return (result == 0);
75efe6 }
72af5a
cd4fec // IlbService calls the driver's ILB service routine with the specified ISP
--1dbd 000bcdbfe904011013a Page 3 of Wrappers.h
989705 // packet, which defines a request for a certain service from the system.
e4af5a
840e05 VXDINLINE·
aa1b0b PGPUInt32·
35e7de IlbService(PISP pIsp)
41bb36 {
c7ea2d ¤   PGPUInt32 result;
1baf5a
0e6e77 ¤   __asm
a3c7a1 ¤   {
bead18 ¤   ¤   push pIsp
96c66a ¤   ¤   call [PGPDISK_Ilb.ILB_service_rtn]
46c177 ¤   ¤   add esp, 4
00c9dd ¤   ¤   mov result, eax
5e9371 ¤   }
85af5a
3e5d73 ¤   return result;
73efe6 }
e1af5a
e10e05 VXDINLINE·
e9a1ba VOID·
53c205 IlbWait10thSec()
06bb36 {
ac66e6 ¤   __asm call [PGPDISK_Ilb.ILB_Wait_10th_Sec]
acefe6 }
16af5a
b9af5a
9bcbee ///////////////////////////////////
597ea3 // Wrappers around IRS system calls
63cbee ///////////////////////////////////
afaf5a
520f93 // IrsGetDriveInfo returns information about the specified drive.
ebaf5a
c40e05 VXDINLINE·
440e55 DWORD·
9c6000 IrsGetDriveInfo(PGPUInt8 drive)
33bb36 {
143bd6 ¤   IRS_drv_get irsDG;
c267c5 ¤
85f0e7 ¤   irsDG.IRS_func¤ ¤   = IRS_GET_DRVINFO;
b1a713 ¤   irsDG.IRS_result¤   = 0;
4a39e6 ¤   irsDG.IRS_DrvLetter¤= drive + 'A';
de2815 ¤   irsDG.IRS_DrvFlags¤ = NULL;
8caf5a
8dc81c ¤   IOS_Requestor_Service((PIRS) &irsDG);
2c67c5 ¤
583175 ¤   if (irsDG.IRS_result != 0)
3a093f ¤   ¤   return 0xFFFFFFFF;
ca0e24 ¤   else
4cd961 ¤   ¤   return irsDG.IRS_DrvFlags;
d1efe6 }
8daf5a
ddaf5a
5fcbee ///////////////////////////////////
fb28cd // Wrappers around ISP system calls
86cbee ///////////////////////////////////
f2af5a
27bc20 // IspAssociateDcb associates the given DCB with the given drive number. This
0e8b1e // effectively mounts the DCB as the given drive number on the system.
4aaf5a
e00e05 VXDINLINE·
9077be PGPBoolean·
adc079 IspAssociateDcb(PDCB pDcb, PGPUInt8 drive, PGPUInt8 flags)
1dbb36 {
b82a21 ¤   ISP_dcb_associate ispDA;
b867c5 ¤
638e8e ¤   ispDA.ISP_d_a_hdr.ISP_func¤ = ISP_ASSOCIATE_DCB;
cc0811 ¤   ispDA.ISP_d_a_dcb¤  ¤   ¤   = (PDCB_COMMON) pDcb;
09be0b ¤   ispDA.ISP_d_a_drive¤¤   ¤   = drive;
9f897b ¤   ispDA.ISP_d_a_flags¤¤   ¤   = flags;
a567c5 ¤
bcdf93 ¤   IlbService((PISP) &ispDA);
--fb12 0008cef73194011013a Page 4 of Wrappers.h
9d96c4 ¤   return (ispDA.ISP_d_a_hdr.ISP_result == 0);
b0efe6 }
43af5a
b045c7 // IspCreateDdb creates the driver's DDB structure during IOS initialization.
dbaf5a
550e05 VXDINLINE·
5aa3fa PDDB·
7d8452 IspCreateDdb(PGPUInt16 size, PGPUInt8 flags)
08bb36 {
963867 ¤   ISP_ddb_create ispDC;
01af5a
94d93f ¤   ispDC.ISP_ddb_hdr.ISP_func¤ = ISP_CREATE_DDB;
928870 ¤   ispDC.ISP_ddb_size¤ ¤   ¤   = sizeof(IOSDDB);
3ad672 ¤   ispDC.ISP_ddb_flags¤¤   ¤   = flags;
4e67c5 ¤
ece6e5 ¤   IlbService((PISP) &ispDC);
fd3aa9 ¤   return (PDDB) ispDC.ISP_ddb_ptr;
90efe6 }
daaf5a
b7d063 // IspCreateIop allocates a new IOP/IOR structure.
3baf5a
a00e05 VXDINLINE·
2e2fb6 PIOP·
51d886 IspCreateIop(
d3cb4e ¤   PGPUInt16¤  size,·
7f2e94 ¤   PGPUInt32¤  delta,·
b75142 ¤   PGPUInt8¤   flags,·
49918e ¤   PIOP¤   ¤   pIop = NULL)
16bb36 {
706e4d ¤   ISP_IOP_alloc ispIA;
ecaf5a
450fab ¤   if (pIop)
2e7d61 ¤   ¤   pgpAssert(flags & ISP_M_FL_EXTERNAL_IOP == ISP_M_FL_EXTERNAL_IOP);
9867c5 ¤
72b26f ¤   ispIA.ISP_i_c_hdr.ISP_func¤ = ISP_CREATE_IOP;
302044 ¤   ispIA.ISP_IOP_size¤ ¤   ¤   = size;
319c0d ¤   ispIA.ISP_delta_to_ior¤ ¤   = delta;
227b7b ¤   ispIA.ISP_IOP_ptr¤  ¤   ¤   = (PGPUInt32) pIop;¤// for external allocation
b190e4 ¤   ispIA.ISP_i_c_flags¤¤   ¤   = flags;
5caf5a
aba3e7 ¤   IlbService((PISP) &ispIA);
a4af5a
e3a6ea ¤   if (ispIA.ISP_i_c_hdr.ISP_result == 0)
6fbe8e ¤   ¤   return (PIOP) (ispIA.ISP_IOP_ptr + delta - FIELDOFFSET(IOP, IOP_ior));
e00e24 ¤   else
af7ed2 ¤   ¤   return NULL;
30efe6 }
8daf5a
16cabf // IspDeallocMem deallocates memory allocated by the IOS.
f7af5a
f10e05 VXDINLINE·
8677be PGPBoolean·
9bf57b IspDeallocMem(void *pMem)
5abb36 {
5934db ¤   ISP_mem_dealloc ispMD;
a967c5 ¤
918609 ¤   ispMD.ISP_mem_da_hdr.ISP_func = ISP_DEALLOC_MEM;
151bde ¤   ispMD.ISP_mem_ptr_da = (ULONG) pMem;
86af5a
d8e0a0 ¤   IlbService((PISP) &ispMD);
d6dae7 ¤   return (ispMD.ISP_mem_da_hdr.ISP_result == 0);
93efe6 }
4eaf5a
effbf6 // IspDisassociateDcb disassociates the given drive letter from the mounted
495ce0 // DCB that describes the volume it is associated with.
39af5a
0a0e05 VXDINLINE·
cd77be PGPBoolean·
96125c IspDisassociateDcb(PGPUInt8 drive)
07bb36 {
3c5836 ¤   ISP_DISASSOC_DCB ispDD;
8caf5a
--ca3b 0005ebce32e4011013a Page 5 of Wrappers.h
d61ff1 ¤   ispDD.ISP_dis_dcb_hdr.ISP_func = ISP_DISASSOCIATE_DCB;
02fd5c ¤   ispDD.ISP_dis_dcb_drive = drive;
71af5a
74b1c4 ¤   IlbService((PISP) &ispDD);
6336d0 ¤   return (ispDD.ISP_dis_dcb_hdr.ISP_result == 0);
92efe6 }
3aaf5a
13ac91 // IspDriveLetterPick asks the system to pick and return a free drive letter
e85637 // that can be used for mounting.
dcaf5a
220e05 VXDINLINE·
aa671d PGPUInt8·
5f64df IspDriveLetterPick(PDCB pDcb, PGPUInt8 flags)
8bbb36 {
5224c6 ¤   ISP_pick_drive_letter ispPDL;
5467c5 ¤
7dc17d ¤   ispPDL.ISP_p_d_l_hdr.ISP_func¤  = ISP_DRIVE_LETTER_PICK;
871d61 ¤   ispPDL.ISP_p_d_l_pdcb¤  ¤   ¤   = pDcb;
958d38 ¤   ispPDL.ISP_p_d_l_flags¤ ¤   ¤   = flags;
e8af5a
ef153b ¤   IlbService((PISP) &ispPDL);
e7af5a
4eb0b4 ¤   if (ispPDL.ISP_p_d_l_hdr.ISP_result == 0)
3ebd4e ¤   ¤   return ispPDL.ISP_p_d_l_letter[0];
350e24 ¤   else
288cc5 ¤   ¤   return kInvalidDrive;
e4efe6 }
acaf5a
83452d // IspGetDcb will retrieve the logical DCB associated with a given drive #,
f72d22 // which must represent a mounted volume.
ddaf5a
cb0e05 VXDINLINE·
25f4db PDCB·
40bff9 IspGetDcb(PGPUInt8 drive)
e5bb36 {
2f0e9e ¤   ISP_dcb_get ispDG;
13af5a
97b77e ¤   ispDG.ISP_g_d_hdr.ISP_func = ISP_GET_DCB;
806ccd ¤   ispDG.ISP_g_d_drive = drive;
4baf5a
5f9409 ¤   IlbService((PISP) &ispDG);
60af5a
0eb626 ¤   if (ispDG.ISP_g_d_hdr.ISP_result == 0)
49feda ¤   ¤   return (PDCB) ispDG.ISP_g_d_dcb;
9f0e24 ¤   else
0f7ed2 ¤   ¤   return NULL;
dcefe6 }
04af5a
f79a1e // IspInsertCalldown inserts the driver into the I/O calldown table for the
aa7543 // given DCB.
a7af5a
1e0e05 VXDINLINE·
f877be PGPBoolean·
63d3bf IspInsertCalldown(
edd4a9 ¤   PDCB¤   ¤   pDcb,·
ef1bf6 ¤   void¤   ¤   *req,·
912d7b ¤   PDDB¤   ¤   ddb,·
ce6928 ¤   PGPUInt16¤  expan,·
890246 ¤   PGPUInt32¤  flags,·
64485f ¤   PGPUInt8¤   lgn)
70bb36 {
ca99fa ¤   ISP_calldown_insert ispCI;
14af5a
3a4554 ¤   pgpFillMemory(&ispCI, sizeof(ispCI), NULL);
f6af5a
e37dc8 ¤   ispCI.ISP_i_cd_hdr.ISP_func¤= ISP_INSERT_CALLDOWN;
f18713 ¤   ispCI.ISP_i_cd_dcb¤ ¤   ¤   = (PDCB_COMMON) pDcb;
422ae3 ¤   ispCI.ISP_i_cd_req¤ ¤   ¤   = req;¤ ¤
83d3b5 ¤   ispCI.ISP_i_cd_ddb¤ ¤   ¤   = ddb;¤ ¤
3f1abf ¤   ispCI.ISP_i_cd_expan_len¤   = expan;
b9d09e ¤   ispCI.ISP_i_cd_flags¤   ¤   = flags;¤
5e94a8 ¤   ispCI.ISP_i_cd_lgn¤ ¤   ¤   = lgn;¤ ¤
--98b9 0001c77c4264011013a Page 6 of Wrappers.h
e0af5a
ce0a97 ¤   IlbService((PISP) &ispCI);
2daffa ¤   return (!ispCI.ISP_i_cd_hdr.ISP_result);
5eefe6 }
75af5a
d04e46 // IspDeallocMem allocates memory from the IOS.
5daf5a
9f0e05 VXDINLINE·
1421f6 void *·
41d68f IspAllocMem(PGPUInt16 memsize, PGPUInt8 flags)
8dbb36 {
069c77 ¤   ISP_mem_alloc ispMA;
ecaf5a
d91c86 ¤   ispMA.ISP_mem_a_hdr.ISP_func¤   = ISP_ALLOC_MEM;
c1e575 ¤   ispMA.ISP_mem_size¤ ¤   ¤   ¤   = memsize;
cb536a ¤   ispMA.ISP_mem_type¤ ¤   ¤   ¤   = NULL;
c7675c ¤   ispMA.ISP_mem_flags¤¤   ¤   ¤   = flags;
7faf5a
9f8ef7 ¤   IlbService((PISP) &ispMA);
5a4849 ¤   return (void *) (ispMA.ISP_mem_ptr);
feefe6 }
f3af5a
81af5a
bdb474 //////////////////////////////
580db5 // Small IOS utility functions
3db474 //////////////////////////////
d8af5a
1c86f2 /// ExtractBlockSize returns the block size of the volume describe by the DCB.
b1af5a
6fc85e inline·
27411c PGPUInt16·
5f6957 ExtractBlockSize(PDCB pDcb)
53bb36 {
1686c8 ¤   return (1 << pDcb->DCB_cmn.DCB_apparent_blk_shift);
e3efe6 }
e0af5a
2408f5 // BusID returns the bus ID of the DCB.
13af5a
3fc85e inline·
6b671d PGPUInt8·
f655fc ExtractBusID(PDCB pDcb)
b9bb36 {
aa74c4 ¤   return pDcb->DCB_unit_on_ctl;
baefe6 }
7baf5a
c91620 // Drive returns the drive number associated with a DCB.
6daf5a
b9c85e inline·
67671d PGPUInt8·
3cb8de ExtractDrive(PDCB pDcb)
7cbb36 {
1773de ¤   return pDcb->DCB_cmn.DCB_drive_lttr_equiv;
9befe6 }
79af5a
a9b910 // InBytes returns TRUE if the IOR's transfer length data field is in bytes,
9c61a7 // FALSE if it's in sectors.
d1af5a
ecc85e inline·
7e77be PGPBoolean·
0c36ce IsInBytes(PIOR pIor)
8ebb36 {
5382dc ¤   return (pIor->IOR_flags & IORF_CHAR_COMMAND ? TRUE : FALSE);
e0efe6 }
a3af5a
812caa // IsPhysical returns TRUE if the DCB describes a physical drive, FALSE
134da2 // otherwise.
2aaf5a
52c85e inline·
fd77be PGPBoolean·
85455f IsPhysical(PDCB pDcb)
6bbb36 {
1c2f84 ¤   return (pDcb->DCB_cmn.DCB_device_flags & DCB_DEV_PHYSICAL ? TRUE : FALSE);
--314d 00131e4c09f4011013a Page 7 of Wrappers.h
7aefe6 }
46af5a
7d4d56 // ScatterGather returns TRUE if the IOR uses scatter/gather blocks in its
5e9253 // request.
e1af5a
83c85e inline·
f377be PGPBoolean·
86198c IsScatterGather(PIOR pIor)
4dbb36 {
2061f5 ¤   return (pIor->IOR_flags & IORF_SCATTER_GATHER ? TRUE : FALSE);
9defe6 }
ebaf5a
3154de #endif¤ // ] Included_Wrappers_h
--00ee 001cb8553e04011013b Page 1 of PGPdiskInstallHelper.def
8abcfc LIBRARY¤¤   PGPdskIH
5eb0cd DESCRIPTION¤'PGPdisk Install Helper'
baaf5a
b1ef2b EXPORTS
9dca57 ¤   KillPGPdiskResident¤¤   @1 PRIVATE¤ ¤   ; Kill PGPdiskResident.exe.
9b5890 ¤   PGPdiskCleanup¤ ¤   ¤   @2 PRIVATE¤ ¤   ; Cleanup PGPdisk reg entries.
48bbbd ¤   AreAnyPGPdisksMounted¤  @3 PRIVATE¤ ¤   ; Are any PGPdisks mounted?
2d8bc8 ¤   IsVolumeAPGPdisk¤   ¤   @4 PRIVATE¤ ¤   ; Is the drive a PGPdisk?
cbe283 ¤   UnmountAllPGPdisks¤ ¤   @5 PRIVATE¤ ¤   ; Unmount all PGPdisks.
--cb0a 001876450554011013c Page 1 of PGPdiskInstallHelper.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
2229f7 #include "Source\Resource.h"
28af5a
2be1bf #define APSTUDIO_READONLY_SYMBOLS
196c0e /////////////////////////////////////////////////////////////////////////////
2f465d //
d00131 // Generated from the TEXTINCLUDE 2 resource.
19465d //
58897a #include "afxres.h"
2daf5a
8d6c0e /////////////////////////////////////////////////////////////////////////////
287b93 #undef APSTUDIO_READONLY_SYMBOLS
ceaf5a
cb6c0e /////////////////////////////////////////////////////////////////////////////
04f930 // English (U.S.) resources
2baf5a
cd1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
d4ec08 #ifdef _WIN32
ebe912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
e59c1c #pragma code_page(1252)
e21f8e #endif //_WIN32
e5af5a
9cf860 #ifdef APSTUDIO_INVOKED
5d6c0e /////////////////////////////////////////////////////////////////////////////
12465d //
895733 // TEXTINCLUDE
91465d //
e0af5a
ea86ef 1 TEXTINCLUDE DISCARDABLE·
414523 BEGIN
b1df56 ····"Source\\Resource.h\0"
6ae0d1 END
a4af5a
417037 2 TEXTINCLUDE DISCARDABLE·
1b4523 BEGIN
01eb23 ····"#include ""afxres.h""\r\n"
f8db5c ····"\0"
f6e0d1 END
f1af5a
ce227f 3 TEXTINCLUDE DISCARDABLE·
c74523 BEGIN
76e8df ····"#include ""PGPdiskInstallHelperVer.rc""\0"
a5e0d1 END
d3af5a
6a69ab #endif ···// APSTUDIO_INVOKED
45af5a
3b1b3a #endif ···// English (U.S.) resources
b46c0e /////////////////////////////////////////////////////////////////////////////
c3af5a
09af5a
78af5a
64ce8c #ifndef APSTUDIO_INVOKED
736c0e /////////////////////////////////////////////////////////////////////////////
c1465d //
028464 // Generated from the TEXTINCLUDE 3 resource.
47465d //
347e8f #include "PGPdiskInstallHelperVer.rc"
276c0e /////////////////////////////////////////////////////////////////////////////
6c8072 #endif ···// not APSTUDIO_INVOKED
87af5a
--c139 001c798580d4011013d Page 1 of PGPdiskInstallHelperVer.rc
b3eddb // VERSIONINFO structure which automatically include version
f014b6 // string from PGPdiskVersion.h
a6465d //
ed0380 #include <winver.h>
7b5a72 #include "..\Shared\PGPdiskVersion.h"
2aaf5a
016c0e /////////////////////////////////////////////////////////////////////////////
64465d //
29c5f2 // Version
f4465d //
5faf5a
0a8df2 VS_VERSION_INFO VERSIONINFO
e75e85 ·FILEVERSION kPGPdiskFileVerData
e16589 ·PRODUCTVERSION kPGPdiskProductVerData
29a381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
4b1f29 #ifdef _DEBUG
637c0e ·FILEFLAGS VS_FF_DEBUG
6cdb21 #else
db12ca ·FILEFLAGS 0x0L
e57454 #endif
e003bb ·FILEOS VOS__WINDOWS32
1b5212 ·FILETYPE VFT_DLL
f87247 ·FILESUBTYPE VFT2_UNKNOWN
844523 BEGIN
a32c72 ····BLOCK "StringFileInfo"
445574 ····BEGIN
6d70ac ········BLOCK "040904b0"
3a52d6 ········BEGIN
74f777 ············VALUE "CompanyName", kPGPdiskCompanyName
b97de1 ············VALUE "FileDescription", "PGPdisk Install Helper DLL\0"
b7126d ············VALUE "FileVersion", kPGPdiskFileVerString
e38247 ············VALUE "InternalName", "PGPdskIH.dll\0"
61f2bf ············VALUE "LegalCopyright", kPGPdiskCopyright
b855d7 ············VALUE "OriginalFilename", "PGPdskIH.dll\0"
c61fa9 ············VALUE "ProductName", kPGPdiskProductVerName
807b64 ············VALUE "ProductVersion", kPGPdiskProductVerString
20f37f ········END
517d01 ····END
e426ab ····BLOCK "VarFileInfo"
c85574 ····BEGIN
304b11 ········VALUE "Translation", 0x409, 1200
eb7d01 ····END
c7e0d1 END
--999c 0007eefdd344011013e Page 1 of CPGPdiskInstallHelperDll.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
cc3416 // CPGPdiskInstallHelperDll.cpp
00465d //
5f2b16 // Helper functions called by the PGPdisk installer.
d61bc3 //////////////////////////////////////////////////////////////////////////////
cfaf5a
b5bb6e // $Id: CPGPdiskInstallHelperDll.cpp,v 1.2.2.13 1998/07/30 00:50:25 nryan Exp $
84af5a
bbcbce // Copyright (C) 1998 by Network Associates, Inc.
e071ae // All rights reserved.
46af5a
029e12 #include "StdAfx.h"
6aaf5a
9f9bcf #include "Required.h"
40af5a
65ac00 #include "DriverComm.h"
117efd #include "LinkResolution.h"
5a0092 #include "Packets.h"
b5babe #include "PGPdiskRegistry.h"
c3cd22 #include "PGPdiskResidentDefines.h"
306673 #include "SharedMemory.h"
62bfe9 #include "UtilityFunctions.h"
69dd74 #include "WindowsVersion.h"
9caf5a
7a28ba #include "CPGPdiskInstallHelperDll.h"
43af5a
41af5a
3b09b7 ////////////
c8e738 // Constants
0809b7 ////////////
7daf5a
f57c95 // Data for spurious keys and values that need cleaning up.
e5af5a
f6b44e const HKEY¤ ¤   kRegistrySpurious1Root¤ ¤   ¤   = HKEY_LOCAL_MACHINE;
92d8fb static LPCSTR¤  kRegistrySpurious1Section¤  ¤   = "Enum\\ESDI";
2185f3 static LPCSTR¤  kRegistrySpurious1SubkeyMatch¤  = "PGPDISK";
faaf5a
ea72be const HKEY¤ ¤   kRegistrySpurious2Root¤ ¤   ¤   = HKEY_LOCAL_MACHINE;
c8afcb static LPCSTR¤  kRegistrySpurious2Section¤  ¤   =·
6001a2 ¤   "System\\CurrentControlSet\\Control\\ASD\\Prob";
864739 static LPCSTR¤  kRegistrySpurious2ValueMatch¤   = "PGPDISK";
55af5a
aac7e4 const HKEY¤ ¤   kRegistrySpurious3Root¤ ¤   ¤   = HKEY_DYN_DATA;
b38e18 static LPCSTR¤  kRegistrySpurious3Section¤  ¤   = "Config Manager\\Enum";
d8e2ca static LPCSTR¤  kRegistrySpurious3Value¤¤   ¤   = "HardWareKey";
bb99ca static LPCSTR¤  kRegistrySpurious3StringMatch¤  = "PGPDISK";
2daf5a
04af5a
be83f5 ///////////////////////////
c6aeb4 // Global variables for MFC
9583f5 ///////////////////////////
e6af5a
90544c CPGPdiskInstallHelperDll theApp;
ebaf5a
1faf5a
1283f5 ///////////////////////////
9db249 // MFC specific definitions
3183f5 ///////////////////////////
13af5a
9b0455 // MFC message map
36af5a
a544e9 BEGIN_MESSAGE_MAP(CPGPdiskInstallHelperDll, CWinApp)
1430fc ¤   //{{AFX_MSG_MAP(CPGPdiskInstallHelperDll)
112e09 ¤   //}}AFX_MSG
caaf28 END_MESSAGE_MAP()
95af5a
83af5a
ab063a ////////////////////////////////////////////////////////////////////////////
096e8d // CPGPdiskInstallHelperDll public custom functions and non-default handlers
a3063a ////////////////////////////////////////////////////////////////////////////
75af5a
7e5513 // The CPGPdiskInstallHelperDll constructor.
--7129 000173abd034011013e Page 2 of CPGPdiskInstallHelperDll.cpp
e0af5a
493073 CPGPdiskInstallHelperDll::CPGPdiskInstallHelperDll()
f5bb36 {
073364 ¤   ExplicitlyLinkAPIsForPlatform();
b4efe6 }
e2af5a
95954f // The CPGPdiskInstallHelperDll destructor.
49af5a
9df3c8 CPGPdiskInstallHelperDll::~CPGPdiskInstallHelperDll()
26bb36 {
6a1c25 ¤   CleanupExplicitLinkage();
ccefe6 }
4daf5a
2f3967 // ExitInstance is called when the DLL is unloading.
59af5a
39fcf4 int·
cd3366 CPGPdiskInstallHelperDll::ExitInstance()
26bb36 {
dc7d36 ¤   DualErr derr;
34af5a
501c25 ¤   CleanupExplicitLinkage();
f6af5a
deecec ¤   return CWinApp::ExitInstance();
dfefe6 }
f7af5a
52af5a
5ae953 // InitInstance is called during DLL initialization.
faaf5a
447efe BOOL·
e69217 CPGPdiskInstallHelperDll::InitInstance()
a7bb36 {
b97d36 ¤   DualErr derr;
1daf5a
80ffd6 ¤   derr = CheckWindowsVersion();
d2af5a
2c2361 ¤   if (derr.IsntError())
52c7a1 ¤   {
21e98e ¤   ¤   derr = ExplicitlyLinkAPIsForPlatform();
2e9371 ¤   }
16af5a
8864a3 ¤   // DON'T bug user on error, just fail to load.
269933 ¤   return derr.IsntError();
eaefe6 }
88af5a
f46c0e /////////////////////////////////////////////////////////////////////////////
c4d1fe // CPGPdiskInstallHelperDll private custom functions and non-default handlers
eb6c0e /////////////////////////////////////////////////////////////////////////////
8aaf5a
f9eabc // CheckWindowsVersion checks if we are running an incompatible version of
4f74f7 // Windows.
b4af5a
d02292 DualErr·
4a5ea5 CPGPdiskInstallHelperDll::CheckWindowsVersion()
aebb36 {
be7d36 ¤   DualErr derr;
68af5a
7de20f ¤   if (!IsWin95CompatibleMachine() && !IsWinNT4CompatibleMachine())
bbc7a1 ¤   {
280b8e ¤   ¤   derr = DualErr(kPGDMinorError_NotCompatibleWindows);
1d9371 ¤   }
baaf5a
aa33e3 ¤   return derr;
f8efe6 }
9caf5a
72af5a
a96cc2 /////////////////////
ca13d2 // Exported functions
476cc2 /////////////////////
a3af5a
7430fb // KillPGPdiskResident cleans up extraneous PGPdisk registry entries.
70af5a
17c823 void·
--ba15 00051828ea54011013e Page 3 of CPGPdiskInstallHelperDll.cpp
6cb45d __stdcall·
6bde84 KillPGPdiskResident()
83bb36 {
479a95 ¤   DualErr¤¤   ¤   derr;
e67139 ¤   PGPBoolean¤ ¤   attachedMem¤= FALSE;
abebfc ¤   PGPdiskResInfo¤ *pgpDiskResInfo;
d952c1 ¤   SharedMemory¤   pgpDiskResInfoMem;
fdaf5a
a2a500 ¤   // Try to find an existing PGPdiskResident application.
e1cfcc ¤   derr = pgpDiskResInfoMem.Attach(kPGPdiskResSharedMemName);
50faa8 ¤   attachedMem = derr.IsntError();
54af5a
56d4a5 ¤   // If found, kill it.
512361 ¤   if (derr.IsntError())
50c7a1 ¤   {
16a3a5 ¤   ¤   pgpDiskResInfo = (PGPdiskResInfo *)·
55a4a7 ¤   ¤   ¤   pgpDiskResInfoMem.GetMemPointer();
aeaf5a
456e02 ¤   ¤   PostMessage(pgpDiskResInfo->hiddenWindowHwnd, WM_QUIT, NULL, NULL);
389371 ¤   }
59af5a
677ac6 ¤   if (attachedMem)
e781dd ¤   ¤   pgpDiskResInfoMem.Detach();
baefe6 }
1faf5a
464c52 // PGPdiskCleanup cleans up extraneous PGPdisk registry entries.
1aaf5a
21c823 void·
46b45d __stdcall·
6e1c71 PGPdiskCleanup()
cebb36 {
7978f1 ¤   try
9bc7a1 ¤   {
871778 ¤   ¤   CString¤¤   keyName, keyPath, valueString;
d679f4 ¤   ¤   DualErr¤¤   derr;
8ecde1 ¤   ¤   PGPBoolean¤ isIndexValid;
ab8f5c ¤   ¤   PGPUInt32¤  i, j;
8eaf5a
1b26c3 ¤   ¤   // Wipe the "PGPDISK" subtree under "HKLM\Enum\ESDI".
549ed6 ¤   ¤   i = 0;
86af5a
ba48f8 ¤   ¤   while (derr.IsntError())
f65b34 ¤   ¤   {
94d47d ¤   ¤   ¤   derr = PGPdiskEnumSubkeys(kRegistrySpurious1Root,·
afc249 ¤   ¤   ¤   ¤   kRegistrySpurious1Section, i,·
489026 ¤   ¤   ¤   ¤   keyName.GetBuffer(kMaxStringSize), kMaxStringSize,·
dcd1ad ¤   ¤   ¤   ¤   &isIndexValid);
e9af5a
8e3192 ¤   ¤   ¤   keyName.ReleaseBuffer();
a2af5a
ad9d3d ¤   ¤   ¤   if (derr.IsntError())
2df776 ¤   ¤   ¤   {
b0a0a9 ¤   ¤   ¤   ¤   if (!isIndexValid)
4314c3 ¤   ¤   ¤   ¤   ¤   break;
cfaf5a
a1b33f ¤   ¤   ¤   ¤   if (keyName.Find(kRegistrySpurious1SubkeyMatch) == -1)
ef72c3 ¤   ¤   ¤   ¤   {
ba71b6 ¤   ¤   ¤   ¤   ¤   i++;
505914 ¤   ¤   ¤   ¤   ¤   continue;
842613 ¤   ¤   ¤   ¤   }
8bfa07 ¤   ¤   ¤   ¤   else
2872c3 ¤   ¤   ¤   ¤   {
0fe102 ¤   ¤   ¤   ¤   ¤   derr = PGPdiskDeleteSubkey(kRegistrySpurious1Root,·
924234 ¤   ¤   ¤   ¤   ¤   ¤   kRegistrySpurious1Section, keyName);
d914c3 ¤   ¤   ¤   ¤   ¤   break;
912613 ¤   ¤   ¤   ¤   }
7fa3a6 ¤   ¤   ¤   }
a90fe4 ¤   ¤   }
7baf5a
da9e84 ¤   ¤   derr = DualErr::NoError;
55af5a
51bf97 ¤   ¤   // Wipe all values containing "PGPDISK" in all keys that reside under
--780b 000f63b32044011013e Page 4 of CPGPdiskInstallHelperDll.cpp
ae26c8 ¤   ¤   // "HKLM\System\CurrentControlSet\control\ASD\Prob".
81af5a
0a9ed6 ¤   ¤   i = 0;
90af5a
dd48f8 ¤   ¤   while (derr.IsntError())
ea5b34 ¤   ¤   {
8b5ead ¤   ¤   ¤   derr = PGPdiskEnumSubkeys(kRegistrySpurious2Root,·
034177 ¤   ¤   ¤   ¤   kRegistrySpurious2Section, i,·
be9026 ¤   ¤   ¤   ¤   keyName.GetBuffer(kMaxStringSize), kMaxStringSize,·
16d1ad ¤   ¤   ¤   ¤   &isIndexValid);
6baf5a
513192 ¤   ¤   ¤   keyName.ReleaseBuffer();
51af5a
2a9d3d ¤   ¤   ¤   if (derr.IsntError())
3df776 ¤   ¤   ¤   {
9a2c86 ¤   ¤   ¤   ¤   CString valueName;
c5af5a
d0eff2 ¤   ¤   ¤   ¤   j = 0;
d9af5a
7ca0a9 ¤   ¤   ¤   ¤   if (!isIndexValid)
bb14c3 ¤   ¤   ¤   ¤   ¤   break;
fdaf5a
fe4dd3 ¤   ¤   ¤   ¤   keyPath¤= kRegistrySpurious2Section;
691265 ¤   ¤   ¤   ¤   keyPath += "\\";
f0ccd2 ¤   ¤   ¤   ¤   keyPath¤+= keyName;
2aaf5a
cdd1b6 ¤   ¤   ¤   ¤   // Enumerate all values under this key.
c8707d ¤   ¤   ¤   ¤   while (derr.IsntError())
1072c3 ¤   ¤   ¤   ¤   {
dab9da ¤   ¤   ¤   ¤   ¤   derr = PGPdiskEnumValues(kRegistrySpurious2Root,·
2e1b98 ¤   ¤   ¤   ¤   ¤   ¤   keyPath, j, valueName.GetBuffer(kMaxStringSize),·
eb7c38 ¤   ¤   ¤   ¤   ¤   ¤   kMaxStringSize, NULL, &isIndexValid);
70af5a
526ba6 ¤   ¤   ¤   ¤   ¤   valueName.ReleaseBuffer();
ebae30 ¤   ¤   ¤   ¤   ¤
0a4ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
db4859 ¤   ¤   ¤   ¤   ¤   {
b1ef16 ¤   ¤   ¤   ¤   ¤   ¤   if (!isIndexValid)
1b8c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
a8af5a
39359d ¤   ¤   ¤   ¤   ¤   ¤   if (valueName.Find(kRegistrySpurious2ValueMatch) ==·
42fb6d ¤   ¤   ¤   ¤   ¤   ¤   ¤   -1)
bb8fec ¤   ¤   ¤   ¤   ¤   ¤   {
83e371 ¤   ¤   ¤   ¤   ¤   ¤   ¤   j++;
0b816f ¤   ¤   ¤   ¤   ¤   ¤   ¤   continue;
57db3c ¤   ¤   ¤   ¤   ¤   ¤   }
287f8b ¤   ¤   ¤   ¤   ¤   ¤   else
b18fec ¤   ¤   ¤   ¤   ¤   ¤   {
b284b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   derr = PGPdiskDeleteValue(kRegistrySpurious2Root,·
9b9422 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyPath, valueName);
2f9544 ¤   ¤   ¤   ¤   ¤   ¤   ¤   j = 0;
86db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ca1c89 ¤   ¤   ¤   ¤   ¤   }
562613 ¤   ¤   ¤   ¤   }
dfa3a6 ¤   ¤   ¤   }
19af5a
3a81ec ¤   ¤   ¤   i++;
4b0fe4 ¤   ¤   }
adaf5a
1f9e84 ¤   ¤   derr = DualErr::NoError;
daaf5a
fdda21 ¤   ¤   // Wipe all keys with a "HardWareKey" value containing "PGPDISK"
3589b8 ¤   ¤   // under "HDD\Config Manager\Enum".
9daf5a
fa9ed6 ¤   ¤   i = 0;
53af5a
be48f8 ¤   ¤   while (derr.IsntError())
ff5b34 ¤   ¤   {
cbdf12 ¤   ¤   ¤   derr = PGPdiskEnumSubkeys(kRegistrySpurious3Root,·
d23f9d ¤   ¤   ¤   ¤   kRegistrySpurious3Section, i,·
c09026 ¤   ¤   ¤   ¤   keyName.GetBuffer(kMaxStringSize), kMaxStringSize,·
f6d1ad ¤   ¤   ¤   ¤   &isIndexValid);
--3eff 0009af3ee0d4011013e Page 5 of CPGPdiskInstallHelperDll.cpp
e0af5a
fb3192 ¤   ¤   ¤   keyName.ReleaseBuffer();
73af5a
1f9d3d ¤   ¤   ¤   if (derr.IsntError())
0cf776 ¤   ¤   ¤   {
40a0a9 ¤   ¤   ¤   ¤   if (!isIndexValid)
4314c3 ¤   ¤   ¤   ¤   ¤   break;
deaf5a
e261f4 ¤   ¤   ¤   ¤   keyPath¤= kRegistrySpurious3Section;
a51265 ¤   ¤   ¤   ¤   keyPath += "\\";
25ccd2 ¤   ¤   ¤   ¤   keyPath¤+= keyName;
51af5a
7525de ¤   ¤   ¤   ¤   derr = PGPdiskGetRawKey(kRegistrySpurious3Root, keyPath,·
d4fb16 ¤   ¤   ¤   ¤   ¤   kRegistrySpurious3Value,·
451b27 ¤   ¤   ¤   ¤   ¤   (PGPUInt8 *) valueString.GetBuffer(kMaxStringSize),·
bcc6d9 ¤   ¤   ¤   ¤   ¤   kMaxStringSize);
23af5a
07ba66 ¤   ¤   ¤   ¤   valueString.ReleaseBuffer();
20a3a6 ¤   ¤   ¤   }
28af5a
c19d3d ¤   ¤   ¤   if (derr.IsntError())
fbf776 ¤   ¤   ¤   {
072d1a ¤   ¤   ¤   ¤   if (valueString.Find(kRegistrySpurious3StringMatch) == -1)
1772c3 ¤   ¤   ¤   ¤   {
d571b6 ¤   ¤   ¤   ¤   ¤   i++;
5b5914 ¤   ¤   ¤   ¤   ¤   continue;
8b2613 ¤   ¤   ¤   ¤   }
4dfa07 ¤   ¤   ¤   ¤   else
5372c3 ¤   ¤   ¤   ¤   {
72ea6d ¤   ¤   ¤   ¤   ¤   derr = PGPdiskDeleteSubkey(kRegistrySpurious3Root,·
a1f489 ¤   ¤   ¤   ¤   ¤   ¤   kRegistrySpurious3Section, keyName);
0ca57d ¤   ¤   ¤   ¤   ¤   i = 0;
7c2613 ¤   ¤   ¤   ¤   }
cba3a6 ¤   ¤   ¤   }
e30fe4 ¤   ¤   }
e49371 ¤   }
f43c88 ¤   catch (CMemoryException *ex)
32c7a1 ¤   {
ce6adc ¤   ¤   ex->Delete();
ba9371 ¤   }
34efe6 }
b9af5a
2ce741 // AreAnyPGPdisksMounted returns TRUE if any PGPdisks are mounted, FALSE
274da2 // otherwise.
9daf5a
e76726 BOOLEAN·
afb45d __stdcall·
c51931 AreAnyPGPdisksMounted()
44bb36 {
0dbe41 ¤   DualErr¤¤   derr;
b4db14 ¤   PGPBoolean¤ anyMounted¤ = FALSE;
9baf5a
beb1f4 ¤   // Open the driver.
cacd3f ¤   derr = OpenPGPdiskDriver();
afaf5a
c92361 ¤   if (derr.IsntError())
bac7a1 ¤   {
e81104 ¤   ¤   PGPUInt8 i;
30af5a
b4523e ¤   ¤   // Check if any drive letter is a mounted PGPdisk.
c59302 ¤   ¤   for (i = 0; i < kMaxDrives; i++)
db5b34 ¤   ¤   {
d06cd2 ¤   ¤   ¤   derr = IsVolumeAPGPdisk(i, &anyMounted);
31af5a
bb1088 ¤   ¤   ¤   if (derr.IsError())
71f622 ¤   ¤   ¤   ¤   break;
14af5a
999a72 ¤   ¤   ¤   if (anyMounted)
98f622 ¤   ¤   ¤   ¤   break;
d40fe4 ¤   ¤   }
4c9371 ¤   }
9aaf5a
--4999 000ad1209d24011013e Page 6 of CPGPdiskInstallHelperDll.cpp
1af832 ¤   // Close the driver.
b19a2c ¤   if (IsDriverOpen())
7ea2cd ¤   ¤   ClosePGPdiskDriver();
d6af5a
302361 ¤   if (derr.IsntError())
c72ebd ¤   ¤   return anyMounted;
f80e24 ¤   else
6198aa ¤   ¤   return FALSE;
19efe6 }
2caf5a
06c5c9 // IsVolumeAPGPdisk returns TRUE if the specified volume is a mounted
f641a0 // PGPdisk.
c6af5a
a46726 BOOLEAN·
64b45d __stdcall·
db3e16 IsVolumeAPGPdisk(int drive)
66bb36 {
97be41 ¤   DualErr¤¤   derr;
5d40e4 ¤   PGPBoolean¤ isVolumeAPGPdisk;
92af5a
4faa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
b1af5a
8eb1f4 ¤   // Open the driver.
78cd3f ¤   derr = OpenPGPdiskDriver();
66af5a
a69f5a ¤   // Check if drive is PGPdisk.
c42361 ¤   if (derr.IsntError())
c0c7a1 ¤   {
22435e ¤   ¤   derr = IsVolumeAPGPdisk(drive, &isVolumeAPGPdisk);
df9371 ¤   }
f3af5a
4bf832 ¤   // Close the driver.
2b9a2c ¤   if (IsDriverOpen())
90a2cd ¤   ¤   ClosePGPdiskDriver();
ccaf5a
b42361 ¤   if (derr.IsntError())
654f75 ¤   ¤   return isVolumeAPGPdisk;
b90e24 ¤   else
db98aa ¤   ¤   return FALSE;
49efe6 }
e7af5a
f5f317 // UnmountAllPGPdisks returns TRUE if all mounted PGPdisks were successfully
e84da1 // unmounted, FALSE otherwise.
f3af5a
476726 BOOLEAN·
f7b45d __stdcall·
78d75e UnmountAllPGPdisks()
99bb36 {
907d36 ¤   DualErr derr;
57af5a
4f8d90 ¤   if (!AreAnyPGPdisksMounted())
a8836c ¤   ¤   return TRUE;
f0af5a
ddb1f4 ¤   // Open the driver.
38cd3f ¤   derr = OpenPGPdiskDriver();
57af5a
b32361 ¤   if (derr.IsntError())
91c7a1 ¤   {
55e5b3 ¤   ¤   PGPUInt8¤   i;
29368b ¤   ¤   PGPUInt32¤  drives;
6baf5a
3d6ab5 ¤   ¤   drives = GetLogicalDrives();
b4af5a
93c2fd ¤   ¤   // For every drive...
fd9302 ¤   ¤   for (i = 0; i < kMaxDrives; i++)
7d5b34 ¤   ¤   {
258b1d ¤   ¤   ¤   if (drives & (1 << i))
c1f776 ¤   ¤   ¤   {
426e5d ¤   ¤   ¤   ¤   PGPBoolean isVolumeAPGPdisk = FALSE;
29af5a
a3f879 ¤   ¤   ¤   ¤   //... ask if it's a mounted PGPdisk.
add72e ¤   ¤   ¤   ¤   IsVolumeAPGPdisk(i, &isVolumeAPGPdisk);
--3b8c 001b935766d4011013e Page 7 of CPGPdiskInstallHelperDll.cpp
e0af5a
c08c79 ¤   ¤   ¤   ¤   // If so, unmount it.
301f5e ¤   ¤   ¤   ¤   if (isVolumeAPGPdisk)
3d72c3 ¤   ¤   ¤   ¤   {
af8dec ¤   ¤   ¤   ¤   ¤   AD_Unmount UNMNT;
50af5a
a7e072 ¤   ¤   ¤   ¤   ¤   UNMNT.drive = i;
42ec5a ¤   ¤   ¤   ¤   ¤   UNMNT.isThisEmergency = FALSE;
a8af5a
3d9a5b ¤   ¤   ¤   ¤   ¤   derr = SendUnmountRequest(&UNMNT);
322613 ¤   ¤   ¤   ¤   }
b5a3a6 ¤   ¤   ¤   }
7caf5a
701088 ¤   ¤   ¤   if (derr.IsError())
27f622 ¤   ¤   ¤   ¤   break;
8a0fe4 ¤   ¤   }
fc9371 ¤   }
26af5a
07f832 ¤   // Close the driver.
859a2c ¤   if (IsDriverOpen())
8da2cd ¤   ¤   ClosePGPdiskDriver();
97af5a
119933 ¤   return derr.IsntError();
b9efe6 }
--9d0c 001a5a777e34011013f Page 1 of CPGPdiskInstallHelperDll.h
541bc3 //////////////////////////////////////////////////////////////////////////////
899c3d // CPGPdiskInstallHelperDll.h
28465d //
d47e9b // Contains declarations for CPGPdiskInstallHelperDll.cpp.
5f1bc3 //////////////////////////////////////////////////////////////////////////////
f0af5a
f648b2 // $Id: CPGPdiskInstallHelperDll.h,v 1.1.2.7 1998/07/30 00:50:26 nryan Exp $
04af5a
9ecbce // Copyright (C) 1998 by Network Associates, Inc.
d571ae // All rights reserved.
5faf5a
e778a1 #ifndef Included_CPGPdiskInstallHelper_h¤   // [
fd398a #define Included_CPGPdiskInstallHelper_h
f4af5a
87af5a
3219ee /////////////////////////////////
dd7f9f // Class CPGPdiskInstallHelperDll
0f19ee /////////////////////////////////
acaf5a
a640ce class CPGPdiskInstallHelperDll : public CWinApp
41bb36 {
bb5ed4 public:
21697f ¤   CPGPdiskInstallHelperDll();
420ba3 ¤   ~CPGPdiskInstallHelperDll();
50af5a
cdcde6 ¤   //{{AFX_VIRTUAL(CPGPdiskInstallHelperApp)
7067d4 ¤   public:
a81c2f ¤   virtual int ExitInstance();
e6019a ¤   virtual BOOL InitInstance();
67af53 ¤   //}}AFX_VIRTUAL
8baf5a
411358 ¤   //{{AFX_MSG(CPGPdiskInstallHelperApp)
392e09 ¤   //}}AFX_MSG
7eaf5a
a70fb9 private:
4f5a29 ¤   DualErr CheckWindowsVersion();
e1af5a
b12409 ¤   DECLARE_MESSAGE_MAP()
5182f7 };
1daf5a
61af5a
b56cc2 /////////////////////
bc13d2 // Exported functions
166cc2 /////////////////////
88af5a
9a6da1 extern "C" void __stdcall¤  ¤   KillPGPdiskResident();
abcace extern "C" void __stdcall¤  ¤   PGPdiskCleanup();
84f4b2 extern "C" BOOLEAN __stdcall¤   AreAnyPGPdisksMounted();
d4a812 extern "C" BOOLEAN __stdcall¤   IsVolumeAPGPdisk(int drive);
85fe2f extern "C" BOOLEAN __stdcall¤   UnmountAllPGPdisks();
a1af5a
95c18c //{{AFX_INSERT_LOCATION}}
e9af5a
a591c1 #endif // Included_CPGPdiskInstallHelper_h
--7fdd 0017d5c96d440110140 Page 1 of Resource.h
739d39 //{{NO_DEPENDENCIES}}
361fba // Microsoft Visual C++ generated include file.
1d063a // Used by PGPDISKINSTALLHELPER.RC
ae465d //
4aaf5a
7a11aa // Next default values for new objects
29ac6a //·
78f860 #ifdef APSTUDIO_INVOKED
823f23 #ifndef APSTUDIO_READONLY_SYMBOLS
ccaf5a
01cbd3 #define _APS_NEXT_RESOURCE_VALUE ·······129
1ab061 #define _APS_NEXT_COMMAND_VALUE ········32771
d8f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
3a1285 #define _APS_NEXT_SYMED_VALUE ··········101
e17454 #endif
7d7454 #endif
--16d0 001e0fc050d40110141 Page 1 of StdAfx.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
77fc35 // StdAfx.cpp
06465d //
c0afe4 // MFC source.
d41bc3 //////////////////////////////////////////////////////////////////////////////
36af5a
63f7a2 // $Id: StdAfx.cpp,v 1.1.2.1 1998/05/29 17:16:45 nryan Exp $
1daf5a
6ad221 // Not really Copyright (C) 1998 by Network Associates, Inc.
56af5a
e09e12 #include "StdAfx.h"
--fe3a 0016d87445e40110142 Page 1 of StdAfx.h
541bc3 //////////////////////////////////////////////////////////////////////////////
465fb0 // StdAfx.h
01465d //
7120f8 // Contains global MFC includes.
081bc3 //////////////////////////////////////////////////////////////////////////////
82af5a
6db617 // $Id: StdAfx.h,v 1.1.2.1 1998/05/29 17:16:46 nryan Exp $
50af5a
a3d221 // Not really Copyright (C) 1998 by Network Associates, Inc.
7e71ae // All rights reserved.
a9af5a
6f96d7 #ifndef Included_StdAfx_h¤  // [
b64653 #define Included_StdAfx_h
e7af5a
4e6b7d #include <afxwin.h> ········// MFC core and standard components
ebbe9b #include <afxext.h> ········// MFC extensions
e9af5a
a98e6d #ifndef _AFX_NO_OLE_SUPPORT
ff4ea2 #include <afxole.h> ········// MFC OLE classes
aa4f52 #include <afxodlgs.h> ······// MFC OLE dialog classes
b57e9c #include <afxdisp.h> ·······// MFC OLE automation classes
7442ac #endif // _AFX_NO_OLE_SUPPORT
0baf5a
f8af5a
6f7ed7 #ifndef _AFX_NO_DB_SUPPORT
b95762 #include <afxdb.h>¤ ¤   ¤   // MFC ODBC database classes
40e3bd #endif // _AFX_NO_DB_SUPPORT
31af5a
5b8566 #ifndef _AFX_NO_DAO_SUPPORT
6a0aa9 #include <afxdao.h>¤¤   ¤   // MFC DAO database classes
ec49a7 #endif // _AFX_NO_DAO_SUPPORT
8baf5a
efaef9 #ifndef _AFX_NO_AFXCMN_SUPPORT
05eb71 #include <afxcmn.h>¤¤   ¤   // MFC support for Windows Common Controls
6d9db5 #endif // _AFX_NO_AFXCMN_SUPPORT
6daf5a
f1c18c //{{AFX_INSERT_LOCATION}}
e3af5a
6da54d #endif // Included_StdAfx_h
--9741 001216362bd40110143 Page 1 of PGPdiskResident.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
2229f7 #include "Source\Resource.h"
28af5a
2be1bf #define APSTUDIO_READONLY_SYMBOLS
196c0e /////////////////////////////////////////////////////////////////////////////
2f465d //
d00131 // Generated from the TEXTINCLUDE 2 resource.
19465d //
58897a #include "afxres.h"
2daf5a
8d6c0e /////////////////////////////////////////////////////////////////////////////
287b93 #undef APSTUDIO_READONLY_SYMBOLS
ceaf5a
cb6c0e /////////////////////////////////////////////////////////////////////////////
04f930 // English (U.S.) resources
2baf5a
cd1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
d4ec08 #ifdef _WIN32
ebe912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
e59c1c #pragma code_page(1252)
e21f8e #endif //_WIN32
e5af5a
9cf860 #ifdef APSTUDIO_INVOKED
5d6c0e /////////////////////////////////////////////////////////////////////////////
12465d //
895733 // TEXTINCLUDE
91465d //
e0af5a
ea86ef 1 TEXTINCLUDE DISCARDABLE·
414523 BEGIN
b1df56 ····"Source\\Resource.h\0"
6ae0d1 END
a4af5a
417037 2 TEXTINCLUDE DISCARDABLE·
1b4523 BEGIN
01eb23 ····"#include ""afxres.h""\r\n"
f8db5c ····"\0"
f6e0d1 END
f1af5a
ce227f 3 TEXTINCLUDE DISCARDABLE·
c74523 BEGIN
e269b2 ····"#include ""PGPdiskResidentVer.rc""\0"
8de0d1 END
30af5a
6669ab #endif ···// APSTUDIO_INVOKED
b6af5a
881b3a #endif ···// English (U.S.) resources
ec6c0e /////////////////////////////////////////////////////////////////////////////
e9af5a
82af5a
22af5a
d4ce8c #ifndef APSTUDIO_INVOKED
9b6c0e /////////////////////////////////////////////////////////////////////////////
94465d //
2e8464 // Generated from the TEXTINCLUDE 3 resource.
0d465d //
091680 #include "PGPdiskResidentVer.rc"
9f6c0e /////////////////////////////////////////////////////////////////////////////
d78072 #endif ···// not APSTUDIO_INVOKED
21af5a
--2a86 0011530bcb640110144 Page 1 of PGPdiskResidentVer.rc
b3eddb // VERSIONINFO structure which automatically include version
f014b6 // string from PGPdiskVersion.h
a6465d //
ed0380 #include <winver.h>
7b5a72 #include "..\Shared\PGPdiskVersion.h"
2aaf5a
016c0e /////////////////////////////////////////////////////////////////////////////
64465d //
29c5f2 // Version
f4465d //
5faf5a
0a8df2 VS_VERSION_INFO VERSIONINFO
e75e85 ·FILEVERSION kPGPdiskFileVerData
e16589 ·PRODUCTVERSION kPGPdiskProductVerData
29a381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
4b1f29 #ifdef _DEBUG
637c0e ·FILEFLAGS VS_FF_DEBUG
6cdb21 #else
db12ca ·FILEFLAGS 0x0L
e57454 #endif
e003bb ·FILEOS VOS__WINDOWS32
1b5212 ·FILETYPE VFT_DLL
f87247 ·FILESUBTYPE VFT2_UNKNOWN
844523 BEGIN
a32c72 ····BLOCK "StringFileInfo"
445574 ····BEGIN
6d70ac ········BLOCK "040904b0"
3a52d6 ········BEGIN
74f777 ············VALUE "CompanyName", kPGPdiskCompanyName
21250b ············VALUE "FileDescription", "PGPdisk Resident Application\0"
bb126d ············VALUE "FileVersion", kPGPdiskFileVerString
bfbc3b ············VALUE "InternalName", "PGPdiskResident.exe\0"
82f2bf ············VALUE "LegalCopyright", kPGPdiskCopyright
42d6fd ············VALUE "OriginalFilename", "PGPdiskResident.exe\0"
211fa9 ············VALUE "ProductName", kPGPdiskProductVerName
f37b64 ············VALUE "ProductVersion", kPGPdiskProductVerString
35f37f ········END
007d01 ····END
3226ab ····BLOCK "VarFileInfo"
5f5574 ····BEGIN
474b11 ········VALUE "Translation", 0x409, 1200
257d01 ····END
15e0d1 END
--f7ba 000bee48bc440110145 Page 1 of CHiddenWindow.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
a476d3 // CHiddenWindow.cpp
f4465d //
86dd0e // Implementation of class CHiddenWindow.
fb1bc3 //////////////////////////////////////////////////////////////////////////////
58af5a
e88584 // $Id: CHiddenWindow.cpp,v 1.3.2.11 1998/07/06 08:58:34 nryan Exp $
65af5a
3acbce // Copyright (C) 1998 by Network Associates, Inc.
8c71ae // All rights reserved.
8caf5a
959e12 #include "StdAfx.h"
1ae9d9 #include <Pbt.h>
b2af5a
9d9bcf #include "Required.h"
004b7a #include "CommonStrings.h"
51ac00 #include "DriverComm.h"
483a85 #include "DualErr.h"
80babe #include "PGPdiskRegistry.h"
aecd22 #include "PGPdiskResidentDefines.h"
79993c #include "StringAssociation.h"
58bfe9 #include "UtilityFunctions.h"
63dd74 #include "WindowsVersion.h"
28af5a
d576a0 #include "CHiddenWindow.h"
5266a0 #include "CPGPdiskResidentApp.h"
3dc411 #include "Globals.h"
e3af5a
9baf5a
c909b7 ////////////
83e738 // Constants
8209b7 ////////////
01af5a
652854 PGPUInt16 kPGPdiskResAppHotKeyId = 0;
83af5a
1caf5a
b783f5 ///////////////////////////
7cb249 // MFC specific definitions
5183f5 ///////////////////////////
fcaf5a
9e0455 // MFC message map
25af5a
b0791f BEGIN_MESSAGE_MAP(CHiddenWindow, CWnd)
32ffb7 ¤   //{{AFX_MSG_MAP(CHiddenWindow)
478e2f ¤   ON_MESSAGE(WM_ENDSESSION, OnEndSession)
8b588e ¤   ON_MESSAGE(WM_HOTKEY, OnHotKey)
e1eb27 ¤   ON_MESSAGE(WM_PGPDISKRES_NEWPREFS, OnNewPrefs)
a4d22c ¤   ON_MESSAGE(WM_POWERBROADCAST, OnPowerBroadcast)
2adf96 ¤   ON_WM_CLOSE()
e86816 ¤   ON_WM_CREATE()
42044a ¤   //}}AFX_MSG_MAP
beaf28 END_MESSAGE_MAP()
6eaf5a
3aaf5a
c8186d /////////////////////////////////////////////////////////////////////////
d99fc1 // CHiddenWindow public custom functions and non-default message handlers
48186d /////////////////////////////////////////////////////////////////////////
d5af5a
cfd212 // Default constructor for CHiddenWindow.
51af5a
c6433c CHiddenWindow::CHiddenWindow()
bebb36 {
9a589a ¤   mIsHotKeyRegistered = FALSE;
40efe6 }
d6af5a
547f64 // Default destructor for CHiddenWindow.
b0af5a
ce9d11 CHiddenWindow::~CHiddenWindow()
6bbb36 {
4eefe6 }
efaf5a
beaf5a
--bca4 0003dd8b62c40110145 Page 2 of CHiddenWindow.cpp
f4063a ////////////////////////////////////////////////////////////////////////////
0aec6d // CHiddenWindow protected custom functions and non-default message handlers
1e063a ////////////////////////////////////////////////////////////////////////////
a3af5a
938009 // OnEndSession is called when the system is shutting down or the user is
e15485 // logging off. Notify the driver in the latter case.
f0af5a
5fc823 void·
ede20a CHiddenWindow::OnEndSession(WPARAM wParam, LPARAM lParam)
63bb36 {
a87d36 ¤   DualErr derr;
65af5a
0ea9b3 ¤   if (((BOOL) wParam) && (lParam = ENDSESSION_LOGOFF))
aace4c ¤   ¤   NotifyUserLogoff();
7aefe6 }
c9af5a
9e498c // OnHotKey is called when our unmount hot key is pressed.
82af5a
4ec823 void·
b1ac4a CHiddenWindow::OnHotKey(WPARAM wParam, LPARAM lParam)
22bb36 {
bc7d36 ¤   DualErr derr;
e6af5a
2664ca ¤   if (wParam != kPGPdiskResAppHotKeyId)
6299bf ¤   ¤   return;
59af5a
0f0216 ¤   derr = UnmountAllPGPdisks();
8eaf5a
6e4bb3 ¤   if (derr.IsError())
d0c7a1 ¤   {
3b21e6 ¤   ¤   ReportError(kPGDMajorError_PGPdiskUnmountAllFailed, derr);
7d9371 ¤   }
5defe6 }
45af5a
306a1b // OnNewPrefs is called when the application tells us it has updated the
583475 // PGPdisk preferences.
51af5a
6bc823 void·
f8fb00 CHiddenWindow::OnNewPrefs(WPARAM wParam, LPARAM lParam)
1cbb36 {
8410db ¤   if (wParam != kPGPdiskMessageMagic)¤¤   // prevent collisions
6299bf ¤   ¤   return;
41af5a
9f68c8 ¤   // Update our preferences.
038206 ¤   UpdatePrefs();
03af5a
7e05fa ¤   // Update the hot key;
24b358 ¤   UpdateHotKey();
a6efe6 }
d8af5a
6e9606 // We handle OnPowerBroadcast to see sleep events.
a6af5a
2efcf4 int·
9d1504 CHiddenWindow::OnPowerBroadcast(WPARAM wParam, LPARAM lParam)
0abb36 {
31705b ¤   DualErr¤¤   ¤   ¤   derr;
b7a502 ¤   PGPBoolean¤ ¤   ¤   denyThisMessage¤¤   ¤   = FALSE;
a79f82 ¤   static PGPBoolean¤  sawASleepRequest¤   ¤   = FALSE;
dcc786 ¤   static PGPBoolean¤  failAllSleepRequests¤   = FALSE;
88af5a
10ee02 ¤   // Windows will send us multiple sleep requests, but we will only process
21f399 ¤   // the first one.
ffaf5a
599645 ¤   switch (wParam)
14c7a1 ¤   {
0e8455 ¤   case PBT_APMQUERYSUSPEND:
459ced ¤   ¤   if (sawASleepRequest)
245b34 ¤   ¤   {
84ca0a ¤   ¤   ¤   denyThisMessage = failAllSleepRequests;
be0fe4 ¤   ¤   }
e10e1d ¤   ¤   else
3d5b34 ¤   ¤   {
--7264 000e8823c3540110145 Page 3 of CHiddenWindow.cpp
b6e16f ¤   ¤   ¤   PGPBoolean canWarnUser = (lParam & 1 > 0);
49af5a
9bce55 ¤   ¤   ¤   sawASleepRequest = TRUE;
c9af5a
69dfd9 ¤   ¤   ¤   if (mUnmountOnSleep)
d2f776 ¤   ¤   ¤   {
bb3c2b ¤   ¤   ¤   ¤   derr = UnmountAllPGPdisks();
25af5a
dabc7f ¤   ¤   ¤   ¤   // Fail the sleep if error and the preference was set.
589b3b ¤   ¤   ¤   ¤   if (derr.IsError() && mNoSleepIfUnmountFail)
d172c3 ¤   ¤   ¤   ¤   {
66bf5a ¤   ¤   ¤   ¤   ¤   denyThisMessage¤¤   ¤   = TRUE;
671c6e ¤   ¤   ¤   ¤   ¤   failAllSleepRequests¤   = TRUE;
8aaf5a
933e3e ¤   ¤   ¤   ¤   ¤   if (canWarnUser)
154859 ¤   ¤   ¤   ¤   ¤   {
143ae4 ¤   ¤   ¤   ¤   ¤   ¤   ReportError(kPGDMajorError_NoSleepOnUnmountFailure);
8b1c89 ¤   ¤   ¤   ¤   ¤   }
b12613 ¤   ¤   ¤   ¤   }
d1a3a6 ¤   ¤   ¤   }
580fe4 ¤   ¤   }
662f68 ¤   ¤   break;
2baf5a
6b99f3 ¤   case PBT_APMQUERYSUSPENDFAILED:
53e41d ¤   ¤   sawASleepRequest¤   ¤   = FALSE;
9abc19 ¤   ¤   failAllSleepRequests¤   = FALSE;
db2f68 ¤   ¤   break;
d2af5a
c44644 ¤   case PBT_APMSUSPEND:
cce41d ¤   ¤   sawASleepRequest¤   ¤   = FALSE;
18bc19 ¤   ¤   failAllSleepRequests¤   = FALSE;
d62f68 ¤   ¤   break;
00f828 ¤   }¤
4eaf5a
12b0cb ¤   if (denyThisMessage)
6d498a ¤   ¤   return BROADCAST_QUERY_DENY;
420e24 ¤   else
41836c ¤   ¤   return TRUE;
cdefe6 }
7baf5a
36eccb // SendRequestToApp asks the PGPdisk application to perform a command.
d8af5a
e32292 DualErr·
f21869 CHiddenWindow::SendRequestToApp(LPCSTR command)
30bb36 {
f87d36 ¤   DualErr derr;
a6af5a
69d3d9 ¤   pgpAssertStrValid(command);
bcaf5a
2778f1 ¤   try
5dc7a1 ¤   {
9e3c85 ¤   ¤   CString¤¤   appName, commandLine;
cf0187 ¤   ¤   PGPUInt32¤  result;
93af5a
1d74a2 ¤   ¤   // Construct the application name.
191cf5 ¤   ¤   appName = kPGPdiskAppName;
f94b45 ¤   ¤   appName += ".exe";
d2af5a
a5bc30 ¤   ¤   // Execute the command line.
6c489c ¤   ¤   result = (PGPUInt32) ShellExecute(NULL, "open", appName, command,·
1543f0 ¤   ¤   ¤   NULL, SW_SHOW);
98af5a
d9e754 ¤   ¤   if (result < 32)
3e01c6 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_CouldntFindAppString);
4f9371 ¤   }
453c88 ¤   catch (CMemoryException *ex)
1bc7a1 ¤   {
b9ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
f26adc ¤   ¤   ex->Delete();
3f9371 ¤   }
58af5a
e833e3 ¤   return derr;
--bcb0 0002eefb49c40110145 Page 4 of CHiddenWindow.cpp
7aefe6 }
46af5a
039e05 // UnmountAllPGPdisks unmounts all PGPdisks.
0aaf5a
939d6b DualErr¤
5c1e78 CHiddenWindow::UnmountAllPGPdisks()
c5bb36 {
145bc6 ¤   return SendRequestToApp(GetCommonString(kPGPdiskUnmountAllCmdString));
11efe6 }
a9af5a
593514 // UpdateHotKey registeres or deregisters the hotkey as necessary.
1daf5a
dcc823 void·
dfa027 CHiddenWindow::UpdateHotKey()
c5bb36 {
c17d36 ¤   DualErr derr;
17af5a
527950 ¤   // First deregister the current hot key.
2ef29b ¤   if (mIsHotKeyRegistered)
71c7a1 ¤   {
c5ea06 ¤   ¤   if (!UnregisterHotKey(m_hWnd, kPGPdiskResAppHotKeyId))
fdd410 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_UnregisterHotKeyFailed);
0baf5a
4a65f2 ¤   ¤   mIsHotKeyRegistered = FALSE;
ea9371 ¤   }
5eaf5a
60e94d ¤   // Now re-enable the hotkey with the new information if we should.
a24bd3 ¤   if (derr.IsntError() && mHotKeyEnabled)
5bc7a1 ¤   {
7425d4 ¤   ¤   PGPUInt8¤   primaryVKey, modKeyState;
8d2680 ¤   ¤   PGPUInt32¤  hotKeyModKeyState;
08af5a
00371c ¤   ¤   primaryVKey = GetLowByte(mHotKeyCode);
26bca8 ¤   ¤   modKeyState = GetHighByte(mHotKeyCode);
34af5a
6db86b ¤   ¤   hotKeyModKeyState = NULL;
47af5a
745fcf ¤   ¤   if (modKeyState & kSHK_Alt)
4f1854 ¤   ¤   ¤   hotKeyModKeyState |= MOD_ALT;
6caf5a
70e75f ¤   ¤   if (modKeyState & kSHK_Control)
0bc6a8 ¤   ¤   ¤   hotKeyModKeyState |= MOD_CONTROL;
17af5a
e1d606 ¤   ¤   if (modKeyState & kSHK_Shift)
9ccdd6 ¤   ¤   ¤   hotKeyModKeyState |= MOD_SHIFT;
5caf5a
75f51b ¤   ¤   if (!RegisterHotKey(m_hWnd, kPGPdiskResAppHotKeyId,·
927172 ¤   ¤   ¤   hotKeyModKeyState, primaryVKey))
695b34 ¤   ¤   {
6982a1 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RegisterHotKeyFailed);
610fe4 ¤   ¤   }
a7af5a
695a77 ¤   ¤   mIsHotKeyRegistered = derr.IsntError();
de9371 ¤   }
51af5a
e34bb3 ¤   if (derr.IsError())
cdbae5 ¤   ¤   ReportError(kPGDMajorError_PGPdiskResHotKeyOpFailed, derr);
f2efe6 }
cfaf5a
089659 // UpdatePrefs updates our prefs from the registry.
64af5a
8bc823 void·
03e986 CHiddenWindow::UpdatePrefs()
45bb36 {
8e3340 ¤   PGPUInt32 temp;
46af5a
c481da ¤   // Get the value for the 'Auto-Unmount' key.
5cebac ¤   temp = PGPdiskGetPrefDWord(kRegistryAutoUnmountKey,·
88f9d7 ¤   ¤   kInvalidRegDWordValue);
74af5a
57eaf3 ¤   if (temp == FALSE)
2ef266 ¤   ¤   mAutoUnmount = FALSE;
--4f27 00090fefa3540110145 Page 5 of CHiddenWindow.cpp
416842 ¤   else if (temp == TRUE)
a40195 ¤   ¤   mAutoUnmount = TRUE;
c60e24 ¤   else
fc2d7d ¤   ¤   mAutoUnmount = kDefaultAutoUnmount;
3aaf5a
2b45fc ¤   // Get the value for the 'HotKeyCode' key.
1a007a ¤   mHotKeyCode = (PGPUInt16) PGPdiskGetPrefDWord(kRegistryHotKeyCodeKey,·
9af9d7 ¤   ¤   kInvalidRegDWordValue);
29af5a
bc00c5 ¤   // Get the value for the 'HotKeyEnabled' key.
5f191d ¤   temp = PGPdiskGetPrefDWord(kRegistryHotKeyEnabledKey,·
30f9d7 ¤   ¤   kInvalidRegDWordValue);
f367c5 ¤
98eaf3 ¤   if (temp == FALSE)
cc77aa ¤   ¤   mHotKeyEnabled = FALSE;
666842 ¤   else if (temp == TRUE)
b8cd04 ¤   ¤   mHotKeyEnabled = TRUE;
460e24 ¤   else
3fc6af ¤   ¤   mHotKeyEnabled = kDefaultHotKeyEnabled;
d3af5a
030d6f ¤   // Get the value for the 'UnmountOnSleep' key.
d375a2 ¤   temp = PGPdiskGetPrefDWord(kRegistryUnmountOnSleepKey,·
cdf9d7 ¤   ¤   kInvalidRegDWordValue);
9167c5 ¤
8eeaf3 ¤   if (temp == FALSE)
595db2 ¤   ¤   mUnmountOnSleep = FALSE;
6c6842 ¤   else if (temp == TRUE)
5c8f9f ¤   ¤   mUnmountOnSleep = TRUE;
9a0e24 ¤   else
0cc611 ¤   ¤   mUnmountOnSleep = kDefaultUnmountOnSleep;
91af5a
58009c ¤   // Get the value for the 'NoSleepIfUnmountFail' key.
7139ea ¤   temp = PGPdiskGetPrefDWord(kRegistryNoSleepIfFailKey,·
aaf9d7 ¤   ¤   kInvalidRegDWordValue);
0867c5 ¤
a7eaf3 ¤   if (temp == FALSE)
4ba63c ¤   ¤   mNoSleepIfUnmountFail = FALSE;
766842 ¤   else if (temp == TRUE)
e0eea3 ¤   ¤   mNoSleepIfUnmountFail = TRUE;
8a0e24 ¤   else
316749 ¤   ¤   mNoSleepIfUnmountFail = kDefaultNoSleepIfUnmountFail;
39af5a
3cadf9 ¤   // Get the value for the 'UnmountTimeout' key.
78c157 ¤   temp = PGPdiskGetPrefDWord(kRegistryUnmountTimeoutKey,·
91ff30 ¤   ¤   kMaxUnmountTimeout + 1);
1967c5 ¤
7d82ad ¤   if ((temp == FALSE) || (temp > kMaxUnmountTimeout))
981698 ¤   ¤   mUnmountTimeout = kDefaultUnmountTimeout;
290e24 ¤   else
7f104c ¤   ¤   mUnmountTimeout = temp;
5cefe6 }
91af5a
5faf5a
208fbd ///////////////////////////////////////////////////
d2053e // CHiddenWindow protected default message handlers
758fbd ///////////////////////////////////////////////////
ffaf5a
f8c4d9 // OnClose is called when the user is trying to kill us in Windows 95. Warn
e58f0a // him.
24af5a
ddc823 void·
9c71b2 CHiddenWindow::OnClose()·
72bb36 {
ed9ec6 ¤   UserResponse button;
0caf5a
a4ef3f ¤   button = DisplayMessage(kPGPdiskResConfirmPGPdiskResQuit,·
8939f5 ¤   ¤   kPMBS_YesNo, kPMBF_NoButton);
dcaf5a
567c57 ¤   if (button == kUR_Yes)
bd3d89 ¤   ¤   CWnd::OnClose();
41efe6 }
90af5a
--bc38 001c936503d40110145 Page 6 of CHiddenWindow.cpp
3b7738 // OnCreate is called when we're being created.
51af5a
0bfcf4 int·
108125 CHiddenWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)·
83bb36 {
5498c7 ¤   if (CWnd::OnCreate(lpCreateStruct) == -1)
cb043c ¤   ¤   return -1;
c767c5 ¤
da68c8 ¤   // Update our preferences.
db8206 ¤   UpdatePrefs();
81af5a
9b05fa ¤   // Update the hot key;
a5b358 ¤   UpdateHotKey();
3daf5a
c53e6b ¤   return 0;
c9efe6 }
--77d5 00118cd3eaf40110146 Page 1 of CHiddenWindow.h
541bc3 //////////////////////////////////////////////////////////////////////////////
0ee88a // CHiddenWindow.h
6b465d //
20bb61 // Declaration of class CHiddenWindow..
981bc3 //////////////////////////////////////////////////////////////////////////////
87af5a
9fc8f5 // $Id: CHiddenWindow.h,v 1.3.2.5 1998/07/06 08:58:35 nryan Exp $
deaf5a
2acbce // Copyright (C) 1998 by Network Associates, Inc.
a571ae // All rights reserved.
41af5a
348934 #ifndef Included_CHiddenWindow_h // [
60dc00 #define Included_CHiddenWindow_h
36af5a
b53a85 #include "DualErr.h"
39af5a
c2af5a
f417a3 //////////////////////
d23680 // Class CHiddenWindow
ca17a3 //////////////////////
6baf5a
5230b3 class CHiddenWindow : public CWnd
b1bb36 {
195ed4 public:
9e4a4d ¤   ¤   ¤   CHiddenWindow();
5edae2 ¤   virtual¤~CHiddenWindow();
c6af5a
2f0b37 ¤   //{{AFX_VIRTUAL(CHiddenWindow)
5daf53 ¤   //}}AFX_VIRTUAL
bcaf5a
58a2d3 protected:
e9b012 ¤   PGPBoolean¤ mAutoUnmount;¤  ¤   ¤   ¤   // auto-unmount enabled?
1de5d6 ¤   PGPBoolean¤ mHotKeyEnabled;¤¤   ¤   ¤   // unmount hotkey enabled?
3529a5 ¤   PGPUInt16¤  mHotKeyCode;¤   ¤   ¤   ¤   // hot key codes
d017b7 ¤   PGPBoolean¤ mUnmountOnSleep;¤   ¤   ¤   // unmount on sleep?
d6687c ¤   PGPBoolean¤ mNoSleepIfUnmountFail;¤ ¤   // no sleep unmount fails?
6c59d2 ¤   PGPUInt32¤  mUnmountTimeout;¤   ¤   ¤   // mins b4 auto-unmount
2daf5a
305ee9 ¤   PGPBoolean¤ mIsHotKeyRegistered;¤   ¤   // hot key currently registered?
6daf5a
8c7302 ¤   //{{AFX_MSG(CHiddenWindow)
46860e ¤   afx_msg void OnEndSession(WPARAM wParam, LPARAM lParam);
d43529 ¤   afx_msg void OnNewPrefs(WPARAM wParam, LPARAM lParam);
8704b1 ¤   afx_msg void OnHotKey(WPARAM wParam, LPARAM lParam);
f61416 ¤   afx_msg int OnPowerBroadcast(WPARAM wParam, LPARAM lParam);
2bc61b ¤   afx_msg void OnClose();
78cc17 ¤   afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
262e09 ¤   //}}AFX_MSG
9caf5a
f70faf ¤   DualErr¤SendRequestToApp(LPCSTR command);
331016 ¤   DualErr¤UnmountAllPGPdisks();
27be8b ¤   void¤   UpdateHotKey();
2c39db ¤   void¤   UpdatePrefs();
2aaf5a
a02409 ¤   DECLARE_MESSAGE_MAP()
7a82f7 };
48af5a
186186 #endif // Included_CHiddenWindow_h
--4ebe 000f0a3669640110147 Page 1 of CPGPdiskResidentApp.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
aa76cc // CPGPdiskResidentApp.cpp
ea465d //
653b61 // Implementation of class CPGPdiskResidentApp.
e31bc3 //////////////////////////////////////////////////////////////////////////////
43af5a
2f57ee // $Id: CPGPdiskResidentApp.cpp,v 1.2.2.7 1998/07/30 00:50:27 nryan Exp $
a8af5a
3dcbce // Copyright (C) 1998 by Network Associates, Inc.
5271ae // All rights reserved.
83af5a
939e12 #include "StdAfx.h"
79af5a
5e9bcf #include "Required.h"
a8ac00 #include "DriverComm.h"
923a85 #include "DualErr.h"
457efd #include "LinkResolution.h"
22cd22 #include "PGPdiskResidentDefines.h"
ff993c #include "StringAssociation.h"
cadd74 #include "WindowsVersion.h"
92af5a
e266a0 #include "CPGPdiskResidentApp.h"
87af5a
dfaf5a
bc83f5 ///////////////////////////
8caeb4 // Global variables for MFC
2b83f5 ///////////////////////////
7daf5a
be8c2d CPGPdiskResidentApp theApp;¤¤   // the one and only application
c5af5a
dfaf5a
9504c6 ///////////////////////////////////////
5d6aed // Global variables for the application
e504c6 ///////////////////////////////////////
74af5a
809988 CPGPdiskResidentApp *App;¤  ¤   ¤   // pointer to application object
24af5a
14af5a
9583f5 ///////////////////////////
58b249 // MFC specific definitions
3c83f5 ///////////////////////////
71af5a
ce0455 // MFC message map
fcaf5a
c95b64 BEGIN_MESSAGE_MAP(CPGPdiskResidentApp, CWinApp)
557b7f ¤   //{{AFX_MSG_MAP(CPGPdiskResidentApp)
092e09 ¤   //}}AFX_MSG
57af28 END_MESSAGE_MAP()
12af5a
e8af5a
bfa6b9 ///////////////////////////////////////////////////////////////////////
fcf1e9 // CPGPdiskResidentApp public custom functions and non-default handlers
7da6b9 ///////////////////////////////////////////////////////////////////////
ccaf5a
cbcba7 // The CPGPdiskResidentApp constructor.
24af5a
188ce2 CPGPdiskResidentApp::CPGPdiskResidentApp()
96bb36 {
0aa669 ¤   App = this;
7faf5a
62a9dc ¤   mHiddenWindow = NULL;
57d904 ¤   mPGPdiskResInfo = NULL;
8befe6 }
59af5a
78af5a
309bef //////////////////////////////////////////////
a3f33b // CPGPdiskResidentApp public default handlers
0e9bef //////////////////////////////////////////////
59af5a
f340b1 // AbortPGPdiskResApp is the correct way to abort.
4baf5a
f0c823 void·
--a742 00038d1100c40110147 Page 2 of CPGPdiskResidentApp.cpp
fcb7ae CPGPdiskResidentApp::AbortPGPdiskResApp()
3abb36 {
2bd7ea ¤   exit(-1);
43efe6 }
45af5a
cbead3 // ExitInstance is called when the app is exiting.
eeaf5a
50fcf4 int·
720b2e CPGPdiskResidentApp::ExitInstance()·
06bb36 {
2b7d36 ¤   DualErr derr;
52af5a
63068e ¤   // Destroy our shared memory.
fdcf0e ¤   derr = DeletePGPdiskResInfo();
7f3afe ¤   pgpAssert(derr.IsntError());
6baf5a
f530c1 ¤   // Delete the hidden window.
841a3d ¤   DeleteHiddenWindow();
91af5a
42f832 ¤   // Close the driver.
ac5536 ¤   derr = ClosePGPdiskDriver();
d13afe ¤   pgpAssert(derr.IsntError());
4baf5a
ffc23f ¤   // Cleanup explicit linkage.
661c25 ¤   CleanupExplicitLinkage();
59af5a
75ecec ¤   return CWinApp::ExitInstance();
c0efe6 }
daaf5a
05af5a
ca191f // InitInstance is called to initialize the app.
ebaf5a
437efe BOOL·
03b9ae CPGPdiskResidentApp::InitInstance()
c0bb36 {
d37d36 ¤   DualErr derr;
faaf5a
9d41d5 ¤   // Check Windows version.
2fa255 ¤   CheckWindowsVersion();
e2af5a
753d5e ¤   // Resolve APIs unique to a platform.
51f1de ¤   derr = ExplicitlyLinkAPIsForPlatform();
b1af5a
c30626 ¤   // There can be only one!
602361 ¤   if (derr.IsntError())
a2c7a1 ¤   {
395282 ¤   ¤   EnforceUniquePGPdiskResApp();
91af5a
618a21 ¤   ¤   // Create our hidden window.
d4bd2b ¤   ¤   derr = CreateHiddenWindow();
9f9371 ¤   }
6aaf5a
b8b1f4 ¤   // Open the driver.
a42361 ¤   if (derr.IsntError())
e4c7a1 ¤   {
c946c3 ¤   ¤   derr = OpenPGPdiskDriver();
bb9371 ¤   }
12af5a
799af5 ¤   // Create our shared info structure.
db2361 ¤   if (derr.IsntError())
d8c7a1 ¤   {
be6934 ¤   ¤   derr = CreatePGPdiskResInfo();
6c9371 ¤   }
68af5a
752361 ¤   if (derr.IsntError())
16c7a1 ¤   {
52836c ¤   ¤   return TRUE;
479371 ¤   }
240e24 ¤   else
95c7a1 ¤   {
c6b37c ¤   ¤   ReportError(kPGDMajorError_ResidentAppInitFailed, derr);
3898aa ¤   ¤   return FALSE;
--2265 000f50edb5c40110147 Page 3 of CPGPdiskResidentApp.cpp
a19371 ¤   }
c9efe6 }
a0af5a
67af5a
4bda3d ////////////////////////////////////////////////////////////////////////
17f443 // CPGPdiskResidentApp private custom functions and non-default handlers
c7da3d ////////////////////////////////////////////////////////////////////////
a1af5a
c4d6d3 // CheckWindowsVersion exits if we are running an incompatible version of
5174f7 // Windows.
2faf5a
6dc823 void·
8fe78e CPGPdiskResidentApp::CheckWindowsVersion()
05bb36 {
16e20f ¤   if (!IsWin95CompatibleMachine() && !IsWinNT4CompatibleMachine())
36c7a1 ¤   {
46f77b ¤   ¤   ReportError(kPGDMajorError_NotCompatibleWindows);
0565ee ¤   ¤   AbortPGPdiskResApp();
979371 ¤   }
9cefe6 }
7caf5a
5be1d7 // EnforceUniquePGPdiskResApp croaks the app if an instance is already
1d5f6c // running.
02af5a
88c823 void·
d2a90c CPGPdiskResidentApp::EnforceUniquePGPdiskResApp()
84bb36 {
6b7d36 ¤   DualErr derr;
94af5a
36be54 ¤   derr = mResInfoSharedMem.Attach(kPGPdiskResSharedMemName);
fdaf5a
9b2361 ¤   if (derr.IsntError())
be65ee ¤   ¤   AbortPGPdiskResApp();
a5efe6 }
1baf5a
727814 // CreateHiddenWindow creates the hidden window.
a5af5a
122292 DualErr·
98709c CPGPdiskResidentApp::CreateHiddenWindow()
84bb36 {
b9be41 ¤   DualErr¤¤   derr;
0eb4d5 ¤   PGPBoolean¤ createdHiddenWindow¤= FALSE;
9baf5a
1878f1 ¤   try
14c7a1 ¤   {
349596 ¤   ¤   // Register our class name.
656556 ¤   ¤   mHiddenWindowClass = AfxRegisterWndClass(WS_OVERLAPPED);
02af5a
0b238b ¤   ¤   // Allocate the window.
d14ee8 ¤   ¤   mHiddenWindow = new CHiddenWindow;
ab9371 ¤   }
3d3c88 ¤   catch (CMemoryException *ex)
b7c7a1 ¤   {
b6ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
966adc ¤   ¤   ex->Delete();
449371 ¤   }
4faf5a
035e23 ¤   createdHiddenWindow = derr.IsntError();
fbaf5a
30796b ¤   // Create the actual window.
f12361 ¤   if (derr.IsntError())
f3c7a1 ¤   {
0fb8d2 ¤   ¤   if (!mHiddenWindow->CreateEx(NULL, mHiddenWindowClass,·
57f888 ¤   ¤   ¤   kPGPdiskResWindowTitle, WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL,·
3da6a5 ¤   ¤   ¤   NULL))
935b34 ¤   ¤   {
2241ba ¤   ¤   ¤   derr = DualErr(kPGDMinorError_WindowCreationFailed);
e80fe4 ¤   ¤   }
1a9371 ¤   }
90af5a
ba2361 ¤   if (derr.IsntError())
f5c7a1 ¤   {
--3902 001c37cc71340110147 Page 4 of CPGPdiskResidentApp.cpp
6d0d46 ¤   ¤   m_pMainWnd = mHiddenWindow;
629371 ¤   }
eeaf5a
1f4bb3 ¤   if (derr.IsError())
6cc7a1 ¤   {
cfbda5 ¤   ¤   if (createdHiddenWindow)
d35b34 ¤   ¤   {
434975 ¤   ¤   ¤   delete mHiddenWindow;
981780 ¤   ¤   ¤   mHiddenWindow = NULL;
a60fe4 ¤   ¤   }
e59371 ¤   }
4caf5a
6f33e3 ¤   return derr;
d1efe6 }
87af5a
d7c996 // DeleteHiddenWindow destroys the hidden window.
b0af5a
66c823 void·
deb74f CPGPdiskResidentApp::DeleteHiddenWindow()
96bb36 {
c6ff41 ¤   if (IsntNull(mHiddenWindow))
67c7a1 ¤   {
187e7d ¤   ¤   delete mHiddenWindow;
eb2088 ¤   ¤   mHiddenWindow = NULL;
469371 ¤   }
73efe6 }
62af5a
cd9940 // CreatePGPdiskResInfo allocates our shared application info structure.
15af5a
092292 DualErr·
e73fde CPGPdiskResidentApp::CreatePGPdiskResInfo()
7abb36 {
087d36 ¤   DualErr derr;
bcaf5a
126d0a ¤   pgpAssertAddrValid(mHiddenWindow, CHiddenWindow);
52af5a
68189f ¤   derr = mResInfoSharedMem.CreateAndAttach(kPGPdiskResSharedMemName,·
69ac82 ¤   ¤   sizeof(PGPdiskResInfo));
93af5a
142361 ¤   if (derr.IsntError())
70c7a1 ¤   {
060147 ¤   ¤   // Get shared memory pointer.
32c4c3 ¤   ¤   mPGPdiskResInfo = (PGPdiskResInfo *)·
6c4fc0 ¤   ¤   ¤   mResInfoSharedMem.GetMemPointer();
3caf5a
980b70 ¤   ¤   // Initialize the shared memory object.
4890a2 ¤   ¤   mPGPdiskResInfo->hiddenWindowHwnd = mHiddenWindow->m_hWnd;
249371 ¤   }
63af5a
d133e3 ¤   return derr;
15efe6 }
5baf5a
14cc8d // DeletePGPdiskResInfo deletes our shared application info structure.
62af5a
172292 DualErr·
03f83e CPGPdiskResidentApp::DeletePGPdiskResInfo()
5dbb36 {
ac7d36 ¤   DualErr derr;
4aaf5a
17fdfa ¤   if (IsntNull(mPGPdiskResInfo))
c3c7a1 ¤   {
4d0fde ¤   ¤   pgpAssertAddrValid(mPGPdiskResInfo, PGPdiskResInfo);
95af5a
a20b33 ¤   ¤   derr = mResInfoSharedMem.Detach();
4d745a ¤   ¤   mPGPdiskResInfo = NULL;
8f9371 ¤   }
62af5a
2333e3 ¤   return derr;
c3efe6 }
--b6fa 001fea0f4ff40110148 Page 1 of CPGPdiskResidentApp.h
541bc3 //////////////////////////////////////////////////////////////////////////////
ab1165 // CPGPdiskResidentApp.h
1a465d //
9caf05 // Declaration of class CPGPdiskResidentApp.
681bc3 //////////////////////////////////////////////////////////////////////////////
96af5a
e73679 // $Id: CPGPdiskResidentApp.h,v 1.2.2.3 1998/07/06 08:58:36 nryan Exp $
50af5a
04cbce // Copyright (C) 1998 by Network Associates, Inc.
c571ae // All rights reserved.
01af5a
0cfb4d #ifndef Included_CPGPdiskResidentApp_h // [
74bd3f #define Included_CPGPdiskResidentApp_h
1caf5a
673a85 #include "DualErr.h"
506673 #include "SharedMemory.h"
846560 #include "Win32Utils.h"
a2af5a
b376a0 #include "CHiddenWindow.h"
54af5a
06af5a
c15270 ////////////////////////////
ac08e9 // Class CPGPdiskResidentApp
525270 ////////////////////////////
0baf5a
ffc934 class CPGPdiskResidentApp : public CWinApp
c6bb36 {
2b5ed4 public:
e4e4c7 ¤   CHiddenWindow¤  *mHiddenWindow;
b9f42c ¤   CString¤¤   ¤   mHiddenWindowClass;
8310cf ¤   PGPdiskResInfo¤ *mPGPdiskResInfo;
f3af5a
119303 ¤   ¤   ¤   CPGPdiskResidentApp();
0daf5a
00d970 ¤   void¤   AbortPGPdiskResApp();
d8af5a
8ecc6b ¤   //{{AFX_VIRTUAL(CPGPdiskResidentApp)
0b67d4 ¤   public:
4a019a ¤   virtual BOOL InitInstance();
341c2f ¤   virtual int ExitInstance();
34af53 ¤   //}}AFX_VIRTUAL
efaf5a
fe50ef ¤   //{{AFX_MSG(CPGPdiskResidentApp)
922e09 ¤   //}}AFX_MSG
68af5a
3a0fb9 private:
73bc46 ¤   SharedMemory mResInfoSharedMem;
50af5a
17cb36 ¤   void¤   CheckWindowsVersion();
be13d8 ¤   void¤   EnforceUniquePGPdiskResApp();
45af5a
1d9243 ¤   DualErr¤CreateHiddenWindow();
232ff7 ¤   void¤   DeleteHiddenWindow();
70af5a
461b54 ¤   DualErr¤CreatePGPdiskResInfo();
e7fc9d ¤   DualErr¤DeletePGPdiskResInfo();
4aaf5a
bf2409 ¤   DECLARE_MESSAGE_MAP()
fb82f7 };
a1af5a
1cc18c //{{AFX_INSERT_LOCATION}}
09af5a
fe8297 #endif // Included_CPGPdiskResidentApp_h
--1ffa 001f8ddb00340110149 Page 1 of Globals.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b6c9cd // Globals.h
73465d //
6e3be4 // Contains extern declarations for global variables.
221bc3 //////////////////////////////////////////////////////////////////////////////
54af5a
573f06 // $Id: Globals.h,v 1.2.2.2 1998/07/06 08:58:37 nryan Exp $
12af5a
11cbce // Copyright (C) 1998 by Network Associates, Inc.
8071ae // All rights reserved.
43af5a
af7e7c #ifndef Included_Globals_h¤ // [
ee80bb #define Included_Globals_h
b9af5a
9466a0 #include "CPGPdiskResidentApp.h"
0caf5a
25af5a
58c7c6 ///////////////////////////////
2b269b // Global variable declarations
15c7c6 ///////////////////////////////
c1af5a
f78fd4 // All of the global variables are defined in CPGPdiskResident.cpp.
53af5a
65f54f extern CPGPdiskResidentApp *App;¤   ¤   // pointer to application object
96af5a
f83932 #endif¤ // ] Included_Globals_h
--8692 001059c732c4011014a Page 1 of Resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
869c33 // Used by C:\OldSource\clients\disk\win32\PGPdiskResident\PGPdiskResident.rc
91465d //
6109d3 #define IDD_ABOUTBOX ···················100
ca2853 #define IDR_MAINFRAME ··················128
e8fcee #define IDR_PGPDISTYPE ·················129
2caf5a
3111aa // Next default values for new objects
44ac6a //·
51f860 #ifdef APSTUDIO_INVOKED
903f23 #ifndef APSTUDIO_READONLY_SYMBOLS
7f4617 #define _APS_NEXT_RESOURCE_VALUE ·······130
1cb061 #define _APS_NEXT_COMMAND_VALUE ········32771
a2f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
511285 #define _APS_NEXT_SYMED_VALUE ··········101
947454 #endif
057454 #endif
--ff08 00114e77f694011014b Page 1 of StdAfx.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
77fc35 // StdAfx.cpp
06465d //
c0afe4 // MFC source.
d41bc3 //////////////////////////////////////////////////////////////////////////////
36af5a
a63cb6 // $Id: StdAfx.cpp,v 1.1.2.1 1998/05/29 17:16:56 nryan Exp $
a2af5a
e2d221 // Not really Copyright (C) 1998 by Network Associates, Inc.
32af5a
149e12 #include "StdAfx.h"
--01b0 001abfc6f074011014c Page 1 of StdAfx.h
541bc3 //////////////////////////////////////////////////////////////////////////////
465fb0 // StdAfx.h
01465d //
7120f8 // Contains global MFC includes.
081bc3 //////////////////////////////////////////////////////////////////////////////
82af5a
4980d7 // $Id: StdAfx.h,v 1.1.2.1 1998/05/29 17:16:57 nryan Exp $
47af5a
ecd221 // Not really Copyright (C) 1998 by Network Associates, Inc.
8571ae // All rights reserved.
91af5a
6196d7 #ifndef Included_StdAfx_h¤  // [
f54653 #define Included_StdAfx_h
a8af5a
cf6b7d #include <afxwin.h> ········// MFC core and standard components
62be9b #include <afxext.h> ········// MFC extensions
0e7e9c #include <afxdisp.h> ·······// MFC OLE automation classes
8daef9 #ifndef _AFX_NO_AFXCMN_SUPPORT
06eb71 #include <afxcmn.h>¤¤   ¤   // MFC support for Windows Common Controls
319db5 #endif // _AFX_NO_AFXCMN_SUPPORT
dbaf5a
c1c18c //{{AFX_INSERT_LOCATION}}
23af5a
ab242f #endif¤ // ] Included_StdAfx_h
--d41b 001d5f2dd874011014d Page 1 of PGPdiskShellExt.def
dfb261 LIBRARY ·····PGPdskSE
c6678f DESCRIPTION ·'PGPdisk Shell Extension'
66af5a
68ef2b EXPORTS
3a476b ····DllCanUnloadNow ············@1 PRIVATE ·········;DLL unloading
d5ff14 ····DllGetClassObject ··········@2 PRIVATE ·········;Component object model
--7cb8 001f5c3cb3e4011014e Page 1 of PGPdiskShellExt.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
2229f7 #include "Source\Resource.h"
28af5a
2be1bf #define APSTUDIO_READONLY_SYMBOLS
196c0e /////////////////////////////////////////////////////////////////////////////
2f465d //
d00131 // Generated from the TEXTINCLUDE 2 resource.
19465d //
58897a #include "afxres.h"
2daf5a
8d6c0e /////////////////////////////////////////////////////////////////////////////
287b93 #undef APSTUDIO_READONLY_SYMBOLS
ceaf5a
cb6c0e /////////////////////////////////////////////////////////////////////////////
04f930 // English (U.S.) resources
2baf5a
cd1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
d4ec08 #ifdef _WIN32
ebe912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
e59c1c #pragma code_page(1252)
e21f8e #endif //_WIN32
e5af5a
9cf860 #ifdef APSTUDIO_INVOKED
5d6c0e /////////////////////////////////////////////////////////////////////////////
12465d //
895733 // TEXTINCLUDE
91465d //
e0af5a
ea86ef 1 TEXTINCLUDE DISCARDABLE·
414523 BEGIN
b1df56 ····"Source\\Resource.h\0"
6ae0d1 END
a4af5a
417037 2 TEXTINCLUDE DISCARDABLE·
1b4523 BEGIN
01eb23 ····"#include ""afxres.h""\r\n"
f8db5c ····"\0"
f6e0d1 END
f1af5a
ce227f 3 TEXTINCLUDE DISCARDABLE·
c74523 BEGIN
01a3cc ····"#include ""PGPdiskShellExtVer.rc""\0"
5ae0d1 END
b9af5a
b069ab #endif ···// APSTUDIO_INVOKED
d8af5a
1c1b3a #endif ···// English (U.S.) resources
c96c0e /////////////////////////////////////////////////////////////////////////////
85af5a
69af5a
1aaf5a
61ce8c #ifndef APSTUDIO_INVOKED
bf6c0e /////////////////////////////////////////////////////////////////////////////
e4465d //
428464 // Generated from the TEXTINCLUDE 3 resource.
ec465d //
49b034 #include "PGPdiskShellExtVer.rc"
726c0e /////////////////////////////////////////////////////////////////////////////
cc8072 #endif ···// not APSTUDIO_INVOKED
f5af5a
--063f 0013ca5b2d34011014f Page 1 of PGPdiskShellExtVer.rc
b3eddb // VERSIONINFO structure which automatically include version
f014b6 // string from PGPdiskVersion.h
a6465d //
ed0380 #include <winver.h>
7b5a72 #include "..\Shared\PGPdiskVersion.h"
2aaf5a
016c0e /////////////////////////////////////////////////////////////////////////////
64465d //
29c5f2 // Version
f4465d //
5faf5a
0a8df2 VS_VERSION_INFO VERSIONINFO
e75e85 ·FILEVERSION kPGPdiskFileVerData
e16589 ·PRODUCTVERSION kPGPdiskProductVerData
29a381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
4b1f29 #ifdef _DEBUG
637c0e ·FILEFLAGS VS_FF_DEBUG
6cdb21 #else
db12ca ·FILEFLAGS 0x0L
e57454 #endif
e003bb ·FILEOS VOS__WINDOWS32
1b5212 ·FILETYPE VFT_DLL
f87247 ·FILESUBTYPE VFT2_UNKNOWN
844523 BEGIN
a32c72 ····BLOCK "StringFileInfo"
445574 ····BEGIN
6d70ac ········BLOCK "040904b0"
3a52d6 ········BEGIN
74f777 ············VALUE "CompanyName", kPGPdiskCompanyName
1173c9 ············VALUE "FileDescription", "PGPdisk Shell Extension\0"
7e126d ············VALUE "FileVersion", kPGPdiskFileVerString
f36ca0 ············VALUE "InternalName", "PGPdskSE.dll\0"
64f2bf ············VALUE "LegalCopyright", kPGPdiskCopyright
aebb30 ············VALUE "OriginalFilename", "PGPdskSE.dll\0"
3f1fa9 ············VALUE "ProductName", kPGPdiskProductVerName
9e7b64 ············VALUE "ProductVersion", kPGPdiskProductVerString
20f37f ········END
267d01 ····END
dd26ab ····BLOCK "VarFileInfo"
4d5574 ····BEGIN
bc4b11 ········VALUE "Translation", 0x409, 1200
6b7d01 ····END
3ce0d1 END
--029c 0004eb1acc540110150 Page 1 of CPGPdiskShellExtDll.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
4d300e // CPGPdiskShellExtDll.cpp
14465d //
37d714 // Definition of class CPGPdiskShellExtDll and DLL exported functions.
221bc3 //////////////////////////////////////////////////////////////////////////////
91af5a
1b2763 // $Id: CPGPdiskShellExtDll.cpp,v 1.1.2.3.2.1 1998/08/22 01:55:38 nryan Exp $
3caf5a
5bcbce // Copyright (C) 1998 by Network Associates, Inc.
3071ae // All rights reserved.
9aaf5a
e59e12 #include "StdAfx.h"
1faf5a
ea9bcf #include "Required.h"
12ac00 #include "DriverComm.h"
557efd #include "LinkResolution.h"
ecdd74 #include "WindowsVersion.h"
4daf5a
f480a4 #include "CPGPdiskShellExtDll.h"
9a47f5 #include "CShellExtClassFactory.h"
23af5a
d3af5a
4c09b7 ////////////
05e738 // Constants
3609b7 ////////////
9baf5a
0d0b17 // Initialize GUIDs (should be done only and at-least once per DLL/EXE).
84af5a
5ac28b #pragma data_seg(".text")
a4af5a
0c841d #define INITGUID
5d0cbc #include <initguid.h>
fa961d #include <shlguid.h>
3caf5a
03a31d DEFINE_GUID(CLSID_ShellExtension,·
74a0f3 ¤   ¤   ¤   0xf8b14440L,·
259016 ¤   ¤   ¤   0x3785, 0x11d1,·
3cd8b3 ¤   ¤   ¤   0xb3, 0x63, 0x5c, 0x6f, 0x08, 0xc1, 0x00, 0x00);
49af5a
66d116 #pragma data_seg()
f7af5a
a2af5a
8483f5 ///////////////////////////
39aeb4 // Global variables for MFC
7283f5 ///////////////////////////
c3af5a
ca9195 CPGPdiskShellExtDll theApp;
a4af5a
e2af5a
4fc7c6 ///////////////////////////////
819e24 // Global variables for the DLL
30c7c6 ///////////////////////////////
c2af5a
b5d5e7 CPGPdiskShellExtDll *DLL;¤  ¤   // pointer to DLL object
1aaf5a
7baf5a
2e83f5 ///////////////////////////
3fb249 // MFC specific definitions
7b83f5 ///////////////////////////
47af5a
3d0455 // MFC message map
b8af5a
bfaefb BEGIN_MESSAGE_MAP(CPGPdiskShellExtDll, CWinApp)
6d9a5d ¤   //{{AFX_MSG_MAP(CPGPdiskShellExtDll)
df2e09 ¤   //}}AFX_MSG
dcaf28 END_MESSAGE_MAP()
87af5a
1aaf5a
5ba6b9 ///////////////////////////////////////////////////////////////////////
ccbdf9 // CPGPdiskShellExtDll public custom functions and non-default handlers
b5a6b9 ///////////////////////////////////////////////////////////////////////
4eaf5a
--ae08 000c681c15340110150 Page 2 of CPGPdiskShellExtDll.cpp
1c0aa9 // The CPGPdiskShellExtDll constructor.
9baf5a
1b60a1 CPGPdiskShellExtDll::CPGPdiskShellExtDll()
0cbb36 {
caf028 ¤   DLL = this;
aaaf5a
3320a4 ¤   mGCRefThisDll = 0;
4defe6 }
41af5a
7bc2c2 // The CPGPdiskShellExtDll destructor.
9eaf5a
8b146e CPGPdiskShellExtDll::~CPGPdiskShellExtDll()
b2bb36 {
aaefe6 }
c8af5a
433967 // ExitInstance is called when the DLL is unloading.
87af5a
90fcf4 int·
e3dbb6 CPGPdiskShellExtDll::ExitInstance()
85bb36 {
637d36 ¤   DualErr derr;
b1af5a
8d9a2c ¤   if (IsDriverOpen())
47a2cd ¤   ¤   ClosePGPdiskDriver();
5aaf5a
3d1c25 ¤   CleanupExplicitLinkage();
d4af5a
cdecec ¤   return CWinApp::ExitInstance();
9eefe6 }
2faf5a
55af5a
60e953 // InitInstance is called during DLL initialization.
aeaf5a
e87efe BOOL·
ea7ac7 CPGPdiskShellExtDll::InitInstance()
38bb36 {
fb7d36 ¤   DualErr derr;
74af5a
fbffd6 ¤   derr = CheckWindowsVersion();
34af5a
ea2361 ¤   if (derr.IsntError())
27c7a1 ¤   {
56e98e ¤   ¤   derr = ExplicitlyLinkAPIsForPlatform();
369371 ¤   }
ebaf5a
142361 ¤   if (derr.IsntError())
b0c7a1 ¤   {
7246c3 ¤   ¤   derr = OpenPGPdiskDriver();
ef9371 ¤   }
f8af5a
e92361 ¤   if (derr.IsntError())
b3c7a1 ¤   {
87b0a1 ¤   ¤   derr = CheckDriverVersion();
089371 ¤   }
60af5a
d964a3 ¤   // DON'T bug user on error, just fail to load.
8b9933 ¤   return derr.IsntError();
e7efe6 }
daaf5a
8aaf5a
b2da3d ////////////////////////////////////////////////////////////////////////
24e48e // CPGPdiskShellExtDll private custom functions and non-default handlers
b5da3d ////////////////////////////////////////////////////////////////////////
94af5a
c4eabc // CheckWindowsVersion checks if we are running an incompatible version of
6874f7 // Windows.
fdaf5a
442292 DualErr·
93093c CPGPdiskShellExtDll::CheckWindowsVersion()
76bb36 {
8d7d36 ¤   DualErr derr;
c6af5a
--4121 001088df47940110150 Page 3 of CPGPdiskShellExtDll.cpp
f8e20f ¤   if (!IsWin95CompatibleMachine() && !IsWinNT4CompatibleMachine())
3ec7a1 ¤   {
080b8e ¤   ¤   derr = DualErr(kPGDMinorError_NotCompatibleWindows);
879371 ¤   }
54af5a
8a33e3 ¤   return derr;
6fefe6 }
abaf5a
dfaf5a
3c6cc2 /////////////////////
f813d2 // Exported functions
cc6cc2 /////////////////////
38af5a
9ed847 // DllCanUnloadNow is called to determine whether it is OK to unload this
e92048 // DLL.
62af5a
48e6b9 STDAPI·
0baedb DllCanUnloadNow()
40bb36 {
25de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
efaf5a
42fa26 ¤   if (DLL->mGCRefThisDll == 0)
c7a5c1 ¤   ¤   return AfxDllCanUnloadNow();
030e24 ¤   else
1493bf ¤   ¤   return S_FALSE;
f4efe6 }
9baf5a
88cb9c // DllGetClassObject returns the class object for the shell extension.
28af5a
1fe6b9 STDAPI·
e1c7e7 DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
99bb36 {
5aaaca ¤   CShellExtClassFactory¤  *pcf;
eed9d8 ¤   PGPBoolean¤ ¤   ¤   ¤   madeInterface, makeInterface;
2caf5a
33de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
91af5a
61ec35 ¤   // Fail if factory or extension still active
c14040 ¤   if (DLL->mGCRefThisDll > 0)
996a5b ¤   ¤   return CLASS_E_CLASSNOTAVAILABLE;
efaf5a
069f1d ¤   (* ppvOut) = NULL;
a9af5a
87a036 ¤   // Do we make an interface?
9879a7 ¤   makeInterface = IsEqualIID(rclsid, CLSID_ShellExtension);
03af5a
004e72 ¤   if (makeInterface)
d8c7a1 ¤   {
7941f1 ¤   ¤   try
cd5b34 ¤   ¤   {
342f75 ¤   ¤   ¤   pcf = new CShellExtClassFactory;¤
c51c30 ¤   ¤   ¤   madeInterface = TRUE;
880fe4 ¤   ¤   }
ab01e0 ¤   ¤   catch (CMemoryException *ex)
d45b34 ¤   ¤   {
e000dc ¤   ¤   ¤   madeInterface = FALSE;
dcad69 ¤   ¤   ¤   ex->Delete();
fb0fe4 ¤   ¤   }
699371 ¤   }
34af5a
e954c2 ¤   if (makeInterface && madeInterface)
abbd38 ¤   ¤   return pcf->QueryInterface(riid, ppvOut);
380e24 ¤   else
1c6a5b ¤   ¤   return CLASS_E_CLASSNOTAVAILABLE;
08efe6 }
--10a7 0016f66c82e40110151 Page 1 of CPGPdiskShellExtDll.h
541bc3 //////////////////////////////////////////////////////////////////////////////
271394 // CPGPdiskShellExtDll.h
b3465d //
3fc2af // Declarations for CPGPdiskShellExtDll.cpp
951bc3 //////////////////////////////////////////////////////////////////////////////
bbaf5a
ebae6e // $Id: CPGPdiskShellExtDll.h,v 1.1.2.3 1998/07/30 00:50:29 nryan Exp $
b6af5a
bbcbce // Copyright (C) 1998 by Network Associates, Inc.
9c71ae // All rights reserved.
47af5a
7b56d9 #ifndef Included_CPGPdiskShellExtDll_h // [
3abfce #define Included_CPGPdiskShellExtDll_h
deaf5a
8e3a85 #include "DualErr.h"
36af5a
64af5a
9a5270 ////////////////////////////
f1146f // Class CPGPdiskShellExtDll
435270 ////////////////////////////
8baf5a
1b3730 class CPGPdiskShellExtDll : public CWinApp
7fbb36 {
7a5ed4 public:
d45414 ¤   PGPUInt32 mGCRefThisDll;
3eaf5a
82ed50 ¤   CPGPdiskShellExtDll();
cf2c07 ¤   ~CPGPdiskShellExtDll();
dfaf5a
ed7fbe ¤   //{{AFX_VIRTUAL(CPGPdiskShellExtApp)
f167d4 ¤   public:
601c2f ¤   virtual int ExitInstance();
bf019a ¤   virtual BOOL InitInstance();
10af53 ¤   //}}AFX_VIRTUAL
b4af5a
d4e33a ¤   //{{AFX_MSG(CPGPdiskShellExtApp)
512e09 ¤   //}}AFX_MSG
dfaf5a
780fb9 private:
4d5a29 ¤   DualErr CheckWindowsVersion();
69af5a
442409 ¤   DECLARE_MESSAGE_MAP()
3782f7 };
d4af5a
18af5a
f76cc2 /////////////////////
4f13d2 // Exported functions
2b6cc2 /////////////////////
22af5a
2aeccd STDAPI¤ DllCanUnloadNow();
31c0d1 STDAPI¤ DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut);
96af5a
6f7658 #endif¤ // ] Included_CPGPdiskShellExtDll_h
--186e 000273c938740110152 Page 1 of CShellExt.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
935f4d // CShellExt.cpp
2f465d //
1ce510 // Definition of class CShellExt.
2d1bc3 //////////////////////////////////////////////////////////////////////////////
d2af5a
2cd307 // $Id: CShellExt.cpp,v 1.1.2.8.2.1 1998/08/22 01:55:38 nryan Exp $
d4af5a
95cbce // Copyright (C) 1998 by Network Associates, Inc.
6771ae // All rights reserved.
38af5a
799e12 #include "StdAfx.h"
b6af5a
609bcf #include "Required.h"
45ac00 #include "DriverComm.h"
bf3a85 #include "DualErr.h"
b3babe #include "PGPdiskRegistry.h"
9f993c #include "StringAssociation.h"
d6bfe9 #include "UtilityFunctions.h"
066560 #include "Win32Utils.h"
e3dd74 #include "WindowsVersion.h"
d7af5a
6b487c #include "CShellExt.h"
15c411 #include "Globals.h"
55af5a
00af5a
8c09b7 ////////////
d3e738 // Constants
6c09b7 ////////////
94af5a
6948de static LPCSTR¤  kPGPdiskShellExtSendToStringNT¤ = "Send &To";
063c41 static LPCSTR¤  kPGPdiskShellExtSendToStringWin95¤  = "Se&nd To";
c2af5a
18af5a
dbd43e /////////
bb596b // Macros
6dd43e /////////
7faf5a
8f8428 #define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, \
6c6040 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (USHORT)(i)))
7eaf5a
dfaf5a
661c7a //////////////////////////////////////////
4c08a8 // Class CShellExt public member functions
151c7a //////////////////////////////////////////
ccaf5a
ebf4be // The CShellExt default constructor.
d8af5a
e3eb1a CShellExt::CShellExt()
33bb36 {
6c89a5 ¤   mPDataObj¤  = NULL;
d56e4d ¤   mRefCount¤  = 0;
89af5a
516183 ¤   mTargets¤   = NULL;
bd66dd ¤   mNumDropped¤= 0;
b8af5a
ae65b9 ¤   mNumTotalPGPdisks¤  = 0;
c81b66 ¤   mNumMountedPGPdisks¤= 0;
d4af5a
a15db3 ¤   DLL->mGCRefThisDll++;
4eefe6 }
0daf5a
215441 // The CShellExt destructor.
91af5a
4f74e0 CShellExt::~CShellExt()
96bb36 {
7186cc ¤   DeletePathsAndCommandLine();
4daf5a
16c0f0 ¤   DLL->mGCRefThisDll--;
08efe6 }
e0af5a
278405 // QueryInterface returns a pointer to this class object's interface.
--de2a 0007206a83e40110152 Page 2 of CShellExt.cpp
e0af5a
4b287f STDMETHODIMP·
75a129 CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
84bb36 {
d1de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
8baf5a
9a7675 ¤   (* ppv) = NULL;
74af5a
454a9b ¤   if (IsEqualIID(riid, IID_IShellExtInit) ||·
c413bd ¤   ¤   IsEqualIID(riid, IID_IUnknown))
10c7a1 ¤   {
f0e0ce ¤   ¤   (* ppv) = (LPSHELLEXTINIT) this;
4b9371 ¤   }
ec5918 ¤   else if (IsEqualIID(riid, IID_IContextMenu))
c2c7a1 ¤   {
9fccb8 ¤   ¤   (* ppv) = (LPCONTEXTMENU) this;
999371 ¤   }
20af5a
659315 ¤   if (* ppv)
71c7a1 ¤   {
affb5c ¤   ¤   AddRef();
8354df ¤   ¤   return NOERROR;
bc9371 ¤   }
d50e24 ¤   else
79c7a1 ¤   {
2f4df4 ¤   ¤   return E_NOINTERFACE;
c49371 ¤   }
8eefe6 }
0faf5a
34a1c2 // QueryContextMenu is called to construct our context menu.
daaf5a
c5287f STDMETHODIMP·
d71e22 CShellExt::QueryContextMenu(
11dfa1 ¤   HMENU¤  hMenu,·
c84a27 ¤   UINT¤   indexMenu,·
58129b ¤   UINT¤   idCmdFirst, ¤   ¤   ¤   ¤   ¤
4e71c9 ¤   UINT¤   idCmdLast,·
19565c ¤   UINT¤   uFlags)
1bbb36 {
b8be41 ¤   DualErr¤¤   derr;
41ccda ¤   PGPBoolean¤ hasTimedOut, success;
bfb5a2 ¤   PGPUInt32¤  itemPosition, menuId, subMenuPosition;
2267c5 ¤
44de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
3caf5a
effcf8 ¤   menuId = idCmdFirst;
0e8770 ¤   itemPosition = 0;
11af5a
4f7f39 ¤   hasTimedOut = FALSE;
e4af5a
786a4b ¤   // Shift key down?
1fd051 ¤   mShiftKeyDown = (::GetAsyncKeyState(VK_SHIFT) & 0x8000 ? TRUE : FALSE);
b0af5a
3d9d6f ¤   // Beta or demo timed out?
7578b0 ¤   #if PGPDISK_BETAVERSION
db683c ¤   ¤   hasTimedOut = HasBetaTimedOut();
21de32 ¤   #elif PGPDISK_DEMOVERSION
0423b7 ¤   ¤   hasTimedOut = HasDemoTimedOut();
b6d629 ¤   #endif // PGPDISK_BETAVERSION
cdaf5a
8f9c84 ¤   // Only show a menu if we found PGPdisks.
7ebd02 ¤   if (mNumTotalPGPdisks == 0)
f06823 ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
bfaf5a
2bc95a ¤   // There are also other special cases in which we don't show the menu.
f12361 ¤   if (derr.IsntError())
a1c7a1 ¤   {
5759b3 ¤   ¤   if (((uFlags & 0x000F) != CMF_NORMAL) &&·
bfb3a3 ¤   ¤   ¤   !(uFlags & CMF_EXPLORE) && !(uFlags & CMF_VERBSONLY))
365b34 ¤   ¤   {
580710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
720fe4 ¤   ¤   }
--c54e 0005ebe34c940110152 Page 3 of CShellExt.cpp
a19371 ¤   }
93af5a
1928ea ¤   // Save parent menu handle for later.
cb2361 ¤   if (derr.IsntError())
5fc7a1 ¤   {
f61699 ¤   ¤   if (!mParentMenu.Attach(hMenu))
fec507 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_AttachMenuFailed);
119371 ¤   }
f4af5a
5d832a ¤   // Create the submenu.
062361 ¤   if (derr.IsntError())
33c7a1 ¤   {
397cf5 ¤   ¤   if (!mSubMenu.CreatePopupMenu())
a1644f ¤   ¤   ¤   derr = DualErr(kPGDMinorError_CreatePopupMenuFailed);
569371 ¤   }
2baf5a
b7ac6e ¤   // Add items to the menu.
532361 ¤   if (derr.IsntError())
75c7a1 ¤   {
19f729 ¤   ¤   PGPUInt32 flags, sendToPosition;
f9af5a
a259a4 ¤   ¤   flags = MF_BYPOSITION;
99af5a
1c925a ¤   ¤   // Insert open/mount/unmount item.
a59ef6 ¤   ¤   if (mNumTotalPGPdisks > 1)
f05b34 ¤   ¤   {
fbf7ad ¤   ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
44e8a9 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtOpenMenuString));
e9af5a
8a0fe4 ¤   ¤   }
1892d1 ¤   ¤   else if (mNumMountedPGPdisks == 1)
695b34 ¤   ¤   {
47f7ad ¤   ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
aba99e ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtUnmountMenuString));
df0fe4 ¤   ¤   }
740e1d ¤   ¤   else
dd5b34 ¤   ¤   {
5ef7ad ¤   ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
edbfa0 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtMountMenuString));
940fe4 ¤   ¤   }
35af5a
58b1d9 ¤   ¤   // Insert separator.
140bc9 ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags | MF_SEPARATOR, 0);
32af5a
d12ed4 ¤   ¤   // Insert passphrase items.
9050bf ¤   ¤   flags = MF_BYPOSITION | (mNumMountedPGPdisks > 0 ? MF_GRAYED : NULL);
87af5a
b84bb4 ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
723cca ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtAddPassMenuString));
44af5a
0a4bb4 ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
cb992c ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtChangePassMenuString));
39af5a
02a2d3 ¤   ¤   if (mShiftKeyDown)
555b34 ¤   ¤   {
e0f7ad ¤   ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
fd0ec5 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtRemoveAltsMenuString));
b00fe4 ¤   ¤   }
650e1d ¤   ¤   else
a55b34 ¤   ¤   {
8af7ad ¤   ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
3962a5 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtRemovePassMenuString));
150fe4 ¤   ¤   }
09af5a
2a4bb4 ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
78580a ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtPubKeysMenuString));
41af5a
62b1d9 ¤   ¤   // Insert separator.
e178b2 ¤   ¤   flags = MF_BYPOSITION | MF_SEPARATOR;
150bc9 ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags | MF_SEPARATOR, 0);
23af5a
5e9029 ¤   ¤   // Insert help item.
--4317 0008a9a5d8840110152 Page 4 of CShellExt.cpp
0f59a4 ¤   ¤   flags = MF_BYPOSITION;
ed4bb4 ¤   ¤   mSubMenu.InsertMenu(itemPosition++, flags, menuId++,·
c2635a ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtHelpMenuString));
e5af5a
05e453 ¤   ¤   // Find position of "Send To".
9be261 ¤   ¤   if (IsWin95CompatibleMachine())
875b34 ¤   ¤   {
70f7ee ¤   ¤   ¤   sendToPosition = FindMenuItemPosition(&mParentMenu,·
4bbf77 ¤   ¤   ¤   ¤   kPGPdiskShellExtSendToStringWin95);
520fe4 ¤   ¤   }
b10e1d ¤   ¤   else
355b34 ¤   ¤   {
daf7ee ¤   ¤   ¤   sendToPosition = FindMenuItemPosition(&mParentMenu,·
96d597 ¤   ¤   ¤   ¤   kPGPdiskShellExtSendToStringNT);
cd0fe4 ¤   ¤   }
19af5a
9fa083 ¤   ¤   if (sendToPosition == -1)
aeeced ¤   ¤   ¤   subMenuPosition = indexMenu;
9e0e1d ¤   ¤   else
a9cf33 ¤   ¤   ¤   subMenuPosition = sendToPosition + 1;
a2af5a
6f43b8 ¤   ¤   // Insert another separator.
314493 ¤   ¤   mParentMenu.InsertMenu(subMenuPosition++,·
334cdd ¤   ¤   ¤   MF_BYPOSITION | MF_SEPARATOR, 0);
92af5a
e1010a ¤   ¤   // Insert the submenu menu.
f7799f ¤   ¤   success = mParentMenu.InsertMenu(subMenuPosition,·
3dcf93 ¤   ¤   ¤   MF_BYPOSITION | MF_POPUP, (PGPUInt32) mSubMenu.m_hMenu,·
883c65 ¤   ¤   ¤   "&PGPdisk");
35af5a
ee9a3f ¤   ¤   if (!success)
6df798 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InsertMenuFailed);
699371 ¤   }
e3af5a
32951e ¤   return ResultFromShort(itemPosition);
1befe6 }
beaf5a
aefb31 // InvokeCommand is called after the user has selected a menu item.
f7af5a
85287f STDMETHODIMP·
d91267 CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
a0bb36 {
bba380 ¤   HRESULT hr = E_INVALIDARG;
a9af5a
97de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
a0af5a
bb78f1 ¤   try
3cc7a1 ¤   {
55835b ¤   ¤   // If HIWORD(lpcmi->lpVerb) then we have been called programmatically
3014ba ¤   ¤   // and lpVerb is a command that should be invoked. Otherwise, the
2490af ¤   ¤   // shell has called us, and LOWORD(lpcmi->lpVerb) is the menu ID the
67b56b ¤   ¤   // user has selected. Actually, it's (menu ID - idCmdFirst) from
d11a09 ¤   ¤   // QueryContextMenu().
95af5a
8ce4db ¤   ¤   if (!HIWORD(lpcmi->lpVerb))
cd5b34 ¤   ¤   {
2a31c4 ¤   ¤   ¤   CString¤¤   command;
01bd3b ¤   ¤   ¤   PGPBoolean¤ isNonTargeted, sendRequest;
f54688 ¤   ¤   ¤   UINT¤   ¤   idCmd¤  = LOWORD(lpcmi->lpVerb);
8aaf5a
33cf3e ¤   ¤   ¤   hr = NOERROR;
e5af5a
db493f ¤   ¤   ¤   isNonTargeted¤  = FALSE;
e4d0fa ¤   ¤   ¤   sendRequest¤¤   = TRUE;
57af5a
0ded47 ¤   ¤   ¤   switch (idCmd)
82f776 ¤   ¤   ¤   {
3375ac ¤   ¤   ¤   case 0:
8fd149 ¤   ¤   ¤   ¤   if (mNumTotalPGPdisks > 1)
ef36ee ¤   ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskOpenCmdString);
36dbfb ¤   ¤   ¤   ¤   else if (mNumMountedPGPdisks == 1)
8ada2b ¤   ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskUnmountCmdString);
--7870 0005b03a90140110152 Page 5 of CShellExt.cpp
67fa07 ¤   ¤   ¤   ¤   else
a14854 ¤   ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskMountCmdString);
d1f622 ¤   ¤   ¤   ¤   break;
85af5a
7e2f70 ¤   ¤   ¤   case 1:
1d4442 ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskAddPassCmdString);
59f622 ¤   ¤   ¤   ¤   break;
e0af5a
dfc014 ¤   ¤   ¤   case 2:
3800da ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskChangePassCmdString);
e2f622 ¤   ¤   ¤   ¤   break;
94af5a
729ac8 ¤   ¤   ¤   case 3:
6c3a84 ¤   ¤   ¤   ¤   if (mShiftKeyDown)
c7723b ¤   ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskRemoveAltsCmdString);
d0fa07 ¤   ¤   ¤   ¤   else
351cc5 ¤   ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskRemovePassCmdString);
c3f622 ¤   ¤   ¤   ¤   break;
38af5a
6716cd ¤   ¤   ¤   case 4:
94942b ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskPubKeysCmdString);
43f622 ¤   ¤   ¤   ¤   break;
12af5a
be4c11 ¤   ¤   ¤   case 5:
f2a826 ¤   ¤   ¤   ¤   command = GetCommonString(kPGPdiskHelpCmdString);
95776d ¤   ¤   ¤   ¤   isNonTargeted = TRUE;
8df622 ¤   ¤   ¤   ¤   break;
e5af5a
75db68 ¤   ¤   ¤   default:
be5606 ¤   ¤   ¤   ¤   hr = E_INVALIDARG;
3e787c ¤   ¤   ¤   ¤   sendRequest = FALSE;
bef622 ¤   ¤   ¤   ¤   break;
50a3a6 ¤   ¤   ¤   }
c5af5a
e00c93 ¤   ¤   ¤   if (sendRequest)
613830 ¤   ¤   ¤   ¤   SendRequestToApp(command, isNonTargeted);
520fe4 ¤   ¤   }
fa9371 ¤   }
ca3c88 ¤   catch (CMemoryException *ex)
0ac7a1 ¤   {
896adc ¤   ¤   ex->Delete();
3e9371 ¤   }
a0af5a
52776d ¤   return hr;
6aefe6 }
f0af5a
6cda37 // GetCommandString returns the help string associated with a command.
e1af5a
44287f STDMETHODIMP·
bc2bc8 CShellExt::GetCommandString(
506f3d ¤   UINT¤   ¤   idCmd,·
9d5c1e ¤   UINT¤   ¤   uFlags,·
148abc ¤   UINT FAR¤   *reserved,·
c3d5b0 ¤   LPSTR¤  ¤   pszName,·
424bba ¤   UINT¤   ¤   cchMax)
f9bb36 {
18de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
bcaf5a
d778f1 ¤   try
d4c7a1 ¤   {
b0b988 ¤   ¤   CString helpString;
6faf5a
490fa6 ¤   ¤   switch (idCmd)
085b34 ¤   ¤   {
00e2df ¤   ¤   case 0:
5cdf05 ¤   ¤   ¤   if (mNumTotalPGPdisks > 1)
eff776 ¤   ¤   ¤   {
2d5116 ¤   ¤   ¤   ¤   helpString =·
c933ab ¤   ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeOpenString);
9ca3a6 ¤   ¤   ¤   }
1a0349 ¤   ¤   ¤   else if (mNumMountedPGPdisks == 1)
5bf776 ¤   ¤   ¤   {
--c6a5 00034f9feb340110152 Page 6 of CShellExt.cpp
115116 ¤   ¤   ¤   ¤   helpString =·
3ba9b4 ¤   ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeUnmountString);
99a3a6 ¤   ¤   ¤   }
0dbb8c ¤   ¤   ¤   else
9af776 ¤   ¤   ¤   {
3a5116 ¤   ¤   ¤   ¤   helpString =·
7af131 ¤   ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeMountString);
f5a3a6 ¤   ¤   ¤   }
0fcdcb ¤   ¤   ¤   break;
28af5a
d6b803 ¤   ¤   case 1:
ccd842 ¤   ¤   ¤   helpString =·
dfa3d3 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeAddPassString);
9fcdcb ¤   ¤   ¤   break;
49af5a
d25767 ¤   ¤   case 2:
4ad842 ¤   ¤   ¤   helpString =·
b88705 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeChangePassString);
2bcdcb ¤   ¤   ¤   break;
edaf5a
a00dbb ¤   ¤   case 3:
30b6fb ¤   ¤   ¤   if (mShiftKeyDown)
bef776 ¤   ¤   ¤   {
845116 ¤   ¤   ¤   ¤   helpString =·
1da8ab ¤   ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeRemoveAltsString);
80a3a6 ¤   ¤   ¤   }
7ebb8c ¤   ¤   ¤   else
0bf776 ¤   ¤   ¤   {
2c5116 ¤   ¤   ¤   ¤   helpString =·
faddff ¤   ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeRemovePassString);
97a3a6 ¤   ¤   ¤   }
22cdcb ¤   ¤   ¤   break;
cdaf5a
2881be ¤   ¤   case 4:
34d842 ¤   ¤   ¤   helpString =·
720359 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribePubKeysString);
16cdcb ¤   ¤   ¤   break;
26af5a
42db62 ¤   ¤   case 5:
b1d842 ¤   ¤   ¤   helpString =·
8c03f7 ¤   ¤   ¤   ¤   GetCommonString(kPGPdiskShellExtDescribeHelpString);
efcdcb ¤   ¤   ¤   break;
f50fe4 ¤   ¤   }
22af5a
d91ce6 ¤   ¤   SmartStringCopy(pszName, helpString, cchMax);
2e9371 ¤   }
5f3c88 ¤   catch (CMemoryException *ex)
3cc7a1 ¤   {
296adc ¤   ¤   ex->Delete();
499371 ¤   }
6aaf5a
212e2b ¤   return NOERROR;
8befe6 }
06af5a
4bb4f3 // AddRef increases the reference count for this class object.
40af5a
85984f STDMETHODIMP_(ULONG)·
8e68ac CShellExt::AddRef()
b3bb36 {
42de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
506925 ¤   return ++mRefCount;
a7efe6 }
b3af5a
7e3443 // Release decreases the reference count for this class object.
72af5a
dd984f STDMETHODIMP_(ULONG)·
d95b7b CShellExt::Release()
82bb36 {
a3de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
2eaf5a
7fa8ac ¤   if (--mRefCount)
34d627 ¤   ¤   return mRefCount;
--e786 00097ffa93540110152 Page 7 of CShellExt.cpp
e0af5a
5c5345 ····if (mPDataObj)
5178a1 ········mPDataObj->Release();
31af5a
420fbf ¤   delete this;
a7af5a
d53e6b ¤   return 0;
17efe6 }
c6af5a
45afed // Initialize is called before initializing the context menu.
5faf5a
66287f STDMETHODIMP·
a7b108 CShellExt::Initialize(
bd479d ¤   LPCITEMIDLIST¤  pIDFolder,·
95ec3c ¤   LPDATAOBJECT¤   pDataObj,·
d7c5e8 ¤   HKEY¤   ¤   ¤   hRegKey)
c2bb36 {
707d36 ¤   DualErr derr;
b3af5a
a2de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
17af5a
d9486b ¤   // Initialize can be called more than once.
491a8b ¤   if (mPDataObj)
b49a8f ¤   ¤   mPDataObj->Release();
68af5a
5dae2b ¤   // Duplicate the object pointer and registry handle, and extract the path
82c88a ¤   // of the file or drive being operated on.
2aaf5a
57aa0f ¤   if (IsntNull(pDataObj))
abc7a1 ¤   {
a60682 ¤   ¤   mPDataObj = pDataObj;
a46fcb ¤   ¤   pDataObj->AddRef();
ffaf5a
63fdf6 ¤   ¤   derr = PreparePathsAndCommandLine();
7a9371 ¤   }
a8af5a
3f2361 ¤   if (derr.IsntError())
0d54df ¤   ¤   return NOERROR;
810e24 ¤   else
833768 ¤   ¤   return E_OUTOFMEMORY;
4aefe6 }
26af5a
7aaf5a
7a68ca /////////////////////////////////////////////
849683 // Class CShellExt protected member functions
ce68ca /////////////////////////////////////////////
39af5a
b0bc2e // DeletePathsAndCommandLine releases memory allocated by
490603 // PreparePathsAndCommandLine.
75af5a
21c823 void·
c758db CShellExt::DeletePathsAndCommandLine()
b7bb36 {
41e27e ¤   if (IsntNull(mTargets))
31c7a1 ¤   {
90d281 ¤   ¤   delete[] mTargets;
c143aa ¤   ¤   mTargets = NULL;
639371 ¤   }
1cefe6 }
78af5a
a450eb // ProcessTarget is a helper function for PreparePathsAndCommandLine.
09af5a
9f2292 DualErr·
bbf12f CShellExt::ProcessTarget(HDROP hDrop, PGPUInt32 i)
0cbb36 {
2c7d36 ¤   DualErr derr;
86af5a
10ed2d ¤   pgpAssert(IsntNull(hDrop));
eb1f1a ¤   pgpAssert(i <= mNumDropped);
71af5a
7178f1 ¤   try
97c7a1 ¤   {
--75ce 0002b6e8cbd40110152 Page 8 of CShellExt.cpp
4f70b8 ¤   ¤   char¤   ¤   ext[_MAX_EXT];
898b97 ¤   ¤   PGPBoolean¤ isAPGPdisk;
60af5a
3fba19 ¤   ¤   mTargets[i].isVolume¤   ¤   ¤   = FALSE;
670527 ¤   ¤   mTargets[i].isPGPdisk¤  ¤   ¤   = FALSE;
61e531 ¤   ¤   mTargets[i].isMountedPGPdisk¤   = FALSE;
46af5a
5bc9bc ¤   ¤   // Get the path.
8ecffe ¤   ¤   DragQueryFile((HDROP) hDrop, i,·
6bb585 ¤   ¤   ¤   mTargets[i].path.GetBuffer(kMaxStringSize), kMaxStringSize);
00af5a
9085bc ¤   ¤   mTargets[i].path.ReleaseBuffer();
bfaf5a
e5c642 ¤   ¤   // Is this a volume being pointed at?
d523c8 ¤   ¤   mTargets[i].isVolume = IsPlainLocalRoot(mTargets[i].path);
48af5a
bd5a97 ¤   ¤   // Check if it is a mounted PGPdisk.
9407df ¤   ¤   if (mTargets[i].isVolume)
c15b34 ¤   ¤   {
a73e2d ¤   ¤   ¤   PGPUInt8 drive;
01af5a
3711d6 ¤   ¤   ¤   // It's a volume, but is a PGPdisk volume (mounted)?
ad1e21 ¤   ¤   ¤   drive = DriveLetToNum(mTargets[i].path[0]);
31e66e ¤   ¤   ¤   derr = IsVolumeAPGPdisk(drive, &isAPGPdisk);
79af5a
569d3d ¤   ¤   ¤   if (derr.IsntError())
4df776 ¤   ¤   ¤   {
8335c9 ¤   ¤   ¤   ¤   if (isAPGPdisk)
8572c3 ¤   ¤   ¤   ¤   {
202448 ¤   ¤   ¤   ¤   ¤   mNumTotalPGPdisks++;
438ef2 ¤   ¤   ¤   ¤   ¤   mNumMountedPGPdisks++;
c0af5a
ff83df ¤   ¤   ¤   ¤   ¤   mTargets[i].isPGPdisk¤  ¤   ¤   = TRUE;
c0a348 ¤   ¤   ¤   ¤   ¤   mTargets[i].isMountedPGPdisk¤   = TRUE;
462613 ¤   ¤   ¤   ¤   }
40a3a6 ¤   ¤   ¤   }
f20fe4 ¤   ¤   }
360e1d ¤   ¤   else
ee5b34 ¤   ¤   {
1553c6 ¤   ¤   ¤   // It's a file, but is it a PGPdisk file (mounted or unmounted)?
07444f ¤   ¤   ¤   _splitpath(mTargets[i].path, NULL, NULL, NULL, ext);
f9e9b3 ¤   ¤   ¤   mTargets[i].isPGPdisk = !_stricmp(ext, kPGPdiskFileExtension);
dbaf5a
ccc172 ¤   ¤   ¤   if (mTargets[i].isPGPdisk)
04f776 ¤   ¤   ¤   {
1f58b0 ¤   ¤   ¤   ¤   PGPBoolean isLoopedBack;
3daf5a
3521a5 ¤   ¤   ¤   ¤   mNumTotalPGPdisks++;
ccaf5a
16bb39 ¤   ¤   ¤   ¤   // Resolve looped UNC paths.
643c18 ¤   ¤   ¤   ¤   if (IsUNCPath(mTargets[i].path))
e272c3 ¤   ¤   ¤   ¤   {
49aeb3 ¤   ¤   ¤   ¤   ¤   derr = CheckIfLoopedBack(mTargets[i].path,·
20540d ¤   ¤   ¤   ¤   ¤   ¤   &mTargets[i].path, &isLoopedBack);
d02613 ¤   ¤   ¤   ¤   }
cdaf5a
6cf9d3 ¤   ¤   ¤   ¤   // Is this a mounted PGPdisk?
5a99ad ¤   ¤   ¤   ¤   derr = IsFileAPGPdisk(mTargets[i].path, &isAPGPdisk);
3caf5a
f5724e ¤   ¤   ¤   ¤   if (derr.IsntError())
ec72c3 ¤   ¤   ¤   ¤   {
86f883 ¤   ¤   ¤   ¤   ¤   mTargets[i].isMountedPGPdisk = isAPGPdisk;
daaf5a
e0be35 ¤   ¤   ¤   ¤   ¤   if (isAPGPdisk)
d61f6a ¤   ¤   ¤   ¤   ¤   ¤   mNumMountedPGPdisks++;
622613 ¤   ¤   ¤   ¤   }
bba3a6 ¤   ¤   ¤   }
fa0fe4 ¤   ¤   }
d3af5a
1b9371 ¤   }
003c88 ¤   catch (CMemoryException *ex)
2bc7a1 ¤   {
--fe87 00055801f1040110152 Page 9 of CShellExt.cpp
d7ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
e66adc ¤   ¤   ex->Delete();
0c9371 ¤   }
b1af5a
5f33e3 ¤   return derr;
ccefe6 }
86af5a
dc1c63 // PreparePathsAndCommandLine prepares the list of targets and space for the
bf55e3 // command line for the app.
58af5a
da2292 DualErr·
126f1f CShellExt::PreparePathsAndCommandLine()
39bb36 {
f8be41 ¤   DualErr¤¤   derr;
ca9fed ¤   PGPBoolean¤ createdTargets¤ = FALSE;
46af5a
bd78f1 ¤   try
c3c7a1 ¤   {
345c71 ¤   ¤   FORMATETC¤  fmte = {CF_HDROP, (DVTARGETDEVICE FAR *) NULL,·
f4bb23 ¤   ¤   ¤   DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
b49955 ¤   ¤   PGPBoolean¤ createdTargets¤ = FALSE;
183cc8 ¤   ¤   PGPUInt32¤  i;
dbb6de ¤   ¤   STGMEDIUM¤  medium;
06af5a
79d843 ¤   ¤   mPDataObj->GetData(&fmte, &medium);
81af5a
bc12ce ¤   ¤   // Get the number of targets.
6a31b1 ¤   ¤   mNumDropped = DragQueryFile((HDROP) medium.hGlobal, 0xFFFFFFFF, NULL,·
570084 ¤   ¤   ¤   NULL);
57af5a
08fcd4 ¤   ¤   if (mNumDropped == 0)
240710 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FailSilently);
64af5a
f7aa35 ¤   ¤   if (derr.IsntError())
575b34 ¤   ¤   {
1b83ce ¤   ¤   ¤   mNumTotalPGPdisks = mNumMountedPGPdisks = 0;
34af5a
0d7b04 ¤   ¤   ¤   // Get space for the target array.
f80b73 ¤   ¤   ¤   mTargets = new TargetInfo[mNumDropped];
baf534 ¤   ¤   ¤   createdTargets = TRUE;
48af5a
b7e12d ¤   ¤   ¤   // Get info about each of them.
4e2ba1 ¤   ¤   ¤   for (i = 0; i < mNumDropped; i++)
8ff776 ¤   ¤   ¤   {
497fe5 ¤   ¤   ¤   ¤   derr = ProcessTarget((HDROP) medium.hGlobal, i);
c7af5a
459b74 ¤   ¤   ¤   ¤   if (derr.IsError())
9c14c3 ¤   ¤   ¤   ¤   ¤   break;
d1a3a6 ¤   ¤   ¤   }
d10fe4 ¤   ¤   }
d19371 ¤   }
413c88 ¤   catch (CMemoryException *ex)
cbc7a1 ¤   {
2cecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
796adc ¤   ¤   ex->Delete();
659371 ¤   }
93af5a
99b877 ¤   // Cleanup if error.
ab4bb3 ¤   if (derr.IsError())
b1c7a1 ¤   {
e78742 ¤   ¤   if (createdTargets)
235b34 ¤   ¤   {
ddc6a9 ¤   ¤   ¤   delete[] mTargets;
01af5a
7077f7 ¤   ¤   ¤   mTargets = NULL;
7c0fe4 ¤   ¤   }
99af5a
8447a4 ¤   ¤   mNumDropped = mNumTotalPGPdisks = mNumMountedPGPdisks = 0;
929371 ¤   }
b2af5a
5c33e3 ¤   return derr;
55efe6 }
--11e3 001e569999740110152 Page 10 of CShellExt.cpp
e0af5a
7393b8 // SendRequestToApp asks the PGPdisk application to perform a command on the
a95bf2 // PGPdisk targets. A "non-targeted" command does not take a pathname
ee3c17 // argument.
06af5a
c0c823 void·
7ec6a2 CShellExt::SendRequestToApp(LPCSTR command, PGPBoolean isNonTargeted)
93bb36 {
8078f1 ¤   try
9dc7a1 ¤   {
bfd1be ¤   ¤   CString¤¤   appName, temp;
f20187 ¤   ¤   PGPUInt32¤  result;
40af5a
c75825 ¤   ¤   pgpAssertStrValid(command);
d6af5a
03500f ¤   ¤   // For each PGPdisk target, add a command to the command line
5bdf7d ¤   ¤   // we are building.
b3af5a
618c94 ¤   ¤   if (isNonTargeted)
605b34 ¤   ¤   {
b56ee0 ¤   ¤   ¤   mCommandLine += command;
280fe4 ¤   ¤   }
0b0e1d ¤   ¤   else
af5b34 ¤   ¤   {
83b305 ¤   ¤   ¤   for (PGPUInt32 i=0; i < mNumDropped; i++)
06f776 ¤   ¤   ¤   {
89cf3e ¤   ¤   ¤   ¤   if (mTargets[i].isPGPdisk)
0f72c3 ¤   ¤   ¤   ¤   {
ce1507 ¤   ¤   ¤   ¤   ¤   PGPInt32 length;
feae30 ¤   ¤   ¤   ¤   ¤
ae442e ¤   ¤   ¤   ¤   ¤   length = mTargets[i].path.GetLength();
03af5a
b9ddb2 ¤   ¤   ¤   ¤   ¤   // If slash on end, double it.
0351d6 ¤   ¤   ¤   ¤   ¤   if (mTargets[i].path[length - 1] == '\\')
e82141 ¤   ¤   ¤   ¤   ¤   ¤   mTargets[i].path += "\\";
29af5a
1eae91 ¤   ¤   ¤   ¤   ¤   temp.Format(" %s \"%s\"", command, mTargets[i].path);
45ef17 ¤   ¤   ¤   ¤   ¤   mCommandLine += temp;
722613 ¤   ¤   ¤   ¤   }
3da3a6 ¤   ¤   ¤   }
2b0fe4 ¤   ¤   }
7eaf5a
3ebc30 ¤   ¤   // Execute the command line.
221cf5 ¤   ¤   appName = kPGPdiskAppName;
a34b45 ¤   ¤   appName += ".exe";
ddaf5a
92342d ¤   ¤   result = (PGPUInt32) ShellExecute(NULL, "open", appName,·
2c25a0 ¤   ¤   ¤   mCommandLine, NULL, SW_SHOWNORMAL);
6baf5a
20e754 ¤   ¤   if (result < 32)
d4c51a ¤   ¤   ¤   ReportError(kPGDMajorError_CouldntFindAppString);
f09371 ¤   }
2f3c88 ¤   catch (CMemoryException *ex)
a4c7a1 ¤   {
146adc ¤   ¤   ex->Delete();
419371 ¤   }
e5efe6 }
--73c5 0007d769dff40110153 Page 1 of CShellExt.h
541bc3 //////////////////////////////////////////////////////////////////////////////
529df0 // CShellExt.h
f8465d //
8e555a // Declarations for CShellExt.cpp.
631bc3 //////////////////////////////////////////////////////////////////////////////
c9af5a
9db8ae // $Id: CShellExt.h,v 1.1.2.3 1998/07/06 08:58:40 nryan Exp $
95af5a
becbce // Copyright (C) 1998 by Network Associates, Inc.
4f71ae // All rights reserved.
a0af5a
3440b3 #ifndef Included_CShellExt_h // [
e02292 #define Included_CShellExt_h
e3af5a
5f5f7a #include <Shlobj.h>
403a85 #include "DualErr.h"
40af5a
8eaf5a
92d557 ////////
a902c9 // Types
bed557 ////////
69af5a
c8d08d // A TargetInfo holds info about the specified shell target.
2daf5a
f0182b typedef struct TargetInfo
5cbb36 {
a5f65c ¤   CString¤¤   path;
6daf5a
b4b22e ¤   PGPBoolean¤ isVolume;
b1f03e ¤   PGPBoolean¤ isPGPdisk;
8ebff7 ¤   PGPBoolean¤ isMountedPGPdisk;
1faf5a
04e87a } TargetInfo;
a9af5a
42af5a
bad594 //////////////////
97c07f // Class CShellExt
81d594 //////////////////
37af5a
637ba2 // This is the actual OLE Shell context menu handler.
e5af5a
8031ee class CShellExt : public IContextMenu, IShellExtInit
acbb36 {
305ed4 public:
95f212 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CShellExt();
8cc405 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ~CShellExt();
cdaf5a
0e03c8 ¤   // IUnknown members.
4ebe8c ¤   STDMETHODIMP¤   ¤   ¤   QueryInterface(REFIID riid, LPVOID FAR *ppv);
84b279 ¤   STDMETHODIMP_(ULONG)¤   AddRef();
22ebc8 ¤   STDMETHODIMP_(ULONG)¤   Release();
29af5a
6edfd0 ¤   // IShell members.
5f9907 ¤   STDMETHODIMP¤   ¤   ¤   QueryContextMenu(HMENU hMenu, UINT indexMenu,·
46d0e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
cfaf5a
87f8d3 ¤   STDMETHODIMP¤   ¤   ¤   InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
10e779 ¤   STDMETHODIMP¤   ¤   ¤   GetCommandString(UINT idCmd, UINT uFlags,·
73c19d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT FAR *reserved, LPSTR pszName,·
0acff4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT cchMax);
31af5a
66b028 ¤   // IShellExtInit methods.
b0d700 ¤   STDMETHODIMP¤   ¤   ¤   Initialize(LPCITEMIDLIST pIDFolder,·
2ef909 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPDATAOBJECT pDataObj, HKEY hKeyID);
f7af5a
6c0782 ¤   // IExtractIcon methods.
263db6 ¤   STDMETHODIMP¤   ¤   ¤   GetIconLocation(UINT uFlags, LPSTR szIconFile,·
7c938c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT cchMax, int *piIndex, UINT *pwFlags);
bbaf5a
2af280 ¤   STDMETHODIMP¤   ¤   ¤   Extract(LPCSTR pszFile, UINT nIconIndex,·
d19aa3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   HICON *phiconLarge, HICON *phiconSmall,·
7d8d15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT nIconSize);
--aac1 0019bc1a2cd40110153 Page 2 of CShellExt.h
e0af5a
90a2d3 protected:
6a9136 ¤   LPDATAOBJECT¤   mPDataObj;¤ ¤   ¤   ¤   // data object passed to us
685872 ¤   PGPUInt32¤  ¤   mRefCount;¤ ¤   ¤   ¤   // ref count for the object
63af5a
f8f031 ¤   CMenu¤  ¤   ¤   mParentMenu;¤   ¤   ¤   // parent menu of PGPdisk menu
3219d2 ¤   CMenu¤  ¤   ¤   mSubMenu;¤  ¤   ¤   ¤   // the PGPdisk menu
48af5a
bff537 ¤   CString¤¤   ¤   mCommandLine;¤  ¤   ¤   // command line
f64336 ¤   TargetInfo¤ ¤   *mTargets;¤ ¤   ¤   ¤   // array of targets
f5af5a
0861a6 ¤   PGPUInt32¤  ¤   mNumDropped;¤   ¤   ¤   // number of targets
5bc48a ¤   PGPUInt32¤  ¤   mNumTotalPGPdisks;¤ ¤   // # that are PGPdisks
bdbb4d ¤   PGPUInt32¤  ¤   mNumMountedPGPdisks;¤   // # that are mounted PGPdisks
4daf5a
8f8871 ¤   PGPBoolean¤ ¤   mShiftKeyDown;¤ ¤   ¤   // shift key down?
3daf5a
782593 ¤   void¤   ¤   ¤   DeletePathsAndCommandLine();
916f2b ¤   DualErr¤¤   ¤   ProcessTarget(HDROP hDrop, PGPUInt32 i);
4f512d ¤   DualErr¤¤   ¤   PreparePathsAndCommandLine();
c6af5a
714127 ¤   void¤   ¤   ¤   SendRequestToApp(LPCSTR request,·
6f6ea6 ¤   ¤   ¤   ¤   ¤   ¤   PGPBoolean isNonTargeted = FALSE);
d182f7 };
2faf5a
d0e3d6 typedef CShellExt *LPCSHELLEXT;
0baf5a
9b510c #endif¤ // ] Included_CShellExt_h
--9683 00093668f1a40110154 Page 1 of CShellExtClassFactory.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
6e0472 // CShellExtClassFactory.cpp
dd465d //
558539 // Definition of class CShellExtClassFactory.
661bc3 //////////////////////////////////////////////////////////////////////////////
2aaf5a
bb8cda // $Id: CShellExtClassFactory.cpp,v 1.1.2.2.2.1 1998/08/22 01:55:39 nryan Exp $
d2af5a
ddcbce // Copyright (C) 1998 by Network Associates, Inc.
1671ae // All rights reserved.
aaaf5a
189e12 #include "StdAfx.h"
f9af5a
3c9bcf #include "Required.h"
8c487c #include "CShellExt.h"
0547f5 #include "CShellExtClassFactory.h"
6bc411 #include "Globals.h"
aeaf5a
23af5a
d8b474 //////////////////////////////
f5f95a // Class CShellExtClassFactory
80b474 //////////////////////////////
29af5a
736cfc // The CShellExtClassFactory default constructor.
e5af5a
2b940c CShellExtClassFactory::CShellExtClassFactory()
fcbb36 {
14689c ¤   mRefCount = 0;
8ca201 ¤   DLL->mGCRefThisDll++;·
83efe6 }
1daf5a
9d4ee2 // The CShellExtClassFactory destructor.
6f0753 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
d94d16 CShellExtClassFactory::~CShellExtClassFactory() ¤   ¤   ¤
5fbb36 {
6bc0f0 ¤   DLL->mGCRefThisDll--;
5befe6 }
ffaf5a
953831 // QueryInterface is called to ask the shell extension to return a pointer to
40458b // its interface.
9eaf5a
9c287f STDMETHODIMP·
5f9c73 CShellExtClassFactory::QueryInterface(REFIID riid, LPVOID FAR *ppv)
4dbb36 {
3dde1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
7eaf5a
107675 ¤   (* ppv) = NULL;
4eaf5a
5390cc ¤   // Any interface on this object is the object pointer.
6262ce ¤   if (IsEqualIID(riid, IID_IUnknown) ||·
b025ab ¤   ¤   IsEqualIID(riid, IID_IClassFactory))
d7c7a1 ¤   {
bfb594 ¤   ¤   (* ppv) = (LPCLASSFACTORY) this;
f6fb5c ¤   ¤   AddRef();
80af5a
3d54df ¤   ¤   return NOERROR;
af9371 ¤   }
680e24 ¤   else
91c7a1 ¤   {
9f4df4 ¤   ¤   return E_NOINTERFACE;
999371 ¤   }
d2efe6 }
cfaf5a
5ab4f3 // AddRef increases the reference count for this class object.
d0af5a
e1984f STDMETHODIMP_(ULONG)·
354178 CShellExtClassFactory::AddRef()
90bb36 {
73de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
4a6925 ¤   return ++mRefCount;
6fefe6 }
93af5a
--b6f7 00136f875dc40110154 Page 2 of CShellExtClassFactory.cpp
872740 // Release descreases the reference count for this class object.
43af5a
1e984f STDMETHODIMP_(ULONG)·
fccbfb CShellExtClassFactory::Release()
bcbb36 {
39de1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
d1af5a
7ea8ac ¤   if (--mRefCount)
29d627 ¤   ¤   return mRefCount;
81af5a
900fbf ¤   delete this;
56af5a
da3e6b ¤   return 0;
10efe6 }
83af5a
e9ff7f // CreateInstance creates an instance of this class object.
d5af5a
37287f STDMETHODIMP·
2c33f8 CShellExtClassFactory::CreateInstance(
32523d ¤   LPUNKNOWN¤  pUnkOuter,·
cd05ad ¤   REFIID¤ ¤   riid,·
002405 ¤   LPVOID¤ ¤   *ppvObj)
57bb36 {
60a501 ¤   LPCSHELLEXT¤pShellExt;
668c61 ¤   PGPBoolean¤ madeShellExt;
37af5a
ffde1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
10af5a
6d30c5 ¤   (* ppvObj) = NULL;
1caf5a
505010 ¤   // Shell extensions typically don't support aggregation (inheritance).
ec005e ¤   if (pUnkOuter)
aebaa0 ¤   ¤   return CLASS_E_NOAGGREGATION;
74af5a
571f8d ¤   // Create the main shell extension object.¤ The shell will then call
91e4f4 ¤   // QueryInterface with IID_IShellExtInit--this is how shell extensions
0e5f62 ¤   // are initialized.
f2af5a
f578f1 ¤   try
85c7a1 ¤   {
952932 ¤   ¤   pShellExt = new CShellExt();¤   ¤
8e55c5 ¤   ¤   madeShellExt = TRUE;
8b9371 ¤   }
e33c88 ¤   catch (CMemoryException *ex)
53c7a1 ¤   {
94a0b7 ¤   ¤   madeShellExt = FALSE;
616adc ¤   ¤   ex->Delete();
0e9371 ¤   }
64af5a
e18b64 ¤   if (madeShellExt)
e706d0 ¤   ¤   return pShellExt->QueryInterface(riid, ppvObj);
c60e24 ¤   else
743768 ¤   ¤   return E_OUTOFMEMORY;
16efe6 }
23af5a
18f050 // LockServer just returns since we don't support it.
51af5a
cd287f STDMETHODIMP·
50ea37 CShellExtClassFactory::LockServer(BOOL fLock)
21bb36 {
1ade1c ¤   AFX_MANAGE_STATE(AfxGetStaticModuleState());
eb2e2b ¤   return NOERROR;
36efe6 }
--f7a4 0013753155a40110155 Page 1 of CShellExtClassFactory.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d8f355 // CShellExtClassFactory.h
78465d //
06dae6 // Declarations CShellExtClassFactory.cpp.
7e1bc3 //////////////////////////////////////////////////////////////////////////////
cdaf5a
ed5f5c // $Id: CShellExtClassFactory.h,v 1.1.2.2 1998/07/06 08:58:41 nryan Exp $
4caf5a
adcbce // Copyright (C) 1998 by Network Associates, Inc.
c371ae // All rights reserved.
1eaf5a
c0f290 #ifndef Included_CShellExtClassFactory_h // [
a07607 #define Included_CShellExtClassFactory_h
8baf5a
dfaf5a
61b474 //////////////////////////////
67f95a // Class CShellExtClassFactory
73b474 //////////////////////////////
1aaf5a
a6b2e1 // This class factory object creates context menu handlers.
84af5a
ef97ef class CShellExtClassFactory : public IClassFactory
aabb36 {
e45ed4 public:
68dd74 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CShellExtClassFactory();
952c8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ~CShellExtClassFactory();
9baf5a
fc03c8 ¤   // IUnknown members.
c98943 ¤   STDMETHODIMP¤   ¤   ¤   QueryInterface(REFIID riid , LPVOID FAR* ppv);
82b279 ¤   STDMETHODIMP_(ULONG)¤   AddRef();
beebc8 ¤   STDMETHODIMP_(ULONG)¤   Release();
c5af5a
3e2755 ¤   // IClassFactory members.
0dbbf4 ¤   STDMETHODIMP¤   ¤   ¤   CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid,·
afc3fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPVOID FAR *ppvObj);
384485 ¤   STDMETHODIMP¤   ¤   ¤   LockServer(BOOL);
deaf5a
71a2d3 protected:
02890e ¤   ULONG mRefCount;¤   ¤   // ref count for the object
7eaf5a
5382f7 };
1caf5a
a21057 typedef CShellExtClassFactory *LPCSHELLEXTCLASSFACTORY;
e1af5a
376047 #endif¤ // ] Included_CShellExtClassFactory_h
--e019 0018d561b7840110156 Page 1 of Globals.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b6c9cd // Globals.h
73465d //
6e3be4 // Contains extern declarations for global variables.
221bc3 //////////////////////////////////////////////////////////////////////////////
54af5a
05b5db // $Id: Globals.h,v 1.1.2.2 1998/07/06 08:58:42 nryan Exp $
0faf5a
75cbce // Copyright (C) 1998 by Network Associates, Inc.
6a71ae // All rights reserved.
34af5a
9a7e7c #ifndef Included_Globals_h¤ // [
5480bb #define Included_Globals_h
4eaf5a
f680a4 #include "CPGPdiskShellExtDll.h"
44af5a
c8af5a
7fc7c6 ///////////////////////////////
48269b // Global variable declarations
aac7c6 ///////////////////////////////
d5af5a
d28437 // All of the global variables are defined in CPGPdiskShellExtDll.cpp.
c4af5a
215ffa extern CPGPdiskShellExtDll *DLL;¤   // pointer to Dll object
f0af5a
8d3932 #endif¤ // ] Included_Globals_h
--c9b3 001a58d2ba040110157 Page 1 of Resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
04dda3 // Used by C:\Source\clients\disk\win32\PGPdiskShellExt\PGPdiskShellExt.rc
c7465d //
72af5a
e011aa // Next default values for new objects
b0ac6a //·
b8f860 #ifdef APSTUDIO_INVOKED
ae3f23 #ifndef APSTUDIO_READONLY_SYMBOLS
d1b0ab #define _APS_NEXT_RESOURCE_VALUE ·······101
1b611c #define _APS_NEXT_COMMAND_VALUE ········40001
b1f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
8a1285 #define _APS_NEXT_SYMED_VALUE ··········101
ea7454 #endif
a57454 #endif
--da98 001aabee66840110158 Page 1 of StdAfx.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
77fc35 // StdAfx.cpp
06465d //
c0afe4 // MFC source.
d41bc3 //////////////////////////////////////////////////////////////////////////////
36af5a
a5a646 // $Id: StdAfx.cpp,v 1.1.2.2 1998/05/29 00:43:56 nryan Exp $
8daf5a
9ed221 // Not really Copyright (C) 1998 by Network Associates, Inc.
88af5a
aa9e12 #include "StdAfx.h"
--777a 001cce87b6f40110159 Page 1 of StdAfx.h
541bc3 //////////////////////////////////////////////////////////////////////////////
465fb0 // StdAfx.h
01465d //
7120f8 // Contains global MFC includes.
081bc3 //////////////////////////////////////////////////////////////////////////////
82af5a
4a1a27 // $Id: StdAfx.h,v 1.1.2.2 1998/05/29 00:43:57 nryan Exp $
68af5a
90d221 // Not really Copyright (C) 1998 by Network Associates, Inc.
3671ae // All rights reserved.
9caf5a
9096d7 #ifndef Included_StdAfx_h¤  // [
304653 #define Included_StdAfx_h
f8af5a
7a6b7d #include <afxwin.h> ········// MFC core and standard components
26be9b #include <afxext.h> ········// MFC extensions
1eaf5a
ba8e6d #ifndef _AFX_NO_OLE_SUPPORT
484ea2 #include <afxole.h> ········// MFC OLE classes
b54f52 #include <afxodlgs.h> ······// MFC OLE dialog classes
db7e9c #include <afxdisp.h> ·······// MFC OLE automation classes
2642ac #endif // _AFX_NO_OLE_SUPPORT
35af5a
15af5a
417ed7 #ifndef _AFX_NO_DB_SUPPORT
5e5762 #include <afxdb.h>¤ ¤   ¤   // MFC ODBC database classes
c6e3bd #endif // _AFX_NO_DB_SUPPORT
feaf5a
398566 #ifndef _AFX_NO_DAO_SUPPORT
950aa9 #include <afxdao.h>¤¤   ¤   // MFC DAO database classes
3d49a7 #endif // _AFX_NO_DAO_SUPPORT
22af5a
bbaef9 #ifndef _AFX_NO_AFXCMN_SUPPORT
81eb71 #include <afxcmn.h>¤¤   ¤   // MFC support for Windows Common Controls
d59db5 #endif // _AFX_NO_AFXCMN_SUPPORT
acaf5a
1dc18c //{{AFX_INSERT_LOCATION}}
c1af5a
cca54d #endif // Included_StdAfx_h
--6ca0 000410ee37c4011015a Page 1 of CommonStrings.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
b70f39 // CommonStrings.cpp
fb465d //
b6841d // All PGPdisk project strings are defined here.
591bc3 //////////////////////////////////////////////////////////////////////////////
b6af5a
180b90 // $Id: CommonStrings.cpp,v 1.1.2.12.2.5 1998/10/30 22:49:18 nryan Exp $
42af5a
b5cbce // Copyright (C) 1998 by Network Associates, Inc.
6971ae // All rights reserved.
08af5a
4f6931 #if defined(PGPDISK_MFC)
f9af5a
829e12 #include "StdAfx.h"
42af5a
b14268 #elif defined(PGPDISK_95DRIVER)
96af5a
3106a9 #include <vtoolscp.h>
a286d2 #include LOCKED_CODE_SEGMENT
325269 #include LOCKED_DATA_SEGMENT
e5af5a
49f5a6 #elif defined(PGPDISK_NTDRIVER)
dcaf5a
5ad7a1 #include <vdw.h>
e0af5a
6adb21 #else
f2112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
0c05d6 #endif¤ // PGPDISK_MFC
70af5a
189bcf #include "Required.h"
3d4b7a #include "CommonStrings.h"
1fb616 #include "Errors.h"
daaf5a
c8af5a
d683f5 ///////////////////////////
67b29d // String association array
cc83f5 ///////////////////////////
a3af5a
b38ec3 LPCSTR kPGPdiskCommonStrings[kPGPdiskMaxCommonStrings] =
cebb36 {
aa6e15 ¤   // kPGPdiskBadCmdLineString
72c7a1 ¤   {
a2d5af ¤   ¤   "Unrecognized command line option or command."
5b42d0 ¤   },·
98af5a
cef51f ¤   // kPGPdiskCmdLineHelpString
76c7a1 ¤   {
007f14 ¤   ¤   "Commands: create, mount, open unmount, unmountall, addpass, "·
3c94db ¤   ¤   "changepass, removepass, removealts, addrempubkeys, about, help, "
9394ef ¤   ¤   "prefs.\n\nOptions: -s: silent mode"
f8ba24 ¤   },
e0af5a
2d666f ¤   // kPGPdiskBecauseString
73c7a1 ¤   {
cbfc1a ¤   ¤   "because "
d442d0 ¤   },·
7faf5a
1c7d48 ¤   // kPGPdiskNoMemForErrorString
3fc7a1 ¤   {
c86b7b ¤   ¤   "PGPdisk is running out of memory - please quit now."
dd42d0 ¤   },·
e8af5a
ba5366 ¤   // kPGPdiskRemoveAltsSuccessString
8fc7a1 ¤   {
09de7b ¤   ¤   "All alternate passphrases were successfully removed."
f342d0 ¤   },·
c2af5a
a6a9d1 ¤   // kPGPdiskNoPGPdisksToUnmountString
b9c7a1 ¤   {
d9695f ¤   ¤   "There are no PGPdisks currently mounted."
0a42d0 ¤   },·
41af5a
--08d9 000a061e1474011015a Page 2 of CommonStrings.cpp
5ba5ff ¤   // kPGPdiskLicenseToText
e8c7a1 ¤   {
870d5e ¤   ¤   "Licensed To:"
3842d0 ¤   },·
deaf5a
9bf90a ¤   // kPGPdiskDemoTimeoutWarning
b1c7a1 ¤   {
dea349 ¤   ¤   "This demo version of PGPdisk has expired. From now on, you will "
fb0689 ¤   ¤   "only be able to mount your PGPdisks in read-only mode. For "
2034b1 ¤   ¤   "instructions on how to purchase a fully-enabled copy of PGPdisk, "
6d591d ¤   ¤   "click on the link below."
b042d0 ¤   },·
9baf5a
a86904 ¤   // kPGPdiskDemoBadCommandWarning
74c7a1 ¤   {
bb6792 ¤   ¤   "This command is unavailable becaue your demo copy of PGPdisk has "·
bc8980 ¤   ¤   "expired. For instructions on how to purchase a fully-enabled copy "
184b2f ¤   ¤   "of PGPdisk, click on the button below."
0142d0 ¤   },·
9faf5a
668219 ¤   // kPGPdiskURL
01c7a1 ¤   {
dd6091 ¤   ¤   "http://www.pgp.com/"
1c42d0 ¤   },·
26af5a
59736a ¤   // kPGPdiskBuyNowURL
17c7a1 ¤   {
656091 ¤   ¤   "http://www.pgp.com/"
ac42d0 ¤   },·
73af5a
1bad8a ¤   // kPGPdiskCPDTAddPassMsg
aec7a1 ¤   {
996ea1 ¤   ¤   "Please enter an additional passphrase for \"%s\"."
a242d0 ¤   },·
d6af5a
8c9135 ¤   // kPGPdiskCPDTChangePassMsg
9fc7a1 ¤   {
8afbc9 ¤   ¤   "Please enter a new passphrase for \"%s\"."
5642d0 ¤   },·
9caf5a
ae2636 ¤   // kPGPdiskSDTCreateDialogTitle
83c7a1 ¤   {
f4034e ¤   ¤   "New PGPdisk"
ea42d0 ¤   },·
6daf5a
6a87c8 ¤   // kPGPdiskSDTSaveFilter
abc7a1 ¤   {
ad094b ¤   ¤   "PGPdisk Files (*.pgd)||"
ee42d0 ¤   },·
a4af5a
4467ba ¤   // kPGPdiskSPDTChangePassMsg
f1c7a1 ¤   {
2ca8d2 ¤   ¤   "Please enter the passphrase to change for \"%s\"."
7e42d0 ¤   },·
dfaf5a
d491e7 ¤   // kPGPdiskSPDTMasterPassMsg
78c7a1 ¤   {
294c2d ¤   ¤   "Please enter the master passphrase for \"%s\"."
aa42d0 ¤   },·
a0af5a
8d6f34 ¤   // kPGPdiskSPDTMountPassMsg
36c7a1 ¤   {
e63f20 ¤   ¤   "Please enter a passphrase for \"%s\"."
1442d0 ¤   },·
88af5a
2d15fe ¤   // kPGPdiskSPDTPublicKeyPassMsg
b7c7a1 ¤   {
25371f ¤   ¤   "Please enter a public key passphrase for \"%s\"."
bb42d0 ¤   },·
eeaf5a
b85588 ¤   // kPGPdiskSPDTRemovePassMsg
a0c7a1 ¤   {
--e52d 000cde29c344011015a Page 3 of CommonStrings.cpp
d0933f ¤   ¤   "Please enter the passphrase to remove from \"%s\"."
1742d0 ¤   },·
b7af5a
40623e ¤   // kPGPdiskPrefsSheetTitleString
2bc7a1 ¤   {
ba15e9 ¤   ¤   "Preferences"
f642d0 ¤   },·
73af5a
b51e3b ¤   // kPGPdiskDiskWizSheetTitleString
3ec7a1 ¤   {
804b76 ¤   ¤   "New PGPdisk Wizard"
e542d0 ¤   },·
40af5a
2e2dd2 ¤   // kPGPdiskCreationCreateMsgString
22c7a1 ¤   {
04cbff ¤   ¤   "Creating: \"%s\""
bd42d0 ¤   },·
66af5a
c2e303 ¤   // kPGPdiskCreationDoneMsgString
adc7a1 ¤   {
26ed33 ¤   ¤   "Finished: \"%s\""
3c42d0 ¤   },·
1aaf5a
a1af5a
49710a ¤   // kPGPdiskFreeSize1MsgString
74c7a1 ¤   {
a94ef6 ¤   ¤   "You have %s of free space available. Note that the actual amount "
e2fc57 ¤   ¤   "of free space on the PGPdisk volume you create will be somewhat "
e0691d ¤   ¤   "smaller than the figure you choose below."
bb42d0 ¤   },·
31af5a
8a8fb9 ¤   // kPGPdiskFreeSize2MsgString
bcc7a1 ¤   {
2f4ef6 ¤   ¤   "You have %s of free space available. Note that the actual amount "
79fc57 ¤   ¤   "of free space on the PGPdisk volume you create will be somewhat "
5a691d ¤   ¤   "smaller than the figure you choose below."
4e42d0 ¤   },·
5faf5a
40da28 ¤   // kPGPdiskFreeSize3MsgString
6bc7a1 ¤   {
e57ee1 ¤   ¤   "PGPdisk was unable to determine the amount of available free "
030585 ¤   ¤   "space. Note that the actual amount of free space on the PGPdisk "
eef25a ¤   ¤   "volume you create will be somewhat smaller than the figure you "
49c485 ¤   ¤   "choose below."
a742d0 ¤   },·
fcaf5a
1165dc ¤   // kPGPdiskOpenCmdString
2ac7a1 ¤   {
5304cd ¤   ¤   "open"
0d42d0 ¤   },·
2daf5a
fc07c0 ¤   // kPGPdiskGlobalConvertCmdString
46c7a1 ¤   {
704fc0 ¤   ¤   "globalconvert"
1342d0 ¤   },·
9faf5a
00f8d3 ¤   // kPGPdiskCreateCmdString
2bc7a1 ¤   {
2d340c ¤   ¤   "create"
4542d0 ¤   },·
7daf5a
f03c60 ¤   // kPGPdiskMountCmdString
04c7a1 ¤   {
27f6bc ¤   ¤   "mount"
4142d0 ¤   },·
e1af5a
eace83 ¤   // kPGPdiskUnmountCmdString
b0c7a1 ¤   {
83ca45 ¤   ¤   "unmount"
c242d0 ¤   },·
eeaf5a
cd3060 ¤   // kPGPdiskUnmountAllCmdString
--7021 000404b368f4011015a Page 4 of CommonStrings.cpp
f7c7a1 ¤   {
b019b6 ¤   ¤   "unmountall"
ab42d0 ¤   },·
8baf5a
4d44ea ¤   // kPGPdiskAddPassCmdString
39c7a1 ¤   {
864f9c ¤   ¤   "addpass"
d642d0 ¤   },·
38af5a
2836d7 ¤   // kPGPdiskChangePassCmdString
4cc7a1 ¤   {
eee2af ¤   ¤   "changepass"
3a42d0 ¤   },·
58af5a
c43b08 ¤   // kPGPdiskRemovePassCmdString
fcc7a1 ¤   {
348bc3 ¤   ¤   "removepass"
9142d0 ¤   },·
58af5a
042fdc ¤   // kPGPdiskRemoveAltsCmdString
11c7a1 ¤   {
5ae60d ¤   ¤   "removealts"
b942d0 ¤   },·
0baf5a
3ed39f ¤   // kPGPdiskPubKeyCmdString
d7c7a1 ¤   {
cc82a6 ¤   ¤   "addrempubkeys"
fe42d0 ¤   },·
6baf5a
69ebfc ¤   // kPGPdiskWipeAllCmdString
60c7a1 ¤   {
3e735a ¤   ¤   "disableallmounted"
c6ba24 ¤   },
87af5a
cf7885 ¤   // kPGPdiskWipeIndCmdString
b9c7a1 ¤   {
9692f3 ¤   ¤   "disablethisdisk"
5fba24 ¤   },
c3af5a
0cc3a3 ¤   // kPGPdiskAboutCmdString
b6c7a1 ¤   {
7b89a5 ¤   ¤   "about"
8342d0 ¤   },·
5aaf5a
f5ebb3 ¤   // kPGPdiskHelpCmdString
4cc7a1 ¤   {
37e6e5 ¤   ¤   "help"
4142d0 ¤   },·
edaf5a
0deb58 ¤   // kPGPdiskPrefsCmdString
46c7a1 ¤   {
7dc7c8 ¤   ¤   "prefs"
7742d0 ¤   },·
40af5a
9fea6d ¤   // kPGPdiskShellExtOpenMenuString
00c7a1 ¤   {
2e358f ¤   ¤   "&Open PGPdisks..."
9842d0 ¤   },·
1467c5 ¤
7f8892 ¤   // kPGPdiskShellExtMountMenuString
8ac7a1 ¤   {
498f60 ¤   ¤   "&Mount PGPdisk..."
9242d0 ¤   },·
22af5a
1c9abf ¤   // kPGPdiskShellExtUnmountMenuString
8ec7a1 ¤   {
6ae7ce ¤   ¤   "&Unmount PGPdisk"
4542d0 ¤   },·
0caf5a
3164f2 ¤   // kPGPdiskShellExtAddPassMenuString
97c7a1 ¤   {
40de89 ¤   ¤   "&Add Passphrase..."
--6abb 0007eec10b44011015a Page 5 of CommonStrings.cpp
c442d0 ¤   },·
b9af5a
47050b ¤   // kPGPdiskShellExtChangePassMenuString
a0c7a1 ¤   {
8853c3 ¤   ¤   "&Change Passphrase..."
4442d0 ¤   },·
5caf5a
602b7c ¤   // kPGPdiskShellExtRemovePassMenuString
0ec7a1 ¤   {
f854d5 ¤   ¤   "&Remove Passphrase..."
3d42d0 ¤   },·
07af5a
6fbbc1 ¤   // kPGPdiskShellExtRemoveAltsMenuString
e4c7a1 ¤   {
6c23b0 ¤   ¤   "&Remove Alternate Passphrases..."
5c42d0 ¤   },·
7faf5a
0eb044 ¤   // kPGPdiskShellExtPubKeysMenuString
a5c7a1 ¤   {
ba6e99 ¤   ¤   "Add/Remove Public &Keys..."
e642d0 ¤   },·
90af5a
177112 ¤   // kPGPdiskShellExtHelpMenuString
98c7a1 ¤   {
820fc0 ¤   ¤   "&Help..."
ee42d0 ¤   },·
dfaf5a
ce6dd1 ¤   // kPGPdiskShellExtDescribeOpenString,·
8ec7a1 ¤   {
cf8587 ¤   ¤   "Mounts or explores the selected PGPdisks"
7342d0 ¤   },·
7aaf5a
b8f67b ¤   // kPGPdiskShellExtDescribeMountString,·
98c7a1 ¤   {
a6950e ¤   ¤   "Mounts an unmounted PGPdisk"
2d42d0 ¤   },·
d8af5a
1ce6c2 ¤   // kPGPdiskShellExtDescribeUnmountString,·
00c7a1 ¤   {
e1cb75 ¤   ¤   "Unmounts a mounted PGPdisk"
0542d0 ¤   },·
75af5a
7ff7ac ¤   // kPGPdiskShellExtDescribeAddPassString,·
c7c7a1 ¤   {
df8e7c ¤   ¤   "Adds a passphrase to an unmounted PGPdisk"
d242d0 ¤   },·
23af5a
f60cbe ¤   // kPGPdiskShellExtDescribeChangePassString,·
4fc7a1 ¤   {
dcc934 ¤   ¤   "Changes a passphrase on an unmounted PGPdisk"
c142d0 ¤   },·
03af5a
7ebb63 ¤   // kPGPdiskShellExtDescribeRemovePassString,·
27c7a1 ¤   {
0087b0 ¤   ¤   "Remove all alternate passphrases from an unmounted PGPdisk"
4d42d0 ¤   },·
b1af5a
eece37 ¤   // kPGPdiskShellExtDescribeRemoveAltsString,·
aac7a1 ¤   {
a0d2b5 ¤   ¤   "Removes a passphrase from an unmounted PGPdisk"
5d42d0 ¤   },·
9daf5a
da5726 ¤   // kPGPdiskShellExtDescribePubKeysString,·
73c7a1 ¤   {
e2187f ¤   ¤   "Adds and removes public keys to or from an unmounted PGPdisk"
8542d0 ¤   },·
6caf5a
8d6d4c ¤   // kPGPdiskShellExtDescribeHelpString
dec7a1 ¤   {
97bb2a ¤   ¤   "Displays the PGPdisk help file"
5d42d0 ¤   },·
7eaf5a
--9c50 00070258fd54011015a Page 6 of CommonStrings.cpp
639c04 ¤   // kPGPdiskBetaTimeOutWarning
b1c7a1 ¤   {
d535b3 ¤   ¤   "This beta version of PGPdisk has expired. From now on, you will "
9eca47 ¤   ¤   "only be able to mount your PGPdisks in read-only mode."
4442d0 ¤   },·
8aaf5a
b360a6 ¤   // kPGPdiskVerifyRemoveAlternates
4fc7a1 ¤   {
f3045d ¤   ¤   "Are you sure you want to remove all passphrases from this PGPdisk? "
f0859b ¤   ¤   "If you choose 'Yes', only the master passphrase will be able to "
61eaec ¤   ¤   "mount this PGPdisk."
1442d0 ¤   },·
7baf5a
f9873f ¤   // kPGPdiskNotifyMountMaybeCorrupt
64c7a1 ¤   {
4b68eb ¤   ¤   "This PGPdisk was either unmounted improperly or was created by "
df0f03 ¤   ¤   "copying an already mounted PGPdisk file, and may be damaged and/or "
b72b9b ¤   ¤   "out-of-date. You should check it with a disk repair utility at the "
290308 ¤   ¤   "first opportunity."
9e42d0 ¤   },·
fcaf5a
dad215 ¤   // kPGPdiskConfirmFormat
fdc7a1 ¤   {
4a1ea2 ¤   ¤   "The PGPdisk does not appear to be formatted. Do you want to format "
e208cd ¤   ¤   "it now?"
b742d0 ¤   },·
e4af5a
b29ab5 ¤   // kPGPdiskAskToSavePrefs
0fc7a1 ¤   {
747014 ¤   ¤   "You have made changes that have not been applied. Do you want to "
264801 ¤   ¤   "apply them now?"
1842d0 ¤   },·
01af5a
f56aa2 ¤   // kPGPdiskPGPdiskIsNotEncrypted
f8c7a1 ¤   {
1f735a ¤   ¤   "This PGPdisk was created using a demo version of PGPdisk and is "
0dd4bb ¤   ¤   "not encrypted. For security reasons, you will only be able to "
8dbfbf ¤   ¤   "mount it in read-only mode."
c342d0 ¤   },·
5eaf5a
5e400b ¤   // kPGPdiskConfirmCancelFormat
e3c7a1 ¤   {
af23dd ¤   ¤   "Your new PGPdisk volume still hasn't been formatted. Do you want "
0329d0 ¤   ¤   "to attempt formatting again?"
c242d0 ¤   },·
edaf5a
8d92a0 ¤   // kPGPdiskResConfirmPGPdiskResQuit
4ec7a1 ¤   {
c23bcc ¤   ¤   "Are you sure you want to stop the PGPdiskResident application? If "
9c0bcd ¤   ¤   "you do so, important PGPdisk features such as the unmount hotkey "
ca376e ¤   ¤   "will not work."
a442d0 ¤   },·
cdaf5a
8ac0e1 ¤   // kPGPdiskConfirmCancelCreation
0ac7a1 ¤   {
daf2db ¤   ¤   "Are you sure you want to cancel creating your new PGPdisk?"
f642d0 ¤   },·
cbaf5a
745af8 ¤   // kPGPdiskForceROOnLoopbackString
bec7a1 ¤   {
d9189a ¤   ¤   "You are attempting to mount a PGPdisk via a network path that "
a240d8 ¤   ¤   "points to a directory on the local machine. Since PGPdisk cannot "
5fa992 ¤   ¤   "fully resolve this path on non-Administrator accounts, you will be "
081b3b ¤   ¤   "forced to mount this PGPdisk in read-only mode."
fc42d0 ¤   },·
a4af5a
1d5403 ¤   // kPGPdiskErrorWasString
32c7a1 ¤   {
e713ca ¤   ¤   "The error was \"%s.\""
dd42d0 ¤   },·
0daf5a
702e82 ¤   // kPGPdiskConfirmWipeAllPasses
--319f 0008d9d8fdd4011015a Page 7 of CommonStrings.cpp
f7c7a1 ¤   {
6b26a7 ¤   ¤   "Are you sure you want to wipe the master and alternate passphrases "
0f30b6 ¤   ¤   "of all mounted PGPdisks? Only PGPdisks with public key passphrases "
a3f32a ¤   ¤   "will be affected, and those public key passphrases will be left "
c0bfb3 ¤   ¤   "alone."
a042d0 ¤   },·
c5af5a
3ff1ed ¤   // kPGPdiskConfirmWipeIndPasses
35c7a1 ¤   {
3026a7 ¤   ¤   "Are you sure you want to wipe the master and alternate passphrases "
4091e1 ¤   ¤   "of the specified PGPdisk? Only PGPdisks with public key passphrases "
9bf32a ¤   ¤   "will be affected, and those public key passphrases will be left "
c5bfb3 ¤   ¤   "alone."
2842d0 ¤   },·
18af5a
59c4c1 ¤   // kPGPdiskBadCASTAskConvertPNM
6fc7a1 ¤   {
90d1e8 ¤   ¤   "This PGPdisk was created with an earlier version of PGPdisk and "
d87ab2 ¤   ¤   "may not be secure. Do you wish to convert the PGPdisk to the newer "
e2515c ¤   ¤   "format? This may take several minutes, and if you choose \"No\", "
4bdab9 ¤   ¤   "you will not be allowed to modify files contained in the PGPdisk."
1842d0 ¤   },·
e7af5a
e2a397 ¤   // kPGPdiskBadCASTAskContinuePNM
23c7a1 ¤   {
5e4fd2 ¤   ¤   "This PGPdisk was being converted to the new, more secure format "
1e8785 ¤   ¤   "when the process was interrupted. Do you wish to continue the "
fe2097 ¤   ¤   "conversion? You must complete the conversion in order to access "
7d04be ¤   ¤   "the PGPdisk."
aa42d0 ¤   },·
b4af5a
99c13b ¤   // kPGPdiskBadCASTAskConvertPM
ebc7a1 ¤   {
26d1e8 ¤   ¤   "This PGPdisk was created with an earlier version of PGPdisk and "
ea7ab2 ¤   ¤   "may not be secure. Do you wish to convert the PGPdisk to the newer "
c7515c ¤   ¤   "format? This may take several minutes, and if you choose \"No\", "
d0dab9 ¤   ¤   "you will not be allowed to modify files contained in the PGPdisk."
5842d0 ¤   },·
96af5a
9db11f ¤   // kPGPdiskBadCASTAskContinuePM
9ac7a1 ¤   {
a74fd2 ¤   ¤   "This PGPdisk was being converted to the new, more secure format "
348785 ¤   ¤   "when the process was interrupted. Do you wish to continue the "
7b2097 ¤   ¤   "conversion? You must complete the conversion in order to access "
4104be ¤   ¤   "the PGPdisk."
3542d0 ¤   },·
feaf5a
61fbdb ¤   // kPGPdiskBadCASTReadOnly
e1c7a1 ¤   {
b2d1e8 ¤   ¤   "This PGPdisk was created with an earlier version of PGPdisk and "
c236ee ¤   ¤   "may not be secure. Since the specified PGPdisk file is read-only, "
c9d8d2 ¤   ¤   "it cannot be converted to the newer format at the current time. "
ebddc6 ¤   ¤   "Please mark it read/write or copy its contents to a new PGPdisk as "
6f3653 ¤   ¤   "soon as possible."
8a42d0 ¤   },·
31af5a
079dd6 ¤   // kPGPdiskConvertWizSheetTitleString
bec7a1 ¤   {
939bc7 ¤   ¤   "PGPdisk Conversion Wizard"
5e42d0 ¤   },·
adaf5a
425af7 ¤   // kPGPdiskConversionConvertMsgString
37c7a1 ¤   {
f884a0 ¤   ¤   "Converting: \"%s\""
d742d0 ¤   },·
dcaf5a
f7ff07 ¤   // kPGPdiskConversionDoneMsgString
adc7a1 ¤   {
e5ed33 ¤   ¤   "Finished: \"%s\""
c342d0 ¤   },·
76af5a
8dc201 ¤   // kPGPdiskConfirmCancelConversion
--d926 001a7584f054011015a Page 8 of CommonStrings.cpp
f7c7a1 ¤   {
2c3f36 ¤   ¤   "Are you sure you want to cancel the PGPdisk conversion process? "
99d6ff ¤   ¤   "You won't be able to access the PGPdisk again until you allow "
a7c147 ¤   ¤   "PGPdisk to finish the conversion."
7a42d0 ¤   },·
0caf5a
4f3644 ¤   // kPGPdiskGlobalCWizSheetTitleString
01c7a1 ¤   {
504542 ¤   ¤   "PGPdisk Global Conversion Wizard"
f242d0 ¤   },·
3eaf5a
305dd2 ¤   // kPGPdiskConfirmCancelSearching
e6c7a1 ¤   {
c9f88d ¤   ¤   "Are you sure you want to cancel the PGPdisk global search and "
da2a9d ¤   ¤   "conversion process?"
a142d0 ¤   },·
faaf5a
d2bc48 ¤   // kPGPdiskSearchingSearchMsgString
5dc7a1 ¤   {
a6ca99 ¤   ¤   "Searching:"
0642d0 ¤   },·
25af5a
d6f028 ¤   // kPGPdiskSearchingDoneMsgString
e0c7a1 ¤   {
af1129 ¤   ¤   "Done searching."
0542d0 ¤   },·
19af5a
355bee ¤   // kPGPdiskConversionWipedMsgString
62c7a1 ¤   {
0640d9 ¤   ¤   "This PGPdisk has previously had its master and alternate "
94c515 ¤   ¤   "passphrases wiped. In order to proceed with conversion, you must "
fee155 ¤   ¤   "enter the passphrase for one of the public keys left on the "
d0ba98 ¤   ¤   "PGPdisk. The conversion process will restore the PGPdisk to "
8a9d01 ¤   ¤   "ordinary functionality, with a new master passphrase identical to "
6689ac ¤   ¤   "the passphrase you enter for the public key. All public keys on "
2a3e45 ¤   ¤   "the PGPdisk (except for ADKs) will be removed."
359371 ¤   }
b4af5a
a782f7 };
--e4ff 000d7419dbc4011015b Page 1 of CommonStrings.h
541bc3 //////////////////////////////////////////////////////////////////////////////
0dd176 // CommonStrings.h
1a465d //
712c30 // Contains declarations for CommonStrings.cpp.
531bc3 //////////////////////////////////////////////////////////////////////////////
31af5a
21afb4 // $Id: CommonStrings.h,v 1.1.2.10.2.4 1998/10/25 23:31:35 nryan Exp $
beaf5a
f2cbce // Copyright (C) 1998 by Network Associates, Inc.
ff71ae // All rights reserved.
84af5a
69403c #ifndef Included_CommonStrings_h¤   // [
98e5fc #define Included_CommonStrings_h
e4af5a
4eaf5a
bd09b7 ////////////
52e738 // Constants
9609b7 ////////////
f7af5a
4973e3 const PGPUInt32 kPGPdiskMaxCommonStrings = 1024;
1faf5a
b7f210 static LPCSTR kPGPdiskUnknownString = "Unknown string.";
89af5a
a1af5a
7b2af8 //////////
18647f // Externs
242af8 //////////
6daf5a
269940 extern LPCSTR kPGPdiskCommonStrings[kPGPdiskMaxCommonStrings];
dbaf5a
8aaf5a
6ed557 ////////
5802c9 // Types
56d557 ////////
37af5a
8ba6f4 enum kPGPdiskCommonStrings
87bb36 {
a1a34f ¤   kPGPdiskCmdLineHelpString,·
654717 ¤   kPGPdiskBadCmdLineString,·
7de782 ¤   kPGPdiskBecauseString,·
bda53a ¤   kPGPdiskNoMemForErrorString,·
c51938 ¤   kPGPdiskRemoveAltsSuccessString,·
4f26e3 ¤   kPGPdiskNoPGPdisksToUnmountString,·
250a48 ¤   kPGPdiskLicenseToText,·
a0d2ac ¤   kPGPdiskDemoTimeoutWarning,·
e7bf0a ¤   kPGPdiskDemoBadCommandWarning,·
3a29bb ¤   kPGPdiskURL,·
9a4c8d ¤   kPGPdiskBuyNowURL,·
d0e481 ¤   kPGPdiskCPDTAddPassMsg,·
80582e ¤   kPGPdiskCPDTChangePassMsg,·
608a12 ¤   kPGPdiskSDTCreateDialogTitle,·
def3f2 ¤   kPGPdiskSDTSaveFilter,·
93c593 ¤   kPGPdiskSPDTChangePassMsg,·
df34a5 ¤   kPGPdiskSPDTMasterPassMsg,·
a06c75 ¤   kPGPdiskSPDTMountPassMsg,·
728d60 ¤   kPGPdiskSPDTPublicKeyPassMsg,·
eb5210 ¤   kPGPdiskSPDTRemovePassMsg,·
dd4a0b ¤   kPGPdiskPrefsSheetTitleString,·
eae356 ¤   kPGPdiskDiskWizSheetTitleString,·
cadecf ¤   kPGPdiskCreationCreateMsgString,·
55d950 ¤   kPGPdiskCreationDoneMsgString,·
71daec ¤   kPGPdiskFreeSize1MsgString,·
e7d41b ¤   kPGPdiskFreeSize2MsgString,·
1cd1b6 ¤   kPGPdiskFreeSize3MsgString,·
afc51f ¤   kPGPdiskOpenCmdString,·
4af2fc ¤   kPGPdiskGlobalConvertCmdString,·
f1c9c0 ¤   kPGPdiskCreateCmdString,·
af7568 ¤   kPGPdiskMountCmdString,·
d9af90 ¤   kPGPdiskUnmountCmdString,·
f8d128 ¤   kPGPdiskUnmountAllCmdString,·
ad368f ¤   kPGPdiskAddPassCmdString,·
d7c378 ¤   kPGPdiskChangePassCmdString,·
--d754 001a8fa07484011015b Page 2 of CommonStrings.h
cec46e ¤   kPGPdiskRemovePassCmdString,·
74aa90 ¤   kPGPdiskRemoveAltsCmdString,·
7fe6e6 ¤   kPGPdiskPubKeysCmdString,·
49aa33 ¤   kPGPdiskWipeAllCmdString,·
eb2bfd ¤   kPGPdiskWipeIndCmdString,·
bb9ad2 ¤   kPGPdiskAboutCmdString,·
804ef4 ¤   kPGPdiskHelpCmdString,·
96af38 ¤   kPGPdiskPrefsCmdString,·
edd190 ¤   kPGPdiskShellExtOpenMenuString,·
176a0e ¤   kPGPdiskShellExtMountMenuString,·
bbdabe ¤   kPGPdiskShellExtUnmountMenuString,·
1e3251 ¤   kPGPdiskShellExtAddPassMenuString,·
87afbc ¤   kPGPdiskShellExtChangePassMenuString,·
8bda0c ¤   kPGPdiskShellExtRemovePassMenuString,·
3ac493 ¤   kPGPdiskShellExtRemoveAltsMenuString,·
12cc46 ¤   kPGPdiskShellExtPubKeysMenuString,·
8888c6 ¤   kPGPdiskShellExtHelpMenuString,·
eb2aa8 ¤   kPGPdiskShellExtDescribeOpenString,·
4b187a ¤   kPGPdiskShellExtDescribeMountString,·
79f16a ¤   kPGPdiskShellExtDescribeUnmountString,·
95e004 ¤   kPGPdiskShellExtDescribeAddPassString,·
041d32 ¤   kPGPdiskShellExtDescribeChangePassString,·
6faaef ¤   kPGPdiskShellExtDescribeRemovePassString,·
0edfbb ¤   kPGPdiskShellExtDescribeRemoveAltsString,·
97408e ¤   kPGPdiskShellExtDescribePubKeysString,·
7f1d82 ¤   kPGPdiskShellExtDescribeHelpString,·
a97c17 ¤   kPGPdiskBetaTimeOutWarning,·
4fd4c0 ¤   kPGPdiskVerifyRemoveAlternates,·
4a8d7e ¤   kPGPdiskNotifyMountMaybeCorrupt,·
bb1999 ¤   kPGPdiskConfirmFormat,·
bd94d7 ¤   kPGPdiskAskToSavePrefs,·
ee76be ¤   kPGPdiskPGPdiskIsNotEncrypted,·
0f2352 ¤   kPGPdiskConfirmCancelFormat,·
05bd9d ¤   kPGPdiskResConfirmPGPdiskResQuit,·
6010e0 ¤   kPGPdiskConfirmCancelCreation,·
1a07b4 ¤   kPGPdiskForceROOnLoopbackString,·
44d51b ¤   kPGPdiskErrorWasString,·
9c5b54 ¤   kPGPdiskConfirmWipeAllPasses,·
2093b3 ¤   kPGPdiskConfirmWipeIndPasses,·
8a7f0e ¤   kPGPdiskBadCASTAskConvertPNM,·
f0e569 ¤   kPGPdiskBadCASTAskContinuePNM,·
ac0071 ¤   kPGPdiskBadCASTAskConvertPM,·
af9e0f ¤   kPGPdiskBadCASTAskContinuePM,·
34359b ¤   kPGPdiskBadCASTReadOnly,·
060e20 ¤   kPGPdiskConvertWizSheetTitleString,·
8e8678 ¤   kPGPdiskConversionConvertMsgString,·
850ad3 ¤   kPGPdiskConversionDoneMsgString,·
03b465 ¤   kPGPdiskConfirmCancelConversion,·
a23f14 ¤   kPGPdiskGlobalCWizSheetTitleString,·
2ca902 ¤   kPGPdiskConfirmCancelSearching,·
5b52b8 ¤   kPGPdiskSearchingSearchMsgString,·
1d5695 ¤   kPGPdiskSearchingDoneMsgString,·
2c1ad9 ¤   kPGPdiskConversionWipedMsgString
2f82f7 };
84af5a
a8587a #endif // Included_CommonStrings_h
--94de 0002626c4f14011015c Page 1 of DriverComm.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
62ffc4 // DriverComm.cpp
2b465d //
7d9db5 // Driver communication functions.
2b1bc3 //////////////////////////////////////////////////////////////////////////////
96af5a
448da7 // $Id: DriverComm.cpp,v 1.1.2.17 1998/08/04 02:10:06 nryan Exp $
24af5a
a1cbce // Copyright (C) 1998 by Network Associates, Inc.
5571ae // All rights reserved.
8daf5a
0a6931 #if defined(PGPDISK_MFC)
c5af5a
ac9e12 #include "StdAfx.h"
08af5a
6fdb21 #else
58333e #error Define PGPDISK_MFC.
ec05d6 #endif¤ // PGPDISK_MFC
cbaf5a
e99bcf #include "Required.h"
31ac00 #include "DriverComm.h"
ee5788 #include "PGPdiskVersion.h"
3abfe9 #include "UtilityFunctions.h"
67dd74 #include "WindowsVersion.h"
feaf5a
f8af5a
a42af8 //////////
11b932 // Globals
1f2af8 //////////
a2af5a
12e44d HANDLE DriverHandle = INVALID_HANDLE_VALUE;
c0af5a
b6af5a
5017a3 //////////////////////
080897 // Low-level functions
2f17a3 //////////////////////
07af5a
1b80df // IsDriverOpen returns TRUE if the PGPdisk driver is open, FALSE otherwise.
efaf5a
b677be PGPBoolean·
2bfb11 IsDriverOpen()
fcbb36 {
08f325 ¤   return (DriverHandle != INVALID_HANDLE_VALUE);
17efe6 }
faaf5a
265455 // OpenPGPdiskDriver opens a handle to the PGPdisk driver.
33af5a
982292 DualErr·
cc88ed OpenPGPdiskDriver()
20bb36 {
547d36 ¤   DualErr derr;
99af5a
d799f1 ¤   if (!IsDriverOpen())
54c7a1 ¤   {
8bdbaf ¤   ¤   DriverHandle = CreateFile(kPGPdiskDriverName,·
4f48b8 ¤   ¤   ¤   GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,·
79a5f7 ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL, NULL);
b9af5a
a402db ¤   ¤   if (DriverHandle == INVALID_HANDLE_VALUE)
09df43 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DriverNotInstalled);
749371 ¤   }
87af5a
fa33e3 ¤   return derr;
b6efe6 }
e5af5a
a679d2 // ClosePGPdiskDriver closes a handle to the PGPdisk driver.
87af5a
842292 DualErr·
a95a5b ClosePGPdiskDriver()
81bb36 {
ff7d36 ¤   DualErr derr;
26af5a
--af0d 0004cb67bbd4011015c Page 2 of DriverComm.cpp
cb9a2c ¤   if (IsDriverOpen())
b1c7a1 ¤   {
b7cc06 ¤   ¤   if (!::CloseHandle(DriverHandle))
6ec786 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_CloseHandleFailed);
4f9371 ¤   }
93af5a
a52361 ¤   if (derr.IsntError())
8ac7a1 ¤   {
31126e ¤   ¤   DriverHandle = INVALID_HANDLE_VALUE;
779371 ¤   }
b3af5a
7533e3 ¤   return derr;
e9efe6 }
7faf5a
1321ff // SendPacket sends a packet to the driver using DeviceIoControl.
3eaf5a
962292 DualErr·
d94166 SendPacket(PADPacketHeader pPacket, PGPUInt16 code, PGPUInt32 packetSize)
93bb36 {
4e9a95 ¤   DualErr¤¤   ¤   derr;
88b299 ¤   unsigned long¤  nBytesReturned;
fcaf5a
739599 ¤   pgpAssertAddrValid(pPacket, ADPacketHeader);
c93b83 ¤   pgpAssert(IsDriverOpen());
33af5a
fb07a0 ¤   // Initialize the packet header.
8fb616 ¤   pPacket->magic¤ = kPGPdiskADPacketMagic;
3daae7 ¤   pPacket->code¤  = code;
1768e9 ¤   pPacket->pDerr¤ = &derr;
26af5a
ba82f2 ¤   // Send the packet.
28ac5e ¤   if (!(DeviceIoControl(DriverHandle, IOCTL_PGPDISK_SENDPACKET, pPacket,·
4726b8 ¤   ¤   packetSize, NULL, NULL, &nBytesReturned, NULL)))
e8c7a1 ¤   {
023825 ¤   ¤   derr = DualErr(kPGDMinorError_DriverCommFailure, GetLastError());
109371 ¤   }
0aaf5a
c033e3 ¤   return derr;
d1efe6 }
0faf5a
45af5a
8afc6a ////////////////////////////////////
cc3d38 // Version and preferences functions
18fc6a ////////////////////////////////////
e8af5a
267111 // CheckDriverVersion makes sure the correct version of the driver is running.
1eaf5a
872292 DualErr·
325865 CheckDriverVersion()
a1bb36 {
e79d15 ¤   AD_QueryVersion¤QV;
da9a95 ¤   DualErr¤¤   ¤   derr;
466620 ¤   PGPUInt32¤  ¤   driverVersion;
cfaf5a
db3b83 ¤   pgpAssert(IsDriverOpen());
a6af5a
3c041d ¤   // Fill in and send the version query packet.
e2e711 ¤   QV.appVersion = kPGPdiskAppVersion;
40c369 ¤   QV.pDriverVersion = &driverVersion;
51af5a
b8158f ¤   derr = SendPacket((PADPacketHeader) &QV, kAD_QueryVersion, sizeof(QV));
abaf5a
8d9813 ¤   // Check for version incompatiblity.
082361 ¤   if (derr.IsntError())
8bc7a1 ¤   {
0b4cd7 ¤   ¤   if (driverVersion != kCompatDriverVersion)
072f32 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_DriverIsIncompatVersion);
c29371 ¤   }
a3af5a
d733e3 ¤   return derr;
dfefe6 }
4caf5a
--898a 000a668b4694011015c Page 3 of DriverComm.cpp
cffbf5 // NotifyUserLogoff tells the driver the current user is logging off. It will
8830f1 // then continually attempt to unmount all PGPdisks.
90af5a
c92292 DualErr·
1cf940 NotifyUserLogoff()
5cbb36 {
296dbe ¤   AD_NotifyUserLogoff¤NUL;
45705b ¤   DualErr¤¤   ¤   ¤   derr;
d4af5a
8582f2 ¤   // Send the packet.
16285a ¤   derr = SendPacket((PADPacketHeader) &NUL, kAD_NotifyUserLogoff,·
9d7ebb ¤   ¤   sizeof(NUL));
ffaf5a
9633e3 ¤   return derr;
62efe6 }
f3af5a
c3a891 // SetDriverPrefs informs the driver of the state of the application's
a20ef8 // preferences.
d3af5a
682292 DualErr·
8860f8 SetDriverPrefs(PGPBoolean autoUnmount, PGPUInt32 autoUnmountTimeout)
d1bb36 {
c800e7 ¤   AD_ChangePrefs¤ CP;
d39a95 ¤   DualErr¤¤   ¤   derr;
0baf5a
4211b8 ¤   CP.autoUnmount¤ ¤   = autoUnmount;
aa2f45 ¤   CP.unmountTimeout¤  = autoUnmountTimeout;
33af5a
cb82f2 ¤   // Send the packet.
23efa0 ¤   derr = SendPacket((PADPacketHeader) &CP, kAD_ChangePrefs, sizeof(CP));
cfaf5a
df33e3 ¤   return derr;
87efe6 }
9aaf5a
d6af5a
e08104 /////////////////////////////
f45a37 // PGPdisk-specific functions
c58104 /////////////////////////////
89af5a
686cbc // GetPGPdiskInfo asks the driver for info on all mounted PGPdisks.
a4af5a
282292 DualErr·
65621e GetPGPdiskInfo(PGPdiskInfo *pPDIArray, PGPUInt32 elemsArray)
a7bb36 {
ab37a2 ¤   AD_GetPGPdiskInfo¤  GPI;
2b705b ¤   DualErr¤¤   ¤   ¤   derr;
3daf5a
c91637 ¤   pgpAssertAddrValid(pPDIArray, PGPdiskInfo);
4c3b83 ¤   pgpAssert(IsDriverOpen());
1baf5a
f0daf7 ¤   // Fill in and send the GetPGPdiskInfo packet.
a7aa17 ¤   GPI.arrayElems¤ = elemsArray;
270f9b ¤   GPI.pPDIArray¤  = pPDIArray;
0aaf5a
0cad28 ¤   derr = SendPacket((PADPacketHeader) &GPI, kAD_GetPGPdiskInfo,·
d10d51 ¤   ¤   sizeof(GPI));
2caf5a
2d33e3 ¤   return derr;
73efe6 }
45af5a
c3af5a
b01277 // IsFileAPGPdisk asks the driver if the specified file is a mounted PGPdisk.
39af5a
c92292 DualErr·
5e6374 IsFileAPGPdisk(LPCSTR path, PGPBoolean *isFileAPGPdisk)
76bb36 {
a39a95 ¤   DualErr¤¤   ¤   derr;
5ca93b ¤   AD_QueryMounted¤QM;
65af5a
b738ba ¤   pgpAssertAddrValid(isFileAPGPdisk, PGPBoolean);
d4639f ¤   pgpAssertStrValid(path);
a6af5a
--13e2 0005d2ccbbf4011015c Page 4 of DriverComm.cpp
f9d16c ¤   QM.trueIfUsePath¤   = TRUE;
eb4f93 ¤   QM.path¤¤   ¤   ¤   = path;
22d9a8 ¤   QM.sizePath¤¤   ¤   = strlen(path) + 1;
103bc8 ¤   QM.pIsPGPdisk¤  ¤   = isFileAPGPdisk;
40af5a
1ddc42 ¤   derr = SendPacket((PADPacketHeader) &QM, kAD_QueryMounted, sizeof(QM));
3aaf5a
ac33e3 ¤   return derr;
32efe6 }
ddaf5a
0dd01e // IsVolumeAPGPdisk asks the driver if the specified volume is a PGPdisk.
ecaf5a
6c2292 DualErr·
ae1bc9 IsVolumeAPGPdisk(PGPUInt8 drive, PGPBoolean *isVolumeAPGPdisk)
a7bb36 {
119a95 ¤   DualErr¤¤   ¤   derr;
a9a93b ¤   AD_QueryMounted¤QM;
efaf5a
964185 ¤   pgpAssertAddrValid(isVolumeAPGPdisk, PGPBoolean);
14aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
b9af5a
6d98f8 ¤   QM.trueIfUsePath¤   = FALSE;
0e9e51 ¤   QM.drive¤   ¤   ¤   = drive;
a72e68 ¤   QM.pIsPGPdisk¤  ¤   = isVolumeAPGPdisk;
daaf5a
a8dc42 ¤   derr = SendPacket((PADPacketHeader) &QM, kAD_QueryMounted, sizeof(QM));
a4af5a
3333e3 ¤   return derr;
92efe6 }
73af5a
ff6310 // SendMountRequest sends an already filled in mount packet to the driver.
e1af5a
8f2292 DualErr·
38aa34 SendMountRequest(PAD_Mount pMNT)
f6bb36 {
fa7d36 ¤   DualErr derr;
12af5a
4ebccc ¤   pgpAssertAddrValid(pMNT, AD_Mount);
b64d28 ¤   derr = SendPacket((PADPacketHeader) pMNT, kAD_Mount, sizeof(AD_Mount));
c5af5a
9533e3 ¤   return derr;
97efe6 }
52af5a
dd093a // SendUnmountRequest sends an already filled in unmount packet to the
beb3bd // driver.
81af5a
412292 DualErr·
ef5a38 SendUnmountRequest(PAD_Unmount pUNMNT)
3bbb36 {
f37d36 ¤   DualErr derr;
5daf5a
34de3b ¤   pgpAssertAddrValid(pUNMNT, AD_Unmount);
f5af5a
4230f5 ¤   derr = SendPacket((PADPacketHeader) pUNMNT, kAD_Unmount,·
f22bb0 ¤   ¤   sizeof(AD_Unmount));
73af5a
de33e3 ¤   return derr;
2aefe6 }
44af5a
7aaf5a
248104 /////////////////////////////
b2cce3 // Volume/directory functions
c88104 /////////////////////////////
51af5a
5da34b // AreFilesOpenOnDrive returns TRUE if the given drive has open file handles,·
a6e111 // FALSE otherwise. It needs to ask the driver to get this information.
4eaf5a
672292 DualErr·
29c520 AreFilesOpenOnDrive(PGPUInt8 drive, PGPBoolean *areFilesOpen)
02bb36 {
c1c1b7 ¤   AD_QueryOpenFiles¤  QOF;
5d705b ¤   DualErr¤¤   ¤   ¤   derr;
--bcac 000bb9a6ba94011015c Page 5 of DriverComm.cpp
e0af5a
15ebe0 ¤   pgpAssertAddrValid(areFilesOpen, PGPBoolean);
a8aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
33af5a
7877f4 ¤   // Fill it in and send the packet to the driver.
132add ¤   QOF.drive¤  ¤   ¤   = drive;
b2860c ¤   QOF.pHasOpenFiles¤  = areFilesOpen;
9baf5a
e48f16 ¤   derr = SendPacket((PADPacketHeader) &QOF, kAD_QueryOpenFiles,·
59f590 ¤   ¤   sizeof(QOF));
23af5a
a233e3 ¤   return derr;
b0efe6 }
abaf5a
995259 // LockUnlockVolume locks or unlocks a mounted volume.
bcaf5a
452292 DualErr·
276d8d LockUnlockVolume(PGPUInt8 drive, LockOp lockOp)
4ebb36 {
d3e881 ¤   AD_LockUnlockVol¤   LUV;
d7705b ¤   DualErr¤¤   ¤   ¤   derr;
c7af5a
7caa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
bbaf5a
ab3ceb ¤   // Prepare the lock request.
06b7d9 ¤   LUV.drive¤  = drive;
d865ca ¤   LUV.lockOp¤ = lockOp;
13af5a
79b619 ¤   // Send the request to the driver.
4a52aa ¤   derr = SendPacket((PADPacketHeader) &LUV, kAD_LockUnlockVol, sizeof(LUV));
a0af5a
bb33e3 ¤   return derr;
f7efe6 }
6eaf5a
4d05c5 // DirectDiskRead reads blocks from a locked mounted volume.
c9af5a
5d2292 DualErr·
1efee7 DirectDiskRead(
807fa2 ¤   PGPUInt8¤   drive,·
674f03 ¤   PGPUInt8¤   *buf,·
ba803d ¤   PGPUInt32¤  bufSize,·
8a15ca ¤   PGPUInt64¤  pos,·
a1eb3c ¤   PGPUInt32¤  nBlocks)
33bb36 {
250990 ¤   AD_ReadWriteVol¤RWV;
199a95 ¤   DualErr¤¤   ¤   derr;
deaf5a
f3aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
7fb442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
4eaf5a
5b33f7 ¤   // Prepare the read request.
1f2c18 ¤   RWV.trueIfRead¤ = TRUE;
ace17b ¤   RWV.drive¤  ¤   = drive;
ce1cfe ¤   RWV.buf¤¤   ¤   = buf;
179473 ¤   RWV.bufSize¤¤   = bufSize;
57e756 ¤   RWV.pos¤¤   ¤   = pos;
a50c84 ¤   RWV.nBlocks¤¤   = nBlocks;
d3af5a
fcb619 ¤   // Send the request to the driver.
6a661f ¤   derr = SendPacket((PADPacketHeader) &RWV, kAD_ReadWriteVol, sizeof(RWV));
3faf5a
db33e3 ¤   return derr;
3befe6 }
e9af5a
50897d // DirectDiskWrite writes blocks to a locked mounted volume.
3caf5a
5b2292 DualErr·
f0e2dc DirectDiskWrite(
987fa2 ¤   PGPUInt8¤   drive,·
024f03 ¤   PGPUInt8¤   *buf,·
77803d ¤   PGPUInt32¤  bufSize,·
bb15ca ¤   PGPUInt64¤  pos,·
--f432 0000dcc558f4011015c Page 6 of DriverComm.cpp
f6eb3c ¤   PGPUInt32¤  nBlocks)
e3bb36 {
3c0990 ¤   AD_ReadWriteVol¤RWV;
119a95 ¤   DualErr¤¤   ¤   derr;
77af5a
ebaa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
36b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
d3af5a
9c33f7 ¤   // Prepare the read request.
9cada6 ¤   RWV.trueIfRead¤ = FALSE;
a7e17b ¤   RWV.drive¤  ¤   = drive;
7e1cfe ¤   RWV.buf¤¤   ¤   = buf;
d39473 ¤   RWV.bufSize¤¤   = bufSize;
1fe756 ¤   RWV.pos¤¤   ¤   = pos;
af0c84 ¤   RWV.nBlocks¤¤   = nBlocks;
46af5a
fcb619 ¤   // Send the request to the driver.
e2661f ¤   derr = SendPacket((PADPacketHeader) &RWV, kAD_ReadWriteVol, sizeof(RWV));
dcaf5a
4033e3 ¤   return derr;
e0efe6 }
bdaf5a
06dc4c // QueryVolInfo gets some extra volume information from the driver.
d9af5a
122292 DualErr·
b9375d QueryVolInfo(PGPUInt8 drive, PGPUInt16 *pBlockSize, PGPUInt64 *pTotalBlocks)
46bb36 {
63d78a ¤   AD_QueryVolInfo¤QVI;
899a95 ¤   DualErr¤¤   ¤   derr;
afaf5a
7caa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
d89fea ¤   pgpAssertAddrValid(pBlockSize, PGPUInt16);
25acbf ¤   pgpAssertAddrValid(pTotalBlocks, PGPUInt64);
33af5a
799f66 ¤   // Prepare the request.
8310f2 ¤   QVI.drive¤  ¤   ¤   = drive;
cc04c9 ¤   QVI.pBlockSize¤ ¤   = pBlockSize;
e6d95c ¤   QVI.pTotalBlocks¤   = pTotalBlocks;
0aaf5a
32b619 ¤   // Send the request to the driver.
5bcb01 ¤   derr = SendPacket((PADPacketHeader) &QVI, kAD_QueryVolInfo, sizeof(QVI));
83af5a
a633e3 ¤   return derr;
b5efe6 }
2daf5a
26af5a
a220a9 ///////////////////
e22f4a // Memory functions
2a20a9 ///////////////////
46af5a
715d78 // AllocLockedMem allocates and returns a block of locked memory of the
278106 // specified size (rounded up to the nearest page boundary).
3baf5a
402292 DualErr·
f1e74a AllocLockedMem(PGPUInt32 nBytes, void **pPMem)
96bb36 {
44be41 ¤   DualErr¤¤   derr;
630e8d ¤   PGPBoolean¤ allocedMem¤ = FALSE;
52a8ff ¤   void¤   ¤   *pLockedMem;
c7af5a
33deed ¤   pgpAssertAddrValid(pPMem, VoidAlign);
f5af5a
2c5140 ¤   // Allocate the memory.
9ad8eb ¤   pLockedMem = VirtualAlloc(NULL, nBytes, MEM_COMMIT, PAGE_READWRITE);
bcaf5a
17b749 ¤   if (IsNull(pLockedMem))
b3ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
97af5a
6e2d34 ¤   allocedMem = derr.IsntError();
a3af5a
1135d2 ¤   // Ask the driver to lock it.
0d2361 ¤   if (derr.IsntError())
--4e7c 001a02cb6844011015c Page 7 of DriverComm.cpp
f7c7a1 ¤   {
084e30 ¤   ¤   AD_LockUnlockMem LUM;
87af5a
fed223 ¤   ¤   LUM.pMem¤   ¤   = pLockedMem;
5e5547 ¤   ¤   LUM.nBytes¤ ¤   = nBytes;
3d80cb ¤   ¤   LUM.trueForLock¤= TRUE;
f2af5a
628688 ¤   ¤   derr = SendPacket((PADPacketHeader) &LUM, kAD_LockUnlockMem,·
0585f1 ¤   ¤   ¤   sizeof(LUM));
e89371 ¤   }
f8af5a
572361 ¤   if (derr.IsntError())
59c7a1 ¤   {
660041 ¤   ¤   (* pPMem) = pLockedMem;
ef9371 ¤   }
95af5a
764bb3 ¤   if (derr.IsError())
21c7a1 ¤   {
285b11 ¤   ¤   if (allocedMem)
cfec54 ¤   ¤   ¤   VirtualFree(pLockedMem, 0, MEM_RELEASE);
dc9371 ¤   }
c5af5a
c033e3 ¤   return derr;
09efe6 }
c5af5a
17c81a // FreeLockedMem frees a block of locked memory previously allocated by
4fafd6 // AllocLockedMem.
0caf5a
e72292 DualErr·
800f80 FreeLockedMem(void *pMem, PGPUInt32 nBytes)
74bb36 {
85e7c7 ¤   AD_LockUnlockMem¤   LUM;
13705b ¤   DualErr¤¤   ¤   ¤   derr;
7caf5a
b8a97e ¤   pgpAssertAddrValid(pMem, VoidAlign);
e0af5a
a792cc ¤   // Ask the driver to unlock the memory.
8280d5 ¤   LUM.pMem¤   ¤   = pMem;
5d624f ¤   LUM.nBytes¤ ¤   = nBytes;
93f24a ¤   LUM.trueForLock¤= FALSE;
ebaf5a
84eee1 ¤   derr = SendPacket((PADPacketHeader) &LUM, kAD_LockUnlockMem, sizeof(LUM));
5caf5a
3ccf93 ¤   // Free the memory.
a92361 ¤   if (derr.IsntError())
bdc7a1 ¤   {
9ccdda ¤   ¤   if (!::VirtualFree(pMem, 0, MEM_RELEASE))
1ba033 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_VirtualFreeFailed);
3b9371 ¤   }
35af5a
8d33e3 ¤   return derr;
a0efe6 }
--9c78 001a7d700cf4011015d Page 1 of DriverComm.h
541bc3 //////////////////////////////////////////////////////////////////////////////
6512be // DriverComm.h
31465d //
685712 // Declarations for DriverComm.cpp.
591bc3 //////////////////////////////////////////////////////////////////////////////
deaf5a
999e07 // $Id: DriverComm.h,v 1.1.2.14 1998/08/04 02:10:06 nryan Exp $
b8af5a
a3cbce // Copyright (C) 1998 by Network Associates, Inc.
0971ae // All rights reserved.
a8af5a
a5eb49 #ifndef Included_DriverComm_h¤  // [
a8ceef #define Included_DriverComm_h
87af5a
df3a85 #include "DualErr.h"
8b0092 #include "Packets.h"
b8af5a
7caf5a
c86cc2 /////////////////////
5d13d2 // Exported functions
3c6cc2 /////////////////////
a7af5a
526183 PGPBoolean¤ IsDriverOpen();
c50d42 DualErr¤¤   OpenPGPdiskDriver();
85fd94 DualErr¤¤   ClosePGPdiskDriver();
87af5a
bc256b DualErr¤¤   CheckDriverVersion();
9ac0ed DualErr¤¤   NotifyUserLogoff();
1daf5a
c8933a DualErr¤¤   SetDriverPrefs(PGPBoolean autoUnmount,·
0db3be ¤   ¤   ¤   ¤   PGPUInt32 autoUnmountTimeout);
47af5a
3a45a1 DualErr¤¤   GetPGPdiskInfo(PGPdiskInfo *pPDIArray, PGPUInt32 elemsArray);
6fe837 DualErr¤¤   IsFileAPGPdisk(LPCSTR path, PGPBoolean *isFileAPGPdisk);
fe1820 DualErr¤¤   IsVolumeAPGPdisk(PGPUInt8 drive, PGPBoolean *isVolumeAPGPdisk);
98af5a
63c9bd DualErr¤¤   SendMountRequest(PAD_Mount pMNT);
8cc59f DualErr¤¤   SendUnmountRequest(PAD_Unmount pUNMNT);
d6af5a
40fbb6 DualErr¤¤   AreFilesOpenOnDrive(PGPUInt8 drive, PGPBoolean *areFilesOpen);
0faf5a
6dd689 DualErr¤¤   LockUnlockVolume(PGPUInt8 drive, LockOp lockOp);
c2f3f9 DualErr¤¤   DirectDiskRead(PGPUInt8 drive, PGPUInt8 *buf, PGPUInt32 bufSize,·
51b129 ¤   ¤   ¤   ¤   PGPUInt64 pos, PGPUInt32 nBlocks);
9f8244 DualErr¤¤   DirectDiskWrite(PGPUInt8 drive, PGPUInt8 *buf, PGPUInt32 bufSize,·
cbb129 ¤   ¤   ¤   ¤   PGPUInt64 pos, PGPUInt32 nBlocks);
248b8d DualErr¤¤   QueryVolInfo(PGPUInt8 drive, PGPUInt16 *pBlockSize,·
cd7d17 ¤   ¤   ¤   ¤   PGPUInt64 *pTotalBlocks);
96af5a
a0a4c4 DualErr¤¤   AllocLockedMem(PGPUInt32 nBytes, void **pPMem);
b23a93 DualErr¤¤   FreeLockedMem(void *pMem, PGPUInt32 nBytes);
65af5a
a7b36b #endif¤ // ] Included_DriverComm_h
--6c96 0014bca9ac14011015e Page 1 of DualErr.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
4e9f65 // DualErr.cpp
95465d //
2adcb5 // Holds static data members of class DualErr.
3b1bc3 //////////////////////////////////////////////////////////////////////////////
60af5a
d1fbe4 // $Id: DualErr.cpp,v 1.1.2.14 1998/08/04 02:10:07 nryan Exp $
54af5a
9acbce // Copyright (C) 1998 by Network Associates, Inc.
6e71ae // All rights reserved.
feaf5a
1a6931 #if defined(PGPDISK_MFC)
65af5a
199e12 #include "StdAfx.h"
4eaf5a
cc4268 #elif defined(PGPDISK_95DRIVER)
0aaf5a
ce06a9 #include <vtoolscp.h>
7a86d2 #include LOCKED_CODE_SEGMENT
f95269 #include LOCKED_DATA_SEGMENT
12af5a
8bf5a6 #elif defined(PGPDISK_NTDRIVER)
73af5a
17d7a1 #include <vdw.h>
3aaf5a
c5db21 #else
e8112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
6a05d6 #endif¤ // PGPDISK_MFC
2daf5a
8e9bcf #include "Required.h"
c63a85 #include "DualErr.h"
64af5a
44af5a
605270 ////////////////////////////
69111a // Globals for class DualErr
1d5270 ////////////////////////////
1baf5a
4b224e DualErr DualErr::NoError = DualErr();
--1630 000a35c561e4011015f Page 1 of DualErr.h
541bc3 //////////////////////////////////////////////////////////////////////////////
e39aa4 // DualErr.h
03465d //
02a62b // Declaration and implementation of class DualErr.
ce1bc3 //////////////////////////////////////////////////////////////////////////////
86af5a
9a5fc4 // $Id: DualErr.h,v 1.1.2.10 1998/08/04 02:10:08 nryan Exp $
4faf5a
49cbce // Copyright (C) 1998 by Network Associates, Inc.
9671ae // All rights reserved.
5faf5a
a7b410 #ifndef Included_DualErr_h¤ // [
14d3d2 #define Included_DualErr_h
a2af5a
bfea4b #if PGPDISK_PUBLIC_KEY
352f8d #include "pgpErrors.h"
0b38e4 #endif¤ // PGPDISK_PUBLIC_KEY
9caf5a
aab616 #include "Errors.h"
a0af5a
43e79f // Align to 1.
c5fcdb #pragma pack(push, 1)
87af5a
98af5a
9bd557 ////////
c702c9 // Types
fbd557 ////////
adaf5a
4766a8 // ExternalErrorType defines what type of external error a DualErr holds.
d7af5a
41d482 enum ExternalErrorType {kEET_Win32Error, kEET_KernelModeError,·
19216c ¤   kEET_PGPSdkError};
f2af5a
240149 #if defined(PGPDISK_NTDRIVER)
a00517 const ExternalErrorType kDefaultExErrorType = kEET_KernelModeError;
1adb21 #else
dc79a0 const ExternalErrorType kDefaultExErrorType = kEET_Win32Error;
132fb2 #endif // PGPDISK_NTDRIVER
44af5a
00af5a
249791 ////////////////
ee3bf3 // Class DualErr
829791 ////////////////
31af5a
f85252 // Note: This is code adapted from the CComboError class of the pfl. Instead
cca414 // of including a PGPError, the class includes a PGDMinorError and an
d1e9a3 // 'external error' type.
23af5a
ff9b84 class DualErr
6abb36 {
805ed4 public:
c1450e ¤   static DualErr¤ ¤   NoError;
2faf5a
72faa7 ¤   PGDMinorError¤  ¤   mMinorError;
7caebd ¤   ExternalErrorType¤  mExErrorType;
685227 ¤   ExternalError¤  ¤   mExternalError;
2267c5 ¤
d57b52 ¤   inline¤ ¤   ¤   ¤   DualErr(PGDMinorError merr = kPGDMinorError_NoErr,·
0b26be ¤   ¤   ¤   ¤   ¤   ¤   ¤   ExternalError exerr = kExternalError_NoErr,·
6f31d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ExternalErrorType extype = kDefaultExErrorType)
8e8fec ¤   ¤   ¤   ¤   ¤   ¤   {
fd4eca ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mMinorError¤¤   = merr;
9a3ab6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mExErrorType¤   = extype;
56995f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mExternalError¤ = exerr;
15db3c ¤   ¤   ¤   ¤   ¤   ¤   }
7daf5a
c3ea4b #if PGPDISK_PUBLIC_KEY
9eaf5a
e37442 ¤   inline¤ ¤   ¤   ¤   DualErr(PGPError pgpErr)
4b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
e7cffe ¤   ¤   ¤   ¤   ¤   ¤   ¤   mExErrorType = kEET_PGPSdkError;
a33852 ¤   ¤   ¤   ¤   ¤   ¤   ¤   mExternalError = (PGPUInt32) pgpErr;
--220f 001cd4c15734011015f Page 2 of DualErr.h
e0af5a
935752 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pgpErr == kPGPError_UserAbort)
e36f7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mMinorError = kPGDMinorError_UserAbort;
f3af74 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else if (IsPGPError(pgpErr))
5c840f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mMinorError = kPGDMinorError_SDKFuncFailed;
38c4dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
3b991c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mMinorError = kPGDMinorError_NoErr;
55db3c ¤   ¤   ¤   ¤   ¤   ¤   }
4eaf5a
2a38e4 #endif¤ // PGPDISK_PUBLIC_KEY
a6af5a
888907 ¤   inline PGPBoolean¤  IsError()
938fec ¤   ¤   ¤   ¤   ¤   ¤   {
8bb5d4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   return (HasPGDMinorError() || HasExternalError());
43db3c ¤   ¤   ¤   ¤   ¤   ¤   }
2f2b85 ¤   ¤   ¤   ¤
dca224 ¤   inline PGPBoolean¤  IsntError()
2a8fec ¤   ¤   ¤   ¤   ¤   ¤   {
b24e53 ¤   ¤   ¤   ¤   ¤   ¤   ¤   return !IsError();
92db3c ¤   ¤   ¤   ¤   ¤   ¤   }
202b85 ¤   ¤   ¤   ¤
6f2c6f ¤   inline PGPBoolean¤  HasPGDMinorError()
338fec ¤   ¤   ¤   ¤   ¤   ¤   {
1af6b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IsPGDMinorError(mMinorError);
b6db3c ¤   ¤   ¤   ¤   ¤   ¤   }
68af5a
e8b3dd ¤   inline PGPBoolean¤  HasExternalError()
a18fec ¤   ¤   ¤   ¤   ¤   ¤   {
c34c46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IsExternalError(mExternalError);
8bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
bd82f7 };
b9af5a
3e1cb1 // Restore alignment.
3cf421 #pragma pack(pop)
49af5a
cd6a5b #endif¤ // ] Included_DualErr_h
--143a 000c1a0b22e40110160 Page 1 of Errors.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
f6ba39 // Errors.cpp
a3465d //
2c33b9 // Defines error strings.
8c1bc3 //////////////////////////////////////////////////////////////////////////////
5faf5a
87b87a // $Id: Errors.cpp,v 1.1.2.34.2.5 1998/10/25 23:31:36 nryan Exp $
74af5a
89cbce // Copyright (C) 1998 by Network Associates, Inc.
c271ae // All rights reserved.
91af5a
c66931 #if defined(PGPDISK_MFC)
61af5a
ce9e12 #include "StdAfx.h"
00af5a
f84268 #elif defined(PGPDISK_95DRIVER)
7faf5a
e606a9 #include <vtoolscp.h>
1786d2 #include LOCKED_CODE_SEGMENT
fd5269 #include LOCKED_DATA_SEGMENT
77af5a
d4f5a6 #elif defined(PGPDISK_NTDRIVER)
e5af5a
04d7a1 #include <vdw.h>
2daf5a
fadb21 #else
dd112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
2705d6 #endif¤ // PGPDISK_MFC
03af5a
919bcf #include "Required.h"
d7b616 #include "Errors.h"
a2af5a
a8af5a
645270 ////////////////////////////
76c758 // String association arrays
7e5270 ////////////////////////////
5daf5a
ced567 LPCSTR kPGPdiskMajorErrorStrings[kPGPdiskMaxMajorErrorStrings] =
3dbb36 {
2e81b3 ¤   // kPGDMajorError_NoErr
44c7a1 ¤   {
a0114b ¤   ¤   "No error occured."
fd42d0 ¤   },·
deaf5a
2b0b24 ¤   // kPGDMajorError_AppInitFailed
59c7a1 ¤   {
6e0b8c ¤   ¤   "PGPdisk was unable to start %s."
8542d0 ¤   },·
0caf5a
808517 ¤   // kPGDMajorError_PGPdiskCreationFailed
53c7a1 ¤   {
42e220 ¤   ¤   "PGPdisk was unable to create a new PGPdisk %s."
6d42d0 ¤   },·
74af5a
9563db ¤   // kPGDMajorError_PGPdiskMountFailed
f8c7a1 ¤   {
9686e9 ¤   ¤   "This PGPdisk could not be mounted %s."
1a42d0 ¤   },·
3faf5a
d03177 ¤   // kPGDMajorError_PGPdiskTooBig
02c7a1 ¤   {
1fa47c ¤   ¤   "PGPdisks cannot be larger than 2048 MB (Win95) or 1024 GB (NT) in "
d587de ¤   ¤   "size."
7e42d0 ¤   },·
c7af5a
1f0dec ¤   // kPGDMajorError_PGPdiskTooSmall
13c7a1 ¤   {
a7a9c9 ¤   ¤   "PGPdisks cannot be smaller than 100k in size."
3742d0 ¤   },·
94af5a
cacbda ¤   // kPGDMajorError_PGPdiskUnmountFailed
c1c7a1 ¤   {
--8670 0007a041d7740110160 Page 2 of Errors.cpp
536f07 ¤   ¤   "The PGPdisk %c:\\ could not be unmounted %s."
d142d0 ¤   },·
62af5a
c61ebf ¤   // kPGDMajorError_PGPdiskReadError
0cc7a1 ¤   {
277ddf ¤   ¤   "A read operation on the PGPdisk %c:\\ has failed %s. Do you wish "
8014d5 ¤   ¤   "to attempt an emergency unmount of the PGPdisk?"
9f42d0 ¤   },·
04af5a
966fab ¤   // kPGDMajorError_PGPdiskWriteError
02c7a1 ¤   {
7ac8a0 ¤   ¤   "A write operation on the PGPdisk %c:\\ has failed %s. Do you wish "
7114d5 ¤   ¤   "to attempt an emergency unmount of the PGPdisk?"
e242d0 ¤   },·
d4af5a
969bca ¤   // kPGDMajorError_AboutBoxDisplayFailed
7dc7a1 ¤   {
0de67e ¤   ¤   "PGPdisk was unable to display the about box %s."
8142d0 ¤   },·
05af5a
75f6d9 ¤   // kPGDMajorError_PreferencesAccessFailed
1bc7a1 ¤   {
0a2a0f ¤   ¤   "An attempt to access the PGPDisk preferences failed %s."
0e42d0 ¤   },·
5baf5a
59e5b5 ¤   // kPGDMajorError_TimeoutValueTooSmall
bbc7a1 ¤   {
561ce4 ¤   ¤   "The inactivity timeout value must be greater than 1 minute."
ad42d0 ¤   },·
66af5a
305cb9 ¤   // kPGDMajorError_TimeoutValueTooBig
8cc7a1 ¤   {
55e74a ¤   ¤   "The inactivity timeout value must be less than 999 minutes."
2642d0 ¤   },·
12af5a
528fa5 ¤   // kPGDMajorError_NotEnoughDiskSpace
a7c7a1 ¤   {
ac1303 ¤   ¤   "There is not enough free disk space to create a PGPdisk of the "
cacd53 ¤   ¤   "size you specified. Please enter a smaller size."
ed42d0 ¤   },·
edaf5a
39a9a9 ¤   // kPGDMajorError_PassphraseTooSmall
46c7a1 ¤   {
735298 ¤   ¤   "Your passphrase must be at least 8 characters in length. Please "
c87a28 ¤   ¤   "choose a longer passphrase and try again."
c442d0 ¤   },·
3daf5a
4e4ec4 ¤   // kPGDMajorError_PassphraseNotConfirmed
92c7a1 ¤   {
7a9263 ¤   ¤   "The passphrase you entered does not match the phrase you typed "
b19382 ¤   ¤   "into the confirmation field. Please correct this and try again."
c942d0 ¤   },·
95af5a
b0c43a ¤   // kPGDMajorError_PGPdiskAddPassFailed
7ec7a1 ¤   {
960257 ¤   ¤   "PGPdisk was unable to add another passphrase %s."
3342d0 ¤   },·
5baf5a
9835f9 ¤   // kPGDMajorError_PGPdiskChangePassFailed
44c7a1 ¤   {
e8b634 ¤   ¤   "PGPdisk was unable to change your passphrase %s."
7d42d0 ¤   },·
ecaf5a
f973b3 ¤   // kPGDMajorError_PGPdiskRemoveOnePassFailed
6cc7a1 ¤   {
8bdca2 ¤   ¤   "PGPdisk was unable to remove your passphrase %s."
4a42d0 ¤   },·
8aaf5a
ba52de ¤   // kPGDMajorError_IncorrectPassphrase
20c7a1 ¤   {
3296b6 ¤   ¤   "The passphrase you entered is not a valid master or alternate "
7a08dc ¤   ¤   "passphrase for this PGPdisk. Please try again."
--9700 0005c58a21740110160 Page 3 of Errors.cpp
c442d0 ¤   },·
b9af5a
51ef5c ¤   // kPGDMajorError_IncorrectMasterPassphrase
07c7a1 ¤   {
cbdeed ¤   ¤   "The passphrase you entered is not a valid master passphrase for "
4f0c6c ¤   ¤   "this PGPdisk. Please try again."
4242d0 ¤   },·
2faf5a
e24038 ¤   // kPGDMajorError_TriedRemoveMasterPass
67c7a1 ¤   {
8346fa ¤   ¤   "You cannot remove the master passphrase from a PGPdisk. Please "
e1376b ¤   ¤   "enter an alternate passphrase instead."
7e42d0 ¤   },·
e7af5a
959d69 ¤   // kPGDMajorError_IncorrectAlternatePassphrase
f9c7a1 ¤   {
0e1908 ¤   ¤   "The passphrase you entered is not a valid alternate passphrase for "
660c6c ¤   ¤   "this PGPdisk. Please try again."
1142d0 ¤   },·
7caf5a
56dd6b ¤   // kPGDMajorError_PassphraseAlreadyExists
28c7a1 ¤   {
b80479 ¤   ¤   "That passphrase already exists. Please try again."
8342d0 ¤   },·
d0af5a
eedabd ¤   // kPGDMajorError_NotCompatibleWindows
1ac7a1 ¤   {
9f13a6 ¤   ¤   "PGPdisk could not be started because it is only compatible with "
c072bc ¤   ¤   "Windows 95/98 and Windows NT 4.0 or later."
7a42d0 ¤   },·
71af5a
26912d ¤   // kPGDMajorError_TriedPassOpOnMountedPGPdisk
dec7a1 ¤   {
a35d52 ¤   ¤   "You must first unmount the selected PGPdisk before adding, "
942767 ¤   ¤   "changing or removing a passphrase or public key."
e942d0 ¤   },·
57af5a
1bb983 ¤   // kPGDMajorError_InvalidCipherContext
a5c7a1 ¤   {
552120 ¤   ¤   "The PGPdisk mounted as drive %c:\\ has been emergency unmounted "
2e52ef ¤   ¤   "%s. It may corrupted - please backup all files on this PGPdisk as "
743653 ¤   ¤   "soon as possible."
e142d0 ¤   },·
ccaf5a
571459 ¤   // kPGDMajorError_DriverUpdatePrefsFailed
f7c7a1 ¤   {
dd842d ¤   ¤   "The PGPdisk application was unable to communicate with the PGPdisk "
cebcb6 ¤   ¤   "driver %s. Please restart your computer and reinstall PGPdisk."
c942d0 ¤   },·
caaf5a
2d2d67 ¤   // kPGDMajorError_DialogDisplayFailed
27c7a1 ¤   {
37ef6c ¤   ¤   "PGPdisk was unable to display a dialog box %s."
af42d0 ¤   },·
3baf5a
dce9b2 ¤   // kPGDMajorError_ChoseReadOnlyDirInCreate
43c7a1 ¤   {
9b6702 ¤   ¤   "The directory you have chosen is write-protected. Please choose "
14239a ¤   ¤   "another."
5242d0 ¤   },·
62af5a
028d96 ¤   // kPGDMajorError_ChoseTooSmallDirInCreate
5dc7a1 ¤   {
f7eafa ¤   ¤   "The directory you have chosen does not have the minimum required "
4f5234 ¤   ¤   "amount of free space (about 100k). Please choose another."
9542d0 ¤   },·
12af5a
c52952 ¤   // kPGDMajorError_ChoseInvalidDirInCreate
a9c7a1 ¤   {
ba2f80 ¤   ¤   "The directory you have chosen does not exist. Please choose "
8c239a ¤   ¤   "another."
5c42d0 ¤   },·
--9ff9 000595ddaba40110160 Page 4 of Errors.cpp
e0af5a
97cd76 ¤   // kPGDMajorError_NoSleepOnUnmountFailure
f1c7a1 ¤   {
59adf4 ¤   ¤   "Computer sleep has been prevented because PGPdisk could not "
4a101f ¤   ¤   "unmount one or more of its volumes. You can disable this check by "
90d36c ¤   ¤   "deselecting the appropriate option from within the PGPdisk "
d7386f ¤   ¤   "preferences."
6342d0 ¤   },·
7eaf5a
662209 ¤   // kPGDMajorError_BadCommandAfterBetaTimeout
acc7a1 ¤   {
8c9d56 ¤   ¤   "This command is unavailable because your beta copy of PGPdisk has "
7b5a44 ¤   ¤   "expired."
8b42d0 ¤   },·
1faf5a
c0faa3 ¤   // kPGDMajorError_ChoseReplaceFileInUse
f4c7a1 ¤   {
c12390 ¤   ¤   "This file is in use by another program and cannot be replaced."
6542d0 ¤   },·
76af5a
1e72dc ¤   // kPGDMajorError_PGPdiskRemoveAllPassesFailed
ebc7a1 ¤   {
b63770 ¤   ¤   "PGPdisk was unable to remove all of your passphrases %s."
8e42d0 ¤   },·
e8af5a
e429dc ¤   // kPGDMajorError_PGPdiskUnmountAllFailed
a9c7a1 ¤   {
c99e11 ¤   ¤   "Some PGPdisks could not be unmounted %s."
6342d0 ¤   },·
cfaf5a
1383eb ¤   // kPGDMajorError_InvalidVolumeName
59c7a1 ¤   {
98c3cb ¤   ¤   "A PGPdisk volume name cannot contain any of the following "
d3c4a0 ¤   ¤   "characters: \"&*+./:;<=>?[\\]^|"
3642d0 ¤   },·
57af5a
165a8b ¤   // kPGDMajorError_WindowsFormatFailed
4cc7a1 ¤   {
e0326b ¤   ¤   "PGPdisk encountered an error when trying to display the standard "
c4ac42 ¤   ¤   "Windows formatting dialog. PGPdisk will now attempt to format your "
f67de2 ¤   ¤   "new PGPdisk volume using its own algorithm; it is suggested that "
2b215e ¤   ¤   "you reformat from the Windows Explorer as soon as possible."
cf42d0 ¤   },·
72af5a
ed7fff ¤   // kPGDMajorError_ResidentAppInitFailed
55c7a1 ¤   {
d38760 ¤   ¤   "The background application \"PGPdiskResident.exe\" could not be "
48004f ¤   ¤   "started %s. Important PGPdisk functions may not work as a result."
b942d0 ¤   },·
69af5a
175baf ¤   // kPGDMajorError_PGPdiskResHotKeyOpFailed
2cc7a1 ¤   {
8b8472 ¤   ¤   "PGPdisk couldn't enable or disable the PGPdisk unmount hotkey. "
92a289 ¤   ¤   "The key combination you have chosen may not be compatible with "
28bec6 ¤   ¤   "your system, or may be conflicting with another application. "
1bd2ed ¤   ¤   "You should choose another hotkey, quit all other applications, or "
787b0b ¤   ¤   "reboot your system."
7e42d0 ¤   },·
d7af5a
87b950 ¤   // kPGDMajorError_PGPdiskIrpCleanupError
7ec7a1 ¤   {
806f17 ¤   ¤   "PGPdisk couldn't disable IO to the PGPdisk drive %c:\\ %s"
1f42d0 ¤   },·
13af5a
15b1c7 ¤   // kPGDMajorError_CouldntFindAppString
7dc7a1 ¤   {
9437ed ¤   ¤   "Your request could not be completed because the PGPdisk "
367876 ¤   ¤   "application could not be found. Please run PGPdisk once to correct "
e3655a ¤   ¤   "this."
4642d0 ¤   },·
d1af5a
597452 ¤   // kPGDMajorError_KModeExceptionOccured
--0452 0005c53b09740110160 Page 5 of Errors.cpp
f7c7a1 ¤   {
6f3368 ¤   ¤   "An internal error was encountered within the PGPdisk driver %s."
4042d0 ¤   },·
f4af5a
f6f686 ¤   // kPGDMajorError_CouldntFindResidentApp
7ec7a1 ¤   {
f58760 ¤   ¤   "The background application \"PGPdiskResident.exe\" could not be "
aa21c7 ¤   ¤   "found. This application must always be in the same directory as "
57cd1f ¤   ¤   "\"PGPdisk.exe\". Important PGPdisk functions may not work as a "
90d62f ¤   ¤   "result."
9e42d0 ¤   },·
39af5a
756762 ¤   // kPGDMajorError_AddRemovePublicKeysFailed
43c7a1 ¤   {
e0cf07 ¤   ¤   "PGPdisk was unable to read and/or modify the public keys "
0895bd ¤   ¤   "associated with the specified PGPdisk %s."
a942d0 ¤   },·
a6af5a
8c6722 ¤   // kPGDMajorError_IncPassAndKeyNotInRing
8dc7a1 ¤   {
3796b6 ¤   ¤   "The passphrase you entered is not a valid master or alternate "
8cffc8 ¤   ¤   "passphrase for this PGPdisk. (Note that there were public key "
cc22e4 ¤   ¤   "passphrases on this PGPdisk that could not be checked, either "
9d44c3 ¤   ¤   "because they aren't on the local keyring or because the local "
143c2d ¤   ¤   "keyring could not be opened.) Please try again."
a442d0 ¤   },·
c0af5a
87d814 ¤   // kPGDMajorError_PGPdiskPassesWiped
99c7a1 ¤   {
476181 ¤   ¤   "This PGPdisk has had its master and alternate passphrases wiped. "
311bfb ¤   ¤   "It can now only be mounted by the holder of the private key "
586ef2 ¤   ¤   "associated with one or more of the public keys on the PGPdisk. You "
138b4d ¤   ¤   "will now be shown a dialog containing a read-only list of these "
692ca9 ¤   ¤   "public keys (bottom pane)."
5f42d0 ¤   },·
fbaf5a
995a0b ¤   // kPGDMajorError_WipePassesFailed
ffc7a1 ¤   {
72adc6 ¤   ¤   "PGPdisk was unable to wipe the master and alternate passphrases on "
aed877 ¤   ¤   "one or more PGPdisks %s."
ba42d0 ¤   },·
c3af5a
2ea8af ¤   // kPGDMajorError_PGPdiskConversionFailed
66c7a1 ¤   {
c377e1 ¤   ¤   "PGPdisk was unable to convert a PGPdisk to the new format %s."
bb42d0 ¤   },·
c3af5a
788fd7 ¤   // kPGDMajorError_PGPdiskGlobalConversionFailed
22c7a1 ¤   {
390e6d ¤   ¤   "PGPdisk was unable to invoke the global PGPdisk conversion "
cd7da9 ¤   ¤   "wizard %s."
7042d0 ¤   },·
96af5a
3546fd ¤   // kPGDMajorError_IncorrectPublicKeyPassphrase
7ac7a1 ¤   {
02d908 ¤   ¤   "The passphrase you entered is not a valid public key passphrase "
020871 ¤   ¤   "for this PGPdisk. Please try again."
989371 ¤   }
ebaf5a
b482f7 };
73af5a
36aba8 LPCSTR kPGPdiskMinorErrorStrings[kPGPdiskMaxMinorErrorStrings] =
07bb36 {
97f9ce ¤   // kPGDMinorError_NoErr
7fc7a1 ¤   {
52c002 ¤   ¤   "there was no error"
9342d0 ¤   },·
65af5a
cbde19 ¤   // kPGDMinorError_DialogDisplayFailed
1dc7a1 ¤   {
dc494f ¤   ¤   "PGPdisk was unable to display a dialog box"
5c42d0 ¤   },·
--acd4 0007ded103e40110160 Page 6 of Errors.cpp
2a67c5 ¤
1e665b ¤   // kPGDMinorError_DriverCommFailure
55c7a1 ¤   {
23ff08 ¤   ¤   "data could not be sent to or received from the driver"
b942d0 ¤   },·
4b67c5 ¤
bfae36 ¤   // kPGDMinorError_TooManyAppsRegistered
eac7a1 ¤   {
e2b99f ¤   ¤   "there are too many PGPdisk apps currently open"
6242d0 ¤   },·
8467c5 ¤
fcd253 ¤   // kPGDMinorError_FilesOpenOnDrive
25c7a1 ¤   {
f443cd ¤   ¤   "there are open files on or open views of a PGPdisk. Please close "
911aca ¤   ¤   "all open files and all Explorer windows and then try again."
6042d0 ¤   },·
7a67c5 ¤
5c82fc ¤   // kPGDMinorError_MaxPGPdisksMounted
13c7a1 ¤   {
abfdf4 ¤   ¤   "the maximum number of PGPdisks are already mounted"
0042d0 ¤   },·
7067c5 ¤
7d61de ¤   // kPGDMinorError_NoPGPdisksToUnmount
95c7a1 ¤   {
ed4ee9 ¤   ¤   "there are no PGPdisks currently mounted"
e742d0 ¤   },·
a567c5 ¤
f8d186 ¤   // kPGDMinorError_OutOfMemory
7dc7a1 ¤   {
e103f2 ¤   ¤   "of an out of memory error"
d242d0 ¤   },·
c267c5 ¤
e14404 ¤   // kPGDMinorError_PGPdiskAlreadyMounted
8dc7a1 ¤   {
45c517 ¤   ¤   "the seleced PGPdisk is already mounted"
ca42d0 ¤   },·
1367c5 ¤
2a52b6 ¤   // kPGDMinorError_SemaphoreCreationFailed
38c7a1 ¤   {
7027cf ¤   ¤   "Windows is running critically low on resources"
f542d0 ¤   },·
5c67c5 ¤
7720a1 ¤   // kPGDMinorError_CloseHandleFailed
c9c7a1 ¤   {
f2b438 ¤   ¤   "PGPdisk was unable to close a handle"
bd42d0 ¤   },·
9267c5 ¤
15f873 ¤   // kPGDMinorError_DriverNotInstalled
adc7a1 ¤   {
194903 ¤   ¤   "the PGPdisk driver is not installed. Please re-install PGPdisk and "
2469b9 ¤   ¤   "then try again"
c542d0 ¤   },·
7b67c5 ¤
0a29e3 ¤   // kPGDMinorError_ThreadCreationFailed
6ac7a1 ¤   {
3927cf ¤   ¤   "Windows is running critically low on resources"
fc42d0 ¤   },·
6b67c5 ¤
f88a1e ¤   // kPGDMinorError_FileOpenFailed
71c7a1 ¤   {
d577e7 ¤   ¤   "PGPdisk was unable to open a file"
7c42d0 ¤   },·
4067c5 ¤
26361c ¤   // kPGDMinorError_SetFilePosFailed
acc7a1 ¤   {
1793e0 ¤   ¤   "PGPdisk was unable to set a file position"
eb42d0 ¤   },·
0c67c5 ¤
521a75 ¤   // kPGDMinorError_SetEOFFailed
c2c7a1 ¤   {
61be79 ¤   ¤   "PGPdisk was unable to set the end of file"
7d42d0 ¤   },·
--722a 000cdff6ec840110160 Page 7 of Errors.cpp
2a67c5 ¤
451bea ¤   // kPGDMinorError_FileReadFailed
59c7a1 ¤   {
aee0e5 ¤   ¤   "PGPdisk was unable to read from a file"
7e42d0 ¤   },·
5f67c5 ¤
fde365 ¤   // kPGDMinorError_FileWriteFailed
88c7a1 ¤   {
41b1c4 ¤   ¤   "PGPdisk was unable to write to a file"
bf42d0 ¤   },·
5c67c5 ¤
a0cc76 ¤   // kPGDMinorError_MutexCreationFailed
8cc7a1 ¤   {
4027cf ¤   ¤   "Windows is running critically low on resources"
8942d0 ¤   },·
1867c5 ¤
3f3f4b ¤   // kPGDMinorError_GetFreeSpaceFailed
03c7a1 ¤   {
e5385c ¤   ¤   "PGPdisk was unable to determine the amount of free disk space"
a342d0 ¤   },·
ff67c5 ¤
efd54d ¤   // kPGDMinorError_GetVersionFailed
1cc7a1 ¤   {
3beadf ¤   ¤   "PGPdisk was unable to determine the version of Windows installed "
7ff383 ¤   ¤   "on this system"
1a42d0 ¤   },·
7b67c5 ¤
638d2c ¤   // kPGDMinorError_IOFlagViolation
d7c7a1 ¤   {
e99d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9a42d0 ¤   },·
e967c5 ¤
ce0c2c ¤   // kPGDMinorError_IspGetDcbFailed
92c7a1 ¤   {
169d25 ¤   ¤   "of an internal error within the PGPdisk driver"
5242d0 ¤   },·
d067c5 ¤
afafbf ¤   // kPGDMinorError_IspInsertCalldownFailed
c0c7a1 ¤   {
fd9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
4a42d0 ¤   },·
be67c5 ¤
75d750 ¤   // kPGDMinorError_FindAppPathFailed
44c7a1 ¤   {
419a6b ¤   ¤   "PGPdisk was unable to find the pathname of the PGPdisk application"
4342d0 ¤   },·
4167c5 ¤
da3414 ¤   // kPGDMinorError_GetAppModuleFailed
0fc7a1 ¤   {
fd27cf ¤   ¤   "Windows is running critically low on resources"
be42d0 ¤   },·
4567c5 ¤
754642 ¤   // kPGDMinorError_LockVolumeFailed
c6c7a1 ¤   {
d7d07a ¤   ¤   "a volume could not be locked for use by PGPdisk. It may be in use "
efb8b6 ¤   ¤   "by another disk utility"
3442d0 ¤   },·
9c67c5 ¤
937fee ¤   // kPGDMinorError_UnlockVolumeFailed
ffc7a1 ¤   {
b291b1 ¤   ¤   "a volume could not be unlocked for use by PGPdisk. It may be in "
2e49c8 ¤   ¤   "use by another disk utility"
4a42d0 ¤   },·
3867c5 ¤
59199b ¤   // kPGDMinorError_EnumOpenFilesFailed
6dc7a1 ¤   {
f59d25 ¤   ¤   "of an internal error within the PGPdisk driver"
0742d0 ¤   },·
2767c5 ¤
e4c7b9 ¤   // kPGDMinorError_InvalidVRP
d6c7a1 ¤   {
cd7366 ¤   ¤   "the PGPdisk's host volume appears to have gone away"
--56c9 000dcbc2d5b40110160 Page 8 of Errors.cpp
c442d0 ¤   },·
0067c5 ¤
58de9a ¤   // kPGDMinorError_IorAllocationFailed
73c7a1 ¤   {
4427cf ¤   ¤   "Windows is running critically low on resources"
1942d0 ¤   },·
7c67c5 ¤
b4bda2 ¤   // kPGDMinorError_IspDriveLetterPickFailed
28c7a1 ¤   {
2395ef ¤   ¤   "there are no free drive letters available"
af42d0 ¤   },·
b267c5 ¤
82e501 ¤   // kPGDMinorError_IspAssociateDcbFailed
68c7a1 ¤   {
689d25 ¤   ¤   "of an internal error within the PGPdisk driver"
7c42d0 ¤   },·
9767c5 ¤
6c9a54 ¤   // kPGDMinorError_IspDisassocDcbFailed
4ec7a1 ¤   {
779d25 ¤   ¤   "of an internal error within the PGPdisk driver"
e942d0 ¤   },·
5a67c5 ¤
33668c ¤   // kPGDMinorError_R0OpenFailed
24c7a1 ¤   {
17a266 ¤   ¤   "the driver was unable to open a file"
6a42d0 ¤   },·
f367c5 ¤
5e7d14 ¤   // kPGDMinorError_R0CloseFailed
46c7a1 ¤   {
5b8287 ¤   ¤   "the driver was unable to close a file"
db42d0 ¤   },·
ba67c5 ¤
96f778 ¤   // kPGDMinorError_R0ReadFailed
0ac7a1 ¤   {
a7f7db ¤   ¤   "the driver was unable to read from a file"
7142d0 ¤   },·
c767c5 ¤
d95412 ¤   // kPGDMinorError_R0WriteFailed
30c7a1 ¤   {
e136a3 ¤   ¤   "the driver was unable to write to a file"
6f42d0 ¤   },·
fa67c5 ¤
103701 ¤   // kPGDMinorError_R0SetFilePosFailed
9ac7a1 ¤   {
4dddcc ¤   ¤   "the driver was unable to set a file position"
5342d0 ¤   },·
2aaf5a
8aa7bb ¤   // kPGDMinorError_IorReadFailure
d4c7a1 ¤   {
cedb4b ¤   ¤   "the driver was unable to read from a volume"
a342d0 ¤   },·
6667c5 ¤
8ed2a7 ¤   // kPGDMinorError_IorWriteFailure
d7c7a1 ¤   {
a132ca ¤   ¤   "the driver was unable to write to a volume"
2c42d0 ¤   },·
3667c5 ¤
aa1c0b ¤   // kPGDMinorError_IosRegistrationFailed
4fc7a1 ¤   {
9e9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
3a42d0 ¤   },·
0867c5 ¤
ae6353 ¤   // kPGDMinorError_LoadLibraryFailed
b4c7a1 ¤   {
cd5251 ¤   ¤   "PGPdisk was unable to load a needed Windows .dll"
d142d0 ¤   },·
d067c5 ¤
60fac1 ¤   // kPGDMinorError_GetProcAddrFailed
10c7a1 ¤   {
a7310a ¤   ¤   "of an internal error within the PGPdisk application"
9042d0 ¤   },·
dc67c5 ¤
--de68 000a4b5a62640110160 Page 9 of Errors.cpp
c7a540 ¤   // kPGDMinorError_R0GetFileSize
2cc7a1 ¤   {
632f68 ¤   ¤   "the driver was unable to determine the size of a file"
ed42d0 ¤   },·
2667c5 ¤
78ae8f ¤   // kPGDMinorError_OOBFileRequest
19c7a1 ¤   {
fb70b8 ¤   ¤   "an invalid read or write request was received"
9142d0 ¤   },·
da67c5 ¤
ebdb10 ¤   // kPGDMinorError_CorruptFat
97c7a1 ¤   {
ac70a2 ¤   ¤   "the FAT table of the host volume appears to be corrupted"
ab42d0 ¤   },·
f167c5 ¤
4f69cc ¤   // kPGDMinorError_GetFirstClustFailed
a3c7a1 ¤   {
759d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9642d0 ¤   },·
3d67c5 ¤
0b8060 ¤   // kPGDMinorError_VWIN32NotFound
08c7a1 ¤   {
08310a ¤   ¤   "of an internal error within the PGPdisk application"
c542d0 ¤   },·
2b67c5 ¤
693cb5 ¤   // kPGDMinorError_DcbClaimFailed
ecc7a1 ¤   {
4c9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
6a42d0 ¤   },·
4567c5 ¤
383ace ¤   // kPGDMinorError_FileNotFound
a6c7a1 ¤   {
2abd48 ¤   ¤   "this file could not be found"
c742d0 ¤   },·
4567c5 ¤
125593 ¤   // kPGDMinorError_RegistryWriteFailed
c4c7a1 ¤   {
4c47c2 ¤   ¤   "of a problem accessing the system registry"
d642d0 ¤   },·
4967c5 ¤
cbf489 ¤   // kPGDMinorError_FailSilently
73c7a1 ¤   {
34d370 ¤   ¤   "the user canceled the operation"
0142d0 ¤   },·
0167c5 ¤
ebbd4f ¤   // kPGDMinorError_DeviceHookFailed
9fc7a1 ¤   {
2c9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9942d0 ¤   },·
9d67c5 ¤
db61aa ¤   // kPGDMinorError_AppIsIncompatVersion
83c7a1 ¤   {
d126fd ¤   ¤   "this system is running different versions of the PGPdisk driver "
1c7e26 ¤   ¤   "and the PGPdisk application. Please re-install PGPdisk to correct "
b168e6 ¤   ¤   "this"
6742d0 ¤   },·
7e67c5 ¤
adaa63 ¤   // kPGDMinorError_DriverIsIncompatVersion
c0c7a1 ¤   {
7a26fd ¤   ¤   "this system is running different versions of the PGPdisk driver "
407e26 ¤   ¤   "and the PGPdisk application. Please re-install PGPdisk to correct "
1868e6 ¤   ¤   "this"
ff42d0 ¤   },·
d867c5 ¤
325d5e ¤   // kPGDMinorError_PostThreadMessageFailed
6cc7a1 ¤   {
25310a ¤   ¤   "of an internal error within the PGPdisk application"
8542d0 ¤   },·
1b67c5 ¤
a07504 ¤   // kPGDMinorError_BadAppOp
76c7a1 ¤   {
a4310a ¤   ¤   "of an internal error within the PGPdisk application"
--135f 000a9d75c8340110160 Page 10 of Errors.cpp
c442d0 ¤   },·
0067c5 ¤
813bad ¤   // kPGDMinorError_SetVolumeLabelFailed
93c7a1 ¤   {
bef625 ¤   ¤   "PGPdisk was unable to set the name of a volume"
8642d0 ¤   },·
d467c5 ¤
f7c811 ¤   // kPGDMinorError_SetTimerFailed
afc7a1 ¤   {
c527cf ¤   ¤   "Windows is running critically low on resources"
1a42d0 ¤   },·
a667c5 ¤
d17765 ¤   // kPGDMinorError_HookSysBroadcastFailed
70c7a1 ¤   {
0a9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
0942d0 ¤   },·
6867c5 ¤
076cb5 ¤   // kPGDMinorError_BitmapLoadFailed
cbc7a1 ¤   {
649d25 ¤   ¤   "of an internal error within the PGPdisk driver"
d842d0 ¤   },·
9c67c5 ¤
05ea74 ¤   // kPGDMinorError_LinPageLockFailed
6cc7a1 ¤   {
4b9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
4742d0 ¤   },·
e867c5 ¤
b61837 ¤   // kPGDMinorError_LinPageUnlockFailed
35c7a1 ¤   {
3f9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9242d0 ¤   },·
0f67c5 ¤
0db546 ¤   // kPGDMinorError_VirtualFreeFailed
28c7a1 ¤   {
9e9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
c642d0 ¤   },·
d067c5 ¤
a35af8 ¤   // kPGDMinorError_RegCreateKeyExFailed
2fc7a1 ¤   {
0047c2 ¤   ¤   "of a problem accessing the system registry"
7a42d0 ¤   },·
9867c5 ¤
973e7f ¤   // kPGDMinorError_RegSetValueExFailed
20c7a1 ¤   {
c947c2 ¤   ¤   "of a problem accessing the system registry"
2742d0 ¤   },·
af67c5 ¤
073b13 ¤   // kPGDMinorError_RegCloseKeyFailed
d0c7a1 ¤   {
f447c2 ¤   ¤   "of a problem accessing the system registry"
8e42d0 ¤   },·
e0af5a
fc5f03 ¤   // kPGDMinorError_BadHeaderMagic
b5c7a1 ¤   {
e5660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
a142d0 ¤   },·
c467c5 ¤
cb135c ¤   // kPGDMinorError_BadHeaderCRC
36c7a1 ¤   {
a2660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
a142d0 ¤   },·
8167c5 ¤
1d7850 ¤   // kPGDMinorError_InvalidHeaderType
15c7a1 ¤   {
60660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
ee42d0 ¤   },·
a167c5 ¤
3bdb4b ¤   // kPGDMinorError_NewerHeaderVersion
94c7a1 ¤   {
f35b60 ¤   ¤   "this PGPdisk was created by a newer version of the PGPdisk "
8f156f ¤   ¤   "application."
a942d0 ¤   },·
--5b02 0009c76086e40110160 Page 11 of Errors.cpp
2a67c5 ¤
29f32a ¤   // kPGDMinorError_BadHeaderSize
25c7a1 ¤   {
d7660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
b842d0 ¤   },·
6d67c5 ¤
07d004 ¤   // kPGDMinorError_InvalidAlgorithm
eec7a1 ¤   {
68660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
5642d0 ¤   },·
2867c5 ¤
c7eddc ¤   // kPGDMinorError_InvalidTotalFileSize
96c7a1 ¤   {
ce660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
b842d0 ¤   },·
d267c5 ¤
3a3d6c ¤   // kPGDMinorError_InvalidFileDataSize
9bc7a1 ¤   {
5b660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
0a42d0 ¤   },·
fd67c5 ¤
79284a ¤   // kPGDMinorError_InvalidHeaderBlocks
63c7a1 ¤   {
1d660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
3142d0 ¤   },·
a767c5 ¤
94a1a0 ¤   // kPGDMinorError_IncorrectPassphrase
47c7a1 ¤   {
564224 ¤   ¤   "the passphrase you entered is not a valid master or alternate "
ca4589 ¤   ¤   "passphrase for this PGPdisk"
5742d0 ¤   },·
8967c5 ¤
bb28d3 ¤   // kPGDMinorError_PGPdiskIsWriteProtected
bdc7a1 ¤   {
d14bb4 ¤   ¤   "this PGPdisk file is write-protected"
7642d0 ¤   },·
f367c5 ¤
e2173e ¤   // kPGDMinorError_AllAlternatesTaken
1dc7a1 ¤   {
406573 ¤   ¤   "all seven alternate passphrases are already in use"
6042d0 ¤   },·
8967c5 ¤
071fe4 ¤   // kPGDMinorError_UnsupportedFilesystem
e4c7a1 ¤   {
e8660c ¤   ¤   "this file does not appear to be a valid PGPdisk"
8142d0 ¤   },·
1e67c5 ¤
c50057 ¤   // kPGDMinorError_ContextNotInitialized
d3c7a1 ¤   {
43310a ¤   ¤   "of an internal error within the PGPdisk application"
4942d0 ¤   },·
a267c5 ¤
5fb7f5 ¤   // kPGDMinorError_InvalidSBoxes
49c7a1 ¤   {
ca9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
2142d0 ¤   },·
dc67c5 ¤
c1ffa5 ¤   // kPGDMinorError_GetFileAttribsFailed
88c7a1 ¤   {
a74b75 ¤   ¤   "PGPdisk was unable to access a file"
c442d0 ¤   },·
0367c5 ¤
6f11c4 ¤   // kPGDMinorError_GetVolumeInfoFailed
4ac7a1 ¤   {
4fc654 ¤   ¤   "PGPdisk was unable to get information about a volume"
ac42d0 ¤   },·
7167c5 ¤
5bf66d ¤   // kPGDMinorError_HotKeyHookFailed
c3c7a1 ¤   {
069d25 ¤   ¤   "of an internal error within the PGPdisk driver"
6442d0 ¤   },·
9c67c5 ¤
--c33a 000c6ca5c7640110160 Page 12 of Errors.cpp
69b4af ¤   // kPGDMinorError_RegOpenKeyExFailed
cfc7a1 ¤   {
6647c2 ¤   ¤   "of a problem accessing the system registry"
6d42d0 ¤   },·
3967c5 ¤
cbf332 ¤   // kPGDMinorError_RegQueryValueExFailed
20c7a1 ¤   {
c147c2 ¤   ¤   "of a problem accessing the system registry"
9342d0 ¤   },·
d267c5 ¤
a7d807 ¤   // kPGDMinorError_IopRequestOverflow
e3c7a1 ¤   {
ed1855 ¤   ¤   "an internal buffer overflow error within the PGPdisk driver"
1342d0 ¤   },·
8267c5 ¤
0664f2 ¤   // kPGDMinorError_MiniRequestOverflow
1ec7a1 ¤   {
6bea2f ¤   ¤   "an internal buffer overflow error within the PGPdisk drive"
8942d0 ¤   },·
d067c5 ¤
c77466 ¤   // kPGDMinorError_RegisteredAppNotFound
b2c7a1 ¤   {
cf9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
6142d0 ¤   },·
fd67c5 ¤
8d1483 ¤   // kPGDMinorError_PGPdiskNotFound
d6c7a1 ¤   {
9d0970 ¤   ¤   "this PGPdisk does not exist or could not be found"
ed42d0 ¤   },·
7a67c5 ¤
d646fa ¤   // kPGDMinorError_DirectoryWriteProtected
38c7a1 ¤   {
82a43c ¤   ¤   "the specified directory is write-protected"
8542d0 ¤   },·
df67c5 ¤
e9be04 ¤   // kPGDMinorError_DirectoryNotFound
7ec7a1 ¤   {
1131fa ¤   ¤   "the specified directory does not exist"
8b42d0 ¤   },·
c367c5 ¤
94ec61 ¤   // kPGDMinorError_DirectoryTooSmall
68c7a1 ¤   {
e44da9 ¤   ¤   "the specified directory does not have the minimum required amount "
ca69d0 ¤   ¤   "of free space (about 75k)"
4b42d0 ¤   },·
ae67c5 ¤
ef8769 ¤   // kPGDMinorError_NoDriveLettersFree
17c7a1 ¤   {
fe95ef ¤   ¤   "there are no free drive letters available"
5a42d0 ¤   },·
dc67c5 ¤
765555 ¤   // kPGDMinorError_UserAbort
09c7a1 ¤   {
01d370 ¤   ¤   "the user canceled the operation"
0242d0 ¤   },·
a767c5 ¤
e29fba ¤   // kPGDMinorError_GetFileSizeFailed
55c7a1 ¤   {
158a60 ¤   ¤   "PGPdisk could not determine the size of a file"
0442d0 ¤   },·
a467c5 ¤
ccc60e ¤   // kPGDMinorError_NoAlternatesToRemove
d2c7a1 ¤   {
7de9e3 ¤   ¤   "this PGPdisk has no alternate passphrases to remove"
7042d0 ¤   },·
f367c5 ¤
2d6301 ¤   // kPGDMinorError_RegEnumKeyExFailed
dbc7a1 ¤   {
da47c2 ¤   ¤   "of a problem accessing the system registry"
2e42d0 ¤   },·
0667c5 ¤
c6e818 ¤   // kPGDMinorError_RegDeleteKeyFailed
--4ce5 000d94bd0ca40110160 Page 13 of Errors.cpp
f7c7a1 ¤   {
bd47c2 ¤   ¤   "of a problem accessing the system registry"
2242d0 ¤   },·
aa67c5 ¤
717629 ¤   // kPGDMinorError_PGPdiskNotMounted
8ac7a1 ¤   {
20ae77 ¤   ¤   "the specified file is not a mounted PGPdisk"
c042d0 ¤   },·
1667c5 ¤
e3fb5a ¤   // kPGDMinorError_InvalidPathNameFound
70c7a1 ¤   {
9939f1 ¤   ¤   "the specified path or filename is invalid"
3a42d0 ¤   },·
0067c5 ¤
c985fa ¤   // kPGDMinorError_FindFirstFileFailed
74c7a1 ¤   {
096de9 ¤   ¤   "an error occured while finding a directory or a file"
2542d0 ¤   },·
8667c5 ¤
6bb82c ¤   // kPGDMinorError_CoCreateInstanceFailed
76c7a1 ¤   {
898f9c ¤   ¤   "an error occurred while initializing an OLE object"
7442d0 ¤   },·
1667c5 ¤
e73ff4 ¤   // kPGDMinorError_QueryInterfaceFailed
24c7a1 ¤   {
74bf1a ¤   ¤   "an error occurred while querying an OLE object"
c942d0 ¤   },·
4867c5 ¤
4338c0 ¤   // kPGDMinorError_OLELoadCommandFailed
85c7a1 ¤   {
2988b1 ¤   ¤   "an error occurred whlie loading an OLE object"
5842d0 ¤   },·
4d67c5 ¤
3a2400 ¤   // kPGDMinorError_ResolveShortcutFailed
57c7a1 ¤   {
e52e47 ¤   ¤   "the specified shortcut could not be resolved"
c342d0 ¤   },·
be67c5 ¤
77f6ff ¤   // kPGDMinorError_OLEGetPathFailed
f2c7a1 ¤   {
fa2e47 ¤   ¤   "the specified shortcut could not be resolved"
9642d0 ¤   },·
2d67c5 ¤
081cf6 ¤   // kPGDMinorError_OLEGetDescriptionFailed
9fc7a1 ¤   {
78f5b3 ¤   ¤   "an error occurred while getting a description of the file"
aa42d0 ¤   },·
6e67c5 ¤
84ad59 ¤   // kPGDMinorError_CoInitializeExFailed
f2c7a1 ¤   {
f2fff9 ¤   ¤   "the COM library could not be initialized"
af42d0 ¤   },·
0567c5 ¤
c1fd58 ¤   // kPGDMinorError_InstallFSAPIHookFailed
12c7a1 ¤   {
119d25 ¤   ¤   "of an internal error within the PGPdisk driver"
7d42d0 ¤   },·
b667c5 ¤
8a5eac ¤   // kPGDMinorError_PGPdiskAlreadyInUse
e6c7a1 ¤   {
92a0ad ¤   ¤   "this PGPdisk may already be opened with read/write access by "
d851db ¤   ¤   "another user or application"
1742d0 ¤   },·
2467c5 ¤
74486d ¤   // kPGDMinorError_RegDeleteValueFailed
52c7a1 ¤   {
df47c2 ¤   ¤   "of a problem accessing the system registry"
4442d0 ¤   },·
8567c5 ¤
a13097 ¤   // kPGDMinorError_MapViewOfFileFailed
d9c7a1 ¤   {
--1b44 0007ff29bf440110160 Page 14 of Errors.cpp
7227cf ¤   ¤   "Windows is running critically low on resources"
5842d0 ¤   },·
b667c5 ¤
f4e3d9 ¤   // kPGDMinorError_OleInitFailed
20c7a1 ¤   {
0db829 ¤   ¤   "OLE could not be initialized"
2642d0 ¤   },·
bb67c5 ¤
90e763 ¤   // kPGDMinorError_DeviceConstructFailed
33c7a1 ¤   {
539d25 ¤   ¤   "of an internal error within the PGPdisk driver"
8242d0 ¤   },·
3867c5 ¤
5005a2 ¤   // kPGDMinorError_RegEnumValueFailed
cfc7a1 ¤   {
d847c2 ¤   ¤   "of a problem accessing the system registry"
6e42d0 ¤   },·
4567c5 ¤
b3dae9 ¤   // kPGDMinorError_PGPdiskIsBusy
1bc7a1 ¤   {
f65735 ¤   ¤   "this PGPdisk is busy processing an I/O request"
b142d0 ¤   },·
cf67c5 ¤
d92ca6 ¤   // kPGDMinorError_SHFormatDriveFailed
40c7a1 ¤   {
5a87c3 ¤   ¤   "PGPdisk was unable to display the Windows formatting dialog"
5b42d0 ¤   },·
af67c5 ¤
7a8db2 ¤   // kPGDMinorError_DiskTooBigToFormat
d2c7a1 ¤   {
349023 ¤   ¤   "the specified PGPdisk volume is too large to format automatically. "
69abb3 ¤   ¤   "Instead, browse to the volume in the Windows Explorer, "
84ebbe ¤   ¤   "right-click on the drive letter, and choose 'Format' from the "
660ba6 ¤   ¤   "context menu."
d242d0 ¤   },·
c267c5 ¤
0e71ef ¤   // kPGDMinorError_ZwQueryInfoFileFailed
53c7a1 ¤   {
e7d380 ¤   ¤   "PGPdisk was unable to read the attributes of a file"
e642d0 ¤   },·
8267c5 ¤
40cd4f ¤   // kPGDMinorError_ZwCreateFileFailed
e2c7a1 ¤   {
26b486 ¤   ¤   "PGPdisk was unable to open or create a file"
4a42d0 ¤   },·
e767c5 ¤
16e965 ¤   // kPGDMinorError_ZwCloseFailed
66c7a1 ¤   {
2817d3 ¤   ¤   "PGPdisk was unable to close a file"
1e42d0 ¤   },·
5167c5 ¤
3550fd ¤   // kPGDMinorError_ZwReadFileFailed
8ec7a1 ¤   {
f9e0e5 ¤   ¤   "PGPdisk was unable to read from a file"
c442d0 ¤   },·
8a67c5 ¤
12fddb ¤   // kPGDMinorError_ZwWriteFileFailed
9dc7a1 ¤   {
06b1c4 ¤   ¤   "PGPdisk was unable to write to a file"
ee42d0 ¤   },·
5067c5 ¤
3496ac ¤   // kPGDMinorError_RtlAnsiToUniFailed
30c7a1 ¤   {
974384 ¤   ¤   "PGPdisk was unable to convert a string from ANSI to Unicode"
e542d0 ¤   },·
6d67c5 ¤
0b83fb ¤   // kPGDMinorError_RtlUniToAnsiFailed
47c7a1 ¤   {
4c6b8d ¤   ¤   "PGPdisk was unable to convert a string from Unicode to ANSI"
0e42d0 ¤   },·
4067c5 ¤
7f0fef ¤   // kPGDMinorError_IoGetDeviceObjFailed
--5fbf 000faccd4de40110160 Page 15 of Errors.cpp
f7c7a1 ¤   {
b99d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9942d0 ¤   },·
1267c5 ¤
d5af89 ¤   // kPGDMinorError_IoCreateDeviceFailed
68c7a1 ¤   {
e39d25 ¤   ¤   "of an internal error within the PGPdisk driver"
5942d0 ¤   },·
b267c5 ¤
102148 ¤   // kPGDMinorError_IoCreateSymbolicLinkFailed
a3c7a1 ¤   {
e99d25 ¤   ¤   "of an internal error within the PGPdisk driver"
bf42d0 ¤   },·
ab67c5 ¤
197a62 ¤   // kPGDMinorError_IoDeleteSymbolicLinkFailed
a4c7a1 ¤   {
da9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
ff42d0 ¤   },·
3067c5 ¤
35b5c7 ¤   // kPGDMinorError_ObRefObjByHandleFailed
fcc7a1 ¤   {
b59d25 ¤   ¤   "of an internal error within the PGPdisk driver"
7c42d0 ¤   },·
be67c5 ¤
8ca16b ¤   // kPGDMinorError_IoBuildIOCTLRequestFailed
b8c7a1 ¤   {
be9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9142d0 ¤   },·
4e67c5 ¤
a849b4 ¤   // kPGDMinorError_IoCallDriverFailed
a5c7a1 ¤   {
1c9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
be42d0 ¤   },·
4b67c5 ¤
2d33b3 ¤   // kPGDMinorError_IoBuildSynchFsdRequestFailed
d0c7a1 ¤   {
d69d25 ¤   ¤   "of an internal error within the PGPdisk driver"
a442d0 ¤   },·
2daf5a
7d7717 ¤   // kPGDMinorError_UniStringOpFailed
9dc7a1 ¤   {
2c9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
6c42d0 ¤   },·
5467c5 ¤
9e40b7 ¤   // kPGDMinorError_NotCompatibleWindows
fcc7a1 ¤   {
256818 ¤   ¤   "PGPdisk is not compatible with your version of Windows"
9742d0 ¤   },·
6d67c5 ¤
4d6db1 ¤   // kPGDMinorError_RegisterClassExFailed
8dc7a1 ¤   {
ca4f9f ¤   ¤   "a window class could not be registered"
5342d0 ¤   },·
d067c5 ¤
84511a ¤   // kPGDMinorError_CreateWindowFailed
0bc7a1 ¤   {
76abb3 ¤   ¤   "a window could not be created"
f042d0 ¤   },·
e9af5a
b52b37 ¤   // kPGDMinorError_AttachMenuFailed
14c7a1 ¤   {
eb27cf ¤   ¤   "Windows is running critically low on resources"
5542d0 ¤   },·
e5af5a
06cc22 ¤   // kPGDMinorError_CreatePopupMenuFailed
a2c7a1 ¤   {
349cfb ¤   ¤   "a menu could not be created"
b542d0 ¤   },·
f6af5a
e90873 ¤   // kPGDMinorError_InsertMenuFailed
e3c7a1 ¤   {
fa2150 ¤   ¤   "a menu item could not be inserted into a menu"
--dd09 0001f9c988c40110160 Page 16 of Errors.cpp
c442d0 ¤   },·
b9af5a
8960b3 ¤   // kPGDMinorError_CreateFileMappingFailed
6ec7a1 ¤   {
4627cf ¤   ¤   "Windows is running critically low on resources"
1b42d0 ¤   },·
4daf5a
48a6fc ¤   // kPGDMinorError_OpenFileMappingFailed
7bc7a1 ¤   {
a227cf ¤   ¤   "Windows is running critically low on resources"
2a42d0 ¤   },·
19af5a
50406d ¤   // kPGDMinorError_UnmapViewOfFileFailed,·
bcc7a1 ¤   {
9f310a ¤   ¤   "of an internal error within the PGPdisk application"
2442d0 ¤   },·
cdaf5a
9e1716 ¤   // kPGDMinorError_WindowCreationFailed
92c7a1 ¤   {
823c89 ¤   ¤   "a window couldn't be created"
9e42d0 ¤   },·
55af5a
0588b4 ¤   // kPGDMinorError_InvalidParameter
6dc7a1 ¤   {
b0f743 ¤   ¤   "an invalid parameter was received"
2042d0 ¤   },·
9baf5a
7ecdf1 ¤   // kPGDMinorError_IoAllocateMdlFailed
7dc7a1 ¤   {
a49d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9242d0 ¤   },·
35af5a
1acf6f ¤   // kPGDMinorError_CreateSystemThreadFailed
adc7a1 ¤   {
b027cf ¤   ¤   "Windows is running critically low on resources"
6342d0 ¤   },·
a9af5a
ae24d6 ¤   // kPGDMinorError_InvalidDeviceReceived
1dc7a1 ¤   {
a80982 ¤   ¤   "the system attempted to perform I/O to a non-existant PGPdisk"
c042d0 ¤   },·
33af5a
9078c0 ¤   // kPGDMinorError_BroadcastSystemMessageFailed
7ec7a1 ¤   {
5b621c ¤   ¤   "PGPdisk was unable to broadcast a windows message to the system"
1242d0 ¤   },·
adaf5a
b01f40 ¤   // kPGDMinorError_IoInitializeTimerFailed
92c7a1 ¤   {
8027cf ¤   ¤   "Windows is running critically low on resources"
d242d0 ¤   },·
12af5a
97db92 ¤   // kPGDMinorError_KModeExceptionOccured
90c7a1 ¤   {
6f9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
6c42d0 ¤   },·
3caf5a
ee71c8 ¤   // kPGDMinorError_RegisterHotKeyFailed
36c7a1 ¤   {
d93bfa ¤   ¤   "PGPdisk was unable to register a hotkey"
a842d0 ¤   },·
78af5a
425e71 ¤   // kPGDMinorError_UnregisterHotKeyFailed
aec7a1 ¤   {
bd39c7 ¤   ¤   "PGPdisk was unable to unregister a hotkey"
4f42d0 ¤   },·
78af5a
116ac1 ¤   // kPGDMinorError_CantFormatDrive
3cc7a1 ¤   {
386525 ¤   ¤   "PGPdisk doesn't support formatting drives of this type. Use "
f1c7ba ¤   ¤   "Windows to format the drive instead"
1f42d0 ¤   },·
--4c85 0003436b16440110160 Page 17 of Errors.cpp
e0af5a
81b7ad ¤   // kPGDMinorError_CreateProcessFailed
2fc7a1 ¤   {
62310a ¤   ¤   "of an internal error within the PGPdisk application"
7542d0 ¤   },·
e5af5a
5a1b1f ¤   // kPGDMinorError_AccessDeniedToVolume
25c7a1 ¤   {
00e1f6 ¤   ¤   "access is denied. The current user doesn't have the privileges "
48aeb5 ¤   ¤   "necessary to access the specified volume"
1742d0 ¤   },·
acaf5a
1b2bcd ¤   // kPGDMinorError_CouldntFindAppString
e7c7a1 ¤   {
c7f19c ¤   ¤   "the PGPdisk application could not be found. Please run PGPdisk "
405a22 ¤   ¤   "once to correct this"
b642d0 ¤   },·
20af5a
b460cf ¤   // kPGDMinorError_BlockSizeNotSupported
ffc7a1 ¤   {
1c96d0 ¤   ¤   "PGPdisk does not support volumes whose block size is greater than "
18a66d ¤   ¤   "the page size of the current system (usually 4k)"
9042d0 ¤   },·
cdaf5a
29cffe ¤   // kPGDMinorError_WNetGetUniNameFailed
bdc7a1 ¤   {
01d08c ¤   ¤   "PGPdisk was unable to determine the location of a file on a "
242c64 ¤   ¤   "networked drive"
b742d0 ¤   },·
c4af5a
f48168 ¤   // kPGDMinorError_NetShareGetInfoFailed
93c7a1 ¤   {
47d08c ¤   ¤   "PGPdisk was unable to determine the location of a file on a "
462c64 ¤   ¤   "networked drive"
9042d0 ¤   },·
daaf5a
2822ee ¤   // kPGDMinorError_TriedNTFSOnWin95
77c7a1 ¤   {
958295 ¤   ¤   "it was formatted using the NTFS filesystem under Windows NT, which "
a3bf6f ¤   ¤   "is not compatible with either Windows 95 or 98"
7a42d0 ¤   },·
81af5a
0f7896 ¤   // kPGDMinorError_TriedReadOnlyNTFS
00c7a1 ¤   {
ba457d ¤   ¤   "it was formatted using the NTFS filesystem, which cannot be used "
cb84e0 ¤   ¤   "in read-only mode"
bf42d0 ¤   },·
77af5a
56296a ¤   // kPGDMinorError_ZwOpenProcessFailed,·
7ac7a1 ¤   {
ec9d25 ¤   ¤   "of an internal error within the PGPdisk driver"
9a42d0 ¤   },·
dc67c5 ¤
ca3a72 ¤   // kPGDMinorError_ZwOpenProcessTokenFailed,·
9bc7a1 ¤   {
869d25 ¤   ¤   "of an internal error within the PGPdisk driver"
1b42d0 ¤   },·
3faf5a
0a067b ¤   // kPGDMinorError_ZwDuplicateTokenFailed,·
46c7a1 ¤   {
a69d25 ¤   ¤   "of an internal error within the PGPdisk driver"
7d42d0 ¤   },·
e8af5a
056e3c ¤   // kPGDMinorError_ZwSetThreadInfoFailed
c6c7a1 ¤   {
719d25 ¤   ¤   "of an internal error within the PGPdisk driver"
8442d0 ¤   },·
f6af5a
ede143 ¤   // kPGDMinorError_NetWkstaGetInfoFailed
b4c7a1 ¤   {
89133f ¤   ¤   "PGPdisk was unable to determine the name of a computer"
3442d0 ¤   },·
--3eb8 0011f7a30d040110160 Page 18 of Errors.cpp
e0af5a
596a47 ¤   // kPGDMinorError_SDKFuncFailed
40c7a1 ¤   {
bc27d5 ¤   ¤   "an error occurred while processing a public or private PGP key"
9d42d0 ¤   },·
38af5a
416ce7 ¤   // kPGDMinorError_SDKNotAvailable
88c7a1 ¤   {
457384 ¤   ¤   "the PGPsdk dll file could not be found"
7a42d0 ¤   },·
9caf5a
7d558d ¤   // kPGDMinorError_ZwSetInfoFileFailed
66c7a1 ¤   {
ecdb0b ¤   ¤   "PGPdisk was unable to set the size of a file"
1342d0 ¤   },·
b4af5a
6ca181 ¤   // kPGDMinorError_IncPassAndKeyNotInRing
42c7a1 ¤   {
674224 ¤   ¤   "the passphrase you entered is not a valid master or alternate "
70f039 ¤   ¤   "passphrase for this PGPdisk. (Please note that there were "
5863d0 ¤   ¤   "public key passphrases on this PGPdisk that could not be checked, "
299bda ¤   ¤   "either because they aren't on the local keyring or because the "
c7522a ¤   ¤   "local keyring could not be opened.)"
5e42d0 ¤   },·
daaf5a
e417ea ¤   // kPGDMinorError_CantGetADK
aec7a1 ¤   {
f5646c ¤   ¤   "the Additional Decryption Key associated with this installation of "
e96507 ¤   ¤   "PGPdisk could not be accessed"
7642d0 ¤   },·
eeaf5a
0409a0 ¤   // kPGDMinorError_PGPdiskPassesWiped
59c7a1 ¤   {
5b651b ¤   ¤   "this PGPdisk has had its master and alternate passphrases wiped. "
9b1bfb ¤   ¤   "It can now only be mounted by the holder of the private key "
ee7da4 ¤   ¤   "associated with one or more of the public keys on the PGPdisk"
2742d0 ¤   },·
88af5a
0e2ab0 ¤   // kPGDMinorError_NoADKWhenConverting
81c7a1 ¤   {
d1b9d9 ¤   ¤   "this PGPdisk contains an ADK that is not present on the current "
b42a04 ¤   ¤   "public key ring. Please acquire a copy of this public key before "
f356ee ¤   ¤   "attempting conversion. A list of the public keys on this PGPdisk "
fe9364 ¤   ¤   "will now be displayed."
c09371 ¤   }
3aaf5a
1f82f7 };
--2fb0 000140b8b3940110161 Page 1 of Errors.h
541bc3 //////////////////////////////////////////////////////////////////////////////
241109 // Errors.h
90465d //
831373 // Contains declarations for errors for the project.
e31bc3 //////////////////////////////////////////////////////////////////////////////
deaf5a
0c3a6c // $Id: Errors.h,v 1.3.2.52.2.5 1998/10/25 23:31:37 nryan Exp $
84af5a
a8cbce // Copyright (C) 1998 by Network Associates, Inc.
4971ae // All rights reserved.
d5af5a
c4bcca #ifndef Included_Errors_h¤  // [
1508ea #define Included_Errors_h
ddaf5a
21af5a
7c09b7 ////////////
1ae738 // Constants
4809b7 ////////////
ecaf5a
46a9aa const PGPUInt32 kPGPdiskMaxMajorErrorStrings = 1024;
a3ef73 const PGPUInt32 kPGPdiskMaxMinorErrorStrings = 1024;
19af5a
6faf5a
d52af8 //////////
43647f // Externs
712af8 //////////
e6af5a
0d0709 extern LPCSTR¤  kPGPdiskMajorErrorStrings[kPGPdiskMaxMajorErrorStrings];
f227a4 extern LPCSTR¤  kPGPdiskMinorErrorStrings[kPGPdiskMaxMinorErrorStrings];
24af5a
c8af5a
2fd557 ////////
3b02c9 // Types
2bd557 ////////
f3af5a
7c5f54 // Assume no external error is larger than 32 bits.
4faf5a
51530e typedef¤PGPUInt32 ExternalError;
1129ea const ExternalError kExternalError_NoErr = 0;
aaaf5a
aa683a // A PGDMajorError explains what operation failed.
69af5a
bece80 static LPCSTR kPGPdiskUnknownMajorErrorString =·
746873 ¤   "An unknown error occurred.";
67af5a
61eb05 enum PGDMajorError
27bb36 {
a229f3 ¤   kPGDMajorError_NoErr,·
17d6d4 ¤   kPGDMajorError_AppInitFailed,·
8d1785 ¤   kPGDMajorError_PGPdiskCreationFailed,·
0ab2c5 ¤   kPGDMajorError_PGPdiskMountFailed,·
f2b192 ¤   kPGDMajorError_PGPdiskTooBig,·
ead735 ¤   kPGDMajorError_PGPdiskTooSmall,·
f3394b ¤   kPGDMajorError_PGPdiskUnmountFailed,·
df08fa ¤   kPGDMajorError_PGPdiskReadError,·
61755f ¤   kPGDMajorError_PGPdiskWriteError,·
4f0139 ¤   kPGDMajorError_AboutBoxDisplayFailed,·
be3e11 ¤   kPGDMajorError_PreferencesAccessFailed,·
4417aa ¤   kPGDMajorError_TimeoutValueTooSmall,·
462d54 ¤   kPGDMajorError_TimeoutValueTooBig,·
88f573 ¤   kPGDMajorError_NotEnoughDiskSpace,·
cc18e7 ¤   kPGDMajorError_PassphraseTooSmall,·
6a1cc6 ¤   kPGDMajorError_PassphraseNotConfirmed,·
c92825 ¤   kPGDMajorError_PGPdiskAddPassFailed,·
9ee9b5 ¤   kPGDMajorError_PGPdiskChangePassFailed,·
2112b1 ¤   kPGDMajorError_PGPdiskRemoveOnePassFailed,·
23fe1b ¤   kPGDMajorError_IncorrectPassphrase,·
7479fc ¤   kPGDMajorError_IncorrectMasterPassphrase,·
6b26df ¤   kPGDMajorError_TriedRemoveMasterPass,·
40d5f9 ¤   kPGDMajorError_IncorrectAlternatePassphrase,·
3ea81e ¤   kPGDMajorError_PassphraseAlreadyExists,·
14101e ¤   kPGDMajorError_NotCompatibleWindows,·
--3c2e 000a92ca6e540110161 Page 2 of Errors.h
fa3ff1 ¤   kPGDMajorError_TriedPassOpOnMountedPGPdisk,·
666d31 ¤   kPGDMajorError_InvalidCipherContext,·
1876c1 ¤   kPGDMajorError_DriverUpdatePrefsFailed,·
7f981d ¤   kPGDMajorError_DialogDisplayFailed,·
c07bce ¤   kPGDMajorError_ChoseReadOnlyDirInCreate,·
fe1abf ¤   kPGDMajorError_ChoseTooSmallDirInCreate,·
7a780f ¤   kPGDMajorError_ChoseInvalidDirInCreate,·
279d76 ¤   kPGDMajorError_NoSleepOnUnmountFailure,·
6d96a3 ¤   kPGDMajorError_BadCommandAfterBetaTimeout,·
81c1fb ¤   kPGDMajorError_ChoseReplaceFileInUse,·
0b8ed6 ¤   kPGDMajorError_PGPdiskRemoveAllPassesFailed,·
a26ed3 ¤   kPGDMajorError_PGPdiskUnmountAllFailed,·
371e5b ¤   kPGDMajorError_InvalidVolumeName,·
72df1c ¤   kPGDMajorError_WindowsFormatFailed,·
3b6809 ¤   kPGDMajorError_ResidentAppInitFailed,·
1dc8be ¤   kPGDMajorError_PGPdiskResHotKeyOpFailed,·
e7e1cb ¤   kPGDMajorError_PGPdiskIrpCleanupError,·
a7c07f ¤   kPGDMajorError_CouldntFindAppString,·
2bc95d ¤   kPGDMajorError_KModeExceptionOccured,·
5150d3 ¤   kPGDMajorError_CouldntFindResidentApp,·
fe5d0e ¤   kPGDMajorError_AddRemovePublicKeysFailed,·
f21d4c ¤   kPGDMajorError_IncPassAndKeyNotInRing,·
f3f0ff ¤   kPGDMajorError_PGPdiskPassesWiped,·
8551d4 ¤   kPGDMajorError_WipePassesFailed,·
d621fe ¤   kPGDMajorError_PGPdiskConversionFailed,·
c60601 ¤   kPGDMajorError_PGPdiskGlobalConversionFailed,·
790888 ¤   kPGDMajorError_IncorrectPublicKeyPassphrase
f7af5a
c782f7 };
b8af5a
33f8ed // A PGDMinorError explains why the operation failed.
20af5a
e0eec5 static LPCSTR kPGPdiskDefaultMinorErrorString =·
a14bba ¤   "an error occurred.";
7baf5a
858f23 static LPCSTR kPGPdiskUnknownMinorErrorString =·
71b7bc ¤   "an unknown error occurred.";
36af5a
03bdc9 enum PGDMinorError
2dbb36 {
4c9680 ¤   kPGDMinorError_NoErr,·
5c37dd ¤   kPGDMinorError_DialogDisplayFailed,·
af9496 ¤   kPGDMinorError_DriverCommFailure,·
61b2bf ¤   kPGDMinorError_TooManyAppsRegistered,·
6d44a3 ¤   kPGDMinorError_FilesOpenOnDrive,·
812a79 ¤   kPGDMinorError_MaxPGPdisksMounted,·
9bfd03 ¤   kPGDMinorError_NoPGPdisksToUnmount,·
725a8a ¤   kPGDMinorError_OutOfMemory,·
e97ff9 ¤   kPGDMinorError_PGPdiskAlreadyMounted,·
c03ba2 ¤   kPGDMinorError_SemaphoreCreationFailed,·
7632dc ¤   kPGDMinorError_CloseHandleFailed,·
80f9a0 ¤   kPGDMinorError_DriverNotInstalled,·
199ced ¤   kPGDMinorError_ThreadCreationFailed,·
32027e ¤   kPGDMinorError_FileOpenFailed,·
1b2027 ¤   kPGDMinorError_SetFilePosFailed,·
3ab459 ¤   kPGDMinorError_SetEOFFailed,·
529c16 ¤   kPGDMinorError_FileReadFailed,·
cd8291 ¤   kPGDMinorError_FileWriteFailed,·
ade2d3 ¤   kPGDMinorError_MutexCreationFailed,·
343371 ¤   kPGDMinorError_GetFreeSpaceFailed,·
603f9d ¤   kPGDMinorError_GetVersionFailed,·
c99997 ¤   kPGDMinorError_IOFlagViolation,·
790c16 ¤   kPGDMinorError_IspGetDcbFailed,·
92c0d0 ¤   kPGDMinorError_IspInsertCalldownFailed,·
58d43c ¤   kPGDMinorError_FindAppPathFailed,·
f6dd9d ¤   kPGDMinorError_GetAppModuleFailed,·
3c1a47 ¤   kPGDMinorError_LockVolumeFailed,·
43a032 ¤   kPGDMinorError_UnlockVolumeFailed,·
ab3a12 ¤   kPGDMinorError_EnumOpenFilesFailed,·
9e4af1 ¤   kPGDMinorError_InvalidVRP,·
c99179 ¤   kPGDMinorError_IorAllocationFailed,·
a9fafe ¤   kPGDMinorError_IspDriveLetterPickFailed,·
--c873 000b488959640110161 Page 3 of Errors.h
46b5c2 ¤   kPGDMinorError_IspAssociateDcbFailed,·
6a6c9b ¤   kPGDMinorError_IspDisassocDcbFailed,·
72a6a2 ¤   kPGDMinorError_R0OpenFailed,·
6876c7 ¤   kPGDMinorError_R0CloseFailed,·
ed38ca ¤   kPGDMinorError_R0ReadFailed,·
5e9ed4 ¤   kPGDMinorError_R0WriteFailed,·
09042f ¤   kPGDMinorError_R0SetFilePosFailed,·
f029de ¤   kPGDMinorError_IorReadFailure,·
ec5b81 ¤   kPGDMinorError_IorWriteFailure,·
1922fc ¤   kPGDMinorError_IosRegistrationFailed,·
de0dfb ¤   kPGDMinorError_LoadLibraryFailed,·
302e5e ¤   kPGDMinorError_GetProcAddrFailed,·
7e9895 ¤   kPGDMinorError_R0GetFileSize,·
f265dd ¤   kPGDMinorError_OOBFileRequest,·
5fe8fb ¤   kPGDMinorError_CorruptFat,·
05d76a ¤   kPGDMinorError_GetFirstClustFailed,·
d3c7f0 ¤   kPGDMinorError_VWIN32NotFound,·
149994 ¤   kPGDMinorError_DcbClaimFailed,·
fa4b9d ¤   kPGDMinorError_FileNotFound,·
8e7cba ¤   kPGDMinorError_RegistryWriteFailed,·
b46f81 ¤   kPGDMinorError_FailSilently,·
0de363 ¤   kPGDMinorError_DeviceHookFailed,·
16c3df ¤   kPGDMinorError_AppIsIncompatVersion,·
7e61e6 ¤   kPGDMinorError_DriverIsIncompatVersion,·
18e40c ¤   kPGDMinorError_PostThreadMessageFailed,·
64841e ¤   kPGDMinorError_BadAppOp,·
cc7308 ¤   kPGDMinorError_SetVolumeLabelFailed,·
11e0a0 ¤   kPGDMinorError_SetTimerFailed,·
f006a3 ¤   kPGDMinorError_HookSysBroadcastFailed,·
1ea51f ¤   kPGDMinorError_BitmapLoadFailed,·
cd7a09 ¤   kPGDMinorError_LinPageLockFailed,·
662dc4 ¤   kPGDMinorError_LinPageUnlockFailed,·
2e5569 ¤   kPGDMinorError_VirtualFreeFailed,·
d1acc8 ¤   kPGDMinorError_RegCreateKeyExFailed,·
97e156 ¤   kPGDMinorError_RegSetValueExFailed,·
199550 ¤   kPGDMinorError_RegCloseKeyFailed,·
f1a6b7 ¤   kPGDMinorError_BadHeaderMagic,·
c2ddb3 ¤   kPGDMinorError_BadHeaderCRC,·
e689c1 ¤   kPGDMinorError_InvalidHeaderType,·
2a925b ¤   kPGDMinorError_NewerHeaderVersion,·
803703 ¤   kPGDMinorError_BadHeaderSize,·
58f94e ¤   kPGDMinorError_InvalidAlgorithm,·
0129af ¤   kPGDMinorError_InvalidTotalFileSize,·
ac6c34 ¤   kPGDMinorError_InvalidFileDataSize,·
2e5cfb ¤   kPGDMinorError_InvalidHeaderBlocks,·
0251db ¤   kPGDMinorError_IncorrectPassphrase,·
ddfc92 ¤   kPGDMinorError_PGPdiskIsWriteProtected,·
6a1047 ¤   kPGDMinorError_AllAlternatesTaken,·
9d7a36 ¤   kPGDMinorError_UnsupportedFilesystem,·
b58246 ¤   kPGDMinorError_ContextNotInitialized,·
61efd0 ¤   kPGDMinorError_InvalidSBoxes,·
393de0 ¤   kPGDMinorError_GetFileAttribsFailed,·
c3e665 ¤   kPGDMinorError_GetVolumeInfoFailed,·
750f37 ¤   kPGDMinorError_HotKeyHookFailed,·
748753 ¤   kPGDMinorError_RegOpenKeyExFailed,·
f75cbf ¤   kPGDMinorError_RegQueryValueExFailed,·
5c4f06 ¤   kPGDMinorError_IopRequestOverflow,·
18203d ¤   kPGDMinorError_MiniRequestOverflow,·
a8189f ¤   kPGDMinorError_RegisteredAppNotFound,·
2dbce8 ¤   kPGDMinorError_PGPdiskNotFound,·
e082c1 ¤   kPGDMinorError_DirectoryWriteProtected,·
2e9e6c ¤   kPGDMinorError_DirectoryNotFound,·
28f416 ¤   kPGDMinorError_DirectoryTooSmall,·
321a31 ¤   kPGDMinorError_NoDriveLettersFree,·
6e8e21 ¤   kPGDMinorError_UserAbort,·
fb0e99 ¤   kPGDMinorError_GetFileSizeFailed,·
63daf5 ¤   kPGDMinorError_NoAlternatesToRemove,·
1b108e ¤   kPGDMinorError_RegEnumKeyExFailed,·
7968dc ¤   kPGDMinorError_RegDeleteKeyFailed,·
124763 ¤   kPGDMinorError_PGPdiskNotMounted,·
c18404 ¤   kPGDMinorError_InvalidPathNameFound,·
b4187a ¤   kPGDMinorError_FindFirstFileFailed,·
--a3a0 00062ecb23940110161 Page 4 of Errors.h
53a926 ¤   kPGDMinorError_CoCreateInstanceFailed,·
7931c3 ¤   kPGDMinorError_QueryInterfaceFailed,·
7a94be ¤   kPGDMinorError_OLELoadCommandFailed,·
797b9f ¤   kPGDMinorError_ResolveShortcutFailed,·
e825da ¤   kPGDMinorError_OLEGetPathFailed,·
9cd6be ¤   kPGDMinorError_OLEGetDescriptionFailed,·
e699df ¤   kPGDMinorError_CoInitializeExFailed,·
2d2b2b ¤   kPGDMinorError_InstallFSAPIHookFailed,·
30f703 ¤   kPGDMinorError_PGPdiskAlreadyInUse,·
88f8be ¤   kPGDMinorError_RegDeleteValueFailed,·
ce2f71 ¤   kPGDMinorError_MapViewOfFileFailed,·
db71e2 ¤   kPGDMinorError_OleInitFailed,·
dac035 ¤   kPGDMinorError_DeviceConstructFailed,·
709329 ¤   kPGDMinorError_RegEnumValueFailed,·
3a6b02 ¤   kPGDMinorError_PGPdiskIsBusy,·
815ae6 ¤   kPGDMinorError_SHFormatDriveFailed,·
2b0ef8 ¤   kPGDMinorError_DiskTooBigToFormat,·
3f14e6 ¤   kPGDMinorError_ZwQueryInfoFileFailed,·
6d808c ¤   kPGDMinorError_ZwCreateFileFailed,·
d54d76 ¤   kPGDMinorError_ZwCloseFailed,·
55d656 ¤   kPGDMinorError_ZwReadFileFailed,·
9b3200 ¤   kPGDMinorError_ZwWriteFileFailed,·
78af2b ¤   kPGDMinorError_RtlAnsiToUniFailed,·
cc76f8 ¤   kPGDMinorError_RtlUniToAnsiFailed,·
9e7179 ¤   kPGDMinorError_IoGetDeviceObjFailed,·
f1e5f6 ¤   kPGDMinorError_IoCreateDeviceFailed,·
8efb86 ¤   kPGDMinorError_IoCreateSymbolicLinkFailed,·
31c993 ¤   kPGDMinorError_IoDeleteSymbolicLinkFailed,·
5c7ff2 ¤   kPGDMinorError_ObRefObjByHandleFailed,·
42292c ¤   kPGDMinorError_IoBuildIOCTLRequestFailed,·
24da00 ¤   kPGDMinorError_IoCallDriverFailed,·
d63bc6 ¤   kPGDMinorError_IoBuildSynchFsdRequestFailed,·
347a58 ¤   kPGDMinorError_UniStringOpFailed,·
2bd6bd ¤   kPGDMinorError_NotCompatibleWindows,·
9087ec ¤   kPGDMinorError_RegisterClassExFailed,·
607326 ¤   kPGDMinorError_CreateWindowFailed,·
0f2cd8 ¤   kPGDMinorError_AttachMenuFailed,·
7f005a ¤   kPGDMinorError_CreatePopupMenuFailed,·
c81e47 ¤   kPGDMinorError_InsertMenuFailed,·
64578b ¤   kPGDMinorError_CreateFileMappingFailed,·
2c092d ¤   kPGDMinorError_OpenFileMappingFailed,·
eb510a ¤   kPGDMinorError_UnmapViewOfFileFailed,·
a346a0 ¤   kPGDMinorError_WindowCreationFailed,·
031ded ¤   kPGDMinorError_InvalidParameter,·
d4329e ¤   kPGDMinorError_IoAllocateMdlFailed,·
10d0b9 ¤   kPGDMinorError_CreateSystemThreadFailed,·
657074 ¤   kPGDMinorError_InvalidDeviceReceived,·
ac1dbd ¤   kPGDMinorError_BroadcastSystemMessageFailed,·
e88a9b ¤   kPGDMinorError_IoInitializeTimerFailed,·
e85e0a ¤   kPGDMinorError_KModeExceptionOccured,·
fb85bb ¤   kPGDMinorError_RegisterHotKeyFailed,·
ee4891 ¤   kPGDMinorError_UnregisterHotKeyFailed,·
cc53c7 ¤   kPGDMinorError_CantFormatDrive,·
7b9414 ¤   kPGDMinorError_CreateProcessFailed,·
f15bd4 ¤   kPGDMinorError_AccessDeniedToVolume,·
6806dc ¤   kPGDMinorError_CouldntFindAppString,·
d236dd ¤   kPGDMinorError_BlockSizeNotSupported,·
b03b3c ¤   kPGDMinorError_WNetGetUniNameFailed,·
aa22ad ¤   kPGDMinorError_NetShareGetInfoFailed,·
80393a ¤   kPGDMinorError_TriedNTFSOnWin95,·
ba17bb ¤   kPGDMinorError_TriedReadOnlyNTFS,·
526e13 ¤   kPGDMinorError_ZwOpenProcessFailed,·
cf3f73 ¤   kPGDMinorError_ZwOpenProcessTokenFailed,·
1911d3 ¤   kPGDMinorError_ZwDuplicateTokenFailed,·
9a89c3 ¤   kPGDMinorError_ZwSetThreadInfoFailed,·
c78630 ¤   kPGDMinorError_NetWkstaGetInfoFailed,·
49eb66 ¤   kPGDMinorError_SDKFuncFailed,·
af4112 ¤   kPGDMinorError_SDKNotAvailable,·
ba733b ¤   kPGDMinorError_ZwSetInfoFileFailed,·
533be1 ¤   kPGDMinorError_IncPassAndKeyNotInRing,·
b365e3 ¤   kPGDMinorError_CantGetADK,·
626af5 ¤   kPGDMinorError_PGPdiskPassesWiped,·
--6ed0 0004303b8f740110161 Page 5 of Errors.h
dd8297 ¤   kPGDMinorError_NoADKWhenConverting
f8af5a
4182f7 };
98af5a
26af5a
acca3a ////////////////////
e9e785 // Utility functions
f7ca3a ////////////////////
d4af5a
94f11f // DoesMajorErrTakeDrive returns TRUE if the major error string takes a drive
fea0c9 // number parameter.
24af5a
05c85e inline·
1a7750 PGPBoolean
ab26f8 DoesMajorErrTakeDrive(PGDMajorError perr)
03bb36 {
ccf274 ¤   switch (perr)
78c7a1 ¤   {
87b54a ¤   case kPGDMajorError_PGPdiskUnmountFailed:
b77a7c ¤   case kPGDMajorError_InvalidCipherContext:
26ff0b ¤   case kPGDMajorError_PGPdiskIrpCleanupError:
d7836c ¤   ¤   return TRUE;
77af5a
322f72 ¤   default:
2d98aa ¤   ¤   return FALSE;
d99371 ¤   }
20efe6 }
84af5a
205192 // IsExternalError returns TRUE if the passed external error is an error.
f5af5a
9fc85e inline·
397750 PGPBoolean
4818e8 IsExternalError(ExternalError err)
43bb36 {
d80451 ¤   return (err != kExternalError_NoErr);
61efe6 }
5baf5a
7b8f4d // IsntExternalError returns TRUE if the passed external error isn't an
5e4486 // error.
28af5a
3ec85e inline·
ed7750 PGPBoolean
b68dec IsntExternalError(ExternalError err)
2fbb36 {
eec608 ¤   return (err == kExternalError_NoErr);
afefe6 }
17af5a
6d69cb // IsPGDMajorError returns TRUE if the passed PGDMajorError variable is an
314486 // error.
2aaf5a
9cc85e inline·
9b7750 PGPBoolean
877c0a IsPGDMajorError(PGDMajorError perr)
83bb36 {
94eb89 ¤   return (perr != kPGDMajorError_NoErr);
deefe6 }
c5af5a
2cf59b // IsntPGDMajorError returns TRUE if the passed PGDMajorError variable is not
71fe5d // an error.
6eaf5a
5ac85e inline·
817750 PGPBoolean
d53abb IsntPGDMajorError(PGDMajorError perr)
46bb36 {
4d29d0 ¤   return (perr == kPGDMajorError_NoErr);
f2efe6 }
1daf5a
e6f064 // IsPGDMinorError returns TRUE if the passed PGDMinorError variable is an
0d4486 // error.
59af5a
f9c85e inline·
437750 PGPBoolean
--b340 001766a3a1a40110161 Page 6 of Errors.h
8cf709 IsPGDMinorError(PGDMinorError perr)
aabb36 {
c954fa ¤   return (perr != kPGDMinorError_NoErr);
04efe6 }
46af5a
c7a8ff // IsntPGDMinorError returns TRUE if the passed PGDMinorError variable is not
10fe5d // an error.
9caf5a
9bc85e inline·
207750 PGPBoolean
5eb1b8 IsntPGDMinorError(PGDMinorError perr)
74bb36 {
f896a3 ¤   return (perr == kPGDMinorError_NoErr);
03efe6 }
abaf5a
766a96 #endif¤ // ] Included_Errors_h
--2228 000391c387f40110162 Page 1 of FatUtils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
73686e // FatUtils.cpp
43465d //
b2ee72 // Utility functions for processing FAT filesystem data.
a21bc3 //////////////////////////////////////////////////////////////////////////////
d9af5a
1dafb0 // $Id: FatUtils.cpp,v 1.1.2.16 1998/08/04 02:10:11 nryan Exp $
bbaf5a
4ccbce // Copyright (C) 1998 by Network Associates, Inc.
0171ae // All rights reserved.
b9af5a
2b6931 #if defined(PGPDISK_MFC)
32af5a
6f9e12 #include "StdAfx.h"
8eaf5a
9b4268 #elif defined(PGPDISK_95DRIVER)
4aaf5a
8206a9 #include <vtoolscp.h>
9c86d2 #include LOCKED_CODE_SEGMENT
a35269 #include LOCKED_DATA_SEGMENT
42af5a
f3f5a6 #elif defined(PGPDISK_NTDRIVER)
bfaf5a
88d7a1 #include <vdw.h>
dfaf5a
88db21 #else
ea112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
4d05d6 #endif¤ // PGPDISK_MFC
33af5a
6c9bcf #include "Required.h"
cb3db7 #include "FatUtils.h"
2cbfe9 #include "UtilityFunctions.h"
51af5a
74af5a
31fcb8 //////////////////////////////////
33610b // Disk Geometry Utility Functions
13fcb8 //////////////////////////////////
bbaf5a
7722b2 // CalcGeometry return fake geometry information for a drive.
e1af5a
8fc823 void·
c72521 CalcGeometry(PGPUInt64 blocksDisk, PGPUInt16 blockSize, Geometry *geom)
52bb36 {
3456ec ¤   pgpAssertAddrValid(geom, Geometry);
bbe50f ¤   pgpAssert(blocksDisk > 0);
128650 ¤   pgpAssert(blockSize > 0);
a7af5a
15a07a ¤   geom->geHeads¤  ¤   = kMaxHeads - 1;
00ed09 ¤   geom->geCyls¤   ¤   = kMaxCyls - 1;
9b9d6f ¤   geom->geSpt¤¤   ¤   = kMaxSpt - 1;
a4b090 ¤   geom->geBlockSize¤  = blockSize;
4fbe54 ¤   geom->geSecsDisk¤   = blocksDisk;
cbefe6 }
2faf5a
dfaf5a
34512c ////////////////////////////////
285fb1 // General FAT Utility Functions
dc512c ////////////////////////////////
5faf5a
1184bb // CalcFat16Spc calculates the sectors per cluster required for a FAT16
b3fea7 // volume of the given size in blocks.
94af5a
75411c PGPUInt16·
30c9e0 CalcFat16Spc(PGPUInt64 blocksData, PGPUInt16 blockSize)
b5bb36 {
4ba806 ¤   PGPUInt64 megsData = blocksData * blockSize/kBytesPerMeg;
feaf5a
c8fef4 ¤   if (megsData < 16)
267d1c ¤   ¤   return 8;
c75fc3 ¤   else if (megsData < 128)
1bd8bf ¤   ¤   return 4;
390535 ¤   else if (megsData < 256)
--7973 000c7adae1c40110162 Page 2 of FatUtils.cpp
777d1c ¤   ¤   return 8;
d82464 ¤   else if (megsData < 512)
d7dcac ¤   ¤   return 16;
17e205 ¤   else if (megsData < 1024)
1886bb ¤   ¤   return 32;
6f4264 ¤   else·
1d3e35 ¤   ¤   return 64;
f0efe6 }
33af5a
8e7fa2 // CalcFat32Spc calculates the sectors per cluster required for a FAT32
c3fea7 // volume of the given size in blocks.
74af5a
38411c PGPUInt16·
5e4528 CalcFat32Spc(PGPUInt64 blocksData, PGPUInt16 blockSize)
d5bb36 {
cda806 ¤   PGPUInt64 megsData = blocksData * blockSize/kBytesPerMeg;
0caf5a
129974 ¤   // This function is not reliable for sizes above 8 gigabytes as Microsoft
dd8372 ¤   // hasn't appeared to have told us yet what clusters sizes should be in
801202 ¤   // volumes above 8 gigs.
92af5a
b0c88a ¤   if (megsData < 8192)
ee7d1c ¤   ¤   return 8;
8c0e24 ¤   else
6586bb ¤   ¤   return 32;
e9efe6 }
4aaf5a
04cbed // CalcFatSize will calculate the size of the FAT tables for a volume.
a1465d //
018cca // On entry the fdBlockSize, fdFatCount, fdReservedSecs, and fdSPC members
4487c9 // must be specified.
e3465d //
b2f5bf // On exit fdFatSize will have been filled in.
cbaf5a
7cc823 void·
980e58 CalcFatSize(FatData *fat, PGPUInt64 blocksDisk)
83bb36 {
b5fe0a ¤   PGPUInt32¤  bitsPerClust, bitsPerBlock, bitsPerSpc, numClusts;
7252e2 ¤   PGPUInt64¤  bitsAvail;
14af5a
a8d626 ¤   pgpAssertAddrValid(fat, FatData);
882a6c ¤   pgpAssert(IsFatVolume(fat->fdFsId));
5f6fb6 ¤   pgpAssert(fat->fdBlockSize > 0);
0ace43 ¤   pgpAssert(fat->fdFatCount > 0);
f533de ¤   pgpAssert(fat->fdSpc > 0);
03af5a
4bda7e ¤   switch (fat->fdFsId)
c1c7a1 ¤   {
c7c111 ¤   case kFS_FAT12:
1f073d ¤   ¤   bitsPerClust = kBitsFat12Clust;
cb2f68 ¤   ¤   break;
96af5a
7fa270 ¤   case kFS_FAT16:
d711e3 ¤   ¤   bitsPerClust = kBitsFat16Clust;
e92f68 ¤   ¤   break;
62af5a
7bf867 ¤   case kFS_FAT32:
6b9cc7 ¤   ¤   bitsPerClust = kBitsFat32Clust;
a62f68 ¤   ¤   break;
caaf5a
d12f72 ¤   default:
758f52 ¤   ¤   pgpAssert(FALSE);
232f68 ¤   ¤   break;
ab9371 ¤   }
fcaf5a
bf449f ¤   // Bits per block = bytes per block * bits per byte.
c40f2b ¤   bitsPerBlock = fat->fdBlockSize * kBitsPerByte;
4faf5a
7e4f8e ¤   // Bits available for FAT tables = (# of blocks on disk - # of reserved
d519b6 ¤   // sectors) * bits per block.
89af5a
c73292 ¤   bitsAvail = (blocksDisk - fat->fdReservedSecs) * bitsPerBlock;
--8651 000e34464a640110162 Page 3 of FatUtils.cpp
e0af5a
6cc745 ¤   // Bits per SPC = # of spc * bits per block.
525d93 ¤   bitsPerSpc = fat->fdSpc * bitsPerBlock;
8baf5a
a1cdda ¤   // # of clusters = available bits / (bits per SPC + (# fats * bits per
9def4c ¤   // fat table cluster)).
b2af5a
65aa56 ¤   numClusts = (PGPUInt32)·
dd453b ¤   ¤   (bitsAvail / (bitsPerSpc + (fat->fdFatCount * bitsPerClust)));
b2af5a
3d3646 ¤   // Blocks per FAT = ceiling of (# of clusters * bits per cluster) divided
6a341e ¤   // by (bits per block);
29af5a
81fcd3 ¤   fat->fdFatSize = (PGPUInt32) CeilDiv((numClusts * bitsPerClust),·
99721c ¤   ¤   bitsPerBlock);
56efe6 }
3eaf5a
41738d // CalcFatDataSec will calculate and return the index of the first sector on
6dc0d0 // disk of the data area of a FAT drive.
2a465d //
7cd3c9 // On entry the fdBlockSize, fdFatCount, fdReservedSecs, fdSPC,·
a80aa8 // fdRootDirEnts (if non-FAT32), and fdFatSize members must be specified.
6b465d //
77394e // On exit fdFirstSecData will have been filled in.
daaf5a
fcc823 void·
e4c9b7 CalcFatDataSec(FatData *fat)
52bb36 {
b36f2f ¤   PGPUInt32 bytesDirEnt, secsRootDir;
98af5a
5ad626 ¤   pgpAssertAddrValid(fat, FatData);
e42a6c ¤   pgpAssert(IsFatVolume(fat->fdFsId));
536fb6 ¤   pgpAssert(fat->fdBlockSize > 0);
d2ce43 ¤   pgpAssert(fat->fdFatCount > 0);
df33de ¤   pgpAssert(fat->fdSpc > 0);
cb48c3 ¤   pgpAssert(fat->fdFatSize > 0);
e9af5a
37da7e ¤   switch (fat->fdFsId)
25c7a1 ¤   {
83c111 ¤   case kFS_FAT12:
a5a270 ¤   case kFS_FAT16:
0a8fdc ¤   ¤   // Size of the root directory = ceiling of (# of root directory
5fdbe9 ¤   ¤   // entries * the size of each entry) divided by (# bytes per sector).
6aaf5a
7cc9e6 ¤   ¤   bytesDirEnt = (fat->fdFsId == kFS_FAT12 ? kBytesFat12DirEnt :·
6dc47c ¤   ¤   ¤   kBytesFat16DirEnt);
15af5a
5369b1 ¤   ¤   // First sector of data area = (# of reserved sectors) plus (# of FAT
88c08d ¤   ¤   // tables times size of each table in sectors) plus (sectors in the
2f05dc ¤   ¤   // root directory).
adaf5a
aa7d14 ¤   ¤   secsRootDir = (PGPUInt32)·
292d08 ¤   ¤   ¤   CeilDiv((fat->fdRootDirEnts * bytesDirEnt),·
7e4764 ¤   ¤   ¤   fat->fdBlockSize);
ffaf5a
963b39 ¤   ¤   fat->fdFirstSecData = fat->fdReservedSecs +·
61a1b5 ¤   ¤   ¤   (fat->fdFatCount * fat->fdFatSize) + secsRootDir;
922f68 ¤   ¤   break;
39af5a
98f867 ¤   case kFS_FAT32:
0269b1 ¤   ¤   // First sector of data area = (# of reserved sectors) plus (# of FAT
6c301f ¤   ¤   // tables times size of each table in sectors).
c8af5a
4d3b39 ¤   ¤   fat->fdFirstSecData = fat->fdReservedSecs +·
276649 ¤   ¤   ¤   (fat->fdFatCount*fat->fdFatSize);
e82f68 ¤   ¤   break;
45af5a
162f72 ¤   default:
bb8f52 ¤   ¤   pgpAssert(FALSE);
8f2f68 ¤   ¤   break;
6d9371 ¤   }
e3efe6 }
--6634 000a7afe92640110162 Page 4 of FatUtils.cpp
e0af5a
a0add4 // InitFatData will initialize a FatData structure with default values. On
974f3a // entrance, the fdFsId member must be filled in.
4daf5a
9cc823 void·
6cce6f InitFatData(FatData *fat, PGPUInt64 blocksDisk)
f9bb36 {
c0d626 ¤   pgpAssertAddrValid(fat, FatData);
b02a6c ¤   pgpAssert(IsFatVolume(fat->fdFsId));
71af5a
b1da7e ¤   switch (fat->fdFsId)
6bc7a1 ¤   {
e1af5a
d2c111 ¤   case kFS_FAT12:
01ca5e ¤   ¤   fat->fdBlockSize¤   = kDefaultBlockSize;
4f4e94 ¤   ¤   fat->fdActiveFat¤   = 0;
3401d6 ¤   ¤   fat->fdFatCount¤¤   = kDefaultFatCount;
4deb75 ¤   ¤   fat->fdReservedSecs¤= kDefaultFat12Reserved;
04b399 ¤   ¤   fat->fdRootDirEnts¤ = kDefaultRootDirEnts;
214eb2 ¤   ¤   fat->fdSpc¤ ¤   ¤   = 1;
d62f68 ¤   ¤   break;
22af5a
98a270 ¤   case kFS_FAT16:
d9ca5e ¤   ¤   fat->fdBlockSize¤   = kDefaultBlockSize;
624e94 ¤   ¤   fat->fdActiveFat¤   = 0;
3701d6 ¤   ¤   fat->fdFatCount¤¤   = kDefaultFatCount;
6ab520 ¤   ¤   fat->fdReservedSecs¤= kDefaultFat16Reserved;
47b399 ¤   ¤   fat->fdRootDirEnts¤ = kDefaultRootDirEnts;
85f29d ¤   ¤   fat->fdSpc¤ ¤   ¤   = CalcFat16Spc(blocksDisk, fat->fdBlockSize);
d42f68 ¤   ¤   break;
a2af5a
41f867 ¤   case kFS_FAT32:
4aca5e ¤   ¤   fat->fdBlockSize¤   = kDefaultBlockSize;
7a0ddb ¤   ¤   fat->fdActiveFat¤   = kDefaultActiveFat;
8a01d6 ¤   ¤   fat->fdFatCount¤¤   = kDefaultFatCount;
70e9ce ¤   ¤   fat->fdReservedSecs¤= kDefaultFat32Reserved;
922f2c ¤   ¤   fat->fdSpc¤ ¤   ¤   = CalcFat32Spc(blocksDisk, fat->fdBlockSize);
af2f68 ¤   ¤   break;
f3af5a
422f72 ¤   default:
038f52 ¤   ¤   pgpAssert(FALSE);
cf2f68 ¤   ¤   break;
3a9371 ¤   }
63af5a
0012a8 ¤   CalcFatSize(fat, blocksDisk);
1b26f3 ¤   CalcFatDataSec(fat);
b1efe6 }
d5af5a
d8af5a
af3e71 /////////////////////////////////////
9808a1 // Cluster Specific Utility Functions
403e71 /////////////////////////////////////
0baf5a
9d2f8a // ClusterToSector returns the sector number corresponding to the first sector
c42401 // that the given cluster points to. The bias is a small constant subtracted
2c629f // from the cluster index to account for some reserved non-data clusters at
aff3ba // the beginning of every FAT table.
f8465d //
3712ec // First sector referenced by cluster = the first sector of the data area +
de3380 // the adjusted index of the cluster * the number of sectors per cluster.
2aaf5a
4a1b0b PGPUInt32·
4e39d8 ClusterToSector(
43a5d9 ¤   PGPUInt32 clustNum,·
48824b ¤   PGPUInt32 firstSecData,·
bf9dcf ¤   PGPUInt16 spc,·
cf4d6f ¤   PGPUInt16 bias)
a6bb36 {
521808 ¤   pgpAssert(firstSecData > 0);
c21beb ¤   pgpAssert(spc > 0);
9aaf5a
a73b3f ¤   return firstSecData + ((clustNum - bias) * spc);
--6441 000df5fc0a240110162 Page 5 of FatUtils.cpp
7aefe6 }
46af5a
5922c4 // ExtractCluster returns the value stored at the cluster that is bitOffset
826012 // bits into the buffer mSecBuf (which contains sectors from a FAT table),
5bb26b // representing the cluster index curClust.
3faf5a
a51b0b PGPUInt32·
d0aefc ExtractCluster(
794f03 ¤   PGPUInt8¤   *buf,·
9c48e8 ¤   PGPUInt32¤  bitOffset,·
a2d3d1 ¤   PGPUInt32¤  curClust,·
a2e2e4 ¤   FileSysId¤  fsId)
f2bb36 {
f36f5d ¤   PGPUInt8 a, b;
d3af5a
f6b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
be3e63 ¤   pgpAssert(IsFatVolume(fsId));
bfaf5a
0df84d ¤   switch (fsId)
f7c7a1 ¤   {
80c111 ¤   case kFS_FAT12:
258e1a ¤   ¤   a = buf[bitOffset/kBitsPerByte];¤   ¤   ¤   ¤   // get byte 1
b6d5fb ¤   ¤   b = buf[bitOffset/kBitsPerByte + 1];¤   ¤   ¤   // get byte 2
c1af5a
d99a35 ¤   ¤   if (curClust % 2)
cb42e5 ¤   ¤   ¤   return (MakeWord(a, b) >> 4);
310e1d ¤   ¤   else
eedb36 ¤   ¤   ¤   return (MakeWord(a, b) & 0x0FFF);
a3af5a
4da270 ¤   case kFS_FAT16:
0e926c ¤   ¤   return ((PGPUInt16*) buf)[bitOffset/kBitsPerWord];
23af5a
14f867 ¤   case kFS_FAT32:
e14ab6 ¤   ¤   return ((PGPUInt32*) buf)[bitOffset/kBitsPerDWord] & kFat32ClustMask;
91af5a
f3af5a
1b2f72 ¤   default:
2f8f52 ¤   ¤   pgpAssert(FALSE);
17bbde ¤   ¤   return 0;
a79371 ¤   }
e6af5a
283e6b ¤   return 0;
66efe6 }
23af5a
7b8480 // GetClusterSector takes as input:
b1465d //
5f8720 // fFatSec = the number of the first sector of a FAT table,
e65f37 // clustNum = the index of a cluster in that table,
ebd34e // bitsClust = the size of each cluster in bits.
78465d //
fa38db // As output, it sets the value of these variables (passed by reference):
92465d //
6d556e // clustSec = the number of the sector (within the FAT table) containing
b493d2 // bitOffset = the offset of the cluster in that particular sector (in bits).
baaf5a
68c823 void·
e7ca58 GetClusterInfo(
c5e5c2 ¤   PGPUInt32¤  firstFatSec,·
e3c06d ¤   PGPUInt32¤  clustNum,·
805f8e ¤   PGPUInt32¤  bitsClust,·
5ec578 ¤   PGPUInt16¤  blockSize,·
5c0a81 ¤   PGPUInt32¤  *clustSec,·
6c0bb7 ¤   PGPUInt32¤  *bitOffset)
e6bb36 {
97ff6a ¤   pgpAssertAddrValid(clustSec, PGPUInt32);
e8b415 ¤   pgpAssertAddrValid(bitOffset, PGPUInt32);
eb1082 ¤   pgpAssert(firstFatSec > 0);
174b51 ¤   pgpAssert(bitsClust > 0);
aaaf5a
89b850 ¤   (* clustSec) = firstFatSec +·
3fd898 ¤   ¤   ((clustNum*bitsClust)/kBitsPerByte/blockSize);
dfaf5a
--ea1f 001bf74f71540110162 Page 6 of FatUtils.cpp
9e67e2 ¤   (* bitOffset) = (PGPUInt16)·
d41c86 ¤   ¤   ((clustNum*bitsClust)%(blockSize*kBitsPerByte));
5defe6 }
89af5a
551574 // TotalClusters returns the total number of clusters in a FAT table of size
81036e // 'fatSize' (in sectors) with clusters of size 'bitsClust' (in bits) and
215f7a // blocks of size 'blockSize' (in bytes).
c6af5a
3a1b0b PGPUInt32·
cd088a TotalClusters(
aca0c7 ¤   PGPUInt32¤  fatSize,·
fd5f8e ¤   PGPUInt32¤  bitsClust,·
e07c2f ¤   PGPUInt16¤  blockSize)
2bbb36 {
06af9f ¤   pgpAssert(fatSize > 0);
554b51 ¤   pgpAssert(bitsClust > 0);
928650 ¤   pgpAssert(blockSize > 0);
23af5a
475f25 ¤   return (fatSize * blockSize * kBitsPerByte) / bitsClust;
bfefe6 }
--6006 00059790b5d40110163 Page 1 of FatUtils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
936224 // FatUtils.h
ad465d //
8ebe5f // Declarations for FatUtils.cpp.
ca1bc3 //////////////////////////////////////////////////////////////////////////////
8baf5a
b9c1ff // $Id: FatUtils.h,v 1.1.2.12 1998/08/04 02:10:11 nryan Exp $
8caf5a
1ecbce // Copyright (C) 1998 by Network Associates, Inc.
d371ae // All rights reserved.
98af5a
b64e9a #ifndef Included_FatUtils_h¤// [
27e826 #define Included_FatUtils_h
bdaf5a
6ce79f // Align to 1.
d0fcdb #pragma pack(push, 1)
a3af5a
9790e1 //////////////////////////////////////
0d4782 // Constants common to all FAT volumes
5f90e1 //////////////////////////////////////
a5af5a
facfa2 const PGPUInt8¤ kMediaByte¤ ¤   ¤   = 0xF8;
4ccc0f const PGPUInt8¤ kHardDriveId¤   ¤   = 0x80;
59060f const PGPUInt8¤ kFat12PartId¤   ¤   = 0x01;
ff3aaf const PGPUInt8¤ kBigFat16PartId¤¤   = 0x06;
b5a995 const PGPUInt8¤ kSmallFat16PartId¤  = 0x04;
bbdf3b const PGPUInt8¤ kFat32PartId¤   ¤   = 0x0B;
e1455f const PGPUInt8¤ kFirstBootSig¤  ¤   = 0x29;
19a6e2 const PGPUInt16¤kSecondBootSig¤ ¤   = 0xAA55;
18af5a
d1af5a
7290e1 //////////////////////////////////////
72aa52 // Constants specific to FAT12 volumes
d190e1 //////////////////////////////////////
08af5a
224a5b static LPCSTR kFat12IdStr = "FAT12 ··";
7faf5a
7edb6b const PGPUInt32¤kFat12Offset¤   ¤   = 0x36;
5fdec0 const PGPUInt32¤kFat12ClustBias¤¤   = 2;
8582ac const PGPUInt32¤kBitsFat12Clust¤¤   = 12;
ae20ac const PGPUInt32¤kBytesFat12DirEnt¤  = 32;
d4a7ef const PGPUInt16¤kMinFat12Clust¤ ¤   = 0x0002;
d0f7cd const PGPUInt16¤kMaxFat12Clust¤ ¤   = 0x0FEF;
2e2377 const PGPUInt32¤kFat12Sig¤  ¤   ¤   = 0x00FFFFF8;
21af5a
23af5a
f890e1 //////////////////////////////////////
c31ace // Constants specific to FAT16 volumes
ba90e1 //////////////////////////////////////
b3af5a
94f89d static LPCSTR kFat16IdStr = "FAT16 ··";
f2af5a
40ec6d const PGPUInt32¤kFat16Offset¤   ¤   = 0x36;
98bbab const PGPUInt32¤kFat16ClustBias¤¤   = 2;
2fa1f1 const PGPUInt32¤kBitsFat16Clust¤¤   = 16;
a308ce const PGPUInt32¤kBytesFat16DirEnt¤  = 32;
9112b9 const PGPUInt16¤kMinFat16Clust¤ ¤   = 0x0002;
e39f60 const PGPUInt16¤kMaxFat16Clust¤ ¤   = 0xFFEF;
807c19 const PGPUInt32¤kOver16MbFat16Sig¤  = 0xFFFFFFF8;
1ecde4 const PGPUInt32¤kUnder16MbFat16Sig¤ = 0x00FFFFF8;
9aaf5a
98af5a
d090e1 //////////////////////////////////////
a20170 // Constants specific to FAT32 volumes
9490e1 //////////////////////////////////////
a4af5a
e21b9f static LPCSTR kFat32IdStr = "FAT32 ··";
12af5a
f4f40f const PGPUInt32¤kFat32Offset¤   ¤   ¤   = 0x52;
3cedb0 const PGPUInt32¤kFat32ClustBias¤¤   ¤   = 2;
762853 const PGPUInt32¤kBitsFat32Clust¤¤   ¤   = 32;
596c03 const PGPUInt32¤kBigFatSig¤ ¤   ¤   ¤   = 0x61417272;
--88e2 00001ca166640110163 Page 2 of FatUtils.h
9673ed const PGPUInt32¤kBigFatSecSig¤  ¤   ¤   = 0x41615252;
7b1990 const PGPUInt32¤kFat32ClustMask¤¤   ¤   = 0x00FFFFFF;
3059ce const PGPUInt32¤kMinFat32Megs¤  ¤   ¤   = 260;
3209ba const PGPUInt32¤kMinFat32Clust¤ ¤   ¤   = 0x00000002;
1746e3 const PGPUInt32¤kMaxFat32Clust¤ ¤   ¤   = 0x00FFFFEF;
b67a0a const PGPUInt32¤kFat32Clust1¤   ¤   ¤   = 0x0FFFFFF8;
bc1c11 const PGPUInt32¤kFat32Clust2¤   ¤   ¤   = 0x0FFFFFFF;
9ade9a const PGPUInt32¤kFat32Clust3¤   ¤   ¤   = 0x0FFFFFF8;
62d659 const PGPUInt32¤BGBPB_F_ActiveFATMsk¤   = 0x000F;
6e9cbf const PGPUInt32¤BGBPB_F_NoFATMirror¤¤   = 0x0080;
48af5a
08af5a
d4b352 //////////////////////////
58a347 // Miscellaneous constants
78b352 //////////////////////////
aaaf5a
fa3b2d const PGPUInt8 kFloppyMediaId = 0xF0;
7aaf5a
21af5a
29d557 ////////
db02c9 // Types
47d557 ////////
18af5a
221819 enum FileSysId {kFS_FAT12, kFS_FAT16, kFS_FAT32, kFS_NTFS, kFS_Unknown};
72af5a
81c86b #pragma pack(1)
faaf5a
5fbe9d // Geometry is a structure that describes the geometry of a drive.
a2af5a
a1a76c typedef struct Geometry
f8bb36 {
099229 ¤   PGPUInt8¤   geHeads;
25541a ¤   PGPUInt8¤   geCyls;
4209e4 ¤   PGPUInt8¤   geSpt;
e80d7c ¤   PGPUInt16¤  geBlockSize;
88bb19 ¤   PGPUInt64¤  geSecsDisk;
efaf5a
e45f34 } Geometry, *PGeometry;
e7af5a
f20d83 // FatData is a PGPdisk-specific structure used to store FAT information about
dc1637 // a certain file open on a FAT16 or FAT32 host drive.
1daf5a
ca4a28 typedef struct FatData
7cbb36 {
231ced ¤   FileSysId¤  fdFsId;¤¤   ¤   ¤   ¤   // will be FAT12, FAT16 or FAT32
17af5a
570176 ¤   PGPUInt8¤   fdActiveFat;¤   ¤   ¤   // index of active FAT
54367f ¤   PGPUInt8¤   fdFatCount;¤¤   ¤   ¤   // number of FATs
e0af5a
2f2d78 ¤   PGPUInt16¤  fdBlockSize;¤   ¤   ¤   // blocksize of the volume
eb79e4 ¤   PGPUInt16¤  fdReservedSecs;¤¤   ¤   // number of reserved sectors
978c20 ¤   PGPUInt16¤  fdRootDirEnts;¤ ¤   ¤   // entries in root dir (FAT12/16)
f9d4d0 ¤   PGPUInt16¤  fdSpc;¤ ¤   ¤   ¤   ¤   // sectors per cluster
72af5a
f6687b ¤   PGPUInt32¤  fdFatSize;¤ ¤   ¤   ¤   // # of sectors per fat
1dff1a ¤   PGPUInt32¤  fdFirstSecFat;¤ ¤   ¤   // sector # of first fat
09abe2 ¤   PGPUInt32¤  fdFirstClustFile;¤  ¤   // clust # where file's data begins
4f590a ¤   PGPUInt32¤  fdFirstSecData;¤¤   ¤   // first sector of data area on drive
3aaf5a
339e00 } FatData, *PFatData;
39af5a
1ca55c // FvBlock is used by the system during int21h 440d 42 calls. It specifies
38b841 // a sector on a disk to format.
63af5a
4b87c0 typedef struct FvBlock
10bb36 {
f87c7f ¤   PGPUInt8¤   fvSpecFunc;¤¤   ¤   ¤   // 'special function'
d833f8 ¤   PGPUInt16¤  fvHead;¤¤   ¤   ¤   ¤   // head
8e6b65 ¤   PGPUInt16¤  fvCylinder;¤¤   ¤   ¤   // cylinder
9d3a5a ¤   PGPUInt16¤  fvTracks;¤  ¤   ¤   ¤   // track
9aaf5a
017280 } FvBlock;
--7188 0002a8adf5440110163 Page 3 of FatUtils.h
e0af5a
3495b0 // FvBlock is used by the system during int21h 440d 61 calls. It specified
b54375 // one or more sectors on a disk to read.
d2af5a
c755b3 typedef struct RwBlock
87bb36 {
7bd116 ¤   PGPUInt8¤   rwSpecFunc;¤¤   ¤   ¤   // 'special function'
e56d02 ¤   PGPUInt16¤  rwHead;¤¤   ¤   ¤   ¤   // head
375318 ¤   PGPUInt16¤  rwCylinder;¤¤   ¤   ¤   // cylinder
dec3ac ¤   PGPUInt16¤  rwFirstSector;¤ ¤   ¤   // spt
049a01 ¤   PGPUInt16¤  rwSectors;¤ ¤   ¤   ¤   // number of sectors
124b88 ¤   PGPUInt32¤  rwBuffer;¤  ¤   ¤   ¤   // output buffer
5daf5a
14334e } RwBlock;
17af5a
34093c // MID is used by the system during int21h 440d 66 calls.
c1af5a
bea6a9 typedef struct MID
59bb36 {
9c2665 ¤   PGPUInt16¤  midInfoLevel;¤  ¤   ¤   // information level
7a60c1 ¤   PGPUInt32¤  midSerialNum;¤  ¤   ¤   // serial number
4b8637 ¤   PGPUInt8¤   midVolLabel[11];¤   ¤   // volume label
9f06f8 ¤   PGPUInt8¤   midFileSysType[8];¤ ¤   // filesystem type
d0af5a
f370a6 } MID;
69af5a
f0c7d7 // A PartEntry is a structure contained in the MBR (master boot record) of a
c7f426 // hard disk that describes the geometry for a particular partition. There can
8a2fc4 // be up to 4 of these.
5daf5a
5fff98 typedef struct PartEntry
28bb36 {
5ffd6d ¤   PGPUInt8¤   peBootable;¤¤   ¤   ¤   // 80h = bootable, 00h = nonbootable
a49b01 ¤   PGPUInt8¤   peBeginHead;¤   ¤   ¤   // beginning head
121d60 ¤   PGPUInt8¤   peBeginSector;¤ ¤   ¤   // beginning sector
b7e43f ¤   PGPUInt8¤   peBeginCylinder;¤   ¤   // beginning cylinder
c367c7 ¤   PGPUInt8¤   peFileSystem;¤  ¤   ¤   // ID of filesystem
a56c34 ¤   PGPUInt8¤   peEndHead;¤ ¤   ¤   ¤   // ending head
fea537 ¤   PGPUInt8¤   peEndSector;¤   ¤   ¤   // ending sector
deda90 ¤   PGPUInt8¤   peEndCylinder;¤ ¤   ¤   // ending cylinder
e79bfd ¤   PGPUInt32¤  peStartSector;¤ ¤   ¤   // starting sector
78ad5e ¤   PGPUInt32¤  peSectors;¤ ¤   ¤   ¤   // total sectors
e1af5a
f83673 } PartEntry, *PPartEntry;
00af5a
815775 // BootSector16 is a structure exactly 512 bytes long that occupies the first
c0d65c // sector of a FAT66 partition. On real hard disks, there are actually two
41f2ae // boot blocks: the MBR (master boot record) at the very beginning of the disk
24e8a2 // and a FAT bootsector in each partition. With PGPdisks we simply combine the
0744df // MBR and FAT bootblocks into one big partition.
4daf5a
101d28 typedef struct BootSector16
ddbb36 {
51574c ¤   PGPUInt8¤   bsJump[3];¤ ¤   ¤   ¤   // jmp to bootstrap instruction
4a94c7 ¤   char¤   ¤   bsOemName[8];¤  ¤   ¤   // OEM name and version
f6af5a
e9b9f9 ¤   PGPUInt16¤  bsBytesPerSec;¤ ¤   ¤   // bytes per sector
3203ab ¤   PGPUInt8¤   bsSecPerClust;¤ ¤   ¤   // sectors per cluster
c2c611 ¤   PGPUInt16¤  bsResSectors;¤  ¤   ¤   // number of reserved sectors
13767b ¤   PGPUInt8¤   bsFats;¤¤   ¤   ¤   ¤   // number of file allocation tables
686038 ¤   PGPUInt16¤  bsRootDirEnts;¤ ¤   ¤   // number of root-directory entries
590f18 ¤   PGPUInt16¤  bsSectors;¤ ¤   ¤   ¤   // total number of secs (<= 32 megs)
fc4c54 ¤   PGPUInt8¤   bsMedia;¤   ¤   ¤   ¤   // media descriptor
5d51d0 ¤   PGPUInt16¤  bsFatSecs;¤ ¤   ¤   ¤   // number of sectors per FAT
1d8cc9 ¤   PGPUInt16¤  bsSecPerTrack;¤ ¤   ¤   // sectors per track (head)
f74cf5 ¤   PGPUInt16¤  bsHeads;¤   ¤   ¤   ¤   // number of heads
c9d97f ¤   PGPUInt32¤  bsHiddenSecs;¤  ¤   ¤   // number of hidden sectors
9e82ca ¤   PGPUInt32¤  bsHugeSectors;¤ ¤   ¤   // total number of sectors (> 32 megs)
8c7668 ¤   PGPUInt8¤   bsDriveNumber;¤ ¤   ¤   // drive number (80h)
59af5a
7ebb19 ¤   PGPUInt8¤   bsReserved1;¤   ¤   ¤   // reserved
2a4190 ¤   PGPUInt8¤   bsBootSignature;¤   ¤   // extended boot signature (29h)
--a803 000039927f040110163 Page 4 of FatUtils.h
b68fde ¤   PGPUInt32¤  bsVolumeId;¤¤   ¤   ¤   // volume ID number
ee0806 ¤   char¤   ¤   bsVolumeLabel[11];¤ ¤   // volume label
7144bc ¤   char¤   ¤   bsFileSysType[8];¤  ¤   // filesystem type
7c31d6 ¤   PGPUInt8¤   padding[384];¤  ¤   ¤   // padding to 512 bytes
f7c597 ¤   PartEntry¤  bsPartEnts[4];¤ ¤   ¤   // partition entry table
433763 ¤   PGPUInt16¤  bsSignature;¤   ¤   ¤   // boot block signature (0xAA55h)
e6af5a
866937 } BootSector16, *PBootSector16;
0daf5a
a46236 typedef BootSector16 BootSector12;
2d4732 typedef BootSector12 *PBootSector12;
bdaf5a
5a2672 // The BigFatBootFSInfo structure (yes, this is the official Microsoft name
cbfca0 // for it) contains extra info for FAT32 drives and typically occupies its own
cbe532 // sector.
9caf5a
93d69a typedef struct BigFatBootFSInfo
b7bb36 {
981f4a ¤   PGPUInt32¤  bfSecSig;¤  ¤   ¤   ¤   ¤   ¤   // sector sig (kBigFatSecSig)
5b163e ¤   PGPUInt8¤   bfPadding1[480];¤   ¤   ¤   ¤   // padding to 512 bytes
d4af5a
bc49af ¤   PGPUInt32¤  bfFSInf_Sig;¤   ¤   ¤   ¤   ¤   // signature (kBigFatSig)
f9bc03 ····PGPUInt32¤  bfFSInf_free_clus_cnt;¤ ¤   ¤   // number of free clusters
aeccbc ¤   PGPUInt32¤  bfFSInf_next_free_clus;¤¤   ¤   // next free cluster
ea68cb ····PGPUInt32¤  bfFSInf_resvd;
48bc90 ¤   PGPUInt32¤  bfReserved[2];
1e9fc2 ¤   PGPUInt8¤   bfPadding2[2];¤ ¤   ¤   ¤   ¤   // padding to 512 bytes
f13e71 ¤   PGPUInt16¤  bsSignature;¤   ¤   ¤   ¤   ¤   // 0xAA55h as in boot block
c3af5a
40f8c6 } BigFatBootFSInfo, *PBigFatBootFSInfo;
cbaf5a
de09fd // BootSector32 is a structure that is two sectors long and represents the
80230f // boot blocks for FAT32 drives. The first sector is similar to that for
6c42e3 // FAT16, but the second sector contains some additional information about
5adeb7 // free sectors, etc.
dfaf5a
2acff0 typedef struct BootSector32
a0bb36 {
fd574c ¤   PGPUInt8¤   bsJump[3];¤ ¤   ¤   ¤   // jmp to bootstrap instruction
0394c7 ¤   char¤   ¤   bsOemName[8];¤  ¤   ¤   // OEM name and version
ffaf5a
75b9f9 ¤   PGPUInt16¤  bsBytesPerSec;¤ ¤   ¤   // bytes per sector
d703ab ¤   PGPUInt8¤   bsSecPerClust;¤ ¤   ¤   // sectors per cluster
a2c611 ¤   PGPUInt16¤  bsResSectors;¤  ¤   ¤   // number of reserved sectors
e5767b ¤   PGPUInt8¤   bsFats;¤¤   ¤   ¤   ¤   // number of file allocation tables
ab6038 ¤   PGPUInt16¤  bsRootDirEnts;¤ ¤   ¤   // number of root-directory entries
ce0f18 ¤   PGPUInt16¤  bsSectors;¤ ¤   ¤   ¤   // total number of secs (<= 32 megs)
dc4c54 ¤   PGPUInt8¤   bsMedia;¤   ¤   ¤   ¤   // media descriptor
ad51d0 ¤   PGPUInt16¤  bsFatSecs;¤ ¤   ¤   ¤   // number of sectors per FAT
ed8cc9 ¤   PGPUInt16¤  bsSecPerTrack;¤ ¤   ¤   // sectors per track (head)
724cf5 ¤   PGPUInt16¤  bsHeads;¤   ¤   ¤   ¤   // number of heads
cbd97f ¤   PGPUInt32¤  bsHiddenSecs;¤  ¤   ¤   // number of hidden sectors
0a82ca ¤   PGPUInt32¤  bsHugeSectors;¤ ¤   ¤   // total number of sectors (> 32 megs)
e87a10 ¤   PGPUInt32¤  bsBigSectorsPerFat;¤¤   // total sectors per FAT
7d0901 ¤   PGPUInt16¤  bsExtFlags;¤¤   ¤   ¤   // extended flags
d45e67 ¤   PGPUInt16¤  bsFS_Version;¤  ¤   ¤   // filesystem version
6909b4 ¤   PGPUInt32¤  bsRootDirStrtClus;¤ ¤   // first cluster of root dir
6517e8 ¤   PGPUInt16¤  bsFsInfoSec;¤   ¤   ¤   // sector of FSInfo sec
7f6ad2 ¤   PGPUInt16¤  bsBkUpBootSec;¤ ¤   ¤   // sector of backup boot sec
d441fe ¤   PGPUInt16¤  bsReserved2[6];¤¤   ¤   // reserved
4e67c5 ¤
867668 ¤   PGPUInt8¤   bsDriveNumber;¤ ¤   ¤   // drive number (80h)
a6bb19 ¤   PGPUInt8¤   bsReserved1;¤   ¤   ¤   // reserved
364190 ¤   PGPUInt8¤   bsBootSignature;¤   ¤   // extended boot signature (29h)
b18fde ¤   PGPUInt32¤  bsVolumeId;¤¤   ¤   ¤   // volume ID number
070806 ¤   char¤   ¤   bsVolumeLabel[11];¤ ¤   // volume label
0444bc ¤   char¤   ¤   bsFileSysType[8];¤  ¤   // filesystem type
ee26df ¤   PGPUInt8¤   padding1[356];¤ ¤   ¤   // padding to fill out first sector
4bc597 ¤   PartEntry¤  bsPartEnts[4];¤ ¤   ¤   // partition entry table
c63763 ¤   PGPUInt16¤  bsSignature;¤   ¤   ¤   // boot block signature (0xAA55h)
0caf5a
03d89b } BootSector32, *PBootSector32;
--a62b 000a326f18040110163 Page 5 of FatUtils.h
e0af5a
fdf0f9 // In order to gather the necessary information about the structure of the
f7e432 // host FAT drive, the app makes simulated DOS IOCTL calls. If the host is
c45917 // FAT16, it makes a call to retrieve a FAT16 DevParams structure. If the
fd6bc9 // host is FAT32, it makes a call to retrieve a FAT32 DevParams structure.
21af5a
01fc26 typedef struct DevParams16
0bbb36 {
ec35ed ¤   PGPUInt8¤   dpSpecFunc;¤¤   ¤   ¤   // special functions
705c33 ¤   PGPUInt8¤   dpDevType;¤ ¤   ¤   ¤   // device type
f977bd ¤   PGPUInt16¤  dpDevAttr;¤ ¤   ¤   ¤   // device attributes
e90d99 ¤   PGPUInt16¤  dpCylinders;¤   ¤   ¤   // number of cylinders
45ce1f ¤   PGPUInt8¤   dpMediaType;¤   ¤   ¤   // media type
44af5a
3a8f3d ¤   // FAT16 BPB begins here.
f41014 ¤   PGPUInt16¤  dpBytesPerSec;¤ ¤   ¤   // bytes per sector
c88d92 ¤   PGPUInt8¤   dpSecPerClust;¤ ¤   ¤   // sectors per cluster
c86d62 ¤   PGPUInt16¤  dpResSectors;¤  ¤   ¤   // number of reserved sectors
9cff7b ¤   PGPUInt8¤   dpFats;¤¤   ¤   ¤   ¤   // number of FATs
81046c ¤   PGPUInt16¤  dpRootDirEnts;¤ ¤   ¤   // number of root-directory entries
886c45 ¤   PGPUInt16¤  dpSectors;¤ ¤   ¤   ¤   // total # of sectors (<= 32 megs)
b6e5b9 ¤   PGPUInt8¤   dpMedia;¤   ¤   ¤   ¤   // media descriptor
1f589e ¤   PGPUInt16¤  dpFatSecs;¤ ¤   ¤   ¤   // number of sectors per FAT
d9d5cd ¤   PGPUInt16¤  dpSecPerTrack;¤ ¤   ¤   // sectors per track
f4cb99 ¤   PGPUInt16¤  dpHeads;¤   ¤   ¤   ¤   // number of heads
cfdfe6 ¤   PGPUInt32¤  dpHiddenSecs;¤  ¤   ¤   // number of hidden sectors
dddf55 ¤   PGPUInt32¤  dpHugeSectors;¤ ¤   ¤   // total # of sectors (> 32 megs)
1baf5a
a8ff6d } DevParams16, *PDevParams16;
7baf5a
5b2efe typedef struct DevParams32
cdbb36 {
7935ed ¤   PGPUInt8¤   dpSpecFunc;¤¤   ¤   ¤   // special functions
a95c33 ¤   PGPUInt8¤   dpDevType;¤ ¤   ¤   ¤   // device type
e277bd ¤   PGPUInt16¤  dpDevAttr;¤ ¤   ¤   ¤   // device attributes
140d99 ¤   PGPUInt16¤  dpCylinders;¤   ¤   ¤   // number of cylinders
61ce1f ¤   PGPUInt8¤   dpMediaType;¤   ¤   ¤   // media type
8daf5a
dbdf3b ¤   // FAT32 BPB begins here
fabfe2 ¤   PGPUInt16¤  dpBytesPerSector;¤  ¤   // bytes per sector¤
8ba3fa ¤   PGPUInt8¤   dpSectorsPerClust;¤ ¤   // sectors per cluster
505dbe ¤   PGPUInt16¤  dpReservedSectors;¤ ¤   // number of reserved sectors
8ea539 ¤   PGPUInt8¤   dpNumberOfFats;¤¤   ¤   // number of FATs
455604 ¤   PGPUInt16¤  dpRootEntries;¤ ¤   ¤   // field ignored on FAT32
2f982b ¤   PGPUInt16¤  dpTotalSectors;¤¤   ¤   // total number sectors
fa0974 ¤   PGPUInt8¤   dpMediaDescriptor;¤ ¤   // media descriptor
600666 ¤   PGPUInt16¤  dpSectorsPerFat;¤   ¤   // field ignored in FAT32
133df8 ¤   PGPUInt16¤  dpSectorsPerTrack;¤ ¤   // sectors per track (head)
9ccb99 ¤   PGPUInt16¤  dpHeads;¤   ¤   ¤   ¤   // number of heads
9337e2 ¤   PGPUInt32¤  dpHiddenSectors;¤   ¤   // number of hidden sectors
a73310 ¤   PGPUInt32¤  dpBigTotalSectors;¤ ¤   // total sectors on drive
c976dc ¤   PGPUInt32¤  dpBigSectorsPerFat;¤¤   // total sectors per FAT
c675b2 ¤   PGPUInt16¤  dpExtFlags;¤¤   ¤   ¤   // extended flags
c23f4d ¤   PGPUInt16¤  dpFS_Version;¤  ¤   ¤   // filesystem version
a700fa ¤   PGPUInt32¤  dpRootDirStrtClus;¤ ¤   // first cluster of root dir
0ebb24 ¤   PGPUInt16¤  dpFsInfoSec;¤   ¤   ¤   // sector of FSInfo sec
ec639c ¤   PGPUInt16¤  dpBkUpBootSec;¤ ¤   ¤   // sector of backup boot sec
a3257a ¤   PGPUInt16¤  dpReserved;¤¤   ¤   ¤   // reserved
c78dbd ¤   // FAT 32 BPB ends here
6daf5a
861ae9 ¤   PGPUInt8¤   dpPadding[32];
d7af5a
597056 } DevParams32, *PDevParams32;
43af5a
2f1cb1 // Restore alignment.
c6f421 #pragma pack(pop)
1daf5a
85af5a
3883f5 ///////////////////////////
b25e9b // Inline utility functions
9a83f5 ///////////////////////////
a3af5a
--09e2 0016e20766b40110163 Page 6 of FatUtils.h
fc022c // IsFatVolume returns TRUE if the passed file system ID refers to a FAT
7a9d2f // volume.
91af5a
d9c85e inline·
677750 PGPBoolean
6cc231 IsFatVolume(FileSysId fsId)
d4bb36 {
983459 ¤   return ((fsId == kFS_FAT12) || (fsId == kFS_FAT16) ||·
ccc6bf ¤   ¤   (fsId == kFS_FAT32));
66efe6 }
e4af5a
3caf5a
fd6cc2 /////////////////////
7513d2 // Exported functions
8e6cc2 /////////////////////
f3af5a
67792d void¤   ¤   CalcGeometry(PGPUInt64 blocksDisk, PGPUInt16 blockSize,·
4fbebb ¤   ¤   ¤   ¤   Geometry *geom);
b1af5a
3c52e2 PGPUInt16¤  CalcFat16Spc(PGPUInt64 blocksData);
e688da PGPUInt16¤  CalcFat32Spc(PGPUInt64 blocksData);
387b15 void¤   ¤   CalcFatSize(FatData *fat, PGPUInt64 blocksDisk);
66499f void¤   ¤   CalcFatDataSec(FatData *fat);
72af5a
453ee9 void¤   ¤   InitFatData(FatData *fat, PGPUInt64 blocksDisk);
ccaf5a
86da43 PGPUInt32¤  ClusterToSector(PGPUInt32 clustNum, PGPUInt32 firstSecData,·
af53e5 ¤   ¤   ¤   ¤   PGPUInt16 spc, PGPUInt16 bias);
82f07d PGPUInt32¤  ExtractCluster(PGPUInt8 *buf, PGPUInt32 bitOffset,·
a26142 ¤   ¤   ¤   ¤   PGPUInt32 curClust, FileSysId fsId);
61ac70 void¤   ¤   GetClusterInfo(PGPUInt32 firstFatSec, PGPUInt32 clustNum,·
d2e06e ¤   ¤   ¤   ¤   PGPUInt32 bitsClust, PGPUInt16 blockSize, PGPUInt32 *clustSec,·
87711e ¤   ¤   ¤   ¤   PGPUInt32 *bitOffset);
39c801 PGPUInt32¤  TotalClusters(PGPUInt32 fatSize, PGPUInt32 bitsClust,·
e910dd ¤   ¤   ¤   ¤   PGPUInt16 blockSize);
1caf5a
6ef156 #endif¤ // ] Included_FatUtils_h
--3d74 00198d93a9040110164 Page 1 of GenericCallback.h
541bc3 //////////////////////////////////////////////////////////////////////////////
88cb68 // GenericCallback.h
ba465d //
ed9aef // The PGPdisk GenericCallback implementation.
c31bc3 //////////////////////////////////////////////////////////////////////////////
4caf5a
441083 // $Id: GenericCallback.h,v 1.1.2.6 1998/08/04 02:10:12 nryan Exp $
b3af5a
c0cbce // Copyright (C) 1998 by Network Associates, Inc.
9171ae // All rights reserved.
91af5a
26e21e #ifndef Included_GenericCallback_h¤ // [
7009c0 #define Included_GenericCallback_h
13af5a
843a85 #include "DualErr.h"
b1af5a
68af5a
43d557 ////////
9d02c9 // Types
2bd557 ////////
49af5a
f69ca9 struct GenericCallbackInfo;
45af5a
3ef8b8 // PEZCALLBACK defines a pointer to a simple callback function.
aeaf5a
36fb38 typedef void (* PEZCALLBACK)(PGPUInt32);
8baf5a
0b91fc // PGENCBFUNC defines a pointer to a GenericCallbackInfo callback function.
39af5a
a48cb5 typedef void (* PGENCBFUNC)(GenericCallbackInfo *);
b4af5a
0ddcbc // GenericCallbackInfo is for use by certain PGPdisk classes that use
98a44c // callbacks.
bfaf5a
f0c5e3 typedef struct GenericCallbackInfo
05bb36 {
1b43f7 ¤   PGENCBFUNC¤ callback;¤  ¤   // address of callback
91b33f ¤   PGPUInt32¤  refData[8];¤¤   // reference data
795101 ¤   DualErr¤¤   derr;¤  ¤   ¤   // error code
3caf5a
4dce77 } GenericCallbackInfo, *PGenericCallbackInfo;
b1af5a
98ed45 #endif // ] Included_GenericCallback_h
--12b1 00009cbf3e140110165 Page 1 of LinkResolution.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
6f80c4 // LinkResolution.cpp
2a465d //
624fab // Contains code for explicitly loading certain Windows API functions.
fa1bc3 //////////////////////////////////////////////////////////////////////////////
e6af5a
9404e5 // $Id: LinkResolution.cpp,v 1.1.2.9.2.2 1998/08/22 01:55:41 nryan Exp $
d4af5a
3fcbce // Copyright (C) 1998 by Network Associates, Inc.
f971ae // All rights reserved.
91af5a
17af5a
5c6931 #if defined(PGPDISK_MFC)
77af5a
74b855 #define NOSERVICE
bc9e12 #include "StdAfx.h"
31af5a
d69bcf #include "Required.h"
7baf5a
0cdd74 #include "WindowsVersion.h"
c37efd #include "LinkResolution.h"
35af5a
81db21 #else
8c333e #error Define PGPDISK_MFC.
6a05d6 #endif¤ // PGPDISK_MFC
78af5a
31af5a
97d43e /////////
ba596b // Macros
c7d43e /////////
ffaf5a
199e32 #define CLEANUP_WINAPI_STACK(bytes) __asm sub esp, bytes
daaf5a
79af5a
1fd557 ////////
9702c9 // Types
59d557 ////////
a5af5a
02c59a typedef long (* BroadcastSystemMessageType)(DWORD, LPDWORD, UINT, WPARAM,·
9ebd33 ¤   LPARAM);
3faf5a
9e1d1e typedef BOOL (* GetDiskFreeSpaceExAType)(LPCTSTR, PULARGE_INTEGER,·
0d83ae ¤   PULARGE_INTEGER, PULARGE_INTEGER);
33af5a
8f2988 typedef BOOL (* GetDiskFreeSpaceExWType)(LPCWSTR, PULARGE_INTEGER,·
e383ae ¤   PULARGE_INTEGER, PULARGE_INTEGER);
93af5a
e15b36 typedef SC_HANDLE (* OpenSCManagerAType)(LPCSTR, LPCSTR, DWORD);
5f75d5 typedef SC_HANDLE (* OpenSCManagerWType)(LPCWSTR, LPCWSTR, DWORD);
51af5a
fc1f32 typedef SC_HANDLE (* OpenServiceAType)(SC_HANDLE, LPCSTR, DWORD);
0883fe typedef SC_HANDLE (* OpenServiceWType)(SC_HANDLE, LPCWSTR, DWORD);
01af5a
f078bb typedef BOOL (* StartServiceAType)(SC_HANDLE, DWORD, LPCSTR *);
6e1c83 typedef BOOL (* StartServiceWType)(SC_HANDLE, DWORD, LPCWSTR *);
cdaf5a
de5c58 typedef BOOL (* ControlServiceType)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
412262 typedef BOOL (* CloseServiceHandleType)(SC_HANDLE);
23af5a
1e4ecd typedef DWORD (* WinNT_NetShareGetInfoType)(LPWSTR, LPWSTR, DWORD, LPBYTE *);
7baf5a
7387cb typedef DWORD (* Win95_NetShareGetInfoType)(const char FAR *,·
6ca667 ¤   const char FAR *, short, char FAR *, unsigned short,·
d1bb0a ¤   unsigned short FAR *);
bfaf5a
b017ce typedef DWORD (* WinNT_NetWkstaGetInfoType)(LPWSTR servername, DWORD level,·
d2886c ¤   LPBYTE *bufptr);
91af5a
636e27 typedef DWORD (* WinNT_NetApiBufferFreeType)(LPVOID);
11af5a
4caf5a
092af8 //////////
--7b46 000b0b9728940110165 Page 2 of LinkResolution.cpp
7ab932 // Globals
b12af8 //////////
83af5a
0c565d // Dll handles.
a5df04 static HINSTANCE¤   Advapi32Handle;
8b8b76 static HINSTANCE¤   Kernel32Handle;
103ddd static HINSTANCE¤   NetApi32Handle;
e5c227 static HINSTANCE¤   SvrApiHandle;
1ab047 static HINSTANCE¤   User32Handle;
bdaf5a
a171a9 // Function addresses.
42e06e static BroadcastSystemMessageType¤  BroadcastSystemMessageAddress;
b3c6dc static GetDiskFreeSpaceExAType¤ ¤   GetDiskFreeSpaceExAAddress;
c8c48d static GetDiskFreeSpaceExWType¤ ¤   GetDiskFreeSpaceExWAddress;
2caf5a
d87ea5 static OpenSCManagerAType¤  ¤   OpenSCManagerAAddress;
0db923 static OpenSCManagerWType¤  ¤   OpenSCManagerWAddress;
e38fb9 static OpenServiceAType¤¤   ¤   OpenServiceAAddress;
20483f static OpenServiceWType¤¤   ¤   OpenServiceWAddress;
b98f00 static StartServiceAType¤   ¤   StartServiceAAddress;
c94886 static StartServiceWType¤   ¤   StartServiceWAddress;
a560e4 static ControlServiceType¤  ¤   ControlServiceAddress;
abf630 static CloseServiceHandleType¤  CloseServiceHandleAddress;
1faf5a
81778a static WinNT_NetShareGetInfoType¤   WinNT_NetShareGetInfoAddress;
6b7108 static Win95_NetShareGetInfoType¤   Win95_NetShareGetInfoAddress;
e0a8e8 static WinNT_NetWkstaGetInfoType¤   WinNT_NetWkstaGetInfoAddress;
e32a79 static WinNT_NetApiBufferFreeType¤  WinNT_NetApiBufferFreeAddress;
afaf5a
35af5a
3b90e1 //////////////////////////////////////
677bcc // Initialization and cleanup routines
c390e1 //////////////////////////////////////
6aaf5a
fe84f8 // LinkStandardWin32API links in 'standard' Win32 functions.
2faf5a
b82292 DualErr·
b91f9f LinkStandardWin32API()
d4bb36 {
bc7d36 ¤   DualErr derr;
0caf5a
a49c02 ¤   Kernel32Handle = LoadLibrary("kernel32.dll");
b6af5a
e65ab5 ¤   if (IsNull(Kernel32Handle))
561aa1 ¤   ¤   derr = DualErr(kPGDMinorError_LoadLibraryFailed);
73af5a
912361 ¤   if (derr.IsntError())
f7c7a1 ¤   {
2c219d ¤   ¤   User32Handle = LoadLibrary("user32.dll");
ccaf5a
73efa3 ¤   ¤   if (IsNull(User32Handle))
03f8a1 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LoadLibraryFailed);
c09371 ¤   }
15af5a
662361 ¤   if (derr.IsntError())
5cc7a1 ¤   {
6d9890 ¤   ¤   BroadcastSystemMessageAddress = (BroadcastSystemMessageType)
3faa66 ¤   ¤   ¤   GetProcAddress(User32Handle, "BroadcastSystemMessage");
4a1b52 ¤   ¤
ea4fbd ¤   ¤   if (IsNull(BroadcastSystemMessageAddress))
5c5b34 ¤   ¤   {
ebb2d2 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetProcAddrFailed, GetLastError());
a30fe4 ¤   ¤   }
069371 ¤   }
79af5a
2a2361 ¤   if (derr.IsntError())
3ec7a1 ¤   {
d64e69 ¤   ¤   if (IsWin95OSR2CompatibleMachine() ||·
d466cc ¤   ¤   ¤   IsWinNT4CompatibleMachine())
b15b34 ¤   ¤   {
de5c01 ¤   ¤   ¤   GetDiskFreeSpaceExAAddress = (GetDiskFreeSpaceExAType)·
b0959e ¤   ¤   ¤   ¤   GetProcAddress(Kernel32Handle, "GetDiskFreeSpaceExA");
--9933 000e13e7a5f40110165 Page 3 of LinkResolution.cpp
e0af5a
770061 ¤   ¤   ¤   GetDiskFreeSpaceExWAddress = (GetDiskFreeSpaceExWType)·
101a46 ¤   ¤   ¤   ¤   GetProcAddress(Kernel32Handle, "GetDiskFreeSpaceExW");
e7af5a
130e18 ¤   ¤   ¤   if (IsNull(BroadcastSystemMessageAddress) ||·
e1f42e ¤   ¤   ¤   ¤   IsNull(GetDiskFreeSpaceExAAddress) ||·
c894f4 ¤   ¤   ¤   ¤   IsNull(GetDiskFreeSpaceExWAddress))
c2f776 ¤   ¤   ¤   {
d37bcc ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetProcAddrFailed,·
923177 ¤   ¤   ¤   ¤   ¤   GetLastError());
5ba3a6 ¤   ¤   ¤   }
b80fe4 ¤   ¤   }
549371 ¤   }
83af5a
bd33e3 ¤   return derr;
63efe6 }
95af5a
c0eab6 // LinkNetworkingFunctions links in networking functions.
a4af5a
2b2292 DualErr·
c421a9 LinkNetworkingFunctions()
c0bb36 {
017d36 ¤   DualErr derr;
57af5a
ea2734 ¤   if (IsWin95CompatibleMachine())
fbc7a1 ¤   {
046a22 ¤   ¤   SvrApiHandle = LoadLibrary("SvrApi.dll");
44af5a
fb8cd7 ¤   ¤   if (IsNull(SvrApiHandle))
c4f8a1 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LoadLibraryFailed);
1aaf5a
c4aa35 ¤   ¤   if (derr.IsntError())
dd5b34 ¤   ¤   {
9bd353 ¤   ¤   ¤   Win95_NetShareGetInfoAddress = (Win95_NetShareGetInfoType)·
042175 ¤   ¤   ¤   ¤   GetProcAddress(SvrApiHandle, "NetShareGetInfo");
a987c7 ¤   ¤   ¤
1ed64a ¤   ¤   ¤   if (IsNull(Win95_NetShareGetInfoAddress))
05f776 ¤   ¤   ¤   {
407bcc ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetProcAddrFailed,·
833177 ¤   ¤   ¤   ¤   ¤   GetLastError());
99a3a6 ¤   ¤   ¤   }
a00fe4 ¤   ¤   }
7f9371 ¤   }
1b2804 ¤   else if (IsWinNT4CompatibleMachine())
f0c7a1 ¤   {
99322a ¤   ¤   NetApi32Handle = LoadLibrary("NetApi32.dll");
3caf5a
acca26 ¤   ¤   if (IsNull(NetApi32Handle))
e7f8a1 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LoadLibraryFailed);
fdaf5a
98aa35 ¤   ¤   if (derr.IsntError())
a35b34 ¤   ¤   {
92211f ¤   ¤   ¤   WinNT_NetShareGetInfoAddress = (WinNT_NetShareGetInfoType)·
e62e79 ¤   ¤   ¤   ¤   GetProcAddress(NetApi32Handle, "NetShareGetInfo");
47af5a
d43de8 ¤   ¤   ¤   WinNT_NetWkstaGetInfoAddress = (WinNT_NetWkstaGetInfoType)
6fedfe ¤   ¤   ¤   ¤   GetProcAddress(NetApi32Handle, "NetWkstaGetInfo");
82af5a
b9b060 ¤   ¤   ¤   WinNT_NetApiBufferFreeAddress = (WinNT_NetApiBufferFreeType)·
7b2949 ¤   ¤   ¤   ¤   GetProcAddress(NetApi32Handle, "NetApiBufferFree");
dcaf5a
49708e ¤   ¤   ¤   if (IsNull(WinNT_NetShareGetInfoAddress) ||·
223335 ¤   ¤   ¤   ¤   IsNull(WinNT_NetWkstaGetInfoAddress) ||·
8de7b9 ¤   ¤   ¤   ¤   IsNull(WinNT_NetApiBufferFreeAddress))
91f776 ¤   ¤   ¤   {
ef7bcc ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetProcAddrFailed,·
eb3177 ¤   ¤   ¤   ¤   ¤   GetLastError());
c3a3a6 ¤   ¤   ¤   }
a40fe4 ¤   ¤   }
f69371 ¤   }
1baf5a
e133e3 ¤   return derr;
--ec8e 000df8db37f40110165 Page 4 of LinkResolution.cpp
7aefe6 }
46af5a
f66fc6 // LinkServiceFunctions links in NT service functions.
b1af5a
d32292 DualErr·
8a9b2c LinkServiceFunctions()
b9bb36 {
527d36 ¤   DualErr derr;
6daf5a
6d9e1d ¤   if (IsWinNT4CompatibleMachine())
16c7a1 ¤   {
af917f ¤   ¤   Advapi32Handle = LoadLibrary("Advapi32.dll");
cfaf5a
198188 ¤   ¤   if (IsNull(Advapi32Handle))
5ef8a1 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_LoadLibraryFailed);
d7af5a
b6aa35 ¤   ¤   if (derr.IsntError())
775b34 ¤   ¤   {
0c3908 ¤   ¤   ¤   OpenSCManagerAAddress = (OpenSCManagerAType)·
39d8a3 ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "OpenSCManagerA");
f7af5a
24d0ee ¤   ¤   ¤   OpenSCManagerWAddress = (OpenSCManagerWType)·
f1577b ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "OpenSCManagerW");
ffaf5a
56f111 ¤   ¤   ¤   OpenServiceAAddress = (OpenServiceAType)·
7caafc ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "OpenServiceA");
69af5a
900ace ¤   ¤   ¤   OpenServiceWAddress = (OpenServiceWType)·
cb2524 ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "OpenServiceW");
f3af5a
950fce ¤   ¤   ¤   StartServiceAAddress = (StartServiceAType)·
6e044a ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "StartServiceA");
28af5a
bb3c0d ¤   ¤   ¤   StartServiceWAddress = (StartServiceWType)·
018b92 ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "StartServiceW");
5caf5a
d664ed ¤   ¤   ¤   ControlServiceAddress = (ControlServiceType)·
f11a65 ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "ControlService");
64af5a
d1f643 ¤   ¤   ¤   CloseServiceHandleAddress = (CloseServiceHandleType)·
6a48ed ¤   ¤   ¤   ¤   GetProcAddress(Advapi32Handle, "CloseServiceHandle");
90af5a
f366ca ¤   ¤   ¤   if (IsNull(OpenSCManagerAAddress) ||·
39e135 ¤   ¤   ¤   ¤   IsNull(OpenSCManagerWAddress) ||·
284ac6 ¤   ¤   ¤   ¤   IsNull(OpenServiceAAddress) ||·
dc927c ¤   ¤   ¤   ¤   IsNull(OpenServiceWAddress) ||·
e647b9 ¤   ¤   ¤   ¤   IsNull(StartServiceAAddress) ||·
de9f03 ¤   ¤   ¤   ¤   IsNull(StartServiceWAddress) ||·
f71a58 ¤   ¤   ¤   ¤   IsNull(ControlServiceAddress) ||·
f132b8 ¤   ¤   ¤   ¤   IsNull(CloseServiceHandleAddress))
0ff776 ¤   ¤   ¤   {
1b7bcc ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_GetProcAddrFailed,·
833177 ¤   ¤   ¤   ¤   ¤   GetLastError());
f4a3a6 ¤   ¤   ¤   }
300fe4 ¤   ¤   }
b39371 ¤   }
bbaf5a
a533e3 ¤   return derr;
ebefe6 }
33af5a
e46e62 // ExplicitlyLinkAPIsForPlatform loads and resolves needed API function
47f2aa // addresses for the version of Windows that we are using.
e9af5a
352292 DualErr·
b55cee ExplicitlyLinkAPIsForPlatform()
9ebb36 {
487d36 ¤   DualErr derr;
aeaf5a
d53703 ¤   pgpAssert(IsWin95CompatibleMachine() || IsWinNT4CompatibleMachine());
05af5a
ed2cea ¤   derr = LinkStandardWin32API();
dfaf5a
--bf80 00074aa992640110165 Page 5 of LinkResolution.cpp
752361 ¤   if (derr.IsntError())
cac7a1 ¤   {
59ea8d ¤   ¤   derr = LinkServiceFunctions();
329371 ¤   }
eeaf5a
f92361 ¤   if (derr.IsntError())
1ec7a1 ¤   {
596433 ¤   ¤   derr = LinkNetworkingFunctions();
5e9371 ¤   }
3eaf5a
274bb3 ¤   if (derr.IsError())
b9c7a1 ¤   {
562b2d ¤   ¤   CleanupExplicitLinkage();
569371 ¤   }
45af5a
1f33e3 ¤   return derr;
72efe6 }
c4af5a
c79680 // CleanupExplicitLinkage unloads all Dlls that have handles open.
d5af5a
fac823 void·
a3d081 CleanupExplicitLinkage()
aebb36 {
cd7529 ¤   if (IsntNull(SvrApiHandle))
607f75 ¤   ¤   FreeLibrary(SvrApiHandle);
4aaf5a
544670 ¤   if (IsntNull(NetApi32Handle))
34cf8b ¤   ¤   FreeLibrary(NetApi32Handle);
cdaf5a
640dde ¤   if (IsntNull(Advapi32Handle))
a58425 ¤   ¤   FreeLibrary(Advapi32Handle);
daaf5a
465d1f ¤   if (IsntNull(Kernel32Handle))
b4d4e4 ¤   ¤   FreeLibrary(Kernel32Handle);
4baf5a
ea165d ¤   if (IsntNull(User32Handle))
db1c01 ¤   ¤   FreeLibrary(User32Handle);
aaefe6 }
4baf5a
11af5a
ec90e1 //////////////////////////////////////
037bcc // Initialization and cleanup routines
1a90e1 //////////////////////////////////////
e1af5a
88f960 // Wrapper around BroadcastSystemMessage.
7daf5a
b81bd8 long·
9cf394 LinkSafe_BroadcastSystemMessage(
53ad57 ¤   DWORD¤  dwFlags,·
701654 ¤   LPDWORD¤lpdwRecipients,·
fb6c56 ¤   UINT¤   uiMessage,·
28a605 ¤   WPARAM¤ wParam,·
c39036 ¤   LPARAM¤ lParam)
6ebb36 {
de399a ¤   long result;
a5af5a
f253e9 ¤   pgpAssert(IsntNull(BroadcastSystemMessageAddress));
ccaf5a
c17872 ¤   result = BroadcastSystemMessageAddress(dwFlags, lpdwRecipients,·
51d659 ¤   ¤   uiMessage, wParam, lParam);
97af5a
3e9487 ¤   CLEANUP_WINAPI_STACK(20);
56af5a
565d73 ¤   return result;
33efe6 }
8baf5a
63af5a
05b6eb // Wrapper around GetDiskFreeSpaceExA for OSR2/NT4.
32af5a
ca7efe BOOL·
d3c635 LinkSafe_GetDiskFreeSpaceExA(
74e8ef ¤   LPCSTR¤ ¤   ¤   lpDirectoryName,·
--e35a 000208cc7c840110165 Page 6 of LinkResolution.cpp
53f032 ¤   PULARGE_INTEGER¤lpFreeBytesAvailableToCaller,·
da40e1 ¤   PULARGE_INTEGER¤lpTotalNumberOfBytes,·
a4b075 ¤   PULARGE_INTEGER¤lpTotalNumberOfFreeBytes)
d6bb36 {
e191e2 ¤   BOOL result;
4baf5a
0b2654 ¤   pgpAssert(IsntNull(GetDiskFreeSpaceExAAddress));
68af5a
416928 ¤   result = GetDiskFreeSpaceExAAddress(lpDirectoryName,·
b43ef3 ¤   ¤   lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes,·
037daf ¤   ¤   lpTotalNumberOfFreeBytes);
a0af5a
8dc2d1 ¤   CLEANUP_WINAPI_STACK(16);
4eaf5a
7c5d73 ¤   return result;
c8efe6 }
62af5a
282b30 // Wrapper around GetDiskFreeSpaceExW for OSR2/NT4.
79af5a
b17efe BOOL·
909579 LinkSafe_GetDiskFreeSpaceExW(
84257d ¤   LPCWSTR¤¤   ¤   lpDirectoryName,·
fef032 ¤   PULARGE_INTEGER¤lpFreeBytesAvailableToCaller,·
ec40e1 ¤   PULARGE_INTEGER¤lpTotalNumberOfBytes,·
3fb075 ¤   PULARGE_INTEGER¤lpTotalNumberOfFreeBytes)
0abb36 {
f491e2 ¤   BOOL result;
01af5a
133441 ¤   pgpAssert(IsntNull(GetDiskFreeSpaceExWAddress));
b2af5a
61805c ¤   result = GetDiskFreeSpaceExWAddress(lpDirectoryName,·
1f3ef3 ¤   ¤   lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes,·
a77daf ¤   ¤   lpTotalNumberOfFreeBytes);
a3af5a
b5c2d1 ¤   CLEANUP_WINAPI_STACK(16);
2caf5a
3e5d73 ¤   return result;
2fefe6 }
0baf5a
187970 // Wrapper around OpenSCManagerA for NT.
f4af5a
424995 SC_HANDLE·
87d970 LinkSafe_OpenSCManagerA(
59ab4e ¤   LPCSTR¤ lpMachineName,·
95a195 ¤   LPCSTR¤ lpDatabaseName,·
f69e67 ¤   DWORD¤  dwDesiredAccess)
62bb36 {
b317ef ¤   SC_HANDLE result;
11af5a
99ec9d ¤   pgpAssert(IsntNull(OpenSCManagerAAddress));
e5af5a
c04a32 ¤   result = OpenSCManagerAAddress(lpMachineName, lpDatabaseName,·
645465 ¤   ¤   dwDesiredAccess);
efaf5a
beb03d ¤   CLEANUP_WINAPI_STACK(12);
c7af5a
345d73 ¤   return result;
5aefe6 }
a5af5a
6043f0 // Wrapper around OpenSCManagerW for NT.
b4af5a
194995 SC_HANDLE·
658a3c LinkSafe_OpenSCManagerW(
06513f ¤   LPCWSTR¤lpMachineName,·
c6c361 ¤   LPCWSTR¤lpDatabaseName,·
4b9e67 ¤   DWORD¤  dwDesiredAccess)
6bbb36 {
b317ef ¤   SC_HANDLE result;
4aaf5a
2bfe88 ¤   pgpAssert(IsntNull(OpenSCManagerWAddress));
04af5a
20b11a ¤   result = OpenSCManagerWAddress(lpMachineName, lpDatabaseName,·
--b957 000f83386ef40110165 Page 7 of LinkResolution.cpp
df5465 ¤   ¤   dwDesiredAccess);
b9af5a
e9b03d ¤   CLEANUP_WINAPI_STACK(12);
e9af5a
055d73 ¤   return result;
7aefe6 }
5daf5a
2491c7 // Wrapper around OpenServiceA for NT.
09af5a
e74995 SC_HANDLE·
83d951 LinkSafe_OpenServiceA(
b59c01 ¤   SC_HANDLE¤  hSCManager,·
7b1c6f ¤   LPCSTR¤ ¤   lpServiceName,·
7f1890 ¤   DWORD¤  ¤   dwDesiredAccess)
63bb36 {
0917ef ¤   SC_HANDLE result;
3caf5a
a0c64e ¤   pgpAssert(IsntNull(OpenServiceAAddress));
79af5a
a13363 ¤   result = OpenServiceAAddress(hSCManager, lpServiceName, dwDesiredAccess);
d3af5a
f3b03d ¤   CLEANUP_WINAPI_STACK(12);
6faf5a
a55d73 ¤   return result;
a9efe6 }
b3af5a
e9ab47 // Wrapper around OpenServiceW for NT.
bbaf5a
094995 SC_HANDLE·
5f8a1d LinkSafe_OpenServiceW(
cc9c01 ¤   SC_HANDLE¤  hSCManager,·
31a5df ¤   LPCWSTR¤¤   lpServiceName,·
c91890 ¤   DWORD¤  ¤   dwDesiredAccess)
d0bb36 {
4b17ef ¤   SC_HANDLE result;
acaf5a
52d45b ¤   pgpAssert(IsntNull(OpenServiceWAddress));
b1af5a
78e161 ¤   result = OpenServiceWAddress(hSCManager, lpServiceName, dwDesiredAccess);
20af5a
44b03d ¤   CLEANUP_WINAPI_STACK(12);
2eaf5a
e25d73 ¤   return result;
b1efe6 }
89af5a
08211b // Wrapper around StartServiceA for NT.
7eaf5a
2f7efe BOOL·
7ed6da LinkSafe_StartServiceA(
414a35 ¤   SC_HANDLE¤  hService,·
cdecaf ¤   DWORD¤  ¤   dwNumServiceArgs,·
c926b0 ¤   LPCSTR¤ ¤   *lpServiceArgVectors)
abbb36 {
ef91e2 ¤   BOOL result;
e8af5a
fa20b9 ¤   pgpAssert(IsntNull(StartServiceAAddress));
0aaf5a
03f59a ¤   result = StartServiceAAddress(hService, dwNumServiceArgs,·
ee574a ¤   ¤   lpServiceArgVectors);
81af5a
86b03d ¤   CLEANUP_WINAPI_STACK(12);
b6af5a
ba5d73 ¤   return result;
71efe6 }
45af5a
881b9b // Wrapper around StartServiceW for NT.
c3af5a
917efe BOOL·
988596 LinkSafe_StartServiceW(
554a35 ¤   SC_HANDLE¤  hService,·
61ecaf ¤   DWORD¤  ¤   dwNumServiceArgs,·
f8eb22 ¤   LPCWSTR¤¤   *lpServiceArgVectors)
--e72c 0004facf04f40110165 Page 8 of LinkResolution.cpp
2cbb36 {
dc91e2 ¤   BOOL result;
68af5a
a632ac ¤   pgpAssert(IsntNull(StartServiceWAddress));
ffaf5a
0fef33 ¤   result = StartServiceWAddress(hService, dwNumServiceArgs,·
00574a ¤   ¤   lpServiceArgVectors);
9aaf5a
eeb03d ¤   CLEANUP_WINAPI_STACK(12);
06af5a
df5d73 ¤   return result;
13efe6 }
06af5a
da0b30 // Wrapper around ControlService for NT.
ddaf5a
2d7efe BOOL·
be3b4d LinkSafe_ControlService(
3f6b88 ¤   SC_HANDLE¤  ¤   ¤   hService,·
d831b5 ¤   DWORD¤  ¤   ¤   ¤   dwControl,·
1cd0da ¤   LPSERVICE_STATUS¤   lpServiceStatus)
00bb36 {
0191e2 ¤   BOOL result;
45af5a
abfa6e ¤   pgpAssert(IsntNull(ControlServiceAddress));
39af5a
50c7ea ¤   result = ControlServiceAddress(hService, dwControl, lpServiceStatus);
7eaf5a
9fb03d ¤   CLEANUP_WINAPI_STACK(12);
67af5a
3c5d73 ¤   return result;
18efe6 }
2caf5a
70787e // Wrapper around CloseServiceHandle for NT.
9caf5a
c47efe BOOL·
13b50f LinkSafe_CloseServiceHandle(SC_HANDLE hSCObject)
bfbb36 {
5791e2 ¤   BOOL result;
9baf5a
786740 ¤   pgpAssert(IsntNull(CloseServiceHandleAddress));
88af5a
4520f3 ¤   result = CloseServiceHandleAddress(hSCObject);
3faf5a
3ddaa0 ¤   CLEANUP_WINAPI_STACK(4);
05af5a
725d73 ¤   return result;
58efe6 }
3faf5a
3931f5 // Wrapper around NetShareGetInfo for NT4.
3eaf5a
a60e55 DWORD·
267c09 LinkSafe_WinNT_NetShareGetInfo(
ab289f ¤   LPWSTR¤ servername,·
9df199 ¤   LPWSTR¤ netname,·
c4bfa1 ¤   DWORD¤  level,·
9c0699 ¤   LPBYTE¤ *bufptr)
40bb36 {
dff7db ¤   DWORD result;
02af5a
e45bac ¤   pgpAssert(IsntNull(WinNT_NetShareGetInfoAddress));
ffaf5a
a989a6 ¤   result = WinNT_NetShareGetInfoAddress(servername, netname, level, bufptr);
2caf5a
a0c2d1 ¤   CLEANUP_WINAPI_STACK(16);
8faf5a
235d73 ¤   return result;
69efe6 }
0baf5a
31531f // Wrapper around NetShareGetInfo for Win95.
d6af5a
790e55 DWORD·
4f2be7 LinkSafe_Win95_NetShareGetInfo(
--d500 001e3f98d7f40110165 Page 9 of LinkResolution.cpp
41e020 ¤   const char FAR¤ ¤   *pszServer,·
4fb762 ¤   const char FAR¤ ¤   *pszNetName,·
487dad ¤   short¤  ¤   ¤   ¤   sLevel,·
cc2f15 ¤   char FAR¤   ¤   ¤   *pbBuffer,·
84c903 ¤   unsigned short¤ ¤   cbBuffer,·
7d253d ¤   unsigned short FAR¤ *pcbTotalAvail)
4cbb36 {
57f7db ¤   DWORD result;
47af5a
2ff773 ¤   pgpAssert(IsntNull(Win95_NetShareGetInfoAddress));
2aaf5a
31e865 ¤   result = Win95_NetShareGetInfoAddress(pszServer, pszNetName, sLevel,·
ceb8ce ¤   ¤   pbBuffer, cbBuffer, pcbTotalAvail);
18af5a
c7e66b ¤   CLEANUP_WINAPI_STACK(24);
93af5a
a95d73 ¤   return result;
bcefe6 }
73af5a
a3cf36 // Wrapper around NetWkstaGetInfo for WinNT
9eaf5a
010e55 DWORD·
49e779 LinkSafe_WinNT_NetWkstaGetInfo(LPWSTR servername, DWORD level, LPBYTE *bufptr)
f2bb36 {
27f7db ¤   DWORD result;
5caf5a
6511a7 ¤   pgpAssert(IsntNull(WinNT_NetWkstaGetInfoAddress));
bdaf5a
17fe88 ¤   result = WinNT_NetWkstaGetInfoAddress(servername, level, bufptr);
17af5a
54b03d ¤   CLEANUP_WINAPI_STACK(12);
b0af5a
a15d73 ¤   return result;
49efe6 }
edaf5a
e2e029 // Wrapper around NetApiBufferFree for NT4.
84af5a
0b0e55 DWORD·
00e5c2 LinkSafe_WinNT_NetApiBufferFree(LPVOID Buffer)
9dbb36 {
02f7db ¤   DWORD result;
c7af5a
fc4901 ¤   pgpAssert(IsntNull(WinNT_NetApiBufferFreeAddress));
fbaf5a
7a3fa3 ¤   result = WinNT_NetApiBufferFreeAddress(Buffer);
81af5a
33daa0 ¤   CLEANUP_WINAPI_STACK(4);
f4af5a
395d73 ¤   return result;
e3efe6 }
--16da 000c29c6ce040110166 Page 1 of LinkResolution.h
541bc3 //////////////////////////////////////////////////////////////////////////////
11a05e // LinkResolution.h
92465d //
1a69f5 // Contains declarations for Windows API functions we explicitly load.
ff1bc3 //////////////////////////////////////////////////////////////////////////////
f0af5a
170a09 // $Id: LinkResolution.h,v 1.1.2.8 1998/08/04 02:10:14 nryan Exp $
59af5a
4bcbce // Copyright (C) 1998 by Network Associates, Inc.
6b71ae // All rights reserved.
84af5a
ebd1eb #ifndef Included_LinkResolution_h¤  // [
c617c2 #define Included_LinkResolution_h
b4af5a
d93a85 #include "DualErr.h"
a6af5a
fbaf5a
dbd557 ////////
0302c9 // Types
f4d557 ////////
21af5a
5c8a4f #if defined(NOSERVICE)
32af5a
61f87e // From Winsvc.h.
75af5a
ea8074 typedef HANDLE SC_HANDLE;
d2af5a
448145 typedef struct _SERVICE_STATUS {
d771c0 ¤   DWORD¤  dwServiceType;
421b8e ¤   DWORD¤  dwCurrentState;
7731b8 ¤   DWORD¤  dwControlsAccepted;
2249da ¤   DWORD¤  dwWin32ExitCode;
9232af ¤   DWORD¤  dwServiceSpecificExitCode;
a20429 ¤   DWORD¤  dwCheckPoint;
3042a7 ¤   DWORD¤  dwWaitHint;
9faf5a
ce0bce } SERVICE_STATUS, *LPSERVICE_STATUS;
91af5a
e8b765 #endif¤ // NOSERVICE
7caf5a
38af5a
39d48e ////////////////////////
bbe467 // Function declarations
4ad48e ////////////////////////
75af5a
8f4d07 DualErr¤¤   ExplicitlyLinkAPIsForPlatform();
a2b9ea void¤   ¤   CleanupExplicitLinkage();
a5af5a
1cdd75 long¤   ¤   LinkSafe_BroadcastSystemMessage(DWORD dwFlags,·
ec7d44 ¤   ¤   ¤   ¤   LPDWORD lpdwRecipients, UINT uiMessage, WPARAM wParam,·
e229e9 ¤   ¤   ¤   ¤   LPARAM lParam);
b1af5a
910e6c BOOL¤   ¤   LinkSafe_GetDiskFreeSpaceExA(LPCSTR lpDirectoryName,·
5a51cf ¤   ¤   ¤   ¤   PULARGE_INTEGER lpFreeBytesAvailableToCaller,·
19bd01 ¤   ¤   ¤   ¤   PULARGE_INTEGER lpTotalNumberOfBytes,·
f6e37b ¤   ¤   ¤   ¤   PULARGE_INTEGER lpTotalNumberOfFreeBytes);
e0af5a
2a9980 BOOL¤   ¤   LinkSafe_GetDiskFreeSpaceExW(LPCWSTR lpDirectoryName,·
e151cf ¤   ¤   ¤   ¤   PULARGE_INTEGER lpFreeBytesAvailableToCaller,·
13bd01 ¤   ¤   ¤   ¤   PULARGE_INTEGER lpTotalNumberOfBytes,·
d2e37b ¤   ¤   ¤   ¤   PULARGE_INTEGER lpTotalNumberOfFreeBytes);
a9af5a
0e82b1 SC_HANDLE¤  LinkSafe_OpenSCManagerA(LPCSTR lpMachineName,·
581e72 ¤   ¤   ¤   ¤   LPCSTR lpDatabaseName, DWORD dwDesiredAccess);
4aaf5a
deadb5 SC_HANDLE¤  LinkSafe_OpenSCManagerW(LPCWSTR lpMachineName,·
6f11f8 ¤   ¤   ¤   ¤   LPCWSTR lpDatabaseName, DWORD dwDesiredAccess);
5daf5a
425f2a SC_HANDLE¤  LinkSafe_OpenServiceA(SC_HANDLE hSCManager,·
4253af ¤   ¤   ¤   ¤   LPCSTR lpServiceName, DWORD dwDesiredAccess);
ffaf5a
c20180 SC_HANDLE¤  LinkSafe_OpenServiceW(SC_HANDLE hSCManager,·
--ad5c 0017cbaebd940110166 Page 2 of LinkResolution.h
bda150 ¤   ¤   ¤   ¤   LPCWSTR lpServiceName, DWORD dwDesiredAccess);
88af5a
25950c BOOL¤   ¤   LinkSafe_StartServiceA(SC_HANDLE hService,·
8910e6 ¤   ¤   ¤   ¤   DWORD dwNumServiceArgs, LPCSTR *lpServiceArgVectors);
25af5a
c26591 BOOL¤   ¤   LinkSafe_StartServiceW(SC_HANDLE hService,·
27c7f0 ¤   ¤   ¤   ¤   DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors);
19af5a
ab86d0 BOOL¤   ¤   LinkSafe_ControlService(SC_HANDLE hService, DWORD dwControl,·
cede65 ¤   ¤   ¤   ¤   LPSERVICE_STATUS lpServiceStatus);
45af5a
547d40 BOOL¤   ¤   LinkSafe_CloseServiceHandle(SC_HANDLE hSCObject);
e1af5a
59d3ca DWORD¤  ¤   LinkSafe_WinNT_NetShareGetInfo(LPWSTR servername, LPWSTR netname,·
b32030 ¤   ¤   ¤   ¤   DWORD level, LPBYTE *bufptr);
d2af5a
d15d17 DWORD¤  ¤   LinkSafe_Win95_NetShareGetInfo(const char FAR *pszServer,·
a561b6 ¤   ¤   ¤   ¤   const char FAR *pszNetName, short sLevel, char FAR *pbBuffer,·
2a2a0f ¤   ¤   ¤   ¤   unsigned short cbBuffer, unsigned short FAR * pcbTotalAvail);
c5af5a
d99657 DWORD¤  ¤   LinkSafe_WinNT_NetWkstaGetInfo(LPWSTR servername, DWORD level,·
afb6b6 ¤   ¤   ¤   ¤   LPBYTE *bufptr);
a0af5a
0e2aac DWORD¤  ¤   LinkSafe_WinNT_NetApiBufferFree(LPVOID Buffer);
bcaf5a
42af5a
3620a9 ///////////////////
df2053 // Function defines
6120a9 ///////////////////
faaf5a
f22ccd #undef BroadcastSystemMessage
3239cb #undef GetDiskFreeSpaceEx
9a4e3e #undef OpenSCManager
714cf9 #undef OpenService
d94a59 #undef StartService
7eaf5a
c5f16b #if defined(UNICODE)
7aaf5a
ceefdc #define BroadcastSystemMessage¤ LinkSafe_BroadcastSystemMessage
98c310 #define¤GetDiskFreeSpaceEx¤ ¤   LinkSafe_GetDiskFreeSpaceExW
c9943e #define¤OpenSCManager¤  ¤   ¤   LinkSafe_OpenSCManagerW
a2ebb2 #define¤OpenService¤¤   ¤   ¤   LinkSafe_OpenServiceW
179ede #define¤StartService¤   ¤   ¤   LinkSafe_StartServiceW
67af5a
d3db21 #else
31af5a
c9efdc #define BroadcastSystemMessage¤ LinkSafe_BroadcastSystemMessage
c1a91d #define GetDiskFreeSpaceEx¤ ¤   LinkSafe_GetDiskFreeSpaceExA
ac557f #define¤OpenSCManager¤  ¤   ¤   LinkSafe_OpenSCManagerA
192af3 #define¤OpenService¤¤   ¤   ¤   LinkSafe_OpenServiceA
fd5f9f #define¤StartService¤   ¤   ¤   LinkSafe_StartServiceA
35af5a
ed133a #endif // UNICODE
adaf5a
930f51 #define WinNT_ControlService¤   ¤   LinkSafe_ControlService
1d88b5 #define WinNT_CloseServiceHandle¤   LinkSafe_CloseServiceHandle
59af5a
210d0c #define¤WinNT_NetShareGetInfo¤  LinkSafe_WinNT_NetShareGetInfo
51af1c #define¤Win95_NetShareGetInfo¤  LinkSafe_Win95_NetShareGetInfo
08588d #define¤WinNT_NetWkstaGetInfo¤  LinkSafe_WinNT_NetWkstaGetInfo
b030e2 #define¤WinNT_NetApiBufferFree¤ LinkSafe_WinNT_NetApiBufferFree
95af5a
7c37e7 #endif¤ // ] Included_LinkResolution_h
--48da 0000fef6e2140110167 Page 1 of PGPdiskContainer.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
50c73d // PGPdiskContainer.cpp
3a465d //
38c165 // Implementation of class PGPdiskContainer.
d51bc3 //////////////////////////////////////////////////////////////////////////////
63af5a
691073 // $Id: PGPdiskContainer.cpp,v 1.1.2.28 1998/08/04 02:10:14 nryan Exp $
9baf5a
f8cbce // Copyright (C) 1998 by Network Associates, Inc.
e971ae // All rights reserved.
0faf5a
d46931 #if defined(PGPDISK_MFC)
20af5a
089e12 #include "StdAfx.h"
0eaf5a
084268 #elif defined(PGPDISK_95DRIVER)
15af5a
f606a9 #include <vtoolscp.h>
2a86d2 #include LOCKED_CODE_SEGMENT
405269 #include LOCKED_DATA_SEGMENT
51af5a
26f5a6 #elif defined(PGPDISK_NTDRIVER)
f0af5a
80d7a1 #include <vdw.h>
e5af5a
8ddb21 #else
03112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
2e05d6 #endif¤ // PGPDISK_MFC
e2af5a
689bcf #include "Required.h"
0f5f98 #include "PGPdiskContainer.h"
357414 #include "PGPdiskHighLevelUtils.h"
6cbfe9 #include "UtilityFunctions.h"
25af5a
f168c6 #include "PGPdisk.h"
36af5a
da1b10 #if defined(PGPDISK_95DRIVER) || defined(PGPDISK_NTDRIVER)
e3c411 #include "Globals.h"
0fc29a #endif¤ // PGPDISK_95DRIVER || PGPDISK_NTDRIVER
8eaf5a
ebaf5a
9319ca /////////////////////////////////////////////////
afa936 // Class PGPdiskContainer public member functions
e519ca /////////////////////////////////////////////////
62af5a
303e66 // The PGPdiskContainer constructor.
fcaf5a
470478 PGPdiskContainer::PGPdiskContainer()
02bb36 {
8956d6 ¤   mNumPGPdisks = 0;
3caf5a
c1daae ¤   ClearContainer();
84efe6 }
53af5a
03e681 // GetSize returns the number of PGPdisks in the container.
3daf5a
9c1b0b PGPUInt32·
528d2e PGPdiskContainer::GetNumPGPdisks()
0cbb36 {
d99b95 ¤   return mNumPGPdisks;
31efe6 }
32af5a
a4130b // EnumPGPdisks returns the nth PGPdisk in the container.
8caf5a
661857 PGPdisk *·
9aadf0 PGPdiskContainer::EnumPGPdisks(PGPUInt32 n)
70bb36 {
7b7874 ¤   PGPBoolean¤ foundPGPdisk¤   = FALSE;
a970f5 ¤   PGPdisk¤¤   *pPGD;
cfc7a8 ¤   PGPUInt32¤  i¤  ¤   ¤   ¤   = 0;
ef9e1c ¤   PGPUInt32¤  j¤  ¤   ¤   ¤   = 0;
0faf5a
--17c1 000408b905840110167 Page 2 of PGPdiskContainer.cpp
f241f8 ¤   while (i < kMaxDrives)
afc7a1 ¤   {
1106f9 ¤   ¤   if (mPGPdiskArray[i])
015b34 ¤   ¤   {
edcad0 ¤   ¤   ¤   if (j++ == n)
8ef776 ¤   ¤   ¤   {
6d64a0 ¤   ¤   ¤   ¤   foundPGPdisk = TRUE;
4a1d76 ¤   ¤   ¤   ¤   pPGD = mPGPdiskArray[i];
d7f622 ¤   ¤   ¤   ¤   break;
6da3a6 ¤   ¤   ¤   }
c90fe4 ¤   ¤   }
91af5a
8a347d ¤   ¤   i++;
8f9371 ¤   }
d2af5a
fa2baf ¤   if (foundPGPdisk)
e8a023 ¤   ¤   return pPGD;
4f0e24 ¤   else
ad7ed2 ¤   ¤   return NULL;
e8efe6 }
4daf5a
515b57 // IsLocalDriveAPGPdiskHost returns TRUE if specified local drive hosts a
b5abb5 // PGPdisk, FALSE otherwise.
3baf5a
2977be PGPBoolean·
2f4ce8 PGPdiskContainer::IsLocalDriveAPGPdiskHost(PGPUInt8 drive)
ffbb36 {
c6aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
64af5a
03c3bf ¤   return (mLocalHosts[drive] > 0);
63efe6 }
e3af5a
46f742 // FindPGPdisk(PGPUInt8 drive) finds and returns the PGPdisk specified by
efee19 // 'drive'.
6baf5a
8d1857 PGPdisk *·
18c57e PGPdiskContainer::FindPGPdisk(PGPUInt8 drive)
55bb36 {
8baa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
cfaf5a
36e6e0 ¤   return mPGPdiskArray[drive];
e8efe6 }
85af5a
f5ac88 // FindPGPdisk(LPCSTR path) finds and returns the PGPdisk whose pathname is
30a754 // 'path'. Note how it compares the session Id, not the exact path.
ffaf5a
691857 PGPdisk *·
c3c0a6 PGPdiskContainer::FindPGPdisk(LPCSTR path)
03bb36 {
1870f5 ¤   PGPdisk¤¤   *pPGD;
5ec303 ¤   PGPUInt32¤  i¤  = 0;
b0bfa0 ¤   PGPUInt64¤  sessionId;
4caf5a
c7639f ¤   pgpAssertStrValid(path);
a4af5a
f73731 ¤   sessionId = GetPGPdiskUniqueSessionId(path);
8aaf5a
65c014 ¤   pPGD = EnumPGPdisks(i);
22af5a
079c02 ¤   while (IsntNull(pPGD))
67c7a1 ¤   {
c2a222 ¤   ¤   if ((pPGD->GetUniqueSessionId() == sessionId) &&·
7b5b2a ¤   ¤   ¤   pPGD->BestGuessComparePaths(path))
b75b34 ¤   ¤   {
9ecdcb ¤   ¤   ¤   break;
ef0fe4 ¤   ¤   }
76af5a
aec7d3 ¤   ¤   pPGD = EnumPGPdisks(i++);
b79371 ¤   }
6eaf5a
45e1a8 ¤   return pPGD;
40efe6 }
--4189 000278e32c740110167 Page 3 of PGPdiskContainer.cpp
e0af5a
28b687 #if defined(PGPDISK_95DRIVER)
eaaf5a
344a8c // FindPGPdisk(PDCB pDcb) finds and returns the PGPdisk whose DCB is 'pDcb'.
18af5a
2b1857 PGPdisk *·
c52bd8 PGPdiskContainer::FindPGPdisk(PDCB pDcb)
e9bb36 {
67c303 ¤   PGPUInt32¤  i¤  = 0;
1a70f5 ¤   PGPdisk¤¤   *pPGD;
b7af5a
89d339 ¤   pgpAssertAddrValid(pDcb);
f8af5a
669186 ¤   while (pPGD = EnumPGPdisks(i++))
90c7a1 ¤   {
4329ad ¤   ¤   if (pPGD->GetDcb() == pDcb)
9dcdcb ¤   ¤   ¤   break;
199371 ¤   }
f0af5a
f8e1a8 ¤   return pPGD;
8befe6 }
25af5a
6542fd // FlipAllContexts tells each PGPdisk in the container to flip the bits on
cf4b4c // each of its contexts.
e6af5a
0fc823 void·
69b743 PGPdiskContainer::FlipAllContexts()
9bbb36 {
04c303 ¤   PGPUInt32¤  i¤  = 0;
b470f5 ¤   PGPdisk¤¤   *pPGD;
65af5a
2c9186 ¤   while (pPGD = EnumPGPdisks(i++))
d1c7a1 ¤   {
6c18e9 ¤   ¤   pPGD->FlipContexts();
8c9371 ¤   }
b8efe6 }
e4af5a
6c3608 // ValidateAllCipherContexts tells each PGPdisk in the container to verify
df2e95 // that its cipher contexts are not damaged.
ccaf5a
a8c823 void·
509d18 PGPdiskContainer::ValidateAllCipherContexts()
f2bb36 {
48be41 ¤   DualErr¤¤   derr;
4fc303 ¤   PGPUInt32¤  i¤  = 0;
de70f5 ¤   PGPdisk¤¤   *pPGD;
86af5a
5a9186 ¤   while (pPGD = EnumPGPdisks(i++))
e6c7a1 ¤   {
cff3b2 ¤   ¤   derr = pPGD->ValidateContexts();
0caf5a
c2bdd6 ¤   ¤   if (derr.IsError())
2f5b34 ¤   ¤   {
5e8019 ¤   ¤   ¤   DualErr derr;
acaf5a
d04a38 ¤   ¤   ¤   PGPUInt8 drive = pPGD->GetDrive();
67af5a
01607a ¤   ¤   ¤   // Emergency unmount NOW.
8bbd14 ¤   ¤   ¤   derr = Driver->UnmountPGPdisk(drive, TRUE);
fcaf5a
ba9d3d ¤   ¤   ¤   if (derr.IsntError())
fcf776 ¤   ¤   ¤   {
971c4b ¤   ¤   ¤   ¤   Driver->ReportError(kPGDMajorError_InvalidCipherContext,·
a2cf9a ¤   ¤   ¤   ¤   ¤   DualErr::NoError, drive);
4ba3a6 ¤   ¤   ¤   }
f30fe4 ¤   ¤   }
d59371 ¤   }
a7efe6 }
65af5a
0bf5a6 #elif defined(PGPDISK_NTDRIVER)
6eaf5a
2742fd // FlipAllContexts tells each PGPdisk in the container to flip the bits on
--8e70 000f3d19bb940110167 Page 4 of PGPdiskContainer.cpp
714b4c // each of its contexts.
d7af5a
c0c823 void·
3bb743 PGPdiskContainer::FlipAllContexts()
ccbb36 {
45c303 ¤   PGPUInt32¤  i¤  = 0;
2570f5 ¤   PGPdisk¤¤   *pPGD;
0caf5a
d49186 ¤   while (pPGD = EnumPGPdisks(i++))
8fc7a1 ¤   {
f118e9 ¤   ¤   pPGD->FlipContexts();
209371 ¤   }
f4efe6 }
82af5a
ac3608 // ValidateAllCipherContexts tells each PGPdisk in the container to verify
fd2e95 // that its cipher contexts are not damaged.
fbaf5a
e6c823 void·
ef9d18 PGPdiskContainer::ValidateAllCipherContexts()
0abb36 {
d7be41 ¤   DualErr¤¤   derr;
75c303 ¤   PGPUInt32¤  i¤  = 0;
3970f5 ¤   PGPdisk¤¤   *pPGD;
43af5a
a19186 ¤   while (pPGD = EnumPGPdisks(i++))
f6c7a1 ¤   {
9ef3b2 ¤   ¤   derr = pPGD->ValidateContexts();
0baf5a
16bdd6 ¤   ¤   if (derr.IsError())
c85b34 ¤   ¤   {
838019 ¤   ¤   ¤   DualErr derr;
98af5a
f54a38 ¤   ¤   ¤   PGPUInt8 drive = pPGD->GetDrive();
4daf5a
7e607a ¤   ¤   ¤   // Emergency unmount NOW.
a42833 ¤   ¤   ¤   derr = Interface->UnmountPGPdisk(drive, TRUE);
85af5a
919d3d ¤   ¤   ¤   if (derr.IsntError())
86f776 ¤   ¤   ¤   {
f38bcd ¤   ¤   ¤   ¤   Interface->ReportError(kPGDMajorError_InvalidCipherContext,·
4acf9a ¤   ¤   ¤   ¤   ¤   DualErr::NoError, drive);
70a3a6 ¤   ¤   ¤   }
9f0fe4 ¤   ¤   }
af9371 ¤   }
a9efe6 }
a7af5a
5538f5 #endif¤ // ] PGPDISK_95DRIVER
3baf5a
b79337 // AddPGPdisk adds a mounted PGPdisk to the container.
ddaf5a
aec823 void·
9dc6ec PGPdiskContainer::AddPGPdisk(PGPdisk *pPGD)
a3bb36 {
61b2bc ¤   PGPUInt8 drive;
caaf5a
105b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
d898d2 ¤   pgpAssert(pPGD->Mounted());
b8af5a
c1a1f7 ¤   drive = pPGD->GetDrive();
abaf5a
beaa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
afda0a ¤   pgpAssert(IsNull(mPGPdiskArray[drive]));
6eaf5a
6dfe55 ¤   mPGPdiskArray[drive] = pPGD;
c9e5f2 ¤   mNumPGPdisks++;
aeaf5a
75bee4 ¤   if (!pPGD->IsHostNetworked())
4c6d1d ¤   ¤   mLocalHosts[pPGD->GetLocalHostDrive()]++;
7befe6 }
f4af5a
3b86fe // RemovePGPdisk looks for the passed PGPdisk pointer in the container and
f370fe // removes it if it was found.
--ba59 001c4ffc4ec40110167 Page 5 of PGPdiskContainer.cpp
e0af5a
20c823 void·
91365c PGPdiskContainer::RemovePGPdisk(PGPdisk *pPGD)
4bbb36 {
82b2bc ¤   PGPUInt8 drive;
abaf5a
245b87 ¤   pgpAssertAddrValid(pPGD, PGPdisk);
6f98d2 ¤   pgpAssert(pPGD->Mounted());
20af5a
25a1f7 ¤   drive = pPGD->GetDrive();
73aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
5553e4 ¤   pgpAssert(IsntNull(mPGPdiskArray[drive]));
a1af5a
5c20a4 ¤   mPGPdiskArray[drive] = NULL;
bb78b1 ¤   mNumPGPdisks--;
e4af5a
46bee4 ¤   if (!pPGD->IsHostNetworked())
01f05e ¤   ¤   mLocalHosts[pPGD->GetLocalHostDrive()]--;
42efe6 }
1faf5a
1693ae // ClearContainer purges all the PGPdisks from the container.
7faf5a
5dc823 void·
6dce68 PGPdiskContainer::ClearContainer()
52bb36 {
d12e07 ¤   for (PGPUInt32 i=0; i<kMaxDrives; i++)
2dc7a1 ¤   {
e8da4e ¤   ¤   mLocalHosts[i] = 0;
a7ba20 ¤   ¤   mPGPdiskArray[i] = NULL;
e89371 ¤   }
40af5a
1956d6 ¤   mNumPGPdisks = 0;
f3efe6 }
cbaf5a
f5fedb // ClearContainerWithDelete purges all the PGPdisks from the container and
021406 // deletes the objects.
42af5a
65c823 void·
194a0b PGPdiskContainer::ClearContainerWithDelete()
95bb36 {
7a2e07 ¤   for (PGPUInt32 i=0; i<kMaxDrives; i++)
27c7a1 ¤   {
dcda4e ¤   ¤   mLocalHosts[i] = 0;
29af5a
90e773 ¤   ¤   if (IsntNull(mPGPdiskArray[i]))
a75b34 ¤   ¤   {
5801df ¤   ¤   ¤   pgpAssertAddrValid(mPGPdiskArray[i], PGPdisk);
41af5a
368a50 ¤   ¤   ¤   delete mPGPdiskArray[i];
8b8748 ¤   ¤   ¤   mPGPdiskArray[i] = NULL;
ee0fe4 ¤   ¤   }
149371 ¤   }
dcaf5a
ea56d6 ¤   mNumPGPdisks = 0;
c4efe6 }
--6016 001dabc7c8740110168 Page 1 of PGPdiskContainer.h
541bc3 //////////////////////////////////////////////////////////////////////////////
8420bd // PGPdiskContainer.h
af465d //
24c72d // Declaration of class PGPdiskContainer.
4f1bc3 //////////////////////////////////////////////////////////////////////////////
22af5a
a02f9e // $Id: PGPdiskContainer.h,v 1.1.2.17 1998/08/04 02:10:15 nryan Exp $
a1af5a
08cbce // Copyright (C) 1998 by Network Associates, Inc.
6371ae // All rights reserved.
3caf5a
581085 #ifndef Included_PGPdiskContainer_h¤// [
a695c7 #define Included_PGPdiskContainer_h
28af5a
443a85 #include "DualErr.h"
e4af5a
64af5a
f3d557 ////////
3902c9 // Types
f6d557 ////////
62af5a
9c9e57 class PGPdisk;
d5af5a
7eaf5a
629f73 /////////////////////////
6bc1b8 // Class PGPdiskContainer
f79f73 /////////////////////////
a8af5a
8b73d5 // Class PGPdiskContainer objects serve as containers for mounted PGPdisks.
cd2997 // You can attach a PGPdisk by pointer and detach it, as well as search the
71906f // list of PGPdisks for one matching a specific mounted drive number or path.
9b6cff // This class is thread-safe.
89af5a
85bb86 class PGPdiskContainer
a9bb36 {
4b5ed4 public:
fcd312 ¤   ¤   ¤   ¤   PGPdiskContainer();
faa0e5 ¤   ¤   ¤   ¤   ~PGPdiskContainer() { };
5faf5a
6d7f26 ¤   PGPUInt32¤  GetNumPGPdisks();
8f3a25 ¤   PGPdisk¤*¤  EnumPGPdisks(PGPUInt32 n);
9aaf5a
82718a ¤   PGPBoolean¤ IsLocalDriveAPGPdiskHost(PGPUInt8 drive);
e1af5a
6f0292 ¤   PGPdisk *¤  FindPGPdisk(PGPUInt8 drive);
a02b35 ¤   PGPdisk *¤  FindPGPdisk(LPCSTR path);
c3af5a
4db687 #if defined(PGPDISK_95DRIVER)
13667d ¤   PGPdisk *¤  FindPGPdisk(PDCB pDcb);
37a147 #endif¤ // PGPDISK_95DRIVER
1baf5a
4f1b10 #if defined(PGPDISK_95DRIVER) || defined(PGPDISK_NTDRIVER)
e7af5a
1612c1 ¤   void¤   ¤   FlipAllContexts();
97a057 ¤   void¤   ¤   ValidateAllCipherContexts();
91af5a
3ac29a #endif¤ // PGPDISK_95DRIVER || PGPDISK_NTDRIVER
cdaf5a
f3bcaa ¤   void¤   ¤   AddPGPdisk(PGPdisk *pPGD);
f08b5a ¤   void¤   ¤   RemovePGPdisk(PGPdisk *pPGD);
8daf5a
5f28d1 ¤   void¤   ¤   ClearContainer();
207654 ¤   void¤   ¤   ClearContainerWithDelete();
28af5a
9c0fb9 private:
449ab0 ¤   PGPdisk¤¤   *mPGPdiskArray[kMaxDrives];¤// cross-ref drives&PGPdisks
2da437 ¤   PGPUInt32¤  mNumPGPdisks;¤  ¤   ¤   ¤   // population of the array
d1af5a
dfe384 ¤   PGPUInt32¤  mLocalHosts[kMaxDrives];¤   // local vol host PGPdisk?
9182f7 };
44af5a
dae94e #endif¤ // ] Included_PGPdiskContainer_h
--9446 000e9678b4f40110169 Page 1 of PGPdiskDefaults.h
541bc3 //////////////////////////////////////////////////////////////////////////////
035f60 // PGPdiskDefaults.h
eb465d //
4da382 // Default values for new PGPdisks.
851bc3 //////////////////////////////////////////////////////////////////////////////
c6af5a
a3a5a1 // $Id: PGPdiskDefaults.h,v 1.2.2.22 1998/08/04 02:10:16 nryan Exp $
93af5a
28cbce // Copyright (C) 1998 by Network Associates, Inc.
6871ae // All rights reserved.
54af5a
ced043 #ifndef Included_PGPdiskDefaults_h¤ // [
4c9dc8 #define Included_PGPdiskDefaults_h
aaaf5a
52af5a
095270 ////////////////////////////
3214cf // PGPdisk default constants
db5270 ////////////////////////////
68af5a
878ed5 #if PGPDISK_BETAVERSION
3faf5a
d27297 // Beta timeout constants
ecaf5a
04729f const PGPUInt16¤kPGPdiskBetaTimeoutYear¤¤   = 1998;
5329f1 const PGPUInt16¤kPGPdiskBetaTimeoutMonth¤   = 9;¤   ¤   // June
3e5e56 const PGPUInt16¤kPGPdiskBetaTimeoutDay¤ ¤   = 15;
3baf5a
925766 #elif PGPDISK_DEMOVERSION
ffaf5a
a4d647 // Demo timeout constants.
0aede3 const PGPUInt16 kDemoTimeoutDays = 60;
c0af5a
34e121 #endif // PGPDISK_BETAVERSION
f6af5a
347ceb // Max number of apps.
1d039a const PGPUInt32 kMaxPGPdiskApps = 32;
65af5a
2ac552 // Make PGPdisk custom Windows messages unique.
f6d26e const PGPUInt16 kPGPdiskMessageMagic = 0xAB42;
93af5a
dc4784 // Names.
74af5a
d26552 static LPCSTR¤  kPGPdiskAppName¤¤   = "PGPdisk";
8a0cfb static LPCSTR¤  kPGPdiskDriverName¤ = "\\\\.\\PGPdisk";
c26b46 static LPCSTR¤  kPGPdiskServiceName¤= "PGPdisk";
aeaf5a
bfe912 // File and volume defaults for new PGPdisks.
73af5a
b97206 static LPCSTR¤  kPGPdiskFileExtension¤  = ".pgd";
7ba0ac static LPCSTR¤  kDefaultNewDiskName¤¤   = "New PGPdisk%s.pgd";
a040ee static LPCSTR¤  kPGPdiskDefaultVolLabel¤= "NEW PGPDISK";
03af5a
637dc3 const PGPUInt32¤kPGPdiskMinKbSizeWin95¤ = 100;
00566f const PGPUInt32¤kPGPdiskMaxKbSizeWin95¤ = 2047*kKbPerMeg;
3b5206 const PGPUInt32¤kPGPdiskMinKbSizeWinNT¤ = 100;
1e42fb const PGPUInt32¤kPGPdiskMaxKbSizeWinNT¤ = 1024*kKbPerGig;
5fb8dd const PGPUInt32¤kDefaultPGPdiskMbSize¤  = 100;
eeaf5a
ac1786 // Default FAT values for new PGPdisks
a0af5a
83416e static LPCSTR¤  kDefaultOEMName¤¤   = "PGPDISK ";
027b49 static LPCSTR¤  kDefaultVolLabel¤   = "UNNAMED ···";
f6af5a
d35663 const PGPUInt16¤kDefaultBlockSize¤  ¤   = 512;
575eee const PGPUInt8¤ kDefaultActiveFat¤  ¤   = 1;
244a08 const PGPUInt8¤ kDefaultFatCount¤   ¤   = 2;
6b8547 const PGPUInt32¤kDefaultFat12Reserved¤  = 1;
5ec57b const PGPUInt32¤kDefaultFat16Reserved¤  = 1;
58bdf5 const PGPUInt32¤kDefaultFat32Reserved¤  = 32;
2ee95e const PGPUInt16¤kDefaultRootDirEnts¤¤   = 512;
95657e const PGPUInt32¤kDefaultRootDirStart¤   = 2;
e9ae3f const PGPUInt32¤kDefaultBigFatStart¤¤   = 1;
--6dda 0013f2743cf40110169 Page 2 of PGPdiskDefaults.h
e0af5a
79727c // Passphrase specific constants.
c2af5a
c4feb9 const PGPUInt32¤kMaxPassphraseLength¤   = 130;
e0c8fd const PGPUInt32¤kMinPassphraseLength¤   = 8;
d0af5a
51aac2 // Default values for preferences.
68af5a
acfb01 const PGPBoolean¤   kDefaultAutoUnmount¤¤   ¤   ¤   = FALSE;
700f26 const PGPBoolean¤   kDefaultHotKeyEnabled¤  ¤   ¤   = FALSE;
261f02 const PGPBoolean¤   kDefaultUseAsyncIO¤ ¤   ¤   ¤   = TRUE;
d0bbeb const PGPUInt32¤¤   kDefaultHotKeyCode¤ ¤   ¤   ¤   = 0;
52a759 const PGPBoolean¤   kDefaultUnmountOnSleep¤ ¤   ¤   = FALSE;
8fadbc const PGPBoolean¤   kDefaultNoSleepIfUnmountFail¤   = FALSE;
582f95 const PGPUInt32¤¤   kDefaultUnmountTimeout¤ ¤   ¤   = 15;
ef368c const PGPUInt32¤¤   kMaxUnmountTimeout¤ ¤   ¤   ¤   = 999;
17af5a
fada52 // Miscellaneous.
9daf5a
febe70 const PGPUInt32 kMaxCheckOpenFilesAttempts = 10;
bbaf5a
3feb47 #endif¤ // ] Included_PGPdiskDefaults_h
--ca91 000fd23af5c4011016a Page 1 of PGPdiskFileFormat.h
541bc3 //////////////////////////////////////////////////////////////////////////////
da8088 // PGPdiskFileFormat.h
3a465d //
a06724 // The file format of PGPdisks.
5a1bc3 //////////////////////////////////////////////////////////////////////////////
afaf5a
c5d00d // $Id: PGPdiskFileFormat.h,v 1.1.2.15.2.3 1998/10/22 00:41:50 nryan Exp $
02af5a
bdcbce // Copyright (C) 1998 by Network Associates, Inc.
dd71ae // All rights reserved.
80af5a
edebc1 #ifndef¤Included_PGPdiskFileFormat_h¤   // [
2ebb46 #define¤Included_PGPdiskFileFormat_h
50af5a
e8ea4b #if PGPDISK_PUBLIC_KEY
7ae82c #include "pgpPubTypes.h"
f938e4 #endif¤ // PGPDISK_PUBLIC_KEY
3caf5a
5a3db7 #include "FatUtils.h"
95af5a
8d69ea #include "Cast5.h"
fb8f51 #include "CipherUtils.h"
a9af5a
f5e79f // Align to 1.
c7fcdb #pragma pack(push, 1)
5baf5a
3009b7 ////////////
4de738 // Constants
e209b7 ////////////
08af5a
895e33 static LPCSTR¤  kPGPdiskHeaderMagic¤¤   ¤   = "PGPd";
58412f static LPCSTR¤  kPGPdiskPrimaryHeaderType¤  = "MAIN";
abaf5a
b4f642 static LPCSTR¤  kPGPdiskBadCASTInfoMagic¤   = "BADC";
b4af5a
1f6a5f const PGPUInt16¤kPGPdiskPrimaryHeaderMajorVersion ¤ = 4;
bf489d const PGPUInt16¤kPGPdiskPrimaryHeaderMinorVersion ¤ = 0;
30af5a
624d90 const PGPUInt16 kPGPdiskBadCASTMaxHeaderMajorVersion = 2;
349095 const PGPUInt16 kPGPdiskConvertInProgressMajorVersion = 3;
dcaf5a
7d873f const PGPUInt32¤kPGPdiskReservedHeaderBlocks¤   = 12;
1b7383 const PGPUInt32¤kPGPdiskAlternateHeaderBlocks¤  = 1;
e185f3 const PGPUInt32¤kPGPdiskAlternateHeaderSize¤¤   = ·
55dc1b ¤   kPGPdiskAlternateHeaderBlocks * kDefaultBlockSize;
c7af5a
87323a const PGPUInt16¤kMasterPassphraseIndex¤ ¤   = 0;
3a6b63 const PGPUInt16¤kMaxAlternatePassphrases¤   = 7;
1daf5a
77c279 const PGPUInt64 kInvalidSessionId = 0xFFFFFFFFFFFFFFFF;
ecaf5a
f5af5a
39d557 ////////
0402c9 // Types
37d557 ////////
d0af5a
36dec2 // PGPdiskEncryptionAlgorithm describes valid and invalid encryption
2124e7 // algorithms for PGPdisks.
5aaf5a
ec9724 enum PGPdiskEncryptionAlgorithm
acbb36 {
6c96b2 ¤   kInvalidEncryptionAlgorithm¤¤   = 0,·
9c8193 ¤   kCopyDataEncryptionAlgorithm¤   = 1,·
a5f397 ¤   kBrokenCASTEncryptionAlgorithm¤ = 2,·
48fb61 ¤   kCASTEncryptionAlgorithm¤   ¤   = 3,·
f6af5a
8c20ad ¤   kDefaultEncryptionAlgorithm¤¤   = kCASTEncryptionAlgorithm,·
0f38a9 ¤   kDummyEncryptionAlgorithm ¤ ¤   = ULONG_MAX¤¤   // force size to 4 bytes
95af5a
6f82f7 };
e4af5a
fd7bd1 // PGPdiskFileHeaderInfo stores info about the structure of a PGPdisk's
--08ef 0004fa90e4b4011016a Page 2 of PGPdiskFileFormat.h
ec799e // header.
49af5a
ea87ad typedef struct PGPdiskFileHeaderInfo
2fbb36 {
ea0acf ¤   char¤   ¤   headerMagic[4];¤¤   // Magic field. Always kPGPdiskHeaderMagic
8f05ea ¤   char¤   ¤   headerType[4];¤ ¤   // kPGPdiskPrimaryHeaderType + ???
f20019 ¤   PGPUInt32¤  headerSize;¤¤   ¤   // Total size of this header, in bytes
e6adb5 ¤   CRC32¤  ¤   headerCRC;¤ ¤   ¤   // CRC of this header
ccc062 ¤   PGPUInt64¤  nextHeaderOffset;¤  // Offset to next header from file start
690a0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // 0 = no additional headers
b46c23 ¤   PGPUInt32¤  reserved[2];
43af5a
5c88cc } PGPdiskFileHeaderInfo;
baaf5a
23ac79 // CheckBytes contains data that lets us verify a passphrase is valid.
31af5a
21cdae typedef struct CheckBytes
bbbb36 {
b0d5cc ¤   PGPUInt8 theBytes[8];
3baf5a
c53b0a } CheckBytes;
87af5a
c97fc5 // PassphraseKey contains the encrypted key for the PGPdisk.
9caf5a
7e2e97 typedef struct PassphraseKey
97bb36 {
b3fb01 ¤   EncryptedCASTKey¤   encryptedKey;¤  // session encrypted with salted pass
f44e92 ¤   CheckBytes¤ ¤   ¤   checkBytes;¤¤   // first 8b of enc-hash-salt user key
16a6ba ¤   PGPUInt16¤  ¤   ¤   hashReps;¤  ¤   // # of hashes on passphrase
cc3a12 ¤   PGPUInt16¤  ¤   ¤   inUse¤  ¤   : 1;
78a213 ¤   PGPUInt16¤  ¤   ¤   readOnly¤   : 1;
6bce65 ¤   PGPUInt16¤  ¤   ¤   unused¤ ¤   : 14;
dacbed ¤   PGPUInt32¤  ¤   ¤   unusedLong;
8aaf5a
ea3be9 } PassphraseKey;
8baf5a
5fadf3 // A PGPdiskFileHeader describes the attributes of a PGPdisk.
26af5a
168acf typedef struct PGPdiskFileHeader
b2bb36 {
a10f54 ¤   PGPdiskFileHeaderInfo¤  ¤   headerInfo;
06af5a
fefae8 ¤   PGPUInt8¤   majorVersion;
bbd2f6 ¤   PGPUInt8¤   minorVersion;
e571f5 ¤   PGPUInt16¤  reserved;
d3af5a
a78b33 ¤   PGPUInt32¤  numFileBlocks;¤ ¤   ¤   // Size of the file, in blocks
46fcf1 ¤   PGPUInt32¤  numHeaderBlocks;¤   ¤   // Size of header data
b7a505 ¤   PGPUInt32¤  numDataBlocks;¤ ¤   ¤   // Size of the encrypted data
11af5a
5d5b57 ¤   PGPdiskEncryptionAlgorithm algorithm;¤  // encryption method (4 bytes)
acaf5a
c3cd35 ¤   PGPUInt8¤   drive;¤ ¤   ¤   ¤   ¤   // preferred drive letter
654fe1 ¤   PGPBoolean¤ mountedFlag;¤   ¤   ¤   // set while disk is mounted
b50c25 ¤   PGPUInt64¤  uniqueSessionId;¤   ¤   // random session ID
3befa6 ¤   PGPUInt8¤   reservedBytes[54];¤ ¤   // reserved for future use
45af5a
83ebbd ¤   PassphraseSalt¤ salt;¤  ¤   ¤   ¤   // salt for passphrase and IVs
c29072 ¤   PassphraseKey¤  masterPassphrase;
1f55ae ¤   PassphraseKey¤  otherPassphrases[kMaxAlternatePassphrases];
52af5a
e17c3b } PGPdiskFileHeader;
d3af5a
acea4b #if PGPDISK_PUBLIC_KEY
e5af5a
1fdd83 static LPCSTR¤  kPGPdiskPublicKeyHeaderType¤¤   ¤   = "PKEY";
6bedaa const PGPUInt16¤kPGPdiskPublicKeyHeaderMajorVersion¤= 1;
f31f6c const PGPUInt16¤kPGPdiskPublicKeyHeaderMinorVersion¤= 0;
93af5a
5de82f // A PGPdiskPublicKeyHeader describes a public-key-encrypted session key.
e2af5a
4f20d7 typedef struct PGPdiskPublicKeyHeader
--2e1f 001b6b6755e4011016a Page 3 of PGPdiskFileFormat.h
2cbb36 {
b9f0cd ¤   PGPdiskFileHeaderInfo¤  headerInfo;
2167c5 ¤
950dce ¤   PGPUInt8¤   ¤   ¤   ¤   majorVersion;
c925d0 ¤   PGPUInt8¤   ¤   ¤   ¤   minorVersion;
c3a7cb ¤   PGPUInt16¤  ¤   ¤   ¤   reserved;
ecaf5a
b38694 ¤   PGPUInt32¤  ¤   ¤   ¤   readOnly ¤  : 1;
b06316 ¤   PGPUInt32¤  ¤   ¤   ¤   locked ¤¤   : 1;
4d8db9 ¤   PGPUInt32¤  ¤   ¤   ¤   unused¤ ¤   : 30;
c467c5 ¤
f2efd5 ¤   CheckBytes¤ ¤   ¤   ¤   checkBytes;
2267c5 ¤
6f8fb0 ¤   PGPUInt32¤  ¤   ¤   ¤   keyIDOffset;
e1cad3 ¤   PGPUInt32¤  ¤   ¤   ¤   keyIDSize;
fa67c5 ¤
1897a1 ¤   PGPUInt32¤  ¤   ¤   ¤   encryptedKeyOffset;
41ef65 ¤   PGPUInt32¤  ¤   ¤   ¤   encryptedKeySize;
c167c5 ¤
5bea37 ¤   PGPPublicKeyAlgorithm¤  algorithm;
3367c5 ¤
760c78 ¤   PGPUInt32¤  ¤   ¤   ¤   reserved2[10];
ceaf5a
df0172 ¤   // Exported key ID here
4b2c71 ¤   // Encrypted key here.
5c67c5 ¤
7260e8 } PGPdiskPublicKeyHeader;
ccaf5a
484a2b // PGPdiskCASTConvertInfo is placed at the end of the first sector and keeps
81d13b // track of the conversion of a PGPdisk with bad CAST.
61af5a
d3feeb typedef struct PGPdiskCASTConvertInfo
16bb36 {
217126 ¤   char¤   ¤   ¤   convertInfoMagic[4];¤   // kPGPdiskBadCASTInfoMagic
a3af5a
c14b79 ¤   PGPUInt32¤  ¤   lastConvertedBlock;¤¤   // index of last converted block
cbf743 ¤   CASTKey¤¤   ¤   oldSessionKey;¤ ¤   ¤   // the old session key
8b4d47 ¤   PassphraseSalt¤ oldSalt;¤   ¤   ¤   ¤   // the old salt
59af5a
1f9bd9 } PGPdiskCASTConvertInfo;
10af5a
7138e4 #endif¤ // PGPDISK_PUBLIC_KEY
1daf5a
d41cb1 // Restore alignment.
e6f421 #pragma pack(pop)
7baf5a
23af5a
94ca3a ////////////////////
8fe785 // Utility functions
e2ca3a ////////////////////
21af5a
7eea4b #if PGPDISK_PUBLIC_KEY
08af5a
9be19e // IsPublicKeyHeader returns TRUE if the given header is a public key header,·
949a91 // FALSE otherwise.
ebaf5a
d5c85e inline·
4577be PGPBoolean·
0d77c3 IsPublicKeyHeader(PGPdiskFileHeaderInfo *hdrInfo)
71bb36 {
12f7f6 ¤   pgpAssertAddrValid(hdrInfo, PGPdiskFileHeaderInfo);
46af5a
d066a1 ¤   return (strncmp(hdrInfo->headerType, kPGPdiskPublicKeyHeaderType, 4) ==·
bafa39 ¤   ¤   0);
d7efe6 }
dbaf5a
e238e4 #endif¤ // PGPDISK_PUBLIC_KEY
68af5a
b6d9af #endif¤ // ] Included_PGPdiskFileFormat_h
--3059 000967440204011016b Page 1 of PGPdiskHighLevelUtils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
15f2c6 // PGPdiskHighLevelUtils.cpp
df465d //
a1aba1 // High-level utility functions for working with PGPdisks.
0b1bc3 //////////////////////////////////////////////////////////////////////////////
caaf5a
6d5e4b // $Id: PGPdiskHighLevelUtils.cpp,v 1.1.2.26.2.3 1998/10/22 22:28:01 nryan Exp $
9aaf5a
c5cbce // Copyright (C) 1998 by Network Associates, Inc.
1671ae // All rights reserved.
d8af5a
4b6931 #if defined(PGPDISK_MFC)
0eaf5a
239e12 #include "StdAfx.h"
f9b8af #include <new.h>
7faf5a
3d4268 #elif defined(PGPDISK_95DRIVER)
f4af5a
e206a9 #include <vtoolscp.h>
843a08 #include "PlacementNew.h"
8186d2 #include LOCKED_CODE_SEGMENT
9c5269 #include LOCKED_DATA_SEGMENT
d6af5a
31f5a6 #elif defined(PGPDISK_NTDRIVER)
e1af5a
4ed7a1 #include <vdw.h>
aaaf5a
1ddb21 #else
2f112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
e405d6 #endif¤ // PGPDISK_MFC
64af5a
779bcf #include "Required.h"
f27414 #include "PGPdiskHighLevelUtils.h"
192229 #include "PGPdiskLowLevelUtils.h"
2faf5a
43ea4b #if PGPDISK_PUBLIC_KEY
b4af5a
beb2b1 #include "PGPclx.h"
bce8b2 #include "pflPrefs.h"
cd4720 #include "pflPrefTypes.h"
e53991 #include "pgpAdminPrefs.h"
3c2f8d #include "pgpErrors.h"
6f42aa #include "pgpPublicKey.h"
5b4919 #include "pgpUtilities.h"
a5af5a
d4f4f6 #include "PGPdiskPublicKeyUtils.h"
6faf5a
ec38e4 #endif¤ // PGPDISK_PUBLIC_KEY
39af5a
8370d4 #include "SecureMemory.h"
4fbfe9 #include "UtilityFunctions.h"
76af5a
f0f037 #include "File.h"
d6af5a
79af5a
6c90e1 //////////////////////////////////////
53a9a3 // High-level header utility functions
4490e1 //////////////////////////////////////
e9af5a
5a4650 // ReadPGPdiskFileMainHeader(File *diskFile... ) reads in the main header
c4cf96 // from the opened PGPdisk.
4aaf5a
4ae677 DualErr
4fa82f ReadPGPdiskFileMainHeader(File *diskFile, PGPdiskFileHeader **fileHeader)
20bb36 {
65945d ¤   DualErr¤derr;
d1af5a
4f9137 ¤   pgpAssertAddrValid(diskFile, File);
cc1071 ¤   pgpAssert(diskFile->Opened());
5c7e20 ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader *);
2caf5a
969b81 ¤   // Assert rigid file format assumptions.
--5431 0003b207e0a4011016b Page 2 of PGPdiskHighLevelUtils.cpp
8fac86 ¤   pgpAssert(sizeof(PGPdiskFileHeader) == 380);
66afeb ¤   pgpAssert(sizeof(PGPdiskFileHeader)%4 == 0);
a2eff7 ¤   pgpAssert(sizeof(PGPdiskEncryptionAlgorithm) == 4);
1146fb ¤   pgpAssertMsg(kDefaultBlockSize == 512, "kDefaultBlockSize must be 512");
7b07df ¤   pgpAssertMsg(kPGPdiskAlternateHeaderSize == 512, "Cannot change the "·
d32cd9 ¤   ¤   "alternate header size and expect to read old files correctly");
2a383f ¤   pgpAssert(sizeof(PassphraseSalt) == 8);
a1ff2c ¤   pgpAssert(sizeof(EncryptedCASTKey) == 16);
70af5a
b78187 ¤   derr = ReadPGPdiskFilePrimaryHeader(diskFile, fileHeader);
87af5a
074bb3 ¤   if (derr.IsError())
fec7a1 ¤   {
738e38 ¤   ¤   DualErr savedDerr = derr;
4eaf5a
e86b9c ¤   ¤   derr = ReadPGPdiskFileAlternateHeader(diskFile, fileHeader);
9caf5a
c4fbe1 ¤   ¤   // Success on alternate wipes out first error, else report the
fc6aa5 ¤   ¤   // first error and not the second error.
f9af5a
a0aa35 ¤   ¤   if (derr.IsntError())
755b34 ¤   ¤   {
6ca3ec ¤   ¤   ¤   derr = DualErr::NoError;
100fe4 ¤   ¤   }
4f0e1d ¤   ¤   else
775b34 ¤   ¤   {
8c9385 ¤   ¤   ¤   derr = savedDerr;
5c0fe4 ¤   ¤   }
3c9371 ¤   }
6faf5a
e333e3 ¤   return derr;
74efe6 }
b1af5a
36ceb9 // ReadPGPdiskFileMainHeader(LPCSTR path... ) is a wrapper function.
16af5a
70e677 DualErr
a24a2b ReadPGPdiskFileMainHeader(LPCSTR path, PGPdiskFileHeader **fileHeader)
d4bb36 {
b4945d ¤   DualErr¤derr;
147cd6 ¤   File¤   diskFile;
6eaf5a
e5639f ¤   pgpAssertStrValid(path);
1d7e20 ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader *);
deaf5a
418be9 ¤   derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
a3af5a
d52361 ¤   if (derr.IsntError())
d3c7a1 ¤   {
efa903 ¤   ¤   derr = ReadPGPdiskFileMainHeader(&diskFile, fileHeader);
c49371 ¤   }
80af5a
a5d27f ¤   if (diskFile.Opened())
c3d016 ¤   ¤   diskFile.Close();
35af5a
7f33e3 ¤   return derr;
c5efe6 }
a4af5a
339d18 // WritePGPdiskFileMainHeader(File *diskFile... ) writes the main PGPdisk
15f217 // file header.
82af5a
7ee677 DualErr
be8ad1 WritePGPdiskFileMainHeader(
bf7082 ¤   File¤   ¤   ¤   ¤   ¤   *diskFile,·
b03852 ¤   const PGPdiskFileHeader¤*fileHeader)
6dbb36 {
d67d36 ¤   DualErr derr;
9767c5 ¤
f79137 ¤   pgpAssertAddrValid(diskFile, File);
131071 ¤   pgpAssert(diskFile->Opened());
b6e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
68af5a
3b9e26 ¤   derr = WritePGPdiskFilePrimaryHeader(diskFile, fileHeader);
--4773 000b67727cd4011016b Page 3 of PGPdiskHighLevelUtils.cpp
e0af5a
6a2361 ¤   if (derr.IsntError())
cbc7a1 ¤   {
a8aaab ¤   ¤   derr = WritePGPdiskFileAlternateHeader(diskFile, fileHeader);
959371 ¤   }
bc1b52 ¤   ¤
8433e3 ¤   return derr;
f2efe6 }
19af5a
b5a81f // WritePGPdiskFileMainHeader(LPCSTR path... ) is a wrapper function.
aeaf5a
57e677 DualErr
811d5e WritePGPdiskFileMainHeader(LPCSTR path, const PGPdiskFileHeader *fileHeader)
3fbb36 {
14945d ¤   DualErr¤derr;
4c7cd6 ¤   File¤   diskFile;
1faf5a
d8639f ¤   pgpAssertStrValid(path);
f8e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
25af5a
3d8dae ¤   derr = diskFile.Open(path, kOF_MustExist);
36af5a
ed2361 ¤   if (derr.IsntError())
96c7a1 ¤   {
08f5c9 ¤   ¤   derr = WritePGPdiskFileMainHeader(&diskFile, fileHeader);
1c9371 ¤   }
bdaf5a
f4d27f ¤   if (diskFile.Opened())
a4d016 ¤   ¤   diskFile.Close();
2baf5a
2933e3 ¤   return derr;
9cefe6 }
ccaf5a
0e77d8 // ValidatePGPdisk checks if the file specified by 'path' is a valid PGPdisk.
d2af5a
e12292 DualErr·
5cbc72 ValidatePGPdisk(LPCSTR path)
eebb36 {
84705b ¤   DualErr¤¤   ¤   ¤   derr;
f2e1a0 ¤   File¤   ¤   ¤   ¤   diskFile;
33d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
c28fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
5f2726 ¤   PGPUInt64¤  ¤   ¤   bytesFile;
0f67c5 ¤
3b639f ¤   pgpAssertStrValid(path);
ad67c5 ¤
e2b1fe ¤   // Open the file.
fa8be9 ¤   derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
73af5a
7daba6 ¤   // Get the file's length.
992361 ¤   if (derr.IsntError())
70c7a1 ¤   {
0c6f34 ¤   ¤   derr = diskFile.GetLength(&bytesFile);
f19371 ¤   }
e0af5a
e1b380 ¤   // Close the file.
1ed27f ¤   if (diskFile.Opened())
2cc7a1 ¤   {
03d016 ¤   ¤   diskFile.Close();
8f9371 ¤   }
86af5a
ffe2ee ¤   // Read in the header.
ae2361 ¤   if (derr.IsntError())
88c7a1 ¤   {
b592bd ¤   ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
29e17d ¤   ¤   readHeader = derr.IsntError();
c59371 ¤   }
ddaf5a
48109d ¤   // Verify the header.
5a2361 ¤   if (derr.IsntError())
50c7a1 ¤   {
b64131 ¤   ¤   derr = VerifyPGPdiskFileMainHeader(fileHeader, bytesFile);
--1f92 0005b637e504011016b Page 4 of PGPdiskHighLevelUtils.cpp
a19371 ¤   }
93af5a
26fd0b ¤   if (readHeader)
9f3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
19af5a
0d33e3 ¤   return derr;
b5efe6 }
9aaf5a
d8af5a
a81c7a //////////////////////////////////////////
d0e6c6 // High-level passphrase utility functions
971c7a //////////////////////////////////////////
8caf5a
7c49b6 // HowManyAlternatePassphrases returns the number of alternate passphrases in
2b1e01 // use on the specified PGPdisk.
f0af5a
942292 DualErr·
59c2a9 HowManyAlternatePassphrases(LPCSTR path, PGPUInt32 *numAlts)
75bb36 {
45705b ¤   DualErr¤¤   ¤   ¤   derr;
afd957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
388fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
9367c5 ¤
14639f ¤   pgpAssertStrValid(path);
d2604b ¤   pgpAssertAddrValid(numAlts, PGPUInt32);
d7af5a
bbe2ee ¤   // Read in the header.
25b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
b0a08e ¤   readHeader = derr.IsntError();
7faf5a
8056d1 ¤   // Calculate number of alternate passphrases in use.
702361 ¤   if (derr.IsntError())
c7c7a1 ¤   {
fbd98b ¤   ¤   (* numAlts) = 0;
2faf5a
a7703c ¤   ¤   for (PGPUInt32 i=0; i < kMaxAlternatePassphrases; i++)
465b34 ¤   ¤   {
516a24 ¤   ¤   ¤   if (fileHeader->otherPassphrases[i].inUse)
5a40e6 ¤   ¤   ¤   ¤   (* numAlts)++;
af0fe4 ¤   ¤   }
009371 ¤   }
9daf5a
1efd0b ¤   if (readHeader)
413fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
cfaf5a
3133e3 ¤   return derr;
1eefe6 }
17af5a
a45d12 // VerifyNormalPassphrase verifies a non-public-key passphrase.
ecaf5a
b7e677 DualErr
5fb37f VerifyNormalPassphrase(LPCSTR path, SecureString *passphrase)
7bbb36 {
2a705b ¤   DualErr¤¤   ¤   ¤   derr;
b0d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
738fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
04af5a
a5639f ¤   pgpAssertStrValid(path);
2fc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
5aaf5a
3db408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
cea08e ¤   readHeader = derr.IsntError();
ccaf5a
4e353a ¤   // Check normal keys.
c12361 ¤   if (derr.IsntError())
c4c7a1 ¤   {
22374e ¤   ¤   PGPUInt16 index;
6aaf5a
bbc097 ¤   ¤   derr = FindMatchingPassphrase(fileHeader, passphrase, &index);
2c9371 ¤   }
45af5a
5bfd0b ¤   if (readHeader)
--90f6 00058d2d84d4011016b Page 5 of PGPdiskHighLevelUtils.cpp
003fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
aeaf5a
f133e3 ¤   return derr;
4befe6 }
61af5a
98ea4b #if PGPDISK_PUBLIC_KEY
41af5a
bdcfb7 // VerifyPublicKeyPassphrase verifies that a passphrase is a public key
45b3c3 // passphrase for a public key on the PGPdisk.
66af5a
bee677 DualErr
df054f VerifyPublicKeyPassphrase(LPCSTR path, SecureString *passphrase)
0fbb36 {
96705b ¤   DualErr¤¤   ¤   ¤   derr;
51d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
278fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
1faf5a
9e639f ¤   pgpAssertStrValid(path);
7bc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
ceaf5a
a9b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
60a08e ¤   readHeader = derr.IsntError();
b8af5a
2dd1f9 ¤   // Check public keys.
5d2361 ¤   if (derr.IsntError())
1cc7a1 ¤   {
4433d4 ¤   ¤   PGPdiskPublicKeyHeader *pubKeyHdr;
e6af5a
d13b8f ¤   ¤   derr = FindPublicPGPdiskKeyHeader(path, passphrase, &pubKeyHdr);
b5af5a
faaa35 ¤   ¤   if (derr.IsntError())
813898 ¤   ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) pubKeyHdr);
ca9371 ¤   }
d3af5a
86fd0b ¤   if (readHeader)
7b3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
30af5a
4633e3 ¤   return derr;
27efe6 }
1caf5a
5738e4 #endif¤ // PGPDISK_PUBLIC_KEY
ceaf5a
119b79 // VerifyPassphrase verifies that a passphrase is a master or an alternate
8864cb // passphrase for the specified PGPdisk.
98af5a
4ce677 DualErr
a3884b VerifyPassphrase(LPCSTR path, SecureString *passphrase)
f0bb36 {
247d36 ¤   DualErr derr;
66af5a
c0639f ¤   pgpAssertStrValid(path);
2dc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
c4af5a
68353a ¤   // Check normal keys.
452361 ¤   if (derr.IsntError())
6cc7a1 ¤   {
d825ed ¤   ¤   derr = VerifyNormalPassphrase(path, passphrase);
6b9371 ¤   }
62af5a
f3ea4b #if PGPDISK_PUBLIC_KEY
a5af5a
f7d1f9 ¤   // Check public keys.
eb4bb3 ¤   if (derr.IsError())
6cc7a1 ¤   {
6c4cab ¤   ¤   derr = VerifyPublicKeyPassphrase(path, passphrase);
b79371 ¤   }
a9af5a
b238e4 #endif¤ // PGPDISK_PUBLIC_KEY
58af5a
6e33e3 ¤   return derr;
baefe6 }
58af5a
--8917 00084e287e24011016b Page 6 of PGPdiskHighLevelUtils.cpp
2aa023 // VerifyMasterPassphrase verifies that a passphrase is the master passphrase
61b9aa // for the specified PGPdisk.
5aaf5a
d5e677 DualErr
39bd41 VerifyMasterPassphrase(LPCSTR path, SecureString *passphrase)
72bb36 {
72705b ¤   DualErr¤¤   ¤   ¤   derr;
aad957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
238fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
c1af5a
d6639f ¤   pgpAssertStrValid(path);
7ac1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
1767c5 ¤
97b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
2fa08e ¤   readHeader = derr.IsntError();
9eaf5a
392361 ¤   if (derr.IsntError())
04c7a1 ¤   {
4fce15 ¤   ¤   derr = VerifyFileHeaderPassphrase(fileHeader, passphrase,·
0980b8 ¤   ¤   ¤   kMasterPassphraseIndex);
5d9371 ¤   }
c1af5a
75fd0b ¤   if (readHeader)
743fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
95af5a
ee33e3 ¤   return derr;
1defe6 }
0daf5a
7fc4cb // InternalAddPassphrase is a helper function for AddPassphrase.
26af5a
f5e677 DualErr
6c7921 InternalAddPassphrase(
c88d79 ¤   PGPdiskFileHeader¤  *fileHeader,·
4c5b18 ¤   SecureString¤   ¤   *masterPassphrase,·
f5a41b ¤   SecureString¤   ¤   *newPassphrase,·
280601 ¤   PassphraseKey¤  ¤   *userInfo,·
a195e7 ¤   PGPBoolean¤ ¤   ¤   readOnly)
f0bb36 {
54fe11 ¤   CASTKey¤¤   *decryptedKey;
bebe41 ¤   DualErr¤¤   derr;
f8af5a
d1ad5f ¤   SecureMemory¤   smDecryptedKey(sizeof(CASTKey));
0daf5a
f0c13e ¤   // Did we get our locked memory?
7277cd ¤   derr = smDecryptedKey.mInitErr;
31af5a
ce2361 ¤   if (derr.IsntError())
4dc7a1 ¤   {
c4c398 ¤   ¤   // Set the locked memory pointer.
17ec55 ¤   ¤   decryptedKey = (CASTKey *) smDecryptedKey.GetPtr();
aaaf5a
533f06 ¤   ¤   userInfo->inUse = TRUE;
698262 ¤   ¤   userInfo->readOnly = readOnly;
49af5a
5204b3 ¤   ¤   // Decrypt the master key
9f6f26 ¤   ¤   derr = DecryptPassphraseKey(&fileHeader->masterPassphrase,·
3f55a1 ¤   ¤   ¤   &fileHeader->salt, masterPassphrase, decryptedKey);
a79371 ¤   }
43af5a
8b2361 ¤   if (derr.IsntError())
bcc7a1 ¤   {
b1a262 ¤   ¤   // Encrypt the decrypted key again using the user's passphrase.
24d5f2 ¤   ¤   derr = EncryptPassphraseKey(decryptedKey, &fileHeader->salt,·
333829 ¤   ¤   ¤   newPassphrase, userInfo);
659371 ¤   }
adaf5a
2e33e3 ¤   return derr;
c0efe6 }
dbaf5a
fc99e6 // AddPassphrase adds a new alternate passphrase to the specified PGPdisk.
c0af5a
84e677 DualErr
--20c2 0005d1803194011016b Page 7 of PGPdiskHighLevelUtils.cpp
2dc94f AddPassphrase(
2f20cd ¤   LPCSTR¤ ¤   ¤   path,·
d04995 ¤   SecureString¤   *masterPassphrase,·
02dd9e ¤   SecureString¤   *newPassphrase,·
4d2973 ¤   PGPBoolean¤ ¤   readOnly)
dfbb36 {
21705b ¤   DualErr¤¤   ¤   ¤   derr;
330459 ¤   PGPBoolean¤ ¤   ¤   didAdd, readHeader;
928fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
2a2a7b ¤   PGPUInt16¤  ¤   ¤   index;
d8af5a
3d098b ¤   didAdd = readHeader = FALSE;
08af5a
c7639f ¤   pgpAssertStrValid(path);
a3da2a ¤   pgpAssertAddrValid(masterPassphrase, SecureString);
b85ec2 ¤   pgpAssertAddrValid(newPassphrase, SecureString);
0eaf5a
af1e42 ¤   pgpAssert(VerifyMasterPassphrase(path, masterPassphrase).IsntError());
16affb ¤   pgpAssert(VerifyNormalPassphrase(path, newPassphrase).IsError());
e4af5a
42f4be ¤   // Read in file header.
e1b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
cea08e ¤   readHeader = derr.IsntError();
22af5a
9f67b9 ¤   // Find a place to put the new passphrase and put it there.
b52361 ¤   if (derr.IsntError())
c0c7a1 ¤   {
588efe ¤   ¤   for (index = 1; index <= kMaxAlternatePassphrases; index++)
265b34 ¤   ¤   {
3ec9a8 ¤   ¤   ¤   PassphraseKey *userInfo;
76af5a
2abe2d ¤   ¤   ¤   userInfo = (PassphraseKey *) GetPassphraseKeyPtr(fileHeader,·
425e83 ¤   ¤   ¤   ¤   index);
78af5a
171d98 ¤   ¤   ¤   // We found a spot
bdfc9d ¤   ¤   ¤   if (!userInfo->inUse)
a9f776 ¤   ¤   ¤   {
3bcdcb ¤   ¤   ¤   ¤   derr = InternalAddPassphrase(fileHeader, masterPassphrase,·
06bbae ¤   ¤   ¤   ¤   ¤   newPassphrase, userInfo, readOnly);
c2af5a
86b8bd ¤   ¤   ¤   ¤   didAdd = derr.IsntError();
daf622 ¤   ¤   ¤   ¤   break;
41a3a6 ¤   ¤   ¤   }
8c0fe4 ¤   ¤   }
2d9371 ¤   }
76af5a
442361 ¤   if (derr.IsntError())
39c7a1 ¤   {
fc47ac ¤   ¤   if (!didAdd)
5636a4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_AllAlternatesTaken);
8b9371 ¤   }
6caf5a
9adf4a ¤   // Write out the new header
bf2361 ¤   if (derr.IsntError())
c1c7a1 ¤   {
a90897 ¤   ¤   derr = WritePGPdiskFileMainHeader(path, fileHeader);
aa9371 ¤   }
f5af5a
d7fd0b ¤   if (readHeader)
523fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
5eaf5a
6633e3 ¤   return derr;
c3efe6 }
37af5a
ac69a0 // InternalChangePassphrase is a helper function for ChangePassphrase.
aeaf5a
b4e677 DualErr
6eae92 InternalChangePassphrase(
272341 ¤   PassphraseKey¤  ¤   ¤   *userInfo,·
563d12 ¤   const PassphraseSalt¤   *salt,·
523945 ¤   SecureString¤   ¤   ¤   *oldPassphrase,·
5d1be0 ¤   SecureString¤   ¤   ¤   *newPassphrase)
--97e0 000f8584f924011016b Page 8 of PGPdiskHighLevelUtils.cpp
2cbb36 {
828b7a ¤   CASTKey¤*decryptedKey;
b4945d ¤   DualErr¤derr;
ddaf5a
33ad5f ¤   SecureMemory¤   smDecryptedKey(sizeof(CASTKey));
7daf5a
57b05f ¤   pgpAssertAddrValid(userInfo, PassphraseKey);
abf904 ¤   pgpAssertAddrValid(salt, PassphraseSalt);
42ade0 ¤   pgpAssertAddrValid(oldPassphrase, SecureString);
025ec2 ¤   pgpAssertAddrValid(newPassphrase, SecureString);
afaf5a
0e32c1 ¤   pgpAssert(VerifyPassphraseKey(userInfo, salt, oldPassphrase).IsntError());
56af5a
06c13e ¤   // Did we get our locked memory?
6277cd ¤   derr = smDecryptedKey.mInitErr;
f9af5a
dd2361 ¤   if (derr.IsntError())
14c7a1 ¤   {
a4c398 ¤   ¤   // Set the locked memory pointer.
9fec55 ¤   ¤   decryptedKey = (CASTKey *) smDecryptedKey.GetPtr();
32af5a
b64a6e ¤   ¤   // Decrypt the key
d08f6c ¤   ¤   derr = DecryptPassphraseKey(userInfo, salt, oldPassphrase,·
2fb2da ¤   ¤   ¤   decryptedKey);
109371 ¤   }
82af5a
492361 ¤   if (derr.IsntError())
79c7a1 ¤   {
4ba262 ¤   ¤   // Encrypt the decrypted key again using the user's passphrase.
4ad19c ¤   ¤   derr = EncryptPassphraseKey(decryptedKey, salt, newPassphrase,·
68bd30 ¤   ¤   ¤   userInfo);
8f9371 ¤   }
d9af5a
5433e3 ¤   return derr;
89efe6 }
e3af5a
6406bc // ChangePassphrase changes an existing passphrase on the specified PGPdisk.
55af5a
d0e677 DualErr
9281aa ChangePassphrase(
5d20cd ¤   LPCSTR¤ ¤   ¤   path,·
261f3f ¤   SecureString¤   *oldPassphrase,·
6a5bb7 ¤   SecureString¤   *newPassphrase)
d3bb36 {
ff705b ¤   DualErr¤¤   ¤   ¤   derr;
aed957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
568fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
c02a7b ¤   PGPUInt16¤  ¤   ¤   index;
46af5a
f8639f ¤   pgpAssertStrValid(path);
69ade0 ¤   pgpAssertAddrValid(oldPassphrase, SecureString);
015ec2 ¤   pgpAssertAddrValid(newPassphrase, SecureString);
b1af5a
c8f4be ¤   // Read in file header.
bfb408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
3fa08e ¤   readHeader = derr.IsntError();
a4af5a
93f4d9 ¤   // Find the index of this passphrase
8b2361 ¤   if (derr.IsntError())
91c7a1 ¤   {
897faf ¤   ¤   derr = FindMatchingPassphrase(fileHeader, oldPassphrase, &index);
339371 ¤   }
15af5a
ca3784 ¤   // Change the passphrase
462361 ¤   if (derr.IsntError())
6dc7a1 ¤   {
7cf4c0 ¤   ¤   PassphraseKey *userInfo;
01af5a
ae800a ¤   ¤   userInfo = (PassphraseKey *) GetPassphraseKeyPtr(fileHeader, index);
caaf5a
333304 ¤   ¤   derr = InternalChangePassphrase(userInfo, &fileHeader->salt,·
f8eb9f ¤   ¤   ¤   oldPassphrase, newPassphrase);
--1d96 000dc3c1e644011016b Page 9 of PGPdiskHighLevelUtils.cpp
a19371 ¤   }
93af5a
7b8063 ¤   // Set the modified header
e12361 ¤   if (derr.IsntError())
45c7a1 ¤   {
d60897 ¤   ¤   derr = WritePGPdiskFileMainHeader(path, fileHeader);
289371 ¤   }
37af5a
32fd0b ¤   if (readHeader)
073fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
4eaf5a
ca33e3 ¤   return derr;
7aefe6 }
15af5a
68d14c // RemovePassphrase removes an alternate passphrase from the specified
0c41a0 // PGPdisk.
9aaf5a
4ce677 DualErr
00a988 RemovePassphrase(LPCSTR path, SecureString *passphrase)
15bb36 {
02705b ¤   DualErr¤¤   ¤   ¤   derr;
215cc6 ¤   PGPBoolean¤ ¤   ¤   didRemove, readHeader;
c78fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
96af5a
f6e5dd ¤   didRemove = readHeader = FALSE;
f1af5a
7d639f ¤   pgpAssertStrValid(path);
bcc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
22af5a
7be2ee ¤   // Read in the header.
3eb408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
76a08e ¤   readHeader = derr.IsntError();
4eaf5a
8e5762 ¤   // Remove the passphrase if we can find it.
a42361 ¤   if (derr.IsntError())
adc7a1 ¤   {
b69a0b ¤   ¤   for (PGPUInt16 index = 1; index <= kMaxAlternatePassphrases; ++index)
345b34 ¤   ¤   {
28c9a8 ¤   ¤   ¤   PassphraseKey *userInfo;
58af5a
fa2eaf ¤   ¤   ¤   userInfo = (PassphraseKey *)·
d51d60 ¤   ¤   ¤   ¤   GetPassphraseKeyPtr(fileHeader, index);
5faf5a
9bb760 ¤   ¤   ¤   // Is this passphrase in use?
d4c0a1 ¤   ¤   ¤   if (userInfo->inUse)
03f776 ¤   ¤   ¤   {
1ea918 ¤   ¤   ¤   ¤   DualErr passMatches;
6aaf5a
5d4830 ¤   ¤   ¤   ¤   passMatches = VerifyPassphraseKey(userInfo,·
0da702 ¤   ¤   ¤   ¤   ¤   &fileHeader->salt, passphrase);
26af5a
ce0066 ¤   ¤   ¤   ¤   // Does it match the passphrase we wish to remove?
b5a9a5 ¤   ¤   ¤   ¤   if (passMatches.IsntError())
8c72c3 ¤   ¤   ¤   ¤   {
f57552 ¤   ¤   ¤   ¤   ¤   // Update the fileheader.
714ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
694859 ¤   ¤   ¤   ¤   ¤   {
b27be1 ¤   ¤   ¤   ¤   ¤   ¤   pgpClearMemory(userInfo, sizeof(PassphraseKey));
8c2a80 ¤   ¤   ¤   ¤   ¤   ¤   userInfo->inUse¤= FALSE;
61af5a
75c257 ¤   ¤   ¤   ¤   ¤   ¤   derr = WritePGPdiskFileMainHeader(path, fileHeader);
af2b1a ¤   ¤   ¤   ¤   ¤   ¤   didRemove = derr.IsntError();
f900eb ¤   ¤   ¤   ¤   ¤   ¤   break;
3c1c89 ¤   ¤   ¤   ¤   ¤   }
302613 ¤   ¤   ¤   ¤   }
94a3a6 ¤   ¤   ¤   }
e60fe4 ¤   ¤   }
139371 ¤   }
c0af5a
032361 ¤   if (derr.IsntError())
bfc7a1 ¤   {
dc9a5e ¤   ¤   if (!didRemove)
--dbd6 000068574ab4011016b Page 10 of PGPdiskHighLevelUtils.cpp
0f5fa1 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IncorrectPassphrase);
a19371 ¤   }
6eaf5a
4ffd0b ¤   if (readHeader)
623fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
29af5a
c233e3 ¤   return derr;
cdefe6 }
0eaf5a
2af036 // RemoveAlternatePassphrases removes all alternate passphrases from the·
62020d // specified PGPdisk.
6daf5a
63e677 DualErr
a3b946 RemoveAlternatePassphrases(LPCSTR path)
b8bb36 {
cd705b ¤   DualErr¤¤   ¤   ¤   derr;
9ad957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
868fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
0daf5a
ad639f ¤   pgpAssertStrValid(path);
43af5a
49e2ee ¤   // Read in the header.
40b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
2ba08e ¤   readHeader = derr.IsntError();
1caf5a
b58299 ¤   // Remove all alternate passphrases.
d42361 ¤   if (derr.IsntError())
dec7a1 ¤   {
f29a0b ¤   ¤   for (PGPUInt16 index = 1; index <= kMaxAlternatePassphrases; ++index)
0a5b34 ¤   ¤   {
99c9a8 ¤   ¤   ¤   PassphraseKey *userInfo;
9faf5a
5f3bc8 ¤   ¤   ¤   userInfo =·
1a5404 ¤   ¤   ¤   ¤   (PassphraseKey *) GetPassphraseKeyPtr(fileHeader, index);
deaf5a
255e22 ¤   ¤   ¤   // This clears the inUse flag as well
c52cfb ¤   ¤   ¤   pgpClearMemory(userInfo, sizeof(PassphraseKey));
517b48 ¤   ¤   ¤   userInfo->inUse¤= FALSE;
cb0fe4 ¤   ¤   }
feaf5a
1a0897 ¤   ¤   derr = WritePGPdiskFileMainHeader(path, fileHeader);
bb9371 ¤   }
4eaf5a
98fd0b ¤   if (readHeader)
663fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
1baf5a
9333e3 ¤   return derr;
75efe6 }
beaf5a
a2af5a
77fcb8 //////////////////////////////////
0a763e // Miscellaneous utility functions
f8fcb8 //////////////////////////////////
31af5a
53e193 // IsPGPdiskNotEncrypted returns TRUE if the specified PGPdisk was created
081646 // without encryption, FALSE otherwise.
dbaf5a
dc77be PGPBoolean·
d2bc18 IsPGPdiskNotEncrypted(LPCSTR path)
3fbb36 {
c8705b ¤   DualErr¤¤   ¤   ¤   derr;
1f51de ¤   PGPBoolean¤ ¤   ¤   isNotEncrypted, readHeader;
a88fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
9daf5a
3e0900 ¤   isNotEncrypted = readHeader = FALSE;
1daf5a
80639f ¤   pgpAssertStrValid(path);
9daf5a
c09e89 ¤   // Read the header.
74b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
33a08e ¤   readHeader = derr.IsntError();
06af5a
--21b9 000112ca4764011016b Page 11 of PGPdiskHighLevelUtils.cpp
2e80ec ¤   // Determine if encryption was used.
9e2361 ¤   if (derr.IsntError())
d1c7a1 ¤   {
be2502 ¤   ¤   isNotEncrypted =·
1d0a16 ¤   ¤   ¤   (fileHeader->algorithm == kCopyDataEncryptionAlgorithm);
e19371 ¤   }
fd0e24 ¤   else
93c7a1 ¤   {
88b633 ¤   ¤   isNotEncrypted = FALSE;
d49371 ¤   }
cdaf5a
a1fd0b ¤   if (readHeader)
1b3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
b1af5a
efe52c ¤   return isNotEncrypted;
d7efe6 }
a6af5a
2ce283 // GetDriveLetterPref returns the preferred drive letter setting that is
a764ba // stored in the PGPdisk's header.
7caf5a
b3671d PGPUInt8·
a66d72 GetDriveLetterPref(LPCSTR path)
49bb36 {
e3705b ¤   DualErr¤¤   ¤   ¤   derr;
a2d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
425f53 ¤   PGPUInt8¤   ¤   ¤   drive;
b98fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
66af5a
8f639f ¤   pgpAssertStrValid(path);
21af5a
c99e89 ¤   // Read the header.
8fb408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
4fa08e ¤   readHeader = derr.IsntError();
44af5a
e577f8 ¤   // Retrieve the drive letter field.
212361 ¤   if (derr.IsntError())
58c7a1 ¤   {
896f0d ¤   ¤   drive = fileHeader->drive;
059371 ¤   }
ea0e24 ¤   else
d2c7a1 ¤   {
caa9c7 ¤   ¤   drive = kInvalidDrive;
eb9371 ¤   }
06af5a
40fd0b ¤   if (readHeader)
9a3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
3aaf5a
e7995f ¤   return drive;
69efe6 }
beaf5a
5e7636 // SetDriveLetterPref alters the PGPdisk's header so it remembers the given
151441 // drive letter as its preferred drive letter from now on.
d0af5a
0d2292 DualErr·
0b742f SetDriveLetterPref(LPCSTR path, PGPUInt8 drive)
64bb36 {
3a705b ¤   DualErr¤¤   ¤   ¤   derr;
75d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
358fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
91af5a
a7639f ¤   pgpAssertStrValid(path);
afaf5a
8b9e89 ¤   // Read the header.
dcb408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
dea08e ¤   readHeader = derr.IsntError();
20af5a
e34c07 ¤   // Alter the drive letter field and write out the header.
5d2361 ¤   if (derr.IsntError())
b7c7a1 ¤   {
df4261 ¤   ¤   fileHeader->drive = drive;
37af5a
110897 ¤   ¤   derr = WritePGPdiskFileMainHeader(path, fileHeader);
--2d7b 00061bd76404011016b Page 12 of PGPdiskHighLevelUtils.cpp
a19371 ¤   }
93af5a
26fd0b ¤   if (readHeader)
9f3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
19af5a
0d33e3 ¤   return derr;
b5efe6 }
9aaf5a
989f70 // GetPGPdiskMountedFlag returns the value of the 'mountedFlag' header
5a2c7e // variable.
8daf5a
7577be PGPBoolean·
a159eb GetPGPdiskMountedFlag(LPCSTR path)
0dbb36 {
24705b ¤   DualErr¤¤   ¤   ¤   derr;
844095 ¤   PGPBoolean¤ ¤   ¤   isMounted, readHeader;
b38fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
bbaf5a
a94a37 ¤   isMounted = readHeader = FALSE;
84af5a
36639f ¤   pgpAssertStrValid(path);
feaf5a
3a9e89 ¤   // Read the header.
13b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
67a08e ¤   readHeader = derr.IsntError();
4eaf5a
e54bb3 ¤   if (derr.IsError())
bac7a1 ¤   {
c6eab1 ¤   ¤   isMounted = FALSE;
719371 ¤   }
4c0e24 ¤   else
a6c7a1 ¤   {
ca0d0b ¤   ¤   isMounted = fileHeader->mountedFlag;
5f9371 ¤   }
c4af5a
c3fd0b ¤   if (readHeader)
7e3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
59af5a
2f2fcd ¤   return isMounted;
ceefe6 }
6baf5a
369564 // SetPGPdiskMountedFlag(File *diskFile... ) sets the value of the
c0ff73 // 'mountedFlag' header variable on the opened PGPdisk.
9baf5a
6b2292 DualErr·
d3bac5 SetPGPdiskMountedFlag(File *diskFile, PGPBoolean mountedFlag)
3bbb36 {
5f705b ¤   DualErr¤¤   ¤   ¤   derr;
23d957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
a48fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
b3af5a
a99137 ¤   pgpAssertAddrValid(diskFile, File);
ac1071 ¤   pgpAssert(diskFile->Opened());
ddaf5a
159e89 ¤   // Read the header.
3518e4 ¤   derr = ReadPGPdiskFileMainHeader(diskFile, &fileHeader);
dca08e ¤   readHeader = derr.IsntError();
f3af5a
fade7f ¤   // Set the value of the 'mountedFlag' variable.
af2361 ¤   if (derr.IsntError())
12c7a1 ¤   {
3afca7 ¤   ¤   fileHeader->mountedFlag = mountedFlag;
654542 ¤   ¤   derr = WritePGPdiskFileMainHeader(diskFile, fileHeader);
269371 ¤   }
86af5a
ccfd0b ¤   if (readHeader)
513fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
04af5a
e433e3 ¤   return derr;
beefe6 }
b5af5a
61b5dc // SetPGPdiskMountedFlag(LPCSTR path... ) is a wrapper function.
--bcf8 000227808c84011016b Page 13 of PGPdiskHighLevelUtils.cpp
e0af5a
6f2292 DualErr·
22313d SetPGPdiskMountedFlag(LPCSTR path, PGPBoolean mountedFlag)
41bb36 {
f8945d ¤   DualErr¤derr;
537cd6 ¤   File¤   diskFile;
42af5a
23639f ¤   pgpAssertStrValid(path);
deaf5a
9e8dae ¤   derr = diskFile.Open(path, kOF_MustExist);
08af5a
c02361 ¤   if (derr.IsntError())
73c7a1 ¤   {
7d6a8c ¤   ¤   derr = SetPGPdiskMountedFlag(&diskFile, mountedFlag);
a69371 ¤   }
8eaf5a
5bd27f ¤   if (diskFile.Opened())
b9d016 ¤   ¤   diskFile.Close();
9daf5a
ef33e3 ¤   return derr;
00efe6 }
c9af5a
b30adf // GetPGPdiskUniqueSessionId returns the value of the 'uniqueSessionId' header
aa2c7e // variable.
b5af5a
dba385 PGPUInt64·
fefafb GetPGPdiskUniqueSessionId(LPCSTR path)
1abb36 {
43705b ¤   DualErr¤¤   ¤   ¤   derr;
3ed957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
b78fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
91d0b7 ¤   PGPUInt64¤  ¤   ¤   sessionId;
c8af5a
7a639f ¤   pgpAssertStrValid(path);
77af5a
ea9e89 ¤   // Read the header.
b7b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
fea08e ¤   readHeader = derr.IsntError();
24af5a
b44bb3 ¤   if (derr.IsError())
33c7a1 ¤   {
1365bf ¤   ¤   sessionId = kInvalidSessionId;
799371 ¤   }
820e24 ¤   else
7bc7a1 ¤   {
26c8e2 ¤   ¤   sessionId = fileHeader->uniqueSessionId;
479371 ¤   }
d5af5a
f7fd0b ¤   if (readHeader)
5d3fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
c2af5a
b42015 ¤   return sessionId;
b4efe6 }
84af5a
d1ae89 // MakePGPdiskUniqueSessionId sets the value of the 'uniqueSessionId' header
692c7e // variable.
b3af5a
052292 DualErr·
1f1b6b SetPGPdiskUniqueSessionId(LPCSTR path, PGPUInt64 uniqueSessionId)
10bb36 {
62705b ¤   DualErr¤¤   ¤   ¤   derr;
2ad957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
ce8fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
8baf5a
0d639f ¤   pgpAssertStrValid(path);
b6af5a
8f9e89 ¤   // Read the header.
2db408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
e6a08e ¤   readHeader = derr.IsntError();
4caf5a
ba2b2f ¤   // Set the value of the 'uniqueSessionId'.
222361 ¤   if (derr.IsntError())
--1c9d 000df9721e44011016b Page 14 of PGPdiskHighLevelUtils.cpp
f7c7a1 ¤   {
25b7ba ¤   ¤   fileHeader->uniqueSessionId = uniqueSessionId;
210897 ¤   ¤   derr = WritePGPdiskFileMainHeader(path, fileHeader);
bf9371 ¤   }
18af5a
6ffd0b ¤   if (readHeader)
b73fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
b1af5a
9733e3 ¤   return derr;
e7efe6 }
6caf5a
1348cb // DoesPGPdiskHaveBadCAST returns TRUE if the specified PGPdisk needs to be
9f4286 // converted to a newer version of CAST.
2baf5a
fb77be PGPBoolean·
ded74f DoesPGPdiskHaveBadCAST(LPCSTR path)
5bbb36 {
34705b ¤   DualErr¤¤   ¤   ¤   derr;
760641 ¤   PGPBoolean¤ ¤   ¤   hasBadCAST, readHeader;
728fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
24af5a
8b0fa8 ¤   hasBadCAST = readHeader = FALSE;
c2af5a
9b639f ¤   pgpAssertStrValid(path);
49af5a
909e89 ¤   // Read the header.
74b408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
5ea08e ¤   readHeader = derr.IsntError();
b3af5a
c24bb3 ¤   if (derr.IsError())
45c7a1 ¤   {
4a7dcf ¤   ¤   hasBadCAST = FALSE;
b19371 ¤   }
630e24 ¤   else
67c7a1 ¤   {
496c19 ¤   ¤   hasBadCAST = (fileHeader->majorVersion <=·
549171 ¤   ¤   ¤   kPGPdiskConvertInProgressMajorVersion);
319371 ¤   }
e2af5a
5dfd0b ¤   if (readHeader)
b53fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
e9af5a
ac210b ¤   return hasBadCAST;
cdefe6 }
27af5a
875de5 // WasPGPdiskConversionInterrupted returns TRUE if the specified PGPdisk
326d36 // is only partially converted to the newer version of CAST.
63af5a
8d77be PGPBoolean·
d956c7 WasPGPdiskConversionInterrupted(LPCSTR path)
60bb36 {
ee705b ¤   DualErr¤¤   ¤   ¤   derr;
3d5c0c ¤   PGPBoolean¤ ¤   ¤   wasInterrupted, readHeader;
3f8fe4 ¤   PGPdiskFileHeader¤  *fileHeader;
7baf5a
43f507 ¤   wasInterrupted = readHeader = FALSE;
54af5a
e9639f ¤   pgpAssertStrValid(path);
c1af5a
6a9e89 ¤   // Read the header.
7eb408 ¤   derr = ReadPGPdiskFileMainHeader(path, &fileHeader);
00a08e ¤   readHeader = derr.IsntError();
f3af5a
ea4bb3 ¤   if (derr.IsError())
66c7a1 ¤   {
08ca47 ¤   ¤   wasInterrupted = FALSE;
619371 ¤   }
b30e24 ¤   else
05c7a1 ¤   {
85d481 ¤   ¤   wasInterrupted = (fileHeader->majorVersion ==·
169171 ¤   ¤   ¤   kPGPdiskConvertInProgressMajorVersion);
df9371 ¤   }
--3773 0006177c40f4011016b Page 15 of PGPdiskHighLevelUtils.cpp
e0af5a
aefd0b ¤   if (readHeader)
a33fb9 ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) fileHeader);
65af5a
f566f7 ¤   return wasInterrupted;
f7efe6 }
a6af5a
34a89b // NukeAllNonADKHeaders deletes all non-ADK headers on the PGPdisk. If there
0bf60a // are any ADK headers, it re-encrypts them.
5daf5a
cf2292 DualErr·
e814da NukeAllNonADKHeaders(File *diskFile, const CASTKey *newSessionKey)
b7bb36 {
c79f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
cda351 ¤   PGPBoolean¤ ¤   ¤   ¤   gotItemList, gotNewItemList;
263249 ¤   PGPdiskFileHeaderItem¤  *itemList, *newList;
25af5a
cdcab2 ¤   gotItemList = gotNewItemList = FALSE;
5caf5a
7fea4b #if PGPDISK_PUBLIC_KEY
57af5a
8a0570 ¤   PGPBoolean¤ ¤   ¤   ¤   foundADKToAdd, gotAllKeys, gotContext;
520b4c ¤   PGPByte¤¤   ¤   ¤   ¤   *exportedKeyID;
18429f ¤   PGPContextRef¤  ¤   ¤   context;
b8a0a6 ¤   PGPdiskFileHeaderItem¤  *curItem;
183f1b ¤   PGPKeyID¤   ¤   ¤   ¤   keyID;
1f74c9 ¤   PGPKeyRef¤  ¤   ¤   ¤   pubKey;
f5ae97 ¤   PGPKeySetRef¤   ¤   ¤   allKeys;
bbaf5a
f4867b ¤   foundADKToAdd = gotAllKeys = gotContext = FALSE;
0faf5a
8838e4 #endif¤ // PGPDISK_PUBLIC_KEY
d6af5a
f99137 ¤   pgpAssertAddrValid(diskFile, File);
b31071 ¤   pgpAssert(diskFile->Opened());
e17988 ¤   pgpAssertAddrValid(newSessionKey, CASTKey);
28af5a
58d314 ¤   // Get list of headers.
3af2f2 ¤   derr = GetHeaderItemList(diskFile, &itemList);
9cb5ee ¤   gotItemList = derr.IsntError();
8caf5a
58ea4b #if PGPDISK_PUBLIC_KEY
71af5a
ff7147 ¤   // Deal with ADKs.
152361 ¤   if (derr.IsntError())
f3c7a1 ¤   {
bd2fb6 ¤   ¤   curItem = itemList->next;
edaf5a
1c3628 ¤   ¤   // Get context ref.
22e0ff ¤   ¤   derr = PGPNewContext(kPGPsdkAPIVersion, &context);
4f8a50 ¤   ¤   gotContext = derr.IsntError();
30af5a
ac2abd ¤   ¤   // Open default key rings.
e7aa35 ¤   ¤   if (derr.IsntError())
4a5b34 ¤   ¤   {
be400c ¤   ¤   ¤   derr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
924d58 ¤   ¤   ¤   gotAllKeys = derr.IsntError();
400fe4 ¤   ¤   }
7d1b52 ¤   ¤
f0831d ¤   ¤   while (derr.IsntError() && IsntNull(curItem))
9b5b34 ¤   ¤   {
717766 ¤   ¤   ¤   if (IsPublicKeyHeader(curItem->hdr))
bef776 ¤   ¤   ¤   {
8d7afe ¤   ¤   ¤   ¤   PGPdiskPublicKeyHeader *pubKeyHdr;
ebaf5a
13b23d ¤   ¤   ¤   ¤   pubKeyHdr = (PGPdiskPublicKeyHeader *) curItem->hdr;
fdaf5a
2fc501 ¤   ¤   ¤   ¤   // A locked key means ADK.
980d0d ¤   ¤   ¤   ¤   if (pubKeyHdr->locked)
c472c3 ¤   ¤   ¤   ¤   {
24390d ¤   ¤   ¤   ¤   ¤   // Import key ID.
618487 ¤   ¤   ¤   ¤   ¤   exportedKeyID = (PGPByte *) pubKeyHdr +·
--61a2 00039861c534011016b Page 16 of PGPdiskHighLevelUtils.cpp
43295b ¤   ¤   ¤   ¤   ¤   ¤   pubKeyHdr->keyIDOffset;
0baf5a
fb6736 ¤   ¤   ¤   ¤   ¤   derr = PGPImportKeyID(exportedKeyID, &keyID);
35af5a
6e4531 ¤   ¤   ¤   ¤   ¤   // Get actual key.
0e4ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
5a4859 ¤   ¤   ¤   ¤   ¤   {
db7aab ¤   ¤   ¤   ¤   ¤   ¤   derr = PGPGetKeyByKeyID(allKeys, &keyID,·
11ebf1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pubKeyHdr->algorithm, &pubKey);
e21c89 ¤   ¤   ¤   ¤   ¤   }
6faf5a
1d4ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
014859 ¤   ¤   ¤   ¤   ¤   {
1cb021 ¤   ¤   ¤   ¤   ¤   ¤   foundADKToAdd = TRUE;
e01c89 ¤   ¤   ¤   ¤   ¤   }
3faf5a
0a14c3 ¤   ¤   ¤   ¤   ¤   break;
002613 ¤   ¤   ¤   ¤   }
c6a3a6 ¤   ¤   ¤   }
13af5a
fb782d ¤   ¤   ¤   curItem = curItem->next;
470fe4 ¤   ¤   }
509371 ¤   }
abaf5a
5338e4 #endif¤ // PGPDISK_PUBLIC_KEY
ddaf5a
0e9800 ¤   // Construct new list.
642361 ¤   if (derr.IsntError())
f8c7a1 ¤   {
a9c3d8 ¤   ¤   derr = MakeHeaderItem(&newList);
b57d02 ¤   ¤   gotNewItemList = derr.IsntError();
dbaf5a
5caa35 ¤   ¤   if (derr.IsntError())
855b34 ¤   ¤   {
a1fd32 ¤   ¤   ¤   derr = CopyHeader(itemList->hdr, &newList->hdr);
b30fe4 ¤   ¤   }
f9af5a
e9aa35 ¤   ¤   if (derr.IsntError())
155b34 ¤   ¤   {
7bbf29 ¤   ¤   ¤   newList->prev = newList->next = NULL;
710fe4 ¤   ¤   }
029371 ¤   }
8caf5a
89ea4b #if PGPDISK_PUBLIC_KEY
32af5a
46a175 ¤   // Attach ADK.
0c5476 ¤   if (derr.IsntError() && foundADKToAdd)
01c7a1 ¤   {
3ea1b0 ¤   ¤   PGPdiskPublicKeyHeader *newADKHeader;
c1af5a
e6b039 ¤   ¤   derr = CreatePublicKeyHeader(context, pubKey, newSessionKey, TRUE,·
ed7dd5 ¤   ¤   ¤   TRUE, &newADKHeader);
beaf5a
2faa35 ¤   ¤   if (derr.IsntError())
365b34 ¤   ¤   {
d29798 ¤   ¤   ¤   derr = InsertPGPdiskHeaderInList(newList,·
826afe ¤   ¤   ¤   ¤   (PGPdiskFileHeaderInfo *) newADKHeader);
950fe4 ¤   ¤   }
c69371 ¤   }
0faf5a
4738e4 #endif¤ // PGPDISK_PUBLIC_KEY
e1af5a
de2361 ¤   if (derr.IsntError())
dfc7a1 ¤   {
7f6243 ¤   ¤   UpdateHeaderItemList(diskFile, newList);
0f9371 ¤   }
e6af5a
a7ea4b #if PGPDISK_PUBLIC_KEY
f3af5a
3ffcc4 ¤   if (gotAllKeys)
854192 ¤   ¤   PGPFreeKeySet(allKeys);
39af5a
--f887 001e0dd3abb4011016b Page 17 of PGPdiskHighLevelUtils.cpp
07b0b2 ¤   if (gotContext)
ac3e8c ¤   ¤   PGPFreeContext(context);
5daf5a
de38e4 #endif¤ // PGPDISK_PUBLIC_KEY
91af5a
e9b8b0 ¤   if (gotNewItemList)
0081dd ¤   ¤   FreeHeaderItemList(newList);
09af5a
903020 ¤   if (gotItemList)
dea68d ¤   ¤   FreeHeaderItemList(itemList);
0daf5a
be33e3 ¤   return derr;
e0efe6 }
--ab2c 00066f7d52a4011016c Page 1 of PGPdiskHighLevelUtils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
1d8147 // PGPdiskHighLevelUtils.h
13465d //
ac5272 // Declarations for PGPdiskHighLevelUtils.cpp.
841bc3 //////////////////////////////////////////////////////////////////////////////
fcaf5a
f25904 // $Id: PGPdiskHighLevelUtils.h,v 1.1.2.16.2.2 1998/10/22 00:41:52 nryan Exp $
d9af5a
9ccbce // Copyright (C) 1998 by Network Associates, Inc.
0471ae // All rights reserved.
a5af5a
71f07d #ifndef¤Included_PGPdiskHighLevelUtils_h¤   // [
48ef49 #define¤Included_PGPdiskHighLevelUtils_h
95af5a
f43db7 #include "FatUtils.h"
9ec16a #include "PGPdiskFileFormat.h"
8aaf5a
2369ea #include "Cast5.h"
298f51 #include "CipherUtils.h"
20af5a
64af5a
d7d557 ////////
d402c9 // Types
e6d557 ////////
30af5a
999bc8 class File;
c7af5a
2aaf5a
7b6cc2 /////////////////////
4213d2 // Exported functions
ea6cc2 /////////////////////
09af5a
e0b4c7 DualErr¤¤   ReadPGPdiskFileMainHeader(File *diskFile,·
4c274f ¤   ¤   ¤   ¤   PGPdiskFileHeader **fileHeader);
5d7340 DualErr¤¤   ReadPGPdiskFileMainHeader(LPCSTR path,·
7e274f ¤   ¤   ¤   ¤   PGPdiskFileHeader **fileHeader);
27af5a
ac5187 DualErr¤¤   WritePGPdiskFileMainHeader(File *diskFile,·
32beb9 ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader);
3bdd06 DualErr¤¤   WritePGPdiskFileMainHeader(LPCSTR path,·
9fbeb9 ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader);
6eaf5a
ea71c3 DualErr¤¤   ValidatePGPdisk(LPCSTR path);
fdaf5a
dd51b2 DualErr¤¤   VerifyNormalPassphrase(LPCSTR path, SecureString *passphrase);
c9af5a
daea4b #if PGPDISK_PUBLIC_KEY
57c1a2 DualErr¤¤   VerifyPublicKeyPassphrase(LPCSTR path, SecureString *passphrase);
bd38e4 #endif¤ // PGPDISK_PUBLIC_KEY
14af5a
9b21a8 DualErr¤¤   VerifyPassphrase(LPCSTR path, SecureString *passphrase);
648941 DualErr¤¤   VerifyMasterPassphrase(LPCSTR path, SecureString *passphrase);
1baf5a
de8435 DualErr¤¤   HowManyAlternatePassphrases(LPCSTR path, PGPUInt32 *numAlts);
45af5a
302d62 DualErr¤¤   AddPassphrase(LPCSTR path, SecureString *masterPassphrase,·
5704e7 ¤   ¤   ¤   ¤   SecureString *newPassphrase, PGPBoolean readOnly);
87a08b DualErr¤¤   ChangePassphrase(LPCSTR path, SecureString *oldPassphrase,·
ceb897 ¤   ¤   ¤   ¤   SecureString *newPassphrase);
cbaf5a
c5d51e DualErr¤¤   RemovePassphrase(LPCSTR path, SecureString *passphrase);
f2efaf DualErr¤¤   RemoveAlternatePassphrases(LPCSTR path);
ccaf5a
326719 PGPBoolean¤ IsPGPdiskNotEncrypted(LPCSTR path);
87af5a
6716c6 PGPUInt8¤   GetDriveLetterPref(LPCSTR path);
2e5088 DualErr¤¤   SetDriveLetterPref(LPCSTR path, PGPUInt8 drive);
eaaf5a
66a2e8 PGPBoolean¤ GetPGPdiskMountedFlag(LPCSTR path);
6e4b6a DualErr¤¤   SetPGPdiskMountedFlag(File *diskFile, PGPBoolean mountedFlag);
f1063e DualErr¤¤   SetPGPdiskMountedFlag(LPCSTR path, PGPBoolean mountedFlag);
66af5a
--31ce 001a29db9b94011016c Page 2 of PGPdiskHighLevelUtils.h
9df85b PGPUInt64¤  GetPGPdiskUniqueSessionId(LPCSTR path);
dfe836 DualErr¤¤   SetPGPdiskUniqueSessionId(LPCSTR path, PGPUInt64 uniqueSessionId);
e1af5a
e73297 PGPBoolean¤ DoesPGPdiskHaveBadCAST(LPCSTR path);
2ab9df PGPBoolean¤ WasPGPdiskConversionInterrupted(LPCSTR path);
9caf5a
78c656 DualErr¤¤   NukeAllNonADKHeaders(File *diskFile,·
dafd72 ¤   ¤   ¤   ¤   const CASTKey *newSessionKey);
00af5a
a21255 #endif¤ // ] Included_PGPdiskHighLevelUtils_h
--73e4 000505e3ef04011016d Page 1 of PGPdiskLowLevelUtils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
82e8c6 // PGPdiskLowLevelUtils.cpp
ef465d //
475591 // Low-level utility functions for working with PGPdisks.
5f1bc3 //////////////////////////////////////////////////////////////////////////////
89af5a
199d5f // $Id: PGPdiskLowLevelUtils.cpp,v 1.1.2.27.2.1 1998/10/21 01:35:32 nryan Exp $
b4af5a
c6cbce // Copyright (C) 1998 by Network Associates, Inc.
a171ae // All rights reserved.
0baf5a
716931 #if defined(PGPDISK_MFC)
47af5a
349e12 #include "StdAfx.h"
02b8af #include <new.h>
6aaf5a
e04268 #elif defined(PGPDISK_95DRIVER)
b6af5a
0d06a9 #include <vtoolscp.h>
823a08 #include "PlacementNew.h"
b9af5a
6c86d2 #include LOCKED_CODE_SEGMENT
375269 #include LOCKED_DATA_SEGMENT
06f5a6 #elif defined(PGPDISK_NTDRIVER)
faaf5a
33d7a1 #include <vdw.h>
72af5a
1fdb21 #else
3c112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
a405d6 #endif¤ // PGPDISK_MFC
aeaf5a
8d9bcf #include "Required.h"
a07414 #include "PGPdiskHighLevelUtils.h"
bd2229 #include "PGPdiskLowLevelUtils.h"
8c70d4 #include "SecureMemory.h"
c2bfe9 #include "UtilityFunctions.h"
98af5a
85f037 #include "File.h"
e1af5a
04af5a
2a3e71 /////////////////////////////////////
3e1da2 // Low-level header utility functions
763e71 /////////////////////////////////////
baaf5a
c7d0e3 // MakeEmptyHeader creates a PGPdisk header of the specified size.
59af5a
832292 DualErr·
4763f0 MakeEmptyHeader(PGPUInt32 headerSize, PGPdiskFileHeaderInfo **hdr)
7ebb36 {
f27d36 ¤   DualErr derr;
43af5a
01de7a ¤   pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo *);
87af5a
f66931 #if defined(PGPDISK_MFC)
e7af5a
b078f1 ¤   try
79c7a1 ¤   {
2d0f50 ¤   ¤   (* hdr) = (PGPdiskFileHeaderInfo *) new PGPUInt8[headerSize];
b29371 ¤   }
503c88 ¤   catch (CMemoryException *ex)
01c7a1 ¤   {
66ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
206adc ¤   ¤   ex->Delete();
719371 ¤   }
f4af5a
2d7497 #else¤  // !PGPDISK_MFC
c4af5a
f81a73 ¤   (* hdr) = (PGPdiskFileHeaderInfo *) new PGPUInt8[headerSize];
d7af5a
3e59a7 ¤   if (IsNull((* hdr)))
5becf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
50af5a
--5466 000e4ae1f164011016d Page 2 of PGPdiskLowLevelUtils.cpp
d005d6 #endif¤ // PGPDISK_MFC
7baf5a
5333e3 ¤   return derr;
a0efe6 }
8daf5a
0f45b4 // CopyHeader copies a PGPdisk header.
d1af5a
022292 DualErr·
b3a3d5 CopyHeader(PGPdiskFileHeaderInfo *inHdr, PGPdiskFileHeaderInfo **outHdr)
60bb36 {
8f7d36 ¤   DualErr derr;
fbaf5a
38fdd2 ¤   pgpAssertAddrValid(inHdr, PGPdiskFileHeaderInfo);
edbf39 ¤   pgpAssertAddrValid(outHdr, PGPdiskFileHeaderInfo *);
34af5a
6f1981 ¤   derr = MakeEmptyHeader(inHdr->headerSize, outHdr);
a9af5a
0a2361 ¤   if (derr.IsntError())
72c7a1 ¤   {
d489ec ¤   ¤   pgpCopyMemory(inHdr, (* outHdr), inHdr->headerSize);
8e9371 ¤   }
57af5a
9433e3 ¤   return derr;
46efe6 }
c7af5a
13241e // FreeHeader frees a PGPdisk headder allocated with MakeEmptyHeader.
3daf5a
afc823 void·
3ad4a9 FreeHeader(PGPdiskFileHeaderInfo *hdr)
2fbb36 {
86ca67 ¤   pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo);
07af5a
4b1b74 ¤   delete[] (PGPUInt8 *) hdr;
97efe6 }
47af5a
6a88a5 // ReadPGPdiskFileHeaderAtOffset reads in the header at the given offset.
e5af5a
2c2292 DualErr·
2364a6 ReadPGPdiskFileHeaderAtOffset(
247082 ¤   File¤   ¤   ¤   ¤   ¤   *diskFile,·
305351 ¤   PGPUInt64¤  ¤   ¤   ¤   pos,·
425468 ¤   PGPdiskFileHeaderInfo¤  **hdr)
7fbb36 {
939f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
163108 ¤   PGPBoolean¤ ¤   ¤   ¤   allocedFileHeader¤  = FALSE;
48ddee ¤   PGPdiskFileHeaderInfo¤  hdrInfo;
e3af5a
f49137 ¤   pgpAssertAddrValid(diskFile, File);
f91071 ¤   pgpAssert(diskFile->Opened());
90de7a ¤   pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo *);
e6af5a
d70729 ¤   // Read in next header.
13ff1c ¤   derr = diskFile->Read((PGPUInt8 *) &hdrInfo, pos,·
d1b9d8 ¤   ¤   sizeof(PGPdiskFileHeaderInfo));
55af5a
4a2361 ¤   if (derr.IsntError())
03c7a1 ¤   {
802ed2 ¤   ¤   if (strncmp(hdrInfo.headerMagic, kPGPdiskHeaderMagic, 4) != 0)
0ac9a3 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_BadHeaderMagic);
379371 ¤   }
ecaf5a
fe421c ¤   // Allocate space for header.
812361 ¤   if (derr.IsntError())
fec7a1 ¤   {
d691fe ¤   ¤   derr = MakeEmptyHeader(hdrInfo.headerSize, hdr);
3ffb8e ¤   ¤   allocedFileHeader = derr.IsntError();
019371 ¤   }
c9af5a
759ff2 ¤   // Read it in.
282361 ¤   if (derr.IsntError())
adc7a1 ¤   {
e4a1bc ¤   ¤   derr = diskFile->Read((PGPUInt8 *) (* hdr), pos, hdrInfo.headerSize);
--dfea 0002d15e44b4011016d Page 3 of PGPdiskLowLevelUtils.cpp
a19371 ¤   }
93af5a
4f2f6f ¤   // Cleanup on error.
6c4bb3 ¤   if (derr.IsError())
2fc7a1 ¤   {
510eed ¤   ¤   if (allocedFileHeader)
199303 ¤   ¤   ¤   FreeHeader((* hdr));
da9371 ¤   }
bfaf5a
5933e3 ¤   return derr;
c1efe6 }
34af5a
51f204 // WritePGPdiskFileHeaderAtOffset writes a header at the given offset.
06af5a
982292 DualErr·
fe9ce9 WritePGPdiskFileHeaderAtOffset(
cc7082 ¤   File¤   ¤   ¤   ¤   ¤   *diskFile,·
745351 ¤   PGPUInt64¤  ¤   ¤   ¤   pos,·
03ea28 ¤   PGPdiskFileHeaderInfo¤  *hdr)
dabb36 {
e7be41 ¤   DualErr¤¤   derr;
dba9f5 ¤   PGPUInt8¤   blanks[kDefaultBlockSize];
b8af5a
9f1300 ¤   pgpClearMemory(blanks, kDefaultBlockSize);
a3af5a
a79137 ¤   pgpAssertAddrValid(diskFile, File);
021071 ¤   pgpAssert(diskFile->Opened());
2cca67 ¤   pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo);
c8af5a
9b0506 ¤   // Update header CRC.
1fae23 ¤   UpdatePGPdiskFileHeaderCRC(hdr);
09af5a
4fb646 ¤   // Write out the header.
e8d18d ¤   derr = diskFile->Write((PGPUInt8 *) hdr, pos, hdr->headerSize);
63af5a
08c88e ¤   // Clear space up to block boundary.
9d023e ¤   if (hdr->headerSize % kDefaultBlockSize > 0)
e6c7a1 ¤   {
1a29cc ¤   ¤   derr = diskFile->Write(blanks, pos + hdr->headerSize,·
1c510b ¤   ¤   ¤   kDefaultBlockSize - hdr->headerSize%kDefaultBlockSize);
f59371 ¤   }
4daf5a
2733e3 ¤   return derr;
43efe6 }
f2af5a
7fb4de // FreePGPdiskFileHeader frees a header allocated with
6672f0 // ReadPGPdiskFileHeaderAtOffset.
81af5a
ccc823 void·
e2743a FreePGPdiskFileHeader(PGPdiskFileHeaderInfo *hdr)
c4bb36 {
c7ca67 ¤   pgpAssertAddrValid(hdr, PGPdiskFileHeaderInfo);
90af5a
62445d ¤   FreeHeader(hdr);
cdefe6 }
85af5a
5d1178 // MakeHeaderItem simply allocates a new header item.
26af5a
d32292 DualErr·
9a0601 MakeHeaderItem(PGPdiskFileHeaderItem **item)
06bb36 {
a97d36 ¤   DualErr derr;
33af5a
41640d ¤   pgpAssertAddrValid(item, PGPdiskFileHeaderItem *);
2aaf5a
326931 #if defined(PGPDISK_MFC)
7eaf5a
7278f1 ¤   try
51c7a1 ¤   {
5b388f ¤   ¤   (* item) = new PGPdiskFileHeaderItem;
b49371 ¤   }
2d3c88 ¤   catch (CMemoryException *ex)
--8671 0003baf6c3c4011016d Page 4 of PGPdiskLowLevelUtils.cpp
f7c7a1 ¤   {
0cecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
046adc ¤   ¤   ex->Delete();
b89371 ¤   }
28af5a
c97497 #else¤  // !PGPDISK_MFC
90af5a
a3014a ¤   (* item) = new PGPdiskFileHeaderItem;
05af5a
35f1c8 ¤   if (IsNull((* item)))
72ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
9faf5a
5f05d6 #endif¤ // PGPDISK_MFC
1daf5a
5633e3 ¤   return derr;
17efe6 }
efaf5a
83ca71 // FreeHeaderItem frees an item allocated with MakeHeaderItem.
abaf5a
f0c823 void·
6ce093 FreeHeaderItem(PGPdiskFileHeaderItem *item)
bdbb36 {
43640d ¤   pgpAssertAddrValid(item, PGPdiskFileHeaderItem *);
62af5a
ceb91a ¤   delete item;
9aefe6 }
a4af5a
2aec9c // InsertPGPdiskHeaderInList inserts a header item in a header item list.
5faf5a
282292 DualErr·
30096f InsertPGPdiskHeaderInList(
6a486b ¤   ·PGPdiskFileHeaderItem¤ *curItem,·
dd6491 ¤   ·PGPdiskFileHeaderInfo¤ *newHdr)
0bbb36 {
989f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
8e06af ¤   PGPdiskFileHeaderItem¤  *newItem;
41af5a
0fc084 ¤   pgpAssertAddrValid(curItem, PGPdiskFileHeaderItem *);
8dbe83 ¤   pgpAssertAddrValid(newHdr, PGPdiskFileHeader *);
51af5a
8d7edc ¤   // Get a new item.
15f4e3 ¤   derr = MakeHeaderItem(&newItem);
27af5a
ffb26c ¤   // Adjust the list.
052361 ¤   if (derr.IsntError())
08c7a1 ¤   {
b7531a ¤   ¤   newItem->prev = curItem;
87057d ¤   ¤   newItem->next = curItem->next;
adaf5a
23bea6 ¤   ¤   newItem->hdr = newHdr;
d4af5a
d3f48a ¤   ¤   if (IsntNull(newItem->next))
1baff2 ¤   ¤   ¤   newItem->next->prev = newItem;
faaf5a
42c107 ¤   ¤   curItem->next = newItem;
be9371 ¤   }
eaaf5a
c133e3 ¤   return derr;
d5efe6 }
81af5a
484437 // RemovePGPdiskHeaderFromList removes a header item in a header item list.
b0af5a
ddc823 void·
be4511 RemovePGPdiskHeaderFromList(PGPdiskFileHeaderItem **itemToRemove)
e2bb36 {
7f138b ¤   PGPdiskFileHeaderItem *prevItem, *nextItem;
4daf5a
29aba2 ¤   pgpAssertAddrValid(itemToRemove, PGPdiskFileHeaderItem *);
e6af5a
df43bb ¤   prevItem = (* itemToRemove)->prev;
c1cf9e ¤   nextItem = (* itemToRemove)->next;
3baf5a
--30e5 000073cf0d24011016d Page 5 of PGPdiskLowLevelUtils.cpp
fead58 ¤   // Remove the item from the linked list.
7838d7 ¤   if (IsntNull(prevItem))
859a0d ¤   ¤   prevItem->next = nextItem;
64af5a
e4efc1 ¤   if (IsntNull(nextItem))
8cf752 ¤   ¤   nextItem->prev = prevItem;
20af5a
0d126c ¤   // Free the item.
e35be8 ¤   FreeHeaderItem((* itemToRemove));
1caf5a
ad33ef ¤   (* itemToRemove) = (IsntNull(prevItem) ? prevItem : nextItem);
37efe6 }
98af5a
5c0679 // GetHeaderItemList constructs an item list of the headers in the PGPdisk.
1aaf5a
19e677 DualErr
f2c3f3 GetHeaderItemList(File *diskFile, PGPdiskFileHeaderItem **itemList)
59bb36 {
569f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
054c09 ¤   PGPdiskFileHeaderInfo¤  *hdr;
48b7d7 ¤   PGPdiskFileHeaderItem¤  *curItem, *firstItem, *nextItem;
68af5a
179137 ¤   pgpAssertAddrValid(diskFile, File);
a41071 ¤   pgpAssert(diskFile->Opened());
43ea0e ¤   pgpAssertAddrValid(itemList, PGPdiskFileHeaderItem *);
b4af5a
82cb49 ¤   // Read in main header.
94d764 ¤   derr = ReadPGPdiskFileMainHeader(diskFile, (PGPdiskFileHeader **) &hdr);
24af5a
31aa3d ¤   // Set it as first item.
b52361 ¤   if (derr.IsntError())
bbc7a1 ¤   {
d46868 ¤   ¤   derr = MakeHeaderItem(&firstItem);
4a9371 ¤   }
0faf5a
e32361 ¤   if (derr.IsntError())
29c7a1 ¤   {
6b6b7f ¤   ¤   firstItem->next = firstItem->prev = NULL;
0c849a ¤   ¤   firstItem->hdr = hdr;
299371 ¤   }
ccaf5a
c6598a ¤   // Read in remaining headers.
c72361 ¤   if (derr.IsntError())
45c7a1 ¤   {
3c12d3 ¤   ¤   PGPBoolean headersLeft = TRUE;
e7af5a
f86a55 ¤   ¤   curItem = firstItem;
9faf5a
960c19 ¤   ¤   do
f35b34 ¤   ¤   {
682348 ¤   ¤   ¤   PGPUInt64 pos;
a9af5a
6b0544 ¤   ¤   ¤   // Get position of next header.
d797d3 ¤   ¤   ¤   pos = curItem->hdr->nextHeaderOffset;
12af5a
bd70ae ¤   ¤   ¤   if (pos == 0)
d3f776 ¤   ¤   ¤   {
6f65b5 ¤   ¤   ¤   ¤   // There is no next header.
0b3b01 ¤   ¤   ¤   ¤   headersLeft = FALSE;
e6a3a6 ¤   ¤   ¤   }
7cbb8c ¤   ¤   ¤   else
80f776 ¤   ¤   ¤   {
3e0bd5 ¤   ¤   ¤   ¤   PGPBoolean readHeader = FALSE;
21af5a
f5e4de ¤   ¤   ¤   ¤   // Read in next header.
3856aa ¤   ¤   ¤   ¤   derr = ReadPGPdiskFileHeaderAtOffset(diskFile, pos, &hdr);
2b7ea9 ¤   ¤   ¤   ¤   readHeader = derr.IsntError();
3caf5a
2b1d9b ¤   ¤   ¤   ¤   // Insert it into the list.
5e724e ¤   ¤   ¤   ¤   if (derr.IsntError())
0172c3 ¤   ¤   ¤   ¤   {
079763 ¤   ¤   ¤   ¤   ¤   derr = InsertPGPdiskHeaderInList(curItem, hdr);
--37ff 00095bb54f04011016d Page 6 of PGPdiskLowLevelUtils.cpp
862613 ¤   ¤   ¤   ¤   }
fdaf5a
7c1032 ¤   ¤   ¤   ¤   // Iterate to next item.
ed724e ¤   ¤   ¤   ¤   if (derr.IsntError())
b572c3 ¤   ¤   ¤   ¤   {
5d7b78 ¤   ¤   ¤   ¤   ¤   curItem = curItem->next;
862613 ¤   ¤   ¤   ¤   }
f0af5a
fc9d0c ¤   ¤   ¤   ¤   // Cleanup on error.
769b74 ¤   ¤   ¤   ¤   if (derr.IsError())
4d72c3 ¤   ¤   ¤   ¤   {
c65738 ¤   ¤   ¤   ¤   ¤   if (readHeader)
656a4a ¤   ¤   ¤   ¤   ¤   ¤   FreePGPdiskFileHeader(hdr);
e92613 ¤   ¤   ¤   ¤   }
f3a3a6 ¤   ¤   ¤   }
f70fe4 ¤   ¤   }
98498e ¤   ¤   while (derr.IsntError() && headersLeft);
75af5a
b8aa35 ¤   ¤   if (derr.IsntError())
215b34 ¤   ¤   {
61de0e ¤   ¤   ¤   curItem->next = NULL;
a17369 ¤   ¤   ¤   (* itemList) = firstItem;
0d0fe4 ¤   ¤   }
c19371 ¤   }
92af5a
f32f6f ¤   // Cleanup on error.
614bb3 ¤   if (derr.IsError())
88c7a1 ¤   {
186a55 ¤   ¤   curItem = firstItem;
22af5a
1a8ccc ¤   ¤   while (IsntNull(curItem))
605b34 ¤   ¤   {
ac1b06 ¤   ¤   ¤   nextItem = curItem->next;
b5af5a
8c5a64 ¤   ¤   ¤   FreePGPdiskFileHeader(curItem->hdr);
5f865d ¤   ¤   ¤   FreeHeaderItem(curItem);
a5af5a
af9a3f ¤   ¤   ¤   curItem = nextItem;
cf0fe4 ¤   ¤   }
309371 ¤   }
b6af5a
7633e3 ¤   return derr;
a0efe6 }
e4af5a
da507b // FreeHeaderItemList frees a list created with GetHeaderItemList.
4baf5a
27c823 void·
61a2f5 FreeHeaderItemList(PGPdiskFileHeaderItem *itemList)
e2bb36 {
e878eb ¤   PGPdiskFileHeaderItem *curItem, *nextItem;
4daf5a
d1efce ¤   curItem = itemList;
94af5a
d7bbc4 ¤   while (IsntNull(curItem))
69c7a1 ¤   {
b7c3cf ¤   ¤   pgpAssertAddrValid(curItem, PGPdiskFileHeaderItem);
1aa55e ¤   ¤   pgpAssertAddrValid(curItem->hdr, PGPdiskFileHeaderInfo);
f7af5a
bef475 ¤   ¤   nextItem = curItem->next;
c3af5a
4908f9 ¤   ¤   FreePGPdiskFileHeader(curItem->hdr);
2bbb35 ¤   ¤   FreeHeaderItem(curItem);
c2af5a
ef3761 ¤   ¤   curItem = nextItem;
899371 ¤   }
6aefe6 }
b0af5a
1ee876 // UpdateHeaderItemList writes out a header list to a PGPdisk.
d5af5a
a1e677 DualErr
c518f9 UpdateHeaderItemList(File *diskFile, PGPdiskFileHeaderItem *itemList)
95bb36 {
--f423 00080e55e0c4011016d Page 7 of PGPdiskLowLevelUtils.cpp
449f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
65d9c5 ¤   PGPdiskFileHeader¤  ¤   *mainHdr;
dc34cb ¤   PGPdiskFileHeaderItem¤  *curItem, *nextItem;
0c1b64 ¤   PGPUInt32¤  ¤   ¤   ¤   blockAfterData, i;
b5816c ¤   PGPUInt64¤  ¤   ¤   ¤   length;
f5af5a
d79137 ¤   pgpAssertAddrValid(diskFile, File);
e21071 ¤   pgpAssert(diskFile->Opened());
ddea0e ¤   pgpAssertAddrValid(itemList, PGPdiskFileHeaderItem *);
04dea2 ¤   pgpAssertAddrValid(itemList->hdr, PGPdiskFileHeaderInfo);
3caf5a
55652e ¤   mainHdr = (PGPdiskFileHeader *) itemList->hdr;
e95e37 ¤   blockAfterData = mainHdr->numHeaderBlocks + mainHdr->numDataBlocks;
69af5a
3ed7ac ¤   // Set file size to minimum.
27b2dc ¤   derr = diskFile->SetLength((PGPUInt64)·
180c30 ¤   ¤   blockAfterData * kDefaultBlockSize);
48af5a
d769b0 ¤   // Wipe reserved header blocks.
542361 ¤   if (derr.IsntError())
e8c7a1 ¤   {
923fa8 ¤   ¤   PGPUInt8 blanks[kDefaultBlockSize];
09af5a
17cbb2 ¤   ¤   pgpClearMemory(blanks, kDefaultBlockSize);
ccaf5a
8646cc ¤   ¤   for (i = 0; i < mainHdr->numHeaderBlocks; i++)
5b5b34 ¤   ¤   {
b20aca ¤   ¤   ¤   derr = diskFile->Write(blanks, i*kDefaultBlockSize,·
83674b ¤   ¤   ¤   ¤   kDefaultBlockSize);
b2af5a
ce1088 ¤   ¤   ¤   if (derr.IsError())
1bf622 ¤   ¤   ¤   ¤   break;
ef0fe4 ¤   ¤   }
eb9371 ¤   }
d6af5a
666a58 ¤   // Assume always enough room to store main header in beginning.
b72361 ¤   if (derr.IsntError())
38c7a1 ¤   {
d80fee ¤   ¤   PGPBoolean¤ usedUpReservedBlocks¤   = FALSE;
32008f ¤   ¤   PGPUInt32¤  blocksTaken, nextBlock, remainingBlocks;
63af5a
c019ab ¤   ¤   curItem = itemList;
8eaf5a
58d79a ¤   ¤   nextBlock = 0;
f485d2 ¤   ¤   remainingBlocks = mainHdr->numHeaderBlocks;
17af5a
463ec7 ¤   ¤   // Calculate new offsets for each header.
d48ccc ¤   ¤   while (IsntNull(curItem))
d75b34 ¤   ¤   {
361b06 ¤   ¤   ¤   nextItem = curItem->next;
2faf5a
a18c3c ¤   ¤   ¤   if (IsNull(nextItem))
3cf776 ¤   ¤   ¤   {
1f2dee ¤   ¤   ¤   ¤   curItem->hdr->nextHeaderOffset = 0;
afa3a6 ¤   ¤   ¤   }
73bb8c ¤   ¤   ¤   else
e9f776 ¤   ¤   ¤   {
e9af5a
e6324f ¤   ¤   ¤   ¤   pgpAssertAddrValid(nextItem, PGPdiskFileHeaderItem);
4d449b ¤   ¤   ¤   ¤   pgpAssertAddrValid(nextItem->hdr, PGPdiskFileHeaderInfo);
46af5a
ced2e6 ¤   ¤   ¤   ¤   blocksTaken = (PGPUInt32) CeilDiv(curItem->hdr->headerSize,·
b3a21e ¤   ¤   ¤   ¤   ¤   kDefaultBlockSize);
bcaf5a
d707fc ¤   ¤   ¤   ¤   // Any space left at beginning of file?
6fb685 ¤   ¤   ¤   ¤   if (!usedUpReservedBlocks)
0272c3 ¤   ¤   ¤   ¤   {
f2c615 ¤   ¤   ¤   ¤   ¤   if (blocksTaken <= remainingBlocks)
8c4859 ¤   ¤   ¤   ¤   ¤   {
1a1dc9 ¤   ¤   ¤   ¤   ¤   ¤   remainingBlocks -= blocksTaken;
806159 ¤   ¤   ¤   ¤   ¤   ¤   nextBlock += blocksTaken;
80af5a
--4f0d 00016d7f1194011016d Page 8 of PGPdiskLowLevelUtils.cpp
c09493 ¤   ¤   ¤   ¤   ¤   ¤   // OK to put at current offset.
35c352 ¤   ¤   ¤   ¤   ¤   ¤   curItem->hdr->nextHeaderOffset = nextBlock *·
fd3522 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kDefaultBlockSize;
ad1c89 ¤   ¤   ¤   ¤   ¤   }
b14bd6 ¤   ¤   ¤   ¤   ¤   else
e64859 ¤   ¤   ¤   ¤   ¤   {
221140 ¤   ¤   ¤   ¤   ¤   ¤   nextBlock = blockAfterData + blocksTaken;
4835bf ¤   ¤   ¤   ¤   ¤   ¤   usedUpReservedBlocks = TRUE;
13af5a
dbb8f0 ¤   ¤   ¤   ¤   ¤   ¤   // Exhausted bytes at beginning of file.
1cb393 ¤   ¤   ¤   ¤   ¤   ¤   if (IsntNull(curItem->prev))
678fec ¤   ¤   ¤   ¤   ¤   ¤   {
5fbf96 ¤   ¤   ¤   ¤   ¤   ¤   ¤   curItem->prev->hdr->nextHeaderOffset =·
ba7b75 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   blockAfterData * kDefaultBlockSize;
2edb3c ¤   ¤   ¤   ¤   ¤   ¤   }
73af5a
afc352 ¤   ¤   ¤   ¤   ¤   ¤   curItem->hdr->nextHeaderOffset = nextBlock *·
c23522 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kDefaultBlockSize;
a31c89 ¤   ¤   ¤   ¤   ¤   }
2c2613 ¤   ¤   ¤   ¤   }
45fa07 ¤   ¤   ¤   ¤   else
f972c3 ¤   ¤   ¤   ¤   {
352e67 ¤   ¤   ¤   ¤   ¤   nextBlock += blocksTaken;
70af5a
94b234 ¤   ¤   ¤   ¤   ¤   // Already after end of file.
63cabe ¤   ¤   ¤   ¤   ¤   curItem->hdr->nextHeaderOffset =·
4ce8ea ¤   ¤   ¤   ¤   ¤   ¤   nextBlock * kDefaultBlockSize;
fb2613 ¤   ¤   ¤   ¤   }
22a3a6 ¤   ¤   ¤   }
6caf5a
a89a3f ¤   ¤   ¤   curItem = nextItem;
890fe4 ¤   ¤   }
929371 ¤   }
e0af5a
4ada71 ¤   // Write out all the headers.
472361 ¤   if (derr.IsntError())
5ac7a1 ¤   {
4f312a ¤   ¤   PGPUInt64 curOffset;
b2af5a
6a19ab ¤   ¤   curItem = itemList;
86267b ¤   ¤   curOffset = 0;
54af5a
b9831d ¤   ¤   while (derr.IsntError() && IsntNull(curItem))
085b34 ¤   ¤   {
78e794 ¤   ¤   ¤   derr = WritePGPdiskFileHeaderAtOffset(diskFile, curOffset,·
a2c948 ¤   ¤   ¤   ¤   curItem->hdr);
61af5a
01dbe0 ¤   ¤   ¤   curOffset = curItem->hdr->nextHeaderOffset;
46782d ¤   ¤   ¤   curItem = curItem->next;
260fe4 ¤   ¤   }
b49371 ¤   }
16af5a
3ebf60 ¤   // Restore main and alternate header.
862361 ¤   if (derr.IsntError())
5dc7a1 ¤   {
7c8324 ¤   ¤   derr = diskFile->GetLength(&length);
499371 ¤   }
b7af5a
a52361 ¤   if (derr.IsntError())
d4c7a1 ¤   {
6c1870 ¤   ¤   mainHdr->numFileBlocks = (PGPUInt32) (length/kDefaultBlockSize +·
a8fa96 ¤   ¤   ¤   kPGPdiskAlternateHeaderBlocks);
3aaf5a
e7a40d ¤   ¤   derr = diskFile->SetLength(length + kPGPdiskAlternateHeaderBlocks *
e5ecb7 ¤   ¤   ¤   kDefaultBlockSize);
be9371 ¤   }
58af5a
6f2361 ¤   if (derr.IsntError())
68c7a1 ¤   {
3d1add ¤   ¤   derr = WritePGPdiskFileMainHeader(diskFile, mainHdr);
bb9371 ¤   }
16af5a
--ae59 000cdbe6be04011016d Page 9 of PGPdiskLowLevelUtils.cpp
dd33e3 ¤   return derr;
a2efe6 }
c9af5a
a6d14c // ReadPGPdiskFilePrimaryHeader reads in and verifies the primary PGPdisk
48799e // header.
3aaf5a
b5e677 DualErr
85323c ReadPGPdiskFilePrimaryHeader(File *diskFile, PGPdiskFileHeader **fileHeader)
c5bb36 {
f0be41 ¤   DualErr¤¤   derr;
b5cedc ¤   PGPBoolean¤ readHeader¤ = FALSE;
4a4831 ¤   PGPUInt64¤  bytesFile;
8baf5a
3d9137 ¤   pgpAssertAddrValid(diskFile, File);
7e1071 ¤   pgpAssert(diskFile->Opened());
367e20 ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader *);
96af5a
3108cd ¤   derr = ReadPGPdiskFileHeaderAtOffset(diskFile, 0,·
51830f ¤   ¤   (PGPdiskFileHeaderInfo **) fileHeader);
29af5a
01a08e ¤   readHeader = derr.IsntError();
20af5a
092361 ¤   if (derr.IsntError())
58c7a1 ¤   {
5b5701 ¤   ¤   derr = diskFile->GetLength(&bytesFile);
919371 ¤   }
05af5a
982361 ¤   if (derr.IsntError())
63c7a1 ¤   {
c6b42e ¤   ¤   derr = VerifyPGPdiskFileMainHeader((* fileHeader), bytesFile);
e79371 ¤   }
f4af5a
664bb3 ¤   if (derr.IsError())
bbc7a1 ¤   {
0287ff ¤   ¤   if (readHeader)
7169a3 ¤   ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) (* fileHeader));
759371 ¤   }
c6af5a
0533e3 ¤   return derr;
c7efe6 }
ceaf5a
b8dca0 // WritePGPdiskFilePrimaryHeader verifies and writes out the primary PGPdisk
f6d134 // file header to a PGPdisk file.
8eaf5a
f3e677 DualErr
dc51bc WritePGPdiskFilePrimaryHeader(
767082 ¤   File¤   ¤   ¤   ¤   ¤   *diskFile,·
283852 ¤   const PGPdiskFileHeader¤*fileHeader)
55bb36 {
95be41 ¤   DualErr¤¤   derr;
5c4831 ¤   PGPUInt64¤  bytesFile;
a667c5 ¤
429137 ¤   pgpAssertAddrValid(diskFile, File);
3a1071 ¤   pgpAssert(diskFile->Opened());
67e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
10af5a
5d4f51 ¤   derr = diskFile->GetLength(&bytesFile);
dfaf5a
312361 ¤   if (derr.IsntError())
67c7a1 ¤   {
bc8755 ¤   ¤   derr = WritePGPdiskFileHeaderAtOffset(diskFile, 0,·
d02824 ¤   ¤   ¤   (PGPdiskFileHeaderInfo *) fileHeader);
729371 ¤   }
20af5a
bc33e3 ¤   return derr;
abefe6 }
1faf5a
903c83 // ReadPGPdiskFileAlternateHeader reads in and verifies the alternate PGPdisk
bb799e // header.
edaf5a
c4e677 DualErr
cd4c07 ReadPGPdiskFileAlternateHeader(File *diskFile, PGPdiskFileHeader **fileHeader)
--c9c6 0008ed6dd454011016d Page 10 of PGPdiskLowLevelUtils.cpp
2cbb36 {
4bbe41 ¤   DualErr¤¤   derr;
c8cedc ¤   PGPBoolean¤ readHeader¤ = FALSE;
844831 ¤   PGPUInt64¤  bytesFile;
05af5a
f79137 ¤   pgpAssertAddrValid(diskFile, File);
c91071 ¤   pgpAssert(diskFile->Opened());
797e20 ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader *);
00af5a
cb4f51 ¤   derr = diskFile->GetLength(&bytesFile);
08af5a
c32361 ¤   if (derr.IsntError())
10c7a1 ¤   {
3f1d88 ¤   ¤   derr = ReadPGPdiskFileHeaderAtOffset(diskFile,·
0bb706 ¤   ¤   ¤   bytesFile - kPGPdiskAlternateHeaderSize,·
be154e ¤   ¤   ¤   (PGPdiskFileHeaderInfo **) fileHeader);
22af5a
cae17d ¤   ¤   readHeader = derr.IsntError();
ed9371 ¤   }
17af5a
c04bb3 ¤   if (derr.IsError())
f1c7a1 ¤   {
8887ff ¤   ¤   if (readHeader)
fc69a3 ¤   ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) (* fileHeader));
529371 ¤   }
ddaf5a
b133e3 ¤   return derr;
52efe6 }
28af5a
275fc8 // WritePGPdiskFileAlternateHeader verifies and writes out the alternate
b81879 // PGPdisk file header to a PGPdisk file.
3baf5a
5ee677 DualErr
c6de54 WritePGPdiskFileAlternateHeader(
187082 ¤   File¤   ¤   ¤   ¤   ¤   *diskFile,·
643852 ¤   const PGPdiskFileHeader¤*fileHeader)
b2bb36 {
26be41 ¤   DualErr¤¤   derr;
134831 ¤   PGPUInt64¤  bytesFile;
8567c5 ¤
e19137 ¤   pgpAssertAddrValid(diskFile, File);
641071 ¤   pgpAssert(diskFile->Opened());
61e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
77af5a
124f51 ¤   derr = diskFile->GetLength(&bytesFile);
e4af5a
562361 ¤   if (derr.IsntError())
e6c7a1 ¤   {
af7de7 ¤   ¤   // Alternate header is ALWAYS 'kPGPdiskAlternateHeaderSize' bytes
a32dcd ¤   ¤   // from the end of the file.
43af5a
674a31 ¤   ¤   derr = WritePGPdiskFileHeaderAtOffset(diskFile,·
e0b706 ¤   ¤   ¤   bytesFile - kPGPdiskAlternateHeaderSize,·
2d2824 ¤   ¤   ¤   (PGPdiskFileHeaderInfo *) fileHeader);
a19371 ¤   }
3e67c5 ¤
5533e3 ¤   return derr;
fdefe6 }
f6af5a
184e7d // VerifyPGPdiskFileMainHeader verifies certain fields of the given PGPdisk
cc441a // file header for a file of the given size.
37af5a
492292 DualErr·
bbb32d VerifyPGPdiskFileMainHeader(
0446ea ¤   const PGPdiskFileHeader¤*fileHeader,
e4cac4 ¤   PGPUInt64¤  ¤   ¤   ¤   bytesFile)
9abb36 {
bae0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
a71b52 ¤   ¤
876de6 ¤   if (strncmp(fileHeader->headerInfo.headerMagic, kPGPdiskHeaderMagic, 4)·
3e4bb5 ¤   ¤   != 0)
8ec7a1 ¤   {
--77f0 000ad28dacf4011016d Page 11 of PGPdiskLowLevelUtils.cpp
0cd0a5 ¤   ¤   return DualErr(kPGDMinorError_BadHeaderMagic);
1c9371 ¤   }
fbaf5a
b07e0c ¤   if (fileHeader->headerInfo.headerSize > sizeof(PGPdiskFileHeader))
adc7a1 ¤   {
c5a62b ¤   ¤   return DualErr(kPGDMinorError_BadHeaderSize);
a89371 ¤   }
93af5a
88a266 ¤   if (fileHeader->headerInfo.headerCRC !=·
a2fa5b ¤   ¤   ComputePGPdiskFileHeaderCRC((PGPdiskFileHeaderInfo *) fileHeader))
fdc7a1 ¤   {
0d787b ¤   ¤   return DualErr(kPGDMinorError_BadHeaderCRC);
9a9371 ¤   }
87af5a
a489c2 ¤   if (strncmp(fileHeader->headerInfo.headerType,·
f38dcf ¤   ¤   kPGPdiskPrimaryHeaderType, 4) != 0)
b8c7a1 ¤   {
1fe8cb ¤   ¤   return DualErr(kPGDMinorError_InvalidHeaderType);
bd9371 ¤   }
e5af5a
7d7114 ¤   if (fileHeader->majorVersion > kPGPdiskPrimaryHeaderMajorVersion)
06c7a1 ¤   {
6be6a9 ¤   ¤   return DualErr(kPGDMinorError_NewerHeaderVersion);
4f9371 ¤   }
a5af5a
78e3a4 ¤   if ((fileHeader->algorithm != kBrokenCASTEncryptionAlgorithm) &&·
35c218 ¤   ¤   (fileHeader->algorithm != kCASTEncryptionAlgorithm) &&·
c1c258 ¤   ¤   (fileHeader->algorithm != kCopyDataEncryptionAlgorithm))
52c7a1 ¤   {
81c901 ¤   ¤   return DualErr(kPGDMinorError_InvalidAlgorithm);
759371 ¤   }
f7af5a
1a4cc3 ¤   if ((PGPUInt64) fileHeader->numFileBlocks*kDefaultBlockSize != bytesFile)
e2c7a1 ¤   {
ded36b ¤   ¤   return DualErr(kPGDMinorError_InvalidTotalFileSize);
4d9371 ¤   }
7daf5a
0ddbfc ¤   if (fileHeader->numDataBlocks > fileHeader->numFileBlocks)
f3c7a1 ¤   {
546314 ¤   ¤   return DualErr(kPGDMinorError_InvalidFileDataSize);
839371 ¤   }
c9af5a
30c728 ¤   if (fileHeader->numHeaderBlocks + fileHeader->numDataBlocks >·
145716 ¤   ¤   fileHeader->numFileBlocks)
80c7a1 ¤   {
d553db ¤   ¤   return DualErr(kPGDMinorError_InvalidHeaderBlocks);
e79371 ¤   }
adaf5a
8e302b ¤   return DualErr::NoError;
ccefe6 }
8aaf5a
2650bc // ComputePGPdiskFileHeaderCRC computes and returns a checksum over the given
97c89a // PGPdisk file header.
b7af5a
1679a4 CRC32·
85187b ComputePGPdiskFileHeaderCRC(PGPdiskFileHeaderInfo *fileHeader)
aabb36 {
4eae8f ¤   CRC32¤  saveCRCValue;
f07741 ¤   CRC32¤  crc;
1b67c5 ¤
005320 ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeaderInfo);
36af5a
5eb087 ¤   // Always set CRC value to zero before computing.
e59700 ¤   saveCRCValue = fileHeader->headerCRC;
cc67c5 ¤
bfd6e8 ¤   fileHeader->headerCRC = 0;
2067c5 ¤
5d6c03 ¤   crc = ComputeCRC32((const PGPUInt32 *) fileHeader,·
2f87d7 ¤   ¤   fileHeader->headerSize / sizeof(PGPUInt32));
8f67c5 ¤
8d979f ¤   fileHeader->headerCRC = saveCRCValue;
ad67c5 ¤
--3d09 000af6116ee4011016d Page 12 of PGPdiskLowLevelUtils.cpp
7eba79 ¤   return crc;
14efe6 }
eeaf5a
fb6028 // UpdatePGPdiskFileHeaderCRC stores the checksum of the PGPdisk file header
fcca64 // in its 'headerCRC' member.
30af5a
d8c823 void·
aa76f6 UpdatePGPdiskFileHeaderCRC(PGPdiskFileHeaderInfo *fileHeader)
c4bb36 {
db5320 ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeaderInfo);
76af5a
6b8df8 ¤   fileHeader->headerCRC = ComputePGPdiskFileHeaderCRC(fileHeader);
a0efe6 }
b2af5a
13af5a
e4ed79 /////////////////////////////////////////
cb135e // Low-level passphrase utility functions
9ded79 /////////////////////////////////////////
7faf5a
4e2d33 // FindMatchingPassphrase determines if the specified passphrase is
75e81d // legitimate for any of the keys.
21af5a
b22292 DualErr·
5ed4fa FindMatchingPassphrase(
736d5e ¤   const PGPdiskFileHeader¤*fileHeader,·
8db415 ¤   SecureString¤   ¤   ¤   *passphrase,·
a7023d ¤   PGPUInt16¤  ¤   ¤   ¤   *index)
fabb36 {
44be41 ¤   DualErr¤¤   derr;
ca6036 ¤   PGPBoolean¤ foundKey¤   = FALSE;
0567c5 ¤
78e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
5dc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
8812d4 ¤   pgpAssertAddrValid(index, PGPUInt16);
95af5a
f14255 ¤   pgpAssert(kMasterPassphraseIndex == 0);
efaf5a
2cb2e2 ¤   for (PGPUInt16 keyIndex = 0; keyIndex <= kMaxAlternatePassphrases;·
987203 ¤   ¤   ++keyIndex)
a1c7a1 ¤   {
b87059 ¤   ¤   const PassphraseKey *userInfo = NULL;
14af5a
831a9d ¤   ¤   userInfo = GetPassphraseKeyPtr(fileHeader, keyIndex);
4aaf5a
cd7bf7 ¤   ¤   if (userInfo->inUse)
c65b34 ¤   ¤   {
534b6c ¤   ¤   ¤   derr = VerifyPassphraseKey(userInfo, &fileHeader->salt,·
f4d759 ¤   ¤   ¤   ¤   passphrase);
6eaf5a
7bc4f7 ¤   ¤   ¤   foundKey = derr.IsntError();
2aaf5a
2fbf49 ¤   ¤   ¤   if (foundKey)
59f776 ¤   ¤   ¤   {
8b1236 ¤   ¤   ¤   ¤   (* index) = keyIndex;
93f622 ¤   ¤   ¤   ¤   break;
85a3a6 ¤   ¤   ¤   }
eb0fe4 ¤   ¤   }
9a9371 ¤   }
c6af5a
57e8cf ¤   if (!foundKey)
5e9bbd ¤   ¤   derr = DualErr(kPGDMinorError_IncorrectPassphrase);
73af5a
4133e3 ¤   return derr;
cbefe6 }
bfaf5a
90c7e0 // GetPassphraseKeyPtr returns a pointer to the PassphraseKey corresponding to
e5a076 // the index.
f4af5a
e16ef5 const PassphraseKey *·
5d1bac GetPassphraseKeyPtr(
be6d5e ¤   const PGPdiskFileHeader¤*fileHeader,·
af4a0e ¤   PGPUInt16¤  ¤   ¤   ¤   whichPassphrase)
--77d1 000271ad2eb4011016d Page 13 of PGPdiskLowLevelUtils.cpp
2cbb36 {
6c499c ¤   const PassphraseKey *userInfo = NULL;
a767c5 ¤
ad1849 ¤   // 0 being master, 1...kMaxAlternatePassphrases alternates.
ec6579 ¤   pgpAssert(whichPassphrase <= kMaxAlternatePassphrases);
1d1b52 ¤   ¤
264098 ¤   if (whichPassphrase == kMasterPassphraseIndex)
c08ffb ¤   ¤   userInfo = &fileHeader->masterPassphrase;
e00e24 ¤   else
5d6230 ¤   ¤   userInfo = &fileHeader->otherPassphrases[whichPassphrase-1];
af87c7 ¤   ¤   ¤
abbb55 ¤   return userInfo;
30efe6 }
f4af5a
3ea13b // VerifyPassphraseKey verifies that the specified passphrase unlocks the
090904 // specified key.
23af5a
202292 DualErr·
0f2605 VerifyPassphraseKey(
d9f780 ¤   const PassphraseKey¤¤   *userInfo,·
f53d12 ¤   const PassphraseSalt¤   *salt,·
15867d ¤   SecureString¤   ¤   ¤   *passphrase)
febb36 {
5b945d ¤   DualErr¤derr;
2a8b7a ¤   CASTKey¤*decryptedKey;
5eaf5a
f51d27 ¤   SecureMemory smDecryptedKey(sizeof(CASTKey));
57af5a
54b05f ¤   pgpAssertAddrValid(userInfo, PassphraseKey);
5bc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
5df904 ¤   pgpAssertAddrValid(salt, PassphraseSalt);
6f2cd5 ¤   pgpAssert(userInfo->inUse);
9daf5a
3ac13e ¤   // Did we get our locked memory?
bb77cd ¤   derr = smDecryptedKey.mInitErr;
8daf5a
3f2361 ¤   if (derr.IsntError())
44c7a1 ¤   {
e2c398 ¤   ¤   // Set the locked memory pointer.
c1ec55 ¤   ¤   decryptedKey = (CASTKey *) smDecryptedKey.GetPtr();
fdaf5a
17140d ¤   ¤   // Attempt to decypt the key
630673 ¤   ¤   derr = DecryptPassphraseKey(userInfo, salt, passphrase,
dcb2da ¤   ¤   ¤   decryptedKey);
cd9371 ¤   }
7faf5a
3e33e3 ¤   return derr;
5eefe6 }
ddaf5a
6205cc // VerifyFileHeaderPassphrase verifies that a passphrase is valid for the
27267f // specified passphrase index in the specified header.
70af5a
f4e677 DualErr
afa85f VerifyFileHeaderPassphrase(
5e46ea ¤   const PGPdiskFileHeader¤*fileHeader,
7ef8c5 ¤   SecureString¤   ¤   ¤   *passphrase,
bc0c14 ¤   PGPUInt16¤  ¤   ¤   ¤   whichKey)
afbb36 {
f5705b ¤   DualErr¤¤   ¤   ¤   derr;
1f4337 ¤   const PassphraseKey¤*userInfo;
eb67c5 ¤
25e0ac ¤   pgpAssertAddrValid(fileHeader, PGPdiskFileHeader);
6dc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
9367c5 ¤
c30d9d ¤   userInfo = GetPassphraseKeyPtr(fileHeader, whichKey);
deaf5a
0542c1 ¤   if (!userInfo->inUse)
c89bbd ¤   ¤   derr = DualErr(kPGDMinorError_IncorrectPassphrase);
58af5a
342361 ¤   if (derr.IsntError())
f9c7a1 ¤   {
270ef5 ¤   ¤   derr = VerifyPassphraseKey(userInfo, &fileHeader->salt, passphrase);
--4269 00196ce739f4011016d Page 14 of PGPdiskLowLevelUtils.cpp
a19371 ¤   }
93af5a
0c33e3 ¤   return derr;
96efe6 }
--806a 000ff3f54254011016e Page 1 of PGPdiskLowLevelUtils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
d78ee0 // PGPdiskLowLevelUtils.h
5a465d //
0e2a61 // Declarations for PGPdiskLowLevelUtils.cpp.
b21bc3 //////////////////////////////////////////////////////////////////////////////
ecaf5a
06ee08 // $Id: PGPdiskLowLevelUtils.h,v 1.1.2.15 1998/08/04 02:10:20 nryan Exp $
6daf5a
74cbce // Copyright (C) 1998 by Network Associates, Inc.
5f71ae // All rights reserved.
ebaf5a
b0209d #ifndef¤Included_PGPdiskLowLevelUtils_h¤// [
3ddd45 #define¤Included_PGPdiskLowLevelUtils_h
dfaf5a
bb3db7 #include "FatUtils.h"
51c16a #include "PGPdiskFileFormat.h"
99af5a
8569ea #include "Cast5.h"
af8f51 #include "CipherUtils.h"
dfaf5a
34af5a
ebd557 ////////
4002c9 // Types
38d557 ////////
b6af5a
3e9bc8 class File;
06af5a
704476 typedef struct PGPdiskFileHeaderItem
a0bb36 {
e14e22 ¤   PGPdiskFileHeaderItem¤  *next;
0b4c3a ¤   PGPdiskFileHeaderItem¤  *prev;
e2af5a
964c09 ¤   PGPdiskFileHeaderInfo¤  *hdr;
bfaf5a
d1e051 } PGPdiskFileHeaderItem;
7faf5a
2faf5a
cb6cc2 /////////////////////
8f13d2 // Exported functions
596cc2 /////////////////////
21af5a
108f3f DualErr¤¤   ¤   ¤   ¤   MakeEmptyHeader(PGPUInt32 headerSize,·
f72f66 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderInfo **hdr);
84af5a
deed66 DualErr¤¤   ¤   ¤   ¤   CopyHeader(PGPdiskFileHeaderInfo *inHdr,·
48596b ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderInfo **outHdr);
c1af5a
ceb5e2 void¤   ¤   ¤   ¤   ¤   FreeHeader(PGPdiskFileHeaderInfo *hdr);
40af5a
282930 DualErr¤¤   ¤   ¤   ¤   ReadPGPdiskFileHeaderAtOffset(File *diskFile,·
cd3052 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt64 pos, PGPdiskFileHeaderInfo **hdr);
a7af5a
50363b DualErr¤¤   ¤   ¤   ¤   WritePGPdiskFileHeaderAtOffset(File *diskFile,·
3900c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt64 pos, PGPdiskFileHeaderInfo *hdr);
abaf5a
8450dc void¤   ¤   ¤   ¤   ¤   FreePGPdiskFileHeader(PGPdiskFileHeaderInfo *hdr);
f3af5a
7d5108 DualErr¤¤   ¤   ¤   ¤   MakeHeaderItem(PGPdiskFileHeaderItem **item);
068370 void¤   ¤   ¤   ¤   ¤   FreeHeaderItem(PGPdiskFileHeaderItem *item);
95af5a
022100 DualErr¤¤   ¤   ¤   ¤   InsertPGPdiskHeaderInList(
6149fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderItem *curItem,·
813bdf ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderInfo *newHdr);
b6af5a
069749 void¤   ¤   ¤   ¤   ¤   RemovePGPdiskHeaderFromList(
17d7c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderItem **itemToRemove);
24af5a
e423a8 DualErr¤¤   ¤   ¤   ¤   GetHeaderItemList(File *diskFile,·
63f892 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderItem **itemList);
2daf5a
3045fd void¤   ¤   ¤   ¤   ¤   FreeHeaderItemList(PGPdiskFileHeaderItem *itemList);
ffaf5a
--1ab6 0017153940a4011016e Page 2 of PGPdiskLowLevelUtils.h
cdae9a DualErr¤¤   ¤   ¤   ¤   UpdateHeaderItemList(File *diskFile,·
7ed669 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderItem *itemList);
e8af5a
47b10c DualErr¤¤   ¤   ¤   ¤   ReadPGPdiskFilePrimaryHeader(File *diskFile,·
af3dd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeader **fileHeader);
fcaf5a
7043e3 DualErr¤¤   ¤   ¤   ¤   WritePGPdiskFilePrimaryHeader(File *diskFile,·
38e3d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader);
37af5a
e4de7c DualErr¤¤   ¤   ¤   ¤   ReadPGPdiskFileAlternateHeader(File *diskFile,·
853dd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeader **fileHeader);
8aaf5a
6c60b0 DualErr¤¤   ¤   ¤   ¤   WritePGPdiskFileAlternateHeader(File *diskFile,·
d5e3d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader);
75af5a
4ff8fa DualErr¤¤   ¤   ¤   ¤   VerifyPGPdiskFileMainHeader(
85ff06 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader,·
9dfa21 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt64 bytesFile);
f6af5a
e7896e CRC32¤  ¤   ¤   ¤   ¤   ComputePGPdiskFileHeaderCRC(
69736b ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderInfo *fileHeader);
afaf5a
5c7d2d void¤   ¤   ¤   ¤   ¤   UpdatePGPdiskFileHeaderCRC(
04736b ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPdiskFileHeaderInfo *fileHeader);
91af5a
634195 DualErr¤¤   ¤   ¤   ¤   FindMatchingPassphrase(
1bff06 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader,·
057765 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SecureString *passphrase, PGPUInt16 *index);
77af5a
940ee5 const PassphraseKey *¤  GetPassphraseKeyPtr(
5cff06 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader,·
e38c8d ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt16 whichPassphrase);
8baf5a
291746 DualErr¤¤   ¤   ¤   ¤   VerifyPassphraseKey(const PassphraseKey *userInfo,·
eb591d ¤   ¤   ¤   ¤   ¤   ¤   ¤   const PassphraseSalt *salt,·
d9534f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SecureString *passphrase);
75af5a
bc3386 DualErr¤¤   ¤   ¤   ¤   VerifyFileHeaderPassphrase(
46a71c ¤   ¤   ¤   ¤   ¤   ¤   ¤   const PGPdiskFileHeader *fileHeader,
9d230e ¤   ¤   ¤   ¤   ¤   ¤   ¤   SecureString *passphrase, PGPUInt16 whichKey);
b9af5a
711e1f #endif¤ // ] Included_PGPdiskLowLevelUtils_h
--94c0 000cba36ffb4011016f Page 1 of PGPdiskPfl.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
aa33cc // PGPdiskPfl.cpp
be465d //
ac0ba6 // Code fixes to make the three PGPdisk projects work with a stock PFL.
b61bc3 //////////////////////////////////////////////////////////////////////////////
77af5a
9df40f // $Id: PGPdiskPfl.cpp,v 1.1.2.19 1998/08/04 02:10:21 nryan Exp $
a6af5a
e3cbce // Copyright (C) 1998 by Network Associates, Inc.
8f71ae // All rights reserved.
1eaf5a
6d9791 ////////////////
540d59 // Fixes for MFC
059791 ////////////////
69af5a
42b1b4 #if defined(PGPDISK_MFC)¤   ¤   ¤   // MFC
bcaf5a
4a9e12 #include "StdAfx.h"
259bcf #include "Required.h"
12af5a
7c90d6 // No fixes needed for MFC.
15af5a
988104 /////////////////////////////
1e8352 // Fixes for the Win95 driver
1f8104 /////////////////////////////
faaf5a
831b0b #elif defined(PGPDISK_95DRIVER)¤¤   // Win95 Driver
18af5a
cc06a9 #include <vtoolscp.h>
ea9bcf #include "Required.h"
0c86d2 #include LOCKED_CODE_SEGMENT
925269 #include LOCKED_DATA_SEGMENT
1eaf5a
f998e5 // _CrtDbgReport causes a blue-screen assert.
f4af5a
b3430d int¤
17d072 _CrtDbgReport(
6d1ede ¤   int¤¤   ¤   arg1,·
7f3b13 ¤   int¤¤   ¤   arg2,·
e227a8 ¤   int¤¤   ¤   arg3,·
867089 ¤   int¤¤   ¤   arg4,·
16cb39 ¤   const char¤ *format,·
765fa9 ¤   const char¤ *message)
cbbb36 {
cf0e9c ¤   static char debugMsg[kMaxStringSize];¤  // don't waste stack space!
0daf5a
721016 ¤   sprintf(debugMsg, format, message);
39cd2b ¤   dprintf(debugMsg);
82af5a
6c9324 ¤   SHELL_SYSMODAL_Message(Get_Sys_VM_Handle(), MB_SYSTEMMODAL, debugMsg,·
0a1bca ¤   ¤   "PGPdisk Message");
d567c5 ¤
1e64b7 ¤   return 1;
0defe6 }
dcaf5a
e90fcb // _CrtDbgBreak causes an 'int 3'.
acaf5a
4efcf4 int·
4dcb0e _CrtDbgBreak()
c5bb36 {
31e9c4 ¤   __asm int 3
90af5a
4964b7 ¤   return 1;
55efe6 }
fdaf5a
a6af5a
c68104 /////////////////////////////
a1349c // Fixes for the WinNT driver
358104 /////////////////////////////
f4af5a
c28213 #elif defined(PGPDISK_NTDRIVER)¤¤   // WinNT Driver
cbaf5a
--f620 0015a3c54d24011016f Page 2 of PGPdiskPfl.cpp
99d7a1 #include <vdw.h>
5ffeb2 #include <stdio.h>
79af5a
349bcf #include "Required.h"
e7af5a
2bf1f6 #include "KernelModeUtils.h"
bcaf5a
e6bdb9 // _CrtDbgReport outputs a debug string and breaks.
65af5a
20430d int¤
28d072 _CrtDbgReport(
281ede ¤   int¤¤   ¤   arg1,·
533b13 ¤   int¤¤   ¤   arg2,·
0c27a8 ¤   int¤¤   ¤   arg3,·
357089 ¤   int¤¤   ¤   arg4,·
53cb39 ¤   const char¤ *format,·
d95fa9 ¤   const char¤ *message)
5abb36 {
230e9c ¤   static char debugMsg[kMaxStringSize];¤  // don't waste stack space!
4baf5a
9943bf ¤   sprintf(debugMsg, (char *) format, message);
2bcf8a ¤   DbgPrint(debugMsg);
eeaf5a
169e2d ¤   // Pop-up dialog at passive level only.
97adeb ¤   if (KeGetCurrentIrql() == PASSIVE_LEVEL)
d6c7a1 ¤   {
4f18d1 ¤   ¤   KUstring uniErrString;
73af5a
a2aed3 ¤   ¤   AssignToUni(&uniErrString, debugMsg);
bdaf5a
b933d5 ¤   ¤   IoRaiseInformationalHardError(IO_ERR_DRIVER_ERROR, uniErrString,·
5c85b0 ¤   ¤   ¤   KeGetCurrentThread());
b69371 ¤   }
7caf5a
8064b7 ¤   return 1;
85efe6 }
22af5a
5fed56 // _CrtDbgBreak does nothing on NT.
e0af5a
f6fcf4 int·
57cb0e _CrtDbgBreak()
eabb36 {
6e64b7 ¤   return 1;
77efe6 }
90af5a
12db21 #else
d4112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
5a05d6 #endif¤ // PGPDISK_MFC
--c332 000d6fd880b40110170 Page 1 of PGPdiskPfl.h
541bc3 //////////////////////////////////////////////////////////////////////////////
01cd88 // PGPdiskPfl.h
bf465d //
aadb96 // Declarations for PGPdiskPfl.cpp.
1c1bc3 //////////////////////////////////////////////////////////////////////////////
17af5a
d0efd6 // $Id: PGPdiskPfl.h,v 1.1.2.13 1998/08/04 02:10:21 nryan Exp $
f1af5a
2ccbce // Copyright (C) 1998 by Network Associates, Inc.
de71ae // All rights reserved.
edaf5a
361d84 #ifndef Included_PGPdiskPfl_h¤  // [
8711d9 #define Included_PGPdiskPfl_h
d6af5a
aaaf5a
409791 ////////////////
e20d59 // Fixes for MFC
209791 ////////////////
e1af5a
7fb1b4 #if defined(PGPDISK_MFC)¤   ¤   ¤   // MFC
a7af5a
eb90d6 // No fixes needed for MFC.
12af5a
8eaf5a
da8104 /////////////////////////////
4c8352 // Fixes for the Win95 driver
178104 /////////////////////////////
bbaf5a
cf1b0b #elif defined(PGPDISK_95DRIVER)¤¤   // Win95 Driver
6aaf5a
0b4cdb // We need to 'roll our own' _CrtDbgReport.
30344b extern "C" int _CrtDbgReport(int arg1, int arg2, int arg3, int arg4,·
a8cb2d ¤   ¤   ¤   ¤   const char *format, const char* message);
eeaf5a
f62870 // We need to 'roll our own' _CrtDbgBreak.
3fd400 extern "C" int¤ _CrtDbgBreak();
deaf5a
94af5a
a88104 /////////////////////////////
71349c // Fixes for the WinNT driver
638104 /////////////////////////////
c4af5a
aaf5a6 #elif defined(PGPDISK_NTDRIVER)
72af5a
ce79d1 #include "OperatorNewFixups.h"
9eaf5a
bf4cdb // We need to 'roll our own' _CrtDbgReport.
ffeead int¤_CrtDbgReport(int arg1, int arg2, int arg3, int arg4,·
47665b ¤   ¤   const char *format, const char* message);
47af5a
cd2870 // We need to 'roll our own' _CrtDbgBreak.
3b5cd0 int¤_CrtDbgBreak();
38af5a
20db21 #else
36112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
eb05d6 #endif¤ // PGPDISK_MFC
5daf5a
c7af5a
9b7606 ///////////////
ba7710 // Common fixes
027606 ///////////////
b2af5a
d5c5d5 #include "pgpBase.h"
f4675a #include "pgpTypes.h"
95a146 #include "pgpDebug.h"
a194a0 #include "pgpLeaks.h"
e10d08 #include "pgpMem.h"
10af5a
76e9dd // VC doesn't allow structure definitions within parentheses. 'Alignof' dies.
6affb5 #undef¤ alignof
2bcdd2 #define¤alignof(type) (1)
d6af5a
--b479 001f9d016d740110170 Page 2 of PGPdiskPfl.h
f96c5d #endif¤ // ] Included_PGPdiskPfl_h
--a64f 0008e3e5fdd40110171 Page 1 of PGPdiskPublicKeyUtils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
c1365a // PGPdiskPublicKeyUtils.cpp
75465d //
6c2642 // Utility functions for working with public keys and PGPdisks.
4e1bc3 //////////////////////////////////////////////////////////////////////////////
a5af5a
be39cf // $Id: PGPdiskPublicKeyUtils.cpp,v 1.1.2.20.2.3 1998/10/28 01:42:35 nryan Exp $
1eaf5a
8ccbce // Copyright (C) 1998 by Network Associates, Inc.
1a71ae // All rights reserved.
92af5a
c56931 #if defined(PGPDISK_MFC)
18af5a
d19e12 #include "StdAfx.h"
3eb8af #include <new.h>
27af5a
d94268 #elif defined(PGPDISK_95DRIVER)
e7af5a
0606a9 #include <vtoolscp.h>
923a08 #include "PlacementNew.h"
4786d2 #include LOCKED_CODE_SEGMENT
6f5269 #include LOCKED_DATA_SEGMENT
b6af5a
f0f5a6 #elif defined(PGPDISK_NTDRIVER)
40af5a
42d7a1 #include <vdw.h>
7caf5a
dfdb21 #else
ff112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
f305d6 #endif¤ // PGPDISK_MFC
d9af5a
919bcf #include "Required.h"
93af5a
eaea4b #if PGPDISK_PUBLIC_KEY
c7af5a
8cb2b1 #include "PGPclx.h"
3de8b2 #include "pflPrefs.h"
cb4720 #include "pflPrefTypes.h"
913991 #include "pgpAdminPrefs.h"
e72f8d #include "pgpErrors.h"
cc42aa #include "pgpPublicKey.h"
054919 #include "pgpUtilities.h"
3faf5a
df7414 #include "PGPdiskHighLevelUtils.h"
3e2229 #include "PGPdiskLowLevelUtils.h"
d0f4f6 #include "PGPdiskPublicKeyUtils.h"
a270d4 #include "SecureMemory.h"
4ebfe9 #include "UtilityFunctions.h"
51af5a
bef037 #include "File.h"
aeaf5a
61af5a
43af5a
6f09b7 ////////////
9ae738 // Constants
c609b7 ////////////
69af5a
9ccf59 static LPCSTR kPGPdiskPassesWipedId = "WIPED";
7eaf5a
3baf5a
61c7c6 ///////////////////////////////
1ae1c0 // Public key utility functions
adc7c6 ///////////////////////////////
4daf5a
159f21 // HavePGPsdk returns TRUE if the SDK is available for use, FALSE otherwise.
e1af5a
c077be PGPBoolean·
9f6d15 HavePGPsdk()
6bbb36 {
2b49d9 ¤   static PGPBoolean¤  inited¤ = FALSE;
d57aa1 ¤   static PGPBoolean¤  haveSDK¤= FALSE;
8e67c5 ¤
--137f 00039f6de9840110171 Page 2 of PGPdiskPublicKeyUtils.cpp
64a003 ¤   if (!inited)
85c7a1 ¤   {
8f708a ¤   ¤   PGPContextRef context;
bbaf5a
1463e6 ¤   ¤   inited = TRUE;
4687c7 ¤   ¤   ¤
ad229d ¤   ¤   if (IsntPGPError(PGPNewContext(kPGPsdkAPIVersion, &context)))
e45b34 ¤   ¤   {
4f60c9 ¤   ¤   ¤   haveSDK = TRUE;
eb2b85 ¤   ¤   ¤   ¤
8303e4 ¤   ¤   ¤   PGPFreeContext(context);
3a0fe4 ¤   ¤   }
019371 ¤   }
c667c5 ¤
958c0f ¤   return haveSDK;
b5efe6 }
74af5a
8986d7 // DoesPGPdiskHavePublicKey returns TRUE if the specified PGPdisk has a
0a921a // public key passphrase, FALSE otherwise.
5faf5a
4a77be PGPBoolean·
5580d9 DoesPGPdiskHavePublicKey(LPCSTR path)
64bb36 {
0e9f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
742eee ¤   File¤   ¤   ¤   ¤   ¤   diskFile;
c3d871 ¤   PGPBoolean¤ ¤   ¤   ¤   gotItemList, hasPublicKey;
6a1a01 ¤   PGPdiskFileHeaderItem¤  *curItem, *itemList;
4faf5a
6b0964 ¤   gotItemList = hasPublicKey = FALSE;
2aaf5a
66639f ¤   pgpAssertStrValid(path);
baaf5a
c39e67 ¤   // Open the PGPdisk.
5c8be9 ¤   derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
4daf5a
31d314 ¤   // Get list of headers.
8f2361 ¤   if (derr.IsntError())
78c7a1 ¤   {
710032 ¤   ¤   derr = GetHeaderItemList(&diskFile, &itemList);
6170bb ¤   ¤   gotItemList = derr.IsntError();
ee9371 ¤   }
b1af5a
d46a9d ¤   // Look for a public key header.
a42361 ¤   if (derr.IsntError())
20c7a1 ¤   {
9a19ab ¤   ¤   curItem = itemList;
76af5a
a98ccc ¤   ¤   while (IsntNull(curItem))
1f5b34 ¤   ¤   {
ae7766 ¤   ¤   ¤   if (IsPublicKeyHeader(curItem->hdr))
0cf776 ¤   ¤   ¤   {
de1f87 ¤   ¤   ¤   ¤   hasPublicKey = TRUE;
94f622 ¤   ¤   ¤   ¤   break;
cfa3a6 ¤   ¤   ¤   }
e6af5a
dd782d ¤   ¤   ¤   curItem = curItem->next;
f10fe4 ¤   ¤   }
159371 ¤   }
bbaf5a
f43020 ¤   if (gotItemList)
b8a68d ¤   ¤   FreeHeaderItemList(itemList);
2aaf5a
e1d27f ¤   if (diskFile.Opened())
70d016 ¤   ¤   diskFile.Close();
70af5a
074bb3 ¤   if (derr.IsError())
9e98aa ¤   ¤   return FALSE;
450e24 ¤   else
9db631 ¤   ¤   return hasPublicKey;
8aefe6 }
f6af5a
391ae4 // IsKeyIDMemberOfRecipList returns TRUE if the given key ID corresponds to a
--c244 0000777c01640110171 Page 3 of PGPdiskPublicKeyUtils.cpp
fb5572 // key in the given recipient list, FALSE otherwise.
6faf5a
4c2292 DualErr·
dd01d7 IsKeyIDMemberOfRecipList(
bb4056 ¤   PGPKeyID¤   ¤   ¤   goalKeyID,·
7b324e ¤   PGPRecipientSpec¤   *recipList,·
659199 ¤   PGPUInt32¤  ¤   ¤   size,·
678b26 ¤   PGPBoolean¤ ¤   ¤   *isMember)
24bb36 {
5ebe41 ¤   DualErr¤¤   derr;
940721 ¤   PGPUInt32¤  i;
e2af5a
de8fea ¤   pgpAssertAddrValid(recipList, PGPRecipientSpec);
e66942 ¤   pgpAssertAddrValid(isMember, PGPBoolean);
8daf5a
203e9f ¤   (* isMember) = FALSE;
0caf5a
3e7e98 ¤   // For every recipient spec...
2509c7 ¤   for (i = 0; i < size; i++)
8fc7a1 ¤   {
5e263a ¤   ¤   PGPKeyID keyID;
84af5a
2f7632 ¤   ¤   // ... if its key ID equals goal key ID, goal key is a member.
7583d4 ¤   ¤   switch (recipList[i].type)
265b34 ¤   ¤   {
537ea3 ¤   ¤   case kPGPRecipientSpecType_Key:
f6af5a
f20a59 ¤   ¤   ¤   pgpAssert(PGPKeyRefIsValid(recipList[i].u.key));
1bb5ac ¤   ¤   ¤   derr = PGPGetKeyIDFromKey(recipList[i].u.key, &keyID);
65af5a
7f9d3d ¤   ¤   ¤   if (derr.IsntError())
85f776 ¤   ¤   ¤   {
c9fa7c ¤   ¤   ¤   ¤   if (PGPCompareKeyIDs(&keyID, &goalKeyID) == 0)
1f1371 ¤   ¤   ¤   ¤   ¤   (* isMember) = TRUE;
88a3a6 ¤   ¤   ¤   }
46af5a
d0cdcb ¤   ¤   ¤   break;
49af5a
009203 ¤   ¤   case kPGPRecipientSpecType_KeyID:
31af5a
304b87 ¤   ¤   ¤   if (PGPCompareKeyIDs(&recipList[i].u.id.keyID, &goalKeyID) == 0)
ae169c ¤   ¤   ¤   ¤   (* isMember) = TRUE;
00af5a
00cdcb ¤   ¤   ¤   break;
70af5a
6c9ae3 ¤   ¤   default:
bacdcb ¤   ¤   ¤   break;
cf0fe4 ¤   ¤   }
caaf5a
09eb1c ¤   ¤   if ((* isMember) || derr.IsError())
5dcdcb ¤   ¤   ¤   break;
b79371 ¤   }
b0af5a
ba33e3 ¤   return derr;
2befe6 }
88af5a
ef88ba // AddRecipientSpecToList adds a single PGPRecipientSpec to the given array.
26af5a
eb2292 DualErr·
b84718 AddRecipientSpecToList(PGPRecipientSpec **recipList, PGPUInt32 size)
d1bb36 {
7c705b ¤   DualErr¤¤   ¤   ¤   derr;
a61a4d ¤   PGPRecipientSpec¤   *newList;
1caf5a
59f767 ¤   pgpAssertAddrValid(recipList, PGPRecipientSpec *);
bdaf5a
0178f1 ¤   try
aac7a1 ¤   {
942fef ¤   ¤   newList = new PGPRecipientSpec[size + 1];
369371 ¤   }
6a3c88 ¤   catch (CMemoryException *ex)
07c7a1 ¤   {
--9f47 0000ad6df2e40110171 Page 4 of PGPdiskPublicKeyUtils.cpp
d7ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
e66adc ¤   ¤   ex->Delete();
0c9371 ¤   }
b1af5a
4b2361 ¤   if (derr.IsntError())
30c7a1 ¤   {
4542d7 ¤   ¤   pgpClearMemory((void *) &newList[size], sizeof(PGPRecipientSpec));
5baf5a
6f9668 ¤   ¤   if (size > 0)
725b34 ¤   ¤   {
ce2f2a ¤   ¤   ¤   pgpCopyMemory((* recipList), newList,·
8d040e ¤   ¤   ¤   ¤   sizeof(PGPRecipientSpec) * size);
36af5a
d7a32a ¤   ¤   ¤   delete[] (* recipList);
cf0fe4 ¤   ¤   }
67af5a
2cc421 ¤   ¤   (* recipList) = newList;
379371 ¤   }
e6af5a
8933e3 ¤   return derr;
68efe6 }
91af5a
bb5308 // FreeRecipientSpecList frees a list of recipient specs and the keys within.
0faf5a
7bc823 void·
8ff4aa FreeRecipientSpecList(PGPRecipientSpec *recipList, PGPUInt32 size)
05bb36 {
fbacf2 ¤   if (size > 0)
d6c7a1 ¤   {
2ce0d9 ¤   ¤   pgpAssertAddrValid(recipList, PGPRecipientSpec);
579b13 ¤   ¤   delete[] recipList;
b49371 ¤   }
faefe6 }
68af5a
b69068 // GetPGPdiskRecipKeys returns a list of the public keys associated with a
3041a0 // PGPdisk.
ffaf5a
9e2292 DualErr·
94aa79 GetPGPdiskRecipKeys(
b338df ¤   LPCSTR¤ ¤   ¤   ¤   path,·
f75a0a ¤   PGPContextRef¤  ¤   context,·
7cf2f7 ¤   PGPKeySetRef¤   ¤   allKeys,·
29b46f ¤   PGPRecipientSpec¤   **pDiskRecipKeys,·
22322e ¤   PGPUInt32¤  ¤   ¤   *pNumRecipKeys)
e2bb36 {
722eee ¤   File¤   ¤   ¤   ¤   ¤   diskFile;
1e9f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
7012f3 ¤   PGPBoolean¤ ¤   ¤   ¤   gotAnyRecips, gotItemList;
991a01 ¤   PGPdiskFileHeaderItem¤  *curItem, *itemList;
c09dac ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr;
a7df2d ¤   PGPRecipientSpec¤   ¤   *diskRecipKeys;
a987d4 ¤   PGPUInt32¤  ¤   ¤   ¤   numRecipKeys;
6faf5a
632da4 ¤   gotAnyRecips = gotItemList = FALSE;
16af5a
59639f ¤   pgpAssertStrValid(path);
d64326 ¤   pgpAssert(PGPContextRefIsValid(context));
9bbf3a ¤   pgpAssert(PGPKeySetRefIsValid(allKeys));
dac04e ¤   pgpAssertAddrValid(pDiskRecipKeys, PGPRecipientSpec *);
04befd ¤   pgpAssertAddrValid(pNumRecipKeys, PGPUInt32);
a1af5a
a04d9a ¤   (* pNumRecipKeys) = numRecipKeys = 0;
ecaf5a
9e9e67 ¤   // Open the PGPdisk.
3e8be9 ¤   derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
76af5a
8cd314 ¤   // Get list of headers.
552361 ¤   if (derr.IsntError())
86c7a1 ¤   {
660032 ¤   ¤   derr = GetHeaderItemList(&diskFile, &itemList);
fd70bb ¤   ¤   gotItemList = derr.IsntError();
0a9371 ¤   }
--ea66 0007615534740110171 Page 5 of PGPdiskPublicKeyUtils.cpp
e0af5a
6a2361 ¤   if (derr.IsntError())
cbc7a1 ¤   {
7219ab ¤   ¤   curItem = itemList;
1baf5a
3f6ec7 ¤   ¤   // Extract key from each public key header.
32831d ¤   ¤   while (derr.IsntError() && IsntNull(curItem))
895b34 ¤   ¤   {
1ed332 ¤   ¤   ¤   PGPByte¤¤   ¤   ¤   *exportedKeyID;
2aa48c ¤   ¤   ¤   PGPKeyID¤   ¤   ¤   keyID;
67cb1f ¤   ¤   ¤   PGPKeyRef¤  ¤   ¤   curKey;
b55bfd ¤   ¤   ¤   PGPRecipientSpec¤   *curRecipSpec;
10af5a
107766 ¤   ¤   ¤   if (IsPublicKeyHeader(curItem->hdr))
e8f776 ¤   ¤   ¤   {
97b23d ¤   ¤   ¤   ¤   pubKeyHdr = (PGPdiskPublicKeyHeader *) curItem->hdr;
90af5a
3fa232 ¤   ¤   ¤   ¤   exportedKeyID = (PGPByte *) pubKeyHdr +·
24310b ¤   ¤   ¤   ¤   ¤   pubKeyHdr->keyIDOffset;
7caf5a
737c6e ¤   ¤   ¤   ¤   // Create new recip spec.
2b77d8 ¤   ¤   ¤   ¤   derr = AddRecipientSpecToList(&diskRecipKeys, numRecipKeys);
c1af5a
6c1741 ¤   ¤   ¤   ¤   if (!gotAnyRecips)
a7427e ¤   ¤   ¤   ¤   ¤   gotAnyRecips = derr.IsntError();
c3af5a
0f724e ¤   ¤   ¤   ¤   if (derr.IsntError())
f572c3 ¤   ¤   ¤   ¤   {
8fea47 ¤   ¤   ¤   ¤   ¤   // Get pointer to current recip spec.
f69dfa ¤   ¤   ¤   ¤   ¤   curRecipSpec = &diskRecipKeys[numRecipKeys++];
a2af5a
46c44d ¤   ¤   ¤   ¤   ¤   // Read in key ID.
ef6736 ¤   ¤   ¤   ¤   ¤   derr = PGPImportKeyID(exportedKeyID, &keyID);
262613 ¤   ¤   ¤   ¤   }
34af5a
143985 ¤   ¤   ¤   ¤   // If actual key found, add key ref to spec, else add ID.
28724e ¤   ¤   ¤   ¤   if (derr.IsntError())
3d72c3 ¤   ¤   ¤   ¤   {
5492d7 ¤   ¤   ¤   ¤   ¤   DualErr keyInRingErr;
adaf5a
950991 ¤   ¤   ¤   ¤   ¤   keyInRingErr = PGPGetKeyByKeyID(allKeys, &keyID,·
acf8fc ¤   ¤   ¤   ¤   ¤   ¤   pubKeyHdr->algorithm, &curKey);
0daf5a
f1dbc2 ¤   ¤   ¤   ¤   ¤   if (keyInRingErr.IsntError())
774859 ¤   ¤   ¤   ¤   ¤   {
ab747e ¤   ¤   ¤   ¤   ¤   ¤   curRecipSpec->type = kPGPRecipientSpecType_Key;
934e29 ¤   ¤   ¤   ¤   ¤   ¤   curRecipSpec->locked = pubKeyHdr->locked;
2baf5a
9b38fd ¤   ¤   ¤   ¤   ¤   ¤   curRecipSpec->u.key = curKey;
881c89 ¤   ¤   ¤   ¤   ¤   }
8d4bd6 ¤   ¤   ¤   ¤   ¤   else
bd4859 ¤   ¤   ¤   ¤   ¤   {
e1d779 ¤   ¤   ¤   ¤   ¤   ¤   curRecipSpec->type = kPGPRecipientSpecType_KeyID;
d14e29 ¤   ¤   ¤   ¤   ¤   ¤   curRecipSpec->locked = pubKeyHdr->locked;
61af5a
78ab72 ¤   ¤   ¤   ¤   ¤   ¤   curRecipSpec->u.id.keyID = keyID;
e684d9 ¤   ¤   ¤   ¤   ¤   ¤   curRecipSpec->u.id.algorithm = pubKeyHdr->algorithm;
5d1c89 ¤   ¤   ¤   ¤   ¤   }
53af5a
e68d79 ¤   ¤   ¤   ¤   #if !PGP_BUSINESS_SECURITY
3a43c0 ¤   ¤   ¤   ¤   ¤   // No locked keys in personal build.
b3f758 ¤   ¤   ¤   ¤   ¤   curRecipSpec->locked = FALSE;
373ff9 ¤   ¤   ¤   ¤   #endif // !PGP_BUSINESS_SECURITY
51af5a
672613 ¤   ¤   ¤   ¤   }
c1a3a6 ¤   ¤   ¤   }
01af5a
f0782d ¤   ¤   ¤   curItem = curItem->next;
250fe4 ¤   ¤   }
519371 ¤   }
68af5a
762361 ¤   if (derr.IsntError())
--2679 000b084185640110171 Page 6 of PGPdiskPublicKeyUtils.cpp
f7c7a1 ¤   {
10cdb7 ¤   ¤   (* pDiskRecipKeys) = diskRecipKeys;
b27999 ¤   ¤   (* pNumRecipKeys) = numRecipKeys;
b29371 ¤   }
ffaf5a
722f6f ¤   // Cleanup on error.
e74bb3 ¤   if (derr.IsError())
88c7a1 ¤   {
1e8db1 ¤   ¤   if (gotAnyRecips)
84d381 ¤   ¤   ¤   FreeRecipientSpecList(diskRecipKeys, numRecipKeys);
1c9371 ¤   }
8faf5a
d43020 ¤   if (gotItemList)
b7a68d ¤   ¤   FreeHeaderItemList(itemList);
6daf5a
fad27f ¤   if (diskFile.Opened())
71d016 ¤   ¤   diskFile.Close();
88af5a
9c33e3 ¤   return derr;
07efe6 }
a9af5a
98694b // UpdatePGPdiskPublicKeys updates the public keys headers on a PGPdisk.
80af5a
c82292 DualErr·
722e0f UpdatePGPdiskPublicKeys(
2638df ¤   LPCSTR¤ ¤   ¤   ¤   path,·
b85b18 ¤   SecureString¤   ¤   *masterPassphrase,·
155a0a ¤   PGPContextRef¤  ¤   context,·
77f2f7 ¤   PGPKeySetRef¤   ¤   allKeys,·
765937 ¤   PGPRecipientSpec¤   *newRecipKeys,·
0eaaa3 ¤   PGPUInt32¤  ¤   ¤   numRecipKeys,·
1f292a ¤   PGPBoolean¤ ¤   ¤   newKeysReadOnly)
cdbb36 {
f52eee ¤   File¤   ¤   ¤   ¤   ¤   diskFile;
192fdb ¤   CASTKey¤¤   ¤   ¤   ¤   *decryptedKey;
d59f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
cebed1 ¤   PGPBoolean¤ ¤   ¤   ¤   gotItemList¤= FALSE;
9696af ¤   PGPdiskFileHeader¤  ¤   *mainHeader;
6d1a01 ¤   PGPdiskFileHeaderItem¤  *curItem, *itemList;
da9dac ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr;
a6e7d1 ¤   PGPKeyRef¤  ¤   ¤   ¤   curKey;
09de7c ¤   PGPUInt32¤  ¤   ¤   ¤   i;
5baf5a
5cad5f ¤   SecureMemory¤   smDecryptedKey(sizeof(CASTKey));
ebaf5a
ba639f ¤   pgpAssertStrValid(path);
8dda2a ¤   pgpAssertAddrValid(masterPassphrase, SecureString);
ff4326 ¤   pgpAssert(PGPContextRefIsValid(context));
72bf3a ¤   pgpAssert(PGPKeySetRefIsValid(allKeys));
83129c ¤   pgpAssertAddrValid(newRecipKeys, PGPRecipientSpec);
faaf5a
5dc13e ¤   // Did we get our locked memory?
0877cd ¤   derr = smDecryptedKey.mInitErr;
b6af5a
b12361 ¤   if (derr.IsntError())
25c7a1 ¤   {
97c398 ¤   ¤   // Set the locked memory pointer.
e0ec55 ¤   ¤   decryptedKey = (CASTKey *) smDecryptedKey.GetPtr();
72af5a
3daa3a ¤   ¤   // Open the PGPdisk.
91551c ¤   ¤   derr = diskFile.Open(path, kOF_MustExist);
639371 ¤   }
62af5a
add314 ¤   // Get list of headers.
272361 ¤   if (derr.IsntError())
63c7a1 ¤   {
990032 ¤   ¤   derr = GetHeaderItemList(&diskFile, &itemList);
4370bb ¤   ¤   gotItemList = derr.IsntError();
a29371 ¤   }
09af5a
ba2361 ¤   if (derr.IsntError())
b0c7a1 ¤   {
--2539 0005e6218f940110171 Page 7 of PGPdiskPublicKeyUtils.cpp
8c2f0b ¤   ¤   // Get main header pointer.
f4fe42 ¤   ¤   mainHeader = (PGPdiskFileHeader *) itemList->hdr;
34af5a
1904b3 ¤   ¤   // Decrypt the master key
f42147 ¤   ¤   derr = DecryptPassphraseKey(&mainHeader->masterPassphrase,·
0eeef6 ¤   ¤   ¤   &mainHeader->salt, masterPassphrase, decryptedKey);
e79371 ¤   }
60af5a
bbb842 ¤   // Add keys not in the PGPdisk to the PGPdisk.
282361 ¤   if (derr.IsntError())
9dc7a1 ¤   {
549a46 ¤   ¤   // For each recipient spec...
980e9d ¤   ¤   for (i = 0; i < numRecipKeys; i++)
1a5b34 ¤   ¤   {
aff69e ¤   ¤   ¤   // ... if it is a key ref...
61520f ¤   ¤   ¤   if ((newRecipKeys[i].type) == kPGPRecipientSpecType_Key)
92f776 ¤   ¤   ¤   {
72f7b6 ¤   ¤   ¤   ¤   curKey = newRecipKeys[i].u.key;
e6b812 ¤   ¤   ¤   ¤   pgpAssert(PGPKeyRefIsValid(curKey));
1aaf5a
6615ce ¤   ¤   ¤   ¤   // ... and if not in header list...
41741f ¤   ¤   ¤   ¤   derr = FindPublicKeyInHeaderList(&diskFile, context, curKey,·
2c5b18 ¤   ¤   ¤   ¤   ¤   itemList, &curItem);
70af5a
aea1f5 ¤   ¤   ¤   ¤   if (derr.IsntError() && IsNull(curItem))
8472c3 ¤   ¤   ¤   ¤   {
28c499 ¤   ¤   ¤   ¤   ¤   // Create a new header for it.
cd2ccc ¤   ¤   ¤   ¤   ¤   derr = CreatePublicKeyHeader(context, curKey,·
9a6564 ¤   ¤   ¤   ¤   ¤   ¤   decryptedKey, FALSE, newKeysReadOnly, &pubKeyHdr);
baaf5a
c45d60 ¤   ¤   ¤   ¤   ¤   // ...insert the new header after the main header.
574ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
d44859 ¤   ¤   ¤   ¤   ¤   {
951ede ¤   ¤   ¤   ¤   ¤   ¤   derr = InsertPGPdiskHeaderInList(itemList,·
83a1e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPdiskFileHeaderInfo *) pubKeyHdr);
b31c89 ¤   ¤   ¤   ¤   ¤   }
e72613 ¤   ¤   ¤   ¤   }
0ea3a6 ¤   ¤   ¤   }
750fe4 ¤   ¤   }
f39371 ¤   }
f1af5a
5a6256 ¤   // Remove keys not in the key list from the PGPdisk.
fa2361 ¤   if (derr.IsntError())
f9c7a1 ¤   {
c419ab ¤   ¤   curItem = itemList;
13af5a
3ea5fe ¤   ¤   // For every header...
d2831d ¤   ¤   while (derr.IsntError() && IsntNull(curItem))
b75b34 ¤   ¤   {
6b75ce ¤   ¤   ¤   PGPBoolean¤ isMember;
4458ea ¤   ¤   ¤   PGPByte¤¤   *exportedKeyID;
fbb97f ¤   ¤   ¤   PGPKeyID¤   keyID;
09af5a
cd8e4d ¤   ¤   ¤   // ...if it's a public key header...
3d7766 ¤   ¤   ¤   if (IsPublicKeyHeader(curItem->hdr))
63f776 ¤   ¤   ¤   {
dab23d ¤   ¤   ¤   ¤   pubKeyHdr = (PGPdiskPublicKeyHeader *) curItem->hdr;
b2af5a
e7a232 ¤   ¤   ¤   ¤   exportedKeyID = (PGPByte *) pubKeyHdr +·
4c310b ¤   ¤   ¤   ¤   ¤   pubKeyHdr->keyIDOffset;
2eaf5a
0185be ¤   ¤   ¤   ¤   // Read in key ID.
3fdb2f ¤   ¤   ¤   ¤   derr = PGPImportKeyID(exportedKeyID, &keyID);
fbaf5a
daaaf1 ¤   ¤   ¤   ¤   // ... and isn't in the list, remove it from PGPdisk.
7b724e ¤   ¤   ¤   ¤   if (derr.IsntError())
cf72c3 ¤   ¤   ¤   ¤   {
11c9f5 ¤   ¤   ¤   ¤   ¤   derr = IsKeyIDMemberOfRecipList(keyID, newRecipKeys,·
c9c37f ¤   ¤   ¤   ¤   ¤   ¤   numRecipKeys, &isMember);
6d2613 ¤   ¤   ¤   ¤   }
50af5a
5e724e ¤   ¤   ¤   ¤   if (derr.IsntError())
--c8db 00051e1359140110171 Page 8 of PGPdiskPublicKeyUtils.cpp
d072c3 ¤   ¤   ¤   ¤   {
af3061 ¤   ¤   ¤   ¤   ¤   if (!isMember)
73382c ¤   ¤   ¤   ¤   ¤   ¤   RemovePGPdiskHeaderFromList(&curItem);
fd2613 ¤   ¤   ¤   ¤   }
cca3a6 ¤   ¤   ¤   }
87af5a
f41db8 ¤   ¤   ¤   if (IsntNull(curItem))
df7dc0 ¤   ¤   ¤   ¤   curItem = curItem->next;
530fe4 ¤   ¤   }
f69371 ¤   }
61af5a
fa2847 ¤   // Write out the updated headers to the PGPdisk.
0d2361 ¤   if (derr.IsntError())
68c7a1 ¤   {
150f3b ¤   ¤   derr = UpdateHeaderItemList(&diskFile, itemList);
579371 ¤   }
87af5a
a03020 ¤   if (gotItemList)
03a68d ¤   ¤   FreeHeaderItemList(itemList);
d3af5a
38d27f ¤   if (diskFile.Opened())
52d016 ¤   ¤   diskFile.Close();
c6af5a
7933e3 ¤   return derr;
69efe6 }
4eaf5a
7f66b2 // FindPublicKeyInHeaderList finds the header item in the given list, if any,·
d18f33 // that corresponds to the given public key.
16af5a
f32292 DualErr·
912cec FindPublicKeyInHeaderList(
cb7082 ¤   File¤   ¤   ¤   ¤   ¤   *diskFile,·
d440e0 ¤   PGPContextRef¤  ¤   ¤   context,·
dfeb3f ¤   PGPKeyRef¤  ¤   ¤   ¤   curKey,·
7096e8 ¤   PGPdiskFileHeaderItem¤  *itemList,·
96ba7c ¤   PGPdiskFileHeaderItem¤  **keyItem)
10bb36 {
e39f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
8ba0a6 ¤   PGPdiskFileHeaderItem¤  *curItem;
ac9dac ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr;
66a211 ¤   PGPKeyID¤   ¤   ¤   ¤   goalKeyID;
3daf5a
c59137 ¤   pgpAssertAddrValid(diskFile, File);
1b1071 ¤   pgpAssert(diskFile->Opened());
ac4326 ¤   pgpAssert(PGPContextRefIsValid(context));
48bf2c ¤   pgpAssert(PGPKeyRefIsValid(curKey));
516a2e ¤   pgpAssertAddrValid(itemList, PGPdiskFileHeaderItem);
694f56 ¤   pgpAssertAddrValid(keyItem, PGPdiskFileHeaderItem *);
08af5a
fe2f24 ¤   (* keyItem) = NULL;
e3af5a
1556a7 ¤   // Get ID of key to look for.
bd45a4 ¤   derr = PGPGetKeyIDFromKey(curKey, &goalKeyID);
f7af5a
08efce ¤   curItem = itemList;
fdaf5a
482d1c ¤   while (derr.IsntError() && IsntNull(curItem))
bec7a1 ¤   {
7435d1 ¤   ¤   PGPByte¤¤   ¤   *exportedKeyID;
4fd4d7 ¤   ¤   PGPKeyID¤   ¤   keyID;
10af5a
b925fb ¤   ¤   if (IsPublicKeyHeader(curItem->hdr))
855b34 ¤   ¤   {
4f3878 ¤   ¤   ¤   pubKeyHdr = (PGPdiskPublicKeyHeader *) curItem->hdr;
cb4614 ¤   ¤   ¤   exportedKeyID = (PGPByte *) pubKeyHdr + pubKeyHdr->keyIDOffset;
a1af5a
9509c1 ¤   ¤   ¤   // Read in key ID.
fd392f ¤   ¤   ¤   derr = PGPImportKeyID(exportedKeyID, &keyID);
d0af5a
f561a7 ¤   ¤   ¤   // Do they match?
85fa9e ¤   ¤   ¤   if (PGPCompareKeyIDs(&keyID, &goalKeyID) == 0)
51f776 ¤   ¤   ¤   {
--f1da 0000675fe7440110171 Page 9 of PGPdiskPublicKeyUtils.cpp
509653 ¤   ¤   ¤   ¤   (* keyItem) = curItem;
75f622 ¤   ¤   ¤   ¤   break;
50a3a6 ¤   ¤   ¤   }
d20fe4 ¤   ¤   }
00af5a
d34545 ¤   ¤   curItem = curItem->next;
939371 ¤   }
f4af5a
b433e3 ¤   return derr;
c3efe6 }
47af5a
1c7db7 // GetHeaderForPublicKey returns a copy of the PGPdisk header that
0bf9cf // corresponds to the given public key.
7aaf5a
2a2292 DualErr·
053aa0 GetHeaderForPublicKey(
c7815f ¤   LPCSTR¤ ¤   ¤   ¤   ¤   path,·
a240e0 ¤   PGPContextRef¤  ¤   ¤   context,·
faeb3f ¤   PGPKeyRef¤  ¤   ¤   ¤   curKey,·
c81fdf ¤   PGPdiskPublicKeyHeader¤ **pubKeyHdr)
0cbb36 {
6d2eee ¤   File¤   ¤   ¤   ¤   ¤   diskFile;
509f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
48193e ¤   PGPBoolean¤ ¤   ¤   ¤   gotItemList;
7c8b73 ¤   PGPdiskFileHeaderItem¤  *itemList, *keyItem;
caaf5a
5d639f ¤   pgpAssertStrValid(path);
394326 ¤   pgpAssert(PGPContextRefIsValid(context));
76bf2c ¤   pgpAssert(PGPKeyRefIsValid(curKey));
baaf5a
209e67 ¤   // Open the PGPdisk.
548be9 ¤   derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
1aaf5a
b4d314 ¤   // Get list of headers.
a22361 ¤   if (derr.IsntError())
88c7a1 ¤   {
710032 ¤   ¤   derr = GetHeaderItemList(&diskFile, &itemList);
1970bb ¤   ¤   gotItemList = derr.IsntError();
349371 ¤   }
8caf5a
9889bc ¤   // Look for associated header.
cc2361 ¤   if (derr.IsntError())
37c7a1 ¤   {
261be3 ¤   ¤   derr = FindPublicKeyInHeaderList(&diskFile, context, curKey,·
e3524c ¤   ¤   ¤   itemList, &keyItem);
f39371 ¤   }
d9af5a
329cbb ¤   // Copy the header.
f42361 ¤   if (derr.IsntError())
43c7a1 ¤   {
bf20c2 ¤   ¤   derr = CopyHeader(keyItem->hdr, (PGPdiskFileHeaderInfo **) pubKeyHdr);
a79371 ¤   }
90af5a
b13020 ¤   if (gotItemList)
fba68d ¤   ¤   FreeHeaderItemList(itemList);
74af5a
1ed27f ¤   if (diskFile.Opened())
49d016 ¤   ¤   diskFile.Close();
63af5a
4333e3 ¤   return derr;
b5efe6 }
36af5a
b70d34 // CreatePublicKeyHeader creates and returns a new PGPdisk public key header
cffe4c // using the specified information.
2baf5a
8a2292 DualErr·
0f0881 CreatePublicKeyHeader(
2940e0 ¤   PGPContextRef¤  ¤   ¤   context,·
8d7765 ¤   PGPKeyRef¤  ¤   ¤   ¤   pubKey,·
13391e ¤   const CASTKey¤  ¤   ¤   *decryptedKey,·
5ea23f ¤   PGPBoolean¤ ¤   ¤   ¤   locked,·
066a78 ¤   PGPBoolean¤ ¤   ¤   ¤   readOnly,·
--8a21 00021ab883d40110171 Page 10 of PGPdiskPublicKeyUtils.cpp
aef480 ¤   PGPdiskPublicKeyHeader¤ **outPubKeyHdr)
3abb36 {
6d9f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
f1efd5 ¤   CheckBytes¤ ¤   ¤   ¤   checkBytes;
63dddb ¤   PGPBoolean¤ ¤   ¤   ¤   gotEncryptedKey¤= FALSE;
455177 ¤   PGPByte¤¤   ¤   ¤   ¤   *data, exportedKeyID[kPGPMaxExportedKeyIDSize];
7e3f1b ¤   PGPKeyID¤   ¤   ¤   ¤   keyID;
4b7790 ¤   PGPInt32¤   ¤   ¤   ¤   alg;
46ea37 ¤   PGPPublicKeyAlgorithm¤  algorithm;
619dac ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr;
759905 ¤   PGPSize¤¤   ¤   ¤   ¤   exportedKeyIDSize;
7d5cdf ¤   PGPUInt32¤  ¤   ¤   ¤   encryptedKeySize, headerSize;
ea7c5e ¤   void¤   ¤   ¤   ¤   ¤   *encryptedKey¤  = NULL;
27af5a
d6b3a4 ¤   encryptedKeySize = 0;
37af5a
424326 ¤   pgpAssert(PGPContextRefIsValid(context));
65426f ¤   pgpAssert(PGPKeyRefIsValid(pubKey));
f0448c ¤   pgpAssertAddrValid(decryptedKey, CASTKey);
4f25cd ¤   pgpAssertAddrValid(outPubKeyHdr, PGPdiskPublicKeyHeader *);
8daf5a
033fd0 ¤   // Encrypt decypted key using the private key of the public key.
3ca3ae ¤   derr = EncryptPublicKey(decryptedKey, pubKey, &encryptedKey,·
b8b629 ¤   ¤   &encryptedKeySize, &checkBytes);
2daf5a
b6d4fd ¤   gotEncryptedKey = derr.IsntError();
55af5a
2e24ac ¤   // Get key ID.
b02361 ¤   if (derr.IsntError())
5cc7a1 ¤   {
8d9db2 ¤   ¤   derr = PGPGetKeyIDFromKey(pubKey, &keyID);
139371 ¤   }
e8af5a
ae6bdd ¤   // Get exported key ID.
bf2361 ¤   if (derr.IsntError())
f2c7a1 ¤   {
29357d ¤   ¤   derr = PGPExportKeyID(&keyID, exportedKeyID, &exportedKeyIDSize);
379371 ¤   }
79af5a
2ce6e1 ¤   // Get key algorithm.
692361 ¤   if (derr.IsntError())
a9c7a1 ¤   {
2b4afb ¤   ¤   derr = PGPGetKeyNumber(pubKey, kPGPKeyPropAlgID, &alg);
909371 ¤   }
e2af5a
124ef6 ¤   // Allocate header.
0f2361 ¤   if (derr.IsntError())
5e58c8 ¤   {¤  ¤
c22842 ¤   ¤   algorithm = (PGPPublicKeyAlgorithm) alg;
8daf5a
ed7872 ¤   ¤   headerSize = sizeof(PGPdiskPublicKeyHeader) + exportedKeyIDSize +·
7aa925 ¤   ¤   ¤   encryptedKeySize;
3aaf5a
3441f1 ¤   ¤   try
055b34 ¤   ¤   {
89db65 ¤   ¤   ¤   pubKeyHdr = (PGPdiskPublicKeyHeader *) new PGPUInt8[headerSize];
660fe4 ¤   ¤   }
7e01e0 ¤   ¤   catch (CMemoryException *ex)
4d5b34 ¤   ¤   {
a2b95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
80ad69 ¤   ¤   ¤   ex->Delete();
5a0fe4 ¤   ¤   }
d59371 ¤   }
c3af5a
356c5a ¤   // Initialize header fields.
b62361 ¤   if (derr.IsntError())
f7c7a1 ¤   {
bfe801 ¤   ¤   pgpClearMemory(pubKeyHdr, sizeof(PGPdiskPublicKeyHeader));
f7af5a
ef8393 ¤   ¤   strncpy(pubKeyHdr->headerInfo.headerMagic, kPGPdiskHeaderMagic, 4);
30af5a
216dcd ¤   ¤   strncpy(pubKeyHdr->headerInfo.headerType,·
--4de1 00078b0087640110171 Page 11 of PGPdiskPublicKeyUtils.cpp
43d1ab ¤   ¤   ¤   kPGPdiskPublicKeyHeaderType, 4);
05af5a
619cdc ¤   ¤   pubKeyHdr->headerInfo.headerSize = headerSize;
b0af5a
25e839 ¤   ¤   pubKeyHdr->majorVersion¤= kPGPdiskPublicKeyHeaderMajorVersion;
d2acb1 ¤   ¤   pubKeyHdr->minorVersion¤= kPGPdiskPublicKeyHeaderMinorVersion;
44ed43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
027774 ¤   ¤   pubKeyHdr->readOnly¤= readOnly;
2fe247 ¤   ¤   pubKeyHdr->locked¤  = locked;
6baf5a
ef777d ¤   ¤   pubKeyHdr->keyIDSize¤   ¤   = exportedKeyIDSize;
1612b7 ¤   ¤   pubKeyHdr->encryptedKeySize¤= encryptedKeySize;
711cda ¤   ¤   pubKeyHdr->checkBytes¤  ¤   = checkBytes;
a97f44 ¤   ¤   pubKeyHdr->algorithm¤   ¤   = algorithm;
611b52 ¤   ¤
d0ef54 ¤   ¤   data = (PGPByte *) pubKeyHdr + sizeof(PGPdiskPublicKeyHeader);
ba19c2 ¤   ¤   pgpCopyMemory(exportedKeyID, data, exportedKeyIDSize);
2daf5a
655e19 ¤   ¤   pubKeyHdr->keyIDOffset = data - (PGPByte *) pubKeyHdr;
f21b52 ¤   ¤
0af2d9 ¤   ¤   data += exportedKeyIDSize;
bf4538 ¤   ¤   pgpCopyMemory(encryptedKey, data, encryptedKeySize);
9caf5a
d13b02 ¤   ¤   pubKeyHdr->encryptedKeyOffset = data - (PGPByte *) pubKeyHdr;
3aaf5a
8ce321 ¤   ¤   (* outPubKeyHdr) = pubKeyHdr;
f99371 ¤   }
e8af5a
59d780 ¤   if (gotEncryptedKey)
c02da4 ¤   ¤   delete[] (PGPUInt8 *) encryptedKey;
14af5a
3f33e3 ¤   return derr;
d1efe6 }
44af5a
717823 // ArePGPdiskPassesWiped returns TRUE if this PGPdisk has had its passes
6bbf8d // wiped, FALSE otherwise.
46af5a
7e77be PGPBoolean·
6a909b ArePGPdiskPassesWiped(LPCSTR path)
06bb36 {
dd705b ¤   DualErr¤¤   ¤   ¤   derr;
c7e1a0 ¤   File¤   ¤   ¤   ¤   diskFile;
a5551f ¤   PGPBoolean¤ ¤   ¤   arePassesWiped, masterInUse, readHeader;
038b3a ¤   PGPdiskFileHeader¤  *mainHeader;
19af5a
e1a28a ¤   arePassesWiped = readHeader = FALSE;
fdaf5a
cb639f ¤   pgpAssertStrValid(path);
b8af5a
d6dc8c ¤   // Read main header.
488bff ¤   derr = ReadPGPdiskFileMainHeader(path, &mainHeader);
baa08e ¤   readHeader = derr.IsntError();
ddaf5a
312767 ¤   // If master passphrase not in use and ID matches, then we're wiped.
3c2361 ¤   if (derr.IsntError())
0bc7a1 ¤   {
011aac ¤   ¤   masterInUse = (mainHeader->masterPassphrase.inUse ? TRUE : FALSE);
231b52 ¤   ¤
eebe27 ¤   ¤   if (!masterInUse)
1f5b34 ¤   ¤   {
2350f8 ¤   ¤   ¤   arePassesWiped = (strcmp((LPCSTR)·
2ff69b ¤   ¤   ¤   ¤   &mainHeader->masterPassphrase.checkBytes.theBytes,·
a489cb ¤   ¤   ¤   ¤   kPGPdiskPassesWipedId) == 0);
8b0fe4 ¤   ¤   }
da9371 ¤   }
14af5a
c9fd0b ¤   if (readHeader)
84004e ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) mainHeader);
01af5a
d84bb3 ¤   if (derr.IsError())
c398aa ¤   ¤   return FALSE;
780e24 ¤   else
--3c2c 000c83a7e8640110171 Page 12 of PGPdiskPublicKeyUtils.cpp
2ba401 ¤   ¤   return arePassesWiped;
aaefe6 }
aaaf5a
ae09a2 // ShowReadOnlyListOfPublicKeys displays the recipient dialog containing a
a6e3ab // read-only list of all the public keys on the specified PGPdisk.
28af5a
d12292 DualErr·
cd4369 ShowReadOnlyListOfPublicKeys(LPCSTR path)
0cbb36 {
6b705b ¤   DualErr¤¤   ¤   ¤   derr;
4480c6 ¤   PGPBoolean¤ ¤   ¤   gotAllKeys, gotContext, gotExistingKeys, gotNewKeys;
e1911c ¤   PGPBoolean¤ ¤   ¤   gotOptionsList;
097925 ¤   PGPContextRef¤  ¤   context;
592142 ¤   PGPKeySetRef¤   ¤   allKeys, newKeySet;
483015 ¤   PGPOptionListRef¤   recipientOptions;
280f92 ¤   PGPRecipientSpec¤   *existingKeys;
ea672c ¤   PGPUInt32¤  ¤   ¤   numExistKeys;
b1af5a
b90eed ¤   gotAllKeys = gotContext = gotExistingKeys = gotNewKeys =·
26b064 ¤   ¤   gotOptionsList = FALSE;
59af5a
40c04d ¤   // Get context ref.
d0e7c4 ¤   derr = PGPNewContext(kPGPsdkAPIVersion, &context);
1ecba3 ¤   gotContext = derr.IsntError();
8aaf5a
3fa6c2 ¤   // Open default key rings.
4e2361 ¤   if (derr.IsntError())
b1c7a1 ¤   {
3b9a25 ¤   ¤   derr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
dc4314 ¤   ¤   gotAllKeys = derr.IsntError();
079371 ¤   }
8faf5a
6120f7 ¤   // Retrieve already existing keys from the PGPdisk.
822361 ¤   if (derr.IsntError())
eec7a1 ¤   {
a66dd8 ¤   ¤   derr = GetPGPdiskRecipKeys(path, context, allKeys, &existingKeys,·
3c56c5 ¤   ¤   ¤   &numExistKeys);
3aaf5a
69f4bb ¤   ¤   gotExistingKeys = derr.IsntError();
839371 ¤   }
a2af5a
d52046 ¤   // Make each key read-only in the dialog.
db2361 ¤   if (derr.IsntError())
62c7a1 ¤   {
8c1077 ¤   ¤   PGPUInt32 i;
afaf5a
78e570 ¤   ¤   for (i = 0; i < numExistKeys; i++)
3a5b34 ¤   ¤   {
4139f9 ¤   ¤   ¤   existingKeys[i].locked = TRUE;
500fe4 ¤   ¤   }
6c9371 ¤   }
6eaf5a
94a917 ¤   // Build option list for the recipient dialog.
ce2361 ¤   if (derr.IsntError())
3cc7a1 ¤   {
5c9df8 ¤   ¤   PGPOptionListRef defRecipOption;
40af5a
7c3b57 ¤   ¤   defRecipOption = PGPOUIDefaultRecipients(context, numExistKeys,·
0b04e2 ¤   ¤   ¤   existingKeys);
ffaf5a
6884eb ¤   ¤   derr = PGPBuildOptionList(context, &recipientOptions, defRecipOption,·
eee5ff ¤   ¤   ¤   PGPOLastOption(context));
25af5a
c8f13a ¤   ¤   gotOptionsList = derr.IsntError();
c79371 ¤   }
4faf5a
32512b ¤   // Show the recipient dialog.
0f2361 ¤   if (derr.IsntError())
07c7a1 ¤   {
532968 ¤   ¤   derr = PGPRecipientDialog(context, allKeys, TRUE, &newKeySet,
ed8210 ¤   ¤   ¤   recipientOptions, PGPOLastOption(context));
c8af5a
--de7d 0007df3fd5740110171 Page 13 of PGPdiskPublicKeyUtils.cpp
03191b ¤   ¤   gotNewKeys = derr.IsntError();
129371 ¤   }
e5af5a
8205a4 ¤   if (gotNewKeys)
92510e ¤   ¤   PGPFreeKeySet(newKeySet);
3aaf5a
32b83d ¤   if (gotOptionsList)
a377af ¤   ¤   PGPFreeOptionList(recipientOptions);
c4af5a
a52176 ¤   if (gotExistingKeys)
52a784 ¤   ¤   FreeRecipientSpecList(existingKeys, numExistKeys);
65af5a
46fcc4 ¤   if (gotAllKeys)
304192 ¤   ¤   PGPFreeKeySet(allKeys);
aeaf5a
76b0b2 ¤   if (gotContext)
b23e8c ¤   ¤   PGPFreeContext(context);
e1af5a
fa33e3 ¤   return derr;
f0efe6 }
97af5a
564c7f // WipeMasterAndAlternatePasses wipes all the master and alternate
9bdaef // passphrases on a PGPdisk, but leaves the public key passphrases alone.
c6af5a
a42292 DualErr·
ce2a1b WipeMasterAndAlternatePasses(LPCSTR path)
32bb36 {
7b705b ¤   DualErr¤¤   ¤   ¤   derr;
57e1a0 ¤   File¤   ¤   ¤   ¤   diskFile;
8fd957 ¤   PGPBoolean¤ ¤   ¤   readHeader¤ = FALSE;
f48b3a ¤   PGPdiskFileHeader¤  *mainHeader;
69af5a
b0639f ¤   pgpAssertStrValid(path);
89af5a
02dc8c ¤   // Read main header.
1c8bff ¤   derr = ReadPGPdiskFileMainHeader(path, &mainHeader);
42a08e ¤   readHeader = derr.IsntError();
7daf5a
b1deb0 ¤   // Wipe master and alternate passes.
1d2361 ¤   if (derr.IsntError())
9cc7a1 ¤   {
a41077 ¤   ¤   PGPUInt32 i;
d2af5a
6dd3af ¤   ¤   pgpClearMemory(&mainHeader->masterPassphrase,·
43f8b1 ¤   ¤   ¤   sizeof(mainHeader->masterPassphrase));
80af5a
36449e ¤   ¤   pgpClearMemory(mainHeader->otherPassphrases,·
cca636 ¤   ¤   ¤   sizeof(mainHeader->otherPassphrases));
e7af5a
9970a6 ¤   ¤   mainHeader->masterPassphrase.inUse = FALSE;
93af5a
c12eb9 ¤   ¤   for (i = 0; i < kMaxAlternatePassphrases; i++)
a05b34 ¤   ¤   {
137976 ¤   ¤   ¤   mainHeader->otherPassphrases[i].inUse = FALSE;
1e0fe4 ¤   ¤   }
eeaf5a
24db68 ¤   ¤   strcpy((LPSTR) &mainHeader->masterPassphrase.checkBytes.theBytes,·
3c3c10 ¤   ¤   ¤   kPGPdiskPassesWipedId);
f8af5a
473760 ¤   ¤   derr = WritePGPdiskFileMainHeader(path, mainHeader);
939371 ¤   }
66af5a
35fd0b ¤   if (readHeader)
6a004e ¤   ¤   FreePGPdiskFileHeader((PGPdiskFileHeaderInfo *) mainHeader);
10af5a
3533e3 ¤   return derr;
44efe6 }
c6af5a
31af5a
776557 ///////////////////////
153978 // ADK utility routines
7d6557 ///////////////////////
--5bd8 000b40f1f1640110171 Page 14 of PGPdiskPublicKeyUtils.cpp
e0af5a
88d9a0 // IsTherePGPdiskADK returns TRUE if a PGPdisk ADK exists, FALSE otherwise.
20af5a
dd2292 DualErr·
6a052d IsTherePGPdiskADK(PGPContextRef context, PGPBoolean *isThereADK)
f8bb36 {
c07d36 ¤   DualErr derr;
bcaf5a
c34326 ¤   pgpAssert(PGPContextRefIsValid(context));
b258b0 ¤   pgpAssertAddrValid(isThereADK, PGPBoolean);
5eaf5a
f22672 ¤   (* isThereADK) = FALSE;
04af5a
e7be29 #if PGP_BUSINESS_SECURITY
50af5a
d03893 ¤   PGPBoolean¤ openedAdminPrefs¤   = FALSE;
ef52da ¤   PGPPrefRef¤ adminPrefsRef;
25af5a
d916b5 ¤   // Is the SDK available?
e3d94f ¤   if (!HavePGPsdk())
6d4346 ¤   ¤   derr = DualErr(kPGDMinorError_SDKNotAvailable);
9daf5a
15030e ¤   // Open admin prefs file.
182361 ¤   if (derr.IsntError())
5e58c8 ¤   {¤  ¤
030718 ¤   ¤   derr = PGPclOpenAdminPrefs(PGPGetContextMemoryMgr(context),·
ee5622 ¤   ¤   ¤   &adminPrefsRef, TRUE);
38af5a
409a40 ¤   ¤   openedAdminPrefs = derr.IsntError();
999371 ¤   }
1baf5a
9730f0 ¤   // Uses ADK?
a22361 ¤   if (derr.IsntError())
afc7a1 ¤   {
ca9c5f ¤   ¤   derr = PGPGetPrefBoolean(adminPrefsRef, kPGPPrefUsePGPdiskADK,·
13c986 ¤   ¤   ¤   isThereADK);
569371 ¤   }
64af5a
426d6f ¤   if (openedAdminPrefs)
83db34 ¤   ¤   PGPclCloseAdminPrefs(adminPrefsRef, FALSE);
2eaf5a
a097b2 #endif¤ // PGP_BUSINESS_SECURITY
cbaf5a
a733e3 ¤   return derr;
18efe6 }
b9af5a
a6d489 // GetADKKey gets the PGPdisk ADK key.
cbaf5a
f32292 DualErr·
789165 GetADKKey(
25cc60 ¤   PGPContextRef¤  context,·
2a445c ¤   PGPKeySetRef¤   allKeys,·
15c988 ¤   PGPKeyRef¤  ¤   *ADKKey)
6dbb36 {
d99f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
131cc1 ¤   PGPBoolean¤ ¤   ¤   ¤   gotIDData, openedAdminPrefs;
563f1b ¤   PGPKeyID¤   ¤   ¤   ¤   keyID;
04cb5e ¤   PGPPrefRef¤ ¤   ¤   ¤   adminPrefsRef;
14ea37 ¤   PGPPublicKeyAlgorithm¤  algorithm;
ded626 ¤   PGPSize¤¤   ¤   ¤   ¤   dataLength;
0a808a ¤   PGPUInt32¤  ¤   ¤   ¤   tempAlg;
8bcd9c ¤   void¤   ¤   ¤   ¤   ¤   *data;
0eaf5a
e1529f ¤   gotIDData = openedAdminPrefs = FALSE;
60af5a
af4a31 ¤   pgpAssert(PGP_BUSINESS_SECURITY);
f3af5a
1b4326 ¤   pgpAssert(PGPContextRefIsValid(context));
54bf3a ¤   pgpAssert(PGPKeySetRefIsValid(allKeys));
7c3574 ¤   pgpAssertAddrValid(ADKKey, PGPKeyRef);
51af5a
b4030e ¤   // Open admin prefs file.
--b14d 000c4e5f82840110171 Page 15 of PGPdiskPublicKeyUtils.cpp
9e8d5d ¤   derr = PGPclOpenAdminPrefs(PGPGetContextMemoryMgr(context),·
1dda5d ¤   ¤   &adminPrefsRef, TRUE);
fcaf5a
4c9cf8 ¤   openedAdminPrefs = derr.IsntError();
d4af5a
605561 ¤   // Get ADK algorithm.
fd2361 ¤   if (derr.IsntError())
4ac7a1 ¤   {
6ae2eb ¤   ¤   derr = PGPGetPrefNumber(adminPrefsRef,·
715b01 ¤   ¤   ¤   kPGPPrefPGPdiskADKPublicKeyAlgorithm, &tempAlg);
a69371 ¤   }
24af5a
9d5561 ¤   // Get ADK algorithm.
aa2361 ¤   if (derr.IsntError())
4a5cb4 ¤   {¤  ¤   ¤
25f112 ¤   ¤   algorithm = (PGPPublicKeyAlgorithm) tempAlg;
391b52 ¤   ¤
9adb8c ¤   ¤   derr = PGPGetPrefData(adminPrefsRef, kPGPPrefPGPdiskADKKeyID,·
342b36 ¤   ¤   ¤   &dataLength, &data);
1daf5a
cee098 ¤   ¤   gotIDData = derr.IsntError();
6b9371 ¤   }
5caf5a
f24afc ¤   // Get ADK key ID.
512361 ¤   if (derr.IsntError())
cac7a1 ¤   {
a8f79d ¤   ¤   derr = PGPImportKeyID(data, &keyID);
5b9371 ¤   }
25af5a
bcabeb ¤   // Get ADK key.
3b2361 ¤   if (derr.IsntError())
7cc7a1 ¤   {
3b989e ¤   ¤   derr = PGPGetKeyByKeyID(allKeys, &keyID, algorithm, ADKKey);
5c9371 ¤   }
46af5a
88aac0 ¤   if (gotIDData)
25496b ¤   ¤   PGPFreeData(data);
52af5a
af6d6f ¤   if (openedAdminPrefs)
1cdb34 ¤   ¤   PGPclCloseAdminPrefs(adminPrefsRef, FALSE);
2aaf5a
aa33e3 ¤   return derr;
6cefe6 }
d2af5a
b1dc4a // GetADKUserID gets the user ID of the current PGPdisk ADK.
0daf5a
8c2292 DualErr·
12e44e GetADKUserID(
adcc60 ¤   PGPContextRef¤  context,·
c3445c ¤   PGPKeySetRef¤   allKeys,·
9aba75 ¤   LPSTR¤  ¤   ¤   userID,·
c75baa ¤   PGPUInt32¤  ¤   sizeUserID)
0abb36 {
6abe41 ¤   DualErr¤¤   derr;
81785d ¤   PGPKeyRef¤  ADKKey;
1caf5a
054a31 ¤   pgpAssert(PGP_BUSINESS_SECURITY);
c9af5a
c64326 ¤   pgpAssert(PGPContextRefIsValid(context));
54bf3a ¤   pgpAssert(PGPKeySetRefIsValid(allKeys));
993fd7 ¤   pgpAssertAddrValid(userID, char);
91af5a
bbabeb ¤   // Get ADK key.
43987e ¤   derr = GetADKKey(context, allKeys, &ADKKey);
b1af5a
0c1766 ¤   // Get user ID string.
e82361 ¤   if (derr.IsntError())
74c7a1 ¤   {
511d8d ¤   ¤   PGPSize usedLength;
13af5a
252b6e ¤   ¤   derr = PGPGetPrimaryUserIDNameBuffer(ADKKey, sizeUserID, userID,·
c4b6cd ¤   ¤   ¤   &usedLength);
--d85b 000be37153640110171 Page 16 of PGPdiskPublicKeyUtils.cpp
a19371 ¤   }
93af5a
0c33e3 ¤   return derr;
96efe6 }
80af5a
237298 // AddADKToPGPdisk adds an existing ADK to a PGPdisk.
b4af5a
e92292 DualErr·
b7e046 AddADKToPGPdisk(LPCSTR path, SecureString *masterPassphrase)
51bb36 {
ff2fdb ¤   CASTKey¤¤   ¤   ¤   ¤   *decryptedKey;
eb9f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
5d2eee ¤   File¤   ¤   ¤   ¤   ¤   diskFile;
ddc1e0 ¤   PGPBoolean¤ ¤   ¤   ¤   gotAllKeys, gotNewContext, gotItemList;
94429f ¤   PGPContextRef¤  ¤   ¤   context;
99c74f ¤   PGPdiskFileHeaderItem¤  *itemList;
8d9dac ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr;
b696af ¤   PGPdiskFileHeader¤  ¤   *mainHeader;
53f172 ¤   PGPKeyRef¤  ¤   ¤   ¤   ADKKey;
72ae97 ¤   PGPKeySetRef¤   ¤   ¤   allKeys;
98af5a
cdad5f ¤   SecureMemory¤   smDecryptedKey(sizeof(CASTKey));
14af5a
c3a66f ¤   gotAllKeys = gotNewContext = gotItemList = FALSE;
ba639f ¤   pgpAssertStrValid(path);
9aaf5a
30c13e ¤   // Did we get our locked memory?
8977cd ¤   derr = smDecryptedKey.mInitErr;
d6af5a
5eff76 ¤   // Set the locked memory pointer.
e82361 ¤   if (derr.IsntError())
cdc7a1 ¤   {
7cec55 ¤   ¤   decryptedKey = (CASTKey *) smDecryptedKey.GetPtr();
0f9371 ¤   }
80af5a
30c9e2 ¤   // Create new PGP context.
bc2361 ¤   if (derr.IsntError())
77c7a1 ¤   {
97e0ff ¤   ¤   derr = PGPNewContext(kPGPsdkAPIVersion, &context);
e95b8d ¤   ¤   gotNewContext = derr.IsntError();
189371 ¤   }
ecaf5a
2506c6 ¤   // Load default key ring.
fd2361 ¤   if (derr.IsntError())
67c7a1 ¤   {
0f9a25 ¤   ¤   derr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
064314 ¤   ¤   gotAllKeys = derr.IsntError();
6e9371 ¤   }
feaf5a
b5abeb ¤   // Get ADK key.
e92361 ¤   if (derr.IsntError())
b4c7a1 ¤   {
b0cb65 ¤   ¤   derr = GetADKKey(context, allKeys, &ADKKey);
fe9371 ¤   }
a6af5a
019e67 ¤   // Open the PGPdisk.
492361 ¤   if (derr.IsntError())
56c7a1 ¤   {
82551c ¤   ¤   derr = diskFile.Open(path, kOF_MustExist);
f29371 ¤   }
c3af5a
40d314 ¤   // Get list of headers.
6d2361 ¤   if (derr.IsntError())
16c7a1 ¤   {
420032 ¤   ¤   derr = GetHeaderItemList(&diskFile, &itemList);
7870bb ¤   ¤   gotItemList = derr.IsntError();
669371 ¤   }
9daf5a
1c2361 ¤   if (derr.IsntError())
b2c7a1 ¤   {
6f2f0b ¤   ¤   // Get main header pointer.
befe42 ¤   ¤   mainHeader = (PGPdiskFileHeader *) itemList->hdr;
--536f 000fa68cdec40110171 Page 17 of PGPdiskPublicKeyUtils.cpp
e0af5a
c704b3 ¤   ¤   // Decrypt the master key
092147 ¤   ¤   derr = DecryptPassphraseKey(&mainHeader->masterPassphrase,·
d0eef6 ¤   ¤   ¤   &mainHeader->salt, masterPassphrase, decryptedKey);
dc9371 ¤   }
1caf5a
61c20c ¤   // Create a new header for it.
8d2361 ¤   if (derr.IsntError())
abc7a1 ¤   {
226396 ¤   ¤   derr = CreatePublicKeyHeader(context, ADKKey, decryptedKey, TRUE,·
9ac7d1 ¤   ¤   ¤   TRUE, &pubKeyHdr);
4e9371 ¤   }
b4af5a
203a66 ¤   // Insert the new header after the main header.
f42361 ¤   if (derr.IsntError())
08c7a1 ¤   {
8b3d57 ¤   ¤   derr = InsertPGPdiskHeaderInList(itemList,·
3f5288 ¤   ¤   ¤   (PGPdiskFileHeaderInfo *) pubKeyHdr);
519371 ¤   }
2aaf5a
232847 ¤   // Write out the updated headers to the PGPdisk.
682361 ¤   if (derr.IsntError())
70c7a1 ¤   {
dc0f3b ¤   ¤   derr = UpdateHeaderItemList(&diskFile, itemList);
909371 ¤   }
c2af5a
b53020 ¤   if (gotItemList)
53a68d ¤   ¤   FreeHeaderItemList(itemList);
c1af5a
e6fcc4 ¤   if (gotAllKeys)
f54192 ¤   ¤   PGPFreeKeySet(allKeys);
e7af5a
fc48fe ¤   if (gotNewContext)
f63e8c ¤   ¤   PGPFreeContext(context);
a6af5a
10d27f ¤   if (diskFile.Opened())
5fd016 ¤   ¤   diskFile.Close();
74af5a
5b33e3 ¤   return derr;
7defe6 }
8eaf5a
f5af5a
9ce27e ////////////////////////////////////////////
c57508 // Public key encryption/decryption routines
f0e27e ////////////////////////////////////////////
c8af5a
ea7a0e // DecryptPublicKey decrypts data using a public/private key pair.
82af5a
762292 DualErr·
a3953b DecryptPublicKey(
4bce37 ¤   PGPKeyRef¤  ¤   ¤   pubKey,
da8140 ¤   SecureString¤   ¤   *passphrase,
0ccfab ¤   const void¤ ¤   ¤   *encryptedData,
6c6a65 ¤   PGPSize¤¤   ¤   ¤   encryptedDataSize,
4d5ac0 ¤   const CheckBytes¤   *checkBytes,
b22d26 ¤   CASTKey¤¤   ¤   ¤   *decryptedKey)
77bb36 {
db1797 ¤   CheckBytes¤ ¤   ¤   ¤   decryptedCheckBytes;
f19f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
4bbe88 ¤   ExpandedCASTKey¤¤   ¤   *expandedKey;
5ff2d9 ¤   PGPBoolean¤ ¤   ¤   ¤   allocedDataBuf, gotPrivContext;
198107 ¤   PGPByte¤¤   ¤   ¤   ¤   *data, fingerPrint[128];
188f89 ¤   PGPPrivateKeyContextRef¤privContext;
a5429f ¤   PGPContextRef¤  ¤   ¤   context;
6dac82 ¤   PGPSize¤¤   ¤   ¤   ¤   decryptedDataSize, fingerPrintSize;
afd49d ¤   PGPSize¤¤   ¤   ¤   ¤   maxDecryptedBufferSize, maxEncryptedBufferSize;
b5f2d6 ¤   PGPSize¤¤   ¤   ¤   ¤   maxSignatureSize;
a9f306 ¤   PGPUInt8¤   ¤   ¤   ¤   *secureBuf;
ceaf5a
905500 ¤   SecureMemory¤   smExpandedKey(sizeof(ExpandedCASTKey));
c31ed1 ¤   SecureMemory¤   smSecureBuf(kMaxPassphraseLength);
fa410c ¤   SecureMemory¤   *pSmCASTKey;
--51d2 000a613c71f40110171 Page 18 of PGPdiskPublicKeyUtils.cpp
e0af5a
a6e104 ¤   allocedDataBuf = gotPrivContext = FALSE;
0baf5a
2a426f ¤   pgpAssert(PGPKeyRefIsValid(pubKey));
5fc1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
2e6275 ¤   pgpAssertAddrValid(encryptedData, VoidAlign);
5a2da7 ¤   pgpAssertAddrValid(checkBytes, checkBytes);
63448c ¤   pgpAssertAddrValid(decryptedKey, CASTKey);
51af5a
07c13e ¤   // Did we get our locked memory?
635933 ¤   derr = smExpandedKey.mInitErr;
ccaf5a
5d2361 ¤   if (derr.IsntError())
f0c7a1 ¤   {
3876f9 ¤   ¤   derr = smSecureBuf.mInitErr;
4a9371 ¤   }
a7af5a
ab2361 ¤   if (derr.IsntError())
7ac7a1 ¤   {
25b65a ¤   ¤   // Get locked memory pointer.
357e68 ¤   ¤   expandedKey¤= (ExpandedCASTKey *) smExpandedKey.GetPtr();
cb5a6d ¤   ¤   secureBuf¤  = (PGPUInt8 *) smSecureBuf.GetPtr();
24af5a
4857dc ¤   ¤   // Get passphrase string.
ddf9f9 ¤   ¤   passphrase->GetString((LPSTR) secureBuf, kMaxStringSize);
7faf5a
8362a4 ¤   ¤   // Get key context.
bc84ef ¤   ¤   context = PGPGetKeyContext(pubKey);
39af5a
c1692a ¤   ¤   // Initialize private context.
e9af69 ¤   ¤   derr = PGPNewPrivateKeyContext(pubKey,·
075cef ¤   ¤   ¤   kPGPPublicKeyMessageFormat_PGP, &privContext,·
100123 ¤   ¤   ¤   PGPOPassphrase(context, (LPCSTR) secureBuf),·
4ee5ff ¤   ¤   ¤   PGPOLastOption(context));
95af5a
980b91 ¤   ¤   gotPrivContext = derr.IsntError();
839371 ¤   }
a8af5a
073dee ¤   // Get operation sizes.
c62361 ¤   if (derr.IsntError())
fc58c8 ¤   {¤  ¤
0c6131 ¤   ¤   derr = PGPGetPrivateKeyOperationSizes(privContext,·
2627b9 ¤   ¤   ¤   &maxDecryptedBufferSize, &maxEncryptedBufferSize,·
430d01 ¤   ¤   ¤   &maxSignatureSize);
819371 ¤   }
49af5a
2423d5 ¤   // Get key properties.
052361 ¤   if (derr.IsntError())
cdc7a1 ¤   {
453149 ¤   ¤   pgpClearMemory(fingerPrint, sizeof(fingerPrint));¤  ¤   ¤
6587c7 ¤   ¤   ¤
e9541e ¤   ¤   derr = PGPGetKeyPropertyBuffer(pubKey, kPGPKeyPropFingerprint,
9b6533 ¤   ¤   ¤   sizeof(fingerPrint), fingerPrint, &fingerPrintSize);
719371 ¤   }
67af5a
0894ff ¤   // Get space for buffer.
712361 ¤   if (derr.IsntError())
44c7a1 ¤   {
4441f1 ¤   ¤   try
0d5b34 ¤   ¤   {
e7f8e3 ¤   ¤   ¤   pSmCASTKey = new SecureMemory(maxDecryptedBufferSize);
ce6241 ¤   ¤   ¤   data = (PGPUInt8 *) pSmCASTKey->GetPtr();
d60fe4 ¤   ¤   }
f901e0 ¤   ¤   catch (CMemoryException *ex)
f25b34 ¤   ¤   {
5ab95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
86ad69 ¤   ¤   ¤   ex->Delete();
f60fe4 ¤   ¤   }
aaaf5a
0c7149 ¤   ¤   allocedDataBuf = derr.IsntError();
af9371 ¤   }
a6af5a
--6d42 000fd78828140110171 Page 19 of PGPdiskPublicKeyUtils.cpp
e087c2 ¤   // Decrypt the data.
de2361 ¤   if (derr.IsntError())
65c7a1 ¤   {
be3c87 ¤   ¤   derr = PGPPrivateKeyDecrypt(privContext, encryptedData,
8d6dea ¤   ¤   ¤   encryptedDataSize, data, &decryptedDataSize);
bc9371 ¤   }
23af5a
41d2c1 ¤   // Check the result.
8b2361 ¤   if (derr.IsntError())
74c7a1 ¤   {
2c8edf ¤   ¤   if (decryptedDataSize == sizeof(CASTKey))
3e5b34 ¤   ¤   {
a8f1d9 ¤   ¤   ¤   pgpCopyMemory(data, decryptedKey, sizeof(CASTKey));
21af5a
8ea722 ¤   ¤   ¤   // Decrypt the check bytes. We encrypted the first eight bytes of
4d1ed5 ¤   ¤   ¤   // the fingerprint.
0eaf5a
d6f8a8 ¤   ¤   ¤   CAST5schedule(expandedKey->keyDWords, decryptedKey->keyBytes);
c7af5a
7b4773 ¤   ¤   ¤   CAST5decrypt(&checkBytes->theBytes[0],·
b37ec8 ¤   ¤   ¤   ¤   &decryptedCheckBytes.theBytes[0], expandedKey->keyDWords);
fdaf5a
2b78df ¤   ¤   ¤   if (!pgpMemoryEqual(&decryptedCheckBytes, fingerPrint,·
53b391 ¤   ¤   ¤   ¤   sizeof(decryptedCheckBytes)))
fff776 ¤   ¤   ¤   {
bdd751 ¤   ¤   ¤   ¤   // Should never get here.
6f2e1b ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
f047af ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤   ¤
160fe4 ¤   ¤   }
a30e1d ¤   ¤   else
eb5b34 ¤   ¤   {
77f432 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidParameter);
650fe4 ¤   ¤   }
819371 ¤   }
28af5a
4d905a ¤   if (gotPrivContext)
69a207 ¤   ¤   PGPFreePrivateKeyContext(privContext);
9baf5a
0b575f ¤   if (allocedDataBuf)
e6460d ¤   ¤   delete pSmCASTKey;
bbaf5a
fd33e3 ¤   return derr;
70efe6 }
10af5a
f61eac // EncryptPublicKey encrypts data using a public/private key pair.
06af5a
a12292 DualErr·
baddb5 EncryptPublicKey(
6d0157 ¤   const CASTKey¤  *decryptedKey,
727f38 ¤   PGPKeyRef¤  ¤   pubKey,
2ee590 ¤   void¤   ¤   ¤   **encryptedData,
00b5e4 ¤   PGPUInt32¤  ¤   *encryptedDataSize,
2405ef ¤   CheckBytes¤ ¤   *checkBytes)
87bb36 {
229f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
c2be88 ¤   ExpandedCASTKey¤¤   ¤   *expandedKey;
a17768 ¤   PGPBoolean¤ ¤   ¤   ¤   allocedDataBuf, gotPubContext;
cd8107 ¤   PGPByte¤¤   ¤   ¤   ¤   *data, fingerPrint[128];
32603a ¤   PGPPublicKeyContextRef¤ pubContext;
6dbc6b ¤   PGPSize¤¤   ¤   ¤   ¤   dataSize, fingerPrintSize, maxDecryptedBufferSize;
a211c8 ¤   PGPSize¤¤   ¤   ¤   ¤   maxEncryptedBufferSize, maxSignatureSize;
c0af5a
6f5500 ¤   SecureMemory¤   smExpandedKey(sizeof(ExpandedCASTKey));
e9af5a
9e242e ¤   allocedDataBuf = gotPubContext = FALSE;
31af5a
63426f ¤   pgpAssert(PGPKeyRefIsValid(pubKey));
a96275 ¤   pgpAssertAddrValid(encryptedData, VoidAlign);
b22da7 ¤   pgpAssertAddrValid(checkBytes, checkBytes);
fb448c ¤   pgpAssertAddrValid(decryptedKey, CASTKey);
a8af5a
fdc13e ¤   // Did we get our locked memory?
--5b1b 0003852ad8540110171 Page 20 of PGPdiskPublicKeyUtils.cpp
575933 ¤   derr = smExpandedKey.mInitErr;
68af5a
e32361 ¤   if (derr.IsntError())
04c7a1 ¤   {
a9b65a ¤   ¤   // Get locked memory pointer.
5f2327 ¤   ¤   expandedKey = (ExpandedCASTKey *) smExpandedKey.GetPtr();
70af5a
7c692a ¤   ¤   // Initialize private context.
29f1c6 ¤   ¤   derr = PGPNewPublicKeyContext(pubKey, kPGPPublicKeyMessageFormat_PGP,·
2b9b80 ¤   ¤   ¤   &pubContext);
71af5a
200e66 ¤   ¤   gotPubContext = derr.IsntError();
009371 ¤   }
06af5a
da3dee ¤   // Get operation sizes.
702361 ¤   if (derr.IsntError())
a558c8 ¤   {¤  ¤
56b7a2 ¤   ¤   derr = PGPGetPublicKeyOperationSizes(pubContext,·
c127b9 ¤   ¤   ¤   &maxDecryptedBufferSize, &maxEncryptedBufferSize,·
450d01 ¤   ¤   ¤   &maxSignatureSize);
0e9371 ¤   }
89af5a
b023d5 ¤   // Get key properties.
052361 ¤   if (derr.IsntError())
b5c7a1 ¤   {
3f3149 ¤   ¤   pgpClearMemory(fingerPrint, sizeof(fingerPrint));¤  ¤   ¤
b187c7 ¤   ¤   ¤
02541e ¤   ¤   derr = PGPGetKeyPropertyBuffer(pubKey, kPGPKeyPropFingerprint,
756533 ¤   ¤   ¤   sizeof(fingerPrint), fingerPrint, &fingerPrintSize);
1f9371 ¤   }
6caf5a
5f94ff ¤   // Get space for buffer.
a32361 ¤   if (derr.IsntError())
cac7a1 ¤   {
6641f1 ¤   ¤   try
965b34 ¤   ¤   {
a081b6 ¤   ¤   ¤   data = new PGPByte[maxEncryptedBufferSize];
0d0fe4 ¤   ¤   }
3c01e0 ¤   ¤   catch (CMemoryException *ex)
915b34 ¤   ¤   {
bbb95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
c0ad69 ¤   ¤   ¤   ex->Delete();
610fe4 ¤   ¤   }
30af5a
227149 ¤   ¤   allocedDataBuf = derr.IsntError();
f19371 ¤   }
5daf5a
de2361 ¤   if (derr.IsntError())
f1c7a1 ¤   {
6a53ed ¤   ¤   // Compute the check bytes.
b82803 ¤   ¤   CAST5schedule(expandedKey->keyDWords, decryptedKey->keyBytes);
5aaf5a
7c824b ¤   ¤   CAST5encrypt(fingerPrint, &checkBytes->theBytes[0],·
b8ee65 ¤   ¤   ¤   expandedKey->keyDWords);
35af5a
1f7f95 ¤   ¤   // Perform the encryption.
5cad98 ¤   ¤   derr = PGPPublicKeyEncrypt(pubContext, decryptedKey, sizeof(CASTKey),·
5af7d5 ¤   ¤   ¤   data, &dataSize);
909371 ¤   }
02af5a
7d2361 ¤   if (derr.IsntError())
06c7a1 ¤   {
fdd278 ¤   ¤   (* encryptedData) ¤ ¤   = data;
4d4e84 ¤   ¤   (* encryptedDataSize)¤  = dataSize;
fc9371 ¤   }
36af5a
166fab ¤   if (gotPubContext)
2fa61c ¤   ¤   PGPFreePublicKeyContext(pubContext);
56af5a
9e4bb3 ¤   if (derr.IsError())
64c7a1 ¤   {
38a13a ¤   ¤   if (allocedDataBuf)
--2fc8 00040a7194340110171 Page 21 of PGPdiskPublicKeyUtils.cpp
953ea1 ¤   ¤   ¤   delete[] data;
e59371 ¤   }
2eaf5a
f333e3 ¤   return derr;
57efe6 }
2caf5a
dc22bc // GetDecryptedKeyUsingPublicKey decrypts an encrypted session key using info
21f89f // from a public key header.
ecaf5a
ef2292 DualErr·
6526d3 GetDecryptedKeyUsingPublicKey(
74b415 ¤   SecureString¤   ¤   ¤   *passphrase,·
ef4327 ¤   PGPdiskPublicKeyHeader¤ *pubKeyHdr,·
5f89fa ¤   CASTKey¤¤   ¤   ¤   ¤   *decryptedKey)
26bb36 {
8f9a95 ¤   DualErr¤¤   ¤   derr;
743ee1 ¤   PGPBoolean¤ ¤   gotContext, gotAllKeys;
4f7adc ¤   PGPByte¤¤   ¤   *encryptedKey, *exportedKeyID;
d4c0ff ¤   PGPKeyID¤   ¤   keyID;
938a97 ¤   PGPContextRef¤  context;
08a7a1 ¤   PGPKeyRef¤  ¤   pubKey;
b8dedb ¤   PGPKeySetRef¤   allKeys;
dcaf5a
17f95f ¤   gotContext = gotAllKeys = FALSE;
62af5a
4ec1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
147a2c ¤   pgpAssertAddrValid(pubKeyHdr, PGPdiskPublicKeyHeader);
5b448c ¤   pgpAssertAddrValid(decryptedKey, CASTKey);
5caf5a
7343d4 ¤   // Create context.
71e7c4 ¤   derr = PGPNewContext(kPGPsdkAPIVersion, &context);
d4cba3 ¤   gotContext = derr.IsntError();
07af5a
322896 ¤   // Load SDK prefs.
b72361 ¤   if (derr.IsntError())
c9c7a1 ¤   {
f51637 ¤   ¤   derr = PGPsdkLoadDefaultPrefs(context);
6d9371 ¤   }
9caf5a
6d06c6 ¤   // Load default key ring.
982361 ¤   if (derr.IsntError())
e7c7a1 ¤   {
729a25 ¤   ¤   derr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
7e4314 ¤   ¤   gotAllKeys = derr.IsntError();
149371 ¤   }
95af5a
a0af97 ¤   // Import key ID.
942361 ¤   if (derr.IsntError())
d2c7a1 ¤   {
ba5d1d ¤   ¤   exportedKeyID = (PGPByte *) pubKeyHdr + pubKeyHdr->keyIDOffset;
6c3a58 ¤   ¤   derr = PGPImportKeyID(exportedKeyID, &keyID);
449371 ¤   }
67af5a
a67e74 ¤   // Get actual key.
732361 ¤   if (derr.IsntError())
31c7a1 ¤   {
24628c ¤   ¤   derr = PGPGetKeyByKeyID(allKeys, &keyID, pubKeyHdr->algorithm,·
e85ca2 ¤   ¤   ¤   &pubKey);
2d9371 ¤   }
a4af5a
89f039 ¤   // Decrypt the encrypted session key.
bc2361 ¤   if (derr.IsntError())
18c7a1 ¤   {
5df5db ¤   ¤   encryptedKey = (PGPByte *) pubKeyHdr + pubKeyHdr->encryptedKeyOffset;
0eaf5a
98c567 ¤   ¤   derr = DecryptPublicKey(pubKey, passphrase, encryptedKey,·
8297a2 ¤   ¤   ¤   pubKeyHdr->encryptedKeySize, &pubKeyHdr->checkBytes,·
45b2da ¤   ¤   ¤   decryptedKey);
a19371 ¤   }
93af5a
67fcc4 ¤   if (gotAllKeys)
404192 ¤   ¤   PGPFreeKeySet(allKeys);
--2d6f 0003a15486d40110171 Page 22 of PGPdiskPublicKeyUtils.cpp
e0af5a
c6b0b2 ¤   if (gotContext)
a23e8c ¤   ¤   PGPFreeContext(context);
d2af5a
e633e3 ¤   return derr;
0fefe6 }
b1af5a
2ddf1a // FindPublicPGPdiskKeyHeader finds a PGPdisk public key header whose private
5b26b9 // key is unlocked by the specified passphrase.
ceaf5a
9e2292 DualErr·
e0f62f FindPublicPGPdiskKeyHeader(
df815f ¤   LPCSTR¤ ¤   ¤   ¤   ¤   path,·
1cb415 ¤   SecureString¤   ¤   ¤   *passphrase,·
411fdf ¤   PGPdiskPublicKeyHeader¤ **pubKeyHdr)
bbbb36 {
df705b ¤   DualErr¤¤   ¤   ¤   derr;
1968f6 ¤   PGPBoolean¤ ¤   ¤   anyKeysNotInRing, foundKey, gotAllKeys, gotContext;
c49480 ¤   PGPBoolean¤ ¤   ¤   gotDiskKeys;
347925 ¤   PGPContextRef¤  ¤   context;
6a85b6 ¤   PGPKeyRef¤  ¤   ¤   curKey;
dbe658 ¤   PGPKeySetRef¤   ¤   allKeys;
530482 ¤   PGPRecipientSpec¤   *diskRecipKeys;
a5feab ¤   PGPUInt8¤   ¤   ¤   *secureBuf;
6aebf0 ¤   PGPUInt32¤  ¤   ¤   i, numRecipKeys;
dbaf5a
261ed1 ¤   SecureMemory¤   smSecureBuf(kMaxPassphraseLength);
2baf5a
a19ee4 ¤   anyKeysNotInRing = foundKey = gotAllKeys = gotContext = gotDiskKeys =·
5ebf61 ¤   ¤   FALSE;
9faf5a
6d639f ¤   pgpAssertStrValid(path);
26c1f2 ¤   pgpAssertAddrValid(passphrase, SecureString);
03c93f ¤   pgpAssertAddrValid(pubKeyHdr, PGPdiskPublicKeyHeader *);
8daf5a
52c13e ¤   // Did we get our locked memory?
684b91 ¤   derr = smSecureBuf.mInitErr;
4daf5a
ee2361 ¤   if (derr.IsntError())
2fc7a1 ¤   {
d7b65a ¤   ¤   // Get locked memory pointer.
2df7c5 ¤   ¤   secureBuf = (PGPUInt8 *) smSecureBuf.GetPtr();
b8af5a
3257dc ¤   ¤   // Get passphrase string.
0df9f9 ¤   ¤   passphrase->GetString((LPSTR) secureBuf, kMaxStringSize);
f9af5a
98a135 ¤   ¤   // Create context.
c2e0ff ¤   ¤   derr = PGPNewContext(kPGPsdkAPIVersion, &context);
978a50 ¤   ¤   gotContext = derr.IsntError();
e59371 ¤   }
2aaf5a
3d2896 ¤   // Load SDK prefs.
e72361 ¤   if (derr.IsntError())
55c7a1 ¤   {
5d1637 ¤   ¤   derr = PGPsdkLoadDefaultPrefs(context);
6f9371 ¤   }
c5af5a
2c06c6 ¤   // Load default key ring.
142361 ¤   if (derr.IsntError())
bfc7a1 ¤   {
859a25 ¤   ¤   derr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
504314 ¤   ¤   gotAllKeys = derr.IsntError();
a79371 ¤   }
f0af5a
e7d56d ¤   // Get list of keys from PGPdisk.
e82361 ¤   if (derr.IsntError())
5fc7a1 ¤   {
061fbd ¤   ¤   derr = GetPGPdiskRecipKeys(path, context, allKeys, &diskRecipKeys,·
973bb3 ¤   ¤   ¤   &numRecipKeys);
72af5a
fc7c96 ¤   ¤   gotDiskKeys = derr.IsntError();
3a9371 ¤   }
--0647 0005b14737d40110171 Page 23 of PGPdiskPublicKeyUtils.cpp
e0af5a
adde59 ¤   // Find the key that corresponds to the passphrase.
852361 ¤   if (derr.IsntError())
80c7a1 ¤   {
231851 ¤   ¤   // For every recipient spec in the list...
290e9d ¤   ¤   for (i = 0; i < numRecipKeys; i++)
6c5b34 ¤   ¤   {
13f2b0 ¤   ¤   ¤   // ... if it has an associated key ref...
2763e8 ¤   ¤   ¤   if (diskRecipKeys[i].type == kPGPRecipientSpecType_Key)
5cf776 ¤   ¤   ¤   {
6c54bc ¤   ¤   ¤   ¤   PGPBoolean canDecrypt = FALSE;
60af5a
51b26a ¤   ¤   ¤   ¤   curKey = diskRecipKeys[i].u.key;
06425a ¤   ¤   ¤   ¤   PGPGetKeyBoolean(curKey, kPGPKeyPropCanDecrypt, &canDecrypt);
a2af5a
e35455 ¤   ¤   ¤   ¤   //... and if the given passphrase unlocks it, we're done.
a48093 ¤   ¤   ¤   ¤   if (canDecrypt && PGPPassphraseIsValid(curKey,
b25f3a ¤   ¤   ¤   ¤   ¤   PGPOPassphrase(context, (LPCSTR) secureBuf),·
1d46f5 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context)))
ef72c3 ¤   ¤   ¤   ¤   {
d8e1f7 ¤   ¤   ¤   ¤   ¤   foundKey = TRUE;
7f14c3 ¤   ¤   ¤   ¤   ¤   break;
252613 ¤   ¤   ¤   ¤   }
74a3a6 ¤   ¤   ¤   }
f5bb8c ¤   ¤   ¤   else
fef776 ¤   ¤   ¤   {
1abf09 ¤   ¤   ¤   ¤   anyKeysNotInRing = TRUE;
3fa3a6 ¤   ¤   ¤   }
a80fe4 ¤   ¤   }
a49371 ¤   }
6faf5a
28617f ¤   // Get header associated with the key if one was found.
b82361 ¤   if (derr.IsntError())
b8c7a1 ¤   {
5e78fc ¤   ¤   if (foundKey)
a05b34 ¤   ¤   {
d1b76b ¤   ¤   ¤   derr = GetHeaderForPublicKey(path, context, curKey, pubKeyHdr);
b20fe4 ¤   ¤   }
560e1d ¤   ¤   else
215b34 ¤   ¤   {
5fbe42 ¤   ¤   ¤   if (anyKeysNotInRing)
a2b4ec ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IncPassAndKeyNotInRing);
68bb8c ¤   ¤   ¤   else
3862cf ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_IncorrectPassphrase);
fc0fe4 ¤   ¤   }
7a9371 ¤   }
c3af5a
4f12ba ¤   if (gotDiskKeys)
88179d ¤   ¤   FreeRecipientSpecList(diskRecipKeys, numRecipKeys);
aeaf5a
a6fcc4 ¤   if (gotAllKeys)
2a4192 ¤   ¤   PGPFreeKeySet(allKeys);
aaaf5a
8cb0b2 ¤   if (gotContext)
403e8c ¤   ¤   PGPFreeContext(context);
75af5a
e033e3 ¤   return derr;
89efe6 }
e5af5a
196a7d // CheckIfLockedKeysOnKeyring checks if all the PGPdisk's locked public keys
e910a3 // are on the local keyring.
68af5a
872292 DualErr·
74d4ee CheckIfLockedKeysOnKeyring(LPCSTR path, PGPBoolean *pLockedKeysOnKeyring)
78bb36 {
099f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
b92eee ¤   File¤   ¤   ¤   ¤   ¤   diskFile;
24637d ¤   PGPBoolean¤ ¤   ¤   ¤   gotAllKeys, gotContext, gotItemList;
3b4178 ¤   PGPBoolean¤ ¤   ¤   ¤   lockedKeysOnKeyring;
b60b4c ¤   PGPByte¤¤   ¤   ¤   ¤   *exportedKeyID;
36429f ¤   PGPContextRef¤  ¤   ¤   context;
5b1a01 ¤   PGPdiskFileHeaderItem¤  *curItem, *itemList;
--2687 00064ad748640110171 Page 24 of PGPdiskPublicKeyUtils.cpp
f73f1b ¤   PGPKeyID¤   ¤   ¤   ¤   keyID;
0174c9 ¤   PGPKeyRef¤  ¤   ¤   ¤   pubKey;
dbae97 ¤   PGPKeySetRef¤   ¤   ¤   allKeys;
02af5a
cb2495 ¤   gotAllKeys = gotContext = gotItemList = FALSE;
31f8ef ¤   lockedKeysOnKeyring = TRUE;
7aaf5a
e1639f ¤   pgpAssertStrValid(path);
52a1c4 ¤   pgpAssertAddrValid(pLockedKeysOnKeyring, PGPBoolean);
d0af5a
a59e67 ¤   // Open the PGPdisk.
c62361 ¤   if (derr.IsntError())
05c7a1 ¤   {
d837f0 ¤   ¤   derr = diskFile.Open(path, kOF_MustExist | kOF_ReadOnly);
a79371 ¤   }
8e67c5 ¤
afd314 ¤   // Get list of headers.
b52361 ¤   if (derr.IsntError())
e4c7a1 ¤   {
490032 ¤   ¤   derr = GetHeaderItemList(&diskFile, &itemList);
4e70bb ¤   ¤   gotItemList = derr.IsntError();
c39371 ¤   }
f2af5a
aa96b6 ¤   // Search for locked keys.
ce2361 ¤   if (derr.IsntError())
1ac7a1 ¤   {
8c2fb6 ¤   ¤   curItem = itemList->next;
8baf5a
163628 ¤   ¤   // Get context ref.
c7e0ff ¤   ¤   derr = PGPNewContext(kPGPsdkAPIVersion, &context);
698a50 ¤   ¤   gotContext = derr.IsntError();
28af5a
e12abd ¤   ¤   // Open default key rings.
cbaa35 ¤   ¤   if (derr.IsntError())
c55b34 ¤   ¤   {
fb400c ¤   ¤   ¤   derr = PGPOpenDefaultKeyRings(context, 0, &allKeys);
1b4d58 ¤   ¤   ¤   gotAllKeys = derr.IsntError();
920fe4 ¤   ¤   }
4f1b52 ¤   ¤
89831d ¤   ¤   while (derr.IsntError() && IsntNull(curItem))
225b34 ¤   ¤   {
527766 ¤   ¤   ¤   if (IsPublicKeyHeader(curItem->hdr))
b0f776 ¤   ¤   ¤   {
297afe ¤   ¤   ¤   ¤   PGPdiskPublicKeyHeader *pubKeyHdr;
f2af5a
0fb23d ¤   ¤   ¤   ¤   pubKeyHdr = (PGPdiskPublicKeyHeader *) curItem->hdr;
18af5a
0b9cba ¤   ¤   ¤   ¤   // Is it locked?
440d0d ¤   ¤   ¤   ¤   if (pubKeyHdr->locked)
1872c3 ¤   ¤   ¤   ¤   {
d2390d ¤   ¤   ¤   ¤   ¤   // Import key ID.
888487 ¤   ¤   ¤   ¤   ¤   exportedKeyID = (PGPByte *) pubKeyHdr +·
86295b ¤   ¤   ¤   ¤   ¤   ¤   pubKeyHdr->keyIDOffset;
86af5a
386736 ¤   ¤   ¤   ¤   ¤   derr = PGPImportKeyID(exportedKeyID, &keyID);
c2af5a
114531 ¤   ¤   ¤   ¤   ¤   // Get actual key.
f54ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
b04859 ¤   ¤   ¤   ¤   ¤   {
647aab ¤   ¤   ¤   ¤   ¤   ¤   derr = PGPGetKeyByKeyID(allKeys, &keyID,·
79ebf1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pubKeyHdr->algorithm, &pubKey);
61af5a
c9919d ¤   ¤   ¤   ¤   ¤   ¤   // If failed, then bail.
14d647 ¤   ¤   ¤   ¤   ¤   ¤   if (derr.IsError())
268fec ¤   ¤   ¤   ¤   ¤   ¤   {
f1a13f ¤   ¤   ¤   ¤   ¤   ¤   ¤   derr = DualErr::NoError;
5b7eca ¤   ¤   ¤   ¤   ¤   ¤   ¤   lockedKeysOnKeyring = FALSE;
428c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
2adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
0d1c89 ¤   ¤   ¤   ¤   ¤   }
ac2613 ¤   ¤   ¤   ¤   }
64a3a6 ¤   ¤   ¤   }
--a560 00118a5dd3640110171 Page 25 of PGPdiskPublicKeyUtils.cpp
e0af5a
72782d ¤   ¤   ¤   curItem = curItem->next;
5a0fe4 ¤   ¤   }
ec9371 ¤   }
1daf5a
8394c6 ¤   (* pLockedKeysOnKeyring) = lockedKeysOnKeyring;
d8af5a
6ffcc4 ¤   if (gotAllKeys)
614192 ¤   ¤   PGPFreeKeySet(allKeys);
a5af5a
91b0b2 ¤   if (gotContext)
db3e8c ¤   ¤   PGPFreeContext(context);
25af5a
933020 ¤   if (gotItemList)
faa68d ¤   ¤   FreeHeaderItemList(itemList);
4daf5a
13d27f ¤   if (diskFile.Opened())
55d016 ¤   ¤   diskFile.Close();
4caf5a
5a33e3 ¤   return derr;
59efe6 }
10af5a
1838e4 #endif¤ // PGPDISK_PUBLIC_KEY
--291b 00076afec9340110172 Page 1 of PGPdiskPublicKeyUtils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
c34b83 // PGPdiskPublicKeyUtils.h
cd465d //
b70c53 // Declarations for PGPdiskPublicKeyUtils.cpp.
7f1bc3 //////////////////////////////////////////////////////////////////////////////
bbaf5a
c88ff2 // $Id: PGPdiskPublicKeyUtils.h,v 1.1.2.13.2.2 1998/10/22 22:28:04 nryan Exp $
85af5a
4dcbce // Copyright (C) 1998 by Network Associates, Inc.
9371ae // All rights reserved.
35af5a
12e0fc #ifndef¤Included_PGPdiskPublicKeyUtils_h¤   // [
8a258d #define¤Included_PGPdiskPublicKeyUtils_h
84af5a
acea4b #if PGPDISK_PUBLIC_KEY
3baf5a
9ec2ae #include "pgpGroups.h"
51a076 #include "pgpKeys.h"
ebe684 #include "pgpUserInterface.h"
b0af5a
733db7 #include "FatUtils.h"
94c16a #include "PGPdiskFileFormat.h"
442229 #include "PGPdiskLowLevelUtils.h"
35af5a
0f69ea #include "Cast5.h"
148f51 #include "CipherUtils.h"
43af5a
ecaf5a
a6d557 ////////
b702c9 // Types
e9d557 ////////
5faf5a
9f9bc8 class File;
59af5a
11af5a
cb6cc2 /////////////////////
eb13d2 // Exported functions
136cc2 /////////////////////
a5af5a
df70ed PGPBoolean¤ HavePGPsdk();
2e7099 PGPBoolean¤ DoesPGPdiskHavePublicKey(LPCSTR path);
aeaf5a
0e7e5b DualErr¤¤   IsKeyIDMemberOfRecipList(PGPKeyID goalKeyID,·
0b25f8 ¤   ¤   ¤   ¤   PGPRecipientSpec *recipList, PGPUInt32 size,·
6686b8 ¤   ¤   ¤   ¤   PGPBoolean *isMember);
1baf5a
a1b651 DualErr¤¤   AddRecipientSpecToList(PGPRecipientSpec **recipList,·
779366 ¤   ¤   ¤   ¤   PGPUInt32 size);
09af5a
5c116e void¤   ¤   FreeRecipientSpecList(PGPRecipientSpec *recipList,·
169366 ¤   ¤   ¤   ¤   PGPUInt32 size);
0faf5a
030f34 DualErr¤¤   GetPGPdiskRecipKeys(LPCSTR path, PGPContextRef context,·
2434d8 ¤   ¤   ¤   ¤   PGPKeySetRef allKeys, PGPRecipientSpec **pDiskRecipKeys,·
86c161 ¤   ¤   ¤   ¤   PGPUInt32 *pNumRecipKeys);
82af5a
132e37 DualErr¤¤   UpdatePGPdiskPublicKeys(LPCSTR path,·
df74d9 ¤   ¤   ¤   ¤   SecureString *masterPassphrase, PGPContextRef context,·
72db72 ¤   ¤   ¤   ¤   PGPKeySetRef allKeys, PGPRecipientSpec *newRecipKeys,·
c8eeda ¤   ¤   ¤   ¤   PGPUInt32 numRecipKeys, PGPBoolean newKeysReadOnly);
05af5a
bc778f DualErr¤¤   FindPublicKeyInHeaderList(File *diskFile, PGPContextRef context,·
77edc2 ¤   ¤   ¤   ¤   PGPKeyRef curKey, PGPdiskFileHeaderItem *itemList,·
88aa57 ¤   ¤   ¤   ¤   PGPdiskFileHeaderItem **keyItem);
efaf5a
620328 DualErr¤¤   GetHeaderForPublicKey(LPCSTR path, PGPContextRef context,·
335385 ¤   ¤   ¤   ¤   PGPKeyRef curKey, PGPdiskPublicKeyHeader **pubKeyHdr);
8daf5a
6cc68b DualErr¤¤   CreatePublicKeyHeader(PGPContextRef context, PGPKeyRef pubKey,·
2e4539 ¤   ¤   ¤   ¤   const CASTKey *decryptedKey, PGPBoolean locked,·
73d4dd ¤   ¤   ¤   ¤   PGPBoolean readOnly, PGPdiskPublicKeyHeader **outPubKeyHdr);
76af5a
--6fc4 001cab2a76f40110172 Page 2 of PGPdiskPublicKeyUtils.h
81d1a6 PGPBoolean¤ ArePGPdiskPassesWiped(LPCSTR path);
7daf5a
65d380 DualErr¤¤   ShowReadOnlyListOfPublicKeys(LPCSTR path);
68837c DualErr¤¤   WipeMasterAndAlternatePasses(LPCSTR path);
bdaf5a
c381b6 DualErr¤¤   IsTherePGPdiskADK(PGPContextRef context, PGPBoolean *isThereADK);
01af5a
67ed3f DualErr¤¤   GetADKUserID(PGPContextRef context, PGPKeySetRef allKeys,·
95aebe ¤   ¤   ¤   ¤   LPSTR userID, PGPUInt32 sizeUserID);
56af5a
a1a30d DualErr¤¤   GetADKKey(PGPContextRef context, PGPKeySetRef allKeys,·
3551de ¤   ¤   ¤   ¤   PGPKeyRef *ADKKey);
37af5a
499bee DualErr¤¤   AddADKToPGPdisk(LPCSTR path, SecureString *masterPassphrase);
cbaf5a
8e1d48 DualErr¤¤   DecryptPublicKey(PGPKeyRef pubKey, SecureString *passphrase,·
de0a91 ¤   ¤   ¤   ¤   const void *encryptedData, PGPSize encryptedDataSize,·
8b1250 ¤   ¤   ¤   ¤   const CheckBytes *checkBytes, CASTKey *decryptedKey);
cfaf5a
904973 DualErr¤¤   EncryptPublicKey(const CASTKey *decryptedKey, PGPKeyRef pubKey,·
f5a39a ¤   ¤   ¤   ¤   void **encryptedData, PGPUInt32 *encryptedDataSize,·
e1b225 ¤   ¤   ¤   ¤   CheckBytes *checkBytes);
47af5a
27062e DualErr¤¤   GetDecryptedKeyUsingPublicKey(SecureString *passphrase,·
9e1ac0 ¤   ¤   ¤   ¤   PGPdiskPublicKeyHeader *pubKeyHdr, CASTKey *decryptedKey);
c5af5a
fdf558 DualErr¤¤   FindPublicPGPdiskKeyHeader(LPCSTR path, SecureString *passphrase,·
205db3 ¤   ¤   ¤   ¤   PGPdiskPublicKeyHeader **pubKeyHdr);
ebaf5a
530e6f DualErr¤¤   CheckIfLockedKeysOnKeyring(LPCSTR path,·
c4ca32 ¤   ¤   ¤   ¤   PGPBoolean *pLockedKeysOnKeyring);
34af5a
e638e4 #endif¤ // PGPDISK_PUBLIC_KEY
4daf5a
cad891 #endif¤ // ] Included_PGPdiskPublicKeyUtils_h
--829e 00022f78aea40110173 Page 1 of PGPdiskRegistry.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
bc7b90 // PGPdiskRegistry.cpp
5c465d //
082877 // Functions for accessing the system registry.
4e1bc3 //////////////////////////////////////////////////////////////////////////////
6baf5a
a8a9ed // $Id: PGPdiskRegistry.cpp,v 1.1.2.6.2.1 1998/10/05 18:28:26 nryan Exp $
57af5a
ddcbce // Copyright (C) 1998 by Network Associates, Inc.
7f71ae // All rights reserved.
4aaf5a
e06931 #if defined(PGPDISK_MFC)
dfaf5a
a89e12 #include "StdAfx.h"
56af5a
cadb21 #else
2d333e #error Define PGPDISK_MFC.
9d05d6 #endif¤ // PGPDISK_MFC
b0af5a
579bcf #include "Required.h"
13babe #include "PGPdiskRegistry.h"
6cbfe9 #include "UtilityFunctions.h"
c7af5a
c6af5a
0909b7 ////////////
1ae738 // Constants
5809b7 ////////////
9aaf5a
f678c1 // The global path is under "HKEY_LOCAL_MACHINE" and contains preferences
040da4 // specific to all users.
48af5a
774d6b static LPCSTR kRegistryGlobalPath =·
751afe ¤   "SOFTWARE\\Network Associates\\PGPdisk";
e4af5a
e7b4e5 static LPCSTR kRegistryLocalPath =·
27a513 ¤   "Software\\Network Associates\\PGPdisk";
33af5a
869f6b static LPCSTR kRegistryLocalPGP60Path =·
4c8baf ¤   "Software\\Network Associates\\PGP60";
41af5a
c0af5a
655270 ////////////////////////////
b5fe20 // Low-Level Registry Access
735270 ////////////////////////////
7faf5a
ab355d // PGPdiskEnumSubkeys enumerates subkeys of a given key. Start with 'index'
9fe4ca // as 0 and then increment until 'isIndexValid' is set to FALSE.
70af5a
e22292 DualErr·
6c3cbe PGPdiskEnumSubkeys(
ba8ee8 ¤   HKEY¤   ¤   ¤   root,·
467892 ¤   LPCSTR¤ ¤   ¤   section,·
518077 ¤   PGPUInt32¤  ¤   index,·
a8d4f2 ¤   LPSTR¤  ¤   ¤   keyName,·
a74251 ¤   unsigned long¤  valueSize,·
d9e685 ¤   PGPBoolean¤ ¤   *isIndexValid)
b7bb36 {
72be41 ¤   DualErr¤¤   derr;
1dae25 ¤   HKEY¤   ¤   regHandle;
457eef ¤   PGPBoolean¤ openedKey¤  = FALSE;
f3f7e2 ¤   PGPUInt32¤  result;
bbaf5a
b1d7f4 ¤   pgpAssertStrValid(section);
43255f ¤   pgpAssertAddrValid(keyName, char);
2301d1 ¤   pgpAssertAddrValid(isIndexValid, PGPBoolean);
61af5a
008d7e ¤   result = RegOpenKeyEx(root, section, NULL, KEY_READ, &regHandle);
0baf5a
5e83a0 ¤   if (result != ERROR_SUCCESS)
7fc7a1 ¤   {
14aae4 ¤   ¤   derr = DualErr(kPGDMinorError_RegOpenKeyExFailed, result);
2274db ¤   ¤   openedKey = derr.IsntError();
--ffd1 0003c501b7f40110173 Page 2 of PGPdiskRegistry.cpp
a19371 ¤   }
93af5a
cf2361 ¤   if (derr.IsntError())
69c7a1 ¤   {
535877 ¤   ¤   result = RegEnumKeyEx(regHandle, index, keyName, &valueSize, NULL,·
ee2026 ¤   ¤   ¤   NULL, NULL, NULL);
43af5a
a196b8 ¤   ¤   if (result == ERROR_NO_MORE_ITEMS)
295b34 ¤   ¤   {
a22313 ¤   ¤   ¤   (* isIndexValid) = FALSE;
a70fe4 ¤   ¤   }
b1a39b ¤   ¤   else if (result != ERROR_SUCCESS)
aa5b34 ¤   ¤   {
a30212 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RegEnumKeyExFailed, result);
a60fe4 ¤   ¤   }
c40e1d ¤   ¤   else
c25b34 ¤   ¤   {
c2c132 ¤   ¤   ¤   (* isIndexValid) = TRUE;
c70fe4 ¤   ¤   }
939371 ¤   }
7baf5a
db3831 ¤   if (openedKey)
43dece ¤   ¤   RegCloseKey(regHandle);
8daf5a
0233e3 ¤   return derr;
adefe6 }
5aaf5a
ae9285 // PGPdiskEnumValues enumerates the names and types of the values under a
8017fc // given key. Start with 'index' ·as 0 and then increment until
945792 // 'isIndexValid' is set to FALSE.
04af5a
4e2292 DualErr·
65b256 PGPdiskEnumValues(
848ee8 ¤   HKEY¤   ¤   ¤   root,·
f47892 ¤   LPCSTR¤ ¤   ¤   section,·
678077 ¤   PGPUInt32¤  ¤   index,·
7f3af3 ¤   LPSTR¤  ¤   ¤   valueName,·
542b2a ¤   unsigned long¤  valueNameSize,·
e1f5e7 ¤   unsigned long¤  *valueType,·
5ce685 ¤   PGPBoolean¤ ¤   *isIndexValid)
78bb36 {
ecbe41 ¤   DualErr¤¤   derr;
68ae25 ¤   HKEY¤   ¤   regHandle;
717eef ¤   PGPBoolean¤ openedKey¤  = FALSE;
fff7e2 ¤   PGPUInt32¤  result;
f5af5a
5bd7f4 ¤   pgpAssertStrValid(section);
4414f9 ¤   pgpAssertAddrValid(valueName, char);
d801d1 ¤   pgpAssertAddrValid(isIndexValid, PGPBoolean);
b7af5a
dbcbdb ¤   if (IsntNull(valueType))
b4a74f ¤   ¤   pgpAssertAddrValid(valueType, unsigned long);
43af5a
488d7e ¤   result = RegOpenKeyEx(root, section, NULL, KEY_READ, &regHandle);
06af5a
f083a0 ¤   if (result != ERROR_SUCCESS)
91c7a1 ¤   {
e8aae4 ¤   ¤   derr = DualErr(kPGDMinorError_RegOpenKeyExFailed, result);
6a74db ¤   ¤   openedKey = derr.IsntError();
0b9371 ¤   }
e3af5a
c22361 ¤   if (derr.IsntError())
22c7a1 ¤   {
fd272b ¤   ¤   result = RegEnumValue(regHandle, index, valueName, &valueNameSize,·
2aa81a ¤   ¤   ¤   NULL, valueType, NULL, NULL);
43af5a
7f96b8 ¤   ¤   if (result == ERROR_NO_MORE_ITEMS)
a55b34 ¤   ¤   {
7d2313 ¤   ¤   ¤   (* isIndexValid) = FALSE;
780fe4 ¤   ¤   }
a6a39b ¤   ¤   else if (result != ERROR_SUCCESS)
3c5b34 ¤   ¤   {
--357b 000e1cd410640110173 Page 3 of PGPdiskRegistry.cpp
e6cd7d ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RegEnumValueFailed, result);
ab0fe4 ¤   ¤   }
730e1d ¤   ¤   else
ef5b34 ¤   ¤   {
83c132 ¤   ¤   ¤   (* isIndexValid) = TRUE;
710fe4 ¤   ¤   }
f49371 ¤   }
22af5a
743831 ¤   if (openedKey)
4cdece ¤   ¤   RegCloseKey(regHandle);
f0af5a
f433e3 ¤   return derr;
b1efe6 }
d0af5a
fcd45d // PGPdiskGetRawKey returns the data associated with the specified registry
3e5312 // key in the specified buffer.
a8af5a
a02292 DualErr·
d28fe5 PGPdiskGetRawKey(
de8ee8 ¤   HKEY¤   ¤   ¤   root,·
567892 ¤   LPCSTR¤ ¤   ¤   section,·
d7769a ¤   LPCSTR¤ ¤   ¤   keyName,·
02727c ¤   PGPUInt8¤   ¤   *buf,·
76200b ¤   unsigned long¤  bufSize)
74bb36 {
749a95 ¤   DualErr¤¤   ¤   derr;
7d5360 ¤   HKEY¤   ¤   ¤   regHandle;
ddd1cb ¤   PGPBoolean¤ ¤   openedKey¤  = FALSE;
6a31c0 ¤   PGPUInt32¤  ¤   result;
5d9782 ¤   unsigned long¤  valueType;
b9af5a
96b442 ¤   pgpAssertAddrValid(buf, PGPUInt8);
93d7f4 ¤   pgpAssertStrValid(section);
ecd9fc ¤   pgpAssertStrValid(keyName);
94af5a
ec8d7e ¤   result = RegOpenKeyEx(root, section, NULL, KEY_READ, &regHandle);
68af5a
0f83a0 ¤   if (result != ERROR_SUCCESS)
8fc7a1 ¤   {
a8aae4 ¤   ¤   derr = DualErr(kPGDMinorError_RegOpenKeyExFailed, result);
899371 ¤   }
3aaf5a
9e9ba8 ¤   openedKey = derr.IsntError();
4faf5a
472361 ¤   if (derr.IsntError())
eac7a1 ¤   {
7883e2 ¤   ¤   result = RegQueryValueEx(regHandle, keyName, NULL, &valueType,·
40df58 ¤   ¤   ¤   buf, &bufSize);
1daf5a
7cbec8 ¤   ¤   if (result != ERROR_SUCCESS)
e2b62e ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RegQueryValueExFailed, result);
7c9371 ¤   }
78af5a
b73831 ¤   if (openedKey)
2ddece ¤   ¤   RegCloseKey(regHandle);
f9af5a
d633e3 ¤   return derr;
8eefe6 }
a3af5a
4b3a04 // PGPdiskCreateAndSetRawKey creats and sets the value of any key in the
9d95d7 // registry, according to the parameters. It is a wrapper around
c43a58 // RegCreateKeyEx and RegSetValueEx.
b7af5a
332292 DualErr·
55fdda PGPdiskCreateAndSetRawKey(
688ee8 ¤   HKEY¤   ¤   ¤   root,·
777892 ¤   LPCSTR¤ ¤   ¤   section,·
41769a ¤   LPCSTR¤ ¤   ¤   keyName,·
0d60b0 ¤   const PGPUInt8¤ *value,·
151f4d ¤   PGPUInt32¤  ¤   valueSize,·
d5f1d1 ¤   PGPUInt32¤  ¤   dataType)
e1bb36 {
--327c 000ddb943bc40110173 Page 4 of PGPdiskRegistry.cpp
559a95 ¤   DualErr¤¤   ¤   derr;
765360 ¤   HKEY¤   ¤   ¤   regHandle;
16d1cb ¤   PGPBoolean¤ ¤   openedKey¤  = FALSE;
5831c0 ¤   PGPUInt32¤  ¤   result;
9aa294 ¤   unsigned long¤  disp;
06af5a
00d7f4 ¤   pgpAssertStrValid(section);
d2b0e7 ¤   pgpAssertAddrValid(value, PGPUInt8);
32af5a
c3d40a ¤   result = RegCreateKeyEx(root, section, 0, NULL, NULL, KEY_ALL_ACCESS,·
1ec230 ¤   ¤   NULL, &regHandle, &disp);
71af5a
a483a0 ¤   if (result != ERROR_SUCCESS)
f5c7a1 ¤   {
c38f27 ¤   ¤   derr = DualErr(kPGDMinorError_RegCreateKeyExFailed, result);
f89371 ¤   }
72af5a
0f9ba8 ¤   openedKey = derr.IsntError();
40af5a
922361 ¤   if (derr.IsntError())
0ec7a1 ¤   {
f50452 ¤   ¤   result = RegSetValueEx(regHandle, keyName, 0, dataType, value,·
ebabdf ¤   ¤   ¤   valueSize);
5caf5a
d3bec8 ¤   ¤   if (result != ERROR_SUCCESS)
d153b7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RegSetValueExFailed, result);
f49371 ¤   }
e9af5a
053831 ¤   if (openedKey)
1cdece ¤   ¤   RegCloseKey(regHandle);
d0af5a
5833e3 ¤   return derr;
16efe6 }
00af5a
d41bab // PGPdiskDeleteSubkey deletes the specified subkey.
bdaf5a
a02292 DualErr·
95b3e0 PGPdiskDeleteSubkey(HKEY root, LPCSTR section, LPCSTR keyName)
fcbb36 {
69be41 ¤   DualErr¤¤   derr;
92ae25 ¤   HKEY¤   ¤   regHandle;
817eef ¤   PGPBoolean¤ openedKey¤  = FALSE;
55f7e2 ¤   PGPUInt32¤  result;
a5af5a
03d7f4 ¤   pgpAssertStrValid(section);
33d9fc ¤   pgpAssertStrValid(keyName);
64af5a
edb606 ¤   result = RegOpenKeyEx(root, section, NULL, KEY_ALL_ACCESS, &regHandle);
e1af5a
2983a0 ¤   if (result != ERROR_SUCCESS)
16c7a1 ¤   {
27aae4 ¤   ¤   derr = DualErr(kPGDMinorError_RegOpenKeyExFailed, result);
ad74db ¤   ¤   openedKey = derr.IsntError();
939371 ¤   }
a1af5a
df2361 ¤   if (derr.IsntError())
e1c7a1 ¤   {
733a74 ¤   ¤   result = RegDeleteKey(regHandle, keyName);
71af5a
57bec8 ¤   ¤   if (result != ERROR_SUCCESS)
bcf854 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RegDeleteKeyFailed, result);
ce9371 ¤   }
88af5a
2aaf5a
883831 ¤   if (openedKey)
14dece ¤   ¤   RegCloseKey(regHandle);
75af5a
4533e3 ¤   return derr;
f0efe6 }
26af5a
b4259c // PGPdiskDeleteSubkey deletes the specified value.
ddaf5a
--3e6a 000b3c71b2940110173 Page 5 of PGPdiskRegistry.cpp
782292 DualErr·
6e8e1a PGPdiskDeleteValue(HKEY root, LPCSTR section, LPCSTR valueName)
38bb36 {
b3be41 ¤   DualErr¤¤   derr;
ebae25 ¤   HKEY¤   ¤   regHandle;
777eef ¤   PGPBoolean¤ openedKey¤  = FALSE;
baf7e2 ¤   PGPUInt32¤  result;
12af5a
78d7f4 ¤   pgpAssertStrValid(section);
3bfbd9 ¤   pgpAssertStrValid(valueName);
7faf5a
1cb606 ¤   result = RegOpenKeyEx(root, section, NULL, KEY_ALL_ACCESS, &regHandle);
9aaf5a
7c83a0 ¤   if (result != ERROR_SUCCESS)
05c7a1 ¤   {
beaae4 ¤   ¤   derr = DualErr(kPGDMinorError_RegOpenKeyExFailed, result);
5274db ¤   ¤   openedKey = derr.IsntError();
ec9371 ¤   }
dbaf5a
e62361 ¤   if (derr.IsntError())
68c7a1 ¤   {
b132df ¤   ¤   result = RegDeleteValue(regHandle, valueName);
21af5a
21bec8 ¤   ¤   if (result != ERROR_SUCCESS)
f20020 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_RegDeleteValueFailed, result);
619371 ¤   }
6aaf5a
c1af5a
aa3831 ¤   if (openedKey)
b4dece ¤   ¤   RegCloseKey(regHandle);
e3af5a
0e33e3 ¤   return derr;
2defe6 }
49af5a
46af5a
445270 ////////////////////////////
2e5bb3 // Mid-Level Registry Access
d65270 ////////////////////////////
a4af5a
e2cef9 // PGPdiskGetPrefDWord gets the DWORD value of a key from the PGPdisk
bff515 // preferences. If there is an error, 'defaultDWord' is returned.
abaf5a
891b0b PGPUInt32·
967030 PGPdiskGetPrefDWord(
9570a5 ¤   LPCSTR¤ ¤   ¤   ¤   regKey,·
050cf3 ¤   PGPUInt32¤  ¤   ¤   defaultDWord,·
efe81f ¤   PGPdiskRegLocation¤ regLoc)
aebb36 {
dd8347 ¤   CString¤¤   regSection;
c7be41 ¤   DualErr¤¤   derr;
202029 ¤   HKEY¤   ¤   regRoot;
f7adc4 ¤   PGPUInt32¤  theDWord;
e3af5a
3978f1 ¤   try
25c7a1 ¤   {
f44ef3 ¤   ¤   switch (regLoc)
735b34 ¤   ¤   {
716fb1 ¤   ¤   case kPRL_CurrentUser:
815773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
c251a5 ¤   ¤   ¤   regSection = kRegistryLocalPath;
12cdcb ¤   ¤   ¤   break;
b1af5a
45e252 ¤   ¤   case kPRL_LocalMachine:
8b699a ¤   ¤   ¤   regRoot = HKEY_LOCAL_MACHINE;
1f3a25 ¤   ¤   ¤   regSection = kRegistryGlobalPath;
abcdcb ¤   ¤   ¤   break;
d4af5a
a356f9 ¤   ¤   case kPRL_PGP60CurrentUser:
245773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
9c246e ¤   ¤   ¤   regSection = kRegistryLocalPGP60Path;
a1cdcb ¤   ¤   ¤   break;
b3af5a
--01c9 000cafed31540110173 Page 6 of PGPdiskRegistry.cpp
d39ae3 ¤   ¤   default:
b30606 ¤   ¤   ¤   pgpAssert(FALSE);
f9cdcb ¤   ¤   ¤   break;
9a0fe4 ¤   ¤   }
dc9371 ¤   }
283c88 ¤   catch (CMemoryException *ex)
38c7a1 ¤   {
68ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
506adc ¤   ¤   ex->Delete();
869371 ¤   }
3faf5a
322361 ¤   if (derr.IsntError())
70c7a1 ¤   {
9800a2 ¤   ¤   derr = PGPdiskGetRawKey(regRoot, regSection, regKey,·
b3b3e1 ¤   ¤   ¤   (PGPUInt8 *) &theDWord, sizeof(theDWord));
5d9371 ¤   }
16af5a
7b4bb3 ¤   if (derr.IsError())
17c7a1 ¤   {
377bb0 ¤   ¤   return defaultDWord;
be9371 ¤   }
b10e24 ¤   else
acc7a1 ¤   {
c216c0 ¤   ¤   return theDWord;
549371 ¤   }
44efe6 }
dbaf5a
a46874 // PGPdiskSetPrefDWord sets the DWORD value of a key from the PGPdisk
0c0ef8 // preferences.
36af5a
bf2292 DualErr·
b9555e PGPdiskSetPrefDWord(
8770a5 ¤   LPCSTR¤ ¤   ¤   ¤   regKey,·
da3820 ¤   PGPUInt32¤  ¤   ¤   newDWord,·
3ae81f ¤   PGPdiskRegLocation¤ regLoc)
92bb36 {
05a4bd ¤   CString¤regSection;
9da5fc ¤   HKEY¤   regRoot;
30945d ¤   DualErr¤derr;
48af5a
be78f1 ¤   try
dbc7a1 ¤   {
234ef3 ¤   ¤   switch (regLoc)
385b34 ¤   ¤   {
236fb1 ¤   ¤   case kPRL_CurrentUser:
315773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
7051a5 ¤   ¤   ¤   regSection = kRegistryLocalPath;
aacdcb ¤   ¤   ¤   break;
c6af5a
18e252 ¤   ¤   case kPRL_LocalMachine:
0d699a ¤   ¤   ¤   regRoot = HKEY_LOCAL_MACHINE;
a13a25 ¤   ¤   ¤   regSection = kRegistryGlobalPath;
3bcdcb ¤   ¤   ¤   break;
99af5a
6b56f9 ¤   ¤   case kPRL_PGP60CurrentUser:
e15773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
3c246e ¤   ¤   ¤   regSection = kRegistryLocalPGP60Path;
b4cdcb ¤   ¤   ¤   break;
93af5a
f29ae3 ¤   ¤   default:
5b0606 ¤   ¤   ¤   pgpAssert(FALSE);
ddcdcb ¤   ¤   ¤   break;
170fe4 ¤   ¤   }
d09371 ¤   }
cd3c88 ¤   catch (CMemoryException *ex)
5dc7a1 ¤   {
c7ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
5b6adc ¤   ¤   ex->Delete();
b09371 ¤   }
38af5a
992361 ¤   if (derr.IsntError())
cac7a1 ¤   {
--b759 000e4656cec40110173 Page 7 of PGPdiskRegistry.cpp
b65b05 ¤   ¤   derr = PGPdiskCreateAndSetRawKey(regRoot, regSection, regKey,·
d06a71 ¤   ¤   ¤   (PGPUInt8 *) &newDWord, sizeof(newDWord), REG_DWORD);
c89371 ¤   }
53af5a
6433e3 ¤   return derr;
0aefe6 }
b4af5a
fc40a9 // PGPdiskGetPrefQWord gets the 64-bit QWord value of a key from the PGPdisk
d2d295 // preferences. If there is an error, 'defaultQWord' is returned.
9faf5a
86a385 PGPUInt64·
7a355a PGPdiskGetPrefQWord(
3470a5 ¤   LPCSTR¤ ¤   ¤   ¤   regKey,·
accb1e ¤   PGPUInt64¤  ¤   ¤   defaultQWord,·
dce81f ¤   PGPdiskRegLocation¤ regLoc)
65bb36 {
098347 ¤   CString¤¤   regSection;
7ebe41 ¤   DualErr¤¤   derr;
b52029 ¤   HKEY¤   ¤   regRoot;
ef8650 ¤   PGPUInt64¤  theQWord;
b0af5a
7578f1 ¤   try
1ec7a1 ¤   {
544ef3 ¤   ¤   switch (regLoc)
915b34 ¤   ¤   {
4d6fb1 ¤   ¤   case kPRL_CurrentUser:
645773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
bf51a5 ¤   ¤   ¤   regSection = kRegistryLocalPath;
14cdcb ¤   ¤   ¤   break;
79af5a
49e252 ¤   ¤   case kPRL_LocalMachine:
18699a ¤   ¤   ¤   regRoot = HKEY_LOCAL_MACHINE;
b43a25 ¤   ¤   ¤   regSection = kRegistryGlobalPath;
37cdcb ¤   ¤   ¤   break;
8aaf5a
2e56f9 ¤   ¤   case kPRL_PGP60CurrentUser:
695773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
f8246e ¤   ¤   ¤   regSection = kRegistryLocalPGP60Path;
d9cdcb ¤   ¤   ¤   break;
52af5a
109ae3 ¤   ¤   default:
f90606 ¤   ¤   ¤   pgpAssert(FALSE);
76cdcb ¤   ¤   ¤   break;
3f0fe4 ¤   ¤   }
389371 ¤   }
423c88 ¤   catch (CMemoryException *ex)
97c7a1 ¤   {
a4ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
e56adc ¤   ¤   ex->Delete();
069371 ¤   }
85af5a
ed2361 ¤   if (derr.IsntError())
1fc7a1 ¤   {
3c00a2 ¤   ¤   derr = PGPdiskGetRawKey(regRoot, regSection, regKey,·
fc6b82 ¤   ¤   ¤   (PGPUInt8 *) &theQWord, sizeof(theQWord));
4f9371 ¤   }
31af5a
b94bb3 ¤   if (derr.IsError())
30c7a1 ¤   {
0d3eda ¤   ¤   return defaultQWord;
4c9371 ¤   }
3c0e24 ¤   else
19c7a1 ¤   {
1c53aa ¤   ¤   return theQWord;
609371 ¤   }
ecefe6 }
22af5a
556eb4 // PGPdiskSetPrefQWord sets the QWORD value of a key from the PGPdisk
b90ef8 // preferences.
39af5a
342292 DualErr·
e41034 PGPdiskSetPrefQWord(
--c06d 0001c99b25840110173 Page 8 of PGPdiskRegistry.cpp
4b70a5 ¤   LPCSTR¤ ¤   ¤   ¤   regKey,·
46e6f9 ¤   PGPUInt64¤  ¤   ¤   newQWord,·
d6e81f ¤   PGPdiskRegLocation¤ regLoc)
e4bb36 {
1da4bd ¤   CString¤regSection;
25a5fc ¤   HKEY¤   regRoot;
d5945d ¤   DualErr¤derr;
c0af5a
3878f1 ¤   try
30c7a1 ¤   {
ca4ef3 ¤   ¤   switch (regLoc)
de5b34 ¤   ¤   {
996fb1 ¤   ¤   case kPRL_CurrentUser:
505773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
ec51a5 ¤   ¤   ¤   regSection = kRegistryLocalPath;
edcdcb ¤   ¤   ¤   break;
f3af5a
41e252 ¤   ¤   case kPRL_LocalMachine:
71699a ¤   ¤   ¤   regRoot = HKEY_LOCAL_MACHINE;
2f3a25 ¤   ¤   ¤   regSection = kRegistryGlobalPath;
53cdcb ¤   ¤   ¤   break;
48af5a
9056f9 ¤   ¤   case kPRL_PGP60CurrentUser:
a05773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
ae246e ¤   ¤   ¤   regSection = kRegistryLocalPGP60Path;
c6cdcb ¤   ¤   ¤   break;
40af5a
919ae3 ¤   ¤   default:
4a0606 ¤   ¤   ¤   pgpAssert(FALSE);
1dcdcb ¤   ¤   ¤   break;
d00fe4 ¤   ¤   }
2f9371 ¤   }
893c88 ¤   catch (CMemoryException *ex)
c5c7a1 ¤   {
adecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
be6adc ¤   ¤   ex->Delete();
4f9371 ¤   }
cfaf5a
752361 ¤   if (derr.IsntError())
50c7a1 ¤   {
435b05 ¤   ¤   derr = PGPdiskCreateAndSetRawKey(regRoot, regSection, regKey,·
8ef049 ¤   ¤   ¤   (PGPUInt8 *) &newQWord, sizeof(newQWord), REG_BINARY);
839371 ¤   }
35af5a
1733e3 ¤   return derr;
67efe6 }
d7af5a
5bd23d // PGPdiskGetPrefString gets the string value of a key from the PGPdisk
950ef8 // preferences.
daaf5a
17c823 void·
d7966d PGPdiskGetPrefString(
e770a5 ¤   LPCSTR¤ ¤   ¤   ¤   regKey,·
148385 ¤   LPCSTR¤ ¤   ¤   ¤   defaultString,·
5d720a ¤   CString¤¤   ¤   ¤   *outputString, ·
6de81f ¤   PGPdiskRegLocation¤ regLoc)
85bb36 {
3aa4bd ¤   CString¤regSection;
e8a5fc ¤   HKEY¤   regRoot;
4f945d ¤   DualErr¤derr;
d4af5a
a2332f ¤   pgpAssertAddrValid(outputString, CString);
16af5a
2b78f1 ¤   try
d6c7a1 ¤   {
af4ef3 ¤   ¤   switch (regLoc)
725b34 ¤   ¤   {
976fb1 ¤   ¤   case kPRL_CurrentUser:
1b5773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
ed51a5 ¤   ¤   ¤   regSection = kRegistryLocalPath;
f5cdcb ¤   ¤   ¤   break;
1caf5a
--13b5 00030cb0e7340110173 Page 9 of PGPdiskRegistry.cpp
b4e252 ¤   ¤   case kPRL_LocalMachine:
93699a ¤   ¤   ¤   regRoot = HKEY_LOCAL_MACHINE;
f63a25 ¤   ¤   ¤   regSection = kRegistryGlobalPath;
51cdcb ¤   ¤   ¤   break;
3daf5a
b456f9 ¤   ¤   case kPRL_PGP60CurrentUser:
1b5773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
57246e ¤   ¤   ¤   regSection = kRegistryLocalPGP60Path;
d7cdcb ¤   ¤   ¤   break;
a2af5a
3b9ae3 ¤   ¤   default:
270606 ¤   ¤   ¤   pgpAssert(FALSE);
76cdcb ¤   ¤   ¤   break;
740fe4 ¤   ¤   }
89af5a
e5aa35 ¤   ¤   if (derr.IsntError())
f25b34 ¤   ¤   {
4fbcbb ¤   ¤   ¤   derr = PGPdiskGetRawKey(regRoot, regSection, regKey,·
dd0b39 ¤   ¤   ¤   ¤   (PGPUInt8 *) outputString->GetBuffer(kMaxStringSize),·
24fbb1 ¤   ¤   ¤   ¤   kMaxStringSize);
f1af5a
2f471b ¤   ¤   ¤   outputString->ReleaseBuffer();
c90fe4 ¤   ¤   }
8aaf5a
65bdd6 ¤   ¤   if (derr.IsError())
925b34 ¤   ¤   {
512d9e ¤   ¤   ¤   (* outputString) = defaultString;
bf0fe4 ¤   ¤   }
f29371 ¤   }
063c88 ¤   catch (CMemoryException *ex)
76c7a1 ¤   {
94ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
2c6adc ¤   ¤   ex->Delete();
739371 ¤   }
81efe6 }
40af5a
392f06 // PGPdiskSetPrefString sets the string value of a key from the PGPdisk
1d0ef8 // preferences.
21af5a
622292 DualErr·
981c30 PGPdiskSetPrefString(
0f70a5 ¤   LPCSTR¤ ¤   ¤   ¤   regKey,·
b3f66f ¤   LPCSTR¤ ¤   ¤   ¤   newString,·
9ee81f ¤   PGPdiskRegLocation¤ regLoc)
3ebb36 {
04a4bd ¤   CString¤regSection;
ffa5fc ¤   HKEY¤   regRoot;
28945d ¤   DualErr¤derr;
61af5a
909e79 ¤   pgpAssertStrValid(newString);
c9af5a
ed78f1 ¤   try
83c7a1 ¤   {
174ef3 ¤   ¤   switch (regLoc)
965b34 ¤   ¤   {
0b6fb1 ¤   ¤   case kPRL_CurrentUser:
7f5773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
bb51a5 ¤   ¤   ¤   regSection = kRegistryLocalPath;
f2cdcb ¤   ¤   ¤   break;
98af5a
6de252 ¤   ¤   case kPRL_LocalMachine:
df699a ¤   ¤   ¤   regRoot = HKEY_LOCAL_MACHINE;
883a25 ¤   ¤   ¤   regSection = kRegistryGlobalPath;
fdcdcb ¤   ¤   ¤   break;
fcaf5a
5d56f9 ¤   ¤   case kPRL_PGP60CurrentUser:
235773 ¤   ¤   ¤   regRoot = HKEY_CURRENT_USER;
08246e ¤   ¤   ¤   regSection = kRegistryLocalPGP60Path;
73cdcb ¤   ¤   ¤   break;
5faf5a
389ae3 ¤   ¤   default:
300606 ¤   ¤   ¤   pgpAssert(FALSE);
--741b 00029a56af640110173 Page 10 of PGPdiskRegistry.cpp
7ecdcb ¤   ¤   ¤   break;
690fe4 ¤   ¤   }
209371 ¤   }
543c88 ¤   catch (CMemoryException *ex)
70c7a1 ¤   {
65ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
c16adc ¤   ¤   ex->Delete();
759371 ¤   }
beaf5a
e32361 ¤   if (derr.IsntError())
99c7a1 ¤   {
a55b05 ¤   ¤   derr = PGPdiskCreateAndSetRawKey(regRoot, regSection, regKey,·
7abc34 ¤   ¤   ¤   (PGPUInt8 *) newString, strlen(newString), REG_SZ);
e19371 ¤   }
ceaf5a
2b33e3 ¤   return derr;
73efe6 }
aeaf5a
4d8104 /////////////////////////////
4dc18e // High-Level Registry Access
c98104 /////////////////////////////
87af5a
9f96e8 // RecallWindowPos recalls the position of a given window from the given
bbf281 // registry key.
cdaf5a
f0c823 void·
160ad1 RecallWindowPos(CWnd *pWnd, LPCSTR wndCoordsKey)
7dbb36 {
02f3f8 ¤   PGPUInt32 coords;
b1af5a
21d027 ¤   pgpAssertAddrValid(pWnd, CWnd);
7631fc ¤   pgpAssertStrValid(wndCoordsKey);
ccaf5a
905f77 ¤   coords = PGPdiskGetPrefDWord(wndCoordsKey, kInvalidRegDWordValue);
73af5a
9782db ¤   // Move the window if the key exists.
89f6c1 ¤   if (coords != kInvalidRegDWordValue)
b3c7a1 ¤   {
b2e0d0 ¤   ¤   PGPUInt16 x = GetLowWord(coords);
a9132f ¤   ¤   PGPUInt16 y = GetHighWord(coords);
1caf5a
55aaef ¤   ¤   if ((x >= 0) && (y >= 0) &&
6cd289 ¤   ¤   ¤   (x < GetSystemMetrics(SM_CXSCREEN)) &&
c971fb ¤   ¤   ¤   (y < GetSystemMetrics(SM_CYSCREEN)))
015b34 ¤   ¤   {
b95d9e ¤   ¤   ¤   pWnd->SetWindowPos(&CWnd::wndTop, x, y, 0, 0,·
499a57 ¤   ¤   ¤   ¤   SWP_NOSIZE | SWP_NOZORDER);
2f0fe4 ¤   ¤   }
9b9371 ¤   }
63efe6 }
feaf5a
9210e5 // SaveWindowPos saves the position of a given window in the given registry
d2e306 // key.
72af5a
b4c823 void·
ba6d85 SaveWindowPos(CWnd *pWnd, LPCSTR wndCoordsKey)
1abb36 {
2aee37 ¤   PGPUInt32¤  coords;
604119 ¤   RECT¤   ¤   rect;
68af5a
deee99 ¤   pgpAssertAddrValid(pWnd, Wnd);
2a31fc ¤   pgpAssertStrValid(wndCoordsKey);
c7af5a
dc4fa7 ¤   pWnd->GetWindowRect(&rect);
4f09b9 ¤   coords = MakeLong((PGPUInt16) rect.left, (PGPUInt16) rect.top);
b1af5a
2656c1 ¤   PGPdiskSetPrefDWord(wndCoordsKey, coords);
4cefe6 }
48af5a
6b8ed5 #if PGPDISK_BETAVERSION
0aaf5a
295fac // HasBetaTimedOut returns TRUE if this beta version of PGPdisk has timed
--5da7 000a74d688640110173 Page 11 of PGPdiskRegistry.cpp
1c4d36 // out, FALSE otherwise.
16af5a
7b77be PGPBoolean·
fc89c6 HasBetaTimedOut()
2cbb36 {
0404bb ¤   PGPUInt64 currentTime, timeoutTime;
9aaf5a
ea5cc9 ¤   // Get the current time.
1ed77a ¤   currentTime = GetSecondsSince1970();
e3af5a
d4b0a4 ¤   // Get the timeout time.
5ea2d6 ¤   timeoutTime = PGPdiskGetPrefQWord(kRegistryBetaTimeoutKey,·
deb01e ¤   ¤   kInvalidRegQWordValue);
58af5a
a96aaf ¤   // If we've exceeded the timeout data, return TRUE.
bda273 ¤   if (timeoutTime != kInvalidRegQWordValue)
6fffe9 ¤   ¤   return (currentTime >= timeoutTime);
340e24 ¤   else
ed98aa ¤   ¤   return FALSE;
65efe6 }
31af5a
e70ac6 // SetPGPdiskBetaTimeout burns a beta timeout date into the registry, but
1883d5 // only if no date is there already.
f7af5a
7f2292 DualErr·
5d03b8 SetPGPdiskBetaTimeout()
5abb36 {
34be41 ¤   DualErr¤¤   derr;
e25525 ¤   PGPUInt64¤  timeoutTime;
23af5a
c1a2d6 ¤   timeoutTime = PGPdiskGetPrefQWord(kRegistryBetaTimeoutKey,·
92b01e ¤   ¤   kInvalidRegQWordValue);
d6af5a
bc18da ¤   // If no demo timeout has been set, set it now.
57602a ¤   if (timeoutTime == kInvalidRegQWordValue)
30c7a1 ¤   {
5606b6 ¤   ¤   FILETIME¤   fileTimeoutTime;
69ec85 ¤   ¤   SYSTEMTIME¤ sysTimeoutTime;
f2af5a
c85775 ¤   ¤   // Prepare data structure with target timeout date.
7293d9 ¤   ¤   pgpClearMemory(&sysTimeoutTime, sizeof(sysTimeoutTime));
18af5a
bb2dda ¤   ¤   sysTimeoutTime.wYear¤   = kPGPdiskBetaTimeoutYear;
f19618 ¤   ¤   sysTimeoutTime.wMonth¤  = kPGPdiskBetaTimeoutMonth;
8c4654 ¤   ¤   sysTimeoutTime.wDay¤¤   = kPGPdiskBetaTimeoutDay;
faaf5a
f5b93a ¤   ¤   // Convert it to a 64-bit value.
9b98e9 ¤   ¤   SystemTimeToFileTime(&sysTimeoutTime, &fileTimeoutTime);
efaf5a
677bc8 ¤   ¤   // Convert it to standard form.
4dce1c ¤   ¤   timeoutTime = ConvertFileTimeToSecondsSince1970(&fileTimeoutTime);
9daf5a
c57bde ¤   ¤   // Set the timeout time.
82e051 ¤   ¤   derr = PGPdiskSetPrefQWord(kRegistryBetaTimeoutKey, timeoutTime);
ba9371 ¤   }
d5af5a
d233e3 ¤   return derr;
ecefe6 }
e9af5a
cc5766 #elif PGPDISK_DEMOVERSION
e7af5a
549fd7 // HasDemoTimedOut returns TRUE if this demo version of PGPdisk has timed
9f4d36 // out, FALSE otherwise.
6faf5a
3677be PGPBoolean·
e64e1f HasDemoTimedOut()
d5bb36 {
3504bb ¤   PGPUInt64 currentTime, timeoutTime;
16af5a
585cc9 ¤   // Get the current time.
2ad77a ¤   currentTime = GetSecondsSince1970();
a7af5a
--2438 001ff2a5bc140110173 Page 12 of PGPdiskRegistry.cpp
a6b0a4 ¤   // Get the timeout time.
f59846 ¤   timeoutTime = PGPdiskGetPrefQWord(kRegistryDemoTimeoutKey,·
64b01e ¤   ¤   kInvalidRegQWordValue);
8daf5a
b86aaf ¤   // If we've exceeded the timeout data, return TRUE.
1fa273 ¤   if (timeoutTime != kInvalidRegQWordValue)
ebffe9 ¤   ¤   return (currentTime >= timeoutTime);
9f0e24 ¤   else
fa98aa ¤   ¤   return FALSE;
30efe6 }
79af5a
bcd973 // SetPGPdiskDemoTimeout burns a demo timeout date into the registry, but
a483d5 // only if no date is there already.
05af5a
162292 DualErr·
89de69 SetPGPdiskDemoTimeout()
26bb36 {
0ebe41 ¤   DualErr¤¤   derr;
195525 ¤   PGPUInt64¤  timeoutTime;
41af5a
309846 ¤   timeoutTime = PGPdiskGetPrefQWord(kRegistryDemoTimeoutKey,·
5db01e ¤   ¤   kInvalidRegQWordValue);
96af5a
4318da ¤   // If no demo timeout has been set, set it now.
b4602a ¤   if (timeoutTime == kInvalidRegQWordValue)
f2c7a1 ¤   {
8e6b04 ¤   ¤   // Determine the timeout time.
78c7b6 ¤   ¤   timeoutTime = GetSecondsSince1970() + kDemoTimeoutDays*kSecondsInADay;
20af5a
cd7bde ¤   ¤   // Set the timeout time.
574a1c ¤   ¤   derr = PGPdiskSetPrefQWord(kRegistryDemoTimeoutKey, timeoutTime);
259371 ¤   }
d5af5a
c633e3 ¤   return derr;
4aefe6 }
11af5a
ffe121 #endif // PGPDISK_BETAVERSION
--4db6 000f45d371040110174 Page 1 of PGPdiskRegistry.h
541bc3 //////////////////////////////////////////////////////////////////////////////
ed6700 // PGPdiskRegistry.h
2c465d //
8b987a // Declarations for PGPdiskRegistry.cpp.
ae1bc3 //////////////////////////////////////////////////////////////////////////////
7daf5a
0a793c // $Id: PGPdiskRegistry.h,v 1.1.2.7.2.1 1998/10/05 18:28:27 nryan Exp $
aaaf5a
abcbce // Copyright (C) 1998 by Network Associates, Inc.
e271ae // All rights reserved.
42af5a
0bd903 #ifndef Included_PGPdiskRegistry_h¤ // [
7aa5a8 #define Included_PGPdiskRegistry_h
92af5a
0e3a85 #include "DualErr.h"
58af5a
edaf5a
3209b7 ////////////
1ce738 // Constants
7c09b7 ////////////
dfaf5a
7bdfc9 const PGPUInt32¤kInvalidRegDWordValue¤  = 0xFFFFFFFF;
ad1f1f const PGPUInt64¤kInvalidRegQWordValue¤  = 0xFFFFFFFFFFFFFFFF;
2baf5a
0108a0 // Under "HKEY_CURRENT_USER\Software\Network Associates\PGP60".
17af5a
6aa54e static LPCSTR¤  kRegistryPGP60LicenseUserKey¤   = "User";
6f4795 static LPCSTR¤  kRegistryPGP60LicenseOrgKey¤¤   = "Company Name";
ecaf5a
31d697 // Under "HKEY_CURRENT_USER\Software\Network Associates\PGPdisk".
b6af5a
b84176 static LPCSTR¤  kRegistryLicenseUserKey¤¤   = "User";
8516be static LPCSTR¤  kRegistryLicenseOrgKey¤ ¤   = "Company Name";
2a116a static LPCSTR¤  kRegistryLastOpenDirKey¤¤   = "LastOpenDir";
364d21 static LPCSTR¤  kRegistryLastSaveDirKey¤¤   = "LastSaveDir";
2e22dc static LPCSTR¤  kRegistryLastCreateSizeKey¤ = "LastCreateSize";
b4c9a0 static LPCSTR¤  kRegistryLastCreateScaleKey¤= "LastCreateScale";
526eb0 static LPCSTR¤  kRegistryLastDateSplashKey¤ = "LastDateSplashed";
8c6887 static LPCSTR¤  kRegistryWasDialogSmallKey¤ = "WasMainDialogSmall";
d9b6fb static LPCSTR¤  kRegistryMainCoordsKey¤ ¤   = "MainWindowCoords";
6d338f static LPCSTR¤  kRegistryMainStayOnTopKey¤  = "MainWndStayOnTop";
0fb733 static LPCSTR¤  kRegistryAutoUnmountKey¤¤   = "AutoUnmount";
df5919 static LPCSTR¤  kRegistryHotKeyCodeKey¤ ¤   = "HotKeyCode";
1da862 static LPCSTR¤  kRegistryHotKeyEnabledKey¤  = "HotKeyEnabled";
1896f2 static LPCSTR¤  kRegistryUnmountOnSleepKey¤ = "UnmountOnSleep";
51ddc0 static LPCSTR¤  kRegistryNoSleepIfFailKey¤  = "NoSleepIfUnmountFail";
11ed26 static LPCSTR¤  kRegistryUnmountTimeoutKey¤ = "UnmountTimeout";
a3f183 static LPCSTR¤  kRegistryPGPdiskVolsKey¤¤   = "PGPdiskVols";
3aaf5a
9c5c98 #if PGP_DEBUG
5fc3ef static LPCSTR¤  kRegistryUseAsyncIOKey¤ ¤   = "UseAsyncIO";
2c1e67 #endif¤ // PGP_DEBUG
d1af5a
0a8ed5 #if PGPDISK_BETAVERSION
013c09 static LPCSTR¤  kRegistryBetaTimeoutKey¤¤   = "BetaTimeout";
5b5766 #elif PGPDISK_DEMOVERSION
cc70ba static LPCSTR¤  kRegistryDemoTimeoutKey¤¤   = "DemoTimeout";
31e121 #endif // PGPDISK_BETAVERSION
5caf5a
013c3f // Shift state flags for the hotkey.
7ae8a4 const PGPUInt8¤ kSHK_Control¤   = 0x01;
cbbe67 const PGPUInt8¤ kSHK_Alt¤   ¤   = 0x02;
e8db9f const PGPUInt8¤ kSHK_Shift¤ ¤   = 0x04;
912661 const PGPUInt8¤ kSHK_Extended¤  = 0x08;
0daf5a
a1af5a
1bd557 ////////
1f02c9 // Types
27d557 ////////
f7af5a
44840f // PGPdiskRegLocation is used to specify where to look for the requested
f4dac6 // PGPdisk preference.
--4bb3 0018be567c940110174 Page 2 of PGPdiskRegistry.h
e0af5a
dfae78 enum PGPdiskRegLocation {kPRL_CurrentUser, kPRL_LocalMachine,·
c430fc ¤   kPRL_PGP60CurrentUser};
b6af5a
0792c5 // PGPdiskCreateScale enumerates the scale of the last create size.
53af5a
e2c7b1 enum PGPdiskCreateScale {kLCS_KbScale, kLCS_MbScale, kLCS_GbScale,·
23b09b ¤   kLCS_InvalidScale};
40af5a
68af5a
b96cc2 /////////////////////
41bf67 // Exported Functions
886cc2 /////////////////////
29af5a
189b31 DualErr¤¤   PGPdiskEnumSubkeys(HKEY root, LPCSTR section,·
50f2b8 ¤   ¤   ¤   ¤   PGPUInt32 index, LPSTR keyName,·
433d97 ¤   ¤   ¤   ¤   unsigned long valueSize, PGPBoolean *isIndexValid);
fbc4fe DualErr¤¤   PGPdiskEnumValues(HKEY root, LPCSTR section,·
3ec5d1 ¤   ¤   ¤   ¤   PGPUInt32 index, LPSTR valueName,·
9fbd90 ¤   ¤   ¤   ¤   unsigned long valueSize, unsigned long *valueType,·
8eca39 ¤   ¤   ¤   ¤   PGPBoolean *isIndexValid);
81af5a
b460d4 DualErr¤¤   PGPdiskGetRawKey(HKEY root, LPCSTR section,·
fc82f8 ¤   ¤   ¤   ¤   LPCSTR keyName, PGPUInt8 *buf, unsigned long bufSize);
7faf5a
24988a DualErr¤¤   PGPdiskCreateAndSetRawKey(HKEY root, LPCSTR section,·
8edfc0 ¤   ¤   ¤   ¤   LPCSTR keyName, const PGPUInt8 *value,·
5a507d ¤   ¤   ¤   ¤   PGPUInt32 valueSize, PGPUInt32 dataType);
52af5a
caefe2 DualErr¤¤   PGPdiskDeleteSubkey(HKEY root, LPCSTR section,·
4c5ee7 ¤   ¤   ¤   ¤   LPCSTR keyName);
41ef90 DualErr¤¤   PGPdiskDeleteValue(HKEY root, LPCSTR section,·
877a57 ¤   ¤   ¤   ¤   LPCSTR valueName);
52af5a
4eb1b8 PGPUInt32¤  PGPdiskGetPrefDWord(LPCSTR regKey, PGPUInt32 defaultDWord,·
2a86b4 ¤   ¤   ¤   ¤   PGPdiskRegLocation regLoc = kPRL_CurrentUser);
595b7c DualErr¤¤   PGPdiskSetPrefDWord(LPCSTR regKey, PGPUInt32 newDWord,·
bc86b4 ¤   ¤   ¤   ¤   PGPdiskRegLocation regLoc = kPRL_CurrentUser);
feaf5a
890635 PGPUInt64¤  PGPdiskGetPrefQWord(LPCSTR regKey,·
141695 ¤   ¤   ¤   ¤   PGPUInt64 defaultQWord,·
1886b4 ¤   ¤   ¤   ¤   PGPdiskRegLocation regLoc = kPRL_CurrentUser);
8e458c DualErr¤¤   PGPdiskSetPrefQWord(LPCSTR regKey, PGPUInt64 newQWord,·
6c86b4 ¤   ¤   ¤   ¤   PGPdiskRegLocation regLoc = kPRL_CurrentUser);
81af5a
49ebab void¤   ¤   PGPdiskGetPrefString(LPCSTR regKey, LPCSTR defaultString,·
da3308 ¤   ¤   ¤   ¤   CString *outputString,·
4386b4 ¤   ¤   ¤   ¤   PGPdiskRegLocation regLoc = kPRL_CurrentUser);
ffd2ad DualErr¤¤   PGPdiskSetPrefString(LPCSTR regKey, LPCSTR newString,·
7586b4 ¤   ¤   ¤   ¤   PGPdiskRegLocation regLoc = kPRL_CurrentUser);
7eaf5a
7a5532 void¤   ¤   RecallWindowPos(CWnd *pWnd, LPCSTR wndCoordsKey);
eb2f48 void¤   ¤   SaveWindowPos(CWnd *pWnd, LPCSTR wndCoordsKey);
9faf5a
ca8ed5 #if PGPDISK_BETAVERSION
14af5a
74f929 DualErr¤¤   SetPGPdiskBetaTimeout();
4daf5a
c35766 #elif PGPDISK_DEMOVERSION
d2af5a
503ef0 DualErr¤¤   SetPGPdiskDemoTimeout();
d6af5a
66e121 #endif // PGPDISK_BETAVERSION
30af5a
8bd327 #endif¤ // ] Included_PGPdiskRegistry_h
--6b0b 001dddc1a2440110175 Page 1 of PGPdiskResidentDefines.h
d3065d ///////////////////////////////////////////////////////////////////////////////
01dbbc // PGPdiskResidentDefines.h
49465d //
284a0d // Public defines for the PGPdiskResident project.
40065d ///////////////////////////////////////////////////////////////////////////////
24af5a
ddcb7a // $Id: PGPdiskResidentDefines.h,v 1.1.2.5 1998/08/04 02:10:25 nryan Exp $
d0af5a
3ccbce // Copyright (C) 1998 by Network Associates, Inc.
e771ae // All rights reserved.
dfaf5a
21d3a4 #ifndef Included_PGPdiskResidentDefines_h¤  // [
273654 #define Included_PGPdiskResidentDefines_h
71af5a
8eaf5a
5d09b7 ////////////
f9e738 // Constants
5209b7 ////////////
c6af5a
0d7125 const PGPUInt16 WM_PGPDISKRES_NEWPREFS = WM_USER + 197;
42af5a
86f76e static LPCSTR¤  kPGPdiskResAppName¤ ¤   ¤   = "PGPdiskResident";
dd0a9c static LPCSTR¤  kPGPdiskResWindowTitle¤ ¤   = "PGPdiskResHiddenWindow";
32963d static LPCSTR¤  kPGPdiskResSharedMemName¤   = "PGPdiskResidentSharedInfo";
7daf5a
3baf5a
18d557 ////////
ba02c9 // Types
48d557 ////////
63af5a
745dc1 // PGPdiskResInfo holds info about the PGPdiskResident application.
67af5a
48807c typedef struct PGPdiskResInfo
ffbb36 {
b09468 ¤   HWND hiddenWindowHwnd;
cfaf5a
ba7e94 } PGPdiskResInfo;
21af5a
dd7446 #endif¤ // ] Included_PGPdiskResidentDefines_h
--3afd 0013317dab440110176 Page 1 of PGPdiskVersion.h
d3065d ///////////////////////////////////////////////////////////////////////////////
d297f6 // PGPdiskVersion.h
4d465d //
2b4ea0 // Includes version constants and strings for the entire project.
8a065d ///////////////////////////////////////////////////////////////////////////////
b9af5a
baae3f // $Id: PGPdiskVersion.h,v 1.2.2.27.2.18.2.1 1998/11/12 03:06:28 heller Exp $
a2af5a
a5cbce // Copyright (C) 1998 by Network Associates, Inc.
8271ae // All rights reserved.
4eaf5a
da3198 #ifndef Included_PGPdiskVersion_h¤  // [
36206a #define Included_PGPdiskVersion_h
afaf5a
ebaf5a
9c09b7 ////////////
f8e738 // Constants
d609b7 ////////////
92af5a
403deb // The version numbers of the app and driver.
0bc068 #define¤kPGPdiskAppVersion¤ ¤   0x60000001
a4c000 #define¤kPGPdiskDriverVersion¤  kPGPdiskAppVersion
66af5a
fa5aec // The version numbers the app/driver are compatible with.
8457d0 #define¤kCompatDriverVersion¤   kPGPdiskAppVersion
dab7e3 #define¤kCompatAppVersion¤  ¤   kPGPdiskDriverVersion
efaf5a
00dfb1 // The version text string seen in the about box.
321c65 #define¤kVersionTextString¤ "6.0.2"
53af5a
186f50 // Version information that goes in the 'Version' resource of modules.
452cb5 #define¤kPGPdiskFileVerData¤¤   6,0,2,0
dd3997 #define¤kPGPdiskProductVerData¤ kPGPdiskFileVerData
edaf5a
cd62fc #define kPGPdiskFileVerString¤  ¤   "6.0.2.0\0"
72aab3 #define kPGPdiskProductVerString¤   kPGPdiskFileVerString
27af5a
9c7374 #define¤kPGPdiskCompanyName¤¤   "Network Associates, Inc.\0"
c7391e #define¤kPGPdiskCopyright¤  ¤   "Copyright (C) 1998 Network Associates, Inc.\0"
78f9e7 #define¤kPGPdiskProductVerName¤ "PGPdisk for Windows v6.0.2\0"
8baf5a
33004f #endif¤ // ] Included_PGPdiskVersion_h
--2390 0008a05134640110177 Page 1 of Packets.h
541bc3 //////////////////////////////////////////////////////////////////////////////
8b562f // Packets.h
20465d //
cdfc6d // Contains definitions for the app/driver packet communication language.
241bc3 //////////////////////////////////////////////////////////////////////////////
e3af5a
c9ad6b // $Id: Packets.h,v 1.1.2.28 1998/08/04 02:10:26 nryan Exp $
16af5a
ffcbce // Copyright (C) 1998 by Network Associates, Inc.
6671ae // All rights reserved.
05af5a
05a0d0 #ifndef Included_Packets_h¤ // [
841f59 #define Included_Packets_h
67af5a
0eefcd #if !defined(PGPDISK_NTDRIVER)
566fe7 #include <winioctl.h>
61cf67 #endif // !PGPDISK_NTDRIVER
103a85 #include "DualErr.h"
b0af5a
f5e79f // Align to 1.
fafcdb #pragma pack(push, 1)
aaaf5a
6ad557 ////////
8f02c9 // Types
fcd557 ////////
5faf5a
0dd1bd class CipherContext;
12af5a
e1b874 // A PGPdiskInfo structure holds some simple information about a mounted
dce603 // PGPdisk. A linked list of these structures is passed to the application
777867 // from the driver during registration.
4aaf5a
d743ce typedef struct PGPdiskInfo
7fbb36 {
c48e37 ¤   char path[kMaxStringSize];¤ // path to the PGPdisk
34af5a
f074ba ¤   PGPUInt8¤   drive;¤ ¤   // drive # of a mounted PGPdisk
b085dd ¤   PGPUInt64¤  sessionId;¤ // unique session Id
18af5a
b58974 } PGPdiskInfo;
44af5a
27616c // Lock op enumeration.
d6af5a
b4bd4b enum LockOp {kLO_LockReadWrite, kLO_UnlockReadWrite, kLO_LockFormat,·
123ee4 ¤   kLO_UnlockFormat};
50af5a
2daf5a
8f460c /////////////////////////////////////////////////////////////
6598bf // Application to driver (DeviceIoControl) packet definitions
e6460c /////////////////////////////////////////////////////////////
aeaf5a
c2c076 // The PGPdisk app is allowed to pass two values to the driver - a control
780c4f // code and a pointer.
adaf5a
c7de5d const PGPUInt32 IOCTL_PGPDISK_SENDPACKET = CTL_CODE(FILE_DEVICE_DISK, 0x800,·
6e0664 ¤   METHOD_BUFFERED, FILE_ANY_ACCESS) | 0x40000000;
c6af5a
de4886 const PGPUInt32 kPGPdiskADPacketMagic = 0x820F7353;
4caf5a
a54ea7 // Functions codes for packets.
7aaf5a
3bcff7 const PGPUInt16¤kAD_Mount¤  ¤   ¤   ¤   = 0x0001;
abf904 const PGPUInt16¤kAD_Unmount¤¤   ¤   ¤   = 0x0002;
7ac4f1 const PGPUInt16¤kAD_QueryVersion¤   ¤   = 0x0003;
1f9da1 const PGPUInt16¤kAD_QueryMounted¤   ¤   = 0x0004;
e4a4d1 const PGPUInt16¤kAD_QueryOpenFiles¤ ¤   = 0x0005;
82ee4e const PGPUInt16¤kAD_ChangePrefs¤¤   ¤   = 0x0006;
199969 const PGPUInt16¤kAD_LockUnlockMem¤  ¤   = 0x0007;
039ef5 const PGPUInt16¤kAD_GetPGPdiskInfo¤ ¤   = 0x0008;
c5db9a const PGPUInt16¤kAD_LockUnlockVol¤  ¤   = 0x0009;
efa997 const PGPUInt16¤kAD_ReadWriteVol¤   ¤   = 0x000A;
8a81aa const PGPUInt16¤kAD_QueryVolInfo¤   ¤   = 0x000B;
--716f 0008207f3cc40110177 Page 2 of Packets.h
4e1a4c const PGPUInt16¤kAD_NotifyUserLogoff¤   = 0x000C;
98af5a
90c8b6 // Standard packet header.
1faf5a
258edc typedef struct ADPacketHeader
62bb36 {
bde64b ¤   PGPUInt32¤  magic;¤ ¤   // must be kPGPdiskADPacketMagic
8a9316 ¤   PGPUInt16¤  code;¤  ¤   // packet code
1b3234 ¤   DualErr¤¤   *pDerr;¤¤   // error (DualErr *)
93af5a
7e7404 } ADPacketHeader, *PADPacketHeader;
2baf5a
4c7b51 // Struct AD_Mount.
4baf5a
faa74b typedef struct AD_Mount
f6bb36 {
c3f4d9 ¤   ADPacketHeader header;¤ ¤   ¤   ¤   // standard header
e0af5a
ddde2b ¤   LPCSTR¤ ¤   ¤   path;¤  ¤   ¤   ¤   // path to the PGPdisk
adb38a ¤   PGPUInt32¤  ¤   sizePath;¤  ¤   ¤   // size of path
6caf5a
aa8164 ¤   PGPUInt8¤   ¤   drive;¤ ¤   ¤   ¤   // preferred drive letter
b9cc08 ¤   PGPBoolean¤ ¤   readOnly;¤  ¤   ¤   // mount as read-only?
35af5a
62be63 ¤   CipherContext¤  *pContext;¤ ¤   ¤   // the cipher context
d7ceba ¤   PGPUInt8¤   ¤   *pDrive;¤   ¤   ¤   // drive mounted on (PGPUInt8 *)
d7af5a
50a76a } AD_Mount, *PAD_Mount;
c1af5a
f0f2dd // Struct AD_Unmount.
d8af5a
69b0af typedef struct AD_Unmount
2cbb36 {
58a366 ¤   ADPacketHeader header;¤ ¤   ¤   // standard header
63af5a
bf5c88 ¤   PGPUInt8¤   drive;¤ ¤   ¤   ¤   // drive to unmount
f88be9 ¤   PGPBoolean¤ isThisEmergency;¤   // emergency unmount?
46af5a
331891 } AD_Unmount, *PAD_Unmount;
96af5a
5404f8 // Struct AD_QueryVersion.
c3af5a
52cdd3 typedef struct AD_QueryVersion
75bb36 {
79a366 ¤   ADPacketHeader header;¤ ¤   ¤   // standard header
22af5a
3d05bc ¤   PGPUInt32¤  appVersion;¤¤   ¤   // application version
267094 ¤   PGPUInt32¤  *pDriverVersion;¤   // driver version (PGPUInt32 *)
6faf5a
2019ee } AD_QueryVersion, *PAD_QueryVersion;
f5af5a
c1a3e5 // Struct AD_QueryMounted.
4daf5a
7cca51 typedef struct AD_QueryMounted
0fbb36 {
92c838 ¤   ADPacketHeader header;¤ ¤   // standard header
b1af5a
8b5cee ¤   PGPBoolean¤ trueIfUsePath;¤ // TRUE to use path, FALSE to use drive
f6af5a
150879 ¤   LPCSTR¤ ¤   path;¤  ¤   ¤   // file to enquire about
db4dfa ¤   PGPUInt32¤  sizePath;¤  ¤   // size of path
be2a2d ¤   PGPUInt8¤   drive;¤ ¤   ¤   // drive to enquire about
7aaf5a
e60a7f ¤   PGPBoolean¤ *pIsPGPdisk;¤   // is a mounted PGPdisk? (PGPBoolean *)
02af5a
c9252e } AD_QueryMounted, *PAD_QueryMounted;
09af5a
2d7db0 // Struct AD_QueryOpenFiles.
28af5a
7caee1 typedef struct AD_QueryOpenFiles
51bb36 {
82a366 ¤   ADPacketHeader header;¤ ¤   ¤   // standard header
--c71d 000b29a12c040110177 Page 3 of Packets.h
e0af5a
ec69fc ¤   PGPUInt8¤   drive;¤ ¤   ¤   ¤   // drive to enumerate open files on
cdcddd ¤   PGPBoolean¤ *pHasOpenFiles;¤¤   // pointer to answer (PGPBoolean *)
bbaf5a
ccd770 } AD_QueryOpenFiles, *PAD_QueryOpenFiles;
84af5a
d51ac6 // Struct AD_ChangePrefs.
e7af5a
8e44f7 typedef struct AD_ChangePrefs
f1bb36 {
d6a366 ¤   ADPacketHeader header;¤ ¤   ¤   // standard header
1867c5 ¤
ac4951 ¤   PGPBoolean¤ autoUnmount;¤   ¤   // is auto-unmount enabled?
7b13f6 ¤   PGPUInt32¤  unmountTimeout;¤¤   // auto unmount timeout in minutes
23af5a
2c5c5b } AD_ChangePrefs, *PAD_ChangePrefs;
c6af5a
596688 // Struct AD_LockUnlockMem.
a0af5a
efca33 typedef struct AD_LockUnlockMem
28bb36 {
41c838 ¤   ADPacketHeader header;¤ ¤   // standard header
6667c5 ¤
fdb039 ¤   void¤   ¤   *pMem;¤ ¤   ¤   // the linear memory address
042e84 ¤   PGPUInt32¤  nBytes;¤¤   ¤   // size of memory block
5e3eab ¤   PGPBoolean¤ trueForLock;¤   // TRUE to lock, FALSE to unlock
87af5a
b3c441 } AD_LockUnlockMem, *PAD_LockUnlockMem;
82af5a
d51293 // Struct AD_GetPGPdiskInfo.
14af5a
67eb4d typedef struct AD_GetPGPdiskInfo
ddbb36 {
85c838 ¤   ADPacketHeader header;¤ ¤   // standard header
d2af5a
441ac0 ¤   PGPUInt32¤  arrayElems;¤¤   // elems in below array
3e15f3 ¤   PGPdiskInfo *pPDIArray;¤¤   // array of kMaxDrives # of structures.
4faf5a
e4afea } AD_GetPGPdiskInfo, *PAD_GetPGPdiskInfo;
1faf5a
4b1356 // Struct AD_LockUnlockVol.
87af5a
cda325 typedef struct AD_LockUnlockVol
3fbb36 {
82c838 ¤   ADPacketHeader header;¤ ¤   // standard header
d5af5a
0fd0ef ¤   PGPUInt8¤   drive;¤ ¤   ¤   // drive number
0897e4 ¤   LockOp¤ ¤   lockOp;¤¤   ¤   // lock op to perform
d0af5a
592c39 } AD_LockUnlockVol, *PAD_LockUnlockVol;
4caf5a
f88bb0 // Struct AD_ReadWriteVol.
deaf5a
a9d5e8 typedef struct AD_ReadWriteVol
1bbb36 {
5dc838 ¤   ADPacketHeader header;¤ ¤   // standard header
95af5a
22eefa ¤   PGPBoolean¤ trueIfRead;¤¤   // TRUE for read, FALSE for write
f5af5a
c3d0ef ¤   PGPUInt8¤   drive;¤ ¤   ¤   // drive number
c8bf41 ¤   PGPUInt64¤  pos;¤   ¤   ¤   // starting block
12eace ¤   PGPUInt32¤  nBlocks;¤   ¤   // number of blocks
baaf5a
48dcde ¤   PGPUInt8¤   *buf;¤  ¤   ¤   // buffer
82eb07 ¤   PGPUInt32¤  bufSize;¤   ¤   // size of buffer
1daf5a
905d48 } AD_ReadWriteVol, *PAD_ReadWriteVol;
76af5a
3c6c7e // Struct AD_QueryVolInfo.
c6af5a
1b1508 typedef struct AD_QueryVolInfo
b2bb36 {
--03aa 001b820710740110177 Page 4 of Packets.h
6fc838 ¤   ADPacketHeader header;¤ ¤   // standard header
75af5a
a8d0ef ¤   PGPUInt8¤   drive;¤ ¤   ¤   // drive number
871075 ¤   PGPUInt16¤  *pBlockSize;¤   // return blocksize here (PGPUInt16 *)
5e21c7 ¤   PGPUInt64¤  *pTotalBlocks;¤ // return total blocks here (PGPUInt64 *)
5baf5a
6d22d9 } AD_QueryVolInfo, *PAD_QueryVolInfo;
beaf5a
587489 // Struct AD_NotifyUserLogoff.
2caf5a
49c5c2 typedef struct AD_NotifyUserLogoff
72bb36 {
afc838 ¤   ADPacketHeader header;¤ ¤   // standard header
c8af5a
f69583 } AD_NotifyUserLogoff, *PAD_NotifyUserLogoff;
95af5a
ed1cb1 // Restore alignment.
6af421 #pragma pack(pop)
20af5a
b8a6d0 #endif¤ // ] Included_Packets_h
--af70 001d5bd0b1940110178 Page 1 of Required.h
541bc3 //////////////////////////////////////////////////////////////////////////////
9808b7 // Required.h
4d465d //
d8e7a3 // Includes for every source file in the project.
3b1bc3 //////////////////////////////////////////////////////////////////////////////
e8af5a
76b52c // $Id: Required.h,v 1.1.2.13.2.2 1998/10/25 19:37:54 build Exp $
67af5a
e4cbce // Copyright (C) 1998 by Network Associates, Inc.
ce71ae // All rights reserved.
2baf5a
512809 #ifndef Included_Required_h¤// [
7882b5 #define Included_Required_h
0baf5a
d97606 ///////////////
9ae150 // PFL includes
f37606 ///////////////
5baf5a
9af86a #include "PGPdiskPfl.h"
d9af5a
c1af5a
edd48e ////////////////////////
c5d9ae // Condition compilation
2ed48e ////////////////////////
f6af5a
c54565 #if defined(PGPDISK_95DRIVER) || \
86dfd6 ¤   defined(PGPDISK_NTDRIVER) || \
a7e6eb ¤   defined(PGPDISK_INSTALL_DLL)
68af5a
176498 #define PGPDISK_PUBLIC_KEY 0
8eaf5a
9003e4 #else¤  // !(PGPDISK_95DRIVER || PGPDISK_NTDRIVER)
7baf5a
907d40 #define PGPDISK_PUBLIC_KEY 1
13af5a
57c29a #endif¤ // PGPDISK_95DRIVER || PGPDISK_NTDRIVER
98af5a
f90468 #define PGPDISK_BETA_VERSION 0
63c3b1 #define PGPDISK_DEMO_VERSION 0
deaf5a
83b153 #if PGPDISK_BETA_VERSION && PGPDISK_DEMO_VERSION
e65f00 #error Defined only one of PGPDISK_BETA_VERSION and PGPDISK_DEMO_VERSION.
f308ae #endif¤ // PGPDISK_BETA_VERSION && PGPDISK_DEMO_VERSION
23af5a
623624 #define PGPDISK_WIPE_FUNCS 1
aeaf5a
e9af5a
f020a9 ///////////////////
05b98b // Further includes
b020a9 ///////////////////
1baf5a
e881a7 #include "SystemConstants.h"
8fd980 #include "PGPdiskDefaults.h"
01af5a
d59bc5 #endif¤ // ] Included_Required_h
--01d6 001d44d356b40110179 Page 1 of SafeObject.h
d3065d ///////////////////////////////////////////////////////////////////////////////
5560d3 // SafeObject.h
71465d //
53c3a3 // Declaration and implementation of class SafeObject
f1065d ///////////////////////////////////////////////////////////////////////////////
b9af5a
12cbce // Copyright (C) 1998 by Network Associates, Inc.
3271ae // All rights reserved.
acaf5a
88acd4 #ifndef Included_SafeObject_h¤  // [
d6bc82 #define Included_SafeObject_h
deaf5a
ea3a85 #include "DualErr.h"
c3340a #include "WaitObjectClasses.h"
dcaf5a
76af5a
1620a9 ///////////////////
487b9b // Class SafeObject
8d20a9 ///////////////////
b0af5a
c5e86a // SafeObject is the base class for all thread-safe objects in the project.
61893c // It provides a mutex and two functions for entering and leaving that
5418c1 // mutex, intended to be placed around accesses to the object. Lock/Unlock
b432bc // fake 'constness' so that const member functions of derived classes can use
da3016 // them.
cfaf5a
78d8b9 class SafeObject
d1bb36 {
7b5ed4 public:
321603 ¤   DualErr mInitErr;
5caf5a
b68e34 ¤   ¤   ¤   SafeObject();
67af5a
22ae69 ¤   void¤   Lock() const;¤  ¤   ¤   ¤   // claim object for use
a8c70a ¤   void¤   Unlock() const;¤¤   ¤   ¤   // release object
3baf5a
c70fb9 private:
f662f6 ¤   mutable PGPdiskMutex mAccessMutex;
8382f7 };
63af5a
b1af5a
a6460c /////////////////////////////////////////////////////////////
39687d // Class SafeObject public inline member function definitions
f5460c /////////////////////////////////////////////////////////////
89af5a
588f90 // The SafeObject constructor creates the mutex.
13af5a
0b4c4a inline
54f6f4 SafeObject::SafeObject()
d8bb36 {
705acc ¤   mInitErr = mAccessMutex.mInitErr;
e3efe6 }
8eaf5a
2ddf7e // Lock is called to lock the object for access by one thread.
61af5a
41c85e inline·
4dc823 void·
03b36a SafeObject::Lock() const
76bb36 {
47d4d2 ¤   mAccessMutex.Enter();
67efe6 }
65af5a
dca479 // Unlock releases a locked object.
20af5a
74c85e inline·
74c823 void·
694395 SafeObject::Unlock() const
34bb36 {
88ceb2 ¤   mAccessMutex.Leave();
f2efe6 }
67af5a
d4c106 #endif¤ // ] Included_SafeObject_h
--ca10 0001c20ff014011017a Page 1 of SecureMemory.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
01dbca // SecureMemory.cpp
92465d //
61eee3 // Implementation of class SecureMemory.
4e1bc3 //////////////////////////////////////////////////////////////////////////////
76af5a
e81518 // $Id: SecureMemory.cpp,v 1.1.2.16 1998/08/04 02:10:28 nryan Exp $
e8af5a
36cbce // Copyright (C) 1998 by Network Associates, Inc.
ae71ae // All rights reserved.
f4af5a
9e6931 #if defined(PGPDISK_MFC)
daaf5a
bf9e12 #include "StdAfx.h"
2caf5a
754268 #elif defined(PGPDISK_95DRIVER)
f8af5a
c206a9 #include <vtoolscp.h>
7986d2 #include LOCKED_CODE_SEGMENT
b95269 #include LOCKED_DATA_SEGMENT
38af5a
91f5a6 #elif defined(PGPDISK_NTDRIVER)
12af5a
8fd7a1 #include <vdw.h>
09af5a
84db21 #else
da112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
a005d6 #endif¤ // PGPDISK_MFC
5faf5a
b79bcf #include "Required.h"
6b70d4 #include "SecureMemory.h"
73af5a
4a6931 #if defined(PGPDISK_MFC)
caaf5a
b3ac00 #include "DriverComm.h"
9cc411 #include "Globals.h"
86af5a
5a05d6 #endif¤ // PGPDISK_MFC
2baf5a
61af5a
bb68ca /////////////////////////////////////////////
576183 // Class SecureMemory public member functions
ca68ca /////////////////////////////////////////////
dbaf5a
72f414 // The SecureMemory default constructor allocates a block of locked memory of
275f26 // the specified size and wipes it.
8eaf5a
29bd9b SecureMemory::SecureMemory(PGPUInt32 size)
31bb36 {
395072 ¤   mSize = size;
f4bdc0 ¤   mPMem = NULL;
f7af5a
2a6931 #if defined(PGPDISK_MFC)
96af5a
70d045 ¤   mInitErr = AllocLockedMem(mSize, &mPMem);
ebaf5a
b24268 #elif defined(PGPDISK_95DRIVER)
06af5a
129276 ¤   mPMem = HeapAllocate(mSize, NULL);
41af5a
91aaee ¤   if (IsNull(mPMem))
d89a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
d3af5a
cef5a6 #elif defined(PGPDISK_NTDRIVER)
a9af5a
36d8b3 ¤   mPMem = (void *) new PGPUInt8[mSize];
1caf5a
03aaee ¤   if (IsNull(mPMem))
2a9a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
ddaf5a
4c05d6 #endif¤ // PGPDISK_MFC
1caf5a
--8006 001b328a8d04011017a Page 2 of SecureMemory.cpp
e79c32 ¤   if (mInitErr.IsntError())
2cc7a1 ¤   {
310626 ¤   ¤   pgpClearMemory(mPMem, mSize);
ed9371 ¤   }
c8efe6 }
c3af5a
38e7a3 // The SecureMemory destructor wipes and deallocates the locked memory
a33b45 // allocated in the constructor.
9aaf5a
0d528b SecureMemory::~SecureMemory()
56bb36 {
7d301c ¤   if (IsntNull(mPMem))
fac7a1 ¤   {
0a0626 ¤   ¤   pgpClearMemory(mPMem, mSize);
7b8459 ¤   ¤   pgpDebugWhackMemory(mPMem, mSize);
0eaf5a
2f6931 #if defined(PGPDISK_MFC)
57d226 ¤   ¤   FreeLockedMem(mPMem, mSize);
ab4268 #elif defined(PGPDISK_95DRIVER)
1159a1 ¤   ¤   HeapFree(mPMem, NULL);
e9f5a6 #elif defined(PGPDISK_NTDRIVER)
329220 ¤   ¤   delete[] (PGPUInt8 *) mPMem;
0905d6 #endif¤ // PGPDISK_MFC
9faf5a
50875a ¤   ¤   mPMem = NULL;
8b9371 ¤   }
a6efe6 }
abaf5a
69195b // GetPtr returns a pointer to the currently allocated memory block.
8faf5a
5b21f6 void *·
078a8c SecureMemory::GetPtr()
d1bb36 {
53387f ¤   return mPMem;
91efe6 }
40af5a
187f8d // GetSize returns the size of the currently allocated memory block.
cbaf5a
1d1b0b PGPUInt32·
3baa2a SecureMemory::GetSize()
f6bb36 {
d6ce19 ¤   return mSize;
b3efe6 }
--2555 0015cbf67c24011017b Page 1 of SecureMemory.h
541bc3 //////////////////////////////////////////////////////////////////////////////
834dcb // SecureMemory.h
7e465d //
2e98d2 // Declaration of class SecureMemory.
ed1bc3 //////////////////////////////////////////////////////////////////////////////
62af5a
33b256 // $Id: SecureMemory.h,v 1.1.2.6 1998/08/04 02:10:29 nryan Exp $
24af5a
bfcbce // Copyright (C) 1998 by Network Associates, Inc.
fc71ae // All rights reserved.
4faf5a
0efe9b #ifndef Included_SecureMemory_h¤// [
b05fb6 #define Included_SecureMemory_h
c5af5a
7d3a85 #include "DualErr.h"
23af5a
64af5a
c56cc2 /////////////////////
f57d3b // Class SecureMemory
b56cc2 /////////////////////
f1af5a
a36cff // This class is thread-safe.
48af5a
a6fa29 class SecureMemory
dcbb36 {
395ed4 public:
b71603 ¤   DualErr mInitErr;
73af5a
00a150 ¤   SecureMemory(PGPUInt32 size);
fca733 ¤   ~SecureMemory();
09af5a
da78ec ¤   PGPUInt32¤  GetSize();¤ ¤   // returns the size of the allocated memory
4e8f47 ¤   void¤   ¤   *GetPtr();¤ ¤   // returns a pointer to the allocated memory
19af5a
990fb9 private:
29253f ¤   PGPUInt32¤  mSize;¤ ¤   ¤   // size of the memory
10f7f4 ¤   void¤   ¤   *mPMem;¤¤   ¤   // pointer to the locked memory
4582f7 };
baaf5a
5c1c78 #endif¤ // ] Included_SecureMemory_h
--cb49 000485318864011017c Page 1 of SecureString.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
19166b // SecureString.cpp
99465d //
332a30 // Implementation of class SecureString.
241bc3 //////////////////////////////////////////////////////////////////////////////
1daf5a
d9e8ec // $Id: SecureString.cpp,v 1.1.2.9 1998/08/04 02:10:29 nryan Exp $
02af5a
11cbce // Copyright (C) 1998 by Network Associates, Inc.
4b71ae // All rights reserved.
e7af5a
036931 #if defined(PGPDISK_MFC)
61af5a
9a9e12 #include "StdAfx.h"
15af5a
554268 #elif defined(PGPDISK_95DRIVER)
97af5a
3f06a9 #include <vtoolscp.h>
9a86d2 #include LOCKED_CODE_SEGMENT
1f5269 #include LOCKED_DATA_SEGMENT
6baf5a
2ef5a6 #elif defined(PGPDISK_NTDRIVER)
c2af5a
dbd7a1 #include <vdw.h>
3efeb2 #include <stdio.h>
31bea3 #include <stdlib.h>
79af5a
5adb21 #else
01112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
fb05d6 #endif¤ // PGPDISK_MFC
37af5a
3f9bcf #include "Required.h"
ec85af #include "SecureString.h"
92af5a
2daf5a
fd9c30 ////////////////////////////////////////////////////
3e5538 // Class SecureString public inline member functions
ef9c30 ////////////////////////////////////////////////////
77af5a
1f7f39 // The SecureString creates our 8-bit key. Eat your heart out, NSA.
afaf5a
641716 SecureString::SecureString(LPCSTR str)
f2bb36 {
0b988b ¤   mLength = 0;
84af5a
92cfa1 ¤   do
c6c7a1 ¤   {
1329f7 ¤   ¤   mKey = (PGPUInt8) (PGPdiskGetTicks() % 0xFF);
379371 ¤   }
2bc53c ¤   while (mKey == 0);
70af5a
04b824 ¤   for (PGPUInt32 i=0; i<kMaxStringSize; i++)
fc031b ¤   ¤   mString[i] = mKey^NULL;
8caf5a
9364d8 ¤   if (str)
abeb7c ¤   ¤   SetString(str);
07efe6 }
98af5a
60c1e5 // operator= copies one SecureString to another without changing the key of
bd2a6d // either string.
f8af5a
00434d SecureString &·
c0cf9f SecureString::operator=(const SecureString &from)
4cbb36 {
ed4615 ¤   PGPUInt32 i = 0;
4eaf5a
c78ffb ¤   if (this == &from)
2d316c ¤   ¤   return (* this);
77af5a
15f5a3 ¤   ClearString();
e6af5a
487d5e ¤   while (i < from.GetLength())
--288b 0004f57c9b04011017c Page 2 of SecureString.cpp
f7c7a1 ¤   {
6d9668 ¤   ¤   InsertAt(i, from.GetAt(i));
aa347d ¤   ¤   i++;
059371 ¤   }
75af5a
3280bd ¤   return (* this);
a3efe6 }
fbaf5a
a11b5a // operator== compares one SecureString to another, returns TRUE if equal.
92af5a
7e77be PGPBoolean·
05ad19 SecureString::operator==(const SecureString &peer) const
6ebb36 {
092e8b ¤   PGPBoolean areEqual = TRUE;
14af5a
a63ad8 ¤   if (mLength != peer.GetLength())
efc7a1 ¤   {
935f58 ¤   ¤   areEqual = FALSE;
c89371 ¤   }
800e24 ¤   else
f7c7a1 ¤   {
567fba ¤   ¤   for (PGPUInt32 i=0; i < mLength; i++)
2a5b34 ¤   ¤   {
f88e8b ¤   ¤   ¤   if (GetAt(i) != peer.GetAt(i))
97f776 ¤   ¤   ¤   {
b7e104 ¤   ¤   ¤   ¤   areEqual = FALSE;
64f622 ¤   ¤   ¤   ¤   break;
14a3a6 ¤   ¤   ¤   }
db0fe4 ¤   ¤   }
7e9371 ¤   }
37af5a
9d2855 ¤   return areEqual;
d6efe6 }
8faf5a
45b2e6 // operator!= compares one SecureString to another, returns FALSE if equal.
67af5a
b177be PGPBoolean·
0b23a5 SecureString::operator!=(const SecureString &peer) const
5abb36 {
bc263e ¤   return !operator==(peer);
8aefe6 }
49af5a
916cf8 // GetLength returns the length of the string, sans the terminating null.
ddaf5a
781b0b PGPUInt32·
99468e SecureString::GetLength() const
f0bb36 {
ed9bd4 ¤   return mLength;
31efe6 }
1daf5a
4ef32e // GetString copies the decrypted string into the output buffer.
b6af5a
6ac823 void·
2e7ff1 SecureString::GetString(LPSTR str, PGPUInt32 size) const
ebbb36 {
5ac2bf ¤   PGPUInt32 i, numToCopy;
fcaf5a
8dff6c ¤   i = 0;
162336 ¤   numToCopy = min(size, mLength);
37af5a
3b8e1e ¤   while (i < numToCopy)
1ac7a1 ¤   {
0ad37a ¤   ¤   str[i] = GetAt(i);
bb347d ¤   ¤   i++;
6e9371 ¤   }
11af5a
31018e ¤   str[i] = NULL;
e0efe6 }
7caf5a
647584 // SetString assigns the input string to the SecureString object.
86af5a
4fc823 void·
--2408 000c9ad1f964011017c Page 3 of SecureString.cpp
8570fb SecureString::SetString(LPCSTR str)
82bb36 {
6c4615 ¤   PGPUInt32 i = 0;
55af5a
5e9618 ¤   pgpAssertStrValid(str);
e7af5a
76f5a3 ¤   ClearString();
56af5a
bd7651 ¤   while ((i < kMaxStringSize) && (str[i] != NULL))
edc7a1 ¤   {
e9a3ac ¤   ¤   InsertAt(i, str[i]);
f6347d ¤   ¤   i++;
9a9371 ¤   }
35efe6 }
eaaf5a
cb2209 // ClearString sets the length of the string to 0;
bdaf5a
91c823 void·
a1ea2f SecureString::ClearString()
7cbb36 {
41988b ¤   mLength = 0;
06efe6 }
ddaf5a
f7a36e // GetAt returns the unencrypted character at the specified index.
24af5a
17671d PGPUInt8·
7eb2f1 SecureString::GetAt(PGPUInt32 i) const
60bb36 {
a6f50d ¤   PGPUInt8 c;
cbaf5a
7c2fda ¤   if (i > mLength)
fb7ed2 ¤   ¤   return NULL;
b1af5a
074b22 ¤   c = mKey^mString[i];
e4af5a
8052ec ¤   return c;
ecefe6 }
deaf5a
1aabcc // SetAt sets the character at the specified index.
44af5a
9fc823 void·
a68cd5 SecureString::SetAt(PGPUInt32 i, PGPUInt8 c)
52bb36 {
952fda ¤   if (i > mLength)
c899bf ¤   ¤   return;
51af5a
021a02 ¤   mString[i] = mKey^c;
6befe6 }
a9af5a
fd1d99 // RemoveAt removes and returns the character at the given index,
d46798 // and shrinks the string.
73af5a
44671d PGPUInt8·
38650d SecureString::RemoveAt(PGPUInt32 i)
ccbb36 {
1df50d ¤   PGPUInt8 c;
4caf5a
b04b4f ¤   if ((i > mLength) || (mLength == 0))
9c7ed2 ¤   ¤   return NULL;
c5af5a
7bde80 ¤   c = GetAt(i);
f6af5a
7c28cb ¤   for (PGPUInt32 j = i; j<mLength-1; j++)
811a85 ¤   ¤   SetAt(j, GetAt(j+1));
5daf5a
66b9b0 ¤   mLength--;
b1af5a
6f52ec ¤   return c;
1aefe6 }
89af5a
471a16 // InsertAt inserts a character at the given location, and expands the
c9cee5 // string to accomodate.
--7cb2 00199688b3c4011017c Page 4 of SecureString.cpp
e0af5a
20c823 void·
2dafea SecureString::InsertAt(PGPUInt32 i, PGPUInt8 c)
dbbb36 {
4d6419 ¤   if ((i > mLength) || (mLength == kMaxStringSize))
0899bf ¤   ¤   return;
6daf5a
3324f3 ¤   mLength++;
b6a655 ¤   SetAt(i, c);
71af5a
47cbfb ¤   for (PGPUInt32 j=mLength-1; j>i; j--)
b1027f ¤   ¤   SetAt(j, GetAt(j-1));
99efe6 }
--daf0 001b31e8c654011017d Page 1 of SecureString.h
541bc3 //////////////////////////////////////////////////////////////////////////////
05a919 // SecureString.h
4d465d //
841435 // Declaration and implementation of class SecureString.
391bc3 //////////////////////////////////////////////////////////////////////////////
cdaf5a
b1a1b3 // $Id: SecureString.h,v 1.1.2.10 1998/08/04 02:10:30 nryan Exp $
2daf5a
7acbce // Copyright (C) 1998 by Network Associates, Inc.
4171ae // All rights reserved.
b4af5a
8fd142 #ifndef Included_SecureString_h¤// [
33bb64 #define Included_SecureString_h
7eaf5a
723a85 #include "DualErr.h"
a4bfe9 #include "UtilityFunctions.h"
8eaf5a
86af5a
696cc2 /////////////////////
11b2d9 // Class SecureString
626cc2 /////////////////////
ceaf5a
906c2c // SecureString is a very simple string class that incorporates a randomly
1ebb26 // generated XOR encryption algorithm to foil techniques such as memory and
6a64d6 // swap-file keyword searching.
3faf5a
5e35cb class SecureString
36bb36 {
275ed4 public:
86cbb9 ¤   ¤   ¤   ¤   ¤   SecureString(LPCSTR str = NULL);
05af5a
61d731 ¤   SecureString &¤ operator=(const SecureString &from);
ae749f ¤   PGPBoolean¤ ¤   operator==(const SecureString &peer) const;
730bf6 ¤   PGPBoolean¤ ¤   operator!=(const SecureString &peer) const;
2baf5a
518a48 ¤   PGPUInt32¤  ¤   GetLength() const;
1daf5a
0b3599 ¤   void¤   ¤   ¤   GetString(LPSTR str, PGPUInt32 size) const;
f314d7 ¤   void¤   ¤   ¤   SetString(LPCSTR str);
b745c8 ¤   void¤   ¤   ¤   ClearString();
25af5a
54e5b9 ¤   PGPUInt8¤   ¤   GetAt(PGPUInt32 i) const;
f97135 ¤   void¤   ¤   ¤   SetAt(PGPUInt32 i, PGPUInt8 c);
bcaf5a
610674 ¤   PGPUInt8¤   ¤   RemoveAt(PGPUInt32 i);
3d228f ¤   void¤   ¤   ¤   InsertAt(PGPUInt32 i, PGPUInt8 c);
e0af5a
bf0fb9 private:
f33304 ¤   PGPUInt8¤   mString[kMaxStringSize];¤   // encrypted string
e3b383 ¤   PGPUInt8¤   mKey;¤  ¤   ¤   ¤   ¤   ¤   // XOR key
c47480 ¤   PGPUInt32¤  mLength;¤   ¤   ¤   ¤   ¤   // length of string
3982f7 };
07af5a
b3f8aa #endif¤ // ] Included_SecureString_h
--cdd3 00082053caf4011017e Page 1 of SharedMemory.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
970a69 // SharedMemory.cpp
22465d //
7c2995 // Implementation of class SharedMemory.
cc1bc3 //////////////////////////////////////////////////////////////////////////////
4faf5a
a96892 // $Id: SharedMemory.cpp,v 1.1.2.7 1998/08/04 02:10:31 nryan Exp $
63af5a
55cbce // Copyright (C) 1998 by Network Associates, Inc.
cd71ae // All rights reserved.
48af5a
ac6931 #if defined(PGPDISK_MFC)
67af5a
919e12 #include "StdAfx.h"
99af5a
afdb21 #else
f7333e #error Define PGPDISK_MFC.
4605d6 #endif¤ // PGPDISK_MFC
c3af5a
919bcf #include "Required.h"
6e6673 #include "SharedMemory.h"
fcaf5a
21af5a
7f68ca /////////////////////////////////////////////
c519a1 // Class SharedMemory public member functions
1368ca /////////////////////////////////////////////
36af5a
b9c92a // The SharedMemory constructor.
58af5a
d7c7a5 SharedMemory::SharedMemory()
acbb36 {
aaa4ea ¤   mSharedMemHandle = NULL;
a2bdc0 ¤   mPMem = NULL;
92efe6 }
a5af5a
816557 // The SharedMemory destructor.
c5af5a
fd5025 SharedMemory::~SharedMemory()
bcbb36 {
e57d36 ¤   DualErr derr;
b7af5a
e7c038 ¤   if (IsMemAttached())
88c7a1 ¤   {
726c27 ¤   ¤   derr = Detach();
8b0796 ¤   ¤   pgpAssert(derr.IsntError());
cc9371 ¤   }
5defe6 }
94af5a
5bea9b // IsMemAttached returns TRUE if shared memory is attached, FALSE otherwise.
a9af5a
1b77be PGPBoolean·
d5f249 SharedMemory::IsMemAttached()
7cbb36 {
5da478 ¤   return IsntNull(mSharedMemHandle);
6eefe6 }
adaf5a
d703a1 // GetMemPointer returns a pointer to the attached shared memory.
e5af5a
6121f6 void *·
eb469b SharedMemory::GetMemPointer()
0fbb36 {
979bc1 ¤   pgpAssert(IsMemAttached());
c6af5a
f9387f ¤   return mPMem;
5eefe6 }
16af5a
1b9e12 // GetMemName returns a constant pointer to the name of the shared memory.
4baf5a
fd03c3 LPCSTR·
5d77cd SharedMemory::GetMemName()
e4bb36 {
829bc1 ¤   pgpAssert(IsMemAttached());
--6126 000c6c0bf654011017e Page 2 of SharedMemory.cpp
e0af5a
092da4 ¤   return mSharedMemName;
0cefe6 }
2eaf5a
744ef4 // Attach attaches already existing shared memory to the object.
a0af5a
002292 DualErr·
eee13d SharedMemory::Attach(LPCSTR memName)
48bb36 {
26be41 ¤   DualErr¤¤   derr;
ca078e ¤   PGPBoolean¤ openedMapping¤  = FALSE;
68af5a
057c88 ¤   pgpAssertStrValid(memName);
db2881 ¤   pgpAssert(!IsMemAttached());
47af5a
00a32e ¤   // Try to open the shared memory object.
6ae9d3 ¤   mSharedMemHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, memName);
82af5a
afc027 ¤   if (IsNull(mSharedMemHandle))
979e87 ¤   ¤   derr = DualErr(kPGDMinorError_OpenFileMappingFailed, GetLastError());
74af5a
f9087a ¤   openedMapping = derr.IsntError();
72af5a
da6a99 ¤   // If succeeded, map a view of the shared memory.
412361 ¤   if (derr.IsntError())
9dc7a1 ¤   {
cbbee2 ¤   ¤   mPMem = MapViewOfFile(mSharedMemHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
3eaf5a
80480f ¤   ¤   if (IsNull(mPMem))
005b34 ¤   ¤   {
903dda ¤   ¤   ¤   derr = DualErr(kPGDMinorError_MapViewOfFileFailed,·
270c1f ¤   ¤   ¤   ¤   GetLastError());
da0fe4 ¤   ¤   }
5c9371 ¤   }
a7af5a
502361 ¤   if (derr.IsntError())
03c7a1 ¤   {
7ccee2 ¤   ¤   mSharedMemName = memName;
369371 ¤   }
f6af5a
474bb3 ¤   if (derr.IsError())
dfc7a1 ¤   {
493dce ¤   ¤   if (openedMapping)
c45b34 ¤   ¤   {
3dbe61 ¤   ¤   ¤   CloseHandle(mSharedMemHandle);
0322d4 ¤   ¤   ¤   mSharedMemHandle = NULL;
760fe4 ¤   ¤   }
1c9371 ¤   }
2baf5a
8133e3 ¤   return derr;
b9efe6 }
14af5a
c77768 // Detach detaches shared memory we previously attached.
00af5a
162292 DualErr·
987c2f SharedMemory::Detach()
d2bb36 {
d47d36 ¤   DualErr derr;
42af5a
2e9bc1 ¤   pgpAssert(IsMemAttached());
77af5a
8b9f4a ¤   if (!UnmapViewOfFile(mPMem))
a00fe1 ¤   ¤   derr = DualErr(kPGDMinorError_UnmapViewOfFileFailed, GetLastError());
64af5a
58bdc0 ¤   mPMem = NULL;
4daf5a
a69198 ¤   if (!CloseHandle(mSharedMemHandle))
c22093 ¤   ¤   derr = DualErr(kPGDMinorError_CloseHandleFailed, GetLastError());
8caf5a
5da4ea ¤   mSharedMemHandle = NULL;
caaf5a
c633e3 ¤   return derr;
--db43 0019038942a4011017e Page 3 of SharedMemory.cpp
7aefe6 }
46af5a
e58f86 // CreateAndAttach creates new shared memory and attaches it to the object.
b6af5a
a52292 DualErr·
4a41d8 SharedMemory::CreateAndAttach(LPCSTR memName, PGPUInt32 memSize)
50bb36 {
febe41 ¤   DualErr¤¤   derr;
c8584e ¤   PGPBoolean¤ createdMapping¤ = FALSE;
2eaf5a
837c88 ¤   pgpAssertStrValid(memName);
0caf5a
d44a23 ¤   // Create the file mapping for the memory.
4a8c23 ¤   mSharedMemHandle = CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL,·
5221cb ¤   ¤   PAGE_READWRITE, 0, memSize, memName);
49af5a
40e617 ¤   if (IsntNull(mSharedMemHandle))
f3c7a1 ¤   {
8bfb32 ¤   ¤   // Make sure this memory doesn't already exist.
3ab6b2 ¤   ¤   if (GetLastError() == ERROR_ALREADY_EXISTS)
995b34 ¤   ¤   {
fc058e ¤   ¤   ¤   derr = DualErr(kPGDMinorError_CreateFileMappingFailed,·
970c1f ¤   ¤   ¤   ¤   GetLastError());
4daf5a
edbe61 ¤   ¤   ¤   CloseHandle(mSharedMemHandle);
d322d4 ¤   ¤   ¤   mSharedMemHandle = NULL;
b50fe4 ¤   ¤   }
859371 ¤   }
8b0e24 ¤   else
5ac7a1 ¤   {
1538e0 ¤   ¤   derr = DualErr(kPGDMinorError_CreateFileMappingFailed,·
05b749 ¤   ¤   ¤   GetLastError());
3e9371 ¤   }
abaf5a
3def24 ¤   createdMapping = derr.IsntError();
29af5a
9e6a99 ¤   // If succeeded, map a view of the shared memory.
382361 ¤   if (derr.IsntError())
b2c7a1 ¤   {
6abee2 ¤   ¤   mPMem = MapViewOfFile(mSharedMemHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
8baf5a
c3480f ¤   ¤   if (IsNull(mPMem))
3c5b34 ¤   ¤   {
ad3dda ¤   ¤   ¤   derr = DualErr(kPGDMinorError_MapViewOfFileFailed,·
c90c1f ¤   ¤   ¤   ¤   GetLastError());
ed0fe4 ¤   ¤   }
129371 ¤   }
c6af5a
3d2361 ¤   if (derr.IsntError())
62c7a1 ¤   {
6ccee2 ¤   ¤   mSharedMemName = memName;
c09371 ¤   }
b8af5a
d14bb3 ¤   if (derr.IsError())
6ec7a1 ¤   {
acadf0 ¤   ¤   if (createdMapping)
175b34 ¤   ¤   {
8dbe61 ¤   ¤   ¤   CloseHandle(mSharedMemHandle);
7622d4 ¤   ¤   ¤   mSharedMemHandle = NULL;
ae0fe4 ¤   ¤   }
b89371 ¤   }
13af5a
8133e3 ¤   return derr;
90efe6 }
--c26d 0016d1fe6b34011017f Page 1 of SharedMemory.h
541bc3 //////////////////////////////////////////////////////////////////////////////
485bbd // SharedMemory.h
ae465d //
995fa4 // Declaration of class SharedMemory.
3a1bc3 //////////////////////////////////////////////////////////////////////////////
5baf5a
3ad5d5 // $Id: SharedMemory.h,v 1.1.2.6 1998/08/04 02:10:32 nryan Exp $
0eaf5a
69cbce // Copyright (C) 1998 by Network Associates, Inc.
5771ae // All rights reserved.
84af5a
9558cb #ifndef Included_SharedMemory_h¤// [
1c49c0 #define Included_SharedMemory_h
d4af5a
f03a85 #include "DualErr.h"
c2af5a
08af5a
746cc2 /////////////////////
830fea // Class SharedMemory
9b6cc2 /////////////////////
b1af5a
8f88f8 class SharedMemory
49bb36 {
195ed4 public:
c5bd91 ¤   SharedMemory();
f2b194 ¤   ~SharedMemory();
f1af5a
ecb064 ¤   PGPBoolean¤ IsMemAttached();
8792b6 ¤   void *¤ ¤   GetMemPointer();
242530 ¤   LPCSTR¤ ¤   GetMemName();
77af5a
d48617 ¤   DualErr¤¤   Attach(LPCSTR memName);
b8e20a ¤   DualErr¤¤   Detach();
d7af5a
5a1148 ¤   DualErr¤¤   CreateAndAttach(LPCSTR memName, PGPUInt32 memSize);
a5af5a
c90fb9 private:
7bdf19 ¤   CString¤¤   mSharedMemName;
fd1fff ¤   HANDLE¤ ¤   mSharedMemHandle;
f95da8 ¤   void¤   ¤   *mPMem;
aa82f7 };
1eaf5a
6d04f8 #endif // Included_SharedMemory_h
--9bae 00067469ce640110180 Page 1 of SimpleQueue.h
541bc3 //////////////////////////////////////////////////////////////////////////////
fc1c82 // SimpleQueue.h
2c465d //
845684 // Declaration and implementation of class SimpleQueue.
5d1bc3 //////////////////////////////////////////////////////////////////////////////
83af5a
639a46 // $Id: SimpleQueue.h,v 1.1.2.6 1998/08/04 02:10:33 nryan Exp $
a8af5a
0ccbce // Copyright (C) 1998 by Network Associates, Inc.
7e71ae // All rights reserved.
e1af5a
8554f6 #ifndef Included_SimpleQueue_h¤ // [
c2c3a8 #define Included_SimpleQueue_h
3aaf5a
9c3a85 #include "DualErr.h"
28bfe9 #include "UtilityFunctions.h"
e5af5a
6baf5a
4c09b7 ////////////
32e738 // Constants
2809b7 ////////////
8daf5a
bd7ba2 const PGPUInt32¤kMaxQueueSize = 100;¤   ¤   // max elems in queue
d7af5a
9daf5a
ecca3a ////////////////////
34fb4b // Class SimpleQueue
9eca3a ////////////////////
ddaf5a
eccb51 // SimpleQueue is a simple circular queue for 32-bit integers.
fbaf5a
b7f9f8 class SimpleQueue
1cbb36 {
685ed4 public:
ff59ab ¤   ¤   ¤   ¤   ¤   SimpleQueue();
90d70b ¤   ¤   ¤   ¤   ¤   ~SimpleQueue();
91af5a
82f101 ¤   SimpleQueue &¤  operator=(const SimpleQueue &from);
7daf5a
043125 ¤   PGPBoolean¤ ¤   IsEmpty();
39af5a
7b3df8 ¤   PGPBoolean¤ ¤   Push(PGPUInt32 num);
0b6619 ¤   PGPBoolean¤ ¤   Pop(PGPUInt32 *pNum);
40af5a
cb0fb9 private:
c3e439 ¤   PGPUInt32¤  mQueueElems[kMaxQueueSize];¤// elements stored here
742ad5 ¤   PGPUInt32¤  mQueueStart, mQueueEnd;¤¤   // start and end indices
240cec ¤   PGPUInt32¤  mNumElems;¤ ¤   ¤   ¤   ¤   // population
6182f7 };
e0af5a
ceaf5a
eb9c30 ////////////////////////////////////////////////////
275538 // Class SecureString public inline member functions
779c30 ////////////////////////////////////////////////////
d6af5a
79cd59 // The SimpleQueue default constructor.
d4af5a
d1c85e inline·
c57d70 SimpleQueue::SimpleQueue()
a9bb36 {
452a83 ¤   mQueueStart = mQueueEnd = mNumElems = 0;
8defe6 }
76af5a
4e1d16 // The SimpleQueue destructor.
7faf5a
3cc85e inline·
7584b0 SimpleQueue::~SimpleQueue()
0ebb36 {
0cefe6 }
d9af5a
9b0194 // operator= copies one SimpleQueue to another.
67af5a
--3675 000fcbcebaf40110180 Page 2 of SimpleQueue.h
21c85e inline·
057024 SimpleQueue &·
9517e2 SimpleQueue::operator=(const SimpleQueue &from)
2ebb36 {
ae4615 ¤   PGPUInt32 i = 0;
26af5a
138ffb ¤   if (this == &from)
9a316c ¤   ¤   return (* this);
7baf5a
8a76bd ¤   for (i=0; i<kMaxQueueSize; i++)
bec7a1 ¤   {
d318d3 ¤   ¤   mQueueElems[i] = from.mQueueElems[i];
3c9371 ¤   }
faaf5a
a43ca8 ¤   mQueueStart¤= from.mQueueStart;
178917 ¤   mQueueEnd¤  = from.mQueueEnd;
54d35a ¤   mNumElems¤  = from.mNumElems;
b6af5a
c480bd ¤   return (* this);
42efe6 }
d0af5a
f9fdd2 // IsEmpty returns TRUE if the queue is empty, FALSE otherwise.
08af5a
8fc85e inline·
4177be PGPBoolean·
225729 SimpleQueue::IsEmpty()
a5bb36 {
88442a ¤   return (mNumElems == 0);
f3efe6 }
b6af5a
19a412 // Push pushes a new number on top of the queue. TRUE if successful, FALSE
924da2 // otherwise.
13af5a
6ec85e inline·
1b77be PGPBoolean·
8d3c7d SimpleQueue::Push(PGPUInt32 num)
15bb36 {
b2d1a9 ¤   if (mNumElems == kMaxQueueSize)
5398aa ¤   ¤   return FALSE;
f1af5a
153455 ¤   mQueueElems[mQueueEnd] = num;
21af5a
3750e6 ¤   mNumElems++;
f1ebaf ¤   mQueueEnd++;
e6af5a
56caa8 ¤   if (mQueueEnd == kMaxQueueSize)
9de7ce ¤   ¤   mQueueEnd = 0;
26af5a
aac2e7 ¤   return TRUE;
e4efe6 }
1daf5a
d1a69a // Pop pops a number from the bottom of the queue. TRUE if successful, FALSE
2c4da2 // otherwise.
62af5a
12c85e inline·
fb77be PGPBoolean·
1382b3 SimpleQueue::Pop(PGPUInt32 *pNum)
afbb36 {
623f50 ¤   if (mNumElems == 0)
3a98aa ¤   ¤   return FALSE;
77af5a
be3921 ¤   (* pNum) = mQueueElems[mQueueStart];
46af5a
79cda5 ¤   mNumElems--;
80bef3 ¤   mQueueStart++;
7aaf5a
19ee19 ¤   if (mQueueStart == kMaxQueueSize)
601289 ¤   ¤   mQueueStart = 0;
edaf5a
82c2e7 ¤   return TRUE;
05efe6 }
fcaf5a
--d2c8 001ebad50db40110180 Page 3 of SimpleQueue.h
eb01f9 #endif¤ // ] Included_SimpleQueue_h
--9d0d 000bd084ef740110181 Page 1 of StringAssociation.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
909dc6 // StringAssociation.cpp
2a465d //
bd3304 // Functions for associating string identifiers with strings.
3d1bc3 //////////////////////////////////////////////////////////////////////////////
31af5a
a1fd19 // $Id: StringAssociation.cpp,v 1.1.2.10 1998/08/04 02:10:33 nryan Exp $
c1af5a
77cbce // Copyright (C) 1998 by Network Associates, Inc.
3171ae // All rights reserved.
dbaf5a
166931 #if defined(PGPDISK_MFC)
d3af5a
0f9e12 #include "StdAfx.h"
faaf5a
3a4268 #elif defined(PGPDISK_95DRIVER)
22af5a
5706a9 #include <vtoolscp.h>
e586d2 #include LOCKED_CODE_SEGMENT
fb5269 #include LOCKED_DATA_SEGMENT
f3af5a
aff5a6 #elif defined(PGPDISK_NTDRIVER)
f4af5a
c6d7a1 #include <vdw.h>
05af5a
e5db21 #else
35112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
cc05d6 #endif¤ // PGPDISK_MFC
00af5a
189bcf #include "Required.h"
48af5a
b9ea4b #if PGPDISK_PUBLIC_KEY
1e2f8d #include "pgpErrors.h"
9d38e4 #endif¤ // PGPDISK_PUBLIC_KEY
fbaf5a
254b7a #include "CommonStrings.h"
52b616 #include "Errors.h"
b8993c #include "StringAssociation.h"
71bfe9 #include "UtilityFunctions.h"
cfaf5a
47af5a
8d09b7 ////////////
a3659a // Functions
5e09b7 ////////////
eeaf5a
ecbd29 // GetCommonString returns a pointer to the string associated with the given
43ea28 // string ID, or a default string if none can be found.
7eaf5a
4703c3 LPCSTR·
339702 GetCommonString(PGPUInt32 stringId, LPCSTR defaultString)
66bb36 {
9e3079 ¤   LPSTR stringFound = NULL;
77af5a
ae600d ¤   if (stringId < kPGPdiskMaxCommonStrings)
0e2f01 ¤   ¤   stringFound = (LPSTR) kPGPdiskCommonStrings[stringId];
a1af5a
ef9c68 ¤   if (IsNull(stringFound))
aafc6d ¤   ¤   stringFound = (LPSTR) defaultString;
bcaf5a
03e4ea ¤   return stringFound;
eeefe6 }
e1af5a
1a30ad // GetMajorErrorString returns a pointer to the string associated with the
357226 // given PGDMajorError.
bfaf5a
f503c3 LPCSTR·
21065a GetMajorErrorString(
5eae93 ¤   PGDMajorError¤  perr,·
1edc4b ¤   LPCSTR¤ ¤   ¤   defaultString = kPGPdiskUnknownMajorErrorString)
32bb36 {
b53079 ¤   LPSTR stringFound = NULL;
bdaf5a
--8710 000971c53f540110181 Page 2 of StringAssociation.cpp
30ded9 ¤   if (perr < kPGPdiskMaxMajorErrorStrings)
b6d7b2 ¤   ¤   stringFound = (LPSTR) kPGPdiskMajorErrorStrings[perr];
ceaf5a
729c68 ¤   if (IsNull(stringFound))
acfc6d ¤   ¤   stringFound = (LPSTR) defaultString;
95af5a
25e4ea ¤   return stringFound;
d6efe6 }
5eaf5a
efbac3 // GetMinorErrorString returns a pointer to the string associated with the
577e10 // given PGDMinorError.
b6af5a
c903c3 LPCSTR·
21ae40 GetMinorErrorString(
2f74b6 ¤   PGDMinorError¤  merr,·
cd7451 ¤   LPCSTR¤ ¤   ¤   defaultString = kPGPdiskUnknownMinorErrorString)
95bb36 {
cc3079 ¤   LPSTR stringFound = NULL;
aeaf5a
8d254d ¤   if (merr < kPGPdiskMaxMinorErrorStrings)
adb130 ¤   ¤   stringFound = (LPSTR) kPGPdiskMinorErrorStrings[merr];
0baf5a
4a9c68 ¤   if (IsNull(stringFound))
5afc6d ¤   ¤   stringFound = (LPSTR) defaultString;
6baf5a
e7e4ea ¤   return stringFound;
a4efe6 }
2caf5a
03fdf2 // GetExternalErrorString returns a string describing the given external
644486 // error.
74af5a
15c823 void·
fb2054 GetExternalErrorString(
799aec ¤   ExternalErrorType¤  exErrType,·
5be50e ¤   PGPUInt32¤  ¤   ¤   exErr,·
875c5f ¤   PGPUInt32¤  ¤   ¤   sizeErrString,·
64be43 ¤   LPSTR¤  ¤   ¤   ¤   errString)
3abb36 {
bda9e1 ¤   static char¤tempString[kMaxStringSize];
94af5a
433315 ¤   pgpAssertAddrValid(errString, char);
7aaf5a
05ce6d ¤   switch (exErrType)
90c7a1 ¤   {
74af5a
4a0ae3 ¤   case kEET_Win32Error:
a1af5a
d96931 #if defined(PGPDISK_MFC)
4caf5a
2d0f2e ¤   ¤   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
358601 ¤   ¤   ¤   FORMAT_MESSAGE_IGNORE_INSERTS |
265971 ¤   ¤   ¤   FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, exErr,·
4a1978 ¤   ¤   ¤   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errString,·
91ab14 ¤   ¤   ¤   sizeErrString, NULL);
eeaf5a
fc7497 #else¤  // !PGPDISK_MFC
255de5 ¤   ¤   strcpy(errString, kEmptyString);
df05d6 #endif¤ // PGPDISK_MFC
ccaf5a
2e2f68 ¤   ¤   break;
a9af5a
f8bf80 ¤   case kEET_PGPSdkError:
6caf5a
d0ea4b #if PGPDISK_PUBLIC_KEY
d6af5a
5ad4c9 ¤   ¤   PGPGetErrorString((PGPError) exErr, sizeErrString, errString);
d7af5a
92b8cb ¤   ¤   sprintf(tempString, GetCommonString(kPGPdiskErrorWasString),·
d03027 ¤   ¤   ¤   errString);
f6690c ¤   ¤   SmartStringCopy(errString, tempString, sizeErrString);
69af5a
97a11d #else¤  // !PGPDISK_PUBLIC_KEY
--ac5b 000ee8004bc40110181 Page 3 of StringAssociation.cpp
ea5de5 ¤   ¤   strcpy(errString, kEmptyString);
a838e4 #endif¤ // PGPDISK_PUBLIC_KEY
d3af5a
d42f68 ¤   ¤   break;
14af5a
5d2f72 ¤   default:
f05de5 ¤   ¤   strcpy(errString, kEmptyString);
ef2f68 ¤   ¤   break;
d09371 ¤   }
58efe6 }
b2af5a
792add // FormatErrorString creates a single formatted error string from multiple
140a6c // sources of information.
39af5a
f1c823 void·
d7050a FormatErrorString(
fbae93 ¤   PGDMajorError¤  perr,·
5cef62 ¤   DualErr¤¤   ¤   derr,·
47f4ef ¤   PGPUInt8¤   ¤   drive,·
76df2a ¤   LPSTR¤  ¤   ¤   outString,·
39afdf ¤   PGPUInt32¤  ¤   outStringSize)
1ebb36 {
9821b0 ¤   static char¤majorErrorString[kMaxStringSize];
85e713 ¤   static char¤minorErrorString[kMaxStringSize];
a55b62 ¤   static char¤systemMessage[kMaxStringSize];
c23226 ¤   static char¤temp[kMaxStringSize];
0d2850 ¤   PGPBoolean¤ isQuestion;
9eaf5a
8779fb ¤   pgpAssertAddrValid(outString, char);
cbaf5a
7ec360 ¤   // There are four possibilities. We can either have both a PGDMinorError
d14244 ¤   // and an external error, a PGDMinorError alone, an external error alone,·
20bd0a ¤   // or neither.
53a617 ¤   //
96a7ff ¤   // Each major error has the form of "text%s.text" or "text %c:\\ text%s."
f007b7 ¤   // %c represents an optional drive parameter, and %s is the place where·
586a84 ¤   // the PGDMinorError/external error explanation string goes.
c5af5a
ecfd1f ¤   strcpy(majorErrorString, GetMajorErrorString(perr));
92af5a
0273f4 ¤   // Is this a question?
fd4a42 ¤   isQuestion = majorErrorString[strlen(majorErrorString) - 1] == '?';
e0af5a
733240 ¤   // Don't put stuff after question mark.
e51a9f ¤   if (isQuestion)
63cd46 ¤   ¤   derr.mExternalError = kExternalError_NoErr;
7eaf5a
235a3c ¤   if (DoesMajorErrTakeDrive(perr))¤   ¤   // using drive parameter?
eec7a1 ¤   {
be7295 ¤   ¤   sprintf(temp, majorErrorString, DriveNumToLet(drive), "%s");
e64589 ¤   ¤   strcpy(majorErrorString, temp);
bd9371 ¤   }
a5af5a
32f35a ¤   if (derr.HasPGDMinorError() && derr.HasExternalError())¤// both errs?
bdc7a1 ¤   {
f2d2aa ¤   ¤   strcpy(minorErrorString, "");
db884f ¤   ¤   strcat(minorErrorString, GetCommonString(kPGPdiskBecauseString));
8d3a06 ¤   ¤   strcat(minorErrorString, GetMinorErrorString(derr.mMinorError));
2aaf5a
e8767d ¤   ¤   sprintf(temp, majorErrorString, minorErrorString);
8b4589 ¤   ¤   strcpy(majorErrorString, temp);
76af5a
fc9cb1 ¤   ¤   GetExternalErrorString(derr.mExErrorType, derr.mExternalError,·
b79853 ¤   ¤   ¤   kMaxStringSize, systemMessage);
d5af5a
47d310 ¤   ¤   strcat(majorErrorString, " ");
1197a0 ¤   ¤   strcat(majorErrorString, systemMessage);
879371 ¤   }
47418c ¤   else if (derr.HasPGDMinorError())¤  ¤   // just a PGDMinorError?
bbc7a1 ¤   {
c0d2aa ¤   ¤   strcpy(minorErrorString, "");
ee884f ¤   ¤   strcat(minorErrorString, GetCommonString(kPGPdiskBecauseString));
--d68b 0010bc0e8c440110181 Page 4 of StringAssociation.cpp
363a06 ¤   ¤   strcat(minorErrorString, GetMinorErrorString(derr.mMinorError));
b5af5a
b2767d ¤   ¤   sprintf(temp, majorErrorString, minorErrorString);
3f4589 ¤   ¤   strcpy(majorErrorString, temp);
289371 ¤   }
708b47 ¤   else if (derr.HasExternalError())¤  ¤   // just an external Error?
e1c7a1 ¤   {
049cb1 ¤   ¤   GetExternalErrorString(derr.mExErrorType, derr.mExternalError,·
5f9853 ¤   ¤   ¤   kMaxStringSize, systemMessage);
52af5a
25ecbd ¤   ¤   sprintf(temp, majorErrorString, kEmptyString);
5a4589 ¤   ¤   strcpy(majorErrorString, temp);
75af5a
d3d310 ¤   ¤   strcat(majorErrorString, " ");
d097a0 ¤   ¤   strcat(majorErrorString, systemMessage);
259371 ¤   }
76af5a
274809 ¤   // Stick a numeric error ID on the end.
6afa77 ¤   if (derr.HasPGDMinorError())
15c7a1 ¤   {
e55119 ¤   ¤   if (derr.HasExternalError())
2e5b34 ¤   ¤   {
e260a7 ¤   ¤   ¤   sprintf(temp, " (%d, %X)", (PGPUInt32) derr.mMinorError,·
3eb3a7 ¤   ¤   ¤   ¤   derr.mExternalError);
ae0fe4 ¤   ¤   }
f10e1d ¤   ¤   else
af5b34 ¤   ¤   {
664315 ¤   ¤   ¤   sprintf(temp, " (%d)", (PGPUInt32) derr.mMinorError);
3d0fe4 ¤   ¤   }
00af5a
8583d3 ¤   ¤   // Tack extra space onto end if last char isn't already space.
451bb8 ¤   ¤   if (majorErrorString[strlen(majorErrorString) - 1] != ' ')
46dd5c ¤   ¤   ¤   strcat(majorErrorString, " ");
22af5a
569ba0 ¤   ¤   strcat(majorErrorString, temp);
119371 ¤   }
77af5a
36142f ¤   SmartStringCopy(outString, majorErrorString, outStringSize);
0befe6 }
--dd28 001c98deabb40110182 Page 1 of StringAssociation.h
541bc3 //////////////////////////////////////////////////////////////////////////////
dd0372 // StringAssociation.h
28465d //
e14cec // Contains declarations for StringAssociation.cpp.
c71bc3 //////////////////////////////////////////////////////////////////////////////
cfaf5a
55572a // $Id: StringAssociation.h,v 1.1.2.7 1998/08/04 02:10:34 nryan Exp $
d3af5a
44cbce // Copyright (C) 1998 by Network Associates, Inc.
e471ae // All rights reserved.
bfaf5a
c6c2df #ifndef Included_StringAssociation_h¤   // [
5e43e0 #define Included_StringAssociation_h
98af5a
134b7a #include "CommonStrings.h"
c23a85 #include "DualErr.h"
44b616 #include "Errors.h"
c1af5a
00af5a
d96cc2 /////////////////////
1913d2 // Exported functions
946cc2 /////////////////////
0baf5a
77a60b LPCSTR¤ GetCommonString(PGPUInt32 StringId,·
104f1b ¤   ¤   ¤   LPCSTR defaultString = kPGPdiskUnknownString);
7baf5a
877d17 void¤   FormatErrorString(PGDMajorError perr, DualErr derr, PGPUInt8 drive,·
fed161 ¤   ¤   ¤   LPSTR outString, PGPUInt32 sizeOutString);
b6af5a
c95029 #endif // Included_StringAssociation_h
--1ddb 00073b8c5e840110183 Page 1 of SystemConstants.h
541bc3 //////////////////////////////////////////////////////////////////////////////
c0ad9a // SystemConstants.h
e2465d //
40756f // General constants.
321bc3 //////////////////////////////////////////////////////////////////////////////
66af5a
191cad // $Id: SystemConstants.h,v 1.1.2.18 1998/08/06 00:42:59 nryan Exp $
5faf5a
fdcbce // Copyright (C) 1998 by Network Associates, Inc.
b871ae // All rights reserved.
d5af5a
81b0c0 #ifndef Included_SystemConstants_h¤ // [
fa6f32 #define Included_SystemConstants_h
d1af5a
15af5a
42d557 ////////
8b02c9 // Types
f1d557 ////////
78af5a
c40931 #if !defined(LPSTR)
116ce2 typedef char *LPSTR;
0239b4 #endif // LPSTR
d1af5a
df168a #if !defined(LPCSTR)
bb9e19 typedef const char *LPCSTR;
037443 #endif // LPCSTR
b8af5a
a14fd1 #if !defined(LPCWSTR)
1cca59 typedef const WCHAR *LPCWSTR;
236e6e #endif // LPCWSTR
7faf5a
30af5a
c309b7 ////////////
1de738 // Constants
5a09b7 ////////////
f9af5a
3080e2 // Memory constants.
5eaf5a
af9f70 static PGPUInt32 kWin32Power2PageSize = 12;
63af5a
ea9e96 // Character constants.
072e15 const char kNullChar = '\0';
9baf5a
e3c805 // String constants.
54af5a
af0742 static LPCSTR kEmptyString = "";
86af5a
7f2053 static LPCWSTR¤ kNTDevicePathPrefix¤¤   = L"\\Device\\";
b7a1c2 static LPCWSTR¤ kNTLinkPathPrefix¤  ¤   = L"\\??\\";
6a4dbe static LPCWSTR¤ kNTUNCLinkPathPrefix¤   = L"\\Device\\mup\\";
c1af5a
d94106 // Kernel-mode constants.
ebaf5a
03b226 const PGPUInt32 kPGPdiskBugCheckCode = 0x20000042;
3caf5a
a87bdb // Drive constants
06af5a
e11f64 static LPCSTR kInvalidVolumeNameChars = "\"&*+./:;<=>?[\\]^|";
8daf5a
84a5a4 const PGPUInt16¤kMaxSpts¤   = 64;
1f60d0 const PGPUInt8¤ kMaxSpt¤¤   = 63;
ed1f4d const PGPUInt16¤kMaxHeads¤  = 256;
0e6059 const PGPUInt8¤ kMaxHead¤   = 255;
ea69aa const PGPUInt16¤kMaxCyls¤   = 256;
d6e489 const PGPUInt8¤ kMaxCyl¤¤   = 255;
86af5a
9ccf0f const PGPUInt32¤kSizeSpt¤   = 1;
548dd8 const PGPUInt32¤kSizeHead¤  = kSizeSpt*kMaxSpt;
5bb278 const PGPUInt32¤kSizeCyl¤   = kSizeHead*kMaxHeads;
15af5a
a20b2e const PGPUInt32¤kMaxDrives¤ ¤   ¤   ¤   = 26;¤  ¤
73f955 const PGPUInt32¤kMaxMountedPGPdisks¤¤   = kMaxDrives;
--c727 0015489d8d840110183 Page 2 of SystemConstants.h
f6a867 const PGPUInt32¤kMaxVolumeLabelLength¤  = 11;
62b4c3 const PGPUInt8¤ kInvalidDrive¤  ¤   ¤   = 0xFF;¤¤   // invalid drive #
63437c const PGPUInt32¤kMaxStringSize¤ ¤   ¤   = 300;¤ ¤   // > MAX_PATH
13af5a
bcc32d // Conversion constants
82af5a
13af6b const PGPUInt8¤ kBitsPerByte¤   = 8;
0d95a0 const PGPUInt8¤ kBitsPerWord¤   = 16;
704bdc const PGPUInt8¤ kBitsPerDWord¤  = 32;
4caf5a
2dd513 const PGPUInt16¤kBytesPerKb¤¤   = 1024;
81d885 const PGPUInt32¤kBytesPerMeg¤   = 1024*1024;
54de8c const PGPUInt16¤kKbPerMeg¤  ¤   = 1024;
e002e2 const PGPUInt32¤kKbPerGig¤  ¤   = 1024*kKbPerMeg;
c1bd3e const PGPUInt32¤kMbPerGig¤  ¤   = 1024;
1baf5a
5a5046 // Time constants
1daf5a
1655aa const PGPUInt32¤k100nsPerSecond¤= 10000000;
998d66 const PGPUInt64¤kSecondsInADay¤ = 60*60*24;
f7af5a
8e7796 const PGPUInt64 kSecsBetween1601And1970 = 0x00000002b6109100;
2eaf5a
5419bd #endif¤ // ] Included_SystemConstants_h
--bf8b 0009ccc34f340110184 Page 1 of UtilityFunctions.h
541bc3 //////////////////////////////////////////////////////////////////////////////
95672a // UtilityFunctions.h
c5465d //
7f9cf3 // Small inline utility functions used by the application and the driver.
e61bc3 //////////////////////////////////////////////////////////////////////////////
2faf5a
6c36b1 // $Id: UtilityFunctions.h,v 1.1.2.31 1998/08/10 23:31:57 nryan Exp $
0caf5a
c8cbce // Copyright (C) 1998 by Network Associates, Inc.
b571ae // All rights reserved.
d6af5a
575fda #ifndef Included_UtilityFunctions_h¤// [
5ad250 #define Included_UtilityFunctions_h
52af5a
4b3a85 #include "DualErr.h"
bb0092 #include "Packets.h"
18af5a
080149 #if defined(PGPDISK_NTDRIVER)
0efeb2 #include <stdio.h>
f5bea3 #include <stdlib.h>
b7f4d5 #endif¤ // PGPDISK_NTDRIVER
83af5a
09af5a
4cd43e /////////
2b596b // Macros
cad43e /////////
dfaf5a
7707fe #ifndef max
9a0642 #define max(a,b) (((a) > (b)) ? (a) : (b))
887454 #endif
c2af5a
97007d #ifndef min
cd811a #define min(a,b) (((a) < (b)) ? (a) : (b))
f17454 #endif
5baf5a
2aea78 // Debugging macros.
cfaf5a
00a8f0 #if !PGP_DEBUG
1caf5a
8be35a #define DebugOut NoOpPrintf
1faf5a
3cea93 #elif defined(PGPDISK_MFC)
28af5a
09792f #define DebugOut TRACE
a1af5a
964268 #elif defined(PGPDISK_95DRIVER)
c7af5a
ff51c3 #define DebugOut dprintf
05af5a
c0f5a6 #elif defined(PGPDISK_NTDRIVER)
19af5a
407c33 #define DebugOut DbgPrint
2baf5a
397a20 #endif // PGPDISK_95DRIVER
56af5a
18ef87 // Helper function for the above macros.
3daf5a
d3c85e inline·
fefcf4 int·
93d80e __cdecl·
de5265 NoOpPrintf(const char *, ...)
52bb36 {
c53e6b ¤   return 0;
01efe6 }
33af5a
f2af5a
407746 /////////////////
137ee1 // Math functions
a07746 /////////////////
89af5a
c5c476 // CeilDiv divides 'a' by 'b' and rounds the result up to the nearest integer.
9caf5a
--8a4f 00035caf4e940110184 Page 2 of UtilityFunctions.h
21c85e inline·
e7a385 PGPUInt64·
a1508a CeilDiv(PGPUInt64 a, PGPUInt64 b)
7ebb36 {
d54245 ¤   if (a % b)
31817e ¤   ¤   return ((a / b) + 1);
060e24 ¤   else
dd6d46 ¤   ¤   return (a / b);
f8efe6 }
c9af5a
5ec7c0 // GetHighByte extracts and returns the high byte of the given word.
1caf5a
39c85e inline·
ec671d PGPUInt8·
f1fbcb GetHighByte(PGPUInt16 w)
9dbb36 {
3187a7 ¤   return (PGPUInt8) ((w & 0xFF00) >> 8);
feefe6 }
eaaf5a
d5ea7b // GetLowByte extracts and returns the low byte of the given word.
49af5a
64c85e inline·
ba671d PGPUInt8·
d16848 GetLowByte(PGPUInt16 w)
02bb36 {
851f88 ¤   return (PGPUInt8) (w & 0x00FF);
edefe6 }
11af5a
010c29 // GetHighWord extracts and returns the high word of the given double word.
3eaf5a
22c85e inline·
15411c PGPUInt16·
9c242d GetHighWord(PGPUInt32 dw)
2cbb36 {
10d73f ¤   return (PGPUInt16) ((dw & 0xFFFF0000) >> 16);
c1efe6 }
f9af5a
6e9557 // GetLowWord extracts and returns the low word of the given double word.
08af5a
d1c85e inline·
2f411c PGPUInt16·
c1922d GetLowWord(PGPUInt32 dw)
3ebb36 {
f3fc2e ¤   return (PGPUInt16) (dw & 0x0000FFFF);
33efe6 }
92af5a
08605c // GetHighDWord extracts and returns the high dword of the given quad word.
76af5a
33c85e inline·
f81b0b PGPUInt32·
cd4bea GetHighDWord(PGPUInt64 qw)
37bb36 {
7e53b0 ¤   return (PGPUInt32) ((qw & 0xFFFFFFFF00000000) >> 32);
a3efe6 }
dfaf5a
e7a935 // GetLowDWord extracts and returns the low dword of the given quad word.
42af5a
85c85e inline·
221b0b PGPUInt32·
654b5c GetLowDWord(PGPUInt64 qw)
5bbb36 {
ab8ead ¤   return (PGPUInt32) (qw & 0x00000000FFFFFFFF);
b5efe6 }
a8af5a
6b4dc6 // MakeWord makes a WORD out of a low byte and a high byte
aaaf5a
fbc85e inline·
3c411c PGPUInt16·
851b05 MakeWord(PGPUInt8 low, PGPUInt8 high)
aebb36 {
36d1e3 ¤   return (PGPUInt16) (((PGPUInt16) high) << 8 | low);
35efe6 }
--6869 0000a6fdc6540110184 Page 3 of UtilityFunctions.h
e0af5a
df1ff0 // MakeLong makes a DWORD out of a low word and a high word.
4caf5a
ecc85e inline·
951b0b PGPUInt32·
ce6ba9 MakeLong(PGPUInt16 low, PGPUInt16 high)
00bb36 {
44a045 ¤   return (PGPUInt32) (((PGPUInt32) high) << 16 | low);
17efe6 }
f2af5a
207532 // MakeQWord makes a QWORD out of a low DWORD and a high bDWORDyte
a8af5a
25c85e inline·
a5a385 PGPUInt64·
15ff0b MakeQWord(PGPUInt32 low, PGPUInt32 high)
7ebb36 {
2d3d00 ¤   return (PGPUInt64) (((PGPUInt64) high) << 32 | low);
6defe6 }
64af5a
744767 // IsValidHexChar returns TRUE if the specified char is 0-1 or A-F.
4daf5a
3ac85e inline·
d677be PGPBoolean·
21cbdb IsValidHexChar(char c)
2ebb36 {
93cec1 ¤   c = toupper(c);
50af5a
c34d60 ¤   return (((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'F')));
7befe6 }
97af5a
ec925c // SimpleLog2 returns the base 2 logarithm of a, assuming a is a perfect power
447f79 // of two.
34af5a
cdc85e inline·
20671d PGPUInt8·
d731b7 SimpleLog2(PGPUInt32 a)
c4bb36 {
70a864 ¤   PGPUInt8 i = 0;
59af5a
1f0ebc ¤   while (a > 1)
00c7a1 ¤   {
ab3ed7 ¤   ¤   a = a >> 1;
79347d ¤   ¤   i++;
239371 ¤   }
f2af5a
eb2196 ¤   return i;
70efe6 }
29af5a
bfaf5a
b320a9 ///////////////////
c32f4a // Memory functions
3f20a9 ///////////////////
ccaf5a
5b6519 // DupeString duplicates a string.
66af5a
8ac85e inline·
ff2292 DualErr·
8a2fe1 DupeString(LPCSTR in, LPSTR *out)
55bb36 {
5e945d ¤   DualErr¤derr;
ef3d8d ¤   LPSTR¤  copy;
deaf5a
49c1d0 ¤   pgpAssertAddrValid(out, LPCSTR);
6b4a31 ¤   pgpAssertStrValid(in);
f5af5a
a46931 #if defined(PGPDISK_MFC)
9caf5a
0d78f1 ¤   try
67c7a1 ¤   {
945643 ¤   ¤   copy = new char[strlen(in) + 1];
2f3df4 ¤   ¤   strcpy(copy, in);
0a9371 ¤   }
--7241 00098c85a3440110184 Page 4 of UtilityFunctions.h
213c88 ¤   catch (CMemoryException *ex)
35c7a1 ¤   {
3eecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
9a6adc ¤   ¤   ex->Delete();
3e9371 ¤   }
3baf5a
578c8d #elif defined(PGPDISK_95DRIVER) || defined(PGPDISK_NTDRIVER)
c0af5a
2653ae ¤   copy = new char[strlen(in) + 1];
c7af5a
e76a93 ¤   if (IsNull(copy))
23ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
1c0e24 ¤   else
803df4 ¤   ¤   strcpy(copy, in);
3aaf5a
07db21 #else
fe112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
4405d6 #endif¤ // PGPDISK_MFC
72af5a
512361 ¤   if (derr.IsntError())
64c7a1 ¤   {
d90468 ¤   ¤   (* out) = copy;
f69371 ¤   }
67af5a
a533e3 ¤   return derr;
2defe6 }
c6af5a
39d4b4 // GetByteBuffer returns a pointer to a buffer of bytes of the specified
329019 // size.
3baf5a
71c85e inline·
dd2292 DualErr·
b76352 GetByteBuffer(PGPUInt32 size, PGPUInt8 **buf)
bdbb36 {
2ebe41 ¤   DualErr¤¤   derr;
75d71f ¤   PGPUInt8¤   *pMem;
0eaf5a
ba1908 ¤   pgpAssertAddrValid(buf, PGPUInt8 *);
e6af5a
b26931 #if defined(PGPDISK_MFC)
dfaf5a
2d78f1 ¤   try
51c7a1 ¤   {
4a1f74 ¤   ¤   pMem = new PGPUInt8[size];
6f9371 ¤   }
6d3c88 ¤   catch (CMemoryException *ex)
afc7a1 ¤   {
8eecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
876adc ¤   ¤   ex->Delete();
729371 ¤   }
d1af5a
0b73cc #else // !PGPDISK_MFC
f9af5a
2c930b ¤   pMem = new PGPUInt8[size];
2caf5a
4ed95b ¤   if (IsNull(pMem))
f8ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
e1af5a
5b663c #endif // PGPDISK_MFC
d567c5 ¤
e92361 ¤   if (derr.IsntError())
8cc7a1 ¤   {
6593a8 ¤   ¤   (* buf) = pMem;
509371 ¤   }
e9af5a
7033e3 ¤   return derr;
deefe6 }
23af5a
3ed961 // FreeByteBuffer frees a byte buffer allocated by GetByteBuffer.
a2af5a
bec85e inline·
98c823 void·
--38b6 0008e406afc40110184 Page 5 of UtilityFunctions.h
0e7c5a FreeByteBuffer(PGPUInt8 *buf)
c3bb36 {
b3139f ¤   delete[] buf;
59efe6 }
2eaf5a
63eb6e // FlipBytes flips the bits in a chunk of memory.
b0af5a
40c85e inline·
4dc823 void·
4ec183 FlipBytes(PGPUInt8 *pMem, PGPUInt32 size)
eebb36 {
ef0719 ¤   pgpAssertAddrValid(pMem, PGPUInt8);
09af5a
3306ce ¤   for (PGPUInt32 i=0; i < size; i++)
d4c7a1 ¤   {
6882f3 ¤   ¤   pMem[i] = ~pMem[i];
0c9371 ¤   }
11efe6 }
b9af5a
3a1735 // SmartStringCopy copies either 'inString' in its entirety to 'outString',·
2d0e88 // or 'size' chars of 'inString', whichever is smaller, and appends a NULL.
afaf5a
a4c85e inline·
bdc823 void·
fffe71 SmartStringCopy(LPSTR outString, LPCSTR inString, PGPUInt32 size)
48bb36 {
60f62b ¤   PGPUInt32 numToCopy;
5faf5a
879115 ¤   pgpAssertStrValid(inString);
2879fb ¤   pgpAssertAddrValid(outString, char);
e0af5a
d2b365 ¤   numToCopy = min(strlen(inString), size - 1);
24af5a
212254 ¤   strncpy(outString, inString, numToCopy);
20c8e2 ¤   outString[numToCopy] = kNullChar;
8fefe6 }
3caf5a
adaf5a
6e04c6 ///////////////////////////////////////
697df9 // Data conversion/extraction functions
0a04c6 ///////////////////////////////////////
45af5a
67b8bd // DriveLetToNum converts a drive letter to a 0-based drive number.
67af5a
89c85e inline·
71671d PGPUInt8·
9a1e31 DriveLetToNum(char drivelet)
a1bb36 {
8a5b2e ¤   return (toupper(drivelet) - 'A');
4defe6 }
2aaf5a
9e5694 // DriveNumToLet converts a 0-based drive number to an uppercase drive letter.
61af5a
1ac85e inline·
13185c char·
be5c48 DriveNumToLet(PGPUInt8 drive)
b5bb36 {
2f428d ¤   pgpAssert(drive <= kMaxDrives);
0caf5a
bc2614 ¤   return (drive + 'A');
c8efe6 }
5eaf5a
ed2877 // DriveFromPath returns the drive number from a path.
9aaf5a
61c85e inline·
41671d PGPUInt8·
b3a3b4 DriveFromPath(LPCSTR path)
2dbb36 {
c4639f ¤   pgpAssertStrValid(path);
8faf5a
519b3f ¤   return DriveLetToNum(path[0]);
8eefe6 }
--5af5 0004de4684340110184 Page 6 of UtilityFunctions.h
e0af5a
8fd04e // IsLegalDriveLetter returns TRUE if a legal drive letter was specified.
1daf5a
2cc85e inline·
a177be PGPBoolean·
2ada95 IsLegalDriveLetter(char drivelet)
5ebb36 {
9e12d9 ¤   return (DriveLetToNum(drivelet) < kMaxDrives);
8defe6 }
3baf5a
e92449 // IsLegalDriveNumber returns TRUE if a legal drive number was specified.
bfaf5a
dfc85e inline·
c877be PGPBoolean·
cd5173 IsLegalDriveNumber(PGPUInt8 drive)
47bb36 {
dfaa13 ¤   return (drive < kMaxDrives);
07efe6 }
adaf5a
cc7dfc // FormatSizeString takes a disk size and returns a string describing the
1d1183 // size in English.
c4af5a
86c85e inline·
f1c823 void·
0a8de7 FormatSizeString(PGPUInt32 kb, LPSTR sbuf, PGPUInt32 size)
08bb36 {
441409 ¤   char kbStr[20], mbStr[20];
c6af5a
0c5037 ¤   pgpAssertAddrValid(sbuf, PGPUInt8);
ffaf5a
536326 ¤   if (size < 25)
e7c7a1 ¤   {
16653b ¤   ¤   sbuf[0] = NULL;
cc99bf ¤   ¤   return;
f19371 ¤   }
1daf5a
600899 #if defined(PGPDISK_SHELLEXT)
8eaf5a
0f847c ¤   if (kb < kKbPerMeg*2)
72c7a1 ¤   {
07dadf ¤   ¤   _itoa(kb, kbStr, 10);
10cfe3 ¤   ¤   wsprintf(sbuf, "%s KB", kbStr);
259371 ¤   }
58696e ¤   else if (kb < kKbPerGig*2)
09c7a1 ¤   {
016c88 ¤   ¤   _itoa(kb/kKbPerMeg, mbStr, 10);
2dcfbc ¤   ¤   wsprintf(sbuf, "%s MB", mbStr);
1a9371 ¤   }
a10e24 ¤   else
a0c7a1 ¤   {
66b448 ¤   ¤   _itoa(kb/kKbPerGig, mbStr, 10);
24e98e ¤   ¤   wsprintf(sbuf, "%s GB", mbStr);
a39371 ¤   }
78af5a
9e857b #else // !PGPDISK_SHELLEXT
60af5a
36847c ¤   if (kb < kKbPerMeg*2)
16c7a1 ¤   {
35dadf ¤   ¤   _itoa(kb, kbStr, 10);
54e34d ¤   ¤   sprintf(sbuf, "%s KB", kbStr);
5e9371 ¤   }
6b696e ¤   else if (kb < kKbPerGig*2)
3dc7a1 ¤   {
036c88 ¤   ¤   _itoa(kb/kKbPerMeg, mbStr, 10);
f1e312 ¤   ¤   sprintf(sbuf, "%s MB", mbStr);
459371 ¤   }
660e24 ¤   else
53c7a1 ¤   {
63b448 ¤   ¤   _itoa(kb/kKbPerGig, mbStr, 10);
cac520 ¤   ¤   sprintf(sbuf, "%s GB", mbStr);
569371 ¤   }
4daf5a
--fff6 000c302249b40110184 Page 7 of UtilityFunctions.h
f66c4c #endif¤ // PGPDISK_SHELLEXT
eeefe6 }
a4af5a
a5af5a
a7b352 //////////////////////////
6b11fb // File and path functions
76b352 //////////////////////////
7caf5a
a3949e // HasPlainLocalRoot returns TRUE if the specified path begins with a form
590fc0 // "C:\", FALSE otherwise.
d0af5a
e3c85e inline·
c877be PGPBoolean·
17408c HasPlainLocalRoot(LPCSTR path)
cdbb36 {
df639f ¤   pgpAssertStrValid(path);
70af5a
af0417 ¤   return ((path[1] == ':') && (path[2] == '\\'));
c7efe6 }
90af5a
08ca92 // IsPlainLocalRoot returns TRUE if the specified path is of the form "C:\",
819a91 // FALSE otherwise.
9eaf5a
71c85e inline·
2777be PGPBoolean·
d2a6d7 IsPlainLocalRoot(LPCSTR path)
2dbb36 {
f0639f ¤   pgpAssertStrValid(path);
3aaf5a
3053f2 ¤   return ((strlen(path) == 3) && HasPlainLocalRoot(path));
deefe6 }
12af5a
78af5a
02be49 // IsShortCut returns TRUE if the specified path is of the form "*.lnk",·
7b9a91 // FALSE otherwise.
0baf5a
c5c85e inline·
a777be PGPBoolean·
d8c4f8 IsShortCut(LPCSTR path)
59bb36 {
4fc956 ¤   char¤   ¤   ext[4];
a54f7f ¤   PGPUInt32¤  length;
18af5a
95639f ¤   pgpAssertStrValid(path);
97af5a
1f7555 ¤   length = strlen(path);
d9af5a
357bb0 ¤   if (strlen(path) < 4)
acc7a1 ¤   {
3898aa ¤   ¤   return FALSE;
bb9371 ¤   }
da0e24 ¤   else
29c7a1 ¤   {
05ba34 ¤   ¤   // There is no string 'right' command in Ring-0.
716b4b ¤   ¤   ext[0] = path[length - 4];
d7b5a3 ¤   ¤   ext[1] = path[length - 3];
cf3b52 ¤   ¤   ext[2] = path[length - 2];
b99756 ¤   ¤   ext[3] = path[length - 1];
48af5a
f8e1ec ¤   ¤   return (_strnicmp(ext, ".lnk", 4) == 0);
fe9371 ¤   }
faefe6 }
bdaf5a
1a260c // IsUNCPath returns TRUE if the specified path is in UNC format, FALSE
dc4da2 // otherwise.
aaaf5a
e1c85e inline·
3a77be PGPBoolean·
5bc50f IsUNCPath(LPCSTR path)
dabb36 {
0e2a28 ¤   PGPUInt32 i, length, numSlashes;
c3af5a
--dabe 0004709d23a40110184 Page 8 of UtilityFunctions.h
a3639f ¤   pgpAssertStrValid(path);
2baf5a
77b3d9 ¤   if (strncmp(path, "\\\\", 2) != 0)
f798aa ¤   ¤   return FALSE;
58af5a
3a7555 ¤   length = strlen(path);
999976 ¤   numSlashes = 0;
a0af5a
52b141 ¤   for (i = 0; i < length; i++)
aec7a1 ¤   {
bdc573 ¤   ¤   if ((path[i] == '\\') || (path[i] == '/'))
b7570e ¤   ¤   ¤   numSlashes++;
91af5a
65bb63 ¤   ¤   if (numSlashes == 4)
9532bd ¤   ¤   ¤   return TRUE;
4f9371 ¤   }
abaf5a
32a230 ¤   return FALSE;
a5efe6 }
26af5a
561efc // IsNetworkedPath returns TRUE if the specified path resides on a networked
670881 // drive, FALSE otherwise.
59af5a
e8c85e inline·
3b77be PGPBoolean·
ed2aa0 IsNetworkedPath(LPCSTR path)
75bb36 {
d6639f ¤   pgpAssertStrValid(path);
dbaf5a
16f7b5 ¤   if (strlen(path) < 3)
c098aa ¤   ¤   return FALSE;
2eaf5a
59bcb2 ¤   if (IsUNCPath(path))
23836c ¤   ¤   return TRUE;
a6af5a
746931 #if defined(PGPDISK_MFC)
adaf5a
35b0fb ¤   char head[4];
2caf5a
ed70ef ¤   strncpy(head, path, 3);
2754e2 ¤   head[3] = NULL;
58af5a
7cba4d ¤   return (GetDriveType(head) == DRIVE_REMOTE);
e1af5a
9c73cc #else // !PGPDISK_MFC
09af5a
a1a230 ¤   return FALSE;
e7af5a
2005d6 #endif¤ // PGPDISK_MFC
b6efe6 }
17af5a
32af5a
936557 ///////////////////////
a44137 // System call wrappers
e26557 ///////////////////////
1eaf5a
d54f50 // PGPdiskGetTicks returns the 'system tick' count.
15af5a
fac85e inline·
72a385 PGPUInt64·
1436e9 PGPdiskGetTicks()
d0bb36 {
1b6931 #if defined(PGPDISK_MFC)
94af5a
6bd9f7 ¤   return GetTickCount();
17af5a
994268 #elif defined(PGPDISK_95DRIVER)
0eaf5a
e4b6b3 ¤   return Get_System_Time();
0caf5a
bbf5a6 #elif defined(PGPDISK_NTDRIVER)
47af5a
--9cd1 00158d43da140110184 Page 9 of UtilityFunctions.h
ee6699 ¤   LARGE_INTEGER tickCount;
bdaf5a
4a7f1d ¤   KeQueryTickCount(&tickCount);
04af5a
42d59a ¤   return tickCount.QuadPart;
56af5a
8d05d6 #endif¤ // PGPDISK_MFC
25efe6 }
09af5a
4336f2 // ConvertSystemTimeToSecondsSince1970 converts a system time to the number
0adfec // of seconds since 1970.
9baf5a
74c85e inline·
aea385 PGPUInt64·
322d27 ConvertSystemTimeToSecondsSince1970(PGPUInt64 HundredNsSince1601)
f4bb36 {
b96931 #if defined(PGPDISK_MFC)
a2af5a
a911e5 ¤   PGPUInt64 secsSince1601, secsSince1970;
dfaf5a
749d9e ¤   secsSince1601¤  = HundredNsSince1601 / k100nsPerSecond;
8e0478 ¤   secsSince1970¤  = secsSince1601 - kSecsBetween1601And1970;
d3af5a
be1740 ¤   return secsSince1970;
1aaf5a
a48c8d #elif defined(PGPDISK_95DRIVER) || defined(PGPDISK_NTDRIVER)
7caf5a
e55949 ¤   pgpDebugMsg("This function is not available in driver mode.");
52af5a
5f9af6 ¤   return 0xFFFFFFFFFFFFFFFF;
97af5a
a005d6 #endif¤ // PGPDISK_MFC
40efe6 }
eeaf5a
c4707b // GetSecondsSince1970 returns the number of seconds elapsed since 1970.
3920e4 // This is according to UTC time.
01af5a
dec85e inline·
50a385 PGPUInt64·
fa8b70 GetSecondsSince1970()
60bb36 {
196931 #if defined(PGPDISK_MFC)
22af5a
5f5fac ¤   FILETIME¤   fileTime;
db0cf7 ¤   PGPUInt64¤  HundredNsSince1601;
b2af5a
adcf5a ¤   GetSystemTimeAsFileTime(&fileTime);
7eaf5a
51631d ¤   HundredNsSince1601 = MakeQWord(fileTime.dwLowDateTime,·
d87f16 ¤   ¤   fileTime.dwHighDateTime);
afaf5a
f58c2f ¤   return ConvertSystemTimeToSecondsSince1970(HundredNsSince1601);
1faf5a
e24268 #elif defined(PGPDISK_95DRIVER)
b9af5a
284636 ¤   PGPUInt32 moreMs;
d6af5a
804cd8 ¤   return IFSMgr_Get_NetTime(&moreMs);
8baf5a
6ff5a6 #elif defined(PGPDISK_NTDRIVER)
d0af5a
acf7dc ¤   LARGE_INTEGER HundredNsSince1601;
55af5a
67d23e ¤   KeQuerySystemTime(&HundredNsSince1601);
29af5a
2588c4 ¤   return ConvertSystemTimeToSecondsSince1970(HundredNsSince1601.QuadPart);
2faf5a
7305d6 #endif¤ // PGPDISK_MFC
a2efe6 }
0aaf5a
588273 #endif // Included_UtilityFunctions_h
--392c 0001e57f7ea40110185 Page 1 of WaitObjectClasses.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
5fc9de // WaitObjectClasses.cpp
30465d //
c38898 // Synchronization object classes.
a01bc3 //////////////////////////////////////////////////////////////////////////////
ecaf5a
01ac88 // $Id: WaitObjectClasses.cpp,v 1.1.2.9 1998/08/04 02:10:36 nryan Exp $
a0af5a
59cbce // Copyright (C) 1998 by Network Associates, Inc.
c071ae // All rights reserved.
a1af5a
346931 #if defined(PGPDISK_MFC)
e0af5a
899e12 #include "StdAfx.h"
0eaf5a
134268 #elif defined(PGPDISK_95DRIVER)
97af5a
e106a9 #include <vtoolscp.h>
ca86d2 #include LOCKED_CODE_SEGMENT
555269 #include LOCKED_DATA_SEGMENT
3aaf5a
b0f5a6 #elif defined(PGPDISK_NTDRIVER)
78af5a
add7a1 #include <vdw.h>
7daf5a
50db21 #else
d2112c #error Define PGPDISK_MFC, PGPDISK_95DRIVER, or PGPDISK_NTDRIVER.
0a05d6 #endif¤ // PGPDISK_MFC
8daf5a
0e9bcf #include "Required.h"
d9340a #include "WaitObjectClasses.h"
ffaf5a
2faf5a
e41bc3 //////////////////////////////////////////////////////////////////////////////
f8e9c4 // NOTE:
78465d //
7670b1 // Unfortunately, synchronization primitive creation and use is so different
1e78be // across Win32, 95 driver mode and NT driver mode that it's impossible to
82154b // provide a consistent calling interface to the following functions.
551bc3 //////////////////////////////////////////////////////////////////////////////
51af5a
666931 #if defined(PGPDISK_MFC)
68af5a
bf68ca /////////////////////////////////////////////
a677d0 // Class PGPdiskMutex public member functions
c268ca /////////////////////////////////////////////
12af5a
b4a12b // PGPdiskMutex constructs a PGPdiskMutex object.
05af5a
7b7e3a PGPdiskMutex::PGPdiskMutex(PGPBoolean initOwnership, LPCSTR name)
eabb36 {
a14580 ¤   mMutexHandle = CreateMutex(NULL, initOwnership, name);
14af5a
2480b4 ¤   if (IsNull(mMutexHandle))
b9c7a1 ¤   {
2b4f41 ¤   ¤   mInitErr = DualErr(kPGDMinorError_MutexCreationFailed,·
c7b749 ¤   ¤   ¤   GetLastError());
3f9371 ¤   }
67efe6 }
4daf5a
6c7279 // ~PGPdiskMutex destroys a PGPdiskMutexObject.
abaf5a
4bc7ac PGPdiskMutex::~PGPdiskMutex()
dabb36 {
404e42 ¤   if (IsntNull(mMutexHandle))
b0c7a1 ¤   {
3f798f ¤   ¤   CloseHandle(mMutexHandle);
ab67de ¤   ¤   mMutexHandle = NULL;
ed9371 ¤   }
36efe6 }
84af5a
1e246b // Enter enters the mutex.
--58b0 0006eeede9040110185 Page 2 of WaitObjectClasses.cpp
e0af5a
e01b0b PGPUInt32·
7cb226 PGPdiskMutex::Enter(PGPUInt32 timeout, PGPBoolean alertable)
82bb36 {
71372d ¤   pgpAssert(IsntNull(mMutexHandle));
27af5a
521101 ¤   return WaitForSingleObjectEx(mMutexHandle, timeout, alertable);
17efe6 }
a3af5a
dd5a91 // Leave leaves the mutex.
a4af5a
44c823 void·
a29aa9 PGPdiskMutex::Leave()
ecbb36 {
d4372d ¤   pgpAssert(IsntNull(mMutexHandle));
87af5a
a792cf ¤   ReleaseMutex(mMutexHandle);
49efe6 }
6caf5a
4daf5a
e919ca /////////////////////////////////////////////////
7f181e // Class PGPdiskSemaphore public member functions
1819ca /////////////////////////////////////////////////
89af5a
d57b94 // PGPdiskSemaphore constructs a PGPdiskSemaphore object.
94d83c ·
40cd80 PGPdiskSemaphore::PGPdiskSemaphore(
e9dc12 ¤   PGPUInt32¤  initCount,·
e37ca8 ¤   PGPUInt32¤  maxCount,·
b3f1d6 ¤   LPCSTR¤ ¤   name)
acbb36 {
8e23ad ¤   mSemHandle = ·CreateSemaphore(NULL, initCount, maxCount, name);
71af5a
df122f ¤   if (IsNull(mSemHandle))
c7c7a1 ¤   {
031cb3 ¤   ¤   mInitErr = DualErr(kPGDMinorError_SemaphoreCreationFailed,·
24b749 ¤   ¤   ¤   GetLastError());
259371 ¤   }
e2efe6 }
e8af5a
46e3d8 // ~PGPdiskSemaphore destroys a PGPdiskSemaphore object.
60d83c ·
56c062 PGPdiskSemaphore::~PGPdiskSemaphore()
4fbb36 {
42a960 ¤   if (IsntNull(mSemHandle))
2dc7a1 ¤   {
a3b6fe ¤   ¤   CloseHandle(mSemHandle);
61c496 ¤   ¤   mSemHandle = NULL;
149371 ¤   }
d6efe6 }
e8af5a
75cb2e // Waits waits on the semaphore.
91af5a
e81b0b PGPUInt32·
95be35 PGPdiskSemaphore::Wait(PGPUInt32 timeout, PGPBoolean alertable)
adbb36 {
eac008 ¤   pgpAssert(IsntNull(mSemHandle));
caaf5a
3adc6c ¤   return WaitForSingleObjectEx(mSemHandle, timeout, alertable);
04efe6 }
34af5a
54bf98 // Signal signals the semaphore.
51af5a
96c823 void·
eb5fcb PGPdiskSemaphore::Signal(PGPUInt32 count)
75bb36 {
c0c008 ¤   pgpAssert(IsntNull(mSemHandle));
08af5a
b8ee5f ¤   ReleaseSemaphore(mSemHandle, count, NULL);
bdefe6 }
85af5a
6eaf5a
--b939 0000de3eb8e40110185 Page 3 of WaitObjectClasses.cpp
194268 #elif defined(PGPDISK_95DRIVER)
9daf5a
de68ca /////////////////////////////////////////////
bb77d0 // Class PGPdiskMutex public member functions
e468ca /////////////////////////////////////////////
9eaf5a
c8a12b // PGPdiskMutex constructs a PGPdiskMutex object.
9faf5a
f16cf0 PGPdiskMutex::PGPdiskMutex(PGPUInt32 boost, PGPUInt32 flags)
35bb36 {
e51811 ¤   mMutexHandle = CreateMutex(boost, flags);
16af5a
9480b4 ¤   if (IsNull(mMutexHandle))
f45390 ¤   ¤   mInitErr = DualErr(kPGDMinorError_MutexCreationFailed);
33efe6 }
b4af5a
447279 // ~PGPdiskMutex destroys a PGPdiskMutexObject.
58af5a
b0c7ac PGPdiskMutex::~PGPdiskMutex()
93bb36 {
8b4e42 ¤   if (IsntNull(mMutexHandle))
95c7a1 ¤   {
5f1450 ¤   ¤   DestroyMutex(mMutexHandle);
7867de ¤   ¤   mMutexHandle = NULL;
ab9371 ¤   }
d9efe6 }
70af5a
6d246b // Enter enters the mutex.
fdaf5a
5dc823 void·
bf5780 PGPdiskMutex::Enter(PGPUInt32 flags)
40bb36 {
3d372d ¤   pgpAssert(IsntNull(mMutexHandle));
7daf5a
fa799c ¤   EnterMutex(mMutexHandle, flags);
6befe6 }
5eaf5a
f95a91 // Leave leaves the mutex.
efaf5a
13c823 void·
b09aa9 PGPdiskMutex::Leave()
78bb36 {
82372d ¤   pgpAssert(IsntNull(mMutexHandle));
49af5a
c75397 ¤   LeaveMutex(mMutexHandle);
1eefe6 }
c0af5a
caaf5a
a719ca /////////////////////////////////////////////////
34181e // Class PGPdiskSemaphore public member functions
2f19ca /////////////////////////////////////////////////
b5af5a
aa7b94 // PGPdiskSemaphore constructs a PGPdiskSemaphore object.
40d83c ·
45dba5 PGPdiskSemaphore::PGPdiskSemaphore(PGPUInt32 tokenCount)
e5bb36 {
9cec24 ¤   mSemHandle = ·Create_Semaphore(tokenCount);
61af5a
7e122f ¤   if (IsNull(mSemHandle))
7b0062 ¤   ¤   mInitErr = DualErr(kPGDMinorError_SemaphoreCreationFailed);
19efe6 }
d9af5a
73e3d8 // ~PGPdiskSemaphore destroys a PGPdiskSemaphore object.
81d83c ·
a3c062 PGPdiskSemaphore::~PGPdiskSemaphore()
d2bb36 {
bda960 ¤   if (IsntNull(mSemHandle))
adc7a1 ¤   {
9a5e88 ¤   ¤   Destroy_Semaphore(mSemHandle);
d5c496 ¤   ¤   mSemHandle = NULL;
3f9371 ¤   }
0defe6 }
--5be3 0001a34b17d40110185 Page 4 of WaitObjectClasses.cpp
e0af5a
9fcb2e // Waits waits on the semaphore.
14af5a
f8c823 void·
1ad8ab PGPdiskSemaphore::Wait(PGPUInt32 flags)
edbb36 {
6ec008 ¤   pgpAssert(IsntNull(mSemHandle));
f4af5a
12ac12 ¤   Wait_Semaphore(mSemHandle, flags);
fcefe6 }
44af5a
02bf98 // Signal signals the semaphore.
edaf5a
2ac823 void·
212c4b PGPdiskSemaphore::Signal()
36bb36 {
85c008 ¤   pgpAssert(IsntNull(mSemHandle));
d1af5a
35c63a ¤   Signal_Semaphore(mSemHandle);
baefe6 }
30af5a
82af5a
9ef5a6 #elif defined(PGPDISK_NTDRIVER)
71af5a
ef68ca /////////////////////////////////////////////
9877d0 // Class PGPdiskMutex public member functions
e268ca /////////////////////////////////////////////
afaf5a
99a12b // PGPdiskMutex constructs a PGPdiskMutex object.
65af5a
09e026 PGPdiskMutex::PGPdiskMutex(PGPUInt32 level)
1ebb36 {
58fa77 ¤   mMutexPointer = new KMUTEX;
8aaf5a
033632 ¤   if (IsNull(mMutexPointer))
3b9a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
f4af5a
b79c32 ¤   if (mInitErr.IsntError())
08c7a1 ¤   {
27c79f ¤   ¤   KeInitializeMutex(mMutexPointer, level);
0b9371 ¤   }
18efe6 }
bcaf5a
2e7279 // ~PGPdiskMutex destroys a PGPdiskMutexObject.
35af5a
6ec7ac PGPdiskMutex::~PGPdiskMutex()
90bb36 {
cba445 ¤   if (IsntNull(mMutexPointer))
70c7a1 ¤   {
08b7b4 ¤   ¤   delete mMutexPointer;
6d02aa ¤   ¤   mMutexPointer = NULL;
a09371 ¤   }
7aefe6 }
d4af5a
8f246b // Enter enters the mutex.
d0af5a
2b1b0b PGPUInt32·
74b226 PGPdiskMutex::Enter(PGPUInt32 timeout, PGPBoolean alertable)
91bb36 {
100e1e ¤   pgpAssertAddrValid(mMutexPointer, KMUTEX);
1daf5a
064d1d ¤   if (timeout == INFINITE)
b3c7a1 ¤   {
4cade9 ¤   ¤   return KeWaitForMutexObject(mMutexPointer, Executive, KernelMode,·
c7457b ¤   ¤   ¤   alertable, NULL);
389371 ¤   }
2d0e24 ¤   else
53c7a1 ¤   {
c10c7f ¤   ¤   LARGE_INTEGER largeTimeout;
b4af5a
ee9f6f ¤   ¤   largeTimeout.QuadPart = timeout;
1aaf5a
--3898 000536e121a40110185 Page 5 of WaitObjectClasses.cpp
38ade9 ¤   ¤   return KeWaitForMutexObject(mMutexPointer, Executive, KernelMode,·
d5a692 ¤   ¤   ¤   alertable, &largeTimeout);
f59371 ¤   }
f2efe6 }
37af5a
615a91 // Leave leaves the mutex.
bcaf5a
15c823 void·
f3a8f8 PGPdiskMutex::Leave(PGPBoolean wait)
0abb36 {
190e1e ¤   pgpAssertAddrValid(mMutexPointer, KMUTEX);
d3af5a
1d48e2 ¤   KeReleaseMutex(mMutexPointer, wait);
f0efe6 }
21af5a
eaaf5a
a319ca /////////////////////////////////////////////////
e8181e // Class PGPdiskSemaphore public member functions
9419ca /////////////////////////////////////////////////
3caf5a
dc7b94 // PGPdiskSemaphore constructs a PGPdiskSemaphore object.
80d83c ·
bbbffd PGPdiskSemaphore::PGPdiskSemaphore(PGPUInt32 count, PGPUInt32 limit)
e5bb36 {
1c3c23 ¤   mSemPointer = new KSEMAPHORE;
b1af5a
a31cfa ¤   if (IsNull(mSemPointer))
fa9a8d ¤   ¤   mInitErr = DualErr(kPGDMinorError_OutOfMemory);
3daf5a
8d9c32 ¤   if (mInitErr.IsntError())
4fc7a1 ¤   {
87db36 ¤   ¤   KeInitializeSemaphore(mSemPointer, count, limit);
3e9371 ¤   }
e1efe6 }
2baf5a
aee3d8 // ~PGPdiskSemaphore destroys a PGPdiskSemaphore object.
29d83c ·
a4c062 PGPdiskSemaphore::~PGPdiskSemaphore()
fdbb36 {
c2a6b2 ¤   if (IsntNull(mSemPointer))
5ec7a1 ¤   {
72525e ¤   ¤   delete mSemPointer;
dbcc45 ¤   ¤   mSemPointer = NULL;
2d9371 ¤   }
b6efe6 }
81af5a
29cb2e // Waits waits on the semaphore.
d9af5a
ac1b0b PGPUInt32·
adbe35 PGPdiskSemaphore::Wait(PGPUInt32 timeout, PGPBoolean alertable)
51bb36 {
3db112 ¤   pgpAssertAddrValid(mSemPointer, KSEMAPHORE);
a4af5a
054d1d ¤   if (timeout == INFINITE)
30c7a1 ¤   {
9fe94d ¤   ¤   return KeWaitForSingleObject(mSemPointer, Executive, KernelMode,·
7a457b ¤   ¤   ¤   alertable, NULL);
259371 ¤   }
8e0e24 ¤   else
ddc7a1 ¤   {
530c7f ¤   ¤   LARGE_INTEGER largeTimeout;
afaf5a
379f6f ¤   ¤   largeTimeout.QuadPart = timeout;
a8af5a
41e94d ¤   ¤   return KeWaitForSingleObject(mSemPointer, Executive, KernelMode,·
fca692 ¤   ¤   ¤   alertable, &largeTimeout);
2c9371 ¤   }
f4efe6 }
0faf5a
90bf98 // Signal signals the semaphore.
36af5a
53c823 void·
--66ca 0011cba2f9b40110185 Page 6 of WaitObjectClasses.cpp
6d6cad PGPdiskSemaphore::Signal(PGPUInt32 count, BOOLEAN wait)
fbbb36 {
41b112 ¤   pgpAssertAddrValid(mSemPointer, KSEMAPHORE);
02af5a
857b02 ¤   KeReleaseSemaphore(mSemPointer, 0, count, wait);
23efe6 }
18af5a
1c663c #endif // PGPDISK_MFC
--6228 000974acd2640110186 Page 1 of WaitObjectClasses.h
541bc3 //////////////////////////////////////////////////////////////////////////////
7f7f5a // WaitObjectClasses.h
b8465d //
16d296 // Declarations for WaitObjectClasses.cpp.
621bc3 //////////////////////////////////////////////////////////////////////////////
48af5a
e9e213 // $Id: WaitObjectClasses.h,v 1.1.2.8 1998/08/04 02:10:37 nryan Exp $
2aaf5a
67cbce // Copyright (C) 1998 by Network Associates, Inc.
4c71ae // All rights reserved.
33af5a
9cf945 #ifndef Included_WaitObjectClasses_h¤   // [
083fc8 #define Included_WaitObjectClasses_h
c3af5a
073a85 #include "DualErr.h"
ddaf5a
90af5a
d81bc3 //////////////////////////////////////////////////////////////////////////////
2ce9c4 // NOTE:
96465d //
8f70b1 // Unfortunately, synchronization primitive creation and use is so different
9b78be // across Win32, 95 driver mode and NT driver mode that it's impossible to
e8154b // provide a consistent calling interface to the following functions.
bd1bc3 //////////////////////////////////////////////////////////////////////////////
74af5a
3ba89a // The following classes are thread-safe.
07af5a
b209b7 ////////////
3ae738 // Constants
1b09b7 ////////////
c6af5a
44db91 const PGPUInt32 kInfiniteKernelSemLimit = 0x7FFFFFFF;
afaf5a
c3af5a
0e6931 #if defined(PGPDISK_MFC)
faaf5a
d06cc2 /////////////////////
3dbbb4 // Class PGPdiskMutex
f36cc2 /////////////////////
d7af5a
a63ca6 class PGPdiskMutex
35bb36 {
db5ed4 public:
c61603 ¤   DualErr mInitErr;
b5af5a
434ee7 ¤   ¤   ¤   ¤   PGPdiskMutex(PGPBoolean initOwnership = FALSE,·
780c9d ¤   ¤   ¤   ¤   ¤   LPCSTR name = NULL);
b241b8 ¤   ¤   ¤   ¤   ~PGPdiskMutex();
1faf5a
c554f8 ¤   PGPUInt32¤  Enter(PGPUInt32 timeout = INFINITE,·
268122 ¤   ¤   ¤   ¤   ¤   PGPBoolean alertable = FALSE);
b65a61 ¤   void¤   ¤   Leave();
6baf5a
4a0fb9 private:
5ad050 ¤   HANDLE mMutexHandle;
0382f7 };
69af5a
b2af5a
ff9f73 /////////////////////////
73b80d // Class PGPdiskSemaphore
d99f73 /////////////////////////
e8af5a
a9c233 class PGPdiskSemaphore
33bb36 {
d95ed4 public:
1a1603 ¤   DualErr mInitErr;
83af5a
135fcd ¤   ¤   ¤   ¤   PGPdiskSemaphore(PGPUInt32 initCount = 0, PGPUInt32 maxCount = ¶
632eed 1,·
6d0c9d ¤   ¤   ¤   ¤   ¤   LPCSTR name = NULL);
98ee61 ¤   ¤   ¤   ¤   ~PGPdiskSemaphore();
97af5a
--2704 000b0de2a9b40110186 Page 2 of WaitObjectClasses.h
cc3f84 ¤   PGPUInt32¤  Wait(PGPUInt32 timeout = INFINITE,·
d88122 ¤   ¤   ¤   ¤   ¤   PGPBoolean alertable = FALSE);
346e3a ¤   void¤   ¤   Signal(PGPUInt32 count = 1);
adaf5a
2f0fb9 private:
75e0af ¤   HANDLE mSemHandle;
a082f7 };
47af5a
44af5a
354268 #elif defined(PGPDISK_95DRIVER)
72af5a
e16cc2 /////////////////////
85bbb4 // Class PGPdiskMutex
e36cc2 /////////////////////
80af5a
963ca6 class PGPdiskMutex
51bb36 {
345ed4 public:
b91603 ¤   DualErr mInitErr;
bdaf5a
fdc3da ¤   ¤   ¤   PGPdiskMutex(PGPUInt32 boost = 0, PGPUInt32 flags = NULL);
75faee ¤   ¤   ¤   ~PGPdiskMutex();
3eaf5a
48459a ¤   void¤   Enter(PGPUInt32 flags = BLOCK_ENABLE_INTS | BLOCK_SVC_INTS);
277577 ¤   void¤   Leave();
53af5a
c50fb9 private:
4a3416 ¤   MUTEXHANDLE mMutexHandle;
a282f7 };
58af5a
f0af5a
7c9f73 /////////////////////////
5bb80d // Class PGPdiskSemaphore
d89f73 /////////////////////////
bfaf5a
b4c233 class PGPdiskSemaphore
afbb36 {
1e5ed4 public:
571603 ¤   DualErr mInitErr;
0faf5a
85155d ¤   ¤   ¤   PGPdiskSemaphore(PGPUInt32 tokenCount = 1);
bdd309 ¤   ¤   ¤   ~PGPdiskSemaphore();
11af5a
654fc9 ¤   void¤   Wait(PGPUInt32 flags = BLOCK_ENABLE_INTS | BLOCK_SVC_INTS);
3d9e50 ¤   void¤   Signal();
58af5a
f40fb9 private:
886898 ¤   SEMHANDLE mSemHandle;
6382f7 };
6aaf5a
fbaf5a
00f5a6 #elif defined(PGPDISK_NTDRIVER)
4faf5a
623e17 #define INFINITE 0xFFFFFFFF
53af5a
8e6cc2 /////////////////////
17bbb4 // Class PGPdiskMutex
456cc2 /////////////////////
86af5a
de3ca6 class PGPdiskMutex
dcbb36 {
af5ed4 public:
d91603 ¤   DualErr mInitErr;
e6af5a
832333 ¤   ¤   ¤   ¤   PGPdiskMutex(PGPUInt32 level);
7c41b8 ¤   ¤   ¤   ¤   ~PGPdiskMutex();
53af5a
4154f8 ¤   PGPUInt32¤  Enter(PGPUInt32 timeout = INFINITE,·
c38122 ¤   ¤   ¤   ¤   ¤   PGPBoolean alertable = FALSE);
93c96d ¤   void¤   ¤   Leave(PGPBoolean wait = FALSE);
b6af5a
b00fb9 private:
--c56b 001623e751340110186 Page 3 of WaitObjectClasses.h
ece99b ¤   PKMUTEX mMutexPointer;
4882f7 };
91af5a
e1af5a
199f73 /////////////////////////
31b80d // Class PGPdiskSemaphore
029f73 /////////////////////////
c0af5a
1ec233 class PGPdiskSemaphore
29bb36 {
195ed4 public:
661603 ¤   DualErr mInitErr;
c5af5a
eb064a ¤   ¤   ¤   ¤   PGPdiskSemaphore(PGPUInt32 count = 0, PGPUInt32 limit = 1);
50ee61 ¤   ¤   ¤   ¤   ~PGPdiskSemaphore();
70af5a
5e3f84 ¤   PGPUInt32¤  Wait(PGPUInt32 timeout = INFINITE,·
508122 ¤   ¤   ¤   ¤   ¤   PGPBoolean alertable = FALSE);
01f304 ¤   void¤   ¤   Signal(PGPUInt32 count = 1, PGPBoolean wait = FALSE);
03af5a
fe0fb9 private:
867767 ¤   PKSEMAPHORE mSemPointer;
ce82f7 };
2eaf5a
cc663c #endif // PGPDISK_MFC
1daf5a
626c96 #endif // ] Included_WaitObjectClasses_h
--2f3b 0006bdade4e40110187 Page 1 of Win32Utils.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
249c0b // Win32Utils.cpp
c6465d //
4de130 // Common Win32 utils.
921bc3 //////////////////////////////////////////////////////////////////////////////
a4af5a
f63ead // $Id: Win32Utils.cpp,v 1.1.2.23.2.4 1998/10/23 02:19:00 nryan Exp $
b2af5a
5ecbce // Copyright (C) 1998 by Network Associates, Inc.
7771ae // All rights reserved.
dcaf5a
3c6931 #if defined(PGPDISK_MFC)
eaaf5a
b49e12 #include "StdAfx.h"
fadfe4 #include "AfxPriv.h"
3caf5a
305f71 #include <Objbase.h>
595f7a #include <Shlobj.h>
df3366 #include <Dbt.h>
45af5a
dbdb21 #else
70333e #error Define PGPDISK_MFC.
d205d6 #endif¤ // PGPDISK_MFC
d2af5a
919bcf #include "Required.h"
d47efd #include "LinkResolution.h"
62babe #include "PGPdiskRegistry.h"
21993c #include "StringAssociation.h"
61bfe9 #include "UtilityFunctions.h"
2b6560 #include "Win32Utils.h"
24dd74 #include "WindowsVersion.h"
00af5a
23af5a
5709b7 ////////////
62e738 // Constants
4509b7 ////////////
78af5a
5e37cb const char kInvalidCharReplacement = '_';
89af5a
6eaf5a
4c2af8 //////////
16b932 // Globals
382af8 //////////
9faf5a
d0acac static CWnd *MessageBoxParent;
08af5a
23af5a
3ed48e ////////////////////////
8e3ef7 // Message box functions
72d48e ////////////////////////
0eaf5a
e43e63 // RegisterPGPdiskMsgBoxParent registers a window to be used as a message-box
8d3369 // parent.
d5af5a
82c823 void·
741981 RegisterPGPdiskMsgBoxParent(CWnd *pWnd)
98bb36 {
9c82eb ¤   MessageBoxParent = pWnd;
f1efe6 }
20af5a
0b4509 // GetLastPGPdiskWindow returns the frontmost PGPdisk window.
2caf5a
4e4f68 CWnd *·
d9abea GetLastPGPdiskWindow()
ebbb36 {
ed6380 ¤   if (MessageBoxParent->GetSafeHwnd())
cc06e3 ¤   ¤   return MessageBoxParent->GetLastActivePopup();
e50e24 ¤   else
4e7ed2 ¤   ¤   return NULL;
83efe6 }
4caf5a
6bfe25 // PGPdiskMessageBox shows a message box with the specified options. It
--1a99 0000b4e734340110187 Page 2 of Win32Utils.cpp
fb67e0 // returns the button the user pressed.
6aaf5a
e4d991 UserResponse·
662b0d PGPdiskMessageBox(
39674a ¤   LPCSTR¤ ¤   ¤   ¤   message,·
55cd2b ¤   CWnd¤   ¤   ¤   ¤   *pParent,·
56a127 ¤   LPCSTR¤ ¤   ¤   ¤   title,·
617756 ¤   PGDMessageBoxStyle¤ style,·
e2c7cb ¤   PGDMessageBoxFocus¤ focus)
cfbb36 {
135682 ¤   MSGBOXPARAMS¤   mbParams;
16c1ec ¤   PGPUInt32¤  ¤   button, defaultButton, flags;
b6af5a
7da350 ¤   pgpAssertStrValid(message);
0738b1 ¤   pgpAssertStrValid(title);
2caf5a
57ad70 ¤   mbParams.cbSize = sizeof(MSGBOXPARAMS);
b5af5a
62899e ¤   mbParams.hwndOwner¤ ¤   ¤   = pParent->GetSafeHwnd();
9e575a ¤   mbParams.hInstance¤ ¤   ¤   = NULL;
717457 ¤   mbParams.lpszText¤  ¤   ¤   = message;
3b7a54 ¤   mbParams.lpszCaption¤   ¤   = title;
33f250 ¤   mbParams.lpszIcon¤  ¤   ¤   = NULL;
6263d3 ¤   mbParams.dwContextHelpId¤   = NULL;
5d7636 ¤   mbParams.lpfnMsgBoxCallback¤= NULL;
dbb4ca ¤   mbParams.dwLanguageId¤  ¤   = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
24af5a
ecdbd5 ¤   flags = MB_SETFOREGROUND;
6eaf5a
a5c6fb ¤   // If main window on top, always on top.
d1b57e ¤   if (PGPdiskGetPrefDWord(kRegistryMainStayOnTopKey, MF_UNCHECKED) ==·
80c783 ¤   ¤   MF_CHECKED)
e3c7a1 ¤   {
a46017 ¤   ¤   flags |= MB_TOPMOST;
2b9371 ¤   }
d8af5a
9bf47f ¤   switch (style)
c4c7a1 ¤   {
2d0164 ¤   case kPMBS_Ok:
b5e712 ¤   ¤   flags |= MB_OK | MB_ICONERROR;
acaf5a
64e78f ¤   ¤   mbParams.dwStyle = flags;
c8af5a
b53e85 ¤   ¤   button = MessageBoxIndirect(&mbParams);
0d2f68 ¤   ¤   break;
bfaf5a
98db9d ¤   case kPMBS_OkCancel:
66740f ¤   ¤   switch (focus)
df5b34 ¤   ¤   {
4ea70f ¤   ¤   case kPMBF_OkButton:
a3fdca ¤   ¤   ¤   defaultButton = MB_DEFBUTTON1;
eccdcb ¤   ¤   ¤   break;
b4af5a
128f6d ¤   ¤   case kPMBF_CancelButton:
5612ae ¤   ¤   ¤   defaultButton = MB_DEFBUTTON2;
01cdcb ¤   ¤   ¤   break;
89af5a
199ae3 ¤   ¤   default:
b50606 ¤   ¤   ¤   pgpAssert(FALSE);
3bcdcb ¤   ¤   ¤   break;
1e0fe4 ¤   ¤   }
bd1b52 ¤   ¤
930708 ¤   ¤   flags |= defaultButton | MB_OKCANCEL | MB_ICONERROR;
51af5a
aee78f ¤   ¤   mbParams.dwStyle = flags;
bdaf5a
133e85 ¤   ¤   button = MessageBoxIndirect(&mbParams);
762f68 ¤   ¤   break;
c0af5a
8ef44d ¤   case kPMBS_YesNo:
2e740f ¤   ¤   switch (focus)
0b5b34 ¤   ¤   {
--4815 0004213d61f40110187 Page 3 of Win32Utils.cpp
b240f7 ¤   ¤   case kPMBF_YesButton:
c8fdca ¤   ¤   ¤   defaultButton = MB_DEFBUTTON1;
3fcdcb ¤   ¤   ¤   break;
b4af5a
c7b4cd ¤   ¤   case kPMBF_NoButton:
8a12ae ¤   ¤   ¤   defaultButton = MB_DEFBUTTON2;
b3cdcb ¤   ¤   ¤   break;
58af5a
829ae3 ¤   ¤   default:
0d0606 ¤   ¤   ¤   pgpAssert(FALSE);
d0cdcb ¤   ¤   ¤   break;
7c0fe4 ¤   ¤   }
7faf5a
21daf9 ¤   ¤   flags |= defaultButton | MB_YESNO | MB_ICONEXCLAMATION;
6baf5a
82e78f ¤   ¤   mbParams.dwStyle = flags;
4aaf5a
a03e85 ¤   ¤   button = MessageBoxIndirect(&mbParams);
9a2f68 ¤   ¤   break;
90af5a
58c27c ¤   case kPMBS_YesNoCancel:
18740f ¤   ¤   switch (focus)
d25b34 ¤   ¤   {
dc40f7 ¤   ¤   case kPMBF_YesButton:
14fdca ¤   ¤   ¤   defaultButton = MB_DEFBUTTON1;
3acdcb ¤   ¤   ¤   break;
15af5a
3cb4cd ¤   ¤   case kPMBF_NoButton:
7c12ae ¤   ¤   ¤   defaultButton = MB_DEFBUTTON2;
7dcdcb ¤   ¤   ¤   break;
1faf5a
408f6d ¤   ¤   case kPMBF_CancelButton:
984872 ¤   ¤   ¤   defaultButton = MB_DEFBUTTON3;
23cdcb ¤   ¤   ¤   break;
18af5a
459ae3 ¤   ¤   default:
7f0606 ¤   ¤   ¤   pgpAssert(FALSE);
15cdcb ¤   ¤   ¤   break;
950fe4 ¤   ¤   }
f7af5a
d1c592 ¤   ¤   flags |= defaultButton | MB_YESNOCANCEL | MB_ICONEXCLAMATION;
2faf5a
bee78f ¤   ¤   mbParams.dwStyle = flags;
81af5a
693e85 ¤   ¤   button = MessageBoxIndirect(&mbParams);
e92f68 ¤   ¤   break;
6daf5a
9b2f72 ¤   default:
fa8f52 ¤   ¤   pgpAssert(FALSE);
3b2f68 ¤   ¤   break;
059371 ¤   }
b9af5a
7c3f62 ¤   // Finally return the choice the user made in the message box.
8ee5f5 ¤   switch (button)
4fc7a1 ¤   {
b5557c ¤   case IDYES:
bea6ad ¤   ¤   return kUR_Yes;
42a519 ¤   case IDNO:
f2f0cf ¤   ¤   return kUR_No;
f8dac3 ¤   case IDOK:
d08c2e ¤   ¤   return kUR_OK;
e22f72 ¤   default:
eb37d4 ¤   ¤   return kUR_Cancel;
c59371 ¤   }
8defe6 }
16af5a
3ba5cd // ReportError reports an error to the user.
b8af5a
ccd991 UserResponse·
438e3e ReportError(
9e026f ¤   PGDMajorError¤  ¤   perr,·
42c0fa ¤   DualErr¤¤   ¤   ¤   derr,·
--10a2 000ca502b6540110187 Page 4 of Win32Utils.cpp
a64c9d ¤   PGPUInt8¤   ¤   ¤   drive,·
e37756 ¤   PGDMessageBoxStyle¤ style,·
04c7cb ¤   PGDMessageBoxFocus¤ focus)
b4bb36 {
bafd7d ¤   UserResponse button = kUR_Cancel;
03af5a
148f47 ¤   // Don't display dialog if we fail silently or if user canceled.
e190d8 ¤   if ((derr.mMinorError == kPGDMinorError_FailSilently) ||
1cc2b7 ¤   ¤   (derr.mMinorError == kPGDMinorError_UserAbort))
cdc7a1 ¤   {
7237d4 ¤   ¤   return kUR_Cancel;
dc9371 ¤   }
46af5a
8302c1 ¤   MessageBeep(MB_ICONHAND);
c8af5a
db78f1 ¤   try
4cc7a1 ¤   {
8dae63 ¤   ¤   CString errorString;
e0af5a
6a15b3 ¤   ¤   // Get the error string.
288e0d ¤   ¤   FormatErrorString(perr, derr, drive,·
426fd8 ¤   ¤   ¤   errorString.GetBuffer(kMaxStringSize), kMaxStringSize);
0daf5a
a3c6dd ¤   ¤   errorString.ReleaseBuffer();
79af5a
022c09 ¤   ¤   // Show the error message.
ccd8e1 ¤   ¤   button = PGPdiskMessageBox(errorString, GetLastPGPdiskWindow(),·
46e692 ¤   ¤   ¤   kPGPdiskErrorMsgBoxTitle, style, focus);
769371 ¤   }
873c88 ¤   catch (CMemoryException *ex)
f0c7a1 ¤   {
a2b209 ¤   ¤   // Guaranteed to succeed with these flags.
a4500d ¤   ¤   MessageBox(NULL, kPGPdiskErrorMsgBoxTitle,·
c162bb ¤   ¤   ¤   GetCommonString(kPGPdiskNoMemForErrorString),·
0a1302 ¤   ¤   ¤   MB_ICONHAND | MB_SYSTEMMODAL);
6aaf5a
a06adc ¤   ¤   ex->Delete();
129371 ¤   }
daaf5a
227775 ¤   return button;
aeefe6 }
33af5a
d44ede // DisplayMessage displays a message to the user.
e1af5a
81d991 UserResponse·
73e869 DisplayMessage(
fe5b5d ¤   PGPUInt32¤  ¤   ¤   stringId,·
247756 ¤   PGDMessageBoxStyle¤ style,·
dfc7cb ¤   PGDMessageBoxFocus¤ focus)
1fbb36 {
38fd7d ¤   UserResponse button = kUR_Cancel;
08af5a
21cdc2 ¤   // Show the message.
1bafee ¤   button = PGPdiskMessageBox(GetCommonString(stringId),·
b49847 ¤   ¤   GetLastPGPdiskWindow(), kPGPdiskNormalMsgBoxTitle, style, focus);
3caf5a
1f7775 ¤   return button;
a9efe6 }
62af5a
e7af5a
249791 ////////////////
b52e01 // GUI functions
639791 ////////////////
e3af5a
63ab22 // FindMenuItemPosition returns the position of the menu item with the given
62a262 // text in the given menu, or -1 otherwise.
cfaf5a
9330fb PGPInt32·
a95dc4 FindMenuItemPosition(CMenu *pMenu, LPCSTR menuString)
23bb36 {
ea41af ¤   PGPInt32 position = -1;
caaf5a
--1a25 0000a37335e40110187 Page 5 of Win32Utils.cpp
8a78f1 ¤   try
bbc7a1 ¤   {
97712c ¤   ¤   CString¤¤   itemText;
0904ae ¤   ¤   PGPInt32¤   i, numItems;
29af5a
2cfa07 ¤   ¤   pgpAssertAddrValid(pMenu, CMenu);
b278a9 ¤   ¤   pgpAssertStrValid(menuString);
ddaf5a
2d3713 ¤   ¤   numItems = pMenu->GetMenuItemCount();
31af5a
908653 ¤   ¤   if (numItems == -1)
083fd5 ¤   ¤   ¤   return -1;
94af5a
54ac92 ¤   ¤   for (i = 0; i < numItems; i++)
355b34 ¤   ¤   {
13e5b5 ¤   ¤   ¤   pMenu->GetMenuString(i, itemText, MF_BYPOSITION);
cc87c7 ¤   ¤   ¤
af6819 ¤   ¤   ¤   if (itemText.Compare(menuString) == 0)
27f776 ¤   ¤   ¤   {
1630ae ¤   ¤   ¤   ¤   position = i;
8df622 ¤   ¤   ¤   ¤   break;
58a3a6 ¤   ¤   ¤   }
b60fe4 ¤   ¤   }
b69371 ¤   }
e23c88 ¤   catch (CMemoryException *ex)
86c7a1 ¤   {
6a6adc ¤   ¤   ex->Delete();
d89371 ¤   }
71af5a
047cbb ¤   return position;
bcefe6 }
8eaf5a
beaf5a
96512c ////////////////////////////////
1125bd // Pathname Processing Functions
d7512c ////////////////////////////////
e3af5a
5b184c // ConvertPathToLong converts a short pathname to a long pathname.
06af5a
f12292 DualErr·
fd7aab ConvertPathToLong(CString *path)
82bb36 {
a77d36 ¤   DualErr derr;
74af5a
b878f1 ¤   try
91c7a1 ¤   {
2de7df ¤   ¤   CString¤¤   ¤   longPath, piece, prefix, temp;
f03286 ¤   ¤   HANDLE¤ ¤   ¤   findHandle;
052403 ¤   ¤   PGPUInt32¤  ¤   length;
f16350 ¤   ¤   WIN32_FIND_DATA¤findData;
fdaf5a
f5f896 ¤   ¤   pgpAssertAddrValid(path, CString);
83af5a
7f9035 ¤   ¤   length = path->GetLength();
dcaf5a
809008 ¤   ¤   // Get the prefix.
dfc4a5 ¤   ¤   if (path->GetAt(length - 1) == '\\')
3c5b34 ¤   ¤   {
24b65b ¤   ¤   ¤   (* path) = path->Left(length - 1);
83ff33 ¤   ¤   ¤   length--;
ed0fe4 ¤   ¤   }
ddaf5a
8810cf ¤   ¤   derr = GetRoot((* path), &prefix);
54af5a
9aa1fd ¤   ¤   // Take out the prefix and save it for later.
34aa35 ¤   ¤   if (derr.IsntError())
985b34 ¤   ¤   {
b3ee64 ¤   ¤   ¤   (* path) = path->Right(length - prefix.GetLength());
0d0fe4 ¤   ¤   }
8faf5a
a1ea51 ¤   ¤   // Convert each component of the pathname to its long form.
0ad8af ¤   ¤   while (derr.IsntError() && !path->IsEmpty())
--f7a0 00079b14b5c40110187 Page 6 of Win32Utils.cpp
e35b34 ¤   ¤   {
87f8f6 ¤   ¤   ¤   temp = prefix + (* path);
b1218f ¤   ¤   ¤   findHandle = FindFirstFile(temp, &findData);
acaf5a
f628e7 ¤   ¤   ¤   if (findHandle == INVALID_HANDLE_VALUE)
64f776 ¤   ¤   ¤   {
4a37bf ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_FindFirstFileFailed,·
763177 ¤   ¤   ¤   ¤   ¤   GetLastError());
a0a3a6 ¤   ¤   ¤   }
4fbb8c ¤   ¤   ¤   else
6bf776 ¤   ¤   ¤   {
56f5a6 ¤   ¤   ¤   ¤   FindClose(findHandle);
1caf5a
4f01af ¤   ¤   ¤   ¤   (* path) = path->Left(path->ReverseFind('\\'));
d2af5a
96413c ¤   ¤   ¤   ¤   piece = findData.cFileName;
21add1 ¤   ¤   ¤   ¤   longPath = piece + '\\' + longPath;
46a3a6 ¤   ¤   ¤   }
070fe4 ¤   ¤   }
90af5a
51c3b3 ¤   ¤   // Prepare the output.
52aa35 ¤   ¤   if (derr.IsntError())
6b5b34 ¤   ¤   {
2d6001 ¤   ¤   ¤   longPath¤   = longPath.Left(longPath.GetLength() - 1);
f7b9b0 ¤   ¤   ¤   longPath¤   = prefix + longPath;
6baf5a
a6cfaa ¤   ¤   ¤   (* path) = longPath;
ec0fe4 ¤   ¤   }
a79371 ¤   }
093c88 ¤   catch (CMemoryException *ex)
c2c7a1 ¤   {
c2ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
3c6adc ¤   ¤   ex->Delete();
c99371 ¤   }
86af5a
6033e3 ¤   return derr;
a9efe6 }
efaf5a
430a76 // GetRoot takes any legal path and returns a string of the form "C:\" or
0d0c2a // "\\UncVolumeName\share\".
e6af5a
962292 DualErr·
71f14b GetRoot(LPCSTR path, CString *root)
e5bb36 {
837d36 ¤   DualErr derr;
f4af5a
e1639f ¤   pgpAssertStrValid(path);
77d0f2 ¤   pgpAssertAddrValid(root, CString);
53af5a
8a78f1 ¤   try
b8c7a1 ¤   {
b48fed ¤   ¤   CString tempString;
b9af5a
dbf16c ¤   ¤   tempString = path;
a414d6 ¤   ¤   root->Empty();
c4af5a
42a9ab ¤   ¤   if (HasPlainLocalRoot(path))
cc5b34 ¤   ¤   {
2bd999 ¤   ¤   ¤   (* root) = tempString.Left(3);
f30fe4 ¤   ¤   }
1799ce ¤   ¤   else if (IsUNCPath(path))
8c5b34 ¤   ¤   {
b0951b ¤   ¤   ¤   PGPInt32¤   i;
2d7460 ¤   ¤   ¤   PGPUInt32¤  numSlashes;
d3af5a
930f69 ¤   ¤   ¤   for (i = 0, numSlashes = 0; i < tempString.GetLength(); i++)
53f776 ¤   ¤   ¤   {
e7c357 ¤   ¤   ¤   ¤   if (path[i] == '\\')
83e952 ¤   ¤   ¤   ¤   ¤   numSlashes++;
3caf5a
dd3d5d ¤   ¤   ¤   ¤   if (numSlashes == 4)
7972c3 ¤   ¤   ¤   ¤   {
--d93b 000109492aa40110187 Page 7 of Win32Utils.cpp
46c8fe ¤   ¤   ¤   ¤   ¤   (* root) = tempString.Left(i + 1);
3d14c3 ¤   ¤   ¤   ¤   ¤   break;
482613 ¤   ¤   ¤   ¤   }
d5a3a6 ¤   ¤   ¤   }
bd0fe4 ¤   ¤   }
f49371 ¤   }
6c3c88 ¤   catch (CMemoryException *ex)
9ac7a1 ¤   {
baecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
8e6adc ¤   ¤   ex->Delete();
329371 ¤   }
89af5a
8933e3 ¤   return derr;
b4efe6 }
2faf5a
563026 // MakeRoot makes a root out of a drive number.
b7af5a
f22292 DualErr·
331185 MakeRoot(PGPUInt8 drive, CString *root)
dbbb36 {
b27d36 ¤   DualErr derr;
adaf5a
19aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
5cd0f2 ¤   pgpAssertAddrValid(root, CString);
daaf5a
ca78f1 ¤   try
39c7a1 ¤   {
7bcd55 ¤   ¤   root->Format("%c:\\", DriveNumToLet(drive));
149371 ¤   }
c93c88 ¤   catch (CMemoryException *ex)
fac7a1 ¤   {
efecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
596adc ¤   ¤   ex->Delete();
4a9371 ¤   }
ceaf5a
8a33e3 ¤   return derr;
2fefe6 }
73af5a
dbe02b // StripRoot removes the root from a pathname.
9aaf5a
4a2292 DualErr·
38876b StripRoot(LPCSTR path, CString *nonRoot)
50bb36 {
047d36 ¤   DualErr derr;
34af5a
01639f ¤   pgpAssertStrValid(path);
fb5691 ¤   pgpAssertAddrValid(nonRoot, CString);
7aaf5a
8178f1 ¤   try
f9c7a1 ¤   {
2aefcd ¤   ¤   CString csInPath, root;
adaf5a
b47f80 ¤   ¤   csInPath = path;
d8af5a
65cc97 ¤   ¤   derr = GetRoot(path, &root);
67af5a
93aa35 ¤   ¤   if (derr.IsntError())
dc5b34 ¤   ¤   {
60cbfb ¤   ¤   ¤   (* nonRoot) = csInPath.Right(csInPath.GetLength() -·
39a4c0 ¤   ¤   ¤   ¤   root.GetLength());
a30fe4 ¤   ¤   }
499371 ¤   }
553c88 ¤   catch (CMemoryException *ex)
16c7a1 ¤   {
f9ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
cd6adc ¤   ¤   ex->Delete();
8f9371 ¤   }
67af5a
5733e3 ¤   return derr;
beefe6 }
85af5a
1062f7 // GetServer takes a UNC path and returns the server component.
--a23d 0003eb6b49f40110187 Page 8 of Win32Utils.cpp
e0af5a
6f2292 DualErr·
838f9a GetServer(LPCSTR path, CString *server)
a8bb36 {
187d36 ¤   DualErr derr;
a9af5a
d3639f ¤   pgpAssertStrValid(path);
7dcc6f ¤   pgpAssertAddrValid(server, CString);
2daf5a
0878f1 ¤   try
edc7a1 ¤   {
428fed ¤   ¤   CString tempString;
5aaf5a
cf2aa0 ¤   ¤   server->Empty();
b8af5a
2588ef ¤   ¤   if (IsUNCPath(path))
2f5b34 ¤   ¤   {
6f1112 ¤   ¤   ¤   tempString = path + 2;
deed15 ¤   ¤   ¤   (* server) = tempString.Left(tempString.Find('\\'));
ca0fe4 ¤   ¤   }
ad9371 ¤   }
073c88 ¤   catch (CMemoryException *ex)
ebc7a1 ¤   {
c7ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
b36adc ¤   ¤   ex->Delete();
ed9371 ¤   }
62af5a
ec33e3 ¤   return derr;
9eefe6 }
bbaf5a
9af9bb // GetShare takes a UNC path and returns the share component.
c4af5a
1b2292 DualErr·
ba8e0e GetShare(LPCSTR path, CString *share)
0cbb36 {
7c7d36 ¤   DualErr derr;
1caf5a
c7639f ¤   pgpAssertStrValid(path);
57d3ff ¤   pgpAssertAddrValid(share, CString);
b4af5a
ba78f1 ¤   try
cec7a1 ¤   {
0b8fed ¤   ¤   CString tempString;
06af5a
23f16c ¤   ¤   tempString = path;
3bb051 ¤   ¤   share->Empty();
86af5a
6988ef ¤   ¤   if (IsUNCPath(path))
bb5b34 ¤   ¤   {
5e951b ¤   ¤   ¤   PGPInt32¤   i;
767460 ¤   ¤   ¤   PGPUInt32¤  numSlashes;
dcaf5a
db0f69 ¤   ¤   ¤   for (i = 0, numSlashes = 0; i < tempString.GetLength(); i++)
78f776 ¤   ¤   ¤   {
90c357 ¤   ¤   ¤   ¤   if (path[i] == '\\')
afe952 ¤   ¤   ¤   ¤   ¤   numSlashes++;
d7af5a
90b158 ¤   ¤   ¤   ¤   if (numSlashes == 3)
2172c3 ¤   ¤   ¤   ¤   {
251436 ¤   ¤   ¤   ¤   ¤   tempString = path + i + 1;
7bf7e6 ¤   ¤   ¤   ¤   ¤   (* share) = tempString.Left(tempString.Find('\\'));
e0af5a
2314c3 ¤   ¤   ¤   ¤   ¤   break;
8f2613 ¤   ¤   ¤   ¤   }
14a3a6 ¤   ¤   ¤   }
0a0fe4 ¤   ¤   }
e19371 ¤   }
ee3c88 ¤   catch (CMemoryException *ex)
d1c7a1 ¤   {
76ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
526adc ¤   ¤   ex->Delete();
3e9371 ¤   }
--1ed0 0009f86710f40110187 Page 9 of Win32Utils.cpp
e0af5a
cf33e3 ¤   return derr;
f5efe6 }
08af5a
c1c802 // GetCurrentDirectory gets the current working directory.
bfaf5a
ab2292 DualErr·
bbea5a GetCurrentDirectory(CString *outDir)
f5bb36 {
147d36 ¤   DualErr derr;
48af5a
6a6901 ¤   pgpAssertAddrValid(outDir, CString);
9aaf5a
03c332 ¤   try·
dec7a1 ¤   {
867d25 ¤   ¤   LPSTR outDirBuf;
e4af5a
1626f9 ¤   ¤   outDirBuf = outDir->GetBuffer(kMaxStringSize);
fad497 ¤   ¤   GetCurrentDirectory(kMaxStringSize, outDirBuf);
7435fa ¤   ¤   outDir->ReleaseBuffer();
889371 ¤   }
843c88 ¤   catch (CMemoryException *ex)
1dc7a1 ¤   {
a8ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
e56adc ¤   ¤   ex->Delete();
0f9371 ¤   }
efaf5a
f433e3 ¤   return derr;
4cefe6 }
b8af5a
00f1a6 // GetDirectory strips the file name off of a path.
11af5a
6ee677 DualErr
da56ff GetDirectory(LPCSTR path, CString *dir)
59bb36 {
7f7d36 ¤   DualErr derr;
89af5a
74639f ¤   pgpAssertStrValid(path);
e2a7be ¤   pgpAssertAddrValid(dir, CString);
63af5a
6678f1 ¤   try
a8c7a1 ¤   {
3a8fed ¤   ¤   CString tempString;
fdaf5a
30e016 ¤   ¤   dir->Empty();
ccf16c ¤   ¤   tempString = path;
b2af5a
bf9ab7 ¤   ¤   if (tempString.GetAt(tempString.GetLength() - 1) != '\\')
755b34 ¤   ¤   {
58aaf3 ¤   ¤   ¤   PGPInt32 lastSlash;
6baf5a
1c91f2 ¤   ¤   ¤   lastSlash = tempString.ReverseFind('\\');
eeaf5a
cc2e3b ¤   ¤   ¤   if (lastSlash != -1)
9f33c6 ¤   ¤   ¤   ¤   (* dir) = tempString.Left(lastSlash + 1);
de0fe4 ¤   ¤   }
9e0e1d ¤   ¤   else
405b34 ¤   ¤   {
edabab ¤   ¤   ¤   (* dir) = tempString;
da0fe4 ¤   ¤   }
ec9371 ¤   }
a83c88 ¤   catch (CMemoryException *ex)
2dc7a1 ¤   {
bfecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
156adc ¤   ¤   ex->Delete();
af9371 ¤   }
84af5a
df33e3 ¤   return derr;
1fefe6 }
c8af5a
47b7fe // GetDirectorySmart is like GetDirectory except it tacks on a working
9f5310 // directory path to incomplete directories.
--99b6 00089f4d04640110187 Page 10 of Win32Utils.cpp
e0af5a
1fe677 DualErr
012675 GetDirectorySmart(LPCSTR path, CString *dir)
34bb36 {
ea7d36 ¤   DualErr derr;
dbaf5a
fd639f ¤   pgpAssertStrValid(path);
e6a7be ¤   pgpAssertAddrValid(dir, CString);
d2af5a
5878f1 ¤   try
0cc7a1 ¤   {
348fed ¤   ¤   CString tempString;
f8af5a
01e016 ¤   ¤   dir->Empty();
88f16c ¤   ¤   tempString = path;
d9af5a
869ab7 ¤   ¤   if (tempString.GetAt(tempString.GetLength() - 1) != '\\')
b25b34 ¤   ¤   {
996678 ¤   ¤   ¤   PGPUInt32 lastSlash;
8aaf5a
9391f2 ¤   ¤   ¤   lastSlash = tempString.ReverseFind('\\');
e1af5a
3a2e3b ¤   ¤   ¤   if (lastSlash != -1)
f3f776 ¤   ¤   ¤   {
4ebf90 ¤   ¤   ¤   ¤   (* dir) = tempString.Left(lastSlash);
5e679b ¤   ¤   ¤   ¤   (* dir) += "\\";
fca3a6 ¤   ¤   ¤   }
a30fe4 ¤   ¤   }
760e1d ¤   ¤   else
425b34 ¤   ¤   {
e9abab ¤   ¤   ¤   (* dir) = tempString;
bd0fe4 ¤   ¤   }
35af5a
13aaf6 ¤   ¤   if (!HasPlainLocalRoot((* dir)) && !IsUNCPath((* dir)))
215b34 ¤   ¤   {
38ad1c ¤   ¤   ¤   CString workingDir;
28af5a
8d2cb5 ¤   ¤   ¤   derr = GetCurrentDirectory(&workingDir);
3aaf5a
d69d3d ¤   ¤   ¤   if (derr.IsntError())
e1f776 ¤   ¤   ¤   {
682baa ¤   ¤   ¤   ¤   tempString = (* dir);
99af5a
f23563 ¤   ¤   ¤   ¤   if (tempString.IsEmpty() || (tempString.GetAt(0) != '\\'))
bbd559 ¤   ¤   ¤   ¤   ¤   (* dir) = workingDir + "\\" + tempString;
defa07 ¤   ¤   ¤   ¤   else
cbae00 ¤   ¤   ¤   ¤   ¤   (* dir) = workingDir + tempString;
7ca3a6 ¤   ¤   ¤   }
6a0fe4 ¤   ¤   }
909371 ¤   }
7e3c88 ¤   catch (CMemoryException *ex)
d0c7a1 ¤   {
25ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
836adc ¤   ¤   ex->Delete();
469371 ¤   }
8baf5a
8e33e3 ¤   return derr;
ccefe6 }
a5af5a
0eb8d6 // GetBareName takes a full pathname to a file and returns just the name of
2b29bc // the file, without the path. It checks the Windows 'show extensions'
cf0d22 // preference and keeps or discards the extension as necessary.
d4af5a
4de677 DualErr
75b64c GetBareName(LPCSTR path, CString *bareName, BareNameExtFlag bneFlag)
d3bb36 {
7c7d36 ¤   DualErr derr;
f2af5a
a6639f ¤   pgpAssertStrValid(path);
ad51df ¤   pgpAssertAddrValid(bareName, CString);
28af5a
8978f1 ¤   try
--d836 000d2ad905540110187 Page 11 of Win32Utils.cpp
f7c7a1 ¤   {
bbc861 ¤   ¤   CString¤¤   displayName, tempString;
3b6baa ¤   ¤   PGPBoolean¤ stripExtension;
2ccf8c ¤   ¤   PGPInt32¤   lastSlash;
6c1c8a ¤   ¤   SHFILEINFO¤ SHFI;
f5af5a
ec6830 ¤   ¤   bareName->Empty();
feaf5a
1e7ee1 ¤   ¤   if (strlen(path) < 3)
5e831e ¤   ¤   ¤   derr = DualErr(kPGDMinorError_InvalidPathNameFound);
6baf5a
d5b8aa ¤   ¤   // Will we show or hide the extension?
d4aa35 ¤   ¤   if (derr.IsntError())
3d5b34 ¤   ¤   {
71239c ¤   ¤   ¤   switch (bneFlag)
65f776 ¤   ¤   ¤   {
871bb5 ¤   ¤   ¤   case kBNE_Default:
f5e125 ¤   ¤   ¤   ¤   // Ask the system how to display this pathname.
79f755 ¤   ¤   ¤   ¤   SHGetFileInfo(path, NULL, &SHFI, sizeof(SHFI),·
bcc744 ¤   ¤   ¤   ¤   ¤   SHGFI_DISPLAYNAME);
e8af5a
d1c5d3 ¤   ¤   ¤   ¤   displayName = SHFI.szDisplayName;
2aaf5a
9ee580 ¤   ¤   ¤   ¤   stripExtension = (displayName.Right(4).CompareNoCase(
b32e08 ¤   ¤   ¤   ¤   ¤   kPGPdiskFileExtension) != 0);
8934a5 ¤   ¤   ¤   ¤   ;
ebf622 ¤   ¤   ¤   ¤   break;
c4af5a
112273 ¤   ¤   ¤   case kBNE_HideExt:
b52978 ¤   ¤   ¤   ¤   stripExtension = TRUE;
9df622 ¤   ¤   ¤   ¤   break;
c4af5a
8fc9f1 ¤   ¤   ¤   case kBNE_ShowExt:
0ccea5 ¤   ¤   ¤   ¤   stripExtension = FALSE;
94f622 ¤   ¤   ¤   ¤   break;
f8af5a
9edb68 ¤   ¤   ¤   default:
85310e ¤   ¤   ¤   ¤   pgpAssert(FALSE);
f4f622 ¤   ¤   ¤   ¤   break;
bfa3a6 ¤   ¤   ¤   }
86af5a
16e544 ¤   ¤   ¤   tempString = path;
48af5a
b0cbe7 ¤   ¤   ¤   // Strip the path component.
c991f2 ¤   ¤   ¤   lastSlash = tempString.ReverseFind('\\');
93af5a
c92e3b ¤   ¤   ¤   if (lastSlash != -1)
65f776 ¤   ¤   ¤   {
ae5dfa ¤   ¤   ¤   ¤   (* bareName) = tempString.Right(tempString.GetLength() -·
46b122 ¤   ¤   ¤   ¤   ¤   lastSlash - 1);
8aa3a6 ¤   ¤   ¤   }
f4bb8c ¤   ¤   ¤   else
85f776 ¤   ¤   ¤   {
64782c ¤   ¤   ¤   ¤   (* bareName) = tempString;
87a3a6 ¤   ¤   ¤   }
14af5a
f4fb6f ¤   ¤   ¤   // Strip extension if ordered to.
5ded9c ¤   ¤   ¤   if (stripExtension)
abf776 ¤   ¤   ¤   {
af972d ¤   ¤   ¤   ¤   PGPInt32 lastDot;
04af5a
68289d ¤   ¤   ¤   ¤   tempString = (* bareName);
2799dc ¤   ¤   ¤   ¤   lastDot = tempString.ReverseFind('.');
6faf5a
85d7f6 ¤   ¤   ¤   ¤   if (lastDot != -1)
821f5f ¤   ¤   ¤   ¤   ¤   (* bareName) = tempString.Left(lastDot);
3fa3a6 ¤   ¤   ¤   }
100fe4 ¤   ¤   }
549371 ¤   }
e23c88 ¤   catch (CMemoryException *ex)
46c7a1 ¤   {
d2ecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
--fcea 00021c4cf4740110187 Page 12 of Win32Utils.cpp
fd6adc ¤   ¤   ex->Delete();
9a9371 ¤   }
b5af5a
2033e3 ¤   return derr;
13efe6 }
abaf5a
456279 // CanonicalizeVolumeName turns the input string into a legal volume name.
e6af5a
2d2292 DualErr·
01d46d CanonicalizeVolumeName(LPCSTR inName, CString *outName)
82bb36 {
2c7d36 ¤   DualErr derr;
2aaf5a
3d2b1e ¤   pgpAssertStrValid(inName);
a40f58 ¤   pgpAssertAddrValid(outName, CString);
a0af5a
52c332 ¤   try·
adc7a1 ¤   {
181077 ¤   ¤   PGPUInt32 i;
91af5a
d78945 ¤   ¤   // Legalize the label.
fda392 ¤   ¤   (* outName)¤= inName;
83f23a ¤   ¤   (* outName)¤= outName->Left(kMaxVolumeLabelLength);
45af5a
e26bb3 ¤   ¤   while ((i = outName->FindOneOf(kInvalidVolumeNameChars)) != -1)
b45b34 ¤   ¤   {
42526d ¤   ¤   ¤   outName->SetAt(i, kInvalidCharReplacement);
d20fe4 ¤   ¤   }
b39371 ¤   }
fb3c88 ¤   catch (CMemoryException *ex)
c7c7a1 ¤   {
8cecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
826adc ¤   ¤   ex->Delete();
829371 ¤   }
23af5a
2a33e3 ¤   return derr;
4eefe6 }
0faf5a
980ce9 // VerifyAndCanonicalizePath takes a pathname or a filename, and returns the
e0dcc1 // full path to the closest file it can find.
e8af5a
532292 DualErr·
078fa2 VerifyAndCanonicalizePath(LPCSTR inPath, CString *outPath)
9abb36 {
037d36 ¤   DualErr derr;
15af5a
c978f1 ¤   try
36c7a1 ¤   {
b3eb42 ¤   ¤   CString¤¤   bareName, csInPath, dir, localPath;
05a958 ¤   ¤   LPSTR¤  ¤   pFilePart¤  = NULL;
1debcb ¤   ¤   PGPBoolean¤ isLoopedBack;
b7af5a
82fa22 ¤   ¤   pgpAssertStrValid(inPath);
4682ad ¤   ¤   pgpAssertAddrValid(outPath, CString);
b5af5a
10c470 ¤   ¤   csInPath = inPath;
0baf5a
e164a9 ¤   ¤   // If looped back, resolve it a to local path.
40aa35 ¤   ¤   if (derr.IsntError())
b25b34 ¤   ¤   {
ee79c8 ¤   ¤   ¤   if (IsNetworkedPath(csInPath))
2af776 ¤   ¤   ¤   {
6d97eb ¤   ¤   ¤   ¤   if (!IsUNCPath(csInPath))
9153d6 ¤   ¤   ¤   ¤   ¤   derr = TranslateDriveToUNC(csInPath, &csInPath);
9faf5a
54724e ¤   ¤   ¤   ¤   if (derr.IsntError())
2472c3 ¤   ¤   ¤   ¤   {
ebe1a1 ¤   ¤   ¤   ¤   ¤   CheckIfLoopedBack(csInPath, &localPath,·
8a117a ¤   ¤   ¤   ¤   ¤   ¤   &isLoopedBack);
e5af5a
384ea0 ¤   ¤   ¤   ¤   ¤   if (derr.IsntError())
214859 ¤   ¤   ¤   ¤   ¤   {
--09ab 0002300186840110187 Page 13 of Win32Utils.cpp
6e71b2 ¤   ¤   ¤   ¤   ¤   ¤   if (isLoopedBack)
41388a ¤   ¤   ¤   ¤   ¤   ¤   ¤   csInPath = localPath;
0e1c89 ¤   ¤   ¤   ¤   ¤   }
69af5a
8f1787 ¤   ¤   ¤   ¤   ¤   // This check WILL fail on non-admin accounts; don't
a550c1 ¤   ¤   ¤   ¤   ¤   // sweat it now, we will deal with it later.
f6af5a
97a0b9 ¤   ¤   ¤   ¤   ¤   derr = DualErr::NoError;
432613 ¤   ¤   ¤   ¤   }
9fa3a6 ¤   ¤   ¤   }
a50fe4 ¤   ¤   }
4daf5a
5eb283 ¤   ¤   // Get the bare file name.
49aa35 ¤   ¤   if (derr.IsntError())
685b34 ¤   ¤   {
c403c8 ¤   ¤   ¤   derr = GetBareName(csInPath, &bareName, kBNE_ShowExt);
950fe4 ¤   ¤   }
f6af5a
d78e1a ¤   ¤   // Get the directory component.
1caa35 ¤   ¤   if (derr.IsntError())
365b34 ¤   ¤   {
7ec819 ¤   ¤   ¤   derr = GetDirectorySmart(csInPath, &dir);
560fe4 ¤   ¤   }
c9af5a
9e8fdc ¤   ¤   // Get full pathname to the file.
47aa35 ¤   ¤   if (derr.IsntError())
c55b34 ¤   ¤   {
a7dff8 ¤   ¤   ¤   if (!::SearchPath(dir, bareName, kPGPdiskFileExtension,·
75057c ¤   ¤   ¤   ¤   kMaxStringSize, outPath->GetBuffer(kMaxStringSize),·
fe3ba4 ¤   ¤   ¤   ¤   &pFilePart))
53f776 ¤   ¤   ¤   {
4cf5f7 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_PGPdiskNotFound);
95a3a6 ¤   ¤   ¤   }
13af5a
b89faa ¤   ¤   ¤   outPath->ReleaseBuffer();
2e0fe4 ¤   ¤   }
28af5a
ad27ec ¤   ¤   // Convert to long pathname form.
a0aa35 ¤   ¤   if (derr.IsntError())
c25b34 ¤   ¤   {
a000b8 ¤   ¤   ¤   derr = ConvertPathToLong(outPath);
b93b90 ¤   ¤   }¤
369371 ¤   }
7e3c88 ¤   catch (CMemoryException *ex)
5ac7a1 ¤   {
dfecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
816adc ¤   ¤   ex->Delete();
089371 ¤   }
d7af5a
cd33e3 ¤   return derr;
cbefe6 }
24af5a
f21c6d // ResolveShortcut takes a path to a shortcut and returns a path to the actual
46a117 // file. Ripped from the SDK.
15af5a
e72292 DualErr·
9472dd ResolveShortcut(LPCSTR shortcutPath, CString *fullPath)
23bb36 {
4fd78f ¤   CString¤¤   ¤   szGotPath;
6c8d59 ¤   DualErr ¤   ¤   derr;
15f875 ¤   HRESULT ¤   ¤   result;
214185 ¤   IPersistFile¤   *pIPF;
4604fe ¤   IShellLink¤ ¤   *pShellLink;
01a63b ¤   PGPBoolean¤ ¤   loadedCOM, loadedPersistFile, loadedShellLink;
f22eaa ¤   WIN32_FIND_DATA¤WFD;
95d83c ·
37d064 ¤   pgpAssertStrValid(shortcutPath);
1c3a4c ¤   pgpAssertAddrValid(fullPath, CString);
96af5a
61b0a9 ¤   loadedCOM = loadedPersistFile = loadedShellLink = FALSE;
e1af5a
23f015 ¤   // Load COM.
--3a72 0002163eda540110187 Page 14 of Win32Utils.cpp
4fef1a ¤   result = CoInitialize(NULL);
99af5a
eaadda ¤   if (result < 0)
f144ec ¤   ¤   derr = DualErr(kPGDMinorError_CoInitializeExFailed);
1baf5a
88e4c4 ¤   loadedCOM = derr.IsntError();
30af5a
da5d70 ¤   // Get a pointer to the IShellLink interface.
422361 ¤   if (derr.IsntError())
41c7a1 ¤   {
fc7d19 ¤   ¤   result = CoCreateInstance(CLSID_ShellLink, NULL,·
0258f9 ¤   ¤   ¤   CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &pShellLink);
b4af5a
dcd72e ¤   ¤   if (result < 0)
4135a7 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_CoCreateInstanceFailed);
8eaf5a
758f06 ¤   ¤   loadedShellLink = derr.IsntError();
239371 ¤   }
92af5a
08841f ¤   // Get a pointer to the IPersistFile interface.
b42361 ¤   if (derr.IsntError())
739108 ¤   {·
fe9104 ¤   ¤   result = pShellLink->QueryInterface(IID_IPersistFile,·
727b32 ¤   ¤   ¤   (void **) &pIPF);
16af5a
68d72e ¤   ¤   if (result < 0)
9f36d9 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_QueryInterfaceFailed);
b8af5a
e70f21 ¤   ¤   loadedPersistFile = derr.IsntError();
fb9371 ¤   }
deaf5a
1d2361 ¤   if (derr.IsntError())
8bc7a1 ¤   {
ea014b ¤   ¤   PGPUInt16 uniSCPath[kMaxStringSize];·
8dd83c ·
0f315c ¤   ¤   // Ensure that the string is Unicode.
58e818 ¤   ¤   MultiByteToWideChar(CP_ACP, 0, shortcutPath, -1, uniSCPath,·
0440e7 ¤   ¤   ¤   kMaxStringSize);
17d83c ·
4c6988 ¤   ¤   // Load the shortcut.
167a0b ¤   ¤   result = pIPF->Load(uniSCPath, STGM_READ);
59af5a
90d72e ¤   ¤   if (result < 0)
c293a4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OLELoadCommandFailed);
649371 ¤   }
01af5a
e8805a ¤   // Resolve the link.
4a2361 ¤   if (derr.IsntError())
59c7a1 ¤   {
4255f3 ¤   ¤   result = pShellLink->Resolve(MessageBoxParent->GetSafeHwnd(),·
d6b525 ¤   ¤   ¤   SLR_ANY_MATCH);
0baf5a
e5d72e ¤   ¤   if (result < 0)
221f8a ¤   ¤   ¤   derr = DualErr(kPGDMinorError_ResolveShortcutFailed);
8d9371 ¤   }
baaf5a
a04453 ¤   // Get the path to the link target.
dc2361 ¤   if (derr.IsntError())
4bc7a1 ¤   {
1341f1 ¤   ¤   try
845b34 ¤   ¤   {
95bb43 ¤   ¤   ¤   result = pShellLink->GetPath(fullPath->GetBuffer(kMaxStringSize),·
c1ca32 ¤   ¤   ¤   ¤   kMaxStringSize, (WIN32_FIND_DATA *) &WFD, SLGP_SHORTPATH);
47af5a
8993e1 ¤   ¤   ¤   fullPath->ReleaseBuffer();
d8af5a
c9214b ¤   ¤   ¤   if (result < 0)
04162c ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OLEGetPathFailed);
240fe4 ¤   ¤   }
f901e0 ¤   ¤   catch (CMemoryException *ex)
d25b34 ¤   ¤   {
21b95c ¤   ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
--170a 0003b7d82a740110187 Page 15 of Win32Utils.cpp
46ad69 ¤   ¤   ¤   ex->Delete();
910fe4 ¤   ¤   }
619371 ¤   }
22af5a
e49464 ¤   // Release the pointer to the IPersistFile interface.
669fbe ¤   if (loadedPersistFile)
54f391 ¤   ¤   pIPF->Release();·
1aaf5a
a3aa5d ¤   // Release the pointer to the IShellLink interface.
fa0eca ¤   if (loadedShellLink)
363711 ¤   ¤   pShellLink->Release();·
e5af5a
574c28 ¤   if (loadedCOM)
4eba71 ¤   ¤   CoUninitialize();
a5af5a
e333e3 ¤   return derr;
91efe6 }
c4af5a
6caf5a
079f73 /////////////////////////
e2d30c // Drive/volume functions
679f73 /////////////////////////
a2af5a
70c4d4 // BroadcastDriveMessage broadcasts a system message concerning the volume.
0eaf5a
d92292 DualErr·
527fc8 BroadcastDriveMessage(PGPUInt8 drive, WPARAM msg)
3cbb36 {
861ff6 ¤   DEV_BROADCAST_VOLUME¤   DBV;
679f1b ¤   DualErr¤¤   ¤   ¤   ¤   derr;
309a35 ¤   PGPInt32¤   ¤   ¤   ¤   result;
e1af5a
e8aa16 ¤   pgpAssert(IsLegalDriveNumber(drive));
1daf5a
27c70b ¤   DBV.dbcv_size¤  ¤   = sizeof(DBV);·
b37ea8 ¤   DBV.dbcv_devicetype = DBT_DEVTYP_VOLUME;·
8c612c ¤   DBV.dbcv_reserved¤  = 0;
469ab7 ¤   DBV.dbcv_unitmask¤  = 1 << drive;·
e03ec3 ¤   DBV.dbcv_flags¤ ¤   = DBTF_MEDIA;
ebaf5a
d7d944 ¤   result = BroadcastSystemMessage(BSF_NOHANG | BSF_POSTMESSAGE, NULL,·
03f84e ¤   ¤   WM_DEVICECHANGE, msg, (LPARAM) &DBV);
02af5a
5cf706 ¤   if (result < 1)
f0cc2e ¤   ¤   derr = DualErr(kPGDMinorError_BroadcastSystemMessageFailed);
ab67c5 ¤
b033e3 ¤   return derr;
8aefe6 }
32af5a
287d6f // GetLocalComputerName returns the name of the local computer.
d4af5a
a42292 DualErr·
51d6f7 GetLocalComputerName(CString *compName)
37bb36 {
527d36 ¤   DualErr derr;
39af5a
3c78f1 ¤   try
70c7a1 ¤   {
319c9e ¤   ¤   PGPUInt32¤  ¤   result;
fb983e ¤   ¤   WKSTA_INFO_100¤ *pWI100;
a0af5a
ef8fc8 ¤   ¤   USES_CONVERSION;
cfaf5a
0d7d1d ¤   ¤   pgpAssertAddrValid(compName, CString);
131e30 ¤   ¤   pgpAssert(IsWinNT4CompatibleMachine());
34af5a
0c546f ¤   ¤   result = WinNT_NetWkstaGetInfo(NULL, 100, (LPBYTE *) &pWI100);
e0af5a
f8a788 ¤   ¤   if (result != NERR_Success)
4f5b34 ¤   ¤   {
6dfef4 ¤   ¤   ¤   derr = DualErr(kPGDMinorError_NetWkstaGetInfoFailed,·
3b805d ¤   ¤   ¤   ¤   result);
--9c8e 000b495ead440110187 Page 16 of Win32Utils.cpp
b50fe4 ¤   ¤   }
e6af5a
64aa35 ¤   ¤   if (derr.IsntError())
3c5b34 ¤   ¤   {
18d20d ¤   ¤   ¤   (* compName) = W2A((LPWSTR) pWI100->wki100_computername);
191877 ¤   ¤   ¤   WinNT_NetApiBufferFree(pWI100);
3c0fe4 ¤   ¤   }
bf9371 ¤   }
7d3c88 ¤   catch (CMemoryException *ex)
39c7a1 ¤   {
ef6adc ¤   ¤   ex->Delete();
7eecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
6f9371 ¤   }
c1af5a
4033e3 ¤   return derr;
c8efe6 }
65af5a
11e79e // Win95GetUniversalName implements a hack under Windows95 that simulates
8411c8 // the non-working WNetGetUniversalName (from KB Article ID: Q131416).
67af5a
1a67fb static BOOL
60dc32 Win95GetUniversalName( LPCTSTR szDrive, LPTSTR szUniv ·) ··
c4bb36 {
f35707 ¤   // get the local drive letter
b7b1e5 ¤   char chLocal = toupper( szDrive[0] );
9daf5a
99456e ¤   // cursory validation
284702 ¤   if ( chLocal < 'A' || chLocal > 'Z' )
3098aa ¤   ¤   return FALSE;
a0af5a
39f6c5 ¤   if ( szDrive[1] != ':' || szDrive[2] != '\\' )
f698aa ¤   ¤   return FALSE;
bdaf5a
2eb355 ¤   HANDLE hEnum;
9b2795 ¤   DWORD dwResult = WNetOpenEnum( RESOURCE_CONNECTED, RESOURCETYPE_DISK,
cf5e1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·0, NULL, &hEnum );
93af5a
727ccc ¤   if ( dwResult != NO_ERROR )
1298aa ¤   ¤   return FALSE;
8faf5a
168d9a ¤   // request all available entries
f99a47 ¤   const int ···c_cEntries ··= 0xFFFFFFFF;
756228 ¤   // start with a reasonable buffer size
f071fc ¤   DWORD ·······cbBuffer ····= 50 * sizeof( NETRESOURCE );
83f61e ¤   NETRESOURCE *pNetResource = (NETRESOURCE*) malloc( cbBuffer );
8caf5a
f2d477 ¤   BOOL fResult = FALSE;
1faf5a
d472c9 ¤   while ( TRUE )
50c7a1 ¤   {
eb1bf0 ¤   ¤   DWORD dwSize ··= cbBuffer,
28f294 ¤   ¤   cEntries = c_cEntries;
91af5a
fadc79 ¤   ¤   dwResult = WNetEnumResource( hEnum, &cEntries, pNetResource,
6b0f69 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··&dwSize );
8faf5a
1bca57 ¤   ¤   if ( dwResult == ERROR_MORE_DATA )
695b34 ¤   ¤   {
5551e6 ¤   ¤   ¤   // the buffer was too small, enlarge
6829dc ¤   ¤   ¤   cbBuffer = dwSize;
b8dced ¤   ¤   ¤   pNetResource = (NETRESOURCE*) realloc(pNetResource, cbBuffer);
6517f5 ¤   ¤   ¤   continue;
870fe4 ¤   ¤   }
f6af5a
b2f730 ¤   ¤   if ( dwResult != NO_ERROR )
651dc4 ¤   ¤   ¤   goto done;
c8af5a
f8aa0b ¤   ¤   // search for the specified drive letter
70e4bf ¤   ¤   for ( int i = 0; i < (int) cEntries; i++ )
effd32 ¤   ¤   ¤   if ( pNetResource[i].lpLocalName &&
4f2235 ¤   ¤   ¤   ¤   chLocal == toupper(pNetResource[i].lpLocalName[0]) )
b4f776 ¤   ¤   ¤   {
--8521 000ec68f6ff40110187 Page 17 of Win32Utils.cpp
b29ef4 ¤   ¤   ¤   ¤   // match
1f25f2 ¤   ¤   ¤   ¤   fResult = TRUE;
5eaf5a
1c07df ¤   ¤   ¤   ¤   // build a UNC name
2c6d3b ¤   ¤   ¤   ¤   strcpy( szUniv, pNetResource[i].lpRemoteName );
12b040 ¤   ¤   ¤   ¤   strcat( szUniv, szDrive + 2 );
28864b ¤   ¤   ¤   ¤   _strupr( szUniv );
0cff25 ¤   ¤   ¤   ¤   goto done;
ffa3a6 ¤   ¤   ¤   }
ce0fe4 ¤   ¤   }
53af5a
37b38c done:
7dcd7e ¤   // cleanup
6b65dd ¤   WNetCloseEnum( hEnum );
3c7c91 ¤   free( pNetResource );
0daf5a
c08a84 ¤   return fResult;
9defe6 }
14af5a
f7af5a
1f20cb // TranslateDriveToUNC translates a mapped networked drive-based pathname to
839192 // its UNC form.
b3af5a
8d2292 DualErr·
2b6386 TranslateDriveToUNC(LPCSTR inPath, CString *outPath)
4fbb36 {
a9945d ¤   DualErr¤derr;
58af5a
1078f1 ¤   try
b4c7a1 ¤   {
ff2d98 ¤   ¤   PGPUInt32 result;
c0af5a
8ffa22 ¤   ¤   pgpAssertStrValid(inPath);
0782ad ¤   ¤   pgpAssertAddrValid(outPath, CString);
47af5a
434369 ¤   ¤   if (IsWin95CompatibleMachine() && !IsWin98CompatibleMachine())
815b34 ¤   ¤   {
073216 ¤   ¤   ¤   PGPBoolean resultWin95;
0839f9 ¤   ¤   ¤   char¤   ···tempOutPath[kMaxStringSize];
f3af5a
36566d ¤   ¤   ¤   // Special hack function for Windows95.
ffe8d7 ¤   ¤   ¤   resultWin95 = Win95GetUniversalName(inPath, tempOutPath);
e7af5a
51aba1 ¤   ¤   ¤   if (!resultWin95)
dff776 ¤   ¤   ¤   {
d4aab2 ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_WNetGetUniNameFailed,·
c93177 ¤   ¤   ¤   ¤   ¤   GetLastError());
dfa3a6 ¤   ¤   ¤   }
98bb8c ¤   ¤   ¤   else
4ff776 ¤   ¤   ¤   {
cb1c4c ¤   ¤   ¤   ¤   (* outPath) = tempOutPath;
f4a3a6 ¤   ¤   ¤   }
140fe4 ¤   ¤   }
570e1d ¤   ¤   else
475b34 ¤   ¤   {
b41011 ¤   ¤   ¤   UNIVERSAL_NAME_INFO¤*pUNI;
614580 ¤   ¤   ¤   unsigned long¤  ¤   bufSize;
c9af5a
9f6a93 ¤   ¤   ¤   // Handle normally for Win98 and WinNT.
521d71 ¤   ¤   ¤   bufSize = sizeof(UNIVERSAL_NAME_INFO) +·
3fdb25 ¤   ¤   ¤   ¤   kMaxStringSize * sizeof(WCHAR);
2daf5a
eff78f ¤   ¤   ¤   pUNI = (UNIVERSAL_NAME_INFO *) new PGPUInt8[bufSize];
34af5a
579d3d ¤   ¤   ¤   if (derr.IsntError())
c3f776 ¤   ¤   ¤   {
417ed1 ¤   ¤   ¤   ¤   result = WNetGetUniversalName(inPath,·
e95900 ¤   ¤   ¤   ¤   ¤   UNIVERSAL_NAME_INFO_LEVEL, pUNI, &bufSize);
c7af5a
16860a ¤   ¤   ¤   ¤   if (result != NO_ERROR)
b272c3 ¤   ¤   ¤   ¤   {
ece04c ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_WNetGetUniNameFailed,
--934a 0001011738340110187 Page 18 of Win32Utils.cpp
1e0f56 ¤   ¤   ¤   ¤   ¤   ¤   result);
e12613 ¤   ¤   ¤   ¤   }
3ea3a6 ¤   ¤   ¤   }
d0af5a
679d3d ¤   ¤   ¤   if (derr.IsntError())
a5f776 ¤   ¤   ¤   {
510b7c ¤   ¤   ¤   ¤   (* outPath) = pUNI->lpUniversalName;
cca3a6 ¤   ¤   ¤   }
5daf5a
a529ea ¤   ¤   ¤   delete[] (PGPUInt8 *) pUNI;
cf0fe4 ¤   ¤   }
419371 ¤   }
683c88 ¤   catch (CMemoryException *ex)
d9c7a1 ¤   {
3b6adc ¤   ¤   ex->Delete();
eeecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
909371 ¤   }
97af5a
9233e3 ¤   return derr;
dcefe6 }
48af5a
4374ea // TranslateUNCToLocal translates a 'looped-back' path to its local form.
64af5a
172292 DualErr·
863045 TranslateUNCToLocal(
a45bdf ¤   LPCSTR¤ ¤   inPath,·
d77bdf ¤   CString¤¤   *outPath,·
5312be ¤   PGPBoolean¤ *isLoopedBack)
cbbb36 {
8b945d ¤   DualErr¤derr;
16af5a
47765d ¤   pgpAssertStrValid(inPath);
e5bb68 ¤   pgpAssertAddrValid(outPath, CString);
84be3e ¤   pgpAssertAddrValid(isLoopedBack, PGPBoolean);
c1af5a
be3703 ¤   pgpAssert(IsWin95CompatibleMachine() || IsWinNT4CompatibleMachine());
69af5a
e778f1 ¤   try
25c7a1 ¤   {
e6213e ¤   ¤   CString newRoot, nonRoot, share;
5eaf5a
dd6860 ¤   ¤   derr = GetShare(inPath, &share);
d9af5a
59aa35 ¤   ¤   if (derr.IsntError())
ca5b34 ¤   ¤   {
a27894 ¤   ¤   ¤   derr = StripRoot(inPath, &nonRoot);
060fe4 ¤   ¤   }
34af5a
03aa35 ¤   ¤   if (derr.IsntError())
a05b34 ¤   ¤   {
fa6a07 ¤   ¤   ¤   if (IsWin95CompatibleMachine())
eff776 ¤   ¤   ¤   {
59baae ¤   ¤   ¤   ¤   PGPUInt32¤  ¤   bufSize, result;
d72636 ¤   ¤   ¤   ¤   share_info_50¤  *pSI50;
3ac427 ¤   ¤   ¤   ¤   unsigned short¤ cbTotalAvail;
5faf5a
49c54d ¤   ¤   ¤   ¤   bufSize = sizeof(share_info_50) + MAX_PATH + MAXCOMMENTSZ + 2;
eee5ce ¤   ¤   ¤   ¤   pSI50 = (share_info_50 *) new PGPUInt8[bufSize];
68af5a
6ec88e ¤   ¤   ¤   ¤   result = Win95_NetShareGetInfo(NULL, share, 50,·
bf9ea3 ¤   ¤   ¤   ¤   ¤   (char *) pSI50, bufSize, &cbTotalAvail);
7faf5a
eceabb ¤   ¤   ¤   ¤   if (result != NERR_Success)
bc72c3 ¤   ¤   ¤   ¤   {
8e59fc ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_NetShareGetInfoFailed,·
ec0f56 ¤   ¤   ¤   ¤   ¤   ¤   result);
532613 ¤   ¤   ¤   ¤   }
e7af5a
2a724e ¤   ¤   ¤   ¤   if (derr.IsntError())
eb72c3 ¤   ¤   ¤   ¤   {
621561 ¤   ¤   ¤   ¤   ¤   newRoot = pSI50->shi50_path;
102613 ¤   ¤   ¤   ¤   }
--4beb 0001633382c40110187 Page 19 of Win32Utils.cpp
e0af5a
658214 ¤   ¤   ¤   ¤   delete[] (PGPUInt8 *) pSI50;
67a3a6 ¤   ¤   ¤   }
c95eff ¤   ¤   ¤   else if (IsWinNT4CompatibleMachine())
3ef776 ¤   ¤   ¤   {
f4d237 ¤   ¤   ¤   ¤   PGPUInt32¤  ¤   result;
acfffd ¤   ¤   ¤   ¤   SHARE_INFO_2¤   *pSI2;
3caf5a
f100c3 ¤   ¤   ¤   ¤   USES_CONVERSION;
38af5a
883a95 ¤   ¤   ¤   ¤   result = WinNT_NetShareGetInfo(NULL, A2W(share), 2,·
01aada ¤   ¤   ¤   ¤   ¤   (LPBYTE *) &pSI2);
aaaf5a
fbeabb ¤   ¤   ¤   ¤   if (result != NERR_Success)
9d72c3 ¤   ¤   ¤   ¤   {
fe59fc ¤   ¤   ¤   ¤   ¤   derr = DualErr(kPGDMinorError_NetShareGetInfoFailed,·
9f0f56 ¤   ¤   ¤   ¤   ¤   ¤   result);
4d2613 ¤   ¤   ¤   ¤   }
57af5a
5d724e ¤   ¤   ¤   ¤   if (derr.IsntError())
e872c3 ¤   ¤   ¤   ¤   {
f87ead ¤   ¤   ¤   ¤   ¤   newRoot = W2A((LPWSTR) pSI2->shi2_path);
73ac98 ¤   ¤   ¤   ¤   ¤   WinNT_NetApiBufferFree(pSI2);
ee2613 ¤   ¤   ¤   ¤   }
43a3a6 ¤   ¤   ¤   }
150fe4 ¤   ¤   }
97af5a
b0aa35 ¤   ¤   if (derr.IsntError())
a45b34 ¤   ¤   {
600964 ¤   ¤   ¤   (* outPath) = newRoot + "\\" + nonRoot;
870fe4 ¤   ¤   }
7a9371 ¤   }
703c88 ¤   catch (CMemoryException *ex)
f8c7a1 ¤   {
226adc ¤   ¤   ex->Delete();
1eecf0 ¤   ¤   derr = DualErr(kPGDMinorError_OutOfMemory);
209371 ¤   }
bfaf5a
6c9b69 ¤   (* isLoopedBack) = derr.IsntError();
11af5a
df33e3 ¤   return derr;
5defe6 }
5eaf5a
69545f // CheckIfLoopedBack checks if the given networked path is looped back to a
f8d3a9 // local drive.
f2af5a
a32292 DualErr·
0ed614 CheckIfLoopedBack(
625bdf ¤   LPCSTR¤ ¤   inPath,·
137bdf ¤   CString¤¤   *outPath,·
7912be ¤   PGPBoolean¤ *isLoopedBack)
aabb36 {
3e7d36 ¤   DualErr derr;
6eaf5a
a3765d ¤   pgpAssertStrValid(inPath);
82bb68 ¤   pgpAssertAddrValid(outPath, CString);
4bbe3e ¤   pgpAssertAddrValid(isLoopedBack, PGPBoolean);
82af5a
6d03d4 ¤   if (!IsNetworkedPath(inPath))
53c7a1 ¤   {
507428 ¤   ¤   (* isLoopedBack) = FALSE;
c29371 ¤   }
1f33ad ¤   else if (IsUNCPath(inPath))
52c7a1 ¤   {
6228da ¤   ¤   derr = TranslateUNCToLocal(inPath, outPath, isLoopedBack);
7b9371 ¤   }
330e24 ¤   else
c9c7a1 ¤   {
8de692 ¤   ¤   CString uncPath, share;
a9af5a
3404d5 ¤   ¤   derr = TranslateDriveToUNC(inPath, &uncPath);
161b52 ¤   ¤
--5496 0014f4cfddb40110187 Page 20 of Win32Utils.cpp
08aa35 ¤   ¤   if (derr.IsntError())
e95b34 ¤   ¤   {
9f9b38 ¤   ¤   ¤   derr = TranslateUNCToLocal(uncPath, outPath, isLoopedBack);
340fe4 ¤   ¤   }
f69371 ¤   }
08af5a
0633e3 ¤   return derr;
4fefe6 }
--fd97 000abfd699440110188 Page 1 of Win32Utils.h
541bc3 //////////////////////////////////////////////////////////////////////////////
930681 // Win32Utils.h
44465d //
19698a // Declarations for Win32Utils.cpp.
c61bc3 //////////////////////////////////////////////////////////////////////////////
12af5a
5e8253 // $Id: Win32Utils.h,v 1.1.2.16.2.2 1998/10/22 00:41:55 nryan Exp $
acaf5a
c3cbce // Copyright (C) 1998 by Network Associates, Inc.
a671ae // All rights reserved.
2faf5a
1776eb #ifndef Included_Win32Utils_h¤  // [
b1dad0 #define Included_Win32Utils_h
c5af5a
3caf5a
af09b7 ////////////
70e738 // Constants
fd09b7 ////////////
72af5a
5b5a11 static LPCSTR¤  kPGPdiskNormalMsgBoxTitle¤  = "PGPdisk";
79d0ae static LPCSTR¤  kPGPdiskErrorMsgBoxTitle¤   = "PGPdisk Error";
e9af5a
d961af // From Lmcons.h.
7eaf5a
f6e4eb #define NERR_Success¤   0 ······/* Success */
a8af5a
4633e3 #define¤LM20_NNLEN¤ ¤   12¤ ¤   // LM 2.0 Net name length
9333ea #define¤MAXCOMMENTSZ¤   256¤¤   // Multipurpose comment length
2e6d1f #define¤SHPWLEN¤¤   ¤   8¤  ¤   // Share password length (bytes)
ecaf5a
02af5a
95d557 ////////
ea02c9 // Types
3cd557 ////////
86af5a
1e30bb // PGDMessageBoxStyle defines message box styles.
44af5a
9ca9d7 enum PGDMessageBoxStyle {kPMBS_Ok, kPMBS_OkCancel, kPMBS_YesNo,·
343b15 ¤   kPMBS_YesNoCancel};
9eaf5a
b7df9c // PGDMessageBoxFocus defines the initial focus on message box buttons.
b2af5a
074cb5 enum PGDMessageBoxFocus {kPMBF_YesButton, kPMBF_NoButton, kPMBF_OkButton,·
6d9ece ¤   kPMBF_CancelButton};
b3af5a
356d9c // UserResponse defines message box return values.
0baf5a
468903 enum UserResponse {kUR_OK, kUR_Cancel, kUR_Yes, kUR_No};
2daf5a
0272a2 // BareNameExtFlag is used by the GetBareName function.
61af5a
ed547d enum BareNameExtFlag {kBNE_Default, kBNE_HideExt, kBNE_ShowExt};
3faf5a
fc9764 // From Svrapi.h.
84af5a
ae4d1f struct share_info_50·
0ebb36 {
8b04ec ¤   char¤   ¤   ¤   shi50_netname[LM20_NNLEN+1];
e2d3cf ¤   unsigned char ¤ shi50_type;·
417461 ····unsigned short¤ shi50_flags;
33ec72 ¤   char FAR *¤ ¤   shi50_remark;
1b1b25 ¤   char FAR *¤ ¤   shi50_path;
d85663 ¤   char¤   ¤   ¤   shi50_rw_password[SHPWLEN+1];
51e477 ¤   char¤   ¤   ¤   shi50_ro_password[SHPWLEN+1];
12af5a
e882f7 };
ceaf5a
fbc39c // From Lmshare.h.
4aaf5a
4288cd typedef struct _SHARE_INFO_2·
fdbb36 {
abb234 ····LPTSTR ·shi2_netname;
--a126 000bce9246240110188 Page 2 of Win32Utils.h
0a0ab1 ····DWORD ··shi2_type;
06b3b0 ····LPTSTR ·shi2_remark;
b4fbe3 ····DWORD ··shi2_permissions;
2e1145 ····DWORD ··shi2_max_uses;
f76501 ····DWORD ··shi2_current_uses;
5ee4eb ····LPTSTR ·shi2_path;
622ae3 ····LPTSTR ·shi2_passwd;
0daf5a
efb1c1 } SHARE_INFO_2, *PSHARE_INFO_2, *LPSHARE_INFO_2;
77af5a
17af5a
65629b // From Lmwksta.h
23af5a
b2ff58 typedef struct _WKSTA_INFO_100
56bb36 {
3445a5 ····DWORD ··wki100_platform_id;
983a50 ····LPTSTR ·wki100_computername;
a27ba7 ····LPTSTR ·wki100_langroup;
7e5a4d ····DWORD ··wki100_ver_major;
3e5605 ····DWORD ··wki100_ver_minor;
93af5a
fed1ce } WKSTA_INFO_100, *PWKSTA_INFO_100, *LPWKSTA_INFO_100;
8faf5a
e9af5a
536cc2 /////////////////////
8a13d2 // Exported functions
d36cc2 /////////////////////
f5af5a
84f15b void¤   ¤   ¤   RegisterPGPdiskMsgBoxParent(CWnd *pWnd);
d7af5a
1ca176 UserResponse¤   PGPdiskMessageBox(LPCSTR message,·
25ad9f ¤   ¤   ¤   ¤   ¤   CWnd *pParent = NULL,·
1ff767 ¤   ¤   ¤   ¤   ¤   LPCSTR title = kPGPdiskNormalMsgBoxTitle,·
afed0e ¤   ¤   ¤   ¤   ¤   PGDMessageBoxStyle style = kPMBS_Ok,·
ab81e7 ¤   ¤   ¤   ¤   ¤   PGDMessageBoxFocus focus = kPMBF_YesButton);
caaf5a
9da858 UserResponse¤   ReportError(PGDMajorError perr,·
f7aac1 ¤   ¤   ¤   ¤   ¤   DualErr derr = DualErr::NoError,·
2a34fa ¤   ¤   ¤   ¤   ¤   PGPUInt8 drive = kInvalidDrive,·
feed0e ¤   ¤   ¤   ¤   ¤   PGDMessageBoxStyle style = kPMBS_Ok,·
5a81e7 ¤   ¤   ¤   ¤   ¤   PGDMessageBoxFocus focus = kPMBF_YesButton);
92af5a
700a03 UserResponse¤   DisplayMessage(PGPUInt32 stringId,·
d6ed0e ¤   ¤   ¤   ¤   ¤   PGDMessageBoxStyle style = kPMBS_Ok,·
7481e7 ¤   ¤   ¤   ¤   ¤   PGDMessageBoxFocus focus = kPMBF_YesButton);
0eaf5a
2e6a56 PGPInt32¤   ¤   FindMenuItemPosition(CMenu *pMenu, LPCSTR menuString);
51af5a
728066 DualErr¤¤   ¤   ConvertPathToLong(CString *path);
2731ef DualErr¤¤   ¤   GetRoot(LPCSTR path, CString *root);
7f6b98 DualErr¤¤   ¤   MakeRoot(PGPUInt8 drive, CString *root);
4f17a6 DualErr¤¤   ¤   StripRoot(LPCSTR path, CString *nonRoot);
cd8370 DualErr¤¤   ¤   GetServer(LPCSTR path, CString *server);
9fcab8 DualErr¤¤   ¤   GetShare(LPCSTR path, CString *share);
658717 DualErr¤¤   ¤   GetCurrentDirectory(CString *outDir);
95b702 DualErr¤¤   ¤   GetDirectory(LPCSTR path, CString *dir);
ced758 DualErr¤¤   ¤   GetDirectorySmart(LPCSTR path, CString *dir);
00a3e0 DualErr¤¤   ¤   GetBareName(LPCSTR path, CString *bareName,·
dc8e1d ¤   ¤   ¤   ¤   ¤   BareNameExtFlag bneFlag = kBNE_Default);
2caf5a
78418b DualErr¤¤   ¤   CanonicalizeVolumeName(LPCSTR inName, CString *outName);
8a16b3 DualErr¤¤   ¤   VerifyAndCanonicalizePath(LPCSTR inPath,·
343fbb ¤   ¤   ¤   ¤   ¤   CString *outPath);
e9f4a6 DualErr¤¤   ¤   ResolveShortcut(LPCSTR shortcutPath, CString *fullPath);
d4af5a
72201e DualErr¤¤   ¤   BroadcastDriveMessage(PGPUInt8 drive, WPARAM msg);
feaf5a
803bca DualErr¤¤   ¤   GetLocalComputerName(CString *compName);
6340e5 DualErr¤¤   ¤   TranslateDriveToUNC(LPCSTR inPath, CString *outPath);
9fe8b7 DualErr¤¤   ¤   TranslateUNCToLocal(LPCSTR inPath, CString *outPath,
8fd5df ¤   ¤   ¤   ¤   ¤   PGPBoolean *isLoopedBack);
bcaf5a
--c023 001014e19a240110188 Page 3 of Win32Utils.h
bc0b46 DualErr¤¤   ¤   CheckIfLoopedBack(LPCSTR inFilePath, CString *outFilePath,·
b1d5df ¤   ¤   ¤   ¤   ¤   PGPBoolean *isLoopedBack);
efaf5a
0151f6 #endif // Included_Win32Utils_h
--2c2a 000edb35b2540110189 Page 1 of WindowsVersion.cpp
541bc3 //////////////////////////////////////////////////////////////////////////////
9b99ae // WindowsVersion.cpp
1e465d //
78a362 // Functions for determining the currently running version of Windows.
3c1bc3 //////////////////////////////////////////////////////////////////////////////
1aaf5a
e3db88 // $Id: WindowsVersion.cpp,v 1.1.2.5.2.1 1998/08/21 05:57:01 nryan Exp $
4aaf5a
1bcbce // Copyright (C) 1998 by Network Associates, Inc.
e371ae // All rights reserved.
d0af5a
7e6931 #if defined(PGPDISK_MFC)
3baf5a
f29e12 #include "StdAfx.h"
b2af5a
52db21 #else
4f333e #error Define PGPDISK_MFC.
2705d6 #endif¤ // PGPDISK_MFC
a1af5a
5a9bcf #include "Required.h"
ccbfe9 #include "UtilityFunctions.h"
70dd74 #include "WindowsVersion.h"
82af5a
a5af5a
77d557 ////////
d002c9 // Types
e0d557 ////////
bfaf5a
428b37 // Enumerates the currently running version of Windows.
33af5a
f325b8 enum WindowsVersion {kWV_Win95OSR1, kWV_Win95OSR2, kWV_Win98OrFuture,·
347058 ¤   kWV_WinNT3, kWV_WinNT4NoSp, kWV_WinNT4Sp1, kWV_WinNT4Sp2, kWV_WinNT4Sp3,·
8b168e ¤   kWV_WinNT4PostSp3, kWV_WinNTPost4, kWV_WinUnknown, kWV_Uninitialized};
54af5a
ccaf5a
e009b7 ////////////
ed659a // Functions
8d09b7 ////////////
80af5a
eabb15 // GetWindowsVersion returns the currently running version of Windows.
bbaf5a
0bdcbf WindowsVersion·
6ca601 GetWindowsVersion()
56bb36 {
5de17f ¤   OSVERSIONINFO verInfo;
a5af5a
0bf337 ¤   verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
5daf5a
6bb9f4 ¤   if (!::GetVersionEx(&verInfo))
95b573 ¤   ¤   return kWV_WinUnknown;
7daf5a
6f0de6 ¤   switch (verInfo.dwPlatformId)
78c7a1 ¤   {
e8af5a
92266c ¤   case VER_PLATFORM_WIN32_WINDOWS:
88150f ¤   ¤   if (verInfo.dwMinorVersion == 0)
935b34 ¤   ¤   {
39a85d ¤   ¤   ¤   if (GetLowWord(verInfo.dwBuildNumber) > 1080)
14f776 ¤   ¤   ¤   {
3a8475 ¤   ¤   ¤   ¤   return kWV_Win95OSR2;
74a3a6 ¤   ¤   ¤   }
43bb8c ¤   ¤   ¤   else
e9f776 ¤   ¤   ¤   {
606b11 ¤   ¤   ¤   ¤   return kWV_Win95OSR1;
5ea3a6 ¤   ¤   ¤   }
460fe4 ¤   ¤   }
620e1d ¤   ¤   else
045b34 ¤   ¤   {
58c5a7 ¤   ¤   ¤   return kWV_Win98OrFuture;
610fe4 ¤   ¤   }
88af5a
ed6ed5 ¤   case VER_PLATFORM_WIN32_NT:
--ba5c 000e566700540110189 Page 2 of WindowsVersion.cpp
604518 ¤   ¤   if (verInfo.dwMajorVersion == 3)
df5b34 ¤   ¤   {
ac2e80 ¤   ¤   ¤   return kWV_WinNT3;
cc0fe4 ¤   ¤   }
80432c ¤   ¤   else if (verInfo.dwMajorVersion == 4)
c85b34 ¤   ¤   {
1a6a0b ¤   ¤   ¤   if (strlen(verInfo.szCSDVersion) == 0)
bff776 ¤   ¤   ¤   {
526397 ¤   ¤   ¤   ¤   return kWV_WinNT4NoSp;
13a3a6 ¤   ¤   ¤   }
18e842 ¤   ¤   ¤   else if (strcmp(verInfo.szCSDVersion, "Service Pack 1") == 0)
02f776 ¤   ¤   ¤   {
781a37 ¤   ¤   ¤   ¤   return kWV_WinNT4Sp1;
f3a3a6 ¤   ¤   ¤   }
d79c2b ¤   ¤   ¤   else if (strcmp(verInfo.szCSDVersion, "Service Pack 2") == 0)
c5f776 ¤   ¤   ¤   {
3bf553 ¤   ¤   ¤   ¤   return kWV_WinNT4Sp2;
97a3a6 ¤   ¤   ¤   }
70b00c ¤   ¤   ¤   else if (strcmp(verInfo.szCSDVersion, "Service Pack 3") == 0)
99f776 ¤   ¤   ¤   {
07af8f ¤   ¤   ¤   ¤   return kWV_WinNT4Sp3;
b2a3a6 ¤   ¤   ¤   }
82bb8c ¤   ¤   ¤   else
71f776 ¤   ¤   ¤   {
e5f4cd ¤   ¤   ¤   ¤   return kWV_WinNT4PostSp3;
46a3a6 ¤   ¤   ¤   }
940fe4 ¤   ¤   }
220e1d ¤   ¤   else
575b34 ¤   ¤   {
7616c9 ¤   ¤   ¤   return kWV_WinNTPost4;
c90fe4 ¤   ¤   }
97af5a
8d2f72 ¤   default:
63b573 ¤   ¤   return kWV_WinUnknown;
5b9371 ¤   }
0befe6 }
e5af5a
b021de // IsWin95CompatibleMachine returns TRUE if the user is running a Win95
68d0c1 // compatible machine.
41af5a
7e77be PGPBoolean·
dbf926 IsWin95CompatibleMachine()
4ebb36 {
dcf0e0 ¤   switch (GetWindowsVersion())
6ac7a1 ¤   {
350476 ¤   ¤   case kWV_Win95OSR1:
5eeb12 ¤   ¤   case kWV_Win95OSR2:
0765f5 ¤   ¤   case kWV_Win98OrFuture:
f232bd ¤   ¤   ¤   return TRUE;
c7af5a
a79ae3 ¤   ¤   default:
fd5f1f ¤   ¤   ¤   return FALSE;
729371 ¤   }
a0efe6 }
05af5a
44da4b // IsWin95OSR2CompatibleMachine returns TRUE if the user is running a Win95
4ef96c // OSR2 compatible machine.
daaf5a
5c77be PGPBoolean·
4e1171 IsWin95OSR2CompatibleMachine()
22bb36 {
19f0e0 ¤   switch (GetWindowsVersion())
4ec7a1 ¤   {
7beb12 ¤   ¤   case kWV_Win95OSR2:
cd65f5 ¤   ¤   case kWV_Win98OrFuture:
6a32bd ¤   ¤   ¤   return TRUE;
b5af5a
159ae3 ¤   ¤   default:
d25f1f ¤   ¤   ¤   return FALSE;
159371 ¤   }
b3efe6 }
e5af5a
--b951 001b1dd6f6e40110189 Page 3 of WindowsVersion.cpp
8dc15e // IsWin98CompatibleMachine returns TRUE if the user is running a Win98
6bd0c1 // compatible machine.
d0af5a
7377be PGPBoolean·
f1a08b IsWin98CompatibleMachine()
79bb36 {
13f0e0 ¤   switch (GetWindowsVersion())
84c7a1 ¤   {
b165f5 ¤   ¤   case kWV_Win98OrFuture:
f032bd ¤   ¤   ¤   return TRUE;
faaf5a
749ae3 ¤   ¤   default:
cc5f1f ¤   ¤   ¤   return FALSE;
7f9371 ¤   }
22efe6 }
f7af5a
2ae414 // IsWinNT4CompatibleMachine returns TRUE if the user is running a version of
217fe8 // Windows NT greater than version 3.
56af5a
f777be PGPBoolean·
841251 IsWinNT4CompatibleMachine()
eebb36 {
caf0e0 ¤   switch (GetWindowsVersion())
d2c7a1 ¤   {
6d3745 ¤   ¤   case kWV_WinNT4NoSp:
897550 ¤   ¤   case kWV_WinNT4Sp1:
e79a34 ¤   ¤   case kWV_WinNT4Sp2:
37c0e8 ¤   ¤   case kWV_WinNT4Sp3:
dd6871 ¤   ¤   case kWV_WinNT4PostSp3:
d303e8 ¤   ¤   case kWV_WinNTPost4:
9c32bd ¤   ¤   ¤   return TRUE;
deaf5a
239ae3 ¤   ¤   default:
285f1f ¤   ¤   ¤   return FALSE;
c19371 ¤   }
43efe6 }
34af5a
d2dc09 // IsWinNT5CompatibleMachine returns TRUE if the user is running a version of
b3f3ed // Windows NT greater than version 4.
32af5a
ac77be PGPBoolean·
b3253d IsWinNT5CompatibleMachine()
22bb36 {
30f0e0 ¤   switch (GetWindowsVersion())
aac7a1 ¤   {
3203e8 ¤   ¤   case kWV_WinNTPost4:
6632bd ¤   ¤   ¤   return TRUE;
65af5a
079ae3 ¤   ¤   default:
145f1f ¤   ¤   ¤   return FALSE;
509371 ¤   }
b1efe6 }
--3904 0010025da3b4011018a Page 1 of WindowsVersion.h
541bc3 //////////////////////////////////////////////////////////////////////////////
b21398 // WindowsVersion.h
44465d //
c70807 // Small inline utility functions to help with determing the Windows version.
db1bc3 //////////////////////////////////////////////////////////////////////////////
3eaf5a
1b56db // $Id: WindowsVersion.h,v 1.1.2.8.2.1 1998/08/21 05:57:01 nryan Exp $
d4af5a
aecbce // Copyright (C) 1998 by Network Associates, Inc.
b071ae // All rights reserved.
a0af5a
db0632 #ifndef Included_WindowsVersion_h¤  // [
afa404 #define Included_WindowsVersion_h
4faf5a
17af5a
af6cc2 /////////////////////
4bbf67 // Exported Functions
326cc2 /////////////////////
69af5a
9b29da PGPBoolean¤ IsWin95CompatibleMachine();
4c83de PGPBoolean¤ IsWin95OSR2CompatibleMachine();
72576c PGPBoolean¤ IsWin98CompatibleMachine();
d1066f PGPBoolean¤ IsWinNT4CompatibleMachine();
b7af32 PGPBoolean¤ IsWinNT5CompatibleMachine();
d1af5a
008421 #endif¤ // ] Included_WindowsVersion_h
--66a2 00074fe39814011018b Page 1 of jpeglib.dsp
7a8aa8 # Microsoft Developer Studio Project File - Name="jpeglib" - Package Owner=<4>
b7e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
258537 # ** DO NOT EDIT **
b2af5a
1c877a # TARGTYPE "Win32 (x86) Static Library" 0x0104
34af5a
3a26e2 CFG=jpeglib - Win32 Debug
04894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
bb5c35 !MESSAGE use the Export Makefile command and run
e16309 !MESSAGE·
d87c55 !MESSAGE NMAKE /f "jpeglib.mak".
066309 !MESSAGE·
abcdb3 !MESSAGE You can specify a configuration when running NMAKE
f3e013 !MESSAGE by defining the macro CFG on the command line. For example:
506309 !MESSAGE·
655414 !MESSAGE NMAKE /f "jpeglib.mak" CFG="jpeglib - Win32 Debug"
ca6309 !MESSAGE·
161dd7 !MESSAGE Possible choices for configuration are:
726309 !MESSAGE·
f9ca2a !MESSAGE "jpeglib - Win32 Release" (based on "Win32 (x86) Static Library")
08272a !MESSAGE "jpeglib - Win32 Debug" (based on "Win32 (x86) Static Library")
a76309 !MESSAGE·
19af5a
3b3e63 # Begin Project
88b23f # PROP Scc_ProjName ""
47df4a # PROP Scc_LocalPath ""
9740a4 CPP=cl.exe
13af5a
2a6fd7 !IF ·"$(CFG)" == "jpeglib - Win32 Release"
13af5a
848243 # PROP BASE Use_MFC 0
a4e662 # PROP BASE Use_Debug_Libraries 0
6d7d73 # PROP BASE Output_Dir "Release"
6b6180 # PROP BASE Intermediate_Dir "Release"
d94c81 # PROP BASE Target_Dir ""
b721ad # PROP Use_MFC 0
77b771 # PROP Use_Debug_Libraries 0
50f310 # PROP Output_Dir "Release"
8701a1 # PROP Intermediate_Dir "Release"
8fb6fa # PROP Target_Dir ""
f04fa4 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD¶
319f26 ·/c
6ea15e # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PGP_¶
efe94e WIN32" /YX /FD /c
7618fc BSC32=bscmake.exe
ec7a24 # ADD BASE BSC32 /nologo
154f1b # ADD BSC32 /nologo
8c7a92 LIB32=link.exe -lib
b3629d # ADD BASE LIB32 /nologo
6257a2 # ADD LIB32 /nologo
3caf5a
1caccd !ELSEIF ·"$(CFG)" == "jpeglib - Win32 Debug"
ceaf5a
e58243 # PROP BASE Use_MFC 0
d6ffba # PROP BASE Use_Debug_Libraries 1
5254b8 # PROP BASE Output_Dir "Debug"
c2198a # PROP BASE Intermediate_Dir "Debug"
c04c81 # PROP BASE Target_Dir ""
3521ad # PROP Use_MFC 0
c2aea9 # PROP Use_Debug_Libraries 1
93ad22 # PROP Output_Dir "Debug"
a6b954 # PROP Intermediate_Dir "Debug"
60b6fa # PROP Target_Dir ""
657248 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX¶
5d10c2 ·/FD /c
707d81 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D ¶
f79803 "PGP_WIN32" /YX /FD /c
c8d3db # SUBTRACT CPP /X
cb18fc BSC32=bscmake.exe
347a24 # ADD BASE BSC32 /nologo
284f1b # ADD BSC32 /nologo
747a92 LIB32=link.exe -lib
--ecde 000c3ca529c4011018b Page 2 of jpeglib.dsp
86629d # ADD BASE LIB32 /nologo
2757a2 # ADD LIB32 /nologo
edaf5a
8930ec !ENDIF·
69af5a
c9b8a5 # Begin Target
d1af5a
981c06 # Name "jpeglib - Win32 Release"
6810d8 # Name "jpeglib - Win32 Debug"
0b1d6b # Begin Group "Source"
cfaf5a
e14be2 # PROP Default_Filter "*.c"
cddf4f # Begin Source File
91af5a
29087a SOURCE=..\common\jcapimin.c
b06ccd # End Source File
a1df4f # Begin Source File
abaf5a
8967f2 SOURCE=..\common\jcapistd.c
d06ccd # End Source File
78df4f # Begin Source File
21af5a
9bb652 SOURCE=..\common\jccoefct.c
a56ccd # End Source File
62df4f # Begin Source File
d7af5a
a592c4 SOURCE=..\common\jccolor.c
296ccd # End Source File
5adf4f # Begin Source File
e3af5a
970561 SOURCE=..\common\jcdctmgr.c
fa6ccd # End Source File
68df4f # Begin Source File
31af5a
effb92 SOURCE=..\common\jchuff.c
786ccd # End Source File
9edf4f # Begin Source File
efaf5a
cf9bf9 SOURCE=..\common\jcinit.c
a96ccd # End Source File
bcdf4f # Begin Source File
38af5a
a5cd48 SOURCE=..\common\jcmainct.c
026ccd # End Source File
92df4f # Begin Source File
70af5a
8a6a86 SOURCE=..\common\jcmarker.c
bf6ccd # End Source File
4bdf4f # Begin Source File
2daf5a
6f8a6a SOURCE=..\common\jcmaster.c
516ccd # End Source File
9adf4f # Begin Source File
99af5a
1976ca SOURCE=..\common\jcomapi.c
b26ccd # End Source File
fedf4f # Begin Source File
67af5a
ccaebf SOURCE=..\common\jcparam.c
5d6ccd # End Source File
69df4f # Begin Source File
40af5a
eb039e SOURCE=..\common\jcphuff.c
ba6ccd # End Source File
cbdf4f # Begin Source File
43af5a
02242e SOURCE=..\common\jcprepct.c
c06ccd # End Source File
7bdf4f # Begin Source File
94af5a
c9488b SOURCE=..\common\jcsample.c
c36ccd # End Source File
--7618 0005b2b2a214011018b Page 3 of jpeglib.dsp
41df4f # Begin Source File
d0af5a
acec14 SOURCE=..\common\jctrans.c
8b6ccd # End Source File
2edf4f # Begin Source File
99af5a
38cc8f SOURCE=..\common\jdapimin.c
a66ccd # End Source File
5bdf4f # Begin Source File
8baf5a
b0a307 SOURCE=..\common\jdapistd.c
1b6ccd # End Source File
c7df4f # Begin Source File
70af5a
d6c629 SOURCE=..\common\jdatadst.c
a76ccd # End Source File
22df4f # Begin Source File
92af5a
57078c SOURCE=..\common\jdatasrc.c
e16ccd # End Source File
1ddf4f # Begin Source File
6faf5a
4f72a7 SOURCE=..\common\jdcoefct.c
846ccd # End Source File
7ddf4f # Begin Source File
6caf5a
7d7b26 SOURCE=..\common\jdcolor.c
de6ccd # End Source File
0ddf4f # Begin Source File
e9af5a
6ac194 SOURCE=..\common\jddctmgr.c
406ccd # End Source File
75df4f # Begin Source File
49af5a
d8679c SOURCE=..\common\jdhuff.c
bc6ccd # End Source File
07df4f # Begin Source File
8faf5a
c70216 SOURCE=..\common\jdinput.c
b56ccd # End Source File
5adf4f # Begin Source File
06af5a
c409bd SOURCE=..\common\jdmainct.c
246ccd # End Source File
27df4f # Begin Source File
84af5a
7eae73 SOURCE=..\common\jdmarker.c
a76ccd # End Source File
6bdf4f # Begin Source File
37af5a
2b4e9f SOURCE=..\common\jdmaster.c
5b6ccd # End Source File
4bdf4f # Begin Source File
7faf5a
f217ce SOURCE=..\common\jdmerge.c
1d6ccd # End Source File
b0df4f # Begin Source File
d6af5a
04ea7c SOURCE=..\common\jdphuff.c
a26ccd # End Source File
94df4f # Begin Source File
47af5a
97fcd6 SOURCE=..\common\jdpostct.c
146ccd # End Source File
d8df4f # Begin Source File
53af5a
7d8c7e SOURCE=..\common\jdsample.c
a46ccd # End Source File
6ddf4f # Begin Source File
09af5a
c405f6 SOURCE=..\common\jdtrans.c
5b6ccd # End Source File
--5729 001e112b6724011018b Page 4 of jpeglib.dsp
41df4f # Begin Source File
d0af5a
ce4645 SOURCE=..\common\jerror.c
296ccd # End Source File
89df4f # Begin Source File
02af5a
e4b889 SOURCE=..\common\jfdctflt.c
036ccd # End Source File
44df4f # Begin Source File
ddaf5a
bc6635 SOURCE=..\common\jfdctfst.c
946ccd # End Source File
2edf4f # Begin Source File
b3af5a
d09388 SOURCE=..\common\jfdctint.c
9d6ccd # End Source File
a5df4f # Begin Source File
2aaf5a
961555 SOURCE=..\common\jidctflt.c
cd6ccd # End Source File
36df4f # Begin Source File
59af5a
1fcbe9 SOURCE=..\common\jidctfst.c
476ccd # End Source File
efdf4f # Begin Source File
98af5a
0a3e54 SOURCE=..\common\jidctint.c
586ccd # End Source File
1ddf4f # Begin Source File
4faf5a
6dd58c SOURCE=..\common\jidctred.c
606ccd # End Source File
79df4f # Begin Source File
0daf5a
c73d10 SOURCE=..\common\jmemmgr.c
246ccd # End Source File
c3df4f # Begin Source File
5eaf5a
50974d SOURCE=..\common\jmemnobs.c
376ccd # End Source File
5ddf4f # Begin Source File
dfaf5a
abfec2 SOURCE=..\common\jquant1.c
386ccd # End Source File
b0df4f # Begin Source File
39af5a
d3db0f SOURCE=..\common\jquant2.c
316ccd # End Source File
43df4f # Begin Source File
f0af5a
0c2b12 SOURCE=..\common\jutils.c
3f6ccd # End Source File
7d3f5a # End Group
d8e5cf # End Target
e1f262 # End Project
--ffa6 0013f2cb1e14011018c Page 1 of jpeglib.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
d6707e Project: "jpeglib"=.\jpeglib.dsp - Package Owner=<4>
d6af5a
e8e41b Package=<5>
058818 {{{
f1418b }}}
30af5a
32bec7 Package=<4>
358818 {{{
09418b }}}
6faf5a
f92d94 ###############################################################################
d5af5a
a220da Global:
17af5a
d3e41b Package=<5>
4a8818 {{{
69418b }}}
b8af5a
ce32c2 Package=<3>
aa8818 {{{
3d418b }}}
5baf5a
992d94 ###############################################################################
3faf5a
--28de 000af3758994011018d Page 1 of EudoraPlugin.dsp
367640 # Microsoft Developer Studio Project File - Name="EudoraPlugin" - Package Owner¶
291544 =<4>
7ee7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
af8537 # ** DO NOT EDIT **
90af5a
c9a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
15af5a
893728 CFG=EudoraPlugin - Win32 Release
50894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
ce5c35 !MESSAGE use the Export Makefile command and run
b36309 !MESSAGE·
274237 !MESSAGE NMAKE /f "EudoraPlugin.mak".
b36309 !MESSAGE·
d9cdb3 !MESSAGE You can specify a configuration when running NMAKE
c9e013 !MESSAGE by defining the macro CFG on the command line. For example:
9b6309 !MESSAGE·
9a0d1d !MESSAGE NMAKE /f "EudoraPlugin.mak" CFG="EudoraPlugin - Win32 Release"
a56309 !MESSAGE·
291dd7 !MESSAGE Possible choices for configuration are:
486309 !MESSAGE·
f30647 !MESSAGE "EudoraPlugin - Win32 Release" (based on\
9417ca ·"Win32 (x86) Dynamic-Link Library")
29bd39 !MESSAGE "EudoraPlugin - Win32 Debug" (based on\
5617ca ·"Win32 (x86) Dynamic-Link Library")
a36309 !MESSAGE·
f0af5a
473e63 # Begin Project
ecb23f # PROP Scc_ProjName ""
65df4a # PROP Scc_LocalPath ""
1f40a4 CPP=cl.exe
69a46a MTL=midl.exe
ed2e1f RSC=rc.exe
72af5a
9e8a43 !IF ·"$(CFG)" == "EudoraPlugin - Win32 Release"
f9af5a
878243 # PROP BASE Use_MFC 0
efe662 # PROP BASE Use_Debug_Libraries 0
e04681 # PROP BASE Output_Dir ".\Release"
bcca0c # PROP BASE Intermediate_Dir ".\Release"
264c81 # PROP BASE Target_Dir ""
d421ad # PROP Use_MFC 0
62b771 # PROP Use_Debug_Libraries 0
4d106d # PROP Output_Dir ".\EudoraPlugin\Release"
fec302 # PROP Intermediate_Dir ".\EudoraPlugin\Release"
429ad5 # PROP Ignore_Export_Lib 0
12b6fa # PROP Target_Dir ""
00c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
d09f26 ·/c
114ac1 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\shared" /I "include" /I "shared" /I¶
79e193 ·"..\shared" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win¶
aaf503 32" /I "..\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\win32" /I "..\..\..\lib¶
7d5c60 s\pfl\common\prefs" /I "..\..\..\libs\pfl\common\file" /D UNFINISHED_CODE_ALLOW¶
f1b8d9 ED=0 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Yu"win¶
e6b247 dows.h" /FD /c
92592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
eaa23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
00b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
22de84 # ADD RSC /l 0x409 /d "NDEBUG"
b418fc BSC32=bscmake.exe
b57a24 # ADD BASE BSC32 /nologo
244f1b # ADD BSC32 /nologo
dd268f LINK32=link.exe
84cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
f2a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
8a5e3b ·/nologo /subsystem:windows /dll /machine:I386
5cdebb # ADD LINK32 ..\..\..\libs\pfl\win32\pflCommon\Release\pflCommon.lib ..\..\..\l¶
f3f51e ibs\pgpcdk\win32\pgpsdknetworklib\release\pgpsdknl.lib pgpcl\release\pgp60cl.li¶
6b53de b pgpsc\release\pgp60sc.lib comctl32.lib kernel32.lib user32.lib gdi32.lib wins¶
2243ea pool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ¶
23f7ea odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /nodefaul¶
ed0303 tlib:"LIBC" /out:".\EudoraPlugin\Release\pgpEudoraPlugin.dll"
af84a1 # SUBTRACT LINK32 /pdb:none
--d105 000a51dc9d14011018d Page 2 of EudoraPlugin.dsp
e0af5a
d51461 !ELSEIF ·"$(CFG)" == "EudoraPlugin - Win32 Debug"
5faf5a
7b8243 # PROP BASE Use_MFC 0
92ffba # PROP BASE Use_Debug_Libraries 1
40cc98 # PROP BASE Output_Dir ".\Debug"
ecd06b # PROP BASE Intermediate_Dir ".\Debug"
924c81 # PROP BASE Target_Dir ""
3921ad # PROP Use_MFC 0
bfaea9 # PROP Use_Debug_Libraries 1
328463 # PROP Output_Dir ".\EudoraPlugin\Debug"
a86d6f # PROP Intermediate_Dir ".\EudoraPlugin\Debug"
2b9ad5 # PROP Ignore_Export_Lib 0
8ab6fa # PROP Target_Dir ""
0f6cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
ad8dcb DOWS" /YX /c
c40737 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\shared" /I "include" /I "shar¶
29edb4 ed" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win32" /I ".¶
d174f9 .\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pfl\com¶
246152 mon\prefs" /I "..\..\..\libs\pfl\common\file" /D "_DEBUG" /D UNFINISHED_CODE_AL¶
af28b6 LOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D "WIN32" /D "_WINDOWS" /Yu"windows.h" /¶
3ad0d1 FD /c
336c5d # SUBTRACT CPP /Fr
69b3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
afed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
78699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
b90443 # ADD RSC /l 0x409 /d "_DEBUG"
7a18fc BSC32=bscmake.exe
9a7a24 # ADD BASE BSC32 /nologo
004f1b # ADD BSC32 /nologo
65268f LINK32=link.exe
efcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
c5a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
31c590 ·/nologo /subsystem:windows /dll /debug /machine:I386
f3debf # ADD LINK32 ..\..\..\libs\pfl\win32\pflCommon\Debug\pflCommon.lib ..\..\..\lib¶
2b9901 s\pgpcdk\win32\pgpsdknetworklib\debug\pgpsdknl.lib pgpcl\debug\pgp60cl.lib pgps¶
d120dc c\debug\pgp60sc.lib comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib¶
51e619 ·comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.l¶
4180dc ib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Eu¶
573d33 doraPlugin\Debug\pgpEudoraPlugin.dll"
c484a1 # SUBTRACT LINK32 /pdb:none
d3af5a
b830ec !ENDIF·
17af5a
2ab8a5 # Begin Target
4baf5a
1301b8 # Name "EudoraPlugin - Win32 Release"
7a70dd # Name "EudoraPlugin - Win32 Debug"
b54cc4 # Begin Group "Source Files"
4baf5a
137b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
01df4f # Begin Source File
0caf5a
4b2697 SOURCE=.\shared\AddKey.c
3f6ccd # End Source File
d1df4f # Begin Source File
95af5a
751da7 SOURCE=.\shared\BlockUtils.c
bb6ccd # End Source File
41df4f # Begin Source File
1faf5a
6d4331 SOURCE=.\EudoraPlugin\CBTProc.c
b66ccd # End Source File
77df4f # Begin Source File
d9af5a
b964f0 SOURCE=.\EudoraPlugin\CreateToolbar.c
a46ccd # End Source File
26df4f # Begin Source File
76af5a
032772 SOURCE=.\shared\DecryptVerify.c
186ccd # End Source File
a5df4f # Begin Source File
--f056 000548b2bdf4011018d Page 3 of EudoraPlugin.dsp
e0af5a
800900 SOURCE=.\EudoraPlugin\DisplayMessage.c
b16ccd # End Source File
a1df4f # Begin Source File
56af5a
bdce65 SOURCE=.\shared\EncryptSign.c
e96ccd # End Source File
74df4f # Begin Source File
dbaf5a
1fd877 SOURCE=.\EudoraPlugin\EudoraMailHeaders.c
076ccd # End Source File
c8df4f # Begin Source File
51af5a
dcdebf SOURCE=.\EudoraPlugin\EudoraMainWndProc.c
e26ccd # End Source File
48df4f # Begin Source File
02af5a
389cce SOURCE=.\EudoraPlugin\EudoraReadMailWndProc.c
a56ccd # End Source File
c5df4f # Begin Source File
1aaf5a
3786ae SOURCE=.\EudoraPlugin\EudoraSendMailWndProc.c
dc6ccd # End Source File
b7df4f # Begin Source File
1baf5a
38971d SOURCE=.\EudoraPlugin\MapFile.c
ec6ccd # End Source File
72df4f # Begin Source File
eaaf5a
f601b0 SOURCE=.\EudoraPlugin\emssdk\MIMETYPE.CPP
93ae01 # SUBTRACT CPP /YX /Yc /Yu
3e6ccd # End Source File
15df4f # Begin Source File
d3af5a
6a02dc SOURCE=.\EudoraPlugin\MyMIMEUtils.c
126ccd # End Source File
c1df4f # Begin Source File
56af5a
9870da SOURCE=.\EudoraPlugin\PGPPlug.c
13c7e9 # ADD CPP /Yc"windows.h"
ff6ccd # End Source File
dcdf4f # Begin Source File
8daf5a
a177e3 SOURCE=.\EudoraPlugin\PGPplugin.def
8e6ccd # End Source File
5fdf4f # Begin Source File
38af5a
cceac8 SOURCE=.\EudoraPlugin\PGPplugin.rc
2b4d1f # ADD BASE RSC /l 0x409 /i "EudoraPlugin"
ed5a57 # ADD RSC /l 0x409 /i "EudoraPlugin" /i ".\EudoraPlugin"
406ccd # End Source File
8cdf4f # Begin Source File
38af5a
07d839 SOURCE=..\shared\pgpVersionHeader.c
d2ae01 # SUBTRACT CPP /YX /Yc /Yu
fb6ccd # End Source File
d2df4f # Begin Source File
5baf5a
710d54 SOURCE=.\shared\Prefs.c
206ccd # End Source File
a1df4f # Begin Source File
4daf5a
01b323 SOURCE=.\EudoraPlugin\ReadMailToolbarWndProc.c
c06ccd # End Source File
8bdf4f # Begin Source File
49af5a
a16a71 SOURCE=.\EudoraPlugin\emssdk\RFC822.CPP
c6ae01 # SUBTRACT CPP /YX /Yc /Yu
f76ccd # End Source File
88df4f # Begin Source File
12af5a
54794d SOURCE=.\shared\RichEdit_IO.c
--e1ed 000b66973c84011018d Page 4 of EudoraPlugin.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
2e7c18 SOURCE=.\EudoraPlugin\SendMailToolbarWndProc.c
cc6ccd # End Source File
cadf4f # Begin Source File
e1af5a
df62e2 SOURCE=.\shared\SigEvent.c
e66ccd # End Source File
47df4f # Begin Source File
9faf5a
74fda8 SOURCE=.\EudoraPlugin\strstri.c
daae01 # SUBTRACT CPP /YX /Yc /Yu
de6ccd # End Source File
76df4f # Begin Source File
36af5a
d09e4f SOURCE=.\EudoraPlugin\transbmp.c
946ccd # End Source File
03df4f # Begin Source File
3caf5a
560c1d SOURCE=.\EudoraPlugin\Translators.c
1b6ccd # End Source File
52df4f # Begin Source File
14af5a
e0e2be SOURCE=.\EudoraPlugin\TranslatorUtils.c
ba6ccd # End Source File
1cdf4f # Begin Source File
ebaf5a
a73d38 SOURCE=.\shared\VerificationBlock.c
7a6ccd # End Source File
f5df4f # Begin Source File
44af5a
4ae8b5 SOURCE=.\shared\Working.c
726ccd # End Source File
d73f5a # End Group
978925 # Begin Group "Resource Files"
c4af5a
94a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
74df4f # Begin Source File
35af5a
214d76 SOURCE=.\EudoraPlugin\Res\lock.ico
a56ccd # End Source File
7adf4f # Begin Source File
faaf5a
085581 SOURCE=.\EudoraPlugin\Res\lock1.ico
dd6ccd # End Source File
54df4f # Begin Source File
6daf5a
b700c1 SOURCE=.\EudoraPlugin\Res\pgp50.ico
236ccd # End Source File
3fdf4f # Begin Source File
35af5a
b99907 SOURCE=.\EudoraPlugin\Res\readtool.bmp
ba6ccd # End Source File
19df4f # Begin Source File
d7af5a
0980e6 SOURCE=.\EudoraPlugin\Res\sendtool.bmp
c86ccd # End Source File
b9df4f # Begin Source File
9baf5a
b8428a SOURCE=.\EudoraPlugin\Res\sign.ico
816ccd # End Source File
32df4f # Begin Source File
1aaf5a
63ae5b SOURCE=.\EudoraPlugin\Res\verify.ico
c56ccd # End Source File
643f5a # End Group
856775 # Begin Group "Project Header Files"
fcaf5a
196783 # PROP Default_Filter "h;hpp"
0fdf4f # Begin Source File
b6af5a
--f497 000be9c61ba4011018d Page 5 of EudoraPlugin.dsp
31f90f SOURCE=.\shared\BlockUtils.h
616ccd # End Source File
d5df4f # Begin Source File
6baf5a
efa799 SOURCE=.\EudoraPlugin\CBTProc.h
ec6ccd # End Source File
38df4f # Begin Source File
faaf5a
8c8058 SOURCE=.\EudoraPlugin\CreateToolbar.h
1f6ccd # End Source File
51df4f # Begin Source File
6faf5a
fdeda8 SOURCE=.\EudoraPlugin\DisplayMessage.h
8f6ccd # End Source File
f5df4f # Begin Source File
35af5a
25f685 SOURCE=".\EudoraPlugin\emssdk\ems-win.h"
456ccd # End Source File
78df4f # Begin Source File
bcaf5a
6f7fe4 SOURCE=.\EudoraPlugin\emssdk\ENCODING.H
666ccd # End Source File
9bdf4f # Begin Source File
c2af5a
f9941b SOURCE=.\EudoraPlugin\EncryptSign.h
3d6ccd # End Source File
0ddf4f # Begin Source File
45af5a
d03cdf SOURCE=.\EudoraPlugin\EudoraMailHeaders.h
336ccd # End Source File
8fdf4f # Begin Source File
a0af5a
8c3a17 SOURCE=.\EudoraPlugin\EudoraMainWndProc.h
316ccd # End Source File
62df4f # Begin Source File
4aaf5a
c97866 SOURCE=.\EudoraPlugin\EudoraReadMailWndProc.h
866ccd # End Source File
76df4f # Begin Source File
edaf5a
f56206 SOURCE=.\EudoraPlugin\EudoraSendMailWndProc.h
366ccd # End Source File
d7df4f # Begin Source File
30af5a
4a73b5 SOURCE=.\EudoraPlugin\MapFile.h
d36ccd # End Source File
87df4f # Begin Source File
5daf5a
a2e14a SOURCE=.\EudoraPlugin\emssdk\MIMETYPE.H
316ccd # End Source File
17df4f # Begin Source File
50af5a
d6e674 SOURCE=.\EudoraPlugin\MyMIMEUtils.h
286ccd # End Source File
26df4f # Begin Source File
ecaf5a
c11890 SOURCE=.\EudoraPlugin\PGPDefinedMessages.h
2a6ccd # End Source File
6bdf4f # Begin Source File
bcaf5a
0428c9 SOURCE=.\INCLUDE\PGPkm.h
dd6ccd # End Source File
01df4f # Begin Source File
bbaf5a
ee40e6 SOURCE=.\include\pgpphras.h
3a6ccd # End Source File
dcdf4f # Begin Source File
4caf5a
da1861 SOURCE=.\EudoraPlugin\PGPPlugTypes.h
c56ccd # End Source File
97df4f # Begin Source File
beaf5a
--729a 00038072d724011018d Page 6 of EudoraPlugin.dsp
ae5346 SOURCE=.\include\PGPRecip.h
8b6ccd # End Source File
d0df4f # Begin Source File
7faf5a
df16e8 SOURCE=.\include\pgpversion.h
986ccd # End Source File
68df4f # Begin Source File
a8af5a
2862c4 SOURCE=.\INCLUDE\pgpWerr.h
6b6ccd # End Source File
afdf4f # Begin Source File
7aaf5a
83578b SOURCE=.\EudoraPlugin\ReadMailToolbarWndProc.h
fc6ccd # End Source File
fbdf4f # Begin Source File
afaf5a
e819f9 SOURCE=.\EudoraPlugin\emssdk\RFC822.H
9f6ccd # End Source File
61df4f # Begin Source File
a2af5a
c99de5 SOURCE=.\shared\RichEdit_IO.h
a96ccd # End Source File
63df4f # Begin Source File
83af5a
9398b0 SOURCE=.\EudoraPlugin\SendMailToolbarWndProc.h
666ccd # End Source File
42df4f # Begin Source File
faaf5a
b5864a SOURCE=.\shared\SigEvent.h
ec6ccd # End Source File
0edf4f # Begin Source File
71af5a
841900 SOURCE=.\EudoraPlugin\strstri.h
4e6ccd # End Source File
19df4f # Begin Source File
3daf5a
357ae7 SOURCE=.\EudoraPlugin\transbmp.h
b46ccd # End Source File
bbdf4f # Begin Source File
e0af5a
5c4b74 SOURCE=.\EudoraPlugin\TranslatorIDs.h
066ccd # End Source File
1adf4f # Begin Source File
e2af5a
c7e8b5 SOURCE=.\EudoraPlugin\Translators.h
4b6ccd # End Source File
a1df4f # Begin Source File
38af5a
a40616 SOURCE=.\EudoraPlugin\TranslatorUtils.h
a26ccd # End Source File
26df4f # Begin Source File
2caf5a
119280 SOURCE=.\shared\WrapBuff.h
b26ccd # End Source File
5d3f5a # End Group
0c52cb # Begin Group "Library Header Files"
b1af5a
14561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
fcdf4f # Begin Source File
2eaf5a
6595cd SOURCE=..\..\..\libs\pfl\common\pflContext.h
436ccd # End Source File
46df4f # Begin Source File
69af5a
60e71e SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefs.h
8f6ccd # End Source File
05df4f # Begin Source File
7baf5a
bab7ae SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefTypes.h
826ccd # End Source File
dfdf4f # Begin Source File
38af5a
--76a1 000091f03634011018d Page 7 of EudoraPlugin.dsp
2f97b4 SOURCE=..\..\..\libs\pfl\common\pflTypes.h
f76ccd # End Source File
19df4f # Begin Source File
6eaf5a
e2b550 SOURCE=..\..\..\libs\pfl\common\pgpBase.h
566ccd # End Source File
90df4f # Begin Source File
d6af5a
d9a283 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpCipherFeedback.h
0e6ccd # End Source File
dadf4f # Begin Source File
6aaf5a
411a03 SOURCE=..\..\..\libs\pgpcdk\win32\pgpConfig.h
ce6ccd # End Source File
cadf4f # Begin Source File
1aaf5a
5714e8 SOURCE=..\..\..\libs\pfl\common\pgpDebug.h
076ccd # End Source File
20df4f # Begin Source File
36af5a
04f43c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpEncode.h
996ccd # End Source File
b0df4f # Begin Source File
04af5a
94b9d9 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpErrors.h
606ccd # End Source File
7ddf4f # Begin Source File
a7af5a
ebe1d3 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpHash.h
ad6ccd # End Source File
dadf4f # Begin Source File
49af5a
ae160d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeys.h
196ccd # End Source File
e3df4f # Begin Source File
09af5a
0f519c SOURCE=..\..\..\libs\pfl\common\pgpLeaks.h
036ccd # End Source File
addf4f # Begin Source File
03af5a
50dbb2 SOURCE=..\..\..\libs\pfl\common\pgpMem.h
966ccd # End Source File
20df4f # Begin Source File
ccaf5a
183e03 SOURCE=..\..\..\libs\pfl\win32\pgpPFLConfig.h
0c6ccd # End Source File
54df4f # Begin Source File
8caf5a
41aafb SOURCE=..\..\..\libs\pfl\common\pgpPFLErrors.h
216ccd # End Source File
7edf4f # Begin Source File
a4af5a
d29472 SOURCE=.\EudoraPlugin\PGPPlug.h
8e6ccd # End Source File
6bdf4f # Begin Source File
53af5a
3e307d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpPubTypes.h
9f6ccd # End Source File
c3df4f # Begin Source File
feaf5a
4472a7 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSDKPrefs.h
546ccd # End Source File
41df4f # Begin Source File
76af5a
a1e72b SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSymmetricCipher.h
886ccd # End Source File
fedf4f # Begin Source File
f1af5a
f30428 SOURCE=..\..\..\libs\pfl\common\pgpTypes.h
176ccd # End Source File
a9df4f # Begin Source File
09af5a
--79f0 001b27564df4011018d Page 8 of EudoraPlugin.dsp
5eea6c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpUtilities.h
666ccd # End Source File
8f3f5a # End Group
90e5cf # End Target
b2f262 # End Project
--47ed 000e1e66e304011018e Page 1 of EudoraPlugin.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
4aeb32 Project: "EudoraPlugin"=.\EudoraPlugin.dsp - Package Owner=<4>
bbaf5a
41e41b Package=<5>
df8818 {{{
78418b }}}
53af5a
a4bec7 Package=<4>
028818 {{{
162c9f ····Begin Project Dependency
97ba3b ····Project_Dep_Name PGPcdk
4304a4 ····End Project Dependency
a92c9f ····Begin Project Dependency
bf7257 ····Project_Dep_Name PGPsc
8104a4 ····End Project Dependency
4c2c9f ····Begin Project Dependency
f7740a ····Project_Dep_Name PGPcl
dd04a4 ····End Project Dependency
6c418b }}}
acaf5a
372d94 ###############################################################################
e7af5a
41f187 Project: "PGPcdk"=..\..\..\libs\pgpcdk\win32\PGPcdk\PGPcdk.dsp - Package Owner=¶
77bde1 <4>
4baf5a
36e41b Package=<5>
718818 {{{
89418b }}}
65af5a
8cbec7 Package=<4>
3b8818 {{{
6e418b }}}
f0af5a
f92d94 ###############################################################################
a4af5a
4be0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
01af5a
e9e41b Package=<5>
8c8818 {{{
86418b }}}
70af5a
e2bec7 Package=<4>
d28818 {{{
fe2c9f ····Begin Project Dependency
f2ba3b ····Project_Dep_Name PGPcdk
4204a4 ····End Project Dependency
8a2c9f ····Begin Project Dependency
2edd55 ····Project_Dep_Name PGPsdkNetworkLib
bb04a4 ····End Project Dependency
a42c9f ····Begin Project Dependency
a7143b ····Project_Dep_Name TreeList
5504a4 ····End Project Dependency
5c418b }}}
a5af5a
372d94 ###############################################################################
84af5a
391a36 Project: "PGPsc"=.\PGPsc.dsp - Package Owner=<4>
97af5a
b7e41b Package=<5>
208818 {{{
99418b }}}
74af5a
e2bec7 Package=<4>
0e8818 {{{
222c9f ····Begin Project Dependency
75ba3b ····Project_Dep_Name PGPcdk
2404a4 ····End Project Dependency
e12c9f ····Begin Project Dependency
--bd24 000a086fb954011018e Page 2 of EudoraPlugin.dsw
a49050 ····Project_Dep_Name PGPcdkKeyServer
a004a4 ····End Project Dependency
25418b }}}
8faf5a
ae2d94 ###############################################################################
40af5a
22786e Project: "PGPsdkNetworkLib"=..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\PGPsdkN¶
a3db59 etworkLib.dsp - Package Owner=<4>
92af5a
c3e41b Package=<5>
428818 {{{
bb418b }}}
47af5a
a9bec7 Package=<4>
e28818 {{{
162c9f ····Begin Project Dependency
84d307 ····Project_Dep_Name liblber
6404a4 ····End Project Dependency
582c9f ····Begin Project Dependency
8dc84c ····Project_Dep_Name libldap
8a04a4 ····End Project Dependency
81418b }}}
87af5a
fc2d94 ###############################################################################
5eaf5a
d490a2 Project: "TreeList"=.\TreeList.dsp - Package Owner=<4>
75af5a
d6e41b Package=<5>
8e8818 {{{
df418b }}}
41af5a
d6bec7 Package=<4>
818818 {{{
af418b }}}
90af5a
4d2d94 ###############################################################################
e3af5a
7ca53c Project: "liblber"=..\..\..\libs\network\ldaplib\win32\liblber.dsp - Package Ow¶
916f39 ner=<4>
08af5a
9ae41b Package=<5>
ba8818 {{{
10418b }}}
92af5a
75bec7 Package=<4>
e58818 {{{
fe418b }}}
a5af5a
f32d94 ###############################################################################
56af5a
c9a9a3 Project: "libldap"=..\..\..\libs\network\ldaplib\win32\libldap.dsp - Package Ow¶
d86f39 ner=<4>
fbaf5a
e4e41b Package=<5>
018818 {{{
4b418b }}}
f3af5a
e0bec7 Package=<4>
448818 {{{
01418b }}}
1caf5a
cc2d94 ###############################################################################
e3af5a
ac20da Global:
15af5a
c4e41b Package=<5>
f68818 {{{
08418b }}}
49af5a
0c32c2 Package=<3>
6f8818 {{{
a0418b }}}
--9453 001ee7020c64011018e Page 3 of EudoraPlugin.dsw
e0af5a
7e2d94 ###############################################################################
eeaf5a
--a4e1 00085f523244011018f Page 1 of EudoraPluginV4.dsp
67e8fb # Microsoft Developer Studio Project File - Name="EudoraPluginV4" - Package Own¶
1a8c35 er=<4>
4ae7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
058537 # ** DO NOT EDIT **
b1af5a
46a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
bbaf5a
5092fb CFG=EudoraPluginV4 - Win32 Debug
2a894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
175c35 !MESSAGE use the Export Makefile command and run
346309 !MESSAGE·
f428b4 !MESSAGE NMAKE /f "EudoraPluginV4.mak".
416309 !MESSAGE·
72cdb3 !MESSAGE You can specify a configuration when running NMAKE
d2e013 !MESSAGE by defining the macro CFG on the command line. For example:
9c6309 !MESSAGE·
5df934 !MESSAGE NMAKE /f "EudoraPluginV4.mak" CFG="EudoraPluginV4 - Win32 Debug"
8b6309 !MESSAGE·
861dd7 !MESSAGE Possible choices for configuration are:
206309 !MESSAGE·
439788 !MESSAGE "EudoraPluginV4 - Win32 Release" (based on\
1d17ca ·"Win32 (x86) Dynamic-Link Library")
df1684 !MESSAGE "EudoraPluginV4 - Win32 Debug" (based on\
a517ca ·"Win32 (x86) Dynamic-Link Library")
5e6309 !MESSAGE·
e6af5a
353e63 # Begin Project
c7b23f # PROP Scc_ProjName ""
74df4a # PROP Scc_LocalPath ""
b640a4 CPP=cl.exe
fda46a MTL=midl.exe
4a2e1f RSC=rc.exe
dbaf5a
dc6b0c !IF ·"$(CFG)" == "EudoraPluginV4 - Win32 Release"
98af5a
c28243 # PROP BASE Use_MFC 0
ede662 # PROP BASE Use_Debug_Libraries 0
2e7d73 # PROP BASE Output_Dir "Release"
a06180 # PROP BASE Intermediate_Dir "Release"
864c81 # PROP BASE Target_Dir ""
4f21ad # PROP Use_MFC 0
a9b771 # PROP Use_Debug_Libraries 0
4bf310 # PROP Output_Dir "Release"
0101a1 # PROP Intermediate_Dir "Release"
ee9ad5 # PROP Ignore_Export_Lib 0
98b6fa # PROP Target_Dir ""
4cc65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
9810c2 ·/FD /c
dc4ac1 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\shared" /I "include" /I "shared" /I¶
31e193 ·"..\shared" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win¶
aef503 32" /I "..\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\win32" /I "..\..\..\lib¶
125c60 s\pfl\common\prefs" /I "..\..\..\libs\pfl\common\file" /D UNFINISHED_CODE_ALLOW¶
b0b8d9 ED=0 /D PGP_DEBUG=0 /D PGP_WIN32=1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Yu"win¶
26b247 dows.h" /FD /c
a61e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
f46d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
efb35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
bede84 # ADD RSC /l 0x409 /d "NDEBUG"
aa18fc BSC32=bscmake.exe
6c7a24 # ADD BASE BSC32 /nologo
ac4f1b # ADD BSC32 /nologo
dd268f LINK32=link.exe
66cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
1fa5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
e55e3b ·/nologo /subsystem:windows /dll /machine:I386
9ddebb # ADD LINK32 ..\..\..\libs\pfl\win32\pflCommon\Release\pflCommon.lib ..\..\..\l¶
80f51e ibs\pgpcdk\win32\pgpsdknetworklib\release\pgpsdknl.lib pgpcl\release\pgp60cl.li¶
d953de b pgpsc\release\pgp60sc.lib comctl32.lib kernel32.lib user32.lib gdi32.lib wins¶
c743ea pool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ¶
ad6914 odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Eud¶
12237a oraPluginV4/Release/pgpEudoraPluginV4.dll"
8584a1 # SUBTRACT LINK32 /pdb:none
--708a 000dcc414734011018f Page 2 of EudoraPluginV4.dsp
e0af5a
9253e7 !ELSEIF ·"$(CFG)" == "EudoraPluginV4 - Win32 Debug"
87af5a
d98243 # PROP BASE Use_MFC 0
1affba # PROP BASE Use_Debug_Libraries 1
8f54b8 # PROP BASE Output_Dir "Debug"
0a198a # PROP BASE Intermediate_Dir "Debug"
244c81 # PROP BASE Target_Dir ""
1721ad # PROP Use_MFC 0
c3aea9 # PROP Use_Debug_Libraries 1
6c697d # PROP Output_Dir "EudoraPluginV4/Debug"
818071 # PROP Intermediate_Dir "EudoraPluginV4/Debug"
e89ad5 # PROP Ignore_Export_Lib 0
7fb6fa # PROP Target_Dir ""
a76cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
3b1fea DOWS" /YX /FD /c
560737 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\shared" /I "include" /I "shar¶
99edb4 ed" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win32" /I ".¶
d974f9 .\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pfl\com¶
c86152 mon\prefs" /I "..\..\..\libs\pfl\common\file" /D "_DEBUG" /D UNFINISHED_CODE_AL¶
4428b6 LOWED=1 /D PGP_DEBUG=1 /D PGP_WIN32=1 /D "WIN32" /D "_WINDOWS" /Yu"windows.h" /¶
d9d0d1 FD /c
b1c0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
4ab3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
a0699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
bc0443 # ADD RSC /l 0x409 /d "_DEBUG"
2418fc BSC32=bscmake.exe
b87a24 # ADD BASE BSC32 /nologo
da4f1b # ADD BSC32 /nologo
20268f LINK32=link.exe
48cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
aea5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
b917bf ·/nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
b6debf # ADD LINK32 ..\..\..\libs\pfl\win32\pflCommon\Debug\pflCommon.lib ..\..\..\lib¶
759901 s\pgpcdk\win32\pgpsdknetworklib\debug\pgpsdknl.lib pgpcl\debug\pgp60cl.lib pgps¶
5d20dc c\debug\pgp60sc.lib comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib¶
b2e619 ·comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.l¶
f77eba ib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Eudo¶
4df2a6 raPluginV4/Debug/pgpEudoraPluginV4.dll" /pdbtype:sept
d284a1 # SUBTRACT LINK32 /pdb:none
deaf5a
d730ec !ENDIF·
c2af5a
4eb8a5 # Begin Target
95af5a
34c977 # Name "EudoraPluginV4 - Win32 Release"
21e50b # Name "EudoraPluginV4 - Win32 Debug"
6e4cc4 # Begin Group "Source Files"
8aaf5a
a356ed # PROP Default_Filter "c;cpp"
cedf4f # Begin Source File
03af5a
342697 SOURCE=.\shared\AddKey.c
316ccd # End Source File
57df4f # Begin Source File
c9af5a
d21da7 SOURCE=.\shared\BlockUtils.c
366ccd # End Source File
cedf4f # Begin Source File
96af5a
352772 SOURCE=.\shared\DecryptVerify.c
386ccd # End Source File
5adf4f # Begin Source File
98af5a
5aab59 SOURCE=.\EudoraPluginV4\DisplayMessage.c
bf6ccd # End Source File
cfdf4f # Begin Source File
9baf5a
90ca1a SOURCE=.\EudoraPluginV4\emssdk\ENCODING.CPP
f6ae01 # SUBTRACT CPP /YX /Yc /Yu
946ccd # End Source File
dcdf4f # Begin Source File
--0b91 000a1814c804011018f Page 3 of EudoraPluginV4.dsp
e0af5a
46ce65 SOURCE=.\shared\EncryptSign.c
d06ccd # End Source File
f2df4f # Begin Source File
1baf5a
2be405 SOURCE=.\EudoraPluginV4\MapFile.c
726ccd # End Source File
f9df4f # Begin Source File
8baf5a
bb8202 SOURCE=.\EudoraPluginV4\emssdk\MIMETYPE.CPP
e3ae01 # SUBTRACT CPP /YX /Yc /Yu
3d6ccd # End Source File
22df4f # Begin Source File
b5af5a
3b4b19 SOURCE=.\EudoraPluginV4\MyMIMEUtils.c
136ccd # End Source File
68df4f # Begin Source File
d7af5a
1b3e26 SOURCE=.\EudoraPluginV4\PGPplugin.def
106ccd # End Source File
0edf4f # Begin Source File
29af5a
867333 SOURCE=.\EudoraPluginV4\PGPplugin.rc
e46ccd # End Source File
fedf4f # Begin Source File
c9af5a
e0d839 SOURCE=..\shared\pgpVersionHeader.c
8cae01 # SUBTRACT CPP /YX /Yc /Yu
426ccd # End Source File
9fdf4f # Begin Source File
76af5a
5a0fc3 SOURCE=.\EudoraPluginV4\PluginMain.c
96c7e9 # ADD CPP /Yc"windows.h"
576ccd # End Source File
35df4f # Begin Source File
d8af5a
9f0d54 SOURCE=.\shared\Prefs.c
276ccd # End Source File
a1df4f # Begin Source File
38af5a
0ea597 SOURCE=.\EudoraPluginV4\emssdk\RFC822.CPP
a3ae01 # SUBTRACT CPP /YX /Yc /Yu
c76ccd # End Source File
cadf4f # Begin Source File
dcaf5a
e362e2 SOURCE=.\shared\SigEvent.c
606ccd # End Source File
9adf4f # Begin Source File
f4af5a
e68eb0 SOURCE=.\EudoraPluginV4\strstri.c
fcae01 # SUBTRACT CPP /YX /Yc /Yu
d86ccd # End Source File
d4df4f # Begin Source File
7daf5a
ee45d8 SOURCE=.\EudoraPluginV4\Translators.c
aa6ccd # End Source File
67df4f # Begin Source File
b8af5a
db2d58 SOURCE=.\EudoraPluginV4\TranslatorUtils.c
136ccd # End Source File
f5df4f # Begin Source File
2caf5a
643d38 SOURCE=.\shared\VerificationBlock.c
a66ccd # End Source File
c3df4f # Begin Source File
01af5a
9ae8b5 SOURCE=.\shared\Working.c
016ccd # End Source File
ce3f5a # End Group
326775 # Begin Group "Project Header Files"
f1af5a
a16590 # PROP Default_Filter "h"
--5077 00079379b9c4011018f Page 4 of EudoraPluginV4.dsp
41df4f # Begin Source File
d0af5a
fcf90f SOURCE=.\shared\BlockUtils.h
4c6ccd # End Source File
c0df4f # Begin Source File
50af5a
bb4ff1 SOURCE=.\EudoraPluginV4\DisplayMessage.h
b66ccd # End Source File
7adf4f # Begin Source File
23af5a
0cb551 SOURCE=".\EudoraPluginV4\emssdk\ems-win.h"
196ccd # End Source File
8cdf4f # Begin Source File
a8af5a
e2b002 SOURCE=.\EudoraPluginV4\emssdk\ENCODING.H
9e6ccd # End Source File
eedf4f # Begin Source File
13af5a
1700ad SOURCE=.\EudoraPluginV4\MapFile.h
706ccd # End Source File
75df4f # Begin Source File
d5af5a
1de9c2 SOURCE=.\EudoraPluginV4\emssdk\Mimetype.h
cd6ccd # End Source File
48df4f # Begin Source File
d5af5a
feafb1 SOURCE=.\EudoraPluginV4\MyMIMEUtils.h
c56ccd # End Source File
50df4f # Begin Source File
6caf5a
eb0b92 SOURCE=.\include\pgpkm.h
216ccd # End Source File
f9df4f # Begin Source File
6daf5a
4240e6 SOURCE=.\include\pgpphras.h
9c6ccd # End Source File
93df4f # Begin Source File
71af5a
985346 SOURCE=.\include\PGPRecip.h
8d6ccd # End Source File
a4df4f # Begin Source File
eaaf5a
a468eb SOURCE=.\INCLUDE\PGPsc.h
166ccd # End Source File
38df4f # Begin Source File
21af5a
bfeb6b SOURCE=.\EudoraPluginV4\PluginMain.h
c86ccd # End Source File
c5df4f # Begin Source File
c3af5a
e6722e SOURCE=.\EudoraPluginV4\emssdk\RFC822.H
f36ccd # End Source File
04df4f # Begin Source File
ebaf5a
db864a SOURCE=.\shared\SigEvent.h
f06ccd # End Source File
38df4f # Begin Source File
63af5a
7920a3 SOURCE=.\EudoraPluginV4\TranslatorIDs.h
9b6ccd # End Source File
2edf4f # Begin Source File
bfaf5a
89a170 SOURCE=.\EudoraPluginV4\Translators.h
6a6ccd # End Source File
6adf4f # Begin Source File
c6af5a
69c9f0 SOURCE=.\EudoraPluginV4\TranslatorUtils.h
7b6ccd # End Source File
ad3f5a # End Group
eb8925 # Begin Group "Resource Files"
13af5a
794dc4 # PROP Default_Filter "ico;bmp"
--ecf1 0009731fb494011018f Page 5 of EudoraPluginV4.dsp
41df4f # Begin Source File
d0af5a
253abd SOURCE=.\EudoraPluginV4\Res\addkey.ico
ad6ccd # End Source File
7adf4f # Begin Source File
d6af5a
a5ae8b SOURCE=.\EudoraPluginV4\Res\encryptsign.ico
016ccd # End Source File
4cdf4f # Begin Source File
87af5a
68f07e SOURCE=.\EudoraPluginV4\Res\Key.ico
416ccd # End Source File
52df4f # Begin Source File
c2af5a
ccd48d SOURCE=.\EudoraPluginV4\Res\lock.ico
e16ccd # End Source File
62df4f # Begin Source File
0eaf5a
6c1c44 SOURCE=.\EudoraPluginV4\Res\lock1.ico
3a6ccd # End Source File
bddf4f # Begin Source File
ecaf5a
8f4904 SOURCE=.\EudoraPluginV4\Res\pgp50.ico
356ccd # End Source File
56df4f # Begin Source File
77af5a
a4fd8b SOURCE=.\EudoraPluginV4\Res\pgp_addkey.ico
ab6ccd # End Source File
11df4f # Begin Source File
7caf5a
25bff1 SOURCE=.\EudoraPluginV4\Res\pgp_encrypt_sign.ico
5a6ccd # End Source File
e9df4f # Begin Source File
1aaf5a
b33b5e SOURCE=.\EudoraPluginV4\Res\readtool.bmp
616ccd # End Source File
7fdf4f # Begin Source File
f0af5a
ca22bf SOURCE=.\EudoraPluginV4\Res\sendtool.bmp
d36ccd # End Source File
08df4f # Begin Source File
0eaf5a
e4db71 SOURCE=.\EudoraPluginV4\Res\sign.ico
066ccd # End Source File
e7df4f # Begin Source File
aeaf5a
b85ff5 SOURCE=.\EudoraPluginV4\Res\unlock.ico
e76ccd # End Source File
67df4f # Begin Source File
61af5a
603fb3 SOURCE=.\EudoraPluginV4\Res\verify.ico
d76ccd # End Source File
ae3f5a # End Group
f752cb # Begin Group "Library Header Files"
22af5a
5c6590 # PROP Default_Filter "h"
58df4f # Begin Source File
1faf5a
b495cd SOURCE=..\..\..\libs\pfl\common\pflContext.h
076ccd # End Source File
b9df4f # Begin Source File
6caf5a
02e71e SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefs.h
bd6ccd # End Source File
96df4f # Begin Source File
4baf5a
3ab7ae SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefTypes.h
cd6ccd # End Source File
01df4f # Begin Source File
74af5a
fa97b4 SOURCE=..\..\..\libs\pfl\common\pflTypes.h
976ccd # End Source File
--20a8 000803ec4c54011018f Page 6 of EudoraPluginV4.dsp
41df4f # Begin Source File
d0af5a
bab550 SOURCE=..\..\..\libs\pfl\common\pgpBase.h
b06ccd # End Source File
bddf4f # Begin Source File
88af5a
9c8894 SOURCE=..\shared\pgpBuildFlags.h
936ccd # End Source File
68df4f # Begin Source File
bcaf5a
8342a0 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpCFB.h
cc6ccd # End Source File
67df4f # Begin Source File
0eaf5a
37b357 SOURCE=..\shared\pgpClientPrefs.h
f06ccd # End Source File
35df4f # Begin Source File
b5af5a
d61a03 SOURCE=..\..\..\libs\pgpcdk\win32\pgpConfig.h
246ccd # End Source File
96df4f # Begin Source File
b0af5a
4914e8 SOURCE=..\..\..\libs\pfl\common\pgpDebug.h
026ccd # End Source File
3fdf4f # Begin Source File
95af5a
2ff43c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpEncode.h
696ccd # End Source File
95df4f # Begin Source File
f2af5a
64b9d9 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpErrors.h
5a6ccd # End Source File
35df4f # Begin Source File
90af5a
f7e1d3 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpHash.h
bc6ccd # End Source File
2fdf4f # Begin Source File
d5af5a
cc160d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeys.h
1c6ccd # End Source File
e1df4f # Begin Source File
54af5a
9b519c SOURCE=..\..\..\libs\pfl\common\pgpLeaks.h
a96ccd # End Source File
cbdf4f # Begin Source File
a1af5a
86dbb2 SOURCE=..\..\..\libs\pfl\common\pgpMem.h
6b6ccd # End Source File
fedf4f # Begin Source File
cfaf5a
4f3e03 SOURCE=..\..\..\libs\pfl\win32\pgpPFLConfig.h
266ccd # End Source File
49df4f # Begin Source File
2eaf5a
60aafb SOURCE=..\..\..\libs\pfl\common\pgpPFLErrors.h
6a6ccd # End Source File
37df4f # Begin Source File
95af5a
96307d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpPubTypes.h
b06ccd # End Source File
60df4f # Begin Source File
e3af5a
4272a7 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSDKPrefs.h
516ccd # End Source File
2fdf4f # Begin Source File
a6af5a
aae72b SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSymmetricCipher.h
326ccd # End Source File
e2df4f # Begin Source File
55af5a
330428 SOURCE=..\..\..\libs\pfl\common\pgpTypes.h
806ccd # End Source File
--67d0 00154a751274011018f Page 7 of EudoraPluginV4.dsp
41df4f # Begin Source File
d0af5a
17ea6c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpUtilities.h
296ccd # End Source File
d1df4f # Begin Source File
06af5a
0a6a72 SOURCE=.\include\PGPversion.h
896ccd # End Source File
abdf4f # Begin Source File
d6af5a
553c91 SOURCE=..\shared\pgpVersionHeader.h
ed6ccd # End Source File
37df4f # Begin Source File
f5af5a
5962c4 SOURCE=.\INCLUDE\pgpWerr.h
736ccd # End Source File
5a3f5a # End Group
7ce5cf # End Target
54f262 # End Project
--70de 0005e1d13b940110190 Page 1 of EudoraPluginV4.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
99b6a3 Project: "EudoraPluginV4"=.\EudoraPluginV4.dsp - Package Owner=<4>
c9af5a
dfe41b Package=<5>
d78818 {{{
e7418b }}}
d6af5a
9abec7 Package=<4>
e48818 {{{
d72c9f ····Begin Project Dependency
f1ba3b ····Project_Dep_Name PGPcdk
de04a4 ····End Project Dependency
142c9f ····Begin Project Dependency
b27257 ····Project_Dep_Name PGPsc
ff04a4 ····End Project Dependency
1c2c9f ····Begin Project Dependency
0c740a ····Project_Dep_Name PGPcl
6d04a4 ····End Project Dependency
6a418b }}}
17af5a
1f2d94 ###############################################################################
a9af5a
36f187 Project: "PGPcdk"=..\..\..\libs\pgpcdk\win32\PGPcdk\PGPcdk.dsp - Package Owner=¶
26bde1 <4>
6caf5a
abe41b Package=<5>
158818 {{{
6a418b }}}
62af5a
c7bec7 Package=<4>
b38818 {{{
c7418b }}}
deaf5a
352d94 ###############################################################################
78af5a
99e0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
88af5a
fee41b Package=<5>
a78818 {{{
41418b }}}
35af5a
f7bec7 Package=<4>
878818 {{{
4c2c9f ····Begin Project Dependency
feba3b ····Project_Dep_Name PGPcdk
d304a4 ····End Project Dependency
1b2c9f ····Begin Project Dependency
e7dd55 ····Project_Dep_Name PGPsdkNetworkLib
6204a4 ····End Project Dependency
51418b }}}
80af5a
b82d94 ###############################################################################
59af5a
de1a36 Project: "PGPsc"=.\PGPsc.dsp - Package Owner=<4>
5baf5a
c2e41b Package=<5>
498818 {{{
fb418b }}}
4faf5a
b5bec7 Package=<4>
c08818 {{{
7f2c9f ····Begin Project Dependency
daba3b ····Project_Dep_Name PGPcdk
5d04a4 ····End Project Dependency
6c2c9f ····Begin Project Dependency
f29050 ····Project_Dep_Name PGPcdkKeyServer
8a04a4 ····End Project Dependency
5e418b }}}
--e492 001d790effa40110190 Page 2 of EudoraPluginV4.dsw
e0af5a
7e2d94 ###############################################################################
eeaf5a
2b786e Project: "PGPsdkNetworkLib"=..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\PGPsdkN¶
48db59 etworkLib.dsp - Package Owner=<4>
0caf5a
d0e41b Package=<5>
e88818 {{{
c1418b }}}
c3af5a
eebec7 Package=<4>
dc8818 {{{
e92c9f ····Begin Project Dependency
7ed307 ····Project_Dep_Name liblber
ab04a4 ····End Project Dependency
3b2c9f ····Begin Project Dependency
b0c84c ····Project_Dep_Name libldap
5d04a4 ····End Project Dependency
e8418b }}}
43af5a
582d94 ###############################################################################
6aaf5a
c2a53c Project: "liblber"=..\..\..\libs\network\ldaplib\win32\liblber.dsp - Package Ow¶
db6f39 ner=<4>
dbaf5a
d6e41b Package=<5>
098818 {{{
b7418b }}}
1daf5a
bbbec7 Package=<4>
1e8818 {{{
a9418b }}}
a0af5a
6e2d94 ###############################################################################
f5af5a
fca9a3 Project: "libldap"=..\..\..\libs\network\ldaplib\win32\libldap.dsp - Package Ow¶
ab6f39 ner=<4>
07af5a
c3e41b Package=<5>
7f8818 {{{
bc418b }}}
15af5a
4abec7 Package=<4>
d58818 {{{
51418b }}}
15af5a
ec2d94 ###############################################################################
e0af5a
c620da Global:
f8af5a
e6e41b Package=<5>
178818 {{{
d8418b }}}
29af5a
4932c2 Package=<3>
fd8818 {{{
1f418b }}}
ddaf5a
9d2d94 ###############################################################################
d7af5a
--3b49 000149d999940110191 Page 1 of OEloader.dsp
d15eca # Microsoft Developer Studio Project File - Name="OEloader" - Package Owner=<4>
89e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
1f8537 # ** DO NOT EDIT **
3caf5a
39e536 # TARGTYPE "Win32 (x86) Application" 0x0101
08af5a
df9faa CFG=OEloader - Win32 Debug
3f894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
075c35 !MESSAGE use the Export Makefile command and run
676309 !MESSAGE·
0de9b3 !MESSAGE NMAKE /f "OEloader.mak".
a66309 !MESSAGE·
d6cdb3 !MESSAGE You can specify a configuration when running NMAKE
71e013 !MESSAGE by defining the macro CFG on the command line. For example:
2d6309 !MESSAGE·
90429e !MESSAGE NMAKE /f "OEloader.mak" CFG="OEloader - Win32 Debug"
6c6309 !MESSAGE·
f51dd7 !MESSAGE Possible choices for configuration are:
1b6309 !MESSAGE·
0c8dff !MESSAGE "OEloader - Win32 Release" (based on "Win32 (x86) Application")
2219d6 !MESSAGE "OEloader - Win32 Debug" (based on "Win32 (x86) Application")
1c6309 !MESSAGE·
27af5a
643e63 # Begin Project
37b23f # PROP Scc_ProjName ""
60df4a # PROP Scc_LocalPath ""
4c40a4 CPP=cl.exe
7ba46a MTL=midl.exe
812e1f RSC=rc.exe
a6af5a
89c79f !IF ·"$(CFG)" == "OEloader - Win32 Release"
0caf5a
298243 # PROP BASE Use_MFC 0
14e662 # PROP BASE Use_Debug_Libraries 0
e37d73 # PROP BASE Output_Dir "Release"
d36180 # PROP BASE Intermediate_Dir "Release"
a04c81 # PROP BASE Target_Dir ""
3c21ad # PROP Use_MFC 0
a7b771 # PROP Use_Debug_Libraries 0
b25a0d # PROP Output_Dir ".\OEloader\Release"
60db6c # PROP Intermediate_Dir ".\OEloader\Release"
709ad5 # PROP Ignore_Export_Lib 0
e2b6fa # PROP Target_Dir ""
454fa4 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD¶
c09f26 ·/c
f1f564 # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
4e1e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
cf6d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
90b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
84de84 # ADD RSC /l 0x409 /d "NDEBUG"
3918fc BSC32=bscmake.exe
ba7a24 # ADD BASE BSC32 /nologo
384f1b # ADD BSC32 /nologo
b9268f LINK32=link.exe
06cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
f5a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
6d2ac3 ·/nologo /subsystem:windows /machine:I386
23700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
291e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
c83e76 ogo /subsystem:windows /machine:I386 /out:".\OEloader\Release/msimn.exe"
deaf5a
d8f3b7 !ELSEIF ·"$(CFG)" == "OEloader - Win32 Debug"
f9af5a
528243 # PROP BASE Use_MFC 0
8fffba # PROP BASE Use_Debug_Libraries 1
3154b8 # PROP BASE Output_Dir "Debug"
60198a # PROP BASE Intermediate_Dir "Debug"
104c81 # PROP BASE Target_Dir ""
9721ad # PROP Use_MFC 0
2aaea9 # PROP Use_Debug_Libraries 1
266616 # PROP Output_Dir ".\OEloader\Debug"
14af65 # PROP Intermediate_Dir ".\OEloader\Debug"
--7fd4 0010297e8dd40110191 Page 2 of OEloader.dsp
9e9ad5 # PROP Ignore_Export_Lib 0
78b6fa # PROP Target_Dir ""
d2a5f2 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
e150ba ·/YX /FD /c
8ff484 # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX ¶
47aaa6 /FD /c
6ec0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
18b3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
20699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
5c0443 # ADD RSC /l 0x409 /d "_DEBUG"
4718fc BSC32=bscmake.exe
867a24 # ADD BASE BSC32 /nologo
8b4f1b # ADD BSC32 /nologo
83268f LINK32=link.exe
62cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
94a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
2366c6 ·/nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
17700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
2b1e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
a2bf77 ogo /subsystem:windows /debug /machine:I386 /out:".\OEloader\Debug/msimn.exe" /¶
c947f8 pdbtype:sept
cbaf5a
1c30ec !ENDIF·
daaf5a
71b8a5 # Begin Target
9baf5a
ca00e8 # Name "OEloader - Win32 Release"
15b427 # Name "OEloader - Win32 Debug"
49df4f # Begin Source File
b1af5a
f7d4c5 SOURCE=.\OEloader\Res\envelope.ico
486ccd # End Source File
01df4f # Begin Source File
d2af5a
6d7e75 SOURCE=.\OEloader\Res\letter.ico
ee6ccd # End Source File
7adf4f # Begin Source File
71af5a
747a32 SOURCE=.\OEloader\main.cpp
736ccd # End Source File
a2df4f # Begin Source File
f5af5a
5c78ce SOURCE=.\OEloader\Res\msimn.ico
966ccd # End Source File
e0df4f # Begin Source File
17af5a
aa7003 SOURCE=.\OEloader\msimn.rc
606ccd # End Source File
84df4f # Begin Source File
11af5a
69a730 SOURCE=.\OEloader\Res\news.ico
bf6ccd # End Source File
24df4f # Begin Source File
39af5a
b45f5c SOURCE=.\OEloader\Res\package.ico
ed6ccd # End Source File
4ce5cf # End Target
02f262 # End Project
--9533 00132d80a6740110192 Page 1 of OEloader.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
c5f615 Project: "OEloader"=.\OEloader.dsp - Package Owner=<4>
1eaf5a
cbe41b Package=<5>
2c8818 {{{
1a418b }}}
ecaf5a
4bbec7 Package=<4>
308818 {{{
30418b }}}
65af5a
a12d94 ###############################################################################
5baf5a
1120da Global:
ceaf5a
7de41b Package=<5>
448818 {{{
97418b }}}
b7af5a
3032c2 Package=<3>
7a8818 {{{
66418b }}}
7baf5a
002d94 ###############################################################################
32af5a
--2d76 00091e0141f40110193 Page 1 of OutlookExpress.dsp
1f865d # Microsoft Developer Studio Project File - Name="OutlookExpress" - Package Own¶
118c35 er=<4>
33e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
ed8537 # ** DO NOT EDIT **
b6af5a
19a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
99af5a
6353d5 CFG=OutlookExpress - Win32 Debug
0c894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
895c35 !MESSAGE use the Export Makefile command and run
3b6309 !MESSAGE·
3095e5 !MESSAGE NMAKE /f "OutlookExpress.mak".
1c6309 !MESSAGE·
0ccdb3 !MESSAGE You can specify a configuration when running NMAKE
ade013 !MESSAGE by defining the macro CFG on the command line. For example:
416309 !MESSAGE·
df882c !MESSAGE NMAKE /f "OutlookExpress.mak" CFG="OutlookExpress - Win32 Debug"
746309 !MESSAGE·
951dd7 !MESSAGE Possible choices for configuration are:
c86309 !MESSAGE·
287367 !MESSAGE "OutlookExpress - Win32 Release" (based on\
f417ca ·"Win32 (x86) Dynamic-Link Library")
c73a9a !MESSAGE "OutlookExpress - Win32 Debug" (based on\
9a17ca ·"Win32 (x86) Dynamic-Link Library")
a06309 !MESSAGE·
07af5a
573e63 # Begin Project
80b23f # PROP Scc_ProjName ""
25df4a # PROP Scc_LocalPath ""
9a40a4 CPP=cl.exe
72a46a MTL=midl.exe
112e1f RSC=rc.exe
10af5a
f5ab5e !IF ·"$(CFG)" == "OutlookExpress - Win32 Release"
cbaf5a
1c8243 # PROP BASE Use_MFC 0
2fe662 # PROP BASE Use_Debug_Libraries 0
487d73 # PROP BASE Output_Dir "Release"
386180 # PROP BASE Intermediate_Dir "Release"
bd4c81 # PROP BASE Target_Dir ""
3b21ad # PROP Use_MFC 0
e2b771 # PROP Use_Debug_Libraries 0
39cc50 # PROP Output_Dir ".\OutlookExpress\Release"
aecedb # PROP Intermediate_Dir ".\OutlookExpress\Release"
549ad5 # PROP Ignore_Export_Lib 0
46b6fa # PROP Target_Dir ""
08c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
a310c2 ·/FD /c
add3d9 # ADD CPP /nologo /MT /W3 /GX /O2 /I ".\include" /I "..\..\..\libs\pfl\common" ¶
4663b3 /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\l¶
4da162 ibs\pfl\common\file" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pg¶
86a9b1 pcdk\win32" /I "..\shared" /I "shared" /D UNFINISHED_CODE_ALLOWED=0 /D PGP_WIN=¶
6f6d63 1 /D PGP_DEBUG=0 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOWS" /Yu"window¶
1ba1c3 s.h" /FD /c
681e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
e46d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
6fb35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
caf2df # ADD RSC /l 0x409 /i ".\include" /d "NDEBUG"
a318fc BSC32=bscmake.exe
337a24 # ADD BASE BSC32 /nologo
834f1b # ADD BSC32 /nologo
26268f LINK32=link.exe
4fcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
f1a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
b15e3b ·/nologo /subsystem:windows /dll /machine:I386
99f756 # ADD LINK32 ..\..\..\libs\pgpcdk\win32\PGPcdk\Release\PGP_SDK.lib ..\..\..\lib¶
0b478e s\pfl\win32\pflCommon\Release\pflCommon.lib .\PGPcl\Release\PGP60cl.lib .\PGPsc¶
8bfd2d \Release\PGP60sc.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.li¶
f419b3 b advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.¶
1fcde9 lib comctl32.lib ..\..\..\libs\pgpcdk\win32\pgpsdknetworklib\release\pgpsdknl.l¶
f71850 ib /nologo /subsystem:windows /dll /machine:I386 /out:".\OutlookExpress\Release¶
91e3e9 /PGP60oe.dll"
--f7be 0004e9dbb9340110193 Page 2 of OutlookExpress.dsp
e0af5a
f19b5a !ELSEIF ·"$(CFG)" == "OutlookExpress - Win32 Debug"
ffaf5a
068243 # PROP BASE Use_MFC 0
90ffba # PROP BASE Use_Debug_Libraries 1
7954b8 # PROP BASE Output_Dir "Debug"
8f198a # PROP BASE Intermediate_Dir "Debug"
734c81 # PROP BASE Target_Dir ""
5921ad # PROP Use_MFC 0
4daea9 # PROP Use_Debug_Libraries 1
fac8f4 # PROP Output_Dir ".\OutlookExpress\Debug"
791b9b # PROP Intermediate_Dir ".\OutlookExpress\Debug"
f69ad5 # PROP Ignore_Export_Lib 0
c5b6fa # PROP Target_Dir ""
626cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
cc1fea DOWS" /YX /FD /c
6b33ed # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".\include" /I "..\..\..\libs\pfl¶
48c703 \common" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pfl\common\prefs" /I ".¶
afe32c .\..\..\libs\pfl\common\file" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\.¶
261b72 .\libs\pgpcdk\win32" /I "..\shared" /I "shared" /D "_DEBUG" /D UNFINISHED_CODE_¶
fec283 ALLOWED=1 /D PGP_WIN=1 /D PGP_DEBUG=1 /D "WIN32" /D "_WINDOWS" /D PGP_WIN32=1 /¶
aa7765 Yu"windows.h" /FD /c
5bc0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
fdb3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
74699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
3e2818 # ADD RSC /l 0x409 /i ".\include" /d "_DEBUG"
1a18fc BSC32=bscmake.exe
ba7a24 # ADD BASE BSC32 /nologo
1c4f1b # ADD BSC32 /nologo
88268f LINK32=link.exe
b2cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
f6a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
7b17bf ·/nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
723606 # ADD LINK32 ..\..\..\libs\pgpcdk\win32\PGPcdk\Debug\PGP_SDK.lib ..\..\..\libs\¶
d51800 pfl\win32\pflCommon\Debug\pflCommon.lib .\PGPcl\Debug\PGP60cl.lib .\PGPsc\Debug¶
fc5cd0 \PGP60sc.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
3d55b4 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comc¶
da10e9 tl32.lib ..\..\..\libs\pgpcdk\win32\pgpsdknetworklib\debug\pgpsdknl.lib /nologo¶
2a228f ·/subsystem:windows /dll /debug /machine:I386 /out:".\OutlookExpress\Debug/PGP6¶
678a1f 0oe.dll" /pdbtype:sept
cdaf5a
9530ec !ENDIF·
79af5a
05b8a5 # Begin Target
a8af5a
160925 # Name "OutlookExpress - Win32 Release"
002db6 # Name "OutlookExpress - Win32 Debug"
534cc4 # Begin Group "Source Files"
24af5a
8dd4b9 # PROP Default_Filter "*.c;*.cpp;*.rc;*.def"
34df4f # Begin Source File
b9af5a
042697 SOURCE=.\shared\AddKey.c
8fae01 # SUBTRACT CPP /YX /Yc /Yu
406ccd # End Source File
43df4f # Begin Source File
d6af5a
431da7 SOURCE=.\shared\BlockUtils.c
2cae01 # SUBTRACT CPP /YX /Yc /Yu
a66ccd # End Source File
0bdf4f # Begin Source File
33af5a
cd0f2e SOURCE=.\OutlookExpress\CBTProc.cpp
0f6ccd # End Source File
efdf4f # Begin Source File
3aaf5a
fa3f68 SOURCE=.\OutlookExpress\CommonWndProc.cpp
386ccd # End Source File
4adf4f # Begin Source File
9aaf5a
fc2772 SOURCE=.\shared\DecryptVerify.c
4eae01 # SUBTRACT CPP /YX /Yc /Yu
--2e8e 000a880cc5a40110193 Page 3 of OutlookExpress.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
53ce65 SOURCE=.\shared\EncryptSign.c
8eae01 # SUBTRACT CPP /YX /Yc /Yu
e96ccd # End Source File
50df4f # Begin Source File
a1af5a
0eaf0e SOURCE=.\OutlookExpress\main.cpp
14c7e9 # ADD CPP /Yc"windows.h"
676ccd # End Source File
e8df4f # Begin Source File
52af5a
c1457d SOURCE=.\OutlookExpress\MainWndProc.cpp
626ccd # End Source File
b8df4f # Begin Source File
54af5a
b8b9d6 SOURCE=.\OutlookExpress\PGP55oe.rc
ba6ccd # End Source File
c0df4f # Begin Source File
eeaf5a
8ed839 SOURCE=..\shared\pgpVersionHeader.c
8cae01 # SUBTRACT CPP /YX /Yc /Yu
7f6ccd # End Source File
eddf4f # Begin Source File
11af5a
2aef3c SOURCE=.\OutlookExpress\PluginInfo.cpp
426ccd # End Source File
e1df4f # Begin Source File
11af5a
6b0d54 SOURCE=.\shared\Prefs.c
6cae01 # SUBTRACT CPP /YX /Yc /Yu
a46ccd # End Source File
e3df4f # Begin Source File
2aaf5a
f3042f SOURCE=.\OutlookExpress\ReadMsgWndProc.cpp
286ccd # End Source File
31df4f # Begin Source File
12af5a
5fbe55 SOURCE=.\OutlookExpress\Recipients.cpp
c86ccd # End Source File
68df4f # Begin Source File
86af5a
186733 SOURCE=.\OutlookExpress\SendMsgWndProc.cpp
8d6ccd # End Source File
f5df4f # Begin Source File
d9af5a
7f62e2 SOURCE=.\shared\SigEvent.c
d4ae01 # SUBTRACT CPP /YX /Yc /Yu
c26ccd # End Source File
d8df4f # Begin Source File
edaf5a
a04bc4 SOURCE=.\OutlookExpress\TextIO.cpp
246ccd # End Source File
d6df4f # Begin Source File
1daf5a
2d01a6 SOURCE=.\OutlookExpress\UIutils.cpp
866ccd # End Source File
38df4f # Begin Source File
88af5a
29f8f6 SOURCE=.\OutlookExpress\UnknownWndProc.cpp
236ccd # End Source File
19df4f # Begin Source File
ccaf5a
2b3d38 SOURCE=.\shared\VerificationBlock.c
8eae01 # SUBTRACT CPP /YX /Yc /Yu
ca6ccd # End Source File
10df4f # Begin Source File
6faf5a
85e8b5 SOURCE=.\shared\Working.c
ccae01 # SUBTRACT CPP /YX /Yc /Yu
a86ccd # End Source File
--a291 0010b97763440110193 Page 4 of OutlookExpress.dsp
f13f5a # End Group
80ba44 # Begin Group "Header Files"
19af5a
8a13ab # PROP Default_Filter "*.h;*.hpp"
d8df4f # Begin Source File
b9af5a
22b4bc SOURCE=.\OutlookExpress\HookProcs.h
2e6ccd # End Source File
49df4f # Begin Source File
faaf5a
26d564 SOURCE=.\OutlookExpress\PluginInfo.h
826ccd # End Source File
9ddf4f # Begin Source File
69af5a
a521a7 SOURCE=.\OutlookExpress\Recipients.h
416ccd # End Source File
c5df4f # Begin Source File
d0af5a
228349 SOURCE=.\OutlookExpress\TextIO.h
dc6ccd # End Source File
cbdf4f # Begin Source File
22af5a
e6711e SOURCE=.\OutlookExpress\UIutils.h
4d6ccd # End Source File
753f5a # End Group
b38925 # Begin Group "Resource Files"
afaf5a
88c19f # PROP Default_Filter "*.bmp;*.ico"
6fdf4f # Begin Source File
2baf5a
a53457 SOURCE=.\OutlookExpress\Res\addkey.bmp
6e6ccd # End Source File
99df4f # Begin Source File
98af5a
c76e49 SOURCE=.\OutlookExpress\Res\decrypt.bmp
236ccd # End Source File
59df4f # Begin Source File
26af5a
c5a905 SOURCE=.\OutlookExpress\Res\encrypt.bmp
0f6ccd # End Source File
65df4f # Begin Source File
dbaf5a
7783af SOURCE=.\OutlookExpress\Res\pgpkeys.bmp
7b6ccd # End Source File
62df4f # Begin Source File
60af5a
cc8b16 SOURCE=.\OutlookExpress\Res\pgpkeysl.bmp
9d6ccd # End Source File
acdf4f # Begin Source File
82af5a
7f876b SOURCE=.\OutlookExpress\Res\pgpkeyso.bmp
836ccd # End Source File
74df4f # Begin Source File
03af5a
63c514 SOURCE=.\OutlookExpress\Res\pkl4.bmp
876ccd # End Source File
e6df4f # Begin Source File
24af5a
b86d7a SOURCE=.\OutlookExpress\Res\pko4.bmp
936ccd # End Source File
b3df4f # Begin Source File
aaaf5a
7c0791 SOURCE=.\OutlookExpress\Res\sign.bmp
a76ccd # End Source File
3d3f5a # End Group
57e5cf # End Target
0bf262 # End Project
--98d3 000058e32e440110194 Page 1 of OutlookExpress.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
960da9 Project: "OutlookExpress"=.\OutlookExpress.dsp - Package Owner=<4>
f0af5a
e7e41b Package=<5>
008818 {{{
d3418b }}}
48af5a
d7bec7 Package=<4>
9f8818 {{{
032c9f ····Begin Project Dependency
3fba3b ····Project_Dep_Name PGPcdk
8d04a4 ····End Project Dependency
5b2c9f ····Begin Project Dependency
8e7257 ····Project_Dep_Name PGPsc
c404a4 ····End Project Dependency
012c9f ····Begin Project Dependency
130ce3 ····Project_Dep_Name pflCommon
f204a4 ····End Project Dependency
012c9f ····Begin Project Dependency
f4740a ····Project_Dep_Name PGPcl
6504a4 ····End Project Dependency
08418b }}}
ceaf5a
b42d94 ###############################################################################
4aaf5a
e8f187 Project: "PGPcdk"=..\..\..\libs\pgpcdk\win32\PGPcdk\PGPcdk.dsp - Package Owner=¶
7fbde1 <4>
c2af5a
dbe41b Package=<5>
ab8818 {{{
6a418b }}}
81af5a
51bec7 Package=<4>
7e8818 {{{
b42c9f ····Begin Project Dependency
5d0ce3 ····Project_Dep_Name pflCommon
2b04a4 ····End Project Dependency
d2418b }}}
a1af5a
662d94 ###############################################################################
7aaf5a
fce0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
29af5a
9de41b Package=<5>
388818 {{{
f2418b }}}
ebaf5a
abbec7 Package=<4>
ee8818 {{{
e32c9f ····Begin Project Dependency
f40ce3 ····Project_Dep_Name pflCommon
db04a4 ····End Project Dependency
702c9f ····Begin Project Dependency
98ba3b ····Project_Dep_Name PGPcdk
f404a4 ····End Project Dependency
472c9f ····Begin Project Dependency
58dd55 ····Project_Dep_Name PGPsdkNetworkLib
2104a4 ····End Project Dependency
932c9f ····Begin Project Dependency
3afd6b ····Project_Dep_Name PGPsdkUI
f804a4 ····End Project Dependency
bf2c9f ····Begin Project Dependency
a5143b ····Project_Dep_Name TreeList
d804a4 ····End Project Dependency
e5418b }}}
28af5a
8e2d94 ###############################################################################
05af5a
--02ac 00000498d4540110194 Page 2 of OutlookExpress.dsw
121a36 Project: "PGPsc"=.\PGPsc.dsp - Package Owner=<4>
80af5a
46e41b Package=<5>
f48818 {{{
1c418b }}}
9daf5a
8dbec7 Package=<4>
678818 {{{
a12c9f ····Begin Project Dependency
41ba3b ····Project_Dep_Name PGPcdk
a704a4 ····End Project Dependency
792c9f ····Begin Project Dependency
07740a ····Project_Dep_Name PGPcl
4104a4 ····End Project Dependency
ae418b }}}
afaf5a
b02d94 ###############################################################################
baaf5a
5e786e Project: "PGPsdkNetworkLib"=..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\PGPsdkN¶
4ddb59 etworkLib.dsp - Package Owner=<4>
8daf5a
e5e41b Package=<5>
008818 {{{
bf418b }}}
ffaf5a
13bec7 Package=<4>
ba8818 {{{
bc2c9f ····Begin Project Dependency
590ce3 ····Project_Dep_Name pflCommon
cf04a4 ····End Project Dependency
de2c9f ····Begin Project Dependency
09ba3b ····Project_Dep_Name PGPcdk
3d04a4 ····End Project Dependency
f02c9f ····Begin Project Dependency
58d307 ····Project_Dep_Name liblber
5404a4 ····End Project Dependency
9e2c9f ····Begin Project Dependency
95c84c ····Project_Dep_Name libldap
3e04a4 ····End Project Dependency
5d418b }}}
48af5a
2d2d94 ###############################################################################
78af5a
0278be Project: "PGPsdkUI"=..\..\..\libs\pgpcdk\win32\PGPsdkUI\PGPsdkUI.dsp - Package ¶
6194b2 Owner=<4>
94af5a
cae41b Package=<5>
448818 {{{
ff418b }}}
cbaf5a
04bec7 Package=<4>
328818 {{{
882c9f ····Begin Project Dependency
4d0ce3 ····Project_Dep_Name pflCommon
3904a4 ····End Project Dependency
162c9f ····Begin Project Dependency
eaba3b ····Project_Dep_Name PGPcdk
8b04a4 ····End Project Dependency
63418b }}}
ecaf5a
0f2d94 ###############################################################################
1aaf5a
4390a2 Project: "TreeList"=.\TreeList.dsp - Package Owner=<4>
f1af5a
1de41b Package=<5>
5c8818 {{{
d7418b }}}
49af5a
91bec7 Package=<4>
928818 {{{
49418b }}}
00af5a
--54a3 0010251b83640110194 Page 3 of OutlookExpress.dsw
7d2d94 ###############################################################################
5aaf5a
18a53c Project: "liblber"=..\..\..\libs\network\ldaplib\win32\liblber.dsp - Package Ow¶
c26f39 ner=<4>
64af5a
4de41b Package=<5>
3f8818 {{{
ac418b }}}
f0af5a
a1bec7 Package=<4>
cc8818 {{{
b4418b }}}
49af5a
a42d94 ###############################################################################
f9af5a
6ca9a3 Project: "libldap"=..\..\..\libs\network\ldaplib\win32\libldap.dsp - Package Ow¶
c06f39 ner=<4>
8daf5a
c9e41b Package=<5>
da8818 {{{
13418b }}}
18af5a
1cbec7 Package=<4>
c38818 {{{
c9418b }}}
3baf5a
e92d94 ###############################################################################
beaf5a
282a11 Project: "pflCommon"=..\..\..\libs\pfl\win32\pflCommon\pflCommon.dsp - Package ¶
ca94b2 Owner=<4>
23af5a
8ae41b Package=<5>
698818 {{{
e5418b }}}
1faf5a
32bec7 Package=<4>
658818 {{{
11418b }}}
07af5a
b82d94 ###############################################################################
52af5a
5620da Global:
04af5a
f2e41b Package=<5>
c78818 {{{
dc418b }}}
34af5a
3832c2 Package=<3>
ef8818 {{{
8b418b }}}
02af5a
3c2d94 ###############################################################################
02af5a


--530b 00004f9268140110195 Page 1 of PGP55.DSP
b44779 # Microsoft Developer Studio Project File - Name="PGP55" - Package Owner=<4>
a9e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
868537 # ** DO NOT EDIT **
43af5a
27877a # TARGTYPE "Win32 (x86) Static Library" 0x0104
ceaf5a
54afa5 CFG=PGP55 - Win32 Debug
3c894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
385c35 !MESSAGE use the Export Makefile command and run
596309 !MESSAGE·
71cb4b !MESSAGE NMAKE /f "PGP55.MAK".
8e6309 !MESSAGE·
e3cdb3 !MESSAGE You can specify a configuration when running NMAKE
90e013 !MESSAGE by defining the macro CFG on the command line. For example:
4e6309 !MESSAGE·
b6e747 !MESSAGE NMAKE /f "PGP55.MAK" CFG="PGP55 - Win32 Debug"
ef6309 !MESSAGE·
db1dd7 !MESSAGE Possible choices for configuration are:
556309 !MESSAGE·
2a6a21 !MESSAGE "PGP55 - Win32 Release" (based on "Win32 (x86) Static Library")
6a9082 !MESSAGE "PGP55 - Win32 Debug" (based on "Win32 (x86) Static Library")
c66309 !MESSAGE·
b4af5a
203e63 # Begin Project
40b23f # PROP Scc_ProjName ""
5ddf4a # PROP Scc_LocalPath ""
2640a4 CPP=cl.exe
4aaf5a
10dd8f !IF ·"$(CFG)" == "PGP55 - Win32 Release"
a6af5a
008243 # PROP BASE Use_MFC 0
93e662 # PROP BASE Use_Debug_Libraries 0
a07d73 # PROP BASE Output_Dir "Release"
476180 # PROP BASE Intermediate_Dir "Release"
994c81 # PROP BASE Target_Dir ""
e921ad # PROP Use_MFC 0
d7b771 # PROP Use_Debug_Libraries 0
f53e11 # PROP Output_Dir ".\PGP55\Release"
60392e # PROP Intermediate_Dir ".\PGP55\Release"
7bb6fa # PROP Target_Dir ""
d54fa4 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD¶
7d9f26 ·/c
94a3e1 # ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOW¶
23c146 S" /YX /FD /c
7e18fc BSC32=bscmake.exe
ef7a24 # ADD BASE BSC32 /nologo
294f1b # ADD BSC32 /nologo
527a92 LIB32=link.exe -lib
96629d # ADD BASE LIB32 /nologo
c657a2 # ADD LIB32 /nologo
05cb10 # Begin Special Build Tool
70e5f2 SOURCE=$(InputPath)
b39710 PostBuild_Desc=Copying files into PGP55\Release
4900d8 PostBuild_Cmds=del /q PGP55\Release\*.*¤copy\
e3673d ·····EudoraPlugin\Release\pgpEudoraPlugin.dll PGP55\Release\.¤  copy\
32c29a ·····PGPadmin\Release\PGPadmin.exe PGP55\Release\.¤ copy\
4553fb ······················..\..\..\libs\pgpcdk\win32\PGPcdk\Release\PGP_SDK.dll PGP¶
921072 55\Release\.¤   copy\
aae7ba ······················..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\Release\PGPsd¶
b8d0a5 kNL.dll\
ecbeca ······················PGP55\Release\.¤  copy ·······pgpExch\Release\pgpExch.dll¶
8e3f01 ·PGP55\Release\.¤   copy\
b8d822 ············PGPkeys\Release\PGPkeys.exe ··········PGP55\Release\.¤  copy\
098515 ···················PGPlog\Release\PGPlog.exe PGP55\Release\.¤   copy PGPhk\Rele¶
255230 ase\PGP60hk.dll\
367a15 ······················PGP55\Release\.¤  copy PGPsc\Release\PGP60sc.dll PGP55\Re¶
5081ab lease\.¤copy\
76af4d ···················PGPtools\Release\PGPtools.exe PGP55\Release\.¤   copy PGPtra¶
674d0c y\Release\PGPtray.exe\
443bc1 ······················PGP55\Release\.¤  copy pgpwctx\Release\PGP60mn.dll PGP55\¶
c323ec Release\.¤  copy\
040ade ···············EudoraPluginV4\Release\pgpEudoraPluginV4.dll ·······PGP55\Releas¶
--a38b 000d897bba440110195 Page 2 of PGP55.DSP
afe7b5 e\.¤copy\
bf21a1 ··············PGPcl\Release\PGP60cl.dll PGP55\Release\.¤copy\
708e3e ······················..\..\..\libs\pgpcdk\win32\PGPsdkUI\Release\PGPsdkUI.dll ¶
e2a146 PGP55\Release\.¤copy\
2d6d74 ········OEloader\Release\msimn.exe PGP55\Release\.¤ copy\
5f363d ········OutlookExpress\Release\PGP60oe.dll PGP55\Release\.
e5b4b9 # End Special Build Tool
6baf5a
760be5 !ELSEIF ·"$(CFG)" == "PGP55 - Win32 Debug"
02af5a
178243 # PROP BASE Use_MFC 0
51ffba # PROP BASE Use_Debug_Libraries 1
8d3bf7 # PROP BASE Output_Dir "PGP55___"
91feff # PROP BASE Intermediate_Dir "PGP55___"
914c81 # PROP BASE Target_Dir ""
f121ad # PROP Use_MFC 0
fdaea9 # PROP Use_Debug_Libraries 1
406b05 # PROP Output_Dir ".\PGP55\Debug"
7a2472 # PROP Intermediate_Dir ".\PGP55\Debug"
f2b6fa # PROP Target_Dir ""
e47248 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX¶
2a10c2 ·/FD /c
ddd5f0 # ADD CPP /nologo /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D PGP_W¶
6f4f7f IN32=1 /FR /YX /FD /c
0318fc BSC32=bscmake.exe
e87a24 # ADD BASE BSC32 /nologo
604f1b # ADD BSC32 /nologo
2a7a92 LIB32=link.exe -lib
e7629d # ADD BASE LIB32 /nologo
b157a2 # ADD LIB32 /nologo
a9cb10 # Begin Special Build Tool
f1e5f2 SOURCE=$(InputPath)
e942bb PostBuild_Desc=Copying files into PGP55\Debug
4c7111 PostBuild_Cmds=del /q PGP55\Debug\*.*¤  copy\
4d0e76 ·····EudoraPlugin\Debug\pgpEudoraPlugin.dll ··············PGP55\Debug\.¤copy\
ed9383 ·····PGPadmin\Debug\PGPadmin.exe PGP55\Debug\.¤ copy\
c76b05 ······················..\..\..\libs\pgpcdk\win32\PGPcdk\Debug\PGP_SDK.dll PGP55¶
4cb49d \Debug\.¤   copy\
1ed2d7 ······················..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\Debug\PGPsdkN¶
7d3dce L.dll\
a7d8ae ······················PGP55\Debug\.¤copy ·······pgpExch\Debug\pgpExch.dll PGP55¶
cfb49d \Debug\.¤   copy\
0599e8 ············PGPkeys\Debug\PGPkeys.exe ··········PGP55\Debug\.¤  copy\
58e97a ···················PGPlog\Debug\PGPlog.exe PGP55\Debug\.¤   copy PGPhk\Debug\PG¶
c24530 P60hk.dll\
05064e ······················PGP55\Debug\.¤copy PGPsc\Debug\PGP60sc.dll PGP55\Debug\.¶
f54f98 ¤   copy\
8d821c ···················PGPtools\Debug\PGPtools.exe PGP55\Debug\.¤   copy PGPtray\De¶
a4b2ec bug\PGPtray.exe\
87f878 ······················PGP55\Debug\.¤copy pgpwctx\Debug\PGP60mn.dll PGP55\Debug\¶
40273b .¤  copy\
592910 ···············EudoraPluginV4\Debug\pgpEudoraPluginV4.dll ·······PGP55\Debug\.¶
544f98 ¤   copy\
c35c2a ··············PGPcl\Debug\PGP60cl.dll PGP55\Debug\.¤copy\
bc78fb ······················..\..\..\libs\pgpcdk\win32\PGPsdkUI\Debug\PGPsdkUI.dll PG¶
429056 P55\Debug\.¤copy\
bda799 ········OEloader\Debug\msimn.exe PGP55\Debug\.¤ copy OutlookExpress\Debug\PGP60¶
407dc7 oe.dll\
1b4c03 ········PGP55\Debug\.
0ab4b9 # End Special Build Tool
a9af5a
1130ec !ENDIF·
69af5a
b7b8a5 # Begin Target
3aaf5a
43089b # Name "PGP55 - Win32 Release"
6eaf35 # Name "PGP55 - Win32 Debug"
b1df4f # Begin Source File
edaf5a
e425d0 SOURCE=.\PGP55\main.c
366ccd # End Source File
d8e5cf # End Target
--4bde 0011bfa8a8240110195 Page 3 of PGP55.DSP
1bf262 # End Project
--1cd1 000945e2e4640110196 Page 1 of PGP55.DSW
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
4aeb32 Project: "EudoraPlugin"=.\EudoraPlugin.dsp - Package Owner=<4>
bbaf5a
41e41b Package=<5>
df8818 {{{
78418b }}}
53af5a
a4bec7 Package=<4>
028818 {{{
162c9f ····Begin Project Dependency
97ba3b ····Project_Dep_Name PGPcdk
4304a4 ····End Project Dependency
a92c9f ····Begin Project Dependency
bf7257 ····Project_Dep_Name PGPsc
8104a4 ····End Project Dependency
9e418b }}}
10af5a
3a2d94 ###############################################################################
7baf5a
0db6a3 Project: "EudoraPluginV4"=.\EudoraPluginV4.dsp - Package Owner=<4>
a1af5a
97e41b Package=<5>
5e8818 {{{
ae418b }}}
42af5a
4ebec7 Package=<4>
468818 {{{
a72c9f ····Begin Project Dependency
caba3b ····Project_Dep_Name PGPcdk
a204a4 ····End Project Dependency
9f2c9f ····Begin Project Dependency
a588c4 ····Project_Dep_Name PGPlog
1504a4 ····End Project Dependency
062c9f ····Begin Project Dependency
9a7257 ····Project_Dep_Name PGPsc
1004a4 ····End Project Dependency
9a418b }}}
05af5a
802d94 ###############################################################################
dfaf5a
b3f615 Project: "OEloader"=.\OEloader.dsp - Package Owner=<4>
b6af5a
38e41b Package=<5>
9c8818 {{{
b6418b }}}
62af5a
87bec7 Package=<4>
3f8818 {{{
58418b }}}
d3af5a
1b2d94 ###############################################################################
b8af5a
ae0da9 Project: "OutlookExpress"=.\OutlookExpress.dsp - Package Owner=<4>
23af5a
84e41b Package=<5>
d08818 {{{
b2418b }}}
e5af5a
12bec7 Package=<4>
d68818 {{{
e72c9f ····Begin Project Dependency
fcba3b ····Project_Dep_Name PGPcdk
3404a4 ····End Project Dependency
c42c9f ····Begin Project Dependency
c2740a ····Project_Dep_Name PGPcl
bc04a4 ····End Project Dependency
582c9f ····Begin Project Dependency
947257 ····Project_Dep_Name PGPsc
--743a 000f91c438d40110196 Page 2 of PGP55.DSW
ad04a4 ····End Project Dependency
a72c9f ····Begin Project Dependency
f8fd6b ····Project_Dep_Name PGPsdkUI
f204a4 ····End Project Dependency
91418b }}}
83af5a
2e2d94 ###############################################################################
9faf5a
0d188e Project: "PGP55"=.\PGP55.DSP - Package Owner=<4>
0baf5a
d3e41b Package=<5>
378818 {{{
44418b }}}
5faf5a
58bec7 Package=<4>
228818 {{{
9c2c9f ····Begin Project Dependency
9db121 ····Project_Dep_Name PGPadmin
e904a4 ····End Project Dependency
1c2c9f ····Begin Project Dependency
5271da ····Project_Dep_Name PGPkeys
9104a4 ····End Project Dependency
4a2c9f ····Begin Project Dependency
8a88c4 ····Project_Dep_Name PGPlog
6304a4 ····End Project Dependency
be2c9f ····Begin Project Dependency
f585d8 ····Project_Dep_Name PGPtools
9204a4 ····End Project Dependency
e92c9f ····Begin Project Dependency
bb85c1 ····Project_Dep_Name PGPtray
4b04a4 ····End Project Dependency
d42c9f ····Begin Project Dependency
88b2f4 ····Project_Dep_Name pgpwctx
6e04a4 ····End Project Dependency
c62c9f ····Begin Project Dependency
8aef18 ····Project_Dep_Name pgpExch
2204a4 ····End Project Dependency
b72c9f ····Begin Project Dependency
bdfd47 ····Project_Dep_Name EudoraPlugin
6204a4 ····End Project Dependency
882c9f ····Begin Project Dependency
847fdc ····Project_Dep_Name EudoraPluginV4
4104a4 ····End Project Dependency
1c2c9f ····Begin Project Dependency
24cb25 ····Project_Dep_Name OEloader
0c04a4 ····End Project Dependency
cd2c9f ····Begin Project Dependency
abedf8 ····Project_Dep_Name OutlookExpress
8f04a4 ····End Project Dependency
7a418b }}}
10af5a
922d94 ###############################################################################
36af5a
bb1a87 Project: "PGPadmin"=.\PGPadmin.dsp - Package Owner=<4>
d5af5a
27e41b Package=<5>
dd8818 {{{
17418b }}}
12af5a
0abec7 Package=<4>
bc8818 {{{
a02c9f ····Begin Project Dependency
d2ba3b ····Project_Dep_Name PGPcdk
2604a4 ····End Project Dependency
dc2c9f ····Begin Project Dependency
ce740a ····Project_Dep_Name PGPcl
5304a4 ····End Project Dependency
122c9f ····Begin Project Dependency
b00ce3 ····Project_Dep_Name pflCommon
e404a4 ····End Project Dependency
a5418b }}}
f9af5a
--0ddf 000fd40ade440110196 Page 3 of PGP55.DSW
7d2d94 ###############################################################################
5aaf5a
3ff187 Project: "PGPcdk"=..\..\..\libs\pgpcdk\win32\PGPcdk\PGPcdk.dsp - Package Owner=¶
7ebde1 <4>
a8af5a
8fe41b Package=<5>
918818 {{{
5c418b }}}
46af5a
e7bec7 Package=<4>
d18818 {{{
fc2c9f ····Begin Project Dependency
bb0ce3 ····Project_Dep_Name pflCommon
2e04a4 ····End Project Dependency
52418b }}}
1aaf5a
532d94 ###############################################################################
8eaf5a
77e0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
d9af5a
22e41b Package=<5>
a98818 {{{
93418b }}}
4eaf5a
07bec7 Package=<4>
a48818 {{{
de2c9f ····Begin Project Dependency
01143b ····Project_Dep_Name TreeList
ca04a4 ····End Project Dependency
252c9f ····Begin Project Dependency
42ba3b ····Project_Dep_Name PGPcdk
5c04a4 ····End Project Dependency
7a2c9f ····Begin Project Dependency
9aff0b ····Project_Dep_Name jpeglib
e004a4 ····End Project Dependency
e82c9f ····Begin Project Dependency
3d0ce3 ····Project_Dep_Name pflCommon
da04a4 ····End Project Dependency
522c9f ····Begin Project Dependency
4afd6b ····Project_Dep_Name PGPsdkUI
c404a4 ····End Project Dependency
8d2c9f ····Begin Project Dependency
f8dd55 ····Project_Dep_Name PGPsdkNetworkLib
0704a4 ····End Project Dependency
d7418b }}}
9eaf5a
ea2d94 ###############################################################################
2baf5a
d573c0 Project: "PGPhk"=.\PGPhk.dsp - Package Owner=<4>
43af5a
a1e41b Package=<5>
a48818 {{{
a4418b }}}
f8af5a
5dbec7 Package=<4>
c98818 {{{
f0418b }}}
00af5a
f32d94 ###############################################################################
f6af5a
05778a Project: "PGPkeys"=.\PGPkeys.dsp - Package Owner=<4>
1caf5a
39e41b Package=<5>
588818 {{{
12418b }}}
42af5a
83bec7 Package=<4>
908818 {{{
012c9f ····Begin Project Dependency
5dba3b ····Project_Dep_Name PGPcdk
3b04a4 ····End Project Dependency
fd2c9f ····Begin Project Dependency
--7d19 000a142706340110196 Page 4 of PGP55.DSW
5a740a ····Project_Dep_Name PGPcl
6004a4 ····End Project Dependency
822c9f ····Begin Project Dependency
ccdd55 ····Project_Dep_Name PGPsdkNetworkLib
2204a4 ····End Project Dependency
c92c9f ····Begin Project Dependency
1ffd6b ····Project_Dep_Name PGPsdkUI
b404a4 ····End Project Dependency
172c9f ····Begin Project Dependency
1a143b ····Project_Dep_Name TreeList
bd04a4 ····End Project Dependency
79418b }}}
bbaf5a
182d94 ###############################################################################
50af5a
8501eb Project: "PGPlog"=.\PGPlog.dsp - Package Owner=<4>
6daf5a
22e41b Package=<5>
648818 {{{
38418b }}}
d6af5a
9abec7 Package=<4>
e78818 {{{
852c9f ····Begin Project Dependency
027257 ····Project_Dep_Name PGPsc
fd04a4 ····End Project Dependency
f7418b }}}
b9af5a
642d94 ###############################################################################
ffaf5a
8b1a36 Project: "PGPsc"=.\PGPsc.dsp - Package Owner=<4>
b7af5a
b2e41b Package=<5>
f78818 {{{
63418b }}}
c1af5a
69bec7 Package=<4>
bc8818 {{{
192c9f ····Begin Project Dependency
fcba3b ····Project_Dep_Name PGPcdk
8a04a4 ····End Project Dependency
e22c9f ····Begin Project Dependency
78740a ····Project_Dep_Name PGPcl
6b04a4 ····End Project Dependency
5b2c9f ····Begin Project Dependency
470ce3 ····Project_Dep_Name pflCommon
7604a4 ····End Project Dependency
6e2c9f ····Begin Project Dependency
aa10a4 ····Project_Dep_Name PGPhk
b804a4 ····End Project Dependency
7c418b }}}
d2af5a
ba2d94 ###############################################################################
40af5a
47786e Project: "PGPsdkNetworkLib"=..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\PGPsdkN¶
c2db59 etworkLib.dsp - Package Owner=<4>
3baf5a
98e41b Package=<5>
7a8818 {{{
84418b }}}
49af5a
96bec7 Package=<4>
798818 {{{
df2c9f ····Begin Project Dependency
44d307 ····Project_Dep_Name liblber
d804a4 ····End Project Dependency
a52c9f ····Begin Project Dependency
33c84c ····Project_Dep_Name libldap
9a04a4 ····End Project Dependency
c62c9f ····Begin Project Dependency
4bba3b ····Project_Dep_Name PGPcdk
a104a4 ····End Project Dependency
--9d4c 00019a7b99240110196 Page 5 of PGP55.DSW
372c9f ····Begin Project Dependency
780ce3 ····Project_Dep_Name pflCommon
7704a4 ····End Project Dependency
a3418b }}}
9eaf5a
f52d94 ###############################################################################
f6af5a
2278be Project: "PGPsdkUI"=..\..\..\libs\pgpcdk\win32\PGPsdkUI\PGPsdkUI.dsp - Package ¶
3c94b2 Owner=<4>
5baf5a
98e41b Package=<5>
608818 {{{
ee418b }}}
f0af5a
75bec7 Package=<4>
c78818 {{{
402c9f ····Begin Project Dependency
e8ba3b ····Project_Dep_Name PGPcdk
aa04a4 ····End Project Dependency
462c9f ····Begin Project Dependency
870ce3 ····Project_Dep_Name pflCommon
a104a4 ····End Project Dependency
3b2c9f ····Begin Project Dependency
75dd55 ····Project_Dep_Name PGPsdkNetworkLib
ef04a4 ····End Project Dependency
f9418b }}}
85af5a
1b2d94 ###############################################################################
33af5a
c7054c Project: "PGPtools"=.\PGPtools.dsp - Package Owner=<4>
6baf5a
7ae41b Package=<5>
3a8818 {{{
2e418b }}}
13af5a
5bbec7 Package=<4>
c98818 {{{
702c9f ····Begin Project Dependency
927257 ····Project_Dep_Name PGPsc
2b04a4 ····End Project Dependency
fe418b }}}
a5af5a
6b2d94 ###############################################################################
77af5a
37e14f Project: "PGPtray"=.\PGPtray.dsp - Package Owner=<4>
bfaf5a
61e41b Package=<5>
ae8818 {{{
93418b }}}
45af5a
79bec7 Package=<4>
2a8818 {{{
f52c9f ····Begin Project Dependency
e47257 ····Project_Dep_Name PGPsc
9004a4 ····End Project Dependency
812c9f ····Begin Project Dependency
de10a4 ····Project_Dep_Name PGPhk
5404a4 ····End Project Dependency
09418b }}}
9daf5a
4a2d94 ###############################################################################
b8af5a
f890a2 Project: "TreeList"=.\TreeList.dsp - Package Owner=<4>
20af5a
0de41b Package=<5>
a08818 {{{
24418b }}}
4eaf5a
1bbec7 Package=<4>
658818 {{{
cb418b }}}
19af5a
--0a9b 0008b24a27140110196 Page 6 of PGP55.DSW
7d2d94 ###############################################################################
5aaf5a
c3b063 Project: "jpeglib"=..\shared\JPEG\win32\jpeglib.dsp - Package Owner=<4>
d0af5a
7fe41b Package=<5>
0a8818 {{{
a3418b }}}
1faf5a
dfbec7 Package=<4>
678818 {{{
71418b }}}
bfaf5a
dc2d94 ###############################################################################
1eaf5a
afa53c Project: "liblber"=..\..\..\libs\network\ldaplib\win32\liblber.dsp - Package Ow¶
d76f39 ner=<4>
78af5a
1fe41b Package=<5>
e18818 {{{
13418b }}}
6daf5a
1bbec7 Package=<4>
4a8818 {{{
2c418b }}}
e1af5a
392d94 ###############################################################################
77af5a
2aa9a3 Project: "libldap"=..\..\..\libs\network\ldaplib\win32\libldap.dsp - Package Ow¶
746f39 ner=<4>
68af5a
54e41b Package=<5>
8a8818 {{{
7b418b }}}
35af5a
16bec7 Package=<4>
448818 {{{
9d2c9f ····Begin Project Dependency
3c7aad ····Project_Dep_Name libthread
8b04a4 ····End Project Dependency
69418b }}}
49af5a
4d2d94 ###############################################################################
32af5a
e02a11 Project: "pflCommon"=..\..\..\libs\pfl\win32\pflCommon\pflCommon.dsp - Package ¶
bb94b2 Owner=<4>
76af5a
cee41b Package=<5>
4b8818 {{{
58418b }}}
4eaf5a
fcbec7 Package=<4>
f48818 {{{
1d418b }}}
1aaf5a
ed2d94 ###############################################################################
bbaf5a
8e2ce1 Project: "pgpExch"=.\pgpExch.dsp - Package Owner=<4>
76af5a
dde41b Package=<5>
978818 {{{
02418b }}}
75af5a
80bec7 Package=<4>
808818 {{{
e62c9f ····Begin Project Dependency
e9ba3b ····Project_Dep_Name PGPcdk
ca04a4 ····End Project Dependency
f32c9f ····Begin Project Dependency
3a7257 ····Project_Dep_Name PGPsc
9504a4 ····End Project Dependency
8c2c9f ····Begin Project Dependency
8b740a ····Project_Dep_Name PGPcl
--9705 001a9daf36240110196 Page 7 of PGP55.DSW
ad04a4 ····End Project Dependency
a72c9f ····Begin Project Dependency
430ce3 ····Project_Dep_Name pflCommon
2804a4 ····End Project Dependency
41418b }}}
3caf5a
9e2d94 ###############################################################################
e3af5a
c2800e Project: "pgpwctx"=.\Pgpwctx.dsp - Package Owner=<4>
6baf5a
48e41b Package=<5>
a18818 {{{
98418b }}}
8faf5a
b1bec7 Package=<4>
198818 {{{
702c9f ····Begin Project Dependency
147257 ····Project_Dep_Name PGPsc
6704a4 ····End Project Dependency
01418b }}}
82af5a
742d94 ###############################################################################
e1af5a
b320da Global:
d9af5a
18e41b Package=<5>
db8818 {{{
d8418b }}}
49af5a
8932c2 Package=<3>
7b8818 {{{
21418b }}}
36af5a
662d94 ###############################################################################
a9af5a
--1516 000817584a140110197 Page 1 of PGPadmin.dsp
4c3711 # Microsoft Developer Studio Project File - Name="PGPadmin" - Package Owner=<4>
4ce7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
798537 # ** DO NOT EDIT **
9daf5a
28e536 # TARGTYPE "Win32 (x86) Application" 0x0101
1faf5a
ab8bfa CFG=PGPadmin - Win32 Release
e8894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
195c35 !MESSAGE use the Export Makefile command and run
e86309 !MESSAGE·
16a044 !MESSAGE NMAKE /f "PGPadmin.mak".
a86309 !MESSAGE·
bbcdb3 !MESSAGE You can specify a configuration when running NMAKE
62e013 !MESSAGE by defining the macro CFG on the command line. For example:
e86309 !MESSAGE·
a4ff13 !MESSAGE NMAKE /f "PGPadmin.mak" CFG="PGPadmin - Win32 Release"
5c6309 !MESSAGE·
a01dd7 !MESSAGE Possible choices for configuration are:
0a6309 !MESSAGE·
65a3d7 !MESSAGE "PGPadmin - Win32 Release" (based on "Win32 (x86) Application")
d84386 !MESSAGE "PGPadmin - Win32 Debug" (based on "Win32 (x86) Application")
fc6309 !MESSAGE·
33af5a
a73e63 # Begin Project
f5b23f # PROP Scc_ProjName ""
a2df4a # PROP Scc_LocalPath ""
4b40a4 CPP=cl.exe
47a46a MTL=midl.exe
732e1f RSC=rc.exe
81af5a
8bbfdd !IF ·"$(CFG)" == "PGPadmin - Win32 Release"
eaaf5a
9c8243 # PROP BASE Use_MFC 0
9de662 # PROP BASE Use_Debug_Libraries 0
7b4681 # PROP BASE Output_Dir ".\Release"
f5ca0c # PROP BASE Intermediate_Dir ".\Release"
e24c81 # PROP BASE Target_Dir ""
d721ad # PROP Use_MFC 0
20b771 # PROP Use_Debug_Libraries 0
0bcb42 # PROP Output_Dir ".\PGPadmin\Release"
3b4a23 # PROP Intermediate_Dir ".\PGPadmin\Release"
f29ad5 # PROP Ignore_Export_Lib 0
37b6fa # PROP Target_Dir ""
d21d69 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
c697df # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\libs\pfl\common" /I "..\..\..\li¶
2419d9 bs\pfl\win32" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\libs\pfl\common\¶
dd0a60 file" /I "..\..\..\libs\pfl\common\util" /I "..\..\..\libs\pgpcdk\pub\include" ¶
24ff8d /I "..\..\..\libs\pgpcdk\win32" /I "..\shared" /I "include" /D UNFINISHED_CODE_¶
bae36e ALLOWED=1 /D PGP_WIN32=1 /D PGP_DEBUG=0 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Y¶
3111c2 u"PGPadmin.h" /FD /c
ab6c5d # SUBTRACT CPP /Fr
8e592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
47a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
13b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
5ede84 # ADD RSC /l 0x409 /d "NDEBUG"
4518fc BSC32=bscmake.exe
9a7a24 # ADD BASE BSC32 /nologo
144f1b # ADD BSC32 /nologo
08268f LINK32=link.exe
fbcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
f11165 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:wind¶
c62300 ows /machine:I386
11700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
2bb08d 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib ..\..\..\libs\p¶
f6ccb7 gpcdk\win32\PGPcdk\Release\PGP_SDK.lib .\PGPcl\Release\PGP60cl.lib ..\..\..\lib¶
049856 s\pfl\win32\pflCommon\Release\pflCommon.lib /nologo /subsystem:windows /machine¶
4a1ae3 :I386
bc5e55 # SUBTRACT LINK32 /nodefaultlib
9faf5a
88f9be !ELSEIF ·"$(CFG)" == "PGPadmin - Win32 Debug"
f7af5a
818243 # PROP BASE Use_MFC 0
--35e9 000140f07c840110197 Page 2 of PGPadmin.dsp
bcffba # PROP BASE Use_Debug_Libraries 1
fbcc98 # PROP BASE Output_Dir ".\Debug"
a6d06b # PROP BASE Intermediate_Dir ".\Debug"
2b4c81 # PROP BASE Target_Dir ""
cc21ad # PROP Use_MFC 0
74aea9 # PROP Use_Debug_Libraries 1
32e56f # PROP Output_Dir ".\PGPadmin\Debug"
b72c1c # PROP Intermediate_Dir ".\PGPadmin\Debug"
cd9ad5 # PROP Ignore_Export_Lib 0
d9b6fa # PROP Target_Dir ""
11a5f2 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
92ac8b ·/YX /c
538b42 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\libs\pfl\common" /I "..¶
de529a \..\..\libs\pfl\win32" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\libs\pf¶
447af5 l\common\file" /I "..\..\..\libs\pfl\common\util" /I "..\..\..\libs\pgpcdk\pub\¶
7cf4fe include" /I "..\..\..\libs\pgpcdk\win32" /I "..\shared" /I "include" /D "_DEBUG¶
b32ee4 " /D UNFINISHED_CODE_ALLOWED=1 /D PGP_WIN32=1 /D PGP_DEBUG=1 /D USE_PGP_LEAKS=1¶
5c44fd ·/D "WIN32" /D "_WINDOWS" /Yu"PGPadmin.h" /FD /c
22b3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
9ded08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
56699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
e00443 # ADD RSC /l 0x409 /d "_DEBUG"
9318fc BSC32=bscmake.exe
c67a24 # ADD BASE BSC32 /nologo
8b4f1b # ADD BSC32 /nologo
ef268f LINK32=link.exe
73cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
ea1165 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:wind¶
979586 ows /debug /machine:I386
f8700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
36b08d 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib ..\..\..\libs\p¶
fcffa9 gpcdk\win32\PGPcdk\Debug\PGP_SDK.lib .\PGPcl\Debug\PGP60cl.lib ..\..\..\libs\pf¶
baf3a1 l\win32\pflCommon\Debug\pflCommon.lib /nologo /subsystem:windows /debug /machin¶
5e4ec5 e:I386
845e55 # SUBTRACT LINK32 /nodefaultlib
0daf5a
0b30ec !ENDIF·
a1af5a
4ab8a5 # Begin Target
6caf5a
4b78aa # Name "PGPadmin - Win32 Release"
f6be2e # Name "PGPadmin - Win32 Debug"
8e4cc4 # Begin Group "Source Files"
11af5a
3bcd69 # PROP Default_Filter "c;cpp;rc;def"
9edf4f # Begin Source File
63af5a
20b51f SOURCE=.\PGPadmin\AdditionalDecryption.cpp
156ccd # End Source File
b4df4f # Begin Source File
d2af5a
702190 SOURCE=.\PGPadmin\ClientPrefs.cpp
136ccd # End Source File
d6df4f # Begin Source File
d6af5a
405ab4 SOURCE=.\PGPadmin\CopyInstaller.cpp
ef6ccd # End Source File
67df4f # Begin Source File
beaf5a
5a644c SOURCE=.\PGPadmin\CorpKey.cpp
d76ccd # End Source File
9adf4f # Begin Source File
1daf5a
067140 SOURCE=.\PGPadmin\CreateWiz.cpp
75ce95 # ADD CPP /Yc"PGPadmin.h"
5b6ccd # End Source File
a4df4f # Begin Source File
21af5a
7cdc60 SOURCE=.\PGPadmin\DefaultKeys.cpp
9c6ccd # End Source File
0edf4f # Begin Source File
14af5a
--56f1 000135d21bf40110197 Page 3 of PGPadmin.dsp
1067c4 SOURCE=.\PGPadmin\FindInstaller.cpp
2b6ccd # End Source File
2edf4f # Begin Source File
12af5a
ba8a18 SOURCE=.\PGPadmin\Finish.cpp
b56ccd # End Source File
39df4f # Begin Source File
ccaf5a
f72789 SOURCE=.\PGPadmin\InstallOptions.cpp
6b6ccd # End Source File
85df4f # Begin Source File
91af5a
9d3850 SOURCE=.\PGPadmin\Intro.cpp
b76ccd # End Source File
c5df4f # Begin Source File
abaf5a
aa81b6 SOURCE=.\PGPadmin\KeyGen.cpp
e66ccd # End Source File
12df4f # Begin Source File
d0af5a
e7d567 SOURCE=.\PGPadmin\License.cpp
466ccd # End Source File
48df4f # Begin Source File
2caf5a
9358b9 SOURCE=.\PGPadmin\Misc.cpp
256ccd # End Source File
f8df4f # Begin Source File
25af5a
1d4b92 SOURCE=.\PGPadmin\PassPhrase.cpp
016ccd # End Source File
02df4f # Begin Source File
6daf5a
0648cb SOURCE=.\PGPadmin\PGPadmin.cpp
65ae01 # SUBTRACT CPP /YX /Yc /Yu
d06ccd # End Source File
41df4f # Begin Source File
4aaf5a
eb238d SOURCE=.\PGPadmin\PGPadmin.rc
b1ecf1 # ADD BASE RSC /l 0x409 /i "PGPadmin"
c1a4d8 # ADD RSC /l 0x409 /i "PGPadmin" /i ".\PGPadmin"
796ccd # End Source File
badf4f # Begin Source File
65af5a
46d839 SOURCE=..\shared\pgpVersionHeader.c
ebae01 # SUBTRACT CPP /YX /Yc /Yu
896ccd # End Source File
bddf4f # Begin Source File
79af5a
226ede SOURCE=.\PGPadmin\Review.cpp
f36ccd # End Source File
03df4f # Begin Source File
6daf5a
16a1bc SOURCE=.\PGPadmin\Revoker.cpp
ef6ccd # End Source File
23df4f # Begin Source File
b7af5a
10f01e SOURCE=.\PGPadmin\ServerUpdates.cpp
ba6ccd # End Source File
16df4f # Begin Source File
a9af5a
f3891a SOURCE=.\PGPadmin\Utils.cpp
616ccd # End Source File
c03f5a # End Group
e0ba44 # Begin Group "Header Files"
9daf5a
12174d # PROP Default_Filter "h;hpp;hxx"
44df4f # Begin Source File
55af5a
ce7d57 SOURCE=.\PGPadmin\CopyInstaller.h
7d6ccd # End Source File
31df4f # Begin Source File
13af5a
--b013 0016da552b640110197 Page 4 of PGPadmin.dsp
28e5c4 SOURCE=.\PGPadmin\CreateWiz.h
956ccd # End Source File
dcdf4f # Begin Source File
5eaf5a
1730b0 SOURCE=.\PGPadmin\FindInstaller.h
2e6ccd # End Source File
75df4f # Begin Source File
77af5a
0f092e SOURCE=.\PGPadmin\PGPadmin.h
166ccd # End Source File
f7df4f # Begin Source File
39af5a
e5a0ec SOURCE=.\PGPadmin\Utils.h
df6ccd # End Source File
8d3f5a # End Group
ec8925 # Begin Group "Resource Files"
40af5a
a4296f # PROP Default_Filter "bmp;ico;gif;jpg;dlg"
c4df4f # Begin Source File
8baf5a
76970f SOURCE=.\PGPadmin\Res\admin.ico
836ccd # End Source File
1adf4f # Begin Source File
dcaf5a
c02a81 SOURCE=.\PGPadmin\Res\AdminWiz1bit.bmp
656ccd # End Source File
0adf4f # Begin Source File
7daf5a
eed540 SOURCE=.\PGPadmin\Res\AdminWiz24bit.bmp
a36ccd # End Source File
b2df4f # Begin Source File
c0af5a
185899 SOURCE=.\PGPadmin\Res\AdminWiz4bit.bmp
9b6ccd # End Source File
fedf4f # Begin Source File
63af5a
3c18b6 SOURCE=.\PGPadmin\Res\AdminWiz8bit.bmp
7e6ccd # End Source File
3edf4f # Begin Source File
5caf5a
0204c1 SOURCE=PGPadmin\..\shared\images24.bmp
e96ccd # End Source File
69df4f # Begin Source File
d8af5a
c1332c SOURCE=PGPadmin\..\shared\images4.bmp
106ccd # End Source File
743f5a # End Group
6be5cf # End Target
6df262 # End Project
--e719 000d6bfe0f740110198 Page 1 of PGPadmin.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
7b1a87 Project: "PGPadmin"=.\PGPadmin.dsp - Package Owner=<4>
fdaf5a
6ae41b Package=<5>
788818 {{{
b7418b }}}
efaf5a
83bec7 Package=<4>
928818 {{{
532c9f ····Begin Project Dependency
d2ba3b ····Project_Dep_Name PGPcdk
9d04a4 ····End Project Dependency
722c9f ····Begin Project Dependency
1e740a ····Project_Dep_Name PGPcl
ca04a4 ····End Project Dependency
c12c9f ····Begin Project Dependency
dc0ce3 ····Project_Dep_Name pflCommon
4004a4 ····End Project Dependency
7e418b }}}
e3af5a
f12d94 ###############################################################################
b8af5a
a0f187 Project: "PGPcdk"=..\..\..\libs\pgpcdk\win32\PGPcdk\PGPcdk.dsp - Package Owner=¶
2ebde1 <4>
28af5a
5ee41b Package=<5>
208818 {{{
29418b }}}
8baf5a
45bec7 Package=<4>
8b8818 {{{
762c9f ····Begin Project Dependency
dd0ce3 ····Project_Dep_Name pflCommon
9c04a4 ····End Project Dependency
08418b }}}
a6af5a
702d94 ###############################################################################
b4af5a
a8e0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
8caf5a
1ae41b Package=<5>
7e8818 {{{
dc418b }}}
6baf5a
d1bec7 Package=<4>
508818 {{{
272c9f ····Begin Project Dependency
53ba3b ····Project_Dep_Name PGPcdk
4d04a4 ····End Project Dependency
102c9f ····Begin Project Dependency
cb9050 ····Project_Dep_Name PGPcdkKeyServer
d904a4 ····End Project Dependency
762c9f ····Begin Project Dependency
38143b ····Project_Dep_Name TreeList
6e04a4 ····End Project Dependency
c82c9f ····Begin Project Dependency
efdd55 ····Project_Dep_Name PGPsdkNetworkLib
0304a4 ····End Project Dependency
da2c9f ····Begin Project Dependency
470ce3 ····Project_Dep_Name pflCommon
8d04a4 ····End Project Dependency
692c9f ····Begin Project Dependency
3dfd6b ····Project_Dep_Name PGPsdkUI
9704a4 ····End Project Dependency
d6418b }}}
44af5a
692d94 ###############################################################################
d6af5a
--d9b8 000a61ba2cc40110198 Page 2 of PGPadmin.dsw
eb786e Project: "PGPsdkNetworkLib"=..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\PGPsdkN¶
8cdb59 etworkLib.dsp - Package Owner=<4>
cfaf5a
84e41b Package=<5>
ab8818 {{{
33418b }}}
0aaf5a
36bec7 Package=<4>
5f8818 {{{
7c2c9f ····Begin Project Dependency
c6d307 ····Project_Dep_Name liblber
8904a4 ····End Project Dependency
ae2c9f ····Begin Project Dependency
5fc84c ····Project_Dep_Name libldap
4004a4 ····End Project Dependency
ca2c9f ····Begin Project Dependency
6eba3b ····Project_Dep_Name PGPcdk
c904a4 ····End Project Dependency
d8418b }}}
49af5a
3b2d94 ###############################################################################
76af5a
cb78be Project: "PGPsdkUI"=..\..\..\libs\pgpcdk\win32\PGPsdkUI\PGPsdkUI.dsp - Package ¶
4f94b2 Owner=<4>
5aaf5a
83e41b Package=<5>
aa8818 {{{
f8418b }}}
2faf5a
acbec7 Package=<4>
9f8818 {{{
2b2c9f ····Begin Project Dependency
9bba3b ····Project_Dep_Name PGPcdk
1304a4 ····End Project Dependency
f4418b }}}
ecaf5a
112d94 ###############################################################################
77af5a
2d90a2 Project: "TreeList"=.\TreeList.dsp - Package Owner=<4>
29af5a
1de41b Package=<5>
f08818 {{{
98418b }}}
b3af5a
13bec7 Package=<4>
a68818 {{{
fc418b }}}
e6af5a
f82d94 ###############################################################################
6daf5a
b8a53c Project: "liblber"=..\..\..\libs\network\ldaplib\win32\liblber.dsp - Package Ow¶
b56f39 ner=<4>
8faf5a
fbe41b Package=<5>
458818 {{{
d0418b }}}
8aaf5a
d2bec7 Package=<4>
478818 {{{
8b418b }}}
93af5a
ba2d94 ###############################################################################
3caf5a
e1a9a3 Project: "libldap"=..\..\..\libs\network\ldaplib\win32\libldap.dsp - Package Ow¶
036f39 ner=<4>
88af5a
fde41b Package=<5>
728818 {{{
83418b }}}
64af5a
45bec7 Package=<4>
a68818 {{{
--be90 0010682aa1840110198 Page 3 of PGPadmin.dsw
bf418b }}}
deaf5a
6e2d94 ###############################################################################
75af5a
6d2a11 Project: "pflCommon"=..\..\..\libs\pfl\win32\pflCommon\pflCommon.dsp - Package ¶
8b94b2 Owner=<4>
cdaf5a
89e41b Package=<5>
408818 {{{
07418b }}}
55af5a
d7bec7 Package=<4>
f58818 {{{
3a418b }}}
7eaf5a
872d94 ###############################################################################
1daf5a
6b20da Global:
f0af5a
57e41b Package=<5>
eb8818 {{{
62418b }}}
38af5a
b732c2 Package=<3>
9f8818 {{{
5e418b }}}
daaf5a
342d94 ###############################################################################
06af5a
--5dd5 000420d479740110199 Page 1 of PGPcl.dsp
c23b1d # Microsoft Developer Studio Project File - Name="PGPcl" - Package Owner=<4>
67e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
cc8537 # ** DO NOT EDIT **
faaf5a
2fa99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
b4af5a
c360eb CFG=PGPcl - Win32 Release
3d894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
0a5c35 !MESSAGE use the Export Makefile command and run
af6309 !MESSAGE·
9a8e8b !MESSAGE NMAKE /f "PGPcl.mak".
266309 !MESSAGE·
a8cdb3 !MESSAGE You can specify a configuration when running NMAKE
91e013 !MESSAGE by defining the macro CFG on the command line. For example:
fb6309 !MESSAGE·
29f2aa !MESSAGE NMAKE /f "PGPcl.mak" CFG="PGPcl - Win32 Release"
ca6309 !MESSAGE·
731dd7 !MESSAGE Possible choices for configuration are:
126309 !MESSAGE·
856252 !MESSAGE "PGPcl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
a9da8c !MESSAGE "PGPcl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
336309 !MESSAGE·
ceaf5a
973e63 # Begin Project
80b23f # PROP Scc_ProjName ""
7bdf4a # PROP Scc_LocalPath ""
7440a4 CPP=cl.exe
ffa46a MTL=midl.exe
432e1f RSC=rc.exe
fbaf5a
c1584b !IF ·"$(CFG)" == "PGPcl - Win32 Release"
26af5a
b78243 # PROP BASE Use_MFC 0
6ce662 # PROP BASE Use_Debug_Libraries 0
864681 # PROP BASE Output_Dir ".\Release"
60ca0c # PROP BASE Intermediate_Dir ".\Release"
1a4c81 # PROP BASE Target_Dir ""
7f21ad # PROP Use_MFC 0
86b771 # PROP Use_Debug_Libraries 0
782e1f # PROP Output_Dir ".\PGPcl\Release"
5a2920 # PROP Intermediate_Dir ".\PGPcl\Release"
7b9ad5 # PROP Ignore_Export_Lib 0
64b6fa # PROP Target_Dir ""
98c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
b49f26 ·/c
2db581 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\libs\pgpcdk\pub\include" /I "..\¶
aa5d59 ..\..\libs\pgpcdk\win32" /I "..\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\co¶
5dff6f mmon\file" /I "..\..\..\libs\pfl\common\util" /I "..\..\..\libs\pfl\win32\pgpAs¶
0bd52d yncDNS" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\libs\pfl\common\sortin¶
3b0b9e g" /I "..\shared" /I ".\include" /I "..\shared\JPEG\common" /D PGP_DEBUG=0 /D "¶
f71ef6 PGP_WIN32" /D "_PGPCLDLL" /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOWS" /¶
8acc73 YX /FD /I "..\..\..\libs\pfl\win32" /c
37592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
baa23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
95b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
cede84 # ADD RSC /l 0x409 /d "NDEBUG"
ee18fc BSC32=bscmake.exe
dd7a24 # ADD BASE BSC32 /nologo
c64f1b # ADD BSC32 /nologo
b9268f LINK32=link.exe
6dcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
33a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
dd5e3b ·/nologo /subsystem:windows /dll /machine:I386
8d700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
6a55b4 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comc¶
7bea38 tl32.lib ..\..\..\libs\pgpcdk\win32\pgpcdk\Release\pgp_sdk.lib treelist\release¶
9c78cb \treelist.lib ..\..\..\libs\pgpcdk\win32\pgpsdknetworklib\release\pgpsdknl.lib ¶
8d21f7 ..\..\..\libs\pgpcdk\win32\pgpsdkUI\Release\pgpsdkUI.lib ..\shared\JPEG\win32\r¶
042623 elease\jpeglib.lib ..\..\..\libs\pfl\win32\pflCommon\Release\pflCommon.lib /nol¶
19b34c ogo /subsystem:windows /dll /machine:I386 /out:".\PGPcl\Release/PGP60cl.dll"
bf5e55 # SUBTRACT LINK32 /nodefaultlib
42af5a
--41b6 0007622cb4940110199 Page 2 of PGPcl.dsp
878607 !ELSEIF ·"$(CFG)" == "PGPcl - Win32 Debug"
c3af5a
108243 # PROP BASE Use_MFC 0
87ffba # PROP BASE Use_Debug_Libraries 1
1ecc98 # PROP BASE Output_Dir ".\Debug"
a9d06b # PROP BASE Intermediate_Dir ".\Debug"
d64c81 # PROP BASE Target_Dir ""
d321ad # PROP Use_MFC 0
49aea9 # PROP Use_Debug_Libraries 1
c82b3e # PROP Output_Dir ".\PGPcl\Debug"
da6449 # PROP Intermediate_Dir ".\PGPcl\Debug"
fe9ad5 # PROP Ignore_Export_Lib 0
99b6fa # PROP Target_Dir ""
b26cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
ec8dcb DOWS" /YX /c
d88840 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\libs\pgpcdk\pub\include¶
aae529 " /I "..\..\..\libs\pgpcdk\win32" /I "..\..\..\libs\pfl\common" /I "..\..\..\li¶
d348ee bs\pfl\win32\pgpAsyncDNS" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\libs¶
2854e1 \pfl\common\util" /I "..\..\..\libs\pfl\common\file" /I "..\..\..\libs\pfl\comm¶
464060 on\sorting" /I "..\shared" /I ".\include" /I "..\shared\JPEG\common" /D "_DEBUG¶
bd2a38 " /D PGP_DEBUG=1 /D "PGP_WIN32" /D "_PGPCLDLL" /D "WIN32" /D "_WINDOWS" /D PGP_¶
002340 WIN32=1 /YX /FD /I "..\..\..\libs\pfl\win32" /c
7cb3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
29ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
d3699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
ca0443 # ADD RSC /l 0x409 /d "_DEBUG"
7418fc BSC32=bscmake.exe
a97a24 # ADD BASE BSC32 /nologo
3f4f1b # ADD BSC32 /nologo
90268f LINK32=link.exe
1ccadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
3da5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
e5c590 ·/nologo /subsystem:windows /dll /debug /machine:I386
e4700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
4a55b4 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comc¶
f69862 tl32.lib ..\..\..\libs\pgpcdk\win32\pgpcdk\Debug\pgp_sdk.lib treelist\debug\tre¶
933e98 elist.lib ..\..\..\libs\pgpcdk\win32\pgpsdknetworklib\Debug\pgpsdknl.lib ..\..\¶
c8eee4 ..\libs\pgpcdk\win32\pgpsdkUI\Debug\pgpsdkUI.lib ..\shared\JPEG\win32\debug\jpe¶
1e95eb glib.lib ..\..\..\libs\pfl\win32\pflCommon\Debug\pflCommon.lib /nologo /subsyst¶
37ff34 em:windows /dll /debug /machine:I386 /out:".\PGPcl\Debug/PGP60cl.dll"
946b9d # SUBTRACT LINK32 /verbose /nodefaultlib
6aaf5a
0b30ec !ENDIF·
97af5a
0eb8a5 # Begin Target
7baf5a
418d5f # Name "PGPcl - Win32 Release"
a222d7 # Name "PGPcl - Win32 Debug"
784cc4 # Begin Group "Source Files"
deaf5a
4a7b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
83df4f # Begin Source File
2faf5a
6efe0b SOURCE=.\PGPcl\CLabout.c
096ccd # End Source File
3fdf4f # Begin Source File
98af5a
937bd0 SOURCE=.\PGPcl\CLcache.c
d06ccd # End Source File
66df4f # Begin Source File
cbaf5a
289901 SOURCE=.\PGPcl\CLerror.c
1f6ccd # End Source File
32df4f # Begin Source File
40af5a
d02a3e SOURCE=.\PGPcl\CLexpire.c
0d6ccd # End Source File
7bdf4f # Begin Source File
87af5a
39d6dd SOURCE=.\PGPcl\CLgroups.c
156ccd # End Source File
76df4f # Begin Source File
--ec38 000d2fed3bd40110199 Page 3 of PGPcl.dsp
e0af5a
7a9843 SOURCE=.\PGPcl\CLkspref.c
5d6ccd # End Source File
4ddf4f # Begin Source File
79af5a
79e3d7 SOURCE=.\PGPcl\CLmisc.c
846ccd # End Source File
f4df4f # Begin Source File
f7af5a
35e16d SOURCE=.\PGPcl\CLphrase.c
5c6ccd # End Source File
bbdf4f # Begin Source File
62af5a
0446a6 SOURCE=.\PGPcl\CLprefs.c
036ccd # End Source File
36df4f # Begin Source File
4caf5a
7f45ff SOURCE=.\PGPcl\CLquery.c
c76ccd # End Source File
b9df4f # Begin Source File
00af5a
b5f1a7 SOURCE=.\PGPcl\CLrand.c
2b6ccd # End Source File
c3df4f # Begin Source File
f0af5a
f968d3 SOURCE=.\PGPcl\CLrecip.c
e16ccd # End Source File
94df4f # Begin Source File
b5af5a
9b3ea8 SOURCE=.\PGPcl\CLrecon.c
e56ccd # End Source File
cadf4f # Begin Source File
94af5a
025f36 SOURCE=.\PGPcl\CLsdksrv.c
586ccd # End Source File
e6df4f # Begin Source File
4daf5a
8bc5a9 SOURCE=.\PGPcl\CLselect.c
906ccd # End Source File
a9df4f # Begin Source File
3eaf5a
587ede SOURCE=.\PGPcl\CLsend.c
706ccd # End Source File
eddf4f # Begin Source File
b8af5a
94c88e SOURCE=.\PGPcl\CLserver.c
586ccd # End Source File
a3df4f # Begin Source File
1daf5a
17f9c9 SOURCE=.\PGPcl\CLsplash.c
766ccd # End Source File
afdf4f # Begin Source File
f6af5a
df4da5 SOURCE=.\PGPcl\CLsrvprf.c
136ccd # End Source File
f4df4f # Begin Source File
b5af5a
b71eda SOURCE=.\PGPcl\CLwarn.c
126ccd # End Source File
b3df4f # Begin Source File
75af5a
daa12a SOURCE=.\PGPcl\KMAddUsr.c
c76ccd # End Source File
79df4f # Begin Source File
49af5a
f51634 SOURCE=.\PGPcl\KMChange.c
3b6ccd # End Source File
92df4f # Begin Source File
7baf5a
df475d SOURCE=.\PGPcl\KMColumn.c
056ccd # End Source File
d2df4f # Begin Source File
--8710 000462a71a740110199 Page 4 of PGPcl.dsp
e0af5a
b9bd28 SOURCE=.\PGPcl\KMConvrt.c
df6ccd # End Source File
4fdf4f # Begin Source File
9faf5a
6bb8bb SOURCE=.\PGPcl\KMFocus.c
986ccd # End Source File
e0df4f # Begin Source File
7eaf5a
f47ef6 SOURCE=.\PGPcl\KMIDataObject.cpp
916ccd # End Source File
6cdf4f # Begin Source File
f2af5a
5d4ca4 SOURCE=.\PGPcl\KMIDropSource.cpp
af6ccd # End Source File
58df4f # Begin Source File
94af5a
735614 SOURCE=.\PGPcl\KMIDropTarget.cpp
8a6ccd # End Source File
87df4f # Begin Source File
73af5a
bb7812 SOURCE=.\PGPcl\KMIEnumFormatEtc.cpp
556ccd # End Source File
a6df4f # Begin Source File
afaf5a
02f8a8 SOURCE=.\PGPcl\KMKeyIO.c
bb6ccd # End Source File
4edf4f # Begin Source File
35af5a
1b35ea SOURCE=.\PGPcl\KMKeyOps.c
846ccd # End Source File
81df4f # Begin Source File
09af5a
490fda SOURCE=.\PGPcl\KMMenu.c
946ccd # End Source File
f8df4f # Begin Source File
0daf5a
c27e21 SOURCE=.\PGPcl\KMMisc.c
226ccd # End Source File
fbdf4f # Begin Source File
57af5a
2ee57e SOURCE=.\PGPcl\KMNotPrc.c
e06ccd # End Source File
ecdf4f # Begin Source File
88af5a
56574f SOURCE=.\PGPcl\KMPhoto.c
b46ccd # End Source File
d4df4f # Begin Source File
2caf5a
697254 SOURCE=.\PGPcl\KMProps.c
dd6ccd # End Source File
65df4f # Begin Source File
b4af5a
c51f4a SOURCE=.\PGPcl\KMRevoke.c
a96ccd # End Source File
01df4f # Begin Source File
bfaf5a
d85803 SOURCE=.\PGPcl\KMserver.c
1a6ccd # End Source File
47df4f # Begin Source File
3aaf5a
35030b SOURCE=.\PGPcl\KMShare.c
3b6ccd # End Source File
c4df4f # Begin Source File
88af5a
a42106 SOURCE=.\PGPcl\KMTree.c
926ccd # End Source File
f5df4f # Begin Source File
9aaf5a
ab2e78 SOURCE=.\PGPcl\KMUser.c
286ccd # End Source File
46df4f # Begin Source File
--d62f 0009d37785d40110199 Page 5 of PGPcl.dsp
e0af5a
8360ab SOURCE=.\PGPcl\PGPcl.c
506ccd # End Source File
2ddf4f # Begin Source File
82af5a
6cae25 SOURCE=.\PGPcl\PGPcl.def
f86ccd # End Source File
14df4f # Begin Source File
06af5a
32d9e7 SOURCE=.\PGPcl\PGPcl.rc
e0af5a
0b584b !IF ·"$(CFG)" == "PGPcl - Win32 Release"
21af5a
118730 # ADD BASE RSC /l 0x409 /i "PGPcl"
997eea # ADD RSC /l 0x409 /i "PGPcl" /i ".\PGPcl"
67af5a
ff8607 !ELSEIF ·"$(CFG)" == "PGPcl - Win32 Debug"
6aaf5a
d88730 # ADD BASE RSC /l 0x409 /i "PGPcl"
cf7eea # ADD RSC /l 0x409 /i "PGPcl" /i ".\PGPcl"
8faf5a
a930ec !ENDIF·
98af5a
246ccd # End Source File
1edf4f # Begin Source File
02af5a
0764c2 SOURCE=..\shared\pgpClientErrors.c
8e6ccd # End Source File
cadf4f # Begin Source File
84af5a
76dc12 SOURCE=..\shared\pgpKeyServerPrefs.c
d16ccd # End Source File
82df4f # Begin Source File
a6af5a
742630 SOURCE=.\PGPcl\PGPkm.c
b56ccd # End Source File
9bdf4f # Begin Source File
ecaf5a
62042a SOURCE=..\shared\pgpShare.c
346ccd # End Source File
12df4f # Begin Source File
b0af5a
fdfd24 SOURCE=..\shared\pgpShareFile.c
c26ccd # End Source File
c8df4f # Begin Source File
96af5a
db5ffe SOURCE=..\shared\pgpSKEP.c
d36ccd # End Source File
b23f5a # End Group
42ba44 # Begin Group "Header Files"
06af5a
a6561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
90df4f # Begin Source File
edaf5a
b695cd SOURCE=..\..\..\libs\pfl\common\pflContext.h
296ccd # End Source File
66df4f # Begin Source File
b6af5a
6b460e SOURCE=..\..\..\libs\pfl\common\pflContextPriv.h
c56ccd # End Source File
bddf4f # Begin Source File
d4af5a
afe71e SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefs.h
006ccd # End Source File
13df4f # Begin Source File
a4af5a
b5b7ae SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefTypes.h
936ccd # End Source File
d6df4f # Begin Source File
69af5a
6a97b4 SOURCE=..\..\..\libs\pfl\common\pflTypes.h
9d6ccd # End Source File
--9041 000fe88535d40110199 Page 6 of PGPcl.dsp
41df4f # Begin Source File
d0af5a
39dccc SOURCE=..\..\shared\pgpAdminPrefs.h
096ccd # End Source File
b5df4f # Begin Source File
d7af5a
f0b550 SOURCE=..\..\..\libs\pfl\common\pgpBase.h
946ccd # End Source File
1cdf4f # Begin Source File
32af5a
f70c16 SOURCE=.\include\pgpbuild.h
246ccd # End Source File
e3df4f # Begin Source File
b4af5a
280aa1 SOURCE=..\..\shared\pgpBuildFlags.h
026ccd # End Source File
5cdf4f # Begin Source File
22af5a
9bff45 SOURCE=.\INCLUDE\Help\PGPcdHlp.h
c66ccd # End Source File
17df4f # Begin Source File
4eaf5a
0ece83 SOURCE=.\PGPcl\PGPcdlgx.h
b46ccd # End Source File
82df4f # Begin Source File
e1af5a
90a283 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpCipherFeedback.h
746ccd # End Source File
18df4f # Begin Source File
c3af5a
d11d1a SOURCE=.\include\PGPcl.h
be6ccd # End Source File
3edf4f # Begin Source File
36af5a
47d5fb SOURCE=..\..\shared\pgpClientPrefs.h
4e6ccd # End Source File
c2df4f # Begin Source File
a4af5a
561a03 SOURCE=..\..\..\libs\pgpcdk\win32\pgpConfig.h
c36ccd # End Source File
bedf4f # Begin Source File
54af5a
f514e8 SOURCE=..\..\..\libs\pfl\common\pgpDebug.h
b56ccd # End Source File
d6df4f # Begin Source File
22af5a
6af43c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpEncode.h
ee6ccd # End Source File
8edf4f # Begin Source File
5eaf5a
c4b9d9 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpErrors.h
346ccd # End Source File
4adf4f # Begin Source File
27af5a
b98195 SOURCE=..\..\..\libs\pfl\common\file\pgpFileIO.h
c86ccd # End Source File
3adf4f # Begin Source File
14af5a
889034 SOURCE=..\..\..\libs\pfl\common\file\pgpFileIOPriv.h
086ccd # End Source File
7ddf4f # Begin Source File
2baf5a
1a76ed SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpec.h
b76ccd # End Source File
f4df4f # Begin Source File
47af5a
6f5cc1 SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecMacPriv.h
156ccd # End Source File
dadf4f # Begin Source File
feaf5a
3c2f98 SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecPriv.h
fe6ccd # End Source File
--748d 000d14405f040110199 Page 7 of PGPcl.dsp
41df4f # Begin Source File
d0af5a
87412d SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecStd.h
566ccd # End Source File
77df4f # Begin Source File
70af5a
191eea SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecStdPriv.h
4d6ccd # End Source File
b9df4f # Begin Source File
28af5a
365dee SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecVTBL.h
4e6ccd # End Source File
42df4f # Begin Source File
d5af5a
17c9a8 SOURCE=..\..\..\libs\pfl\common\file\pgpFileUtilities.h
fe6ccd # End Source File
d1df4f # Begin Source File
51af5a
14e1d3 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpHash.h
c66ccd # End Source File
8cdf4f # Begin Source File
d2af5a
0eb3dd SOURCE=..\..\..\libs\pfl\common\file\pgpIO.h
c56ccd # End Source File
d4df4f # Begin Source File
48af5a
54504d SOURCE=..\..\..\libs\pfl\common\file\pgpIOPriv.h
856ccd # End Source File
9fdf4f # Begin Source File
10af5a
6a160d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeys.h
e56ccd # End Source File
d4df4f # Begin Source File
15af5a
6d9abb SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeyServer.h
e46ccd # End Source File
bbdf4f # Begin Source File
94af5a
68a34b SOURCE=..\..\shared\pgpKeyServerPrefs.h
726ccd # End Source File
d8df4f # Begin Source File
87af5a
ceac30 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeyServerTypes.h
716ccd # End Source File
16df4f # Begin Source File
8aaf5a
c5519c SOURCE=..\..\..\libs\pfl\common\pgpLeaks.h
ec6ccd # End Source File
a6df4f # Begin Source File
7faf5a
5cdbb2 SOURCE=..\..\..\libs\pfl\common\pgpMem.h
076ccd # End Source File
6ddf4f # Begin Source File
70af5a
423e03 SOURCE=..\..\..\libs\pfl\win32\pgpPFLConfig.h
a96ccd # End Source File
9edf4f # Begin Source File
b8af5a
e2aafb SOURCE=..\..\..\libs\pfl\common\pgpPFLErrors.h
d46ccd # End Source File
74df4f # Begin Source File
40af5a
f240e6 SOURCE=.\include\pgpphras.h
cb6ccd # End Source File
57df4f # Begin Source File
f3af5a
f24780 SOURCE=.\PGPphrase\PGPphrsx.h
736ccd # End Source File
4adf4f # Begin Source File
0eaf5a
01307d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpPubTypes.h
d16ccd # End Source File
--652d 0001e3d56ee40110199 Page 8 of PGPcl.dsp
41df4f # Begin Source File
d0af5a
09c54f SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpRandomPool.h
426ccd # End Source File
bfdf4f # Begin Source File
9faf5a
f172a7 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSDKPrefs.h
846ccd # End Source File
9cdf4f # Begin Source File
91af5a
986824 SOURCE=..\..\..\libs\pfl\common\file\pgpStdFileIO.h
5e6ccd # End Source File
c4df4f # Begin Source File
eeaf5a
6578ac SOURCE=..\..\..\libs\pfl\common\file\pgpStdFileIOPriv.h
606ccd # End Source File
4adf4f # Begin Source File
56af5a
83e72b SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSymmetricCipher.h
a26ccd # End Source File
8ddf4f # Begin Source File
a4af5a
bf0428 SOURCE=..\..\..\libs\pfl\common\pgpTypes.h
ee6ccd # End Source File
43df4f # Begin Source File
6eaf5a
56ea6c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpUtilities.h
3a6ccd # End Source File
4bdf4f # Begin Source File
a0af5a
d16a72 SOURCE=.\include\PGPversion.h
536ccd # End Source File
b2df4f # Begin Source File
8baf5a
d162c4 SOURCE=.\INCLUDE\pgpWerr.h
996ccd # End Source File
8cdf4f # Begin Source File
33af5a
da8304 SOURCE=.\PGPcl\TimeDateWndProc.h
dd6ccd # End Source File
5edf4f # Begin Source File
f9af5a
9fe4c5 SOURCE=.\include\treelist.h
586ccd # End Source File
c43f5a # End Group
708925 # Begin Group "Resource Files"
8baf5a
baa92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
a6df4f # Begin Source File
cbaf5a
1da4c3 SOURCE=.\shared\bitmap1.bmp
686ccd # End Source File
fadf4f # Begin Source File
8faf5a
f8f117 SOURCE=.\PGPcl\Res\bizsplash1bit.bmp
626ccd # End Source File
1bdf4f # Begin Source File
46af5a
d5830f SOURCE=.\PGPcl\Res\bizsplash4bit.bmp
406ccd # End Source File
55df4f # Begin Source File
0baf5a
8ec320 SOURCE=.\PGPcl\Res\bizsplash8bit.bmp
bb6ccd # End Source File
7ddf4f # Begin Source File
1faf5a
7fd453 SOURCE=.\shared\bmp00001.bmp
c66ccd # End Source File
9ddf4f # Begin Source File
d5af5a
63b4aa SOURCE=.\PGPcl\Res\CDimag24.bmp
1e6ccd # End Source File
--21cb 000f4bf210040110199 Page 9 of PGPcl.dsp
41df4f # Begin Source File
d0af5a
e8fbc9 SOURCE=.\PGPcl\Res\CDimag4.bmp
b16ccd # End Source File
fcdf4f # Begin Source File
6eaf5a
fbbe46 SOURCE=.\PGPcl\Res\CLimag24.bmp
4e6ccd # End Source File
4adf4f # Begin Source File
dcaf5a
7d4763 SOURCE=.\PGPcl\Res\CLimag4.bmp
bc6ccd # End Source File
65df4f # Begin Source File
87af5a
0f01ab SOURCE=.\PGPcl\Res\credits1bit.bmp
736ccd # End Source File
72df4f # Begin Source File
10af5a
f773b3 SOURCE=.\PGPcl\Res\credits4bit.bmp
116ccd # End Source File
eddf4f # Begin Source File
f9af5a
7d339c SOURCE=.\PGPcl\Res\credits8bit.bmp
026ccd # End Source File
65df4f # Begin Source File
3daf5a
9d2972 SOURCE=.\PGPcl\res\eval1bit.bmp
536ccd # End Source File
e2df4f # Begin Source File
7faf5a
345b6a SOURCE=.\PGPcl\res\eval4bit.bmp
6c6ccd # End Source File
8edf4f # Begin Source File
50af5a
981b45 SOURCE=.\PGPcl\res\eval8bit.bmp
666ccd # End Source File
6cdf4f # Begin Source File
eeaf5a
5ca84f SOURCE=.\PGPcl\Res\expired.bmp
fc6ccd # End Source File
76df4f # Begin Source File
6eaf5a
007385 SOURCE=.\PGPcl\Res\freesplash1bit.BMP
116ccd # End Source File
a5df4f # Begin Source File
65af5a
0d019d SOURCE=.\PGPcl\Res\freesplash4bit.BMP
546ccd # End Source File
4adf4f # Begin Source File
91af5a
5741b2 SOURCE=.\PGPcl\Res\freesplash8bit.BMP
816ccd # End Source File
dbdf4f # Begin Source File
d1af5a
d3d397 SOURCE=.\PGPcl\Res\id1.bmp
fd6ccd # End Source File
1adf4f # Begin Source File
87af5a
f27cbf SOURCE=.\PGPcl\Res\images24.bmp
cb6ccd # End Source File
d7df4f # Begin Source File
51af5a
973336 SOURCE=.\shared\images24.bmp
366ccd # End Source File
f7df4f # Begin Source File
38af5a
0492e7 SOURCE=.\PGPcl\Res\images4.bmp
a06ccd # End Source File
c1df4f # Begin Source File
b4af5a
a4777a SOURCE=.\shared\images4.bmp
f46ccd # End Source File
--fbe0 00140a9d4d640110199 Page 10 of PGPcl.dsp
41df4f # Begin Source File
d0af5a
9e1403 SOURCE=.\PGPcl\Res\Key.ico
436ccd # End Source File
afdf4f # Begin Source File
4caf5a
e48dea SOURCE=.\PGPcl\Res\nagsplash1bit.BMP
556ccd # End Source File
62df4f # Begin Source File
d4af5a
10fff2 SOURCE=.\PGPcl\Res\nagsplash4bit.BMP
146ccd # End Source File
d4df4f # Begin Source File
0caf5a
31bfdd SOURCE=.\PGPcl\Res\nagsplash8bit.BMP
7f6ccd # End Source File
fedf4f # Begin Source File
b4af5a
fde8e4 SOURCE=.\PGPcl\Res\notavail.bmp
4f6ccd # End Source File
b3df4f # Begin Source File
30af5a
39114f SOURCE=.\PGPcl\Res\qmark.bmp
9d6ccd # End Source File
65df4f # Begin Source File
78af5a
7f4292 SOURCE=.\PGPcl\Res\revoked.bmp
386ccd # End Source File
32df4f # Begin Source File
0faf5a
eafa70 SOURCE=.\PGPcl\Res\splash1bit.bmp
e26ccd # End Source File
1edf4f # Begin Source File
14af5a
498868 SOURCE=.\PGPcl\Res\splash4bit.bmp
976ccd # End Source File
f7df4f # Begin Source File
d5af5a
abc847 SOURCE=.\PGPcl\Res\splash8bit.bmp
ab6ccd # End Source File
dd3f5a # End Group
4ee5cf # End Target
40f262 # End Project
--ebf2 0010ebfd4614011019a Page 1 of PGPcl.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
8de0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
c6af5a
fde41b Package=<5>
f88818 {{{
3f418b }}}
17af5a
e0bec7 Package=<4>
7e8818 {{{
4b418b }}}
b9af5a
f72d94 ###############################################################################
d0af5a
5620da Global:
41af5a
dee41b Package=<5>
828818 {{{
bc418b }}}
9daf5a
5232c2 Package=<3>
088818 {{{
b7418b }}}
d0af5a
642d94 ###############################################################################
0eaf5a
--8250 000cc24c6f84011019b Page 1 of PGPhk.dsp
3eb99f # Microsoft Developer Studio Project File - Name="PGPhk" - Package Owner=<4>
afe7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
dd8537 # ** DO NOT EDIT **
e6af5a
6ca99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
81af5a
6d0f96 CFG=PGPhk - Win32 Debug
0f894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
9a5c35 !MESSAGE use the Export Makefile command and run
696309 !MESSAGE·
73bb48 !MESSAGE NMAKE /f "PGPhk.mak".
f06309 !MESSAGE·
51cdb3 !MESSAGE You can specify a configuration when running NMAKE
46e013 !MESSAGE by defining the macro CFG on the command line. For example:
ec6309 !MESSAGE·
98242a !MESSAGE NMAKE /f "PGPhk.mak" CFG="PGPhk - Win32 Debug"
5f6309 !MESSAGE·
191dd7 !MESSAGE Possible choices for configuration are:
436309 !MESSAGE·
63d6da !MESSAGE "PGPhk - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
fc2337 !MESSAGE "PGPhk - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
0b6309 !MESSAGE·
e5af5a
463e63 # Begin Project
f5b23f # PROP Scc_ProjName ""
69df4a # PROP Scc_LocalPath ""
0240a4 CPP=cl.exe
34a46a MTL=midl.exe
9a2e1f RSC=rc.exe
6faf5a
961bba !IF ·"$(CFG)" == "PGPhk - Win32 Release"
4caf5a
c18243 # PROP BASE Use_MFC 0
aee662 # PROP BASE Use_Debug_Libraries 0
117d73 # PROP BASE Output_Dir "Release"
966180 # PROP BASE Intermediate_Dir "Release"
914c81 # PROP BASE Target_Dir ""
3921ad # PROP Use_MFC 0
7cb771 # PROP Use_Debug_Libraries 0
1b3a0a # PROP Output_Dir "PGPhk/Release"
57757d # PROP Intermediate_Dir "PGPhk/Release"
509ad5 # PROP Ignore_Export_Lib 0
78b6fa # PROP Target_Dir ""
5cc65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
7c10c2 ·/FD /c
5e49f8 # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD ¶
bfa99b /c
ec1e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
2c6d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
b0b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
71de84 # ADD RSC /l 0x409 /d "NDEBUG"
0218fc BSC32=bscmake.exe
f37a24 # ADD BASE BSC32 /nologo
3f4f1b # ADD BSC32 /nologo
67268f LINK32=link.exe
72cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
cda5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
c65e3b ·/nologo /subsystem:windows /dll /machine:I386
13700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
111e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
5fffdf ogo /subsystem:windows /dll /machine:I386 /out:"PGPhk/Release/PGP60hk.dll"
e4af5a
cb085d !ELSEIF ·"$(CFG)" == "PGPhk - Win32 Debug"
20af5a
f28243 # PROP BASE Use_MFC 0
d8ffba # PROP BASE Use_Debug_Libraries 1
0b54b8 # PROP BASE Output_Dir "Debug"
34198a # PROP BASE Intermediate_Dir "Debug"
074c81 # PROP BASE Target_Dir ""
e021ad # PROP Use_MFC 0
04aea9 # PROP Use_Debug_Libraries 1
ccfc9f # PROP Output_Dir "PGPhk/Debug"
--0a29 001f24f5b6e4011019b Page 2 of PGPhk.dsp
f8b834 # PROP Intermediate_Dir "PGPhk/Debug"
9d9ad5 # PROP Ignore_Export_Lib 0
9eb6fa # PROP Target_Dir ""
e46cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
d11fea DOWS" /YX /FD /c
6ca40f # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
d750ba ·/YX /FD /c
4bc0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
3ab3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
ff699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
630443 # ADD RSC /l 0x409 /d "_DEBUG"
4818fc BSC32=bscmake.exe
5a7a24 # ADD BASE BSC32 /nologo
164f1b # ADD BSC32 /nologo
fb268f LINK32=link.exe
0acadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
b4a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
e817bf ·/nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
73700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
071e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
60ac95 ogo /subsystem:windows /dll /debug /machine:I386 /out:"PGPhk/Debug/PGP60hk.dll"¶
b05d2c ·/pdbtype:sept
deaf5a
6630ec !ENDIF·
c1af5a
10b8a5 # Begin Target
99af5a
91ceae # Name "PGPhk - Win32 Release"
f5ac8d # Name "PGPhk - Win32 Debug"
584cc4 # Begin Group "Source Files"
6baf5a
f2d7c2 # PROP Default_Filter ".c"
bedf4f # Begin Source File
22af5a
ca0d87 SOURCE=.\PGPhk\hook.c
2a6ccd # End Source File
22df4f # Begin Source File
a8af5a
29880d SOURCE=.\PGPhk\pgphk.def
ec6ccd # End Source File
ec3f5a # End Group
9cba44 # Begin Group "Header Files"
e8af5a
f5fe64 # PROP Default_Filter ".h"
e6df4f # Begin Source File
2eaf5a
bc7e9f SOURCE=.\INCLUDE\PGPhk.h
816ccd # End Source File
f43f5a # End Group
028925 # Begin Group "Resource Files"
c6af5a
9524d0 # PROP Default_Filter ".rc"
71df4f # Begin Source File
63af5a
89e9fa SOURCE=.\PGPhk\PGPhk.rc
c56ccd # End Source File
843f5a # End Group
6be5cf # End Target
f2f262 # End Project
--f26a 0011f089c804011019c Page 1 of PGPhk.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
3373c0 Project: "PGPhk"=.\PGPhk.dsp - Package Owner=<4>
c1af5a
c4e41b Package=<5>
078818 {{{
36418b }}}
e3af5a
2cbec7 Package=<4>
ec8818 {{{
64418b }}}
c1af5a
6d2d94 ###############################################################################
93af5a
ed20da Global:
0eaf5a
2ee41b Package=<5>
608818 {{{
a3418b }}}
c3af5a
5e32c2 Package=<3>
f68818 {{{
cb418b }}}
64af5a
d22d94 ###############################################################################
1faf5a
--9e53 000e8d5b7d54011019d Page 1 of PGPkeys.dsp
95dbed # Microsoft Developer Studio Project File - Name="PGPkeys" - Package Owner=<4>
b5e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
748537 # ** DO NOT EDIT **
27af5a
8ae536 # TARGTYPE "Win32 (x86) Application" 0x0101
3caf5a
8ffdb8 CFG=PGPkeys - Win32 Release
11894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
c45c35 !MESSAGE use the Export Makefile command and run
616309 !MESSAGE·
13d650 !MESSAGE NMAKE /f "PGPkeys.mak".
246309 !MESSAGE·
0fcdb3 !MESSAGE You can specify a configuration when running NMAKE
63e013 !MESSAGE by defining the macro CFG on the command line. For example:
976309 !MESSAGE·
12bddc !MESSAGE NMAKE /f "PGPkeys.mak" CFG="PGPkeys - Win32 Release"
aa6309 !MESSAGE·
0b1dd7 !MESSAGE Possible choices for configuration are:
1a6309 !MESSAGE·
68d4ea !MESSAGE "PGPkeys - Win32 Release" (based on "Win32 (x86) Application")
648ef8 !MESSAGE "PGPkeys - Win32 Debug" (based on "Win32 (x86) Application")
b46309 !MESSAGE·
43af5a
0b3e63 # Begin Project
c2b23f # PROP Scc_ProjName ""
8cdf4a # PROP Scc_LocalPath ""
8b40a4 CPP=cl.exe
5fa46a MTL=midl.exe
6e2e1f RSC=rc.exe
fbaf5a
995b37 !IF ·"$(CFG)" == "PGPkeys - Win32 Release"
42af5a
238243 # PROP BASE Use_MFC 0
5fe662 # PROP BASE Use_Debug_Libraries 0
314681 # PROP BASE Output_Dir ".\Release"
c0ca0c # PROP BASE Intermediate_Dir ".\Release"
294c81 # PROP BASE Target_Dir ""
bb21ad # PROP Use_MFC 0
d3b771 # PROP Use_Debug_Libraries 0
e78d71 # PROP Output_Dir ".\PGPkeys\Release"
8fcca4 # PROP Intermediate_Dir ".\PGPkeys\Release"
509ad5 # PROP Ignore_Export_Lib 0
36b6fa # PROP Target_Dir ""
3b1d69 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
ddb581 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\libs\pgpcdk\pub\include" /I "..\¶
403acd ..\..\libs\pgpcdk\win32" /I "..\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\wi¶
68636a n32" /I "..\shared" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\libs\pfl\c¶
0b07ef ommon\file" /I "..\..\..\libs\pfl\common\util" /I ".\include" /I ".\include\hel¶
aa9c52 p" /D "PGP_WIN32" /D "UNFINISHED_CODE_ALLOWED" /D "NDEBUG" /D PGP_WIN32=1 /D "W¶
17656b IN32" /D "_WINDOWS" /YX /FD /c
9b592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
3aa23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
13b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
7ede84 # ADD RSC /l 0x409 /d "NDEBUG"
3618fc BSC32=bscmake.exe
f37a24 # ADD BASE BSC32 /nologo
1a4f1b # ADD BSC32 /nologo
38268f LINK32=link.exe
88cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
31a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
ef2ac3 ·/nologo /subsystem:windows /machine:I386
ec700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
d255b4 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comc¶
4b0f84 tl32.lib treelist\release\treelist.lib pgpcl\release\pgp60cl.lib ../../../libs/¶
76d8f2 pgpcdk/win32/pgpcdk/release/pgp_sdk.lib ../../../libs/pgpcdk/win32/pgpsdknetwor¶
5b0a4b klib/release/pgpsdknl.lib WSOCK32.lib ..\..\..\libs\pgpcdk\win32\pgpsdkUI\Relea¶
6e35d3 se\pgpsdkUI.lib /nologo /subsystem:windows /machine:I386
ffaf5a
8f8514 !ELSEIF ·"$(CFG)" == "PGPkeys - Win32 Debug"
02af5a
8f8243 # PROP BASE Use_MFC 0
e8ffba # PROP BASE Use_Debug_Libraries 1
--14fb 000c9de8fe44011019d Page 2 of PGPkeys.dsp
44cc98 # PROP BASE Output_Dir ".\Debug"
3ad06b # PROP BASE Intermediate_Dir ".\Debug"
ef4c81 # PROP BASE Target_Dir ""
1e21ad # PROP Use_MFC 0
a7aea9 # PROP Use_Debug_Libraries 1
c15808 # PROP Output_Dir ".\PGPkeys\Debug"
b85f37 # PROP Intermediate_Dir ".\PGPkeys\Debug"
909ad5 # PROP Ignore_Export_Lib 0
d9b6fa # PROP Target_Dir ""
3ba5f2 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
44ac8b ·/YX /c
708840 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\libs\pgpcdk\pub\include¶
f1e529 " /I "..\..\..\libs\pgpcdk\win32" /I "..\..\..\libs\pfl\common" /I "..\..\..\li¶
faed05 bs\pfl\win32" /I "..\shared" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\l¶
7869fa ibs\pfl\common\file" /I "..\..\..\libs\pfl\common\util" /I ".\include" /I ".\in¶
47e91b clude\help" /D "_DEBUG" /D UNFINISHED_CODE_ALLOWED=1 /D PGP_DEBUG=1 /D PGP_WIN3¶
8dfef4 2=1 /D "WIN32" /D "_WINDOWS" /FR /YX /FD /c
77d3db # SUBTRACT CPP /X
2eb3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
c4ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
db699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
5a0443 # ADD RSC /l 0x409 /d "_DEBUG"
f318fc BSC32=bscmake.exe
8e7a24 # ADD BASE BSC32 /nologo
754f1b # ADD BSC32 /nologo
d6268f LINK32=link.exe
eccadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
d6a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
855980 ·/nologo /subsystem:windows /debug /machine:I386
a3700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
1f55b4 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comc¶
efaad5 tl32.lib treelist\debug\treelist.lib pgpcl\debug\pgp60cl.lib ../../../libs/pgpc¶
52aac0 dk/win32/pgpcdk/debug/pgp_sdk.lib ../../../libs/pgpcdk/win32/pgpsdknetworklib/d¶
83a196 ebug/pgpsdknl.lib WSOCK32.lib ..\..\..\libs\pgpcdk\win32\pgpsdkUI\Debug\pgpsdkU¶
9553d1 I.lib /nologo /subsystem:windows /debug /machine:I386
f7cb10 # Begin Special Build Tool
74e5f2 SOURCE=$(InputPath)
dc76d4 PostBuild_Desc=Executing Post-Build Commands
a35d1c PostBuild_Cmds=del /F/Q pgpkeys\debug\*.dll¤copy pgpcl\debug\pgp60cl.dll\
cf27e1 ·································pgpkeys\debug¤ copy ·..\..\..\libs\pgpcdk\win3¶
3b622e 2\pgpcdk\debug\pgp_sdk.dll\
aa3302 ························pgpkeys\debug¤  copy\
c5e56e ·················..\..\..\libs\pgpcdk\win32\pgpsdknetworklib\debug\pgpsdknl.dll\
1827e1 ·································pgpkeys\debug¤ copy ·..\..\..\libs\pgpcdk\win3¶
df12f6 2\pgpsdkui\debug\pgpsdkui.dll\
b175a2 ··················pgpkeys\debug
46b4b9 # End Special Build Tool
7aaf5a
e530ec !ENDIF·
18af5a
9fb8a5 # Begin Target
e4af5a
fa28e6 # Name "PGPkeys - Win32 Release"
253901 # Name "PGPkeys - Win32 Debug"
3f4cc4 # Begin Group "Source Files"
d1af5a
587b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
47df4f # Begin Source File
24af5a
681cf1 SOURCE=.\PGPkeys\Choice.c
846ccd # End Source File
36df4f # Begin Source File
a6af5a
1952d9 SOURCE=.\PGPkeys\ChoiceProc.c
bb6ccd # End Source File
0adf4f # Begin Source File
3faf5a
527d0d SOURCE=.\PGPkeys\GMIDropTarget.cpp
256ccd # End Source File
fcdf4f # Begin Source File
fcaf5a
c9d89c SOURCE=.\PGPkeys\GMMenu.c
--ac7a 000d60c5dbb4011019d Page 3 of PGPkeys.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
d9a967 SOURCE=.\PGPkeys\GMMisc.c
866ccd # End Source File
f8df4f # Begin Source File
26af5a
c0634a SOURCE=.\PGPkeys\GMNewGrp.c
876ccd # End Source File
fadf4f # Begin Source File
ddaf5a
9c55fa SOURCE=.\PGPkeys\GMNotPrc.c
076ccd # End Source File
44df4f # Begin Source File
3faf5a
6c11c4 SOURCE=.\PGPkeys\GMOps.c
456ccd # End Source File
e7df4f # Begin Source File
fdaf5a
22f640 SOURCE=.\PGPkeys\GMTree.c
f86ccd # End Source File
90df4f # Begin Source File
feaf5a
a52bbc SOURCE=.\PGPkeys\PGPkeys.c
886ccd # End Source File
ccdf4f # Begin Source File
4eaf5a
dabd92 SOURCE=.\PGPkeys\PGPkeys.rc
e38035 # ADD BASE RSC /l 0x409 /i "PGPkeys"
6c2ab4 # ADD RSC /l 0x409 /i "PGPkeys" /i ".\PGPkeys"
086ccd # End Source File
c9df4f # Begin Source File
c8af5a
668317 SOURCE=.\PGPkeys\PKgenwiz.c
b66ccd # End Source File
3edf4f # Begin Source File
37af5a
3ed35b SOURCE=.\PGPkeys\PKMenu.c
2f6ccd # End Source File
3bdf4f # Begin Source File
6baf5a
53a2a0 SOURCE=.\PGPkeys\PKMisc.c
d06ccd # End Source File
6fdf4f # Begin Source File
10af5a
cec731 SOURCE=.\PGPkeys\PKMsgPrc.c
7d6ccd # End Source File
5bdf4f # Begin Source File
75af5a
c23f23 SOURCE=.\PGPkeys\PKTool.c
c66ccd # End Source File
afdf4f # Begin Source File
5aaf5a
b6f2f9 SOURCE=.\PGPkeys\PKUser.c
da6ccd # End Source File
a4df4f # Begin Source File
bbaf5a
cd3b83 SOURCE=.\PGPkeys\Search.c
836ccd # End Source File
6fdf4f # Begin Source File
d6af5a
476355 SOURCE=.\PGPkeys\SearchCommon.c
6f6ccd # End Source File
44df4f # Begin Source File
19af5a
74ecd7 SOURCE=.\PGPkeys\SearchFilter.c
786ccd # End Source File
1adf4f # Begin Source File
adaf5a
07bed4 SOURCE=.\PGPkeys\SearchProc.c
546ccd # End Source File
d63f5a # End Group
--1053 000a4faba654011019d Page 4 of PGPkeys.dsp
35ba44 # Begin Group "Header Files"
87af5a
db561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
f7df4f # Begin Source File
e3af5a
07f859 SOURCE=.\PGPkeys\Choice.h
266ccd # End Source File
b7df4f # Begin Source File
e9af5a
b9b671 SOURCE=.\PGPkeys\ChoiceProc.h
586ccd # End Source File
c2df4f # Begin Source File
79af5a
9795cd SOURCE=..\..\..\libs\pfl\common\pflContext.h
8a6ccd # End Source File
ccdf4f # Begin Source File
c3af5a
5f460e SOURCE=..\..\..\libs\pfl\common\pflContextPriv.h
306ccd # End Source File
a9df4f # Begin Source File
a0af5a
3ee71e SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefs.h
2d6ccd # End Source File
14df4f # Begin Source File
25af5a
c0b7ae SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefTypes.h
7a6ccd # End Source File
42df4f # Begin Source File
23af5a
2e97b4 SOURCE=..\..\..\libs\pfl\common\pflTypes.h
e36ccd # End Source File
c2df4f # Begin Source File
22af5a
b1dccc SOURCE=..\..\shared\pgpAdminPrefs.h
866ccd # End Source File
f1df4f # Begin Source File
bbaf5a
6fb550 SOURCE=..\..\..\libs\pfl\common\pgpBase.h
186ccd # End Source File
2fdf4f # Begin Source File
e7af5a
b40aa1 SOURCE=..\..\shared\pgpBuildFlags.h
c06ccd # End Source File
aadf4f # Begin Source File
bfaf5a
c4a283 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpCipherFeedback.h
126ccd # End Source File
11df4f # Begin Source File
39af5a
ebd5fb SOURCE=..\..\shared\pgpClientPrefs.h
656ccd # End Source File
afdf4f # Begin Source File
77af5a
e21a03 SOURCE=..\..\..\libs\pgpcdk\win32\pgpConfig.h
9f6ccd # End Source File
88df4f # Begin Source File
42af5a
2914e8 SOURCE=..\..\..\libs\pfl\common\pgpDebug.h
ba6ccd # End Source File
0cdf4f # Begin Source File
88af5a
8cf43c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpEncode.h
5b6ccd # End Source File
88df4f # Begin Source File
c8af5a
5cb9d9 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpErrors.h
486ccd # End Source File
7ddf4f # Begin Source File
dbaf5a
498195 SOURCE=..\..\..\libs\pfl\common\file\pgpFileIO.h
ab6ccd # End Source File
a4df4f # Begin Source File
--2f4c 0003649a16c4011019d Page 5 of PGPkeys.dsp
e0af5a
5d9034 SOURCE=..\..\..\libs\pfl\common\file\pgpFileIOPriv.h
5c6ccd # End Source File
14df4f # Begin Source File
bdaf5a
b176ed SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpec.h
7f6ccd # End Source File
eedf4f # Begin Source File
bfaf5a
af5cc1 SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecMacPriv.h
0b6ccd # End Source File
42df4f # Begin Source File
ffaf5a
c32f98 SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecPriv.h
ac6ccd # End Source File
73df4f # Begin Source File
bfaf5a
4f412d SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecStd.h
736ccd # End Source File
5edf4f # Begin Source File
eeaf5a
fb1eea SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecStdPriv.h
7e6ccd # End Source File
79df4f # Begin Source File
4aaf5a
0d5dee SOURCE=..\..\..\libs\pfl\common\file\pgpFileSpecVTBL.h
956ccd # End Source File
3cdf4f # Begin Source File
d7af5a
06c9a8 SOURCE=..\..\..\libs\pfl\common\file\pgpFileUtilities.h
836ccd # End Source File
fbdf4f # Begin Source File
08af5a
0be1d3 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpHash.h
976ccd # End Source File
9fdf4f # Begin Source File
1daf5a
17b3dd SOURCE=..\..\..\libs\pfl\common\file\pgpIO.h
786ccd # End Source File
95df4f # Begin Source File
78af5a
2f504d SOURCE=..\..\..\libs\pfl\common\file\pgpIOPriv.h
e46ccd # End Source File
58df4f # Begin Source File
52af5a
59160d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeys.h
946ccd # End Source File
96df4f # Begin Source File
46af5a
179abb SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeyServer.h
c86ccd # End Source File
9ddf4f # Begin Source File
32af5a
1cac30 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeyServerTypes.h
bc6ccd # End Source File
e0df4f # Begin Source File
4faf5a
ede1f6 SOURCE=.\PGPkeys\PGPkeysx.h
fd6ccd # End Source File
b2df4f # Begin Source File
43af5a
780b92 SOURCE=.\include\pgpkm.h
ea6ccd # End Source File
3fdf4f # Begin Source File
3aaf5a
a4519c SOURCE=..\..\..\libs\pfl\common\pgpLeaks.h
766ccd # End Source File
f7df4f # Begin Source File
19af5a
badbb2 SOURCE=..\..\..\libs\pfl\common\pgpMem.h
406ccd # End Source File
36df4f # Begin Source File
--a9a6 00092fa92694011019d Page 6 of PGPkeys.dsp
e0af5a
c13e03 SOURCE=..\..\..\libs\pfl\win32\pgpPFLConfig.h
e66ccd # End Source File
30df4f # Begin Source File
85af5a
28aafb SOURCE=..\..\..\libs\pfl\common\pgpPFLErrors.h
226ccd # End Source File
88df4f # Begin Source File
98af5a
b940e6 SOURCE=.\include\pgpphras.h
116ccd # End Source File
91df4f # Begin Source File
2aaf5a
9f3719 SOURCE=.\INCLUDE\Help\PGPpkHlp.h
ba6ccd # End Source File
6ddf4f # Begin Source File
b9af5a
25b039 SOURCE=..\libs\pgpcdk\pub\include\pgpPrefs.h
ad6ccd # End Source File
a0df4f # Begin Source File
97af5a
6a307d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpPubTypes.h
af6ccd # End Source File
d8df4f # Begin Source File
c0af5a
83c54f SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpRandomPool.h
e56ccd # End Source File
00df4f # Begin Source File
e9af5a
1372a7 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSDKPrefs.h
2e6ccd # End Source File
bedf4f # Begin Source File
d3af5a
4b78ac SOURCE=..\..\..\libs\pfl\common\file\pgpStdFileIOPriv.h
246ccd # End Source File
54df4f # Begin Source File
d9af5a
eee72b SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSymmetricCipher.h
1d6ccd # End Source File
0cdf4f # Begin Source File
8baf5a
990428 SOURCE=..\..\..\libs\pfl\common\pgpTypes.h
9c6ccd # End Source File
bfdf4f # Begin Source File
32af5a
62ea6c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpUtilities.h
ec6ccd # End Source File
a5df4f # Begin Source File
81af5a
d616e8 SOURCE=.\include\pgpversion.h
8e6ccd # End Source File
7bdf4f # Begin Source File
21af5a
3062c4 SOURCE=.\INCLUDE\pgpWerr.h
8b6ccd # End Source File
28df4f # Begin Source File
a1af5a
8083bb SOURCE=.\PGPkeys\PKVer.h
de6ccd # End Source File
98df4f # Begin Source File
71af5a
d8df2b SOURCE=.\PGPkeys\Search.h
e16ccd # End Source File
29df4f # Begin Source File
80af5a
8387fd SOURCE=.\PGPkeys\SearchCommon.h
c36ccd # End Source File
62df4f # Begin Source File
83af5a
f9087f SOURCE=.\PGPkeys\SearchFilter.h
766ccd # End Source File
92df4f # Begin Source File

--125d 0000509f36d4011019d Page 7 of PGPkeys.dsp
e0af5a
a45a7c SOURCE=.\PGPkeys\SearchProc.h
866ccd # End Source File
dbdf4f # Begin Source File
76af5a
93e4c5 SOURCE=.\include\treelist.h
f56ccd # End Source File
aa3f5a # End Group
d88925 # Begin Group "Resource Files"
b5af5a
2ba92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
21df4f # Begin Source File
8faf5a
1b2917 SOURCE=.\PGPkeys\arrowcop.cur
2c6ccd # End Source File
bddf4f # Begin Source File
07af5a
9dbcdd SOURCE=.\PGPkeys\Res\arrowcop.cur
a86ccd # End Source File
8cdf4f # Begin Source File
daaf5a
758bea SOURCE=.\PGPkeys\Res\bmp00010.bmp
f16ccd # End Source File
48df4f # Begin Source File
e2af5a
9e8fc1 SOURCE=.\PGPkeys\Res\bmp00011.bmp
da6ccd # End Source File
ebdf4f # Begin Source File
94af5a
900303 SOURCE=.\PGPkeys\Res\closelock.ico
646ccd # End Source File
87df4f # Begin Source File
ecaf5a
78f771 SOURCE=.\PGPkeys\Res\images24.bmp
646ccd # End Source File
61df4f # Begin Source File
ebaf5a
c72a33 SOURCE=PGPkeys\..\shared\images24.bmp
a06ccd # End Source File
87df4f # Begin Source File
92af5a
ce2c98 SOURCE=.\PGPkeys\Res\images4.bmp
c86ccd # End Source File
29df4f # Begin Source File
21af5a
10bbf3 SOURCE=PGPkeys\..\shared\images4.bmp
316ccd # End Source File
c6df4f # Begin Source File
b6af5a
a3d905 SOURCE=.\PGPkeys\Res\Key.ico
446ccd # End Source File
5edf4f # Begin Source File
feaf5a
413749 SOURCE=.\PGPkeys\Res\kgwiz1bit.bmp
b86ccd # End Source File
9ddf4f # Begin Source File
52af5a
059f19 SOURCE=.\PGPkeys\Res\kgwiz24bit.bmp
8a6ccd # End Source File
f4df4f # Begin Source File
2eaf5a
2d4551 SOURCE=.\PGPkeys\Res\kgwiz4bit.bmp
946ccd # End Source File
70df4f # Begin Source File
2caf5a
74057e SOURCE=.\PGPkeys\Res\kgwiz8bit.bmp
6e6ccd # End Source File
05df4f # Begin Source File
a8af5a
a96a5b SOURCE=.\PGPkeys\Res\openlock.ico
8f6ccd # End Source File
05df4f # Begin Source File

--f0f1 001d70ad9694011019d Page 8 of PGPkeys.dsp
e0af5a
21f608 SOURCE=.\PGPkeys\Res\pgpkey~21.ico
b36ccd # End Source File
94df4f # Begin Source File
41af5a
ae69dd SOURCE=.\PGPkeys\Res\pgpkey~31.ico
9d6ccd # End Source File
f7df4f # Begin Source File
19af5a
a5aec5 SOURCE=.\PGPkeys\Res\pgpkey~41.ico
486ccd # End Source File
a5df4f # Begin Source File
86af5a
2da403 SOURCE=.\PGPkeys\Res\push.bmp
3a6ccd # End Source File
a6df4f # Begin Source File
00af5a
ef5fa6 SOURCE=.\PGPkeys\Res\pushedms.bmp
5d6ccd # End Source File
5edf4f # Begin Source File
52af5a
09909e SOURCE=.\PGPkeys\Res\temp.bmp
ca6ccd # End Source File
93df4f # Begin Source File
eeaf5a
d41862 SOURCE=.\PGPkeys\Res\Toolbar24bit.bmp
046ccd # End Source File
bbdf4f # Begin Source File
28af5a
cd2ee2 SOURCE=.\PGPkeys\Res\Toolbar4bit.bmp
256ccd # End Source File
1b3f5a # End Group
a6e5cf # End Target
d7f262 # End Project
--dc56 00011d207b24011019e Page 1 of PGPkeys.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
63f187 Project: "PGPcdk"=..\..\..\libs\pgpcdk\win32\PGPcdk\PGPcdk.dsp - Package Owner=¶
f8bde1 <4>
84af5a
fde41b Package=<5>
c28818 {{{
f1418b }}}
48af5a
02bec7 Package=<4>
4e8818 {{{
76418b }}}
02af5a
682d94 ###############################################################################
73af5a
cbe0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
ffaf5a
46e41b Package=<5>
858818 {{{
b5418b }}}
14af5a
a7bec7 Package=<4>
0f8818 {{{
ae2c9f ····Begin Project Dependency
ff143b ····Project_Dep_Name TreeList
9604a4 ····End Project Dependency
d12c9f ····Begin Project Dependency
63ba3b ····Project_Dep_Name PGPcdk
a004a4 ····End Project Dependency
092c9f ····Begin Project Dependency
c1dd55 ····Project_Dep_Name PGPsdkNetworkLib
3e04a4 ····End Project Dependency
f42c9f ····Begin Project Dependency
d5fd6b ····Project_Dep_Name PGPsdkUI
7b04a4 ····End Project Dependency
e6418b }}}
f6af5a
f72d94 ###############################################################################
44af5a
44778a Project: "PGPkeys"=.\PGPkeys.dsp - Package Owner=<4>
ebaf5a
91e41b Package=<5>
fc8818 {{{
fa418b }}}
4aaf5a
81bec7 Package=<4>
9f8818 {{{
492c9f ····Begin Project Dependency
91143b ····Project_Dep_Name TreeList
2f04a4 ····End Project Dependency
282c9f ····Begin Project Dependency
539050 ····Project_Dep_Name PGPcdkKeyServer
3004a4 ····End Project Dependency
482c9f ····Begin Project Dependency
1d740a ····Project_Dep_Name PGPcl
0904a4 ····End Project Dependency
652c9f ····Begin Project Dependency
97ba3b ····Project_Dep_Name PGPcdk
db04a4 ····End Project Dependency
ec2c9f ····Begin Project Dependency
f3dd55 ····Project_Dep_Name PGPsdkNetworkLib
1004a4 ····End Project Dependency
c82c9f ····Begin Project Dependency
65fd6b ····Project_Dep_Name PGPsdkUI
e204a4 ····End Project Dependency
93418b }}}
efaf5a
d32d94 ###############################################################################
11af5a

--cc1b 001e2dfd2294011019e Page 2 of PGPkeys.dsw
eb786e Project: "PGPsdkNetworkLib"=..\..\..\libs\pgpcdk\win32\PGPsdkNetworkLib\PGPsdkN¶
8cdb59 etworkLib.dsp - Package Owner=<4>
cfaf5a
84e41b Package=<5>
ab8818 {{{
33418b }}}
0aaf5a
36bec7 Package=<4>
5f8818 {{{
7c2c9f ····Begin Project Dependency
2aba3b ····Project_Dep_Name PGPcdk
7004a4 ····End Project Dependency
b6418b }}}
42af5a
ba2d94 ###############################################################################
fdaf5a
8778be Project: "PGPsdkUI"=..\..\..\libs\pgpcdk\win32\PGPsdkUI\PGPsdkUI.dsp - Package ¶
7094b2 Owner=<4>
23af5a
8be41b Package=<5>
008818 {{{
e0418b }}}
0faf5a
9bbec7 Package=<4>
2f8818 {{{
7d2c9f ····Begin Project Dependency
90ba3b ····Project_Dep_Name PGPcdk
6804a4 ····End Project Dependency
152c9f ····Begin Project Dependency
b9dd55 ····Project_Dep_Name PGPsdkNetworkLib
2d04a4 ····End Project Dependency
36418b }}}
bcaf5a
532d94 ###############################################################################
d8af5a
bc90a2 Project: "TreeList"=.\TreeList.dsp - Package Owner=<4>
9eaf5a
dae41b Package=<5>
588818 {{{
a2418b }}}
e4af5a
eebec7 Package=<4>
bb8818 {{{
1c418b }}}
eaaf5a
e52d94 ###############################################################################
3faf5a
5520da Global:
1faf5a
36e41b Package=<5>
028818 {{{
29418b }}}
c4af5a
5732c2 Package=<3>
fb8818 {{{
55418b }}}
34af5a
672d94 ###############################################################################
e2af5a
--db4e 000682582074011019f Page 1 of PGPlog.dsp
60a9af # Microsoft Developer Studio Project File - Name="PGPlog" - Package Owner=<4>
75e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
d58537 # ** DO NOT EDIT **
07af5a
c7e536 # TARGTYPE "Win32 (x86) Application" 0x0101
14af5a
e68867 CFG=PGPlog - Win32 Release
35894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
d45c35 !MESSAGE use the Export Makefile command and run
4a6309 !MESSAGE·
5e3b36 !MESSAGE NMAKE /f "PGPlog.mak".
1a6309 !MESSAGE·
29cdb3 !MESSAGE You can specify a configuration when running NMAKE
95e013 !MESSAGE by defining the macro CFG on the command line. For example:
a26309 !MESSAGE·
8165a8 !MESSAGE NMAKE /f "PGPlog.mak" CFG="PGPlog - Win32 Release"
206309 !MESSAGE·
5e1dd7 !MESSAGE Possible choices for configuration are:
e06309 !MESSAGE·
ba8550 !MESSAGE "PGPlog - Win32 Release" (based on "Win32 (x86) Application")
48dfbe !MESSAGE "PGPlog - Win32 Debug" (based on "Win32 (x86) Application")
f26309 !MESSAGE·
4baf5a
f23e63 # Begin Project
b6b23f # PROP Scc_ProjName ""
51df4a # PROP Scc_LocalPath ""
0940a4 CPP=cl.exe
19a46a MTL=midl.exe
632e1f RSC=rc.exe
0caf5a
21ffa9 !IF ·"$(CFG)" == "PGPlog - Win32 Release"
44af5a
a38243 # PROP BASE Use_MFC 0
4de662 # PROP BASE Use_Debug_Libraries 0
6d4681 # PROP BASE Output_Dir ".\Release"
7bca0c # PROP BASE Intermediate_Dir ".\Release"
4f4c81 # PROP BASE Target_Dir ""
ea21ad # PROP Use_MFC 0
7db771 # PROP Use_Debug_Libraries 0
02f440 # PROP Output_Dir ".\PGPlog\Release"
563d33 # PROP Intermediate_Dir ".\PGPlog\Release"
269ad5 # PROP Ignore_Export_Lib 0
46b6fa # PROP Target_Dir ""
d31d69 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
13a3e1 # ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOW¶
0ec146 S" /YX /FD /c
df592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
64a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
c4b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
b1de84 # ADD RSC /l 0x409 /d "NDEBUG"
0918fc BSC32=bscmake.exe
4b7a24 # ADD BASE BSC32 /nologo
6e4f1b # ADD BSC32 /nologo
f7268f LINK32=link.exe
e3cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
23a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
112ac3 ·/nologo /subsystem:windows /machine:I386
00700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
d2e640 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib PGPs¶
878140 c\Release\PGP60sc.lib comctl32.lib /nologo /subsystem:windows /machine:I386
19af5a
bfc3c7 !ELSEIF ·"$(CFG)" == "PGPlog - Win32 Debug"
70af5a
3d8243 # PROP BASE Use_MFC 0
a8ffba # PROP BASE Use_Debug_Libraries 1
6bcc98 # PROP BASE Output_Dir ".\Debug"
e9d06b # PROP BASE Intermediate_Dir ".\Debug"
fa4c81 # PROP BASE Target_Dir ""
8a21ad # PROP Use_MFC 0
5eaea9 # PROP Use_Debug_Libraries 1
c584f9 # PROP Output_Dir ".\PGPlog\Debug"
68838e # PROP Intermediate_Dir ".\PGPlog\Debug"
--481c 000d417cbca4011019f Page 2 of PGPlog.dsp
9e9ad5 # PROP Ignore_Export_Lib 0
78b6fa # PROP Target_Dir ""
d2a5f2 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
7bac8b ·/YX /c
83894d # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\libs\pgpcdk\pub\include" /I "..\li¶
a2263d bs\pgpcdk\win32" /I "..\libs\pfl\common" /I "..\libs\pfl\win32" /D "_DEBUG" /D ¶
8a4812 "WIN32" /D "_WINDOWS" /D PGP_WIN32=1 /YX /FD /c
31b3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
10ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
16699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
430443 # ADD RSC /l 0x409 /d "_DEBUG"
7918fc BSC32=bscmake.exe
147a24 # ADD BASE BSC32 /nologo
2c4f1b # ADD BSC32 /nologo
85268f LINK32=link.exe
8acadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
31a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
255980 ·/nologo /subsystem:windows /debug /machine:I386
f3700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
5155b4 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comc¶
e7d4b5 tl32.lib PGPsc\Debug\PGP60sc.lib /nologo /subsystem:windows /debug /machine:I386
ecaf5a
7630ec !ENDIF·
b5af5a
9cb8a5 # Begin Target
beaf5a
c2a9d9 # Name "PGPlog - Win32 Release"
0515ee # Name "PGPlog - Win32 Debug"
7c4cc4 # Begin Group "Source Files"
ccaf5a
567b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
87df4f # Begin Source File
b1af5a
f282b1 SOURCE=.\PGPlog\ListMng.c
c76ccd # End Source File
19df4f # Begin Source File
fdaf5a
11ae7d SOURCE=.\PGPlog\main.c
6d6ccd # End Source File
addf4f # Begin Source File
b5af5a
67b672 SOURCE=.\PGPlog\OwnDraw.c
c46ccd # End Source File
0ddf4f # Begin Source File
60af5a
cfe779 SOURCE=.\PGPlog\PGPlog.rc
d20357 # ADD BASE RSC /l 0x409 /i "PGPlog"
09642d # ADD RSC /l 0x409 /i "PGPlog" /i ".\PGPlog"
706ccd # End Source File
133f5a # End Group
3cba44 # Begin Group "Header Files"
c8af5a
00561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
b0df4f # Begin Source File
07af5a
99e5b6 SOURCE=.\include\PGPrecip.h
616ccd # End Source File
9fdf4f # Begin Source File
a1af5a
db1ba3 SOURCE=.\include\PGPsc.h
446ccd # End Source File
753f5a # End Group
1d8925 # Begin Group "Resource Files"
3aaf5a
c1a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
4bdf4f # Begin Source File
bfaf5a
66e2cc SOURCE=.\PGPlog\res\badsig.ico
e56ccd # End Source File
1adf4f # Begin Source File
53af5a
d42e26 SOURCE=.\PGPlog\res\goodsig.ico
--e465 00170e4919c4011019f Page 3 of PGPlog.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
847e72 SOURCE=.\PGPlog\res\images24.bmp
616ccd # End Source File
0fdf4f # Begin Source File
28af5a
753336 SOURCE=.\shared\images24.bmp
356ccd # End Source File
54df4f # Begin Source File
bcaf5a
f2777a SOURCE=.\shared\images4.bmp
af6ccd # End Source File
cbdf4f # Begin Source File
dcaf5a
737e24 SOURCE=.\PGPlog\res\images4b.bmp
1a6ccd # End Source File
73df4f # Begin Source File
8eaf5a
57e119 SOURCE=.\PGPlog\res\logicon.ico
e36ccd # End Source File
18df4f # Begin Source File
4eaf5a
2b6f9f SOURCE=.\PGPlog\res\pgperror.ico
8d6ccd # End Source File
7e3f5a # End Group
fde5cf # End Target
70f262 # End Project
--9807 001d43a4d91401101a0 Page 1 of PGPlog.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
4801eb Project: "PGPlog"=.\PGPlog.dsp - Package Owner=<4>
dbaf5a
afe41b Package=<5>
e78818 {{{
7e418b }}}
39af5a
b4bec7 Package=<4>
298818 {{{
89418b }}}
7faf5a
f22d94 ###############################################################################
2faf5a
b620da Global:
14af5a
97e41b Package=<5>
478818 {{{
a3418b }}}
46af5a
a232c2 Package=<3>
d08818 {{{
8d418b }}}
4eaf5a
812d94 ###############################################################################
d4af5a
--80ab 0004dfe56ac401101a1 Page 1 of PGPsc.dsp
cb6c48 # Microsoft Developer Studio Project File - Name="PGPsc" - Package Owner=<4>
c7e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
c18537 # ** DO NOT EDIT **
84af5a
12a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
b2af5a
b6193a CFG=PGPsc - Win32 Release
11894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
5c5c35 !MESSAGE use the Export Makefile command and run
096309 !MESSAGE·
dbc0ad !MESSAGE NMAKE /f "PGPsc.mak".
166309 !MESSAGE·
97cdb3 !MESSAGE You can specify a configuration when running NMAKE
67e013 !MESSAGE by defining the macro CFG on the command line. For example:
506309 !MESSAGE·
c9ebea !MESSAGE NMAKE /f "PGPsc.mak" CFG="PGPsc - Win32 Release"
d66309 !MESSAGE·
461dd7 !MESSAGE Possible choices for configuration are:
f76309 !MESSAGE·
be23c6 !MESSAGE "PGPsc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
05c1c0 !MESSAGE "PGPsc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
206309 !MESSAGE·
c6af5a
483e63 # Begin Project
94b23f # PROP Scc_ProjName ""
fcdf4a # PROP Scc_LocalPath ""
ea40a4 CPP=cl.exe
daa46a MTL=midl.exe
722e1f RSC=rc.exe
1faf5a
239f36 !IF ·"$(CFG)" == "PGPsc - Win32 Release"
57af5a
e78243 # PROP BASE Use_MFC 0
51e662 # PROP BASE Use_Debug_Libraries 0
084681 # PROP BASE Output_Dir ".\Release"
15ca0c # PROP BASE Intermediate_Dir ".\Release"
f44c81 # PROP BASE Target_Dir ""
ea21ad # PROP Use_MFC 0
04b771 # PROP Use_Debug_Libraries 0
e6278b # PROP Output_Dir ".\PGPsc\Release"
ed20b4 # PROP Intermediate_Dir ".\PGPsc\Release"
759ad5 # PROP Ignore_Export_Lib 0
57b6fa # PROP Target_Dir ""
65c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
859f26 ·/c
3e46a5 # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\shared" /I "include" /I "shared" /I ".¶
55b202 .\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\libs\¶
4b4711 pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win32" /I "..\..\..\libs\pfl\win32¶
e94ab3 " /I "..\..\..\libs\pfl\common\file" /I "..\..\..\libs\pfl\common\util" /D "NDE¶
1b0aac BUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOWS" /D PGP_DEBUG=0 /YX /FD /c
e2592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
58a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
c6b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
ffde84 # ADD RSC /l 0x409 /d "NDEBUG"
9d18fc BSC32=bscmake.exe
9c7a24 # ADD BASE BSC32 /nologo
ec4f1b # ADD BSC32 /nologo
70268f LINK32=link.exe
33cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
1aa5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
8c5e3b ·/nologo /subsystem:windows /dll /machine:I386
2c3946 # ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg¶
ad7039 32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbc¶
99ee57 cp32.lib ..\..\..\libs\pgpcdk\win32\pgpcdk\Release\pgp_sdk.lib PGPcl\Release\PG¶
19cc66 P60cl.lib ..\..\..\libs\pgpcdk\win32\pgpsdkUI\Release\pgpsdkUI.lib ..\..\..\lib¶
03169e s\pfl\win32\pflCommon\Release\pflCommon.lib ..\..\..\libs\pgpcdk\win32\pgpsdkne¶
dc7e4d tworklib\Release\pgpsdknl.lib PGPhk\Release\PGP60hk.lib /nologo /subsystem:wind¶
360606 ows /dll /machine:I386 /out:".\PGPsc\Release/PGP60sc.dll"
48af5a
e780dd !ELSEIF ·"$(CFG)" == "PGPsc - Win32 Debug"
57af5a
4d8243 # PROP BASE Use_MFC 0
--aec2 000a26eb0f0401101a1 Page 2 of PGPsc.dsp
bcffba # PROP BASE Use_Debug_Libraries 1
fbcc98 # PROP BASE Output_Dir ".\Debug"
a6d06b # PROP BASE Intermediate_Dir ".\Debug"
2b4c81 # PROP BASE Target_Dir ""
cc21ad # PROP Use_MFC 0
74aea9 # PROP Use_Debug_Libraries 1
b66f44 # PROP Output_Dir ".\PGPsc\Debug"
4b2033 # PROP Intermediate_Dir ".\PGPsc\Debug"
7a9ad5 # PROP Ignore_Export_Lib 0
98b6fa # PROP Target_Dir ""
f86cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
798dcb DOWS" /YX /c
eb0737 # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\shared" /I "include" /I "shar¶
1338d5 ed" /I "..\..\..\libs\pfl\common" /I "..\..\..\libs\pfl\common\prefs" /I "..\..¶
3dc7ca \..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win32" /I "..\..\..\libs\¶
401aac pfl\win32" /I "..\..\..\libs\pfl\common\file" /I "..\..\..\libs\pfl\common\util¶
99962a " /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D PGP_WIN32=1 /D PGP_DEBUG=1 /YX /FD /c
a3b3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
c9ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
38699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
440443 # ADD RSC /l 0x409 /d "_DEBUG"
0418fc BSC32=bscmake.exe
987a24 # ADD BASE BSC32 /nologo
f34f1b # ADD BSC32 /nologo
0a268f LINK32=link.exe
8dcadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
a1a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
84c590 ·/nologo /subsystem:windows /dll /debug /machine:I386
353946 # ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg¶
e37039 32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbc¶
b95144 cp32.lib ..\..\..\libs\pgpcdk\win32\pgpcdk\Debug\pgp_sdk.lib PGPcl\Debug\PGP60c¶
ad7b95 l.lib ..\..\..\libs\pgpcdk\win32\pgpsdkUI\Debug\pgpsdkUI.lib ..\..\..\libs\pfl\¶
90f2ab win32\pflCommon\Debug\pflCommon.lib ..\..\..\libs\pgpcdk\win32\pgpsdknetworklib¶
6387ad \Debug\pgpsdknl.lib PGPhk\Debug\PGP60hk.lib /nologo /subsystem:windows /dll /de¶
0b66c7 bug /machine:I386 /out:".\PGPsc\Debug/PGP60sc.dll"
38af5a
fe30ec !ENDIF·
c0af5a
bab8a5 # Begin Target
20af5a
224a22 # Name "PGPsc - Win32 Release"
39240d # Name "PGPsc - Win32 Debug"
a04cc4 # Begin Group "Source Files"
78af5a
3f7b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
21df4f # Begin Source File
57af5a
b0b62d SOURCE=.\PGPsc\AddKey.c
ee6ccd # End Source File
2adf4f # Begin Source File
77af5a
b3b2fa SOURCE=.\PGPsc\Clipbrd.c
b06ccd # End Source File
48df4f # Begin Source File
11af5a
083e96 SOURCE=.\PGPsc\ClVwClip.c
016ccd # End Source File
98df4f # Begin Source File
b4af5a
123669 SOURCE=.\PGPsc\DDElog.c
426ccd # End Source File
10df4f # Begin Source File
00af5a
b84359 SOURCE=.\PGPsc\decrypt.c
936ccd # End Source File
81df4f # Begin Source File
a5af5a
5fc6b3 SOURCE=.\PGPsc\encrypt.c
286ccd # End Source File
44df4f # Begin Source File
dfaf5a
a2437e SOURCE=.\PGPsc\events.c
--8763 000835994d4401101a1 Page 3 of PGPsc.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
662191 SOURCE=.\PGPsc\main.c
906ccd # End Source File
dbdf4f # Begin Source File
22af5a
0f46fd SOURCE=..\shared\pgpDiskWiper.c
ac6ccd # End Source File
f7df4f # Begin Source File
b8af5a
4c19bd SOURCE=.\PGPsc\pgpsc.def
b06ccd # End Source File
d2df4f # Begin Source File
c6af5a
06f83f SOURCE=.\PGPsc\PGPsc.rc
8e0e56 # ADD BASE RSC /l 0x409 /i "PGPsc"
5e1dea # ADD RSC /l 0x409 /i "PGPsc" /i ".\PGPsc"
6f6ccd # End Source File
fcdf4f # Begin Source File
99af5a
18042a SOURCE=..\shared\pgpShare.c
6e6ccd # End Source File
2bdf4f # Begin Source File
42af5a
8cfd24 SOURCE=..\shared\pgpShareFile.c
166ccd # End Source File
2bdf4f # Begin Source File
60af5a
f0d839 SOURCE=..\shared\pgpVersionHeader.c
bc6ccd # End Source File
fcdf4f # Begin Source File
1faf5a
6e6767 SOURCE=.\PGPsc\recpass.c
c16ccd # End Source File
05df4f # Begin Source File
58af5a
13c562 SOURCE=.\PGPsc\SaveOpen.c
576ccd # End Source File
f7df4f # Begin Source File
85af5a
eb62e2 SOURCE=.\shared\SigEvent.c
e26ccd # End Source File
02df4f # Begin Source File
cdaf5a
6c5480 SOURCE=.\PGPsc\Tempest.c
456ccd # End Source File
29df4f # Begin Source File
9eaf5a
caac70 SOURCE=.\PGPsc\Utils.c
716ccd # End Source File
81df4f # Begin Source File
aaaf5a
275032 SOURCE=.\PGPsc\WFfat.c
006ccd # End Source File
addf4f # Begin Source File
aaaf5a
13a8ee SOURCE=.\PGPsc\WFnt.c
0a6ccd # End Source File
19df4f # Begin Source File
c5af5a
16e2cb SOURCE=.\PGPsc\WFwiz.c
776ccd # End Source File
f4df4f # Begin Source File
f6af5a
277966 SOURCE=.\PGPsc\wipe.c
c56ccd # End Source File
52df4f # Begin Source File
4daf5a
8d5e41 SOURCE=.\PGPsc\working.c
b76ccd # End Source File
833f5a # End Group
--2d4b 000e2242bc5401101a1 Page 4 of PGPsc.dsp
35ba44 # Begin Group "Header Files"
87af5a
db561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
f7df4f # Begin Source File
e3af5a
125652 SOURCE=.\PGPsc\Clipbrd.h
c96ccd # End Source File
84df4f # Begin Source File
e0af5a
1bda3e SOURCE=.\PGPsc\ClVwClip.h
7d6ccd # End Source File
c3df4f # Begin Source File
82af5a
8da7d6 SOURCE=.\PGPsc\events.h
9d6ccd # End Source File
d0df4f # Begin Source File
baaf5a
01e71e SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefs.h
616ccd # End Source File
85df4f # Begin Source File
d5af5a
76b7ae SOURCE=..\..\..\libs\pfl\common\prefs\pflPrefTypes.h
466ccd # End Source File
bcdf4f # Begin Source File
43af5a
8b97b4 SOURCE=..\..\..\libs\pfl\common\pflTypes.h
9b6ccd # End Source File
21df4f # Begin Source File
35af5a
755ef9 SOURCE=..\shared\pgpAdminPrefs.h
116ccd # End Source File
80df4f # Begin Source File
64af5a
cab550 SOURCE=..\..\..\libs\pfl\common\pgpBase.h
e46ccd # End Source File
addf4f # Begin Source File
48af5a
c58894 SOURCE=..\shared\pgpBuildFlags.h
176ccd # End Source File
81df4f # Begin Source File
24af5a
0c1d1a SOURCE=.\include\PGPcl.h
a16ccd # End Source File
d4df4f # Begin Source File
52af5a
86b357 SOURCE=..\shared\pgpClientPrefs.h
f76ccd # End Source File
bbdf4f # Begin Source File
3daf5a
941a03 SOURCE=..\..\..\libs\pgpcdk\win32\pgpConfig.h
7c6ccd # End Source File
eadf4f # Begin Source File
c1af5a
b414e8 SOURCE=..\..\..\libs\pfl\common\pgpDebug.h
026ccd # End Source File
11df4f # Begin Source File
96af5a
0ba255 SOURCE=..\shared\pgpDiskWiper.h
2d6ccd # End Source File
b9df4f # Begin Source File
faaf5a
57f43c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpEncode.h
d66ccd # End Source File
a4df4f # Begin Source File
13af5a
84b9d9 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpErrors.h
1c6ccd # End Source File
2bdf4f # Begin Source File
fcaf5a
f4c493 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpGroups.h
b26ccd # End Source File
e2df4f # Begin Source File
--541d 000b81384b8401101a1 Page 5 of PGPsc.dsp
e0af5a
1ae1d3 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpHash.h
a36ccd # End Source File
34df4f # Begin Source File
3caf5a
e5160d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeys.h
556ccd # End Source File
a1df4f # Begin Source File
f0af5a
4d9abb SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpKeyServer.h
176ccd # End Source File
f0df4f # Begin Source File
fbaf5a
6038ba SOURCE=..\shared\pgpKeyServerPrefs.h
5a6ccd # End Source File
7bdf4f # Begin Source File
f2af5a
3ecf55 SOURCE=..\..\..\libs\pfl\common\pgpMemoryMgr.h
de6ccd # End Source File
b8df4f # Begin Source File
62af5a
e4d14c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpOptionList.h
cb6ccd # End Source File
33df4f # Begin Source File
76af5a
433e03 SOURCE=..\..\..\libs\pfl\win32\pgpPFLConfig.h
266ccd # End Source File
e4df4f # Begin Source File
7aaf5a
dcaafb SOURCE=..\..\..\libs\pfl\common\pgpPFLErrors.h
a86ccd # End Source File
3adf4f # Begin Source File
4faf5a
a540e6 SOURCE=.\include\pgpphras.h
a56ccd # End Source File
27df4f # Begin Source File
48af5a
88307d SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpPubTypes.h
136ccd # End Source File
67df4f # Begin Source File
4eaf5a
de68eb SOURCE=.\INCLUDE\PGPsc.h
3f6ccd # End Source File
1bdf4f # Begin Source File
5baf5a
5072a7 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSDKPrefs.h
8a6ccd # End Source File
9ddf4f # Begin Source File
29af5a
69e72b SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpSymmetricCipher.h
f66ccd # End Source File
49df4f # Begin Source File
e0af5a
a48f73 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpTLS.h
3e6ccd # End Source File
11df4f # Begin Source File
deaf5a
890428 SOURCE=..\..\..\libs\pfl\common\pgpTypes.h
286ccd # End Source File
7ddf4f # Begin Source File
aaaf5a
c13550 SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpUserInterface.h
0d6ccd # End Source File
0ddf4f # Begin Source File
96af5a
56ea6c SOURCE=..\..\..\libs\pgpcdk\pub\include\pgpUtilities.h
856ccd # End Source File
97df4f # Begin Source File
43af5a
bc16e8 SOURCE=.\include\pgpversion.h
c66ccd # End Source File
b8df4f # Begin Source File
--22be 000605cff96401101a1 Page 6 of PGPsc.dsp
e0af5a
863c91 SOURCE=..\shared\pgpVersionHeader.h
7d6ccd # End Source File
f4df4f # Begin Source File
baaf5a
7c62c4 SOURCE=.\INCLUDE\pgpWerr.h
a86ccd # End Source File
b9df4f # Begin Source File
41af5a
d4a8c3 SOURCE=.\PGPsc\Precomp.h
d26ccd # End Source File
a8df4f # Begin Source File
6eaf5a
1d2060 SOURCE=.\PGPsc\ProgVal.h
256ccd # End Source File
03df4f # Begin Source File
0daf5a
dc83cf SOURCE=.\PGPsc\recpass.h
fa6ccd # End Source File
f8df4f # Begin Source File
d9af5a
d7a0c3 SOURCE=.\PGPsc\saveopen.h
8f6ccd # End Source File
44df4f # Begin Source File
22af5a
e1864a SOURCE=.\shared\SigEvent.h
f46ccd # End Source File
eedf4f # Begin Source File
82af5a
74b49a SOURCE=.\PGPsc\WFfat.h
476ccd # End Source File
b8df4f # Begin Source File
a4af5a
e54c46 SOURCE=.\PGPsc\WFnt.h
d66ccd # End Source File
0edf4f # Begin Source File
96af5a
520663 SOURCE=.\PGPsc\WFwiz.h
c86ccd # End Source File
5adf4f # Begin Source File
d9af5a
49bae9 SOURCE=.\PGPsc\working.h
686ccd # End Source File
4c3f5a # End Group
778925 # Begin Group "Resource Files"
aeaf5a
d9a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
a7df4f # Begin Source File
7caf5a
f4515d SOURCE=.\PGPsc\res\AEXPK.ICO
ed6ccd # End Source File
2fdf4f # Begin Source File
22af5a
f9eb62 SOURCE=.\PGPsc\res\ASC.ICO
ad6ccd # End Source File
4bdf4f # Begin Source File
92af5a
83230e SOURCE=.\PGPsc\res\fyeo.ico
a16ccd # End Source File
08df4f # Begin Source File
ecaf5a
86d883 SOURCE=.\PGPsc\res\grp.ico
356ccd # End Source File
01df4f # Begin Source File
1daf5a
71a55e SOURCE=.\PGPsc\res\icon1.ico
1d6ccd # End Source File
51df4f # Begin Source File
edaf5a
9f5bf3 SOURCE=.\PGPsc\res\ma13x24.bmp
d36ccd # End Source File
60df4f # Begin Source File
--f5b4 001616b8ebc401101a1 Page 7 of PGPsc.dsp
e0af5a
9ea5d7 SOURCE=.\PGPsc\res\PGP.ICO
2b6ccd # End Source File
41df4f # Begin Source File
a8af5a
9052c9 SOURCE=.\PGPsc\res\pgr.ico
876ccd # End Source File
05df4f # Begin Source File
d4af5a
b22ddb SOURCE=.\PGPsc\res\PRVKR.ICO
206ccd # End Source File
74df4f # Begin Source File
caaf5a
78899f SOURCE=.\PGPsc\res\PUBKR.ICO
756ccd # End Source File
2bdf4f # Begin Source File
98af5a
bc42d5 SOURCE=.\PGPsc\res\rnd.ico
fe6ccd # End Source File
26df4f # Begin Source File
c9af5a
6f93f1 SOURCE=.\PGPsc\res\shf.ico
f16ccd # End Source File
cedf4f # Begin Source File
34af5a
ddf747 SOURCE=.\PGPsc\res\SIG.ICO
8c6ccd # End Source File
5e3f5a # End Group
e7e5cf # End Target
61f262 # End Project
--fd18 00144a34b26401101a2 Page 1 of PGPsc.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
761a36 Project: "PGPsc"=.\PGPsc.dsp - Package Owner=<4>
83af5a
3ce41b Package=<5>
d28818 {{{
87418b }}}
f0af5a
66bec7 Package=<4>
728818 {{{
42418b }}}
0eaf5a
b92d94 ###############################################################################
65af5a
4d20da Global:
75af5a
7ae41b Package=<5>
898818 {{{
b3418b }}}
f1af5a
7232c2 Package=<3>
688818 {{{
a8418b }}}
41af5a
a72d94 ###############################################################################
44af5a
--a9d5 000446a212a401101a3 Page 1 of PGPtools.dsp
5817d2 # Microsoft Developer Studio Project File - Name="PGPtools" - Package Owner=<4>
c5e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
4c8537 # ** DO NOT EDIT **
0caf5a
e5e536 # TARGTYPE "Win32 (x86) Application" 0x0101
5faf5a
47ca34 CFG=PGPtools - Win32 Release
f1894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
105c35 !MESSAGE use the Export Makefile command and run
a26309 !MESSAGE·
c5bc55 !MESSAGE NMAKE /f "PGPtools.mak".
966309 !MESSAGE·
7ccdb3 !MESSAGE You can specify a configuration when running NMAKE
75e013 !MESSAGE by defining the macro CFG on the command line. For example:
626309 !MESSAGE·
210926 !MESSAGE NMAKE /f "PGPtools.mak" CFG="PGPtools - Win32 Release"
346309 !MESSAGE·
751dd7 !MESSAGE Possible choices for configuration are:
c76309 !MESSAGE·
fb5dbd !MESSAGE "PGPtools - Win32 Release" (based on "Win32 (x86) Application")
5a60ae !MESSAGE "PGPtools - Win32 Debug" (based on "Win32 (x86) Application")
786309 !MESSAGE·
20af5a
843e63 # Begin Project
44b23f # PROP Scc_ProjName ""
26df4a # PROP Scc_LocalPath ""
fd40a4 CPP=cl.exe
8da46a MTL=midl.exe
ce2e1f RSC=rc.exe
76af5a
b690ee !IF ·"$(CFG)" == "PGPtools - Win32 Release"
edaf5a
258243 # PROP BASE Use_MFC 0
9ee662 # PROP BASE Use_Debug_Libraries 0
5c4681 # PROP BASE Output_Dir ".\Release"
e0ca0c # PROP BASE Intermediate_Dir ".\Release"
5e4c81 # PROP BASE Target_Dir ""
0521ad # PROP Use_MFC 0
b6b771 # PROP Use_Debug_Libraries 0
5465e3 # PROP Output_Dir ".\PGPTools\Release"
4be482 # PROP Intermediate_Dir ".\PGPTools\Release"
2e9ad5 # PROP Ignore_Export_Lib 0
8ab6fa # PROP Target_Dir ""
2f1d69 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
b8e880 # ADD CPP /nologo /MTd /W3 /GX /O2 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_W¶
66f1aa INDOWS" /YX /FD /c
8a592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
71a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
e7b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
67de84 # ADD RSC /l 0x409 /d "NDEBUG"
ae18fc BSC32=bscmake.exe
237a24 # ADD BASE BSC32 /nologo
af4f1b # ADD BSC32 /nologo
1f268f LINK32=link.exe
d3cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
5ea5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
0b2ac3 ·/nologo /subsystem:windows /machine:I386
6b700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
b0e640 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib PGPs¶
788140 c\Release\PGP60sc.lib comctl32.lib /nologo /subsystem:windows /machine:I386
f6af5a
882bcd !ELSEIF ·"$(CFG)" == "PGPtools - Win32 Debug"
56af5a
ba8243 # PROP BASE Use_MFC 0
f8ffba # PROP BASE Use_Debug_Libraries 1
98cc98 # PROP BASE Output_Dir ".\Debug"
d7d06b # PROP BASE Intermediate_Dir ".\Debug"
b84c81 # PROP BASE Target_Dir ""
0221ad # PROP Use_MFC 0
49aea9 # PROP Use_Debug_Libraries 1
74e47b # PROP Output_Dir ".\PGPtools\Debug"
442d08 # PROP Intermediate_Dir ".\PGPtools\Debug"
--f32e 000e2069f08401101a3 Page 2 of PGPtools.dsp
9e9ad5 # PROP Ignore_Export_Lib 0
78b6fa # PROP Target_Dir ""
d2a5f2 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
7bac8b ·/YX /c
7889bd # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\libs\pfl\common\prefs" ¶
dc3ec7 /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win32" /I "..\..¶
05f6de \..\libs\pfl\common" /I "..\..\..\libs\pfl\win32" /D "_DEBUG" /D "WIN32" /D "_W¶
7ea77e INDOWS" /D PGP_WIN32=1 /YX /FD /c
3bb3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
c5ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
91699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
2f0443 # ADD RSC /l 0x409 /d "_DEBUG"
f118fc BSC32=bscmake.exe
897a24 # ADD BASE BSC32 /nologo
474f1b # ADD BSC32 /nologo
cd268f LINK32=link.exe
53cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
fba5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
9b5980 ·/nologo /subsystem:windows /debug /machine:I386
c7700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
f2e640 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib PGPs¶
e3c90e c\Debug\PGP60sc.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386
0daf5a
db30ec !ENDIF·
98af5a
7eb8a5 # Begin Target
4baf5a
d25799 # Name "PGPtools - Win32 Release"
476c5d # Name "PGPtools - Win32 Debug"
c94cc4 # Begin Group "Source Files"
3faf5a
927b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
bbdf4f # Begin Source File
90af5a
c9629a SOURCE=.\PGPtools\main.c
5c6ccd # End Source File
25df4f # Begin Source File
56af5a
9039d7 SOURCE=.\PGPtools\openfile.c
3b6ccd # End Source File
c4df4f # Begin Source File
d3af5a
52678e SOURCE=.\PGPtools\PGPtools.rc
ef868b # ADD BASE RSC /l 0x409 /i "PGPtools"
12e191 # ADD RSC /l 0x409 /i "PGPtools" /i ".\PGPtools"
726ccd # End Source File
4ddf4f # Begin Source File
c5af5a
9907c6 SOURCE=.\PGPtools\proc.c
206ccd # End Source File
793f5a # End Group
42ba44 # Begin Group "Header Files"
0baf5a
23561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
2edf4f # Begin Source File
f3af5a
88dd7f SOURCE=.\PGPtools\openfile.h
996ccd # End Source File
b7df4f # Begin Source File
0eaf5a
795346 SOURCE=.\include\PGPRecip.h
9e6ccd # End Source File
73df4f # Begin Source File
a4af5a
551ba3 SOURCE=.\include\PGPsc.h
f06ccd # End Source File
badf4f # Begin Source File
1eaf5a
87e36e SOURCE=.\PGPtools\proc.h
936ccd # End Source File
293f5a # End Group
e28925 # Begin Group "Resource Files"
--1593 00096d7d96d401101a3 Page 3 of PGPtools.dsp
e0af5a
63a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
72df4f # Begin Source File
edaf5a
a46470 SOURCE=.\PGPtools\res\DECRYPT.ICO
876ccd # End Source File
fadf4f # Begin Source File
27af5a
38a33c SOURCE=.\PGPtools\res\ENCRYPT.ICO
b26ccd # End Source File
2bdf4f # Begin Source File
9caf5a
87acd6 SOURCE=.\PGPtools\res\ENCSIGN.ICO
406ccd # End Source File
86df4f # Begin Source File
faaf5a
4cdd70 SOURCE=.\PGPtools\res\icon1.ico
a76ccd # End Source File
7ddf4f # Begin Source File
edaf5a
5ac06b SOURCE=.\PGPtools\res\KEYS.ICO
a26ccd # End Source File
79df4f # Begin Source File
7daf5a
5c5063 SOURCE=.\PGPtools\res\l4decver.ico
5a6ccd # End Source File
5bdf4f # Begin Source File
b9af5a
0fdf3a SOURCE=.\PGPtools\res\l4enc.ico
fe6ccd # End Source File
98df4f # Begin Source File
64af5a
a1687e SOURCE=.\PGPtools\res\l4encsig.ico
996ccd # End Source File
3edf4f # Begin Source File
c9af5a
b7f7db SOURCE=.\PGPtools\res\l4keys.ico
6b6ccd # End Source File
1fdf4f # Begin Source File
e5af5a
654e47 SOURCE=.\PGPtools\res\l4sig.ico
946ccd # End Source File
50df4f # Begin Source File
77af5a
b06871 SOURCE=.\PGPtools\res\l4wipe.ico
946ccd # End Source File
5fdf4f # Begin Source File
9baf5a
be3f1b SOURCE=.\PGPtools\res\l4wipev.ico
8f6ccd # End Source File
5edf4f # Begin Source File
72af5a
c95ff9 SOURCE=.\PGPtools\res\l8decver.ico
fb6ccd # End Source File
80df4f # Begin Source File
7faf5a
bf9f15 SOURCE=.\PGPtools\res\l8enc.ico
f16ccd # End Source File
c4df4f # Begin Source File
baaf5a
6367e4 SOURCE=.\PGPtools\res\l8encsig.ico
ce6ccd # End Source File
37df4f # Begin Source File
54af5a
e02e6e SOURCE=.\PGPtools\res\l8keys.ico
ae6ccd # End Source File
4ddf4f # Begin Source File
efaf5a
650e68 SOURCE=.\PGPtools\res\l8sig.ico
606ccd # End Source File
dedf4f # Begin Source File
96af5a
--be8b 000972acd78401101a3 Page 4 of PGPtools.dsp
73b1c4 SOURCE=.\PGPtools\res\l8wipe.ico
576ccd # End Source File
7cdf4f # Begin Source File
7baf5a
69dde4 SOURCE=.\PGPtools\res\l8wipev.ico
966ccd # End Source File
7adf4f # Begin Source File
50af5a
953f98 SOURCE=.\PGPtools\res\s4decver.ico
fa6ccd # End Source File
0cdf4f # Begin Source File
66af5a
71a0b4 SOURCE=.\PGPtools\res\s4enc.ico
436ccd # End Source File
1fdf4f # Begin Source File
b0af5a
c50785 SOURCE=.\PGPtools\res\s4encsig.ico
656ccd # End Source File
abdf4f # Begin Source File
cbaf5a
309ad2 SOURCE=.\PGPtools\res\s4keys.ico
6a6ccd # End Source File
44df4f # Begin Source File
28af5a
0131c9 SOURCE=.\PGPtools\res\s4sig.ico
246ccd # End Source File
b4df4f # Begin Source File
ddaf5a
910578 SOURCE=.\PGPtools\res\s4wipe.ico
6d6ccd # End Source File
14df4f # Begin Source File
d9af5a
9da2b7 SOURCE=.\PGPtools\res\s4wipev.ico
d36ccd # End Source File
3fdf4f # Begin Source File
d0af5a
bc3002 SOURCE=.\PGPtools\res\s8decver.ico
ad6ccd # End Source File
d8df4f # Begin Source File
50af5a
eee09b SOURCE=.\PGPtools\res\s8enc.ico
0b6ccd # End Source File
13df4f # Begin Source File
11af5a
6f081f SOURCE=.\PGPtools\res\s8encsig.ico
106ccd # End Source File
3ddf4f # Begin Source File
7eaf5a
ff4367 SOURCE=.\PGPtools\res\s8keys.ico
016ccd # End Source File
0adf4f # Begin Source File
0aaf5a
2471e6 SOURCE=.\PGPtools\res\s8sig.ico
2c6ccd # End Source File
32df4f # Begin Source File
a8af5a
bfdccd SOURCE=.\PGPtools\res\s8wipe.ico
206ccd # End Source File
c8df4f # Begin Source File
e6af5a
f64048 SOURCE=.\PGPtools\res\s8wipev.ico
726ccd # End Source File
92df4f # Begin Source File
50af5a
3c3fd0 SOURCE=.\PGPtools\res\SIGN.ICO
4d6ccd # End Source File
3ddf4f # Begin Source File
88af5a
287c49 SOURCE=.\PGPtools\res\smdec.ico
466ccd # End Source File
f8df4f # Begin Source File
97af5a
--6f5b 001172da9e9401101a3 Page 5 of PGPtools.dsp
4b8b74 SOURCE=.\PGPtools\res\smenc.ico
b96ccd # End Source File
0bdf4f # Begin Source File
18af5a
c0ca84 SOURCE=.\PGPtools\res\smencsig.ico
376ccd # End Source File
8edf4f # Begin Source File
69af5a
f05cf5 SOURCE=.\PGPtools\res\smkeys.ico
416ccd # End Source File
30df4f # Begin Source File
9faf5a
e2ef7e SOURCE=.\PGPtools\res\smkeys2.ico
926ccd # End Source File
84df4f # Begin Source File
faaf5a
81a34e SOURCE=.\PGPtools\res\smsign.ico
416ccd # End Source File
a8df4f # Begin Source File
80af5a
03c35f SOURCE=.\PGPtools\res\smwipe.ico
9f6ccd # End Source File
38df4f # Begin Source File
b6af5a
9de5b1 SOURCE=.\PGPtools\res\smwipe2.ico
a26ccd # End Source File
0ddf4f # Begin Source File
daaf5a
ff0dd4 SOURCE=.\PGPtools\res\TOOLSICO.ICO
7e6ccd # End Source File
a6df4f # Begin Source File
deaf5a
e05fc1 SOURCE=.\PGPtools\res\WIPE.ICO
836ccd # End Source File
313f5a # End Group
3ae5cf # End Target
17f262 # End Project
--a828 00142d6a605401101a4 Page 1 of PGPtools.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
98054c Project: "PGPtools"=.\PGPtools.dsp - Package Owner=<4>
e2af5a
26e41b Package=<5>
408818 {{{
88418b }}}
3daf5a
f3bec7 Package=<4>
0e8818 {{{
8c418b }}}
c4af5a
712d94 ###############################################################################
6daf5a
5e20da Global:
b4af5a
6de41b Package=<5>
9c8818 {{{
38418b }}}
cbaf5a
5e32c2 Package=<3>
358818 {{{
f7418b }}}
c5af5a
642d94 ###############################################################################
42af5a
--e26f 0003dedc5a0401101a5 Page 1 of PGPtray.dsp
643f1c # Microsoft Developer Studio Project File - Name="PGPtray" - Package Owner=<4>
ece7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
298537 # ** DO NOT EDIT **
94af5a
1ee536 # TARGTYPE "Win32 (x86) Application" 0x0101
23af5a
975bf7 CFG=PGPtray - Win32 Debug
1c894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
e85c35 !MESSAGE use the Export Makefile command and run
1c6309 !MESSAGE·
350b73 !MESSAGE NMAKE /f "PGPtray.mak".
866309 !MESSAGE·
08cdb3 !MESSAGE You can specify a configuration when running NMAKE
c3e013 !MESSAGE by defining the macro CFG on the command line. For example:
e66309 !MESSAGE·
018c8b !MESSAGE NMAKE /f "PGPtray.mak" CFG="PGPtray - Win32 Debug"
896309 !MESSAGE·
b61dd7 !MESSAGE Possible choices for configuration are:
dc6309 !MESSAGE·
214694 !MESSAGE "PGPtray - Win32 Release" (based on "Win32 (x86) Application")
447c29 !MESSAGE "PGPtray - Win32 Debug" (based on "Win32 (x86) Application")
8e6309 !MESSAGE·
4baf5a
5a3e63 # Begin Project
4eb23f # PROP Scc_ProjName ""
d3df4a # PROP Scc_LocalPath ""
d740a4 CPP=cl.exe
9fa46a MTL=midl.exe
f02e1f RSC=rc.exe
82af5a
709343 !IF ·"$(CFG)" == "PGPtray - Win32 Release"
83af5a
e18243 # PROP BASE Use_MFC 0
0de662 # PROP BASE Use_Debug_Libraries 0
da7d73 # PROP BASE Output_Dir "Release"
486180 # PROP BASE Intermediate_Dir "Release"
594c81 # PROP BASE Target_Dir ""
5121ad # PROP Use_MFC 0
b1b771 # PROP Use_Debug_Libraries 0
75a919 # PROP Output_Dir "PGPtray\Release"
4cae26 # PROP Intermediate_Dir "PGPtray\Release"
349ad5 # PROP Ignore_Export_Lib 0
e9b6fa # PROP Target_Dir ""
c74fa4 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD¶
fb9f26 ·/c
f1a3e1 # ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOW¶
f1c146 S" /YX /FD /c
891e73 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
196d12 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
9cb35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
bbde84 # ADD RSC /l 0x409 /d "NDEBUG"
fa18fc BSC32=bscmake.exe
cc7a24 # ADD BASE BSC32 /nologo
094f1b # ADD BSC32 /nologo
a5268f LINK32=link.exe
c6cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
eca5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
a92ac3 ·/nologo /subsystem:windows /machine:I386
e8700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
50e640 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib PGPs¶
dea8d7 c\Release\PGP60sc.lib PGPhk\Release\PGP60hk.lib /nologo /subsystem:windows /mac¶
5a1a43 hine:I386
c1af5a
8eeb9c !ELSEIF ·"$(CFG)" == "PGPtray - Win32 Debug"
43af5a
238243 # PROP BASE Use_MFC 0
a4ffba # PROP BASE Use_Debug_Libraries 1
4054b8 # PROP BASE Output_Dir "Debug"
6f198a # PROP BASE Intermediate_Dir "Debug"
404c81 # PROP BASE Target_Dir ""
2221ad # PROP Use_MFC 0
3daea9 # PROP Use_Debug_Libraries 1
--f855 001d4859c71401101a5 Page 2 of PGPtray.dsp
622948 # PROP Output_Dir "PGPtray\Debug"
d5663f # PROP Intermediate_Dir "PGPtray\Debug"
009ad5 # PROP Ignore_Export_Lib 0
1cb6fa # PROP Target_Dir ""
94a5f2 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"¶
bd50ba ·/YX /FD /c
4e23c7 # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D P¶
72549f GP_WIN32=1 /YX /FD /c
56c0da # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
53b3bb # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
71699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
420443 # ADD RSC /l 0x409 /d "_DEBUG"
e418fc BSC32=bscmake.exe
237a24 # ADD BASE BSC32 /nologo
fe4f1b # ADD BSC32 /nologo
4f268f LINK32=link.exe
71cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
d7a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
3466c6 ·/nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
b4700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
a0e640 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib PGPs¶
b7b609 c\Debug\PGP60sc.lib PGPhk\Debug\PGP60hk.lib /nologo /subsystem:windows /debug /¶
040afd machine:I386 /pdbtype:sept
65af5a
8f30ec !ENDIF·
c2af5a
e8b8a5 # Begin Target
05af5a
83e092 # Name "PGPtray - Win32 Release"
765789 # Name "PGPtray - Win32 Debug"
b34cc4 # Begin Group "Source Files"
4aaf5a
3956ed # PROP Default_Filter "c;cpp"
70df4f # Begin Source File
19af5a
b9f380 SOURCE=.\PGPtray\EnclyptorProc.c
796ccd # End Source File
d6df4f # Begin Source File
e6af5a
9a4123 SOURCE=.\PGPtray\Main.c
a76ccd # End Source File
e6df4f # Begin Source File
4daf5a
edb293 SOURCE=.\PGPtray\PGPTray.rc
786ccd # End Source File
96df4f # Begin Source File
4eaf5a
87c0c2 SOURCE=.\PGPtray\Taskbar.c
6d6ccd # End Source File
e33f5a # End Group
218925 # Begin Group "Resource Files"
71af5a
b64dc4 # PROP Default_Filter "ico;bmp"
59df4f # Begin Source File
65af5a
4e7add SOURCE=.\PGPtray\Res\Taskbar.ico
666ccd # End Source File
15df4f # Begin Source File
afaf5a
63189c SOURCE=.\PGPtray\taskbar.ico
8c6ccd # End Source File
79df4f # Begin Source File
55af5a
9df80e SOURCE=.\PGPtray\Res\ted.ico
0d6ccd # End Source File
3a3f5a # End Group
a4e5cf # End Target
d4f262 # End Project
--d5cb 001dc8bbea6401101a6 Page 1 of PGPtray.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
98e14f Project: "PGPtray"=.\PGPtray.dsp - Package Owner=<4>
bcaf5a
c3e41b Package=<5>
908818 {{{
4c418b }}}
c1af5a
ddbec7 Package=<4>
da8818 {{{
04418b }}}
14af5a
722d94 ###############################################################################
0caf5a
f520da Global:
63af5a
76e41b Package=<5>
6f8818 {{{
b6418b }}}
20af5a
5632c2 Package=<3>
cc8818 {{{
28418b }}}
54af5a
5d2d94 ###############################################################################
dcaf5a
--d87e 000b6c1f415401101a7 Page 1 of Pgpwctx.dsp
3bc483 # Microsoft Developer Studio Project File - Name="pgpwctx" - Package Owner=<4>
50e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
4a8537 # ** DO NOT EDIT **
5eaf5a
bca99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
b1af5a
12a697 CFG=pgpwctx - Win32 Release
42894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
ff5c35 !MESSAGE use the Export Makefile command and run
f36309 !MESSAGE·
819996 !MESSAGE NMAKE /f "Pgpwctx.mak".
636309 !MESSAGE·
45cdb3 !MESSAGE You can specify a configuration when running NMAKE
5fe013 !MESSAGE by defining the macro CFG on the command line. For example:
906309 !MESSAGE·
ee9c0a !MESSAGE NMAKE /f "Pgpwctx.mak" CFG="pgpwctx - Win32 Release"
6f6309 !MESSAGE·
b01dd7 !MESSAGE Possible choices for configuration are:
1a6309 !MESSAGE·
9481d1 !MESSAGE "pgpwctx - Win32 Release" (based on\
d517ca ·"Win32 (x86) Dynamic-Link Library")
8fd6aa !MESSAGE "pgpwctx - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
6b6309 !MESSAGE·
3eaf5a
863e63 # Begin Project
46b23f # PROP Scc_ProjName ""
12df4a # PROP Scc_LocalPath ""
7d40a4 CPP=cl.exe
72a46a MTL=midl.exe
d62e1f RSC=rc.exe
dbaf5a
bc8299 !IF ·"$(CFG)" == "pgpwctx - Win32 Release"
9eaf5a
e68243 # PROP BASE Use_MFC 0
7de662 # PROP BASE Use_Debug_Libraries 0
ee4681 # PROP BASE Output_Dir ".\Release"
3eca0c # PROP BASE Intermediate_Dir ".\Release"
e34c81 # PROP BASE Target_Dir ""
f021ad # PROP Use_MFC 0
f5b771 # PROP Use_Debug_Libraries 0
86855e # PROP Output_Dir ".\pgpwctx\Release"
28c48b # PROP Intermediate_Dir ".\pgpwctx\Release"
669ad5 # PROP Ignore_Export_Lib 0
b5b6fa # PROP Target_Dir ""
adc65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
579f26 ·/c
229b41 # ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WI¶
2520da NDOWS" /YX /FD /c
f6592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
34a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
d6b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
4bde84 # ADD RSC /l 0x409 /d "NDEBUG"
1418fc BSC32=bscmake.exe
2c7a24 # ADD BASE BSC32 /nologo
db4f1b # ADD BSC32 /nologo
08268f LINK32=link.exe
e7cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
b8a5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
855e3b ·/nologo /subsystem:windows /dll /machine:I386
65700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
d41e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
e1b1be ogo /subsystem:windows /dll /map /machine:I386 /out:".\pgpwctx\Release/PGP60mn.¶
0a9d44 dll"
cbaf5a
7467dd !ELSEIF ·"$(CFG)" == "pgpwctx - Win32 Debug"
26af5a
ee8243 # PROP BASE Use_MFC 0
15ffba # PROP BASE Use_Debug_Libraries 1
2ecc98 # PROP BASE Output_Dir ".\Debug"
add06b # PROP BASE Intermediate_Dir ".\Debug"
ac4c81 # PROP BASE Target_Dir ""
b621ad # PROP Use_MFC 0
--0d51 0004a6a4ec3401101a7 Page 2 of Pgpwctx.dsp
b3aea9 # PROP Use_Debug_Libraries 1
82b6a4 # PROP Output_Dir ".\pgpwctx\Debug"
16b19b # PROP Intermediate_Dir ".\pgpwctx\Debug"
259ad5 # PROP Ignore_Export_Lib 0
1db6fa # PROP Target_Dir ""
426cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
e78dcb DOWS" /YX /c
ff89bd # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\libs\pfl\common\prefs" ¶
053ec7 /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pgpcdk\win32" /I "..\..¶
57f6de \..\libs\pfl\common" /I "..\..\..\libs\pfl\win32" /D "_DEBUG" /D "WIN32" /D "_W¶
b8a77e INDOWS" /D PGP_WIN32=1 /YX /FD /c
f1b3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
d9ed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
60699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
a30443 # ADD RSC /l 0x409 /d "_DEBUG"
8118fc BSC32=bscmake.exe
807a24 # ADD BASE BSC32 /nologo
ad4f1b # ADD BSC32 /nologo
e9268f LINK32=link.exe
62cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
2da5f0 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib¶
d4c590 ·/nologo /subsystem:windows /dll /debug /machine:I386
ab700c # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi¶
231e64 32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nol¶
2aeff9 ogo /subsystem:windows /dll /debug /machine:I386 /out:".\pgpwctx\Debug/PGP60mn.¶
859d44 dll"
f0af5a
2330ec !ENDIF·
c6af5a
c4b8a5 # Begin Target
66af5a
f9f148 # Name "pgpwctx - Win32 Release"
1adbc8 # Name "pgpwctx - Win32 Debug"
804cc4 # Begin Group "Source Files"
ecaf5a
e57b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
ffdf4f # Begin Source File
b3af5a
78e096 SOURCE=.\Pgpwctx\Ctxmenu.cpp
7f6ccd # End Source File
8edf4f # Begin Source File
deaf5a
b0cade SOURCE=.\Pgpwctx\Ctxmenu.def
236ccd # End Source File
88df4f # Begin Source File
acaf5a
96fb2b SOURCE=.\Pgpwctx\Pgpwctx.cpp
aa6ccd # End Source File
6cdf4f # Begin Source File
4daf5a
a89ad1 SOURCE=.\Pgpwctx\pgpwctx.rc
0ebfb3 # ADD BASE RSC /l 0x409 /i "Pgpwctx"
597e26 # ADD RSC /l 0x409 /i "Pgpwctx" /i ".\Pgpwctx"
d96ccd # End Source File
83df4f # Begin Source File
ccaf5a
2424f0 SOURCE=.\PGPWCTX\SClink.cpp
dc6ccd # End Source File
62df4f # Begin Source File
89af5a
13edc8 SOURCE=.\Pgpwctx\Shexinit.cpp
eb6ccd # End Source File
423f5a # End Group
dcba44 # Begin Group "Header Files"
14af5a
98561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
61df4f # Begin Source File
2baf5a
e5f9e0 SOURCE=.\include\PGPphras.h
b06ccd # End Source File
b5df4f # Begin Source File
4aaf5a
--f369 0014de87ac4401101a7 Page 3 of Pgpwctx.dsp
1c5cb0 SOURCE=.\include\pgprecip.h
586ccd # End Source File
5adf4f # Begin Source File
50af5a
c016e8 SOURCE=.\include\pgpversion.h
5b6ccd # End Source File
acdf4f # Begin Source File
5eaf5a
a83b3e SOURCE=.\Pgpwctx\Pgpwctx.hpp
4b6ccd # End Source File
c63f5a # End Group
6e8925 # Begin Group "Resource Files"
f0af5a
47a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
673f5a # End Group
e1e5cf # End Target
4df262 # End Project
--aff6 001e2e37cfc401101a8 Page 1 of Pgpwctx.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
df800e Project: "pgpwctx"=.\Pgpwctx.dsp - Package Owner=<4>
17af5a
e8e41b Package=<5>
558818 {{{
ca418b }}}
c5af5a
00bec7 Package=<4>
c68818 {{{
b4418b }}}
6eaf5a
622d94 ###############################################################################
a4af5a
2820da Global:
75af5a
10e41b Package=<5>
3d8818 {{{
1a418b }}}
58af5a
aa32c2 Package=<3>
618818 {{{
5a418b }}}
f4af5a
5b2d94 ###############################################################################
e2af5a
--a4f0 00032c91d7d401101a9 Page 1 of TreeList.dsp
2bc0b1 # Microsoft Developer Studio Project File - Name="TreeList" - Package Owner=<4>
ace7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
5b8537 # ** DO NOT EDIT **
e1af5a
8f877a # TARGTYPE "Win32 (x86) Static Library" 0x0104
45af5a
8b7cb8 CFG=TreeList - Win32 Release
ac894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
ad5c35 !MESSAGE use the Export Makefile command and run
4d6309 !MESSAGE·
e0076a !MESSAGE NMAKE /f "TreeList.mak".
2c6309 !MESSAGE·
4dcdb3 !MESSAGE You can specify a configuration when running NMAKE
d3e013 !MESSAGE by defining the macro CFG on the command line. For example:
916309 !MESSAGE·
902a00 !MESSAGE NMAKE /f "TreeList.mak" CFG="TreeList - Win32 Release"
6f6309 !MESSAGE·
de1dd7 !MESSAGE Possible choices for configuration are:
036309 !MESSAGE·
32cd5c !MESSAGE "TreeList - Win32 Release" (based on "Win32 (x86) Static Library")
eb34a6 !MESSAGE "TreeList - Win32 Debug" (based on "Win32 (x86) Static Library")
ba6309 !MESSAGE·
81af5a
3c3e63 # Begin Project
34b23f # PROP Scc_ProjName ""
eadf4a # PROP Scc_LocalPath ""
8540a4 CPP=cl.exe
89af5a
06de3c !IF ·"$(CFG)" == "TreeList - Win32 Release"
58af5a
d78243 # PROP BASE Use_MFC 0
87e662 # PROP BASE Use_Debug_Libraries 0
af4681 # PROP BASE Output_Dir ".\Release"
2cca0c # PROP BASE Intermediate_Dir ".\Release"
cb4c81 # PROP BASE Target_Dir ""
cf21ad # PROP Use_MFC 0
d7b771 # PROP Use_Debug_Libraries 0
2c3a95 # PROP Output_Dir ".\TreeList\Release"
27bbf4 # PROP Intermediate_Dir ".\TreeList\Release"
53b6fa # PROP Target_Dir ""
bc1d69 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
8d9b41 # ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WI¶
3c20da NDOWS" /YX /FD /c
2518fc BSC32=bscmake.exe
7f7a24 # ADD BASE BSC32 /nologo
2a4f1b # ADD BSC32 /nologo
2f7a92 LIB32=link.exe -lib
1b629d # ADD BASE LIB32 /nologo
2357a2 # ADD LIB32 /nologo
f2af5a
ad344e !ELSEIF ·"$(CFG)" == "TreeList - Win32 Debug"
6baf5a
5e8243 # PROP BASE Use_MFC 0
43ffba # PROP BASE Use_Debug_Libraries 1
dfcc98 # PROP BASE Output_Dir ".\Debug"
94d06b # PROP BASE Intermediate_Dir ".\Debug"
9c4c81 # PROP BASE Target_Dir ""
f921ad # PROP Use_MFC 0
20aea9 # PROP Use_Debug_Libraries 1
1c2db4 # PROP Output_Dir ".\TreeList\Debug"
12e4c7 # PROP Intermediate_Dir ".\TreeList\Debug"
81b6fa # PROP Target_Dir ""
587248 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX¶
a49f26 ·/c
4f45b0 # ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D ¶
bfe0d4 PGP_WIN32=1 /YX /FD /c
8118fc BSC32=bscmake.exe
0d7a24 # ADD BASE BSC32 /nologo
bf4f1b # ADD BSC32 /nologo
477a92 LIB32=link.exe -lib
aa629d # ADD BASE LIB32 /nologo
3257a2 # ADD LIB32 /nologo
--3775 001aa7a2a2f401101a9 Page 2 of TreeList.dsp
e0af5a
f730ec !ENDIF·
52af5a
89b8a5 # Begin Target
34af5a
f8194b # Name "TreeList - Win32 Release"
c873de # Name "TreeList - Win32 Debug"
ae4cc4 # Begin Group "Source Files"
7caf5a
377b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
a9df4f # Begin Source File
c8af5a
db192e SOURCE=.\TreeList\TLMisc.c
1f6ccd # End Source File
41df4f # Begin Source File
1daf5a
a80eae SOURCE=.\TreeList\TLMouse.c
606ccd # End Source File
dcdf4f # Begin Source File
00af5a
fedab5 SOURCE=.\TreeList\TLMsgPrc.c
076ccd # End Source File
13df4f # Begin Source File
50af5a
ac0d40 SOURCE=.\TreeList\TLPaint.c
c06ccd # End Source File
93df4f # Begin Source File
72af5a
b44609 SOURCE=.\TreeList\TLTree.c
056ccd # End Source File
16df4f # Begin Source File
b0af5a
fd83f5 SOURCE=.\TreeList\TreeList.c
3b6ccd # End Source File
9f3f5a # End Group
5aba44 # Begin Group "Header Files"
32af5a
4a561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
e1df4f # Begin Source File
3eaf5a
40521b SOURCE=.\TreeList\TLintern.h
fd6ccd # End Source File
52df4f # Begin Source File
37af5a
276379 SOURCE=.\TreeList\..\include\TreeList.h
086ccd # End Source File
b23f5a # End Group
a78925 # Begin Group "Resource Files"
dfaf5a
dca92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
c03f5a # End Group
0be5cf # End Target
aaf262 # End Project
--42bd 001484de4e5401101aa Page 1 of TreeList.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
6590a2 Project: "TreeList"=.\TreeList.dsp - Package Owner=<4>
11af5a
36e41b Package=<5>
d18818 {{{
9b418b }}}
8eaf5a
d5bec7 Package=<4>
758818 {{{
8c418b }}}
46af5a
6c2d94 ###############################################################################
31af5a
9820da Global:
ffaf5a
c8e41b Package=<5>
578818 {{{
38418b }}}
16af5a
1032c2 Package=<3>
ca8818 {{{
9f418b }}}
0baf5a
ff2d94 ###############################################################################
48af5a
--c0fa 000bd308416401101ab Page 1 of pgpExch.dsp
052052 # Microsoft Developer Studio Project File - Name="pgpExch" - Package Owner=<4>
44e7df # Microsoft Developer Studio Generated Build File, Format Version 5.00
438537 # ** DO NOT EDIT **
17af5a
56a99b # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
60af5a
4b2f90 CFG=pgpExch - Win32 Release
19894d !MESSAGE This is not a valid makefile. To build this project using NMAKE,
975c35 !MESSAGE use the Export Makefile command and run
f16309 !MESSAGE·
be86d8 !MESSAGE NMAKE /f "pgpExch.mak".
606309 !MESSAGE·
3ecdb3 !MESSAGE You can specify a configuration when running NMAKE
f3e013 !MESSAGE by defining the macro CFG on the command line. For example:
9a6309 !MESSAGE·
66130a !MESSAGE NMAKE /f "pgpExch.mak" CFG="pgpExch - Win32 Release"
2f6309 !MESSAGE·
ae1dd7 !MESSAGE Possible choices for configuration are:
556309 !MESSAGE·
b07869 !MESSAGE "pgpExch - Win32 Release" (based on\
bd17ca ·"Win32 (x86) Dynamic-Link Library")
eac1d2 !MESSAGE "pgpExch - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
736309 !MESSAGE·
4faf5a
e13e63 # Begin Project
0eb23f # PROP Scc_ProjName ""
e7df4a # PROP Scc_LocalPath ""
9f40a4 CPP=cl.exe
1da46a MTL=midl.exe
1c2e1f RSC=rc.exe
2daf5a
f2f6af !IF ·"$(CFG)" == "pgpExch - Win32 Release"
caaf5a
d58243 # PROP BASE Use_MFC 0
2ee662 # PROP BASE Use_Debug_Libraries 0
354681 # PROP BASE Output_Dir ".\Release"
b7ca0c # PROP BASE Intermediate_Dir ".\Release"
f44c81 # PROP BASE Target_Dir ""
1721ad # PROP Use_MFC 0
f5b771 # PROP Use_Debug_Libraries 0
4694a8 # PROP Output_Dir ".\pgpExch\Release"
88d57d # PROP Intermediate_Dir ".\pgpExch\Release"
1d9ad5 # PROP Ignore_Export_Lib 0
e3b6fa # PROP Target_Dir ""
e1c65c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX¶
dd9f26 ·/c
04d3d9 # ADD CPP /nologo /MT /W3 /GX /O2 /I ".\include" /I "..\..\..\libs\pfl\common" ¶
c063b3 /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pfl\common\prefs" /I "..\..\..\l¶
7ea162 ibs\pfl\common\file" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\..\libs\pg¶
d1e19b pcdk\win32" /I "..\shared" /I "shared" /D UNFINISHED_CODE_ALLOWED=1 /D PGP_WIN=¶
8f7546 1 /D PGP_DEBUG=0 /D "NDEBUG" /D PGP_WIN32=1 /D "WIN32" /D "_WINDOWS" /FD /c
3d7d4c # SUBTRACT CPP /YX
e5592a # ADD BASE MTL /nologo /D "NDEBUG" /win32
a9a23a # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
90b35b # ADD BASE RSC /l 0x409 /d "NDEBUG"
99de84 # ADD RSC /l 0x409 /d "NDEBUG"
3a18fc BSC32=bscmake.exe
dc7a24 # ADD BASE BSC32 /nologo
c34f1b # ADD BSC32 /nologo
9b268f LINK32=link.exe
e8cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
321165 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:wind¶
06f1e3 ows /dll /machine:I386
d22081 # ADD LINK32 libcmt.lib oldnames.lib kernel32.lib wsock32.lib advapi32.lib user¶
1598fd 32.lib gdi32.lib comdlg32.lib winspool.lib mapi32.lib uuid.lib version.lib shel¶
66210d l32.lib ..\..\..\libs\pgpcdk\win32\PGPcdk\Release\PGP_SDK.lib ..\..\..\libs\pfl¶
3550f7 \win32\pflCommon\Release\pflCommon.lib .\PGPcl\Release\PGP60cl.lib .\PGPsc\Rele¶
e22897 ase\PGP60sc.lib ..\..\..\libs\pgpcdk\win32\pgpsdknetworklib\release\pgpsdknl.li¶
462c5c b /nologo /subsystem:windows /dll /machine:I386 /nodefaultlib
a8af5a
8d0080 !ELSEIF ·"$(CFG)" == "pgpExch - Win32 Debug"
bdaf5a
--9474 00056100221401101ab Page 2 of pgpExch.dsp
dd8243 # PROP BASE Use_MFC 0
03ffba # PROP BASE Use_Debug_Libraries 1
49cc98 # PROP BASE Output_Dir ".\Debug"
ead06b # PROP BASE Intermediate_Dir ".\Debug"
704c81 # PROP BASE Target_Dir ""
9621ad # PROP Use_MFC 0
71aea9 # PROP Use_Debug_Libraries 1
a75018 # PROP Output_Dir ".\pgpExch\Debug"
715727 # PROP Intermediate_Dir ".\pgpExch\Debug"
2c9ad5 # PROP Ignore_Export_Lib 0
b8b6fa # PROP Target_Dir ""
a96cb3 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WIN¶
bc8dcb DOWS" /YX /c
1b33ed # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".\include" /I "..\..\..\libs\pfl¶
bdc703 \common" /I "..\..\..\libs\pfl\win32" /I "..\..\..\libs\pfl\common\prefs" /I ".¶
f0e32c .\..\..\libs\pfl\common\file" /I "..\..\..\libs\pgpcdk\pub\include" /I "..\..\.¶
ba1b72 .\libs\pgpcdk\win32" /I "..\shared" /I "shared" /D "_DEBUG" /D UNFINISHED_CODE_¶
25c283 ALLOWED=1 /D PGP_WIN=1 /D PGP_DEBUG=1 /D "WIN32" /D "_WINDOWS" /D PGP_WIN32=1 /¶
52d0d1 FD /c
fa7d4c # SUBTRACT CPP /YX
88b3e4 # ADD BASE MTL /nologo /D "_DEBUG" /win32
fbed08 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
8c699c # ADD BASE RSC /l 0x409 /d "_DEBUG"
c20443 # ADD RSC /l 0x409 /d "_DEBUG"
4b18fc BSC32=bscmake.exe
c67a24 # ADD BASE BSC32 /nologo
054f1b # ADD BSC32 /nologo
2a268f LINK32=link.exe
b9cadf # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a¶
7b1165 dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:wind¶
c052e5 ows /dll /debug /machine:I386
d42f80 # ADD LINK32 libcmtd.lib oldnames.lib kernel32.lib wsock32.lib advapi32.lib use¶
8dbfab r32.lib gdi32.lib comdlg32.lib winspool.lib mapi32.lib uuid.lib version.lib she¶
244702 ll32.lib ..\..\..\libs\pgpcdk\win32\PGPcdk\Debug\PGP_SDK.lib ..\..\..\libs\pfl\¶
43a4d7 win32\pflCommon\Debug\pflCommon.lib .\PGPcl\Debug\PGP60cl.lib .\PGPsc\Debug\PGP¶
3b634d 60sc.lib ..\..\..\libs\pgpcdk\win32\pgpsdknetworklib\debug\pgpsdknl.lib /nologo¶
206037 ·/subsystem:windows /dll /debug /machine:I386 /nodefaultlib
dfaf5a
0330ec !ENDIF·
77af5a
b8b8a5 # Begin Target
adaf5a
a8857e # Name "pgpExch - Win32 Release"
e8bc95 # Name "pgpExch - Win32 Debug"
c04cc4 # Begin Group "Source Files"
35af5a
fa7b0e # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
b3df4f # Begin Source File
27af5a
ec2697 SOURCE=.\shared\AddKey.c
596ccd # End Source File
09df4f # Begin Source File
6faf5a
7ed7a8 SOURCE=.\pgpExch\Attachments.cpp
f7b099 # ADD CPP /Yu"stdinc.h"
076ccd # End Source File
05df4f # Begin Source File
aaaf5a
d81da7 SOURCE=.\shared\BlockUtils.c
8c6ccd # End Source File
60df4f # Begin Source File
2caf5a
9fb489 SOURCE=.\pgpExch\Commands.cpp
3fb099 # ADD CPP /Yu"stdinc.h"
626ccd # End Source File
d0df4f # Begin Source File
19af5a
8c2772 SOURCE=.\shared\DecryptVerify.c
b86ccd # End Source File
30df4f # Begin Source File
73af5a
56ce65 SOURCE=.\shared\EncryptSign.c
--d641 000e3aa74d0401101ab Page 3 of pgpExch.dsp
aa6ccd # End Source File
bddf4f # Begin Source File
d3af5a
dd4543 SOURCE=.\pgpExch\GUIDS.CPP
b07d4c # SUBTRACT CPP /YX
a16ccd # End Source File
dbdf4f # Begin Source File
a0af5a
bfec2f SOURCE=.\pgpExch\Main.cpp
1fa28c # ADD CPP /Yc"stdinc.h"
cf6ccd # End Source File
afdf4f # Begin Source File
30af5a
a5107c SOURCE=.\pgpExch\MessageEvents.cpp
aeb099 # ADD CPP /Yu"stdinc.h"
b36ccd # End Source File
92df4f # Begin Source File
55af5a
797023 SOURCE=.\pgpExch\MsgProps.cpp
e9b099 # ADD CPP /Yu"stdinc.h"
8f6ccd # End Source File
89df4f # Begin Source File
fcaf5a
d3ef65 SOURCE=.\pgpExch\pgpExch.DEF
846ccd # End Source File
d5df4f # Begin Source File
19af5a
d7a496 SOURCE=.\pgpExch\pgpExch.RC
2565b5 # ADD BASE RSC /l 0x409 /i "pgpExch"
5d1d1c # ADD RSC /l 0x409 /i "pgpExch" /i ".\pgpExch"
f66ccd # End Source File
62df4f # Begin Source File
b0af5a
36d839 SOURCE=..\shared\pgpVersionHeader.c
0c6ccd # End Source File
9edf4f # Begin Source File
83af5a
7c0d54 SOURCE=.\shared\Prefs.c
136ccd # End Source File
4fdf4f # Begin Source File
daaf5a
45d63b SOURCE=.\pgpExch\PropertySheets.cpp
c9b099 # ADD CPP /Yu"stdinc.h"
446ccd # End Source File
13df4f # Begin Source File
7caf5a
3fae29 SOURCE=.\pgpExch\Recipients.cpp
6fb099 # ADD CPP /Yu"stdinc.h"
606ccd # End Source File
3ddf4f # Begin Source File
9eaf5a
41794d SOURCE=.\shared\RichEdit_IO.c
e26ccd # End Source File
f1df4f # Begin Source File
7aaf5a
f962e2 SOURCE=.\shared\SigEvent.c
206ccd # End Source File
d6df4f # Begin Source File
b0af5a
39b3d2 SOURCE=.\pgpExch\STDNOTE.CPP
e7b099 # ADD CPP /Yu"stdinc.h"
dc6ccd # End Source File
60df4f # Begin Source File
a3af5a
1e1fff SOURCE=.\pgpExch\UIutils.cpp
80b099 # ADD CPP /Yu"stdinc.h"
976ccd # End Source File
20df4f # Begin Source File
a8af5a
5b3d38 SOURCE=.\shared\VerificationBlock.c
306ccd # End Source File
e3df4f # Begin Source File
--fd24 0003ebbca16401101ab Page 4 of pgpExch.dsp
e0af5a
35e8b5 SOURCE=.\shared\Working.c
246ccd # End Source File
9b3f5a # End Group
cdba44 # Begin Group "Header Files"
caaf5a
d4561e # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
12df4f # Begin Source File
2daf5a
5df93c SOURCE=.\pgpExch\Exchange.h
706ccd # End Source File
f4df4f # Begin Source File
88af5a
1cc39b SOURCE=.\pgpExch\GUIDS.H
456ccd # End Source File
40df4f # Begin Source File
22af5a
6023b4 SOURCE=.\pgpExch\outlook.h
d26ccd # End Source File
01df4f # Begin Source File
3caf5a
b2eefd SOURCE=.\pgpExch\Recipients.h
836ccd # End Source File
42df4f # Begin Source File
6eaf5a
b2a380 SOURCE=.\pgpExch\STDINC.H
c96ccd # End Source File
95df4f # Begin Source File
50af5a
3ded63 SOURCE=.\pgpExch\UIutils.h
fe6ccd # End Source File
3c3f5a # End Group
7f8925 # Begin Group "Resource Files"
dcaf5a
41a92f # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
d4df4f # Begin Source File
71af5a
a4242b SOURCE=.\pgpExch\Res\addkey.bmp
606ccd # End Source File
a0df4f # Begin Source File
c1af5a
6b624e SOURCE=.\pgpExch\Res\both.bmp
b66ccd # End Source File
3fdf4f # Begin Source File
6caf5a
12d7b2 SOURCE=.\pgpExch\Res\decrypt.bmp
e66ccd # End Source File
20df4f # Begin Source File
13af5a
e110fe SOURCE=.\pgpExch\Res\encrypt.bmp
b86ccd # End Source File
b9df4f # Begin Source File
6caf5a
2d3a54 SOURCE=.\pgpExch\Res\pgpkeys.bmp
726ccd # End Source File
a8df4f # Begin Source File
90af5a
bcc8cb SOURCE=.\pgpExch\Res\sign.bmp
746ccd # End Source File
b0df4f # Begin Source File
06af5a
ba0e7c SOURCE=.\pgpExch\Res\Tboth.bmp
cd6ccd # End Source File
d4df4f # Begin Source File
57af5a
f62851 SOURCE=.\pgpExch\Res\Tdecrypt.bmp
b76ccd # End Source File
56df4f # Begin Source File
daaf5a
43ef1d SOURCE=.\pgpExch\Res\Tencrypt.bmp
456ccd # End Source File
3edf4f # Begin Source File
--0f63 00182e56002401101ab Page 5 of pgpExch.dsp
e0af5a
bec5b7 SOURCE=.\pgpExch\Res\Tpgpkeys.bmp
356ccd # End Source File
35df4f # Begin Source File
31af5a
c0a4f9 SOURCE=.\pgpExch\Res\Tsign.bmp
646ccd # End Source File
3b3f5a # End Group
fae5cf # End Target
82f262 # End Project
--8cbc 000c93620c5401101ac Page 1 of pgpExch.dsw
b3cc77 Microsoft Developer Studio Workspace File, Format Version 5.00
d1e8b0 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
6baf5a
ae2d94 ###############################################################################
93af5a
63f187 Project: "PGPcdk"=..\..\..\libs\pgpcdk\win32\PGPcdk\PGPcdk.dsp - Package Owner=¶
f8bde1 <4>
84af5a
fde41b Package=<5>
c28818 {{{
f1418b }}}
48af5a
02bec7 Package=<4>
4e8818 {{{
76418b }}}
02af5a
682d94 ###############################################################################
73af5a
cbe0aa Project: "PGPcl"=.\PGPcl.dsp - Package Owner=<4>
ffaf5a
46e41b Package=<5>
858818 {{{
b5418b }}}
14af5a
a7bec7 Package=<4>
0f8818 {{{
c4418b }}}
b6af5a
472d94 ###############################################################################
1aaf5a
c01a36 Project: "PGPsc"=.\PGPsc.dsp - Package Owner=<4>
9aaf5a
0de41b Package=<5>
608818 {{{
cd418b }}}
dbaf5a
8abec7 Package=<4>
728818 {{{
612c9f ····Begin Project Dependency
3bba3b ····Project_Dep_Name PGPcdk
3d04a4 ····End Project Dependency
092c9f ····Begin Project Dependency
a3740a ····Project_Dep_Name PGPcl
b704a4 ····End Project Dependency
ec418b }}}
3daf5a
232d94 ###############################################################################
12af5a
4b90a2 Project: "TreeList"=.\TreeList.dsp - Package Owner=<4>
a1af5a
75e41b Package=<5>
0a8818 {{{
80418b }}}
61af5a
c6bec7 Package=<4>
238818 {{{
ad418b }}}
4aaf5a
722d94 ###############################################################################
a0af5a
9f2a11 Project: "pflCommon"=..\..\..\libs\pfl\win32\pflCommon\pflCommon.dsp - Package ¶
9d94b2 Owner=<4>
9aaf5a
c5e41b Package=<5>
868818 {{{
2d418b }}}
7eaf5a
06bec7 Package=<4>
668818 {{{
c6418b }}}
6baf5a
c92d94 ###############################################################################
--d1e3 001ae9b4a19401101ac Page 2 of pgpExch.dsw
e0af5a
4e2ce1 Project: "pgpExch"=.\pgpExch.dsp - Package Owner=<4>
a0af5a
26e41b Package=<5>
a08818 {{{
38418b }}}
38af5a
d4bec7 Package=<4>
8c8818 {{{
ec2c9f ····Begin Project Dependency
22ba3b ····Project_Dep_Name PGPcdk
d904a4 ····End Project Dependency
cc2c9f ····Begin Project Dependency
3b7257 ····Project_Dep_Name PGPsc
7404a4 ····End Project Dependency
482c9f ····Begin Project Dependency
09740a ····Project_Dep_Name PGPcl
c804a4 ····End Project Dependency
922c9f ····Begin Project Dependency
ec0ce3 ····Project_Dep_Name pflCommon
2c04a4 ····End Project Dependency
4d418b }}}
cbaf5a
5d2d94 ###############################################################################
46af5a
4f20da Global:
0eaf5a
aee41b Package=<5>
9f8818 {{{
34418b }}}
81af5a
6f32c2 Package=<3>
8d8818 {{{
b6418b }}}
88af5a
4a2d94 ###############################################################################
aeaf5a

--6f87 000c9d44ded401101ad Page 1 of CBTProc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
f89743 ¤   $Id: CBTProc.c,v 1.5.16.1 1998/11/12 03:11:20 heller Exp $
3af7f7 ____________________________________________________________________________*/
39af5a
e89b16 // System Headers
795655 #include <windows.h>
7b3d0b #include <windowsx.h>
c9af5a
a3e8e0 // Project Headers
f95ce1 #include "strstri.h"
50a6f9 #include "EudoraSendMailWndProc.h"
afc5e5 #include "EudoraReadMailWndProc.h"
09ade2 #include "EudoraMainWndProc.h"
816c40 #include "PGPDefinedMessages.h"
248031 #include "resource.h"
eaaf5a
a6482b // Global Variables
ef40d3 extern HHOOK¤   ¤   g_hCBTHook;
182569 extern HINSTANCE¤   g_hinst;
794597 extern HWND¤¤   ¤   g_hwndEudoraStatusbar;
fcedfc extern HWND¤¤   ¤   g_hwndEudoraMainWindow;
bbaf5a
5b7aa2 // Project Defines
ef693b #define EUDORA_SEND_EMAIL 1
345ab2 #define EUDORA_READ_EMAIL 2
29af5a
58f72c void HANDLE_HCBT_CREATEWND(int nCode, WPARAM wParam, LPARAM lParam);
edaf5a
2baf5a
e5c03d //=================== CBTProc: Finds Windows ====================
95af5a
78cf2c LRESULT WINAPI CBTProc (int nCode, WPARAM wParam, LPARAM lParam)
fabb36 {
e6d807 ¤   if (nCode >= 0)
64c7a1 ¤   {
91e511 ¤   ¤   switch (nCode)
512b60 ········{
464647 ¤   ¤   ¤   case HCBT_CREATEWND:
f3f776 ¤   ¤   ¤   {
1c917c ¤   ¤   ¤   ¤   HANDLE_HCBT_CREATEWND(¤ nCode,
dff76e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam,
37e54b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lParam);
7ef622 ¤   ¤   ¤   ¤   break;
1d5a2a ¤   ¤   ¤   }¤
a031d3 ¤   ¤   }¤  ¤   ¤
749371 ¤   }
79af5a
c67a29 ¤   return CallNextHookEx (g_hCBTHook, nCode, wParam, lParam);
d1efe6 }
dbaf5a
c883f0 void HANDLE_HCBT_CREATEWND(int nCode, WPARAM wParam, LPARAM lParam)
71bb36 {
c859ec ¤   static¤ DWORD ThreadId¤ ¤   ¤   = 0;
1bb1c5 ¤   int¤¤   WindowCode¤ ¤   ¤   ¤   = 0;
d3e98e ¤   HWND¤   hwndDetect¤ ¤   ¤   ¤   = NULL;
553555 ¤   HWND¤   hwnd¤   ¤   ¤   ¤   ¤   = NULL ;
4aac6e ¤   HWND¤   hwndParent¤ ¤   ¤   ¤   = NULL;·
cd2ebc ¤   int¤¤   result¤ ¤   ¤   ¤   ¤   = 0;
6c7892 ¤   char¤   szWndClass[1024]¤   ¤   = {0x00};
377ec3 ¤   char¤   szTitleText[256]¤   ¤   = {0x00};
ba7452 ¤   char¤   szModuleName[MAX_PATH]¤ = {0x00};
b7af5a
ebcd8e ¤   hwnd¤   = (HWND) wParam ;
82eda9 ¤   hwndParent¤ = (HWND)((LPCREATESTRUCT)
34688d ¤   ¤   ¤   ¤   ¤   ((CBT_CREATEWND*)lParam)->lpcs)->hwndParent;·
22af5a
c97d02 ¤   // Get the class of our window
--a325 000bffe6b7d401101ad Page 2 of CBTProc.c
30347c ¤   result = GetClassName( hwnd, szWndClass, sizeof(szWndClass) );¤
b5af5a
bd7487 ¤   // did we get the classname ??
20a112 ¤   if(result)
e9c7a1 ¤   {
9bcf9f ¤   ¤   // Eudora_Pro and Eudora_Light Child Windows
b1df59 ¤   ¤   if( strstri(szWndClass, "RICHEDIT") )·
a85b34 ¤   ¤   {
da529e ¤   ¤   ¤   HWND hwndGrandParent = GetParent(hwndParent);
c34564 ¤   ¤   ¤   HWND hwndGreat_GrandParent = GetParent(hwndGrandParent);
3783b0 ¤   ¤   ¤   HWND hwndGreat_Great_GrandParent =·
7c2322 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetParent(hwndGreat_GrandParent);
a3af5a
b55369 ¤   ¤   ¤   if(hwndGreat_GrandParent)
4af776 ¤   ¤   ¤   {
b093a1 ¤   ¤   ¤   ¤   // Get the text in the TitleBar
b1a8c1 ¤   ¤   ¤   ¤   result = GetWindowText(¤hwndGreat_GrandParent,·
7548b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTitleText,·
c2cb0e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTitleText) );
84af5a
a1610d ¤   ¤   ¤   ¤   if( result &&·
de5a84 ¤   ¤   ¤   ¤   ¤   ( strstr(szTitleText, "Eudora Pro") ||·
c9b5d2 ¤   ¤   ¤   ¤   ¤   strstr(szTitleText, "Eudora Light") ) )
df72c3 ¤   ¤   ¤   ¤   {
e0cf8f ¤   ¤   ¤   ¤   ¤   WindowCode = EUDORA_READ_EMAIL;
162613 ¤   ¤   ¤   ¤   }
699e20 ¤   ¤   ¤   } // if hwndGreat_GrandParent
5baf5a
a26ffb ¤   ¤   ¤   if(hwndGreat_Great_GrandParent)
1df776 ¤   ¤   ¤   {
4393a1 ¤   ¤   ¤   ¤   // Get the text in the TitleBar
c64826 ¤   ¤   ¤   ¤   result = GetWindowText(¤hwndGreat_Great_GrandParent,·
e748b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTitleText,·
02cb0e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTitleText) );
40af5a
d4610d ¤   ¤   ¤   ¤   if( result &&·
165a84 ¤   ¤   ¤   ¤   ¤   ( strstr(szTitleText, "Eudora Pro") ||·
94b5d2 ¤   ¤   ¤   ¤   ¤   strstr(szTitleText, "Eudora Light") ) )
f772c3 ¤   ¤   ¤   ¤   {
f0e706 ¤   ¤   ¤   ¤   ¤   WindowCode = EUDORA_SEND_EMAIL;
a72613 ¤   ¤   ¤   ¤   }
4496b2 ¤   ¤   ¤   } //if hwndGreat_Great_GrandParent
e4d83c ·
3faf5a
2fa6bf ¤   ¤   ¤   if( WindowCode == EUDORA_SEND_EMAIL )
18f776 ¤   ¤   ¤   {
c712ae ¤   ¤   ¤   ¤   //MessageBox(NULL, "EUDORA_SEND_EMAIL", "Detected", MB_OK);
f4af5a
a709fc ¤   ¤   ¤   ¤   // Set the proc address as a property·
cc9b8b ¤   ¤   ¤   ¤   // of the window so it can get it
9b5b63 ¤   ¤   ¤   ¤   SetProp(hwnd,·
a47761 ¤   ¤   ¤   ¤   ¤   ¤   "oldproc",
447a17 ¤   ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong(hwnd, GWL_WNDPROC));
d92b85 ¤   ¤   ¤   ¤
6ba5ab ¤   ¤   ¤   ¤   // Subclass the window
505587 ¤   ¤   ¤   ¤   SetWindowLong(¤ hwnd,·
3413ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
5fb2d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)EudoraSendMailWndProc ); ·
5da3a6 ¤   ¤   ¤   }
9acf12 ¤   ¤   ¤   else if( WindowCode == EUDORA_READ_EMAIL )
91f776 ¤   ¤   ¤   {
8500a5 ¤   ¤   ¤   ¤   //MessageBox(NULL, "EUDORA_READ_EMAIL", "Detected", MB_OK);
77af5a
b109fc ¤   ¤   ¤   ¤   // Set the proc address as a property·
059b8b ¤   ¤   ¤   ¤   // of the window so it can get it
095b63 ¤   ¤   ¤   ¤   SetProp(hwnd,·
f37761 ¤   ¤   ¤   ¤   ¤   ¤   "oldproc",
f47a17 ¤   ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong(hwnd, GWL_WNDPROC));
f72b85 ¤   ¤   ¤   ¤
55a5ab ¤   ¤   ¤   ¤   // Subclass the window
eb5587 ¤   ¤   ¤   ¤   SetWindowLong(¤ hwnd,·
bf13ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
--f129 0010af5aa33401101ad Page 3 of CBTProc.c
6483f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)EudoraReadMailWndProc); ·
14a3a6 ¤   ¤   ¤   }
7faf5a
24d27d ¤   ¤   ¤   // Send Main Window ID
796dc1 ¤   ¤   ¤   PostMessage(hwnd, WM_PGP_CREATE_INTERFACE, 0,(LPARAM)hwnd);·
cd87c7 ¤   ¤   ¤
f9b292 ¤   ¤   } // if RICHEDIT
f27e24 ¤   ¤   // Check to see if Parent Window Menu Created yet
944621 ¤   ¤   else if( strstri(szWndClass, "ToolbarWindow32"))·
e45b34 ¤   ¤   {
19b011 ¤   ¤   ¤   static BOOL bParentFound = FALSE;
0faf5a
21f4f9 ¤   ¤   ¤   //MessageBox(NULL, "Toolbar Window", "Detected", MB_OK);
2aaf5a
e01f9b ¤   ¤   ¤   if(!bParentFound)
bbf776 ¤   ¤   ¤   {
c18d39 ¤   ¤   ¤   ¤   HMENU hmenu = GetMenu(hwndParent);
b5af5a
d5d843 ¤   ¤   ¤   ¤   if(hmenu)
5e72c3 ¤   ¤   ¤   ¤   {
3ab827 ¤   ¤   ¤   ¤   ¤   HMENU submenu = NULL;
4054dc ¤   ¤   ¤   ¤   ¤   HMENU AboutMenu = NULL;
d0af5a
dc2cdf ¤   ¤   ¤   ¤   ¤   bParentFound = TRUE;
c1af5a
089cd5 ¤   ¤   ¤   ¤   ¤   AboutMenu = LoadMenu(g_hinst,·
1b9a1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDM_PGPABOUTMENU));
52af5a
4337f3 ¤   ¤   ¤   ¤   ¤   InsertMenu(¤hmenu,·
119639 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   7,·
d3e82d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_ENABLED|MF_BYPOSITION|MF_STRING|MF_POPUP,·
5cb2a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (UINT)AboutMenu,·
1bf803 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "&PGP");
6caf5a
a50ec7 ¤   ¤   ¤   ¤   ¤   // Set the proc address as a property·
81358a ¤   ¤   ¤   ¤   ¤   // of the window so it can get it
0f3004 ¤   ¤   ¤   ¤   ¤   SetProp(hwndParent,·
3f3692 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "oldproc",
f8bf93 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong(hwndParent, GWL_WNDPROC));·
e1af5a
c8abe7 ¤   ¤   ¤   ¤   ¤   // Subclass the window
2b9473 ¤   ¤   ¤   ¤   ¤   SetWindowLong(¤ hwndParent,·
b95cc1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
c8abf3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)EudoraMainWndProc ); ·
0aaf5a
7bfc5f ¤   ¤   ¤   ¤   ¤   g_hwndEudoraMainWindow = hwndParent;
192613 ¤   ¤   ¤   ¤   }
cda3a6 ¤   ¤   ¤   }
190fe4 ¤   ¤   }
30b4f6 ¤   ¤   // Check to see if this is the statusbar
a1f68f ¤   ¤   else if(strstri(szWndClass, "msctls_statusbar32"))·
c65b34 ¤   ¤   {
279ad4 ¤   ¤   ¤   g_hwndEudoraStatusbar = hwnd;
710fe4 ¤   ¤   }
46af5a
0b693e ¤   } // if result
f5efe6 }
0aaf5a
--6732 001b3e2c719401101ae Page 1 of CBTProc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7da8a4 ¤   CBTProc.h,v 1.3 1997/10/22 23:05:47 elrod Exp
76f7f7 ____________________________________________________________________________*/
e8af5a
df22a1 #ifndef Included_CBTProc_h¤ /* [ */
76277e #define Included_CBTProc_h
caaf5a
3eeb81 LRESULT WINAPI CBTProc (int nCode, WPARAM wParam, LPARAM lParam);
a8af5a
cb4439 #endif /* ] Included_CBTProc_h */
40af5a
6baf5a
097e4d /*__Editor_settings____
f9af5a
644126 ¤   Local Variables:
997b17 ¤   tab-width: 4
7b0e6c ¤   End:
395f8c ¤   vi: ts=4 sw=4
c39e9b ¤   vim: si
b37c50 _____________________*/¶
--e661 0005ffa1255401101af Page 1 of CreateToolbar.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
0f5794 ¤   $Id: CreateToolbar.c,v 1.3.8.1 1998/11/12 03:11:21 heller Exp $
40f7f7 ____________________________________________________________________________*/
6faf5a
3f9b16 // System Headers
6b5655 #include <windows.h>
3f3d0b #include <windowsx.h>
8490fb #include <commctrl.h>
0caf5a
0de8e0 // Project Headers
1b0d56 #include "CreateToolbar.h"
be1402 #include "transBMP.h"
503e80 #include "ReadMailToolbarWndProc.h"
a9b11f #include "SendMailToolbarWndProc.h"
906c40 #include "PGPDefinedMessages.h"
e18031 #include "resource.h"
0caf5a
93af5a
fa017f #define TRANSPARENT_COLOR RGB(255, 0, 0)
7aaf5a
2319cd extern HINSTANCE g_hinst;
22af5a
dbfda7 HWND CreateToolbarRead(HWND hwndParent)
3abb36 {
96a701 ¤   TBBUTTON tbread[]= {
417519 ¤   ¤   ¤   ¤   {0,IDC_DECRYPT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},
466d46 ¤   ¤   ¤   ¤   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
cf0ac1 ¤   ¤   ¤   ¤   {2,IDC_KEYMGR,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},
51fe40 ¤   ¤   ¤   ¤   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0}};
21af5a
e35308 ¤   static HBITMAP hTransparentBMP¤ = NULL;
fc9fb3 ¤   HBITMAP¤hReadToolbar¤   = NULL;·
16a794 ¤   HBITMAP¤hOldBitmap¤ ¤   = NULL;
382516 ¤   HDC¤¤   hdc¤¤   ¤   ¤   = NULL;
332f61 ¤   HDC¤¤   hdcMem¤ ¤   ¤   = NULL;
413c39 ¤   HBRUSH¤ hBrush¤ ¤   ¤   = NULL;
1be238 ¤   HBRUSH¤ hOldBrush¤  ¤   = NULL;
07e50d ¤   SIZE¤   size¤   ¤   ¤   = {0,0};
727854 ¤   HWND¤   hwndToolbar¤¤   = NULL;
58af5a
e8dc27 ¤   // all this work just to load a bitmap and make it transparent...
c9f183 ¤   hReadToolbar = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_READTOOLBAR));
5caf5a
6b1afe ¤   hdc = CreateIC("DISPLAY",NULL,NULL,NULL);
1f4f98 ¤   hdcMem = CreateCompatibleDC(hdc);
6c1cc3 ¤   hBrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
02af5a
c3242d ¤   hTransparentBMP = ·CreateCompatibleBitmap(hdc,54,18);
a48993 ¤   hOldBitmap = SelectObject(hdcMem,hTransparentBMP);
7f3583 ¤   hOldBrush = SelectObject(hdcMem,hBrush);
fee854 ¤   PatBlt(hdcMem,0,0,54,18,PATCOPY);
75086e ¤   TransparentBitmap(hReadToolbar, 54, 18, TRANSPARENT_COLOR, hdcMem, 0,0);
e339ca ¤   SelectObject(hdcMem,hOldBitmap);
ef7b9f ¤   SelectObject(hdcMem,hOldBrush);
d25be3 ¤   DeleteObject(hBrush);
f1fcce ¤   DeleteObject(hReadToolbar);
ccb72b ¤   DeleteDC(hdcMem);
d035c1 ¤   DeleteDC(hdc);
f4af5a
f95278 ¤   // now we can create the actual toolbar
7fa42b ¤   hwndToolbar = CreateToolbarEx(
046577 ¤   ¤   ¤   ¤   hwndParent,
488427 ¤   ¤   ¤   ¤   TBSTYLE_TOOLTIPS|WS_VISIBLE|WS_CHILD|
b89eeb ¤   ¤   ¤   ¤   WS_CLIPSIBLINGS|CCS_TOP|CCS_NODIVIDER|CCS_NORESIZE,
b4760b ¤   ¤   ¤   ¤   IDC_READTOOLBAR,
62ece8 ¤   ¤   ¤   ¤   3,
5fe022 ¤   ¤   ¤   ¤   NULL,
--8a1f 0003aa14dd4401101af Page 2 of CreateToolbar.c
e83e29 ¤   ¤   ¤   ¤   (UINT)hTransparentBMP,
7c4fa4 ¤   ¤   ¤   ¤   tbread,
898596 ¤   ¤   ¤   ¤   sizeof(tbread)/sizeof(TBBUTTON),
096c91 ¤   ¤   ¤   ¤   18,
d96c91 ¤   ¤   ¤   ¤   18,
456c91 ¤   ¤   ¤   ¤   18,
bd6c91 ¤   ¤   ¤   ¤   18,
48bb52 ¤   ¤   ¤   ¤   sizeof(TBBUTTON));
56af5a
0a67c5 ¤
8751f1 ¤   // Set the proc address as a property·
65d19e ¤   // of the window so it can get it
5b878a ¤   SetProp(hwndParent,·
b40dd7 ¤   ¤   ¤   "oldproc",
550b8c ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndParent, GWL_WNDPROC ) );·
d9af5a
457c0f ¤   // Subclass the window
38f8d3 ¤   SetWindowLong(¤ hwndParent,·
93f9a7 ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
f33bdf ¤   ¤   ¤   ¤   ¤   (DWORD)ReadMailToolbarWndProc ); ·
02af5a
98f6ac ¤   return hwndToolbar;
b6efe6 }
21af5a
3792ac HWND CreateToolbarSend(HWND hwndParent)
20bb36 {
2ba701 ¤   TBBUTTON tbread[]= {
a36d46 ¤   ¤   ¤   ¤   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
1be506 ¤   ¤   ¤   ¤   {4,IDC_KEYMGR,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},
f06d46 ¤   ¤   ¤   ¤   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
bb2eb4 ¤   ¤   ¤   ¤   {3,IDC_MIME,TBSTATE_ENABLED,TBSTYLE_CHECK,0,0,0,0},¤¤   ¤   ¶
9187c7 ¤   ¤   ¤
906d46 ¤   ¤   ¤   ¤   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
edb9c0 ¤   ¤   ¤   ¤   {1,IDC_ENCRYPT,TBSTATE_ENABLED,TBSTYLE_CHECK,0,0,0,0},
1aa339 ¤   ¤   ¤   ¤   {2,IDC_SIGN,TBSTATE_ENABLED,TBSTYLE_CHECK,0,0,0,0},
05fe40 ¤   ¤   ¤   ¤   {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0}};
23af5a
785308 ¤   static HBITMAP hTransparentBMP¤ = NULL;
25af5a
748a31 ¤   HBITMAP¤hSendToolbar¤   ¤   ¤   = NULL;·
442d6f ¤   HBITMAP¤hOldBitmap¤ ¤   ¤   ¤   = NULL;
9b5c44 ¤   HDC¤¤   hdc¤¤   ¤   ¤   ¤   ¤   = NULL;
8da164 ¤   HDC¤¤   hdcMem¤ ¤   ¤   ¤   ¤   = NULL;
5daff6 ¤   HBRUSH¤ hBrush¤ ¤   ¤   ¤   ¤   = NULL;
3d5cba ¤   HBRUSH¤ hOldBrush¤  ¤   ¤   ¤   = NULL;
be6e5a ¤   HWND¤   hwndToolbar¤¤   ¤   ¤   = NULL;
47af5a
0bdc27 ¤   // all this work just to load a bitmap and make it transparent...
f1f38d ¤   hSendToolbar = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_SENDTOOLBAR));
e0af5a
ff1afe ¤   hdc = CreateIC("DISPLAY",NULL,NULL,NULL);
264f98 ¤   hdcMem = CreateCompatibleDC(hdc);
001cc3 ¤   hBrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
69af5a
c47039 ¤   hTransparentBMP = ·CreateCompatibleBitmap(hdc,90,18);
b18993 ¤   hOldBitmap = SelectObject(hdcMem,hTransparentBMP);
7a3583 ¤   hOldBrush = SelectObject(hdcMem,hBrush);
42b84b ¤   PatBlt(hdcMem,0,0,90,18,PATCOPY);
0b4cc1 ¤   TransparentBitmap(hSendToolbar, 90, 18, TRANSPARENT_COLOR, hdcMem, 0,0);
fc39ca ¤   SelectObject(hdcMem,hOldBitmap);
a87b9f ¤   SelectObject(hdcMem,hOldBrush);
ff5be3 ¤   DeleteObject(hBrush);
660a50 ¤   DeleteObject(hSendToolbar);
50b72b ¤   DeleteDC(hdcMem);
1d35c1 ¤   DeleteDC(hdc);
97af5a
295278 ¤   // now we can create the actual toolbar
17a42b ¤   hwndToolbar = CreateToolbarEx(
986577 ¤   ¤   ¤   ¤   hwndParent,
2a8427 ¤   ¤   ¤   ¤   TBSTYLE_TOOLTIPS|WS_VISIBLE|WS_CHILD|
d79eeb ¤   ¤   ¤   ¤   WS_CLIPSIBLINGS|CCS_TOP|CCS_NODIVIDER|CCS_NORESIZE,
3a6fea ¤   ¤   ¤   ¤   IDC_SENDTOOLBAR,
--a1ac 000a64ddffa401101af Page 3 of CreateToolbar.c
403a31 ¤   ¤   ¤   ¤   5,
ffe022 ¤   ¤   ¤   ¤   NULL,
3b3e29 ¤   ¤   ¤   ¤   (UINT)hTransparentBMP,
0d4fa4 ¤   ¤   ¤   ¤   tbread,
118596 ¤   ¤   ¤   ¤   sizeof(tbread)/sizeof(TBBUTTON),
146c91 ¤   ¤   ¤   ¤   18,
0b6c91 ¤   ¤   ¤   ¤   18,
fa6c91 ¤   ¤   ¤   ¤   18,
696c91 ¤   ¤   ¤   ¤   18,
f3bb52 ¤   ¤   ¤   ¤   sizeof(TBBUTTON));
12af5a
3a67c5 ¤
b251f1 ¤   // Set the proc address as a property·
94d19e ¤   // of the window so it can get it
4f878a ¤   SetProp(hwndParent,·
aa0dd7 ¤   ¤   ¤   "oldproc",
0a0b8c ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndParent, GWL_WNDPROC ) );·
5367c5 ¤
4d7c0f ¤   // Subclass the window
f0f8d3 ¤   SetWindowLong(¤ hwndParent,·
8df9a7 ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
b2ddb5 ¤   ¤   ¤   ¤   ¤   (DWORD)SendMailToolbarWndProc ); ·
ecaf5a
daf6ac ¤   return hwndToolbar;
7befe6 }
96af5a
a4eede void CalculateToolbarRect(HWND hwndToolbar, RECT* rect)
00bb36 {
3c92ec ¤   int width¤  ¤   = 0;
164fc9 ¤   int buttoncount = 0;
11a4bd ¤   RECT tempRect;
f0af5a
846e53 ¤   // initialize rect
410138 ¤   rect->left¤ ¤   = 0;
f17547 ¤   rect->right¤¤   = 0;
748711 ¤   rect->top¤  ¤   = 0;
951274 ¤   rect->bottom¤   = 0;
19af5a
8c07bf ¤   buttoncount = SendMessage(hwndToolbar,TB_BUTTONCOUNT,0,0);·
33af5a
6effe2 ¤   // get right most button
ff853a ¤   SendMessage(hwndToolbar,·
1b9664 ¤   ¤   ¤   ¤   TB_GETITEMRECT,
655263 ¤   ¤   ¤   ¤   buttoncount-1,
747f60 ¤   ¤   ¤   ¤   (LPARAM) (LPRECT) &tempRect);·
05af5a
ef9353 ¤   rect->right = tempRect.right;
fb034b ¤   rect->bottom = tempRect.bottom;
68af5a
7099f3 ¤   // get left most button
863f1c ¤   SendMessage(hwndToolbar, TB_GETITEMRECT,0,(LPARAM) (LPRECT) &tempRect);·
56af5a
50dc08 ¤   rect->left = tempRect.left;
33c2f8 ¤   rect->top = tempRect.top;
05efe6 }
19af5a
0338e5 /*
bf5d3c LPVOID lpMessageBuffer;
d9af5a
3bd2bf ¤   ¤   FormatMessage(
d9186a ¤   ¤   ··FORMAT_MESSAGE_ALLOCATE_BUFFER |
8e52c7 ¤   ¤   ··FORMAT_MESSAGE_FROM_SYSTEM,
5f6141 ¤   ¤   ··NULL,
e221f9 ¤   ¤   ··GetLastError(),
55c84b ¤   ¤   ··MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
a1ae52 ¤   ¤   ··(LPTSTR) &lpMessageBuffer,
3da7a3 ¤   ¤   ··0,
d3ab0a ¤   ¤   ··NULL );
56af5a
a673f3 ¤   ¤   // now display this string
f1141d ·¤  ¤   MessageBox(NULL, (char*)lpMessageBuffer, 0, MB_OK);
a6af5a
--0817 0010a15631f401101af Page 4 of CreateToolbar.c
ec83ee ¤   ¤   // Free the buffer allocated by the system
460eb8 ¤   ¤   LocalFree( lpMessageBuffer );
155c12 ¤   ¤   */
0aaf5a
--29f9 001cedf509b401101b0 Page 1 of CreateToolbar.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
b89b42 ¤   CreateToolbar.h,v 1.3 1997/10/22 23:05:47 elrod Exp
d0f7f7 ____________________________________________________________________________*/
fcaf5a
9e8ea9 #ifndef Included_CreateToolbar_h¤   /* [ */
8eedf8 #define Included_CreateToolbar_h
3baf5a
9a5964 #define IDC_READTOOLBAR¤WM_USER + 1020
8c2c4d #define IDC_SENDTOOLBAR¤WM_USER + 1021
e9af5a
93af5a
1dd168 HWND CreateToolbarRead(HWND hwndParent);
266fd4 HWND CreateToolbarSend(HWND hwndParent);
b43f3d void CalculateToolbarRect(HWND hwndToolbar, RECT* rect);
59af5a
c34eb0 #endif /* ] Included_CreateToolbar_h */
8eaf5a
5aaf5a
1f7e4d /*__Editor_settings____
71af5a
9c4126 ¤   Local Variables:
877b17 ¤   tab-width: 4
3b0e6c ¤   End:
2e5f8c ¤   vi: ts=4 sw=4
179e9b ¤   vim: si
ced062 _____________________*/
--15ef 00110631257401101b1 Page 1 of DisplayMessage.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
59976c ¤   DisplayMessage.c,v 1.3 1997/07/21 06:03:26 elrod Exp
b2f7f7 ____________________________________________________________________________*/
87af5a
6f9b16 // System Headers
b35655 #include <windows.h>
2faf5a
1ce8e0 // Project Headers
0d8031 #include "resource.h"
5aaf5a
dad2af int DisplayMessage(HWND hwnd, long StringId, long TitleId, UINT buttons)
36bb36 {
4f3b0b ¤   char szMessageBuffer[1024];
290278 ¤   char szTitleBuffer[256];
670bf5 ¤   HINSTANCE hInst = NULL;
47af5a
9e5c2a ¤   hInst = GetModuleHandle("PGPplugin.dll");
10af5a
869437 ¤   LoadString(hInst, StringId, szMessageBuffer, sizeof(szMessageBuffer));
b5e1ad ¤   LoadString(hInst, TitleId, szTitleBuffer, sizeof(szTitleBuffer));
faaf5a
0e6ad6 ¤   return MessageBox(hwnd, szMessageBuffer, szTitleBuffer, buttons);
10efe6 }
--2ea1 001f7c91618401101b2 Page 1 of DisplayMessage.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
389b65 ¤   DisplayMessage.h,v 1.3 1997/07/21 06:03:27 elrod Exp
2cf7f7 ____________________________________________________________________________*/
0f0776 #ifndef Included_DisplayMessage_h¤  /* [ */
2bd435 #define Included_DisplayMessage_h
f7af5a
ef3379 #ifdef __cplusplus
186dad extern "C" {
e17454 #endif
3baf5a
de5d0f int DisplayMessage(HWND hwnd, long StringId, long TitleId, UINT buttons);
13af5a
19af5a
8a3379 #ifdef __cplusplus
71efe6 }
6e7454 #endif
4faf5a
a5af5a
41af5a
5cb1f5 #endif /* ] Included_DisplayMessage_h */
3aaf5a
edaf5a
db7e4d /*__Editor_settings____
f7af5a
524126 ¤   Local Variables:
657b17 ¤   tab-width: 4
050e6c ¤   End:
2d5f8c ¤   vi: ts=4 sw=4
5e9e9b ¤   vim: si
f7d062 _____________________*/
--c484 0012a1d1804401101b3 Page 1 of EudoraINI.h
bc38e5 /*
620c71 ** Copyright (C)1997 Network Associates, Inc. and its affiliates.
2df124 ** All rights reserved.
3c7fe0 */
8daf5a
e5b900 #ifndef _EUDORAINI_H
5b49be #define _EUDORAINI_H
9daf5a
20af5a
631d4f typedef struct _EUDORAMAPPINGS{
4d5c1e ¤   char extension[10];
145f29 ¤   char type[10];
e5107c ¤   char creator[10];
b7893f ¤   char mimetype[256];
743ae0 ¤   struct _EUDORAMAPPINGS* next;
13af5a
2253be }EUDORAMAPPINGS, *PEUDORAMAPPINGS;
ebaf5a
fb6753 void SetDefaultMailAction(void);
2e2334 BOOL GetEudoraINIPath(char* Path);
2c3c58 BOOL GetEudoraUserId(char* buffer);
e62b63 PEUDORAMAPPINGS LoadEudoraMappings(void);
a867c5 ¤
60af5a
2a7454 #endif
--378b 00076ddd0ce401101b4 Page 1 of EudoraMailHeaders.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
f8899f ¤   $Id: EudoraMailHeaders.c,v 1.6.16.1 1998/11/12 03:11:24 heller Exp $
50f7f7 ____________________________________________________________________________*/
0aaf5a
659b16 // System Headers
e9af5a
bc5655 #include <windows.h>
e03d0b #include <windowsx.h>
a92f6f #include <richedit.h>
ed90fb #include <commctrl.h>
5cb1cb #include <ctype.h>
69bb5f #include <assert.h>
80feb2 #include <stdio.h>
43af5a
b45582 // PGPsdk Headers
73e2ff #include "pgpConfig.h"
f3a076 #include "pgpKeys.h"
322f8d #include "pgpErrors.h"
1e4919 #include "pgpUtilities.h"
9daf5a
0ce8e0 // Project Headers
ac5ce1 #include "strstri.h"
ade7a0 #include "EudoraMailHeaders.h"
7b2bcf #include "MyMIMEUtils.h"
6aaf5a
9ef628 int GetEudoraAddressFromNickname(char *pNickname,·
f9bd6c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char *pAddress,·
9e65bd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·int nAddressSize);
bbaf5a
ed3fb4 void GetEudoraHeaders( HWND hwndHeaders, PHEADERDATA phd)
41bb36 {
7e3b6e ¤   HWND hwndTo = NULL;
e0c247 ¤   HWND hwndFrom = NULL;
f90594 ¤   HWND hwndSubject = NULL;
ee9fcd ¤   HWND hwndCC = NULL;
d3a68f ¤   HWND hwndBCC = NULL;
cc6484 ¤   HWND hwndAttach = NULL;
f2862b ¤   long FieldLength = 0;
3eaf5a
8014a9 ¤   if( hwndHeaders ·&& phd )
8ec7a1 ¤   {
40082d ¤   ¤   // Find the windows we are interested in...
1c7151 ¤   ¤   hwndTo¤ ¤   = FindWindowEx(hwndHeaders, NULL,¤  ¤   "Edit", NULL);
e5c5e8 ¤   ¤   hwndFrom¤   = FindWindowEx(hwndHeaders, hwndTo,¤¤   "Edit", NULL);
151e78 ¤   ¤   hwndSubject = FindWindowEx(hwndHeaders, hwndFrom,¤  "Edit", NULL);
3f59cf ¤   ¤   hwndCC¤ ¤   = FindWindowEx(hwndHeaders, hwndSubject,"Edit", NULL);
cca723 ¤   ¤   hwndBCC¤¤   = FindWindowEx(hwndHeaders, hwndCC,¤¤   "Edit", NULL);
3a924a ¤   ¤   hwndAttach¤ = FindWindowEx(hwndHeaders, hwndBCC,¤   "Edit", NULL);
50af5a
97720b ¤   ¤   // Get all the recipients...
ed67dd ¤   ¤   if( hwndTo )
315b34 ¤   ¤   {
24f0a2 ¤   ¤   ¤   FieldLength = GetWindowTextLength( hwndTo );
83217a ¤   ¤   ¤   FieldLength += 2;
f1af5a
242ceb ¤   ¤   ¤   phd->pTo = (char*)malloc( FieldLength );
53af5a
a6f9ad ¤   ¤   ¤   if( phd->pTo )
0df776 ¤   ¤   ¤   {
cdebbb ¤   ¤   ¤   ¤   GetWindowText( hwndTo, phd->pTo, FieldLength + 2);
b7474c ¤   ¤   ¤   ¤   //MessageBox(NULL, pTo, "pTo", MB_OK);
e7a3a6 ¤   ¤   ¤   }
060fe4 ¤   ¤   }
41af5a
c3fb26 ¤   ¤   if( hwndCC )
325b34 ¤   ¤   {
76b962 ¤   ¤   ¤   FieldLength = GetWindowTextLength( hwndCC );
--9c3b 00046822565401101b4 Page 2 of EudoraMailHeaders.c
29217a ¤   ¤   ¤   FieldLength += 2;
4eaf5a
cf6671 ¤   ¤   ¤   phd->pCC = (char*)malloc( FieldLength );
39af5a
666556 ¤   ¤   ¤   if( phd->pCC )
54f776 ¤   ¤   ¤   {
efab13 ¤   ¤   ¤   ¤   GetWindowText( hwndCC, phd->pCC, FieldLength + 2);
085cdf ¤   ¤   ¤   ¤   //MessageBox(NULL, pCC, "pCC", MB_OK);
3ba3a6 ¤   ¤   ¤   }
b10fe4 ¤   ¤   }
beaf5a
6ec6d2 ¤   ¤   if( hwndBCC )
c05b34 ¤   ¤   {
b1aa69 ¤   ¤   ¤   FieldLength = GetWindowTextLength( hwndBCC );
6b217a ¤   ¤   ¤   FieldLength += 2;
8daf5a
33b6c1 ¤   ¤   ¤   phd->pBCC = (char*)malloc( FieldLength );
70af5a
a5b5cb ¤   ¤   ¤   if( phd->pBCC )
acf776 ¤   ¤   ¤   {
875b5e ¤   ¤   ¤   ¤   GetWindowText( hwndBCC, phd->pBCC, FieldLength + 2);
7b4dcb ¤   ¤   ¤   ¤   //MessageBox(NULL, pBCC, "pBCC", MB_OK);
faa3a6 ¤   ¤   ¤   }
9f0fe4 ¤   ¤   }
10af5a
6fa80c ¤   ¤   // get attachments
0b7d6f ¤   ¤   if(hwndAttach)
545b34 ¤   ¤   {
d40556 ¤   ¤   ¤   FieldLength = GetWindowTextLength( hwndAttach );
2d217a ¤   ¤   ¤   FieldLength += 2;
86af5a
4d467b ¤   ¤   ¤   phd->pAttachments = (char*)malloc( FieldLength );
e0af5a
668f96 ¤   ¤   ¤   if( phd->pAttachments )
29f776 ¤   ¤   ¤   {
c857a9 ¤   ¤   ¤   ¤   GetWindowText( hwndAttach,·
cf1e9b ¤   ¤   ¤   ¤   ¤   phd->pAttachments,·
9567d1 ¤   ¤   ¤   ¤   ¤   FieldLength + 2);
16a3a6 ¤   ¤   ¤   }
eb0fe4 ¤   ¤   }
3faf5a
2bac39 ¤   ¤   // get subject
bf9f6c ¤   ¤   if(hwndSubject)
ea5b34 ¤   ¤   {
47d9e5 ¤   ¤   ¤   FieldLength = GetWindowTextLength( hwndSubject );
af217a ¤   ¤   ¤   FieldLength += 2;
ebaf5a
c797c7 ¤   ¤   ¤   phd->pSubject = (char*)malloc( FieldLength );
37af5a
c7b0fb ¤   ¤   ¤   if( phd->pSubject )
81f776 ¤   ¤   ¤   {
2a882d ¤   ¤   ¤   ¤   GetWindowText( hwndSubject, phd->pSubject, FieldLength + 2);
c6a3a6 ¤   ¤   ¤   }
330fe4 ¤   ¤   }
49af5a
d7af5a
e69782 ¤   ¤   // get From
6f0729 ¤   ¤   if(hwndFrom)
9e5b34 ¤   ¤   {
5c6180 ¤   ¤   ¤   FieldLength = GetWindowTextLength( hwndFrom );
19217a ¤   ¤   ¤   FieldLength += 2;
74af5a
0da539 ¤   ¤   ¤   phd->pFrom = (char*)malloc( FieldLength );
37af5a
726461 ¤   ¤   ¤   if( phd->pFrom )
6ff776 ¤   ¤   ¤   {
6b5c72 ¤   ¤   ¤   ¤   GetWindowText( hwndFrom, phd->pFrom, FieldLength + 2);
b6a3a6 ¤   ¤   ¤   }
8f0fe4 ¤   ¤   }
959371 ¤   }
ebefe6 }
46af5a
--e542 000fbab5ed2401101b4 Page 3 of EudoraMailHeaders.c
e0af5a
3cfcdb DWORD CreateRecipientListFromEudoraHeaders(¤PHEADERDATA phd,·
225968 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   char*** Recipients)
17bb36 {
1ed6d3 ¤   int RecipientBufferLength = 0;
9e60f9 ¤   char* pAddresses = NULL;
ab2687 ¤   DWORD numRecipients = 0;
ffaf5a
f486d4 ¤   // initialize pNumAddresses and ppPGPRecipientList
24228a ¤   *Recipients = NULL;
07af5a
9ade23 ¤   // calculate initial length we might need for buffer
27ff07 ¤   if(phd->pTo)
07c7a1 ¤   {
ccbc4e ¤   ¤   RecipientBufferLength += strlen(phd->pTo);
e89371 ¤   }
3caf5a
fbcd1f ¤   if(phd->pCC)
b3c7a1 ¤   {
9520b5 ¤   ¤   RecipientBufferLength += strlen(phd->pCC);
ad9371 ¤   }
78af5a
20af5a
0733c9 ¤   if(phd->pBCC)
37c7a1 ¤   {
66936a ¤   ¤   RecipientBufferLength += strlen(phd->pBCC);
509371 ¤   }
e7af5a
b413da ¤   // make room for trailing NULL
f2a64c ¤   RecipientBufferLength += 1;
16af5a
bb6c7c ¤   // now strip out real email addresses and·
a99b35 ¤   // place in one list
3eef6b ¤   pAddresses = (char*) malloc( RecipientBufferLength + 3 );
27af5a
ed1a99 ¤   if(pAddresses)
84c7a1 ¤   {
9a40a7 ¤   ¤   char* pToken = NULL;
04af5a
4fc3c1 ¤   ¤   wsprintf(pAddresses, "%s,%s,%s", phd->pTo, phd->pCC, phd->pBCC);
d667c5 ¤
2a2a78 ¤   ¤   // iterate through the comma delimited list
642e07 ¤   ¤   pToken = strtok(pAddresses,",");
8bd83c ·
c6a39a ¤   ¤   while(pToken)
da5b34 ¤   ¤   {
f327ed ¤   ¤   ¤   char* pAtSymbol = NULL;
9baf5a
3d6128 ¤   ¤   ¤   if(!(*Recipients))
58f776 ¤   ¤   ¤   {
96076d ¤   ¤   ¤   ¤   *Recipients = (char**) malloc(sizeof(char*));
18a3a6 ¤   ¤   ¤   }
e1bb8c ¤   ¤   ¤   else
11f776 ¤   ¤   ¤   {
6c86e8 ¤   ¤   ¤   ¤   *Recipients = realloc(*Recipients,·
bccac1 ¤   ¤   ¤   ¤   ¤   ¤   ( sizeof(char*) * numRecipients) + sizeof(char*) );
10a3a6 ¤   ¤   ¤   }
2caf5a
5da54f ¤   ¤   ¤   // strip off leading spaces or tabs
80f0a0 ¤   ¤   ¤   while( *pToken == ' ' || *pToken == '\t')
5ef776 ¤   ¤   ¤   {
dca654 ¤   ¤   ¤   ¤   pToken++;
4fa3a6 ¤   ¤   ¤   }
f2af5a
6f0404 ¤   ¤   ¤   // strip off trailing spaces or tabs
070d62 ¤   ¤   ¤   while( *(pToken + strlen(pToken) - 1) == ' ' ||·
c51aac ¤   ¤   ¤   ¤   ¤   *(pToken + strlen(pToken) - 1) == '\t')
51f776 ¤   ¤   ¤   {
6004f9 ¤   ¤   ¤   ¤   memmove(pToken + 1, pToken, strlen(pToken) - 1);
82a654 ¤   ¤   ¤   ¤   pToken++;
7fa3a6 ¤   ¤   ¤   }
fbaf5a
--f387 0003a7d50a4401101b4 Page 4 of EudoraMailHeaders.c
ef735a ¤   ¤   ¤   //MessageBox(NULL, pToken, "pToken", MB_OK);
6faf5a
65ba43 ¤   ¤   ¤   // see if we can find an email address
46e4dd ¤   ¤   ¤   pAtSymbol = strchr(pToken, '@');
faaf5a
209421 ¤   ¤   ¤   if( pAtSymbol )
0bf776 ¤   ¤   ¤   {
f87670 ¤   ¤   ¤   ¤   char* pBeginning = NULL;
db4380 ¤   ¤   ¤   ¤   char* pEnd = NULL;
faae30 ¤   ¤   ¤   ¤   ¤
c21d94 ¤   ¤   ¤   ¤   // find the beginning and ending of the email address
078fdc ¤   ¤   ¤   ¤   pBeginning = pAtSymbol;
0a9464 ¤   ¤   ¤   ¤   pEnd = pAtSymbol;
34af5a
913a30 ¤   ¤   ¤   ¤   while(¤ !isspace(*pBeginning) &&·
fe0197 ¤   ¤   ¤   ¤   ¤   ¤   *(pBeginning - 1)!= '<' &&·
701a10 ¤   ¤   ¤   ¤   ¤   ¤   pBeginning > pToken)
9972c3 ¤   ¤   ¤   ¤   {
8db31b ¤   ¤   ¤   ¤   ¤   pBeginning--;
6f2613 ¤   ¤   ¤   ¤   }
55af5a
f41ae4 ¤   ¤   ¤   ¤   while(!isspace(*pEnd) && *pEnd != '>' && *pEnd != 0x00)
e372c3 ¤   ¤   ¤   ¤   {
1ee65a ¤   ¤   ¤   ¤   ¤   //MessageBox(NULL, pEnd, "pEnd", MB_OK);
5e2db5 ¤   ¤   ¤   ¤   ¤   pEnd++;
702613 ¤   ¤   ¤   ¤   }
61af5a
da4a44 ¤   ¤   ¤   ¤   *pEnd = 0x00;
fb2b85 ¤   ¤   ¤   ¤
76eebd ¤   ¤   ¤   ¤   if(*Recipients)
aa72c3 ¤   ¤   ¤   ¤   {
22af5a
e4a661 ¤   ¤   ¤   ¤   ¤   (*Recipients)[numRecipients] =·
588180 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(pBeginning) + 1);·
24af5a
317435 ¤   ¤   ¤   ¤   ¤   strcpy((*Recipients)[numRecipients++], pBeginning);
fd2613 ¤   ¤   ¤   ¤   }
b4af5a
44b702 ¤   ¤   ¤   ¤   //MessageBox(NULL, pRawAddresses, "Address", MB_OK);
e6a3a6 ¤   ¤   ¤   }
701b2a ¤   ¤   ¤   else // see if this is an alias
a2f776 ¤   ¤   ¤   {
7484f5 ¤   ¤   ¤   ¤   char szAddress[512];
b9af5a
fdebda ¤   ¤   ¤   ¤   if(GetEudoraAddressFromNickname(pToken,·
9db363 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szAddress,·
e64fc3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szAddress)) == 0)
c772c3 ¤   ¤   ¤   ¤   {
06fcd4 ¤   ¤   ¤   ¤   ¤   if( *Recipients )
2b4859 ¤   ¤   ¤   ¤   ¤   {
a2f3cd ¤   ¤   ¤   ¤   ¤   ¤   (*Recipients)[numRecipients] =·
8264d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(szAddress) + 1);·
9aaf5a
298b28 ¤   ¤   ¤   ¤   ¤   ¤   strcpy((*Recipients)[numRecipients++], szAddress);
2a1c89 ¤   ¤   ¤   ¤   ¤   }
692613 ¤   ¤   ¤   ¤   }
8a4050 ¤   ¤   ¤   ¤   else // append the default extension to the name
b472c3 ¤   ¤   ¤   ¤   {
939c0a ¤   ¤   ¤   ¤   ¤   char szDefaultDomain[256];
0d6beb ¤   ¤   ¤   ¤   ¤   char ApplicationPath[3 * MAX_PATH];
99404c ¤   ¤   ¤   ¤   ¤   HKEY hkey;
8878dc ¤   ¤   ¤   ¤   ¤   char szKey[] = "Software\\Qualcomm\\Eudora\\"
e34797 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "CommandLine\\current";
745b90 ¤   ¤   ¤   ¤   ¤   char* pEudoraPath = NULL;
80af5a
2ec0e2 ¤   ¤   ¤   ¤   ¤   // Get the Install Path from the Registry
724242 ¤   ¤   ¤   ¤   ¤   if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT,
0f5d52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szKey,
f2c118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
ade6c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,
76408c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hkey))
3a4859 ¤   ¤   ¤   ¤   ¤   {
--27d6 0009aabd5e4401101b4 Page 5 of EudoraMailHeaders.c
834490 ¤   ¤   ¤   ¤   ¤   ¤   DWORD Size,Type;
8daf5a
b9ff2b ¤   ¤   ¤   ¤   ¤   ¤   Size = sizeof(ApplicationPath);
3d0c7d ¤   ¤   ¤   ¤   ¤   ¤   RegQueryValueEx(hkey,·
16832d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
d58c2b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
f781fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &Type,·
f922c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (BYTE*)ApplicationPath,·
f0542c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &Size);
8faf5a
cf2b1a ¤   ¤   ¤   ¤   ¤   ¤   pEudoraPath = strrchr(ApplicationPath, 0x20);
fcaf5a
31f953 ¤   ¤   ¤   ¤   ¤   ¤   if(pEudoraPath)
f58fec ¤   ¤   ¤   ¤   ¤   ¤   {
cd27f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pEudoraPath++; // move past the space
aedb3c ¤   ¤   ¤   ¤   ¤   ¤   }
efaf5a
48597b ¤   ¤   ¤   ¤   ¤   ¤   RegCloseKey(hkey);
821c89 ¤   ¤   ¤   ¤   ¤   }
3baf5a
7036a3 ¤   ¤   ¤   ¤   ¤   GetPrivateProfileString(
04e01c ¤   ¤   ¤   ¤   ¤   ¤   "Settings",·
a84701 ¤   ¤   ¤   ¤   ¤   ¤   "DomainQualifier",·
e3f083 ¤   ¤   ¤   ¤   ¤   ¤   "",
8c590a ¤   ¤   ¤   ¤   ¤   ¤   szDefaultDomain,·
bf826b ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szDefaultDomain),
03516c ¤   ¤   ¤   ¤   ¤   ¤   pEudoraPath);
fcaf5a
4292d1 ¤   ¤   ¤   ¤   ¤   strcpy(szAddress, pToken);
b5af5a
859e40 ¤   ¤   ¤   ¤   ¤   // check to see if the string is empty or not
574b70 ¤   ¤   ¤   ¤   ¤   if(*szDefaultDomain)
ce4859 ¤   ¤   ¤   ¤   ¤   {
5a6f52 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szAddress, "@");
ddab17 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szAddress, szDefaultDomain);
5d1c89 ¤   ¤   ¤   ¤   ¤   }
09af5a
e5fcd4 ¤   ¤   ¤   ¤   ¤   if( *Recipients )
594859 ¤   ¤   ¤   ¤   ¤   {
13f3cd ¤   ¤   ¤   ¤   ¤   ¤   (*Recipients)[numRecipients] =·
7b64d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(szAddress) + 1);·
8caf5a
1b8b28 ¤   ¤   ¤   ¤   ¤   ¤   strcpy((*Recipients)[numRecipients++], szAddress);
961c89 ¤   ¤   ¤   ¤   ¤   }
132613 ¤   ¤   ¤   ¤   }
1ba3a6 ¤   ¤   ¤   }
1d1b52 ¤   ¤
c9234e ¤   ¤   ¤   pToken = strtok(NULL,",");
c80fe4 ¤   ¤   }
529371 ¤   }
0daf5a
77384d ¤   if( pAddresses )
7f9108 ¤   {·
bc9b66 ¤   ¤   free( pAddresses);
059371 ¤   }
d9af5a
cddde5 ¤   return numRecipients;
56efe6 }
22af5a
3aaf5a
311625 #define MAX_LINEBUF 500
ebaf5a
3d465d //
a04a91 // returns: -1 file error
525d90 //¤ ¤   ¤   -2 record too large (>MAX_LINEBUF bytes)
815439 //¤ ¤   ¤   ·1 not found
8b13f6 //¤ ¤   ¤   ·0 success
feaf5a
37f628 int GetEudoraAddressFromNickname(char *pNickname,·
77bd6c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char *pAddress,·
67ab06 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·int nAddressSize)
9abb36 {
--7a3a 00097cb7d1c401101b4 Page 6 of EudoraMailHeaders.c
fbed71 ¤   FILE *fh;
ff80dc ¤   char buffer[MAX_LINEBUF+1];
0432ee ¤   char *pEOL;
84b547 ¤   char *pSystemCommandLine, *pEudoraPath = NULL, *pEudoraExe;
1e0638 ¤   int¤ nNicknameLen;
e5663e ¤   int¤ nOffset;
8b7f64 ¤   int¤ rc = 1;
5daf5a
06b945 ¤   assert(pNickname);
a1a176 ¤   assert(pAddress);
9eaf5a
90726b ¤   //DebugBreak();
7aaf5a
d0d154 ¤   nNicknameLen = strlen(pNickname);
05af5a
46f191 ¤   //Get the pointer to the system's static buf:
356fe0 ¤   pSystemCommandLine = GetCommandLine();
2baf5a
1ef004 ¤   //plus 2 because "nndbase.txt" is one character more than "eudora.exe".
5555df ¤   if((pEudoraPath = (char*)malloc(strlen(pSystemCommandLine) + 2)))
46c7a1 ¤   {
34d12b ¤   ¤   strcpy(pEudoraPath, pSystemCommandLine);
ed6129 ¤   ¤   if((pEudoraExe = strstri(pEudoraPath, "\\eudora.exe")))
9c5b34 ¤   ¤   {
4c17c4 ¤   ¤   ¤   *pEudoraExe = '\0';
b8bbe3 ¤   ¤   ¤   strcat(pEudoraPath, "\\nndbase.txt");
ea0fe4 ¤   ¤   }
4a0e1d ¤   ¤   else
9b5b34 ¤   ¤   {
5ceba4 ¤   ¤   ¤   free(pEudoraPath);
ad1cbd ¤   ¤   ¤   pEudoraPath = NULL;
9a0fe4 ¤   ¤   }
a39371 ¤   }
caaf5a
e49635 ¤   if(pEudoraPath)
80c7a1 ¤   {
74573a ¤   ¤   //Win95 puts this string in quotes. ·#@&*^%@#^%!
648d2c ¤   ¤   if(*pEudoraPath == '\"')
7c326b ¤   ¤   ¤   nOffset = 1;
ce0e1d ¤   ¤   else
df68b7 ¤   ¤   ¤   nOffset = 0;
6aaf5a
b4ab06 ¤   ¤   fh = fopen((pEudoraPath + nOffset), "rt");
22ff8c ¤   ¤   free(pEudoraPath);
119371 ¤   }
e10e24 ¤   else
f3c7a1 ¤   {
0b1a70 ¤   ¤   fh = fopen("\\eudora\\nnbase.txt", "rt");
a09371 ¤   }
9aaf5a
7d88d4 ¤   if (!fh) {
c5043c ¤   ¤   return -1;
069371 ¤   }
faaf5a
5c9ea8 ¤   while (!feof(fh)) {
1de4f0 ¤   ¤   if (fgets(buffer, MAX_LINEBUF, fh) == NULL) {
eacdcb ¤   ¤   ¤   break;
4d0fe4 ¤   ¤   }
2ae8cd ¤   ¤   if ((pEOL = strchr(buffer, '\n')) == NULL) {
b13412 ¤   ¤   ¤   // no end of line...line too big
cbe341 ¤   ¤   ¤   rc = -2;
94cdcb ¤   ¤   ¤   break;
9b45a6 ¤   ¤   } else {
7cddab ¤   ¤   ¤   // stamp over it with a null
b7abe7 ¤   ¤   ¤   *pEOL = '\0';
980fe4 ¤   ¤   }
ddaf5a
11af5a
f30fbf ¤   ¤   nOffset = 6;
42cb70 ¤   ¤   // look for "alias ", that will follow the nickname and·
ecbbf0 ¤   ¤   // then the email address
9770bd ¤   ¤   // alias nickname foo@bar.com
--f760 0000707fc17401101b4 Page 7 of EudoraMailHeaders.c
e0af5a
55ea8e ¤   ¤   if (!strncmp(buffer, "alias ", nOffset)) {
c75995 ¤   ¤   ¤   // see if the nickname matches
79bdf9 ¤   ¤   ¤   if (!strncmp(buffer+nOffset, pNickname, nNicknameLen) &&·
be0836 ¤   ¤   ¤   ¤   buffer[nOffset+nNicknameLen] == ' ') {
ad8d86 ¤   ¤   ¤   ¤   // step past the nickname + white space, and·
e991f6 ¤   ¤   ¤   ¤   //copy the email address
bba5e9 ¤   ¤   ¤   ¤   nOffset += nNicknameLen+1;
f6d0c4 ¤   ¤   ¤   ¤   strncpy(pAddress, buffer+nOffset, nAddressSize);
9a8abf ¤   ¤   ¤   ¤   //These things seem to have trailing commas a lot...
5dd0dc ¤   ¤   ¤   ¤   if(*(pAddress + strlen(pAddress) - 1) == ',')
2fdce0 ¤   ¤   ¤   ¤   ¤   *(pAddress + strlen(pAddress) - 1) = '\0';
9b98a2 ¤   ¤   ¤   ¤   rc = 0;
7bf622 ¤   ¤   ¤   ¤   break;
2ba3a6 ¤   ¤   ¤   }
b00fe4 ¤   ¤   }
c89371 ¤   }
89654d ¤   fclose(fh);
928e33 ¤   return(rc);
a4efe6 }
55af5a
a8af5a
1bd2af void SetEudoraAttachments(HWND hwndHeaders, char* pAttach)
53bb36 {
cc3b6e ¤   HWND hwndTo = NULL;
65c247 ¤   HWND hwndFrom = NULL;
e30594 ¤   HWND hwndSubject = NULL;
b49fcd ¤   HWND hwndCC = NULL;
11a68f ¤   HWND hwndBCC = NULL;
aa6484 ¤   HWND hwndAttach = NULL;
e7862b ¤   long FieldLength = 0;
3baf5a
90c94d ¤   if( hwndHeaders ·&& pAttach )
64c7a1 ¤   {
07082d ¤   ¤   // Find the windows we are interested in...
677151 ¤   ¤   hwndTo¤ ¤   = FindWindowEx(hwndHeaders, NULL,¤  ¤   "Edit", NULL);
11c5e8 ¤   ¤   hwndFrom¤   = FindWindowEx(hwndHeaders, hwndTo,¤¤   "Edit", NULL);
111e78 ¤   ¤   hwndSubject = FindWindowEx(hwndHeaders, hwndFrom,¤  "Edit", NULL);
4759cf ¤   ¤   hwndCC¤ ¤   = FindWindowEx(hwndHeaders, hwndSubject,"Edit", NULL);
f9a723 ¤   ¤   hwndBCC¤¤   = FindWindowEx(hwndHeaders, hwndCC,¤¤   "Edit", NULL);
f1924a ¤   ¤   hwndAttach¤ = FindWindowEx(hwndHeaders, hwndBCC,¤   "Edit", NULL);
cbaf5a
9b4fa4 ¤   ¤   SetWindowText(hwndAttach, pAttach);
d89371 ¤   }
aaefe6 }
0caf5a
ebe1a1 void FreeHeaderData(PHEADERDATA phd)
65bb36 {
5b20a5 ¤   if( phd->pTo )
c4c7a1 ¤   {
ba0bf4 ¤   ¤   free(phd->pTo);
699371 ¤   }
60af5a
69170d ¤   if( phd->pFrom)
adc7a1 ¤   {
63259f ¤   ¤   free(phd->pFrom);
659371 ¤   }
17af5a
83bc5e ¤   if( phd->pCC )
f5c7a1 ¤   {
a8970f ¤   ¤   free(phd->pCC);
4f9371 ¤   }
91af5a
d7395a ¤   if( phd->pBCC )
b4c7a1 ¤   {
33890c ¤   ¤   free(phd->pBCC);
9d9371 ¤   }
5baf5a
a5a934 ¤   if( phd->pAttachments )
48c7a1 ¤   {
398343 ¤   ¤   free(phd->pAttachments);
079371 ¤   }
--8292 0017e9a6272401101b4 Page 8 of EudoraMailHeaders.c
e0af5a
a5ebc0 ¤   if( phd->pSubject )
4fc7a1 ¤   {
45ceee ¤   ¤   free(phd->pSubject);
da9371 ¤   }
9baf5a
0f902d ¤   if( phd->pEmailSig )
bec7a1 ¤   {
18ab05 ¤   ¤   free(phd->pEmailSig);
0d9371 ¤   }
66af5a
aaefe6 }
2baf5a
7eaf5a
--8b50 001deb388ad401101b5 Page 1 of EudoraMailHeaders.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ea7d78 ¤   EudoraMailHeaders.h,v 1.4 1997/07/29 01:47:39 elrod Exp
07f7f7 ____________________________________________________________________________*/
4a7c66 #ifndef Included_EudoraMailHeaders_h¤   /* [ */
01304d #define Included_EudoraMailHeaders_h
cbaf5a
6eaf5a
7bb7dc typedef struct _HEADERDATA
e3bb36 {
83925f ¤   char*¤  pTo;·
ae6a53 ¤   char*¤  pFrom;·
71ba8a ¤   char*¤  pCC;
e36696 ¤   char*¤  pBCC;
9ee502 ¤   char*¤  pSubject;
77fc61 ¤   char*¤  pAttachments;
6e247b ¤   char*¤  pEmailSig;
3906f4 ¤   int¤¤   priority;
99c40b ¤   int¤¤   receipt;
82af5a
2bdd39 }HEADERDATA, *PHEADERDATA;
0daf5a
cdc823 void·
547f35 GetEudoraHeaders(¤  HWND hwndHeaders,·
59a035 ¤   ¤   ¤   ¤   ¤   PHEADERDATA phd);
f0af5a
e8fcdb DWORD CreateRecipientListFromEudoraHeaders(¤PHEADERDATA phd,·
7def37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   char*** Recipients);
3faf5a
5e6351 void SetEudoraAttachments(HWND hwndHeaders,
5680d4 ¤   ¤   ¤   ¤   ¤   ¤   ··char* pAttach);
42af5a
5baf5a
091828 void FreeHeaderData( PHEADERDATA phd );
b8af5a
fe0480 #endif /* ] Included_EudoraMailHeaders_h */
89af5a
94af5a
687e4d /*__Editor_settings____
e5af5a
504126 ¤   Local Variables:
e67b17 ¤   tab-width: 4
db0e6c ¤   End:
c75f8c ¤   vi: ts=4 sw=4
4a9e9b ¤   vim: si
08d062 _____________________*/
deaf5a
--f595 0001abd1f3f401101b6 Page 1 of EudoraMainWndProc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
88c4cc ¤   $Id: EudoraMainWndProc.c,v 1.22.8.1 1998/11/12 03:11:25 heller Exp $
84f7f7 ____________________________________________________________________________*/
4aaf5a
f99b16 // System Headers
3c5655 #include <windows.h>
de3d0b #include <windowsx.h>
8790fb #include <commctrl.h>
8f2f6f #include <richedit.h>
3eaf5a
cd5582 // PGPsdk Headers
54e2ff #include "pgpConfig.h"
aaa076 #include "pgpKeys.h"
7c2f8d #include "pgpErrors.h"
294919 #include "pgpUtilities.h"
93ec82 #include "pgpTLS.h"
3faf5a
3b2062 // Shared Headers
b55ab2 #include "PGPcl.h"
46af5a
23e8e0 // Project Headers
8d05f4 #include "AddKey.h"
6b6c40 #include "PGPDefinedMessages.h"
128031 #include "resource.h"
29af5a
2d482b // Global Variables
127679 HWND¤   ¤   ¤   ¤   ¤   g_hwndEudoraStatusbar = NULL;
2d5f9c HWND¤   ¤   ¤   ¤   ¤   g_hwndEudoraMainWindow = NULL;
53af5a
d16ba0 extern HINSTANCE¤   ¤   g_hinst;
911c13 extern PGPContextRef¤   g_pgpContext;
4c6768 extern PGPtlsContextRef¤g_tlsContext;
19d742 extern HHOOK¤   ¤   ¤   g_hCBTHook;
e1215b extern UINT¤¤   ¤   ¤   g_nPurgeCacheMsg;
05af5a
ceaf5a
020218 LRESULT·
5542ef WINAPI·
fcaaae EudoraMainWndProc(HWND hwnd,·
148d94 ¤   ¤   ¤   ¤   ··UINT msg,·
e0b6dd ¤   ¤   ¤   ¤   ··WPARAM wParam,·
4c89a3 ¤   ¤   ¤   ¤   ··LPARAM lParam)
7fbb36 {
14c9cd ¤   WNDPROC lpOldProc;
a2cbbe ¤   static BOOL bShutdown = FALSE;
85af5a
30215d ¤   lpOldProc = (WNDPROC)GetProp( hwnd, "oldproc" );
bee8c6 ···
ee5b13 ¤   if (msg == g_nPurgeCacheMsg)
e9c7a1 ¤   {
b584b4 ¤   ¤   PGPclPurgeCachedPassphrase(wParam);
c9836c ¤   ¤   return TRUE;
df9371 ¤   }
6baf5a
859467 ¤   switch(msg)
3d9108 ¤   {·
5caf5a
0d3cdc ¤   ¤   case WM_DESTROY: ··
3e5b34 ¤   ¤   {
8862d2 ¤   ¤   ¤   // ·Put back old window proc and
651d17 ¤   ¤   ¤   SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );
57af5a
53b94c ¤   ¤   ¤   if(g_hCBTHook)
17f776 ¤   ¤   ¤   {
2f04ce ¤   ¤   ¤   ¤   UnhookWindowsHookEx(g_hCBTHook);
67a3a6 ¤   ¤   ¤   }
1aaf5a
--14bd 000d2dd0513401101b6 Page 2 of EudoraMainWndProc.c
f00b20 ¤   ¤   ¤   PGPclPurgeCachedPassphrase (
12f325 ¤   ¤   ¤   ¤   PGPCL_DECRYPTIONCACHE|PGPCL_SIGNINGCACHE);
b9af5a
8e0b63 ¤   ¤   ¤   if( PGPRefIsValid(g_pgpContext) )
aff776 ¤   ¤   ¤   {
fd64bc ¤   ¤   ¤   ¤   PGPclCloseLibrary();
b9e826 ¤   ¤   ¤   ¤   PGPFreeTLSContext(g_tlsContext);
ca6e0a ¤   ¤   ¤   ¤   PGPFreeContext(g_pgpContext);
99a3a6 ¤   ¤   ¤   }
8daf5a
6daf5a
ac8170 ¤   ¤   ¤   RemoveProp(hwnd, "oldproc");
59cdcb ¤   ¤   ¤   break;
a90fe4 ¤   ¤   }
2baf5a
22e142 ¤   ¤   case WM_ENDSESSION:
055b34 ¤   ¤   {
7dc6a6 ¤   ¤   ¤   bShutdown = (BOOL)wParam;
4aaf5a
a138be ¤   ¤   ¤   SendMessage(hwnd, WM_CLOSE, 0,0);
358144 ¤   ¤   ¤   return 0;
9dcdcb ¤   ¤   ¤   break;
190fe4 ¤   ¤   }
cbaf5a
56fed0 ¤   ¤   case WM_MENUSELECT:
d95b34 ¤   ¤   {
29382f ¤   ¤   ¤   char szStatus[256];
44af5a
ace5f1 ¤   ¤   ¤   strcpy(szStatus, "");
4daf5a
dc9164 ¤   ¤   ¤   switch(LOWORD(wParam))
dff776 ¤   ¤   ¤   {
c73c99 ¤   ¤   ¤   ¤   case ID_PREFERENCES:
6772c3 ¤   ¤   ¤   ¤   {
e803f1 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPPREFSTATUS, szStatus,
0b6900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
0b14c3 ¤   ¤   ¤   ¤   ¤   break;
042613 ¤   ¤   ¤   ¤   }
3dda4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
f1af5a
715ed9 ¤   ¤   ¤   ¤   case ID_ABOUTPGP:
9c72c3 ¤   ¤   ¤   ¤   {
fe40e6 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPABOUTSTATUS, szStatus,
f56900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
5714c3 ¤   ¤   ¤   ¤   ¤   break;
8c2613 ¤   ¤   ¤   ¤   }
ce2b85 ¤   ¤   ¤   ¤
ffaf5a
7bc784 ¤   ¤   ¤   ¤   case ID_PGPKEYS:
ce72c3 ¤   ¤   ¤   ¤   {
5d3d71 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPKEYSSTATUS, szStatus,
586900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
b814c3 ¤   ¤   ¤   ¤   ¤   break;
222613 ¤   ¤   ¤   ¤   }
ab2b85 ¤   ¤   ¤   ¤
b0af5a
c5896b ¤   ¤   ¤   ¤   case ID_PGPHELP:
b972c3 ¤   ¤   ¤   ¤   {
4354cd ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPHELPSTATUS, szStatus,
836900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
6b14c3 ¤   ¤   ¤   ¤   ¤   break;
c32613 ¤   ¤   ¤   ¤   }
fdaf5a
62bef9 ¤   ¤   ¤   ¤   case ID_PGPDECRYPTVERIFY:
ff72c3 ¤   ¤   ¤   ¤   {
309fe7 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPDECRYPTSTATUS, szStatus,
d96900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
f014c3 ¤   ¤   ¤   ¤   ¤   break;
822613 ¤   ¤   ¤   ¤   }
29af5a
3ca830 ¤   ¤   ¤   ¤   case ID_PGPENCRYPTSIGN:
d272c3 ¤   ¤   ¤   ¤   {
--f04d 000077ef1d0401101b6 Page 3 of EudoraMainWndProc.c
05ff3d ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPENCRYPTSIGNSTATUS, szStatus,
c76900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
8c14c3 ¤   ¤   ¤   ¤   ¤   break;
4a2613 ¤   ¤   ¤   ¤   }
38c455 ¤   ¤   ¤   ¤   case ID_PGPSIGN:
2172c3 ¤   ¤   ¤   ¤   {
317880 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPSIGNSTATUS, szStatus,
526900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
db14c3 ¤   ¤   ¤   ¤   ¤   break;
512613 ¤   ¤   ¤   ¤   }
c37dee ¤   ¤   ¤   ¤   case ID_PGPENCRYPT:
3e72c3 ¤   ¤   ¤   ¤   {
7abc52 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPENCRYPTSTATUS, szStatus,
026900 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szStatus));
f714c3 ¤   ¤   ¤   ¤   ¤   break;
7e2613 ¤   ¤   ¤   ¤   }
36af5a
a25a2a ¤   ¤   ¤   }¤
0f87c7 ¤   ¤   ¤
54f263 ¤   ¤   ¤   if (strlen(szStatus) > 0)
8ebaf1 ¤   ¤   ¤   ¤   SendMessage(g_hwndEudoraStatusbar,
2f436f ¤   ¤   ¤   ¤   ¤   SB_SETTEXT,
8d3865 ¤   ¤   ¤   ¤   ¤   0,
49c634 ¤   ¤   ¤   ¤   ¤   (LPARAM) szStatus);
03af5a
11cdcb ¤   ¤   ¤   break;
fb0fe4 ¤   ¤   }
12af5a
ced752 ¤   ¤   case WM_INITMENUPOPUP:
265b34 ¤   ¤   {
2f031c ¤   ¤   ¤   HMENU hmenuPopup = (HMENU) wParam; ···// handle of submenu
c324fa ¤   ¤   ¤   UINT uPos = (UINT) LOWORD(lParam); ···// submenu item position·
4a5c3b ¤   ¤   ¤   BOOL fSystemMenu = (BOOL) HIWORD(lParam); // window menu flag·
e6cf15 ¤   ¤   ¤   LRESULT ReturnValue = 0;
34af5a
1377f6 ¤   ¤   ¤   ReturnValue = CallWindowProc(¤  lpOldProc,·
56f175 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd,·
bc5947 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   msg,·
79fcd8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam,·
db25e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lParam ) ;
6daf5a
b41407 ¤   ¤   ¤   if(hmenuPopup && !fSystemMenu)
bef776 ¤   ¤   ¤   {
f7e95d ¤   ¤   ¤   ¤   char szMenuString[256] = {0x00};
b7ed15 ¤   ¤   ¤   ¤   char szEncryptMenu[256];
803223 ¤   ¤   ¤   ¤   char szPGPkeysMenu[256];
66a59b ¤   ¤   ¤   ¤   char szDecryptMenu[256];
29af5a
700d0d ¤   ¤   ¤   ¤   GetMenuString(¤ hmenuPopup,·
5ec118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
f02234 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szMenuString,·
7e9754 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szMenuString),·
2b893e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYPOSITION);
d2af5a
7961ef ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_ENCRYPTMENU, szEncryptMenu,
93a954 ¤   ¤   ¤   ¤   ¤   sizeof(szEncryptMenu));
6105b1 ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPKEYSMENU, szPGPkeysMenu,
f31ba5 ¤   ¤   ¤   ¤   ¤   sizeof(szPGPkeysMenu));
4353e4 ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_DECRYPTMENU, szDecryptMenu,
198d23 ¤   ¤   ¤   ¤   ¤   sizeof(szDecryptMenu));
4eaf5a
0473d9 ¤   ¤   ¤   ¤   if( !strcmp(szMenuString, szEncryptMenu) ||·
ac91fb ¤   ¤   ¤   ¤   ¤   !strcmp(szMenuString, szPGPkeysMenu) ||·
862717 ¤   ¤   ¤   ¤   ¤   !strcmp(szMenuString, szDecryptMenu) )
9172c3 ¤   ¤   ¤   ¤   {
82d6bd ¤   ¤   ¤   ¤   ¤   EnableMenuItem( hmenuPopup, 0, MF_BYPOSITION|MF_ENABLED);·
601389 ¤   ¤   ¤   ¤   ¤   EnableMenuItem( hmenuPopup, 1, MF_BYPOSITION|MF_ENABLED);·
9554c4 ¤   ¤   ¤   ¤   ¤   EnableMenuItem( hmenuPopup, 2, MF_BYPOSITION|MF_ENABLED);·
4391f0 ¤   ¤   ¤   ¤   ¤   EnableMenuItem( hmenuPopup, 3, MF_BYPOSITION|MF_ENABLED);·
30da5e ¤   ¤   ¤   ¤   ¤   EnableMenuItem( hmenuPopup, 4, MF_BYPOSITION|MF_ENABLED);·
1d2613 ¤   ¤   ¤   ¤   }
07a3a6 ¤   ¤   ¤   }
--e681 000f46c540e401101b6 Page 4 of EudoraMainWndProc.c
e0af5a
8b425e ¤   ¤   ¤   return ReturnValue;
85cdcb ¤   ¤   ¤   break;
4c0fe4 ¤   ¤   }
e8af5a
93af5a
719b01 ¤   ¤   case WM_INITMENU:
d75b34 ¤   ¤   {
916b9d ¤   ¤   ¤   HMENU hmenu = (HMENU) wParam;
b8cf15 ¤   ¤   ¤   LRESULT ReturnValue = 0;
ceaf5a
7f77f6 ¤   ¤   ¤   ReturnValue = CallWindowProc(¤  lpOldProc,·
daf175 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd,·
0e5947 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   msg,·
45fcd8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam,·
f525e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lParam ) ;
fdaf5a
9c1ff6 ¤   ¤   ¤   if(hmenu)
5df776 ¤   ¤   ¤   {
a784c9 ¤   ¤   ¤   ¤   HMENU submenu = NULL;
44119c ¤   ¤   ¤   ¤   HMENU PGPMenu = NULL;
7de95d ¤   ¤   ¤   ¤   char szMenuString[256] = {0x00};
5510dd ¤   ¤   ¤   ¤   char szCutMenu[256];
d91992 ¤   ¤   ¤   ¤   char szCopyMenu[256];
4aaf5a
4ac405 ¤   ¤   ¤   ¤   GetMenuString(¤ hmenu,·
3ac118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
432234 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szMenuString,·
2a9754 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szMenuString),·
6c893e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYPOSITION);
32af5a
eba12c ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_CUTMENU, szCutMenu,
cfe993 ¤   ¤   ¤   ¤   ¤   sizeof(szCutMenu));
323073 ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_COPYMENU, szCopyMenu,
0ef7e6 ¤   ¤   ¤   ¤   ¤   sizeof(szCopyMenu));
32af5a
b35e71 ¤   ¤   ¤   ¤   if(!strcmp(szMenuString, szCutMenu))
7b72c3 ¤   ¤   ¤   ¤   {
96fd20 ¤   ¤   ¤   ¤   ¤   PGPMenu = LoadMenu(¤g_hinst,·
849cb8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDM_PGPENCRYPTMENU));
09af5a
5fadf7 ¤   ¤   ¤   ¤   ¤   AppendMenu(hmenu, MF_ENABLED|MF_SEPARATOR , 0, "");
85368d ¤   ¤   ¤   ¤   ¤   AppendMenu(hmenu, MF_ENABLED|MF_STRING|MF_POPUP ,·
7d50d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (UINT)PGPMenu, "P&GP");
5a2613 ¤   ¤   ¤   ¤   }
791b65 ¤   ¤   ¤   ¤   else if(!strcmp(szMenuString, szCopyMenu))
c272c3 ¤   ¤   ¤   ¤   {
7ffd20 ¤   ¤   ¤   ¤   ¤   PGPMenu = LoadMenu(¤g_hinst,·
1ab8cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDM_PGPDECRYPTMENU));
52af5a
66adf7 ¤   ¤   ¤   ¤   ¤   AppendMenu(hmenu, MF_ENABLED|MF_SEPARATOR , 0, "");
d0368d ¤   ¤   ¤   ¤   ¤   AppendMenu(hmenu, MF_ENABLED|MF_STRING|MF_POPUP ,·
ee50d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (UINT)PGPMenu, "P&GP");
e92613 ¤   ¤   ¤   ¤   }
1da3a6 ¤   ¤   ¤   }
85af5a
4c425e ¤   ¤   ¤   return ReturnValue;
62cdcb ¤   ¤   ¤   break;
f10fe4 ¤   ¤   }
97af5a
d88e1e ¤   ¤   case WM_COMMAND:
e45b34 ¤   ¤   {
2fa168 ¤   ¤   ¤   switch( LOWORD(wParam) )
b2f776 ¤   ¤   ¤   {
61039c ¤   ¤   ¤   ¤   case IDC_SENDMAIL:
0972c3 ¤   ¤   ¤   ¤   {
4d3505 ¤   ¤   ¤   ¤   ¤   HWND hwndMDIClient = NULL;
712cba ¤   ¤   ¤   ¤   ¤   HWND hwndActive = NULL;
8baf5a
160ebe ¤   ¤   ¤   ¤   ¤   hwndMDIClient = FindWindowEx(¤  hwnd,·
8b4d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
f4f29e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "MDIClient",·
--498b 0002e061ce4401101b6 Page 5 of EudoraMainWndProc.c
615152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
d8af5a
7d82ec ¤   ¤   ¤   ¤   ¤   if(hwndMDIClient)
b24859 ¤   ¤   ¤   ¤   ¤   {
4d0fb0 ¤   ¤   ¤   ¤   ¤   ¤   hwndActive = (HWND)SendMessage(¤hwndMDIClient,·
22b9bd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_MDIGETACTIVE,·
8ed8c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
fec410 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
d2af5a
503c52 ¤   ¤   ¤   ¤   ¤   ¤   if(hwndActive)
3b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
70ee4e ¤   ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndToolbar = NULL;
f9af5a
ae86f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar = ·FindWindowEx(hwndActive,·
5b4d61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
7e7e96 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",·
4851b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
faaf5a
d47f17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(hwndToolbar)
7006b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
a3ba22 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndToolbar,·
842ded ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,
daf1c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_SENDMAIL,·
e588aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
192b30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return 0;
965268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
fbdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
431c89 ¤   ¤   ¤   ¤   ¤   }
ab14c3 ¤   ¤   ¤   ¤   ¤   break;
8ab889 ¤   ¤   ¤   ¤   }¤
a9af5a
045ed9 ¤   ¤   ¤   ¤   case ID_ABOUTPGP:
d772c3 ¤   ¤   ¤   ¤   {
38bd5d ¤   ¤   ¤   ¤   ¤   PGPclHelpAbout (g_pgpContext, hwnd, NULL, NULL, NULL);
5d14c3 ¤   ¤   ¤   ¤   ¤   break;
a42613 ¤   ¤   ¤   ¤   }
2eaf5a
d1896b ¤   ¤   ¤   ¤   case ID_PGPHELP:
8672c3 ¤   ¤   ¤   ¤   {
43abd7 ¤   ¤   ¤   ¤   ¤   CHAR szHelpFile[MAX_PATH] = {0x00};
f47da3 ¤   ¤   ¤   ¤   ¤   char szKey[] =¤ "Software\\Microsoft\\Windows\\"
3a52d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "CurrentVersion\\App Paths\\PGPKeys.exe";
c120dd ¤   ¤   ¤   ¤   ¤   HKEY hKey;
a98e49 ¤   ¤   ¤   ¤   ¤   LONG lResult;
bcc780 ¤   ¤   ¤   ¤   ¤   CHAR* p;
8dafa8 ¤   ¤   ¤   ¤   ¤   DWORD dwValueType, dwSize;
4e9322 ¤   ¤   ¤   ¤   ¤   char szHelpName[256];
e3af5a
850a4d ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_HELPFILE, szHelpName,
580f9f ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szHelpName));
bbaf5a
d7326a ¤   ¤   ¤   ¤   ¤   lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE,·
c01a34 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szKey,
24947b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
13b068 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_READ,·
ae65ba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
b1af5a
21dedf ¤   ¤   ¤   ¤   ¤   if (lResult == ERROR_SUCCESS)·
5c4859 ¤   ¤   ¤   ¤   ¤   {
c13abd ¤   ¤   ¤   ¤   ¤   ¤   dwSize = MAX_PATH;
eb0de4 ¤   ¤   ¤   ¤   ¤   ¤   lResult = RegQueryValueEx (¤hKey,·
054d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
f74d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
51e8dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwValueType,·
a224c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)szHelpFile,·
134ac5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwSize);
18e5f1 ¤   ¤   ¤   ¤   ¤   ¤   RegCloseKey (hKey);
7d1faa ¤   ¤   ¤   ¤   ¤   ¤   p = strrchr (szHelpFile, '\\');
10b4cb ¤   ¤   ¤   ¤   ¤   ¤   if (p)·
858fec ¤   ¤   ¤   ¤   ¤   ¤   {
851b99 ¤   ¤   ¤   ¤   ¤   ¤   ¤   p++;
2e3fbb ¤   ¤   ¤   ¤   ¤   ¤   ¤   *p = '\0';
--a847 00016a0bb89401101b6 Page 6 of EudoraMainWndProc.c
62abb1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szHelpFile, szHelpName);
8cdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
a81fe8 ¤   ¤   ¤   ¤   ¤   ¤   else·
75b758 ¤   ¤   ¤   ¤   ¤   ¤   {¤
9836e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   lstrcpy (szHelpFile, "");
dcdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
6d1c89 ¤   ¤   ¤   ¤   ¤   }
61af5a
ef4bb0 ¤   ¤   ¤   ¤   ¤   WinHelp (hwnd, szHelpFile, HELP_FINDER, 0);
66af5a
6814c3 ¤   ¤   ¤   ¤   ¤   break;
da2613 ¤   ¤   ¤   ¤   }
76af5a
28c784 ¤   ¤   ¤   ¤   case ID_PGPKEYS:
b572c3 ¤   ¤   ¤   ¤   {
5ae9bf ¤   ¤   ¤   ¤   ¤   char szPath[MAX_PATH];
cf960f ¤   ¤   ¤   ¤   ¤   char szPGPkeys[256];
69d2bc ¤   ¤   ¤   ¤   ¤   PGPError error = kPGPError_NoErr;
40af5a
411f75 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPKEYSEXE, szPGPkeys,
5ccece ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szPGPkeys));
d9af5a
608ce8 ¤   ¤   ¤   ¤   ¤   error = PGPclGetPGPPath (szPath, sizeof(szPath));
b4af5a
272b28 ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
344859 ¤   ¤   ¤   ¤   ¤   {
4367d0 ¤   ¤   ¤   ¤   ¤   ¤   // '/s' keeps it from showing that·
426f27 ¤   ¤   ¤   ¤   ¤   ¤   // damn splash screen
f65435 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPath, szPGPkeys);
d9e38f ¤   ¤   ¤   ¤   ¤   ¤   // run it...
14cf88 ¤   ¤   ¤   ¤   ¤   ¤   WinExec(szPath, SW_SHOW);
581c89 ¤   ¤   ¤   ¤   ¤   }
3e4bd6 ¤   ¤   ¤   ¤   ¤   else
d14859 ¤   ¤   ¤   ¤   ¤   {
bd9bb5 ¤   ¤   ¤   ¤   ¤   ¤   char szError[256];
ceaf5a
4075e5 ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_E_LAUNCHPGPKEYS, szError,
25e442 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szError));
82af5a
474c3a ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(NULL,·
4f1b14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szError,·
764ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
025380 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK);
151c89 ¤   ¤   ¤   ¤   ¤   }
b5ae30 ¤   ¤   ¤   ¤   ¤
8e14c3 ¤   ¤   ¤   ¤   ¤   break;
1db889 ¤   ¤   ¤   ¤   }¤
c1af5a
083c99 ¤   ¤   ¤   ¤   case ID_PREFERENCES:
0e72c3 ¤   ¤   ¤   ¤   {
ed6f9d ¤   ¤   ¤   ¤   ¤   PGPclPreferences (g_pgpContext, hwnd, 2, NULL);
e014c3 ¤   ¤   ¤   ¤   ¤   break;
74b889 ¤   ¤   ¤   ¤   }¤
9baf5a
7abef9 ¤   ¤   ¤   ¤   case ID_PGPDECRYPTVERIFY:
5272c3 ¤   ¤   ¤   ¤   {
723505 ¤   ¤   ¤   ¤   ¤   HWND hwndMDIClient = NULL;
8b2cba ¤   ¤   ¤   ¤   ¤   HWND hwndActive = NULL;
16af5a
e7a5b4 ¤   ¤   ¤   ¤   ¤   hwndMDIClient = FindWindowEx¤   (hwnd,·
204d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
e3f29e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "MDIClient",·
425152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
f9af5a
4b82ec ¤   ¤   ¤   ¤   ¤   if(hwndMDIClient)
8b4859 ¤   ¤   ¤   ¤   ¤   {
100fb0 ¤   ¤   ¤   ¤   ¤   ¤   hwndActive = (HWND)SendMessage(¤hwndMDIClient,·
6cb9bd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_MDIGETACTIVE,·
63d8c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
3bc410 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
e8af5a
163c52 ¤   ¤   ¤   ¤   ¤   ¤   if(hwndActive)
--22fd 0004866060c401101b6 Page 7 of EudoraMainWndProc.c
5b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
6bee4e ¤   ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndToolbar = NULL;
96af5a
1486f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar = ·FindWindowEx(hwndActive,·
0d4d61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
9c7e96 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",·
9851b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
05af5a
157f17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(hwndToolbar)
a906b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
260c8d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   switch(wParam)
9231b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
e68774 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   case ID_PGPDECRYPTVERIFY:
8bdec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
cde43b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndToolbar,·
1366a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,
55898a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_DECRYPT,
2fac45 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);¤
9652b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
898a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
8c6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
155268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
be6181 ¤   ¤   ¤   ¤   ¤   ¤   }¤
851c89 ¤   ¤   ¤   ¤   ¤   }
5814c3 ¤   ¤   ¤   ¤   ¤   break;
9e2613 ¤   ¤   ¤   ¤   }
eaaf5a
17a830 ¤   ¤   ¤   ¤   case ID_PGPENCRYPTSIGN:
a1c455 ¤   ¤   ¤   ¤   case ID_PGPSIGN:
a47dee ¤   ¤   ¤   ¤   case ID_PGPENCRYPT:
2872c3 ¤   ¤   ¤   ¤   {
ec3505 ¤   ¤   ¤   ¤   ¤   HWND hwndMDIClient = NULL;
752cba ¤   ¤   ¤   ¤   ¤   HWND hwndActive = NULL;
e1af5a
f3ae30 ¤   ¤   ¤   ¤   ¤
dd0ebe ¤   ¤   ¤   ¤   ¤   hwndMDIClient = FindWindowEx(¤  hwnd,·
f84d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
25f29e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "MDIClient",·
375152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
bfaf5a
b582ec ¤   ¤   ¤   ¤   ¤   if(hwndMDIClient)
3f4859 ¤   ¤   ¤   ¤   ¤   {
2774a5 ¤   ¤   ¤   ¤   ¤   ¤   hwndActive = (HWND)SendMessage(hwndMDIClient,·
b1b9bd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_MDIGETACTIVE,·
00d8c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
19c410 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
04af5a
ba3c52 ¤   ¤   ¤   ¤   ¤   ¤   if(hwndActive)
2c8fec ¤   ¤   ¤   ¤   ¤   ¤   {
05ee4e ¤   ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndToolbar = NULL;
8af1fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndPGPToolbar = NULL;
d4af5a
8886f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar = ·FindWindowEx(hwndActive,·
a24d61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
aa7e96 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",·
c851b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
6daf5a
6abadd ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndPGPToolbar = FindWindowEx(¤ hwndToolbar,·
2dc09d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
ddfaee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",
f3dc4c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
a0af5a
567356 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(hwndPGPToolbar)
2406b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
cd0c8d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   switch(wParam)
7c31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
96eb60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   case ID_PGPENCRYPT:
60dec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
243b6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndPGPToolbar,
502c49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
618b7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_ENCRYPT,·
4802bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
--d9b9 0001077a18a401101b6 Page 8 of EudoraMainWndProc.c
fa52b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
108a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
6baf5a
2efbee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   case ID_PGPSIGN:
e7dec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
dd3b6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndPGPToolbar,
962c49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
c5adbe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_SIGN,·
cc02bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
5c52b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
7e8a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
74af5a
9e74bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   case ID_PGPENCRYPTSIGN:
11dec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
5e3b6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndPGPToolbar,
e8d53b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
ab88e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_ENCRYPT,·
23012e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
81af5a
a93b6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndPGPToolbar,
14d53b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
c633ce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_SIGN,·
7a012e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
5f52b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
ac8a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
d76560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
d4da4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
a9ba22 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndToolbar,·
852ded ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,
ed4c30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_JUSTDOIT,·
8de734 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)SENT_FROM_CONTEXT_MENU);
f1af5a
7a5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
df6181 ¤   ¤   ¤   ¤   ¤   ¤   }¤
171c89 ¤   ¤   ¤   ¤   ¤   }
18ae30 ¤   ¤   ¤   ¤   ¤
c114c3 ¤   ¤   ¤   ¤   ¤   break;
b22613 ¤   ¤   ¤   ¤   }
21a3a6 ¤   ¤   ¤   }
54af5a
bbcdcb ¤   ¤   ¤   break;
5f0fe4 ¤   ¤   }
c547d1 ¤   }·
d267c5 ¤
50c543 ¤   // ·Pass all non-custom messages to old window proc
93afea ¤   return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam ) ;
22efe6 }
b1af5a
9caf5a
6e6565 LRESULT WINAPI EudoraStatusbarWndProc(HWND hwnd,·
695a62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
c1bdba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
9cb618 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
11bb36 {
5ac9cd ¤   WNDPROC lpOldProc;
54af5a
6c215d ¤   lpOldProc = (WNDPROC)GetProp( hwnd, "oldproc" );
f7e8c6 ···
a39467 ¤   switch(msg)
22c7a1 ¤   {
5f3cdc ¤   ¤   case WM_DESTROY: ··
6c5b34 ¤   ¤   {
0f62d2 ¤   ¤   ¤   // ·Put back old window proc and
1f1d17 ¤   ¤   ¤   SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );
5caf5a
073d89 ¤   ¤   ¤   // ·remove window property
e19697 ¤   ¤   ¤   RemoveProp( hwnd, "oldproc" );·
8ccdcb ¤   ¤   ¤   break;
b00fe4 ¤   ¤   }
fcaf5a
bc47d1 ¤   }·
1067c5 ¤
--3a42 001cbdd866a401101b6 Page 9 of EudoraMainWndProc.c
e6c543 ¤   // ·Pass all non-custom messages to old window proc
53afea ¤   return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam ) ;
cbefe6 }
--ab9b 001c5e53c0f401101b7 Page 1 of EudoraMainWndProc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
03cb47 ¤   EudoraMainWndProc.h,v 1.4 1997/10/22 23:05:49 elrod Exp
b4f7f7 ____________________________________________________________________________*/
a0af5a
ed7700 #ifndef Included_EudoraMainWndProc_h¤   /* [ */
183685 #define Included_EudoraMainWndProc_h
30af5a
c90218 LRESULT·
bf42ef WINAPI·
2f2757 EudoraMainWndProc(¤ HWND hwnd,·
16919a ¤   ¤   ¤   ¤   ¤   UINT msg,·
1d83f0 ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
c4a215 ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
09af5a
520218 LRESULT·
3942ef WINAPI·
fffd2e EudoraStatusbarWndProc(¤HWND hwnd,·
ee1de5 ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
8846a5 ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
636740 ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
deaf5a
089c08 #endif /* ] Included_EudoraMainWndProc_h */
25af5a
f3af5a
887e4d /*__Editor_settings____
fcaf5a
8b4126 ¤   Local Variables:
eb7b17 ¤   tab-width: 4
2b0e6c ¤   End:
b75f8c ¤   vi: ts=4 sw=4
3b9e9b ¤   vim: si
c5d062 _____________________*/
--5c98 00053b963fe401101b8 Page 1 of EudoraReadMailWndProc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
4e6755 ¤   $Id: EudoraReadMailWndProc.c,v 1.7.8.1 1998/11/12 03:11:27 heller Exp $
91f7f7 ____________________________________________________________________________*/
62af5a
719b16 // System Headers
c25655 #include <windows.h>
d63d0b #include <windowsx.h>
2a90fb #include <commctrl.h>
baaf5a
d7e8e0 // Project Headers
1a6c40 #include "PGPDefinedMessages.h"
930d56 #include "CreateToolbar.h"
18cc89 #include "Prefs.h"
8e5ab2 #include "PGPcl.h"
21af5a
63af5a
647aa2 // Project Defines
3c3b39 #define READTOOLBAR_SPACING¤¤   8
5caf5a
42482b // Global Variables
b11c13 extern PGPContextRef¤   g_pgpContext;
f2215b extern UINT¤¤   ¤   ¤   g_nPurgeCacheMsg;
cdaf5a
a6add4 LRESULT WINAPI EudoraReadMailWndProc(HWND hwnd,·
44bf00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,·
0bd05c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
2c2696 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
e4bb36 {
9ec9cd ¤   WNDPROC lpOldProc;
96af5a
0b215d ¤   lpOldProc = (WNDPROC)GetProp( hwnd, "oldproc" );
15e8c6 ···
cc5b13 ¤   if (msg == g_nPurgeCacheMsg)
bcc7a1 ¤   {
3084b4 ¤   ¤   PGPclPurgeCachedPassphrase(wParam);
cd836c ¤   ¤   return TRUE;
5b9371 ¤   }
4eaf5a
0e9467 ¤   switch(msg)
19c7a1 ¤   {
f02271 ¤   ¤   case WM_PGP_CREATE_INTERFACE:
345b34 ¤   ¤   {
afd7bf ¤   ¤   ¤   HWND hwndParent¤¤   = NULL;
a8b17a ¤   ¤   ¤   HWND hwndToolbar¤   = NULL;
a24468 ¤   ¤   ¤   HWND hwndReadToolbar = NULL;
48af5a
8d03d0 ¤   ¤   ¤   // Find the windows we are interested in
91ffa2 ¤   ¤   ¤   hwndParent = GetParent(hwnd);
f27e56 ¤   ¤   ¤   hwndToolbar = ·FindWindowEx(hwndParent,·
cd832d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
18d29a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",·
879ffc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
b4af5a
1e1053 ¤   ¤   ¤   if( hwndToolbar )
aef776 ¤   ¤   ¤   {
039719 ¤   ¤   ¤   ¤   HWND hwndSubjectText = NULL;
9d69e5 ¤   ¤   ¤   ¤   HWND hwndSubjectEdit = NULL;
a18f79 ¤   ¤   ¤   ¤   HWND hwndComboBox¤  ·= NULL;
e7c51d ¤   ¤   ¤   ¤   RECT SubjectTextRect;
76ac52 ¤   ¤   ¤   ¤   RECT SubjectEditRect;
f6d7b2 ¤   ¤   ¤   ¤   RECT ComboBoxRect;
00ca6b ¤   ¤   ¤   ¤   RECT ReadToolbarRect;
4bac4c ¤   ¤   ¤   ¤   int ReadToolbarWidth = 0;
edaf5a
179ca6 ¤   ¤   ¤   ¤   // find the windows we are interested in
bcaf5a
535029 ¤   ¤   ¤   ¤   // The first will be the little graphic,·
--3d8e 000e04cfd61401101b8 Page 2 of EudoraReadMailWndProc.c
f9cdee ¤   ¤   ¤   ¤   // we want the 'Subject:' Text
d9bcae ¤   ¤   ¤   ¤   hwndSubjectText = FindWindowEx(¤hwndToolbar,·
4f4ab8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
8847b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Static",·
b35669 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
b1af5a
0cbcae ¤   ¤   ¤   ¤   hwndSubjectText = FindWindowEx(¤hwndToolbar,·
80a8f5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndSubjectText,·
7347b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Static",·
ba5669 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
0caf5a
f255cd ¤   ¤   ¤   ¤   hwndSubjectEdit = FindWindowEx(¤hwndToolbar,·
784ab8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
229d71 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Edit",·
9a5669 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
0eaf5a
050241 ¤   ¤   ¤   ¤   hwndComboBox¤   = FindWindowEx(¤hwndToolbar,·
b34ab8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
0dccd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ComboBox",·
165669 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
b7af5a
597af2 ¤   ¤   ¤   ¤   if( hwndSubjectText && hwndSubjectEdit && hwndComboBox )
e472c3 ¤   ¤   ¤   ¤   {
7ac2dd ¤   ¤   ¤   ¤   ¤   // create our Decrypting Toolbar for the Read window
743f36 ¤   ¤   ¤   ¤   ¤   hwndReadToolbar = CreateToolbarRead(hwndToolbar);
d0af5a
754e8f ¤   ¤   ¤   ¤   ¤   // did we create it correctly
04170c ¤   ¤   ¤   ¤   ¤   if( hwndReadToolbar )
854859 ¤   ¤   ¤   ¤   ¤   {
f5571d ¤   ¤   ¤   ¤   ¤   ¤   // Find Position of ReadToolbar
8956fa ¤   ¤   ¤   ¤   ¤   ¤   CalculateToolbarRect(hwndReadToolbar,·
db3e97 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ReadToolbarRect);
97af5a
d2aba1 ¤   ¤   ¤   ¤   ¤   ¤   ReadToolbarWidth = (ReadToolbarRect.right -·
5f881c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReadToolbarRect.left);
c6af5a
2f62dc ¤   ¤   ¤   ¤   ¤   ¤   // Find Position of ComboBox
2ed8d9 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndComboBox, &ComboBoxRect);
3c7482 ¤   ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL,·
52abb7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar,·
716680 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (POINT*)&ComboBoxRect,·
60a98c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
3eaf5a
cc7f1b ¤   ¤   ¤   ¤   ¤   ¤   // Find Position of the TextField 'Subject:'
7e308c ¤   ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndSubjectText, &SubjectTextRect);
427482 ¤   ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL,·
72abb7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar,·
2721cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (POINT*)&SubjectTextRect,·
a9a98c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
1caf5a
b1b1a2 ¤   ¤   ¤   ¤   ¤   ¤   // move the toolbar into the proper position
a81918 ¤   ¤   ¤   ¤   ¤   ¤   // we want it right where the old subject used to be.
8d08e8 ¤   ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndReadToolbar,·
89fe40 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectTextRect.left, ·
a495d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ComboBoxRect.top - 2,·
16d998 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReadToolbarWidth,
69eaf5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (ComboBoxRect.bottom -·
d4b891 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ComboBoxRect.top) + 5,
4f526c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
dfaf5a
3884c5 ¤   ¤   ¤   ¤   ¤   ¤   // Find New Position of ReadToolbar
3375b4 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndReadToolbar, &ReadToolbarRect);
cb7482 ¤   ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL,·
3cabb7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar,·
a73775 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (POINT*)&ReadToolbarRect,·
c4a98c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
25af5a
8daf5a
41b6d3 ¤   ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndSubjectText,·
0b8dc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReadToolbarRect.right,·
39e184 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectTextRect.top,·
e03750 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (SubjectTextRect.right -·
--e6bb 0015437873d401101b8 Page 3 of EudoraReadMailWndProc.c
c27910 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectTextRect.left),
777707 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (SubjectTextRect.bottom -·
8726bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectTextRect.top),
775c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
28af5a
485afc ¤   ¤   ¤   ¤   ¤   ¤   // Find the New Position of the TextField 'Subject:'
06308c ¤   ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndSubjectText, &SubjectTextRect);
7f7482 ¤   ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL,·
0dabb7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar,·
3321cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (POINT*)&SubjectTextRect,·
6da98c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
cbaf5a
048282 ¤   ¤   ¤   ¤   ¤   ¤   // Move the Edit Box containing the subject
23c748 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndSubjectEdit, &SubjectEditRect);
3a7482 ¤   ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL,·
b8abb7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar,·
4b9b51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (POINT*)&SubjectEditRect,·
5fa98c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
cbaf5a
f527e0 ¤   ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndSubjectEdit,·
827699 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectTextRect.right,·
0429aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectEditRect.top,·
0ce4af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (SubjectEditRect.right -·
d65037 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectEditRect.left) -·
46daef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReadToolbarWidth,
b878ac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (SubjectEditRect.bottom -·
680fe2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SubjectEditRect.top),
73526c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
feaf5a
b13b9f ¤   ¤   ¤   ¤   ¤   ¤   if(AutoDecrypt(PGPGetContextMemoryMgr(g_pgpContext)))
528fec ¤   ¤   ¤   ¤   ¤   ¤   {
8eb955 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndToolbar,·
817841 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,
26de90 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_DECRYPT,
03c2f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);¤
61db3c ¤   ¤   ¤   ¤   ¤   ¤   }
621c89 ¤   ¤   ¤   ¤   ¤   }
2f2613 ¤   ¤   ¤   ¤   }
2baf5a
06a937 ¤   ¤   ¤   ¤   //MessageBox(NULL, "found hwndToolbar", "ReadMail", MB_OK);
48a3a6 ¤   ¤   ¤   }
f5af5a
7ccdcb ¤   ¤   ¤   break;
160fe4 ¤   ¤   }
bbaf5a
a53cdc ¤   ¤   case WM_DESTROY: ··
9d5b34 ¤   ¤   {
ae62d2 ¤   ¤   ¤   // ·Put back old window proc and
801d17 ¤   ¤   ¤   SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );
fbaf5a
973d89 ¤   ¤   ¤   // ·remove window property
c59697 ¤   ¤   ¤   RemoveProp( hwnd, "oldproc" );·
a2cdcb ¤   ¤   ¤   break;
e10fe4 ¤   ¤   }
a747d1 ¤   }·
b067c5 ¤
9bc543 ¤   // ·Pass all non-custom messages to old window proc
b3afea ¤   return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam ) ;
54efe6 }
--c178 001299fb201401101b9 Page 1 of EudoraReadMailWndProc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d290ed ¤   EudoraReadMailWndProc.h,v 1.3 1997/10/22 23:05:51 elrod Exp
faf7f7 ____________________________________________________________________________*/
3baf5a
6de31c #ifndef Included_EudoraReadMailWndProc_h¤   /* [ */
905ee1 #define Included_EudoraReadMailWndProc_h
1daf5a
5eadd4 LRESULT WINAPI EudoraReadMailWndProc(HWND hwnd,·
53bf00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,·
e8d05c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
ccf1b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
f2af5a
23b8a7 #endif /* ] Included_EudoraReadMailWndProc_h */
2baf5a
1baf5a
ad7e4d /*__Editor_settings____
7aaf5a
e04126 ¤   Local Variables:
717b17 ¤   tab-width: 4
f50e6c ¤   End:
9b5f8c ¤   vi: ts=4 sw=4
499e9b ¤   vim: si
29d062 _____________________*/
--a27d 0000733c570401101ba Page 1 of EudoraSendMailWndProc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
5e7400 ¤   $Id: EudoraSendMailWndProc.c,v 1.7.8.1 1998/11/12 03:11:28 heller Exp $
2ef7f7 ____________________________________________________________________________*/
c6af5a
f59b16 // System Headers
8f5655 #include <windows.h>
4c3d0b #include <windowsx.h>
1d90fb #include <commctrl.h>
4aaf5a
3fe8e0 // Project Headers
666c40 #include "PGPDefinedMessages.h"
f30d56 #include "CreateToolbar.h"
c4cc89 #include "Prefs.h"
fc5ab2 #include "PGPcl.h"
70af5a
327aa2 // Project Defines
82fd9d #define SENDBUTTON_SHRINKAGE¤   31
3d43b5 #define SENDTOOLBAR_SEPARATORS¤ 16
70b4a6 #define SENDTOOLBAR_SPACING¤¤   8
16af5a
9d482b // Global Variables
cfc7be extern BOOL g_bEncrypt;
75af8a extern BOOL g_bSign;
3d8148 extern BOOL g_bSendingMail;
5a45c8 extern HWND g_hwndSendToolbar;
c3a836 extern UINT¤g_nPurgeCacheMsg;
0eaf5a
03482b // Global Variables
d01c13 extern PGPContextRef¤   g_pgpContext;
d2af5a
1f4bbe LRESULT WINAPI EudoraSendMailWndProc(HWND hwnd,·
44bf00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,·
9cd05c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
e52696 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
3fbb36 {
5ec9cd ¤   WNDPROC lpOldProc;
1caf5a
8d215d ¤   lpOldProc = (WNDPROC)GetProp( hwnd, "oldproc" );
b7e8c6 ···
ee5b13 ¤   if (msg == g_nPurgeCacheMsg)
5dc7a1 ¤   {
3a84b4 ¤   ¤   PGPclPurgeCachedPassphrase(wParam);
4c836c ¤   ¤   return TRUE;
609371 ¤   }
e2af5a
e99467 ¤   switch(msg)
96c7a1 ¤   {
b62271 ¤   ¤   case WM_PGP_CREATE_INTERFACE:
725b34 ¤   ¤   {
b6d7bf ¤   ¤   ¤   HWND hwndParent¤¤   = NULL;
91b17a ¤   ¤   ¤   HWND hwndToolbar¤   = NULL;
b89ee6 ¤   ¤   ¤   HWND hwndSendToolbar = NULL;
477437 ¤   ¤   ¤   HWND hwndSendButton¤= NULL;
bdb762 ¤   ¤   ¤   int¤buttoncount = 0;
874e5d ¤   ¤   ¤   RECT rectEudoraToolbarButton;
73f01d ¤   ¤   ¤   LONG style;
3caf5a
d103d0 ¤   ¤   ¤   // Find the windows we are interested in
7cffa2 ¤   ¤   ¤   hwndParent = GetParent(hwnd);
2b6f2c ¤   ¤   ¤   hwndParent = GetParent(hwndParent);
1d7e56 ¤   ¤   ¤   hwndToolbar = ·FindWindowEx(hwndParent,·
c5832d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
2dd29a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",·
4b9ffc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
948b54 ¤   ¤   ¤   hwndSendButton = FindWindowEx(hwndToolbar, NULL, "Button", NULL);
b9af5a
07c1ec ¤   ¤   ¤   hwndSendToolbar = CreateToolbarSend(hwndToolbar);
--e32a 000058a881e401101ba Page 2 of EudoraSendMailWndProc.c
e0af5a
ef0bef ¤   ¤   ¤   style = GetWindowLong(hwndToolbar, GWL_STYLE);
f143f1 ¤   ¤   ¤   style |= WS_CLIPCHILDREN;
f299de ¤   ¤   ¤   SetWindowLong(hwndToolbar, GWL_STYLE,style);
a374a6 ¤   ¤   ¤   buttoncount = SendMessage(hwndToolbar,TB_BUTTONCOUNT,0,0);·
f4af5a
135d41 ¤   ¤   ¤   SendMessage(hwndToolbar,·
289664 ¤   ¤   ¤   ¤   TB_GETITEMRECT,
6c5263 ¤   ¤   ¤   ¤   buttoncount-1,
ae6461 ¤   ¤   ¤   ¤   (LPARAM) &rectEudoraToolbarButton);·
09af5a
9c320f ¤   ¤   ¤   if( hwndSendToolbar )
63f776 ¤   ¤   ¤   {
8eb16a ¤   ¤   ¤   ¤   PGPMemoryMgrRef memoryMgr;
0b97be ¤   ¤   ¤   ¤   RECT rectSendToolbar;
ee1c20 ¤   ¤   ¤   ¤   BOOL bCheckByDefault = FALSE;
4e4fd3 ¤   ¤   ¤   ¤   BOOL bPGPMIME = FALSE;
3fc347 ¤   ¤   ¤   ¤   int SendToolbarWidth = 0;
60af5a
f32dd2 ¤   ¤   ¤   ¤   memoryMgr = PGPGetContextMemoryMgr(g_pgpContext);
5763af ¤   ¤   ¤   ¤   CalculateToolbarRect(hwndSendToolbar, &rectSendToolbar);
02af5a
8d9572 ¤   ¤   ¤   ¤   SendToolbarWidth =·
927b74 ¤   ¤   ¤   ¤   ¤   (rectSendToolbar.right - rectSendToolbar.left);
9eaf5a
cfde8b ¤   ¤   ¤   ¤   MoveWindow(¤hwndSendToolbar,
5c723c ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectEudoraToolbarButton.right,
fd71f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectEudoraToolbarButton.top - 2,
9a22c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendToolbarWidth,
43aefd ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectSendToolbar.bottom - rectSendToolbar.top + 5,
cf1dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
dcaf5a
2f504b ¤   ¤   ¤   ¤   // Preset the buttons according to the User Preferences·
1ca4bf ¤   ¤   ¤   ¤   // or globals indicating return from cancel
71af5a
245312 ¤   ¤   ¤   ¤   if( UsePGPMimeForEncryption(memoryMgr) ·|| g_bEncrypt·
0a028a ¤   ¤   ¤   ¤   ¤   || g_bSign)
4672c3 ¤   ¤   ¤   ¤   {
7ad27f ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
b109b7 ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
33d34f ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_MIME,·
90bd7f ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
362266 ¤   ¤   ¤   ¤   ¤   bPGPMIME = TRUE;
322613 ¤   ¤   ¤   ¤   }
23af5a
03f132 ¤   ¤   ¤   ¤   if( ByDefaultEncrypt(memoryMgr) || g_bEncrypt)
5172c3 ¤   ¤   ¤   ¤   {
f6f8b7 ¤   ¤   ¤   ¤   ¤   g_bEncrypt = FALSE;
3ed27f ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
7809b7 ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
5134b9 ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_ENCRYPT,·
6ebd7f ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
da43cb ¤   ¤   ¤   ¤   ¤   bCheckByDefault = TRUE;
3a2613 ¤   ¤   ¤   ¤   }
caaf5a
4c4ac8 ¤   ¤   ¤   ¤   if( ByDefaultSign(memoryMgr) || g_bSign)
ae72c3 ¤   ¤   ¤   ¤   {
bbe191 ¤   ¤   ¤   ¤   ¤   g_bSign = FALSE;
2dd27f ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
8f09b7 ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
010afb ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_SIGN,
b0bd7f ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
2f43cb ¤   ¤   ¤   ¤   ¤   bCheckByDefault = TRUE;
af2613 ¤   ¤   ¤   ¤   }
7caf5a
0aac4b ¤   ¤   ¤   ¤   if( !bCheckByDefault || bPGPMIME)
8f72c3 ¤   ¤   ¤   ¤   {
e6d27f ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
3e70b6 ¤   ¤   ¤   ¤   ¤   ¤   TB_ENABLEBUTTON,
de969b ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_JUSTDOIT,
2a3964 ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) MAKELONG(FALSE, 0));
052613 ¤   ¤   ¤   ¤   }
--303d 001e1392a86401101ba Page 3 of EudoraSendMailWndProc.c
e0af5a
c05e3e ¤   ¤   ¤   ¤   // Find New Position of ReadToolbar
e06d6e ¤   ¤   ¤   ¤   GetWindowRect(hwndSendToolbar, &rectSendToolbar);
44eb56 ¤   ¤   ¤   ¤   MapWindowPoints(NULL,·
d2a0d0 ¤   ¤   ¤   ¤   ¤   hwndToolbar,·
1ff5b8 ¤   ¤   ¤   ¤   ¤   (POINT*)&rectSendToolbar,·
993478 ¤   ¤   ¤   ¤   ¤   2);
9aaf5a
3213b5 ¤   ¤   ¤   ¤   if( hwndSendButton )
6372c3 ¤   ¤   ¤   ¤   {
a55f0f ¤   ¤   ¤   ¤   ¤   RECT rectButton;
4caf5a
ec39ed ¤   ¤   ¤   ¤   ¤   // Resize the Send Button·
50fc4e ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndSendButton, &rectButton);
45e51a ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL,·
a14fa3 ¤   ¤   ¤   ¤   ¤   ¤   hwndToolbar,·
e85031 ¤   ¤   ¤   ¤   ¤   ¤   (POINT*)&rectButton,
0ec21d ¤   ¤   ¤   ¤   ¤   ¤   2);
43af5a
2caa15 ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndSendButton,·
0afc09 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectSendToolbar.right,·
341af2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectButton.top,·
40a235 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (rectButton.right - rectButton.left)·
324fc9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   - SENDBUTTON_SHRINKAGE,
e61b04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (rectButton.bottom - rectButton.top),
595c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
be2613 ¤   ¤   ¤   ¤   }
84a3a6 ¤   ¤   ¤   }
d6af5a
56cdcb ¤   ¤   ¤   break;
0a0fe4 ¤   ¤   }
8caf5a
793cdc ¤   ¤   case WM_DESTROY: ··
f65b34 ¤   ¤   {
0162d2 ¤   ¤   ¤   // ·Put back old window proc and
da1d17 ¤   ¤   ¤   SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );
d3af5a
a03d89 ¤   ¤   ¤   // ·remove window property
f79697 ¤   ¤   ¤   RemoveProp( hwnd, "oldproc" );·
91cdcb ¤   ¤   ¤   break;
c10fe4 ¤   ¤   }
8147d1 ¤   }·
c067c5 ¤
a4c543 ¤   // ·Pass all non-custom messages to old window proc
6aafea ¤   return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam ) ;
e1efe6 }
--9d14 00183f3ecfd401101bb Page 1 of EudoraSendMailWndProc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ed5128 ¤   EudoraSendMailWndProc.h,v 1.3 1997/10/22 23:05:51 elrod Exp
b1f7f7 ____________________________________________________________________________*/
35af5a
da2fa6 #ifndef Included_EudoraSendMailWndProc_h¤   /* [ */
334481 #define Included_EudoraSendMailWndProc_h
11af5a
ffaf5a
df0218 LRESULT·
6a42ef WINAPI·
bae184 EudoraSendMailWndProc(HWND hwnd,·
4a36c2 ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
d959ae ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
c1784b ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
ebaf5a
58d50b #endif /* ] Included_EudoraSendMailWndProc_h */
4caf5a
34af5a
cc7e4d /*__Editor_settings____
3eaf5a
444126 ¤   Local Variables:
637b17 ¤   tab-width: 4
f90e6c ¤   End:
1a5f8c ¤   vi: ts=4 sw=4
6c9e9b ¤   vim: si
83d062 _____________________*/
--1999 000d151587a401101bc Page 1 of MapFile.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
1efa66 ¤   MapFile.c,v 1.3 1997/07/16 05:51:49 elrod Exp
dbf7f7 ____________________________________________________________________________*/
17af5a
889b16 // System Headers
ef5655 #include <windows.h>
e9af5a
cef4d6 char* MapFile(const char* Path, DWORD* FileSize)
fbbb36 {
daafa7 ¤   char* cp = NULL;
7df5a3 ¤   char* pBeginning = NULL;
b14331 ¤   HANDLE fh = NULL;
c9287f ¤   DWORD Bytes;
51af5a
cfbbf6 ¤   fh = CreateFile(Path,·
93bdd2 ¤   ¤   ¤   ¤   ¤   GENERIC_READ,·
83f1ff ¤   ¤   ¤   ¤   ¤   FILE_SHARE_READ|FILE_SHARE_WRITE,·
03c55d ¤   ¤   ¤   ¤   ¤   NULL,·
98cecb ¤   ¤   ¤   ¤   ¤   OPEN_EXISTING,·
d7a5b7 ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,
56d98c ¤   ¤   ¤   ¤   ¤   NULL);
44af5a
31e5f7 ¤   if(fh != INVALID_HANDLE_VALUE)
02c7a1 ¤   {
f3f9b5 ¤   ¤   *FileSize = ·GetFileSize(fh, NULL);
5eaf5a
84b0ca ¤   ¤   if(*FileSize > 0)
605b34 ¤   ¤   {
2a26d2 ¤   ¤   ¤   pBeginning = (char*) malloc (*FileSize + 1);
d0af5a
11ec7d ¤   ¤   ¤   if(!pBeginning)
2ff776 ¤   ¤   ¤   {
04fb5e ¤   ¤   ¤   ¤   return NULL;
37a3a6 ¤   ¤   ¤   }
dbaf5a
5b95c4 ¤   ¤   ¤   cp = pBeginning;
caaf5a
7702fe ¤   ¤   ¤   ReadFile(fh, cp, *FileSize, &Bytes, NULL);
9eaf5a
6ca0cf ¤   ¤   ¤   *(cp+(*FileSize)) = 0x00;¤
a10fe4 ¤   ¤   }
050e1d ¤   ¤   else
b15b34 ¤   ¤   {
3dc825 ¤   ¤   ¤   pBeginning = (char*) malloc (1);
59af5a
fbe4f2 ¤   ¤   ¤   if(pBeginning)
e9f776 ¤   ¤   ¤   {
d55182 ¤   ¤   ¤   ¤   *pBeginning = 0x00;
43a3a6 ¤   ¤   ¤   }
9b0fe4 ¤   ¤   }
eaaf5a
8b6425 ¤   ¤   CloseHandle( fh );
d69371 ¤   }
c5479d ¤   /*else
dec7a1 ¤   {
710607 ¤   ¤   LPVOID lpMessageBuffer;
59af5a
9ad2bf ¤   ¤   FormatMessage(
9c186a ¤   ¤   ··FORMAT_MESSAGE_ALLOCATE_BUFFER |
9a52c7 ¤   ¤   ··FORMAT_MESSAGE_FROM_SYSTEM,
f06141 ¤   ¤   ··NULL,
2d21f9 ¤   ¤   ··GetLastError(),
e7c84b ¤   ¤   ··MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
dfae52 ¤   ¤   ··(LPTSTR) &lpMessageBuffer,
51a7a3 ¤   ¤   ··0,
eaab0a ¤   ¤   ··NULL );
d1af5a
--f910 001f0ba7f5f401101bc Page 2 of MapFile.c
2273f3 ¤   ¤   // now display this string
d601ca ·¤  ¤   MessageBox(NULL, (char*)lpMessageBuffer, Path, MB_OK|MB_ICONWARNING);
77af5a
3f83ee ¤   ¤   // Free the buffer allocated by the system
9b0eb8 ¤   ¤   LocalFree( lpMessageBuffer );
30af5a
5e4394 ¤   }*/
a8af5a
d77df5 ¤   return pBeginning;
b5efe6 }
f0af5a
--6077 00175c5457d401101bd Page 1 of MapFile.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7dfb5d ¤   MapFile.h,v 1.3 1997/10/22 23:05:52 elrod Exp
95f7f7 ____________________________________________________________________________*/
84af5a
267602 #ifndef Included_MapFile_h¤ /* [ */
71f352 #define Included_MapFile_h
bfaf5a
55af5a
913379 #ifdef __cplusplus
296dad extern "C" {
517454 #endif
1caf5a
2bb36f char* MapFile(const char* Path, DWORD* FileSize);
84af5a
3aaf5a
d43379 #ifdef __cplusplus
8aefe6 }
da7454 #endif
acaf5a
91af5a
f6dafa #endif /* ] Included_MapFile_h */
c8af5a
0baf5a
e57e4d /*__Editor_settings____
48af5a
614126 ¤   Local Variables:
307b17 ¤   tab-width: 4
290e6c ¤   End:
c75f8c ¤   vi: ts=4 sw=4
c69e9b ¤   vim: si
75d062 _____________________*/
--db92 0009b49c44d401101be Page 1 of MyMIMEUtils.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d9a424 ¤   $Id: MyMIMEUtils.c,v 1.3.16.1 1998/11/12 03:11:30 heller Exp $
cbf7f7 ____________________________________________________________________________*/
75af5a
349b16 // System Headers
945655 #include <windows.h>
42af5a
a95582 // PGPsdk Headers
97e2ff #include "pgpConfig.h"
faa076 #include "pgpKeys.h"
362f8d #include "pgpErrors.h"
c14919 #include "pgpUtilities.h"
fc0d08 #include "pgpMem.h"
baaf5a
ee4f9a // Eudora Headers
455e47 #include "emssdk/ems-win.h"
700011 #include "emssdk/mimetype.h"
cd4cfb #include "emssdk/encoding.h"
02af5a
65e8e0 // Project Headers
4ebead #include "MapFile.h"
91bbc6 #include "TranslatorUtils.h"
002bcf #include "MyMIMEUtils.h"
e4af5a
bbaf5a
56af5a
bb33d7 ¤   long
7f8b5e CreateMIMEParam(
ce4dc2 ¤   const char*¤¤   ¤   ¤   nameString,
909aea ¤   const char*¤¤   ¤   ¤   valueString,
30e579 ¤   emsMIMEParamP *¤¤   ¤   ppMimeParam )
b3bb36 {
755371 ¤   emsMIMEParamP¤  ¤   pParam = NULL;
d52e28 ¤   long¤   ¤   ¤   ¤   err¤= 0;
1567c5 ¤
37443a ¤   pParam = (emsMIMEParamP) malloc ( sizeof(emsMIMEparam) );
2caf5a
ab2640 ¤   if ( pParam )
6ac7a1 ¤   {
f664ed ¤   ¤   pParam->name¤   = strdup( nameString );
169cd2 ¤   ¤   pParam->value¤  = strdup( valueString );
908dad ¤   ¤   pParam->next¤   = NULL;
1a1b52 ¤   ¤
5c9371 ¤   }
b70e24 ¤   else
92c7a1 ¤   {
84e5b1 ¤   ¤   err¤= 1;
149371 ¤   }
ca67c5 ¤
74c914 ¤   *ppMimeParam¤   = pParam;
ebdeb7 ¤   return( err );
30efe6 }
b3af5a
1baf5a
2b87c7 ¤   ¤   ¤
8b33d7 ¤   long
903cb3 AddMIMEParam(
04eabc ¤   emsMIMEtypeP¤   ¤   pMimeType,
2decc6 ¤   const char*¤¤   ¤   nameString,
98f644 ¤   const char*¤¤   ¤   valueString
905b71 )
93bb36 {
9d2e28 ¤   long¤   ¤   ¤   ¤   err¤= 0;
6b5371 ¤   emsMIMEParamP¤  ¤   pParam = NULL;
5467c5 ¤
2dd530 ¤   err¤= CreateMIMEParam( nameString, valueString, &pParam );
9baf5a
--e124 000977acdb2401101be Page 2 of MyMIMEUtils.c
02bea2 ¤   if ( ! err )·
0bc7a1 ¤   {
235424 ¤   ¤   if ( !pMimeType->params )·
9f5b34 ¤   ¤   {
39ba78 ¤   ¤   ¤   pMimeType->params¤  = pParam;
ab0fe4 ¤   ¤   }
950e1d ¤   ¤   else
a75b34 ¤   ¤   {
7a3706 ¤   ¤   ¤   emsMIMEParamP¤  pCurParam;
3f67c5 ¤
2db267 ¤   ¤   ¤   // now find the last param, and add the new param to it
a0b036 ¤   ¤   ¤   pCurParam¤  = pMimeType->params;
ecaf5a
e2f0ef ¤   ¤   ¤   while ( pCurParam )
daf776 ¤   ¤   ¤   {
5d383b ¤   ¤   ¤   ¤   if ( !pCurParam->next )·
2972c3 ¤   ¤   ¤   ¤   {
e261ec ¤   ¤   ¤   ¤   ¤   pCurParam->next¤= pParam;
0a14c3 ¤   ¤   ¤   ¤   ¤   break;
7c2613 ¤   ¤   ¤   ¤   }
e52b85 ¤   ¤   ¤   ¤
74dfc8 ¤   ¤   ¤   ¤   pCurParam¤  = pCurParam->next;
afa3a6 ¤   ¤   ¤   }
2c0fe4 ¤   ¤   }
c89371 ¤   }
d0a4ab ¤   ·
10deb7 ¤   return( err );
83efe6 }
1caf5a
abaf5a
6c33d7 ¤   long
15b060 CreateMIMEType(
53ba62 ¤   const char*¤¤   ¤   ¤   typeString,
c86814 ¤   const char*¤¤   ¤   ¤   subtypeString,
ec01d9 ¤   emsMIMEtypeP *¤ ¤   ¤   ppMimeType
b25b71 )
d6bb36 {
c472e6 ¤   emsMIMEtypeP¤   pTempMimeType;
f220d9 ¤   long¤   ¤   ¤   err¤= 0;
fbaf5a
47e18a ¤   pTempMimeType = (emsMIMEtypeP) malloc ( sizeof(emsMIMEtype) );
87af5a
c6bfc0 ¤   if(pTempMimeType)
adc7a1 ¤   {
1522fc ¤   ¤   pTempMimeType->mime_version = strdup("1.0");
ca1fc1 ¤   ¤   pTempMimeType->mime_type = strdup(typeString);
3094c8 ¤   ¤   pTempMimeType->sub_type = strdup(subtypeString);
1184aa ¤   ¤   pTempMimeType->params¤  = NULL;
759371 ¤   }
1b67c5 ¤
d805e5 ¤   *ppMimeType = pTempMimeType;
d3deb7 ¤   return( err );
44efe6 }
6daf5a
dc67c5 ¤
916d52 ¤   void
b51df5 DisposeMIMEType( emsMIMEtypeP¤  pMimeType)
12bb36 {
003efd ¤   emsMIMEparam*¤  pParams;
28af5a
41faf3 ¤   if(pMimeType->mime_version)
86df05 ¤   ¤   free(pMimeType->mime_version);
e8af5a
d6b61d ¤   if(pMimeType->mime_type)
dc371a ¤   ¤   free(pMimeType->mime_type);
52af5a
808111 ¤   if(pMimeType->sub_type)
073ee2 ¤   ¤   free(pMimeType->sub_type);
8e67c5 ¤
73208c ¤   pParams¤= pMimeType->params;
4867c5 ¤
972983 ¤   while ( pParams )
--4fd9 000f9db777f401101be Page 3 of MyMIMEUtils.c
f7c7a1 ¤   {
df1747 ¤   ¤   emsMIMEparam*¤  next;
531b52 ¤   ¤
9dc373 ¤   ¤   next¤   = pParams->next;
e71ca6 ¤   ¤   free(pParams);
ca2dd7 ¤   ¤   pParams¤= next;
ddf828 ¤   }¤
13efe6 }
d7af5a
afaf5a
092811 /*___________________________________________________________________________
cc313a ¤   Build a Eudora data structure representing
9a4947 ¤   multipart/encrypted; boundary=foo; protocol="application/pgp-encrypted"
06c988 ___________________________________________________________________________*/
4533d7 ¤   long
f83a22 BuildEncryptedPGPMIMEType(
61db8a ¤   emsMIMEtypeP *¤ ppMimeType,
5e885e ¤   const char *¤   boundaryString )
15bb36 {
e72e28 ¤   long¤   ¤   ¤   ¤   err¤= 0;
17afb9 ¤   emsMIMEtypeP¤   ¤   pMimeType = NULL;
5eaf5a
5e418b ¤   err¤= CreateMIMEType( "multipart", "encrypted", &pMimeType );
7bbea2 ¤   if ( ! err )·
f958c8 ¤   {¤  ¤
004c1b ¤   ¤   err¤= AddMIMEParam( pMimeType, "boundary", boundaryString );
251b52 ¤   ¤
ad0851 ¤   ¤   if (! err )·
d65b34 ¤   ¤   {
b7d229 ¤   ¤   ¤   err¤= AddMIMEParam( pMimeType,·
e39dbc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "protocol",·
13d11e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "application/pgp-encrypted" );
140fe4 ¤   ¤   }
961b52 ¤   ¤
cf5317 ¤   ¤   if ( ·err ·)
575b34 ¤   ¤   {
563c32 ¤   ¤   ¤   DisposeMIMEType( pMimeType );
055b72 ¤   ¤   ¤   pMimeType = NULL;
e20fe4 ¤   ¤   }
7f9371 ¤   }
5467c5 ¤
0fb1dd ¤   *ppMimeType = pMimeType;
5467c5 ¤
20deb7 ¤   return( err );
b6efe6 }
cfaf5a
efaf5a
9c5e9b /*__________________________________________________________________________
be313a ¤   Build a Eudora data structure representing
09cdda ¤   multipart/signed; boundary=foo; protocol="application/pgp-signature"
95c988 ___________________________________________________________________________*/
ea33d7 ¤   long
d6a9d2 BuildSignedPGPMIMEType(
ccdb8a ¤   emsMIMEtypeP *¤ ppMimeType,
ea885e ¤   const char *¤   boundaryString )
36bb36 {
252e28 ¤   long¤   ¤   ¤   ¤   err¤= 0;
faafb9 ¤   emsMIMEtypeP¤   ¤   pMimeType = NULL;
9367c5 ¤
0918fc ¤   err¤= CreateMIMEType( "multipart", "signed", &pMimeType );
2b49da ¤   if (! err )·
45f2a4 ¤   {¤  ¤   ¤   ¤
734c1b ¤   ¤   err¤= AddMIMEParam( pMimeType, "boundary", boundaryString );
8667c5 ¤
990851 ¤   ¤   if (! err )·
e05b34 ¤   ¤   {
83d229 ¤   ¤   ¤   err¤= AddMIMEParam( pMimeType,·
899dbc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "protocol",·
dcf4f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "application/pgp-signature" );
990fe4 ¤   ¤   }
881b52 ¤   ¤
f90851 ¤   ¤   if (! err )·
--ff1f 000f3f8e990401101be Page 4 of MyMIMEUtils.c
e35b34 ¤   ¤   {
9ae36a ¤   ¤   ¤   err¤= AddMIMEParam( pMimeType, "micalg", "pgp-md5" );
c80fe4 ¤   ¤   }
64af5a
6a1b52 ¤   ¤
560a9f ¤   ¤   if ( ·err )
df5b34 ¤   ¤   {
6d3c32 ¤   ¤   ¤   DisposeMIMEType( pMimeType );
24ea03 ¤   ¤   ¤   pMimeType¤  = NULL;
da0fe4 ¤   ¤   }
ee9371 ¤   }
4667c5 ¤
ebb1dd ¤   *ppMimeType = pMimeType;
6267c5 ¤
32deb7 ¤   return( err );
25efe6 }
3daf5a
56af5a
905e9b /*__________________________________________________________________________
f8b7d7 ¤   *ppMimeType is set to NULL if no valid Content-type is found.
12c988 ___________________________________________________________________________*/
8367c5 ¤
096d52 ¤   void
2b44c8 ParseMIMEType(
da87e0 ¤   const char*¤¤   ¤   szText,
2665ad ¤   emsMIMEtype**¤  ppMimeType
ed5b71 )
efbb36 {
169de1 ¤   *ppMimeType¤= NULL;
4c67c5 ¤
fd78b0 ¤   *ppMimeType = parse_make_mime_type(szText);
8eaf5a
56ff86 ¤   if ( *ppMimeType )
84c7a1 ¤   {
b819e4 ¤   ¤   // parse_mime_ct doesn't fill in mime_version
952e62 ¤   ¤   (*ppMimeType)->mime_version = strdup( "1.0");
289371 ¤   }
bbefe6 }
13af5a
906fcf long
c25934 ParseFileForMIMEType(
a6eff6 ¤   const char *¤   ¤   szInputFile,
149835 ¤   emsMIMEtype**¤  ¤   ppMimeType
d85b71 )
e3bb36 {
dad183 ¤   long err = 0;
a234f2 ¤   char* buffer = NULL;
986ea9 ¤   DWORD length = 0;
0baf5a
fe21b8 ¤   buffer¤ = MapFile( szInputFile, &length );
b567c5 ¤
58aaf3 ¤   if ( buffer )
27c7a1 ¤   {
342680 ¤   ¤   ParseMIMEType( buffer, ppMimeType);
38af5a
ecbdd7 ¤   ¤   free(buffer);
cd9371 ¤   }
8e0e24 ¤   else
97c7a1 ¤   {
a2f0bf ¤   ¤   err = 1;
d89371 ¤   }
cc67c5 ¤
0ddeb7 ¤   return( err );
5fefe6 }
56af5a
31af5a
09af5a
9e23d1 ¤   BOOL
2a1794 GetMIMEParameter(
fa5c16 ¤   emsMIMEtype*¤   ¤   ¤   pMimeType,
0953c6 ¤   const char*¤¤   ¤   ¤   paramName,
f341f1 ¤   char*¤  ¤   ¤   ¤   ¤   outValue )
--fa4f 001db44e5e7401101be Page 5 of MyMIMEUtils.c
2cbb36 {
5d3efd ¤   emsMIMEparam*¤  pParams;
6567c5 ¤
05ee81 ¤   *outValue = 0x00;
8067c5 ¤
84b2b5 ¤   pParams¤= (*pMimeType).params;
f1af5a
832983 ¤   while ( pParams )
eec7a1 ¤   {
075f3b ¤   ¤   if ( !strcmp( (*pParams).name, paramName) )
3b5b34 ¤   ¤   {
aeadc3 ¤   ¤   ¤   strcpy( outValue, (*pParams).value);
97cdcb ¤   ¤   ¤   break;
540fe4 ¤   ¤   }
9db6c0 ¤   ¤   pParams¤= (*pParams).next;
7e9371 ¤   }
6caf5a
8f346c ····return( strlen( outValue ) != 0 );
881862 }¤
51af5a
70af5a
45af5a
5838e5 /*
0eaf5a
4b7e69 ¤   Boolean
1b6895 MatchMIMEType(
571952 ¤   ConstemsMIMETypeHandle¤ typeH,
1177a9 ¤   ConstStringPtr¤ ¤   ¤   typeString,
4bff8a ¤   ConstStringPtr¤ ¤   ¤   subString)
08bb36 {
5ad88d ¤   return( match_mime_type( typeH, typeString, subString ) != 0 );
9defe6 }
a6af5a
dbaf5a
d2af5a
8daf5a
d3af5a
dbaf5a
53af5a
d8af5a
acaf5a
79af5a
79af5a
387fe0 */
2daf5a
3faf5a
82af5a
23af5a
ffaf5a
dbaf5a
--0767 0003e09ac69401101bf Page 1 of MyMIMEUtils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
5c9a3f ¤   MyMIMEUtils.h,v 1.5 1997/10/22 23:05:53 elrod Exp
9df7f7 ____________________________________________________________________________*/
daaf5a
03364c #ifndef Included_MyMIMEUtils_h¤ /* [ */
4d5dae #define Included_MyMIMEUtils_h
e4af5a
51d83c ·
4e5e47 #include "emssdk/ems-win.h"
a3af5a
8833ee ¤   ¤   long
e53cb3 AddMIMEParam(
84eabc ¤   emsMIMEtypeP¤   ¤   pMimeType,
61ecc6 ¤   const char*¤¤   ¤   nameString,
8bf644 ¤   const char*¤¤   ¤   valueString
c26275 );
d987c7 ¤   ¤   ¤
6933d7 ¤   long
69b060 CreateMIMEType(
f1ba62 ¤   const char*¤¤   ¤   ¤   typeString,
026814 ¤   const char*¤¤   ¤   ¤   subtypeString,
7901d9 ¤   emsMIMEtypeP *¤ ¤   ¤   ppMimeType
ba6275 );
1d87c7 ¤   ¤   ¤
c587c7 ¤   ¤   ¤
6b6d52 ¤   void
e77bd4 DisposeMIMEType(·
934593 ¤   emsMIMEtypeP¤   pMimeType
936275 );
bdaf5a
73af5a
61af5a
2a33d7 ¤   long
f23a22 BuildEncryptedPGPMIMEType(
5adb8a ¤   emsMIMEtypeP *¤ ppMimeType,
60718a ¤   const char *¤   boundaryString·
f66275 );
4087c7 ¤   ¤   ¤
8e33d7 ¤   long
3da9d2 BuildSignedPGPMIMEType(
d9db8a ¤   emsMIMEtypeP *¤ ppMimeType,
f4718a ¤   const char *¤   boundaryString·
aa6275 );
ecaf5a
2af7a4 long ParseFileForMIMEType(
91eff6 ¤   const char *¤   ¤   szInputFile,
b39835 ¤   emsMIMEtype**¤  ¤   ppMimeType
1b6275 );
adaf5a
56ab08 void ParseMIMEType(·
62dafa ¤   const char* szText,·
929830 ¤   emsMIMEtype** ppMimeType
a56275 );
dcaf5a
a1f853 BOOL GetMIMEParameter(
9a5c16 ¤   emsMIMEtype*¤   ¤   ¤   pMimeType,
4d53c6 ¤   const char*¤¤   ¤   ¤   paramName,
6faab5 ¤   char*¤  ¤   ¤   ¤   ¤   outValue·
b86275 );
d9af5a
3a38e5 /*
5baf5a
c2af5a
9c25d4 BOOL MatchMIMEType( emsMIMEtypeP¤
924f1c ¤   ¤   ¤   ¤   ¤   MIMEtypeHandle,
59306c ¤   ¤   ¤   ¤   ¤   const char* mType,·
3e266e ¤   ¤   ¤   ¤   ¤   const char* subtype);

--418b 001e2c57eee401101bf Page 2 of MyMIMEUtils.h
e0af5a
1aaf5a
17af5a
437fe0 */
a9af5a
f0af5a
0760b2 #endif /* ] Included_MyMIMEUtils_h */
90af5a
3caf5a
3d7e4d /*__Editor_settings____
42af5a
c94126 ¤   Local Variables:
9f7b17 ¤   tab-width: 4
340e6c ¤   End:
525f8c ¤   vi: ts=4 sw=4
8b9e9b ¤   vim: si
e2d062 _____________________*/
--580c 001beceb56d401101c0 Page 1 of PGPDefinedMessages.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ee7ad8 ¤   PGPDefinedMessages.h,v 1.7 1997/10/22 23:05:54 elrod Exp
28f7f7 ____________________________________________________________________________*/
88af5a
b08d2f #ifndef Included_PGPDefinedMessages_h¤  /* [ */
1033fd #define Included_PGPDefinedMessages_h
0daf5a
747323 #define WM_PGP_CREATE_INTERFACE WM_USER + 1000
15af5a
f72dfc #define IDC_DECRYPT¤¤   ¤   WM_USER + 1010
7d66e9 #define IDC_GETKEY¤ ¤   ¤   WM_USER + 1011
8cb86c #define IDC_KEYMGR¤ ¤   ¤   WM_USER + 1012
b1ad6e #define IDC_JUSTDOIT¤   ¤   WM_USER + 1013
c0e134 #define IDC_ENCRYPT¤¤   ¤   WM_USER + 1014
2210ea #define IDC_SIGN¤   ¤   ¤   WM_USER + 1015
266a22 #define IDC_ENCRYPT_SIGN¤   WM_USER + 1016
b596a3 #define IDC_MIME¤   ¤   ¤   WM_USER + 1017
90af5a
60cebb // Eudora Messages
beec0b #define IDC_SENDMAIL¤   32802
ae6ffc #define IDC_PLUGINMENU¤ 32987
3aaf5a
acaf5a
63ddb7 // Private Flags
924449 #define SENT_FROM_CONTEXT_MENU 666
73af5a
f4974e #endif /* ] Included_PGPDefinedMessages_h */
61af5a
1aaf5a
347e4d /*__Editor_settings____
c8af5a
de4126 ¤   Local Variables:
c97b17 ¤   tab-width: 4
990e6c ¤   End:
385f8c ¤   vi: ts=4 sw=4
899e9b ¤   vim: si
bed062 _____________________*/
--8810 0009ee75fec401101c1 Page 1 of PGPPlug.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
85add3 ¤   $Id: PGPPlug.c,v 1.24.8.1 1998/11/12 03:11:32 heller Exp $
aaf7f7 ____________________________________________________________________________*/
0daf5a
2d9b16 // System Headers
c55655 #include <windows.h>
bb3d0b #include <windowsx.h>
ecaf5a
105582 // PGPsdk Headers
89e2ff #include "pgpConfig.h"
c22f8d #include "pgpErrors.h"
134919 #include "pgpUtilities.h"
199f63 #include "pgpEncode.h"
3cec82 #include "pgpTLS.h"
afaf5a
bf4f9a // Eudora Headers
892ba1 #include "emssdk/Mimetype.h"
fdaf5a
152062 // Shared Headers
d95ab2 #include "PGPcl.h"
a4af5a
95e8e0 // Project Headers
bc0cf9 #include "PGPPlug.h"
0ae6f3 #include "TranslatorIDs.h"
fbfc44 #include "Translators.h"
0a5517 #include "CBTProc.h"
e2af5a
85482b // Global Variables
58db68 HINSTANCE¤  ¤   ¤   g_hinst¤¤   ¤   ¤   = NULL;
08c3ac PGPContextRef¤  ¤   g_pgpContext¤   ¤   = kPGPInvalidRef;
219563 PGPtlsContextRef¤   g_tlsContext¤   ¤   = kPGPInvalidRef;
841a14 HHOOK¤  ¤   ¤   ¤   g_hCBTHook¤ ¤   ¤   = NULL;
dda464 UINT¤   ¤   ¤   ¤   g_nPurgeCacheMsg¤   = 0;
e9af5a
b7af5a
787efe BOOL·
4142ef WINAPI·
8bc799 DllMain (¤  HINSTANCE hinstDll,·
044f29 ¤   ¤   ¤   DWORD fdwReason,
533f3b ¤   ¤   ¤   LPVOID lpvReserved)
97bb36 {
05ab4e ¤   switch (fdwReason)
14c7a1 ¤   {
317e00 ¤   ¤   case DLL_PROCESS_ATTACH:
4c6673 ¤   ¤   ¤   g_hinst = hinstDll;
b4cdcb ¤   ¤   ¤   break;
91af5a
d336e3 ¤   ¤   case DLL_THREAD_ATTACH:
37cdcb ¤   ¤   ¤   break;
bdaf5a
a28b9e ¤   ¤   case DLL_THREAD_DETACH:
2fcdcb ¤   ¤   ¤   break;
eeaf5a
61c37d ¤   ¤   case DLL_PROCESS_DETACH:
accdcb ¤   ¤   ¤   break;
ecb144 ···}
787921 ···return(TRUE);
e9efe6 }
d2af5a
71af5a
dcfb70 /*****\
6b7119 *
df5dbc * ems_plugin_version: Get the version of the API used for this plugin
417119 *
102375 \*****/
8faf5a
9eb47e long WINAPI ems_plugin_version(
--7071 00083f9a15f401101c1 Page 2 of PGPPlug.c
ec1be3 ····short FAR* api_version ·····/* Place to return api version */
205b71 )
5ebb36 {
49dfd2 ¤   *api_version = EMS_VERSION;
6adbc3 ¤   return (EMSR_OK);
86efe6 }
dcaf5a
f4af5a
b4fb70 /*****\
787119 *
98bce9 * ems_plugin_finish: End use of a plugin and clean up
547119 *
462375 \*****/
2caf5a
541f49 long WINAPI ems_plugin_finish(
0037ab ····void FAR* globals ·······/* Pointer to translator instance structure */
d85b71 )
127142 {·
5c447d ¤   /*PGPclCloseLibrary();
87af5a
1a0e48 ¤   if( PGPRefIsValid(g_pgpContext) )
b0c7a1 ¤   {
306b21 ¤   ¤   PGPFreeContext(g_pgpContext);
754394 ¤   }*/
7baf5a
5dd100 ¤   return (EMSR_OK);·
30efe6 }
fdd83c ·
09d83c ·
effb70 /*****\
c37119 *
402dce * ems_plugin_init: Initialize plugin and get its basic info
df7119 *
d72375 \*****/
edaf5a
ce1118 long WINAPI ems_plugin_init(
1a30dc ····void FAR*FAR* globals, ·····/* Return for allocated instance structure */
936ad2 ····char FAR* config_dir, ······/* Optional directory for config file */
942f37 ····char FAR* user_name, ·······/* Users full name from Eudora config */
9ca2c0 ····char FAR* user_addr, ·······/* Users address (RFC-822 addr spec) */
fb7c69 ····short FAR* num_trans, ······/* Place to return num of translators */
32398a ····char FAR*FAR* plugin_desc, ·/* Return for string description of plugin */
10ef68 ····short FAR* plugin_id, ······/* Place to return unique plugin id */
228f96 ····HICON FAR*FAR* plugin_icon¤ /* Return for plugin icon data */
b35b71 )
51bb36 {
76fe2e ¤   long ReturnValue = EMSR_OK;
0a0040 ¤   PGPError err;
b1af5a
04621d ¤   // Initialize the PGPsdk for the plugin
4cf5e5 ¤   err = PGPNewContext( kPGPsdkAPIVersion, &g_pgpContext );
8eaf5a
c5bdc8 ¤   if( IsPGPError(err) )
7ec7a1 ¤   {
673e38 ¤   ¤   if(err == kPGPError_FeatureNotAvailable)
fc5b34 ¤   ¤   {
9c1732 ¤   ¤   ¤   char szMessage[256];
a50207 ¤   ¤   ¤   char szTitle[256];
40af5a
d3fbfc ¤   ¤   ¤   LoadString(g_hinst, IDS_E_EXPIRED, szMessage, sizeof(szMessage));
99ee11 ¤   ¤   ¤   LoadString(g_hinst, IDS_E_EXPIREDTITLE, szTitle, sizeof(szTitle));
1faf5a
1c5e0d ¤   ¤   ¤   MessageBox(NULL, szMessage, szTitle, MB_OK);
df0fe4 ¤   ¤   }
ef0e1d ¤   ¤   else
765b34 ¤   ¤   {
d4d53e ¤   ¤   ¤   PGPclErrorBox (NULL, err);
710fe4 ¤   ¤   }
3eaf5a
f30177 ¤   ¤   return EMSR_UNKNOWN_FAIL;
2a9371 ¤   }
83af5a
--be75 000dc243412401101c1 Page 3 of PGPPlug.c
a0123e ¤   // Initialize the Common Libraries
8cac53 ¤   err = PGPclInitLibrary (g_pgpContext);
48af5a
2f17e9 ····if (IsPGPError (err))·
45c7a1 ¤   {
ae1818 ········PGPclErrorBox (NULL, err);
f1d83c ·
d59c7f ········return EMSR_UNKNOWN_FAIL;
fd6fe7 ····}
c3af5a
980224 ¤   // has this beta version expired?
6b8486 ¤   if(PGPclIsExpired(NULL))
94c7a1 ¤   {
460177 ¤   ¤   return EMSR_UNKNOWN_FAIL;
e89371 ¤   }
72af5a
d02b10 ¤   PGPNewTLSContext(g_pgpContext, &g_tlsContext);
6baf5a
67c65c ¤   // Register the purge passphrase cache message
70af5a
2446cc ¤   g_nPurgeCacheMsg = RegisterWindowMessage(PURGEPASSPHRASECACEHMSG);
1daf5a
57025e ¤   // Set the number of translators in this module
2d0de6 ¤   if (num_trans)
77c7a1 ¤   {
95f208 ¤   ¤   *num_trans = kPGPNumTranslators;
a59371 ¤   }
a10e24 ¤   else
47c7a1 ¤   {
1dca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
829371 ¤   }
a3af5a
54d5af ¤   // Set the module's description
3de3c1 ¤   if (plugin_desc)
36c7a1 ¤   {
9873e1 ¤   ¤   *plugin_desc = strdup(kPGPPluginDescription);
9c9371 ¤   }
7a0e24 ¤   else
5ec7a1 ¤   {
75ca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
6a9371 ¤   }
5e67c5 ¤
db000b ¤   // set the plugin id
dfe152 ¤   if (plugin_id)
96c7a1 ¤   {
8151e1 ¤   ¤   *plugin_id = kPGPPluginID;
6d9371 ¤   }
e40e24 ¤   else
20c7a1 ¤   {
b0ca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
b29371 ¤   }
eaaf5a
d38fde ¤   // Set the plugin's icon
43466c ¤   if (plugin_icon)
72c7a1 ¤   {
a305b5 ¤   ¤   *plugin_icon = (HICON *)malloc(sizeof(HICON));
bbaf5a
735b1b ¤   ¤   if(*plugin_icon)
da5b34 ¤   ¤   {
0ada41 ¤   ¤   ¤   **plugin_icon = LoadIcon(¤  g_hinst,·
d35f0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE( IDI_PGP32 ) );
5c0fe4 ¤   ¤   }
740e1d ¤   ¤   else
865b34 ¤   ¤   {
b1ccff ¤   ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
c90fe4 ¤   ¤   }
849371 ¤   }
090e24 ¤   else
ebc7a1 ¤   {
b3ca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
f29371 ¤   }
dcaf5a
--29f5 00048cd7d28401101c1 Page 4 of PGPPlug.c
579972 ¤   g_hCBTHook = SetWindowsHookEx(¤ WH_CBT,·
84d521 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (HOOKPROC)CBTProc,·
cc12b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
418ad9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetCurrentThreadId());
98af5a
75c0b4 ¤   return (ReturnValue);
48efe6 }
0aaf5a
3aaf5a
6bfb70 /*****\
2a7119 *
30f9c6 * ems_translator_info: Get details about a translator in a plugin
d87119 *
162375 \*****/
e8af5a
eb1da0 long WINAPI ems_translator_info(
239ced ····void FAR* globals,¤ ¤   ¤   /* Pointer to translator instance structure */
069032 ····short trans_id,¤¤   ¤   ¤   /* ID of tRanslator to get info for */
adcb9f ····long FAR* trans_type,¤  ¤   /* Return for translator type*/
b7a5d7 ····long FAR* trans_sub_type,¤  /* Return for translator subtype */
73f93b ····unsigned long FAR* trans_flags, /* Return for translator flags */
c93c46 ····char FAR*FAR* trans_desc,¤  /* Return for translator string description */
5aec71 ····HICON FAR*FAR* trans_icon¤  /* Return for translator icon data */
5c5b71 )
93bb36 {
84fe2e ¤   long ReturnValue = EMSR_OK;
f92298 ¤   TransInfoStruct *InfoPtr = NULL;
acaf5a
af3dae ¤   // make sure we have this many plug-ins
6ad944 ¤   if ( (trans_id <= 0) || (trans_id > kNumTrans) )
d2c7a1 ¤   {
41ba2c ¤   ¤   return (EMSR_INVALID_TRANS);
7f9371 ¤   }
fcaf5a
82f48c ¤   // index the plug-in
77e9aa ¤   InfoPtr = gTransInfo + (trans_id - 1);
11af5a
8f2b23 ¤   // fill out the various members from our structure
c780c9 ¤   if (trans_type)
6ec7a1 ¤   {
fd5bf6 ¤   ¤   *trans_type = InfoPtr->type;
639371 ¤   }
08af5a
bf0e24 ¤   else
bdc7a1 ¤   {
bcca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
cb9371 ¤   }
8aaf5a
4665c3 ¤   if (trans_sub_type)
22c7a1 ¤   {
229b8b ¤   ¤   *trans_sub_type = InfoPtr->subtype;
6d9371 ¤   }
150e24 ¤   else
92c7a1 ¤   {
47ca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
2e9371 ¤   }
0aaf5a
dd5fe2 ¤   if (trans_flags)
cdc7a1 ¤   {
d29182 ¤   ¤   *trans_flags = InfoPtr->flags;
a39371 ¤   }
a00e24 ¤   else
b5c7a1 ¤   {
d6ca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
ca9371 ¤   }
32af5a
67f21d ¤   if (trans_desc)
efc7a1 ¤   {
1c9909 ¤   ¤   *trans_desc = strdup(InfoPtr->description);
e69371 ¤   }
e80e24 ¤   else
48c7a1 ¤   {
--e630 000324dc2aa401101c1 Page 5 of PGPPlug.c
41ca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
449371 ¤   }
3caf5a
cc444d ¤   // give it the right icons
4657b0 ¤   if (trans_icon)
39c7a1 ¤   {
e63254 ¤   ¤   *trans_icon = (HICON *)malloc(sizeof(HICON));
52af5a
cdc97d ¤   ¤   if(*trans_icon)
535b34 ¤   ¤   {
9f86f6 ¤   ¤   ¤   **trans_icon = LoadIcon(g_hinst,·
3ac843 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(gTransInfo[trans_id-1].nIconID));
9d0fe4 ¤   ¤   }
170e1d ¤   ¤   else
5b5b34 ¤   ¤   {
2fccff ¤   ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
7b0fe4 ¤   ¤   }
599371 ¤   }
030e24 ¤   else
cbc7a1 ¤   {
cfca47 ¤   ¤   ReturnValue = EMSR_UNKNOWN_FAIL;
b79371 ¤   }
67af5a
80c0b4 ¤   return (ReturnValue);
b0efe6 }
61af5a
a9fb70 /*****\
b97119 *
1fc49d * ems_can_translate_file:
a6cd35 * ····Check and see if a translation can be performed (file version)
d27119 *
842375 \*****/
1baf5a
b0df96 long WINAPI ems_can_translate(
ba85aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
3b8a21 ····long context, ··············/* Context for check; e.g. EMSF_ON_xxx */
1c8988 ····short trans_id, ············/* ID of translator to call */
95f145 ····emsMIMEtypeP in_mime, ······/* MIME type of data to check */
3c160a ····char FAR*FAR* addresses, ···/* List of addresses (sender and recipients) */
410a96 ····char FAR* properties, ······/* Properties for queued translations */
8775a9 ····char FAR*FAR* out_error, ···/* Place to return string with error message */
85f68e ····long FAR* out_code ·········/* Return for translator-specific result code */
1f5b71 )
5ebb36 {
337a11 ¤   PluginError¤err¤= EMSR_CANT_TRANS;
f8af5a
4271b9 ¤   InitPtrToNull( out_error );
72af5a
6fc7c4 ¤   // see if this is one of our id's
defff1 ¤   if ((trans_id > 0) && (trans_id < kLastTranslatorIDPlusOne))
f1c7a1 ¤   {
503711 ¤   ¤   err = CanPerformTranslation(trans_id, in_mime, context);
539371 ¤   }
660e24 ¤   else
61c7a1 ¤   {
7ab457 ¤   ¤   err = EMSR_INVALID_TRANS;
1c9371 ¤   }
b867c5 ¤
ef5ea8 ¤   return err;
d8efe6 }
0faf5a
e5fb70 /*****\
a17119 *
57774e * ems_translate_file: Actually perform a translation on a file
217119 *
c22375 \*****/
40af5a
9b1f17 long WINAPI ems_translate_file(
7f85aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
5aa965 ····long context, ··············/* Context for translation; e.g. EMSF_ON_xxx */
948988 ····short trans_id, ············/* ID of translator to call */
321064 ····emsMIMEtypeP in_mime, ······/* MIME type of input data */
--f17b 001fb953ee6401101c1 Page 6 of PGPPlug.c
739af8 ····char FAR* in_file, ·········/* The input file name */
9e160a ····char FAR*FAR* addresses, ···/* List of addresses (sender and recipients) */
e00a96 ····char FAR* properties, ······/* Properties for queued translations */
d298ad ····emsProgress progress, ······/* Func to report progress / check for abort */
06fc91 ····emsMIMEtypeP FAR* out_mime, /* Place to return MIME type of result */
0d59c3 ····char FAR* out_file, ······/* The output file (specified by Eudora) */
462a36 ····HICON FAR*FAR* out_icon, ·/* Place to return icon representing result */
9432ee ····char FAR*FAR* out_desc, ··/* Returned string for display with the result */
2ed6c5 ····char FAR*FAR* out_error, ·/* Place to return string with error message */
ec8545 ····long FAR* out_code ·······/* Return for translator-specific result code */
a35b71 )
7ebb36 {
017a11 ¤   PluginError¤err¤= EMSR_CANT_TRANS;
b7af5a
a9b558 ¤   InitPtrToNull( out_icon );
4e5878 ¤   InitPtrToNull( out_desc );
1d71b9 ¤   InitPtrToNull( out_error );
56af5a
c6c7c4 ¤   // see if this is one of our id's
c3fff1 ¤   if ((trans_id > 0) && (trans_id < kLastTranslatorIDPlusOne))
09c7a1 ¤   {
6a1540 ¤   ¤   err = PerformTranslation(¤  trans_id,·
4f7cb6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_file,·
e8c38b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   out_file,·
83705f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   addresses,·
be1675 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_mime,
4da29c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   out_mime);
a29371 ¤   }
f50e24 ¤   else
d0c7a1 ¤   {
d1b457 ¤   ¤   err = EMSR_INVALID_TRANS;
b99371 ¤   }
84af5a
9f5ea8 ¤   return err;
f1efe6 }
bbaf5a
f4af5a
88fb70 /*****\
637119 *
9bcb28 * ems_plugin_config: Call the plug-ins configuration Interface·
5b7119 *
752375 \*****/
7aaf5a
50efd1 long WINAPI ems_plugin_config(
f885aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
d86ad2 ····char FAR* config_dir, ······/* Optional directory for config file */
592f37 ····char FAR* user_name, ·······/* Users full name from Eudora config */
688691 ····char FAR* user_addr ········/* Users address (RFC-822 addr spec) */
095b71 )
90bb36 {
dd2668 ¤   PGPclPreferences (g_pgpContext, NULL, 2, NULL);
70af5a
aa0472 ¤   return EMSR_OK;
3defe6 }
04af5a
44fb70 /*****\
497119 *
f02d1d * ems_free: Free memory allocated by EMS plug-in
757119 *
982375 \*****/
1eaf5a
9c1693 long WINAPI ems_free(
ef8228 ····void FAR* mem ··············/* Memory to free */
395b71 )
b6bb36 {
53a168 ¤   if (mem)
5bc7a1 ¤   {
3bf1e9 ¤   ¤   free(mem);
0b9371 ¤   }
7daf5a
25dbc3 ¤   return (EMSR_OK);
fbbe43 }¶
--db87 0007bd1ceb3401101c2 Page 1 of PGPPlug.h
bc38e5 /*
620c71 ** Copyright (C)1997 Network Associates, Inc. and its affiliates.
2df124 ** All rights reserved.
3c7fe0 */
8daf5a
85af5a
12af5a
e67766 #ifndef _PGP_PLUGIN_H·
d82097 #define _PGP_PLUGIN_H·
c3af5a
5b5e47 #include "emssdk/ems-win.h"
3a23fb #include "PGPPlugTypes.h"
9de6f3 #include "TranslatorIDs.h"
9d8031 #include "resource.h"
43af5a
86e0bc #define InitPtrToNull( p )¤ { if ( !( p ) )¤*(p) = NULL; }
fcaf5a
9dc6a2 typedef struct _TransInfoStruct {
e3061a ¤   char *description;
d41004 ¤   long type;
e77078 ¤   long subtype;
88dddd ¤   unsigned long flags;
29eaa9 ¤   unsigned long nIconID;
5b8f94 }TransInfoStruct;
dfaf5a
efcaab static TransInfoStruct gTransInfo[] = {
bdc7a1 ¤   {
4e0238 ¤   ¤   "Decrypt PGP/MIME Message",
7d526c ¤   ¤   EMST_PREPROCESS,
20fa09 ¤   ¤   kDecryptTranslatorID,·
888993 ¤   ¤   ( EMSF_ON_ARRIVAL | EMSF_ON_DISPLAY | EMSF_WHOLE_MESSAGE | EMSF_REQUIRE¶
d048f4 S_MIME | EMSF_GENERATES_MIME ),
80762c ¤   ¤   IDI_PGP_DECRYPT
40ba24 ¤   },
b7c7a1 ¤   {
f4d27a ¤   ¤   "Verify PGP/MIME Message",
d7256a ¤   ¤   EMST_SIGNATURE,
979160 ¤   ¤   kVerifyTranslatorID,·
aa8993 ¤   ¤   ( EMSF_ON_ARRIVAL | EMSF_ON_DISPLAY | EMSF_WHOLE_MESSAGE | EMSF_REQUIRE¶
bc48f4 S_MIME | EMSF_GENERATES_MIME ),
4c1e5c ¤   ¤   IDI_PGP_VERIFY
14ba24 ¤   },
47c7a1 ¤   {
b3a4e2 ¤   ¤   "PGP plugin 1 (use toolbar)",
5b526c ¤   ¤   EMST_PREPROCESS,
3ab991 ¤   ¤   kEncryptTranslatorID,·
87ea1c ¤   ¤   ( EMSF_Q4_TRANSMISSION | EMSF_WHOLE_MESSAGE | EMSF_REQUIRES_MIME | EMSF¶
01dfb3 _GENERATES_MIME ),
fd8111 ¤   ¤   IDI_PGP_ENCRYPT
4c9371 ¤   }
5a595e ¤   ,
29c7a1 ¤   {
cda5da ¤   ¤   "PGP plugin 2 (use toolbar)",
2d256a ¤   ¤   EMST_SIGNATURE,
f952bc ¤   ¤   kSignTranslatorID,·
10ea1c ¤   ¤   ( EMSF_Q4_TRANSMISSION | EMSF_WHOLE_MESSAGE | EMSF_REQUIRES_MIME | EMSF¶
c4dfb3 _GENERATES_MIME ),
dffe60 ¤   ¤   IDI_PGP_ENCRYPT//IDI_PGP_SIGN
d4ba24 ¤   },
8cc7a1 ¤   {
f59f7f ¤   ¤   "PGPmime Encrypt & Sign",
2421ae ¤   ¤   EMST_COALESCED,
9f2760 ¤   ¤   kEncryptAndSignTranslatorID,·
d9ea1c ¤   ¤   ( EMSF_Q4_TRANSMISSION | EMSF_WHOLE_MESSAGE | EMSF_REQUIRES_MIME | EMSF¶
a6dfb3 _GENERATES_MIME ),
4e80c0 ¤   ¤   0L //IDI_PGP_ENCRYPT_SIGN
22ba24 ¤   },
53d8af ¤   /*
74c7a1 ¤   {
2788f1 ¤   ¤   "PGP Encrypt & Sign",
366026 ¤   ¤   EMST_LANGUAGE,
7b1427 ¤   ¤   kManualEncryptSignTranslatorID,
--de7f 00108cac774401101c2 Page 2 of PGPPlug.h
d9694c ¤   ¤   ( EMSF_ON_REQUEST | EMSF_WHOLE_MESSAGE ·),
ae8111 ¤   ¤   IDI_PGP_ENCRYPT
c5ba24 ¤   },
27c7a1 ¤   {
0aa72c ¤   ¤   "PGP Decrypt & Verify",
ea6026 ¤   ¤   EMST_LANGUAGE,
212d3b ¤   ¤   kManualDecryptVerifyTranslatorID,·
01b92e ¤   ¤   ( EMSF_ON_REQUEST | EMSF_WHOLE_MESSAGE ),
9e762c ¤   ¤   IDI_PGP_DECRYPT
e1ba24 ¤   },
8867c5 ¤
b6c7a1 ¤   {
c659bb ¤   ¤   "Extract PGP Key From Message",
d06026 ¤   ¤   EMST_LANGUAGE,
8a0051 ¤   ¤   kManualAddKeyTranslatorID,
5b694c ¤   ¤   ( EMSF_ON_REQUEST | EMSF_WHOLE_MESSAGE ·),
4f316c ¤   ¤   IDI_PGP_ADDKEY
004394 ¤   }*/
8282f7 };
72af5a
28ce79 static const long¤  kNumTrans¤  ¤   ¤   ¤   = (sizeof(gTransInfo)/sizeof(*gTran¶
c293de sInfo));
0a2aa5 static const short¤ kPGPPluginID¤   ¤   ¤   = 880; // for future use we have 88¶
0d8ed8 1 882 883 884 as well
c3af5a
4636d3 static const char*¤ kPGPPluginDescription¤  = "PGP 6.0";
26af5a
081998 #endif _PGP_PLUGIN_H
--1f11 0014f8e4323401101c3 Page 1 of PGPPlugTypes.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
fa04e2 ¤   PGPPlugTypes.h,v 1.2 1997/10/22 23:05:55 elrod Exp
0bf7f7 ____________________________________________________________________________*/
88af5a
caac12 #ifndef Included_PGPPlugTypes_h¤/* [ */
6dfdf7 #define Included_PGPPlugTypes_h
50af5a
18af5a
09a0b0 typedef¤long¤   PluginError;·
f0af5a
cccd0e #endif /* ] Included_PGPPlugTypes_h */
daaf5a
73af5a
7b7e4d /*__Editor_settings____
66af5a
ac4126 ¤   Local Variables:
4f7b17 ¤   tab-width: 4
e40e6c ¤   End:
d95f8c ¤   vi: ts=4 sw=4
0d9e9b ¤   vim: si
4fd062 _____________________*/
--7614 001c73caed3401101c4 Page 1 of PGPplugin.def
412cc6 ; PGPplugin.def : Declares the module parameters for the DLL.
d1af5a
6807af LIBRARY ·····"pgpEudoraPlugin"
5d9052 DESCRIPTION ·'pgpEudoraPlugin Windows Dynamic Link Library'
44af5a
67ef2b EXPORTS
cf5002 ¤   ems_plugin_version
e21d6e ¤   ems_plugin_init
756332 ¤   ems_translator_info
43b259 ¤   ems_can_translate
97434c ¤   ems_translate_file
6e7e78 ¤   ems_plugin_config
a051ff ¤   ems_plugin_finish
c7bf32 ¤   ems_free
--bb14 000bca6b75d401101c5 Page 1 of PGPplugin.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
6d6c0e /////////////////////////////////////////////////////////////////////////////
81465d //
fbcbaf // Icon
7c465d //
56af5a
e52951 // Icon with lowest ID value placed first to ensure application icon
d50f06 // remains consistent on all systems.
f0db3f IDI_PGP_DECRYPT ········ICON ···DISCARDABLE ····"res\\lock1.ico"
036f1e IDI_PGP_VERIFY ·········ICON ···DISCARDABLE ····"res\\verify.ico"
73c065 IDI_PGP32 ··············ICON ···DISCARDABLE ····"res\\pgp50.ico"
3b7c3b IDI_PGP_SIGN ···········ICON ···DISCARDABLE ····"res\\sign.ico"
806d43 IDI_PGP_ENCRYPT ········ICON ···DISCARDABLE ····"Res\\lock.ico"
52af5a
b4f860 #ifdef APSTUDIO_INVOKED
086c0e /////////////////////////////////////////////////////////////////////////////
04465d //
1a5733 // TEXTINCLUDE
32465d //
abaf5a
b086ef 1 TEXTINCLUDE DISCARDABLE·
6b4523 BEGIN
98541e ····"resource.h\0"
f4e0d1 END
7daf5a
cc7037 2 TEXTINCLUDE DISCARDABLE·
f14523 BEGIN
abeb23 ····"#include ""afxres.h""\r\n"
bbdb5c ····"\0"
8ce0d1 END
45af5a
1b227f 3 TEXTINCLUDE DISCARDABLE·
574523 BEGIN
1482bb ····"#include ""PGPpluginVer.rc""\r\n"
404537 ····"#include ""..\\shared\\Working.rc""\r\n"
ad6c56 ····"#include ""..\\shared\\SharedStrings.rc""\r\n"
71e851 ····"\r\n"
b2db5c ····"\0"
4fe0d1 END
03af5a
0e69ab #endif ···// APSTUDIO_INVOKED
4eaf5a
7faf5a
676c0e /////////////////////////////////////////////////////////////////////////////
42465d //
29ae70 // Bitmap
4d465d //
b1af5a
093773 IDB_READTOOLBAR ········BITMAP ·DISCARDABLE ····"res\\readtool.bmp"
bcc192 IDB_SENDTOOLBAR ········BITMAP ·DISCARDABLE ····"res\\sendtool.bmp"
--132b 000f6cfc4ea401101c5 Page 2 of PGPplugin.rc
e0af5a
226c0e /////////////////////////////////////////////////////////////////////////////
27465d //
a086c0 // Menu
a7465d //
edaf5a
951b77 IDM_PGPABOUTMENU MENU DISCARDABLE·
814523 BEGIN
e57621 ····MENUITEM "&Launch PGPkeys...", ·········ID_PGPKEYS
65b1ec ····MENUITEM "&Preferences...", ············ID_PREFERENCES
0c7481 ····MENUITEM "&Help Topics...", ············ID_PGPHELP
46a3ed ····MENUITEM SEPARATOR
a39429 ····MENUITEM "&About PGP...", ··············ID_ABOUTPGP
8fe0d1 END
ceaf5a
2470d5 IDM_PGPENCRYPTMENU MENU DISCARDABLE·
ae4523 BEGIN
d7c386 ····MENUITEM "&Encrypt", ···················ID_PGPENCRYPT
87e934 ····MENUITEM "&Sign", ······················ID_PGPSIGN
06e5db ····MENUITEM "Encrypt &and Sign", ··········ID_PGPENCRYPTSIGN
15e0d1 END
e7af5a
10a29b IDM_PGPDECRYPTMENU MENU DISCARDABLE·
6b4523 BEGIN
5e3496 ····MENUITEM "&Decrypt and Verify", ········ID_PGPDECRYPTVERIFY
c7e0d1 END
86af5a
07af5a
106c0e /////////////////////////////////////////////////////////////////////////////
a4465d //
fe5e87 // String Table
6d465d //
7baf5a
dd6f6c STRINGTABLE DISCARDABLE·
344523 BEGIN
bc99c1 ····IDS_WARN_NORECIPIENTS ··"In order to Encrypt you must choose\nat least one ¶
675f9a recipient."
9f05e0 ····IDS_WARN_NORECIPIENTSTITLE "No Recpients Chosen"
d42d40 ····IDS_TITLE_RECIPIENTDIALOG "PGP Eudora - Encrypt Message To..."
c8655a ····IDS_TITLE_PGPERROR ·····"PGP Error"
b76f95 ····IDS_SUCCESS_ADDKEY ·····"PGP successfully added the key(s) to your keyring."
68dc71 ····IDS_TITLE_ADDKEY ·······"PGP Eudora - Extract Key"
271bc1 ····IDS_TOOLTIP1 ···········"Decrypt PGP Encrypted Email Message"
9980fe ····IDS_TOOLTIP3 ···········"Launch PGPkeys Application"
45535e ····IDS_TOOLTIP4 ···········"Just Do It!"
828142 ····IDS_TOOLTIP5 ···········"PGP Encrypt Email Message"
159c63 ····IDS_TOOLTIP6 ···········"PGP Sign Email Message"
7fe0d1 END
90af5a
d26f6c STRINGTABLE DISCARDABLE·
7c4523 BEGIN
7bc489 ····IDS_TOOLTIP7 ···········"PGP Encrypt and Sign Email Message"
275ae1 ····IDS_TOOLTIP8 ···········"Use PGP/MIME When Sending Email Message"
ef7e54 ····IDS_PGPPREFSTATUS ······"Edit your PGP preferences"
1272d7 ····IDS_PGPABOUTSTATUS ·····"Display PGP product and version information"
32a47d ····IDS_PGPKEYSSTATUS ······"Launch the PGPkeys Application"
5654d2 ····IDS_PGPHELPSTATUS ······"Need help with PGP? You'll find it here"
1cb26a ····IDS_PGPDECRYPTSTATUS ···"Decrypt PGP Encrypted Email Message or Selected Te¶
c3e3fd xt"
d5a4e9 ····IDS_PGPENCRYPTSIGNSTATUS·
689769 ····························"PGP Encrypt and Sign Email Message or Selected Tex¶
035c60 t"
893ff5 ····IDS_PGPSIGNSTATUS ······"PGP Sign Email Message or Selected Text"
ea2c28 ····IDS_PGPENCRYPTSTATUS ···"PGP Encrypt Email Message or Selected Text"
3faacc ····IDS_ENCRYPTMENU ········"&Encrypt"
6203a5 ····IDS_PGPKEYSMENU ········"&Launch PGPkeys..."
429823 ····IDS_DECRYPTMENU ········"&Decrypt and Verify"
21e6b0 ····IDS_CUTMENU ············"Cu&t"
59b1df ····IDS_COPYMENU ···········"&Copy"
8ae0d1 END
a0af5a
f66f6c STRINGTABLE DISCARDABLE·
--1735 00112c5cb8a401101c5 Page 3 of PGPplugin.rc
254523 BEGIN
42f604 ····IDS_HELPFILE ···········"PGP55.HLP"
119978 ····IDS_PGPKEYSEXE ·········"PGPkeys /s"
9a6abd ····IDS_E_LAUNCHPGPKEYS ····"Unable to locate the PGPkeys application"
2cf46f ····IDS_E_EXPIRED ··········"The evaluation period for PGP has passed.\nThe Eud¶
a207d1 ora Plugin will no longer function."
3771f8 ····IDS_E_EXPIREDTITLE ·····"PGP Plugin Expired"
561ff0 ····IDS_EXE ················"Eudora"
148dff ····IDS_DLL ················"pgpplugin.dll"
47dd9f ····IDS_E_SENDMAIL ·········"There was an error communicating with Eudora.\nIf ¶
3d0e83 you continue to send this message it will\nNOT be encrypted or signed. Do you w¶
d597c7 ish to\nsend this message?"
226e66 ····IDS_E_SENDMAILTITLE ····"PGP Error"
5224d2 ····IDS_E_OLDVERSION ·······"The PGP Plugin is not compatible with this\nversio¶
63be70 n of Eudora. Please contact Eudora's\ncustomer support for further assistance."
ffe0d1 END
01af5a
5d1b3a #endif ···// English (U.S.) resources
296c0e /////////////////////////////////////////////////////////////////////////////
69af5a
d0af5a
f4af5a
8cce8c #ifndef APSTUDIO_INVOKED
4c6c0e /////////////////////////////////////////////////////////////////////////////
0e465d //
938464 // Generated from the TEXTINCLUDE 3 resource.
66465d //
28dfa5 #include "PGPpluginVer.rc"
fef88e #include "..\shared\Working.rc"
1496d0 #include "..\shared\SharedStrings.rc"
1caf5a
1faf5a
ed6c0e /////////////////////////////////////////////////////////////////////////////
728072 #endif ···// not APSTUDIO_INVOKED
12af5a
--10dd 0015ef65cdc401101c6 Page 1 of PGPpluginVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
2da67a ············VALUE "FileDescription", "PGP Plug-in For Eudora E-mail Client\0"
3dc1dd ············VALUE "FileVersion", PGPVERSIONSTRING
6979c3 ············VALUE "InternalName", "pgpEudoraPlugin\0"
b58ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
522bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
5b2cb6 ············VALUE "OriginalFilename", "pgpEudoraPlugin.dll\0"
939317 ············VALUE "ProductName", PGPPRODUCTNAME
b1d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
42f37f ········END
9c7d01 ····END
4926ab ····BLOCK "VarFileInfo"
175574 ····BEGIN
d84b11 ········VALUE "Translation", 0x409, 1200
1a7d01 ····END
0de0d1 END
a7af5a
28af5a
5eaf5a
--d657 000b9d99a31401101c7 Page 1 of ReadMailToolbarWndProc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8cd322 ¤   $Id: ReadMailToolbarWndProc.c,v 1.26.2.1.2.1 1998/11/12 03:11:34 heller Exp¶
7bed4e ·$
59f7f7 ____________________________________________________________________________*/
97af5a
9b9b16 // System Headers
1b5655 #include <windows.h>
ad3d0b #include <windowsx.h>
152f6f #include <richedit.h>
4590fb #include <commctrl.h>
d6af5a
285582 // PGPsdk Headers
1ee2ff #include "pgpConfig.h"
71a076 #include "pgpKeys.h"
c12f8d #include "pgpErrors.h"
5c4919 #include "pgpUtilities.h"
56ec82 #include "pgpTLS.h"
40af5a
804f9a // Eudora Headers
a02ba1 #include "emssdk/Mimetype.h"
20af5a
c22062 // Shared Headers
8a5ab2 #include "PGPcl.h"
89af5a
3fe8e0 // Project Headers
ee6c40 #include "PGPDefinedMessages.h"
b63e80 #include "ReadMailToolbarWndProc.h"
9153a7 #include "DecryptVerify.h"
251db1 #include "RichEdit_IO.h"
e1e6f3 #include "TranslatorIDs.h"
26fc44 #include "Translators.h"
5005f4 #include "AddKey.h"
07fd0e #include "DisplayMessage.h"
f8bbc6 #include "TranslatorUtils.h"
d1d2cf #include "BlockUtils.h"
1c8031 #include "resource.h"
8153a7 #include "DecryptVerify.h"
20b545 #include "pgpSC.h"
b0af5a
29482b // Global Variables
766ba0 extern HINSTANCE¤   ¤   g_hinst;
b92ba9 extern HWND¤¤   ¤   ¤   g_hwndEudoraStatusbar;
e2356f extern HWND¤¤   ¤   ¤   g_hwndEudoraMainWindow;
031c13 extern PGPContextRef¤   g_pgpContext;
f070a4 extern PGPtlsContextRef g_tlsContext;
11af5a
21af5a
937f06 BOOL DecryptVerifyRichEditText(char** ppBuffer, long* pLength, BOOL *FYEO);
7caf5a
76d5ee LRESULT WINAPI·
6ab1b4 ReadMailToolbarWndProc(HWND hwnd,·
c9bff5 ¤   ¤   ¤   ¤   ¤   ···UINT msg,·
e469ae ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
b23fea ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
e0bb36 {
ebc9cd ¤   WNDPROC lpOldProc;
6daf5a
75215d ¤   lpOldProc = (WNDPROC)GetProp( hwnd, "oldproc" );
8fe8c6 ···
2a9467 ¤   switch(msg)
cec7a1 ¤   {
8b3cdc ¤   ¤   case WM_DESTROY: ··
bf5b34 ¤   ¤   {
8762d2 ¤   ¤   ¤   // ·Put back old window proc and
3d1d17 ¤   ¤   ¤   SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );
5aaf5a
b93d89 ¤   ¤   ¤   // ·remove window property
--73d4 000041f47fb401101c7 Page 2 of ReadMailToolbarWndProc.c
219697 ¤   ¤   ¤   RemoveProp( hwnd, "oldproc" );·
70cdcb ¤   ¤   ¤   break;
320fe4 ¤   ¤   }
53af5a
13b3c8 ¤   ¤   case WM_NOTIFY:
f75b34 ¤   ¤   {
c14151 ¤   ¤   ¤   static char szTooltip[256] = {0x00};
de9cc6 ¤   ¤   ¤   LPTOOLTIPTEXT lpToolTipText = (LPTOOLTIPTEXT) lParam;;
bfaf5a
7056fd ¤   ¤   ¤   switch (((LPNMHDR)lParam)->code)
58f776 ¤   ¤   ¤   {
598704 ¤   ¤   ¤   ¤   case TTN_NEEDTEXTA:
af72c3 ¤   ¤   ¤   ¤   {
128583 ¤   ¤   ¤   ¤   ¤   if(lpToolTipText->hdr.idFrom >= IDC_DECRYPT &&·
f84fda ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->hdr.idFrom <= IDC_MIME )
cc4859 ¤   ¤   ¤   ¤   ¤   {
d43e89 ¤   ¤   ¤   ¤   ¤   ¤   int StringId = lpToolTipText->hdr.idFrom - ·
63c4d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_USER - 1000;
d7af5a
54de97 ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst,·
994350 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   StringId,
b21003 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTooltip,
b3f951 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTooltip));
39af5a
49e3bc ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->lpszText = szTooltip;
84af5a
fbf48f ¤   ¤   ¤   ¤   ¤   ¤   if(g_hwndEudoraStatusbar)
c38fec ¤   ¤   ¤   ¤   ¤   ¤   {
34ac0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(g_hwndEudoraStatusbar,
600bb1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SB_SETTEXT,
450b19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)0,
ff67ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)szTooltip);
a8db3c ¤   ¤   ¤   ¤   ¤   ¤   }
1094aa ¤   ¤   ¤   ¤   ¤   ¤
f4f8ad ¤   ¤   ¤   ¤   ¤   ¤   return 0;
b71c89 ¤   ¤   ¤   ¤   ¤   }
c02613 ¤   ¤   ¤   ¤   }
5aaf5a
aed448 ¤   ¤   ¤   ¤   case TTN_NEEDTEXTW:
3672c3 ¤   ¤   ¤   ¤   {
adc559 ¤   ¤   ¤   ¤   ¤   static wchar_t wideBuf[256];
beaf5a
678583 ¤   ¤   ¤   ¤   ¤   if(lpToolTipText->hdr.idFrom >= IDC_DECRYPT &&·
314fda ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->hdr.idFrom <= IDC_MIME )
034859 ¤   ¤   ¤   ¤   ¤   {
7748fe ¤   ¤   ¤   ¤   ¤   ¤   int StringId = lpToolTipText->hdr.idFrom -·
4ec4d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_USER - 1000;
6eae30 ¤   ¤   ¤   ¤   ¤
a1bc0c ····¤   ¤   ¤   ¤   ¤   LoadString (g_hinst,·
894350 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   StringId,
511003 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTooltip,
f9f951 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTooltip));
8daf5a
1e9ed7 ¤   ¤   ¤   ¤   ¤   ¤   MultiByteToWideChar(CP_ACP,·
a8e51d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_PRECOMPOSED,·
11d42a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTooltip,·
8cc849 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   -1,·
1bade4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wideBuf,·
dd0b69 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   256);
e4af5a
28bf8f ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->lpszText = (char*)wideBuf;
16af5a
0bf48f ¤   ¤   ¤   ¤   ¤   ¤   if(g_hwndEudoraStatusbar)
fc8fec ¤   ¤   ¤   ¤   ¤   ¤   {
1aac0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(g_hwndEudoraStatusbar,
890bb1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SB_SETTEXT,
7a0b19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)0,
e267ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)szTooltip);
b7db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e6af5a
5ef8ad ¤   ¤   ¤   ¤   ¤   ¤   return 0;
041c89 ¤   ¤   ¤   ¤   ¤   }
--c3d0 000b3d075b6401101c7 Page 3 of ReadMailToolbarWndProc.c
862613 ¤   ¤   ¤   ¤   }
2ba3a6 ¤   ¤   ¤   }
08cdcb ¤   ¤   ¤   break;
670fe4 ¤   ¤   }
d5af5a
0e8e1e ¤   ¤   case WM_COMMAND:
1c5b34 ¤   ¤   {
47577d ¤   ¤   ¤   HWND hwndParent = NULL;
ce03a1 ¤   ¤   ¤   HWND hwndRichEdit = NULL;
2eaf5a
564afd ¤   ¤   ¤   switch(wParam)
adf776 ¤   ¤   ¤   {
224f7d ¤   ¤   ¤   ¤   case IDC_DECRYPT:
2772c3 ¤   ¤   ¤   ¤   {
cfef8d ¤   ¤   ¤   ¤   ¤   //char temp[1024];
685065 ¤   ¤   ¤   ¤   ¤   char* pRichEditText = NULL;
3b8d16 ¤   ¤   ¤   ¤   ¤   long nChar = 0;
a5a3bc ¤   ¤   ¤   ¤   ¤   CHARRANGE chRange = {0,0};
d0da6a ¤   ¤   ¤   ¤   ¤   BOOL bMimeMessage = FALSE;
eee118 ¤   ¤   ¤   ¤   ¤   BOOL bDecryptSuccessful = FALSE;
b354cf ¤   ¤   ¤   ¤   ¤   BOOL bToggle = FALSE;
e55dfb ¤   ¤   ¤   ¤   ¤   BOOL bSelectedText = FALSE;
f25277 ¤   ¤   ¤   ¤   ¤   FINDTEXT ftEncrypted;
66ff0d ¤   ¤   ¤   ¤   ¤   FINDTEXT ftSigned;
913f5a ¤   ¤   ¤   ¤   ¤   long nCharPos = 0;
f45198 ¤   ¤   ¤   ¤   ¤   HCURSOR hCursor, hOldCursor;
eb6ece ¤   ¤   ¤   ¤   ¤   BOOL FYEO;
99af5a
fa16ca ¤   ¤   ¤   ¤   ¤   // Find the windows we are interested in...
da8959 ¤   ¤   ¤   ¤   ¤   hwndParent = GetParent(hwnd);
1016ee ¤   ¤   ¤   ¤   ¤   hwndRichEdit = FindWindowEx(hwndParent,·
e14ab8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
3f3730 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "RICHEDIT",·
815669 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
e7af5a
a10dcb ¤   ¤   ¤   ¤   ¤   // Is the control in Edit Mode
9a248a ¤   ¤   ¤   ¤   ¤   bToggle = !SendMessage(hwnd, TB_ISBUTTONCHECKED, 34002, 0);
12af5a
9822a5 ¤   ¤   ¤   ¤   ¤   // See if the user has selected text in the window
e74e2f ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit, ·
daed6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EM_EXGETSEL,·
754233 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)0,
b1e4e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)·
edc93f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &chRange);
83af5a
8a5a67 ¤   ¤   ¤   ¤   ¤   bSelectedText = chRange.cpMax - chRange.cpMin;
0aaf5a
d3626c ¤   ¤   ¤   ¤   ¤   // Prepare to look for our plug-ins
a22580 ¤   ¤   ¤   ¤   ¤   // Mime Encrypted Text
fe6373 ¤   ¤   ¤   ¤   ¤   ftEncrypted.lpstrText = "<0880.0001>"; // Search String
432300 ¤   ¤   ¤   ¤   ¤   ftEncrypted.chrg.cpMin = 0;
df8c6e ¤   ¤   ¤   ¤   ¤   ftEncrypted.chrg.cpMax = -1; // All Text
c8af5a
863fb7 ¤   ¤   ¤   ¤   ¤   // Mime Signed Text
bc7606 ¤   ¤   ¤   ¤   ¤   ftSigned.lpstrText = "<0880.0002>"; // Search String
18cbd2 ¤   ¤   ¤   ¤   ¤   ftSigned.chrg.cpMin = 0;
22a0eb ¤   ¤   ¤   ¤   ¤   ftSigned.chrg.cpMax = -1; // All Text
18ae30 ¤   ¤   ¤   ¤   ¤
e27462 ¤   ¤   ¤   ¤   ¤   // Lock window so we do not flash
f07a2d ¤   ¤   ¤   ¤   ¤   //LockWindowUpdate( hwndRichEdit );·
00af5a
586678 ¤   ¤   ¤   ¤   ¤   // if not in edit mode place us there
193cd9 ¤   ¤   ¤   ¤   ¤   if(bToggle)
154859 ¤   ¤   ¤   ¤   ¤   {
04782e ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndParent, WM_COMMAND, 34002, 0);
68d4f6 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwnd,·
47e34f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,·
409586 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   34002,·
5b155f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELONG(TRUE, 0));
111c89 ¤   ¤   ¤   ¤   ¤   }
bcaf5a
b3a60a ¤   ¤   ¤   ¤   ¤   // This could take awhile... give some feedback.
--6529 0009b35422a401101c7 Page 4 of ReadMailToolbarWndProc.c
e0af5a
25d680 ¤   ¤   ¤   ¤   ¤   hCursor = LoadCursor(NULL, IDC_WAIT);
817a07 ¤   ¤   ¤   ¤   ¤   hOldCursor = SetCursor(hCursor);
dcaf5a
29806e ¤   ¤   ¤   ¤   ¤   // get text of message
959c5e ¤   ¤   ¤   ¤   ¤   pRichEditText = GetRichEditContents (¤  hwndRichEdit,·
232263 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &nChar,·
638307 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE,·
cdb9f3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSelectedText);
b2ae30 ¤   ¤   ¤   ¤   ¤
639d25 ¤   ¤   ¤   ¤   ¤   if(!bSelectedText)
ea4859 ¤   ¤   ¤   ¤   ¤   {
ce464b ¤   ¤   ¤   ¤   ¤   ¤   // see if our mime encrypted text plugin is there
35461b ¤   ¤   ¤   ¤   ¤   ¤   nCharPos = SendMessage(¤hwndRichEdit,·
f9ea6b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EM_FINDTEXT,·
6e5dce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,(LPARAM)·
df9708 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ftEncrypted);
cbaf5a
426ebd ¤   ¤   ¤   ¤   ¤   ¤   if( nCharPos == -1 )
c68fec ¤   ¤   ¤   ¤   ¤   ¤   {
128e7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   // if not see if our mime signed text plugin is·
9baa1b ¤   ¤   ¤   ¤   ¤   ¤   ¤   // there
65cbe7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nCharPos = SendMessage(¤hwndRichEdit,·
0b5672 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EM_FINDTEXT,·
655561 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
db341a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) &ftSigned);
fddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
8eaf5a
6e82b7 ¤   ¤   ¤   ¤   ¤   ¤   // if one of them are there "click" on the plugin
430ea7 ¤   ¤   ¤   ¤   ¤   ¤   if( nCharPos != -1 )
db8fec ¤   ¤   ¤   ¤   ¤   ¤   {
7d8ab0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   POINT pt;
aaaf5a
276626 ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MessageBox(NULL, "Click!!", "Decrypt", MB_OK);
0daf5a
77ad9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   bMimeMessage = TRUE;
37af5a
21b828 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit,·
9bc6b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EM_POSFROMCHAR,·
9a529f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM) &pt,
56207b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) nCharPos);
86af5a
ceb828 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit,·
1fa51b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_LBUTTONDOWN,·
44aff7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MK_LBUTTON,·
4affce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(pt.x + 2, pt.y + 2));
faaf5a
acb828 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit,·
51abb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_LBUTTONUP,·
55aff7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MK_LBUTTON,·
e4ffce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(pt.x + 2, pt.y + 2));
35af5a
d8b828 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit,·
ca83a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_LBUTTONDBLCLK,·
3baff7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MK_LBUTTON,·
f1ffce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(pt.x + 2, pt.y + 2));
c5db3c ¤   ¤   ¤   ¤   ¤   ¤   }
777f8b ¤   ¤   ¤   ¤   ¤   ¤   else
ff8fec ¤   ¤   ¤   ¤   ¤   ¤   {
73a88f ¤   ¤   ¤   ¤   ¤   ¤   ¤   // if we were not in edit mode take ourselves·
21394d ¤   ¤   ¤   ¤   ¤   ¤   ¤   // out of edit mode
a07270 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(bToggle)
8c06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
c345a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndParent, WM_COMMAND, 34002, 0);
6b9ddc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwnd,·
5fe34f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,·
1d9586 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   34002,·
aba724 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELONG(FALSE, 0));
705268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
f6db3c ¤   ¤   ¤   ¤   ¤   ¤   }
511c89 ¤   ¤   ¤   ¤   ¤   }
9baf5a
--d1cf 00033cca6e3401101c7 Page 5 of ReadMailToolbarWndProc.c
a6d679 ¤   ¤   ¤   ¤   ¤   // Let the window update itself
3397e5 ¤   ¤   ¤   ¤   ¤   //LockWindowUpdate( NULL );·
5faf5a
24b338 ¤   ¤   ¤   ¤   ¤   // if it was not a mime message then see if there is·
e4505e ¤   ¤   ¤   ¤   ¤   // any "classic" pgp text
234464 ¤   ¤   ¤   ¤   ¤   if( !bMimeMessage && pRichEditText )//<0880.0004>
ee4859 ¤   ¤   ¤   ¤   ¤   {
274947 ¤   ¤   ¤   ¤   ¤   ¤   // Decrypt Text
a21277 ¤   ¤   ¤   ¤   ¤   ¤   bDecryptSuccessful = DecryptVerifyRichEditText(
c10f47 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pRichEditText,·
de6d6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &nChar, &FYEO);
9baf5a
42c215 ¤   ¤   ¤   ¤   ¤   ¤   if( bDecryptSuccessful )
998fec ¤   ¤   ¤   ¤   ¤   ¤   {
282850 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // put it in edit mode so they have to explicitly·
e78f4c ¤   ¤   ¤   ¤   ¤   ¤   ¤   // save it as cleartext
3d97b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // if there was a MIME message we are already in·
e6dc53 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // edit mode
f1af5a
13f62e ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(FYEO)
df06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
2af521 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TempestViewer((void *)g_pgpContext,hwnd,
81bf03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pRichEditText,nChar);
d15268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
c2c4dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
ff06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
fc13f5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(bToggle && !bMimeMessage)
fc31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
b19c48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndParent,·
0176b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,·
1f8dd6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   34002,·
b790fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
a58cfb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwnd,·
7c8c7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,·
c38dd6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   34002,·
1b9a08 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELONG(TRUE, 0));
7c6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
8eaf5a
7ff7ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetRichEditContents (hwndRichEdit,·
a66325 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pRichEditText,
d22e9f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE,·
f3cf04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSelectedText);
59531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
139e9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MessageBox(NULL, "huh?", "Decrypt", MB_OK);
0e5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
8bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
3b1c89 ¤   ¤   ¤   ¤   ¤   }
5eaf5a
49dc77 ¤   ¤   ¤   ¤   ¤   if( pRichEditText )
a74859 ¤   ¤   ¤   ¤   ¤   {
f6c620 ¤   ¤   ¤   ¤   ¤   ¤   // clean up after ourselves
323bdc ¤   ¤   ¤   ¤   ¤   ¤   HeapFree(GetProcessHeap(), 0, pRichEditText);
721c89 ¤   ¤   ¤   ¤   ¤   }
8caf5a
5dfd2d ¤   ¤   ¤   ¤   ¤   SetCursor(hOldCursor);
7614c3 ¤   ¤   ¤   ¤   ¤   break;
dc2613 ¤   ¤   ¤   ¤   }
ccaf5a
f003ba ¤   ¤   ¤   ¤   case IDC_KEYMGR:
6772c3 ¤   ¤   ¤   ¤   {
0fe9bf ¤   ¤   ¤   ¤   ¤   char szPath[MAX_PATH];
5f960f ¤   ¤   ¤   ¤   ¤   char szPGPkeys[256];
95d2bc ¤   ¤   ¤   ¤   ¤   PGPError error = kPGPError_NoErr;
3baf5a
4b1f75 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPKEYSEXE, szPGPkeys,
e6cece ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szPGPkeys));
6eaf5a
418ce8 ¤   ¤   ¤   ¤   ¤   error = PGPclGetPGPPath (szPath, sizeof(szPath));
0faf5a
8e2b28 ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
594859 ¤   ¤   ¤   ¤   ¤   {
3367d0 ¤   ¤   ¤   ¤   ¤   ¤   // '/s' keeps it from showing that·
--3424 000bf3077c7401101c7 Page 6 of ReadMailToolbarWndProc.c
ce6f27 ¤   ¤   ¤   ¤   ¤   ¤   // damn splash screen
665435 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPath, szPGPkeys);
32e38f ¤   ¤   ¤   ¤   ¤   ¤   // run it...
58cf88 ¤   ¤   ¤   ¤   ¤   ¤   WinExec(szPath, SW_SHOW);
331c89 ¤   ¤   ¤   ¤   ¤   }
654bd6 ¤   ¤   ¤   ¤   ¤   else
474859 ¤   ¤   ¤   ¤   ¤   {
e69bb5 ¤   ¤   ¤   ¤   ¤   ¤   char szError[256];
beaf5a
f875e5 ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_E_LAUNCHPGPKEYS, szError,
16e442 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szError));
83af5a
1e4c3a ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(NULL,·
161b14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szError,·
f14ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
aa5380 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK);
7d1c89 ¤   ¤   ¤   ¤   ¤   }
ebae30 ¤   ¤   ¤   ¤   ¤
1114c3 ¤   ¤   ¤   ¤   ¤   break;
d02613 ¤   ¤   ¤   ¤   }
07a3a6 ¤   ¤   ¤   }
280fe4 ¤   ¤   }
a247d1 ¤   }·
7567c5 ¤
aac543 ¤   // ·Pass all non-custom messages to old window proc
f0afea ¤   return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam ) ;
74efe6 }
76af5a
23c1bc BOOL DecryptVerifyRichEditText(char** ppBuffer, long* pLength, BOOL *FYEO)
2cbb36 {
535abb ¤   BOOL ReturnValue = FALSE;
cc62e4 ¤   void* pOutput = NULL;
8d1449 ¤   long outSize = 0;
805ad6 ¤   PGPError error;
3cf842 ¤   ulong start, size;
da1340 ¤   BOOL bPGP = FALSE;
c928c3 ¤   char szExe[256];
966896 ¤   char szDll[256];
4eaf5a
e5f1e6 ¤   LoadString(g_hinst, IDS_EXE, szExe, sizeof(szExe));
fa9ff8 ¤   LoadString(g_hinst, IDS_DLL, szDll, sizeof(szDll));
56af5a
be782f ¤   error = DecryptVerifyBuffer(g_hinst, g_hwndEudoraMainWindow, g_pgpContext,
64f7c7 ¤   ¤   ¤   ¤   g_tlsContext, szExe, szDll, *ppBuffer, *pLength,·
c7e014 ¤   ¤   ¤   ¤   FALSE, &pOutput, &outSize, FYEO);
c9af5a
4cd802 ¤   bPGP = (FindEncryptedBlock(*ppBuffer, *pLength, &start, &size) ||
bfef01 ¤   ¤   ¤   FindSignedBlock(*ppBuffer, *pLength, &start, &size));
af87c7 ¤   ¤   ¤
ec4568 ¤   /*if(!bPGP)
7dc7a1 ¤   {
611879 ¤   ¤   bPGP = ;
cb4394 ¤   }*/
2c87c7 ¤   ¤   ¤
a7d83c ·
01fc2b ¤   *pLength = outSize;
ceaf5a
78f678 ¤   if( IsntPGPError(error) )
26c7a1 ¤   {
b4c6e5 ¤   ¤   *ppBuffer = (char*)HeapReAlloc(¤GetProcessHeap(),·
13f8b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   HEAP_ZERO_MEMORY,·
32bd2c ¤   ¤   ¤   ¤   ·¤  ¤   ¤   ¤   ¤   ¤   *ppBuffer, ·
8a455c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *pLength + 1);
6faf5a
9c05d6 ¤   ¤   if(*ppBuffer)
7c5b34 ¤   ¤   {
bd3321 ¤   ¤   ¤   ReturnValue = TRUE;
1c176d ¤   ¤   ¤   memcpy(*ppBuffer, (char*)pOutput, *pLength);
60d700 ¤   ¤   ¤   *(*ppBuffer + *pLength) = 0x00; // NULL terminate the string
a91632 ¤   ¤   ¤   memset(pOutput, 0x00, *pLength);
c4af5a
bf6a87 ¤   ¤   ¤   // if this has no pgp data (no translation occured)
--4a0c 00178226944401101c7 Page 7 of ReadMailToolbarWndProc.c
f11a73 ¤   ¤   ¤   if(!bPGP)
c4f776 ¤   ¤   ¤   {
cc3c93 ¤   ¤   ¤   ¤   ReturnValue = FALSE;
0da3a6 ¤   ¤   ¤   }
b8af5a
920fe4 ¤   ¤   }
cfaf5a
d22960 ¤   ¤   //MessageBox(NULL, *ppBuffer, "buffer", MB_OK);
5c47f9 //¤ ¤   AddKeyBuffer(g_hwndEudoraMainWindow, g_pgpContext,·
d041a5 //¤ ¤   ¤   g_tlsContext, *ppBuffer, *pLength);
119371 ¤   }
d8af5a
56f01e ¤   if (pOutput != NULL)
f1c7a1 ¤   {
6f6498 ¤   ¤   PGPFreeData(pOutput);
e95b60 ¤   ¤   pOutput = NULL;
639371 ¤   }
73af5a
8e1965 ¤   return ReturnValue;
25efe6 }
78af5a
--ddef 001dd9a92fd401101c8 Page 1 of ReadMailToolbarWndProc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
724aa1 ¤   ReadMailToolbarWndProc.h,v 1.3 1997/10/22 23:05:56 elrod Exp
32f7f7 ____________________________________________________________________________*/
80af5a
50a404 #ifndef Included_ReadMailToolbarWndProc_h¤  /* [ */
840c46 #define Included_ReadMailToolbarWndProcs_h
b6af5a
a22fc7 LRESULT WINAPI ReadMailToolbarWndProc(HWND hwnd,·
9c5a62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
cabdba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
d39c5f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
85af5a
a0563a #endif /* ] Included_ReadMailToolbarWndProc_h */
81af5a
42af5a
307e4d /*__Editor_settings____
8eaf5a
844126 ¤   Local Variables:
097b17 ¤   tab-width: 4
920e6c ¤   End:
ce5f8c ¤   vi: ts=4 sw=4
9b9e9b ¤   vim: si
ddd062 _____________________*/
--c592 00068ac6abd401101c9 Page 1 of SendMailToolbarWndProc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
040a9a ¤   $Id: SendMailToolbarWndProc.c,v 1.28.2.2.2.1 1998/11/12 03:11:36 heller Exp¶
aaed4e ·$
b6f7f7 ____________________________________________________________________________*/
72af5a
9e9b16 // System Headers
405655 #include <windows.h>
863d0b #include <windowsx.h>
8d2f6f #include <richedit.h>
e890fb #include <commctrl.h>
e6b1cb #include <ctype.h>
72af5a
6baf5a
db5582 // PGPsdk Headers
57e2ff #include "pgpConfig.h"
ada076 #include "pgpKeys.h"
799f63 #include "pgpEncode.h"
442f8d #include "pgpErrors.h"
f64919 #include "pgpUtilities.h"
93ec82 #include "pgpTLS.h"
9191b9 #include "pgpSDKPrefs.h"
68af5a
384f9a // Eudora Headers
8e2ba1 #include "emssdk/Mimetype.h"
b9af5a
3e2062 // Shared Headers
815ab2 #include "PGPcl.h"
e2af5a
cbe8e0 // Project Headers
f2cc89 #include "Prefs.h"
a66c40 #include "PGPDefinedMessages.h"
013e80 #include "ReadMailToolbarWndProc.h"
b1b04c #include "EncryptSign.h"
db1db1 #include "RichEdit_IO.h"
bbe6f3 #include "TranslatorIDs.h"
33fc44 #include "Translators.h"
c705f4 #include "AddKey.h"
c9fd0e #include "DisplayMessage.h"
febbc6 #include "TranslatorUtils.h"
cd8031 #include "resource.h"
d9bead #include "MapFile.h"
cee7a0 #include "EudoraMailHeaders.h"
07bbc6 #include "TranslatorUtils.h"
5caf5a
b3af5a
10af5a
ca482b // Global Variables
536ba0 extern HINSTANCE¤   ¤   g_hinst;
b12ba9 extern HWND¤¤   ¤   ¤   g_hwndEudoraStatusbar;
1b356f extern HWND¤¤   ¤   ¤   g_hwndEudoraMainWindow;
f81c13 extern PGPContextRef¤   g_pgpContext;
5570a4 extern PGPtlsContextRef g_tlsContext;
b3af5a
2c0f8a BOOL g_bEncrypt = FALSE;
762ac0 BOOL g_bSign = FALSE;
b9f419 BOOL g_bInitializeButtons = FALSE;
e4adf7 BOOL g_bSendingMail = FALSE;
620736 HWND g_hwndSendToolbar = NULL;
68af5a
dd4d88 BOOL EncryptSignRichEditText(char** ppBuffer,·
63fb1f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·long* pLength,·
6227a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL bEncrypt,·
3af1ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL bSign,·
b6ca0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char** pAddresses,·
6d3e50 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·long NumAddresses,
c462f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char* pAttachments,
681a82 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char** pOutAttachments);
--979a 0006f88889d401101c9 Page 2 of SendMailToolbarWndProc.c
e0af5a
31fdce PGPError EncryptAttachments(char* pInAttachments,·
1858fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   char** ppOutAttachments,
6456e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds,
1ef423 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOptionListRef userOptions,
6f1ccd ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt,
6e8f55 ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bSign);
83af5a
ed29a6 BOOL VerifyOutputFileName(char* filename);
b2af5a
b9af5a
dcd5ee LRESULT WINAPI·
e9f4fb SendMailToolbarWndProc(¤HWND hwnd,·
2d1de5 ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
a246a5 ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
154624 ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
d2bb36 {
3ec9cd ¤   WNDPROC lpOldProc;
59af5a
04215d ¤   lpOldProc = (WNDPROC)GetProp( hwnd, "oldproc" );
d3e8c6 ···
bd9467 ¤   switch(msg)
c2c7a1 ¤   {
313cdc ¤   ¤   case WM_DESTROY: ··
0e5b34 ¤   ¤   {
8962d2 ¤   ¤   ¤   // ·Put back old window proc and
a71d17 ¤   ¤   ¤   SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );
a6af5a
5873ae ¤   ¤   ¤   // remove window property
519697 ¤   ¤   ¤   RemoveProp( hwnd, "oldproc" );·
72cdcb ¤   ¤   ¤   break;
0e0fe4 ¤   ¤   }
1caf5a
7fb3c8 ¤   ¤   case WM_NOTIFY:
fb5b34 ¤   ¤   {
634151 ¤   ¤   ¤   static char szTooltip[256] = {0x00};
999cc6 ¤   ¤   ¤   LPTOOLTIPTEXT lpToolTipText = (LPTOOLTIPTEXT) lParam;;
cbaf5a
2a56fd ¤   ¤   ¤   switch (((LPNMHDR)lParam)->code)
f9f776 ¤   ¤   ¤   {
6f8704 ¤   ¤   ¤   ¤   case TTN_NEEDTEXTA:
d572c3 ¤   ¤   ¤   ¤   {
658583 ¤   ¤   ¤   ¤   ¤   if(lpToolTipText->hdr.idFrom >= IDC_DECRYPT &&·
554fda ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->hdr.idFrom <= IDC_MIME )
b34859 ¤   ¤   ¤   ¤   ¤   {
530e56 ¤   ¤   ¤   ¤   ¤   ¤   int StringId =¤ lpToolTipText->hdr.idFrom - ·
c0c4d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_USER - 1000;
41af5a
71de97 ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst,·
a04350 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   StringId,
7b1003 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTooltip,
2ef951 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTooltip));
c8af5a
4de3bc ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->lpszText = szTooltip;
afaf5a
11f48f ¤   ¤   ¤   ¤   ¤   ¤   if(g_hwndEudoraStatusbar)
458fec ¤   ¤   ¤   ¤   ¤   ¤   {
3aac0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(g_hwndEudoraStatusbar,
230bb1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SB_SETTEXT,
9c0b19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)0,
8e67ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)szTooltip);
78db3c ¤   ¤   ¤   ¤   ¤   ¤   }
7eae30 ¤   ¤   ¤   ¤   ¤
b1f8ad ¤   ¤   ¤   ¤   ¤   ¤   return 0;
eb1c89 ¤   ¤   ¤   ¤   ¤   }
9f2613 ¤   ¤   ¤   ¤   }
e4af5a
76d448 ¤   ¤   ¤   ¤   case TTN_NEEDTEXTW:
4f72c3 ¤   ¤   ¤   ¤   {
6dc559 ¤   ¤   ¤   ¤   ¤   static wchar_t wideBuf[256];
beaf5a
6f8583 ¤   ¤   ¤   ¤   ¤   if(lpToolTipText->hdr.idFrom >= IDC_DECRYPT &&·
--fb3d 000d600ceef401101c9 Page 3 of SendMailToolbarWndProc.c
b24fda ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->hdr.idFrom <= IDC_MIME )
8e4859 ¤   ¤   ¤   ¤   ¤   {
253e89 ¤   ¤   ¤   ¤   ¤   ¤   int StringId = lpToolTipText->hdr.idFrom - ·
60c4d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_USER - 1000;
41ae30 ¤   ¤   ¤   ¤   ¤
e4bc0c ····¤   ¤   ¤   ¤   ¤   LoadString (g_hinst,·
ec4350 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   StringId,
a01003 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTooltip,
c1f951 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTooltip));
4caf5a
829ed7 ¤   ¤   ¤   ¤   ¤   ¤   MultiByteToWideChar(CP_ACP,·
8ae51d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_PRECOMPOSED,·
31d42a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTooltip,·
0fc849 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   -1,·
3dade4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wideBuf,·
4e0b69 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   256);
3eaf5a
19bf8f ¤   ¤   ¤   ¤   ¤   ¤   lpToolTipText->lpszText = (char*)wideBuf;
1baf5a
7af48f ¤   ¤   ¤   ¤   ¤   ¤   if(g_hwndEudoraStatusbar)
538fec ¤   ¤   ¤   ¤   ¤   ¤   {
c3ac0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(g_hwndEudoraStatusbar,
990bb1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SB_SETTEXT,
420b19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)0,
d267ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)szTooltip);
83db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ffaf5a
30f8ad ¤   ¤   ¤   ¤   ¤   ¤   return 0;
881c89 ¤   ¤   ¤   ¤   ¤   }
c72613 ¤   ¤   ¤   ¤   }
ada3a6 ¤   ¤   ¤   }
eecdcb ¤   ¤   ¤   break;
410fe4 ¤   ¤   }
ed67c5 ¤
a68e1e ¤   ¤   case WM_COMMAND:
e65b34 ¤   ¤   {
d94afd ¤   ¤   ¤   switch(wParam)
daf776 ¤   ¤   ¤   {
82039c ¤   ¤   ¤   ¤   case IDC_SENDMAIL:
8672c3 ¤   ¤   ¤   ¤   {
26cac3 ¤   ¤   ¤   ¤   ¤   HWND hwndSendToolbar = NULL;
f8cade ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt = FALSE;
8f4620 ¤   ¤   ¤   ¤   ¤   BOOL bSign = FALSE;
96419f ¤   ¤   ¤   ¤   ¤   BOOL bPGPMIME = FALSE;
477863 ¤   ¤   ¤   ¤   ¤   BYTE KeyboardStatus[256];
3372c8 ¤   ¤   ¤   ¤   ¤   //char temp[100];
54af5a
2924fa ¤   ¤   ¤   ¤   ¤   // Did the user have the shift key pressed·
078bf6 ¤   ¤   ¤   ¤   ¤   // when they sent mail?
28db24 ¤   ¤   ¤   ¤   ¤   GetKeyboardState( KeyboardStatus );
11af5a
cefc3d ¤   ¤   ¤   ¤   ¤   // Get our Toolbar
2b849f ¤   ¤   ¤   ¤   ¤   hwndSendToolbar = ·FindWindowEx(hwnd,·
034d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
69659f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",·
365152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
5caf5a
5be3b7 ¤   ¤   ¤   ¤   ¤   if(hwndSendToolbar)
8755b9 ¤   ¤   ¤   ¤   ¤   {¤
e7a451 ¤   ¤   ¤   ¤   ¤   ¤   g_bSendingMail = TRUE;
7ec531 ¤   ¤   ¤   ¤   ¤   ¤   g_hwndSendToolbar = hwndSendToolbar;
80af5a
df9ecf ¤   ¤   ¤   ¤   ¤   ¤   // set up the Eudora Plugin Menu correctly
b4d4f6 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwnd,·
5325a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,·
fa49f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_PLUGINMENU,·
85189c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
2394aa ¤   ¤   ¤   ¤   ¤   ¤
0bfccd ¤   ¤   ¤   ¤   ¤   ¤   // See if the user wants us to use PGPMIME
e9be3a ¤   ¤   ¤   ¤   ¤   ¤   if(SendMessage(¤hwndSendToolbar,
f351b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ISBUTTONCHECKED,
d65f6c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_MIME,
--9404 0006aa72d85401101c9 Page 4 of SendMailToolbarWndProc.c
b636db ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0))
798fec ¤   ¤   ¤   ¤   ¤   ¤   {
872133 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bPGPMIME = TRUE;
d1db3c ¤   ¤   ¤   ¤   ¤   ¤   }
d9af5a
892c8a ¤   ¤   ¤   ¤   ¤   ¤   // See if the user wants us encrypt the message
f9be3a ¤   ¤   ¤   ¤   ¤   ¤   if(SendMessage(¤hwndSendToolbar,
ad51b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ISBUTTONCHECKED,
983401 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_ENCRYPT,
2136db ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0))
698fec ¤   ¤   ¤   ¤   ¤   ¤   {
d8104c ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt = TRUE;
b7db3c ¤   ¤   ¤   ¤   ¤   ¤   }
16af5a
6714b7 ¤   ¤   ¤   ¤   ¤   ¤   // See if the user wants us sign the message
0cbe3a ¤   ¤   ¤   ¤   ¤   ¤   if(SendMessage(¤hwndSendToolbar,
ac51b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ISBUTTONCHECKED,
d7d176 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_SIGN,
b436db ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0))
008fec ¤   ¤   ¤   ¤   ¤   ¤   {
adb00e ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSign = TRUE;
94db3c ¤   ¤   ¤   ¤   ¤   ¤   }
441c89 ¤   ¤   ¤   ¤   ¤   }
e54bd6 ¤   ¤   ¤   ¤   ¤   else
564859 ¤   ¤   ¤   ¤   ¤   {
30dd26 ¤   ¤   ¤   ¤   ¤   ¤   int err;
d4290f ¤   ¤   ¤   ¤   ¤   ¤   char szMessage[256];
1bc1c7 ¤   ¤   ¤   ¤   ¤   ¤   char szTitle[256];
55af5a
752bf7 ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_E_SENDMAIL, szMessage,·
272808 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szMessage));
85053b ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_E_SENDMAILTITLE, szTitle,·
a77a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTitle));
cdaf5a
28c3b7 ¤   ¤   ¤   ¤   ¤   ¤   err = MessageBox(NULL,·
de2aa5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szMessage,·
ae1039 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTitle,¤
2d0e5b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONSTOP);
57af5a
117d92 ¤   ¤   ¤   ¤   ¤   ¤   if(err == IDNO)
c08fec ¤   ¤   ¤   ¤   ¤   ¤   {
ee17de ¤   ¤   ¤   ¤   ¤   ¤   ¤   return 0;
fbdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
678360 ¤   ¤   ¤   ¤   ¤   }¤
40af5a
32854a ¤   ¤   ¤   ¤   ¤   if(!bPGPMIME)
6b4859 ¤   ¤   ¤   ¤   ¤   {
5360dc ¤   ¤   ¤   ¤   ¤   ¤   if(!SendMessage(hwnd, WM_COMMAND, IDC_JUSTDOIT, 0))
5c8fec ¤   ¤   ¤   ¤   ¤   ¤   {
6517de ¤   ¤   ¤   ¤   ¤   ¤   ¤   return 0;
32db3c ¤   ¤   ¤   ¤   ¤   ¤   }
d07f8b ¤   ¤   ¤   ¤   ¤   ¤   else
278fec ¤   ¤   ¤   ¤   ¤   ¤   {
353cd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LRESULT lresult;
35007a ¤   ¤   ¤   ¤   ¤   ¤   ¤   BYTE oldKeyboardStatus[256];
20531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
066d50 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetKeyboardState( oldKeyboardStatus );
f9a52b ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetKeyboardState( KeyboardStatus );
09af5a
b929fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   lresult = ·CallWindowProc(¤ lpOldProc,·
e1e78b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd,·
251631 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   msg,·
ee6f77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam,·
8cc633 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lParam );
61531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
001f16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // reset these keys so they don't "stick"
07cc20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   oldKeyboardStatus[VK_SHIFT]¤¤   = 0;
2b92cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   oldKeyboardStatus[VK_CONTROL]¤  = 0;
66ac47 ¤   ¤   ¤   ¤   ¤   ¤   ¤   oldKeyboardStatus[VK_MENU]¤ ¤   = 0;
73af5a
17c05d ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetKeyboardState( oldKeyboardStatus );
6aaf5a
--087c 0000fc82759401101c9 Page 5 of SendMailToolbarWndProc.c
9c3f44 ¤   ¤   ¤   ¤   ¤   ¤   ¤   return lresult;
65db3c ¤   ¤   ¤   ¤   ¤   ¤   }
161c89 ¤   ¤   ¤   ¤   ¤   }
bfae30 ¤   ¤   ¤   ¤   ¤
5b14c3 ¤   ¤   ¤   ¤   ¤   break;
db2613 ¤   ¤   ¤   ¤   }
06af5a
f438a4 ¤   ¤   ¤   ¤   case IDC_JUSTDOIT:
6d72c3 ¤   ¤   ¤   ¤   {
2bcac3 ¤   ¤   ¤   ¤   ¤   HWND hwndSendToolbar = NULL;
cecade ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt = FALSE;
1d4620 ¤   ¤   ¤   ¤   ¤   BOOL bSign = FALSE;
82b657 ¤   ¤   ¤   ¤   ¤   BOOL bEncryptSuccessful = FALSE;
ba5198 ¤   ¤   ¤   ¤   ¤   HCURSOR hCursor, hOldCursor;
8572c8 ¤   ¤   ¤   ¤   ¤   //char temp[100];
08af5a
8dfc3d ¤   ¤   ¤   ¤   ¤   // Get our Toolbar
6b849f ¤   ¤   ¤   ¤   ¤   hwndSendToolbar = ·FindWindowEx(hwnd,·
274d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
c3659f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32",·
8f5152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
38af5a
1de3b7 ¤   ¤   ¤   ¤   ¤   if(hwndSendToolbar)
a88c10 ¤   ¤   ¤   ¤   ¤   {¤  ¤
ed2c8a ¤   ¤   ¤   ¤   ¤   ¤   // See if the user wants us encrypt the message
fcbe3a ¤   ¤   ¤   ¤   ¤   ¤   if(SendMessage(¤hwndSendToolbar,
a751b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ISBUTTONCHECKED,
e43401 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_ENCRYPT,
2b36db ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0))
bf8fec ¤   ¤   ¤   ¤   ¤   ¤   {
7b104c ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt = TRUE;
0bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
3faf5a
7414b7 ¤   ¤   ¤   ¤   ¤   ¤   // See if the user wants us sign the message
1dbe3a ¤   ¤   ¤   ¤   ¤   ¤   if(SendMessage(¤hwndSendToolbar,
3d51b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ISBUTTONCHECKED,
93d176 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_SIGN,
ab36db ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0))
668fec ¤   ¤   ¤   ¤   ¤   ¤   {
9ab00e ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSign = TRUE;
d5db3c ¤   ¤   ¤   ¤   ¤   ¤   }
f61c89 ¤   ¤   ¤   ¤   ¤   }
57af5a
553ae9 ¤   ¤   ¤   ¤   ¤   // does the user want us to do anything to the message
7c6e1c ¤   ¤   ¤   ¤   ¤   if(bEncrypt || bSign )
a64859 ¤   ¤   ¤   ¤   ¤   {
90cbba ¤   ¤   ¤   ¤   ¤   ¤   BOOL bSelectedText = FALSE;
d47b0e ¤   ¤   ¤   ¤   ¤   ¤   CHARRANGE chRange = {0,0};
ef021e ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndParent = NULL;
c649b4 ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndRichEdit = NULL;
0d50e4 ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndAfxWnd = NULL;
094872 ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndHeaders = NULL;
eac624 ¤   ¤   ¤   ¤   ¤   ¤   char* pRichEditText = NULL;
defc7b ¤   ¤   ¤   ¤   ¤   ¤   char** pPGPRecipients = NULL;
6c318c ¤   ¤   ¤   ¤   ¤   ¤   long NumAddresses = 0;
114843 ¤   ¤   ¤   ¤   ¤   ¤   long nChar = 0;
066ee5 ¤   ¤   ¤   ¤   ¤   ¤   HEADERDATA hd;
34af5a
1864cd ¤   ¤   ¤   ¤   ¤   ¤   // zero out HEADERDATA struct
83471f ¤   ¤   ¤   ¤   ¤   ¤   memset(&hd, 0x00, sizeof(hd));
39af5a
d72ba4 ¤   ¤   ¤   ¤   ¤   ¤   // Find the windows we are interested in...
5ee915 ¤   ¤   ¤   ¤   ¤   ¤   hwndParent¤ ¤   = GetParent(hwnd);
5348c9 ¤   ¤   ¤   ¤   ¤   ¤   hwndAfxWnd¤ ¤   = FindWindowEx(¤hwndParent,·
064d61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
7c94ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "AfxMDIFrame40",·
6a51b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
05af5a
48440e ¤   ¤   ¤   ¤   ¤   ¤   if(!hwndAfxWnd) // 3.04 and 3.05 use new mfc versions
a88fec ¤   ¤   ¤   ¤   ¤   ¤   {
b8deca ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndAfxWnd¤ = FindWindowEx(¤hwndParent,·
0f4d61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
--195e 00047aec05f401101c9 Page 6 of SendMailToolbarWndProc.c
2d8223 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "AfxMDIFrame42",·
bc00fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·¤  ¤   ¤   ¤   ¤   NULL);
8064de ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!hwndAfxWnd)·
f706b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
462889 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   char szMessage[256];
08af5a
26bf08 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_E_OLDVERSION,·
0a8e2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szMessage, sizeof(szMessage));
c8af5a
9374ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(NULL,
860067 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szMessage,
de044d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
631eb3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK);
95af5a
5c2b30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return 0;
c85268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
25af5a
3fadf7 ¤   ¤   ¤   ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤   ¤
6baf5a
143672 ¤   ¤   ¤   ¤   ¤   ¤   hwndRichEdit¤   = FindWindowEx(¤hwndAfxWnd,·
1e4d61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
69675c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "RICHEDIT",·
4251b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
0faf5a
3a19e5 ¤   ¤   ¤   ¤   ¤   ¤   hwndHeaders¤¤   = FindWindowEx(¤hwndAfxWnd,·
454d61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
1861f4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "#32770", //Dialog·
8551b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
d9af5a
62f20e ¤   ¤   ¤   ¤   ¤   ¤   // See if the user has selected text in the window
17d86e ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit, ·
35a254 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EM_EXGETSEL,·
f6d3ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)0,
b2dd26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)·
3558a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &chRange);
35af5a
d049eb ¤   ¤   ¤   ¤   ¤   ¤   bSelectedText = chRange.cpMax - chRange.cpMin;
cfaf5a
f3be01 ¤   ¤   ¤   ¤   ¤   ¤   // if not context menu invoked then we don't·
d5a198 ¤   ¤   ¤   ¤   ¤   ¤   // want to do selected text.·
4f64c7 ¤   ¤   ¤   ¤   ¤   ¤   // this will protect users·
c65772 ¤   ¤   ¤   ¤   ¤   ¤   if(lParam != SENT_FROM_CONTEXT_MENU)
b18fec ¤   ¤   ¤   ¤   ¤   ¤   {
a02fc1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSelectedText = FALSE;
87db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e6af5a
5b9369 ¤   ¤   ¤   ¤   ¤   ¤   if(!bSelectedText)
f08fec ¤   ¤   ¤   ¤   ¤   ¤   {
32cad7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   RECT rect;
c4af5a
81f031 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // there is a bug in the richedit control...·
bf4852 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // so if there is no selected text click in·
c1eb4e ¤   ¤   ¤   ¤   ¤   ¤   ¤   // the lower right corner real quick to·
6028d5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // clear up the bug...
90af5a
0b8de0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetClientRect(hwndRichEdit, &rect);
06b828 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit,·
899933 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_LBUTTONDOWN,·
63ae71 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MK_LBUTTON,·
023d0d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(rect.right - 5,·
bbe219 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.bottom -5 ));·
0faf5a
6eb828 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndRichEdit,·
9a6225 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_LBUTTONUP,·
a64290 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MK_LBUTTON, ·
2fc97f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(rect.right - 5 ,·
41e219 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.bottom -5 ));·
58db3c ¤   ¤   ¤   ¤   ¤   ¤   }
36af5a
56a17c ¤   ¤   ¤   ¤   ¤   ¤   // This could take awhile... give some feedback.
c53480 ¤   ¤   ¤   ¤   ¤   ¤   hCursor = LoadCursor(NULL, IDC_WAIT);
471534 ¤   ¤   ¤   ¤   ¤   ¤   hOldCursor = SetCursor(hCursor);
--676e 000c78aeb7b401101c9 Page 7 of SendMailToolbarWndProc.c
e0af5a
ce11f6 ¤   ¤   ¤   ¤   ¤   ¤   // get text of message
3a7179 ¤   ¤   ¤   ¤   ¤   ¤   pRichEditText = GetRichEditContents (¤  hwndRichEdit,·
ef2515 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &nChar,·
03cd70 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE,·
9beca3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSelectedText);
09af5a
2c5be6 ¤   ¤   ¤   ¤   ¤   ¤   // get the email headers
6d59d9 ¤   ¤   ¤   ¤   ¤   ¤   GetEudoraHeaders( hwndHeaders, &hd);
b0af5a
605f61 ¤   ¤   ¤   ¤   ¤   ¤   // now create an appropriate list for pgplib
f4f843 ¤   ¤   ¤   ¤   ¤   ¤   NumAddresses = CreateRecipientListFromEudoraHeaders(
49efa4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hd,·
c1fb43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pPGPRecipients);
09af5a
ee5411 ¤   ¤   ¤   ¤   ¤   ¤   if( pRichEditText )
7e5ea4 ¤   ¤   ¤   ¤   ¤   ¤   {¤  ¤   ¤   ¤
fdd27b ¤   ¤   ¤   ¤   ¤   ¤   ¤   char* pInAttachments = "";
1d58a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   char* pOutAttachments = NULL;
94af5a
814524 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // if context menu invoked then we don't·
165187 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // want to do attachments.·
d78d5b ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(lParam != SENT_FROM_CONTEXT_MENU)
5606b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
1af011 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pInAttachments = hd.pAttachments;
ee5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
daaf5a
7d0bc2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // length might have changed
5110cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   nChar = strlen(pRichEditText);
1caf5a
4d498e ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Encrypt Text
386c5a ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEncryptSuccessful = EncryptSignRichEditText(¤
a81fae ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pRichEditText,·
cc2263 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &nChar,·
1d1315 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt,·
1b863b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSign,·
3ad5ae ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPGPRecipients,·
eb08d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NumAddresses,
4a2815 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pInAttachments,
4f0d7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pOutAttachments);
13af5a
ff499e ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( bEncryptSuccessful )
cf06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
e5ef5b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetRichEditContents (¤  hwndRichEdit,·
e3ebab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pRichEditText,
4fbe69 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE,·
76a2fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSelectedText);
cfaf5a
7dfec9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(pOutAttachments)
b531b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
1cbe97 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // set the attachments
62e191 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetEudoraAttachments(¤  hwndHeaders,·
5f1b84 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pOutAttachments);
eaaf5a
b2d37f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   free(pOutAttachments);
c36560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
8ef9b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
d631b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
ba44bd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Wait for about .5 seconds·
154795 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // so user can see encrypted text...
476495 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   Sleep(500);
696560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
995268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
02db3c ¤   ¤   ¤   ¤   ¤   ¤   }
9d94aa ¤   ¤   ¤   ¤   ¤   ¤
a45a63 ¤   ¤   ¤   ¤   ¤   ¤   // want to reset buttons for context menu
d3cd9e ¤   ¤   ¤   ¤   ¤   ¤   // regardless of success or failure
98dd3e ¤   ¤   ¤   ¤   ¤   ¤   if(¤bEncryptSuccessful ||·
c3305c ¤   ¤   ¤   ¤   ¤   ¤   ¤   lParam == SENT_FROM_CONTEXT_MENU)
398fec ¤   ¤   ¤   ¤   ¤   ¤   {
80cac5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Reset the buttons
c7ee57 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
--7142 000a3c5a38a401101c9 Page 8 of SendMailToolbarWndProc.c
2a5a6c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
9434f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_ENCRYPT,·
ce9e49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(FALSE,0));
da531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
8a2d6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   HeapFree(GetProcessHeap(), 0, pRichEditText);
19de78 ¤   ¤   ¤   ¤   ¤   ¤   }·
bdaf5a
735a63 ¤   ¤   ¤   ¤   ¤   ¤   // want to reset buttons for context menu
c7cd9e ¤   ¤   ¤   ¤   ¤   ¤   // regardless of success or failure
d1dd3e ¤   ¤   ¤   ¤   ¤   ¤   if(¤bEncryptSuccessful ||·
88305c ¤   ¤   ¤   ¤   ¤   ¤   ¤   lParam == SENT_FROM_CONTEXT_MENU)
298fec ¤   ¤   ¤   ¤   ¤   ¤   {
2bcac5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Reset the buttons
64ee57 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
365a6c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
d134f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_ENCRYPT,·
e39e49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(FALSE,0));
09af5a
f4ee57 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
275a6c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_CHECKBUTTON,
00d176 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_SIGN,
2048c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(FALSE, 0));
17af5a
aeee57 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndSendToolbar,
7a18bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ENABLEBUTTON,
ab96d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)IDC_JUSTDOIT,
2148c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(FALSE, 0));
31db3c ¤   ¤   ¤   ¤   ¤   ¤   }
8baf5a
e2c620 ¤   ¤   ¤   ¤   ¤   ¤   // clean up after ourselves
04002b ¤   ¤   ¤   ¤   ¤   ¤   FreeRecipientList(pPGPRecipients, NumAddresses);
8aaf5a
0dfa06 ¤   ¤   ¤   ¤   ¤   ¤   FreeHeaderData(&hd);
b8af5a
6a6cb5 ¤   ¤   ¤   ¤   ¤   ¤   SetCursor(hOldCursor);
f01c89 ¤   ¤   ¤   ¤   ¤   }
534bd6 ¤   ¤   ¤   ¤   ¤   else
2e4859 ¤   ¤   ¤   ¤   ¤   {
56c013 ¤   ¤   ¤   ¤   ¤   ¤   // we 'successfully' did nothing to the message
1fb0a8 ¤   ¤   ¤   ¤   ¤   ¤   bEncryptSuccessful = TRUE;
0e1c89 ¤   ¤   ¤   ¤   ¤   }
84af5a
fac604 ¤   ¤   ¤   ¤   ¤   return bEncryptSuccessful;
c914c3 ¤   ¤   ¤   ¤   ¤   break;
292613 ¤   ¤   ¤   ¤   }
b2af5a
7703ba ¤   ¤   ¤   ¤   case IDC_KEYMGR:
2372c3 ¤   ¤   ¤   ¤   {
5ee9bf ¤   ¤   ¤   ¤   ¤   char szPath[MAX_PATH];
87960f ¤   ¤   ¤   ¤   ¤   char szPGPkeys[256];
02d2bc ¤   ¤   ¤   ¤   ¤   PGPError error = kPGPError_NoErr;
4caf5a
bd1f75 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_PGPKEYSEXE, szPGPkeys,
7ccece ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szPGPkeys));
5aaf5a
648ce8 ¤   ¤   ¤   ¤   ¤   error = PGPclGetPGPPath (szPath, sizeof(szPath));
fdaf5a
9a2b28 ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
f74859 ¤   ¤   ¤   ¤   ¤   {
5067d0 ¤   ¤   ¤   ¤   ¤   ¤   // '/s' keeps it from showing that·
d66f27 ¤   ¤   ¤   ¤   ¤   ¤   // damn splash screen
825435 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPath, szPGPkeys);
a2e38f ¤   ¤   ¤   ¤   ¤   ¤   // run it...
a7cf88 ¤   ¤   ¤   ¤   ¤   ¤   WinExec(szPath, SW_SHOW);
b01c89 ¤   ¤   ¤   ¤   ¤   }
004bd6 ¤   ¤   ¤   ¤   ¤   else
6e4859 ¤   ¤   ¤   ¤   ¤   {
a79bb5 ¤   ¤   ¤   ¤   ¤   ¤   char szError[256];
c7af5a
dc75e5 ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_E_LAUNCHPGPKEYS, szError,
79e442 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szError));
a3af5a
--ac44 000c392f867401101c9 Page 9 of SendMailToolbarWndProc.c
724c3a ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(NULL,·
921b14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szError,·
e34ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
bf5380 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK);
821c89 ¤   ¤   ¤   ¤   ¤   }
7bae30 ¤   ¤   ¤   ¤   ¤
0514c3 ¤   ¤   ¤   ¤   ¤   break;
882613 ¤   ¤   ¤   ¤   }
2da3a6 ¤   ¤   ¤   }
290fe4 ¤   ¤   }
1f1b52 ¤   ¤
3ae328 ¤   ¤   case WM_ENTERIDLE:
475b34 ¤   ¤   {
ab3e20 ¤   ¤   ¤   if( g_bSendingMail && g_hwndSendToolbar && wParam == MSGF_MENU )
f0f776 ¤   ¤   ¤   {
1e5336 ¤   ¤   ¤   ¤   //char szString[256] = {0x00};
c56ea7 ¤   ¤   ¤   ¤   //wsprintf(szString, "count = %d", count);
f0af5a
24f3a9 ¤   ¤   ¤   ¤   g_bInitializeButtons = FALSE;
16e2dd ¤   ¤   ¤   ¤   g_bSendingMail = FALSE;
bf5105 ¤   ¤   ¤   ¤   g_hwndSendToolbar = NULL;
f39939 ¤   ¤   ¤   ¤   PostMessage(hwnd, WM_KEYDOWN, (WPARAM)VK_ESCAPE, 0x001c0001);·
35d82d ¤   ¤   ¤   ¤   PostMessage(hwnd, WM_KEYUP, (WPARAM)VK_ESCAPE, 0x001c0001);·
dfaf5a
71530e ¤   ¤   ¤   ¤   //MessageBox(NULL, szString, 0, MB_OK);
b2a3a6 ¤   ¤   ¤   }
0baf5a
a1cdcb ¤   ¤   ¤   break;
740fe4 ¤   ¤   }
e967c5 ¤
b07810 ¤   ¤   case WM_DRAWITEM:
1e5b34 ¤   ¤   {
fecb33 ¤   ¤   ¤   // control identifier·
eaa940 ¤   ¤   ¤   UINT idCtl = (UINT) wParam;¤
68baed ¤   ¤   ¤   // item-drawing information
08fea1 ¤   ¤   ¤   LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam; ·
b8c2ae ¤   ¤   ¤   //char szString[256] = {0x00};
0daf5a
5c0644 ¤   ¤   ¤   if( g_bSendingMail )
31f776 ¤   ¤   ¤   {
2567c9 ¤   ¤   ¤   ¤   if(lpdis && lpdis->CtlType == ODT_MENU)
df72c3 ¤   ¤   ¤   ¤   {
cc322e ¤   ¤   ¤   ¤   ¤   if(*((void**)(lpdis->itemData + 4)))
c54859 ¤   ¤   ¤   ¤   ¤   {
e8fe6c ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wCommand = 0;
3ddc57 ¤   ¤   ¤   ¤   ¤   ¤   BOOL bItemChecked = FALSE;
9daf5a
bba537 ¤   ¤   ¤   ¤   ¤   ¤   // see if it is already checked
20aa44 ¤   ¤   ¤   ¤   ¤   ¤   if((lpdis->itemState & ODS_CHECKED))·
858fec ¤   ¤   ¤   ¤   ¤   ¤   {
39efc4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bItemChecked = TRUE;
addb3c ¤   ¤   ¤   ¤   ¤   ¤   }
a6af5a
769e1d ¤   ¤   ¤   ¤   ¤   ¤   // see which plugin this menuitem represents
0cc793 ¤   ¤   ¤   ¤   ¤   ¤   if( !strcmp(*((char**)(lpdis->itemData + 4)),·
7317e9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "PGP plugin 1 (use toolbar)") )
658fec ¤   ¤   ¤   ¤   ¤   ¤   {
351118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   wCommand = IDC_ENCRYPT;
cdaf5a
2d18fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   // we might be getting a window from a cancel...
c69b98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( g_bInitializeButtons && bItemChecked)·
2106b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
d8c759 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_bEncrypt = TRUE;
fc5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
01db3c ¤   ¤   ¤   ¤   ¤   ¤   }
c31f24 ¤   ¤   ¤   ¤   ¤   ¤   else if( !strcmp(*((char**)(lpdis->itemData + 4)),·
4f650b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "PGP plugin 2 (use toolbar)") )
da8fec ¤   ¤   ¤   ¤   ¤   ¤   {
f01f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   wCommand = IDC_SIGN;
2aaf5a
d918fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   // we might be getting a window from a cancel...
c39b98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( g_bInitializeButtons && bItemChecked)·
--bdca 0000ec1e01f401101c9 Page 10 of SendMailToolbarWndProc.c
2606b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
1fc1e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_bSign¤= TRUE;
bc5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
7cdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
88af5a
eae265 ¤   ¤   ¤   ¤   ¤   ¤   if( !g_bInitializeButtons )
1a8fec ¤   ¤   ¤   ¤   ¤   ¤   {
c06064 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // make sure the window handle is valid
9f50f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( g_hwndSendToolbar)·
ff06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
a3a380 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( wCommand ) // is this one of our menus
b631b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
da451b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bCommandPressed = FALSE;
4eafad ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bPGPMIMEPressed = FALSE;
0baf5a
3aa1d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bCommandPressed = SendMessage(¤
946d0d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_hwndSendToolbar,·
1b68cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ISBUTTONCHECKED,·
d336b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wCommand,·
96c410 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
8eaf5a
0e0257 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bPGPMIMEPressed = SendMessage(¤
486d0d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_hwndSendToolbar,·
a668cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_ISBUTTONCHECKED,·
3c50ae ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_MIME,·
29c410 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
64af5a
5a6402 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( (bCommandPressed &&·
aa5968 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   !bItemChecked && bPGPMIMEPressed) ||·
eee2c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (bCommandPressed && bItemChecked &&·
082778 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   !bPGPMIMEPressed) ||
80e07b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (!bCommandPressed && bItemChecked))
16dec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
4c8bc0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwnd,·
d6e516 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,·
6ff479 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)lpdis->itemID,·
6c4b47 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
378a13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
0b6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
db5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
9edb3c ¤   ¤   ¤   ¤   ¤   ¤   }
f01c89 ¤   ¤   ¤   ¤   ¤   }
0c2613 ¤   ¤   ¤   ¤   }
17a3a6 ¤   ¤   ¤   }
d1cdcb ¤   ¤   ¤   break;
a40fe4 ¤   ¤   }
ab47d1 ¤   }·
e367c5 ¤
2ec543 ¤   // ·Pass all non-custom messages to old window proc
1eafea ¤   return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam ) ;
aaefe6 }
e0af5a
967efe BOOL·
eca64b EncryptSignRichEditText(char** ppBuffer,·
d86c60 ¤   ¤   ¤   ¤   ¤   ¤   long* pLength,·
25b0df ¤   ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt,·
fe9669 ¤   ¤   ¤   ¤   ¤   ¤   BOOL bSign,·
bd27ca ¤   ¤   ¤   ¤   ¤   ¤   char** pAddresses,·
98a01a ¤   ¤   ¤   ¤   ¤   ¤   long NumAddresses,
9c8f36 ¤   ¤   ¤   ¤   ¤   ¤   char* pAttachments,
617559 ¤   ¤   ¤   ¤   ¤   ¤   char** ppOutAttachments)
8abb36 {
665abb ¤   BOOL ReturnValue = FALSE;
2962e4 ¤   void* pOutput = NULL;
701449 ¤   long outSize = 0;
af36a8 ¤   PGPError error = kPGPError_NoErr;
243731 ¤   PGPOptionListRef userOptions = kPGPInvalidRef;
661ce7 ¤   PRECIPIENTDIALOGSTRUCT prds = NULL;¤
5128c3 ¤   char szExe[256];
f06896 ¤   char szDll[256];
c1af5a
0ef1e6 ¤   LoadString(g_hinst, IDS_EXE, szExe, sizeof(szExe));
--782c 0006707940a401101c9 Page 11 of SendMailToolbarWndProc.c
5a9ff8 ¤   LoadString(g_hinst, IDS_DLL, szDll, sizeof(szDll));
4aaf5a
77b649 ¤   // allocate a recipient dialog structure
bf793c ¤   prds = (PRECIPIENTDIALOGSTRUCT) calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);
d33b8e ¤   if (!prds)
17c7a1 ¤   {
f924ec ¤   ¤   PGPclErrorBox(g_hwndEudoraMainWindow, kPGPError_OutOfMemory);
f398aa ¤   ¤   return FALSE;
999371 ¤   }
8eaf5a
b43a12 ¤   error = PGPsdkLoadDefaultPrefs(g_pgpContext);
328385 ¤   if (IsPGPError(error))
afc7a1 ¤   {
f3e45f ¤   ¤   PGPclEncDecErrorBox(g_hwndEudoraMainWindow, error);
2e98aa ¤   ¤   return FALSE;
3e9371 ¤   }
82af5a
c764bf ¤   error = PGPOpenDefaultKeyRings(g_pgpContext, (PGPKeyRingOpenFlags)0,·
40908d ¤   ¤   ¤   ¤   &(prds->OriginalKeySetRef));
66af5a
d38385 ¤   if (IsPGPError(error))
25c7a1 ¤   {
1de45f ¤   ¤   PGPclEncDecErrorBox(g_hwndEudoraMainWindow, error);
7393bf ¤   ¤   return S_FALSE;
2b9371 ¤   }
a0af5a
017b73 ¤   if(prds && bEncrypt)
0bc7a1 ¤   {
2e888a ¤   ¤   char szTitle[256]¤  ¤   = {0x00};¤  // title for recipient dialog
787fb3 ¤   ¤   UINT recipientReturn¤   = FALSE;¤   // recipient dialog result
9daf5a
e7c855 ¤   ¤   LoadString(GetModuleHandle("PGPplugin.dll"),·
e4d7ad ¤   ¤   ¤   IDS_TITLE_RECIPIENTDIALOG, szTitle, sizeof(szTitle));
31af5a
d4c170 ¤   ¤   if( IsntPGPError(error) )
8f5b34 ¤   ¤   {
8859a5 ¤   ¤   ¤   prds->Context¤  ¤   ¤   = g_pgpContext;
9ad53b ¤   ¤   ¤   prds->tlsContext¤   ¤   = g_tlsContext;
7b19f7 ¤   ¤   ¤   prds->Version¤  ¤   ¤   = CurrentPGPrecipVersion;
cfcf01 ¤   ¤   ¤   prds->hwndParent¤   ¤   = g_hwndEudoraMainWindow;
04e5d3 ¤   ¤   ¤   prds->szTitle¤  ¤   ¤   = szTitle;
728dca ¤   ¤   ¤   prds->dwOptions¤¤   ¤   = PGPCL_ASCIIARMOR;¤
ccaf5a
a0e0e4 ¤   ¤   ¤   prds->dwDisableFlags¤   = PGPCL_DISABLE_WIPEORIG |
dab4b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPCL_DISABLE_ASCIIARMOR;
40af5a
fbf821 ¤   ¤   ¤   prds->dwNumRecipients¤  = NumAddresses;¤
f36a47 ¤   ¤   ¤   prds->szRecipientArray¤ = pAddresses;
51af5a
8b25d9 ¤   ¤   ¤   // If shift is pressed, force the dialog to pop.
671a3f ¤   ¤   ¤   if (GetAsyncKeyState( VK_CONTROL) & 0x8000)
2f4da5 ¤   ¤   ¤   ¤   prds->dwDisableFlags|=PGPCL_DISABLE_AUTOMODE;
b9af5a
622730 ¤   ¤   ¤   // See who we wish to encrypt this to
7fab37 ¤   ¤   ¤   recipientReturn = PGPclRecipientDialog( prds );
cd0fe4 ¤   ¤   }
9baf5a
b4729f ¤   ¤   if (prds->AddedKeys != NULL)
b45b34 ¤   ¤   {
803fe2 ¤   ¤   ¤   PGPUInt32 numKeys;
4eaf5a
43871b ¤   ¤   ¤   PGPCountKeys(prds->AddedKeys, &numKeys);
e1c77a ¤   ¤   ¤   if (numKeys > 0)
b2fc81 ¤   ¤   ¤   ¤   PGPclQueryAddKeys(g_pgpContext, g_tlsContext,·
4e9522 ¤   ¤   ¤   ¤   ¤   g_hwndEudoraMainWindow, prds->AddedKeys, NULL);
44af5a
04c53e ¤   ¤   ¤   PGPFreeKeySet(prds->AddedKeys);
8c5487 ¤   ¤   ¤   prds->AddedKeys = NULL;
620fe4 ¤   ¤   }
20af5a
03ffb6 ¤   ¤   if (!recipientReturn)
675b34 ¤   ¤   {
--8042 000f8f7e90c401101c9 Page 12 of SendMailToolbarWndProc.c
823036 ¤   ¤   ¤   if (prds->SelectedKeySetRef != NULL)
5a9af7 ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
fabb2e ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
4cadfc ¤   ¤   ¤   free(prds);
3b5f1f ¤   ¤   ¤   return FALSE;
0d0fe4 ¤   ¤   }
dc9371 ¤   }
baaf5a
67f678 ¤   if( IsntPGPError(error) )
c4c7a1 ¤   {
8486d5 ¤   ¤   error = EncryptSignBuffer(g_hinst, g_hwndEudoraMainWindow,
b523ad ¤   ¤   ¤   ¤   ¤   g_pgpContext, g_tlsContext, szExe, szDll,
9395c8 ¤   ¤   ¤   ¤   ¤   *ppBuffer, *pLength, prds, NULL, &userOptions, &pOutput,
f1111b ¤   ¤   ¤   ¤   ¤   &outSize, bEncrypt, bSign, FALSE);
3b9371 ¤   }
610e24 ¤   else
20c7a1 ¤   {
ade45f ¤   ¤   PGPclEncDecErrorBox(g_hwndEudoraMainWindow, error);
c99371 ¤   }
bbaf5a
d1fc2b ¤   *pLength = outSize;
5faf5a
7ef678 ¤   if( IsntPGPError(error) )
b6c7a1 ¤   {
af780f ¤   ¤   if( pOutput )
ce5b34 ¤   ¤   {
2dc607 ¤   ¤   ¤   *ppBuffer = (char*)HeapReAlloc(¤GetProcessHeap(),·
8ef85b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   HEAP_ZERO_MEMORY,·
77783d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *ppBuffer,·
0d4267 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *pLength + 1);
f4af5a
a5c263 ¤   ¤   ¤   if(*ppBuffer)
c6f776 ¤   ¤   ¤   {
bdb8dd ¤   ¤   ¤   ¤   ReturnValue = TRUE;
7531d8 ¤   ¤   ¤   ¤   memcpy(*ppBuffer, (char*)pOutput, *pLength);
944ada ¤   ¤   ¤   ¤   *(*ppBuffer + *pLength) = 0x00; // NULL terminate the string
8744af ¤   ¤   ¤   ¤   memset(pOutput, 0x00, *pLength);
97a3a6 ¤   ¤   ¤   }
ec6b93 ¤   ¤   ¤   else·
2ef776 ¤   ¤   ¤   {
7d2f55 ¤   ¤   ¤   ¤   error = kPGPError_OutOfMemory;
8fa3a6 ¤   ¤   ¤   }
f4af5a
155390 ¤   ¤   ¤   PGPFreeData(pOutput);
1f0fe4 ¤   ¤   }
ac9371 ¤   }
1467c5 ¤
28061a ¤   // are there attachments?
063dfa ¤   if(IsntPGPError(error) && pAttachments && *pAttachments)·
8ac7a1 ¤   {
9e5213 ¤   ¤   error = EncryptAttachments(¤pAttachments,·
765924 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppOutAttachments,
ed428b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prds,
a81671 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   userOptions,
db4b35 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt,
823772 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSign);
bbaf5a
589371 ¤   }
e8af5a
c68fdd ¤   if( PGPRefIsValid(userOptions) )
e5c7a1 ¤   {
5cd3ae ¤   ¤   PGPFreeOptionList(userOptions);
419371 ¤   }
50af5a
9db3e7 ¤   if (prds)
4ac7a1 ¤   {
a762ab ¤   ¤   if (prds->SelectedKeySetRef != NULL)
2acf5b ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
c02d6f ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
bbd708 ¤   ¤   free(prds);
959371 ¤   }
f8af5a
--3d0b 00079a18f6c401101c9 Page 13 of SendMailToolbarWndProc.c
721965 ¤   return ReturnValue;
34efe6 }
a3af5a
c7fdce PGPError EncryptAttachments(char* pInAttachments,·
e458fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   char** ppOutAttachments,
5c56e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds,
5af423 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOptionListRef userOptions,
4d1ccd ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt,
ac253b ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bSign)
3abb36 {
1a36a8 ¤   PGPError error = kPGPError_NoErr;
8e9a4b ¤   char in_file[MAX_PATH] = {0x00};
af2499 ¤   char out_file[MAX_PATH] = {0x00};
f2560d ¤   char* pInAttachBackup = NULL;
f6869e ¤   char* token = NULL;
2e95fe ¤   long size = 0;
6f28c3 ¤   char szExe[256];
b76896 ¤   char szDll[256];
99af5a
37f1e6 ¤   LoadString(g_hinst, IDS_EXE, szExe, sizeof(szExe));
bb9ff8 ¤   LoadString(g_hinst, IDS_DLL, szDll, sizeof(szDll));
75af5a
783dd1 ¤   size = strlen(pInAttachments);
04af5a
5c4891 ¤   pInAttachBackup = malloc(size + 1);
12af5a
50d6c7 ¤   if( !pInAttachBackup )
9bc7a1 ¤   {
b94030 ¤   ¤   return kPGPError_OutOfMemory;
e19371 ¤   }
7d0e24 ¤   else
ddc7a1 ¤   {
19eb18 ¤   ¤   strcpy(pInAttachBackup, pInAttachments);
8c9371 ¤   }
44af5a
bc83cf ¤   *ppOutAttachments = malloc(size*2);
76af5a
42c2f9 ¤   if( !*ppOutAttachments )
4fc7a1 ¤   {
735c62 ¤   ¤   free(pInAttachBackup);
3b4030 ¤   ¤   return kPGPError_OutOfMemory;
af9371 ¤   }
f8af5a
3dbde6 ¤   // NULL terminate
fffd5a ¤   **ppOutAttachments = 0x00;
31af5a
649c62 ¤   token = strtok(pInAttachments,";");
a4af5a
68d6c7 ¤   while(token)
06c7a1 ¤   {
20bd1f ¤   ¤   // strip off leading spaces or tabs
98764c ¤   ¤   while( *token == ' ' || *token == '\t')
dc5b34 ¤   ¤   {
cc5e0a ¤   ¤   ¤   token++;
690fe4 ¤   ¤   }
82af5a
31fa09 ¤   ¤   strcpy(in_file, token);
6a1428 ¤   ¤   strcpy(out_file, token);
be2f8f ¤   ¤   strcat(out_file, ".pgp");
d7af5a
cf6694 ¤   ¤   if(VerifyOutputFileName(out_file))
eb5b34 ¤   ¤   {
797e1c ¤   ¤   ¤   strcat(*ppOutAttachments, out_file);
a74fa5 ¤   ¤   ¤   strcat(*ppOutAttachments, ";");
73af5a
8a2181 ¤   ¤   ¤   error = EncryptSignFile(g_hinst, g_hwndEudoraMainWindow,·
239c4a ¤   ¤   ¤   ¤   ¤   ¤   g_pgpContext, g_tlsContext, szExe, szDll, in_file,
d13189 ¤   ¤   ¤   ¤   ¤   ¤   prds, NULL, &userOptions, out_file, bEncrypt, bSign,
3091ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
6d0fe4 ¤   ¤   }
0f0e1d ¤   ¤   else
795b34 ¤   ¤   {
--33dd 000de6b0fd3401101c9 Page 14 of SendMailToolbarWndProc.c
47f773 ¤   ¤   ¤   strcpy(*ppOutAttachments, pInAttachBackup);
ecc635 ¤   ¤   ¤   error = kPGPError_UserAbort;
5dcdcb ¤   ¤   ¤   break;
180fe4 ¤   ¤   }
72af5a
029270 ¤   ¤   token = strtok(NULL,";");¤
b79371 ¤   }
87af5a
fc9f0f ¤   if(pInAttachBackup)
90c7a1 ¤   {
db5c62 ¤   ¤   free(pInAttachBackup);
ae9371 ¤   }
93af5a
d7c674 ¤   return error;
1cefe6 }
a0af5a
03c4a8 BOOL VerifyOutputFileName(char* filename)
b0bb36 {
4dc564 ¤   HANDLE hFileSearch = NULL;
29409e ¤   WIN32_FIND_DATA FindDataStruct;
8b875d ¤   BOOL returnValue = FALSE;
59af5a
d1260c ¤   hFileSearch = FindFirstFile(filename, &FindDataStruct);
c2af5a
e250fb ¤   if(hFileSearch != INVALID_HANDLE_VALUE)
69c7a1 ¤   {
77e418 ¤   ¤   BOOL userCancel = FALSE;
86dee0 ¤   ¤   OPENFILENAME saveFileName;
03b3ff ¤   ¤   char initialDir[MAX_PATH] = {0x00};
d96a3c ¤   ¤   char* slash = NULL;
bec79b ¤   ¤   char finalFile[MAX_PATH] = {0x00};
94f473 ¤   ¤   char defaultExtension[MAX_PATH] = {0x00};
94b9d4 ¤   ¤   int fileStart = 0, fileExtensionStart = 0;
0aaf5a
f0bf66 ¤   ¤   strcpy(initialDir, filename );
4e6a00 ¤   ¤   strcpy(finalFile, filename );
8caf5a
7bf5ce ¤   ¤   slash = strrchr(initialDir, '\\');
b3af5a
15fdd8 ¤   ¤   if(slash)
795b34 ¤   ¤   {
2c58bb ¤   ¤   ¤   *slash = 0x00;
210fe4 ¤   ¤   }
bcaf5a
e32c78 ¤   ¤   saveFileName.lStructSize=sizeof(saveFileName);·
f48927 ¤   ¤   saveFileName.hwndOwner=NULL;·
5b1689 ¤   ····saveFileName.hInstance=NULL;·
a83529 ¤   ····saveFileName.lpstrFilter=¤  "PGP Files (*.PGP, *.ASC)\0"
d17c02 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "*.PGP;*.ASC\0"
971a5c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "All Files (*.*)\0"
ee7522 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "*.*\0\0";
7c265c ¤   ¤   saveFileName.lpstrCustomFilter=NULL;·
feb8dd ¤   ····saveFileName.nMaxCustFilter=0;·
0ce8fc ¤   ¤   saveFileName.nFilterIndex=1;·
ef5167 ··¤ ····saveFileName.lpstrFile=finalFile;·
c7c499 ¤   ····saveFileName.nMaxFile=MAX_PATH;·
90d38f ¤   ····saveFileName.lpstrFileTitle=NULL;·
62e222 ¤   ¤   saveFileName.nMaxFileTitle=0;·
ba626c ¤   ¤   saveFileName.lpstrInitialDir=initialDir;·
5135fd ¤   ¤   saveFileName.lpstrTitle=NULL;·
51e715 ¤   ¤   saveFileName.Flags= OFN_OVERWRITEPROMPT |·
d06699 ¤   ¤   ¤   ¤   ¤   ¤   ¤   OFN_HIDEREADONLY |·
a6e7bd ¤   ¤   ¤   ¤   ¤   ¤   ¤   OFN_NOREADONLYRETURN|·
104193 ¤   ¤   ¤   ¤   ¤   ¤   ¤   OFN_EXPLORER;
af7dba ¤   ¤   saveFileName.nFileOffset=fileStart;·
9c1bfb ¤   ¤   saveFileName.nFileExtension=fileExtensionStart;·
45d61a ¤   ¤   saveFileName.lpstrDefExt=defaultExtension;·
027106 ¤   ¤   saveFileName.lCustData=(long)NULL;·
d723e8 ¤   ¤   saveFileName.lpfnHook=NULL;
87c085 ¤   ¤   saveFileName.lpTemplateName=NULL;·
faaf5a
dec20a ¤   ¤   returnValue = GetSaveFileName(&saveFileName);
--a9eb 0019cd4b953401101c9 Page 15 of SendMailToolbarWndProc.c
e0af5a
2db88a ¤   ¤   if(returnValue)
765b34 ¤   ¤   {
014416 ¤   ¤   ¤   strcpy(filename, finalFile);
640fe4 ¤   ¤   }
6e1b52 ¤   ¤
3136e3 ¤   ¤   FindClose(hFileSearch);
8c9371 ¤   }
770e24 ¤   else
e1c7a1 ¤   {
92a79a ¤   ¤   returnValue = ·TRUE;
2f9371 ¤   }
29af5a
cdaf5a
62acc5 ¤   return returnValue;
3baf5a
9cbe43 }¶
--8a76 0011c6be64c401101ca Page 1 of SendMailToolbarWndProc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ad7d14 ¤   SendMailToolbarWndProc.h,v 1.3 1997/10/22 23:05:57 elrod Exp
3df7f7 ____________________________________________________________________________*/
59af5a
f7733f #ifndef Included_SendMailToolbarWndProc_h¤  /* [ */
93f4db #define Included_SendMailToolbarWndProc_h
67af5a
49af5a
c1f8fc LRESULT WINAPI SendMailToolbarWndProc(HWND hwnd,·
165a62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
a8bdba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
4a9c5f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
63af5a
43b050 #endif /* ] Included_SendMailToolbarWndProc_h */
43af5a
bfaf5a
267e4d /*__Editor_settings____
b7af5a
ee4126 ¤   Local Variables:
947b17 ¤   tab-width: 4
150e6c ¤   End:
205f8c ¤   vi: ts=4 sw=4
ab9e9b ¤   vim: si
1cd062 _____________________*/
--e105 0014315933d401101cb Page 1 of TranslatorIDs.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
842e79 ¤   TranslatorIDs.h,v 1.2 1997/10/22 23:05:58 elrod Exp
edf7f7 ____________________________________________________________________________*/
53af5a
cf6011 #ifndef Included_TranslatorIDs_h¤   /* [ */
2e26d4 #define Included_TranslatorIDs_h
d5af5a
c401bf typedef enum TranslatorID
c5bb36 {
fa183c ¤   kInvalidTranslatorID = 0,
a067c5 ¤
7c1d57 ¤   // note: ids must start at 1 and be sequential
876ecb ¤   kFirstTranslatorID = 1,
68af5a
d61450 ¤   kDecryptTranslatorID = kFirstTranslatorID,
6e9bfc ¤   kVerifyTranslatorID,
c267c5 ¤
79f5ef ¤   kEncryptTranslatorID ,
4ab5d5 ¤   kSignTranslatorID,
1b014a ¤   kEncryptAndSignTranslatorID,
ac67c5 ¤
261a80 ¤   kFirstManualTranslatorID,
9467c5 ¤
7bcd6b ¤   kManualEncryptSignTranslatorID = kFirstManualTranslatorID,
3f0b66 ¤   kManualDecryptVerifyTranslatorID,
e49c97 //¤ kManualAddKeyTranslatorID,·
f5ba7e ¤   kLastTranslatorIDPlusOne,
8f67c5 ¤
830234 ¤   kPGPNumTranslators¤ = kLastTranslatorIDPlusOne - kFirstTranslatorID
af519d } TranslatorID;
aaaf5a
d5af5a
88af5a
bdc62a #endif /* ] Included_TranslatorIDs_h */
8faf5a
54af5a
727e4d /*__Editor_settings____
6baf5a
904126 ¤   Local Variables:
5d7b17 ¤   tab-width: 4
770e6c ¤   End:
b15f8c ¤   vi: ts=4 sw=4
479e9b ¤   vim: si
437c50 _____________________*/¶
--3ee6 00087b016af401101cc Page 1 of TranslatorUtils.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
608330 ¤   $Id: TranslatorUtils.c,v 1.8.8.1 1998/11/12 03:11:38 heller Exp $
caf7f7 ____________________________________________________________________________*/
d5af5a
ef9b16 // System Headers
935655 #include <windows.h>
813d0b #include <windowsx.h>
40bb5f #include <assert.h>
630a8b #include <time.h>
fdaf5a
ae5582 // PGPsdk Headers
f6e2ff #include "pgpConfig.h"
d3a076 #include "pgpKeys.h"
7c2f8d #include "pgpErrors.h"
7a4919 #include "pgpUtilities.h"
c89f72 #include "pgpHash.h"
2daf5a
a2e8e0 // Project Headers
06bead #include "MapFile.h"
ebd2cf #include "BlockUtils.h"
efbbc6 #include "TranslatorUtils.h"
58af5a
752cef /*¤ Address list:
049d8e ¤   ¤   [0] From
ab4ab4 ¤   ¤   [1] To
22e6f9 ¤   ¤   [2] Cc
7af4d1 ¤   ¤   [3] Bcc
707fe0 */
eaaf5a
fe4a66 #define¤FROM_ADDRESS¤   0
f7af5a
6a0335 /*____________________________________________________________________________
4806cd ¤   'EudoraAddresses' as supplied by Eudora consists·
dc6954 ¤   of an array of StringHandles that come in groups·
fd3770 ¤   of three. ·Each group consists of
fdaf5a
41b932 ¤   ¤   { "user@host.domain", "full user name", "nickname" }
1c1b52 ¤   ¤
b30bb7 ¤   The last two entries may be null and the list terminates·
8833d3 ¤   when a first item is null.
e3f7f7 ____________________________________________________________________________*/
204fe7 unsigned long·
923d0d CreateRecipientList(char** EudoraAddresses,·
f741f8 ¤   ¤   ¤   ¤   ¤   char*** Recipients)
35bb36 {
f9ada5 ¤   const ushort kClumpSize = 3;
f3c5cb ¤   ulong numRecipients = 0;
bd1b0f ¤   ulong curGroupIndex¤= 0;¤   // start at first recipient·
fcaf5a
830e3d ¤   assert(EudoraAddresses);
67045a ¤   assert(Recipients);
34af5a
ec6786 ¤   while ( EudoraAddresses )
4cc7a1 ¤   {
1d2f75 ¤   ¤   char* userName = NULL;
21af5a
1fb562 ¤   ¤   userName = EudoraAddresses [ curGroupIndex ];
41af5a
adf157 ¤   ¤   if ( !userName )
33519f ¤   ¤   ¤   break;¤ // all done
401b52 ¤   ¤
87cae4 ¤   ¤   if ( userName[ 0 ] == '\0' )
48519f ¤   ¤   ¤   break;¤ // all done
4faf5a
c8af6b ¤   ¤   // Don't encrypt to the From: address */
7eaf5a
87cc98 ¤   ¤   if (curGroupIndex == (FROM_ADDRESS * kClumpSize))
--bb0c 0009d0ef8ca401101cc Page 2 of TranslatorUtils.c
e35b34 ¤   ¤   {
01f0e2 ¤   ¤   ¤   curGroupIndex += kClumpSize;
e817f5 ¤   ¤   ¤   continue;
fb0fe4 ¤   ¤   }
4baf5a
7d7500 ¤   ¤   if(!(*Recipients))
8a5b34 ¤   ¤   {
78e56d ¤   ¤   ¤   *Recipients = (char**) malloc(sizeof(char*));
b2af5a
8c43e3 ¤   ¤   ¤   if(*Recipients)
42f776 ¤   ¤   ¤   {
843020 ¤   ¤   ¤   ¤   (*Recipients)[numRecipients] =·
785025 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(userName) + 1);·
56af5a
ea053c ¤   ¤   ¤   ¤   strcpy((*Recipients)[numRecipients++], userName);
93a3a6 ¤   ¤   ¤   }
84bb8c ¤   ¤   ¤   else
c7f776 ¤   ¤   ¤   {
f5f622 ¤   ¤   ¤   ¤   break;
afa3a6 ¤   ¤   ¤   }
080fe4 ¤   ¤   }
0f0e1d ¤   ¤   else
ce5b34 ¤   ¤   {
41dbb0 ¤   ¤   ¤   *Recipients = (char**) realloc(*Recipients,·
5ad4cd ¤   ¤   ¤   ¤   sizeof(char*) * (numRecipients + 1) );
4daf5a
2743e3 ¤   ¤   ¤   if(*Recipients)
51f776 ¤   ¤   ¤   {
bb3020 ¤   ¤   ¤   ¤   (*Recipients)[numRecipients] =·
d15025 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(userName) + 1);·
77af5a
71053c ¤   ¤   ¤   ¤   strcpy((*Recipients)[numRecipients++], userName);
98a3a6 ¤   ¤   ¤   }
3bbb8c ¤   ¤   ¤   else
cef776 ¤   ¤   ¤   {
80f622 ¤   ¤   ¤   ¤   break;
ada3a6 ¤   ¤   ¤   }
510fe4 ¤   ¤   }
141b52 ¤   ¤
01f50f ¤   ¤   curGroupIndex += kClumpSize;
189371 ¤   }
43af5a
bfdde5 ¤   return numRecipients;
93efe6 }
52af5a
2bc823 void·
157f6e FreeRecipientList(char** Recipients,·
7aed0a ¤   ¤   ¤   ¤   ··unsigned long ·numRecipients)
18bb36 {
c53745 ¤   unsigned long index = 0;
1baf5a
02f570 ¤   //assert(Recipients);
73af5a
d2b1fb ¤   if(Recipients)
bdc7a1 ¤   {
e1f6e5 ¤   ¤   for(index = 0; index < numRecipients; index++)
7f5b34 ¤   ¤   {
b862b4 ¤   ¤   ¤   if( Recipients[index] )
2cf776 ¤   ¤   ¤   {
2a00de ¤   ¤   ¤   ¤   // free each string
9a56e4 ¤   ¤   ¤   ¤   free(Recipients[index]);
13a3a6 ¤   ¤   ¤   }
ba0fe4 ¤   ¤   }
8caf5a
83bc80 ¤   ¤   free(Recipients);
7c9371 ¤   }
93efe6 }
92af5a
59af5a
3f33d7 ¤   long
213e45 ConvertFileToEncryptedPGPMIME(
9d7654 ¤   const char*¤¤   ¤   file,
--991d 0004a59c0ee401101cc Page 3 of TranslatorUtils.c
c82e35 ¤   char *¤ ¤   ¤   ¤   delimiter )
31bb36 {
258994 ¤   long¤   ¤   err¤= 0;
4e3fc9 ¤   char¤   ¤   tempFile[MAX_PATH];
94af5a
20758e ¤   assert(file);
8e33cd ¤   assert(delimiter);
fa67c5 ¤
58e8c4 ¤   GetUniqueMIMEDelimiter( delimiter );
e8af5a
5baf4b ¤   strcpy(tempFile, file);
b5af76 ¤   strcat(tempFile, ".tmp");
f5af5a
8d6b3a ¤   err¤= WrapWithEncryptedPGPMIME( file, tempFile, delimiter);
dcaf5a
ce8598 ¤   if ( !err )·
2cc7a1 ¤   {
5d699f ¤   ¤   if( DeleteFile(file))
435b34 ¤   ¤   {
64b35c ¤   ¤   ¤   MoveFile( tempFile, file );
6d0fe4 ¤   ¤   }
cc9371 ¤   }
8967c5 ¤
0bdeb7 ¤   return( err );
f0efe6 }
dcaf5a
af33d7 ¤   long
361b4d ConvertFileToSignedPGPMIME(
277654 ¤   const char*¤¤   ¤   file,
ceb57a ¤   const char*¤¤   ¤   sigfile,·
42d382 ¤   long¤   ¤   ¤   ¤   hash,
552e35 ¤   char *¤ ¤   ¤   ¤   delimiter )
ecbb36 {
d88994 ¤   long¤   ¤   err¤= 0;
613fc9 ¤   char¤   ¤   tempFile[MAX_PATH];
01af5a
a5758e ¤   assert(file);
65dd67 ¤   assert(sigfile);
af33cd ¤   assert(delimiter);
5967c5 ¤
f5e8c4 ¤   GetUniqueMIMEDelimiter( delimiter );
e6af5a
5faf4b ¤   strcpy(tempFile, file);
1aaf76 ¤   strcat(tempFile, ".tmp");
66af5a
9871c7 ¤   err¤= WrapWithSignedPGPMIME( file, sigfile, tempFile, delimiter, hash);
4caf5a
a78598 ¤   if ( !err )·
06c7a1 ¤   {
fe699f ¤   ¤   if( DeleteFile(file))
fe5b34 ¤   ¤   {
bab35c ¤   ¤   ¤   MoveFile( tempFile, file );
990fe4 ¤   ¤   }
d79371 ¤   }
2467c5 ¤
aedeb7 ¤   return( err );
44efe6 }
faaf5a
930335 /*____________________________________________________________________________
5ef346 ¤   Wrap a PGP encrypted message block with PGP mime headers.
f967c5 ¤
2140c9 ¤   The output is suitable for a mailer.
4af7f7 ____________________________________________________________________________*/
ae33d7 ¤   long
09e700 WrapWithEncryptedPGPMIME(
f7888f ¤   const char*¤¤   ¤   inputfile,
1b29c0 ¤   const char*¤¤   ¤   outputfile,
4b0405 ¤   const char *¤   ¤   delimiter¤  // does not include the "--" part
ef27e6 ¤   )
37bb36 {
2b859f ¤   HANDLE¤ ¤   hOutput = NULL;
4a8994 ¤   long¤   ¤   err¤= 0;
--376a 00045b27d1f401101cc Page 4 of TranslatorUtils.c
2a67c5 ¤
67e3c1 ¤   // create and open the output file
055c8e ¤   hOutput = CreateFile(¤  outputfile,
257194 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GENERIC_WRITE|GENERIC_READ,
324ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
025d0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
6e3e31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CREATE_ALWAYS,·
cf6acc ¤   ¤   ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,·
7f41db ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
b8af5a
d5af5a
c94f1d ¤   // did we successfully open the file
12180f ¤   if ( INVALID_HANDLE_VALUE != hOutput)
6bc7a1 ¤   {
f593a6 ¤   ¤   char¤   buffer[ 1024 ];
64597a ¤   ¤   DWORD¤  count;
f01b52 ¤   ¤
d8c7d8 ¤   ¤   const char¤ kEncryptedMIMEHeaderTemplate[] =
92a76b ¤   ¤   "Mime-Version: 1.0\r\n"
c8b179 ¤   ¤   "Content-Type: multipart/encrypted; boundary="
b4e905 ¤   ¤   "\"%s\"; protocol=\"application/pgp-encrypted\"; "
796abe ¤   ¤   "PGPFormat=\"PGPMIME-encrypted\"\r\n\r\n"
a26b8d ¤   ¤   "--%s\r\n"
2be073 ¤   ¤   "Content-Type: application/pgp-encrypted\r\n\r\n"
b4375e ¤   ¤   "Version: 1\r\n\r\n"
ee6b8d ¤   ¤   "--%s\r\n"
fdba47 ¤   ¤   "Content-Type: application/octet-stream\r\n\r\n";
e01b52 ¤   ¤
ccee18 ¤   ¤   wsprintf( buffer,kEncryptedMIMEHeaderTemplate,·
94c996 ¤   ¤   ¤   ¤   ¤   delimiter, delimiter, delimiter);
a11b52 ¤   ¤
86fd1d ¤   ¤   count¤  = strlen( buffer );
be1b52 ¤   ¤
499c8f ¤   ¤   if ( WriteFile(hOutput,buffer,count, &count, NULL) )
c75b34 ¤   ¤   {
b49eaf ¤   ¤   ¤   err = CopyInputFileToOutputFile( inputfile, hOutput );
b8af5a
9fef35 ¤   ¤   ¤   if ( ! err )
8df776 ¤   ¤   ¤   {
93ea90 ¤   ¤   ¤   ¤   wsprintf( buffer, ·"\r\n--%s--\r\n", delimiter );
57085f ¤   ¤   ¤   ¤   count = strlen( buffer );
66af5a
a390cc ¤   ¤   ¤   ¤   if(!WriteFile(hOutput, buffer, count, &count, NULL))
1b72c3 ¤   ¤   ¤   ¤   {
0534b8 ¤   ¤   ¤   ¤   ¤   err = 1;
d22613 ¤   ¤   ¤   ¤   }
12a3a6 ¤   ¤   ¤   }
7e0fe4 ¤   ¤   }
8a0e1d ¤   ¤   else
a35b34 ¤   ¤   {
f0b134 ¤   ¤   ¤   err = 1;
710fe4 ¤   ¤   }
e51b52 ¤   ¤
87ff22 ¤   ¤   CloseHandle( hOutput );
309371 ¤   }
1867c5 ¤
85deb7 ¤   return( err );
e8efe6 }
e1af5a
4baf5a
cf33d7 ¤   long
cdb645 WrapWithSignedPGPMIME(
e3818a ¤   const char *¤   ¤   inputfile,
ee7a6b ¤   const char *¤   ¤   sigfile,
b37e64 ¤   const char *¤   ¤   outputfile,
ff05bb ¤   const char *¤   ¤   delimiter,
f38a36 ¤   unsigned long¤  ¤   hash)
86bb36 {
53859f ¤   HANDLE¤ ¤   hOutput = NULL;
688994 ¤   long¤   ¤   err¤= 0;
20af5a
45e3c1 ¤   // create and open the output file
--bd45 0006638c84f401101cc Page 5 of TranslatorUtils.c
a95c8e ¤   hOutput = CreateFile(¤  outputfile,
837194 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GENERIC_WRITE|GENERIC_READ,
614ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
875d0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
a43e31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CREATE_ALWAYS,·
2d6acc ¤   ¤   ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,·
a941db ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
eaaf5a
baaf5a
1aaf5a
e543ad ¤   // did we successfully open the files
eaa477 ¤   if(¤( INVALID_HANDLE_VALUE != hOutput ) )
94c7a1 ¤   {
5993a6 ¤   ¤   char¤   buffer[ 1024 ];
8a597a ¤   ¤   DWORD¤  count;
7d1b63 ¤   ¤   const char¤ kMessageIntegrityCheckMD5[] = "pgp-md5";
482f72 ¤   ¤   const char¤ kMessageIntegrityCheckSHA1[] = "pgp-sha1";
1a07f6 ¤   ¤   const char¤ kSignedMIMEHeaderTemplate[] =
ce2c97 ¤   ¤   ¤   "Mime-Version: 1.0\r\n"
16f085 ¤   ¤   ¤   "Content-Type: multipart/signed; boundary="
db1b93 ¤   ¤   ¤   "\"%s\""
507508 ¤   ¤   ¤   "; micalg=%s; protocol=\"application/pgp-signature\"; "
07c081 ¤   ¤   ¤   "PGPFormat=\"PGPMIME-signed\""
6c63fc ¤   ¤   ¤   "\r\n\r\n"
af2552 ¤   ¤   ¤   "--%s\r\n";
b067c5 ¤
3b69c1 ¤   ¤   wsprintf(¤  buffer,·
470501 ¤   ¤   ¤   ¤   ¤   kSignedMIMEHeaderTemplate,·
dc354a ¤   ¤   ¤   ¤   ¤   delimiter,·
e19ba1 ¤   ¤   ¤   ¤   ¤   (hash == kPGPHashAlgorithm_MD5 ?·
71156a ¤   ¤   ¤   ¤   ¤   kMessageIntegrityCheckMD5 : kMessageIntegrityCheckSHA1),·
dce31d ¤   ¤   ¤   ¤   ¤   delimiter );
fe87c7 ¤   ¤   ¤
4fdbc2 ¤   ¤   count = strlen( buffer );
adaf5a
b19c8f ¤   ¤   if ( WriteFile(hOutput,buffer,count, &count, NULL) )
735b34 ¤   ¤   {
2b9eaf ¤   ¤   ¤   err = CopyInputFileToOutputFile( inputfile, hOutput );
66af5a
c7ef35 ¤   ¤   ¤   if ( ! err )
4cf776 ¤   ¤   ¤   {
ac1e42 ¤   ¤   ¤   ¤   const char kSignedDividerTemplate[] =
5fd8ca ¤   ¤   ¤   ¤   "\r\n--%s\r\nContent-Type: application/pgp-signature\r\n\r\n";
16af5a
823561 ¤   ¤   ¤   ¤   wsprintf( buffer, kSignedDividerTemplate, delimiter );
4e085f ¤   ¤   ¤   ¤   count = strlen( buffer );
4caf5a
a890cc ¤   ¤   ¤   ¤   if(!WriteFile(hOutput, buffer, count, &count, NULL))
1872c3 ¤   ¤   ¤   ¤   {
0934b8 ¤   ¤   ¤   ¤   ¤   err = 1;
1e2613 ¤   ¤   ¤   ¤   }
d0fa07 ¤   ¤   ¤   ¤   else
3a72c3 ¤   ¤   ¤   ¤   {
a41e0a ¤   ¤   ¤   ¤   ¤   err = CopyInputFileToOutputFile( sigfile, hOutput );
e0af5a
3d48c0 ¤   ¤   ¤   ¤   ¤   if( ! err )
fb4859 ¤   ¤   ¤   ¤   ¤   {
8ee905 ¤   ¤   ¤   ¤   ¤   ¤   wsprintf( buffer, ·"\r\n--%s--\r\n", delimiter );
643e3f ¤   ¤   ¤   ¤   ¤   ¤   count¤  = strlen( buffer );
1daf5a
fc0a60 ¤   ¤   ¤   ¤   ¤   ¤   if(!WriteFile(hOutput, buffer, count, &count, NULL))
3b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
a6b286 ¤   ¤   ¤   ¤   ¤   ¤   ¤   err = 1;
9fdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
fb1c89 ¤   ¤   ¤   ¤   ¤   }
c52613 ¤   ¤   ¤   ¤   }
e0a3a6 ¤   ¤   ¤   }
c40fe4 ¤   ¤   }
5f0e1d ¤   ¤   else
525b34 ¤   ¤   {
92b134 ¤   ¤   ¤   err = 1;
660fe4 ¤   ¤   }
--0c79 000fec3bc17401101cc Page 6 of TranslatorUtils.c
f11b52 ¤   ¤
e8ff22 ¤   ¤   CloseHandle( hOutput );
d09371 ¤   }
9e67c5 ¤
99deb7 ¤   return( err );
8aefe6 }
82af5a
cdaf5a
f86d52 ¤   void
4d69e0 GetUniqueMIMEDelimiter( char * delimiter )
b8bb36 {
d4d7f2 ¤   static BOOL bSeeded = FALSE;
19a4b4 ¤   const char szPGPmimePlugin[] = "=====_Eudora-PGP-Plugin";
9baf5a
7e33cd ¤   assert(delimiter);
b7af5a
15c513 ¤   if( !bSeeded)
45c7a1 ¤   {
62adeb ¤   ¤   srand( (unsigned)time( NULL ) );
8ef25b ¤   ¤   bSeeded = TRUE;
b39371 ¤   }
66af5a
105bd3 ¤   wsprintf(delimiter, "%s%d==_",
e826f1 ¤   ¤   ¤   ¤   ¤   ¤   szPGPmimePlugin,
f8763e ¤   ¤   ¤   ¤   ¤   ¤   rand());
98efe6 }
e0af5a
31b086 long CopyInputFileToOutputFile(const char* szInputFile,·
7aeecf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···HANDLE hOutputFile)
4abb36 {
fcd183 ¤   long err = 0;
21c33e ¤   HANDLE hInputFile = NULL;
a3af5a
36af5a
5e552b ¤   // open the input file
045d6b ¤   hInputFile = CreateFile(¤   szInputFile,
509d04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GENERIC_READ,
e93bb2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FILE_SHARE_READ,·
041cf9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
899ba8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   OPEN_EXISTING,·
413f60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,·
610028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
baaf5a
684f1d ¤   // did we successfully open the file
35a7f9 ¤   if ( INVALID_HANDLE_VALUE != hInputFile)
d3c7a1 ¤   {
7ec6f3 ¤   ¤   void* buffer = NULL;
daefcc ¤   ¤   DWORD dwFileSize = 0;
55af5a
92ee6d ¤   ¤   // let's find out how much data there is to copy
608f0b ¤   ¤   dwFileSize = GetFileSize(hInputFile, NULL);
33af5a
aff974 ¤   ¤   if( dwFileSize != 0xffffffff) // if there was no error
5c5b34 ¤   ¤   {
8ee196 ¤   ¤   ¤   buffer = malloc( dwFileSize + 1);
f1af5a
5946e8 ¤   ¤   ¤   if(buffer)
56f776 ¤   ¤   ¤   {
6ed260 ¤   ¤   ¤   ¤   // read in the data from the input file
a45c70 ¤   ¤   ¤   ¤   if( ReadFile(¤  hInputFile,·
d89eb7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   buffer,·
35e8d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   dwFileSize,
7b9111 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwFileSize,·
94a778 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL) )
b872c3 ¤   ¤   ¤   ¤   {
37c1dc ¤   ¤   ¤   ¤   ¤   // write it to the current position of the ouput file
c6c69d ¤   ¤   ¤   ¤   ¤   if(!WriteFile(¤ hOutputFile,·
4e980f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   buffer,·
7cb03d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   dwFileSize,·
45de2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwFileSize,·
19a845 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL))
fe4859 ¤   ¤   ¤   ¤   ¤   {
--aa10 0000779f234401101cc Page 7 of TranslatorUtils.c
098fee ¤   ¤   ¤   ¤   ¤   ¤   err = 1;
511c89 ¤   ¤   ¤   ¤   ¤   }
992613 ¤   ¤   ¤   ¤   }
4efa07 ¤   ¤   ¤   ¤   else
cd72c3 ¤   ¤   ¤   ¤   {
5b34b8 ¤   ¤   ¤   ¤   ¤   err = 1;
d42613 ¤   ¤   ¤   ¤   }
a8af5a
e4a1c4 ¤   ¤   ¤   ¤   // clean up
0ef336 ¤   ¤   ¤   ¤   free(buffer);
19a3a6 ¤   ¤   ¤   }
8f0fe4 ¤   ¤   }
d8af5a
c02d55 ¤   ¤   // clean up
2e9c67 ¤   ¤   CloseHandle(hInputFile);
129371 ¤   }
07af5a
e35ea8 ¤   return err;
d7efe6 }
b6af5a
f50049 void RecreateOriginalMessageFile(const char* szInputFile,·
b0ecff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·const char* szOutputFile)
63bb36 {
4e91bc ¤   char szTempFile[MAX_PATH];
04eeb1 ¤   HANDLE hTemp;
0f8f08 ¤   DWORD InputFileSize = 0;
71cf3d ¤   char* InputBuffer = NULL;
091a0e ¤   DWORD encryptedBlockStart = 0;
5632d3 ¤   DWORD encryptedBlockSize = 0;
1e6d85 ¤   BOOL Success = FALSE;
6eaf5a
9f0e4c ¤   strcpy(szTempFile, szOutputFile);
6f4155 ¤   strcat(szTempFile, ".tmp");
a8af5a
8e271d ¤   hTemp = CreateFile(¤¤   szTempFile,
ac7194 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GENERIC_WRITE|GENERIC_READ,
4d4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
d65d0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
fe3e31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CREATE_ALWAYS,·
ef6acc ¤   ¤   ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,·
7341db ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
20af5a
17af5a
acaf5a
a54f1d ¤   // did we successfully open the file
5c7619 ¤   if(¤( INVALID_HANDLE_VALUE != hTemp ) )
9ec7a1 ¤   {
066051 ¤   ¤   InputBuffer = MapFile(szInputFile, &InputFileSize);
43af5a
cddf1a ¤   ¤   if(InputBuffer)
4a5b34 ¤   ¤   {
00048a ¤   ¤   ¤   if( FindEncryptedBlock((const void *)InputBuffer,·
fd7789 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   InputFileSize,·
8c1b9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &encryptedBlockStart,
cc734a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &encryptedBlockSize) )
4ef776 ¤   ¤   ¤   {
6e319d ¤   ¤   ¤   ¤   DWORD count = encryptedBlockStart;
63af5a
eb66e2 ¤   ¤   ¤   ¤   if(WriteFile(hTemp, InputBuffer, count, &count, NULL))
fe72c3 ¤   ¤   ¤   ¤   {
db68a6 ¤   ¤   ¤   ¤   ¤   CopyInputFileToOutputFile(szOutputFile, hTemp);
29af5a
8e6438 ¤   ¤   ¤   ¤   ¤   count = InputFileSize -·
9ccda0 ¤   ¤   ¤   ¤   ¤   ¤   ( (InputBuffer + encryptedBlockStart +·
c4d1db ¤   ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockSize) - InputBuffer);
7baf5a
3ae8f4 ¤   ¤   ¤   ¤   ¤   if(WriteFile(hTemp,·
c07b8b ¤   ¤   ¤   ¤   ¤   ¤   (InputBuffer + encryptedBlockStart +·
877fb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockSize),·
18362c ¤   ¤   ¤   ¤   ¤   ¤   count,·
bf3aff ¤   ¤   ¤   ¤   ¤   ¤   &count,·
076b85 ¤   ¤   ¤   ¤   ¤   ¤   NULL))
--f96a 0006381c7f9401101cc Page 8 of TranslatorUtils.c
e04859 ¤   ¤   ¤   ¤   ¤   {
d27227 ¤   ¤   ¤   ¤   ¤   ¤   Success = TRUE;
611c89 ¤   ¤   ¤   ¤   ¤   }
c62613 ¤   ¤   ¤   ¤   }
eea3a6 ¤   ¤   ¤   }
2eaf5a
6983c9 ¤   ¤   ¤   free(InputBuffer);
8b0fe4 ¤   ¤   }
25af5a
e24b86 ¤   ¤   CloseHandle(hTemp);
05af5a
22faa3 ¤   ¤   if(Success)
555b34 ¤   ¤   {
cfe7cf ¤   ¤   ¤   CopyFile(szTempFile, szOutputFile, FALSE);·
7a0fe4 ¤   ¤   }
40af5a
6a365b ¤   ¤   DeleteFile(szTempFile);
0c9371 ¤   }
a3efe6 }
2faf5a
c4717a char* RecreateOriginalMessageBuffer(const char* pInputBuffer,·
5976d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char* pOutputBuffer)
b8bb36 {
9b1a0e ¤   DWORD encryptedBlockStart = 0;
c732d3 ¤   DWORD encryptedBlockSize = 0;
84f540 ¤   char* pTempMem = NULL;
af54b6 ¤   DWORD dwTempMemSize = 0;
90af5a
093ecf ¤   dwTempMemSize = ( strlen(pInputBuffer) > strlen(pOutputBuffer) )·
3894a1 ¤   ¤   ¤   ¤   ? strlen(pInputBuffer) : strlen(pOutputBuffer);
94af5a
813b56 ¤   if(pInputBuffer)
30c7a1 ¤   {
23a307 ¤   ¤   if( FindEncryptedBlock((const void *)pInputBuffer,·
76b623 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen(pInputBuffer),·
0e7c89 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &encryptedBlockStart,·
957471 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &encryptedBlockSize) )
1e5b34 ¤   ¤   {
e1e92f ¤   ¤   ¤   DWORD count = encryptedBlockStart;
c187c7 ¤   ¤   ¤
88fc9c ¤   ¤   ¤   dwTempMemSize += encryptedBlockSize;
0c67c5 ¤
b14853 ¤   ¤   ¤   pTempMem = (char*)malloc(dwTempMemSize);
2daf5a
4b2338 ¤   ¤   ¤   if( pTempMem )
5ff776 ¤   ¤   ¤   {
f36125 ¤   ¤   ¤   ¤   memset(pTempMem, 0x00, dwTempMemSize);
1aaf5a
c9b50f ¤   ¤   ¤   ¤   memcpy(pTempMem, pInputBuffer, count);
83af5a
3d5e33 ¤   ¤   ¤   ¤   strcat(pTempMem, pOutputBuffer);
5daf5a
74280b ¤   ¤   ¤   ¤   count = strlen(pInputBuffer) -·
025291 ¤   ¤   ¤   ¤   ¤   ( (pInputBuffer + encryptedBlockStart +·
092522 ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockSize) - pInputBuffer);
2baf5a
9118ba ¤   ¤   ¤   ¤   strcat(¤pTempMem,·
c117df ¤   ¤   ¤   ¤   ¤   ¤   (pInputBuffer + encryptedBlockStart +·
6f6361 ¤   ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockSize));
80a3a6 ¤   ¤   ¤   }
670fe4 ¤   ¤   }
469371 ¤   }
92af5a
7d9a83 ¤   return pTempMem;
18efe6 }
f2af5a
5983a1 void AddCRLFToEOF(const char* szInputFile)
37bb36 {
d64f13 ¤   HANDLE¤ ¤   hInputFile = NULL;
faaf5a
12e3c1 ¤   // create and open the output file
635d6b ¤   hInputFile = CreateFile(¤   szInputFile,
--4b33 001556f7e14401101cc Page 9 of TranslatorUtils.c
fafec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GENERIC_WRITE|GENERIC_READ,
8fc118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
f61cf9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
049ba8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   OPEN_EXISTING,·
1b3f60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,·
e00028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
8aaf5a
c04f1d ¤   // did we successfully open the file
4ca7f9 ¤   if ( INVALID_HANDLE_VALUE != hInputFile)
0dc7a1 ¤   {
8c75ff ¤   ¤   const char CRLF[] = "\r\n";
f97c69 ¤   ¤   DWORD count = strlen(CRLF);
dbaf5a
ca511e ¤   ¤   SetFilePointer(hInputFile, 0, NULL, FILE_END);
6baf5a
11ae4d ¤   ¤   WriteFile(hInputFile, CRLF, count, &count, NULL);
ebaf5a
322d55 ¤   ¤   // clean up
399c67 ¤   ¤   CloseHandle(hInputFile);
a39371 ¤   }
6aefe6 }
55af5a
--7f62 00044da7906401101cd Page 1 of TranslatorUtils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
9e0e35 ¤   TranslatorUtils.h,v 1.4 1997/10/22 23:05:59 elrod Exp
53f7f7 ____________________________________________________________________________*/
60af5a
bd81e9 #ifndef Included_TranslatorUtils_h¤ /* [ */
b8d5b9 #define Included_TranslatorUtils_h
38af5a
36af5a
10e127 #define DELIMITERLENGTH 256
28af5a
215e47 #include "emssdk/ems-win.h"
03af5a
631bea unsigned long CreateRecipientList(
82d3b8 ¤   char** EudoraAddresses,·
b4cca5 ¤   char*** Recipients
a4823f ¤   );
f6af5a
e6c823 void·
49561e FreeRecipientList(
06fa81 ¤   char** Recipients,·
6a1ee3 ¤   unsigned long ·numRecipients
5a823f ¤   );
f5af5a
d94819 long ConvertFileToEncryptedPGPMIME(
547654 ¤   const char*¤¤   ¤   file,
910819 ¤   char *¤ ¤   ¤   ¤   delimiter·
ff823f ¤   );
f0af5a
3ad723 long ConvertFileToSignedPGPMIME(
527654 ¤   const char*¤¤   ¤   file,
f9b57a ¤   const char*¤¤   ¤   sigfile,·
7ad382 ¤   long¤   ¤   ¤   ¤   hash,
b371b4 ¤   char*¤  ¤   ¤   ¤   delimiter·
c7823f ¤   );
b7af5a
ac1603 long WrapWithEncryptedPGPMIME(
5b888f ¤   const char*¤¤   ¤   inputfile,
8829c0 ¤   const char*¤¤   ¤   outputfile,
e50405 ¤   const char *¤   ¤   delimiter¤  // does not include the "--" part
fd823f ¤   );
82af5a
1f2262 long WrapWithSignedPGPMIME(
59818a ¤   const char *¤   ¤   inputfile,
dc7a6b ¤   const char *¤   ¤   sigfile,
057e64 ¤   const char *¤   ¤   outputfile,
490aa3 ¤   const char *¤   ¤   delimiter, // does not include the "--" part
c75dfd ¤   unsigned long¤  ¤   hash
20823f ¤   );
3baf5a
c2f021 void GetUniqueMIMEDelimiter(·
1a3015 ¤   char * delimiter·
04823f ¤   );
07af5a
1bd268 long CopyInputFileToOutputFile(
ecc1eb ¤   const char* szInputFile,·
385045 ¤   HANDLE hOutputFile
d3823f ¤   );
33af5a
1daf5a
bdf3fe void AddCRLFToEOF(
063cca ¤   const char* szInputFile
fc823f ¤   );
58af5a
1659b2 void RecreateOriginalMessageFile(
49c1eb ¤   const char* szInputFile,·
dd1a3b ¤   const char* szOutputFile
44823f ¤   );
--3b9f 0016613086b401101cd Page 2 of TranslatorUtils.h
e0af5a
b89217 char* RecreateOriginalMessageBuffer(
29e61a ¤   const char* pInputBuffer,·
0bb2ae ¤   const char* pOutputBuffer
20823f ¤   );
ebaf5a
26bed2 #endif /* ] Included_TranslatorUtils_h */
54af5a
b3af5a
bd7e4d /*__Editor_settings____
70af5a
f24126 ¤   Local Variables:
ea7b17 ¤   tab-width: 4
580e6c ¤   End:
ef5f8c ¤   vi: ts=4 sw=4
fb9e9b ¤   vim: si
15d062 _____________________*/
66af5a
--c3a7 000dcd118bc401101ce Page 1 of Translators.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8f534c ¤   $Id: Translators.c,v 1.25.2.3.2.1 1998/11/12 03:11:39 heller Exp $
cef7f7 ____________________________________________________________________________*/
1daf5a
c69b16 // System Headers
605655 #include <windows.h>
053d0b #include <windowsx.h>
7bbb5f #include <assert.h>
68af5a
1eaf5a
235582 // PGPsdk Headers
a2e2ff #include "pgpConfig.h"
eca076 #include "pgpKeys.h"
fc2f8d #include "pgpErrors.h"
044919 #include "pgpUtilities.h"
70ec82 #include "pgpTLS.h"
a391b9 #include "pgpSDKPrefs.h"
f9af5a
ff4f9a // Eudora Headers
242ba1 #include "emssdk/Mimetype.h"
5aaf5a
ac2062 // Shared Headers
ae5ab2 #include "PGPcl.h"
78af5a
fde8e0 // Project Headers
e60cf9 #include "PGPPlug.h"
f1e6f3 #include "TranslatorIDs.h"
13b04c #include "EncryptSign.h"
5d53a7 #include "DecryptVerify.h"
ab05f4 #include "AddKey.h"
78bbc6 #include "TranslatorUtils.h"
6ffd0e #include "DisplayMessage.h"
3c8031 #include "resource.h"
9f2bcf #include "MyMIMEUtils.h"
8bcc89 #include "Prefs.h"
35af5a
e7482b // Global Variables
f36ba0 extern HINSTANCE¤   ¤   g_hinst;
3f1c13 extern PGPContextRef¤   g_pgpContext;
1870a4 extern PGPtlsContextRef g_tlsContext;
76356f extern HWND¤¤   ¤   ¤   g_hwndEudoraMainWindow;
b1af5a
c9af5a
69fbc6 PluginError CanTranslateMIMEType(long transContext,
84cbf3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·emsMIMEtypeP mimeType,
b05042 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·const char* type,·
d99b4e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·const char* subType);
03af5a
dbaf5a
a0af5a
9b4b3d PluginError CanPerformTranslation(
9ba485 ¤   short trans_id,·
694b15 ¤   emsMIMEtypeP in_mime,·
80ef4f ¤   long context
985b71 )
debb36 {
09773b ¤   PluginError err = EMSR_CANT_TRANS;
69af5a
421419 ¤   if ( in_mime )
185cb4 ¤   {¤  ¤   ¤
3fd9a5 ¤   ¤   switch(trans_id)
235b34 ¤   ¤   {
3c0d8a ¤   ¤   ¤   // manual (aka On-Demand) translators
790c18 ¤   ¤   ¤   case kManualEncryptSignTranslatorID:
b3d751 ¤   ¤   ¤   case kManualDecryptVerifyTranslatorID:
20f776 ¤   ¤   ¤   {
dcbbcf ¤   ¤   ¤   ¤   if( in_mime && match_mime_type(in_mime, "text", "plain") )
--4a72 000d4e8742f401101ce Page 2 of Translators.c
d072c3 ¤   ¤   ¤   ¤   {
dc049e ¤   ¤   ¤   ¤   ¤   if ( ( context & EMSF_ON_REQUEST ) != 0 )
5a4859 ¤   ¤   ¤   ¤   ¤   {
141537 ¤   ¤   ¤   ¤   ¤   ¤   err = EMSR_NOW;
f91c89 ¤   ¤   ¤   ¤   ¤   }
0a2613 ¤   ¤   ¤   ¤   }
99f622 ¤   ¤   ¤   ¤   break;
fba3a6 ¤   ¤   ¤   }
8aaf5a
90349a ¤   ¤   ¤   // Mime Translators
e4fb54 ¤   ¤   ¤   case kEncryptTranslatorID:
337dbe ¤   ¤   ¤   case kSignTranslatorID:
d56fee ¤   ¤   ¤   case kEncryptAndSignTranslatorID:
96f776 ¤   ¤   ¤   {
cb5b9e ¤   ¤   ¤   ¤   err = EMSR_NOW;
86f622 ¤   ¤   ¤   ¤   break;
15a3a6 ¤   ¤   ¤   }
deaf5a
206f05 ¤   ¤   ¤   case kDecryptTranslatorID:
3df776 ¤   ¤   ¤   {
112e23 ¤   ¤   ¤   ¤   err = CanTranslateMIMEType(¤context,·
d7e04f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_mime,·
966817 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "multipart",·
796535 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "encrypted");
c6af5a
63f622 ¤   ¤   ¤   ¤   break;
fda3a6 ¤   ¤   ¤   }
b1af5a
61193f ¤   ¤   ¤   case kVerifyTranslatorID:
bbf776 ¤   ¤   ¤   {
0b2e23 ¤   ¤   ¤   ¤   err = CanTranslateMIMEType(¤context,·
ffe04f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_mime,·
5f6817 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "multipart",·
8d42aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "signed");
a1af5a
fdf622 ¤   ¤   ¤   ¤   break;
e8a3a6 ¤   ¤   ¤   }
08ec70 ¤   ¤   }¤  ¤
969371 ¤   }
59af5a
895ea8 ¤   return err;
eeefe6 }
f0af5a
66c2a7 PluginError PerformTranslation(
b1a485 ¤   short trans_id,·
7f750e ¤   char* in_file,·
fdfa41 ¤   char* out_file,·
609823 ¤   char** addresses,·
a530ec ¤   emsMIMEtypeP ·in_mime,
a219f9 ¤   emsMIMEtypeP* out_mime
955b71 )
c5bb36 {
d2bea5 ¤   PluginError pluginReturn¤   ¤   ¤   = EMSR_UNKNOWN_FAIL;
d124fe ¤   BOOL¤   ¤   bSign¤  ¤   ¤   ¤   ¤   = FALSE;
23304f ¤   PGPError¤   error¤  ¤   ¤   ¤   ¤   = 0;
746d05 ¤   PGPSize¤¤   mimeBodyOffset¤ ¤   ¤   = 0;
1538c0 ¤   char¤   ¤   szExe[256];
1f7895 ¤   char¤   ¤   szDll[256];
e5af5a
5d1784 ¤   assert(in_file);
e90ab8 ¤   assert(out_file);
37af5a
7ff1e6 ¤   LoadString(g_hinst, IDS_EXE, szExe, sizeof(szExe));
7c9ff8 ¤   LoadString(g_hinst, IDS_DLL, szDll, sizeof(szDll));
29af5a
39dcaa ¤   switch( trans_id )
2bc7a1 ¤   {
9fbaa7 ¤   ¤   case kEncryptTranslatorID:
46f642 ¤   ¤   case kSignTranslatorID:
a7562b ¤   ¤   case kEncryptAndSignTranslatorID:
d35b34 ¤   ¤   {
d4027f ¤   ¤   ¤   char** RecipientList = NULL;
--85f5 0000f3c7810401101ce Page 3 of Translators.c
d4793c ¤   ¤   ¤   unsigned long numRecipients = 0;
2fb023 ¤   ¤   ¤   PGPOptionListRef pgpOptions = NULL;
a03415 ¤   ¤   ¤   PGPOptionListRef signOptions = NULL;
497b29 ¤   ¤   ¤   char mimeSeparator[kPGPMimeSeparatorSize];
de48c2 ¤   ¤   ¤   PRECIPIENTDIALOGSTRUCT prds = NULL;¤
761b52 ¤   ¤
17b7cf ¤   ¤   ¤   // allocate a recipient dialog structure
e26188 ¤   ¤   ¤   prds = (PRECIPIENTDIALOGSTRUCT)·
60e941 ¤   ¤   ¤   ¤   ¤   calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);
bbaf5a
a5bd2e ¤   ¤   ¤   if(prds)
fbf776 ¤   ¤   ¤   {
731dcd ¤   ¤   ¤   ¤   char szTitle[256] = {0x00};¤¤   // title for recipient dialog
14d564 ¤   ¤   ¤   ¤   UINT recipientReturn = FALSE;¤  // recipient dialog result
63af5a
4e7564 ¤   ¤   ¤   ¤   error = PGPsdkLoadDefaultPrefs(g_pgpContext);
995a21 ¤   ¤   ¤   ¤   if (IsPGPError(error))
7872c3 ¤   ¤   ¤   ¤   {
e0535a ¤   ¤   ¤   ¤   ¤   PGPclEncDecErrorBox(g_hwndEudoraMainWindow, error);
25eb2f ¤   ¤   ¤   ¤   ¤   return EMSR_UNKNOWN_FAIL;
712613 ¤   ¤   ¤   ¤   }
83af5a
216be9 ¤   ¤   ¤   ¤   error = PGPOpenDefaultKeyRings(g_pgpContext,·
e2275b ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPKeyRingOpenFlags)0,·
d0fe38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(prds->OriginalKeySetRef));
a0af5a
8f5a21 ¤   ¤   ¤   ¤   if (IsPGPError(error))
c972c3 ¤   ¤   ¤   ¤   {
f6535a ¤   ¤   ¤   ¤   ¤   PGPclEncDecErrorBox(g_hwndEudoraMainWindow, error);
0beb2f ¤   ¤   ¤   ¤   ¤   return EMSR_UNKNOWN_FAIL;
952613 ¤   ¤   ¤   ¤   }
14af5a
60cf60 ¤   ¤   ¤   ¤   if ((trans_id == kEncryptTranslatorID) ||
2fb749 ¤   ¤   ¤   ¤   ¤   (trans_id == kEncryptAndSignTranslatorID))
9572c3 ¤   ¤   ¤   ¤   {
45b692 ¤   ¤   ¤   ¤   ¤   if(addresses) // do we have addresses to pass along
c14859 ¤   ¤   ¤   ¤   ¤   {
f28871 ¤   ¤   ¤   ¤   ¤   ¤   numRecipients = CreateRecipientList(addresses,·
a9b089 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &RecipientList);
7f1c89 ¤   ¤   ¤   ¤   ¤   }
73af5a
2d953b ¤   ¤   ¤   ¤   ¤   LoadString(GetModuleHandle("PGPplugin.dll"),·
a9ad72 ¤   ¤   ¤   ¤   ¤   ¤   IDS_TITLE_RECIPIENTDIALOG, szTitle, sizeof(szTitle));
e9af5a
b2835e ¤   ¤   ¤   ¤   ¤   prds->Context¤  ¤   ¤   = g_pgpContext;
910fc0 ¤   ¤   ¤   ¤   ¤   prds->tlsContext¤   ¤   = g_tlsContext;
9eb0cd ¤   ¤   ¤   ¤   ¤   prds->Version¤  ¤   ¤   = CurrentPGPrecipVersion;
5490b6 ¤   ¤   ¤   ¤   ¤   prds->hwndParent¤   ¤   = g_hwndEudoraMainWindow;¤  ¤   ¤
fd2c46 ¤   ¤   ¤   ¤   ¤   prds->szTitle¤  ¤   ¤   = szTitle;
9b7156 ¤   ¤   ¤   ¤   ¤   prds->dwOptions¤¤   ¤   = PGPCL_ASCIIARMOR;¤
e087c7 ¤   ¤   ¤
fc7e94 ¤   ¤   ¤   ¤   ¤   prds->dwDisableFlags¤   = PGPCL_DISABLE_WIPEORIG |
b4c7a1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPCL_DISABLE_ASCIIARMOR;
7caf5a
a58e3d ¤   ¤   ¤   ¤   ¤   prds->dwNumRecipients¤  = numRecipients;¤
43840e ¤   ¤   ¤   ¤   ¤   prds->szRecipientArray¤ = RecipientList;
7caf5a
0075b5 ¤   ¤   ¤   ¤   ¤   // If shift is pressed, force the dialog to pop.
e45174 ¤   ¤   ¤   ¤   ¤   if (GetAsyncKeyState( VK_CONTROL) & 0x8000)
17e49f ¤   ¤   ¤   ¤   ¤   ¤   prds->dwDisableFlags|=PGPCL_DISABLE_AUTOMODE;
b0af5a
428a46 ¤   ¤   ¤   ¤   ¤   // See who we wish to encrypt this to
545245 ¤   ¤   ¤   ¤   ¤   recipientReturn = PGPclRecipientDialog( prds );
e82b85 ¤   ¤   ¤   ¤
5f2357 ¤   ¤   ¤   ¤   ¤   if (prds->AddedKeys != NULL)
f04859 ¤   ¤   ¤   ¤   ¤   {
7ffc22 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 numKeys;
90ae30 ¤   ¤   ¤   ¤   ¤
ce14b4 ¤   ¤   ¤   ¤   ¤   ¤   PGPCountKeys(prds->AddedKeys, &numKeys);
8e44a9 ¤   ¤   ¤   ¤   ¤   ¤   if (numKeys > 0)
64b25a ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys(g_pgpContext, g_tlsContext,·
0f781f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_hwndEudoraMainWindow, prds->AddedKeys,·
--c8ce 0009523dbab401101ce Page 4 of Translators.c
9d0028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
4eae30 ¤   ¤   ¤   ¤   ¤
0e1e83 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->AddedKeys);
6301e4 ¤   ¤   ¤   ¤   ¤   ¤   prds->AddedKeys = NULL;
3b1c89 ¤   ¤   ¤   ¤   ¤   }
50af5a
901b23 ¤   ¤   ¤   ¤   ¤   if (!recipientReturn)
414859 ¤   ¤   ¤   ¤   ¤   {
0cfdd7 ¤   ¤   ¤   ¤   ¤   ¤   if (RecipientList)
b9dd59 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreeRecipientList(RecipientList, numRecipients);
c52aab ¤   ¤   ¤   ¤   ¤   ¤   if (prds->SelectedKeySetRef != NULL)
1becd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
63a5c9 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
4e7d3b ¤   ¤   ¤   ¤   ¤   ¤   free(prds);
25a411 ¤   ¤   ¤   ¤   ¤   ¤   return EMSR_UNKNOWN_FAIL;
891c89 ¤   ¤   ¤   ¤   ¤   }
da2613 ¤   ¤   ¤   ¤   }
eaaf5a
0612ed ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
ea72c3 ¤   ¤   ¤   ¤   {
4cbb4a ¤   ¤   ¤   ¤   ¤   error = PGPBuildOptionList(g_pgpContext, &pgpOptions,
c72836 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOOutputLineEndType(g_pgpContext,·
55e3f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPLineEnd_CRLF),
35c4e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPGPMIMEEncoding(g_pgpContext,·
7a4ebd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE,·
371f7a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mimeBodyOffset,·
2e5536 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mimeSeparator), ····
7ebd10 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(g_pgpContext) );
0a2613 ¤   ¤   ¤   ¤   }
ebaf5a
6db78c ¤   ¤   ¤   ¤   if(IsntPGPError( error))
0172c3 ¤   ¤   ¤   ¤   {
a24e7d ¤   ¤   ¤   ¤   ¤   error = EncryptSignFile(g_hinst, g_hwndEudoraMainWindow,·
3897d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_pgpContext, g_tlsContext, szExe,·
7fb4fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDll, in_file, prds, pgpOptions,·
e56db6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &signOptions, out_file,·
821ff3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ((trans_id ==·
b60a31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kSignTranslatorID) ? FALSE : TRUE ),
e81ff3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ((trans_id ==·
da07e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kEncryptTranslatorID) ? FALSE : TRUE ),
e9ba28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
80af5a
cf8055 ¤   ¤   ¤   ¤   ¤   PGPFreeOptionList(pgpOptions);
363657 ¤   ¤   ¤   ¤   ¤   PGPFreeOptionList(signOptions);
f82613 ¤   ¤   ¤   ¤   }
1ffa07 ¤   ¤   ¤   ¤   else
8b72c3 ¤   ¤   ¤   ¤   {
771e3a ¤   ¤   ¤   ¤   ¤   PGPclEncDecErrorBox (NULL, error);
262613 ¤   ¤   ¤   ¤   }
3caf5a
7eb268 ¤   ¤   ¤   ¤   if (RecipientList)
d747f5 ¤   ¤   ¤   ¤   ¤   FreeRecipientList(RecipientList, numRecipients);
9a632d ¤   ¤   ¤   ¤   if (prds->SelectedKeySetRef != NULL)
9915a0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
ffee82 ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
7c5b99 ¤   ¤   ¤   ¤   free(prds);
82af5a
1412ed ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
fc72c3 ¤   ¤   ¤   ¤   {
4fb3c8 ¤   ¤   ¤   ¤   ¤   if( out_mime )
1b4859 ¤   ¤   ¤   ¤   ¤   {
739d1a ¤   ¤   ¤   ¤   ¤   ¤   pluginReturn = BuildEncryptedPGPMIMEType(·
3c7001 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   out_mime,·
a07da0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mimeSeparator );
b9af5a
120bcf ¤   ¤   ¤   ¤   ¤   ¤   if(EMSR_OK == pluginReturn)
2b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
2a2e28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pluginReturn = AddMIMEParam(*out_mime,·
14c941 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "PGPFormat",·
9f511b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "PGPMIME-encrypted" );
7fdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
951c89 ¤   ¤   ¤   ¤   ¤   }
--f052 0002336ef95401101ce Page 5 of Translators.c
862613 ¤   ¤   ¤   ¤   }
2ba3a6 ¤   ¤   ¤   }
74af5a
d0cdcb ¤   ¤   ¤   break;
cf0fe4 ¤   ¤   }
1caf5a
172ef6 ¤   ¤   case kDecryptTranslatorID:
13f64c ¤   ¤   case kVerifyTranslatorID:
755b34 ¤   ¤   {
13ea83 ¤   ¤   ¤   char *szTempFile = NULL;
40d3c8 ¤   ¤   ¤   BOOL bDummy;
9eaf5a
79c5ae ¤   ¤   ¤   error = DecryptVerifyFile(g_hinst, g_hwndEudoraMainWindow,·
a7c88e ¤   ¤   ¤   ¤   ¤   ¤   g_pgpContext, g_tlsContext, szExe, szDll, in_file,·
527e07 ¤   ¤   ¤   ¤   ¤   ¤   TRUE, FALSE, &szTempFile, NULL, NULL, &bDummy);
46af5a
ed17f9 ¤   ¤   ¤   if( IsntPGPError(error) )·
eef776 ¤   ¤   ¤   {
192651 ¤   ¤   ¤   ¤   CopyFile(szTempFile, out_file, FALSE);
6e78f2 ¤   ¤   ¤   ¤   DeleteFile(szTempFile);
95af5a
160e91 //¤ ¤   ¤   ¤   AddKeyFile(g_hwndEudoraMainWindow, g_pgpContext,·
b5cd56 //¤ ¤   ¤   ¤   ¤   g_tlsContext, out_file);
5faf5a
5d3fb7 ¤   ¤   ¤   ¤   if( out_mime )
6d72c3 ¤   ¤   ¤   ¤   {
a9b161 ¤   ¤   ¤   ¤   ¤   ParseFileForMIMEType( out_file, out_mime );
632613 ¤   ¤   ¤   ¤   }
6baf5a
93ba1f ¤   ¤   ¤   ¤   pluginReturn = EMSR_OK;
d6a3a6 ¤   ¤   ¤   }
2eaf5a
706591 ¤   ¤   ¤   if (szTempFile != NULL)
9b0608 ¤   ¤   ¤   ¤   PGPFreeData(szTempFile);
c3cdcb ¤   ¤   ¤   break;
5b0fe4 ¤   ¤   }
15af5a
e69371 ¤   }
25af5a
41e082 ¤   return pluginReturn;
daefe6 }
2aaf5a
00af5a
030719 PluginError CanTranslateMIMEType(
df26f7 ¤   long¤   ¤   ¤   ¤   ¤   transContext,
40fa60 ¤   emsMIMEtypeP¤   ¤   ¤   mimeType,
f9cd20 ¤   const char*¤¤   ¤   ¤   type,
de58bc ¤   const char*¤¤   ¤   ¤   subType)
32bb36 {
477a11 ¤   PluginError¤err¤= EMSR_CANT_TRANS;
3d67c5 ¤
6bd3ed ¤   if ( mimeType )
3ec7a1 ¤   {
49400a ¤   ¤   BOOL¤   ¤   haveValidContext;
9ed6e6 ¤   ¤   const long¤ kValidContextMask¤  = EMSF_ON_DISPLAY | EMSF_ON_ARRIVAL;
7b1b52 ¤   ¤
2fa335 ¤   ¤   haveValidContext¤   = ( transContext & kValidContextMask ) != 0;
691b52 ¤   ¤
7210a9 ¤   ¤   if ( haveValidContext )
aa5b34 ¤   ¤   {
df1c35 ¤   ¤   ¤   BOOL¤   haveMatch;
6787c7 ¤   ¤   ¤
ea3c18 ¤   ¤   ¤   haveMatch¤  = match_mime_type( mimeType, type, subType );
7aaf5a
318839 ¤   ¤   ¤   if( haveMatch )
aef776 ¤   ¤   ¤   {
b3d74f ¤   ¤   ¤   ¤   const char* PGPMimeParam = NULL;
d5af5a
8e207c ¤   ¤   ¤   ¤   PGPMimeParam = get_mime_parameter(mimeType, "protocol");
41af5a
04c481 ¤   ¤   ¤   ¤   if(PGPMimeParam &&·
237d44 ¤   ¤   ¤   ¤   ¤   (!strcmp(PGPMimeParam, "application/pgp-encrypted") ||·
--bd74 001c0c2ced1401101ce Page 6 of Translators.c
599fa5 ¤   ¤   ¤   ¤   ¤   !strcmp(PGPMimeParam, "application/pgp-signature") ) )
5372c3 ¤   ¤   ¤   ¤   {
72f292 ¤   ¤   ¤   ¤   ¤   haveMatch = TRUE;
542613 ¤   ¤   ¤   ¤   }
41fa07 ¤   ¤   ¤   ¤   else
5972c3 ¤   ¤   ¤   ¤   {
d6862a ¤   ¤   ¤   ¤   ¤   haveMatch = FALSE;
782613 ¤   ¤   ¤   ¤   }
4da3a6 ¤   ¤   ¤   }
5187c7 ¤   ¤   ¤
6a3435 ¤   ¤   ¤   if ( haveMatch )
59f776 ¤   ¤   ¤   {
58d9ab ¤   ·¤  ¤   ····if( transContext == EMSF_ON_ARRIVAL )
0a0baa ¤   ·¤  ¤   ····{
d928dd ¤   ¤   ···¤ ·······err = EMSR_NOT_NOW;
bb1023 ¤   ¤   ···¤ ···}
659edb ¤   ¤   ···¤ ···else
c344f3 ¤   ¤   ···¤ ···{
6e84f7 ¤   ¤   ···¤¤   ····err = EMSR_NOW;
69b776 ¤   ¤   ···¤¤   }
d2a3a6 ¤   ¤   ¤   }
d50fe4 ¤   ¤   }
8f9371 ¤   }
9c67c5 ¤
a5deb7 ¤   return( err );
c0efe6 }
--da89 0010cf89fd2401101cf Page 1 of Translators.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
46c524 ¤   Translators.h,v 1.3 1997/10/22 23:06:00 elrod Exp
d3f7f7 ____________________________________________________________________________*/
9aaf5a
4a6908 #ifndef Included_Translators_h¤ /* [ */
34536f #define Included_Translators_h
50af5a
c223fb #include "PGPPlugTypes.h"
1aaf5a
db4b3d PluginError CanPerformTranslation(
27a485 ¤   short trans_id,·
c14b15 ¤   emsMIMEtypeP in_mime,·
52ef4f ¤   long context
5d823f ¤   );
b5af5a
32c2a7 PluginError PerformTranslation(
53a485 ¤   short trans_id,·
4a750e ¤   char* in_file,·
c3fa41 ¤   char* out_file,·
7f9823 ¤   char** addresses,·
1630ec ¤   emsMIMEtypeP ·in_mime,
3219f9 ¤   emsMIMEtypeP* out_mime
73823f ¤   );
51af5a
92af5a
48aae4 #endif /* ] Included_Translators_h */
dbaf5a
5daf5a
d57e4d /*__Editor_settings____
8daf5a
934126 ¤   Local Variables:
3f7b17 ¤   tab-width: 4
e50e6c ¤   End:
cf5f8c ¤   vi: ts=4 sw=4
fe9e9b ¤   vim: si
4ed062 _____________________*/
0caf5a
--34ee 0005bd95c05401101d0 Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
c3dbbc // Used by PGPplugin.rc
d4465d //
3e4dd0 #define IDS_WARN_NORECIPIENTS ··········1
a859be #define IDS_WARN_NORECIPIENTSTITLE ·····2
82bf59 #define IDS_TITLE_RECIPIENTDIALOG ······3
b4f1e8 #define IDS_WARN_DECRYPTFAILED ·········4
c4bf25 #define IDS_TITLE_PGPERROR ·············5
60c4d5 #define IDS_SUCCESS_ADDKEY ·············6
ef0f3b #define IDS_TITLE_ADDKEY ···············7
74f13b #define IDS_WARN_ADDKEY ················8
92a493 #define IDS_STRING8 ····················8
0fe60f #define IDS_STRING9 ····················9
660e4a #define IDS_TOOLTIP1 ···················10
7efa5e #define IDS_TOOLTIP2 ···················11
338b72 #define IDS_TOOLTIP3 ···················12
381a67 #define IDS_TOOLTIP4 ···················13
4a0c2b #define IDS_TOOLTIP5 ···················14
a1f83f #define IDS_TOOLTIP6 ···················15
258913 #define IDS_TOOLTIP7 ···················16
43d204 #define IDS_TOOLTIP8 ···················17
843349 #define IDS_PGPPREFSTATUS ··············18
9ad963 #define IDS_PGPABOUTSTATUS ·············19
3da226 #define IDS_PGPKEYSSTATUS ··············20
7eb8af #define IDS_PGPHELPSTATUS ··············21
01e719 #define IDS_PGPGETKEYSTATUS ············22
b49337 #define IDS_PGPDECRYPTSTATUS ···········23
1e2a90 #define IDS_PGPENCRYPTSIGNSTATUS ·······24
95ff60 #define IDS_PGPSIGNSTATUS ··············25
68572b #define IDS_PGPENCRYPTSTATUS ···········26
b90c19 #define IDS_ENCRYPTMENU ················27
fdf8a8 #define IDS_PGPKEYSMENU ················28
553da1 #define IDS_DECRYPTMENU ················29
0c12da #define IDS_CUTMENU ····················30
b2b380 #define IDS_COPYMENU ···················31
6576af #define IDS_HELPFILE ···················32
d9a7cb #define IDS_PGPKEYSEXE ·················33
c12a17 #define IDS_E_LAUNCHPGPKEYS ············34
ba118d #define IDS_E_EXPIRED ··················35
ca427f #define IDS_E_EXPIREDTITLE ·············36
69532e #define IDS_EXE ························37
7381c2 #define IDS_DLL ························38
62ba38 #define IDS_E_SENDMAIL ·················39
d6acff #define IDS_E_SENDMAILTITLE ············40
c35b5c #define IDS_E_OLDVERSION ···············41
224bd4 #define IDI_PGP32 ······················101
fd689b #define IDI_PGP_ENCRYPT ················103
649f37 #define IDI_PGP_DECRYPT ················104
0c3cd6 #define IDI_PGP_ENCRYPT_SIGN ···········105
a1ded3 #define IDI_PGP_SIGN ···················106
88f376 #define IDI_PGP_VERIFY ·················107
313696 #define IDI_PGP_ADDKEY ·················108
aa8ab8 #define IDM_PGPABOUTMENU ···············113
463bdf #define IDM_PGPMENU ····················114
7b66e7 #define IDM_PGPENCRYPTMENU ·············114
0a9cab #define IDM_PGPDECRYPTMENU ·············115
c8bd3b #define IDB_READTOOLBAR ················161
740d61 #define IDB_SENDTOOLBAR ················162
2f54c7 #define IDD_PASSPHRASE ·················1001
5ea32a #define IDC_PHRASE ·····················1002
45fd6b #define IDC_HIDETYPING ·················1003
2e2942 #define IDC_PROMPTSTRING ···············1004
f1413d #define ID_PGPHELP ·····················60001
052b6b #define ID_ABOUTPGP ····················60002
5cda01 #define ID_PGPENCRYPT ··················60003
e52c7a #define ID_PGPSIGN ·····················60004
1982e0 #define ID_PGPENCRYPTSIGN ··············60005
5473e5 #define ID_PREFERENCES ·················60006
cd3ea6 #define ID_PGPDECRYPTVERIFY ············60007
9cea80 #define ID_PGPGETKEY ···················60008
5ba934 #define ID_PGPKEYS ·····················60009
--8093 001b0125b0b401101d0 Page 2 of resource.h
e0af5a
8011aa // Next default values for new objects
a7ac6a //·
a2f860 #ifdef APSTUDIO_INVOKED
883f23 #ifndef APSTUDIO_READONLY_SYMBOLS
f76273 #define _APS_NEXT_RESOURCE_VALUE ·······125
652a4e #define _APS_NEXT_COMMAND_VALUE ········60010
f2ef34 #define _APS_NEXT_CONTROL_VALUE ········1001
571285 #define _APS_NEXT_SYMED_VALUE ··········101
687454 #endif
b07454 #endif
--755e 00156369879401101d1 Page 1 of strstri.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c8465e ¤   strstri.c,v 1.3 1997/07/16 05:51:53 elrod Exp
08f7f7 ____________________________________________________________________________*/
10af5a
279b16 // System Headers
f4bea3 #include <stdlib.h>
e6af5a
4e5f12 char* strstri(char * inBuffer, char * inSearchStr)
80bb36 {
52d7d6 ¤   char* ·currBuffPointer = inBuffer;
eeaf5a
9e00fc ····while (*currBuffPointer != 0x00)
dfc7a1 ¤   {
c6af1d ········char* compareOne = currBuffPointer;
937f55 ········char* compareTwo = inSearchStr;
f9af5a
d8bc20 ········while (tolower(*compareOne) == tolower(*compareTwo))
675b34 ¤   ¤   {
fc30d7 ············compareOne++;
6ad8f7 ············compareTwo++;
1c3e48 ············if (*compareTwo == 0x00)
85f776 ¤   ¤   ¤   {
7bc220 ¤   ¤   ¤   ¤   return (char*) currBuffPointer;
4e7812 ············}
ec7fb0 ········}
c98f8c ········currBuffPointer++;
526fe7 ····}
397daf ····return NULL;
56efe6 }
--12f4 00149be8a5c401101d2 Page 1 of strstri.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
9081f8 ¤   strstri.h,v 1.3 1997/10/22 23:06:02 elrod Exp
45f7f7 ____________________________________________________________________________*/
15af5a
f53db2 #ifndef Included_strstri_h¤ /* [ */
b699e7 #define Included_strstri_h
75af5a
f63379 #ifdef __cplusplus
066dad extern "C" {
617454 #endif
1eaf5a
6a33ec char* strstri(char * inBuffer, char * inSearchStr);
58af5a
4f3379 #ifdef __cplusplus
f9efe6 }
3a7454 #endif
2aaf5a
4df120 #endif /* ] Included_strstri_h */
e1af5a
6caf5a
147e4d /*__Editor_settings____
98af5a
154126 ¤   Local Variables:
be7b17 ¤   tab-width: 4
bf0e6c ¤   End:
495f8c ¤   vi: ts=4 sw=4
ce9e9b ¤   vim: si
49d062 _____________________*/
--08fd 000b21fd837401101d3 Page 1 of transbmp.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
a9bd07 ¤   transbmp.c,v 1.3 1997/07/16 05:51:54 elrod Exp
0ff7f7 ____________________________________________________________________________*/
e4af5a
6a9b16 // System Headers
eb5655 #include <windows.h>
2f3d0b #include <windowsx.h>
d0af5a
767efe BOOL·
3145df TransparentBitmap(¤ HBITMAP hBitmap,·
5712db ¤   ¤   ¤   ¤   ¤   int iXsize,·
f99364 ¤   ¤   ¤   ¤   ¤   int iYsize,·
ea254f ····················DWORD rgbTransparent,·
3537ff ¤   ¤   ¤   ¤   ¤   HDC hDC,·
fe3fad ¤   ¤   ¤   ¤   ¤   int iXoffset,
ff0ce8 ¤   ¤   ¤   ¤   ¤   int iYoffset)
00bb36 {
4fb7c8 ¤   HDC mDC, nDC;
1c7b11 ¤   HBITMAP hMask;
9a51be ¤   LPBYTE lpBits;
d5af5a
a14505 ¤   // ·Create a memory DC for bitmap work
8bf4e8 ¤   mDC = CreateCompatibleDC( hDC );
0daf5a
30467f ¤   // ·If memory DC was created...
f7e4a9 ¤   if( mDC ) ····························
6cc7a1 ¤   {
c76d78 ¤   ¤   // ·Select passed bitmap to memory DC
3e792b ¤   ¤   SelectObject( mDC, hBitmap ); ·····
75af5a
fcb112 ¤   ¤   // ·Allocate a buffer for monochrome bitmap
3f2de2 ¤   ¤   lpBits = (LPBYTE) GlobalAllocPtr( GHND, iXsize * iYsize * 2 );
3eaf5a
7017f4 ¤   ¤   if( lpBits )
e65f16 ¤   ¤   { ··
9f946c ¤   ¤   ¤   // ·Create mono (mask) bitmap
b87c6f ¤   ¤   ¤   hMask = CreateBitmap( iXsize, iYsize, 1, 1, lpBits );
e671e9 ¤   ¤   ¤   if( hMask )
be8f59 ¤   ¤   ¤   { ·
51b2d6 ¤   ¤   ¤   ¤   // ·If mono bitmap worked, create mem DC for it
9a6585 ¤   ¤   ¤   ¤   nDC = CreateCompatibleDC( hDC );
fbaf5a
a61883 ¤   ¤   ¤   ¤   if( nDC )
1072c3 ¤   ¤   ¤   ¤   {
880e1c ¤   ¤   ¤   ¤   ¤   // ·Apply mask bitmap to mem DC
8ed6b6 ¤   ¤   ¤   ¤   ¤   SelectObject( nDC, hMask );
2eaf5a
d6433f ¤   ¤   ¤   ¤   ¤   // Specify "see thru" color
d8eb4b ¤   ¤   ¤   ¤   ¤   SetBkColor( mDC, rgbTransparent ); ··
08af5a
3fa88a ¤   ¤   ¤   ¤   ¤   // ·First, blit original bitmap into mono space
e85c13 ¤   ¤   ¤   ¤   ¤   // ·to create the bitmap mask
779e70 ¤   ¤   ¤   ¤   ¤   BitBlt( nDC,·
ce4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
de4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
d40c65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iXsize,·
de8dda ¤   ¤   ¤   ¤   ¤   ¤   ¤   iYsize,·
1ee593 ¤   ¤   ¤   ¤   ¤   ¤   ¤   mDC,·
684ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
e04ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
dc92d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SRCCOPY );
19af5a
0d1056 ¤   ¤   ¤   ¤   ¤   // ·Now blit original onto screen and invert
e8868a ¤   ¤   ¤   ¤   ¤   BitBlt( hDC,·
31021d ¤   ¤   ¤   ¤   ¤   ¤   ¤   iXoffset,·
ff2ebb ¤   ¤   ¤   ¤   ¤   ¤   ¤   iYoffset,
b20c65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iXsize,·
--c7bf 001a5bc0916401101d3 Page 2 of transbmp.c
c08dda ¤   ¤   ¤   ¤   ¤   ¤   ¤   iYsize,·
cfe593 ¤   ¤   ¤   ¤   ¤   ¤   ¤   mDC,·
124ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
f24ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
e676bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   SRCINVERT );
2aaf5a
12c71e ¤   ¤   ¤   ¤   ¤   // ·AND screen bits with mask bits
43a712 ¤   ¤   ¤   ¤   ¤   // ·This will "mask" anything specified
4b9620 ¤   ¤   ¤   ¤   ¤   // ·by the previous call to SetBkColor()
5e868a ¤   ¤   ¤   ¤   ¤   BitBlt( hDC,·
1b021d ¤   ¤   ¤   ¤   ¤   ¤   ¤   iXoffset,·
3b2ebb ¤   ¤   ¤   ¤   ¤   ¤   ¤   iYoffset,
3a0c65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iXsize,·
0a8dda ¤   ¤   ¤   ¤   ¤   ¤   ¤   iYsize,·
90e9ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   nDC,·
974ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
ab4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
c87d2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SRCAND );
b9af5a
6dd755 ¤   ¤   ¤   ¤   ¤   // ·Blit original again inverting again
6e7637 ¤   ¤   ¤   ¤   ¤   // ·to produce transparent image
34868a ¤   ¤   ¤   ¤   ¤   BitBlt( hDC,·
17021d ¤   ¤   ¤   ¤   ¤   ¤   ¤   iXoffset,·
262e3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   iYoffset,·
de0c65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iXsize,·
db8dda ¤   ¤   ¤   ¤   ¤   ¤   ¤   iYsize,·
d6e593 ¤   ¤   ¤   ¤   ¤   ¤   ¤   mDC,·
844ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
484ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
4176bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   SRCINVERT );
67af5a
e46175 ¤   ¤   ¤   ¤   ¤   // ·Delete second mem DC
099336 ¤   ¤   ¤   ¤   ¤   DeleteDC( nDC ); ·······················
292613 ¤   ¤   ¤   ¤   }
18af5a
d31c35 ¤   ¤   ¤   ¤   // ·Delete mask bitmap
551a53 ¤   ¤   ¤   ¤   DeleteObject( hMask ); ······················
dfa3a6 ¤   ¤   ¤   }
3eaf5a
cd3ad1 ¤   ¤   ¤   // ·Free space mask took up
1b1f46 ¤   ¤   ¤   GlobalFreePtr( lpBits ); ··················
bf0fe4 ¤   ¤   }
c2af5a
5a2046 ¤   ¤   // ·Kill off the memory DC, unlocking passed BMP
5b1376 ¤   ¤   DeleteDC( mDC ); ········
d79371 ¤   }
1d1966 ¤   return( TRUE );
daefe6 }
b6af5a
a5af5a
--ccf4 001d62e99f6401101d4 Page 1 of transbmp.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
1e7d6c ¤   transbmp.h,v 1.3 1997/10/22 23:06:03 elrod Exp
aef7f7 ____________________________________________________________________________*/
81af5a
b0023e #ifndef Included_TransBMP_h¤/* [ */
b3fd04 #define Included_TransBMP_h
f2af5a
123379 #ifdef __cplusplus
f36dad extern "C" {
527454 #endif
c6af5a
3d3617 BOOL TransparentBitmap(HBITMAP hBitmap,·
b83c3a ¤   ¤   ¤   ¤   ¤   ···int iXsize,·
44bd85 ¤   ¤   ¤   ¤   ¤   ···int iYsize,·
4f7471 ·······················DWORD rgbTransparent,·
cc2220 ¤   ¤   ¤   ¤   ¤   ···HDC hDC,·
b5c904 ¤   ¤   ¤   ¤   ¤   ···int iXoffset,
ae5357 ¤   ¤   ¤   ¤   ¤   ···int iYoffset);
90af5a
7b3379 #ifdef __cplusplus
bdefe6 }
e27454 #endif
fdaf5a
a69f7b #endif /* ] Included_TransBMP_h */
30af5a
83af5a
ad7e4d /*__Editor_settings____
e4af5a
864126 ¤   Local Variables:
427b17 ¤   tab-width: 4
020e6c ¤   End:
c45f8c ¤   vi: ts=4 sw=4
259e9b ¤   vim: si
d6d062 _____________________*/
--8814 00090d7c494401101d5 Page 1 of BUFTYPE.CPP
bc38e5 /*
940c2e ·* File: BUFTYPE.CPP
44775e ·*
8de440 ·* Date: Wednesday, August 28, 1996
00775e ·*
cc4ad2 ·* Author: Scott Manjourides
ba775e ·*
bbdc09 ·* Copyright (c) 1996 QUALCOMM, Incorporated
f3775e ·*
60495d ·*/
4baf5a
18bea3 #include <stdlib.h>
01324c #include <string.h>
69af5a
e2d3fb #include "BUFTYPE.H"
50af5a
77dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
c9af5a
1c64cc #ifndef TRUE
0a55ea #¤  define TRUE (1)
d57454 #endif
8eaf5a
6aec14 #ifndef FALSE
a6bdaf #¤  define FALSE (0)
3b7454 #endif
dbaf5a
d6e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d7af5a
1a87dc static int resizebuf_buf(BufTypePtr dst, unsigned int newSize);
efaf5a
eee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
04af5a
88b3b4 BufTypePtr makesize_buf(unsigned int n)
61bb36 {
efec30 ¤   BufTypePtr bp = (BufTypePtr) malloc(sizeof(BufType));
90af5a
423ab1 ¤   if (!bp)
388021 ¤   ¤   return (NULL);
ccaf5a
2ab30f ¤   clear_buf(bp);
2faf5a
4a01bb ¤   bp->buf = (char *) malloc(n * sizeof(char));
33af5a
02ad05 ¤   if (bp->buf)
1835eb ¤   ¤   bp->buf_size = n;
5c0e24 ¤   else
42c7a1 ¤   {
0bb5ff ¤   ¤   delete_buf(bp);
1f8021 ¤   ¤   return (NULL);
7f9371 ¤   }
58af5a
22a329 ¤   return (bp);
1befe6 }
30af5a
d7e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
09af5a
330d95 BufTypePtr make_buf()
8abb36 {
eeec30 ¤   BufTypePtr bp = (BufTypePtr) malloc(sizeof(BufType));
99af5a
503ab1 ¤   if (!bp)
f18021 ¤   ¤   return (NULL);
2aaf5a
a1b30f ¤   clear_buf(bp);
e0af5a
a8a329 ¤   return (bp);
77efe6 }
b6af5a
93e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
14af5a
041aba /* boolean */ int isempty_buf(BufTypePtr bp)
90bb36 {
--9b5a 0006bc4058f401101d5 Page 2 of BUFTYPE.CPP
a62b5f ¤   if ((!bp) || (bp->buf == NULL) || (bp->len == 0))
abdc29 ¤   ¤   return (TRUE);
27af5a
bc5d9d ¤   return (FALSE);
fbefe6 }
f4af5a
f3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d3af5a
11d548 unsigned int availspace_buf(BufTypePtr bp)
f2bb36 {
c32359 ¤   if ((!bp) || (bp->buf == NULL))
c8f109 ¤   ¤   return (0);
d7af5a
430faf ¤   return (bp->buf_size - bp->len);
ecefe6 }
d1af5a
d7e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
50af5a
2b272b unsigned int buflen_buf(BufTypePtr bp) /* Number of valid chars in buffer. Alwa¶
25e1e8 ys < bufsize_buf() */
3bbb36 {
fdd4f4 ¤   if (isempty_buf(bp))
1cf109 ¤   ¤   return (0);
3faf5a
411d07 ¤   return (bp->len);
22efe6 }
99af5a
76e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d0af5a
13ce9f char *getbuf_buf(BufTypePtr bp)
f5bb36 {
2b3ab1 ¤   if (!bp)
d58021 ¤   ¤   return (NULL);
55af5a
56753d ¤   return (bp->buf);
f4efe6 }
f8af5a
66e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
adaf5a
ea513a char *getend_buf(BufTypePtr bp)
bbbb36 {
29d4f4 ¤   if (isempty_buf(bp))
1e8021 ¤   ¤   return (NULL);
10af5a
b1bd0d ¤   return ((bp->buf) + (bp->len - 1));
16efe6 }
c3af5a
a5e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
71af5a
d628d5 unsigned int bufsize_buf(BufTypePtr bp)
30bb36 {
453ab1 ¤   if (!bp)
b3f109 ¤   ¤   return (0);
d7af5a
e157c4 ¤   return (bp->buf_size);
6befe6 }
ffaf5a
0ee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
8aaf5a
eb343a /* boolean */ int endspan_buf(BufTypePtr buf, BufTypePtr find)
bbbb36 {
6087eb ¤   if (isempty_buf(buf) || isempty_buf(find))
b72769 ¤   ¤   return (FALSE);
4faf5a
b412f1 ¤   char cEnd = *getend_buf(buf); /* buf->buf[buf->len - 1]; */
ab7cc8 ¤   char *pPos = getpos_buf(find); /* find->buf */
485326 ¤   char *pEnd = getend_buf(find); /* (find->buf + find->len - 1); */
9caf5a
6d5b33 ¤   /* Return TRUE if the last char in 'buf' is anywhere in 'find' */
27301d ¤   while (pPos <= pEnd)
6bc7a1 ¤   {
6bf5e4 ¤   ¤   if (*pPos == cEnd)
--b992 000d2d03606401101d5 Page 3 of BUFTYPE.CPP
3f3ec8 ¤   ¤   ¤   return (TRUE);
43af5a
28f38a ¤   ¤   pPos++;
f09371 ¤   }
6baf5a
fe5d9d ¤   return (FALSE);
98efe6 }
7baf5a
4ce6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
f0af5a
f7ba63 /* boolean */ int setlen_buf(BufTypePtr bp, const unsigned int n)
cabb36 {
226254 ¤   if ((!bp) || (bp->buf == NULL) || (n > (bp->buf_size)))
8a2769 ¤   ¤   return (FALSE);
04af5a
c7d6eb ¤   bp->len = n;
96af5a
cee7c0 ¤   return (TRUE);
b8efe6 }
38af5a
42e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d5af5a
6c53c8 unsigned int bufncat_buf(BufTypePtr dst, BufTypePtr src, unsigned int n)
9fbb36 {
fd9a7c ¤   if ((isempty_buf(src)) || (n < 1) || (!dst))
54f109 ¤   ¤   return (0);
0daf5a
a50591 ¤   unsigned int oldSize = buflen_buf(dst);
d9f6e4 ¤   unsigned int addSize = poslen_buf(src);
25af5a
491a87 ¤   if (n < addSize)
e94b0b ¤   ¤   addSize = n;
a5af5a
babd20 ¤   unsigned int newSize = oldSize + addSize;
9caf5a
abd88d ¤   if (newSize > bufsize_buf(dst))
fdc7a1 ¤   {
2438e8 ¤   ¤   if (!resizebuf_buf(dst, newSize))
6d8bfd ¤   ¤   ¤   return (0);
979371 ¤   }
a5af5a
002d4b ¤   if (oldSize == 0)
f4f83b ¤   ¤   dst->pos = dst->buf;
7eaf5a
ba0631 ¤   char *cpDst, *cpSrc = getpos_buf(src);
074a90 ¤   unsigned int nCopy = addSize;
7eaf5a
89a881 ¤   if (oldSize > 0)
d2547b ¤   ¤   cpDst = getend_buf(dst) + 1;
650e24 ¤   else
10aca0 ¤   ¤   cpDst = getpos_buf(dst);
1daf5a
b52593 ¤   while (nCopy--)
85ad0a ¤   ¤   *cpDst++ = *cpSrc++;
48af5a
f42bb2 ¤   incpos_buf(src, addSize);
7cc4ba ¤   dst->len = newSize;
e7af5a
79e009 ¤   return (addSize);
23efe6 }
b4af5a
9ae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
85af5a
baaca4 unsigned int bufins_buf(BufTypePtr dst, BufTypePtr src)
60bb36 {
658d74 ¤   if (isempty_buf(src))
aaf109 ¤   ¤   return (0);
85af5a
a51735 ¤   unsigned int oldLen = poslen_buf(dst);
fc3884 ¤   unsigned int bufSize = bufsize_buf(dst);
5d106c ¤   unsigned int addLen = poslen_buf(src);
d225dc ¤   unsigned int newLen = oldLen + addLen;
--9565 000e951d5e0401101d5 Page 4 of BUFTYPE.CPP
e0af5a
635f04 ¤   if (newLen > bufSize)
1d2123 ¤   ¤   addLen = bufSize - oldLen;
8baf5a
18ec01 ¤   if (addLen < 1)
0f879c ¤   ¤   return (0); /* Buffer is already full */
90af5a
edaee5 ¤   return (bufncat_buf(dst, src, addLen));
e3efe6 }
d3af5a
ece6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49af5a
45782d unsigned int bufnins_buf(BufTypePtr dst, BufTypePtr src, unsigned int n)
0abb36 {
15050c ¤   if ((isempty_buf(src)) || (n < 1))
4df109 ¤   ¤   return (0);
8baf5a
e31735 ¤   unsigned int oldLen = poslen_buf(dst);
843884 ¤   unsigned int bufSize = bufsize_buf(dst);
f6106c ¤   unsigned int addLen = poslen_buf(src);
fc25dc ¤   unsigned int newLen = oldLen + addLen;
99af5a
805f04 ¤   if (newLen > bufSize)
e62123 ¤   ¤   addLen = bufSize - oldLen;
87af5a
e60593 ¤   if (n < addLen)
dac2d6 ¤   ¤   addLen = n;
8eaf5a
54ec01 ¤   if (addLen < 1)
36879c ¤   ¤   return (0); /* Buffer is already full */
a1af5a
beaee5 ¤   return (bufncat_buf(dst, src, addLen));
31efe6 }
72af5a
25e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
29af5a
e0ad1e unsigned int poslen_buf(BufTypePtr bp) /* Number of valid chars, starting at cu¶
39d3ba rrent position */
50bb36 {
882291 ¤   if ((isempty_buf(bp)) || ((bp->pos) == NULL))
6ef109 ¤   ¤   return (0);
25af5a
084d73 ¤   return ( (bp->len) - ((bp->pos) - (bp->buf)) );
f0efe6 }
eeaf5a
74e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5aaf5a
ea2278 void incpos_buf(BufTypePtr bp, unsigned int n)
02bb36 {
bc3ab1 ¤   if (!bp)
1299bf ¤   ¤   return;
8267c5 ¤
832b9a ¤   if (poslen_buf(bp) > n)
b0fd16 ¤   ¤   bp->pos += n;
ca0e24 ¤   else
ae3dd1 ¤   ¤   bp->pos = NULL;
9eefe6 }
04af5a
52e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
55af5a
e32ffe void delpos_buf(BufTypePtr bp)
ebbb36 {
6d3ab1 ¤   if (!bp)
d599bf ¤   ¤   return;
d2af5a
d64725 ¤   bp->pos = NULL;
ecefe6 }
abaf5a
39e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
dcaf5a
a82301 void resetpos_buf(BufTypePtr bp)
e9bb36 {
--e436 000a6b119a6401101d5 Page 5 of BUFTYPE.CPP
807ea0 ¤   if (bp)
5651f7 ¤   ¤   bp->pos = bp->buf;
c2efe6 }
17af5a
c1e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3caf5a
c47047 char *getpos_buf(BufTypePtr bp)
35bb36 {
493ab1 ¤   if (!bp)
2c8021 ¤   ¤   return (NULL);
92af5a
063e49 ¤   if ((bp->pos) == NULL)
1d51f7 ¤   ¤   bp->pos = bp->buf;
3767c5 ¤
fd6ac5 ¤   return (bp->pos);
f3efe6 }
d3af5a
d4e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
a4af5a
323e67 unsigned int strcpy_buf(BufTypePtr dst, const char *src)
8fbb36 {
554c6a ¤   if ((!src) || (!dst))
dbf109 ¤   ¤   return (0);
04af5a
a3ba98 ¤   unsigned int nLen = strlen(src);
53af5a
fa925b ¤   if (nLen > 0)
6fc7a1 ¤   {
1fb726 ¤   ¤   if (nLen > bufsize_buf(dst))
015b34 ¤   ¤   {
112f2f ¤   ¤   ¤   if (!resizebuf_buf(dst, nLen))
1a7d98 ¤   ¤   ¤   ¤   return (0);
270fe4 ¤   ¤   }
62af5a
b4a090 ¤   ¤   char *cp = dst->buf;
abaf5a
ceea6c ¤   ¤   while (*src)
8144ed ¤   ¤   ¤   *cp++ = *src++;
a3af5a
75f83b ¤   ¤   dst->pos = dst->buf;
259371 ¤   }
49a406 ¤   else /* nLen == 0 */
37c7a1 ¤   {
fc5557 ¤   ¤   dst->pos = NULL;
c99371 ¤   }
c0af5a
156e7b ¤   dst->len = nLen;
7aaf5a
dc3858 ¤   return (nLen);
00efe6 }
c3af5a
cae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b3af5a
ed3e43 unsigned int strncpy_buf(BufTypePtr dst, const char *src, const unsigned int n)
00bb36 {
e34c6a ¤   if ((!src) || (!dst))
9cf109 ¤   ¤   return (0);
94af5a
c2ba98 ¤   unsigned int nLen = strlen(src);
b7af5a
7bc393 ¤   if (n < nLen)
b8dfda ¤   ¤   nLen = n;
9aaf5a
ca925b ¤   if (nLen > 0)
b2c7a1 ¤   {
5bb726 ¤   ¤   if (nLen > bufsize_buf(dst))
295b34 ¤   ¤   {
e02f2f ¤   ¤   ¤   if (!resizebuf_buf(dst, nLen))
af7d98 ¤   ¤   ¤   ¤   return (0);
7d0fe4 ¤   ¤   }
30af5a
a6a090 ¤   ¤   char *cp = dst->buf;
--8209 000c33e7283401101d5 Page 6 of BUFTYPE.CPP
e0af5a
d9ea6c ¤   ¤   while (*src)
9d44ed ¤   ¤   ¤   *cp++ = *src++;
01af5a
15f83b ¤   ¤   dst->pos = dst->buf;
649371 ¤   }
d6a406 ¤   else /* nLen == 0 */
f8c7a1 ¤   {
805557 ¤   ¤   dst->pos = NULL;
aa9371 ¤   }
70af5a
426e7b ¤   dst->len = nLen;
49af5a
343858 ¤   return (nLen);
46efe6 }
00af5a
bbe6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
34af5a
fbfde8 unsigned int strcat_buf(BufTypePtr dst, const char *src)
6cbb36 {
eb4c6a ¤   if ((!src) || (!dst))
10f109 ¤   ¤   return (0);
6baf5a
fb0591 ¤   unsigned int oldSize = buflen_buf(dst);
3e6b7b ¤   unsigned int addSize = strlen(src);
fcbd20 ¤   unsigned int newSize = oldSize + addSize;
88af5a
87d88d ¤   if (newSize > bufsize_buf(dst))
8bc7a1 ¤   {
3338e8 ¤   ¤   if (!resizebuf_buf(dst, newSize))
e98bfd ¤   ¤   ¤   return (0);
9c9371 ¤   }
c3af5a
6d2d4b ¤   if (oldSize == 0)
b9f83b ¤   ¤   dst->pos = dst->buf;
2eaf5a
438807 ¤   char *cpDst, *cpSrc = (char *) src;
9c4a90 ¤   unsigned int nCopy = addSize;
66af5a
afa881 ¤   if (oldSize > 0)
02547b ¤   ¤   cpDst = getend_buf(dst) + 1;
ad0e24 ¤   else
6baca0 ¤   ¤   cpDst = getpos_buf(dst);
93af5a
e02593 ¤   while (nCopy--)
55ad0a ¤   ¤   *cpDst++ = *cpSrc++;
c6af5a
bdc4ba ¤   dst->len = newSize;
2caf5a
ede009 ¤   return (addSize);
a1af5a
7cefe6 }
efaf5a
80e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
07af5a
4e842a unsigned int strncat_buf(BufTypePtr dst, const char *src, const unsigned int n)
11bb36 {
0b4c6a ¤   if ((!src) || (!dst))
49f109 ¤   ¤   return (0);
d3af5a
ce0591 ¤   unsigned int oldSize = buflen_buf(dst);
9d6b7b ¤   unsigned int addSize = strlen(src);
3267c5 ¤
3f1a87 ¤   if (n < addSize)
464b0b ¤   ¤   addSize = n;
1c67c5 ¤
24bd20 ¤   unsigned int newSize = oldSize + addSize;
10af5a
5ad88d ¤   if (newSize > bufsize_buf(dst))
5fc7a1 ¤   {
8f38e8 ¤   ¤   if (!resizebuf_buf(dst, newSize))
c38bfd ¤   ¤   ¤   return (0);
--7be4 000cad85d8b401101d5 Page 7 of BUFTYPE.CPP
a19371 ¤   }
93af5a
5f2d4b ¤   if (oldSize == 0)
c2f83b ¤   ¤   dst->pos = dst->buf;
19af5a
148807 ¤   char *cpDst, *cpSrc = (char *) src;
a24a90 ¤   unsigned int nCopy = addSize;
17af5a
9da881 ¤   if (oldSize > 0)
d0547b ¤   ¤   cpDst = getend_buf(dst) + 1;
b60e24 ¤   else
4baca0 ¤   ¤   cpDst = getpos_buf(dst);
0daf5a
e92593 ¤   while (nCopy--)
15ad0a ¤   ¤   *cpDst++ = *cpSrc++;
c0af5a
efc4ba ¤   dst->len = newSize;
53af5a
25e009 ¤   return (addSize);
1caf5a
46efe6 }
9eaf5a
25e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
16af5a
eec483 void delete_buf(BufTypePtr bp)
47bb36 {
f33ab1 ¤   if (!bp)
2299bf ¤   ¤   return;
0daf5a
2b5efd ¤   free_buf(bp);
76e1db ¤   safefree(bp);
34efe6 }
f0af5a
66e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d4af5a
c00940 void free_buf(BufTypePtr bp)
6ebb36 {
183ab1 ¤   if (!bp)
0299bf ¤   ¤   return;
27af5a
e3d3d2 ¤   safefree(bp->buf);
82b30f ¤   clear_buf(bp);
7cefe6 }
a9af5a
9ae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d2af5a
3efa0a void clear_buf(BufTypePtr bp)
c9bb36 {
b53ab1 ¤   if (!bp)
3b99bf ¤   ¤   return;
d2af5a
e07862 ¤   bp->buf = NULL;
9e61a6 ¤   bp->buf_size = 0;
09af5a
f6ffa2 ¤   emptybuf_buf(bp);
59efe6 }
48af5a
a5e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
42af5a
e60c82 void emptybuf_buf(BufTypePtr bp)
10bb36 {
d53ab1 ¤   if (!bp)
5099bf ¤   ¤   return;
d1af5a
09b316 ¤   bp->pos = bp->buf;
5e4513 ¤   bp->len = 0;
e0efe6 }
29af5a
5be6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
64af5a
c4af5a
ca49b3 static /* boolean */ int resizebuf_buf(BufTypePtr bp, unsigned int newSize)
--8a70 000b3cbf197401101d5 Page 8 of BUFTYPE.CPP
2cbb36 {
33e756 ¤   unsigned int oldSize = bp->buf_size;
7caf5a
f7cd02 ¤   if (oldSize == newSize)
6bdc29 ¤   ¤   return (TRUE);
d267c5 ¤
92c343 ¤   char *tmpPtr = (char *) realloc(bp->buf, newSize);
75af5a
4392d3 ¤   if (tmpPtr == NULL)
9c2769 ¤   ¤   return (FALSE);
77af5a
cc4087 ¤   bp->buf = tmpPtr;
323aea ¤   bp->buf_size = newSize;
99af5a
08777c ¤   if (newSize < oldSize) /* Getting smaller */
85c7a1 ¤   {
3ee86a ¤   ¤   /* Check for valid length */
0c4f03 ¤   ¤   if (bp->len > newSize)
f85757 ¤   ¤   ¤   bp->len = newSize;
c8af5a
c586a8 ¤   ¤   /* Check pos */
2aa6bb ¤   ¤   unsigned int nPos = ((bp->pos) - (bp->buf));
74fa6f ¤   ¤   if (nPos >= bp->len)
86cbb4 ¤   ¤   ¤   bp->pos = NULL;
389371 ¤   }
4285b6 ¤   else if (oldSize == 0)
ffc7a1 ¤   {
8851f7 ¤   ¤   bp->pos = bp->buf;
2f9371 ¤   }
37af5a
fbe7c0 ¤   return (TRUE);
b4efe6 }
40af5a
eee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36af5a
bc8c6a // If doesn't continue match, returns zero
57febc // otherwise returns number of chars of pSearchBuf that have been matched
ced424 unsigned int completecount_buf(BufTypePtr buf, BufTypePtr find, const unsigned ¶
1ca7fa int nPreMatched)
58bb36 {
cb87eb ¤   if (isempty_buf(buf) || isempty_buf(find))
85f109 ¤   ¤   return (0);
68af5a
57cff5 ¤   if (nPreMatched >= poslen_buf(find))
7df109 ¤   ¤   return (0);
97af5a
68b406 ¤   char *pBuf = getpos_buf(buf);
cf5ab3 ¤   char *pBufEnd = getend_buf(buf);
33af5a
cd8728 ¤   char *pFind = getpos_buf(find) + nPreMatched;
804889 ¤   char *pFindEnd = getend_buf(find);
4aaf5a
573cbf ¤   unsigned int nSkipCount = 0;
96af5a
b9165e ¤   while ((pBuf <= pBufEnd) && (pFind <= pFindEnd) && ((*pBuf) == (*pFind)))
dc9ce9 ¤   ¤   pBuf++, pFind++, nSkipCount++;
3eaf5a
2bb5ec ¤   if ((pBuf > pBufEnd) || (pFind > pFindEnd))
de4a2e ¤   ¤   return (nPreMatched + nSkipCount);
b5af5a
912424 ¤   return (0); /* match failed */
7aefe6 }
07af5a
c3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
e3af5a
7aa313 // Find match of pSearchBuf, either complete or end-spanning
1f1be8 // return number of chars to skip before match
498516 // No match: return length of buf (skip the whole buffer)
daa386 unsigned int skipcount_buf(BufTypePtr buf, BufTypePtr find)
c0bb36 {
579564 ¤   if (isempty_buf(buf))
b3f109 ¤   ¤   return (0);
--3598 0014c767d73401101d5 Page 9 of BUFTYPE.CPP
e0af5a
4c589c ¤   if (isempty_buf(find))
616523 ¤   ¤   return (poslen_buf(buf));
c6af5a
7bb406 ¤   char *pBuf = getpos_buf(buf);
d5051d ¤   char *pFind = getpos_buf(find);
3e5ab3 ¤   char *pBufEnd = getend_buf(buf);
244889 ¤   char *pFindEnd = getend_buf(find);
55af5a
87a056 ¤   char *s1 = NULL, *s2 = NULL;
b8af5a
113cbf ¤   unsigned int nSkipCount = 0;
94af5a
6b1672 ¤   while (pBuf <= pBufEnd)
56c7a1 ¤   {
95ba32 ¤   ¤   s1 = pBuf;
4a1398 ¤   ¤   s2 = pFind;
43af5a
e50344 ¤   ¤   while ((s1 <= pBufEnd) && (s2 <= pFindEnd) && ((*s1) == (*s2)))
814d31 ¤   ¤   ¤   s1++, s2++;
4daf5a
6d7583 ¤   ¤   if ((s1 > pBufEnd) || (s2 > pFindEnd))
ecf135 ¤   ¤   ¤   return (nSkipCount);
dbaf5a
b88852 ¤   ¤   pBuf++;
fe3a3e ¤   ¤   nSkipCount++;
649371 ¤   }
f2af5a
b7522b ¤   return (poslen_buf(buf));
4cefe6 }
--23a4 001eed5b5a7401101d6 Page 1 of BUFTYPE.H
bc38e5 /*
9abbab ·* File: BUFTYPE.H
1e775e ·*
aee440 ·* Date: Wednesday, August 28, 1996
96775e ·*
c14ad2 ·* Author: Scott Manjourides
c0775e ·*
60dc09 ·* Copyright (c) 1996 QUALCOMM, Incorporated
ec775e ·*
c5495d ·*/
20af5a
b750df #ifndef BUFTYPE_H
4e8d86 #define BUFTYPE_H
01af5a
73e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
59af5a
0ff0f7 typedef struct {
7499d0 ¤   char *buf;
255e85 ¤   unsigned int buf_size;
28b069 ¤   unsigned int len;
44983f ¤   char *pos;
255467 } BufType;
19af5a
c8d9e8 typedef BufType *BufTypePtr;
04af5a
75e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
06af5a
b3f33c BufTypePtr makesize_buf(unsigned int n);
d8c309 BufTypePtr make_buf();
3aaf5a
261aeb /* boolean */ int isempty_buf(BufTypePtr bp);
3bceb9 unsigned int availspace_buf(BufTypePtr bp);
54f3f5 unsigned int buflen_buf(BufTypePtr bp); /* Number of valid chars in buffer. Alw¶
6fb053 ays < bufsize_buf() */
136c90 char *getbuf_buf(BufTypePtr bp);
5baf5a
3b9ea8 char *getend_buf(BufTypePtr bp);
2faa05 unsigned int bufsize_buf(BufTypePtr bp); /* The size of the buffer -- used or n¶
777268 ot */
a4a8a6 unsigned int buflen_buf(BufTypePtr bp);
ea5107 /* boolean */ int setlen_buf(BufTypePtr bp, const unsigned int n);
40af5a
164a37 unsigned int bufncat_buf(BufTypePtr dst, BufTypePtr src, unsigned int n);
203a52 unsigned int bufins_buf(BufTypePtr b1, BufTypePtr b2);
9461b9 unsigned int bufnins_buf(BufTypePtr b1, BufTypePtr b2, unsigned int n);
e5af5a
fe2401 unsigned int poslen_buf(BufTypePtr bp); /* Number of valid chars, starting at c¶
aa61db urrent position */
55af5a
f6ffcd void incpos_buf(BufTypePtr bp, unsigned int n);
151efe void delpos_buf(BufTypePtr bp);
a35aed char *getpos_buf(BufTypePtr bp); /* NULL problems */
da118a void resetpos_buf(BufTypePtr bp);
99af5a
9e17a7 unsigned int strcpy_buf(BufTypePtr dst, const char *src);
457081 unsigned int strncpy_buf(BufTypePtr dst, const char *src, const unsigned int n);
ab6b9b unsigned int strcat_buf(BufTypePtr dst, const char *src);
808efc unsigned int strncat_buf(BufTypePtr dst, const char *src, const unsigned int n);
2baf5a
84b677 void delete_buf(BufTypePtr bp);
fa422d void free_buf(BufTypePtr bp);
aeaf80 void clear_buf(BufTypePtr bp);
c8a736 void emptybuf_buf(BufTypePtr bp);
1baf5a
231f24 unsigned int completecount_buf(BufTypePtr src, BufTypePtr find, const unsigned ¶
64bd49 int n);
1fe1bd unsigned int skipcount_buf(BufTypePtr buf, BufTypePtr find);
c8af5a
ee7454 #endif
--3bd9 000099c7337401101d7 Page 1 of ENCODING.CPP
bc38e5 /*
288ba0 ·* ·Functions to encode and decode using BASE64 or Quoted-Printable
aab5e8 ·* ·Also a transfer-encoding header line parser
e1775e ·*
fe5064 ·* ·Filename: encoding.cpp
07775e ·*
badec9 ·* ·Last Edited: Friday, August 30, 1996
7c775e ·*
77005b ·* ·Author: Scott Manjourides
3b775e ·*
10cbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
12ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
63775e ·*
c1c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
1c495d ·*/
56af5a
b65655 #include <windows.h>
03fbd1 #include "ems-win.h"
7eaf5a
eabde1 #include "encoding.h"
0c291a #include "rfc822.h" ···
5395d9 #include "string.h"·
6f242a #include "ctype.h" ··
07ba0a #include "stdlib.h"
bcaf5a
4ac51a /* ========================================================================= */
a7af5a
a8dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
daaf5a
52c51a /* ========================================================================= */
76af5a
41cac7 /* Local util functions */
4e93e6 static char *newline_copy(char *dst);
27febb static int newline_test(const char prev, const char curr);
387185 static int hex2dec(const char ch);
d2af5a
abc067 /*****************************************************************************/
db0aa1 /* ·······························B A S E 6 4 ·······························*/
85c067 /*****************************************************************************/
0eaf5a
9f345b /* Base64 encoder/decoder ported from Macintosh source by Myra Callen */
33af5a
643330 #define SKIP (-1)
cd72de #define FAIL (-2)
20e683 #define PAD ·(-3)
c2af5a
fba7e5 #define kNewLine¤   ¤   ¤   "\015\012"
df8954 #define kNewLineLength (2)
07af5a
193f44 #define ABS(x) ··((x)<0 ? -(x) : (x))
c0af5a
c5e038 static char *g64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv¶
77d66c wxyz0123456789+/";
8f6293 static short g64DecodeArr[] =·
90bb36 {
96b475 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,SKIP,SKIP,FAIL,FAIL,SKIP,FAIL,¶
c68e54 FAIL,¤  /* 0 */
7cfca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
ad8510 FAIL,¤  /* 1 */
4d8e2b ¤   SKIP,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,0x3e,FAIL,FAIL,FAIL,¶
8a9f43 0x3f,¤  /* 2 */
7cf4d2 ¤   0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,FAIL,FAIL,FAIL,PAD ,FAIL,¶
349398 FAIL,¤  /* 3 */
4b8b6d ¤   FAIL,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,¶
822912 0x0e,¤  /* 4 */
2ac5e9 ¤   0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,FAIL,FAIL,FAIL,FAIL,¶
f0a800 FAIL,¤  /* 5 */
0131fb ¤   FAIL,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,¶
b3c5be 0x28,¤  /* 6 */
e2842b ¤   0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,FAIL,FAIL,FAIL,FAIL,¶
aabe88 FAIL,¤  /* 7 */
09fca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
--6405 0006aebdb8e401101d7 Page 2 of ENCODING.CPP
edd474 FAIL,¤  /* 8 */
5dfca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
cbdf30 FAIL,¤  /* 9 */
1bfca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
b390e3 FAIL,¤  /* A */
bdfca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
d58d2f FAIL,¤  /* B */
c4fca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
29866b FAIL,¤  /* C */
a0fca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
9fb6b7 FAIL,¤  /* D */
73fca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
7dbdf3 FAIL,¤  /* E */
1afca4 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,¶
8ba03f FAIL,¤  /* F */
18975e ··/* 0 ···1 ···2 ···3 ···4 ···5 ···6 ···7 ···8 ···9 ···A ···B ···C ···D ···E ··¶
03a4a8 ·F ·*/
ed82f7 };
64af5a
4438e5 /*
c9f6e2 ·* Bit extracting macros
2e495d ·*/
b063c5 #define Bot2(b) ((b)&0x3)
d86176 #define Bot4(b) ((b)&0xf)
e25310 #define Bot6(b) ((b)&0x3f)
a2b929 #define Top2(b) Bot2((b)>>6)
35e633 #define Top4(b) Bot4((b)>>4)
d7917b #define Top6(b) Bot6((b)>>2)
42af5a
cc38e5 /*
63219c ·* the decoder
85495d ·*/
fe8947 #define EncodeThree64(bin,b64,bpl)¤ EncodeThreeFour(bin,b64,bpl,g64EncodeChars)
b1af5a
9b439f #define EncodeThreeFour(bin,b64,bpl,vector) ····················\
ffe7cc ¤   do ·························································\
3051d2 ¤   { ··························································\
64056e ¤   ¤   if ((bpl)==68) ·········································\
3343ff ¤   ¤   { ······················································\
f434c0 ¤   ¤   ¤   (b64) = newline_copy(b64); ·························\
fcf452 ¤   ¤   ¤   (bpl) = 0; ·········································\
7d6c61 ¤   ¤   } ······················································\
676d5a ¤   ¤   (bpl) += 4; ············································\
4447ca ¤   ¤   *(b64)++ = vector[Top6((bin)[0])]; ·····················\
875159 ¤   ¤   *(b64)++ = vector[Bot2((bin)[0])<<4 | Top4((bin)[1])]; ·\
404835 ¤   ¤   *(b64)++ = vector[Bot4((bin)[1])<<2 | Top2((bin)[2])]; ·\
22c187 ¤   ¤   *(b64)++ = vector[Bot6((bin)[2])]; ·····················\
d658a3 ¤   } ··························································\
520755 ¤   while (0)
6baf5a
e3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b5af5a
f038e5 /*
2df752 ·* ·Convert binary data to base64
2f775e ·*
c66a22 ·* ·Args:
4ad736 ·* ··binPtr ····[IN] ····the binary data (or NULL to close encoder)
bf229f ·* ··binLen ····[IN] ····the length of the binary data
85967e ·* ··sixFourPtr [IN] ····pointer to buffer for the base64 data
96322c ·* ··e64 ·······[IN/OUT] state; caller must preserve
46775e ·*
d54185 ·* ·Returns: The length of the base64 data
6e495d ·*/
427f3a long Encode64(
5f66b0 ¤   char *binPtr,
a0f6b7 ¤   long binLen,
5b008b ¤   char *sixFourPtr,
cae4f5 ¤   Enc64Ptr e64)
14bb36 {
80301e ¤   char *binSpot;¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   /* the byte currently being¶
6483a4 ·decoded */
6aab02 ¤   char *sixFourSpot = sixFourPtr;¤/* the spot to which to copy the encoded ch¶
--52b5 000e887c535401101d7 Page 3 of ENCODING.CPP
b20e8b ars */
641ada ¤   short bpl;
cecea7 ¤   char *end;¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   /* end of integral deco¶
18ffac ding */
b2af5a
c126cf ¤   bpl = e64->bytesOnLine;¤/* in inner loop; want local copy */
6367c5 ¤
279b20 ¤   if (binLen)
ebc7a1 ¤   {
b61b52 ¤   ¤
5f1b17 ¤   ¤   /*
6c8768 ¤   ¤   ·* do we have any stuff left from last time?
969de3 ¤   ¤   ·*/
835d9e ¤   ¤   if (e64->partialCount)
505b34 ¤   ¤   {
67f4d1 ¤   ¤   ¤   short needMore = 3 - e64->partialCount;
08fa22 ¤   ¤   ¤   if (binLen >= needMore)
6ef776 ¤   ¤   ¤   {
c6980e ¤   ¤   ¤   ¤   /*
193f46 ¤   ¤   ¤   ¤   ·* we can encode some bytes
ed1020 ¤   ¤   ¤   ¤   ·*/
d96338 ¤   ¤   ¤   ¤   memcpy(e64->partial+e64->partialCount,binPtr,needMore);
4eab5e ¤   ¤   ¤   ¤   binLen -= needMore;
4d8aa2 ¤   ¤   ¤   ¤   binPtr += needMore;
e241f4 ¤   ¤   ¤   ¤   EncodeThree64(e64->partial,sixFourSpot,bpl);
123e04 ¤   ¤   ¤   ¤   e64->partialCount = 0;
a4a3a6 ¤   ¤   ¤   }
bc7aad ¤   ¤   ¤   /*
3c4cef ¤   ¤   ¤   ·* if we don't have enough bytes to complete the leftovers, we
110ce1 ¤   ¤   ¤   ·* obviously don't have 3 bytes. ·So the encoding code will fall
1fcac3 ¤   ¤   ¤   ·* through to the point where we copy the leftovers to the partial
bc10a2 ¤   ¤   ¤   ·* buffer. ·As long as we're careful to append and not copy blindly,
ed6491 ¤   ¤   ¤   ·* we'll be fine.
1c8753 ¤   ¤   ¤   ·*/
d70fe4 ¤   ¤   }
ab1b52 ¤   ¤
781b17 ¤   ¤   /*
b04dbf ¤   ¤   ·* we encode the integral multiples of three
3c9de3 ¤   ¤   ·*/
6f006b ¤   ¤   end = binPtr + 3*(binLen/3);
e5bf33 ¤   ¤   for (binSpot = binPtr; binSpot < end; binSpot += 3)
355b34 ¤   ¤   {
785f6d ¤   ¤   ¤   EncodeThree64(binSpot,sixFourSpot,bpl);
e40f9b ¤   ¤   ¤   /* *sixFourLen = sixFourSpot - sixFourPtr; */
d50fe4 ¤   ¤   }
141b52 ¤   ¤
4d1b17 ¤   ¤   /*
30451c ¤   ¤   ·* now, copy the leftovers to the partial buffer
e29de3 ¤   ¤   ·*/
cf2cdd ¤   ¤   binLen = binLen % 3;
1a0c53 ¤   ¤   if (binLen)
f35b34 ¤   ¤   {
5b2c9b ¤   ¤   ¤   memcpy(e64->partial+e64->partialCount,binSpot,binLen);
d86fc8 ¤   ¤   ¤   e64->partialCount += (short)binLen;
000fe4 ¤   ¤   }
4d9371 ¤   }
d40e24 ¤   else
37c7a1 ¤   {
e31b17 ¤   ¤   /*
110e92 ¤   ¤   ·* we've been called to cleanup the leftovers
5d9de3 ¤   ¤   ·*/
d55d9e ¤   ¤   if (e64->partialCount)
695b34 ¤   ¤   {
7a9bb3 ¤   ¤   ¤   if (e64->partialCount<2) e64->partial[1] = 0;
f535e4 ¤   ¤   ¤   e64->partial[2] = 0;
e36741 ¤   ¤   ¤   EncodeThree64(e64->partial,sixFourSpot,bpl);
9587c7 ¤   ¤   ¤
d37aad ¤   ¤   ¤   /*
e16440 ¤   ¤   ¤   ·* now, replace the unneeded bytes with ='s
748753 ¤   ¤   ¤   ·*/
f4f49d ¤   ¤   ¤   sixFourSpot[-1] = '=';
e8ed18 ¤   ¤   ¤   if (e64->partialCount==1) sixFourSpot[-2] = '=';
--b792 00091dff2b2401101d7 Page 4 of ENCODING.CPP
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
137d89 ¤   e64->bytesOnLine = bpl;¤/* copy back to state buffer */
1caf5a
6724b8 ¤   return (sixFourSpot - sixFourPtr);
beefe6 }
3daf5a
cfe6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5baf5a
8138e5 /*
a93695 ·* ·Convert base64 data to binary
f7775e ·*
dc6a22 ·* ·Args:
81612c ·* ··sixFourPtr [IN] ····the base64 data (or nil to close decoder)
1d00b5 ·* ··sixFourLen [IN] ····the length of the base64 data
34bb0a ·* ··binPtr ····[IN] ····pointer to buffer to hold binary data
8cc42f ·* ··d64 ·······[IN/OUT] pointer to decoder state; caller must preserve
8d01f8 ·* ··decErrCnt ·[OUT] ···the number of decoding errors found
c8775e ·*
f97f6c ·* ·Returns: The length of the binary data
55495d ·*/
9bfad0 long Decode64(
5f008b ¤   char *sixFourPtr,
4283a0 ¤   long sixFourLen,
c166b0 ¤   char *binPtr,
1fcc7c ¤   Dec64Ptr d64,
082eab ¤   long *decErrCnt)
97bb36 {
ef113f ¤   short ¤ decode;¤¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   /* the deco¶
299fdb ded short */
207772 ¤   unsigned char ¤ ¤   c;¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¶
b8c0be ¤   ¤   /* the decoded byte */
7cbc26 ¤   /* we separate the short & the byte to the compiler can worry about byteord¶
e760fe er */
b24719 ¤   char *end = sixFourPtr + sixFourLen;¤   /* stop decoding here */
6625a8 ¤   char *binSpot = binPtr;¤¤   ¤   ¤   ¤   ¤   ¤   ¤   /* current output chara¶
624715 cter */
058df9 ¤   short ¤ decoderState;¤  ¤   /* which of 4 bytes are we seeing now? */
965724 ¤   long ¤  ¤   invalCount;¤¤   ¤   /* how many bad chars found this time aroun¶
a5d983 d? */
efbecc ¤   long ¤  ¤   padCount;¤  ¤   ¤   ¤   /* how many pad chars found so far? */
294073 ¤   unsigned char ¤ ¤   partial;¤   ¤   ¤   ¤   /* partially decoded byte from/¶
3710b0 for last/next time */
8ac731 ¤   short wasCR;
93f5ce ¤   char *sixFourStartPtr;
8267c5 ¤
93d8af ¤   /*
501817 ¤   ·* fetch state from caller's buffer
c5a4e3 ¤   ·*/
df4201 ¤   decoderState = d64->decoderState;
103dd3 ¤   invalCount = 0;¤/* we'll add the invalCount to the buffer later */
0bf97a ¤   padCount = d64->padCount;
ab078b ¤   partial = d64->partial;
a57729 ¤   wasCR = d64->wasCR;
0d67c5 ¤
75aa43 ¤   if (sixFourLen)
58c7a1 ¤   {
345799 ¤   ¤   sixFourStartPtr = sixFourPtr;
81f0bd ¤   ¤   for (;sixFourPtr<end;sixFourPtr++)
905b34 ¤   ¤   {
5d5e84 ¤   ¤   ¤   switch(decode=g64DecodeArr[*sixFourPtr])
a6f776 ¤   ¤   ¤   {
ab31ac ¤   ¤   ¤   ¤   case SKIP: break;¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   /* skip whi¶
321692 tespace */
63af96 ¤   ¤   ¤   ¤   case FAIL: invalCount++; break;¤¤   /* count invalid characters¶
d1495d ·*/
af03a4 ¤   ¤   ¤   ¤   case PAD: padCount++; break;¤   ¤   ¤   /* count pad characters¶
47495d ·*/
8c6ab9 ¤   ¤   ¤   ¤   default:
faa3e7 ¤   ¤   ¤   ¤   ¤   /*
911b13 ¤   ¤   ¤   ¤   ¤   ·* found a non-pad character, so if we had previously found¶
--8655 000cba2471c401101d7 Page 5 of ENCODING.CPP
1ad71d ·a pad,
668621 ¤   ¤   ¤   ¤   ¤   ·* that pad was an error
48ec4b ¤   ¤   ¤   ¤   ·¤  */
187185 ¤   ¤   ¤   ¤   ¤   if (padCount) {invalCount+=padCount;padCount=0;}
a6ae30 ¤   ¤   ¤   ¤   ¤
53a3e7 ¤   ¤   ¤   ¤   ¤   /*
e5c187 ¤   ¤   ¤   ¤   ¤   ·* extract the right bits
6a6ad4 ¤   ¤   ¤   ¤   ¤   ·*/
67b1c6 ¤   ¤   ¤   ¤   ¤   c = (char) decode;
2e6a1a ¤   ¤   ¤   ¤   ¤   switch (decoderState)
094859 ¤   ¤   ¤   ¤   ¤   {
5c5463 ¤   ¤   ¤   ¤   ¤   ¤   case 0:
0396b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   partial = c<<2;
4d3f27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState++;
0a8c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
610ebf ¤   ¤   ¤   ¤   ¤   ¤   case 1:
b5c42a ¤   ¤   ¤   ¤   ¤   ¤   ¤   *binSpot++ = partial|Top4(c);
594730 ¤   ¤   ¤   ¤   ¤   ¤   ¤   partial = Bot4(c)<<4;
be3f27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState++;
df8c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
54e1db ¤   ¤   ¤   ¤   ¤   ¤   case 2:
0ccc7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   *binSpot++ = partial|Top6(c);
c05697 ¤   ¤   ¤   ¤   ¤   ¤   ¤   partial = Bot2(c)<<6;
633f27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState++;
e18c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
13bb07 ¤   ¤   ¤   ¤   ¤   ¤   case 3:
9b1496 ¤   ¤   ¤   ¤   ¤   ¤   ¤   *binSpot++ = partial|c;
5e1b2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState=0;
b98c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
e80a52 ¤   ¤   ¤   ¤   ¤   } /* switch decoderState */
d242e8 ¤   ¤   ¤   } /* switch decode */
cf32e7 ¤   ¤   } /* for sixFourPtr */
48d0ed ¤   } /* if sixFourLen */
2b0e24 ¤   else
5dc7a1 ¤   {
dc1b17 ¤   ¤   /*
d3e193 ¤   ¤   ·* all done. ·Did all end up evenly?
419de3 ¤   ¤   ·*/
738e8f ¤   ¤   switch (decoderState)
935b34 ¤   ¤   {
a075ac ¤   ¤   ¤   case 0:
67258b ¤   ¤   ¤   ¤   invalCount += padCount;¤¤   /* came out evenly, so should be no¶
bff920 ·pads */
d1f622 ¤   ¤   ¤   ¤   break;
eb2f70 ¤   ¤   ¤   case 1:
b3c24d ¤   ¤   ¤   ¤   invalCount++;¤  ¤   ¤   ¤   ¤   ¤   ¤   /* data missing */
f510b1 ¤   ¤   ¤   ¤   invalCount += padCount;¤¤   /* since data missing; should be no¶
5af920 ·pads */
d8f622 ¤   ¤   ¤   ¤   break;
07c014 ¤   ¤   ¤   case 2:
fac4ab ¤   ¤   ¤   ¤   invalCount += ABS(padCount-2);¤ /* need exactly 2 pads */
a2f622 ¤   ¤   ¤   ¤   break;
009ac8 ¤   ¤   ¤   case 3:
668b4c ¤   ¤   ¤   ¤   invalCount += ABS(padCount-1);¤ /* need exactly 1 pad */
f5f622 ¤   ¤   ¤   ¤   break;
140fe4 ¤   ¤   }
189371 ¤   }
7a67c5 ¤
fdd8af ¤   /*
9334d3 ¤   ·* save state in caller's buffer
9ba4e3 ¤   ·*/
efbf77 ¤   d64->decoderState = decoderState;
253bca ¤   d64->invalCount += invalCount;
57d820 ¤   d64->padCount = padCount;
44d1c4 ¤   d64->partial = partial;
f1f1f6 ¤   d64->wasCR = wasCR;
59af5a
e74fd1 ¤   *decErrCnt = invalCount;
afaf5a
7c4ca1 ¤   return (binSpot - binPtr);
c3efe6 }
cbaf5a
--bb04 0008286addc401101d7 Page 6 of ENCODING.CPP
c8c067 /*****************************************************************************/
77505f /* ·····················Q U O T E D - P R I N T A B L E ·····················*/
3ec067 /*****************************************************************************/
16af5a
e87890 /* ------------------------------------------------------------------------- */
57ecde /* NOTE: To handle BINARY data, you must always quote newline characters, ···*/
2a620c /* ··this implementation assumes TEXT data and thus does not encode newlines */
e07890 /* ------------------------------------------------------------------------- */
88af5a
7b38e5 /*
0f21a9 ·* ·Convert binary data to quoted-printable
4f775e ·*
d56a22 ·* ·Args:
64083e ·* ··pBin ····[IN] ····the binary data (or NULL to close the encoder)
434398 ·* ··nLen ····[IN] ····the length of the binary data (or 0 to close the encoder)
8c77a2 ·* ··pQP ·····[IN] ····pointer to buffer for the quoted-printable data
b6acf0 ·* ··eQPstate [IN/OUT] state; caller must preserve
4c775e ·*
525abf ·* ·Returns: The length of the quoted-printable data
cc495d ·*/
dad7d3 long EncodeQP(
fca8e1 ¤   char *pBin,
1cd5f6 ¤   long nLen,
994e49 ¤   char *pQP,
065185 ¤   EncQPPtr eQPstate)
14bb36 {
185d14 ¤   /* These characters are legal to leave UNQUOTED, everything else must be qu¶
14f3af oted */
bc90d7 ¤   const char *gQPEncodeChars
16e90c ¤   ¤   = "\t\n\r %&'()*+,-./0123456789:;<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefgh¶
239c4b ijklmnopqrstuvwxyz";
9faf5a
e11a88 ¤   /* The hex digits -- in order */
741818 ¤   const char *pHexArr = "0123456789ABCDEF";
db1826 ¤   const char *pQPStart = pQP; /* Remember the start pos */
ddebe2 ¤   char *pEnd, ch, cLastChar;
aaa283 ¤   int nLineChars, bEncode;
1aaf5a
b4f3b5 ¤   /* Check if this call is to close the encoding */
a618c3 ¤   if ((pBin == NULL) || (nLen < 1))
1fc7a1 ¤   {
1dab04 ¤   ¤   /* If there is anything on the current line, cap it with an equal */
e61911 ¤   ¤   /* This avoids having trailing whitespace that would be ignored */
aadc03 ¤   ¤   /* Newline is added for good measure, because we assume TEXT, this */
4636dc ¤   ¤   /* ·shouldn't be a problem */
e1abc3 ¤   ¤   if ((eQPstate->nCurLineLen) > 0)
b85b34 ¤   ¤   {
7df9d4 ¤   ¤   ¤   *pQP++ = '=';
661b89 ¤   ¤   ¤   pQP = newline_copy(pQP);
8aaf5a
47d892 ¤   ¤   ¤   eQPstate->nCurLineLen = 0;
f7f898 ¤   ¤   ¤   return (pQP - pQPStart);
d20fe4 ¤   ¤   }
42af5a
81f109 ¤   ¤   return (0);
b29371 ¤   }
b7af5a
276ff4 ¤   /* Restore the state from the caller data */
b9ba5d ¤   nLineChars = eQPstate->nCurLineLen;
ee846a ¤   cLastChar = eQPstate->cLastChar;
92af5a
5103f0 ¤   /* Loop through the binary data */
328d48 ¤   for (pEnd = pBin + nLen; pBin < pEnd; pBin++)
4fc7a1 ¤   {
93fdd7 ¤   ¤   /* Check if the binary character must be encoded */
f0fe61 ¤   ¤   bEncode = (strchr(gQPEncodeChars, (ch = *pBin)) ? 0 : 1);
81af5a
5a6451 ¤   ¤   /* Will this action put us past the 76 char limit? */
b32427 ¤   ¤   if ((nLineChars + (bEncode ? 3 : 1)) > 76)
d35b34 ¤   ¤   {
20c391 ¤   ¤   ¤   /* Cap the line, and add a newline */
82f9d4 ¤   ¤   ¤   *pQP++ = '=';
--b6c9 0004f668698401101d7 Page 7 of ENCODING.CPP
a71b89 ¤   ¤   ¤   pQP = newline_copy(pQP);
9baf5a
0251a3 ¤   ¤   ¤   nLineChars = 0; /* Starting new line */
350fe4 ¤   ¤   }
a7af5a
9deff4 ¤   ¤   if (bEncode) /* Encode the character using hex (ie. "A" -> "=41") */
875b34 ¤   ¤   {
79f9d4 ¤   ¤   ¤   *pQP++ = '=';
cc9385 ¤   ¤   ¤   *pQP++ = pHexArr[(ch>>4) & 0xF];
a58279 ¤   ¤   ¤   *pQP++ = pHexArr[ch & 0xF];
6187c7 ¤   ¤   ¤
fc68cf ¤   ¤   ¤   nLineChars += 3;
190fe4 ¤   ¤   }
da6a6f ¤   ¤   else /* No encoding needed, just copy character over */
c15b34 ¤   ¤   {
e0e92a ¤   ¤   ¤   *pQP++ = ch;
54af5a
789601 ¤   ¤   ¤   /* If we copied a newline, then we need to reset the line char coun¶
c4c850 t */
61983a ¤   ¤   ¤   if (newline_test(cLastChar, ch))
939026 ¤   ¤   ¤   ¤   nLineChars = 0;
f0bb8c ¤   ¤   ¤   else
21f2b9 ¤   ¤   ¤   ¤   nLineChars++;
550fe4 ¤   ¤   }
1caf5a
cb8e0c ¤   ¤   /* Keep track of the last character */
a03545 ¤   ¤   cLastChar = ch;
9e9371 ¤   }
67af5a
17f3ae ¤   /* Save the state */
b5cc0c ¤   eQPstate->nCurLineLen = nLineChars;
caf971 ¤   eQPstate->cLastChar = cLastChar;
8aaf5a
34eba4 ¤   /* Return the number of characters we but in the buffer */
657ea6 ¤   return (pQP - pQPStart);
6befe6 }
26af5a
a3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
c6af5a
e138e5 /*
a62a8e ·* ·Convert quoted printable data to binary
6f775e ·*
326a22 ·* ·Args:
b360c8 ·* ··pQP ······[IN] ····the quoted printable data (or NULL to close the decoder)
628ca3 ·* ··nLen ·····[IN] ····the length of the quoted printable data (or 0 to close ¶
dfad5a the decoder)
a72c5b ·* ··pBin ·····[IN] ····pointer to buffer to hold binary data
238301 ·* ··dQPstate ·[IN/OUT] pointer to decoder state; caller must preserve
125838 ·* ··decErrCnt [OUT] ···the number of decoding errors found
41775e ·*
847f6c ·* ·Returns: The length of the binary data
a6495d ·*/
aa5239 long DecodeQP(
0a4e49 ¤   char *pQP,
61d5f6 ¤   long nLen,
d8a8e1 ¤   char *pBin,
d66e24 ¤   DecQPPtr dQPstate,
cd2eab ¤   long *decErrCnt)
93bb36 {
494f10 ¤   const char *pBinStart = pBin;
4d5350 ¤   char *pEnd, ch;
3267c5 ¤
dd05da ¤   /* Restore the state from the caller */
8492ca ¤   QPStates CurState = dQPstate->CurState;
042e28 ¤   char cLastChar = dQPstate->cLastChar;
a9af5a
d534f9 ¤   /* Check if this call is to close the decoding */
1867ae ¤   if ((pQP == NULL) || (nLen < 1))
48c7a1 ¤   {
e53ee9 ¤   ¤   /* If the state is in the middle of doing something, then error */
d7a4ee ¤   ¤   if ((CurState == qpEqual) || (CurState == qpEncoded))
4f5b34 ¤   ¤   {
--0ad9 000b53bb80b401101d7 Page 8 of ENCODING.CPP
a2d216 ¤   ¤   ¤   (*decErrCnt)++;
a6f1a2 ¤   ¤   ¤   CurState = qpNormal;
cf0fe4 ¤   ¤   }
5eaf5a
91f109 ¤   ¤   return (0);
dc9371 ¤   }
5aaf5a
defdc3 ¤   /* Loop through the QP data */
7136f9 ¤   for (pEnd = pQP + nLen; pQP < pEnd; pQP++)
78c7a1 ¤   {
d65f26 ¤   ¤   /* Get the current character */
c30bae ¤   ¤   ch = *pQP;
aeaf5a
69d611 ¤   ¤   /* What state are we in? */
d70315 ¤   ¤   switch (CurState)
305b34 ¤   ¤   {
8577f4 ¤   ¤   ¤   case qpNormal: /* Normal: copy everything until an 'equal' */
90475c ¤   ¤   ¤   ¤   if (ch == '=')
3615a6 ¤   ¤   ¤   ¤   ¤   CurState = qpEqual; /* Found an 'equal' char */
6ffa07 ¤   ¤   ¤   ¤   else
172e36 ¤   ¤   ¤   ¤   ¤   *pBin++ = ch;
96cdcb ¤   ¤   ¤   break;
04ae30 ¤   ¤   ¤   ¤   ¤
b8204c ¤   ¤   ¤   case qpEqual: /* qpEqual: Last char was an equal */
bada32 ¤   ¤   ¤   ¤   if (isxdigit(ch)) ····················/* This char should be a ¶
7b110d hex digit */
05497f ¤   ¤   ¤   ¤   ¤   CurState = qpEncoded;
aaeb9e ¤   ¤   ¤   ¤   else if (newline_test(cLastChar, ch)) /* Or it could be a newli¶
30c947 ne */
50c927 ¤   ¤   ¤   ¤   ¤   CurState = qpNormal;
8f3af9 ¤   ¤   ¤   ¤   else if (isspace(ch)) ················/* Or some whitespace bef¶
a7248d ore the newline */
23f287 ¤   ¤   ¤   ¤   ¤   CurState = qpTrailingWhitespace;
26fa07 ¤   ¤   ¤   ¤   else
6f0956 ¤   ¤   ¤   ¤   ¤   CurState = qpError; ··············/* Otherwise, an error */
69cdcb ¤   ¤   ¤   break;
b82b85 ¤   ¤   ¤   ¤
5c9772 ¤   ¤   ¤   case qpEncoded: /* qpEncoded: Last char was the first hex digit of ¶
fb47e7 an encoding */
ede03a ¤   ¤   ¤   ¤   if ((isxdigit(ch)) && (isxdigit(cLastChar)))
cc72c3 ¤   ¤   ¤   ¤   {
e9ecd5 ¤   ¤   ¤   ¤   ¤   int left = hex2dec(cLastChar);
030882 ¤   ¤   ¤   ¤   ¤   int right = hex2dec(ch);
1f1f27 ¤   ¤   ¤   ¤   ¤   int leftshift = left << 4;
82ad9f ¤   ¤   ¤   ¤   ¤   int final = leftshift | right;
aec094 ¤   ¤   ¤   ¤   ¤   /* Decode the hex digits into a character */
844aa5 ¤   ¤   ¤   ¤   ¤   *pBin++ = final;
63c927 ¤   ¤   ¤   ¤   ¤   CurState = qpNormal;
772613 ¤   ¤   ¤   ¤   }
7efa07 ¤   ¤   ¤   ¤   else
e97342 ¤   ¤   ¤   ¤   ¤   CurState = qpError; /* This char is not a hex digit: an err¶
4049f0 or */
59cdcb ¤   ¤   ¤   break;
37af5a
179b35 ¤   ¤   ¤   case qpTrailingWhitespace: /* qpTrailingWhitespace: whitespace is a¶
974a1c llowed after */
98cc91 ¤   ¤   ¤   ¤   ·······················/* ·an equals and before the newline */
6ccaa7 ¤   ¤   ¤   ¤   if (newline_test(cLastChar, ch))
248374 ¤   ¤   ¤   ¤   ¤   CurState = qpNormal; /* When we find the newline, don't cop¶
d72d6b y it */
d7dbb8 ¤   ¤   ¤   ¤   else if (!isspace(ch))
8a13e4 ¤   ¤   ¤   ¤   ¤   CurState = qpError; /* If we get to some char BEFORE a newl¶
37cd13 ine: an error */
06cdcb ¤   ¤   ¤   break;
950fe4 ¤   ¤   }
66af5a
a90656 ¤   ¤   if (CurState == qpError) /* Count the errors, reset to normal state (ke¶
f16026 ep trying) */
d15b34 ¤   ¤   {
23d216 ¤   ¤   ¤   (*decErrCnt)++;
13f1a2 ¤   ¤   ¤   CurState = qpNormal;
b50fe4 ¤   ¤   }
--f5f4 000a61ba14c401101d7 Page 9 of ENCODING.CPP
e0af5a
418e0c ¤   ¤   /* Keep track of the last character */
4d3545 ¤   ¤   cLastChar = ch;
b29371 ¤   }
a5af5a
575d67 ¤   /* Save the state for next time */
1c8261 ¤   dQPstate->CurState = CurState;
1bb912 ¤   dQPstate->cLastChar = cLastChar;
faaf5a
30eba4 ¤   /* Return the number of characters we but in the buffer */
f5c084 ¤   return (pBin - pBinStart);
46efe6 }
d2af5a
4ee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
fcaf5a
1a38e5 /*
3ea1b7 ·* ·Parse Content-Transer-Encoding header line
26775e ·*
676a22 ·* ·Args:
1d860b ·* ··src [IN] Valid Transfer-Encoding header.
72775e ·*
9db353 ·* ·Returns: enumerated integer 'TrEncType' type specifying CTE.
e3495d ·*/
e351d6 TrEncType rfc822_parse_cte(const char *src)
5abb36 {
9be05b ¤   const char *kPrefixStr = "Content-Transfer-Encoding:";
da1c27 ¤   const unsigned int kPrefixStrLen = strlen(kPrefixStr);
f9af5a
c73d3a ¤   char *cp = (char *) src + kPrefixStrLen, *mechanism = NULL;
604d2c ¤   TrEncType cte = CTE_Error;
71af5a
454eb8 ¤   // Check prefix
7272d2 ¤   if (strnicmp(src, kPrefixStr, kPrefixStrLen) == 0)
d4c7a1 ¤   {
cb00d1 ¤   ¤   // Get first token (skips whitespace/comments)
0fc513 ¤   ¤   mechanism = rfc822_extract_token(&cp);
11af5a
a5a983 ¤   ¤   // If we got something
6d4ac8 ¤   ¤   if ((mechanism) && (strlen(mechanism) > 0))
f05b34 ¤   ¤   {
080cca ¤   ¤   ¤   if (stricmp(mechanism, "base64") == 0)
dbf9a6 ¤   ¤   ¤   ¤   cte = CTE_Base64;
9c1c4a ¤   ¤   ¤   else if (stricmp(mechanism, "quoted-printable") == 0)
be20ce ¤   ¤   ¤   ¤   cte = CTE_QP;
bb202c ¤   ¤   ¤   else if (stricmp(mechanism, "7bit") == 0)
fead59 ¤   ¤   ¤   ¤   cte = CTE_7bit;
1a1507 ¤   ¤   ¤   else if (stricmp(mechanism, "8bit") == 0)
2290d0 ¤   ¤   ¤   ¤   cte = CTE_8bit;
7c3ddf ¤   ¤   ¤   else if (stricmp(mechanism, "binary") == 0)
a7e067 ¤   ¤   ¤   ¤   cte = CTE_Binary;
8b0fe4 ¤   ¤   }
06af5a
67e106 ¤   ¤   safefree(mechanism);
c99371 ¤   }
06af5a
8424d5 ¤   return (cte);
7defe6 }
a4af5a
4ae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b0af5a
ee38e5 /*
49a8b7 ·* ·Create Content-Transer-Encoding header line
e7775e ·*
a9322b ·* ·NOTE: The user of this function is responsible for freeing the
a6c8a5 ·* ·······returned string.
ba775e ·*
f26a22 ·* ·Args:
006981 ·* ··mechanism [IN] Enumerated integer 'TrEncType' type specifying CTE.
06775e ·*
8781c9 ·* ·Returns: Content tranfer encoding header line string.
d4495d ·*/
a6b631 char *rfc822_make_cte(TrEncType mechanism)
--34d7 000c8bcb006401101d7 Page 10 of ENCODING.CPP
2cbb36 {
63f526 ¤   const char *kPrefix = "Content-Transfer-Encoding: ";
802c83 ¤   char pBuf[40], *pCTE;
65af5a
7bdfbc ¤   switch (mechanism)
88c7a1 ¤   {
7d2c9f ¤   ¤   case CTE_Base64:¤   strcpy(pBuf, "base64");¤¤   ¤   ¤   break;
550af4 ¤   ¤   case CTE_QP:¤   ¤   strcpy(pBuf, "quoted-printable");¤  break;
f70a84 ¤   ¤   case CTE_7bit:¤ ¤   strcpy(pBuf, "7bit");¤  ¤   ¤   ¤   break;
c320ba ¤   ¤   case CTE_8bit:¤ ¤   strcpy(pBuf, "8bit");¤  ¤   ¤   ¤   break;
d16038 ¤   ¤   case CTE_Binary:¤   strcpy(pBuf, "binary");¤¤   ¤   ¤   break;
d0af5a
189ae3 ¤   ¤   default:
ec62c0 ¤   ¤   ¤   return (NULL);
3c9371 ¤   }
9faf5a
9b2d4f ¤   pCTE = (char *) malloc(strlen(pBuf) + strlen(kPrefix) + 1);
8f91b5 ¤   strcpy(pCTE, kPrefix);
827f32 ¤   strcat(pCTE, pBuf);
6caf5a
b1a6ea ¤   return (pCTE);
5aefe6 }
82af5a
9ce6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4eaf5a
3038e5 /*
81f7b2 ·* ·Finds and extracts the content transfer encoding header line from a full
f42bdb ·* ·multi-lined header. All unfolding (removing newlines) is done before
6dc4e2 ·* ·header line is returned.
cc775e ·*
67322b ·* ·NOTE: The user of this function is responsible for freeing the
9ac8a5 ·* ·······returned string.
4b775e ·*
946a22 ·* ·Args:
170990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
71775e ·*
6fd4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
4e495d ·*/
b12283 char *rfc822_extract_cte(const char *pFullHeader)
6cbb36 {
ba1665 ¤   return rfc822_extract_header(pFullHeader, "Content-Transfer-Encoding:");
5eefe6 }
24af5a
7a60e8 /* ========================================================================== */
43f935 /* ·····························LOCAL FUNCTIONS ······························*/
7360e8 /* ========================================================================== */
06af5a
0cfb1a /* ·NEWLINE STUFF: Used locally to copy and test for newlines ·*/
1c5ab1 static const char gNewlineCh1 = '\r';
7a7a4d static const char gNewlineCh2 = '\n';
fbaf5a
47e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
41af5a
879c08 /* Insert a newline, returning position after newline */
ff8dff /* static */ char *newline_copy(char *dst)
09bb36 {
ef817b ¤   *dst++ = gNewlineCh1;
1e6e1f ¤   *dst++ = gNewlineCh2;
4daf5a
f19f8e ¤   return dst;
5eefe6 }
5faf5a
6ae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
e5af5a
6307f2 /* Check if these two characters represent a newline */
31f82c /* static */ int newline_test(const char prev, const char curr)
22bb36 {
789120 ¤   return ((prev == gNewlineCh1) && (curr == gNewlineCh2));
e1efe6 }
8eaf5a
6be6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
c8af5a
--2a5d 0015e569042401101d7 Page 11 of ENCODING.CPP
c25177 /* Convert a single HEX character-digit (0123456789ABCDEF) to the decimal */
52c724 /* value. ·NOTE: This function assumes the character is a valid hex digit */
ea6ce7 /* static */ int hex2dec(const char ch)
41bb36 {
ac8588 ¤   if (isdigit(ch))
1242a7 ¤   ¤   return (ch -'0');
08af5a
7d1aae ¤   return ((toupper(ch) - 'A') + 10);
88efe6 }
5eaf5a
--f9df 000ddbcec80401101d8 Page 1 of ENCODING.H
bc38e5 /*
288ba0 ·* ·Functions to encode and decode using BASE64 or Quoted-Printable
aab5e8 ·* ·Also a transfer-encoding header line parser
e1775e ·*
5eff93 ·* ·Filename: encoding.h
5f775e ·*
2aa235 ·* ·Last Edited: September 24, 1996
56775e ·*
03005b ·* ·Author: Scott Manjourides
d3775e ·*
24cbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
4aea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
1b775e ·*
f3c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
95775e ·*
f9495d ·*/
94af5a
31c2f3 #ifndef EMS_ENCODING_H
579502 #define EMS_ENCODING_H
52af5a
6838e5 /*
e5608c ·* state buffer for base64 encoding. Initialize all values to zero.
a4495d ·*/
dbf0f7 typedef struct {
969664 ¤   unsigned char partial[4];
8d0bae ¤   short partialCount;
f1d048 ¤   short bytesOnLine;
ef01d1 } Enc64, *Enc64Ptr;
9aaf5a
e438e5 /*
b19dc5 ·* state buffer for base64 decoding. Initialize all values to zero.
f9495d ·*/
4ff0f7 typedef struct {
125627 ¤   short decoderState;¤¤   /* which of 4 bytes are we seeing now? */
5b6b4a ¤   long invalCount;¤   ¤   /* how many bad chars found so far? */
148cce ¤   long padCount;¤ ¤   ¤   /* how many pad chars found so far? */
061dec ¤   unsigned char partial;/* partially decoded byte from/for last/next time */
128a0b ¤   short wasCR;¤   ¤   ¤   /* was the last character a carriage return? */
1dccb5 } Dec64, *Dec64Ptr;
2aaf5a
c638e5 /*
560435 ·* used internally to track parsing state
78495d ·*/
0aed84 typedef enum {
fcb952 ¤   qpNormal,
78ee23 ¤   qpEqual,
1dbc2c ¤   qpEncoded,
323baf ¤   qpTrailingWhitespace,
7a7430 ¤   qpError
51a3f1 } QPStates;
2daf5a
4c38e5 /*
ab2e65 ·* state buffer for QP encoding. Initialize all values to zero.
84495d ·*/
0cf0f7 typedef struct {
ca6ab0 ¤   int nCurLineLen; /* Number of characters outputed to current line */
6aec41 ¤   char cLastChar; ·/* Last character read in */
81c694 } EncQP, *EncQPPtr;
50af5a
3f38e5 /*
c67701 ·* state buffer for QP decoding. Initialize CurState to qpNormal.
97495d ·*/
93f0f7 typedef struct {
8ab5da ¤   QPStates CurState;
84a22f ¤   char cLastChar;
d00bf0 } DecQP, *DecQPPtr;
7caf5a
2c38e5 /*
ed1b8c ·* Valid return values for rfc822_parse_cte which specify the trasnfer
282cc6 ·* encoding found in the parsed header line
2a495d ·*/
dded84 typedef enum {
--43cb 000f7d1de15401101d8 Page 2 of ENCODING.H
f3b8c4 ¤   CTE_Error,
14b60f ¤   CTE_Base64,
deadd7 ¤   CTE_QP,
a2fc24 ¤   CTE_7bit,
1cc1ad ¤   CTE_8bit,
2cafce ¤   CTE_Binary,
0cd77a ¤   CTE_NONE
2bf804 } TrEncType;
28af5a
f4c067 /*****************************************************************************/
330aa1 /* ·······························B A S E 6 4 ·······························*/
f4c067 /*****************************************************************************/
c0af5a
2e38e5 /*
51f752 ·* ·Convert binary data to base64
ad775e ·*
296a22 ·* ·Args:
82d736 ·* ··binPtr ····[IN] ····the binary data (or NULL to close encoder)
b5229f ·* ··binLen ····[IN] ····the length of the binary data
fc967e ·* ··sixFourPtr [IN] ····pointer to buffer for the base64 data
33322c ·* ··e64 ·······[IN/OUT] state; caller must preserve
67775e ·*
394185 ·* ·Returns: The length of the base64 data
0d495d ·*/
a30c3d long Encode64(char *bin, long len, char *sixFour, Enc64Ptr e64);
3faf5a
1f38e5 /*
d43695 ·* ·Convert base64 data to binary
6b775e ·*
4b6a22 ·* ·Args:
d3612c ·* ··sixFourPtr [IN] ····the base64 data (or nil to close decoder)
b100b5 ·* ··sixFourLen [IN] ····the length of the base64 data
3dbb0a ·* ··binPtr ····[IN] ····pointer to buffer to hold binary data
fdc42f ·* ··d64 ·······[IN/OUT] pointer to decoder state; caller must preserve
2001f8 ·* ··decErrCnt ·[OUT] ···the number of decoding errors found
ad775e ·*
f47f6c ·* ·Returns: The length of the binary data
51495d ·*/
fe31ee long Decode64(char *sixFour,·
4b68c6 ¤   ¤   ¤   ··long sixFourLen,·
3edcbb ¤   ¤   ¤   ··char *bin, Dec64Ptr d64,·
ebf3d4 ¤   ¤   ¤   ··long *decErrCnt);
06af5a
fec067 /*****************************************************************************/
50505f /* ·····················Q U O T E D - P R I N T A B L E ·····················*/
65c067 /*****************************************************************************/
5daf5a
ae7890 /* ------------------------------------------------------------------------- */
f6ecde /* NOTE: To handle BINARY data, you must always quote newline characters, ···*/
40620c /* ··this implementation assumes TEXT data and thus does not encode newlines */
bf7890 /* ------------------------------------------------------------------------- */
91af5a
ae38e5 /*
9121a9 ·* ·Convert binary data to quoted-printable
e6775e ·*
636a22 ·* ·Args:
1a083e ·* ··pBin ····[IN] ····the binary data (or NULL to close the encoder)
cd25aa ·* ··nLen ····[IN] ····the length of the binary data·
8adbac ¤   ¤   ¤   ¤   ¤   ¤   (or 0 to close the encoder)
6f77a2 ·* ··pQP ·····[IN] ····pointer to buffer for the quoted-printable data
6dacf0 ·* ··eQPstate [IN/OUT] state; caller must preserve
da775e ·*
145abf ·* ·Returns: The length of the quoted-printable data
40495d ·*/
ff27ab long EncodeQP(char *bin, long len, char *qp, EncQPPtr eQP);
c1af5a
9f38e5 /*
932a8e ·* ·Convert quoted printable data to binary
db775e ·*
b16a22 ·* ·Args:
494771 ·* ··pQP ······[IN] ····the quoted printable data·
f732c4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (or NULL to close the decoder)
--e224 00184918890401101d8 Page 3 of ENCODING.H
7acb8f ·* ··nLen ·····[IN] ····the length of the quoted printable data·
ff6491 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (or 0 to close the decoder)
eb2c5b ·* ··pBin ·····[IN] ····pointer to buffer to hold binary data
3b8301 ·* ··dQPstate ·[IN/OUT] pointer to decoder state; caller must preserve
935838 ·* ··decErrCnt [OUT] ···the number of decoding errors found
18775e ·*
447f6c ·* ·Returns: The length of the binary data
a8495d ·*/
7f332e long DecodeQP(char *qp, long qpLen, char *bin, DecQPPtr dqp, long *decErrCnt);
50af5a
38c067 /*****************************************************************************/
23a2a4 /* ····························CTE ··P A R S E R ····························*/
f0c067 /*****************************************************************************/
58af5a
bf38e5 /*
21a1b7 ·* ·Parse Content-Transer-Encoding header line
86775e ·*
346a22 ·* ·Args:
41860b ·* ··src [IN] Valid Transfer-Encoding header.
6a775e ·*
501218 ·* ·Returns: enumerated integer 'TrEncType' type specifying CTE (see above).
42495d ·*/
49b3ca TrEncType rfc822_parse_cte(const char *src);
f1af5a
c938e5 /*
6ea8b7 ·* ·Create Content-Transer-Encoding header line
de775e ·*
6f322b ·* ·NOTE: The user of this function is responsible for freeing the
b9c8a5 ·* ·······returned string.
81775e ·*
716a22 ·* ·Args:
626981 ·* ··mechanism [IN] Enumerated integer 'TrEncType' type specifying CTE.
cc775e ·*
7181c9 ·* ·Returns: Content tranfer encoding header line string.
7e495d ·*/
f0209c char *rfc822_make_cte(TrEncType mechanism);
4daf5a
d038e5 /*
46f7b2 ·* ·Finds and extracts the content transfer encoding header line from a full
132bdb ·* ·multi-lined header. All unfolding (removing newlines) is done before
24c4e2 ·* ·header line is returned.
45775e ·*
9c322b ·* ·NOTE: The user of this function is responsible for freeing the
d7c8a5 ·* ·······returned string.
ab775e ·*
6c6a22 ·* ·Args:
520990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
81775e ·*
dfd4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
33495d ·*/
47b691 char *rfc822_extract_cte(const char *pFullHeader);
04af5a
84a763 #endif /* EMS_ENCODING_H */
--915d 00025525f15401101d9 Page 1 of MIMETYPE.CPP
bc38e5 /*
8820c2 ·* ·Functions to manage emsMIMEtype structures
af12c6 ·* ·for use with Eudora EMS API under MS Windows.
34775e ·*
5d187c ·* ·Filename: mimetype.cpp
11775e ·*
01e658 ·* ·Last Edited: Wednesday, October 2, 1996
12775e ·*
4b005b ·* ·Author: Scott Manjourides
cd775e ·*
b1ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
ef775e ·*
a0c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
d1495d ·*/
14af5a
155655 #include <windows.h>
17324c #include <string.h>
1b5e84 #include <malloc.h>
0eaf5a
44fbd1 #include "ems-win.h"
c8f10b #include "mimetype.h"
6b6bd2 #include "rfc822.h"
85af5a
dbbb9a //extern "C" {
44af5a
586ab5 /* ======================================================================= */
ecaf5a
b80bf8 #define safefree(p) { if (p) { free(p); p = NULL; } }
0faf5a
b96ab5 /* ======================================================================= */
4aaf5a
0bb42b static void free_param_type(emsMIMEParamP paramPtr);
25af5a
8e6ab5 /* ======================================================================= */
4caf5a
4b38e5 /*
3385ce ·* ·Create an emsMIMEtype structure to hold MIME information. Only the
5266cf ·* ·type and subtype are set here, use add_mime_parameter() to add
e5f3dd ·* ·any name/value parameter pairs.
ee775e ·*
abf79f ·* ·NOTE: All input strings are COPIED before permanent use. The user
41eb22 ·* ·······of this function is responsible for calling free_mime_type()
5586a5 ·* ·······on returned structure.
fb775e ·*
486a22 ·* ·Args:
820bbc ·* ··mime_type ···[IN] the main MIME type: e.g., text, application, image
ffa734 ·* ··sub_type ····[IN] the sub type: e.g., plain, octet-stream, jpeg
a41cc3 ·* ··mime_version [IN] the MIME verion number, if NULL will default to "1.0"
0e775e ·*
d304db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
5c495d ·*/
7cfe91 emsMIMEtypeP make_mime_type(const char *mime_type,·
f6c8fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char *sub_type,·
e36224 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char *mime_version)
e9bb36 {
a20409 ¤   emsMIMEtypeP mimePtr = NULL;
1aaf5a
ee60cc ¤   mimePtr = (emsMIMEtypeP) malloc(sizeof(emsMIMEtype));
ffaf5a
f6e242 ¤   if ((mimePtr) && (mime_type) && (sub_type))
cbc7a1 ¤   {
dd1f0e ¤   ¤   mimePtr->mime_type = strdup(mime_type);
bc7bdb ¤   ¤   mimePtr->sub_type = strdup(sub_type);
37af5a
e32aeb ¤   ¤   if (mime_version)
e103fa ¤   ¤   ¤   mimePtr->mime_version = strdup(mime_version);
c90e1d ¤   ¤   else
2f91a4 ¤   ¤   ¤   mimePtr->mime_version = strdup("1.0");
97af5a
81259e ¤   ¤   mimePtr->params = NULL;
c9af5a
2529b9 ¤   ¤   if ((mimePtr->mime_type) &&·
--fd17 000fc73ec5b401101d9 Page 2 of MIMETYPE.CPP
59d562 ¤   ¤   ¤   (mimePtr->sub_type) &&·
df6566 ¤   ¤   ¤   (mimePtr->mime_version))
625b34 ¤   ¤   {
03d7ff ¤   ¤   ¤   return mimePtr;
190fe4 ¤   ¤   }
1c9371 ¤   }
deaf5a
e4f9d3 ¤   // If we get here then something went wrong
597650 ¤   // Do complete cleanup and return NULL
92af5a
a70dfb ¤   free_mime_type(mimePtr);
62af5a
0fde0a ¤   return (NULL); // ERROR
45efe6 }
27af5a
cadcd5 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
fbaf5a
b238e5 /*
5a605e ·* ·Create an emsMIMEtype structure to hold MIME information. Structure is
af65ea ·* ·initialized to values provided in RFC822 content-type header line. This
b34b95 ·* ·includes all parameter name-value pairs.
caa3b2 ·* ··
ade058 ·* ·NOTE: The user of this function is responsible for calling
da9141 ·* ·······free_mime_type() on returned structure.
1c775e ·*
a76a22 ·* ·Args:
18671c ·* ··content_type [IN] The RFC822 content-type string to parse
d8775e ·*
4b04db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
36495d ·*/
503ca1 emsMIMEtypeP parse_make_mime_type(const char *content_type)
54bb36 {
4e952d ¤   const char *kPrefixStr = "Content-Type:";
a31c27 ¤   const unsigned int kPrefixStrLen = strlen(kPrefixStr);
0baf5a
04ffaf ¤   if (strnicmp(content_type, kPrefixStr, kPrefixStrLen) != 0)
017ed2 ¤   ¤   return NULL;
58af5a
7dcb1f ¤   char *cp = (char *) content_type + kPrefixStrLen;
2f870b ¤   char *mime_type = NULL, *mime_subtype = NULL;
cfaf5a
a83ca2 ¤   mime_type = rfc822_extract_token(&cp);
0eaf5a
c3fd67 ¤   if ((strlen(mime_type) > 0) && ((*cp++) == '/'))
c9c7a1 ¤   {
8a51ba ¤   ¤   mime_subtype = rfc822_extract_token(&cp);
f6af5a
48b3d4 ¤   ¤   if (strlen(mime_subtype) > 0)
995b34 ¤   ¤   {
8958c0 ¤   ¤   ¤   // We have a type/subtype, so create emsMIMEtype structure
360a17 ¤   ¤   ¤   emsMIMEtypeP mimePtr = make_mime_type(¤ mime_type,·
7f0726 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mime_subtype,·
d25152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
9baf5a
160f39 ¤   ¤   ¤   safefree(mime_type);
20e86e ¤   ¤   ¤   safefree(mime_subtype);
b8af5a
f9ae58 ¤   ¤   ¤   if (mimePtr)
25f776 ¤   ¤   ¤   {
dfe976 ¤   ¤   ¤   ¤   char *name = NULL, *value = NULL;
ceaf5a
d2b788 ¤   ¤   ¤   ¤   do {
acaf5a
6036a7 ¤   ¤   ¤   ¤   ¤   if ((*cp++) != ';') // Skip semi-colon
5600eb ¤   ¤   ¤   ¤   ¤   ¤   break;
542b85 ¤   ¤   ¤   ¤
f22c86 ¤   ¤   ¤   ¤   ¤   if (!(name = rfc822_extract_token(&cp)))
cc00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
dfaf5a
92db5e ¤   ¤   ¤   ¤   ¤   if ((*cp++) != '=') // Skip equals
ca00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
fcaf5a
--8150 00085823b0f401101d9 Page 3 of MIMETYPE.CPP
c53708 ¤   ¤   ¤   ¤   ¤   if (!(value = rfc822_extract_token(&cp)))
2800eb ¤   ¤   ¤   ¤   ¤   ¤   break;
63af5a
356669 ¤   ¤   ¤   ¤   ¤   if ((strlen(name) > 0) && (strlen(value) > 0))
7ab960 ¤   ¤   ¤   ¤   ¤   ¤   add_mime_parameter(mimePtr, name, value);
36af5a
48964f ¤   ¤   ¤   ¤   ¤   safefree(name);
9acd44 ¤   ¤   ¤   ¤   ¤   safefree(value);
d38f3f ¤   ¤   ¤   ¤   } while (*cp);
65af5a
ff1db3 ¤   ¤   ¤   ¤   safefree(name);
96f02c ¤   ¤   ¤   ¤   safefree(value);
0faf5a
c07aa1 ¤   ¤   ¤   ¤   return mimePtr;
b2a3a6 ¤   ¤   ¤   }
1a0fe4 ¤   ¤   }
629371 ¤   }
39af5a
2ff9d3 ¤   // If we get here then something went wrong
8c97ca ¤   // Do complete cleanup
29af5a
2d8032 ¤   safefree(mime_type);
aececc ¤   safefree(mime_subtype);
85af5a
94de0a ¤   return (NULL); // ERROR
71efe6 }
1daf5a
9eb3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
80af5a
1a38e5 /*
77dd1d ·* ·Add a parameter to an existing emsMIMEtype structure. This structure
e265ad ·* ·should be created using make_mime_type().
9d775e ·*
ca97ac ·* ·NOTE: All input strings are COPIED before permanent use.
bf775e ·*
699648 ·* Args:
72d232 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be added too
e7f186 ·* ··name ···[IN] Name of the parameter
d10476 ·* ··value ··[IN] Value of the parameter
75a3b2 ·* ··
b68b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
08495d ·*/
003200 int add_mime_parameter(emsMIMEtypeP mimePtr,·
56e4b5 ¤   ¤   ¤   ¤   ¤   ···const char *name,·
265e50 ¤   ¤   ¤   ¤   ¤   ···const char *value)
d6bb36 {
2a855d ¤   if (!mimePtr)
952769 ¤   ¤   return (FALSE);
f367c5 ¤
efba75 ¤   emsMIMEParamP paramPtr = (emsMIMEParamP) malloc (sizeof(emsMIMEparam));
d1af5a
bf06aa ¤   if (paramPtr)
ecc7a1 ¤   {
3fa20b ¤   ¤   paramPtr->name = strdup(name);
5782b1 ¤   ¤   paramPtr->value = strdup(value);
979fe8 ¤   ¤   paramPtr->next = NULL;
7eaf5a
5da825 ¤   ¤   if ((paramPtr->name) && (paramPtr->value))
a65b34 ¤   ¤   {
04d619 ¤   ¤   ¤   emsMIMEParamP *paramEnd = &(mimePtr->params);
76af5a
9d5436 ¤   ¤   ····while (*paramEnd)
5fe735 ¤   ¤   ¤   ¤   paramEnd = &((*paramEnd)->next);
57af5a
9c33f6 ¤   ¤   ¤   *paramEnd = paramPtr;
82af5a
8d3ec8 ¤   ¤   ¤   return (TRUE);
660fe4 ¤   ¤   }
459371 ¤   }
baaf5a
78f9d3 ¤   // If we get here then something went wrong
8597ca ¤   // Do complete cleanup
--ebb3 00006662155401101d9 Page 4 of MIMETYPE.CPP
e0af5a
d18d69 ¤   free_param_type(paramPtr);
985d9d ¤   return (FALSE);
ddefe6 }
58af5a
6ab3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
6caf5a
e838e5 /*
7c5516 ·* ·Free an emsMIMEtype structure, including all strings and parameters.
e7775e ·*
d66a22 ·* ·Args:
efb927 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be freed
bd775e ·*
dd03d6 ·* ·No return value.
e2495d ·*/
0ab897 void free_mime_type(emsMIMEtypeP mimePtr)
e5bb36 {
a55e02 ¤   if (mimePtr)
76c7a1 ¤   {
02ad42 ¤   ¤   safefree(mimePtr->mime_type);
989f9c ¤   ¤   safefree(mimePtr->sub_type);
517e09 ¤   ¤   safefree(mimePtr->mime_version);
d91b52 ¤   ¤
d255d7 ¤   ¤   free_param_type(mimePtr->params);
74af5a
c0457f ¤   ¤   safefree(mimePtr);
109371 ¤   }
dfefe6 }
8aaf5a
05b3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
aeaf5a
1b38e5 /*
522ec7 ·* ·Convert an emsMIMEtype structure to a Content-Type header field line
6aa7eb ·* ·in the format specified by RFC 882.
d4775e ·*
f3322b ·* ·NOTE: The user of this function is responsible for freeing the
5fc8a5 ·* ·······returned string.
ff775e ·*
6f6a22 ·* ·Args:
e8cd7c ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure
d0775e ·*
b99fca ·* ·Returns: String containing header field; dynamically allocated.
db495d ·*/
081ea2 char *string_mime_type(emsMIMEtypeP mimePtr)·
8abb36 {
d8244c ¤   const char *kPrefixStr ·········= "Content-Type: ";
f42363 ¤   const char *kParamSepStr ·······= ";\r\n ·";
f5e081 ¤   const char *kTypeSubtypeSepStr ·= "/";
9c862f ¤   const char *kAttValueSepStr ····= "=";
9faf5a
978aef ¤   // Must have a valid mime structure
46855d ¤   if (!mimePtr)
377ed2 ¤   ¤   return NULL;
63af5a
5584f2 ¤   // Both TYPE and SUBTYPE are required by RFC822
6ccaec ¤   if ((!mimePtr->mime_type) || (!mimePtr->sub_type))
767ed2 ¤   ¤   return NULL;
cfaf5a
b618e1 ¤   // Calculate the length of the header string
9e31bf ¤   unsigned int hLen = 0;
72af5a
077b91 ¤   hLen += strlen(kPrefixStr);
e6f078 ¤   hLen += rfc822_quoted_strlen(mimePtr->mime_type);
609271 ¤   hLen += strlen(kTypeSubtypeSepStr);
2e5833 ¤   hLen += rfc822_quoted_strlen(mimePtr->sub_type);
cdaf5a
3733c3 ¤   emsMIMEParamP paramPtr = mimePtr->params;
0baf5a
8e494e ¤   while (paramPtr)
1bc7a1 ¤   {
6e4682 ¤   ¤   hLen += strlen(kParamSepStr);
06211c ¤   ¤   hLen += rfc822_quoted_strlen(paramPtr->name);
--3ded 0004ae3c03b401101d9 Page 5 of MIMETYPE.CPP
6acadd ¤   ¤   hLen += strlen(kAttValueSepStr);
d3aded ¤   ¤   hLen += rfc822_quoted_strlen(paramPtr->value);
34af5a
cef723 ¤   ¤   paramPtr = paramPtr->next;
cb9371 ¤   }
a0af5a
886362 ¤   // Allocate space for the header line
de0ee5 ¤   char *hStr = (char *) malloc(hLen + 1);
0367c5 ¤
3eaace ¤   if (!hStr)
107ed2 ¤   ¤   return NULL;
54af5a
cec0a8 ¤   // Build the header line
cb185f ¤   char *cp = hStr;
82af5a
c8d079 ¤   cp = strchr(strcpy(cp, kPrefixStr), '\0');
ea4018 ¤   cp = rfc822_quote_strcpy(cp, mimePtr->mime_type);
e72c23 ¤   cp = strchr(strcpy(cp, kTypeSubtypeSepStr), '\0');
2e9bd6 ¤   cp = rfc822_quote_strcpy(cp, mimePtr->sub_type);
d3af5a
48e0d9 ¤   paramPtr = mimePtr->params;
ed494e ¤   while (paramPtr)
09c7a1 ¤   {
0ebd8b ¤   ¤   cp = strchr(strcpy(cp, kParamSepStr), '\0');
6bbcf8 ¤   ¤   cp = rfc822_quote_strcpy(cp, paramPtr->name);
822bbc ¤   ¤   cp = strchr(strcpy(cp, kAttValueSepStr), '\0');
8e0c5a ¤   ¤   cp = rfc822_quote_strcpy(cp, paramPtr->value);
f5af5a
f8f723 ¤   ¤   paramPtr = paramPtr->next;
8c9371 ¤   }
1caf5a
d91943 ¤   // Return the header line
e0f43d ¤   return (hStr);
b9efe6 }
96af5a
c3b3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
20af5a
9238e5 /*
4e8116 ·* ·Pick out a specific parameter name-value pair from an emsMIMEtype
0425b3 ·* ·structure. The match is case sensitive.
8e775e ·*
2c43e4 ·* ·NOTE: The user of this function should NOT alter the returned string
3a5e8d ·* ·······in any way -- it should be considered READ-ONLY.
1d775e ·*
e66a22 ·* ·Args:
f49ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
a455c4 ·* ··paramName [IN] Name of parameter to look for
cd775e ·*
c6ab2e ·* ·Returns: String of the associated value or NULL if no match is found
27495d ·*/
53853a const char *get_mime_parameter(emsMIMEtypeP mimePtr, const char *paramName)
95bb36 {
ee855d ¤   if (!mimePtr)
a97ed2 ¤   ¤   return NULL;
f7af5a
cc33c3 ¤   emsMIMEParamP paramPtr = mimePtr->params;
7eaf5a
a7494e ¤   while (paramPtr)
63c7a1 ¤   {
d747ac ¤   ¤   if (strcmp(paramPtr->name, paramName) == 0)
0a5782 ¤   ¤   ¤   return (paramPtr->value);
2eaf5a
d9f723 ¤   ¤   paramPtr = paramPtr->next;
629371 ¤   }
b7af5a
d6f206 ····return (NULL);
ab797c }¤  ¤   ¤   ¤
03af5a
8cb3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d3af5a
a838e5 /*
4a266d ·* ·Remove a parameter from an existing emsMIMEtype structure. This structure
--0f99 00036cd8bfd401101d9 Page 6 of MIMETYPE.CPP
ab65ad ·* ·should be created using make_mime_type().
a0775e ·*
0e97ac ·* ·NOTE: All input strings are COPIED before permanent use.
3b775e ·*
ff9648 ·* Args:
20d93e ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to altered
ca7c06 ·* ··name ···[IN] Name of the parameter to be removed
a0a3b2 ·* ··
fc8b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
0f495d ·*/
ddb568 int remove_mime_parameter(emsMIMEtypeP mimePtr, const char *name)
e8bb36 {
d0855d ¤   if (!mimePtr)
5f2769 ¤   ¤   return (FALSE);
64af5a
c54ff4 ¤   emsMIMEParamP paramPtr = mimePtr->params, prevParamPtr = NULL;
14af5a
927615 ¤   /* Find the parameter */
fc494e ¤   while (paramPtr)
59c7a1 ¤   {
10726b ¤   ¤   if (strcmp(paramPtr->name, name) == 0)
68cdcb ¤   ¤   ¤   break;
1daf5a
2d7956 ¤   ¤   prevParamPtr = paramPtr;
47f723 ¤   ¤   paramPtr = paramPtr->next;
c69371 ¤   }
09af5a
9dac03 ¤   if (!paramPtr)
6ebce8 ¤   ····return (FALSE); /* Not found */
bcaf5a
959836 ¤   if (prevParamPtr == NULL) /* Removing first in list */
30ec1c ¤   ¤   mimePtr->params = paramPtr->next;
070e24 ¤   else
499712 ¤   ¤   prevParamPtr->next = paramPtr->next;
2caf5a
458bc0 ¤   paramPtr->next = NULL;
568d69 ¤   free_param_type(paramPtr);
ddaf5a
b4e7c0 ¤   return (TRUE);
0eefe6 }
1eaf5a
eeb3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
33af5a
ab38e5 /*
195b1f ·* ·Check for a matching MIME type/subtype. If either type or subtype is
4843fd ·* ·NULL, then it won't be checked. If both are NULL, then TRUE is always
337d43 ·* ·returned.
49775e ·*
c66a22 ·* ·Args:
d09ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
7942a6 ·* ··mime_type [IN] The major MIME type to check
213923 ·* ··sub_type ·[IN] The MIME subtype to check
ebe6a2 ·* ·
106740 ·* ·Returns: Boolean (TRUE if the MIME type matches, FALSE if not)
be495d ·*/
87b7d5 int match_mime_type(emsMIMEtypeP mimePtr,·
a2fefd ¤   ¤   ¤   ¤   ¤   const char *mime_type,·
cee009 ¤   ¤   ¤   ¤   ¤   const char *sub_type)
39bb36 {
3a855d ¤   if (!mimePtr)
972769 ¤   ¤   return (FALSE);
77af5a
2beb9e ¤   return (
1aa5a3 ¤   ¤   ¤   ((mime_type == NULL) ||·
5a44ce ¤   ¤   ¤   (stricmp(mimePtr->mime_type, mime_type) == 0))
ca4f13 ¤   ¤   ¤   &&
b4914d ¤   ¤   ¤   ((sub_type == NULL) ||·
59f985 ¤   ¤   ¤   (stricmp(mimePtr->sub_type, sub_type) == 0))
3ad4e4 ¤   ¤   ···);
2defe6 }
94af5a
363dba /* ======================================================================== */
--6e13 00162245b18401101d9 Page 7 of MIMETYPE.CPP
6ef8ba /* ·····························LOCAL FUNCTIONS ····························*/
bc3dba /* ======================================================================== */
91af5a
06235e /* Private function used to free the parameter linked-list */
1adf59 /* static */ void free_param_type(emsMIMEParamP paramPtr)
8cbb36 {
d173ac ¤   emsMIMEParamP nextParamPtr;
a4af5a
6d494e ¤   while (paramPtr)
7dc7a1 ¤   {
cca999 ¤   ¤   nextParamPtr = paramPtr->next;
1caf5a
c4bb53 ¤   ¤   safefree(paramPtr->name);
681784 ¤   ¤   safefree(paramPtr->value);
3c280a ¤   ¤   safefree(paramPtr);
a9af5a
5c0738 ¤   ¤   paramPtr = nextParamPtr;
989371 ¤   }
9befe6 }
56af5a
f99bb0 //}
62af5a
--602c 00069ecc86d401101da Page 1 of MIMETYPE.H
bc38e5 /*
8820c2 ·* ·Functions to manage emsMIMEtype structures
af12c6 ·* ·for use with Eudora EMS API under MS Windows.
34775e ·*
00613d ·* ·Filename: mimetype.h
01775e ·*
a25074 ·* ·Last Edited: August 21, 1996
b6775e ·*
40005b ·* ·Author: Scott Manjourides
aa775e ·*
f9ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
16775e ·*
7ac179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
90495d ·*/
cdaf5a
105c5d #ifndef EMS_MIMETYPE_H
980bac #define EMS_MIMETYPE_H
69af5a
4e5655 #include <windows.h>
e6fbd1 #include "ems-win.h"
2daf5a
f93379 #ifdef __cplusplus
a66dad extern "C" {
797454 #endif
caaf5a
e338e5 /*
f785ce ·* ·Create an emsMIMEtype structure to hold MIME information. Only the
0666cf ·* ·type and subtype are set here, use add_mime_parameter() to add
d8f3dd ·* ·any name/value parameter pairs.
d0775e ·*
41f79f ·* ·NOTE: All input strings are COPIED before permanent use. The user
7aeb22 ·* ·······of this function is responsible for calling free_mime_type()
d886a5 ·* ·······on returned structure.
4f775e ·*
536a22 ·* ·Args:
ffaaa9 ·* ··mime_type ···[IN] the main MIME type: e.g., "text", "application", "image"
1161dc ·* ··sub_type ····[IN] the sub type: e.g., "plain", "octet-stream", "jpeg"
ce1cc3 ·* ··mime_version [IN] the MIME verion number, if NULL will default to "1.0"
07775e ·*
ea04db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
ab495d ·*/
2cfe91 emsMIMEtypeP make_mime_type(const char *mime_type,·
6dc8fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char *sub_type,·
5f6764 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char *mime_version);
beaf5a
fe38e5 /*
5f605e ·* ·Create an emsMIMEtype structure to hold MIME information. Structure is
aa65ea ·* ·initialized to values provided in RFC822 content-type header line. This
064b95 ·* ·includes all parameter name-value pairs.
9fa3b2 ·* ··
46e058 ·* ·NOTE: The user of this function is responsible for calling
369141 ·* ·······free_mime_type() on returned structure.
93775e ·*
e96a22 ·* ·Args:
2a671c ·* ··content_type [IN] The RFC822 content-type string to parse
9c775e ·*
3704db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
27495d ·*/
3d701e emsMIMEtypeP parse_make_mime_type(const char *src);
e9af5a
2038e5 /*
08dd1d ·* ·Add a parameter to an existing emsMIMEtype structure. This structure
bf65ad ·* ·should be created using make_mime_type().
01775e ·*
1b97ac ·* ·NOTE: All input strings are COPIED before permanent use.
fa775e ·*
569648 ·* Args:
a7d232 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be added too
0af186 ·* ··name ···[IN] Name of the parameter
bd0476 ·* ··value ··[IN] Value of the parameter
40a3b2 ·* ··
698b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
--21a0 000fd61ede6401101da Page 2 of MIMETYPE.H
47495d ·*/
ec3200 int add_mime_parameter(emsMIMEtypeP mimePtr,·
37e4b5 ¤   ¤   ¤   ¤   ¤   ···const char *name,·
9952fb ¤   ¤   ¤   ¤   ¤   ···const char *value);
9daf5a
8e38e5 /*
aa266d ·* ·Remove a parameter from an existing emsMIMEtype structure. This structure
b265ad ·* ·should be created using make_mime_type().
a5775e ·*
f497ac ·* ·NOTE: All input strings are COPIED before permanent use.
6f775e ·*
259648 ·* Args:
9fd93e ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to altered
587c06 ·* ··name ···[IN] Name of the parameter to be removed
35a3b2 ·* ··
1f8b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
14495d ·*/
8cefdb int remove_mime_parameter(emsMIMEtypeP mimePtr, const char *name);
89af5a
d738e5 /*
9b5516 ·* ·Free an emsMIMEtype structure, including all strings and parameters.
59775e ·*
ab6a22 ·* ·Args:
72b927 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be freed
59775e ·*
3603d6 ·* ·No return value.
4c495d ·*/
2de0ae void free_mime_type(emsMIMEtypeP mimePtr);
83af5a
3a38e5 /*
662ec7 ·* ·Convert an emsMIMEtype structure to a Content-Type header field line
c0a7eb ·* ·in the format specified by RFC 882.
3f775e ·*
c2322b ·* ·NOTE: The user of this function is responsible for freeing the
5bc8a5 ·* ·······returned string.
c3775e ·*
9b6a22 ·* ·Args:
e6cd7c ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure
09775e ·*
6c9fca ·* ·Returns: String containing header field; dynamically allocated.
fc495d ·*/
d63bce char *string_mime_type(emsMIMEtypeP mimePtr);
fdaf5a
9838e5 /*
3d8116 ·* ·Pick out a specific parameter name-value pair from an emsMIMEtype
fa25b3 ·* ·structure. The match is case sensitive.
72775e ·*
6c43e4 ·* ·NOTE: The user of this function should NOT alter the returned string
a55e8d ·* ·······in any way -- it should be considered READ-ONLY.
f7775e ·*
406a22 ·* ·Args:
5d9ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
b355c4 ·* ··paramName [IN] Name of parameter to look for
16775e ·*
7bab2e ·* ·Returns: String of the associated value or NULL if no match is found
d9495d ·*/
849e7c const char *get_mime_parameter(emsMIMEtypeP mimePtr, const char *paramName);
5caf5a
9a38e5 /*
f15b1f ·* ·Check for a matching MIME type/subtype. If either type or subtype is
8d43fd ·* ·NULL, then it won't be checked. If both are NULL, then TRUE is always
a87d43 ·* ·returned.
cc775e ·*
df6a22 ·* ·Args:
549ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
4142a6 ·* ··mime_type [IN] The major MIME type to check
a73923 ·* ··sub_type ·[IN] The MIME subtype to check
cfe6a2 ·* ·
576740 ·* ·Returns: Boolean (TRUE if the MIME type matches, FALSE if not)
1c495d ·*/
48b7d5 int match_mime_type(emsMIMEtypeP mimePtr,·
fdfefd ¤   ¤   ¤   ¤   ¤   const char *mime_type,·
--b9ed 001b3ff74cd401101da Page 3 of MIMETYPE.H
229d01 ¤   ¤   ¤   ¤   ¤   const char *sub_type);
2faf5a
7e3be2 #endif /* EMS_MIMETYPE_H */
73af5a
4d3379 #ifdef __cplusplus
ceefe6 }
b37454 #endif
--05d6 000da8764cd401101db Page 1 of RFC1847.CPP
bc38e5 /*
d566b4 ·* ·Functions to aide manipulation and parsing of MIME RFC1847 objects.
d6775e ·*
abe658 ·* ·Last Edited: Wednesday, October 2, 1996
6e775e ·*
54ba78 ·* ·Last Edited: Monday, September 9, 1996
5e775e ·*
69005b ·* ·Author: Scott Manjourides
db775e ·*
aeea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
71775e ·*
10c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
f3775e ·*
bf495d ·*/
93af5a
dc7066 #include <stdlib.h> /* rand() */
39ff6d #include <time.h> /* time() */
612242 #include <stdio.h> /* sprintf() */
83568d #include <windows.h> /* Must be included for ems-win.h */
69af5a
4cfbd1 #include "ems-win.h"
338595 #include "RFC822.H"
339dcb #include "RFC1847.H"
b7d3fb #include "BUFTYPE.H"
ec5004 #include "MIMETYPE.H"
b7af5a
707890 /* ------------------------------------------------------------------------- */
4faf5a
051c52 static char *kBoundaryParameterName = "boundary";
1c9528 static char *kBoundaryPrefixSuffix = "=-=-=-=";
2eaf5a
847890 /* ------------------------------------------------------------------------- */
6eaf5a
51dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
6caf5a
cb7890 /* ------------------------------------------------------------------------- */
eaaf5a
7e3b13 static int rfc1847_create_init(createStatePtr pState);
bb5b46 static int rfc1847_parse_init(parseStatePtr pState);
53af5a
a47890 /* ------------------------------------------------------------------------- */
13af5a
9938e5 /*
5fae27 ·* ·Allocates and returns a pointer to an initialized createState structure.
0aa3b2 ·* ··
f182c9 ·* ·NOTE: The user of this function is responsible for properly
6bf6d8 ·* ·······deleting the returned data by calling delete_create_state()
d261f8 ·* ·······when the state data is no longer needed.
23775e ·*
80b7ce ·* ·No arguments.
f8775e ·*
742d82 ·* ·Pointer to newly created createState structure. NULL if error.
b7495d ·*/
eb5776 createStatePtr new_create_state()
11bb36 {
d932d4 ¤   createStatePtr p;
46d72f ¤   p = (createStatePtr) malloc(sizeof(createState));
57af5a
844dda ¤   if (!p)
c08021 ¤   ¤   return (NULL);
22af5a
be2f2a ¤   p->stage = p->next_stage = p->afterout_stage = CSE_Fail;
57af5a
81de3f ¤   p->pBoundaryStr = NULL;
1f693f ¤   p->current_part = 0;
c6af5a
c81a9c ¤   p->pTmpBuf = make_buf();
1b09c3 ¤   p->pOutputBuf = NULL;
f5af5a
fea182 ¤   p->bInitialized = FALSE;
d2af5a
da70cd ¤   return (p);
--7e04 000a6a36682401101db Page 2 of RFC1847.CPP
7aefe6 }
46af5a
13e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
cbaf5a
0f38e5 /*
37739f ·* ·Frees all memory within the state structure, including the structure
c7ea81 ·* ·itself.
cfa3b2 ·* ··
81f8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
db775e ·*
e16a22 ·* ·Args:
08f565 ·* ···pState [IN] Pointer to the state structure to be deleted.
10775e ·*
0c03d6 ·* ·No return value.
cc495d ·*/
e92ea5 void delete_create_state(createStatePtr p)
8dbb36 {
e04dda ¤   if (!p)
8299bf ¤   ¤   return;
f5af5a
2cc87f ¤   delete_buf(p->pTmpBuf);
5b0972 ¤   safefree(p->pBoundaryStr);
42af5a
30868d ¤   safefree(p);
12efe6 }
3faf5a
a9e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
9aaf5a
b138e5 /*
35b5e4 ·* ·Allocates and returns a pointer to an initialized parseState structure.
f5a3b2 ·* ··
7f82c9 ·* ·NOTE: The user of this function is responsible for properly
99f6d8 ·* ·······deleting the returned data by calling delete_create_state()
7a61f8 ·* ·······when the state data is no longer needed.
11775e ·*
c2b7ce ·* ·No arguments.
c2775e ·*
3f87bd ·* ·Pointer to newly created parseState structure. NULL if error.
de495d ·*/
cb51fd parseStatePtr new_parse_state()
06bb36 {
236d9c ¤   parseStatePtr p;
17d97d ¤   p = (parseStatePtr) malloc(sizeof(parseState));
42af5a
ca4dda ¤   if (!p)
698021 ¤   ¤   return (NULL);
e0af5a
988911 ¤   p->stage = p->next_stage = p->afterout_stage = PSE_Fail;
abaf5a
0a693f ¤   p->current_part = 0;
dbaf5a
2c4847 ¤   p->nOutputCount = 0;
90c213 ¤   p->nAfteroutSkip = 0;
dd103d ¤   p->nLeftSpanCount = 0;
33af5a
c409c3 ¤   p->pOutputBuf = NULL;
e7dd55 ¤   p->pSearchBuf = NULL;
b0af5a
1d9259 //¤ p->pTmpBuf = make_buf();
dedfd7 ¤   p->pPrevBuf = make_buf();
85c334 ¤   p->pBoundaryBuf = make_buf();
b70377 ¤   p->pDblNewlineBuf = make_buf();
94252d ¤   p->pNewlineBuf = make_buf();
40af5a
4da182 ¤   p->bInitialized = FALSE;
d9af5a
5470cd ¤   return (p);
e2efe6 }
caaf5a
2ae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
68af5a
a638e5 /*
--2557 00072b92f39401101db Page 3 of RFC1847.CPP
0a739f ·* ·Frees all memory within the state structure, including the structure
ecea81 ·* ·itself.
34a3b2 ·* ··
ecf8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
65775e ·*
326a22 ·* ·Args:
8ff565 ·* ···pState [IN] Pointer to the state structure to be deleted.
73775e ·*
a203d6 ·* ·No return value.
0d495d ·*/
d618c9 void delete_parse_state(parseStatePtr p)
70bb36 {
6d4dda ¤   if (!p)
8399bf ¤   ¤   return;
ff1b52 ¤   ¤
bd6533 //¤ delete_buf(p->pTmpBuf);
b6c173 ¤   delete_buf(p->pPrevBuf);
612c52 ¤   delete_buf(p->pBoundaryBuf);
e0b96c ¤   delete_buf(p->pDblNewlineBuf);
4814af ¤   delete_buf(p->pNewlineBuf);
f8af5a
6b868d ¤   safefree(p);
cbefe6 }
75af5a
85e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
42af5a
0038e5 /*
f25452 ·* ·Performs necessary initialization for rfc1847_create().
d1a3b2 ·* ··
3e6a22 ·* ·Args:
ee963f ·* ···pState [IN] Pointer to the state structure.
59775e ·*
8d6448 ·* ·Return value: BOOLEAN indicating success.
60495d ·*/
1fe09a static int rfc1847_create_init(createStatePtr pState)
5cbb36 {
6c9685 ¤   char *pBoundaryTxt = (char *) malloc(128);
8daf5a
55583f ¤   if (!pBoundaryTxt)
6c2769 ¤   ¤   return (FALSE);
56af5a
02d72d ¤   /* Create a random boundary; max 68 chars */
f7f5a2 ¤   srand((unsigned)time(NULL));
80af5a
a593e6 ¤   sprintf(pBoundaryTxt, "%s%d%d%d%s",
dbd255 ¤   ¤   kBoundaryPrefixSuffix,
887921 ¤   ¤   rand(),
8b7921 ¤   ¤   rand(),
c07921 ¤   ¤   rand(),
833c67 ¤   ¤   kBoundaryPrefixSuffix);
0faf5a
2d312c ¤   pState->pBoundaryStr = pBoundaryTxt;
4a00b0 ¤   pState->stage = CSE_Start;
21af5a
270aa9 ¤   pState->bInitialized = TRUE;
60af5a
b2e7c0 ¤   return (TRUE);
6fefe6 }
b9af5a
fce6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
0faf5a
da38e5 /*
279c8e ·* ·Creates RFC1847 MIME structure.
5fa3b2 ·* ··
8c6a22 ·* ·Args:
be379d ·* ···mimePtr ·[IN] ····MIME content info, used to create the MIME headers.
863c43 ·* ···pOutBuf ·[OUT] ···Output buffer (RFC1847 MIME structure).
622dc1 ·* ···pInPart1 [IN] ····Input buffer used for first part.
20822a ·* ···pInPart2 [IN] ····Input buffer used for second part.
d86d62 ·* ···pState ··[IN/OUT] Pointer to state info, caller must preserve.
1b775e ·*
728a08 ·* ·Return values:
--fe85 000fb5dca6f401101db Page 4 of RFC1847.CPP
34ec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
5f4815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
7feeac ·* ···RFC1847_FAIL ·······Parsing error.
3a495d ·*/
18af5a
b8883d int rfc1847_create(emsMIMEtypeP mimePtr,
55e65d ¤   ¤   ¤   ¤   ···BufTypePtr pOutBuf,
683c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
24d359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
d77568 ¤   ¤   ¤   ¤   ···createStatePtr pState)
6bbb36 {
1397e1 ¤   if (!pState->bInitialized)
bed82f ¤   ¤   if (!rfc1847_create_init(pState))
ac39a0 ¤   ¤   ¤   pState->stage = CSE_Fail;
5daf5a
f358c6 ¤   while (pState->stage != CSE_Done)
7fc7a1 ¤   {
e06c44 ¤   ¤   switch (pState->stage)
285b34 ¤   ¤   {
f581af ¤   ¤   ¤   case CSE_Start:
c74c3c ¤   ¤   ¤   ¤   pState->stage = CSE_DoHeader; /* Just an entry point */
9ecdcb ¤   ¤   ¤   break;
ebaf5a
7140c0 ¤   ¤   ¤   case CSE_DoHeader:
01f776 ¤   ¤   ¤   {
a05713 ¤   ¤   ¤   ¤   pState->stage = CSE_Fail; // If not changed, then something fai¶
cc9f4f led
e9af5a
11f0e0 ¤   ¤   ¤   ¤   if ((mimePtr) && (pState->pBoundaryStr))
ae72c3 ¤   ¤   ¤   ¤   {
086fe6 ¤   ¤   ¤   ¤   ¤   /* Remove the boundary parameter from the MIME struct -- if¶
9aa914 ·it's there */
bac788 ¤   ¤   ¤   ¤   ¤   remove_mime_parameter(mimePtr, kBoundaryParameterName);
02af5a
92d426 ¤   ¤   ¤   ¤   ¤   /* Add the boundary to the MIME type struct */
0ea01f ¤   ¤   ¤   ¤   ¤   if (add_mime_parameter(mimePtr, kBoundaryParameterName, pSt¶
577f85 ate->pBoundaryStr))
224859 ¤   ¤   ¤   ¤   ¤   {
4098aa ¤   ¤   ¤   ¤   ¤   ¤   char *pCT = NULL;
69af5a
f0c4b0 ¤   ¤   ¤   ¤   ¤   ¤   /* Create an RFC822 Content-Type header line from the M¶
664666 IME struct*/
5f88dd ¤   ¤   ¤   ¤   ¤   ¤   if ((pCT = string_mime_type(mimePtr)) != NULL)
728fec ¤   ¤   ¤   ¤   ¤   ¤   {
ebc0f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy_buf(pState->pTmpBuf, pCT); /* Content-Type: ¶
747fe0 */
c224ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "\r\n"); /* Not the bla¶
777313 nk line, just end of CT: */
b1e468 ¤   ¤   ¤   ¤   ¤   ¤   ¤   resetpos_buf(pState->pTmpBuf);
e8af5a
960463 ¤   ¤   ¤   ¤   ¤   ¤   ¤   safefree(pCT);
28af5a
bcaaa7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pState->pTmpBuf;
0ca661 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoBoundary;
a6f3d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
15db3c ¤   ¤   ¤   ¤   ¤   ¤   }
791c89 ¤   ¤   ¤   ¤   ¤   }
112613 ¤   ¤   ¤   ¤   }
1aa3a6 ¤   ¤   ¤   }
42cdcb ¤   ¤   ¤   break;
25af5a
3f2cf4 ¤   ¤   ¤   case CSE_DoBoundary:
acf776 ¤   ¤   ¤   {
012a64 ¤   ¤   ¤   ¤   strcpy_buf(pState->pTmpBuf, "\r\n");
4ec12a ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "--");
051252 ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, pState->pBoundaryStr);
a4af5a
bab45a ¤   ¤   ¤   ¤   if ((pState->current_part) < 2) /* End the header and first par¶
61c850 t */
d472c3 ¤   ¤   ¤   ¤   {
751f64 ¤   ¤   ¤   ¤   ¤   pState->current_part++;
fb8fdb ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoPart;
--4759 000f079b8be401101db Page 5 of RFC1847.CPP
862613 ¤   ¤   ¤   ¤   }
888684 ¤   ¤   ¤   ¤   else /* End of second part */
7672c3 ¤   ¤   ¤   ¤   {
01d00d ¤   ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "--");
8acb12 ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_Done;
0e2613 ¤   ¤   ¤   ¤   }
b9af5a
874dab ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "\r\n");
2f2ac6 ¤   ¤   ¤   ¤   resetpos_buf(pState->pTmpBuf);
dcaf5a
62119a ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
5af7c9 ¤   ¤   ¤   ¤   pState->pOutputBuf = pState->pTmpBuf;
bfa3a6 ¤   ¤   ¤   }
13cdcb ¤   ¤   ¤   break;
12af5a
c97739 ¤   ¤   ¤   case CSE_DoPart:
b6f776 ¤   ¤   ¤   {
f24810 ¤   ¤   ¤   ¤   switch (pState->current_part)
d372c3 ¤   ¤   ¤   ¤   {
6aac6e ¤   ¤   ¤   ¤   ¤   case 1: /* We're doing part 1 now */
924859 ¤   ¤   ¤   ¤   ¤   {
db3f2e ¤   ¤   ¤   ¤   ¤   ¤   if (poslen_buf(pInPart1) > 0)
428fec ¤   ¤   ¤   ¤   ¤   ¤   {
b9f3d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
7c4477 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInPart1;
f8af5a
2d76a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pInPart2)
8ea117 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoBoundary;
98c4dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
a1f902 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoPart;
66db3c ¤   ¤   ¤   ¤   ¤   ¤   }
d38cac ¤   ¤   ¤   ¤   ¤   ¤   else /* pInPart1 is empty/completed/non-existant */
9f8fec ¤   ¤   ¤   ¤   ¤   ¤   {
e576a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pInPart2)
7d9855 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoBoundary;
e453c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else /* !pInPart2 */
07f43c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_COMPLETED); /* We've eaten all ¶
2cc55f of part 1, and there is no part 2 */
c8db3c ¤   ¤   ¤   ¤   ¤   ¤   }
931c89 ¤   ¤   ¤   ¤   ¤   }
a314c3 ¤   ¤   ¤   ¤   ¤   break;
83af5a
4de3cf ¤   ¤   ¤   ¤   ¤   case 2: /* We're doing part 2 now */
f34859 ¤   ¤   ¤   ¤   ¤   {
6eb5fe ¤   ¤   ¤   ¤   ¤   ¤   if (poslen_buf(pInPart2) > 0)
d08fec ¤   ¤   ¤   ¤   ¤   ¤   {
a9f3d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
41ab13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInPart2;
5c7347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoPart;
53db3c ¤   ¤   ¤   ¤   ¤   ¤   }
c68cac ¤   ¤   ¤   ¤   ¤   ¤   else /* pInPart1 is empty/completed/non-existant */
cb8fec ¤   ¤   ¤   ¤   ¤   ¤   {
ff76a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pInPart2)
30f43c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_COMPLETED); /* We've eaten all ¶
7843d0 of part 2 */
5f53c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else /* !pInPart2 */
a89855 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoBoundary;
55db3c ¤   ¤   ¤   ¤   ¤   ¤   }
a81c89 ¤   ¤   ¤   ¤   ¤   }
7e14c3 ¤   ¤   ¤   ¤   ¤   break;
332613 ¤   ¤   ¤   ¤   }
bda3a6 ¤   ¤   ¤   }
f8cdcb ¤   ¤   ¤   break;
b4af5a
d3b318 ¤   ¤   ¤   case CSE_DoOutput:
12f776 ¤   ¤   ¤   {
b7b63b ¤   ¤   ¤   ¤   if (pOutBuf)
0072c3 ¤   ¤   ¤   ¤   {
41cd44 ¤   ¤   ¤   ¤   ¤   unsigned int nLen = poslen_buf(pState->pOutputBuf);
319528 ¤   ¤   ¤   ¤   ¤   unsigned int nOut = bufins_buf(pOutBuf, pState->pOutputBuf);
59af5a
f03377 ¤   ¤   ¤   ¤   ¤   if (nOut < nLen) /* Anything left to output */
--9380 00022db216d401101db Page 6 of RFC1847.CPP
b3a6fe ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL);
43af5a
1ff366 ¤   ¤   ¤   ¤   ¤   pState->stage = pState->afterout_stage;
f92613 ¤   ¤   ¤   ¤   }
52fa07 ¤   ¤   ¤   ¤   else
87655e ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL); /* No output buffer */
d2a3a6 ¤   ¤   ¤   }
eccdcb ¤   ¤   ¤   break;
5eaf5a
e8d65f ¤   ¤   ¤   case CSE_Fail:
c5cd39 ¤   ¤   ¤   ¤   return (RFC1847_FAIL);
aacdcb ¤   ¤   ¤   break;
9b3ab2 ¤   ¤   } /* switch (stage) */
7a456d ¤   } /* while */
69af5a
ac7e63 ¤   return (RFC1847_COMPLETED);
9befe6 }
ebaf5a
9ee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
edaf5a
b838e5 /*
ec75fe ·* ·Performs necessary initialization for rfc1847_parse().
83775e ·*
356a22 ·* ·Args:
80963f ·* ···pState [IN] Pointer to the state structure.
b5775e ·*
a76448 ·* ·Return value: BOOLEAN indicating success.
12495d ·*/
48abc9 static int rfc1847_parse_init(parseStatePtr pState)
9abb36 {
7bcfc0 ¤   if (!pState)
e32769 ¤   ¤   return (FALSE);
3aaf5a
b8b8ac ¤   strcpy_buf(pState->pNewlineBuf, "\r\n");
718f61 ¤   strcpy_buf(pState->pDblNewlineBuf, "\r\n\r\n");
08af5a
5e772f ¤   resetpos_buf(pState->pNewlineBuf);
12fabd ¤   resetpos_buf(pState->pDblNewlineBuf);
3b67c5 ¤
1e8f46 ¤   pState->stage = PSE_Start;
de0aa9 ¤   pState->bInitialized = TRUE;
5aaf5a
4de7c0 ¤   return (TRUE);
3cefe6 }
98af5a
48e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1baf5a
3738e5 /*
ab070c ·* ·Parses RFC1847 MIME structure, returning MIME info and separated parts.
a2a3b2 ·* ··
906a22 ·* ·Args:
6a047b ·* ···mimePtr ··[OUT] ···Returns a pointer to a newly created emsMIMEtype.
b347d4 ·* ···pOutPart1 [OUT] ···Output buffer, part 1.
3a5ad7 ·* ···pOutPart2 [OUT] ···Output buffer, part 2.
2d183e ·* ···pInBuf ···[IN] ····Input buffer containing full RFC1847 MIME structure.
49cf05 ·* ···pState ···[IN/OUT] Pointer to state info, caller must preserve.
8e775e ·*
d88a08 ·* ·Return values:
8fec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
cf4815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
80eeac ·* ···RFC1847_FAIL ·······Parsing error.
ed495d ·*/
d9892a int rfc1847_parse(emsMIMEtypeP *mimePtr,
ca4889 ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart1,
1fa7ed ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart2,
da824b ¤   ¤   ¤   ¤   ··BufTypePtr pInBuf,
1617a0 ¤   ¤   ¤   ¤   ··parseStatePtr pState)
88bb36 {
215757 ¤   int bForceJumpState = FALSE;
35af5a
0c97e1 ¤   if (!pState->bInitialized)
22ec5f ¤   ¤   if (!rfc1847_parse_init(pState))
--b537 000e3180812401101db Page 7 of RFC1847.CPP
1f9f9b ¤   ¤   ¤   pState->stage = PSE_Fail;
a0af5a
c14432 ¤   while ((bForceJumpState) || (poslen_buf(pInBuf) > 0))
84c7a1 ¤   {
3ded3c ¤   ¤   bForceJumpState = FALSE;
13af5a
fa6c44 ¤   ¤   switch (pState->stage)
a55b34 ¤   ¤   {
970e59 ¤   ¤   ¤   case PSE_Start:
a3f776 ¤   ¤   ¤   {
91f7e3 ¤   ¤   ¤   ¤   /* Just an entry point */
ad9424 ¤   ¤   ¤   ¤   pState->stage = PSE_SkipHeader;
33a3a6 ¤   ¤   ¤   }
11cdcb ¤   ¤   ¤   break;
48af5a
b5a823 ¤   ¤   ¤   case PSE_SkipHeader:
b8f776 ¤   ¤   ¤   {
ea23f3 ¤   ¤   ¤   ¤   pState->stage = PSE_KeepUntil;
9d6498 ¤   ¤   ¤   ¤   pState->next_stage = PSE_ParseHeader;
fb817d ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pDblNewlineBuf;
1ba3a6 ¤   ¤   ¤   }
bdcdcb ¤   ¤   ¤   break;
40af5a
e67d29 ¤   ¤   ¤   case PSE_ParseHeader: /* Do all the mimePtr stuff */
bff776 ¤   ¤   ¤   {
f2e9db ¤   ¤   ¤   ¤   resetpos_buf(pState->pPrevBuf);
7faf5a
8fd50c ¤   ¤   ¤   ¤   unsigned int nPrevLen = poslen_buf(pState->pPrevBuf);
dc97be ¤   ¤   ¤   ¤   char *pHeader = (char *) malloc(nPrevLen + 1);
97af5a
49dcb4 ¤   ¤   ¤   ¤   if (!pHeader)
9372c3 ¤   ¤   ¤   ¤   {
ef9ab0 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
cee844 ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
772613 ¤   ¤   ¤   ¤   }
9caf5a
6933e6 ¤   ¤   ¤   ¤   strncpy(pHeader, getpos_buf(pState->pPrevBuf), nPrevLen);
60de51 ¤   ¤   ¤   ¤   *(pHeader + nPrevLen) = '\0';
3caf5a
53a179 ¤   ¤   ¤   ¤   char *pCT = rfc822_extract_header(pHeader, "Content-Type:");
586a9e ¤   ¤   ¤   ¤   safefree(pHeader);
1daf5a
0acef3 ¤   ¤   ¤   ¤   if (!pCT)
dd72c3 ¤   ¤   ¤   ¤   {
ad9ab0 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
a6e844 ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
742613 ¤   ¤   ¤   ¤   }
a2af5a
6ac025 ¤   ¤   ¤   ¤   *mimePtr = parse_make_mime_type(pCT);
7cc7a3 ¤   ¤   ¤   ¤   safefree(pCT);
a9af5a
b27739 ¤   ¤   ¤   ¤   /* get boundary info */
cad6de ¤   ¤   ¤   ¤   const char *cp = get_mime_parameter(*mimePtr, kBoundaryParamete¶
1809aa rName);
20af5a
fb63c1 ¤   ¤   ¤   ¤   if (!cp)
3472c3 ¤   ¤   ¤   ¤   {
db9ab0 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
15e844 ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
142613 ¤   ¤   ¤   ¤   }
bdaf5a
c5284d ¤   ¤   ¤   ¤   strcpy_buf(pState->pBoundaryBuf, "\r\n--");
127ece ¤   ¤   ¤   ¤   strcat_buf(pState->pBoundaryBuf, cp);
57cc2f ¤   ¤   ¤   ¤   // DO NOT free() cp
1caf5a
fdaf5a
60ae4e ¤   ¤   ¤   ¤   resetpos_buf(pState->pBoundaryBuf);
edaf5a
8f2e3d ¤   ¤   ¤   ¤   unsigned int nSkip = skipcount_buf(pState->pPrevBuf, pState->pB¶
81271e oundaryBuf);
7b6177 ¤   ¤   ¤   ¤   unsigned int nRemain = nPrevLen - nSkip;
e3af5a
--afc3 000bedb556c401101db Page 8 of RFC1847.CPP
435506 ¤   ¤   ¤   ¤   pState->nLeftSpanCount = nRemain;
f6af5a
a5da06 ¤   ¤   ¤   ¤   clear_buf(pState->pPrevBuf);
79af5a
60497e ¤   ¤   ¤   ¤   pState->stage = PSE_SkipFirst;
a2a3a6 ¤   ¤   ¤   }
aacdcb ¤   ¤   ¤   break;
06af5a
45adc2 ¤   ¤   ¤   case PSE_SkipFirst:
34f776 ¤   ¤   ¤   {
3a047b ¤   ¤   ¤   ¤   pState->stage = PSE_IgnoreUntil;
013a54 ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pBoundaryBuf;
1adc4d ¤   ¤   ¤   ¤   pState->next_stage = PSE_PrePart;
85a3a6 ¤   ¤   ¤   }
67cdcb ¤   ¤   ¤   break;
a5af5a
c9d157 ¤   ¤   ¤   case PSE_PrePart:
f5f776 ¤   ¤   ¤   {
c9047b ¤   ¤   ¤   ¤   pState->stage = PSE_IgnoreUntil;
a908f5 ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pNewlineBuf;
4603e3 ¤   ¤   ¤   ¤   pState->next_stage = PSE_OutPart;
c8a3a6 ¤   ¤   ¤   }
5fcdcb ¤   ¤   ¤   break;
5daf5a
6e0ef9 ¤   ¤   ¤   case PSE_OutPart:
248cf3 ¤   ¤   ¤   {¤
999702 ¤   ¤   ¤   ¤   pState->current_part++;
eeaf5a
2a2c30 ¤   ¤   ¤   ¤   if (pState->current_part <= 2)
ff72c3 ¤   ¤   ¤   ¤   {
1b778b ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_OutputUntil;
003ab6 ¤   ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pBoundaryBuf;
09724c ¤   ¤   ¤   ¤   ¤   pState->next_stage = PSE_PrePart;
8d2613 ¤   ¤   ¤   ¤   }
66fa07 ¤   ¤   ¤   ¤   else
553861 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Done;
54a3a6 ¤   ¤   ¤   }
b1cdcb ¤   ¤   ¤   break;
a1af5a
d9d2b5 ¤   ¤   ¤   case PSE_Done:
5ef776 ¤   ¤   ¤   {
0473b4 ¤   ¤   ¤   ¤   delpos_buf(pInBuf);
b7a3a6 ¤   ¤   ¤   }
34cdcb ¤   ¤   ¤   break;
3eaf5a
747064 ¤   ¤   ¤   case PSE_Fail:
61f776 ¤   ¤   ¤   {
54cd39 ¤   ¤   ¤   ¤   return (RFC1847_FAIL);
8da3a6 ¤   ¤   ¤   }
50cdcb ¤   ¤   ¤   break;
4baf5a
a7e1a2 ¤   ¤   ¤   /* ----- ----- */
54af5a
8dc74f ¤   ¤   ¤   case PSE_KeepUntil:
3933fc ¤   ¤   ¤   case PSE_IgnoreUntil:
e91317 ¤   ¤   ¤   case PSE_OutputUntil:
7cf776 ¤   ¤   ¤   {
911651 ¤   ¤   ¤   ¤   int bFound = FALSE;
3a41b3 ¤   ¤   ¤   ¤   unsigned int nPrefixCount = 0, nAfterSkip = 0;
b7af5a
cf6ca9 ¤   ¤   ¤   ¤   resetpos_buf(pState->pSearchBuf);
0eaf5a
c0d636 ¤   ¤   ¤   ¤   const unsigned int nInLen = poslen_buf(pInBuf);
33138a ¤   ¤   ¤   ¤   const unsigned int nSearchLen = poslen_buf(pState->pSearchBuf);
efaf5a
a66803 ¤   ¤   ¤   ¤   /* Did we have a partial span at the end of last buffer? */
6fe564 ¤   ¤   ¤   ¤   if (pState->nLeftSpanCount > 0)
1472c3 ¤   ¤   ¤   ¤   {
1b5b1d ¤   ¤   ¤   ¤   ¤   //unsigned int nRemainingCount = nSearchLen - (pState->nLef¶
e4136e tSpanCount);
efae30 ¤   ¤   ¤   ¤   ¤
be7235 ¤   ¤   ¤   ¤   ¤   /* Check for completion of span */
--849d 0002f96414b401101db Page 9 of RFC1847.CPP
25d3be ¤   ¤   ¤   ¤   ¤   // If doesn't continue match, returns zero
53f632 ¤   ¤   ¤   ¤   ¤   // otherwise returns number of chars of pSearchBuf that hav¶
7e4ba5 e been matched
8d73aa ¤   ¤   ¤   ¤   ¤   unsigned int nNewMatched = completecount_buf(pInBuf, pState¶
f4ece5 ->pSearchBuf, pState->nLeftSpanCount);
60af5a
86c76e ¤   ¤   ¤   ¤   ¤   if (nNewMatched == nSearchLen) /* complete match made */
6e4859 ¤   ¤   ¤   ¤   ¤   {
ac41d1 ¤   ¤   ¤   ¤   ¤   ¤   bFound = TRUE;
29cada ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = 0; /* No chars in this buffer are before¶
675186 ·the match */
d03782 ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = nSearchLen - (pState->nLeftSpanCount); /* ¶
1fe0af Move buffer position to AFTER match */
83af5a
382b92 ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = 0;
841c89 ¤   ¤   ¤   ¤   ¤   }
245fea ¤   ¤   ¤   ¤   ¤   else if (nNewMatched == 0) /* match failed */
424859 ¤   ¤   ¤   ¤   ¤   {
f8469e ¤   ¤   ¤   ¤   ¤   ¤   /* need to 'do' pState->nLeftSpanCount of pState->pSear¶
637243 chBuf */
92af5a
3a3e1c ¤   ¤   ¤   ¤   ¤   ¤   switch (pState->stage)
6d8fec ¤   ¤   ¤   ¤   ¤   ¤   {
7419d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   case PSE_KeepUntil:
cba898 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bufncat_buf(pState->pPrevBuf, pState->pSearchBu¶
00e8e9 f, pState->nLeftSpanCount);
b58c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
0eaf5a
17969a ¤   ¤   ¤   ¤   ¤   ¤   ¤   case PSE_IgnoreUntil:
74cde4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   /* Ignore -- do nothing */
8a8c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
23531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
46b671 ¤   ¤   ¤   ¤   ¤   ¤   ¤   case PSE_OutputUntil:
bd164c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pState->pSearchBuf;
465851 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nOutputCount = pState->nLeftSpanCount;
5c29a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = pState->stage; /* Stay¶
9054ea ·in same stage */
c2443b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_DoOutput;
518c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
42db3c ¤   ¤   ¤   ¤   ¤   ¤   }
04af5a
5d2b92 ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = 0;
8eaf5a
95a74d ¤   ¤   ¤   ¤   ¤   ¤   if (pState->stage == PSE_DoOutput)
4f655a ¤   ¤   ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
b71c89 ¤   ¤   ¤   ¤   ¤   }
b9d696 ¤   ¤   ¤   ¤   ¤   else /* Continued to match, but not completed yet -- the in¶
301559 put buffer is smaller than the pSearchBuf */
0f4859 ¤   ¤   ¤   ¤   ¤   {
7277b2 ¤   ¤   ¤   ¤   ¤   ¤   // Remainder of pInBuf matches, so we need to gobble it
f73e87 ¤   ¤   ¤   ¤   ¤   ¤   delpos_buf(pInBuf);
c3953d ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = nNewMatched;
7d46d0 ¤   ¤   ¤   ¤   ¤   ¤   continue; // We want to 'return', because we are done w¶
1c4dc2 ith input
131c89 ¤   ¤   ¤   ¤   ¤   }
6a2613 ¤   ¤   ¤   ¤   }
34af5a
c36ca9 ¤   ¤   ¤   ¤   resetpos_buf(pState->pSearchBuf);
e7af5a
e3adac ¤   ¤   ¤   ¤   if (!bFound)
4172c3 ¤   ¤   ¤   ¤   {
7a0876 ¤   ¤   ¤   ¤   ¤   if (pState->pSearchBuf) // nSearchLen?
104859 ¤   ¤   ¤   ¤   ¤   {
43dfb6 ¤   ¤   ¤   ¤   ¤   ¤   // Find match of pSearchBuf, either complete or end-spa¶
968cce nning
034bd4 ¤   ¤   ¤   ¤   ¤   ¤   // return number of chars to skip before match
17e747 ¤   ¤   ¤   ¤   ¤   ¤   unsigned int nSkip = skipcount_buf(pInBuf, pState->pSea¶
2ddfa7 rchBuf);
3e13fb ¤   ¤   ¤   ¤   ¤   ¤   unsigned int nRemain = nInLen - nSkip;
3caf5a
325c4a ¤   ¤   ¤   ¤   ¤   ¤   if (nRemain > nSearchLen) /* Found 'complete' */
2f8fec ¤   ¤   ¤   ¤   ¤   ¤   {
--8c14 000d4682c28401101db Page 10 of RFC1847.CPP
584f9d ¤   ¤   ¤   ¤   ¤   ¤   ¤   bFound = TRUE;
404678 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = nSkip;
3d8037 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = nSearchLen;
07db3c ¤   ¤   ¤   ¤   ¤   ¤   }
081811 ¤   ¤   ¤   ¤   ¤   ¤   else /* Either not found or partial possible */
af8fec ¤   ¤   ¤   ¤   ¤   ¤   {
884678 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = nSkip;
950ec1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = nRemain; /* Gobble up the remaining (k¶
1a610c nown to match) */
741a70 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = nRemain;
6bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
ca1c89 ¤   ¤   ¤   ¤   ¤   }
8a4bd6 ¤   ¤   ¤   ¤   ¤   else
ed4859 ¤   ¤   ¤   ¤   ¤   {
743e6f ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = nInLen;
4519db ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = 0;
281c89 ¤   ¤   ¤   ¤   ¤   }
2a2613 ¤   ¤   ¤   ¤   }
31af5a
716ca9 ¤   ¤   ¤   ¤   resetpos_buf(pState->pSearchBuf);
f7af5a
8cdb60 ¤   ¤   ¤   ¤   if (bFound) /* Found */
4572c3 ¤   ¤   ¤   ¤   {
6aaf84 ¤   ¤   ¤   ¤   ¤   switch (pState->stage)
7d4859 ¤   ¤   ¤   ¤   ¤   {
000180 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_KeepUntil:
f3894f ¤   ¤   ¤   ¤   ¤   ¤   ¤   bufncat_buf(pState->pPrevBuf, pInBuf, nPrefixCount ¶
6c4856 + nAfterSkip);
5f1db0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = pState->next_stage;
2100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
b9af5a
36c6a6 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_IgnoreUntil: /* Ignore -- do nothing */
bcaab1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   incpos_buf(pInBuf, nPrefixCount + nAfterSkip);
cf1db0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = pState->next_stage;
9a00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
c494aa ¤   ¤   ¤   ¤   ¤   ¤
7ef94f ¤   ¤   ¤   ¤   ¤   ¤   case PSE_OutputUntil:
ec9fe5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInBuf;
0cfac1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nOutputCount = nPrefixCount;
ae8875 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = pState->next_stage;
2002cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nAfteroutSkip = nAfterSkip;
22a63b ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_DoOutput;
4900eb ¤   ¤   ¤   ¤   ¤   ¤   break;
28af5a
10e5b2 ¤   ¤   ¤   ¤   ¤   ¤   default:
487b8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
8400eb ¤   ¤   ¤   ¤   ¤   ¤   break;
3c1c89 ¤   ¤   ¤   ¤   ¤   }
462613 ¤   ¤   ¤   ¤   }
74431e ¤   ¤   ¤   ¤   else /* not found */
cb72c3 ¤   ¤   ¤   ¤   {
90af84 ¤   ¤   ¤   ¤   ¤   switch (pState->stage)
3f4859 ¤   ¤   ¤   ¤   ¤   {
be0180 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_KeepUntil:
99894f ¤   ¤   ¤   ¤   ¤   ¤   ¤   bufncat_buf(pState->pPrevBuf, pInBuf, nPrefixCount ¶
5e4856 + nAfterSkip);
6300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
53af5a
2dc6a6 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_IgnoreUntil: /* Ignore -- do nothing */
c2aab1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   incpos_buf(pInBuf, nPrefixCount + nAfterSkip);
d200eb ¤   ¤   ¤   ¤   ¤   ¤   break;
4494aa ¤   ¤   ¤   ¤   ¤   ¤
5af94f ¤   ¤   ¤   ¤   ¤   ¤   case PSE_OutputUntil:
429fe5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInBuf;
f0fac1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nOutputCount = nPrefixCount;
1fec25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = pState->stage; /* Same sta¶
c4ec34 ge */
0302cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nAfteroutSkip = nAfterSkip;
c4a63b ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_DoOutput;
b100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
b2af5a
d4e5b2 ¤   ¤   ¤   ¤   ¤   ¤   default:
--baca 00118302a81401101db Page 11 of RFC1847.CPP
207b8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
3b00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
aa1c89 ¤   ¤   ¤   ¤   ¤   }
dc2613 ¤   ¤   ¤   ¤   }
0ba3a6 ¤   ¤   ¤   }
06cdcb ¤   ¤   ¤   break;
11af5a
4ae6f1 ¤   ¤   ¤   case PSE_DoOutput:
9af776 ¤   ¤   ¤   {
751c35 ¤   ¤   ¤   ¤   // Need to distiguish between the two output paths
61ad80 ¤   ¤   ¤   ¤   BufTypePtr p = NULL;
05af5a
ff4810 ¤   ¤   ¤   ¤   switch (pState->current_part)
d472c3 ¤   ¤   ¤   ¤   {
e17ea7 ¤   ¤   ¤   ¤   ¤   case 1: p = pOutPart1;
e614c3 ¤   ¤   ¤   ¤   ¤   break;
b0af5a
3690fb ¤   ¤   ¤   ¤   ¤   case 2: p = pOutPart2;
7014c3 ¤   ¤   ¤   ¤   ¤   break;
76af5a
789592 ¤   ¤   ¤   ¤   ¤   default: pState->stage = PSE_Fail;
1414c3 ¤   ¤   ¤   ¤   ¤   break;
9f2613 ¤   ¤   ¤   ¤   }
d8af5a
7cd00c ¤   ¤   ¤   ¤   if (p)
2472c3 ¤   ¤   ¤   ¤   {
94325c ¤   ¤   ¤   ¤   ¤   unsigned int nOut = bufnins_buf(p, pState->pOutputBuf, pSta¶
6a6709 te->nOutputCount);
26af5a
8222fd ¤   ¤   ¤   ¤   ¤   // Need to check if not everything was outputted
419029 ¤   ¤   ¤   ¤   ¤   // If not -- buffer is full, adjust 'nOutputCount', return ¶
5f3875 BUFFERFULL;
afbed7 ¤   ¤   ¤   ¤   ¤   pState->nOutputCount -= nOut;
51af5a
6780d3 ¤   ¤   ¤   ¤   ¤   if ((pState->nOutputCount) > 0) /* Anything left to output ¶
627fe0 */
0fa6fe ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL);
dfaf5a
59f366 ¤   ¤   ¤   ¤   ¤   pState->stage = pState->afterout_stage;
2671c0 ¤   ¤   ¤   ¤   ¤   if (pState->nAfteroutSkip > 0)
9b2c09 ¤   ¤   ¤   ¤   ¤   ¤   incpos_buf(pState->pOutputBuf, pState->nAfteroutSkip);
b42613 ¤   ¤   ¤   ¤   }
d1fa07 ¤   ¤   ¤   ¤   else
2e655e ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL); /* No output buffer */
3d2b85 ¤   ¤   ¤   ¤
a9a3a6 ¤   ¤   ¤   }
f2cdcb ¤   ¤   ¤   break;
770fe4 ¤   ¤   }
a19371 ¤   }
04af5a
657e63 ¤   return (RFC1847_COMPLETED);
18efe6 }
--55cf 000f268d17e401101dc Page 1 of RFC1847.H
bc38e5 /*
cf9756 ·* ·Functions to aide creation and parsing of MIME RFC1847 objects.
b5775e ·*
d69382 ·* ·Filename: RFC1847.H
02775e ·*
6d2ce1 ·* ·Last Edited: Monday, September 30, 1996
23775e ·*
1e005b ·* ·Author: Scott Manjourides
e4775e ·*
f9ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
9c775e ·*
77c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
a2775e ·*
a3495d ·*/
2caf5a
942f2f /* =========================================================================
93af5a
152315 ···- WHAT -
97af5a
609d62 ···The functions provided here allow easy creation and parsing of RFC1847
f2a0d8 ···MIME structure using buffer-based piping. For file-based RFC1847
29bb13 ···interactions use FILE1847.CPP.
09af5a
44af5a
c5fff5 ···- DESIGN -
f1af5a
ef9344 ···The intent of the design of these functions is to allow easy integration
439952 ···with most other buffer-based libraries. The buffers used here are all of
f6af5d ···the 'BufType' type, as defined in BUFTYPE.CPP. This design was chosen to
f337f1 ···make easy transition to other common buffers, and functions are provided
7c5dd3 ···to do just such conversations (see BUFTYPE.CPP).
d5af5a
ff7be5 ···Another major concern in the design of these functions is that of piping.
445614 ···We tried to assure that the buffer-based approach we chose would allow
a66fb3 ···easy transition to and from existing buffer-based libraries. All buffers
e03484 ···handled here have inherent size, max size, and position. The
bbd78f ···combination of these three state variables for each buffer gives the
e016b4 ···flexibility for either push (producer driven) or pull (consumer driven)
07d068 ···piping of data. This flexibility should allow these functions to easily
eeb2f2 ···be used in many applications.
75af5a
23b51b ···The mechanism for producing and consuming data is identical for both
6d2b93 ···the parse and create functions.
d1af5a
3daf5a
e22528 ···- HOW TO USE -
44af5a
004ed5 ···=============
e3cd8d ···Creating 1847
df4ed5 ···=============
20af5a
87a524 ···You will provide the top-most MIME type in an emsMIMEtype structure. This
2520ed ···MIME type structure should contain all required content-type parameters,
b03c7a ···except "boundary", which will be created and added for you.
88af5a
d8f2a6 ···You also need to provide two binary byte streams, one for each part of
2dd82b ···the MIME structure. These binary streams are presented to rfc1847_create
1aebff ···using buffer structures defined in BUFTYPE.H. Each buffer should be
285244 ···filled using the appropriate _buf() call from BUFTYPE.H and passed to
264856 ···rfc1847_create to be consumed.
b0af5a
5797da ···The formatted MIME rfc1847 structure is returned in the output buffer,
a0c5c7 ···without changing the buffer's size. This means that it is possible to
b92eb1 ···have the output buffer fill before the input buffer(s) are completely
8e466e ···consumed. In this case rfc1847_create() will return RFC1847_BUFFERFULL.
8a61b3 ···When this value is returned, the caller should simply consume the output
6251a4 ···buffer and re-call rfc1847_create(). The input buffers will retain any
78a91e ···partially consumed status, and thus should not be altered.
c9af5a
1abfbc ···Because the byte streams are presented in pieces through the use of a
f6b042 ···buffer, the question of indicating the end of a stream needs to be
f2e07d ···addressed. The implied ordering of the two streams (part 1, then part 2)
--ada7 0005ae16f1e401101dc Page 2 of RFC1847.H
b1be1e ···gives some help in solving this problem. If you need to chop part 1 into
31081a ···multiple buffer pieces, then you will need to NOT supply part 2 until
ddca62 ···part 1 is completed. This is done by passing NULL in place of the buffer.
f0928b ···As soon as the part 2 is not NULL, part 1 is assumed to be completed.
023619 ···Part 2 is assumed to be completed when the part 2 buffer is NULL after
c00951 ···is was non-NULL.
5caf5a
b84460 ···Example with part 1 using 3 buffer blocks:
24af5a
f0def8 ···Part 1 ······Part 2
230814 ···------ ······------
3a0353 ···Block 1 ·····NULL
2884bd ···Block 2 ·····NULL
265a1e ···Final block ·Part 2
d54f1b ···NULL ········NULL ···<-- Indicates you are finished, does cleanup
3faf5a
d6ff1d ···Of course, if everything fits into one buffer, the entire creation can
1b7a94 ···be done in two calls. First call with both valid parts, then finish with
4c77b4 ···the required NULL-NULL cleanup call.
24af5a
fc0015 ···The state parameter should be created before the first call, passed
f4eb58 ···(untouched) between calls, and deleted after the final call.
3caf5a
7ef4ba ···============
b85664 ···Parsing 1847
3ff4ba ···============
7be8c6 ···
d22f91 ···In much the same way as creating 1847, you must provide the input 1847
3d722a ···MIME structure in the form of a buffer or buffers as defined by BUFTYPE.H.
d9af5a
066aa5 ···When the parser returns RFC1847_BUFFERFULL, you should clear both output
6541bb ···buffer (one each for both parts) before re-calling.
77af5a
a597f2 ···The MIME type of the parsed 1847 structure is returned as an emsMIMEtype
5e509e ···structure.
b3af5a
6d0015 ···The state parameter should be created before the first call, passed
b1eb58 ···(untouched) between calls, and deleted after the final call.
04af5a
6fb61c ···========================================================================= */
03af5a
7b0453 #ifndef RFC1847_H
47d90a #define RFC1847_H
dcaf5a
03568d #include <windows.h> /* Must be included for ems-win.h */
f0fbd1 #include "ems-win.h"
4faf5a
64d3fb #include "BUFTYPE.H"
83af5a
a07890 /* ------------------------------------------------------------------------- */
ffaf5a
9c3e7d /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
7b4f34 /* THESE STRCUTURES AND TYPES ARE TO BE CONSIDERED OPAQUE TO THE USER */
46c76b ¤   /* Internally used values -- irrelevant to the avaerae user */
fa0f27 ¤   typedef enum {
c95c17 ¤   ¤   CSE_Start,
04ad9a ¤   ¤   CSE_DoHeader,
9677e2 ¤   ¤   CSE_DoBoundary,
eadc2a ¤   ¤   CSE_DoPart,
c35e42 ¤   ¤   CSE_DoOutput,
86ad13 ¤   ¤   CSE_Done,
a0fec1 ¤   ¤   CSE_Fail
6d9a50 ¤   } CreateStageEnum;
82af5a
69c76b ¤   /* Internally used values -- irrelevant to the avaerae user */
910f27 ¤   typedef enum {
f7d3e1 ¤   ¤   PSE_Start,
19f335 ¤   ¤   PSE_SkipHeader,
d37efa ¤   ¤   PSE_ParseHeader,
fbc2fd ¤   ¤   PSE_SkipFirst,
3c61eb ¤   ¤   PSE_PrePart,
5abe45 ¤   ¤   PSE_OutPart,
--e663 000c2c0c347401101dc Page 3 of RFC1847.H
b60b28 ¤   ¤   PSE_Done,
61a9f9 ¤   ¤   PSE_Fail,
c5a870 ¤   ¤   PSE_KeepUntil,
9cd41d ¤   ¤   PSE_IgnoreUntil,
65f4f6 ¤   ¤   PSE_OutputUntil,
fab785 ¤   ¤   PSE_DoOutput
d463bd ¤   } ParseStageEnum;
9eaf5a
dab290 ¤   /* Create-state strucutre -- irrelevant to the avaerae user */
3fee21 ¤   typedef struct createState {
629de4 ¤   ¤   int bInitialized;
99950a ¤   ¤   CreateStageEnum stage, next_stage, afterout_stage;
540f1d ¤   ¤   unsigned int current_part;
92df53 ¤   ¤   BufTypePtr pTmpBuf, pOutputBuf;
4cbf6c ¤   ¤   char *pBoundaryStr;
a19ddc ¤   } createState;
6daf5a
d83744 ¤   typedef createState *createStatePtr;
72af5a
2e4eb2 ¤   /* Parse-state strucutre -- irrelevant to the avaerae user */
a06db5 ¤   typedef struct parseState {
859de4 ¤   ¤   int bInitialized;
1f27b8 ¤   ¤   ParseStageEnum stage, next_stage, afterout_stage;
3d4f3e ¤   ¤   unsigned int current_part, nOutputCount, nAfteroutSkip, nLeftSpanCount;
28c74e ¤   ¤   BufTypePtr /*pTmpBuf,*/ pOutputBuf, pSearchBuf, pPrevBuf, pBoundaryBuf,
c7d0bc ¤   ¤   ¤   pDblNewlineBuf, pNewlineBuf;
7636bd ¤   } parseState;
04af5a
00c0e5 ¤   typedef parseState *parseStatePtr;
896bc8 /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
7eaf5a
d38e7e /* Return values for parse and create functions */
723761 enum { RFC1847_FAIL, RFC1847_COMPLETED, RFC1847_BUFFERFULL };
ebaf5a
d27890 /* ------------------------------------------------------------------------- */
46af5a
b738e5 /*
1cae27 ·* ·Allocates and returns a pointer to an initialized createState structure.
36a3b2 ·* ··
8382c9 ·* ·NOTE: The user of this function is responsible for properly
a0f6d8 ·* ·······deleting the returned data by calling delete_create_state()
8361f8 ·* ·······when the state data is no longer needed.
5d775e ·*
f8b7ce ·* ·No arguments.
4a775e ·*
082d82 ·* ·Pointer to newly created createState structure. NULL if error.
1d495d ·*/
bd16c6 createStatePtr new_create_state();
f1af5a
8938e5 /*
ee739f ·* ·Frees all memory within the state structure, including the structure
98ea81 ·* ·itself.
f7a3b2 ·* ··
bdf8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
f2775e ·*
ad6a22 ·* ·Args:
b3f565 ·* ···pState [IN] Pointer to the state structure to be deleted.
fa775e ·*
0403d6 ·* ·No return value.
92495d ·*/
398214 void delete_create_state(createStatePtr pState);
c2af5a
0638e5 /*
24b5e4 ·* ·Allocates and returns a pointer to an initialized parseState structure.
82a3b2 ·* ··
a282c9 ·* ·NOTE: The user of this function is responsible for properly
fbf6d8 ·* ·······deleting the returned data by calling delete_create_state()
7f61f8 ·* ·······when the state data is no longer needed.
b9775e ·*
f7b7ce ·* ·No arguments.
43775e ·*
c287bd ·* ·Pointer to newly created parseState structure. NULL if error.
--1b9b 00152bf5654401101dc Page 4 of RFC1847.H
47495d ·*/
bf2c1b parseStatePtr new_parse_state();
adaf5a
d138e5 /*
07739f ·* ·Frees all memory within the state structure, including the structure
50ea81 ·* ·itself.
25a3b2 ·* ··
96f8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
b8775e ·*
686a22 ·* ·Args:
19f565 ·* ···pState [IN] Pointer to the state structure to be deleted.
69775e ·*
fa03d6 ·* ·No return value.
00495d ·*/
22db18 void delete_parse_state(parseStatePtr pState);
ffaf5a
0338e5 /*
219c8e ·* ·Creates RFC1847 MIME structure.
38a3b2 ·* ··
686a22 ·* ·Args:
16379d ·* ···mimePtr ·[IN] ····MIME content info, used to create the MIME headers.
523c43 ·* ···pOutBuf ·[OUT] ···Output buffer (RFC1847 MIME structure).
e32dc1 ·* ···pInPart1 [IN] ····Input buffer used for first part.
e6822a ·* ···pInPart2 [IN] ····Input buffer used for second part.
ce6d62 ·* ···pState ··[IN/OUT] Pointer to state info, caller must preserve.
d2775e ·*
d78a08 ·* ·Return values:
11ec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
8b4815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
f2eeac ·* ···RFC1847_FAIL ·······Parsing error.
a9495d ·*/
eb883d int rfc1847_create(emsMIMEtypeP mimePtr,
9ae65d ¤   ¤   ¤   ¤   ···BufTypePtr pOutBuf,
ee3c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
68d359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
58ef1b ¤   ¤   ¤   ¤   ···createStatePtr pState);
11af5a
b438e5 /*
76070c ·* ·Parses RFC1847 MIME structure, returning MIME info and separated parts.
4ba3b2 ·* ··
8a6a22 ·* ·Args:
1d047b ·* ···mimePtr ··[OUT] ···Returns a pointer to a newly created emsMIMEtype.
ae47d4 ·* ···pOutPart1 [OUT] ···Output buffer, part 1.
3a5ad7 ·* ···pOutPart2 [OUT] ···Output buffer, part 2.
05183e ·* ···pInBuf ···[IN] ····Input buffer containing full RFC1847 MIME structure.
45cf05 ·* ···pState ···[IN/OUT] Pointer to state info, caller must preserve.
54775e ·*
b48a08 ·* ·Return values:
23ec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
734815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
e3eeac ·* ···RFC1847_FAIL ·······Parsing error.
69495d ·*/
fb892a int rfc1847_parse(emsMIMEtypeP *mimePtr,
3a4889 ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart1,
44a7ed ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart2,
91824b ¤   ¤   ¤   ¤   ··BufTypePtr pInBuf,
aba53d ¤   ¤   ¤   ¤   ··parseStatePtr pState);
acaf5a
52dd50 #endif /* RFC1847_H */¶
--770a 00073334dde401101dd Page 1 of RFC822.CPP
bc38e5 /*
ebb257 ·* ·Functions to aide manipulation of MIME RFC822 headers.
8b775e ·*
8f60b9 ·* ·Filename: RFC822.cpp
c6775e ·*
772ba5 ·* ·Last Edited: July 15, 1996
32775e ·*
b9005b ·* ·Author: Scott Manjourides
ce775e ·*
77cbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
23ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
74775e ·*
c3c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
d2495d ·*/
59af5a
8fbea3 #include <stdlib.h>
ad5e84 #include <malloc.h>
d5324c #include <string.h>
6aaf5a
460043 #include <istream.h> // ifstream class
3eb6e4 #include <fstream.h> // ofstream class
6caf5a
056bd2 #include "rfc822.h"
4eaf5a
57c51a /* ========================================================================= */
b3af5a
861b61 const char *kRFC822_MustBeQuoted = "()<>@,;:\\\"/[]?= ";
ce35fe const char *kRFC822_MustBeEscaped = "\\\"";
917282 const char *kRFC822_EOL = "\r\n";
bbaf5a
46c51a /* ========================================================================= */
abaf5a
42dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
5eaf5a
3cc51a /* ========================================================================= */
7caf5a
5a38e5 /*
c26550 ·* ·Find next RFC822 token in given string, copying it into a newly created
95bdf0 ·* ·string. Advance pointer past token and any following whitespace.
42a3b2 ·* ··
6e3bed ·* ·NOTE: The user of this function is responsible for freeing returned
006c68 ·* ·······string.
8a775e ·*
fe6a22 ·* ·Args:
5c656a ·* ··cpp [IN/OUT] Handle (pointer-to-pointer) of RFC822 string to extract from
8d775e ·*
1d79f1 ·* ·Returns: String containing next token, NULL if error.
51e88e ·* ········Moves cpp to first non-whitespace character AFTER extracted token
bd495d ·*/
735bd5 char *rfc822_extract_token(char **cpp)
d0bb36 {
75302c ¤   char *start, *cp = *cpp;
25af5a
e2242b ¤   cp = rfc822_skipws(cp); // Skip white space
60fe0f ¤   start = cp;
dcaf5a
9f07ef ¤   cp = rfc822_skipword(cp); // Skip word
f1af5a
02b61f ¤   if (cp > start)
20c7a1 ¤   {
d66f29 ¤   ¤   const int len = cp - start;
de7b9e ¤   ¤   char *buf = (char *) malloc(len + 1);
26af5a
b49402 ¤   ¤   if (buf)
df5b34 ¤   ¤   {
451e8d ¤   ¤   ¤   rfc822_unquote_strcpy(buf, start, len);
b2962d ¤   ¤   ¤   *cpp = rfc822_skipws(cp);
70af5a
c1f358 ¤   ¤   ¤   return (buf);
e20fe4 ¤   ¤   }
ef9371 ¤   }
73af5a
--7bbc 0002a9f7c87401101dd Page 2 of RFC822.CPP
7d867d ¤   return (NULL); // No token to extract
83efe6 }
4caf5a
03e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b0af5a
8838e5 /*
087334 ·* ·Advances to next non-whitespace character in string. This includes
0bd4de ·* ·ignoring RFC822 comments.
74a3b2 ·* ··
1e6a22 ·* ·Args:
602c45 ·* ··cp [IN] RFC822 string
93775e ·*
e4bac7 ·* ·Returns: Pointer to next non-whitespace character.
8f495d ·*/
90c538 char *rfc822_skipws(char *cp)
62bb36 {
9143ab ¤   do {
1af940 ¤   ¤   while (*cp == ' ') // Skip spaces
66b3d6 ¤   ¤   ¤   cp++;
b1af5a
56a2f7 ¤   ¤   if (*cp == '(') // A comment?
225b34 ¤   ¤   {
8e829c ¤   ¤   ¤   int nested = 1;
22af5a
6a4840 ¤   ¤   ¤   while ((*++cp) && (nested)) // Find end of comment
a1f776 ¤   ¤   ¤   {
ebf486 ¤   ¤   ¤   ¤   switch (*cp)
3072c3 ¤   ¤   ¤   ¤   {
9a53f3 ¤   ¤   ¤   ¤   ¤   case '(': nested++;
e814c3 ¤   ¤   ¤   ¤   ¤   break;
59af5a
3bb05a ¤   ¤   ¤   ¤   ¤   case ')': nested--;
3f14c3 ¤   ¤   ¤   ¤   ¤   break;
42af5a
c70e93 ¤   ¤   ¤   ¤   ¤   case '\\': // Escape character
b1b66b ¤   ¤   ¤   ¤   ¤   ¤   if ((*(cp+1)) != '\0') // Check for end-of-string
e2f0a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   cp++;
bc14c3 ¤   ¤   ¤   ¤   ¤   break;
c8af5a
59273b ¤   ¤   ¤   ¤   ¤   case '\"': // Quote inside comment
a06231 ¤   ¤   ¤   ¤   ¤   ¤   while ((*cp) && (*++cp != '\"'))·
b965d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Go 'til end of quote
004cb9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if ((*cp == '\\') && ((*(cp+1)) != '\0'))
9396e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   cp++;·
1f78b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Escaped character inside quote --·
dc1166 ¤   ¤   ¤   ¤   ¤   ¤   ¤   //inside comment (eeek!)
ad14c3 ¤   ¤   ¤   ¤   ¤   break;
c62613 ¤   ¤   ¤   ¤   }
87a3a6 ¤   ¤   ¤   }
080fe4 ¤   ¤   }
6f1689 ¤   } while (*cp == ' ');
9aaf5a
d302c0 ¤   return cp;
46efe6 }
f9af5a
dee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
dbaf5a
ae38e5 /*
958bdc ·* ·Advances to next character in string directly after the current token.
dfa9fc ·* ·The first character must be the beginning of a valid token or end of
b58505 ·* ·string (ie. all whitespace must be skipped BEFORE calling this function).
00775e ·*
706a22 ·* ·Args:
902c45 ·* ··cp [IN] RFC822 string
36775e ·*
85e27b ·* ·Returns: Pointer to next valid whitespace character.
d8495d ·*/
132dcb char *rfc822_skipword(char *cp)
b7bb36 {
5dbc70 ¤   int bInQuotes = 0;
77af5a
2a4af4 ¤   // First character must be a quote to be valid double-quoted string
--b3e3 0000d3ba6ec401101dd Page 3 of RFC822.CPP
c5571c ¤   if (*cp == '\"')
82c7a1 ¤   {
efc6c8 ¤   ¤   bInQuotes = 1;
883663 ¤   ¤   cp++;
a59371 ¤   }
6367c5 ¤
1643d2 ¤   while (*cp)
e9c7a1 ¤   {
eb7a14 ¤   ¤   if (strchr(kRFC822_MustBeQuoted, *cp))
af5b34 ¤   ¤   {
9c92d2 ¤   ¤   ¤   // Found a character that should be double-quoted, but is not
a18ab6 ¤   ¤   ¤   if (!bInQuotes)·
136c6a ¤   ¤   ¤   ¤   return (cp);
f0af5a
f4a0a0 ¤   ¤   ¤   // Now we know we are inside a double-quoted string
88af5a
36c0db ¤   ¤   ¤   switch (*cp)
bbf776 ¤   ¤   ¤   {
7025ac ¤   ¤   ¤   ¤   case '\"': return (cp+1); // End double-quote
0814c3 ¤   ¤   ¤   ¤   ¤   break;
aa555d ¤   ¤   ¤   ¤   case '\\': cp++; // Escape character, skip next
f814c3 ¤   ¤   ¤   ¤   ¤   break;
fc8da2 ¤   ¤   ¤   ¤   default: // nothing
db14c3 ¤   ¤   ¤   ¤   ¤   break;
95a3a6 ¤   ¤   ¤   }
540fe4 ¤   ¤   }
1faf5a
cd3663 ¤   ¤   cp++;
949371 ¤   }
73af5a
aea86d ¤   return (cp);
e4efe6 }
7aaf5a
b7e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
a2af5a
cd38e5 /*
1fa539 ·* ·Calculates the length of the given text string if it were converted
7953aa ·* ·to an RFC822 string.
92775e ·*
b56a22 ·* ·Args:
dddfd1 ·* ··cp [IN] Text string
e7775e ·*
2bc1f0 ·* ·Returns: Equivalent RFC822 length of given text.
da495d ·*/
2c36fa unsigned int rfc822_quoted_strlen(char *cp)
aebb36 {
980c19 ¤   unsigned int len = 0, bQuoted = 0;
3baf5a
5643d2 ¤   while (*cp)
29c7a1 ¤   {
047cab ¤   ¤   len++;
50af5a
da7a19 ¤   ¤   if ((!bQuoted) && (strchr(kRFC822_MustBeQuoted, *cp) != NULL))
a5879d ¤   ¤   ¤   bQuoted = 1;
50af5a
903ac6 ¤   ¤   if (strchr(kRFC822_MustBeEscaped, *cp) != NULL)
60bc2c ¤   ¤   ¤   len++, bQuoted = 1;
07af5a
703663 ¤   ¤   cp++;
1b9371 ¤   }
2caf5a
a88be2 ¤   if (bQuoted)
5b7cbd ¤   ¤   len += 2; // Quotes
f5af5a
d6664d ¤   return (len);
e9efe6 }
e6af5a
24e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
e9af5a
ed38e5 /*
e7b4be ·* ·Copies and converts the source text string to a destination
0d27ba ·* ·RFC822 string. The source must be NULL terminated, and the
--5350 0000a5ae4e2401101dd Page 4 of RFC822.CPP
a8c297 ·* ·destination will be NULL terminated.
17775e ·*
8f6a22 ·* ·Args:
266d68 ·* ··dst [OUT] RFC822 string
d9ce7b ·* ··src [IN] ·Text string
61775e ·*
e050ce ·* ·Returns: Pointer to destination NULL termination.
ae495d ·*/
c0184e char *rfc822_quote_strcpy(char *dst, const char *src)
76bb36 {
62ae2a ¤   const unsigned int bQuoted =·
179b35 ¤   ¤   ( strpbrk(src, kRFC822_MustBeQuoted) ? 1 : 0 );
7caf5a
238be2 ¤   if (bQuoted)
1e2355 ¤   ¤   *dst++ = '\"';
0aaf5a
ababe7 ¤   while (*src)
e4c7a1 ¤   {
75885c ¤   ¤   if (strchr(kRFC822_MustBeEscaped, *src) != NULL)
f935b3 ¤   ¤   ¤   *dst++ = '\\';
c7af5a
58b539 ¤   ¤   *dst++ = *src++;
8b9371 ¤   }
a7af5a
708be2 ¤   if (bQuoted)
032355 ¤   ¤   *dst++ = '\"';
5baf5a
62064c ¤   *dst = '\0';
29af5a
f9d7c2 ¤   return (dst);
03efe6 }
ebaf5a
93e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
72af5a
bb38e5 /*
40a027 ·* ·Copies and converts the source RFC822 string to a destination
fdf16a ·* ·text string. The source must be NULL terminated, and the
18c297 ·* ·destination will be NULL terminated.
ea775e ·*
5f6a22 ·* ·Args:
e12fe1 ·* ··dst [OUT] Text string
897fc2 ·* ··src [IN] ·RFC822 string
fa8f1f ·* ··len [IN] ·Maximum charcters to copy; Zero implies whole string
02775e ·*
2950ce ·* ·Returns: Pointer to destination NULL termination.
3f495d ·*/
e25918 char *rfc822_unquote_strcpy(char *dst, const char *src, unsigned int len)
68bb36 {
ac2666 ¤   // If 'len' is provided (ie. >0) then only len chars will be copied
4ba5fb ¤   // Otherwise, copy 'til end-of-string
231f00 ¤   char *end;
e496ef ¤   unsigned int bEscaped = 0;
58af5a
b60935 ¤   end = strchr(src, '\0');
afaf5a
2a15aa ¤   if ((len > 0) && ((src + len) < end))
3a5d8c ¤   ¤   end = (char *) src + len;
5aaf5a
75391e ¤   while (src < end)
cac7a1 ¤   {
c315c7 ¤   ¤   if (bEscaped)
4945d0 ¤   ¤   ¤   bEscaped = 0;
fb0e1d ¤   ¤   else
d95b34 ¤   ¤   {
3a36a5 ¤   ¤   ¤   switch (*src)
4bf776 ¤   ¤   ¤   {
f76b5b ¤   ¤   ¤   ¤   case '\\':¤ bEscaped = 1;
0706b3 ¤   ¤   ¤   ¤   case '\"':¤ src++;
7a816f ¤   ¤   ¤   ¤   ¤   ¤   ¤   continue;
1ff622 ¤   ¤   ¤   ¤   break;
27a3a6 ¤   ¤   ¤   }
0a0fe4 ¤   ¤   }
--1109 000e2e1cbf6401101dd Page 5 of RFC822.CPP
e0af5a
07b539 ¤   ¤   *dst++ = *src++;
589371 ¤   }
66af5a
72064c ¤   *dst = '\0';
bdaf5a
7a9f8e ¤   return dst;
97efe6 }
b9af5a
38e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
90af5a
e538e5 /*
efcdeb ·* ·Finds and extracts a header line from a full multi-lined header. All
e546fd ·* ·unfolding (removing newlines) is done before header line is returned.
84775e ·*
14322b ·* ·NOTE: The user of this function is responsible for freeing the
17c8a5 ·* ·······returned string.
04775e ·*
7f6a22 ·* ·Args:
8c0990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
41b2b8 ·* ··pLinePrefix [IN] Prefix of header line to extract
b2775e ·*
dfd4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
eb495d ·*/
78782d char *rfc822_extract_header(const char *pFullHeader, const char *pLinePrefix)
96bb36 {
5f4ae6 ¤   const char *kNewline = "\r\n";
b874be ¤   const unsigned int kNewlineLen = (2);
2fcba9 ¤   const unsigned int nPreLen = strlen(pLinePrefix);
18af5a
044724 ¤   char *pStart, *pEnd, *pBuf, *pPos, *pRetBuf;
e6af5a
6bdbe4 ¤   if (nPreLen < 1)
3f8021 ¤   ¤   return (NULL);
33af5a
57ae69 ¤   pStart = (char *) pFullHeader;
b2af5a
4d737d ¤   /* Find first 'line' which matches prefix */
44978b ¤   while ((pStart) && (strnicmp(pStart, pLinePrefix, nPreLen) != 0))
cb9cb8 ¤   ¤   if (pStart = strstr(pStart, kNewline))
39d79f ¤   ¤   ¤   pStart += kNewlineLen;
09af5a
6f5b13 ¤   if (!pStart)
a13445 ¤   ¤   return (NULL); /* Not found */
24af5a
9ca1c1 ¤   /* Find the end of this header line */
c558ef ¤   for (pEnd = strstr(pStart, kNewline);·
da9295 ¤   ¤   (pEnd != NULL);·
9c66c7 ¤   ¤   pEnd = strstr(pEnd, kNewline))
d5c7a1 ¤   {
1534cb ¤   ¤   pPos = pEnd + kNewlineLen;
f5af5a
a2e88f ¤   ¤   /* Does header line continue on next line? */
a36e77 ¤   ¤   if ((*pPos == ' ') || (*pPos == '\t'))
02ffd4 ¤   ¤   ¤   pEnd = pPos;
6c0e1d ¤   ¤   else
cacdcb ¤   ¤   ¤   break;
0b9371 ¤   }
60af5a
0db2d7 ¤   /* If we ran off the end of the string,·
239d64 ¤   ¤   then the end is the last char in the string */
7bd3e6 ¤   if (pEnd == NULL)
f3f3cd ¤   ¤   pEnd = strchr(pStart, '\0');
af67c5 ¤
fd7836 ¤   pBuf = pRetBuf = (char *) malloc(pEnd - pStart + 1);·
1666a9 ¤   /* Max length of output string */
aeaf5a
398bd3 ¤   for (pPos = pStart; pPos < pEnd; pPos++)
b8c7a1 ¤   {
ad581e ¤   ¤   if (strncmp(pPos, kNewline, kNewlineLen) == 0)·
ba3be5 ¤   ¤   ¤   /* We're at a newline */
e2e841 ¤   ¤   ¤   pPos += kNewlineLen; /* Skip over newline */
--0ff8 000bd57789a401101dd Page 6 of RFC822.CPP
e0af5a
71da85 ¤   ¤   *pBuf++ = *pPos;
4c9371 ¤   }
7baf5a
aacdc5 ¤   *pBuf = '\0';
9aaf5a
cd709e ¤   return (pRetBuf);
95efe6 }
98af5a
b8e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
03af5a
4e38e5 /*
e4c16d ·* ·Reads and returns the RFC822 header from input file. This is defined
a39ca2 ·* ·here as reading until the first blank line from current file
2ac871 ·* ·position. The blank line is discarded.
4b775e ·*
d1322b ·* ·NOTE: The user of this function is responsible for freeing the
00c8a5 ·* ·······returned string.
b8775e ·*
dd6a22 ·* ·Args:
d9c2dd ·* ··inFile [IN] Input file stream; already open
15775e ·*
cff523 ·* ·Returns: Complete multi-lined RFC822 header; dynamically allocated.
815046 ·* ····The file pointer is left immediately after the first read blank line.
db495d ·*/
4f1821 char *rfc822_read_header(ifstream& inFile)
63bb36 {
220acf ¤   // We don't know how big the header is, but we know each line
45c5e5 ¤   // must be less than 1024 chars. We use 'kBlockSize' to
a42750 ¤   // increase the memory of the header while ensuring that
0e55c9 ¤   // there is at least kBlockSize available for each read.
e660a3 ¤   const unsigned int kBlockSize = 1024;
24af5a
6d418e ¤   char *pBuf, *pPos, *cp;
fddf4f ¤   unsigned int nBufSize, nStrLen;
5baf5a
9e1986 ¤   if ((!inFile.good()) || (inFile.eof()))
ea7ed2 ¤   ¤   return NULL;
21af5a
a73e77 ¤   nStrLen = nBufSize = 0;
6d58d5 ¤   pBuf = NULL;
73af5a
786b50 ¤   while ((inFile.good()) && (!inFile.eof()))
fcc7a1 ¤   {
2deb2b ¤   ¤   if ((nBufSize - nStrLen) < (kBlockSize + 1))
555b34 ¤   ¤   {
b100c3 ¤   ¤   ¤   nBufSize += kBlockSize;
0c6ead ¤   ¤   ¤   if ((cp = (char *) realloc(pBuf, nBufSize)) == NULL)
c9f776 ¤   ¤   ¤   {
ae6ceb ¤   ¤   ¤   ¤   safefree(pBuf);
da6e97 ¤   ¤   ¤   ¤   return (NULL); // Out of memory?
4da3a6 ¤   ¤   ¤   }
adaf5a
087308 ¤   ¤   ¤   pPos = (pBuf = cp) + nStrLen;
970fe4 ¤   ¤   }
9eaf5a
bddb6b ¤   ¤   // Get next line
0cb7c4 ¤   ¤   cp = pPos;
2cb3e2 ¤   ¤   while ((inFile.good()) && (!inFile.eof()))
1a0513 ¤   ¤   ¤   if ((*cp++ = inFile.get()) == '\n')
c2f776 ¤   ¤   ¤   {
41ba85 ¤   ¤   ¤   ¤   *cp = '\0';
9df622 ¤   ¤   ¤   ¤   break;
5fa3a6 ¤   ¤   ¤   }
48af5a
4b7cc0 ¤   ¤   /* inFile.getline(pPos, kBlockSize); */
e262ea ¤   ¤   /* getline() strips '\n' chars! Yuck! */
faaf5a
30ad39 ¤   ¤   if (strcmp(pPos, kRFC822_EOL) == 0) /* Empty line */
f4cdcb ¤   ¤   ¤   break;
a6af5a
bd8b45 ¤   ¤   pPos = strchr(pPos, '\0');
--aa65 0017e556780401101dd Page 7 of RFC822.CPP
ca1bec ¤   ¤   nStrLen = pPos - pBuf;
1f9371 ¤   }
28af5a
705b31 ¤   // Null terminate the header string
91f282 ¤   *pPos = '\0';
3eaf5a
b8398d ¤   // Chop off any excess allocated memory
465a5c ¤   if (cp = (char *) realloc(pBuf, strlen(pBuf) + 1))
a9b63c ¤   ¤   pBuf = cp;
5467c5 ¤
15638a ¤   return (pBuf);
7eefe6 }
--d4ec 000bf3803d3401101de Page 1 of RFC822.H
bc38e5 /*
ebb257 ·* ·Functions to aide manipulation of MIME RFC822 headers.
8b775e ·*
887b87 ·* ·Filename: RFC822.h
44775e ·*
c72ba5 ·* ·Last Edited: July 15, 1996
f6775e ·*
19005b ·* ·Author: Scott Manjourides
5b775e ·*
8ccbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
f0ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
0c775e ·*
78c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
4e775e ·*
1b495d ·*/
83af5a
df4489 #ifndef EMS_RFC822_H
1bb437 #define EMS_RFC822_H
91af5a
f40043 #include <istream.h> // ifstream class
d1b6e4 #include <fstream.h> // ofstream class
7daf5a
573379 #ifdef __cplusplus
2b6dad extern "C" {
e57454 #endif
afaf5a
2838e5 /*
226550 ·* ·Find next RFC822 token in given string, copying it into a newly created
33bdf0 ·* ·string. Advance pointer past token and any following whitespace.
9da3b2 ·* ··
4e3bed ·* ·NOTE: The user of this function is responsible for freeing returned
8d6c68 ·* ·······string.
0e775e ·*
d36a22 ·* ·Args:
25656a ·* ··cpp [IN/OUT] Handle (pointer-to-pointer) of RFC822 string to extract from
12775e ·*
dc79f1 ·* ·Returns: String containing next token, NULL if error.
d4e88e ·* ········Moves cpp to first non-whitespace character AFTER extracted token
0a495d ·*/
06815b char *rfc822_extract_token(char **cpp);
c4af5a
e938e5 /*
d67334 ·* ·Advances to next non-whitespace character in string. This includes
add4de ·* ·ignoring RFC822 comments.
3ea3b2 ·* ··
616a22 ·* ·Args:
3b2c45 ·* ··cp [IN] RFC822 string
17775e ·*
c6bac7 ·* ·Returns: Pointer to next non-whitespace character.
cb495d ·*/
e0bd2e char *rfc822_skipws(char *cp);
18af5a
d438e5 /*
398bdc ·* ·Advances to next character in string directly after the current token.
87a9fc ·* ·The first character must be the beginning of a valid token or end of
048505 ·* ·string (ie. all whitespace must be skipped BEFORE calling this function).
10775e ·*
f66a22 ·* ·Args:
132c45 ·* ··cp [IN] RFC822 string
44775e ·*
ade27b ·* ·Returns: Pointer to next valid whitespace character.
2c495d ·*/
ab78d2 char *rfc822_skipword(char *cp);
b3af5a
6b38e5 /*
93a539 ·* ·Calculates the length of the given text string if it were converted
fc53aa ·* ·to an RFC822 string.
3c775e ·*
1e6a22 ·* ·Args:
0edfd1 ·* ··cp [IN] Text string
f6775e ·*
bfc1f0 ·* ·Returns: Equivalent RFC822 length of given text.
--fd3f 001d0b6798e401101de Page 2 of RFC822.H
47495d ·*/
3058c3 unsigned int rfc822_quoted_strlen(char *cp);
88af5a
1738e5 /*
2cb4be ·* ·Copies and converts the source text string to a destination
c827ba ·* ·RFC822 string. The source must be NULL terminated, and the
98c297 ·* ·destination will be NULL terminated.
17775e ·*
7a6a22 ·* ·Args:
576d68 ·* ··dst [OUT] RFC822 string
95ce7b ·* ··src [IN] ·Text string
f4775e ·*
9e50ce ·* ·Returns: Pointer to destination NULL termination.
d1495d ·*/
84ab42 char *rfc822_quote_strcpy(char *dst, const char *src);
3baf5a
4438e5 /*
7fa027 ·* ·Copies and converts the source RFC822 string to a destination
7ef16a ·* ·text string. The source must be NULL terminated, and the
24c297 ·* ·destination will be NULL terminated.
92775e ·*
956a22 ·* ·Args:
852fe1 ·* ··dst [OUT] Text string
497fc2 ·* ··src [IN] ·RFC822 string
048f1f ·* ··len [IN] ·Maximum charcters to copy; Zero implies whole string
1c775e ·*
3d50ce ·* ·Returns: Pointer to destination NULL termination.
c0495d ·*/
c09cb0 char *rfc822_unquote_strcpy(char *dst, const char *src, unsigned int len);
c4af5a
ca38e5 /*
7ccdeb ·* ·Finds and extracts a header line from a full multi-lined header. All
2b46fd ·* ·unfolding (removing newlines) is done before header line is returned.
a8775e ·*
27322b ·* ·NOTE: The user of this function is responsible for freeing the
8ec8a5 ·* ·······returned string.
ab775e ·*
fd6a22 ·* ·Args:
e00990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
27b2b8 ·* ··pLinePrefix [IN] Prefix of header line to extract
93775e ·*
51d4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
85495d ·*/
7ffabf char *rfc822_extract_header(const char *pFullHeader, const char *pLinePrefix);
a5af5a
fb38e5 /*
15c16d ·* ·Reads and returns the RFC822 header from input file. This is defined
e69ca2 ·* ·here as reading until the first blank line from current file
1fc871 ·* ·position. The blank line is discarded.
37775e ·*
5a322b ·* ·NOTE: The user of this function is responsible for freeing the
9fc8a5 ·* ·······returned string.
18775e ·*
016a22 ·* ·Args:
a3c2dd ·* ··inFile [IN] Input file stream; already open
68775e ·*
52f523 ·* ·Returns: Complete multi-lined RFC822 header; dynamically allocated.
405046 ·* ····The file pointer is left immediately after the first read blank line.
57495d ·*/
8230b3 char *rfc822_read_header(ifstream& inFile);
d5af5a
05af5a
8b3379 #ifdef __cplusplus
41efe6 }
977454 #endif
67af5a
d057d1 #endif /* EMS_RFC822_H */
--8b35 00012f8aee0401101df Page 1 of ems-win.h
f94b9b #ifndef __EMS_WIN__
40421c #define __EMS_WIN__
5314b9 /* ======================================================================
e3af5a
465156 ····This SDK supports EMSAPI version 2
95b06d ····Copyright 1995, 1996 QUALCOMM Inc.
5883da ····Send comments and questions to <emsapi-info@qualcomm.com>
1aaf5a
4bf82a ····Generated: Tue Aug 20 10:36:38 PDT 1996
a5ecbe ····Filname: ems-win.h
9d869e ····
938c4b ····USE THIS FILE TO BUILD YOUR WINDOWS TRANSLATOR DLL
a5af5a
e181b0 ····Note: this file is generated automatically by scripts and must be
96d57d ····kept in synch with other translation API definitions, so it should
44c9b0 ····probably not ever be changed.
aeaf5a
b6af5a
bfe251 /* ========== CONSTANTS AND RETURN VALUES ================================ */
19af5a
0a5815 /* ----- Translator return codes --- store as a long --------------------- */·
e4ae46 #define EMSR_OK ·············(0L) ····/* The translation operation succeeded */
1d8023 #define EMSR_UNKNOWN_FAIL ···(1L) ····/* Failed for unspecified reason */
f73bf8 #define EMSR_CANT_TRANS ·····(2L) ····/* Don't know how to translate this */
ab6e8c #define EMSR_INVALID_TRANS ··(3L) ····/* The translator ID given was invalid */
65feb8 #define EMSR_NO_ENTRY ·······(4L) ····/* The value requested doesn't exist */
b4c5d6 #define EMSR_NO_INPUT_FILE ··(5L) ····/* Couldn't find input file */
e1a9bb #define EMSR_CANT_CREATE ····(6L) ····/* Couldn't create the output file */
e7b7be #define EMSR_TRANS_FAILED ···(7L) ····/* The translation failed. */
e56520 #define EMSR_INVALID ········(8L) ····/* Invalid argument(s) given */
489faf #define EMSR_NOT_NOW ········(9L) ····/* Translation can be done not in current
a3cdc1 ·········································context */
2746ad #define EMSR_NOW ···········(10L) ····/* Indicates translation can be performed
f32fd1 ·········································right away */
f42249 #define EMSR_ABORTED ·······(11L) ····/* Translation was aborted by user */
c40b39 #define EMSR_OK_DID_NOTHING (12L) ····/* Trans OK, data was not changed */
04d83c ·
78d83c ·
c97a73 /* ----- Translator types --- store as a long ---------------------------- */·
dbed98 #define EMST_NO_TYPE ·········(-1L)
5be4cc #define EMST_LANGUAGE ········(0x10L)
19ce6b #define EMST_TEXT_FORMAT ·····(0x20L)
368235 #define EMST_GRAPHIC_FORMAT ··(0x30L)
0318e2 #define EMST_COMPRESSION ·····(0x40L)
4ae9b4 #define EMST_COALESCED ·······(0x50L)
98d4c4 #define EMST_SIGNATURE ·······(0x60L)
c4d203 #define EMST_PREPROCESS ······(0x70L)
4659a1 #define EMST_CERT_MANAGEMENT ·(0x80L)
86af5a
17af5a
12b4b5 /* ----- Translator info flags and contexts --- store as a long ---------- */
ee4e9b /* Used both as bit flags and as constants */
14887d #define EMSF_ON_ARRIVAL ·····(0x0001L) /* Call on message arrivial */
d1acb3 #define EMSF_ON_DISPLAY ·····(0x0002L) /* Call when user views message */
9ab246 #define EMSF_ON_REQUEST ·····(0x0004L) /* Call when selected from menu */
e8b093 #define EMSF_Q4_COMPLETION ··(0x0008L) /* Queue and call on complete·
be85bc ··········································composition of a message */
18d7eb #define EMSF_Q4_TRANSMISSION (0x0010L) /* Queue and call on transmission
e7343f ··········································of a message */
1d45e1 #define EMSF_WHOLE_MESSAGE ··(0x0200L) /* Works on the whole message even if
ac963d ·········································it has sub-parts. (e.g. signature) */
09e729 #define EMSF_REQUIRES_MIME ··(0x0400L) /* Items presented for translation
c1a467 ··········································should be MIME entities with
f82a6f ··········································canonical end of line representation,
534aaf ··········································proper transfer encoding
99ec42 ··········································and headers */
c78e65 #define EMSF_GENERATES_MIME ·(0x0800L) /* Data produced will be MIME format */
0b80b9 #define EMSF_ALL_HEADERS ····(0x1000L) /* All headers in & out of trans when
2d77ee ··········································MIME format is used */
9897a8 /* all other flag bits in the long are RESERVED and may not be used */
4faf5a
12af5a
--6be7 000ec02e330401101df Page 2 of ems-win.h
675137 /* ----- The version of the API defined by this include file ------------- */
0cba52 #define EMS_VERSION ·········(2) ······/* Used in plugin init */
5434bc #define EMS_COMPONENT ·······'EuTL' ···/* Macintosh component type */
71af5a
e8af5a
950f81 /* ----- Translator and translator type specific return codes ------------ */
75e08a #define EMSC_SIGOK ··········(1L) ·····/* A signature verification succeeded */
6f6abc #define EMSC_SIGBAD ·········(2L) ·····/* A signature verification failed */
b92491 #define EMSC_SIGUNKNOWN ·····(3L) ·····/* Result of verification unknown */
74af5a
8771c3 /* ========== FUNCTIONS PASSED ACROSS THE API ============================ */
7ab4ab typedef short (FAR* emsProgress)(short); ····/* The progress function ·*/
82af5a
7faf5a
f5839d /* ========== DATA STRUCTURES ============================================ */
cf899f /* All strings on Windows are NULL terminated C strings */
8e3dac /* ----- MIME type data passed across the API ---------------------------- */
09b642 typedef struct emsMIMEparamS FAR*emsMIMEParamP;
f06a09 typedef struct emsMIMEparamS {
bf3a99 ····char ············FAR* ···name; ···/* Mime parameter name (e.g., charset) */
eff6f3 ····char ············FAR* ···value; ··/* param value (e.g. us-ascii) */
b7ebd1 ····struct emsMIMEparamS FAR* next; ··/* Linked list of parameters */
56ceae } emsMIMEparam;
1ea7d0 typedef struct emsMIMEtypeS FAR*emsMIMEtypeP;·
a1c713 typedef struct emsMIMEtypeS {
2b49ee ····char ········FAR* mime_version; ··/* The MIME-Version header */
242a95 ····char ········FAR* mime_type; ·····/* Top-level MIME type */ ·····
9a4e84 ····char ········FAR* sub_type; ······/* MIME sub-type */
299567 ····emsMIMEparam ·FAR* params; ·······/* MIME parameter list */
ade1b4 } emsMIMEtype;
a9af5a
b0f31b /* ========== FUNCTION PROTOTYPES ======================================== */
87af5a
d33379 #ifdef __cplusplus
436dad extern "C" {
287454 #endif
54af5a
e0233b /* ----- Get the API Version number this plugin implements ----------------- */
03b47e long WINAPI ems_plugin_version(
b51be3 ····short FAR* api_version ·····/* Place to return api version */
b46275 );
66af5a
9ab780 /* ----- Initialize plugin and get its basic info -------------------------- */
c01118 long WINAPI ems_plugin_init(
8530dc ····void FAR*FAR* globals, ·····/* Return for allocated instance structure */
c36ad2 ····char FAR* config_dir, ······/* Optional directory for config file */
ef2f37 ····char FAR* user_name, ·······/* Users full name from Eudora config */
74a2c0 ····char FAR* user_addr, ·······/* Users address (RFC-822 addr spec) */
177c69 ····short FAR* num_trans, ······/* Place to return num of translators */
62398a ····char FAR*FAR* plugin_desc, ·/* Return for string description of plugin */
4def68 ····short FAR* plugin_id, ······/* Place to return unique plugin id */
a3f0c5 ····HICON FAR*FAR* plugin_icon ·/* Return for plugin icon data */
c46275 );
f0af5a
e4cf66 /* ----- Get details about a translator in a plugin ------------------------ */
4c1da0 long WINAPI ems_translator_info(
9985aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
137f6e ····short trans_id, ············/* ID of translator to get info for */
479de7 ····long FAR* trans_type, ·····/* Return for translator type, e.g., EMST_xxx */
ceaa96 ····long FAR* trans_sub_type, ··/* Return for translator subtype */
86f93b ····unsigned long FAR* trans_flags, /* Return for translator flags */
e2090e ····char FAR*FAR* trans_desc, ··/* Return for translator string description */
844b38 ····HICON FAR*FAR* trans_icon ··/* Return for translator icon data */
666275 );
7daf5a
ef5ef0 /* ----- Check and see if a translation can be performed ------------------- */
a8df96 long WINAPI ems_can_translate(
0885aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
148a21 ····long context, ··············/* Context for check; e.g. EMSF_ON_xxx */
358988 ····short trans_id, ············/* ID of translator to call */
58f145 ····emsMIMEtypeP in_mime, ······/* MIME type of data to check */
ec160a ····char FAR*FAR* addresses, ···/* List of addresses (sender and recipients) */
--7273 000273615cb401101df Page 3 of ems-win.h
630a96 ····char FAR* properties, ······/* Properties for queued translations */
2f75a9 ····char FAR*FAR* out_error, ···/* Place to return string with error message */
68fb98 ····long FAR* out_code ········/* Return for translator-specific result code */
f36275 );
75af5a
896f40 /* ----- Actually perform a translation on a file -------------------------- */
fa1f17 long WINAPI ems_translate_file(
9f85aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
56a965 ····long context, ··············/* Context for translation; e.g. EMSF_ON_xxx */
bc8988 ····short trans_id, ············/* ID of translator to call */
391064 ····emsMIMEtypeP in_mime, ······/* MIME type of input data */
be9af8 ····char FAR* in_file, ·········/* The input file name */
3a160a ····char FAR*FAR* addresses, ···/* List of addresses (sender and recipients) */
b90a96 ····char FAR* properties, ······/* Properties for queued translations */
7f98ad ····emsProgress progress, ······/* Func to report progress / check for abort */
5ffc91 ····emsMIMEtypeP FAR* out_mime, /* Place to return MIME type of result */
e7c49d ····char FAR* out_file, ········/* The output file (specified by Eudora) */
3003a1 ····HICON FAR*FAR* out_icon, ···/* Place to return icon representing result */
e732ee ····char FAR*FAR* out_desc, ··/* Returned string for display with the result */
7275a9 ····char FAR*FAR* out_error, ···/* Place to return string with error message */
dbf68e ····long FAR* out_code ·········/* Return for translator-specific result code */
fb6275 );
4daf5a
bbc800 /* ----- Actually perform a translation on a buffer ------------------------ */
911014 long WINAPI ems_translate_buf(
c485aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
7da965 ····long context, ··············/* Context for translation; e.g. EMSF_ON_xxx */
1f8988 ····short trans_id, ············/* ID of translator to call */
a91064 ····emsMIMEtypeP in_mime, ······/* MIME type of input data */
f2d650 ····unsigned char FAR* in_buffer, /* Pointer to buffer of data to translate */
96047b ····long FAR* in_buffer_len, ···/* Amount of input & returns input consumed */
a7160a ····char FAR*FAR* addresses, ···/* List of addresses (sender and recipients) */
9c0a96 ····char FAR* properties, ······/* Properties for queued translations */
849a99 ····emsProgress progress, ······/* Func to report progress/check for abort */
3ffc91 ····emsMIMEtypeP FAR* out_mime, /* Place to return MIME type of result */
22629d ····unsigned char FAR* FAR* out_buffer, /* Eudora supplied output buffer */
6a1d33 ····long FAR* out_buffer_len, ·/* Out buffer size & returns amount filled in */
d403a1 ····HICON FAR*FAR* out_icon, ···/* Place to return icon representing result */
c032ee ····char FAR*FAR* out_desc, ··/* Returned string for display with the result */
5a75a9 ····char FAR*FAR* out_error, ···/* Place to return string with error message */
fcfb98 ····long FAR* out_code ········/* Return for translator-specific result code */
bb6275 );
8daf5a
3e14a0 /* ----- End use of a plugin and clean up ---------------------------------- */
531f49 long WINAPI ems_plugin_finish(
7d718e ····void FAR* globals ··········/* Pointer to translator instance structure */
7d6275 );
dbaf5a
f818bf /* ----- Free memory allocated by EMS plug-in ------------------------------ */
5a1693 long WINAPI ems_free(
3d8228 ····void FAR* mem ··············/* Memory to free */
a06275 );
7baf5a
1e048a /* ----- Call the plug-ins configuration Interface ------------------------- */
1befd1 long WINAPI ems_plugin_config(
4b85aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
4d6ad2 ····char FAR* config_dir, ······/* Optional directory for config file */
fe2f37 ····char FAR* user_name, ·······/* Users full name from Eudora config */
c88691 ····char FAR* user_addr ········/* Users address (RFC-822 addr spec) */
c26275 );
eaaf5a
afb6c1 /* ----- Manage properties for queued translations ------------------------- */
b4591a long WINAPI ems_queued_properties(
d785aa ····void FAR* globals, ·········/* Pointer to translator instance structure */
740cf6 ····long context, ··············/* EMSF_Q4_COMPLETION or _TRANSMISSION */
5f8988 ····short trans_id, ············/* ID of translator to call */
02f650 ····short FAR* selected, ·······/* Returned flag - is trans selected? */
608254 ····char FAR*FAR* properties ···/* ASCII string encoded properties */
416275 );
1aaf5a
3a3379 #ifdef __cplusplus
27efe6 }
--5afa 001b19fb69f401101df Page 4 of ems-win.h
a07454 #endif
e0af5a
f6af5a
947a00 #endif /* __EMS_WIN__ */
b1af5a
--3371 00094562d4d401101e0 Page 1 of file1847.cpp
bc38e5 /*
87fe00 ·* ·Filename: file1847.cpp
15775e ·*
b6e658 ·* ·Last Edited: Wednesday, October 2, 1996
5b775e ·*
b4005b ·* ·Author: Scott Manjourides
b7775e ·*
0fea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
4f775e ·*
f2c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
14495d ·*/
6daf5a
8dbea3 #include <stdlib.h>
c4feb2 #include <stdio.h>
c75655 #include <windows.h>
36af5a
a63ad6 #include "ems-win.h" // The EMS API
aff10b #include "mimetype.h"
69bde1 #include "encoding.h"
046bd2 #include "rfc822.h"
6c27f6 #include "rfc1847.h"
88af5a
2b8bfa #include "file1847.h"
f7af5a
d6bf23 /* ------------------------------------------------------------------------ */
2aaf5a
23f0f7 typedef struct {
2f6b54 ¤   int bFoundHeader;
754f25 ¤   BufTypePtr pBuf, pSearchBuf;
2d0d1f ¤   TrEncType cte;
519a23 ¤   unsigned int nPrevEndMatch;
367d9d ¤   char *preEncBuffer;
651a48 ¤   Dec64Ptr d64state;
d9b6bd ¤   DecQPPtr dQPstate;
e1bde8 } PartParseState;
36af5a
648a05 typedef PartParseState *PartParseStatePtr;
42af5a
b0bf23 /* ------------------------------------------------------------------------ */
80af5a
fabe35 static int DoCreateOnePart(emsMIMEtypeP InPartMimePtr,
2813ac ¤   ¤   ¤   ¤   ¤   ·emsMIMEtypeP OutMimePtr,
7a0da2 ¤   ¤   ¤   ¤   ¤   ·TrEncType InPartCTE,
ea4c6a ¤   ¤   ¤   ¤   ¤   ·FILE *fIn,
e469a4 ¤   ¤   ¤   ¤   ¤   ·FILE *fOut,
de0e17 ¤   ¤   ¤   ¤   ¤   ·int nPart,
2ff877 ¤   ¤   ¤   ¤   ¤   ·long nPreLen,
f2bfd8 ¤   ¤   ¤   ¤   ¤   ·long nTotalInLen,
6b2114 ¤   ¤   ¤   ¤   ¤   ·createStatePtr pState,
08fbbc ¤   ¤   ¤   ¤   ¤   ·emsProgress progress);
fdaf5a
3ab798 static int DoCreatePartsOutput(emsMIMEtypeP mimePtr,
5b3c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
62d359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
5d0bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
6df6f0 ¤   ¤   ¤   ¤   ···FILE *fOut);
c0af5a
e3f32b static int DoCreateStringOutput(const char *pStr,
bce775 ¤   ¤   ¤   ¤   ···int nPart,
8d97ec ¤   ¤   ¤   ¤   ···emsMIMEtypeP mimePtr,
3c0bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
82f6f0 ¤   ¤   ¤   ¤   ···FILE *fOut);
47af5a
39c02d static int DoParsePart(BufTypePtr pInBuf,
15d2f2 ¤   ¤   ¤   ¤   ·FILE *fOut,
177303 ¤   ¤   ¤   ¤   ·emsMIMEtypeP *mimePtr,
b43632 ¤   ¤   ¤   ¤   ·int bDeMime,
ba24c2 ¤   ¤   ¤   ¤   ·PartParseStatePtr pState);
04af5a
186bac static PartParseStatePtr create_PartParseState();
321a2d static void delete_PartParseState(PartParseStatePtr p);
94af5a
--a2fe 000ff84108d401101e0 Page 2 of file1847.cpp
d994f8 static void DoBufOutput(FILE *fOut, BufTypePtr pBuf);
ffaf5a
7abf23 /* ------------------------------------------------------------------------ */
6faf5a
a77f62 #define kBufferSize (1024)
c2af5a
e0dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
03da59 #define safeclose(f) { if (f) { fclose(f); (f) = NULL; } }
efaf5a
f1d1f7 const char *kMimeVersionStr = "Mime-Version: 1.0\r\n";
9eaf5a
32bf23 /* ------------------------------------------------------------------------ */
6faf5a
54ee80 /* ·CreateTmpFile
38775e ·*
386438 ·* ·Creates a empty, unique, temporary file in the users 'TEMP'
014970 ·* ···directory.
a1775e ·*
b1b7ce ·* ·No arguments.
35775e ·*
f059a2 ·* ·Returns a pointer to the filename string. This should be
e3cb59 ·* ···considered temporary data, and should never be free()'d.
6d495d ·*/
031088 char *CreateTmpFile()
10bb36 {
5f7c54 ¤   static char tmpName[_MAX_PATH + 1];
f5af5a
249186 #ifdef WIN32 // 32-bit
02ecdf ¤   char path[_MAX_PATH + 1];¤  ¤   ¤
058cbc ¤   GetTempPath(_MAX_PATH, path);
3efdcc ¤   GetTempFileName(path, "tmp", 0, tmpName);
7a5c9a #else // 16-bit
857ce5 ¤   BYTE btmpDrv = GetTempDrive(0);
cb59e6 ¤   GetTempFileName(btmpDrv,"tmp", 0, tmpName);
a67454 #endif
cfaf5a
80ef33 ¤   return (tmpName);
85efe6 }
29af5a
30bf23 /* ------------------------------------------------------------------------ */
14af5a
b4dc23 /* ·rfc1847_file_create
a7775e ·*
ec9c8e ·* ·Creates RFC1847 MIME structure.
f5775e ·*
7e6a22 ·* ·Args:
c63da4 ·* ···pOutFilename ····[IN] ····Output filename ** WRITE-ONLY **
001aa8 ·* ···OutMimePtr ······[IN/OUT] MIME type of output -- boundary param will be a¶
41f634 dded
efa061 ·* ···InPart1MimePtr ··[IN] ····MIME type of part 1
0243df ·* ···InPart1CTE ······[IN] ····Content-transfer-encoding for part 1
d41941 ·* ···pInPart1Filename [IN] ····Input filename for part 1 ** READ-ONLY **
899847 ·* ···InPart2MimePtr ··[IN] ····MIME type of part 2
be1fd0 ·* ···InPart2CTE ······[IN] ····Content-transfer-encoding for part 2
c880bd ·* ···pInPart2Filename [IN] ····Input filename for part 2 ** READ-ONLY **
2019c2 ·* ···progress ········[IN] ····EMS progress callback function
b8775e ·*
ec0ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
2d495d ·*/
49c7ea int rfc1847_file_create(const char *pOutFilename,
08303e ¤   ¤   ¤   ¤   ···emsMIMEtypeP OutMimePtr,
e6af5a
880178 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart1MimePtr,
accfb5 ¤   ¤   ¤   ¤   ···TrEncType InPart1CTE,
9235df ¤   ¤   ¤   ¤   ···const char *pInPart1Filename,
e4af5a
537511 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart2MimePtr,
f2c3c8 ¤   ¤   ¤   ¤   ···TrEncType InPart2CTE,
2acb6c ¤   ¤   ¤   ¤   ···const char *pInPart2Filename,
f8af5a
c4eda7 ¤   ¤   ¤   ¤   ···emsProgress progress)
ffbb36 {
--de1e 000ef8062b1401101e0 Page 3 of file1847.cpp
5b0c3a ¤   FILE *fOut = NULL, *fIn1 = NULL, *fIn2 = NULL;
47af5a
7aa614 ¤   fOut = fopen(pOutFilename, "ab"); ····/* WRITE - Append: Binary */
c17ba4 ¤   fIn1 = fopen(pInPart1Filename, "rb"); /* READ-ONLY: Binary */
46aaad ¤   fIn2 = fopen(pInPart2Filename, "rb"); /* READ-ONLY: Binary */
acaf5a
f5a5c4 ¤   int nStatus = FILE1847_OK;
b4af5a
afbec5 ¤   if (fOut && fIn1 && fIn2)
01c7a1 ¤   {
371640 ¤   ¤   fwrite(kMimeVersionStr, sizeof(char), strlen(kMimeVersionStr), fOut);
6baf5a
786620 ¤   ¤   long nLen1 = 0, nTotalInLen = 0;
72af5a
982c8a ¤   ¤   if (progress)
0e5b34 ¤   ¤   {
d7cd59 ¤   ¤   ¤   // get the file length of the two input files -- use for progress
38bd9e ¤   ¤   ¤   rewind(fIn1);
ddce73 ¤   ¤   ¤   fseek(fIn1, 0, SEEK_END);
fcf03f ¤   ¤   ¤   nLen1 = ftell(fIn1);
4cbd9e ¤   ¤   ¤   rewind(fIn1);
9daf5a
1e9853 ¤   ¤   ¤   rewind(fIn2);
1ffe62 ¤   ¤   ¤   fseek(fIn2, 0, SEEK_END);
80ea4e ¤   ¤   ¤   nTotalInLen = nLen1 + ftell(fIn2);
7f9853 ¤   ¤   ¤   rewind(fIn2);
5b0fe4 ¤   ¤   }
8eaf5a
d2c40b ¤   ¤   createStatePtr pState = new_create_state();
d8af5a
538e4b ¤   ¤   if (!pState)
0dff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
1caf5a
ab76fe ¤   ¤   /* ---------- PART 1 ---------- */
14af5a
89aa4a ¤   ¤   if (nStatus == FILE1847_OK)
49b8d7 ¤   ¤   ¤   nStatus = DoCreateOnePart(InPart1MimePtr, OutMimePtr, InPart1CTE, f¶
9f8af5 In1, fOut, 1, 0, nTotalInLen, pState, progress);
d6af5a
8aecdf ¤   ¤   /* ---------- PART 2 ---------- */
63af5a
85aa4a ¤   ¤   if (nStatus == FILE1847_OK)
32a820 ¤   ¤   ¤   nStatus = DoCreateOnePart(InPart2MimePtr, OutMimePtr, InPart2CTE, f¶
68220d In2, fOut, 2, nLen1, nTotalInLen, pState, progress);
9baf5a
5a1c74 ¤   ¤   // Do 1847 cleanup
94aa4a ¤   ¤   if (nStatus == FILE1847_OK)
bb5b34 ¤   ¤   {
be9533 ¤   ¤   ¤   if (!DoCreatePartsOutput(OutMimePtr, NULL, NULL, pState, fOut))
30fa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
b50fe4 ¤   ¤   }
d5af5a
74f21e ¤   ¤   // Do final progress indicator
4d3f2a ¤   ¤   if ((nStatus == FILE1847_OK) && (progress))
ce5b34 ¤   ¤   {
d98a35 ¤   ¤   ¤   if (progress(100) ? 1 : 0)
5400e3 ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
af0fe4 ¤   ¤   }
fcaf5a
5c08b7 ¤   ¤   // Done with the state data
71593a ¤   ¤   delete_create_state(pState);
199371 ¤   }
57af5a
f39c34 ¤   safeclose(fOut);
800f82 ¤   safeclose(fIn1);
5e2a4f ¤   safeclose(fIn2);
0baf5a
fb844e ¤   return(nStatus);
b9efe6 }
f1af5a
55bf23 /* ------------------------------------------------------------------------ */
efaf5a
--5ac4 0008f00f6dc401101e0 Page 4 of file1847.cpp
31aa24 /* ·rfc1847_file_parse
96775e ·*
a9911a ·* ·Parses RFC1847 MIME structure.
c3775e ·*
5b6a22 ·* ·Args:
04894a ·* ···pInFilename ······[IN] ·Input filename of file to parse ** READ-ONLY **
4dd77d ·* ···InMimePtr ········[OUT] MIME type of input file
14974c ·* ···pOutPart1Filename [IN] ·Output filename for part 1 ** WRITE-ONLY **
9d2072 ·* ···OutPart1MimePtr ··[OUT] MIME type of created part 1
1a8f77 ·* ···bPart1DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
4ff1f2 t 1?
9e07da ·* ···pOutPart2Filename [IN] ·Output filename for part 2 ** WRITE-ONLY **
aa5057 ·* ···OutPart2MimePtr ··[OUT] MIME type of created part 2
e72f00 ·* ···bPart2DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
021e96 t 2?
e94ccd ·* ···progress ·········[IN] ·EMS progress callback function
20775e ·*
170ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
57495d ·*/
66c74a int rfc1847_file_parse(const char *pInFilename,
204698 ¤   ¤   ¤   ¤   ¤   ···emsMIMEtypeP *InMimePtr,
fcaf5a
4cdbea ¤   ¤   ¤   ¤   ¤   ···const char *pOutPart1Filename,
e38f64 ¤   ¤   ¤   ¤   ¤   ···emsMIMEtypeP *OutPart1MimePtr,
b4590d ¤   ¤   ¤   ¤   ¤   ···int bPart1DeMime,
47af5a
be2559 ¤   ¤   ¤   ¤   ¤   ···const char *pOutPart2Filename,
d5fb0d ¤   ¤   ¤   ¤   ¤   ···emsMIMEtypeP *OutPart2MimePtr,
3a8f0a ¤   ¤   ¤   ¤   ¤   ···int bPart2DeMime,
b57e90 ¤   ¤   ¤   ¤   ··
12eb1f ¤   ¤   ¤   ¤   ¤   ···emsProgress progress)
20bb36 {
727e5c ¤   FILE *fIn = NULL, *fOut1 = NULL, *fOut2 = NULL;
51af5a
c4b4d4 ¤   fIn = fopen(pInFilename, "rb"); ······/* READ-ONLY: Binary */
1641f5 ¤   fOut1 = fopen(pOutPart1Filename, "ab"); /* READ-ONLY: Binary */
8726b2 ¤   fOut2 = fopen(pOutPart2Filename, "ab"); /* WRITE - Append: Binary */
d7af5a
7aa5c4 ¤   int nStatus = FILE1847_OK;
deaf5a
7326ba ¤   if (fIn && fOut1 && fOut2)
0dc7a1 ¤   {
0ac246 ¤   ¤   BufTypePtr pOutPart1= makesize_buf(kBufferSize),
76e260 ¤   ¤   ¤   pOutPart2 = makesize_buf(kBufferSize),
5e3bb2 ¤   ¤   ¤   pInBuf = makesize_buf(kBufferSize);
b1af5a
bcb44c ¤   ¤   if ((!pOutPart1) || (!pOutPart2) || (!pInBuf))
d0ff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
3aaf5a
4f172e ¤   ¤   parseStatePtr pState;
e20988 ¤   ¤   PartParseStatePtr pParsePart1State, pParsePart2State;
55bb4b ¤   ¤   unsigned int nRead;
3c64b2 ¤   ¤   int ret;
44af5a
c79e4a ¤   ¤   long nTotalInLen = 0;
282366 ¤   ¤   int nPercentComplete = 0;
c0af5a
067dec ¤   ¤   // Check to see if we need to parse the parts
79aadc ¤   ¤   int bReallyParse1 = FALSE, bReallyParse2 = FALSE;
f0f8be ¤   ¤   if ((OutPart1MimePtr) || (bPart1DeMime))
b927b1 ¤   ¤   ¤   bReallyParse1 = TRUE;
c08f95 ¤   ¤   if ((OutPart2MimePtr) || (bPart2DeMime))
d453d8 ¤   ¤   ¤   bReallyParse2 = TRUE;
22af5a
93083b ¤   ¤   if ((nStatus == FILE1847_OK) && progress)
935b34 ¤   ¤   {
1acd59 ¤   ¤   ¤   // get the file length of the two input files -- use for progress
b9904e ¤   ¤   ¤   rewind(fIn);
165558 ¤   ¤   ¤   fseek(fIn, 0, SEEK_END);
8055ed ¤   ¤   ¤   nTotalInLen = ftell(fIn);
65904e ¤   ¤   ¤   rewind(fIn);
8faf5a
--8472 000a69e7213401101e0 Page 5 of file1847.cpp
2c8c55 ¤   ¤   ¤   if (progress(nPercentComplete) ? 1 : 0)
4a00e3 ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
8e0fe4 ¤   ¤   }
1faf5a
896204 ¤   ¤   pParsePart1State = create_PartParseState();
8a9063 ¤   ¤   pParsePart2State = create_PartParseState();
df7f4d ¤   ¤   pState = new_parse_state();
28af5a
ca0f01 ¤   ¤   if ((nStatus == FILE1847_OK) && (pParsePart1State) && (pParsePart2State¶
e1fe28 ) && (pState))
c05b34 ¤   ¤   {
fdf603 ¤   ¤   ¤   do {
cb76dd ¤   ¤   ¤   ¤   /* Fill the input buffer from the input file */
06061a ¤   ¤   ¤   ¤   emptybuf_buf(pInBuf);
bdf54f ¤   ¤   ¤   ¤   if ((nRead = fread(getbuf_buf(pInBuf), sizeof(char), (bufsize_b¶
477723 uf(pInBuf)), fIn)) > 0)
33bf31 ¤   ¤   ¤   ¤   ¤   setlen_buf(pInBuf, nRead);
38af5a
fc99b8 ¤   ¤   ¤   ¤   /* Parse the input, producing output until completed input */
92b788 ¤   ¤   ¤   ¤   do {
0dfcd1 ¤   ¤   ¤   ¤   ¤   emptybuf_buf(pOutPart1);
0cd91c ¤   ¤   ¤   ¤   ¤   emptybuf_buf(pOutPart2);
7baf5a
b8ca63 ¤   ¤   ¤   ¤   ¤   ret = rfc1847_parse(InMimePtr, pOutPart1, pOutPart2, pInBuf¶
64a6d2 , pState);
43af5a
ca3400 ¤   ¤   ¤   ¤   ¤   if (ret != RFC1847_FAIL)
0f4859 ¤   ¤   ¤   ¤   ¤   {
bca696 ¤   ¤   ¤   ¤   ¤   ¤   if (bReallyParse1) /* Parse part #1 */
5d8fec ¤   ¤   ¤   ¤   ¤   ¤   {
8b9cd6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(pOutPart1, fOut1, OutPart1MimePtr,¶
738319 ·bPart1DeMime, pParsePart1State))
369299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
76db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ca586b ¤   ¤   ¤   ¤   ¤   ¤   else /* Raw output part #1 */
47c097 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DoBufOutput(fOut1, pOutPart1);
9daf5a
012910 ¤   ¤   ¤   ¤   ¤   ¤   if (bReallyParse2) /* Parse part #2 */
fe8fec ¤   ¤   ¤   ¤   ¤   ¤   {
5f61e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(pOutPart2, fOut2, OutPart2MimePtr,¶
910f2d ·bPart2DeMime, pParsePart2State))
0a9299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
33db3c ¤   ¤   ¤   ¤   ¤   ¤   }
9345a7 ¤   ¤   ¤   ¤   ¤   ¤   else /* Raw output part #2 */
c03d24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DoBufOutput(fOut2, pOutPart2);
4e1c89 ¤   ¤   ¤   ¤   ¤   }
316eb6 ¤   ¤   ¤   ¤   } while ((nStatus == FILE1847_OK) && (ret == RFC1847_BUFFERFULL¶
ed1445 ));
afaf5a
a9fa1d ¤   ¤   ¤   ¤   if (ret == RFC1847_FAIL)
3afc2c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
abaf5a
4be5d1 ¤   ¤   ¤   ¤   if ((nStatus == FILE1847_OK) && (progress))
d072c3 ¤   ¤   ¤   ¤   {
977576 ¤   ¤   ¤   ¤   ¤   // Update the progress and check for abort
d37fc4 ¤   ¤   ¤   ¤   ¤   nPercentComplete = (int) ((((double)ftell(fIn))/nTotalInLen¶
1f7e6b ) * 100.0);
6d56ae ¤   ¤   ¤   ¤   ¤   if (progress(nPercentComplete) ? 1 : 0)
477618 ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
4b2613 ¤   ¤   ¤   ¤   }
caad4c ¤   ¤   ¤   } while ((nStatus == FILE1847_OK) && (!feof(fIn)) && (!ferror(fIn))¶
b76275 );
26af5a
2c6f1f ¤   ¤   ¤   if (nStatus == FILE1847_OK)
36f776 ¤   ¤   ¤   {
55a14f ¤   ¤   ¤   ¤   if (bReallyParse1) /* Parse part #1 */
c462cc ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(NULL, fOut1, OutPart1MimePtr, bPart1DeMime¶
ebe822 , pParsePart1State))
b3aeb1 ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
8faf5a
592ec9 ¤   ¤   ¤   ¤   if (bReallyParse2) /* Parse part #2 */
a6ab60 ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(NULL, fOut2, OutPart2MimePtr, bPart2DeMime¶
--ab1d 0000b608b4a401101e0 Page 6 of file1847.cpp
953e25 , pParsePart2State))
91aeb1 ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
28a3a6 ¤   ¤   ¤   }
3c0fe4 ¤   ¤   }
470e1d ¤   ¤   else
bcff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
d3af5a
2117d3 ¤   ¤   delete_PartParseState(pParsePart1State);
aac1d4 ¤   ¤   delete_PartParseState(pParsePart2State);
421b52 ¤   ¤
edd92c ¤   ¤   delete_parse_state(pState);
4d67c5 ¤
dc0ee5 ¤   ¤   delete_buf(pOutPart1);
1c2b28 ¤   ¤   delete_buf(pOutPart2);
f97ca0 ¤   ¤   delete_buf(pInBuf);
859371 ¤   }
520e24 ¤   else
5cd0b1 ¤   ¤   nStatus = FILE1847_FAIL; // Files did not open -- error
ecaf5a
b93f89 ¤   safeclose(fIn);
45614f ¤   safeclose(fOut1);
e54482 ¤   safeclose(fOut2);
30af5a
bd844e ¤   return(nStatus);
c8efe6 }
f1af5a
44bf23 /* ------------------------------------------------------------------------ */
ceaf5a
37c4aa /* ·DoCreatePartsOutput (static)
81775e ·*
4e8245 ·* ·Private function used to pipe 1847 output to a file.
d9495d ·*/
0eb798 static int DoCreatePartsOutput(emsMIMEtypeP mimePtr,
f03c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
c6d359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
330bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
ba57e1 ¤   ¤   ¤   ¤   ···FILE *fOut)
20bb36 {
7543e6 ¤   BufTypePtr pOutBuf = makesize_buf(kBufferSize);
43a66d ¤   unsigned int nOutLen, ret;
d557c4 ¤   char *cp;
e0af5a
19723c ¤   if (pOutBuf)
d7c7a1 ¤   {
8433b9 ¤   ¤   if (pInPart1)
268e90 ¤   ¤   ¤   resetpos_buf(pInPart1);
47af5a
64dcdd ¤   ¤   if (pInPart2)
cfab5d ¤   ¤   ¤   resetpos_buf(pInPart2);
90af5a
4a4392 ¤   ¤   do {
dc6916 ¤   ¤   ¤   // Clear the output
c4ce6c ¤   ¤   ¤   emptybuf_buf(pOutBuf);
81af5a
eb5c49 ¤   ¤   ¤   // Do the 1847-dance
fe886c ¤   ¤   ¤   ret = rfc1847_create(mimePtr, pOutBuf, pInPart1, pInPart2, pState);
62af5a
14d054 ¤   ¤   ¤   // Output whatever we got
c46f9f ¤   ¤   ¤   if ((nOutLen = buflen_buf(pOutBuf)) > 0)
84f776 ¤   ¤   ¤   {
84b92e ¤   ¤   ¤   ¤   cp = getbuf_buf(pOutBuf);
b8ea2d ¤   ¤   ¤   ¤   fwrite(cp, 1, nOutLen, fOut);
f2a3a6 ¤   ¤   ¤   }
ea6afd ¤   ¤   } while (ret == RFC1847_BUFFERFULL);
ae9371 ¤   }
290e24 ¤   else
22a89d ¤   ¤   return (FALSE); // Could not create buffer
46af5a
59a169 ¤   delete_buf(pOutBuf);
b8af5a
5f0bfb ¤   return (ret != RFC1847_FAIL);
0befe6 }
--1a49 000b10ee6e2401101e0 Page 7 of file1847.cpp
e0af5a
dabf23 /* ------------------------------------------------------------------------ */
28af5a
411e54 /* ·DoCreateStringOutput (static)
1d775e ·*
a51de2 ·* ·Private function used to send a C-string through the 1847 creator and
7b9019 ·* ·eventually pipe the 1847 output to a file.
2f495d ·*/
8ef32b static int DoCreateStringOutput(const char *pStr,
cce775 ¤   ¤   ¤   ¤   ···int nPart,
0c97ec ¤   ¤   ¤   ¤   ···emsMIMEtypeP mimePtr,
520bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
cc57e1 ¤   ¤   ¤   ¤   ···FILE *fOut)
15bb36 {
1be2ca ¤   BufTypePtr pTmpBuf = make_buf();
950e94 ¤   int ret = RFC1847_FAIL;
96af5a
cef5a1 ¤   if (pTmpBuf)
54c7a1 ¤   {
97385f ¤   ¤   // Manually setup the buffer structure -- kind of ugly, but
f51350 ¤   ¤   // more effiecient than copying the string
ec673c ¤   ¤   pTmpBuf->buf = (char *) pStr;
f8381b ¤   ¤   pTmpBuf->len = strlen(pStr);
6c5407 ¤   ¤   pTmpBuf->buf_size = pTmpBuf->len + 1;
a3d920 ¤   ¤   resetpos_buf(pTmpBuf);
6faf5a
a166e2 ¤   ¤   // Now output the buffer
b41ff2 ¤   ¤   ret = DoCreatePartsOutput(mimePtr,
c72432 ¤   ¤   ¤   ((nPart == 1) ? pTmpBuf : NULL), /* Part 1 */
092eb5 ¤   ¤   ¤   ((nPart == 2) ? pTmpBuf : NULL), /* Part 2 */
8ba8d1 ¤   ¤   ¤   pState,
a6faca ¤   ¤   ¤   fOut);
49af5a
818589 ¤   ¤   clear_buf(pTmpBuf); // Unassociate buffer with string
c31558 ¤   ¤   delete_buf(pTmpBuf); // Delete buffer struct -- AFTER we clear it's con¶
57f3a3 tents
fa9371 ¤   }
fb0e24 ¤   else
25a89d ¤   ¤   return (FALSE); // Could not create buffer
96af5a
c50bfb ¤   return (ret != RFC1847_FAIL);
65efe6 }
b3af5a
e8bf23 /* ------------------------------------------------------------------------ */
3caf5a
d60b1c /* ·DoCreateOnePart (static)
cc775e ·*
e075cd ·* ·Private function used to pipe a given file through the 1847 creator as
df695e ·* ·either part 1 or part 2. All De-mime stuff is also done here.
00495d ·*/
0bbe35 static int DoCreateOnePart(emsMIMEtypeP InPartMimePtr,
9e13ac ¤   ¤   ¤   ¤   ¤   ·emsMIMEtypeP OutMimePtr,
550da2 ¤   ¤   ¤   ¤   ¤   ·TrEncType InPartCTE,
bd4c6a ¤   ¤   ¤   ¤   ¤   ·FILE *fIn,
cd69a4 ¤   ¤   ¤   ¤   ¤   ·FILE *fOut,
120e17 ¤   ¤   ¤   ¤   ¤   ·int nPart,
aaf877 ¤   ¤   ¤   ¤   ¤   ·long nPreLen,
17bfd8 ¤   ¤   ¤   ¤   ¤   ·long nTotalInLen,
2d2114 ¤   ¤   ¤   ¤   ¤   ·createStatePtr pState,
50733c ¤   ¤   ¤   ¤   ¤   ·emsProgress progress)
a5bb36 {
25c2e6 ¤   BufTypePtr pInBuf = makesize_buf(kBufferSize);
a5af5a
fc7662 ¤   if (!pInBuf)
5d1aa4 ¤   ¤   return (FILE1847_FAIL); // Could not create buffer -- error
04af5a
82a5c4 ¤   int nStatus = FILE1847_OK;
bcaf5a
183b64 ¤   // Do InPartMimePtr (Content-Type) header
2b9025 ¤   if ((nStatus == FILE1847_OK) && (InPartMimePtr))
9ac7a1 ¤   {
b191c5 ¤   ¤   char *pCT = string_mime_type(InPartMimePtr);
--9710 000b6617ad6401101e0 Page 8 of file1847.cpp
f11b52 ¤   ¤
8102b4 ¤   ¤   if (pCT)
9b5b34 ¤   ¤   {
5fb399 ¤   ¤   ¤   if (!DoCreateStringOutput(pCT, nPart, OutMimePtr, pState, fOut))
ecfa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
13bb8c ¤   ¤   ¤   else
9a500e ¤   ¤   ¤   ¤   if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fO¶
00df5a ut))
28fc2c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
8a0fe4 ¤   ¤   }
4d0e1d ¤   ¤   else
5bff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
7faf5a
40316a ¤   ¤   safefree(pCT);
2d9371 ¤   }
d7af5a
f163bb ¤   // Do InPartCTE (Content-Transfer-Encoding) header
b8fca4 ¤   if ((nStatus == FILE1847_OK) && (InPartCTE != CTE_NONE))
4fc7a1 ¤   {
aa213d ¤   ¤   char *pCTE = rfc822_make_cte(InPartCTE);
431b52 ¤   ¤
4ff542 ¤   ¤   if (pCTE)
0a5b34 ¤   ¤   {
564ea6 ¤   ¤   ¤   if (!DoCreateStringOutput(pCTE, nPart, OutMimePtr, pState, fOut))
56fa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
1dbb8c ¤   ¤   ¤   else
ac500e ¤   ¤   ¤   ¤   if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fO¶
22df5a ut))
68fc2c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
d50fe4 ¤   ¤   }
cc0e1d ¤   ¤   else
8dff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
91af5a
0bf2b0 ¤   ¤   safefree(pCTE);
349371 ¤   }
b9af5a
afff2f ¤   // Do blank line -- only if we put out some header already
c565b8 ¤   if ((nStatus == FILE1847_OK) && ((InPartMimePtr) || (InPartCTE != CTE_NONE)¶
5bc454 ))
08c7a1 ¤   {
919f1c ¤   ¤   if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fOut))
a4ff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
e79371 ¤   }
8caf5a
111e5a ¤   char *preEncBuffer = NULL;
75241e ¤   unsigned int preEncBufLen;
d1af5a
c19b0d ¤   Enc64Ptr e64state = NULL; // Used by Encode64()
958cae ¤   EncQPPtr eQPstate = NULL; // Used by EucodeQP()
41af5a
1c21b6 ¤   if (nStatus == FILE1847_OK)
cfc7a1 ¤   {
3aa9c0 ¤   ¤   switch (InPartCTE)
7d5b34 ¤   ¤   {
2d0d03 ¤   ¤   ¤   // BASE64
e28a6f ¤   ¤   ¤   case CTE_Base64:
fbf776 ¤   ¤   ¤   {
bbc52e ¤   ¤   ¤   ¤   // BASE64 expands about 1/3
021385 ¤   ¤   ¤   ¤   preEncBufLen = ((kBufferSize * 6) / 10);
622533 ¤   ¤   ¤   ¤   preEncBuffer = (char *) malloc(preEncBufLen);
3eaf5a
14672c ¤   ¤   ¤   ¤   if (!preEncBuffer)
3b795c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL; // Could not create buffer
0caf5a
8f78c4 ¤   ¤   ¤   ¤   e64state = (Enc64Ptr) malloc(sizeof(Enc64)); // Used by Encode6¶
6ba096 4()
dae2bb ¤   ¤   ¤   ¤   e64state->partialCount = e64state->bytesOnLine = 0;
a5a3a6 ¤   ¤   ¤   }
81cdcb ¤   ¤   ¤   break;
9daf5a
b91acb ¤   ¤   ¤   // QUOTED-PRINTABLE
b607eb ¤   ¤   ¤   case CTE_QP:
--f821 00047753207401101e0 Page 9 of file1847.cpp
99f776 ¤   ¤   ¤   {
5b6d85 ¤   ¤   ¤   ¤   // QP expands max of 3 times
39ae86 ¤   ¤   ¤   ¤   preEncBufLen = (kBufferSize / 4);
b32533 ¤   ¤   ¤   ¤   preEncBuffer = (char *) malloc(preEncBufLen);
33af5a
c0672c ¤   ¤   ¤   ¤   if (!preEncBuffer)
96795c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL; // Could not create buffer
9caf5a
b4898b ¤   ¤   ¤   ¤   eQPstate = (EncQPPtr) malloc(sizeof(EncQP)); // Used by Encode6¶
c2a096 4()
c6d6de ¤   ¤   ¤   ¤   eQPstate->nCurLineLen = 0;
4552e3 ¤   ¤   ¤   ¤   eQPstate->cLastChar = '\0';
bda3a6 ¤   ¤   ¤   }
0ecdcb ¤   ¤   ¤   break;
1eaf5a
43d487 ¤   ¤   ¤   // Otherwise, no encoding
a8db68 ¤   ¤   ¤   default:
4ff776 ¤   ¤   ¤   {
51dbe4 ¤   ¤   ¤   ¤   preEncBufLen = 0;
17a3a6 ¤   ¤   ¤   }
8ccdcb ¤   ¤   ¤   break;
a90fe4 ¤   ¤   }
e09371 ¤   }
7eaf5a
644123 ¤   size_t nReadLen = 0;
7d146e ¤   int nPercentComplete = 0;
ccaf5a
62cd49 ¤   // Do pInPartFilename
647861 ¤   while ((nStatus == FILE1847_OK) && (!feof(fIn)) && (!ferror(fIn)))
04c7a1 ¤   {
9bde61 ¤   ¤   emptybuf_buf(pInBuf);
20af5a
dba9c0 ¤   ¤   switch (InPartCTE)
365b34 ¤   ¤   {
4e8a6f ¤   ¤   ¤   case CTE_Base64:
baf776 ¤   ¤   ¤   {
255410 ¤   ¤   ¤   ¤   nReadLen = fread(preEncBuffer, sizeof(char), preEncBufLen, fIn);
52a7cf ¤   ¤   ¤   ¤   nReadLen = Encode64(preEncBuffer, nReadLen, getbuf_buf(pInBuf),¶
25c52a ·e64state);
cca3a6 ¤   ¤   ¤   }
72cdcb ¤   ¤   ¤   break;
beaf5a
5a07eb ¤   ¤   ¤   case CTE_QP:
caf776 ¤   ¤   ¤   {
e55410 ¤   ¤   ¤   ¤   nReadLen = fread(preEncBuffer, sizeof(char), preEncBufLen, fIn);
f4070f ¤   ¤   ¤   ¤   nReadLen = EncodeQP(preEncBuffer, nReadLen, getbuf_buf(pInBuf),¶
b5d2ae ·eQPstate);
7da3a6 ¤   ¤   ¤   }
4acdcb ¤   ¤   ¤   break;
8baf5a
1b0d94 ¤   ¤   ¤   default: /* 7bit, 8bit, binary, none */
c4f776 ¤   ¤   ¤   {
6138dd ¤   ¤   ¤   ¤   nReadLen = fread(getbuf_buf(pInBuf), sizeof(char), bufsize_buf(¶
6e2416 pInBuf), fIn);
49a3a6 ¤   ¤   ¤   }
c8cdcb ¤   ¤   ¤   break;
6b0fe4 ¤   ¤   }
4baf5a
a184fe ¤   ¤   if (nReadLen > 0)
2a5b34 ¤   ¤   {
0c1dbe ¤   ¤   ¤   setlen_buf(pInBuf, nReadLen);
3daf5a
5aa652 ¤   ¤   ¤   if (!DoCreatePartsOutput(OutMimePtr,
351c52 ¤   ¤   ¤   ¤   ¤   ((nPart == 1) ? pInBuf : NULL), /* Part 1 */
1df3f9 ¤   ¤   ¤   ¤   ¤   ((nPart == 2) ? pInBuf : NULL), /* Part 2 */
382440 ¤   ¤   ¤   ¤   ¤   pState,
1385e3 ¤   ¤   ¤   ¤   ¤   fOut))
79fa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
2c0fe4 ¤   ¤   }
8eaf5a
593f2a ¤   ¤   if ((nStatus == FILE1847_OK) && (progress))
475b34 ¤   ¤   {
--b67e 000af056916401101e0 Page 10 of file1847.cpp
6c72af ¤   ¤   ¤   // Update the progress and check for abort
dfbf27 ¤   ¤   ¤   nPercentComplete = (int) (((((double)ftell(fIn) + nPreLen))/nTotalI¶
e8a072 nLen) * 100.0);
808c55 ¤   ¤   ¤   if (progress(nPercentComplete) ? 1 : 0)
0900e3 ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
ee0fe4 ¤   ¤   }
329371 ¤   }
b4af5a
4921b6 ¤   if (nStatus == FILE1847_OK)
6ac7a1 ¤   {
9c2a0b ¤   ¤   // Finish part -- if needed
08a9c0 ¤   ¤   switch (InPartCTE)
225b34 ¤   ¤   {
e28a6f ¤   ¤   ¤   case CTE_Base64:
89f776 ¤   ¤   ¤   {
0fd7a6 ¤   ¤   ¤   ¤   nReadLen = Encode64(NULL, 0, getbuf_buf(pInBuf), e64state);
17a3a6 ¤   ¤   ¤   }
91cdcb ¤   ¤   ¤   break;
81af5a
7e07eb ¤   ¤   ¤   case CTE_QP:
43f776 ¤   ¤   ¤   {
21f066 ¤   ¤   ¤   ¤   nReadLen = EncodeQP(NULL, 0, getbuf_buf(pInBuf), eQPstate);
b8a3a6 ¤   ¤   ¤   }
eacdcb ¤   ¤   ¤   break;
0faf5a
e90d94 ¤   ¤   ¤   default: /* 7bit, 8bit, binary, none */
91f776 ¤   ¤   ¤   {
9b1694 ¤   ¤   ¤   ¤   nReadLen = 0;
56a3a6 ¤   ¤   ¤   }
5dcdcb ¤   ¤   ¤   break;
ec0fe4 ¤   ¤   }
0baf5a
e684fe ¤   ¤   if (nReadLen > 0)
df5b34 ¤   ¤   {
351dbe ¤   ¤   ¤   setlen_buf(pInBuf, nReadLen);
daaf5a
cda652 ¤   ¤   ¤   if (!DoCreatePartsOutput(OutMimePtr,
351c52 ¤   ¤   ¤   ¤   ¤   ((nPart == 1) ? pInBuf : NULL), /* Part 1 */
28f3f9 ¤   ¤   ¤   ¤   ¤   ((nPart == 2) ? pInBuf : NULL), /* Part 2 */
302440 ¤   ¤   ¤   ¤   ¤   pState,
b085e3 ¤   ¤   ¤   ¤   ¤   fOut))
bdfa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
1b0fe4 ¤   ¤   }
c09371 ¤   }
58af5a
3a52d2 ¤   safefree(e64state);
894556 ¤   safefree(eQPstate);
782871 ¤   safefree(preEncBuffer);
d18ac5 ¤   delete_buf(pInBuf);
82af5a
3083bb ¤   return (nStatus);
bdefe6 }
47af5a
cbbf23 /* ------------------------------------------------------------------------ */
2baf5a
57a4cd /* ·DoParsePart (static)
1e775e ·*
72a66d ·* ·Private function used to pipe the output of 1847 parsing into a file.
06495d ·*/
33c02d static int DoParsePart(BufTypePtr pInBuf,
12d2f2 ¤   ¤   ¤   ¤   ·FILE *fOut,
e17303 ¤   ¤   ¤   ¤   ·emsMIMEtypeP *mimePtr,
8a3632 ¤   ¤   ¤   ¤   ·int bDeMime,
5ac875 ¤   ¤   ¤   ¤   ·PartParseStatePtr pState)
ccbb36 {
ed41b2 ¤   if (!pInBuf) // Input buf NULL indicates 'cleanup'
06c7a1 ¤   {
272a9b ¤   ¤   if (!pState->bFoundHeader)
3fd10c ¤   ¤   ¤   return (FALSE);
9a0e1d ¤   ¤   else
1e3ec8 ¤   ¤   ¤   return (TRUE);
af9371 ¤   }
--6ad8 00036d40abf401101e0 Page 11 of file1847.cpp
e0af5a
4ba6e4 ¤   if (!pState->bFoundHeader)
7fc7a1 ¤   {
641a52 ¤   ¤   resetpos_buf(pState->pSearchBuf);
70af5a
4bcbc9 ¤   ¤   if (pState->nPrevEndMatch > 0)
e25b34 ¤   ¤   {
c0bba0 ¤   ¤   ¤   /* Check for completion of span */
60af5a
aed467 ¤   ¤   ¤   // If doesn't continue match, returns zero
367a08 ¤   ¤   ¤   // otherwise returns number of chars of pSearchBuf that have been m¶
57bf21 atched
4de594 ¤   ¤   ¤   unsigned int nNewMatched = completecount_buf(pInBuf, pState->pSearc¶
350366 hBuf, pState->nPrevEndMatch);
2faf5a
f712e3 ¤   ¤   ¤   if (nNewMatched == buflen_buf(pState->pSearchBuf)) /* complete matc¶
9cd11b h made */
66f776 ¤   ¤   ¤   {
8807cc ¤   ¤   ¤   ¤   pState->bFoundHeader = TRUE;
6b0acc ¤   ¤   ¤   ¤   pState->nPrevEndMatch = 0;
29199d ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, (buflen_buf(pState->pSearchBu¶
01e0f3 f) - (pState->nPrevEndMatch)));
80a3a6 ¤   ¤   ¤   }
a588c3 ¤   ¤   ¤   else if (nNewMatched != 0) /* Continued to match, but not completed¶
a2fb71 ·yet -- the input buffer is smaller than the pSearchBuf */
71f776 ¤   ¤   ¤   {
dc405f ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
452d2b ¤   ¤   ¤   ¤   pState->nPrevEndMatch = nNewMatched;
722ae0 ¤   ¤   ¤   ¤   return (TRUE);
4da3a6 ¤   ¤   ¤   }
262f52 ¤   ¤   ¤   else /* No match continuation */
04f776 ¤   ¤   ¤   {
9d0acc ¤   ¤   ¤   ¤   pState->nPrevEndMatch = 0;
6da3a6 ¤   ¤   ¤   }
e30fe4 ¤   ¤   }
31af5a
a61a52 ¤   ¤   resetpos_buf(pState->pSearchBuf);
59af5a
57b655 ¤   ¤   // Still not found -- no span
192a9b ¤   ¤   if (!pState->bFoundHeader)
bf5b34 ¤   ¤   {
c3f409 ¤   ¤   ¤   // Find match of pSearchBuf, either complete or end-spanning
7fd546 ¤   ¤   ¤   // return number of chars to skip before match
c08930 ¤   ¤   ¤   unsigned int nSkip = skipcount_buf(pInBuf, pState->pSearchBuf);
1e1996 ¤   ¤   ¤   unsigned int nRemain = poslen_buf(pInBuf) - nSkip;
f6af5a
89c888 ¤   ¤   ¤   if (nRemain == 0) // Not found
daf776 ¤   ¤   ¤   {
99405f ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
972ae0 ¤   ¤   ¤   ¤   return (TRUE);
9ea3a6 ¤   ¤   ¤   }
86bb8c ¤   ¤   ¤   else
fabc95 ¤   ¤   ¤   if (nRemain > buflen_buf(pState->pSearchBuf)) /* Found 'complete' */
dff776 ¤   ¤   ¤   {
2b07cc ¤   ¤   ¤   ¤   pState->bFoundHeader = TRUE;
2a429c ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, (nSkip + buflen_buf(pState->p¶
339596 SearchBuf)) );
2ca3a6 ¤   ¤   ¤   }
5a2a40 ¤   ¤   ¤   else // Partial possible
76f776 ¤   ¤   ¤   {
13ea66 ¤   ¤   ¤   ¤   pState->nPrevEndMatch = nRemain;
0b405f ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
9a2ae0 ¤   ¤   ¤   ¤   return (TRUE);
0ea3a6 ¤   ¤   ¤   }
380fe4 ¤   ¤   }
f0af5a
14385e ¤   ¤   // ---------- Now we know it is found ----------
d4af5a
caa61f ¤   ¤   unsigned int nLen = buflen_buf(pState->pBuf);
95bfec ¤   ¤   char *pHeader = (char *) malloc(nLen + 1);
d74bab ¤   ¤   strncpy(pHeader, getbuf_buf(pState->pBuf), nLen);
36af5a
--dc8a 00074350355401101e0 Page 12 of file1847.cpp
6f3bd5 ¤   ¤   char *pCT = rfc822_extract_header(pHeader, "Content-Type:");
13af5a
031f89 ¤   ¤   if (mimePtr)
016e24 ¤   ¤   ¤   *mimePtr = parse_make_mime_type(pCT);
42af5a
1849bf ¤   ¤   if (bDeMime)
a45b34 ¤   ¤   {
134496 ¤   ¤   ¤   char *pCTE = rfc822_extract_cte(pHeader);
e8cfd8 ¤   ¤   ¤   if (pCTE)
228e90 ¤   ¤   ¤   ¤   pState->cte = rfc822_parse_cte(pCTE);
a9bb8c ¤   ¤   ¤   else
e06301 ¤   ¤   ¤   ¤   pState->cte = CTE_NONE; /* No CTE header, so no encoding */
25af5a
d86552 ¤   ¤   ¤   switch (pState->cte)
def776 ¤   ¤   ¤   {
3bcab6 ¤   ¤   ¤   ¤   // BASE64
dd3139 ¤   ¤   ¤   ¤   case CTE_Base64:
9572c3 ¤   ¤   ¤   ¤   {
95dd7e ¤   ¤   ¤   ¤   ¤   // BASE64 expands about 1/3
c2df72 ¤   ¤   ¤   ¤   ¤   unsigned int preEncBufLen = ((kBufferSize * 10) / 6);
4f2a85 ¤   ¤   ¤   ¤   ¤   pState->preEncBuffer = (char *) malloc(preEncBufLen);
e6af5a
66b7ef ¤   ¤   ¤   ¤   ¤   pState->d64state = (Dec64Ptr) malloc(sizeof(Dec64)); // Use¶
526c39 d by Decode64()
836975 ¤   ¤   ¤   ¤   ¤   pState->d64state->decoderState = 0;
2bf8a7 ¤   ¤   ¤   ¤   ¤   pState->d64state->invalCount = 0;
bfc1ec ¤   ¤   ¤   ¤   ¤   pState->d64state->padCount = 0;
ffa97f ¤   ¤   ¤   ¤   ¤   pState->d64state->partial = 0;
eeb197 ¤   ¤   ¤   ¤   ¤   pState->d64state->wasCR = FALSE;
b62613 ¤   ¤   ¤   ¤   }
e2f622 ¤   ¤   ¤   ¤   break;
81af5a
b69137 ¤   ¤   ¤   ¤   // QUOTED-PRINTABLE
3633b6 ¤   ¤   ¤   ¤   case CTE_QP:
1f72c3 ¤   ¤   ¤   ¤   {
c73f18 ¤   ¤   ¤   ¤   ¤   // QP expands max of 3 times
e7c730 ¤   ¤   ¤   ¤   ¤   unsigned int preEncBufLen = (kBufferSize * 4);
6b2a85 ¤   ¤   ¤   ¤   ¤   pState->preEncBuffer = (char *) malloc(preEncBufLen);
48af5a
30acda ¤   ¤   ¤   ¤   ¤   pState->dQPstate = (DecQPPtr) malloc(sizeof(EncQP));
32816c ¤   ¤   ¤   ¤   ¤   pState->dQPstate->CurState = qpNormal;
585754 ¤   ¤   ¤   ¤   ¤   pState->dQPstate->cLastChar = 0;
032613 ¤   ¤   ¤   ¤   }
86f622 ¤   ¤   ¤   ¤   break;
d5af5a
71e869 ¤   ¤   ¤   ¤   // Otherwise, no encoding
296ab9 ¤   ¤   ¤   ¤   default:
98f622 ¤   ¤   ¤   ¤   break;
a2a3a6 ¤   ¤   ¤   }
4d0fe4 ¤   ¤   }
0e0e1d ¤   ¤   else
cd5b34 ¤   ¤   {
d27fbe ¤   ¤   ¤   fwrite(getbuf_buf(pState->pBuf), sizeof(char), nLen, fOut);
da0fe4 ¤   ¤   }
a3af5a
b887c1 ¤   ¤   free_buf(pState->pBuf);
8b9371 ¤   }
b7af5a
d5f329 ¤   // ---------- Now we know it is found and header is init'd ----------
dfaf5a
32bcc3 ¤   long errorcnt;
81af5a
17ea59 ¤   switch (pState->cte)
77c7a1 ¤   {
42be32 ¤   ¤   case CTE_Base64:
a95b34 ¤   ¤   {
ac1014 ¤   ¤   ¤   unsigned int nReadLen = Decode64(getpos_buf(pInBuf), poslen_buf(pIn¶
a8149c Buf), pState->preEncBuffer, pState->d64state, &errorcnt);
e73a53 ¤   ¤   ¤   fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut);
530fe4 ¤   ¤   }
842f68 ¤   ¤   break;
74af5a
--77b2 0001ba4a120401101e0 Page 13 of file1847.cpp
feb63a ¤   ¤   case CTE_QP:
5f5b34 ¤   ¤   {
2170b8 ¤   ¤   ¤   unsigned int nReadLen = DecodeQP(getpos_buf(pInBuf), poslen_buf(pIn¶
face75 Buf), pState->preEncBuffer, pState->dQPstate, &errorcnt);
893a53 ¤   ¤   ¤   fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut);
210fe4 ¤   ¤   }
b42f68 ¤   ¤   break;
39af5a
399bd5 ¤   ¤   default: /* 7bit, 8bit, binary, none */
995b34 ¤   ¤   {
6d4af9 ¤   ¤   ¤   fwrite(getpos_buf(pInBuf), sizeof(char), poslen_buf(pInBuf), fOut);
930fe4 ¤   ¤   }
ad2f68 ¤   ¤   break;
459371 ¤   }
c2af5a
7be7c0 ¤   return (TRUE);
a7efe6 }
3daf5a
b5bf23 /* ------------------------------------------------------------------------ */
27af5a
a0da0d /* ·create_PartParseState (static)
b6775e ·*
c087a2 ·* ·Private function used initialize the parse state.
37495d ·*/
99cae8 static PartParseStatePtr create_PartParseState()
3ebb36 {
0bac27 ¤   PartParseStatePtr p = (PartParseStatePtr) malloc(sizeof(PartParseState));
b5af5a
ee68fc ¤   if (p)
68c7a1 ¤   {
06c42a ¤   ¤   p->bFoundHeader = FALSE;
b542b8 ¤   ¤   p->pBuf = make_buf();
4e6c36 ¤   ¤   p->pSearchBuf = make_buf();
e0a9a4 ¤   ¤   strcpy_buf(p->pSearchBuf, "\r\n\r\n");
c2a625 ¤   ¤   p->cte = CTE_NONE;
3db628 ¤   ¤   p->nPrevEndMatch = 0;
5af8bf ¤   ¤   p->preEncBuffer = NULL;
7a8034 ¤   ¤   p->d64state = NULL;
ad11a6 ¤   ¤   p->dQPstate = NULL;
519371 ¤   }
40af5a
3c70cd ¤   return (p);
3fefe6 }
02af5a
7abf23 /* ------------------------------------------------------------------------ */
41af5a
b044ed /* ·delete_PartParseState (static)
e8775e ·*
b7eb66 ·* ·Private function used to delete the parse state.
18495d ·*/
95dcba static void delete_PartParseState(PartParseStatePtr p)
fcbb36 {
8468fc ¤   if (p)
79c7a1 ¤   {
0bb27f ¤   ¤   delete_buf(p->pBuf);
c72ca3 ¤   ¤   delete_buf(p->pSearchBuf);
bf5794 ¤   ¤   safefree(p->preEncBuffer);
c42010 ¤   ¤   safefree(p->d64state);
1f3794 ¤   ¤   safefree(p->dQPstate);
911b52 ¤   ¤
4dc706 ¤   ¤   safefree(p);
649371 ¤   }
ebefe6 }
11af5a
0fbf23 /* ------------------------------------------------------------------------ */
53af5a
2c0892 /* ·DoBufOutput (static)
c1775e ·*
568bfa ·* ·Private function used to output a buffer.
27495d ·*/
0e5190 static void DoBufOutput(FILE *fOut, BufTypePtr pBuf)
1bbb36 {
--4506 001d6295d76401101e0 Page 14 of file1847.cpp
2010fc ¤   fwrite(getpos_buf(pBuf), sizeof(char), poslen_buf(pBuf), fOut);
d6be43 }¶
--af45 000f4655076401101e1 Page 1 of file1847.h
bc38e5 /*
d75fd4 ·* ·Filename: file1847.h
29775e ·*
92e658 ·* ·Last Edited: Wednesday, October 2, 1996
6e775e ·*
35005b ·* ·Author: Scott Manjourides
94775e ·*
11ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
b4775e ·*
f3c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
d7495d ·*/
d3af5a
bf6b95 #ifndef EMS_FILE1847_H
bb3c64 #define EMS_FILE1847_H
18af5a
12568d #include <windows.h> /* Must be included for ems-win.h */
18fbd1 #include "ems-win.h"
3aaf5a
46bde1 #include "encoding.h"
2527f6 #include "rfc1847.h"
d3af5a
ed18b2 enum { FILE1847_FAIL = (-1), FILE1847_ABORT = (0), FILE1847_OK = (1) };
c4af5a
8b7890 /* ------------------------------------------------------------------------- */
76af5a
67ee80 /* ·CreateTmpFile
b6775e ·*
b66438 ·* ·Creates a empty, unique, temporary file in the users 'TEMP'
eb4970 ·* ···directory.
fe775e ·*
5db7ce ·* ·No arguments.
2c775e ·*
a359a2 ·* ·Returns a pointer to the filename string. This should be
2acb59 ·* ···considered temporary data, and should never be free()'d.
9d495d ·*/
970870 char *CreateTmpFile();
15af5a
ebbf23 /* ------------------------------------------------------------------------ */
e7af5a
85dc23 /* ·rfc1847_file_create
6f775e ·*
ba9c8e ·* ·Creates RFC1847 MIME structure.
2c775e ·*
9e6a22 ·* ·Args:
5d3da4 ·* ···pOutFilename ····[IN] ····Output filename ** WRITE-ONLY **
a81aa8 ·* ···OutMimePtr ······[IN/OUT] MIME type of output -- boundary param will be a¶
19f634 dded
31a061 ·* ···InPart1MimePtr ··[IN] ····MIME type of part 1
4a43df ·* ···InPart1CTE ······[IN] ····Content-transfer-encoding for part 1
d21941 ·* ···pInPart1Filename [IN] ····Input filename for part 1 ** READ-ONLY **
269847 ·* ···InPart2MimePtr ··[IN] ····MIME type of part 2
591fd0 ·* ···InPart2CTE ······[IN] ····Content-transfer-encoding for part 2
1480bd ·* ···pInPart2Filename [IN] ····Input filename for part 2 ** READ-ONLY **
f519c2 ·* ···progress ········[IN] ····EMS progress callback function
8d775e ·*
af0ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
9e495d ·*/
21c7ea int rfc1847_file_create(const char *pOutFilename,
1f303e ¤   ¤   ¤   ¤   ···emsMIMEtypeP OutMimePtr,
9caf5a
860178 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart1MimePtr,
75cfb5 ¤   ¤   ¤   ¤   ···TrEncType InPart1CTE,
ed35df ¤   ¤   ¤   ¤   ···const char *pInPart1Filename,
33af5a
b07511 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart2MimePtr,
33c3c8 ¤   ¤   ¤   ¤   ···TrEncType InPart2CTE,
2acb6c ¤   ¤   ¤   ¤   ···const char *pInPart2Filename,
fdaf5a
4fd178 ¤   ¤   ¤   ¤   ···emsProgress progress);
f8af5a
b1bf23 /* ------------------------------------------------------------------------ */
f4af5a
--1304 00170b445b8401101e1 Page 2 of file1847.h
31aa24 /* ·rfc1847_file_parse
96775e ·*
a9911a ·* ·Parses RFC1847 MIME structure.
c3775e ·*
5b6a22 ·* ·Args:
04894a ·* ···pInFilename ······[IN] ·Input filename of file to parse ** READ-ONLY **
4dd77d ·* ···InMimePtr ········[OUT] MIME type of input file
14974c ·* ···pOutPart1Filename [IN] ·Output filename for part 1 ** WRITE-ONLY **
9d2072 ·* ···OutPart1MimePtr ··[OUT] MIME type of created part 1
1a8f77 ·* ···bPart1DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
4ff1f2 t 1?
9e07da ·* ···pOutPart2Filename [IN] ·Output filename for part 2 ** WRITE-ONLY **
aa5057 ·* ···OutPart2MimePtr ··[OUT] MIME type of created part 2
e72f00 ·* ···bPart2DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
021e96 t 2?
e94ccd ·* ···progress ·········[IN] ·EMS progress callback function
20775e ·*
170ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
57495d ·*/
66c74a int rfc1847_file_parse(const char *pInFilename,
c43a88 ¤   ¤   ¤   ¤   ··emsMIMEtypeP *InMimePtr,
9eaf5a
0cfb99 ¤   ¤   ¤   ¤   ··const char *pOutPart1Filename,
e5af17 ¤   ¤   ¤   ¤   ··emsMIMEtypeP *OutPart1MimePtr,
7aaddb ¤   ¤   ¤   ¤   ··int bPart1DeMime,
38af5a
ab052a ¤   ¤   ¤   ¤   ··const char *pOutPart2Filename,
35db7e ¤   ¤   ¤   ¤   ··emsMIMEtypeP *OutPart2MimePtr,
287bdc ¤   ¤   ¤   ¤   ··int bPart2DeMime,
ed7e90 ¤   ¤   ¤   ¤   ··
b429d5 ¤   ¤   ¤   ¤   ··emsProgress progress);
5eaf5a
702c19 #endif /* EMS_FILE1847_H */¶

--f474 00110631257401101e2 Page 1 of DisplayMessage.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
59976c ¤   DisplayMessage.c,v 1.3 1997/07/21 06:03:26 elrod Exp
b2f7f7 ____________________________________________________________________________*/
87af5a
6f9b16 // System Headers
b35655 #include <windows.h>
2faf5a
1ce8e0 // Project Headers
0d8031 #include "resource.h"
5aaf5a
dad2af int DisplayMessage(HWND hwnd, long StringId, long TitleId, UINT buttons)
36bb36 {
4f3b0b ¤   char szMessageBuffer[1024];
290278 ¤   char szTitleBuffer[256];
670bf5 ¤   HINSTANCE hInst = NULL;
47af5a
9e5c2a ¤   hInst = GetModuleHandle("PGPplugin.dll");
10af5a
869437 ¤   LoadString(hInst, StringId, szMessageBuffer, sizeof(szMessageBuffer));
b5e1ad ¤   LoadString(hInst, TitleId, szTitleBuffer, sizeof(szTitleBuffer));
faaf5a
0e6ad6 ¤   return MessageBox(hwnd, szMessageBuffer, szTitleBuffer, buttons);
10efe6 }
--3549 001f7c91618401101e3 Page 1 of DisplayMessage.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
389b65 ¤   DisplayMessage.h,v 1.3 1997/07/21 06:03:27 elrod Exp
2cf7f7 ____________________________________________________________________________*/
0f0776 #ifndef Included_DisplayMessage_h¤  /* [ */
2bd435 #define Included_DisplayMessage_h
f7af5a
ef3379 #ifdef __cplusplus
186dad extern "C" {
e17454 #endif
3baf5a
de5d0f int DisplayMessage(HWND hwnd, long StringId, long TitleId, UINT buttons);
13af5a
19af5a
8a3379 #ifdef __cplusplus
71efe6 }
6e7454 #endif
4faf5a
a5af5a
41af5a
5cb1f5 #endif /* ] Included_DisplayMessage_h */
3aaf5a
edaf5a
db7e4d /*__Editor_settings____
f7af5a
524126 ¤   Local Variables:
657b17 ¤   tab-width: 4
050e6c ¤   End:
2d5f8c ¤   vi: ts=4 sw=4
5e9e9b ¤   vim: si
f7d062 _____________________*/
--57a1 00144792a9d401101e4 Page 1 of MapFile.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
1efa66 ¤   MapFile.c,v 1.3 1997/07/16 05:51:49 elrod Exp
dbf7f7 ____________________________________________________________________________*/
17af5a
889b16 // System Headers
ef5655 #include <windows.h>
e9af5a
cef4d6 char* MapFile(const char* Path, DWORD* FileSize)
fbbb36 {
daafa7 ¤   char* cp = NULL;
7df5a3 ¤   char* pBeginning = NULL;
b14331 ¤   HANDLE fh = NULL;
c9287f ¤   DWORD Bytes;
51af5a
cfbbf6 ¤   fh = CreateFile(Path,·
93bdd2 ¤   ¤   ¤   ¤   ¤   GENERIC_READ,·
83f1ff ¤   ¤   ¤   ¤   ¤   FILE_SHARE_READ|FILE_SHARE_WRITE,·
03c55d ¤   ¤   ¤   ¤   ¤   NULL,·
98cecb ¤   ¤   ¤   ¤   ¤   OPEN_EXISTING,·
d7a5b7 ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,
56d98c ¤   ¤   ¤   ¤   ¤   NULL);
44af5a
31e5f7 ¤   if(fh != INVALID_HANDLE_VALUE)
02c7a1 ¤   {
f3f9b5 ¤   ¤   *FileSize = ·GetFileSize(fh, NULL);
5eaf5a
84b0ca ¤   ¤   if(*FileSize > 0)
605b34 ¤   ¤   {
2a26d2 ¤   ¤   ¤   pBeginning = (char*) malloc (*FileSize + 1);
d0af5a
11ec7d ¤   ¤   ¤   if(!pBeginning)
2ff776 ¤   ¤   ¤   {
04fb5e ¤   ¤   ¤   ¤   return NULL;
37a3a6 ¤   ¤   ¤   }
dbaf5a
5b95c4 ¤   ¤   ¤   cp = pBeginning;
caaf5a
7702fe ¤   ¤   ¤   ReadFile(fh, cp, *FileSize, &Bytes, NULL);
9eaf5a
6ca0cf ¤   ¤   ¤   *(cp+(*FileSize)) = 0x00;¤
a10fe4 ¤   ¤   }
050e1d ¤   ¤   else
b15b34 ¤   ¤   {
3dc825 ¤   ¤   ¤   pBeginning = (char*) malloc (1);
59af5a
fbe4f2 ¤   ¤   ¤   if(pBeginning)
e9f776 ¤   ¤   ¤   {
d55182 ¤   ¤   ¤   ¤   *pBeginning = 0x00;
43a3a6 ¤   ¤   ¤   }
9b0fe4 ¤   ¤   }
eaaf5a
8b6425 ¤   ¤   CloseHandle( fh );
d69371 ¤   }
59af5a
707df5 ¤   return pBeginning;
7defe6 }
44af5a
--f5a7 00152f6735b401101e5 Page 1 of MapFile.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
3e2d03 ¤   $Id: MapFile.h,v 1.2.8.1 1998/11/12 03:11:47 heller Exp $
54f7f7 ____________________________________________________________________________*/
427602 #ifndef Included_MapFile_h¤ /* [ */
6ff352 #define Included_MapFile_h
9aaf5a
2caf5a
fb3379 #ifdef __cplusplus
716dad extern "C" {
2a7454 #endif
60af5a
34b36f char* MapFile(const char* Path, DWORD* FileSize);
4baf5a
4baf5a
ce3379 #ifdef __cplusplus
11efe6 }
007454 #endif
24af5a
eddafa #endif /* ] Included_MapFile_h */
14af5a
3caf5a
567e4d /*__Editor_settings____
1aaf5a
674126 ¤   Local Variables:
837b17 ¤   tab-width: 4
ec0e6c ¤   End:
ab5f8c ¤   vi: ts=4 sw=4
5c9e9b ¤   vim: si
f5d062 _____________________*/
9eaf5a
52af5a
--ecc9 0007bf9e125401101e6 Page 1 of MyMIMEUtils.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
924fa7 ¤   $Id: MyMIMEUtils.c,v 1.2.8.1 1998/11/12 03:11:47 heller Exp $
50f7f7 ____________________________________________________________________________*/
76af5a
9d9b16 // System Headers
e05655 #include <windows.h>
d8af5a
d75582 // PGPsdk Headers
bae2ff #include "pgpConfig.h"
6fa076 #include "pgpKeys.h"
ff2f8d #include "pgpErrors.h"
f34919 #include "pgpUtilities.h"
780d08 #include "pgpMem.h"
38af5a
834f9a // Eudora Headers
cb5e47 #include "emssdk/ems-win.h"
bc0011 #include "emssdk/mimetype.h"
e84cfb #include "emssdk/encoding.h"
8baf5a
4ae8e0 // Project Headers
56bead #include "MapFile.h"
f6bbc6 #include "TranslatorUtils.h"
432bcf #include "MyMIMEUtils.h"
12af5a
6eaf5a
82ea3d /*_______________________________________________________________
28b7d7 ¤   *ppMimeType is set to NULL if no valid Content-type is found.
1582b4 ________________________________________________________________*/
d4af5a
f96d52 ¤   void
3f44c8 ParseMIMEType(
6d87e0 ¤   const char*¤¤   ¤   szText,
7265ad ¤   emsMIMEtype**¤  ppMimeType
cb5b71 )
36bb36 {
3f9de1 ¤   *ppMimeType¤= NULL;
a667c5 ¤
b478b0 ¤   *ppMimeType = parse_make_mime_type(szText);
07af5a
c0ff86 ¤   if ( *ppMimeType )
3cc7a1 ¤   {
6219e4 ¤   ¤   // parse_mime_ct doesn't fill in mime_version
cff7a3 ¤   ¤   (*ppMimeType)->version = strdup( "1.0");
af9371 ¤   }
edefe6 }
dfaf5a
b96fcf long
d15934 ParseFileForMIMEType(
b4eff6 ¤   const char *¤   ¤   szInputFile,
ec9835 ¤   emsMIMEtype**¤  ¤   ppMimeType
c45b71 )
d7bb36 {
f0d183 ¤   long err = 0;
7b34f2 ¤   char* buffer = NULL;
356ea9 ¤   DWORD length = 0;
c5af5a
5221b8 ¤   buffer¤ = MapFile( szInputFile, &length );
bc67c5 ¤
e1aaf3 ¤   if ( buffer )
65c7a1 ¤   {
e62680 ¤   ¤   ParseMIMEType( buffer, ppMimeType);
92af5a
cebdd7 ¤   ¤   free(buffer);
259371 ¤   }
ea0e24 ¤   else
47c7a1 ¤   {
7bf0bf ¤   ¤   err = 1;
--7360 001d28b54ec401101e6 Page 2 of MyMIMEUtils.c
a19371 ¤   }
9967c5 ¤
c7deb7 ¤   return( err );
6aefe6 }
baaf5a
aeaf5a
02af5a
86af5a
d2af5a
--8b24 001e0232a9d401101e7 Page 1 of MyMIMEUtils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e50d96 ¤   $Id: MyMIMEUtils.h,v 1.2.8.1 1998/11/12 03:11:48 heller Exp $
aaf7f7 ____________________________________________________________________________*/
29364c #ifndef Included_MyMIMEUtils_h¤ /* [ */
865dae #define Included_MyMIMEUtils_h
96af5a
8faf5a
39d83c ·
3f5e47 #include "emssdk/ems-win.h"
05af5a
bbf7a4 long ParseFileForMIMEType(
daeff6 ¤   const char *¤   ¤   szInputFile,
889835 ¤   emsMIMEtype**¤  ¤   ppMimeType
136275 );
3faf5a
10ab08 void ParseMIMEType(·
a3dafa ¤   const char* szText,·
d69830 ¤   emsMIMEtype** ppMimeType
a76275 );
14af5a
fcaf5a
0560b2 #endif /* ] Included_MyMIMEUtils_h */
99af5a
5aaf5a
7e7e4d /*__Editor_settings____
38af5a
164126 ¤   Local Variables:
047b17 ¤   tab-width: 4
240e6c ¤   End:
255f8c ¤   vi: ts=4 sw=4
b79e9b ¤   vim: si
f6d062 _____________________*/
e0af5a
--9285 00197eaf011401101e8 Page 1 of PGPplugin.def
412cc6 ; PGPplugin.def : Declares the module parameters for the DLL.
d1af5a
0162dd LIBRARY ·····"pgpEudoraPluginV4.dll"
861239 DESCRIPTION ·'pgpEudoraPluginV4 Windows Dynamic Link Library'
81af5a
49ef2b EXPORTS
415002 ¤   ems_plugin_version
3c1d6e ¤   ems_plugin_init
456332 ¤   ems_translator_info
b7b259 ¤   ems_can_translate
44434c ¤   ems_translate_file
2a7e78 ¤   ems_plugin_config
01acd2 ¤   ems_special_info
b64053 ¤   ems_special_hook
4451ff ¤   ems_plugin_finish
97bf32 ¤   ems_free
--196c 0001a395bac401101e9 Page 1 of PGPplugin.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
6d6c0e /////////////////////////////////////////////////////////////////////////////
81465d //
fbcbaf // Icon
7c465d //
56af5a
e52951 // Icon with lowest ID value placed first to ensure application icon
d50f06 // remains consistent on all systems.
d6e819 IDI_PGP_DECRYPT ········ICON ···DISCARDABLE ····"res\\unlock.ico"
f86f1e IDI_PGP_VERIFY ·········ICON ···DISCARDABLE ····"res\\verify.ico"
45c065 IDI_PGP32 ··············ICON ···DISCARDABLE ····"res\\pgp50.ico"
8e7c3b IDI_PGP_SIGN ···········ICON ···DISCARDABLE ····"res\\sign.ico"
386d43 IDI_PGP_ENCRYPT ········ICON ···DISCARDABLE ····"Res\\lock.ico"
30860f IDI_PGP_KEYS ···········ICON ···DISCARDABLE ····"res\\key.ico"
914ce7 IDI_PGP_ENCRYPT_SIGN ···ICON ···DISCARDABLE ····"res\\encryptsign.ico"
90af5a
96f860 #ifdef APSTUDIO_INVOKED
f46c0e /////////////////////////////////////////////////////////////////////////////
e6465d //
cc5733 // TEXTINCLUDE
fe465d //
34af5a
5c86ef 1 TEXTINCLUDE DISCARDABLE·
704523 BEGIN
d9541e ····"resource.h\0"
ace0d1 END
e6af5a
527037 2 TEXTINCLUDE DISCARDABLE·
654523 BEGIN
feeb23 ····"#include ""afxres.h""\r\n"
56db5c ····"\0"
d7e0d1 END
5caf5a
1e227f 3 TEXTINCLUDE DISCARDABLE·
d74523 BEGIN
2182bb ····"#include ""PGPpluginVer.rc""\r\n"
ca4537 ····"#include ""..\\shared\\Working.rc""\r\n"
516c56 ····"#include ""..\\shared\\SharedStrings.rc""\r\n"
addb5c ····"\0"
17e0d1 END
51af5a
d969ab #endif ···// APSTUDIO_INVOKED
c1af5a
aaaf5a
976c0e /////////////////////////////////////////////////////////////////////////////
61465d //
375e87 // String Table
2d465d //
6daf5a
1a6f6c STRINGTABLE DISCARDABLE·
--3e59 001dd19b319401101e9 Page 2 of PGPplugin.rc
254523 BEGIN
9a99c1 ····IDS_WARN_NORECIPIENTS ··"In order to Encrypt you must choose\nat least one ¶
575f9a recipient."
8b05e0 ····IDS_WARN_NORECIPIENTSTITLE "No Recpients Chosen"
d82d40 ····IDS_TITLE_RECIPIENTDIALOG "PGP Eudora - Encrypt Message To..."
80655a ····IDS_TITLE_PGPERROR ·····"PGP Error"
726f95 ····IDS_SUCCESS_ADDKEY ·····"PGP successfully added the key(s) to your keyring."
3cdc71 ····IDS_TITLE_ADDKEY ·······"PGP Eudora - Extract Key"
5d4957 ····IDS_STRING8 ············"Reserved"
7b4d2c ····IDS_STRING9 ············"Reserved"
e81bc1 ····IDS_TOOLTIP1 ···········"Decrypt PGP Encrypted Email Message"
ee1d5b ····IDS_TOOLTIP2 ···········"Extract PGP Key(s) from Email Message"
e980fe ····IDS_TOOLTIP3 ···········"Launch PGPkeys Application"
b8535e ····IDS_TOOLTIP4 ···········"Just Do It!"
0f8142 ····IDS_TOOLTIP5 ···········"PGP Encrypt Email Message"
139c63 ····IDS_TOOLTIP6 ···········"PGP Sign Email Message"
10e0d1 END
b0af5a
796f6c STRINGTABLE DISCARDABLE·
444523 BEGIN
c6c489 ····IDS_TOOLTIP7 ···········"PGP Encrypt and Sign Email Message"
c65ae1 ····IDS_TOOLTIP8 ···········"Use PGP/MIME When Sending Email Message"
3ff46f ····IDS_E_EXPIRED ··········"The evaluation period for PGP has passed.\nThe Eud¶
1d07d1 ora Plugin will no longer function."
2d71f8 ····IDS_E_EXPIREDTITLE ·····"PGP Plugin Expired"
269978 ····IDS_PGPKEYSEXE ·········"PGPkeys /s"
806abd ····IDS_E_LAUNCHPGPKEYS ····"Unable to locate the PGPkeys application"
f81ff0 ····IDS_EXE ················"Eudora"
138dff ····IDS_DLL ················"pgpplugin.dll"
b6e0d1 END
f9af5a
bb1b3a #endif ···// English (U.S.) resources
9e6c0e /////////////////////////////////////////////////////////////////////////////
99af5a
43af5a
44af5a
9dce8c #ifndef APSTUDIO_INVOKED
466c0e /////////////////////////////////////////////////////////////////////////////
e0465d //
a68464 // Generated from the TEXTINCLUDE 3 resource.
9d465d //
bcdfa5 #include "PGPpluginVer.rc"
adf88e #include "..\shared\Working.rc"
1996d0 #include "..\shared\SharedStrings.rc"
fbaf5a
7a6c0e /////////////////////////////////////////////////////////////////////////////
148072 #endif ···// not APSTUDIO_INVOKED
ddaf5a
--56c9 001faa3a917401101ea Page 1 of PGPpluginVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
2da67a ············VALUE "FileDescription", "PGP Plug-in For Eudora E-mail Client\0"
3dc1dd ············VALUE "FileVersion", PGPVERSIONSTRING
e6b490 ············VALUE "InternalName", "pgpEudoraPluginV4\0"
b58ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
762bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
441168 ············VALUE "OriginalFilename", "pgpEudoraPluginV4.dll\0"
7c9317 ············VALUE "ProductName", PGPPRODUCTNAME
a7d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
86f37f ········END
7a7d01 ····END
d826ab ····BLOCK "VarFileInfo"
055574 ····BEGIN
1e4b11 ········VALUE "Translation", 0x409, 1200
887d01 ····END
8fe0d1 END
28af5a
acaf5a
faaf5a
--d7d9 000779afd9f401101eb Page 1 of PluginMain.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8e9c59 ¤   $Id: PluginMain.c,v 1.13.8.1 1998/11/12 03:11:49 heller Exp $
52f7f7 ____________________________________________________________________________*/
9aaf5a
bb9b16 // System Headers
a25655 #include <windows.h>
5a3d0b #include <windowsx.h>
71af5a
705582 // PGPsdk Headers
2fe2ff #include "pgpConfig.h"
462f8d #include "pgpErrors.h"
4b4919 #include "pgpUtilities.h"
a49f63 #include "pgpEncode.h"
36ec82 #include "pgpTLS.h"
9faf5a
4caf5a
ce4f9a // Eudora Headers
222ba1 #include "emssdk/Mimetype.h"
1faf5a
e92062 // Shared Headers
8c5ab2 #include "PGPcl.h"
f8af5a
72e8e0 // Project Headers
0300ec #include "PluginMain.h"
88cc89 #include "Prefs.h"
10e6f3 #include "TranslatorIDs.h"
6cfc44 #include "Translators.h"
94af5a
2a482b // Global Variables
93db68 HINSTANCE¤  ¤   ¤   g_hinst¤¤   ¤   ¤   = NULL;
86c3ac PGPContextRef¤  ¤   g_pgpContext¤   ¤   = kPGPInvalidRef;
629563 PGPtlsContextRef¤   g_tlsContext¤   ¤   = kPGPInvalidRef;
68a464 UINT¤   ¤   ¤   ¤   g_nPurgeCacheMsg¤   = 0;
21d47c HWND¤   ¤   ¤   ¤   g_hwndHidden¤   ¤   = NULL;
81af5a
b1235f static HWND CreateHiddenWindow(void);
b2af5a
155aa8 LRESULT CALLBACK HiddenWindowProc(HWND hwnd,·
2108ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
4d13bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
0b325e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
5eaf5a
f57efe BOOL·
0442ef WINAPI·
9ec799 DllMain (¤  HINSTANCE hinstDll,·
164f29 ¤   ¤   ¤   DWORD fdwReason,
ca3f3b ¤   ¤   ¤   LPVOID lpvReserved)
7fbb36 {
d6ab4e ¤   switch (fdwReason)
a3c7a1 ¤   {
477e00 ¤   ¤   case DLL_PROCESS_ATTACH:
b06673 ¤   ¤   ¤   g_hinst = hinstDll;
4ccdcb ¤   ¤   ¤   break;
e4af5a
c336e3 ¤   ¤   case DLL_THREAD_ATTACH:
07cdcb ¤   ¤   ¤   break;
07af5a
ee8b9e ¤   ¤   case DLL_THREAD_DETACH:
77cdcb ¤   ¤   ¤   break;
63af5a
54c37d ¤   ¤   case DLL_PROCESS_DETACH:
abcdcb ¤   ¤   ¤   break;
8bb144 ···}
f67921 ···return(TRUE);
1fefe6 }
9daf5a
77af5a
--3c31 000b31187a9401101eb Page 2 of PluginMain.c
9e3e5c /***************************************************************************/
412932 /* TRANSLATER API FUNCTIONS */
77af5a
59fb70 /*****\
8c7119 *
0c5dbc * ems_plugin_version: Get the version of the API used for this plugin
287119 *
2a2375 \*****/
68af5a
196fcf long
158524 WINAPI
2de66f ems_plugin_version(
611be3 ····short FAR* api_version ·····/* Place to return api version */
2c5b71 )
fcbb36 {
1fdfd2 ¤   *api_version = EMS_VERSION;
c7dbc3 ¤   return (EMSR_OK);
aaefe6 }
7eaf5a
18b3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3aaf5a
4dfb70 /*****\
d97119 *
392dce * ems_plugin_init: Initialize plugin and get its basic info
907119 *
262375 \*****/
23af5a
7a6fcf long
778524 WINAPI
017437 ems_plugin_init(
2f3365 ····void FAR*FAR* globals, ·····/* Out: Return for instance structure */
0d9ae4 ····short eudAPIVersion, ·······/* In: The API version eudora is using */
9d6760 ····emsMailConfigP mailConfig, ·/* In: Eudoras mail configuration */
dfdc65 ····emsPluginInfoP pluginInfo ··/* Out: Return Plugin Information */
fc5b71 )
efbb36 {
104e0f ¤   long returnValue = EMSR_OK;
045ad6 ¤   PGPError error;
e3af5a
97621d ¤   // Initialize the PGPsdk for the plugin
23d46b ¤   error = PGPNewContext(¤ kPGPsdkAPIVersion,·
c102a4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &g_pgpContext );
26af5a
4738f5 ¤   if( IsPGPError(error) )
7ac7a1 ¤   {
6ad9a1 ¤   ¤   if(error == kPGPError_FeatureNotAvailable)
3d5b34 ¤   ¤   {
e81732 ¤   ¤   ¤   char szMessage[256];
2a0207 ¤   ¤   ¤   char szTitle[256];
d9af5a
37fbfc ¤   ¤   ¤   LoadString(g_hinst, IDS_E_EXPIRED, szMessage, sizeof(szMessage));
04ee11 ¤   ¤   ¤   LoadString(g_hinst, IDS_E_EXPIREDTITLE, szTitle, sizeof(szTitle));
50af5a
c05e0d ¤   ¤   ¤   MessageBox(NULL, szMessage, szTitle, MB_OK);
9e0fe4 ¤   ¤   }
b00e1d ¤   ¤   else
565b34 ¤   ¤   {
3ce72b ¤   ¤   ¤   PGPclErrorBox (¤NULL,·
697b39 ¤   ¤   ¤   ¤   ¤   ¤   ¤   error);
fc0fe4 ¤   ¤   }
71af5a
1c86af ¤   ¤   returnValue = EMSR_UNKNOWN_FAIL;
789371 ¤   }
d6af5a
de123e ¤   // Initialize the Common Libraries
b9d2b7 ¤   error = PGPclInitLibrary (g_pgpContext);
c0af5a
fb06f4 ····if (IsPGPError (error))·
1fc7a1 ¤   {
8cc3f9 ········PGPclErrorBox (NULL, error);
f2d83c ·
b32a8e ········returnValue = EMSR_UNKNOWN_FAIL;
--e07f 0008ebdc4ee401101eb Page 3 of PluginMain.c
9f6fe7 ····}
86af5a
480224 ¤   // has this beta version expired?
cc8486 ¤   if(PGPclIsExpired(NULL))
42c7a1 ¤   {
76e282 ¤   ¤   PGPclCloseLibrary();
766b21 ¤   ¤   PGPFreeContext(g_pgpContext);
adda19 ¤   ¤   g_pgpContext = NULL;
7067c5 ¤
430177 ¤   ¤   return EMSR_UNKNOWN_FAIL;
049371 ¤   }
71af5a
b63884 ¤   PGPNewTLSContext( g_pgpContext, &g_tlsContext );
ddaf5a
49c936 ¤   // Register the passphrase cache purge message
81af5a
7546cc ¤   g_nPurgeCacheMsg = RegisterWindowMessage(PURGEPASSPHRASECACEHMSG);
33af5a
d56011 ¤   // Create a hidden window to catch messages
a6af5a
ec4386 ¤   g_hwndHidden = CreateHiddenWindow();
c2af5a
d6eb81 ¤   if (pluginInfo &&
b7b463 ¤   ¤   returnValue == EMSR_OK)
a8c7a1 ¤   {
248ffc ¤   ¤   pluginInfo->numTrans = kNumTrans;
43ed1f ¤   ¤   pluginInfo->numAttachers = 0;
a73577 ¤   ¤   pluginInfo->numSpecials = kNumSpecial;
e71b52 ¤   ¤
58ec66 ¤   ¤   pluginInfo->desc = strdup(kPluginDescription);
9e1b52 ¤   ¤
17dc15 ¤   ¤   pluginInfo->icon = (HICON*)malloc(sizeof(HICON));
5faf5a
c8ee0d ¤   ¤   if(pluginInfo->icon)
8f5b34 ¤   ¤   {
fbb92d ¤   ¤   ¤   *pluginInfo->icon = LoadIcon(¤  g_hinst,·
c34406 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE( IDI_PGP32 ) );
de0fe4 ¤   ¤   }
860e1d ¤   ¤   else
e35b34 ¤   ¤   {
278017 ¤   ¤   ¤   returnValue = EMSR_UNKNOWN_FAIL;
e00fe4 ¤   ¤   }
eb1b52 ¤   ¤
679e56 ¤   ¤   pluginInfo->id = kPluginID;
da9371 ¤   }
4267c5 ¤
2f650b ¤   return (returnValue);
2cefe6 }
7eaf5a
49b3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00af5a
90fb70 /*****\
8c7119 *
edf9c6 * ems_translator_info: Get details about a translator in a plugin
ec7119 *
3f2375 \*****/
0aaf5a
fa6fcf long
c78524 WINAPI
861cfa ems_translator_info(
eceb2c ····void FAR* globals, ·········/* Out: Return for instance structure */
71d55c ····emsTranslatorP transInfo ···/* In/Out: Return Translator Information */
2c5b71 )
a9bb36 {
682298 ¤   TransInfoStruct *InfoPtr = NULL;
194e0f ¤   long returnValue = EMSR_OK;
ceaf5a
245db3 ¤   if ((transInfo) && (gTransInfo))
7fc7a1 ¤   {
4b5f60 ¤   ¤   const long id = transInfo->id;
0aaf5a
8eb8a7 ¤   ¤   if ((id > 0) &&·
--383a 0004210c17d401101eb Page 4 of PluginMain.c
6988ab ¤   ¤   ¤   (id <= kNumTrans))
1e5b34 ¤   ¤   {
ae3e34 ¤   ¤   ¤   InfoPtr = gTransInfo + (id - 1);
cbaf5a
9b8bb3 ¤   ¤   ¤   transInfo->type = InfoPtr->type;
607fd1 ¤   ¤   ¤   transInfo->flags = InfoPtr->flags;
bcaf5a
a7561b ¤   ¤   ¤   if(¤kEncryptTranslatorID == id &&·
78bbfd ¤   ¤   ¤   ¤   ByDefaultEncrypt(PGPGetContextMemoryMgr(g_pgpContext)))
12f776 ¤   ¤   ¤   {
40e976 ¤   ¤   ¤   ¤   transInfo->flags |= EMSF_DEFAULT_Q_ON;
cca3a6 ¤   ¤   ¤   }
26167e ¤   ¤   ¤   else if(kSignTranslatorID == id &&
48702d ¤   ¤   ¤   ¤   ¤   ByDefaultSign(PGPGetContextMemoryMgr(g_pgpContext)))
1af776 ¤   ¤   ¤   {
5be976 ¤   ¤   ¤   ¤   transInfo->flags |= EMSF_DEFAULT_Q_ON;
58a3a6 ¤   ¤   ¤   }
c6af5a
92714e ¤   ¤   ¤   transInfo->desc = strdup(InfoPtr->description);
ce527c ¤   ¤   ¤   transInfo->icon = (HICON *)malloc(sizeof(HICON));
5daf5a
6f0a5c ¤   ¤   ¤   if(transInfo->icon)
f9f776 ¤   ¤   ¤   {
6293b3 ¤   ¤   ¤   ¤   *transInfo->icon = LoadIcon(g_hinst,·
dedbdf ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(gTransInfo[id - 1].nIconID));
67a3a6 ¤   ¤   ¤   }
17bb8c ¤   ¤   ¤   else
2cf776 ¤   ¤   ¤   {
cad28a ¤   ¤   ¤   ¤   returnValue = EMSR_UNKNOWN_FAIL;
b8a3a6 ¤   ¤   ¤   }
1f0fe4 ¤   ¤   }
570e1d ¤   ¤   else
bb5b34 ¤   ¤   {
017628 ¤   ¤   ¤   returnValue = EMSR_INVALID_TRANS;
760fe4 ¤   ¤   }
739371 ¤   }
790e24 ¤   else
f5c7a1 ¤   {
bb86af ¤   ¤   returnValue = EMSR_UNKNOWN_FAIL;
729371 ¤   }
46af5a
3d650b ¤   return (returnValue);
27efe6 }
0baf5a
acb3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
88af5a
09fb70 /*****\
2a7119 *
afc49d * ems_can_translate_file:
68cd35 * ····Check and see if a translation can be performed (file version)
237119 *
032375 \*****/
1baf5a
386fcf long
5c8524 WINAPI
3e4bc6 ems_can_translate(
fd8e80 ····void FAR* globals, ···········/* Out: Return for instance structure */
88e85a ····emsTranslatorP transInfo, ····/* In: Translator Info */
2c49cc ····emsDataFileP inTransData, ····/* In: What to translate */
475638 ····emsResultStatusP transStatus ·/* Out: Translations Status information */
db5b71 )
53bb36 {
594e0f ¤   long returnValue = EMSR_OK;
b9af5a
53a88c ¤   if ((transInfo) && (inTransData))
3fc7a1 ¤   {
805f60 ¤   ¤   const long id = transInfo->id;
f1a903 ¤   ¤   const long context = inTransData->context;
cb0a93 ¤   ¤   const emsMIMEtypeP in_mime = inTransData->info;
6faf5a
fcb8a7 ¤   ¤   if ((id > 0) &&·
4288ab ¤   ¤   ¤   (id <= kNumTrans))
--40c9 000afe0299b401101eb Page 5 of PluginMain.c
e35b34 ¤   ¤   {
f4946b ¤   ¤   ¤   returnValue = CanPerformTranslation(¤
6ecda7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   id,·
bc4e4e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_mime,·
89ca38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context);
fb0fe4 ¤   ¤   }
050e1d ¤   ¤   else
145b34 ¤   ¤   {
397628 ¤   ¤   ¤   returnValue = EMSR_INVALID_TRANS;
4e0fe4 ¤   ¤   }
d39371 ¤   }
e40e24 ¤   else
a3c7a1 ¤   {
ce86af ¤   ¤   returnValue = EMSR_UNKNOWN_FAIL;
6b9371 ¤   }
57af5a
03acc5 ¤   return returnValue;
9cefe6 }
f7af5a
3bb3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
e7af5a
7ffb70 /*****\
f27119 *
1d774e * ems_translate_file: Actually perform a translation on a file
8a7119 *
d32375 \*****/
ceaf5a
c16fcf long
208524 WINAPI
a24d06 ems_translate_file(
f36144 ····void FAR* globals, ··········/* Out: Return for instance structure */
b2b926 ····emsTranslatorP transInfo, ···/* In: Translator Info */
2a20dc ····emsDataFileP inFileData, ····/* In: What to translate */
567cd0 ····emsProgress progress, ·······/* Func to report progress/check for abort */
e40dc0 ····emsDataFileP outFileData, ···/* Out: Result of the translation */
625c76 ····emsResultStatusP transStatus /* Out: Translations Status information */
085b71 )
08bb36 {
a84e0f ¤   long returnValue = EMSR_OK;
2ed83c ·
64fca5 ¤   if(¤inFileData &&
1dfb6c ¤   ¤   outFileData &&·
a30684 ¤   ¤   transInfo &&
cf4a1b ¤   ¤   transStatus)
e3c7a1 ¤   {
6a25c0 ¤   ¤   const char *in_file = inFileData->fileName;
4db52d ¤   ¤   const char *out_file = outFileData->fileName;
595f60 ¤   ¤   const long id = transInfo->id;
e79a9c ¤   ¤   emsMIMEtypeP in_mime = inFileData->info;
39c1f4 ¤   ¤   emsMIMEtypeP FAR *out_mime = &(outFileData->info);
2b40b0 ¤   ¤   char FAR* FAR*out_desc = &(transStatus->desc);
b2af5a
cefb2a ¤   ¤   // see if this is one of our id's
6ab8a7 ¤   ¤   if ((id > 0) &&·
4488ab ¤   ¤   ¤   (id <= kNumTrans))
b15b34 ¤   ¤   {
8ce007 ¤   ¤   ¤   HANDLE hOutput = NULL;
4daf5a
37ddb9 ¤   ¤   ¤   returnValue = PerformTranslation(¤
43cda7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   id,·
2e3388 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_file,·
901b39 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   out_file,·
393203 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   inFileData->header,·
dc44e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_mime,
167a2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   out_mime);
d60fe4 ¤   ¤   }
0c0e1d ¤   ¤   else
715b34 ¤   ¤   {
907628 ¤   ¤   ¤   returnValue = EMSR_INVALID_TRANS;
680fe4 ¤   ¤   }
ea9371 ¤   }
afaf5a
--1faf 0008779dcc2401101eb Page 6 of PluginMain.c
c1acc5 ¤   return returnValue;
bcefe6 }
b4af5a
b7af5a
05b3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
a0af5a
aafb70 /*****\
6e7119 *
d22279 * ems_plugin_config: Call the plug-ins configuration Interface
187119 *
672375 \*****/
abaf5a
936fcf long
988524 WINAPI
947b81 ems_plugin_config(
3dc6ac ····void FAR* globals,¤ ¤   ¤   /* Out: Return for instance structure */
6b4773 ····emsMailConfigP mailConfig¤  /* In: Eudora mail info */
9e5b71 )
04bb36 {
7e2668 ¤   PGPclPreferences (g_pgpContext, NULL, 2, NULL);
4baf5a
d7dbc3 ¤   return (EMSR_OK);
e4efe6 }
a3af5a
c3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
81af5a
0dfb70 /*****\
917119 *
9ea1fd * ems_special_info: Get details about a attacher in a plugin
707119 *
1d2375 \*****/
a7af5a
f5a9e0 long WINAPI ems_special_info(
49eb2c ····void FAR* globals, ·········/* Out: Return for instance structure */
de5b83 ····emsMenuP specialMenu ········/* Out: The menu */
185b71 )
dfbb36 {
d92298 ¤   TransInfoStruct *InfoPtr = NULL;
184e0f ¤   long returnValue = EMSR_OK;
33af5a
289d48 ¤   if ( specialMenu->id != kSpecialLaunchKeysID )
16c7a1 ¤   {
17ba2c ¤   ¤   return (EMSR_INVALID_TRANS);
189371 ¤   }
4eaf5a
9348c5 ¤   specialMenu->flags = gSpecialInfo->flags;
67ffd9 ¤   specialMenu->desc = strdup(gSpecialInfo->description);
edaf5a
abfc60 ¤   specialMenu->icon = (HICON *)malloc(sizeof(HICON));
36af5a
a8165b ¤   if(specialMenu->icon)
37c7a1 ¤   {
e6b1b3 ¤   ¤   *specialMenu->icon = LoadIcon(g_hinst,·
950f66 ¤   ¤   ¤   MAKEINTRESOURCE(gSpecialInfo->nIconID));
4c9371 ¤   }
b80e24 ¤   else
c2c7a1 ¤   {
8286af ¤   ¤   returnValue = EMSR_UNKNOWN_FAIL;
dd9371 ¤   }
95af5a
6facc5 ¤   return returnValue;
c9efe6 }
eae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b9af5a
abfb70 /*****\
2d7119 *
cfb6e8 * ems_special_hook: Get details about a attacher in a plugin
697119 *
2d2375 \*****/
25af5a
fc3c8d long WINAPI ems_special_hook(
87eb2c ····void FAR* globals, ·········/* Out: Return for instance structure */
--7484 0008a15ba82401101eb Page 7 of PluginMain.c
3b7561 ····emsMenuP specialMenu ·······/* In: The menu */
715b71 )
f5bb36 {
18efa3 ¤   if (!specialMenu)·
69c7a1 ¤   {
c47bf5 ¤   ¤   return (EMSR_UNKNOWN_FAIL);
1f9371 ¤   }
8d67c5 ¤
da3dea ¤   if (specialMenu->id == kSpecialLaunchKeysID)
5bc7a1 ¤   {
5e2a7f ¤   ¤   char szPath[MAX_PATH];
6b15dc ¤   ¤   char szPGPkeys[256];
c10a46 ¤   ¤   PGPError error = kPGPError_NoErr;
ceaf5a
1c9550 ¤   ¤   LoadString(g_hinst, IDS_PGPKEYSEXE, szPGPkeys,
290801 ¤   ¤   ¤   sizeof(szPGPkeys));
63af5a
25c7d2 ¤   ¤   error = PGPclGetPGPPath (szPath, sizeof(szPath));
8baf5a
dec170 ¤   ¤   if( IsntPGPError(error) )
a25b34 ¤   ¤   {
002b6a ¤   ¤   ¤   // '/s' keeps it from showing that·
04857f ¤   ¤   ¤   // damn splash screen
351353 ¤   ¤   ¤   strcat(szPath, szPGPkeys);
6251ec ¤   ¤   ¤   // run it...
79859d ¤   ¤   ¤   WinExec(szPath, SW_SHOW);
280fe4 ¤   ¤   }
5a0e1d ¤   ¤   else
355b34 ¤   ¤   {
fa5875 ¤   ¤   ¤   char szError[256];
82af5a
80ca69 ¤   ¤   ¤   LoadString(g_hinst, IDS_E_LAUNCHPGPKEYS, szError,
4d0e1a ¤   ¤   ¤   ¤   sizeof(szError));
f3af5a
51a8af ¤   ¤   ¤   MessageBox(NULL,·
9b4a3b ¤   ¤   ¤   ¤   szError,·
ff6b2b ¤   ¤   ¤   ¤   0,·
8e8347 ¤   ¤   ¤   ¤   MB_OK);
0a0fe4 ¤   ¤   }
d49371 ¤   }
a0af5a
79dbc3 ¤   return (EMSR_OK);
18efe6 }
0caf5a
aaaf5a
97af5a
7ab3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
75af5a
79fb70 /*****\
2c7119 *
f2bce9 * ems_plugin_finish: End use of a plugin and clean up
d17119 *
642375 \*****/
93af5a
246fcf long
638524 WINAPI
998b19 ems_plugin_finish(
7a666c ····void FAR* globals ···/* Pointer to translator instance structure */
295b71 )
5ebb36 {
952970 ¤   if (g_hwndHidden != NULL)
868f61 ¤   ¤   DestroyWindow(g_hwndHidden);
93af5a
ad5980 ¤   if( PGPRefIsValid(g_tlsContext) )
adc7a1 ¤   {
66bc03 ¤   ¤   PGPFreeTLSContext(g_tlsContext);
929371 ¤   }
64af5a
720e48 ¤   if( PGPRefIsValid(g_pgpContext) )
09c7a1 ¤   {
25e282 ¤   ¤   PGPclCloseLibrary();
8a6b21 ¤   ¤   PGPFreeContext(g_pgpContext);
--48f9 000151ed38b401101eb Page 8 of PluginMain.c
a19371 ¤   }
9967c5 ¤
dcd100 ¤   return (EMSR_OK);·
d7efe6 }
b4af5a
78b3dd /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
69af5a
42fb70 /*****\
af7119 *
412d1d * ems_free: Free memory allocated by EMS plug-in
de7119 *
582375 \*****/
bdaf5a
e16fcf long
e78524 WINAPI
9a01b5 ems_free(
058228 ····void FAR* mem ··············/* Memory to free */
6e5b71 )
00bb36 {
a2a168 ¤   if (mem)
19c7a1 ¤   {
5b5f72 ¤   ¤   free(mem);·
3f32d6 ¤   ¤   mem = NULL;·
1747d1 ¤   }·
8aaf5a
e1dbc3 ¤   return (EMSR_OK);
39efe6 }
fbaf5a
3eaf5a
31fb33 HWND CreateHiddenWindow(void)
e6bb36 {
ac55cf ¤   HWND hwnd;
a6d663 ¤   WNDCLASS wc;
66af5a
975e44 ¤   // Register the Window Class
03af5a
b47783 ¤   wc.style¤   ¤   ¤   = 0;
79f813 ¤   wc.lpfnWndProc¤ ¤   = HiddenWindowProc;
da2ff0 ¤   wc.cbClsExtra¤  ¤   = 0;
8df5bd ¤   wc.cbWndExtra¤  ¤   = 0;
d15f64 ¤   wc.hInstance¤   ¤   = g_hinst;
ed6b61 ¤   wc.hIcon¤   ¤   ¤   = 0;
4c1af3 ¤   wc.hCursor¤ ¤   ¤   = 0;
95fdb7 ¤   wc.hbrBackground¤   = 0;
3a4d10 ¤   wc.lpszMenuName¤¤   = 0;
e54cb9 ¤   wc.lpszClassName¤   = "EudoraPluginV4 Hidden Window";
40af5a
27fd79 ¤   RegisterClass(&wc);
15af5a
82e7b7 ¤   hwnd = CreateWindow("EudoraPluginV4 Hidden Window",·
f66e4e ¤   ¤   "EudoraPluginV4 Hidden Window",
7a7b39 ¤   ¤   WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
7aa9ec ¤   ¤   CW_USEDEFAULT, NULL, NULL, g_hinst, NULL);
baaf5a
16a706 ¤   return hwnd;
1fefe6 }
6faf5a
c9af5a
615aa8 LRESULT CALLBACK HiddenWindowProc(HWND hwnd,·
3908ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
4b13bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
b5e503 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
3ebb36 {
61b539 ¤   if (msg == WM_CREATE)
eac7a1 ¤   {
02efb3 ¤   ¤   ShowWindow(hwnd, SW_HIDE);
a6bbde ¤   ¤   return 0;
f89371 ¤   }
60af5a
ad5b13 ¤   if (msg == g_nPurgeCacheMsg)
fcc7a1 ¤   {
1584b4 ¤   ¤   PGPclPurgeCachedPassphrase(wParam);
--038e 00155ef1ee9401101eb Page 9 of PluginMain.c
00836c ¤   ¤   return TRUE;
609371 ¤   }
50af5a
624c1c ¤   return DefWindowProc(hwnd, msg, wParam, lParam);
21efe6 }
8aaf5a
fdaf5a
c17e4d /*__Editor_settings____
1aaf5a
634126 ¤   Local Variables:
ba7b17 ¤   tab-width: 4
6d0e6c ¤   End:
fb5f8c ¤   vi: ts=4 sw=4
7a9e9b ¤   vim: si
55d062 _____________________*/
--7fea 00081a6b1ad401101ec Page 1 of PluginMain.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
b45240 ¤   $Id: PluginMain.h,v 1.8.8.1 1998/11/12 03:11:50 heller Exp $
f7f7f7 ____________________________________________________________________________*/
589835 #ifndef Included_PluginMain_h¤  /* [ */
0a60d6 #define Included_PluginMain_h
6aaf5a
8f5e47 #include "emssdk/ems-win.h"
66e6f3 #include "TranslatorIDs.h"
ad8031 #include "resource.h"
bcaf5a
99e0bc #define InitPtrToNull( p )¤ { if ( !( p ) )¤*(p) = NULL; }
13af5a
08c6a2 typedef struct _TransInfoStruct {
6b061a ¤   char *description;
501004 ¤   long type;
147078 ¤   long subtype;
6ddddd ¤   unsigned long flags;
abeaa9 ¤   unsigned long nIconID;
1e8f94 }TransInfoStruct;
0faf5a
a2caab static TransInfoStruct gTransInfo[] = {
68c7a1 ¤   {
090238 ¤   ¤   "Decrypt PGP/MIME Message",
ff526c ¤   ¤   EMST_PREPROCESS,
dcfa09 ¤   ¤   kDecryptTranslatorID,·
1d92f3 ¤   ¤   ( EMSF_ON_ARRIVAL | EMSF_ON_DISPLAY | EMSF_WHOLE_MESSAGE |·
0514fe ¤   ¤   ¤   EMSF_REQUIRES_MIME | EMSF_GENERATES_MIME ),
a7762c ¤   ¤   IDI_PGP_DECRYPT
59ba24 ¤   },
7ac7a1 ¤   {
86d27a ¤   ¤   "Verify PGP/MIME Message",
43256a ¤   ¤   EMST_SIGNATURE,
2a9160 ¤   ¤   kVerifyTranslatorID,·
6692f3 ¤   ¤   ( EMSF_ON_ARRIVAL | EMSF_ON_DISPLAY | EMSF_WHOLE_MESSAGE |·
d514fe ¤   ¤   ¤   EMSF_REQUIRES_MIME | EMSF_GENERATES_MIME ),
c21e5c ¤   ¤   IDI_PGP_VERIFY
1eba24 ¤   },
61c7a1 ¤   {
d07c54 ¤   ¤   "PGP Encrypt",
a6526c ¤   ¤   EMST_PREPROCESS,
63b991 ¤   ¤   kEncryptTranslatorID,·
4917f9 ¤   ¤   ( EMSF_Q4_COMPLETION | EMSF_WHOLE_MESSAGE | EMSF_REQUIRES_MIME |·
254ba8 ¤   ¤   ¤   EMSF_GENERATES_MIME),
918111 ¤   ¤   IDI_PGP_ENCRYPT
6aba24 ¤   },
c7c7a1 ¤   {
2d6fe1 ¤   ¤   "PGP Sign",
0b256a ¤   ¤   EMST_SIGNATURE,
e252bc ¤   ¤   kSignTranslatorID,·
db17f9 ¤   ¤   ( EMSF_Q4_COMPLETION | EMSF_WHOLE_MESSAGE | EMSF_REQUIRES_MIME |·
e44ba8 ¤   ¤   ¤   EMSF_GENERATES_MIME),
267659 ¤   ¤   IDI_PGP_SIGN
b2ba24 ¤   },
a5c7a1 ¤   {
cb88f1 ¤   ¤   "PGP Encrypt & Sign",
c921ae ¤   ¤   EMST_COALESCED,
d42760 ¤   ¤   kEncryptAndSignTranslatorID,·
4817f9 ¤   ¤   ( EMSF_Q4_COMPLETION | EMSF_WHOLE_MESSAGE | EMSF_REQUIRES_MIME |·
8e316e ¤   ¤   ¤   EMSF_GENERATES_MIME ),
4380c0 ¤   ¤   0L //IDI_PGP_ENCRYPT_SIGN
60ba24 ¤   },
0bc7a1 ¤   {
f47c54 ¤   ¤   "PGP Encrypt",
786026 ¤   ¤   EMST_LANGUAGE,
e9b510 ¤   ¤   kManualEncryptTranslatorID,·
7f694c ¤   ¤   ( EMSF_ON_REQUEST | EMSF_WHOLE_MESSAGE ·),
818111 ¤   ¤   IDI_PGP_ENCRYPT
--0f80 001f58e68ca401101ec Page 2 of PluginMain.h
50ba24 ¤   },
fec7a1 ¤   {
cf6fe1 ¤   ¤   "PGP Sign",
3a6026 ¤   ¤   EMST_LANGUAGE,
4f7319 ¤   ¤   kManualSignTranslatorID,·
86694c ¤   ¤   ( EMSF_ON_REQUEST | EMSF_WHOLE_MESSAGE ·),
687659 ¤   ¤   IDI_PGP_SIGN
3aba24 ¤   },
6dc7a1 ¤   {
9488f1 ¤   ¤   "PGP Encrypt & Sign",
6b6026 ¤   ¤   EMST_LANGUAGE,
ad1427 ¤   ¤   kManualEncryptSignTranslatorID,
4c694c ¤   ¤   ( EMSF_ON_REQUEST | EMSF_WHOLE_MESSAGE ·),
ada412 ¤   ¤   IDI_PGP_ENCRYPT_SIGN
56ba24 ¤   },
fbc7a1 ¤   {
d2a72c ¤   ¤   "PGP Decrypt & Verify",
4f6026 ¤   ¤   EMST_LANGUAGE,
222d3b ¤   ¤   kManualDecryptVerifyTranslatorID,·
147597 ¤   ¤   ( EMSF_ON_REQUEST | EMSF_WHOLE_MESSAGE | EMSF_GENERATES_MIME |
148866 ¤   ¤   ¤   EMSF_TOOLBAR_PRESENCE),
e3762c ¤   ¤   IDI_PGP_DECRYPT
799371 ¤   }
e982f7 };
0faf5a
94f844 static TransInfoStruct gSpecialInfo[] = {
97af5a
04c7a1 ¤   {
6f551b ¤   ¤   "Launch PGPkeys",
796026 ¤   ¤   EMST_LANGUAGE,
939f87 ¤   ¤   kSpecialLaunchKeysID,
560337 ¤   ¤   ( EMSF_ON_REQUEST | EMSF_TOOLBAR_PRESENCE ·),
7bbf6a ¤   ¤   IDI_PGP_KEYS
f19371 ¤   }
28af5a
0e82f7 };
b6af5a
1183bd static const long¤  kNumTrans = (sizeof(gTransInfo)/sizeof(*gTransInfo));
a7af5a
da39cc static const long¤  kNumSpecial =·
22c9c5 ¤   ¤   ¤   ¤   (sizeof(gSpecialInfo)/sizeof(*gSpecialInfo));
72af5a
4814b5 // for future use we have 881 882 883 884 as well
7fc5c1 static const short¤ kPluginID = 880;·
d6af5a
4544a2 static const char*¤ kPluginDescription = "PGP 6.0";
fdaf5a
1977bf #endif /* ] Included_PluginMain_h */
1baf5a
f1af5a
9c7e4d /*__Editor_settings____
46af5a
2e4126 ¤   Local Variables:
6c7b17 ¤   tab-width: 4
c60e6c ¤   End:
265f8c ¤   vi: ts=4 sw=4
ec9e9b ¤   vim: si
12d062 _____________________*/
81af5a
f5af5a
--9ea5 001c97ac572401101ed Page 1 of TranslatorIDs.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
dcf73c ¤   $Id: TranslatorIDs.h,v 1.3.8.1 1998/11/12 03:11:50 heller Exp $
fff7f7 ____________________________________________________________________________*/
706011 #ifndef Included_TranslatorIDs_h¤   /* [ */
d326d4 #define Included_TranslatorIDs_h
2aaf5a
6101bf typedef enum TranslatorID
7fbb36 {
37183c ¤   kInvalidTranslatorID = 0,
7e67c5 ¤
491d57 ¤   // note: ids must start at 1 and be sequential
ec6ecb ¤   kFirstTranslatorID = 1,
15af5a
f11450 ¤   kDecryptTranslatorID = kFirstTranslatorID,
159bfc ¤   kVerifyTranslatorID,
aff5ef ¤   kEncryptTranslatorID ,
9bb5d5 ¤   kSignTranslatorID,
cf014a ¤   kEncryptAndSignTranslatorID,
7667c5 ¤
061a80 ¤   kFirstManualTranslatorID,
ce67c5 ¤
7a19d0 ¤   kManualEncryptTranslatorID = kFirstManualTranslatorID,
7a4b42 ¤   kManualSignTranslatorID,
f07508 ¤   kManualEncryptSignTranslatorID,·
dc0b66 ¤   kManualDecryptVerifyTranslatorID,
bbaf5a
d2ba7e ¤   kLastTranslatorIDPlusOne,
0667c5 ¤
770234 ¤   kPGPNumTranslators¤ = kLastTranslatorIDPlusOne - kFirstTranslatorID
a5519d } TranslatorID;
e4af5a
71af5a
2844d3 typedef enum SpecialID
71bb36 {
b85b66 ¤   kInvalidSpecialID = 0,
af67c5 ¤
5c1d57 ¤   // note: ids must start at 1 and be sequential
894c3c ¤   kFirstSpecialID = 1,
41af5a
967374 ¤   kSpecialLaunchKeysID = kFirstSpecialID,
c2af5a
46f1da ¤   kLastSpecialIDPlusOne,
d667c5 ¤
213e38 ¤   kPGPNumSpecials¤= kLastSpecialIDPlusOne - kFirstSpecialID
a1519d } TranslatorID;
0eaf5a
8eaf5a
2cc62a #endif /* ] Included_TranslatorIDs_h */
2daf5a
25af5a
b17e4d /*__Editor_settings____
6faf5a
ad4126 ¤   Local Variables:
c67b17 ¤   tab-width: 4
630e6c ¤   End:
c95f8c ¤   vi: ts=4 sw=4
b69e9b ¤   vim: si
c97c50 _____________________*/¶
--6357 0004075c5f6401101ee Page 1 of TranslatorUtils.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c174b5 ¤   $Id: TranslatorUtils.c,v 1.2.8.1 1998/11/12 03:11:51 heller Exp $
9bf7f7 ____________________________________________________________________________*/
aeaf5a
099b16 // System Headers
a05655 #include <windows.h>
ad3d0b #include <windowsx.h>
9abb5f #include <assert.h>
380a8b #include <time.h>
d9af5a
425582 // PGPsdk Headers
10e2ff #include "pgpConfig.h"
2da076 #include "pgpKeys.h"
702f8d #include "pgpErrors.h"
fd4919 #include "pgpUtilities.h"
619f72 #include "pgpHash.h"
e0af5a
904f9a // Eudora Headers
7e5e47 #include "emssdk/ems-win.h"
28af5a
fee8e0 // Project Headers
40bead #include "MapFile.h"
c4d2cf #include "BlockUtils.h"
9ebbc6 #include "TranslatorUtils.h"
bcaf5a
daaf5a
fc1bd8 long·
6765c3 ExtractAddressesFromMailHeader(¤emsHeaderDataP header,·
7527b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   char*** addresses)
1dbb36 {
7a9f9d ¤   emsAddressP¤to = header->to;
82aed4 ¤   emsAddressP¤cc = header->cc;
0f2efd ¤   emsAddressP¤bcc = header->bcc;
60cc65 ¤   long numRecipients = 0;
656142 ¤   long index = 0;
04af5a
71b0ec ¤   assert(header);
25a847 ¤   assert(addresses);
54af5a
55e7f2 ¤   *addresses = NULL;
89af5a
45a614 ¤   // first count all the addresses
81c39c ¤   while( to && to->address )
0fc7a1 ¤   {
53a017 ¤   ¤   numRecipients++;
31c371 ¤   ¤   to = to->next;
9f9371 ¤   }
59af5a
8f2827 ¤   while( cc && cc->address )
3fc7a1 ¤   {
48a017 ¤   ¤   numRecipients++;
a9db00 ¤   ¤   cc = cc->next;
8f9371 ¤   }
36af5a
b8ad2a ¤   while( bcc && bcc->address )
cfc7a1 ¤   {
5da017 ¤   ¤   numRecipients++;
fdfaaa ¤   ¤   bcc = bcc->next;
659371 ¤   }
53af5a
99d5ad ¤   if(numRecipients)
a4c7a1 ¤   {
800c77 ¤   ¤   to = header->to;
193d3e ¤   ¤   cc = header->cc;
159c06 ¤   ¤   bcc = header->bcc;
0eaf5a
401867 ¤   ¤   // allocate address array
--14b2 0002bfc3787401101ee Page 2 of TranslatorUtils.c
f9b00c ¤   ¤   *addresses = (char**) malloc(numRecipients * sizeof(char*) );
54af5a
4d8915 ¤   ¤   if(*addresses)
905b34 ¤   ¤   {
4db9be ¤   ¤   ¤   // fill the array
750e10 ¤   ¤   ¤   while( to && to->address )
01f776 ¤   ¤   ¤   {
1af807 ¤   ¤   ¤   ¤   (*addresses)[index] =·
2c451b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(to->address) + 1);·
97af5a
bce390 ¤   ¤   ¤   ¤   if((*addresses)[index])
c772c3 ¤   ¤   ¤   ¤   {
eb1ca5 ¤   ¤   ¤   ¤   ¤   strcpy((*addresses)[index++], to->address);
722613 ¤   ¤   ¤   ¤   }
88af5a
9835b8 ¤   ¤   ¤   ¤   to = to->next;
bda3a6 ¤   ¤   ¤   }
f0af5a
01e5ab ¤   ¤   ¤   while( cc && cc->address )
3cf776 ¤   ¤   ¤   {
3cf807 ¤   ¤   ¤   ¤   (*addresses)[index] =·
58332c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(cc->address) + 1);·
acaf5a
84e390 ¤   ¤   ¤   ¤   if((*addresses)[index])
2972c3 ¤   ¤   ¤   ¤   {
4a8129 ¤   ¤   ¤   ¤   ¤   strcpy((*addresses)[index++], cc->address);
cd2613 ¤   ¤   ¤   ¤   }
f9af5a
8a2dc9 ¤   ¤   ¤   ¤   cc = cc->next;
aba3a6 ¤   ¤   ¤   }
d6af5a
9d95af ¤   ¤   ¤   while( bcc && bcc->address )
c7f776 ¤   ¤   ¤   {
a8f807 ¤   ¤   ¤   ¤   (*addresses)[index] =·
3260fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char*) malloc(strlen(bcc->address) + 1);·
7baf5a
11e390 ¤   ¤   ¤   ¤   if((*addresses)[index])
8f72c3 ¤   ¤   ¤   ¤   {
295ed9 ¤   ¤   ¤   ¤   ¤   strcpy((*addresses)[index++], bcc->address);
732613 ¤   ¤   ¤   ¤   }
2daf5a
8e75a1 ¤   ¤   ¤   ¤   bcc = bcc->next;
c9a3a6 ¤   ¤   ¤   }
370fe4 ¤   ¤   }
efaf5a
a79082 ¤   ¤   assert(index == numRecipients);
0b9371 ¤   }
6eaf5a
8bdde5 ¤   return numRecipients;
0befe6 }
60af5a
77c823 void·
0a7f6e FreeRecipientList(char** Recipients,·
3eed0a ¤   ¤   ¤   ¤   ··unsigned long ·numRecipients)
a3bb36 {
d93745 ¤   unsigned long index = 0;
7eaf5a
cdf570 ¤   //assert(Recipients);
76af5a
ecb1fb ¤   if(Recipients)
68c7a1 ¤   {
7df6e5 ¤   ¤   for(index = 0; index < numRecipients; index++)
3f5b34 ¤   ¤   {
5562b4 ¤   ¤   ¤   if( Recipients[index] )
23f776 ¤   ¤   ¤   {
de00de ¤   ¤   ¤   ¤   // free each string
6e56e4 ¤   ¤   ¤   ¤   free(Recipients[index]);
bca3a6 ¤   ¤   ¤   }
ce0fe4 ¤   ¤   }
a1af5a
1abc80 ¤   ¤   free(Recipients);
2b9371 ¤   }
--a75c 001444b52fd401101ee Page 3 of TranslatorUtils.c
7aefe6 }
46af5a
c3b15c void StripMIMEHeader(const char* file)
20bb36 {
888ab8 ¤   HANDLE¤ hTempFile = NULL;
7591bc ¤   char szTempFile[MAX_PATH];
1e7c47 ¤   BOOL success = FALSE;
b7af5a
30758e ¤   assert(file);
b9af5a
cde36f ¤   strcpy(szTempFile, file);
2d4155 ¤   strcat(szTempFile, ".tmp");
a8af5a
bdc5d3 ¤   hTempFile = CreateFile(¤szTempFile,
387194 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GENERIC_WRITE|GENERIC_READ,
e54ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
945d0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
963e31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CREATE_ALWAYS,·
2a6acc ¤   ¤   ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL,·
4241db ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
10af5a
bb4f1d ¤   // did we successfully open the file
79fb8d ¤   if(¤( INVALID_HANDLE_VALUE != hTempFile ) )
1bc7a1 ¤   {
a3cb1b ¤   ¤   char* input = NULL;
cf9fc6 ¤   ¤   DWORD size = 0;
d3af5a
c4b888 ¤   ¤   input = MapFile(file, &size);
c3af5a
427db8 ¤   ¤   if(input)
c15b34 ¤   ¤   {
63f4a1 ¤   ¤   ¤   int count = 3;
1656a8 ¤   ¤   ¤   char* pointer = input;
21af5a
76c130 ¤   ¤   ¤   while(count && *pointer)
f5f776 ¤   ¤   ¤   {
231adf ¤   ¤   ¤   ¤   pointer = strstr(pointer, "\r\n");
210361 ¤   ¤   ¤   ¤   pointer¤+= 2;
f382cb ¤   ¤   ¤   ¤   count--;
aca3a6 ¤   ¤   ¤   }
5daf5a
8d14d0 ¤   ¤   ¤   success = WriteFile(hTempFile,·
79038c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pointer,·
2e0fd1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen(pointer),·
edbb48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &size,·
e60028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
e8af5a
fcc976 ¤   ¤   ¤   free(input);
570fe4 ¤   ¤   }
7daf5a
0e2d55 ¤   ¤   // clean up
e0b38f ¤   ¤   CloseHandle(hTempFile);
a1af5a
590d9a ¤   ¤   if(success)
145b34 ¤   ¤   {
ee4710 ¤   ¤   ¤   CopyFile(szTempFile, file, FALSE);·
780fe4 ¤   ¤   }
acaf5a
05365b ¤   ¤   DeleteFile(szTempFile);
909371 ¤   }
0aaf5a
a0efe6 }
4faf5a
44af5a
--0537 0015a80b8fc401101ef Page 1 of TranslatorUtils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
acdddf ¤   $Id: TranslatorUtils.h,v 1.3.8.1 1998/11/12 03:11:51 heller Exp $
23f7f7 ____________________________________________________________________________*/
5f81e9 #ifndef Included_TranslatorUtils_h¤ /* [ */
18d5b9 #define Included_TranslatorUtils_h
39af5a
52e127 #define DELIMITERLENGTH 256
b4af5a
335e47 #include "emssdk/ems-win.h"
98af5a
f80f9b long ExtractAddressesFromMailHeader(
77c755 ¤   emsHeaderDataP header,·
b54d5a ¤   char*** addresses
43823f ¤   );
32af5a
eec823 void·
63561e FreeRecipientList(
2afa81 ¤   char** Recipients,·
211ee3 ¤   unsigned long ·numRecipients
44823f ¤   );
77af5a
9ec823 void·
b10a15 StripMIMEHeader(
82a3b4 ¤   const char* path
c6823f ¤   );
c0af5a
03af5a
66bed2 #endif /* ] Included_TranslatorUtils_h */
35af5a
fdaf5a
fb7e4d /*__Editor_settings____
bdaf5a
fc4126 ¤   Local Variables:
9d7b17 ¤   tab-width: 4
e20e6c ¤   End:
3a5f8c ¤   vi: ts=4 sw=4
209e9b ¤   vim: si
5a7c50 _____________________*/¶
--24d5 00044f9fb08401101f0 Page 1 of Translators.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
87221c ¤   $Id: Translators.c,v 1.16.2.4.2.1 1998/11/12 03:11:52 heller Exp $
82f7f7 ____________________________________________________________________________*/
73d83c ·
899b16 // System Headers
f55655 #include <windows.h>
db3d0b #include <windowsx.h>
e4bb5f #include <assert.h>
26af5a
68af5a
705582 // PGPsdk Headers
1ae2ff #include "pgpConfig.h"
2ba076 #include "pgpKeys.h"
252f8d #include "pgpErrors.h"
274919 #include "pgpUtilities.h"
8dec82 #include "pgpTLS.h"
0c91b9 #include "pgpSDKPrefs.h"
cdaf5a
2b4f9a // Eudora Headers
a12ba1 #include "emssdk/Mimetype.h"
abaf5a
a62062 // Shared Headers
2e5ab2 #include "PGPcl.h"
f172fe #include "PGPsc.h"
73af5a
ade8e0 // Project Headers
2700ec #include "PluginMain.h"
0eb04c #include "EncryptSign.h"
3353a7 #include "DecryptVerify.h"
b705f4 #include "AddKey.h"
2cbbc6 #include "TranslatorUtils.h"
7d2bcf #include "MyMIMEUtils.h"
99fd0e #include "DisplayMessage.h"
a0cc89 #include "Prefs.h"
ef8031 #include "resource.h"
8baf5a
9daf5a
9e482b // Global Variables
bf6ba0 extern HINSTANCE¤   ¤   g_hinst;
8b1c13 extern PGPContextRef¤   g_pgpContext;
2c6768 extern PGPtlsContextRef¤g_tlsContext;
6caf5a
a3af5a
a6b9ca long CanTranslateMIMEType(¤ long transContext,
a81596 ¤   ¤   ¤   ¤   ¤   ¤   ¤   emsMIMEtypeP mimeType,
c3c9d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char* type,·
cb3316 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char* subType);
37af5a
a6af5a
c3c638 long CanPerformTranslation(
270d78 ¤   const long trans_id,·
8ea1c8 ¤   const emsMIMEtypeP in_mime,·
c9333d ¤   const long context
9d5b71 )
dfbb36 {
5d1693 ¤   long err = EMSR_CANT_TRANS;
a5af5a
a71419 ¤   if ( in_mime )
a25cb4 ¤   {¤  ¤   ¤
f6d9a5 ¤   ¤   switch(trans_id)
d55b34 ¤   ¤   {
b40d8a ¤   ¤   ¤   // manual (aka On-Demand) translators
450063 ¤   ¤   ¤   case kManualEncryptTranslatorID:
5c7709 ¤   ¤   ¤   case kManualSignTranslatorID:
930c18 ¤   ¤   ¤   case kManualEncryptSignTranslatorID:
9ad751 ¤   ¤   ¤   case kManualDecryptVerifyTranslatorID:
44f776 ¤   ¤   ¤   {
--e714 0004f0cf5ad401101f0 Page 2 of Translators.c
61597d ¤   ¤   ¤   ¤   if( in_mime && match_mime_type(¤in_mime,·
6c2808 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "text",·
81b4fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "plain") )
6872c3 ¤   ¤   ¤   ¤   {
1c5d9a ¤   ¤   ¤   ¤   ¤   if( ( context & EMSF_ON_REQUEST ) != 0 )
544859 ¤   ¤   ¤   ¤   ¤   {
1b1537 ¤   ¤   ¤   ¤   ¤   ¤   err = EMSR_NOW;
561c89 ¤   ¤   ¤   ¤   ¤   }
f72613 ¤   ¤   ¤   ¤   }
68f622 ¤   ¤   ¤   ¤   break;
f1a3a6 ¤   ¤   ¤   }
8baf5a
6c349a ¤   ¤   ¤   // Mime Translators
b3fb54 ¤   ¤   ¤   case kEncryptTranslatorID:
d37dbe ¤   ¤   ¤   case kSignTranslatorID:
476fee ¤   ¤   ¤   case kEncryptAndSignTranslatorID:
aff776 ¤   ¤   ¤   {
b75b9e ¤   ¤   ¤   ¤   err = EMSR_NOW;
25f622 ¤   ¤   ¤   ¤   break;
dca3a6 ¤   ¤   ¤   }
60af5a
596f05 ¤   ¤   ¤   case kDecryptTranslatorID:
6bf776 ¤   ¤   ¤   {
16597d ¤   ¤   ¤   ¤   if( in_mime && match_mime_type(¤in_mime,·
698a17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "multipart",·
5d6c9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "encrypted") )
e772c3 ¤   ¤   ¤   ¤   {
cd2d54 ¤   ¤   ¤   ¤   ¤   err = CanTranslateMIMEType(¤context,·
11e338 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_mime,·
848a17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "multipart",·
678735 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "encrypted");
ac2613 ¤   ¤   ¤   ¤   }
29af5a
90f622 ¤   ¤   ¤   ¤   break;
70a3a6 ¤   ¤   ¤   }
5aaf5a
80193f ¤   ¤   ¤   case kVerifyTranslatorID:
8cf776 ¤   ¤   ¤   {
b4597d ¤   ¤   ¤   ¤   if( in_mime && match_mime_type(¤in_mime,·
428a17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "multipart",·
008f77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "signed") )
1a72c3 ¤   ¤   ¤   ¤   {
522d54 ¤   ¤   ¤   ¤   ¤   err = CanTranslateMIMEType(¤context,·
d1e338 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   in_mime,·
ad8a17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "multipart",·
fc4591 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "signed");
b82613 ¤   ¤   ¤   ¤   }
eaaf5a
65f622 ¤   ¤   ¤   ¤   break;
f1a3a6 ¤   ¤   ¤   }
f4ec70 ¤   ¤   }¤  ¤
4d9371 ¤   }
5aaf5a
225ea8 ¤   return err;
23efe6 }
67af5a
fcd7c3 long PerformTranslation(
d80d78 ¤   const long trans_id,·
fbb6f5 ¤   const char* in_file,·
78b3de ¤   const char* out_file,·
1ac755 ¤   emsHeaderDataP header,·
b237bd ¤   emsMIMEtypeP in_mime,
ec19f9 ¤   emsMIMEtypeP* out_mime
6e5b71 )
22bb36 {
25d6eb ¤   long¤   ¤   pluginReturn¤   = EMSR_UNKNOWN_FAIL;
d1d356 ¤   BOOL¤   ¤   bSign¤  ¤   ¤   = FALSE;
89e6c1 ¤   PGPError¤   error¤  ¤   ¤   = kPGPError_NoErr;
792ddc ¤   PGPSize¤¤   mimeBodyOffset¤ = 0;
086b39 ¤   BOOL¤   ¤   bMIME¤  ¤   ¤   = FALSE;
297ade ¤   BOOL¤   ¤   bManual¤¤   ¤   = TRUE;
4f38c0 ¤   char¤   ¤   szExe[256];
--46cd 000b18ac3cf401101f0 Page 3 of Translators.c
fd7895 ¤   char¤   ¤   szDll[256];
b0fb4a ¤   char¤   ¤   temp_file[256];
64af5a
e91784 ¤   assert(in_file);
3c0ab8 ¤   assert(out_file);
fa6b80 ¤   temp_file[0] = 0;
a6af5a
0ef1e6 ¤   LoadString(g_hinst, IDS_EXE, szExe, sizeof(szExe));
bf9ff8 ¤   LoadString(g_hinst, IDS_DLL, szDll, sizeof(szDll));
e5af5a
7ddcaa ¤   switch( trans_id )
90c7a1 ¤   {
9bbaa7 ¤   ¤   case kEncryptTranslatorID:
ebf642 ¤   ¤   case kSignTranslatorID:
8d562b ¤   ¤   case kEncryptAndSignTranslatorID:
e65b34 ¤   ¤   {
1786e0 ¤   ¤   ¤   bManual = FALSE;
6daf5a
639b82 ¤   ¤   ¤   if(UsePGPMimeForEncryption(PGPGetContextMemoryMgr(g_pgpContext))
eb184f ¤   ¤   ¤   ¤   || ( in_mime && !match_mime_type(in_mime, "text", "plain") )·
e11731 ¤   ¤   ¤   )
32f776 ¤   ¤   ¤   {
77518a ¤   ¤   ¤   ¤   bMIME = TRUE;
11a3a6 ¤   ¤   ¤   }
fe0fe4 ¤   ¤   }
06af5a
2f06db ¤   ¤   case kManualEncryptTranslatorID:
0d4be7 ¤   ¤   case kManualSignTranslatorID:
6d5e85 ¤   ¤   case kManualEncryptSignTranslatorID:
105b34 ¤   ¤   {
fdfb9f ¤   ¤   ¤   char** addresses = NULL;
f9793c ¤   ¤   ¤   unsigned long numRecipients = 0;
abb023 ¤   ¤   ¤   PGPOptionListRef pgpOptions = NULL;
953415 ¤   ¤   ¤   PGPOptionListRef signOptions = NULL;
1d7b29 ¤   ¤   ¤   char mimeSeparator[kPGPMimeSeparatorSize];
f18561 ¤   ¤   ¤   BOOL bEncrypt = FALSE;
9f0889 ¤   ¤   ¤   BOOL bSign = FALSE;
2a48c2 ¤   ¤   ¤   PRECIPIENTDIALOGSTRUCT prds = NULL;¤
b3af5a
da8692 ¤   ¤   ¤   if(bManual)
5af776 ¤   ¤   ¤   {
213994 ¤   ¤   ¤   ¤   long lWrapWidth = 0;
45af5a
cf0275 ¤   ¤   ¤   ¤   bEncrypt = ((trans_id == kManualSignTranslatorID)·
fb4e60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ? FALSE : TRUE );
2aaf5a
37757a ¤   ¤   ¤   ¤   bSign = ((trans_id == kManualEncryptTranslatorID)·
0a4e60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ? FALSE : TRUE );
c0af5a
d45dba ¤   ¤   ¤   ¤   if (ByDefaultWordWrap(PGPGetContextMemoryMgr(g_pgpContext),·
2d3508 ¤   ¤   ¤   ¤   ¤   ¤   &lWrapWidth))
1472c3 ¤   ¤   ¤   ¤   {
f275ca ¤   ¤   ¤   ¤   ¤   HANDLE hFile = NULL;
e8abef ¤   ¤   ¤   ¤   ¤   DWORD dwBytes;
326dbc ¤   ¤   ¤   ¤   ¤   DWORD dwLength;
7dd6e4 ¤   ¤   ¤   ¤   ¤   char *szFileData = NULL;
f3ca4c ¤   ¤   ¤   ¤   ¤   char *szWrapped = NULL;
29af5a
b73484 ¤   ¤   ¤   ¤   ¤   hFile = CreateFile(in_file, GENERIC_READ, 0, NULL,·
2018cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
b5af5a
d8ef3b ¤   ¤   ¤   ¤   ¤   dwLength = GetFileSize(hFile, NULL);
f6af5a
096425 ¤   ¤   ¤   ¤   ¤   szFileData = (char *) calloc(sizeof(char), dwLength+1);
97af5a
fc5c6a ¤   ¤   ¤   ¤   ¤   ReadFile(hFile, szFileData, dwLength, &dwBytes, NULL);
ddbd45 ¤   ¤   ¤   ¤   ¤   CloseHandle(hFile);
943509 ¤   ¤   ¤   ¤   ¤   szFileData[dwLength] = 0;
15af5a
655736 ¤   ¤   ¤   ¤   ¤   if (WrapBuffer(&szWrapped, szFileData, (short)lWrapWidth))
ac4859 ¤   ¤   ¤   ¤   ¤   {
b1e592 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(temp_file, in_file);
--44f5 000355981c1401101f0 Page 4 of Translators.c
dcc966 ¤   ¤   ¤   ¤   ¤   ¤   dwBytes = strlen(temp_file);
e07ed2 ¤   ¤   ¤   ¤   ¤   ¤   temp_file[dwBytes-5]++;
b172af ¤   ¤   ¤   ¤   ¤   ¤   temp_file[dwBytes-6]++;
3d7684 ¤   ¤   ¤   ¤   ¤   ¤   temp_file[dwBytes-7]++;
7baf5a
35d15d ¤   ¤   ¤   ¤   ¤   ¤   hFile = CreateFile(temp_file, GENERIC_WRITE, 0, NULL,·
9c9ed8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,·
d90e64 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
8caf5a
41bbf3 ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, szWrapped, strlen(szWrapped),
2a09f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwBytes, NULL);
b53523 ¤   ¤   ¤   ¤   ¤   ¤   CloseHandle(hFile);
ddaf5a
c68d5e ¤   ¤   ¤   ¤   ¤   ¤   in_file = temp_file;
711c89 ¤   ¤   ¤   ¤   ¤   }
0baf5a
879691 ¤   ¤   ¤   ¤   ¤   free(szFileData);
fd2071 ¤   ¤   ¤   ¤   ¤   free(szWrapped);
f12613 ¤   ¤   ¤   ¤   }
2aa3a6 ¤   ¤   ¤   }
90bb8c ¤   ¤   ¤   else
4df776 ¤   ¤   ¤   {
b38e2a ¤   ¤   ¤   ¤   bEncrypt = ((trans_id == kSignTranslatorID) ? FALSE : TRUE );
877911 ¤   ¤   ¤   ¤   bSign = ((trans_id == kEncryptTranslatorID) ? FALSE : TRUE );
44af5a
64fbf1 ¤   ¤   ¤   ¤   if(!bMIME)
cd72c3 ¤   ¤   ¤   ¤   {
b10f70 ¤   ¤   ¤   ¤   ¤   // want it to look clean upon decryption
4389db ¤   ¤   ¤   ¤   ¤   // we need only the text of the message
792e87 ¤   ¤   ¤   ¤   ¤   StripMIMEHeader(in_file);
7f2613 ¤   ¤   ¤   ¤   }
e50b49 ¤   ¤   ¤   }¤  ¤   ¤
46af5a
1fb7cf ¤   ¤   ¤   // allocate a recipient dialog structure
6b6188 ¤   ¤   ¤   prds = (PRECIPIENTDIALOGSTRUCT)·
c6e941 ¤   ¤   ¤   ¤   ¤   calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);
14af5a
88bd2e ¤   ¤   ¤   if(prds)
e0f776 ¤   ¤   ¤   {
721dcd ¤   ¤   ¤   ¤   char szTitle[256] = {0x00};¤¤   // title for recipient dialog
0cd564 ¤   ¤   ¤   ¤   UINT recipientReturn = FALSE;¤  // recipient dialog result
0bcfc1 ¤   ¤   ¤   ¤   PGPKeySetRef¤   keyset¤ = kPGPInvalidRef;
26af5a
c07564 ¤   ¤   ¤   ¤   error = PGPsdkLoadDefaultPrefs(g_pgpContext);
345a21 ¤   ¤   ¤   ¤   if (IsPGPError(error))
7172c3 ¤   ¤   ¤   ¤   {
f000c1 ¤   ¤   ¤   ¤   ¤   PGPclEncDecErrorBox(NULL, error);
98eb2f ¤   ¤   ¤   ¤   ¤   return EMSR_UNKNOWN_FAIL;
e12613 ¤   ¤   ¤   ¤   }
10af5a
a96be9 ¤   ¤   ¤   ¤   error = PGPOpenDefaultKeyRings(g_pgpContext,·
24275b ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPKeyRingOpenFlags)0,·
32fe38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(prds->OriginalKeySetRef));
d0af5a
6c5a21 ¤   ¤   ¤   ¤   if (IsPGPError(error))
c372c3 ¤   ¤   ¤   ¤   {
e900c1 ¤   ¤   ¤   ¤   ¤   PGPclEncDecErrorBox(NULL, error);
1eeb2f ¤   ¤   ¤   ¤   ¤   return EMSR_UNKNOWN_FAIL;
ec2613 ¤   ¤   ¤   ¤   }
10af5a
6d8d49 ¤   ¤   ¤   ¤   if (bEncrypt)
c472c3 ¤   ¤   ¤   ¤   {
c249f5 ¤   ¤   ¤   ¤   ¤   // do we have the header structure?
3c6156 ¤   ¤   ¤   ¤   ¤   // should we autofind recipients?
2b6571 ¤   ¤   ¤   ¤   ¤   if(header)·
194859 ¤   ¤   ¤   ¤   ¤   {
5add97 ¤   ¤   ¤   ¤   ¤   ¤   numRecipients = ExtractAddressesFromMailHeader(¤
344591 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   header,
d4d087 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &addresses);
6a1c89 ¤   ¤   ¤   ¤   ¤   }
b7af5a
35953b ¤   ¤   ¤   ¤   ¤   LoadString(GetModuleHandle("PGPplugin.dll"),·
--6376 000747f88f6401101f0 Page 5 of Translators.c
3bad72 ¤   ¤   ¤   ¤   ¤   ¤   IDS_TITLE_RECIPIENTDIALOG, szTitle, sizeof(szTitle));
09af5a
a4835e ¤   ¤   ¤   ¤   ¤   prds->Context¤  ¤   ¤   = g_pgpContext;
ea0fc0 ¤   ¤   ¤   ¤   ¤   prds->tlsContext¤   ¤   = g_tlsContext;
4eb0cd ¤   ¤   ¤   ¤   ¤   prds->Version¤  ¤   ¤   = CurrentPGPrecipVersion;
ff2418 ¤   ¤   ¤   ¤   ¤   prds->hwndParent¤   ¤   = NULL;¤¤   ¤
f72c46 ¤   ¤   ¤   ¤   ¤   prds->szTitle¤  ¤   ¤   = szTitle;
6f7156 ¤   ¤   ¤   ¤   ¤   prds->dwOptions¤¤   ¤   = PGPCL_ASCIIARMOR;¤
d887c7 ¤   ¤   ¤
e97e94 ¤   ¤   ¤   ¤   ¤   prds->dwDisableFlags¤   = PGPCL_DISABLE_WIPEORIG |
cec7a1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPCL_DISABLE_ASCIIARMOR;
24af5a
8f8e3d ¤   ¤   ¤   ¤   ¤   prds->dwNumRecipients¤  = numRecipients;¤
433c88 ¤   ¤   ¤   ¤   ¤   prds->szRecipientArray¤ = addresses;
45af5a
b375b5 ¤   ¤   ¤   ¤   ¤   // If shift is pressed, force the dialog to pop.
d26126 ¤   ¤   ¤   ¤   ¤   if (GetAsyncKeyState( VK_CONTROL ) & 0x8000)
b8e49f ¤   ¤   ¤   ¤   ¤   ¤   prds->dwDisableFlags|=PGPCL_DISABLE_AUTOMODE;
fdaf5a
108a46 ¤   ¤   ¤   ¤   ¤   // See who we wish to encrypt this to
1f5245 ¤   ¤   ¤   ¤   ¤   recipientReturn = PGPclRecipientDialog( prds );
442b85 ¤   ¤   ¤   ¤
4d2357 ¤   ¤   ¤   ¤   ¤   if (prds->AddedKeys != NULL)
0d4859 ¤   ¤   ¤   ¤   ¤   {
35fc22 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32 numKeys;
f594aa ¤   ¤   ¤   ¤   ¤   ¤
af14b4 ¤   ¤   ¤   ¤   ¤   ¤   PGPCountKeys(prds->AddedKeys, &numKeys);
7444a9 ¤   ¤   ¤   ¤   ¤   ¤   if (numKeys > 0)
c5b25a ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys(g_pgpContext, g_tlsContext,·
f0f32e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, prds->AddedKeys,·
6f0028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
09ae30 ¤   ¤   ¤   ¤   ¤
371e83 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->AddedKeys);
d201e4 ¤   ¤   ¤   ¤   ¤   ¤   prds->AddedKeys = NULL;
c71c89 ¤   ¤   ¤   ¤   ¤   }
a9af5a
631b23 ¤   ¤   ¤   ¤   ¤   if (!recipientReturn)
6d4859 ¤   ¤   ¤   ¤   ¤   {
5c9d83 ¤   ¤   ¤   ¤   ¤   ¤   if (addresses)
48a2c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FreeRecipientList(addresses, numRecipients);
8e2aab ¤   ¤   ¤   ¤   ¤   ¤   if (prds->SelectedKeySetRef != NULL)
43ecd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
faa5c9 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
b27d3b ¤   ¤   ¤   ¤   ¤   ¤   free(prds);
2da411 ¤   ¤   ¤   ¤   ¤   ¤   return EMSR_UNKNOWN_FAIL;
c11c89 ¤   ¤   ¤   ¤   ¤   }
162613 ¤   ¤   ¤   ¤   }
a1af5a
8812ed ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
5172c3 ¤   ¤   ¤   ¤   {
17bb4a ¤   ¤   ¤   ¤   ¤   error = PGPBuildOptionList(g_pgpContext, &pgpOptions,
2a2836 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOOutputLineEndType(g_pgpContext,·
a7e3f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPLineEnd_CRLF),
a9e97c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (bMIME ·?·
44d76e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPGPMIMEEncoding(g_pgpContext,·
dedf25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE,·
ef1c0d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &mimeBodyOffset,·
1539da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mimeSeparator) :·
496b73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPONullOption(g_pgpContext) ), ····
ccbd10 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(g_pgpContext) );
b02613 ¤   ¤   ¤   ¤   }
55af5a
0fb78c ¤   ¤   ¤   ¤   if(IsntPGPError( error))
c472c3 ¤   ¤   ¤   ¤   {
0c7286 ¤   ¤   ¤   ¤   ¤   error = EncryptSignFile(g_hinst, NULL,·
a997d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_pgpContext, g_tlsContext, szExe,·
4ec153 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDll, (char *) in_file, prds,·
b6b276 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pgpOptions, &signOptions, (char *) out_file,·
cb43ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt, bSign, bMIME);·
ecaf5a
678055 ¤   ¤   ¤   ¤   ¤   PGPFreeOptionList(pgpOptions);
743657 ¤   ¤   ¤   ¤   ¤   PGPFreeOptionList(signOptions);
--b42d 000aaf95356401101f0 Page 6 of Translators.c
862613 ¤   ¤   ¤   ¤   }
7dfa07 ¤   ¤   ¤   ¤   else
8772c3 ¤   ¤   ¤   ¤   {
111e3a ¤   ¤   ¤   ¤   ¤   PGPclEncDecErrorBox (NULL, error);
d72613 ¤   ¤   ¤   ¤   }
32af5a
fb500f ¤   ¤   ¤   ¤   if (addresses)
862ffa ¤   ¤   ¤   ¤   ¤   FreeRecipientList(addresses, numRecipients);
4a632d ¤   ¤   ¤   ¤   if (prds->SelectedKeySetRef != NULL)
3315a0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
73ee82 ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
2f5b99 ¤   ¤   ¤   ¤   free(prds);
81af5a
d4c334 ¤   ¤   ¤   ¤   if (in_file == temp_file)
af33ba ¤   ¤   ¤   ¤   ¤   DeleteFile(temp_file);
ffaf5a
eb12ed ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
4072c3 ¤   ¤   ¤   ¤   {
eeb3c8 ¤   ¤   ¤   ¤   ¤   if( out_mime )
9f4859 ¤   ¤   ¤   ¤   ¤   {
be31b9 ¤   ¤   ¤   ¤   ¤   ¤   if(bMIME)
168fec ¤   ¤   ¤   ¤   ¤   ¤   {
90ffc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   *out_mime = make_mime_type(¤"multipart",
6f32de ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "encrypted",·
f88b76 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "1.0");
eeaf5a
93457b ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( *out_mime )
bc06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
0ae9c4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pluginReturn = EMSR_OK;
fbaf5a
7201af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   add_mime_parameter(¤*out_mime,·
6b53e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "boundary",·
2d4da1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   mimeSeparator);
9daf5a
8e01af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   add_mime_parameter(¤*out_mime,·
97dc62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "PGPFormat",·
61e516 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "PGPMIME-encrypted");
3f5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
0ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
b57f8b ¤   ¤   ¤   ¤   ¤   ¤   else
428fec ¤   ¤   ¤   ¤   ¤   ¤   {
81457b ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( *out_mime )
0506b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
4ae9c4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pluginReturn = EMSR_OK;
d4af5a
56578f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *out_mime = make_mime_type(¤"text",
c84ae0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "plain",·
c8b618 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "1.0");
765268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
e2db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ff1c89 ¤   ¤   ¤   ¤   ¤   }
d52613 ¤   ¤   ¤   ¤   }
7da3a6 ¤   ¤   ¤   }
daaf5a
71cdcb ¤   ¤   ¤   break;
920fe4 ¤   ¤   }
b4af5a
5d2ef6 ¤   ¤   case kDecryptTranslatorID:
6df64c ¤   ¤   case kVerifyTranslatorID:
6f5b34 ¤   ¤   {
6386e0 ¤   ¤   ¤   bManual = FALSE;
ca0fe4 ¤   ¤   }
8f0fe3 ¤   ¤   case kManualDecryptVerifyTranslatorID:
a1af5a
9f5b34 ¤   ¤   {
18ea83 ¤   ¤   ¤   char *szTempFile = NULL;
fa226d ¤   ¤   ¤   BOOL bFYEO = FALSE;
c67a4e ¤   ¤   ¤   void *pOutput = NULL;
594c89 ¤   ¤   ¤   PGPSize outSize = 0;
61af5a
b49cf0 ¤   ¤   ¤   error = DecryptVerifyFile(g_hinst, NULL, g_pgpContext,·
aa36e0 ¤   ¤   ¤   ¤   ¤   ¤   g_tlsContext, szExe, szDll, (char *) in_file,·
--c89a 000ba707864401101f0 Page 7 of Translators.c
fa764e ¤   ¤   ¤   ¤   ¤   ¤   !bManual, FALSE, &szTempFile, &pOutput, &outSize,
939a25 ¤   ¤   ¤   ¤   ¤   ¤   &bFYEO);
54af5a
ab17f9 ¤   ¤   ¤   if( IsntPGPError(error) )·
0ef776 ¤   ¤   ¤   {
4d27ff ¤   ¤   ¤   ¤   if (bFYEO)
cb7bae ¤   ¤   ¤   ¤   ¤   TempestViewer((void *)g_pgpContext,NULL,pOutput,outSize);
8faf5a
752651 ¤   ¤   ¤   ¤   CopyFile(szTempFile, out_file, FALSE);
3678f2 ¤   ¤   ¤   ¤   DeleteFile(szTempFile);
0faf5a
d5b966 //¤ ¤   ¤   ¤   AddKeyFile(NULL, g_pgpContext,·
f8cd56 //¤ ¤   ¤   ¤   ¤   g_tlsContext, out_file);
87af5a
483fb7 ¤   ¤   ¤   ¤   if( out_mime )
c672c3 ¤   ¤   ¤   ¤   {
d1b161 ¤   ¤   ¤   ¤   ¤   ParseFileForMIMEType( out_file, out_mime );
1e2613 ¤   ¤   ¤   ¤   }
1eaf5a
3427ff ¤   ¤   ¤   ¤   if (bFYEO)
fe878d ¤   ¤   ¤   ¤   ¤   pluginReturn = EMSR_UNKNOWN_FAIL;
1dfa07 ¤   ¤   ¤   ¤   else
5f3279 ¤   ¤   ¤   ¤   ¤   pluginReturn = EMSR_OK;
f9a3a6 ¤   ¤   ¤   }
98af5a
636591 ¤   ¤   ¤   if (szTempFile != NULL)
250608 ¤   ¤   ¤   ¤   PGPFreeData(szTempFile);
8f7f15 ¤   ¤   ¤   if (pOutput != NULL)
9cbce3 ¤   ¤   ¤   ¤   PGPFreeData(pOutput);
a2af5a
0ecdcb ¤   ¤   ¤   break;
420fe4 ¤   ¤   }
61af5a
089371 ¤   }
dcaf5a
b2e082 ¤   return pluginReturn;
dbefe6 }
57af5a
65af5a
7c4200 long CanTranslateMIMEType(
d826f7 ¤   long¤   ¤   ¤   ¤   ¤   transContext,
4efa60 ¤   emsMIMEtypeP¤   ¤   ¤   mimeType,
bdcd20 ¤   const char*¤¤   ¤   ¤   type,
7858bc ¤   const char*¤¤   ¤   ¤   subType)
49bb36 {
c0011a ¤   long¤   err¤= EMSR_CANT_TRANS;
e267c5 ¤
1cd3ed ¤   if ( mimeType )
29c7a1 ¤   {
62400a ¤   ¤   BOOL¤   ¤   haveValidContext;
3d1cc8 ¤   ¤   const long¤ kValidContextMask = EMSF_ON_DISPLAY | EMSF_ON_ARRIVAL;
7b1b52 ¤   ¤
5aa335 ¤   ¤   haveValidContext¤   = ( transContext & kValidContextMask ) != 0;
921b52 ¤   ¤
1710a9 ¤   ¤   if ( haveValidContext )
a05b34 ¤   ¤   {
af90db ¤   ¤   ¤   BOOL haveMatch;
8287c7 ¤   ¤   ¤
83edd7 ¤   ¤   ¤   haveMatch = match_mime_type( mimeType, type, subType );
edaf5a
ae8839 ¤   ¤   ¤   if( haveMatch )
9ef776 ¤   ¤   ¤   {
8bd74f ¤   ¤   ¤   ¤   const char* PGPMimeParam = NULL;
7daf5a
dcda4c ¤   ¤   ¤   ¤   PGPMimeParam = get_mime_parameter(¤ mimeType,·
091344 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "protocol");
f8af5a
31f823 ¤   ¤   ¤   ¤   if(¤PGPMimeParam &&·
427d44 ¤   ¤   ¤   ¤   ¤   (!strcmp(PGPMimeParam, "application/pgp-encrypted") ||·
2433ed ¤   ¤   ¤   ¤   ¤   !strcmp(PGPMimeParam, "application/pgp-signature") )·
959284 ¤   ¤   ¤   ¤   )
ba72c3 ¤   ¤   ¤   ¤   {
--a2e3 001f2b2f56d401101f0 Page 8 of Translators.c
a8f292 ¤   ¤   ¤   ¤   ¤   haveMatch = TRUE;
ba2613 ¤   ¤   ¤   ¤   }
27fa07 ¤   ¤   ¤   ¤   else
4972c3 ¤   ¤   ¤   ¤   {
d1862a ¤   ¤   ¤   ¤   ¤   haveMatch = FALSE;
9c2613 ¤   ¤   ¤   ¤   }
23a3a6 ¤   ¤   ¤   }
1887c7 ¤   ¤   ¤
b43435 ¤   ¤   ¤   if ( haveMatch )
eaf776 ¤   ¤   ¤   {
4fd9ab ¤   ·¤  ¤   ····if( transContext == EMSF_ON_ARRIVAL )
700baa ¤   ·¤  ¤   ····{
3028dd ¤   ¤   ···¤ ·······err = EMSR_NOT_NOW;
181023 ¤   ¤   ···¤ ···}
129edb ¤   ¤   ···¤ ···else
ba44f3 ¤   ¤   ···¤ ···{
8884f7 ¤   ¤   ···¤¤   ····err = EMSR_NOW;
eab776 ¤   ¤   ···¤¤   }
62a3a6 ¤   ¤   ¤   }
200fe4 ¤   ¤   }
6a9371 ¤   }
af67c5 ¤
95deb7 ¤   return( err );
f2efe6 }
--c5d4 00197a37c1c401101f1 Page 1 of Translators.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
95bcb3 ¤   $Id: Translators.h,v 1.3.8.1 1998/11/12 03:11:53 heller Exp $
1af7f7 ____________________________________________________________________________*/
276908 #ifndef Included_Translators_h¤ /* [ */
8f536f #define Included_Translators_h
2caf5a
c2af5a
12c638 long CanPerformTranslation(
e10d78 ¤   const long trans_id,·
c0a1c8 ¤   const emsMIMEtypeP in_mime,·
f3333d ¤   const long context
06823f ¤   );
95af5a
9cd7c3 long PerformTranslation(
510d78 ¤   const long trans_id,·
93b6f5 ¤   const char* in_file,·
b3b3de ¤   const char* out_file,·
403fb5 ¤   emsHeaderDataP header,
4137bd ¤   emsMIMEtypeP in_mime,
eb19f9 ¤   emsMIMEtypeP* out_mime
d9823f ¤   );
f9af5a
7caf5a
64aae4 #endif /* ] Included_Translators_h */
55af5a
f9af5a
5e7e4d /*__Editor_settings____
00af5a
644126 ¤   Local Variables:
777b17 ¤   tab-width: 4
1c0e6c ¤   End:
f35f8c ¤   vi: ts=4 sw=4
529e9b ¤   vim: si
977c50 _____________________*/¶
--ccfb 001f754c5d9401101f2 Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
c3dbbc // Used by PGPplugin.rc
d4465d //
3e4dd0 #define IDS_WARN_NORECIPIENTS ··········1
a859be #define IDS_WARN_NORECIPIENTSTITLE ·····2
82bf59 #define IDS_TITLE_RECIPIENTDIALOG ······3
b4f1e8 #define IDS_WARN_DECRYPTFAILED ·········4
c4bf25 #define IDS_TITLE_PGPERROR ·············5
60c4d5 #define IDS_SUCCESS_ADDKEY ·············6
ef0f3b #define IDS_TITLE_ADDKEY ···············7
74f13b #define IDS_WARN_ADDKEY ················8
92a493 #define IDS_STRING8 ····················8
0fe60f #define IDS_STRING9 ····················9
660e4a #define IDS_TOOLTIP1 ···················10
7efa5e #define IDS_TOOLTIP2 ···················11
338b72 #define IDS_TOOLTIP3 ···················12
381a67 #define IDS_TOOLTIP4 ···················13
4a0c2b #define IDS_TOOLTIP5 ···················14
a1f83f #define IDS_TOOLTIP6 ···················15
258913 #define IDS_TOOLTIP7 ···················16
43d204 #define IDS_TOOLTIP8 ···················17
ef144d #define IDS_E_EXPIRED ··················18
b2740f #define IDS_E_EXPIREDTITLE ·············19
1cd77f #define IDS_PGPKEYSEXE ·················20
9b0e73 #define IDS_E_LAUNCHPGPKEYS ············21
fc774a #define IDS_EXE ························22
f73fb6 #define IDS_DLL ························23
e04bd4 #define IDI_PGP32 ······················101
62689b #define IDI_PGP_ENCRYPT ················103
cc9f37 #define IDI_PGP_DECRYPT ················104
313cd6 #define IDI_PGP_ENCRYPT_SIGN ···········105
8bded3 #define IDI_PGP_SIGN ···················106
40f376 #define IDI_PGP_VERIFY ·················107
b73696 #define IDI_PGP_ADDKEY ·················108
db8ab8 #define IDM_PGPABOUTMENU ···············113
073bdf #define IDM_PGPMENU ····················114
4d66e7 #define IDM_PGPENCRYPTMENU ·············114
cf9cab #define IDM_PGPDECRYPTMENU ·············115
4962fd #define IDI_PGP_KEYS ···················125
d7bd3b #define IDB_READTOOLBAR ················161
530d61 #define IDB_SENDTOOLBAR ················162
5a54c7 #define IDD_PASSPHRASE ·················1001
0ba32a #define IDC_PHRASE ·····················1002
adfd6b #define IDC_HIDETYPING ·················1003
a52942 #define IDC_PROMPTSTRING ···············1004
81413d #define ID_PGPHELP ·····················60001
902b6b #define ID_ABOUTPGP ····················60002
21da01 #define ID_PGPENCRYPT ··················60003
dc2c7a #define ID_PGPSIGN ·····················60004
3582e0 #define ID_PGPENCRYPTSIGN ··············60005
e573e5 #define ID_PREFERENCES ·················60006
363ea6 #define ID_PGPDECRYPTVERIFY ············60007
48ea80 #define ID_PGPGETKEY ···················60008
cba934 #define ID_PGPKEYS ·····················60009
2daf5a
b211aa // Next default values for new objects
eaac6a //·
c5f860 #ifdef APSTUDIO_INVOKED
943f23 #ifndef APSTUDIO_READONLY_SYMBOLS
0d51c3 #define _APS_NEXT_RESOURCE_VALUE ·······127
532a4e #define _APS_NEXT_COMMAND_VALUE ········60010
a0ef34 #define _APS_NEXT_CONTROL_VALUE ········1001
fd1285 #define _APS_NEXT_SYMED_VALUE ··········101
f67454 #endif
f77454 #endif
--3476 00156369879401101f3 Page 1 of strstri.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c8465e ¤   strstri.c,v 1.3 1997/07/16 05:51:53 elrod Exp
08f7f7 ____________________________________________________________________________*/
10af5a
279b16 // System Headers
f4bea3 #include <stdlib.h>
e6af5a
4e5f12 char* strstri(char * inBuffer, char * inSearchStr)
80bb36 {
52d7d6 ¤   char* ·currBuffPointer = inBuffer;
eeaf5a
9e00fc ····while (*currBuffPointer != 0x00)
dfc7a1 ¤   {
c6af1d ········char* compareOne = currBuffPointer;
937f55 ········char* compareTwo = inSearchStr;
f9af5a
d8bc20 ········while (tolower(*compareOne) == tolower(*compareTwo))
675b34 ¤   ¤   {
fc30d7 ············compareOne++;
6ad8f7 ············compareTwo++;
1c3e48 ············if (*compareTwo == 0x00)
85f776 ¤   ¤   ¤   {
7bc220 ¤   ¤   ¤   ¤   return (char*) currBuffPointer;
4e7812 ············}
ec7fb0 ········}
c98f8c ········currBuffPointer++;
526fe7 ····}
397daf ····return NULL;
56efe6 }
--efe3 00161415ef8401101f4 Page 1 of strstri.h
bc38e5 /*
620c71 ** Copyright (C)1997 Network Associates, Inc. and its affiliates.
2df124 ** All rights reserved.
3c7fe0 */
8daf5a
eb3379 #ifdef __cplusplus
406dad extern "C" {
cf7454 #endif
4faf5a
ec33ec char* strstri(char * inBuffer, char * inSearchStr);
abaf5a
073379 #ifdef __cplusplus
39efe6 }
617454 #endif

--80e2 00090d7c494401101f5 Page 1 of BUFTYPE.CPP
bc38e5 /*
940c2e ·* File: BUFTYPE.CPP
44775e ·*
8de440 ·* Date: Wednesday, August 28, 1996
00775e ·*
cc4ad2 ·* Author: Scott Manjourides
ba775e ·*
bbdc09 ·* Copyright (c) 1996 QUALCOMM, Incorporated
f3775e ·*
60495d ·*/
4baf5a
18bea3 #include <stdlib.h>
01324c #include <string.h>
69af5a
e2d3fb #include "BUFTYPE.H"
50af5a
77dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
c9af5a
1c64cc #ifndef TRUE
0a55ea #¤  define TRUE (1)
d57454 #endif
8eaf5a
6aec14 #ifndef FALSE
a6bdaf #¤  define FALSE (0)
3b7454 #endif
dbaf5a
d6e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d7af5a
1a87dc static int resizebuf_buf(BufTypePtr dst, unsigned int newSize);
efaf5a
eee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
04af5a
88b3b4 BufTypePtr makesize_buf(unsigned int n)
61bb36 {
efec30 ¤   BufTypePtr bp = (BufTypePtr) malloc(sizeof(BufType));
90af5a
423ab1 ¤   if (!bp)
388021 ¤   ¤   return (NULL);
ccaf5a
2ab30f ¤   clear_buf(bp);
2faf5a
4a01bb ¤   bp->buf = (char *) malloc(n * sizeof(char));
33af5a
02ad05 ¤   if (bp->buf)
1835eb ¤   ¤   bp->buf_size = n;
5c0e24 ¤   else
42c7a1 ¤   {
0bb5ff ¤   ¤   delete_buf(bp);
1f8021 ¤   ¤   return (NULL);
7f9371 ¤   }
58af5a
22a329 ¤   return (bp);
1befe6 }
30af5a
d7e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
09af5a
330d95 BufTypePtr make_buf()
8abb36 {
eeec30 ¤   BufTypePtr bp = (BufTypePtr) malloc(sizeof(BufType));
99af5a
503ab1 ¤   if (!bp)
f18021 ¤   ¤   return (NULL);
2aaf5a
a1b30f ¤   clear_buf(bp);
e0af5a
a8a329 ¤   return (bp);
77efe6 }
b6af5a
93e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
14af5a
041aba /* boolean */ int isempty_buf(BufTypePtr bp)
90bb36 {
--93ac 0006bc4058f401101f5 Page 2 of BUFTYPE.CPP
a62b5f ¤   if ((!bp) || (bp->buf == NULL) || (bp->len == 0))
abdc29 ¤   ¤   return (TRUE);
27af5a
bc5d9d ¤   return (FALSE);
fbefe6 }
f4af5a
f3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d3af5a
11d548 unsigned int availspace_buf(BufTypePtr bp)
f2bb36 {
c32359 ¤   if ((!bp) || (bp->buf == NULL))
c8f109 ¤   ¤   return (0);
d7af5a
430faf ¤   return (bp->buf_size - bp->len);
ecefe6 }
d1af5a
d7e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
50af5a
2b272b unsigned int buflen_buf(BufTypePtr bp) /* Number of valid chars in buffer. Alwa¶
25e1e8 ys < bufsize_buf() */
3bbb36 {
fdd4f4 ¤   if (isempty_buf(bp))
1cf109 ¤   ¤   return (0);
3faf5a
411d07 ¤   return (bp->len);
22efe6 }
99af5a
76e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d0af5a
13ce9f char *getbuf_buf(BufTypePtr bp)
f5bb36 {
2b3ab1 ¤   if (!bp)
d58021 ¤   ¤   return (NULL);
55af5a
56753d ¤   return (bp->buf);
f4efe6 }
f8af5a
66e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
adaf5a
ea513a char *getend_buf(BufTypePtr bp)
bbbb36 {
29d4f4 ¤   if (isempty_buf(bp))
1e8021 ¤   ¤   return (NULL);
10af5a
b1bd0d ¤   return ((bp->buf) + (bp->len - 1));
16efe6 }
c3af5a
a5e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
71af5a
d628d5 unsigned int bufsize_buf(BufTypePtr bp)
30bb36 {
453ab1 ¤   if (!bp)
b3f109 ¤   ¤   return (0);
d7af5a
e157c4 ¤   return (bp->buf_size);
6befe6 }
ffaf5a
0ee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
8aaf5a
eb343a /* boolean */ int endspan_buf(BufTypePtr buf, BufTypePtr find)
bbbb36 {
6087eb ¤   if (isempty_buf(buf) || isempty_buf(find))
b72769 ¤   ¤   return (FALSE);
4faf5a
b412f1 ¤   char cEnd = *getend_buf(buf); /* buf->buf[buf->len - 1]; */
ab7cc8 ¤   char *pPos = getpos_buf(find); /* find->buf */
485326 ¤   char *pEnd = getend_buf(find); /* (find->buf + find->len - 1); */
9caf5a
6d5b33 ¤   /* Return TRUE if the last char in 'buf' is anywhere in 'find' */
27301d ¤   while (pPos <= pEnd)
6bc7a1 ¤   {
6bf5e4 ¤   ¤   if (*pPos == cEnd)
--b164 000d2d03606401101f5 Page 3 of BUFTYPE.CPP
3f3ec8 ¤   ¤   ¤   return (TRUE);
43af5a
28f38a ¤   ¤   pPos++;
f09371 ¤   }
6baf5a
fe5d9d ¤   return (FALSE);
98efe6 }
7baf5a
4ce6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
f0af5a
f7ba63 /* boolean */ int setlen_buf(BufTypePtr bp, const unsigned int n)
cabb36 {
226254 ¤   if ((!bp) || (bp->buf == NULL) || (n > (bp->buf_size)))
8a2769 ¤   ¤   return (FALSE);
04af5a
c7d6eb ¤   bp->len = n;
96af5a
cee7c0 ¤   return (TRUE);
b8efe6 }
38af5a
42e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d5af5a
6c53c8 unsigned int bufncat_buf(BufTypePtr dst, BufTypePtr src, unsigned int n)
9fbb36 {
fd9a7c ¤   if ((isempty_buf(src)) || (n < 1) || (!dst))
54f109 ¤   ¤   return (0);
0daf5a
a50591 ¤   unsigned int oldSize = buflen_buf(dst);
d9f6e4 ¤   unsigned int addSize = poslen_buf(src);
25af5a
491a87 ¤   if (n < addSize)
e94b0b ¤   ¤   addSize = n;
a5af5a
babd20 ¤   unsigned int newSize = oldSize + addSize;
9caf5a
abd88d ¤   if (newSize > bufsize_buf(dst))
fdc7a1 ¤   {
2438e8 ¤   ¤   if (!resizebuf_buf(dst, newSize))
6d8bfd ¤   ¤   ¤   return (0);
979371 ¤   }
a5af5a
002d4b ¤   if (oldSize == 0)
f4f83b ¤   ¤   dst->pos = dst->buf;
7eaf5a
ba0631 ¤   char *cpDst, *cpSrc = getpos_buf(src);
074a90 ¤   unsigned int nCopy = addSize;
7eaf5a
89a881 ¤   if (oldSize > 0)
d2547b ¤   ¤   cpDst = getend_buf(dst) + 1;
650e24 ¤   else
10aca0 ¤   ¤   cpDst = getpos_buf(dst);
1daf5a
b52593 ¤   while (nCopy--)
85ad0a ¤   ¤   *cpDst++ = *cpSrc++;
48af5a
f42bb2 ¤   incpos_buf(src, addSize);
7cc4ba ¤   dst->len = newSize;
e7af5a
79e009 ¤   return (addSize);
23efe6 }
b4af5a
9ae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
85af5a
baaca4 unsigned int bufins_buf(BufTypePtr dst, BufTypePtr src)
60bb36 {
658d74 ¤   if (isempty_buf(src))
aaf109 ¤   ¤   return (0);
85af5a
a51735 ¤   unsigned int oldLen = poslen_buf(dst);
fc3884 ¤   unsigned int bufSize = bufsize_buf(dst);
5d106c ¤   unsigned int addLen = poslen_buf(src);
d225dc ¤   unsigned int newLen = oldLen + addLen;
--9d93 000e951d5e0401101f5 Page 4 of BUFTYPE.CPP
e0af5a
635f04 ¤   if (newLen > bufSize)
1d2123 ¤   ¤   addLen = bufSize - oldLen;
8baf5a
18ec01 ¤   if (addLen < 1)
0f879c ¤   ¤   return (0); /* Buffer is already full */
90af5a
edaee5 ¤   return (bufncat_buf(dst, src, addLen));
e3efe6 }
d3af5a
ece6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49af5a
45782d unsigned int bufnins_buf(BufTypePtr dst, BufTypePtr src, unsigned int n)
0abb36 {
15050c ¤   if ((isempty_buf(src)) || (n < 1))
4df109 ¤   ¤   return (0);
8baf5a
e31735 ¤   unsigned int oldLen = poslen_buf(dst);
843884 ¤   unsigned int bufSize = bufsize_buf(dst);
f6106c ¤   unsigned int addLen = poslen_buf(src);
fc25dc ¤   unsigned int newLen = oldLen + addLen;
99af5a
805f04 ¤   if (newLen > bufSize)
e62123 ¤   ¤   addLen = bufSize - oldLen;
87af5a
e60593 ¤   if (n < addLen)
dac2d6 ¤   ¤   addLen = n;
8eaf5a
54ec01 ¤   if (addLen < 1)
36879c ¤   ¤   return (0); /* Buffer is already full */
a1af5a
beaee5 ¤   return (bufncat_buf(dst, src, addLen));
31efe6 }
72af5a
25e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
29af5a
e0ad1e unsigned int poslen_buf(BufTypePtr bp) /* Number of valid chars, starting at cu¶
39d3ba rrent position */
50bb36 {
882291 ¤   if ((isempty_buf(bp)) || ((bp->pos) == NULL))
6ef109 ¤   ¤   return (0);
25af5a
084d73 ¤   return ( (bp->len) - ((bp->pos) - (bp->buf)) );
f0efe6 }
eeaf5a
74e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5aaf5a
ea2278 void incpos_buf(BufTypePtr bp, unsigned int n)
02bb36 {
bc3ab1 ¤   if (!bp)
1299bf ¤   ¤   return;
8267c5 ¤
832b9a ¤   if (poslen_buf(bp) > n)
b0fd16 ¤   ¤   bp->pos += n;
ca0e24 ¤   else
ae3dd1 ¤   ¤   bp->pos = NULL;
9eefe6 }
04af5a
52e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
55af5a
e32ffe void delpos_buf(BufTypePtr bp)
ebbb36 {
6d3ab1 ¤   if (!bp)
d599bf ¤   ¤   return;
d2af5a
d64725 ¤   bp->pos = NULL;
ecefe6 }
abaf5a
39e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
dcaf5a
a82301 void resetpos_buf(BufTypePtr bp)
e9bb36 {
--ecc0 000a6b119a6401101f5 Page 5 of BUFTYPE.CPP
807ea0 ¤   if (bp)
5651f7 ¤   ¤   bp->pos = bp->buf;
c2efe6 }
17af5a
c1e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3caf5a
c47047 char *getpos_buf(BufTypePtr bp)
35bb36 {
493ab1 ¤   if (!bp)
2c8021 ¤   ¤   return (NULL);
92af5a
063e49 ¤   if ((bp->pos) == NULL)
1d51f7 ¤   ¤   bp->pos = bp->buf;
3767c5 ¤
fd6ac5 ¤   return (bp->pos);
f3efe6 }
d3af5a
d4e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
a4af5a
323e67 unsigned int strcpy_buf(BufTypePtr dst, const char *src)
8fbb36 {
554c6a ¤   if ((!src) || (!dst))
dbf109 ¤   ¤   return (0);
04af5a
a3ba98 ¤   unsigned int nLen = strlen(src);
53af5a
fa925b ¤   if (nLen > 0)
6fc7a1 ¤   {
1fb726 ¤   ¤   if (nLen > bufsize_buf(dst))
015b34 ¤   ¤   {
112f2f ¤   ¤   ¤   if (!resizebuf_buf(dst, nLen))
1a7d98 ¤   ¤   ¤   ¤   return (0);
270fe4 ¤   ¤   }
62af5a
b4a090 ¤   ¤   char *cp = dst->buf;
abaf5a
ceea6c ¤   ¤   while (*src)
8144ed ¤   ¤   ¤   *cp++ = *src++;
a3af5a
75f83b ¤   ¤   dst->pos = dst->buf;
259371 ¤   }
49a406 ¤   else /* nLen == 0 */
37c7a1 ¤   {
fc5557 ¤   ¤   dst->pos = NULL;
c99371 ¤   }
c0af5a
156e7b ¤   dst->len = nLen;
7aaf5a
dc3858 ¤   return (nLen);
00efe6 }
c3af5a
cae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b3af5a
ed3e43 unsigned int strncpy_buf(BufTypePtr dst, const char *src, const unsigned int n)
00bb36 {
e34c6a ¤   if ((!src) || (!dst))
9cf109 ¤   ¤   return (0);
94af5a
c2ba98 ¤   unsigned int nLen = strlen(src);
b7af5a
7bc393 ¤   if (n < nLen)
b8dfda ¤   ¤   nLen = n;
9aaf5a
ca925b ¤   if (nLen > 0)
b2c7a1 ¤   {
5bb726 ¤   ¤   if (nLen > bufsize_buf(dst))
295b34 ¤   ¤   {
e02f2f ¤   ¤   ¤   if (!resizebuf_buf(dst, nLen))
af7d98 ¤   ¤   ¤   ¤   return (0);
7d0fe4 ¤   ¤   }
30af5a
a6a090 ¤   ¤   char *cp = dst->buf;
--8aff 000c33e7283401101f5 Page 6 of BUFTYPE.CPP
e0af5a
d9ea6c ¤   ¤   while (*src)
9d44ed ¤   ¤   ¤   *cp++ = *src++;
01af5a
15f83b ¤   ¤   dst->pos = dst->buf;
649371 ¤   }
d6a406 ¤   else /* nLen == 0 */
f8c7a1 ¤   {
805557 ¤   ¤   dst->pos = NULL;
aa9371 ¤   }
70af5a
426e7b ¤   dst->len = nLen;
49af5a
343858 ¤   return (nLen);
46efe6 }
00af5a
bbe6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
34af5a
fbfde8 unsigned int strcat_buf(BufTypePtr dst, const char *src)
6cbb36 {
eb4c6a ¤   if ((!src) || (!dst))
10f109 ¤   ¤   return (0);
6baf5a
fb0591 ¤   unsigned int oldSize = buflen_buf(dst);
3e6b7b ¤   unsigned int addSize = strlen(src);
fcbd20 ¤   unsigned int newSize = oldSize + addSize;
88af5a
87d88d ¤   if (newSize > bufsize_buf(dst))
8bc7a1 ¤   {
3338e8 ¤   ¤   if (!resizebuf_buf(dst, newSize))
e98bfd ¤   ¤   ¤   return (0);
9c9371 ¤   }
c3af5a
6d2d4b ¤   if (oldSize == 0)
b9f83b ¤   ¤   dst->pos = dst->buf;
2eaf5a
438807 ¤   char *cpDst, *cpSrc = (char *) src;
9c4a90 ¤   unsigned int nCopy = addSize;
66af5a
afa881 ¤   if (oldSize > 0)
02547b ¤   ¤   cpDst = getend_buf(dst) + 1;
ad0e24 ¤   else
6baca0 ¤   ¤   cpDst = getpos_buf(dst);
93af5a
e02593 ¤   while (nCopy--)
55ad0a ¤   ¤   *cpDst++ = *cpSrc++;
c6af5a
bdc4ba ¤   dst->len = newSize;
2caf5a
ede009 ¤   return (addSize);
a1af5a
7cefe6 }
efaf5a
80e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
07af5a
4e842a unsigned int strncat_buf(BufTypePtr dst, const char *src, const unsigned int n)
11bb36 {
0b4c6a ¤   if ((!src) || (!dst))
49f109 ¤   ¤   return (0);
d3af5a
ce0591 ¤   unsigned int oldSize = buflen_buf(dst);
9d6b7b ¤   unsigned int addSize = strlen(src);
3267c5 ¤
3f1a87 ¤   if (n < addSize)
464b0b ¤   ¤   addSize = n;
1c67c5 ¤
24bd20 ¤   unsigned int newSize = oldSize + addSize;
10af5a
5ad88d ¤   if (newSize > bufsize_buf(dst))
5fc7a1 ¤   {
8f38e8 ¤   ¤   if (!resizebuf_buf(dst, newSize))
c38bfd ¤   ¤   ¤   return (0);
--7312 000cad85d8b401101f5 Page 7 of BUFTYPE.CPP
a19371 ¤   }
93af5a
5f2d4b ¤   if (oldSize == 0)
c2f83b ¤   ¤   dst->pos = dst->buf;
19af5a
148807 ¤   char *cpDst, *cpSrc = (char *) src;
a24a90 ¤   unsigned int nCopy = addSize;
17af5a
9da881 ¤   if (oldSize > 0)
d0547b ¤   ¤   cpDst = getend_buf(dst) + 1;
b60e24 ¤   else
4baca0 ¤   ¤   cpDst = getpos_buf(dst);
0daf5a
e92593 ¤   while (nCopy--)
15ad0a ¤   ¤   *cpDst++ = *cpSrc++;
c0af5a
efc4ba ¤   dst->len = newSize;
53af5a
25e009 ¤   return (addSize);
1caf5a
46efe6 }
9eaf5a
25e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
16af5a
eec483 void delete_buf(BufTypePtr bp)
47bb36 {
f33ab1 ¤   if (!bp)
2299bf ¤   ¤   return;
0daf5a
2b5efd ¤   free_buf(bp);
76e1db ¤   safefree(bp);
34efe6 }
f0af5a
66e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d4af5a
c00940 void free_buf(BufTypePtr bp)
6ebb36 {
183ab1 ¤   if (!bp)
0299bf ¤   ¤   return;
27af5a
e3d3d2 ¤   safefree(bp->buf);
82b30f ¤   clear_buf(bp);
7cefe6 }
a9af5a
9ae6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d2af5a
3efa0a void clear_buf(BufTypePtr bp)
c9bb36 {
b53ab1 ¤   if (!bp)
3b99bf ¤   ¤   return;
d2af5a
e07862 ¤   bp->buf = NULL;
9e61a6 ¤   bp->buf_size = 0;
09af5a
f6ffa2 ¤   emptybuf_buf(bp);
59efe6 }
48af5a
a5e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
42af5a
e60c82 void emptybuf_buf(BufTypePtr bp)
10bb36 {
d53ab1 ¤   if (!bp)
5099bf ¤   ¤   return;
d1af5a
09b316 ¤   bp->pos = bp->buf;
5e4513 ¤   bp->len = 0;
e0efe6 }
29af5a
5be6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
64af5a
c4af5a
ca49b3 static /* boolean */ int resizebuf_buf(BufTypePtr bp, unsigned int newSize)
--8286 000b3cbf197401101f5 Page 8 of BUFTYPE.CPP
2cbb36 {
33e756 ¤   unsigned int oldSize = bp->buf_size;
7caf5a
f7cd02 ¤   if (oldSize == newSize)
6bdc29 ¤   ¤   return (TRUE);
d267c5 ¤
92c343 ¤   char *tmpPtr = (char *) realloc(bp->buf, newSize);
75af5a
4392d3 ¤   if (tmpPtr == NULL)
9c2769 ¤   ¤   return (FALSE);
77af5a
cc4087 ¤   bp->buf = tmpPtr;
323aea ¤   bp->buf_size = newSize;
99af5a
08777c ¤   if (newSize < oldSize) /* Getting smaller */
85c7a1 ¤   {
3ee86a ¤   ¤   /* Check for valid length */
0c4f03 ¤   ¤   if (bp->len > newSize)
f85757 ¤   ¤   ¤   bp->len = newSize;
c8af5a
c586a8 ¤   ¤   /* Check pos */
2aa6bb ¤   ¤   unsigned int nPos = ((bp->pos) - (bp->buf));
74fa6f ¤   ¤   if (nPos >= bp->len)
86cbb4 ¤   ¤   ¤   bp->pos = NULL;
389371 ¤   }
4285b6 ¤   else if (oldSize == 0)
ffc7a1 ¤   {
8851f7 ¤   ¤   bp->pos = bp->buf;
2f9371 ¤   }
37af5a
fbe7c0 ¤   return (TRUE);
b4efe6 }
40af5a
eee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36af5a
bc8c6a // If doesn't continue match, returns zero
57febc // otherwise returns number of chars of pSearchBuf that have been matched
ced424 unsigned int completecount_buf(BufTypePtr buf, BufTypePtr find, const unsigned ¶
1ca7fa int nPreMatched)
58bb36 {
cb87eb ¤   if (isempty_buf(buf) || isempty_buf(find))
85f109 ¤   ¤   return (0);
68af5a
57cff5 ¤   if (nPreMatched >= poslen_buf(find))
7df109 ¤   ¤   return (0);
97af5a
68b406 ¤   char *pBuf = getpos_buf(buf);
cf5ab3 ¤   char *pBufEnd = getend_buf(buf);
33af5a
cd8728 ¤   char *pFind = getpos_buf(find) + nPreMatched;
804889 ¤   char *pFindEnd = getend_buf(find);
4aaf5a
573cbf ¤   unsigned int nSkipCount = 0;
96af5a
b9165e ¤   while ((pBuf <= pBufEnd) && (pFind <= pFindEnd) && ((*pBuf) == (*pFind)))
dc9ce9 ¤   ¤   pBuf++, pFind++, nSkipCount++;
3eaf5a
2bb5ec ¤   if ((pBuf > pBufEnd) || (pFind > pFindEnd))
de4a2e ¤   ¤   return (nPreMatched + nSkipCount);
b5af5a
912424 ¤   return (0); /* match failed */
7aefe6 }
07af5a
c3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
e3af5a
7aa313 // Find match of pSearchBuf, either complete or end-spanning
1f1be8 // return number of chars to skip before match
498516 // No match: return length of buf (skip the whole buffer)
daa386 unsigned int skipcount_buf(BufTypePtr buf, BufTypePtr find)
c0bb36 {
579564 ¤   if (isempty_buf(buf))
b3f109 ¤   ¤   return (0);
--3d6e 0014c767d73401101f5 Page 9 of BUFTYPE.CPP
e0af5a
4c589c ¤   if (isempty_buf(find))
616523 ¤   ¤   return (poslen_buf(buf));
c6af5a
7bb406 ¤   char *pBuf = getpos_buf(buf);
d5051d ¤   char *pFind = getpos_buf(find);
3e5ab3 ¤   char *pBufEnd = getend_buf(buf);
244889 ¤   char *pFindEnd = getend_buf(find);
55af5a
87a056 ¤   char *s1 = NULL, *s2 = NULL;
b8af5a
113cbf ¤   unsigned int nSkipCount = 0;
94af5a
6b1672 ¤   while (pBuf <= pBufEnd)
56c7a1 ¤   {
95ba32 ¤   ¤   s1 = pBuf;
4a1398 ¤   ¤   s2 = pFind;
43af5a
e50344 ¤   ¤   while ((s1 <= pBufEnd) && (s2 <= pFindEnd) && ((*s1) == (*s2)))
814d31 ¤   ¤   ¤   s1++, s2++;
4daf5a
6d7583 ¤   ¤   if ((s1 > pBufEnd) || (s2 > pFindEnd))
ecf135 ¤   ¤   ¤   return (nSkipCount);
dbaf5a
b88852 ¤   ¤   pBuf++;
fe3a3e ¤   ¤   nSkipCount++;
649371 ¤   }
f2af5a
b7522b ¤   return (poslen_buf(buf));
4cefe6 }
--3827 001eed5b5a7401101f6 Page 1 of BUFTYPE.H
bc38e5 /*
9abbab ·* File: BUFTYPE.H
1e775e ·*
aee440 ·* Date: Wednesday, August 28, 1996
96775e ·*
c14ad2 ·* Author: Scott Manjourides
c0775e ·*
60dc09 ·* Copyright (c) 1996 QUALCOMM, Incorporated
ec775e ·*
c5495d ·*/
20af5a
b750df #ifndef BUFTYPE_H
4e8d86 #define BUFTYPE_H
01af5a
73e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
59af5a
0ff0f7 typedef struct {
7499d0 ¤   char *buf;
255e85 ¤   unsigned int buf_size;
28b069 ¤   unsigned int len;
44983f ¤   char *pos;
255467 } BufType;
19af5a
c8d9e8 typedef BufType *BufTypePtr;
04af5a
75e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
06af5a
b3f33c BufTypePtr makesize_buf(unsigned int n);
d8c309 BufTypePtr make_buf();
3aaf5a
261aeb /* boolean */ int isempty_buf(BufTypePtr bp);
3bceb9 unsigned int availspace_buf(BufTypePtr bp);
54f3f5 unsigned int buflen_buf(BufTypePtr bp); /* Number of valid chars in buffer. Alw¶
6fb053 ays < bufsize_buf() */
136c90 char *getbuf_buf(BufTypePtr bp);
5baf5a
3b9ea8 char *getend_buf(BufTypePtr bp);
2faa05 unsigned int bufsize_buf(BufTypePtr bp); /* The size of the buffer -- used or n¶
777268 ot */
a4a8a6 unsigned int buflen_buf(BufTypePtr bp);
ea5107 /* boolean */ int setlen_buf(BufTypePtr bp, const unsigned int n);
40af5a
164a37 unsigned int bufncat_buf(BufTypePtr dst, BufTypePtr src, unsigned int n);
203a52 unsigned int bufins_buf(BufTypePtr b1, BufTypePtr b2);
9461b9 unsigned int bufnins_buf(BufTypePtr b1, BufTypePtr b2, unsigned int n);
e5af5a
fe2401 unsigned int poslen_buf(BufTypePtr bp); /* Number of valid chars, starting at c¶
aa61db urrent position */
55af5a
f6ffcd void incpos_buf(BufTypePtr bp, unsigned int n);
151efe void delpos_buf(BufTypePtr bp);
a35aed char *getpos_buf(BufTypePtr bp); /* NULL problems */
da118a void resetpos_buf(BufTypePtr bp);
99af5a
9e17a7 unsigned int strcpy_buf(BufTypePtr dst, const char *src);
457081 unsigned int strncpy_buf(BufTypePtr dst, const char *src, const unsigned int n);
ab6b9b unsigned int strcat_buf(BufTypePtr dst, const char *src);
808efc unsigned int strncat_buf(BufTypePtr dst, const char *src, const unsigned int n);
2baf5a
84b677 void delete_buf(BufTypePtr bp);
fa422d void free_buf(BufTypePtr bp);
aeaf80 void clear_buf(BufTypePtr bp);
c8a736 void emptybuf_buf(BufTypePtr bp);
1baf5a
231f24 unsigned int completecount_buf(BufTypePtr src, BufTypePtr find, const unsigned ¶
64bd49 int n);
1fe1bd unsigned int skipcount_buf(BufTypePtr buf, BufTypePtr find);
c8af5a
ee7454 #endif
--c1d3 00073bf53d6401101f7 Page 1 of ENCODING.CPP
bc38e5 /*
288ba0 ·* ·Functions to encode and decode using BASE64 or Quoted-Printable
aab5e8 ·* ·Also a transfer-encoding header line parser
e1775e ·*
fe5064 ·* ·Filename: encoding.cpp
07775e ·*
badec9 ·* ·Last Edited: Friday, August 30, 1996
7c775e ·*
77005b ·* ·Author: Scott Manjourides
3b775e ·*
10cbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
12ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
63775e ·*
c1c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
1c495d ·*/
56af5a
b65655 #include <windows.h>
03fbd1 #include "ems-win.h"
7eaf5a
eabde1 #include "encoding.h"
0c291a #include "rfc822.h" ···
5395d9 #include "string.h"·
6f242a #include "ctype.h" ··
07ba0a #include "stdlib.h"
bcaf5a
4ac51a /* ========================================================================= */
a7af5a
a8dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
daaf5a
52c51a /* ========================================================================= */
76af5a
41cac7 /* Local util functions */
4e93e6 static char *newline_copy(char *dst);
27febb static int newline_test(const char prev, const char curr);
387185 static int hex2dec(const char ch);
d2af5a
abc067 /*****************************************************************************/
db0aa1 /* ·······························B A S E 6 4 ·······························*/
85c067 /*****************************************************************************/
0eaf5a
9f345b /* Base64 encoder/decoder ported from Macintosh source by Myra Callen */
33af5a
643330 #define SKIP (-1)
cd72de #define FAIL (-2)
20e683 #define PAD ·(-3)
c2af5a
fba7e5 #define kNewLine¤   ¤   ¤   "\015\012"
df8954 #define kNewLineLength (2)
07af5a
193f44 #define ABS(x) ··((x)<0 ? -(x) : (x))
c0af5a
1907f2 static char *g64EncodeChars =·
9122a4 ¤   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
cb6293 static short g64DecodeArr[] =·
68bb36 {
b390a3 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,SKIP,SKIP,FAIL,FAIL,SKIP,
a52f9e ¤   ¤   FAIL,FAIL,¤ /* 0 */
d95bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
20d2bf ¤   FAIL,FAIL,¤ /* 1 */
211add ¤   SKIP,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,0x3e,FAIL,FAIL,
7e6804 ¤   FAIL,0x3f,¤ /* 2 */
bc5225 ¤   0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,FAIL,FAIL,FAIL,PAD ,
77c437 ¤   FAIL,FAIL,¤ /* 3 */
59a677 ¤   FAIL,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
ee2b90 ¤   0x0d,0x0e,¤ /* 4 */
eaf982 ¤   0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,FAIL,FAIL,FAIL,
6fffaf ¤   FAIL,FAIL,¤ /* 5 */
26b181 ¤   FAIL,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
8c1c9e ¤   0x27,0x28,¤ /* 6 */
6ce2ef ¤   0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,FAIL,FAIL,FAIL,
68e927 ¤   FAIL,FAIL,¤ /* 7 */
735bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
--0225 00039b55de2401101f7 Page 2 of ENCODING.CPP
f983db ¤   FAIL,FAIL,¤ /* 8 */
805bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
b3889f ¤   FAIL,FAIL,¤ /* 9 */
035bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
28c74c ¤   FAIL,FAIL,¤ /* A */
035bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
14da80 ¤   FAIL,FAIL,¤ /* B */
6e5bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
48d1c4 ¤   FAIL,FAIL,¤ /* C */
865bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
cee118 ¤   FAIL,FAIL,¤ /* D */
b05bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
d9ea5c ¤   FAIL,FAIL,¤ /* E */
445bf2 ¤   FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,FAIL,
dbf790 ¤   FAIL,FAIL,¤ /* F */
7f5cc7 ··/* 0 ···1 ···2 ···3 ···4 ···5 ···6 ···7 ···8 ···9 ···A ···B ···C ···D ···
f67281 ··E ···F ·*/
3782f7 };
a6af5a
0538e5 /*
0af6e2 ·* Bit extracting macros
91495d ·*/
cd63c5 #define Bot2(b) ((b)&0x3)
146176 #define Bot4(b) ((b)&0xf)
655310 #define Bot6(b) ((b)&0x3f)
c7b929 #define Top2(b) Bot2((b)>>6)
bae633 #define Top4(b) Bot4((b)>>4)
03917b #define Top6(b) Bot6((b)>>2)
50af5a
a538e5 /*
b1219c ·* the decoder
0e495d ·*/
3b8947 #define EncodeThree64(bin,b64,bpl)¤ EncodeThreeFour(bin,b64,bpl,g64EncodeChars)
b7af5a
f8439f #define EncodeThreeFour(bin,b64,bpl,vector) ····················\
4ae7cc ¤   do ·························································\
1851d2 ¤   { ··························································\
b2056e ¤   ¤   if ((bpl)==68) ·········································\
a843ff ¤   ¤   { ······················································\
e534c0 ¤   ¤   ¤   (b64) = newline_copy(b64); ·························\
acf452 ¤   ¤   ¤   (bpl) = 0; ·········································\
7f6c61 ¤   ¤   } ······················································\
606d5a ¤   ¤   (bpl) += 4; ············································\
fd47ca ¤   ¤   *(b64)++ = vector[Top6((bin)[0])]; ·····················\
b65159 ¤   ¤   *(b64)++ = vector[Bot2((bin)[0])<<4 | Top4((bin)[1])]; ·\
d84835 ¤   ¤   *(b64)++ = vector[Bot4((bin)[1])<<2 | Top2((bin)[2])]; ·\
d3c187 ¤   ¤   *(b64)++ = vector[Bot6((bin)[2])]; ·····················\
d358a3 ¤   } ··························································\
470755 ¤   while (0)
4eaf5a
f9e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
fcaf5a
2138e5 /*
d9f752 ·* ·Convert binary data to base64
14775e ·*
346a22 ·* ·Args:
4cd736 ·* ··binPtr ····[IN] ····the binary data (or NULL to close encoder)
05229f ·* ··binLen ····[IN] ····the length of the binary data
86967e ·* ··sixFourPtr [IN] ····pointer to buffer for the base64 data
a8322c ·* ··e64 ·······[IN/OUT] state; caller must preserve
8e775e ·*
a94185 ·* ·Returns: The length of the base64 data
16495d ·*/
d97f3a long Encode64(
a366b0 ¤   char *binPtr,
b2f6b7 ¤   long binLen,
8a008b ¤   char *sixFourPtr,
7ee4f5 ¤   Enc64Ptr e64)
54bb36 {
c6fec4 ¤   char *binSpot;¤ ¤   ¤   ¤   ¤   /* the byte currently being decoded */
9b2695 ¤   char *sixFourSpot = sixFourPtr;¤/* the spot to which to copy the encoded·
39bf8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   /* chars */
--73b1 00094615fa5401101f7 Page 3 of ENCODING.CPP
e81ada ¤   short bpl;
853954 ¤   char *end;¤ ¤   ¤   ¤   ¤   ¤   /* end of integral decoding */
bfaf5a
eb26cf ¤   bpl = e64->bytesOnLine;¤/* in inner loop; want local copy */
ea67c5 ¤
189b20 ¤   if (binLen)
67c7a1 ¤   {
fa1b52 ¤   ¤
c11b17 ¤   ¤   /*
368768 ¤   ¤   ·* do we have any stuff left from last time?
669de3 ¤   ¤   ·*/
4e5d9e ¤   ¤   if (e64->partialCount)
bd5b34 ¤   ¤   {
16f4d1 ¤   ¤   ¤   short needMore = 3 - e64->partialCount;
a2fa22 ¤   ¤   ¤   if (binLen >= needMore)
e7f776 ¤   ¤   ¤   {
95980e ¤   ¤   ¤   ¤   /*
2a3f46 ¤   ¤   ¤   ¤   ·* we can encode some bytes
111020 ¤   ¤   ¤   ¤   ·*/
166338 ¤   ¤   ¤   ¤   memcpy(e64->partial+e64->partialCount,binPtr,needMore);
50ab5e ¤   ¤   ¤   ¤   binLen -= needMore;
3f8aa2 ¤   ¤   ¤   ¤   binPtr += needMore;
fc41f4 ¤   ¤   ¤   ¤   EncodeThree64(e64->partial,sixFourSpot,bpl);
8d3e04 ¤   ¤   ¤   ¤   e64->partialCount = 0;
1ba3a6 ¤   ¤   ¤   }
aa7aad ¤   ¤   ¤   /*
8f4cef ¤   ¤   ¤   ·* if we don't have enough bytes to complete the leftovers, we
1a0ce1 ¤   ¤   ¤   ·* obviously don't have 3 bytes. ·So the encoding code will fall
75cac3 ¤   ¤   ¤   ·* through to the point where we copy the leftovers to the partial
a05f55 ¤   ¤   ¤   ·* buffer. ·As long as we're careful to append and not copy·
f76069 ¤   ¤   ¤   ·* blindly, we'll be fine.
7c8753 ¤   ¤   ¤   ·*/
bd0fe4 ¤   ¤   }
021b52 ¤   ¤
4e1b17 ¤   ¤   /*
a44dbf ¤   ¤   ·* we encode the integral multiples of three
a99de3 ¤   ¤   ·*/
5a006b ¤   ¤   end = binPtr + 3*(binLen/3);
eabf33 ¤   ¤   for (binSpot = binPtr; binSpot < end; binSpot += 3)
595b34 ¤   ¤   {
c05f6d ¤   ¤   ¤   EncodeThree64(binSpot,sixFourSpot,bpl);
540f9b ¤   ¤   ¤   /* *sixFourLen = sixFourSpot - sixFourPtr; */
ce0fe4 ¤   ¤   }
e61b52 ¤   ¤
581b17 ¤   ¤   /*
e1451c ¤   ¤   ·* now, copy the leftovers to the partial buffer
889de3 ¤   ¤   ·*/
412cdd ¤   ¤   binLen = binLen % 3;
5c0c53 ¤   ¤   if (binLen)
4d5b34 ¤   ¤   {
d22c9b ¤   ¤   ¤   memcpy(e64->partial+e64->partialCount,binSpot,binLen);
c76fc8 ¤   ¤   ¤   e64->partialCount += (short)binLen;
c40fe4 ¤   ¤   }
7c9371 ¤   }
4c0e24 ¤   else
76c7a1 ¤   {
9e1b17 ¤   ¤   /*
440e92 ¤   ¤   ·* we've been called to cleanup the leftovers
e69de3 ¤   ¤   ·*/
fa5d9e ¤   ¤   if (e64->partialCount)
ae5b34 ¤   ¤   {
fd9bb3 ¤   ¤   ¤   if (e64->partialCount<2) e64->partial[1] = 0;
fa35e4 ¤   ¤   ¤   e64->partial[2] = 0;
d76741 ¤   ¤   ¤   EncodeThree64(e64->partial,sixFourSpot,bpl);
dd87c7 ¤   ¤   ¤
f27aad ¤   ¤   ¤   /*
346440 ¤   ¤   ¤   ·* now, replace the unneeded bytes with ='s
ef8753 ¤   ¤   ¤   ·*/
c4f49d ¤   ¤   ¤   sixFourSpot[-1] = '=';
14ed18 ¤   ¤   ¤   if (e64->partialCount==1) sixFourSpot[-2] = '=';
c30fe4 ¤   ¤   }
949371 ¤   }
--51d3 000be6bef16401101f7 Page 4 of ENCODING.CPP
e0af5a
547d89 ¤   e64->bytesOnLine = bpl;¤/* copy back to state buffer */
efaf5a
b424b8 ¤   return (sixFourSpot - sixFourPtr);
b5efe6 }
3caf5a
1de6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
9eaf5a
e138e5 /*
1f3695 ·* ·Convert base64 data to binary
67775e ·*
3c6a22 ·* ·Args:
e0612c ·* ··sixFourPtr [IN] ····the base64 data (or nil to close decoder)
c600b5 ·* ··sixFourLen [IN] ····the length of the base64 data
73bb0a ·* ··binPtr ····[IN] ····pointer to buffer to hold binary data
7ac42f ·* ··d64 ·······[IN/OUT] pointer to decoder state; caller must preserve
f701f8 ·* ··decErrCnt ·[OUT] ···the number of decoding errors found
67775e ·*
917f6c ·* ·Returns: The length of the binary data
2f495d ·*/
9afad0 long Decode64(
39008b ¤   char *sixFourPtr,
0583a0 ¤   long sixFourLen,
d866b0 ¤   char *binPtr,
9ccc7c ¤   Dec64Ptr d64,
f02eab ¤   long *decErrCnt)
b3bb36 {
8a11da ¤   short ¤ decode;¤¤   ¤   ¤   ¤   /* the decoded short */
eb7772 ¤   unsigned char ¤ ¤   c;¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¶
06c0be ¤   ¤   /* the decoded byte */
6809a7 ¤   /* we separate the short & the byte to the compiler can worry about·
2a0183 ¤   ¤   byteorder */
1f1650 ¤   char *end = sixFourPtr + sixFourLen;/* stop decoding here */
ca9108 ¤   char *binSpot = binPtr;¤¤   ¤   ¤   /* current output character */
0d8df9 ¤   short ¤ decoderState;¤  ¤   /* which of 4 bytes are we seeing now? */
5d7042 ¤   long ¤  ¤   invalCount;¤¤   /* how many bad chars found this time around?*/
3ea8d3 ¤   long ¤  ¤   padCount;¤  ¤   /* how many pad chars found so far? */
489e84 ¤   unsigned char ¤ ¤   partial;/* partially decoded byte from/for last/
a1da01 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   next time */
49c731 ¤   short wasCR;
a0f5ce ¤   char *sixFourStartPtr;
2a67c5 ¤
fed8af ¤   /*
971817 ¤   ·* fetch state from caller's buffer
c1a4e3 ¤   ·*/
444201 ¤   decoderState = d64->decoderState;
123dd3 ¤   invalCount = 0;¤/* we'll add the invalCount to the buffer later */
56f97a ¤   padCount = d64->padCount;
39078b ¤   partial = d64->partial;
307729 ¤   wasCR = d64->wasCR;
f267c5 ¤
c3aa43 ¤   if (sixFourLen)
2ec7a1 ¤   {
505799 ¤   ¤   sixFourStartPtr = sixFourPtr;
66f0bd ¤   ¤   for (;sixFourPtr<end;sixFourPtr++)
c15b34 ¤   ¤   {
0d5e84 ¤   ¤   ¤   switch(decode=g64DecodeArr[*sixFourPtr])
23f776 ¤   ¤   ¤   {
c95987 ¤   ¤   ¤   ¤   case SKIP: break;¤  ¤   ¤   ¤   /* skip whitespace */
366096 ¤   ¤   ¤   ¤   case FAIL: invalCount++; break;¤/* count invalid characters */
28fe30 ¤   ¤   ¤   ¤   case PAD: padCount++; break;¤   /* count pad characters */
f06ab9 ¤   ¤   ¤   ¤   default:
b5a3e7 ¤   ¤   ¤   ¤   ¤   /*
bc0f5c ¤   ¤   ¤   ¤   ¤   ·* found a non-pad character, so if we had previously·
94378a ¤   ¤   ¤   ¤   ¤   ·* found a pad, that pad was an error
5eec4b ¤   ¤   ¤   ¤   ·¤  */
4d7185 ¤   ¤   ¤   ¤   ¤   if (padCount) {invalCount+=padCount;padCount=0;}
51ae30 ¤   ¤   ¤   ¤   ¤
26a3e7 ¤   ¤   ¤   ¤   ¤   /*
27c187 ¤   ¤   ¤   ¤   ¤   ·* extract the right bits
9d6ad4 ¤   ¤   ¤   ¤   ¤   ·*/
beb1c6 ¤   ¤   ¤   ¤   ¤   c = (char) decode;
--2f47 000cff231b5401101f7 Page 5 of ENCODING.CPP
016a1a ¤   ¤   ¤   ¤   ¤   switch (decoderState)
e94859 ¤   ¤   ¤   ¤   ¤   {
475463 ¤   ¤   ¤   ¤   ¤   ¤   case 0:
9096b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   partial = c<<2;
3f3f27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState++;
858c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
2f0ebf ¤   ¤   ¤   ¤   ¤   ¤   case 1:
e8c42a ¤   ¤   ¤   ¤   ¤   ¤   ¤   *binSpot++ = partial|Top4(c);
da4730 ¤   ¤   ¤   ¤   ¤   ¤   ¤   partial = Bot4(c)<<4;
a33f27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState++;
098c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
d2e1db ¤   ¤   ¤   ¤   ¤   ¤   case 2:
bfcc7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   *binSpot++ = partial|Top6(c);
785697 ¤   ¤   ¤   ¤   ¤   ¤   ¤   partial = Bot2(c)<<6;
fe3f27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState++;
958c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
96bb07 ¤   ¤   ¤   ¤   ¤   ¤   case 3:
8a1496 ¤   ¤   ¤   ¤   ¤   ¤   ¤   *binSpot++ = partial|c;
2b1b2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   decoderState=0;
028c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
0c0a52 ¤   ¤   ¤   ¤   ¤   } /* switch decoderState */
c542e8 ¤   ¤   ¤   } /* switch decode */
b432e7 ¤   ¤   } /* for sixFourPtr */
fad0ed ¤   } /* if sixFourLen */
4e0e24 ¤   else
b5c7a1 ¤   {
1a1b17 ¤   ¤   /*
b0e193 ¤   ¤   ·* all done. ·Did all end up evenly?
2b9de3 ¤   ¤   ·*/
f88e8f ¤   ¤   switch (decoderState)
265b34 ¤   ¤   {
7575ac ¤   ¤   ¤   case 0:
e9c4a4 ¤   ¤   ¤   ¤   invalCount += padCount;/*¤  came out evenly,·
d26c3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   so should be no pads */
faf622 ¤   ¤   ¤   ¤   break;
542f70 ¤   ¤   ¤   case 1:
81c0dc ¤   ¤   ¤   ¤   invalCount++;¤  ¤   ¤   ¤   /* data missing */
5db3d2 ¤   ¤   ¤   ¤   invalCount += padCount;¤¤   /* since data missing;·
d9f49b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   should be no pads */
fcf622 ¤   ¤   ¤   ¤   break;
8cc014 ¤   ¤   ¤   case 2:
c2c4ab ¤   ¤   ¤   ¤   invalCount += ABS(padCount-2);¤ /* need exactly 2 pads */
f0f622 ¤   ¤   ¤   ¤   break;
af9ac8 ¤   ¤   ¤   case 3:
e18b4c ¤   ¤   ¤   ¤   invalCount += ABS(padCount-1);¤ /* need exactly 1 pad */
9ef622 ¤   ¤   ¤   ¤   break;
d50fe4 ¤   ¤   }
ec9371 ¤   }
5967c5 ¤
fbd8af ¤   /*
7f34d3 ¤   ·* save state in caller's buffer
d2a4e3 ¤   ·*/
76bf77 ¤   d64->decoderState = decoderState;
6a3bca ¤   d64->invalCount += invalCount;
f4d820 ¤   d64->padCount = padCount;
30d1c4 ¤   d64->partial = partial;
61f1f6 ¤   d64->wasCR = wasCR;
99af5a
6e4fd1 ¤   *decErrCnt = invalCount;
c8af5a
d54ca1 ¤   return (binSpot - binPtr);
b8efe6 }
6caf5a
c4c067 /*****************************************************************************/
78505f /* ·····················Q U O T E D - P R I N T A B L E ·····················*/
c7c067 /*****************************************************************************/
3caf5a
477890 /* ------------------------------------------------------------------------- */
edecde /* NOTE: To handle BINARY data, you must always quote newline characters, ···*/
1d620c /* ··this implementation assumes TEXT data and thus does not encode newlines */
487890 /* ------------------------------------------------------------------------- */
cfaf5a
--e15a 0008c125c43401101f7 Page 6 of ENCODING.CPP
bc38e5 /*
6821a9 ·* ·Convert binary data to quoted-printable
c0775e ·*
d26a22 ·* ·Args:
91d1e8 ·* ··pBin ····[IN] ···the binary data (or NULL to close the encoder)
5985ec ·* ··nLen ····[IN] ···the length of the binary data (or 0 to close the encoder)
02c967 ·* ··pQP ·····[IN] ···pointer to buffer for the quoted-printable data
2facf0 ·* ··eQPstate [IN/OUT] state; caller must preserve
bd775e ·*
2f5abf ·* ·Returns: The length of the quoted-printable data
13495d ·*/
01d7d3 long EncodeQP(
1da8e1 ¤   char *pBin,
90d5f6 ¤   long nLen,
a94e49 ¤   char *pQP,
7e5185 ¤   EncQPPtr eQPstate)
a4bb36 {
08c479 ¤   /* These characters are legal to leave UNQUOTED, everything else must be·
ae4535 ¤   ¤   quoted */
7090d7 ¤   const char *gQPEncodeChars
f00dd6 ¤   = "\t\n\r %&'()*+,-./0123456789:;<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghij"
56a099 ¤   "klmnopqrstuvwxyz";
b3af5a
501a88 ¤   /* The hex digits -- in order */
b91818 ¤   const char *pHexArr = "0123456789ABCDEF";
bb1826 ¤   const char *pQPStart = pQP; /* Remember the start pos */
b9ebe2 ¤   char *pEnd, ch, cLastChar;
2aa283 ¤   int nLineChars, bEncode;
27af5a
1ef3b5 ¤   /* Check if this call is to close the encoding */
5b18c3 ¤   if ((pBin == NULL) || (nLen < 1))
29c7a1 ¤   {
24ab04 ¤   ¤   /* If there is anything on the current line, cap it with an equal */
9e1911 ¤   ¤   /* This avoids having trailing whitespace that would be ignored */
2ddc03 ¤   ¤   /* Newline is added for good measure, because we assume TEXT, this */
c436dc ¤   ¤   /* ·shouldn't be a problem */
9dabc3 ¤   ¤   if ((eQPstate->nCurLineLen) > 0)
695b34 ¤   ¤   {
13f9d4 ¤   ¤   ¤   *pQP++ = '=';
0b1b89 ¤   ¤   ¤   pQP = newline_copy(pQP);
14af5a
d5d892 ¤   ¤   ¤   eQPstate->nCurLineLen = 0;
0cf898 ¤   ¤   ¤   return (pQP - pQPStart);
aa0fe4 ¤   ¤   }
a2af5a
2cf109 ¤   ¤   return (0);
ae9371 ¤   }
69af5a
a36ff4 ¤   /* Restore the state from the caller data */
53ba5d ¤   nLineChars = eQPstate->nCurLineLen;
49846a ¤   cLastChar = eQPstate->cLastChar;
d9af5a
5c03f0 ¤   /* Loop through the binary data */
4b8d48 ¤   for (pEnd = pBin + nLen; pBin < pEnd; pBin++)
3cc7a1 ¤   {
95fdd7 ¤   ¤   /* Check if the binary character must be encoded */
28fe61 ¤   ¤   bEncode = (strchr(gQPEncodeChars, (ch = *pBin)) ? 0 : 1);
09af5a
796451 ¤   ¤   /* Will this action put us past the 76 char limit? */
d42427 ¤   ¤   if ((nLineChars + (bEncode ? 3 : 1)) > 76)
175b34 ¤   ¤   {
7cc391 ¤   ¤   ¤   /* Cap the line, and add a newline */
77f9d4 ¤   ¤   ¤   *pQP++ = '=';
fc1b89 ¤   ¤   ¤   pQP = newline_copy(pQP);
fdaf5a
6051a3 ¤   ¤   ¤   nLineChars = 0; /* Starting new line */
a40fe4 ¤   ¤   }
93af5a
d6eff4 ¤   ¤   if (bEncode) /* Encode the character using hex (ie. "A" -> "=41") */
2a5b34 ¤   ¤   {
52f9d4 ¤   ¤   ¤   *pQP++ = '=';
8c9385 ¤   ¤   ¤   *pQP++ = pHexArr[(ch>>4) & 0xF];
--de56 0005cb73865401101f7 Page 7 of ENCODING.CPP
078279 ¤   ¤   ¤   *pQP++ = pHexArr[ch & 0xF];
8487c7 ¤   ¤   ¤
b368cf ¤   ¤   ¤   nLineChars += 3;
cd0fe4 ¤   ¤   }
306a6f ¤   ¤   else /* No encoding needed, just copy character over */
965b34 ¤   ¤   {
a0e92a ¤   ¤   ¤   *pQP++ = ch;
5baf5a
0c2d29 ¤   ¤   ¤   /* If we copied a newline, then we need to reset the line char
42c661 ¤   ¤   ¤   count */
2c983a ¤   ¤   ¤   if (newline_test(cLastChar, ch))
9f9026 ¤   ¤   ¤   ¤   nLineChars = 0;
00bb8c ¤   ¤   ¤   else
c4f2b9 ¤   ¤   ¤   ¤   nLineChars++;
6c0fe4 ¤   ¤   }
9aaf5a
838e0c ¤   ¤   /* Keep track of the last character */
e23545 ¤   ¤   cLastChar = ch;
799371 ¤   }
85af5a
b4f3ae ¤   /* Save the state */
29cc0c ¤   eQPstate->nCurLineLen = nLineChars;
bff971 ¤   eQPstate->cLastChar = cLastChar;
2faf5a
25eba4 ¤   /* Return the number of characters we but in the buffer */
aa7ea6 ¤   return (pQP - pQPStart);
38efe6 }
66af5a
57e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
e5af5a
fc38e5 /*
002a8e ·* ·Convert quoted printable data to binary
1c775e ·*
ff6a22 ·* ·Args:
9b4336 ·* ··pQP ······[IN] ··the quoted printable data (or NULL to close the decoder)
484391 ·* ··nLen ·····[IN] ··the length of the quoted printable data·
10313d ¤   ¤   ¤   ¤   ¤   ¤   (or 0 to close the decoder)
64bf10 ·* ··pBin ·····[IN] ··pointer to buffer to hold binary data
fa8301 ·* ··dQPstate ·[IN/OUT] pointer to decoder state; caller must preserve
915838 ·* ··decErrCnt [OUT] ···the number of decoding errors found
bc775e ·*
e07f6c ·* ·Returns: The length of the binary data
ca495d ·*/
ae5239 long DecodeQP(
ad4e49 ¤   char *pQP,
eed5f6 ¤   long nLen,
f1a8e1 ¤   char *pBin,
d86e24 ¤   DecQPPtr dQPstate,
582eab ¤   long *decErrCnt)
2fbb36 {
ba4f10 ¤   const char *pBinStart = pBin;
305350 ¤   char *pEnd, ch;
2e67c5 ¤
ae05da ¤   /* Restore the state from the caller */
1492ca ¤   QPStates CurState = dQPstate->CurState;
f82e28 ¤   char cLastChar = dQPstate->cLastChar;
5daf5a
0c34f9 ¤   /* Check if this call is to close the decoding */
1b67ae ¤   if ((pQP == NULL) || (nLen < 1))
83c7a1 ¤   {
f73ee9 ¤   ¤   /* If the state is in the middle of doing something, then error */
bea4ee ¤   ¤   if ((CurState == qpEqual) || (CurState == qpEncoded))
185b34 ¤   ¤   {
c3d216 ¤   ¤   ¤   (*decErrCnt)++;
aaf1a2 ¤   ¤   ¤   CurState = qpNormal;
230fe4 ¤   ¤   }
21af5a
f5f109 ¤   ¤   return (0);
b39371 ¤   }
0baf5a
cbfdc3 ¤   /* Loop through the QP data */
5c36f9 ¤   for (pEnd = pQP + nLen; pQP < pEnd; pQP++)
--67a3 00082db26ca401101f7 Page 8 of ENCODING.CPP
f7c7a1 ¤   {
1b5f26 ¤   ¤   /* Get the current character */
890bae ¤   ¤   ch = *pQP;
6baf5a
78d611 ¤   ¤   /* What state are we in? */
130315 ¤   ¤   switch (CurState)
ce5b34 ¤   ¤   {
4f77f4 ¤   ¤   ¤   case qpNormal: /* Normal: copy everything until an 'equal' */
6d475c ¤   ¤   ¤   ¤   if (ch == '=')
1115a6 ¤   ¤   ¤   ¤   ¤   CurState = qpEqual; /* Found an 'equal' char */
f6fa07 ¤   ¤   ¤   ¤   else
712e36 ¤   ¤   ¤   ¤   ¤   *pBin++ = ch;
40cdcb ¤   ¤   ¤   break;
efae30 ¤   ¤   ¤   ¤   ¤
76204c ¤   ¤   ¤   case qpEqual: /* qpEqual: Last char was an equal */
44f4a4 ¤   ¤   ¤   ¤   if (isxdigit(ch)) ····················/* This char should be a·
64fd9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hex digit */
b9497f ¤   ¤   ¤   ¤   ¤   CurState = qpEncoded;
47fac6 ¤   ¤   ¤   ¤   else if (newline_test(cLastChar, ch)) /* Or it could be a·
259b42 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   newline */
0bc927 ¤   ¤   ¤   ¤   ¤   CurState = qpNormal;
0a1e13 ¤   ¤   ¤   ¤   else if (isspace(ch)) ················/* Or some whitespace
8ca6ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   before the newline */
d8f287 ¤   ¤   ¤   ¤   ¤   CurState = qpTrailingWhitespace;
cafa07 ¤   ¤   ¤   ¤   else
e00956 ¤   ¤   ¤   ¤   ¤   CurState = qpError; ··············/* Otherwise, an error */
20cdcb ¤   ¤   ¤   break;
e52b85 ¤   ¤   ¤   ¤
97e369 ¤   ¤   ¤   case qpEncoded: /* qpEncoded: Last char was the first·
709c00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hex digit of an encoding */
4be03a ¤   ¤   ¤   ¤   if ((isxdigit(ch)) && (isxdigit(cLastChar)))
7372c3 ¤   ¤   ¤   ¤   {
62ecd5 ¤   ¤   ¤   ¤   ¤   int left = hex2dec(cLastChar);
720882 ¤   ¤   ¤   ¤   ¤   int right = hex2dec(ch);
1d1f27 ¤   ¤   ¤   ¤   ¤   int leftshift = left << 4;
f4ad9f ¤   ¤   ¤   ¤   ¤   int final = leftshift | right;
abc094 ¤   ¤   ¤   ¤   ¤   /* Decode the hex digits into a character */
ff4aa5 ¤   ¤   ¤   ¤   ¤   *pBin++ = final;
fdc927 ¤   ¤   ¤   ¤   ¤   CurState = qpNormal;
bf2613 ¤   ¤   ¤   ¤   }
52fa07 ¤   ¤   ¤   ¤   else
524be4 ¤   ¤   ¤   ¤   ¤   CurState = qpError; /* This char is not a hex digit:·
450d4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   an error */
f1cdcb ¤   ¤   ¤   break;
37af5a
52a2c4 ¤   ¤   ¤   case qpTrailingWhitespace: /* qpTrailingWhitespace: whitespace·
d37b75 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   is allowed after */
2ccc91 ¤   ¤   ¤   ¤   ·······················/* ·an equals and before the newline */
e7caa7 ¤   ¤   ¤   ¤   if (newline_test(cLastChar, ch))
b1a7e7 ¤   ¤   ¤   ¤   ¤   CurState = qpNormal; /* When we find the newline,·
645df0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   don't copy it */
74dbb8 ¤   ¤   ¤   ¤   else if (!isspace(ch))
ee4199 ¤   ¤   ¤   ¤   ¤   CurState = qpError; /* If we get to some char BEFORE
3bc7cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   a newline: an error */
afcdcb ¤   ¤   ¤   break;
d50fe4 ¤   ¤   }
a0af5a
69592b ¤   ¤   if (CurState == qpError) /* Count the errors, reset to normal·
858cd4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   state (keep trying) */
0f5b34 ¤   ¤   {
b9d216 ¤   ¤   ¤   (*decErrCnt)++;
a4f1a2 ¤   ¤   ¤   CurState = qpNormal;
370fe4 ¤   ¤   }
c8af5a
2f8e0c ¤   ¤   /* Keep track of the last character */
3c3545 ¤   ¤   cLastChar = ch;
eb9371 ¤   }
5faf5a
8d5d67 ¤   /* Save the state for next time */
b08261 ¤   dQPstate->CurState = CurState;
d3b912 ¤   dQPstate->cLastChar = cLastChar;
82af5a
--69b1 0003be584de401101f7 Page 9 of ENCODING.CPP
87eba4 ¤   /* Return the number of characters we but in the buffer */
72c084 ¤   return (pBin - pBinStart);
b7efe6 }
4eaf5a
fee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
0faf5a
0238e5 /*
02a1b7 ·* ·Parse Content-Transer-Encoding header line
93775e ·*
606a22 ·* ·Args:
12860b ·* ··src [IN] Valid Transfer-Encoding header.
11775e ·*
30b353 ·* ·Returns: enumerated integer 'TrEncType' type specifying CTE.
15495d ·*/
1151d6 TrEncType rfc822_parse_cte(const char *src)
9fbb36 {
b1e05b ¤   const char *kPrefixStr = "Content-Transfer-Encoding:";
de1c27 ¤   const unsigned int kPrefixStrLen = strlen(kPrefixStr);
8daf5a
c93d3a ¤   char *cp = (char *) src + kPrefixStrLen, *mechanism = NULL;
de4d2c ¤   TrEncType cte = CTE_Error;
7eaf5a
6c4eb8 ¤   // Check prefix
bd72d2 ¤   if (strnicmp(src, kPrefixStr, kPrefixStrLen) == 0)
4fc7a1 ¤   {
5200d1 ¤   ¤   // Get first token (skips whitespace/comments)
51c513 ¤   ¤   mechanism = rfc822_extract_token(&cp);
a7af5a
9aa983 ¤   ¤   // If we got something
ec4ac8 ¤   ¤   if ((mechanism) && (strlen(mechanism) > 0))
1f5b34 ¤   ¤   {
cb0cca ¤   ¤   ¤   if (stricmp(mechanism, "base64") == 0)
73f9a6 ¤   ¤   ¤   ¤   cte = CTE_Base64;
fd1c4a ¤   ¤   ¤   else if (stricmp(mechanism, "quoted-printable") == 0)
6a20ce ¤   ¤   ¤   ¤   cte = CTE_QP;
a0202c ¤   ¤   ¤   else if (stricmp(mechanism, "7bit") == 0)
06ad59 ¤   ¤   ¤   ¤   cte = CTE_7bit;
fd1507 ¤   ¤   ¤   else if (stricmp(mechanism, "8bit") == 0)
a290d0 ¤   ¤   ¤   ¤   cte = CTE_8bit;
f03ddf ¤   ¤   ¤   else if (stricmp(mechanism, "binary") == 0)
23e067 ¤   ¤   ¤   ¤   cte = CTE_Binary;
410fe4 ¤   ¤   }
76af5a
5de106 ¤   ¤   safefree(mechanism);
879371 ¤   }
b3af5a
6024d5 ¤   return (cte);
a2efe6 }
94af5a
44e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5faf5a
5d38e5 /*
2fa8b7 ·* ·Create Content-Transer-Encoding header line
b5775e ·*
cb322b ·* ·NOTE: The user of this function is responsible for freeing the
c7c8a5 ·* ·······returned string.
2c775e ·*
1b6a22 ·* ·Args:
016981 ·* ··mechanism [IN] Enumerated integer 'TrEncType' type specifying CTE.
80775e ·*
7381c9 ·* ·Returns: Content tranfer encoding header line string.
60495d ·*/
a8b631 char *rfc822_make_cte(TrEncType mechanism)
d6bb36 {
c0f526 ¤   const char *kPrefix = "Content-Transfer-Encoding: ";
5e2c83 ¤   char pBuf[40], *pCTE;
e8af5a
47dfbc ¤   switch (mechanism)
d4c7a1 ¤   {
c42c9f ¤   ¤   case CTE_Base64:¤   strcpy(pBuf, "base64");¤¤   ¤   ¤   break;
110af4 ¤   ¤   case CTE_QP:¤   ¤   strcpy(pBuf, "quoted-printable");¤  break;
3b0a84 ¤   ¤   case CTE_7bit:¤ ¤   strcpy(pBuf, "7bit");¤  ¤   ¤   ¤   break;
--5670 0000d892718401101f7 Page 10 of ENCODING.CPP
cd20ba ¤   ¤   case CTE_8bit:¤ ¤   strcpy(pBuf, "8bit");¤  ¤   ¤   ¤   break;
026038 ¤   ¤   case CTE_Binary:¤   strcpy(pBuf, "binary");¤¤   ¤   ¤   break;
09af5a
f39ae3 ¤   ¤   default:
e362c0 ¤   ¤   ¤   return (NULL);
de9371 ¤   }
26af5a
e52d4f ¤   pCTE = (char *) malloc(strlen(pBuf) + strlen(kPrefix) + 1);
c891b5 ¤   strcpy(pCTE, kPrefix);
e77f32 ¤   strcat(pCTE, pBuf);
bcaf5a
5ca6ea ¤   return (pCTE);
d6efe6 }
51af5a
a7e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
6aaf5a
6038e5 /*
03f7b2 ·* ·Finds and extracts the content transfer encoding header line from a full
172bdb ·* ·multi-lined header. All unfolding (removing newlines) is done before
ddc4e2 ·* ·header line is returned.
9f775e ·*
2f322b ·* ·NOTE: The user of this function is responsible for freeing the
5cc8a5 ·* ·······returned string.
f2775e ·*
6e6a22 ·* ·Args:
200990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
e3775e ·*
f7d4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
8a495d ·*/
272283 char *rfc822_extract_cte(const char *pFullHeader)
5cbb36 {
5b1665 ¤   return rfc822_extract_header(pFullHeader, "Content-Transfer-Encoding:");
e6efe6 }
1eaf5a
1960e8 /* ========================================================================== */
c5f935 /* ·····························LOCAL FUNCTIONS ······························*/
0660e8 /* ========================================================================== */
56af5a
fbfb1a /* ·NEWLINE STUFF: Used locally to copy and test for newlines ·*/
c05ab1 static const char gNewlineCh1 = '\r';
c47a4d static const char gNewlineCh2 = '\n';
78af5a
62e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
58af5a
8b9c08 /* Insert a newline, returning position after newline */
f48dff /* static */ char *newline_copy(char *dst)
1dbb36 {
e2817b ¤   *dst++ = gNewlineCh1;
316e1f ¤   *dst++ = gNewlineCh2;
15af5a
f69f8e ¤   return dst;
daefe6 }
3caf5a
d6e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
7eaf5a
d607f2 /* Check if these two characters represent a newline */
fff82c /* static */ int newline_test(const char prev, const char curr)
65bb36 {
9a9120 ¤   return ((prev == gNewlineCh1) && (curr == gNewlineCh2));
09efe6 }
2baf5a
a1e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
bfaf5a
105177 /* Convert a single HEX character-digit (0123456789ABCDEF) to the decimal */
66c724 /* value. ·NOTE: This function assumes the character is a valid hex digit */
5b6ce7 /* static */ int hex2dec(const char ch)
5bbb36 {
e78588 ¤   if (isdigit(ch))
ec42a7 ¤   ¤   return (ch -'0');
edaf5a
431aae ¤   return ((toupper(ch) - 'A') + 10);
0defe6 }
--6459 001e0d5e91e401101f7 Page 11 of ENCODING.CPP
e0af5a
--48ae 0000f8c59ab401101f8 Page 1 of ENCODING.H
bc38e5 /*
288ba0 ·* ·Functions to encode and decode using BASE64 or Quoted-Printable
aab5e8 ·* ·Also a transfer-encoding header line parser
e1775e ·*
5eff93 ·* ·Filename: encoding.h
5f775e ·*
2aa235 ·* ·Last Edited: September 24, 1996
56775e ·*
03005b ·* ·Author: Scott Manjourides
d3775e ·*
24cbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
4aea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
1b775e ·*
f3c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
95775e ·*
f9495d ·*/
94af5a
31c2f3 #ifndef EMS_ENCODING_H
579502 #define EMS_ENCODING_H
52af5a
6838e5 /*
e5608c ·* state buffer for base64 encoding. Initialize all values to zero.
a4495d ·*/
dbf0f7 typedef struct {
969664 ¤   unsigned char partial[4];
8d0bae ¤   short partialCount;
f1d048 ¤   short bytesOnLine;
ef01d1 } Enc64, *Enc64Ptr;
9aaf5a
e438e5 /*
b19dc5 ·* state buffer for base64 decoding. Initialize all values to zero.
f9495d ·*/
4ff0f7 typedef struct {
125627 ¤   short decoderState;¤¤   /* which of 4 bytes are we seeing now? */
5b6b4a ¤   long invalCount;¤   ¤   /* how many bad chars found so far? */
148cce ¤   long padCount;¤ ¤   ¤   /* how many pad chars found so far? */
889917 ¤   unsigned char partial;¤ /* partially decoded byte from/for last
70da01 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   next time */
168a0b ¤   short wasCR;¤   ¤   ¤   /* was the last character a carriage return? */
b3ccb5 } Dec64, *Dec64Ptr;
52af5a
f938e5 /*
d80435 ·* used internally to track parsing state
c1495d ·*/
b6ed84 typedef enum {
7ab952 ¤   qpNormal,
dfee23 ¤   qpEqual,
11bc2c ¤   qpEncoded,
ff3baf ¤   qpTrailingWhitespace,
b47430 ¤   qpError
c0a3f1 } QPStates;
09af5a
a338e5 /*
112e65 ·* state buffer for QP encoding. Initialize all values to zero.
f2495d ·*/
f1f0f7 typedef struct {
3d6ab0 ¤   int nCurLineLen; /* Number of characters outputed to current line */
04ec41 ¤   char cLastChar; ·/* Last character read in */
17c694 } EncQP, *EncQPPtr;
22af5a
4138e5 /*
597701 ·* state buffer for QP decoding. Initialize CurState to qpNormal.
63495d ·*/
e3f0f7 typedef struct {
9eb5da ¤   QPStates CurState;
6aa22f ¤   char cLastChar;
ba0bf0 } DecQP, *DecQPPtr;
17af5a
8c38e5 /*
8d1b8c ·* Valid return values for rfc822_parse_cte which specify the trasnfer
132cc6 ·* encoding found in the parsed header line
0f495d ·*/
--58ff 00046d18c46401101f8 Page 2 of ENCODING.H
c4ed84 typedef enum {
16b8c4 ¤   CTE_Error,
c0b60f ¤   CTE_Base64,
43add7 ¤   CTE_QP,
f4fc24 ¤   CTE_7bit,
20c1ad ¤   CTE_8bit,
2fafce ¤   CTE_Binary,
aed77a ¤   CTE_NONE
60f804 } TrEncType;
7eaf5a
268017 /*************************************************************************/
071e20 /* ·······························B A S E 6 4 ···························*/
aa8017 /*************************************************************************/
a8af5a
2138e5 /*
3bf752 ·* ·Convert binary data to base64
31775e ·*
9a6a22 ·* ·Args:
4ed736 ·* ··binPtr ····[IN] ····the binary data (or NULL to close encoder)
ad229f ·* ··binLen ····[IN] ····the length of the binary data
dc967e ·* ··sixFourPtr [IN] ····pointer to buffer for the base64 data
1d322c ·* ··e64 ·······[IN/OUT] state; caller must preserve
42775e ·*
bb4185 ·* ·Returns: The length of the base64 data
2e495d ·*/
8c0c3d long Encode64(char *bin, long len, char *sixFour, Enc64Ptr e64);
13af5a
b138e5 /*
e83695 ·* ·Convert base64 data to binary
da775e ·*
1d6a22 ·* ·Args:
2b612c ·* ··sixFourPtr [IN] ····the base64 data (or nil to close decoder)
d900b5 ·* ··sixFourLen [IN] ····the length of the base64 data
d2bb0a ·* ··binPtr ····[IN] ····pointer to buffer to hold binary data
65c42f ·* ··d64 ·······[IN/OUT] pointer to decoder state; caller must preserve
d901f8 ·* ··decErrCnt ·[OUT] ···the number of decoding errors found
da775e ·*
aa7f6c ·* ·Returns: The length of the binary data
dd495d ·*/
935662 long Decode64(char *sixFour, long sixFourLen, char *bin, Dec64Ptr d64,·
5bf3d4 ¤   ¤   ¤   ··long *decErrCnt);
11af5a
71cbf5 /*******************************************************************/
531c97 /* ·····················Q U O T E D - P R I N T A B L E ·············*/
41214a /***************************************************************/
cdaf5a
f35c14 /* ------------------------------------------------------------------ */
086f67 /* NOTE: To handle BINARY data, you must always quote newline characters, */
e4b345 /* ··this implementation assumes TEXT data and thus does not encode
53c30a ¤   newlines */
867ae9 /* ----------------------------------------------------------- */
d0af5a
d338e5 /*
e321a9 ·* ·Convert binary data to quoted-printable
89775e ·*
8c6a22 ·* ·Args:
90083e ·* ··pBin ····[IN] ····the binary data (or NULL to close the encoder)
2c6cfa ·* ··nLen ····[IN] ····the length of the binary data (or 0 to close·
fac2fa ·the encoder)
6777a2 ·* ··pQP ·····[IN] ····pointer to buffer for the quoted-printable data
a0acf0 ·* ··eQPstate [IN/OUT] state; caller must preserve
ce775e ·*
085abf ·* ·Returns: The length of the quoted-printable data
ae495d ·*/
db27ab long EncodeQP(char *bin, long len, char *qp, EncQPPtr eQP);
e1af5a
b938e5 /*
222a8e ·* ·Convert quoted printable data to binary
71775e ·*
da6a22 ·* ·Args:
204fbd ·* ··pQP ······[IN] ····the quoted printable data (or NULL to close·
46286b ·the decoder)
--c2b6 001e8fc0c34401101f8 Page 3 of ENCODING.H
5a049e ·* ··nLen ·····[IN] ····the length of the quoted printable data (or 0·
88884d ·to close the decoder)
832c5b ·* ··pBin ·····[IN] ····pointer to buffer to hold binary data
fa8301 ·* ··dQPstate ·[IN/OUT] pointer to decoder state; caller must preserve
c85838 ·* ··decErrCnt [OUT] ···the number of decoding errors found
7b775e ·*
147f6c ·* ·Returns: The length of the binary data
0a495d ·*/
63dc53 long DecodeQP(char *qp, long qpLen, char *bin, DecQPPtr dqp,·
e0f3d4 ¤   ¤   ¤   ··long *decErrCnt);
d6af5a
88afd2 /**************************************************************************/
6c66f9 /* ····························CTE ··P A R S E R ·························*/
3b8017 /*************************************************************************/
0faf5a
a838e5 /*
b7a1b7 ·* ·Parse Content-Transer-Encoding header line
a7775e ·*
3c6a22 ·* ·Args:
09860b ·* ··src [IN] Valid Transfer-Encoding header.
65775e ·*
3c1218 ·* ·Returns: enumerated integer 'TrEncType' type specifying CTE (see above).
79495d ·*/
24b3ca TrEncType rfc822_parse_cte(const char *src);
24af5a
7b38e5 /*
17a8b7 ·* ·Create Content-Transer-Encoding header line
0d775e ·*
3b322b ·* ·NOTE: The user of this function is responsible for freeing the
a8c8a5 ·* ·······returned string.
05775e ·*
c56a22 ·* ·Args:
4a6981 ·* ··mechanism [IN] Enumerated integer 'TrEncType' type specifying CTE.
e6775e ·*
6681c9 ·* ·Returns: Content tranfer encoding header line string.
bc495d ·*/
e2209c char *rfc822_make_cte(TrEncType mechanism);
c0af5a
b138e5 /*
cff7b2 ·* ·Finds and extracts the content transfer encoding header line from a full
362bdb ·* ·multi-lined header. All unfolding (removing newlines) is done before
9bc4e2 ·* ·header line is returned.
42775e ·*
d7322b ·* ·NOTE: The user of this function is responsible for freeing the
c7c8a5 ·* ·······returned string.
df775e ·*
886a22 ·* ·Args:
bd0990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
08775e ·*
0ad4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
cb495d ·*/
19b691 char *rfc822_extract_cte(const char *pFullHeader);
4daf5a
e8a763 #endif /* EMS_ENCODING_H */
--f871 0001d65964e401101f9 Page 1 of MIMETYPE.CPP
bc38e5 /*
8820c2 ·* ·Functions to manage emsMIMEtype structures
af12c6 ·* ·for use with Eudora EMS API under MS Windows.
34775e ·*
5d187c ·* ·Filename: mimetype.cpp
11775e ·*
f866d0 ·* ·Last Edited: Wednesday, April 2, 1996
12775e ·*
61005b ·* ·Author: Scott Manjourides
8f775e ·*
acea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
1f775e ·*
f1c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
57495d ·*/
30af5a
8c5655 #include <windows.h>
13324c #include <string.h>
a05e84 #include <malloc.h>
feaf5a
67fbd1 #include "ems-win.h"
82f10b #include "mimetype.h"
4d6bd2 #include "rfc822.h"
bdaf5a
4fc51a /* ========================================================================= */
17af5a
f00bf8 #define safefree(p) { if (p) { free(p); p = NULL; } }
deaf5a
6ec51a /* ========================================================================= */
0caf5a
0fb42b static void free_param_type(emsMIMEParamP paramPtr);
4aaf5a
bcc51a /* ========================================================================= */
e9af5a
2d38e5 /*
eb85ce ·* ·Create an emsMIMEtype structure to hold MIME information. Only the
4966cf ·* ·type and subtype are set here, use add_mime_parameter() to add
44f3dd ·* ·any name/value parameter pairs.
9b775e ·*
8cf79f ·* ·NOTE: All input strings are COPIED before permanent use. The user
b4eb22 ·* ·······of this function is responsible for calling free_mime_type()
9586a5 ·* ·······on returned structure.
b1775e ·*
fb6a22 ·* ·Args:
4d0bbc ·* ··mime_type ···[IN] the main MIME type: e.g., text, application, image
8aa734 ·* ··sub_type ····[IN] the sub type: e.g., plain, octet-stream, jpeg
771cc3 ·* ··mime_version [IN] the MIME verion number, if NULL will default to "1.0"
2f775e ·*
c004db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
c1495d ·*/
c80d89 emsMIMEtypeP make_mime_type(const char *mime_type, const char *sub_type,·
256224 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char *mime_version)
2abb36 {
aa0409 ¤   emsMIMEtypeP mimePtr = NULL;
a1af5a
1360cc ¤   mimePtr = (emsMIMEtypeP) malloc(sizeof(emsMIMEtype));
89af5a
98e242 ¤   if ((mimePtr) && (mime_type) && (sub_type))
7fc7a1 ¤   {
e3de88 ¤   ¤   mimePtr->type = strdup(mime_type);
077bec ¤   ¤   mimePtr->subType = strdup(sub_type);
04af5a
4b2aeb ¤   ¤   if (mime_version)
d20efd ¤   ¤   ¤   mimePtr->version = strdup(mime_version);
190e1d ¤   ¤   else
ecc264 ¤   ¤   ¤   mimePtr->version = strdup("1.0");
ceaf5a
696275 ¤   ¤   mimePtr->size = sizeof(emsMIMEtype);
34259e ¤   ¤   mimePtr->params = NULL;
1be12c ¤   ¤   mimePtr->contentDisp = NULL;
8a084e ¤   ¤   mimePtr->contentParams = NULL;
2daf5a
1d91c6 ¤   ¤   if ((mimePtr->type) && (mimePtr->subType) && (mimePtr->version))
--4cf6 000786753f5401101f9 Page 2 of MIMETYPE.CPP
e35b34 ¤   ¤   {
58d7ff ¤   ¤   ¤   return mimePtr;
1e0fe4 ¤   ¤   }
599371 ¤   }
82af5a
acf9d3 ¤   // If we get here then something went wrong
7d7650 ¤   // Do complete cleanup and return NULL
deaf5a
380dfb ¤   free_mime_type(mimePtr);
91af5a
32de0a ¤   return (NULL); // ERROR
06efe6 }
a7af5a
10e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
aaaf5a
6038e5 /*
9e605e ·* ·Create an emsMIMEtype structure to hold MIME information. Structure is
7965ea ·* ·initialized to values provided in RFC822 content-type header line. This
b24b95 ·* ·includes all parameter name-value pairs.
dda3b2 ·* ··
a8e058 ·* ·NOTE: The user of this function is responsible for calling
529141 ·* ·······free_mime_type() on returned structure.
15775e ·*
856a22 ·* ·Args:
0a671c ·* ··content_type [IN] The RFC822 content-type string to parse
38775e ·*
1904db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
c9495d ·*/
193ca1 emsMIMEtypeP parse_make_mime_type(const char *content_type)
d1bb36 {
32952d ¤   const char *kPrefixStr = "Content-Type:";
341c27 ¤   const unsigned int kPrefixStrLen = strlen(kPrefixStr);
80af5a
26ffaf ¤   if (strnicmp(content_type, kPrefixStr, kPrefixStrLen) != 0)
957ed2 ¤   ¤   return NULL;
18af5a
36cb1f ¤   char *cp = (char *) content_type + kPrefixStrLen;
ff870b ¤   char *mime_type = NULL, *mime_subtype = NULL;
feaf5a
593ca2 ¤   mime_type = rfc822_extract_token(&cp);
80af5a
22fd67 ¤   if ((strlen(mime_type) > 0) && ((*cp++) == '/'))
f9c7a1 ¤   {
4751ba ¤   ¤   mime_subtype = rfc822_extract_token(&cp);
efaf5a
9fb3d4 ¤   ¤   if (strlen(mime_subtype) > 0)
045b34 ¤   ¤   {
9058c0 ¤   ¤   ¤   // We have a type/subtype, so create emsMIMEtype structure
ab4053 ¤   ¤   ¤   emsMIMEtypeP mimePtr = make_mime_type(mime_type, mime_subtype,·
455152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
ddaf5a
910f39 ¤   ¤   ¤   safefree(mime_type);
c8e86e ¤   ¤   ¤   safefree(mime_subtype);
9faf5a
4aae58 ¤   ¤   ¤   if (mimePtr)
23f776 ¤   ¤   ¤   {
24e976 ¤   ¤   ¤   ¤   char *name = NULL, *value = NULL;
e2af5a
d9b788 ¤   ¤   ¤   ¤   do {
b4af5a
5f36a7 ¤   ¤   ¤   ¤   ¤   if ((*cp++) != ';') // Skip semi-colon
0b00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
5d2b85 ¤   ¤   ¤   ¤
242c86 ¤   ¤   ¤   ¤   ¤   if (!(name = rfc822_extract_token(&cp)))
d300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
3aaf5a
8edb5e ¤   ¤   ¤   ¤   ¤   if ((*cp++) != '=') // Skip equals
7a00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
d0af5a
4e3708 ¤   ¤   ¤   ¤   ¤   if (!(value = rfc822_extract_token(&cp)))
6000eb ¤   ¤   ¤   ¤   ¤   ¤   break;
78af5a
--bdb3 00071307b74401101f9 Page 3 of MIMETYPE.CPP
c16669 ¤   ¤   ¤   ¤   ¤   if ((strlen(name) > 0) && (strlen(value) > 0))
49b960 ¤   ¤   ¤   ¤   ¤   ¤   add_mime_parameter(mimePtr, name, value);
3baf5a
ab964f ¤   ¤   ¤   ¤   ¤   safefree(name);
53cd44 ¤   ¤   ¤   ¤   ¤   safefree(value);
988f3f ¤   ¤   ¤   ¤   } while (*cp);
67af5a
a81db3 ¤   ¤   ¤   ¤   safefree(name);
cff02c ¤   ¤   ¤   ¤   safefree(value);
76af5a
2c7aa1 ¤   ¤   ¤   ¤   return mimePtr;
fca3a6 ¤   ¤   ¤   }
3f0fe4 ¤   ¤   }
729371 ¤   }
aaaf5a
0ef9d3 ¤   // If we get here then something went wrong
4797ca ¤   // Do complete cleanup
caaf5a
b78032 ¤   safefree(mime_type);
b6cecc ¤   safefree(mime_subtype);
03af5a
cdde0a ¤   return (NULL); // ERROR
c1efe6 }
c5af5a
22e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
72af5a
4938e5 /*
79dd1d ·* ·Add a parameter to an existing emsMIMEtype structure. This structure
2465ad ·* ·should be created using make_mime_type().
93775e ·*
d997ac ·* ·NOTE: All input strings are COPIED before permanent use.
95775e ·*
d19648 ·* Args:
aed232 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be added too
0ef186 ·* ··name ···[IN] Name of the parameter
900476 ·* ··value ··[IN] Value of the parameter
7fa3b2 ·* ··
8c8b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
0b495d ·*/
1a922b int add_mime_parameter(emsMIMEtypeP mimePtr, const char *name,·
465e50 ¤   ¤   ¤   ¤   ¤   ···const char *value)
ecbb36 {
4f855d ¤   if (!mimePtr)
202769 ¤   ¤   return (FALSE);
8867c5 ¤
38ba75 ¤   emsMIMEParamP paramPtr = (emsMIMEParamP) malloc (sizeof(emsMIMEparam));
75af5a
a606aa ¤   if (paramPtr)
ffc7a1 ¤   {
bd85e9 ¤   ¤   paramPtr->size = sizeof(emsMIMEparam);
8ea20b ¤   ¤   paramPtr->name = strdup(name);
ed82b1 ¤   ¤   paramPtr->value = strdup(value);
7f9fe8 ¤   ¤   paramPtr->next = NULL;
15af5a
99a825 ¤   ¤   if ((paramPtr->name) && (paramPtr->value))
d95b34 ¤   ¤   {
89d619 ¤   ¤   ¤   emsMIMEParamP *paramEnd = &(mimePtr->params);
4daf5a
375436 ¤   ¤   ····while (*paramEnd)
87e735 ¤   ¤   ¤   ¤   paramEnd = &((*paramEnd)->next);
92af5a
7633f6 ¤   ¤   ¤   *paramEnd = paramPtr;
56af5a
c73ec8 ¤   ¤   ¤   return (TRUE);
810fe4 ¤   ¤   }
1c9371 ¤   }
99af5a
b2f9d3 ¤   // If we get here then something went wrong
bd97ca ¤   // Do complete cleanup
03af5a
cd8d69 ¤   free_param_type(paramPtr);
715d9d ¤   return (FALSE);
--bd9c 00048eb3f6d401101f9 Page 4 of MIMETYPE.CPP
7aefe6 }
46af5a
13e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
cbaf5a
0f38e5 /*
365516 ·* ·Free an emsMIMEtype structure, including all strings and parameters.
40775e ·*
726a22 ·* ·Args:
beb927 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be freed
11775e ·*
ae03d6 ·* ·No return value.
16495d ·*/
ecb897 void free_mime_type(emsMIMEtypeP mimePtr)
3ebb36 {
0e5e02 ¤   if (mimePtr)
d7c7a1 ¤   {
a717c5 ¤   ¤   safefree(mimePtr->version);
f64050 ¤   ¤   safefree(mimePtr->type);
f3d710 ¤   ¤   safefree(mimePtr->subType);
101b52 ¤   ¤
e355d7 ¤   ¤   free_param_type(mimePtr->params);
fdaf5a
0fccb5 ¤   ¤   safefree(mimePtr->contentDisp);
ce250f ¤   ¤   free_param_type(mimePtr->contentParams);
44af5a
d9457f ¤   ¤   safefree(mimePtr);
279371 ¤   }
ebefe6 }
93af5a
57e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
77af5a
0938e5 /*
532ec7 ·* ·Convert an emsMIMEtype structure to a Content-Type header field line
96a7eb ·* ·in the format specified by RFC 882.
f0775e ·*
f4322b ·* ·NOTE: The user of this function is responsible for freeing the
f4c8a5 ·* ·······returned string.
06775e ·*
e56a22 ·* ·Args:
0ccd7c ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure
98775e ·*
cf9fca ·* ·Returns: String containing header field; dynamically allocated.
c1495d ·*/
0a1ea2 char *string_mime_type(emsMIMEtypeP mimePtr)·
a8bb36 {
46244c ¤   const char *kPrefixStr ·········= "Content-Type: ";
b12363 ¤   const char *kParamSepStr ·······= ";\r\n ·";
b5e081 ¤   const char *kTypeSubtypeSepStr ·= "/";
0e862f ¤   const char *kAttValueSepStr ····= "=";
46af5a
0e8aef ¤   // Must have a valid mime structure
04855d ¤   if (!mimePtr)
997ed2 ¤   ¤   return NULL;
57af5a
0d84f2 ¤   // Both TYPE and SUBTYPE are required by RFC822
408b36 ¤   if ((!mimePtr->type) || (!mimePtr->subType))
2f7ed2 ¤   ¤   return NULL;
1eaf5a
c718e1 ¤   // Calculate the length of the header string
4731bf ¤   unsigned int hLen = 0;
33af5a
347b91 ¤   hLen += strlen(kPrefixStr);
0ea535 ¤   hLen += rfc822_quoted_strlen(mimePtr->type);
0a9271 ¤   hLen += strlen(kTypeSubtypeSepStr);
257cc1 ¤   hLen += rfc822_quoted_strlen(mimePtr->subType);
11af5a
0f33c3 ¤   emsMIMEParamP paramPtr = mimePtr->params;
a9af5a
d2494e ¤   while (paramPtr)
3cc7a1 ¤   {
de4682 ¤   ¤   hLen += strlen(kParamSepStr);
48211c ¤   ¤   hLen += rfc822_quoted_strlen(paramPtr->name);
--4797 0009998b13b401101f9 Page 5 of MIMETYPE.CPP
6acadd ¤   ¤   hLen += strlen(kAttValueSepStr);
d3aded ¤   ¤   hLen += rfc822_quoted_strlen(paramPtr->value);
34af5a
cef723 ¤   ¤   paramPtr = paramPtr->next;
cb9371 ¤   }
a0af5a
886362 ¤   // Allocate space for the header line
de0ee5 ¤   char *hStr = (char *) malloc(hLen + 1);
0367c5 ¤
3eaace ¤   if (!hStr)
107ed2 ¤   ¤   return NULL;
54af5a
cec0a8 ¤   // Build the header line
cb185f ¤   char *cp = hStr;
82af5a
c8d079 ¤   cp = strchr(strcpy(cp, kPrefixStr), '\0');
de803c ¤   cp = rfc822_quote_strcpy(cp, mimePtr->type);
372c23 ¤   cp = strchr(strcpy(cp, kTypeSubtypeSepStr), '\0');
e2bd54 ¤   cp = rfc822_quote_strcpy(cp, mimePtr->subType);
ecaf5a
67e0d9 ¤   paramPtr = mimePtr->params;
72494e ¤   while (paramPtr)
5ec7a1 ¤   {
c8bd8b ¤   ¤   cp = strchr(strcpy(cp, kParamSepStr), '\0');
e3bcf8 ¤   ¤   cp = rfc822_quote_strcpy(cp, paramPtr->name);
b92bbc ¤   ¤   cp = strchr(strcpy(cp, kAttValueSepStr), '\0');
f80c5a ¤   ¤   cp = rfc822_quote_strcpy(cp, paramPtr->value);
e8af5a
fcf723 ¤   ¤   paramPtr = paramPtr->next;
e79371 ¤   }
19af5a
351943 ¤   // Return the header line
e1f43d ¤   return (hStr);
adefe6 }
d7af5a
51e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
9aaf5a
8838e5 /*
268116 ·* ·Pick out a specific parameter name-value pair from an emsMIMEtype
7e25b3 ·* ·structure. The match is case sensitive.
d3775e ·*
0743e4 ·* ·NOTE: The user of this function should NOT alter the returned string
455e8d ·* ·······in any way -- it should be considered READ-ONLY.
92775e ·*
266a22 ·* ·Args:
9c9ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
1055c4 ·* ··paramName [IN] Name of parameter to look for
6f775e ·*
51ab2e ·* ·Returns: String of the associated value or NULL if no match is found
f5495d ·*/
24853a const char *get_mime_parameter(emsMIMEtypeP mimePtr, const char *paramName)
9cbb36 {
29855d ¤   if (!mimePtr)
167ed2 ¤   ¤   return NULL;
b6af5a
de33c3 ¤   emsMIMEParamP paramPtr = mimePtr->params;
93af5a
b4494e ¤   while (paramPtr)
5ac7a1 ¤   {
1847ac ¤   ¤   if (strcmp(paramPtr->name, paramName) == 0)
ad5782 ¤   ¤   ¤   return (paramPtr->value);
1aaf5a
adf723 ¤   ¤   paramPtr = paramPtr->next;
619371 ¤   }
2caf5a
39f206 ····return (NULL);
3d797c }¤  ¤   ¤   ¤
0eaf5a
8de6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37af5a
6a38e5 /*
99266d ·* ·Remove a parameter from an existing emsMIMEtype structure. This structure
--3c38 00095b5e0cd401101f9 Page 6 of MIMETYPE.CPP
ab65ad ·* ·should be created using make_mime_type().
a0775e ·*
0e97ac ·* ·NOTE: All input strings are COPIED before permanent use.
3b775e ·*
ff9648 ·* Args:
20d93e ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to altered
ca7c06 ·* ··name ···[IN] Name of the parameter to be removed
a0a3b2 ·* ··
fc8b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
0f495d ·*/
ddb568 int remove_mime_parameter(emsMIMEtypeP mimePtr, const char *name)
e8bb36 {
d0855d ¤   if (!mimePtr)
5f2769 ¤   ¤   return (FALSE);
64af5a
c54ff4 ¤   emsMIMEParamP paramPtr = mimePtr->params, prevParamPtr = NULL;
14af5a
927615 ¤   /* Find the parameter */
fc494e ¤   while (paramPtr)
59c7a1 ¤   {
10726b ¤   ¤   if (strcmp(paramPtr->name, name) == 0)
68cdcb ¤   ¤   ¤   break;
1daf5a
2d7956 ¤   ¤   prevParamPtr = paramPtr;
47f723 ¤   ¤   paramPtr = paramPtr->next;
c69371 ¤   }
09af5a
9dac03 ¤   if (!paramPtr)
6ebce8 ¤   ····return (FALSE); /* Not found */
bcaf5a
959836 ¤   if (prevParamPtr == NULL) /* Removing first in list */
30ec1c ¤   ¤   mimePtr->params = paramPtr->next;
070e24 ¤   else
499712 ¤   ¤   prevParamPtr->next = paramPtr->next;
2caf5a
458bc0 ¤   paramPtr->next = NULL;
568d69 ¤   free_param_type(paramPtr);
ddaf5a
b4e7c0 ¤   return (TRUE);
0eefe6 }
1eaf5a
55e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
77af5a
3f38e5 /*
af5b1f ·* ·Check for a matching MIME type/subtype. If either type or subtype is
5d43fd ·* ·NULL, then it won't be checked. If both are NULL, then TRUE is always
4f7d43 ·* ·returned.
b1775e ·*
016a22 ·* ·Args:
3b9ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
1142a6 ·* ··mime_type [IN] The major MIME type to check
b43923 ·* ··sub_type ·[IN] The MIME subtype to check
cde6a2 ·* ·
236740 ·* ·Returns: Boolean (TRUE if the MIME type matches, FALSE if not)
69495d ·*/
c95719 int match_mime_type(emsMIMEtypeP mimePtr, const char *mime_type,
e4e009 ¤   ¤   ¤   ¤   ¤   const char *sub_type)
50bb36 {
2f855d ¤   if (!mimePtr)
a22769 ¤   ¤   return (FALSE);
55af5a
a4eb9e ¤   return (
6a6816 ¤   ¤   ¤   ((mime_type == NULL) || (stricmp(mimePtr->type, mime_type) == 0))
124f13 ¤   ¤   ¤   &&
e18856 ¤   ¤   ¤   ((sub_type == NULL) || (stricmp(mimePtr->subType, sub_type) == 0))
fbd4e4 ¤   ¤   ···);
e8efe6 }
49af5a
6760e8 /* ========================================================================== */
7ef935 /* ·····························LOCAL FUNCTIONS ······························*/
0a60e8 /* ========================================================================== */
95af5a
--42e8 0015ffd6912401101f9 Page 7 of MIMETYPE.CPP
41235e /* Private function used to free the parameter linked-list */
5ddf59 /* static */ void free_param_type(emsMIMEParamP paramPtr)
6dbb36 {
8c73ac ¤   emsMIMEParamP nextParamPtr;
26af5a
29494e ¤   while (paramPtr)
e6c7a1 ¤   {
5da999 ¤   ¤   nextParamPtr = paramPtr->next;
a9af5a
79bb53 ¤   ¤   safefree(paramPtr->name);
4a1784 ¤   ¤   safefree(paramPtr->value);
8e280a ¤   ¤   safefree(paramPtr);
90af5a
c60738 ¤   ¤   paramPtr = nextParamPtr;
679371 ¤   }
f8efe6 }
5faf5a
--9581 000a85d7d5d401101fa Page 1 of Mimetype.h
bc38e5 /*
8820c2 ·* ·Functions to manage emsMIMEtype structures
af12c6 ·* ·for use with Eudora EMS API under MS Windows.
34775e ·*
00613d ·* ·Filename: mimetype.h
01775e ·*
a25074 ·* ·Last Edited: August 21, 1996
b6775e ·*
40005b ·* ·Author: Scott Manjourides
aa775e ·*
f9ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
16775e ·*
7ac179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
90495d ·*/
cdaf5a
105c5d #ifndef EMS_MIMETYPE_H
980bac #define EMS_MIMETYPE_H
69af5a
4e5655 #include <windows.h>
e6fbd1 #include "ems-win.h"
2daf5a
8caf5a
833379 #ifdef __cplusplus
286dad extern "C" {
d87454 #endif
e1af5a
1738e5 /*
3785ce ·* ·Create an emsMIMEtype structure to hold MIME information. Only the
4766cf ·* ·type and subtype are set here, use add_mime_parameter() to add
a7f3dd ·* ·any name/value parameter pairs.
f9775e ·*
16f79f ·* ·NOTE: All input strings are COPIED before permanent use. The user
8eeb22 ·* ·······of this function is responsible for calling free_mime_type()
0186a5 ·* ·······on returned structure.
3e775e ·*
0b6a22 ·* ·Args:
923aa6 ·* ··mime_type ···[IN] the main MIME type: e.g., "text", "application",·
5b28ce ·"image"
9c61dc ·* ··sub_type ····[IN] the sub type: e.g., "plain", "octet-stream", "jpeg"
be1cc3 ·* ··mime_version [IN] the MIME verion number, if NULL will default to "1.0"
b3775e ·*
fc04db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
cc495d ·*/
cb0d89 emsMIMEtypeP make_mime_type(const char *mime_type, const char *sub_type,·
106764 ¤   ¤   ¤   ¤   ¤   ¤   ¤   const char *mime_version);
43af5a
7b38e5 /*
25605e ·* ·Create an emsMIMEtype structure to hold MIME information. Structure is
e965ea ·* ·initialized to values provided in RFC822 content-type header line. This
ee4b95 ·* ·includes all parameter name-value pairs.
12a3b2 ·* ··
bee058 ·* ·NOTE: The user of this function is responsible for calling
909141 ·* ·······free_mime_type() on returned structure.
42775e ·*
156a22 ·* ·Args:
54671c ·* ··content_type [IN] The RFC822 content-type string to parse
fd775e ·*
2b04db ·* ·Returns: Pointer to the created emsMIMEtype structure, NULL if error.
07495d ·*/
a3701e emsMIMEtypeP parse_make_mime_type(const char *src);
51af5a
2538e5 /*
eddd1d ·* ·Add a parameter to an existing emsMIMEtype structure. This structure
a565ad ·* ·should be created using make_mime_type().
6e775e ·*
ce97ac ·* ·NOTE: All input strings are COPIED before permanent use.
10775e ·*
709648 ·* Args:
a5d232 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be added too
01f186 ·* ··name ···[IN] Name of the parameter
5d0476 ·* ··value ··[IN] Value of the parameter
a8a3b2 ·* ··
--31bf 000e16044e7401101fa Page 2 of Mimetype.h
748b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
19495d ·*/
c0922b int add_mime_parameter(emsMIMEtypeP mimePtr, const char *name,·
4d52fb ¤   ¤   ¤   ¤   ¤   ···const char *value);
60af5a
ac38e5 /*
af9f36 ·* ·Remove a parameter from an existing emsMIMEtype structure.·
117816 ·This structure
e565ad ·* ·should be created using make_mime_type().
21775e ·*
8d97ac ·* ·NOTE: All input strings are COPIED before permanent use.
98775e ·*
e49648 ·* Args:
68d93e ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to altered
587c06 ·* ··name ···[IN] Name of the parameter to be removed
87a3b2 ·* ··
1d8b0b ·* ·Returns: Boolean (TRUE = success, FALSE = failure)
d6495d ·*/
bbefdb int remove_mime_parameter(emsMIMEtypeP mimePtr, const char *name);
39af5a
6638e5 /*
315516 ·* ·Free an emsMIMEtype structure, including all strings and parameters.
d8775e ·*
1c6a22 ·* ·Args:
3bb927 ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure to be freed
c7775e ·*
9303d6 ·* ·No return value.
d2495d ·*/
4be0ae void free_mime_type(emsMIMEtypeP mimePtr);
1caf5a
5d38e5 /*
7f2ec7 ·* ·Convert an emsMIMEtype structure to a Content-Type header field line
dda7eb ·* ·in the format specified by RFC 882.
6d775e ·*
ca322b ·* ·NOTE: The user of this function is responsible for freeing the
cac8a5 ·* ·······returned string.
a8775e ·*
1d6a22 ·* ·Args:
5bcd7c ·* ··mimePtr [IN] Pointer to the emsMIMEtype structure
89775e ·*
ae9fca ·* ·Returns: String containing header field; dynamically allocated.
45495d ·*/
763bce char *string_mime_type(emsMIMEtypeP mimePtr);
91af5a
b138e5 /*
dc8116 ·* ·Pick out a specific parameter name-value pair from an emsMIMEtype
6225b3 ·* ·structure. The match is case sensitive.
45775e ·*
9343e4 ·* ·NOTE: The user of this function should NOT alter the returned string
cf5e8d ·* ·······in any way -- it should be considered READ-ONLY.
c9775e ·*
a36a22 ·* ·Args:
899ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
8a55c4 ·* ··paramName [IN] Name of parameter to look for
03775e ·*
ddab2e ·* ·Returns: String of the associated value or NULL if no match is found
e9495d ·*/
3d9e7c const char *get_mime_parameter(emsMIMEtypeP mimePtr, const char *paramName);
eeaf5a
6a38e5 /*
e75b1f ·* ·Check for a matching MIME type/subtype. If either type or subtype is
a943fd ·* ·NULL, then it won't be checked. If both are NULL, then TRUE is always
217d43 ·* ·returned.
49775e ·*
d46a22 ·* ·Args:
c89ef2 ·* ··mimePtr ··[IN] Pointer to the emsMIMEtype structure
0442a6 ·* ··mime_type [IN] The major MIME type to check
b73923 ·* ··sub_type ·[IN] The MIME subtype to check
f1e6a2 ·* ·
606740 ·* ·Returns: Boolean (TRUE if the MIME type matches, FALSE if not)
66495d ·*/
e1a85b int match_mime_type(emsMIMEtypeP mimePtr, const char *mime_type,·
--029e 0017f3f6d7d401101fa Page 3 of Mimetype.h
229d01 ¤   ¤   ¤   ¤   ¤   const char *sub_type);
2faf5a
0b3379 #ifdef __cplusplus
a2efe6 }
3e7454 #endif
fdaf5a
7f3be2 #endif /* EMS_MIMETYPE_H */
--7fd1 0006873d25a401101fb Page 1 of RFC1847.CPP
bc38e5 /*
d566b4 ·* ·Functions to aide manipulation and parsing of MIME RFC1847 objects.
d6775e ·*
abe658 ·* ·Last Edited: Wednesday, October 2, 1996
6e775e ·*
54ba78 ·* ·Last Edited: Monday, September 9, 1996
5e775e ·*
69005b ·* ·Author: Scott Manjourides
db775e ·*
aeea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
71775e ·*
10c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
f3775e ·*
bf495d ·*/
93af5a
dc7066 #include <stdlib.h> /* rand() */
39ff6d #include <time.h> /* time() */
612242 #include <stdio.h> /* sprintf() */
5e324c #include <string.h>
fc568d #include <windows.h> /* Must be included for ems-win.h */
8daf5a
90fbd1 #include "ems-win.h"
8a8595 #include "RFC822.H"
329dcb #include "RFC1847.H"
6fd3fb #include "BUFTYPE.H"
965004 #include "MIMETYPE.H"
03af5a
937890 /* ------------------------------------------------------------------------- */
13af5a
da1c52 static char *kBoundaryParameterName = "boundary";
909528 static char *kBoundaryPrefixSuffix = "=-=-=-=";
c0af5a
367890 /* ------------------------------------------------------------------------- */
6aaf5a
d5dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
c6af5a
d97890 /* ------------------------------------------------------------------------- */
0baf5a
1d3b13 static int rfc1847_create_init(createStatePtr pState);
1f5b46 static int rfc1847_parse_init(parseStatePtr pState);
b0af5a
717890 /* ------------------------------------------------------------------------- */
89af5a
6238e5 /*
d8ae27 ·* ·Allocates and returns a pointer to an initialized createState structure.
69a3b2 ·* ··
cf82c9 ·* ·NOTE: The user of this function is responsible for properly
2df6d8 ·* ·······deleting the returned data by calling delete_create_state()
d761f8 ·* ·······when the state data is no longer needed.
3c775e ·*
05b7ce ·* ·No arguments.
65775e ·*
8f2d82 ·* ·Pointer to newly created createState structure. NULL if error.
e7495d ·*/
295776 createStatePtr new_create_state()
9dbb36 {
a032d4 ¤   createStatePtr p;
20d72f ¤   p = (createStatePtr) malloc(sizeof(createState));
47af5a
754dda ¤   if (!p)
b58021 ¤   ¤   return (NULL);
b3af5a
982f2a ¤   p->stage = p->next_stage = p->afterout_stage = CSE_Fail;
feaf5a
b9de3f ¤   p->pBoundaryStr = NULL;
b3693f ¤   p->current_part = 0;
d4af5a
491a9c ¤   p->pTmpBuf = make_buf();
5409c3 ¤   p->pOutputBuf = NULL;
27af5a
aea182 ¤   p->bInitialized = FALSE;
68af5a
--1590 000b7fecd17401101fb Page 2 of RFC1847.CPP
8670cd ¤   return (p);
0defe6 }
a3af5a
8fe6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
46af5a
1f38e5 /*
4d739f ·* ·Frees all memory within the state structure, including the structure
5aea81 ·* ·itself.
92a3b2 ·* ··
48f8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
de775e ·*
f76a22 ·* ·Args:
4ff565 ·* ···pState [IN] Pointer to the state structure to be deleted.
da775e ·*
ac03d6 ·* ·No return value.
83495d ·*/
942ea5 void delete_create_state(createStatePtr p)
bdbb36 {
774dda ¤   if (!p)
2b99bf ¤   ¤   return;
0daf5a
9ac87f ¤   delete_buf(p->pTmpBuf);
0c0972 ¤   safefree(p->pBoundaryStr);
abaf5a
2a868d ¤   safefree(p);
13efe6 }
9aaf5a
26e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
d9af5a
8438e5 /*
8ab5e4 ·* ·Allocates and returns a pointer to an initialized parseState structure.
5aa3b2 ·* ··
df82c9 ·* ·NOTE: The user of this function is responsible for properly
e7f6d8 ·* ·······deleting the returned data by calling delete_create_state()
aa61f8 ·* ·······when the state data is no longer needed.
81775e ·*
a7b7ce ·* ·No arguments.
b5775e ·*
3f87bd ·* ·Pointer to newly created parseState structure. NULL if error.
f2495d ·*/
6551fd parseStatePtr new_parse_state()
09bb36 {
6e6d9c ¤   parseStatePtr p;
02d97d ¤   p = (parseStatePtr) malloc(sizeof(parseState));
04af5a
d84dda ¤   if (!p)
d08021 ¤   ¤   return (NULL);
16af5a
ab8911 ¤   p->stage = p->next_stage = p->afterout_stage = PSE_Fail;
90af5a
f5693f ¤   p->current_part = 0;
33af5a
814847 ¤   p->nOutputCount = 0;
27c213 ¤   p->nAfteroutSkip = 0;
5a103d ¤   p->nLeftSpanCount = 0;
a0af5a
2209c3 ¤   p->pOutputBuf = NULL;
d6dd55 ¤   p->pSearchBuf = NULL;
e0af5a
d59259 //¤ p->pTmpBuf = make_buf();
87dfd7 ¤   p->pPrevBuf = make_buf();
23c334 ¤   p->pBoundaryBuf = make_buf();
160377 ¤   p->pDblNewlineBuf = make_buf();
dc252d ¤   p->pNewlineBuf = make_buf();
62af5a
48a182 ¤   p->bInitialized = FALSE;
59af5a
dd70cd ¤   return (p);
6eefe6 }
4eaf5a
43e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b7af5a
--d2c8 0002af3c129401101fb Page 3 of RFC1847.CPP
bc38e5 /*
c8739f ·* ·Frees all memory within the state structure, including the structure
d1ea81 ·* ·itself.
aca3b2 ·* ··
f1f8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
68775e ·*
9a6a22 ·* ·Args:
d9f565 ·* ···pState [IN] Pointer to the state structure to be deleted.
ef775e ·*
2703d6 ·* ·No return value.
3a495d ·*/
3718c9 void delete_parse_state(parseStatePtr p)
81bb36 {
6b4dda ¤   if (!p)
ed99bf ¤   ¤   return;
2c1b52 ¤   ¤
ad6533 //¤ delete_buf(p->pTmpBuf);
04c173 ¤   delete_buf(p->pPrevBuf);
8f2c52 ¤   delete_buf(p->pBoundaryBuf);
0ab96c ¤   delete_buf(p->pDblNewlineBuf);
a614af ¤   delete_buf(p->pNewlineBuf);
87af5a
75868d ¤   safefree(p);
f6efe6 }
63af5a
e4e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44af5a
5538e5 /*
cf5452 ·* ·Performs necessary initialization for rfc1847_create().
9ca3b2 ·* ··
b46a22 ·* ·Args:
9f963f ·* ···pState [IN] Pointer to the state structure.
c9775e ·*
cd6448 ·* ·Return value: BOOLEAN indicating success.
7b495d ·*/
4fe09a static int rfc1847_create_init(createStatePtr pState)
7fbb36 {
019685 ¤   char *pBoundaryTxt = (char *) malloc(128);
6eaf5a
49583f ¤   if (!pBoundaryTxt)
5b2769 ¤   ¤   return (FALSE);
a9af5a
d1d72d ¤   /* Create a random boundary; max 68 chars */
ecf5a2 ¤   srand((unsigned)time(NULL));
d9af5a
e693e6 ¤   sprintf(pBoundaryTxt, "%s%d%d%d%s",
20d255 ¤   ¤   kBoundaryPrefixSuffix,
cf7921 ¤   ¤   rand(),
fb7921 ¤   ¤   rand(),
ef7921 ¤   ¤   rand(),
2a3c67 ¤   ¤   kBoundaryPrefixSuffix);
0faf5a
78312c ¤   pState->pBoundaryStr = pBoundaryTxt;
fd00b0 ¤   pState->stage = CSE_Start;
d4af5a
2a0aa9 ¤   pState->bInitialized = TRUE;
72af5a
80e7c0 ¤   return (TRUE);
4eefe6 }
a0af5a
34e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
40af5a
a738e5 /*
fd9c8e ·* ·Creates RFC1847 MIME structure.
86a3b2 ·* ··
096a22 ·* ·Args:
6e379d ·* ···mimePtr ·[IN] ····MIME content info, used to create the MIME headers.
b23c43 ·* ···pOutBuf ·[OUT] ···Output buffer (RFC1847 MIME structure).
5d2dc1 ·* ···pInPart1 [IN] ····Input buffer used for first part.
8e822a ·* ···pInPart2 [IN] ····Input buffer used for second part.
d86d62 ·* ···pState ··[IN/OUT] Pointer to state info, caller must preserve.
2a775e ·*
--aa77 00029477ec3401101fb Page 4 of RFC1847.CPP
418a08 ·* ·Return values:
72ec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
cb4815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
4ceeac ·* ···RFC1847_FAIL ·······Parsing error.
08495d ·*/
46af5a
11883d int rfc1847_create(emsMIMEtypeP mimePtr,
cae65d ¤   ¤   ¤   ¤   ···BufTypePtr pOutBuf,
613c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
13d359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
e87568 ¤   ¤   ¤   ¤   ···createStatePtr pState)
82bb36 {
bd97e1 ¤   if (!pState->bInitialized)
acd82f ¤   ¤   if (!rfc1847_create_init(pState))
6739a0 ¤   ¤   ¤   pState->stage = CSE_Fail;
28af5a
7c58c6 ¤   while (pState->stage != CSE_Done)
d5c7a1 ¤   {
3c6c44 ¤   ¤   switch (pState->stage)
035b34 ¤   ¤   {
5281af ¤   ¤   ¤   case CSE_Start:
7d4c3c ¤   ¤   ¤   ¤   pState->stage = CSE_DoHeader; /* Just an entry point */
e4cdcb ¤   ¤   ¤   break;
3aaf5a
4340c0 ¤   ¤   ¤   case CSE_DoHeader:
3ef776 ¤   ¤   ¤   {
cb5713 ¤   ¤   ¤   ¤   pState->stage = CSE_Fail; // If not changed, then something fai¶
989f4f led
1baf5a
bbf0e0 ¤   ¤   ¤   ¤   if ((mimePtr) && (pState->pBoundaryStr))
e572c3 ¤   ¤   ¤   ¤   {
366fe6 ¤   ¤   ¤   ¤   ¤   /* Remove the boundary parameter from the MIME struct -- if¶
b8a914 ·it's there */
44c788 ¤   ¤   ¤   ¤   ¤   remove_mime_parameter(mimePtr, kBoundaryParameterName);
a4af5a
4ad426 ¤   ¤   ¤   ¤   ¤   /* Add the boundary to the MIME type struct */
51a01f ¤   ¤   ¤   ¤   ¤   if (add_mime_parameter(mimePtr, kBoundaryParameterName, pSt¶
777f85 ate->pBoundaryStr))
504859 ¤   ¤   ¤   ¤   ¤   {
c898aa ¤   ¤   ¤   ¤   ¤   ¤   char *pCT = NULL;
22af5a
48c4b0 ¤   ¤   ¤   ¤   ¤   ¤   /* Create an RFC822 Content-Type header line from the M¶
7a4666 IME struct*/
df88dd ¤   ¤   ¤   ¤   ¤   ¤   if ((pCT = string_mime_type(mimePtr)) != NULL)
818fec ¤   ¤   ¤   ¤   ¤   ¤   {
bcc0f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy_buf(pState->pTmpBuf, pCT); /* Content-Type: ¶
787fe0 */
6124ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "\r\n"); /* Not the bla¶
417313 nk line, just end of CT: */
dbe468 ¤   ¤   ¤   ¤   ¤   ¤   ¤   resetpos_buf(pState->pTmpBuf);
09af5a
de0463 ¤   ¤   ¤   ¤   ¤   ¤   ¤   safefree(pCT);
3caf5a
85aaa7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pState->pTmpBuf;
4ea661 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoBoundary;
7bf3d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
9ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
301c89 ¤   ¤   ¤   ¤   ¤   }
1e2613 ¤   ¤   ¤   ¤   }
71a3a6 ¤   ¤   ¤   }
1ccdcb ¤   ¤   ¤   break;
87af5a
c52cf4 ¤   ¤   ¤   case CSE_DoBoundary:
3af776 ¤   ¤   ¤   {
372a64 ¤   ¤   ¤   ¤   strcpy_buf(pState->pTmpBuf, "\r\n");
dbc12a ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "--");
901252 ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, pState->pBoundaryStr);
c1af5a
b1b45a ¤   ¤   ¤   ¤   if ((pState->current_part) < 2) /* End the header and first par¶
bac850 t */
f872c3 ¤   ¤   ¤   ¤   {
291f64 ¤   ¤   ¤   ¤   ¤   pState->current_part++;
--07f3 000d40787cd401101fb Page 5 of RFC1847.CPP
5e8fdb ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoPart;
5d2613 ¤   ¤   ¤   ¤   }
078684 ¤   ¤   ¤   ¤   else /* End of second part */
8072c3 ¤   ¤   ¤   ¤   {
08d00d ¤   ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "--");
47cb12 ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_Done;
832613 ¤   ¤   ¤   ¤   }
fbaf5a
ab4dab ¤   ¤   ¤   ¤   strcat_buf(pState->pTmpBuf, "\r\n");
2c2ac6 ¤   ¤   ¤   ¤   resetpos_buf(pState->pTmpBuf);
e1af5a
22119a ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
a8f7c9 ¤   ¤   ¤   ¤   pState->pOutputBuf = pState->pTmpBuf;
3da3a6 ¤   ¤   ¤   }
70cdcb ¤   ¤   ¤   break;
17af5a
1a7739 ¤   ¤   ¤   case CSE_DoPart:
62f776 ¤   ¤   ¤   {
c04810 ¤   ¤   ¤   ¤   switch (pState->current_part)
b172c3 ¤   ¤   ¤   ¤   {
63ac6e ¤   ¤   ¤   ¤   ¤   case 1: /* We're doing part 1 now */
214859 ¤   ¤   ¤   ¤   ¤   {
b43f2e ¤   ¤   ¤   ¤   ¤   ¤   if (poslen_buf(pInPart1) > 0)
058fec ¤   ¤   ¤   ¤   ¤   ¤   {
8df3d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
bf4477 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInPart1;
9daf5a
7a76a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pInPart2)
8ba117 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoBoundary;
cec4dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
93f902 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoPart;
94db3c ¤   ¤   ¤   ¤   ¤   ¤   }
9a8cac ¤   ¤   ¤   ¤   ¤   ¤   else /* pInPart1 is empty/completed/non-existant */
058fec ¤   ¤   ¤   ¤   ¤   ¤   {
8d76a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pInPart2)
6e9855 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoBoundary;
1653c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else /* !pInPart2 */
9af43c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_COMPLETED); /* We've eaten all ¶
8fc55f of part 1, and there is no part 2 */
bbdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
b01c89 ¤   ¤   ¤   ¤   ¤   }
1b14c3 ¤   ¤   ¤   ¤   ¤   break;
22af5a
06e3cf ¤   ¤   ¤   ¤   ¤   case 2: /* We're doing part 2 now */
b64859 ¤   ¤   ¤   ¤   ¤   {
d0b5fe ¤   ¤   ¤   ¤   ¤   ¤   if (poslen_buf(pInPart2) > 0)
7e8fec ¤   ¤   ¤   ¤   ¤   ¤   {
d2f3d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoOutput;
daab13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInPart2;
067347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = CSE_DoPart;
64db3c ¤   ¤   ¤   ¤   ¤   ¤   }
128cac ¤   ¤   ¤   ¤   ¤   ¤   else /* pInPart1 is empty/completed/non-existant */
6d8fec ¤   ¤   ¤   ¤   ¤   ¤   {
a976a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pInPart2)
98f43c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_COMPLETED); /* We've eaten all ¶
d443d0 of part 2 */
7753c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else /* !pInPart2 */
ff9855 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = CSE_DoBoundary;
21db3c ¤   ¤   ¤   ¤   ¤   ¤   }
551c89 ¤   ¤   ¤   ¤   ¤   }
c314c3 ¤   ¤   ¤   ¤   ¤   break;
ca2613 ¤   ¤   ¤   ¤   }
f4a3a6 ¤   ¤   ¤   }
6dcdcb ¤   ¤   ¤   break;
b7af5a
d0b318 ¤   ¤   ¤   case CSE_DoOutput:
7af776 ¤   ¤   ¤   {
41b63b ¤   ¤   ¤   ¤   if (pOutBuf)
1f72c3 ¤   ¤   ¤   ¤   {
61cd44 ¤   ¤   ¤   ¤   ¤   unsigned int nLen = poslen_buf(pState->pOutputBuf);
bc9528 ¤   ¤   ¤   ¤   ¤   unsigned int nOut = bufins_buf(pOutBuf, pState->pOutputBuf);
d4af5a
--73d2 000cc4d968d401101fb Page 6 of RFC1847.CPP
9e3377 ¤   ¤   ¤   ¤   ¤   if (nOut < nLen) /* Anything left to output */
f3a6fe ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL);
f5af5a
4ff366 ¤   ¤   ¤   ¤   ¤   pState->stage = pState->afterout_stage;
fc2613 ¤   ¤   ¤   ¤   }
1cfa07 ¤   ¤   ¤   ¤   else
81655e ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL); /* No output buffer */
40a3a6 ¤   ¤   ¤   }
26cdcb ¤   ¤   ¤   break;
36af5a
64d65f ¤   ¤   ¤   case CSE_Fail:
7dcd39 ¤   ¤   ¤   ¤   return (RFC1847_FAIL);
7dcdcb ¤   ¤   ¤   break;
113ab2 ¤   ¤   } /* switch (stage) */
f8456d ¤   } /* while */
a3af5a
957e63 ¤   return (RFC1847_COMPLETED);
ecefe6 }
a7af5a
f3e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
7faf5a
6538e5 /*
c775fe ·* ·Performs necessary initialization for rfc1847_parse().
f1775e ·*
d56a22 ·* ·Args:
47963f ·* ···pState [IN] Pointer to the state structure.
e3775e ·*
1c6448 ·* ·Return value: BOOLEAN indicating success.
30495d ·*/
5aabc9 static int rfc1847_parse_init(parseStatePtr pState)
7ebb36 {
26cfc0 ¤   if (!pState)
832769 ¤   ¤   return (FALSE);
51af5a
89b8ac ¤   strcpy_buf(pState->pNewlineBuf, "\r\n");
d58f61 ¤   strcpy_buf(pState->pDblNewlineBuf, "\r\n\r\n");
f7af5a
bd772f ¤   resetpos_buf(pState->pNewlineBuf);
3cfabd ¤   resetpos_buf(pState->pDblNewlineBuf);
ea67c5 ¤
408f46 ¤   pState->stage = PSE_Start;
680aa9 ¤   pState->bInitialized = TRUE;
8baf5a
b9e7c0 ¤   return (TRUE);
10efe6 }
40af5a
62e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ebaf5a
b638e5 /*
26070c ·* ·Parses RFC1847 MIME structure, returning MIME info and separated parts.
8da3b2 ·* ··
cb6a22 ·* ·Args:
1d047b ·* ···mimePtr ··[OUT] ···Returns a pointer to a newly created emsMIMEtype.
7b47d4 ·* ···pOutPart1 [OUT] ···Output buffer, part 1.
fa5ad7 ·* ···pOutPart2 [OUT] ···Output buffer, part 2.
0c183e ·* ···pInBuf ···[IN] ····Input buffer containing full RFC1847 MIME structure.
3fcf05 ·* ···pState ···[IN/OUT] Pointer to state info, caller must preserve.
7c775e ·*
7e8a08 ·* ·Return values:
8aec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
924815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
ddeeac ·* ···RFC1847_FAIL ·······Parsing error.
5d495d ·*/
50892a int rfc1847_parse(emsMIMEtypeP *mimePtr,
b24889 ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart1,
2da7ed ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart2,
13824b ¤   ¤   ¤   ¤   ··BufTypePtr pInBuf,
8617a0 ¤   ¤   ¤   ¤   ··parseStatePtr pState)
adbb36 {
8c5757 ¤   int bForceJumpState = FALSE;
c0af5a
cc97e1 ¤   if (!pState->bInitialized)
--3f2f 0005331a124401101fb Page 7 of RFC1847.CPP
43ec5f ¤   ¤   if (!rfc1847_parse_init(pState))
e59f9b ¤   ¤   ¤   pState->stage = PSE_Fail;
9baf5a
334432 ¤   while ((bForceJumpState) || (poslen_buf(pInBuf) > 0))
e4c7a1 ¤   {
a2ed3c ¤   ¤   bForceJumpState = FALSE;
03af5a
866c44 ¤   ¤   switch (pState->stage)
435b34 ¤   ¤   {
6d0e59 ¤   ¤   ¤   case PSE_Start:
5ff776 ¤   ¤   ¤   {
7ef7e3 ¤   ¤   ¤   ¤   /* Just an entry point */
409424 ¤   ¤   ¤   ¤   pState->stage = PSE_SkipHeader;
87a3a6 ¤   ¤   ¤   }
1dcdcb ¤   ¤   ¤   break;
5aaf5a
4ba823 ¤   ¤   ¤   case PSE_SkipHeader:
5cf776 ¤   ¤   ¤   {
7f23f3 ¤   ¤   ¤   ¤   pState->stage = PSE_KeepUntil;
1f6498 ¤   ¤   ¤   ¤   pState->next_stage = PSE_ParseHeader;
3f817d ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pDblNewlineBuf;
27a3a6 ¤   ¤   ¤   }
aacdcb ¤   ¤   ¤   break;
13af5a
8a7d29 ¤   ¤   ¤   case PSE_ParseHeader: /* Do all the mimePtr stuff */
41f776 ¤   ¤   ¤   {
b4e9db ¤   ¤   ¤   ¤   resetpos_buf(pState->pPrevBuf);
9faf5a
4dd50c ¤   ¤   ¤   ¤   unsigned int nPrevLen = poslen_buf(pState->pPrevBuf);
f697be ¤   ¤   ¤   ¤   char *pHeader = (char *) malloc(nPrevLen + 1);
bfaf5a
03dcb4 ¤   ¤   ¤   ¤   if (!pHeader)
2e72c3 ¤   ¤   ¤   ¤   {
3c9ab0 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
27e844 ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
562613 ¤   ¤   ¤   ¤   }
cfaf5a
9a33e6 ¤   ¤   ¤   ¤   strncpy(pHeader, getpos_buf(pState->pPrevBuf), nPrevLen);
b9de51 ¤   ¤   ¤   ¤   *(pHeader + nPrevLen) = '\0';
c1af5a
03a179 ¤   ¤   ¤   ¤   char *pCT = rfc822_extract_header(pHeader, "Content-Type:");
ce6a9e ¤   ¤   ¤   ¤   safefree(pHeader);
3daf5a
7ccef3 ¤   ¤   ¤   ¤   if (!pCT)
7472c3 ¤   ¤   ¤   ¤   {
889ab0 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
9ee844 ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
e02613 ¤   ¤   ¤   ¤   }
d6af5a
fdc025 ¤   ¤   ¤   ¤   *mimePtr = parse_make_mime_type(pCT);
b8c7a3 ¤   ¤   ¤   ¤   safefree(pCT);
d7af5a
297739 ¤   ¤   ¤   ¤   /* get boundary info */
fdd6de ¤   ¤   ¤   ¤   const char *cp = get_mime_parameter(*mimePtr, kBoundaryParamete¶
2d09aa rName);
6faf5a
5163c1 ¤   ¤   ¤   ¤   if (!cp)
f072c3 ¤   ¤   ¤   ¤   {
3b9ab0 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
f7e844 ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
ab2613 ¤   ¤   ¤   ¤   }
0faf5a
8c284d ¤   ¤   ¤   ¤   strcpy_buf(pState->pBoundaryBuf, "\r\n--");
607ece ¤   ¤   ¤   ¤   strcat_buf(pState->pBoundaryBuf, cp);
42cc2f ¤   ¤   ¤   ¤   // DO NOT free() cp
05af5a
32af5a
99ae4e ¤   ¤   ¤   ¤   resetpos_buf(pState->pBoundaryBuf);
bdaf5a
fe2e3d ¤   ¤   ¤   ¤   unsigned int nSkip = skipcount_buf(pState->pPrevBuf, pState->pB¶
47271e oundaryBuf);
536177 ¤   ¤   ¤   ¤   unsigned int nRemain = nPrevLen - nSkip;
--93ab 000a323ba43401101fb Page 8 of RFC1847.CPP
e0af5a
eb5506 ¤   ¤   ¤   ¤   pState->nLeftSpanCount = nRemain;
ddaf5a
4547db ¤   ¤   ¤   ¤   free_buf(pState->pPrevBuf);
3faf5a
bc497e ¤   ¤   ¤   ¤   pState->stage = PSE_SkipFirst;
80a3a6 ¤   ¤   ¤   }
d6cdcb ¤   ¤   ¤   break;
24af5a
57adc2 ¤   ¤   ¤   case PSE_SkipFirst:
8ff776 ¤   ¤   ¤   {
21047b ¤   ¤   ¤   ¤   pState->stage = PSE_IgnoreUntil;
c93a54 ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pBoundaryBuf;
f2dc4d ¤   ¤   ¤   ¤   pState->next_stage = PSE_PrePart;
6fa3a6 ¤   ¤   ¤   }
0acdcb ¤   ¤   ¤   break;
f9af5a
05d157 ¤   ¤   ¤   case PSE_PrePart:
a3f776 ¤   ¤   ¤   {
0c047b ¤   ¤   ¤   ¤   pState->stage = PSE_IgnoreUntil;
8e08f5 ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pNewlineBuf;
2903e3 ¤   ¤   ¤   ¤   pState->next_stage = PSE_OutPart;
b3a3a6 ¤   ¤   ¤   }
1ccdcb ¤   ¤   ¤   break;
5caf5a
cf0ef9 ¤   ¤   ¤   case PSE_OutPart:
858cf3 ¤   ¤   ¤   {¤
7d9702 ¤   ¤   ¤   ¤   pState->current_part++;
c4af5a
1a2c30 ¤   ¤   ¤   ¤   if (pState->current_part <= 2)
a572c3 ¤   ¤   ¤   ¤   {
7b778b ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_OutputUntil;
b83ab6 ¤   ¤   ¤   ¤   ¤   pState->pSearchBuf = pState->pBoundaryBuf;
8c724c ¤   ¤   ¤   ¤   ¤   pState->next_stage = PSE_PrePart;
bf2613 ¤   ¤   ¤   ¤   }
25fa07 ¤   ¤   ¤   ¤   else
473861 ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Done;
eea3a6 ¤   ¤   ¤   }
c7cdcb ¤   ¤   ¤   break;
aeaf5a
6dd2b5 ¤   ¤   ¤   case PSE_Done:
6df776 ¤   ¤   ¤   {
9e73b4 ¤   ¤   ¤   ¤   delpos_buf(pInBuf);
ffa3a6 ¤   ¤   ¤   }
5fcdcb ¤   ¤   ¤   break;
08af5a
687064 ¤   ¤   ¤   case PSE_Fail:
caf776 ¤   ¤   ¤   {
83cd39 ¤   ¤   ¤   ¤   return (RFC1847_FAIL);
caa3a6 ¤   ¤   ¤   }
36cdcb ¤   ¤   ¤   break;
ceaf5a
e9e1a2 ¤   ¤   ¤   /* ----- ----- */
7aaf5a
7ec74f ¤   ¤   ¤   case PSE_KeepUntil:
b033fc ¤   ¤   ¤   case PSE_IgnoreUntil:
6f1317 ¤   ¤   ¤   case PSE_OutputUntil:
fcf776 ¤   ¤   ¤   {
fd1651 ¤   ¤   ¤   ¤   int bFound = FALSE;
aa41b3 ¤   ¤   ¤   ¤   unsigned int nPrefixCount = 0, nAfterSkip = 0;
d6af5a
b36ca9 ¤   ¤   ¤   ¤   resetpos_buf(pState->pSearchBuf);
49af5a
ced636 ¤   ¤   ¤   ¤   const unsigned int nInLen = poslen_buf(pInBuf);
23138a ¤   ¤   ¤   ¤   const unsigned int nSearchLen = poslen_buf(pState->pSearchBuf);
edaf5a
5b6803 ¤   ¤   ¤   ¤   /* Did we have a partial span at the end of last buffer? */
91e564 ¤   ¤   ¤   ¤   if (pState->nLeftSpanCount > 0)
1872c3 ¤   ¤   ¤   ¤   {
f45b1d ¤   ¤   ¤   ¤   ¤   //unsigned int nRemainingCount = nSearchLen - (pState->nLef¶
07136e tSpanCount);
a3ae30 ¤   ¤   ¤   ¤   ¤
--854c 0008806be2a401101fb Page 9 of RFC1847.CPP
c37235 ¤   ¤   ¤   ¤   ¤   /* Check for completion of span */
c0d3be ¤   ¤   ¤   ¤   ¤   // If doesn't continue match, returns zero
adf632 ¤   ¤   ¤   ¤   ¤   // otherwise returns number of chars of pSearchBuf that hav¶
b84ba5 e been matched
3d73aa ¤   ¤   ¤   ¤   ¤   unsigned int nNewMatched = completecount_buf(pInBuf, pState¶
deece5 ->pSearchBuf, pState->nLeftSpanCount);
d1af5a
b6c76e ¤   ¤   ¤   ¤   ¤   if (nNewMatched == nSearchLen) /* complete match made */
0e4859 ¤   ¤   ¤   ¤   ¤   {
e741d1 ¤   ¤   ¤   ¤   ¤   ¤   bFound = TRUE;
2bcada ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = 0; /* No chars in this buffer are before¶
465186 ·the match */
203782 ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = nSearchLen - (pState->nLeftSpanCount); /* ¶
e6e0af Move buffer position to AFTER match */
b6af5a
ec2b92 ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = 0;
f21c89 ¤   ¤   ¤   ¤   ¤   }
1d5fea ¤   ¤   ¤   ¤   ¤   else if (nNewMatched == 0) /* match failed */
464859 ¤   ¤   ¤   ¤   ¤   {
82469e ¤   ¤   ¤   ¤   ¤   ¤   /* need to 'do' pState->nLeftSpanCount of pState->pSear¶
677243 chBuf */
38af5a
6e3e1c ¤   ¤   ¤   ¤   ¤   ¤   switch (pState->stage)
318fec ¤   ¤   ¤   ¤   ¤   ¤   {
ba19d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   case PSE_KeepUntil:
aaa898 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bufncat_buf(pState->pPrevBuf, pState->pSearchBu¶
58e8e9 f, pState->nLeftSpanCount);
898c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
51af5a
81969a ¤   ¤   ¤   ¤   ¤   ¤   ¤   case PSE_IgnoreUntil:
a5cde4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   /* Ignore -- do nothing */
e98c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
20531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
34b671 ¤   ¤   ¤   ¤   ¤   ¤   ¤   case PSE_OutputUntil:
6c164c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pState->pSearchBuf;
095851 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nOutputCount = pState->nLeftSpanCount;
be29a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = pState->stage; /* Stay¶
5f54ea ·in same stage */
d4443b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_DoOutput;
548c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
abdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
e3af5a
fb2b92 ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = 0;
6daf5a
6fa74d ¤   ¤   ¤   ¤   ¤   ¤   if (pState->stage == PSE_DoOutput)
8f655a ¤   ¤   ¤   ¤   ¤   ¤   ¤   { bForceJumpState = TRUE; continue; };
401c89 ¤   ¤   ¤   ¤   ¤   }
1dd696 ¤   ¤   ¤   ¤   ¤   else /* Continued to match, but not completed yet -- the in¶
781559 put buffer is smaller than the pSearchBuf */
c54859 ¤   ¤   ¤   ¤   ¤   {
1c77b2 ¤   ¤   ¤   ¤   ¤   ¤   // Remainder of pInBuf matches, so we need to gobble it
c83e87 ¤   ¤   ¤   ¤   ¤   ¤   delpos_buf(pInBuf);
f1953d ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = nNewMatched;
7446d0 ¤   ¤   ¤   ¤   ¤   ¤   continue; // We want to 'return', because we are done w¶
c94dc2 ith input
b81c89 ¤   ¤   ¤   ¤   ¤   }
1a2613 ¤   ¤   ¤   ¤   }
62af5a
4e6ca9 ¤   ¤   ¤   ¤   resetpos_buf(pState->pSearchBuf);
01af5a
a6adac ¤   ¤   ¤   ¤   if (!bFound)
b372c3 ¤   ¤   ¤   ¤   {
d50876 ¤   ¤   ¤   ¤   ¤   if (pState->pSearchBuf) // nSearchLen?
464859 ¤   ¤   ¤   ¤   ¤   {
11dfb6 ¤   ¤   ¤   ¤   ¤   ¤   // Find match of pSearchBuf, either complete or end-spa¶
678cce nning
6c4bd4 ¤   ¤   ¤   ¤   ¤   ¤   // return number of chars to skip before match
8ce747 ¤   ¤   ¤   ¤   ¤   ¤   unsigned int nSkip = skipcount_buf(pInBuf, pState->pSea¶
e4dfa7 rchBuf);
4613fb ¤   ¤   ¤   ¤   ¤   ¤   unsigned int nRemain = nInLen - nSkip;
eaaf5a
885c4a ¤   ¤   ¤   ¤   ¤   ¤   if (nRemain > nSearchLen) /* Found 'complete' */
--19d6 00075065865401101fb Page 10 of RFC1847.CPP
5b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
014f9d ¤   ¤   ¤   ¤   ¤   ¤   ¤   bFound = TRUE;
e94678 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = nSkip;
358037 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = nSearchLen;
61db3c ¤   ¤   ¤   ¤   ¤   ¤   }
3b1811 ¤   ¤   ¤   ¤   ¤   ¤   else /* Either not found or partial possible */
318fec ¤   ¤   ¤   ¤   ¤   ¤   {
544678 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = nSkip;
450ec1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = nRemain; /* Gobble up the remaining (k¶
19610c nown to match) */
891a70 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nLeftSpanCount = nRemain;
9ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
f51c89 ¤   ¤   ¤   ¤   ¤   }
794bd6 ¤   ¤   ¤   ¤   ¤   else
0d4859 ¤   ¤   ¤   ¤   ¤   {
ed3e6f ¤   ¤   ¤   ¤   ¤   ¤   nPrefixCount = nInLen;
1519db ¤   ¤   ¤   ¤   ¤   ¤   nAfterSkip = 0;
4d1c89 ¤   ¤   ¤   ¤   ¤   }
c82613 ¤   ¤   ¤   ¤   }
d3af5a
8f6ca9 ¤   ¤   ¤   ¤   resetpos_buf(pState->pSearchBuf);
0aaf5a
36db60 ¤   ¤   ¤   ¤   if (bFound) /* Found */
3972c3 ¤   ¤   ¤   ¤   {
b5af84 ¤   ¤   ¤   ¤   ¤   switch (pState->stage)
224859 ¤   ¤   ¤   ¤   ¤   {
230180 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_KeepUntil:
47894f ¤   ¤   ¤   ¤   ¤   ¤   ¤   bufncat_buf(pState->pPrevBuf, pInBuf, nPrefixCount ¶
6b4856 + nAfterSkip);
dc1db0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = pState->next_stage;
0b00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
23af5a
6ec6a6 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_IgnoreUntil: /* Ignore -- do nothing */
a4aab1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   incpos_buf(pInBuf, nPrefixCount + nAfterSkip);
431db0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = pState->next_stage;
3700eb ¤   ¤   ¤   ¤   ¤   ¤   break;
6094aa ¤   ¤   ¤   ¤   ¤   ¤
39f94f ¤   ¤   ¤   ¤   ¤   ¤   case PSE_OutputUntil:
599fe5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInBuf;
c5fac1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nOutputCount = nPrefixCount;
a68875 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = pState->next_stage;
ee02cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nAfteroutSkip = nAfterSkip;
bda63b ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_DoOutput;
db00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
b3af5a
b4e5b2 ¤   ¤   ¤   ¤   ¤   ¤   default:
b17b8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
e400eb ¤   ¤   ¤   ¤   ¤   ¤   break;
7f1c89 ¤   ¤   ¤   ¤   ¤   }
742613 ¤   ¤   ¤   ¤   }
75431e ¤   ¤   ¤   ¤   else /* not found */
c172c3 ¤   ¤   ¤   ¤   {
a5af84 ¤   ¤   ¤   ¤   ¤   switch (pState->stage)
064859 ¤   ¤   ¤   ¤   ¤   {
850180 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_KeepUntil:
a2894f ¤   ¤   ¤   ¤   ¤   ¤   ¤   bufncat_buf(pState->pPrevBuf, pInBuf, nPrefixCount ¶
794856 + nAfterSkip);
a200eb ¤   ¤   ¤   ¤   ¤   ¤   break;
4aaf5a
17c6a6 ¤   ¤   ¤   ¤   ¤   ¤   case PSE_IgnoreUntil: /* Ignore -- do nothing */
1baab1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   incpos_buf(pInBuf, nPrefixCount + nAfterSkip);
b500eb ¤   ¤   ¤   ¤   ¤   ¤   break;
3c94aa ¤   ¤   ¤   ¤   ¤   ¤
51f94f ¤   ¤   ¤   ¤   ¤   ¤   case PSE_OutputUntil:
149fe5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->pOutputBuf = pInBuf;
7ffac1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nOutputCount = nPrefixCount;
a8ec25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->afterout_stage = pState->stage; /* Same sta¶
cfec34 ge */
1302cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->nAfteroutSkip = nAfterSkip;
16a63b ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_DoOutput;
6c00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
75af5a
--550c 00144d1885e401101fb Page 11 of RFC1847.CPP
e9e5b2 ¤   ¤   ¤   ¤   ¤   ¤   default:
4f7b8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   pState->stage = PSE_Fail;
9e00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
851c89 ¤   ¤   ¤   ¤   ¤   }
da2613 ¤   ¤   ¤   ¤   }
86a3a6 ¤   ¤   ¤   }
c6cdcb ¤   ¤   ¤   break;
b1af5a
8de6f1 ¤   ¤   ¤   case PSE_DoOutput:
4ff776 ¤   ¤   ¤   {
231c35 ¤   ¤   ¤   ¤   // Need to distiguish between the two output paths
07ad80 ¤   ¤   ¤   ¤   BufTypePtr p = NULL;
99af5a
4a4810 ¤   ¤   ¤   ¤   switch (pState->current_part)
ef72c3 ¤   ¤   ¤   ¤   {
c97ea7 ¤   ¤   ¤   ¤   ¤   case 1: p = pOutPart1;
9314c3 ¤   ¤   ¤   ¤   ¤   break;
4eaf5a
4a90fb ¤   ¤   ¤   ¤   ¤   case 2: p = pOutPart2;
8114c3 ¤   ¤   ¤   ¤   ¤   break;
14af5a
139592 ¤   ¤   ¤   ¤   ¤   default: pState->stage = PSE_Fail;
4414c3 ¤   ¤   ¤   ¤   ¤   break;
942613 ¤   ¤   ¤   ¤   }
d8af5a
89d00c ¤   ¤   ¤   ¤   if (p)
5d72c3 ¤   ¤   ¤   ¤   {
54325c ¤   ¤   ¤   ¤   ¤   unsigned int nOut = bufnins_buf(p, pState->pOutputBuf, pSta¶
396709 te->nOutputCount);
a3af5a
2422fd ¤   ¤   ¤   ¤   ¤   // Need to check if not everything was outputted
a89029 ¤   ¤   ¤   ¤   ¤   // If not -- buffer is full, adjust 'nOutputCount', return ¶
c63875 BUFFERFULL;
eebed7 ¤   ¤   ¤   ¤   ¤   pState->nOutputCount -= nOut;
9caf5a
1a80d3 ¤   ¤   ¤   ¤   ¤   if ((pState->nOutputCount) > 0) /* Anything left to output ¶
887fe0 */
64a6fe ¤   ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL);
b7af5a
e2f366 ¤   ¤   ¤   ¤   ¤   pState->stage = pState->afterout_stage;
2971c0 ¤   ¤   ¤   ¤   ¤   if (pState->nAfteroutSkip > 0)
cf2c09 ¤   ¤   ¤   ¤   ¤   ¤   incpos_buf(pState->pOutputBuf, pState->nAfteroutSkip);
e22613 ¤   ¤   ¤   ¤   }
10fa07 ¤   ¤   ¤   ¤   else
f6655e ¤   ¤   ¤   ¤   ¤   return (RFC1847_BUFFERFULL); /* No output buffer */
9a2b85 ¤   ¤   ¤   ¤
65a3a6 ¤   ¤   ¤   }
22cdcb ¤   ¤   ¤   break;
f30fe4 ¤   ¤   }
b39371 ¤   }
05af5a
c57e63 ¤   return (RFC1847_COMPLETED);
44efe6 }
--4e4c 000f268d17e401101fc Page 1 of RFC1847.H
bc38e5 /*
cf9756 ·* ·Functions to aide creation and parsing of MIME RFC1847 objects.
b5775e ·*
d69382 ·* ·Filename: RFC1847.H
02775e ·*
6d2ce1 ·* ·Last Edited: Monday, September 30, 1996
23775e ·*
1e005b ·* ·Author: Scott Manjourides
e4775e ·*
f9ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
9c775e ·*
77c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
a2775e ·*
a3495d ·*/
2caf5a
942f2f /* =========================================================================
93af5a
152315 ···- WHAT -
97af5a
609d62 ···The functions provided here allow easy creation and parsing of RFC1847
f2a0d8 ···MIME structure using buffer-based piping. For file-based RFC1847
29bb13 ···interactions use FILE1847.CPP.
09af5a
44af5a
c5fff5 ···- DESIGN -
f1af5a
ef9344 ···The intent of the design of these functions is to allow easy integration
439952 ···with most other buffer-based libraries. The buffers used here are all of
f6af5d ···the 'BufType' type, as defined in BUFTYPE.CPP. This design was chosen to
f337f1 ···make easy transition to other common buffers, and functions are provided
7c5dd3 ···to do just such conversations (see BUFTYPE.CPP).
d5af5a
ff7be5 ···Another major concern in the design of these functions is that of piping.
445614 ···We tried to assure that the buffer-based approach we chose would allow
a66fb3 ···easy transition to and from existing buffer-based libraries. All buffers
e03484 ···handled here have inherent size, max size, and position. The
bbd78f ···combination of these three state variables for each buffer gives the
e016b4 ···flexibility for either push (producer driven) or pull (consumer driven)
07d068 ···piping of data. This flexibility should allow these functions to easily
eeb2f2 ···be used in many applications.
75af5a
23b51b ···The mechanism for producing and consuming data is identical for both
6d2b93 ···the parse and create functions.
d1af5a
3daf5a
e22528 ···- HOW TO USE -
44af5a
004ed5 ···=============
e3cd8d ···Creating 1847
df4ed5 ···=============
20af5a
87a524 ···You will provide the top-most MIME type in an emsMIMEtype structure. This
2520ed ···MIME type structure should contain all required content-type parameters,
b03c7a ···except "boundary", which will be created and added for you.
88af5a
d8f2a6 ···You also need to provide two binary byte streams, one for each part of
2dd82b ···the MIME structure. These binary streams are presented to rfc1847_create
1aebff ···using buffer structures defined in BUFTYPE.H. Each buffer should be
285244 ···filled using the appropriate _buf() call from BUFTYPE.H and passed to
264856 ···rfc1847_create to be consumed.
b0af5a
5797da ···The formatted MIME rfc1847 structure is returned in the output buffer,
a0c5c7 ···without changing the buffer's size. This means that it is possible to
b92eb1 ···have the output buffer fill before the input buffer(s) are completely
8e466e ···consumed. In this case rfc1847_create() will return RFC1847_BUFFERFULL.
8a61b3 ···When this value is returned, the caller should simply consume the output
6251a4 ···buffer and re-call rfc1847_create(). The input buffers will retain any
78a91e ···partially consumed status, and thus should not be altered.
c9af5a
1abfbc ···Because the byte streams are presented in pieces through the use of a
f6b042 ···buffer, the question of indicating the end of a stream needs to be
f2e07d ···addressed. The implied ordering of the two streams (part 1, then part 2)
--b624 0005ae16f1e401101fc Page 2 of RFC1847.H
b1be1e ···gives some help in solving this problem. If you need to chop part 1 into
31081a ···multiple buffer pieces, then you will need to NOT supply part 2 until
ddca62 ···part 1 is completed. This is done by passing NULL in place of the buffer.
f0928b ···As soon as the part 2 is not NULL, part 1 is assumed to be completed.
023619 ···Part 2 is assumed to be completed when the part 2 buffer is NULL after
c00951 ···is was non-NULL.
5caf5a
b84460 ···Example with part 1 using 3 buffer blocks:
24af5a
f0def8 ···Part 1 ······Part 2
230814 ···------ ······------
3a0353 ···Block 1 ·····NULL
2884bd ···Block 2 ·····NULL
265a1e ···Final block ·Part 2
d54f1b ···NULL ········NULL ···<-- Indicates you are finished, does cleanup
3faf5a
d6ff1d ···Of course, if everything fits into one buffer, the entire creation can
1b7a94 ···be done in two calls. First call with both valid parts, then finish with
4c77b4 ···the required NULL-NULL cleanup call.
24af5a
fc0015 ···The state parameter should be created before the first call, passed
f4eb58 ···(untouched) between calls, and deleted after the final call.
3caf5a
7ef4ba ···============
b85664 ···Parsing 1847
3ff4ba ···============
7be8c6 ···
d22f91 ···In much the same way as creating 1847, you must provide the input 1847
3d722a ···MIME structure in the form of a buffer or buffers as defined by BUFTYPE.H.
d9af5a
066aa5 ···When the parser returns RFC1847_BUFFERFULL, you should clear both output
6541bb ···buffer (one each for both parts) before re-calling.
77af5a
a597f2 ···The MIME type of the parsed 1847 structure is returned as an emsMIMEtype
5e509e ···structure.
b3af5a
6d0015 ···The state parameter should be created before the first call, passed
b1eb58 ···(untouched) between calls, and deleted after the final call.
04af5a
6fb61c ···========================================================================= */
03af5a
7b0453 #ifndef RFC1847_H
47d90a #define RFC1847_H
dcaf5a
03568d #include <windows.h> /* Must be included for ems-win.h */
f0fbd1 #include "ems-win.h"
4faf5a
64d3fb #include "BUFTYPE.H"
83af5a
a07890 /* ------------------------------------------------------------------------- */
ffaf5a
9c3e7d /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
7b4f34 /* THESE STRCUTURES AND TYPES ARE TO BE CONSIDERED OPAQUE TO THE USER */
46c76b ¤   /* Internally used values -- irrelevant to the avaerae user */
fa0f27 ¤   typedef enum {
c95c17 ¤   ¤   CSE_Start,
04ad9a ¤   ¤   CSE_DoHeader,
9677e2 ¤   ¤   CSE_DoBoundary,
eadc2a ¤   ¤   CSE_DoPart,
c35e42 ¤   ¤   CSE_DoOutput,
86ad13 ¤   ¤   CSE_Done,
a0fec1 ¤   ¤   CSE_Fail
6d9a50 ¤   } CreateStageEnum;
82af5a
69c76b ¤   /* Internally used values -- irrelevant to the avaerae user */
910f27 ¤   typedef enum {
f7d3e1 ¤   ¤   PSE_Start,
19f335 ¤   ¤   PSE_SkipHeader,
d37efa ¤   ¤   PSE_ParseHeader,
fbc2fd ¤   ¤   PSE_SkipFirst,
3c61eb ¤   ¤   PSE_PrePart,
5abe45 ¤   ¤   PSE_OutPart,
--fde0 000c2c0c347401101fc Page 3 of RFC1847.H
b60b28 ¤   ¤   PSE_Done,
61a9f9 ¤   ¤   PSE_Fail,
c5a870 ¤   ¤   PSE_KeepUntil,
9cd41d ¤   ¤   PSE_IgnoreUntil,
65f4f6 ¤   ¤   PSE_OutputUntil,
fab785 ¤   ¤   PSE_DoOutput
d463bd ¤   } ParseStageEnum;
9eaf5a
dab290 ¤   /* Create-state strucutre -- irrelevant to the avaerae user */
3fee21 ¤   typedef struct createState {
629de4 ¤   ¤   int bInitialized;
99950a ¤   ¤   CreateStageEnum stage, next_stage, afterout_stage;
540f1d ¤   ¤   unsigned int current_part;
92df53 ¤   ¤   BufTypePtr pTmpBuf, pOutputBuf;
4cbf6c ¤   ¤   char *pBoundaryStr;
a19ddc ¤   } createState;
6daf5a
d83744 ¤   typedef createState *createStatePtr;
72af5a
2e4eb2 ¤   /* Parse-state strucutre -- irrelevant to the avaerae user */
a06db5 ¤   typedef struct parseState {
859de4 ¤   ¤   int bInitialized;
1f27b8 ¤   ¤   ParseStageEnum stage, next_stage, afterout_stage;
3d4f3e ¤   ¤   unsigned int current_part, nOutputCount, nAfteroutSkip, nLeftSpanCount;
28c74e ¤   ¤   BufTypePtr /*pTmpBuf,*/ pOutputBuf, pSearchBuf, pPrevBuf, pBoundaryBuf,
c7d0bc ¤   ¤   ¤   pDblNewlineBuf, pNewlineBuf;
7636bd ¤   } parseState;
04af5a
00c0e5 ¤   typedef parseState *parseStatePtr;
896bc8 /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
7eaf5a
d38e7e /* Return values for parse and create functions */
723761 enum { RFC1847_FAIL, RFC1847_COMPLETED, RFC1847_BUFFERFULL };
ebaf5a
d27890 /* ------------------------------------------------------------------------- */
46af5a
b738e5 /*
1cae27 ·* ·Allocates and returns a pointer to an initialized createState structure.
36a3b2 ·* ··
8382c9 ·* ·NOTE: The user of this function is responsible for properly
a0f6d8 ·* ·······deleting the returned data by calling delete_create_state()
8361f8 ·* ·······when the state data is no longer needed.
5d775e ·*
f8b7ce ·* ·No arguments.
4a775e ·*
082d82 ·* ·Pointer to newly created createState structure. NULL if error.
1d495d ·*/
bd16c6 createStatePtr new_create_state();
f1af5a
8938e5 /*
ee739f ·* ·Frees all memory within the state structure, including the structure
98ea81 ·* ·itself.
f7a3b2 ·* ··
bdf8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
f2775e ·*
ad6a22 ·* ·Args:
b3f565 ·* ···pState [IN] Pointer to the state structure to be deleted.
fa775e ·*
0403d6 ·* ·No return value.
92495d ·*/
398214 void delete_create_state(createStatePtr pState);
c2af5a
0638e5 /*
24b5e4 ·* ·Allocates and returns a pointer to an initialized parseState structure.
82a3b2 ·* ··
a282c9 ·* ·NOTE: The user of this function is responsible for properly
fbf6d8 ·* ·······deleting the returned data by calling delete_create_state()
7f61f8 ·* ·······when the state data is no longer needed.
b9775e ·*
f7b7ce ·* ·No arguments.
43775e ·*
c287bd ·* ·Pointer to newly created parseState structure. NULL if error.
--0018 00152bf5654401101fc Page 4 of RFC1847.H
47495d ·*/
bf2c1b parseStatePtr new_parse_state();
adaf5a
d138e5 /*
07739f ·* ·Frees all memory within the state structure, including the structure
50ea81 ·* ·itself.
25a3b2 ·* ··
96f8aa ·* ·NOTE: The pointer argument should be assumed invalid after this call.
b8775e ·*
686a22 ·* ·Args:
19f565 ·* ···pState [IN] Pointer to the state structure to be deleted.
69775e ·*
fa03d6 ·* ·No return value.
00495d ·*/
22db18 void delete_parse_state(parseStatePtr pState);
ffaf5a
0338e5 /*
219c8e ·* ·Creates RFC1847 MIME structure.
38a3b2 ·* ··
686a22 ·* ·Args:
16379d ·* ···mimePtr ·[IN] ····MIME content info, used to create the MIME headers.
523c43 ·* ···pOutBuf ·[OUT] ···Output buffer (RFC1847 MIME structure).
e32dc1 ·* ···pInPart1 [IN] ····Input buffer used for first part.
e6822a ·* ···pInPart2 [IN] ····Input buffer used for second part.
ce6d62 ·* ···pState ··[IN/OUT] Pointer to state info, caller must preserve.
d2775e ·*
d78a08 ·* ·Return values:
11ec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
8b4815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
f2eeac ·* ···RFC1847_FAIL ·······Parsing error.
a9495d ·*/
eb883d int rfc1847_create(emsMIMEtypeP mimePtr,
9ae65d ¤   ¤   ¤   ¤   ···BufTypePtr pOutBuf,
ee3c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
68d359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
58ef1b ¤   ¤   ¤   ¤   ···createStatePtr pState);
11af5a
b438e5 /*
76070c ·* ·Parses RFC1847 MIME structure, returning MIME info and separated parts.
4ba3b2 ·* ··
8a6a22 ·* ·Args:
1d047b ·* ···mimePtr ··[OUT] ···Returns a pointer to a newly created emsMIMEtype.
ae47d4 ·* ···pOutPart1 [OUT] ···Output buffer, part 1.
3a5ad7 ·* ···pOutPart2 [OUT] ···Output buffer, part 2.
05183e ·* ···pInBuf ···[IN] ····Input buffer containing full RFC1847 MIME structure.
45cf05 ·* ···pState ···[IN/OUT] Pointer to state info, caller must preserve.
54775e ·*
b48a08 ·* ·Return values:
23ec93 ·* ···RFC1847_COMPLETED ··Input was sucessfully and completely parsed.
734815 ·* ···RFC1847_BUFFERFULL ·The output buffer is full; input partially parsed.
e3eeac ·* ···RFC1847_FAIL ·······Parsing error.
69495d ·*/
fb892a int rfc1847_parse(emsMIMEtypeP *mimePtr,
3a4889 ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart1,
44a7ed ¤   ¤   ¤   ¤   ··BufTypePtr pOutPart2,
91824b ¤   ¤   ¤   ¤   ··BufTypePtr pInBuf,
aba53d ¤   ¤   ¤   ¤   ··parseStatePtr pState);
acaf5a
52dd50 #endif /* RFC1847_H */¶
--c182 00073334dde401101fd Page 1 of RFC822.CPP
bc38e5 /*
ebb257 ·* ·Functions to aide manipulation of MIME RFC822 headers.
8b775e ·*
8f60b9 ·* ·Filename: RFC822.cpp
c6775e ·*
772ba5 ·* ·Last Edited: July 15, 1996
32775e ·*
b9005b ·* ·Author: Scott Manjourides
ce775e ·*
77cbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
23ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
74775e ·*
c3c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
d2495d ·*/
59af5a
8fbea3 #include <stdlib.h>
ad5e84 #include <malloc.h>
d5324c #include <string.h>
6aaf5a
460043 #include <istream.h> // ifstream class
3eb6e4 #include <fstream.h> // ofstream class
6caf5a
056bd2 #include "rfc822.h"
4eaf5a
57c51a /* ========================================================================= */
b3af5a
861b61 const char *kRFC822_MustBeQuoted = "()<>@,;:\\\"/[]?= ";
ce35fe const char *kRFC822_MustBeEscaped = "\\\"";
917282 const char *kRFC822_EOL = "\r\n";
bbaf5a
46c51a /* ========================================================================= */
abaf5a
42dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
5eaf5a
3cc51a /* ========================================================================= */
7caf5a
5a38e5 /*
c26550 ·* ·Find next RFC822 token in given string, copying it into a newly created
95bdf0 ·* ·string. Advance pointer past token and any following whitespace.
42a3b2 ·* ··
6e3bed ·* ·NOTE: The user of this function is responsible for freeing returned
006c68 ·* ·······string.
8a775e ·*
fe6a22 ·* ·Args:
5c656a ·* ··cpp [IN/OUT] Handle (pointer-to-pointer) of RFC822 string to extract from
8d775e ·*
1d79f1 ·* ·Returns: String containing next token, NULL if error.
51e88e ·* ········Moves cpp to first non-whitespace character AFTER extracted token
bd495d ·*/
735bd5 char *rfc822_extract_token(char **cpp)
d0bb36 {
75302c ¤   char *start, *cp = *cpp;
25af5a
e2242b ¤   cp = rfc822_skipws(cp); // Skip white space
60fe0f ¤   start = cp;
dcaf5a
9f07ef ¤   cp = rfc822_skipword(cp); // Skip word
f1af5a
02b61f ¤   if (cp > start)
20c7a1 ¤   {
d66f29 ¤   ¤   const int len = cp - start;
de7b9e ¤   ¤   char *buf = (char *) malloc(len + 1);
26af5a
b49402 ¤   ¤   if (buf)
df5b34 ¤   ¤   {
451e8d ¤   ¤   ¤   rfc822_unquote_strcpy(buf, start, len);
b2962d ¤   ¤   ¤   *cpp = rfc822_skipws(cp);
70af5a
c1f358 ¤   ¤   ¤   return (buf);
e20fe4 ¤   ¤   }
ef9371 ¤   }
73af5a
--2267 0006fa8882b401101fd Page 2 of RFC822.CPP
7d867d ¤   return (NULL); // No token to extract
83efe6 }
4caf5a
03e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
b0af5a
8838e5 /*
087334 ·* ·Advances to next non-whitespace character in string. This includes
0bd4de ·* ·ignoring RFC822 comments.
74a3b2 ·* ··
1e6a22 ·* ·Args:
602c45 ·* ··cp [IN] RFC822 string
93775e ·*
e4bac7 ·* ·Returns: Pointer to next non-whitespace character.
8f495d ·*/
90c538 char *rfc822_skipws(char *cp)
62bb36 {
9143ab ¤   do {
1af940 ¤   ¤   while (*cp == ' ') // Skip spaces
66b3d6 ¤   ¤   ¤   cp++;
b1af5a
56a2f7 ¤   ¤   if (*cp == '(') // A comment?
225b34 ¤   ¤   {
8e829c ¤   ¤   ¤   int nested = 1;
22af5a
6a4840 ¤   ¤   ¤   while ((*++cp) && (nested)) // Find end of comment
a1f776 ¤   ¤   ¤   {
ebf486 ¤   ¤   ¤   ¤   switch (*cp)
3072c3 ¤   ¤   ¤   ¤   {
9a53f3 ¤   ¤   ¤   ¤   ¤   case '(': nested++;
e814c3 ¤   ¤   ¤   ¤   ¤   break;
59af5a
3bb05a ¤   ¤   ¤   ¤   ¤   case ')': nested--;
3f14c3 ¤   ¤   ¤   ¤   ¤   break;
42af5a
c70e93 ¤   ¤   ¤   ¤   ¤   case '\\': // Escape character
b1b66b ¤   ¤   ¤   ¤   ¤   ¤   if ((*(cp+1)) != '\0') // Check for end-of-string
e2f0a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   cp++;
bc14c3 ¤   ¤   ¤   ¤   ¤   break;
c8af5a
59273b ¤   ¤   ¤   ¤   ¤   case '\"': // Quote inside comment
a9120c ¤   ¤   ¤   ¤   ¤   ¤   while ((*cp) && (*++cp != '\"')) // Go 'til end·
5c8868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·// of quote
d14cb9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if ((*cp == '\\') && ((*(cp+1)) != '\0'))
26f61f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   cp++; // Escaped character inside quote·
d6572c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // -- inside comment (eeek!)
3f14c3 ¤   ¤   ¤   ¤   ¤   break;
ba2613 ¤   ¤   ¤   ¤   }
50a3a6 ¤   ¤   ¤   }
0e0fe4 ¤   ¤   }
a91689 ¤   } while (*cp == ' ');
f3af5a
8b02c0 ¤   return cp;
1aefe6 }
7daf5a
59e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49af5a
7538e5 /*
668bdc ·* ·Advances to next character in string directly after the current token.
f2a9fc ·* ·The first character must be the beginning of a valid token or end of
1f8505 ·* ·string (ie. all whitespace must be skipped BEFORE calling this function).
e8775e ·*
be6a22 ·* ·Args:
332c45 ·* ··cp [IN] RFC822 string
fb775e ·*
a9e27b ·* ·Returns: Pointer to next valid whitespace character.
7e495d ·*/
c52dcb char *rfc822_skipword(char *cp)
f1bb36 {
09bc70 ¤   int bInQuotes = 0;
c2af5a
884af4 ¤   // First character must be a quote to be valid double-quoted string
6f571c ¤   if (*cp == '\"')
--b7d8 0007521f316401101fd Page 3 of RFC822.CPP
f7c7a1 ¤   {
03c6c8 ¤   ¤   bInQuotes = 1;
7c3663 ¤   ¤   cp++;
aa9371 ¤   }
2867c5 ¤
8743d2 ¤   while (*cp)
36c7a1 ¤   {
4c7a14 ¤   ¤   if (strchr(kRFC822_MustBeQuoted, *cp))
135b34 ¤   ¤   {
30bb0d ¤   ¤   ¤   if (!bInQuotes) // Found a character that should be double-quoted, ¶
d05cd2 but is not
e06c6a ¤   ¤   ¤   ¤   return (cp);
21af5a
31a0a0 ¤   ¤   ¤   // Now we know we are inside a double-quoted string
60af5a
0ac0db ¤   ¤   ¤   switch (*cp)
68f776 ¤   ¤   ¤   {
9725ac ¤   ¤   ¤   ¤   case '\"': return (cp+1); // End double-quote
bd14c3 ¤   ¤   ¤   ¤   ¤   break;
86555d ¤   ¤   ¤   ¤   case '\\': cp++; // Escape character, skip next
6714c3 ¤   ¤   ¤   ¤   ¤   break;
7d8da2 ¤   ¤   ¤   ¤   default: // nothing
e214c3 ¤   ¤   ¤   ¤   ¤   break;
28a3a6 ¤   ¤   ¤   }
040fe4 ¤   ¤   }
40af5a
2a3663 ¤   ¤   cp++;
4a9371 ¤   }
58af5a
77a86d ¤   return (cp);
00efe6 }
a5af5a
8ee6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
94af5a
0b38e5 /*
a6a539 ·* ·Calculates the length of the given text string if it were converted
f553aa ·* ·to an RFC822 string.
b6775e ·*
366a22 ·* ·Args:
1cdfd1 ·* ··cp [IN] Text string
f2775e ·*
71c1f0 ·* ·Returns: Equivalent RFC822 length of given text.
45495d ·*/
ea36fa unsigned int rfc822_quoted_strlen(char *cp)
bfbb36 {
3c0c19 ¤   unsigned int len = 0, bQuoted = 0;
b3af5a
b243d2 ¤   while (*cp)
3ec7a1 ¤   {
2a7cab ¤   ¤   len++;
eaaf5a
9b7a19 ¤   ¤   if ((!bQuoted) && (strchr(kRFC822_MustBeQuoted, *cp) != NULL))
48879d ¤   ¤   ¤   bQuoted = 1;
bfaf5a
3f3ac6 ¤   ¤   if (strchr(kRFC822_MustBeEscaped, *cp) != NULL)
20bc2c ¤   ¤   ¤   len++, bQuoted = 1;
f6af5a
ab3663 ¤   ¤   cp++;
009371 ¤   }
b5af5a
9b8be2 ¤   if (bQuoted)
797cbd ¤   ¤   len += 2; // Quotes
deaf5a
9b664d ¤   return (len);
05efe6 }
caaf5a
b6e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ffaf5a
2238e5 /*
2eb4be ·* ·Copies and converts the source text string to a destination
c027ba ·* ·RFC822 string. The source must be NULL terminated, and the
75c297 ·* ·destination will be NULL terminated.
--8252 000acbb647a401101fd Page 4 of RFC822.CPP
4f775e ·*
df6a22 ·* ·Args:
766d68 ·* ··dst [OUT] RFC822 string
e2ce7b ·* ··src [IN] ·Text string
42775e ·*
3f50ce ·* ·Returns: Pointer to destination NULL termination.
ce495d ·*/
09184e char *rfc822_quote_strcpy(char *dst, const char *src)
f0bb36 {
a9ae2a ¤   const unsigned int bQuoted =·
fa9b35 ¤   ¤   ( strpbrk(src, kRFC822_MustBeQuoted) ? 1 : 0 );
aeaf5a
da8be2 ¤   if (bQuoted)
ca2355 ¤   ¤   *dst++ = '\"';
1baf5a
f9abe7 ¤   while (*src)
b6c7a1 ¤   {
34885c ¤   ¤   if (strchr(kRFC822_MustBeEscaped, *src) != NULL)
8f35b3 ¤   ¤   ¤   *dst++ = '\\';
89af5a
c8b539 ¤   ¤   *dst++ = *src++;
1e9371 ¤   }
78af5a
2d8be2 ¤   if (bQuoted)
8f2355 ¤   ¤   *dst++ = '\"';
f9af5a
22064c ¤   *dst = '\0';
99af5a
16d7c2 ¤   return (dst);
5fefe6 }
9baf5a
74e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
baaf5a
2b38e5 /*
f3a027 ·* ·Copies and converts the source RFC822 string to a destination
e8f16a ·* ·text string. The source must be NULL terminated, and the
3bc297 ·* ·destination will be NULL terminated.
8a775e ·*
646a22 ·* ·Args:
d12fe1 ·* ··dst [OUT] Text string
4a7fc2 ·* ··src [IN] ·RFC822 string
308f1f ·* ··len [IN] ·Maximum charcters to copy; Zero implies whole string
ca775e ·*
7c50ce ·* ·Returns: Pointer to destination NULL termination.
90495d ·*/
905918 char *rfc822_unquote_strcpy(char *dst, const char *src, unsigned int len)
dabb36 {
fd2666 ¤   // If 'len' is provided (ie. >0) then only len chars will be copied
c5a5fb ¤   // Otherwise, copy 'til end-of-string
9e1f00 ¤   char *end;
0d96ef ¤   unsigned int bEscaped = 0;
62af5a
990935 ¤   end = strchr(src, '\0');
2aaf5a
df15aa ¤   if ((len > 0) && ((src + len) < end))
615d8c ¤   ¤   end = (char *) src + len;
2daf5a
a8391e ¤   while (src < end)
c6c7a1 ¤   {
ac15c7 ¤   ¤   if (bEscaped)
a845d0 ¤   ¤   ¤   bEscaped = 0;
dc0e1d ¤   ¤   else
395b34 ¤   ¤   {
fd36a5 ¤   ¤   ¤   switch (*src)
20f776 ¤   ¤   ¤   {
db6b5b ¤   ¤   ¤   ¤   case '\\':¤ bEscaped = 1;
9e06b3 ¤   ¤   ¤   ¤   case '\"':¤ src++;
55816f ¤   ¤   ¤   ¤   ¤   ¤   ¤   continue;
49f622 ¤   ¤   ¤   ¤   break;
eaa3a6 ¤   ¤   ¤   }
070fe4 ¤   ¤   }
acaf5a
--4435 00039cd6ccd401101fd Page 5 of RFC822.CPP
47b539 ¤   ¤   *dst++ = *src++;
839371 ¤   }
67af5a
5b064c ¤   *dst = '\0';
15af5a
0a9f8e ¤   return dst;
f8efe6 }
adaf5a
dce6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
6daf5a
a838e5 /*
73cdeb ·* ·Finds and extracts a header line from a full multi-lined header. All
9146fd ·* ·unfolding (removing newlines) is done before header line is returned.
af775e ·*
a5322b ·* ·NOTE: The user of this function is responsible for freeing the
5ac8a5 ·* ·······returned string.
39775e ·*
126a22 ·* ·Args:
720990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
6fb2b8 ·* ··pLinePrefix [IN] Prefix of header line to extract
45775e ·*
83d4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
b8495d ·*/
42782d char *rfc822_extract_header(const char *pFullHeader, const char *pLinePrefix)
17bb36 {
334ae6 ¤   const char *kNewline = "\r\n";
3d74be ¤   const unsigned int kNewlineLen = (2);
29cba9 ¤   const unsigned int nPreLen = strlen(pLinePrefix);
9eaf5a
154724 ¤   char *pStart, *pEnd, *pBuf, *pPos, *pRetBuf;
6eaf5a
dbdbe4 ¤   if (nPreLen < 1)
698021 ¤   ¤   return (NULL);
3daf5a
c2ae69 ¤   pStart = (char *) pFullHeader;
4eaf5a
06737d ¤   /* Find first 'line' which matches prefix */
5f978b ¤   while ((pStart) && (strnicmp(pStart, pLinePrefix, nPreLen) != 0))
0e9cb8 ¤   ¤   if (pStart = strstr(pStart, kNewline))
d2d79f ¤   ¤   ¤   pStart += kNewlineLen;
dbaf5a
ef5b13 ¤   if (!pStart)
a23445 ¤   ¤   return (NULL); /* Not found */
1daf5a
89a1c1 ¤   /* Find the end of this header line */
df91d1 ¤   for (pEnd = strstr(pStart, kNewline); (pEnd != NULL); pEnd =
6cd06b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strstr(pEnd, kNewline))
b3c7a1 ¤   {
2a34cb ¤   ¤   pPos = pEnd + kNewlineLen;
a6af5a
06e88f ¤   ¤   /* Does header line continue on next line? */
7f6e77 ¤   ¤   if ((*pPos == ' ') || (*pPos == '\t'))
4cffd4 ¤   ¤   ¤   pEnd = pPos;
e90e1d ¤   ¤   else
a0cdcb ¤   ¤   ¤   break;
cc9371 ¤   }
59af5a
5ff420 ¤   /* If we ran off the end of the string, then the end·
a42e7e ¤   ¤   is the last char in the string */
a4d3e6 ¤   if (pEnd == NULL)
79f3cd ¤   ¤   pEnd = strchr(pStart, '\0');
6f67c5 ¤
af726e ¤   pBuf = pRetBuf = (char *) malloc(pEnd - pStart + 1); /* Max length·
37195c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   of output string */
0eaf5a
c68bd3 ¤   for (pPos = pStart; pPos < pEnd; pPos++)
f6c7a1 ¤   {
23bc1a ¤   ¤   if (strncmp(pPos, kNewline, kNewlineLen) == 0) /* We're at a newline */
f1e841 ¤   ¤   ¤   pPos += kNewlineLen; /* Skip over newline */
19af5a
89da85 ¤   ¤   *pBuf++ = *pPos;
399371 ¤   }
--4f19 00028eb3482401101fd Page 6 of RFC822.CPP
e0af5a
bbcdc5 ¤   *pBuf = '\0';
0caf5a
3d709e ¤   return (pRetBuf);
bfefe6 }
f2af5a
5eaf5a
84fef3 // Finds header and REMOVES that header line from the full header
c75201 char *rfc822_remove_header(char *pFullHeader, const char *pLinePrefix)
0cbb36 {
924ae6 ¤   const char *kNewline = "\r\n";
9074be ¤   const unsigned int kNewlineLen = (2);
7dcba9 ¤   const unsigned int nPreLen = strlen(pLinePrefix);
fbaf5a
ac4724 ¤   char *pStart, *pEnd, *pBuf, *pPos, *pRetBuf;
2caf5a
84dbe4 ¤   if (nPreLen < 1)
3e8021 ¤   ¤   return (NULL);
f4af5a
15ae69 ¤   pStart = (char *) pFullHeader;
a2af5a
82737d ¤   /* Find first 'line' which matches prefix */
cc978b ¤   while ((pStart) && (strnicmp(pStart, pLinePrefix, nPreLen) != 0))
1c9cb8 ¤   ¤   if (pStart = strstr(pStart, kNewline))
23d79f ¤   ¤   ¤   pStart += kNewlineLen;
bfaf5a
b95b13 ¤   if (!pStart)
393445 ¤   ¤   return (NULL); /* Not found */
8baf5a
e1a1c1 ¤   /* Find the end of this header line */
1a310b ¤   for (pEnd = strstr(pStart, kNewline); (pEnd != NULL);·
42375f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pEnd = strstr(pEnd, kNewline))
cfc7a1 ¤   {
7934cb ¤   ¤   pPos = pEnd + kNewlineLen;
55af5a
3ee88f ¤   ¤   /* Does header line continue on next line? */
936e77 ¤   ¤   if ((*pPos == ' ') || (*pPos == '\t'))
a9ffd4 ¤   ¤   ¤   pEnd = pPos;
400e1d ¤   ¤   else
3ccdcb ¤   ¤   ¤   break;
3d9371 ¤   }
76af5a
e6b2d7 ¤   /* If we ran off the end of the string,·
469a5f ¤   ¤   ¤   then the end is the last char in the string */
6bd3e6 ¤   if (pEnd == NULL)
a9f3cd ¤   ¤   pEnd = strchr(pStart, '\0');
2a67c5 ¤
c1b411 ¤   pBuf = pRetBuf = (char *) malloc(pEnd - pStart + 1); /* Max length of
639500 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   output string */
fbaf5a
8e8bd3 ¤   for (pPos = pStart; pPos < pEnd; pPos++)
77c7a1 ¤   {
aabc1a ¤   ¤   if (strncmp(pPos, kNewline, kNewlineLen) == 0) /* We're at a newline */
49e841 ¤   ¤   ¤   pPos += kNewlineLen; /* Skip over newline */
d8af5a
2cda85 ¤   ¤   *pBuf++ = *pPos;
429371 ¤   }
52af5a
3dcdc5 ¤   *pBuf = '\0';
04af5a
5ab4d5 ¤   // Now squish the header string down by copying over the requested header
2ecc9c ¤   while ((*pStart++ = *pEnd++) != '\0')
5209bd ¤   ¤   /* copy */ ;
08af5a
5a709e ¤   return (pRetBuf);
d5efe6 }
5faf5a
42e6ec /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
e0af5a
8438e5 /*
47c16d ·* ·Reads and returns the RFC822 header from input file. This is defined
289ca2 ·* ·here as reading until the first blank line from current file
--b6a3 001a6df570e401101fd Page 7 of RFC822.CPP
63c871 ·* ·position. The blank line is discarded.
0a775e ·*
31322b ·* ·NOTE: The user of this function is responsible for freeing the
37c8a5 ·* ·······returned string.
a4775e ·*
1f6a22 ·* ·Args:
fac2dd ·* ··inFile [IN] Input file stream; already open
ad775e ·*
47f523 ·* ·Returns: Complete multi-lined RFC822 header; dynamically allocated.
6d5046 ·* ····The file pointer is left immediately after the first read blank line.
ab495d ·*/
a41821 char *rfc822_read_header(ifstream& inFile)
64bb36 {
850acf ¤   // We don't know how big the header is, but we know each line
c0c5e5 ¤   // must be less than 1024 chars. We use 'kBlockSize' to
3e2750 ¤   // increase the memory of the header while ensuring that
2755c9 ¤   // there is at least kBlockSize available for each read.
ce60a3 ¤   const unsigned int kBlockSize = 1024;
f5af5a
f7418e ¤   char *pBuf, *pPos, *cp;
b7df4f ¤   unsigned int nBufSize, nStrLen;
eeaf5a
c61986 ¤   if ((!inFile.good()) || (inFile.eof()))
867ed2 ¤   ¤   return NULL;
f0af5a
173e77 ¤   nStrLen = nBufSize = 0;
4958d5 ¤   pBuf = NULL;
a3af5a
336b50 ¤   while ((inFile.good()) && (!inFile.eof()))
0dc7a1 ¤   {
93eb2b ¤   ¤   if ((nBufSize - nStrLen) < (kBlockSize + 1))
f45b34 ¤   ¤   {
6f00c3 ¤   ¤   ¤   nBufSize += kBlockSize;
9b6ead ¤   ¤   ¤   if ((cp = (char *) realloc(pBuf, nBufSize)) == NULL)
9df776 ¤   ¤   ¤   {
6c6ceb ¤   ¤   ¤   ¤   safefree(pBuf);
ef6e97 ¤   ¤   ¤   ¤   return (NULL); // Out of memory?
c8a3a6 ¤   ¤   ¤   }
12af5a
5d7308 ¤   ¤   ¤   pPos = (pBuf = cp) + nStrLen;
6f0fe4 ¤   ¤   }
63af5a
3ddb6b ¤   ¤   // Get next line
00b7c4 ¤   ¤   cp = pPos;
a3b3e2 ¤   ¤   while ((inFile.good()) && (!inFile.eof()))
120513 ¤   ¤   ¤   if ((*cp++ = inFile.get()) == '\n')
c1f776 ¤   ¤   ¤   {
18ba85 ¤   ¤   ¤   ¤   *cp = '\0';
4af622 ¤   ¤   ¤   ¤   break;
59a3a6 ¤   ¤   ¤   }
dcaf5a
5c7cc0 ¤   ¤   /* inFile.getline(pPos, kBlockSize); */
c062ea ¤   ¤   /* getline() strips '\n' chars! Yuck! */
faaf5a
a2ad39 ¤   ¤   if (strcmp(pPos, kRFC822_EOL) == 0) /* Empty line */
bdcdcb ¤   ¤   ¤   break;
41af5a
188b45 ¤   ¤   pPos = strchr(pPos, '\0');
f01bec ¤   ¤   nStrLen = pPos - pBuf;
669371 ¤   }
76af5a
435b31 ¤   // Null terminate the header string
e0f282 ¤   *pPos = '\0';
b6af5a
76398d ¤   // Chop off any excess allocated memory
925a5c ¤   if (cp = (char *) realloc(pBuf, strlen(pBuf) + 1))
dcb63c ¤   ¤   pBuf = cp;
7a67c5 ¤
06638a ¤   return (pBuf);
a6efe6 }
--008c 000c563cba3401101fe Page 1 of RFC822.H
bc38e5 /*
ebb257 ·* ·Functions to aide manipulation of MIME RFC822 headers.
8b775e ·*
887b87 ·* ·Filename: RFC822.h
44775e ·*
c72ba5 ·* ·Last Edited: July 15, 1996
f6775e ·*
19005b ·* ·Author: Scott Manjourides
5b775e ·*
8ccbf0 ·* ·Portions adopted from code originally written by Stever Dorner.
f0ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
0c775e ·*
78c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
4e775e ·*
1b495d ·*/
83af5a
df4489 #ifndef EMS_RFC822_H
1bb437 #define EMS_RFC822_H
91af5a
f40043 #include <istream.h> // ifstream class
d1b6e4 #include <fstream.h> // ofstream class
7daf5a
a111fb char *rfc822_remove_header(char *pFullHeader, const char *pLinePrefix);
6faf5a
8e38e5 /*
5f6550 ·* ·Find next RFC822 token in given string, copying it into a newly created
cfbdf0 ·* ·string. Advance pointer past token and any following whitespace.
9ca3b2 ·* ··
113bed ·* ·NOTE: The user of this function is responsible for freeing returned
0e6c68 ·* ·······string.
83775e ·*
6f6a22 ·* ·Args:
a8656a ·* ··cpp [IN/OUT] Handle (pointer-to-pointer) of RFC822 string to extract from
0f775e ·*
5279f1 ·* ·Returns: String containing next token, NULL if error.
12e88e ·* ········Moves cpp to first non-whitespace character AFTER extracted token
7e495d ·*/
64815b char *rfc822_extract_token(char **cpp);
e5af5a
f938e5 /*
2c7334 ·* ·Advances to next non-whitespace character in string. This includes
27d4de ·* ·ignoring RFC822 comments.
8aa3b2 ·* ··
246a22 ·* ·Args:
db2c45 ·* ··cp [IN] RFC822 string
14775e ·*
10bac7 ·* ·Returns: Pointer to next non-whitespace character.
73495d ·*/
bdbd2e char *rfc822_skipws(char *cp);
1aaf5a
ee38e5 /*
188bdc ·* ·Advances to next character in string directly after the current token.
27a9fc ·* ·The first character must be the beginning of a valid token or end of
828505 ·* ·string (ie. all whitespace must be skipped BEFORE calling this function).
48775e ·*
c66a22 ·* ·Args:
1d2c45 ·* ··cp [IN] RFC822 string
0f775e ·*
3be27b ·* ·Returns: Pointer to next valid whitespace character.
ef495d ·*/
0778d2 char *rfc822_skipword(char *cp);
c9af5a
e538e5 /*
dca539 ·* ·Calculates the length of the given text string if it were converted
0e53aa ·* ·to an RFC822 string.
df775e ·*
c96a22 ·* ·Args:
dedfd1 ·* ··cp [IN] Text string
95775e ·*
8ac1f0 ·* ·Returns: Equivalent RFC822 length of given text.
9b495d ·*/
c558c3 unsigned int rfc822_quoted_strlen(char *cp);
--d33e 001545f8930401101fe Page 2 of RFC822.H
e0af5a
d338e5 /*
d6b4be ·* ·Copies and converts the source text string to a destination
6c27ba ·* ·RFC822 string. The source must be NULL terminated, and the
a2c297 ·* ·destination will be NULL terminated.
51775e ·*
cb6a22 ·* ·Args:
9b6d68 ·* ··dst [OUT] RFC822 string
83ce7b ·* ··src [IN] ·Text string
9b775e ·*
ad50ce ·* ·Returns: Pointer to destination NULL termination.
6a495d ·*/
ddab42 char *rfc822_quote_strcpy(char *dst, const char *src);
4baf5a
f038e5 /*
3ba027 ·* ·Copies and converts the source RFC822 string to a destination
0df16a ·* ·text string. The source must be NULL terminated, and the
b9c297 ·* ·destination will be NULL terminated.
d6775e ·*
666a22 ·* ·Args:
b62fe1 ·* ··dst [OUT] Text string
277fc2 ·* ··src [IN] ·RFC822 string
bd8f1f ·* ··len [IN] ·Maximum charcters to copy; Zero implies whole string
8e775e ·*
9350ce ·* ·Returns: Pointer to destination NULL termination.
11495d ·*/
cd9cb0 char *rfc822_unquote_strcpy(char *dst, const char *src, unsigned int len);
2daf5a
5f38e5 /*
0dcdeb ·* ·Finds and extracts a header line from a full multi-lined header. All
1146fd ·* ·unfolding (removing newlines) is done before header line is returned.
6e775e ·*
85322b ·* ·NOTE: The user of this function is responsible for freeing the
b8c8a5 ·* ·······returned string.
13775e ·*
876a22 ·* ·Args:
120990 ·* ··pFullHeader [IN] Pointer to a full RFC822 header, including newlines
12b2b8 ·* ··pLinePrefix [IN] Prefix of header line to extract
18775e ·*
c0d4f7 ·* ·Returns: Extracted header line string; dynamically allocated.
f3495d ·*/
fbfabf char *rfc822_extract_header(const char *pFullHeader, const char *pLinePrefix);
fbaf5a
1638e5 /*
05c16d ·* ·Reads and returns the RFC822 header from input file. This is defined
759ca2 ·* ·here as reading until the first blank line from current file
55c871 ·* ·position. The blank line is discarded.
68775e ·*
fe322b ·* ·NOTE: The user of this function is responsible for freeing the
88c8a5 ·* ·······returned string.
b0775e ·*
596a22 ·* ·Args:
e6c2dd ·* ··inFile [IN] Input file stream; already open
07775e ·*
a1f523 ·* ·Returns: Complete multi-lined RFC822 header; dynamically allocated.
af5046 ·* ····The file pointer is left immediately after the first read blank line.
d6495d ·*/
2b30b3 char *rfc822_read_header(ifstream& inFile);
4faf5a
5457d1 #endif /* EMS_RFC822_H */
--279c 0009c13a406401101ff Page 1 of ems-win.h
f94b9b #ifndef __EMS_WIN__
40421c #define __EMS_WIN__
5314b9 /* ======================================================================
e3af5a
7b97aa ····C header for EMSAPI version 4
5ecd8b ····Copyright 1996, 1997 QUALCOMM Inc.
cf83da ····Send comments and questions to <emsapi-info@qualcomm.com>
8caf5a
749e9e ····Generated: Mon Oct 6 15:22:45 PDT 1997
b4ecbe ····Filname: ems-win.h
26869e ····
9c8c4b ····USE THIS FILE TO BUILD YOUR WINDOWS TRANSLATOR DLL
61af5a
a281b0 ····Note: this file is generated automatically by scripts and must be
47d57d ····kept in synch with other translation API definitions, so it should
35c9b0 ····probably not ever be changed.
41af5a
0caf5a
2ee251 /* ========== CONSTANTS AND RETURN VALUES ================================ */
83af5a
f95815 /* ----- Translator return codes --- store as a long --------------------- */·
53023e #define EMSR_OK ·············(0L) ····/* The translation operation·
7fc5ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   succeeded */
618023 #define EMSR_UNKNOWN_FAIL ···(1L) ····/* Failed for unspecified reason */
d03bf8 #define EMSR_CANT_TRANS ·····(2L) ····/* Don't know how to translate this */
7e612c #define EMSR_INVALID_TRANS ··(3L) ····/* The translator ID given was·
febcd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   invalid */
6cfeb8 #define EMSR_NO_ENTRY ·······(4L) ····/* The value requested doesn't exist */
36c5d6 #define EMSR_NO_INPUT_FILE ··(5L) ····/* Couldn't find input file */
1fa9bb #define EMSR_CANT_CREATE ····(6L) ····/* Couldn't create the output file */
5eb7be #define EMSR_TRANS_FAILED ···(7L) ····/* The translation failed. */
ce6520 #define EMSR_INVALID ········(8L) ····/* Invalid argument(s) given */
3502b1 #define EMSR_NOT_NOW ········(9L) ····/* Translation can be done not in·
f9e137 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   current context */
ef1058 #define EMSR_NOW ···········(10L) ····/* Indicates translation can be·
41125e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   performed right away */
b52249 #define EMSR_ABORTED ·······(11L) ····/* Translation was aborted by user */
a8fdb4 #define EMSR_DATA_UNCHANGED (12L) ····/* Trans OK, data was not changed */
1bd83c ·
a1d83c ·
707a73 /* ----- Translator types --- store as a long ---------------------------- */·
8eed98 #define EMST_NO_TYPE ·········(-1L)
d4e4cc #define EMST_LANGUAGE ········(0x10L)
e0ce6b #define EMST_TEXT_FORMAT ·····(0x20L)
648235 #define EMST_GRAPHIC_FORMAT ··(0x30L)
9218e2 #define EMST_COMPRESSION ·····(0x40L)
ffe9b4 #define EMST_COALESCED ·······(0x50L)
47d4c4 #define EMST_SIGNATURE ·······(0x60L)
c5d203 #define EMST_PREPROCESS ······(0x70L)
a959a1 #define EMST_CERT_MANAGEMENT ·(0x80L)
76af5a
2eaf5a
97b4b5 /* ----- Translator info flags and contexts --- store as a long ---------- */
674e9b /* Used both as bit flags and as constants */
6b887d #define EMSF_ON_ARRIVAL ·····(0x0001L) /* Call on message arrivial */
20acb3 #define EMSF_ON_DISPLAY ·····(0x0002L) /* Call when user views message */
8ab246 #define EMSF_ON_REQUEST ·····(0x0004L) /* Call when selected from menu */
44b093 #define EMSF_Q4_COMPLETION ··(0x0008L) /* Queue and call on complete·
13c75e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   composition of a message */
d17c46 #define EMSF_Q4_TRANSMISSION (0x0010L) /* Queue and call on transmission·
023c58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   of a message */
c1edc5 #define EMSF_WHOLE_MESSAGE ··(0x0200L) /* Works on the whole message even·
399413 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if it has sub-parts.·
30ce7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (e.g. signature) */
4ce729 #define EMSF_REQUIRES_MIME ··(0x0400L) /* Items presented for translation
31a467 ··········································should be MIME entities with
1150e4 ··········································canonical end of line·
c1ae8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   representation,
204aaf ··········································proper transfer encoding
7dec42 ··········································and headers */
71e294 #define EMSF_GENERATES_MIME ·(0x0800L) /* Data produced will be·
9c7351 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MIME format */
--6ebe 000ae659610401101ff Page 2 of ems-win.h
a37b92 #define EMSF_ALL_HEADERS ····(0x1000L) /* All headers in & out of·
ccae50 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   trans when MIME format is used */
022151 #define EMSF_BASIC_HEADERS ··(0x2000L) /* Just the basic to, from,·
19e4f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   subject, cc,bcc headers */
397675 #define EMSF_DEFAULT_Q_ON ···(0x4000L) /* Causes queued translation to be·
3e7227 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   on for a new message by default */
7ea2c6 #define EMSF_TOOLBAR_PRESENCE (0x8000L)/* Appear on the Toolbar */
14b56c #define EMSF_ALL_TEXT¤  ¤   ·(0x10000L)/* ON_REQUEST WANTS WHOLE MESSAGE */
a9af5a
a9af5a
fc5137 /* ----- The version of the API defined by this include file ------------- */
b094c4 #define EMS_VERSION ·········(4) ······/* Used in plugin init */
1cb709 #define EMS_PB_VERSION ······(3) ······/* Minimum version that·
c3ca51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uses parameter blocks */
be34bc #define EMS_COMPONENT ·······'EuTL' ···/* Macintosh component type */
daaf5a
beaf5a
ac0f81 /* ----- Translator and translator type specific return codes ------------ */
a5abda #define EMSC_SIGOK ··········(1L) ·····/* A signature verification·
2caad9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   succeeded */
176abc #define EMSC_SIGBAD ·········(2L) ·····/* A signature verification failed */
282491 #define EMSC_SIGUNKNOWN ·····(3L) ·····/* Result of verification unknown */
beaf5a
d2af5a
1d5021 /* ----- Progress Data ---------------------------- */
992fed typedef struct emsProgressDataS FAR* emsProgressDataP;
3a005d typedef struct emsProgressDataS {
77462e ¤   long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
1490d4 ¤   long¤   ¤   ¤   value;¤ ¤   ¤   /* Range of Progress, percent complete */
98aa05 ¤   LPSTR¤  ¤   ¤   message;¤   ¤   /* Progress Message */
a7fca4 } emsProgressData;
10af5a
11af5a
a1bf68 /* ----- User Address ---------------------------- */
75844d typedef struct emsAddressS FAR*emsAddressP;·
d53bd0 typedef struct emsAddressS {
92462e ¤   long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
265bbf ¤   LPSTR¤  ¤   ¤   address;¤   ¤   /* user address */
9ac61b ¤   LPSTR¤  ¤   ¤   realname;¤  ¤   /* Users full name from Eudora config */
dfa294 ¤   emsAddressP¤¤   next;¤  ¤   ¤   /* Linked list of addresses */
e1da16 } emsAddress;
cfaf5a
07af5a
95ce69 /* == CALL BACK FUNCTIONS FROM EUDORA ACROSS THE API======================== */
7273c8 typedef short ····(FAR* emsProgress)(emsProgressDataP);/* The progress·
5e3f7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   function ·*/
0faf5a
fb839d /* ========== DATA STRUCTURES ============================================ */
2e899f /* All strings on Windows are NULL terminated C strings */
073dac /* ----- MIME type data passed across the API ---------------------------- */
99af5a
effdfa /* ----- MIME Params ---------------------------- */
eab642 typedef struct emsMIMEparamS FAR*emsMIMEParamP;
7f6a09 typedef struct emsMIMEparamS {
8b4162 ····long¤   ¤   ¤   size;
5b44b5 ····LPSTR¤  ¤   ¤   name;¤  ¤   ¤   /* Mime parameter name (e.g., charset) */
0360f0 ····LPSTR¤  ¤   ¤   value;¤ ¤   ¤   /* param value (e.g. us-ascii) */
40558a ····emsMIMEParamP ·¤next;¤  ¤   ¤   /* Linked list of parameters */
3aceae } emsMIMEparam;
25af5a
f6af5a
831c41 /* ----- MIME Info ---------------------------- */
bfa7d0 typedef struct emsMIMEtypeS FAR*emsMIMEtypeP;·
4fc713 typedef struct emsMIMEtypeS {
444162 ····long¤   ¤   ¤   size;
b45230 ····LPSTR¤  ¤   ¤   version;¤   ¤   /* The MIME-Version header */
37c108 ····LPSTR¤  ¤   ¤   type;¤  ¤   ¤   /* Top-level MIME type */ ·····
2d09ca ····LPSTR ··········subType;¤   ¤   /* sub-type */
23fe16 ····emsMIMEParamP¤  params;¤¤   ¤   /* MIME parameter list */
63e191 ····LPSTR ······¤   contentDisp; ·¤ /* Content-Disposition */
ceaf63 ····emsMIMEParamP ··contentParams; ¤/* Handle to first parameter in list */
aee1b4 } emsMIMEtype;
--3590 0002eb60210401101ff Page 3 of ems-win.h
e0af5a
b86a7f /* ----- Header Data ---------------------------- */
0396cf typedef struct emsHeaderDataS FAR*emsHeaderDataP;·
58ace7 typedef struct emsHeaderDataS {
a9fee8 ····long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
bdcac4 ····emsAddressP¤¤   to;¤¤   ¤   ¤   /* To Header */
f7f69d ····emsAddressP¤¤   from;¤  ¤   ¤   /* From Header */
7e07b1 ····LPSTR¤  ¤   ¤   subject;¤   ¤   /* Subject Header */
f82520 ····emsAddressP¤¤   cc;¤¤   ¤   ¤   /* cc Header */
a4f692 ····emsAddressP¤¤   bcc;¤   ¤   ¤   /* bcc Header */
557011 ····LPSTR¤  ¤   ¤   rawHeaders;¤¤   /* The 822 headers */
d0c7c7 } emsHeaderData;
42af5a
4eaf5a
8faf5a
fa6751 /* ----- How Eudora is configured ---------------------------- */
3585b3 typedef struct emsMailConfigS FAR*emsMailConfigP;·
e22cab typedef struct emsMailConfigS {
cf462e ¤   long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
f02fa9 ¤   HWND¤   ¤   ¤   FAR*eudoraWnd;¤ /* Eudora's main window */
9667de ····LPSTR¤  ¤   ¤   configDir;¤ ¤   /* Optional directory for config file */
611bc6 ¤   emsAddress¤ ¤   userAddr;¤  ¤   /* Users full name from Eudora config */
ac1adc ¤   unsigned long¤  reserved;¤  ¤   /* V4! reserved */
ff3dd0 } emsMailConfig;
a3af5a
dcf873 /* ----- Plugin Info ---------------------------- */
963bf4 typedef struct emsPluginInfoS FAR*emsPluginInfoP;·
d5bdf2 typedef struct emsPluginInfoS {
e2fee8 ····long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
69a30b ····long¤   ¤   ¤   numTrans;¤  ¤   /* Place to return num of translators */
a48091 ····long¤   ¤   ¤   numAttachers;¤  /* Place to return num of attach hooks */
87fab0 ····long¤   ¤   ¤   numSpecials;/* Place to return num of special hooks */
222cc9 ····LPSTR¤  ¤   ¤   desc;¤  ¤   /* Return for string description of plugin */
5c57f9 ····long¤   ¤   ¤   id;¤¤   ¤   ¤   /* Place to return unique plugin id */
4f0aa4 ····HICON¤  ¤   ¤   FAR*icon;¤  ¤   /* Return for plugin icon data */
c35d10 ····long¤   ¤   ¤   mem_rqmnt;/* V4! Return Memory Required to run this */
e19904 ····long ···········reserved1;¤ ¤   /* V4! reserved */
766fdc ····long ···········reserved2;¤ ¤   /* V4! reserved */
a60fdf } emsPluginInfo;
cbaf5a
2d2bb1 /* ----- Translator Info ---------------------------- */
931b99 typedef struct emsTranslatorS FAR*emsTranslatorP;·
4f8fd2 typedef struct emsTranslatorS {
2ffee8 ····long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
e250d1 ····long¤   ¤   ¤   id;¤¤   ¤   ¤   /* ID of translator to get info for */
04748b ····long¤   ¤   ¤   type;¤  ¤   ¤   /* translator type, e.g., EMST_xxx */
624207 ····ULONG¤  ¤   ¤   flags;¤ ¤   ¤   /* translator flags */
429be7 ····LPSTR¤  ¤   ¤   desc;¤  ¤   ¤   /* translator string description */
7d5a18 ····HICON¤  ¤   ¤   FAR*icon;¤  ¤   /* translator icon data */
34f6f4 ····LPSTR¤  ¤   ¤   properties;¤¤   /* Properties for queued translations */
f2f781 } emsTranslator;
4daf5a
26a3d1 /* ----- Menu Item Info ---------------------------- */
c4c86b typedef struct emsMenuS FAR*emsMenuP;·
8df762 typedef struct emsMenuS {
18fee8 ····long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
5c50d1 ····long¤   ¤   ¤   id;¤¤   ¤   ¤   /* ID of translator to get info for */
599be7 ····LPSTR¤  ¤   ¤   desc;¤  ¤   ¤   /* translator string description */
d42a2f ····HICON¤  ¤   ¤   FAR*icon;¤  ¤   /* NEW V4! menu icon ·*/
c3d5f3 ····long¤   ¤   ¤   flags;¤ ¤   /* NEW V4! flags like EMSF_TOOLBAR_PRESENCE */
f035d7 } emsMenu;
3baf5a
1e7b2f /* ----- Translation Data ---------------------------- */
4fb589 typedef struct emsDataFileS FAR*emsDataFileP;·
b7c5d5 typedef struct emsDataFileS {
d1fee8 ····long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
d3f84a ····long¤   ¤   ¤   context;
b7286e ····emsMIMEtypeP¤   info;¤  ¤   ¤   /* MIME type of data to check */
0519d0 ····emsHeaderDataP ·header;¤¤   ¤   /* EMSF_BASIC_HEADERS & EMSF_ALL_HEADERS
18482e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   determine contents */
142226 ····LPSTR¤  ¤   ¤   fileName;¤  ¤   /* The input file name */
2e4e64 } emsDataFile;
--0308 000a4589f68401101ff Page 4 of ems-win.h
e0af5a
3ff189 /* ----- Resulting Status Data ---------------------------- */
049129 typedef struct emsResultStatusS FAR*emsResultStatusP;·
ec66aa typedef struct emsResultStatusS {
b9fee8 ····long¤   ¤   ¤   size;¤  ¤   ¤   /* Size of this data structure */
52b730 ····LPSTR¤  ¤   ¤   desc;¤  ¤   ¤   /* Returned string for display with
a5623c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   the result */
96cf25 ····LPSTR¤  ¤   ¤   error;¤ ¤   ¤   /* Place to return string with·
dc00a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error message */
25f76a ····long¤   ¤   ¤   code;¤  ¤   ¤   /* Return for translator-specific·
7df14b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   result code */
bc3c8b } emsResultStatus;
3faf5a
b8af5a
72f31b /* ========== FUNCTION PROTOTYPES ======================================== */
27af5a
bf3379 #ifdef __cplusplus
986dad extern "C" {
b67454 #endif
b667c5 ¤
ceefc7 /* ----- Get the API Version number this plugin implements --------------- */
01b47e long WINAPI ems_plugin_version(
6dcc08 ····short FAR* apiVersion¤  ¤   ¤   /* Out: Plugin Version */
826275 );
a9af5a
a3e4c4 /* ----- Initialize plugin and get its basic info ------------------------ */
401118 long WINAPI ems_plugin_init(
9dc6da ····void FAR*FAR* globals,¤ ¤   ¤   /* Out: Return for allocated·
40ca29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   instance structure */
e479bb ····short eudAPIVersion,¤   ¤   ¤   /* In: The API version eudora is·
a40255 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   using */
df6a82 ····emsMailConfigP mailConfig,¤ ¤   /* In: Eudoras mail configuration */
e57553 ····emsPluginInfoP pluginInfo¤  ¤   /* Out: Return Plugin Information */
336275 );
afaf5a
e8ec7c /* ----- Get details about a translator in a plugin ---------------------- */
621da0 long WINAPI ems_translator_info(
39407c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated·
aaca29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   instance structure */
c7d2d9 ····emsTranslatorP transInfo¤   ¤   /* In/Out: Return Translator·
8f5e49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   Information */
2e6275 );
98af5a
5d9a2a /* ----- Check and see if a translation can be performed ----------------- */
6edf96 long WINAPI ems_can_translate(
15407c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated·
f9ca29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   instance structure */
43e385 ····emsTranslatorP trans,¤  ¤   ¤   /* In: Translator Info */
3e361a ····emsDataFileP inTransData,¤  ¤   /* In: What to translate */
66dbbe ····emsResultStatusP transStatus¤   /* Out: Translations Status·
031390 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   information */
1e6275 );
b4af5a
b23938 /* ----- Actually perform a translation on a file ------------------------ */
f51f17 long WINAPI ems_translate_file(
2b407c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated·
50ca29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   instance structure */
18e385 ····emsTranslatorP trans,¤  ¤   ¤   /* In: Translator Info */
1f23b1 ····emsDataFileP inFile,¤   ¤   ¤   /* In: What to translate */
4e09e0 ····emsProgress progress,¤  ¤   ¤   /* Func to report progress/check·
8daf22 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   for abort */
4d9ba0 ····emsDataFileP outFile,¤  ¤   ¤   /* Out: Result of the translation */
0edbbe ····emsResultStatusP transStatus¤   /* Out: Translations Status·
fb1390 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   information */
326275 );
d1af5a
bbf37e /* ----- End use of a plugin and clean up -------------------------------- */
591f49 long WINAPI ems_plugin_finish(
a34d7e ····void FAR* globals¤  /* Out: Return for allocated instance structure */
fe6275 );
d4af5a
a4553d short ems_allocate(
--4ae5 001ee09c73f401101ff Page 5 of ems-win.h
d0379e ····void FAR** mem, ············
1c1497 ¤   size_t size
f76275 );
ebaf5a
ecd8c2 /* ----- Free memory allocated by EMS plug-in ---------------------------- */
261693 long WINAPI ems_free(
a5943e ····void FAR* mem¤  ¤   ¤   ¤   ¤   /* Memory to free */
a96275 );
1daf5a
a29930 /* ----- Call the plug-ins configuration Interface ----------------------- */
ccefd1 long WINAPI ems_plugin_config(
9e407c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated·
6aca29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   instance structure */
c55302 ····emsMailConfigP mailConfig¤  ¤   /* In: Eudora mail info */
4c6275 );
15af5a
f7a93f /* ----- Manage properties for queued translations ----------------------- */
bb591a long WINAPI ems_queued_properties(
79937c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated instance struc¶
05c54b ture */
9f271b ····emsTranslatorP trans,¤  ¤   ¤   /* In/Out: The translator */
468d16 ····long FAR* selected¤ ¤   ¤   ¤   /* In/Out: State of this translator */
bd6275 );
5eaf5a
0f0ece /* ----- Info about menu hook to attach/insert composed object ----------- */
aa134b long WINAPI ems_attacher_info(
09937c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated instance struc¶
ecc54b ture */
26d405 ····emsMenuP attachMenu¤¤   ¤   ¤   /* Out: The menu */
b06275 );
a6af5a
fccbe6 /* ----- Call an attacher hook to compose some special object ------------ */
a88626 long WINAPI ems_attacher_hook(
39407c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated·
90ca29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   instance structure */
55f3bb ····emsMenuP attachMenu,¤   ¤   ¤   /* In: The menu */
bc0271 ····LPSTR attachDir,¤   ¤   ¤   ¤   /* In: Location to put attachments */
53c808 ····long * numAttach,¤  ¤   ¤   ¤   /* Out: Number of files attached */
9546e4 ····emsDataFileP ** attachFiles¤¤   /* Out: Name of files written */
d96275 );
94af5a
a5464d /* ----- Info about special menu items hooks ----------------------------- */
73a9e0 long WINAPI ems_special_info(
51ac67 ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated instance·
923039 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   structure */
f4bdad ····emsMenuP specialMenu¤   ¤   ¤   /* Out: The menu */
726275 );
4eaf5a
ce26ac /* ----- Call a special menu item hook ----------------------------------- */
fb3c8d long WINAPI ems_special_hook(
7a407c ····void FAR* globals,¤ ¤   ¤   ¤   /* Out: Return for allocated·
a9ca29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   instance structure */
c6ccc8 ····emsMenuP specialMenu¤   ¤   ¤   /* In: The menu */
9e6275 );
05af5a
0d3379 #ifdef __cplusplus
adefe6 }
f37454 #endif
26af5a
077a00 #endif /* __EMS_WIN__ */
eeaf5a
--f9c9 000662616be40110200 Page 1 of file1847.cpp
bc38e5 /*
87fe00 ·* ·Filename: file1847.cpp
15775e ·*
b6e658 ·* ·Last Edited: Wednesday, October 2, 1996
5b775e ·*
b4005b ·* ·Author: Scott Manjourides
b7775e ·*
0fea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
4f775e ·*
f2c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
14495d ·*/
6daf5a
8dbea3 #include <stdlib.h>
c4feb2 #include <stdio.h>
93324c #include <string.h>
845655 #include <windows.h>
d6af5a
af3ad6 #include "ems-win.h" // The EMS API
0bf10b #include "mimetype.h"
99bde1 #include "encoding.h"
966bd2 #include "rfc822.h"
a627f6 #include "rfc1847.h"
8caf5a
e58bfa #include "file1847.h"
0baf5a
aabf23 /* ------------------------------------------------------------------------ */
30af5a
83f0f7 typedef struct {
ed6b54 ¤   int bFoundHeader;
e44f25 ¤   BufTypePtr pBuf, pSearchBuf;
270d1f ¤   TrEncType cte;
549a23 ¤   unsigned int nPrevEndMatch;
0f7d9d ¤   char *preEncBuffer;
7c1a48 ¤   Dec64Ptr d64state;
91b6bd ¤   DecQPPtr dQPstate;
2dbde8 } PartParseState;
8faf5a
4c8a05 typedef PartParseState *PartParseStatePtr;
b4af5a
63bf23 /* ------------------------------------------------------------------------ */
dcaf5a
25be35 static int DoCreateOnePart(emsMIMEtypeP InPartMimePtr,
d913ac ¤   ¤   ¤   ¤   ¤   ·emsMIMEtypeP OutMimePtr,
190da2 ¤   ¤   ¤   ¤   ¤   ·TrEncType InPartCTE,
924c6a ¤   ¤   ¤   ¤   ¤   ·FILE *fIn,
3369a4 ¤   ¤   ¤   ¤   ¤   ·FILE *fOut,
7d0e17 ¤   ¤   ¤   ¤   ¤   ·int nPart,
98f877 ¤   ¤   ¤   ¤   ¤   ·long nPreLen,
77bfd8 ¤   ¤   ¤   ¤   ¤   ·long nTotalInLen,
7c2114 ¤   ¤   ¤   ¤   ¤   ·createStatePtr pState,
41fbbc ¤   ¤   ¤   ¤   ¤   ·emsProgress progress);
d0af5a
c9b798 static int DoCreatePartsOutput(emsMIMEtypeP mimePtr,
463c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
3bd359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
510bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
b9f6f0 ¤   ¤   ¤   ¤   ···FILE *fOut);
0eaf5a
abf32b static int DoCreateStringOutput(const char *pStr,
dee775 ¤   ¤   ¤   ¤   ···int nPart,
0997ec ¤   ¤   ¤   ¤   ···emsMIMEtypeP mimePtr,
350bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
0bf6f0 ¤   ¤   ¤   ¤   ···FILE *fOut);
1caf5a
19c02d static int DoParsePart(BufTypePtr pInBuf,
f2d2f2 ¤   ¤   ¤   ¤   ·FILE *fOut,
f67303 ¤   ¤   ¤   ¤   ·emsMIMEtypeP *mimePtr,
743632 ¤   ¤   ¤   ¤   ·int bDeMime,
1024c2 ¤   ¤   ¤   ¤   ·PartParseStatePtr pState);
b9af5a
316bac static PartParseStatePtr create_PartParseState();
661a2d static void delete_PartParseState(PartParseStatePtr p);
--2317 0003f7d99ec40110200 Page 2 of file1847.cpp
e0af5a
5694f8 static void DoBufOutput(FILE *fOut, BufTypePtr pBuf);
28af5a
85bf23 /* ------------------------------------------------------------------------ */
30af5a
297f62 #define kBufferSize (1024)
3daf5a
90dd8c #define safefree(p) { if (p) { free(p); (p) = NULL; } }
5ada59 #define safeclose(f) { if (f) { fclose(f); (f) = NULL; } }
34af5a
6ed1f7 const char *kMimeVersionStr = "Mime-Version: 1.0\r\n";
75af5a
cbbf23 /* ------------------------------------------------------------------------ */
cfaf5a
87ee80 /* ·CreateTmpFile
1e775e ·*
c06438 ·* ·Creates a empty, unique, temporary file in the users 'TEMP'
bb4970 ·* ···directory.
46775e ·*
a4b7ce ·* ·No arguments.
6a775e ·*
ba59a2 ·* ·Returns a pointer to the filename string. This should be
31cb59 ·* ···considered temporary data, and should never be free()'d.
64495d ·*/
b71088 char *CreateTmpFile()
73bb36 {
ba7c54 ¤   static char tmpName[_MAX_PATH + 1];
10af5a
a59186 #ifdef WIN32 // 32-bit
81ecdf ¤   char path[_MAX_PATH + 1];¤  ¤   ¤
7b8cbc ¤   GetTempPath(_MAX_PATH, path);
6ffdcc ¤   GetTempFileName(path, "tmp", 0, tmpName);
225c9a #else // 16-bit
647ce5 ¤   BYTE btmpDrv = GetTempDrive(0);
3c59e6 ¤   GetTempFileName(btmpDrv,"tmp", 0, tmpName);
b27454 #endif
19af5a
6eef33 ¤   return (tmpName);
9eefe6 }
2daf5a
1bbf23 /* ------------------------------------------------------------------------ */
eeaf5a
89dc23 /* ·rfc1847_file_create
13775e ·*
e59c8e ·* ·Creates RFC1847 MIME structure.
5e775e ·*
8e6a22 ·* ·Args:
093da4 ·* ···pOutFilename ····[IN] ····Output filename ** WRITE-ONLY **
e71aa8 ·* ···OutMimePtr ······[IN/OUT] MIME type of output -- boundary param will be a¶
3bf634 dded
92a061 ·* ···InPart1MimePtr ··[IN] ····MIME type of part 1
5743df ·* ···InPart1CTE ······[IN] ····Content-transfer-encoding for part 1
591941 ·* ···pInPart1Filename [IN] ····Input filename for part 1 ** READ-ONLY **
789847 ·* ···InPart2MimePtr ··[IN] ····MIME type of part 2
cd1fd0 ·* ···InPart2CTE ······[IN] ····Content-transfer-encoding for part 2
b580bd ·* ···pInPart2Filename [IN] ····Input filename for part 2 ** READ-ONLY **
5119c2 ·* ···progress ········[IN] ····EMS progress callback function
b5775e ·*
000ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
b9495d ·*/
5bc7ea int rfc1847_file_create(const char *pOutFilename,
d4303e ¤   ¤   ¤   ¤   ···emsMIMEtypeP OutMimePtr,
e3af5a
bc0178 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart1MimePtr,
27cfb5 ¤   ¤   ¤   ¤   ···TrEncType InPart1CTE,
e935df ¤   ¤   ¤   ¤   ···const char *pInPart1Filename,
dbaf5a
d17511 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart2MimePtr,
d4c3c8 ¤   ¤   ¤   ¤   ···TrEncType InPart2CTE,
90cb6c ¤   ¤   ¤   ¤   ···const char *pInPart2Filename,
aaaf5a
3feda7 ¤   ¤   ¤   ¤   ···emsProgress progress)
--08a8 000bfb4d72540110200 Page 3 of file1847.cpp
2cbb36 {
840c3a ¤   FILE *fOut = NULL, *fIn1 = NULL, *fIn2 = NULL;
b2af5a
dba614 ¤   fOut = fopen(pOutFilename, "ab"); ····/* WRITE - Append: Binary */
2a7ba4 ¤   fIn1 = fopen(pInPart1Filename, "rb"); /* READ-ONLY: Binary */
8aaaad ¤   fIn2 = fopen(pInPart2Filename, "rb"); /* READ-ONLY: Binary */
01af5a
d0a5c4 ¤   int nStatus = FILE1847_OK;
1daf5a
d6bec5 ¤   if (fOut && fIn1 && fIn2)
0bc7a1 ¤   {
ac1640 ¤   ¤   fwrite(kMimeVersionStr, sizeof(char), strlen(kMimeVersionStr), fOut);
a1af5a
666620 ¤   ¤   long nLen1 = 0, nTotalInLen = 0;
12896f ¤   ¤   emsProgressData progData;
34af5a
b5dd24 ¤   ¤   progData.size = sizeof(emsProgressData);
3d0674 ¤   ¤   progData.value = 0L;
3ad530 ¤   ¤   progData.message = NULL;
67af5a
372c8a ¤   ¤   if (progress)
2c5b34 ¤   ¤   {
58cd59 ¤   ¤   ¤   // get the file length of the two input files -- use for progress
d7bd9e ¤   ¤   ¤   rewind(fIn1);
0dce73 ¤   ¤   ¤   fseek(fIn1, 0, SEEK_END);
94f03f ¤   ¤   ¤   nLen1 = ftell(fIn1);
efbd9e ¤   ¤   ¤   rewind(fIn1);
02af5a
8e9853 ¤   ¤   ¤   rewind(fIn2);
03fe62 ¤   ¤   ¤   fseek(fIn2, 0, SEEK_END);
b7ea4e ¤   ¤   ¤   nTotalInLen = nLen1 + ftell(fIn2);
449853 ¤   ¤   ¤   rewind(fIn2);
40af5a
36182c ¤   ¤   ¤   progress(&progData);
a40fe4 ¤   ¤   }
ccaf5a
40c40b ¤   ¤   createStatePtr pState = new_create_state();
f9af5a
5b8e4b ¤   ¤   if (!pState)
77ff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
deaf5a
4d76fe ¤   ¤   /* ---------- PART 1 ---------- */
e9af5a
a3aa4a ¤   ¤   if (nStatus == FILE1847_OK)
1bb8d7 ¤   ¤   ¤   nStatus = DoCreateOnePart(InPart1MimePtr, OutMimePtr, InPart1CTE, f¶
f08af5 In1, fOut, 1, 0, nTotalInLen, pState, progress);
13af5a
94ecdf ¤   ¤   /* ---------- PART 2 ---------- */
f7af5a
c4aa4a ¤   ¤   if (nStatus == FILE1847_OK)
45a820 ¤   ¤   ¤   nStatus = DoCreateOnePart(InPart2MimePtr, OutMimePtr, InPart2CTE, f¶
e2220d In2, fOut, 2, nLen1, nTotalInLen, pState, progress);
91af5a
391c74 ¤   ¤   // Do 1847 cleanup
78aa4a ¤   ¤   if (nStatus == FILE1847_OK)
a45b34 ¤   ¤   {
1e9533 ¤   ¤   ¤   if (!DoCreatePartsOutput(OutMimePtr, NULL, NULL, pState, fOut))
f6fa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
ef0fe4 ¤   ¤   }
10af5a
c2f21e ¤   ¤   // Do final progress indicator
343f2a ¤   ¤   if ((nStatus == FILE1847_OK) && (progress))
da5b34 ¤   ¤   {
b9237f ¤   ¤   ¤   progData.value = (long) 100;
60186e ¤   ¤   ¤   if (progress(&progData) ? 1 : 0)
4e00e3 ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
400fe4 ¤   ¤   }
0daf5a
7508b7 ¤   ¤   // Done with the state data
64593a ¤   ¤   delete_create_state(pState);
649371 ¤   }
bfaf5a
--8db7 000f4b2f45140110200 Page 4 of file1847.cpp
4a9c34 ¤   safeclose(fOut);
9e0f82 ¤   safeclose(fIn1);
472a4f ¤   safeclose(fIn2);
1caf5a
bb844e ¤   return(nStatus);
ebefe6 }
3eaf5a
19bf23 /* ------------------------------------------------------------------------ */
b2af5a
bcaa24 /* ·rfc1847_file_parse
0b775e ·*
e6911a ·* ·Parses RFC1847 MIME structure.
3f775e ·*
686a22 ·* ·Args:
9d894a ·* ···pInFilename ······[IN] ·Input filename of file to parse ** READ-ONLY **
4cd77d ·* ···InMimePtr ········[OUT] MIME type of input file
51974c ·* ···pOutPart1Filename [IN] ·Output filename for part 1 ** WRITE-ONLY **
102072 ·* ···OutPart1MimePtr ··[OUT] MIME type of created part 1
4c8f77 ·* ···bPart1DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
95f1f2 t 1?
7e07da ·* ···pOutPart2Filename [IN] ·Output filename for part 2 ** WRITE-ONLY **
425057 ·* ···OutPart2MimePtr ··[OUT] MIME type of created part 2
f62f00 ·* ···bPart2DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
271e96 t 2?
544ccd ·* ···progress ·········[IN] ·EMS progress callback function
f5775e ·*
970ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
91495d ·*/
8cc74a int rfc1847_file_parse(const char *pInFilename,
8f4698 ¤   ¤   ¤   ¤   ¤   ···emsMIMEtypeP *InMimePtr,
b1af5a
bbdbea ¤   ¤   ¤   ¤   ¤   ···const char *pOutPart1Filename,
1d8f64 ¤   ¤   ¤   ¤   ¤   ···emsMIMEtypeP *OutPart1MimePtr,
4c590d ¤   ¤   ¤   ¤   ¤   ···int bPart1DeMime,
88af5a
882559 ¤   ¤   ¤   ¤   ¤   ···const char *pOutPart2Filename,
abfb0d ¤   ¤   ¤   ¤   ¤   ···emsMIMEtypeP *OutPart2MimePtr,
118f0a ¤   ¤   ¤   ¤   ¤   ···int bPart2DeMime,
547e90 ¤   ¤   ¤   ¤   ··
feeb1f ¤   ¤   ¤   ¤   ¤   ···emsProgress progress)
97bb36 {
9b7e5c ¤   FILE *fIn = NULL, *fOut1 = NULL, *fOut2 = NULL;
f6af5a
ceb4d4 ¤   fIn = fopen(pInFilename, "rb"); ······/* READ-ONLY: Binary */
342bfd ¤   fOut1 = fopen(pOutPart1Filename, "ab"); /* WRITE - Append: Binary */
dd26b2 ¤   fOut2 = fopen(pOutPart2Filename, "ab"); /* WRITE - Append: Binary */
8faf5a
d6a5c4 ¤   int nStatus = FILE1847_OK;
9eaf5a
8c26ba ¤   if (fIn && fOut1 && fOut2)
f2c7a1 ¤   {
8fc246 ¤   ¤   BufTypePtr pOutPart1= makesize_buf(kBufferSize),
c2e260 ¤   ¤   ¤   pOutPart2 = makesize_buf(kBufferSize),
5f3bb2 ¤   ¤   ¤   pInBuf = makesize_buf(kBufferSize);
2baf5a
1db44c ¤   ¤   if ((!pOutPart1) || (!pOutPart2) || (!pInBuf))
9fff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
78af5a
19172e ¤   ¤   parseStatePtr pState;
380988 ¤   ¤   PartParseStatePtr pParsePart1State, pParsePart2State;
abbb4b ¤   ¤   unsigned int nRead;
ab64b2 ¤   ¤   int ret;
14af5a
8d9e4a ¤   ¤   long nTotalInLen = 0;
4c2366 ¤   ¤   int nPercentComplete = 0;
ae896f ¤   ¤   emsProgressData progData;
4aaf5a
d9dd24 ¤   ¤   progData.size = sizeof(emsProgressData);
710674 ¤   ¤   progData.value = 0L;
50d530 ¤   ¤   progData.message = NULL;
dbaf5a
f47dec ¤   ¤   // Check to see if we need to parse the parts
--4de8 000ccb431d340110200 Page 5 of file1847.cpp
d7aadc ¤   ¤   int bReallyParse1 = FALSE, bReallyParse2 = FALSE;
96f8be ¤   ¤   if ((OutPart1MimePtr) || (bPart1DeMime))
de27b1 ¤   ¤   ¤   bReallyParse1 = TRUE;
598f95 ¤   ¤   if ((OutPart2MimePtr) || (bPart2DeMime))
ef53d8 ¤   ¤   ¤   bReallyParse2 = TRUE;
1caf5a
02083b ¤   ¤   if ((nStatus == FILE1847_OK) && progress)
605b34 ¤   ¤   {
72cd59 ¤   ¤   ¤   // get the file length of the two input files -- use for progress
b0904e ¤   ¤   ¤   rewind(fIn);
235558 ¤   ¤   ¤   fseek(fIn, 0, SEEK_END);
3355ed ¤   ¤   ¤   nTotalInLen = ftell(fIn);
9a904e ¤   ¤   ¤   rewind(fIn);
91af5a
05c4dc ¤   ¤   ¤   progData.value = (long) nPercentComplete;
b8186e ¤   ¤   ¤   if (progress(&progData) ? 1 : 0)
3900e3 ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
b50fe4 ¤   ¤   }
c3af5a
336204 ¤   ¤   pParsePart1State = create_PartParseState();
bc9063 ¤   ¤   pParsePart2State = create_PartParseState();
d67f4d ¤   ¤   pState = new_parse_state();
1caf5a
b90f01 ¤   ¤   if ((nStatus == FILE1847_OK) && (pParsePart1State) && (pParsePart2State¶
c1fe28 ) && (pState))
bc5b34 ¤   ¤   {
02f603 ¤   ¤   ¤   do {
f776dd ¤   ¤   ¤   ¤   /* Fill the input buffer from the input file */
bf061a ¤   ¤   ¤   ¤   emptybuf_buf(pInBuf);
54f54f ¤   ¤   ¤   ¤   if ((nRead = fread(getbuf_buf(pInBuf), sizeof(char), (bufsize_b¶
fe7723 uf(pInBuf)), fIn)) > 0)
1dbf31 ¤   ¤   ¤   ¤   ¤   setlen_buf(pInBuf, nRead);
4aaf5a
c099b8 ¤   ¤   ¤   ¤   /* Parse the input, producing output until completed input */
09b788 ¤   ¤   ¤   ¤   do {
10fcd1 ¤   ¤   ¤   ¤   ¤   emptybuf_buf(pOutPart1);
98d91c ¤   ¤   ¤   ¤   ¤   emptybuf_buf(pOutPart2);
beaf5a
e2ca63 ¤   ¤   ¤   ¤   ¤   ret = rfc1847_parse(InMimePtr, pOutPart1, pOutPart2, pInBuf¶
19a6d2 , pState);
d3af5a
a73400 ¤   ¤   ¤   ¤   ¤   if (ret != RFC1847_FAIL)
214859 ¤   ¤   ¤   ¤   ¤   {
a7a696 ¤   ¤   ¤   ¤   ¤   ¤   if (bReallyParse1) /* Parse part #1 */
e68fec ¤   ¤   ¤   ¤   ¤   ¤   {
679cd6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(pOutPart1, fOut1, OutPart1MimePtr,¶
a38319 ·bPart1DeMime, pParsePart1State))
069299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
2ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
3c586b ¤   ¤   ¤   ¤   ¤   ¤   else /* Raw output part #1 */
63c097 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DoBufOutput(fOut1, pOutPart1);
adaf5a
732910 ¤   ¤   ¤   ¤   ¤   ¤   if (bReallyParse2) /* Parse part #2 */
f08fec ¤   ¤   ¤   ¤   ¤   ¤   {
0d61e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(pOutPart2, fOut2, OutPart2MimePtr,¶
ac0f2d ·bPart2DeMime, pParsePart2State))
b69299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
85db3c ¤   ¤   ¤   ¤   ¤   ¤   }
b145a7 ¤   ¤   ¤   ¤   ¤   ¤   else /* Raw output part #2 */
7a3d24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DoBufOutput(fOut2, pOutPart2);
ff1c89 ¤   ¤   ¤   ¤   ¤   }
116eb6 ¤   ¤   ¤   ¤   } while ((nStatus == FILE1847_OK) && (ret == RFC1847_BUFFERFULL¶
6d1445 ));
a4af5a
d8fa1d ¤   ¤   ¤   ¤   if (ret == RFC1847_FAIL)
d6fc2c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
e8af5a
27e5d1 ¤   ¤   ¤   ¤   if ((nStatus == FILE1847_OK) && (progress))
3772c3 ¤   ¤   ¤   ¤   {
d27576 ¤   ¤   ¤   ¤   ¤   // Update the progress and check for abort
727fc4 ¤   ¤   ¤   ¤   ¤   nPercentComplete = (int) ((((double)ftell(fIn))/nTotalInLen¶
cc7e6b ) * 100.0);
--affa 000d7ecb82a40110200 Page 6 of file1847.cpp
8425ab ¤   ¤   ¤   ¤   ¤   progData.value = (long) nPercentComplete;
0319e8 ¤   ¤   ¤   ¤   ¤   if (progress(&progData) ? 1 : 0)
667618 ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
e22613 ¤   ¤   ¤   ¤   }
1fad4c ¤   ¤   ¤   } while ((nStatus == FILE1847_OK) && (!feof(fIn)) && (!ferror(fIn))¶
b56275 );
a4af5a
126f1f ¤   ¤   ¤   if (nStatus == FILE1847_OK)
a9f776 ¤   ¤   ¤   {
45a14f ¤   ¤   ¤   ¤   if (bReallyParse1) /* Parse part #1 */
2562cc ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(NULL, fOut1, OutPart1MimePtr, bPart1DeMime¶
82e822 , pParsePart1State))
1baeb1 ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
15af5a
3f2ec9 ¤   ¤   ¤   ¤   if (bReallyParse2) /* Parse part #2 */
e3ab60 ¤   ¤   ¤   ¤   ¤   if (!DoParsePart(NULL, fOut2, OutPart2MimePtr, bPart2DeMime¶
793e25 , pParsePart2State))
3faeb1 ¤   ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
cba3a6 ¤   ¤   ¤   }
b70fe4 ¤   ¤   }
ac0e1d ¤   ¤   else
58ff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
7caf5a
7c17d3 ¤   ¤   delete_PartParseState(pParsePart1State);
9fc1d4 ¤   ¤   delete_PartParseState(pParsePart2State);
ce1b52 ¤   ¤
85d92c ¤   ¤   delete_parse_state(pState);
b767c5 ¤
fb0ee5 ¤   ¤   delete_buf(pOutPart1);
fd2b28 ¤   ¤   delete_buf(pOutPart2);
a17ca0 ¤   ¤   delete_buf(pInBuf);
c89371 ¤   }
840e24 ¤   else
5ed0b1 ¤   ¤   nStatus = FILE1847_FAIL; // Files did not open -- error
9eaf5a
973f89 ¤   safeclose(fIn);
eb614f ¤   safeclose(fOut1);
424482 ¤   safeclose(fOut2);
02af5a
ae844e ¤   return(nStatus);
24efe6 }
1faf5a
9ebf23 /* ------------------------------------------------------------------------ */
8caf5a
b5c4aa /* ·DoCreatePartsOutput (static)
94775e ·*
dc8245 ·* ·Private function used to pipe 1847 output to a file.
b1495d ·*/
dab798 static int DoCreatePartsOutput(emsMIMEtypeP mimePtr,
5a3c3d ¤   ¤   ¤   ¤   ···BufTypePtr pInPart1,
5ed359 ¤   ¤   ¤   ¤   ···BufTypePtr pInPart2,
b30bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
4d57e1 ¤   ¤   ¤   ¤   ···FILE *fOut)
eebb36 {
4643e6 ¤   BufTypePtr pOutBuf = makesize_buf(kBufferSize);
57a66d ¤   unsigned int nOutLen, ret;
c857c4 ¤   char *cp;
62af5a
cf723c ¤   if (pOutBuf)
26c7a1 ¤   {
7233b9 ¤   ¤   if (pInPart1)
208e90 ¤   ¤   ¤   resetpos_buf(pInPart1);
2faf5a
ffdcdd ¤   ¤   if (pInPart2)
0eab5d ¤   ¤   ¤   resetpos_buf(pInPart2);
39af5a
e44392 ¤   ¤   do {
366916 ¤   ¤   ¤   // Clear the output
fdce6c ¤   ¤   ¤   emptybuf_buf(pOutBuf);
55af5a
ce5c49 ¤   ¤   ¤   // Do the 1847-dance
d7886c ¤   ¤   ¤   ret = rfc1847_create(mimePtr, pOutBuf, pInPart1, pInPart2, pState);
--db5b 000ab1ccb5340110200 Page 7 of file1847.cpp
e0af5a
29d054 ¤   ¤   ¤   // Output whatever we got
326f9f ¤   ¤   ¤   if ((nOutLen = buflen_buf(pOutBuf)) > 0)
5af776 ¤   ¤   ¤   {
acb92e ¤   ¤   ¤   ¤   cp = getbuf_buf(pOutBuf);
5dea2d ¤   ¤   ¤   ¤   fwrite(cp, 1, nOutLen, fOut);
35a3a6 ¤   ¤   ¤   }
386afd ¤   ¤   } while (ret == RFC1847_BUFFERFULL);
009371 ¤   }
590e24 ¤   else
76a89d ¤   ¤   return (FALSE); // Could not create buffer
8daf5a
daa169 ¤   delete_buf(pOutBuf);
27af5a
fb0bfb ¤   return (ret != RFC1847_FAIL);
2cefe6 }
58af5a
c6bf23 /* ------------------------------------------------------------------------ */
e8af5a
a01e54 /* ·DoCreateStringOutput (static)
84775e ·*
d71de2 ·* ·Private function used to send a C-string through the 1847 creator and
d79019 ·* ·eventually pipe the 1847 output to a file.
74495d ·*/
dbf32b static int DoCreateStringOutput(const char *pStr,
e7e775 ¤   ¤   ¤   ¤   ···int nPart,
1097ec ¤   ¤   ¤   ¤   ···emsMIMEtypeP mimePtr,
560bd0 ¤   ¤   ¤   ¤   ···createStatePtr pState,
2757e1 ¤   ¤   ¤   ¤   ···FILE *fOut)
2bbb36 {
36e2ca ¤   BufTypePtr pTmpBuf = make_buf();
b70e94 ¤   int ret = RFC1847_FAIL;
ebaf5a
e2f5a1 ¤   if (pTmpBuf)
9ac7a1 ¤   {
ab385f ¤   ¤   // Manually setup the buffer structure -- kind of ugly, but
a31350 ¤   ¤   // more effiecient than copying the string
15673c ¤   ¤   pTmpBuf->buf = (char *) pStr;
70381b ¤   ¤   pTmpBuf->len = strlen(pStr);
b25407 ¤   ¤   pTmpBuf->buf_size = pTmpBuf->len + 1;
8bd920 ¤   ¤   resetpos_buf(pTmpBuf);
fdaf5a
be66e2 ¤   ¤   // Now output the buffer
131ff2 ¤   ¤   ret = DoCreatePartsOutput(mimePtr,
a42432 ¤   ¤   ¤   ((nPart == 1) ? pTmpBuf : NULL), /* Part 1 */
5e2eb5 ¤   ¤   ¤   ((nPart == 2) ? pTmpBuf : NULL), /* Part 2 */
c0a8d1 ¤   ¤   ¤   pState,
dffaca ¤   ¤   ¤   fOut);
ceaf5a
848589 ¤   ¤   clear_buf(pTmpBuf); // Unassociate buffer with string
4d1558 ¤   ¤   delete_buf(pTmpBuf); // Delete buffer struct -- AFTER we clear it's con¶
c4f3a3 tents
4b9371 ¤   }
2c0e24 ¤   else
24a89d ¤   ¤   return (FALSE); // Could not create buffer
e9af5a
9e0bfb ¤   return (ret != RFC1847_FAIL);
c8efe6 }
89af5a
80bf23 /* ------------------------------------------------------------------------ */
74af5a
3a0b1c /* ·DoCreateOnePart (static)
55775e ·*
aa75cd ·* ·Private function used to pipe a given file through the 1847 creator as
ba695e ·* ·either part 1 or part 2. All De-mime stuff is also done here.
b6495d ·*/
12be35 static int DoCreateOnePart(emsMIMEtypeP InPartMimePtr,
3c13ac ¤   ¤   ¤   ¤   ¤   ·emsMIMEtypeP OutMimePtr,
ef0da2 ¤   ¤   ¤   ¤   ¤   ·TrEncType InPartCTE,
8e4c6a ¤   ¤   ¤   ¤   ¤   ·FILE *fIn,
6369a4 ¤   ¤   ¤   ¤   ¤   ·FILE *fOut,
ab0e17 ¤   ¤   ¤   ¤   ¤   ·int nPart,
--328f 000f4d7835840110200 Page 8 of file1847.cpp
09f877 ¤   ¤   ¤   ¤   ¤   ·long nPreLen,
94bfd8 ¤   ¤   ¤   ¤   ¤   ·long nTotalInLen,
a52114 ¤   ¤   ¤   ¤   ¤   ·createStatePtr pState,
7d733c ¤   ¤   ¤   ¤   ¤   ·emsProgress progress)
27bb36 {
2fc2e6 ¤   BufTypePtr pInBuf = makesize_buf(kBufferSize);
5eaf5a
587662 ¤   if (!pInBuf)
481aa4 ¤   ¤   return (FILE1847_FAIL); // Could not create buffer -- error
feaf5a
c8a5c4 ¤   int nStatus = FILE1847_OK;
85af5a
8c3b64 ¤   // Do InPartMimePtr (Content-Type) header
869025 ¤   if ((nStatus == FILE1847_OK) && (InPartMimePtr))
fac7a1 ¤   {
bb91c5 ¤   ¤   char *pCT = string_mime_type(InPartMimePtr);
cb1b52 ¤   ¤
8202b4 ¤   ¤   if (pCT)
325b34 ¤   ¤   {
53b399 ¤   ¤   ¤   if (!DoCreateStringOutput(pCT, nPart, OutMimePtr, pState, fOut))
01fa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
86bb8c ¤   ¤   ¤   else
57500e ¤   ¤   ¤   ¤   if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fO¶
dbdf5a ut))
44fc2c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
4c0fe4 ¤   ¤   }
060e1d ¤   ¤   else
56ff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
f2af5a
db316a ¤   ¤   safefree(pCT);
439371 ¤   }
11af5a
d763bb ¤   // Do InPartCTE (Content-Transfer-Encoding) header
bdfca4 ¤   if ((nStatus == FILE1847_OK) && (InPartCTE != CTE_NONE))
dcc7a1 ¤   {
03213d ¤   ¤   char *pCTE = rfc822_make_cte(InPartCTE);
941b52 ¤   ¤
85f542 ¤   ¤   if (pCTE)
4f5b34 ¤   ¤   {
674ea6 ¤   ¤   ¤   if (!DoCreateStringOutput(pCTE, nPart, OutMimePtr, pState, fOut))
97fa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
49bb8c ¤   ¤   ¤   else
a3500e ¤   ¤   ¤   ¤   if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fO¶
1cdf5a ut))
15fc2c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
330fe4 ¤   ¤   }
e90e1d ¤   ¤   else
74ff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
1daf5a
b6f2b0 ¤   ¤   safefree(pCTE);
bc9371 ¤   }
36af5a
86ff2f ¤   // Do blank line -- only if we put out some header already
1d65b8 ¤   if ((nStatus == FILE1847_OK) && ((InPartMimePtr) || (InPartCTE != CTE_NONE)¶
fcc454 ))
09c7a1 ¤   {
d89f1c ¤   ¤   if (!DoCreateStringOutput("\r\n", nPart, OutMimePtr, pState, fOut))
afff79 ¤   ¤   ¤   nStatus = FILE1847_FAIL;
719371 ¤   }
5aaf5a
181e5a ¤   char *preEncBuffer = NULL;
8c241e ¤   unsigned int preEncBufLen;
0caf5a
a59b0d ¤   Enc64Ptr e64state = NULL; // Used by Encode64()
608cae ¤   EncQPPtr eQPstate = NULL; // Used by EucodeQP()
59af5a
b821b6 ¤   if (nStatus == FILE1847_OK)
6dc7a1 ¤   {
4ba9c0 ¤   ¤   switch (InPartCTE)
205b34 ¤   ¤   {
470d03 ¤   ¤   ¤   // BASE64
f48a6f ¤   ¤   ¤   case CTE_Base64:
--82cb 0008d40adbb40110200 Page 9 of file1847.cpp
99f776 ¤   ¤   ¤   {
12c52e ¤   ¤   ¤   ¤   // BASE64 expands about 1/3
801385 ¤   ¤   ¤   ¤   preEncBufLen = ((kBufferSize * 6) / 10);
302533 ¤   ¤   ¤   ¤   preEncBuffer = (char *) malloc(preEncBufLen);
09af5a
57672c ¤   ¤   ¤   ¤   if (!preEncBuffer)
57795c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL; // Could not create buffer
18af5a
b278c4 ¤   ¤   ¤   ¤   e64state = (Enc64Ptr) malloc(sizeof(Enc64)); // Used by Encode6¶
59a096 4()
6ce2bb ¤   ¤   ¤   ¤   e64state->partialCount = e64state->bytesOnLine = 0;
e8a3a6 ¤   ¤   ¤   }
2ecdcb ¤   ¤   ¤   break;
abaf5a
3e1acb ¤   ¤   ¤   // QUOTED-PRINTABLE
a707eb ¤   ¤   ¤   case CTE_QP:
4ef776 ¤   ¤   ¤   {
e16d85 ¤   ¤   ¤   ¤   // QP expands max of 3 times
d4ae86 ¤   ¤   ¤   ¤   preEncBufLen = (kBufferSize / 4);
282533 ¤   ¤   ¤   ¤   preEncBuffer = (char *) malloc(preEncBufLen);
98af5a
f3672c ¤   ¤   ¤   ¤   if (!preEncBuffer)
43795c ¤   ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL; // Could not create buffer
a5af5a
65898b ¤   ¤   ¤   ¤   eQPstate = (EncQPPtr) malloc(sizeof(EncQP)); // Used by Encode6¶
ada096 4()
11d6de ¤   ¤   ¤   ¤   eQPstate->nCurLineLen = 0;
dc52e3 ¤   ¤   ¤   ¤   eQPstate->cLastChar = '\0';
34a3a6 ¤   ¤   ¤   }
b8cdcb ¤   ¤   ¤   break;
a5af5a
f6d487 ¤   ¤   ¤   // Otherwise, no encoding
a3db68 ¤   ¤   ¤   default:
78f776 ¤   ¤   ¤   {
acdbe4 ¤   ¤   ¤   ¤   preEncBufLen = 0;
67a3a6 ¤   ¤   ¤   }
84cdcb ¤   ¤   ¤   break;
3f0fe4 ¤   ¤   }
3d9371 ¤   }
74af5a
244123 ¤   size_t nReadLen = 0;
17146e ¤   int nPercentComplete = 0;
04be67 ¤   emsProgressData progData;
1daf5a
7d8fb9 ¤   progData.size = sizeof(emsProgressData);
b63229 ¤   progData.value = 0L;
fc6e66 ¤   progData.message = NULL;
4aaf5a
76cd49 ¤   // Do pInPartFilename
917861 ¤   while ((nStatus == FILE1847_OK) && (!feof(fIn)) && (!ferror(fIn)))
03c7a1 ¤   {
e1de61 ¤   ¤   emptybuf_buf(pInBuf);
efaf5a
b4a9c0 ¤   ¤   switch (InPartCTE)
dd5b34 ¤   ¤   {
ea8a6f ¤   ¤   ¤   case CTE_Base64:
01f776 ¤   ¤   ¤   {
505410 ¤   ¤   ¤   ¤   nReadLen = fread(preEncBuffer, sizeof(char), preEncBufLen, fIn);
d2a7cf ¤   ¤   ¤   ¤   nReadLen = Encode64(preEncBuffer, nReadLen, getbuf_buf(pInBuf),¶
29c52a ·e64state);
42a3a6 ¤   ¤   ¤   }
c3cdcb ¤   ¤   ¤   break;
b6af5a
c907eb ¤   ¤   ¤   case CTE_QP:
24f776 ¤   ¤   ¤   {
0f5410 ¤   ¤   ¤   ¤   nReadLen = fread(preEncBuffer, sizeof(char), preEncBufLen, fIn);
7e070f ¤   ¤   ¤   ¤   nReadLen = EncodeQP(preEncBuffer, nReadLen, getbuf_buf(pInBuf),¶
a8d2ae ·eQPstate);
40a3a6 ¤   ¤   ¤   }
9bcdcb ¤   ¤   ¤   break;
02af5a
8d0d94 ¤   ¤   ¤   default: /* 7bit, 8bit, binary, none */
--8f45 00026326be540110200 Page 10 of file1847.cpp
99f776 ¤   ¤   ¤   {
de38dd ¤   ¤   ¤   ¤   nReadLen = fread(getbuf_buf(pInBuf), sizeof(char), bufsize_buf(¶
e22416 pInBuf), fIn);
b0a3a6 ¤   ¤   ¤   }
45cdcb ¤   ¤   ¤   break;
510fe4 ¤   ¤   }
d3af5a
3c84fe ¤   ¤   if (nReadLen > 0)
a15b34 ¤   ¤   {
231dbe ¤   ¤   ¤   setlen_buf(pInBuf, nReadLen);
e8af5a
a5a652 ¤   ¤   ¤   if (!DoCreatePartsOutput(OutMimePtr,
771c52 ¤   ¤   ¤   ¤   ¤   ((nPart == 1) ? pInBuf : NULL), /* Part 1 */
36f3f9 ¤   ¤   ¤   ¤   ¤   ((nPart == 2) ? pInBuf : NULL), /* Part 2 */
a02440 ¤   ¤   ¤   ¤   ¤   pState,
6f85e3 ¤   ¤   ¤   ¤   ¤   fOut))
cafa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
680fe4 ¤   ¤   }
53af5a
0b3f2a ¤   ¤   if ((nStatus == FILE1847_OK) && (progress))
5e5b34 ¤   ¤   {
cb72af ¤   ¤   ¤   // Update the progress and check for abort
89bf27 ¤   ¤   ¤   nPercentComplete = (int) (((((double)ftell(fIn) + nPreLen))/nTotalI¶
2ea072 nLen) * 100.0);
85c4dc ¤   ¤   ¤   progData.value = (long) nPercentComplete;
3e186e ¤   ¤   ¤   if (progress(&progData) ? 1 : 0)
3100e3 ¤   ¤   ¤   ¤   nStatus = FILE1847_ABORT;
1a0fe4 ¤   ¤   }
0e9371 ¤   }
0caf5a
e821b6 ¤   if (nStatus == FILE1847_OK)
03c7a1 ¤   {
882a0b ¤   ¤   // Finish part -- if needed
c8a9c0 ¤   ¤   switch (InPartCTE)
7d5b34 ¤   ¤   {
438a6f ¤   ¤   ¤   case CTE_Base64:
38f776 ¤   ¤   ¤   {
d0d7a6 ¤   ¤   ¤   ¤   nReadLen = Encode64(NULL, 0, getbuf_buf(pInBuf), e64state);
9fa3a6 ¤   ¤   ¤   }
28cdcb ¤   ¤   ¤   break;
c7af5a
9d07eb ¤   ¤   ¤   case CTE_QP:
e4f776 ¤   ¤   ¤   {
67f066 ¤   ¤   ¤   ¤   nReadLen = EncodeQP(NULL, 0, getbuf_buf(pInBuf), eQPstate);
66a3a6 ¤   ¤   ¤   }
b5cdcb ¤   ¤   ¤   break;
9baf5a
1f0d94 ¤   ¤   ¤   default: /* 7bit, 8bit, binary, none */
fef776 ¤   ¤   ¤   {
3b1694 ¤   ¤   ¤   ¤   nReadLen = 0;
afa3a6 ¤   ¤   ¤   }
63cdcb ¤   ¤   ¤   break;
760fe4 ¤   ¤   }
d8af5a
5284fe ¤   ¤   if (nReadLen > 0)
fb5b34 ¤   ¤   {
4b1dbe ¤   ¤   ¤   setlen_buf(pInBuf, nReadLen);
f8af5a
f2a652 ¤   ¤   ¤   if (!DoCreatePartsOutput(OutMimePtr,
fa1c52 ¤   ¤   ¤   ¤   ¤   ((nPart == 1) ? pInBuf : NULL), /* Part 1 */
8ff3f9 ¤   ¤   ¤   ¤   ¤   ((nPart == 2) ? pInBuf : NULL), /* Part 2 */
762440 ¤   ¤   ¤   ¤   ¤   pState,
ca85e3 ¤   ¤   ¤   ¤   ¤   fOut))
9dfa94 ¤   ¤   ¤   ¤   nStatus = FILE1847_FAIL;
6a0fe4 ¤   ¤   }
d79371 ¤   }
e5af5a
8f52d2 ¤   safefree(e64state);
e84556 ¤   safefree(eQPstate);
9f2871 ¤   safefree(preEncBuffer);
eb8ac5 ¤   delete_buf(pInBuf);
26af5a
--7bd2 000065cd58540110200 Page 11 of file1847.cpp
2c83bb ¤   return (nStatus);
05efe6 }
bdaf5a
55bf23 /* ------------------------------------------------------------------------ */
38af5a
1da4cd /* ·DoParsePart (static)
47775e ·*
8aa66d ·* ·Private function used to pipe the output of 1847 parsing into a file.
5b495d ·*/
bec02d static int DoParsePart(BufTypePtr pInBuf,
88d2f2 ¤   ¤   ¤   ¤   ·FILE *fOut,
e57303 ¤   ¤   ¤   ¤   ·emsMIMEtypeP *mimePtr,
893632 ¤   ¤   ¤   ¤   ·int bDeMime,
79c875 ¤   ¤   ¤   ¤   ·PartParseStatePtr pState)
6cbb36 {
f341b2 ¤   if (!pInBuf) // Input buf NULL indicates 'cleanup'
4fc7a1 ¤   {
622a9b ¤   ¤   if (!pState->bFoundHeader)
8ed10c ¤   ¤   ¤   return (FALSE);
690e1d ¤   ¤   else
693ec8 ¤   ¤   ¤   return (TRUE);
0a9371 ¤   }
86af5a
6ba6e4 ¤   if (!pState->bFoundHeader)
26c7a1 ¤   {
451a52 ¤   ¤   resetpos_buf(pState->pSearchBuf);
43af5a
f3cbc9 ¤   ¤   if (pState->nPrevEndMatch > 0)
ae5b34 ¤   ¤   {
b0bba0 ¤   ¤   ¤   /* Check for completion of span */
84af5a
55d467 ¤   ¤   ¤   // If doesn't continue match, returns zero
b47a08 ¤   ¤   ¤   // otherwise returns number of chars of pSearchBuf that have been m¶
27bf21 atched
55e594 ¤   ¤   ¤   unsigned int nNewMatched = completecount_buf(pInBuf, pState->pSearc¶
860366 hBuf, pState->nPrevEndMatch);
49af5a
b412e3 ¤   ¤   ¤   if (nNewMatched == buflen_buf(pState->pSearchBuf)) /* complete matc¶
0dd11b h made */
61f776 ¤   ¤   ¤   {
fe07cc ¤   ¤   ¤   ¤   pState->bFoundHeader = TRUE;
a60acc ¤   ¤   ¤   ¤   pState->nPrevEndMatch = 0;
5a199d ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, (buflen_buf(pState->pSearchBu¶
fce0f3 f) - (pState->nPrevEndMatch)));
48a3a6 ¤   ¤   ¤   }
2188c3 ¤   ¤   ¤   else if (nNewMatched != 0) /* Continued to match, but not completed¶
9bfb71 ·yet -- the input buffer is smaller than the pSearchBuf */
0bf776 ¤   ¤   ¤   {
a9405f ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
332d2b ¤   ¤   ¤   ¤   pState->nPrevEndMatch = nNewMatched;
632ae0 ¤   ¤   ¤   ¤   return (TRUE);
4aa3a6 ¤   ¤   ¤   }
7f2f52 ¤   ¤   ¤   else /* No match continuation */
e4f776 ¤   ¤   ¤   {
360acc ¤   ¤   ¤   ¤   pState->nPrevEndMatch = 0;
d1a3a6 ¤   ¤   ¤   }
6f0fe4 ¤   ¤   }
5baf5a
861a52 ¤   ¤   resetpos_buf(pState->pSearchBuf);
43af5a
44b655 ¤   ¤   // Still not found -- no span
a72a9b ¤   ¤   if (!pState->bFoundHeader)
b85b34 ¤   ¤   {
69f409 ¤   ¤   ¤   // Find match of pSearchBuf, either complete or end-spanning
5bd546 ¤   ¤   ¤   // return number of chars to skip before match
748930 ¤   ¤   ¤   unsigned int nSkip = skipcount_buf(pInBuf, pState->pSearchBuf);
701996 ¤   ¤   ¤   unsigned int nRemain = poslen_buf(pInBuf) - nSkip;
a7af5a
e3c888 ¤   ¤   ¤   if (nRemain == 0) // Not found
bbf776 ¤   ¤   ¤   {
34405f ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
062ae0 ¤   ¤   ¤   ¤   return (TRUE);
--2162 000ee5f70fe40110200 Page 12 of file1847.cpp
cfa3a6 ¤   ¤   ¤   }
41bb8c ¤   ¤   ¤   else
10bc95 ¤   ¤   ¤   if (nRemain > buflen_buf(pState->pSearchBuf)) /* Found 'complete' */
35f776 ¤   ¤   ¤   {
3007cc ¤   ¤   ¤   ¤   pState->bFoundHeader = TRUE;
e1429c ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, (nSkip + buflen_buf(pState->p¶
b89596 SearchBuf)) );
07a3a6 ¤   ¤   ¤   }
8c2a40 ¤   ¤   ¤   else // Partial possible
5ff776 ¤   ¤   ¤   {
a2ea66 ¤   ¤   ¤   ¤   pState->nPrevEndMatch = nRemain;
27405f ¤   ¤   ¤   ¤   bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf));
482ae0 ¤   ¤   ¤   ¤   return (TRUE);
23a3a6 ¤   ¤   ¤   }
2e0fe4 ¤   ¤   }
f9af5a
5d385e ¤   ¤   // ---------- Now we know it is found ----------
99af5a
d0a61f ¤   ¤   unsigned int nLen = buflen_buf(pState->pBuf);
61bfec ¤   ¤   char *pHeader = (char *) malloc(nLen + 1);
dcaf5a
af4bab ¤   ¤   strncpy(pHeader, getbuf_buf(pState->pBuf), nLen);
07af5a
c55b34 ¤   ¤   {
553ca3 ¤   ¤   ¤   char *pCT = rfc822_extract_header(pHeader, "Content-Type:");
a3af5a
2dae58 ¤   ¤   ¤   if (mimePtr)
e1f776 ¤   ¤   ¤   {
def2ee ¤   ¤   ¤   ¤   if (pCT)
ec72c3 ¤   ¤   ¤   ¤   {
4ac352 ¤   ¤   ¤   ¤   ¤   *mimePtr = parse_make_mime_type(pCT);
792613 ¤   ¤   ¤   ¤   }
d3fa07 ¤   ¤   ¤   ¤   else
0772c3 ¤   ¤   ¤   ¤   {
ca5619 ¤   ¤   ¤   ¤   ¤   *mimePtr = make_mime_type("text", "plain", "1.0");
702613 ¤   ¤   ¤   ¤   }
84a3a6 ¤   ¤   ¤   }
b0af5a
1ed38b ¤   ¤   ¤   safefree(pCT);
2d0fe4 ¤   ¤   }
63af5a
a949bf ¤   ¤   if (bDeMime)
3a5b34 ¤   ¤   {
1ff776 ¤   ¤   ¤   {
6247e1 ¤   ¤   ¤   ¤   char *pCTE = rfc822_extract_cte(pHeader);
f3086d ¤   ¤   ¤   ¤   if (pCTE)
778de7 ¤   ¤   ¤   ¤   ¤   pState->cte = rfc822_parse_cte(pCTE);
2dfa07 ¤   ¤   ¤   ¤   else
c03651 ¤   ¤   ¤   ¤   ¤   pState->cte = CTE_NONE; /* No CTE header, so no encoding */
cca98b ¤   ¤   ¤   ¤   safefree(pCTE);
2ba3a6 ¤   ¤   ¤   }
ddaf5a
f46552 ¤   ¤   ¤   switch (pState->cte)
f7f776 ¤   ¤   ¤   {
bfcab6 ¤   ¤   ¤   ¤   // BASE64
533139 ¤   ¤   ¤   ¤   case CTE_Base64:
1a72c3 ¤   ¤   ¤   ¤   {
b3dd7e ¤   ¤   ¤   ¤   ¤   // BASE64 expands about 1/3
3ddf72 ¤   ¤   ¤   ¤   ¤   unsigned int preEncBufLen = ((kBufferSize * 10) / 6);
4a2a85 ¤   ¤   ¤   ¤   ¤   pState->preEncBuffer = (char *) malloc(preEncBufLen);
26af5a
a2b7ef ¤   ¤   ¤   ¤   ¤   pState->d64state = (Dec64Ptr) malloc(sizeof(Dec64)); // Use¶
6c6c39 d by Decode64()
476975 ¤   ¤   ¤   ¤   ¤   pState->d64state->decoderState = 0;
29f8a7 ¤   ¤   ¤   ¤   ¤   pState->d64state->invalCount = 0;
b9c1ec ¤   ¤   ¤   ¤   ¤   pState->d64state->padCount = 0;
87a97f ¤   ¤   ¤   ¤   ¤   pState->d64state->partial = 0;
afb197 ¤   ¤   ¤   ¤   ¤   pState->d64state->wasCR = FALSE;
072613 ¤   ¤   ¤   ¤   }
28f622 ¤   ¤   ¤   ¤   break;
04af5a
ee9137 ¤   ¤   ¤   ¤   // QUOTED-PRINTABLE
--6c97 000f93d335240110200 Page 13 of file1847.cpp
0533b6 ¤   ¤   ¤   ¤   case CTE_QP:
cd72c3 ¤   ¤   ¤   ¤   {
c03f18 ¤   ¤   ¤   ¤   ¤   // QP expands max of 3 times
23c730 ¤   ¤   ¤   ¤   ¤   unsigned int preEncBufLen = (kBufferSize * 4);
b22a85 ¤   ¤   ¤   ¤   ¤   pState->preEncBuffer = (char *) malloc(preEncBufLen);
cbaf5a
d1acda ¤   ¤   ¤   ¤   ¤   pState->dQPstate = (DecQPPtr) malloc(sizeof(EncQP));
e4816c ¤   ¤   ¤   ¤   ¤   pState->dQPstate->CurState = qpNormal;
f75754 ¤   ¤   ¤   ¤   ¤   pState->dQPstate->cLastChar = 0;
b82613 ¤   ¤   ¤   ¤   }
3bf622 ¤   ¤   ¤   ¤   break;
e2af5a
dfe869 ¤   ¤   ¤   ¤   // Otherwise, no encoding
876ab9 ¤   ¤   ¤   ¤   default:
b5f622 ¤   ¤   ¤   ¤   break;
47a3a6 ¤   ¤   ¤   }
360fe4 ¤   ¤   }
f00e1d ¤   ¤   else
2a5b34 ¤   ¤   {
857fbe ¤   ¤   ¤   fwrite(getbuf_buf(pState->pBuf), sizeof(char), nLen, fOut);
b20fe4 ¤   ¤   }
d5af5a
914ea5 ¤   ¤   safefree(pHeader)
9187c1 ¤   ¤   free_buf(pState->pBuf);
569371 ¤   }
19af5a
3bf329 ¤   // ---------- Now we know it is found and header is init'd ----------
dcaf5a
2ebcc3 ¤   long errorcnt;
80af5a
c7ea59 ¤   switch (pState->cte)
82c7a1 ¤   {
bfbe32 ¤   ¤   case CTE_Base64:
8f5b34 ¤   ¤   {
d51014 ¤   ¤   ¤   unsigned int nReadLen = Decode64(getpos_buf(pInBuf), poslen_buf(pIn¶
91149c Buf), pState->preEncBuffer, pState->d64state, &errorcnt);
fc3a53 ¤   ¤   ¤   fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut);
9a0fe4 ¤   ¤   }
cc2f68 ¤   ¤   break;
88af5a
feb63a ¤   ¤   case CTE_QP:
9b5b34 ¤   ¤   {
bd70b8 ¤   ¤   ¤   unsigned int nReadLen = DecodeQP(getpos_buf(pInBuf), poslen_buf(pIn¶
70ce75 Buf), pState->preEncBuffer, pState->dQPstate, &errorcnt);
1d3a53 ¤   ¤   ¤   fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut);
140fe4 ¤   ¤   }
562f68 ¤   ¤   break;
a5af5a
089bd5 ¤   ¤   default: /* 7bit, 8bit, binary, none */
f75b34 ¤   ¤   {
cc4af9 ¤   ¤   ¤   fwrite(getpos_buf(pInBuf), sizeof(char), poslen_buf(pInBuf), fOut);
8f0fe4 ¤   ¤   }
032f68 ¤   ¤   break;
909371 ¤   }
0baf5a
5ee7c0 ¤   return (TRUE);
64efe6 }
3faf5a
42bf23 /* ------------------------------------------------------------------------ */
b2af5a
1eda0d /* ·create_PartParseState (static)
ef775e ·*
8c87a2 ·* ·Private function used initialize the parse state.
f0495d ·*/
70cae8 static PartParseStatePtr create_PartParseState()
e0bb36 {
3cac27 ¤   PartParseStatePtr p = (PartParseStatePtr) malloc(sizeof(PartParseState));
5eaf5a
2268fc ¤   if (p)
94c7a1 ¤   {
e5c42a ¤   ¤   p->bFoundHeader = FALSE;
f942b8 ¤   ¤   p->pBuf = make_buf();
--fff3 00148de7baa40110200 Page 14 of file1847.cpp
896c36 ¤   ¤   p->pSearchBuf = make_buf();
7ea9a4 ¤   ¤   strcpy_buf(p->pSearchBuf, "\r\n\r\n");
8ea625 ¤   ¤   p->cte = CTE_NONE;
66b628 ¤   ¤   p->nPrevEndMatch = 0;
6ef8bf ¤   ¤   p->preEncBuffer = NULL;
808034 ¤   ¤   p->d64state = NULL;
bc11a6 ¤   ¤   p->dQPstate = NULL;
cb9371 ¤   }
ecaf5a
5070cd ¤   return (p);
e2efe6 }
4baf5a
bdbf23 /* ------------------------------------------------------------------------ */
50af5a
fd44ed /* ·delete_PartParseState (static)
00775e ·*
84eb66 ·* ·Private function used to delete the parse state.
bc495d ·*/
38dcba static void delete_PartParseState(PartParseStatePtr p)
21bb36 {
9b68fc ¤   if (p)
f2c7a1 ¤   {
62b27f ¤   ¤   delete_buf(p->pBuf);
0d2ca3 ¤   ¤   delete_buf(p->pSearchBuf);
675794 ¤   ¤   safefree(p->preEncBuffer);
b72010 ¤   ¤   safefree(p->d64state);
9e3794 ¤   ¤   safefree(p->dQPstate);
6b1b52 ¤   ¤
48c706 ¤   ¤   safefree(p);
d39371 ¤   }
24efe6 }
02af5a
94bf23 /* ------------------------------------------------------------------------ */
a1af5a
900892 /* ·DoBufOutput (static)
6a775e ·*
218bfa ·* ·Private function used to output a buffer.
be495d ·*/
625190 static void DoBufOutput(FILE *fOut, BufTypePtr pBuf)
b7bb36 {
7010fc ¤   fwrite(getpos_buf(pBuf), sizeof(char), poslen_buf(pBuf), fOut);
48be43 }¶
--61ee 000f465507640110201 Page 1 of file1847.h
bc38e5 /*
d75fd4 ·* ·Filename: file1847.h
29775e ·*
92e658 ·* ·Last Edited: Wednesday, October 2, 1996
6e775e ·*
35005b ·* ·Author: Scott Manjourides
94775e ·*
11ea75 ·* ·Copyright 1995, 1996 QUALCOMM Inc.
b4775e ·*
f3c179 ·* ·Send comments and questions to <emsapi-info@qualcomm.com>
d7495d ·*/
d3af5a
bf6b95 #ifndef EMS_FILE1847_H
bb3c64 #define EMS_FILE1847_H
18af5a
12568d #include <windows.h> /* Must be included for ems-win.h */
18fbd1 #include "ems-win.h"
3aaf5a
46bde1 #include "encoding.h"
2527f6 #include "rfc1847.h"
d3af5a
ed18b2 enum { FILE1847_FAIL = (-1), FILE1847_ABORT = (0), FILE1847_OK = (1) };
c4af5a
8b7890 /* ------------------------------------------------------------------------- */
76af5a
67ee80 /* ·CreateTmpFile
b6775e ·*
b66438 ·* ·Creates a empty, unique, temporary file in the users 'TEMP'
eb4970 ·* ···directory.
fe775e ·*
5db7ce ·* ·No arguments.
2c775e ·*
a359a2 ·* ·Returns a pointer to the filename string. This should be
2acb59 ·* ···considered temporary data, and should never be free()'d.
9d495d ·*/
970870 char *CreateTmpFile();
15af5a
ebbf23 /* ------------------------------------------------------------------------ */
e7af5a
85dc23 /* ·rfc1847_file_create
6f775e ·*
ba9c8e ·* ·Creates RFC1847 MIME structure.
2c775e ·*
9e6a22 ·* ·Args:
5d3da4 ·* ···pOutFilename ····[IN] ····Output filename ** WRITE-ONLY **
a81aa8 ·* ···OutMimePtr ······[IN/OUT] MIME type of output -- boundary param will be a¶
19f634 dded
31a061 ·* ···InPart1MimePtr ··[IN] ····MIME type of part 1
4a43df ·* ···InPart1CTE ······[IN] ····Content-transfer-encoding for part 1
d21941 ·* ···pInPart1Filename [IN] ····Input filename for part 1 ** READ-ONLY **
269847 ·* ···InPart2MimePtr ··[IN] ····MIME type of part 2
591fd0 ·* ···InPart2CTE ······[IN] ····Content-transfer-encoding for part 2
1480bd ·* ···pInPart2Filename [IN] ····Input filename for part 2 ** READ-ONLY **
f519c2 ·* ···progress ········[IN] ····EMS progress callback function
8d775e ·*
af0ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
9e495d ·*/
21c7ea int rfc1847_file_create(const char *pOutFilename,
1f303e ¤   ¤   ¤   ¤   ···emsMIMEtypeP OutMimePtr,
9caf5a
860178 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart1MimePtr,
75cfb5 ¤   ¤   ¤   ¤   ···TrEncType InPart1CTE,
ed35df ¤   ¤   ¤   ¤   ···const char *pInPart1Filename,
33af5a
b07511 ¤   ¤   ¤   ¤   ···emsMIMEtypeP InPart2MimePtr,
33c3c8 ¤   ¤   ¤   ¤   ···TrEncType InPart2CTE,
2acb6c ¤   ¤   ¤   ¤   ···const char *pInPart2Filename,
fdaf5a
4fd178 ¤   ¤   ¤   ¤   ···emsProgress progress);
f8af5a
b1bf23 /* ------------------------------------------------------------------------ */
f4af5a
--ddaf 00170b445b840110201 Page 2 of file1847.h
31aa24 /* ·rfc1847_file_parse
96775e ·*
a9911a ·* ·Parses RFC1847 MIME structure.
c3775e ·*
5b6a22 ·* ·Args:
04894a ·* ···pInFilename ······[IN] ·Input filename of file to parse ** READ-ONLY **
4dd77d ·* ···InMimePtr ········[OUT] MIME type of input file
14974c ·* ···pOutPart1Filename [IN] ·Output filename for part 1 ** WRITE-ONLY **
9d2072 ·* ···OutPart1MimePtr ··[OUT] MIME type of created part 1
1a8f77 ·* ···bPart1DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
4ff1f2 t 1?
9e07da ·* ···pOutPart2Filename [IN] ·Output filename for part 2 ** WRITE-ONLY **
aa5057 ·* ···OutPart2MimePtr ··[OUT] MIME type of created part 2
e72f00 ·* ···bPart2DeMime ·····[IN] ·Boolean: Remove header and transfer encoding, par¶
021e96 t 2?
e94ccd ·* ···progress ·········[IN] ·EMS progress callback function
20775e ·*
170ede ·* ·Returns boolean. TRUE for success, FALSE for failure.
57495d ·*/
66c74a int rfc1847_file_parse(const char *pInFilename,
c43a88 ¤   ¤   ¤   ¤   ··emsMIMEtypeP *InMimePtr,
9eaf5a
0cfb99 ¤   ¤   ¤   ¤   ··const char *pOutPart1Filename,
e5af17 ¤   ¤   ¤   ¤   ··emsMIMEtypeP *OutPart1MimePtr,
7aaddb ¤   ¤   ¤   ¤   ··int bPart1DeMime,
38af5a
ab052a ¤   ¤   ¤   ¤   ··const char *pOutPart2Filename,
35db7e ¤   ¤   ¤   ¤   ··emsMIMEtypeP *OutPart2MimePtr,
287bdc ¤   ¤   ¤   ¤   ··int bPart2DeMime,
ed7e90 ¤   ¤   ¤   ¤   ··
b429d5 ¤   ¤   ¤   ¤   ··emsProgress progress);
5eaf5a
702c19 #endif /* EMS_FILE1847_H */¶

--6b20 0001999498f40110202 Page 1 of PGPcl.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
ddc952 ¤   PGPcl.h - header file for PGP ClientLib DLL
ea67c5 ¤
04af5a
911085 ¤   $Id: PGPcl.h,v 1.43.2.1 1998/09/28 19:43:29 wjb Exp $
81f7f7 ____________________________________________________________________________*/
a0e23d #ifndef Included_PGPcl_h¤   /* [ */
90cab1 #define Included_PGPcl_h
37af5a
704720 #include "pflPrefTypes.h"
8b69fa #include "pgpGroups.h"·
c6ed82 #include "pgpKeyServerPrefs.h"
d6af5a
b3860a #ifdef _PGPCLDLL
2f8bbd # define PGPclExport __declspec( dllexport )
4bdb21 #else
68078b # define PGPclExport __declspec( dllimport )
147454 #endif
67af5a
513379 #ifdef __cplusplus
176dad extern "C" {
da7454 #endif
8baf5a
09af5a
9e46e5 //¤ _______________________________________________________
dd465d //
9406b9 //¤ Library Initialization/Cleanup·
d5465d //
ab00d3 //¤ Open library and initialize
f3af5a
379d43 PGPError PGPclExport·
f29720 PGPclInitLibrary (PGPContextRef context);
03af5a
163fdf //¤ Close down DLL and purge passphrase buffers.
54af5a
709d43 PGPError PGPclExport·
265bfc PGPclCloseLibrary (VOID);
88af5a
2daf5a
5546e5 //¤ _______________________________________________________
79465d //
b20e55 //¤ Word wrap convenience functions·
e6465d //
b458d8 //¤ Wrap text using platform independent word wrap code.
066638 //¤ Output buffer must be freed with PGPclFreeWrapBuffer
2b465d //
cec802 //¤ Entry parameters :
5fb3b0 //¤ ¤   szInText¤   ¤   - input buffer
886676 //¤ ¤   wrapColumn¤ ¤   - column at which to wrap
80386b //¤ ¤   pszOutText¤ ¤   - buffer to receive pointer to
a5b679 //¤ ¤   ¤   ¤   ¤   ¤   ··output buffer containing wrapped text
94af5a
489d43 PGPError PGPclExport·
c61f8b PGPclWrapBuffer (
f467ec ¤   ¤   LPSTR¤  ¤   szInText,
534429 ¤   ¤   PGPUInt16¤  wrapColumn,
c8a3af ¤   ¤   LPSTR*¤ ¤   pszOutText);
1eaf5a
0ec5f8 //¤ Free previously-wrapped text buffer.
76465d //
23c802 //¤ Entry parameters :
1eff47 //¤ ¤   textBuffer¤ ¤   - buffer to free
11af5a
299d43 PGPError PGPclExport·
260844 PGPclFreeWrapBuffer (LPSTR textBuffer);
0caf5a
4baf5a
5046e5 //¤ _______________________________________________________
19465d //
--649e 00041ff2f1740110202 Page 2 of PGPcl.h
b11f57 //¤ Miscellaneous common dialogs and UI elements
d5af5a
b342a9 //¤ Post PGP preferences property sheets.
36465d //
d8487f //¤ This function posts the "PGP Preferences" property
2a75a5 //¤ sheet dialog boxes. ·Appropriate calls are made into
67ba0b //¤ the pgpkeydb library to set the preferences.
a9465d //
30c802 //¤ Entry parameters :
6df7bc //¤ ¤   Context¤¤   - PGP library context
becccb //¤ ¤   hWndParent¤ - handle of parent window
4c4745 //¤ ¤   iStartsheet¤- zero-based index of property sheet·
2ae678 // ···················page to display initially.
0504d7 //¤ ¤   ¤   ¤   ¤   ··use the below-defined constants
986cc7 //¤ ¤   keysetMain¤ - main keyset, if available. ·If not
5eab2b //¤ ¤   ¤   ¤   ¤   ··available, NULL is OK.
2f465d //
1b45fb //¤ This function returns kPGPError_UserAbort (if the user·
00d28e //¤ presses the cancel button)
17af5a
5ef98e //¤ preferences pages (used for "iStartsheet")
97bef8 #define PGPCL_GENERALPREFS¤ ¤   ¤   0
91fb39 #define PGPCL_KEYRINGPREFS¤ ¤   ¤   1
ac00d6 #define PGPCL_EMAILPREFS¤   ¤   ¤   2
274d14 #define PGPCL_KEYSERVERPREFS¤   ¤   3
e7afa2 #define PGPCL_ADVANCEDPREFS¤¤   ¤   4
36af5a
509d43 PGPError PGPclExport·
940b3f PGPclPreferences (
9a57dd ¤   ¤   PGPContextRef¤  Context,·
7fac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
0b82c1 ¤   ¤   INT¤¤   ¤   ¤   iStartsheet,
7334a0 ¤   ¤   PGPKeySetRef¤   keysetMain);
75af5a
38c568 //¤ Get descriptive string for error code for encode/decode modules
3a465d //
e5c802 //¤ Entry parameters :
bcaafb //¤ ¤   iCode¤  ¤   - error code returned by pgp or simple library routine
e89819 //¤ ¤   szString¤   - buffer to be filled with descriptive error message
955b55 //¤ ¤   uLen¤   ¤   - length of buffer in bytes
12465d //
0a5a1d //¤ This function evaluates iCode. ·If iCode warrants an error
34dc59 //¤ message, the buffer is filled with the message and the function
e14cc0 //¤ returns kPGPError_UnknownError. ·If no message is warranted,·
a95bed //¤ the function returns kPGPError_NoErr.
edaf5a
5e9d43 PGPError PGPclExport·
539e39 PGPclEncDecErrorToString (
b0422d ¤   ¤   INT¤¤   iCode,·
9ffdef ¤   ¤   LPSTR¤  szString, ·
eb8536 ¤   ¤   UINT¤   uLen);
d0af5a
8ef822 //¤ Putup error messagebox (if necessary) for encode/decode modules
05465d //
5bc802 //¤ Entry parameters :
77f201 //¤ ¤   hWnd¤   ¤   - handle of parent (NULL is OK)
e3aafb //¤ ¤   iCode¤  ¤   - error code returned by pgp or simple library routine
13465d //
805663 //¤ This function calls PGPclErrorToString to evaluate iCode.
b26646 //¤ If PGPclErrorToString returns kPGPError_UnknownError, a message·
cc8253 // ·box is posted containing the descriptive text. ·Otherwise no·
e26478 //¤ messagebox is displayed. ·This function returns the value returned·
e850ec //¤ by PGPclErrorToString.
0daf5a
269d43 PGPError PGPclExport·
54678c PGPclEncDecErrorBox (
1ff071 ¤   ¤   HWND¤   hWnd,
295efc ¤   ¤   INT¤¤   iCode);
b4af5a
f6809c //¤ Get descriptive string for error code
80465d //
41c802 //¤ Entry parameters :
--a8b3 0001fe4005340110202 Page 3 of PGPcl.h
04aafb //¤ ¤   iCode¤  ¤   - error code returned by pgp or simple library routine
959819 //¤ ¤   szString¤   - buffer to be filled with descriptive error message
f05b55 //¤ ¤   uLen¤   ¤   - length of buffer in bytes
3b465d //
265a1d //¤ This function evaluates iCode. ·If iCode warrants an error
fadc59 //¤ message, the buffer is filled with the message and the function
8c4cc0 //¤ returns kPGPError_UnknownError. ·If no message is warranted,·
545bed //¤ the function returns kPGPError_NoErr.
e2af5a
4c9d43 PGPError PGPclExport·
105e56 PGPclErrorToString (
53422d ¤   ¤   INT¤¤   iCode,·
6dfdef ¤   ¤   LPSTR¤  szString, ·
ed8536 ¤   ¤   UINT¤   uLen);
a9af5a
0d6d63 //¤ Putup error messagebox (if necessary)
cd465d //
afc802 //¤ Entry parameters :
aaf201 //¤ ¤   hWnd¤   ¤   - handle of parent (NULL is OK)
8daafb //¤ ¤   iCode¤  ¤   - error code returned by pgp or simple library routine
58465d //
555663 //¤ This function calls PGPclErrorToString to evaluate iCode.
6a6646 //¤ If PGPclErrorToString returns kPGPError_UnknownError, a message·
d88253 // ·box is posted containing the descriptive text. ·Otherwise no·
c66478 //¤ messagebox is displayed. ·This function returns the value returned·
9050ec //¤ by PGPclErrorToString.
4daf5a
ff9d43 PGPError PGPclExport·
32ddaf PGPclErrorBox (
6df071 ¤   ¤   HWND¤   hWnd,
615efc ¤   ¤   INT¤¤   iCode);
fdaf5a
32c66e //¤ Collect entropy from keyboard/mouse.
43465d //
50c802 //¤ Entry parameters :
75f7bc //¤ ¤   Context¤¤   - PGP library context
61cccb //¤ ¤   hWndParent¤ - handle of parent window
d68dca //¤ ¤   uNeeded¤¤   - bits of entropy needed
d6465d //
9fa953 //¤ This function returns kPGPError_UserAbort (if the user
9b8ea4 // ·presses the cancel button).
30af5a
8eaf5a
de9d43 PGPError PGPclExport·
b8a4e9 PGPclRandom (
7a1e61 ¤   ¤   PGPContextRef¤  Context,
94ac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
f1f35e ¤   ¤   UINT¤   ¤   ¤   uNeeded);
1caf5a
36d1e3 //¤ Post Help|About dialog with button for browser launch to specified URL.
66465d //
20c802 //¤ Entry parameters :
3c131f //¤ ¤   context¤¤   - current PGP context·
56cccb //¤ ¤   hWndParent¤ - handle of parent window
b25bce //¤ ¤   szVersion¤  - string containing version information
6a4767 //¤ ¤   ¤   ¤   ¤   ··to be displayed
9e2da3 //¤ ¤   ¤   ¤   ¤   ··NULL => use default version string
7a74dd //¤ ¤   szLinkText¤ - text to be displayed on link button
8b58ea //¤ ¤   ¤   ¤   ¤   ··(should be <= ~20 chars),
ce303a //¤ ¤   ¤   ¤   ¤   ··NULL => use default ("www.pgp.com")
4a6a7f //¤ ¤   szLink¤ ¤   - URL to which to jump
226109 //¤ ¤   ¤   ¤   ¤   ··NULL => use default ("http://www.pgp.com/")
85af5a
469d43 PGPError PGPclExport·
099a17 PGPclHelpAbout (
a0e958 ¤   ¤   PGPContextRef¤  context,
aeac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
936a2c ¤   ¤   LPSTR¤  ¤   ¤   szVersion, ¤
40686c ¤   ¤   LPSTR¤  ¤   ¤   szLinkText,·
a53526 ¤   ¤   LPSTR¤  ¤   ¤   szLink);
67af5a
1fbddb //¤ Post nag dialog with button for browser launch to specified URL.
--975f 000874edd4640110202 Page 4 of PGPcl.h
c1465d //
4ac802 //¤ Entry parameters :
56cccb //¤ ¤   hWndParent¤ - handle of parent window
b674dd //¤ ¤   szLinkText¤ - text to be displayed on link button
aa58ea //¤ ¤   ¤   ¤   ¤   ··(should be <= ~20 chars),
109e6c //¤ ¤   ¤   ¤   ¤   ··NULL => use default ("Order Now!")
326a7f //¤ ¤   szLink¤ ¤   - URL to which to jump
e86109 //¤ ¤   ¤   ¤   ¤   ··NULL => use default ("http://www.pgp.com/")
6faf5a
8e9d43 PGPError PGPclExport·
ea6224 PGPclNag (
34b771 ¤   ¤   HWND¤   hWndParent,·
35ac49 ¤   ¤   LPSTR¤  szLinkText,·
2ce669 ¤   ¤   LPSTR¤  szLink);
3baf5a
778ec2 //¤ Post Splash screen
e9465d //
bdc802 //¤ Entry parameters :
059f44 //¤ ¤   hWndParent¤ ¤   - handle of parent window (if NULL,
6b7c7d //¤ ¤   ¤   ¤   ¤   ¤   ··screen will not be dismissed until
a6f5f8 //¤ ¤   ¤   ¤   ¤   ¤   ··PGPclSetSplashParent is called·
bddf14 //¤ ¤   ¤   ¤   ¤   ¤   ··with a non-null value)
24d5dd //¤ ¤   uMilliseconds¤  - milliseconds to display splash
c4af5a
4b9d43 PGPError PGPclExport·
b8bdc8 PGPclSplash (
801e61 ¤   ¤   PGPContextRef¤  Context,
9bac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
1a407b ¤   ¤   UINT¤   ¤   ¤   uMS);
f7af5a
d68e03 //¤ Inform splash screen who its parent is
81465d //
7fc802 //¤ Entry parameters :
3d9f1a //¤ ¤   hWndParent¤ ¤   - handle of parent window
0baf5a
3c9d43 PGPError PGPclExport·
ffd23d PGPclSetSplashParent (HWND hWndParent);
5faf5a
d673f6 //¤ display and handle selective key import dialog
1b465d //
7dc802 //¤ Entry parameters :
cc9f1a //¤ ¤   hWndParent¤ ¤   - handle of parent window
7e3b26 //¤ ¤   KeySetToAdd¤- keyset containing keys to add
49d333 //¤ ¤   KeySetMain¤ ¤   - keyset to which keys will be added
cb465d //
450a22 //¤ Returns kPGPError_NoErr if no error
b5465d //
6baf5a
5e9d43 PGPError PGPclExport·
358940 PGPclQueryAddKeys (PGPContextRef¤   Context,
e198ee ¤   ¤   ¤   ¤   ···PGPtlsContextRef¤tlsContext,
133482 ¤   ¤   ¤   ¤   ···HWND¤¤   ¤   ¤   hWndParent,·
b7ba6f ¤   ¤   ¤   ¤   ···PGPKeySetRef¤¤   KeySetToAdd,¤   ¤   ¤
ec89dc ¤   ¤   ¤   ¤   ···PGPKeySetRef¤¤   KeySetMain);
87af5a
9fa3e3 //¤ display keyset and allow user to select keys
6b465d //
b4c802 //¤ Entry parameters :
6b9f1a //¤ ¤   hWndParent¤ ¤   - handle of parent window
76bcea //¤ ¤   pszPrompt¤  ¤   - prompt string
858d79 //¤ ¤   KeySetToDisplay¤- keyset containing keys to show
5029cf //¤ ¤   KeySetMain¤ ¤   - backing keyset·
975be8 //¤ ¤   pKeySetSelected¤- buffer to receive keyset ref of selected keys
0906ab //¤ ¤
3d465d //
9e0a22 //¤ Returns kPGPError_NoErr if no error
0a465d //
79af5a
149d43 PGPError PGPclExport·
7bd44a PGPclSelectKeys (PGPContextRef¤ ¤   Context,
8398ee ¤   ¤   ¤   ¤   ···PGPtlsContextRef¤tlsContext,
873482 ¤   ¤   ¤   ¤   ···HWND¤¤   ¤   ¤   hWndParent,·
--c0f9 00014fd28eb40110202 Page 5 of PGPcl.h
f476e4 ¤   ¤   ¤   ¤   ···LPSTR¤   ¤   ¤   pszPrompt,
55f634 ¤   ¤   ¤   ¤   ···PGPKeySetRef¤¤   KeySetToDisplay,¤   ¤   ¤
48e2e5 ¤   ¤   ¤   ¤   ···PGPKeySetRef¤¤   KeySetMain,
3b6e19 ¤   ¤   ¤   ¤   ···PGPKeySetRef*¤   pKeySetSelected);
3daf5a
f54852 //¤ Post RSA/DSA mix warning dialog·
53465d //
3dc802 //¤ Entry parameters :
59cccb //¤ ¤   hWndParent¤ - handle of parent window
3b465d //
574c80 //¤ Returns kPGPError_NoErr, kPGPError_UserAbort, or PGPCL_NO
c3465d //
16af5a
039d43 PGPError PGPclExport·
2fb8e8 PGPclRSADSAMixWarning (HWND hWnd, PGPBoolean *pbNeverShowAgain);
2aaf5a
f24800 //¤ Check for product expiration·
89465d //
c679a2 //¤ Returns kPGPError_FeatureNotAvailable if the beta or eval has expired,
fdccbd // ·and displays a message box. ·Returns kPGPError_NoErr and does nothing·
59cf81 //¤ if it's still valid.
bc465d //
bfc802 //¤ Entry parameters :
714303 //¤ ¤   hwnd¤   ¤   - Parent of window so we can show the MB. ·
4b4c47 //¤ ¤   ¤   ¤   ¤   ··NULL is acceptable.
a4af5a
5f9d43 PGPError PGPclExport·
df8ea4 PGPclIsExpired (HWND hwnd);
08af5a
e7eba6 //¤ Check for evaluation product expiration·
bf465d //
876c8a //¤ Returns kPGPError_FeatureNotAvailable if the evaluation has expired,·
d0c91f // ·and displays a message box. ·If the eval is partially expired, the·
c9dcd7 // ·nag screen will be displayed.
d5465d //
9ec802 //¤ Entry parameters :
8ee122 //¤ ¤   hwnd¤   ¤   Parent of window so we can show the MB or nag screen. ·
9b46a5 //¤ ¤   ¤   ¤   ¤   NULL is acceptable.
f6de52 //¤ ¤   nIndex¤ ¤   Type of expiration to test: Encrypt/Sign or All
bcaf5a
7c99f2 #define PGPCL_ENCRYPTSIGNEXPIRED¤   1
96bc89 #define PGPCL_ALLEXPIRED¤   ¤   ¤   2
63af5a
63d673 #if PGP_DEMO
ac8f2e ¤   BOOL PGPclExport PGPclEvalExpired (HWND hwnd, int nIndex);
2bdb21 #else
2549a5 ¤   #define¤PGPclEvalExpired(x,y)¤  kPGPError_NoErr
e32d33 #endif¤ // PGP_DEMO
72af5a
32af5a
b3af5a
a646e5 //¤ _______________________________________________________
ba465d //
31104f //¤ Group files convenience functions·
0daf5a
890b1b typedef struct _PGPclGROUPFILE
d0bb36 {
a2f366 ¤   PGPFileSpecRef¤ filespec;
2405f5 ¤   PGPGroupSetRef¤ groupset;
f48adc } PGPclGROUPFILE;
7aaf5a
166763 //¤ Opens standard groups file·
e0465d //
68c802 //¤ Entry parameters :
dd7aa4 //¤ ¤   ppGroup¤¤   ¤   address of buffer to receive pointer·
156929 //¤ ¤   ¤   ¤   ¤   ¤   to group file structure
32af5a
c59d43 PGPError PGPclExport·
c75386 PGPclOpenGroupFile (
7d6bed ¤   ¤   PGPContextRef¤  ¤   Context,
fcd3d5 ¤   ¤   PGPclGROUPFILE**¤   ppGroup);
14af5a
--6bd2 00049db152540110202 Page 6 of PGPcl.h
3b5537 //¤ Saves groups file
28465d //
cfc802 //¤ Entry parameters :
6eb67b //¤ ¤   pGroup¤ ¤   ¤   pointer to group file structure
dfaf5a
1eec6d PGPError PGPclExport
e4da4e PGPclSaveGroupFile (PGPclGROUPFILE* pGroup);
f3af5a
baee62 //¤ Closes groups file
f7465d //
34c802 //¤ Entry parameters :
96b67b //¤ ¤   pGroup¤ ¤   ¤   pointer to group file structure
caaf5a
a0efcb PGPError PGPclExport ¤
f7e52e PGPclCloseGroupFile (PGPclGROUPFILE* pGroup);
91af5a
eeaf5a
db46e5 //¤ _______________________________________________________
bb465d //
ed0c92 //¤ Preference files convenience functions·
0baf5a
526e14 //¤ Open client preferences file and returns PrefRef to caller
5e465d //
c9c802 //¤ Entry parameters :
731111 //¤ ¤   memMgr¤ ¤   - memory manager to user for allocating fileref
c4d9f1 //¤ ¤   pPrefRef¤   - pointer to buffer to receive PrefRef
49af5a
1a9d43 PGPError PGPclExport·
e938a9 PGPclOpenClientPrefs (
6963c2 ¤   ¤   PGPMemoryMgrRef¤memMgr,
d5b059 ¤   ¤   PGPPrefRef*¤¤   pPrefRef);
11af5a
8da5f9 //¤ Close, and optionally save changes to, open client preference
413497 // ·file. ·
fa465d //
97c802 //¤ Entry parameters :
d64990 //¤ ¤   PrefRef¤- PrefRef of file to close
df096b //¤ ¤   bSave¤  - TRUE => save changes before closing
09af5a
519d43 PGPError PGPclExport·
f5b835 PGPclCloseClientPrefs (
092396 ¤   ¤   PGPPrefRef¤ PrefRef,·
31c350 ¤   ¤   BOOL¤   ¤   bSave);
f4af5a
0cef26 //¤ Open admin preferences file and returns PrefRef to caller
aa465d //
25c802 //¤ Entry parameters :
6d3d2f //¤ ¤   memMgr¤ ¤   ¤   - memory manager to user for allocating fileref
579801 //¤ ¤   pPrefRef¤   ¤   - pointer to buffer to receive PrefRef
2b6c40 //¤ ¤   bLoadDefaults¤  - TRUE=>if file doesn't exist, then create
a110f5 //¤ ¤   ¤   ¤   ¤   ¤   ··and load default values
5156d0 //¤ ¤   ¤   ¤   ¤   ¤   ··FALSE=>if file doesn't exist, return error
5aaf5a
b6ec6d PGPError PGPclExport
0f5eef PGPclOpenAdminPrefs (
6c63c2 ¤   ¤   PGPMemoryMgrRef¤memMgr,
c2ac88 ¤   ¤   PGPPrefRef*¤¤   pPrefRef,·
bda2ea ¤   ¤   BOOL¤   ¤   ¤   bLoadDefaults);
76af5a
bd0aad //¤ Close, and optionally save changes to, open admin preference
193497 // ·file. ·
c5465d //
9dc802 //¤ Entry parameters :
34dec1 //¤ ¤   PrefRef¤¤   ¤   - PrefRef of file to close
c0de3b //¤ ¤   bSave¤  ¤   ¤   - TRUE => save changes before closing
f6af5a
079d43 PGPError PGPclExport·
a4ea2b PGPclCloseAdminPrefs (
c02396 ¤   ¤   PGPPrefRef¤ PrefRef,·
efc350 ¤   ¤   BOOL¤   ¤   bSave);
b2af5a
49af5a
--adfb 000bb592d1640110202 Page 7 of PGPcl.h
4046e5 //¤ _______________________________________________________
66465d //
2489a5 //¤ Miscellaneous convenience functions·
61af5a
e11fc4 //¤ Fills buffer with the path of the current PGP install.
56465d //
4cc802 //¤ Entry parameters :
0b6e12 //¤ ¤   szPath¤ ¤   buffer to receive string
9474c0 //¤ ¤   uLen¤   ¤   length of buffer in bytes
7267c5 ¤
0e9d43 PGPError PGPclExport·
6165fb PGPclGetPGPPath (
920296 ¤   ¤   LPSTR¤  szPath,·
618536 ¤   ¤   UINT¤   uLen);
beaf5a
766638 //¤ Launch web browser and send to specified page
a6465d //
22c802 //¤ Entry parameters :
ab098e //¤ ¤   pszURL¤ ¤   ¤   - URL to open
a6465d //
45af5a
ac9d43 PGPError PGPclExport·
c495d5 PGPclWebBrowse (LPSTR pszURL);
0caf5a
fd605d //¤ Sync keysets to resolve trust info discrepancies
70465d //
99c802 //¤ Entry parameters :
628000 //¤ ¤   context¤¤   - context ref
7a0b4a //¤ ¤   keysetMain¤ - main keyset containing trust info
b55848 //¤ ¤   keysetNew¤  - newly-imported keyset to sync with main
48af5a
d39d43 PGPError PGPclExport·
332981 PGPclSyncKeySets (
2ee958 ¤   ¤   PGPContextRef¤  context,
8e55dd ¤   ¤   PGPKeySetRef¤   keysetMain,
2c4bb9 ¤   ¤   PGPKeySetRef¤   keysetNew);
bbaf5a
d87a84 //¤ Convert info in SYSTEMTIME structure to number of days from today
37465d //
23c802 //¤ Entry parameters :
6c89ed //¤ ¤   pst¤¤   ¤   address of SYSTEMTIME structure containing data
bedb2a //¤ ¤   ¤   ¤   ¤   to convert
f9562c //¤ ¤   piDays¤ ¤   address of buffer to receive number of days from
76a0a3 //¤ ¤   ¤   ¤   ¤   today. ·Negative numbers are prior to today.
efaf5a
ffec6d PGPError PGPclExport
4087ca PGPclSystemTimeToDays (
158e47 ¤   ¤   SYSTEMTIME*¤pst,·
cea1db ¤   ¤   INT*¤   ¤   piDays);
00af5a
281b4a //¤ Check whether SDK supports specified Public Key algorithm
b4465d //
f2c802 //¤ Entry parameters :
5b2153 //¤ ¤   PGPPublicKeyAlgorithm¤  SDK public key algorithm constant
842593 //¤ ¤   mustEncrypt¤¤   ¤   ¤   TRUE=>SDK must support encryption with
c50a3b //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   this algorithm
6fc364 //¤ ¤   mustSign¤   ¤   ¤   ¤   TRUE=>SDK must support signing with
da0a3b //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   this algorithm
87465d //
f9c3b8 //¤ returns kPGPError_NoErr if SDK supports operations with
01f909 //¤ specified algorithm, kPGPError_FeatureNotAvailable otherwise.
b2af5a
639d43 PGPError PGPclExport·
02fa6d PGPclCheckSDKSupportForPKAlg (
594be8 ¤   ¤   PGPPublicKeyAlgorithm¤  alg,
c3dcd3 ¤   ¤   PGPBoolean¤ ¤   ¤   ¤   mustEncrypt,
383346 ¤   ¤   PGPBoolean¤ ¤   ¤   ¤   mustSign);
69af5a
5fe5dd //¤ Check whether SDK supports specified cipher algorithm
4b465d //
16c802 //¤ Entry parameters :
bbd846 //¤ ¤   PGPCipherAlgorithm¤ ¤   SDK cipher algorithm constant
--45fa 0000970d67740110202 Page 8 of PGPcl.h
c1465d //
9fc3b8 //¤ returns kPGPError_NoErr if SDK supports operations with
7df909 //¤ specified algorithm, kPGPError_FeatureNotAvailable otherwise.
39af5a
489d43 PGPError PGPclExport·
7de3d4 PGPclCheckSDKSupportForCipherAlg (PGPCipherAlgorithm alg);
49af5a
f0e7be //¤ Broadcast message that indicates that the keyring
caf3bb //¤ has been changed and that others should reload from
af4ae7 //¤ disk.
50465d //
3ec802 //¤ Entry parameters :
7e131f //¤ ¤   lParam¤ ¤   - 32 value which is passed along as the LPARAM
65b80b //¤ ¤   ¤   ¤   ¤   ··of the broadcast message. ·Current usage
8cf34c //¤ ¤   ¤   ¤   ¤   ··is to set this to your process ID or your
9a431b //¤ ¤   ¤   ¤   ¤   ··window handle so that you can ignore·
232935 //¤ ¤   ¤   ¤   ¤   ··your own messages, if you want. ·Set to
b84046 //¤ ¤   ¤   ¤   ¤   ··zero to ensure all recipients process message.
23af5a
b7bed8 //¤ broadcast message used to inform others of keyring changes
c4592f #define RELOADKEYRINGMSG¤   ("PGPM_RELOADKEYRING")
4baf5a
025860 VOID PGPclExport·
1e472f PGPclNotifyKeyringChanges (LPARAM lParam);
e5af5a
276453 //¤ Broadcast message that indicates that the keyserver prefs
e8161c //¤ have been changed and that others should reload from
cc4ae7 //¤ disk.
2a465d //
67c802 //¤ Entry parameters :
53131f //¤ ¤   lParam¤ ¤   - 32 value which is passed along as the LPARAM
2eb80b //¤ ¤   ¤   ¤   ¤   ··of the broadcast message. ·Current usage
8bf34c //¤ ¤   ¤   ¤   ¤   ··is to set this to your process ID or your
77431b //¤ ¤   ¤   ¤   ¤   ··window handle so that you can ignore·
bb2935 //¤ ¤   ¤   ¤   ¤   ··your own messages, if you want. ·Set to
5a4046 //¤ ¤   ¤   ¤   ¤   ··zero to ensure all recipients process message.
83af5a
3cbed8 //¤ broadcast message used to inform others of keyring changes
e36b7e #define RELOADPREFSMSG¤ ("PGPM_RELOADPREFS")
f0af5a
6d5860 VOID PGPclExport·
1e86b8 PGPclNotifyPrefsChanges (LPARAM lParam);
d1af5a
8e5d29 //¤ Broadcast message that indicates that the prefs
da161c //¤ have been changed and that others should reload from
7c4ae7 //¤ disk.
e1465d //
3bc802 //¤ Entry parameters :
a2131f //¤ ¤   lParam¤ ¤   - 32 value which is passed along as the LPARAM
bcb80b //¤ ¤   ¤   ¤   ¤   ··of the broadcast message. ·Current usage
e3f34c //¤ ¤   ¤   ¤   ¤   ··is to set this to your process ID or your
ab431b //¤ ¤   ¤   ¤   ¤   ··window handle so that you can ignore·
6c2935 //¤ ¤   ¤   ¤   ¤   ··your own messages, if you want. ·Set to
b64046 //¤ ¤   ¤   ¤   ¤   ··zero to ensure all recipients process message.
a1af5a
cdbed8 //¤ broadcast message used to inform others of keyring changes
f6273a #define RELOADKEYSERVERPREFSMSG¤("PGPM_RELOADKEYSERVERPREFS")
f2af5a
5c5860 VOID PGPclExport·
04ecfd PGPclNotifyKeyserverPrefsChanges (LPARAM lParam);
52af5a
571b73 //¤ Copy user info strings to preferences file
a7465d //
02c802 //¤ Entry parameters :
3ceff8 //¤ ¤   szOwnerName¤¤   ¤   owner name
b483d0 //¤ ¤   szCompanyName¤  ¤   company name
4232bf //¤ ¤   szLicenseNumber¤¤   license number
6667c5 ¤
7b9d43 PGPError PGPclExport·
1904fe PGPclSetUserInfo (
fe11f1 ¤   ¤   LPSTR szOwnerName,
09c06e ¤   ¤   LPSTR szCompanyName,
--2220 000c7b83d9140110202 Page 9 of PGPcl.h
337430 ¤   ¤   LPSTR szLicenseNumber);
efaf5a
d4d444 //¤ Query SDK for keyring and randseed file paths
63465d //
cfc802 //¤ Entry parameters :
91c83c //¤ ¤   pszPubRingPath¤ ¤   buffer to receive public keyring file name
b5f3ae //¤ ¤   iPubRingLen¤¤   ¤   length of buffer in bytes
1551a3 //¤ ¤   pszPrivRingPath¤¤   buffer to receive private keyring file name
ba9a5b //¤ ¤   iPrivRingLen¤   ¤   length of buffer in bytes
d1d656 //¤ ¤   pszRandSeedPath¤¤   buffer to receive random seed file name
92b2a5 //¤ ¤   iRandSeedLen¤   ¤   length of buffer in bytes
3e465d //
ad93e0 //¤ Note: any or all buffer pointers can be NULL -- they will be ignored.
78af5a
4e9d43 PGPError PGPclExport·
e3228c PGPclGetSDKFilePaths (
110597 ¤   ¤   LPSTR¤  pszPubRingPath,
744a69 ¤   ¤   INT¤¤   iPubRingLen,
23466d ¤   ¤   LPSTR¤  pszPrivRingPath,
f36ca0 ¤   ¤   INT¤¤   iPrivRingLen,
c4d46b ¤   ¤   LPSTR¤  pszRandSeedPath,
a40efd ¤   ¤   INT¤¤   iRandSeedLen);
6baf5a
c145f4 //¤ Use SDK to set keyring and randseed file paths
5f465d //
5bc802 //¤ Entry parameters :
166972 //¤ ¤   pszPubRingPath¤ ¤   buffer containing public keyring file name
8ffa78 //¤ ¤   pszPrivRingPath¤¤   buffer containing private keyring file name
cf2c4a //¤ ¤   pszRandSeedPath¤¤   buffer containing random seed file name
994a9d //¤ ¤   bForceCreate¤   ¤   TRUE => call PGPOpenDefaultKeyRings with "Create"
5b1386 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   flag to force creation of files
efb449 //¤ ¤   ¤   ¤   ¤   ¤   ¤   FALSE => do not call PGPOpenDefaultKeyRings
ef465d //
9e93e0 //¤ Note: any or all buffer pointers can be NULL -- they will be ignored.
29af5a
1e9d43 PGPError PGPclExport·
e62fac PGPclSetSDKFilePaths (
3e0597 ¤   ¤   LPSTR¤  pszPubRingPath,
26466d ¤   ¤   LPSTR¤  pszPrivRingPath,
04d46b ¤   ¤   LPSTR¤  pszRandSeedPath,
13f949 ¤   ¤   BOOL¤   bForceCreate);
b0af5a
258ca2 //¤ Startup the WinNT memlocking driver. ·If called under Win95, just
172f63 //¤ returns kPGPError_NoErr. ·If called under WinNT, returns·
b56f89 // ·kPGPError_NoErr if driver already started, or driver is successfully
00f16a // ·started. ·Returns kPGPError_UnknownError if driver cannot be started.
02af5a
3cec6d PGPError PGPclExport
d005ac PGPclStartMemLockDriver (VOID);
48af5a
60605b //¤ Get key from Key ID string
85465d //
6ac802 //¤ Entry parameters :
b78000 //¤ ¤   context¤¤   - context ref
7a1b1e //¤ ¤   keyset¤ ¤   - keyset to find key in
690f98 //¤ ¤   szID¤   ¤   - string representation of key ID
93ac8e //¤ ¤   alg¤¤   ¤   - algorithm of key·
5d9100 //¤ ¤   Key¤¤   ¤   - buffer to receive keyref
e7af5a
fa9d43 PGPError PGPclExport·
d90021 PGPclGetKeyFromKeyID (
ece958 ¤   ¤   PGPContextRef¤  context,
088b6a ¤   ¤   PGPKeySetRef¤   keyset,
3cd0ce ¤   ¤   LPSTR¤  ¤   ¤   szID,
6107b4 ¤   ¤   UINT¤   ¤   ¤   uAlg,
bfd025 ¤   ¤   PGPKeyRef*¤ ¤   pkey);
5baf5a
5d46e5 //¤ _______________________________________________________
cc465d //
25e489 //¤ Keyserver convenience functions·
6faf5a
c7af5a
--e671 0007bed8c9e40110202 Page 10 of PGPcl.h
667e4c #define PGPCL_SPECIFIEDSERVER ··0
ea47d5 #define PGPCL_USERIDBASEDSERVER¤1¤  // determine server based on userid
c3958c #define¤PGPCL_DEFAULTSERVER¤¤   2¤  // use default keyserver
17a8a1 #define PGPCL_ROOTSERVER¤   ¤   3¤  // use root keyserver
a8af5a
c9a7bd //¤ Searches keyserver prefs for specifed keyserver and replaces
90a6cf //¤ authentication key. ·
db465d //
74c802 //¤ Entry parameters :
9ee29d //¤ ¤   keyserver¤  ¤   ¤   ¤   ¤   keyserver data to put in prefs file
9067c5 ¤
ac9d43 PGPError PGPclExport·
2929c0 PGPclSyncKeyserverPrefs (
d99cd4 ¤   ¤   PGPContextRef¤  ¤   context,
e74ac2 ¤   ¤   PGPKeyServerEntry*¤ keyserver);
4eaf5a
041a37 //¤ Searches keyservers (as defined in prefs file) for all
358439 //¤ keys in the specified keyset. ·
40465d //
fdc802 //¤ Entry parameters :
732995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
e9f889 //¤ ¤   keysetToUpdate¤ ¤   keyset with keys to update
78affd //¤ ¤   uServer¤¤   ¤   ¤   one of above-defined server constants
740804 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added
1aef4a //¤ ¤   pkeysetUpdated¤ ¤   buffer to receive PGPKeySetRef
8767c5 ¤
259d43 PGPError PGPclExport·
889078 PGPclUpdateKeySetFromServer (
539cd4 ¤   ¤   PGPContextRef¤  ¤   context,
b9a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
9a05b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
5711ac ¤   ¤   PGPKeySetRef¤   ¤   keysetToUpdate,
fc73c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
71809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
b04ef5 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetUpdated);
29af5a
b903b8 //¤ Searches keyservers (as defined in prefs file) for the
3a7c00 //¤ specified userid string.
f5465d //
22c802 //¤ Entry parameters :
ad2995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
202e31 //¤ ¤   szUserID¤   ¤   ¤   string containing userid info
0baffd //¤ ¤   uServer¤¤   ¤   ¤   one of above-defined server constants
7e0804 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added
8cee4e //¤ ¤   pkeysetFound¤   ¤   buffer to receive PGPKeySetRef
bb67c5 ¤
f89d43 PGPError PGPclExport·
a2aa01 PGPclSearchServerForUserID (
bc9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
02a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
7905b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
be7b9b ¤   ¤   LPSTR¤  ¤   ¤   ¤   szUserID,
e173c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
bd809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
1e55de ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetFound);
43af5a
f025a8 //¤ Searches default keyserver for the keyids in the list.
90465d //
73c802 //¤ Entry parameters :
6f2995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
a3b05c //¤ ¤   pkeyidList¤ ¤   ¤   array of PGPKeyID
f3894a //¤ ¤   iNumKeyIDs¤ ¤   ¤   number of PGPKeyIDs in list
e9affd //¤ ¤   uServer¤¤   ¤   ¤   one of above-defined server constants
5e0804 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added
ecee4e //¤ ¤   pkeysetFound¤   ¤   buffer to receive PGPKeySetRef
1067c5 ¤
2a9d43 PGPError PGPclExport·
5f4188 PGPclSearchServerForKeyIDs (
9f9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
53a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
1005b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
7b7d4a ¤   ¤   PGPKeyID*¤  ¤   ¤   pkeyidList,
--cce5 0000a1a287240110202 Page 11 of PGPcl.h
634785 ¤   ¤   INT¤¤   ¤   ¤   ¤   iNumKeyIDs,
6573c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
6d809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
b555de ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetFound);
bfaf5a
4d593a //¤ Searches default keyserver using the specified filter.
04465d //
adc802 //¤ Entry parameters :
ad2995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
7a0d84 //¤ ¤   filter¤ ¤   ¤   ¤   filter to use for search
29affd //¤ ¤   uServer¤¤   ¤   ¤   one of above-defined server constants
400804 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added
57ee4e //¤ ¤   pkeysetFound¤   ¤   buffer to receive PGPKeySetRef
b267c5 ¤
579d43 PGPError PGPclExport·
ea490f PGPclSearchServerWithFilter (
399cd4 ¤   ¤   PGPContextRef¤  ¤   context,
3aa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
ff05b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
b4b21c ¤   ¤   PGPFilterRef¤   ¤   filter,
b973c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
7d809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
ec55de ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetFound);
25af5a
e45a5d //¤ Sends keys in keyset to the specified keyserver
0f465d //
3ac802 //¤ Entry parameters :
f12995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
6d7b44 //¤ ¤   szServerURL¤¤   ¤   server to send to
e2affd //¤ ¤   uServer¤¤   ¤   ¤   one of above-defined server constants
a66776 //¤ ¤   ¤   ¤   ¤   ¤   ¤   or zero to use pkeyserver
0b0e68 //¤ ¤   pkeyserver¤ ¤   ¤   server to send to (if uServer == 0)
8e47e7 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added and·
6bcb24 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   which contains signing keys
531554 //¤ ¤   keysetToSend¤   ¤   keyset with keys to send
5b67c5 ¤
e99d43 PGPError PGPclExport·
355a73 PGPclSendKeysToServer (
5c9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
e8a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
4205b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
dd73c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
d61f76 ¤   ¤   PGPKeyServerEntry*¤ pkeyserver,
07809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
167841 ¤   ¤   PGPKeySetRef¤   ¤   keysetToSend);
3aaf5a
193e87 //¤ Sends keys in keyset to the root keyserver with notifications
46465d //
8bc802 //¤ Entry parameters :
7a3522 //¤ ¤   hWndToReceiveNotifications¤ window to get WM_NOTIFYs
f09a2d //¤ ¤   szServerURL¤¤   ¤   ¤   ¤   server to send to
d49039 //¤ ¤   keysetMain¤ ¤   ¤   ¤   ¤   keyset to which tls key is added and·
f8e77a //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   which contains signing keys
1c8d66 //¤ ¤   keysetToSend¤   ¤   ¤   ¤   keyset with keys to send
af465d //
4a6a13 //¤ returns kPGPError_NoErr. ·Progress notifications and final
1fbfbc //¤ results are sent to window in form of WM_NOTIFY messages
db67c5 ¤
9713c7 // ·keyserver notifications
304e1c #define PGPCL_SERVERDONE¤   ¤   ¤   0x0001
c98af3 #define PGPCL_SERVERPROGRESS¤   ¤   0x0002
64e871 #define PGPCL_SERVERABORT¤  ¤   ¤   0x0003
fdfe88 #define PGPCL_SERVERERROR¤  ¤   ¤   0x0004
86af5a
755e40 typedef struct _PGPclSERVEREVENT
26bb36 {
e545d2 ¤   NMHDR¤  ¤   nmhdr;
f02435 ¤   VOID*¤  ¤   pData;
53c52d ¤   BOOL¤   ¤   cancel;
24f537 ¤   LONG¤   ¤   step;
b2829c ¤   LONG¤   ¤   total;
0a62d4 ¤   CHAR¤   ¤   szmessage[256];
--e175 000e699311440110202 Page 12 of PGPcl.h
491b98 } PGPclSERVEREVENT, *PPGPclSERVEREVENT;
f0af5a
099a0f #define PGPCL_SERVERINFINITE¤   ¤   -1L
88af5a
d69d43 PGPError PGPclExport·
06ccc1 PGPclSendKeysToRootServerNotify (
689cd4 ¤   ¤   PGPContextRef¤  ¤   context,
e2a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
2a0785 ¤   ¤   HWND¤   ¤   ¤   ¤   hWndToReceiveNotifications,·
9b809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
4e7841 ¤   ¤   PGPKeySetRef¤   ¤   keysetToSend);
b9af5a
ad6c09 //¤ Deletes keys in keyset from the specified keyserver
87465d //
e3c802 //¤ Entry parameters :
662995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
447b44 //¤ ¤   szServerURL¤¤   ¤   server to send to
2f519f //¤ ¤   space¤  ¤   ¤   ¤   pending or active bucket
2447e7 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added and·
20cb24 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   which contains signing keys
bdde77 //¤ ¤   keysetToDelete¤ ¤   keyset with keys to delete
e467c5 ¤
7d9d43 PGPError PGPclExport·
38e2ee PGPclDeleteKeysFromServer (
209cd4 ¤   ¤   PGPContextRef¤  ¤   context,
5aa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
7805b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
0f1f76 ¤   ¤   PGPKeyServerEntry*¤ pkeyserver,
d484c8 ¤   ¤   INT¤¤   ¤   ¤   ¤   space,
9c809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
a0e6da ¤   ¤   PGPKeySetRef¤   ¤   keysetToDelete);
44af5a
9c5836 //¤ Disables keys in keyset on the specified keyserver
06465d //
2bc802 //¤ Entry parameters :
e02995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
a67b44 //¤ ¤   szServerURL¤¤   ¤   server to send to
23519f //¤ ¤   space¤  ¤   ¤   ¤   pending or active bucket
c547e7 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added and·
88cb24 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   which contains signing keys
dbfa80 //¤ ¤   keysetToDisable¤¤   keyset with keys to disable
3e67c5 ¤
ce9d43 PGPError PGPclExport·
199b82 PGPclDisableKeysOnServer (
809cd4 ¤   ¤   PGPContextRef¤  ¤   context,
28a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
c305b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
931f76 ¤   ¤   PGPKeyServerEntry*¤ pkeyserver,
9484c8 ¤   ¤   INT¤¤   ¤   ¤   ¤   space,
fa809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
870602 ¤   ¤   PGPKeySetRef¤   ¤   keysetToDisable);
2daf5a
af9540 //¤ Downloads a new groupset from the root server
23465d //
72c802 //¤ Entry parameters :
f12995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
6447e7 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added and·
e1cb24 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   which contains signing keys
14fd69 //¤ ¤   groupsetDownloaded¤ newly downloaded groupset
1467c5 ¤
a19d43 PGPError PGPclExport·
4b3fa9 PGPclGetGroupsFromRootServer (
479feb ¤   ¤   PGPContextRef¤  ¤   ¤   context,
ddd913 ¤   ¤   PGPtlsContextRef¤   ¤   tlsContext,
cf8d32 ¤   ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,·
780556 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
30f1bb ¤   ¤   PGPGroupSetRef*¤¤   ¤   groupsetDownloaded);
c6af5a
db9540 //¤ Downloads a new groupset from the root server
50465d //
e7c802 //¤ Entry parameters :
e62995 //¤ ¤   hwndParent¤ ¤   ¤   parent window
--14ed 000550e7f2b40110202 Page 13 of PGPcl.h
8747e7 //¤ ¤   keysetMain¤ ¤   ¤   keyset to which tls key is added and·
40cb24 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   which contains signing keys
8f76d1 //¤ ¤   groupsetToSend¤ ¤   groupset to send to root server
6467c5 ¤
da9d43 PGPError PGPclExport·
8ee875 PGPclSendGroupsToRootServer (
1f9feb ¤   ¤   PGPContextRef¤  ¤   ¤   context,
77d913 ¤   ¤   PGPtlsContextRef¤   ¤   tlsContext,
ae8d32 ¤   ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,·
b30556 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
df6ac3 ¤   ¤   PGPGroupSetRef¤ ¤   ¤   groupsetToSend);
a0af5a
b246e5 //¤ _______________________________________________________
58465d //
77d26d //¤ Split key sharing functions·
2eaf5a
9c4caf //¤ Send key share file to remote computer
3a465d //
9dc802 //¤ Entry parameters :
a59cb6 //¤ ¤   context¤¤   - PGP library context
753e4c //¤ ¤   hwndParent¤ - handle of parent window
00a442 //¤ ¤   keysetMain¤ - main keyset (should contain decryption
fd073c //¤ ¤   ¤   ¤   ¤   ¤   and authentication keys)
c3af5a
ceec6d PGPError PGPclExport
6b3a8e PGPclSendShares (
44b579 ¤   ¤   PGPContextRef¤  ¤   context,·
d6a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
87f531 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,
2344ea ¤   ¤   PGPKeySetRef¤   ¤   keysetMain);
73af5a
d5af5a
363448 //¤ Reconstitute key by collecting key shares
d9465d //
68c802 //¤ Entry parameters :
5a9cb6 //¤ ¤   context¤¤   - PGP library context
273e4c //¤ ¤   hwndParent¤ - handle of parent window
cea442 //¤ ¤   keysetMain¤ - main keyset (should contain decryption
40073c //¤ ¤   ¤   ¤   ¤   ¤   and authentication keys)
7ee707 //¤ ¤   key¤¤   ¤   - key to reconstitute
9b0994 //¤ ¤   ppPasskeyBuffer¤¤   - pointer to buffer to receive address·
4c36a6 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ··of passkey buffer
b9da65 //¤ ¤   piPasskeyLength¤¤   - pointer to buffer to receive length
17af5a
dfec6d PGPError PGPclExport
d9ca81 PGPclReconstituteKey (
f59cd4 ¤   ¤   PGPContextRef¤  ¤   context,
ffa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
b3f531 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,
31809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
c3402c ¤   ¤   PGPKeyRef¤  ¤   ¤   key,
fb1229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
d3a348 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength);
27af5a
b0af5a
55a44e //¤ Allow user to confirm remote authentication key
94465d //
e9c802 //¤ Entry parameters :
50dcd9 //¤ ¤   hwndParent¤ ¤   - handle of parent window
496117 //¤ ¤   pszServer¤  ¤   - string with name of remote host
3af992 //¤ ¤   keyAuth¤¤   ¤   - authentication key to confirm
3106c8 //¤ ¤   keysetMain¤ ¤   - main keyset to which keyAuth may be added
ec0ece //¤ ¤   uFlags¤ ¤   ¤   - flags controlling text display
f9465d //
559a0d //¤ returns kPGPError_NoErr or kPGPError_UserAbort
31af5a
0eb8c9 #define PGPCL_SHOWAUTHENTICATION¤   0x0000
e8cd42 #define¤PGPCL_AUTHRECONSTITUTING¤   0x0001
0459c1 #define PGPCL_AUTHNEWKEY¤   ¤   ¤   0x0002
a0c1d4 #define PGPCL_AUTHUNEXPECTEDKEY¤¤   0x0003
0be001 #define PGPCL_AUTHEXPECTEDKEY¤  ¤   0x0004
55af5a
--7621 000fe9e6ca340110202 Page 14 of PGPcl.h
329d43 PGPError PGPclExport·
2f1fdb PGPclConfirmRemoteAuthentication (
a7e958 ¤   ¤   PGPContextRef¤  context,
ee8732 ¤   ¤   HWND¤   ¤   ¤   hwndParent,·
bfdbc1 ¤   ¤   LPSTR¤  ¤   ¤   pszServer,
0463e7 ¤   ¤   PGPKeyRef¤  ¤   keyAuth,
2655dd ¤   ¤   PGPKeySetRef¤   keysetMain,
bc6742 ¤   ¤   UINT¤   ¤   ¤   uFlags);
08af5a
b946e5 //¤ _______________________________________________________
e8465d //
828b11 //¤ Passphrase functions·
95af5a
c8ae80 //¤ Get passphrase from user.
c4465d //
11c802 //¤ Entry parameters :
569cb6 //¤ ¤   context¤¤   - PGP library context
39cccb //¤ ¤   hWndParent¤ - handle of parent window
7753b2 //¤ ¤   szPrompt¤   - message string to be displayed to user
eccc09 //¤ ¤   pszPhrase¤  - pointer to receive address of buffer which
87a83a //¤ ¤   ¤   ¤   ¤   ··will contain passphrase. ·The caller should
ca7dd0 //¤ ¤   ¤   ¤   ¤   ··deallocate this buffer by calling PGPclFreePhrase·
eefbe6 //¤ ¤   KeySet¤ ¤   - KeySet containing keys to display in combo or list box
31e90a //¤ ¤   ¤   ¤   ¤   ··NULL => hide key selection combo box
ba59f2 //¤ ¤   pKeyIDs¤¤   - additional keyids to tag onto end of listbox in·
f0b085 //¤ ¤   ¤   ¤   ¤   ··decryption dialog
1c7c5c //¤ ¤   uKeyCount¤  - total number of keys to display (only necessary when
a0036f //¤ ¤   ¤   ¤   ¤   ··keyids are to be displayed, otherwise can be zero)
c7324f //¤ ¤   pKey¤   ¤   - pointer to buffer to receive ref to selected key.·
dcb254 //¤ ¤   ¤   ¤   ¤   ··if buffer contains key on entry, this will be default.
01c2b1 //¤ ¤   ¤   ¤   ¤   ··buffer should be set to NULL to use keyring default key.
89e90a //¤ ¤   ¤   ¤   ¤   ··NULL => hide key selection combo box
fe3e4b //¤ ¤   uOptions¤   - pointer to buffer which contains and will receive·
bdee81 //¤ ¤   ¤   ¤   ¤   ··options bits
a7e5d6 //¤ ¤   ¤   ¤   ¤   ··NULL => hide option checkboxes
d66e71 //¤ ¤   uFlags¤ ¤   - flag bits
71e153 //¤ ¤   ¤   ¤   ¤   ··PGPcl_RSAENCRYPT => encrypting to RSA key
248f32 //¤ ¤   ¤   ¤   ¤   ··PGPcl_DECRYPTION => display decryption dialog
4de3c2 //¤ ¤   ¤   ¤   ¤   ··PGPcl_ENCRYPTION => display conventional encryption
874f50 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··dialog
fa465d //
155c11 //¤ This function returns kPGPError_UserAbort if the user
af81d6 // ·presses the cancel button. ·
acaf5a
8acb17 // options bits
5ce665 #define PGPCL_ASCIIARMOR¤   ¤   ¤   0x0001
3f1903 #define PGPCL_DETACHEDSIG¤  ¤   ¤   0x0002
97cecc #define PGPCL_PASSONLY¤ ¤   ¤   ¤   0x0004
dfe17a #define PGPCL_WIPEORIG¤ ¤   ¤   ¤   0x0008
05736b #define PGPCL_FYEO¤ ¤   ¤   ¤   ¤   0x0010
8baf5a
68509f // disable bits
809271 #define PGPCL_DISABLE_ASCIIARMOR ···0x0001
09d2ee #define PGPCL_DISABLE_AUTOMODE¤ ¤   0x0002
aa00a5 #define PGPCL_DISABLE_PASSONLY¤ ¤   0x0004
a62086 #define PGPCL_DISABLE_WIPEORIG¤ ¤   0x0008
21f74d #define PGPCL_DISABLE_FYEO¤ ¤   ¤   0x0010
99af5a
c8701c // flag bits
948c58 #define PGPCL_RSAENCRYPT¤   ¤   ¤   0x0001
0c6778 #define PGPCL_DECRYPTION¤   ¤   ¤   0x0002
86d03c #define PGPCL_ENCRYPTION¤   ¤   ¤   0x0004
b13e44 #define PGPCL_KEYPASSPHRASE ········0x0008
f65024 #define PGPCL_REJECTSPLITKEYS¤  ¤   0x0010
16af5a
159d43 PGPError PGPclExport·
e42c3b PGPclGetPhrase (
4fe958 ¤   ¤   PGPContextRef¤  context,
cbdffe ¤   ¤   PGPKeySetRef¤   MainKeySet,
2bac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
a5609e ¤   ¤   LPSTR¤  ¤   ¤   szPrompt,
fe930f ¤   ¤   LPSTR*¤ ¤   ¤   ppszPhrase,·
--8c04 000a682565e40110202 Page 15 of PGPcl.h
835d0b ¤   ¤   PGPKeySetRef¤   KeySet,
62975f ¤   ¤   PGPKeyID*¤  ¤   pKeyIDs,
c9a0a6 ¤   ¤   UINT¤   ¤   ¤   uKeyCount,
034994 ¤   ¤   PGPKeyRef*¤ ¤   pKey,·
f53b17 ¤   ¤   UINT*¤  ¤   ¤   puOptions,·
bf3a9c ¤   ¤   UINT¤   ¤   ¤   uFlags,
27e873 ¤   ¤   PGPByte**¤  ¤   ppPasskeyBuffer,
ebab36 ¤   ¤   PGPUInt32*¤ ¤   piPasskeyLength,
07f6f0 ¤   ¤   PGPUInt32¤  ¤   MinLength,
a794d0 ¤   ¤   PGPUInt32¤  ¤   MinQuality,
725c31 ¤   ¤   PGPtlsContextRef tlsContext,
5f3e2c ¤   ¤   PGPKeySetRef¤   *AddedKeys
c15ce5 ¤   ¤   ) ;
90af5a
63d9a2 //¤ Recipient dialog glue call
fa465d //
4026e3 // ·Interfaces to PGPsdkUI calls.
57af5a
369dda #define CurrentPGPrecipVersion 'DUKE'
c9af5a
490846 typedef struct _recipientdialogstruct
56bb36 {
0d0e6c ¤   DWORD¤  ¤   ¤   Version;
141fb2 ¤   HWND¤   ¤   ¤   hwndParent;
df3bdf ¤   char *¤ ¤   ¤   szTitle;
257dae ¤   PGPContextRef¤  Context;
f6cef3 ¤   PGPKeySetRef ¤  OriginalKeySetRef;
fc04f4 ¤   PGPKeySetRef ¤  SelectedKeySetRef;
6c7fe5 ¤   char **¤¤   ¤   szRecipientArray;
fd33b7 ¤   DWORD¤  ¤   ¤   dwNumRecipients;
50ca3a ¤   DWORD¤  ¤   ¤   dwOptions;
e5ce3b ¤   DWORD¤  ¤   ¤   dwFlags;
3a2143 ¤   DWORD¤  ¤   ¤   dwDisableFlags;
59b9c0 ¤   PGPtlsContextRef tlsContext;
19e728 ¤   PGPKeySetRef¤   AddedKeys;
ec50ec } RECIPIENTDIALOGSTRUCT, *PRECIPIENTDIALOGSTRUCT;
42af5a
7d721a UINT PGPclExport PGPclRecipientDialog(PRECIPIENTDIALOGSTRUCT prds);
acaf5a
aaffbb //¤ Wipe and deallocate phrase buffer.
6b465d //
cbc802 //¤ Entry parameters :
7c9365 //¤ ¤   szPhrase¤   - passphrase buffer to wipe and deallocate
82465d //
ceaf5a
615860 VOID PGPclExport·
c5a69f PGPclFreePhrase (LPSTR szPhrase);
faaf5a
fcb71e //___________________________________
83465d //
344955 //¤ passphrase caching routines
20af5a
6f465d //
18689b //¤ PGPclGetCachedDecryptionPhrase
525471 //¤ This routine is called to get either cached phrase·
edf11e //¤ (if available) or prompt user for phrase.
d7af5a
8bec6d PGPError PGPclExport
e47cb8 PGPclGetCachedDecryptionPhrase (
f6b579 ¤   ¤   PGPContextRef¤  ¤   context,·
fea960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
7f809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
ec8d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
42a3e3 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,·
ab55cb ¤   ¤   BOOL¤   ¤   ¤   ¤   bForceUserInput,
32f6f4 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   pszBuffer,
a16077 ¤   ¤   PGPKeySetRef¤   ¤   keysetEncryptedTo,
2a8416 ¤   ¤   PGPKeyID*¤  ¤   ¤   pkeyidEncryptedTo,
985866 ¤   ¤   UINT¤   ¤   ¤   ¤   uKeyIDCount,
a71229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
d82c7e ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength,
a6535d ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetAdded);·
--618a 0004e402de840110202 Page 16 of PGPcl.h
e0af5a
ae465d //
951f9f //¤ PGPclGetCachedSigningPhrase
63262b //¤ This routine is called to get either signing cached phrase·
9af11e //¤ (if available) or prompt user for phrase.
48af5a
3cec6d PGPError PGPclExport
b5d296 PGPclGetCachedSigningPhrase (
19b579 ¤   ¤   PGPContextRef¤  ¤   context,·
0aa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
aa317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
69b7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
a15dc6 ¤   ¤   BOOL¤   ¤   ¤   ¤   bForceUserInput,·
379411 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   pszBuffer,·
303a8d ¤   ¤   PGPKeySetRef¤   ¤   keysetSigning,
366ea9 ¤   ¤   PGPKeyRef*¤ ¤   ¤   pkeySigning,
fa809a ¤   ¤   PGPHashAlgorithm*¤  pulHashAlg,
a14582 ¤   ¤   UINT*¤  ¤   ¤   ¤   puOptions,·
1d0a6a ¤   ¤   UINT¤   ¤   ¤   ¤   uFlags,
931229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
962c7e ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength,
f3be25 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetAdded);
f6af5a
00d157 #define PGPCL_DECRYPTIONCACHE¤  0x0001
7aee7d #define PGPCL_SIGNINGCACHE¤ ¤   0x0002
57af5a
8f465d //
1d9165 //¤ PGPclPurgeCachedPassphrase
bf4266 //¤ Called to purge phrases from cache. ·
c7656a //¤ dwFlags is the logical OR of PGPCL_DECRYPTIONCACHE and
6ff919 //¤ PGPCL_SIGNINGCACHE.
6faf5a
44c4cd BOOL PGPclExport
c17f36 PGPclPurgeCachedPassphrase (DWORD dwFlags);·
09af5a
e8465d //
734dc6 //¤ PGPclFreeCachedPhrase
830e82 //¤ Called to wipe and free the phrase returned by
0e1917 //¤ PGPGetCachedPhrase.
c3af5a
10db9e VOID PGPclExport
b20dc1 PGPclFreeCachedPhrase (LPSTR szPhrase);·
baaf5a
7a465d //
a2389a //¤ PGPclQueryDecryptCacheSecsRemaining
1fa70d //¤ Returns number of seconds remaining until cache expires
18af5a
ed1e15 INT PGPclExport·
475dde PGPclQueryDecryptionCacheSecsRemaining (VOID);·
cbaf5a
53465d //
c611a1 //¤ PGPclQuerySignCacheSecsRemaining
1ea70d //¤ Returns number of seconds remaining until cache expires
f6af5a
e48a9a INT PGPclExport
d525e5 PGPclQuerySigningCacheSecsRemaining (VOID);·
79af5a
0daf5a
2907af //¤ Broadcast message that indicates that the receiving module
8f5cde //¤ should purge its passphrase cache(s)
3b465d //
39c802 //¤ Entry parameters :
f7bf32 //¤ ¤   wParam¤ ¤   - logical OR of PGPCL_DECRYPTIONCACHE and
32fbee //¤ ¤   ¤   ¤   ¤   ··PGPCL_SIGNINGCACHE.
0b131f //¤ ¤   lParam¤ ¤   - 32 value which is passed along as the LPARAM
b7b80b //¤ ¤   ¤   ¤   ¤   ··of the broadcast message. ·Current usage
daf34c //¤ ¤   ¤   ¤   ¤   ··is to set this to your process ID or your
09431b //¤ ¤   ¤   ¤   ¤   ··window handle so that you can ignore·
f52935 //¤ ¤   ¤   ¤   ¤   ··your own messages, if you want. ·Set to
a74046 //¤ ¤   ¤   ¤   ¤   ··zero to ensure all recipients process message.
0baf5a
4ebed8 //¤ broadcast message used to inform others of keyring changes
--b84a 0018a06b81140110202 Page 17 of PGPcl.h
1b0c00 #define PURGEPASSPHRASECACEHMSG¤("PGPM_PURGEPASSPHRASECACHE")
2eaf5a
765860 VOID PGPclExport·
beb634 PGPclNotifyPurgePassphraseCache (
50d425 ¤   ¤   WPARAM wParam,
9d72d2 ¤   ¤   LPARAM lParam);
fbaf5a
1cafaa //¤ __________________________________________________________
5f465d //
00a223 // ·Check to see if it's time to auto-update keys
ef465d //
51c802 //¤ Entry parameters :
91ab9d //¤ ¤   memoryMgr¤  ¤   ¤   ¤   ¤   Memory manager ref
94a6f4 //¤ ¤   bResetDates¤¤   ¤   ¤   ¤   TRUE=>set "last updated" date to today
e84ad6 //¤ ¤   pbUpdateAllKeys¤¤   ¤   ¤   Pointer to boolean, TRUE if it's
82bfed //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   time to update all keys
1f03f6 //¤ ¤   pbUpdateTrustedIntroducers¤ Pointer to boolean, TRUE if it's
a9c73e //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   time to update trusted introducers
8daf5a
5cec6d PGPError PGPclExport
aebd80 PGPclCheckAutoUpdate(PGPMemoryMgrRef memoryMgr,·
f79d00 ¤   ¤   ¤   ¤   ¤   ·PGPBoolean bResetDates,
a98dc6 ¤   ¤   ¤   ¤   ¤   ·PGPBoolean *pbUpdateAllKeys,
f02354 ¤   ¤   ¤   ¤   ¤   ·PGPBoolean *pbUpdateTrustedIntroducers);
6daf5a
26afaa //¤ __________________________________________________________
e7465d //
dba300 // ·Look up an unknown signer's key on the keyserver
83465d //
7ec802 //¤ Entry parameters :
3de56e //¤ ¤   context¤¤   ¤   context ref
9ce8bc //¤ ¤   hwnd¤   ¤   ¤   handle to parent window
803960 //¤ ¤   event¤  ¤   ¤   event data pointer
8520cf //¤ ¤   signingKeyID¤   Key ID of unknown signer
0ccd61 //¤ ¤   pbGotKeys¤  ¤   Pointer to boolean, TRUE if the key(s)
f06aea //¤ ¤   ¤   ¤   ¤   ¤   of the unknown signer were successfully fetched
fcaf5a
1bec6d PGPError PGPclExport
ce4397 PGPclLookupUnknownSigner(PGPContextRef context,
65f235 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPKeySetRef KeySetMain,
f4dd1f ¤   ¤   ¤   ¤   ¤   ¤   ·PGPtlsContextRef tlsContext,
51d92c ¤   ¤   ¤   ¤   ¤   ¤   ·HWND hwnd,
420120 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPEvent *event,
b2ff23 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPKeyID signingKeyID,
90f715 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPBoolean *pbGotKeys);
f646e5 //¤ _______________________________________________________
a1af5a
8e3379 #ifdef __cplusplus
2eefe6 }
687454 #endif
7daf5a
da456e #endif /* ] Included_PGPcl_h */
67af5a
c7af5a
507e4d /*__Editor_settings____
0faf5a
a24126 ¤   Local Variables:
d27b17 ¤   tab-width: 4
bb0e6c ¤   End:
545f8c ¤   vi: ts=4 sw=4
c39e9b ¤   vim: si
8ad062 _____________________*/
--dab8 000a75b5c0c40110203 Page 1 of PGPgm.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
1d5758 ¤   PGPgm.h - include file for PGP group manager DLL
0667c5 ¤
29af5a
5efcde ¤   $Id: PGPgm.h,v 1.12 1998/08/11 14:06:17 pbj Exp $
53f7f7 ____________________________________________________________________________*/
1e8275 #ifndef Included_PGPgm_h¤   /* [ */
88fb1a #define Included_PGPgm_h
fbaf5a
b4b177 #if 0
c29de2 #ifdef _PGPGMDLL
c1f542 # define PGPgmExport __declspec( dllexport )
4ddb21 #else
b37974 # define PGPgmExport __declspec( dllimport )
347454 #endif
3adb21 #else
53a3ae # define PGPgmExport
927454 #endif
7faf5a
9bcb17 // options bits
475467 #define GMF_NOVICEMODE¤ ¤   0x0001
a31140 #define GMF_MARGASINVALID¤  0x0002
6aaf5a
319518 // action codes
d9aee6 #define GM_COPY¤¤   ¤   ¤   0x00000001
589a19 #define GM_PASTE¤   ¤   ¤   0x00000002
f71840 #define GM_DELETE¤  ¤   ¤   0x00000004
c879c4 #define GM_SELECTALL¤   ¤   0x00000008
6ae188 #define GM_COLLAPSEALL¤ ¤   0x00000010
910ca9 #define GM_COLLAPSESEL¤ ¤   0x00000020
21870b #define GM_EXPANDALL¤   ¤   0x00000040
353964 #define GM_EXPANDSEL¤   ¤   0x00000080
608d6e #define GM_PROPERTIES¤  ¤   0x00000100
cedc76 #define GM_NEWGROUP¤¤   ¤   0x00000200
e8a8fb #define GM_LOCATEKEYS¤  ¤   0x00000400
d6421e #define GM_GETFROMSERVER¤   0x00000800
9a6d3d #define GM_IMPORTGROUPS¤¤   0x00001000
11c206 #define¤GM_UPDATEALLGROUPS¤ 0x00002000
6e5edf #define¤GM_SENDALLGROUPS¤   0x00004000
0d21c5 #define GM_UNSELECTALL¤ ¤   0x10000000
a3af5a
ffb143 #define GM_MAINACTIONS¤ ¤   0x00007FFF
ae63a5 #define GM_ALLACTIONS¤  ¤   0x10007FFF
85af5a
69cc2a // column codes
2fb803 #define GM_VALIDITY¤¤   ¤   0x00000001
6719c1 #define GM_DESCRIPTION¤ ¤   0x00000002
14af5a
4945e6 // selection bits set in TLN_CONTEXTMENU notification
445e07 #define PGPGM_GROUPFLAG¤¤   0x01
858b10 #define PGPGM_KEYFLAG¤  ¤   0x02
2baf5a
775bee // typedefs
73aa86 typedef struct _GM FAR* HGROUPMAN;
a233fc typedef struct {¤   ¤   ¤   ¤   // configuration information
d942b6 ¤   HKEYMAN¤¤   ¤   hKM;¤   ¤   ¤   //handle of associated keymanager
b0c0f9 ¤   PGPKeySetRef¤   keysetMain;¤¤   //main keyset
e7646d ¤   LPSTR¤  ¤   ¤   lpszHelpFile;¤  // ·name of help file
fc0686 ¤   ULONG¤  ¤   ¤   ulOptionFlags;¤ //¤ logical OR of option bits (above)
0074ea ¤   ULONG¤  ¤   ¤   ulDisableActions;¤  // ·logical OR of actions (above)
9b3ce0 ¤   HWND¤   ¤   ¤   hWndStatusBar;¤ // ·handle of status bar window
ffbac8 } GMCONFIG, *LPGMCONFIG;
35af5a
cb95f6 #include "..\include\pgpWErr.h"
7eaf5a
8b3379 #ifdef __cplusplus
ed6dad extern "C" {
3c7454 #endif
a7af5a
--4354 00091cfe2c340110203 Page 2 of PGPgm.h
e0af5a
307015 //________________________________________________
08465d //
520766 //¤ PGPgmCreateGroupManager -
3b57ea //¤ Creates empty group manager window
3a465d //
a0c802 //¤ Entry parameters :
b6f7bc //¤ ¤   Context¤¤   - PGP library context
edcccb //¤ ¤   hWndParent¤ - handle of parent window
723a0f //¤ ¤   id¤ ¤   ¤   - window ID to assign to manager (used in notifications)
8af70d //¤ ¤   x¤  ¤   ¤   - x coordinate of manager window relative to parent
1ff175 //¤ ¤   y¤  ¤   ¤   - y coordinate of manager window relative to parent
60bd08 //¤ ¤   nWidth¤ ¤   - width of manager window
f99f3a //¤ ¤   nHeight¤¤   - height of manager window
27465d //
d1ea46 //¤ Returns handle to keymanager
ea465d //
60af5a
d202ac HGROUPMAN PGPgmExport·
4961a3 PGPgmCreateGroupManager (
906bed ¤   ¤   PGPContextRef¤  ¤   Context,
bca960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
1f2e03 ¤   ¤   HWND¤   ¤   ¤   ¤   hWndParent,·
0ac51d ¤   ¤   INT¤¤   ¤   ¤   ¤   Id,·
540a9f ¤   ¤   INT¤¤   ¤   ¤   ¤   x,·
62fb12 ¤   ¤   INT¤¤   ¤   ¤   ¤   y,
ac0a42 ¤   ¤   INT¤¤   ¤   ¤   ¤   nWidth,·
7ffacc ¤   ¤   INT¤¤   ¤   ¤   ¤   nHeight);
ccaf5a
e67015 //________________________________________________
d1465d //
ccc3ad //¤ PGPgmConfigure -
4dde03 //¤ Configures group manager window
56465d //
a4c802 //¤ Entry parameters :
3d0029 //¤ ¤   hGroupMan¤  - handle of group manager to configure
b0c7dd //¤ ¤   pGMConfig¤  - pointer to GMCONFIG struct
e0465d //
d40a22 //¤ Returns kPGPError_NoErr if no error
85465d //
4baf5a
6e6022 PGPError PGPgmExport·
b92122 PGPgmConfigure (HGROUPMAN¤  hGroupMan,·
a94b7f ¤   ¤   ¤   ¤   LPGMCONFIG¤ pGMConfig);
78af5a
ee7015 //________________________________________________
3a465d //
d5c58f //¤ PGPgmDestroyGroupManager -
5ded63 //¤ Destroys group manager window
f8465d //
26c802 //¤ Entry parameters :
857789 //¤ ¤   hGroupMan - handle of group manager to destroy
5e465d //
641a65 //¤ Returns kPGPError_NoErr if successful
f9465d //
e9af5a
656022 PGPError PGPgmExport·
6304ed PGPgmDestroyGroupManager (HGROUPMAN hGroupMan);
f8af5a
ab7015 //________________________________________________
34465d //
059992 //¤ PGPgmDefaultNotificationProc -
cacbf5 //¤ Handles default behavior for TreeList notifications
01465d //
f2c802 //¤ Entry parameters :
a3255d //¤ ¤   hGroupMan¤  - handle of group manager
b56b80 //¤ ¤   lParam¤ ¤   - LPARAM from WM_NOTIFY message
50465d //
15db72 //¤ Returns kPGPError_NoErr
c1465d //
b9af5a
916022 PGPError PGPgmExport·
--c535 0005b7066fa40110203 Page 3 of PGPgm.h
ad2e1d PGPgmDefaultNotificationProc (HGROUPMAN¤hGroupMan, ¤¤   ¤   ¤   ¤   ··
e6ef59 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM¤   lParam);
65af5a
007015 //________________________________________________
20465d //
87beab //¤ PGPgmIsActionEnabled -
2ab061 //¤ reports if specified action is enabled or not
6a465d //
bac802 //¤ Entry parameters :
f1255d //¤ ¤   hGroupMan¤  - handle of group manager
b0ca34 //¤ ¤   uAction¤¤   - action constant from above list
04465d //
388664 //¤ Returns TRUE if enabled, FALSE if not
7c465d //
99af5a
5fc500 BOOL PGPgmExport·
f8ef20 PGPgmIsActionEnabled (HGROUPMAN¤hGroupMan,·
89633d ¤   ¤   ¤   ¤   ¤   ··ULONG¤¤   uAction);
b2af5a
a57015 //________________________________________________
f6465d //
a5794d //¤ PGPgmPerformAction -
4e6f64 //¤ requests that specified action be performed on
f5b7df //¤ currently selected objects
36465d //
96c802 //¤ Entry parameters :
8f255d //¤ ¤   hGroupMan¤  - handle of group manager
f0ca34 //¤ ¤   uAction¤¤   - action constant from above list
5b465d //
871a65 //¤ Returns kPGPError_NoErr if successful
a8465d //
1baf5a
226022 PGPError PGPgmExport·
1fcd57 PGPgmPerformAction (HGROUPMAN¤  hGroupMan,·
4ab506 ¤   ¤   ¤   ¤   ¤   ULONG¤  ¤   uAction);
daaf5a
9e7015 //________________________________________________
9d465d //
ba6fbe //¤ PGPgmGetManagerWindow -
545375 //¤ returns HWND of group manager window
2a465d //
88c802 //¤ Entry parameters :
0b255d //¤ ¤   hGroupMan¤  - handle of group manager
71465d //
646043 //¤ Returns HWND if successful, NULL if error.
a9465d //
8aaf5a
05946b HWND PGPgmExport·
d4eae5 PGPgmGetManagerWindow (HGROUPMAN hGroupMan);
39af5a
bd7015 //________________________________________________
0f465d //
08f36e //¤ PGPgmLoadGroups -
5e75b1 //¤ load groups into manager
35465d //
cac802 //¤ Entry parameters :
d70ffa //¤ ¤   hGroupMan¤  ¤   - handle of group manager
3a465d //
c60a22 //¤ Returns kPGPError_NoErr if no error
e0465d //
11af5a
db8de9 PGPError·
ba72ea PGPgmLoadGroups (HGROUPMAN hGroupMan);·
fdaf5a
2c7015 //________________________________________________
8a465d //
7eaa6f //¤ PGPgmReLoadGroups -
b3a750 //¤ reload groups into manager
c7465d //
34c802 //¤ Entry parameters :
e10ffa //¤ ¤   hGroupMan¤  ¤   - handle of group manager
5b465d //
--3513 001de9066cd40110203 Page 4 of PGPgm.h
cc0a22 //¤ Returns kPGPError_NoErr if no error
4f465d //
5faf5a
806022 PGPError PGPgmExport·
e2033c PGPgmReLoadGroups (HGROUPMAN hGroupMan);
2faf5a
a77015 //________________________________________________
0f465d //
02f411 //¤ PGPgmNewGroup -
585c22 //¤ create new recipient group
ff465d //
9dc802 //¤ Entry parameters :
0f0ffa //¤ ¤   hGroupMan¤  ¤   - handle of group manager
86465d //
9d0a22 //¤ Returns kPGPError_NoErr if no error
22465d //
aeaf5a
815237 PGPError PGPgmExport
0fcf83 PGPgmNewGroup (HGROUPMAN hGroupMan);
63af5a
0a3379 #ifdef __cplusplus
04efe6 }
2e7454 #endif
23af5a
69cc65 #endif /* ] Included_PGPgm_h */
51af5a
e5af5a
027e4d /*__Editor_settings____
45af5a
904126 ¤   Local Variables:
b97b17 ¤   tab-width: 4
8d0e6c ¤   End:
975f8c ¤   vi: ts=4 sw=4
399e9b ¤   vim: si
ded062 _____________________*/
--c731 001a27a7e2540110204 Page 1 of PGPhk.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
a0dce0 ¤   PGPsc.h - include file for PGPsc DLL
4867c5 ¤
cfaf5a
773f36 ¤   $Id: PGPhk.h,v 1.1.2.1 1998/10/06 18:17:11 wjb Exp $
9ff7f7 ____________________________________________________________________________*/
27c2c4 #ifndef _PGPHKH
f5e1cc #define _PGPHKH
a6af5a
fd3379 #ifdef __cplusplus
b26dad extern "C" {
a97454 #endif
f1af5a
09c696 // Use Current Window routines for PGPtray's CBThook
7ce886 HWND ReadCurrentFocus(void);
53df49 void SetHook(void);
857865 void DeleteHook(void);
58af5a
0d3379 #ifdef __cplusplus
ccefe6 }
ba7454 #endif
b0af5a
a223fa #endif // PGPHKH
--4866 0009b43b0d640110205 Page 1 of PGPkm.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
1534d1 ¤   PGPkm.h - include file for PGP key manager DLL
be67c5 ¤
17af5a
bc1ff4 ¤   $Id: PGPkm.h,v 1.35 1998/08/11 14:06:18 pbj Exp $
07f7f7 ____________________________________________________________________________*/
69fad3 #ifndef Included_PGPkm_h¤   /* [ */
6f8c2a #define Included_PGPkm_h
f4af5a
dbac16 #ifdef _PGPKMDLL
62efe5 # define PGPkmExport __declspec( dllexport )
9fdb21 #else
6d63d3 # define PGPkmExport __declspec( dllimport )
ff7454 #endif
b3af5a
aeed82 #include "pgpKeyServerPrefs.h"
a495f6 #include "..\include\pgpWErr.h"
72af5a
0f991a // synchronization message
6bffa2 #define KM_M_REQUESTSDKACCESS¤  ¤   WM_APP+222
338735 #define KM_M_KEYPROPACTION¤ ¤   ¤   WM_APP+223
63af5a
7e5f46 // reason codes
e98f54 #define KMR_EXISTINGSPLITKEYDLGS¤   0x0001
28af5a
c9cb17 // options bits
4c7e03 #define KMF_READONLY¤   ¤   ¤   0x0001
7f715a #define KMF_ENABLECOMMITS¤  ¤   0x0002
d1c39a #define KMF_NOVICEMODE¤ ¤   ¤   0x0004
819b4c #define KMF_ONLYSELECTKEYS¤ ¤   0x0008
4c7e48 #define KMF_ENABLEDROPIN¤   ¤   0x0010
db616f #define KMF_ENABLEDRAGOUT¤  ¤   0x0020
df0dc7 #define KMF_MODALPROPERTIES¤¤   0x0040
9aeaba #define KMF_ENABLERELOADS¤  ¤   0x0080
36ef6e #define KMF_PENDINGBUCKET¤  ¤   0x0100
740260 #define KMF_DISABLEKEYPROPS¤¤   0x0200
46aae6 #define KMF_MARGASINVALID¤  ¤   0x0800
331265 #define KMF_DISABLESTATUSBAR¤   0x1000
25af5a
089518 // action codes
fcbbc3 #define KM_COPY¤¤   ¤   ¤   0x00000001
9c8f3c #define KM_PASTE¤   ¤   ¤   0x00000002
650d65 #define KM_DELETE¤  ¤   ¤   0x00000004
ff6ce1 #define KM_SELECTALL¤   ¤   0x00000008
04f4ad #define KM_COLLAPSEALL¤ ¤   0x00000010
62198c #define KM_COLLAPSESEL¤ ¤   0x00000020
0b922e #define KM_EXPANDALL¤   ¤   0x00000040
282c41 #define KM_EXPANDSEL¤   ¤   0x00000080
8078a2 #define KM_CERTIFY¤ ¤   ¤   0x00000100
f31864 #define KM_ENABLE¤  ¤   ¤   0x00000200
eb7079 #define KM_DISABLE¤ ¤   ¤   0x00000400
89c2a4 #define KM_ADDUSERID¤   ¤   0x00000800
1bdc64 #define KM_REVOKE¤  ¤   ¤   0x00001000
b75066 #define KM_SETASDEFAULT¤¤   0x00002000
336106 #define KM_SETASPRIMARY¤¤   0x00004000
5473ab #define KM_IMPORT¤  ¤   ¤   0x00008000
8152d1 #define KM_EXPORT¤  ¤   ¤   0x00010000
a88ca6 #define KM_PROPERTIES¤  ¤   0x00020000
ad17e0 #define KM_SENDTOSERVER¤¤   0x00040000
f393bb #define KM_GETFROMSERVER¤   0x00080000
915189 #define KM_DELETEFROMSERVER¤0x00100000
ad3487 #define KM_DISABLEONSERVER¤ 0x00200000
e795bc #define KM_REVERIFYSIGS¤¤   0x01000000
dbe4e8 #define KM_SPLITKEY¤¤   ¤   0x02000000
a049e3 #define KM_ADDPHOTOID¤  ¤   0x04000000
2f9c5d #define KM_ADDREVOKER¤  ¤   0x08000000
797907 #define KM_ADDTOMAIN¤   ¤   0x10000000
27e2e7 #define KM_UNSELECTALL¤ ¤   0x20000000
9baf5a
--2e5c 000d0f0bf0540110205 Page 2 of PGPkm.h
2bf2e2 #define KM_MAINACTIONS¤ ¤   0x0F0FFFFF
d41390 #define KM_ALLACTIONS¤  ¤   0x3F3FFFFF
d0af5a
13cc2a // column codes
e1ad26 #define KM_VALIDITY¤¤   ¤   0x00000001
9a48f5 #define KM_SIZE¤¤   ¤   ¤   0x00000002
d95834 #define KM_DESCRIPTION¤ ¤   0x00000004
2e4a18 #define KM_KEYID¤   ¤   ¤   0x00000008
1659e4 #define KM_TRUST¤   ¤   ¤   0x00000010
03028f #define KM_CREATION¤¤   ¤   0x00000020
697d1a #define KM_EXPIRATION¤  ¤   0x00000040
815484 #define KM_ADK¤ ¤   ¤   ¤   0x00000080
28af5a
be45e6 // selection bits set in TLN_CONTEXTMENU notification
1b7693 #define PGPKM_KEYFLAG¤  ¤   0x01
8c3531 #define PGPKM_UIDFLAG¤  ¤   0x02
a590bf #define PGPKM_CERTFLAG¤ ¤   0x04
22af5a
80ae4e // mask bits for KMCONFIGURE struct
16649a #define PGPKM_HELPFILE¤ ¤   0x0001
43605d #define PGPKM_KEYSERVER¤¤   0x0002
886113 #define PGPKM_OPTIONS¤  ¤   0x0004
490129 #define PGPKM_DISABLEFLAGS¤ 0x0008
ae63a2 #define PGPKM_COLUMNFLAGS¤  0x0010
46babb #define PGPKM_STATUSBAR¤¤   0x0020
e1595a #define PGPKM_SETHWNDPROC¤  0x0040
f7f520 #define PGPKM_ALLITEMS¤ ¤   0x007F
feaf5a
6d5bee // typedefs
9b4d16 typedef VOID (*HWNDLISTPROC) (HWND, BOOL, POINT*, HWND*);
29c6cf typedef struct _KM FAR* HKEYMAN;
1d33fc typedef struct {¤   ¤   ¤   ¤   // configuration information
4f6c1a ¤   ULONG¤  ulMask;¤¤   ¤   ¤   // ·mask bits specifying things to configure
9c52f4 ¤   LPSTR¤  lpszHelpFile;¤  ¤   // ·name of help file
fb4737 ¤   ULONG¤  ulOptionFlags;¤ ¤   //¤ logical OR of option bits (above)
9824ae ¤   ULONG¤  ulDisableActions;¤  // ·logical OR of actions (above) to disable
f2495e ¤   ULONG¤  ulShowColumns;¤ ¤   // ·logical OR of columns to always show
5a243a ¤   ULONG¤  ulHideColumns;¤ ¤   // ·logical OR of columns to always hide
eef159 ¤   HWND¤   hWndStatusBar;¤ ¤   // ·handle of status bar window
07af5a
d282a8 ¤   PGPKeyServerEntry¤  keyserver;¤ // ·keyserver to use for subsequent ops
bf3a77 } KMCONFIG, *LPKMCONFIG;
c4af5a
d73379 #ifdef __cplusplus
bb6dad extern "C" {
927454 #endif
edaf5a
17af5a
707015 //________________________________________________
a8465d //
a90360 //¤ PGPkmCreateKeyManager -
971b1e //¤ Creates empty keymanager window
48465d //
bcc802 //¤ Entry parameters :
b1f7bc //¤ ¤   Context¤¤   - PGP library context
e5cccb //¤ ¤   hWndParent¤ - handle of parent window
e13a0f //¤ ¤   id¤ ¤   ¤   - window ID to assign to manager (used in notifications)
dec723 //¤ ¤   lpfnSetList¤- callback to add/remove dialog windows from list
8af70d //¤ ¤   x¤  ¤   ¤   - x coordinate of manager window relative to parent
baf175 //¤ ¤   y¤  ¤   ¤   - y coordinate of manager window relative to parent
c8bd08 //¤ ¤   nWidth¤ ¤   - width of manager window
3b9f3a //¤ ¤   nHeight¤¤   - height of manager window
c5465d //
aaea46 //¤ Returns handle to keymanager
38465d //
37af5a
5b3bad HKEYMAN PGPkmExport·
ef7763 PGPkmCreateKeyManager (PGPContextRef¤   Context,
1e0eaf ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef¤tlsContext,
106799 ¤   ¤   ¤   ¤   ¤   ···HWND¤¤   ¤   ¤   hWndParent,·
546bad ¤   ¤   ¤   ¤   ¤   ···INT¤ ¤   ¤   ¤   id,·
d095e3 ¤   ¤   ¤   ¤   ¤   ···HWNDLISTPROC¤¤   lpfnSetList,
--a664 0004de76c0240110205 Page 3 of PGPkm.h
2767d7 ¤   ¤   ¤   ¤   ¤   ···INT¤ ¤   ¤   ¤   x,·
0dc59c ¤   ¤   ¤   ¤   ¤   ···INT¤ ¤   ¤   ¤   y,
39832b ¤   ¤   ¤   ¤   ¤   ···INT¤ ¤   ¤   ¤   nWidth,·
2a0482 ¤   ¤   ¤   ¤   ¤   ···INT¤ ¤   ¤   ¤   nHeight);
c7af5a
4a7015 //________________________________________________
6d465d //
3824d3 //¤ PGPkmSetConfiguration -
1da5e2 //¤ Configures keymanager window
af465d //
4cc802 //¤ Entry parameters :
7526d7 //¤ ¤   hKeyMan¤¤   - handle of key manager to configure
0bf643 //¤ ¤   pKMConfig¤  - pointer to KMCONFIG struct
b9465d //
ff0a22 //¤ Returns kPGPError_NoErr if no error
bb465d //
7daf5a
bdb997 PGPError PGPkmExport·
2a81a6 PGPkmConfigure (HKEYMAN¤¤   hKeyMan,·
5a7e6b ¤   ¤   ¤   ¤   LPKMCONFIG¤ pKMConfig);
5caf5a
137015 //________________________________________________
6a465d //
6b2ab9 //¤ PGPkmDestroyKeyManager -
5adada //¤ Destroys keymanager window
ad465d //
c5c802 //¤ Entry parameters :
fbec90 //¤ ¤   hKeyMan¤¤   ¤   - handle of key manager to destroy
33910a //¤ ¤   bSaveColumnInfo¤- TRUE => save column info to pref file
af465d //
e71a65 //¤ Returns kPGPError_NoErr if successful
18465d //
67af5a
1bb997 PGPError PGPkmExport·
e9f4ff PGPkmDestroyKeyManager (HKEYMAN hKeyMan,
ce8d6c ¤   ¤   ¤   ¤   ¤   ¤   BOOL¤   bSaveColumnInfo);
82af5a
a47015 //________________________________________________
39465d //
c0f94f //¤ PGPkmDefaultNotificationProc -
b9cbf5 //¤ Handles default behavior for TreeList notifications
1f465d //
1bc802 //¤ Entry parameters :
977490 //¤ ¤   hKeyMan¤- handle of key manager
238c19 //¤ ¤   lParam¤ - LPARAM from WM_NOTIFY message
d2465d //
2edb72 //¤ Returns kPGPError_NoErr
ce465d //
c5af5a
71b997 PGPError PGPkmExport·
195e5d PGPkmDefaultNotificationProc (HKEYMAN¤  hKeyMan, ¤  ¤   ¤   ¤   ¤   ··
8bef59 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM¤   lParam);
0eaf5a
5c7015 //________________________________________________
8d465d //
f9ea84 //¤ PGPkmSynchronizeThreadAccessToSDK -
56edf7 //¤ synchronizes
9d465d //
aec802 //¤ Entry parameters :
9f7490 //¤ ¤   hKeyMan¤- handle of key manager
d7465d //
43db72 //¤ Returns kPGPError_NoErr
1a465d //
50af5a
2d7cb4 VOID PGPkmExport·
0576ea PGPkmSynchronizeThreadAccessToSDK (HKEYMAN¤ hKeyMan);
48af5a
6daf5a
677015 //________________________________________________
a6465d //
713dc0 //¤ PGPkmProcessKeyPropMessage -
4dfb75 //¤ perform action requested by key props property sheet
--d1d7 00060de751b40110205 Page 4 of PGPkm.h
c1465d //
4ac802 //¤ Entry parameters :
e07490 //¤ ¤   hKeyMan¤- handle of key manager
e8d7cf //¤ ¤   wParam¤ - wParam of message coming from prop sheet
5b7756 //¤ ¤   lParam¤ - lParam of message coming from prop sheet
d2465d //
06db72 //¤ Returns kPGPError_NoErr
fa465d //
69af5a
757cb4 VOID PGPkmExport·
b981ef PGPkmProcessKeyPropMessage (HKEYMAN hKeyMan, WPARAM wParam, LPARAM lParam);
34af5a
73af5a
8e7015 //________________________________________________
d6465d //
381116 //¤ PGPkmIsActionEnabled -
59b061 //¤ reports if specified action is enabled or not
98465d //
1bc802 //¤ Entry parameters :
fc7490 //¤ ¤   hKeyMan¤- handle of key manager
b14fbb //¤ ¤   uAction¤- action constant from above list
5d465d //
4f8664 //¤ Returns TRUE if enabled, FALSE if not
75465d //
41af5a
451cb5 BOOL PGPkmExport·
ab6138 PGPkmIsActionEnabled (HKEYMAN¤  hKeyMan,·
18633d ¤   ¤   ¤   ¤   ¤   ··ULONG¤¤   uAction);
8daf5a
487015 //________________________________________________
a5465d //
4e7dad //¤ PGPkmPerformAction -
a66f64 //¤ requests that specified action be performed on
6fb7df //¤ currently selected objects
cc465d //
7cc802 //¤ Entry parameters :
a17490 //¤ ¤   hKeyMan¤- handle of key manager
d84fbb //¤ ¤   uAction¤- action constant from above list
13465d //
961a65 //¤ Returns kPGPError_NoErr if successful
a4465d //
36af5a
ffb997 PGPError PGPkmExport·
aeb057 PGPkmPerformAction (HKEYMAN hKeyMan,·
58e2c8 ¤   ¤   ¤   ¤   ¤   ULONG¤  uAction);
5daf5a
d47015 //________________________________________________
20465d //
63017f //¤ PGPkmGetManagerWindow -
1fd035 //¤ returns HWND of keymanager window
cf465d //
e3c802 //¤ Entry parameters :
e37490 //¤ ¤   hKeyMan¤- handle of key manager
b5465d //
866043 //¤ Returns HWND if successful, NULL if error.
18465d //
15af5a
434dde HWND PGPkmExport·
29b62a PGPkmGetManagerWindow (HKEYMAN hKeyMan);
07af5a
d47015 //________________________________________________
93465d //
4ce847 //¤ PGPkmLoadKeySets -
8e2529 //¤ load keyset into manager
75465d //
28c802 //¤ Entry parameters :
6ae04c //¤ ¤   hKeyMan¤¤   - handle of key manager
7d9f57 //¤ ¤   pKeySetDisp¤- keyset to display in window
4224c3 //¤ ¤   pKeySetMain¤- main keyset used for commits and trust calcs
2b465d //
770a22 //¤ Returns kPGPError_NoErr if no error
60465d //
--fa47 000f42afd7e40110205 Page 5 of PGPkm.h
e0af5a
dbb997 PGPError PGPkmExport·
3de3eb PGPkmLoadKeySet (HKEYMAN¤   ¤   hKeyMan,·
abdf09 ¤   ¤   ¤   ¤   ·PGPKeySetRef¤  KeySetDisp,
b551e9 ¤   ¤   ¤   ¤   ·PGPKeySetRef¤  KeySetMain);
baaf5a
527015 //________________________________________________
53465d //
1858d9 //¤ PGPkmReLoadKeySet -
1ff7c8 //¤ reload keyset into manager
be465d //
2ac802 //¤ Entry parameters :
06e04c //¤ ¤   hKeyMan¤¤   - handle of key manager
abaf31 //¤ ¤   bExpandNew¤ - TRUE => expand any newly-found objects
aa465d //
640a22 //¤ Returns kPGPError_NoErr if no error
d9465d //
a2af5a
86b997 PGPError PGPkmExport·
558736 PGPkmReLoadKeySet (HKEYMAN hKeyMan, BOOL bExpandNew);
29af5a
84af5a
017015 //________________________________________________
3b465d //
79584c //¤ PGPkmSelectColumns -
65b406 //¤ set columns to be displayed
27465d //
c3c802 //¤ Entry parameters :
7d6518 //¤ ¤   hKeyMan¤¤   ¤   - handle of key manager
717a51 //¤ ¤   ulColumnFlags¤  - flags selecting columns to display
b530c9 //¤ ¤   bRedraw¤¤   ¤   - TRUE=>forces redraw of display
7a465d //
440a22 //¤ Returns kPGPError_NoErr if no error
a8465d //
b0af5a
0bb997 PGPError PGPkmExport·
75803b PGPkmSelectColumns (HKEYMAN hKeyMan, ULONG ulColumnFlags, BOOL bRedraw);
25af5a
91af5a
de7015 //________________________________________________
d3465d //
49584c //¤ PGPkmSelectColumns -
cd3a37 //¤ get currently displayed columns
65465d //
b6c802 //¤ Entry parameters :
9d6518 //¤ ¤   hKeyMan¤¤   ¤   - handle of key manager
fa8088 //¤ ¤   pulColumnFlags¤ - buffer to receive flags of selected columns
bb465d //
600a22 //¤ Returns kPGPError_NoErr if no error
a5465d //
1daf5a
a9b997 PGPError PGPkmExport·
d3c3e3 PGPkmGetSelectedColumns (HKEYMAN hKeyMan, ULONG* pulColumnFlags);
50af5a
7daf5a
bb7015 //________________________________________________
eb465d //
724661 //¤ PGPkmSelectKey -
faf06c //¤ select the specified key
2e465d //
d2c802 //¤ Entry parameters :
afe04c //¤ ¤   hKeyMan¤¤   - handle of key manager
689a10 //¤ ¤   key¤¤   ¤   - key to select
4a8429 //¤ ¤   bDeselect¤  - TRUE => deselect all keys before selecting
9a465d //
bc0a22 //¤ Returns kPGPError_NoErr if no error
f5465d //
2eaf5a
94b997 PGPError PGPkmExport·
9cfdee PGPkmSelectKey (HKEYMAN hKeyMan, PGPKeyRef key, BOOL bDeselect);
feaf5a
f4af5a
--c8bd 001c6095b8a40110205 Page 6 of PGPkm.h
1b7015 //________________________________________________
87465d //
311f64 //¤ PGPkmGetSelectedKeys -
9f078d //¤ get a keyset of the currently selected keys
6e465d //
1cc802 //¤ Entry parameters :
126518 //¤ ¤   hKeyMan¤¤   ¤   - handle of key manager
6ffb84 //¤ ¤   pkeysetSelected¤- pointer to buffer to receive keyset ref
0017aa //¤ ¤   ¤   ¤   ¤   ¤   ··(must be freed when done)
ab465d //
a80a22 //¤ Returns kPGPError_NoErr if no error
74465d //
83af5a
63b997 PGPError PGPkmExport·
db11bf PGPkmGetSelectedKeys (HKEYMAN hKeyMan, PGPKeySetRef* pkeysetSelected);
d4af5a
57af5a
807015 //________________________________________________
84465d //
0d97de //¤ PGPkmOKToClose -
c0d076 //¤ ask if OK to close down keymanager
f7465d //
b6c802 //¤ Entry parameters :
11e04c //¤ ¤   hKeyMan¤¤   - handle of key manager
2a658c //¤ ¤   puReason¤   - buffer to receive reason for not closing
d5465d //
43bfbc //¤ Returns TRUE if OK to close
4b465d //
36af5a
1a3ab8 BOOL PGPkmExport
dc29b1 PGPkmOKToClose (HKEYMAN hKeyMan, UINT* puReason);
66af5a
82af5a
f53379 #ifdef __cplusplus
61efe6 }
9d7454 #endif
11af5a
98f707 #endif /* ] Included_PGPkm_h */
6aaf5a
09af5a
0f7e4d /*__Editor_settings____
4caf5a
804126 ¤   Local Variables:
fb7b17 ¤   tab-width: 4
a10e6c ¤   End:
de5f8c ¤   vi: ts=4 sw=4
e99e9b ¤   vim: si
c6d062 _____________________*/
--a04c 00161f99ec240110206 Page 1 of PGPpk.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
2f77ac ¤   PGPpk.h - include file for PGPkeys application
0267c5 ¤
d9af5a
497cfc ¤   $Id: PGPpk.h,v 1.2 1998/08/11 14:06:18 pbj Exp $
6ff7f7 ____________________________________________________________________________*/
572953 #ifndef Included_PGPpk_h¤   /* [ */
60341c #define Included_PGPpk_h
beaf5a
7c9bc5 #define WINCLASSNAME¤   ("PGPkeysMainWinClass")
dac641 #define WINDOWTITLE¤¤   ("PGPkeys")
f9a3c5 #define SEMAPHORENAME¤  ("PGPkeysInstSem")
deaf5a
6b682d #define¤PGPPK_SELECTIVEIMPORT¤  ¤   0x00000001
ebaf5a
b85ade #define¤PGPPK_IMPORTKEYMASK¤¤   ¤   0xFFFF0000
c5e633 #define PGPPK_IMPORTKEYBUFFER¤  ¤   0x00010000
92d44b #define PGPPK_IMPORTKEYFILELIST¤¤   0x00020000
8e4cf6 #define PGPPK_IMPORTKEYCOMMANDLINE¤ 0x00040000
36af5a
82f707 #endif /* ] Included_PGPkm_h */
caaf5a
fcaf5a
287e4d /*__Editor_settings____
84af5a
7c4126 ¤   Local Variables:
ea7b17 ¤   tab-width: 4
cc0e6c ¤   End:
685f8c ¤   vi: ts=4 sw=4
8a9e9b ¤   vim: si
61d062 _____________________*/
--7fed 000f9528dce40110207 Page 1 of PGPsc.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
a0dce0 ¤   PGPsc.h - include file for PGPsc DLL
4867c5 ¤
cfaf5a
4f2d25 ¤   $Id: PGPsc.h,v 1.36.2.3 1998/10/09 16:05:01 wjb Exp $
a4f7f7 ____________________________________________________________________________*/
9507b2 #ifndef _PGPSCH
4c24ba #define _PGPSCH
e0af5a
bcdbcb #include <shellapi.h>
77af5a
1a7515 typedef struct _FILELIST
61bb36 {
d2a27b ¤   char name[MAX_PATH];
47cec2 ¤   BOOL IsDirectory;
c73353 ¤   struct _FILELIST *next;
d44bec } FILELIST;
0faf5a
ff36ec typedef struct _OUTBUFFLIST {
9ca5ab ¤   char *pBuff;
da5b92 ¤   DWORD dwBuffSize;
59414d ¤   BOOL FYEO;
9b96f9 ¤   struct _OUTBUFFLIST *next;
085d1e } OUTBUFFLIST;
26af5a
5f3379 #ifdef __cplusplus
c36dad extern "C" {
b67454 #endif
0faf5a
546a68 // Library initialization routines
c0831a BOOL InitPGPsc(HWND hwnd,void **PGPsc,void **PGPtls);
765283 BOOL UninitPGPsc(HWND hwnd,void *PGPsc,void *PGPtls);
95af5a
038c8e BOOL CheckForPurge(UINT uMsg,WPARAM wParam);
aaaf5a
09309c // Clipboard routines
f30fe9 BOOL EncryptClipboard(HWND hwnd,void *PGPsc,void *PGPtls,
efcd2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL Encrypt,BOOL Sign);
3b45ce BOOL DecryptClipboard(HWND hwnd,void *PGPsc,void *PGPtls);
cfc2a6 BOOL AddKeyClipboard(HWND hwnd,void *PGPsc,void *PGPtls);
11e8d7 BOOL ClipboardWipe(HWND hwnd,void *PGPsc);
8caf5a
647def // Filelist routines
6e9260 BOOL EncryptFileList(HWND hwnd,void *PGPsc,void *PGPtls,
b4e8b0 ¤   ¤   ¤   ¤   ¤   ·FILELIST *ListHead,BOOL bEncrypt,BOOL bSign);
d9b69e BOOL DecryptFileList(HWND hwnd,void *PGPsc,void *PGPtls,FILELIST *ListHead);
8a59f4 BOOL AddKeyFileList(HWND hwnd,void *PGPsc,void *PGPtls,FILELIST *ListHead);
ff1e55 BOOL WipeFileList(HWND hwnd,void *PGPsc,FILELIST *ListHead);
20af5a
e21298 // Filelist utility functions (Note that UserCancel can be NULL)
1bf117 BOOL AddToFileList(FILELIST **filelist,char *filename,BOOL *UserCancel);
801ff8 BOOL FreeFileList(FILELIST *FileList);
7faf5a
a8e087 FILELIST *HDropToFileList(HDROP hDrop);
c0c7fa FILELIST *CmdLineToFileList(char *szCmdLine);
99af5a
cfd3b6 // Call-throughs to PGPcl
e8aae1 UINT PGPscQueryCacheSecsRemaining (void);
2fb30d BOOL PGPscPreferences(HWND hwnd,void *PGPsc,void *PGPtls);
696ee8 BOOL PGPscAbout (HWND hwnd,void *PGPsc);
19af5a
916cc4 // Returns filename from path
2d8ead char *JustFile(char *filename);
73af5a
d9109a // Grabs preferences from pref file
ef6c0a BOOL GetValidityDrawPrefs(void *PGPsc,BOOL *pbInputBool);
08e4f5 BOOL GetMarginalInvalidPref(void *PGPsc,BOOL *pbInputBool);
98af5a
f90d2b // Views the clipboard
--675a 0014c79ed9840110207 Page 2 of PGPsc.h
487870 void LaunchInternalViewer(HWND hwnd);
59af5a
93f10b // Use secure viewer and/or anti-tempest font
4ae6b7 UINT TempestViewer(void *PGPsc,HWND hwnd,char *pInput,DWORD dwInSize);
f4af5a
c277b6 // Launches Keys/Tools
6b42be BOOL DoLaunchKeys(HWND hwnd);
cdc63c BOOL DoLaunchTools(HWND hwnd);
7f32df BOOL DoLaunchDisk(HWND hwnd);
a1af5a
70b8e7 // Wipe free space on disk
03b856 void FreeSpaceWipeWizard(HWND hwnd, void* PGPsc);
1eaf5a
0bf0ea // Detects if window exists
2efc15 BOOL WindowExists (LPSTR lpszClassName, LPSTR lpszWindowTitle);
8eaf5a
ee44e5 // Sends signature info to PGPlog
e68036 BOOL SendPGPlogMsg(HWND hwnd,char* szMsg);
f4af5a
696c7b // Returns path for PGPkeys
02c489 void PGPpath(char *szPath);
01af5a
32210d // Copy/Paste into current window
767607 BOOL DoCopy(HWND hwnd,void *PGPsc,BOOL bUseCurrent,HWND *hwndFocus);
72bf1d void DoPaste(BOOL bUseCurrent,HWND hwndFocus);
e7aab8 void DoFocus(BOOL bUseCurrent,HWND hwndFocus);
14af5a
e05e95 // Auto-update keyring routines
f9e5e8 void StartUpdateTimer(HWND hwnd, UINT *pnLaunchKeysTimer);
5d0f6e VOID CALLBACK UpdateTimerProc(HWND hwnd,·
926983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
ed465b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT idEvent,·
c4a1af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··DWORD dwTime);
59af5a
f6126e OUTBUFFLIST *MakeOutBuffItem(OUTBUFFLIST **obl);
81af5a
204bac BOOL ConcatOutBuffList(void *PGPsc,
b7cefa ¤   ¤   ¤   ¤   ¤   ···OUTBUFFLIST *obl,
1681a5 ¤   ¤   ¤   ¤   ¤   ···char **pBuff,
e39a5d ¤   ¤   ¤   ¤   ¤   ···DWORD *dwBuffSize,
bbb637 ¤   ¤   ¤   ¤   ¤   ···BOOL *FYEO);
79af5a
662664 #ifdef WIN32
c30c6e #define DDElogServer "PGPlog"
efdb21 #else
ae4f91 #define DDElogServer "PGPlog16"
ea7454 #endif
8568ac #define DDElogTopic "Operation_Results"
38af5a
3a3379 #ifdef __cplusplus
4defe6 }
ea7454 #endif
1baf5a
4ce68c #endif // PGPSCH
--243e 00000ca55ff40110208 Page 1 of TreeList.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
928918 ¤   TreeList.h¤ - ¤ header for TreeList custom control
86af5a
d1c8f7 ¤   $Id: TreeList.h,v 1.17 1998/08/11 14:06:19 pbj Exp $
0167c5 ¤
f5f7f7 ____________________________________________________________________________*/
a6edfd // This file partially derived from COMMCTRL.H by Microsoft Corp.
e5af5a
08dce2 #ifndef _INC_TREELIST
3b80e7 #define _INC_TREELIST
7daf5a
25e64e #ifndef NOUSER
a7af5a
64af5a
72465d //
874d19 // Define API decoration for direct importing of DLL references.
29465d //
a72a1e #ifndef WINCOMMCTRLAPI
f4bd37 #if !defined(_COMCTL32_) && defined(_WIN32)
0b74c4 #define WINCOMMCTRLAPI DECLSPEC_IMPORT
71db21 #else
cb7def #define WINCOMMCTRLAPI
fa7454 #endif
9a2e21 #endif // WINCOMMCTRLAPI
53af5a
c9465d //
0ff5e4 // For compilers that don't support nameless unions
ce465d //
66230f #ifndef DUMMYUNIONNAME
4c38f3 #ifdef NONAMELESSUNION
370735 #define DUMMYUNIONNAME ··u
c4f53e #define DUMMYUNIONNAME2 ·u2
38e8cd #define DUMMYUNIONNAME3 ·u3
d0db21 #else
df74fe #define DUMMYUNIONNAME
75c9bd #define DUMMYUNIONNAME2
41d065 #define DUMMYUNIONNAME3
1d7454 #endif
3f2730 #endif // DUMMYUNIONNAME
37af5a
beec08 #ifdef _WIN32
40e8e1 #include <pshpack1.h>
4c7454 #endif
66af5a
803379 #ifdef __cplusplus
076dad extern "C" {
327454 #endif
3daf5a
e2b31d //===========================================================================
26465d //
ba7dbe // Users of this header may define any number of these constants to avoid
4f6574 // the definitions of each functional group.
c6465d //
8fe337 // NOTREELIST ··Custom control which is hybrid of TreeView and ListView
b9465d //
08b31d //===========================================================================
23af5a
28b052 #include <prsht.h>
eaaf5a
0baf5a
423379 #ifdef __cplusplus
b02837 #define SNDMSG ::SendMessage
44db21 #else
50c0e9 #define SNDMSG SendMessage
0c7454 #endif
93af5a
83af5a
ca174c void WINAPI InitTreeListControl (void);
00af5a
--30ca 0003b94f99640110208 Page 2 of TreeList.h
e0af5a
72172e //====== Ranges for control message IDs =====================================
94af5a
821361 #define TLM_FIRST ··············0x1000 ·····// TreeList messages
45af5a
1caf5a
ba780e //====== WM_NOTIFY codes (NMHDR.code values) ================================
2faf5a
bf933f #define TLN_FIRST ··············(0U-100U) ······
f6e72c #define TLN_LAST ···············(0U-199U)
e5af5a
d1af5a
c87c74 //====== TREELIST CONTROL ===================================================
20af5a
ae978a #ifndef NOTREELIST
81af5a
5cec08 #ifdef _WIN32
2b5172 #define WC_TREELISTA ···········"TreeListCtrl32"
04abd8 #define WC_TREELISTW ···········L"TreeListCtrl32"
e7af5a
5cd377 #ifdef UNICODE
66fed0 #define ·WC_TREELIST ···········WC_TREELISTW
b8db21 #else
373f91 #define ·WC_TREELIST ···········WC_TREELISTA
c47454 #endif
2caf5a
0fdb21 #else
991b99 #define WC_TREELIST ············"TreeListCtrl"
137454 #endif
b3af5a
2c0439 #define TLS_HASBUTTONS ·········0x0001
1982f1 #define TLS_HASLINES ···········0x0002
b7aca5 #define TLS_LINESATROOT ········0x0004
2681ac #define TLS_AUTOSCROLL¤ ¤   ¤   0x0008
877e6e #define TLS_PROMISCUOUS¤¤   ¤   0x0010
1cd3d4 #define TLS_SINGLESELECT¤   ¤   0x0020
85307c #define TLS_INTERNALDRAG¤   ¤   0x0040
79c312 #define TLS_DRAGABLEHEADERS¤¤   0x0080
1baf5a
8a1852 typedef struct _TLITEM FAR* HTLITEM;
a2af5a
7998e9 #define TLIF_TEXT ··············0x0001
1ccb38 #define TLIF_IMAGE ·············0x0002
11b047 #define TLIF_PARAM ·············0x0004
206592 #define TLIF_STATE ·············0x0008
809e23 #define TLIF_HANDLE ············0x0010
defdc7 #define TLIF_DATAVALUE¤ ¤   ¤   0x0020
1b4028 #define TLIF_NEXTHANDLE¤¤   ¤   0x0040
4e6fce #define TLIF_PARENTHANDLE¤  ¤   0x0080
80461a #define TLIF_PREVHANDLE¤¤   ¤   0x0100
87fae1 #define TLIF_CHILDHANDLE¤   ¤   0x0200
7aaf5a
397921 #define TLIS_FOCUSED ···········0x0001
a12dda #define TLIS_SELECTED ··········0x0002
ec16ae #define TLIS_EXPANDED ··········0x0004
8124a4 #define TLIS_BOLD ··············0x0008
b0079f #define TLIS_ITALICS¤   ¤   ¤   0x0010
ab3d78 #define TLIS_CLICKED¤   ¤   ¤   0x0020
720bc1 #define TLIS_VISIBLE¤   ¤   ¤   0x0080
5397de #define TLIS_DRAGGEDOVER¤   ¤   0x0100
c1af5a
5fa835 typedef struct _TL_TREEITEMA {
df0a71 ····UINT ·····mask;
be66d2 ····HTLITEM ··hItem;
eb4793 ····UINT ·····state;
a9d4e6 ····UINT ·····stateMask;
7fefd1 ····LPSTR ····pszText;
56be9f ····int ······cchTextMax;
0d8efe ····int ······iImage;
ca197f ····int ······iSelectedImage;
58d24c ····int ······cChildren;
3ba2d4 ····LPARAM ···lParam;
--f40f 000b7be8f2440110208 Page 3 of TreeList.h
7a950d } TL_TREEITEMA, FAR *LPTL_TREEITEMA;
f3af5a
45200e typedef struct _TL_TREEITEMW {
ea0a71 ····UINT ·····mask;
6a66d2 ····HTLITEM ··hItem;
564793 ····UINT ·····state;
78d4e6 ····UINT ·····stateMask;
caeca1 ····LPWSTR ···pszText;
25be9f ····int ······cchTextMax;
248efe ····int ······iImage;
ba197f ····int ······iSelectedImage;
b6d24c ····int ······cChildren;
50a2d4 ····LPARAM ···lParam;
b789dd } TL_TREEITEMW, FAR *LPTL_TREEITEMW;
aaaf5a
88d377 #ifdef UNICODE
12b2d8 #define ·TL_TREEITEM ···············TL_TREEITEMW
a08c6d #define ·LPTL_TREEITEM ·············LPTL_TREEITEMW
0adb21 #else
a27399 #define ·TL_TREEITEM ···············TL_TREEITEMA
e44d2c #define ·LPTL_TREEITEM ·············LPTL_TREEITEMA
217454 #endif
50af5a
33af5a
5a051a #define TLI_ROOT ···············((HTLITEM)0xFFFF0000)
29f6fa #define TLI_FIRST ··············((HTLITEM)0xFFFF0001)
f90283 #define TLI_LAST ···············((HTLITEM)0xFFFF0002)
70ec70 #define TLI_SORT ···············((HTLITEM)0xFFFF0003)
642513 #define TLI_SORTREVERSE ········((HTLITEM)0xFFFF0004)
89af5a
e7a0f6 typedef struct _TL_INSERTSTRUCTA {
7a6461 ····HTLITEM hParent;
44188a ····HTLITEM hInsertAfter;
8309e1 ····TL_TREEITEMA item;
086703 } TL_INSERTSTRUCTA, FAR *LPTL_INSERTSTRUCTA;
15af5a
be28cd typedef struct _TL_INSERTSTRUCTW {
546461 ····HTLITEM hParent;
c8188a ····HTLITEM hInsertAfter;
684f28 ····TL_TREEITEMW item;
860105 } TL_INSERTSTRUCTW, FAR *LPTL_INSERTSTRUCTW;
ccaf5a
3cd377 #ifdef UNICODE
897481 #define ·TL_INSERTSTRUCT ·······TL_INSERTSTRUCTW
ea4a40 #define ·LPTL_INSERTSTRUCT ·····LPTL_INSERTSTRUCTW
67db21 #else
2db5c0 #define ·TL_INSERTSTRUCT ·······TL_INSERTSTRUCTA
ab8b01 #define ·LPTL_INSERTSTRUCT ·····LPTL_INSERTSTRUCTA
df7454 #endif
a2af5a
ef411f #define TLM_INSERTITEMA ········(TLM_FIRST + 0)
c0d09e #define TLM_INSERTITEMW ········(TLM_FIRST + 50)
48d377 #ifdef UNICODE
c23672 #define ·TLM_INSERTITEM ········TLM_INSERTITEMW
1bdb21 #else
2ef733 #define ·TLM_INSERTITEM ········TLM_INSERTITEMA
c27454 #endif
59af5a
321974 #define TreeList_InsertItem(hwnd, lpis) \
189685 ····(HTLITEM)SNDMSG((hwnd), TLM_INSERTITEM, 0, \
00b593 ¤   (LPARAM)(LPTL_INSERTSTRUCT)(lpis))
19af5a
88af5a
3665d6 #define TLM_DELETETREE ·········(TLM_FIRST + 3)
1e26a3 #define TreeList_DeleteTree(hwnd, bFree) \
e0c426 ····(BOOL)SNDMSG((hwnd), TLM_DELETETREE, bFree, 0)
65af5a
84af5a
aae72c #define TLM_DELETEITEM ·········(TLM_FIRST + 1)
69d997 #define TreeList_DeleteItem(hwnd, hitem) \
03bbe3 ····(BOOL)SNDMSG((hwnd), TLM_DELETEITEM, 0, (LPARAM)(HTLITEM)(hitem))
b7af5a
--1915 0002efe8ac740110208 Page 4 of TreeList.h
e0af5a
49684e #define TLM_EXPAND ·············(TLM_FIRST + 2)
74f462 #define TreeList_Expand(hwnd, hitem, code) \
86dc67 ····(BOOL)SNDMSG((hwnd), TLM_EXPAND, (WPARAM)code, \
10b21c ¤   (LPARAM)(HTLITEM)(hitem))
2faf5a
c2af5a
a018a3 #define TLE_COLLAPSE ···········0x0001
dfa448 #define TLE_EXPAND ·············0x0002
661fd5 #define TLE_TOGGLE ·············0x0003
32a2da #define TLE_COLLAPSEALL¤¤   ¤   0x0004
48688f #define TLE_EXPANDALL¤  ¤   ¤   0x0005
b7af5a
71fdaf #define TLM_SETIMAGELIST ·······(TLM_FIRST + 9)
5b2ac4 #define TreeList_SetImageList(hwnd, himl) \
93ffc1 ····(HIMAGELIST)SNDMSG((hwnd), TLM_SETIMAGELIST, 0, \
592079 ¤   (LPARAM)(UINT)(HIMAGELIST)(himl))
d0af5a
cd1a43 #define TLM_SELECTITEM ·········(TLM_FIRST + 11)
923019 #define TreeList_Select(hwnd, hitem, bdeselect) \
f0cf95 ····(HTLITEM)SNDMSG((hwnd), TLM_SELECTITEM, (WPARAM)bdeselect, \
eeb21c ¤   (LPARAM)(HTLITEM)(hitem))
30af5a
80deb9 #define TLM_DRAGOVER¤   ¤   ¤   (TLM_FIRST + 14)
e395b7 #define TreeList_DragOver(hwnd, coords) \
2b6efa ¤   (BOOL)SNDMSG((hwnd), TLM_DRAGOVER, 0, (LPARAM)(coords))
e5af5a
49b7a4 #define TLRB_TOPLEVELONLY¤  ¤   0x0001
cfaf5a
ddee7f typedef struct _TL_DRAGBITMAP {
a9a156 ¤   HBITMAP¤¤   hbmDrag;
2631fa ¤   SIZE¤   ¤   sizeDrag;
dad0d0 ¤   POINT¤  ¤   ptCursorPos;
f66f67 ¤   POINT¤  ¤   ptHotSpot;
3e85e8 ¤   ULONG¤  ¤   ulFlags;
28877f } TL_DRAGBITMAP, FAR *LPTL_DRAGBITMAP;
1daf5a
7b9135 #define TLM_RENDERDRAGBITMAP¤   (TLM_FIRST + 15)
232360 #define TreeList_RenderDragBitmap(hwnd, lpdb) \
19cfe3 ¤   (BOOL)SNDMSG((hwnd), TLM_RENDERDRAGBITMAP, 0, \
44cd4d ¤   (LPARAM)(LPTL_DRAGBITMAP)(lpdb))
97af5a
b44eb6 #define TLM_DRAGOVERPAINT¤  ¤   (TLM_FIRST + 16)
a380ad #define TreeList_DragOverPaint(hwnd) \
245e4d ¤   (BOOL)SNDMSG((hwnd), TLM_DRAGOVERPAINT, 0, 0)
d2af5a
e6c8bb #define TLM_SELECTCHILDREN ·····(TLM_FIRST + 20)
40df02 #define TreeList_SelectChildren(hwnd, hitem) \
723473 ····(HTLITEM)SNDMSG((hwnd), TLM_SELECTCHILDREN, 0, \
a5b21c ¤   (LPARAM)(HTLITEM)(hitem))
88af5a
98765e #define TLM_ITERATESELECTED ····(TLM_FIRST + 21)
6c2aa6 #define TreeList_IterateSelected(hwnd, userstruct) \
53ab81 ····(HTLITEM)SNDMSG((hwnd), TLM_ITERATESELECTED, 0, (LPARAM)(userstruct))
82af5a
33af5a
be2e08 #define TLM_GETITEMA ···········(TLM_FIRST + 12)
1ca411 #define TLM_GETITEMW ···········(TLM_FIRST + 62)
beaf5a
fcd377 #ifdef UNICODE
2e948a #define ·TLM_GETITEM ···········TLM_GETITEMW
a8db21 #else
bc55cb #define ·TLM_GETITEM ···········TLM_GETITEMA
417454 #endif
eaaf5a
97f23d #define TreeList_GetItem(hwnd, pitem) \
a06a3f ····(BOOL)SNDMSG((hwnd), TLM_GETITEM, 0, (LPARAM)(TL_TREEITEM FAR*)(pitem))
dcaf5a
4eaf5a
2270c1 #define TLM_SETITEMA ···········(TLM_FIRST + 13)
4afad8 #define TLM_SETITEMW ···········(TLM_FIRST + 63)
2eaf5a
--a267 000a5f94f9b40110208 Page 5 of TreeList.h
a6d377 #ifdef UNICODE
4ecf35 #define ·TLM_SETITEM ···········TLM_SETITEMW
18db21 #else
ef0e74 #define ·TLM_SETITEM ···········TLM_SETITEMA
3e7454 #endif
d41923 #define TreeList_SetItem(hwnd, pitem) \
70de80 ····(BOOL)SNDMSG((hwnd), TLM_SETITEM, 0, \
7fb7e4 ¤   (LPARAM)(const TL_TREEITEM FAR*)(pitem))
d7af5a
91af5a
f94a99 #define TLM_GETFIRSTITEM ············(TLM_FIRST + 18)
e10af9 #define TreeList_GetFirstItem(hwnd) \
238031 ····(HTLITEM)SNDMSG((hwnd), TLM_GETFIRSTITEM, 0, 0)
0eaf5a
2d95bd typedef struct _TL_COLUMNA
42bb36 {
a2e526 ····UINT mask;
db37e5 ····int fmt;
9c6187 ····int cx;
3175e1 ····LPSTR pszText;
57b7ac ····int cchTextMax;
791c12 ····int iSubItem;
a67339 ¤   UINT iDataType;
c27b02 ¤   BOOL bMouseNotify;
37c352 } TL_COLUMNA;
9aaf5a
0c54fc typedef struct _TL_COLUMNW
d0bb36 {
e0e526 ····UINT mask;
b037e5 ····int fmt;
4c6187 ····int cx;
f123c8 ····LPWSTR pszText;
3eb7ac ····int cchTextMax;
e41c12 ····int iSubItem;
ac7339 ¤   UINT iDataType;
787b02 ¤   BOOL bMouseNotify;
2b901e } TL_COLUMNW;
7aaf5a
52d377 #ifdef UNICODE
014471 #define ·TL_COLUMN ·············TL_COLUMNW
addb21 #else
148530 #define ·TL_COLUMN ·············TL_COLUMNA
097454 #endif
1caf5a
70f723 #define TLC_DATANONE¤   ¤   ¤   0x0000
dfafee #define TLC_DATASTRING¤ ¤   ¤   0x0001
7f69ad #define TLC_DATALONG¤   ¤   ¤   0x0002
14af5a
0093c3 #define TLCF_FMT ···············0x0001
458f11 #define TLCF_WIDTH ·············0x0002
a2eddd #define TLCF_TEXT ··············0x0004
cb7ecb #define TLCF_SUBITEM ···········0x0008
2684d3 #define TLCF_DATATYPE¤  ¤   ¤   0x0010
d96ecc #define TLCF_DATAMAX¤   ¤   ¤   0x0020
0c2092 #define TLCF_DATAVALUE¤ ¤   ¤   0x0040
56bc2e #define TLCF_MOUSENOTIFY¤   ¤   0x0080
e4af5a
0086d5 #define TLCFMT_LEFT ············0x0000
c62323 #define TLCFMT_RIGHT ···········0x0001
cdcc93 #define TLCFMT_CENTER ··········0x0002
5746fb #define TLCFMT_LINBAR¤  ¤   ¤   0x0004
33b846 #define TLCFMT_LOGBAR¤  ¤   ¤   0x0005
9157d2 #define TLCFMT_IMAGE¤   ¤   ¤   0x0006
2aaf5a
e5af5a
b5967e #define TLM_SETCOLUMNA ·········(TLM_FIRST + 26)
426321 #define TLM_SETCOLUMNW ·········(TLM_FIRST + 96)
b6d377 #ifdef UNICODE
107cd0 #define ·TLM_SETCOLUMN ·········TLM_SETCOLUMNW
72db21 #else
aebd91 #define ·TLM_SETCOLUMN ·········TLM_SETCOLUMNA
a57454 #endif
--b2e6 000fe68d6ad40110208 Page 6 of TreeList.h
e0af5a
b0de59 #define TreeList_SetColumn(hwnd, iCol, pcol) \
ac1fae ····(BOOL)SNDMSG((hwnd), TLM_SETCOLUMN, (WPARAM)(int)(iCol), \
3bb56a ¤   (LPARAM)(const TL_COLUMN FAR*)(pcol))
d9af5a
faaf5a
507dea #define TLM_INSERTCOLUMNA ······(TLM_FIRST + 27)
f3e355 #define TLM_INSERTCOLUMNW ······(TLM_FIRST + 97)
66d377 #ifdef UNICODE
ee9c45 # ··define ·TLM_INSERTCOLUMN ···TLM_INSERTCOLUMNW
f8db21 #else
a65d04 # ··define ·TLM_INSERTCOLUMN ···TLM_INSERTCOLUMNA
757454 #endif
a6af5a
4a5f54 #define TreeList_InsertColumn(hwnd, iCol, pcol) \
116ef8 ····(int)SNDMSG((hwnd), TLM_INSERTCOLUMN, (WPARAM)(int)(iCol), \
dfb56a ¤   (LPARAM)(const TL_COLUMN FAR*)(pcol))
7aaf5a
f76173 #define TLM_DELETEALLCOLUMNS¤   (TLM_FIRST + 25)
75f147 #define TreeList_DeleteAllColumns(hwnd) \
02cc75 ····(int)SNDMSG((hwnd), TLM_DELETEALLCOLUMNS, 0, 0)
a6af5a
97b29d #define TLM_ENSUREVISIBLE ······(TLM_FIRST + 28)
d6216c #define TreeList_EnsureVisible(hwnd, hitem) \
dba9c9 ····(BOOL)SNDMSG((hwnd), TLM_ENSUREVISIBLE, 0, (LPARAM)(HTLITEM)(hitem))
cdaf5a
3780a6 #define TLM_GETCOLUMNWIDTH ·····(TLM_FIRST + 29)
d234d5 #define TreeList_GetColumnWidth(hwnd, iCol) \
a40c84 ····(int)SNDMSG((hwnd), TLM_GETCOLUMNWIDTH, (WPARAM)(int)(iCol), 0)
03af5a
afb250 #define TLM_GETORDERARRAY ······(TLM_FIRST + 30)
f20772 #define TreeList_GetOrderArray(hwnd, isize, iarray) \
88a194 ····(BOOL)SNDMSG((hwnd), TLM_GETORDERARRAY, \
8739d2 ¤   (WPARAM)(int)(isize), (LPARAM)(HTLITEM)(iarray))
89af5a
9cbfd4 #define TLM_SETWHEELSCROLLLINES¤(TLM_FIRST + 31)
e775a6 #define TreeList_SetWheelScrollLines(hwnd, ilines) \
403272 ····(BOOL)SNDMSG((hwnd), TLM_SETWHEELSCROLLLINES, 0, (LPARAM)(ilines))
d0af5a
afaf5a
e1aeac typedef struct _NM_TREELIST {
89b98e ····NMHDR ······hdr;
d21648 ····UINT ·······flags;
0551fc ¤   UINT¤   ¤   index;
4234f2 ····TL_TREEITEMA ···itemOld;
deac24 ····TL_TREEITEMA ···itemNew;
ee9ee5 ····POINT ······ptDrag;
34e4ea } NM_TREELIST, FAR *LPNM_TREELIST;
1caf5a
ddf66e #define TLN_SELCHANGED ·········(TLN_FIRST-2)
e9af5a
37307b #define TLC_UNKNOWN ············0x0000
fbe19b #define TLC_BYMOUSE ············0x0001
4c9963 #define TLC_BYKEYBOARD ·········0x0002
f995bf #define TLC_MULTIPLE¤   ¤   ¤   0x0080
66af5a
7fd4ee #define TLN_HEADERCLICKED ······(TLN_FIRST-3)
a501bf #define TLN_LISTITEMCLICKED¤¤   (TLN_FIRST-4)
8f07d5 #define TLN_BEGINDRAG ··········(TLN_FIRST-7)
34f668 #define TLN_DROP ···············(TLN_FIRST-8)
8a5dc0 #define TLN_CONTEXTMENU¤¤   ¤   (TLN_FIRST-9)
8f954a #define TLN_KEYDOWN ············(TLN_FIRST-12)
4619ca #define TLN_CHAR ···············(TLN_FIRST-13)
fcc8bd #define TLN_DRAGGEDOVER¤¤   ¤   (TLN_FIRST-14)
6366d0 #define TLN_HEADERREORDERED¤¤   (TLN_FIRST-15)
b452bc #define TLN_AUTOSCROLLED¤   ¤   (TLN_FIRST-16)
99af5a
63af5a
c6b6d2 typedef struct _TL_KEYDOWN {
0f5417 ····NMHDR hdr;
7853ac ····WORD wVKey;
fef2e4 ····UINT flags;
--8b65 001172af2b740110208 Page 7 of TreeList.h
70ff37 } TL_KEYDOWN;
15af5a
44d5d1 typedef struct _TL_LISTITEMA
babb36 {
b7e526 ····UINT mask;
359306 ¤   UINT state;
64b810 ¤   UINT stateMask;
be6095 ····HTLITEM hItem;
381c12 ····int iSubItem;
c875e1 ····LPSTR pszText;
1fb7ac ····int cchTextMax;
25951b ····LONG lDataValue;
25e2ca } TL_LISTITEMA;
a3af5a
c11490 typedef struct _TL_LISTITEMW
5ebb36 {
50e526 ····UINT mask;
5b9306 ¤   UINT state;
24b810 ¤   UINT stateMask;
646095 ····HTLITEM hItem;
ce1c12 ····int iSubItem;
8623c8 ····LPWSTR pszText;
f8b7ac ····int cchTextMax;
5f951b ····LONG lDataValue;
54b186 } TL_LISTITEMW;
c1af5a
f3d377 #ifdef UNICODE
868203 #define TL_LISTITEM ···TL_LISTITEMW
04db21 #else
1e4342 #define TL_LISTITEM ···TL_LISTITEMA
eb7454 #endif
94af5a
c2b413 #define TLM_SETLISTITEMA ········(TLM_FIRST + 7)
cef855 #define TLM_SETLISTITEMW ········(TLM_FIRST + 77)
bfd377 #ifdef UNICODE
8bdd1b #define TLM_SETLISTITEM ·········TLM_SETLISTITEMW
54db21 #else
401c5a #define TLM_SETLISTITEM ·········TLM_SETLISTITEMA
257454 #endif
920909 #define TreeList_SetListItem(hwnd, pitem, binval) ··\
a5948c ¤   (int)SNDMSG((hwnd), TLM_SETLISTITEM, binval, \
32ceb1 ¤   (LPARAM)(const TL_LISTITEM FAR*)(pitem))
d3af5a
76af5a
eafac1 #define TLM_GETLISTITEMA ········(TLM_FIRST + 8)
f4f5ba #define TLM_GETLISTITEMW ········(TLM_FIRST + 78)
5ed377 #ifdef UNICODE
1ed657 #define TLM_GETLISTITEM ·········TLM_GETLISTITEMW
67db21 #else
411716 #define TLM_GETLISTITEM ·········TLM_GETLISTITEMA
4e7454 #endif
4a5279 #define TreeList_GetListItem(hwnd, pitem) ··\
09c1e9 ¤   (int)SNDMSG((hwnd), TLM_GETLISTITEM, 0, \
60ceb1 ¤   (LPARAM)(const TL_LISTITEM FAR*)(pitem))
23af5a
d5af5a
2eaf5a
087454 #endif
faaf5a
86af5a
d6af5a
c33379 #ifdef __cplusplus
67efe6 }
307454 #endif
d0af5a
b1ec08 #ifdef _WIN32
fb4ddb #include <poppack.h>
567454 #endif
4daf5a
5f5da4 #endif¤ ··//NOUSER
3baf5a
17f87a #endif¤ ··//_INC_TREELIST
--4912 00065a2b9cb40110209 Page 1 of pgpImage.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
a8d4ae ¤   pgpImage.h - header for PGP image index definitions
0467c5 ¤
29af5a
e207c6 ¤   $Id: pgpImage.h,v 1.13 1998/08/11 14:06:20 pbj Exp $
4ef7f7 ____________________________________________________________________________*/
c3f362 #ifndef Included_pgpImage_h¤/* [ */
1323cc #define Included_pgpImage_h
0eaf5a
46af5a
81870c // bitmap images index definitions
ebaf5a
c2fe28 #define IDX_NONE¤   ¤   ¤   -1
6ab206 #define IDX_INVALID¤¤   ¤   0
3cecfd #define IDX_PUSHED¤ ¤   ¤   1
054212 #define IDX_VALID¤  ¤   ¤   2
2487d4 #define IDX_VALIDPUSHED¤¤   3
9cc425 #define IDX_AXIOMATIC¤  ¤   4
94debe #define IDX_AXIOMATICPUSHED¤5
3348fb #define IDX_RSAPUBKEY¤  ¤   6
fc5d7f #define IDX_RSAPUBDISKEY¤   7
81b2e6 #define IDX_RSAPUBREVKEY¤   8
431287 #define IDX_RSAPUBEXPKEY¤   9
fa67b6 #define IDX_RSASECKEY¤  ¤   10
c6e68b #define IDX_RSASECDISKEY¤   11
6a8f83 #define IDX_RSASECREVKEY¤   12
abbea8 #define IDX_RSASECEXPKEY¤   13
a00a64 #define IDX_RSASECSHRKEY¤   14
5250ad #define IDX_DSAPUBKEY¤  ¤   15
bfe220 #define IDX_DSAPUBDISKEY¤   16
96b898 #define IDX_DSAPUBREVKEY¤   17
9c13a3 #define IDX_DSAPUBEXPKEY¤   18
35bf22 #define IDX_DSASECKEY¤  ¤   19
c01fbb #define IDX_DSASECDISKEY¤   20
314503 #define IDX_DSASECREVKEY¤   21
944798 #define IDX_DSASECEXPKEY¤   22
86a784 #define IDX_DSASECSHRKEY¤   23
f37c21 #define IDX_RSAUSERID¤  ¤   24
366a75 #define IDX_DSAUSERID¤  ¤   25
71121b #define IDX_INVALIDUSERID¤  26
04c4ac #define IDX_PHOTOUSERID¤¤   27
28738c #define IDX_CERT¤   ¤   ¤   28
8e8b27 #define IDX_REVCERT¤¤   ¤   29
04f08c #define IDX_EXPCERT¤¤   ¤   30
e5b062 #define IDX_BADCERT¤¤   ¤   31
caaf96 #define IDX_EXPORTCERT¤ ¤   32
36faf6 #define IDX_METACERT¤   ¤   33
b55a81 #define IDX_TRUSTEDCERT¤¤   34
cd88a8 #define IDX_GROUP¤  ¤   ¤   35
e26527 #define IDX_NOADK¤  ¤   ¤   36
c72031 #define¤IDX_NOADKPUSHED¤¤   37
a93f3c #define IDX_ADK¤¤   ¤   ¤   38
1c4e65 #define IDX_ADKPUSHED¤  ¤   39
6a0c65 #define IDX_OPENLOCK¤   ¤   40
d5b416 #define IDX_CLOSEDLOCK¤ ¤   41
30c69b #define IDX_HEAD¤   ¤   ¤   42
501484 #define NUM_BITMAPS¤¤   ¤   43
53af5a
199608 #endif /* ] Included_pgpImage_h */
35af5a
53af5a
ae7e4d /*__Editor_settings____
2caf5a
fc4126 ¤   Local Variables:
7d7b17 ¤   tab-width: 4
a20e6c ¤   End:
555f8c ¤   vi: ts=4 sw=4
6c9e9b ¤   vim: si
65d062 _____________________*/
--70a8 001e0d5e91e40110209 Page 2 of pgpImage.h
e0af5a
--d246 001c4aaeb424011020a Page 1 of pgpVersion.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
ff3cb4 ¤   PGPversion.h¤   - ¤ version and VERSIONINFO strings for PGP modules
0caf5a
01865f ¤   $Id: pgpVersion.h,v 1.69.2.27.2.1 1998/11/12 03:12:29 heller Exp $
6267c5 ¤
72f7f7 ____________________________________________________________________________*/
70af5a
8d39ac #define PGPVERSIONSTRING¤   "6.0.2"
9daf5a
c7f876 #define PGPVERSIONMAJOR¤¤   6
8ba090 #define PGPVERSIONMINOR¤¤   0
439e38 #define PGPVERSIONSUBMINOR¤ 2
233a61 #define PGPCOMPANYNAME¤ ¤   "Network Associates, Inc."
14fdd1 #define¤PGPCOPYRIGHT¤   ¤   "Copyright (C) 1998 Network Associates, Inc. " \
e2ada4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "All Rights Reserved."
10d1bf #define PGPTRADEMARKS¤  ¤   "Network Associates, Pretty Good Privacy, " \
d83b85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "PGP, PGPplugin"
c4830b #define PGPPRODUCTNAME¤ ¤   "PGP Desktop Security"
--508d 001afc2f6354011020b Page 1 of pgpWerr.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
5015c3 ¤   PGPWerr.h¤  - ¤ common Windows error return codes
acaf5a
e3e0db ¤   $Id: pgpWerr.h,v 1.8 1998/08/11 14:06:21 pbj Exp $
8067c5 ¤
6cf7f7 ____________________________________________________________________________*/
afeaea #ifndef Included_pgpWErr_h¤ /* [ */
5503c8 #define Included_pgpWErr_h
ebaf5a
acaf5a
c2e82c #include "pgpPubTypes.h"
3c628e #include "pgpClientErrors.h"
37af5a
cc4d95 enum PGPErrorWin32_
f2bb36 {
4b6611 ¤   kPGPError_Win32_FirstError = kPGPClientError_FirstError - 100,
2067c5 ¤
ba5c23 ¤   kPGPError_Win32_AlreadyOpen,¤   ¤   /* common dialog already open */
5fea0a ¤   kPGPError_Win32_NoSecretKeys,¤  ¤   /* no secret keys in keyring ·*/
6d3fcd ¤   kPGPError_Win32_Expired,¤   ¤   ¤   /* eval period expired ·······*/
f10da6 ¤   kPGPError_Win32_NegativeResponse,¤  /* user responded "No"¤ ¤   ··*/
2f89c6 ¤   kPGPError_Win32_NoSigningKey,¤  ¤   /* no signing key for search ·*/
74af5a
46865a ¤   kPGPError_Win32_InvalidImage,¤  ¤   /* corrupt or unsupported image */
fb1372 ¤   kPGPError_Win32_ImageTooBig,¤   ¤   /* image beyond limits ·········*/
cbaf5a
9de747 ¤   kPGPError_Win32_InvalidComctl32,¤   /* incorrect version of COMCTL32*/
08af5a
eed8cf ¤   kPGPError_Win32_Last
0d82f7 };
5faf5a
d0af5a
af5cf1 #endif /* ] Included_pgpWErr_h */

--59ce 00047e5ebf24011020c Page 1 of PGPclHlp.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
2a78bc ¤   PGPclHlp.h - help IDs for PGPcl
6067c5 ¤
21af5a
7d0511 ¤   $Id: PGPclHlp.h,v 1.14 1998/08/13 19:19:56 pbj Exp $
acf7f7 ____________________________________________________________________________*/
cdaf5a
592a12 /* base ID for PGPkm is 0000¤   */
62af5a
5cef50 #define IDH_PGPKM_DELETEKEY¤¤   ¤   ¤   ¤   130
2f47fc #define IDH_PGPKM_DELETEALLKEYS¤¤   ¤   ¤   131
de29ab #define IDH_PGPKM_DONTDELETEKEY¤¤   ¤   ¤   132
afe483 #define IDH_PGPKM_CANCELDELETE¤ ¤   ¤   ¤   133
a13ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
2f3eb9 #define IDH_PGPKM_NEWUSERID¤¤   ¤   ¤   ¤   141
e5822b #define IDH_PGPKM_NEWEMAILADDR¤ ¤   ¤   ¤   147
9ae117 #define IDH_PGPKM_NEWPHOTOID¤   ¤   ¤   ¤   148
efe262 #define IDH_PGPKM_BROWSENEWPHOTOID¤ ¤   ¤   149
943ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
90155f #define IDH_PGPKM_KEYID¤¤   ¤   ¤   ¤   ¤   160
4acb8c #define IDH_PGPKM_CREATEDATE¤   ¤   ¤   ¤   161
107a22 #define IDH_PGPKM_KEYTYPE¤  ¤   ¤   ¤   ¤   162
146d34 #define IDH_PGPKM_KEYEXPIRES¤   ¤   ¤   ¤   163
b291b2 #define IDH_PGPKM_VALIDITY¤ ¤   ¤   ¤   ¤   164
45d94f #define IDH_PGPKM_VALIDITYBAR¤  ¤   ¤   ¤   165
6458a1 #define IDH_PGPKM_TRUST¤¤   ¤   ¤   ¤   ¤   166
c90727 #define IDH_PGPKM_TRUSTSLIDER¤  ¤   ¤   ¤   167
373d2e #define IDH_PGPKM_FINGERPRINT¤  ¤   ¤   ¤   168
5cd5d6 #define IDH_PGPKM_ENABLED¤  ¤   ¤   ¤   ¤   169
cf0b7e #define IDH_PGPKM_CHANGEPHRASE¤ ¤   ¤   ¤   170
f2a88d #define IDH_PGPKM_AXIOMATIC¤¤   ¤   ¤   ¤   171
111c8e #define IDH_PGPKM_PROPDIALOG¤   ¤   ¤   ¤   172
7bdbf8 #define IDH_PGPKM_ADKAGENT¤ ¤   ¤   ¤   ¤   173
665d25 #define IDH_PGPKM_KEYSIZE¤  ¤   ¤   ¤   ¤   174
42c893 #define IDH_PGPKM_CIPHER¤   ¤   ¤   ¤   ¤   175
90c63a #define IDH_PGPKM_PHOTOID¤  ¤   ¤   ¤   ¤   176
d2987e #define IDH_PGPKM_JOINKEY¤  ¤   ¤   ¤   ¤   177
af3ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
92c84b #define IDH_PGPKM_SUBKEYLIST¤   ¤   ¤   ¤   180
45a1ce #define IDH_PGPKM_SUBKEYCREATE¤ ¤   ¤   ¤   181
0358dd #define IDH_PGPKM_SUBKEYREVOKE¤ ¤   ¤   ¤   182
28f862 #define IDH_PGPKM_SUBKEYREMOVE¤ ¤   ¤   ¤   183
a13ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
a951ad #define IDH_PGPKM_ADKLIST¤  ¤   ¤   ¤   ¤   190
403ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
51b52d #define IDH_PGPKM_REVOKERLIST¤  ¤   ¤   ¤   195
803ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
dad531 #define IDH_PGPKM_SIGNDIALOG¤   ¤   ¤   ¤   200
4c52b0 #define IDH_PGPKM_MORESIGCHOICES¤   ¤   ¤   201
68b96a #define IDH_PGPKM_FEWERSIGCHOICES¤  ¤   ¤   202
25770b #define IDH_PGPKM_SIGNUSERIDLIST¤   ¤   ¤   203
f21802 #define IDH_PGPKM_ALLOWSIGEXPORT¤   ¤   ¤   204
fd3f46 #define IDH_PGPKM_SIGNONEXPORTABLE¤ ¤   ¤   205
b8b8c4 #define IDH_PGPKM_SIGEXPORTABLE¤¤   ¤   ¤   206
4e34bf #define IDH_PGPKM_SIGTRUSTED¤   ¤   ¤   ¤   207
cd7642 #define IDH_PGPKM_SIGMETA¤  ¤   ¤   ¤   ¤   208
8a0035 #define IDH_PGPKM_DOMAINRESTRICTION¤¤   ¤   209
425f25 #define IDH_PGPKM_SIGNEVEREXPIRES¤  ¤   ¤   210
559f03 #define IDH_PGPKM_SIGEXPIRES¤   ¤   ¤   ¤   211
6c26a6 #define IDH_PGPKM_SIGEXPIRATIONDATE¤¤   ¤   212
6caf5a
c06b20 #define IDH_PGPKM_REVOKECERTDIALOG¤ ¤   ¤   220
c93ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
a267b4 #define¤IDH_PGPKM_IMPORT¤   ¤   ¤   ¤   ¤   261
f16cd0 #define¤IDH_PGPKM_IMPORTSELALL¤ ¤   ¤   ¤   262
3bb411 #define¤IDH_PGPKM_IMPORTUNSELALL¤   ¤   ¤   263
0e18d2 #define¤IDH_PGPKM_IMPORTLIST¤   ¤   ¤   ¤   264
9c3ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
47de00 #define IDH_PGPKM_NEWSUBKEYSIZE¤¤   ¤   ¤   281
--c842 0007acbc7244011020c Page 2 of PGPclHlp.h
d97247 #define IDH_PGPKM_NEWSUBKEYSTARTDATE¤   ¤   282
39aca7 #define IDH_PGPKM_NEWSUBKEYNEVEREXPIRES ¤   283
4ba25a #define IDH_PGPKM_NEWSUBKEYEXPIREDATE¤  ¤   284
6d0562 #define IDH_PGPKM_NEWSUBKEYEXPIRES¤ ¤   ¤   285
2faf5a
92b2cb #define¤IDH_PGPKM_SELECT¤   ¤   ¤   ¤   ¤   301
86b9af #define¤IDH_PGPKM_SELECTSELALL¤ ¤   ¤   ¤   302
a9616e #define¤IDH_PGPKM_SELECTUNSELALL¤   ¤   ¤   303
dccdad #define¤IDH_PGPKM_SELECTLIST¤   ¤   ¤   ¤   304
6eaf5a
974bde #define IDH_PGPKM_EXPORTPRIVATEKEYS¤¤   ¤   321
e18e5c #define IDH_PGPKM_INCLUDEEXTENSIONS¤¤   ¤   322
16ed43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
c6af5a
e771eb /* base ID for PGPcl is 1000¤   */
e9af5a
48088b #define IDH_PGPCLCHECK_CHECKDIALOG¤ ¤   ¤   1000
9faf5a
c3e55b #define IDH_PGPCLPREF_ENCRYPTDIALOG¤¤   ¤   1100
9f5f97 #define IDH_PGPCLPREF_ENCRYPTTOSELF¤¤   ¤   1101
965c09 #define IDH_PGPCLPREF_PASSCACHEENABLE¤  ¤   1303
aca27e #define IDH_PGPCLPREF_PASSCACHETIME¤¤   ¤   1103
1dee97 #define IDH_PGPCLPREF_SIGNCACHEENABLE¤  ¤   1102
f0649e #define IDH_PGPCLPREF_SIGNCACHETIME¤¤   ¤   1105
05db08 #define IDH_PGPCLPREF_COMMENTBLOCK¤ ¤   ¤   1111
b8d8ef #define IDH_PGPCLPREF_USEFASTKEYGEN¤¤   ¤   1110
ffc392 #define IDH_PGPCLPREF_WIPECONFIRM¤  ¤   ¤   1112
bfe600 #define IDH_PGPCLPREF_NUMWIPEPASSES¤¤   ¤   1114
b2e2e0 #define IDH_PGPCLPREF_NUMWIPEPASSESSPIN¤¤   1115
8b3ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
0cca89 #define IDH_PGPCLPREF_FILEDIALOG¤   ¤   ¤   1200
211255 #define IDH_PGPCLPREF_PRIVATEKEYRING¤   ¤   1201
a444fc #define IDH_PGPCLPREF_BROWSEPRIVATEKEYRING¤ 1202
bffda5 #define IDH_PGPCLPREF_PUBLICKEYRING¤¤   ¤   1203
e3229f #define IDH_PGPCLPREF_BROWSEPUBLICKEYRING¤  1204
feab29 #define IDH_PGPCLPREF_RANDOMSEEDFILE¤   ¤   1205
59121d #define IDH_PGPCLPREF_BROWSERANDOMSEEDFILE¤ 1206
4c3ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
e84c58 #define IDH_PGPCLPREF_EMAILDIALOG¤  ¤   ¤   1300
a752ff #define IDH_PGPCLPREF_USEPGPMIME¤   ¤   ¤   1301
d89ec4 #define IDH_PGPCLPREF_ENCRYPTBYDEFAULT¤ ¤   1307
f4d307 #define IDH_PGPCLPREF_SIGNBYDEFAULT¤¤   ¤   1308
debd60 #define IDH_PGPCLPREF_AUTODECRYPT¤  ¤   ¤   1113
75fccb #define IDH_PGPCLPREF_WORDWRAPENABLE¤   ¤   1305
ecba36 #define IDH_PGPCLPREF_WORDWRAPCOLUMN¤   ¤   1306
633ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
62c44b #define IDH_PGPCLPREF_KEYSERVERDIALOG¤  ¤   1400
13ae85 #define IDH_PGPCLPREF_SERVERLIST¤   ¤   ¤   1401
c051fe #define IDH_PGPCLPREF_CREATESERVER¤ ¤   ¤   1402
73f035 #define IDH_PGPCLPREF_REMOVESERVER¤ ¤   ¤   1403
c5d1b6 #define IDH_PGPCLPREF_EDITSERVER¤   ¤   ¤   1409
4dd90d #define IDH_PGPCLPREF_SETROOTSERVER¤¤   ¤   1410
9e94c8 #define IDH_PGPCLPREF_SYNCONUNKNOWNKEYS¤¤   1405
6619d5 #define IDH_PGPCLPREF_SYNCONADDNAME¤¤   ¤   1406
d00050 #define IDH_PGPCLPREF_SYNCONSIGN¤   ¤   ¤   1407
73e548 #define IDH_PGPCLPREF_SYNCONREVOKE¤ ¤   ¤   1408
3be32f #define IDH_PGPCLPREF_SYNCONVERIFY¤ ¤   ¤   1411
0baf5a
6904db #define IDH_PGPCLPREF_SERVERNAME¤   ¤   ¤   1421
e1cfe5 #define IDH_PGPCLPREF_SERVERPROTOCOL¤   ¤   1424
eb3cf0 #define IDH_PGPCLPREF_SERVERPORT¤   ¤   ¤   1425
1fc9e1 #define IDH_PGPCLPREF_SERVERAUTHKEY¤¤   ¤   1426
ce1819 #define IDH_PGPCLPREF_SERVERNODOMAIN¤   ¤   1427
a3ef98 #define IDH_PGPCLPREF_SERVERDOMAIN¤ ¤   ¤   1428
245211 #define IDH_PGPCLPREF_SERVERLISTED¤ ¤   ¤   1429
67af5a
90584c #define IDH_PGPCLPREF_ADVANCEDDIALOG¤   ¤   1500
a51e2b #define IDH_PGPCLPREF_PREFERREDALG¤ ¤   ¤   1504
2d75d8 #define IDH_PGPCLPREF_ENABLECAST¤   ¤   ¤   1501
b2105e #define IDH_PGPCLPREF_ENABLE3DES¤   ¤   ¤   1502
27dbb7 #define IDH_PGPCLPREF_ENABLEIDEA¤   ¤   ¤   1503
7ac5f1 #define IDH_PGPCLPREF_DISPMARGVALIDITY¤ ¤   1505
--1b83 001acc5172f4011020c Page 3 of PGPclHlp.h
730abf #define IDH_PGPCLPREF_WARNONMARGINAL¤   ¤   1104
7910be #define IDH_PGPCLPREF_WARNONADK¤¤   ¤   ¤   1506
689136 #define IDH_PGPCLPREF_EXPORTCOMPATIBLE¤ ¤   1507
280329 #define IDH_PGPCLPREF_EXPORTCOMPLETE¤   ¤   1508
3aaf5a
276c32 #define IDH_PGPCLSPLIT_SPLITDIALOG¤ ¤   ¤   1600
e0ee4f #define IDH_PGPCLSPLIT_NEWSHAREHOLDER¤  ¤   1601
efd53a #define IDH_PGPCLSPLIT_KEYTOSPLIT¤  ¤   ¤   1602·
eec5d1 #define IDH_PGPCLSPLIT_SHAREHOLDERS¤¤   ¤   1603
a6ee2e #define IDH_PGPCLSPLIT_SELECTEDSHAREHOLDER¤ 1604·
284bb7 #define IDH_PGPCLSPLIT_SELECTEDSHARES¤  ¤   1605
1d8bc6 #define IDH_PGPCLSPLIT_REMOVESHARES¤¤   ¤   1606
a9e6b9 #define IDH_PGPCLSPLIT_ADDSHARES¤   ¤   ¤   1607
b42128 #define IDH_PGPCLSPLIT_TOTALSHARES¤ ¤   ¤   1608
c1bc54 #define IDH_PGPCLSPLIT_THRESHOLD¤   ¤   ¤   1609
0d7a66 #define IDH_PGPCLSPLIT_SPLIT¤   ¤   ¤   ¤   1610
60af5a
cbd72a #define IDH_PGPCLRECON_KEYTORECON¤  ¤   ¤   1631
53f388 #define IDH_PGPCLRECON_SHAREHOLDERLIST¤ ¤   1632
504756 #define IDH_PGPCLRECON_SHARESCOLLECTED¤ ¤   1633
2e8fe2 #define IDH_PGPCLRECON_SHARESNEEDED¤¤   ¤   1634
88f9fd #define IDH_PGPCLRECON_STARTNETWORK¤¤   ¤   1635
b77e13 #define IDH_PGPCLRECON_NETWORKSTATUS¤   ¤   1636
93279c #define IDH_PGPCLRECON_NETWORKAUTHENTICATION¤   1637
986372 #define IDH_PGPCLRECON_SELECTSHAREFILE¤ ¤   1638
6f2927 #define IDH_PGPCLRECON_STOPNETWORK¤ ¤   ¤   1639
7baf5a
d0d279 #define IDH_PGPCLSEND_SHAREFILE¤¤   ¤   ¤   1661
80e3fe #define IDH_PGPCLSEND_NUMSHARESINFILE¤  ¤   1662
991f06 #define IDH_PGPCLSEND_REMOTECOMPUTER¤   ¤   1663
93eeff #define IDH_PGPCLSEND_NETWORKSTATUS¤¤   ¤   1664
a94b1c #define IDH_PGPCLSEND_NETWORKAUTHENTICATION¤1665
62b997 #define IDH_PGPCLSEND_SENDSHARES¤   ¤   ¤   1666
a29f4d #define IDH_PGPCLSEND_DONE¤ ¤   ¤   ¤   ¤   1667
d2af5a
9a1ff9 #define IDH_PGPCLMISC_AUTHSERVERNAME¤   ¤   1901
a8f77e #define IDH_PGPCLMISC_AUTHKEYNAME¤  ¤   ¤   1902
ad41d6 #define IDH_PGPCLMISC_AUTHKEYFINGERPRINT¤   1903
2ee6b9 #define IDH_PGPCLMISC_AUTHKEYVALIDITY¤  ¤   1904
9f270b #define IDH_PGPCLMISC_AUTHIMPORTKEY¤¤   ¤   1905
ac2f06 #define IDH_PGPCLMISC_AUTHCONFIRM¤  ¤   ¤   1906
--f771 001565cffa44011020d Page 1 of PGPpkHlp.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
fd4310 ¤   PGPpkHlp.h - help IDs for PGPkeys
bd67c5 ¤
33af5a
ac10d9 ¤   $Id: PGPpkHlp.h,v 1.9 1998/08/11 14:06:23 pbj Exp $
37f7f7 ____________________________________________________________________________*/
9eaf5a
fab25e /* base ID for PGPkeys is 2000¤ */
05af5a
09af5a
91f448 #define IDH_PGPPK_WIZ_ABOUT¤¤   ¤   2000
2c0963 #define IDH_PGPPK_WIZ_NAME¤ ¤   ¤   2001
9e1ae7 #define IDH_PGPPK_WIZ_TYPE¤ ¤   ¤   2002
fab51a #define IDH_PGPPK_WIZ_SIZE¤ ¤   ¤   2003
bbbc07 #define IDH_PGPPK_WIZ_EXPIRATION¤   2004
f73763 #define IDH_PGPPK_WIZ_ADK¤  ¤   ¤   2005
cace35 #define IDH_PGPPK_WIZ_CORPKEY¤  ¤   2006
c79847 #define IDH_PGPPK_WIZ_PASSPHRASE¤   2007
b72877 #define IDH_PGPPK_WIZ_BADPHRASE¤¤   2008
7d69f8 #define IDH_PGPPK_WIZ_RANDOBITS¤¤   2009
4335ad #define IDH_PGPPK_WIZ_GENERATION¤   2010
efefc4 #define IDH_PGPPK_WIZ_SIGNOLD¤  ¤   2011
ba3b4c #define IDH_PGPPK_WIZ_PRESEND¤  ¤   2012
c02deb #define IDH_PGPPK_WIZ_SEND¤ ¤   ¤   2013
ed74a6 #define IDH_PGPPK_WIZ_DONE¤ ¤   ¤   2014
b06340 #define IDH_PGPPK_WIZ_REVOKERKEY¤   2015
89af5a
24d96d #define IDH_PGPPK_SEARCH_DIALOG¤¤   2100
ebaf5a
6a487a #define IDH_PGPPKGRP_GROUPNAME¤ ¤   2601
ff3d16 #define IDH_PGPPKGRP_GROUPDESC¤ ¤   2602
34af5a
d6e6a1 #define IDH_PGPPKGRP_DELETEONE¤ ¤   2701
cca924 #define IDH_PGPPKGRP_DELETEALL¤ ¤   2702
82355d #define IDH_PGPPKGRP_DELETENO¤  ¤   2703
f43796 #define IDH_PGPPKGRP_DELETECANCEL¤  2704
73af5a
72015d #define IDH_PGPPKSEARCH_SEARCH¤ ¤   2801
45a284 #define IDH_PGPPKSEARCH_STOP¤   ¤   2802
6ed731 #define IDH_PGPPKSEARCH_CLEAR¤  ¤   2803
0f4267 #define IDH_PGPPKSEARCH_LOCATION¤   2804
18ce44 #define IDH_PGPPKSEARCH_ATTRIBUTE¤  2805
ec0249 #define IDH_PGPPKSEARCH_VERB¤   ¤   2806
fb9967 #define IDH_PGPPKSEARCH_MORE¤   ¤   2811
e1dbdb #define IDH_PGPPKSEARCH_FEWER¤  ¤   2812
56519d #define IDH_PGPPKSEARCH_PENDING¤¤   2813
--a2b1 0014990039e4011020e Page 1 of RDhelp.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
8767c5 ¤
90af5a
ea11db ¤   $Id: RDhelp.h,v 1.2 1998/08/11 14:06:24 pbj Exp $
01f7f7 ____________________________________________________________________________*/
e62d37 #ifndef Included_RDHELP_h¤  /* [ */
da6221 #define Included_RDHELP_h
eaaf5a
0b2353 /*: PGPRcptDlgHelp.h - defines constants for help file */
5ef9ef // Rec Dlg has help IDs ranging from 3000-3999
70af5a
ab88ce #define IDH_IDD_RECIPIENTDLG ··············3000
e0ad6c #define IDH_RSADSARECWARNING ··············3009
b9af5a
14c2db #define IDH_IDOK ··························3008
90405e #define IDH_IDCANCEL ······················3001
69af5a
4d2531 #define IDH_IDC_RECIPIENT_LIST ············3006
9eb614 #define IDH_IDC_USER_ID_LIST ··············3007
87af5a
aa9c2e #define IDH_IDC_PASSONLY ··················3012
c56631 #define IDH_IDC_CHECK_ASCII ···············3002
110ea6 #define IDH_IDC_WIPEORIG ··················3013
13af5a
3666ad #endif /* ] Included_RDHELP_h */
f2af5a
0daf5a
2a7e4d /*__Editor_settings____
36af5a
724126 ¤   Local Variables:
147b17 ¤   tab-width: 4
170e6c ¤   End:
6f5f8c ¤   vi: ts=4 sw=4
fc9e9b ¤   vim: si
49d062 _____________________*/

--901c 00018d582174011020f Page 1 of build.bat
14a50f @ECHO OFF
0caf5a
e2631f ECHO.
09071e ECHO Let's Setup Some Important Paths
4e631f ECHO.
5faf5a
0d4920 SET Installshield_Path=c:\ishield
9196f6 SET INSTRC=%Installshield_Path%\Dialogs\Include·
ca2a91 SET Installshield_Program_Path=%Installshield_Path%\Program
f205f7 SET COMPILE=%Installshield_Program_Path%\compile.exe
e6f624 SET ICOMP=%Installshield_Program_Path%\icomp.exe ·······
8e139c SET PACK=%Installshield_Program_Path%\packlist.exe
b3e030 SET SPLIT=%Installshield_Program_Path%\split.exe
95af5a
5f631f ECHO.
d7b5c5 ECHO Make sure there aren't any read-only files
41c88d attrib -r setup\*.*
843719 attrib -r disk1\*.*
68af5a
b1c356 copy %Installshield_Path%\_isres.dll tempstuff\
40e1ee copy %Installshield_Path%\isdbgn.dll setup\
33adb3 copy %Installshield_Path%\compile.exe setup\
3ea5ff copy %Installshield_Path%\packlist.exe setup\
e803e6 copy %Installshield_Path%\_inst32i.ex_ Disk1\
84216a copy %Installshield_Path%\_isdel.exe Disk1\
240461 copy %Installshield_Path%\_setup.dll Disk1\
969a32 copy %Installshield_Path%\setup.exe Disk1\
df3981 copy %Installshield_Path%\uninst.exe Disk1\
96af5a
055e2b del data\data.*
b1af5a
f537d4 if EXIST disk2 rmdir /S /Q disk2
51f15a if EXIST disk3 rmdir /S /Q disk3
e7b0d2 if EXIST disk4 rmdir /S /Q disk4
7a765c if EXIST disk5 rmdir /S /Q disk5
0d35df if EXIST disk6 rmdir /S /Q disk6
dff351 if EXIST disk7 rmdir /S /Q disk7
08b6cf if EXIST disk8 rmdir /S /Q disk8
017041 if EXIST disk9 rmdir /S /Q disk9
7e0b2d if EXIST disk10 rmdir /S /Q disk10
5d2599 if EXIST disk11 rmdir /S /Q disk11
c65645 if EXIST disk12 rmdir /S /Q disk12
9878f1 if EXIST disk13 rmdir /S /Q disk13
a1b1fd if EXIST disk14 rmdir /S /Q disk14
0a9f49 if EXIST disk15 rmdir /S /Q disk15
d6af5a
bc74ef ECHO Compile The Setup Script
1fa346 %COMPILE% setup\setup.rul -g
f880ef pause
f3af5a
d6af5a
18af5a
b1631f ECHO.
6f7f53 ECHO Copy Output to Disk1
a89261 copy setup\setup.ins disk1
b38337 REM copy setup\setup.dbg disk1
c5af5a
6a631f ECHO.
f0fc2c ECHO Make Sure that Old Data is Destroyed
0ed675 if exist data\data.z del data\data.z
5faf5a
d7631f ECHO.
996d72 ECHO Compile the Data in the Data Directory
087c40 %ICOMP% -i data\*.* data\data.z
59af5a
b14e41 cd Data
c96351 %SPLIT% data.z -f1420 -d1@100
e3af5a
e1631f ECHO.
77b9ac ECHO ·Copy Output to Disks
d5af5a
1875da copy data.1 ..\disk1
--ea84 00063aef6334011020f Page 2 of build.bat
638d04 echo. > ..\disk1\disk1.id
95af5a
6ad235 if NOT EXIST data.2 goto copiedallsegments
c870d3 mkdir ..\disk2
e56e7b echo. > ..\disk2\disk2.id
c7a101 copy data.2 ..\disk2
dfaf5a
c9d64e if NOT EXIST data.3 goto copiedallsegments
ef690b mkdir ..\disk3
3730ae echo. > ..\disk3\disk3.id
bbed48 copy data.3 ..\disk3
a4af5a
a4cb2f if NOT EXIST data.4 goto copiedallsegments
f92403 mkdir ..\disk4
dea094 echo. > ..\disk4\disk4.id
2d00a6 copy data.4 ..\disk4
1daf5a
14cf54 if NOT EXIST data.5 goto copiedallsegments
723ddb mkdir ..\disk5
8bfe41 echo. > ..\disk5\disk5.id
a44cef copy data.5 ..\disk5
f4af5a
0dc3d9 if NOT EXIST data.6 goto copiedallsegments
2317b3 mkdir ..\disk6
791d3e echo. > ..\disk6\disk6.id
529834 copy data.6 ..\disk6
5caf5a
fec7a2 if NOT EXIST data.7 goto copiedallsegments
230e6b mkdir ..\disk7
1943eb echo. > ..\disk7\disk7.id
bad47d copy data.7 ..\disk7
98af5a
c7f91b if NOT EXIST data.8 goto copiedallsegments
958da3 mkdir ..\disk8
b3355b echo. > ..\disk8\disk8.id
264bf9 copy data.8 ..\disk8
fcaf5a
a3fd60 if NOT EXIST data.9 goto copiedallsegments
9a947b mkdir ..\disk9
f76b8e echo. > ..\disk9\disk9.id
d807b0 copy data.9 ..\disk9
35af5a
e96b98 if NOT EXIST data.10 goto copiedallsegments
abef8a mkdir ..\disk10
7db1a8 echo. > ..\disk10\disk10.id
667bbd copy data.10 ..\disk10
3caf5a
fe6fe3 if NOT EXIST data.11 goto copiedallsegments
57f652 mkdir ..\disk11
883fb9 echo. > ..\disk11\disk11.id
41e730 copy data.11 ..\disk11
50af5a
be636e if NOT EXIST data.12 goto copiedallsegments
d3dc3a mkdir ..\disk12
5ca59b echo. > ..\disk12\disk12.id
b54ab6 copy data.12 ..\disk12
e5af5a
236715 if NOT EXIST data.13 goto copiedallsegments
aec5e2 mkdir ..\disk13
072b8a echo. > ..\disk13\disk13.id
40d63b copy data.13 ..\disk13
7aaf5a
837a74 if NOT EXIST data.14 goto copiedallsegments
3788ea mkdir ..\disk14
3199ce echo. > ..\disk14\disk14.id
2c19ab copy data.14 ..\disk14
c9af5a
e17e0f if NOT EXIST data.15 goto copiedallsegments
ba9132 mkdir ..\disk15
5517df echo. > ..\disk15\disk15.id
a88526 copy data.15 ..\disk15
63af5a
--5c00 00199c625764011020f Page 3 of build.bat
69771b :copiedallsegments
59af5a
bc631f ECHO.
fe680a ECHO Create the PackList
0fcfdc cd ..\setup
66b620 %PACK% setup.lst
f9af5a
ac631f ECHO.
c07f53 ECHO Copy Output to Disk1
4a255b copy setup.pkg ..\disk1
cb333f del setup.pkg
44af5a
3d631f ECHO.
7185bd ECHO Make Sure that Old Lib is Destroyed
eb611c del ..\tempstuff\_setup.lib
23af5a
73631f ECHO.
598d65 cd ..
67e31d copy Disk1\license.txt tempstuff
dc03d7 copy Data\Docs\readme.txt tempstuff
150aa9 ECHO Create the Temporary Stuff
09bebd %ICOMP% -i tempstuff\*.* tempstuff\_setup.lib
ecaf5a
1f631f ECHO.
d67f53 ECHO Copy Output to Disk1
438811 copy tempstuff\_setup.lib disk1
5baf5a
4baf5a
7d631f ECHO.
578c7e ECHO Clean up after MeSelf
9b75c5 SET Installshield_Path=
2fb79f SET ·Installshield_Program_Path=
646414 SET COMPILE=
ec8bc7 SET ICOMP=
9517c2 SET PACK=
c6af5a
b789cc ECHO Build.bat Completed
05631f ECHO.
b5631f ECHO.
abaf5a
994302 @ECHO ON
--b467 00052b1983a40110210 Page 1 of setupinstall.bat
aaad7e @echo off
aeaf5a
24445f set INSTALLPGPDISK=
de15c3 set ISADMIN=
30ca37 set RELEASEDIR=..\PGP55\Release
ac158b set LIBSDIR=..\..\..\..\libs
404352 set SECUREMEMORYDIR=%LIBSDIR%\pfl\win32\SecureMemory
c24c4b set PGPDISKDIR=..\..\..\..\clients\disk\win32
afaf5a
643477 REM Delete existing DATA directory and create common hierarchy
31af5a
ffd60e if EXIST DATA rmdir /Q /S Data
a67c1d mkdir DATA
80aa75 mkdir DATA\DOCS
edaf5a
02e1dc REM Check arguments
3b935e if "%1" == "DSADMIN" goto dsadmin
598442 if "%1" == "DSCLIENT" goto dsclient
e3d8bd if "%1" == "PERSONAL" goto personal
aa8f49 if "%1" == "FREEWARE" goto freeware
42dcfb goto badargs
1caf5a
9e447e :dsadmin
1171f7 set INSTALLPGPDISK=YES
699702 set ISADMIN=YES
dccb84 copy docs\DSReadMe.txt DATA\DOCS\ReadMe.txt
31a015 copy licenses\license.txt Disk1\License.txt
0a9925 copy keyrings\DSpubring.pkr tempstuff\pubring.pkr
23671e copy bmps\business\sidebar.bmp tempstuff\
73b51b copy bmps\business\sidebarx.bmp tempstuff\
806ca8 copy bmps\business\setup.bmp Disk1\
ea0398 goto goodargs
1eaf5a
f4f3f4 :dsclient
c871f7 set INSTALLPGPDISK=YES
76cb84 copy docs\DSReadMe.txt DATA\DOCS\ReadMe.txt
29a015 copy licenses\license.txt Disk1\License.txt
f59925 copy keyrings\DSpubring.pkr tempstuff\pubring.pkr
8c671e copy bmps\business\sidebar.bmp tempstuff\
7fb51b copy bmps\business\sidebarx.bmp tempstuff\
496ca8 copy bmps\business\setup.bmp Disk1\
c70398 goto goodargs
a2af5a
e2ca72 :personal
1e71f7 set INSTALLPGPDISK=YES
2371c1 copy docs\PPReadMe.txt DATA\DOCS\ReadMe.txt
551221 copy licenses\reglic.txt Disk1\License.txt
1fbb2a copy keyrings\PPpubring.pkr tempstuff\pubring.pkr
23d041 copy bmps\personal\sidebar.bmp tempstuff\
201fde copy bmps\personal\sidebarx.bmp tempstuff\
96b0e7 copy bmps\personal\setup.bmp Disk1\
ba0398 goto goodargs
c8af5a
809f64 :freeware
078b13 copy docs\FreewareReadMe.txt DATA\DOCS\ReadMe.txt
5a6ee8 copy licenses\freelic.txt Disk1\License.txt
09bb2a copy keyrings\PPpubring.pkr tempstuff\pubring.pkr
f9f476 copy bmps\freeware\sidebar.bmp tempstuff\
0f5ac6 copy bmps\freeware\sidebarx.bmp tempstuff\
5449dc copy bmps\freeware\setup.bmp Disk1\
7d0398 goto goodargs
c3af5a
f9ca9d :goodargs
bdaf5a
e012a8 copy %LIBSDIR%\pfl\win32\InstallDLL\Release\Install.dll tempstuff\
909fef copy Extras\adobe.url tempstuff\
dc5c57 copy Extras\eudora.url tempstuff\
b9af5a
4d6051 mkdir DATA\WINSYSDIR
fa76ad copy %RELEASEDIR%\pgp60cl.dll DATA\WINSYSDIR
fe9535 copy %RELEASEDIR%\pgp60mn.dll DATA\WINSYSDIR
5284a2 copy %RELEASEDIR%\pgp60sc.dll DATA\WINSYSDIR
--db6f 00065fb159c40110210 Page 2 of setupinstall.bat
9463e2 copy %RELEASEDIR%\pgp60hk.dll DATA\WINSYSDIR
d4af5a
daa741 mkdir DATA\SDKWINSYS
fd480b copy %RELEASEDIR%\pgp_sdk.dll DATA\SDKWINSYS
d40636 copy %RELEASEDIR%\pgpsdkNL.dll DATA\SDKWINSYS
b4b8db copy %RELEASEDIR%\pgpsdkUI.dll DATA\SDKWINSYS
8faf5a
3512a8 mkdir DATA\PGP60
b3953b copy %RELEASEDIR%\PGPkeys.exe DATA\PGP60
f76fec copy %RELEASEDIR%\PGPlog.exe DATA\PGP60
ec7d7a copy %RELEASEDIR%\PGPtools.exe DATA\PGP60
21fbb3 copy %RELEASEDIR%\PGPtray.exe DATA\PGP60
aa4219 copy Extras\40ComUpd.exe DATA\PGP60
beb6c4 copy docs\PGP60.cnt DATA\PGP60
bad4a8 copy docs\PGP60.hlp DATA\PGP60
5caf5a
f98df8 mkdir "DATA\PGP60\Sample Keys"
04acf2 copy keyrings\SampleKeys.asc "DATA\PGP60\Sample Keys"
eb3873 copy keyrings\WhatIsThis.txt "DATA\PGP60\Sample Keys"
d8af5a
dd2371 mkdir DATA\OEWINSYS
7bc994 copy %RELEASEDIR%\PGP60oe.dll DATA\OEWINSYS
76af5a
731273 mkdir DATA\OEPLUGIN
1d2496 copy %RELEASEDIR%\msimn.exe DATA\OEPLUGIN
a2af5a
0f7368 mkdir DATA\NTMEMLOC
1725aa copy %SECUREMEMORYDIR%\winNT\sys\i386\free\PGPmemlock.sys DATA\NTMEMLOC
faaf5a
7726fa mkdir DATA\95MEMLOC
8201bb copy %SECUREMEMORYDIR%\win95\Release\PGPmemlock.vxd DATA\95MEMLOC
4eaf5a
7ba415 mkdir DATA\MANUAL
083028 copy docs\PGPWinUsersGuide.pdf DATA\MANUAL
1aaf5a
138e6d mkdir DATA\EXCHANGE
d45f36 copy %RELEASEDIR%\pgpExch.dll DATA\EXCHANGE
eaaf5a
28a1cb mkdir DATA\EUDORA
a0139d mkdir DATA\EUDORA\REGULAR
698241 mkdir DATA\EUDORA\FOURDOTO
34e2be copy %RELEASEDIR%\pgpEudoraPlugin.dll DATA\EUDORA\REGULAR\pgpplugin.dll
ee7578 copy %RELEASEDIR%\pgpEudoraPluginV4.dll DATA\EUDORA\FOURDOTO\pgpplugin.dll
9aaf5a
87c81b REM DATA\DOCS created above
93dbcb copy docs\IntroToCrypto.pdf DATA\DOCS
f89302 copy docs\PGPInstallGuide.pdf DATA\DOCS
dc062a copy Extras\WhatsNew.doc DATA\DOCS
a9af5a
dfdc6b if NOT EXIST Uninstaller\tempstuff mkdir Uninstaller\tempstuff
f6af5a
3969a2 REM Remove existing PGPdisk items
51af5a
1a986a if EXIST Uninstaller\tempstuff\PGPdskIH.dll del Uninstaller\tempstuff\PGPdskIH.¶
602849 dll
e32291 if EXIST tempstuff\PGPdskIH.dll del tempstuff\PGPdskIH.dll
95af5a
6c9375 if NOT DEFINED INSTALLPGPDISK goto checkadmin
90af5a
a67589 copy %PGPDISKDIR%\PGPdiskInstallHelper\Release\PGPdskIH.dll Uninstaller\tempstu¶
2e4d4b ff
c3673c copy %PGPDISKDIR%\PGPdiskInstallHelper\Release\PGPdskIH.dll tempstuff\
6eaf5a
39e098 mkdir DATA\PGPDISK
8daf5a
8f2b19 mkdir DATA\PGPDISK\SHELL
0c9144 copy %PGPDISKDIR%\PGPdiskShellExt\Release\PGPdskSE.dll DATA\PGPDISK\SHELL
60af5a
3ef9a3 mkdir DATA\PGPDISK\PROG
fe03f6 copy %PGPDISKDIR%\PGPdiskApp\Release\PGPdisk.exe DATA\PGPDISK\PROG
e76c77 copy %PGPDISKDIR%\PGPdiskResident\Release\PGPdiskResident.exe DATA\PGPDISK\PROG
65a4ec copy docs\PGPdisk.cnt DATA\PGPDISK\PROG
--329d 0014b2cf2c940110210 Page 3 of setupinstall.bat
c83e14 copy docs\PGPdisk.hlp DATA\PGPDISK\PROG
03af5a
16c28f mkdir DATA\PGPDISK\MFC
e62f52 copy Extras\MFC42.dll DATA\PGPDISK\MFC
67e012 copy Extras\msvcrt.dll DATA\PGPDISK\MFC
1aaf5a
f2652b mkdir DATA\PGPDISK\DRIVERS
12af5a
87a25c mkdir DATA\PGPDISK\DRIVERS\NT
870bc4 copy %PGPDISKDIR%\PGPdiskDrvNT\i386\free\PGPdisk.sys DATA\PGPDISK\DRIVERS\NT
9faf5a
56d20c mkdir DATA\PGPDISK\DRIVERS\95
848f77 copy %PGPDISKDIR%\PGPdiskDrvWin95\Release\PGPdisk.pdr DATA\PGPDISK\DRIVERS\95
95af5a
e54f6e :checkadmin
8daf5a
979fc4 if NOT DEFINED ISADMIN goto doneOK
daaf5a
03a11a mkdir DATA\ADMIN
db5d9e mkdir DATA\ADMIN\ClientInstaller
d1c3a2 copy %RELEASEDIR%\pgpAdmin.exe DATA\ADMIN
5336c7 copy docs\PGPAdministratorsGuide.pdf DATA\DOCS
f5af5a
ebcc0d :doneOK
c5ec64 @echo End of setupinstall.bat
d31ea0 goto done
a0af5a
5badc4 :badargs
bd86e3 @echo Invalid build name argument
e8af5a
4be881 :done

--438b 0016e11578840110211 Page 1 of setup.ini
a279c5 [Startup]
06decb AppName=PGP Desktop Security Version 6.0.2
6eb690 FreeDiskSpace=181

--30b4 00010b8a43840110212 Page 1 of DSReadMe.txt
dc0de2 PGP 6.0.2 Read Me
79e8c6 ···
a0581b Copyright (c) 1998 by Network Associates, Inc.,·
f5f5aa and its Affiliated Companies. ·All Rights Reserved.
39af5a
2eaf5a
87be90 Thank you for using Network Associates' products.·
3074bd This Read Me file contains important information regarding·
8660f6 PGP 6.0.2. Network Associates strongly recommends that you·
c77c57 read this entire document.
c6af5a
277494 Network Associates welcomes your comments and suggestions.·
788830 Please use the information provided in this file to·
a7c35d contact us.
98af5a
e73b0c Warning: Export of this software may be restricted by
3b31e7 the U.S. Government.
60af5a
19af5a
85789a ······***** ·IMPORTANT NOTE FOR PGPDISK USERS *****
deaf5a
3f8daa An internal security review of PGPdisk revealed a security·
1bd93e flaw. This affects PGPdisk 1.0 for Windows and the version·
b57864 of PGPdisk that shipped with PGP 6.0 for Windows. ·THIS DOES·
d5f4f5 NOT AFFECT OTHER PORTIONS OF PGP, ONLY PGPDISK FOR WINDOWS. ·
27af5a
5f8d20 The version of PGPdisk that accompanies this release of PGP·
f8d325 (6.0.2) eliminates the problem. ·After you install PGP 6.0.2·
ffd82d and reboot your machine, the PGPdisk Conversion Wizard will·
3f4a45 scan your machine for any existing PGPdisk volumes and will·
81d840 update them automatically. ·Note that the conversion process·
b7866f will remove any alternate passphrases and public keys (with·
db90b4 the exception of ADKs) associated with the volume.
60af5a
4d4fce You must use the master passphrase to convert each volume.
54af5a
3d2158 PGP will automatically upgrade older volumes as you attempt
35220a to use them. We strongly recommend that you update all your·
0b667e PGPdisk volumes to the new version immediately, including·
9bbc7d any volumes that may exist on backup media or network devices.·
995eef If you choose not to convert a volume, copy the data to a new·
a48915 PGPdisk and wipe the original using the PGP 6.0.2 wipe feature.
a2af5a
63c546 Instructions on how to run the PGPdisk Conversion Wizard·
3a9125 are included in this document.
a6af5a
cc2e68 ··········*******************************
fbaf5a
c9af5a
d7af5a
035e83 ___________________
42b7f9 WHAT'S IN THIS FILE
c0af5a
54d549 - New Features
9f7605 - Known Issues
84597d - RSA Support
ed0362 - PGPdisk Conversion Wizard
29e542 - Important Fixes
bbe3ee - Additional Information
0e8425 - Contacting Network Associates
98af5a
20af5a
f55864 _____________________
eb36d1 NEW FEATURES IN 6.0.2
0caf5a
a45c2f - PGP Version 6.0.2 includes a Secure Viewer feature·
828673 known in previous versions of PGP (Version 2.x) as·
474281 "For Your Eyes Only" or FYEO. ·A message encrypted with·
932f06 the Secure Viewer option is only viewable within the·
169ef3 read-only Secure Viewer window. ·The recipient of the·
913307 message is unable to save the message as plaintext. ·
10d201 The Secure Viewer uses a special font that prevents·
--c4a3 0009a5e72fc40110212 Page 2 of DSReadMe.txt
a6e706 TEMPEST attacks. For more information on Secure Viewer,·
b81a7f please see the What's New section in the PGP User's·
6ff1d0 Guide .pdf file.
dfaf5a
7b7eb4 - Forcing the Recipient Dialog to appear can now be
fbea37 accomplished by holding down a modifier key in the email
212471 plugin to show the Recipient Dialog even in cases where
7d9296 the recipients are all valid. ·This key varies by plugin,
2ba995 but is either Shift or Control.
b1af5a
e9af34 - The Outlook plugin now supports Personal Distribution
6cee8e lists.
cfaf5a
77dd85 - PGPtray now works with files copied to the clipboard·
22e7cf from Explorer. ·It previously only worked with copied text.
c5af5a
45af5a
991098 ____________
99779e KNOWN ISSUES
d4af5a
280a04 - The maximum size for RSA keys is 2048 bits. This is due·
7f279d to limitations in the RSA libraries and our desire to remain·
6f46cb backward compatible with previous versions of PGP. ·(Some
1f68a8 previous versions of PGP did function with large RSA keys,
ce708a but creation of these keys has never been supported.)
0baf5a
3d9392 - Mismatching your keyring files can result in data loss. ·
d6e984 Your public keyring file and private keyring file must be·
cd5a31 kept in sync. ·If, for instance, you select a public·
03a828 keyring file that does not contain the public portion of·
ea7f04 your private key and do not also change the private keyring·
80bcf2 to the corresponding file, you and others will not be able to
22f03b encrypt to exported versions of your key after that time. ·
c84438 In most cases, simply updating your key from a public copy on·
9db16a a keyserver will fix this. ·However, it is recommended that·
7db727 the keyring files always be kept in sync. ·A future version·
d62944 is expected to correct this issue.
a5af5a
d7c5fa - Using a Split Key as a public key for PGPdisk will not·
56207f allow reconstitution of the key through the usual dialog·
5edeb0 provided by the rest of the product for Split Keys. ·In·
cf77e8 order to use such a key to open a PGPdisk, you must first·
104d12 rejoin the key in PGPkeys.
a6af5a
48d4cd - Some PGP 6.0 features are incompatible with previous·
ee5457 versions of PGP, so we now feature a "compatible" export·
25ab33 format that strips incompatible features such as Photo IDs·
e3e0a4 from keys. Selecting "Use 6.0 Extensions" in the Export·
4e5e37 dialog enables these features to be exported. ·By default,·
2badb8 we export in compatible mode. ·You may change the default·
4f7ad2 in the Advanced preferences dialog. ·When sending a key to·
219218 a PGP Certificate Server Version 2.0 or above, Photo IDs·
fb8d28 always accompany the key. The default LDAP server in·
e19b19 PGP 6.0 supports this.
8baf5a
cba948 - In some plugins, the Extract Public Key feature has·
1db62a been merged into the Decrypt/Verify feature. ·When in·
45ce27 doubt, use Decrypt/Verify to extract public keys.
21af5a
f3a158 - Sometimes, after a PGPdisk volume is unmounted and placed·
f471ea in the Recycle Bin and the Bin is emptied, Windows reports·
957824 that the drive letter associated with the PGPdisk volume·
94ebcf is no longer accessible. ·This behavior should cease after·
74a773 the system is rebooted. ·This should not interfere with the·
6bcdec normal operation of your system.
51af5a
81a4f4 - On Windows 95/98, the Free Space Wiper will reset every·
6e5d3d time another program writes to your disk while the wiping·
0a6fd3 process is in progress. ·This is similar to defragmentation·
a11159 programs, and is required by the Operating System. ·For·
8cda4d optimal wiping, make sure to close all open applications. ·
9aca72 On some systems with very low amounts of RAM, it may be·
--bd6d 0002e30487f40110212 Page 3 of DSReadMe.txt
b908a4 advisable to also shutdown Windows Explorer.
5eaf5a
b16707 - If you experience a long delay searching the server·
4c8915 sending mail when using the Exchange/Outlook email plugin·
4416da with an Exchange Server and the Encrypting to Unknown Keys·
94e150 synchronization checkbox is checked, this can be caused·
b2f847 by the email account having many SMTP addresses on the·
6f8f0b Exchange Server or by having many servers specified·
6d27e0 in your PGP preferences.
6baf5a
6388ee - The Windows Explorer provides PGP with information
fce9b9 only about the target of a shortcut and not the shortcut·
76cdf6 itself. ·If you use the Wipe feature in the Explorer,·
bb4404 the shortcut itself will not be wiped. ·The actual target·
248310 will be wiped. ·When using PGPtools, the shortcut will·
906602 also be wiped.
c8af5a
14af5a
e51c32 ___________
22027b RSA SUPPORT
14af5a
0f36f4 If you are interested in using or creating RSA keys,·
f0460e please review the following information to determine·
eb3d0b which version of PGP 6.0.2 you need:
22af5a
520b3a Use ·····················Product (Mac or Windows)
30f8f3 ------------------------------------------------------------ ···
c4c8d2 Use existing ············all versions of PGP 6.0.2,·
58d1de ····OR ··················including PGP Freeware
5bf30a ·create new ···
d659c5 ·Diffie-Hellman/DSS keys
0daf5a
0132ce Use existing ····¤  ·PGP for Personal Privacy with RSA·
9e2065 ····OR¤ ¤   ¤   ·PGP Desktop Security with RSA
a224c0 ·create new RSA keys ······················
7daf5a
b1af5a
d729e7 Limited and **unsupported** RSA functionality is available in·
478314 the Windows versions (ONLY) of PGP through Microsoft's·
76a7ca Cryptographic API (CAPI), as installed with Internet Explorer·
10ca48 4.0. ·If you have installed the 128-bit version of IE 4.0·
c75773 or later on your system, PGP will use CAPI to provide basic·
622ecf RSA functionality. ·With CAPI, you will be unable to generate·
0af953 RSA keys nor use non-standard key sizes. ·If you find that this·
1c08ad RSA implementation does not meet your needs, you will need·
8adf4e to purchase the standard RSA Add-on. ·See the table above·
d4c273 to determine which product best suits your needs. ·
66af5a
cd9a9b If you have purchased an incorrect version or are interested
aec418 in purchasing an RSA Add-on version of PGP please contact the·
99ebb2 Network Associates Customer Care department at:·
d2af5a
096a61 Phone (408) 988-3832
e72a5e Monday-Friday, 6:00 A.M. - 6:00 P.M. Pacific time
33af5a
c2af5a
a3acb1 _________________________
93bd12 PGPDISK CONVERSION WIZARD
77af5a
ff8daa An internal security review of PGPdisk revealed a security·
21d93e flaw. This affects PGPdisk 1.0 for Windows and the version·
507864 of PGPdisk that shipped with PGP 6.0 for Windows. ·THIS DOES·
c1f4f5 NOT AFFECT OTHER PORTIONS OF PGP, ONLY PGPDISK FOR WINDOWS. ·
5aaf5a
897661 We strongly suggest you upgrade all existing PGPdisk volumes.
bb9d5c PGP version 6.0.2 includes the PGPdisk Conversion Wizard,·
9892c6 which automatically upgrades earlier versions of PGPdisk volumes.·
32a781 See the note at the beginning of this ReadMe file for more
b32fdf information.
31af5a
c923ea Note: When you convert a PGPdisk volume, the main passphrase·
2ed09d for the PGPdisk volume and any ADKs associated with the·
--eb10 000eb34c7d840110212 Page 4 of DSReadMe.txt
194c8e volume are preserved; however, alternate passphrases and·
dc52a4 public keys that are associated with the PGPdisk volume·
05805b are not preserved.·
60af5a
01354d ___________________________________________________________
d50d04 To convert all of your PGPdisk volumes, follow these steps:
6aaf5a
43de3f 1. If the installer detects any previous version of PGPdisk·
b271b2 ···on your system, the PGPdisk Conversion Wizard automatically·
c5b9e7 ···appears when you restart your system after PGP 6.0.2·
867a46 ···installation is complete.·
8faf5a
3deda7 ···If the installer fails to detect a previous version of·
844015 ···PGP or PGPdisk, you can manually start the PGPdisk·
adafd4 ···Conversion Wizard by opening the PGPdisk application·
36089a ···and selecting Convert Pre-v6.0.2 disks from the File·
a1a580 ···menu.
5daf5a
9f105d 2. If you want to convert all of your PGPdisk volumes on·
c10799 ···your system now, click Next.·
a1af5a
d02d37 ···The Conversion Wizard searches your system for PGPdisk·
3685b0 ···volumes that have not been converted.
1faf5a
7af8a9 3. Select all PGPdisk volumes listed in the Conversion·
d48eeb ···Wizard.
4faf5a
e4b5d1 4. Click Next.
b6af5a
a556fb ···A warning message appears and prompts you to start the·
69c57d ···PGPdisk Conversion Wizard.
ffaf5a
7bab4b 5. Click Yes to convert the PGPdisk volume.
0aaf5a
6c6f05 ···The PGPdisk Conversion Wizard screen appears.·
d8af5a
109f41 6. Enter the master passphrase for the volume to be
8daa07 ···converted, then click OK.
9aaf5a
61632d 7. Click Next to start converting the PGPdisk volume.
2f69ec ···The PGPdisk volume will be re-encrypted. ·
d4e8c6 ···
55ad8d ···*** Note that you will lose all passphrases and·
de6f5f ···public keys associated with the volume (excluding·
fee0dc ···the volume's master passphrase and any PGPdisk ADKs).
c9af5a
f73065 8. Move your mouse around in a random manner within the·
762a01 ···Wizard window and/or type characters on the keyboard·
703898 ···until the progress bar shown in the dialog box is·
60974b ···completely filled in.·
afaf5a
cec4d2 ···Your mouse movements and typing are used to generate·
1f3070 ···random information used by the PGPdisk program as part·
ba41ec ···of the encryption (data scrambling) process.
04af5a
318430 9. Click Next.
2faf5a
b87c7f ···A progress bar indicates how much of the PGPdisk volume·
58b703 ···has been converted.
83af5a
1de4d9 10. When the progress bar is at 100%, click Next to finish·
9e49ff ····the process.
c8af5a
1f2388 11. Click Finish, then mount the volume by entering the·
632ba7 ····volume's master passphrase.
04af5a
c383a7 12. The PGPdisk volume is secure and ready to use.·
c6af5a
3a56d1 ····Repeat steps 4-10 to convert all of your PGPdisk·
05cdf0 ····volumes. Be sure to convert all of your PGPdisk volumes·
a4603b ····including volumes that are stored on network drives and·
eb0416 ····removable media as well as volumes stored on your local·
--ee9e 0006db77d3a40110212 Page 5 of DSReadMe.txt
ab5614 ····drive(s).
7faf5a
19ad3d _______________________________________________________
f395d6 To convert PGPdisk volumes stored on network drives and·
cce79b removable media, follow these steps:
7caf5a
6893b3 1. Install PGP 6.0.2.
2faf5a
f7af30 2. Mount the PGPdisk volume. PGPdisk will automatically·
fb0d14 ···alert you when you attempt to mount volumes that have·
933434 ···not been upgraded. ·
05af5a
a42a0d 3. Click Yes to convert the PGPdisk volume. ·
34e8c6 ···
fb667d ···*** Note: ·If you choose not to convert the volume·
37f86d ···at this time, the volume is mounted in read-only format·
a4dd94 ···so you can access the contents of the encrypted volume·
a1256b ···to back them up prior to conversion. ·You will be unable·
22648a ···to write to the volume until you convert it.
07af5a
f5e933 ···If you click Yes, the PGPdisk Conversion Wizard screen·
05559e ···appears.·
a9af5a
48f506 4. Click Next to start the Conversion Wizard.
7ee8c6 ···
b3e267 ···*** Note: ·You will lose all passphrases and·
ac6f5f ···public keys associated with the volume (excluding·
6be0dc ···the volume's master passphrase and any PGPdisk ADKs).
6faf5a
131f67 5. Enter the master passphrase for the volume to be
5b5159 ···converted, then click OK.·
4baf5a
dd425d 6. Move your mouse around in a random manner within the·
8a2a01 ···Wizard window and/or type characters on the keyboard·
673898 ···until the progress bar shown in the dialog box is·
32974b ···completely filled in.·
50af5a
1ac4d2 ···Your mouse movements and typing are used to generate·
6fc4a8 ···random information used by the PGPdisk program as part of·
94bcbf ···the encryption (data scrambling) process.
04af5a
3f6daf 7. Click Next.
b9af5a
007c7f ···A progress bar indicates how much of the PGPdisk volume·
96b703 ···has been converted.
03af5a
e86f20 8. When the progress bar is at 100%, click Next to finish·
6f67f9 ···the process.
97af5a
a78767 9. Click Finish, then mount the volume by entering the·
25d7fb ···volume's master passphrase.
46af5a
435125 10.The PGPdisk volume is secure and ready to use.·
f4af5a
77a7d4 ···Repeat steps 2-8 to convert all of your PGPdisk volumes.·
45af5a
74af5a
1b572a _______________
0a5bc2 IMPORTANT FIXES
a3ec2c ························
d3e883 In addition to the PGPdisk issues and some minor issues,
91b133 the following common issues are fixed in this version:
92af5a
c6cdfb - Fixed: Long passphrases are sometimes reported as
5632c8 incorrect even though they are typed correctly.
e8af5a
177994 - Fixed: PGPkeys sometimes creates RSA keys that are
ca722d displayed as split keys.
b1af5a
c381c2 - Fixed: "Wrong version" error when using PGP with the
6a2cd0 comctl32.dll from IE 5.0 beta.
6daf5a
--b94e 001a95cfd1640110212 Page 6 of DSReadMe.txt
d6c1c8 - Fixed: Mouse can disappear "behind" the Recipient Dialog
34d80b if Windows' preference "Hide pointer when typing" is
32659c enabled.
66af5a
8a276f ______________________
248ff5 ADDITIONAL INFORMATION
dcec2c ························
e35d0e * PGP DOCUMENTATION *·
8aaf5a
422ff6 For information on how to use PGP, including introductory·
925dba material on cryptography in general, please refer to the·
113c73 documentation and online help that accompanies 6.0.2. ·
8baf5a
e716c2 The PGP documentation is distributed in Adobe Acrobat·
727ef3 format (.pdf). ·Free readers are available for this·
73f068 format on nearly every platform including Macintosh,·
d515a3 Windows, DOS, SUN Sparc, HP/UX, SGI, AIX, and others·
094529 from the following web site:·
b7af5a
953136 http://www.adobe.com/acrobat/
b75886 ·················
72af5a
e8d5cb _____________________________
69a7c8 CONTACTING NETWORK ASSOCIATES
e2af5a
34f67b * TECHNICAL SUPPORT *·
85af5a
be670c We recommend that you read the PGP documentation before·
fa2b92 you contact technical support to see if your issue is·
b3cfd2 addressed in the documentation. ·
ccaf5a
5ee62b Please send any problems, comments, or suggestions for this
b8cdab product to our technical support staff:
40af5a
9dbc7f Phone ·Phone (408) 988-3832
6838c5 Email ·pgpsupport@pgp.com ·
25af5a
fa9e3a See our website for further instructions and please have·
50e004 your registration number handy.
8baf5a
99c6c7 Enjoy!
75af5a
a9af5a
a9e9d5 The PGP Development Team
--e649 0004973f23c40110213 Page 1 of FreewareReadMe.txt
e320a3 ··················PGP 6.0.2 Read Me
02e8c6 ···
77d84f ···Copyright (c) 1998 by Network Associates, Inc.,·
ee99e4 ···and its Affiliated Companies. ·All Rights Reserved.
feaf5a
71af5a
4cbe90 Thank you for using Network Associates' products.·
3137c2 This Read Me file contains important information
11eadf regarding PGP 6.0.2. Network Associates strongly·
52f911 recommends that you read this entire document.
11af5a
15e731 Network Associates welcomes your comments and·
5206d3 suggestions. Please use the information provided in·
1df823 this file to contact us.
d1af5a
f93b0c Warning: Export of this software may be restricted by
4631e7 the U.S. Government.
32af5a
45af5a
38db34 ············***** ·IMPORTANT NOTE *****
eeaf5a
1fc430 An internal security review of previous versions of
d40ac4 PGPdisk for Windows revealed a serious security flaw.·
d04584 The version of PGPdisk that accompanies this release
505c1f of PGP (6.0.2) repairs this problem. ·After you install
8c1b2c PGP 6.0.2 and reboot your machine, the PGPdisk Conversion
00bfb0 Wizard will scan your machine for any existing PGPdisk·
8a287d volumes so that you may upgrade them. ·During this·
b51dc2 conversion, you will lose any alternate passphrases and·
7bebcc public keys (with the exception of ADKs) associated with·
befcae the volume.
f9af5a
384fce You must use the master passphrase to convert each volume.
78af5a
63aa1e PGPdisk will continue to automatically upgrade older·
2a7c46 volumes as you attempt to use them (this enables you·
7f2d71 to repair volumes on external media, network drives, backups,·
3ceac1 and so on, as you need to). ·We strongly recommend that·
a33595 you update all your PGPdisk volumes to the new version·
fb0858 immediately. ·
4daf5a
4a031f Instructions on how to run the Conversion Wizard are·
57866e included in this document.
afaf5a
282e68 ··········*******************************
f5af5a
6faf5a
3aaf5a
a55e83 ___________________
dcb7f9 WHAT'S IN THIS FILE
a5af5a
26d549 - New Features
3c7605 - Known Issues
c9597d - RSA Support
2a0362 - PGPdisk Conversion Wizard
8fe542 - Important Fixes
d6e3ee - Additional Information
ab8425 - Contacting Network Associates
24af5a
c8af5a
ab5864 _____________________
be36d1 NEW FEATURES IN 6.0.2
cfaf5a
785c2f - PGP Version 6.0.2 includes a Secure Viewer feature·
f28673 known in previous versions of PGP (Version 2.x) as·
544281 "For Your Eyes Only" or FYEO. ·A message encrypted with·
fc2f06 the Secure Viewer option is only viewable within the·
d09ef3 read-only Secure Viewer window. ·The recipient of the·
7d3307 message is unable to save the message as plaintext. ·
ded201 The Secure Viewer uses a special font that prevents·
70e706 TEMPEST attacks. For more information on Secure Viewer,·
491a7f please see the What's New section in the PGP User's·
--278b 0005d896ea040110213 Page 2 of FreewareReadMe.txt
16f1d0 Guide .pdf file.
e2af5a
c17eb4 - Forcing the Recipient Dialog to appear can now be
1bea37 accomplished by holding down a modifier key in the email
832471 plugin to show the Recipient Dialog even in cases where
3d9296 the recipients are all valid. ·This key varies by plugin,
e1a995 but is either Shift or Control.
f2af5a
27af34 - The Outlook plugin now supports Personal Distribution
4bee8e lists.
4baf5a
4e1098 ____________
55779e KNOWN ISSUES
30af5a
bc0a04 - The maximum size for RSA keys is 2048 bits. This is due·
9a279d to limitations in the RSA libraries and our desire to remain·
b746cb backward compatible with previous versions of PGP. ·(Some
c268a8 previous versions of PGP did function with large RSA keys,
1e708a but creation of these keys has never been supported.)
d5af5a
4a9392 - Mismatching your keyring files can result in data loss. ·
6ce984 Your public keyring file and private keyring file must be·
105a31 kept in sync. ·If, for instance, you select a public·
bba828 keyring file that does not contain the public portion of·
697f04 your private key and do not also change the private keyring·
67bcf2 to the corresponding file, you and others will not be able to
c0f03b encrypt to exported versions of your key after that time. ·
164438 In most cases, simply updating your key from a public copy on·
90b16a a keyserver will fix this. ·However, it is recommended that·
05b727 the keyring files always be kept in sync. ·A future version·
582944 is expected to correct this issue.
70af5a
25c5fa - Using a Split Key as a public key for PGPdisk will not·
dd207f allow reconstitution of the key through the usual dialog·
b7deb0 provided by the rest of the product for Split Keys. ·In·
6077e8 order to use such a key to open a PGPdisk, you must first·
c74d12 rejoin the key in PGPkeys.
bbaf5a
8cd4cd - Some PGP 6.0 features are incompatible with previous·
325457 versions of PGP, so we now feature a "compatible" export·
d3ab33 format that strips incompatible features such as Photo IDs·
f7e0a4 from keys. Selecting "Use 6.0 Extensions" in the Export·
a45e37 dialog enables these features to be exported. ·By default,·
10adb8 we export in compatible mode. ·You may change the default·
127ad2 in the Advanced preferences dialog. ·When sending a key to·
229218 a PGP Certificate Server Version 2.0 or above, Photo IDs·
378d28 always accompany the key. The default LDAP server in·
3a9b19 PGP 6.0 supports this.
75af5a
0ba948 - In some plugins, the Extract Public Key feature has·
00b62a been merged into the Decrypt/Verify feature. ·When in·
31ce27 doubt, use Decrypt/Verify to extract public keys.
5daf5a
c5dd85 - PGPtray now works with files copied to the clipboard·
1fe7cf from Explorer. ·It previously only worked with copied text.
9baf5a
5da4f4 - On Windows 95/98, the Free Space Wiper will reset every·
f25d3d time another program writes to your disk while the wiping·
286fd3 process is in progress. ·This is similar to defragmentation·
bb1159 programs, and is required by the Operating System. ·For·
27da4d optimal wiping, make sure to close all open applications. ·
2bca72 On some systems with very low amounts of RAM, it may be·
6a08a4 advisable to also shutdown Windows Explorer.
b2af5a
cf6707 - If you experience a long delay searching the server·
688915 sending mail when using the Exchange/Outlook email plugin·
b716da with an Exchange Server and the Encrypting to Unknown Keys·
fee150 synchronization checkbox is checked, this can be caused·
0af847 by the email account having many SMTP addresses on the·
988f0b Exchange Server or by having many servers specified·
e127e0 in your PGP preferences.
5daf5a
--9675 000a82e76e140110213 Page 3 of FreewareReadMe.txt
2588ee - The Windows Explorer provides PGP with information
47e9b9 only about the target of a shortcut and not the shortcut·
b1cdf6 itself. ·If you use the Wipe feature in the Explorer,·
774404 the shortcut itself will not be wiped. ·The actual target·
128310 will be wiped. ·When using PGPtools, the shortcut will·
e56602 also be wiped.
33af5a
0baf5a
341c32 ___________
57027b RSA SUPPORT
7faf5a
efff9a If you are interested in using or generating·
b426c1 RSA keys, please review the following information·
52ff5b to determine which version of PGP 6.0.2 you need:
f2af5a
fd0b3a Use ·····················Product (Mac or Windows)
85f8f3 ------------------------------------------------------------ ···
5ec8d2 Use existing ············all versions of PGP 6.0.2,·
99d1de ····OR ··················including PGP Freeware
b106f5 ·generate new ···
e259c5 ·Diffie-Hellman/DSS keys
64af5a
76dfc6 Use existing RSA keys ···PGP for Personal Privacy RSA Add-on
649a9e ·························PGP Desktop Security RSA Add-on·
4faf5a
e74781 Generate new RSA keys ···PGP for Personal Privacy RSA Add-on
f1091a ·························PGP Desktop Security RSA Add-on
02d421 ·····························································
f5af5a
6680bd *** Note that you cannot generate RSA keys using PGP for·
adafe4 Personal Privacy and you cannot use existing RSA keys without·
499ac6 the RSA Add-on. ·
27af5a
f429e7 Limited and **unsupported** RSA functionality is available in·
db8314 the Windows versions (ONLY) of PGP through Microsoft's·
56a7ca Cryptographic API (CAPI), as installed with Internet Explorer·
94ca48 4.0. ·If you have installed the 128-bit version of IE 4.0·
d05773 or later on your system, PGP will use CAPI to provide basic·
bd2ecf RSA functionality. ·With CAPI, you will be unable to generate·
1cf953 RSA keys nor use non-standard key sizes. ·If you find that this·
9d08ad RSA implementation does not meet your needs, you will need·
93df4e to purchase the standard RSA Add-on. ·See the table above·
48c273 to determine which product best suits your needs. ·
e0af5a
c39a9b If you have purchased an incorrect version or are interested
11c418 in purchasing an RSA Add-on version of PGP please contact the·
86ebb2 Network Associates Customer Care department at:·
bfaf5a
386a61 Phone (408) 988-3832
8f2a5e Monday-Friday, 6:00 A.M. - 6:00 P.M. Pacific time
a6af5a
fcaf5a
70acb1 _________________________
b7bd12 PGPDISK CONVERSION WIZARD
94af5a
c9e540 PGPdisk volumes created with versions of PGPdisk prior to·
780ac6 version 6.0.2 are not secure. Network Associates strongly·
e97619 recommends that you upgrade all of your PGPdisk volumes·
2feb51 created with earlier versions of PGPdisk to version 6.0.2.·
0cfab8 All PGPdisk volumes must be converted to this new format·
fb91da to ensure that your PGPdisk volumes are secure.
04af5a
cd9d5c PGP version 6.0.2 includes the PGPdisk Conversion Wizard,·
6f9eb3 which converts earlier versions of PGPdisk volumes to a·
16110a secure encryption algorithm.·
19af5a
0023ea Note: When you convert a PGPdisk volume, the main passphrase·
c1d09d for the PGPdisk volume and any ADKs associated with the·
884c8e volume are preserved; however, alternate passphrases and·
5752a4 public keys that are associated with the PGPdisk volume·
49805b are not preserved.·
a8af5a
--bee6 00031c2792c40110213 Page 4 of FreewareReadMe.txt
79354d ___________________________________________________________
bb0d04 To convert all of your PGPdisk volumes, follow these steps:
baaf5a
25de3f 1. If the installer detects any previous version of PGPdisk·
4771b2 ···on your system, the PGPdisk Conversion Wizard automatically·
70b9e7 ···appears when you restart your system after PGP 6.0.2·
2a7a46 ···installation is complete.·
93af5a
caeda7 ···If the installer fails to detect a previous version of·
714015 ···PGP or PGPdisk, you can manually start the PGPdisk·
58afd4 ···Conversion Wizard by opening the PGPdisk application·
94089a ···and selecting Convert Pre-v6.0.2 disks from the File·
7da580 ···menu.
3baf5a
0d105d 2. If you want to convert all of your PGPdisk volumes on·
060799 ···your system now, click Next.·
bfaf5a
f32d37 ···The Conversion Wizard searches your system for PGPdisk·
3c85b0 ···volumes that have not been converted.
5faf5a
3df8a9 3. Select all PGPdisk volumes listed in the Conversion·
e68eeb ···Wizard.
14af5a
76b5d1 4. Click Next.
feaf5a
3756fb ···A warning message appears and prompts you to start the·
d2c57d ···PGPdisk Conversion Wizard.
3eaf5a
0eab4b 5. Click Yes to convert the PGPdisk volume.
e5af5a
786f05 ···The PGPdisk Conversion Wizard screen appears.·
1baf5a
bf9f41 6. Enter the master passphrase for the volume to be
71aa07 ···converted, then click OK.
caaf5a
16632d 7. Click Next to start converting the PGPdisk volume.
5669ec ···The PGPdisk volume will be re-encrypted. ·
ffe8c6 ···
caad8d ···*** Note that you will lose all passphrases and·
de6f5f ···public keys associated with the volume (excluding·
12e0dc ···the volume's master passphrase and any PGPdisk ADKs).
36af5a
df3065 8. Move your mouse around in a random manner within the·
682a01 ···Wizard window and/or type characters on the keyboard·
bc3898 ···until the progress bar shown in the dialog box is·
95974b ···completely filled in.·
b4af5a
f7c4d2 ···Your mouse movements and typing are used to generate·
ca3070 ···random information used by the PGPdisk program as part·
d341ec ···of the encryption (data scrambling) process.
adaf5a
de8430 9. Click Next.
66af5a
ed7c7f ···A progress bar indicates how much of the PGPdisk volume·
19b703 ···has been converted.
3caf5a
73e4d9 10. When the progress bar is at 100%, click Next to finish·
9049ff ····the process.
d2af5a
0a2388 11. Click Finish, then mount the volume by entering the·
cc2ba7 ····volume's master passphrase.
f5af5a
b683a7 12. The PGPdisk volume is secure and ready to use.·
ccaf5a
7756d1 ····Repeat steps 4-10 to convert all of your PGPdisk·
00cdf0 ····volumes. Be sure to convert all of your PGPdisk volumes·
c4603b ····including volumes that are stored on network drives and·
010416 ····removable media as well as volumes stored on your local·
c15614 ····drive(s).
aaaf5a
65ad3d _______________________________________________________
3195d6 To convert PGPdisk volumes stored on network drives and·
--6f86 000499ba2d940110213 Page 5 of FreewareReadMe.txt
3ee79b removable media, follow these steps:
f2af5a
0293b3 1. Install PGP 6.0.2.
2eaf5a
5baf30 2. Mount the PGPdisk volume. PGPdisk will automatically·
b30d14 ···alert you when you attempt to mount volumes that have·
ea3434 ···not been upgraded. ·
02af5a
2c2a0d 3. Click Yes to convert the PGPdisk volume. ·
c7e8c6 ···
ad667d ···*** Note: ·If you choose not to convert the volume·
f9f86d ···at this time, the volume is mounted in read-only format·
5fdd94 ···so you can access the contents of the encrypted volume·
a6256b ···to back them up prior to conversion. ·You will be unable·
38648a ···to write to the volume until you convert it.
d2af5a
55e933 ···If you click Yes, the PGPdisk Conversion Wizard screen·
bc559e ···appears.·
52af5a
10f506 4. Click Next to start the Conversion Wizard.
84e8c6 ···
c4e267 ···*** Note: ·You will lose all passphrases and·
686f5f ···public keys associated with the volume (excluding·
ffe0dc ···the volume's master passphrase and any PGPdisk ADKs).
f6af5a
271f67 5. Enter the master passphrase for the volume to be
1b5159 ···converted, then click OK.·
40af5a
b4425d 6. Move your mouse around in a random manner within the·
d52a01 ···Wizard window and/or type characters on the keyboard·
063898 ···until the progress bar shown in the dialog box is·
e5974b ···completely filled in.·
5caf5a
3bc4d2 ···Your mouse movements and typing are used to generate·
6ac4a8 ···random information used by the PGPdisk program as part of·
8fbcbf ···the encryption (data scrambling) process.
efaf5a
ca6daf 7. Click Next.
5eaf5a
c27c7f ···A progress bar indicates how much of the PGPdisk volume·
f3b703 ···has been converted.
b8af5a
266f20 8. When the progress bar is at 100%, click Next to finish·
7467f9 ···the process.
a6af5a
6f8767 9. Click Finish, then mount the volume by entering the·
09d7fb ···volume's master passphrase.
29af5a
ce5125 10.The PGPdisk volume is secure and ready to use.·
a4af5a
85a7d4 ···Repeat steps 2-8 to convert all of your PGPdisk volumes.·
3daf5a
ecaf5a
92572a _______________
a45bc2 IMPORTANT FIXES
15ec2c ························
1ce883 In addition to the PGPdisk issues and some minor issues,
7bb133 the following common issues are fixed in this version:
65af5a
36cdfb - Fixed: Long passphrases are sometimes reported as
8932c8 incorrect even though they are typed correctly.
10af5a
e97994 - Fixed: PGPkeys sometimes creates RSA keys that are
f0722d displayed as split keys.
2daf5a
9981c2 - Fixed: "Wrong version" error when using PGP with the
762cd0 comctl32.dll from IE 5.0 beta.
9daf5a
e4c1c8 - Fixed: Mouse can disappear "behind" the Recipient Dialog
f4d80b if Windows' preference "Hide pointer when typing" is
f2659c enabled.
49af5a
--f8c8 001ab7a4fb240110213 Page 6 of FreewareReadMe.txt
d0276f ______________________
6c8ff5 ADDITIONAL INFORMATION
17ec2c ························
2b5d0e * PGP DOCUMENTATION *·
05af5a
432ff6 For information on how to use PGP, including introductory·
725dba material on cryptography in general, please refer to the·
9b3c73 documentation and online help that accompanies 6.0.2. ·
58af5a
9716c2 The PGP documentation is distributed in Adobe Acrobat·
7b7ef3 format (.pdf). ·Free readers are available for this·
f9f068 format on nearly every platform including Macintosh,·
3c15a3 Windows, DOS, SUN Sparc, HP/UX, SGI, AIX, and others·
5f4529 from the following web site:·
3baf5a
f43136 http://www.adobe.com/acrobat/
1a5886 ·················
28af5a
0dd5cb _____________________________
3ea7c8 CONTACTING NETWORK ASSOCIATES
50af5a
04f67b * TECHNICAL SUPPORT *·
ecaf5a
87670c We recommend that you read the PGP documentation before·
6b2b92 you contact technical support to see if your issue is·
c1cfd2 addressed in the documentation. ·
bdaf5a
9be62b Please send any problems, comments, or suggestions for this
d7cdab product to our technical support staff:
4faf5a
15bc7f Phone ·Phone (408) 988-3832
5f38c5 Email ·pgpsupport@pgp.com ·
65af5a
7d9e3a See our website for further instructions and please have·
5de004 your registration number handy.
cfaf5a
a1c6c7 Enjoy!
47af5a
13af5a
abe9d5 The PGP Development Team
--730b 000ffed27a040110214 Page 1 of Pgp60.cnt
0eacca :Base Pgp60.HLP>wide
8aec36 :Title PGP Desktop Security
52dab9 1 Concepts
ea1118 2 About PGP=About_PGP>wide
ccef62 2 What's new in PGP Version 6.0=What_s_new_in_PGP_Version_6_0>wide
dd22af 2 About Keys=About_Keys>wide
695cdf 2 About Key Pairs=About_Key_Pairs>wide
dbee47 2 About Keyrings=About_Keyrings>wide
21ad54 2 About Additional Decryption Keys=About_Additional_Decryption_Keys>wide
9b0d0e 2 About Corporate Signing Keys=About_Corporate_Signing_Keys>wide
87f6e8 2 Starting PGP=Starting_PGP
9be744 2 Using PGP=Using_PGP>wide
bfaf8b 1 Getting Help
d7b7e5 2 Contacting Technical Support=Contacting_Technical_Support>wide
ed4956 1 Creating Keys
180112 2 To Create a Key Pair=To_Create_a_Key_Pair>wide
ed22af 2 About Keys=About_Keys>wide
925cdf 2 About Key Pairs=About_Key_Pairs>wide
08ee47 2 About Keyrings=About_Keyrings>wide
a38746 1 Setting Preferences
688b29 2 Establishing PGP Preferences=Establishing_PGP_Preferences>wide
ad1b9a 2 General Preferences=General_Preferences>wide
1d83c1 2 Email Preferences=Email_Preferences>wide
5b36f1 2 Key Files Preferences=Key_Files_Preferences>wide
dca7a0 2 Key Server Preferences=Key_Server_Preferences>wide
284632 2 Advanced Preferences=Advanced_Preferences>wide
9ae962 1 Exchanging Keys
4beeb7 2 Exchanging Keys With Others=Exchanging_Keys_With_Others>wide
611537 2 Using Key Servers
d2c0f4 3 Making Your Public Key Available Through a Server=Making_Your_Public_Key_Avai¶
eac82b lable_Through_a_Server>wide
404adb 3 Retrieving Public Keys From a Key Server=Retrieving_Public_Keys_from_a_Key_Se¶
ab36d5 rver>wide
de5a5a 3 To Send Your Public Key to a Key Server=To_Send_your_Public_Key_to_a_Key_Serv¶
ee0bd6 er>wide
e9eaa5 3 To Get Someone's Public Key from a Key Server=To_Get_Someone_s_Public_Key_fro¶
d66f8e m_a_Key_Server>wide
857fba 3 Adding a certificate server to the server list=Adding_a_certificate_server_to¶
16667e _the_server_list
13fbf4 3 Removing signatures or user names associated with your key=Removing_signature¶
f17c14 s_or_user_names_associated_with_your_key
452b0f 2 Obtaining and Sending Keys Through Email
bafd7f 3 Adding Public Keys from Email Messages=Adding_Public_Keys_from_Email_Messages¶
836941 >wide
aede26 3 Including Your Public Key in an Email Message=Including_Your_Public_Key_in_an¶
2420b2 _Email_Message>wide
57aeb4 2 Importing and Exporting Keys
ab2bfa 3 About Importing and Exporting Keys=About_Importing_and_Exporting_Keys>wide
f41eae 3 To Import a Key From a File=To_Import_a_Key_from_a_File>wide
a5aea9 3 To Export Your Public Key to a File=To_Export_your_public_key_to_a_file>wide
70a55b 1 Protecting Your Keys
465c37 2 Protecting your Keys=Protecting_your_Keys>wide
bbeb80 2 Making a Backup Copy of Your Keys=Making_a_Backup_Copy_of_Your_Keys>wide
972b5b 1 Managing Your Keys
b49c8d 2 Managing Keys=Managing_Keys>wide
425ed0 2 Opening the PGPkeys Window=Opening_the_PGPkeys_Window>wide
9002ae 2 To Search For a Key=To_search_for_a_key>wide
152a52 2 To Specify a Default Key Pair=To_Specify_a_Default_Key_Pair>wide
ed843f 2 Checking a Key's Fingerprint=Checking_a_Key_s_Fingerprint>wide
fd76d1 2 Changing Your Passphrase=Changing_Your_Passphrase>wide
c8d7b4 2 To Add a New User Name or Address=To_Add_a_New_User_Name_or_Address>wide
fc8e2d 2 Adding a Photographic ID to Your Key=Adding_a_photographic_ID_to_your_key>wide
c44b40 2 To replace your photographic ID=To_replace_your_photographic_ID
ac1ff5 2 Updating Your Key=Updating_Your_Key>wide
3c80c0 2 Backing Up Your Keyrings
44968e 3 Making a Backup Copy of Your Keys=Making_a_Backup_Copy_of_Your_Keys>wide
f1c852 2 Validating Keys
156936 3 Validating Your Keys=Validating_your_keys>wide
603177 3 Verifying the Authenticity of a Key=Verifying_the_Authenticity_of_a_Key>wide
cdba3c 3 Examining a Key's Properties=Examining_a_Keys_Properties>wide
917e4a 3 Checking a Key's Fingerprint=Checking_a_Key_s_Fingerprint>wide
fff0af 3 Granting Trust for Key Validations=Granting_Trust_for_Key_Validations>wide
--d6da 0006ac6c12140110214 Page 2 of Pgp60.cnt
d20104 3 Signing Someone's Key=Signing_someone_s_key>wide
02e090 3 Disabling and Enabling Keys=Disabling_and_Enabling_Keys>wide
cd146b 2 Deleting and Revoking Keys
63cab8 3 Deleting a Key or Signature=Deleting_a_Key_or_Signature>wide
0d1219 3 Revoking Keys=Revoking_Keys>wide
cacd81 3 To Appoint a Designated Revoker=To_appoint_a_designated_revoker>wide
93fbf4 3 Removing signatures or user names associated with your key=Removing_signature¶
4e7c14 s_or_user_names_associated_with_your_key
d10564 1 Splitting and Rejoining Keys
e09836 2 To Create a Split Key With Multiple Shares=To_create_a_split_key_with_multipl¶
e22a34 e_shares>wide
8510da 2 Signing and Decrypting Files With a Split Key=Signing_and_decrypting_files_wi¶
98b847 th_a_split_key>wide
44021f 2 To Reconstitute a Split Key=To_reconstitute_a_split_key>wide
75dbb7 2 To Send Your Key Share Over the Network=To_send_your_key_share_over_the_netwo¶
593850 rk>wide
1e4ff5 1 Using PGP With Email
f52417 2 Using PGP With Supported Email Applications=Using_PGP_With_Supported_E_mail_A¶
20b314 pplications>wide
bdea92 2 To Create a Distribution List=To_create_a_distribution_list>wide
8ce1f4 2 To Delete Members From a Distribution List=To_delete_members_from_a_distribut¶
0a57ba ion_list>wide
194d34 2 Encrypting and Signing Email
df68c2 3 Encrypting and Signing your Email=Encrypting_and_signing_your_e_mail>wide
a819d0 3 To Encrypt and Sign with Eudora (with PGP/MIME)=To_Encrypt_and_Sign_with_Eudo¶
b25a1b ra_with_PGP_MIME>wide
4417ae 3 To Encrypt and Sign with Eudora (without PGP/MIME)=To_Encrypt_and_Sign_with_E¶
2fbcd8 udora_without_PGP_MIME>wide
65a313 3 Using PGPtools to Encrypt and Sign=Using_PGPtools_to_encrypt_and_sign>wide
2ea29f 3 Use PGP/MIME When Sending Email=Use_PGP_MIME_When_Sending_Email>wide
d7746c 2 Decrypting and Verifying Email
69c9e6 3 Decrypting and Verifying Your Email=Decrypting_and_verifying_your_e_mail>wide
f7c296 3 Using PGPtools to Decrypt and Verify=Using_PGPtools_to_decrypt_and_verify>wide
b47699 3 To Decrypt and Verify with Eudora (with PGP/MIME)=To_Decrypt_and_Verify_with_¶
a090c2 Eudora_with_PGP_MIME>wide
8a5fea 3 To Decrypt and Verify with Eudora (without PGP/MIME)=To_Decrypt_and_Verify_wi¶
8c0658 th_Eudora_without_PGP_MIME>wide
10b647 1 Using PGP For Secure File Storage
2133d2 2 Using PGP for Secure File Storage=Using_PGP_for_Secure_File_Storage>wide
e61ad3 2 Using PGP Wipe to Delete Files=Using_PGP_Wipe_to_delete_files>wide
01a948 2 Using the Wipe Free Space Wizard to Clean Free Space on Your Disks=Using_the_¶
63dcf9 Wipe_Free_Space_Wizard_to_clean_free_space_on_your_disks
9a542c 2 Encrypting and Signing Files
ff730f 3 Encrypting and Signing Files=Encrypting_and_Signing_Files>wide
ed2499 3 To Encrypt and Sign From the Windows Explorer=To_encrypt_and_sign_from_the_Wi¶
29e27a ndows_Explorer>wide
9fd403 3 To Encrypt and Sign Via the Clipboard=To_encrypt_and_sign_via_the_clipboard@P¶
6d5178 gp.HLP>wide
17e956 3 Using PGPtray to Encrypt and Sign=Using_PGPtray_to_Encrypt_and_Sign>wide
73a313 3 Using PGPtools to Encrypt and Sign=Using_PGPtools_to_encrypt_and_sign>wide
106d74 2 Decrypting and Verifying Files
d0796a 3 Decrypting and Verifying Files=Decrypting_and_Verifying_Files>wide
545e52 3 To Decrypt and Verify from the Windows Explorer=To_Decrypt_and_Verify_from_th¶
e3d02c e_Windows_Explorer@Pgp.HLP>wide
11d5a6 3 To Decrypt and Verify Using the Clipboard=To_decrypt_and_verify_using_the_cli¶
335bcb pboard@Pgp.HLP>wide
b15eaa 3 Using PGPtray to Decrypt and Verify=Using_PGPtray_to_decrypt_and_verify>wide
1fc296 3 Using PGPtools to Decrypt and Verify=Using_PGPtools_to_decrypt_and_verify>wide
12e72f 1 Wipe Free Space
6e725e 2 Wipe Files=Using_PGP_Wipe_to_delete_files
a68959 2 PGP Free Space Wiper for Disks=Using_the_PGP_Free_Space_Wiper
c472f2 1 Vulnerabilities
afacba 2 Compromised passphrase and private key=Compromised_passphrase_and_private_key
77e5f3 2 Cryptanalysis=Cryptanalysis_
e28a2f 2 Exposure on multi-user systems=Exposure_on_multi-user_systems
468850 2 Not quite deleted files=Not_quite_deleted_files
ce352a 2 Physical security breach=Physical_security_breach
ad1f5b 2 Protecting against bogus timestamps=Protecting_against_bogus_timestamps_
135f70 2 Public key tampering=Public_key_tampering_
2a139a 2 Swap files or virtual memory=Swap_files_or_virtual_memory_
3b62cb 2 Tempest attacks=Tempest_attacks
6a756d 2 Traffic analysis=Traffic_analysis
--87af 0017901560340110214 Page 3 of Pgp60.cnt
f6b501 2 Viruses and Trojan horses=Viruses_and_Trojan_horses
c83efc 1 Troubleshooting
7df17d 2 What is an adequate passphrase?=What_is_an_adequate_passphrase
256092 2 Why did the Random Data dialog box appear?=Why_did_the_Random_Data_dialog_box¶
06a095 _appear
1ad033 2 Why is my key generation taking so long?=Why_is_my_key_generation_taking_so_l¶
d6b94c ong
6b1700 2 PGP Error Messages=Troubleshooting_PGP
c7c982 1 Glossary
7965a5 2 Glossary=GLOSS_GLOSSARY@Pgp.HLP>gloss
--3191 0011168189340110215 Page 1 of PGPdisk.cnt
5832b8 :Base PGPdisk.HLP>wide
1852a5 :Title PGPdisk
aeaf8b 1 Getting Help
4c8a2a 2 Contacting Technical Support=Contacting_Technical_Support@PGPdisk.HLP>wide
3699ba 1 Getting Started
d40346 2 About PGPdisk=About_PGPdisk@PGPdisk.HLP>wide
420647 2 Why use PGPdisk?=Why_use_PGPdisk@PGPdisk.HLP>wide
f6609d 2 PGPdisk features=PGPdisk_features@PGPdisk.HLP>wide
daea0e 2 To start PGPdisk=TASK_To_start_PGPdisk
2e544c 2 Using PGPdisk volumes=Using_PGPdisk_volumes@PGPdisk.HLP>wide
b28409 1 Creating and Changing PGPdisk Volumes
62a07d 2 The PGPdisk Window=The_PGPdisk_Window@PGPdisk.HLP>wide
1a955d 2 To create a new PGPdisk volume=TASK_To_create_a_new_PGPdisk_volume@PGPdisk.HL¶
2d1b8e P>wide
4dc1b5 2 To change the size of a PGPdisk volume=TASK_To_change_the_size_of_a_PGPdisk_v¶
9f2767 olume@PGPdisk.HLP>wide
9557f0 1 Working with Passphrases/Public Keys
f3d37c 2 Adding alternate passphrases=Adding_alternate_passphrases@PGPdisk.HLP>wide
33a536 2 To add alternate passphrases=TASK_To_add_alternate_passphrases@PGPdisk.HLP>wi¶
d7d29b de
330b9a 2 Passphrase quality=Passphrase_quality@PGPdisk.HLP>wide
507e56 2 To change a passphrase=TASK_To_change_a_passphrase@PGPdisk.HLP>wide
8dc500 2 To remove a passphrase=TASK_To_remove_a_passphrase@PGPdisk.HLP>wide
b8f180 2 To remove all alternate passphrases=TASK_To_remove_all_alternate_passphrases@¶
6fafa5 PGPdisk.HLP>wide
773cda 2 Adding and Removing Public Keys from a PGPdisk Volume=Adding_and_Removing_Pub¶
a87052 lic_Keys_from_a_PGPdisk_Volume@PGPdisk.HLP>wide
7bde35 2 To add a public key to your PGPdisk volume=To_add_a_public_key_to_your_PGPdis¶
f3f6f2 k_volume@PGPdisk.HLP>wide
657ced 2 To remove a public key from your PGPdisk volume=To_remove_a_public_key_from_y¶
5890af our_PGPdisk_volume@PGPdisk.HLP>wide
1ba915 1 Mounting and Unmounting PGPdisk Volumes
2fb518 2 Mounting a PGPdisk volume=Mounting_a_PGPdisk_volume@PGPdisk.HLP>wide
361e79 2 To mount a PGPdisk volume=TASK_To_mount_a_PGPdisk_volume@PGPdisk.HLP>wide
0df40f 2 To mount PGPdisk volumes automatically=TASK_To_mount_PGPdisk_volumes_automati¶
0bae60 cally@PGPdisk.HLP>wide
e079e0 2 Using a mounted PGPdisk volume=Using_a_mounted_PGPdisk_volume@PGPdisk.HLP>wide
4e65da 2 Unmounting a PGPdisk volume=Unmounting_a_PGPdisk_volume@PGPdisk.HLP>wide
ea09c4 2 To unmount a PGPdisk volume=TASK_To_unmount_a_PGPdisk_volume@PGPdisk.HLP>wide
837e42 1 Exchanging Disk Volumes
d29ecd 2 Exchanging PGPdisk volumes=Exchanging_PGPdisk_volumes@PGPdisk.HLP>wide
1f8746 1 Setting Preferences
6a2e86 2 To specify Preferences=TASK_To_specify_Preferences@PGPdisk.HLP>wide
c52372 1 Taking Security Precautions
653aeb 2 Special security precautions taken by PGPdisk=Special_security_precautions_ta¶
061a5e ken_by_PGPdisk@PGPdisk.HLP>wide
f80a48 2 Security considerations you can take=Security_considerations@PGPdisk.HLP>wide
c85bee 2 To back up a PGPdisk volume=To_back_up_a_PGPdisk_volume@PGPdisk.HLP>wide
11330d 2 Backing up PGPdisk volumes=Backing_up_PGPdisk_volumes@PGPdisk.HLP>wide
--ead2 00010b8a43840110216 Page 1 of PPReadMe.txt
dc0de2 PGP 6.0.2 Read Me
79e8c6 ···
a0581b Copyright (c) 1998 by Network Associates, Inc.,·
f5f5aa and its Affiliated Companies. ·All Rights Reserved.
39af5a
2eaf5a
87be90 Thank you for using Network Associates' products.·
3074bd This Read Me file contains important information regarding·
8660f6 PGP 6.0.2. Network Associates strongly recommends that you·
c77c57 read this entire document.
c6af5a
277494 Network Associates welcomes your comments and suggestions.·
788830 Please use the information provided in this file to·
a7c35d contact us.
98af5a
e73b0c Warning: Export of this software may be restricted by
3b31e7 the U.S. Government.
60af5a
19af5a
85789a ······***** ·IMPORTANT NOTE FOR PGPDISK USERS *****
deaf5a
3f8daa An internal security review of PGPdisk revealed a security·
1bd93e flaw. This affects PGPdisk 1.0 for Windows and the version·
b57864 of PGPdisk that shipped with PGP 6.0 for Windows. ·THIS DOES·
d5f4f5 NOT AFFECT OTHER PORTIONS OF PGP, ONLY PGPDISK FOR WINDOWS. ·
27af5a
5f8d20 The version of PGPdisk that accompanies this release of PGP·
f8d325 (6.0.2) eliminates the problem. ·After you install PGP 6.0.2·
ffd82d and reboot your machine, the PGPdisk Conversion Wizard will·
3f4a45 scan your machine for any existing PGPdisk volumes and will·
81d840 update them automatically. ·Note that the conversion process·
b7866f will remove any alternate passphrases and public keys (with·
db90b4 the exception of ADKs) associated with the volume.
60af5a
4d4fce You must use the master passphrase to convert each volume.
54af5a
3d2158 PGP will automatically upgrade older volumes as you attempt
35220a to use them. We strongly recommend that you update all your·
0b667e PGPdisk volumes to the new version immediately, including·
9bbc7d any volumes that may exist on backup media or network devices.·
995eef If you choose not to convert a volume, copy the data to a new·
a48915 PGPdisk and wipe the original using the PGP 6.0.2 wipe feature.
a2af5a
63c546 Instructions on how to run the PGPdisk Conversion Wizard·
3a9125 are included in this document.
a6af5a
cc2e68 ··········*******************************
fbaf5a
c9af5a
d7af5a
035e83 ___________________
42b7f9 WHAT'S IN THIS FILE
c0af5a
54d549 - New Features
9f7605 - Known Issues
84597d - RSA Support
ed0362 - PGPdisk Conversion Wizard
29e542 - Important Fixes
bbe3ee - Additional Information
0e8425 - Contacting Network Associates
98af5a
20af5a
f55864 _____________________
eb36d1 NEW FEATURES IN 6.0.2
0caf5a
a45c2f - PGP Version 6.0.2 includes a Secure Viewer feature·
828673 known in previous versions of PGP (Version 2.x) as·
474281 "For Your Eyes Only" or FYEO. ·A message encrypted with·
932f06 the Secure Viewer option is only viewable within the·
169ef3 read-only Secure Viewer window. ·The recipient of the·
913307 message is unable to save the message as plaintext. ·
10d201 The Secure Viewer uses a special font that prevents·
--1ec5 0009a5e72fc40110216 Page 2 of PPReadMe.txt
a6e706 TEMPEST attacks. For more information on Secure Viewer,·
b81a7f please see the What's New section in the PGP User's·
6ff1d0 Guide .pdf file.
dfaf5a
7b7eb4 - Forcing the Recipient Dialog to appear can now be
fbea37 accomplished by holding down a modifier key in the email
212471 plugin to show the Recipient Dialog even in cases where
7d9296 the recipients are all valid. ·This key varies by plugin,
2ba995 but is either Shift or Control.
b1af5a
e9af34 - The Outlook plugin now supports Personal Distribution
6cee8e lists.
cfaf5a
77dd85 - PGPtray now works with files copied to the clipboard·
22e7cf from Explorer. ·It previously only worked with copied text.
c5af5a
45af5a
991098 ____________
99779e KNOWN ISSUES
d4af5a
280a04 - The maximum size for RSA keys is 2048 bits. This is due·
7f279d to limitations in the RSA libraries and our desire to remain·
6f46cb backward compatible with previous versions of PGP. ·(Some
1f68a8 previous versions of PGP did function with large RSA keys,
ce708a but creation of these keys has never been supported.)
0baf5a
3d9392 - Mismatching your keyring files can result in data loss. ·
d6e984 Your public keyring file and private keyring file must be·
cd5a31 kept in sync. ·If, for instance, you select a public·
03a828 keyring file that does not contain the public portion of·
ea7f04 your private key and do not also change the private keyring·
80bcf2 to the corresponding file, you and others will not be able to
22f03b encrypt to exported versions of your key after that time. ·
c84438 In most cases, simply updating your key from a public copy on·
9db16a a keyserver will fix this. ·However, it is recommended that·
7db727 the keyring files always be kept in sync. ·A future version·
d62944 is expected to correct this issue.
a5af5a
d7c5fa - Using a Split Key as a public key for PGPdisk will not·
56207f allow reconstitution of the key through the usual dialog·
5edeb0 provided by the rest of the product for Split Keys. ·In·
cf77e8 order to use such a key to open a PGPdisk, you must first·
104d12 rejoin the key in PGPkeys.
a6af5a
48d4cd - Some PGP 6.0 features are incompatible with previous·
ee5457 versions of PGP, so we now feature a "compatible" export·
25ab33 format that strips incompatible features such as Photo IDs·
e3e0a4 from keys. Selecting "Use 6.0 Extensions" in the Export·
4e5e37 dialog enables these features to be exported. ·By default,·
2badb8 we export in compatible mode. ·You may change the default·
4f7ad2 in the Advanced preferences dialog. ·When sending a key to·
219218 a PGP Certificate Server Version 2.0 or above, Photo IDs·
fb8d28 always accompany the key. The default LDAP server in·
e19b19 PGP 6.0 supports this.
8baf5a
cba948 - In some plugins, the Extract Public Key feature has·
1db62a been merged into the Decrypt/Verify feature. ·When in·
45ce27 doubt, use Decrypt/Verify to extract public keys.
21af5a
f3a158 - Sometimes, after a PGPdisk volume is unmounted and placed·
f471ea in the Recycle Bin and the Bin is emptied, Windows reports·
957824 that the drive letter associated with the PGPdisk volume·
94ebcf is no longer accessible. ·This behavior should cease after·
74a773 the system is rebooted. ·This should not interfere with the·
6bcdec normal operation of your system.
51af5a
81a4f4 - On Windows 95/98, the Free Space Wiper will reset every·
6e5d3d time another program writes to your disk while the wiping·
0a6fd3 process is in progress. ·This is similar to defragmentation·
a11159 programs, and is required by the Operating System. ·For·
8cda4d optimal wiping, make sure to close all open applications. ·
9aca72 On some systems with very low amounts of RAM, it may be·
--670b 0002e30487f40110216 Page 3 of PPReadMe.txt
b908a4 advisable to also shutdown Windows Explorer.
5eaf5a
b16707 - If you experience a long delay searching the server·
4c8915 sending mail when using the Exchange/Outlook email plugin·
4416da with an Exchange Server and the Encrypting to Unknown Keys·
94e150 synchronization checkbox is checked, this can be caused·
b2f847 by the email account having many SMTP addresses on the·
6f8f0b Exchange Server or by having many servers specified·
6d27e0 in your PGP preferences.
6baf5a
6388ee - The Windows Explorer provides PGP with information
fce9b9 only about the target of a shortcut and not the shortcut·
76cdf6 itself. ·If you use the Wipe feature in the Explorer,·
bb4404 the shortcut itself will not be wiped. ·The actual target·
248310 will be wiped. ·When using PGPtools, the shortcut will·
906602 also be wiped.
c8af5a
14af5a
e51c32 ___________
22027b RSA SUPPORT
14af5a
0f36f4 If you are interested in using or creating RSA keys,·
f0460e please review the following information to determine·
eb3d0b which version of PGP 6.0.2 you need:
22af5a
520b3a Use ·····················Product (Mac or Windows)
30f8f3 ------------------------------------------------------------ ···
c4c8d2 Use existing ············all versions of PGP 6.0.2,·
58d1de ····OR ··················including PGP Freeware
5bf30a ·create new ···
d659c5 ·Diffie-Hellman/DSS keys
0daf5a
0132ce Use existing ····¤  ·PGP for Personal Privacy with RSA·
9e2065 ····OR¤ ¤   ¤   ·PGP Desktop Security with RSA
a224c0 ·create new RSA keys ······················
7daf5a
b1af5a
d729e7 Limited and **unsupported** RSA functionality is available in·
478314 the Windows versions (ONLY) of PGP through Microsoft's·
76a7ca Cryptographic API (CAPI), as installed with Internet Explorer·
10ca48 4.0. ·If you have installed the 128-bit version of IE 4.0·
c75773 or later on your system, PGP will use CAPI to provide basic·
622ecf RSA functionality. ·With CAPI, you will be unable to generate·
0af953 RSA keys nor use non-standard key sizes. ·If you find that this·
1c08ad RSA implementation does not meet your needs, you will need·
8adf4e to purchase the standard RSA Add-on. ·See the table above·
d4c273 to determine which product best suits your needs. ·
66af5a
cd9a9b If you have purchased an incorrect version or are interested
aec418 in purchasing an RSA Add-on version of PGP please contact the·
99ebb2 Network Associates Customer Care department at:·
d2af5a
096a61 Phone (408) 988-3832
e72a5e Monday-Friday, 6:00 A.M. - 6:00 P.M. Pacific time
33af5a
c2af5a
a3acb1 _________________________
93bd12 PGPDISK CONVERSION WIZARD
77af5a
ff8daa An internal security review of PGPdisk revealed a security·
21d93e flaw. This affects PGPdisk 1.0 for Windows and the version·
507864 of PGPdisk that shipped with PGP 6.0 for Windows. ·THIS DOES·
c1f4f5 NOT AFFECT OTHER PORTIONS OF PGP, ONLY PGPDISK FOR WINDOWS. ·
5aaf5a
897661 We strongly suggest you upgrade all existing PGPdisk volumes.
bb9d5c PGP version 6.0.2 includes the PGPdisk Conversion Wizard,·
9892c6 which automatically upgrades earlier versions of PGPdisk volumes.·
32a781 See the note at the beginning of this ReadMe file for more
b32fdf information.
31af5a
c923ea Note: When you convert a PGPdisk volume, the main passphrase·
2ed09d for the PGPdisk volume and any ADKs associated with the·
--3176 000eb34c7d840110216 Page 4 of PPReadMe.txt
194c8e volume are preserved; however, alternate passphrases and·
dc52a4 public keys that are associated with the PGPdisk volume·
05805b are not preserved.·
60af5a
01354d ___________________________________________________________
d50d04 To convert all of your PGPdisk volumes, follow these steps:
6aaf5a
43de3f 1. If the installer detects any previous version of PGPdisk·
b271b2 ···on your system, the PGPdisk Conversion Wizard automatically·
c5b9e7 ···appears when you restart your system after PGP 6.0.2·
867a46 ···installation is complete.·
8faf5a
3deda7 ···If the installer fails to detect a previous version of·
844015 ···PGP or PGPdisk, you can manually start the PGPdisk·
adafd4 ···Conversion Wizard by opening the PGPdisk application·
36089a ···and selecting Convert Pre-v6.0.2 disks from the File·
a1a580 ···menu.
5daf5a
9f105d 2. If you want to convert all of your PGPdisk volumes on·
c10799 ···your system now, click Next.·
a1af5a
d02d37 ···The Conversion Wizard searches your system for PGPdisk·
3685b0 ···volumes that have not been converted.
1faf5a
7af8a9 3. Select all PGPdisk volumes listed in the Conversion·
d48eeb ···Wizard.
4faf5a
e4b5d1 4. Click Next.
b6af5a
a556fb ···A warning message appears and prompts you to start the·
69c57d ···PGPdisk Conversion Wizard.
ffaf5a
7bab4b 5. Click Yes to convert the PGPdisk volume.
0aaf5a
6c6f05 ···The PGPdisk Conversion Wizard screen appears.·
d8af5a
109f41 6. Enter the master passphrase for the volume to be
8daa07 ···converted, then click OK.
9aaf5a
61632d 7. Click Next to start converting the PGPdisk volume.
2f69ec ···The PGPdisk volume will be re-encrypted. ·
d4e8c6 ···
55ad8d ···*** Note that you will lose all passphrases and·
de6f5f ···public keys associated with the volume (excluding·
fee0dc ···the volume's master passphrase and any PGPdisk ADKs).
c9af5a
f73065 8. Move your mouse around in a random manner within the·
762a01 ···Wizard window and/or type characters on the keyboard·
703898 ···until the progress bar shown in the dialog box is·
60974b ···completely filled in.·
afaf5a
cec4d2 ···Your mouse movements and typing are used to generate·
1f3070 ···random information used by the PGPdisk program as part·
ba41ec ···of the encryption (data scrambling) process.
04af5a
318430 9. Click Next.
2faf5a
b87c7f ···A progress bar indicates how much of the PGPdisk volume·
58b703 ···has been converted.
83af5a
1de4d9 10. When the progress bar is at 100%, click Next to finish·
9e49ff ····the process.
c8af5a
1f2388 11. Click Finish, then mount the volume by entering the·
632ba7 ····volume's master passphrase.
04af5a
c383a7 12. The PGPdisk volume is secure and ready to use.·
c6af5a
3a56d1 ····Repeat steps 4-10 to convert all of your PGPdisk·
05cdf0 ····volumes. Be sure to convert all of your PGPdisk volumes·
a4603b ····including volumes that are stored on network drives and·
eb0416 ····removable media as well as volumes stored on your local·
--34f8 0006db77d3a40110216 Page 5 of PPReadMe.txt
ab5614 ····drive(s).
7faf5a
19ad3d _______________________________________________________
f395d6 To convert PGPdisk volumes stored on network drives and·
cce79b removable media, follow these steps:
7caf5a
6893b3 1. Install PGP 6.0.2.
2faf5a
f7af30 2. Mount the PGPdisk volume. PGPdisk will automatically·
fb0d14 ···alert you when you attempt to mount volumes that have·
933434 ···not been upgraded. ·
05af5a
a42a0d 3. Click Yes to convert the PGPdisk volume. ·
34e8c6 ···
fb667d ···*** Note: ·If you choose not to convert the volume·
37f86d ···at this time, the volume is mounted in read-only format·
a4dd94 ···so you can access the contents of the encrypted volume·
a1256b ···to back them up prior to conversion. ·You will be unable·
22648a ···to write to the volume until you convert it.
07af5a
f5e933 ···If you click Yes, the PGPdisk Conversion Wizard screen·
05559e ···appears.·
a9af5a
48f506 4. Click Next to start the Conversion Wizard.
7ee8c6 ···
b3e267 ···*** Note: ·You will lose all passphrases and·
ac6f5f ···public keys associated with the volume (excluding·
6be0dc ···the volume's master passphrase and any PGPdisk ADKs).
6faf5a
131f67 5. Enter the master passphrase for the volume to be
5b5159 ···converted, then click OK.·
4baf5a
dd425d 6. Move your mouse around in a random manner within the·
8a2a01 ···Wizard window and/or type characters on the keyboard·
673898 ···until the progress bar shown in the dialog box is·
32974b ···completely filled in.·
50af5a
1ac4d2 ···Your mouse movements and typing are used to generate·
6fc4a8 ···random information used by the PGPdisk program as part of·
94bcbf ···the encryption (data scrambling) process.
04af5a
3f6daf 7. Click Next.
b9af5a
007c7f ···A progress bar indicates how much of the PGPdisk volume·
96b703 ···has been converted.
03af5a
e86f20 8. When the progress bar is at 100%, click Next to finish·
6f67f9 ···the process.
97af5a
a78767 9. Click Finish, then mount the volume by entering the·
25d7fb ···volume's master passphrase.
46af5a
435125 10.The PGPdisk volume is secure and ready to use.·
f4af5a
77a7d4 ···Repeat steps 2-8 to convert all of your PGPdisk volumes.·
45af5a
74af5a
1b572a _______________
0a5bc2 IMPORTANT FIXES
a3ec2c ························
d3e883 In addition to the PGPdisk issues and some minor issues,
91b133 the following common issues are fixed in this version:
92af5a
c6cdfb - Fixed: Long passphrases are sometimes reported as
5632c8 incorrect even though they are typed correctly.
e8af5a
177994 - Fixed: PGPkeys sometimes creates RSA keys that are
ca722d displayed as split keys.
b1af5a
c381c2 - Fixed: "Wrong version" error when using PGP with the
6a2cd0 comctl32.dll from IE 5.0 beta.
6daf5a
--6328 001a95cfd1640110216 Page 6 of PPReadMe.txt
d6c1c8 - Fixed: Mouse can disappear "behind" the Recipient Dialog
34d80b if Windows' preference "Hide pointer when typing" is
32659c enabled.
66af5a
8a276f ______________________
248ff5 ADDITIONAL INFORMATION
dcec2c ························
e35d0e * PGP DOCUMENTATION *·
8aaf5a
422ff6 For information on how to use PGP, including introductory·
925dba material on cryptography in general, please refer to the·
113c73 documentation and online help that accompanies 6.0.2. ·
8baf5a
e716c2 The PGP documentation is distributed in Adobe Acrobat·
727ef3 format (.pdf). ·Free readers are available for this·
73f068 format on nearly every platform including Macintosh,·
d515a3 Windows, DOS, SUN Sparc, HP/UX, SGI, AIX, and others·
094529 from the following web site:·
b7af5a
953136 http://www.adobe.com/acrobat/
b75886 ·················
72af5a
e8d5cb _____________________________
69a7c8 CONTACTING NETWORK ASSOCIATES
e2af5a
34f67b * TECHNICAL SUPPORT *·
85af5a
be670c We recommend that you read the PGP documentation before·
fa2b92 you contact technical support to see if your issue is·
b3cfd2 addressed in the documentation. ·
ccaf5a
5ee62b Please send any problems, comments, or suggestions for this
b8cdab product to our technical support staff:
40af5a
9dbc7f Phone ·Phone (408) 988-3832
6838c5 Email ·pgpsupport@pgp.com ·
25af5a
fa9e3a See our website for further instructions and please have·
50e004 your registration number handy.
8baf5a
99c6c7 Enjoy!
75af5a
a9af5a
a9e9d5 The PGP Development Team
--c75c 001c09dcd3d40110217 Page 1 of adobe.url
960ea0 [InternetShortcut]
c07cb1 URL=http://www.adobe.com/prodindex/acrobat/readstep.html
--e652 0015cf3f65640110218 Page 1 of eudora.url
960ea0 [InternetShortcut]
5c3ab2 URL=http://www.eudora.com/eudorapro/updaters.html
--5075 00020c1746c40110219 Page 1 of samplekeys.asc
e6f84e -----BEGIN PGP PUBLIC KEY BLOCK-----
e3874b Version: PGP 6.0b19
beaf5a
bab9bc mQGiBDWuajURBAD9bM78WP6n84FLrqKEYaN2uj6Yg+2LuVmQ9NOHyPUpK4ER8b0W
3556d5 Rgxvgn9jTivUzf+cYN+X7j2+pm77eCUHQzB1hj6LW21x2k6lFIGxvmYFkcW5pHqQ
d26a1f Z5uPTsDhew9PuCsBTMITH++kOpC4nGAhk0QuziMm8omZk1bvLHuBuOZH+QCg/+V8
dc910b KvYilkKIM+r2wfeBiA3twb8EAPyvv1PWk/RUbuJPgz75UxL3B6/2ALe6GrEk33dU
a0f7ce B+UxS0iq/Ts2PvoN9H9+lLBBD++6TbdgDbtwCvq9y4g+mAE6GG7OJUAsw8R3b9rX
e226c4 dm6nJEt5iDErHseAV8pZ3srMDEEOhGA2Iar8ZJGOOskfpRbBCBl+CXdJXdvoy7t5
68d1ec HkAwBACP5//BuUS10m0fUaJ4PRelhVEUpKZuo6E/YavpjrTQNEf8HDmIrxNToLtO
9f00b2 xJEwPnsbVZJ4rcWhWUIHmJk3XbaOe3NFTDRUuk/enJZjZnptOY7cR4xoXFQXf9/h
70be2f f30V1ax5QekVaJQWoj4rlcBjoPOuGmo/Lci3/0+OwgK1mzrtXrQrTmV0d29yayBB
ed4ca7 c3NvY2lhdGVzIFBHUCBTb2Z0d2FyZSBSZWxlYXNlIEtleYkASwQQEQIACwUCNa5q
5ddc42 NQQLAwIBAAoJEBOghfzXeyCUUecAoL3nq4gi9yy6vR/eAil275at5epDAJ9C7SE1
f4a5b6 Vlh9z5wgHG+IS+yJaqNKaIkARgQQEQIABgUCNa6T2QAKCRCsuxZLz3PsTIAOAKD1
8af73f hmmjRTuwpy3ac+uqDmDVrOHx2QCdHAXfhUy1Di0pjIwjd4IgsK4GWVqJAEwEEBEC
086d97 AAwFAjXGR9QFAwLP0wAACgkQY8tpHfrr1fzsNgCgxII/O4X0x8zO5TMciOOKNGGl
cb5fab fX4AoNv6+/qL8NZr/juxq8Nl8AXxdXNJmQGiBDN73mMRBADvRBtAsotxq+XNM6VV
d59cb0 IG9HgoPHrwaA0uqNtdLAWBic/5gae/HtlyiEl8w7R7VrUe+Sg/QBPdNnV6bQRIQN
f2d398 D+B5KTGpnUGiXT42C7sDUKAc2Au+VJnPHCieY3BGHbItXRIqC6f/nl+ICPOwnKNW
2b5e4b O9+DCz2gFNRFq0OYJft6yprwIwCg/0qvrUs6Be/OyjY8gshoiIG/g/UEANOyBGDd
e42131 1yeZcpIMdRB6eDyx+aDyqhGrm3dqul3grwQw2WWjqvUtEOBY8vwhBeGxEc7goCtz
6ecd1b DOTRqsDS65zh92DwLved3qyoXs5hRWiztOYn5KTlI2U+zf2Ldaw2AWOyTLxuOWY1
db57b4 xmn/l3Miyqx1HvMuN2RW2UFzajuYL1kf4qlUA/9zoXbkTqvvT2pPkZ5Y+rEWZO7q
a7973a +vQFaX1Vm/g8RJ8thUti+8stns8+ZmCVxnntvxqaYhZ1GobPWG8f32mpI/ph+mni
02ff18 pLn07DBSnRAu2aMXKO0uUlSRUBDNsxQLhMa5fuTAdUdpN4Zx4AUqpWKmyCw8B20V
266842 qpkunm3I4N90k2QKL7QfTWFyayBKLiBNY0FyZGxlIDxtYXJrbUBwZ3AuY29tPokA
937758 SwQQEQIACwUCM3veYwQLAwECAAoJEHvmW2mPrz4yK7QAoL/LWWCG8y7TAVtkrgY/
bcd274 i9jU5SdOAJ49FnppVmNN1bjvqWin1rrnK4SPGYkAlQMFEDN73nPw0cb4TimeqwEB
4ebb25 P6UD/0T12wkwj0rR0YRh8KxOCLagXeWWirANy7kToQ3CXI00EhiuxGCTQoebAHuV
f38187 wA5tpDkCVRoOMzIch5gVs6VhzmYS4mw+eT0Fs/Wjg5tMAwlqcF9LYzGQTAgiiOSr
041a75 V3DNXrsIJP3GW3i2uRLwI3I1A7e1m8mQmEzGxEFOZH3LI2x2iQA/AwUQM5S+SBe2
8c9e25 aTQFJUGbEQKrSACg4tb35/caVp5GX95EABzX3uQne/EAn3fBArV6Vss0C6gXWCdF
c045c6 88ZrtDBQiQBGBBARAgAGBQI1xgzHAAoJEEtrNGSdSWWEuHsAoPrsd03nQ/gSCiwe
97188d VrSWk9Yfac+JAKDayGw3AAZHyPd8wFSXAwovrlXPsbkCDQQze95kEAgA9kJXtwh/
ee04f3 CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4
cc7c27 DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/
1243ab Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUd
2c6435 D3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGx
55fc79 KUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkm
e7c223 uquiXsNV6TILOwACAgf/cNtltuSMCh3np3hIRk+3t6apPBZnsQgktBnrXEPORhLq
05dccf lJ0tcW0+v1ikxqjYK+2E9DRKk9tO/IaROXuxZR5V1Pccbz24LYk2M+Ms5Aqau+1E
6a7cae wT/EWsZJoTz+9x9l+u0vqipS74HZbl0zSdbF41dgyGJrcqRkUMG6H3AWD2/BQt1Q
ed7599 Qq6x9aY6A+O2gfJHzNcfBgDSUDoSoDQOzpx3whO/x9WMYR8a9Pn4x1xu9mBD2Ssu
fd5a94 OBkjAwXeXftioLCGIesmP3indK47c/OaLF7g3Y2qQcQcq3o4AyOLzrjE1use0Iq5
28f079 caTCSsakCc6wkOxy6AwjhS+5MBedKfbM6MaHD0GLVokAPwMFGDN73mR75ltpj68+
3cd9a5 MhECieoAoLP44YbsKCcDJa3ribdHQktNVkdCAJ9pWKO0iA2JSFRbLvoMhx+g5Z4L
10c1c3 EpkBogQzl1OZEQQAy8uiyWvrqP6zeuXdzW24C+zX6SnJ+vgSgywqGHvTjQWn82Qa
b4cf05 kWvyce0RNDjXYq9bVif9wyXWAaEaGeD0YHt7j0f9Izh9/bOBL1xV4X8XTRfryXGK
01f092 J5y2UKvL6SDCXu8jSUs1AcXtR9JTwZzqVpu2QsdmZc5abLCy4+cD4tmXB+sAoP9B
484539 O7hH9r4ayFCbdYJsRa/BV0qJA/4/NWXQVEoSD0bDx2lbQE7Kk2WG9ZTW89S4cXNt
033f22 L29Wu0/7OWYaOjwYGCesxocYb2jlQdLNwMmE6R9Mbisz590Tk98SdNhUqw0+XCBA
3118b3 gfHA6y+tZ9/+yBuKikcnUl6Qmm/iCREplSDC7c6EtaESJuP5TWGwKDULWJNNlAGP
c236c4 GV0DvgP/SjwKOT/dK/OZav7FkolczugPEokoLWQF9TmZEavWX0pt/9TXdic+PTwT
44f858 cJx4mQ8WGOpHrQhn+a1Xd+5BJrEzUWI5Hoj8R1lmTqsCs8cos+DHFsQyf0bQAlma
c8d1d7 vA5vyUZp7htX7AyRP/4nPepkpsVK5CdcwaKsxBeO1g46roiRcjq0FURKIFlvdW5n
3a12b4 IDxkakBwZ3AuY29tPokASwQQEQIACwUCM5dTmQQLAwECAAoJEIYbZfl/qDptvjsA
dc0aa5 oI7aWHrIJxUVDe09xkz4qBty/h39AJ9EZXBieKx38OV0Tga4VGwpW3NJx4kARgQQ
e0dad4 EQIABgUCNHCa9gAKCRBjy2kd+uvV/LEgAJ9OJNKx48SScXcSoBLoDm3WkzkifwCf
815866 dp+RqE6ggfeGxhNenbgcDnhHl0OJAEYEEBECAAYFAjXGDMcACgkQS2s0ZJ1JZYQU
94461a ngCfdDB+4eiajxkhNK6OAsPumeY3gl8AoLhSL53vuF3iaPM9I9RQjsTisgjJuQIN
0c2a7d BDOXU5kQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz
5aad32 0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP
56f1b9 xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN
561982 ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD
e88c3a ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI
3a6c43 PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICCAC5z0nFkiZzaoOpcRG/XQ312JgA
508c54 le55/Sx+56+HFcdYsllW7ZjYQ2Quv4PbvQv6uNDjxPBPPXbzyu7n0QOwRUr/dHhA
48f2ac 2Wm++dlz+yD5Sttjae5Z1vXyWT51MGTdH/LHBLPPEzGEEz4QaWdJzZ5MfXDKWwKU
2e1b12 hD5ClKnEFDrSfJeIYiYtsA8flJDn6Dn640sL8lkugzHpFSAyZWhIPach3qHP0o6l
34f704 ymS0zdVuBfyyU1PiMgmdYNiNSMH4A0852Olb6k9UHt6qApCwP5BLrv10EdANbTaI
203a96 Z4DBmHADu+svh/Cr4H1uK+zG/FMLTiqzWIil6YNzKlGpydm89yoaoTL4VhBdiQA/
--1514 000692bcefe40110219 Page 2 of samplekeys.asc
9167d3 AwUYM5dTmYYbZfl/qDptEQKmGgCg8foS0E2Wc7Sqs8rnPZWFgYrHr/kAoLjYWsM0
912f78 BQilsSWvTf8T7jovu/I3mQGiBDWUKJIRBAD6mmW8qxP63SsV/kU4iH2jOJJUxIya
3827df SrQdR7idjwGn5GmPL23O0Z2+0D5vDzr6sEWpwrTH56PojWlWJYUnyUgAnv4gt904
3c614c YcpvmBp/9KaBGcdOWdyve8ya9Hbi1gYAKtLTDizl+QUYAg1lmUmOXEATqnw6AM1i
7fb9db GhuxIaZumrQd6QCg/5gbN9pWouDzMOQ1pf0o0z4Hz40D/iITIsffaGDovahXMgsO
1d56a7 QIlSHQ5rQAXpsUZVXYEp8k787Sr0gFuY1rJo9u6gDM6PpoDOP22ZKKab441s1PPl
a9b8e7 VI/q57HFRC1EA75xh7/d7a1+2JWUb7zD4xn2RKweBDPcu5TKF2Q7Hd9k7Dqndg6e
7488b1 zzhPaRd5jTT/TFuevGHgTAwdBAD1NkuGf2mKxFw8vZzt7G5/acrS754oybx5fNss
0dfde1 KZTAOlz0K4E7whyKVPm/62T2X6jb7afyGOS2aDWmT4/B3AaEW1/sAvFEekyer365
dd0390 5wj+9o6OtxpUdTvhFqBAdVdNdv5F7qszd5rlMy2tOCP0e0KbBsE+82k+ijbNuOZz
7a70c1 mXS7B9HJ0/8AAAqOARAAAQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEA
e3aa6c AP/bAEMACgcHCAcGCggICAsKCgsOGBAODQ0OHRUWERgjHyUkIh8iISYrNy8mKTQp
0abea4 ISIwQTE0OTs+Pj4lLkRJQzxINz0+O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7
bffa86 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEI
6802d3 AI4AeAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/
583f94 xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHB
305f81 FVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2Rl
48f739 ZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6
4b63c6 wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEB
1c1581 AQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQID
26f43a EQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkq
782440 NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqS
855d39 k5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl
0109ec 5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/ANbbg4NLS9uaAOa6TnD9MUHPWlNG
ffc364 OKQxNp9aO9LkBckgYrOutbtICVVi7D06VMpxjuOMXLY0KPesQeIFdsBMfWpY9aBY
a38245 Bl4+lZ+3iaeyka+ciiqsOoQTjhsN6GrQPArVST2M2mtxeKOaNxxS0xBS/wA6QdaW
57c6f4 mAHjmijFFAEfPFKM0YoHPWgQuOaR3WKNpHOFUZJp4HvWHrN9nMKkhB1x3NZ1J8kb
fc9399 lwg5uxQv9TnvGKqSkXYCs1uCe596dcS+SOfvH9KpNMzn5c1wXcndnY7Q0RYMoU5Y
9a3e2d flUyyAjKPn2NQW+nzXDYAPNa9toL4+YgGk0OKkylHMWY7W2t6VtaTqMnmeROeD90
af671c k1j39pNYzZHT2p1rcrMoxw6mmpODugcFL3Wdkp9aM81nadfCZQjt8wHGa0gBjNeh
54aa0a Camro4pRcXZhjIyKCcdaKXrxVkhnniij9KKBDMfpTsGgelO4piK93MILd5PQVyby
a67635 +ZKzE5I5NbHiG78tVhB9zXNxyEhj6mvPxEuaVux3UFyq/cpzuZJSSe9aGn26ABmG
0c842d SaznG2Yj3rTtThRk4qOg6estTXjkVMBQBV63uNxH8qykkQj7wzTJtTFnHuAyx6Ut
7404c4 zquktTWv7f7VCeBkDNcmpa1vcEY5pZtZvJ2JaZgPRTgVHG/2hz5m5mx8pB7+9HK7
6e19c6 anO6sZNWNeAsT5kf5VtabfMziGTOT0zXMW1wE434I/hNXItRCzJsXLA9AOainKUJ
32b9e7 +RrOMZw8zr6MUxG3orYPIzUgNeseWGKKXPpRQIaKRnWNC7YAAyTQMjioNQkEVhK5
6859a2 XcAvShuyuJauxxupXjXd1JJ6nj6VQEm0Yp8smSQvFQHIFebvudrdth9x8zLIO9Rt
21d74c O2MbsAdqAxx1phjyc04mc290PSdhypI/GtW5s3n06OeMFj3rLhgMjcDAHU10+lFT
9b5266 b+Q3Q9M05M1oQc00zltpBwRW74f0t55GuJFIRRhcjqatajAlrIrGCNgfzFXNO1FG
a8a442 VUVQvtUSldG1PDqMrtmFq9ibe4bA4aoNKjL3ifNjBrotbEIG6TGSvFYWmIRdBl5A
4a807c 9fSlfQJQ97Q7a1J8hd3YYqXjPFQW7loRxyKm52ivSjqjzpaMdnNFJ+FFWSN3YNQX
9932c2 sqpauGAOQQAafu7VBexG4tyoHzDpSnfldhQtzK5xdzCEJwe9U3rQvonjnKyAiqLD
7a2faf 3rzFfqd87dCMVbswOSQD9arYA5NT2cg8wqaomGki1KckIvFOilmjfJ6e1OeFmQuj
ab363e YJqBQ6n96u/3JNI31ubCXVo0bNOxPrgE4qOyWM3SywhhGT3GM1Dbus5WJ0CxjqB0
03b1cd rZFqJNjRjaF4FQzbXdmT4qYG5t0HUR5P4mmaXbv9kluO3CDPqaj1AS6lq7LEpcLh
84d05a Fx7V0dvpyxWMdsxB2sGb3NbU6bkclSootsntFPl57E9atCmgBAAOg7Uv413xVlY4
83e506 W7sUGigdeaKYiDGKBnHtTM80ucciqIMnWNOMgM0YyMc1zMoVCVVefWu9+8MHkVj3
9db274 3h+G5cvC/lt6dq5KtC7vE6oVtLSOUKk0xCyygjitO50qeF/LRhIw6lelVDaSo+JE
b82d17 IPvXO01uaLXY0raUSLhuDUrRAVFaoDGOKtx5xg8ioOlCQMkbD5cmuksYvMt2dlIG
b2cd0c M4rIhCFuFGa6Kxw0e09xzQrFtu1kU44IoBiONV+g61J1FaSQxW0gadRLbOQGJHzI
355cb0 T0IPpV258Nqp3QzYB6BhxXoQnGS0PMnCSepg9CBRnnIrRl0K7j5TbKB/dPNUJInh
2489a0 fZIpVvQjFamWw3uaKbk/nRTsIhPPel+XgfrSFQKVUBGNwoELxnAHNWUsHkXnjNXd
d3e23d M00EefKBz90GtiK1AGdtRJmkYo5mTSVUDAqGbSo5k2SJ9GHWura29VqF7PHIHFZO
6ec76f JsnY4G40mfT5C23fCf4h2pEjDDiu8ayDIVKgqeo7Gsm58PRBt8Q8sn+E9K5p0nuj
a70540 phVWzOfjgKsDyB3rd035kYDk9OaUaOwT5jyKns4Ps/B6k1jqtzo0auixdQNJp8sY
24b7a2 6lTW/pUj3OjWssgyxjG7PrWOGeY+XEpYtx7V0VlALawig4OxQMjvXRS3uc1a1rFG
412a5d dfKuFI4FSz29veSiGdAwxw3cU+9i+TP4imHmaJh3ArpOY57VtGbTzvjYvCTjPcfW
7d3112 iurkjSd2ilUMki8iiq5+5nynm5YdRn8atafbi4uFJztXlqqjke1aulx7Yck8sc5r
f3d6df RuyIjqzciTdgAcVcVlHy55HFZlvIxkHOBV0IG3Feo5qDQsK8Rfyyw3eh4p3krnB4
356a29 zVe4tFvId68SAdRVa0vpLaYWt3yOgY1N7DL5twrY7HpSPbhlwV/SrLnYFLcoT1FS
eb184d BMjPB9aVxmGbRtx2kgg9KRIW3YdB+IraeAfexTlhVxnFJpbjTZTtoCMHAA9hirq/
85c94a KBS7AowBSgUCGXCboScdKp9DE3sa0JFzGR6iqSJui/3TQgH2bb3JY8DgUVXtHPmG
67d7d2 PoVJFFDVwucEG4xW5bKVt0XvgVgRjdKq+pFdHH9wDrWsjGJajXDAn1q/A2PxrPTg
00d145 AirMTHj1zUmhfQ+W+e3eodRsluofOjHzjkEVLEwPBFIZTbTY+8j9RSaBEemXPnWb
fa5278 wyH5lGMe9XrWXKIT34rHVfsusMi/dkXdir1q5+zhh/f4zUeRZq1EylDlKlU5UGgj
6d8ebd IqU7BYiSRZeO/epCO4qvInlncvBqaKTeuTTa6oQ4DK4qAR4dk7NxVgcGkZckGkmO
21a6d7 xQEHlTmU/wAWBj3oq3OiiNm9OaK0VmJn/9mJAEsEEBECAAsFAjWulV0ECwMCAQAK
1f429c CRD8i3fDuB4F5QGzAKC3GED0Not7FcCLMMnxgeo2YlJvUACfb57lOTDKoTAqOTFS
bc3630 9KRFI/8L3sGJAEYEEBECAAYFAjXGDMcACgkQS2s0ZJ1JZYQYbACfRYiJ7fLpTL44
203742 vblv441EDE7uW4YAn0pEZeUB6tNpm6/nk9dsP5kKiICGtCJDaHJpc3RpZSBGbHVr
10cf32 ZW4gPGNocmlzdGllQHBncC5jb20+iQBLBBARAgALBQI1lCiSBAsDAgEACgkQ/It3
69743d w7geBeUG6gCgxQFICbHPCqcX/tlp2mqKxJs1vYoAniWr/fbUF2dI1OT/ielmZYgT
--4af5 00074b6b05b40110219 Page 3 of samplekeys.asc
288b60 x1IpiQBGBBARAgAGBQI1xgzHAAoJEEtrNGSdSWWEPp4AnjFoixDUblVWrtXRixN5
75e478 gv1gOrq4AKDhj56XT2xqQjh6zDlwKCmEgShKwLkCDQQ1lCkEEAgA09/6w8Dk7+GF
271ddb HuQup4nrwDOtuMlSmQVWoML5myhXwO4Ayke855eQEK6rzepKaXZVk/Gg7eJyWrUf
26c8e7 M4jNuETlDh49F/pZyOAX6rhShH5Tn5nh/qNwlqBZPVTP+KS3RTX2bLzw7y3YWB+k
af7132 iuzY/s5sLHOCIwkgswGRS9naneGkdN4ZC4tt7CxoeMiYdkcSICkI1NxVKAaDhEgg
8a0f86 lizPM2ah57rHe8irgtx5drgOg1V9JKeuDU0pBNcHSPx2dw/dO+hI3r4342bw+ks2
0d9203 +UWes14E/Cmv0fFD9sE/pa06Od8/C2r+yhcpBDo8EwTDmfvp9CiKnHPBR1aIX/5T
44a1a7 g4cnPdINmQACAgf7BTEkFVjEBylIkEv0GRCRBeowxiDpel6F/Zdsq9mTaihTD7bv
48aaf9 YxkW7BUfNMxisjAaDSMfZGTYvhCxfQAd+3IVaPjYt/77yuBl7q7z6TlNlYY6mi4l
ca4127 U3ODbfsTVM7J+L1czOVQ0HAg9enkg0bhjhlOM3XRLH3rEknoQpGZcZ4QjPnJB3YT
7a316d BI1oMPBfeeK33OPGXWZ+j3lcyEUG1pl/OjjIVNQhjHlDjWUn/gQy7OfSH0aUHrdG
3f5596 gcDhOwNvnsYPS5epFqZ63S2r345qoBjnom65U2HMKtuS035gv47F7d0AT74pztmI
ab6f98 i0PU2vWrOCgBb8yV1u5MFbVP3357CoUe4q5sI4kARgQYEQIABgUCNZQpBAAKCRD8
862d48 i3fDuB4F5cJ+AJwPaAxY47ZP+wLZoW86/2myWs9pYgCg0wkytpd4giVbK3sfr7pn
b316c6 Qfhd7VCZAaIEM6E15BEEAPxEmSjiOsK8mUOQgeDDg129Kpz7AEeYJfcy7A0O9FB3
fa2ce8 eLo+SA3Y1EgKLCPk6UhtD03S3FQvYMchxulsGCiT7uKxQg3GKSSxdrUDBwPlMb/5
d0125b ePrPeamFmbEmIrQtxWphgSbpqmtx4Z2GWr/FLdaURXOKmbtXS5SUQNCaZ+X89tXL
da56ff AKD/Mzt1031lGIcYpWqjDreXnrrCEwP+PS8L+wcbX+1pZGJZPreP73gd/Aw2N39C
77dc27 GfAwlrrS/MKZUGcsv5qVhNLDLtRFwFzh9WLnmMnVdqKgj9y59xjOiIAa5AFKfjM9
076da2 FM0wpT5Eu5yhocHzEIkaG6SDMkTPABTV2EQReOC3+bKML8EkHLCMBJbqjWIhzQWZ
4aced1 9QhyN8CNp0gD/0dwea42xeYrLT2jSa8dTaOoRVUnFNF7MRPG9n2Lc6nMHllNX5OS
3dadf8 /dGgSw6jiJnDGvFurx5XGAGIONNsbz7p9g+gY2I9GmA62lKcAB9W3Gm89QJb8HCK
e27bef 0fvq5Get9e7/jF5gurFlCWXikfnVLtQc3f8sZ08p5jhpwm9wpXXhIaBC0cxf/wAA
2fd52c DRoBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQEAAAEAAQAA/9sAQwAKBwcI
7b4230 BwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+
0ba14e PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7
d1da10 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8AAEQgAkAB4AwEiAAIR
841796 AQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMC
dc17a2 BAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJ
61df5e ChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3
7769d1 eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS
582db8 09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAA
649e83 AAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEH
032b3e YXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
4e7d64 R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKj
90240e pKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX2
bec695 9/j5+v/aAAwDAQACEQMRAD8A9mooooAKKKKACkqK6uobK3a4uHCRr1JrzbX/AIiz
44dbd4 G7li075Y9pQMRz9RSbsXGNzurrxLpFnc/Z5rxA4645C/U1Wk8Z6IjYW5MnqVXgfi
e748dc a8Ta/d2yXzn1PWnjfKuUIPsRS1KtE9jfx3o0b7S8h91GRWhbeI9KuoRIl5GM/wAJ
0cbde0 PP5V4ZHK8TfvD+Bq/FrEUXKJ9MdqNR2gz3SK4hnz5Uqvj+6c1JXjFt4ruIZlkjuJ
3cd690 FYHqD/OvS/Dvia11uBU3hblR8yHjd7ihPuTKFtUblFFFUZhRRRQAUUUUAFFFIeBQ
a6bf5e ByPxKupIfC7xRnBkYFv90Ef1IrxaR5H57V6p4r1S38R38WkQB1SBmNy54yuR8o/E
b63bb0 CuT13TraMBIIhGFHGKzclc6VSk43OTBIapVlkUjBNPaA5pAjIQG/A1d0ZcrBpWbh
57a7c4 uKaHwOtW47UyjPJJqG5tHiySMUuZFOEkrkIlIPetXTNTmt5leOUoynIIPSsUE5qW
8209de GRkYbetNoiLsz27w741s9QRLa+lW3usDlzgP+PrXU9eRXzr50jLlgcryDXqXw012
8690a9 bUbSexmkZ/syqU3HOMk559OlCCST1R3NFFFMgKKKKACo52KQOwGSFOBUlNdBJGyH
f61953 owIoBHk1lIZru/uAc5cJke2Sf51Uv1MnJPNaNvYvo6XVrc8yfaHx7j1qvMyMw4rj
122770 m/ePZpRvTRz72Rz0/Smiy38FeK2jsJ9qXy0xhcUudj9iila2oRQKkvraJ7c8ZNWv
318c8a KIGcGobgHyWI7VKk7lSilE42ePy5SvvTUbFSXjZnb61ADXctjxpaMvLJvjEYBBzX
ceac4c a/DC++xeIJbZyALmPbnPcciuBV2HOelbfhie4GswrbjdPIwVf9knvQNas+gKKQZw
a209bc M9aKZmVnv4Uj37hisWbxZbx3Hl7h1ri7rxYj2hSJ8nFcdPqc7zl9560kxvQ98tNT
03eee5 hukBVhVLV/FFlo5AmyxPQL1ry/RvFM0EfzMeKoarrc2p3wdvuqe9K4aEmu+LLu61
cc6724 KWTyQqFzgE9s0211E3aEr1HbNQ6npnm20OoAqPtCH5P7uDjNP8N6Y2+edwfLVdo4
d31cb6 6msZKNrnoUZVOdLoyC6u7pSQgx+NVI766Z8GZQR71pajbs5bZnHPSstLFXXa2Rzk
723220 nvRHlsFVTUtGbVlqdzHhbiPep/iFbKQRzJlTlW71z9jYvDgxSF06GNu9dNYRqkWw
a15eb5 YGO1YVLJ6HVR5mrSOT13SPJ/fIeucisDBFen3dhFcpslXcDXPT+EY/MJWUhSenpW
1eda0b 1OquXU5K2Gk5+4jkhzwa2vDN19i1u1uCoPlyBiCccVpQaHZW8cguIHZM7TITyvuK
7e5081 54xPaag8GctG5GRWsaildI550ZUrOXU+gbLXrK9AEcq5x0zRXhdlrdzY3wdXbaOo
6c6b4a zRVamOhW0xDJKQckUmqRiCcBeM11Gj+HXjUsy8mqHiDRJ/M3IpOKLq5XK7HPJMV6
d482d2 Gni4weaVdNuA3zKRUrac+5SqkkGjQhJneWOm20+j2TTAcRAnJwBVi5jit4vIgUKo
bc450d 67eMmucuNVmtUtI2BAXB2kdasf2wFLNK2QetccuY96jKCS9CeSNFzkAe9OSygkQF
b49956 lDe4FVpNcs5VMSq2SMDI61Wt7+WycbmzGf0qUmW5QZuwWNvEcqDmrMUIR/m79DVC
cd5dc8 2v45iGVqvi4DjHcVlJsrRDpn8tgoxUV0A9jISSDjtRL+8IIpZUV0WJgSOCcGjZEL
171cbc WRk2e8WFwZ2JgiUkbjwcc1xYlee9a4fksxZq6Txbr1q6tZWDhtx/eFei+w9awYbY
97d34f yW5kRgAK7KMbJt9Tz8XUUmox6EMsibzgYoqJraTPrRXRY849ysbFY4QHAzVPUtPW
3f6d73 RuACKzpvFCpwpyaWLXRcDmuazOzmRmajYxwqTtFcy995V1tA4zXT61c74G2+lcDc
d9325d LOZWba3WrimyJSSNjVrhLgwugyVBBqGR4rlAqOAyjkHjFZUcpicNKzYzyCK6WCKA
86146b xRzr5e5lwwfow/xpSXLubU5e0bsZsUaIclxTriaIJzMv41ek2LtCxQpgYJJ3Zqob
f0f416 OEvvfLkADnpUcy6m3LJLRCaXdNHcqoJKP0rpIZf33WubjCi6DAcCti1l3Esaiavq
2db2e7 VTk0rG3CQxqJ1eXz3DHGDgUyGbauB1PFXrdflxjrXO2dMVpc8nC5k2+9dFaAJYhN
3fa13a ozW7pPw/eYmWSQYJyBVq98LTWgIUcV6Em7HiROVQqknzICKKsXNhcRyEbaKnmYc0
740d31 VuQCUodxYmhdUdG+Q8VsS+G28knmufnsmt5CgPetFETZqNftPGo610Gk6Vb3UIZ4
--73e0 0007d225c7040110219 Page 4 of samplekeys.asc
8e4bab wc+1c3ptk0rDc3FdxaPHa2g29hVJWE5XK2q6DaLpsjpbRkhTyRXD2qPcWZVchkcj
6e4b1f jtXT634oSOFoM9eK5e2uxbu+3Kib5lNTNNo0otKWoxYbjdhicCrBVsBelDXuOpqB
08a555 70NzWVmzs5oxW5MAB9auxTrEgUHnvWG12S3HJqxbMzvuJyf0FTKOgqcrs6Syfc+S
8820f5 eK2oSNygDJrAsGCjNbWnlpJN3vXJLc9COxctr+7bXJIlOFDfdrqrhUmsiXX5sVBY
627bcd 6ZbLI14RmRupqSVjIXA6Yr1Iu8TxZRtI4aaW3XU2ikAxmisbxFKttrhy2OaKxasP
ef235b RnVKzTWZbHUVy13o89zOzpnrXp82jxwWxVBwBVDTtNR2bIHWtFdGb5WeeRafeWrD
3e1a0b g4rfinRLXbIcHFdHrGnxQwlto4FeaatezvdG3t8kk44q1dkOyM/XYnuNRVLdTIzn
457235 AVecmuu8NeGGUxxXIWa4745EYPUD+pqppOlSQuo3h7p/vMOfLHp9a9K0HS49MswW
8f4fab ADt1JroUVBXZg3zOyPOPGOk6TpV8sUUBQFeShON1ca8JeQqmSB6V6n4kt/7RmcGE
50d78a SKWJ2kdK46bRktyxVGUtwBnNZSpS3R0KtDRNHPJb7Tg/pWlZwM7hQKv2+hSzvhVf
b6ad97 HeumsPCrRKCXSInqW5NZqhOT941+sQivd3Ken6NJNGD5mP8AgNdDp+iSoBsdWx+F
e45a94 aFjo1hCoEszSt7nj8q14rG2C/uXZR/sNirnh6VtiYYysnuUrWbdDJEjAyKOV700P
ed6247 sjLMe1agtI0dZCoZlz82BmsXxLILWBZIx/rTgAetLlUVaIvaOTvI4rU9BGu6ydnT
4da284 PJoruPD2l+VGJ5Vwzc0UrEcxtTfPER61n2ULwyMSMCrF7qMFlHulO0e9YNz4ysYW
8d4d99 I3Vk5I0jBvoR+LdSS2tyrHluBXKwaWlqBczLmeTkL3FX5dQt/EN+biVMW9n8xz/E
239253 ewrZ0PTDeTG/ulxGOVDd/wD61ddBLl5mY101LlLXhvQvIj+1XKBSeUQcYrdkidm3
7806cf E5QdFx0rO1HxLaaf8i/O44xXNXviO+vnIRtseeAOKu0pO5l7sVYuamrRMc3Ua569
ec4a7d Cf0rJURyyeXBG0zjqzZ60lvYXF27SSttUdWPQVJe3dvp8f2a1O04zJIeoraxncuQ
fc708b mKBSXdSY/vN0VT7etB1AyjdGCF7E965+ykl1ifjItYzgA/xH1NX57qMHy4vm29Wp
5f770c pEtmnFfuG5arsGqujZDc1ziHHfkjNTLMQoweabQJne2OoJdIASA/86sS20MwAkjV
1bee36 sHIyOhrjLCd1UOCfauotL/cqLL1PGa5qlO2qN4Tvoy+FCjAGBRS0VgaH/9mJAEsE
a7c76c EBECAAsFAjWrpqQECwMBAgAKCRAajihwXo3mqbe9AJ9E/JiHteLVc4g2Ef1bhGe/
cb4ebe iPYSAACguDzOHMLghmKbg9SSu3h5FIiTQyiJAEYEEBECAAYFAjXGDMcACgkQS2s0
ddfd4b ZJ1JZYT1UgCg0jXScQanrBdqLo1u43O7M8oRhGsAoM61snkeUakHEzqG5sUVfrRS
c7498a gWuatB1QYXVsIEIuIEpvaG5zb24gPHBiakBwZ3AuY29tPokASwQQEQIACwUCM6E1
53e97e 5AQLAwECAAoJEBqOKHBejeapl3MAn3x2ydqHD30s8oqw06fimriD2hIYAKCp0OWD
7fbda0 GMjyhVpJ4UoY+5HEMTJxcokBFQMFMDOoNGINkLCILJfdZwEBan0H/i1XeHk3yqE5
9b739d M7XV5d4IZygMmb1NrY8RYdsHi+974FGp4SvyO+isByNcmjmSrzA3nuDUNqvp7On9
df19ec 8P4SeQCZCcyudRe3d8zp6Tev//HVShkvn4cC4Vtw8LBPJfsmRP5OJP1ZBvhU2ucL
1a89fc We+Gfgz5zCI8rz0p3qxVbIMYHhlmbaGea64vZrmMK8MHo8FicImgF/m2XqvP4+Gh
bd708c BWM2j77bn7ugpGvH2YdeZp9ylMnWVmJrWzqPxslE2smnjh3KsNITX932JtgDgwas
a7af8b pBSIT/0N2jTUT1EQJ6inPl1UxOmye4LgEMw0IHWlTPYJydhnz/j+VNrLH+dK1FWz
6d47e9 QNXCmJt0aKaJAEYEEBECAAYFAjXGDMcACgkQS2s0ZJ1JZYSWgQCfRe+usPvPoLvd
990d31 DHfXR+IMg1NqGJgAoInDNFvnZrPHfzCLVQ92laaUWwZyuQINBDOhNeUQCAD2Qle3
b1aa35 CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz0AfGy0OplK33TGSG
d5aa94 SfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRPxfx2vIPFRzBhznzJ
e50589 Zv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvNILSd5JEHNmszbDgN
03ec02 RR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv88
46425d 4bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsi
5938a1 GSa6q6Jew1XpMgs7AAICB/0bejMAJ2H65nxKFA8p/JcTEX3u/Sw+2awGgggE1Cu6
267992 8+iZj1KY4178M6/YkdP/zjXNSaz040iaTQmip3NOxe4BmYn1V574A6/7WVRMHcBs
299f8c rCLT3nTlmhtd6nlx/cdXp5BYS3hK7ArZc3wA4pazNUg97GtOm99kJ+2U2JKjIF1K
9f971d BW3bJ1Vk0iPHAGRPG7dqXe7qVGlJadNZqrKXTwi3v0Xy7V5fbjVE3QyC8nildh1l
4470f0 J99xcqJyGugMfRru7dOjMY+ORT7teJ4zxI/vAyo6QRXWT85rV16Se824F7P28bVu
588905 ENsasnAfhwGC9AYk0IsVXghba6u2+rfXLVrO4HE8Kr4WiQA/AwUYM6E15RqOKHBe
c44336 jeapEQKCDACeOX7Mo/WRGzwV/qWhNclIiVqHmtEAn034tt5wuwdisjTeFgSyAfwd
7991ce mH+8mQGiBDOCKMERBADPJwOrw+bds39vbh3uGk6ZNS7JTedhdOCGXUvsOvYvTWj5
de7d64 VlhvkWOBZw0PlsBFHc6My1WsY30MCAZOtvh9Mo0UmZWncSil+ggOg8Kt6QPotG85
e9afea BO6l/xUZ3Bxx+uAVPiI5WONTmgdSR4vldsVuIMkJc/ckiyDlb5bPrlByDtixRQCg
c4f197 /wD4/wNQ2DrjMs/Flbv1IDaZhYcD/j6Xzw+vuC3ShFkt74YZxqpnOVFlYwj2u+0T
95dd28 mgnHcTiKJ09NHtsNlIcVZPC16WFW9/EDfOTC/9/ZVpAKC6FiLWhZB9iNsmWTucD6
ae5e60 EhaT3osiyfojP1JxKwfGHGaKwM28KlhxCI4ARa2yjIEiXA1FKfWH/jd5j/juuYX5
670b23 IZTWFTsUBAC7DKuAu5JIuCHZ9Jiy2vBLWRaH7N1TWm5KDWLlxxuLsQO7K1RbFZp3
ecc963 zjzc2wwe1N0OkOiW1NNymq/fKGByPMhGVvNUs9wAhixN9Ds1RyvvBFKFqbTTedDk
8ea49a MFC4/6HHVbzt2YhaVtpj3mtI6ZB8u3zKsVSk4iLSi/Ny5lMAZEtT3dHM6v8AAA2l
410323 ARAAAQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACgcHCAcG
86a221 CggICAsKCgsOGBAODQ0OHRUWERgjHyUkIh8iISYrNy8mKTQpISIwQTE0OTs+Pj4l
6c048c LkRJQzxINz0+O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
2e70d6 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAJAAeAMBIgACEQED
5d32ee EQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQD
a18d8e BQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoW
f507e5 FxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5
8cacd8 eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU
a7e630 1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAA
0b0b5e AQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2Fx
0feb8d EyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdI
b4bea3 SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Sl
3859ed pqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4
faeee2 +fr/2gAMAwEAAhEDEQA/AK9vqZHU/jWnBqRwOciuajFtdDdZz7G/55uf5Gg3E1o2
7a7ba7 2VWQ+/SuBxTOhM7SG9L9P51aWVmrjrbVlB5arlx4sstNgEly5JP3UTktWfI72Rd0
c76996 dPufGcVmXnibTdOdku7tEZeq9T9K8617xpeau5S3L2tuONqty3ua5x5mdyzsWY9S
7dbc8c xya6IYdv4mYyqroenS/E3TImIhguJRnjjFRr8TdNkfElrPGvrwa8yyetISa2+rwM
--4650 0008899191240110219 Page 5 of samplekeys.asc
f84828 /ayPU/8AhMNCuyALooW/voRU7RpcRiWB0ljPRlORXkuTVuw1S902QPaXDx+qg/Kf
d09c4b qKh4a3wspVu56DNbsO1U3jIPQU/RfEsGsgW06iG7xwP4X+nv7VZuYSrVhZxdmbXT
17a6d6 V0ZEi+USwHynqPSo39auygVRkxGcfwH9K0TIIXPtRSSEUVZJCkUT/NaT7W/uNwat
db387b R6xdWy+TdxiSP0cZFZhQnvz64p4lnWMqzB19GFNxuJOxav72xS28+2dkkJwIjyPz
13a644 rnLi4luZDJIxJ7e1TzkOwGPyqIxqQAp6frWsIKJEpXIcnGBT0iZz0q7ZaeZ3G4YX
d955c9 OMmun0bw+hTfMgIByue9W5WCEHJ2OcttImkt3mKHao4z3ofS3QxqU+Z+T7CvRG0s
9844a9 SQx26oAM5bipX8NpIQcY+UnI9ay52dToI8qe2bz2RVPBxSPayRy+WykMO1enweEY
f7d6c7 lleRox94Y464o1PwrHJdQSoBueTJ47d6rnM/YHmUEUomBjJV1OQehzXWWupT3VuP
00a2e6 PyJgOf8Aa961NT8NLbXPmQRfI3IPpXNpDcWerwI4PzOFCk9iaiaU0LllB+Rdlmf3
c4090f qq8rHrXcXXhc7cjHT0rDu9CeLPFc8ZotxZzTSspxnjtRV+fTiMgiitVJGdmZuecU
955261 jnEbH2ofiRh6E0nUEeorREFIruFSxWxljHRVB5NQkkPj0qVXYqVXitSDb0vyZLhW
732a40 UDYh5yOtd1abZ4FdE4A4rzqxcxyxqeBnnFelaQyz2ylQQuPSs5q51UHYuWsPPNas
092509 NsQucZqrGAGGBWhHIqpyahI2lIb5CjJ71DIi4xjOOlTb8txTWU9aoRRuo1ePBXNc
bd6278 V4ptFFv56oBJFhgfpXdzRlozjtXMa/B/oz7uhBpdRPWLOj02d7rS7aSQAF4lPP0q
af8be2 O9sDIp4H5VV0SQnSbVslv3QH5VrxsrDBDVwtEo4vUNOdCTtorrbvT0nQkA0U+ZoL
be327b HjEvMrkd2NNxTUkDnHrUgrtOcyp3Ambg9elTQZkKjGK9C0TwVYTabDJdwLNJcjdk
d87811 9RnpisrXfBDaLG93aytNbjqrfej+taKRUqLirlPw1pw1DUFSViI05bHU16XCiQxh
82adc0 I1Cqo4ArzvwjIBqKopySOa9HiUOmKmW5tS+EoXuqPassdvA00r+g4FVoX8RTEywQ
45978c ZLH+NgAK3PskVknnsMnrmqUPiSOeb7PaIxckj7vGR700KeupD9u8UWrAPp9u47lW
545359 zWxZXd5OM3UKx+gFctb+JNRvr8xfZvLQPtwx5PvxXYW6hADK2T3xRcajZXIridYA
613a1e 2TjiuC1oa1rc0kVtiG3H8R4FdL4mlYXEXkkhGOGFc1rV/qFhiKzVJomXPmjI59MU
4694c1 gktNSXwhqFzp9pJYXkm7ypSEPtXZQXaSgFXryv8AtaezuDFcQBlPzccMM+9btjrk
dc1e43 LoGt7hiw6xtwwrkqRfM2KLVrHosVxjG4n8qK5K08V2v3ZZDkdcg8UVnZj0PL4XR5
daabcd BtYHmrgFZFvxOmOOa18j1Fd8lY5k7npng67S+0y03tg2oZWH06fpW7q+nefbKpGR
f71555 cZDA9MV5v4S1uHTL0wXT7YJ/4+yt7+1ejW7T3Nsqpdt5avkKwyCPY0LY6ubmSPNd
1a99de BtVsfFUtsvAjJAHtXe28nzAd6wbqxhh16abZiVX6+1a9q2WyKGOmrKxtogm4cbhj
b9313a oacIIIUKCJQp7bajt2+UetW1tnlXdnimh2XUoJY2om3rGqn1Aqa4HldTxSXDCJsA
38e2e5 81UvDLNOI92AoHHrSKSKmpwi6tnCtlxyKzBai8sxJGc9mX0IroEsEkhbbIu9RnrV
7bfb1b SKyMN+5XAWSPLgdM9jSKdjgtXsy93kxhjjBqlf6NGkSy2bOHH3lJ6V0viRTBdqyI
6d9c73 GJ4xnFY88spgf9xj5T/FS5dbnHUfLJop6dPMISbks3OA3XIopmju7WJ/dlgGIJzR
a474a6 VpGEnqc1Au6ZFz1PWtX7J/01P5VmW3/HzH9RW0zAUT3KgVJINn/LQn8K6DQ/Geqa
729dd8 UkNn5iS2wbHzrlkHsa5+Z9zUzOKlGibWx6PfzmTU1mZsiZAwNXrRjgAcmuZjumuN
e54fb6 NspgclMqa39MmDAUzeLszo7ZiEzjpWpb3BMTD0FZEGDHjPbNWrZzscZwdppobdyu
304a57 zF5y+CcfdpXt57gjcKrySzgKbeMMF+9nqfpVi31GyKEXa3QOBkD1/ChDfNuineQX
f5a4d7 JZo4yybRw1YljNfQai6M7SnGTk5rcvr7SmLLZ2lzK45BckKfrk1z9lLLa6jOxCqs
a07825 nJXsvsKGCvvYoeML37PfwHaGJTODXPtq7OCDGvKkfpV3xjdpda1iM5WNAOKwaaWh
100bbe xVHeTLVjd/YoPKGHGc5IoqtRVWM7mVAcXEdaTyZrLiObhPrWjjJwAceuKme5pDYa
a086ba eTTo1DyhD1J7UAc04Fo3EyLuIGCPUVrRpqWrMq1Rx0R0uiRObNoHBADZUkdR7Vs2
e4692a 260kG4fKaytF1V9SuIlMXlxxwiNBnrjqa6sWYkixjPFZTspOx1UuZwTe5ZtLnKjH
bddc39 NaFvcKG7fjXOMk9k2VyVz09KnXUQwAztb3qTW50ICqxIxyacVH3lRWNZttqMcv7t
2461e4 iFbtVxS7cRkMfamJSKF0sm8nCdec1kajGqIZAQTit+eE5zJjntmue1oJbQu7NgYJ
b8bc91 60maOV0edXlyZL+Zied5oSQGqcrb5Xf+8xNCuVqzhaNAciiqL3BEfB5opohmfEcO
a17eb3 DVvziP4v1qpCGLjaMmtGKPP3wpPpjiq5XJ6BzKK1JbQFo2dj7CpQNpojUqcEY9BT
aa0b69 2XvXZCPLGxwzlzSuXdIuVsr9JGJEROG9vevTbIrJGrKwYMMgjoa8pj45rotC8QS6
b7ad1f WBDKDJak9B1j9x/hWFahf3onXhsSo+5PY7qW3Dqe9ZV1pzHO0c+1bdtPDd26TwSL
31b938 LG4yGU0SJ1yPxrjPQORlSaBtxDKR0IqWPXrm3UDAP0OK6IxxNlXVTWNrVpa20ZYR
47cb68 ruI4FUmS0+hkX3iy4SNmRASD65rl9R1i71TiVyEP8K9624tNF1Y3O9ekDy59COhr
1bfb20 mYY1ZSrHDY4ropwUkcVapKLtcgMSbCVJNQIA4fccbRkVfSILJtc/KePxqF7ZVLCM
5c8697 ZJ7GpdKSBVososN30FFTtEVGDGR+NFRexdrk0NusQwFxVyO3ilGAxVxUKSZ6mptu
174e53 8gr8rDvXfGKWx58pN7jWikjbDDcOzCn8kVIJXQYmTI/vCmoM+hHarM231Gng1ZiP
92aa59 HrURAI4FPjP8I6mmJmrpOsXejz77ZsxMfniPRv8A69dTN4teDY91pU8MT9HzkiuG
1ae392 MgjIO1uDwRzWlqXii81S1iguU+SEcYTBP1rGdGMnc3p4ipCNkd5GUuIUnt3DRyDK
16647e t61j6paySZZ2z2Aqv4C1uza5/sq/laJJT+4fPAb+6frXojaVYW2bhozIYgWy5yBj
e45ab2 2rjlTcZWPTjXjKNzgNWtv7E8LS+YuLm+AiRe4Tqa4qe0Uwqw+VwMHHQ1ueINbn13
d93cd9 U2nlG2NCViQdh/jWRcSfutgP1ruhDljY8mpVc58xQKjOwDdT4wIdxZTyOD6VLBFj
6ff599 5jTpH7Y6U7C5uhVZBLngGip40K/Mi5U9V9PpRU8qe41JrZn/2YkASwQQEQIACwUC
e7e20a Na0MTQQLAwECAAoJEIbqwhyCA522Iy4An2uWrR+n6Ohh91JEq1U3+9lIeB2aAJ9l
64aa7d dcTZDopPsaHhtoFawO0SeRIRaIkARgQQEQIABgUCNcYMxwAKCRBLazRknUllhCvQ
9e6d54 AKCV2TvGlunaXOzgkhPhMcyd6Le5XACgzF+d+SFIgVgwx+Uq/4yASsKUxVq0G0pl
fc9aea ZmYgSGFycmVsbCA8amVmZkBwZ3AuY29tPokASwQQEQIACwUCM59EvgQLAwECAAoJ
ac41d9 EIbqwhyCA522CWIAnRA3djO8x8jD4NPgv699IYyhrhioAKDImkqIDsCMcV4zbEGd
7d430a fiu/CD8s7IkAlQMFEDOfRRB3CJPMSJh43QEBKyAD/16SkJM4B8B2RkAsqZTxrffM
fd4744 HxNUJK1+opw4XaTgS1bCRlHRCjE/yMqO59qM/1uGVhLbZ67BIYezmtxqV5xiza0U
869ef7 7c2nzFFvUtC18exxy/NciYBAbjD9V9oAbPGhFH9YkRBErHbP81W4yODby8q/kSsq
72e8b2 n62A/ZQ+HA8/Z5WHIkRziQA/AwUQM59XoBe2aTQFJUGbEQI3nwCgjB1+yiwKfbfL
a7211a rv1ZXmA1tY165MQAn3d581WnoBn4qxhKMbdTOo79KcbfiQA/AwUQM8CIZl3U48Qi
e8426c Q7U2EQIJkwCaAyqDI4nJW2DznizMKJKxXkMCNfMAn11yZoqGA5qEHQVpDlXHeqIu
e2aab4 vjXniQA/AwUQM8Em8ZyMdxVqWP38EQJUdACggI1sn3LzqHa5TYqubBFHVrQOt48A
262a78 n2P/ce+R8pJtEb1c87EhQe2cF13tiQA/AwUQM7uzha1bFJYcJ7ZqEQKNAQCgxFbS
7a4722 jlY+lBLZilmbOZyaIMCVGREAoPkbnORtR+UV16Q+uBGB38INpNPJiQBGBBARAgAG
c1687a BQI1xgzHAAoJEEtrNGSdSWWEzacAoOKKONLz1gVbJFHZNKKMc6jFACoPAKDlPUSm
882274 CzF3nnUC9/I0F42Ba6laQLQfSmVmZiBIYXJyZWxsIDxqZWZmQHByaXZuZXQuY29t
--4cb9 0002b2ddf7040110219 Page 6 of samplekeys.asc
784c78 PokASwQQEQIACwUCM4YEogQLAwECAAoJEIbqwhyCA522AdIAoICRTAKo+Sme4XY0
ebd80d vSjQuvGN5rArAKDHpV6Cv1C4ELlATbWPy0nBxIMu7LQfSmVmZiBIYXJyZWxsIDxq
bfde6d ZWZmQHRoZWhhdGUuY29tPokASwQQEQIACwUCM4YEsQQLAwECAAoJEIbqwhyCA522
afc1d5 WPgAnirQJ3EJRnUI0zJuMRdXs+iUF8doAKCIAXdqjLnTifuznLaa3rLeu73D+bQj
2fbf8f SmVmZiBIYXJyZWxsIDxqZWZmQGxpcXVpZG1ldGFsLmNvbT6JAEsEEBECAAsFAjOG
fc2796 BMMECwMBAgAKCRCG6sIcggOdthF1AJwKmCYGE17OP+eigG0Q336vkM+gywCgnqEi
409c37 bjQm6AzdzfmI4TCMFnqF6CS5Ag0EM4IowRAIAPZCV7cIfwgXcqK61qlC8wXo+VMR
4a5d62 OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf
c4270a 3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g
2001e4 pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA
fbb74e Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD
5d88f8 GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH
b51700 /3Teyhf4f5adiGQYvs2fSqYa91eIpdPjvNAOYpiyFZ6DWRqT3bbZW3Q1cxEzh/zB
76e1fe d5F7oj0LtG/TebqslFJCL6idXsDE/XVnwBBCXP7zuOcs97L7W91pD7rDvO3nCa9J
85c15d lcTPpiYZJFLidkeup3mkjXc1/0icbIE+zEKIcwMDwgw7rkfAXAUdZ2Wa3FojSKVI
ccf74a xifp11C7RTuh5nn9oQpmEjHLptaMTT5aU07wKof+g7uUH0MCkxvJt9fofdrRQqh8
9d3db4 EzAwnt1KBVCfPJcUSRkP7bUvt6fZ6T7AI+NEuBRTbVOvz7la4bLoEmRmmzFURgpP
6f4180 SRiTBx3batDNBM2nE5OSJWGJAD8DBRgzgijBhurCHIIDnbYRAtasAKCBiAt2bYO4
87f8c0 vcxFP2EZ9nb+teKz2QCeL69UkYQOL47A3KaE5FPTcevbZhqZAaIENBh1exEEANmJ
dd962f 3IN3jcnpEHJXeE2+A25XMq7qWq+l/X7X2YVPFxbLFcfXHI2iQNZAVQjrCcWJOOxK
4c985c 1QtYdVGvd8TxXTTFy8Ca/o396ASGnpwM4AzoMkGSzrovroxORmQaFUIEooTmxlnL
811247 jvp4M/AiK1VfiOC4Vy6uxGkmd9wX/DjFSRorfeoxAKD/SKtK7eVnYDVWmOXttoRb
b76eae ndKYMwP/UkyJQHW4vyywlHU1L80h0zntTgR5ZCe+uLpSiIL9wDB4spA4vnXcm0n+
0376a4 TUKq/QbvwifQpW9mVfSxxE44JvEj+wbfxvKI3NwI6rwezsn4RvFQyg8IkPTsFJKA
a0dd4a mGe/rJ1a94xbGir2A49xh03iPr4w/7CPDoHN5px33IMP41i9FJsD+wTchCCMpTFO
13df99 LxiiN/1nBcmnM4qRF9TzPBsFvX5hJ+zgmiJXjeMaiHvx7JqbtaU30qaeiEKf3G6F
990ff2 oWbojmJcMLgUoUPw9h2ps/MpYtBnwiEZ0u/88nLNyyOceJTZC2vYF8wZdASfaN6Q
8cb532 vxTMewKX39H57iD8EacplY7PHvulau4RtCNHYWxpbGVvIFNvbG9yemFubyA8Z2Fs
add950 aWxlb0BwZ3AuY29tPokASgQQEQIACwUCNBh1ewQLAwECAAoJENNilCG+0IQWU2wA
376aa3 l068pAgGIrKrI0/9yisvBzal7eoAnjFQoeXvNUV2+7LQgaX37IRFYT8YiQBGBBAR
841d12 AgAGBQI1xgzHAAoJEEtrNGSdSWWEUHkAoK9p5FLZliy4U7FleBQ90TOZBGi8AKDC
ce2aa2 Tq7nji27zMqhfjS7nUCujOkOIbkCDQQ0GHV8EAgA9kJXtwh/CBdyorrWqULzBej5
8ce380 UxE5T7bxbrlLOCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1
b58c9c WV/cdlJPPT2N286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01ue
884ece jaClcjrUGvC/RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJ
cace0b I8BD8KVbGI2Ou1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaG
a39278 xAMZyAcpesqVDNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwAC
24936b Agf6AiH2f4dyozNT5yDp19tx4hCSDuN6CUVkM+tOstYIeqN6yyc9lfD7r0wk495k
cae642 VeOUU/E7u4JaEiP4d7DuSxi/mE8Y6bXQR8hE7h4CsvjKJeLDph+vuAxvCRam1r3g
1a537b T30sGJgcXlcyKpgmV6f5UZWX0im7wPNGhGGlz9DzgjFypEtNyDM3XQlB84Ao960M
bcd9db KEc6D1zal/NTQio7mhCqAddd/YcTZea6vGy5u1Dq/A+CDaHp91jE8BLzITesLcQK
6245bd kdhr+8fKs3m1esAMJPnb2aFjQo11u0Sm+J/+vbvljxkeMmZkueWBt0U7Io3pMEyd
e43b24 hW107ji2CITxCd9yOWlVwxGcJ4kARgQYEQIABgUCNBh1fAAKCRDTYpQhvtCEFl8e
3a7220 AJ9kL/mXZg3QEpy9ucjqSxQ/IoT3eACgxi4kuDW/O7Nq8y1bK1OUAtevVWWZAaIE
9c9c46 Nauk3REEAPrqaZPiyHmF1zARZHFh4ts5jEEtibZPjGzEF9gYzhEQ1j8jVz+HPgB8
5b04ad gaQ01UpAuMZiE0YOXZ45i2W0DONOzcfAFGHZ1nW8VzuAQLTA+sy/FvBg1jgf41qu
043b88 eMGN4KbaJJYcypcJYh3C94/2CfsNNyh2OCjciP7I2dLo2BbF96OdAKD/eeve0RK3
2e4164 k5zUIsWH3c4NRpfE+wQA1rDCwzbbu3CAKVIoYXbY9+ueaNt2qck7zH8vwi0MCxWn
873a8a TwSmAO8WlrFZJJ+ojQEYpVCf5syyB/c+LASAQbp+MPXMexhL/XDYLL0ARnluPPoT
c1eb01 W8fctz3cj32u2NMpurnZXjT2J46M5DSbo3uQcISQV3EzEsnfH4e8wjYn6w7avTUD
99ead3 /iIU35kklG4oxshtnli6Q3OOQ2IWCO6kxRZR6Du2vNBXX5nimz8FwCze200bJQNx
935cc3 agUD3FgzyRwaFcywPzR+bESrDWOvLhGp69Q0HAnAxpKG0xN6vlPctfRSOFU1JI9Z
844c1a FCIEiuZJ9A2/7GcytnR5ejDXe+GCUpjSEz1eAGjGG5VPiQBhBB8RAgAhBQI1rQDt
24077d AgcAFwyAEbUa+zRB/rok1s2E/e0XpUZR26OcAAoJECQ6gdj6pyJyow4AnAoAZNGy
c80ed2 OC5y3kK6MN3ZrnhI6ePJAKDO9OXNZq5mMiO9mGSGDyomexSsTtHK3f8AAAuYARAA
6632e9 AQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACgcHCAcGCggI
3d1f0c CAsKCgsOGBAODQ0OHRUWERgjHyUkIh8iISYrNy8mKTQpISIwQTE0OTs+Pj4lLkRJ
48e919 QzxINz0+O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
aed069 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAJAAeAMBIgACEQEDEQH/
79d418 xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUE
bb2111 BAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZ
26ed6c GiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOE
d687d1 hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX
697f4e 2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQID
faac81 BAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIy
11dedb gQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpT
8430fd VFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeo
6cfaff qaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/
2066b2 2gAMAwEAAhEDEQA/ANzbRtqTFGK0PMsMxSY5qTFJtoCxHtpMVLtFc9q3jDTtNkaK
ec9c19 PNzKOqp0H40AotuyNzFRu6IfmYD6muAvvHGp3Lj7Mi2y+nUmsqTWL+Vy0t0zZ7Hp
ca6074 U8yNFQmz06e5RIiUdMj1NYZ8SvBNtuY1KZ+/GciuJN5cKc/aX57Zp39pStGUbb9Q
2bf5dc OTUuXY0jhv5j0uG/gngMyNlQM4HpVhGDjKnIPIrg9Bv2OYGIGDxXXaDIZbN1Jzsc
--ab59 0009bb91fd540110219 Page 7 of samplekeys.asc
746ae6 qD7VSdzGdJxL2KQipSKQimZWIsUU/GKKBF/FGKWlpmo3FGKdWV4h1iLRdNe4YgyN
742e23 8sSf3mpDsc54w8RS+cdKsZNnH76QHn6CuLkCxjag69SaSS7lmkklY7nc5ZzSQb5c
eeba38 gcsTgepNZttnfTgoqw1pFX5cAn1NR5YnO8c+2asTWpgYKy/Me5q5p+kS32QF2qP4
94a4b1 sUro1UW3Yx3Zumc06N9pGea35fDRTndWddaRJCpdecUKSG6ckMtbpoJCyY3ds13f
6e1aa8 g+7jayeLdhy2eT1rzhXIf5uDXQ+HLnyrryy5Afp9aa0ZzVY80WelY4pCKbAxeIZ6
69d610 4qQitDzxhGaKcaKAsW8UoooplhjmvLPG2rf2jrTxxvuithsX0z3Nej6xcG10e7nU
58e26d 4ZImIPocV47HF5oBJJZ3wSfSokzooRu7lYK5HcA1u6VYi3gNxOfLJHyDGT9a1bKw
ffa876 gG1vKUsBwSK2rS3jdhuQNjuVrGUj1aVLW5z1pok+pTBwjbT/ABP1NdlaaLHaWixr
4bf792 +NaFikUYHy8+pq4/lBeOajc30i9Dm7qx2qcDIrGurXaTlcg9RXXXI3Kdq8ViXcfO
d005b2 CKRbs0ef6zZfZ5g6D5WptjIVTepw0ZDCtzXbUyQgDgg1gRL5SvnhhWqd0efUjaR6
ea6a24 1ps63WnwXC9JEBqyax/CQb/hG7UseoOPpmtk1ueO1ZtDaKCKKBFyj3opcUyzO8QQ
76c908 +doF8ncwk15Pp5BuFjI/iBr17VY2m0m7jT7zQsB+VeQ2aNHfxqwIyeKzmdWH6nWx
5246ae OsMW9jWrpl/ZKwV35JxwOlZsNoG2zz/6pPXpVv8AtrTIpYoF0/JcZRtvUdM1ha56
43f859 kZW3OuiihljDRsKVbX5vmasNtQksm5XABwV9KsTa0RZ+cnOaRpqWdQmW3jIiTe3a
60e9db uYu5r7/WNbFUB9Otad1e3dtaSXMaCRo0DEfWsyDXbu+t/MuYlClyg2/z9xT5SXKz
98cb96 sZ96yXFozgcY5z2NchIfvMeDiu/vrELC0ij5XXmuKh02S9vWgjBLbsdOlVExqRba
084f0f R6docIg0KyjHQQqfzq7VTRo5odJt4Z+ZIl2E+uKuV0HiSTUmmNNFKaKZJbopcUYo
2be275 KEZdyMp7giuF1zSRFcx3MMQAhwr47Cu8xWB4glaC3uYxFuWdAd3oRWc1pc7cJJJy
f1d466 i+v6FGIiWxERUbSOauWtpZqEkmijkeP7m4Z21n6Y26FEHORW7bWfmEEjNc9z14pN
85913a XZlagWkck8DGQKSJd+jyADPFWNegeKRYogNzDLH0qzaaeY9ODeYmCvIzzQNWuQaV
35cebf cH7OpcbgOAcZxUtzHC+GVBgdgMU/QYVaCaJ1+652n2NWri2CAgce9J3BJGDqUm21
9ffb91 IB+XtUml6XHBo63MYAd28xmPU81W1Y4jdc1LpYMttbxLKxJyCv8Ad5pxIclGd30N
4fe49b +FdsK+/NONOxgAelIa60fPTlzScu43tRS4opkFyjFLRQaBjms7W7KS9sSkS5kB4+
25e9f0 netGk/nSauhxk4u6ON0dD5e0jDKcGuotpFjj3t0ArCnhOn6vKmMRynen49a2Ld1k
9cda68 t+gP1rkkrM9ylNSpozLx7i+vDtUqB39qVrO58ooCVGPXjFNvLSaSclbhlU9Vzimf
839dae YEKhWunP+zuNNG6Vyxpss9k/lMuVzk1rSyCaHcM1j2tikb7mlkYDoCeK1JZUjtcD
7ecaf6 jNSyXocxq/3ZDW3pNgltZwSEHzDGM57Z5rA1GZWnjRzhWcZJ9M1167SilCCuPlI6
0ffe22 EVtSXU8zGVHeyDFIRTqStjzRhFFKRRTAt0UUUFC96axCqWYhVUZJPQCnVzeuahHq
89900f Mp0q2l3Rqc3Tp+iZ/nQNK7sZ2r60up3cbWkT+RCSFmPAl9ce1XbDUEMfLVkvPG18
5ad517 lqmAIh90dqnmsnQGWA/Va556s9WgnGOh0EMqyD5uatfZ0ODj9KwtNvlUAS/Ky9jW
1deb3e 0L6Pbwy4+tRax1qd0RXUiopxxj2rMur8LEctT9V1CMrtj+Zj2FZUVlNOQ8oIQdqV
315de5 iZSvoinIhuCZZR8p7H0rS066l0GVY2dpNNkOME5MBPcf7NJd2+23IA7VYtUWfTws
b77027 qA5XkeorWDOPEU7rU6XgjIOfcU2uZttZuNIRbR7N7m2jGFkR8uo9CD1rasNYsNSH
d87d40 +jXAL943+Vx+Bra55ri0WzRSniimQWqZNNFbxGWaRY41GSzHAFYeo+KYYpDbaYgu
ff279f 7joWH+rj+p7/AEFYz2V3qMnn6lcNM45CnhF+i0rmqg2aV94oN4WtNIjZg/ytdMMB
63c960 R/sjuaq2VslupiiG0D9fc1PHBDBHwpz2NOt1LFjjnNI2UUjGgtSuqzPjljW7CmQA
a8bcad KYlqDdMe55q5HDsbH61zy3PWpJciIBaIWw6A/UVYFhZBOUOfrVtYt68jml+z56ik
9b6f20 DSKP2SBekag0GHI9Fq95LKc7RUUsZP1pMpIzLiEyAgDiktFKRqg4wOa1Bb4jLv0A
018118 qlEoUHGfc1dMwxDVkVGUCZt6gqetV7vSLe4fdsAI6MDhh9DVtk3TMCetORSVwe3H
5b3d82 WtjhM6O61rTOIphdwr/yzuOv4NRWkV4+Y5HtRTI5IsrwwJAvlxxqijoFFWFGOPTu
255ddb aMAP1J9xUjLt+YEYPWgobgbCG475p9ohaMue/aq8wMmFQdTzVqJ0jTa/5UADDy33
839391 dhWhGAUDYBBHaqEjK6nGR7060unt4zG6syf3h/DWU49Tro1LLlZqxYzjtUrAVWjl
20c725 VkLLhuOvrU+8Mmc4b0qDqFOMehqNoxnNL5quDtPK9RnmmeYQrGQYAGc+1IRV1OYr
f291cc abV4ZzjHtVaNNkYz1IpLhjcuS2Ru4UegqNVZTgktt4zW0VZHFVnd6DcYnz0IFJIN
0ddac6 soYcK3U+9SAEcnP+FK674iOOKsxI8cccUU0NxhuD0OKKQH//2YkASgQQEQIACwUC
d738c0 Na0BNgQLAwIBAAoJECQ6gdj6pyJyNAIAnjaKrceV/0ty5HteaE/R7k43jmAVAJiD
2005c9 7i+fFnO5ozBnZDG2u+IlwmAIiQBGBBARAgAGBQI1xgzHAAoJEEtrNGSdSWWE/1oA
d00da2 oPXq9vpJJIa5M+WWG+tz8k3woyotAJ4yT/VSD2BoGbWSlVknzPZ9P3PsD7QiTm9h
fe2fd7 aCBEaWJuZXIgU2Fsem1hbiA8bm9haEBwZ3AuY29tPokASwQQEQIACwUCNauk3QQL
d14915 AwIBAAoJECQ6gdj6pyJyMFUAoPrv3UvBVjCZi0HWr1FhWeccbsQpAJ4sYOapkXLy
6e73e5 3K5+MtgoLHXuPOMUcokARgQQEQIABgUCNa0u/wAKCRDtF6VGUdujnEDlAKDwlq37
f69ca2 DHXSkV8JEE61aESzJ7BE3ACeOKsk0ZHa5utGJonLvMbEABKAiemJAEYEEBECAAYF
8b511b AjXGDMcACgkQS2s0ZJ1JZYQq9gCgw0U11uxZ6Si9F8gN/aP/N0SgRpEAn29j55CC
260939 LUKWhb9uJUF7XvFeF6/+tCZOb2FoIERpYm5lciBTYWx6bWFuIDxuc2Fsem1hbkBu
0e9f38 YWkuY29tPokASwQQEQIACwUCNa0AbgQLAwIBAAoJECQ6gdj6pyJyioQAoIxv4QkX
84eca0 WyWqUt2XgiNXRqajyEP/AJ9AplTk+fub4WKTwvjKdz69wx1R1rkCSAQ1qwHwEAjp
fe5370 Aa71soLo1KuuEgZDykA9tX8sN5d+8CJR6f0hPgpjJhSKcg/+erhmaZUkwQ++7tgT
1e44d5 jrFXUN33Usykcz5azOPY0HbrjIyeROhL2UM73YNkUxVxb6/fliU0NcInrJ5BpZCJ
35a49a tdSKs+s5Oc/aVec7W82pt/R2SSB5FkGGdZ8yykKBNAMSAGBBJdmfngfR0cEkahhb
b91513 t5F6iZW+ZUWPDOndryan2Pwj9YG3zw7LFKJ+t/ubmRdDQgIfavchwNxurXhuVGEB
ef4b4f hNKAElGnK65qT8TQoTfhKbxUvKO62EEu12HCJZnH3RLPaChVKCJXPj3PmYUWNu1q
7666bb 4Ku9T9VlASzYVjVuj+AgEtYw96fIIl8SNpzMxqLt4QBaaD+M6KDWCsbKOv3CbwAC
307c59 AgjmJN/Gr+K486EI38vRZ0gG0m0axZKbfUTmj2gRmT1B37oCv7Jx65m9VUDpVH0n
eb4f30 +sKzcNYHDJxtI8+nFus5AR0Gup+WgY5ZaHftEoZRPhDaVqXz3ewYB4qJav3FUXCn
1479f8 jWAh7MiwZhS0wTDsONUitz5N361kV4dGqMOGtXbnC6AcqMl86SCO1Sc2wBDofRtu
9ab922 grg6VNtc8X6bxxov3/uYTiLPcQ787gjTkNSs1IGM9d9ocRb/LZYjdF0D/+0FUal8
2e232e VEDcKeKgMTV4ZMYKF8avNR6EZvf4yCjgs2eJoOIwj2942vUy0kGU4n4LXe+X5jZW
6557bf /i7fTCmebq7LNuooxwfaywjrFkhjUfLbcEtX9CKWO522hhLK/lZWw1u0kBU0ECW3
22eb96 iQBMBBgRAgAMBQI1rPylBQkDw7iAAAoJECQ6gdj6pyJyhWMAoNS+RYKC2Kgz3BNP
52761f MwrCpv1xsum+AKD+iLkDQFfiq2WgvhSlzB9KZKkCKLkDMwQ5brpwEAyRAfep/JGl
764df0 ORHLF1DbTUaeB0mVjHhL+ZVEZ/arVQQ4nid7nRGmjItBYhc8n7BO2rBkq86v83/d
9be678 uL33IZOJwAm7gHOwJWvy/+j3YkBF+5Gk9ORQxE+0hO9KeleSNmwLe/F/p/j0saeR
--5edb 000724e62cf40110219 Page 8 of samplekeys.asc
9cbabd baMyjgT/MrX6ijLCis+rJOPfeyCawVusuY1BazWq43tFeCJBv1rGlXBV3oStw5zb
1a5575 mHYgNgBCgYpvh9IATtKScK7VpnHF6dol14WlRugdDlqFruA8nF4aWyoIOGDsOZk/
3e1939 yrVardUWWTKWPZIOgwgn+6Vl+u5ZbV1mJKVje0nRdQywAdc460MwweLUlHJ2LWJy
b27e45 4Wtd1Ox0JZ8sT7UUJ9qFw4uPO4LMy4oMyOi9f3swO+tIuk9LjGE6YCS+M1cGWxNt
ad3ac2 9DhJp/77rkT7OmbRnrGZ7AXJKRYkcjXJYBl90wPRr77ouaH5nuU3hptRs2ZU+8df
aa424d XA1dNpb5QOr9iKSAw388bMofNLV11ylCRV9yiexBYsKQOzcRka5atEIMgPdn1Xp7
6b8241 I2xOG6CNNJgoaDHlRwACAgyRAebTAvxn8ASOj+pADgmguQVHm+uufXtxKreuJdqg
4075ff D4ue8IB8u/OL3YfWyg6fbn+2ky5zdP1sR4midq0e1CXCS4m5FFEjAGoQin9vPi6j
74950a U2qgK93HrtfwwJXfPahKoLvkpZdkTvuNw0w/wIIJyiPkpjj0p3dwTsA8nXTuJArj
0e9d59 0aKn5YP2aH6r4Xf/1BuQ41VzuiGPPsZIL5CRggoSTLEuqePrCigvGXBlfD3q9S/z
09f4e7 /fsOFgaFVD62JtZA9+TTeOKQf8U8jd5ZTgDTdwcjl3AivL5AJZggCb952jU8tLVL
0afd9b H6vDyt9Sf0RummUbYES5eU1QkTg/SB+EHbUsn2vXmPMmHRGV7HfK3Nj3TW8e7aoZ
240700 w8KVG/XvmpYoE2R1ttcvuUAeXMP/NG8Kd0QknFJH45tAhb9nBXyPNbUpPowTJ69K
3b55a7 blwh+9FsD8s+uTjhfi/s4NB4B6xwI5Yl6y3dsu0aS6BJnLNFvRKgTRRzQkFdywI2
6856a6 nNXoUn8sRTVyzkJV27NUWQws1ORpmTinUq4yUGe8QeE+6CpUnYkATAQYEQIADAUC
0cbed1 Naz9XgUJA8JnAAAKCRAkOoHY+qcichIoAJ932i6RtY4hMBH8JrFpqS1xnXEtBACe
abbc60 Mf+hhMthI4HGZ1BBCAdWJrsEE3aZAaIENaz2ZxEEAMp1aZW2fznk3d7xP6NdN72K
1ed935 iezpMLxNXYToHTZ49CW1fdYBP+FhXDBc743PVL+K6OsKs4Jp2AArjW4EvZSyo1Z4
1b33d6 Py1CbyaZgm7s0MANoGVfGp6X1Lf8jtse5CEFKoWcLG2GtXZ11OoQBiclnu27BMys
6f7c66 uhkGr+vRl75sqW1CX4ehAKD/isCm+05MT4uWHvcWOau0cpKnjwQAr1JcG1cSZ2m7
0fba63 waJilLSAgkwZHo8ef/wvcgR7MYcA/nMB24vgMXXfGi2D9w/LAy9j7yfp5k+2DG2H
1333eb Svd/I8oZS48BArXnO26RFeXpkMegabcM6K3QIe1De3/++2yRNte4ryHkz+n0Sr9n
260f8d mLsdn7QJKctAi+O7kLkrdqlbLYePI/YD+QHTqRCKvqfIiTbUMXDh/qRrshbvkky7
32efb0 pafQ4gWtmZ8k3xVl0++uLWVeY0LLsczxshtxeItQcYF01sFz3TaufjQx+XT2S71o
cc02c5 yryuFEpiAjzl6/5WNDD0CBy1H1r55c1EmAb/Mc9gNCeW01YAur3GO4a8nbh2IaVo
114114 Z5u8gLpyw077tB5TYWxhaCBaaWFkZWggPHN6aWFkZWhAcGdwLmNvbT6JAFEEEBEC
18c4a6 ABEFAjWs9mcFCQLBUoAECwEDAgAKCRADRseogYZiEz19AKCiG6GietPq0tZGUn3j
74b32d aM5LwiMSPgCgyzUaltc4As0T56aJ0l/eKsDi3j+JAEYEEBECAAYFAjXGDMcACgkQ
df32e9 S2s0ZJ1JZYSwSACgkp2kzMak22d3x43+uHARS/bgdSwAn3A+TJ76pl8ojCtPG/Af
dfd3f3 GLLtkDGZuQINBDWs9mcQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoB
fc7e90 p1ajFOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnh
7f8364 V5JZzf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr
5624e0 5fSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4
0dc17c XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zaf
9894c9 q9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/wI7oj85OI/bzNG
b209dd ZoOYFZNq14D7DNJEX7YNXI0QGCb+SfhvQ1neb4vuHakD3lfncLt9vxClBSpqjQ/A
376305 1t0ZeXEVwvkB2i7DuJbc2KnHOgdn/jtobAFaBRoluRVU03FeCFLiW4Bp0S9KlFO6
2fb762 uUgCIRZcJxUBYjsQv1EAmeKRaTB/DW9mhls6YJ59s28VHW6jJuRFI6QSQuiOAp14
2a0950 ZTOxs/WndetRMiNUCZKE7ljl47TB6r+hjWNu9BpGoVjBiuf66vScJnB/l0EqBZwK
2ad3c2 mQOsrfU6d+H+0p890WylBKNmOYCOB41KOl+asIRW26zKW3HRDlELB2W/FZqDPy5U
c63548 MijNiUvkiQBMBBgRAgAMBQI1rPZnBQkCwVKAAAoJEANGx6iBhmIT8jsAn0+/E9RT
c53939 oLrd96ql5BHsg7uZna7uAKCuX8NnuzNCMTVjE7XeHNDeaqRrb7kCDQQ2nvWAEAgA
11a9ae 9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV89AHxstDqZSt
abb9b1 90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50T8X8dryDxUcw
bca8ad Yc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknbzSC0neSRBzZr
d968a8 M2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdXQ6MdGGzeMyEs
b0f890 tSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbTCD1mpF1Bn5x8
ea3d6a vYlLIhkmuquiXsNV6TILOwACAggA3DImrbLYFK5azJ0/qlxN3yG2M5cLsB9jmO8o
b3abfb qHQNiNCv0bolxkJlc7uGF6zYJFm2W5cCiDppFHwsBfn7bUdc47p3g2JAbYfLh9cQ
b95d1a ea/F5QHznthzwNOFp3ezyMmzO+GFsBYXbtg5XOqpJ7sahTE8mymaKZe04WMuS6cC
ceff95 gmBtSGmCLN3I/gJLg1qRIuW/RPfIune6gXUhst5VjxB59yl4uxENcO4Ap230MdIy
50d3d4 pnY5bfQdKHW0dnHjqTzpycc9dEmFkPik1TjyDJLAz3MhWEKVmuEHS1CzSzTOs6Ep
4df975 x3Xfmv4P15qOYzdkMPjmVzjSC6JnufLHBBy5h2cfqbYyKXD/BIkATAQYEQIADAUC
428460 Naz2+QUJAMcSgAAKCRADRseogYZiE4dCAJ9UKM14XsA8TQCx5Wv+PjMmXMlF5gCg
652bb2 kyaT/L1fvn3xL+IIzkE7xepjiw+5Ag0EN2X58BAIAPZCV7cIfwgXcqK61qlC8wXo
da46f0 +VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D4
a1e587 9Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNb
cb5d05 no2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbz
d89883 ySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLW
0b8ce6 hsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsA
889a11 AgIH/REvrw/mHzA2NrAGsd425kWaJXjbT/oDdLB7ySG6u+RtohxMHhp2vRVrur3Q
fcd79c qmNHPMydFVy184Axt+Ax2Q/cQAGZR44hQnS1P4sMDKWvcT/A9hEYwU6ePc7O5FRb
459f2f +VSkubg8UbFhWj+fWp4lpOMTVHfPZ4wQWI6NpQHQ9ZpGwv63abpRAonFE3tXhLz6
6f69d3 uK75hYTAWvIZUdi6XZzfg/Lfj7fctMnoHr2hRk7ibJHG3XriUCpxV2CpvLXwblgN
e9ca8d tcSwESUuS2DroKds+1+vldZdVWeUJygEgZyTyd7cDAP6Py5xUBoTVSMqaXrYmnKA
ffb4c8 HIrEpUKu7mmZRJleAAHUxNfx6UyJAEwEGBECAAwFAjWs93oFCQEHrAAACgkQA0bH
e83f0a qIGGYhOVaQCfWFegwivCrEevrtp341Uj3Xcx7WsAoJtI+vELWo8XMB7hOF+o46uH
3f68bb YlytmQGiBDQV3DsRBADpXtuVGi3UnZLL/MT6Ze2tuF1kqLapj7B1w+wUuJ+GCZaE
1c394a PGzWvztIhQOD3XRafIhjfkeiL1ZW3irPQNog/YR1ugnqzvEnVDKuqqLA6L0jSkzm
2b6c36 k55zXOqAbm+35nqTInaWrW/cXYDQ3y6T1nFTQ9BOxFYftUrLbGG+ac9v3HGPlQCg
ff7e8c /74k2Nke0O5CfSvDuYLb6trLfysD/33yxP3nhLk++D8PcgINHX5LZVKhdwcyyrpD
7201c8 WOocmQwCATn14u7r9TzbhcbSezdC8gGt0YtPcmfBtlgib6JFTOxUlvkXD8mfC1Mu
--18e3 000bb1c1ea040110219 Page 9 of samplekeys.asc
5b443f PE+kRl0aOknRWstCqaZ87CObjmn5+ATCMj5gw0Ni4vHD2VEy2BIi9vG6EebEHGDC
6ac767 NwQAiQPcA/9cwFkPtTK3RJI1Jnp9pja1GV5AHy01xoyjogSRA+RkCDA775bCUmf4
106e2e 9rfHO5hpD2S86dPh/QEE5f/9i6kkUvHSQMGWqCR7bdWTRKaLST9MMSqSglNH2NmY
79d66f f+dBvhPYSj9uj2l28UabJG2kGTpLA7AQjJnXUrlQJeZHop4uZ4pdNLQlRnJhbmNp
667536 cyBWLiBCcmVubmFuIDxmYnJlbm5hbkBwZ3AuY29tPokASwQQEQIACwUCNBXcOwQL
78738a AwECAAoJEN3N+NkbuIBoIZQAoJSZ7bvVtkxzg+hAen9FhjlGXIroAJwKFoTjq8ta
e518bc m+yfKEtw7hUb/i1lrIkARgQQEQIABgUCNcYMxwAKCRBLazRknUllhDyDAKDDmmdy
48bcde xOrlRzUlnw8675Wuh+jekQCeMC02w+2OO2/+7AG+GGPAIgmXLRu0JUZyYW5jaXMg
23618d Vi4gQnJlbm5hbiA8ZmJyZW5uYW5AbmFpLmNvbT6JAEsEEBECAAsFAjWiql0ECwMB
43f1d0 AgAKCRDdzfjZG7iAaFuMAJ9wGiMUN7hGQrG7teyyfZoy7nLi/QCfQxFVIQD7wTr/
77ffb9 GEIz3Lny1aqaPSa5Ag0ENBXcOxAIAPZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65
08640d Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09
c47f02 jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brw
1612ae v0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiN
a0aaf5 jrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrK
acb40c lQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIIAIn8tvHM
43a2b5 YugvNyMgV1P4nZvuDW6K09imBFyh/J1jHaXiGMtzws0FFaioM3r2XlK9TjuYF0AN
b96bd8 zvJzaoaJjo8MIkIBAONwFfbMhrohVWPkXb5Z2U0pgVq/helejOcojlGJ6VKLRReR
683071 zaij9m6+Tfhp6RMQhlunoBC4IPTxItt7mlsCYOnuJjcML5/Qm+zF8D3S2o0YiLp3
ac6039 9xdlHF8kSbYvVv+pFCzY0HN67+HaLd+9oHBLwK4bopVnxZ4IzrYPLy7XW5Y7hA4W
5ba977 FzpN7W9i7YeCyUImuAZ6ml8JDDlbTR4mfCN++b+YMiRtNe+T/60pVjnySC0jCWu7
21d6ed DWyHkIRkR79VxoeJAEYEGBECAAYFAjQV3DsACgkQ3c342Ru4gGjnpwCghUu3w5h5
1abcf1 rZOYn02IzUxexzHSQjUAn3Tm2LIYIhawdo9uSMDzy7HLIVEkmQGiBDOoLOgRBADB
c33279 IehuXC5S819Xam1NDX/RmCb1CxJKww7T3hQxGUtwtu7zqyLlF6aZv3faE+zVn9xV
f72755 mBsOZbhV03JW0UmCa/kq2YGQ1T+xlph7cbvIpRI5BcbhnpzYSdtpKwre1V6h6pqb
ec3132 MldC/Caa/cN3ozRwmDU81j93z8jJ85eMxAVFv37lMwCg/1XiddPbR7plNrA22dgc
6fc0d9 4OBnA/0D/23WeLma/BRKU6YDj+jYmbvgRI3LWpaVmrSL2gXowxDBAQx5pHLtYTJd
5f82ba olTAdKFW1uwa0HOdB9uIOqTsBbIJGGnDAd+v6DivE/zbZafgRV8OMAbLgY66AosC
ec47a3 Z04zheGuifR5PraUzBVZYsvMEL7Px6VH5nympuipfIkeyFJqDUVLBACRjX1X4yW6
60d81f 2WqOBsWIhsttuliAYjhVd8aCid1MM4D0GEEdi0RBkFaB92fDNVZgcrJX75IxOFPn
53e1e0 DeYwItRExjHRXg/Nw169+MMIcVuvTIWZo48NodcTpdwmGhVlb9c+A+UkpHRHuPlt
47bb4f W6/HVKZSxkxXQcqFvlU8RnbVFndsuqCqb7QYSm9uIENhbGxhcyA8am9uQHBncC5j
f85b15 b20+iQA/AwUQM8qk7xe2aTQFJUGbEQIntACghMAGYE2UZiTCCHp+yo1r+NfVuNgA
3f9615 oLCshqdAxnfvdqGaYXUmtiApDALsiQDtAwUQM6gs8RsXiaAWa37dAQHjlga7BKW/
dc00aa hC51k71xHNL562vqJCUDyUXaGWqNOnTiCNmRlbuA6HMC5xo5UrEZ5jLEAN4FXls1
d0b3de xyDXmsdUp/s4MiMX3t7MYmQKOtwcehOBmlvukvspjfcd+qYiA9E2qlp66W/99Ecg
f69527 gx2+TUbIPsJKrlMG9JhhPozdE81ZxdRkOnTcwMZU/AN8l7zBsrfANKd4k1+CmJNL
d2e0b3 YSP/zayK9DjnWrWPJyqWNNscJkS6Too3l4sqjL4k29wGjBmyFHd2g676LPfLOjto
779795 jbLVZjKcfQVtUM6c6vahK9eIx8vIiQCiAwUQM6gtFHqu1EieFOzVAQHE0ARjBPkH
21aba7 sccpQeCrx6dGyXCWkNClPyxiSLVjQndAj+ckURsiyGYfakh3aTJdAL0qFndRsTad
0d9731 j0d6PluY01bQI++qCm7I8sKXZMvys0E9MOYpWIT73nKuFfv7hZ5An5xoruBCHWl4
b2cdd9 /3vO06F/sPlPmRGtVIgTcpG642DtDAIvB+pb6Fc8yJIE6TR1OlSRUAxMiQBLBBAR
76c630 AgALBQIzqCzoBAsDAQIACgkQffnC5vEpJ6lqxQCgpL5nb49/Hz3cJAyLJ11rkyp2
04135d mvQAoIQDRMakFt0nNerJjUc6K+NXD6kQiQBGBBARAgAGBQI1xgzHAAoJEEtrNGSd
77f935 SWWEoQEAoPeO2ZKmxm6dPh379LAf/8/o9ictAKCR3e4/kMaqHqdoaTUnlxaoT2H7
a1fc91 1bQcSm9uIENhbGxhcyA8amNhbGxhc0BuYWkuY29tPokASwQQEQIACwUCNaUx1QQL
23cc6e AwECAAoJEH35wubxKSeph4IAn1qm0d7DHHjvh5UrqqCZ2OzlE4ehAKDbl98X7/ow
189e70 fMpP9wCrDkpH+tTG17kDDQQzqCzoEAwAzB13VyQ4SuLE8OiOE2eXTpITYfbb6yUO
a51236 F/32mPfIfHmwch04dfv2wXPEgxEmK0Ngw+Po1gr9oSgmC66prrNlD6IAUwGgfNar
b7361c oxIe+g8qzh90hE/K8xfzpEDp19J3tkItAjbBJstoXp18mAkKjX4t7eRdefXUkk+b
41b9ae GI78KqdLfDL2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz
90ad32 0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP
eef1b9 xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN
2f1982 ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD
ce8c3a ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI
4363b2 PWakXUGfnHy9iUsiGSa6q6Jew1XpTDJvAAICDACNEdXO0XXu4zJSjTgRYy1NGe7B
a15e6e 3MNH4gKxnwvPUq2uSqO4IFBtt1/Hi0DPVZaeOYHh+1Fo7nwEedLNmGgoQBBXBZPl
0a1b99 8vZOqFu49sM510lwru5NUXg5fjsmub1pdzpRI9HmMfCtuX2Ocgw21XD+5hBSMq67
1cef10 qwQlhC4Uh/Zpw4UsJFrgY8BQHfaEdMcZ6QE5mfO9W/kowuqmIACPpl7iSeKQk3iq
16db86 IrPBF4/fNDEEhBAcia9XXDcyqZeBURa+WEG3JIFoKkVqHD0202WfloThVkE6xwaD
9680e6 qV6NozkCUrhZy7g3aZ9JZnpaLofvaXpLvekId0zzIknTfl4vMTvHGROPuMWCMGiz
1cec18 cT0+OH4e7SgMfVQd+KMgadoP5gWTjjyoFzpL2O5AaAZolW33LFYBpscgvfCtLU8N
32655b hcuc8+Mgo25Ns6UD7ZiVEW93B8oUJaQ4lQQNPJB28uudaf5dl3E/v/Dxm3fFpitB
e9c668 mMh0XSnTf6mV5VBSYJNt6aGfI5e4leDI2Q2M1AyJAD8DBRgzqCzoffnC5vEpJ6kR
5c0aa0 AlSuAKC/qkAgATEPkbOVB7J4lIJvsCpTTACdEsvLSjDtMG2b4rbEs7F51zJX8hOZ
243b75 AaIEM57qmhEEAPP9iIUDbAwKJfdRocavopdW8CEQR0leWVvKXaJZyom4i+G+GGMW
108cd3 yYIxyx48fBDeCp0YQJlkebm6romzFom8pew98azWsctJagEWn4GFX1DEFTf7e/3S
0c8eeb 6FA1++Uq7vvDduVABFwO+BzvjUQDHShHk+UMLSrSeXPI4X0kfV2HSUTfAKD/C/7G
5ecd6b YPLqwHrQ5TPUn3yuHlRtlQP+IflKWUo0VOfCAmiawmTog4qggN7/BLCQuwJNrLxx
dbb532 8+y2tB8RnpF+/8lUje6Ns69JXylJusjlDv2ADwIzcEeuK48O+sIr7b0tpNBk/W9M
a939aa 3rvzWz3VCcOcu/vzVaafx/8s1Pb3HXOZRwlre6kD2lFNPlUgldIrhNyYfvx+pe+B
bb1db2 sVID/jLz0mkGt4RrM/ySEjS8bdFq9kN9aUXY27aSR8i27TaaUUoeCYqV0hTrseKb
--6adc 000aee175fd40110219 Page 10 of samplekeys.asc
786c92 6ao+RkinIqD/omLNFXBMYG2y4UbckUtuaOye1joUIcwY1WdpauFvKiRkewXFIZZ1
35bd4e mtEBXpccPYoXsoHMbUMZQ/j60ngaHsW6Ww3oecj82Y1hLhq7tCFNYXJjIER5a3N0
80db1f ZXJob3VzZSA8bWFyY2RAcGdwLmNvbT6JAEsEEBECAAsFAjOe6poECwMBAgAKCRCW
b01004 FaAtu+Hg4ne8AKDsic0VMXaRAcfnJwj9N9Z7viajGwCg54CvLxPLo6/dZ/iXZoXB
c771fa iMMnbsGJAJUDBRAznuqv02woBNhbqPsBAQ26A/43HQougZGlUEfqCktloozYNs9q
95f848 ussrBkvH0fWurGatGeHL776SXDtKj654/hV1joNYRXLFX9IGU1E3gC8AFaGAVEsV
a30168 SguqzZ1fVKh3NuQmyJqCBVesaj4iAdQiSdoLGmjoemTQf1iOr+qFbYPX/0/CDDKc
2f27e2 /8I/SXywXjbvrNp4xokARgQQEQIABgUCNcYMxwAKCRBLazRknUllhAWVAJ4/oGKo
1bc273 fgwmNLDDQN/6tzMRL37uxACg4C3TXv0VJWD3dJX2w15OlhYYyUm5Ag0EM57qmhAI
0b79a4 APZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mU
6c64b0 rfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VH
fcf33c MGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2
b5871f azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMh
a92792 LLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+c
cd498b fL2JSyIZJrqrol7DVekyCzsAAgIH+wUns4t9h9WcSBT8K9Rk5BEgTKyaWaMoD1MV
79c899 iCn4Bp1yeQQvndNjqA+qZHTkzszWZwKUo25YbxQ1KCeEZ9j5SqWrIHdpKZA3TSfF
4c59ae KPIlHDOCoehjVLkPJU1l6S00GM2a+wm6Wa0aYaFHNtSyRzCFaP/1pHTVgTxfdDRk
e96d76 a2q9RyzeJwtgNVw0FMyaiCWdrKsvJDOiS0mFY7bPUlk6Dg3HZlPeS5m6pDDFsi6C
b88e4a VVpKsrMlH/XIzgo+nhE9k2XUHBDeAEe1kYqtD2MYsxygPBc/MgV8G0DrBAxTShZj
8ba18f FZ6btNuIgWVShNPAnf3SkJYBZN/fqJNVCZRymy4rPQlIEUp5pheJAD8DBRgznuqa
a8c092 lhWgLbvh4OIRAlRQAKDlcQAYCPaoeBbMEjHLjdrmE3Lz+gCeIuenKA+IkgDuihdi
a6c52e Keop4PFH+lC5Ag0ENoyAgBAIAPZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg
763e70 2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvO
60c066 meFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YA
960779 WCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtV
a84d82 jLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZ
10f6f2 lp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIIAL2BpjFApGxA
e980b0 j979CDc28srX/4iijT7qJKuXyW18SMdaILoj99T7G2zpaoJj4VTYkwv03itXDKeL
aa2c27 HJECNzpjiJLsax1bxSVlnTRwc0sh1tph28aiHvKFt7IT5AdONqvh9rgKDjUY1cah
466b53 zpI1gryShDHCCxjkfaJNYZ4FjjDnEUuRHD/m7A+BlooWZnptfOb+r15KeO9nJH1G
468461 V/TsNBioeWK7Qt0YiIiq4iGuePy+4VxIgVKSog5iFcUkcQxBNccPDWQfkqsjYUgL
e4a3aa Ymk9guldSwndwnZ6tGkJdnd2KYeD9ViwNuRsvWHMjzrDdGEIlC2wn3GsY6YAY0UF
5d3178 B42y69vCbO2JAEwEGBECAAwFAjWkBTkFCQHhM4AACgkQlhWgLbvh4OJDeQCfaNEx
e3ea49 lbtTTvGF+hgPph8Ei0JugqgAoLfBgS+Oiubl/ljT+ZCrHyNC5pe3mQGiBDOVt3UR
2b8318 BADV50ecXc+RlmD6z+m77k1rBAhJ2izhEeZ7WF9YnVgTFbJmm3ovqQ+dVHIxPqYR
fb20f9 zWvWDVQWbqpcf2fx1p9OAtXkP2iq7TrSYgBuUsY3IOzQFhIRzDZbZJUZTjjQa3NW
9f7ea4 tONsKcsVdjcWUbjFu4dE9SdAVGDb5/Tsu5R+L+7X+nBlIwCg/yeIFBmBGznKUYOq
2be4e0 FEkcOqPhUYMEAMWgOIMQRHGXnSBvZXoRnEcxRMrGFmSLr8DBsLFXg1fnB14HOc67
172bcf KZYHf9pr1c4RqiHtT11wool8rm6EjOas47BXzIrWRUgm8b7PF2TNA6LByVRDGT7a
eb430a QCIo0Au6RXOqWNWihaT8ZxVSkexmdC2DvwgaswI1br3B6oJfmGDA/s6WA/0YeGzn
0a57e9 pJUOvbgDi+/K7v1xTwlWZa0l/vUXiBUpm+lGhjAPcrCfmyPniLrfxGZMX1thzcFO
ba4a97 7xS790JUmmg9Bs0QH9X3v/lRFtvtHxV0ELzm2KUEWpr0OdLuZBKgOQViciVToEc1
acd22c uumemkqEHZ/+JR0nYzIdejCbJyhgiBtaoeU2nIkAYQQfEQIAIQUCNaFfFgIHABcM
eb1977 gBE0K8u9J3zLCzV9RuIIR3mGorObcwAKCRDrEJ359vgzGDusAKDQWs00qgZ7Rp1g
a8f7bb iYf4+7MpF/Z24QCgoCm+cO+4tVtt1/+aHoKvU9hl/6eJAGEEHxECACEFAjWhavMC
997751 BwAXDIARBfN7iFfRRmsrcEUJqVSWxoLDHtQACgkQ6xCd+fb4MxjrPgCg6hwhC01o
710ace G4t42iUhxAQjZK/kuncAn1noEFRd7KyI1cooplpMP1CJY/duiQBhBB8RAgAhBQI1
57a9ab oWrzAgcAFwyAEeBUbfAKJfN42XMvhgP1FXP7aDNYAAoJEOsQnfn2+DMYjNIAoKKC
20682a 4tHtDx6Qk0EDEpLPFctyreJlAKCu5LtxqWOYxYkMgDVz8tR+TeXul4kAYQQfEQIA
f1c356 IQUCNaFq8wIHABcMgBHvKH+BXX/bjkWA1s+HfyMXpGNlKwAKCRDrEJ359vgzGGt/
83ee7c AJ9yFvNhd7EJbY7TCEA0IZMUuQu60gCgugXt7Y9EIu54bZxZayCRsQPE+o7RzXz/
c6633c AAAONwEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoH
57a681 BwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7
a04add Pj4+JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7
c3b37f Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCACQAHgDASIA
22c8e6 AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgED
727d1b AwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2Jy
4fa2d4 ggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1
ff829e dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJ
8ec5ee ytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAA
75cb47 AAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJB
883de4 UQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNE
c8b297 RUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJma
e293e9 oqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP0
041ca4 9fb3+Pn6/9oADAMBAAIRAxEAPwDoQKXFApwrY4RMUYp1FADcUh4GTTjVK/v4bKAy
1ab92a SuAB60gLDOAM9Kry39tCf3kqr9TXDav4ollYpbyMkfr3Nc/JfyuSSWYnux61Dn2N
0f47eb VSb3PW4721l+5OjfQ1MGVuhFePJqEiHgsp9jW5pniq4gIWRvMX36ijn7g6T6Ho2K
201a2b Qis3TNYjv0yrKT9a0+tWZjcUmKdikxQA0iilIopATCnCkFOFUIKKMUMQqkmgCve3
f326d5 MdpbPNIwVVFeZ67rMuoXDEnCA/KorZ8Xa0Jn+yxN+7Q5Yjua4meQkkk8mspO7sb0
6f91e2 4295iNJls/rTWbnHU0iL5jqg3ZJxxW5b+HmkQfPgn1pbG6i3sYY4INIHKycn8a6C
4dc83a Xw3Ig+VsnvWZf6VNahWI3A9x2ouDi0T6bqb2soO4jBr0vRtRW/tQdwLAc+9ePgsO
ae85e0 ccr1rsvB98VuRHu4IprRmNSN1c7+kpVIZQR3orQwGmilooAmFOFNpwpiCsXxFqiW
--4937 0002b472a7740110219 Page 11 of samplekeys.asc
b60d4d Vr5YbDvwMVtMQq5JxXm/iy8MmqOqsCFOMjtUydkXCPM7GBqVwZHJznJrMY5kGQSK
3453b1 nuHOabbIXcD1NQtjq8jd0WzUoJioyeBXT2UaFsHise2lW1VFZCqY4PataxvrN5Pl
fca03d kVj6ZqToi0lY0b23RIkKjkjk+tYd9EsgxW7PcwSQYB6dM1h3NxAu4+YpIHY5ptDv
fe7d34 pqcVqEPk3LDpnmtDQbk2l7G/UZxVbWP3kySL0YGq0EhVl54Bp9Dma1aPZLCdZoVK
85b80e kcjIq0RXK+Fb8yoIi2cCuqHIzVp3RxtWdhDRSmimBJThSClFMChrM7Q2EhUD7p5/
670fed CvMNQkLMGcAcZx/jXoPiO5VAIXIUYzlumDXm18SW2lgeevrWU9zaktyjMd3JGBU1
df1f24 hh5umD1FQsw4FS2Thb1M9+KDdbnZRIl5apE4+7jHFEljBawbUjVed2QMc+uaTTTw
e62540 tW9SVpFj5+VTzikb2T1IbsxsLZMcMMviqf8AZNvHP5iqFUtuIBPPt9Ku3CxPc2/k
4021be sSoxu3DGPWnagyxxEigbSepyHiBlNyoUAKvAArMQ9MfjVnU5RLcdeRzVaNcP656U
f75814 +hzPVnW+FJ/KvowWxlCK9EibfEG9RXkui3DQXkbFuh4r1PT332qnOfenEwqqzLJo
ae40a5 oNFWZD6dTRWbqmv2uluISj3Fww4iiGSPr6U3oCVyj4ugDWXnj7w4xjOfSvN7oHcd
8e0ca3 /DDnArub6bWtZhKNDHbQMdwReXx6Z9a5K9sUhkdEctISPkI5H1rKXc3ptLQymUcH
1c5670 GKYAVYEdQeKupYzzjEUTuR/dGcVZGgak5C/Y5Ad4TJUgbj2zQk2aOSW7NDSNRVog
7e4ac0 ZDgjrmtEtI6qzMGU8k1ljSZItOMZjKTITkd8+hp2l6sLdTHNwR1DVJvFmhM7SARg
898517 qSDkMpPAqlqd8UtCGfc3Ip95rMckOIwAx4AFZVzYXMsPmMrMQpdgB90UbsJy0MYs
03527a WclupNSIOmOvanmE+YBjORxx1q/aaPe3KF44H+Ud1xVGF0tyvZ7xcpnHJHXtXqmh
3c0d96 SLJYLg5K8GvPINHumufISFvPQZZSMcV0GkXt1obkahZusJOGkU5x74oi7MiorrQ7
3af332 Q0UyKaOeFZYnDxuMqw6EUVoc5zreJZtYhW20tHt3f/Wzt0i9h6k1oaTosNqpdm8y
23e892 Vzl5HbLMfeszTtKsFvsNC81uc7oA23n1+orqo/CmgyRq8dmxVhkEyt/jSh72pdZe
61594f z32D7OgHG386o3Oj2E8jyTW8TM+NxzgnHvWj/wAIjoh/5cz/AN/W/wAacvhDQgcm
f10955 wU/WRv8AGtbHNzrpcp2NpYWcfkwRRQqTnAIp+qBP7MlIkX5AHHzD+Eg/0q3/AMIr
88a013 oIPGmx/99N/jR/wjGhbgp02HB4IJOP51SbRErPqZt7pFret56TLG7DO8EFW+o9ax
f54578 7jwStzIXaOFyf40lAJrtF8NaJGAF0yAADHGf8ad/YGkDpp8I/A1m1FnTGrUgrXuc
f93d6c VB4NhtiGb7PDt/iZ9xrQl02zgtorSMqWuJlVmJG5sckn0GBXTf2BpB5OnQH6ioLj
3a551b w9ojspOl2+VzggEVUFFPREVak5q0noZEuj6Qbn7T9jtvNByDgcH1qVkjYjMkfX+8
75b159 Ktnw3onfTYf1/wAaT/hG9D7aZB+RqrGXOupDFBZxu0imISSfebcMmo7qG2lXa0kR
7bc6a9 z/tCrf8Awj2ijppsH/fNL/YOjf8AQNt/++aTixqrE49Xm8PSySW/+k6cWzLGhyYT
25842e 6j2oq94nsLJdlrYottGCTceUNoc9gfWiuaUmnZHoQpc8VJiaDaNqGoBnVCkbZY+v
8a21e3 tiu4kkgt4jJK6RRKOWY4ArM06BLd0jRQAPu4FSW8S6neSXdwoeCBzHbxtyuRwzkd
5d0924 zngfSt4x5UclWq6ki9a3NteIWtplkUdcVJIUjQu7hFUZLMcAVW1FzDCtzGoDxuoz
f43f07 jqpIBH05pNbVTol6G+75LUzPQY2s6Yv/AC/RN/und/Kp0ubeS2F0HzD13FSM/h1p
d5a87d tle2MwSG2mgaQICUixxxz0pJCbnWILXqsC+fJ9eiD+Z/Ci4ct2XQyLB5rgxqF3EO
0a7bb5 MFR71n/25avGJIILy4RsbWit2IP0q3qTY067P/TF/wCVUdF1SC5tLe1iW4DRQqG8
bea492 yFlHAHc1KNHZCjWvNDpBp928qHDx7QCnpk5xn2pj6vCsRe4intivVJIzu57jGcin
23c60b LNHpMksdwpWKaRpI5QM72PJQ/wC16etMM8VmG1DUZktmmGAJGxsQdF+vc1aMpXaF
5f7006 TUbSW2e4hl81I/vBFJYf8B60tte214G8iUMV+8pGGX6g81XhuYjPNqkgW3tvLCLJ
e5de2d INpk5zuPt2FJHcQajeQXFnGZFQndcgYUr3X35/KrMWizPdwQKWd8kNs2ryxb0x61
dbf1d6 D/aMYI8yC5iDEKGeIgZPSqsMcyH7fFB57NPIWjBAbB4BXPfAqVL2HUp1t4iymFt8
91af5c yOMMCOgx9aLhylfXNLivLdmVVWYMCGJ4NFX7kBsA8+1FZygmzsp1pxikLaNidPTP
a7533b SpNGGLJk/uTyr/4+arwFhdRlWDIc7hjpVlobiJnexeIGQ7mSYHbu9QRzVs5r6ias
8bf304 +8W1kvMlxMvHoqnLH6cVBqd/9ps9StliYeRCfMYngHPA98jmrFlYtDPJd3M32i6k
9ea11f XaX27VRf7qjsP50waUDbXCNMRJdIRKwHDMT1/AcVI7mhGFCKURVGB91QKzdNle51
a85583 zUU3MgjkG8jgnj5Rn8zWkgCqq5+6AKhNrIJ2ltbjyGkILgxhgx9frSexcXqRaxP9
bd2493 ntZoJJd4mifbu+8MY/Mc1cuLlbSy819zBFACjqx6ACqNxpDzxXJlufOuZl2CV1wI
f36cc0 1znAA6VavoJJ4YxEVDxSK4D9Gx2NIpvVmdfQSraLd3bBroyxiJB92IlhwPU+9ad5
b9ddaa FFKcSRpIAT99QQPzqr9muru8imvREkUB3RwxsW3P/eJ9uwp1xbPO5FxMXiJ4jUbR
0b13dd j39apbkS2K1gsTQSJEubcSHyg3Ix7Z7ZzikgMaSXzwgBFPO3oWC8/wBKkME0gKPK
7c3390 I4hwFiGDj6/4U8wItq1vGBGhUqNvbNWY3K0YZbK2t0YhpF5YdQOpNNuIYke3ggQC
9e90f5 ZHDLjqi/xE+x/WppLQOsQE0sZiTZlDjI/wAinQwR24IjXG7knOSfqaAuMuDyVXIY
e605ea jriiiU/PyzdOgFFJo2i7Iz7WcnUYkDZBJzkcjjpnvW4uK5fRLcWkkKyy+ZIPvyse
2edf55 proXu7aFDJLcxRovVncAD8aE7ozmrMtg0oPvVZLu3kAMdxG4PdXBp4nj/vr+dFhX
e9c34e JTTo2w4qHzo/74pPtEakHcPrSsCkk7l0nJNNJquL2EgsZFx65prX9qJhAbhBKwyE
bc3273 zyanlZrzpljdg1FI3SmNdQoCzSKB71HNdwopYvnb1CjJ/IVSRnKV0PzSVEbiMH73
76dcc8 J5xTDdRgfeqzOzJiaaSKpXOrWttGZJXYADPA5Nc43xM8Pg4AvG5x/qun60nJIuNO
7d8d04 T2R1MmC5J4UDJJPSiuI1rXTqO6S1llW3ZQoRjj60VhKrrod0MN7q5mf/2YkASwQQ
c3237a EQIACwUCNa5x+AQLAwECAAoJEOsQnfn2+DMYr5UAn0/9DlB4H2PWxmqdqq42mEeL
d23002 I17DAJ9znJvXB6Q6QIXE4xxTJmGHIctSxIkARgQQEQIABgUCNcYMxwAKCRBLazRk
7d0fe1 nUllhKZ5AKCbgjZ+CXd1vTuxWWIma+1AjXZKswCg8v2P78RD1RTkC8jgMUorRcTk
220e9e icq0HEphc29uIEJvYmllciA8amFzb25AcGdwLmNvbT6JAEsEEBECAAsFAjOVt3UE
c56291 CwMBAgAKCRDrEJ359vgzGMZ3AKCYjNQyvXRU1G7P3sm0h1v09S7JPQCg5RjOef2i
fb12fc 2pnwUTVBLssO3Lc6ATyJAD8DBRAzmJVGF7ZpNAUlQZsRAmziAJ9Ny2I2fekzFfut
2af117 g1yas4aIDBYD1ACgi5VGYoqaphE/6WFj55Z01nOLd+CJAD8DBRAzqKDbBRRjyl/3
b6abf3 7SoRArdEAJ9LilqrzPPEi6xUFF2BvElieQfksQCfbvKLuEVDbC0ZDBT92iQRqyIN
b26be5 ueOJAJUDBRAzs1Ud8wXb6sBT5R0BAR04A/9iaoPrTchUAVmPqLuLA+QfKahkobM0
166929 6OuDlR+TSJl8eqtgQBdfuQeSzWM3/gUUyuspLL2o5k3QiL7tJm5cBjhgKAj5ZXuv
19163a 5mnmOUFaaLJzWSRj7So5dMa00lXnzpeyLruKbUbemTPCbIfbOurDsBtH+RpO/zQH
e32bb9 QJn5Uchmtnln4YkARgQQEQIABgUCNcYMxwAKCRBLazRknUllhAtwAJ0djFEWwAtL
cfad1e OG9Bzc4ZKwEDcMNzmwCgo6Ug7Vq16dZPwgOUGqWszIBRh1O0Jkphc29uIEJvYmll
380a25 ciA8azA1OTUwOUBob2JiZXMua3pvby5lZHU+iQBLBBARAgALBQIzlbgbBAsDAQIA
2df5cc CgkQ6xCd+fb4MxgtwQCfbpwsusCYvrZKXUwPxsVTdHlvoSkAoLjfAvmwAIZTqi/x
5044ec YcaDIyxOKASWtCJKYXNvbiBCb2JpZXIgPGpib2JpZXJAcHJpdm5ldC5jb20+iQBL
2b5901 BBARAgALBQIzlbg1BAsDAQIACgkQ6xCd+fb4MxgT9gCbBQ6CQbAyI+4dbj08s3Ji
--73e0 00075e0bd6440110219 Page 12 of samplekeys.asc
c75542 SGTmOVUAnRn0kE9Mi/wMap10BxBucx0SRC2UtCRKYXNvbiBCb2JpZXIgPGpib2Jp
7b7c3a ZXJAcHJpc21hdGl4LmNvbT6JAEsEEBECAAsFAjOVuEIECwMBAgAKCRDrEJ359vgz
ba50d6 GDC+AJ0UtN6aQzqrytGD1QEo70hhny7ZIwCeO8AjkIIDBBTaCOJsiTG5nm9rc3K5
3cee61 AhEEM5W3xhAICwactLoTLEE9B6n4IXW2aUdiUnfNeWzWuLn/UEvOdg6FFqCTZFVe
82c6e0 d7t/eIRIeHUDUKJP+94Vp+CF+QTcwi/Ghc5VcqWrkemhgbw9J86vR4iePLstKpyh
5e77bb gb6ApX+2Sj7kf54JG9RJbgpuH4ZgNViokoFcsP8MrrMw7dlOFNTuZJpl80DU/G97
615a6f inSoIuGRMU4Hh/le/2Fz5ejVhmUQrqO88M0mfsLAcepEJ4t41lpBzGLQiFAvdYlv
594b9f LQwPyknWIOB/JQPde9XmCgAZCkeUmZIIZSKcM1990ScEO0qNmvZmq/eUL30DJURO
5ac0ce Q+Zq9PcAcnkFs73RVsIiEBnVlk00qr7fQiiioQACAggKAwuLCJS5v99SBsXHTE+e
ab1254 kgHjIRunsW0J9/kMo8fv/E9E7XYtYcoQnp8LIsG1DGcY3EnMuR4tQki8RqV7TI2B
09b7dc XOco4bmBqK/aQA8WWXLfETAEZ88YzKeQN+8kgapQxJI4g5S3+SkVQPFftLQFM3BF
be4c6b acu73J7wr/3f8+Fa5cKOhMBWH3X7XomzFffCSbdZP7Sj8Rdji8nC5ri9Q8eANEtg
220d16 6cKGu4RbfWziY3aSh70X1qXQJ+JTRjiTB63aiEjGIGMJqMwtpecUbnfxcmON74bl
42d4aa 6/Fn9lJBqk1UgsvDi8rLIf/D2Hft21V5Eefy+TXACFpfOfvuUN84EYZ2Ku+pc3b8
32196b m83IiQA/AwUYM5W3xusQnfn2+DMYEQLjUACfahApW72JGBbbKgiATl1HkTzAmLsA
357bcd oJIaidYo3CgY64hi/Fgot5MfdCgTmQGiBDN6a7YRBAD/RnCMmpu8deZPEdrzUURw
57f0f8 E5O9VMBxgzfN/m1M/0XY25LtYAgdYSFM1XVfNw2fOwWS6rYnOf/ORfTJsFk6dgf3
22d711 qV2lMeRPsWhXWwWLIYpxIDeCcNCEtp/EMKCtTqAP0PoD5F+nqjCA0VmCUZbeooD6
bd053a CUh14sWZPf4uZIJxXPlY5QCg/0KSRt01cMoQ0+7dIdBoolCys08EAOwD091G+gn8
6c4617 0u0e+lCblBuEq/HyRJF0kwivrH+nxRuITIi8LeEn40pksciafnw/1RSOOoBFrhYf
27f3bf DZ0xXdpcmzzSdyT2Qd//aZ9I7Td0Lvi2MVS/eSZFK//kPYZrH1o6n8atR1Yb/t8O
1d43fb pxx3iGNfhpwbhIVP51+PH6xy+JUnafIeBACHHUltR2Gl3EmNuk+6SYJ5mMKRqwer
f2ddf6 QU5GWn0TwDDr/Lj2LyUiIpO/cfdgzuPV2XTAx1rZakdQodngXuyRCXjv/lMsfAiJ
99fe87 X8FFvVPAM/K2QQdsJp0i3l628iDQuav5k0TxA0/QAzQ97RGAnJJWvt3mKu4EKh0A
7abe25 8XkQ69gzS2JGwNHU+P8AABWzARAAAQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEB
9c2ffc AAABAAEAAP/bAEMACgcHCAcGCggICAsKCgsOGBAODQ0OHRUWERgjHyUkIh8iISYr
d2f001 Ny8mKTQpISIwQTE0OTs+Pj4lLkRJQzxINz0+O//bAEMBCgsLDg0OHBAQHDsoIig7
9abff1 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
668e7b O//AABEIAI4AdwMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUG
4ce195 BwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGR
19c524 oQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZX
986a68 WFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0
1e74e7 tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAf
b8a4f6 AQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAAB
c506df AncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZ
74c57b GiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SF
6b7cc3 hoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY
21a7aa 2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AL5huI/+XLxNF/1zmD+l
fbd4b0 Rtdzxg5u/FMWP79sHoGnzJ00LV4/+uGoBv6010uI1P7rxdFx/A4esVqdbsWLi8EV
7a58d5 lE7apLH8x/eNZbmPXquOKq/2naNw2t6e/wD120zb/SrdzcyR2kRF9qkZ3H5orbfJ
fc383d +I/zxVQ6vIPveIdST2n0kf4Vm9P6/wCCC/r+rCebZSf8vPhqT/ftmT+lP8q1e0A8
ffb211 jw4439pmQZpn9rx5w/iCzPtNpWP6U/7XbvZK5vtBkHnFd0lqVHTpjFVdMqz/AK/4
955f74 YaLCBvuaVpL/APXHVCv9at2No8MjbbGSHOceXeecD+v+cVR228n8HhKT/gbJV3T7
2bc688 WNVd1sLBd3Q2FyWDfmf880ONv6/4ArsjFrdDOIPEI54aO7Vs/hR/pydJfFaf9s1f
55a60a +lV00wvl10G3ZiSd0Wr4z74zUq6bcj7uh6kD/wBMtVB/rSUg0/r/AIcGvLxQQdU8
2a1cd8 Qr/1105WqJtQkH3tauR/120Yf4VN9lvE/wCXLxNH/uXivRm9XpL4uT/gKvRbt/X4
90f5b3 isv6sR213HNdCNtRsrg4+6dO8psfXGP/ANdbJX5G/d9uvm8VmW9xcm4Ae71zAH3b
a9916a yyAX8x/npWm6rsb5LY+4Y/yoGTwoyBSq3Az/AM82BopsaAopCRtj0l20UMRgDSB1
106424 Tw1Gf+uGr/8A16edOmUHGiazH/1x1EN/Wojp8MnTQtBk/wCuWpbf60v9lqMlfDEf
a6e3f0 XrBq/wD9lSs0NS7v+vvLtysgsoFU64jL1W2w0o+vr/hVX7RcRjH27xdH7yWwb+lW
8b4931 ri3drG3QWOosVP8AqILja6cf3s8+lVxBPH/y5eK48f3Jw9aJ6E6CHUplP/Ic1lf+
d58cb5 uumA/wBKH1L/AEFS2uZPnH55dL9umAP1pfOuE483xin/AGyDUSahJFYrK2p68mGY
95c01a 5eyBI9iKlr+v6Ytv6/4BA1/bMQH1TQpfaawKH+VYcvjqCxSSOHSrSYCTG+3zGhrA
72aee4 1TWbnVdSZ5JhcLFKfLaQBSV+gqi1s7Z8qMlichFGc5p3stSrc2xqyeI5WlW4/sPT
b04b25 lhIwIgrdfXOak/4SSyaOOH+w4vMJy7rcOv4dax3R0UGaUwHP3SDwaYbJWtgxlQNj
ebfb0a gjv9aWjK5WjvtL1DS9WlEdno0scv/PN9TKH9TWn/AGfOOmj6kMf88tWU/wBa8p8p
978b3e sq6MocdwxBH413+ifZtX01Zv7F0gujeWxkvmjLEd8ZpNW2C/9f0zctreeGYs8OtQ
7dd151 gIeZroSp+VaTuvltlo8+0fNY9haRRXTvHYWcP7sjfbaiZj16bc/5xW07MEI8yccD
d2d2db jyx/OgV/6/q5Imwhcm2Oef3mRRTonCon7zZ1zuh3UUCuc0YoH/5ZeDpP+2rJSGxh
580f7b PI0nw22O8WpEf1qQzwv/AMvnhaX/AK6WxX+lRPHCyHEHgyTjtIVq7JhqaF7Z+dZW
458e8d 8f8AZgnw3Ef23ywOOMPnnHSq66VOOnh2+Qf9MtXB/rU+oWyNY20bafpsqkn93c3Z
06f6ba jj/4Cc/n71RGlQHj/hHdKb/rlrBH9azaa2/r8AUv6/ploWV0P+Yb4ij/AOud+Gqr
909860 rKXqaC4RfEcbZbOXBwP9o08aUAPk8M/9+9YH+NV9ZtLmLQVjh0i/hklkK4F8HwPU
cd1ba2 0OTsPR7f1+J5tFAru6GN550b5geBiu20S1iS1iHkqv8AFgHP61x8NndzaitiQ8E0
47fedb kmH3cYHeu5ia008rE1wkcaL1c81nVd1ZHVQjZ3ZpLpdtcrkwQtMvKmRcgGsJvBdx
4e0af5 cCa4uzGjucskH3cetdTpr2t2M293FI3orjP5VeYSJgbSOOfeuVucDv5KczzKXwfO
a9eb29 s8n2besMS53OOprNsdlld2dwn2dwkqlhKMq3ruFem3krDgk4PXNcHHZWE3icRJMY
6100e5 Y4pt7lIfM245zj610UaknfmOKvTjHY7eyihN/MEi8PMQv/LgWDj863JA4Q5W6A45
e603b2 ZhisSyvYrrUGUajb3GUJ2HTfII5/vY/zmtmSMBD+6XHHLTZB/Ct7nG9CxAGSNcG7
c2554a UHP3EDUUW0bmJCI5G4P+qlxRQI5s6gT97W9If/rpphH9KY04kUgXPheUkfx2bL/S
108b7f umbUI8jfaWx/4EaY15ZN8rafbkn/AG8f0p6oOZdvyMjUQr29soj0RzzkXrHZ2+6B
75eae0 +tZ/2eNsZ03we3+7dMtdNL/Z/lrJNpsGwkhSZlPP41CV0En5tMtBj3T/AApk6HP/
--5742 0006329a6db40110219 Page 13 of samplekeys.asc
53a660 AGOE8jRvDh/3NTYf1pLJSuseQlnbW2yEsFgvPNXJPXvW8bPw4w50m3/DZ/hWVqll
2c3645 ZWV1BqmlWmxQCk0cZXLL3I9azmtNEbUZKM1ch1m3j/tq2maJVlRSQ+MZBpr6Xa3i
1bf79d 7ZYEJ6F2GeKiu9RtdTu4pbKZ5EVdh3c4IrVtdm3c/GDjFczTVj0oWluY6eHLCygM
594d2b ny/aBJuSSJip29lIraa+kZIobbKyOpAaQ8Cq13OhZURVAx97Gac8LC4tQs6s20t8
290330 vOKHJ9TT2cbWTMGbU9dhCS3C213bNnIVSHXHWmeE7Ga2guNUaLXYLi7c7JLKAOPL
71598c +preuwzlY/l3SNgNjHWrsGjafcWcTy6pfWrgY8uB3CAD6VrTkmcVeHKtWV7O6uHn
2ecd35 xJNr7DbjF9Zqo6+o/wA9K1pNgTOLfqMkZJNV49Fs4H8yPXtRkOOFmZ2H6irckUTD
2c4bb8 A1KNTkfdiOf5VvdHFoSQxKYl3R2zHHG6UoRRRCyIsaE2zArkNLGc0UWEc4bwKSP7
f2212a Y1tf9/Th/hSf2mMY/wCEgu/pJpf/ANanG5nUYF74uH1tQ1NbUJwP+Qp4l/4HYCqa
9526e6 /r+mJJf1/wAMXb+6ihsbeU6hBb72/wBeLYybuP7vbPWs86rDyD4k08/7+msP6Vo6
c896c5 ldPDbW7LqE0TbjmS3tPMZvqvb2qidWkHXxJdj/e0kH+lQyl/X9WGjVIj11/RD/vW
7324ac Tj+lSi/RIbeRdS0IklvmeJwp+lRHWG6HxKf+BaP/APWqO91yOCxgK67aSyszKFOn
78fc5f rkk+x6UlqNr+v6RkaMwZi++BgzsQYAQp5rokG+GePJVi2VIrHtbS4t7NcFHmhb5y
26023b oADevSr1tdiSX5TgnGVPaueWrPRg+Utw+SAY5rry5RxmWI7T/wACFVoXR9UVbQB3
2a31ce 6lk5ULWgxdoRleByQOazLm+h0+NzHtjZ1I/u4FLXY2dl71yTzVn1FkZocRAkeZMq
7bd509 ZP4mryXtykYRHtAqjtqCf41jI9usQVrrwzP33XAYtz2pf9Gz93wf/wB8vXTCKieb
98fed3 VqSm9Tfhvr+SZF3RMrdTHeqx/IVsRzyeWubq8APb7KCPzrktPNubyNQvhzcx4+xu
7cf77a wc/TNddAkxhTCapjH8DArVGDRDbsFIlNzOGIxnyNwoqSAyCLg34/654NFMDmDb3I
5eb6b7 PEfjBP8AdlBpji5SMnzfGg/AGlGkXABx4f1kf7uqA/1pJNOukT/kE+JUPql+DTUg
a53a5a sv6t/mXtTlkFta7brVFIZsnT4Qz/APAhj8qofbLgddS8WL/vWQNTa5e21pa2Yurr
7b9e27 UImGf3drIFkH+964rmdU1y4MR/sfU9ZQDq1xc5Jq4xbRKVy9feI9StxttNT1ZSY3
ccea56 ZZNQgWJDtGWxxk4Hp6iqukWE+tT3MaXsbXV3YM93PeKFSFCQ2VbqODzx+ldVq5tU
0440bf tIVvZ9Tdo9FLl4Vj2J5oO8uz8ckKBjHSs1b2a9itLLUo9Vjti/mSwraoGkAgChEU
efc68b Zzjkk1jJVdo3RSrRpbaslsYwthEQOGjBHvQNMjuj5gkMUo7gdap+GdUW8t0sJsrL
426a5c Gp8kONrOgOM4/CtoKUzt5x+lc/K4uzPSUlNXMi4W+syE82NieOpqlbT339ryRWvz
bf08de z+Q0sheJSscY6tzye3A5rRuFO9pJD8ijJJrCjhW+0+4u5j5Bh1S3HnIWMkUTj5iq
8cc44e DlsdSBWlNJv3jGpOMFd6mmusRNGj/wDCRWi7k3Y/sUHH6U7+1oM/8jFZf+CX/wCt
87a748 U0F+XmvI7LVdfFlbzCK2EdokhKBRzwBxnOMjOOtSG+vQxX+0/E7Y7rpi1bTT/r/M
dd94ee 5FJNXt/X3DbG/ilv4VGs2U5z90aWYj/31gYrsYbZjChFmTkZ3re4/TNcna3ly99A
dfde8b kl74gdWPS509Uj/Fh/npXURJDsTMelE7erTEH8qqwN/1/VhbeEmBf9Gbj+7dYx+t
c53026 FJbxxfZk/dWJyP8AlpMQRRTJ1ODvl0nTZvKvPDc0bEf8stUZ/wCRrGkkkZg8LzWu
a54b80 eiRzuQPzNVYgYpJSpOBwTnPH40vmPkoA3XFaxgoq5pdjlnZ2aSQs7j+Jjkmid9ts
7747b1 2Gwc9TUclrIhyGwW6rUslkHt2DtkkdAe9aKSsNPzO41CKyuvF+lSXrm3t20+NyL5
b3a547 BHGI0BYcZw2D2PrVLVLsSRacb6ylaK21nynvGnMc8pZd2wo2Cu4EHJxgUupm9t9P
147448 0W7sbW/+3XOntBA+4XLSMOSNpyRuAz07VW1VotCkGrXMG6+mvILlo7/97cRRhAfM
f9cd7a LLkL8wI246AcVz1bR5ZOWvRE+9fTRfiZGmppFrc6lc6iLqzltGkexhgcyeW2Thdx
b76931 646ZPpzXdWoa40u3v7pTAJbYTybhgKPWuF8V+fdeI9acxR27s24RKpTAKDBKnnJ6
714067 n1JNeh+M9QktvhZZx2TbXvY4IAVbaQpHP6CnKPtVF9y/b2jddTzzV9Zk1aLZbnyr
a0fe63 WRsJj7zj1NFmbeDw3cSeRHFLJM++7cOSFQAqg29M881m+VKhiAVlCkDpworopbCf
9fe0f3 RfDKQ3wtr+3upJmUQzAGQEBhhh0zjuOKKkVFKKVxKTvdsn1eXU3m1PVbWXUNPngh
0640b8 hdrKG28qOFCP4sngnHTg5zxVGz1gFCNRvNZkcc74LvGfwp3imBluZWW4u1nltLee
85885d 5jF358UkeeMscFscdfr3rDSfGec4q4RilZbf13Ii4y+E7DSZ4728hktT4gkRWIYz
882450 XitGOO69eldkk6BVU3FhnbghrU5/PFeQfamgJlglkikByGRyDmvRvDfiybU0ayvr
9625aa xkuY1xGI4FIcelKULbDkjXt5E+zoDcWnI/5aQEk/pRUtvJJHAqi4ufT5LYMD+NFQ
d18260 QeKxzKSQSSGJyDU9tKEOGznv61HHbRFC2SCG9aJ18mdShDIemDyK6b3VmXcmm3SS
b4ba9d qOMj+6asCNmQhhnBqncXAUxmLg8k8UqvM+cu3IB4OKiKEjsLBVh0Xw9fBY7drG/Z
1048dd He2nzMynOVwemf8A0GsLXb5ibn7NcXZMIKyG5uBPIzoxw+SPQ9OmBV2wkeXwRqUc
5a170e n9mb7e5WRFmXEr5GMA5/D6VqpbC0tpbK00eLT0vYZY7m6nlU3AjCAupVvUkdO1ZT
6f8a35 5YS5mrimqe82Zuq2Gt6jfSXMqX1wV0uKbF1EiOsQzkccEhiTyd3PSrfiG+aTwH4P
5e41cb iBJMkbucgn7q4FUdQbXdM0fSNSuby53ajZNbtvu9+UBBBx23Ag9yPas641aS40/S
9854d2 7RogF06F41567mraLhLWD0DlSSUUVbl3FtIkZUuFwBnHNdNrml6RfeFYI9Ptms7e
a20392 xjkBju5Y1kJKhvNypOe/y989BXPwqNSv7axRAXuZ1jAkbAOfet68ls4vCd2HFi+L
6fbe7f 26T7MGUvGxOyN8jIbb6HqK560eaSSdmaJxWkit4hW2s7uSxS1tL0yWEKzXVtEVSJ
e42a8e h2DdGHA59/WsaMxocCPqMH5a1tVglmgubgPKthbQRRwLf5S6OMAggcNg88djWRH5
d17d2d YAYsCM/3qdKHJeL3JdtkOeOEqwWMBicDK96SF5raTzVkdJYfmV1OCKc5V2CwlS27
018e34 OM8VFcnY7AnOBjA6nNarRiTPXNLF1PptvNKl6RJEr5gYAEmim6PsvdDsLiOxUo0I
790d8b Gfte3p7ZorJ7ks8fiiKSSIypg88LVwRMhyyqwH+zWWJpWkI8xunNTebKQV81s49a
68e8f7 3SuirMknhAkDxtgHI56U5Vwm7r8n5Gowp8sE4PGacrjycc5x1rSOwQOp8LyKsWrW
014d96 ZurG3E9urA3Ee5mx1C89+/pxUGqW80Gn2V9qux7VL6Zftcx8yWVSMdDycY/TFWfA
3a2345 0Nzd+IWtraSFBNZyK5mi35HHH54rO1mO60u0uNBvNTuLm4hkjns3CgxxnBLAg8gH
8a3ac0 PbvUSi2tO4OpGPQl1jQ00vw9pxg1aw1K2t7uSGGSGYscOu8rjJU8gHgVjmIlugxW
647ccb jHp9zfaNH4rvVtJI7m+jthaRRmMIoO0lSPukntj3z2qHVoorbWNThWMJHDcbI0U8
def5c6 BcdKdOLh7jHFSUbzI9HtHn1hWW0t5ls4HuZWuJjEkSqPvEj3NWphaR+HbOMWEF1A
a2d7b6 /kNcxOfJfe77vJX+L7vV+nvVVRJJoN1bLZWJS9uIovtEql5YxkD5fTn36V0nii2l
195ea2 0TVtP1LUbaxvopJAiRIhjwIsY/yc1zYiSjK0l6Fe96plPxjZIkmpXaNDHaS7PIgQ
708174 iR48bVJfBIXcQcYPOK5iCHcOeRW14gurldU1i0ljgtvtdwrPHaj5Au0EDnGTjBJx
9b69d1 ySazYeD9a2oJuOpnTjyx0ZBho5AUOCc9ulHluVd2+ZnOc+lSMDuBzz1oYlY2J4xj
064bac pW3Kilud98P2jk8JtG508mC6dR5xOQOo6UUfDCKWbSdUVJECpcqRviDdRRXLU+Jk
160321 SSuf/9mJAEsEEBECAAsFAjWitlAECwMBAgAKCRDhc83TCdDTVWA1AKDfhBGtiKwX
b3e763 aSAnRh2XrnoRtaBgUACgr4QODzAM7ODukFHgfN0bs3j/xY2JAEYEEBECAAYFAjXG
f51278 DMcACgkQS2s0ZJ1JZYTZUQCfXrlB9+RSv1vNm1vDFxaaUbGuXOgAn3LY4CqQzJHJ
6362fd N+B5eV8WZiaHnDV0tBlCaWxsIEJsYW5rZSA8d2piQHBncC5jb20+iQCVAwUQM3p0
--52ca 0005abcb7a940110219 Page 14 of samplekeys.asc
eb76c8 MC+WpjI5nZKZAQHHvQQAiWSgTRtwGrIJ40wh62+/qC7pACTS/XNePtMbLTiw1VQn
ecd1aa xoHVWw/DCJu7EH7snDchh3Ydq/YpKFLwCv+RzF/iiBPtBfsXLx842gmDotKBUrAL
6fadf9 KYGbAm9CXHJaCTbNPmoCC3iC3STh1KB+SweK80qSYzuRlAoItr284ZAuJwGg4UeJ
510984 AEsEEBECAAsFAjN6a7YECwMBAgAKCRDhc83TCdDTVQFbAJ9tQs+0VCA0Xfirgo7F
dd3f5c R1nczz6RrwCg+Xx2dT6/nAq2CZTQllSWpYm29XmJAD8DBRAzmJVHF7ZpNAUlQZsR
db99f2 AnYbAJ4h4PFhgpU1Na33uk0MiKj1o4GPSwCfX1mH/IpsNB8mPe9YllofrJCvh3eJ
9d941e AEYEEBECAAYFAjUbjWkACgkQ6xCd+fb4MxilAACfRzjkHq23QiE9J9VPiN/fIAio
26898c JagAn0al8tV4RIokNX4Q2leBuhjoiIAhiQBGBBARAgAGBQI1xgzHAAoJEEtrNGSd
c1166b SWWE3w0AoKtUEeWU1tvBqDKDXzRHvELmbufeAKDnnErY/bzEhYuTlxGJpkFp6XAG
72e40d y7kEDQQzenJ2EBAAwqxbH6o1ajzBcZ0paJrnSg49Rm+nwPnniXbaDQY3Rraevj+o
589ef0 ejBg+LjX6wNmePaS71uE+v/jlSravQ2493QywLPyB5gQeOwPxd9rR1i0CoOgPQ73
72c1bb ftM94mk3h64qtEgYl+UkpT/imo/e50hhUNyMypmvPeKhrIlL6lCdoV52n6nHSzqo
4ada36 KFC7MUfOw54SYyeYNMEEhJ8XInGB5fnmZQU91OmtExFJCRF3rZWXVvVEj26psxPD
d67276 1Xvzr5k5SUss1UkqbPaHdMmRRKpKBcZmMuLgY/jl+BiyEHBErnLskFdN+F0odJ72
fdbc4a cUsiD1RdEEzt1BuVxfgdXmYfcSD9gvKV1wUax/O/o4c3KUTMIXFZGpi8WXFg3aU3
a8a06a JvUByYB6N2Mpj4uyIlP17Ge3U5xnVllYD4vgiKz6paCJ5ekC43GRenmVRXhX4mKq
3d6932 th2Vszu6WDBqqcgknAsyMm9T9gAHVCF+jZF4Jp2KQGvT4PvpgLhCBZllWNotXXl1
145ba7 y2LntKdGk8b3RHXdPqOx9q48NFlLd8sD7Wf5hSGWr89ga4eeF4I0URcVhrfsxohD
df823d BFwqBW5/NJWBfI20YC3Nxs7mmh8w7/gSupC5zt8R/qJDUF4TsiQqbjV86NBJSsQo
c1e87f +RlZACVOIWjj8vnf1iRDveu814G0P5GDJ8vqHRLmFtdidzc43JobZxXwMecAAgIP
921b92 /1jE72guwgacV4VkYdvC+rXljp4yBOVsZdFsJgxhBy9mx2ew7vjkvwSSfZkLY5ad
e27d36 FzsAMpATjL5EZb5+hb2jxNsIoL4Rlnl3drQ+aLv7jO4zVX/4GTU5CDXvI7YbcKe9
8001f6 AwEfXHJYN9esQJQoByyJIrUm9WWhouZlm6W4aaSP9yQIe1cxELk4JlzFYJaWfLxI
4d45ea 3IqfqDXcAU/4Wks5UiiudnvMz9GFOeHSn/xKqoVLd2mNM9j3T+4g+Ve9LLc6XNxM
0e0bba kuOT9Ozz4U7Z+E5S8L2xW4I5UsQ43HZSn39bl65XzcexdfSm84ubGbQsXFRuPA4a
d0d8d1 FK8rYyy/G1ngzqEXSc/2zsIX/li7YaTUskA+3l7GCkVO05F1MZgTb3pHTaKpNE7r
db193c 4vsBonQ4CxQ/CPJ/gxsuNUREWeYVayMxnyBrhfD7QSEqVBQHhehlaZafWolOI50s
16c559 I2rnJXr6b2yoF1d2jKya9DFKJlqlhh/1qwo8pkchsjmS1YUWMRXBvUpQRGtz2N8b
33532d 80C+VEm+cxZf2zcP5hcJD8HS1FqHWqfHOQjnpi2W/MVxoqvyUU/jzpm39XU/JAiK
7851de cFY2M/KondNWYOUitzombyH+IUAVpIrQrs84ENJBwKhOCtx0FVcxhVXcwIHB0sEM
9d4346 s/fHfwUu4pBH6FAI9v9Q0fo65+IKwfX5TFDAVzhTUPyHiQA/AwUYM3pyduFzzdMJ
d8cc9d 0NNVEQKitQCfTPEfXUKl/s0jzUkjdnTVxZLZbzYAn2zp+nS8EEHRyeu7K3iokjGO
916771 1AXdmQGiBDOBuDoRBADBV/KrslwacvNk+LsXz1A013LH4+DzkJ53R83Sy47c4lJG
a3f573 O/K5X5/kDjMjyN9llazoXjeqYJnBQmHIamT1UwVOLQFOktEsOd3Cuk+BqDKPnGpM
6e6df3 x+mtVAy8Iu59ZPC/gvIaDixWIdmZDKX6OfPTsPEssIcMV/gJ2blrjaU5nC/hsQCg
da8817 /6ec6Iimb7WdMAi/tBeNq7yOdm8EAKAlffWF1Ly0w3HWZU4f66gr4EwWkQM43YkD
f5d56e +85BPUQPhvNZM12HbmzryYVGba8xhtnVAqhv5axgDVP9ONFBra5OPwaPsvP8ryJv
f22fb0 MSW5l4WyMpU6f+N49vVwnqupdpYbYWslCUCIGoHdbB4naMQeW2/YP3fmva7NYBgV
6f0c91 1UJW4fMHA/93Ld88Sb3eNbJVmuGNayBeT1AMevQi8GJiOlZwaaT18zLLnmf6KwzE
874231 43+A+6HCPMoRBFEKLUR7znWCcQ/kAMuzB3JU6t6U5aJBbmMBXuqhBBKxnvWZC+GG
dfb230 iPQICAZmIgo06vSudk2EK0IK5nAvUk3FhqfLS0/1SUOL9NvQedjoZbQcRGFtb24g
5c6e5d R2FsbGF0eSA8ZGdhbEBwZ3AuY29tPokASwQQEQIACwUCM4G4OgQLAwECAAoJEFb/
674284 7csIIkCJq58AnAg9bbPI8Cjyi9PvskIadoqJbFPfAJ9AjckodheWNQUkIY4lQBmN
e7f4b5 LOMg/IkAlQMFEDOBulwI6YXI3bN6fQEBN/EEAIZn2dj/ydT3AJ3JxEvcPR2e3OPC
7fd98d CqF8bQZEtDWgA4Tx3KmYh/bhbrzU1Vi+tkilqpHq8s5+vCMuHWfrbzPj9zaZL9gC
1ab250 1NTmTpDrgWcrjleJRkNxFXEfrQ8+ROCqMX7x1+Ypo76ooGmKssd4egjTtjdvsWxP
9c4a90 kzP9c/2BqZLxAwJ+iQA/AwUQM5S+SBe2aTQFJUGbEQJe9gCgyMdfhU8GHBclPoE6
fa1060 oajkNaSs8fAAoKqwmfsUDKI9T+UmYeNZuawg00WHiQA/AwUQM5USBmPLaR3669X8
65bab2 EQIO4gCeNczTlCSxyxAhfbyTULBMbAdTNHUAniq0mUmLHOtKxSnfEdyKgtuCSwtt
b3f0cc iQBGBBARAgAGBQI1xgzHAAoJEEtrNGSdSWWEkQUAnjAkKBb+L0bsCXe41u9bmJNu
4b9a3c 49HPAKDUjuAzXmg13XUfPxfreXArsqvfuLQgRGFtb24gR2FsbGF0eSA8ZGdhbGxh
00aecc dHlAcGdwLmNvbT6JAEsEEBECAAsFAjQrFS8ECwMBAgAKCRBW/+3LCCJAiaTbAJ9X
b00e38 DG1/KaRGwHqg5A6h/UL9nMvv0gCeNdm9Od5+ROfU2LjR+RHRQGnvBHa5Aw0EM4G6
714638 TBAMANaiOKw+jmtpCdvcp/R5xAEG3CEUJYu+5vfLlKjkwlSzUyuHjghAGMWbRhGS
fb9764 /KLn16RDy0xoYO3yy72rAlSQxQyG0S6gAAS2+YX4DmCR/wTDBsg9P3k826AiwptC
8a5ddc DfdJDYUX4I7wavqacc2pBEuNtQIiqjmGd3K/GmaeWs/yD4IR4h/GXXtoj2Yni6+N
489024 n7qvjofwH3zqDl1u7uhlz9cUGgzEvmYbpWVyhwdVptcGMmQtcA+3/4GfH70yzKkr
19e47f UdXY1kXRM8kxhgxkktp3KntmeJS7M2BMwzWJGqxlTeb2YdjLdoV84Y8bEJLvBBqN
6fcccc 8U/BGsiKxMlcwbX6eGulMAPr9/z8solq5lRQ5ZAVld2FcPtKtjw3vV4tQQmvLMWv
36a3c7 S4G0uFF+0PWTmMQu/JeH9h6Y3Y48BH6S/zOwUvloGjg7Ehi40lT5BFwi+nMjw+mc
739098 zRX1DhLlLBlIPXZmNAdw18f+48GKtHPWOIDrhBEwnoiJdIq+Po/ZqnweasSCar1l
2a0ef8 wNhR0wACAgwAxBo6CY9IxxS3/0x1lANf0+DW3/9jj4/FxLiAxvFxdXBYMeJOQ0M8
78e4e8 gI23IyaouUj1GJ6aJAz/MLfMJoWMAW5Tkk53ECMzpvCiyl/DMHoWC5PtKpJU7RUZ
b5fc84 YfN49k/FuHFkjrun0/1wyzs8bNXBg0CFj7yN3YoWU7U3qFXqDbr8vq+mO/67Jd6F
c3c0f1 ITLx6lUI2DYL8kMKuN7rAusoHCGuZcAZiiDetvkbmi6UiM76xbwKJowkRATm7Fgu
e948ea kNWCIO+BiOLWAUtRVgtT+bTJQ1XqMmPGD43X06zj6qnV4s93HE12YstqeMF4Rte6
66d702 spbBcsEdNZRhqrONdqbW8DvaIdYRzDJ1pgBffHdDAjpeWupzBVVjfzTrY6eniSfz
d76adf pJfh296PbUBkGeQDo6Dfa1cdY4ngXtO4JBuZ7+53DpVg5j2YP/fWmu18rZJIMXLg
a67f1c VkVzsqrRdR90FhH99k7op0IxRH9NpeXi8VKZjnfTVj0Wgnu/u9I1SNtE5D27teGX
39fa66 0lE0wE6SJjmkiQA/AwUYM4G6TFb/7csIIkCJEQJMUACgjvxL2XGisyxsk8JN47On
a34013 vwTb4GwAn1n7tbTmPEhv2agAtDuXJYXZr8akiQBGBCgRAgAGBQI1olULAAoJEFb/
5aab47 7csIIkCJvUIAoK7UWEgBfazD4RySu3D5z1d6OM0vAJ47dRYGycEYCM2SsY2CLFvP
--04c4 0000950694e40110219 Page 15 of samplekeys.asc
d4e60f 8QHno7kDDQQ1ocdwEAwA8DPj7tnO+oWX7AY1VtUQeZILf8jsuRGbKCJLjJAmOUhM
8b7412 2qLbY8vEWsHb/n+qZy3ellrxBSP8jgvqfJUE1i0snU6YhIb0eU7obEYaCtS371cB
8a8f3b SOfQqViPnmTXmMJ3IfUmMAq0XlHeP4O6ZJik265QhqNSF0A1UgtF3b0qclMCuJFg
b41aa1 MHbOYGsz9E4bao6o/WM0vJc1yBu6d+7ImzVYv4yU1Rh7ZUJmf3qsaeJGAndi19m+
caf26f ptSOtbY4oa0GPzSkW/kLWjhh4U8I2+STLFFyp1JfyqvQbVq84GShcwvj8sGGrWAf
062248 DNckN6X3nVvzrmwz/NFJ0jNVAvJcnnJnkN5/pZeHxFv8jbja8bBBaFZcKNCLNNmE
b3323e ZrE7SPfcH4OiRWEihYXp+3cAJl6VD8ozPrlxv6H5hz/bTibXEZthW88R/fbRXo7c
b35fba 1NG27JGX3jK2xN1Yq1uEOuI/tqXRE8UCEXGRzTw85zV/EyLEJpp/dBliputQ0sGJ
dff0a0 zY20oKNhWU1Ow3kxP8arAAICDADGy4fxzkAHe7Y+0J3cN0qakepYzgBZZ5q/fT6i
39a1cb Zoy4m3ze7i/kAM9R5oDHkDiYAcQiqsJWPEXBf0aoOhORxcVX22EHp01nLKXaDqTd
ae0a4f qU4IzgNfUjIY0ekxmhjYN+nLcPwRw+216wsp2JyAlxtf1XvSXHjRzBkj+wgerPi2
8bc1a0 0rW7IeCKFGg1xfhj6Ff0mIaaX2oNBXHqf7aALqvKy3XyX/7wQRBQ1a5tlrzpQtBk
950b8b 1xyfPAO9ffQq8O15pd+WyWpNs5sZhtpsO45CIwqTEmBvFfTpHURx1CVmTV1ZdRWh
e12386 EL9fBr1LrBlCclAD8+QuL6ZL3yr1LgYGs38XbSgkvYpg4gmgUOX6qlUUK9ryqWut
d0c178 hgvXSbJjZDpocC9pm4Cn507s49qHFFpqeiYaFY1dKbCQG8NLo4uEuFvHtAvS8pWX
49e181 JSUXY9HtlLZEa6xRiE2zpXqC59f15CWlbV9QEAGGmzqxqyra3pdTm6uZzCftCdHT
a1e75e WSSABKB9f9q8bL8cx1EUJYm7OaiJAEwEGBECAAwFAjWiVqgFCQHhM4AACgkQVv/t
5d9d2e ywgiQInO4wCg11JQxzJNjHaH6rK/nJu9xAjPdxQAoIWRHkLTrc5wykguMG87FAsX
eb1b20 s+IMuQMNBDeC+vAQDADu7zXPzWUNrBTdGM6gKW77chDniWQOSxi3fBThl0wPPmuI
ff4090 2GYPSp8dODjIBOvAjRa/q8Z4c8NkRJ4Hh5XUoL4JElUpUMi7zpFIuIyN/9nRPAhK
eea3f9 c8Ayx++9EFaZPjDntl5kM4Sl3JtDk3u+7MHEmm2olRUFTP4YQZ5AjiLGKUzZru5f
39dca3 nidu7deGTsiIXX+hVOCR5DLxMgvLTSDSlfnhy9l+mmW5P/N8LVFrtb3Zc8ivPBRi
034032 b9oVt93Z0hYTiWP1ee3PWGyCMEhLC1h/TfbYgiIC2+v6Ve+TGxXt26Luv4h649rg
a4252b C6VKKBA+cGVBWnBjbLjOWjMMSltdW0RHQTjwl2V5vqql4cjqJKmqGTbEeHtFqflP
a2be79 W7XKxSykC8VuJeNtFpYnP7K0utEHt8Uxdijzc2qurYup+l7tlDbuYrD8me27iaZa
c8d923 UD+K6N51eL75O8dOnsCVNAuFwUrgytZhzmDLdsuw57ANJZy9EXqsNKwHNTu/xy3C
b1ba0c Ro2AhdhJyylyAabntDMAAgIMALmwNtLo7PZr5DeXsBb/ZwuWLMW5GCGlaACMYCop
5f3a7a IktuXSbXFbFik7tLBOwrHE8z5CowLDg3Z4B7xNFEaOfAAmtozs0WNG0yUM0f6Jw0
43d0ce FW82rfSZuIyCwOFHOAl8HDNJ2/6nApN9tTz740b87fez17+ZjmExZbAuwgWdJnHx
714f76 xVlh5JWnq2pdN2Lk1ogG4G2ag0f2GPEzspK3sXCHwHdUYR00kWZVamGBUszITuut
a70043 HKXdXPehAPZ+585LLvJ5jYAcOQ9PdDdixRHI6XLe4MRqcLiaQQuEM2+rK6hupVT7
25cc83 zI6MpTR6gRrf5MHepIp5kReMahPlg655J/1oevRDFubg/3gNn5ts4+TV+CcDoc0M
5c0417 6SM59e80Dm6LEAC9VPI8MXhRdazI7yFokNQGOFTaNeFPlK+Cu3Br03Tvy4kBzGZ1
604bc7 t83Qi6/mUs2mcOUQuM4UYXNtUI87RtLU2Li1IWQUcHnD1vXnLyMO3zqZpe50tqRg
3aa2de Ym0Mcfq2za5uhhVBSo200XluJYkATAQYEQIADAUCNaJbnAUJAeKFAAAKCRBW/+3L
82e562 CCJAiWsxAJ45MOy8/109GhpjmL85ZL2yB326KQCeJVcdgskgdXkMVjkzP4B8noHh
99100f i4C5Aw0EOWV/8BAMAM4JxxZTcXQr5DR3SGVIEpMHcsVVzDCDQ7RCh3EEX+pWkkPG
b8de5d 6MOKHyUgAe7V2mE2ZG5+n7E58R+wWYQuSS6v8fgj1dMMVtSL0eiMfPzLnnDOf1Ph
598d5c 4WGQXlu+DfmjHbzLF8y2tAdqAfDq8YBTm8lIds1K11Uolf0PH+/LNjhPWufxoZMp
564afa G8uHMqetS0kAQNsJjwGIK7hajo+hkQH80lpfOqcQivK/fUn2Qrq5m/vlTOVkvRax
e802a6 bLvaEySu3ERbNMrBFJFRtU1xx/vC4z/+fOabV71DIoNCxYxQPQwU7kIuprlcWTWp
ca400e ua5MBYxvd45Jz263AWnT3Ul6UEZ78bP1LgIuhPwO2qKkhFcpTPl6f3kTug/kl3sQ
e46c39 a3AM2fpO1kD8qxRcg90uc0nyO4yeqlz1NJWv1R+KFn2PITbloXpSAC+WfW5dY36U
5678e2 OmMTbddWSc+rFcY5PNGAjhVXuXOvQZZ+FjHR671KkdciJpk/sjvz2dIcqTMMDEFM
162965 J6Om21NQsutoPqNrfwACAgwAwPcfnRNTRfM/G5NRYreBLLlLAiPKHPQo2h0b1c23
19f4d7 kqgskPKUU2GqrZ0mB4qmmqo5YolzMrlmYhYjcaNizCYl/HYZu/q7bguCMniuzI72
e06781 wyE8h8p/HVRXhkakwweLOr6zbUiuq6mUwuEODc6jUxGl7DYoE3QbXxYzae5DDaom
a58365 DO04LoT5YLQBPTdghYDsy1aYEuxjfnONDHLxR/cbCQkie4FZYUqZfPtBTkoGA5iV
73b234 FaFzHD5Stngn5UQszFFUeINj2L0lN9AzvRqpSm9+TKxSHlkeYRAj47I+Y75tS7Un
dd0c3e AypM5c9D65MqAvHG00eWJ90k8vEAm7fm2ZovwZEMfm31NKmHFDA6b6pan7fxwqSO
b0529c 0/iDIk82TLySRzQ2xnbdGm3x592OVhHs9kEnOW36P398OSBnV6X5hEHxnXnKOcp2
5bb633 KvX5KsQkbXugJmghHHsWRaJW89JBEsZj/IyZ39jEB33kzfe8GZ/EbGFK+X9IYBHa
d1b4df 0XnE8XjrDT7pk2PUrvG/jWkJiQBMBBgRAgAMBQI1ol+lBQkB4TOAAAoJEFb/7csI
4885a3 IkCJwKYAoMGAgCMRcFl22ohAW29uIEVsl8F2AJ9BH/BF9pgydrnLkf7dmqC8Ef+g
6fb86c kJkBogQ1NrIqEQQA6O3m/9zu0Sb47LJfzE58LWeJlnx+6573a0h+zP+XX4oppqqK
16af6b HKBrHOdwWMmtcFV+G8fnuYn05UlKHRoCR2i5N4h5vlkJkEKzkB4oNpSpI9ukVPXG
dd4ade O1apKxbaP1fLUmzSkfE97AoivLEIHuyvOcryelavhtoaCwM/CTdR5w7FDVcAoP9z
6ef3cc ZVVFzlJPO7d7rbcrRYVFLUhNA/4iXA0bHtKqJcgFkZcHOim0Q9+Gw3tDE1QXxaJ1
ed0bd8 hdLaVklXyzBB8g9p9vsviBpTNu2spK07GRIP+ciy06BEJFPh+MM5Aa+jJbnAmo0r
650584 xxWH006o/u4IJoWay0zvOnQ3OeW+gj/at6YKOVSGc6TCAPLrNkw8/z5qzezU5csq
e2da36 XFsy5QQAxCCWmfWg5MGGwzJINo/fprXOrhTwsdnwjR4OEesMO+IFfPBLsFugQw9s
a91371 3vNorhsq+ShAj9YmUfA7AjyHDz58FlkJNWU6jF6e0qvk5GSfHhRLj7eH1NyubhOd
7c4a37 95q1DZ3QHog2n5kJAUZ/fVahFTZc9AyysjTtcA1Qd0YxLO4LolvRzLT/AAANbwEQ
c55bfd AAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoI
259603 CAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5E
2f32d3 SUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
44f052 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCACQAHQDASIAAhEBAxEB
f2a665 /8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF
285d5d BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcY
849174 GRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqD
bf669a hIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW
0996c6 19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAEC
--5a9d 000372cc83840110219 Page 16 of samplekeys.asc
128600 AwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMi
d9bc11 MoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
62fcd3 U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaan
d3486d qKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6
beed24 /9oADAMBAAIRAxEAPwDltg9acF96kKntigL61ncVxnln1H5U4Lg04LjtS44ouFxm
d70684 2lAIp4U0YouIbgUuBjtS4NKBj1/OgBAKd270pHpSAEUAHU9/xozS4NGDQAUce1KF
bce754 PpVSe9MMjJ5Wce9GoblrPoB+dFUP7UH/ADx/8eoosx2ZMkrseT+gqZCT1/lVeMc8
129a72 1YQDtTESCngCmjmrtpp1xc8qm1Ou5jgf/X/ChIRVwPSnBAewq9cWUNmuZGaQ+ig4
8bda49 rLudWjiO2O2AB7NzT0W5ag2TbQOw/KjAz0qlDqyzP5fkEk4+72rUjiSWNiJVDD+E
62261c Ef1IpqwONiDb9KQ9O1PlQpjMTrkZzx09cUscZkOEcE9cdD+VFhWIWYj0/KmNIw7/
20ab52 AKVYktZVGdpx6gVWYc4osBC88g6Oazrli7lm5J71oSLVWWMZ5FBSKJoqdoOeDRQM
f53937 0IxxUy9KjQVKoqDNlvT7c3N2kQBOT0zit3U9UttBsdiqHmIPPvj9APb/AAqhoSfv
965dd4 JHHXhf8AP5VgeLfNzvkyPmYey4J4/LB/GqTsXCKe5nXfiO9v58tJgE4HGP8A9dWL
21b212 aGbUf3flmRj0Kj+lZmn6ZJe3EUEOWkY9fSvZNF0K20q0WKJct3Yjkmm1c6FZHDw+
6a88e6 FL6K2+SIhmHJPXpUJ06azBKCfzV6Yzj8gK9QMXNV5YgOSOtN0xnD2bNf28v7vZdw
9ef7fe DdKhGBMvdgPUd/rThbGWATR4yp+ZecH39R+v410k9pEtwk+wbkPPuO9UGtXs9caE
0dad6f ZMFwm4dMBwdpA/8AHSadrGU1Zmc9wY4N4Yk4yrHuO+ayJbpLgk7Qr55x0NW1iaFr
e3e975 yBfuRuSnbgjOKwSTblWc4JNJshRW5dNRSx8ZqXnHFO27hUXEUdtFPkUq5AophYsq
b8488f KeKFXipEXkZ9agg3vDEZaaUH5cqOT0HNS+M9GjuNMaVF+cp5qg8DcAN2eO+AfbH1
cd2a4b qDSZBDpd1Iwwd6ru+v8A+qtBdXj1bT5YHfN1akrLGVHYkZx6df1rVbDje9zE+Hli
6a2cea skkl1Kv70Dao6YH0r0VVyOBXF+DIZYJ76GIZ2MqqCcADr1/z2rrpEv4YvMiu7c4/
bc24b4 hMBI/wDQqqOqOjYnbOMEVAVBGR1qK2vZ5iVuBEG/6Z5x+tPuJ1hPzfL39KsZRuIz
741591 g8VjX12HvYX4AgVjj3JH9cVrO+pXe5oRBHEOjMjHP8q5fV82pfcyys5wXQkBAQcn
40c460 9ePTr6YzlcT1ImkhW0lcuFSVsK2OSBgZ/mPz9OeQvblbq6McWflbCj+6B0H1rUv7
6c3ce5 x5raW5b5FjjHlqeMknAGPoCfwqlotkYbS51GclTs2x5PJc9/51KVyHoXov8AVLnu
a01a39 BV60j8ziqEA/cr34rW0sZfB9albkMjk08s2QKK6NIEZckCir5SeY5ZV+tSKmRQq4
da2559 qVRwKlIgv6c6mxurWTCiVflc/wAJHPSuSnuLnT9Ua7dmWRZ8ysnQgn5v0zXV2Eay
ee8363 CdGOMRMRzjqMfyNZOoWH22zvAo+cOuxTgAdCxP0GTiq7G1M63TrK9TT57i0IWaYB
b6a171 Y2YcDj734HNY99oNzLbWqSGaa83HzpbiZnYncCCnzAAYBGPfOD1HV+GpEl0iAqSU
c789d7 IIUn0BIrbCkECIge5/8Ar1rTVi5K5h6JYTwQ5nkLbMBQxJPTnJNV/EkrNf28S8A4
36f9b3 z+AroJjs+QHrzk9T71y/iiVY7mK5PCqAPoRTY0ZfiHTb02EJlaSWZm/fDzm2xrlT
f144e6 8gBx0BAyO5J7Ac8ba8+0tHC00ls68CXJweM4Lc/hXodrN9qtFDjPHGelUNQSOBSx
8191b8 AziiWqJjFp3OVtdJE8Bku2EVpbMd5bjcccdfqeaoXlwt/Ilvb7VtY5MgqMKT0GB7
045077 Dj8ah1a9ub27e285jGq/ImcKCSf/ANdV7W4QXHkbf3QTaPr6/nWD2G463NkW+AAB
067fbf gAcVe01CHxUcJE0CSDGSOcevertggEtJLUzexsxr8goqSNfkFFamRyIPOMZqQVEt
fdadb6 Sj0qCblzTmUXaoxwJVMefr0/XFQ3bCK6uWK/u3diFHBKkEfyI/OkjJDAqSCDkH0q
d07c6b LVGkkaORcDJIb0OR+vaiW1zWk9bGr4CvJXsJLaf70bl15H3WJ9PcN+ddvHKceteZ
f34e9c +HGeDxIjGRCksbQqA+T/AHgT/wB8ke2cV6JHKqJvYgKByTWkXodV1YLt7qCeJoYD
0edf79 MXI3EMox+ZGfX8DXH+L9bFxILUQMzZxJtX7tbl54y0mznMZufNZTj92QQD9SRn8K
35ce73 x9S8U6PLHHHIkgZSTvIXkn8c+tU7tDUJb2Lnh+WZtKUSptZOFB/u9qzNdutsRJOP
20751b bNXLbUoJLQvBIGH+z2rmfEd3ucoDgDrUt6CjucvdXbs8oQ8ng81oaVbrcShCoIdT
a01352 nI6dKxUdQ6zEffzke+T/AExXV+G7Vg7XGz924+Q+nPI/z6VmlczqOyuaq2sMZDRo
9796fd oIGMgc/nV6wX5j9aj2jGKsWI+Y1Vjnua8Y+TpRT41+QUVVibnEj1zUqEVCDUyZqE
db2cc4 STR1YVI5BsfO09x1FQRjOKsx4zzVpGfNZ3RDci4sISwIkCNuSUoH2Y5HUjH/ANau
6f4f2e st7hbqCOVA2x1DhWGCARnkdjXK6jEXtyYpGjf1B4P1rodKjmj0W0bczPHCMqecjq
2b98e1 cfiTQotOx3U5qcbrcZeWxxIVhWVXzlXXkfjWNd2cxibGnpEW6tkE9vSuvt7mFk3E
7d0cc6 Bv8AGqWoXUbxFiwx3rW7tubqpJaHI27Nah9+MP1AGMYrmdZmMpcAnL9T6CtXVNTy
32b6c0 7xRjkk9KxpocgPMCQSNxziueTu7FWai2ytpOltqVwUkO1UwWZeuPau6t4oreJY4k
333b47 CIBgKO1U7G1tbSHbbqACclu5NW9461so8qPPnNyZKfrU9mfmqn5nXmrNi3z0rE3N
c38dc0 +M/IP8aKZG3yCinYDhozn1q3EKxP7VSPGyMue+Tim/2xdndtESL2OCSPzP8ASsOa
1a216b KOmOCrS6HSouTUb6nZwNsNwjODtKIdzA+hA6fjXIS3N1qR2zzM8WcbTgAn1wOKe0
5a3a21 XkKGQY4wPqTQ6ttjppZXdXm/uO+0YW+rxySMQBE+PLz8xHYn0zz0yOOvUDpoE2KB
1d3e0e 2H6V5VaXkltIsscrQzJ0dT/nI9jxXV2Pjd48C9thIp/jhOD+R6/nTjVT0kbzy909
f441d6 aSuvxOkvNPEu5lyrH+JDj9K5q/0jUJFKJcS7T64Fah8X6O6KTcPGSOVaNsqffAqP
1a1e43 /hK9DIAN6c+nkP8A/E1o3F9TD2dWP2X9xzY8OC2BkkO5jTJtLMkYGOCe4rU1LxLp
3120d2 jSDyDJOp6lEIx/31isG+8RXE0ZSCNIEIwT1b8+3+eazfIjVUa0ulijfmTT3S3tbh
40b458 1K8lVPAz2/r+PvRY6+0ahLtnc8/Pt/wrPkJfPv1J6mopFzGrjsan2juavB03GzOu
ae39e2 gvre5XMMqn1XoR9RVm01awST572Ac/8APUcfrXFbVZRnGfWoj+7OO1V7VsweXxWt
e325a3 9D0f/hLtDiJRr4ZU4O2J2H4EKQaK84yTzRS9qx/UYd2TLnzACOdozUV1IR8oPDHm
135e51 p0GbhhVe7XEigHnPTvWPU9R/Cy3bgBUHbrUl0x8tPdhTYRwn0p1zjMIz1el1N/sl
5a59e7 hjkHI7c1Gjso+UkfjUhUliAM8VEB8tI0kP8APYjBIOPwpvmnPahVTnJOfpRsXrkn
cf3d79 8KYtBjy+5+mKjOGHOfxp7J1wP1pu3jgGgiVhuOKiQbocGpQODUUf+rJpmbRGpI49
8d2015 KJOV5ojAOT70rDIoJ6FbJHeinEc9M/Wimcx//9mJAEsEEBECAAsFAjW2KRsECwMC
425fd8 AQAKCRA34PGYG1NNGIezAKDXM4qOR9UQnYFln1l49ie+jdffmgCgjf4c4g4KsQzv
35e855 m3IUvWqPdHMxWgOJAEYEEBECAAYFAjXGDMcACgkQS2s0ZJ1JZYRmggCffc0zlrQ+
43c7c6 YrWeE3+VkMSskny3UhMAoIM5rPVC/N+tzf2r1bi0jWnLgNsNtCNDaGFuZGEgR3Jv
a377c5 b20gPGNoYW5kYV9ncm9vbUBuYWkuY29tPokASwQQEQIACwUCNTayKgQLAwIBAAoJ
a88399 EDfg8ZgbU00YHqMAn379SVgDPcJibeWTxeSYVsykn7oZAJ0ScHs7/XbwEkBNU9eM
58347d mI8wEQH3YIkARgQQEQIABgUCNcYMxwAKCRBLazRknUllhOAxAJ4kGsDAWZYpWaEM
1ba8fa P7cccPRToV+uigCfRmQe3IsifgWSoxn/c65NQnMh75G5Ag0ENTayKhAIAPZCV7cI
fdf0d1 fwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ
37eff3 +AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm
--c277 000e20731ef40110219 Page 17 of samplekeys.asc
29f734 /xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1F
c4fe4d HQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzh
172e36 sSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZ
55ca87 Jrqrol7DVekyCzsAAgIIANBoTMa65r/XoOS0RcMZjbAsr/VDcfb91SvFh3ruxRUx
9a3330 m5qBWPs0luw48LzAcnqUQ+RD6Uq+A8V1Ri9LIa0jx3h86eZy2A75RA0pv4GLsyZ7
e2d04b L4rOAcLh0YjV+GmsQunHouDwOLb00MKAj0Sj1LDYaYOww6/S6NJuk0uZI8/aiV++
599201 +EZ4kOLy4+0iOvpgl2YPvrm4GIA/lbaCevY0/E00GZHDMgWb0Mx1OYVJMDRyo29x
41dd31 //LFRhzaNVQDTq0iPm3Sh/kuBjAVC3J+T5AGVxNiHqcX+UvxInCBHNr26KrwahiT
2d0618 zmSXuasNGX2hYQQwrfGJZCTNDOxGhqhhoR+YNmFQlPiJAEYEGBECAAYFAjU2sioA
1dd5af CgkQN+DxmBtTTRh6KwCg1REHRJUE8XKYa74IbJ4bTSkN82oAmwcU1OE+4EuDH22h
5b8b01 RU0HCRU4JrlsmQGiBDWuaN4RBADARqPp+skFmp4sx1nZoA5wHmMP+LYhhLG4gvos
a97259 +kQhDiz6u3PxWbpOe881TuGLZ/bIBxmcHz/tmTy8OgIZg+KlzMuxGN+NAGcdTez9
f0be2c a73UPNRQ3cSRBvc3/N6+mkq35i9jjIbsqTM+QzH0LPzkFCk9b8HJR1qmorQFkg1I
16caae AFPw6QCg/6RaGZo9MTwGVHHbvJpfvGHTUqkD/jZhAeBUnlt3zRFawPlCxsxuEpDw
66e3c5 ZbwK6CNo/eM0ujMUWMr1/llfMiBALc2EJKOYpwfH1/BeT5Hb4pRPr73MM4tn1oKQ
def3da msXP/O/qi3OHmh1ukPLU4u3IXh8OjlEGsOnDR2M+GoXMoIRd/IuBr3K5AkzQOAj3
1b1302 1MW7I9X7SM4y8g1yA/9Tn4md1VE1BEQy1NuAuTrVtNuMdam83vtiBH31zWGsUw03
d966c6 EGnyAR49J9rWLl6MHyHibZAFCl4nxTx9YpfX9QY4GdEofpC44O0feaYBF8RBH7rz
581b20 hIXD4NSvj6GGOcRhQ3qzeuDukLwbu8KgCOYppGFY+SJcinsXgLV0dth8xk+lvrQ6
d2b64c TmV0d29yayBBc3NvY2lhdGVzIFROUyBEaXZpc2lvbiBFbXBsb3llZSBDZXJ0aWZp
c0d27b Y2F0aW9uIEtleYkASwQQEQIACwUCNa5o3gQLAwIBAAoJEEtrNGSdSWWE1uAAoMOx
a6205d W0mCkK/Od7X7M20/m3UwwHShAKCEYYlRhF01xDBRCHD9mnNPC7+hWokARgQQEQIA
26084d BgUCNa6TyQAKCRCsuxZLz3PsTD07AJ9DvS6p7CzSWmh5BqG4C90hR9TY6gCeP97U
a11e60 /LnfG0yQm5Mthi+hWIz8YvKJAEYEEBECAAYFAjXGRM0ACgkQY8tpHfrr1fzXhwCg
cc6fee jtDQzRBBcfLfcxQUMFjsJJfSK5UAoPT5aHyZGSFPh9kD6T0OzHOh7fmFmQGiBDOV
ee46c8 9tQRBAD/CnkLlpc+pVNBJ+OiRrKfhI+p9uqKur82mSFwE671V/ezEmxwMfmS8BGe
232fe6 UtMqEOppEoonIal24DTSetjpf8PF1zr9oJGB2orslqCXuKoiqbnHsdyOev6hxhR0
0703cb 9Bh5bLhiQ8kXEoNSm+uMdt+9DJOADKT53npWwxX5+PZVYi9CbQCg/97pug+JmS8T
fd429d OeHnn7gvVCalix8EAOrXYVmZ1d2yslVQvEANJ6g1m/+K6T/1uzrNDexkQYQyUeh1
607830 fQ+fJ+s2lHYtVQk8ycmlwr/LK1KRnIpBi2lAWtEKeNbUH7ENGud+IVOo7SW+4QjA
469e87 6vD2xdx5IXorheKaQziyGAe5//dsTkXLLYgA6shYgx3NyMtsXtmbs7lNGakgBACg
2dd782 qmVTP1s2rCfBeyP70lDJKj2OZVOCBK2bE0i6IuKIncI2do0v0WhIx8hp0rXKYYTZ
e34908 cPaq8uK7FF37TtBtaoNn2mzic7bZULtESGlQLjJArFVqzr/4cYhA2rkbF+GNPZCq
883aa9 4f7n4DZFUbf+abKdjMtdgsoHZOHkyee/H5lHHA40iNHLUf8AAAwMARAAAQEAAAAA
6ec01d AAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACgcHCAcGCggICAsKCgsO
8d0608 GBAODQ0OHRUWERgjHyUkIh8iISYrNy8mKTQpISIwQTE0OTs+Pj4lLkRJQzxINz0+
b151b3 O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
8ce183 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAJAAeAMBIgACEQEDEQH/xAAfAAAB
a9f11e BQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0B
abaee6 AgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp
e0f12e KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImK
ccfefc kpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj
314e5c 5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJ
af84bd Cgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGh
33f432 scEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ
023831 WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1
e14448 tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEA
63e238 AhEDEQA/AOrpaKKkQUlOpKAEpCQKhvLuGytnnnkVEQZJJrzHxB43u7+dorGRre3B
d92e2d wCvDN/hQB6VPqdlbHE93DGe+5wKzv+Eu0MyeWNQjyDjvj868heVp2LyMXY9SxyaT
3023ce oKdgPcLfUrK6/wBRcxyf7rA1aFeDwzy28wkhkZHU5BU4r0Dwz46891s9VIDscJN0
70112d B+tKwzuaKByMinUCEopaMUDEopaKACjFLRQISmuwRC7HAUZJp9c7441L+z/Dsqo2
05e1e6 Jbg+Wvrz1/SgDgvFviCXWdRdUkP2WI4jUdD71z4UN0qe2h82Q55rWttLjlOCOaHJ
8bd365 I0jBy2MRYx361KbVwu9eRXRt4djYgo5H1FWYtEECBWJYVPOaKi+px+wgcim5IIOc
02edc8 V0t5pCgBgB71lXNgUUn0pqaZMqTR6X4K1g6roqrKwM9v8jc8kdjXRV5H4P1Q6VrU
86cc72 Z58ub93IP5GvXRTMgopaKAEopcUUCEpaKKACuJ+JsDtplpOB8scpDfiOK7auS+JE
beffff gXw2qFM75l59MUAecabzLjtXUWaqgGelcvat5FuZcZZjhRWjbX2o4ytuxA74qJK7
95673e OqnJRVjrIpEwDz+VSPMGHP8AKs3TLprhD5qFWHbFTXtyLeMMsZdvQVFje6tcS5Kv
cb56d4 2rC1IbI2+lOlv9TnJMNoVXtkVSM80zNBcoVYjimotamcpp6FSwVpr+GOP77SKF+u
14a888 a9xUEKATyBXi/hzbF4psRKNyrOMj+Ve1YrU4wpaKKACiiigBKWiigQVy3xACnQAG
1d68bb APz5H5V1Vc/4zt/P0QKenmYP4gihlR3POrO2RrVCcEquQPepoLe/YqxlYL/FhsY5
d91851 7D6VJZRCNQmenGa17eHJ4BrK51xhdIpRTSQyKjNkk/p71YnnMk5QHHHy59agu0b7
023965 esSjLDkmiUPFdKZFO3oSB0pGqRVlg1FpA6St5f8AHggEfSiGF5kLXIBdTw1bcsDB
294ef6 OBkYqhMoAIHFO5PJ1MvTIUXxLG56IQ/H1r2GvKrCA/bHnQEt9w/jXqqjCjPXFWmc
d5f29f tRWsFLRRVGQUUUUAJS0lFAhahurWG9t3t503Rv1FTUlAzzK9tVsdXubRCdscvGeu
e09d75 DzV2O5FumTye3vUniy38jxD5o6XEYb8Rwf6VUQo0WW+9Wb3OunLQrtLJLdFlGDuy
28bcc6 SKdO0rt5rZIIwc01IJBkiQ7fTFPKzFSVmYfVaDSxcgv1lh2EYOOPeqVwcFiT0qSF
c6f3ea URfmOWFVblyVwOSxwKkUpaHUeFdCjNpDqM7Fmcl1jxx14NdZVawt/smn29v/AM8o
5e78f7 1U/XFWK1RxNti0tJRTELRRRQA2ikqOe5gtl3TzRxL6uwFAEtYfibxHFoNoGAD3En
57f65d Eaf1PtUV94z02BjFaB72fskI4/OvPvEt/dajqjzXUZiYAARH+AelNaiegkmt3+q3
0dab52 Jku5fMKnKjGAPpV1J90W4Gs/R7Q3LOIhmVV3Be7AdcVe+yupLxr16rWc9zpgmkXL
3f1bdb dXkQAtgVLNGY0ykhPtVOGQgY3FfY09zxy5pF8xH5p+bJqpNOwJkU/wCr5H1qRlZ2
e2b9e4 2Rg896s2+mtO4hCFlAJf2GKFuS9Tr/Dvi+11hFhmIhuQOVY8Mfaujrw1g0MoZSVY
--0915 000703e1de540110219 Page 18 of samplekeys.asc
fad7e0 Ht2NekaV4ytls7dNSimhbYB55TKP75rRmEotOx1WaXNQ211b3kYltpkmQ90bNS0E
7fdcca js0UgooA4GTVfEesP8sq6fH/AAhRyf61PaeEVuZPM1C5muW77mOK2jaIluuF5HU+
1b7ad3 9adoN0Ct3xXPRq+0bRvVp8iTRn2ej2lpiK2gVFHUgcn8a4zx/YfZ9WjnVcJNGOfc
582465 cH+lelRx4P1rnfHmmte6KZI13PaHzOP7vQ11o5WebabeS2V3HPCcPG25ff2r0+zs
25134b dP8AEVgl/b/uXfh9vZu4IrzPSLOG+1KO1llaNXyAyjoewrrdKvbzwddskoM9nLyw
919a4f HXPYj0NRJxUrM6oKU4e7ujWuPCNxuyqJJ7qf8aqnwtd5x9maux0/VbXUbRLq3JaN
63bb30 /Ucg+hq150PqPpzT5EZ+1ktGjkLPwhL1mZYx3A5NXr2ytdH0e5liTGyMkserHtWz
aad1fa d6hbWkDTTN5ca9WPFcNr2taj4hBstPtJEtNw3Fhgv9fQUPliVDnm/I4a4OXGepPN
422287 eneFIo7rw1bxToHXDABhnHNcLqGiGz09b2WXDmcw+XjIOOpBr0bwzD5fh+xA7x7v
2245af zNVayIqSUptozbjwxFHM0llLLZzLyGhbAb6iol1bX9KI+1pHfwrwSo2vXXyxDKyE
28f826 dOtZuqW43Lge9Y1HyR5h01zysQab4n0zUmESymGY/wDLKUbTmism70e2vWKvGA2M
8ec170 hl4IP1orD6wjV0Hc2nb5cdjV/TlzBj0Jqm8ZBIq/po+8PfNc+EdqljfEq8CwVxJU
062723 G1ZGkDqGVxtIPQirL4AZj0FQBSAuepNeqeaY114Q0zybt7S2WO5mXKuP4WHIx6cg
af5d84 VURI9V0xWkQZdcMp7MOCPzrrsciuWjT7HrV5af8ALOYmeIfow/PB/GubFK8U1ujp
42558d wrtI5221Cfwnq4jVmlspfmMZ9O/4iu8sdSs9Tsxd2soaP+IngofQ+lcj4t00XGnG
add2b8 6QfvIDk+471k+F7O7u/PiFxJDaSgJKF6yd8e31opVl7PmZ01qKnqtzabUG8Q6y7K
66fce9 u6wtDiMEcO/qa0JyttbNIRnYM49T2/Wp7ezhs4VhgjVEUcAVFcDzry0tR0eQSP8A
395b9f 7q//AF8Vxup7WouxdlCFkTvoVtcaVBZ30fmLFtdsHGX6n9Sa1IbaO0toYIV2xxqF
147812 Ue1SzL8j08LmJT7V6zdzykrCKSzFCOMVRvuUAPVRiryjFwnucVWv0AGe5BrmxP8A
e51d9c DZvQ/iIyY0/0rH+zRU8a/v8AP+zRXk3PSsTNygb8DV7TV5f2qj/Dgcg4zV7T2xJI
a8a8a9 vtW2F0qoxr/w2WVXzHVOozk0yUZlGP71WI/3ULSnr0H1qHHzLXsHmD65nxCrRSi9
566e80 jXLWr7yB/Eh4Yflz+FdNWVqCq07AjIYYI9a58S+WKfmb4dXk0ZOsFH0S7YEFTCSD
c4534e 61U8M2qw6PbuR8zAvn60rxudBvrDrJbo0a+pXGVP5fyq3pi+XpltGRjES8fhXnS9
dd7980 2Dj5nop3RdIOcVVsD597NddVDiKP6Kef1z+VSXk5is3dOZT8iD1Y8Cn2kItoIoRz
3378ea sAGfX1NTHRXE9XY3HXIYe1EA3W49qew/lVHTNQSa9urMgBoXwB6j1r2keTYu7f3q
8bb1eb n3qjfNmYJ6Ic1ov8rg+hFZdyd18x7HIrlxcrU7dzpw0bzuVC23d64FFKy5Boryj0
4c6ca0 D//ZiQBLBBARAgALBQI1tioiBAsDAQIACgkQIgavhCET2fkdhACgyjaDEewhker+
4bc9b8 aIpyXgxTCNu36nAAn2sLBK9cIIM1XGO/XB4ZM+YWIIZ1iQBGBBARAgAGBQI1xgzH
53d96d AAoJEEtrNGSdSWWEbRQAn1SAyMwVTYNUTxBFhrP8Rg23PVWBAJ4mGCXjil8gvJ1j
8074bc Hb5XzfF8Yo1RtbQfUGhpbGlwIE5hdGhhbiA8cGhpbGlwbkBwZ3AuY29tPokAPwMF
ce6497 EDOYlUYXtmk0BSVBmxECh6QAnAiI5GLQO+sUDhbQG69am2hgGwbJAKD7vZLfFhp0
2c883d NLFHcnWK0asOfzy+J4kASwQQEQIACwUCM5X21AQLAwECAAoJECIGr4QhE9n5qioA
92d0aa n3HTlxic24i1rC755A1a+K0iquuKAJ47V+ejZRfGGBMEDqxV58EHlyHtc4kARgQQ
24e937 EQIABgUCNcYMxwAKCRBLazRknUllhF+OAKDw0H0UPFJi7ywkknehY821jwNEawCe
405420 KTBjlLBu6+/e54zE09qSBNSwnvi5Ag0EM5X21BAIAPZCV7cIfwgXcqK61qlC8wXo
0e46f0 +VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D4
49e587 9Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNb
e15d05 no2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbz
fd9883 ySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLW
fd8ce6 hsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsA
abd354 AgIH/0PYVL+F9yKHQsIici/MFN0okZx1AWc9B7jyfHWP8iIc51JIQV9gd2suUS1C
2f82c6 OEIAPZEVcdnJc/X8IuPN8N1wMXplmCqM4MpDhJ68KMUiZ75dTCAHTuhrUqgUt8CJ
c4a43f F31F+jptITJl73DQ9V/KphzplvD/2KIsQvEmteyKOqhPVjIgV5WBy7g0n/+i5Oqi
e2273c XffZQzuPqo95qL6dlQ1Te7z9Wk8q8F9BZEP4J1w+ERYHhW5RMKaNAQ3ayl+RsAXP
1877a2 GlqNlC2nNxVzq8aw626cem0IxChR/LILzKtmx9Lrd/cJx4qIzmZPhHdo4HZfGdlh
2ad7c8 gITby4c0Vb3p0ycVp5BG7wsV1dSJAD8DBRgzlfbUIgavhCET2fkRAhIaAKDqL/0s
90d00a y1Nr7Jpe0pSOUCReJq36uQCfW3/x4iR8rXBBe7Y/RQzGH8htbeCZAaIEM0lzxREE
010845 APJLIH9Pcp9yrb4R7W6/znGdLHUjXdN86ExN54iHBI1cThpj9isWa7ySlzjUbGZo
8555b5 7zGYp4oVPbaL4CG6XG6TKcWcYh1rDiUloJJ2WZPsfVJXBCc/QfDY80699gZbBzhc
313634 WnjevLRuCtC7b/mwXnIPG7XKG3w5iP+fIzBSzFSNUhR7AKD/7jCDVFtPnz6JAEIx
59a169 4giNE8WniQP/aq4w7P5Xw/hfGPb44guNUgCas2uo2ZkWWrC+uQkcAY2GjS0Jht6Q
7efff5 BNO8qB0Fhw14SvEmbx/6EZcsp5/8ZJxWAQQytGMjfgXxDouaqFR8TJouGrhP+ajm
925c5f OHZsLqxQNisBg9JJVNaUhPgMJv1VHi7fQASqWJfjRXy/lKwNCVmONvQD/2du3WHo
fc0aec aOhnau8TnR33a3Wlyi0VRkrPaOqQ5yTOA5hJPlmLEqzydJ1xzzaM4wnYFce4THtN
43d40a v1n1NemYx9EhYip+gCVHwIT1eHMLTbU8h1J1etFMEff8CSx9lW/R1MZdRUb6+xbE
048a46 qmriW1RiNtJdiGSQSResGhjTasvOfjQx5vctiQBhBB8RAgAhBQI1rQAAAgcAFwyA
c78404 ET/HMgQdI+nqZt21AJydvCHfdNxhAAoJEGPLaR3669X8RLMAoJZY1/zB2NLY9LbL
2c9344 QyfwFCkniom0AKCxm7HBBirx5pZfRVjqTkXU+9/8CNHKH/8AAAraARAAAQEAAAAA
24c01d AAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACgcHCAcGCggICAsKCgsO
cc0608 GBAODQ0OHRUWERgjHyUkIh8iISYrNy8mKTQpISIwQTE0OTs+Pj4lLkRJQzxINz0+
0c51b3 O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
d6e183 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAJAAeAMBIgACEQEDEQH/xAAfAAAB
87f11e BQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0B
1faee6 AgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp
f0f12e KjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImK
30fefc kpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj
ec4e5c 5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJ
0d84bd Cgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGh
ccf432 scEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ
933831 WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1
914448 tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEA
705496 AhEDEQA/ANGiiiuc3CigUUDCoZrqC3H72VV+prN1zWhYJ5Fvhrhh9dtcfcXs0jlp
--5518 0005c5d468340110219 Page 19 of samplekeys.asc
c24e7a ZC7N1JqWxpHcSa1ZRjPnKR9ajPiHTlGTcL+HWvP/ALSS2On1oMmz7xOKV2Gh3a+J
a025f3 9OY43sPfbV221K0u1zFMpPoTzXnKuvXJ+lIZ2TnYynPDKaLsND1CkrjtI8TTW22G
852c82 6zJH0yfvLXYo6SxrIjBlYZBHencQhpDTjSEUwGUUpooEWKKKKYBVDWNRXTbFpcje
8c3c90 flQHua0K8+8VX7XOsSRhv3dv8ijPfuaTGUpruSeV5GYsxOST3NQrtJYtIS3tUJKi
ecb69b LGT+FW7GETMkYH3z+lQ9C1q7DIbUynPIX6VP9mDdSv410sVnEsQQLwKil0qN+UJU
94ceab /pU3Zv7FHOT2+xcbj9M1TYBmxvINbl5pt0pyIww7kDk1jz20nzDyiCO5HNUmZSpt
fba58e DS2wfMA4Heuh8P680GLV2DIfu5PT2rlhbXPXa2PWnKzxOD90g96qxlr1R6rDKk0Y
d047ec dDkGnmsTwzeC6sFXfl0GCK26EA00UGimInpaKKYDXcRxs5OAoJNeV3MolvJJDzuY
386a00 sa9H1yUwaNdOpwdhA/HivMgw3H+Jj1pMBeZGxjitrSIQs2RyQOfas23gaV/lGewx
0f718f XR6dZ/Z4xuHPes5M6KceppR5wKlGOCagUkdKmXDdRUo6kWCkTLzjpVCe3iY5K5/C
e89570 pmPpUMpIUe9NgZ81qpfhQPoMVUl0xZg24ckYzWlIQGx+dRySACkiJJMzfD07WWop
9ae991 E2dzNsIFd1XD6bCJ/FKL2Q7/ANM13BrRHFLcaaKDRVEliiikpgZHiG5hW2FtJG8v
83d31d mkZVOtcXqmmJatHJbuRDJk/N1B9K7HUGT7ZJI/IjArnNQuEuZosRsqZJCkd/Ws76
4649f8 nW6aVNaEug26+SWOCexB61rsVVcsQAKp2lmIbfEfyyE5J9aZPKZEPzGNlOGDKTg/
293121 hUNlr3ULJfyxSfLGSnXI5qWDVreUAFgG781RW91O0LmGF8FSrMj4yPTisqa8ldw7
6fc80c RyRgnHzgHNNIlzadjrftCv8AdqMsZJvZRmsWzun2/KP0q59qkgXdKhG/ke4qbmqZ
f18365 bdfl3EcGqUoGeKZLeEyDfuQL0Vhim71Ybt4NMmTRP4bjMniC5mHIRdufyrra5vwd
a88334 C5iubpgQJHwD6+tdJWqOF7iGikNFMCeiikpiMW7hMs8q4zl8/WsG4/fayOPkXgDF
58831b dNqQMMhmIOxhyQOhrlrVvNnLZ53HANZPc7Oe8Yo3UwBmoLyFH2yfdYHGaVX+XrUo
d33258 CzJsZiM8gjsak1WxTmTegbdg46CqX2MPJuLnArWkse7NtPqpyD+FVo1jeZoVd3ZR
8c3ede k4TA/PNAWIAjIMKoOeOPXtVO/imjdWDZMKjCZz9MVvW8IUH5MsPxxWbfpi6Rv7wI
208a5d /rRYUo6HPyveM5aVG5GS26tHQolvJ8SsPL2njOCfpU0tsjtkHk9cVrWMUFvp6q0Y
b98071 JDF+RyPpVXuc0ouJoaLIv2RrZUCi3bbwMZHr9a0TVTT7T7NGXLHdIAWXsDVo1a2M
b5ddf8 XuNNFBopgT5opM0UxDZyVgcqMnaa4O0IjuSGbJ3HpXZ6pqMGmWL3NxnaOAo6sfSu
bb3bd6 BlmAuzKqlQ53ADtmpki4OzN4nHOeKZNefZ1yAW+lVEvVKYPXFV7y9/dLHHgMx61k
576b7a dd0lcuG5muR80ghQ9e5omZtPTfaSxsD94OeSazvst+2GK8dfaobi3uhyyPt9cZFN
e65d28 D5pW2NSHxGybhKPLfGDjoRVe41WG8IRHw2flPoayvKSQ5kwFHvzTYkjhl3YOz61V
9af4f6 kZupLqdDGNmDOhfHUxHr+BrZ0ueC+k8pYmCx/Nlv5Vy8N2zLjdkDoa6nw7F5dmZ2
ec516a HzSn9KUVqTUatobJpDRmkrQ5hpooNFAE1BOBknA964q78X3smRCscC9sDc35msiX
b9916c Ubm5fM08j5/vMTWqpshzRqeK9TW/n+zRNmGLIyO7dzWZfARW0UqnIwKqsd1SiQT2
63e839 T2zn5gMpTqQslboFOV20+pTFwwyd315p4mZn3E+4qiSR8p4I7U+NySazcSudnZaV
4ab926 eCa3CucsKqahNLC5wrIueo71nWVyIDw/IrZhukvGVZMEBe9YNWZ3RlzIzM/aIyHC
e9b43b tn1Xms6WDEwQZ5rYuDDAx8v06VjXFwScqeSaqN7mNR23LtsgQ+Wp4J/Ou5tWEUMc
7686c7 Y4CqBXJaDZtIRdS/cU/ID3PrXTI9PZmbdzTV8inZqnHJ71YV8imSPopKKYHl/XrS
4c2a87 jqKB0oNd5xCnimsM8jrUhG5aTGOaVhleWMXA9JR/49VTlfYg1ougYZHBqGZUcfvT
1bc345 tf8AvAcGsJR5dtjZPm9St5h9evpU8V9LGcK2ARg1EYgvR1/Gom4OAcn2qLJlXlEt
c19d2e G8csWJ+lVy5Vg5APOQDSovOTSSnNUopEObZ0Vj4iAjVZoRt6Apxj8K27PUba7/1M
d4c8e0 gLDqp4I/CuEhJCe1ThmDhkYqw6MKTpJ7DVRrc9ER6sJJXI6d4gkjAju13j++Ov41
287c36 0Vrdw3Kb4ZAw9uorJxcdzVST2NNGzRUMTUUDPOaKKK7ziHp90j0pR06UyM/Pj1p0
b73b4c jLGNzkKvvQAnABY8AcmiBmlga6WJWEbgJj7349v0qpJI1zwMrEO3dqaV2L8oJU/e
bf95d0 TOA1ZVE5LQuDSepee2sDbgrPKtx94hwMc9s1nyxbLjacfMu4YGK17q4iuIU8qFkj
7783ae hC7yBnzCf1OOayrof6bI0aMuGyA/UD0rnp3b1N6lraDVGBTHUlgBVlVWRQy9DSCP
01a6f9 En0rosc9xEjwuKlVMCkHWnZwKuwhxOKlt7mW2kEkTlGHpVbOWp5OKTVw2Oz0fVkv
e921f3 l2NhZlHI/ve4orkba5ktplmibDociisJUnfQ3VRW1P/ZiQBLBBARAgALBQI1tTM0
e939e0 BAsDAQIACgkQY8tpHfrr1fxbOgCgqTp0fS02zhQI13kd7yqpGnkb0yUAoLnsvOFJ
0bd4ff HAgDxUt0YJp7u2RdpartiQBGBBARAgAGBQI1xgzHAAoJEEtrNGSdSWWET7sAn2nI
2b353f NVk2liOR4fJd9WB5f0hjQaSOAKC4cWfvdllClaGgrr6C1Qbdk/dw5rQiUGhpbGlw
cc66b8 IFIuIFppbW1lcm1hbm4gPHByekBwZ3AuY29tPokASwQQEQIACwUCM0lzxQQLAwEC
2b2995 AAoJEGPLaR3669X8EYYAoI/npyskFaP8uBbrRTEMw01xfq0wAJwJlP2jkUIfWtaK
318031 ZI8Xk0DPIw1HgokAlQMFEDNJdItleYS4x6lm3QEBiZgD/0vhIcNAkbomAzbX4Q3L
0a4063 lb6AglbaX+9BlBmBzZSVf3DyogKKPH/1Fo5N01PNyIcyaJuJHzWRJoajCqVqj77I
0b4349 jw+afjdy6+dMZhh/q3pajtSmgivvuCqlxChPBPFPQ6qGwdF9Nmsf5JEwl5vGSrHS
463706 xCrPVqA4+ExLCee77FYMz1GjiQA/AwUQM5S+SBe2aTQFJUGbEQKs/wCg0dv0B6xv
4857e8 v7+xbNygVdQDvNaMBPAAn0bzhh22EeciiQB7hhXSR711DPOsiQA/AwUQM5T4yay7
a3e2de FkvPc+xMEQKtagCfUKCE7ZsX5ayuZyL9eNo0Bl+8/MUAmwfwutlVxTgscZc9njOO
fe1cd1 S0WXl+EKiQA/AwUwM82l14wELwq1FyxaEQKNOQCdG8MzzDtaVdqSo1OM8hTadh7V
260b82 kf0AnidmhNaeBaXBCBjoAQvQq8E/HT7HiQA/AwUQM6gDTfAgc1f0FJUrEQL9ggCd
7d0943 FRYNedPneiWhVe3NNWmr9BnsC3sAn3ftbylQklJL81nhVqrWHiRd2Od0iQBGBBAR
5df11f AgAGBQI1xgzHAAoJEEtrNGSdSWWEoDwAoKIU2G/4Ap6GNYXLdpEjVo9EO+zqAKCa
8bf277 Aixg+1XB/tesUHKdRu4EaHbWtbQiUGhpbGlwIFIuIFppbW1lcm1hbm4gPHByekBh
df8f66 Y20ub3JnPokASwQQEQIACwUCM6gCOQQLAwECAAoJEGPLaR3669X80gEAnAjbsE6d
008379 /ZF8Plr0/CU1YK8/v2pYAJ4pqpQ2nuBy/cP+JmAVmZKllVNcMokAlQMFEDOoAmxl
b6c0f9 eYS4x6lm3QEB9YkD/1HBIC13gpUJHOH48rouAX2Z8ork39x0EU4mWX9tmsgGNnrK
287c08 pncfjWXhNWeKbXQ9jAGPTSQAQp25inbIqk2F+/A7rB4tZ1FR+vvKR0tEqmg9RQ3f
9bb971 Y6BMgXTIVkRO5svAvWYRUXouZaXs5EyIghG0wiRvkYyxSGhG28j041f7fuLXiQA/
d5d9ac AwUwM82l34wELwq1FyxaEQJFQQCgnPqBEf2IU1HZVHSk1zzFLOI79PgAoMgjiCrg
5fcc0b ykeQ17iSSv4Qz07FC7CkiQA/AwUQM6gDWPAgc1f0FJUrEQJqXQCeO8bXIx/HY9dY
de100f LbzbXtu1v5IdWrsAoM10c51Zh2ABMhXpcgERZZqCFKaPuQINBDNJdHAQCADKiTNK
463b08 DUVbHxFMH0z2tgxvpmdY/4H48vPHwi2KgwRD29g4Sybj4/YXP8QuUbANADUyhVzK
a1ea2f uxscyMsjRINIqnDCPzQU9Pk0tipVWPATewKs+gcIGnOaOOn/dRsAHAdy0u10pVY2
b1c4f0 DNO7rLpBGtmFQP/JWSBjx9Qo//U2Hyt4d7lzb84V2t8EuzVkM7wUwco+remXDX2N
5cfd7d Btmov4kAtN4fKbdxAYMNDuLWSyhBJhtgovNgJr3C0xIMwrRle44nOgSyyL8rdiJE
--eec9 000af50b98540110219 Page 20 of samplekeys.asc
0a5665 2ZdcupNt4k/fZFGhywaitlxoEi3aoZ0996/03rzIO8VhOgpjYfkxGtUGtAvrhJhp
63fa6e Y85Xgdcu+WuuEtnzAAICB/wOK/AAlZsF049BGTY3FrpjAVIyU7uu6ro9XosEiKLU
4b5444 iKDJIh7KIqtKYmsFxltSxoTb3LLQALoL9gnrDMlnsct1e3y2EURh+Br/n7eWzaNc
a31b6a MkGKYifsosErYS/OaLq8de81OSx2yMTm+mwxEkooEIZ3R8xzR+MlWhnU4y4kUegS
e36ee9 VM3W0S3cMdBz2I2lQEppj3dNqae+SCuzEfoLxGeUI8hRcwEmMABEU6EwlS4k5JrM
0d4b15 +PDg70zJSZicA9pipCf9daU9aNIXZ5N2W4kv9KV9EWhb7hpGh7kskVMZE8hWIcyw
5322ec Oeh/gwhsZaZxhB+dOrMTiPwo1KRffU3S8Nfkb/JfBNrciQA/AwUYM0l0cGPLaR36
b1d2aa 69X8EQI74wCfdUcaxo7zsZxfkI1gA3k+opzg67MAoPOk41vvIBlwA9sTKc8O2eJR
e036f1 tuyVmQGiBDOT3v4RBAD89JbKFMwFlwau+5/FxfYGg49V2j8UCEm4b3tpR64UAWi0
37b5d5 hc3pzlDDYv0FmtL5QmKqTRf47r6S3UVXM8hj7/flcVRiKZi8aBJDHCBuPNMdBjHv
37f9a5 iO9QIkn1hxOklzVE4EOAqLi0t+vbivIY7VXBvyS3Kec/LTsEwUuBusH0/CNimwCg
dc2a6a /yRJQ4tHBuSlXdKO6UyAbkXHYucD/RCkA0JvSjYsAjT02aW2u/GThuOwBn1ng7M2
d031f3 35dij3XY83UbX2nS2A+ltKwsDJjTmtM+MSZ0ck+xNc10eAb2+nUxmqjYuym5l1j7
bb1f93 T20zUQO7O+KDzVocor9o/qc0mWKEdHAf0SPh5rvXvuNqPTPH8swbwYbXxLfvfjrn
b2cc42 U/a8WodcBADss3JdYJH+Im7rnuGzMfc9/xpUnR1arfNieF9RVpYNbRknA2kBQeHf
ef4156 qOBs+MY/1HxDjNzDfBliWeYiUPos7xtPyTuntm4VIYAEryXNL2zdBKeaNCfU0xsT
bc5dfb rSBaVsPG4Dkc3CNNMQdZpb7uRlv1q6XmIWOBZN5WtvQdyPGlKCkF87QbV2lsbCBQ
0fb194 cmljZSA8d3ByaWNlQHBncC5jb20+iQBLBBARAgALBQIzk97+BAsDAQIACgkQrLsW
018f3f S89z7Ey6kACfcXtr7blmN3MF1+HW3cTYraoUoeYAoKxaTqowXmZatY558W7Mk3vn
3e8863 b9nxiQBGBBARAgAGBQI1r6x7AAoJEGPLaR3669X8TIMAnjdO66hNrsbUlhIy0qcT
2350d1 wHAqe08OAJoDPEIfQKWlptYUpvUQSMGGYDtoAokAPwMFEDOUvkgXtmk0BSVBmxEC
553c75 774AoIhBCaVfohvxroRrnfAG3M15Cfz2AJ9DZH5PJXvihjfja18v6mGcmnQX4okA
5154c2 PwMFEDOV0weP/qUa4gnt+RECDY8AoNjdZCSr6jHIHTu0C7cuRiDbfZFBAKDdDP5P
754bc2 11VlaFF7VmM6axwWGXMX6YkAdQMFEDOXUNNNtgY6eimbWQEBIqQC/2i8rl+hlIyK
50508c rUcmu4VD9usFQlep0PoZ9dOqUg0hRV3VZWxkceHOe1bbogJIy3bc0bHuzSB2/0DH
f66834 cGe3vcy9PQpcUPZ56+g72qmNroN0hzTiymR93SdVrumw9bpDxSdeJIkARgQQEQIA
f32fc7 BgUCNcYMxwAKCRBLazRknUllhMeVAKCZw4khfCdORNwYdfph/RRcf1Mq3QCguRFe
5bbf8f iVU2Ey0/RmwEw820GMECjqG0H1dpbGwgUHJpY2UgPHdwcmljZUBjeXBoZXJzLm5l
40f6e4 dD6JAEsEEBECAAsFAjWuj1sECwMBAgAKCRCsuxZLz3PsTEV8AJ0RqCZ4LFXm8JE7
1930ea bxLi6U6SesQ2dgCgumbT36Xm++agt000FiMxgMegPZvRzE3/AAANCAEQAAEBAAAA
c78060 AAAAAAAAAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoL
ccb13e DhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9
d6b990 Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
aa0c2b Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCACQAHgDASIAAhEBAxEB/8QAHwAA
1af591 AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9
d5e646 AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJico
c317df KSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJ
87dce7 ipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi
6a1360 4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI
a7d755 CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKR
e376f3 obHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldY
ab6242 WVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0
1196c1 tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMB
e9e6dc AAIRAxEAPwDhZL7yJ/3KkJgYDjFPHiB8FTHGc9608sxAKK+OuVFPFvAcl7WLgd1F
66c64d XY5G12MY6pIwyI1/A00am46xg/jWwY7Ug4to/wDvmoTDaZ5tk/Kiw7rsZ/8AahJH
370b96 7sj2FSR6gJMLtPNWmtbLAYW6jnnBNQmO1EYMcW0k/wB6pbsXFJ9CdHDYySGPQClk
db6f65 jckCMFyeoAzioDLGrt5fXHGTTEvzGfl6nio5maKmi+tldumREeuKSexu4Vy0TADq
938837 adb6v5aKqk5J61cluFnIjlkYKR2bGafOL2Zii4VcAyY+pp6XXPEgxj1roIrLRbqA
c713f5 JLFuxwCDjFVL7wUjQ+fp8pC9SrnJ/CqTvsQ4pbmYtwQw+f8AWpBcsOPM/WqLaHMr
3b818f YW5iP1yKP7Fu8ZE8R/4HT1J0LwuH67v1oqg2k368go30koo1FZdysNZnU/6zn6VM
72f094 mt3TIQHUg8citY6ZpbE5tAPoTTf7J0tQcQsPo5p2HePYyl1O6zhQpJPTFW0a/mBb
c756e8 7OML1IHStCx0zTxdqxjfC8/M2RW5d3NultsTjA4xUvQas+hzqJ5oHmAKR19CKhl0
706cbe 94y207kJyMdRVwhXbccn6VoQW/mqGwOazOmKOdGnzyvhFOfWrMegXDcla6u2hji6
874f2a IM1oRxIaRokcOdCmHGCCKhutOv7Y73RipHUdhXoscEY6qPyqR7aKUbWUEHsRTsDs
78df53 ecWNw4I56dq3zqbpa7iWAHGfStC98NW7N50I2H+IDvVHVtLb7DJFbfvG25AzTitT
ba5388 Graxzc96jzsTKDmljuY2P31/OqT6FqX3jbEjpwRUf9j6gvH2SXj2rTUwsu5qC4TI
b49b1c xIPzorJbTL9RzazD/gBopahZdzQOtRM3ETDPTBpRq0AbLRt9Kxo7G/Q82s3/AHwa
dcde5e kMFyPvQS/ihp6hZG7HqMEsTeUGVwPWoXuXcHLE+grLhV0Y7kdQR3BFWUbjBNZyNq
7c296d aSRatJ334fp71t2Nz1GeK59D81X4XIwQelQao6FJeelaVvIGXrWJaPvAyM1pwlF5
2880e2 zg0y0aK5xkGnq5HeqqyoRndTvPUc5p3HYtOTs571kalPHDAWK8sCOKveeGG0txWH
41ab99 4kjb+znAOCOQapMyqRujF3nOVY80+OaQchyM1zYuJ1/5aN+dO+23H/PRuKu5ych0
fba4a5 b3M2T+9bH1ornxqFz038fSii7HynQJcygcE/nQLiXPDtn61z51a8YAFwQPanLq1y
1b758d BghT9RSuHKbl1O7WsisxOV71z0cx+tTtqryRmNo1+YYyKpKCBx61MtTSmrF+AO5G
e0ef38 PzrUhVY1Ac8d6oWILYqxdLIyDbkj2qDdbFi51aRMJagKAOtZr6zqEcn+tB9qSO2l
03fef9 uJwspZIx196iOkzea2I+BnDZ+9V9CetjZ07xBMxCzda1ZtUEMYdsgEZFc5ZaXKtz
4ca19e EX6bua7DXNES70JZLc4eLB4HUd6k2TstTnX8WSCTEcJIzV261xNS0to2jKyjBB9f
d17f9f WsS+0pLfTVnSWRpy2CF6AVBpzzF2SbJ285NVYxbvcuDRrJ1yLmZWPYqCKadBgbO2
8f2790 9YemU/8Ar1LHMo53DH1p/nK3CsPwNXdHLqVDoH/T4uPXYaKvCQbMbutFGg7s5YPj
badac6 1FOD12n2jPWOM/8AARTQ8LDm0hb/AIAKLIOd9jk7Y7514DY5we9bBSSS3/0qFAHG
8b6a90 VkUYq+6wFGCW0SMe4UA1BLaNcrEpZgi4PXoM1EkdFJ3iynbIYOGPU8VrWwV8D1rP
ad1947 1CNVkynAHGKktJyCBUGiNkWET4yPyq3FYRqnC5+tVbSfpmtWOVWXHeg1SRjzD/S1
af6daa jVcYrptNdHtWilYYK461xesT3cE0nkITu746VRtL/UYgQVYnrxVJ2Ja6HX3GjwyB
--14cb 0011179aca240110219 Page 21 of samplekeys.asc
72317d lHBz1HeqV5osVvp08gAyI25x7Vb0KWc2CPdLtdiTgnPFS6sRJayQhwokUrn0yKXU
6ea751 JfCeX4P96ly46NW23hlh9y/iPHdSCajPhq5yALm3IIzndWlmcXPEyvNmA4kP50Vp
f98d95 /wDCOXhztltzj/ppRRZjuiY6vbnIyR+FPj1W0AOXP5VgYB60mB0BouLlR0Q1O0Y5
ad42e3 MoGfarNleQTyNEJVZSvSuUx705SyHcrkH1FJ6jj7rudJfLEkmwSh85x7gVXiG1uK
2909a5 yYXkeZWLFmXnmtRJBUNG6ldmrbvjFXI7tY+XbH41jxXAU81Za0S9GWkZfoalGyZc
691871 mvbZ1LOyrj1qJJ7HIlEy46YqmmjWqt8zlx/tGnjSrJiVXeD2+birsUjpYLqBoApY
30e9da Djgis/UZt0WAcnpkVmLpdxaEuly3l9kzmqmu3stvFCkUhDtySKFuZ1L8rLRDDBPN
10fd02 MOcYH865/wDtO7/56k/UULqt2Dnfn6irucSizoAdp4OfxorCXWLkddp/CincOVks
834744 Wjh0UmYgkZIxTLjSjBEzibdjtiukM8K9LaNj09MUSfY5oik9qOeyMRS5Rc5xxiYD
99bd1a O6mkEHGa642GjshDW0wPYiSm/wBk6I3PlXKnPXzP/rU+VidWK3OesY3F0ucYNW5v
6dc6dc 3EnP3TWvNYaZbxh7bzvNB43MCKpXUfmL0qJKzN6b5ldDIgsg4NaMMb+WCrZ9RXPG
613bf0 R7Zjg8VctNZ2HDGpsbKVtzoobYzLz696nOlsF3KfwrNttYRTwwwaujVwPm3j6UjR
369ea4 SQ2SOVFZTXI6rcebfMM8R/LXU3F/JeI6W+0SEcFjgD6mucbwtqrBpQIZBnJIlFXG
385121 L3MKs47XMzdS7hU50PUw+z7I5PYggg0j6LqiDLWUwyMj5c07My07kG4UU46ffDg2
2d99ba k/8A3waKCrLudQ/mx/fjIA9RTTOhPGelXGd0Y80xmhl4kRQT3xWzgeeqz6oiVg/v
e4b918 ipOo9MUsKW8cbLGQu05fJrH1PWsAw2QLN0MmOB9KfwonWpLQm1DUre0OzHmS/wB0
13c8e1 Hp9aqrqUk6fuovmAy3GcVi7Hdiz7iSepqaGWa3bKHGayep1xjyxsmaQaK5ycAN6e
3cd42b tV57RMblOD6VXDSbt3vnIq15jSx5x8w6j1qWuxrGfSRSDyIcAmr9oss7BWc49qgM
67d922 QIyMVetE8iLzX6dvU0tzS6jqzRknjsLVQAuM8gjJNaPh64W7iuGZU8tjtIzXJ6jc
8bd40e h8ljluw9Kf4Y1I2uq+SzYjn456bu1bU3Z2OHEJzi5I6e9t5bOT92xMLfdJ7e1VGu
2006d4 ZVZRvbPbmtxonuI2jkHysPyNY0tq0c5hmdUI9QaqcGnoZUaycfe3ES4l/wCejfnR
871f54 Ux0q52B0KOD/AHWoqeWRt7SD6kzxhhnvVOaL86vA8c01lD1q1c4YuxhXFm878k88
399fd7 HmmCyaEcKCPYVsSQ+lR8jgjiocTdT0M0Rr/EvP0qGW0R+gArXaNH7c1F5Kk49KVh
8e2bc0 qVtihDYl0GeKe2nsnzRkEjt61fTaFA7Vs+IRoZs4v7L+WYMPu5+5jndnvmiyGpNn
1c937a ErZFZmaRiIwflHdqmZJZuvyqOABV423myh3PI6DsKnFthBxTk3IFJIyDZqc7lzVW
954b65 ewCfPHwRyMdq6D7OWOMU7+zi4xwKnkY/a23HaN4vjjjWDU0YOvHmqMhvqK2ZNXtL
80cd20 5V+ygTH129BWF/YdvnMhyfQVet/Ls02QKFFaxcluc9SNN6wLsO+FT52FXOQAeaKr
416f7f KJJ37nNFaJvoYOKvqz//2YkASwQQEQIACwUCNa6PkAQLAwECAAoJEKy7FkvPc+xM
e093a9 CFcAnAiP6Lm4sIQ7aDkbhCvrrzDpfFp1AKDuAeToQTpS7MGIESwykB9blxaOWokA
ebdfc1 RgQQEQIABgUCNa+smwAKCRBjy2kd+uvV/AtdAJ4kdcuH4zV/iLxvmSaYYNOkhbMc
63ed32 hwCeOoq5N+r6wcgUuqESgolyiLz/6cuJAEYEEBECAAYFAjXGDMcACgkQS2s0ZJ1J
c1dbd7 ZYTlNgCdGBaT717UvGQbyf4T0XNm5U0sdJ8AnikhVgtgUD+wID+jL/yPK1eS7xCa
2151c6 tCBXaWxsIFByaWNlIDx3cHJpY2VAcHJpbWVuZXQuY29tPokASwQQEQIACwUCM5Ye
a55651 cgQLAwECAAoJEKy7FkvPc+xMDAYAn1LAxjaEn5F45t+jj5r+ZrWuD+/QAKDLEBhY
3fcb95 rl5KaTdwyFYzhr47ZGM59rkD9QQzk+QcEA+gz+q01MgaRHNNimdRPlLeo08sHeY2
bb56d8 Km1ojDI09B+aoz+rUsrN/zsSk+WEuS60tNoUVfgXw/gSJuPiWkxBGZARXv2QZ8mM
072448 jIDu5R23SxOT92VTDUYykSguoy2JlLolqOUpWl5dDlW83hrFXNtjCe4vtzo4xq11
b9222e tlK7wVZU03kHB01+vRE394gvJo4Zc590851shU5GskdpARd9SrN+/qjhheKpg0IE
2076ea XcJYTdN/6O8fVSbLKNEWf7q+TNSzgP8/8sc+ICi6vzGYGwqSmxy67SBRh+96iSlD
3727a7 5dKn7ymRuTCMJFA8/DDQkbFOQWMtAtFuUgOlqMjGdabYQUNcvJVoh5/neyGdbAQM
ecb77d 24dJvGnkN6xl6QuftjM2SzSnF3HT2bFsUql/xIrxH7n/4RIZnJMeq1+9p/pyhYZH
564654 HRIxSOr9SSFp+DttR6C0y8/JbxuZG2a6cCZeRlWgpLqOEgs6Bbu5xSois28Zg1J/
717f67 vuN5SkeowMEp1oCNkQ0ZZkzahhnChTdlBtH1fTBCWw8gLUPLsyt/Zx3pgB+8ZTU6
99abdd XZqUx5BMJbCsFOF2BCkcq+Dm7nK50dwz2mq5EiYc/PQt3mfSxx484ni8tS6wo/yM
5045cc iXpJIlP7ROjuNnYZH6ATgyk0bs+bXDFew/76VNwSNMba0KTDaBjfeAyZ9ND7f9kA
0b58f1 AgIPoKwUGw9BmwCc/i0AY0UhiL4pWvvjVsezZrXPrDwCBJ+wFSKt4p8xz8bd/+F2
1e4cfe ilf2LOu/TAsAgoDYDJD99e2EeMGFglCGGoulpZd7QjHXmTI4MFYE/UviBPH4kgdc
9a5bad iFQLeBhsOpdeYOJ2g2EWX7r5cU2z/H50cuPqzAbkI18Ttt6VLk9ic7UCm6mh1v1f
686d1b M80Z+ZVod5uQq9aLNZY5yDQ0ZroYLUj7GfpVRVkEahtZ2R4xN74Sfp9DElWuYL5Q
0fcc92 Lm0Cq/q1rGR0DaeL9oYVwFXZTZzSOzVR3/niC0yCALyy7DpSks8Sx0TmLfHcWsIb
6d8d84 baEBJqHmosumbhrLtlixSVzks/ezCFZ3HE3zTuXfw/7O9CvP7z51HGxmPTepw8Yb
dd344d re9HzndPERvxsoiRqCpjve4i4HGOQxyTVjOG2HQBnJrgWH/7/Q+W7VvDPTGsSrhO
59fd0f V7fCrWGPQ+LBOLTxIUFDTrRQTYtOwAq96RxS3S5rOhc36pQj0UpmnLc/P58LvN76
9a5a15 w/MDB9G5PF0EU5rJqm4Saeem9j5hTQyoAmdw3WgwEgzosKKPvl0p2OGA71qAO+sX
046441 daUhY18C8XH7lUAPQW+oaFDGRpqHg7FQiOPC2lY57zF9ofcct9E2w3SkIGRl2rv4
d65365 UX3WPMjV5+j6rpl1TwlbO/oT+nO+/JsaiQA/AwUYM5PkHKy7FkvPc+xMEQLOigCg
f5f24d zc2k5GAOPn8e4Td1H4rg9L/nl9UAniESe4GKQapga+dO31VhHShm5BXb
e93f19 =SG28
112971 -----END PGP PUBLIC KEY BLOCK-----¶
--a019 001e99830ee4011021a Page 1 of WhatIsThis.txt
cb78b2 Sample Keys
e9af5a
60af5a
0f63c2 This set of sample keys has been provided for tutorial purposes. ·These are
5fed9a real keys of real people who created the product. ·The web of trust can be
180f06 illustrated by doing the following:
e6af5a
8ee9c6 1] Drag the sample keys file in the same folder as this text file into the
056d2a PGPkeys window to import the keys onto your keyring.
2caf5a
ab8c27 2] Sign the "Network Associates Employee Certification Key" with your key.
d3695d You may also wish to sign other keys such as Phil Zimmermann's key as
6a1081 signing his key generally allows many other keys in the world to be
65b239 considered valid.
6faf5a
2a1eb5 3] Get Properties on the "Network Associates Employee Certification Key"
ae3cca and move the Trust slider to Complete.
c7af5a
364efa You will now see that all the keys you imported are valid. ·The Employee
d891f6 Certification Key has signed all the User IDs and Photo IDs of the imported
9bf790 keys.
9caf5a
9977a1 The Network Associates PGP Software Release Key is also included in this
57a596 set of keys. ·You can use this key to verify that your copy of PGP came
bee478 directly from Network Associates by verifying the signature on your
e96552 distribution.
--1a75 00027bdb79e4011021b Page 1 of fieldlic.txt
f7e090 NETWORK ASSOCIATES, INC. SOFTWARE FIELD TEST LICENSE AGREEMENT
72af5a
52af5a
110267 BEFORE YOU CLICK ON THE "YES" OR "AGREE" BUTTON AT THE END OF THIS DOCUMENT, CA¶
de087a REFULLY READ THE TERMS AND CONDITIONS OF THIS AGREEMENT. THIS IS A LEGAL AGREEM¶
9e6862 ENT BETWEEN YOU AS END USER AND ANY SUBSEQUENT END-USER, AND NETWORK ASSOCIATES¶
c4c148 , INC. ·BY CLICKING THE 'AGREE" OR "YES" BUTTON AT THE END OF THIS AGREEMENT, Y¶
b51ba1 OU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS AGREEMENT (THE "AGREEMENT"). I¶
f58b87 F YOU DO NOT AGREE TO ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT, CLICK ¶
95b877 THE "NO" BUTTON AND DO NOT USE THE SOFTWARE.
47af5a
8c8805 This is a license agreement and not an agreement for sale Network Associates, I¶
786a7e nc. ·hereby licenses this version of the NETWORK ASSOCIATES, INC. software iden¶
88c5bd tified above (the "Software") to the original end-user and any subsequent trans¶
0ab6e7 feree of the Software SOLELY FOR ·TESTING PURPOSES and for use only on the term¶
2a086c s set forth in this Agreement. THIS TEST SOFTWARE CONTAINS A TIME-OUT FEATURE T¶
3d1f04 HAT DISABLES ITS OPERATION AFTER A CERTAIN PERIOD OF TIME. THE WEB PAGE FROM WH¶
ee8dc2 ICH THE SOFTWARE WAS DOWNLOADED OR A TEXT FILE DELIVERED WITH THE SOFTWARE WILL¶
9ff5b0 ·STATE THE SPECIFIC DATE ON WHICH THE SOFTWARE WILL EXPIRE. Further, though NET¶
09731b WORK ASSOCIATES does not offer technical support for the this test Software, we¶
30805c ·welcome your feedback.·
c6af5a
3f4d17 1. ¤GRANT OF LICENSE. ·NETWORK ASSOCIATES, INC. grants you a non-exclusive lice¶
7eb0be nse to put in use solely for testing and evaluation by a person or organization¶
7df243 ·that agrees to be bound by the terms of this Agreement, the number of copies o¶
497dd2 f the Software specified above provided that (1) if the Software is in use in s¶
0ae727 ingle-user environments, each copy of the Software is in use on only one comput¶
b95c39 er at any time or (2) if the Software is in use on computers or computer termin¶
405e17 als in multi-user or networked environments, you have licensed one copy of the ¶
bf1546 Software for each computer or computer terminal which is participating in such ¶
580aca an environment and which has access to the Software. ·The Software is "in use" ¶
c18119 on a computer when it is loaded into the temporary memory (i.e., RAM) or instal¶
7f03bd led into the permanent memory (e.g., hard disc, CD-ROM, or other storage device¶
d99fcb ) of that computer, except that a copy installed on a network server for the so¶
09866d le purpose of distribution to other computers is not "in use." ·
ecf587 If this Software is an upgrade or trade-up from a previous version of a Network¶
a25c83 ·Associates, Inc. product, NETWORK ASSOCIATES, INC. grants you the right to put¶
72e1d8 ·in use either the current or prior version of the Software in the quantity ind¶
3362bf icated above, and any prior version license is replaced by this Agreement.
8daf5a
229930 This Software is still under development and may contain bugs. Though NETWORK A¶
62c70b SSOCIATES, INC. does not offer technical support for the Software, we welcome y¶
e19af8 our feedback. ·While NETWORK ASSOCIATES, INC. intends to distribute a commercia¶
9ad2ce l release of the Software, Network Associates, Inc. reserves the right at any t¶
de8eb6 ime not to release a commercial release of the Software or, if it does so, to a¶
18ca47 lter prices, features, specifications, capabilities, functions, licensing terms¶
a15f98 , release dates, general availability, or other characteristics of the commerci¶
b9d0cb al release.
36af5a
3db187 2.¤ COPYRIGHT. ·All right, title and interest in the Software, the accompanying¶
96f6d2 ·documentation (the "Documentation") and related trademarks, trade names and ot¶
06329b her intellectual property rights are owned by Network Associates, Inc. or its s¶
61f9e7 uppliers and the Software and Documentation are protected by United States copy¶
5d2229 right laws and international treaty provisions. ·Therefore, you must treat the ¶
852078 Software and Documentation like any other copyrighted material (e.g., a book or¶
071027 ·musical recording) except that in addition to the number of copies you are per¶
2d2ae7 mitted to put in use, you may make one copy of the Software solely for backup o¶
3fc458 r archival purposes. ·Such copy shall include NETWORK ASSOCIATES, INC.'s copyri¶
0a8c7b ght and other proprietary notices. ·You may not copy the Documentation.
b9af5a
a46fda 3.¤ OTHER RESTRICTIONS. ·The original of this Agreement is your proof of licens¶
83c5eb e to exercise the rights granted herein and must be retained by you. You may no¶
2d81d8 t rent or lease the Software, but you may transfer your rights under this Agree¶
35a516 ment on a permanent basis provided you transfer this Agreement and all copies o¶
6a1789 f the Software and Documentation, you do not retain any copies of the Software ¶
f5534e or Documentation, and the recipient agrees to the terms of this Agreement. ·Any¶
4d1ca5 ·transfer of the Software must include the most recent update and all prior rev¶
b29099 isions. ·You may not reverse engineer, decompile, disassemble or otherwise tran¶
a80969 slate the Software.
b1af5a
fd19d3 4.¤ DUAL MEDIA SOFTWARE. ·If the Software package contains both 3 1/2" and 5 1/¶
272a07 4" disks, and/or a CD, you may use only the disks appropriate to your computer.¶
--d9b6 000048b7b794011021b Page 2 of fieldlic.txt
c63663 ·You may not use the other disks on another computer or loan, rent, lease, or t¶
c704a4 ransfer them to another user except as permitted under this Agreement or as par¶
ef9368 t of the permanent transfer (as provided above) of all Software and Documentati¶
a72832 on.
1aaf5a
5611c9 5.¤ GOVERNMENT LICENSEE. ·If you are acquiring the Software on behalf of the Un¶
490cab ited States Government, the following provisions apply: ·The Government acknowl¶
494ad8 edges NETWORK ASSOCIATES, INC.'s representation that the Software and Documenta¶
a53582 tion were developed at private expense and no part of them is in public domain.¶
cc4290 ··The Government also acknowledges Network Associates, Inc.'s representation th¶
272242 at the Software is "commercial computer software" as that term is defined in 48¶
2d11a4 ·C.F.R. 12.212 of the Federal Acquisition Regulations ("FAR") and is "Commercia¶
4c8eea l Computer Software" as that term is defined in 48 C.F.R. 227.7014 (a)(i) of th¶
e3f8f1 e Department of Defense Federal Acquisition Regulation Supplement ("DFARS"). ·T¶
ce4b7d he Government agrees that: if the Software is supplied to any unit or agency of¶
610f86 ·the United States Government, the Government's rights in the Software and its ¶
569792 documentation will be only as specified in this Agreement.
c4af5a
d2ecc3 Restricted Rights Legend
2baf5a
fdbaa0 The Contractor/Manufacturer is: NETWORK ASSOCIATES, INC., 2805 Bowers Ave., San¶
906b73 ta Clara, CA 95051.
deaf5a
1d43a6 6.¤ TERMINATION. ·This Agreement will immediately and automatically terminate w¶
02fb3a ithout notice if you fail to comply with any term or condition of this Agreemen¶
0c0219 t. ·You agree upon termination to promptly destroy all of the Software and Docu¶
248325 mentation in your possession together with all copies, modifications and merged¶
07e581 ·portions in any form.
38af5a
ff1197 7. ·····NO WARRANTY FOR TEST SOFTWARE. THE SOFTWARE IS PROVIDED FOR TESTING AND¶
2d02f7 ·EVALUATION PURPOSES ONLY, COMES WITH NO WARRANTY, AND IS PROVIDED ON AN "AS IS¶
280249 " BASIS. ·YOU ASSUME THE ENTIRE COST OF ANY DAMAGE RESULTING FROM THE INFORMATI¶
d610b0 ON CONTAINED IN OR PRODUCED BY THE SOFTWARE. YOU ASSUME ALL RESPONSIBILITIES FO¶
59a3a0 R SELECTION OF THE SOFTWARE TO ACHIEVE YOUR INTENDED RESULTS, AND FOR THE INSTA¶
57f202 LLATION OF, USE OF, AND RESULTS OBTAINED FROM THE SOFTWARE. ·TO THE MAXIMUM EXT¶
6a7e29 ENT PERMITTED BY APPLICABLE LAW, NETWORK ASSOCIATES DISCLAIMS ALL WARRANTIES, E¶
8c301a ITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF ME¶
dfb52e RCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT, WITH RES¶
d2d0f1 PECT TO THE SOFTWARE. SOME STATES DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIE¶
4cb4a9 S, SO THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
dcaf5a
bff410 8.¤ LIMITATION OF LIABILITY. ·NETWORK ASSOCIATES, INC.'S CUMULATIVE LIABILITY T¶
6732aa O YOU OR ANY OTHER PARTY FOR ANY LOSS OR DAMAGES RESULTING FROM ANY CLAIMS, DEM¶
6e8153 ANDS OR ACTIONS ARISING OUT OF OR RELATING TO THIS AGREEMENT SHALL NOT EXCEED T¶
3a8783 HE PURCHASE PRICE PAID FOR THE LICENSE. ·IN NO EVENT SHALL NETWORK ASSOCIATES, ¶
283945 INC. OR ITS SUPPLIERS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, SP¶
4ce9d2 ECIAL OR EXEMPLARY DAMAGES OR LOST PROFITS WHATSOEVER (INCLUDING, WITHOUT LIMIT¶
7f1356 ATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUS¶
a55211 INESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OR INABILITY¶
839731 ·TO USE THE SOFTWARE, EVEN IF NETWORK ASSOCIATES, INC. HAS BEEN ADVISED OF THE ¶
205bf7 POSSIBILITY OF SUCH DAMAGES. ·BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR¶
933326 ·LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIM¶
9bbe8e ITATION MAY NOT APPLY TO YOU.
efaf5a
c35d06 9.¤ EXPORT LAW. Export of the Software may be subject to compliance with the ru¶
618145 les and regulations promulgated from time to time by the Bureau of Export Admin¶
aebc61 istration, United States Department of Commerce, which restrict the export and ¶
718fa1 re-export of certain products and technical data. If the export of the Software¶
1b7f29 ·is controlled under such rules and regulations, then the Software shall not be¶
2217b0 ·exported or reexported, directly or indirectly, (a) without all export or reex¶
3a61cf port licenses and governmental approvals required by any applicable laws, or (b¶
50cae0 ) in violation of any applicable prohibition against the export or reexport of ¶
523cef any part of the Software.
9caf5a
24f4f1 10. GENERAL. THIS AGREEMENT WILL BE GOVERNED BY THE LAWS OF THE STATE OF CALIFO¶
26bc5a RNIA AND YOU CONSENT TO THE JURISDICTION AND VENUE OF THE COURTS OF THE STATE O¶
f5bea9 F CALIFORNIA. ·If any action is brought by either party to this Agreement again¶
5987dc st the other party regarding the subject matter hereof, the prevailing party sh¶
8b74c5 all be entitled to recover, in addition to any other relief granted, reasonable¶
677fe2 ·attorneys fees and expenses of litigation. Should any term of this Agreement b¶
66f233 e declared void or unenforceable by any court of competent jurisdiction, such d¶
044aec eclaration shall have no effect on the remaining terms hereof. The failure of e¶
--9f31 0017b714be84011021b Page 3 of fieldlic.txt
e62b8d ither party to enforce any rights granted hereunder or to take action against t¶
fa9be8 he other party in the event of any breach here under shall not be deemed a waiv¶
16625d er by that party as to subsequent enforcement of rights or subsequent actions i¶
1b0d1e n the event of future breaches.
4daf5a
a68b54 YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, UNDERSTAND I AND AGREE TO BE¶
738d34 ·BOUND BY ITS TERMS AND CONDITIONS. YOU FURTHER AGREE THAT IT IS THE COMPLETE A¶
80a01f ND EXCLUSIVE STATEMENT OF THE AGREEMENT BETWEEN US WHICH SUPERSEDES ANY PROPOSA¶
08d1be L OR PRIOR AGREEMENT, ORAL OR WRITTEN, AND ANY OTHER COMMUNICATION BETWEEN US R¶
0ffbb0 ELATING TO THE SUBJECT MATTER OF THIS AGREEMENT.
b0af5a
07a05e Should you have any questions concerning this Agreement, or if you desire to co¶
a035cb ntact NETWORK ASSOCIATES, INC. for any reason, please write:·
413e74 Network Associates, Inc. Customer Service, 2805 Bowers Ave., Santa Clara, CA 95¶
4a3c7f 051.
d7af5a
beb555 Copyright (c) 1990-1998 NETWORK ASSOCIATES and/or its affiliates in the US and ¶
a20b61 other countries. All rights reserved. Pretty Good Privacy, Pretty Good, PGP and¶
eed941 ·NETWORK ASSOCIATES are registered trademarks of NETWORK ASSOCIATES, INC. and/o¶
cf74dc r its affiliates in the US and other countries.
7b2f36 581-00030C
--58c8 000e4b7194b4011021c Page 1 of freelic.txt
c8b943 PGPfreeware, Version 6.0·
c7af5a
709b7c LICENSE COPY OF NETWORK ASSOCIATES PRODUCTS·
faaf5a
85ed4e (Non-Commercial Distribution and Use Only, Executable Version)·
4aaf5a
b4e593 Copyright (C) 1990-1998 Network Associates Inc., and its Affiliated Companies. ¶
1d0413 ·All Rights Reserved.·
e6af5a
940003 End User License Agreement for PGPfreeware·
cc7516 ·······
c331f6 This special version of PGP, PGPfreeware 6.0, including the software and its re¶
c3e584 lated user documentation, ("Software Product") is owned by Network Associates, ¶
e5eacd Inc. and its affiliated companies, and is protected by copyright laws and inter¶
459466 national copyright treaties, as well as other intellectual property laws and tr¶
bade77 eaties.·
75af5a
e1898c The makers of PGP, however, are committed to making freely available to individ¶
73e76c uals around the world, subject to 2(c) below, a trusted means to secure their p¶
22d6f3 ersonal information and communications from unwanted invasions of privacy. To t¶
aaefb9 hat end, it is important that this Software Product be distributed from as many¶
e6c9ad ·Internet sites as possible. ·Accordingly, Network Associates, Inc. is permitti¶
cbdf4f ng the non-commercial use and non-commercial distribution of this Software Prod¶
ede219 uct (i.e., PGPfreeware 6.0) within the scope of the following licenses, provide¶
45ec2d d that all of the terms and conditions set forth below are complied with.
69af5a
10a183 1.¤ Non-Commercial Use License. You may use this Software Product solely for no¶
39c490 n-commercial purposes. The term "non-commercial" means that the product·
4daf5a
0c929f ¤   (a) has been distributed or otherwise made available at no charge (direct o¶
96c5c0 r indirect) and
63af5a
fbae3b ¤   (b) is not used for any commercial purpose, which includes, but is not limi¶
ab5f4b ted to, any activity engaged for the purpose of generating revenues (directly o¶
92eff3 r indirectly). For example, a commercial purpose includes the use of the produc¶
75fcc8 t within a commercial business or facility or the use of the product to provide¶
5dfeaa ·a service, or in support of service, for which you charge. Commercial purpose ¶
60c4ec also includes use by any government agency or organization. Examples of non-com¶
78d451 mercial purposes include use at home for personal correspondence, use by studen¶
40f718 ts for academic activities, or use by human rights organizations. The software ¶
259917 is in "use" when it is loaded into the temporary memory (i.e., RAM) or installe¶
755bf4 d into the permanent memory (e.g., hard disk, CD ROM, or other storage device) ¶
a8f4e5 of a computer for the purpose of being accessible in client-mode by an end user.
69af5a
070697 2.¤ Non-Commercial Distribution License. You may make exact, unmodified copies ¶
80fe60 of this Software Product and distribute such copies solely by electronic means ¶
5205a8 (for example, posting on Internet sites for others to download), subject to the¶
11a3e1 ·following
d7af5a
ca8e1d ¤   (a) that such distribution is solely for non-commercial purposes (see above¶
16f4cf ·definition),
03af5a
ab0571 ¤   (b) that the Software Product is distributed unmodified and in its entirety¶
138820 ·(with its complete user documentation, its readme files, its copyright, tradem¶
8d6797 ark, other intellectual property notices, including these terms and conditions,¶
8aaee3 ·and all of its other components), and
4467c5 ¤
07d230 ¤   (c) that such distribution may occur anywhere in the world, except that to ¶
acae5a the extent the export of this Software Product outside of the United States is ¶
18e58d restricted by the U.S. government, the Software Product shall not be exported o¶
d16098 r reexported, directly or indirectly, (i) without all export or reexport licens¶
bc8db4 es and governmental approvals required by any applicable laws, or (ii) in viola¶
c0c2f1 tion of any applicable prohibition against the export or reexport of any part o¶
d7213f f the Software Product. In any event, Network Associates, Inc. expressly forbid¶
1a42a6 s the export of this Software Product to any countries embargoed by the U.S. go¶
009990 vernment (currently including, Cuba, Iran, Iraq, Libya, North Korea, Syria and ¶
9ad6a6 Sudan).
20af5a
b3af5a
bcb469 3.¤ Other Uses. All right, title and interest in this Software Product, includi¶
f9adae ng its accompanying user documentation, and all copyrights therein and related ¶
e452e0 trademarks, trade names and other intellectual property rights, are owned by Ne¶
--fd47 0000469eea24011021c Page 2 of freelic.txt
0f368a twork Associates, Inc. and its affiliated companies, or its suppliers. All lice¶
a8585f nse rights not granted herein are reserved by Network Associates, Inc. Should y¶
36d468 ou wish to use or distribute this Software Product for commercial purposes, com¶
2bb493 mercial use licenses are available from Network Associates, Inc. or its authori¶
6e9885 zed resellers; please refer to the Network Associates web site located at http:¶
7507a4 //www.nai.com for further information.·
32af5a
69ac44 4.¤ Technical Support. This Software Product is user-supported, meaning that as¶
785fc9 sistance in its installation and use may be limited to help available from frie¶
7d3120 nds, family, and other users on the Internet. Though Network Associates does no¶
1df925 t offer technical support for this Software Product, we welcome your feedback. ¶
ad57da Technical support is available from Network Associates or its authorized resell¶
fa3948 ers under their standard support policies for those who have purchased copies o¶
318ac9 f the commercial version of this product. For further information, please refer¶
0261df ·to http://www.nai.com.
13af5a
00c410 5.¤ No Warranty. THIS SOFTWARE PRODUCT IS PROVIDED FOR NON-COMMERCIAL USE AND D¶
558a27 ISTRIBUTION ONLY, COMES WITH NO WARRANTY, AND IS PROVIDED ON AN "AS IS" BASIS. ¶
bde4bc YOU ASSUME THE ENTIRE COST OF ANY DAMAGE RESULTING FROM THE INFORMATION CONTAIN¶
1ca056 ED IN OR PRODUCED BY THIS SOFTWARE PRODUCT. YOU ASSUME ALL RESPONSIBILITIES FOR¶
9ba576 ·SELECTION OF THIS SOFTWARE PRODUCT TO ACHIEVE YOUR INTENDED RESULTS, AND FOR T¶
3f569d HE INSTALLATION OF, USE OF, AND RESULTS OBTAINED FROM IT. TO THE MAXIMUM EXTENT¶
9b2461 ·PERMITTED BY APPLICABLE LAW, NETWORK ASSOCIATES, ITS SUPPLIERS AND OTHERS WHO ¶
cbd151 MAY DISTRIBUTE THIS SOFTWARE PRODUCT DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR¶
12cfd1 ·IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, F¶
4fe586 ITNESS FOR A PARTICULAR PURPOSE, CONFORMANCE WITH DESCRIPTION, AND NON-INFRINGE¶
e53c51 MENT, WITH RESPECT TO THIS SOFTWARE PRODUCT.
17af5a
55ca93 6.¤ Limitation of Liability. THE CUMULATIVE LIABILITY OF NETWORK ASSOCIATES, IT¶
3a0eab S SUPPLIERS OR OTHERS WHO MAY DISTRIBUTE THIS SOFTWARE PRODUCT, TO YOU OR ANY O¶
eb97e0 THER PARTY FOR ANY LOSS OR DAMAGES RESULTING FROM ANY CLAIMS, DEMANDS OR ACTION¶
9d4784 S ARISING OUT OF OR RELATING TO THESE TERMS AND CONDITIONS SHALL NOT EXCEED ONE¶
657506 ·U.S. DOLLAR. IN NO EVENT SHALL NETWORK ASSOCIATES, ITS SUPPLIERS OR OTHERS WHO¶
f950e5 ·MAY DISTRIBUTE THIS SOFTWARE PRODUCT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, C¶
58d7f5 ONSEQUENTIAL, SPECIAL OR EXEMPLARY DAMAGES OR LOST PROFITS WHATSOEVER (INCLUDIN¶
f58022 G, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPT¶
a2ef2d ION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE ¶
da617e USE OR INABILITY TO USE THIS SOFTWARE PRODUCT, EVEN IF NETWORK ASSOCIATES, ITS ¶
450d34 SUPPLIERS OR OTHERS WHO MAY DISTRIBUTE THIS SOFTWARE PRODUCT HAVE BEEN ADVISED ¶
fbb96c OF THE POSSIBILITY OF SUCH DAMAGES.
7aaf5a
fcaf5a
f9297d BECAUSE SOME JURISDICTIONS DO NOT ALLOW THE LIMITATIONS ON IMPLIED WARRANTIES O¶
4ffa89 R THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMA¶
6c3811 GES, THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
1aaf5a
70ef28 7.¤ General. These terms and conditions may not be modified, amended, canceled ¶
606011 or in any way altered, nor may they be modified by custom and usage of trade or¶
7793f5 ·course of dealing, except by an instrument in writing and signed by a duly aut¶
cd1adc horized officer of Network Associates, Inc. THESE TERMS AND CONDITIONS SHALL BE¶
49b1ea ·CONSTRUED AND ENFORCED IN ACCORDANCE WITH THE LAWS OF THE STATE OF CALIFORNIA,¶
4f543a ·UNITED STATES OF AMERICA. Any action or proceeding brought by anyone arising o¶
979974 ut of or related to these terms and conditions shall be brought only in a state¶
abee8f ·or federal court of competent jurisdiction located in the county of Santa Clar¶
e3b98e a, California, and the parties hereby consent to the jurisdiction and venue of ¶
4c2f67 said courts. Should any term of these terms and conditions be declared void or ¶
c1dfcb unenforceable by any court of competent jurisdiction, such declaration shall ha¶
590564 ve no effect on the remaining terms hereof. These terms and conditions are in t¶
c18529 he English language, and only the English language version hereof, regardless o¶
82b037 f the existence of other language translations of these terms and conditions, s¶
8c949a hall be controlling in all respects. The failure of either party to enforce any¶
7ef0dc ·rights granted hereunder or to take action against the other party in the even¶
81a46a t of any breach hereunder shall not be deemed a waiver by that party as to subs¶
ba0fc5 equent enforcement of rights or subsequent actions in the event of future breac¶
e3333d hes. Network Associates, Inc. reserves the right at any time without liability ¶
787127 or prior notice to change the features or characteristics of this Software Prod¶
93d187 uct, or its documentation and related materials, or future versions thereof. Th¶
b2c28e ese terms and conditions constitute the complete and exclusive statement of the¶
ee1724 ·agreement between us which supersedes any proposal or prior agreement, oral or¶
b86c82 ·written, and any other communication between us relating to the subject matter¶
b2c77e ·of these terms and conditions.
04af5a
--6640 0019b8073354011021c Page 3 of freelic.txt
bce779 Copyright (C) 1990-1998 Network Associates, Inc. and its affiliated companies. ¶
81cd3f All rights reserved. PGP and Pretty Good Privacy are registered trademarks of N¶
d6b02a etwork Associates, Inc. and its affiliated companies. The Software Product may ¶
362584 use public key algorithms described in U.S. patent numbers 4,200,770, 4,218,582¶
dd0403 , and 4,424,414, and their international equivalents, licensed by Cylink Corpor¶
70f52e ation; the IDEA cryptographic cipher described in U.S. patent number 5,214,703,¶
52df52 ·licensed from Ascom Tech AG; and the Northern Telecom Ltd., CAST Encryption Al¶
b4c8c5 gorithm, licensed from Northern Telecom, Ltd. IDEA is a trademark of Ascom Tech¶
903fed ·AG. The compression code in PGP is by Mark Adler and Jean-loup Gailly, used wi¶
6353f5 th permission from the free Info-ZIP implementation. LDAP software provided cou¶
f4c306 rtesy University of Michigan at Ann Arbor, Copyright (C) 1992-1996 Regents of t¶
96285b he University of Michigan. All rights reserved. Richard Outerbridge is the auth¶
80f515 or of the Triple-DES code used in this product. Network Associates, Inc. and it¶
afa230 s affiliated companies may have patents and/or pending patent applications cove¶
ddd556 ring subject matter in this software or its documentation; the furnishing of th¶
8acef6 is software or documentation does not give you any license to these patents. No¶
1edbcd te: Some countries have laws and regulations regarding the use and export of cr¶
0eb4e3 yptography products; please consult your local government authority for details¶
bd442d . Should you have any questions concerning these terms and conditions, or if yo¶
6c7fe9 u desire to contact Network Associates, Inc. for any reason, please write: Netw¶
c341d3 ork Associates, Inc. Customer Service, 3965 Freedom Circle, Santa Clara, CA 950¶
978db9 54. http://www.nai.com. BEFORE YOU CLICK ON THE "AGREE" BUTTON BELOW, CAREFULLY¶
a6ceed ·READ THE TERMS AND CONDITIONS ABOVE. NETWORK ASSOCIATES HAS PERMITTED THE DIST¶
cab1c5 RIBUTION AND USE OF THIS SOFTWARE PRODUCT ON A NON-COMMERCIAL BASIS SUBJECT TO ¶
40cddc ALL OF THE ABOVE CONDITIONS OF DISTRIBUTION AND USE. BY CLICKING THE 'AGREE" BU¶
bfb9e7 TTON AT·
7b21e6 THE END OF THIS AGREEMENT, YOU AND ANY SUBSEQUENT END-USER ARE AGREEING TO BE B¶
05adf4 OUND BY ALL OF THE TERMS AND CONDITIONS ABOVE. IF YOU DO NOT AGREE TO ALL OF TH¶
f81f85 ESE TERMS AND CONDITIONS, CLICK THE "NO" BUTTON AND DO NOT INSTALL, USE OR DIST¶
9bea66 RIBUTE THIS SOFTWARE PRODUCT.·
--6a8d 000a9b196504011021d Page 1 of license.txt
e0af5a
1aaf5a
139ce2 ¤   Network Associates Two (2)-Year End User License Agreement
06af5a
ceaf5a
db37d8 NOTICE TO ALL USERS: CAREFULLY READ THE FOLLOWING LEGAL AGREEMENT ( "AGREEMENT"¶
88d0b6 ), FOR THE LICENSE OF SPECIFIED SOFTWARE ("SOFTWARE") PRODUCED BY NETWORK ASSOC¶
4de834 IATES, INC. ("NETWORK ASSOCIATES"). ··BY CLICKING THE ACCEPT BUTTON OR INSTALLI¶
0fc0b2 NG THE SOFTWARE, YOU (EITHER AN INDIVIDUAL OR A SINGLE ENTITY) CONSENT TO BE BO¶
c61a83 UND BY AND BECOME A PARTY TO THIS AGREEMENT. ·IF YOU DO NOT AGREE TO ALL OF THE¶
ac13c2 ·TERMS OF THIS AGREEMENT, CLICK THE BUTTON THAT INDICATES THAT YOU DO NOT ACCEP¶
f81784 T THE TERMS OF THIS AGREEMENT AND DO NOT INSTALL THE SOFTWARE. ·(IF APPLICABLE,¶
01bcbb ·YOU MAY RETURN THE PRODUCT TO THE PLACE OF PURCHASE FOR A FULL REFUND.) ·
19af5a
17e9a0 ·1.¤License Grant. ·Subject to the payment of the applicable license fees, and ¶
3a8e7d subject to the terms and conditions of this Agreement, Network Associates hereb¶
71f560 y grants to you a non-exclusive, non-transferable right to use one copy of the ¶
f74084 specified version of the Software and the accompanying documentation (the "Docu¶
b3dafa mentation"). ·You may install one copy of the Software on one computer, worksta¶
2ffb1b tion, personal digital assistant, pager, "smart phone" or other electronic devi¶
ac916a ce for which the Software was designed (each, a "Client Device"). ····If the So¶
02b64f ftware is licensed as a suite or bundle with more than one specified Software p¶
a42afd roducts, this license applies to all such specified Software products, subject ¶
ecc7c0 to any restrictions or usage terms specified on the applicable price list or pr¶
e91b9d oduct packaging that apply to any of such Software products individually.
29af5a
47d73e ·¤  a.¤ Use. ·The Software is licensed as a single product; it may not be used ¶
816719 on more than one Client Device or by more than one user at a time, except as se¶
c20a6b t forth in this Section 1. ·The Software is "in use" on a computer when it is l¶
d4fb52 oaded into the temporary memory (i.e., random-access memory or RAM) or installe¶
610130 d into the permanent memory (e.g., hard disk, CD-ROM, or other storage device) ¶
9b4acc of that Client Device. ·This license authorizes you to make one copy of the Sof¶
c990f3 tware solely for backup or archival purposes, provided that the copy you make c¶
1eb400 ontains all of the Software's proprietary notices.
21af5a
fa35bb ·¤  b.¤ Server-Mode Use. ·To the extent such use is specified in the applicable¶
632dfc ·product invoicing or packaging for the Software, you may use the Software on a¶
7ace8e ·Client Device or on or as a server ("Server") within a multi-user or networked¶
769d89 ·environment ("Server-Mode") for either (i) connecting, directly or indirectly,¶
8a2026 ·to not more than the maximum number of specified Client Devices, or (ii) deplo¶
a6de52 ying not more than the maximum number of agents (pollers) specified for deploym¶
85f709 ent. ·If no such maximum number is specified, this is a single product use lice¶
4cf594 nse subject to subsection (a) above. ·A separate license is required for each C¶
a0cfa7 lient Device or "seat" that may connect to the Server at any time, regardless o¶
6011f3 f whether such licensed Client Devices or seats are concurrently connected to o¶
719c21 r actually accessing or using the Software. ··Use of software or hardware that ¶
d2c296 reduces the number of Client Devices or seats directly accessing or utilizing t¶
040ed5 he Software (e.g., "multiplexing" or "pooling" software or hardware) does not r¶
321d39 educe the number of licenses required (i.e., the required number of licenses wo¶
5590c5 uld equal the number of distinct inputs to the multiplexing or pooling software¶
3b6cdb ·or hardware "front end"). ·If the number of Client Devices or seats that can c¶
bfc9de onnect to the Software can exceed the number of licenses you have obtained, the¶
72bbef n you must have a reasonable mechanism in place to ensure that your use of the ¶
0342e3 Software does not exceed the use limits specified for the license you have obta¶
0d019b ined. ·This license authorizes you to make or download one copy of the Document¶
7a7cfe ation for each Client Device or seat that is licensed, provided that each such ¶
9d9269 copy contains all of the Documentation's proprietary notices.
06af5a
67af5a
830ecf ·¤  c.¤ Volume Use. ·If the Software is licensed with volume license terms spec¶
7c76ae ified in the applicable product invoicing or packaging for the Software, you ma¶
0ce36f y make, use and install as many additional copies of the Software on the number¶
0ae30b ·of Client Devices as the volume license terms specify. ·You must have a reason¶
40ef64 able mechanism in place to ensure that the number of Client Devices on which th¶
a77f9e e Software has been installed does not exceed the number of licenses you have o¶
8510ac btained. ···This license authorizes you to make or download one copy of the Doc¶
3dbcae umentation for each additional copy authorized by the volume license, provided ¶
0cf4cf that each such copy contains all of the Documentation's proprietary notices.
dfaf5a
51bede ·2.¤Term. ·This Agreement is effective for two (2) years unless you or Network ¶
74818b Associates terminates the Agreement earlier, in accordance with the terms set f¶
a92e73 orth herein. This Agreement will terminate automatically if you fail to comply ¶
--cd60 000d108d5814011021d Page 2 of license.txt
ea9a48 with any of the limitations or other requirements described herein. ·When this ¶
76ed40 agreement terminates, you must destroy all copies of the Software and the Docum¶
d5b854 entation. ·You may terminate this Agreement at any point by destroying all copi¶
2ac3e2 es of the Software and the Documentation.·
82af5a
e1d56c 3.¤ Updates. ·During the term of this Agreement, you may download revisions, up¶
7bb1d1 grades, or updates to the Software when and as Network Associates publishes the¶
ddd710 m via its electronic bulletin board system, website or through other online ser¶
e7d94a vices.
4aaf5a
e29838 4.¤ Ownership Rights. ·The Software is protected by United States copyright law¶
2dcbdd s and international treaty provisions. ·Network Associates and its suppliers ow¶
126367 n and retain all right, title and interest in and to the Software, including al¶
f1299a l copyrights, patents, trade secret rights, trademarks and other intellectual p¶
1bb35b roperty rights therein. ·You acknowledge that your possession, installation, or¶
364701 ·use of the Software does not transfer to you any title to the intellectual pro¶
412292 perty in the Software, and that you will not acquire any rights to the Software¶
d69fb3 ·except as expressly set forth in this Agreement. ·You agree that any copies of¶
95cba7 ·the Software and Documentation will contain the same proprietary notices which¶
a8c987 ·appear on and in the Software and Documentation.
86af5a
a23c5a 5. ¤Restrictions. ·You may not rent, lease, loan or resell the Software. ·You m¶
5def8d ay not permit third parties to benefit from the use or functionality of the Sof¶
80a285 tware via a timesharing, service bureau or other arrangement, except to the ext¶
539965 ent such use is specified in the applicable price list, purchase order, ·or pro¶
6e9ae6 duct packaging for the Software. ·You may not transfer any of the rights grante¶
bf4ce9 d to you under this Agreement. ·You may not reverse engineer, decompile, or dis¶
914a8f assemble the Software, except to the extent the foregoing restriction is expres¶
091a77 sly prohibited by applicable law. ·You may not modify, or create derivative wor¶
f392f7 ks based upon, the Software in whole or in part. ·You may not copy the Software¶
7eec5f ·or Documentation except as expressly permitted in Section 1 above. ·You may no¶
ccf966 t remove any proprietary notices or labels on the Software. All rights not expr¶
70e6c6 essly set forth hereunder are reserved by Network Associates. ··Network Associa¶
9140ae tes reserves the right to periodically conduct audits upon advance written noti¶
8d6018 ce to verify compliance with the terms of this Agreement.
9ad83c ·
615e96 6. ¤Warranty and Disclaimer
46af5a
ba2509 a. Limited Warranty. ··Network Associates warrants that for sixty (60) days fro¶
1fc5cd m the date of original purchase the media (for example diskettes) on which the ¶
35cc12 Software is contained will be free from defects in materials and workmanship.
eaaf5a
4dcfe2 b. Customer Remedies. ·Network Associates' and its suppliers' entire liability ¶
11bf51 and your exclusive remedy shall be, at Network Associates' option, either (i) r¶
816999 eturn of the purchase price paid for the license, if any, or (ii) replacement o¶
9d9c1c f the defective media in which the Software is contained with a copy on nondefe¶
4ca004 ctive media. ··You must return the defective media to Network Associates at you¶
d8dd50 r expense with a copy of your receipt. ·This limited warranty is void if the de¶
600ea2 fect has resulted from accident, abuse, or misapplication. ·Any replacement med¶
aeec04 ia will be warranted for the remainder of the original warranty period. ·Outsid¶
3345c8 e the United States, this remedy is not available to the extent Network Associa¶
913e39 tes is subject to restrictions under United States export control laws and regu¶
845a1f lations.
54af5a
c4df77 c. Warranty Disclaimer. ·To the maximum extent permitted by applicable law, and¶
ec3af1 ·except for the limited warranty set forth herein, THE SOFTWARE IS PROVIDED ON ¶
c64c90 AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. WITHOUT LIMI¶
39564f TING THE FOREGOING PROVISIONS, YOU ASSUME RESPONSIBILITY FOR SELECTING THE SOFT¶
f4af61 WARE TO ACHIEVE YOUR INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND¶
1579f7 ·RESULTS OBTAINED FROM THE SOFTWARE. ·WITHOUT LIMITING THE FOREGOING PROVISIONS¶
811852 , NETWORK ASSOCIATES MAKES NO WARRANTY THAT THE SOFTWARE WILL BE ERROR-FREE OR ¶
59f4b3 FREE FROM INTERRUPTIONS OR OTHER FAILURES OR THAT THE SOFTWARE WILL MEET YOUR R¶
b1b49e EQUIREMENTS. ·TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NETWORK ASSOCI¶
c48bb8 ATES DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIM¶
901641 ITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE¶
200b73 , AND NONINFRINGEMENT WITH RESPECT TO THE SOFTWARE AND THE ACCOMPANYING DOCUMEN¶
965169 TATION. ·SOME STATES AND JURISDICTIONS DO NOT ALLOW LIMITATIONS ON IMPLIED WARR¶
54f24b ANTIES, SO THE ABOVE LIMITATION MAY NOT APPLY TO YOU. ·The foregoing provisions¶
f63389 ·shall be enforceable to the maximum extent permitted by applicable law.
7aaf5a
783709 7. ¤Limitation of Liability. ·UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,¶
d133d9 ·WHETHER IN TORT, CONTRACT, OR OTHERWISE, SHALL NETWORK ASSOCIATES OR ITS SUPPL¶
--ae1e 0004ae421364011021d Page 3 of license.txt
085e6e IERS BE LIABLE TO YOU OR TO ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDEN¶
ae3806 TAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, D¶
7c49b4 AMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR¶
b18e5e ·FOR ANY AND ALL OTHER DAMAGES OR LOSSES. ·IN NO EVENT WILL NETWORK ASSOCIATES ¶
1d82db BE LIABLE FOR ANY DAMAGES IN EXCESS OF THE LIST PRICE NETWORK ASSOCIATES CHARGE¶
6feb10 S FOR A LICENSE TO THE SOFTWARE, EVEN IF NETWORK ASSOCIATES SHALL HAVE BEEN ADV¶
6da98a ISED OF THE POSSIBILITY OF SUCH DAMAGES. ·THIS LIMITATION OF LIABILITY SHALL NO¶
12e045 T APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY TO THE EXTENT THAT APPLICABLE¶
097777 ·LAW PROHIBITS SUCH LIMITATION. ·FURTHERMORE, SOME STATES AND JURISDICTIONS ·DO¶
8c79be ·NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, ¶
68d28d SO THIS LIMITATION AND EXCLUSION MAY NOT APPLY TO YOU. ·The foregoing provision¶
7d8ca9 s shall be enforceable to the maximum extent permitted by applicable law.
31af5a
4784cd 8. ¤United States Government. ·The Software and accompanying Documentation are ¶
d042f7 deemed to be "commercial computer software" and "commercial computer software d¶
b5154b ocumentation," respectively, pursuant to DFAR Section 227.7202 and FAR Section ¶
ec6ffc 12.212, as applicable. ·Any use, modification, reproduction, release, performan¶
714de5 ce, display or disclosure of the Software and accompanying Documentation by the¶
cdcdc2 ·United States Government shall be governed solely by the terms of this Agreeme¶
0654d6 nt and shall be prohibited except to the extent expressly permitted by the term¶
41680a s of this Agreement.·
4eaf5a
edaf5a
56e209 ·9.¤Export Controls. Neither the Software nor the Documentation and underlying ¶
9b9bd9 information or technology may be downloaded or otherwise exported or reexported¶
2edc0f ·(i) into (or to a national or resident of ) Cuba, Iran, Iraq, Libya, North Kor¶
83664d ean, Sudan, Syria or any other country to which the United States has embargoed¶
51c8de ·goods; or (ii) to anyone on the United States Treasury Department's list of Sp¶
8dfc6f ecially Designated Nations or the United States Commerce Department's Table of ¶
bff096 Denial Orders. ·By downloading or using the Software you are agreeing to the fo¶
1f698e regoing and you are certifying that you are not located in, under the control o¶
8d6a1f f, or a national or resident of any such country or on any such list. ·
8caf5a
1d18a9 IN ADDITION, YOU SHOULD BE AWARE OF THE FOLLOWING. ·EXPORT OF THE SOFTWARE MAY ¶
2c1af4 BE SUBJECT TO COMPLIANCE WITH THE RULES AND REGULATIONS PROMULGATED FROM TIME T¶
3a816e O TIME BY THE BUREAU OF EXPORT ADMINISTRATION, UNITED STATES DEPARTMENT OF COMM¶
e3e739 ERCE, WHICH RESTRICT THE EXPORT AND RE-EXPORT OF CERTAIN PRODUCTS AND TECHNICAL¶
c920a7 ·DATA. ·IF THE EXPORT OF THE SOFTWARE IS CONTROLLED UNDER SUCH RULES AND REGULA¶
269568 TIONS, THEN THE SOFTWARE SHALL NOT BE EXPORTED OR RE-EXPORTED, DIRECTLY OR INDI¶
7986c4 RECTLY, (A) WITHOUT ALL EXPORT OR RE-EXPORT LICENSES AND UNITED STATES OR OTHER¶
e7219e ·GOVERNMENTAL APPROVALS REQUIRED BY ANY APPLICABLE LAWS, OR (B) IN VIOLATION OF¶
51ac24 ·ANY APPLICABLE PROHIBITION AGAINST THE EXPORT OR RE-EXPORT OF ANY PART OF THE ¶
634287 SOFTWARE. ·SOME COUNTRIES HAVE RESTRICTIONS ON THE USE OF ENCRYPTION WITHIN THE¶
8f4ec5 IR BORDERS, OR THE IMPORT OR EXPORT OF ENCRYPTION EVEN IF FOR ONLY TEMPORARY PE¶
97bb26 RSONAL OR BUSINESS USE. ·YOU ACKNOWLEDGE THAT THE IMPLEMENTATION AND ENFORCEMEN¶
c8fc83 T OF THESE LAWS IS NOT ALWAYS CONSISTENT AS TO SPECIFIC COUNTRIES. ·ALTHOUGH TH¶
7868a6 E FOLLOWING COUNTRIES ARE NOT AN EXHAUSTIVE LIST THERE MAY EXIST RESTRICTIONS O¶
ef60a5 N THE EXPORTATION TO, OR IMPORTATION OF, ENCRYPTION BY: ·BELGIUM, CHINA (INCLUD¶
c408eb ING HONG KONG), FRANCE, INDIA, INDONESIA, ISRAEL, RUSSIA, SAUDI ARABIA, SINGAPO¶
7d86c1 RE, ·AND SOUTH KOREA. YOU ACKNOWLEDGE IT IS YOUR ULTIMATE RESPONSIBILITY TO COM¶
cc2e00 PLY WITH ALL ANY AND ALL GOVERNMENT EXPORT AND OTHER APPLICABLE ·LAWS AND THAT ¶
fec4c0 NETWORK ASSOCIATES HAS NO FURTHER RESPONSIBILITY AFTER THE INITIAL SALE TO YOU ¶
89c33c WITHIN THE ORIGINAL COUNTRY OF SALE.
65af5a
ce9a34 ·10.¤   High Risk Activities. ·The Software is not fault-tolerant and is not de¶
558ad0 signed or intended for use in hazardous environments requiring fail-safe perfor¶
b885f8 mance, including without limitation, in the operation of nuclear facilities, ai¶
94a8f6 rcraft navigation or communication systems, air traffic control, weapons system¶
fa36a4 s, direct life-support machines, or any other application in which the failure ¶
f455e3 of the Software could lead directly to death, personal injury, or severe physic¶
021e3f al or property damage (collectively, "High Risk Activities"). ·Network Associat¶
83b923 es expressly disclaims any express or implied warranty of fitness for High Risk¶
9c558d ·Activities.
0baf5a
95a2cb 11.¤Miscellaneous. ··This Agreement is governed by the laws of the United State¶
f10fc5 s and the State of California, without reference to conflict of laws principles¶
140994 . ·The application of the United Nations Convention of Contracts for the Intern¶
619ba7 ational Sale of Goods is expressly excluded. ·This Agreement sets forth all rig¶
b94d9b hts for the user of the Software and is the entire agreement between the partie¶
418627 s. This agreement supersedes any other communications with respect to the Softw¶
0ccb1e are and Documentation. ··This Agreement may not be modified except by a written¶
4a7e57 ·addendum issued by a duly authorized representative of Network Associates. ·No¶
--ffe3 001aa3840e24011021d Page 4 of license.txt
21c489 ·provision hereof shall be deemed waived unless such waiver shall be in writing¶
34cb20 ·and signed by Network Associates or a duly authorized representative of Networ¶
709353 k Associates. ·If any provision of this Agreement is held invalid, the remainde¶
a847ff r of this Agreement shall continue in full force and effect. ·The parties confi¶
edb7dd rm that it is their wish that this Agreement has been written in the English la¶
b6bbbe nguage only. ·Network Associates may identify you as a customer of Network Asso¶
036234 ciates and describe in a mutually agreeable Customer Case Study the services an¶
e22f22 d solutions delivered by Network Associates to you. Network Associates may also¶
252bb0 ·issue one or more mutually agreeable press releases containing an announcement¶
87f5a0 ·of the execution and delivery of this Agreement and/or the implementation of t¶
407f54 he Products by you. No such document or release shall include any information c¶
45b742 onsidered Confidential by you. Your approval to any such document or release sh¶
3c2592 all not be unreasonably withheld and shall be deemed given unless you indicate ¶
223402 otherwise in writing within ten (10) days of delivery of the proposed document ¶
1f753c or release.·
cbaf5a
673460 12.¤NETWORK ASSOCIATES CUSTOMER CONTACT. ·If you have any questions concerning ¶
9ef9d7 these terms and conditions, or if you would like to contact Network Associates ¶
c5f00a for any other reason, please call (408) 988-3832, fax (408) 970-9727, or write:¶
5842f3 ··Network Associates, Inc. 3965 Freedom Circle, Santa Clara, California 95054. ¶
aa98c3 ·http://www.nai.com.
--6927 000a2df57344011021e Page 1 of reglic.txt
e0af5a
1aaf5a
e21be8 ¤   Network Associates End User License Agreement
62af5a
e0af5a
961817 NOTICE TO ALL USERS: ···CAREFULLY READ THE FOLLOWING LEGAL AGREEMENT ( "AGREEME¶
9a3762 NT"), FOR THE LICENSE OF SPECIFIED SOFTWARE ("SOFTWARE") BY NETWORK ASSOCIATES,¶
e0b3f3 ·INC. ("NETWORK ASSOCIATES"). ··BY CLICKING THE ACCEPT BUTTON OR INSTALLING THE¶
1ecbe4 ·SOFTWARE, YOU (EITHER AN INDIVIDUAL OR A SINGLE ENTITY) CONSENT TO BE BOUND BY¶
3882be ·AND BECOME A PARTY TO THIS AGREEMENT. ·IF YOU DO NOT AGREE TO ALL OF THE TERMS¶
e072b5 ·OF THIS AGREEMENT, CLICK THE BUTTON THAT INDICATES THAT YOU DO NOT ACCEPT THE ¶
3df087 TERMS OF THIS AGREEMENT AND DO NOT INSTALL THE SOFTWARE. ·(IF APPLICABLE, YOU M¶
6184fd AY RETURN THE PRODUCT TO THE PLACE OF PURCHASE FOR A FULL REFUND.) ·
14af5a
b3e9a0 ·1.¤License Grant. ·Subject to the payment of the applicable license fees, and ¶
cf8e7d subject to the terms and conditions of this Agreement, Network Associates hereb¶
d6f560 y grants to you a non-exclusive, non-transferable right to use one copy of the ¶
5c4084 specified version of the Software and the accompanying documentation (the "Docu¶
e6dafa mentation"). ·You may install one copy of the Software on one computer, worksta¶
26fb1b tion, personal digital assistant, pager, "smart phone" or other electronic devi¶
b5916a ce for which the Software was designed (each, a "Client Device"). ····If the So¶
70b64f ftware is licensed as a suite or bundle with more than one specified Software p¶
c92afd roducts, this license applies to all such specified Software products, subject ¶
09c7c0 to any restrictions or usage terms specified on the applicable price list or pr¶
241b9d oduct packaging that apply to any of such Software products individually.
f8af5a
03d73e ·¤  a.¤ Use. ·The Software is licensed as a single product; it may not be used ¶
e76719 on more than one Client Device or by more than one user at a time, except as se¶
9f0a6b t forth in this Section 1. ·The Software is "in use" on a computer when it is l¶
cbfb52 oaded into the temporary memory (i.e., random-access memory or RAM) or installe¶
e60130 d into the permanent memory (e.g., hard disk, CD-ROM, or other storage device) ¶
594acc of that Client Device. ·This license authorizes you to make one copy of the Sof¶
5290f3 tware solely for backup or archival purposes, provided that the copy you make c¶
dcb400 ontains all of the Software's proprietary notices.
4caf5a
89c2b5 ·¤  b.¤ Server-Mode. ·To the extent such use is specified in the applicable pri¶
86af6a ce list or product packaging for the Software, you may use the Software on a Cl¶
af2fc2 ient Device as a server ("Server") within a multi-user or networked environment¶
b3e149 ·("Server-Mode") for ·either (i) connecting, directly or indirectly, to not mor¶
de5822 e than the maximum number of specified Client Devices, or (ii) deploying not mo¶
07aa02 re than the maximum number of agents (pollers) specified for deployment. ·If no¶
773856 ·such maximum number is specified, this is a single product use license subject¶
ee6150 ·to subsection (a) above. ·A separate license is required for each Client Devic¶
9e9b88 e or "seat" that may connect to the Server at any time, regardless of whether s¶
2d9bf1 uch licensed Client Devices or seats are concurrently connected to, accessing o¶
ec7398 r using the Software. ··Use of software or hardware that reduces the number of ¶
fdb3ad Client Devices or seats directly accessing or utilizing the Software (e.g., "mu¶
1e7fd3 ltiplexing" or "pooling" software or hardware) does not reduce the number of li¶
5ea1fe censes required (i.e., the required number of licenses would equal the number o¶
53354f f distinct inputs to the multiplexing or pooling software or hardware "front en¶
16e80f d"). ·If the number of Client Devices or seats that can connect to the Software¶
f66ad3 ·can exceed the number of licenses you have obtained, then you must have a reas¶
5feef7 onable mechanism in place to ensure that your use of the Software does not exce¶
13390c ed the use limits specified for the license you have obtained. ·This license au¶
dcd5f1 thorizes you to make or download one copy of the Documentation for each Client ¶
544e5e Device or seat that is licensed, provided that each such copy contains all of t¶
22df6b he Documentation's proprietary notices.
59af5a
80af5a
3edefe ·¤  c.¤ Volume Licenses. ·If the Software is licensed with volume license terms¶
11befa ·specified in the applicable price list or product packaging for the Software, ¶
d1c5fa you may make, use and install as many additional copies of the Software on the ¶
604d03 number of Client Devices as the volume license authorizes. ·You must have a rea¶
e3082f sonable mechanism in place to ensure that the number of Client Devices on which¶
c1d8b1 ·the Software has been installed does not exceed the number of licenses you hav¶
8900db e obtained. ···This license authorizes you to make or download one copy of the ¶
cdb45f Documentation for each additional copy authorized by the volume license, provid¶
3d78ce ed that each such copy contains all of the Documentation's proprietary notices.
b3af5a
309e17 ·2.¤Term. ·This Agreement is effective unless and until you or Network Associat¶
6e40d6 es terminates the Agreement earlier, in accordance with the terms set forth her¶
a27eda ein. This Agreement will terminate automatically if you fail to comply with any¶
--521b 000525550624011021e Page 2 of reglic.txt
c060b1 ·of the limitations or other requirements described herein. ·When this agreemen¶
8ca102 t terminates, you must destroy all copies of the Software and the Documentation¶
45b24b . ·You may terminate this Agreement at any point by destroying all copies of th¶
172bf0 e Software and the Documentation.·
48af5a
018663 3.¤ Updates. ·For the time period specified in the applicable price list or pro¶
6e22af duct packaging for the Software, and if not specified, then for a period of nin¶
f34c31 ety (90) days from the date of original purchase of the Software, you are entit¶
271a05 led to download revisions, upgrades, or updates to the Software when and as Net¶
ecd0fa work Associates publishes them via its electronic bulletin board system, websit¶
7f3f73 e or through other online services. ·After the specified time period, you have ¶
40d5fc no further rights to receive any revisions, upgrades or updates without purchas¶
ffd1c2 e of a new license to the Software.
7daf5a
7a9838 4.¤ Ownership Rights. ·The Software is protected by United States copyright law¶
5bcbdd s and international treaty provisions. ·Network Associates and its suppliers ow¶
e86367 n and retain all right, title and interest in and to the Software, including al¶
18299a l copyrights, patents, trade secret rights, trademarks and other intellectual p¶
88b35b roperty rights therein. ·You acknowledge that your possession, installation, or¶
204701 ·use of the Software does not transfer to you any title to the intellectual pro¶
532292 perty in the Software, and that you will not acquire any rights to the Software¶
fa9fb3 ·except as expressly set forth in this Agreement. ·You agree that any copies of¶
f5cba7 ·the Software and Documentation will contain the same proprietary notices which¶
27c987 ·appear on and in the Software and Documentation.
a9af5a
0a3c5a 5. ¤Restrictions. ·You may not rent, lease, loan or resell the Software. ·You m¶
e7ef8d ay not permit third parties to benefit from the use or functionality of the Sof¶
afa285 tware via a timesharing, service bureau or other arrangement, except to the ext¶
3e09fe ent such use is specified in the applicable list price or product packaging for¶
14afd4 ·the Software. ·You may not transfer any of the rights granted to you under thi¶
dd3d5c s Agreement. ·You may not reverse engineer, decompile, or disassemble the Softw¶
6d63ab are, except to the extent the foregoing restriction is expressly prohibited by ¶
57f4fe applicable law. ·You may not modify, or create derivative works based upon, the¶
5faa38 ·Software in whole or in part. ·You may not copy the Software or Documentation ¶
5d2537 except as expressly permitted in Section 1 above. ·You may not remove any propr¶
712d62 ietary notices or labels on the Software. All rights not expressly set forth he¶
66d90b reunder are reserved by Network Associates. ··Network Associates reserves the r¶
c22548 ight to periodically conduct audits upon advance written notice to verify compl¶
79cc9d iance with the terms of this Agreement.
f4d83c ·
de5e96 6. ¤Warranty and Disclaimer
63af5a
e1a676 ·¤  a.¤ Limited Warranty. ··Network Associates warrants that for sixty (60) day¶
ffae3e s from the date of original purchase the media (for example diskettes) on which¶
1af5c9 ·the Software is contained will be free from defects in materials and workmansh¶
b1f626 ip.
47af5a
0faf5a
b7cfe2 b. Customer Remedies. ·Network Associates' and its suppliers' entire liability ¶
74bf51 and your exclusive remedy shall be, at Network Associates' option, either (i) r¶
1d6999 eturn of the purchase price paid for the license, if any, or (ii) replacement o¶
a29c1c f the defective media in which the Software is contained with a copy on nondefe¶
48a004 ctive media. ··You must return the defective media to Network Associates at you¶
d2dd50 r expense with a copy of your receipt. ·This limited warranty is void if the de¶
d60ea2 fect has resulted from accident, abuse, or misapplication. ·Any replacement med¶
08ec04 ia will be warranted for the remainder of the original warranty period. ·Outsid¶
c545c8 e the United States, this remedy is not available to the extent Network Associa¶
9a3e39 tes is subject to restrictions under United States export control laws and regu¶
4b5a1f lations.
b4af5a
eedf77 c. Warranty Disclaimer. ·To the maximum extent permitted by applicable law, and¶
4a3af1 ·except for the limited warranty set forth herein, THE SOFTWARE IS PROVIDED ON ¶
694c90 AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. WITHOUT LIMI¶
87564f TING THE FOREGOING PROVISIONS, YOU ASSUME RESPONSIBILITY FOR SELECTING THE SOFT¶
66af61 WARE TO ACHIEVE YOUR INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND¶
8579f7 ·RESULTS OBTAINED FROM THE SOFTWARE. ·WITHOUT LIMITING THE FOREGOING PROVISIONS¶
671852 , NETWORK ASSOCIATES MAKES NO WARRANTY THAT THE SOFTWARE WILL BE ERROR-FREE OR ¶
31f4b3 FREE FROM INTERRUPTIONS OR OTHER FAILURES OR THAT THE SOFTWARE WILL MEET YOUR R¶
e9b49e EQUIREMENTS. ·TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NETWORK ASSOCI¶
f28bb8 ATES DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIM¶
281641 ITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE¶
520b73 , AND NONINFRINGEMENT WITH RESPECT TO THE SOFTWARE AND THE ACCOMPANYING DOCUMEN¶
--3195 0005376d28a4011021e Page 3 of reglic.txt
ed5169 TATION. ·SOME STATES AND JURISDICTIONS DO NOT ALLOW LIMITATIONS ON IMPLIED WARR¶
6cf24b ANTIES, SO THE ABOVE LIMITATION MAY NOT APPLY TO YOU. ·The foregoing provisions¶
783389 ·shall be enforceable to the maximum extent permitted by applicable law.
d5af5a
4e3709 7. ¤Limitation of Liability. ·UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,¶
f433d9 ·WHETHER IN TORT, CONTRACT, OR OTHERWISE, SHALL NETWORK ASSOCIATES OR ITS SUPPL¶
865e6e IERS BE LIABLE TO YOU OR TO ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDEN¶
953806 TAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, D¶
7649b4 AMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR¶
db8e5e ·FOR ANY AND ALL OTHER DAMAGES OR LOSSES. ·IN NO EVENT WILL NETWORK ASSOCIATES ¶
5582db BE LIABLE FOR ANY DAMAGES IN EXCESS OF THE LIST PRICE NETWORK ASSOCIATES CHARGE¶
9aeb10 S FOR A LICENSE TO THE SOFTWARE, EVEN IF NETWORK ASSOCIATES SHALL HAVE BEEN ADV¶
32a98a ISED OF THE POSSIBILITY OF SUCH DAMAGES. ·THIS LIMITATION OF LIABILITY SHALL NO¶
e2e045 T APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY TO THE EXTENT THAT APPLICABLE¶
517777 ·LAW PROHIBITS SUCH LIMITATION. ·FURTHERMORE, SOME STATES AND JURISDICTIONS ·DO¶
0479be ·NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, ¶
d6d28d SO THIS LIMITATION AND EXCLUSION MAY NOT APPLY TO YOU. ·The foregoing provision¶
338ca9 s shall be enforceable to the maximum extent permitted by applicable law.
d6af5a
ed84cd 8. ¤United States Government. ·The Software and accompanying Documentation are ¶
fe42f7 deemed to be "commercial computer software" and "commercial computer software d¶
50154b ocumentation," respectively, pursuant to DFAR Section 227.7202 and FAR Section ¶
a46ffc 12.212, as applicable. ·Any use, modification, reproduction, release, performan¶
ef4de5 ce, display or disclosure of the Software and accompanying Documentation by the¶
01cdc2 ·United States Government shall be governed solely by the terms of this Agreeme¶
1554d6 nt and shall be prohibited except to the extent expressly permitted by the term¶
1e680a s of this Agreement.·
9daf5a
7caf5a
bfe209 ·9.¤Export Controls. Neither the Software nor the Documentation and underlying ¶
c59bd9 information or technology may be downloaded or otherwise exported or reexported¶
8adc0f ·(i) into (or to a national or resident of ) Cuba, Iran, Iraq, Libya, North Kor¶
ec664d ean, Sudan, Syria or any other country to which the United States has embargoed¶
d4c8de ·goods; or (ii) to anyone on the United States Treasury Department's list of Sp¶
d5fc6f ecially Designated Nations or the United States Commerce Department's Table of ¶
88f096 Denial Orders. ·By downloading or using the Software you are agreeing to the fo¶
31698e regoing and you are certifying that you are not located in, under the control o¶
e76a1f f, or a national or resident of any such country or on any such list. ·
d0af5a
f318a9 IN ADDITION, YOU SHOULD BE AWARE OF THE FOLLOWING. ·EXPORT OF THE SOFTWARE MAY ¶
d01af4 BE SUBJECT TO COMPLIANCE WITH THE RULES AND REGULATIONS PROMULGATED FROM TIME T¶
b2816e O TIME BY THE BUREAU OF EXPORT ADMINISTRATION, UNITED STATES DEPARTMENT OF COMM¶
00e739 ERCE, WHICH RESTRICT THE EXPORT AND RE-EXPORT OF CERTAIN PRODUCTS AND TECHNICAL¶
1b20a7 ·DATA. ·IF THE EXPORT OF THE SOFTWARE IS CONTROLLED UNDER SUCH RULES AND REGULA¶
f99568 TIONS, THEN THE SOFTWARE SHALL NOT BE EXPORTED OR RE-EXPORTED, DIRECTLY OR INDI¶
7986c4 RECTLY, (A) WITHOUT ALL EXPORT OR RE-EXPORT LICENSES AND UNITED STATES OR OTHER¶
44219e ·GOVERNMENTAL APPROVALS REQUIRED BY ANY APPLICABLE LAWS, OR (B) IN VIOLATION OF¶
50ac24 ·ANY APPLICABLE PROHIBITION AGAINST THE EXPORT OR RE-EXPORT OF ANY PART OF THE ¶
c64287 SOFTWARE. ·SOME COUNTRIES HAVE RESTRICTIONS ON THE USE OF ENCRYPTION WITHIN THE¶
7b4ec5 IR BORDERS, OR THE IMPORT OR EXPORT OF ENCRYPTION EVEN IF FOR ONLY TEMPORARY PE¶
9ebb26 RSONAL OR BUSINESS USE. ·YOU ACKNOWLEDGE THAT THE IMPLEMENTATION AND ENFORCEMEN¶
91fc83 T OF THESE LAWS IS NOT ALWAYS CONSISTENT AS TO SPECIFIC COUNTRIES. ·ALTHOUGH TH¶
1768a6 E FOLLOWING COUNTRIES ARE NOT AN EXHAUSTIVE LIST THERE MAY EXIST RESTRICTIONS O¶
4f60a5 N THE EXPORTATION TO, OR IMPORTATION OF, ENCRYPTION BY: ·BELGIUM, CHINA (INCLUD¶
7408eb ING HONG KONG), FRANCE, INDIA, INDONESIA, ISRAEL, RUSSIA, SAUDI ARABIA, SINGAPO¶
5a86c1 RE, ·AND SOUTH KOREA. YOU ACKNOWLEDGE IT IS YOUR ULTIMATE RESPONSIBILITY TO COM¶
882e00 PLY WITH ALL ANY AND ALL GOVERNMENT EXPORT AND OTHER APPLICABLE ·LAWS AND THAT ¶
27c4c0 NETWORK ASSOCIATES HAS NO FURTHER RESPONSIBILITY AFTER THE INITIAL SALE TO YOU ¶
3ac33c WITHIN THE ORIGINAL COUNTRY OF SALE.
1baf5a
5b9a34 ·10.¤   High Risk Activities. ·The Software is not fault-tolerant and is not de¶
cd8ad0 signed or intended for use in hazardous environments requiring fail-safe perfor¶
9285f8 mance, including without limitation, in the operation of nuclear facilities, ai¶
b3a8f6 rcraft navigation or communication systems, air traffic control, weapons system¶
b336a4 s, direct life-support machines, or any other application in which the failure ¶
3c55e3 of the Software could lead directly to death, personal injury, or severe physic¶
6a1e3f al or property damage (collectively, "High Risk Activities"). ·Network Associat¶
ecb923 es expressly disclaims any express or implied warranty of fitness for High Risk¶
2a558d ·Activities.
49af5a
eaa2cb 11.¤Miscellaneous. ··This Agreement is governed by the laws of the United State¶
530fc5 s and the State of California, without reference to conflict of laws principles¶
--ab45 0011229af364011021e Page 4 of reglic.txt
180994 . ·The application of the United Nations Convention of Contracts for the Intern¶
809ba7 ational Sale of Goods is expressly excluded. ·This Agreement sets forth all rig¶
3a4d9b hts for the user of the Software and is the entire agreement between the partie¶
db8627 s. This agreement supersedes any other communications with respect to the Softw¶
c4cb1e are and Documentation. ··This Agreement may not be modified except by a written¶
ac7e57 ·addendum issued by a duly authorized representative of Network Associates. ·No¶
a6c489 ·provision hereof shall be deemed waived unless such waiver shall be in writing¶
afcb20 ·and signed by Network Associates or a duly authorized representative of Networ¶
ac9353 k Associates. ·If any provision of this Agreement is held invalid, the remainde¶
2d47ff r of this Agreement shall continue in full force and effect. ·The parties confi¶
d1b7dd rm that it is their wish that this Agreement has been written in the English la¶
149ee8 nguage only. ·
c7af5a
c8af5a
033460 12.¤NETWORK ASSOCIATES CUSTOMER CONTACT. ·If you have any questions concerning ¶
bef9d7 these terms and conditions, or if you would like to contact Network Associates ¶
3cf00a for any other reason, please call (408) 988-3832, fax (408) 970-9727, or write:¶
d30905 ··Network Associates, Inc., 3965 Freedom Circle, Santa Clara, California 95054.¶
12824a ··http://www.nai.com.
--8fd3 000639a05f54011021f Page 1 of triallic.txt
e0af5a
8df1d4 ¤   Network Associates Thirty (30)-Day Evaluation License Agreement
50af5a
94af5a
35bca3 THIS IS AN EVALUATION COPY OF THIS SOFTWARE. You may use this software for only¶
6e0232 ·thirty (30) days, after which period you must either buy the software from Net¶
227f82 work Associates, Inc. or remove it from your computer and stop using it.·
aeaf5a
2ecdf7 NOTICE TO ALL USERS: CAREFULLY READ THE FOLLOWING LEGAL AGREEMENT (THE "AGREEME¶
75856f NT") FOR THE LICENSE OF SOFTWARE (THE "SOFTWARE") BY NETWORK ASSOCIATES, INC. (¶
fc7f31 "NETWORK ASSOCIATES"). ··BY CLICKING THE ACCEPTANCE BUTTON OR INSTALLING THE SO¶
03d102 FTWARE, YOU (EITHER AN INDIVIDUAL OR A SINGLE ENTITY) ARE CONSENTING TO BE BOUN¶
c21bff D BY AND ARE BECOMING A PARTY TO THIS AGREEMENT. ·IF YOU DO NOT AGREE TO ALL OF¶
a6c13b ·THE TERMS OF THIS AGREEMENT, CLICK THE BUTTON THAT INDICATES THAT YOU DO NOT A¶
5b6169 CCEPT THE TERMS AND DO NOT INSTALL THE SOFTWARE. ·(IF APPLICABLE, YOU MAY RETUR¶
31e94e N THE PRODUCT TO THE PLACE OF PURCHASE FOR A FULL REFUND.) Your right to use th¶
089314 e Software is limited. ·If you have already downloaded evaluation copies of thi¶
2741a3 s or prior versions of the Software, you may not use this Software and must imm¶
1fdbf3 ediately cease using this copy and destroy it. ·To obtain full-use rights, you ¶
a0685b must pay for the Software and enter a valid End User License Agreement with Net¶
605192 work Associates concerning such use.
b6af5a
29c57c ·1.¤License Grant. ·Subject to the terms and conditions of this Agreement, Netw¶
f138f2 ork Associates hereby grants to you a non-exclusive, non-transferable right to ¶
98c401 use one copy of the specified version of the Software and the accompanying docu¶
475fb4 mentation (the "Documentation") solely for your internal evaluation purposes du¶
35a1a8 ring the term of this Agreement. ·You may install one copy of the Software on o¶
098113 ne computer, workstation, personal digital assistant, pager, "smart phone" or o¶
8e7f82 ther electronic device for which the Software was designed (each, a "Client Dev¶
a72bea ice").·
aca4ab ¤   ·
d06c2a ·2.¤Term. ·This Agreement is effective for thirty (30) days following the date ¶
a0a399 you installed the Software unless earlier terminated as set forth in this Agree¶
30457e ment. This Agreement will terminate automatically if you fail to comply with an¶
9bf0b3 y of the limitations or other requirements described herein. ·Upon termination,¶
8d226c ·you must destroy all copies of the Software and Documentation. ·You may termin¶
c0f2bf ate this Agreement at any point by destroying the Software and Documentation to¶
8df34e gether with all copies of the Software and Documentation.·
8eaf5a
8120d2 3.¤ Ownership Rights. ·The Software is protected by United States copyright law¶
52cbdd s and international treaty provisions. ·Network Associates and its suppliers ow¶
2d2434 n and retain all right, title and interest ·in and to the Software, including a¶
a11cae ll copyrights, patents, trade secret rights, trademarks and other intellectual ¶
c9aec1 property rights therein. ·You acknowledge that no title to the intellectual pro¶
0f233a perty in the Software is transferred to you, and you will not acquire any right¶
362f42 s to the Software except as expressly set forth in this license. ·You agree tha¶
bcdd33 t any copies of the Software and Documentation will contain the same proprietar¶
a60666 y notices which appear on and in the Software and Documentation.
3faf5a
3761fb 4. ¤Restrictions. You may not rent, lease, loan or resell the Software. ·You ma¶
b95348 y not permit third parties to benefit from the use or functionality of the Soft¶
c2f291 ware via a timesharing, service bureau or other arrangement, except to the exte¶
b94ca7 nt such use is specified in the applicable price list, purchase order, or produ¶
ccf3fd ct packaging for the Software. ·You may not transfer any of the rights granted ¶
7365c6 to you under this Agreement. ·You may not reverse engineer, decompile, or disas¶
e9ad4d semble the Software, except to the extent the foregoing restriction is expressl¶
6dfa77 y prohibited by applicable law. ·You may not modify, or create derivative works¶
bc7a89 ·based upon, the Software in whole or in part. ·You may not copy the Software o¶
905b1f r Documentation except as expressly permitted in Section 1 above. ·You may not ¶
cf0ae8 remove any proprietary notices or labels on the Software. All rights not expres¶
f0a452 sly set forth hereunder are reserved by Network Associates. ··Network Associate¶
facd01 s reserves the right to periodically conduct audits upon advance written notice¶
acdafc ·to verify compliance with the terms of this Agreement.
4eaf5a
55d83c ·
c9e617 5. ¤Warranty Disclaimer ··AS THIS IS AN EVALUATION COPY, TO THE MAXIMUM EXTENT ¶
cf777a PERMITTED BY APPLICABLE LAW THE ·SOFTWARE IS PROVIDED ON AN "AS IS" BASIS WITHO¶
4f9b1a UT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. WITHOUT LIMITING THE FOREGOING, YO¶
450539 U ASSUME RESPONSIBILITY FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR INTENDED ¶
03242c RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED FROM THE SOF¶
4b937c TWARE. ·WITHOUT LIMITING THE FOREGOING, NETWORK ASSOCIATES MAKES NO WARRANTY TH¶
636885 AT THE SOFTWARE WILL BE ERROR-FREE OR UNINTERRUPTED OR THAT THE SOFTWARE WILL M¶
--b436 0003ebe94854011021f Page 2 of triallic.txt
4ae2e5 EET YOUR REQUIREMENTS. ·TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NETW¶
bf9ed4 ORK ASSOCIATES DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING B¶
3d6c01 UT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICUL¶
a1d443 AR PURPOSE, AND NONINFRINGEMENT WITH RESPECT TO THE SOFTWARE AND THE ACCOMPANYI¶
7a5216 NG DOCUMENTATION. ·SOME STATES AND JURISDICTIONS DO NOT ALLOW LIMITATIONS ON IM¶
c2dbdd PLIED WARRANTIES, SO THE ABOVE LIMITATION MAY NOT APPLY TO YOU. ·THE FOREGOING ¶
4ae1e3 SHALL BE ENFORCEABLE TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW.
54af5a
24672c 6. ¤Limitation of Liability. ·UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,¶
9f7d2c ·TORT, CONTRACT, OR OTHERWISE, SHALL NETWORK ASSOCIATES OR ITS SUPPLIERS BE LIA¶
924e2b BLE TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQ¶
4caae8 UENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOS¶
75de17 S OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL O¶
7ca007 THER DAMAGES OR LOSSES. ·IN NO EVENT WILL NETWORK ASSOCIATES BE LIABLE FOR ANY ¶
2f66ad DAMAGES IN EXCESS OF THE AMOUNT PAID BY YOU, IF ANY, FOR THE SOFTWARE, EVEN IF ¶
cc1b6f NETWORK ASSOCIATES SHALL HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ¶
4a0365 THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL¶
cd03d8 ·INJURY TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. ·FURTHERMORE, S¶
c839ce OME STATES AND JURISDICTIONS ·DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCID¶
8651e8 ENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT APPLY ¶
71e584 TO YOU. ·THE FOREGOING SHALL BE ENFORCEABLE TO THE MAXIMUM EXTENT PERMITTED BY ¶
964e0c APPLICABLE LAW.
06af5a
49af5a
80ad2d 7. ¤United States Government. ·The Software and accompanying Documentation are ¶
3c42f7 deemed to be "commercial computer software" and "commercial computer software d¶
ae154b ocumentation," respectively, pursuant to DFAR Section 227.7202 and FAR Section ¶
476ffc 12.212, as applicable. ·Any use, modification, reproduction, release, performan¶
a84de5 ce, display or disclosure of the Software and accompanying Documentation by the¶
f2cdc2 ·United States Government shall be governed solely by the terms of this Agreeme¶
d254d6 nt and shall be prohibited except to the extent expressly permitted by the term¶
e4680a s of this Agreement.·
17af5a
63527b ·8.¤Export Controls. Neither the Software nor the Documentation and underlying ¶
5f9bd9 information or technology may be downloaded or otherwise exported or reexported¶
78dc0f ·(i) into (or to a national or resident of ) Cuba, Iran, Iraq, Libya, North Kor¶
48664d ean, Sudan, Syria or any other country to which the United States has embargoed¶
8cc8de ·goods; or (ii) to anyone on the United States Treasury Department's list of Sp¶
03fc6f ecially Designated Nations or the United States Commerce Department's Table of ¶
95f096 Denial Orders. ·By downloading or using the Software you are agreeing to the fo¶
7b698e regoing and you are certifying that you are not located in, under the control o¶
e16a1f f, or a national or resident of any such country or on any such list. ·
39af5a
7318a9 IN ADDITION, YOU SHOULD BE AWARE OF THE FOLLOWING. ·EXPORT OF THE SOFTWARE MAY ¶
b91af4 BE SUBJECT TO COMPLIANCE WITH THE RULES AND REGULATIONS PROMULGATED FROM TIME T¶
a5816e O TIME BY THE BUREAU OF EXPORT ADMINISTRATION, UNITED STATES DEPARTMENT OF COMM¶
e0e739 ERCE, WHICH RESTRICT THE EXPORT AND RE-EXPORT OF CERTAIN PRODUCTS AND TECHNICAL¶
2f20a7 ·DATA. ·IF THE EXPORT OF THE SOFTWARE IS CONTROLLED UNDER SUCH RULES AND REGULA¶
cd9568 TIONS, THEN THE SOFTWARE SHALL NOT BE EXPORTED OR RE-EXPORTED, DIRECTLY OR INDI¶
4a86c4 RECTLY, (A) WITHOUT ALL EXPORT OR RE-EXPORT LICENSES AND UNITED STATES OR OTHER¶
3f219e ·GOVERNMENTAL APPROVALS REQUIRED BY ANY APPLICABLE LAWS, OR (B) IN VIOLATION OF¶
e9ac24 ·ANY APPLICABLE PROHIBITION AGAINST THE EXPORT OR RE-EXPORT OF ANY PART OF THE ¶
8b4287 SOFTWARE. ·SOME COUNTRIES HAVE RESTRICTIONS ON THE USE OF ENCRYPTION WITHIN THE¶
894ec5 IR BORDERS, OR THE IMPORT OR EXPORT OF ENCRYPTION EVEN IF FOR ONLY TEMPORARY PE¶
c4bb26 RSONAL OR BUSINESS USE. ·YOU ACKNOWLEDGE THAT THE IMPLEMENTATION AND ENFORCEMEN¶
31fc83 T OF THESE LAWS IS NOT ALWAYS CONSISTENT AS TO SPECIFIC COUNTRIES. ·ALTHOUGH TH¶
3468a6 E FOLLOWING COUNTRIES ARE NOT AN EXHAUSTIVE LIST THERE MAY EXIST RESTRICTIONS O¶
bb60a5 N THE EXPORTATION TO, OR IMPORTATION OF, ENCRYPTION BY: ·BELGIUM, CHINA (INCLUD¶
7b08eb ING HONG KONG), FRANCE, INDIA, INDONESIA, ISRAEL, RUSSIA, SAUDI ARABIA, SINGAPO¶
1886c1 RE, ·AND SOUTH KOREA. YOU ACKNOWLEDGE IT IS YOUR ULTIMATE RESPONSIBILITY TO COM¶
a92e00 PLY WITH ALL ANY AND ALL GOVERNMENT EXPORT AND OTHER APPLICABLE ·LAWS AND THAT ¶
49c4c0 NETWORK ASSOCIATES HAS NO FURTHER RESPONSIBILITY AFTER THE INITIAL SALE TO YOU ¶
3cc33c WITHIN THE ORIGINAL COUNTRY OF SALE.
b6af5a
f0ef8a ·9.¤High Risk Activities. ·The Software is not fault-tolerant and is not design¶
d5454c ed or intended for use in hazardous environments requiring fail-safe performanc¶
9db49a e, including without limitation, in the operation of nuclear facilities, aircra¶
6f2aa8 ft navigation or communication systems, air traffic control, weapons systems, d¶
1aac0a irect life-support machines, or any other application in which the failure of t¶
70355c he Software could lead directly to death, personal injury, or severe physical o¶
6a4ba3 r property damage (collectively, "High Risk Activities"). ·Network Associates e¶
3e7f14 xpressly disclaims any express or implied warranty of fitness for High Risk Act¶
--186a 001dcbbec094011021f Page 3 of triallic.txt
31f815 ivities.
56af5a
1360d3 10.¤Miscellaneous. ··This License is governed by the laws of the United States ¶
308ac9 and the State of California, without reference to conflict of laws principles. ¶
670109 ·The application of the United Nations Convention of Contracts for the Internat¶
adf00d ional Sale of Goods is expressly excluded. ·This License is the entire agreemen¶
d81c6b t between the parties and supersedes any other communications with respect to t¶
9db7a3 he Software and Documentation. ··This License may not be modified except by a w¶
032636 ritten addendum issued by a duly authorized representative of Network Associate¶
d96472 s. ·No provision hereof shall be deemed waived unless such waiver shall be in w¶
d3bf11 riting and signed by Network Associates. If any provision of this License is he¶
2eb15b ld invalid, the remainder of this License shall continue in full force and effe¶
c32043 ct. The parties confirm that it is their wish that this License has been writte¶
5fc571 n in the English language only. ·
dfaf5a
162763 11.¤NETWORK ASSOCIATES CUSTOMER CONTACT. ·If have any questions concerning thes¶
c5025c e terms and conditions, or if you would like to contact Network Associates for ¶
d6a468 any other reason, please call (408) 988-3832, fax (408) 970-9727, or write: ·Ne¶
5d02ae twork Associates, Inc. 3965 Freedom Circle, Santa Clara, California 95054. http¶
dc6ebd ://www.nai.com.
--f6ab 001c79a05e640110220 Page 1 of SETUP.LST
f92122 1;
fb2b76 ..\Data\Data.z
9bce46 2;
c4949a 3;
ce189f 4;
694243 5;
d4ad27 6;
abf7fb 7;
2cbd3c 8;
0ce7e0 9;
492bb7 10;
c9716b 11;
c79e0f 12;
--2946 001fbbf21b740110221 Page 1 of setup.ini
a279c5 [Startup]
0e9b49 AppName=PGP for email and files 5.5.5
6bb690 FreeDiskSpace=181
fbaf5a
--cc52 00028705adb40110222 Page 1 of setup.rul
92aa51 // $Id: setup.rul,v 1.262.10.91.2.2 1998/11/14 00:06:23 heller Exp $
79191f //____________________________________________________________________________
ba53fb //¤ Copyright (C) 1997 Pretty Good Privacy, Inc.
3bec97 //¤ All rights reserved.
aa465d //
53465d //
e3191f //____________________________________________________________________________
7caf5a
f0af5a
b9c83e declare
12af5a
4a5ba9 // Remember to do the following prior to compilation
0f1a29 // SET INSTRC=C:\Progra~1\Instal~1\Instal~1\Dialogs\Include·
37af5a
e9f2fd #include "SDDIALOG.H"¤  ¤   ¤
e0934e //#include "browse.h"
aa67c5 ¤
7b2877 // Constant declarations.
31af5a
e5af5a
e02aeb //***********
55ab59 #ifndef RSA
139e77 ¤   #define RSA ····················1
5b7454 #endif
aeaf5a
fc15f9 #ifndef TITLE
0e35b9 ¤   #define TITLE ··················"PGP Desktop Security Version 6.0.2 DH"
827454 #endif
56af5a
cebd63 #ifndef TITLE2
fd4ab4 //no newline title
26d0c2 ¤   #define TITLE2 ·················"PGP Desktop Security Version 6.0.2 DH"
a27454 #endif
baaf5a
66b841 #ifndef PRODUCT_VERSION
d3f4be ¤   #define PRODUCT_VERSION¤¤   ¤   "Desktop Security, version 6.0.2 DH"
b87454 #endif
62af5a
7522f6 #ifndef ISADMIN
a336e7 ¤   #define ISADMIN ················"FALSE" ·····// TRUE or FALSE or NULL(for P¶
ded892 P)
077454 #endif
f4af5a
796908 #ifndef PGP_FREEWARE
ef08b4 ¤   #define PGP_FREEWARE ···········"FALSE" ····// TRUE or FALSE(now does nothi¶
3de59f ng)
997454 #endif
ccaf5a
d60ca7 #ifndef IS_QUALCOMM_BUILD
444d51 ¤   #define IS_QUALCOMM_BUILD ······"FALSE" ····// TRUE or FALSE
247454 #endif
7caf5a
c69bc0 #ifndef INCLUDEPGPDISKEX
e59329 ¤   #define INCLUDEPGPDISKEX ·······"TRUE" ·····// TRUE or FALSE
3f7454 #endif
0faf5a
a4c1f1 #ifndef INCLUDEINSTALLGUIDE
9d003f ¤   #define INCLUDEINSTALLGUIDE ····"TRUE" ·····// TRUE or FALSE
707454 #endif
82af5a
5fff89 #ifndef ISRSAADDON
361385 ¤   #define ISRSAADDON¤ ¤   ¤   ¤   "FALSE" ·····// TRUE or FALSE
427454 #endif
f3af5a
c6e173 #ifndef INCLUDEPGPFONE
372121 ¤   #define INCLUDEPGPFONE¤ ¤   ¤   "FALSE" ·····// TRUE or FALSE
6c7454 #endif
fcaf5a
bc514e #define SPACE_REQUIRED ·············14000000 ···// Disk space in bytes.
cf894b #define APP_NAME¤   ¤   ¤   ¤   ¤   "PGP 6.0.2"
54af5a
28b4c5 //REGAPP_NAME is need for registry entries
--ca27 0004b72862840110222 Page 2 of setup.rul
e0af5a
ea2aeb //***********
2daf5a
ceaf5a
f80655 #define REGAPP_NAME¤¤   ¤   ¤   ¤   "PGP60"
89b92c #define PROGRAM_FOLDER_NAME¤¤   ¤   "PGP60"
0a7faf #define COMPANY_FOLDER_NAME¤¤   ¤   "Network Associates"
d72362 #define APPBASE_PATH¤   ¤   ¤   ¤   "Program Files\\Network Associates\\PGP60"
927187 #define APPBASE_PATH_WIN32S¤¤   ¤   "Program Files\\Network Associates\\PGP60"
f871ba #define COMPANY_NAME¤   ¤   ¤   ¤   "Network Associates"
b84efb #define PRODUCT_NAME¤   ¤   ¤   ¤   "PGP"
a0ed9c #define DEINSTALL_KEY¤  ¤   ¤   ¤   "PGP60DeinstKey"
153e86 #define UNINSTALL_NAME¤ ¤   ¤   ¤   "PGP 6.0"
b8ba9e #define PRODUCT_KEY¤¤   ¤   ¤   ¤   "PGPKEYS.EXE"
060821 #define MB_OKCANCEL¤¤   ¤   ¤   ¤   1
eeb620 #define IDCANCEL¤   ¤   ¤   ¤   ¤   2
c060cd #define IDRETRY ¤   ¤   ¤   ¤   ¤   4
0e9bf7 #define MB_RETRYCANCEL¤ ¤   ¤   ¤   5
828ced #define IDYES¤  ¤   ¤   ¤   ¤   ¤   6
d7cedd #define WM_SYSCOMMAND¤  ¤   ¤   ¤   0x0112
c87214 #define SC_MINIMIZE¤¤   ¤   ¤   ¤   0xF020
a0ec36 #define SC_MAXIMIZE¤¤   ¤   ¤   ¤   0xF030
579cef #define WM_CLOSE¤   ¤   ¤   ¤   ¤   0x0010 // defines the WM_CLOSE message.
7923e2 #define PGP_HIDDEN_WINDOW¤  ¤   ¤   "PGPtray_Hidden_Window"
ba4cc9 #define ALTBMP¤ ¤   ¤   ¤   ¤   ¤   "sidebar.bmp"
ed7f4a #define ALTBMPB¤¤   ¤   ¤   ¤   ¤   "sidebarx.bmp"
391f65 #define DEBUG¤  ¤   ¤   ¤   ¤   ¤   "FALSE"
00af5a
43af5a
fac175 // Global variable declarations.
05b2ea STRING¤ ¤   szString, szDelimiterSet, svString, RegString, KeyVal;
835f2c STRING¤ ¤   szFileFilter,szDlgTitle,svSelectedFile,svSelectedFileb,szExt,szPath;
7b81f4 STRING¤ ¤   szPubKeyPath,szSecKeyPath,svReturnString,svReturnStringb, svReturnS¶
480325 tringc;
3a73a6 STRING¤ ¤   svFolder,svDir,szMsg,szFileSet,szNonLoggedFileSet,szFileGbit
7a958e STRING¤ ¤   svTarget,szProgram,szParam,szTemp,szAppPath,szCool,szShortPath;
daa503 STRING¤ ¤   szQuestion,szLicenseFile,szLocalDB,szSubDirs,szName,szCompany;
bdbcbf STRING¤ ¤   szSerial,szEudoraPath[200],szEudoraFile,svResult,svEudoraVersion;
270be5 STRING¤ ¤   szComponents,nvPubRing,nvPrvRing,szOldPGPPath,szKeyPath;
a4b099 STRING¤ ¤   szTitle,svUninstLogFile,szFormat,szBmpPath,szBMP,PathToExe;
c66d36 STRING¤ ¤   szVerBuffer[1536],szResultBuffer,szData,szData2,EudoraBackup;
6f59df STRING¤ ¤   szFileName,szMessage,LatestVer,UseDefaultPubKey,strUpdate, svCopyKe¶
3131ca ys;
8b6af6 STRING¤ ¤   UpdateNeeded,szBmpName,EudoraPluginPath,svPubLoc,svPrivLoc, UpdateP¶
5e9689 lug;
43fc11 STRING¤ ¤   WhichPlugin, WhichEudoraPath, szOEdir, szKey, svValue, svValueb, sv¶
e77d40 Valuec;
71ddb3 STRING¤ ¤   szVersionInfo1, szVersionInfo2, szDisplay, svOS;
9e756a STRING¤ ¤   szPubRingPath[512];
10e00e STRING¤ ¤   szPrivRingPath[512];
f2ce48 STRING¤ ¤   szRandSeedPath[512], szLongTarget;
dc0713 STRING ¤¤   szUser, szUserCompany, szUserSerial;
156d27 STRING¤ ¤   szKeyb, szKeyc, szOEPATH, svVersionNumber;
1f30a4 STRING¤ ¤   szEudKey, szEudKeyb, szEudKeyc, svEudValue, svEudValueb, svEudValue¶
241779 c;
78f237 STRING¤ ¤   svSubStr, DrvLetUpper, KeyStub, szValue, svInstallDir, svOldDisk, I¶
e2445d NCLUDEPGPDISK;
4ff6b9 STRING ·····szPREV_VERSION, szINSTALLED_VERSION, szAlt_Key;
b3807f STRING ·····szVER_PGPKEYS, szVER_PGPTOOLS, szVER_PGPTRAY, szVER_PGP_SDK, szVER_¶
42b72b PGPSDKNL, szVER_PGPSDKUI, szVER_PGPDISK;
cfec4b STRING ·····szPREV_PGP_PATH, szPREV_PGPDISK_PATH, szOUTLOOK_EXP_PATH, szEUDORA_¶
c21019 PATH;
2126ca STRING ·····szSRCDIR, szTARGETDIR;
92af5a
66956b BOOL¤   ¤   bSpaceOk,bWinNT,bWin32s,bIsShellExplorer,bvOpt1,bvOpt2;
51f63c BOOL¤   ¤   bFoundEudora,bPrvKeysFound,bPubKeysFound,Copy;
e6f4e1 BOOL¤   ¤   bVerValue,bVerInfo,KeyOnDiskOne;
ca5d3b BOOL¤   ¤   bFoundOutlook, RenameOriginal, bCheckVersion;
388559 BOOL¤   ¤   IS_NT, bEasyInstall;
cbaf5a
01eb12 NUMBER¤ ¤   nResult,nvResult,nvSize,Index, nerr;
4b2650 NUMBER¤ ¤   nvPathLen,nSize,nHandle,nMsg, nwParam, nlParam;
--c2ef 0009c5051ea40110222 Page 3 of setup.rul
37fb0a NUMBER¤ ¤   nvType,nID_BITMAP,nDx,nDy,nCorner, LockedFiles;
981839 NUMBER¤ ¤   nCompareFlag, nDisplay, nvOS, nReboot;
ef3289 NUMBER¤ ¤   nDrvLetUpper, DriveNum, IndexNumber, nType, AsciNum;
4f1ec3 NUMBER¤ ¤   nvProgramFiles, nvEudoraPlugin, nvExchangeOutlookPlugin, nvUninstal¶
ce5dbe l;
8ddfa8 NUMBER¤ ¤   nvUserManual, nvPGPdisk, nvReturnValue, nvOutlookExpressPlugin;
4b54f8 NUMBER ·····nFND_PGP_INSTALLED, nFND_PGPDISK, nDETECT_RUNNING_APPS;
8aaf5a
050d62 //These are all assigned values at the begining of the install
45fcd3 NUMBER¤ ¤   PROGRAM_FILES_SIZE, EUDORA_PLUGIN_SIZE, EXCHANGE_OUTLOOK_PLUGIN_SIZ¶
01c29b E;
38e5fe NUMBER¤ ¤   OUTLOOK_EXPRESS_PLUGIN_SIZE, MANUAL_SIZE, CLIENT_INSTALL_SIZE;
0ec8a0 NUMBER¤ ¤   PGPDISK_SIZE, PGPFONE_SIZE;
0aaf5a
6d50cc HWND¤   ¤   hWnd;
ca71aa HWND¤   ¤   hwndIS3;
367b8a HWND¤   ¤   hWnd1,hWnd2,hWnd3,hWnd4,hWnd5,hWnd6,hWnd7,hWnd8,hWnd9;
c2af5a
13e5e0 LIST ···¤   listData, listID;
afaf5a
fcb022 LONG ¤  ¤   lSize,lData;
10af5a
5db661 POINTER ¤   ptr1,ptr2;
02af5a
1f1bde typedef¤¤   MYTYPE_PSZ
c40f89 begin
7ac7c6 STRING szString[24];
922b3d end;
54af5a
7eaf5a
4fb38e //Function prototypes
0af0be prototype¤  DeleteSharedFile
8e8eab ¤   ¤   ¤   (STRING,STRING);
f3af5a
69692a prototype¤  SetupScreen
e5c6f0 ¤   ¤   ¤   ();
6aaf5a
f8d2c3 prototype¤  CheckRequirements
3ec6f0 ¤   ¤   ¤   ();
8caf5a
b7b12c prototype¤  LONG VERSION.GetFileVersionInfoSizeA
6c0c47 ¤   ¤   ¤   (STRING,BYREF LONG);
1faf5a
1159ae prototype¤  BOOL VERSION.GetFileVersionInfoA
c703c8 ¤   ¤   ¤   (STRING,LONG,LONG,BYREF STRING);
26af5a
e60d96 prototype¤  BOOL VERSION.VerQueryValueA
3a6c0c ¤   ¤   ¤   (BYREF STRING,STRING,BYREF POINTER,BYREF NUMBER);
beaf5a
673472 prototype¤  INT PGP60cl.PGPclPreferences
09003e ¤   ¤   ¤   (POINTER,HWND,INT, POINTER);
eaaf5a
6a200e prototype¤  INT PGP60cl.PGPclSetUserInfo
1ab21c ¤   ¤   ¤   (STRING,STRING,STRING);
95af5a
f1364f prototype¤  INT PGP60cl.PGPclGetSDKFilePaths
1061d1 ¤   ¤   ¤   (STRING, INT, STRING, INT, STRING, INT);
e3af5a
b3bfa5 prototype¤  INT PGP60cl.PGPclSetSDKFilePaths
cf6015 ¤   ¤   ¤   (STRING, STRING, STRING, INT);
73af5a
1ebdfa prototype¤  INT install.PGPclStartMemLockDriver ();
caaf5a
fca13c prototype ··IsValidVersion ();
5aaf5a
478503 prototype ··Uninstall5X
d3ace4 ¤   ¤   ¤   (STRING, STRING, STRING, STRING);
b3af5a
7c9c35 prototype ··Uninstall6X ();
12af5a
fa8c17 prototype ··CleanSharedFile
9c3da4 ¤   ¤   ¤   (STRING, STRING);
--516a 0003ab8339240110222 Page 4 of setup.rul
e0af5a
df61dd prototype¤  BOOL install.MyGetOpenFileName32(HWND, STRING, STRING, STRING, STRI¶
988379 NG);
baaf5a
65123c prototype¤  BOOL install.MyBrowseForFolder32(HWND, STRING); ·
dcaf5a
f79a19 prototype ··Uninstall_PGPdisk10 ();
03af5a
3aaf5a
3daee9 // Prototype user-defined function to call MyGetOpenFileName.
3331e1 prototype FileBrowse(HWND, STRING, BYREF STRING, STRING, STRING);
15af5a
6eaf5a
aab668 // Function declarations for PGPdisk·
eebaf8 prototype¤  BOOL PGPdskIH.IsVolumeAPGPdisk (INT);
e039f6 prototype¤  PGPdskIH.KillPGPdiskResident ();
6f04f6 prototype¤  PGPdskIH.PGPdiskCleanup ();
9ee414 prototype¤  BOOL PGPdskIH.LoadPGPdiskDriver ();
4a6c39 prototype¤  BOOL PGPdskIH.AreAnyPGPdisksMounted ();
385ede prototype¤  BOOL PGPdskIH.UnmountAllPGPdisks ();
f8af5a
5baf5a
770086 //Declarations for Qualcomm code snippets
4794b6 prototype¤  BOOL USER.PostWindowMessageA( HWND, NUMBER, NUMBER, NUMBER) ; // WI¶
1681f1 N API functions
2012c7 prototype¤  NUMBER USER.RegisterWindowMessageA( BYREF STRING) ;¤¤   ¤   ··// WI¶
2081f1 N API functions
e5af5a
2faf5a
dfed22 NUMBER ·WM_MAHAVISHNU;
4ed8ad STRING ·lpMahaVishnu;·
ebaf5a
67af5a
36c30c program
2baf5a
50635d StartHere:
dcb545 ¤   GetSystemInfo(COLORS,nvResult,svResult);
9ffbd8 ¤   szFormat ·= ";1;1;0,128,128;0,128,128";
afaf5a
63da08 ¤   if (nvResult < 257) then
1ef34c ¤   ¤   //Logo in upper_right hand corner of screen
d6d2f4 ¤   ¤   PlaceBitmap (SUPPORTDIR ^ "neta.bmp", 0, 0, 0, UPPER_RIGHT);
e71616 ¤   ¤   szBmpPath = "@" + SUPPORTDIR ^ ALTBMP + szFormat;
150e24 ¤   else
edf34c ¤   ¤   //Logo in upper_right hand corner of screen
422c33 ¤   ¤   PlaceBitmap (SUPPORTDIR ^ "netax.bmp", 0, 0, 0, UPPER_RIGHT);
69e75c ¤   ¤   szBmpPath = "@" + SUPPORTDIR ^ ALTBMPB + szFormat;
1deb6d ¤   endif;
93af5a
c64329 ¤   //Set the alternate bitmap for the AskText dialog box.
0c9b6d ··¤ DialogSetInfo
812761 ¤   (DLG_INFO_ALTIMAGE,szBmpPath,TRUE);
29af5a
a64461 ¤   // Set installation info.,which is required for registry entries.
e000d4 ¤   InstallationInfo
897b33 ¤   (COMPANY_NAME,PRODUCT_NAME,PRODUCT_VERSION,PRODUCT_KEY);
1baf5a
aa3e3f ¤   // Set up the installation screen.
58b948 ¤   SetupScreen
fce540 ¤   ();
92af5a
8b5432 ¤   Enable
c5336a ¤   (DIALOGCACHE);
fbaf5a
3f9102 ····// Create a Welcome dialog.
311bd0 ····WelcomeDlg:
bfaf5a
0ad51d ¤   ····Disable
674ae0 ¤   ····(BACKBUTTON);
08bc02 ¤   ····if (bEasyInstall = FALSE) then
089abe ¤   ¤   ····Welcome
3a8556 ¤   ¤   ····(APP_NAME + " Installation Program",0);
--940d 0001b30dd2240110222 Page 5 of setup.rul
916f45 ¤   ····endif;
37af5a
31d01a ¤   ····Enable
b64ae0 ¤   ····(BACKBUTTON);
11af5a
7f8a59 ¤   ····// Test target system for proper configuration.
edee59 ¤   ····CheckRequirements
96ac2e ¤   ····();
fcaf5a
a91daf ····// Display the License Agreement ····
26f23c ····DispAgree:
0d26da ¤   ····VarSave (SRCTARGETDIR);
9034a6 ¤   ····TARGETDIR ·= SUPPORTDIR;
5175c9 ¤   ····CopyFile ("License.txt", "License.txt");
5d8638 ¤   ····VarRestore (SRCTARGETDIR);
5caf5a
516bb5 ¤   ····szTitle = APP_NAME + " Software License Agreement";
5a7c27 ¤   ····szMsg = "Please read the following license agreement. Use " +
fac394 ¤   ¤   ¤   ····"the scroll bar to view\nthe rest of this agreement.";
3ed3b7 ¤   ····szQuestion = "Do you accept all the terms of the preceding license " +
ae3102 ¤   ¤   ¤   ¤   ·····"agreement? ·If so,\npress the Yes push button. " +
c9ecd1 ¤   ¤   ¤   ¤   ·····"If you select No, Setup will close.";
62af5a
d76d49 ···¤ ···szLicenseFile = SUPPORTDIR ^ "LICENSE.TXT";
49af5a
d3c62d ¤   ····if (SdLicense(szTitle,szMsg,szQuestion,szLicenseFile) = BACK) then
9aaf5a
ee4ccd ¤   ¤   ····goto WelcomeDlg;
4baf5a
c46f45 ¤   ····endif;
adaf5a
152134 ····Detect_PGPdisk:
b62fe9 ········SdShowMsg ("Searching for running applications.", TRUE);
a6af5a
f260c1 ········//Ensure that PGPdisk is not running
4a781d ········if (INCLUDEPGPDISK = "TRUE") then
c72d0d ¤   ········if (FindWindow ("", "PGPdisk") != NULL) then
2df6ee ¤   ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s",
6a8268 ¤   ¤   ¤   ········"Please shut down PGPdisk before continuing.") = IDCANCEL) ¶
a62830 then
d2cde4 ¤   ¤   ¤   ········exit;
78ea41 ¤   ¤   ········else
f3fbb7 ¤   ¤   ¤   ········MessageBox ("PGPdisk must not be running to install this pr¶
85f77b oduct.", WARNING);
b351aa ¤   ¤   ········endif;
c56a43 ¤   ········endif;
b888e0 ········endif;
cdaf5a
fcfa07 ········//kill pgptray.exe if possible
3eca3a ········hWnd = FindWindow(PGP_HIDDEN_WINDOW,"");
29bdf5 ········if (hWnd > 0) then
ae2751 ············SetDialogTitle (DLG_ASK_YESNO, "Found PGPtray Running");
2d0e50 ¤   ········if (AskYesNo("Setup has found PGPtray running. ·The install process¶
8f71c0 ·cannot continue unless it is shutdown.\n\n" +
47f2f8 ¤   ¤   ¤   ¤   ·········"Would you like setup to shutdown PGPtray?",YES) = YES¶
b58fea ) then
d9af5a
4822a5 ¤   ¤   ········SendMessage(hWnd,WM_CLOSE,0,0);
2aaf5a
43b9cf ¤   ¤   ········//This delay is needed for PGP Dlls to unlock unfortunately
04adc9 ¤   ¤   ········Delay(8);
e5abca ¤   ········else
07e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
a5a046 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL);
6e51aa ¤   ¤   ········endif;
39af5a
95de96 ¤   ¤   ········MessageBox ("PGPtray must not be running to install this produc¶
a95c85 t.", WARNING);
390a51 ¤   ¤   ········exit;
7f6a43 ¤   ········endif;
8c88e0 ········endif;
1ba985 ········Delay(1);
--659b 0004050ed2e40110222 Page 6 of setup.rul
e0af5a
8ff5e4 ····TestForRunningApps:
51d8aa ········//ENSURE NO PLUGINS\DLL's ARE IN USE
76c1ad ········if (IS_QUALCOMM_BUILD = "FALSE") then
20095b ¤   ········hWnd2 = FindWindow("Microsoft Exchange 4.0 Viewer","");
3d5952 ¤   ········if (hWnd2 != NULL) then
57a9d7 ¤   ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","Fo¶
cd80a0 r Setup to continue Microsoft Exchange must not be" +
d37528 ¤   ¤   ········" running.\nPlease shut down Microsoft Exchange.")= IDCANCEL) t¶
f610d3 hen
258da6 ¤   ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
373d9c ¤   ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL);
5bb34b ¤   ¤   ¤   ········endif;
40cde4 ¤   ¤   ¤   ········exit;
9fea41 ¤   ¤   ········else
f4f817 ¤   ¤   ¤   ········goto TestForRunningApps;
3551aa ¤   ¤   ········endif;
d16a43 ¤   ········endif;
b888e0 ········endif;
cfaf5a
f7bd8f ········//No exchange or outlook ·in Qualcomm build so these apps. can be runni¶
049251 ng
65c1ad ········if (IS_QUALCOMM_BUILD = "FALSE") then
1f66b6 ¤   ········hWnd3 = FindWindow("Microsoft Exchange 5.0 Viewer","");
f9d742 ¤   ········if (hWnd3 != NULL) then
6fa9d7 ¤   ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","Fo¶
e080a0 r Setup to continue Microsoft Exchange must not be" +
f311d4 ¤   ¤   ········" running.\nPlease shut down Microsoft Exchange.") = IDCANCEL) ¶
bd2830 then
df8da6 ¤   ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
57f2cb ¤   ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
06b34b ¤   ¤   ¤   ········endif;
12cde4 ¤   ¤   ¤   ········exit;
e5ea41 ¤   ¤   ········else
00f817 ¤   ¤   ¤   ········goto TestForRunningApps;
7f51aa ¤   ¤   ········endif;
7d6a43 ¤   ········endif;
58af5a
76ad8d ········hWnd4 = FindWindow("rctrl_renwnd32","");
9c1c26 ········if (hWnd4!= NULL) then
4fc49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
877a2f tup to continue Microsoft Outlook must not be" +
a08caa ¤   ········" running.\nPlease shut down Microsoft Outlook.") = IDCANCEL) then
11e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
178b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
0c51aa ¤   ¤   ········endif;
ea0a51 ¤   ¤   ········exit;
c3abca ¤   ········else
91feaf ¤   ¤   ········goto TestForRunningApps;
f46a43 ¤   ········endif;
6d88e0 ········endif;
23af5a
6788e0 ········endif;
9daf5a
b1af5a
464f28 ········hWnd5 = FindWindow("EudoraMainWindow","");
2a60ed ········if (hWnd5 != NULL) then
0ec49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
d684c7 tup to continue Eudora must not be running.\n"+
074de3 ¤   ········"Please shut down Eudora.") = IDCANCEL) then
b9e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
9f8b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
6f51aa ¤   ¤   ········endif;
6a0a51 ¤   ¤   ········exit;
08abca ¤   ········else
f3feaf ¤   ¤   ········goto TestForRunningApps;
ad6a43 ¤   ········endif;
1988e0 ········endif;
79af5a
cb4af0 ········hWnd6 = FindWindow("PGPAdminWizardClass","");
77facc ········if (hWnd6 != NULL) then
40c49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
--e740 0003362a15740110222 Page 7 of setup.rul
f7625a tup to continue the admin wizard must not be" +
5be7ff ¤   ········" running.\nPlease shut down the admin. wizard.") = IDCANCEL) then
86e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
7c8b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
1651aa ¤   ¤   ········endif;
0c0a51 ¤   ¤   ········exit;
a5abca ¤   ········else
b1feaf ¤   ¤   ········goto TestForRunningApps;
8d6a43 ¤   ········endif;
ca88e0 ········endif;
e6af5a
bfc090 ········hWnd7 = FindWindow("PGPkeysMainWinClass","");
a574dc ········if (hWnd7 != NULL) then
3ec49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
12ce79 tup to continue PGPkeys must not be running.\n"+
36f262 ¤   ········"Please shut down PGPkeys.") = IDCANCEL) then
82e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
3e8b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
6d51aa ¤   ¤   ········endif;
880a51 ¤   ¤   ········exit;
d9abca ¤   ········else
f4feaf ¤   ¤   ········goto TestForRunningApps;
5a6a43 ¤   ········endif;
7a88e0 ········endif;
a8af5a
9ab038 ········hWnd8 = FindWindow("PGPtools","");
43965b ········if (hWnd8 != NULL) then
86c49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
6bb608 tup to continue PGPtools must not be running.\n"+
6e1b8e ¤   ········"Please shut down PGPtools.") = IDCANCEL) then
2de295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
d38b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
e951aa ¤   ¤   ········endif;
cf0a51 ¤   ¤   ········exit;
444cb1 ¤   ········else·
5bfeaf ¤   ¤   ········goto TestForRunningApps;
ba6a43 ¤   ········endif;
7e88e0 ········endif;
86af5a
2b9b99 ········hWnd9 = FindWindow("PGPlog","");
a2184b ········if (hWnd9 != NULL) then
cdc49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
960abf tup to continue PGPLog must not be running.\n"+
d9f156 ¤   ········"Please shut down PGPLog.") = IDCANCEL) then
b9e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
9f8b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
fa51aa ¤   ¤   ········endif;
b90a51 ¤   ¤   ········exit;
64abca ¤   ········else
c3feaf ¤   ¤   ········goto TestForRunningApps;
9c6a43 ¤   ········endif;
fc88e0 ········endif;
b6af5a
cebfc1 ········//Ensure that Outlook Express is not running
a220cb ········if (FindWindow ("ThorBrowserWndClass", "") != NULL) then
78c49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
8d9771 tup to continue Outlook Express must not be running.\n"+
d46809 ¤   ········"Please shut down Outlook Express.") = IDCANCEL) then
64e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
008b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
9b51aa ¤   ¤   ········endif;
350a51 ¤   ¤   ········exit;
b5abca ¤   ········else
7dfeaf ¤   ¤   ········goto TestForRunningApps;
d96a43 ¤   ········endif;
4888e0 ········endif;
7baf5a
be8abe ········if (FindWindow ("Ath_Note", "") != NULL) then
adc49a ¤   ········if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For Se¶
d49771 tup to continue Outlook Express must not be running.\n"+
a56809 ¤   ········"Please shut down Outlook Express.") = IDCANCEL) then
33e295 ¤   ¤   ········if (IS_QUALCOMM_BUILD = "TRUE") then
--ac19 0007e0a21f940110222 Page 8 of setup.rul
a28b81 ¤   ¤   ¤   ········PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
ba51aa ¤   ¤   ········endif;
680a51 ¤   ¤   ········exit;
29abca ¤   ········else
31feaf ¤   ¤   ········goto TestForRunningApps;
8e6a43 ¤   ········endif;
7a88e0 ········endif;
75af5a
8531ab ····//Pause to give things a chance to unload
208fa4 ····Delay (2);
e2af5a
f38007 ····SdShowMsg ("Searching for running applications.", FALSE);
2eaf5a
9eaf5a
e1e206 ····SdShowMsg ("Searching for previous installations. ·Please wait...", TRUE);
1aaf5a
648fa4 ····Delay (2);
a2af5a
2ba193 ····// Store the original values away for later
7f5696 ····szSRCDIR ···= SRCDIR;
e96143 ····szTARGETDIR = TARGETDIR;
24af5a
a54b78 ····nFND_PGPDISK = FALSE;
75af5a
afa23f ····// Retrieve previous install path and determine components installed
43c618 ····RegDBSetDefaultRoot (HKEY_CURRENT_USER);
0caf5a
f32c16 ····/**************************************************************************¶
ca860e ****************
746657 ·····*
07f3cd ·····* ·DO NOT DETECT AND UNINSTALL PGP 5.0 BECAUSE IT CAN CO-EXIST WITH PGP 6.X
846657 ·····*
a6780d ·····**************************************************************************¶
5777b4 *****************/
aaaf5a
42b6d4 ····if (RegDBKeyExist ("SOFTWARE\\PGP\\PGP55\\PGPkeys") >= 0) then
d7293d ········szKey ····= "SOFTWARE\\PGP\\PGP55\\PGPkeys";
890a0b ········szAlt_Key = "SOFTWARE\\PGP\\PGP55";
63d7c7 ····elseif (RegDBKeyExist ("SOFTWARE\\Network Associates\\PGP55\\PGPkeys") >= 0¶
c68fea ) then
465b31 ········szKey ····= "SOFTWARE\\Network Associates\\PGP55\\PGPkeys";
68f771 ········szAlt_Key = "SOFTWARE\\Network Associates\\PGP55";
587063 ····elseif (RegDBKeyExist ("SOFTWARE\\Network Associates\\PGP60\\PGPkeys") >= 0¶
a28fea ) then
f2cb16 ········szKey ····= "SOFTWARE\\Network Associates\\PGP60\\PGPkeys";
2284ea ········szAlt_Key = "SOFTWARE\\Network Associates\\PGP60";
a50eff ····endif;
e7af5a
4b3178 ····szINSTALLED_VERSION = "";
4daf5a
084742 ····szName = "Version";
d663bf ····nType ·= REGDB_STRING;
1c36ef ····if (RegDBGetKeyValueEx (szAlt_Key, szName, nType, szINSTALLED_VERSION, nvSi¶
8393d2 ze) < 0) then
9c1ec7 ········// Attempt to retrieve the previous product's name again
016747 ········// This should only happen for PGP 6.x.x
8f7295 ········if (RegDBKeyExist ("SOFTWARE\\Network Associates\\PGP60") >= 0) then
7be278 ············szAlt_Key = "SOFTWARE\\Network Associates\\PGPdisk";
8b23ec ············RegDBGetKeyValueEx (szAlt_Key, szName, nType, szINSTALLED_VERSION, ¶
34ebb9 nvSize);
bd88e0 ········endif;
a10eff ····endif;
0eaf5a
87b12a ····if (RegDBKeyExist (szKey) >= 0) then
64403c ········szName = "ExePath";
f3a728 ········nType ·= REGDB_STRING;
8faf5a
8b0117 ········if (RegDBGetKeyValueEx (szKey, szName, nType, szValue, nvSize) >= 0) th¶
c66cef en
5baec7 ············RegDBSetDefaultRoot (HKEY_CLASSES_ROOT);
73508e ········
7e54fe ············// Retrieve just the path
--7861 000109bb50340110222 Page 9 of setup.rul
9a8e08 ············ParsePath (szPREV_PGP_PATH, szValue, PATH);
0e88e0 ········endif;
3f0eff ····endif;
83af5a
edc37f ····// Find either the executable, the registered extension, or registered file¶
157109 ·type
9bd78f ····if ( (FindFile (szPREV_PGP_PATH, "PGPdisk.exe", svResult) >= 0) ||
c85736 ·········(RegDBKeyExist (".PGD") >= 0) ||
d63043 ·········(RegDBKeyExist ("PGPdisk Volume") >= 0) ) then
1caf5a
176696 ········nFND_PGPDISK = TRUE;
ca9358 ········if ( (VerGetFileVersion (szPREV_PGP_PATH ^ "PGPdisk.exe", szVER_PGPDISK¶
3844fc ) = FILE_NOT_FOUND) ||
6839fe ·············(VerGetFileVersion (szPREV_PGP_PATH ^ "PGPdisk.exe", szVER_PGPDISK¶
745b53 ) = FILE_NO_VERSION) ) then
b2af5a
02040f ············szVER_PGPDISK = "";
ce88e0 ········endif;
cd0eff ····endif;
79af5a
f08bc5 ····// Attempt to find PGPdisk.exe again if the above steps failed
fbeb53 ····if (nFND_PGPDISK = FALSE) then
6f61ea ········RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
f6af5a
36bed8 ········szKey ·= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\PGPd¶
6e7143 isk.exe";
2fdb28 ········szName = "";
c5a728 ········nType ·= REGDB_STRING;
8a0117 ········if (RegDBGetKeyValueEx (szKey, szName, nType, szValue, nvSize) >= 0) th¶
e06cef en
3d54fe ············// Retrieve just the path
1a8e08 ············ParsePath (szPREV_PGP_PATH, szValue, PATH);
62c3bd ············if (FindFile (szPREV_PGP_PATH, "PGPdisk.exe", svResult) >= 0) then
938f4f ················nFND_PGPDISK = TRUE;
333d8c ················if ( (VerGetFileVersion (szPREV_PGP_PATH ^ "PGPdisk.exe", szVER¶
086d63 _PGPDISK) = FILE_NOT_FOUND) ||
c41a68 ·····················(VerGetFileVersion (szPREV_PGP_PATH ^ "PGPdisk.exe", szVER¶
40798a _PGPDISK) = FILE_NO_VERSION) ) then
90af5a
b4299f ····················szVER_PGPDISK = "";
521797 ················endif;
f2238d ············endif;
db88e0 ········endif;
bc0eff ····endif;
d9af5a
05af5a
312c16 ····/**************************************************************************¶
cf03a9 ************
ef6657 ·····*
eb9bbf ·····* ·Attempt to find PGPdisk 1.0's installed path
9d6657 ·····*
00780d ·····**************************************************************************¶
2eca19 ************/
04af5a
3b0d09 ····// Check for and retrieve PGPdisk v1.0's path
e9b0fb ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
fbaf5a
3d4141 ····szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\PGPdisk.e¶
44f3b3 xe";
4ab12a ····if (RegDBKeyExist (szKey) >= 0) then
99db28 ········szName = "";
64a728 ········nType ·= REGDB_STRING;
ec6ddd ········RegDBGetKeyValueEx (szKey, szName, nType, szValue, nvSize);
08af5a
50b7ed ········// Retrieve just the path
d02417 ········ParsePath (szPREV_PGPDISK_PATH, szValue, PATH);
7c842c ····else
b7376d ········RegDBSetDefaultRoot (HKEY_CLASSES_ROOT);
c2af5a
5d0254 ········szKey ··= ".PDG\\ShellNew";
c9cec4 ········szName ·= "Command";
1006a8 ········nType ··= REGDB_STRING;
--27a4 000b3c2f91840110222 Page 10 of setup.rul
d36ddd ········RegDBGetKeyValueEx (szKey, szName, nType, szValue, nvSize);
95af5a
176f75 ········// Extract just the path from: ·C:\PROGRA~1\NETWOR~1\PGPDISK\PGPDISK.EX¶
8f1cab E create "%2"
2d5188 ········StrSub (szPREV_PGPDISK_PATH, szValue, 0, 28);
0c0eff ····endif;
ddaf5a
94968c ····if (FindFile (szPREV_PGPDISK_PATH, "PGPdisk.exe", svResult) >= 0) then
f46696 ········nFND_PGPDISK = TRUE;
dd043c ········VerGetFileVersion (szPREV_PGPDISK_PATH ^ "PGPdisk.exe", szVER_PGPDISK);
de0eff ····endif;
86af5a
b7af5a
4c2c16 ····/**************************************************************************¶
a803a9 ************
fe6657 ·····*
92345d ·····* ·Detect previous installs and offer the user the option of cancelling th¶
e7805f is install
51dc8a ·····* ·or having this install uninstall it.
1e6657 ·····*
be780d ·····**************************************************************************¶
08ca19 ************/
7baf5a
f9209e ····nFND_PGP_INSTALLED = FALSE;
26af5a
65f849 ····// Find PGPKeys, PGPTools, and PGPTray
d8b50f ····if (FindFile (szPREV_PGP_PATH, "PGPKeys.exe", svResult) >= 0) then
c7812c ········VerGetFileVersion (szPREV_PGP_PATH ^ "PGPKeys.exe", szVER_PGPKEYS);
51af5a
d0499a ········if (FindFile (szPREV_PGP_PATH, "PGPTools.exe", svResult) >= 0) then
efc8c5 ············VerGetFileVersion (szPREV_PGP_PATH ^ "PGPTools.exe", szVER_PGPTOOLS¶
0e6275 );
7baf5a
0b332b ············if (FindFile (szPREV_PGP_PATH, "PGPTray.exe", svResult) >= 0) then
b006a9 ················VerGetFileVersion (szPREV_PGP_PATH ^ "PGPTray.exe", szVER_PGPTR¶
6b8466 AY);
6a508e ········
3390a6 ················// Also find PGP_SDK.DLL, PGPsdkNL.dll, and PGPsdkUI.dll
544909 ················if (FindFile (WINSYSDIR, "PGP_SDK.dll", svResult) >= 0) then
b3bc41 ····················VerGetFileVersion (WINSYSDIR ^ "PGP_SDK.dll", szVER_PGP_SDK¶
2b6275 );
cbaf5a
797467 ····················if (FindFile (WINSYSDIR, "PGPsdkNL.dll", svResult) >= 0) th¶
556cef en
ca2415 ························VerGetFileVersion (WINSYSDIR ^ "PGPsdkNL.dll", szVER_PG¶
146946 PSDKNL);
64af5a
6a1346 ························if (FindFile (WINSYSDIR, "PGPsdkUI.dll", svResult) >= 0¶
7f8fea ) then
d7258a ····························VerGetFileVersion (WINSYSDIR ^ "PGPsdkUI.dll", szVE¶
b82564 R_PGPSDKUI);
687f98 ····························nFND_PGP_INSTALLED = TRUE;
7529c0 ························endif;
e3ed57 ····················endif;
d51797 ················endif;
afaf5a
5d238d ············endif;
ca88e0 ········endif;
b40eff ····endif;
4baf5a
d7f386 ····// Find DLL's for PGP 5.5.x install (5.5.4.0 does not exist, just checking ¶
eba79e for the heck of it)
7ce3fe ····if ( (szVER_PGPKEYS % "5.5.0.0") && (szVER_PGPTRAY % "5.5.0.0") ·||
c855f5 ·········(szVER_PGPKEYS % "5.5.1.0") && (szVER_PGPTRAY % "5.5.1.0") ·||
848af4 ·········(szVER_PGPKEYS % "5.5.2.0") && (szVER_PGPTRAY % "5.5.2.0") ·||
123804 ·········(szVER_PGPKEYS % "5.5.3.0") && (szVER_PGPTRAY % "5.5.3.0") ·||
3b3ce7 ·········(szVER_PGPKEYS % "5.5.4.0") && (szVER_PGPTRAY % "5.5.4.0") ·||
ce4d71 ·········(szVER_PGPKEYS % "5.5.5.0") && (szVER_PGPTRAY % "5.5.5.0") ) then
f8508e ········
c823c5 ········if (FindFile (WINSYSDIR, "PGPSDK.dll", svResult) >= 0) then
a482cc ············VerGetFileVersion (WINSYSDIR ^ "PGPSDK.dll", szVER_PGP_SDK);
b3af5a
--8455 00038e5135c40110222 Page 11 of setup.rul
2d9e26 ················nFND_PGP_INSTALLED = TRUE;
44af5a
d6960b ················// Set this value so that the check below will work
10a3d9 ················szVER_PGPSDKNL = szVER_PGP_SDK;
615316 ················szVER_PGPSDKUI = szVER_PGP_SDK;
91af5a
fd88e0 ········endif;
390eff ····endif;
73af5a
f9af5a
a5fea2 ····SdShowMsg ("Searching for previous installations. ·Please wait...", FALSE);
ceaf5a
05f855 ····// Call function to manually uninstall PGPdisk 1.0
66e36c ····if ( (nFND_PGPDISK = TRUE) && (szVER_PGPDISK < "6.0.0.0") ) then
a6a8a5 ········SetDialogTitle (DLG_ASK_YESNO, "Found PGPdisk Installed");
7a66b5 ········if (szVER_PGPDISK = "") then
2b590f ············szQuestion = "Setup has found PGPdisk installed on your computer. ·"
c11457 ·······················+ "It must first be unintalled before Setup can continue¶
33192b . ·PGPdisk volumes will "
cd9c51 ·······················+ "not be uninstalled.\n\n"
977405 ·······················+ "Would you like Setup to uninstall the previous versio¶
857581 n?\n\n"
c4819f ·······················+ "NOTE: ·If you select NO, Setup will exit.\n\n";
1b1e5b ········else
96f8c1 ············szQuestion = "Setup has found PGPdisk " + szVER_PGPDISK + " install¶
2656ea ed on your computer. ·"
821457 ·······················+ "It must first be unintalled before Setup can continue¶
c9192b . ·PGPdisk volumes will "
219c51 ·······················+ "not be uninstalled.\n\n"
497405 ·······················+ "Would you like Setup to uninstall the previous versio¶
8d7581 n?\n\n"
7d819f ·······················+ "NOTE: ·If you select NO, Setup will exit.\n\n";
9a88e0 ········endif;
3aaf5a
064c84 ········if (AskYesNo (szQuestion, YES) = YES) then
9e4c35 ············Uninstall_PGPdisk10 ();
941e5b ········else
8b097a ············abort;
1e88e0 ········endif;
260eff ····endif;
74af5a
a5e383 ····if (nFND_PGP_INSTALLED = TRUE) then
0d61ea ········RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
1daf5a
20e4b1 ········SetDialogTitle (DLG_ASK_YESNO, "Previous Install Found");
7d9bf9 ········if ( ((szVER_PGPKEYS = "6.0.2.0") && (szVER_PGPTOOLS = "6.0.2.0") && (s¶
2bcfdf zVER_PGPTRAY = "6.0.2.0"))
59bc67 ············&&
40d1f4 ·············((szVER_PGP_SDK = "1.5.2.0") && (szVER_PGPSDKNL = "1.5.2.0") && (s¶
7147c0 zVER_PGPSDKUI = "1.5.2.0")) ) then
71af5a
3eba6a ············if (szINSTALLED_VERSION != "") then
0f9d77 ················szQuestion = "Setup has found PGP "
6fac7e ···························+ szINSTALLED_VERSION
99a67c ···························+ " installed on your computer. ·It is recommended t¶
d4517f hat you allow Setup to uninstall "
873f35 ···························+ "it before continuing. ·Any existing keyrings will¶
3ad188 ·be preserved.\n\n"
24f3ab ···························+ "Would you like Setup to uninstall the previous ve¶
9c6aef rsion?\n\n";
fde93c ············else
053c71 ················szQuestion = "Setup has found PGP installed on your computer. ·¶
ff4b29 It is recommended that you allow Setup "
4e7110 ···························+ "to uninstall it before continuing. ·Any existing ¶
ca2b01 keyrings will be preserved.\n\n"
b3f3ab ···························+ "Would you like Setup to uninstall the previous ve¶
c66aef rsion?\n\n";
2d238d ············endif;
1b1e5b ········else
1eba6a ············if (szINSTALLED_VERSION != "") then
179d77 ················szQuestion = "Setup has found PGP "
38ac7e ···························+ szINSTALLED_VERSION
--8afd 0003c81a26940110222 Page 12 of setup.rul
dc725b ···························+ ", installed on your computer. ·It must first be u¶
af0793 nintalled before "
17a070 ···························+ "Setup can continue. ·Any existing keyrings will b¶
1d90d6 e preserved.\n\n"
38f3ab ···························+ "Would you like Setup to uninstall the previous ve¶
6781f9 rsion?\n\n"
34c5cc ···························+ "NOTE: ·If you select NO, Setup will exit.\n\n";
32e93c ············else
ea3c71 ················szQuestion = "Setup has found PGP installed on your computer. ·¶
183618 It must first be unintalled before "
b9a070 ···························+ "Setup can continue. ·Any existing keyrings will b¶
3290d6 e preserved.\n\n"
75f3ab ···························+ "Would you like Setup to uninstall the previous ve¶
f481f9 rsion?\n\n"
dfc5cc ···························+ "NOTE: ·If you select NO, Setup will exit.\n\n";
7a238d ············endif;
3988e0 ········endif;
ea508e ········
c84c84 ········if (AskYesNo (szQuestion, YES) = YES) then
83c2cc ············//kill pgptray.exe if possible
c65390 ············hWnd = FindWindow(PGP_HIDDEN_WINDOW,"");
0e7962 ············if (hWnd > 0) then
482c9a ¤   ············if (AskYesNo("Setup has found PGPtray running. ·The install pro¶
fe147c cess cannot "
9ed1ee ····························+ "continue unless it is shutdown.\n\n"
f3fd34 ····························+ "Would you like setup to shutdown PGPtray?",YES) ¶
703fc2 = YES) then
dee798 ¤   ¤   ············SdShowMsg ("Setup is shutting down PGPtray. ·Please wait...¶
c0e930 ", TRUE);
81f36a ····················
1d2488 ····················SendMessage(hWnd,WM_CLOSE,0,0);
413ee3 ¤   ¤   ············
e5f8e4 ····················//This delay is needed for PGP Dlls to unlock unfortunately
fb6f77 ¤   ¤   ············Delay(3);
58f36a ····················
b10235 ····················SdShowMsg ("Setup is shutting down PGPtray. ·Please wait...¶
6daa1c ", FALSE);
91a8b7 ¤   ············else
d17b9c ¤   ¤   ············if (IS_QUALCOMM_BUILD = "TRUE") then
6260f7 ¤   ¤   ¤   ············PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL);
58fa85 ¤   ¤   ············endif;
55af5a
aa6208 ¤   ¤   ············MessageBox ("PGPtray must not be running to install this pr¶
ce16aa oduct.", INFORMATION);
8e5f1f ¤   ¤   ············exit;
fa1864 ¤   ············endif;
1d238d ············endif;
80af5a
ca6b23 ············RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
87af5a
d6e378 ············// Retrieve Outlook Express and Eudora's installed path
e67d1f ············szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths";
80a57a ············nType = REGDB_STRING;
cdea78 ············if (RegDBGetKeyValueEx (szKey ^ "MSIMN.EXE", "Path", nType, szOUTLO¶
aaf312 OK_EXP_PATH, nvSize) < 0) then
eafc69 ················szOUTLOOK_EXP_PATH = "";
b7238d ············endif;
1501db ············if (RegDBGetKeyValueEx (szKey ^ "EUDORA.EXE", "Path", nType, szEUDO¶
b58b1d RA_PATH, nvSize) < 0) then
83cedf ················szEUDORA_PATH = "";
bd238d ············endif;
c4af5a
28eaeb ············// Determine which uninstall function to call
c88a33 ············// ONLY FORCE AN UNINSTALL IF THE VERSION IS GREATER THAN OR LESS T¶
100e2a HAN 6.0.2
c6ef1a ············if ( ((szVER_PGPKEYS < "6.0.2.0") && (szVER_PGPTOOLS < "6.0.2.0") &¶
148d67 & (szVER_PGPTRAY < "6.0.2.0"))
d4170a ················&&
31f07b ·················((szVER_PGP_SDK < "1.5.2.0") && (szVER_PGPSDKNL < "1.5.2.0") &¶
5d229a & (szVER_PGPSDKUI < "1.5.2.0")) ) then
b0af5a
3cf601 ················if (szVER_PGPKEYS > "5.5.5.0") then
--ddb5 000e61d8a3540110222 Page 13 of setup.rul
11582a ····················Uninstall6X ();
0827c8 ················else
ff7035 ····················Uninstall5X ("PGP55DeinstKey", szOUTLOOK_EXP_PATH , szPREV_¶
ddec65 PGP_PATH, szEUDORA_PATH);
cb1797 ················endif;
38af5a
8a090e ················// LaunchAppAndWait (szPREV_PGP_PATH ^ "UNINSTALL.EXE", "", WAI¶
0ac58f T);
453ccf ············elseif ( ((szVER_PGPKEYS = "6.0.2.0") && (szVER_PGPTOOLS = "6.0.2.0¶
8209c8 ") && (szVER_PGPTRAY = "6.0.2.0"))
72170a ················&&
293311 ·················((szVER_PGP_SDK = "1.5.2.0") && (szVER_PGPSDKNL = "1.5.2.0") &¶
1f15f6 & (szVER_PGPSDKUI = "1.5.2.0")) ) then
26af5a
0f34a5 ················if (RegDBKeyExist ("SOFTWARE\\Microsoft\\Windows\\CurrentVersio¶
8312b5 n\\Uninstall\\PGP60DeinstKey") >= 0) then
b17b04 ····················szName = "PGP60DeinstKey";
9427c8 ················else
d589c8 ····················szName = DEINSTALL_KEY;
001797 ················endif;
a8af5a
681fd6 ················Uninstall6X ();
0833f9 ············elseif ( ((szVER_PGPKEYS > "6.0.2.0") && (szVER_PGPTOOLS > "6.0.2.0¶
d38af6 ") && (szVER_PGPTRAY > "6.0.2.0"))
17170a ················&&
e37ebe ·················((szVER_PGP_SDK > "1.5.2.0") && (szVER_PGPSDKNL > "1.5.2.0") &¶
5e4c42 & (szVER_PGPSDKUI > "1.5.2.0")) ) then
b3af5a
668091 ·················SetDialogTitle (DLG_MSG_SEVERE, "Unable to Uninstall Previous ¶
091400 Version");
cd05d8 ·················szMessage = "Setup is unable to uninstall your previous instal¶
7c839e lation and will exit. ·Please uninstall "
77167d ···························+ "it by clicking on the Uninstall icon in its progr¶
5d154a am group or by selecting it from "
b6e76e ···························+ "Add/Remove Programs in the Control Panel.";
fb7574 ·················MessageBox (szMessage, SEVERE);
545886 ·················
39d96f ·················abort;
05238d ············endif;
40af5a
b4af5a
2a4cb5 ············/*************************************************
082fbc ············THIS WILL NOT WORK BECAUSE SRCDIR DOES NOT INITIALIZE TO WHERE THE ¶
afbde4 SELF EXTRACTING PROGRAM RESIDES
e2af5a
78af5a
68886a ············szKey ··= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
30871f ············szName ·= "PGP Setup";
5df5d0 ············szValue = SRCDIR ^ "Setup.exe";
964154 ············nType ··= REGDB_STRING;
8858c1 ············RegDBSetKeyValueEx(szKey, szName, nType, szValue, -1);
9faf5a
6a44bc ············szTitle ··= "Uninstall Complete";
f38ce0 ············szMessage = "Setup has completed uninstalling PGP"
a8c2d6 ······················+ szINSTALLED_VERSION
f44247 ······················+ ". ·It is recommended that you allow Setup to reboot yo¶
a1fe2d ur machine. ·"
2ef0e6 ······················+ "The installation will automatically continue when Wind¶
2e8a11 ows completes starting up.\n\n"
d819a9 ······················+ "WARNING: ·Please save all your work and close all appl¶
56906b ication(s) prior to rebooting the machine. ·"
eca34c ······················+ "CTRL + TAB to switch between your application(s).";
dc784b ············RebootDialog (szTitle, szMessage, SYS_BOOTMACHINE);
6f2141 ············*************************************************/
b31e5b ········else
a42c70 ············if ( ((szVER_PGPKEYS = "6.0.2.0") && (szVER_PGPTOOLS = "6.0.2.0") &¶
a7f38d & (szVER_PGPTRAY = "6.0.2.0"))
0b170a ················&&
8f3311 ·················((szVER_PGP_SDK = "1.5.2.0") && (szVER_PGPSDKNL = "1.5.2.0") &¶
7d15f6 & (szVER_PGPSDKUI = "1.5.2.0")) ) then
50af5a
e61136 ················// Do nothing if it is the same version and the user elects to ¶
--c15c 0007e49871c40110222 Page 14 of setup.rul
d8c9ca continue without uninstalling
66e93c ············else
7d3d60 ················abort;
d9238d ············endif;
e988e0 ········endif;
a2a127 ····endif; ·// if (nFND_PGP_INSTALLED = TRUE) then
4aaf5a
83af5a
a42c16 ····/**************************************************************************¶
04db0c ********
00780d ·····**************************************************************************¶
4adb0c ********
73780d ·····**************************************************************************¶
63db0c ********
9c6657 ·····*
6b6657 ·····*
267029 ·····* ·Allowing Setup to run UNINSTALL.EXE may not work because the uninstall ¶
44f1ac itself
47d388 ·····* ·is an install script and not a true uninstallation.
716657 ·····*
066657 ·····*
b4780d ·····**************************************************************************¶
5ddb0c ********
81780d ·····**************************************************************************¶
0edb0c ********
bf780d ·····**************************************************************************¶
ad3866 ********/
e5af5a
49af5a
31918c ····// Restore the original values
e9243a ····SRCDIR ···= szSRCDIR;
723948 ····TARGETDIR = szTARGETDIR;
1eaf5a
b2af5a
8c21e1 ¤   if (ISRSAADDON = "TRUE") then
2e4bd9 ¤   ¤   //GET THE PGP 6.0 INSTALLATION DIRECTORY
6b0089 ¤   ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
3fa468 ¤   ¤   szKey = "Software\\Network Associates\\PGP60\\PGPKeys";
56b5b4 ¤   ¤   szName = "ExePath";
5daf5a
2cd2e5 ¤   ¤   if (RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize) <0) then
6721b1 ¤   ¤   ¤   MessageBox ("Cannot proceed, This installation requires that you ha¶
31e43b ve\n" ·+
7cc661 ¤   ¤   ¤   ¤   ¤   ¤   "a valid install of PGP 6.0 already installed.\n", INFO¶
949fdd RMATION);
be17e9 ¤   ¤   ¤   exit;
5b8ad7 ¤   ¤   endif;
47af5a
fd43d3 ¤   ¤   //find out if they are running freeware
45f3eb ¤   ¤   UseDLL("Version.dll");
570230 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
20e51c ¤   ¤   lSize ····= GetFileVersionInfoSizeA
a18572 ¤   ¤   ¤   ¤   ¤   (svValue,nHandle);
f3af5a
c3d578 ¤   ¤   bVerInfo ·= GetFileVersionInfoA
54f2ca ¤   ¤   ¤   ¤   ¤   (svValue,nHandle,lSize,szVerBuffer);
41af5a
68180d ¤   ¤   ptr1 ·····= AddressString
0df8a7 ¤   ¤   ¤   ¤   ¤   (szResultBuffer);
c7c9cc ¤   ¤   ptr2 ·····= AddressNumber
0056b8 ¤   ¤   ¤   ¤   ¤   (ptr1);
c2af5a
720031 ¤   ¤   bVerValue = VerQueryValueA
a3c26d ¤   ¤   ¤   ¤   ¤   (szVerBuffer,"\\StringFileInfo\\040904b0\\ProductName"
e3ac59 ¤   ¤   ¤   ¤   ¤   ,ptr2,nSize);
821b52 ¤   ¤
4e5800 ¤   ¤   if (bVerValue = 0) then
2c7c3f ············SetDialogTitle (DLG_ASK_YESNO, "Unqualified Product Found");
4a2cb0 ¤   ¤   ¤   if (AskYesNo("This product cannot be installed over PGP Freeware.\n¶
726c41 \n" +
5924a3 ¤   ¤   ¤   ¤   ¤   ¤   "Are you running PGP Freeware?",YES) = YES) then
7e2d73 ¤   ¤   ¤   ¤   exit;
--d93d 000b58fcc3440110222 Page 15 of setup.rul
3f6874 ¤   ¤   ¤   endif;
092aa8 ¤   ¤   endif;¤ ¤   ¤
3067c5 ¤
54eeec ¤   ¤   // pszResultBuffer is a pointer to a pointer which is the starting
c6a724 ¤   ¤   // point for the product name. How do you actually get the string?
bcc2bb ¤   ¤   StructGetP(ptr2,"MYTYPE_PSZ","szString",lData,szData);
aa8719 ¤   ¤   UnUseDLL("Version.dll");
04af5a
cf61c5 ¤   ¤   //Check if the user has FreeWare installed, if yes, do not proceed
a86a0e ¤   ¤   if (szData = "PGP Freeware") then
554d79 ¤   ¤   ¤   MessageBox ("Cannot proceed, PGP Freeware detected\n\n" +
b04fbb ¤   ¤   ¤   ¤   ¤   ¤   "This installation requires that you have a valid insta¶
01539c ll\n" ·+
aa4375 ¤   ¤   ¤   ¤   ¤   ¤   "of PGP 6.0 Desktop Security or PGP 6.0 Personal Privac¶
423c34 y\n" +
eaa555 ¤   ¤   ¤   ¤   ¤   ¤   "installed.\n", INFORMATION);
0417e9 ¤   ¤   ¤   exit;
0b87c7 ¤   ¤   ¤
608ad7 ¤   ¤   endif;
19eb6d ¤   endif;
b7af5a
9bc81c ¤   //these are the defines that show how big each module is
0b5754 ····//
9487cc ····//THESE NUMBERS ARE NOT BASED ON 1MB=1024000
cf5754 ····//
2a02e7 ¤   PROGRAM_FILES_SIZE¤ ¤   ¤   ¤   = 6945000;
489d7d ¤   EUDORA_PLUGIN_SIZE¤ ¤   ¤   ¤   = 150000;
6272ea ¤   EXCHANGE_OUTLOOK_PLUGIN_SIZE¤   = 150000;
f83e99 ¤   OUTLOOK_EXPRESS_PLUGIN_SIZE¤¤   = 175000;
54a5ee ¤   MANUAL_SIZE¤¤   ¤   ¤   ¤   ¤   = 1500000;
c9e03a ¤   CLIENT_INSTALL_SIZE¤¤   ¤   ¤   = 7100000;
24e52d ¤   PGPDISK_SIZE¤   ¤   ¤   ¤   ¤   = 2420000;
4e5b3e ¤   if (INCLUDEPGPFONE = "TRUE") then
f107aa ········PGPFONE_SIZE¤   ¤   ¤   ····= 2420000;
14842c ····else
58e6e4 ········PGPFONE_SIZE ···············= 0;
7e0eff ····endif;
6daf5a
2aaf5a
d0768c ¤   if (INCLUDEPGPDISKEX = "TRUE") then
112f10 ¤   ¤   INCLUDEPGPDISK = "TRUE";
5f0e24 ¤   else
8a626b ¤   ¤   INCLUDEPGPDISK = "FALSE";
1feb6d ¤   endif;
cfaf5a
e3c479 ¤   UpdateNeeded = "FALSE";
b2dc37 ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
078fe7 ¤   ¤   lpMahaVishnu = "mahavishnu";·
28ca76 ¤   UseDLL("User.dll");
adc507 ¤   ¤   if (( WM_MAHAVISHNU = RegisterWindowMessageA( lpMahaVishnu)) = 0) then
a18df6 ¤   ¤   ¤   // RegisterWindowMessage failed.......
5f0eab ¤   ¤   endif ;
3acdbf ¤   UnUseDLL("User.dll");
699244 ¤   ¤   // define custom exit handler
c21fe0 ¤   ¤   Handler ( EXIT, Exit_Handler) ;
fdeb6d ¤   endif;
dcaf5a
ceaf65 ¤   //Because of the memlock driver, the user must have Administrator privileges
133a72 ¤   GetSystemInfo(OS, nvOS, svOS);
cabe70 ¤   switch (nvOS)
74af5a
b95af8 ¤   case IS_WINDOWSNT:
deaf5a
2fae0c ¤   ¤   IS_NT = TRUE;
4faf5a
0c7092 ¤   ¤   if (Is (USER_ADMINISTRATOR, "") != TRUE) then
d7b270 ¤   ¤   ¤   SetDialogTitle (DLG_ASK_YESNO,"Administrator Privileges Required");
9995b6 ¤   ¤   ¤   if (AskYesNo ("To run this install you need to be logged in with\n"¶
b86e86 ·+
9c3610 ¤   ¤   ¤   ¤   "Administrator privileges. If you choose to\n" +
87cbee ¤   ¤   ¤   ¤   "continue without these privileges the secure\n" +
b57d27 ¤   ¤   ¤   ¤   "memory driver will not be enabled and you will not be\n" +
--11d4 00011568cce40110222 Page 16 of setup.rul
86218d ¤   ¤   ¤   ¤   "able to install PGPdisk.\n\n" +
34d374 ¤   ¤   ¤   ¤   "Continue ?" ,NO) = NO) then
d0db09 ¤   ¤   ¤   ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
a83071 ¤   ¤   ¤   ¤   ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
62539d ¤   ¤   ¤   ¤   endif;
672d73 ¤   ¤   ¤   ¤   exit;
8abb8c ¤   ¤   ¤   else
58b1f6 ¤   ¤   ¤   ¤   INCLUDEPGPDISK = "FALSE";
516874 ¤   ¤   ¤   endif;
438ad7 ¤   ¤   endif;
82af5a
55080d ¤   case IS_WINDOWS95:
5caf5a
c7a611 ¤   ¤   IS_NT = FALSE;¤ ¤
caaf5a
aedb51 ¤   endswitch;
a5af5a
e412b5 ¤   if (ISADMIN = "FALSE") then
d726fd ¤   ¤   szPath = SRCDIR;
c737b8 ¤   ¤   szFileName = "PGP_Admin.prf";
4fe4c5 ¤   ¤   if (FindFile (szPath, szFileName, svResult) < 0 ) then
a7d745 ¤   ¤   ¤   MessageBox ("This installation has not been configured by your" ·+
0e5f5e ¤   ¤   ¤   ¤   ¤   ¤   " Administrator.\n Please contact your Administrator" +
cafc64 ¤   ¤   ¤   ¤   ¤   ¤   " for more information.", INFORMATION);
a08812 ¤   ¤   ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
3826c7 ¤   ¤   ¤   ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
356874 ¤   ¤   ¤   endif;
c517e9 ¤   ¤   ¤   exit;
c68ad7 ¤   ¤   endif;
96af5a
22c377 ¤   ¤   szFileName = "pubring.pkr";
2db154 ¤   ¤   if (FindFile (szPath, szFileName, svResult) = 0 ) then
71aec7 ¤   ¤   ¤   KeyOnDiskOne = TRUE;
ea8ad7 ¤   ¤   endif;
daeb6d ¤   endif;
c8af5a
496fc0 ¤   //Find out if this is a "quick, no user input install
f25e96 ¤   if (ISADMIN = "TRUE") then
a85d4a ¤   ¤   bEasyInstall = FALSE;
750e24 ¤   else
494ad0 ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "EasyInstall", nvReturnVal¶
91a661 ue);
a51b52 ¤   ¤
71555f ¤   ¤   if (nvReturnValue = 1) then
cfccc9 ¤   ¤   ¤   bEasyInstall = TRUE;
e166b9 ¤   ¤   ¤   //this is a quick install so we need to get all the values
a000b0 ¤   ¤   ¤   GetProfString (SRCDIR ^ "setup.ini", "Startup", "InstallDir", svIns¶
1add37 tallDir);
e6af5a
8cc2d5 ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "ProgramFiles", nvProg¶
ab892a ramFiles);
1073a8 ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "EudoraPlugin", nvEudo¶
ae0a1e raPlugin);
22b0de ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "ExchangeOutlookPlugin¶
9bfeaa ", nvExchangeOutlookPlugin);
0d4a23 ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "OutlookExpressPlugin"¶
68a677 , nvOutlookExpressPlugin);
a547b3 ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "UserManual", nvUserMa¶
f73570 nual);
3fc42e ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "PGPdisk", nvPGPdisk);
4498b9 ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "UninstallOld", nvUnin¶
e7452f stall);
bbaf5a
4571ff ¤   ¤   ¤   if (INCLUDEPGPDISK = "TRUE") then
ce2b14 ¤   ¤   ¤   ¤   GetProfInt (SRCDIR ^ "setup.ini", "Startup", "PGPdisk", nvPGPdi¶
b933bb sk);
656874 ¤   ¤   ¤   endif;
da0e1d ¤   ¤   else
126a42 ¤   ¤   ¤   bEasyInstall = FALSE;
c78ad7 ¤   ¤   endif;
57eb6d ¤   endif;
11af5a
--1af6 000df05fd1640110222 Page 17 of setup.rul
72fee1 //check if there is a previous install on the machine
43af5a
79fcb3 //GET THE PGP 5.5 INSTALLATION DIRECTORY
ec3945 SdShowMsg ("Searching for installed components. ·Please wait...", TRUE);
0daf5a
0c98db // Delay (2);
88af5a
834ec8 nerr = RegDBSetDefaultRoot(HKEY_CURRENT_USER);
4deb27 szKey ····= "Software\\Network Associates\\PGP55\\PGPKeys";
95bdac szEudKey ·= "Software\\Network Associates\\PGP55\\EudoraPlugin";
86af5a
9aa3d6 szKeyb ···= "Software\\PGP\\PGP55\\PGPKeys";
81ce5f szEudKeyb = "Software\\PGP\\PGP55\\EudoraPlugin";
91af5a
3fe2b5 // szKeyc ···= "Software\\PGP\\PGP\\PGPKeys";
3a8bc1 // szEudKeyc = "Software\\PGP\\PGP\\EudoraPlugin";
63af5a
473925 szName = "ExePath";
751cb3 svValue ·= "";
7d86e1 svValueb = "";
ca075e svValuec = "";
d17518 svReturnString ·= "";
a60621 svReturnStringb¤= "";
066ef5 svReturnStringc = "";
9f8ee6 SdShowMsg ("Searching for installed components. ·Please wait...", FALSE);
30af5a
53bb5a if ((RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize) ··=0) ||
d98e63 ¤   (RegDBGetKeyValueEx (szKeyb, szName, nvType, svValueb, nvSize) =0)) then
0caf5a
85d9bb ¤   // (RegDBGetKeyValueEx (szKeyc, szName, nvType, svValuec, nvSize) =0)) then
13af5a
252e1c ¤   ¤   ¤   //Get the existing Eudora plugin paths
adf74e ¤   ¤   ¤   szName = "PluginPath";
c01172 ¤   ¤   ¤   RegDBGetKeyValueEx (szEudKey, szName, nvType, svEudValue, nvSize);
c2224e ¤   ¤   ¤   RegDBGetKeyValueEx (szEudKeyb, szName, nvType, svEudValueb, nvSize);
d739cc ¤   ¤   ¤   RegDBGetKeyValueEx (szEudKeyc, szName, nvType, svEudValuec, nvSize);
65af5a
f9f1f7 ¤   ¤   ¤   ParsePath(svReturnString, svValue, PATH);
9fe706 ¤   ¤   ¤   ParsePath(svReturnStringb, svValueb, PATH);
5d1477 ¤   ¤   ¤   ParsePath(svReturnStringc, svValuec, PATH);
46af5a
9a430d ¤   ¤   ¤   //copy over pref files
d79db5 ¤   ¤   ¤   VarSave (SRCTARGETDIR);
cd0b62 ¤   ¤   ¤   TARGETDIR ·= WINDIR;
d0fa90 ¤   ¤   ¤   SRCDIR ····= WINDIR;
f62af4 ¤   ¤   ¤   CopyFile ("PGPadmin.prf", "PGP_Admin.prf");
8c95a7 ¤   ¤   ¤   DeleteFile ("PGPadmin.prf");
191774 ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
972b85 ¤   ¤   ¤   ¤
538751 ¤   ¤   ¤   if ((FindFile (svReturnStringb, "PGPclient.prf", svResult) = 0) ||
8081ac ¤   ¤   ¤   ¤   (FindFile (svReturnStringb, "PGPadmin.prf", svResult) ·= 0)) th¶
e76cef en
6358e0 ¤   ¤   ¤   ¤   VarSave (SRCTARGETDIR);
23b908 ¤   ¤   ¤   ¤   SRCDIR ····= svReturnStringb;
ce360a ¤   ¤   ¤   ¤   TARGETDIR ·= WINDIR;
fb364f ¤   ¤   ¤   ¤   CopyFile ("PGPadmin", "PGP_Admin.prf");
ae0eeb ¤   ¤   ¤   ¤   CopyFile ("PGPclient", "PGP_Client.prf");
accacf ¤   ¤   ¤   ¤   TARGETDIR ·= svReturnStringb;
281013 ¤   ¤   ¤   ¤   //DeleteFile ("PGPclient.prf");
2ca228 ¤   ¤   ¤   ¤   //DeleteFile ("PGPadmin.prf");
f81938 ¤   ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
9a6874 ¤   ¤   ¤   endif;
1daf5a
56c903 ¤   ¤   ¤   if ((FindFile (svReturnString, "PGPclient.prf", svResult) = 0) ||
f1238d ¤   ¤   ¤   ¤   (FindFile (svReturnString, "PGPadmin.prf", svResult) = 0)) then
0058e0 ¤   ¤   ¤   ¤   VarSave (SRCTARGETDIR);
bec793 ¤   ¤   ¤   ¤   SRCDIR ····= svReturnString;
69360a ¤   ¤   ¤   ¤   TARGETDIR ·= WINDIR;
5e364f ¤   ¤   ¤   ¤   CopyFile ("PGPadmin", "PGP_Admin.prf");
aa0eeb ¤   ¤   ¤   ¤   CopyFile ("PGPclient", "PGP_Client.prf");
e887e3 ¤   ¤   ¤   ¤   TARGETDIR ·= svReturnString;
df1013 ¤   ¤   ¤   ¤   //DeleteFile ("PGPclient.prf");
--8bea 00082647ec840110222 Page 18 of setup.rul
d4a228 ¤   ¤   ¤   ¤   //DeleteFile ("PGPadmin.prf");
fd1938 ¤   ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
7d6874 ¤   ¤   ¤   endif;
88af5a
cc00b3 ¤   ¤   ¤   //Outlook Express install location
9e4cbf ¤   ¤   ¤   szKey = "Software\\Network Associates\\PGP55\\OE";
f50334 ¤   ¤   ¤   szName = "OutlookExpress";
2299e4 ¤   ¤   ¤   RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
1f6eb6 ¤   ¤   ¤   szOEPATH = svValue;¤
b111c9 ¤   ¤   ¤   ¤   ·
bde3d0 ¤   ¤   ¤   //Ask if they want to uninstall
859db5 ¤   ¤   ¤   VarSave (SRCTARGETDIR);
4cee24 ¤   ¤   ¤   if (bEasyInstall = FALSE) then
f7a61a ¤   ¤   ¤   ¤   SetDialogTitle (DLG_ASK_YESNO,"Previous Install Found");
43653d ················szMessage = "Setup has found a previous version of PGP on your ¶
3798b3 machine. Would you "
0b3b4f ··························+ "like Setup to uninstall it before installing " + T¶
2f847b ITLE + "? ··(Recommended)"
89f32d ··························+ "\n\nNOTE: ·If you select NO, Setup will exit.\n\n";
5d475f ¤   ¤   ¤   ¤   if (AskYesNo(szMessage, YES) = YES) then
c08aed ¤   ¤   ¤   ¤   ¤   if (svReturnString != "") then
d9db52 ¤   ¤   ¤   ¤   ¤   ¤   Uninstall5X
eed50f ¤   ¤   ¤   ¤   ¤   ¤   ("PGP555DeinstKey", szOEPATH, svReturnString, svEudValu¶
0895c6 e);
2db17c ¤   ¤   ¤   ¤   ¤   endif;
a379fe ¤   ¤   ¤   ¤   ¤   if (svReturnStringb != "") then
dfdb52 ¤   ¤   ¤   ¤   ¤   ¤   Uninstall5X
71f105 ¤   ¤   ¤   ¤   ¤   ¤   ("PGP55DeinstKey", "", svReturnStringb, svEudValueb);
65b17c ¤   ¤   ¤   ¤   ¤   endif;
e1b904 ¤   ¤   ¤   ¤   ¤   // if (svReturnStringc != "") then
6d8ecc ¤   ¤   ¤   ¤   ¤   // ···Uninstall5X
fa0113 ¤   ¤   ¤   ¤   ¤   // ···("PGP50DeinstKey", "", svReturnStringc, svEudValuec);
a4a3d1 ¤   ¤   ¤   ¤   ¤   // endif;
56fa07 ¤   ¤   ¤   ¤   else
00a9fa ····················// Exit because all installs starting with 6.0.2 requires t¶
f6e301 he previous product
ca5a81 ····················// to be uninstalled
99c7a0 ····················abort;
971797 ················endif;
e5bb8c ¤   ¤   ¤   else
393a19 ¤   ¤   ¤   ¤   if (nvUninstall = 1) then
ac8aed ¤   ¤   ¤   ¤   ¤   if (svReturnString != "") then
57db52 ¤   ¤   ¤   ¤   ¤   ¤   Uninstall5X
add50f ¤   ¤   ¤   ¤   ¤   ¤   ("PGP555DeinstKey", szOEPATH, svReturnString, svEudValu¶
2295c6 e);
61b17c ¤   ¤   ¤   ¤   ¤   endif;
8379fe ¤   ¤   ¤   ¤   ¤   if (svReturnStringb != "") then
91db52 ¤   ¤   ¤   ¤   ¤   ¤   Uninstall5X
0af105 ¤   ¤   ¤   ¤   ¤   ¤   ("PGP55DeinstKey", "", svReturnStringb, svEudValueb);
4eb17c ¤   ¤   ¤   ¤   ¤   endif;
6ab904 ¤   ¤   ¤   ¤   ¤   // if (svReturnStringc != "") then
f78ecc ¤   ¤   ¤   ¤   ¤   // ···Uninstall5X
400113 ¤   ¤   ¤   ¤   ¤   // ···("PGP50DeinstKey", "", svReturnStringc, svEudValuec);
12a3d1 ¤   ¤   ¤   ¤   ¤   // endif;
5a539d ¤   ¤   ¤   ¤   endif;
48af5a
0b6874 ¤   ¤   ¤   endif;
a21774 ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
a128d5 endif;
2eaf5a
547263 //AT THIS POINT ALL FILES SHOULD BE FREE
39af5a
f43695 //Register the user
49df72 RegUser:
a9af5a
28825a ¤   szTitle ··= "User Information";
a191bb ¤   szMsg ····= "Please Register your product now by " +
bef451 ¤   ¤   ¤   ¤   "typing your name and your company's name below.";
d6af5a
d429c3 ¤   szUserCompany = "";
8baf5a
826760 ¤   GetProfString (SRCDIR + "\\setup.ini", "STARTUP", "CompanyName", szUserComp¶
--2ac3 000201c38e140110222 Page 19 of setup.rul
1882c2 any);
04af5a
1252df ¤   szLocalDB = "\\Software" ^ COMPANY_FOLDER_NAME;
06af5a
e98f64 ¤   //Only ask for user info on Admin build or PP or Free
cb7d47 ¤   if ((ISADMIN != "FALSE") || (PGP_FREEWARE = "TRUE")) then
361c0b ¤   ¤   if (SdRegisterUser (szTitle, szMsg, szUser, szUserCompany)= BACK) then
e56553 ¤   ¤   ¤   goto DispAgree;
718ad7 ¤   ¤   endif;
6267c5 ¤
cb0089 ¤   ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
b0af5a
3909b4 ¤   ¤   RegDBCreateKeyEx
04e8af ¤   ¤   ( szLocalDB ^ REGAPP_NAME,"");
d3af5a
13e93e ¤   ¤   RegDBSetKeyValueEx
077c8b ¤   ¤   (szLocalDB ^ REGAPP_NAME ,"User",REGDB_STRING,szUser,-1);
b1eb6d ¤   endif;
8faf5a
fd18d9 ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
12af5a
330bdf ¤   RegDBSetKeyValueEx
6a8300 ¤   (szLocalDB ^ REGAPP_NAME ,"Company Name",REGDB_STRING,szUserCompany,-1);
53af5a
780bdf ¤   RegDBSetKeyValueEx
d58701 ¤   (szLocalDB ^ REGAPP_NAME ,"Version",REGDB_STRING,PRODUCT_VERSION,-1);
7daf5a
e6af5a
0a997a // Ask user for a destination location for the installation.--
a4fefe GetTargetDirectory:
c7af5a
f298fd ¤   szMsg =
ab27d9 ¤   "Setup will install " +APP_NAME+" in the following directory.\n\nTo " +
a79b63 ¤   "install to this directory, click Next.\n\nTo install to a different " +
ce716c ¤   "directory, click Browse and select another directory.\n\nYou can " +
99b493 ¤   "choose not to install " +APP_NAME+", by clicking Cancel to exit Setup.";
4767c5 ¤
02632e ¤   ¤   if (bWin32s) then
0d4f68 ¤   ¤   ¤   svTarget = TARGETDISK ^ APPBASE_PATH_WIN32S;
cd0e1d ¤   ¤   else
e08e76 ¤   ¤   ¤   svTarget = TARGETDISK ^ APPBASE_PATH;
c18ad7 ¤   ¤   endif;
14af5a
33a19b ¤   if (bEasyInstall = FALSE) then
7bc941 ¤   ¤   if (AskDestPath
d7edfd ¤   ¤   (APP_NAME + " Setup: Choose Destination Directory"
6688c2 ¤   ¤   ,szMsg,svTarget,0) = BACK) then
b3931a ¤   ¤   ¤   if (ISADMIN = "TRUE") then
5cb1e1 ¤   ¤   ¤   ¤   goto RegUser;
45bb8c ¤   ¤   ¤   else
07c80d ¤   ¤   ¤   ¤   goto DispAgree;
c06874 ¤   ¤   ¤   endif;
9e8ad7 ¤   ¤   endif;
efeb6d ¤   endif;
01af5a
4344a6 ¤   if (bEasyInstall = TRUE) then
e6d7fb ¤   ¤   svTarget = svInstallDir;
cbeb6d ¤   endif;
a8af5a
1723b7 ¤   if(svTarget % REGAPP_NAME) then
1fd2e9 ¤   ¤   if (ISADMIN = "TRUE") then
4f5ed6 ¤   ¤   ¤   svTarget ·= ·svTarget;
600e1d ¤   ¤   else
0a5ed6 ¤   ¤   ¤   svTarget ·= ·svTarget;
7b8ad7 ¤   ¤   endif;
7f0e24 ¤   else
ddab42 ¤   ¤   if (ISADMIN != "TRUE") then
972708 ¤   ¤   ¤   svTarget ·= ·svTarget ^ "PGP60";
8d0e1d ¤   ¤   else
762708 ¤   ¤   ¤   svTarget ·= ·svTarget ^ "PGP60";
a38ad7 ¤   ¤   endif;
20eb6d ¤   endif;
--1ccc 0007bcaf81140110222 Page 20 of setup.rul
e0af5a
1aaf5a
28964e ¤   // Perform space check of target drive.
6b8eed ¤   bSpaceOk = TRUE;
2b9625 ¤   if (GetDiskSpace(svTarget) < SPACE_REQUIRED) then
2bab89 ¤   ¤   szMsg = "There is not enough space available on the disk\n" +
10646d ¤   ¤   ¤   ¤   "'" + svTarget + "' \n" +
143f7f ¤   ¤   ¤   ¤   "Please free up some space or change the target location\n" +
0f66f5 ¤   ¤   ¤   ¤   "to a different disk";
6aaf5a
5f9663 ¤   ¤   MessageBox(szMsg,WARNING);
c5ca93 ¤   ¤   bSpaceOk = FALSE;
3eeb6d ¤   endif;
f5af5a
736b49 ¤   ·// If not enough space,ask user to try again.
81e4cc ¤   if (bSpaceOk = FALSE) then·
6dabd5 ¤   ¤   if (bEasyInstall = TRUE) then
78dc5f ¤   ¤   ¤   ¤   MessageBox ("The install directory of this pre-configured insta¶
0e7c88 lln\n" ·+
3a4987 ¤   ¤   ¤   ¤   "has insufficient disk space to complete.\n\nPlease contact you¶
b5f6d0 r Administrator" +
b4b72f ¤   ¤   ¤   ¤   " for more information.", INFORMATION);
b0db09 ¤   ¤   ¤   ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
f33071 ¤   ¤   ¤   ¤   ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
9a539d ¤   ¤   ¤   ¤   endif;
73647d ¤   ¤   ¤   ¤   exit;·
4b0e1d ¤   ¤   else
4486be ¤   ¤   ¤   goto GetTargetDirectory;
dd8ad7 ¤   ¤   endif;
a4eb6d ¤   endif;
6eaf5a
87fa9a PickItems:
81a19b ¤   if (bEasyInstall = FALSE) then
a283ed ¤   ¤   szComponents = APP_NAME;
c31b52 ¤   ¤
c05670 ¤   ¤   ComponentAddItem
6253f1 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)",PROGRAM¶
e5f43b _FILES_SIZE,TRUE);
feaf5a
a05670 ¤   ¤   ComponentAddItem
a3484b ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin",EUDORA_PLUGIN_SIZE,TRUE);
fcaf5a
e69f71 ¤   ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
ca622d ¤   ¤   ¤   ComponentAddItem
ae5862 ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin",EXCHAN¶
4e11a5 GE_OUTLOOK_PLUGIN_SIZE,TRUE);
9d8ad7 ¤   ¤   endif;
edaf5a
179f71 ¤   ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
00622d ¤   ¤   ¤   ComponentAddItem
5ba9ba ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin",OUTLOOK¶
778fa4 _EXPRESS_PLUGIN_SIZE,TRUE);
a28ad7 ¤   ¤   endif;
15af5a
865670 ¤   ¤   ComponentAddItem
514f38 ¤   ¤   (szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)",MANUAL_¶
e856e2 SIZE,TRUE);
56af5a
32d2e9 ¤   ¤   if (ISADMIN = "TRUE") then
7c622d ¤   ¤   ¤   ComponentAddItem
cd9bd5 ¤   ¤   ¤   (szComponents,"Unconfigured " + APP_NAME +" Client Install",CLIENT_¶
49e39d INSTALL_SIZE,TRUE);
d58ad7 ¤   ¤   endif;
93af5a
4267d0 ¤   ¤   if (INCLUDEPGPFONE = "TRUE") then
bd622d ¤   ¤   ¤   ComponentAddItem
fbeba8 ¤   ¤   ¤   (szComponents,"PGPfone (Beta)",PGPFONE_SIZE,TRUE);
468ad7 ¤   ¤   endif;
4eaf5a
87feea ¤   ¤   if (INCLUDEPGPDISKEX = "TRUE") then
dd622d ¤   ¤   ¤   ComponentAddItem
7b0336 ¤   ¤   ¤   (szComponents,"PGPdisk for Windows",PGPDISK_SIZE,TRUE);
--4efb 000c16610bf40110222 Page 21 of setup.rul
0e8ad7 ¤   ¤   endif;
31af5a
080e24 ¤   else
1883ed ¤   ¤   szComponents = APP_NAME;
2eaf5a
5dd287 ¤   ¤   if (nvProgramFiles = 1) then
89622d ¤   ¤   ¤   ComponentAddItem
c9f6c3 ¤   ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)",PRO¶
1839a2 GRAM_FILES_SIZE,TRUE);
2b0e1d ¤   ¤   else
68622d ¤   ¤   ¤   ComponentAddItem
3bf6c3 ¤   ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)",PRO¶
ba1d57 GRAM_FILES_SIZE,FALSE);
4c8ad7 ¤   ¤   endif;
9faf5a
cb03c6 ¤   ¤   if (nvEudoraPlugin = 1) then
c1622d ¤   ¤   ¤   ComponentAddItem
61a56c ¤   ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin",EUDORA_PLUGIN_SIZE,TRUE);
1a0e1d ¤   ¤   else
2e622d ¤   ¤   ¤   ComponentAddItem
ce32b9 ¤   ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin",EUDORA_PLUGIN_SIZE,FALSE);
be8ad7 ¤   ¤   endif;
d5af5a
5de41e ¤   ¤   if (nvExchangeOutlookPlugin = 1) then
4f622d ¤   ¤   ¤   ComponentAddItem
415862 ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin",EXCHAN¶
5f11a5 GE_OUTLOOK_PLUGIN_SIZE,TRUE);
5e0e1d ¤   ¤   else
36622d ¤   ¤   ¤   ComponentAddItem
615862 ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin",EXCHAN¶
ff69c0 GE_OUTLOOK_PLUGIN_SIZE,FALSE);
038ad7 ¤   ¤   endif;
7faf5a
6057be ¤   ¤   if (nvOutlookExpressPlugin = 1) then
58622d ¤   ¤   ¤   ComponentAddItem
20a9ba ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin",OUTLOOK¶
cf8fa4 _EXPRESS_PLUGIN_SIZE,TRUE);
330e1d ¤   ¤   else
aa622d ¤   ¤   ¤   ComponentAddItem
1ea9ba ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin",OUTLOOK¶
b378d7 _EXPRESS_PLUGIN_SIZE,FALSE);
ed8ad7 ¤   ¤   endif;
d9af5a
17bc91 ¤   ¤   if (nvUserManual = 1) then
6b622d ¤   ¤   ¤   ComponentAddItem
ebd8c4 ¤   ¤   ¤   (szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)",MAN¶
30479d UAL_SIZE,TRUE);
170e1d ¤   ¤   else
9a622d ¤   ¤   ¤   ComponentAddItem
86d8c4 ¤   ¤   ¤   (szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)",MAN¶
9cd45d UAL_SIZE,FALSE);
658ad7 ¤   ¤   endif;
64af5a
ab1694 ¤   ¤   if (nvPGPdisk = 1) then
91d97b ¤   ¤   ¤   ¤   ComponentAddItem
354d41 ¤   ¤   ¤   ¤   (szComponents,"PGPdisk for Windows",PGPDISK_SIZE,TRUE);
340e1d ¤   ¤   else
edd97b ¤   ¤   ¤   ¤   ComponentAddItem
ddc8b6 ¤   ¤   ¤   ¤   (szComponents,"PGPdisk for Windows",PGPDISK_SIZE,FALSE);
d88ad7 ¤   ¤   endif;
06eb6d ¤   endif;
2daf5a
a1a19b ¤   if (bEasyInstall = FALSE) then
435354 ¤   ¤   if (SdComponentDialog
55ca44 ¤   ¤   ("Select Components",
7318ed ¤   ¤   ·"Select the components you want to install, clear the " +
63a9f8 ¤   ¤   ·"components you do not want to install.",svTarget,
1c4d31 ¤   ¤   ·szComponents) = BACK) then
1aaf5a
5986be ¤   ¤   ¤   goto GetTargetDirectory;
62af5a
c18ad7 ¤   ¤   endif;
--09aa 000730eb44040110222 Page 22 of setup.rul
e0af5a
66a98e ········/**********************************************************************¶
aa1f67 ****************************************
ac407d ·········*
bb73d5 ·········* ·Do not allow the user to continue unless they select to install the¶
bafab4 ·core PGP components,
f52b37 ·········* ·APP_NAME +" Program Files (Required for PGP 6.x)
d3407d ·········*
609cea ·········**********************************************************************¶
fee577 ****************************************/
84af5a
96fde0 ¤   ¤   if (ComponentIsItemSelected (szComponents, APP_NAME +" Program Files (R¶
8e1669 equired for PGP 6.x)") = FALSE) then
3853a2 ············SetDialogTitle (DLG_ASK_YESNO, "Required Component Not Selected");
a7ab16 ············szMessage = APP_NAME +" Program Files (Required for PGP 6.x) was no¶
c44d3c t selected. ·It is required for the "
f5fa7f ······················+ "product to function properly. ·Would you like Setup to¶
ebcc46 ·automatically select this component?";
120169 ············if (AskYesNo (szMessage, YES) = YES) then
351623 ················ComponentSelectItem (szComponents, APP_NAME +" Program Files (R¶
b94108 equired for PGP 6.x)", TRUE);
e5e93c ············else
10cd11 ················SetDialogTitle (DLG_ASK_YESNO, "Cancel Installation");
50a44e ················szMessage = "You have chosen not install " + APP_NAME +" Progra¶
3779c6 m Files (Required for PGP 6.x). ·"
2f675a ··························+ "Would you like to cancel this installation?";
a38125 ················if (AskYesNo (szMessage, NO) = NO) then
a29657 ····················goto PickItems;
dc27c8 ················else
6fc7a0 ····················abort;
721797 ················endif;
f9238d ············endif;
2f8ad7 ¤   ¤   endif;
b4af5a
f867c5 ¤
865272 ¤   ¤   // Set the App Paths key for the main program.
38472c ¤   ¤   szAppPath = svTarget;
45af5a
e0a8fc ¤   ¤   //Here is where we show the user his/her selections and verify
93a222 ¤   ¤   //things are ok before file copy Store retrieved information in list.
67af5a
e7f5d9 ¤   ¤   // Create the list.
60b44f ¤   ¤   listData = ListCreate (STRINGLIST);
8faf5a
f9d2e9 ¤   ¤   if (ISADMIN = "TRUE") then
0d6e28 ¤   ¤   ¤   ListAddString(listData,"Name:",AFTER);
f37f50 ¤   ¤   ¤   ListAddString(listData," ··········" + szUser,AFTER);
b75daf ¤   ¤   ¤   ListAddString(listData,"Company:",AFTER);
4cd522 ¤   ¤   ¤   ListAddString(listData," ··········" + szUserCompany,AFTER);
a6af5a
5daddf ¤   ¤   ¤   //serial number no longer used
a53826 ¤   ¤   ¤   //ListAddString(listData,"Serial #:",AFTER);
84c9ef ¤   ¤   ¤   //if (PGP_NO_LICENSE_NUMBER = "FALSE") then
63c3c0 ¤   ¤   ¤   //¤ ListAddString(listData," ··········" + szUserSerial,AFTER);
eabaa5 ¤   ¤   ¤   //endif;
298ad7 ¤   ¤   endif;
66af5a
b0ea49 ¤   ¤   ListAddString(listData,APP_NAME +" Components Selected:",AFTER);
0eaf5a
741371 ¤   ¤   if (ComponentIsItemSelected
b79320 ¤   ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") = ¶
e62fe7 TRUE) then
cf5fff ¤   ¤   ¤   ListAddString
263504 ¤   ¤   ¤   (listData," ··········" + APP_NAME +" Program Files (Required for P¶
caad91 GP 6.x) ",AFTER);
268ad7 ¤   ¤   endif;
77af5a
6e1371 ¤   ¤   if (ComponentIsItemSelected
f77009 ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin") = TRUE) then
12af5a
dd5fff ¤   ¤   ¤   ListAddString
73083f ¤   ¤   ¤   (listData," ··········" + APP_NAME +" Eudora Plugin",AFTER);
--b25a 000f924205640110222 Page 23 of setup.rul
e0af5a
fa8ad7 ¤   ¤   endif;
039f71 ¤   ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
b3d624 ¤   ¤   ¤   if (ComponentIsItemSelected
fd38df ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin") = TRU¶
c57d7a E) then
53af5a
69d6ab ¤   ¤   ¤   ¤   ListAddString
30f4e5 ¤   ¤   ¤   ¤   (listData," ··········" +
d1b03f ¤   ¤   ¤   ¤   APP_NAME +" Microsoft Exchange/Outlook Plugin",AFTER);
06af5a
516874 ¤   ¤   ¤   endif;
c98ad7 ¤   ¤   endif;
af9f71 ¤   ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
cbd624 ¤   ¤   ¤   if (ComponentIsItemSelected
de963c ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin") = TRUE¶
2f8fea ) then
dcaf5a
8ed6ab ¤   ¤   ¤   ¤   ListAddString
6ef4e5 ¤   ¤   ¤   ¤   (listData," ··········" +
4c9518 ¤   ¤   ¤   ¤   APP_NAME +" Microsoft Outlook Express Plugin",AFTER);
b4af5a
936874 ¤   ¤   ¤   endif;
a28ad7 ¤   ¤   endif;
d41371 ¤   ¤   if (ComponentIsItemSelected
7a3f3e ¤   ¤   (szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)") = TRUE¶
438fea ) then
cdaf5a
dd4b64 ¤   ¤   ¤   ListAddString(listData," ··········" + APP_NAME +" User's Manual " +
1c323d ¤   ¤   ¤   ¤   ¤   ¤   "(Adobe Acrobat format)",AFTER);
7a8ad7 ¤   ¤   endif;
8caf5a
acaf5a
b41371 ¤   ¤   if (ComponentIsItemSelected
1867e0 ¤   ¤   (szComponents,"Unconfigured " + APP_NAME +" Client Install") = TRUE) th¶
b76cef en
f3af5a
75961d ¤   ¤   ¤   ListAddString(listData," ··········" + "Unconfigured " + APP_NAME +¶
bb1968 " Client" +·
1f32ba ¤   ¤   ¤   ¤   ¤   " Install",AFTER);
358ad7 ¤   ¤   endif;
edaf5a
8167d0 ¤   ¤   if (INCLUDEPGPFONE = "TRUE") then
7dd624 ¤   ¤   ¤   if (ComponentIsItemSelected
83f503 ¤   ¤   ¤   (szComponents,"PGPfone (Beta)") = TRUE) then
19af5a
4f88c9 ¤   ¤   ¤   ¤   ListAddString(listData," ··········" + "PGPfone (Beta)",AFTER);
446874 ¤   ¤   ¤   endif;
038ad7 ¤   ¤   endif;
0267c5 ¤
ee483a ¤   ¤   if (INCLUDEPGPDISK = "TRUE") then
35d624 ¤   ¤   ¤   if (ComponentIsItemSelected
b5f02f ¤   ¤   ¤   (szComponents,¤ "PGPdisk for Windows") = TRUE) then
80af5a
2622cc ¤   ¤   ¤   ¤   ListAddString(listData," ··········" + "PGPdisk for Windows"
0802ac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ,AFTER);
ff6874 ¤   ¤   ¤   endif;
2c8ad7 ¤   ¤   endif;
59eb6d ¤   endif;
e9af5a
ec74d4 ¤   if (INCLUDEPGPDISK = "TRUE") then
0ef2eb ¤   ¤   //Shut Down PGPdisk Resident
381371 ¤   ¤   if (ComponentIsItemSelected
253433 ¤   ¤   (szComponents,¤ "PGPdisk for Windows") = TRUE) then
38a33e ¤   ¤   ¤   UseDLL (SUPPORTDIR ^ "PGPdskIH.dll");
15b864 ¤   ¤   ¤   KillPGPdiskResident();
68af5a
9c1ba4 ¤   ¤   ¤   //svSubStr is the first char. of the full path (so the drive letter)
f7ffa2 ¤   ¤   ¤   //svTarget is the directory where the user has selected to install
0a9b1b ¤   ¤   ¤   StrSub (svSubStr, svTarget, 0, 1);
678c31 ¤   ¤   ¤   //Convert the drive letter to uppercase
f9b814 ¤   ¤   ¤   StrToUpper (DrvLetUpper, svSubStr);
--2e67 0007ec9e75d40110222 Page 24 of setup.rul
de4480 ¤   ¤   ¤   GetByte (nDrvLetUpper, DrvLetUpper, 0);
8867c5 ¤
68e43a ¤   ¤   ¤   DriveNum = nDrvLetUpper - 65;
d51b52 ¤   ¤
6df998 ¤   ¤   ¤   if (IsVolumeAPGPdisk (DriveNum) = TRUE) then
2e87c7 ¤   ¤   ¤
df7211 ¤   ¤   ¤   ¤   //The drive they are installing to is a PGP disk
b44b6a ¤   ¤   ¤   ¤   szMsg = "You cannot install PGPdisk onto a PGPdisk volume. Do y¶
25ef1d ou\n" +
46e9de ¤   ¤   ¤   ¤   ¤   ¤   "want to change the target location to a different disk¶
fd6ac2 .";
c3af5a
4fa2ff ¤   ¤   ¤   ¤   if (AskYesNo(szMsg + "\n\n" +·
89a128 ¤   ¤   ¤   ¤   ¤   "If you do not change the target location PGPdisk will not\¶
5f1dd4 n" +
824cd7 ¤   ¤   ¤   ¤   ¤   " be installed. \n Change target location ?",YES) = YES) th¶
e96cef en
acaf5a
b985eb ¤   ¤   ¤   ¤   ¤   goto GetTargetDirectory;
44af5a
03fa07 ¤   ¤   ¤   ¤   else
232b5b ¤   ¤   ¤   ¤   ¤   ComponentSelectItem
fd0572 ¤   ¤   ¤   ¤   ¤   (szComponents,"PGPdisk for Windows",FALSE);
f7af5a
58539d ¤   ¤   ¤   ¤   endif;
caaf5a
426874 ¤   ¤   ¤   endif;
b8af5a
656251 ¤   ¤   ¤   UnUseDLL (SUPPORTDIR ^ "PGPdskIH.dll");
c58ad7 ¤   ¤   endif;
33eb6d ¤   endif;
8aaf5a
f8c19d ¤   //Check if selections made are valid
549562 ¤   if (((ComponentIsItemSelected
c91ba5 ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin") ·······················=¤ TRU¶
ec0c74 E)¤ ||
04865d ¤   ¤   (ComponentIsItemSelected
6b4059 ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin") ···=¤ TRU¶
1c0c74 E)¤ ||
cb865d ¤   ¤   (ComponentIsItemSelected
aebcb6 ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin") ····=¤ TRU¶
077bc9 E))¤&&
39d78f ·¤  ¤   (ComponentIsItemSelected
d04fc1 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") =¤ FAL¶
5bf622 SE)) then
2b4c2a ¤   ¤   ¤   //Tell user program files are required
907117 ¤   ¤   ¤   SdShowMsg·
fba2dc ¤   ¤   ¤   (APP_NAME +" Program Files are required, please select items again",
49128a ¤   ¤   ¤   ·TRUE);
39fad1 ¤   ¤   ¤   Delay (4);
5e7117 ¤   ¤   ¤   SdShowMsg·
4ba2dc ¤   ¤   ¤   (APP_NAME +" Program Files are required, please select items again",
5cb036 ¤   ¤   ¤   ·FALSE);
bfebea ¤   ¤   ¤   goto PickItems;
8beb6d ¤   endif;
dfaf5a
94a812 ¤   //Check for NULL selections
e858f6 ¤   if ((ComponentIsItemSelected
f5468a ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin") ·······················=¤ FAL¶
492088 SE)¤&&
1f865d ¤   ¤   (ComponentIsItemSelected
ec1d76 ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin") ···=¤ FAL¶
cc2088 SE)¤&&
b8865d ¤   ¤   (ComponentIsItemSelected
54e199 ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin") ····=¤ FAL¶
da2088 SE)¤&&
c9865d ¤   ¤   (ComponentIsItemSelected
d6b7fb ¤   ¤   (szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)") =¤ FAL¶
252088 SE)¤&&
0c865d ¤   ¤   (ComponentIsItemSelected
c558c5 ¤   ¤   (szComponents,"PGPdisk for Windows")¤   ¤   ¤   ¤   ¤   ¤   ¤   ·=¤ FAL¶
7e2088 SE)¤&&
--cae3 000c881afa740110222 Page 25 of setup.rul
83865d ¤   ¤   (ComponentIsItemSelected
abe02d ¤   ¤   (szComponents,"PGPfone (Beta)")¤¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·=¤ FAL¶
b72088 SE)¤&&
4b865d ¤   ¤   (ComponentIsItemSelected
71ae23 ¤   ¤   (szComponents,"Unconfigured " + APP_NAME +" Client Install")¤   ·=¤ FAL¶
a02088 SE)¤&&
77d78f ·¤  ¤   (ComponentIsItemSelected
254fc1 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") =¤ FAL¶
45f622 SE)) then
804c2a ¤   ¤   ¤   //Tell user program files are required
187117 ¤   ¤   ¤   SdShowMsg·
312b02 ¤   ¤   ¤   ("Nothing has been selected, please select items again",
0c128a ¤   ¤   ¤   ·TRUE);
9cfad1 ¤   ¤   ¤   Delay (4);
4e7117 ¤   ¤   ¤   SdShowMsg·
042b02 ¤   ¤   ¤   ("Nothing has been selected, please select items again",
beb036 ¤   ¤   ¤   ·FALSE);
78ebea ¤   ¤   ¤   goto PickItems;
91eb6d ¤   endif;
b8af5a
fa58f6 ¤   if ((ComponentIsItemSelected
174de0 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") = FALS¶
91a5ab E) &&
f7207f ¤   ····(ComponentIsItemSelected
b84bb4 ¤   ····(szComponents,"Unconfigured " + APP_NAME +" Client Install") = TRUE)) t¶
c010d3 hen
25af5a
825dd5 ¤   ¤   SetDialogTitle (DLG_ASK_YESNO,"Are you sure?");
bd4ba1 ¤   ¤   if (AskYesNo("You have selected to install the Unconfigured " + APP_NAM¶
42131a E +
cc6c02 ¤   ¤   ¤   " Client Install and have not selected\n" + APP_NAME +" Program Fil¶
6a41ac es." +
3084f3 ¤   ¤   ¤   " This type of install should only be done if you have " + APP_NAME¶
d36e86 ·+
ee589c ¤   ¤   ¤   " already\ninstalled. Do you?",YES) = NO) then
5d7117 ¤   ¤   ¤   SdShowMsg·
74a2dc ¤   ¤   ¤   (APP_NAME +" Program Files are required, please select items again",
3e128a ¤   ¤   ¤   ·TRUE);
55fad1 ¤   ¤   ¤   Delay (4);
507117 ¤   ¤   ¤   SdShowMsg·
eaa2dc ¤   ¤   ¤   (APP_NAME +" Program Files are required, please select items again",
6bb036 ¤   ¤   ¤   ·FALSE);
4aebea ¤   ¤   ¤   goto PickItems;
f28ad7 ¤   ¤   endif;
b9eb6d ¤   endif;
b9af5a
4c8eda ¤   ListAddString(listData,"",AFTER);
351d2f ¤   ListAddString(listData,"Destination Directory:",AFTER);
4bf7c8 ¤   ListAddString(listData," ··········" + szAppPath,AFTER);
29af5a
2d9d4d ¤   // Set title and static text for SdStartCopy.
1dc3b0 ¤   szTitle = "Check Setup Information";
43f3ef ¤   szMsg = "Setup has enough information to begin copying the\n" +
d0e7b7 ¤   ¤   ¤   "program files. ·If you want to review or change any of the\n" +
b1ed3a ············"settings, click Back. ·If you are satisfied with the\n" +
8e8030 ············"settings, click Next to begin copying files.";
d7af5a
e6a19b ¤   if (bEasyInstall = FALSE) then
5723fc ¤   ¤   // Call SdStartCopy to display user selections.
8dc072 ¤   ¤   nvResult = SdStartCopy (szTitle,szMsg,listData);
abaf5a
96d354 ¤   ¤   switch(nvResult)
07af5a
b74fce ¤   ¤   ¤   case NEXT:
8eaf5a
bcccb0 ¤   ¤   ¤   ¤   goto OEoverhead;
54af5a
6b9fcc ¤   ¤   ¤   case BACK:
e4af5a
0946b4 ¤   ¤   ¤   ¤   goto PickItems;
78947c ¤   ¤   ¤   ·
c8db68 ¤   ¤   ¤   default:
--c16e 00095a5944640110222 Page 26 of setup.rul
e0af5a
a9e396 ¤   ¤   ¤   MessageBox("SdStartCopy failed.",SEVERE);
4439f2 ¤   ¤   endswitch;
b6eb6d ¤   endif;
19af5a
45558f //Do overhead for installing Outlook Express
d44774 OEoverhead:
13a6b4 ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
821371 ¤   ¤   if (ComponentIsItemSelected
f33625 ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin") = TRUE) th¶
537cc9 en¤ ··
d7d0eb ¤   ¤   ¤   //Get Outlook Express's Install Directory
ca6626 ¤   ¤   ¤   RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
4a7618 ¤   ¤   ¤   szKey = "Software\\Microsoft\\Outlook Express";
2eedc1 ¤   ¤   ¤   szName = "InstallRoot";
e1af5a
b899e4 ¤   ¤   ¤   RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
1bb286 ¤   ¤   ¤   szOEdir = svValue;
82af5a
9e665c ¤   ¤   ¤   if (FindFile (szOEdir, "msimn.exe", svResult) <0) then
eaf345 ¤   ¤   ¤   ¤   bFoundOutlook = FALSE;
9cbb8c ¤   ¤   ¤   else
db756e ¤   ¤   ¤   ¤   //msimn.exe is present
ce2a84 ¤   ¤   ¤   ¤   bFoundOutlook = TRUE;
ef6874 ¤   ¤   ¤   endif;
bcaf5a
c250e6 ¤   ¤   ¤   if (bFoundOutlook = FALSE) then
918bf5 ¤   ¤   ¤   ¤   Disable (BACKBUTTON);
1a4e5a ¤   ¤   ¤   ¤   // we must ask the user where Outlook is
a4d79b ¤   ¤   ¤   ¤   MessageBox( "Setup could not find your Outlook Express install ¶
c5c4aa directory. Please Browse to it.", INFORMATION );
a210f3 ¤   ¤   ¤   ¤   szOEdir = "";
51f504 ¤   ¤   ¤   ¤   nResult = UseDLL (SUPPORTDIR ^ "INSTALL.DLL");
1d777d ¤   ¤   ¤   ¤   szOEdir = "Browse to your Outlook Express Install folder.";
aefb58 ¤   ¤   ¤   ¤   hwndIS3 = GetWindowHandle(HWND_INSTALL);
b5895c ¤   ¤   ¤   ¤   nResult = MyBrowseForFolder32 (hwndIS3, szOEdir);
2287c7 ¤   ¤   ¤
d085b4 ¤   ¤   ¤   ¤   if (ExistsDir (szOEdir) = EXISTS &&
490b9b ¤   ¤   ¤   ¤   ¤   FindFile(szOEdir,"msimn.exe",svResult)=0) then
782faf ¤   ¤   ¤   ¤   ¤   ¤   bFoundOutlook = TRUE;
d5fa07 ¤   ¤   ¤   ¤   else
7517ea ¤   ¤   ¤   ¤   ¤   //They did not enter a path for Outlook
a67ecd ¤   ¤   ¤   ¤   ¤   // & it cannot be found·
cd2396 ¤   ¤   ¤   ¤   ¤   //so we do not install the plugin.
616a78 ¤   ¤   ¤   ¤   ¤   MessageBox( "There does not appear to be a valid install of¶
426d66 ·Microsoft Outlook " +
5cf60b ¤   ¤   ¤   ¤   ¤   ¤   ····"Express in this directory so the plugin won't be i¶
895886 nstalled.", INFORMATION );
a22b5b ¤   ¤   ¤   ¤   ¤   ComponentSelectItem
bd5ba6 ¤   ¤   ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin"¶
edd69b ,FALSE);
e56335 ¤   ¤   ¤   ¤   ¤   goto SetupFilesToTransfer;
41539d ¤   ¤   ¤   ¤   endif;
166874 ¤   ¤   ¤   endif;
54af5a
ee26f0 ¤   ¤   ¤   ¤   UnUseDLL (SUPPORTDIR ^ "INSTALL.DLL");
91af5a
a9615f //¤ ¤   ¤   ¤   if (AskPath(szMsg,"",szOEdir) = NEXT) then
d6fccf //¤ ¤   ¤   ¤   ¤   if ((szOEdir != "")) then
1ae319 //¤ ¤   ¤   ¤   ¤   ¤   if (ExistsDir(szOEdir)=EXISTS &&
35d509 //¤ ¤   ¤   ¤   ¤   ¤   ¤   FindFile(szOEdir,"msimn.exe",svResult)=0)
732171 //¤ ¤   ¤   ¤   ¤   ¤   ¤   then
985141 //¤ ¤   ¤   ¤   ¤   ¤   ¤   bFoundOutlook = TRUE;
87f74e //¤ ¤   ¤   ¤   ¤   ¤   else
155f3b //¤ ¤   ¤   ¤   ¤   ¤   ¤   //They did not enter a path for Outlook
415f3e //¤ ¤   ¤   ¤   ¤   ¤   ¤   // & it cannot be found·
d16051 //¤ ¤   ¤   ¤   ¤   ¤   ¤   //so we do not install the plugin.
771309 //¤ ¤   ¤   ¤   ¤   ¤   ¤   MessageBox( "There does not appear to be a valid in¶
c58650 stall of Microsoft Outlook " +
5ef062 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····"Express in this directory so the plugin wo¶
56d373 n't be installed.", INFORMATION );
95062c //¤ ¤   ¤   ¤   ¤   ¤   ¤   ComponentSelectItem
--9fb7 0001f8fe95640110222 Page 27 of setup.rul
1c1175 //¤ ¤   ¤   ¤   ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express¶
447291 ·Plugin",FALSE);
0ee967 //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   goto SetupFilesToTransfer;
321906 //¤ ¤   ¤   ¤   ¤   ¤   endif;
49b754 //¤ ¤   ¤   ¤   ¤   endif;
ede97b //¤ ¤   ¤   ¤   endif;
1a9525 //¤ ¤   ¤   endif;
7d465d //
4a024b ¤   ¤   StrRemoveLastSlash (szOEdir);
f0af5a
25af5a
76f77e ¤   ¤   if (FindFile(szOEdir,"PGPmsimn.exe",svResult)=0) then
f71311 ¤   ¤   ¤   RenameOriginal = FALSE;
bc8ad7 ¤   ¤   endif;
7aaf5a
31a278 ¤   ¤   if (RenameOriginal = FALSE) then
f4c9d3 ¤   ¤   ¤   szFileName = szOEdir ^ "msimn.exe";
fa1466 ¤   ¤   ¤   UseDLL( "Version.dll" );
3dfd6c ¤   ¤   ¤   lSize = GetFileVersionInfoSizeA( szFileName, nHandle );
613e8d ¤   ¤   ¤   //NumToStr( szTemp, lSize );
5179da ¤   ¤   ¤   bVerInfo = GetFileVersionInfoA( szFileName, nHandle, lSize, szVerBu¶
29e5a2 ffer);
8831cf ¤   ¤   ¤   ptr1 = AddressString( szResultBuffer );
c556dd ¤   ¤   ¤   ptr2 = AddressNumber( ptr1 );
5bcc6d ¤   ¤   ¤   bVerValue = VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904b0¶
b1350c \\CompanyName", ptr2, nSize);
09af5a
5a239d ¤   ¤   ¤   if (bVerValue =0) then·
6725aa ¤   ¤   ¤   ¤   VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904E4\\Compan¶
c98b02 yName", ptr2, nSize);
5f6874 ¤   ¤   ¤   endif;
10ad3c ¤   ¤   ¤   // pszResultBuffer is a pointer to a pointer which is the starting ¶
cf4361 point
abea17 ¤   ¤   ¤   // for the company name. How do you actually get the string ?
052a71 ¤   ¤   ¤   StructGetP( ptr2, "MYTYPE_PSZ", "szString", lData, szData );
07fa27 ¤   ¤   ¤   //MessageBox (szData, INFORMATION);
1e12e6 ¤   ¤   ¤   UnUseDLL( "Version.dll" );
1d8ad7 ¤   ¤   endif;
d0af5a
c03fd8 ¤   ¤   if (szData = "Microsoft Corporation") then
a4bafa ¤   ¤   ¤   //the user install the plugin then updated outlook
b68b7a ¤   ¤   ¤   //so we DO want to use this newer file
874813 ¤   ¤   ¤   RenameOriginal = TRUE;
79cdb7 ¤   ¤   ¤   VarSave¤ (SRCTARGETDIR);
faccda ¤   ¤   ¤   SRCDIR = szOEdir;
a5f3fd ¤   ¤   ¤   TARGETDIR = szOEdir;
42053d ¤   ¤   ¤   DeleteFile ("pgpmsimn.exe");
6a1774 ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
021875 ¤   ¤   ¤   bCheckVersion = FALSE;
3e8ad7 ¤   ¤   endif;
3faf5a
fc855d ¤   ¤   if (DEBUG = "TRUE") then
d5480a ¤   ¤   ¤   ·MessageBox( "Outlook Express installed in " + szOEdir, INFORMATION¶
0954c8 ·);
e98ad7 ¤   ¤   endif;
e8bd43 //moved from here
1ba937 ¤   ¤   if (bCheckVersion != FALSE) then
c53753 ¤   ¤   ¤   szVersionInfo1 = "4.72.2106.4";
8aaf5a
b62560 ¤   ¤   ¤   VerGetFileVersion (szOEdir ^ "msimn.exe", szVersionInfo2);
e87ecd ¤   ¤   ¤   //Made changes here needs to be checked
427085 ¤   ¤   ¤   if (VerCompare (szVersionInfo1, szVersionInfo2, VERSION)= GREATER_T¶
f349da HAN) then
57dc19 ¤   ¤   ¤   ¤   MessageBox( "The Outlook Express plugin requires Microsoft Outl¶
b84812 ook Express be installed.\n"+
6b017a ¤   ¤   ¤   ¤   ¤   ¤   "Version 4.72.2106.4 or later. If you upgrade your vers¶
bc76e7 ion and wish to\n" +
1faa7c ¤   ¤   ¤   ¤   ¤   ¤   "install the Outlook Express Plugin, you will need to r¶
ca5258 un this setup again.", INFORMATION );
0da33d ¤   ¤   ¤   ¤   ¤   ¤   ComponentSelectItem
d0135c ¤   ¤   ¤   ¤   ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plu¶
1f79e9 gin",FALSE);
--d384 00093bbe7f540110222 Page 28 of setup.rul
55f2ad ¤   ¤   ¤   ¤   goto SetupFilesToTransfer;
b46874 ¤   ¤   ¤   endif;
0f8ad7 ¤   ¤   endif;
21af5a
c2bf95 ¤   ¤   if (RenameOriginal = TRUE) then
279db5 ¤   ¤   ¤   VarSave (SRCTARGETDIR);
02ccda ¤   ¤   ¤   SRCDIR = szOEdir;
d0f3fd ¤   ¤   ¤   TARGETDIR = szOEdir;
ca54d6 ¤   ¤   ¤   if (RenameFile ("msimn.exe", "PGPmsimn.exe")<0) then
5b43a9 ¤   ¤   ¤   ¤   MessageBox( "Unable to rename msimn.exe which is needed for the¶
6467a7 ·Outlook Express\n" +
02d999 ¤   ¤   ¤   ¤   ¤   ¤   "Plugin, please reboot and run this setup again", WARNI¶
2627ab NG );
14db09 ¤   ¤   ¤   ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
823071 ¤   ¤   ¤   ¤   ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
8f539d ¤   ¤   ¤   ¤   endif;
282d73 ¤   ¤   ¤   ¤   exit;
d16874 ¤   ¤   ¤   endif;
2a1774 ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
748ad7 ¤   ¤   endif;
b0eb6d ¤   endif;
b828d5 endif;
68af5a
d3df18 //Begin Copying Files
84af5a
7f402b SetupFilesToTransfer:
d1af5a
f4bbb7 ¤   //Enable (INDVFILESTATUS);
caaf5a
6fccae ¤   szFileSet = "General";
b16800 ¤   // Define the file set.
7db53a ¤   FileSetBeginDefine(szFileSet);
56af5a
61988d ¤   if (ComponentIsItemSelected
7ac704 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") = TRUE¶
b08fea ) then
89af5a
289872 ¤   ¤   SetStatusWindow(-1,"Copying " + APP_NAME +" Program Files...");
e648bc ¤   ¤   TARGETDIR = svTarget;
9baf5a
9feb95 ¤   ¤   if (CompressGet
508d89 ¤   ¤   ¤   ("DATA.Z","PGP60\\*.*",
effca7 ¤   ¤   ¤   COMP_NORMAL | INCLUDE_SUBDIR) < 0) then
90af5a
eec765 ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
1daf5a
c38ad7 ¤   ¤   endif;
61af5a
487561 ¤   ¤   SetStatusWindow(-1,"Copying " + APP_NAME +" Documentation...");
5a7ea4 ¤   ¤   TARGETDIR = svTarget ^ "Documentation";
99eb95 ¤   ¤   if (CompressGet
8b6bea ¤   ¤   ¤   ("DATA.Z","Docs\\*.*",
1ffca7 ¤   ¤   ¤   COMP_NORMAL | INCLUDE_SUBDIR) < 0) then
1faf5a
04c765 ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
0aaf5a
9f8ad7 ¤   ¤   endif;
63eb6d ¤   endif;
51af5a
4bf71d OutlookExpress:
d9a6b4 ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
26af5a
ce1371 ¤   ¤   if (ComponentIsItemSelected
9b3625 ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin") = TRUE) th¶
d96cef en
d4af5a
91e427 ¤   ¤   ¤   SetStatusWindow(-1,"Copying " + APP_NAME +" Outlook Express Plugin"¶
f16275 );
f3af5a
f396d1 ¤   ¤   ¤   TARGETDIR = WINSYSDIR;
591df0 ¤   ¤   ¤   if (CompressGet
93e30c ¤   ¤   ¤   ¤   ("DATA.Z","OEwinsys\\*.*",
--c5d1 000123ecede40110222 Page 29 of setup.rul
d753f6 ¤   ¤   ¤   ¤   COMP_NORMAL) < 0) then
05af5a
e62565 ¤   ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
206874 ¤   ¤   ¤   endif;
98af5a
d0f3fd ¤   ¤   ¤   TARGETDIR = szOEdir;
501df0 ¤   ¤   ¤   if (CompressGet
28174c ¤   ¤   ¤   ¤   ("DATA.Z","OEplugin\\*.*",
aaa90b ¤   ¤   ¤   ¤   COMP_NORMAL | INCLUDE_SUBDIR) < 0) then
c6af5a
d92565 ¤   ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
fb6874 ¤   ¤   ¤   endif;
41af5a
198ad7 ¤   ¤   endif;
21eb6d ¤   endif;
a1af5a
bd7579 ·// Users Manual
2e988d ¤   if (ComponentIsItemSelected
944b4d ¤   ¤   (szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)")
b3ef48 ¤   ¤   ·= TRUE) then
94af5a
39ce6e ¤   ¤   SetStatusWindow(-1,"Copying " + APP_NAME +" User's Manual...");
6d7ea4 ¤   ¤   TARGETDIR = svTarget ^ "Documentation";
55af5a
71eb95 ¤   ¤   if (CompressGet
7afbf6 ¤   ¤   ¤   ("DATA.Z","Manual\\*.*",
09fca7 ¤   ¤   ¤   COMP_NORMAL | INCLUDE_SUBDIR) < 0) then
07af5a
10c765 ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
07af5a
628ad7 ¤   ¤   endif;
6aeb6d ¤   endif;
7daf5a
39ae35 ·//Unconfigured PGP 5.5 Client Install
cfaf5a
80988d ¤   if (ComponentIsItemSelected
ce29d5 ¤   ¤   (szComponents,"Unconfigured " + APP_NAME +" Client Install")
6aef48 ¤   ¤   ·= TRUE) then
16af5a
1d9a7a ¤   ¤   SetStatusWindow(-1,"Copying Unconfigured " + APP_NAME +" Client Install¶
238c19 ...");
1748bc ¤   ¤   TARGETDIR = svTarget;
6aaf5a
aeeb95 ¤   ¤   if (CompressGet
f4b6dc ¤   ¤   ¤   ("DATA.Z","Admin\\*.*",
b6fca7 ¤   ¤   ¤   COMP_NORMAL | INCLUDE_SUBDIR) < 0) then
35af5a
8cc765 ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
24af5a
d58ad7 ¤   ¤   endif;
b5eb6d ¤   endif;
05af5a
b675dd ·//PGP Memlock and common control
c63a72 ¤   GetSystemInfo(OS, nvOS, svOS);
97be70 ¤   switch (nvOS)
50af5a
e85af8 ¤   case IS_WINDOWSNT:
2bbeaa ¤   ¤   SetStatusWindow(-1,"Copying Windows NT Memory Manager...");
e5b3c8 ¤   ¤   TARGETDIR = WINSYSDIR ^ "drivers";
57eb95 ¤   ¤   if (CompressGet
565f09 ¤   ¤   ¤   ("DATA.Z","ntmemloc\\*.*",
072d79 ¤   ¤   ¤   COMP_NORMAL | SHAREDFILE) < 0) then
11af5a
d0c765 ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
1baf5a
878ad7 ¤   ¤   endif;
336332 ¤   ¤   //Set reg. keys for NT PGPmemlock
28353d ¤   ¤   RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
510cc4 ¤   ¤   szKey = "SYSTEM\\CurrentControlSet\\Services\\PGPmemlock";
59f6b8 ¤   ¤   RegDBSetKeyValueEx (szKey ,"ErrorControl",REGDB_NUMBER,"1",-1);
8ddb17 ¤   ¤   RegDBSetKeyValueEx (szKey ,"Type",REGDB_NUMBER,"1",-1);
12655c ¤   ¤   RegDBSetKeyValueEx (szKey ,"Start",REGDB_NUMBER,"2",-1);
--9fcf 000cf30e3cf40110222 Page 30 of setup.rul
7e28be ¤   ¤   RegDBSetKeyValueEx (szKey ,"DisplayName",REGDB_STRING,"PGP secure memor¶
044c45 y driver",-1);
94af5a
d5080d ¤   case IS_WINDOWS95:
01ab84 ¤   ¤   SetStatusWindow(-1,"Copying Windows 95 Memory Manager...");
7a3425 ¤   ¤   TARGETDIR = WINDIR;
d0eb95 ¤   ¤   if (CompressGet
880958 ¤   ¤   ¤   ("DATA.Z","95memloc\\*.*",
f52d79 ¤   ¤   ¤   COMP_NORMAL | SHAREDFILE) < 0) then
57af5a
17c765 ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
5aaf5a
088ad7 ¤   ¤   endif;
ffdb51 ¤   endswitch;
4daf5a
1e2a50 Exchange:
5c9a5a if (IS_QUALCOMM_BUILD = "FALSE") then
2caf5a
6f988d ¤   if (ComponentIsItemSelected
31d843 ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin") = TRUE) t¶
7f10d3 hen
8daf5a
0ea7a2 ¤   ¤   SetStatusWindow(-1,"Copying " + APP_NAME +" Exchange/Outlook Plugin");
12af5a
b11aae ¤   ¤   TARGETDIR = WINSYSDIR;
15eb95 ¤   ¤   if (CompressGet
ed11d7 ¤   ¤   ¤   ("DATA.Z","Exchange\\*.*",
c4fca7 ¤   ¤   ¤   COMP_NORMAL | INCLUDE_SUBDIR) < 0) then
50af5a
7fc765 ¤   ¤   ¤   MessageBox("CompressGet failed PGP",WARNING);
608ad7 ¤   ¤   endif;
16eb6d ¤   endif;
7028d5 endif;
58af5a
c2af5a
e75394 FindEudora:
67af5a
af988d ¤   if (ComponentIsItemSelected
e07009 ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin") = TRUE) then
a4af5a
bea47a ¤   ¤   // add the eudora plugin to the plugins dir
d4d325 ¤   ¤   bFoundEudora = FALSE;
cc0751 ¤   ¤   nvType ······= REGDB_STRING;
a8af5a
b867c5 ¤
30af5a
0a9f71 ¤   ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
7d96c8 ¤   ¤   ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
9dfed5 ¤   ¤   ¤   RegString = "\\Software\\Qualcomm\\Eudora\\CommandLine";
ce715b ¤   ¤   ¤   KeyVal = "Current";
c70e1d ¤   ¤   else
346626 ¤   ¤   ¤   RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
f7065d ¤   ¤   ¤   RegString = "\\Software\\Microsoft\\Windows\\CurrentVersion\\App Pa¶
58ad4d ths\\Eudora.exe";
a4a78f ¤   ¤   ¤   KeyVal = "Path";
008ad7 ¤   ¤   endif;
d7af5a
3598be ¤   ¤   if (RegDBGetKeyValueEx
dda512 ¤   ¤   ¤   (RegString,KeyVal,nvType,szEudoraPath,nvPathLen) < 0) then
93e42d ¤   ¤   ¤   bFoundEudora = FALSE;
0f0e1d ¤   ¤   else
9dd04f ¤   ¤   ¤   if (IS_QUALCOMM_BUILD = "FALSE") then
93aa68 ¤   ¤   ¤   // Set necessary variables.
1567eb ¤   ¤   ¤   listID ········= ListCreate(STRINGLIST);
8353fc ¤   ¤   ¤   szDelimiterSet = " ";
5767c5 ¤
b5d0f9 ¤   ¤   ¤   StrGetTokens(listID, szEudoraPath, szDelimiterSet);
6b7e7e ¤   ¤   ¤   ListGetFirstString(listID, svString);
93e4fd ¤   ¤   ¤   ParsePath(szEudoraPath, svString, PATH);
c86874 ¤   ¤   ¤   endif;
441b52 ¤   ¤
cff4f7 ¤   ¤   ¤   if (ExistsDir(szEudoraPath) = NOTEXISTS) then
--8359 000dc884d4040110222 Page 31 of setup.rul
dd0b5e ¤   ¤   ¤   ¤   bFoundEudora = FALSE;
1bbb8c ¤   ¤   ¤   else
d0c68b ¤   ¤   ¤   ¤   bFoundEudora = TRUE;
b76874 ¤   ¤   ¤   endif;
ccaf5a
808ad7 ¤   ¤   endif;
2faf5a
65a80b ¤   ¤   if (bFoundEudora = FALSE) then
9875e1 ¤   ¤   ¤   // we must ask the user where Eudora is
9cc559 ¤   ¤   ¤   szEudoraPath = "";
7187c7 ¤   ¤   ¤
54074a ¤   ¤   ¤   MessageBox( "Setup could not find your Eudora install directory. Pl¶
09a798 ease Browse to it.", INFORMATION );
15f5e6 ¤   ¤   ¤   nResult = UseDLL (SUPPORTDIR ^ "INSTALL.DLL");
556680 ¤   ¤   ¤   szEudoraPath = "Browse to your Eudora Install folder.";
b0946b ¤   ¤   ¤   hwndIS3 = GetWindowHandle(HWND_INSTALL);
c3232f ¤   ¤   ¤   nResult = MyBrowseForFolder32 (hwndIS3, szEudoraPath);
5c37d7 ¤   ¤   ¤   UnUseDLL (SUPPORTDIR ^ "INSTALL.DLL");
69af5a
bdf361 ¤   ¤   ¤   ¤   if ((szEudoraPath != "")) then
b0bcd4 ¤   ¤   ¤   ¤   ¤   if (ExistsDir(szEudoraPath)=EXISTS &&
0a863e ¤   ¤   ¤   ¤   ¤   ¤   FindFile(szEudoraPath,"Eudora.exe",szEudoraFile)=0)
ba0587 ¤   ¤   ¤   ¤   ¤   ¤   then
19c5de ¤   ¤   ¤   ¤   ¤   ¤   bFoundEudora = TRUE;
bb4bd6 ¤   ¤   ¤   ¤   ¤   else
d3b920 ¤   ¤   ¤   ¤   ¤   ¤   //They did not enter a path for Eudora
4d2c50 ¤   ¤   ¤   ¤   ¤   ¤   // & it cannot be found·
6724ad ¤   ¤   ¤   ¤   ¤   ¤   //so we do not install the plugin.
bfa33d ¤   ¤   ¤   ¤   ¤   ¤   ComponentSelectItem
8c5f11 ¤   ¤   ¤   ¤   ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin",FALSE);
4fb17c ¤   ¤   ¤   ¤   ¤   endif;
7b539d ¤   ¤   ¤   ¤   endif;
ff8ad7 ¤   ¤   endif;
3387c7 ¤   ¤   ¤
199c3f ¤   ¤   if (bFoundEudora = TRUE) then
0969e9 ¤   ¤   ¤   EudoraPluginPath = szEudoraPath + "\\Plugins";
0d2ced ¤   ¤   ¤   PathToExe = szEudoraPath^"Eudora.exe";
d0af5a
8f9919 ¤   ¤   ¤   //find out if they are running PRO or LITE
ee7f94 ¤   ¤   ¤   UseDLL("Version.dll");
c13ede ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
19fd4c ¤   ¤   ¤   lSize ····= GetFileVersionInfoSizeA
0a320e ¤   ¤   ¤   ¤   ¤   ¤   (szEudoraPath^"Eudora.exe",nHandle);
70af5a
6b5d1e ¤   ¤   ¤   bVerInfo ·= GetFileVersionInfoA
da09a3 ¤   ¤   ¤   ¤   ¤   ¤   (szEudoraPath^"Eudora.exe",nHandle,lSize,szVerBuffer);
66af5a
46f77e ¤   ¤   ¤   ptr1 ·····= AddressString
8cc449 ¤   ¤   ¤   ¤   ¤   ¤   (szResultBuffer);
0326bf ¤   ¤   ¤   ptr2 ·····= AddressNumber
40fbe6 ¤   ¤   ¤   ¤   ¤   ¤   (ptr1);
2e41c2 ¤   ¤   ¤   bVerValue = VerQueryValueA
2c66c7 ¤   ¤   ¤   ¤   ¤   ¤   (szVerBuffer,"\\StringFileInfo\\040904E4\\ProductName"
17432a ¤   ¤   ¤   ¤   ¤   ¤   ,ptr2,nSize);
10af5a
2003cb ¤   ¤   ¤   // pszResultBuffer is a pointer to a pointer which is the starting
2d4a03 ¤   ¤   ¤   // point for the product name. How do you actually get the string?
364f47 ¤   ¤   ¤   StructGetP(ptr2,"MYTYPE_PSZ","szString",lData,szData);
c0ba71 ¤   ¤   ¤   UnUseDLL("Version.dll");
b119c2 ¤   ¤   ¤   //szData will now equal Lite or Pro
9eaf5a
bd7695 ¤   ¤   ¤   // check to see if we need to migrate 3.0.1 to 3.0.2
2b3609 ¤   ¤   ¤   WhichPlugin = "REGULAR";
ef2b09 ¤   ¤   ¤   if (VerGetFileVersion
68ed95 ¤   ¤   ¤   ¤   (szEudoraPath^"Eudora.exe",svEudoraVersion) = 0) then
c72b85 ¤   ¤   ¤   ¤
5e4404 ¤   ¤   ¤   ¤   if (ComponentIsItemSelected·
c0f0c4 ¤   ¤   ¤   ¤   ···(szComponents,APP_NAME +" Eudora Plugin") = TRUE) then
54afe8 ¤   ¤   ¤   ¤   ¤   UpdateNeeded = "FALSE";
fabcbd ¤   ¤   ¤   ¤   ¤   if (VerCompare
4b2c6d ¤   ¤   ¤   ¤   ¤   ¤   (svEudoraVersion,"3.0.2.0",VERSION) = LESS_THAN) then
dc69f3 ¤   ¤   ¤   ¤   ¤   ¤   UpdateNeeded = "TRUE";
--8391 00051115d0440110222 Page 32 of setup.rul
7735fa ¤   ¤   ¤   ¤   ¤   ¤   MessageBox
74688c ¤   ¤   ¤   ¤   ¤   ¤   ("Setup has detected that Eudora needs to be updated.\n¶
dadddf " +
5ecd49 ¤   ¤   ¤   ¤   ¤   ¤   "The necessary updates can be found at : \n\n" ········+
345b7e ¤   ¤   ¤   ¤   ¤   ¤   "http://www.eudora.com\n\n" ··+
c30a9c ¤   ¤   ¤   ¤   ¤   ¤   "You will be reminded to do to this at the end of the\n¶
20dddf " +
e5b0aa ¤   ¤   ¤   ¤   ¤   ¤   "install, and a shortcut to this site will be put in" +
d0093d ¤   ¤   ¤   ¤   ¤   ¤   " the\nPGP folder located in the" +
84d58a ¤   ¤   ¤   ¤   ¤   ¤   " startbar.\nInstall update overtop of your current" +
fafc85 ¤   ¤   ¤   ¤   ¤   ¤   " version to maintain\nsettings and plugins, otherwise"¶
476e86 ·+
5a894b ¤   ¤   ¤   ¤   ¤   ¤   " PGP will need to be reinstalled)", INFORMATION);
aeb17c ¤   ¤   ¤   ¤   ¤   endif;
7baf5a
2e1b52 ¤   ¤
bce009 ¤   ¤   ¤   ¤   ¤   if ((VerCompare
035ddf ¤   ¤   ¤   ¤   ¤   ¤   (svEudoraVersion,"4.0.0.0",VERSION) = EQUALS) ||
6caa9f ¤   ¤   ¤   ¤   ¤   ¤   (VerCompare
e6181e ¤   ¤   ¤   ¤   ¤   ¤   (svEudoraVersion,"4.0.0.0",VERSION) = GREATER_THAN)) th¶
c26cef en
6ae6e3 ¤   ¤   ¤   ¤   ¤   ¤   WhichPlugin = "FOURDOTO";
32ae30 ¤   ¤   ¤   ¤   ¤
f1b17c ¤   ¤   ¤   ¤   ¤   endif;
ceaf5a
39539d ¤   ¤   ¤   ¤   endif;
cdd29c ¤   ¤   ¤   endif; // no version info for file
f3af5a
42d624 ¤   ¤   ¤   if (ComponentIsItemSelected
86fdf5 ¤   ¤   ¤   (szComponents,APP_NAME +" Eudora Plugin") = TRUE) then
f0af5a
5d2971 ¤   ¤   ¤   TARGETDIR = szEudoraPath ^ "Plugins";
8baf5a
62eae5 ¤   ¤   ¤   ¤   if (WhichPlugin = "FOURDOTO") then·
b23811 ¤   ¤   ¤   ¤   ¤   WhichEudoraPath = "Eudora\\FOURDOTO\\*.*";
94fa07 ¤   ¤   ¤   ¤   else
20fffb ¤   ¤   ¤   ¤   ¤   WhichEudoraPath = "Eudora\\REGULAR\\*.*";
76539d ¤   ¤   ¤   ¤   endif;
40af5a
0186ac ·······¤¤   ¤   if (CompressGet
08866b ¤   ¤   ¤   ¤   ¤   ("DATA.Z",WhichEudoraPath,COMP_NORMAL) < 0) then
b8a793 ¤   ¤   ¤   ¤   ¤   MessageBox("CompressGet failed Eudora",WARNING);
3f539d ¤   ¤   ¤   ¤   endif;
676874 ¤   ¤   ¤   endif;
9f8ad7 ¤   ¤   endif;
ddeb6d ¤   endif;
c2af5a
47988d ¤   if (ComponentIsItemSelected
c8c704 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") = TRUE¶
c58fea ) then
d71aae ¤   ¤   TARGETDIR = WINSYSDIR;
667409 ¤   ¤   SetStatusWindow
4c2010 ¤   ¤   (-1,"Copying Explorer Extensions...");
42eb95 ¤   ¤   if (CompressGet
29ebbd ¤   ¤   ¤   ("DATA.Z","WinSysDir\\*.*",COMP_NORMAL | LOCKEDFILE) < 0) then
fa4f4c ¤   ¤   ¤   MessageBox
657464 ¤   ¤   ¤   ("CompressGet failed WinSysDir",WARNING);
3c8ad7 ¤   ¤   endif;
b7eb6d ¤   endif;
f5af5a
1758f6 ¤   if ((ComponentIsItemSelected
1bc704 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") = TRUE¶
4b6de3 ) ||
12af5a
2527b0 ¤   ¤   (ComponentIsItemSelected(szComponents,"PGPdisk for Windows") = TRUE)) t¶
9510d3 hen
20af5a
281aae ¤   ¤   TARGETDIR = WINSYSDIR;
547409 ¤   ¤   SetStatusWindow
838fb6 ¤   ¤   (-1,"Copying SDK Extensions...");
93287d ¤   ¤   if (RSA = 1) then
511df0 ¤   ¤   ¤   if (CompressGet
--f2e1 0009445571240110222 Page 33 of setup.rul
ce31bb ¤   ¤   ¤   ¤   ("DATA.Z","SdkWinSys\\*.*",COMP_UPDATE_SAME¤| COMP_UPDATE_VERSI¶
108104 ON | SHAREDFILE) < 0) then
f7adad ¤   ¤   ¤   ¤   MessageBox
96c269 ¤   ¤   ¤   ¤   ("CompressGet failed SDK",WARNING);
256874 ¤   ¤   ¤   endif;
7f0e1d ¤   ¤   else
4d1df0 ¤   ¤   ¤   if (CompressGet
2f31bb ¤   ¤   ¤   ¤   ("DATA.Z","SdkWinSys\\*.*",COMP_UPDATE_SAME¤| COMP_UPDATE_VERSI¶
1b8104 ON | SHAREDFILE) < 0) then
acadad ¤   ¤   ¤   ¤   MessageBox
36c269 ¤   ¤   ¤   ¤   ("CompressGet failed SDK",WARNING);
a76874 ¤   ¤   ¤   endif;
b68ad7 ¤   ¤   endif;
e3af5a
eb256f ¤   ¤   //set reg. key to remove shared files
c80089 ¤   ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
7ea207 ¤   ¤   szLocalDB = "\\Software" ^ "Network Associates";
90af5a
02e93e ¤   ¤   RegDBSetKeyValueEx
a8a75b ¤   ¤   (szLocalDB ^ REGAPP_NAME,"DelSharedFiles",REGDB_STRING,"1",-1);
12eb6d ¤   endif;
11af5a
965b3e ¤   if (INCLUDEPGPFONE = "TRUE") then
e11371 ¤   ¤   if (ComponentIsItemSelected
d4f503 ¤   ¤   ¤   (szComponents,"PGPfone (Beta)") = TRUE) then
869473 ¤   ¤   ¤   //PGPFONE PROGRAM FILES
cda8c5 ¤   ¤   ¤   TARGETDIR = svTarget ^ "PGPfone";
65109f ¤   ¤   ¤   SetStatusWindow( -1, "Copying PGPfone program files..." );
1acc63 ¤   ¤   ¤   CompressGet( "DATA.Z", "pgpfone\\*.*", INCLUDE_SUBDIR | LOCKEDFILE ¶
536275 );
5a8ad7 ¤   ¤   endif;
4deb6d ¤   endif;
15af5a
bc74d4 ¤   if (INCLUDEPGPDISK = "TRUE") then
161371 ¤   ¤   if (ComponentIsItemSelected
b3c8c9 ¤   ¤   ¤   (szComponents,"PGPdisk for Windows") = TRUE) then
e0af5a
fc96ed ¤   ¤   ¤   //set reg. key to tell that PGPdisk was installed with PGP
3a96c8 ¤   ¤   ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
3584b2 ¤   ¤   ¤   szLocalDB = "\\Software" ^ "Network Associates";
a4af5a
75fd16 ¤   ¤   ¤   RegDBSetKeyValueEx
55c391 ¤   ¤   ¤   (szLocalDB ^ REGAPP_NAME,"PGPdiskInstalled",REGDB_STRING,"1",-1);
aaaf5a
1ae52a ¤   ¤   ¤   //PROGRAM FILES
b67fb4 ¤   ¤   ¤   TARGETDIR = svTarget;
dfb1ef ¤   ¤   ¤   SetStatusWindow( -1, "Copying PGPdisk program files..." );
bf50e9 ¤   ¤   ¤   CompressGet( "DATA.Z", "pgpdisk\\prog\\*.*", INCLUDE_SUBDIR | LOCKE¶
491e8c DFILE );
ebaf5a
91090a ¤   ¤   ¤   //SHELL EXTENSION
e296d1 ¤   ¤   ¤   TARGETDIR = WINSYSDIR;
7ddf14 ¤   ¤   ¤   SetStatusWindow( -1, "Copying PGPdisk shell extension files..." );
e2956e ¤   ¤   ¤   CompressGet( "DATA.Z", "pgpdisk\\shell\\*.*", LOCKEDFILE¤   ·);
f8af5a
693468 ¤   ¤   ¤   //DRIVERS
896510 ¤   ¤   ¤   if (IS_NT) then
2f5657 ¤   ¤   ¤   ¤   TARGETDIR = WINSYSDIR ^ "Drivers";
602942 ¤   ¤   ¤   ¤   CompressGet( "DATA.Z", "pgpdisk\\drivers\\nt\\*.*", LOCKEDFILE ¶
2b6275 );
5dbb8c ¤   ¤   ¤   else
f09aa1 ¤   ¤   ¤   ¤   TARGETDIR = WINSYSDIR ^ "iosubsys";
3b9cc3 ¤   ¤   ¤   ¤   CompressGet( "DATA.Z", "pgpdisk\\drivers\\95\\*.*", LOCKEDFILE ¶
fd6275 );
086874 ¤   ¤   ¤   endif;
07af5a
64a607 ¤   ¤   ¤   //MFC DLLS
d796d1 ¤   ¤   ¤   TARGETDIR = WINSYSDIR;
89917e ¤   ¤   ¤   SetStatusWindow( -1, "Copying MFC libraries..." );
0fe6f3 ¤   ¤   ¤   CompressGet( "DATA.Z", "pgpdisk\\mfc\\*.*", SHAREDFILE | COMP_UPDAT¶
21fcfc E_VERSION );
94af5a
--bf4f 000c381b9dd40110222 Page 34 of setup.rul
33d332 ¤   ¤   ¤   //We must remove old PGPdisk "stuff" if it is installed
356626 ¤   ¤   ¤   RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
dff888 ¤   ¤   ¤   szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\P¶
193933 GPdisk.exe";
b912f5 ¤   ¤   ¤   svOldDisk = "";
5faf5a
516e85 ¤   ¤   ¤   if (RegDBGetKeyValueEx (szKey, "", nvType, svOldDisk, nvSize) = 0) ¶
dd2830 then
d5517c ¤   ¤   ¤   ¤   //There IS an old PGPdisk installed so we need to do a few thin¶
bcfcbe gs
f88e3e ¤   ¤   ¤   ¤   //remove its uninstall entry
7e7b7f ¤   ¤   ¤   ¤   ParsePath (svReturnString, svOldDisk, PATH);
1eae30 ¤   ¤   ¤   ¤   ¤
a158e0 ¤   ¤   ¤   ¤   VarSave (SRCTARGETDIR);
702960 ¤   ¤   ¤   ¤   SRCDIR = svReturnString;
1efa29 ¤   ¤   ¤   ¤   TARGETDIR = svReturnString;
a3af5a
559dda ¤   ¤   ¤   ¤   TARGETDIR = svReturnString ^ "signatures";
46c60d ¤   ¤   ¤   ¤   DeleteFile ("*.sig");
f8bf61 ¤   ¤   ¤   ¤   DeleteFile ("*.*.sig");
907a74 ¤   ¤   ¤   ¤   DeleteDir ·(svReturnString ^ "signatures", ONLYDIR);
72af5a
bdfa29 ¤   ¤   ¤   ¤   TARGETDIR = svReturnString;
45af5a
44b652 ¤   ¤   ¤   ¤   DeleteFile ("pgpdisk.exe");
165815 ¤   ¤   ¤   ¤   DeleteFile ("pgpdisk.hlp");
d10bd1 ¤   ¤   ¤   ¤   DeleteFile ("pgpdisk.cnt");
929db0 ¤   ¤   ¤   ¤   DeleteFile ("pgpdisk.pdf");
24cbd1 ¤   ¤   ¤   ¤   DeleteFile ("readme.txt");
e8b32a ¤   ¤   ¤   ¤   DeleteFile ("license.txt");
45126e ¤   ¤   ¤   ¤   DeleteFile ("uninstall.exe");
8daf5a
18d722 ¤   ¤   ¤   ¤   TARGETDIR = WINSYSDIR;
c7bd27 ¤   ¤   ¤   ¤   DeleteFile ("pgpdskSE.dll");
481938 ¤   ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
9e2b85 ¤   ¤   ¤   ¤
719512 ¤   ¤   ¤   ¤   //Remove the entry from the uninstall applet
3a3028 ¤   ¤   ¤   ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
275169 ¤   ¤   ¤   ¤   RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\¶
7035c0 Uninstall\\PGPdiskDeinstKey");
eaaf5a
944491 ¤   ¤   ¤   ¤   //Remove the old start menu group ( will now reside in new P G ¶
119678 P group )
6eb5f2 ¤   ¤   ¤   ¤   DeleteProgramFolder (FOLDER_STARTMENU ^ "Programs" ^ "PGPdisk");
3ba108 ¤   ¤   ¤   ¤   ProgDefGroupType(PERSONAL);
17b5f2 ¤   ¤   ¤   ¤   DeleteProgramFolder (FOLDER_STARTMENU ^ "Programs" ^ "PGPdisk");
19af5a
3a6874 ¤   ¤   ¤   endif;
95af5a
848ad7 ¤   ¤   endif;
ebaf5a
28eb6d ¤   endif;
b2af5a
7b64c2 ¤   FileSetEndDefine(szFileSet);
5eaf5a
3467c5 ¤
49af5a
ccbcad TransferFiles:
b7869e ····
be66f4 ¤   TARGETDIR = svTarget ^ "Documentation";
33b225 ¤   CopyFile ("License.txt", "License.txt");
92af5a
0ac1e8 ¤   TARGETDIR = svTarget;
48ebd1 ¤   //copy old pref files from the copies I made in the windows directory
3b67c5 ¤
b352fa ¤   if ((FindFile (WINDIR, "PGP_Admin.prf", svResult) = 0) ||
25d842 ¤   ¤   (FindFile (WINDIR, "PGP_Client.prf", svResult) = 0)) then
fcaf5a
333cc3 ¤   ¤   SdShowMsg ("Copying old preference files...", TRUE);
ff9619 ¤   ¤   Delay (3);
691649 ¤   ¤   VarSave (SRCTARGETDIR);
c341c6 ¤   ¤   SRCDIR ····= WINDIR;
--a784 000269a34ff40110222 Page 35 of setup.rul
cf534e ¤   ¤   TARGETDIR ·= TARGETDIR;
58fc1e ¤   ¤   CopyFile ("PGP_Admin.prf","PGP_Admin.prf");
65559a ¤   ¤   CopyFile ("PGP_Client.prf","PGP_Client.prf");
fdb034 ¤   ¤   TARGETDIR ·= WINDIR;
cc41c6 ¤   ¤   SRCDIR ····= WINDIR;
515d62 ¤   ¤   DeleteFile ("PGP_Admin.prf");
87fdb2 ¤   ¤   DeleteFile ("PGP_Client.prf");
025687 ¤   ¤   VarRestore (SRCTARGETDIR);
b26fdd ¤   ¤   SdShowMsg ("Copying old preference files...", FALSE);
6faf5a
85eb6d ¤   endif;
f4af5a
66c2cb ¤   //copy the pref. files from disk 1 (if there)
4c9f51 ¤   //these take precedence if they are present
68bb17 ¤   VarSave (SRCTARGETDIR);
1695d1 ¤   SRCDIR ····= SRCDIR;
93fe10 ¤   TARGETDIR ·= TARGETDIR;
bf6a5f ¤   CopyFile ("PGP_Admin.prf","PGP_Admin.prf");
58fb9b ¤   CopyFile ("PGP_Client.prf","PGP_Client.prf");
21daf8 ¤   VarRestore (SRCTARGETDIR);
56af5a
e6bb17 ¤   VarSave (SRCTARGETDIR);
0395d1 ¤   SRCDIR ····= SRCDIR;
2f9168 ¤   TARGETDIR ·= TARGETDIR ^ "PGP Keyrings";
9a157c ¤   CopyFile ("pubring.pkr","pubring.pkr");
55daf8 ¤   VarRestore (SRCTARGETDIR);
49af5a
2e9b11 ¤   // Prepare InstallShield to record deinstallation information.
b59937 //¤ DeinstallStart(svTarget ,svUninstLogFile,DEINSTALL_KEY,0);
cb7240 //¤ RegDBSetItem(REGDB_UNINSTALL_NAME,UNINSTALL_NAME);
bcaf5a
83b71c ¤   // Set up progress indicator and information gauge.
2921fe ¤   Disable(DIALOGCACHE);
4fe8f4 ¤   Enable(STATUSDLG);
b7a24c ¤   PlaceWindow (STATUSDLG, CENTERED, CENTERED, CENTERED);
411f63 ¤   PlaceWindow (FEEDBACK, 0, 0, LOWER_RIGHT);
16af5a
887b43 ¤   // Perform the file set.
0b67d2 ¤   StatusUpdate(ON,100); // this is the final percentage after file copies
68af5a
afaf5a
d7d7bd ¤   SetStatusWindow(0,"Copying " + APP_NAME +" Program Files...");
ebb0bb ¤   nResult = FileSetPerformEz(szFileSet,0);
bfaf5a
dbe7d8 ¤   switch (nResult)
4caf5a
6d68c4 ¤   case FS_DONE: // Successful completion.
deaf5a
f50d12 ¤   case FS_CREATEDIR: // Create directory error.
44d29a ¤   ¤   MessageBox("Unable to create a directory under " + TARGETDIR + "."+
7dd11e ¤   ¤   ¤   ¤   ¤   "Please check write access to this directory.",SEVERE);
c3da8f ¤   ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
b833e4 ¤   ¤   ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
a88ad7 ¤   ¤   endif;
be1e9e ¤   ····exit;
8baf5a
407e8b ¤   default: // Group all other errors under default label.
1b3d7e ¤   ¤   NumToStr(szTemp,nResult);
eba97e ¤   ¤   MessageBox("General file transfer error."+
ef55a2 ¤   ¤   ¤   ¤   ¤   ·"Please check your target location and try again."+
5297d9 ¤   ¤   ¤   ¤   ¤   ·"\n\n Error Number:"+szTemp +
01a8bb ¤   ¤   ¤   ¤   ¤   ·"\n Related File: "+ERRORFILENAME,
a03d23 ¤   ¤   ¤   ¤   ¤   ·SEVERE);
ddda8f ¤   ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
a533e4 ¤   ¤   ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
cb8ad7 ¤   ¤   endif;
5f925c ¤   ¤   exit;
03db51 ¤   endswitch;
88af5a
94441e //Install Icons
caaf5a
2667c7 ¤   ProgDefGroupType(PERSONAL);
--6963 0009abe9c8a40110222 Page 36 of setup.rul
e0af5a
de8ecd ¤   //Add PGP (TED) to their startup group.
cf1b52 ¤   ¤
56c268 ¤   szProgram = TARGETDIR ^ "PGPtray.exe";
7d39a5 ¤   LongPathToQuote (szProgram,TRUE);
30e705 ¤   szAppPath = TARGETDIR;
f3af5a
795792 ¤   AddFolderIcon
d48542 ¤   (FOLDER_STARTUP,"PGPtray",szProgram,szAppPath,"",0,"",REPLACE);
66af5a
a6af5a
b1593a ¤   CreateProgramFolder ("P G P");
21af5a
90988d ¤   if (ComponentIsItemSelected
fc9c9a ¤   (szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)") = TRUE) th¶
bf6cef en
3a4fce ¤   ¤   szProgram = TARGETDIR ^ "Documentation" ^ "PGPWinUsersGuide.pdf";
fa054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
e11281 ¤   ¤   szAppPath = TARGETDIR ^ "Documentation";
4c6d08 ¤   ¤   AddFolderIcon
d60ead ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation",
fd2cfa ¤   ¤   "PGP 6.0 Manual",szProgram,szAppPath
e2deef ¤   ¤   ,"",0,"",REPLACE);
9aeb6d ¤   endif;
fbaf5a
e65b3e ¤   if (INCLUDEPGPFONE = "TRUE") then
b91371 ¤   ¤   if (ComponentIsItemSelected
89f503 ¤   ¤   ¤   (szComponents,"PGPfone (Beta)") = TRUE) then
ec8f11 ¤   ¤   ¤   szProgram = TARGETDIR ^ "PGPfone" ^ "PGPfone.exe";
0a3c8e ¤   ¤   ¤   LongPathToQuote (szProgram,TRUE);
ae7d18 ¤   ¤   ¤   szAppPath = TARGETDIR ^ "PGPfone";
77aabd ¤   ¤   ¤   AddFolderIcon
a5cc8b ¤   ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "PGPfone",
6403fe ¤   ¤   ¤   "PGPfone (Beta)",szProgram,szAppPath
bccac7 ¤   ¤   ¤   ,"",0,"",REPLACE);
17af5a
571b5d ¤   ¤   ¤   szProgram = TARGETDIR ^ "PGPfone" ^ "readme.txt";
f53c8e ¤   ¤   ¤   LongPathToQuote (szProgram,TRUE);
ee7d18 ¤   ¤   ¤   szAppPath = TARGETDIR ^ "PGPfone";
abaabd ¤   ¤   ¤   AddFolderIcon
a1335e ¤   ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "PGPfone" ^ "Documentati¶
806fa3 on",
ef06f5 ¤   ¤   ¤   "ReadMe",szProgram,szAppPath
b4cac7 ¤   ¤   ¤   ,"",0,"",REPLACE);
5aaf5a
780434 ¤   ¤   ¤   szProgram = TARGETDIR ^ "PGPfone" ^ "pgpfone.pdf";
b23c8e ¤   ¤   ¤   LongPathToQuote (szProgram,TRUE);
f87d18 ¤   ¤   ¤   szAppPath = TARGETDIR ^ "PGPfone";
94aabd ¤   ¤   ¤   AddFolderIcon
36335e ¤   ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "PGPfone" ^ "Documentati¶
0a6fa3 on",
05cbe2 ¤   ¤   ¤   "PGPfone Manual",szProgram,szAppPath
08cac7 ¤   ¤   ¤   ,"",0,"",REPLACE);
228ad7 ¤   ¤   endif;
2deb6d ¤   endif;
16af5a
f1988d ¤   if (ComponentIsItemSelected
afc704 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") = TRUE¶
ca8fea ) then
adaf5a
22d2e9 ¤   ¤   if (ISADMIN = "TRUE") then
5a8198 ¤   ¤   ¤   szProgram = TARGETDIR ^ "Documentation" ^ "PGPAdministratorsGuide.p¶
bb150e df";
b43c8e ¤   ¤   ¤   LongPathToQuote (szProgram,TRUE);
0b419a ¤   ¤   ¤   szAppPath = TARGETDIR ^ "Documentation";
37aabd ¤   ¤   ¤   AddFolderIcon
6540da ¤   ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation",
f3a5b6 ¤   ¤   ¤   APP_NAME +" Administrator's Guide",szProgram,szAppPath
5ccac7 ¤   ¤   ¤   ,"",0,"",REPLACE);
658ad7 ¤   ¤   endif;
b0af5a
9ac352 ¤   ¤   if (INCLUDEINSTALLGUIDE = "TRUE") then
--26a0 000415e975b40110222 Page 37 of setup.rul
f54f02 ¤   ¤   ¤   szProgram = TARGETDIR ^ "Documentation" ^ "PGPInstallGuide.pdf";
b43c8e ¤   ¤   ¤   LongPathToQuote (szProgram,TRUE);
73419a ¤   ¤   ¤   szAppPath = TARGETDIR ^ "Documentation";
b4aabd ¤   ¤   ¤   AddFolderIcon
d140da ¤   ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation",
1aee3b ¤   ¤   ¤   APP_NAME +" Install Guide",szProgram,szAppPath
d3cac7 ¤   ¤   ¤   ,"",0,"",REPLACE);
5e8ad7 ¤   ¤   endif;
f4af5a
ff1b48 ¤   ¤   szProgram = TARGETDIR ^ "Documentation" ^ "IntroToCrypto.pdf";
52054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
1e1281 ¤   ¤   szAppPath = TARGETDIR ^ "Documentation";
c86d08 ¤   ¤   AddFolderIcon
df0ead ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation",
bd1a80 ¤   ¤   " Intro To Crypto",szProgram,szAppPath
59deef ¤   ¤   ,"",0,"",REPLACE);
70af5a
75c3ca ¤   ¤   szProgram = TARGETDIR ^ "Documentation" ^ "Readme.txt";
49054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
7f1281 ¤   ¤   szAppPath = TARGETDIR ^ "Documentation";
676d08 ¤   ¤   AddFolderIcon
de0ead ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation",
f9d8ec ¤   ¤   " ReadMe",szProgram,szAppPath
44deef ¤   ¤   ,"",0,"",REPLACE);
fdaf5a
56eb6d ¤   endif;
c5af5a
9b70d2 ¤   if (ComponentIsItemSelected(szComponents,"Unconfigured " + APP_NAME +" Clie¶
5b5b2f nt" +
bfc3db ¤   " Install") = TRUE) then
64f327 ¤   ¤   szProgram = TARGETDIR ^ "PGPadmin.exe";
ac054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
eef32d ¤   ¤   szAppPath = TARGETDIR;
456d08 ¤   ¤   AddFolderIcon
cbad9e ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P",
0f25be ¤   ¤   "PGPadmin",szProgram,szAppPath ,"",0,"",REPLACE);
34eb6d ¤   endif;
38af5a
cd988d ¤   if (ComponentIsItemSelected
94c704 ¤   ¤   (szComponents,APP_NAME +" Program Files (Required for PGP 6.x)") = TRUE¶
1ed26e ) then¤
feaf5a
0fb57c ¤   ¤   szProgram = TARGETDIR ^ "pgpkeys.exe";
d6054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
b8f32d ¤   ¤   szAppPath = TARGETDIR;
9f6d08 ¤   ¤   AddFolderIcon
87ad9e ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P",
add29a ¤   ¤   "PGPkeys",szProgram,szAppPath ,"",0,"",REPLACE);
f4af5a
7453f0 ¤   ¤   szProgram = TARGETDIR ^ "PGPtray.exe";
5c054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
3ff32d ¤   ¤   szAppPath = TARGETDIR;
396d08 ¤   ¤   AddFolderIcon
53ad9e ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P",
7b8703 ¤   ¤   "PGPtray",szProgram,szAppPath,"",0,"",REPLACE);
f81b52 ¤   ¤
53ef36 ¤   ¤   szProgram = TARGETDIR ^ "PGPtools.exe";
0d054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
33f32d ¤   ¤   szAppPath = TARGETDIR;
496d08 ¤   ¤   AddFolderIcon
ccad9e ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P",
a1e21c ¤   ¤   "PGPtools",szProgram,szAppPath,"",0,"",REPLACE);
0faf5a
bffee7 ¤   ¤   szProgram = TARGETDIR ^ "uninstall.exe";
a3054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
52f32d ¤   ¤   szAppPath = TARGETDIR;
ce6d08 ¤   ¤   AddFolderIcon
56ad9e ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P",
3cf8ac ¤   ¤   "Uninstall "+ APP_NAME,szProgram,szAppPath,"",0,"",REPLACE);
b8af5a
1210d1 ¤   ¤   /**********************
41a4ca ¤   ¤   szProgram = TARGETDIR ^ "Documentation" ^ "whatsnew.doc";
--0435 00033e7284340110222 Page 38 of setup.rul
9a054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
4f1281 ¤   ¤   szAppPath = TARGETDIR ^ "Documentation";
876d08 ¤   ¤   AddFolderIcon
a10ead ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation",
48445c ¤   ¤   "What's New in "+ APP_NAME,szProgram,szAppPath,"",0,"",REPLACE);
b0af5a
635614 ········szProgram = TARGETDIR ^ "Documentation" ^ "6.0.2 Change History.txt";
41054b ¤   ¤   LongPathToQuote (szProgram,TRUE);
f61281 ¤   ¤   szAppPath = TARGETDIR ^ "Documentation";
086d08 ¤   ¤   AddFolderIcon
800ead ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation",
1dce57 ¤   ¤   "6.0.2 Change History", szProgram, szAppPath, "", 0, "", REPLACE);
242d13 ········**********************/
47eb6d ¤   endif;
9aaf5a
c874d4 ¤   if (INCLUDEPGPDISK = "TRUE") then
fa1371 ¤   ¤   if (ComponentIsItemSelected
6ec8c9 ¤   ¤   ¤   (szComponents,"PGPdisk for Windows") = TRUE) then
37016c ¤   ¤   ¤   szProgram = TARGETDIR ^ "PGPdisk.exe";
7e3c8e ¤   ¤   ¤   LongPathToQuote (szProgram,TRUE);
c07f52 ¤   ¤   ¤   szAppPath = TARGETDIR;
e4aabd ¤   ¤   ¤   AddFolderIcon
cb039f ¤   ¤   ¤   (FOLDER_STARTMENU ^ "Programs" ^ "P G P",
eaf1a0 ¤   ¤   ¤   "PGPdisk",szProgram,szAppPath,"",0,"",REPLACE);
0c8ad7 ¤   ¤   endif;
50eb6d ¤   endif;
49af5a
540efd ¤   SetStatusWindow
dba605 ¤   (45,"Updating the Registry...");
d2af5a
717ede ¤   nvType = REGDB_STRING;
3118d9 ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
b0af5a
7fbb78 ¤   if (RegDBGetKeyValueEx("Software\\PGP\\PNDetect\\Modules","PGP Plugin"
ec36d7 ¤   ,nvType,szEudoraPath,nvPathLen) = 0) then
68e068 ¤   ¤   if (bEasyInstall = FALSE) then
ac6db3 ¤   ¤   ¤   // ask if they want to remove the 4.5 plugin
3ba26f ¤   ¤   ¤   SetDialogTitle
a88666 ¤   ¤   ¤   (DLG_ASK_YESNO,"Disable the PGPmail 4.5 Eudora/Netscape Plugin?");
b35e13 ¤   ¤   ¤   if (AskYesNo
74b3c2 ¤   ¤   ¤   ("Do you wish to disable the PGPmail 4.5 Eudora/Netscape Plugin?"
06418a ¤   ¤   ¤   ,YES) = YES) then
79fba1 ¤   ¤   ¤   ¤   RegDBDeleteValue
9703ad ¤   ¤   ¤   ¤   ("Software\\PGP\\PNDetect\\Modules","PGP Plugin");
416874 ¤   ¤   ¤   endif;
e60e1d ¤   ¤   else
a340f7 ¤   ¤   ¤   RegDBDeleteValue
798e51 ¤   ¤   ¤   ("Software\\PGP\\PNDetect\\Modules","PGP Plugin");
918ad7 ¤   ¤   endif;
64eb6d ¤   endif;
e9af5a
ecb976 ¤   svDir = TARGETDIR;
098b39 ¤   LongPathToShortPath (svDir);
59af5a
79af5a
450efd ¤   SetStatusWindow
5dd167 ¤   (55,"Updating the Registry...");
97af5a
e29ba7 if (INCLUDEPGPDISK = "TRUE") then
56dd47 ····// Set PGPdisk to automatically run at start up and convert old volumes
05c86e ····if (nFND_PGPDISK = TRUE) then
08e5b7 ¤   ¤   if (ComponentIsItemSelected (szComponents,¤ "PGPdisk for Windows") = TR¶
591695 UE) then
4f6b23 ············RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
f9af5a
34886a ············szKey ··= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
007988 ············szName ·= "PGPdisk";
5f4154 ············nType ··= REGDB_STRING;
c8fb07 ············szValue = TARGETDIR ^ "PGPdisk.exe globalconvert";
1a3182 ············RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
fc88e0 ········endif;
330eff ····endif;
--7af5 0009d08f60440110222 Page 39 of setup.rul
e0af5a
17988d ¤   if (ComponentIsItemSelected
762ac9 ¤   ¤   (szComponents,"PGPdisk for Windows") = TRUE) then
23957b ¤   ¤   //*******************************************¤
bcffd7 ¤   ¤   //SETTING WINDOWS 95 SPECIFIC REGISTRY VALUES·
2768b9 ¤   ¤   //****HKEY_LOCAL_MACHINE****
14b6ff ¤   ¤   //*******************************************
6d3e27 ¤   ¤   if (IS_NT = FALSE) then
7c87c7 ¤   ¤   ¤
60335f ¤   ¤   ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
19af5a
716ae7 ¤   ¤   ¤   for IndexNumber = 1 to 26
e886b3 ¤   ¤   ¤   ¤   switch (IndexNumber)
a6a3e1 ¤   ¤   ¤   ¤   ¤   case 1:
84bbe8 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000000";
0a4c85 ¤   ¤   ¤   ¤   ¤   case 2:
80b0ac ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000010";
641659 ¤   ¤   ¤   ¤   ¤   case 3:
97ad60 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000020";
8c9a5c ¤   ¤   ¤   ¤   ¤   case 4:
96a624 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000030";
9fc080 ¤   ¤   ¤   ¤   ¤   case 5:
3796f8 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000040";
032fe4 ¤   ¤   ¤   ¤   ¤   case 6:
7a9dbc ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000050";
e07538 ¤   ¤   ¤   ¤   ¤   case 7:
768070 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000060";
da3fff ¤   ¤   ¤   ¤   ¤   case 8:
818b34 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000070";
b76523 ¤   ¤   ¤   ¤   ¤   case 9:
9de1c8 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000080";
6f9ca6 ¤   ¤   ¤   ¤   ¤   case 10:
803020 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&000090"; ··
fcc67a ¤   ¤   ¤   ¤   ¤   case 11:
f6f740 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000:0";
fb291e ¤   ¤   ¤   ¤   ¤   case 12:
35fc04 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000;0";
f473c2 ¤   ¤   ¤   ¤   ¤   case 13:
3fccd8 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000<0";
d0ffc7 ¤   ¤   ¤   ¤   ¤   case 14:
a6c79c ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000=0";
1fa51b ¤   ¤   ¤   ¤   ¤   case 15:
01da50 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000>0";
1c4a7f ¤   ¤   ¤   ¤   ¤   case 16:
4ad114 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000?0";
ba10a3 ¤   ¤   ¤   ¤   ¤   case 17:
42ae1b ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000@0";
225a64 ¤   ¤   ¤   ¤   ¤   case 18:
53a55f ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000A0";
6d00b8 ¤   ¤   ¤   ¤   ¤   case 19:
57b893 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000B0";
42b96b ¤   ¤   ¤   ¤   ¤   case 20:
98b3d7 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000C0";
d1e3b7 ¤   ¤   ¤   ¤   ¤   case 21:
cd830b ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000D0";
f40cd3 ¤   ¤   ¤   ¤   ¤   case 22:
a1884f ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000E0";
21560f ¤   ¤   ¤   ¤   ¤   case 23:
629583 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000F0";
49da0a ¤   ¤   ¤   ¤   ¤   case 24:
dc9ec7 ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000G0";
d280d6 ¤   ¤   ¤   ¤   ¤   case 25:
bbf43b ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000H0";
fb6fb2 ¤   ¤   ¤   ¤   ¤   case 26:
9dff7f ¤   ¤   ¤   ¤   ¤   ¤   KeyStub = "ROOT&PGPDISK&0000I0";
f5e0fa ¤   ¤   ¤   ¤   endswitch;
6eaf5a
e90f59 ¤   ¤   ¤   ¤   szKey = "Enum\\ESDI\\PGP_____PGPDISK_________0" ^ KeyStub;
a287c7 ¤   ¤   ¤
5f8b14 ¤   ¤   ¤   ¤   szName = "Capabilities";
ad9ea7 ¤   ¤   ¤   ¤   nType = REGDB_BINARY;
9d27a9 ¤   ¤   ¤   ¤   szValue = "";
--cdc1 0000cd030da40110222 Page 40 of setup.rul
b5753a ¤   ¤   ¤   ¤   for Index = 0 to 3
b25a2a ¤   ¤   ¤   ¤   ¤   AsciNum = 0;
2a10af ¤   ¤   ¤   ¤   ¤   if (Index = 0) then
9e3d9e ¤   ¤   ¤   ¤   ¤   ¤   AsciNum = 1;
4fb17c ¤   ¤   ¤   ¤   ¤   endif;
5c9110 ¤   ¤   ¤   ¤   ¤   if (Index = 1) then
a4372d ¤   ¤   ¤   ¤   ¤   ¤   AsciNum = 14;
40b17c ¤   ¤   ¤   ¤   ¤   endif;
237474 ¤   ¤   ¤   ¤   ¤   SetByte (szValue, Index, AsciNum);
fb46e8 ¤   ¤   ¤   ¤   endfor;
c612a1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, 4);
ddaf5a
b24ef1 ¤   ¤   ¤   ¤   szName = "ConfigFlags";
169ea7 ¤   ¤   ¤   ¤   nType = REGDB_BINARY;
7827a9 ¤   ¤   ¤   ¤   szValue = "";
e0753a ¤   ¤   ¤   ¤   for Index = 0 to 3
975a2a ¤   ¤   ¤   ¤   ¤   AsciNum = 0;
8f7474 ¤   ¤   ¤   ¤   ¤   SetByte (szValue, Index, AsciNum);
3746e8 ¤   ¤   ¤   ¤   endfor;
d412a1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, 4);
84af5a
2ae375 ¤   ¤   ¤   ¤   szName = "DeviceType";
2f9ea7 ¤   ¤   ¤   ¤   nType = REGDB_BINARY;
7d27a9 ¤   ¤   ¤   ¤   szValue = "";
e77e0d ¤   ¤   ¤   ¤   Index = 0;
c5e17c ¤   ¤   ¤   ¤   AsciNum = 0;
cb6553 ¤   ¤   ¤   ¤   SetByte (szValue, Index, AsciNum);
4b12a1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, 4);
bcaf5a
df6ee9 ¤   ¤   ¤   ¤   szName = "RevisionLevel";
5b3799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
16f8d4 ¤   ¤   ¤   ¤   szValue = "0001";
6b47c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
56af5a
d31625 ¤   ¤   ¤   ¤   szName = "ProductId";
033799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
ad2b5a ¤   ¤   ¤   ¤   szValue = "PGPdisk ········";
3b47c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
f7af5a
54b479 ¤   ¤   ¤   ¤   szName = "Manufacturer";
093799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
dc67a6 ¤   ¤   ¤   ¤   szValue = "PGP ····";
9147c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
9daf5a
3d7653 ¤   ¤   ¤   ¤   szName = "CurrentDriveLetterAssignment";
513799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
e927a9 ¤   ¤   ¤   ¤   szValue = "";
3347c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
a787c7 ¤   ¤   ¤
a6fee0 ¤   ¤   ¤   ¤   szName = "HardwareID";
303799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
282076 ¤   ¤   ¤   ¤   szValue = "PGP_____PGPDISK_________0,GenDisk,ESDI\\PGP_____PGPD¶
0ec0db ISK_________0";
bb47c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
3baf5a
bfa67e ¤   ¤   ¤   ¤   szName = "Class";
d43799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
07f04c ¤   ¤   ¤   ¤   szValue = "DiskDrive";
4f47c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
4caf5a
6591c6 ¤   ¤   ¤   ¤   szName = "Driver";
b03799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
84fdaa ¤   ¤   ¤   ¤   szValue = "DiskDrive\\0000";
bc47c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
eeaf5a
9325e7 ¤   ¤   ¤   ¤   szName = "Mfg";
fe3799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
62b60b ¤   ¤   ¤   ¤   szValue = "(Standard disk drives)";
db47c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
adaf5a
1b73ae ¤   ¤   ¤   ¤   szName = "DeviceDesc";
0c3799 ¤   ¤   ¤   ¤   nType = REGDB_STRING;
--2a4f 0003b0c704440110222 Page 41 of setup.rul
76feb7 ¤   ¤   ¤   ¤   szValue = "PGP PGPdisk ········";
8747c1 ¤   ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
463c1c ¤   ¤   ¤   endfor;
951b52 ¤   ¤
10635e ¤   ¤   ¤   szKey = "Enum\\Root\\PGPdisk\\0000";
e2af5a
be9176 ¤   ¤   ¤   szName = "Class";
56d8ea ¤   ¤   ¤   nType = REGDB_STRING;
f0b23b ¤   ¤   ¤   szValue = "PGPdisk";
be09b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
5faf5a
6b8ba4 ¤   ¤   ¤   szName = "ConfigFlags";
e471d4 ¤   ¤   ¤   nType = REGDB_BINARY;
f3aefd ¤   ¤   ¤   szValue = "";
b6f945 ¤   ¤   ¤   for Index = 0 to 3
11e17c ¤   ¤   ¤   ¤   AsciNum = 0;
20d5fa ¤   ¤   ¤   ¤   if (Index = 0) then
de394b ¤   ¤   ¤   ¤   ¤   AsciNum = 4;
fa539d ¤   ¤   ¤   ¤   endif;
c16553 ¤   ¤   ¤   ¤   SetByte (szValue, Index, AsciNum);
f03c1c ¤   ¤   ¤   endfor;
47012d ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, 4);
d2af5a
6d325d ¤   ¤   ¤   szName = "DeviceDesc";
19d8ea ¤   ¤   ¤   nType = REGDB_STRING;
2e56ed ¤   ¤   ¤   szValue = "PGPdisk Volume Driver";
1409b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
1aaf5a
021db9 ¤   ¤   ¤   szName = "Driver";
fcd8ea ¤   ¤   ¤   nType = REGDB_STRING;
f9f3d0 ¤   ¤   ¤   szValue = "PGPdisk\\0000";
8f09b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
25af5a
9f883b ¤   ¤   ¤   szName = "ForcedConfig";
9871d4 ¤   ¤   ¤   nType = REGDB_BINARY;
a0aefd ¤   ¤   ¤   szValue = "";
405db8 ¤   ¤   ¤   for Index = 0 to 11
a2e17c ¤   ¤   ¤   ¤   AsciNum = 0;
9d5445 ¤   ¤   ¤   ¤   if (Index = 1) then
ec394b ¤   ¤   ¤   ¤   ¤   AsciNum = 4;
f7539d ¤   ¤   ¤   ¤   endif;
2b6553 ¤   ¤   ¤   ¤   SetByte (szValue, Index, AsciNum);
233c1c ¤   ¤   ¤   endfor;
41ef0b ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, 12);
fcaf5a
a9bf13 ¤   ¤   ¤   szName = "HardwareID";
0dd8ea ¤   ¤   ¤   nType = REGDB_STRING;
1260c9 ¤   ¤   ¤   szValue = "*PGPdisk";
b509b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
8baf5a
f788b9 ¤   ¤   ¤   szName = "Mfg";
b6d8ea ¤   ¤   ¤   nType = REGDB_STRING;
2b68ea ¤   ¤   ¤   szValue = "Network Associates, Inc.";
2209b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
021b52 ¤   ¤
83a32d ¤   ¤   ¤   szKey = "Enum\\Root\\PGPdisk\\0000\\LogConfig";
82af5a
6c905c ¤   ¤   ¤   szName = "0";
f471d4 ¤   ¤   ¤   nType = REGDB_BINARY;
90aefd ¤   ¤   ¤   szValue = "";
e45db8 ¤   ¤   ¤   for Index = 0 to 11
23e17c ¤   ¤   ¤   ¤   AsciNum = 0;
105445 ¤   ¤   ¤   ¤   if (Index = 1) then
a2394b ¤   ¤   ¤   ¤   ¤   AsciNum = 4;
7e539d ¤   ¤   ¤   ¤   endif;
70429b ¤   ¤   ¤   ¤   if (Index = 5) then
c0a792 ¤   ¤   ¤   ¤   ¤   AsciNum = 224;
db539d ¤   ¤   ¤   ¤   endif;
216553 ¤   ¤   ¤   ¤   SetByte (szValue, Index, AsciNum);
733c1c ¤   ¤   ¤   endfor;
6fef0b ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, 12);
3b1b52 ¤   ¤
--e893 00073b56d3240110222 Page 42 of setup.rul
c7849f ¤   ¤   ¤   szKey = "System\\CurrentControlSet\\Services\\Class\\PGPdisk";
61af5a
1da770 ¤   ¤   ¤   szName = "";
15d8ea ¤   ¤   ¤   nType = REGDB_STRING;
a856ed ¤   ¤   ¤   szValue = "PGPdisk Volume Driver";
ae09b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
78af5a
ef913b ¤   ¤   ¤   szName = "Icon";
40d8ea ¤   ¤   ¤   nType = REGDB_STRING;
a1eb27 ¤   ¤   ¤   szValue = "-9";
2609b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
c91b52 ¤   ¤
2baf5a
e78cf7 ¤   ¤   ¤   szKey = "System\\CurrentControlSet\\Services\\Class\\PGPdisk\\0000";
25af5a
eab0ce ¤   ¤   ¤   szName = "DevLoader";
16d8ea ¤   ¤   ¤   nType = REGDB_STRING;
26acad ¤   ¤   ¤   szValue = "*IOS";
be09b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
ebaf5a
6ad4f3 ¤   ¤   ¤   szName = "DriverDesc";
b6d8ea ¤   ¤   ¤   nType = REGDB_STRING;
5356ed ¤   ¤   ¤   szValue = "PGPdisk Volume Driver";
e009b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
e7af5a
d38595 ¤   ¤   ¤   szName = "PortDriver";
7fd8ea ¤   ¤   ¤   nType = REGDB_STRING;
2aca6e ¤   ¤   ¤   szValue = "PGPDISK.pdr";
3809b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
deaf5a
d77044 ¤   ¤   //*************************************
e78fa1 ¤   ¤   else //IS_NT SO SET NT SPECIFIC ENTRIES
397044 ¤   ¤   //*************************************
906d54 ¤   ¤   ¤   //****HKEY_LOCAL_MACHINE****
2f335f ¤   ¤   ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
6bb0b5 ¤   ¤   ¤   szKey = "System\\CurrentControlSet\\Services\\PGPdisk";
6487c7 ¤   ¤   ¤
377faa ¤   ¤   ¤   szName = "Type";
64e272 ¤   ¤   ¤   nType = REGDB_NUMBER;
39d303 ¤   ¤   ¤   szValue = "1";
1909b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
a8af5a
e1fd4e ¤   ¤   ¤   szName = "Start";
9ce272 ¤   ¤   ¤   nType = REGDB_NUMBER;
adf6ce ¤   ¤   ¤   szValue = "2";
6509b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
2baf5a
4e917d ¤   ¤   ¤   szName = "ErrorControl";
89e272 ¤   ¤   ¤   nType = REGDB_NUMBER;
02d303 ¤   ¤   ¤   szValue = "1";
a109b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
89af5a
2693b7 ¤   ¤   ¤   szName = "Group";
65d8ea ¤   ¤   ¤   nType = REGDB_STRING;
66faa7 ¤   ¤   ¤   szValue = "Extended Base";
5209b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
34af5a
7bf0e0 ¤   ¤   ¤   szKey = "System\\CurrentControlSet\\Services\\EventLog\\System\\PGP¶
5d732c disk";
44af5a
289f41 ¤   ¤   ¤   szName = "EventMessageFile";
d7d8ea ¤   ¤   ¤   nType = REGDB_STRING;
84fa2e ¤   ¤   ¤   szValue = WINSYSDIR ^ "Drivers" ^ "PGPdisk.sys";
f909b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
57af5a
948a4c ¤   ¤   ¤   szName = "TypesSupprted";
45e272 ¤   ¤   ¤   nType = REGDB_NUMBER;
819899 ¤   ¤   ¤   szValue = "7";
0909b6 ¤   ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
488ad7 ¤   ¤   endif;
71af5a
737c32 ¤   ¤   //******************************************************
--7572 000ce225a6240110222 Page 43 of setup.rul
d111c6 ¤   ¤   //SETTING WINDOWS 95 / WINDOWS NT COMMON REGISTRY VALUES·
65d8ee ¤   ¤   //****HKEY_CLASSES_ROOT****
177c32 ¤   ¤   //******************************************************
395426 ¤   ¤   RegDBSetDefaultRoot (HKEY_CLASSES_ROOT);
7caf5a
6b80a1 ¤   ¤   szKey = ".pgd";
37af5a
4516a1 ¤   ¤   szName = "";
f9efe2 ¤   ¤   nType = REGDB_STRING;
c30a21 ¤   ¤   szValue = "PGPdisk Volume";
a434d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
c8af5a
bb01dd ¤   ¤   szKey = ".pgd\\ShellNew";
2aaf5a
1ef175 ¤   ¤   szName = "Command";
ecefe2 ¤   ¤   nType = REGDB_STRING;
07dc72 ¤   ¤   LongPathToShortPath (svTarget);
02d072 ¤   ¤   szValue = svTarget ^ "PGPDISK.EXE create \"%2\"";
24af5a
5dc044 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);¤
5eaf5a
89caf2 ¤   ¤   szKey = "PGPdisk Volume";
dfaf5a
9916a1 ¤   ¤   szName = "";
a6efe2 ¤   ¤   nType = REGDB_STRING;
5e0a21 ¤   ¤   szValue = "PGPdisk Volume";
e1c044 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);¤
92af5a
982628 ¤   ¤   szKey = "PGPdisk Volume\\DefaultIcon";
aaaf5a
b616a1 ¤   ¤   szName = "";
c6efe2 ¤   ¤   nType = REGDB_STRING;
ba191b ¤   ¤   szValue = svTarget ^ "PGPDISK.EXE,5";
e734d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
b1af5a
3ca189 ¤   ¤   szKey = "PGPdisk Volume\\shell\\open\\command";
73af5a
bc16a1 ¤   ¤   szName = "";
66efe2 ¤   ¤   nType = REGDB_STRING;
5f1760 ¤   ¤   szValue = svTarget ^ "PGPDISK.EXE open \"%1\"";
e0d70c ¤   ¤   //LongPathToShortPath (szValue);
9034d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
89af5a
086ae1 ¤   ¤   szKey = "CLSID\\{F8B14440-3785-11D1-B363-5C6F08C10000}";
95af5a
f916a1 ¤   ¤   szName = "";
2eefe2 ¤   ¤   nType = REGDB_STRING;
13cbb5 ¤   ¤   szValue = "PGPdisk Shell Extension";
f434d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
ceaf5a
66eb5a ¤   ¤   szKey = "CLSID\\{F8B14440-3785-11D1-B363-5C6F08C10000}\\InProcServer32";
16af5a
1c16a1 ¤   ¤   szName = "";
8fefe2 ¤   ¤   nType = REGDB_STRING;
3fa983 ¤   ¤   szValue = "PGPdskSE.dll";
5134d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
f6af5a
857c82 ¤   ¤   szName = "ThreadingModel";
f7efe2 ¤   ¤   nType = REGDB_STRING;
f92319 ¤   ¤   szValue = "Apartment";
3734d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
3faf5a
178c16 ¤   ¤   szKey = "PGPdisk Volume\\shellex\\ContextMenuHandlers\\PGPdisk Shell Ex¶
3bb394 tension";
08af5a
f916a1 ¤   ¤   szName = "";
f7efe2 ¤   ¤   nType = REGDB_STRING;
be2961 ¤   ¤   szValue = "{F8B14440-3785-11D1-B363-5C6F08C10000}";
5c34d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
1faf5a
436e23 ¤   ¤   //szKey = "Drive\\shellex\\ContextMenuHandlers";
ceaf5a
--4380 0002906925c40110222 Page 44 of setup.rul
67edc6 ¤   ¤   //szName = "";
07f3ad ¤   ¤   //nType = REGDB_STRING;
cb3bbf ¤   ¤   //szValue = "PGPdisk Shell Extension";
8afdd7 ¤   ¤   //RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
c1af5a
f24877 ¤   ¤   szKey = "Drive\\shellex\\ContextMenuHandlers\\PGPdisk Shell Extension";
41af5a
ca16a1 ¤   ¤   szName = "";
88efe2 ¤   ¤   nType = REGDB_STRING;
312961 ¤   ¤   szValue = "{F8B14440-3785-11D1-B363-5C6F08C10000}";
f634d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
c5af5a
cb68b9 ¤   ¤   //****HKEY_LOCAL_MACHINE****
a89d5e ¤   ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
32af5a
5a5829 ¤   ¤   szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions¶
38d219 \\Approved";
a4af5a
641b95 ¤   ¤   szName = "{F8B14440-3785-11D1-B363-5C6F08C10000}";
b3efe2 ¤   ¤   nType = REGDB_STRING;
dccbb5 ¤   ¤   szValue = "PGPdisk Shell Extension";
5434d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
d1af5a
7bb14d ¤   ¤   //****HKEY_CURRENT_USER****
9401f4 ¤   ¤   RegDBSetDefaultRoot (HKEY_CURRENT_USER);
f2af5a
c7560e ¤   ¤   szKey = "Software\\Network Associates\\PGPdisk";
6aaf5a
f55f24 ¤   ¤   szName = "LastOpenDir";
f6efe2 ¤   ¤   nType = REGDB_STRING;
3671cf ¤   ¤   szValue = "c:\\";
6834d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
ecaf5a
4e4180 ¤   ¤   szName = "LastSaveDir";
a1efe2 ¤   ¤   nType = REGDB_STRING;
2871cf ¤   ¤   szValue = "c:\\";
a934d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
52af5a
e46b1b ¤   ¤   szName = "AllowFAT32";
7ed57a ¤   ¤   nType = REGDB_NUMBER;
6231e2 ¤   ¤   szValue = "1";
4534d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
e2af5a
440d14 ¤   ¤   szName = "AutoUnmount";
bfd57a ¤   ¤   nType = REGDB_NUMBER;
5b31e2 ¤   ¤   szValue = "1";
8c34d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
d2af5a
dc3765 ¤   ¤   szName = "HotKeyCode";
96d57a ¤   ¤   nType = REGDB_NUMBER;
4a6c6b ¤   ¤   szValue = "00000379";
3134d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
ddaf5a
dc61d0 ¤   ¤   szName = "HotKeyEnabled";
26d57a ¤   ¤   nType = REGDB_NUMBER;
5d2d59 ¤   ¤   szValue = "0";
b434d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
85af5a
fbe220 ¤   ¤   szName = "UnmountOnSleep";
44d57a ¤   ¤   nType = REGDB_NUMBER;
bd31e2 ¤   ¤   szValue = "1";
9e34d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
c6af5a
90b7ce ¤   ¤   szName = "UnmountTimeout";
0ad57a ¤   ¤   nType = REGDB_NUMBER;
b74906 ¤   ¤   szValue = "15";
f334d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
04af5a
6aee1b ¤   ¤   szName = "LastCreateSize";
07d57a ¤   ¤   nType = REGDB_NUMBER;
87c343 ¤   ¤   szValue = "00102400";
2934d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
--add8 000a516770540110222 Page 45 of setup.rul
e0af5a
4ae58e ¤   ¤   szName = "LastDateSplashed";
9cd57a ¤   ¤   nType = REGDB_NUMBER;
202c15 ¤   ¤   szValue = "00";
bd34d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
53af5a
7b1d0d ¤   ¤   szName = "WasMainDialogSmall";
58d57a ¤   ¤   nType = REGDB_NUMBER;
cb2c15 ¤   ¤   szValue = "00";
9b34d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
36af5a
bda12a ¤   //¤ szName = "LastCreateInMb";
8bcd1c ¤   //¤ nType = REGDB_NUMBER;
5bccb3 ¤   //¤ szValue = "1";
945057 ¤   //¤ RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
67af5a
756c0b ¤   //¤ szName = "LastCreateName";
fef784 ¤   //¤ nType = REGDB_STRING;
354a12 ¤   //¤ szValue = "Untitled.pgd";
a95057 ¤   //¤ RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
fbaf5a
c5fc6f ¤   //¤ szKey = "SOFTWARE\\PGP\\PGPdisk";
7baf5a
133479 ¤   //¤ szName = "AppPath";
35f784 ¤   //¤ nType = REGDB_STRING;
75dd16 ¤   //¤ szValue = svTarget;
ff5057 ¤   //¤ RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
4caf5a
1468b9 ¤   ¤   //****HKEY_LOCAL_MACHINE****
e89d5e ¤   ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
46af5a
15029e ¤   ¤   szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\PGPdi¶
d9c983 sk.exe";
2016a1 ¤   ¤   szName = "";
f3efe2 ¤   ¤   nType = REGDB_STRING;
9f09ee ¤   ¤   szValue = svTarget ^ "PGPDISK.EXE";
85c75d ¤   ¤   LongPathToShortPath (szValue);
e934d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
89af5a
d5278d ¤   ¤   szName ·= "Path";
087b97 ¤   ¤   nType ··= REGDB_STRING;
245f94 ¤   ¤   szValue = svTarget;
4ec75d ¤   ¤   LongPathToShortPath (szValue);
a234d8 ¤   ¤   RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
f7eb6d ¤   endif;
bd28d5 endif;
47af5a
4daf5a
192c16 ····/**************************************************************************¶
d2391e **********************
dd6657 ·····*
736657 ·····*
0dce54 ·····* ·Write to the registry the components that the user selected to install ¶
ff0223 with this version
076657 ·····*
226657 ·····*
a1780d ·····**************************************************************************¶
d50b17 **********************/
7baf5a
0dc618 ····RegDBSetDefaultRoot (HKEY_CURRENT_USER);
3aaf5a
930999 ····szKey ··= "SOFTWARE\\Network Associates" ^ REGAPP_NAME ^ "Components";
f7869e ····
7db645 ····RegDBCreateKeyEx (szKey, "");
82af5a
cf4e89 ····if (ComponentIsItemSelected¤(szComponents, APP_NAME +" Program Files (Requi¶
b87623 red for PGP 6.x)") = TRUE) then
1177df ········szValue = "1";
09842c ····else
776b64 ········szValue = "0";
c80eff ····endif;
a51ccb ····szName ·= "PGP Core";
--eff5 0000b0a8b9540110222 Page 46 of setup.rul
d7dcc2 ····nType ··= REGDB_NUMBER;
54113b ····RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
87af5a
db80d3 ¤   if (ComponentIsItemSelected¤(szComponents, APP_NAME +" Eudora Plugin") = TR¶
a41695 UE) then
9677df ········szValue = "1";
f8842c ····else
cf6b64 ········szValue = "0";
b70eff ····endif;
c08f13 ····szName ·= "Eudora Plugin";
74dcc2 ····nType ··= REGDB_NUMBER;
93113b ····RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
12af5a
7a694f ¤   if (ComponentIsItemSelected¤(szComponents, APP_NAME +" Microsoft Exchange/O¶
fdef5c utlook Plugin") = TRUE) then
d477df ········szValue = "1";
fa842c ····else
666b64 ········szValue = "0";
1b0eff ····endif;
30f26c ····szName ·= "Microsoft Exchange/Outlook Plugin";
f4dcc2 ····nType ··= REGDB_NUMBER;
91113b ····RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
01af5a
4ed6de ····if (ComponentIsItemSelected¤(szComponents, APP_NAME +" Microsoft Outlook Ex¶
4fc9ac press Plugin") = TRUE) then
ec77df ········szValue = "1";
0e842c ····else
0a6b64 ········szValue = "0";
f20eff ····endif;
851929 ····szName ·= "Microsoft Outlook Express Plugin";
63dcc2 ····nType ··= REGDB_NUMBER;
d5113b ····RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
fbaf5a
89a74b ····if (ComponentIsItemSelected (szComponents, "PGPdisk for Windows") = TRUE) t¶
fb10d3 hen
8b77df ········szValue = "1";
86842c ····else
266b64 ········szValue = "0";
770eff ····endif;
abe51b ····szName ·= "PGPdisk for Windows";
34dcc2 ····nType ··= REGDB_NUMBER;
42113b ····RegDBSetKeyValueEx (szKey, szName, nType, szValue, -1);
35af5a
5daf5a
90af5a
b4ba63 // **** ROOT ****
adaf5a
874d0b ¤   RegDBSetDefaultRoot(HKEY_CLASSES_ROOT);
ffaf5a
860bdf ¤   RegDBSetKeyValueEx
768e7d ¤   ("\\.asc" ,"",REGDB_STRING,"PGP Armored Encrypted File",-1);
390bdf ¤   RegDBSetKeyValueEx
6d6ba1 ¤   ("\\.aexpk" ,"",REGDB_STRING,"PGP Armored Extracted Public Key",-1);
ac0bdf ¤   RegDBSetKeyValueEx
aa6c2c ¤   ("\\.bexpk" ,"",REGDB_STRING,"PGP Binary Extracted Public Key",-1);
3c0bdf ¤   RegDBSetKeyValueEx
d99039 ¤   ("\\.pgp" ,"",REGDB_STRING,"PGP Encrypted File",-1);
f50bdf ¤   RegDBSetKeyValueEx
fafbbd ¤   ("\\.prvkr" ,"",REGDB_STRING,"PGP Private Keyring",-1);
4f0bdf ¤   RegDBSetKeyValueEx
40459b ¤   ("\\.pubkr" ,"",REGDB_STRING,"PGP Public Keyring",-1);
870bdf ¤   RegDBSetKeyValueEx
8c5d6d ¤   ("\\.sig" ,"",REGDB_STRING,"PGP Detached Signature File",-1);
fb0bdf ¤   RegDBSetKeyValueEx
557803 ¤   ("\\.pkr" ,"",REGDB_STRING,"PGP Public Keyring",-1);
ed0bdf ¤   RegDBSetKeyValueEx
43b0d6 ¤   ("\\.skr" ,"",REGDB_STRING,"PGP Private Keyring",-1);
e00bdf ¤   RegDBSetKeyValueEx
36ccfc ¤   ("\\.shf" ,"",REGDB_STRING,"PGP Share",-1);
500bdf ¤   RegDBSetKeyValueEx
b0ccbc ¤   ("\\.rnd" ,"",REGDB_STRING,"PGP Random Seed",-1);
0b0bdf ¤   RegDBSetKeyValueEx
--d566 0008d272fdd40110222 Page 47 of setup.rul
736af7 ¤   ("\\.pgr" ,"",REGDB_STRING,"PGP Groups",-1);
4aaf5a
6ba9fe ¤   szLocalDB = "\\*\\shellex\\ContextMenuHandlers\\" +
a68f1e ¤   "{969223c0-26aa-11d0-90ee-444553540000}";
02af5a
580bdf ¤   RegDBSetKeyValueEx
572a18 ¤   (szLocalDB ,"",REGDB_STRING,"",-1);
a6af5a
62f264 ¤   szLocalDB = "\\Folder\\shellex\\ContextMenuHandlers\\" +
d86d56 ¤   ¤   ¤   ¤   "{969223c0-26aa-11d0-90ee-444553540000}";
32af5a
890bdf ¤   RegDBSetKeyValueEx
b02a18 ¤   (szLocalDB ,"",REGDB_STRING,"",-1);
699e69 ¤   szLocalDB = "\\CLSID\\{969223c0-26aa-11d0-90ee-444553540000}";
c70bdf ¤   RegDBSetKeyValueEx
b71de2 ¤   (szLocalDB ,"",REGDB_STRING,"PGP Shell Extension",-1);
220bdf ¤   RegDBSetKeyValueEx
d3945d ¤   (szLocalDB ^ "InProcServer32","" ,
45d493 ¤   REGDB_STRING,"pgp60mn.dll",-1);
bb0bdf ¤   RegDBSetKeyValueEx
7de1b4 ¤   (szLocalDB ^"InProcServer32","ThreadingModel" ,
707d56 ¤   REGDB_STRING,"Apartment",-1);
84af5a
1be0cd //FILE ASSOCIATED ICONS
66fa81 ¤   szLocalDB = "\\PGP Encrypted File";
780bdf ¤   RegDBSetKeyValueEx
392141 ¤   (szLocalDB,"",
acda7c ¤   REGDB_STRING,"PGP Encrypted File",-1);
920bdf ¤   RegDBSetKeyValueEx
eb9f58 ¤   ("\\PGP Encrypted File" ^ "DefaultIcon","",
4ff5ef ¤   REGDB_STRING,"pgp60sc.dll,-144",-1);
e00bdf ¤   RegDBSetKeyValueEx
c62a27 ¤   ("\\PGP Armored Encrypted File","",
afe995 ····REGDB_STRING,"PGP Armored Encrypted File",-1);
6d0bdf ¤   RegDBSetKeyValueEx
809cef ¤   ("\\PGP Armored Encrypted File" ^ "DefaultIcon" ,"",
e469e1 ¤   REGDB_STRING,"pgp60sc.dll,-143",-1);
af0bdf ¤   RegDBSetKeyValueEx
f55f65 ¤   ("\\PGP Armored Extracted Public Key","",
98e9d3 ¤   REGDB_STRING,"PGP Armored Extracted Public Key",-1);
110bdf ¤   RegDBSetKeyValueEx
a7458c ¤   ("\\PGP Armored Extracted Public Key" ^ "DefaultIcon" ,"",
b67f3f ¤   REGDB_STRING,"pgp60sc.dll,-147",-1);
8f0bdf ¤   RegDBSetKeyValueEx
919250 ¤   ("\\PGP Binary Extracted Public Key","",
e093c1 ¤   REGDB_STRING,"PGP Binary Extracted Public Key",-1);
0b0bdf ¤   RegDBSetKeyValueEx
79483d ¤   ("\\PGP Binary Extracted Public Key" ^ "DefaultIcon" ,"",
027f3f ¤   REGDB_STRING,"pgp60sc.dll,-147",-1);
c40bdf ¤   RegDBSetKeyValueEx
72ab56 ¤   ("\\PGP Detached Signature File","",
d1a7e7 ¤   REGDB_STRING,"PGP Detached Signature File",-1);
ce0bdf ¤   RegDBSetKeyValueEx
f21c42 ¤   ("\\PGP Detached Signature File" ^ "DefaultIcon" ,"",
7fe85e ¤   REGDB_STRING,"pgp60sc.dll,-142",-1);
f90bdf ¤   RegDBSetKeyValueEx
84211c ¤   ("\\PGP Private Keyring","",
1583e1 ¤   REGDB_STRING,"PGP Private Keyring",-1);
3a0bdf ¤   RegDBSetKeyValueEx
cbff40 ¤   ("\\PGP Private Keyring" ^ "DefaultIcon" ,"",
f97450 ¤   REGDB_STRING,"pgp60sc.dll,-145",-1);
950bdf ¤   RegDBSetKeyValueEx
0d216c ¤   ("\\PGP Public Keyring","",REGDB_STRING,"PGP Public Keyring",-1);
390bdf ¤   RegDBSetKeyValueEx
166b82 ¤   ("\\PGP Public Keyring" ^ "DefaultIcon" ,"",
9ffe80 ¤   REGDB_STRING,"pgp60sc.dll,-146",-1);
430bdf ¤   RegDBSetKeyValueEx
4221d2 ¤   ("\\PGP Share","",REGDB_STRING,"PGP Share",-1);
300bdf ¤   RegDBSetKeyValueEx
825eaf ¤   ("\\PGP Share" ^ "DefaultIcon" ,"",
bf40da ¤   REGDB_STRING,"pgp60sc.dll,-107",-1);
8d0bdf ¤   RegDBSetKeyValueEx
--9150 000100d561e40110222 Page 48 of setup.rul
864516 ¤   ("\\Randseed File","",REGDB_STRING,"Randseed File",-1);
d20bdf ¤   RegDBSetKeyValueEx
4f7004 ¤   ("\\Randseed File" ^ "DefaultIcon" ,"",
ccce8d ¤   REGDB_STRING,"pgp60sc.dll,-148",-1);
6f0bdf ¤   RegDBSetKeyValueEx
fb7fa7 ¤   ("\\PGP Groups","",REGDB_STRING,"PGP Groups",-1);
9c0bdf ¤   RegDBSetKeyValueEx
ebe71e ¤   ("\\PGP Groups" ^ "DefaultIcon" ,"",
064f32 ¤   REGDB_STRING,"pgp60sc.dll,-149",-1);
b3af5a
ab0efd ¤   SetStatusWindow
0648c1 ¤   (65,"Updating the Registry...");
5baf5a
f09412 // **** CURRENT USER ****
7faf5a
9818d9 ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
0852df ¤   szLocalDB = "\\Software" ^ COMPANY_FOLDER_NAME;
571927 ¤   LongPathToShortPath (svTarget);
cf1618 ¤   // add "where is keys" key value
3eb865 ¤   RegDBCreateKeyEx
9cb2f5 ¤   ( szLocalDB ^ REGAPP_NAME ^ "PGPkeys","");
c50bdf ¤   RegDBSetKeyValueEx
b219fa ¤   (szLocalDB ^ REGAPP_NAME ^ "PGPkeys","ExePath",REGDB_STRING,
5fe9ab ¤   svTarget ·^ ·"PGPkeys.exe" ,-1);
ccaf5a
f45e96 ¤   if (ISADMIN = "TRUE") then
eae93e ¤   ¤   RegDBSetKeyValueEx
71bf84 ¤   ¤   (szLocalDB ^ REGAPP_NAME ^ "PGPkeys","AdminPath",REGDB_STRING,
3e5599 ¤   ¤   svTarget ,-1);
c5eb6d ¤   endif;
0caf5a
7c988d ¤   if (ComponentIsItemSelected
6e70eb ¤   (szComponents,APP_NAME +" Eudora Plugin") = TRUE) then
b46f00 ¤   ¤   LongPathFromShortPath (EudoraPluginPath);
f3ddec ¤   ¤   // add "where is EudoraPlugin" key value
5e09b4 ¤   ¤   RegDBCreateKeyEx
1cf298 ¤   ¤   ( szLocalDB ^ REGAPP_NAME ^ "EudoraPlugin","");
dbe93e ¤   ¤   RegDBSetKeyValueEx
cfa0ba ¤   ¤   (szLocalDB ^ REGAPP_NAME ^ "EudoraPlugin","PluginPath",REGDB_STRING,
ee0af7 ¤   ¤   EudoraPluginPath,-1);
60eb6d ¤   endif;
0baf5a
9f988d ¤   if (ComponentIsItemSelected
983625 ¤   ¤   (szComponents,APP_NAME +" Microsoft Outlook Express Plugin") = TRUE) th¶
f76cef en
0c0089 ¤   ¤   RegDBSetDefaultRoot(HKEY_CURRENT_USER);
ba0cdc ¤   ¤   RegDBSetKeyValueEx (szLocalDB ^ REGAPP_NAME ^ "OE",
be9630 ¤   ¤   ¤   ¤   ·"OutlookExpress", REGDB_STRING, szOEdir, -1);
3deb6d ¤   endif;
caaf5a
7467a0 ¤   RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
1faf5a
a70bdf ¤   RegDBSetKeyValueEx
d10b49 ¤   ("\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\" +
3222a1 ¤   "Approved","{969223c0-26aa-11d0-90ee-444553540000}"
cdc48d ¤   ,REGDB_STRING,"Shell Extension",-1);
d4af5a
3baf5a
a39a5a if (IS_QUALCOMM_BUILD = "FALSE") then
20988d ¤   if (ComponentIsItemSelected
c1d843 ¤   ¤   (szComponents,APP_NAME +" Microsoft Exchange/Outlook Plugin") = TRUE) t¶
b010d3 hen
6f09b4 ¤   ¤   RegDBCreateKeyEx
959f57 ¤   ¤   ( "SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions\\PGP Plugin","");
26e93e ¤   ¤   RegDBSetKeyValueEx
e02510 ¤   ¤   ¤   ("SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions","PGP Plugin"
77e57a ¤   ¤   ¤   ,REGDB_STRING,"4.0;pgpExch.dll;1;01000111111100;1001110" ,-1);
52eb6d ¤   endif;
b828d5 endif;
e0af5a
250efd ¤   SetStatusWindow
103fa3 ¤   (75,"Updating the Registry...");
--b216 000752d809040110222 Page 49 of setup.rul
e0af5a
62f47f //**** Left Click and Launch ****
12af5a
a64d0b ¤   RegDBSetDefaultRoot(HKEY_CLASSES_ROOT);
f6af5a
7db865 ¤   RegDBCreateKeyEx
6257ff ¤   ("\\PGP Encrypted File" ^ "shell\\open\\command","");
3b0bdf ¤   RegDBSetKeyValueEx
6cf68c ¤   ("\\PGP Encrypted File" ^ "shell\\open\\command" ,"",
6d94e6 ¤   REGDB_STRING,svDir ^ "pgptools.exe %1",-1);
48b865 ¤   RegDBCreateKeyEx
a74bb7 ¤   ("\\PGP Armored Encrypted File" ^ "shell\\open\\command","");
b40bdf ¤   RegDBSetKeyValueEx
c8eac4 ¤   ("\\PGP Armored Encrypted File" ^ "shell\\open\\command" ,"",
3694e6 ¤   REGDB_STRING,svDir ^ "pgptools.exe %1",-1);
3bb865 ¤   RegDBCreateKeyEx
bcd582 ¤   ("\\PGP Armored Extracted Public Key" ^ "shell\\open\\command","");
4b0bdf ¤   RegDBSetKeyValueEx
ba74f1 ¤   ("\\PGP Armored Extracted Public Key" ^ "shell\\open\\command" ,"",
56008d ¤   REGDB_STRING,svDir ^ "pgpkeys.exe %1",-1);
ddb865 ¤   RegDBCreateKeyEx
63eed8 ¤   ("\\PGP Binary Extracted Public Key" ^ "shell\\open\\command","");
6e0bdf ¤   RegDBSetKeyValueEx
b44fab ¤   ("\\PGP Binary Extracted Public Key" ^ "shell\\open\\command" ,"",
00008d ¤   REGDB_STRING,svDir ^ "pgpkeys.exe %1",-1);
9bb865 ¤   RegDBCreateKeyEx
4bb7a0 ¤   ("\\PGP Private Keyring" ^ "shell\\open\\command","");
280bdf ¤   RegDBSetKeyValueEx
cd16d3 ¤   ("\\PGP Private Keyring" ^ "shell\\open\\command" ,"",
2b008d ¤   REGDB_STRING,svDir ^ "pgpkeys.exe %1",-1);
b6b865 ¤   RegDBCreateKeyEx
5088aa ¤   ("\\PGP Public Keyring" ^ "shell\\open\\command","");
a60bdf ¤   RegDBSetKeyValueEx
b029d9 ¤   ("\\PGP Public Keyring" ^ "shell\\open\\command" ,"",
c1008d ¤   REGDB_STRING,svDir ^ "pgpkeys.exe %1",-1);
c6b865 ¤   RegDBCreateKeyEx
39be69 ¤   ("\\PGP Detached Signature File" ^ "shell\\open\\command","");
770bdf ¤   RegDBSetKeyValueEx
b81f1a ¤   ("\\PGP Detached Signature File" ^ "shell\\open\\command" ,"",
7e94e6 ¤   REGDB_STRING,svDir ^ "pgptools.exe %1",-1);
6bb865 ¤   RegDBCreateKeyEx
8eb7a0 ¤   ("\\PGP Private Keyring" ^ "shell\\open\\command","");
da0bdf ¤   RegDBSetKeyValueEx
8b16d3 ¤   ("\\PGP Private Keyring" ^ "shell\\open\\command" ,"",
37008d ¤   REGDB_STRING,svDir ^ "pgpkeys.exe %1",-1);
c4b865 ¤   RegDBCreateKeyEx
e988aa ¤   ("\\PGP Public Keyring" ^ "shell\\open\\command","");
f00bdf ¤   RegDBSetKeyValueEx
d229d9 ¤   ("\\PGP Public Keyring" ^ "shell\\open\\command" ,"",
bf008d ¤   REGDB_STRING,svDir ^ "pgpkeys.exe %1",-1);
a1b865 ¤   RegDBCreateKeyEx
bf08a8 ¤   ("\\PGP Share" ^ "shell\\open\\command","");
ea0bdf ¤   RegDBSetKeyValueEx
e4a9db ¤   ("\\PGP Share" ^ "shell\\open\\command" ,"",
8c94e6 ¤   REGDB_STRING,svDir ^ "pgptools.exe %1",-1);
87af5a
8d152b ¤   Delay(1);
65af5a
e00efd ¤   SetStatusWindow
b29019 ¤   (100,"Installation complete,Thank you for installing " + APP_NAME);
42bfc4 ¤   Disable(STATUSDLG);
4f2eea ····// Remove the bitmap with ID of 14.
91fcf5 ····PlaceBitmap("",12,0,0,REMOVE);
66af5a
87af5a
520139 ¤   //Remove any PGPmail dir from startup·
bb88df ¤   szProgram = TARGETDIR ^ "pgp" ^ "PgpMail.exe";
8839a5 ¤   LongPathToQuote (szProgram,TRUE);
bcd44d ¤   DeleteFolderIcon(FOLDER_STARTUP,"pgpmail");
a7af5a
91af5a
7567c5 ¤
--0610 0009b2883b540110222 Page 50 of setup.rul
80d98e ¤   //Delete the .GID file so help can be updated
2c0620 ¤   DeleteFile ("pgp50.gid");
9baf5a
d0af5a
ab332d ¤   // Announce setup complete,and offer to read README file
a58c97 ¤   // also delete registry entries left behind by PGPmail 4.5
019789 ¤   // this is done at the end in case of install cancel
32af5a
9fd586 ¤   //This is the call to comdlg to set the user info
9caf5a
b4804f ¤   nResult = UseDLL(WINSYSDIR + "pgp60cl.dll");
4d4dcc ¤   Delay (1);
4daf5a
8a7d47 ¤   if ((ISADMIN != "FALSE") || (PGP_FREEWARE = "TRUE")) then
20161e ¤   ¤   nResult = PGPclSetUserInfo (szUser,szUserCompany,"");
a20e24 ¤   else
a4ec66 ¤   ¤   if (szUserCompany != "") then
20f0f6 ¤   ¤   ¤   nResult = PGPclSetUserInfo ("",szUserCompany,"");
628ad7 ¤   ¤   endif;
d2eb6d ¤   endif;
5eaf5a
674dcc ¤   Delay (1);
9daf5a
6ff298 ¤   //Set Default keyring info.
f1e4b3 ¤   szPubRingPath¤  = svTarget ^ "PGP Keyrings\\pubring.pkr";
b7ada3 ¤   szPrivRingPath¤ = svTarget ^ "PGP Keyrings\\secring.skr";
241e27 ¤   szRandSeedPath¤ = WINDIR ^ "randseed.rnd";
33af5a
f4c2e4 ¤   //PGPclSetSDKFilePaths(szPubRingPath, szPrivRingPath, szRandSeedPath, 1);
c0af5a
bcf6d4 ¤   //Set Keyring Locations if needed
228105 ¤   svCopyKeys = "NO";
dda19b ¤   if (bEasyInstall = FALSE) then
09408e ¤   ¤   SetDialogTitle
411d49 ¤   ¤   (DLG_ASK_YESNO,"Existing Keyrings?");
32efc2 ¤   ¤   if (AskYesNo
fca467 ¤   ¤   ¤   ("Do you have existing keyrings you wish to use?",YES) = YES) then
cb1d51 ¤   ¤   ¤   //get main window handle
0c946b ¤   ¤   ¤   hwndIS3 = GetWindowHandle(HWND_INSTALL);
fc8b7d ¤   ¤   //Get new Public ring
7c2a85 ¤   ¤   ¤   szFileFilter = "Public Keyring Files (*.pkr ; pubring.* ; *.pubkr),¶
ac3df4 *.pkr;pubring.pgp;" +
eed48d ¤   ¤   ··············"*.pubkr;,All Files (*.*),*.*";
1aa4ab ¤   ·
981079 ¤   ¤   ¤   // Give the file browse dialog a custom title,if you wish.
f3bf43 ¤   ¤   ¤   // Leave szDlgTitle null ("") to accept the default title ("Open").
949355 ¤   ¤   ¤   szDlgTitle = "Browse to your Public Keyring";
1aaf5a
68a906 ¤   ¤   ¤   // Pass in a default file extension. ·Do NOT include the period.
8be641 ¤   ¤   ¤   // If you pass a null string,no extension is used.
58a823 ¤   ¤   ¤   szExt = "pgp";
3cd83c ·
f55dd0 ¤   ¤   ¤   // Call the FileBrowse function.
7e8f4c ¤   ¤   ¤   svSelectedFile = TARGETDIR ^ "*.pkr";
0b67c5 ¤
86dfdb ¤   ¤   ¤   nResult = FileBrowse(hwndIS3,szFileFilter,svSelectedFile,szDlgTitle¶
a25efd ,szExt);
64af5a
a15456 ¤   ¤   ¤   if (!nResult) then
828204 ¤   ¤   ¤   ¤   // Do something with the selected file.
f493c4 ¤   ¤   ¤   ¤   szPubRingPath = svSelectedFile;
a377fa ¤   ¤   ¤   ¤   bPubKeysFound = TRUE;
98bb8c ¤   ¤   ¤   else
afefbe ¤   ¤   ¤   // Handle the lack of selection,which could be due to a dialog
dab86d ¤   ¤   ¤   // box-related error,chosing the Cancel button,or closing
cfd5ca ¤   ¤   ¤   // the dialog with the Close button.
f77fb8 ¤   ¤   ¤   UseDefaultPubKey = "TRUE";
f92812 ¤   ¤   ¤   bPubKeysFound = FALSE;
f76874 ¤   ¤   ¤   endif;
a30e97 ¤   ¤   //Get new Private ring
78ace2 ¤   ¤   ¤   if (bPubKeysFound = TRUE) then
9be8d8 ¤   ¤   ¤   ¤   szFileFilter = "Private Keyring Files (*.skr ·; *.prvkr ; secri¶
--0999 00093694d1540110222 Page 51 of setup.rul
1f2066 ng.*)" +
e0d1ec ¤   ¤   ¤   ¤   ¤   ¤   ",*.skr;*.prvkr;secring.pgp;,All Files (*.*),*.*";
701b52 ¤   ¤
25c0d2 ¤   ¤   ¤   ¤   // Give the file browse dialog a custom title,if you wish.
98e356 ¤   ¤   ¤   ¤   // Leave szDlgTitle null ("") to accept the default title ("Ope¶
e3ff72 n").
bd115a ¤   ¤   ¤   ¤   szDlgTitle = "Browse to your Private Keyring";
26af5a
200f4d ¤   ¤   ¤   ¤   // Call the FileBrowse function.
2dc722 ¤   ¤   ¤   ¤   nResult = FileBrowse(hwndIS3,szFileFilter,svSelectedFileb,szDlg¶
8d06b3 Title,szExt);
33af5a
9bd829 ¤   ¤   ¤   ¤   if (!nResult) then
de0d53 ¤   ¤   ¤   ¤   ¤   // Do something with the selected file.
1e6163 ¤   ¤   ¤   ¤   ¤   szPrivRingPath = svSelectedFileb;
1a669b ¤   ¤   ¤   ¤   ¤   bPrvKeysFound = TRUE;
84fa07 ¤   ¤   ¤   ¤   else
f18c0a ¤   ¤   ¤   ¤   ¤   // Handle the lack of selection,which could be due to a dia¶
cac65d log
3ad791 ¤   ¤   ¤   ¤   ¤   // box-related error,chosing the Cancel button,or closing
1be9e2 ¤   ¤   ¤   ¤   ¤   // the dialog with the Close button.
df1b7f ¤   ¤   ¤   ¤   ¤   bPrvKeysFound = FALSE;
0b539d ¤   ¤   ¤   ¤   endif;
c36874 ¤   ¤   ¤   endif;
58af5a
af408e ¤   //PUBLIC KEYRING
c793ab ¤   ¤   ¤   if ((bPrvKeysFound = TRUE) &&
ef5a43 ¤   ¤   ¤   ¤   (bPubKeysFound = TRUE)) ··then //only show second dialog if use¶
eadac4 r did select a private key
a458e0 ¤   ¤   ¤   ¤   VarSave (SRCTARGETDIR);
39a267 ¤   ¤   ¤   ¤   ParsePath (svReturnString, szPubRingPath, PATH);
dbe87c ¤   ¤   ¤   ¤   TARGETDIR¤  = svTarget ^ "PGP Keyrings";
e01aef ¤   ¤   ¤   ¤   SRCDIR¤ ¤   = svReturnString;
8bc7cb ¤   ¤   ¤   ¤   ParsePath (svReturnString, szPubRingPath, FILENAME);
729aac ¤   ¤   ¤   ¤   ParsePath (svPubLoc, szPubRingPath, PATH);
af2a1b ¤   ¤   ¤   ¤   szLongTarget = svTarget;
a00351 ¤   ¤   ¤   ¤   LongPathFromShortPath (szLongTarget);
98d7fa ¤   ¤   ¤   ¤   if (svPubLoc != szLongTarget^ "\\PGP Keyrings\\") then
9b3a38 ¤   ¤   ¤   ¤   ¤   SetDialogTitle
1f82fe ¤   ¤   ¤   ¤   ¤   (DLG_ASK_YESNO,"Copy keyrings?");
64d118 ¤   ¤   ¤   ¤   ¤   if (AskYesNo
56d3ae ¤   ¤   ¤   ¤   ¤   ···("Do you want setup to copy these keyrings to your" +
22e525 ¤   ¤   ¤   ¤   ¤   ···" PGP Keyrings directory?",YES) = YES) then
658744 ¤   ¤   ¤   ¤   ¤   ¤   svCopyKeys = "YES";
f8f7e7 ¤   ¤   ¤   ¤   ¤   ¤   CopyFile (svReturnString, "pubring.pkr");
3eb17c ¤   ¤   ¤   ¤   ¤   endif;
dc539d ¤   ¤   ¤   ¤   endif;
4d87c7 ¤   ¤   ¤
2a1938 ¤   ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
36f74f ¤   //PRIVATE KEYRING
2b58e0 ¤   ¤   ¤   ¤   VarSave (SRCTARGETDIR);
5cf495 ¤   ¤   ¤   ¤   ParsePath (svReturnString, ·szPrivRingPath, PATH);
0be87c ¤   ¤   ¤   ¤   TARGETDIR¤  = svTarget ^ "PGP Keyrings";
4b1aef ¤   ¤   ¤   ¤   SRCDIR¤ ¤   = svReturnString;
03dcac ¤   ¤   ¤   ¤   ParsePath (svReturnString, ·szPrivRingPath, FILENAME);
9be78d ¤   ¤   ¤   ¤   ParsePath (svPrivLoc, szPrivRingPath, PATH);
3d2526 ¤   ¤   ¤   ¤   if (svPrivLoc != szLongTarget ^ "\\PGP Keyrings\\") then
834efa ¤   ¤   ¤   ¤   ¤   if (svCopyKeys = "YES") then
1d548d ¤   ¤   ¤   ¤   ¤   ¤   CopyFile (svReturnString, "secring.skr");
85d7ec ¤   ¤   ¤   ¤   ¤   ¤   SdShowMsg ("Your private and public keyrings have been ¶
50e678 copied to your" +
26f377 ¤   ¤   ¤   ¤   ¤   ¤   " PGP Keyrings directory.", TRUE);
a99cdc ¤   ¤   ¤   ¤   ¤   ¤   Delay (5);
c8d7ec ¤   ¤   ¤   ¤   ¤   ¤   SdShowMsg ("Your private and public keyrings have been ¶
bfe678 copied to your" +
939cbd ¤   ¤   ¤   ¤   ¤   ¤   " PGP Keyrings directory.", FALSE);
05b17c ¤   ¤   ¤   ¤   ¤   endif;
a0539d ¤   ¤   ¤   ¤   endif;
421938 ¤   ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
c5af5a
84bb8c ¤   ¤   ¤   else
9358e0 ¤   ¤   ¤   ¤   VarSave (SRCTARGETDIR);
--7680 0002b6fc4e540110222 Page 52 of setup.rul
fee87c ¤   ¤   ¤   ¤   TARGETDIR¤  = svTarget ^ "PGP Keyrings";
01c9ed ¤   ¤   ¤   ¤   SRCDIR¤ ¤   = svTarget ^ "PGP Keyrings";
b79fdb ¤   ¤   ¤   ¤   //They said they dont have existing key so we need to add the d¶
bad6a7 efault pubring
a6071a ¤   ¤   ¤   ¤   //we remove any existing private rings. bug#2688 fix
077805 ¤   ¤   ¤   ¤   RenameFile ("secring.skr", "secring.old" );
ea0d0e ¤   ¤   ¤   ¤   RenameFile ("pubring.pkr", "pubring.old" );
6a9570 ¤   ¤   ¤   ¤   DeleteFile ("secring.skr");
ab361a ¤   ¤   ¤   ¤   DeleteFile ("pubring.pkr");
081da3 ¤   ¤   ¤   ¤   SRCDIR¤ ¤   = SUPPORTDIR;
2eceed ¤   ¤   ¤   ¤   CopyFile ("pubring.pkr", "pubring.pkr");
941938 ¤   ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
276874 ¤   ¤   ¤   endif;
127442 ¤   ¤   //if they dont have existing keys use the default keyring
a90e1d ¤   ¤   else
be9db5 ¤   ¤   ¤   VarSave (SRCTARGETDIR);
b7874f ¤   ¤   ¤   TARGETDIR¤  = svTarget ^ "PGP Keyrings";
b7a6de ¤   ¤   ¤   SRCDIR¤ ¤   = svTarget ^ "PGP Keyrings";
675713 ¤   ¤   ¤   //They said they dont have existing key so we need to add the defau¶
1fb295 lt pubring
f48d5f ¤   ¤   ¤   //we remove any existing private rings. bug#2688 fix
fbf752 ¤   ¤   ¤   RenameFile ("secring.skr", "secring.old" );
f28259 ¤   ¤   ¤   RenameFile ("pubring.pkr", "pubring.old" );
4a1d16 ¤   ¤   ¤   DeleteFile ("secring.skr");
2dbe7c ¤   ¤   ¤   DeleteFile ("pubring.pkr");
3a214d ¤   ¤   ¤   SRCDIR¤ ¤   = SUPPORTDIR;
30a1de ¤   ¤   ¤   CopyFile ("pubring.pkr", "pubring.pkr");
a41774 ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
a78ad7 ¤   ¤   endif;
1e0e24 ¤   else
ed6405 ¤   ¤   //fastinstall
061649 ¤   ¤   VarSave (SRCTARGETDIR);
73d454 ¤   ¤   TARGETDIR¤  = svTarget ^ "PGP Keyrings";
74f5c5 ¤   ¤   SRCDIR¤ ¤   = svTarget ^ "PGP Keyrings";
50f140 ¤   ¤   //They said they dont have existing key so we need to add the default p¶
cb9fa5 ubring
af5776 ¤   ¤   //we remove any existing private rings. bug#2688 fix
61a2fe ¤   ¤   RenameFile ("secring.skr", "secring.old" );
a5d7f5 ¤   ¤   RenameFile ("pubring.pkr", "pubring.old" );
e4d843 ¤   ¤   DeleteFile ("secring.skr");
677b29 ¤   ¤   DeleteFile ("pubring.pkr");
2ece3e ¤   ¤   SRCDIR¤ ¤   = SUPPORTDIR;
07f2c5 ¤   ¤   CopyFile ("pubring.pkr", "pubring.pkr");
465687 ¤   ¤   VarRestore (SRCTARGETDIR);
84eb6d ¤   endif;
3aaf5a
f5225a ¤   if (svCopyKeys = "YES") then
cd10af ¤   ¤   //Re-Set Default keyring info
e358aa ¤   ¤   szPubRingPath¤  = svTarget ^ "PGP Keyrings\\pubring.pkr";
bc11ba ¤   ¤   szPrivRingPath¤ = svTarget ^ "PGP Keyrings\\secring.skr";
e4c695 ¤   ¤   szRandSeedPath¤ = WINDIR ^ "randseed.rnd";
b6af5a
ff02a4 ¤   ¤   PGPclSetSDKFilePaths
71c6d6 ¤   ¤   (szPubRingPath, szPrivRingPath, szRandSeedPath, 1);
860e24 ¤   else
5667a6 ¤   ¤   LongPathFromShortPath (szPrivRingPath);
d2415f ¤   ¤   LongPathFromShortPath (szPubRingPath);
5102a4 ¤   ¤   PGPclSetSDKFilePaths
2fc6d6 ¤   ¤   (szPubRingPath, szPrivRingPath, szRandSeedPath, 1);
98eb6d ¤   endif;
e5af5a
5d5e30 ¤   nResult = UnUseDLL(WINSYSDIR + "pgp60cl.dll");
a7af5a
02af5a
ff35c4 FinalInstallProcess:
22af5a
29b8ee ¤   //End of Script
c4b908 ¤   //Add the Download Adobe Acrobat Icon to Start Menu,
825004 ¤   //this is done at the very end
9af3d6 ¤   //so that ···SRCDIR && TARGETDIR are not lost
9db167 ¤   SRCDIR ····= SUPPORTDIR;
2b5493 ¤   TARGETDIR ·= FOLDER_STARTMENU ^ "Programs" ^ "P G P" ^ "Documentation";
--498d 00022d59e3940110222 Page 53 of setup.rul
16988d ¤   if (ComponentIsItemSelected
9e7635 ¤   ···(szComponents,APP_NAME +" User's Manual (Adobe Acrobat format)") = TRUE)
b4e2b8 ¤   ···then
1fa5eb ¤   ¤   CopyFile ("adobe.url","Download Adobe Acrobat.url");
a8eb6d ¤   endif;
b0af5a
7caf5a
a267a0 ¤   RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
d4d83c ¤   szName = svTarget + "\\uninstall.exe";
ee3096 ¤   LongPathToShortPath (szName);
6f0bdf ¤   RegDBSetKeyValueEx
9e44e5 ¤   ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" ^ DEINSTALL_KEY
2ced87 ¤   ,"UninstallString",REGDB_STRING,szName,-1);
c70bdf ¤   RegDBSetKeyValueEx
7b44e5 ¤   ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" ^ DEINSTALL_KEY
c6221f ¤   ,"DisplayName",REGDB_STRING,APP_NAME,-1);
7c67c5 ¤
43c4b9 ¤   if (UpdateNeeded = "TRUE") then
3f0a31 ¤   ¤   SRCDIR ····= SUPPORTDIR;
758d73 ¤   ¤   TARGETDIR ·= FOLDER_STARTMENU ^ "Programs" ^ "P G P";
657a18 ¤   ¤   CopyFile ("eudora.url","Update Eudora.url");
bdaf5a
49fe80 ¤   ¤   MessageBox ("Don't forget to update your version of Eudora.\n"+
74dc3f ¤   ¤   "The newest versions can be found at\n\n"+
41aa69 ¤   ¤   "http://www.eudora.com\n\n"+
6e7cb5 ¤   ¤   "You must update your Eudora version for the\n"+
042ff2 ¤   ¤   "Eudora Plugin to function properly.\n\n "+
c273b9 ¤   ¤   "Thanks for selecting PGP !", INFORMATION);
41eb6d ¤   endif;
3e67c5 ¤
62bb17 ¤   VarSave (SRCTARGETDIR);
186425 ¤   TARGETDIR¤  = WINSYSDIR;
4a791a ¤   SRCDIR¤ ¤   = svTarget;
2e8d1f ¤   CopyFile ("PGP60.hlp", "PGP60.hlp");
eedaf8 ¤   VarRestore (SRCTARGETDIR);
79af5a
aac1e8 ¤   TARGETDIR = svTarget;
1d284e ¤   DeleteFile ("adobe.url");
292e7b ¤   DeleteFile ("eudora.url");
e4af5a
e5fed9 ¤   //Launch Microsofts comctl32.dll if neccesary
343a72 ¤   GetSystemInfo(OS, nvOS, svOS);
f7de22 ¤   VerGetFileVersion (WINSYSDIR^"comctl32.DLL", svVersionNumber);
82be70 ¤   switch (nvOS)
63af5a
325af8 ¤   case IS_WINDOWSNT:
c728b3 ¤   ¤   if (VerCompare (svVersionNumber, "4.7.0.0", VERSION)= LESS_THAN) then
71d498 ¤   ¤   ¤   //launch microsofts updater 40Comupd.exe with args ·/r:n /q:a for q¶
6e572e uiet
5a82f8 ¤   ¤   ¤   LaunchAppAndWait (svTarget ^ "40Comupd.exe","\/r:n \/q:a", WAIT);
9acbea ¤   ¤   nReboot = 1;
5e8ad7 ¤   ¤   endif;
49af5a
23080d ¤   case IS_WINDOWS95:
3828b3 ¤   ¤   if (VerCompare (svVersionNumber, "4.7.0.0", VERSION)= LESS_THAN) then
c5d498 ¤   ¤   ¤   //launch microsofts updater 40Comupd.exe with args ·/r:n /q:a for q¶
58572e uiet
4582f8 ¤   ¤   ¤   LaunchAppAndWait (svTarget ^ "40Comupd.exe","\/r:n \/q:a", WAIT);
3bcbea ¤   ¤   nReboot = 1;
9a8ad7 ¤   ¤   endif;
40db51 ¤   endswitch;
096801 ¤   Delay (2);
3ac755 ¤   //Dekete the microsoft comctl32.dll updater, its no longer needed
f875fb ¤   VarSave¤¤   (SRCTARGETDIR);
6c12f1 ¤   TARGETDIR ·= svTarget;
b1bb4f ¤   SRCDIR ····= svTarget;
48838b ¤   DeleteFile¤ ("40Comupd.exe");
8d5411 ¤   VarRestore¤ (SRCTARGETDIR);
8367c5 ¤
c45f93 ¤   //If PGPdisk is getting installed try and load the driver on NT
d0988d ¤   if (ComponentIsItemSelected
222ac9 ¤   ¤   (szComponents,"PGPdisk for Windows") = TRUE) then
--d827 00065f6b04740110222 Page 54 of setup.rul
e0af5a
b1cbea ¤   ¤   nReboot = 1;
45af5a
1deb6d ¤   endif;
44af5a
66af5a
ca0175 ¤   nResult = UseDLL(SUPPORTDIR ^ "install.dll");
f9d74f ¤   //#define DRIVER_NO_ERROR¤  ¤   ¤   0
576102 ¤   //#define DRIVER_NOT_WINNT¤ ¤   ¤   1
beec08 ¤   //#define DRIVER_ACCESS_ERROR¤  ¤   2
5593c5 ¤   //#define DRIVER_CREATE_FAIL¤   ¤   3
873840 ¤   //#define DRIVER_ALREADY_STARTED¤   4
4f025b ¤   //#define DRIVER_MISC_ERROR¤¤   ¤   5
ead625 ¤   //#define UNKNOWN_ERROR¤¤   ¤   ¤   6
6f2f77 ¤   nResult = PGPclStartMemLockDriver ();·
9e07a7 ¤   if (( nResult = 0 ) ||
40d8b4 ¤   ¤   ( nResult = 1 ) ||
784292 ¤   ¤   ( nResult = 4 )) then
eac506 ¤   ¤   szTemp = "Setup has finished installing " + APP_NAME +
122d58 ¤   ¤   ¤   ¤   " on your computer." + " Setup can optionally" +
83e017 ¤   ¤   ¤   ¤   " launch PGPkeys and/or the Read Me file." +·
db457e ¤   ¤   ¤   ¤   " Choose the options you want below.";
3aaf5a
7f0e24 ¤   else
7faf5a
1dc506 ¤   ¤   szTemp = "Setup has finished installing " + APP_NAME +
462d58 ¤   ¤   ¤   ¤   " on your computer." + " Setup can optionally" +
0be017 ¤   ¤   ¤   ¤   " launch PGPkeys and/or the Read Me file." +·
a473fc ¤   ¤   ¤   ¤   " Choose the options you want below.\n\n" +
05b57d ¤   ¤   ¤   ¤   "NOTE: To take advantage of the PGP secure " +
4cb5fd ¤   ¤   ¤   ¤   "memory drivers that have been installed, you " +
d7c482 ¤   ¤   ¤   ¤   "will need to reboot your machine.";
f8eb6d ¤   endif;
83c77c ¤   UnUseDLL(SUPPORTDIR ^ "install.dll");
56af5a
a50972 ¤   if ((BATCH_INSTALL = TRUE) || (nReboot = 1)) then
e6af5a
3ea192 ¤   ¤   CommitSharedFiles(0);
57af5a
a5e068 ¤   ¤   if (bEasyInstall = FALSE) then
e4a7c1 ¤   ¤   ¤   bvOpt1 = TRUE;
0c87c7 ¤   ¤   ¤
52d28d ¤   ¤   ¤   szTemp = "Setup can optionally launch the Read Me file.";
f2af5a
428834 ¤   ¤   ¤   SdFinish("Would you like to view the Read Me file ?",szTemp,"",
9c956d ¤   ¤   ¤   ¤   ¤   ·"Yes, I want to view the Read Me file.",
cbba08 ¤   ¤   ¤   ¤   ¤   ·"",bvOpt1,bvOpt2);
b467b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¶
c967b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¶
68b8df ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
458adb ¤   ¤   ¤   ChangeDirectory(svTarget);
f9ff2e ¤   ¤   ¤   if (bvOpt1) then
90ea5d ¤   ¤   ¤   ····hWnd = 0;
4c1960 ¤   ¤   ¤   ¤   LaunchAppAndWait("NOTEPAD.EXE",svTarget^ "Documentation" ^ "rea¶
3250d8 dme.txt", NOWAIT);
f67667 ¤   ¤   ¤   ¤   Delay (1);
b0bce2 ¤   ¤   ¤   ¤   hWnd = FindWindow("", "readme.txt - Notepad");
74ad6d ¤   ¤   ¤   ¤   SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
1f6874 ¤   ¤   ¤   endif;
508ad7 ¤   ¤   endif;
5baf5a
91a109 ········// Clean up value stored in registry to allow Setup to know that the us¶
2cee3f er qualifies for this installation
a561ea ········RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
480e19 ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer¶
d06c47 \\IStatus");
5faf5a
52dc4d ¤   ¤   szTemp = "Setup has finished installing " +
a46191 ¤   ¤   ¤   ¤   ·APP_NAME +" on your computer";
4baf5a
c38bf4 ¤   ¤   szMsg = "Your computer needs to be rebooted for the installation\n" +
65d38c ¤   ¤   ¤   ¤   "to complete.";
--8eaa 000319a3fb840110222 Page 55 of setup.rul
e0af5a
91aefb ¤   ¤   // If SdFinishReboot reboots the system,the shared file data is
d2a56f ¤   ¤   // automatically recorded.
37396c ¤   ¤   RebootDialog ("Restart Windows",szMsg,SYS_BOOTWIN);
b367c5 ¤
68af5a
abbf0c ¤   ¤   // If BATCH_INSTALL is FALSE,Setup is complete.
61cae1 ···¤else
05e068 ¤   ¤   if (bEasyInstall = FALSE) then
e8a7c1 ¤   ¤   ¤   bvOpt1 = TRUE;
d5d3a8 ¤   ¤   ¤   bvOpt2 = TRUE;
34af5a
c4cfd9 ¤   ¤   ¤   SdFinish("Setup Complete",szTemp,"Click Finish to complete Setup.",
eeccb8 ¤   ¤   ¤   ¤   ¤   ·"Yes, I want to run PGPkeys.",
485016 ¤   ¤   ¤   ¤   ¤   ·"Yes, I want to view the Read ME file.",bvOpt1,bvOpt2);
5567b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¶
7367b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¶
f6b8df ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
968adb ¤   ¤   ¤   ChangeDirectory(svTarget);
8bff2e ¤   ¤   ¤   if (bvOpt1) then
35d0b6 ¤   ¤   ¤   ¤   LaunchApp(svTarget ^ "pgpkeys.exe","");
d36874 ¤   ¤   ¤   endif;
0975fe ¤   ¤   ¤   if (bvOpt2) then
51369d ¤   ¤   ¤   ¤   LaunchApp("NOTEPAD.EXE",svTarget^ "Documentation" ^ "readme.txt¶
e7d450 ");
5c6874 ¤   ¤   ¤   endif;
5b8ad7 ¤   ¤   endif;
7baf5a
bf3ba0 ¤   ¤   LaunchApp(svTarget ^ "PGPTray.exe","");
e8af5a
9deb6d ¤   endif;
f8d9da if (IS_QUALCOMM_BUILD = "TRUE") then
7ca1f6 ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 1, NULL) ;
2128d5 endif;
593e1e ¤   exit;
26af5a
4b3c00 Exit_Handler:
34d1d1 // Post a message so that we know the install failed
ca6e8a PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
00a28b exit;
4dba0f return;
03af5a
057c82 /*-------------------------------------------------------------------------*\
93775e ·*
b79db0 ·* Function: ·SetupScreen
fb775e ·*
b206c2 ·* ·Purpose: ·This function will set up the screen look. ·This includes
fb387c ·* ···········colors,fonts,text to be displayed,etc.
67775e ·*
66775e ·*
686918 ·* ···Input:
96775e ·*
7b3e20 ·* ·Returns:
81775e ·*
3a412a ·* Comments:
d4b93c \*-------------------------------------------------------------------------*/
6e3148 function SetupScreen ()
0aaf5a
d4af5a
584a32 ¤   NUMBER ·nDx,nDy;
c6af5a
65af5a
e50f89 begin
0ebdb9 ¤   GetExtents(nDx,nDy);
41af5a
2bcdde ¤   SetFont(FONT_TITLE, STYLE_BOLD | STYLE_ITALIC, "Times New Roman");
7878d8 ¤   GetSystemInfo (VIDEO, nDisplay, szDisplay);
91db01 ¤   if (nDisplay = IS_EGA) then
9991cb ¤   ¤   SetTitle(TITLE + " - Setup", 10, WHITE); // Maybe 10
f3b960 ¤   elseif (nDisplay = IS_VGA) then
8a4d36 ¤   ¤   SetTitle(TITLE + " - Setup", 12, WHITE);
31116e ¤   elseif (nDisplay = IS_SVGA) then
--9b07 00008667c3940110222 Page 56 of setup.rul
f71363 ¤   ¤   SetTitle(TITLE + " - Setup", 16, WHITE);
a85377 ¤   elseif (nDisplay = IS_XVGA) then
f75abe ¤   ¤   SetTitle(TITLE + " - Setup", 18, WHITE);
81e419 ¤   elseif (nDisplay = IS_UVGA) then
473faf ¤   ¤   SetTitle(TITLE + " - Setup", 24, WHITE);
2e0e24 ¤   else
9161fa ¤   ¤   SetTitle(TITLE + " - Setup", 20, WHITE);
1beb6d ¤   endif;
e8de7b ··
193bc9 ¤   Enable(FULLWINDOWMODE);
2f31c0 ¤   Enable(INDVFILESTATUS);
59af5a
94b545 ¤   GetSystemInfo(COLORS,nvResult,svResult);
f3da08 ¤   if (nvResult < 257) then
e12593 ¤   ¤   SetColor( BACKGROUND, RGB(000,000,128) );
ba0e24 ¤   else
f14d9a ¤   ¤   SetColor( BACKGROUND, RGB(42,000,170) );
05eb6d ¤   endif;
7faf5a
9d0f0a ¤   SetColor(STATUSBAR,BLUE); ····// Bright blue.
d00bfd ¤   SetTitle(TITLE2 + " Setup",0,BACKGROUNDCAPTION); // Caption bar text( no ne¶
b52e74 w line ).
7caf5a
a2d9d1 ¤   //Enable(BACKGROUND);
bfaf5a
ab152b ¤   Delay(1);
cdaf5a
5f2b3d end;
95af5a
77af5a
417c82 /*-------------------------------------------------------------------------*\
1e775e ·*
cb0e69 ·* Function: ·CheckRequirements
eb775e ·*
f049ee ·* ·Purpose: ·This function will check all minimum requirements for the
d501d6 ·* ···········application being installed. ·If any fail,then the user
0ad6ab ·* ···········is informed and the installation is terminated.
16775e ·*
7e775e ·*
756918 ·* ···Input:
ce775e ·*
443e20 ·* ·Returns:
8d775e ·*
2e412a ·* Comments:
71b93c \*-------------------------------------------------------------------------*/
d13292 function CheckRequirements ()
b2af5a
57af5a
f56dbc ····NUMBER ·nvDx,nvDy;
81869e ····
2655f2 ····NUMBER ·nvResult;
24869e ····
d18722 ····STRING ·svResult;
56af5a
e4af5a
600f89 begin
c4af5a
e6ea8b ¤   // Check screen resolution.
a6007f ¤   GetExtents(nvDx,nvDy);
b00229 ¤   if (nvDy < 480) then
36af5a
2f74a5 ¤   ¤   MessageBox
e89c32 ¤   ¤   ("This program requires VGA or better resolution.",WARNING);
b5da8f ¤   ¤   if (IS_QUALCOMM_BUILD = "TRUE") then
a833e4 ¤   ¤   ¤   PostWindowMessageA( 0xffff, WM_MAHAVISHNU, 0 ,NULL) ;
f28ad7 ¤   ¤   endif;
a1925c ¤   ¤   exit;
97af5a
b1eb6d ¤   endif;
d6af5a
d10024 ¤   // Determine the target system's operating system.
0830fa ¤   GetSystemInfo(OS,nvResult,svResult);
--c0b9 0000a51c80840110222 Page 57 of setup.rul
8e5e6c ¤   bWinNT ·= FALSE;
6f6183 ¤   bWin32s = FALSE;
51a06e ¤   bIsShellExplorer = FALSE;
0f67c5 ¤
6450b0 ¤   if (nvResult = ·IS_WINDOWSNT) then
9ef07e ¤   ¤   bWinNT = TRUE; // Running Windows NT.
fcaf5a
ae530b ¤   ···// Check to see if NT is using EXPLORER Shell
bd7b7d ¤   ¤   if(QueryShellMgr(svResult) = 0) then
9f12db ¤   ¤   ¤   if(StrCompare(svResult,"EXPLORER.EXE") = 0) then
600afb ¤   ¤   ¤   bIsShellExplorer = TRUE;
fa6874 ¤   ¤   ¤   endif;
968ad7 ¤   ¤   endif;
7caf5a
3b8afe ¤   elseif (nvResult = ·IS_WIN32S) then
7dc6ad ¤   ¤   bWin32s = TRUE; // Running Win32s.
39eb6d ¤   endif;
43af5a
8d2b3d end;
84af5a
d8af5a
007c82 /*-------------------------------------------------------------------------*\
ed775e ·*
e206a2 ·* Function: ·FileBrowse
fd775e ·*
697a8c ·* ·Purpose: ·
49b896 ·* ·········
0e775e ·*
f5775e ·*
e36918 ·* ···Input:
61775e ·*
2d3e20 ·* ·Returns:
4a775e ·*
51412a ·* Comments:
a9b93c \*-------------------------------------------------------------------------*/
48af5a
bb12b5 function FileBrowse (hwnd,szFilter,svSelected,szTitle,szExt)
f2af5a
837402 ······STRING szDLL,svResult;
91af5a
80e2e9 ······NUMBER nvISType,nResult,nLen,n,nvByte;
f3cf72 ······
b15100 ······BOOL bResult;
f4af5a
b00f89 begin
5dba6f ····GetSystemInfo(ISTYPE,nvISType,svResult);
c0cf72 ······
01cf7b ····// Load the DLL,which must be on disk 1 or in _SETUP.LIB
c8b49e ····// so that it gets placed into SUPPORTDIR.
f79c4a ····if (nvISType = 16) then
1dbd28 ········szDLL = SUPPORTDIR ^ "INSTALL.DLL";
3e842c ····else
85bd28 ········szDLL = SUPPORTDIR ^ "INSTALL.DLL";
a80eff ····endif;
daaf5a
a51d5c ····nResult = UseDLL(szDLL);
822595 ····if (nResult < 0) then
09af50 ········MessageBox("FileBrowse failed to load DLL:\n" +
b6f0da ····················szDLL,SEVERE);
6b82c5 ········return 0;
c40eff ····endif;
46af5a
6f8e99 ····// The Windows OPENFILENAME structure requires the browse
bc152c ····// filter in string array format. To achieve this,replace
7ac614 ····// all commas (ASCII 44) with NULL. Then,append an extra NULL
ba9fca ····// because the array ends with two NULLs.
99875b ····nLen = StrLength(szFilter);
462eab ····for n = 0 to nLen - 1
7fbf38 ········GetByte(nvByte,szFilter,n);
80cd6f ········if (nvByte = 44) then
10b401 ············SetByte(szFilter,n,0);
0a88e0 ········endif;
--b3c6 00023de482240110222 Page 58 of setup.rul
1806a1 ····endfor;
6a04c7 ····szFilter = szFilter + "";
67e8c6 ···
c113de ····bResult = MyGetOpenFileName32 (hwnd,szFilter,svSelected,szTitle,szExt);
56cf72 ······
cdd226 ····// Unload the DLL.
837f62 ····UnUseDLL(szDLL);·
e2cf72 ······
03b1b6 ····if (!bResult) then
48aa57 ········return -1;
920eff ····endif;
e0cf72 ······
16958b ····return 0;
3bcf72 ······
162b3d end;
cbaf5a
8eaf5a
cdaf5a
72bedf /******************************************************************************
97775e ·*
ebe05a ·* Function: ···DeleteSharedFile
70775e ·*
b59adf ·* ·Purpose: ···This function will check if a library is shared before deleteing
4b775e ·*
b56918 ·* ···Input:
53775e ·*
433e20 ·* ·Returns:
37775e ·*
a4412a ·* Comments:
aa775e ·*
c83f23 ·******************************************************************************/
28af5a
60bf3d function DeleteSharedFile (szDeleteFilePath, szDeleteFile)
a0af5a
c1af5a
e084db ····STRING ·szDelKey, svString, svValue;
50af5a
63c127 ····NUMBER ·nvVar, nvType, nvSize, nSize;
39af5a
03af5a
ff0f89 begin
e4af5a
e1b0fb ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
44af5a
43cd89 ····szDelKey¤   = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs";
30af5a
0eb0fb ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
69af5a
77e4ec ····if (RegDBGetKeyValueEx·
ef3ad6 ¤   ····(szDelKey, ·szDeleteFilePath ^ szDeleteFile, nvType, svValue, nvSize) <¶
d32953 ·0 ) then
64af5a
7b9613 ¤   ····//this is not a shared .dll so delete
3baf5a
f5c196 ¤   ····TARGETDIR ·= szDeleteFilePath;
207356 ¤   ····SRCDIR ····= szDeleteFilePath;
31d25e ¤   ····DeleteFile (szDeleteFile);
b8af5a
8e842c ····else
0faf5a
193d73 ¤   ····//this is a shared file
119f4f ¤   ····StrToNum (nvVar, svValue);
7a3062 ¤   ····nvVar = nvVar - 1;
f40150 ¤   ····if (nvVar < 1) then
d90513 ¤   ¤   ····SetDialogTitle (DLG_ASK_YESNO,"Shared File");
dc1ce5 ¤   ¤   ····if (AskYesNo
db6919 ¤   ¤   ·······(szDeleteFile + " is a shared library. It appears no other appli¶
3b5f90 cations\n"+
d89bd8 ¤   ¤   ·······"are using it anymore, do you want to delete it?"
c8ddda ¤   ¤   ·······,NO) = YES) then
a5e6ea ¤   ¤   ¤   ¤   ····//Delete the file and decrement the count
237923 ¤   ¤   ¤   ¤   ····RegDBDeleteValue (szDelKey, szDeleteFilePath ^ szDeleteFile¶
--c405 0008a7db1c240110222 Page 59 of setup.rul
eb6275 );
efaf5a
4a86f0 ¤   ¤   ¤   ¤   ····TARGETDIR ·= szDeleteFilePath;
993430 ¤   ¤   ¤   ¤   ····SRCDIR ····= szDeleteFilePath;
bf0c79 ¤   ¤   ¤   ¤   ····DeleteFile (szDeleteFile);
c78de6 ¤   ¤   ····endif;
cf6f45 ¤   ····endif;
22cae0 ¤   ····//write the new number of apps shareing the library
85d8a1 ¤   ····if (nvVar > 0) then
b39c02 ¤   ¤   ····NumToStr (svString, nvVar);
a1951d ¤   ¤   ····RegDBSetKeyValueEx·
381bdf ¤   ¤   ····(szDelKey, ·szDeleteFilePath ^ szDeleteFile, REGDB_NUMBER, svString¶
7ed5cb , nSize);
c56f45 ¤   ····endif;
4f0eff ····endif;
12af5a
882b3d end;
19af5a
07af5a
4abedf /******************************************************************************
59775e ·*
42e05a ·* Function: ···DeleteSharedFile
23775e ·*
2b26b9 ·* ·Purpose: ···This function will cleanup old 5.5.X un-needed shared
8c6b4f ·* ·············file ref's
cc775e ·*
266918 ·* ···Input:
2d775e ·*
cd3e20 ·* ·Returns:
25775e ·*
b1412a ·* Comments:
89775e ·*
be3f23 ·******************************************************************************/
9aaf5a
0c40e6 function CleanSharedFile(szDeleteFilePath, szDeleteFile)
d9af5a
78af5a
5f84db ····STRING ·szDelKey, svString, svValue;
87869e ····
84c127 ····NUMBER ·nvVar, nvType, nvSize, nSize;
4daf5a
7aaf5a
e40f89 begin
88af5a
26b0fb ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
b9af5a
18cd89 ····szDelKey¤   = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs";
84af5a
bab0fb ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
96af5a
9fe4ec ····if (RegDBGetKeyValueEx·
913ad6 ¤   ····(szDelKey, ·szDeleteFilePath ^ szDeleteFile, nvType, svValue, nvSize) <¶
ca2953 ·0 ) then
d4842c ····else
6d169f ¤   ····//Delete the shared file ref
2edf42 ¤   ····RegDBDeleteValue (szDelKey ,szDeleteFilePath ^ szDeleteFile);
b20eff ····endif;
a5af5a
482b3d end;
beaf5a
2baf5a
84af5a
1bbedf /******************************************************************************
52775e ·*
849c70 ·* Function: ·UNINSTALL ·5.X
62775e ·*
5e7a8c ·* ·Purpose: ·
78b896 ·* ·········
28775e ·*
c5775e ·*
d36918 ·* ···Input:
8a775e ·*
--d935 000cbbcfe8040110222 Page 60 of setup.rul
8e3e20 ·* ·Returns:
6f775e ·*
6e412a ·* Comments:
dd3f23 ·******************************************************************************/
7baf5a
9c6a66 function Uninstall5X (UNINSTALLKEY, OEPATH, PGPPATH, EUDPATH)
4baf5a
33af5a
5b09f5 ····STRING¤ ¤   szPubRingPath [512];
62af5a
e3ddaa ····STRING¤ ¤   szPrivRingPath[512];
41af5a
7f318b ····STRING¤ ¤   szRandSeedPath[512];
21af5a
a392ae ····STRING¤ ¤   szKey,szName,svValue,svReturnString,szBmpName, szLocalDB, szTem¶
55cd91 p, szMsg;
53af5a
3f7de2 ····STRING¤ ¤   Installdir,svTarget,svResult, OEinstall;
74af5a
9b691b ····NUMBER¤ ¤   nDx,nDy,nvSize,nvType,nID_BITMAP, nResult, Reboot, nIndex;
29af5a
fbcb84 ····HWND¤   ¤   hWnd1,hWnd2,hWnd3,hWnd4,hWnd5,hWnd6,hWnd7,hWnd8,hWnd9;
bbaf5a
87c8ab ····//For outlook express
d2e182 ····STRING szFileName, szVerBuffer[1536], szResultBuffer, szData;
73768d ····LONG lSize, lData;
e63c9e ····POINTER ptr1, ptr2;
434ddb ····NUMBER nSize, nHandle;
fed470 ····BOOL bVerValue, bVerInfo, bUpgraded;
33af5a
3a583d ·····
720f89 begin
7a673c ····if (szINSTALLED_VERSION != "") then
2ad30e ········szMessage = "Uninstalling PGP " + szINSTALLED_VERSION + ". ·Please wait¶
90d729 ...";
70842c ····else
00b352 ········szMessage = "Uninstalling PGP. ·Please wait...";
190eff ····endif;
715c99 ····SdShowMsg (szMessage, TRUE);
a6af5a
d2f933 ····// Run through this rountine 3 times, just to ensure proper file deletion
e9bd1d ····nIndex = 0;
04eb40 ····while (nIndex < 3)
f9af5a
6ad3e3 ········Reboot = 0;
40af5a
8edd30 ········//DELETE .DLL'S FROM WINDOWS SYSTEM DIRECTORY
2cd230 ········TARGETDIR = WINSYSDIR;
de8b5f ········CleanSharedFile(WINSYSDIR,"PGPsdk.dll");·
0113da ········DeleteFile ("PGPsdk.dll");
e1e534 ········CleanSharedFile(WINSYSDIR,"PGPsdkKS.dll");
4f47d1 ········DeleteFile ("PGPsdkKS.dll");
3862f4 ········CleanSharedFile(WINSYSDIR,"PGPsdkKeyServer.dll");
b2385b ········DeleteFile ("PGPsdkKeyServer.dll");
16ea47 ········CleanSharedFile(WINSYSDIR,"PGP55km.dll");
753d90 ········DeleteFile ("PGP55km.dll");
f1b159 ········CleanSharedFile(WINSYSDIR,"PGP55cd.dll");
ec668e ········DeleteFile ("PGP55cd.dll");
bd4f2c ········CleanSharedFile(WINSYSDIR,"PGP55rd.dll");
6e98fb ········DeleteFile ("PGP55rd.dll");
6f8ae9 ········CleanSharedFile(WINSYSDIR,"PGP55sc.dll");
6c5d3e ········DeleteFile ("PGP55sc.dll");
60d492 ········CleanSharedFile(WINSYSDIR,"PGP55mn.dll");
360345 ········DeleteFile ("PGP55mn.dll");
7611f0 ········CleanSharedFile(WINSYSDIR,"PGPxch.dll");
e04331 ········DeleteFile ("PGPxch.dll");
9e2511 ········CleanSharedFile(WINSYSDIR,"PGP55oe.dll");
47f2c6 ········DeleteFile ("PGP55oe.dll");
50411b ········CleanSharedFile(WINSYSDIR,"PGPsdk.dll");
9013da ········DeleteFile ("PGPsdk.dll");
b33bc8 ········CleanSharedFile(WINSYSDIR,"PGPsdkPrefs");
cbec1f ········DeleteFile ("PGPsdkPrefs");
--2c8e 000b018e47740110222 Page 61 of setup.rul
76fedf ········DeleteFile ("PGPsdk.prf");
bdecb3 ········DeleteFile ("PGPMacBinaryMappings.txt");
7aaf5a
b7af5a
6f8bdb ········//DELETE FILES FROM THE PGP 5.5 INSTALL DIRECTORY
7c1413 ········TARGETDIR = szPREV_PGP_PATH;
75c434 ········Installdir = szPREV_PGP_PATH;
0fda7a ········DeleteFile ("keygen.avi");
297fb5 ········DeleteFile ("license.txt");
f6ac7f ········DeleteFile ("Pgp55.cnt");
bc4a1b ········DeleteFile ("pgp55.hlp");
a46b98 ········DeleteFile ("Pgp55.gid");
2f8e05 ········DeleteFile ("PGPadmin.exe");
aafcb9 ········DeleteFile ("PGPkeys.exe");
bebf11 ········DeleteFile ("PGPlog.exe");
908f11 ········DeleteFile ("PGPtools.exe");
4deffd ········DeleteFile ("PGPtray.exe");
27c5a5 ········DeleteFile ("Quickstart.doc");
35ad04 ········DeleteFile ("Readme.txt");
97ffad ········DeleteFile ("PGPadmin.prf");
cfc3eb ········DeleteFile ("PGPclient.prf");
9a8b6e ········DeleteFile ("Eudora.url");
e537ee ········DeleteFile ("Adobe.url");
2e757e ········DeleteFile ("randseed.bin");
962bf2 ········DeleteFile ("PGP55win.pdf");
2f6aad ········DeleteFile ("*.pdf");
8d69b0 ········DeleteFile ("*.isu");
af849b ········DeleteFile ("uninstall.exe");
5aaf5a
76e6ee ········if (szPREV_PGP_PATH != "") then
a663e9 ¤   ········DeleteDir(szPREV_PGP_PATH ^ "ClientInstaller", ALLCONTENTS);
7bc1b2 ¤   ········DeleteDir(szPREV_PGP_PATH ^ "TEMP", ALLCONTENTS);
221bbb ¤   ········DeleteDir(szPREV_PGP_PATH ^ "Signatures", ALLCONTENTS);
5a88e0 ········endif;
b9af5a
6e2438 ········//DELETE THE EUDORA PLUGIN
00bf37 ········TARGETDIR = EUDPATH;
17022c ········DeleteFile ("pgpplugin.dll");
b8af5a
0616c9 ········//DELETE REGISTRY ENTRIES
8d8bac ········//HKEY_CURRENT_USER
294de9 ········RegDBSetDefaultRoot(HKEY_CURRENT_USER);
9636fb ········RegDBDeleteKey ("Software\\Network Associates\\PGP55");
8b63ef ········RegDBDeleteKey ("Software\\PGP\\PGP55");
6eaf5a
4dca00 ········//HKEY_CLASSES_ROOT
05183b ········RegDBSetDefaultRoot(HKEY_CLASSES_ROOT);
20e2e9 ········RegDBDeleteKey (".aexpk");
025c3a ········RegDBDeleteKey (".asc");
6f34ee ········RegDBDeleteKey (".bexpk");
7714e6 ········RegDBDeleteKey (".pgd");
c48db6 ········RegDBDeleteKey (".pgp");
ebaaca ········RegDBDeleteKey (".pkr");
299b66 ········RegDBDeleteKey (".prvkr");
30e2e9 ········RegDBDeleteKey (".aexpk");
c8ddd7 ········RegDBDeleteKey (".pubkr");
1898e6 ········RegDBDeleteKey (".sig");
6d02a4 ········RegDBDeleteKey (".skr");
dfae6c ········RegDBDeleteKey ("CLSID\\{969223c0-26aa-11d0-90ee-444553540000}");
aa978e ········RegDBDeleteKey ("PGP Armored Encrypted File");
fa5b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
8d63d4 ········RegDBDeleteKey ("PGP Armored Extracted Public Key");
82999e ········RegDBDeleteKey ("PGP Detached Signature File");
41be05 ········RegDBDeleteKey ("PGP Encrypted File");
3e8c50 ········RegDBDeleteKey ("PGP Private Keyring");
54ba27 ········RegDBDeleteKey ("PGP Public Keyring");
5b5b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
015b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
8b5b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
c5af5a
31d474 ········//HKEY_LOCAL_MACHINE
b05676 ········RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
--1354 000b7ddec2340110222 Page 62 of setup.rul
d6e2e9 ········RegDBDeleteKey (".aexpk");
fc5c3a ········RegDBDeleteKey (".asc");
fc34ee ········RegDBDeleteKey (".bexpk");
c714e6 ········RegDBDeleteKey (".pgd");
8c8db6 ········RegDBDeleteKey (".pgp");
d3aaca ········RegDBDeleteKey (".pkr");
309b66 ········RegDBDeleteKey (".prvkr");
0de2e9 ········RegDBDeleteKey (".aexpk");
cdddd7 ········RegDBDeleteKey (".pubkr");
9598e6 ········RegDBDeleteKey (".sig");
5602a4 ········RegDBDeleteKey (".skr");
6fae6c ········RegDBDeleteKey ("CLSID\\{969223c0-26aa-11d0-90ee-444553540000}");
61978e ········RegDBDeleteKey ("PGP Armored Encrypted File");
d85b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
a963d4 ········RegDBDeleteKey ("PGP Armored Extracted Public Key");
e8999e ········RegDBDeleteKey ("PGP Detached Signature File");
a9be05 ········RegDBDeleteKey ("PGP Encrypted File");
7f8c50 ········RegDBDeleteKey ("PGP Private Keyring");
1eba27 ········RegDBDeleteKey ("PGP Public Keyring");
e95b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
975b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
d15b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
2cc1fb ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions\\PGP¶
f9b972 ·Plugin");
e5440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
dc9268 l\\" ^ UNINSTALLKEY);
3100e1 ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP55");
fcd11b ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP");
13440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
ac9268 l\\" ^ UNINSTALLKEY);
e5b379 ········RegDBDeleteKey ("SOFTWARE\\PGP\\PGP55");
51dc06 ········RegDBDeleteKey ("SOFTWARE\\Pretty Good Privacy,Inc.\\PGP 5.5");
448788 ········RegDBDeleteKey ("SOFTWARE\\Pretty Good Privacy, Inc.\\PGP 5.5");
2faf5a
ebfac4 ········RegDBDeleteValue ("SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions", ¶
ce8b55 "PGP Plugin");
41af5a
7c6eb4 ········//HKEY_USERS
7a1d88 ········RegDBSetDefaultRoot(HKEY_USERS);
9f9994 ········RegDBDeleteKey ("S-1-5-21-1998468922-181747292-2076119496-1000\\Softwar¶
88f0bb e\\PGP");
e26d97 ········ProgDefGroupType(PERSONAL);
e7ee29 ········DeleteProgramFolder ("Pretty Good Privacy");
7fc277 ········DeleteFolderIcon(FOLDER_STARTUP,"PGPtray");
92af5a
635676 ········RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
de87ce ········LongPathToShortPath (Installdir);
3caf5a
3d726d ········//Outlook Express Uninstall
f97fab ········VarSave¤¤   (SRCTARGETDIR);
1eaf5a
797cc9 ········SRCDIR = OEPATH;
f3af5a
13e574 ········TARGETDIR = OEPATH;
562b95 ········//See if the user has installed OE plugin and then upgraded OE
c336f8 ········szFileName = OEPATH ^ "msimn.exe";
10e007 ········UseDLL( "Version.dll" );
72b752 ········lSize = GetFileVersionInfoSizeA( szFileName, nHandle );
5248fe ········NumToStr( szTemp, lSize );
4783e9 ········bVerInfo = GetFileVersionInfoA( szFileName, nHandle, lSize, szVerBuffer¶
306275 );
56eaee ········ptr1 = AddressString( szResultBuffer );
04f9ed ········ptr2 = AddressNumber( ptr1 );
f5ce2f ········bVerValue = VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904b0\\Co¶
d1daaf mpanyName", ptr2, nSize);
abaf5a
e0b890 ········if (bVerValue = 0 ) then
40a56f ¤   ········bVerValue = VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904E4¶
bc350c \\CompanyName", ptr2, nSize);
4388e0 ········endif;
f9af5a
b7d5a1 ········// pszResultBuffer is a pointer to a pointer which is the starting point
--d926 000b19c2be940110222 Page 63 of setup.rul
ba99ef ········// for the company name. How do you actually get the string ?
bc5501 ········StructGetP( ptr2, "MYTYPE_PSZ", "szString", lData, szData );
27dfc0 ········UnUseDLL( "Version.dll" );
7daf5a
3ecc8b ········if (szData = "Microsoft Corporation") then
89319c ¤   ········//the user install the plugin then updated outlook
2e97c5 ¤   ········//so we DO want to use this newer file
ce6790 ¤   ········bUpgraded = TRUE;
2988e0 ········endif;
4ae574 ········TARGETDIR = OEPATH;
cfc63d ········if (bUpgraded = FALSE) then
d3af5a
543375 ¤   ········DeleteFile("msimn.exe");
cf7b53 ¤   ········RenameFile ("PGPmsimn.exe", "msimn.exe");
d41e5b ········else
a2464e ¤   ········DeleteFile("PGPmsimn.exe");
b888e0 ········endif;
1faf5a
a8af5a
53d230 ········TARGETDIR = WINSYSDIR;
432511 ········CleanSharedFile(WINSYSDIR,"PGP55oe.dll");
16d55b ········DeleteFile("PGP55oe.dll");
a6af5a
28af5a
785b89 ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP55\\OE");
74af5a
b361ea ········RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
a2440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
11b547 l\\PGPOEPlugin");
ce440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
ead784 l" ^ UNINSTALLKEY);
d2440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
bc31a0 l\\PGP55DeinstKey");
93bc7e ········szLocalDB = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
04af5a
7b5e41 ········VarRestore¤ (SRCTARGETDIR);
25af5a
9824c9 ········Delay (2);
fdaf5a
fda2be ········nIndex = nIndex + 1;
88af5a
5e1b0b ····endwhile; ··// while (nIndex < 5)
dcaf5a
8f9262 ····SdShowMsg (szMessage, FALSE);
96af5a
bdaf5a
112b3d end;
5caf5a
d5af5a
e5af5a
f5bedf /******************************************************************************
05775e ·*
3cb9bd ·* Function: ·UNINSTALL ·6.X
86775e ·*
29d094 ·* ·Purpose: ·Manually remove PGP 6.x's files because calling the uninstall
e08813 ·* ···········will not work because its uninstaller is really an install
fcaa4a ·* ···········script and two installs will not run simultaneously
36775e ·*
920deb ·* ···Input: ·
d6775e ·*
a72e89 ·* ·Returns: ·none
61775e ·*
6ae8de ·* Comments: ·Imported from the uninstall rountine
543f23 ·******************************************************************************/
8caf5a
4a9d93 function Uninstall6X ()
fdaf5a
dfaf5a
5409f5 ····STRING¤ ¤   szPubRingPath [512];
ebaf5a
97ddaa ····STRING¤ ¤   szPrivRingPath[512];
b1af5a
--7d8b 0006f170e6b40110222 Page 64 of setup.rul
fe318b ····STRING¤ ¤   szRandSeedPath[512];
0aaf5a
4492ae ····STRING¤ ¤   szKey,szName,svValue,svReturnString,szBmpName, szLocalDB, szTem¶
13cd91 p, szMsg;
baaf5a
8bcb66 ····STRING¤ ¤   Installdir,svTarget,svResult, OEinstall, svValueAdmin;
95af5a
a6e381 ····NUMBER¤ ¤   nDx,nDy,nvSize,nvType,nID_BITMAP, nResult, Reboot, nIndex, nCou¶
68b973 nter;
b8af5a
0acb84 ····HWND¤   ¤   hWnd1,hWnd2,hWnd3,hWnd4,hWnd5,hWnd6,hWnd7,hWnd8,hWnd9;
80af5a
a3c8ab ····//For outlook express
e87b14 ····STRING ·····szFileName, szVerBuffer[1536], szResultBuffer, szData;
82a991 ····LONG ·······lSize, lData;
e895fd ····POINTER ····ptr1, ptr2;
7045e3 ····NUMBER ·····nSize, nHandle;
cde430 ····BOOL ·······bVerValue, bVerInfo, bUpgraded, bDeleteAdmin, DeleteSharedDLLS;
1daf5a
8d583d ·····
2a0f89 begin
708b84 ····VarSave (SRCTARGETDIR);
f2af5a
77673c ····if (szINSTALLED_VERSION != "") then
f3d30e ········szMessage = "Uninstalling PGP " + szINSTALLED_VERSION + ". ·Please wait¶
65d729 ...";
a7842c ····else
904d9b ········szMessage = "Uninstalling. ·Please wait...";
e20eff ····endif;
ae5c99 ····SdShowMsg (szMessage, TRUE);
6caf5a
ded5c5 ¤   UseDLL (SUPPORTDIR ^ "PGPdskIH.dll");
adaf5a
f26618 ····GetSystemInfo(OS, nvOS, svOS);
49af5a
562c8b ····switch (nvOS)
32afcb ········case IS_WINDOWSNT:
7a70bd ¤   ········IS_NT = TRUE;
024902 ¤   ········if (Is (USER_ADMINISTRATOR, "") != TRUE) then
5daf5a
da5d74 ¤   ¤   ········MessageBox ("To run this uninstall you need to be logged in\n" +
0044f1 ¤   ¤   ¤   ¤   ¤   ········"with administrator privileges.",INFORMATION);·
1499bc ¤   ¤   ¤   ········abort;
7faf5a
926a43 ¤   ········endif;
4caf5a
95fd3e ········case IS_WINDOWS95:
955f5d ¤   ········IS_NT = FALSE;
2c3cf4 ····endswitch;
fdaf5a
52f933 ····// Run through this rountine 3 times, just to ensure proper file deletion
b8bd1d ····nIndex = 0;
2deb40 ····while (nIndex < 3)
c9af5a
f1a98e ········/**********************************************************************¶
ca7e9c ****
43407d ·········*
7a9e30 ·········* ·Unmount all PGPdisk volumes
ac407d ·········*
a8407d ·········*
869cea ·········**********************************************************************¶
95ac4a ****/
b88216 ········UnmountAllPGPdisks ();
d3d8f0 ¤   ¤   KillPGPdiskResident ();
6dbd6d ¤   ¤   PGPdiskCleanup ();
ce24c9 ········Delay (2);
65508e ········
4f7b18 ········nCounter = 0;
11642a ········Reboot ··= 0;
d4af5a
3323c1 ········//See if and components that use the SDK were installed
6f4de9 ········RegDBSetDefaultRoot(HKEY_CURRENT_USER);
--6920 0009625c61140110222 Page 65 of setup.rul
696c71 ········szLocalDB = "\\Software" ^ "Network Associates";
3b25b1 ········szName ···= "DelSharedFiles";
fcaf5a
6a3f48 ········DeleteSharedDLLS = FALSE;
b09f1c ········if (RegDBGetKeyValueEx (szLocalDB ^ "PGP60", szName, nvType, szName, nv¶
f5c9ff Size) = 0 ) then
15464a ············DeleteSharedDLLS = TRUE;
8888e0 ········endif;
08af5a
33dd30 ········//DELETE .DLL'S FROM WINDOWS SYSTEM DIRECTORY
47d230 ········TARGETDIR = WINSYSDIR;
5daf5a
90b227 ········if (DeleteSharedDLLS = TRUE) then
340094 ¤   ········DeleteSharedFile (WINSYSDIR, "PGP_sdk.dll");
f2a03f ¤   ········DeleteSharedFile (WINSYSDIR, "PGPsdkNL.dll");
161d35 ¤   ········DeleteSharedFile (WINSYSDIR, "PGPsdkUI.dll");
5188e0 ········endif;
67af5a
87dfa9 ········DeleteSharedFile (WINSYSDIR, "pgp60cl.dll");
53c5a8 ········DeleteSharedFile (WINSYSDIR, "pgp60mn.dll");
e65e16 ········DeleteSharedFile (WINSYSDIR, "pgp60rd.dll");
729bd3 ········DeleteSharedFile (WINSYSDIR, "pgp60sc.dll");
2e7f05 ········DeleteSharedFile (WINSYSDIR, "pgpExch.dll");
f7342b ········DeleteSharedFile (WINSYSDIR, "pgp60oe.dll");
a32b0b ········DeleteSharedFile (WINSYSDIR, "pgp60hk.dll");
0aaf5a
88757e ········DeleteFile ("randseed.bin");
0630f0 ········DeleteFile ("PGP60.hlp");
07a4d3 ········DeleteFile ("PGP60.gid");
43af5a
ede645 ········TARGETDIR = WINSYSDIR ^ "drivers";
68eabe ········DeleteSharedFile (WINSYSDIR ^ "drivers", "PGPmemlock.sys");
eeaf5a
76c1ad ········TARGETDIR = WINDIR;
d795a3 ········DeleteFile ("PGP_sdk.prf");
a6fedf ········DeleteFile ("PGPsdk.prf");
44ecb3 ········DeleteFile ("PGPMacBinaryMappings.txt");
daaf5a
d5af5a
786b92 ········//Short filename due to 95 bug
49e4ae ········DeleteSharedFile (WINDIR, "PGPMEM~1.vxd");
baaf5a
a92892 ········//GET THE PGP 6.0 INSTALLATION DIRECTORY
ab4de9 ········RegDBSetDefaultRoot(HKEY_CURRENT_USER);
18d338 ········szKey = "Software\\Network Associates\\PGP60\\PGPKeys";
51403c ········szName = "ExePath";
5daf5a
29e694 ········RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
92a342 ········ParsePath(svReturnString, svValue, PATH);
52af5a
4ebaeb ········//GET THE PGP 6.0 ADMIN INSTALLATION DIRECTORY
884de9 ········RegDBSetDefaultRoot(HKEY_CURRENT_USER);
772014 ········szKey = "SOFTWARE\\Network Associates\\PGP60\\PGPKeys";
08403c ········szName = "ExePath";
e1af5a
5a461b ········if (RegDBGetKeyValueEx (szKey, szName, nvType, svValueAdmin, nvSize) = ¶
816262 0) then
ba0fba ············bDeleteAdmin = TRUE;
6488e0 ········endif;
29af5a
0dc4a6 ········//Outlook Express install location
0292c0 ········szKey = "SOFTWARE\\Network Associates\\PGP60\\OE";
9ece12 ········szName = "OutlookExpress";
54af5a
11e694 ········RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
057512 ········OEinstall = svValue;
0daf5a
07c210 ········//DELETE FILES FROM THE PGP 6.0 INSTALL DIRECTORY
6a36b6 ········TARGETDIR = svReturnString;
8aac00 ········Installdir = svReturnString;
eeda7a ········DeleteFile ("keygen.avi");
96aa0e ········DeleteFile ("Pgp60.cnt");
--bdd6 000d1d0a7a440110222 Page 66 of setup.rul
fa4c6a ········DeleteFile ("pgp60.hlp");
e4d849 ········DeleteFile ("pgp60.gid");
e08e05 ········DeleteFile ("PGPadmin.exe");
85fcb9 ········DeleteFile ("PGPkeys.exe");
9bbf11 ········DeleteFile ("PGPlog.exe");
138f11 ········DeleteFile ("PGPtools.exe");
d2effd ········DeleteFile ("PGPtray.exe");
a4c5a5 ········DeleteFile ("Quickstart.doc");
3ccebc ········DeleteFile ("PGP_Admin.prf");
cdc2d2 ········DeleteFile ("PGP_Client.prf");
ffffad ········DeleteFile ("PGPadmin.prf");
aec3eb ········DeleteFile ("PGPclient.prf");
7d8b6e ········DeleteFile ("Eudora.url");
3c37ee ········DeleteFile ("Adobe.url");
65757e ········DeleteFile ("randseed.bin");
2c90ce ········DeleteFile ("randseed.rnd");
f46aad ········DeleteFile ("*.pdf");
3b69b0 ········DeleteFile ("*.isu");
f1849b ········DeleteFile ("uninstall.exe");
17af5a
15b26c ········TARGETDIR = svReturnString + "\\Documentation";
ca7fb5 ········DeleteFile ("license.txt");
33ad04 ········DeleteFile ("Readme.txt");
3c0fcc ········DeleteFile ("6.0.2 Change History.txt");
782bf2 ········DeleteFile ("PGP55win.pdf");
cba3dd ········DeleteFile ("PGPWinUsersGuide.pdf");
bd379d ········DeleteFile ("whatsnew.txt");
0058a9 ········DeleteFile ("whatsnew.doc");
98af5a
d484ba ········TARGETDIR = svReturnString + "\\PGPFone";
840730 ········DeleteFile ("PGPfone.pdf");
c22cd2 ········DeleteFile ("PGPfone.exe");
2c08bb ········DeleteFile ("readme.txt");
4eaf5a
14af5a
e5a4ff ········TARGETDIR = svReturnString + "\\Sample Keys";
598eea ········DeleteFile ("SampleKeys.asc");
cbcebc ········DeleteFile ("WhatIsThis.txt");
92af5a
d94b6f ········// Clean up old ClientInstaller only if this installer is an ADMIN inst¶
ab0b17 aller
c55e3c ········if (ISADMIN = "TRUE") then
55aa57 ············TARGETDIR = szPREV_PGP_PATH ^ "ClientInstaller\\Disk1";
75ad9f ············DeleteFile ("_inst32i.ex_");
790f74 ············DeleteFile ("_isdel.exe");
3be182 ············DeleteFile ("_setup.dll");
004a51 ············DeleteFile ("_setup.lib");
363e8e ············DeleteFile ("Data.1");
cbadd6 ············DeleteFile ("Disk1.id");
025800 ············DeleteFile ("License.txt");
0966cd ············DeleteFile ("Setup.bmp");
ab65f6 ············DeleteFile ("Setup.exe");
51f916 ············DeleteFile ("Setup.ini");
8a01fe ············DeleteFile ("Setup.ins");
dc78d9 ············DeleteFile ("Setup.pkg");
7cb559 ············DeleteFile ("Uninst.exe");
870d45 ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller\\Disk1", ONLYDIR);
69af5a
588f9a ············TARGETDIR = szPREV_PGP_PATH ^ "ClientInstaller\\Disk2";
5a2342 ············DeleteFile ("Data.2");
b72706 ············DeleteFile ("Disk2.id");
418e7b ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller\\Disk2", ONLYDIR);
1caf5a
489321 ············TARGETDIR = szPREV_PGP_PATH ^ "ClientInstaller\\Disk3";
562806 ············DeleteFile ("Data.3");
59a6b9 ············DeleteFile ("Disk3.id");
d7f091 ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller\\Disk3", ONLYDIR);
30af5a
4dc400 ············TARGETDIR = szPREV_PGP_PATH ^ "ClientInstaller\\Disk4";
a318da ············DeleteFile ("Data.4");
ea3ab7 ············DeleteFile ("Disk4.id");
d18016 ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller\\Disk4", ONLYDIR);
--1cec 0002fcd192740110222 Page 67 of setup.rul
e0af5a
f1d8bb ············TARGETDIR = szPREV_PGP_PATH ^ "ClientInstaller\\Disk5";
94139e ············DeleteFile ("Data.5");
48bb08 ············DeleteFile ("Disk5.id");
d0fefc ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller\\Disk5", ONLYDIR);
ccaf5a
5efd76 ············TARGETDIR = szPREV_PGP_PATH ^ "ClientInstaller\\Disk6";
b40e52 ············DeleteFile ("Data.6");
5531d8 ············DeleteFile ("Disk6.id");
407dc2 ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller\\Disk6", ONLYDIR);
85af5a
fae1cd ············TARGETDIR = szPREV_PGP_PATH ^ "ClientInstaller\\Disk7";
a80516 ············DeleteFile ("Data.7");
67b067 ············DeleteFile ("Disk7.id");
d40328 ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller\\Disk7", ONLYDIR);
93af5a
35604a ············DeleteDir (szPREV_PGP_PATH ^ "ClientInstaller", ONLYDIR);
c088e0 ········endif;
41af5a
25f2eb ········if (svReturnString != "") then
eab851 ¤   ········DeleteDir(svReturnString + "\\PGPFone", ONLYDIR);
6e218a ¤   ········// DeleteDir(svReturnString + "\\ClientInstaller", ALLCONTENTS);
7a1f0c ¤   ········DeleteDir(svReturnString + "\\TEMP", ONLYDIR);
b66b25 ¤   ········DeleteDir(svReturnString + "\\Signatures", ONLYDIR);
96c259 ¤   ········DeleteDir(svReturnString + "\\Documentation", ALLCONTENTS);
ecc5c4 ¤   ········DeleteDir(svReturnString + "\\Sample Keys", ONLYDIR);
c288e0 ········endif;
76af5a
9da2dc ········//GET THE EUDORA PLUGIN PATH
844de9 ········RegDBSetDefaultRoot(HKEY_CURRENT_USER);
38ec3b ········szKey = "SOFTWARE\\Network Associates\\PGP60\\EudoraPlugin";
d9b3af ········szName = "PluginPath";
f5af5a
c1e694 ········RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
a9af5a
d72438 ········//DELETE THE EUDORA PLUGIN
001d65 ········TARGETDIR = svValue;
e1022c ········DeleteFile ("pgpplugin.dll");
22ae92 ········//To remove files accidently installed with 6.0b14
f3173e ········DeleteFile ("pgpEudoraPluginv4.dll");
089afb ········DeleteFile ("pgpEudoraPlugin.dll");
39af5a
1f16c9 ········//DELETE REGISTRY ENTRIES
078bac ········//HKEY_CURRENT_USER
0e4de9 ········RegDBSetDefaultRoot(HKEY_CURRENT_USER);
451cd2 ········RegDBDeleteKey ("Software\\Network Associates\\PGP60");
83af5a
1aca00 ········//HKEY_CLASSES_ROOT
c5183b ········RegDBSetDefaultRoot(HKEY_CLASSES_ROOT);
d2e2e9 ········RegDBDeleteKey (".aexpk");
a25c3a ········RegDBDeleteKey (".asc");
3334ee ········RegDBDeleteKey (".bexpk");
cd14e6 ········RegDBDeleteKey (".pgd");
088db6 ········RegDBDeleteKey (".pgp");
6daaca ········RegDBDeleteKey (".pkr");
e09b66 ········RegDBDeleteKey (".prvkr");
09e2e9 ········RegDBDeleteKey (".aexpk");
30ddd7 ········RegDBDeleteKey (".pubkr");
e098e6 ········RegDBDeleteKey (".sig");
0502a4 ········RegDBDeleteKey (".skr");
f69789 ········RegDBDeleteKey (".shf");
779b3e ········RegDBDeleteKey (".pgr");
13062e ········RegDBDeleteKey (".rnd");
17e908 ········RegDBDeleteKey ("PGPdisk Volume");
5de2ed ········RegDBDeleteKey ("PGP Groups");
edaaaf ········RegDBDeleteKey ("PGP Groups File");
b618a1 ········RegDBDeleteKey ("PGP Share");
bb925e ········RegDBDeleteKey ("Randseed File");
e65de4 ········RegDBDeleteKey ("Ranseed File");
83ae6c ········RegDBDeleteKey ("CLSID\\{969223c0-26aa-11d0-90ee-444553540000}");
6e978e ········RegDBDeleteKey ("PGP Armored Encrypted File");
2f5b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
--314e 000edfd92b940110222 Page 68 of setup.rul
c363d4 ········RegDBDeleteKey ("PGP Armored Extracted Public Key");
8f999e ········RegDBDeleteKey ("PGP Detached Signature File");
52be05 ········RegDBDeleteKey ("PGP Encrypted File");
048c50 ········RegDBDeleteKey ("PGP Private Keyring");
18ba27 ········RegDBDeleteKey ("PGP Public Keyring");
815b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
c8b738 ········RegDBDeleteKey ("PGP Share File");
34af5a
e7d474 ········//HKEY_LOCAL_MACHINE
c15676 ········RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
bcd11b ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP");
f9e2e9 ········RegDBDeleteKey (".aexpk");
505c3a ········RegDBDeleteKey (".asc");
0534ee ········RegDBDeleteKey (".bexpk");
3314e6 ········RegDBDeleteKey (".pgd");
098db6 ········RegDBDeleteKey (".pgp");
3baaca ········RegDBDeleteKey (".pkr");
cf9b66 ········RegDBDeleteKey (".prvkr");
44e2e9 ········RegDBDeleteKey (".aexpk");
d0ddd7 ········RegDBDeleteKey (".pubkr");
fa98e6 ········RegDBDeleteKey (".sig");
5a02a4 ········RegDBDeleteKey (".skr");
b6ae6c ········RegDBDeleteKey ("CLSID\\{969223c0-26aa-11d0-90ee-444553540000}");
9d978e ········RegDBDeleteKey ("PGP Armored Encrypted File");
975b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
f463d4 ········RegDBDeleteKey ("PGP Armored Extracted Public Key");
91999e ········RegDBDeleteKey ("PGP Detached Signature File");
2abe05 ········RegDBDeleteKey ("PGP Encrypted File");
be8c50 ········RegDBDeleteKey ("PGP Private Keyring");
d8ba27 ········RegDBDeleteKey ("PGP Public Keyring");
e75b84 ········RegDBDeleteKey ("PGP Binary Extracted Public Key");
27c1fb ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions\\PGP¶
1bb972 ·Plugin");
160e19 ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer¶
2f6c47 \\IStatus");
da440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
2dd1aa l\\" + DEINSTALL_KEY);
da440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
1db8fa l\\PGP602DeinstKey");
262ac8 ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP60");
e8d11b ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP");
813bb1 ········RegDBDeleteKey ("SOFTWARE\\Classes\\.pgr");
4da6a1 ········RegDBDeleteKey ("SOFTWARE\\Classes\\.rnd");
d33002 ········RegDBDeleteKey ("SOFTWARE\\Classes\\PGP Groups");
f22abb ········RegDBDeleteKey ("SOFTWARE\\Classes\\PGP Groups File");
9d5a35 ········RegDBDeleteKey ("SOFTWARE\\Classes\\PGP Share");
0cbdb3 ········RegDBDeleteKey ("SOFTWARE\\Classes\\Randseed File");
33c22a ········RegDBDeleteKey ("SOFTWARE\\Classes\\Ranseed File");
4eaf5a
defac4 ········RegDBDeleteValue ("SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions", ¶
4b8b55 "PGP Plugin");
22af5a
986eb4 ········//HKEY_USERS
1c1d88 ········RegDBSetDefaultRoot(HKEY_USERS);
ad9994 ········RegDBDeleteKey ("S-1-5-21-1998468922-181747292-2076119496-1000\\Softwar¶
87f0bb e\\PGP");
5aaf5a
596d97 ········ProgDefGroupType(PERSONAL);
e8b949 ········DeleteProgramFolder ("P G P");
31c277 ········DeleteFolderIcon(FOLDER_STARTUP,"PGPtray");
b5af5a
8d726d ········//Outlook Express Uninstall
aa168d ········SRCDIR = OEinstall;
eaaf5a
f1adf5 ········TARGETDIR = OEinstall;
982b95 ········//See if the user has installed OE plugin and then upgraded OE
aab3d2 ········szFileName = OEinstall ^ "msimn.exe";
b8e007 ········UseDLL( "Version.dll" );
17b752 ········lSize = GetFileVersionInfoSizeA( szFileName, nHandle );
cb48fe ········NumToStr( szTemp, lSize );
a483e9 ········bVerInfo = GetFileVersionInfoA( szFileName, nHandle, lSize, szVerBuffer¶
ed6275 );
--68f3 0000b6b791d40110222 Page 69 of setup.rul
93eaee ········ptr1 = AddressString( szResultBuffer );
def9ed ········ptr2 = AddressNumber( ptr1 );
c5ce2f ········bVerValue = VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904b0\\Co¶
b8daaf mpanyName", ptr2, nSize);
b8af5a
71b890 ········if (bVerValue = 0 ) then
e4a56f ¤   ········bVerValue = VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904E4¶
5f350c \\CompanyName", ptr2, nSize);
9388e0 ········endif;
feaf5a
2bd5a1 ········// pszResultBuffer is a pointer to a pointer which is the starting point
bc99ef ········// for the company name. How do you actually get the string ?
015501 ········StructGetP( ptr2, "MYTYPE_PSZ", "szString", lData, szData );
37dfc0 ········UnUseDLL( "Version.dll" );
92af5a
afcc8b ········if (szData = "Microsoft Corporation") then
fa319c ¤   ········//the user install the plugin then updated outlook
7097c5 ¤   ········//so we DO want to use this newer file
ba6790 ¤   ········bUpgraded = TRUE;
bd88e0 ········endif;
04adf5 ········TARGETDIR = OEinstall;
67c63d ········if (bUpgraded = FALSE) then
a3af5a
4a3375 ¤   ········DeleteFile("msimn.exe");
e67b53 ¤   ········RenameFile ("PGPmsimn.exe", "msimn.exe");
521e5b ········else
21464e ¤   ········DeleteFile("PGPmsimn.exe");
6888e0 ········endif;
90af5a
79af5a
e1d230 ········TARGETDIR = WINSYSDIR;
186635 ········DeleteFile("PGPdskse.dll");
36af5a
415b89 ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP55\\OE");
a8af5a
3b61ea ········RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
cc440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
74b547 l\\PGPOEPlugin");
daaf5a
1cbc7e ········szLocalDB = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
5eaf5a
8bfeec ········RegDBSetKeyValueEx
8c61bd ········(szLocalDB,"uninstall.exe",REGDB_STRING,"command /c del " + OEinstall ^¶
7439ff "uninstall.exe" ,-1);
afaf5a
04a1fe ¤   ····TARGETDIR = svReturnString ^ "signatures";
90feee ¤   ····DeleteFile ("*.sig");
16c15b ¤   ····DeleteFile ("*.*.sig");
a52edf ¤   ····DeleteDir ·(svReturnString ^ "signatures", ONLYDIR);
38af5a
30fab6 ¤   ····TARGETDIR = svReturnString;
3aaf5a
de3412 ¤   ····DeleteFile ("pgpdiskresident.exe");
31b6cd ¤   ····DeleteFile ("pgpdisk.exe");
d8588a ¤   ····DeleteFile ("pgpdisk.hlp");
3b0b4e ¤   ····DeleteFile ("pgpdisk.cnt");
9c9d2f ¤   ····DeleteFile ("pgpdisk.pdf");
db54d1 ¤   ····DeleteFile ("readme.txt");
f0b3b5 ¤   ····DeleteFile ("license.txt");
dbaf5a
41028f ¤   ····TARGETDIR = WINSYSDIR;
1dd4b4 ¤   ¤   ····DeleteFile ("pgpdskSE.dll");
e9af5a
6dbc4e ¤   ····if (IS_NT) then
d9edef ¤   ¤   ····TARGETDIR = WINSYSDIR ^ "Drivers";
08156f ¤   ¤   ····DeleteFile ("pgpdisk.sys");
8d8415 ¤   ····else
8d4153 ¤   ¤   ····TARGETDIR = WINSYSDIR ^ "Iosubsys";
d7c12a ¤   ¤   ····DeleteFile ("pgpdisk.pdr");
0e6f45 ¤   ····endif;
34af5a
0b6d07 ¤   ····Delay (2);
--670e 000416d441240110222 Page 70 of setup.rul
e0af5a
904a6e ¤   ····//Deleting registry Entries.
1baf5a
daffc5 ¤   ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
71af5a
571ecf ¤   ····RegDBDeleteKey ("Enum\\Root\\PGPdisk");
1bc496 ¤   ····RegDBDeleteKey ("System\\CurrentControlSet\\Services\\Class\\PGPdisk");
3faf5a
71c157 ¤   ····RegDBSetDefaultRoot (HKEY_CLASSES_ROOT);
15af5a
4b7bcd ¤   ····RegDBDeleteKey (".pgd");
bedae9 ¤   ····RegDBDeleteKey ("PGPdisk Volume File");
2f7e7b ¤   ····RegDBDeleteKey ("CLSID\\{f8b14440-3785-11d1-b363-5c6f08c10000}");
75720e ¤   ····RegDBDeleteKey ("PGPdisk Volume File\\shellex\\ContextMenuHandlers\\PGP¶
6ad915 disk Shell Extension");
73f735 ¤   ····RegDBDeleteKey ("Drive\\shellex\\ContextMenuHandlers\\PGPdisk Shell Ext¶
b3e28c ension");
15ef52 ¤   ····RegDBDeleteValue ("Drive\\shellex\\ContextMenuHandlers", "");
c5df8f ¤   ····RegDBDeleteKey ("PGPdisk Volume");
6faf5a
00ffc5 ¤   ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
adaf5a
b41212 ¤   ····RegDBDeleteValue ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell ¶
cdce7c Extensions\\Approved",
0cecbf ¤   ¤   ¤   ¤   ¤   ······"{f8b14440-3785-11d1-b363-5c6f08c10000}" );
16f0bf ¤   ····RegDBDeleteKey ("Enum\\ESDI\\PGP_____PGPDISK_________0");
35e987 ¤   ····RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdisk");
758269 ¤   ····RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdiskAlpha");
826e1d ¤   ····RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdisk Beta");
12473a ¤   ····RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdiskBeta");
7c5b5a ¤   ····RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
038a92 l\\PGPdiskDeinstKey");
ff7e17 ¤   ····RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Path¶
617ec0 s\\PGPdisk.exe");
7f7e17 ¤   ····RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Path¶
685a39 s\\PGPdiskResident.exe");
dfdc8b ¤   ····RegDBDeleteKey ("SOFTWARE\\Classes\\PGPdisk Volume");
11af5a
069485 ¤   ····RegDBSetDefaultRoot (HKEY_CURRENT_USER);
d3af5a
bcd5d3 ¤   ····RegDBDeleteKey ("Software\\Network Associates\\PGPdisk");
4401dd ¤   ····RegDBDeleteKey ("Software\\Network Associates\\PGPdiskAlpha");
adc3cd ¤   ····RegDBDeleteKey ("Software\\Network Associates\\PGPdiskBeta");
a526e9 ¤   ····RegDBDeleteKey ("Software\\PGP\\PGPdisk");
87cb42 ¤   ····RegDBDeleteKey ("Software\\PGP\\PGPdiskAlpha");
3f30c1 ¤   ····RegDBDeleteKey ("Software\\PGP\\PGPdiskBeta");
c2af5a
80bc4e ¤   ····if (IS_NT) then
fa51c4 ¤   ¤   ····RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
ed3b6c ¤   ¤   ····RegDBDeleteKey ("System\\CurrentControlSet\\Services\\PGPdisk");
4b1181 ¤   ¤   ····RegDBDeleteKey ("System\\CurrentControlSet\\Services\\EventLog\\Sys¶
eac2a7 tem\\PGPdisk");
3b6f45 ¤   ····endif;
2caf5a
b424c9 ········Delay (2);
8faf5a
53a2be ········nIndex = nIndex + 1;
acaf5a
4c1b0b ····endwhile; ··// while (nIndex < 5)
1faf5a
edec40 ¤   UnUseDLL (SUPPORTDIR ^ "PGPdskIH.dll");
f9af5a
5c9262 ····SdShowMsg (szMessage, FALSE);
8eaf5a
b70a47 ····VarRestore (SRCTARGETDIR);
01af5a
037705 ····SetDialogTitle (DLG_MSG_INFORMATION,"Uninstall complete");
ec673c ····if (szINSTALLED_VERSION != "") then
15a197 ········MessageBox ("PGP " + szINSTALLED_VERSION + " has been uninstalled. Your¶
425228 ·key files have not been\n" +
6d151a ¤   ¤   ¤   ········"removed. ·You may wish to store them in a safe place.", IN¶
411e39 FORMATION);
--7d18 000fb3c250c40110222 Page 71 of setup.rul
9c842c ····else
d8fc26 ········MessageBox ("PGP has been uninstalled. Your key files have not been\n" +
1e151a ¤   ¤   ¤   ········"removed. ·You may wish to store them in a safe place.", IN¶
241e39 FORMATION);
650eff ····endif;
0daf5a
1e2ce7 ····if (Reboot = 1) then
371fdb ········if (szINSTALLED_VERSION != "") then
0c9949 ¤   ········szTemp = "Setup has completed uninstalling "
5c7e86 ¤   ···············+ szINSTALLED_VERSION + ".";
fd1e5b ········else
b189b3 ¤   ········szTemp = "Setup has completed uninstalling PGP.";
d188e0 ········endif;
88af5a
c8bda5 ¤   ····szMsg = "Some files could not be deleted because "
9315e6 ··············+ "they are currently in use by other programs "
95d447 ··············+ "on the system. ·Files in use will be deleted "
a0e334 ··············+ "the next time you restart your system. You will "
35aaad ··············+ "need to reboot before installing any PGP products.";
b0af5a
22e19f ¤   ····// If SdFinishReboot reboots the system,the shared file data is
9475d0 ¤   ····// automatically recorded.
1eb563 ¤   ····RebootDialog ("Restart Windows", szMsg, SYS_BOOTMACHINE);
e60eff ····endif;
8faf5a
edaf5a
0266a6 end; ···// function Uninstall6X ()
12af5a
65af5a
5faf5a
aaaf5a
c0af5a
e6bedf /******************************************************************************
5c775e ·*
c780cc ·* Function: ···Uninstall_PGPdisk10
06775e ·*
f19adf ·* ·Purpose: ···This function will check if a library is shared before deleteing
3c775e ·*
d16918 ·* ···Input:
ee775e ·*
623e20 ·* ·Returns:
e9775e ·*
31412a ·* Comments:
bb775e ·*
463f23 ·******************************************************************************/
65af5a
5af423 function Uninstall_PGPdisk10 ()
0daf5a
6fc6fa ····STRING ·szKey,szName,svValue,svReturnString,szBmpName, svResult,
5d5b78 ············szrepdKey, svrepdValue, szLocalDB, szTemp, szMsg, szDisplay,
6ec73f ············szStr, svStr;
3faf5a
e32209 ····NUMBER ·LockedFiles, Reboot, RC, nvVar, nIndex,
2df349 ············nDx,nDy,nvSize,nvType,nID_BITMAP, nDisplay, nvLine;
1faf5a
47cc39 ····HWND ···hWnd1;
16af5a
ab0f89 begin
f78b84 ····VarSave (SRCTARGETDIR);
b7af5a
5fbd2a ····// Ensure that this is TRUE since this uninstall function was called
9cf4e9 ····nFND_PGPDISK = TRUE;
d5af5a
4f23ff ····SdShowMsg ("Uninstalling PGPdisk. ·Please wait...", TRUE);
19869e ····
16b425 ····// Loop 3 times to ensure proper file deletion
10bd1d ····nIndex = 0;
9baf5a
c9eb40 ····while (nIndex < 3)
db60c1 ········//Ensure that PGPdisk is not running
1c10d8 ········while (FindWindow ("", "PGPdisk") != NULL)
fb651b ············szMsg = "Setup was unable to shut down PGPdisk. ·Please shut it dow¶
--4fe3 000348dc87d40110222 Page 72 of setup.rul
3e8ee1 n and then click on OK."
6eeb5d ··················+ "\n\nCTRL + TAB to switch between applications";
0d50b7 ¤   ········
6fa882 ············MessageBox( szMsg, WARNING );
8f0c68 ············Delay (3);
c331d3 ········endwhile;
54af5a
8ba98e ········/**********************************************************************¶
2a7e9c ****
79407d ·········*
ba9342 ·········* ·Unmount all PGPdisk volumes, PGPdisk 1.0
34407d ·········*
86407d ·········*
0b9cea ·········**********************************************************************¶
05ac4a ****/
4f6712 ········//GET THE INSTALLATION DIRECTORY
525676 ········RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
4be733 ········szKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\PGPdi¶
c9c983 sk.exe";
7edb28 ········szName = "";
75af5a
a5e694 ········RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
4daf5a
4194de ········ParsePath (svReturnString, svValue, PATH);
8baf5a
b5da60 ········//try and unmount all
af2b1e ········LaunchAppAndWait (svValue, "unmountall" , WAIT);
b7af5a
6936ed ········//launch pgpdisk count to see if any disks are mounted
efaf5a
5d9cc6 ········LaunchAppAndWait (svValue, "count" , WAIT);
48af5a
b6f5b7 ········LaunchAppAndWait (svValue, "cleanup" , WAIT);
7baf5a
474de9 ········RegDBSetDefaultRoot(HKEY_CURRENT_USER);
e49878 ········szKey = "Software\\Network Associates\\PGPdisk";
143447 ········szName = "NumMountedPGPdisks";
fdaf5a
7be694 ········RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
7eaf5a
c3af5a
a9c325 ········StrToNum (nvVar, svValue);
45af5a
df508e ········
35956a ········/*********
3de832 ········if (nvVar > 0) then
79d15a ¤   ········if (AskYesNo("Uninstall has found mounted PGPdisks on your machine,¶
af00ff ·it is recommended\n" +
3a8ba8 ¤   ¤   ¤   ·········"that you unmount all PGPdisks before uninstalling PGPdisk¶
e38ab4 . If you do not\n" +
ba49eb ¤   ¤   ¤   ·········"do this you will need to reboot your machine at the end o¶
986417 f the uninstall.\n\n" +
193ffe ¤   ¤   ¤   ·········"Do you want to Exit and unmount your PGPdisks?",YES) = YE¶
fb3bb3 S) then
050a51 ¤   ¤   ········exit;
72abca ¤   ········else
1c05ae ¤   ¤   ········Reboot = 1;
ca6a43 ¤   ········endif;
b888e0 ········endif;
4a4482 ········***********/
0caf5a
54af5a
75d8ec ········SRCDIR = svReturnString;
5436b6 ········TARGETDIR = svReturnString;
d9af5a
2c7895 ········TARGETDIR = svReturnString ^ "signatures";
0da2ae ········DeleteFile ("pgpdisk.exe.sig");
db9a67 ········DeleteFile ("PGPdskSE.dll.sig");
b83dac ········DeleteFile ("Pgpdisk.pdr.sig");
552146 ········DeleteDir ·(svReturnString ^ "signatures", ONLYDIR);
42af5a
3436b6 ········TARGETDIR = svReturnString;
--cc9d 00010fc7bb640110222 Page 73 of setup.rul
a1bd35 ¤   ········if (RC != 0) then
3605ae ¤   ¤   ········Reboot = 1;
2865b4 ¤   ¤   ········szStr = svReturnString ^ "pgpdisk.exe";
69e82f ¤   ¤   ········if (FileGrep("Wininit.ini", szStr, svStr, nvLine, RESTART) < 0)¶
23f693 ·then
08c1e1 ¤   ¤   ¤   ········if AddProfString(WINDIR ^ "Wininit.ini", "Rename", "NUL", s¶
137065 zStr) < 0 then
39b34b ¤   ¤   ¤   ········endif;
bf51aa ¤   ¤   ········endif;
886a43 ¤   ········endif;
477acd ········DeleteFile ("pgpdisk.exe");
03948a ········DeleteFile ("pgpdisk.hlp");
a5c74e ········DeleteFile ("pgpdisk.cnt");
83512f ········DeleteFile ("pgpdisk.pdf");
ad08bb ········DeleteFile ("readme.txt");
237fb5 ········DeleteFile ("license.txt");
55849b ········DeleteFile ("uninstall.exe");
71af5a
33d230 ········TARGETDIR = WINSYSDIR;
4faf5a
d247c0 ········RC = DeleteFile ("PGPdskSE.dll");
e2bd35 ¤   ········if (RC != 0) then
7905ae ¤   ¤   ········Reboot = 1;
7e7128 ¤   ¤   ········szStr = WINSYSDIR ^"PGPdiskShellExt.dll";
f3e82f ¤   ¤   ········if (FileGrep("Wininit.ini", szStr, svStr, nvLine, RESTART) < 0)¶
fef693 ·then
c5c1e1 ¤   ¤   ¤   ········if AddProfString(WINDIR ^ "Wininit.ini", "Rename", "NUL", s¶
7f7065 zStr) < 0 then
56b34b ¤   ¤   ¤   ········endif;
ef51aa ¤   ¤   ········endif;
856a43 ¤   ········endif;
35af5a
a2a982 ········TARGETDIR = WINSYSDIR ^ "Iosubsys";
bcaf5a
4514d2 ········RC = DeleteFile ("Pgpdisk.pdr");
c1bd35 ¤   ········if (RC != 0) then
4805ae ¤   ¤   ········Reboot = 1;
432c25 ¤   ¤   ········szStr = WINDIR ^ "Iosubsys" ^"pgpdisk.pdr";
fce82f ¤   ¤   ········if (FileGrep("Wininit.ini", szStr, svStr, nvLine, RESTART) < 0)¶
8cf693 ·then
9ec1e1 ¤   ¤   ¤   ········if AddProfString(WINDIR ^ "Wininit.ini", "Rename", "NUL", s¶
c07065 zStr) < 0 then
58b34b ¤   ¤   ¤   ········endif;
6d51aa ¤   ¤   ········endif;
d56a43 ¤   ········endif;
7daf5a
c94aa2 ········//Deleting registry Entries.
d861ea ········RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
2baf5a
4da32e ········RegDBDeleteKey ("Enum\\Root\\PGPdisk");
036c79 ········RegDBDeleteKey ("System\\CurrentControlSet\\Services\\Class\\PGPdisk");
d7af5a
05376d ········RegDBSetDefaultRoot (HKEY_CLASSES_ROOT);
a3af5a
1714e6 ········RegDBDeleteKey (".pgd");
94e908 ········RegDBDeleteKey ("PGPdisk Volume");
e86708 ········RegDBDeleteKey ("PGPdisk Volume File");
9142b8 ········RegDBDeleteKey ("CLSID\\{f8b14440-3785-11d1-b363-5c6f08c10000}");
a66d5f ········RegDBDeleteKey ("PGPdisk Volume File\\shellex\\ContextMenuHandlers\\PGP¶
12d915 disk Shell Extension");
18e864 ········RegDBDeleteKey ("Drive\\shellex\\ContextMenuHandlers\\PGPdisk Shell Ext¶
6ce28c ension");
435794 ········RegDBDeleteValue ("Drive\\shellex\\ContextMenuHandlers", "");
32af5a
7961ea ········RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
05af5a
9d0d43 ········RegDBDeleteValue ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell ¶
a1ce7c Extensions\\Approved",
d84877 ¤   ¤   ¤   ¤   ··········"{f8b14440-3785-11d1-b363-5c6f08c10000}" );
5daf5a
a0340f ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdisk");
1021eb ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdiskAlpha");
--79df 0017f7ba65440110222 Page 74 of setup.rul
74cd9f ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdisk Beta");
b8fffc ········RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdiskBeta");
14440b ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstal¶
6e8a92 l\\PGPdiskDeinstKey");
886146 ········RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Path¶
477ec0 s\\PGPdisk.exe");
0962bf ········RegDBSetDefaultRoot (HKEY_CURRENT_USER);
3caf5a
ee085b ········RegDBDeleteKey ("Software\\Network Associates\\PGPdisk");
f4a25f ········RegDBDeleteKey ("Software\\Network Associates\\PGPdiskAlpha");
467b0b ········RegDBDeleteKey ("Software\\Network Associates\\PGPdiskBeta");
b1ff82 ········RegDBDeleteKey ("Software\\PGP\\PGPdisk");
492c06 ········RegDBDeleteKey ("Software\\PGP\\PGPdiskAlpha");
8e7a21 ········RegDBDeleteKey ("Software\\PGP\\PGPdiskBeta");
84af5a
77e761 ········DeleteProgramFolder (FOLDER_STARTMENU ^ "Programs\\PGPdisk");
3daf5a
0d5676 ········RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
4eaf5a
ab24c9 ········Delay (2);
38af5a
8ea2be ········nIndex = nIndex + 1;
96af5a
90af5a
8f269d ····endwhile;
74af5a
83942d ····SdShowMsg ("Uninstalling PGPdisk. ·Please wait...", FALSE);
3daf5a
d50a47 ····VarRestore (SRCTARGETDIR);
58af5a
ac2ce7 ····if (Reboot = 1) then
10cfcc ¤   ····szMsg ·= "Some files could not be deleted because hey are currently in ¶
5af584 use by other programs "
1771f3 ···············+ "on the system. ·Files in use will be deleted the next time yo¶
0023bd u restart your system. "
3cfd9b ···············+ "You will need to reboot before installing any PGP products.";
92da86 ¤   ····
add31d ¤   ····RebootDialog ("Restart Windows",szMsg,SYS_BOOTMACHINE);
960eff ····endif;
83af5a
aaaf5a
2308d0 end; ···// function Uninstall_PGPdisk ()
0daf5a
9daf5a
96af5a
c36596 // This is required at the very end of this file for compilation
7f9fc0 #include "sddialog.rul"¶
--a263 0014c04aab340110223 Page 1 of BUILD.BAT
aaad7e @echo off
aeaf5a
99895b rem ....Build components...
b94920 SET Installshield_Path=c:\ishield
b396f6 SET INSTRC=%Installshield_Path%\Dialogs\Include·
372a91 SET Installshield_Program_Path=%Installshield_Path%\Program
d205f7 SET COMPILE=%Installshield_Program_Path%\compile.exe
53f624 SET ICOMP=%Installshield_Program_Path%\icomp.exe ·······
08139c SET PACK=%Installshield_Program_Path%\packlist.exe
24e030 SET SPLIT=%Installshield_Program_Path%\split.exe
90af5a
546626 echo. > Disk1\Disk1.id
74af5a
7cdf1f if EXIST tempstuff\_setup.lib del /Q tempstuff\_setup.lib
a3c356 copy %Installshield_Path%\_isres.dll tempstuff\
8d9a32 copy %Installshield_Path%\setup.exe Disk1\
5c03e6 copy %Installshield_Path%\_inst32i.ex_ Disk1\
7c216a copy %Installshield_Path%\_isdel.exe Disk1\
a80461 copy %Installshield_Path%\_setup.dll Disk1\
bcaf5a
64c9ca %COMPILE% Uninst~1\setup.rul -g
2b8fa5 if not exist Uninst~1\setup.ins pause
5baf5a
99d764 copy Uninst~1\setup.ins disk1
52af5a
49bebd %ICOMP% -i tempstuff\*.* tempstuff\_setup.lib
ccaf5a
5b631f ECHO.
617f53 ECHO Copy Output to Disk1
4c8811 copy tempstuff\_setup.lib disk1
--b0c0 0018a86a29040110224 Page 1 of SETUP.INI
a279c5 [Startup]
5119f4 AppName=PGP 6.0
2fb690 FreeDiskSpace=181
8a640b 16on16=N
--e15a 0013b351a0040110225 Page 1 of SETUP.LST
f92122 1;
3b7dc9 ..\disk1\data.z
--ebd3 000d102c98240110226 Page 1 of setup.rul
968b2f // $Id: setup.rul,v 1.62.4.5.2.2 1998/11/14 00:10:05 heller Exp $
aa191f //____________________________________________________________________________
2b53fb //¤ Copyright (C) 1997 Pretty Good Privacy, Inc.
b8ec97 //¤ All rights reserved.
60465d //
88c8ca //¤ Uninstall for PGP for Windows 95/NT
51191f //____________________________________________________________________________
c6af5a
d4c83e declare
4b1a70 #include "SDDIALOG.H"
77af5a
905c9b #ifndef INCLUDEPGPDISK
72caa9 ¤   #define INCLUDEPGPDISK¤ ¤   ¤   "TRUE" ·// TRUE or FALSE¤   ¤   ·¤  ¤   ¤
847454 #endif
caaf5a
0123e2 #define PGP_HIDDEN_WINDOW¤  ¤   ¤   "PGPtray_Hidden_Window"
449cef #define WM_CLOSE¤   ¤   ¤   ¤   ¤   0x0010 // defines the WM_CLOSE message.
bc24a6 #define TITLE¤  ¤   ¤   ¤   ¤   ¤   "PGP 6.0.2"
f8894b #define APP_NAME¤   ¤   ¤   ¤   ¤   "PGP 6.0.2"
b2368d #define VERSIONNUM¤ ¤   ¤   ¤   ¤   "PGP 6.0.2"
b10968 #define UNINSTALLKEY¤   ¤   ¤   ····"PGP60"
0f0821 #define MB_OKCANCEL¤¤   ¤   ¤   ¤   1
20b620 #define IDCANCEL¤   ¤   ¤   ¤   ¤   2
8960cd #define IDRETRY ¤   ¤   ¤   ¤   ¤   4
eb9bf7 #define MB_RETRYCANCEL¤ ¤   ¤   ¤   5
2c8ced #define IDYES¤  ¤   ¤   ¤   ¤   ¤   6
deaf5a
df3b54 //¤ FUNCTION PROTOTYPES
c85f22 prototype¤  LONG VERSION.GetFileVersionInfoSizeA( STRING, BYREF LONG );
3536c6 prototype¤  BOOL VERSION.GetFileVersionInfoA( STRING,LONG,LONG,BYREF STRING );·
de06cd prototype¤  BOOL VERSION.VerQueryValueA( BYREF STRING,STRING,BYREF POINTER,BYRE¶
ef8a34 F NUMBER);
b76c39 prototype¤  BOOL PGPdskIH.AreAnyPGPdisksMounted ();
795ede prototype¤  BOOL PGPdskIH.UnmountAllPGPdisks ();
650c9d prototype¤  PGPdskIH.KillPGPdiskResident();
624fdc prototype¤  DeleteSharedFile (STRING,STRING);
6bbca9 prototype¤  PGPdskIH.PGPdiskCleanup ··();
85af5a
ddfe8c BOOL¤   ¤   IS_NT;
83af5a
fb3451 STRING¤ ¤   szPubRingPath [512];
c7e00e STRING¤ ¤   szPrivRingPath[512];
f40c2f STRING¤ ¤   szRandSeedPath[512];
009de9 STRING¤ ¤   szKey,szName,svValue,svReturnString,szBmpName, szLocalDB, szTemp, s¶
4c5ac9 zMsg;
e71616 STRING¤ ¤   Installdir,svTarget,svResult, OEinstall;
b453f0 STRING¤ ¤   svOS, szDisplay, svValueAdmin;
a15c90 NUMBER¤ ¤   nDx,nDy,nvSize,nvType,nID_BITMAP, nResult, Reboot;
655095 NUMBER¤ ¤   nvOS, nDisplay,nCounter;
547c9c HWND¤   ¤   hWnd1,hWnd2,hWnd3,hWnd4,hWnd5,hWnd6,hWnd7,hWnd8,hWnd9, hWnd;
aeaf5a
44ef86 //For outlook express
238013 STRING szFileName, szVerBuffer[1536], szResultBuffer, szData;
e34297 LONG lSize, lData;
af8371 POINTER ptr1, ptr2;
f1b71b NUMBER nSize, nHandle;
c5cee6 BOOL bVerValue, bVerInfo, bUpgraded, bDeleteAdmin, DeleteSharedDLLS;
7aaf5a
fc88b8 typedef MYTYPE_PSZ
060f89 begin
177617 ¤   STRING szString[24];
402b3d end;
3daf5a
18c30c program
b4af5a
54a27a start:
ccdd33 nCounter = 0;
01af5a
d00918 //SETUP THE SCREEN
390c68 GetExtents(nDx,nDy);
37cdac Enable(FULLWINDOWMODE);
d1c7a5 Enable(INDVFILESTATUS);
--17a0 0008359a45b40110226 Page 2 of setup.rul
5cd273 SetColor(BACKGROUND,BK_BLUE);
ad4034 SetColor(STATUSBAR,BLUE); ····// Bright blue.
8400b7 Enable(DIALOGCACHE);
3daf5a
e3de52 SetFont(FONT_TITLE, STYLE_BOLD | STYLE_ITALIC, "Times New Roman");
f2af5a
3d6088 GetSystemInfo (VIDEO, nDisplay, szDisplay);
a3765f if (nDisplay = IS_EGA) then
b8b661 ¤   SetTitle(TITLE + " - Uninstall", 10, WHITE); // Maybe 10
63329c elseif (nDisplay = IS_VGA) then
deb753 ¤   SetTitle(TITLE + " - Uninstall", 12, WHITE);
452c06 elseif (nDisplay = IS_SVGA) then
ebe906 ¤   SetTitle(TITLE + " - Uninstall", 16, WHITE);
be6e1f elseif (nDisplay = IS_XVGA) then
1da0db ¤   SetTitle(TITLE + " - Uninstall", 18, WHITE);
a9d971 elseif (nDisplay = IS_UVGA) then
f0c5ca ¤   SetTitle(TITLE + " - Uninstall", 24, WHITE);
31523c else
c79b9f ¤   SetTitle(TITLE + " - Uninstall", 20, WHITE);
f728d5 endif;
d0af5a
c3835b Reboot = 0;
eeb60d GetSystemInfo(OS, nvOS, svOS);
d3af5a
d53bc5 switch (nvOS)
4daf5a
3f6111 case IS_WINDOWSNT:
0c9496 ¤   IS_NT = TRUE;
f0de93 ¤   if (Is (USER_ADMINISTRATOR, "") != TRUE) then
17af5a
949ffe ¤   ¤   MessageBox ("To run this uninstall you need to be logged in\n" +
b52bc7 ¤   ¤   ¤   ¤   ¤   "with administrator privileges.",INFORMATION);·
9517e9 ¤   ¤   ¤   exit;
93af5a
8beb6d ¤   endif;
cbaf5a
fe33e4 case IS_WINDOWS95:
22c068 ¤   IS_NT = FALSE;
e4baeb endswitch;
fdaf5a
dba9fc //MAKE SURE THE USER REALLY WANTS TO UNINSTALL
a3fd4b SetDialogTitle (DLG_ASK_YESNO,"Confirm uninstall");
e92a04 if (AskYesNo("Are you sure you want to Uninstall "+VERSIONNUM¤  +"?",NO) = NO) ¶
372830 then
d93e1e ¤   exit;
8028d5 endif;
e2af5a
6f0a94 SdShowMsg ("Uninstalling... Please wait.", TRUE);
faaf5a
40fd54 hWnd = FindWindow(PGP_HIDDEN_WINDOW,"");
9b732f if (hWnd > 0) then
6b3f41 ¤   if (AskYesNo("For uninstall to continue PGPtray must not be running.\n\n" +
6d0eb3 ¤   ¤   ¤   ¤   ·"Would you like setup to shut down PGPtray?",YES) = YES) then
22d1aa ¤   ¤   SendMessage(hWnd,WM_CLOSE,0,0);
deff14 ¤   ¤   //Longer delay needed for correct shut down of tray
5177a8 ¤   ¤   Delay(10);
670e24 ¤   else
fbd448 ¤   ¤   MessageBox ("PGPtray must not be running to install this product.", INF¶
914e94 ORMATION);
4d925c ¤   ¤   exit;
83eb6d ¤   endif;
2228d5 endif;
0bd73e Delay(4);
6faf5a
d94a0b TestForRunningApps:
29af5a
04af5a
d6e263 //ENSURE NO PLUGINS\DLL's ARE IN USE
05af5a
2f9ba7 if (INCLUDEPGPDISK = "TRUE") then
5c2dae ¤   if (FindWindow ("", "PGPdisk") != NULL) then
831444 ¤   ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s",
--2c2c 0000e41512a40110226 Page 3 of setup.rul
253fb4 ¤   ¤   ¤   "Please shut down PGPdisk before continuing.") = IDCANCEL) then
8b59cc ¤   ¤   ¤   SendMessage(hWnd,WM_CLOSE,0,0);
0c17e9 ¤   ¤   ¤   exit;
720e1d ¤   ¤   else
9a4fea ¤   ¤   ¤   MessageBox ("PGPdisk must not be running to install this product.",¶
10bf87 ·INFORMATION);
668ad7 ¤   ¤   endif;
94eb6d ¤   endif;
c728d5 endif;
c0af5a
5e082e hWnd2 = FindWindow("Microsoft Exchange 4.0 Viewer","");
1df4aa if (hWnd2 != NULL) then
19d6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
a2f1c6 to continue Microsoft Exchange must not be" +
34c47f ¤   " running.\nPlease shut down Microsoft Exchange.")= IDCANCEL) then
ea925c ¤   ¤   exit;
930e24 ¤   else
870f23 ¤   ¤   goto TestForRunningApps;
0beb6d ¤   endif;
0828d5 endif;
c0af5a
d3af5a
5367c3 hWnd3 = FindWindow("Microsoft Exchange 5.0 Viewer","");
907aba if (hWnd3 != NULL) then
8fd6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
87f1c6 to continue Microsoft Exchange must not be" +
b16c20 ¤   " running.\nPlease shut down Microsoft Exchange.") = IDCANCEL) then
a7925c ¤   ¤   exit;
870e24 ¤   else
900f23 ¤   ¤   goto TestForRunningApps;
efeb6d ¤   endif;
0828d5 endif;
c5af5a
649ae3 hWnd4 = FindWindow("rctrl_renwnd32","");
b92271 if (hWnd4!= NULL) then
5ed6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
1fb461 to continue Microsoft Outlook must not be" +
2fe60f ¤   " running.\nPlease shut down Microsoft Outlook.") = IDCANCEL) then
65925c ¤   ¤   exit;
470e24 ¤   else
fc0f23 ¤   ¤   goto TestForRunningApps;
6eeb6d ¤   endif;
9328d5 endif;
7daf5a
a5af5a
6af551 hWnd5 = FindWindow("EudoraMainWindow","");
5246e9 if (hWnd5 != NULL) then
24d6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
39868f to continue Eudora must not be running.\n"+
e14d40 ¤   "Please shut down Eudora.") = IDCANCEL) then
bf925c ¤   ¤   exit;
3a0e24 ¤   else
370f23 ¤   ¤   goto TestForRunningApps;
3deb6d ¤   endif;
1328d5 endif;
daaf5a
0a9128 hWnd6 = FindWindow("PGPAdminWizardClass","");
bcdcc8 if (hWnd6 != NULL) then
07d6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
c36012 to continue the admin wizard must not be" +
978d5a ¤   " running.\nPlease shut down the admin. wizard.") = IDCANCEL) then
33925c ¤   ¤   exit;
8d0e24 ¤   else
2f0f23 ¤   ¤   goto TestForRunningApps;
fbeb6d ¤   endif;
4128d5 endif;
8faf5a
881b48 hWnd7 = FindWindow("PGPkeysMainWinClass","");
c352d8 if (hWnd7 != NULL) then
6dd6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
e00037 to continue PGPkeys must not be running.\n"+
0e65f3 ¤   "Please shut down PGPkeys.") = IDCANCEL) then
--3c53 0001a94582b40110226 Page 4 of setup.rul
36925c ¤   ¤   exit;
210e24 ¤   else
800f23 ¤   ¤   goto TestForRunningApps;
a8eb6d ¤   endif;
0e28d5 endif;
14af5a
58aa0a hWnd8 = FindWindow("PGPtools","");
23b05f if (hWnd8 != NULL) then
d2d6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
001dbc to continue PGPtools must not be running.\n"+
159e19 ¤   "Please shut down PGPtools.") = IDCANCEL) then
01925c ¤   ¤   exit;
dd4264 ¤   else·
d40f23 ¤   ¤   goto TestForRunningApps;
1eeb6d ¤   endif;
6528d5 endif;
68af5a
cf0f3d hWnd9 = FindWindow("PGPlog","");
613e4f if (hWnd9 != NULL) then
75d6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
6608f7 to continue PGPLog must not be running.\n"+
3bf1f5 ¤   "Please shut down PGPLog.") = IDCANCEL) then
a5925c ¤   ¤   exit;
ce0e24 ¤   else
350f23 ¤   ¤   goto TestForRunningApps;
4deb6d ¤   endif;
3528d5 endif;
beaf5a
0582cc //Ensure that Outlook Express is not running
c88ea5 if (FindWindow ("ThorBrowserWndClass", "") != NULL) then
b7d6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
1905b7 to continue Outlook Express must not be running.\n"+
638de0 ¤   "Please shut down Outlook Express.") = IDCANCEL) then
08925c ¤   ¤   exit;
300e24 ¤   else
a70f23 ¤   ¤   goto TestForRunningApps;
20eb6d ¤   endif;
1328d5 endif;
13af5a
415166 if (FindWindow ("Ath_Note", "") != NULL) then
9dd6eb ¤   if (SprintfBox (MB_RETRYCANCEL, "Application Running", "%s","For uninstall ¶
0205b7 to continue Outlook Express must not be running.\n"+
b88de0 ¤   "Please shut down Outlook Express.") = IDCANCEL) then
0f925c ¤   ¤   exit;
950e24 ¤   else
ee0f23 ¤   ¤   goto TestForRunningApps;
7deb6d ¤   endif;
3e28d5 endif;
10af5a
ea7263 //AT THIS POINT ALL FILES SHOULD BE FREE
28af5a
b69ba7 if (INCLUDEPGPDISK = "TRUE") then
5f61ce ¤   //Shut down PGPdisk Resident and try to unmount all PGPdisks
e9d5c5 ¤   UseDLL (SUPPORTDIR ^ "PGPdskIH.dll");
19341b ¤   ¤   KillPGPdiskResident();
f4af5a
f5827d ¤   ¤   if (UnmountAllPGPdisks() = FALSE) then
c4bd7c ¤   ¤   ¤   //cant unmount all PGPdisks so warn user
ea034b ¤   ¤   ¤   if (AskYesNo("Uninstall has found mounted PGPdisks on your machine,¶
ad00ff ·it is recommended\n" +
6f4537 ¤   ¤   ¤   ¤   ¤   ·"that you unmount all PGPdisks before uninstalling. If you¶
c26d06 ·do not\n" +
f331ed ¤   ¤   ¤   ¤   ¤   ·"do this you will need to reboot your machine at the end o¶
ea6417 f the uninstall.\n\n" +
5e47f8 ¤   ¤   ¤   ¤   ¤   ·"Do you want to Exit and unmount your PGPdisks?",YES) = YE¶
593bb3 S) then
cc2d73 ¤   ¤   ¤   ¤   exit;
a0bb8c ¤   ¤   ¤   else
aed8d5 ¤   ¤   ¤   ¤   Reboot = 1;
4a6874 ¤   ¤   ¤   endif;
4e8ad7 ¤   ¤   endif;
1aaf5a
--119d 000ca1548d140110226 Page 5 of setup.rul
ef6916 ¤   ¤   PGPdiskCleanup ··();
1eaf5a
f7ec40 ¤   UnUseDLL (SUPPORTDIR ^ "PGPdskIH.dll");
3e28d5 endif;
a1af5a
971fda //See if and components that use the SDK were installed
8e90bf RegDBSetDefaultRoot(HKEY_CURRENT_USER);
bb9e2f szLocalDB = "\\Software" ^ "Network Associates";
70d3a0 szName = "DelSharedFiles";
e6af5a
111c1c DeleteSharedDLLS = FALSE;
3e1a80 if (RegDBGetKeyValueEx (szLocalDB ^ "PGP60", szName, nvType, szName, nvSize) = ¶
6f31b7 0 ) then
b93dec DeleteSharedDLLS = TRUE;
f728d5 endif;
c9af5a
0a06e8 //DELETE .DLL'S FROM WINDOWS SYSTEM DIRECTORY
8cec67 TARGETDIR = WINSYSDIR;
f8af5a
46519d if (DeleteSharedDLLS = TRUE) then
2a0037 ¤   DeleteSharedFile (WINSYSDIR, "PGP_sdk.dll");
be37ae ¤   DeleteSharedFile (WINSYSDIR, "PGPsdkNL.dll");
5b8aa4 ¤   DeleteSharedFile (WINSYSDIR, "PGPsdkUI.dll");
3128d5 endif;
6daf5a
67e2a4 DeleteSharedFile (WINSYSDIR, "pgp60cl.dll");
c9f8a5 DeleteSharedFile (WINSYSDIR, "pgp60mn.dll");
b2631b DeleteSharedFile (WINSYSDIR, "pgp60rd.dll");
84a6de DeleteSharedFile (WINSYSDIR, "pgp60sc.dll");
ba4208 DeleteSharedFile (WINSYSDIR, "pgpExch.dll");
d70926 DeleteSharedFile (WINSYSDIR, "pgp60oe.dll");
c11606 DeleteSharedFile (WINSYSDIR, "pgp60hk.dll");
80af5a
299ca7 DeleteFile ("randseed.bin");
0c13a4 DeleteFile ("PGP60.hlp");
a28787 DeleteFile ("PGP60.gid");
47af5a
31fc77 TARGETDIR = WINSYSDIR ^ "drivers";
d1ca07 DeleteSharedFile (WINSYSDIR ^ "drivers", "PGPmemlock.sys");
a9af5a
d5b8b4 TARGETDIR = WINDIR;
ab32ad DeleteFile ("PGP_sdk.prf");
0cea5d DeleteFile ("PGPsdk.prf");
f8dbdd DeleteFile ("PGPMacBinaryMappings.txt");
37af5a
68af5a
46997e //Short filename due to 95 bug
5c5ed7 DeleteSharedFile (WINDIR, "PGPMEM~1.vxd");
ffaf5a
161ffc //GET THE PGP 6.0 INSTALLATION DIRECTORY
b690bf RegDBSetDefaultRoot(HKEY_CURRENT_USER);
92ef23 szKey = "Software\\Network Associates\\PGP60\\PGPKeys";
1d3925 szName = "ExePath";
3aaf5a
f7cefe RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
a1290d ParsePath(svReturnString, svValue, PATH);
b0af5a
efe0f5 //GET THE PGP 6.0 ADMIN INSTALLATION DIRECTORY
1e90bf RegDBSetDefaultRoot(HKEY_CURRENT_USER);
8f1c0f szKey = "SOFTWARE\\Network Associates\\PGP60\\PGPKeys";
593925 szName = "ExePath";
5caf5a
5795eb if (RegDBGetKeyValueEx (szKey, szName, nvType, svValueAdmin, nvSize) = 0) then
0f56fe bDeleteAdmin = TRUE;
7828d5 endif;
b9af5a
23de94 //Outlook Express install location
a50fba szKey = "SOFTWARE\\Network Associates\\PGP60\\OE";
61da90 szName = "OutlookExpress";
20af5a
21cefe RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
caf82b OEinstall = svValue;
--30d8 000cca0087f40110226 Page 6 of setup.rul
e0af5a
5bdde2 UnInstallStart:
daaf5a
647919 //DELETE FILES FROM THE PGP 6.0 INSTALL DIRECTORY
3b91b8 TARGETDIR = svReturnString;
0845d9 Installdir = svReturnString;
a9cef8 DeleteFile ("keygen.avi");
57895a DeleteFile ("Pgp60.cnt");
bd6f3e DeleteFile ("pgp60.hlp");
78fb1d DeleteFile ("pgp60.gid");
6e67dc DeleteFile ("PGPadmin.exe");
055bb7 DeleteFile ("PGPkeys.exe");
24ab93 DeleteFile ("PGPlog.exe");
e766c8 DeleteFile ("PGPtools.exe");
4448f3 DeleteFile ("PGPtray.exe");
d63749 DeleteFile ("Quickstart.doc");
828519 DeleteFile ("PGP_Admin.prf");
0d303e DeleteFile ("PGP_Client.prf");
681674 DeleteFile ("PGPadmin.prf");
67884e DeleteFile ("PGPclient.prf");
1d9fec DeleteFile ("Eudora.url");
2814ba DeleteFile ("Adobe.url");
8e9ca7 DeleteFile ("randseed.bin");
3b7917 DeleteFile ("randseed.rnd");
6ec662 DeleteFile ("*.pdf");
36c57f DeleteFile ("*.isu");
94af5a
1f4bc9 TARGETDIR = svReturnString + "\\Documentation";
96d8bb DeleteFile ("license.txt");
71b986 DeleteFile ("Readme.txt");
7f38a2 DeleteFile ("6.0.2 Change History.txt");
51c22b DeleteFile ("PGP55win.pdf");
c99914 DeleteFile ("PGPWinUsersGuide.pdf");
6ede44 DeleteFile ("whatsnew.txt");
30b170 DeleteFile ("whatsnew.doc");
4baf5a
d70ef5 TARGETDIR = svReturnString + "\\PGPFone";
2ca03e DeleteFile ("PGPfone.pdf");
438bdc DeleteFile ("PGPfone.exe");
a61c39 DeleteFile ("readme.txt");
f8af5a
f7af5a
f57f27 TARGETDIR = svReturnString + "\\Sample Keys";
6a7c06 DeleteFile ("SampleKeys.asc");
2a3c50 DeleteFile ("WhatIsThis.txt");
49af5a
ad0007 if (svReturnString != "") then
024f59 ¤   DeleteDir(svReturnString + "\\PGPFone", ONLYDIR);
6aa7bf ¤   DeleteDir(svReturnString + "\\ClientInstaller", ALLCONTENTS);
c09a9b ¤   DeleteDir(svReturnString + "\\TEMP", ONLYDIR);
1a9ce7 ¤   DeleteDir(svReturnString + "\\Signatures", ONLYDIR);
80688b ¤   DeleteDir(svReturnString + "\\Documentation", ALLCONTENTS);
0e202d ¤   DeleteDir(svReturnString + "\\Sample Keys", ONLYDIR);
0328d5 endif;
21af5a
fb4b05 //GET THE EUDORA PLUGIN PATH
e390bf RegDBSetDefaultRoot(HKEY_CURRENT_USER);
dbc451 szKey = "SOFTWARE\\Network Associates\\PGP60\\EudoraPlugin";
898df8 szName = "PluginPath";
51af5a
fecefe RegDBGetKeyValueEx (szKey, szName, nvType, svValue, nvSize);
cdaf5a
e430ba //DELETE THE EUDORA PLUGIN
70905c TARGETDIR = svValue;
e74989 DeleteFile ("pgpplugin.dll");
0733e8 //To remove files accidently installed with 6.0b14
684cc9 DeleteFile ("pgpEudoraPluginv4.dll");
0d8870 DeleteFile ("pgpEudoraPlugin.dll");
d0af5a
fd359d //DELETE REGISTRY ENTRIES
6cf2b5 //HKEY_CURRENT_USER
cc90bf RegDBSetDefaultRoot(HKEY_CURRENT_USER);
--32bd 0004aa4608540110226 Page 7 of setup.rul
1420c9 RegDBDeleteKey ("Software\\Network Associates\\PGP60");
7aaf5a
80b319 //HKEY_CLASSES_ROOT
7fc56d RegDBSetDefaultRoot(HKEY_CLASSES_ROOT);
5cf66b RegDBDeleteKey (".aexpk");
a11a38 RegDBDeleteKey (".asc");
58206c RegDBDeleteKey (".bexpk");
7552e4 RegDBDeleteKey (".pgd");
efcbb4 RegDBDeleteKey (".pgp");
0aecc8 RegDBDeleteKey (".pkr");
f58fe4 RegDBDeleteKey (".prvkr");
05f66b RegDBDeleteKey (".aexpk");
5cc955 RegDBDeleteKey (".pubkr");
2adee4 RegDBDeleteKey (".sig");
4044a6 RegDBDeleteKey (".skr");
4cd18b RegDBDeleteKey (".shf");
81dd3c RegDBDeleteKey (".pgr");
6c402c RegDBDeleteKey (".rnd");
311001 RegDBDeleteKey ("PGP Groups");
61b824 RegDBDeleteKey ("PGP Groups File");
9f5304 RegDBDeleteKey ("PGP Share");
b571e4 RegDBDeleteKey ("Randseed File");
0bc940 RegDBDeleteKey ("Ranseed File");
fd29fc RegDBDeleteKey ("CLSID\\{969223c0-26aa-11d0-90ee-444553540000}");
5ecd90 RegDBDeleteKey ("PGP Armored Encrypted File");
5087c4 RegDBDeleteKey ("PGP Binary Extracted Public Key");
69210c RegDBDeleteKey ("PGP Armored Extracted Public Key");
34603b RegDBDeleteKey ("PGP Detached Signature File");
563d6e RegDBDeleteKey ("PGP Encrypted File");
195106 RegDBDeleteKey ("PGP Private Keyring");
77394c RegDBDeleteKey ("PGP Public Keyring");
3687c4 RegDBDeleteKey ("PGP Binary Extracted Public Key");
55ad0a RegDBDeleteKey ("PGP Share File");
5daf5a
9f594d //HKEY_LOCAL_MACHINE
8e6118 RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
b18b9c RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP");
00f66b RegDBDeleteKey (".aexpk");
1d1a38 RegDBDeleteKey (".asc");
41206c RegDBDeleteKey (".bexpk");
5a52e4 RegDBDeleteKey (".pgd");
90cbb4 RegDBDeleteKey (".pgp");
49ecc8 RegDBDeleteKey (".pkr");
688fe4 RegDBDeleteKey (".prvkr");
e8f66b RegDBDeleteKey (".aexpk");
78c955 RegDBDeleteKey (".pubkr");
cddee4 RegDBDeleteKey (".sig");
6244a6 RegDBDeleteKey (".skr");
2429fc RegDBDeleteKey ("CLSID\\{969223c0-26aa-11d0-90ee-444553540000}");
3fcd90 RegDBDeleteKey ("PGP Armored Encrypted File");
fd87c4 RegDBDeleteKey ("PGP Binary Extracted Public Key");
be210c RegDBDeleteKey ("PGP Armored Extracted Public Key");
92603b RegDBDeleteKey ("PGP Detached Signature File");
d93d6e RegDBDeleteKey ("PGP Encrypted File");
765106 RegDBDeleteKey ("PGP Private Keyring");
88394c RegDBDeleteKey ("PGP Public Keyring");
ba87c4 RegDBDeleteKey ("PGP Binary Extracted Public Key");
1916ba RegDBDeleteKey ("SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions\\PGP Plugin"¶
6a6275 );
4af504 RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\IStatu¶
04dc6f s");
43805d RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+UNI¶
f56d4d NSTALLKEY+"DeinstKey");
5916d3 RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP60");
3a8b9c RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP");
4dd54d RegDBDeleteKey ("SOFTWARE\\Classes\\.pgr");
45485d RegDBDeleteKey ("SOFTWARE\\Classes\\.rnd");
9b8b0b RegDBDeleteKey ("SOFTWARE\\Classes\\PGP Groups");
67da56 RegDBDeleteKey ("SOFTWARE\\Classes\\PGP Groups File");
cea86b RegDBDeleteKey ("SOFTWARE\\Classes\\PGP Share");
bfff6b RegDBDeleteKey ("SOFTWARE\\Classes\\Randseed File");
4a1e6a RegDBDeleteKey ("SOFTWARE\\Classes\\Ranseed File");
--a834 0008079479e40110226 Page 8 of setup.rul
e0af5a
e09d9f RegDBDeleteValue ("SOFTWARE\\Microsoft\\Exchange\\Client\\Extensions", "PGP Plu¶
20d504 gin");
08af5a
af5727 //HKEY_USERS
52892c RegDBSetDefaultRoot(HKEY_USERS);
fdbf29 RegDBDeleteKey ("S-1-5-21-1998468922-181747292-2076119496-1000\\Software\\PGP");
faaf5a
f7ca99 ProgDefGroupType(PERSONAL);
7b4ba5 DeleteProgramFolder ("P G P");
9e2c8b DeleteFolderIcon(FOLDER_STARTUP,"PGPtray");
41af5a
b9d563 //Outlook Express Uninstall
196f94 SRCDIR = OEinstall;
d0af5a
0393a2 TARGETDIR = OEinstall;
141efa //See if the user has installed OE plugin and then upgraded OE
cfe825 szFileName = OEinstall ^ "msimn.exe";
42a605 UseDLL( "Version.dll" );
f88b49 lSize = GetFileVersionInfoSizeA( szFileName, nHandle );
a65c7c NumToStr( szTemp, lSize );
30684d bVerInfo = GetFileVersionInfoA( szFileName, nHandle, lSize, szVerBuffer);
0e37b8 ptr1 = AddressString( szResultBuffer );
6db248 ptr2 = AddressNumber( ptr1 );
4e13aa bVerValue = VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904b0\\CompanyNam¶
c747ed e", ptr2, nSize);
d5af5a
53fe92 if (bVerValue = 0 ) then
13678b ¤   bVerValue = VerQueryValueA( szVerBuffer,"\\StringFileInfo\\040904E4\\Compan¶
048b02 yName", ptr2, nSize);
8a28d5 endif;
b8af5a
24ff06 // pszResultBuffer is a pointer to a pointer which is the starting point
87559b // for the company name. How do you actually get the string ?
3c7d6b StructGetP( ptr2, "MYTYPE_PSZ", "szString", lData, szData );
68cb42 UnUseDLL( "Version.dll" );
ceaf5a
c476f2 if (szData = "Microsoft Corporation") then
85bd23 ¤   //the user install the plugin then updated outlook
8ec250 ¤   //so we DO want to use this newer file
354216 ¤   bUpgraded = TRUE;
0628d5 endif;
9993a2 TARGETDIR = OEinstall;
cc6133 if (bUpgraded = FALSE) then
d8af5a
347c42 ¤   DeleteFile("msimn.exe");
ff66d8 ¤   RenameFile ("PGPmsimn.exe", "msimn.exe");
75523c else
e5894b ¤   DeleteFile("PGPmsimn.exe");
9228d5 endif;
daaf5a
78af5a
39ec67 TARGETDIR = WINSYSDIR;
b7c1d9 DeleteFile("PGP55oe.dll");
65af5a
52af5a
747b30 RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGP55\\OE");
18af5a
9deba5 RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
148fa3 RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\PGPOE¶
9a1840 Plugin");
d9af5a
72f4c3 szLocalDB = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
cdaf5a
c93036 RegDBSetKeyValueEx
1d72b1 (szLocalDB,"uninstall.exe",REGDB_STRING,"command /c del " + OEinstall ^"uninsta¶
63745b ll.exe" ,-1);
4eaf5a
329ba7 if (INCLUDEPGPDISK = "TRUE") then
fcaf5a
ac5374 ¤   TARGETDIR = svReturnString ^ "signatures";
809722 ¤   DeleteFile ("*.sig");
--ae89 00004df99af40110226 Page 9 of setup.rul
485c96 ¤   DeleteFile ("*.*.sig");
820cad ¤   DeleteDir ·(svReturnString ^ "signatures", ONLYDIR);
6aaf5a
1d3ce6 ¤   TARGETDIR = svReturnString;
7d008c ¤   SdShowMsg ("Deleting program files.", TRUE);
13af5a
97134d ¤   DeleteFile ("pgpdiskresident.exe");
e8709d ¤   DeleteFile ("pgpdisk.exe");
b99eda ¤   DeleteFile ("pgpdisk.hlp");
e7cd1e ¤   DeleteFile ("pgpdisk.cnt");
115b7f ¤   DeleteFile ("pgpdisk.pdf");
3c0811 ¤   DeleteFile ("readme.txt");
b975e5 ¤   DeleteFile ("license.txt");
a7af5a
340e86 ¤   TARGETDIR = WINSYSDIR;
85be72 ¤   ¤   DeleteFile ("pgpdskSE.dll");
edaf5a
44e981 ¤   if (IS_NT) then
2a1f7d ¤   ¤   TARGETDIR = WINSYSDIR ^ "Drivers";
6a9d96 ¤   ¤   DeleteFile ("pgpdisk.sys");
330e24 ¤   else
22f63a ¤   ¤   TARGETDIR = WINSYSDIR ^ "Iosubsys";
fa49d3 ¤   ¤   DeleteFile ("pgpdisk.pdr");
04eb6d ¤   endif;
53af5a
ba6801 ¤   Delay (2);
f1d512 ¤   SdShowMsg ("Deleting program files.", FALSE);
9aaf5a
85182d ¤   //Deleting registry Entries.
023d55 ¤   SdShowMsg ("Deleting registry entries.", TRUE);
8faf5a
acd260 ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
51af5a
55f61e ¤   RegDBDeleteKey ("Enum\\Root\\PGPdisk");
f38aeb ¤   RegDBDeleteKey ("System\\CurrentControlSet\\Services\\Class\\PGPdisk");
03af5a
c806bb ¤   RegDBSetDefaultRoot (HKEY_CLASSES_ROOT);
1caf5a
be66b9 ¤   RegDBDeleteKey (".pgd");
293238 ¤   RegDBDeleteKey ("PGPdisk Volume File");
f2d00b ¤   RegDBDeleteKey ("CLSID\\{f8b14440-3785-11d1-b363-5c6f08c10000}");
a9293d ¤   RegDBDeleteKey ("PGPdisk Volume File\\shellex\\ContextMenuHandlers\\PGPdisk¶
2bb233 ·Shell Extension");
2011c4 ¤   RegDBDeleteKey ("Drive\\shellex\\ContextMenuHandlers\\PGPdisk Shell Extensi¶
70ae63 on");
d527f9 ¤   RegDBDeleteValue ("Drive\\shellex\\ContextMenuHandlers", "");
22b2c9 ¤   RegDBDeleteKey ("PGPdisk Volume");
90af5a
35d260 ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
18af5a
540190 ¤   RegDBDeleteValue ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Exte¶
ac02e1 nsions\\Approved",
7a67b3 ¤   ¤   ¤   ¤   ¤   ··"{f8b14440-3785-11d1-b363-5c6f08c10000}" );
2345e1 ¤   RegDBDeleteKey ("Enum\\ESDI\\PGP_____PGPDISK_________0");
125cd9 ¤   RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdisk");
fc9978 ¤   RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdiskAlpha");
54750c ¤   RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdisk Beta");
e38f91 ¤   RegDBDeleteKey ("SOFTWARE\\Network Associates\\PGPdiskBeta");
0f509d ¤   RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\P¶
f95c24 GPdiskDeinstKey");
72881a ¤   RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\P¶
00332c GPdisk.exe");
97881a ¤   RegDBDeleteKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\P¶
2990f1 GPdiskResident.exe");
168c3c ¤   RegDBDeleteKey ("SOFTWARE\\Classes\\PGPdisk Volume");
14af5a
265369 ¤   RegDBSetDefaultRoot (HKEY_CURRENT_USER);
57af5a
c3608d ¤   RegDBDeleteKey ("Software\\Network Associates\\PGPdisk");
e31acc ¤   RegDBDeleteKey ("Software\\Network Associates\\PGPdiskAlpha");
ec0b66 ¤   RegDBDeleteKey ("Software\\Network Associates\\PGPdiskBeta");
04d463 ¤   RegDBDeleteKey ("Software\\PGP\\PGPdisk");
--d27a 000b6108ca140110226 Page 10 of setup.rul
d343e2 ¤   RegDBDeleteKey ("Software\\PGP\\PGPdiskAlpha");
3af88d ¤   RegDBDeleteKey ("Software\\PGP\\PGPdiskBeta");
6daf5a
d1e981 ¤   if (IS_NT) then
1c9d5e ¤   ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
5b83db ¤   ¤   RegDBDeleteKey ("System\\CurrentControlSet\\Services\\PGPdisk");
34ebe6 ¤   ¤   RegDBDeleteKey ("System\\CurrentControlSet\\Services\\EventLog\\System\¶
afa60b \PGPdisk");
87eb6d ¤   endif;
0b28d5 endif;
23af5a
42c022 //If there is an Admin install on the system as well, remove it
a2c7e9 if (nCounter = 0) then
b6c3e5 ¤   if (bDeleteAdmin = TRUE) then
5c38c0 ¤   ¤   nCounter = 1;
390808 ¤   ¤   svReturnString = svValueAdmin;
962a50 ¤   ¤   goto UnInstallStart;
45eb6d ¤   endif;
4d28d5 endif;
96af5a
13af5a
4749d1 SdShowMsg ("Uninstalling... Please wait.", FALSE);
8eaf5a
e14155 SetDialogTitle (DLG_MSG_INFORMATION,"Uninstall complete");
5149fa MessageBox ( VERSIONNUM¤+" has been uninstalled. Your key files have not been\n¶
03dddf " +
546d5b ¤   ¤   ¤   "removed. ·You may wish to store them in a safe place.", INFORMATIO¶
b5da80 N);
96af5a
d833a1 if (Reboot = 1) then
c356f2 ¤   szTemp = "Uninstall has finished uninstalling " +
53cf2d ¤   APP_NAME +" on your computer";
5ead91 ¤   szMsg = ··"Some files could not be deleted because" +
284d30 ¤   " they are currently in use by other programs" +
976fd2 ¤   " on the system. ·Files in use will be deleted" +
72977f ¤   " the next time you restart your system. You will" +
e9e1e5 ¤   " need to reboot before installing any PGP products.";
dbe08c ¤   // If SdFinishReboot reboots the system,the shared file data is
e42910 ¤   // automatically recorded.
59b63b ¤   RebootDialog ("Restart Windows",szMsg,SYS_BOOTWIN);
5a28d5 endif;
47a28b exit;
e6af5a
d6af5a
08f890 //This function will check if a library is shared before deleteing
10af5a
cbb4bc function DeleteSharedFile(szDeleteFilePath, szDeleteFile)
d8af5a
682bbb STRING szDelKey, svString, svValue;
5f82c1 NUMBER nvVar, nvType, nvSize, nSize, nReturn;
d8af5a
e80f89 begin
72af5a
11eba5 RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
b1af5a
2389da szDelKey¤   = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs";
71af5a
8beba5 RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
e2af5a
96221a if (RegDBGetKeyValueEx·
db8147 ¤   (szDelKey, ·szDeleteFilePath ^ szDeleteFile, nvType, svValue, nvSize) < 0 )¶
e5f693 ·then
6aaf5a
349391 ¤   //this is not a shared .dll so delete
fbbb17 ¤   VarSave (SRCTARGETDIR);
4ddc0f ¤   TARGETDIR ·= szDeleteFilePath;
bf6ecf ¤   SRCDIR ····= szDeleteFilePath;
cb4dcc ¤   Delay (1);
8100a3 ¤   nReturn = DeleteFile (szDeleteFile);
17169e ¤   if (nReturn != 0) then
d1a668 ¤   ¤   MessageBox (szDeleteFilePath + szDeleteFile + "\n" +
b62dc1 ¤   ¤   ¤   ¤   ¤   "This file could not be deleted. You can\n" +
--bf35 001e9c67ac140110226 Page 11 of setup.rul
a04d86 ¤   ¤   ¤   ¤   ¤   "safely delete this file manually.", INFORMATION);
29eb6d ¤   endif;
9b4dcc ¤   Delay (1);
c6daf8 ¤   VarRestore (SRCTARGETDIR);
f0af5a
90523c else
f3af5a
54a0be ¤   //this is a shared file
88c38f ¤   StrToNum (nvVar, svValue);
dcdd70 ¤   nvVar = nvVar - 1;
36322e ¤   if (nvVar < 1) then
3d48a4 ¤   ¤   SetDialogTitle (DLG_ASK_YESNO,"Confirm delete");
95efc2 ¤   ¤   if (AskYesNo
55504b ¤   ¤   ···(szDeleteFile + " is a shared library. It appears no other applicati¶
ab62dd ons\n"+
494536 ¤   ¤   ···"are using it anymore, do you want to delete it?"
ecb59f ¤   ¤   ···,NO) = YES) then
302a48 ¤   ¤   ¤   ¤   if (szDeleteFile = "PGPmemlock.sys") then
02c3f7 ¤   ¤   ···¤¤   ¤   //delete the reg. entry
71d228 ¤   ¤   ¤   ¤   ¤   RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
5173d2 ¤   ¤   ¤   ¤   ¤   RegDBDeleteKey ("SYSTEM\\CurrentControlSet\\Services\\PGPme¶
c9f059 mlock");
62539d ¤   ¤   ¤   ¤   endif;
6f6671 ¤   ¤   ¤   ¤   //Delete the file and decrement the count
c3db29 ¤   ¤   ¤   ¤   RegDBDeleteValue (szDelKey, szDeleteFilePath ^ szDeleteFile);
5358e0 ¤   ¤   ¤   ¤   VarSave (SRCTARGETDIR);
e00228 ¤   ¤   ¤   ¤   TARGETDIR ·= szDeleteFilePath;
36b0e8 ¤   ¤   ¤   ¤   SRCDIR ····= szDeleteFilePath;
d47667 ¤   ¤   ¤   ¤   Delay (1);
49079d ¤   ¤   ¤   ¤   nReturn = DeleteFile (szDeleteFile);
58cf3a ¤   ¤   ¤   ¤   if (nReturn != 0) then
1ef172 ¤   ¤   ¤   ¤   ¤   MessageBox (szDeleteFilePath + szDeleteFile + "\n" +
3c2dc1 ¤   ¤   ¤   ¤   ¤   "This file could not be deleted. You can\n" +
e94d86 ¤   ¤   ¤   ¤   ¤   "safely delete this file manually.", INFORMATION);
5e539d ¤   ¤   ¤   ¤   endif;
137667 ¤   ¤   ¤   ¤   Delay (1);
371938 ¤   ¤   ¤   ¤   VarRestore (SRCTARGETDIR);
558ad7 ¤   ¤   endif;
10eb6d ¤   endif;
89a2f3 ¤   //write the new number of apps shareing the library
50ebdf ¤   if (nvVar > 0) then
bc14fb ¤   ¤   NumToStr (svString, nvVar);
50fd58 ¤   ¤   RegDBSetKeyValueEx·
620a8d ¤   ¤   (szDelKey, ·szDeleteFilePath ^ szDeleteFile, REGDB_NUMBER, svString, nS¶
d36e5f ize);
43eb6d ¤   endif;
c728d5 endif;
022b3d end;
d5cb79 #include "Sddialog.rul"
a5af5a
e9af5a
--2b64 00028a77a1340110227 Page 1 of main.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
2d5703 ¤   $Id: main.cpp,v 1.7.8.1 1998/11/12 03:12:41 heller Exp $
83f7f7 ____________________________________________________________________________*/
b3af5a
305655 #include <windows.h>
398031 #include "resource.h"
d1af5a
62e1c4 #define OE_REGKEY¤  "SOFTWARE\\Microsoft\\Outlook Express"
13af5a
38b380 HINSTANCE g_hInstance = NULL;
1e4a5a UINT WM_PGP_KILL_OELOADER = 0;
afaf5a
0b38e5 /*
e66dad extern "C" {
c569f0 __declspec(dllimport) HookOutlookExpressPlugin(DWORD dwThreadId);
7f82f7 };
fa7fe0 */
73af5a
eb10e8 void (*HookOutlookExpressPlugin)(DWORD);
d5af5a
7737fd LRESULT CALLBACK MainWndProc(HWND hwnd,·
2b0bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
dcd1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
8df03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
75af5a
f72e69 BOOL GetOELocation(char *szOutlookExpress);
bfaf5a
d1af5a
9cbcce int WINAPI WinMain(
81f2b0 ····HINSTANCE hInstance,¤   // handle to current instance
62e9d2 ····HINSTANCE hPrevInstance,¤   // handle to previous instance
12145b ····LPSTR lpCmdLine,¤   // pointer to command line
88c029 ····int nCmdShow ¤  // show state of window
e405d3 ···)
a4bb36 {
6df567 ····MSG msg;·
06e6fc ····WNDCLASS wc;·
ed805b ¤   HWND hwndMain;
040d2b ¤   STARTUPINFO si;
c35ff5 ¤   PROCESS_INFORMATION pi;
301598 ¤   HANDLE hOutlookExpress;
85b2bc ¤   HANDLE hPGP60oe;
f2d502 ¤   HWND hwndOE;
8c693a ¤   DWORD dwProcessId;
74f68d ¤   DWORD dwThreadId;
7851ab ¤   DWORD dwWait;
b97f93 ¤   BOOL bMainWindow = TRUE;
c8308f ¤   char szOutlookExpress[MAX_PATH*2];
d3d83c ·
91e83d ····g_hInstance = hInstance; ·/* save instance handle */·
f0af5a
4633d6 ¤   /* Attempt to load the Outlook Express plug-in DLL */
7baf5a
d50eb5 ¤   hPGP60oe = LoadLibrary("PGP60oe.dll");
000f94 ¤   if (hPGP60oe == NULL)
4ac7a1 ¤   {
177754 ¤   ¤   char szMsg[255];
c233e2 ¤   ¤   char szTitle[255];
23af5a
34567c ¤   ¤   HookOutlookExpressPlugin = NULL;
856370 ¤   ¤   LoadString(hInstance, IDS_NOPLUGIN, szMsg, 254);
de93e2 ¤   ¤   LoadString(hInstance, IDS_TITLE, szTitle, 254);
4ceb16 ¤   ¤   MessageBox(NULL, szMsg, szTitle, MB_ICONEXCLAMATION);
579371 ¤   }
9c0e24 ¤   else
f0c38b ¤   ¤   HookOutlookExpressPlugin = (void (*)(DWORD))·
28245c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetProcAddress(hPGP60oe,·
--7d2f 00068c230f840110227 Page 2 of main.cpp
55cbdd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "HookOutlookExpressPlugin");
2caf5a
123b1a ¤   /* Launch the real Outlook Express process */
d5af5a
17eaa9 ¤   if (!GetOELocation(szOutlookExpress))
3c98aa ¤   ¤   return FALSE;
32af5a
fb4022 ¤   si.cb = sizeof(STARTUPINFO);
edcb9b ¤   si.lpReserved = NULL;
6cca0e ¤   si.lpDesktop = NULL;
96d6f5 ¤   si.lpTitle = NULL;
a4be65 ¤   si.dwFlags = 0;
46835a ¤   si.cbReserved2 = NULL;
321786 ¤   si.lpReserved2 = NULL;
c4af5a
4c27b4 ¤   strcat(szOutlookExpress, " ");
868b02 ¤   strcat(szOutlookExpress, lpCmdLine);
baaf5a
decdd2 ¤   CreateProcess(NULL, szOutlookExpress, NULL, NULL, FALSE,·
f66694 ¤   ¤   NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
8daf5a
410594 ¤   if (HookOutlookExpressPlugin == NULL)
3a98aa ¤   ¤   return FALSE;
7eaf5a
a36cb7 ¤   if (strstr(lpCmdLine, "/reg") || strstr(lpCmdLine, "/unreg"))
2798aa ¤   ¤   return FALSE;
69af5a
409136 ¤   WM_PGP_KILL_OELOADER = RegisterWindowMessage("PGP Kill OE Loader");
bfaf5a
a436d6 ¤   hOutlookExpress = OpenProcess(STANDARD_RIGHTS_REQUIRED, FALSE,·
0856f3 ¤   ¤   ¤   ¤   ¤   ¤   pi.dwProcessId);
6067c5 ¤
23b639 ¤   WaitForInputIdle(hOutlookExpress, INFINITE);
cab599 ¤   CloseHandle(hOutlookExpress);
40af5a
994c1c ¤   if (strstr(lpCmdLine, "/mailurl") || strstr(lpCmdLine, "/eml") ||
fa555d ¤   ¤   strstr(lpCmdLine, "/nws"))
137738 ¤   ¤   bMainWindow = FALSE;
8aaf5a
bf0480 ¤   if (bMainWindow)
64c7a1 ¤   {
03e927 ¤   ¤   hwndOE = NULL;
c0b462 ¤   ¤   dwWait = GetTickCount();
290c19 ¤   ¤   do
c15b34 ¤   ¤   {
a157fd ¤   ¤   ¤   hwndOE = FindWindowEx(NULL, hwndOE, "ThorBrowserWndClass", NULL);
c0999f ¤   ¤   ¤   dwThreadId = GetWindowThreadProcessId(hwndOE, &dwProcessId);
4b0fe4 ¤   ¤   }
c0917b ¤   ¤   while (¤(dwProcessId != pi.dwProcessId) &&·
043ce6 ¤   ¤   ¤   ¤   ((GetTickCount() - dwWait) < 30000));
4f1b52 ¤   ¤
d9dacb ¤   ¤   HookOutlookExpressPlugin(dwThreadId);
499371 ¤   }
fdaf5a
5532ce ¤   if ((GetTickCount() - dwWait) >= 30000)
c398aa ¤   ¤   return FALSE;
8067c5 ¤
62d2ce ¤   hwndOE = NULL;
c80f34 ¤   dwWait = GetTickCount();
05cfa1 ¤   do
2dc7a1 ¤   {
68c969 ¤   ¤   hwndOE = FindWindowEx(NULL, hwndOE, "AthenaInitWindow", NULL);
9b9ee9 ¤   ¤   dwThreadId = GetWindowThreadProcessId(hwndOE, &dwProcessId);
a59371 ¤   }
a8073a ¤   while (¤(dwProcessId != pi.dwProcessId) &&·
3b92e7 ¤   ¤   ¤   ((GetTickCount() - dwWait) < 30000));
aa67c5 ¤
32e30e ¤   HookOutlookExpressPlugin(dwThreadId);
f267c5 ¤
56de18 ····/* Register the window class for the main window. */·
a6d83c ·
681338 ····if (!hPrevInstance) {·
--8b60 0002da007f840110227 Page 3 of main.cpp
9ca0d2 ········wc.style = 0;·
4db06e ········wc.lpfnWndProc = (WNDPROC) MainWndProc;·
9caf43 ········wc.cbClsExtra = 0;·
bc9a59 ········wc.cbWndExtra = 0;·
f2c09c ········wc.hInstance = hInstance;·
9149de ········wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION);·
66827a ········wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);·
2db6ed ········wc.hbrBackground = GetStockObject(WHITE_BRUSH);·
65f54f ········wc.lpszMenuName = ·NULL;·
adb955 ········wc.lpszClassName = "PGPOEloaderClass";·
37d83c ·
931f77 ········if (!RegisterClass(&wc))·
c09379 ············return FALSE;·
1bb692 ····}·
41af5a
0b6288 ····/* Create the main window. */·
75d83c ·
7f2266 ····hwndMain = CreateWindow("PGPOEloaderClass", "",·
9a189b ········WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,·
8510e0 ········CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL,·
b412e2 ········(HMENU) NULL, hInstance, (LPVOID) NULL);·
11d83c ·
400807 ····/*·
f3dc85 ·····* If the main window cannot be created, terminate·
362815 ·····* the application.·
e67a75 ·····*/·
efd83c ·
17db2c ····if (!hwndMain)·
af69b9 ········return FALSE;·
2ed83c ·
9d660f ····/* Hide the window and paint its contents. */·
fcd83c ·
1f3c3f ····ShowWindow(hwndMain, SW_HIDE);·
6670a6 ····UpdateWindow(hwndMain);·
41d83c ·
f104b8 ····/* Start the message loop. */·
ded83c ·
417b2a ····while (GetMessage(&msg, (HWND) NULL, 0, 0))·
a0c7a1 ¤   {
1b9e81 ¤   ¤   TranslateMessage(&msg);·
8de711 ¤   ¤   DispatchMessage(&msg);·
15b692 ····}·
91d83c ·
dd9262 ····/* Return the exit code to Windows. */·
53d83c ·
d51934 ····return msg.wParam;·
d7efe6 }
48af5a
dcaf5a
ae37fd LRESULT CALLBACK MainWndProc(HWND hwnd,·
650bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
9ed1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
f5a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
bebb36 {
3ddf0f ¤   if (uMsg == WM_PGP_KILL_OELOADER)
81c7a1 ¤   {
aeeb80 ¤   ¤   PostQuitMessage(0);
77bbde ¤   ¤   return 0;
5e9371 ¤   }
acaf5a
1800bb ¤   return DefWindowProc(hwnd, uMsg, wParam, lParam);
26efe6 }
b8af5a
42af5a
2933df BOOL GetOELocation(char *szOutlookExpress)
0fbb36 {
85829c ¤   HKEY¤   ¤   hKey;
b8aa96 ¤   LONG¤   ¤   lResult;
c4878a ¤   DWORD¤  ¤   dwValueType, dwSize;
ce6db0 ¤   BOOL¤   ¤   bSuccess = FALSE;
ded686 ¤   char¤   ¤   szMsg[255];
2debea ¤   char¤   ¤   szTitle[255];
--2c88 001204219d840110227 Page 4 of main.cpp
e0af5a
70a1a2 ¤   lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OE_REGKEY, 0, KEY_READ, &hKey);
a4af5a
f8d84a ¤   if (lResult == ERROR_SUCCESS)·
dcc7a1 ¤   {
a1ed55 ¤   ¤   dwSize = MAX_PATH;
3037f3 ¤   ¤   lResult = RegQueryValueEx(hKey, "InstallRoot", 0, &dwValueType,·
8053cc ¤   ¤   ¤   ¤   ¤   (LPBYTE)szOutlookExpress, &dwSize);
ad8e60 ¤   ¤   RegCloseKey (hKey);
3b99b9 ¤   ¤   if (lResult == ERROR_SUCCESS)·
185b34 ¤   ¤   {
461511 ¤   ¤   ¤   strcat(szOutlookExpress, "\\PGPmsimn.exe");
bfe4bd ¤   ¤   ¤   if (GetFileAttributes(szOutlookExpress) == 0xFFFFFFFF)
15f776 ¤   ¤   ¤   {
65802e ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_BADINSTALL, szMsg, 254);
4b00d6 ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
22422c ¤   ¤   ¤   ¤   MessageBox(NULL, szMsg, szTitle, MB_ICONEXCLAMATION);
7fa3a6 ¤   ¤   ¤   }
f5bb8c ¤   ¤   ¤   else
e8e73b ¤   ¤   ¤   ¤   bSuccess = TRUE;
d50fe4 ¤   ¤   }
e00e1d ¤   ¤   else
7c5b34 ¤   ¤   {
d875bb ¤   ¤   ¤   LoadString(g_hInstance, IDS_NOMSIMN, szMsg, 254);
7fbccf ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
11570f ¤   ¤   ¤   MessageBox(NULL, szMsg, szTitle, MB_ICONEXCLAMATION);
fd0fe4 ¤   ¤   }
819371 ¤   }
eb0e24 ¤   else
04c7a1 ¤   {
dc97bb ¤   ¤   LoadString(g_hInstance, IDS_NOMSIMN, szMsg, 254);
365ecf ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
adeb16 ¤   ¤   MessageBox(NULL, szMsg, szTitle, MB_ICONEXCLAMATION);
d79371 ¤   }
c8af5a
f04ded ¤   return bSuccess;
16efe6 }
50af5a
f1af5a
207e4d /*__Editor_settings____
81af5a
224126 ¤   Local Variables:
607b17 ¤   tab-width: 4
680e6c ¤   End:
f65f8c ¤   vi: ts=4 sw=4
549e9b ¤   vim: si
20d062 _____________________*/
--92cf 000fd006ac540110228 Page 1 of msimn.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
19f860 #ifdef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
66465d //
df5733 // TEXTINCLUDE
a2465d //
99af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
2d4523 BEGIN
70541e ····"resource.h\0"
48e0d1 END
85af5a
467037 2 TEXTINCLUDE DISCARDABLE·
044523 BEGIN
c3eb23 ····"#include ""afxres.h""\r\n"
98db5c ····"\0"
97e0d1 END
5aaf5a
ea227f 3 TEXTINCLUDE DISCARDABLE·
024523 BEGIN
eb8cb3 ····"#include ""msimnVer.rc""\r\n"
4cdb5c ····"\0"
29e0d1 END
8eaf5a
2769ab #endif ···// APSTUDIO_INVOKED
c2af5a
08af5a
666c0e /////////////////////////////////////////////////////////////////////////////
01465d //
60cbaf // Icon
15465d //
b9af5a
322951 // Icon with lowest ID value placed first to ensure application icon
120f06 // remains consistent on all systems.
b57e1c IDI_MSIMN ··············ICON ···FIXED IMPURE ···"Res\\msimn.ico"
d7af5a
03436e IDI_NEWS ···············ICON ···FIXED IMPURE ···"Res\\news.ico"
36af5a
4e1cb6 IDI_ENVELOPE ···········ICON ···FIXED IMPURE ···"Res\\envelope.ico"
04af5a
49e403 IDI_LETTER ·············ICON ···FIXED IMPURE ···"Res\\letter.ico"
d2af5a
73215d IDI_PACKAGE ············ICON ···FIXED IMPURE ···"Res\\package.ico"
f9af5a
19af5a
7b6c0e /////////////////////////////////////////////////////////////////////////////
0f465d //
f05e87 // String Table
62465d //
fdaf5a
--40d3 00110f9b7f840110228 Page 2 of msimn.rc
6e6f6c STRINGTABLE DISCARDABLE·
bf4523 BEGIN
b1988c ····IDS_TITLE ··············"PGP Outlook Express Plug-in"
a45e5f ····IDS_NOPLUGIN ···········"One or more DLL files required for the PGP Outlook¶
8de7bb ·Express plug-in are missing. The plug-in will not be loaded.\n\nYou may need t¶
19d9f3 o re-install PGP and/or the PGP Outlook Express plug-in."
c86c94 ····IDS_NOMSIMN ············"Either Outlook Express is not installed on this ma¶
b85b59 chine, or has been incorrectly installed. Please re-install Outlook Express."
222a42 ····IDS_BADINSTALL ·········"The PGP Outlook Express plug-in was not installed ¶
8609ac correctly, or someone has deleted the Outlook Express program. Please re-instal¶
681610 l Outlook Express, then re-install the plug-in."
3fe0d1 END
a4af5a
d11b3a #endif ···// English (U.S.) resources
016c0e /////////////////////////////////////////////////////////////////////////////
00af5a
88af5a
01af5a
24ce8c #ifndef APSTUDIO_INVOKED
426c0e /////////////////////////////////////////////////////////////////////////////
be465d //
cc8464 // Generated from the TEXTINCLUDE 3 resource.
4a465d //
8e9230 #include "msimnVer.rc"
3caf5a
646c0e /////////////////////////////////////////////////////////////////////////////
238072 #endif ···// not APSTUDIO_INVOKED
10af5a
--51e5 001c3a0a79940110229 Page 1 of msimnVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
b35380 ············VALUE "FileDescription", "PGP Outlook Express loader\0"
b9c1dd ············VALUE "FileVersion", PGPVERSIONSTRING
9e89cc ············VALUE "InternalName", "msimn\0"
988ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
6e2bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
d1ffcb ············VALUE "OriginalFilename", "msimn.exe\0"
639317 ············VALUE "ProductName", PGPPRODUCTNAME
b0d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
75f37f ········END
1c7d01 ····END
9a26ab ····BLOCK "VarFileInfo"
f55574 ····BEGIN
fb4b11 ········VALUE "Translation", 0x409, 1200
c27d01 ····END
7ee0d1 END
95af5a
acaf5a
c3af5a
--8426 0015bbf0ff04011022a Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
2321ec // Used by msimn.rc
9d465d //
6c839d #define IDS_TITLE ······················1
a65101 #define IDS_NOPLUGIN ···················2
ea3d45 #define IDS_NOMSIMN ····················3
080896 #define IDS_BADINSTALL ·················4
1902ee #define IDI_MSIMN ······················2
94bf4e #define IDI_NEWS ·······················3
390537 #define IDI_ENVELOPE ···················4
b976aa #define IDI_LETTER ·····················5
7a49c6 #define IDI_PACKAGE ····················6
60af5a
a311aa // Next default values for new objects
6aac6a //·
bef860 #ifdef APSTUDIO_INVOKED
103f23 #ifndef APSTUDIO_READONLY_SYMBOLS
d467b3 #define _APS_NEXT_RESOURCE_VALUE ·······108
75611c #define _APS_NEXT_COMMAND_VALUE ········40001
44f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
301285 #define _APS_NEXT_SYMED_VALUE ··········101
427454 #endif
5b7454 #endif
--7449 0006061f3d04011022b Page 1 of CBTProc.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
84cf6b ¤   $Id: CBTProc.cpp,v 1.1.12.1 1998/11/12 03:12:42 heller Exp $
ecf7f7 ____________________________________________________________________________*/
f8af5a
385655 #include <windows.h>
60390b #include "PluginInfo.h"
a68d66 #include "HookProcs.h"
e4af5a
83b32f extern HHOOK g_hHook[10];
d6238d extern int g_nNumHooks;
14c080 extern DWORD g_dwThreadID[10];
34af5a
555e41 void AttachPluginToWindow(HWND hwnd);
32af5a
bdaf5a
452c7c LRESULT WINAPI CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
91bb36 {
defcc8 ¤   int nIndex;
66f5b6 ¤   DWORD dwThreadID;
06af5a
91def8 ¤   switch (nCode)
2ac7a1 ¤   {
b6c94c ¤   case HCBT_CREATEWND:
eea443 ¤   case HCBT_ACTIVATE:
3c5b34 ¤   ¤   {
6fef6c ¤   ¤   ¤   AttachPluginToWindow((HWND) wParam);
edcdcb ¤   ¤   ¤   break;
f13b90 ¤   ¤   }¤
d3b466 ¤   }¤  ¤   ¤
5d67c5 ¤
c06fdb ¤   dwThreadID = GetCurrentThreadId();
d7af5a
4f7f41 ¤   for (nIndex=0; nIndex<g_nNumHooks; nIndex++)
d1c7a1 ¤   {
915bbb ¤   ¤   if (g_dwThreadID[nIndex] == dwThreadID)
1ccdcb ¤   ¤   ¤   break;
429371 ¤   }
3daf5a
3fba35 ¤   return CallNextHookEx(g_hHook[nIndex], nCode, wParam, lParam);
31efe6 }
69af5a
23af5a
1c849c void AttachPluginToWindow(HWND hwnd)
31bb36 {
bcc1c0 ¤   DLGPROC lpOldProc;
af5cc0 ¤   PluginInfo *plugin;
f1126f ¤   char szWndClass[1024];
a167c5 ¤
43aa56 ¤   GetClassName(hwnd, szWndClass, 1023);
22af5a
2c39a4 ¤   if (strcmp(szWndClass, "ThorBrowserWndClass") &&·
cb0331 ¤   ¤   strcmp(szWndClass, "ATH_Note"))
2499bf ¤   ¤   return;
4b67c5 ¤
86bd51 ¤   lpOldProc = (DLGPROC)GetProp(hwnd, "oldproc");
792354 ¤   if (lpOldProc != NULL)
e299bf ¤   ¤   return;
79af5a
f75bf9 ¤   plugin = CreatePluginInfo(hwnd);
db67c5 ¤
568456 ¤   if (plugin == NULL)
0a99bf ¤   ¤   return;
1167c5 ¤
3c24bf ¤   // Save away old proc
2d57e2 ¤   SetProp(hwnd, "oldproc",·
c67259 ¤   ¤   (HANDLE) GetWindowLong(hwnd, GWL_WNDPROC));·
6067c5 ¤
--f9ae 001db4f54b34011022b Page 2 of CBTProc.cpp
ee84eb ¤   // Subclass new Outlook Express main window
4f37e0 ¤   if(!strcmp(szWndClass, "ThorBrowserWndClass"))·
538479 ¤   ¤   SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) MainWndProc);
ef67c5 ¤
47bab1 ¤   // Subclass new Outlook Express message window¤
f50e24 ¤   else
bcd713 ¤   ¤   SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) UnknownWndProc);
6e67c5 ¤
a406ce ¤   // Store the pointer to the plugin information
82314c ¤   SavePluginInfo(hwnd, plugin);·
a9830f ¤   return;
f4efe6 }
2faf5a
efaf5a
e57e4d /*__Editor_settings____
39af5a
2b4126 ¤   Local Variables:
a87b17 ¤   tab-width: 4
1a0e6c ¤   End:
895f8c ¤   vi: ts=4 sw=4
b59e9b ¤   vim: si
dbd062 _____________________*/
--4d08 00086986c724011022c Page 1 of CommonWndProc.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
2247bd ¤   $Id: CommonWndProc.cpp,v 1.7.8.1 1998/11/12 03:12:43 heller Exp $
64f7f7 ____________________________________________________________________________*/
cbaf5a
6d5655 #include <windows.h>
5090fb #include <commctrl.h>
78390b #include "PluginInfo.h"
218d66 #include "HookProcs.h"
9fadf9 #include "UIutils.h"
b05ab2 #include "PGPcl.h"
5f8031 #include "resource.h"
36af5a
00af5a
433345 BOOL CALLBACK CommonWndProc(HWND hDlg,·
308dda ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,
24cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
144868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
adbb36 {
2fc1c0 ¤   DLGPROC lpOldProc;
795cc0 ¤   PluginInfo *plugin;
73af5a
e80955 ¤   lpOldProc = (DLGPROC)GetProp( hDlg, "oldproc" );
338af7 ¤   plugin = GetPluginInfo(hDlg);
67af5a
953bed ¤   if (plugin != NULL)
08c7a1 ¤   {
036642 ¤   ¤   if (msg == plugin->nPurgeCacheMsg)
d15b34 ¤   ¤   {
6b9ce4 ¤   ¤   ¤   PGPclPurgeCachedPassphrase(wParam);
1a32bd ¤   ¤   ¤   return TRUE;
840fe4 ¤   ¤   }
3d9371 ¤   }
ddaf5a
d49467 ¤   switch(msg)
b5c7a1 ¤   {
4b6b08 ¤   case WM_DESTROY:
f95b34 ¤   ¤   {
3bbb3f ¤   ¤   ¤   FreePluginInfo(plugin);
9acdcb ¤   ¤   ¤   break;
9e0fe4 ¤   ¤   }
8faf5a
3908b5 ¤   case WM_MENUSELECT:
f45b34 ¤   ¤   {
df8f67 ¤   ¤   ¤   UINT uFlags = (UINT) HIWORD(wParam);
da0767 ¤   ¤   ¤   char szText[255];
d5cfda ¤   ¤   ¤   BOOL bPluginMenu = FALSE;
6aaf5a
5a0edc ¤   ¤   ¤   if (uFlags & MF_POPUP)
ddf776 ¤   ¤   ¤   {
1834e7 ¤   ¤   ¤   ¤   if (LOWORD(wParam) == plugin->nPGPPosition)
c872c3 ¤   ¤   ¤   ¤   {
cb9958 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_PGP);
8f1b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
4c2613 ¤   ¤   ¤   ¤   }
c2a3a6 ¤   ¤   ¤   }
8daf5a
dd9164 ¤   ¤   ¤   switch(LOWORD(wParam))
53f776 ¤   ¤   ¤   {
034094 ¤   ¤   ¤   ¤   case IDC_PREFS:
3a72c3 ¤   ¤   ¤   ¤   {
57a15e ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_PREFS);
901b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
de14c3 ¤   ¤   ¤   ¤   ¤   break;
932613 ¤   ¤   ¤   ¤   }
35da4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
a54811 ¤   ¤   ¤   ¤   case IDC_PGPKEYS:
8672c3 ¤   ¤   ¤   ¤   {
--df83 001fa49a6ca4011022c Page 2 of CommonWndProc.cpp
d6b034 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_PGPKEYS);
4d1b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
4514c3 ¤   ¤   ¤   ¤   ¤   break;
6a2613 ¤   ¤   ¤   ¤   }
535a2a ¤   ¤   ¤   }¤
95af5a
59a162 ¤   ¤   ¤   if (bPluginMenu)
1df776 ¤   ¤   ¤   {
da46c6 ¤   ¤   ¤   ¤   CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
8c01cc ¤   ¤   ¤   ¤   SendMessage(plugin->hStatusBar, SB_SETTEXT,·
7e77f7 ¤   ¤   ¤   ¤   ¤   255 | SBT_NOBORDERS, (LPARAM) szText);
98af5a
4546f1 ¤   ¤   ¤   ¤   return 0;
0aa3a6 ¤   ¤   ¤   }
52af5a
77cdcb ¤   ¤   ¤   break;
ed0fe4 ¤   ¤   }
94af5a
4b3fcf ¤   case WM_COMMAND:
d45b34 ¤   ¤   {
a99164 ¤   ¤   ¤   switch(LOWORD(wParam))
18f776 ¤   ¤   ¤   {
cfedca ¤   ¤   ¤   case IDC_PREFS:
d172c3 ¤   ¤   ¤   ¤   {
fd4478 ¤   ¤   ¤   ¤   ¤   PGPclPreferences(plugin->pgpContext, hDlg, 0, NULL);
35cfa5 ¤   ¤   ¤   ¤   ¤   return 0;
972613 ¤   ¤   ¤   ¤   }
d0af5a
077f19 ¤   ¤   ¤   case IDC_PGPKEYS:
7c72c3 ¤   ¤   ¤   ¤   {
bbe9bf ¤   ¤   ¤   ¤   ¤   char szPath[MAX_PATH];
e0960f ¤   ¤   ¤   ¤   ¤   char szPGPkeys[256];
a94333 ¤   ¤   ¤   ¤   ¤   PGPError err;
8eae30 ¤   ¤   ¤   ¤   ¤
da5fdf ¤   ¤   ¤   ¤   ¤   UIGetString(szPGPkeys, sizeof(szPGPkeys), IDS_PGPKEYSEXE);
cf88bb ¤   ¤   ¤   ¤   ¤   err = PGPclGetPGPPath(szPath, MAX_PATH-1);
a7357e ¤   ¤   ¤   ¤   ¤   if (IsPGPError(err))
e44859 ¤   ¤   ¤   ¤   ¤   {
61b5e3 ¤   ¤   ¤   ¤   ¤   ¤   UIDisplayStringID(hDlg, IDS_E_NOPGPKEYS);
a3f8ad ¤   ¤   ¤   ¤   ¤   ¤   return 0;
ab1c89 ¤   ¤   ¤   ¤   ¤   }
6baf5a
aa8c87 ¤   ¤   ¤   ¤   ¤   strcat(szPath, szPGPkeys);
4f80b6 ¤   ¤   ¤   ¤   ¤   WinExec(szPath, SW_SHOW);
74cfa5 ¤   ¤   ¤   ¤   ¤   return 0;
da2613 ¤   ¤   ¤   ¤   }
08a3a6 ¤   ¤   ¤   }
25af5a
8ccdcb ¤   ¤   ¤   break;
cf0fe4 ¤   ¤   }
2e9371 ¤   }
d1af5a
ce6a22 ¤   return CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
72efe6 }
4baf5a
f2af5a
b77e4d /*__Editor_settings____
3eaf5a
854126 ¤   Local Variables:
b37b17 ¤   tab-width: 4
060e6c ¤   End:
b75f8c ¤   vi: ts=4 sw=4
3c9e9b ¤   vim: si
fad062 _____________________*/
--0dd7 001c34709a14011022d Page 1 of HookProcs.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7c476d ¤   $Id: HookProcs.h,v 1.3.10.1 1998/11/12 03:12:43 heller Exp $
6ff7f7 ____________________________________________________________________________*/
611ceb #ifndef Included_HookProcs_h¤   /* [ */
fd2c61 #define Included_HookProcs_h
8aaf5a
40d3a1 LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam);
77af5a
0cb4b0 BOOL CALLBACK MainWndProc(HWND hDlg,·
8c9cdf ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,
206540 ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
d044a5 ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
c3af5a
d4875c BOOL CALLBACK ToolbarParentWndProc(HWND hDlg,·
917e43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT msg,
b32ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
030f2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
50af5a
87fe0f BOOL CALLBACK SendMsgWndProc(HWND hDlg,·
9f2aaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,
1ad1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
4df03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
5baf5a
2f92fe BOOL CALLBACK ReadMsgWndProc(HWND hDlg,·
7b2aaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,
70d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
0bf03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
a1af5a
b1ed5d BOOL CALLBACK UnknownWndProc(HWND hDlg,·
2d2aaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,
0ad1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
84f03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
13af5a
c43345 BOOL CALLBACK CommonWndProc(HWND hDlg,·
fe8dda ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,
dacec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
2aef26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
b9af5a
eafe3b #endif /* ] Included_HookProcs_h */
2aaf5a
4daf5a
cf7e4d /*__Editor_settings____
08af5a
ce4126 ¤   Local Variables:
607b17 ¤   tab-width: 4
0d0e6c ¤   End:
ed5f8c ¤   vi: ts=4 sw=4
b29e9b ¤   vim: si
c3d062 _____________________*/
--f0df 0004bc480a44011022e Page 1 of MainWndProc.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d3dcab ¤   $Id: MainWndProc.cpp,v 1.12.8.1 1998/11/12 03:12:44 heller Exp $
99f7f7 ____________________________________________________________________________*/
baaf5a
ab5655 #include <windows.h>
b290fb #include <commctrl.h>
16390b #include "PluginInfo.h"
208d66 #include "HookProcs.h"
60adf9 #include "UIutils.h"
235ab2 #include "PGPcl.h"
878031 #include "resource.h"
cfaf5a
a792e0 #define PLUGIN_INFO_PROP¤   ¤   "PGP plugin"
b2af5a
5d6948 void CreateMainWindowGUI(HWND hDlg, PluginInfo *plugin);
ceaf5a
c2af5a
a2b4b0 BOOL CALLBACK MainWndProc(HWND hDlg,·
1a9cdf ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,
866540 ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
f4b126 ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
bbbb36 {
21c1c0 ¤   DLGPROC lpOldProc;
935cc0 ¤   PluginInfo *plugin;
61af5a
ee0955 ¤   lpOldProc = (DLGPROC)GetProp( hDlg, "oldproc" );
738af7 ¤   plugin = GetPluginInfo(hDlg);
b667c5 ¤
aa3bed ¤   if (plugin != NULL)
e2c7a1 ¤   {
f06642 ¤   ¤   if (msg == plugin->nPurgeCacheMsg)
7b5b34 ¤   ¤   {
9e9ce4 ¤   ¤   ¤   PGPclPurgeCachedPassphrase(wParam);
5432bd ¤   ¤   ¤   return TRUE;
3f0fe4 ¤   ¤   }
409371 ¤   }
52af5a
e29467 ¤   switch(msg)
54c7a1 ¤   {
815e2f ¤   case WM_SETTINGCHANGE:
2f2555 ¤   case WM_PALETTECHANGED:
127563 ¤   case WM_FONTCHANGE:
252716 ¤   case WM_SYSCOLORCHANGE:
b25b34 ¤   ¤   {
97c966 ¤   ¤   ¤   HINSTANCE hInst;
516a29 ¤   ¤   ¤   HDC¤hDC;
7ec11e ¤   ¤   ¤   TBBUTTON tbb[1];
aa8831 ¤   ¤   ¤   HIMAGELIST hilToolbar;
ba3b87 ¤   ¤   ¤   HBITMAP hbmpPGPkeys;
f335f1 ¤   ¤   ¤   int nPGPkeysBMP;
a6058f ¤   ¤   ¤   int nPGPkeysSTR;
26fbbf ¤   ¤   ¤   int¤iNumBits;
91114f ¤   ¤   ¤   int nIndex;
2da054 ¤   ¤   ¤   int nReturn;
5e0767 ¤   ¤   ¤   char szText[255];
f287c7 ¤   ¤   ¤
75696d ¤   ¤   ¤   nReturn = CommonWndProc(hDlg, msg, wParam, lParam);
ceaf5a
b8c84e ¤   ¤   ¤   hInst = UIGetInstance();
de9c2a ¤   ¤   ¤   nIndex = SendMessage(plugin->hToolbar, TB_COMMANDTOINDEX,
273907 ¤   ¤   ¤   ¤   ¤   ¤   IDC_PGPKEYS, 0);
6faf5a
c72ce6 ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_DELETEBUTTON, nIndex, 0);
36e1a8 ¤   ¤   ¤   plugin->nPGPKeysButton = -1;
d3af5a
c36ef4 ¤   ¤   ¤   hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar,·
4b6e0b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_GETIMAGELIST, 0, 0);
--6d8f 00020455ba24011022e Page 2 of MainWndProc.cpp
e587c7 ¤   ¤   ¤
948116 ¤   ¤   ¤   ImageList_Remove(hilToolbar, plugin->nPGPKeysImage);
c4af5a
759e61 ¤   ¤   ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
9b7870 ¤   ¤   ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) *·
1aa50f ¤   ¤   ¤   ¤   GetDeviceCaps (hDC, PLANES);
027ec4 ¤   ¤   ¤   ReleaseDC (NULL, hDC);
0c87c7 ¤   ¤   ¤
00dbe0 ¤   ¤   ¤   if (iNumBits <= 8)·
dac253 ¤   ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
4f75c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSOFF4));
fdbb8c ¤   ¤   ¤   else
c1c253 ¤   ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
6bbb19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSOFF));
f187c7 ¤   ¤   ¤
47fd84 ¤   ¤   ¤   nPGPkeysBMP = ImageList_AddMasked(hilToolbar, hbmpPGPkeys,·
a361b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRANSPARENT_COLOR);
36c147 ¤   ¤   ¤   DeleteObject(hbmpPGPkeys);
9a2661 ¤   ¤   ¤   plugin->nPGPKeysImage = nPGPkeysBMP;
c687c7 ¤   ¤   ¤
dceb35 ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_SETIMAGELIST, 0,·
e6762a ¤   ¤   ¤   ¤   (LPARAM) hilToolbar);
4a87c7 ¤   ¤   ¤
5b6ef4 ¤   ¤   ¤   hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar,·
602cc2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_GETHOTIMAGELIST, 0, 0);
4187c7 ¤   ¤   ¤
cb6b69 ¤   ¤   ¤   if (iNumBits <= 8)
c3c253 ¤   ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
cd2196 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSLARGE4));
7abb8c ¤   ¤   ¤   else
c9c253 ¤   ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
7c5a2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSLARGE));
c787c7 ¤   ¤   ¤
ba5aca ¤   ¤   ¤   ImageList_AddMasked(hilToolbar, hbmpPGPkeys,·
9034d5 ¤   ¤   ¤   ¤   TRANSPARENT_COLOR);
eec147 ¤   ¤   ¤   DeleteObject(hbmpPGPkeys);
7c87c7 ¤   ¤   ¤
d52ded ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_SETHOTIMAGELIST, 0,·
b8762a ¤   ¤   ¤   ¤   (LPARAM) hilToolbar);
7a87c7 ¤   ¤   ¤
8570de ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGPKEYS);
680549 ¤   ¤   ¤   nPGPkeysSTR = SendMessage(plugin->hToolbar, TB_ADDSTRING, 0,
24dd61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) szText);
00c6c6 ¤   ¤   ¤   plugin->nPGPKeysString = nPGPkeysSTR;
7f87c7 ¤   ¤   ¤
186414 ¤   ¤   ¤   tbb[0].iBitmap = nPGPkeysBMP;
d0f57d ¤   ¤   ¤   tbb[0].idCommand = IDC_PGPKEYS;
37f493 ¤   ¤   ¤   tbb[0].fsState = TBSTATE_ENABLED;
fc7590 ¤   ¤   ¤   tbb[0].fsStyle = TBSTYLE_BUTTON;
b50626 ¤   ¤   ¤   tbb[0].dwData = 0;
d1fcd7 ¤   ¤   ¤   tbb[0].iString = nPGPkeysSTR;
6487c7 ¤   ¤   ¤
e43bfc ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_ADDBUTTONS, 1,·
d628fb ¤   ¤   ¤   ¤   (LPARAM) &tbb);
d587c7 ¤   ¤   ¤
94e20d ¤   ¤   ¤   plugin->nPGPKeysButton = SendMessage(plugin->hToolbar,
d62e7a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_COMMANDTOINDEX,
03cec4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_PGPKEYS,
3e90fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
dffe02 ¤   ¤   ¤   return nReturn;
7e0fe4 ¤   ¤   }
19af5a
3b6b08 ¤   case WM_DESTROY:
365b34 ¤   ¤   {
ae2538 ¤   ¤   ¤   KillTimer(hDlg, WATCH_TOOLBAR_TIMER);
c2cdcb ¤   ¤   ¤   break;
8e0fe4 ¤   ¤   }
d5af5a
b0a570 ¤   case WM_PARENTNOTIFY:
878ae1 ¤   ¤   if (LOWORD(wParam) == WM_CREATE)
f2cb68 ¤   ¤   ¤   CreateMainWindowGUI(hDlg, plugin);
202f68 ¤   ¤   break;
--f4c3 000bf4525444011022e Page 3 of MainWndProc.cpp
2a67c5 ¤
03e60b ¤   case WM_TIMER:
5e9cd5 ¤   ¤   if (wParam == WATCH_TOOLBAR_TIMER)
3c5b34 ¤   ¤   {
13a5cb ¤   ¤   ¤   int nState;
51af5a
e8bbcd ¤   ¤   ¤   nState = SendMessage(plugin->hToolbar, TB_GETSTATE,·
de3907 ¤   ¤   ¤   ¤   ¤   ¤   IDC_PGPKEYS, 0);
abaf5a
db7073 ¤   ¤   ¤   if (nState & TBSTATE_ENABLED)
6f46f1 ¤   ¤   ¤   ¤   return 0;
feaf5a
341034 ¤   ¤   ¤   nState |= TBSTATE_ENABLED;
716c67 ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_SETSTATE, IDC_PGPKEYS,·
a1ac24 ¤   ¤   ¤   ¤   MAKELONG(nState, 0));
c8af5a
dc8144 ¤   ¤   ¤   return 0;
0a0fe4 ¤   ¤   }
c42f68 ¤   ¤   break;
5aaf5a
2dc37a ¤   case WM_INITMENUPOPUP:
f95b34 ¤   ¤   {
f09a76 ¤   ¤   ¤   // For some reason, the old window proc disables the
1217c8 ¤   ¤   ¤   // menu items in the PGP popup menu. We'll enable
0bfdcb ¤   ¤   ¤   // the items after the old proc disables them
4aaf5a
cbaf24 ¤   ¤   ¤   if ((HMENU) wParam == plugin->hPGPMenu)
b8f776 ¤   ¤   ¤   {
6c46c6 ¤   ¤   ¤   ¤   CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
97a3d8 ¤   ¤   ¤   ¤   EnableMenuItem(plugin->hPGPMenu, IDC_PREFS, MF_BYCOMMAND);
772313 ¤   ¤   ¤   ¤   EnableMenuItem(plugin->hPGPMenu, IDC_PGPKEYS, MF_BYCOMMAND);
6546f1 ¤   ¤   ¤   ¤   return 0;
00a3a6 ¤   ¤   ¤   }
c4af5a
67cdcb ¤   ¤   ¤   break;
e30fe4 ¤   ¤   }
4a9371 ¤   }
b7af5a
bae939 ¤   return CommonWndProc(hDlg, msg, wParam, lParam);
eeefe6 }
55af5a
acaf5a
493eca void CreateMainWindowGUI(HWND hDlg, PluginInfo *plugin)
edbb36 {
9e1bb4 ¤   HWND hReBar;
d84de4 ¤   HWND hSizableRebar;
ea4492 ¤   TBBUTTON tbb[1];
e21066 ¤   HIMAGELIST hilToolbar;
404cea ¤   HINSTANCE hInst;
97b07d ¤   int nPGPkeysBMP;
4c8003 ¤   int nPGPkeysSTR;
fbfcc8 ¤   int nIndex;
62b48c ¤   HBITMAP hbmpPGPkeys;
903935 ¤   MENUITEMINFO menuInfo;
024986 ¤   char szText[255];
a0c1c0 ¤   DLGPROC lpOldProc;
a267c5 ¤
9085c6 ¤   plugin->hMainMenu = GetMenu(hDlg);
fa130c ¤   hSizableRebar = FindWindowEx(hDlg, NULL, "SizableRebar", NULL);
97f314 ¤   hReBar = FindWindowEx(hSizableRebar, NULL, "ReBarWindow32", NULL);
6fd5ac ¤   plugin->hToolbar = FindWindowEx(hReBar, NULL, "ToolbarWindow32", NULL);
6567c5 ¤
68335b ¤   if (!plugin->hMainMenu || !plugin->hToolbar)
0799bf ¤   ¤   return;
8467c5 ¤
2e4e70 ¤   hInst = UIGetInstance();
e167c5 ¤
83c9a4 ¤   menuInfo.cbSize = sizeof(MENUITEMINFO);
073f89 ¤   menuInfo.fMask = MIIM_SUBMENU;
14f02d ¤   GetMenuItemInfo(plugin->hMainMenu, 4, TRUE, &menuInfo);
cc7bef ¤   if (menuInfo.hSubMenu != plugin->hPGPMenu)
bfc7a1 ¤   {
--966b 0003ba223d74011022e Page 4 of MainWndProc.cpp
264687 ¤   ¤   if (plugin->hPGPMenu != NULL)
ad2cc4 ¤   ¤   ¤   DestroyMenu(plugin->hPGPMenu);
331b52 ¤   ¤
130e23 ¤   ¤   plugin->hPGPMenu = CreatePopupMenu();
c95b4d ¤   ¤   plugin->nPGPPosition = 4;
c21b52 ¤   ¤
5dccdd ¤   ¤   InsertMenu(plugin->hMainMenu, plugin->nPGPPosition,·
3a9fb5 ¤   ¤   ¤   MF_BYPOSITION | MF_STRING | MF_POPUP,·
c702a0 ¤   ¤   ¤   (UINT) plugin->hPGPMenu, "&PGP");
3c1b52 ¤   ¤
75248f ¤   ¤   UIGetString(szText, 254, IDS_MENU_PREFS);
7d659a ¤   ¤   AppendMenu(plugin->hPGPMenu, MF_STRING, IDC_PREFS,·
a3e9c0 ¤   ¤   ¤   szText);
271b52 ¤   ¤
ce2572 ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGPKEYS);
761d09 ¤   ¤   AppendMenu(plugin->hPGPMenu, MF_STRING, IDC_PGPKEYS,·
ace9c0 ¤   ¤   ¤   szText);
271b52 ¤   ¤
d43df7 ¤   ¤   DrawMenuBar(hDlg);
b39371 ¤   }
6f67c5 ¤
961b3c ¤   SendMessage(plugin->hToolbar, TB_BUTTONSTRUCTSIZE,
bb7fa9 ¤   ¤   (WPARAM) sizeof(TBBUTTON), 0);
2c67c5 ¤
c23510 ¤   nIndex = SendMessage(plugin->hToolbar, TB_COMMANDTOINDEX,
a40182 ¤   ¤   ¤   ¤   IDC_PGPKEYS, 0);
94af5a
5d3fdd ¤   if (nIndex < 0)
b5c7a1 ¤   {
202ba2 ¤   ¤   HDC¤hDC;
0a3c0a ¤   ¤   int¤iNumBits;
bd1b52 ¤   ¤
6ce4b1 ¤   ¤   hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar,·
67b3ce ¤   ¤   ¤   TB_GETIMAGELIST, 0, 0);
711b52 ¤   ¤
463060 ¤   ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
c51743 ¤   ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) *·
9ef792 ¤   ¤   ¤   ¤   ¤   GetDeviceCaps (hDC, PLANES);
17f2bb ¤   ¤   ReleaseDC (NULL, hDC);
801b52 ¤   ¤
f576be ¤   ¤   if (iNumBits <= 8)·
8f90ce ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
71f83e ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSOFF4));
370e1d ¤   ¤   else
6190ce ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
150700 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSOFF));
b9af5a
8db3f3 ¤   ¤   nPGPkeysBMP = ImageList_AddMasked(hilToolbar, hbmpPGPkeys,·
c4bf29 ¤   ¤   ¤   TRANSPARENT_COLOR);
fa80b4 ¤   ¤   DeleteObject(hbmpPGPkeys);
fc74fc ¤   ¤   plugin->nPGPKeysImage = nPGPkeysBMP;
8baf5a
d3ebd7 ¤   ¤   SendMessage(plugin->hToolbar, TB_SETIMAGELIST, 0,·
e09959 ¤   ¤   ¤   (LPARAM) hilToolbar);
881b52 ¤   ¤
04e4b1 ¤   ¤   hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar,·
5bf0a6 ¤   ¤   ¤   TB_GETHOTIMAGELIST, 0, 0);
9f1b52 ¤   ¤
877f41 ¤   ¤   if (iNumBits <= 8)
c590ce ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
34abd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSLARGE4));
180e1d ¤   ¤   else
3290ce ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst,·
cf6741 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDB_PGPKEYSLARGE));
d5af5a
1259bd ¤   ¤   ImageList_AddMasked(hilToolbar, hbmpPGPkeys,·
39bf29 ¤   ¤   ¤   TRANSPARENT_COLOR);
4980b4 ¤   ¤   DeleteObject(hbmpPGPkeys);
841b52 ¤   ¤
5c91f4 ¤   ¤   SendMessage(plugin->hToolbar, TB_SETHOTIMAGELIST, 0,·
ea9959 ¤   ¤   ¤   (LPARAM) hilToolbar);
3b1b52 ¤   ¤
--ccde 0006740201f4011022e Page 5 of MainWndProc.cpp
8b2572 ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGPKEYS);
4a023f ¤   ¤   nPGPkeysSTR = SendMessage(plugin->hToolbar, TB_ADDSTRING, 0,
4c0031 ¤   ¤   ¤   (LPARAM) szText);
8489f8 ¤   ¤   plugin->nPGPKeysString = nPGPkeysSTR;
d81b52 ¤   ¤
0a58fa ¤   ¤   tbb[0].iBitmap = nPGPkeysBMP;
0a7d1b ¤   ¤   tbb[0].idCommand = IDC_PGPKEYS;
52cd56 ¤   ¤   tbb[0].fsState = TBSTATE_ENABLED;
617328 ¤   ¤   tbb[0].fsStyle = TBSTYLE_BUTTON;
bc120e ¤   ¤   tbb[0].dwData = 0;
d4c039 ¤   ¤   tbb[0].iString = nPGPkeysSTR;
ff1b52 ¤   ¤
841d49 ¤   ¤   SendMessage(plugin->hToolbar, TB_ADDBUTTONS, 1,·
7485a5 ¤   ¤   ¤   (LPARAM) &tbb);
b91b52 ¤   ¤
1a6ff1 ¤   ¤   plugin->nPGPKeysButton = SendMessage(plugin->hToolbar,
572941 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_COMMANDTOINDEX,
e29ddf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_PGPKEYS,
67189c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
72af5a
092901 ¤   ¤   SetTimer(hDlg, WATCH_TOOLBAR_TIMER, 500, NULL);
759371 ¤   }
e367c5 ¤
9207cb ¤   // Look for status bar
595b9f ¤   plugin->hStatusBar = FindWindowEx(hDlg, NULL,·
7ade66 ¤   ¤   "msctls_statusbar32", NULL);
faaf5a
26592b ¤   lpOldProc = (DLGPROC) GetProp(hReBar, "oldproc");
7c9cef ¤   if (lpOldProc == NULL)
9cc7a1 ¤   {
075543 ¤   ¤   // Save away toolbar parent window proc
852993 ¤   ¤   SetProp(hReBar, "oldproc",·
7464dc ¤   ¤   ¤   (HANDLE) GetWindowLong(hReBar, GWL_WNDPROC));·
a8af5a
058028 ¤   ¤   // Save plugin pointer
ddfe7e ¤   ¤   SetProp(hReBar, PLUGIN_INFO_PROP, (HANDLE) plugin);
3daf5a
427e84 ¤   ¤   // Subclass toolbar parent window
6f2c86 ¤   ¤   SetWindowLong(hReBar, GWL_WNDPROC, (DWORD) ToolbarParentWndProc);
539371 ¤   }
36af5a
fe830f ¤   return;
d5efe6 }
c9af5a
3eaf5a
4e875c BOOL CALLBACK ToolbarParentWndProc(HWND hDlg,·
2a7e43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT msg,
e02ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
e475ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
8cbb36 {
5dc1c0 ¤   DLGPROC lpOldProc;
2f5cc0 ¤   PluginInfo *plugin;
52af5a
5c0955 ¤   lpOldProc = (DLGPROC)GetProp( hDlg, "oldproc" );
a76a0f ¤   plugin = (PluginInfo *) GetProp(hDlg, PLUGIN_INFO_PROP);
56af5a
1e9467 ¤   switch(msg)
bac7a1 ¤   {
dec93c ¤   case WM_NOTIFY:
f45b34 ¤   ¤   {
e9114f ¤   ¤   ¤   int nIndex;
23af5a
afa92b ¤   ¤   ¤   if ((((LPNMHDR) lParam)->code) == TBN_BEGINADJUST)
41f776 ¤   ¤   ¤   {
da8a9c ¤   ¤   ¤   ¤   nIndex = SendMessage(plugin->hToolbar, TB_COMMANDTOINDEX,
893fbf ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_PGPKEYS, 0);
f6af5a
fffc4d ¤   ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_DELETEBUTTON, nIndex, 0);
a4e710 ¤   ¤   ¤   ¤   plugin->nPGPKeysButton = -1;
6da3a6 ¤   ¤   ¤   }
12af5a
679160 ¤   ¤   ¤   if ((((LPNMHDR) lParam)->code) == TBN_ENDADJUST)
--2955 0010709350b4011022e Page 6 of MainWndProc.cpp
99f776 ¤   ¤   ¤   {
e27a48 ¤   ¤   ¤   ¤   TBBUTTON tbb[1];
f02b85 ¤   ¤   ¤   ¤
b3367c ¤   ¤   ¤   ¤   tbb[0].iBitmap = plugin->nPGPKeysImage;
aaed2d ¤   ¤   ¤   ¤   tbb[0].idCommand = IDC_PGPKEYS;
b7bbad ¤   ¤   ¤   ¤   tbb[0].fsState = TBSTATE_ENABLED;
b6270d ¤   ¤   ¤   ¤   tbb[0].fsStyle = TBSTYLE_BUTTON;
0c8a59 ¤   ¤   ¤   ¤   tbb[0].dwData = 0;
d92856 ¤   ¤   ¤   ¤   tbb[0].iString = plugin->nPGPKeysString;
742b85 ¤   ¤   ¤   ¤
bbe1d5 ¤   ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_ADDBUTTONS, 1,·
01a307 ¤   ¤   ¤   ¤   ¤   (LPARAM) &tbb);
682b85 ¤   ¤   ¤   ¤
94f181 ¤   ¤   ¤   ¤   plugin->nPGPKeysButton = SendMessage(plugin->hToolbar,
b62e98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_COMMANDTOINDEX,
ffa1f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_PGPKEYS,
5088aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
0aa3a6 ¤   ¤   ¤   }
64af5a
32cdcb ¤   ¤   ¤   break;
4e0fe4 ¤   ¤   }
919371 ¤   }
7eaf5a
016a22 ¤   return CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
9aefe6 }
27af5a
41af5a
1b7e4d /*__Editor_settings____
b7af5a
0c4126 ¤   Local Variables:
b47b17 ¤   tab-width: 4
ae0e6c ¤   End:
8a5f8c ¤   vi: ts=4 sw=4
3f9e9b ¤   vim: si
07d062 _____________________*/
--6899 000596fb7584011022f Page 1 of PGP55oe.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
19f860 #ifdef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
66465d //
df5733 // TEXTINCLUDE
a2465d //
99af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
2d4523 BEGIN
70541e ····"resource.h\0"
48e0d1 END
85af5a
467037 2 TEXTINCLUDE DISCARDABLE·
044523 BEGIN
c3eb23 ····"#include ""afxres.h""\r\n"
98db5c ····"\0"
97e0d1 END
5aaf5a
ea227f 3 TEXTINCLUDE DISCARDABLE·
024523 BEGIN
a7d68a ····"#include ""PGP55oeVer.rc""\r\n"
714537 ····"#include ""..\\shared\\Working.rc""\r\n"
b16c56 ····"#include ""..\\shared\\SharedStrings.rc""\r\n"
02db5c ····"\0"
cae0d1 END
f8af5a
4269ab #endif ···// APSTUDIO_INVOKED
c8af5a
7aaf5a
256c0e /////////////////////////////////////////////////////////////////////////////
8f465d //
deb090 // Dialog
c0465d //
90af5a
6e7ce5 IDD_HEXDUMP DIALOG DISCARDABLE ·0, 0, 346, 218
73e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
58b5d2 CAPTION "Hex Dump"
921145 FONT 9, "Courier New"
ab4523 BEGIN
3e3dd1 ····DEFPUSHBUTTON ··"OK",IDOK,147,197,50,14
478227 ····CONTROL ········"List2",IDC_DUMP,"SysListView32",LVS_REPORT |·
c63ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
e53b50 ····················WS_TABSTOP,7,7,332,179
c4e0d1 END
c9af5a
ad61e0 IDD_WARN DIALOG DISCARDABLE ·0, 0, 186, 95
c5e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
298939 CAPTION "PGP Plug-in for Outlook Express"
7a309f FONT 8, "MS Sans Serif"
594523 BEGIN
--a77d 000d726d1184011022f Page 2 of PGP55oe.rc
d30a61 ····PUSHBUTTON ·····"&Yes",IDC_YESCONTINUE,26,54,50,14
87029e ····PUSHBUTTON ·····"&No",IDC_NOCONTINUE,112,54,50,14
3efab9 ····CTEXT ··········"Place warning here",IDC_WARNING,7,7,172,42
1348d9 ····CONTROL ········"Do not &warn me any more",IDC_NOWARN,"Button",
544d99 ····················BS_AUTOCHECKBOX | WS_TABSTOP,7,77,172,11
75e0d1 END
44af5a
08af5a
c76c0e /////////////////////////////////////////////////////////////////////////////
22465d //
216077 // DESIGNINFO
95465d //
cbaf5a
f6f860 #ifdef APSTUDIO_INVOKED
3770e4 GUIDELINES DESIGNINFO DISCARDABLE·
b44523 BEGIN
feaf4e ····IDD_HEXDUMP, DIALOG
bc5574 ····BEGIN
a6c975 ········LEFTMARGIN, 7
75794b ········RIGHTMARGIN, 339
5987e9 ········TOPMARGIN, 7
ee953e ········BOTTOMMARGIN, 211
a17d01 ····END
05af5a
596371 ····IDD_WARN, DIALOG
cc5574 ····BEGIN
f9c975 ········LEFTMARGIN, 7
cf235c ········RIGHTMARGIN, 179
b287e9 ········TOPMARGIN, 7
6d94b9 ········BOTTOMMARGIN, 88
d77d01 ····END
ade0d1 END
4169ab #endif ···// APSTUDIO_INVOKED
2baf5a
c3af5a
0f6c0e /////////////////////////////////////////////////////////////////////////////
88465d //
99ae70 // Bitmap
9c465d //
57af5a
aae874 IDB_SIGN ···············BITMAP ·DISCARDABLE ····"Res\\sign.bmp"
915baa IDB_DECRYPT ············BITMAP ·DISCARDABLE ····"Res\\decrypt.bmp"
e423f0 IDB_ENCRYPT ············BITMAP ·DISCARDABLE ····"Res\\encrypt.bmp"
73cf75 IDB_PGPKEYS ············BITMAP ·DISCARDABLE ····"Res\\pgpkeys.bmp"
625d63 IDB_PGPKEYSLARGE ·······BITMAP ·DISCARDABLE ····"res\\pgpkeysl.bmp"
8927cd IDB_PGPKEYSOFF ·········BITMAP ·DISCARDABLE ····"res\\pgpkeyso.bmp"
9e9a83 IDB_PGPKEYSLARGE4 ······BITMAP ·DISCARDABLE ····"res\\pkl4.bmp"
30fc40 IDB_PGPKEYSOFF4 ········BITMAP ·DISCARDABLE ····"res\\pko4.bmp"
37af5a
1b6c0e /////////////////////////////////////////////////////////////////////////////
6a465d //
8f5e87 // String Table
e7465d //
baaf5a
4c6f6c STRINGTABLE DISCARDABLE·
074523 BEGIN
49bc27 ····IDS_TITLE ··············"PGP Plug-in for Outlook Express"
0cb956 ····IDS_E_EXPIRED ··········"This version of PGP has expired. The Outlook Expre¶
d28e36 ss plug-in will not be available."
a8ad8c ····IDS_STATUS_PGP ·········"Contains commands for configuring PGP."
e7a246 ····IDS_STATUS_PREFS ·······"Allows you to configure PGP user preferences."
9f0327 ····IDS_STATUS_PGPKEYS ·····"Launches the PGP Key Management program."
67b4c2 ····IDS_LOGNAME ············"Outlook Express"
7bdc9c ····IDS_SIGKEYREVOKED ······"The key used to sign this message has been revoked¶
f5cfc1 . The signature cannot be completely trusted."
1b4194 ····IDS_SIGKEYDISABLED ·····"The key used to sign this message has been disable¶
0447f1 d."
2dd725 ····IDS_SIGKEYEXPIRED ······"The key used to sign this message has expired. The¶
aaf402 ·integrity of the signature is secure if the message was signed before the key'¶
53dc34 s expiration date.\n\nYou may need to update your keyring with the signer's lat¶
038634 est key."
d77c1b ····IDS_E_NOPGP ············"No valid PGP message blocks found"
--7646 00188f354df4011022f Page 3 of PGP55oe.rc
f8a079 ····IDS_E_NOKEYS ···········"No valid PGP key blocks found"
fada54 ····IDS_STATUS_SMIME_ENCRYPT "Encrypts the message using S/MIME."
9ef652 ····IDS_STATUS_PGP_ENCRYPT ·"Encrypts the message using PGP."
ed66de ····IDS_STATUS_SMIME_SIGN ··"Signs the message digitally using S/MIME."
81d5ac ····IDS_STATUS_PGP_SIGN ····"Signs the message digitally using PGP."
14e0d1 END
74af5a
556f6c STRINGTABLE DISCARDABLE·
cd4523 BEGIN
d03475 ····IDS_STATUS_DECRYPT ·····"Decrypts and verifies any PGP-encrypted or PGP-sig¶
1a88d0 ned messages."
2fe6d9 ····IDS_STATUS_ADDKEYS ·····"Adds any PGP public keys to your keyring."
8a7a7b ····IDS_MENU_PREFS ·········"&Preferences..."
65cadb ····IDS_MENU_PGPKEYS ·······"&Launch PGPkeys"
380ff1 ····IDS_MENU_SMIME_ENCRYPT ·"&Encrypt using S/MIME"
7eec29 ····IDS_MENU_PGP_ENCRYPT ···"En&crypt using PGP"
5ee830 ····IDS_MENU_SMIME_SIGN ····"&Digitally Sign using S/MIME"
e45439 ····IDS_MENU_PGP_SIGN ······"Digitally &Sign using PGP"
1452e5 ····IDS_MENU_DECRYPT ·······"&Decrypt message"
753c86 ····IDS_MENU_ADDKEYS ·······"Add &keys"
5af245 ····IDS_TOOLTIP_PGPKEYS ····"Launch PGPkeys"
74fcdc ····IDS_TOOLTIP_SMIME_ENCRYPT "Encrypt message (S/MIME)"
f4f8fe ····IDS_TOOLTIP_PGP_ENCRYPT "Encrypt message (PGP)"
37d270 ····IDS_TOOLTIP_SMIME_SIGN ·"Digitally sign message (S/MIME)"
0aa723 ····IDS_TOOLTIP_PGP_SIGN ···"Digitally sign message (PGP)"
1d7cb7 ····IDS_TOOLTIP_DECRYPT ····"Decrypt PGP message"
94e0d1 END
c9af5a
976f6c STRINGTABLE DISCARDABLE·
2e4523 BEGIN
5f7ff2 ····IDS_TOOLTIP_ADDKEYS ····"Add PGP keys"
db3ba4 ····IDS_WARNING_REGKEY ·····"Software\\Network Associates\\PGP60\\OutlookExpres¶
96d384 s\\"
ea143d ····IDS_W_ATTACHMENT ·······"The files that you have attached to this message w¶
f5a054 ill not be encrypted or signed. If you wish to send encrypted and/or signed fil¶
4ecfd3 es, you must encrypt or sign them before attaching them to the message. Do you ¶
957d74 want to continue sending this message?"
c8894b ····IDS_E_NOPGPKEYS ········"PGPkeys could not be found. Re-install PGP to fix ¶
7b83c8 this problem."
28b7b8 ····IDS_E_BUFFERTOOBIG ·····"Your message is too large. Due to Windows 95 limit¶
023b66 ations, \nmessages larger than 64 K bytes cannot be processed by PGP."
4d9978 ····IDS_PGPKEYSEXE ·········"PGPkeys /s"
d354ac ····IDS_EXE ················"Outlook Express"
c27f2e ····IDS_DLL ················"PGP60oe.dll"
6534d4 ····IDS_RECIPIENTDIALOG ····"Recipient Selection"
3de0d1 END
23af5a
671b3a #endif ···// English (U.S.) resources
a86c0e /////////////////////////////////////////////////////////////////////////////
acaf5a
54af5a
03af5a
97ce8c #ifndef APSTUDIO_INVOKED
976c0e /////////////////////////////////////////////////////////////////////////////
9e465d //
ac8464 // Generated from the TEXTINCLUDE 3 resource.
0d465d //
de4a05 #include "PGP55oeVer.rc"
7df88e #include "..\shared\Working.rc"
5896d0 #include "..\shared\SharedStrings.rc"
8baf5a
e26c0e /////////////////////////////////////////////////////////////////////////////
fb8072 #endif ···// not APSTUDIO_INVOKED
88af5a
--936a 00127f0f65540110230 Page 1 of PGP55oeVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
353263 ············VALUE "FileDescription", "PGP Plug-in for Outlook Express E-mail cl¶
a7d681 ient\0"
ecc1dd ············VALUE "FileVersion", PGPVERSIONSTRING
f1e119 ············VALUE "InternalName", "PGP60oe\0"
ff8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
752bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
8538dc ············VALUE "OriginalFilename", "PGP60oe.dll\0"
819317 ············VALUE "ProductName", PGPPRODUCTNAME
ccd1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
79f37f ········END
887d01 ····END
bd26ab ····BLOCK "VarFileInfo"
bf5574 ····BEGIN
bb4b11 ········VALUE "Translation", 0x409, 1200
617d01 ····END
9fe0d1 END
d5af5a
f2af5a
27af5a
--84a4 00004d0e46740110231 Page 1 of PluginInfo.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d3b4cd ¤   $Id: PluginInfo.cpp,v 1.12.8.1 1998/11/12 03:12:45 heller Exp $
d0f7f7 ____________________________________________________________________________*/
5baf5a
4a5655 #include <windows.h>
06390b #include "PluginInfo.h"
9aadf9 #include "UIutils.h"
748031 #include "resource.h"
bf2f8d #include "pgpErrors.h"
d04919 #include "pgpUtilities.h"
b9a076 #include "pgpKeys.h"
9a5ab2 #include "PGPcl.h"
9baf5a
2a92e0 #define PLUGIN_INFO_PROP¤   ¤   "PGP plugin"
88af5a
7b2c67 PGPContextRef _pgpContext = NULL;¤  ¤   // PGP context of current instance
132733 PGPtlsContextRef _tlsContext = NULL;¤   // TLS context of current instance
3e90fc PGPError _errContext = kPGPError_NoErr;¤// Error code if context failed
266b07 char *_szReplyText = NULL;
72af5a
5b50b2 static BOOL DoIExist(void);
06342d static void SetNoLoad(void);
709c3a static BOOL ShouldILoad(void);
81af5a
ccaf5a
2aad60 PluginInfo * CreatePluginInfo(HWND hwnd)
8dbb36 {
3961e0 ¤   PGPError¤   err;
e69455 ¤   PluginInfo¤ *plugin;
50af5a
64b5ab ¤   plugin = (PluginInfo *) calloc(sizeof(PluginInfo), 1);
e2af5a
7a6b4c ¤   plugin->bLoaded = DoIExist();
8ef39b ¤   if (!(plugin->bLoaded) || (_pgpContext == NULL))
26c12a ¤   ¤   _errContext = PGPNewContext(kPGPsdkAPIVersion, &_pgpContext);
19af5a
330cd7 ¤   if (!ShouldILoad())
46c7a1 ¤   {
5214eb ¤   ¤   free(plugin);
347ed2 ¤   ¤   return NULL;
e49371 ¤   }
83af5a
bc3a8c ¤   // Check for SDK expiration or other SDK initialization failure
a5af5a
812ded ¤   if (IsPGPError(_errContext))
78c7a1 ¤   {
f471c4 ¤   ¤   if (_errContext == kPGPError_FeatureNotAvailable)
9ddb47 ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_EXPIRED);
770e1d ¤   ¤   else
5bc9d7 ¤   ¤   ¤   PGPclErrorBox(hwnd, _errContext);
25af5a
568cd7 ¤   ¤   SetNoLoad();
e014eb ¤   ¤   free(plugin);
1f7ed2 ¤   ¤   return NULL;
3c9371 ¤   }
aeaf5a
7b9c6d ¤   // Check for beta/demo expiration
eaaf5a
ad2d0e ¤   if (PGPclIsExpired(hwnd))
a2c7a1 ¤   {
618cd7 ¤   ¤   SetNoLoad();
9114eb ¤   ¤   free(plugin);
d27ed2 ¤   ¤   return NULL;
879371 ¤   }
9faf5a
b0d1da ¤   if (!(plugin->bLoaded))
042d9e ¤   ¤   PGPNewTLSContext(_pgpContext, &_tlsContext);
--bf97 000b402fded40110231 Page 2 of PluginInfo.cpp
e0af5a
601a65 ¤   // Initialize common library
4daf5a
b4d1da ¤   if (!(plugin->bLoaded))
7fc7a1 ¤   {
1eeb93 ¤   ¤   err = PGPclInitLibrary(_pgpContext);
ddb6ad ¤   ¤   if (IsPGPError(err))
1c5b34 ¤   ¤   {
d59c7e ¤   ¤   ¤   PGPclErrorBox(hwnd, err);
2f3d06 ¤   ¤   ¤   SetNoLoad();
46d35e ¤   ¤   ¤   free(plugin);
01cf03 ¤   ¤   ¤   return NULL;
9d0fe4 ¤   ¤   }
2f9371 ¤   }
6daf5a
790842 ¤   plugin->pgpContext = _pgpContext;
6ad4ae ¤   plugin->tlsContext = _tlsContext;
fad114 ¤   plugin->memoryMgr = PGPGetContextMemoryMgr(_pgpContext);
1373e8 ¤   plugin->nPurgeCacheMsg = RegisterWindowMessage(PURGEPASSPHRASECACEHMSG);
d7d92d ¤   plugin->nPGPKeysButton = -1;
b051de ¤   plugin->nPGPKeysImage = -1;
43304c ¤   plugin->nPGPKeysString = -1;
4c35af ¤   return plugin;
32efe6 }
14af5a
33af5a
064d8f PluginInfo * GetPluginInfo(HWND hwnd)
83bb36 {
aaa136 ¤   return (PluginInfo *) GetProp(hwnd, PLUGIN_INFO_PROP);
4cefe6 }
e7af5a
ddaf5a
796eb8 void SavePluginInfo(HWND hwnd, PluginInfo *plugin)
22bb36 {
0e53f5 ¤   if (plugin->hwndCurrent != NULL)
67cd58 ¤   ¤   RemoveProp(plugin->hwndCurrent, PLUGIN_INFO_PROP);
f7af5a
b12f81 ¤   SetProp(hwnd, PLUGIN_INFO_PROP, (HANDLE) plugin);
c2aa06 ¤   plugin->hwndCurrent = hwnd;
b3830f ¤   return;
7eefe6 }
f3af5a
58af5a
257350 void FreePluginInfo(PluginInfo *plugin)
f4bb36 {
5c53f5 ¤   if (plugin->hwndCurrent != NULL)
c9cd58 ¤   ¤   RemoveProp(plugin->hwndCurrent, PLUGIN_INFO_PROP);
47af5a
e5a9f4 ¤   if (plugin->hPGPMenu != NULL)
d4c7a1 ¤   {
c82288 ¤   ¤   DestroyMenu(plugin->hPGPMenu);
af6279 ¤   ¤   plugin->hPGPMenu = NULL;
779371 ¤   }
98af5a
670b45 ¤   if (plugin->szOutput != NULL)
b7c7a1 ¤   {
fa1087 ¤   ¤   free(plugin->szOutput);
1ee1ae ¤   ¤   plugin->szOutput = NULL;
619371 ¤   }
90af5a
25d1da ¤   if (!(plugin->bLoaded))
88c7a1 ¤   {
b8c668 ¤   ¤   FreeReplyText();
6daf5a
c16703 ¤   ¤   if (_tlsContext)
ff5b34 ¤   ¤   {
99c7b0 ¤   ¤   ¤   PGPFreeTLSContext(_tlsContext);
0a0705 ¤   ¤   ¤   _tlsContext = NULL;
600fe4 ¤   ¤   }
88af5a
34c6eb ¤   ¤   if (_pgpContext && IsntPGPError(_errContext))
b4d901 ¤   ¤   {¤  ¤   ¤
--3664 000236f34af40110231 Page 3 of PluginInfo.cpp
2359d4 ¤   ¤   ¤   PGPclCloseLibrary();
7bbbf9 ¤   ¤   ¤   PGPFreeContext(_pgpContext);
3f9465 ¤   ¤   ¤   _pgpContext = NULL;
350fe4 ¤   ¤   }
2c9371 ¤   }
c8af5a
b32e71 ¤   free(plugin);
44efe6 }
f0af5a
d4af5a
6721a1 void SetReplyText(char *szText)
d9bb36 {
8277b9 ¤   FreeReplyText();
3c5e24 ¤   _szReplyText = szText;
f3830f ¤   return;
26efe6 }
16af5a
deaf5a
b1de29 char *GetReplyText()
bcbb36 {
e59a1e ¤   return _szReplyText;
d2efe6 }
20af5a
6faf5a
5e6d03 void FreeReplyText()
20bb36 {
095a1a ¤   if (_szReplyText != NULL)
62c7a1 ¤   {
12313d ¤   ¤   free(_szReplyText);
992118 ¤   ¤   _szReplyText = NULL;
119371 ¤   }
5667c5 ¤
b3830f ¤   return;
a8efe6 }
beaf5a
05af5a
5c2178 BOOL DoIExist()
dfbb36 {
dd079d ····HANDLE hSem;
97af5a
add5d5 ····// Create or open a named semaphore
d5af5a
0ff16a ¤   hSem = CreateSemaphore (NULL, 0, 1, "pgpOutlookExpressInstSem");
16af5a
31a7d7 ····// Close handle and return TRUE if existing semaphore was opened.
733254 ····if ((hSem != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))·
fcc7a1 ¤   {
8f5806 ········CloseHandle(hSem);
3e4ee5 ········return TRUE;
239371 ¤   }
34af5a
c7a230 ¤   return FALSE;
c2efe6 }
78af5a
32af5a
f13830 void SetNoLoad()
d7bb36 {
ff079d ····HANDLE hSem;
d0af5a
5018c5 ····// Create or open a named semaphore.·
bfccf2 ····hSem = CreateSemaphore (NULL, 0, 1, "pgpOutlookExpressLoadSem");
caaf5a
943254 ····if ((hSem != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))·
8e5806 ········CloseHandle(hSem);
edaf5a
83830f ¤   return;
fdefe6 }
40af5a
27af5a
e3fd9d BOOL ShouldILoad()
1abb36 {
23079d ····HANDLE hSem;
--f262 001128eda5a40110231 Page 4 of PluginInfo.cpp
c21eeb ¤   BOOL bShouldLoad = TRUE;
75af5a
9c18c5 ····// Create or open a named semaphore.·
75ccf2 ····hSem = CreateSemaphore (NULL, 0, 1, "pgpOutlookExpressLoadSem");
5caf5a
1cfd11 ····if (hSem != NULL)
69c7a1 ¤   {
c1b363 ¤   ¤   if (GetLastError() == ERROR_ALREADY_EXISTS)·
cf33c0 ¤   ¤   ¤   bShouldLoad = FALSE;
c00e1d ¤   ¤   else
1f9322 ¤   ¤   ¤   bShouldLoad = TRUE;
fbaf5a
0a4fd4 ¤   ¤   CloseHandle(hSem);
799371 ¤   }
61af5a
0dfaa1 ¤   return bShouldLoad;
58efe6 }
96af5a
95af5a
bd7e4d /*__Editor_settings____
41af5a
744126 ¤   Local Variables:
e37b17 ¤   tab-width: 4
0a0e6c ¤   End:
5e5f8c ¤   vi: ts=4 sw=4
c59e9b ¤   vim: si
12d062 _____________________*/
--fcf9 0002f0ea08a40110232 Page 1 of PluginInfo.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
132534 ¤   $Id: PluginInfo.h,v 1.14.8.1 1998/11/12 03:12:45 heller Exp $
bcf7f7 ____________________________________________________________________________*/
9ae5d1 #ifndef Included_PluginInfo_h¤  /* [ */
95446e #define Included_PluginInfo_h
c9af5a
1c5655 #include <windows.h>
944919 #include "pgpUtilities.h"
18ec82 #include "pgpTLS.h"
88af5a
1618d1 /* Data shared across and during window procs */
baaf5a
1f7736 typedef struct _PluginInfo
e5bb36 {
4186f7 ¤   PGPContextRef pgpContext;
8eb9c0 ¤   PGPtlsContextRef tlsContext;
0c72aa ¤   PGPMemoryMgrRef memoryMgr;
753b9b ¤   BOOL bLoaded;
9d0d37 ¤   UINT nPurgeCacheMsg;
ba2f1c ¤   HMENU hMainMenu;
d4ca71 ¤   HMENU hToolsMenu;
408346 ¤   HMENU hPGPMenu;
26e1ce ¤   HWND hwndCurrent;
a4cb7c ¤   HWND hStatusBar;
540f31 ¤   HWND hToolbar;
e67a9e ¤   HWND hEdit;
bbc0ed ¤   HWND hMessage;
a9cab4 ¤   BOOL bEncrypt;
607b0f ¤   BOOL bSign;
2e5b71 ¤   char *szReplyText;
6c18b9 ¤   char *szOutput;
fe771a ¤   UINT nPGPPosition;
c9690e ¤   INT nPGPKeysButton;
97c7ed ¤   INT nPGPKeysImage;
cb7c77 ¤   INT nPGPKeysString;
8bf96b } PluginInfo;
39af5a
84af5a
f774cf /* Outlook Express Command IDs */
86af5a
0f3ad6 #define IDC_SAVE¤   ¤   ¤   ¤   ¤   110
d1fa60 #define IDC_UNDO¤   ¤   ¤   ¤   ¤   117
951a07 #define IDC_CUT¤¤   ¤   ¤   ¤   ¤   118
64c167 #define IDC_COPY¤   ¤   ¤   ¤   ¤   119
b7002c #define IDC_PASTE¤  ¤   ¤   ¤   ¤   120
ec208b #define IDC_SELECTALL¤  ¤   ¤   ¤   122
6c9047 #define IDC_NEXT¤   ¤   ¤   ¤   ¤   139
3e7aa2 #define IDC_PREVIOUS¤   ¤   ¤   ¤   140
d738c6 #define IDC_REPLY¤  ¤   ¤   ¤   ¤   142
16c5ec #define IDC_REPLYTOALL¤ ¤   ¤   ¤   143
5f9d3b #define IDC_REPLYTOGROUP¤   ¤   ¤   144
a5c1f9 #define IDC_REPLYTOAUTHOR¤  ¤   ¤   145
09044a #define IDC_FORWARD¤¤   ¤   ¤   ¤   146
ceef6b #define IDC_NEXTUNREADARTICLE¤  ¤   151
730a9d #define IDC_PRINT¤  ¤   ¤   ¤   ¤   168¤
d9009a #define IDC_SENDMESSAGE_MENU¤   ¤   207
835913 #define IDC_ATTACHFILE¤ ¤   ¤   ¤   210
ba411c #define IDC_NEXTUNREADTHREAD¤   ¤   227
726338 #define IDC_POSTARTICLE_MENU¤   ¤   234
4228f1 #define IDC_REPLYTOGROUPANDAUTHOR¤  396
9525b2 #define IDC_ENCRYPT_SMIME¤  ¤   ¤   461
709f82 #define IDC_SIGN_SMIME¤ ¤   ¤   ¤   460
664762 #define IDC_NEXTUNREADMESSAGE¤  ¤   471
5575c4 #define IDC_SENDLATER¤  ¤   ¤   ¤   674
ce5864 #define IDC_POSTLATER¤  ¤   ¤   ¤   675
55d73f #define IDC_SENDMESSAGE_BUTTON¤ ¤   678
2f6849 #define IDC_POSTARTICLE_BUTTON¤ ¤   679
--5594 0018dae426b40110232 Page 2 of PluginInfo.h
e0af5a
1aaf5a
c66316 /* Plug-in Command IDs */
2caf5a
518e01 #define IDC_ENCRYPT_PGP¤¤   ¤   ¤   40001
780f94 #define IDC_SIGN_PGP¤   ¤   ¤   ¤   40002
daa24e #define IDC_ENCRYPTNOW¤ ¤   ¤   ¤   40003
d1250e #define IDC_SIGNNOW¤¤   ¤   ¤   ¤   40004
77451a #define IDC_ENCRYPTSIGNNOW¤ ¤   ¤   40005
7f41c0 #define IDC_PREFS¤  ¤   ¤   ¤   ¤   40010
d04185 #define IDC_PGPKEYS¤¤   ¤   ¤   ¤   40011
1abb43 #define IDC_DECRYPT¤¤   ¤   ¤   ¤   40020
1baf5a
09af5a
e298ef /* "Tools" submenu positions */
4baf5a
01b918 #define ENCRYPT_SMIME_POS¤  8
67514a #define ENCRYPT_PGP_POS¤¤   9
584a9f #define SIGN_SMIME_POS¤ ¤   10
676605 #define SIGN_PGP_POS¤   ¤   11
8daf5a
53af5a
e01d59 /* Other menu and submenu positions */
8aaf5a
98432d #define FILE_MENU_POS¤  ¤   ¤   ¤   0
c1d72d #define FILESAVEAS_MENU_POS¤¤   ¤   0
0ae920 #define FILESTATIONERY_MENU_POS¤¤   2
9cc1de #define FILEMOVE_MENU_POS¤  ¤   ¤   5
bb5809 #define FILECOPY_MENU_POS¤  ¤   ¤   6
400b8f #define FILEPRINT_MENU_POS¤ ¤   ¤   8
167f11 #define EDIT_MENU_POS¤  ¤   ¤   ¤   1
f04942 #define VIEW_MENU_POS¤  ¤   ¤   ¤   2
f6d32b #define VIEWFONTS_MENU_POS¤ ¤   ¤   2
a716d7 #define VIEWLANG_MENU_POS¤  ¤   ¤   3
85af5a
dfaf5a
34da78 /* Custom window messages and timers */
aeaf5a
0ef378 #define PASTE_REPLY_TIMER¤  ¤   262
8f66b1 #define WATCH_TOOLBAR_TIMER¤¤   263
ac2a35 #define CORRECT_TOOLBAR_TIMER¤  264
c6de25 #define AUTO_DECRYPT_TIMER¤ ¤   265
99af5a
48158a #define TRANSPARENT_COLOR¤  RGB(255, 0, 0)
d2af5a
51af5a
8f638b PluginInfo * CreatePluginInfo(HWND hwnd);
0a7c92 PluginInfo * GetPluginInfo(HWND hwnd);
7e398d void SavePluginInfo(HWND hwnd, PluginInfo *plugin);
5252d6 void FreePluginInfo(PluginInfo *plugin);
64af5a
beb482 void SetReplyText(char *szText);
21e668 char *GetReplyText(void);
fb8e00 void FreeReplyText(void);
83af5a
fdaf5a
637f6c #endif /* ] Included_PluginInfo_h */
0baf5a
9caf5a
447e4d /*__Editor_settings____
50af5a
0e4126 ¤   Local Variables:
707b17 ¤   tab-width: 4
7f0e6c ¤   End:
8a5f8c ¤   vi: ts=4 sw=4
7b9e9b ¤   vim: si
8dd062 _____________________*/
--0ed1 0006ba1ddf140110233 Page 1 of ReadMsgWndProc.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
963eb3 ¤   $Id: ReadMsgWndProc.cpp,v 1.17.2.1.2.1 1998/11/12 03:12:46 heller Exp $
86f7f7 ____________________________________________________________________________*/
ebaf5a
5f5655 #include <windows.h>
aa90fb #include <commctrl.h>
e7390b #include "PluginInfo.h"
2b8d66 #include "HookProcs.h"
85adf9 #include "UIutils.h"
cef299 #include "TextIO.h"
d9cc89 #include "Prefs.h"
8a8031 #include "resource.h"
d72f8d #include "pgpErrors.h"
2105f4 #include "AddKey.h"
35d2cf #include "BlockUtils.h"
3553a7 #include "DecryptVerify.h"
c2b545 #include "pgpSC.h"
23af5a
32097d static BOOL DecryptVerifyMessage(HWND hwnd, PluginInfo *plugin);
927f58 static void EnableMenus(HWND hwnd, PluginInfo *plugin, BOOL bEnable);
27af5a
daaf5a
1d92fe BOOL CALLBACK ReadMsgWndProc(HWND hDlg,·
402aaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,
f3d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
c9a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
eebb36 {
a4c1c0 ¤   DLGPROC lpOldProc;
ac5cc0 ¤   PluginInfo *plugin;
93af5a
a80955 ¤   lpOldProc = (DLGPROC)GetProp( hDlg, "oldproc" );
488af7 ¤   plugin = GetPluginInfo(hDlg);
e1af5a
999467 ¤   switch(msg)
f6c7a1 ¤   {
0f1fbc ¤   case WM_SIZE:
495b34 ¤   ¤   {
d281fc ¤   ¤   ¤   if (plugin->hEdit)
633eda ¤   ¤   ¤   ¤   if ((wParam == SIZE_MAXIMIZED) || (wParam == SIZE_RESTORED))
ad42bd ¤   ¤   ¤   ¤   ¤   PostMessage(hDlg, WM_EXITSIZEMOVE, 0, 0);
98af5a
5dcdcb ¤   ¤   ¤   break;
360fe4 ¤   ¤   }
dfaf5a
3439a0 ¤   case WM_SIZING:
ccfe54 ¤   case WM_EXITSIZEMOVE:
1a5b34 ¤   ¤   {
9a81fc ¤   ¤   ¤   if (plugin->hEdit)
37f776 ¤   ¤   ¤   {
b51e11 ¤   ¤   ¤   ¤   RECT rc;
fbaf5a
ad20b9 ¤   ¤   ¤   ¤   GetClientRect(plugin->hMessage, &rc);
b29a67 ¤   ¤   ¤   ¤   SetWindowPos(plugin->hEdit, NULL,·
0fad3f ¤   ¤   ¤   ¤   ¤   rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
c8d77d ¤   ¤   ¤   ¤   ¤   SWP_NOZORDER | SWP_SHOWWINDOW);
74a3a6 ¤   ¤   ¤   }
f1af5a
eccdcb ¤   ¤   ¤   break;
2c0fe4 ¤   ¤   }
65af5a
26e60b ¤   case WM_TIMER:
b6876b ¤   ¤   if (wParam == AUTO_DECRYPT_TIMER)
3f5b34 ¤   ¤   {
f47bc3 ¤   ¤   ¤   KillTimer(hDlg, AUTO_DECRYPT_TIMER);
a4d2a6 ¤   ¤   ¤   PostMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_DECRYPT, 0), 0);
c48144 ¤   ¤   ¤   return 0;
6b0fe4 ¤   ¤   }
--a47b 000f9e22fa740110233 Page 2 of ReadMsgWndProc.cpp
4f2f68 ¤   ¤   break;
92af5a
b708b5 ¤   case WM_MENUSELECT:
415b34 ¤   ¤   {
b48f67 ¤   ¤   ¤   UINT uFlags = (UINT) HIWORD(wParam);
e70767 ¤   ¤   ¤   char szText[255];
2ecfda ¤   ¤   ¤   BOOL bPluginMenu = FALSE;
08af5a
b39164 ¤   ¤   ¤   switch(LOWORD(wParam))
51f776 ¤   ¤   ¤   {
944f7d ¤   ¤   ¤   ¤   case IDC_DECRYPT:
4d72c3 ¤   ¤   ¤   ¤   {
901959 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_DECRYPT);
2c1b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
d714c3 ¤   ¤   ¤   ¤   ¤   break;
7c2613 ¤   ¤   ¤   ¤   }
e95a2a ¤   ¤   ¤   }¤
6daf5a
4aa162 ¤   ¤   ¤   if (bPluginMenu)
e7f776 ¤   ¤   ¤   {
f946c6 ¤   ¤   ¤   ¤   CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
9701cc ¤   ¤   ¤   ¤   SendMessage(plugin->hStatusBar, SB_SETTEXT,·
4877f7 ¤   ¤   ¤   ¤   ¤   255 | SBT_NOBORDERS, (LPARAM) szText);
51af5a
bd46f1 ¤   ¤   ¤   ¤   return 0;
55a3a6 ¤   ¤   ¤   }
42af5a
4ecdcb ¤   ¤   ¤   break;
bd0fe4 ¤   ¤   }
fdaf5a
f78e1e ¤   ¤   case WM_COMMAND:
905b34 ¤   ¤   {
ae9164 ¤   ¤   ¤   switch(LOWORD(wParam))
a7f776 ¤   ¤   ¤   {
8e4f7d ¤   ¤   ¤   ¤   case IDC_DECRYPT:
8a72c3 ¤   ¤   ¤   ¤   {
f98a2b ¤   ¤   ¤   ¤   ¤   DecryptVerifyMessage(hDlg, plugin);
6314c3 ¤   ¤   ¤   ¤   ¤   break;
862613 ¤   ¤   ¤   ¤   }
0baf5a
ab148e ¤   ¤   ¤   ¤   case IDC_REPLY:
f262ea ¤   ¤   ¤   ¤   case IDC_REPLYTOALL:
0955e2 ¤   ¤   ¤   ¤   case IDC_REPLYTOGROUP:
5e126e ¤   ¤   ¤   ¤   case IDC_REPLYTOAUTHOR:
94185d ¤   ¤   ¤   ¤   case IDC_REPLYTOGROUPANDAUTHOR:
5e9e4c ¤   ¤   ¤   ¤   case IDC_FORWARD:
1d4859 ¤   ¤   ¤   ¤   ¤   {
d00022 ¤   ¤   ¤   ¤   ¤   ¤   if (plugin->szOutput != NULL)
e78fec ¤   ¤   ¤   ¤   ¤   ¤   {
9fb411 ¤   ¤   ¤   ¤   ¤   ¤   ¤   char *szText;
5daf5a
cfe26b ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText = (char *)·
984432 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·calloc(strlen(plugin->szOutput)+1, 1);
cbaf5a
181e58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szText, plugin->szOutput);
0d5859 ¤   ¤   ¤   ¤   ¤   ¤   ¤   free(plugin->szOutput);
15de15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   plugin->szOutput = NULL;
a2af5a
23aa9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetReplyText(szText);
96db3c ¤   ¤   ¤   ¤   ¤   ¤   }
0900eb ¤   ¤   ¤   ¤   ¤   ¤   break;
381c89 ¤   ¤   ¤   ¤   ¤   }
ffaf5a
e3842b ¤   ¤   ¤   ¤   case IDC_NEXT:
72ae4e ¤   ¤   ¤   ¤   case IDC_PREVIOUS:
574427 ¤   ¤   ¤   ¤   case IDC_NEXTUNREADARTICLE:
71515a ¤   ¤   ¤   ¤   case IDC_NEXTUNREADTHREAD:
edb945 ¤   ¤   ¤   ¤   case IDC_NEXTUNREADMESSAGE:
c14859 ¤   ¤   ¤   ¤   ¤   {
d10022 ¤   ¤   ¤   ¤   ¤   ¤   if (plugin->szOutput != NULL)
aa8fec ¤   ¤   ¤   ¤   ¤   ¤   {
f95859 ¤   ¤   ¤   ¤   ¤   ¤   ¤   free(plugin->szOutput);
--d77c 000c4f7ea6040110233 Page 3 of ReadMsgWndProc.cpp
d0de15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   plugin->szOutput = NULL;
edc6fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   DestroyWindow(plugin->hEdit);
40c756 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ShowWindow(plugin->hMessage, SW_SHOW);
a49e4a ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableMenus(hDlg, plugin, TRUE);
1adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
d2af5a
012c5a ¤   ¤   ¤   ¤   ¤   ¤   if (AutoDecrypt(plugin->memoryMgr))
c9f9be ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTimer(hDlg, AUTO_DECRYPT_TIMER, 500, 0);
91af5a
d200eb ¤   ¤   ¤   ¤   ¤   ¤   break;
881c89 ¤   ¤   ¤   ¤   ¤   }
1fa3a6 ¤   ¤   ¤   }
99cdcb ¤   ¤   ¤   break;
660fe4 ¤   ¤   }
bb1b52 ¤   ¤
92c93c ¤   case WM_NOTIFY:
42b555 ¤   ¤   if ((((LPNMHDR) lParam)->code) == TTN_NEEDTEXT)·
745b34 ¤   ¤   {
efb606 ¤   ¤   ¤   int idCtrl;
cbfab6 ¤   ¤   ¤   TOOLTIPTEXT *pText;
8ea7c8 ¤   ¤   ¤   BOOL bTooltip = FALSE;
ff0767 ¤   ¤   ¤   char szText[255];
79af5a
75ef61 ¤   ¤   ¤   idCtrl = ((LPNMHDR) lParam)->idFrom;
34e537 ¤   ¤   ¤   pText = (LPTOOLTIPTEXT) lParam;
b6af5a
83c283 ¤   ¤   ¤   switch (idCtrl)
09f776 ¤   ¤   ¤   {
562c87 ¤   ¤   ¤   case IDC_ENCRYPT_SMIME:
d9950e ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_SMIME_ENCRYPT);
299d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
5bf622 ¤   ¤   ¤   ¤   break;
f7af5a
c0bd0f ¤   ¤   ¤   case IDC_SIGN_SMIME:
b5d7aa ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_SMIME_SIGN);
e39d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
76f622 ¤   ¤   ¤   ¤   break;
9caf5a
7a7875 ¤   ¤   ¤   case IDC_DECRYPT:
75eb46 ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_DECRYPT);
ad9d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
16f622 ¤   ¤   ¤   ¤   break;
20af5a
2b7f19 ¤   ¤   ¤   case IDC_PGPKEYS:
4a422b ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_PGPKEYS);
669d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
e5f622 ¤   ¤   ¤   ¤   break;
83a3a6 ¤   ¤   ¤   }
82af5a
71d894 ¤   ¤   ¤   if (bTooltip)
23f776 ¤   ¤   ¤   {
78f4e9 ¤   ¤   ¤   ¤   strcpy(pText->szText, szText);
e546f1 ¤   ¤   ¤   ¤   return 0;
d1a3a6 ¤   ¤   ¤   }
a90fe4 ¤   ¤   }
952f68 ¤   ¤   break;
529371 ¤   }
54af5a
68e939 ¤   return CommonWndProc(hDlg, msg, wParam, lParam);
40efe6 }
f3af5a
69af5a
d3de95 BOOL DecryptVerifyMessage(HWND hwnd, PluginInfo *plugin)
2fbb36 {
2a8489 ¤   HWND hDocHost;
f0c0ed ¤   HWND hMessage;
076497 ¤   HWND hAttach;
0bb0c3 ¤   HWND hNoteHdr;
8af25a ¤   HWND hTo;
14b86c ¤   HFONT hFont;
88b3f5 ¤   char *szInput;
c418b9 ¤   char *szOutput;
--ad4c 000cd6c0cc640110233 Page 4 of ReadMsgWndProc.cpp
c2c78f ¤   DWORD dwLength;
b42fc4 ¤   PGPSize nOutLength;
bd5bda ¤   RECT rc;
6f28c3 ¤   char szExe[256];
906896 ¤   char szDll[256];
ac8fe8 ¤   PGPError nError = kPGPError_NoErr;
2f414d ¤   BOOL FYEO;
0567c5 ¤
fca134 ¤   UIGetString(szExe, sizeof(szExe), IDS_EXE);
7be98b ¤   UIGetString(szDll, sizeof(szDll), IDS_DLL);
f1af5a
00921e ¤   hDocHost = FindWindowEx(hwnd, NULL, "Ath_DocHost", NULL);
9c3ee9 ¤   hMessage = FindWindowEx(hDocHost, NULL, "Internet Explorer_Server", NULL);
923418 ¤   plugin->hMessage = hMessage;
af67c5 ¤
388b2c ¤   hAttach = FindWindowEx(hwnd, NULL, "SysListView32", NULL);
fe67c5 ¤
88b4fe ¤   if (plugin->szOutput == NULL)
6ec7a1 ¤   {
e5f66b ¤   ¤   if (!GetMessageText(hwnd, FALSE, &szInput))
de5f1f ¤   ¤   ¤   return FALSE;
40af5a
ce295d ¤   ¤   dwLength = strlen(szInput);
879371 ¤   }
9b0e24 ¤   else
87c7a1 ¤   {
655b51 ¤   ¤   dwLength = GetWindowTextLength(plugin->hEdit);
877262 ¤   ¤   szInput = (char *) calloc(dwLength+1, 1);
0d61bf ¤   ¤   GetWindowText(plugin->hEdit, szInput, dwLength+1);
8e9371 ¤   }
53af5a
2421a3 ¤   FixBadSpaces(szInput);
baaf5a
31c9aa ¤   nError = DecryptVerifyBuffer(UIGetInstance(), hwnd, plugin->pgpContext,·
16dbc9 ¤   ¤   ¤   ¤   plugin->tlsContext, szExe, szDll,
cc7225 ¤   ¤   ¤   ¤   szInput, dwLength, FALSE, (void **) &szOutput, &nOutLength,
26bee2 ¤   ¤   ¤   ¤   &FYEO);
7caf5a
cd48f5 ¤   if (IsntPGPError(nError) && (szOutput != NULL) && (nOutLength > 0))
a4c7a1 ¤   {
2be436 ¤   ¤   if (plugin->szOutput != NULL)
395b34 ¤   ¤   {
ce9b7b ¤   ¤   ¤   free(plugin->szOutput);
abdcc6 ¤   ¤   ¤   plugin->szOutput = NULL;
380fe4 ¤   ¤   }
edaf5a
47b417 ¤   ¤   if(FYEO)
db5b34 ¤   ¤   {
159a4e ¤   ¤   ¤   TempestViewer((void *)plugin->pgpContext,hwnd,
db41aa ¤   ¤   ¤   ¤   szOutput,nOutLength);
02af5a
27fb36 ¤   ¤   ¤   PGPFreeData(szOutput);
f90fe4 ¤   ¤   }
d80e1d ¤   ¤   else
df5b34 ¤   ¤   {
3f0e84 ¤   ¤   ¤   plugin->szOutput = (char *) calloc(dwLength + nOutLength + 1, 1);
de5102 ¤   ¤   ¤   strcpy(plugin->szOutput, szOutput);
6ffb36 ¤   ¤   ¤   PGPFreeData(szOutput);
2eaf5a
368eb8 ¤   ¤   ¤   GetClientRect(plugin->hMessage, &rc);
eb260f ¤   ¤   ¤   ShowWindow(plugin->hMessage, SW_HIDE);
791b52 ¤   ¤
4e81fc ¤   ¤   ¤   if (plugin->hEdit)
a224b3 ¤   ¤   ¤   ¤   DestroyWindow(plugin->hEdit);
bfaf5a
224c8c ¤   ¤   ¤   plugin->hEdit = CreateWindowEx(WS_EX_CLIENTEDGE,·
2a458e ¤   ¤   ¤   ¤   "EDIT", plugin->szOutput,·
6105b1 ¤   ¤   ¤   ¤   WS_VISIBLE | WS_CHILD |·
a87b6f ¤   ¤   ¤   ¤   WS_VSCROLL |·
b50998 ¤   ¤   ¤   ¤   ES_MULTILINE | ES_WANTRETURN |·
c555c2 ¤   ¤   ¤   ¤   ES_AUTOVSCROLL,
cd7224 ¤   ¤   ¤   ¤   rc.left, rc.top,·
--c7b9 000b024167d40110233 Page 5 of ReadMsgWndProc.cpp
e24bc1 ¤   ¤   ¤   ¤   rc.right - rc.left,·
8c1f86 ¤   ¤   ¤   ¤   rc.bottom - rc.top,
11b9c9 ¤   ¤   ¤   ¤   hDocHost, NULL,·
0924f7 ¤   ¤   ¤   ¤   UIGetInstance(), NULL);
841b52 ¤   ¤
daf199 ¤   ¤   ¤   hFont = (HFONT) GetStockObject(ANSI_VAR_FONT);
6faa73 ¤   ¤   ¤   PostMessage(plugin->hEdit, WM_SETFONT, (WPARAM) hFont,·
16b854 ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
6b1b52 ¤   ¤
ac8a0a ¤   ¤   ¤   hNoteHdr = FindWindowEx(hwnd, NULL, "ATH_NoteHdr", NULL);
3f77e8 ¤   ¤   ¤   hTo = FindWindowEx(hNoteHdr, NULL, "RICHEDIT", NULL);
ad55bf ¤   ¤   ¤   SetFocus(hTo);
cb9d1e ¤   ¤   ¤   SetFocus(plugin->hEdit);
34af5a
b49728 ¤   ¤   ¤   EnableMenus(hwnd, plugin, FALSE);
120fe4 ¤   ¤   }
8a9371 ¤   }
7567c5 ¤
5a20ea ¤   free(szInput);
bfaf5a
4ab8c7 ¤   if (hAttach)
eeac60 ¤   ¤   if (ListView_GetItemCount(hAttach) > 0)
575b34 ¤   ¤   {
7990c1 ¤   ¤   ¤   LV_ITEM lviAttach;
e04f53 ¤   ¤   ¤   char szFileName[MAX_PATH];
1a87c7 ¤   ¤   ¤
afc6fb ¤   ¤   ¤   lviAttach.mask = LVIF_TEXT | LVIF_PARAM;
302a81 ¤   ¤   ¤   lviAttach.iItem = 0;
57404e ¤   ¤   ¤   lviAttach.iSubItem = 0;
5ff8ea ¤   ¤   ¤   lviAttach.pszText = szFileName;
8f2de4 ¤   ¤   ¤   lviAttach.cchTextMax = sizeof(szFileName);
2387c7 ¤   ¤   ¤
3113cc ¤   ¤   ¤   ListView_GetItem(hAttach, &lviAttach);
35bcf5 ¤   ¤   ¤   MessageBox(hwnd, szFileName, "Attachment", MB_OK);
600fe4 ¤   ¤   }
551b52 ¤   ¤
fb2bc9 ¤   return TRUE;¤   ¤
13efe6 }
baaf5a
33af5a
441340 void EnableMenus(HWND hwnd, PluginInfo *plugin, BOOL bEnable)
4fbb36 {
ca3935 ¤   MENUITEMINFO menuInfo;
3311e1 ¤   UINT uFlags = MF_BYPOSITION;
8baf5a
ddc9a4 ¤   menuInfo.cbSize = sizeof(MENUITEMINFO);
fb3f89 ¤   menuInfo.fMask = MIIM_SUBMENU;
afaf5a
7110ca ¤   if (bEnable)
aa4aa7 ¤   ¤   uFlags |= MF_ENABLED;
b70e24 ¤   else
d8efeb ¤   ¤   uFlags |= MF_GRAYED;
7eaf5a
bdbfc9 ¤   GetMenuItemInfo(plugin->hMainMenu, FILE_MENU_POS, TRUE, &menuInfo);
446c4d ¤   EnableMenuItem(menuInfo.hSubMenu, FILESAVEAS_MENU_POS, uFlags);
c19e3f ¤   EnableMenuItem(menuInfo.hSubMenu, FILESTATIONERY_MENU_POS, uFlags);
8e19b7 ¤   EnableMenuItem(menuInfo.hSubMenu, FILEMOVE_MENU_POS, uFlags);
f2eff3 ¤   EnableMenuItem(menuInfo.hSubMenu, FILECOPY_MENU_POS, uFlags);
8f6a12 ¤   EnableMenuItem(menuInfo.hSubMenu, FILEPRINT_MENU_POS, uFlags);
9667c5 ¤
e52f15 ¤   EnableMenuItem(plugin->hMainMenu, EDIT_MENU_POS, uFlags);
cd67c5 ¤
801bbb ¤   GetMenuItemInfo(plugin->hMainMenu, VIEW_MENU_POS, TRUE, &menuInfo);
149c76 ¤   EnableMenuItem(menuInfo.hSubMenu, VIEWFONTS_MENU_POS, uFlags);
f390b9 ¤   EnableMenuItem(menuInfo.hSubMenu, VIEWLANG_MENU_POS, uFlags);
05af5a
af27fe ¤   DrawMenuBar(hwnd);
16af5a
09e3df ¤   SendMessage(plugin->hToolbar, TB_ENABLEBUTTON, IDC_SAVE,
ee0b2b ¤   ¤   MAKELONG(bEnable, 0));
674830 ¤   SendMessage(plugin->hToolbar, TB_ENABLEBUTTON, IDC_PRINT,
b00b2b ¤   ¤   MAKELONG(bEnable, 0));
--86eb 001c4a8146840110233 Page 6 of ReadMsgWndProc.cpp
1cab7b ¤   SendMessage(plugin->hToolbar, TB_ENABLEBUTTON, IDC_COPY,
c00b2b ¤   ¤   MAKELONG(bEnable, 0));
a9af5a
1b830f ¤   return;
93efe6 }
75af5a
9baf5a
a57e4d /*__Editor_settings____
13af5a
714126 ¤   Local Variables:
787b17 ¤   tab-width: 4
560e6c ¤   End:
8a5f8c ¤   vi: ts=4 sw=4
6a9e9b ¤   vim: si
c4d062 _____________________*/
--1aaf 00054ef54f240110234 Page 1 of Recipients.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e306ce ¤   $Id: Recipients.cpp,v 1.11.2.1.2.1 1998/11/12 03:12:47 heller Exp $
77f7f7 ____________________________________________________________________________*/
e0af5a
1f5655 #include <windows.h>
3699a3 #include "wab.h"
34adf9 #include "UIutils.h"
818031 #include "resource.h"
22cd68 #include "Recipients.h"
ab2f8d #include "pgpErrors.h"
0ca076 #include "pgpKeys.h"
8a5ab2 #include "PGPcl.h"
d2af5a
81af5a
1373f4 enum {
54d132 ····ieidPR_DISPLAY_NAME = 0,
f5de51 ····ieidPR_ENTRYID,
c3ee9c ¤   ieidPR_OBJECT_TYPE,
7bd8cc ····ieidMax
0682f7 };
289fd1 static const SizedSPropTagArray(ieidMax, ptaEid)=
70bb36 {
5ed401 ····ieidMax,
683b37 ····{
a46f15 ········PR_DISPLAY_NAME,
c33492 ········PR_ENTRYID,
59a568 ¤   ¤   PR_OBJECT_TYPE,
9e6fe7 ····}
3682f7 };
f9af5a
0eaf5a
d973f4 enum {
122fe6 ····iemailPR_DISPLAY_NAME = 0,
00b812 ····iemailPR_ENTRYID,
ff8738 ····iemailPR_EMAIL_ADDRESS,
1fcb69 ····iemailPR_OBJECT_TYPE,
c9a91a ····iemailMax
c982f7 };
20f82c static const SizedSPropTagArray(iemailMax, ptaEmail)=
fabb36 {
fa67cb ····iemailMax,
5d3b37 ····{
946f15 ········PR_DISPLAY_NAME,
e43492 ········PR_ENTRYID,
497fff ········PR_EMAIL_ADDRESS,
f560a3 ········PR_OBJECT_TYPE
bc6fe7 ····}
fd82f7 };
7baf5a
bf6305 typedef struct _AdrBookTable
c1bb36 {
9f10ee ¤   char *szName;
86a6d4 ¤   char *szEmail;
5272d5 } AdrBookTable;
61af5a
35af5a
fe2d56 BOOL LoadWAB(HINSTANCE *phWAB,·
9603e6 ¤   ¤   ¤   ·LPWABOPEN *ppWABOpen,·
33193c ¤   ¤   ¤   ·LPADRBOOK *ppAdrBook,·
0067a4 ¤   ¤   ¤   ·LPWABOBJECT *ppWABObject);
ddaf5a
3f16d4 BOOL ReadWAB(LPADRBOOK pAdrBook,·
37fbb1 ¤   ¤   ¤   ·LPWABOBJECT pWABObject,·
311916 ¤   ¤   ¤   ·AdrBookTable **ppTable,
4af00c ¤   ¤   ¤   ·UINT *pNumEntries);
f9af5a
545e04 void FreeProws(LPWABOBJECT pWABObject, LPSRowSet prows);
--171f 0008b42432240110234 Page 2 of Recipients.cpp
e0af5a
b2819e void FreeWAB(HINSTANCE hWAB,·
d23bd1 ¤   ¤   ¤   ·LPADRBOOK pAdrBook,·
0d3058 ¤   ¤   ¤   ·LPWABOBJECT pWABObject,
ef2105 ¤   ¤   ¤   ·AdrBookTable *pTable,
a9f20a ¤   ¤   ¤   ·UINT nNumEntries);
18af5a
43af5a
b08529 PGPError GetRecipients(HWND hwnd,
15ddd4 ¤   ¤   ¤   ¤   ¤   ···char *szNames,·
1766f0 ¤   ¤   ¤   ¤   ¤   ···PGPContextRef pgpContext,·
b4deb9 ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,
c8c738 ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds)
b5bb36 {
ec6a62 ····HINSTANCE¤  ¤   hWAB = NULL;
d65b37 ····LPWABOPEN¤  ¤   pWABOpen = NULL;
a02e1b ····LPADRBOOK¤  ¤   pAdrBook = NULL;·
46e84e ····LPWABOBJECT¤¤   pWABObject = NULL;
5d499a ¤   AdrBookTable *¤ pTable = NULL;
439a05 ¤   UINT¤   ¤   ¤   nNumEntries = 0;
c19469 ¤   UINT¤   ¤   ¤   nIndex;
6a5f39 ¤   DWORD¤  ¤   ¤   dwNumRecips = 0;
dcdd10 ¤   BOOL¤   ¤   ¤   bGotRecipients = FALSE;
217f40 ¤   BOOL¤   ¤   ¤   bAddressBook = FALSE;
7d0a85 ¤   char¤   ¤   ¤   szTitle[256];
6bf23f ¤   char *¤ ¤   ¤   szName;
586132 ¤   char *¤ ¤   ¤   szEmail;
e58759 ¤   char *¤ ¤   ¤   szNewRecipient;
7d28fe ¤   char **¤¤   ¤   szOldRecipients;
08d9ac ¤   char **¤¤   ¤   szRecipientArray = NULL;
a04f04 ¤   PGPKeySetRef¤   pubKeySet = NULL;
5c3bb5 ¤   PGPError¤   ¤   err = kPGPError_NoErr;
12af5a
bb7713 ¤   if (LoadWAB(&hWAB, &pWABOpen, &pAdrBook, &pWABObject))
60beb8 ¤   ¤   if (ReadWAB(pAdrBook, pWABObject, &pTable, &nNumEntries))
4bbec7 ¤   ¤   ¤   bAddressBook = TRUE;
cdaf5a
fb4106 ¤   szName = strtok(szNames, ",;");
d0fcf7 ¤   while (szName)
57c7a1 ¤   {
6d53dc ¤   ¤   szEmail = szName;
48af5a
549f99 ¤   ¤   if (bAddressBook)
b45b34 ¤   ¤   {
9044a4 ¤   ¤   ¤   for (nIndex=0; nIndex<nNumEntries; nIndex++)
a4f776 ¤   ¤   ¤   {
34a620 ¤   ¤   ¤   ¤   if ((!_stricmp(szName, pTable[nIndex].szName)) &&
e9e5b0 ¤   ¤   ¤   ¤   ¤   (pTable[nIndex].szEmail != NULL))
7c72c3 ¤   ¤   ¤   ¤   {
7f5eae ¤   ¤   ¤   ¤   ¤   szEmail = pTable[nIndex].szEmail;
e29055 ¤   ¤   ¤   ¤   ¤   nIndex = nNumEntries;
612613 ¤   ¤   ¤   ¤   }
26a3a6 ¤   ¤   ¤   }
570fe4 ¤   ¤   }
0baf5a
9a3aea ¤   ¤   szNewRecipient = (char *) calloc(sizeof(char), strlen(szEmail)+1);
a78429 ¤   ¤   strcpy(szNewRecipient, szEmail);
071b52 ¤   ¤
b2b719 ¤   ¤   szOldRecipients = szRecipientArray;
d9109e ¤   ¤   szRecipientArray = (char **) calloc(sizeof(char *), dwNumRecips+1);
2eaf5a
540d84 ¤   ¤   if (dwNumRecips > 0)
335b34 ¤   ¤   {
691345 ¤   ¤   ¤   UINT i;
8aaf5a
7ed7b0 ¤   ¤   ¤   for (i=0; i<dwNumRecips; i++)
ee1c92 ¤   ¤   ¤   ¤   (szRecipientArray)[i] = szOldRecipients[i];
9f0fe4 ¤   ¤   }
abaf5a
ed89ca ¤   ¤   (szRecipientArray)[dwNumRecips] = szNewRecipient;
1414f8 ¤   ¤   dwNumRecips++;
8b8db3 ¤   ¤   szName = strtok(NULL, ",;");
--1dc5 00049cf572e40110234 Page 3 of Recipients.cpp
a19371 ¤   }
93af5a
782b45 ¤   UIGetString(szTitle, sizeof(szTitle), IDS_RECIPIENTDIALOG);
b2af5a
5dd97c ¤   prds->Version = CurrentPGPrecipVersion;
908cdc ¤   prds->hwndParent = hwnd;
69d315 ¤   prds->szTitle = "Recipient Selection";
86a2a3 ¤   prds->Context = pgpContext;
a6d67c ¤   prds->tlsContext = tlsContext;
f12581 ¤   prds->SelectedKeySetRef = NULL;
4f4236 ¤   prds->szRecipientArray = szRecipientArray;
b5933d ¤   prds->dwNumRecipients = dwNumRecips;
104840 ¤   prds->dwOptions = PGPCL_ASCIIARMOR;
c75127 ¤   prds->dwFlags = 0;
ef0892 ¤   prds->dwDisableFlags = PGPCL_DISABLE_ASCIIARMOR |
d32c3e ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_DISABLE_WIPEORIG;
6a7225 ¤   prds->AddedKeys = NULL;
9baf5a
7e6c5f ¤   // If shift is pressed, force the dialog to pop.
31196e ¤   if (GetAsyncKeyState( VK_SHIFT) & 0x8000)
2eacd2 ¤   ¤   prds->dwDisableFlags|=PGPCL_DISABLE_AUTOMODE;
93af5a
309fbb ¤   bGotRecipients = PGPclRecipientDialog(prds);
31af5a
3d4ff7 ¤   if (prds->AddedKeys != NULL)
71c7a1 ¤   {
b02bca ¤   ¤   PGPUInt32 numKeys;
ceaf5a
21d400 ¤   ¤   PGPCountKeys(prds->AddedKeys, &numKeys);
aff327 ¤   ¤   if (numKeys > 0)
2a99ab ¤   ¤   ¤   PGPclQueryAddKeys(pgpContext, tlsContext, hwnd,·
91a4bd ¤   ¤   ¤   ¤   prds->AddedKeys, NULL);
cfaf5a
264d58 ¤   ¤   PGPFreeKeySet(prds->AddedKeys);
6bdf7b ¤   ¤   prds->AddedKeys = NULL;
bf9371 ¤   }
15af5a
4d5b65 ¤   if (bGotRecipients != TRUE)
15c7a1 ¤   {
ae0fd8 ¤   ¤   err = kPGPError_UserAbort;
5035b8 ¤   ¤   goto GetRecipientsError;
779371 ¤   }
b5af5a
610cb5 ¤   FreeWAB(hWAB, pAdrBook, pWABObject, pTable, nNumEntries);
215ea8 ¤   return err;
8eaf5a
437090 GetRecipientsError:
adaf5a
de6802 ¤   FreeRecipients(prds);
5e0cb5 ¤   FreeWAB(hWAB, pAdrBook, pWABObject, pTable, nNumEntries);
165ea8 ¤   return err;
f1efe6 }
5baf5a
aeaf5a
fc878b void FreeRecipients(RECIPIENTDIALOGSTRUCT *prds)
e5bb36 {
6e5fb5 ¤   DWORD dwIndex;
afaf5a
72d698 ¤   for (dwIndex=0; dwIndex<prds->dwNumRecipients; dwIndex++)
d2c7a1 ¤   {
8805df ¤   ¤   if ((prds->szRecipientArray)[dwIndex] != NULL)
c35b34 ¤   ¤   {
04b05d ¤   ¤   ¤   free((prds->szRecipientArray)[dwIndex]);
644c40 ¤   ¤   ¤   (prds->szRecipientArray)[dwIndex] = NULL;
ad0fe4 ¤   ¤   }
b49371 ¤   }
ffaf5a
086413 ¤   if (prds->SelectedKeySetRef != NULL)
36c7a1 ¤   {
ea591a ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
d0e0d4 ¤   ¤   prds->SelectedKeySetRef = NULL;
499371 ¤   }
--640d 0004df7e40c40110234 Page 4 of Recipients.cpp
2a67c5 ¤
94830f ¤   return;
c0efe6 }
57af5a
90af5a
662d56 BOOL LoadWAB(HINSTANCE *phWAB,·
3b03e6 ¤   ¤   ¤   ·LPWABOPEN *ppWABOpen,·
8b193c ¤   ¤   ¤   ·LPADRBOOK *ppAdrBook,·
97a224 ¤   ¤   ¤   ·LPWABOBJECT *ppWABObject)
e2bb36 {
07eb4a ····HINSTANCE ··hWAB = *phWAB;
20be32 ····LPWABOPEN ··pWABOpen = *ppWABOpen;
81d25d ····LPADRBOOK ··pAdrBook = *ppAdrBook;·
1a5120 ····LPWABOBJECT pWABObject = *ppWABObject;
daaf5a
ee56cc ¤   TCHAR¤  szWABDllPath[MAX_PATH];
15488e ¤   DWORD¤  dwType = 0;
dbd06d ¤   ULONG¤  cbData = sizeof(szWABDllPath);
e8dfdb ¤   HKEY¤   hKey = NULL;
7367c5 ¤
2014f5 ¤   *szWABDllPath = '\0';
f767c5 ¤
965713 ¤   // First we look under the default WAB DLL path location in the
49e2b6 ¤   // Registry.·
bb8968 ¤   // WAB_DLL_PATH_KEY is defined in wabapi.h
68a617 ¤   //
e43065 ¤   if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, ¶
a1fb43 KEY_READ, &hKey))
0c2a33 ¤   ¤   RegQueryValueEx( hKey, "", NULL, &dwType, (LPBYTE) szWABDllPath,·
cbbc1a ¤   ¤   ¤   &cbData);
1067c5 ¤
10699e ¤   if(hKey) RegCloseKey(hKey);
c467c5 ¤
b8be1d ¤   // if the Registry came up blank, we do a loadlibrary on the wab32.dll
899a64 ¤   // WAB_DLL_NAME is defined in wabapi.h
42a617 ¤   //
fd64a6 ¤   hWAB = LoadLibrary((lstrlen(szWABDllPath))·
ca0f73 ¤   ¤   ¤   ¤   ¤   ? szWABDllPath : WAB_DLL_NAME );
aaaf5a
c8cb21 ····if(hWAB)
643b37 ····{
723ee2 ········// if we loaded the dll, get the entry point·
a2717e ········//
aa4045 ········pWABOpen = (LPWABOPEN) GetProcAddress(hWAB, "WABOpen");
f4af5a
ddbadf ········if(pWABOpen)
072b60 ········{
24c005 ············HRESULT hr = E_FAIL;
916213 ············WAB_PARAM wp = {0};
aa785a ············wp.cbSize = sizeof(WAB_PARAM);
d24f57 ············wp.szFileName = "";
fb508e ········
400902 ············// if we choose not to pass in a WAB_PARAM object,·
016ec3 ············// the default WAB file will be opened up
e9f761 ············//
b595ea ············hr = pWABOpen(ppAdrBook,ppWABObject,&wp,0);
fd7fb0 ········}
4d0e1d ¤   ¤   else
9f5f1f ¤   ¤   ¤   return FALSE;
416fe7 ····}
2e0e24 ¤   else
6b98aa ¤   ¤   return FALSE;
78af5a
4dc2e7 ¤   return TRUE;
1cefe6 }
f9af5a
f7af5a
a316d4 BOOL ReadWAB(LPADRBOOK pAdrBook,·
f8fbb1 ¤   ¤   ¤   ·LPWABOBJECT pWABObject,·
b21916 ¤   ¤   ¤   ·AdrBookTable **ppTable,
5a9b87 ¤   ¤   ¤   ·UINT *pNumEntries)
4dbb36 {
--1e2e 00030713df040110234 Page 5 of Recipients.cpp
776662 ····ULONG ulObjType = ··0;
4b4fb2 ¤   LPMAPITABLE lpAB = ·NULL;
b22527 ····LPTSTR * lppszArray=NULL;
dcee37 ····ULONG cRows = ······0;
182924 ····LPSRowSet lpRow = ··NULL;
0aca31 ¤   LPSRowSet lpRowAB = NULL;
4d8385 ····LPABCONT ·lpContainer = NULL;
9fbec5 ¤   int cNumRows = 0;
90fbfc ····int nRows=0;
5c1793 ¤   int nCount = 0;
e8af5a
f38607 ····HRESULT hr = E_FAIL;
1baf5a
a0aa95 ····ULONG lpcbEID;
2d788f ¤   LPENTRYID lpEID = NULL;
2aaf5a
fa4b55 ····// Get the entryid of the root PAB container
265754 ····//
78469b ····hr = pAdrBook->GetPAB( &lpcbEID, &lpEID);
9eaf5a
90f6d8 ¤   ulObjType = 0;
35af5a
e8378f ····// Open the root PAB container
d8e960 ····// This is where all the WAB contents reside
8c5754 ····//
92db64 ····hr = pAdrBook->OpenEntry(lpcbEID,
da06c6 ¤   ¤   ¤   ¤   ¤   ····¤   ¤   (LPENTRYID)lpEID,
78dd58 ¤   ¤   ¤   ¤   ¤   ¤   ····¤   NULL,
f5b390 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····0,
5f775a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····&ulObjType,
b65229 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ····(LPUNKNOWN *)&lpContainer);
afaf5a
fa2da3 ¤   pWABObject->FreeBuffer(lpEID);
bdaf5a
dd95a8 ¤   lpEID = NULL;
a567c5 ¤
84ae46 ····if(HR_FAILED(hr))
da8099 ········goto exit;
23af5a
8d6450 ····// Get a contents table of all the contents in the
1a6b58 ····// WABs root container
ca5754 ····//
112f42 ····hr = lpContainer->GetContentsTable( 0,
945547 ············¤   ¤   ¤   ¤   ¤   ¤   ¤   &lpAB);
45af5a
7dae46 ····if(HR_FAILED(hr))
e38099 ········goto exit;
53af5a
92a640 ····// Order the columns in the ContentsTable to conform to the
b82252 ····// ones we want - which are mainly DisplayName, EntryID and
c55590 ····// ObjectType
f77514 ····// The table is gauranteed to set the columns in the order·
9ae824 ····// requested
ce5754 ····//
65b70e ¤   hr =lpAB->SetColumns( (LPSPropTagArray)&ptaEid, 0 );
9baf5a
b2ae46 ····if(HR_FAILED(hr))
c48099 ········goto exit;
74af5a
6baf5a
bcdd0d ····// Reset to the beginning of the table
645754 ····//
201839 ¤   hr = lpAB->SeekRow( BOOKMARK_BEGINNING, 0, NULL );
f9af5a
daae46 ····if(HR_FAILED(hr))
f88099 ········goto exit;
96af5a
0da47b ····// Read all the rows of the table one by one
cd5754 ····//
be43ab ¤   do {
85af5a
303406 ¤   ¤   hr = lpAB->QueryRows(1,¤0, &lpRowAB);
--a7b7 000363f21f340110234 Page 6 of Recipients.cpp
e0af5a
b0896b ········if(HR_FAILED(hr))
c68632 ············break;
4baf5a
c65d69 ········if(lpRowAB)
172b60 ········{
f497b4 ············cNumRows = lpRowAB->cRows;
4faf5a
47b8a5 ¤   ¤   ····if (cNumRows)
f80be0 ¤   ¤   ····{
b09344 ················LPTSTR szName = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].V¶
6b9d5d alue.lpszA;
044f5d ¤   ¤   ¤   ¤   LPTSTR szEmail = NULL;
f70f2d ················LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_E¶
84807d NTRYID].Value.bin.lpb;
9b6f89 ················ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bi¶
6a4eb6 n.cb;
f6866f ¤   ¤   ¤   ¤   LPMAILUSER pMailUser = NULL;
ec6c3d ¤   ¤   ¤   ¤   ULONG ulObjType = 0;
516794 ¤   ¤   ¤   ¤   ULONG ulValues;
8c090a ¤   ¤   ¤   ¤   LPSPropValue lpPropArray;
70af5a
e0d6df ¤   ¤   ¤   ¤   *ppTable = (AdrBookTable *) realloc(*ppTable,·
40658f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(AdrBookTable) * (nCount+1));
d3af5a
668b4a ¤   ¤   ¤   ¤   (*ppTable)[nCount].szName =·
d78bd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) calloc(strlen(szName)+1, 1);
1ae793 ¤   ¤   ¤   ¤   strcpy((*ppTable)[nCount].szName, szName);
0baf5a
f7ff7f ¤   ¤   ¤   ¤   if (lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l ==·
75ece5 ¤   ¤   ¤   ¤   ¤   MAPI_MAILUSER)
ef72c3 ¤   ¤   ¤   ¤   {
3f690a ¤   ¤   ¤   ¤   ¤   pAdrBook->OpenEntry(cbEID,
8bd86f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lpEID,
e102cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, ········// interface
644772 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, ···········// flags
ce851a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ulObjType,
55cbfb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPUNKNOWN *)&pMailUser);
d4af5a
f9523e ¤   ¤   ¤   ¤   ¤   if(pMailUser)
964859 ¤   ¤   ¤   ¤   ¤   {
02d860 ¤   ¤   ¤   ¤   ¤   ¤   pMailUser->GetProps((LPSPropTagArray) &ptaEmail,·
37044d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
52829f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ulValues,·
4b4bb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &lpPropArray);
ce94aa ¤   ¤   ¤   ¤   ¤   ¤
7ff394 ¤   ¤   ¤   ¤   ¤   ¤   pMailUser->Release();
b91c89 ¤   ¤   ¤   ¤   ¤   }
9cae30 ¤   ¤   ¤   ¤   ¤
13b411 ¤   ¤   ¤   ¤   ¤   szEmail = lpPropArray[iemailPR_EMAIL_ADDRESS].Value.lpszA;
7bae30 ¤   ¤   ¤   ¤   ¤
7114cc ¤   ¤   ¤   ¤   ¤   (*ppTable)[nCount].szEmail =·
808a44 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) calloc(strlen(szEmail)+1, 1);
de6995 ¤   ¤   ¤   ¤   ¤   strcpy((*ppTable)[nCount].szEmail, szEmail);
7967c5 ¤
ade1b6 ¤   ¤   ¤   ¤   ¤   pWABObject->FreeBuffer(lpPropArray);
6c2613 ¤   ¤   ¤   ¤   }
1ffa07 ¤   ¤   ¤   ¤   else
07e78b ¤   ¤   ¤   ¤   ¤   (*ppTable)[nCount].szEmail = NULL;
1e2b85 ¤   ¤   ¤   ¤
1705ae ¤   ¤   ¤   ¤   nCount++;
9e5f30 ¤   ¤   ····}
c572fa ¤   ¤   ····FreeProws(pWABObject, lpRowAB);¤¤
cb7fb0 ········}
f8af5a
151dbf ¤   }while ( SUCCEEDED(hr) && cNumRows && lpRowAB) ·;
d7af5a
40bb53 exit:
22af5a
86fdd2 ¤   if ( lpContainer )
3c7b2f ¤   ¤   lpContainer->Release();
36af5a
--1e17 001120657a240110234 Page 7 of Recipients.cpp
64cc64 ¤   if ( lpAB )
b3b55f ¤   ¤   lpAB->Release();
b7af5a
e695da ¤   *pNumEntries = nCount;
4daf5a
fe09bc ¤   if (SUCCEEDED(hr))
07836c ¤   ¤   return TRUE;
eb0e24 ¤   else
ae98aa ¤   ¤   return FALSE;
74efe6 }
3eaf5a
5eaf5a
bdc19c void FreeProws(LPWABOBJECT pWABObject, LPSRowSet prows)
34bb36 {
e690e2 ¤   ULONG¤  ¤   irow;
740ed5 ¤   if (!prows)
b699bf ¤   ¤   return;
98a3d4 ¤   for (irow = 0; irow < prows->cRows; ++irow)
922559 ¤   ¤   pWABObject->FreeBuffer(prows->aRow[irow].lpProps);
bb78d6 ¤   pWABObject->FreeBuffer(prows);
77efe6 }
97af5a
e0af5a
c8819e void FreeWAB(HINSTANCE hWAB,·
953bd1 ¤   ¤   ¤   ·LPADRBOOK pAdrBook,·
ec3058 ¤   ¤   ¤   ·LPWABOBJECT pWABObject,
f12105 ¤   ¤   ¤   ·AdrBookTable *pTable,
da8da5 ¤   ¤   ¤   ·UINT nNumEntries)
16bb36 {
d4a09f ¤   if (pTable && nNumEntries)
17c7a1 ¤   {
aa10d5 ¤   ¤   for (UINT i=0; i<nNumEntries; i++)
795b34 ¤   ¤   {
d94c8c ¤   ¤   ¤   if (pTable[i].szName)
2b2841 ¤   ¤   ¤   ¤   free(pTable[i].szName);
3daf5a
eb7090 ¤   ¤   ¤   if (pTable[i].szEmail)
f14b7a ¤   ¤   ¤   ¤   free(pTable[i].szEmail);
530fe4 ¤   ¤   }
05af5a
3bfca6 ¤   ¤   free(pTable);
949371 ¤   }
47af5a
4c94fd ¤   if(pAdrBook)
412e57 ¤   ¤   pAdrBook->Release();
1d67c5 ¤
a2424a ¤   if(pWABObject)
a5d607 ¤   ¤   pWABObject->Release();
6467c5 ¤
c6516f ¤   if(hWAB)
75aba6 ¤   ¤   FreeLibrary(hWAB);
5baf5a
c3830f ¤   return;
2eefe6 }
67af5a
daaf5a
217e4d /*__Editor_settings____
70af5a
ad4126 ¤   Local Variables:
797b17 ¤   tab-width: 4
650e6c ¤   End:
c55f8c ¤   vi: ts=4 sw=4
e19e9b ¤   vim: si
12d062 _____________________*/
--4bdf 001502d277740110235 Page 1 of Recipients.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
711ade ¤   $Id: Recipients.h,v 1.4.8.1 1998/11/12 03:12:48 heller Exp $
f3f7f7 ____________________________________________________________________________*/
6177c9 #ifndef Included_Recipients_h¤  /* [ */
e1b0ad #define Included_Recipients_h
2eaf5a
045655 #include <windows.h>
442f8d #include "pgpErrors.h"
0d4919 #include "pgpUtilities.h"
a378f8 #include "pgpcl.h"
8eaf5a
978529 PGPError GetRecipients(HWND hwnd,
41ddd4 ¤   ¤   ¤   ¤   ¤   ···char *szNames,·
9f66f0 ¤   ¤   ¤   ¤   ¤   ···PGPContextRef pgpContext,·
08deb9 ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,
dabd2c ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds);
2faf5a
683a7c void FreeRecipients(RECIPIENTDIALOGSTRUCT *prds);
c0af5a
6781fa #endif /* ] Included_Recipients_h */
33af5a
23af5a
bf7e4d /*__Editor_settings____
96af5a
004126 ¤   Local Variables:
147b17 ¤   tab-width: 4
690e6c ¤   End:
ee5f8c ¤   vi: ts=4 sw=4
a29e9b ¤   vim: si
50d062 _____________________*/
--c679 000267da35d40110236 Page 1 of SendMsgWndProc.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
97b6af ¤   $Id: SendMsgWndProc.cpp,v 1.13.8.1 1998/11/12 03:12:48 heller Exp $
def7f7 ____________________________________________________________________________*/
76af5a
a55655 #include <windows.h>
b190fb #include <commctrl.h>
08390b #include "PluginInfo.h"
0e8d66 #include "HookProcs.h"
23adf9 #include "UIutils.h"
e7f299 #include "TextIO.h"
fecd68 #include "Recipients.h"
ef2f8d #include "pgpErrors.h"
7b9f63 #include "pgpEncode.h"
58fb31 #include "pgpOptionList.h"
fe91b9 #include "pgpSDKPrefs.h"
618031 #include "resource.h"
27b04c #include "EncryptSign.h"
e5af5a
dbf8fe static BOOL EncryptSignMessage(HWND hwnd);
8ad4fe static void DoubleLineFeeds(char *szOriginal, char *szNew);
736650 static void UpdateMenus(HWND hwnd, PluginInfo *plugin);
68af5a
34d5ba typedef struct _AttStruct
febb36 {
a782e0 ¤   char *String0;
1cd83c ¤   char *String1;
79985e ¤   HANDLE hFile0;
2ec282 ¤   HANDLE hFile1;
2ed90c } AttStruct;
16af5a
dfaf5a
04fe0f BOOL CALLBACK SendMsgWndProc(HWND hDlg,·
7b2aaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,
68d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
66a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
7abb36 {
5bc1c0 ¤   DLGPROC lpOldProc;
7f5cc0 ¤   PluginInfo *plugin;
61af5a
bf0955 ¤   lpOldProc = (DLGPROC)GetProp( hDlg, "oldproc" );
da8af7 ¤   plugin = GetPluginInfo(hDlg);
26af5a
189467 ¤   switch(msg)
48c7a1 ¤   {
e4e60b ¤   case WM_TIMER:
071875 ¤   ¤   if (wParam == CORRECT_TOOLBAR_TIMER)
9b5b34 ¤   ¤   {
f90fa3 ¤   ¤   ¤   KillTimer(hDlg, CORRECT_TOOLBAR_TIMER);
adaf5a
a98548 ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_SETBUTTONWIDTH, 0,
a66f53 ¤   ¤   ¤   ¤   MAKELONG(24, 24));
a3e7aa ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_AUTOSIZE, 0, 0);
6199a0 ¤   ¤   ¤   UpdateMenus(hDlg, plugin);
bfaf5a
2e8144 ¤   ¤   ¤   return 0;
3b0fe4 ¤   ¤   }
ca236e ¤   ¤   else if (wParam == PASTE_REPLY_TIMER)
185b34 ¤   ¤   {
48d9d0 ¤   ¤   ¤   char *szText;
5587c7 ¤   ¤   ¤
222e98 ¤   ¤   ¤   // Paste any reply text
0e4992 ¤   ¤   ¤   szText = GetReplyText();
44c6b1 ¤   ¤   ¤   if (szText != NULL)
72f776 ¤   ¤   ¤   {
3121c7 ¤   ¤   ¤   ¤   char *szReplyText;
a4c4ae ¤   ¤   ¤   ¤   char *szReplyHeader;
26af5a
--c143 0001b2da47740110236 Page 2 of SendMsgWndProc.cpp
c259eb ¤   ¤   ¤   ¤   GetMessageText(hDlg, FALSE, &szReplyHeader);
9af6c9 ¤   ¤   ¤   ¤   if (FindReplyHeader(szReplyHeader))
9272c3 ¤   ¤   ¤   ¤   {
8d1963 ¤   ¤   ¤   ¤   ¤   free(szReplyHeader);
d7160e ¤   ¤   ¤   ¤   ¤   GetMessageText(hDlg, TRUE, &szReplyHeader);
6bbf95 ¤   ¤   ¤   ¤   ¤   FindReplyHeader(szReplyHeader);
30e47a ¤   ¤   ¤   ¤   ¤   szReplyText = (char *) calloc(strlen(szReplyHeader) +
4a1f23 ¤   ¤   ¤   ¤   ¤   ¤   strlen(szText) * 2 + 1, 1);
f1ae30 ¤   ¤   ¤   ¤   ¤
ea105d ¤   ¤   ¤   ¤   ¤   strcpy(szReplyText, szReplyHeader);
f3b5cb ¤   ¤   ¤   ¤   ¤   AddReply(szReplyText, szText);
986551 ¤   ¤   ¤   ¤   ¤   SetMessageText(hDlg, szReplyText);
00f280 ¤   ¤   ¤   ¤   ¤   free(szReplyText);
63ca85 ¤   ¤   ¤   ¤   ¤   KillTimer(hDlg, PASTE_REPLY_TIMER);
552613 ¤   ¤   ¤   ¤   }
05fa07 ¤   ¤   ¤   ¤   else
4c72c3 ¤   ¤   ¤   ¤   {
ba1963 ¤   ¤   ¤   ¤   ¤   free(szReplyHeader);
7fcfa5 ¤   ¤   ¤   ¤   ¤   return 0;
982613 ¤   ¤   ¤   ¤   }
e32b85 ¤   ¤   ¤   ¤
f11c8e ¤   ¤   ¤   ¤   free(szReplyHeader);
324963 ¤   ¤   ¤   ¤   FreeReplyText();
87a3a6 ¤   ¤   ¤   }
ccbb8c ¤   ¤   ¤   else
6c9f29 ¤   ¤   ¤   ¤   KillTimer(hDlg, PASTE_REPLY_TIMER);
24af5a
dd8144 ¤   ¤   ¤   return 0;
d50fe4 ¤   ¤   }
302f68 ¤   ¤   break;
23af5a
ce08b5 ¤   case WM_MENUSELECT:
545b34 ¤   ¤   {
2d8f67 ¤   ¤   ¤   UINT uFlags = (UINT) HIWORD(wParam);
f90767 ¤   ¤   ¤   char szText[255];
4fcfda ¤   ¤   ¤   BOOL bPluginMenu = FALSE;
d3af5a
aa0edc ¤   ¤   ¤   if (uFlags & MF_POPUP)
f1f776 ¤   ¤   ¤   {
461e39 ¤   ¤   ¤   ¤   if (LOWORD(wParam) == plugin->nPGPPosition+1)
9c0674 ¤   ¤   ¤   ¤   ¤   UpdateMenus(hDlg, plugin);
5fa3a6 ¤   ¤   ¤   }
0caf5a
b29164 ¤   ¤   ¤   switch(LOWORD(wParam))
06f776 ¤   ¤   ¤   {
ece9d2 ¤   ¤   ¤   ¤   case IDC_ENCRYPT_SMIME:
a172c3 ¤   ¤   ¤   ¤   {
6c6319 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_SMIME_ENCRYPT);
521b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
bc14c3 ¤   ¤   ¤   ¤   ¤   break;
242613 ¤   ¤   ¤   ¤   }
31da4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
b18067 ¤   ¤   ¤   ¤   case IDC_SIGN_SMIME:
1c72c3 ¤   ¤   ¤   ¤   {
015740 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_SMIME_SIGN);
271b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
7814c3 ¤   ¤   ¤   ¤   ¤   break;
f72613 ¤   ¤   ¤   ¤   }
52af5a
e999d5 ¤   ¤   ¤   ¤   case IDC_ENCRYPT_PGP:
b672c3 ¤   ¤   ¤   ¤   {
41c22e ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_PGP_ENCRYPT);
081b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
ee14c3 ¤   ¤   ¤   ¤   ¤   break;
e22613 ¤   ¤   ¤   ¤   }
c9da4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
ab7d71 ¤   ¤   ¤   ¤   case IDC_SIGN_PGP:
8772c3 ¤   ¤   ¤   ¤   {
a6f29d ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_STATUS_PGP_SIGN);
c81b37 ¤   ¤   ¤   ¤   ¤   bPluginMenu = TRUE;
6514c3 ¤   ¤   ¤   ¤   ¤   break;
1b2613 ¤   ¤   ¤   ¤   }
--a912 000cfeba10940110236 Page 3 of SendMsgWndProc.cpp
fc5a2a ¤   ¤   ¤   }¤
23af5a
e7a162 ¤   ¤   ¤   if (bPluginMenu)
c0f776 ¤   ¤   ¤   {
c346c6 ¤   ¤   ¤   ¤   CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
d901cc ¤   ¤   ¤   ¤   SendMessage(plugin->hStatusBar, SB_SETTEXT,·
5277f7 ¤   ¤   ¤   ¤   ¤   255 | SBT_NOBORDERS, (LPARAM) szText);
42af5a
bd46f1 ¤   ¤   ¤   ¤   return 0;
71a3a6 ¤   ¤   ¤   }
fdaf5a
88cdcb ¤   ¤   ¤   break;
9e0fe4 ¤   ¤   }
b5af5a
a28e1e ¤   ¤   case WM_COMMAND:
565b34 ¤   ¤   {
439164 ¤   ¤   ¤   switch(LOWORD(wParam))
a7f776 ¤   ¤   ¤   {
f71339 ¤   ¤   ¤   ¤   case IDC_SENDMESSAGE_MENU:
bf92ac ¤   ¤   ¤   ¤   case IDC_SENDMESSAGE_BUTTON:
4a2a13 ¤   ¤   ¤   ¤   case IDC_SENDLATER:
f10c22 ¤   ¤   ¤   ¤   case IDC_POSTARTICLE_MENU:
070be3 ¤   ¤   ¤   ¤   case IDC_POSTARTICLE_BUTTON:
364cf9 ¤   ¤   ¤   ¤   case IDC_POSTLATER:
3372c3 ¤   ¤   ¤   ¤   {
3073d5 ¤   ¤   ¤   ¤   ¤   if (plugin->bEncrypt || plugin->bSign)
eef2e2 ¤   ¤   ¤   ¤   ¤   ¤   if (!EncryptSignMessage(hDlg))
ea17de ¤   ¤   ¤   ¤   ¤   ¤   ¤   return 0;
32af5a
4b14c3 ¤   ¤   ¤   ¤   ¤   break;
602613 ¤   ¤   ¤   ¤   }
f4af5a
0899d5 ¤   ¤   ¤   ¤   case IDC_ENCRYPT_PGP:
4372c3 ¤   ¤   ¤   ¤   {
48eedd ¤   ¤   ¤   ¤   ¤   MENUITEMINFO menuInfo;
50af5a
059d4e ¤   ¤   ¤   ¤   ¤   menuInfo.cbSize = sizeof(MENUITEMINFO);
477059 ¤   ¤   ¤   ¤   ¤   menuInfo.fMask = MIIM_STATE;
1cf9df ¤   ¤   ¤   ¤   ¤   GetMenuItemInfo(plugin->hToolsMenu, IDC_ENCRYPT_PGP,·
deed26 ¤   ¤   ¤   ¤   ¤   ¤   FALSE, &menuInfo);
bbae30 ¤   ¤   ¤   ¤   ¤
c47576 ¤   ¤   ¤   ¤   ¤   if (menuInfo.fState & MFS_CHECKED)
861a35 ¤   ¤   ¤   ¤   ¤   ¤   plugin->bEncrypt = FALSE;
1d4bd6 ¤   ¤   ¤   ¤   ¤   else
58248a ¤   ¤   ¤   ¤   ¤   ¤   plugin->bEncrypt = TRUE;
4aaf5a
920674 ¤   ¤   ¤   ¤   ¤   UpdateMenus(hDlg, plugin);
dfcfa5 ¤   ¤   ¤   ¤   ¤   return 0;
152613 ¤   ¤   ¤   ¤   }
abaf5a
447d71 ¤   ¤   ¤   ¤   case IDC_SIGN_PGP:
5d72c3 ¤   ¤   ¤   ¤   {
ceeedd ¤   ¤   ¤   ¤   ¤   MENUITEMINFO menuInfo;
96af5a
629d4e ¤   ¤   ¤   ¤   ¤   menuInfo.cbSize = sizeof(MENUITEMINFO);
ef7059 ¤   ¤   ¤   ¤   ¤   menuInfo.fMask = MIIM_STATE;
698ffe ¤   ¤   ¤   ¤   ¤   GetMenuItemInfo(plugin->hToolsMenu, IDC_SIGN_PGP,·
41ed26 ¤   ¤   ¤   ¤   ¤   ¤   FALSE, &menuInfo);
0dae30 ¤   ¤   ¤   ¤   ¤
707576 ¤   ¤   ¤   ¤   ¤   if (menuInfo.fState & MFS_CHECKED)
7fcb03 ¤   ¤   ¤   ¤   ¤   ¤   plugin->bSign = FALSE;
3f4bd6 ¤   ¤   ¤   ¤   ¤   else
dfa72d ¤   ¤   ¤   ¤   ¤   ¤   plugin->bSign = TRUE;
96af5a
080674 ¤   ¤   ¤   ¤   ¤   UpdateMenus(hDlg, plugin);
e5cfa5 ¤   ¤   ¤   ¤   ¤   return 0;
462613 ¤   ¤   ¤   ¤   }
48a3a6 ¤   ¤   ¤   }
22cdcb ¤   ¤   ¤   break;
5a0fe4 ¤   ¤   }
351b52 ¤   ¤
cfc93c ¤   case WM_NOTIFY:
--e8a7 000c52e1a3540110236 Page 4 of SendMsgWndProc.cpp
dbb555 ¤   ¤   if ((((LPNMHDR) lParam)->code) == TTN_NEEDTEXT)·
2c5b34 ¤   ¤   {
e0b606 ¤   ¤   ¤   int idCtrl;
99fab6 ¤   ¤   ¤   TOOLTIPTEXT *pText;
56a7c8 ¤   ¤   ¤   BOOL bTooltip = FALSE;
eb0767 ¤   ¤   ¤   char szText[255];
7baf5a
ffef61 ¤   ¤   ¤   idCtrl = ((LPNMHDR) lParam)->idFrom;
73e537 ¤   ¤   ¤   pText = (LPTOOLTIPTEXT) lParam;
baaf5a
15c283 ¤   ¤   ¤   switch (idCtrl)
6df776 ¤   ¤   ¤   {
6a2c87 ¤   ¤   ¤   case IDC_ENCRYPT_SMIME:
86950e ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_SMIME_ENCRYPT);
419d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
c4f622 ¤   ¤   ¤   ¤   break;
e1af5a
01bd0f ¤   ¤   ¤   case IDC_SIGN_SMIME:
bcd7aa ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_SMIME_SIGN);
739d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
cdf622 ¤   ¤   ¤   ¤   break;
05af5a
3576a6 ¤   ¤   ¤   case IDC_ENCRYPT_PGP:
0d8afa ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_PGP_ENCRYPT);
a79d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
53f622 ¤   ¤   ¤   ¤   break;
9caf5a
01f10e ¤   ¤   ¤   case IDC_SIGN_PGP:
fd1a19 ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_PGP_SIGN);
0d9d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
c4f622 ¤   ¤   ¤   ¤   break;
0caf5a
5a7f19 ¤   ¤   ¤   case IDC_PGPKEYS:
ce422b ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_TOOLTIP_PGPKEYS);
ee9d62 ¤   ¤   ¤   ¤   bTooltip = TRUE;
2ff622 ¤   ¤   ¤   ¤   break;
b5a3a6 ¤   ¤   ¤   }
7daf5a
f0d894 ¤   ¤   ¤   if (bTooltip)
c5f776 ¤   ¤   ¤   {
25f4e9 ¤   ¤   ¤   ¤   strcpy(pText->szText, szText);
7446f1 ¤   ¤   ¤   ¤   return 0;
cca3a6 ¤   ¤   ¤   }
5b0fe4 ¤   ¤   }
a52f68 ¤   ¤   break;
309371 ¤   }
90af5a
56e939 ¤   return CommonWndProc(hDlg, msg, wParam, lParam);
7eefe6 }
0daf5a
d6af5a
e053cf BOOL EncryptSignMessage(HWND hwnd)
30bb36 {
486497 ¤   HWND hAttach;
f7b3f5 ¤   char *szInput;
a618b9 ¤   char *szOutput;
45c78f ¤   DWORD dwLength;
c02fc4 ¤   PGPSize nOutLength;
cd5916 ¤   RECIPIENTDIALOGSTRUCT *prds = NULL;
626030 ¤   PGPOptionListRef signOptions = NULL;
885cc0 ¤   PluginInfo *plugin;
5df0a1 ¤   BOOL bSuccess = FALSE;
2f28c3 ¤   char szExe[256];
e66896 ¤   char szDll[256];
088fe8 ¤   PGPError nError = kPGPError_NoErr;
5f67c5 ¤
c1a134 ¤   UIGetString(szExe, sizeof(szExe), IDS_EXE);
d5e98b ¤   UIGetString(szDll, sizeof(szDll), IDS_DLL);
5e67c5 ¤
aa721f ¤   plugin = GetPluginInfo(hwnd);
54af5a
c58b2c ¤   hAttach = FindWindowEx(hwnd, NULL, "SysListView32", NULL);
--9bbb 000ce886be440110236 Page 5 of SendMsgWndProc.cpp
2a67c5 ¤
83b8c7 ¤   if (hAttach)
2cac60 ¤   ¤   if (ListView_GetItemCount(hAttach) > 0)
ebb38f ¤   ¤   ¤   if (!UIWarnUser(hwnd, IDS_W_ATTACHMENT, "Attachment"))
fcd64b ¤   ¤   ¤   ¤   return FALSE;
93af5a
86d7e3 ¤   prds = (RECIPIENTDIALOGSTRUCT *)·
5c0836 ¤   ¤   ¤   calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);
41af5a
79802c ¤   nError = PGPsdkLoadDefaultPrefs(plugin->pgpContext);
5d0734 ¤   if (IsPGPError(nError))
e1c7a1 ¤   {
c507a6 ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, szDll, nError);
6ebaae ¤   ¤   goto EncryptSignMessageError;
559371 ¤   }
f4af5a
a7fbe0 ¤   nError = PGPOpenDefaultKeyRings(plugin->pgpContext,·
b9f215 ¤   ¤   ¤   ¤   (PGPKeyRingOpenFlags)0, &(prds->OriginalKeySetRef));
3aaf5a
0b0734 ¤   if (IsPGPError(nError))
73c7a1 ¤   {
4007a6 ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, szDll, nError);
91baae ¤   ¤   goto EncryptSignMessageError;
669371 ¤   }
e5af5a
61af87 ¤   if (plugin->bEncrypt)
69c7a1 ¤   {
705b59 ¤   ¤   char *szRecipients;
b7af5a
104f9c ¤   ¤   if (!GetRecipientText(hwnd, &szRecipients))
0e8640 ¤   ¤   ¤   goto EncryptSignMessageError;
77af5a
4e174c ¤   ¤   nError = GetRecipients(hwnd, szRecipients, plugin->pgpContext,·
bc8def ¤   ¤   ¤   ¤   ¤   plugin->tlsContext, prds);
a572dd ¤   ¤   free(szRecipients);
269371 ¤   }
69af5a
610734 ¤   if (IsPGPError(nError))
1bc7a1 ¤   {
f97622 ¤   ¤   if (nError != kPGPError_UserAbort)
84782d ¤   ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, szDll,·
d95c44 ¤   ¤   ¤   ¤   nError);
d5af5a
3e6982 ¤   ¤   goto EncryptSignMessageError;·
629371 ¤   }
7e87c7 ¤   ¤   ¤
1a602a ¤   if (!GetMessageText(hwnd, FALSE, &szInput))
c7baae ¤   ¤   goto EncryptSignMessageError;
18af5a
cca2a1 ¤   dwLength = strlen(szInput);
8121a3 ¤   FixBadSpaces(szInput);
e0af5a
aeb22c ¤   nError = EncryptSignBuffer(UIGetInstance(), hwnd, plugin->pgpContext,·
c3745c ¤   ¤   ¤   ¤   plugin->tlsContext, szExe, szDll, szInput, dwLength, prds,·
f24663 ¤   ¤   ¤   ¤   NULL, &signOptions, (void **) &szOutput, &nOutLength,·
516998 ¤   ¤   ¤   ¤   plugin->bEncrypt, plugin->bSign, FALSE);
6faf5a
4620ea ¤   free(szInput);
5faf5a
7fbc7b ¤   if (IsntPGPError(nError))
cdc7a1 ¤   {
a74af9 ¤   ¤   if (!SetMessageText(hwnd, szOutput))
a3fb36 ¤   ¤   ¤   PGPFreeData(szOutput);
a90e1d ¤   ¤   else
d55b34 ¤   ¤   {
eafb36 ¤   ¤   ¤   PGPFreeData(szOutput);
e85020 ¤   ¤   ¤   plugin->bEncrypt = FALSE;
241524 ¤   ¤   ¤   plugin->bSign = FALSE;
72e542 ¤   ¤   ¤   UpdateMenus(hwnd, plugin);
465c6d ¤   ¤   ¤   bSuccess = TRUE;
ee0fe4 ¤   ¤   }
ce9371 ¤   }
--9260 0005ffcbc4540110236 Page 6 of SendMsgWndProc.cpp
e0af5a
0d7ef2 EncryptSignMessageError:
1eaf5a
77ffc5 ¤   if (signOptions != NULL)
12c7a1 ¤   {
a83020 ¤   ¤   PGPFreeOptionList(signOptions);
648bbc ¤   ¤   signOptions = NULL;
599371 ¤   }
0baf5a
9267c5 ¤
2b5051 ¤   if (prds->OriginalKeySetRef != NULL)
86c7a1 ¤   {
272d6f ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
e309b1 ¤   ¤   prds->OriginalKeySetRef = NULL;
2e9371 ¤   }
d9af5a
8c6802 ¤   FreeRecipients(prds);
1d407b ¤   free(prds);
0aaf5a
8f4ded ¤   return bSuccess;
e9efe6 }
71af5a
95af5a
171f00 void DoubleLineFeeds(char *szOriginal, char *szNew)
64bb36 {
05aaa5 ¤   int nOrigIndex = 0;
556edf ¤   int nNewIndex = 0;
e2b118 ¤   BOOL bCRLF = FALSE;
ffaf5a
1ec9b2 ¤   while (szOriginal[nOrigIndex] != '\0')
d2c7a1 ¤   {
3b4e6c ¤   ¤   szNew[nNewIndex++] = szOriginal[nOrigIndex++];
e97fda ¤   ¤   if (szOriginal[nOrigIndex-1] == '\n')
b75b34 ¤   ¤   {
51f308 ¤   ¤   ¤   if (bCRLF)
acf776 ¤   ¤   ¤   {
809ffc ¤   ¤   ¤   ¤   szNew[nNewIndex++] = '\r';
c5cb69 ¤   ¤   ¤   ¤   szNew[nNewIndex++] = '\n';
f0f9e7 ¤   ¤   ¤   ¤   bCRLF = FALSE;
c3a3a6 ¤   ¤   ¤   }
e4bb8c ¤   ¤   ¤   else
27d82e ¤   ¤   ¤   ¤   bCRLF = TRUE;
b20fe4 ¤   ¤   }
e09371 ¤   }
f1af5a
04229c ¤   szNew[nNewIndex] = '\0';
f5830f ¤   return;
c7efe6 }
08af5a
f3af5a
ad5e35 static void UpdateMenus(HWND hwnd, PluginInfo *plugin)
d8bb36 {
fbaf87 ¤   if (plugin->bEncrypt)
b1c7a1 ¤   {
14ec7c ¤   ¤   CheckMenuItem(plugin->hToolsMenu, IDC_ENCRYPT_PGP,·
7f1f09 ¤   ¤   ¤   MF_BYCOMMAND | MF_CHECKED);
64e9f9 ¤   ¤   SendMessage(plugin->hToolbar, TB_CHECKBUTTON, IDC_ENCRYPT_PGP,
02082d ¤   ¤   ¤   MAKELONG(TRUE, 0));
6a9371 ¤   }
a90e24 ¤   else
00c7a1 ¤   {
8aec7c ¤   ¤   CheckMenuItem(plugin->hToolsMenu, IDC_ENCRYPT_PGP,·
62e36a ¤   ¤   ¤   MF_BYCOMMAND | MF_UNCHECKED);
9ee9f9 ¤   ¤   SendMessage(plugin->hToolbar, TB_CHECKBUTTON, IDC_ENCRYPT_PGP,
5df7ac ¤   ¤   ¤   MAKELONG(FALSE, 0));
ba9371 ¤   }
2b67c5 ¤
cce0f1 ¤   if (plugin->bSign)
e7c7a1 ¤   {
3e8cbb ¤   ¤   CheckMenuItem(plugin->hToolsMenu, IDC_SIGN_PGP,·
e11f09 ¤   ¤   ¤   MF_BYCOMMAND | MF_CHECKED);
5f8b3f ¤   ¤   SendMessage(plugin->hToolbar, TB_CHECKBUTTON, IDC_SIGN_PGP,
--3d98 0010b6a59a940110236 Page 7 of SendMsgWndProc.cpp
3f082d ¤   ¤   ¤   MAKELONG(TRUE, 0));
d29371 ¤   }
460e24 ¤   else
5bc7a1 ¤   {
858cbb ¤   ¤   CheckMenuItem(plugin->hToolsMenu, IDC_SIGN_PGP,·
15e36a ¤   ¤   ¤   MF_BYCOMMAND | MF_UNCHECKED);
628b3f ¤   ¤   SendMessage(plugin->hToolbar, TB_CHECKBUTTON, IDC_SIGN_PGP,
8af7ac ¤   ¤   ¤   MAKELONG(FALSE, 0));
789371 ¤   }
8567c5 ¤
fbefe6 }
0faf5a
91af5a
ef7e4d /*__Editor_settings____
9aaf5a
034126 ¤   Local Variables:
f67b17 ¤   tab-width: 4
090e6c ¤   End:
955f8c ¤   vi: ts=4 sw=4
179e9b ¤   vim: si
0bd062 _____________________*/
--c776 0004818d4c140110237 Page 1 of TextIO.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ffdf2a ¤   $Id: TextIO.cpp,v 1.7.8.1 1998/11/12 03:12:49 heller Exp $
e9f7f7 ____________________________________________________________________________*/
49af5a
5a5655 #include <windows.h>
a32f6f #include <richedit.h>
1a8031 #include "resource.h"
5e390b #include "PluginInfo.h"
e6f299 #include "TextIO.h"
96adf9 #include "UIutils.h"
83af5a
bac172 BOOL CopyRichEditCtrl(HWND hwnd, char **szText);
797d60 BOOL GetNextLine(char *szBuffer, UINT *pnIndex, char *szLine, int nMax);
bfaf5a
f6af5a
bb6d48 BOOL GetRecipientText(HWND hwnd, char **szRecipients)
12bb36 {
c6b0c3 ¤   HWND hNoteHdr;
b85af0 ¤   HWND hTo, hCc, hBcc;
a8cb4b ¤   char *szTo = NULL;
f9c35d ¤   char *szCc = NULL;
8f9eef ¤   char *szBcc = NULL;
9af0a1 ¤   BOOL bSuccess = FALSE;
a5af5a
a72330 ¤   hNoteHdr = FindWindowEx(hwnd, NULL, "ATH_NoteHdr", NULL);
7629f1 ¤   hTo = FindWindowEx(hNoteHdr, NULL, "RICHEDIT", NULL);
477787 ¤   hCc = FindWindowEx(hNoteHdr, hTo, "RICHEDIT", NULL);
adf9e6 ¤   hBcc = FindWindowEx(hNoteHdr, hCc, "RICHEDIT", NULL);
09af5a
3ba835 ¤   if (!CopyRichEditCtrl(hTo, &szTo))
ceb6d3 ¤   ¤   goto GetRecipientTextError;
13af5a
3cce22 ¤   if (!CopyRichEditCtrl(hCc, &szCc))
82b6d3 ¤   ¤   goto GetRecipientTextError;
ffaf5a
4eb54b ¤   if (!CopyRichEditCtrl(hBcc, &szBcc))
f2b6d3 ¤   ¤   goto GetRecipientTextError;
2aaf5a
10f48a ¤   *szRecipients = (char *) calloc(strlen(szTo) +·
fe13c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen(szCc) + strlen(szBcc) + 3, 1);
de67c5 ¤
4c44bd ¤   if (szTo[0] != '\r')
875bf7 ¤   ¤   strcat(*szRecipients, szTo);
f0af5a
5b0a44 ¤   if (szCc[0] != '\r')
7ec7a1 ¤   {
b070e0 ¤   ¤   if (szTo[0] != '\r')
e5b27d ¤   ¤   ¤   strcat(*szRecipients, ",");
baaf5a
6e485f ¤   ¤   strcat(*szRecipients, szCc);
ed9371 ¤   }
4367c5 ¤
b0ad93 ¤   if (szBcc[0] != '\r')
6fc7a1 ¤   {
2c289a ¤   ¤   if ((szTo[0] != '\r') || (szCc[0] != '\r'))
e5b27d ¤   ¤   ¤   strcat(*szRecipients, ",");
e2af5a
ce5405 ¤   ¤   strcat(*szRecipients, szBcc);
1b9371 ¤   }
68af5a
8bd9e1 ¤   bSuccess = TRUE;
07af5a
f25968 GetRecipientTextError:
82af5a
33411e ¤   if (szTo != NULL)
aade7a ¤   ¤   free(szTo);
48af5a
--1173 00073be4c1c40110237 Page 2 of TextIO.cpp
f134a1 ¤   if (szCc != NULL)
dbcdd2 ¤   ¤   free(szCc);
d9af5a
b7c271 ¤   if (szBcc != NULL)
740b6d ¤   ¤   free(szBcc);
94af5a
f84ded ¤   return bSuccess;
d3efe6 }
4aaf5a
2daf5a
7872fd BOOL GetMessageText(HWND hwnd, BOOL bCut, char **szMessage)
54bb36 {
5a8489 ¤   HWND hDocHost;
81c0ed ¤   HWND hMessage;
2a2026 ¤   HANDLE hText;
1ae876 ¤   char *szText = NULL;
b9b42f ¤   char *szOldText = NULL;
28d6b7 ¤   BOOL bSuccess = TRUE;
8aaf5a
dfdbd5 ¤   OpenClipboard(hwnd);
12127d ¤   hText = GetClipboardData(CF_TEXT);
f5e48e ¤   szText = (char *) GlobalLock(hText);
5caf5a
129d8a ¤   if (szText != NULL)
46c7a1 ¤   {
5883d8 ¤   ¤   szOldText = (char *) calloc(strlen(szText)+1, 1);
b77b29 ¤   ¤   strcpy(szOldText, szText);
1d9371 ¤   }
97af5a
dbf432 ¤   GlobalUnlock(hText);
139ed4 ¤   CloseClipboard();
54af5a
0c921e ¤   hDocHost = FindWindowEx(hwnd, NULL, "Ath_DocHost", NULL);
ea3ee9 ¤   hMessage = FindWindowEx(hDocHost, NULL, "Internet Explorer_Server", NULL);
2daf5a
5f2d85 ¤   SetFocus(hDocHost);
2008e3 ¤   SetFocus(hMessage);
1e22c7 ¤   SendMessage(hwnd, WM_COMMAND,·
35891c ¤   ¤   MAKEWPARAM(IDC_SELECTALL, 0), (LPARAM) hMessage);
45af5a
55758b ¤   if (bCut)
95c7a1 ¤   {
9a6334 ¤   ¤   SendMessage(hwnd, WM_COMMAND,·
65203c ¤   ¤   ¤   MAKEWPARAM(IDC_CUT, 0), (LPARAM) hMessage);
849371 ¤   }
4d0e24 ¤   else
3bc7a1 ¤   {
e66334 ¤   ¤   SendMessage(hwnd, WM_COMMAND,·
071c4e ¤   ¤   ¤   MAKEWPARAM(IDC_COPY, 0), (LPARAM) hMessage);
e29371 ¤   }
c667c5 ¤
42dbd5 ¤   OpenClipboard(hwnd);
f9127d ¤   hText = GetClipboardData(CF_TEXT);
2ae48e ¤   szText = (char *) GlobalLock(hText);
de2231 ¤   if (szText == NULL)
f6c7a1 ¤   {
91c06f ¤   ¤   GlobalUnlock(hText);
2f00a8 ¤   ¤   bSuccess = FALSE;
6c2498 ¤   ¤   goto GetMessageTextError;
069371 ¤   }
9daf5a
3b6982 ¤   if (strlen(szText) >= 65535)
c0c7a1 ¤   {
a48a37 ¤   ¤   OSVERSIONINFO osvi;
88af5a
599c8d ¤   ¤   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
e7f213 ¤   ¤   GetVersionEx(&osvi);
0865e0 ¤   ¤   if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
645b34 ¤   ¤   {
dc8c18 ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_BUFFERTOOBIG);
facaa4 ¤   ¤   ¤   if (bCut)
73f776 ¤   ¤   ¤   {
--6313 000e096e82b40110237 Page 3 of TextIO.cpp
85fce0 ¤   ¤   ¤   ¤   SendMessage(hwnd, WM_COMMAND,·
348cc8 ¤   ¤   ¤   ¤   ¤   MAKEWPARAM(IDC_UNDO, 0), (LPARAM) hMessage);
36a3a6 ¤   ¤   ¤   }
ef87c7 ¤   ¤   ¤
5589fc ¤   ¤   ¤   bSuccess = FALSE;
e00fe4 ¤   ¤   }
859371 ¤   }
efaf5a
82a153 ¤   if (bSuccess == TRUE)
8fc7a1 ¤   {
9613d7 ¤   ¤   *szMessage = (char *) calloc(strlen(szText)+1, 1);
711972 ¤   ¤   strcpy(*szMessage, szText);
b19371 ¤   }
f0af5a
28f432 ¤   GlobalUnlock(hText);
6bf56e ¤   EmptyClipboard();
27af5a
eef4c4 ¤   if (szOldText != NULL)
05c7a1 ¤   {
6c1078 ¤   ¤   hText = GlobalAlloc(GHND | GMEM_DDESHARE, strlen(szOldText)+1);
13e236 ¤   ¤   szText = (char *) GlobalLock(hText);
61282a ¤   ¤   strcpy(szText, szOldText);
6cc06f ¤   ¤   GlobalUnlock(hText);
25af5a
596993 ¤   ¤   if (!SetClipboardData(CF_TEXT, hText))
385b34 ¤   ¤   {
45646f ¤   ¤   ¤   DWORD dwError;
f57db8 ¤   ¤   ¤   char szError[255];
1d87c7 ¤   ¤   ¤
932467 ¤   ¤   ¤   dwError = GetLastError();
559837 ¤   ¤   ¤   wsprintf(szError, "Error %d", dwError);
f8716f ¤   ¤   ¤   MessageBox(hwnd, szError, NULL, MB_ICONEXCLAMATION);
dc89fc ¤   ¤   ¤   bSuccess = FALSE;
4487c7 ¤   ¤   ¤
a2cbeb ¤   ¤   ¤   goto GetMessageTextError;
170fe4 ¤   ¤   }
529371 ¤   }
fbaf5a
80ca93 GetMessageTextError:
44af5a
7a9ed4 ¤   CloseClipboard();
11af5a
84f4c4 ¤   if (szOldText != NULL)
cbcb1e ¤   ¤   free(szOldText);
17af5a
354ded ¤   return bSuccess;
c6efe6 }
e5af5a
0aaf5a
46b64b BOOL SetMessageText(HWND hwnd, char *szMessage)
1fbb36 {
ac8489 ¤   HWND hDocHost;
30c0ed ¤   HWND hMessage;
c02026 ¤   HANDLE hText;
7ee876 ¤   char *szText = NULL;
4db42f ¤   char *szOldText = NULL;
c4d6b7 ¤   BOOL bSuccess = TRUE;
5867c5 ¤
5b173d ¤   if (strlen(szMessage) >= 65535)
aac7a1 ¤   {
2c8a37 ¤   ¤   OSVERSIONINFO osvi;
35af5a
6b9c8d ¤   ¤   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
06f213 ¤   ¤   GetVersionEx(&osvi);
8865e0 ¤   ¤   if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
c45b34 ¤   ¤   {
a48c18 ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_BUFFERTOOBIG);
fb89fc ¤   ¤   ¤   bSuccess = FALSE;
1378a8 ¤   ¤   ¤   goto SetMessageTextError;
da0fe4 ¤   ¤   }
439371 ¤   }
e0af5a
--eb6b 0006896c2a140110237 Page 4 of TextIO.cpp
8d921e ¤   hDocHost = FindWindowEx(hwnd, NULL, "Ath_DocHost", NULL);
e23ee9 ¤   hMessage = FindWindowEx(hDocHost, NULL, "Internet Explorer_Server", NULL);
d767c5 ¤
76dbd5 ¤   OpenClipboard(hwnd);
54127d ¤   hText = GetClipboardData(CF_TEXT);
17e48e ¤   szText = (char *) GlobalLock(hText);
6baf5a
fc9d8a ¤   if (szText != NULL)
47c7a1 ¤   {
6a83d8 ¤   ¤   szOldText = (char *) calloc(strlen(szText)+1, 1);
a87b29 ¤   ¤   strcpy(szOldText, szText);
be9371 ¤   }
e9af5a
acf432 ¤   GlobalUnlock(hText);
bbf56e ¤   EmptyClipboard();
13af5a
f89c3c ¤   hText = GlobalAlloc(GHND | GMEM_DDESHARE, strlen(szMessage)+1);
7fe48e ¤   szText = (char *) GlobalLock(hText);
8c9d8a ¤   if (szText != NULL)
e5c7a1 ¤   {
d930b4 ¤   ¤   strcpy(szText, szMessage);
90c06f ¤   ¤   GlobalUnlock(hText);
e71b52 ¤   ¤
686993 ¤   ¤   if (!SetClipboardData(CF_TEXT, hText))
705b34 ¤   ¤   {
e7646f ¤   ¤   ¤   DWORD dwError;
4d7db8 ¤   ¤   ¤   char szError[255];
a787c7 ¤   ¤   ¤
942467 ¤   ¤   ¤   dwError = GetLastError();
669837 ¤   ¤   ¤   wsprintf(szError, "Error %d", dwError);
fe716f ¤   ¤   ¤   MessageBox(hwnd, szError, NULL, MB_ICONEXCLAMATION);
4989fc ¤   ¤   ¤   bSuccess = FALSE;
bc87c7 ¤   ¤   ¤
ab78a8 ¤   ¤   ¤   goto SetMessageTextError;
ee0fe4 ¤   ¤   }
679371 ¤   }
0eaf5a
379ed4 ¤   CloseClipboard();
83af5a
fb2d85 ¤   SetFocus(hDocHost);
5308e3 ¤   SetFocus(hMessage);
1022c7 ¤   SendMessage(hwnd, WM_COMMAND,·
b1891c ¤   ¤   MAKEWPARAM(IDC_SELECTALL, 0), (LPARAM) hMessage);
9f22c7 ¤   SendMessage(hwnd, WM_COMMAND,·
9954dd ¤   ¤   MAKEWPARAM(IDC_PASTE, 0), (LPARAM) hMessage);
94af5a
9adbd5 ¤   OpenClipboard(hwnd);
abf56e ¤   EmptyClipboard();
dcaf5a
42f4c4 ¤   if (szOldText != NULL)
33c7a1 ¤   {
841078 ¤   ¤   hText = GlobalAlloc(GHND | GMEM_DDESHARE, strlen(szOldText)+1);
d6e236 ¤   ¤   szText = (char *) GlobalLock(hText);
e5282a ¤   ¤   strcpy(szText, szOldText);
3ec06f ¤   ¤   GlobalUnlock(hText);
381b52 ¤   ¤
996993 ¤   ¤   if (!SetClipboardData(CF_TEXT, hText))
455b34 ¤   ¤   {
2c646f ¤   ¤   ¤   DWORD dwError;
2e7db8 ¤   ¤   ¤   char szError[255];
6b87c7 ¤   ¤   ¤
462467 ¤   ¤   ¤   dwError = GetLastError();
3c9837 ¤   ¤   ¤   wsprintf(szError, "Error %d", dwError);
f7716f ¤   ¤   ¤   MessageBox(hwnd, szError, NULL, MB_ICONEXCLAMATION);
6289fc ¤   ¤   ¤   bSuccess = FALSE;
2287c7 ¤   ¤   ¤
b078a8 ¤   ¤   ¤   goto SetMessageTextError;
4f0fe4 ¤   ¤   }
eb9371 ¤   }
27af5a
bc79d0 SetMessageTextError:
689ed4 ¤   CloseClipboard();
--5285 000736dcf8d40110237 Page 5 of TextIO.cpp
e0af5a
7ef4c4 ¤   if (szOldText != NULL)
d4cb1e ¤   ¤   free(szOldText);
b1af5a
634ded ¤   return bSuccess;
31efe6 }
3aaf5a
d2af5a
b366b7 BOOL CopyRichEditCtrl(HWND hwnd, char **szText)
7dbb36 {
d91bda ¤   CHARRANGE chRange;
0e2026 ¤   HANDLE hText;
93ead8 ¤   char *szLocalText = NULL;
29b42f ¤   char *szOldText = NULL;
bef0a1 ¤   BOOL bSuccess = FALSE;
e6af5a
53dbd5 ¤   OpenClipboard(hwnd);
d8127d ¤   hText = GetClipboardData(CF_TEXT);
0f8aba ¤   szLocalText = (char *) GlobalLock(hText);
3eaf5a
ad84b1 ¤   if (szLocalText != NULL)
78c7a1 ¤   {
75e101 ¤   ¤   szOldText = (char *) calloc(strlen(szLocalText)+1, 1);
c31151 ¤   ¤   strcpy(szOldText, szLocalText);
4e9371 ¤   }
a1af5a
b4f432 ¤   GlobalUnlock(hText);
2b9ed4 ¤   CloseClipboard();
e1af5a
53dd26 ¤   chRange.cpMin = 0;
43469e ¤   chRange.cpMax = -1;
f0399c ¤   SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) &chRange);
5f4fa7 ¤   SendMessage(hwnd, WM_COPY, 0, 0);
ac67c5 ¤
23dbd5 ¤   OpenClipboard(hwnd);
a2127d ¤   hText = GetClipboardData(CF_TEXT);
cb8aba ¤   szLocalText = (char *) GlobalLock(hText);
34af5a
ac84b1 ¤   if (szLocalText != NULL)
46c7a1 ¤   {
e2b523 ¤   ¤   *szText = (char *) calloc(strlen(szLocalText)+1, 1);
2541b8 ¤   ¤   strcpy(*szText, szLocalText);
fd9371 ¤   }
d6af5a
52f432 ¤   GlobalUnlock(hText);
75f56e ¤   EmptyClipboard();
eaaf5a
29f4c4 ¤   if (szOldText != NULL)
e8c7a1 ¤   {
ed1078 ¤   ¤   hText = GlobalAlloc(GHND | GMEM_DDESHARE, strlen(szOldText)+1);
d2c584 ¤   ¤   szLocalText = (char *) GlobalLock(hText);
38b25d ¤   ¤   strcpy(szLocalText, szOldText);
e2c06f ¤   ¤   GlobalUnlock(hText);
c11b52 ¤   ¤
f56993 ¤   ¤   if (!SetClipboardData(CF_TEXT, hText))
c15b34 ¤   ¤   {
f0646f ¤   ¤   ¤   DWORD dwError;
c47db8 ¤   ¤   ¤   char szError[255];
a687c7 ¤   ¤   ¤
1f2467 ¤   ¤   ¤   dwError = GetLastError();
9a9837 ¤   ¤   ¤   wsprintf(szError, "Error %d", dwError);
04716f ¤   ¤   ¤   MessageBox(hwnd, szError, NULL, MB_ICONEXCLAMATION);
da87c7 ¤   ¤   ¤
98ed84 ¤   ¤   ¤   goto CopyRichEditCtrlError;
c90fe4 ¤   ¤   }
829371 ¤   }
27af5a
d1d9e1 ¤   bSuccess = TRUE;
a5af5a
68c76a CopyRichEditCtrlError:
fdaf5a
739ed4 ¤   CloseClipboard();
--3be4 00016ceacfb40110237 Page 6 of TextIO.cpp
e0af5a
7ef4c4 ¤   if (szOldText != NULL)
d4cb1e ¤   ¤   free(szOldText);
b1af5a
634ded ¤   return bSuccess;
31efe6 }
3aaf5a
d2af5a
317e56 BOOL FindReplyHeader(char *szReplyHeader)
9ebb36 {
a6ab53 ¤   char szLine[1024];
9a1cfe ¤   UINT nIndex;
fdbc2e ¤   int nStop;
c8331a ¤   BOOL bEnd = FALSE;
23af5a
344f5d ¤   nIndex = 0;
b8cfa1 ¤   do
a8c7a1 ¤   {
78d291 ¤   ¤   bEnd = GetNextLine(szReplyHeader, &nIndex, szLine, 1023);
f84d87 ¤   ¤   if (bEnd)
68cdcb ¤   ¤   ¤   break;
d7af5a
741362 ¤   ¤   szLine[5] = '\0';
c69371 ¤   }
2542da ¤   while (strcmp(szLine, "Date:"));
0faf5a
89c832 ¤   if (bEnd)
1a98aa ¤   ¤   return FALSE;
a9af5a
cccfa1 ¤   do
60c7a1 ¤   {
4071eb ¤   ¤   nStop = nIndex;
61d291 ¤   ¤   bEnd = GetNextLine(szReplyHeader, &nIndex, szLine, 1023);
324d87 ¤   ¤   if (bEnd)
03cdcb ¤   ¤   ¤   break;
059371 ¤   }
4ff9fb ¤   while (szLine[0] != '\r');
69af5a
cbc832 ¤   if (bEnd)
b198aa ¤   ¤   return FALSE;
e8af5a
337f28 ¤   szReplyHeader[nStop] = 0;
18c2e7 ¤   return TRUE;
0befe6 }
87af5a
50af5a
95c1dc void AddReply(char *szHeader, char *szReply)
c2bb36 {
28ab53 ¤   char szLine[1024];
08866a ¤   UINT nIndex = 0;
bfaf5a
c0f0d4 ¤   strcat(szHeader, "\r\n\r\n");
63af5a
beb2de ¤   while (!GetNextLine(szReply, &nIndex, szLine, 1023))
2ac7a1 ¤   {
2641ae ¤   ¤   strcat(szHeader, ">");
dc5d7c ¤   ¤   strcat(szHeader, szLine);
359371 ¤   }
0baf5a
ce830f ¤   return;
35efe6 }
42af5a
b2af5a
d4b79e BOOL GetNextLine(char *szBuffer, UINT *pnIndex, char *szLine, int nMax)
3ebb36 {
d2125d ¤   char cCopy;
936f4e ¤   int nLength;
feaf5a
163968 ¤   if (*pnIndex > strlen(szBuffer))
73836c ¤   ¤   return TRUE;
8faf5a
16967c ¤   nLength = 0;
--bc82 0018b9021e140110237 Page 7 of TextIO.cpp
98cfa1 ¤   do
59c7a1 ¤   {
720d96 ¤   ¤   cCopy = szBuffer[(*pnIndex)++];
a5fbc1 ¤   ¤   szLine[nLength] = cCopy;
869371 ¤   }
8e66f1 ¤   while ((cCopy != '\n') && (cCopy != 0) && (nLength++ < nMax));
d9af5a
862cd1 ¤   szLine[nLength] = 0;
8aa230 ¤   return FALSE;
44efe6 }
52af5a
d2af5a
ac7643 void FixBadSpaces(char *szInput)
21bb36 {
0d88a3 ¤   int nIndex = 0;
726f4e ¤   int nLength;
d1af5a
3461d9 ¤   if (szInput == NULL)
7899bf ¤   ¤   return;
7caf5a
c2f9b8 ¤   nLength = strlen(szInput);
54b65a ¤   while (nIndex <= nLength)
69c7a1 ¤   {
2a6be4 ¤   ¤   if (szInput[nIndex] == (char) 0xa0)
9f3ab9 ¤   ¤   ¤   szInput[nIndex] = 0x20;
4daf5a
96ed07 ¤   ¤   nIndex++;
189371 ¤   }
ebaf5a
7c830f ¤   return;
2cefe6 }
46af5a
76af5a
8f7e4d /*__Editor_settings____
08af5a
2a4126 ¤   Local Variables:
927b17 ¤   tab-width: 4
b50e6c ¤   End:
825f8c ¤   vi: ts=4 sw=4
6c9e9b ¤   vim: si
8bd062 _____________________*/
--fb66 0011bfaef0d40110238 Page 1 of TextIO.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
2df90e ¤   $Id: TextIO.h,v 1.2.12.1 1998/11/12 03:12:50 heller Exp $
e9f7f7 ____________________________________________________________________________*/
cd1740 #ifndef Included_TextIO_h¤  /* [ */
80b3cc #define Included_TextIO_h
1caf5a
895655 #include <windows.h>
dcaf5a
c0ce01 BOOL GetRecipientText(HWND hwnd, char **szRecipients);
6a2c38 BOOL GetMessageText(HWND hwnd, BOOL bCut, char **szMessage);
42fc41 BOOL SetMessageText(HWND hwnd, char *szMessage);
9f37ed BOOL FindReplyHeader(char *szReplyHeader);
ea1c00 void AddReply(char *szHeader, char *szReply);
4870c9 void FixBadSpaces(char *szInput);
f0af5a
c0d690 #endif /* ] Included_TextIO_h */
9caf5a
7aaf5a
807e4d /*__Editor_settings____
46af5a
5e4126 ¤   Local Variables:
9b7b17 ¤   tab-width: 4
2e0e6c ¤   End:
d25f8c ¤   vi: ts=4 sw=4
9d9e9b ¤   vim: si
1bd062 _____________________*/
--74a2 0007086641140110239 Page 1 of UIutils.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
305bbe ¤   $Id: UIutils.cpp,v 1.4.8.1 1998/11/12 03:12:50 heller Exp $
81f7f7 ____________________________________________________________________________*/
a65655 #include <windows.h>
7490fb #include <commctrl.h>
d4d92d #include <stdarg.h>
22460b #include <crtdbg.h>
dfaf5a
a9a146 #include "pgpDebug.h"
14adf9 #include "UIutils.h"
558031 #include "resource.h"
a1a076 #include "pgpKeys.h"
b25ab2 #include "PGPcl.h"
0caf5a
409f92 #define WARN_BIT¤   ¤   0x0001
4695a9 #define CONTINUE_BIT¤   0x0002
22af5a
45fa7d static HINSTANCE g_hInstance;
98af5a
9300fd typedef struct _HexDumpParam
0ebb36 {
2524ff ¤   char *szText;
986f4e ¤   int nLength;
a90971 } HexDumpParam;
fcaf5a
f3af5a
e7561a BOOL CALLBACK WarnUserDlgProc(HWND hwndDlg,·
aa6983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
025c85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
037d60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
1faf5a
e056a3 BOOL CALLBACK HexDumpDlgProc(HWND hwndDlg,·
a70bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
13d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
27f03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
47af5a
96f43b void DumpText(HWND hList, char *szText, int nLength);
a5af5a
abaf5a
3361c7 HINSTANCE UIGetInstance(void)
abbb36 {
9b734e ¤   return g_hInstance;
dfefe6 }
cfaf5a
7daf5a
9988b0 void UISetInstance(HINSTANCE hInstance)
18bb36 {
993cfe ¤   g_hInstance = hInstance;
51efe6 }
37af5a
ddaf5a
e70b12 void UIGetString(char *szBuffer, size_t nLength, UINT nID)
e6bb36 {
8dd8b4 ¤   LoadString(g_hInstance, nID, szBuffer, nLength);
01830f ¤   return;
d2efe6 }
d8af5a
0aaf5a
9dee88 void UIFormatString(char *szBuffer, size_t nLength, UINT nID, char *szData)
d1bb36 {
2baf7d ¤   char szTemp[1024];
43af5a
fff373 ····LoadString(g_hInstance, nID, szTemp, 1023);
0060d5 ¤   wsprintf(szBuffer, szTemp, szData);
d5830f ¤   return;
ecefe6 }
70af5a
--ea26 000278887ef40110239 Page 2 of UIutils.cpp
e0af5a
83a111 void UIDisplayString(HWND hwnd, char *szBuffer)
28bb36 {
3ad103 ¤   char szTitle[255];
9aaf5a
8a5db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
593fbb ¤   MessageBox(hwnd, szBuffer, szTitle, MB_OK);
9f830f ¤   return;
f3efe6 }
49af5a
92af5a
448ec3 void UIDisplayStringID(HWND hwnd, UINT nID)
7fbb36 {
37d103 ¤   char szTitle[255];
781ecc ¤   char szBuffer[1024];
46af5a
835db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
c589cc ¤   LoadString(g_hInstance, nID, szBuffer, 1023);
fa3fbb ¤   MessageBox(hwnd, szBuffer, szTitle, MB_OK);
54830f ¤   return;
1defe6 }
53af5a
a8af5a
eb6687 BOOL UIAskYesNoStringID(HWND hwnd, UINT nID)
bfbb36 {
a2d103 ¤   char szTitle[255];
dc1ecc ¤   char szBuffer[1024];
6daf5a
055db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
2089cc ¤   LoadString(g_hInstance, nID, szBuffer, 1023);
0467c5 ¤
5159e4 ¤   return MessageBox(hwnd, szBuffer, szTitle, MB_YESNO);
93efe6 }
8daf5a
3eaf5a
84e34d void UIDisplayErrorCode(char *szFile,·
75a4bc ¤   ¤   ¤   ¤   ¤   ¤   int nLine,·
ef7ff0 ¤   ¤   ¤   ¤   ¤   ¤   char *szModule,·
9d74d2 ¤   ¤   ¤   ¤   ¤   ¤   int nCode)
e5bb36 {
09907b ¤   char szErrorMsg[255];
8fd103 ¤   char szTitle[255];
c1af5a
27962d ¤   PGPclEncDecErrorToString(nCode, szErrorMsg, 254);
71af5a
621f29 #ifdef _DEBUG
1e1c4d ¤   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
180851 ¤   _CrtDbgReport(_CRT_ERROR, szFile, nLine, szModule, szErrorMsg);
fb7454 #endif
47af5a
925db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
ba517a ¤   MessageBox(NULL, szErrorMsg, szTitle, MB_ICONEXCLAMATION);
37830f ¤   return;
72efe6 }
0caf5a
22af5a
b58a67 BOOL UIWarnUser(HWND hwnd, UINT nID, char *szRegValue)
77bb36 {
116fcf ¤   HKEY hkey;
cc2cf2 ¤   char szRegKey[255];
a3bdf4 ¤   char szMessage[255];
99ac71 ¤   BOOL bContinue;
157f12 ¤   DWORD dwResult;
9bf00f ¤   DWORD dwDummy;
032d6a ¤   DWORD dwValue;
bb563d ¤   DWORD dwType;
9311df ¤   DWORD dwSize=4;
e4af5a
0a19de ¤   UIGetString(szMessage, 254, nID);
d14b46 ¤   UIGetString(szRegKey, 254, IDS_WARNING_REGKEY);
1baf5a
270e9d ¤   RegCreateKeyEx(HKEY_CURRENT_USER, szRegKey, 0, NULL,·
--b92f 000ffac5de740110239 Page 3 of UIutils.cpp
1fb5c9 ¤   ¤   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDummy);
ccaf5a
0c49b6 ¤   if (RegQueryValueEx(hkey, szRegValue, 0, &dwType, (BYTE *) &dwValue,·
40d793 ¤   ¤   &dwSize) != ERROR_SUCCESS)
d0c7a1 ¤   {
101a04 ¤   ¤   dwValue = TRUE;
008866 ¤   ¤   RegSetValueEx(hkey, szRegValue, 0, REG_DWORD, (BYTE *) &dwValue,·
5a2b50 ¤   ¤   ¤   sizeof(DWORD));
b79371 ¤   }
2767c5 ¤
efd403 ¤   if (dwValue == FALSE)
72836c ¤   ¤   return TRUE;
f5af5a
3b3de4 ¤   dwResult = DialogBoxParam(UIGetInstance(), MAKEINTRESOURCE(IDD_WARN),·
560773 ¤   ¤   ¤   ¤   ¤   hwnd, (DLGPROC) WarnUserDlgProc, (LPARAM) szMessage);
00af5a
f53589 ¤   dwValue = (dwResult & WARN_BIT) == WARN_BIT;
b7ab06 ¤   bContinue = (dwResult & CONTINUE_BIT) == CONTINUE_BIT;
ccaf5a
3d9ed0 ¤   RegSetValueEx(hkey, szRegValue, 0, REG_DWORD, (BYTE *) &dwValue,·
cddd35 ¤   ¤   sizeof(DWORD));
116c72 ¤   RegCloseKey(hkey);
b3af5a
311cde ¤   return bContinue;
f6efe6 }
bdaf5a
b5af5a
8b2908 void PGPDebugMessage(const char *szMessage)
a3bb36 {
d9d103 ¤   char szTitle[255];
1faf5a
7e1f29 #ifdef _DEBUG
991c4d ¤   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
f5c097 ¤   _CrtDbgReport(_CRT_ERROR, NULL, NULL, NULL, szMessage);
f47454 #endif
4aaf5a
c85db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
33a166 ¤   MessageBox(NULL, szMessage, szTitle, MB_ICONEXCLAMATION);
22830f ¤   return;
d5efe6 }
17af5a
54af5a
7cb991 void UIHexDump(HWND hwnd, char *szMessage, int nLength)
4dbb36 {
e9a48d ¤   HexDumpParam lParam;
10af5a
731a75 ¤   lParam.szText = szMessage;
93bcfa ¤   lParam.nLength = nLength;
e0af5a
2fed6b ¤   DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_HEXDUMP), hwnd,·
8d2994 ¤   ¤   (DLGPROC) HexDumpDlgProc, (LPARAM) &lParam);
18af5a
ab830f ¤   return;
4defe6 }
dbaf5a
83af5a
70561a BOOL CALLBACK WarnUserDlgProc(HWND hwndDlg,·
bd6983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
9e5c85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
c1b79e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
d9bb36 {
1c8d02 ¤   BOOL bReturnCode = FALSE;
db7f12 ¤   DWORD dwResult;
6baf5a
63c08d ¤   switch(uMsg)
e6c7a1 ¤   {
4d2940 ¤   case WM_INITDIALOG:
935b34 ¤   ¤   {
289289 ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_WARNING), (char *) lParam);
9dcdcb ¤   ¤   ¤   break;
a30fe4 ¤   ¤   }
ffaf5a
--6a69 000be11861a40110239 Page 4 of UIutils.cpp
fd3fcf ¤   case WM_COMMAND:
da72a4 ¤   ¤   switch (LOWORD(wParam))
b75b34 ¤   ¤   {
9edb23 ¤   ¤   case IDC_YESCONTINUE:
9fc486 ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_NOWARN) == BST_CHECKED)
4b2066 ¤   ¤   ¤   ¤   dwResult = CONTINUE_BIT;
c5bb8c ¤   ¤   ¤   else
63438a ¤   ¤   ¤   ¤   dwResult = CONTINUE_BIT | WARN_BIT;
aaaf5a
952c0c ¤   ¤   ¤   EndDialog(hwndDlg, dwResult);
b30fe0 ¤   ¤   ¤   bReturnCode = TRUE;
32cdcb ¤   ¤   ¤   break;
96af5a
298a8e ¤   ¤   case IDC_NOCONTINUE:
67c486 ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_NOWARN) == BST_CHECKED)
839c9f ¤   ¤   ¤   ¤   dwResult = 0;
2bbb8c ¤   ¤   ¤   else
f66555 ¤   ¤   ¤   ¤   dwResult = WARN_BIT;
a5af5a
e12c0c ¤   ¤   ¤   EndDialog(hwndDlg, dwResult);
810fe0 ¤   ¤   ¤   bReturnCode = TRUE;
a4cdcb ¤   ¤   ¤   break;
d60fe4 ¤   ¤   }
362f68 ¤   ¤   break;
589371 ¤   }
c8af5a
3b48b1 ¤   return(bReturnCode);
06efe6 }
aaaf5a
c2af5a
ed56a3 BOOL CALLBACK HexDumpDlgProc(HWND hwndDlg,·
dd0bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
22d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
d2a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
32bb36 {
f38d02 ¤   BOOL bReturnCode = FALSE;
6b3c96 ¤   HWND hList;
4aaf5a
83a07f ¤   hList = GetDlgItem(hwndDlg, IDC_DUMP);
cbaf5a
7cc08d ¤   switch(uMsg)
2cc7a1 ¤   {
0a2940 ¤   case WM_INITDIALOG:
4b5b34 ¤   ¤   {
c7371c ¤   ¤   ¤   LV_COLUMN lvcText;
fb7969 ¤   ¤   ¤   HexDumpParam *pParam;
97af5a
238613 ¤   ¤   ¤   // Setup the list control columns
44ec7b ¤   ¤   ¤   lvcText.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
14625f ¤   ¤   ¤   lvcText.fmt = LVCFMT_LEFT;
04408f ¤   ¤   ¤   lvcText.cx = 500;
9a3a49 ¤   ¤   ¤   lvcText.pszText = "ASCII";
3817f8 ¤   ¤   ¤   lvcText.iSubItem = -1;
edaa19 ¤   ¤   ¤   ListView_InsertColumn(hList, 0, &lvcText);
6487c7 ¤   ¤   ¤
b9ec7b ¤   ¤   ¤   lvcText.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
fa625f ¤   ¤   ¤   lvcText.fmt = LVCFMT_LEFT;
036885 ¤   ¤   ¤   lvcText.cx = 1400;
3d3cc5 ¤   ¤   ¤   lvcText.pszText = "Hex";
46bc21 ¤   ¤   ¤   lvcText.iSubItem = 1;
8dd4f3 ¤   ¤   ¤   ListView_InsertColumn(hList, 1, &lvcText);
daaf5a
15491d ¤   ¤   ¤   pParam = (HexDumpParam *) lParam;
b7af5a
4c8f66 ¤   ¤   ¤   // Fill list control with text
b94f44 ¤   ¤   ¤   DumpText(hList, pParam->szText, pParam->nLength);
30cdcb ¤   ¤   ¤   break;
0e0fe4 ¤   ¤   }
64af5a
923fcf ¤   case WM_COMMAND:
c372a4 ¤   ¤   switch (LOWORD(wParam))
be5b34 ¤   ¤   {
--5774 000d54aeef840110239 Page 5 of UIutils.cpp
8d3860 ¤   ¤   case IDOK:
92796b ¤   ¤   ¤   EndDialog(hwndDlg, FALSE);
630fe0 ¤   ¤   ¤   bReturnCode = TRUE;
7dcdcb ¤   ¤   ¤   break;
c80fe4 ¤   ¤   }
c62f68 ¤   ¤   break;
299371 ¤   }
7eaf5a
2b48b1 ¤   return(bReturnCode);
88efe6 }
d5af5a
8eaf5a
398cc3 void DumpText(HWND hList, char *szText, int nLength)
d4bb36 {
96a993 ¤   int nX, nY;
45ac24 ¤   int nHexIndex, nAsciiIndex;
8c7349 ¤   int nLimit;
0075b4 ¤   int nLines;
1392d7 ¤   char szHex[241];
68f3d0 ¤   char szAscii[81];
25880a ¤   LV_ITEM¤lviText;
9faf5a
2012de ¤   nLines = 0;
f7af5a
b796f6 ¤   for (nX=0; nX<nLength; nX+=80)
d7c7a1 ¤   {
bac8a2 ¤   ¤   nHexIndex = 0;
02da0a ¤   ¤   nAsciiIndex = 0;
79af5a
6c6d7a ¤   ¤   if ((nX+80) > nLength)
151e81 ¤   ¤   ¤   nLimit = nLength;
ac0e1d ¤   ¤   else
bc8d2e ¤   ¤   ¤   nLimit = nX+80;
1daf5a
62e635 ¤   ¤   for (nY=nX; nY<nLimit; nY++)
895b34 ¤   ¤   {
61049a ¤   ¤   ¤   wsprintf(&(szHex[nHexIndex]), "%02X ", szText[nY]);
fce788 ¤   ¤   ¤   nHexIndex += 3;
afaf5a
a21ef4 ¤   ¤   ¤   if ((szText[nY] > 31) && (szText[nY] < 127))
2a86c8 ¤   ¤   ¤   ¤   wsprintf(&(szAscii[nAsciiIndex]), "%c", szText[nY]);
6bfa34 ¤   ¤   ¤   else if (szText[nY] == '\n')
22f776 ¤   ¤   ¤   {
b1c813 ¤   ¤   ¤   ¤   nX = nY-79;
3750dd ¤   ¤   ¤   ¤   nY = nLimit;
3ba3a6 ¤   ¤   ¤   }
cdbb8c ¤   ¤   ¤   else
38ea2c ¤   ¤   ¤   ¤   wsprintf(&(szAscii[nAsciiIndex]), " ");
a38683 ¤   ¤   ¤   nAsciiIndex++;
ca0fe4 ¤   ¤   }
d91b52 ¤   ¤
c6fcbe ¤   ¤   szHex[nHexIndex] = 0;
7fc52e ¤   ¤   szAscii[nAsciiIndex] = 0;
80af5a
125277 ¤   ¤   lviText.mask = LVIF_TEXT;
348762 ¤   ¤   lviText.pszText = szAscii;
144774 ¤   ¤   lviText.iItem = nLines;
5cad9e ¤   ¤   lviText.iSubItem = 0;
ebeb13 ¤   ¤   ListView_InsertItem(hList, &lviText);
b8af5a
b25277 ¤   ¤   lviText.mask = LVIF_TEXT;
caf2ec ¤   ¤   lviText.pszText = szHex;
564774 ¤   ¤   lviText.iItem = nLines;
00f742 ¤   ¤   lviText.iSubItem = 1;
744b7b ¤   ¤   ListView_SetItem(hList, &lviText);
02af5a
2eadaa ¤   ¤   nLines++;
a19371 ¤   }
06af5a
8d830f ¤   return;
2aefe6 }
d5af5a
--9b61 00154a9f3aa40110239 Page 6 of UIutils.cpp
e0af5a
1aaf5a
dd7e4d /*__Editor_settings____
96af5a
e44126 ¤   Local Variables:
997b17 ¤   tab-width: 4
f90e6c ¤   End:
f75f8c ¤   vi: ts=4 sw=4
8b9e9b ¤   vim: si
54d062 _____________________*/
--c8f4 0013d0d28734011023a Page 1 of UIutils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
550d74 ¤   $Id: UIutils.h,v 1.3.12.1 1998/11/12 03:12:51 heller Exp $
f4f7f7 ____________________________________________________________________________*/
0843f2 #ifndef Included_UIutils_h¤ /* [ */
e23e71 #define Included_UIutils_h
e0af5a
ea5655 #include <windows.h>
08af5a
803379 #ifdef __cplusplus
c86dad extern "C" {
3f7454 #endif
5baf5a
39b2f2 HINSTANCE UIGetInstance(void);
19b523 void UISetInstance(HINSTANCE hInstance);
eb33b8 void UIGetString(char *szBuffer, size_t nLength, UINT nID);
1a088e void UIFormatString(char *szBuffer, size_t nLength, UINT nID, char *szData);
8d0189 void UIDisplayString(HWND hwnd, char *szBuffer);
34f439 void UIDisplayStringID(HWND hwnd, UINT nID);
20f0f1 BOOL UIAskYesNoStringID(HWND hwnd, UINT nID);
468599 void UIHexDump(HWND hwnd, char *szMessage, int nLength);
abe34d void UIDisplayErrorCode(char *szFile,·
71a4bc ¤   ¤   ¤   ¤   ¤   ¤   int nLine,·
227ff0 ¤   ¤   ¤   ¤   ¤   ¤   char *szModule,·
b1f5cb ¤   ¤   ¤   ¤   ¤   ¤   int nCode);
f91713 BOOL UIWarnUser(HWND hwnd, UINT nID, char *szRegValue);
638c41 void PGPDebugMessage(const char *szMessage);
34af5a
de3379 #ifdef __cplusplus
7aefe6 }
b47454 #endif
07af5a
2481bb #endif /* ] Included_utils_h */
4daf5a
1daf5a
5b7e4d /*__Editor_settings____
f4af5a
eb4126 ¤   Local Variables:
837b17 ¤   tab-width: 4
800e6c ¤   End:
815f8c ¤   vi: ts=4 sw=4
419e9b ¤   vim: si
3dd062 _____________________*/
--b7fd 0002e397e0f4011023b Page 1 of UnknownWndProc.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e52172 ¤   $Id: UnknownWndProc.cpp,v 1.7.8.1 1998/11/12 03:12:52 heller Exp $
b1f7f7 ____________________________________________________________________________*/
ceaf5a
785655 #include <windows.h>
c290fb #include <commctrl.h>
81390b #include "PluginInfo.h"
e78d66 #include "HookProcs.h"
1eadf9 #include "UIutils.h"
4af299 #include "TextIO.h"
f6cc89 #include "Prefs.h"
338031 #include "resource.h"
deaf5a
a8af5a
c3ed5d BOOL CALLBACK UnknownWndProc(HWND hDlg,·
e52aaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT msg,
2cd1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
f3a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
02bb36 {
51c1c0 ¤   DLGPROC lpOldProc;
dc5cc0 ¤   PluginInfo *plugin;
873935 ¤   MENUITEMINFO menuInfo;
8ff05f ¤   BOOL bSend = FALSE;
d5af5a
d90955 ¤   lpOldProc = (DLGPROC)GetProp( hDlg, "oldproc" );
a88af7 ¤   plugin = GetPluginInfo(hDlg);
66af5a
f49467 ¤   switch(msg)
f3c7a1 ¤   {
9ba570 ¤   case WM_PARENTNOTIFY:
9d8ae1 ¤   ¤   if (LOWORD(wParam) == WM_CREATE)
935b34 ¤   ¤   {
55ebee ¤   ¤   ¤   HWND hReBar;
6caf49 ¤   ¤   ¤   TBBUTTON tbb[4];
d18831 ¤   ¤   ¤   HIMAGELIST hilToolbar;
dec966 ¤   ¤   ¤   HINSTANCE hInst;
9135f1 ¤   ¤   ¤   int nPGPkeysBMP;
0d3b87 ¤   ¤   ¤   HBITMAP hbmpPGPkeys;
c20767 ¤   ¤   ¤   char szText[255];
9eaf5a
c71a12 ¤   ¤   ¤   plugin->hMainMenu = GetMenu(hDlg);
acc436 ¤   ¤   ¤   hReBar = FindWindowEx(hDlg, NULL, "ReBarWindow32", NULL);
c3901a ¤   ¤   ¤   plugin->hToolbar = FindWindowEx(hReBar, NULL,·
0e7c5c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "ToolbarWindow32", NULL);
204d83 ¤   ¤   ¤   plugin->hStatusBar = FindWindowEx(hDlg, NULL,·
654f1a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "msctls_statusbar32", NULL);
4aaf5a
8d5188 ¤   ¤   ¤   if (!plugin->hMainMenu || !plugin->hToolbar ||·
f90f5b ¤   ¤   ¤   ¤   !plugin->hStatusBar)
a9f622 ¤   ¤   ¤   ¤   break;
4caf5a
02c565 ¤   ¤   ¤   plugin->hEdit = NULL;
74ba69 ¤   ¤   ¤   plugin->szReplyText = NULL;
9fc84e ¤   ¤   ¤   hInst = UIGetInstance();
10af5a
b987db ¤   ¤   ¤   // Subclass the Window
7fc4bd ¤   ¤   ¤   if (GetMenuItemCount(plugin->hMainMenu) == 8)
09f776 ¤   ¤   ¤   {
364d54 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, GWL_WNDPROC, (DWORD)SendMsgWndProc);
fad20c ¤   ¤   ¤   ¤   plugin->nPGPPosition = 5;
e5835d ¤   ¤   ¤   ¤   bSend = TRUE;
baa3a6 ¤   ¤   ¤   }
409b79 ¤   ¤   ¤   else if (GetMenuItemCount(plugin->hMainMenu) == 6)
e2f776 ¤   ¤   ¤   {
e4fcee ¤   ¤   ¤   ¤   SetWindowLong(hDlg, GWL_WNDPROC, (DWORD)ReadMsgWndProc);
1488d0 ¤   ¤   ¤   ¤   plugin->nPGPPosition = 4;
2ea3a6 ¤   ¤   ¤   }
--a847 00003206fdf4011023b Page 2 of UnknownWndProc.cpp
b1bb8c ¤   ¤   ¤   else
89f776 ¤   ¤   ¤   {
6e882a ¤   ¤   ¤   ¤   SetWindowLong(hDlg, GWL_WNDPROC, (DWORD)lpOldProc);
b27e6a ¤   ¤   ¤   ¤   FreePluginInfo(plugin);
64f622 ¤   ¤   ¤   ¤   break;
35a3a6 ¤   ¤   ¤   }
4aaf5a
0b47b5 ¤   ¤   ¤   menuInfo.cbSize = sizeof(MENUITEMINFO);
437036 ¤   ¤   ¤   menuInfo.fMask = MIIM_SUBMENU;
0cf895 ¤   ¤   ¤   GetMenuItemInfo(plugin->hMainMenu, plugin->nPGPPosition,·
670a2a ¤   ¤   ¤   ¤   TRUE, &menuInfo);
ce8c9b ¤   ¤   ¤   plugin->hToolsMenu = menuInfo.hSubMenu;
22af5a
4a411d ¤   ¤   ¤   plugin->hPGPMenu = CreatePopupMenu();
ff16f4 ¤   ¤   ¤   InsertMenu(plugin->hMainMenu, plugin->nPGPPosition,·
dd8e92 ¤   ¤   ¤   ¤   MF_BYPOSITION | MF_STRING | MF_POPUP,·
f34d9e ¤   ¤   ¤   ¤   (UINT) plugin->hPGPMenu, "&PGP");
8daf5a
b71ce5 ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_BUTTONSTRUCTSIZE,
78e07d ¤   ¤   ¤   ¤   (WPARAM) sizeof(TBBUTTON), 0);
f987c7 ¤   ¤   ¤
c76ef4 ¤   ¤   ¤   hilToolbar = (HIMAGELIST) SendMessage(plugin->hToolbar,·
576e0b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TB_GETIMAGELIST, 0, 0);
29af5a
305513 ¤   ¤   ¤   if (bSend)
fff776 ¤   ¤   ¤   {
e4ea32 ¤   ¤   ¤   ¤   int nEncryptBMP;
4fcb7c ¤   ¤   ¤   ¤   int nSignBMP;
c53e61 ¤   ¤   ¤   ¤   HBITMAP hbmpEncrypt;
f53fde ¤   ¤   ¤   ¤   HBITMAP hbmpSign;
09af5a
56cc78 ¤   ¤   ¤   ¤   GetMenuString(plugin->hToolsMenu, ENCRYPT_SMIME_POS,
c2181a ¤   ¤   ¤   ¤   ¤   szText, 254, MF_BYPOSITION);
81af5a
c02428 ¤   ¤   ¤   ¤   if (!strcmp(szText, "&Encrypt"))
7172c3 ¤   ¤   ¤   ¤   {
f559e2 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGP_ENCRYPT);
4a0cd5 ¤   ¤   ¤   ¤   ¤   InsertMenu(plugin->hToolsMenu, ENCRYPT_PGP_POS,·
2ea387 ¤   ¤   ¤   ¤   ¤   ¤   MF_BYPOSITION | MF_STRING, IDC_ENCRYPT_PGP,·
fad71a ¤   ¤   ¤   ¤   ¤   ¤   szText);
f8ae30 ¤   ¤   ¤   ¤   ¤
f84695 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGP_SIGN);
b52657 ¤   ¤   ¤   ¤   ¤   InsertMenu(plugin->hToolsMenu, SIGN_PGP_POS,·
924f77 ¤   ¤   ¤   ¤   ¤   ¤   MF_BYPOSITION | MF_STRING, IDC_SIGN_PGP,·
dfd71a ¤   ¤   ¤   ¤   ¤   ¤   szText);
d4ae30 ¤   ¤   ¤   ¤   ¤
c59d4e ¤   ¤   ¤   ¤   ¤   menuInfo.cbSize = sizeof(MENUITEMINFO);
f9ec61 ¤   ¤   ¤   ¤   ¤   menuInfo.fMask = MIIM_TYPE;
063ba6 ¤   ¤   ¤   ¤   ¤   menuInfo.fType = MFT_STRING;
b3c104 ¤   ¤   ¤   ¤   ¤   menuInfo.dwTypeData = szText;
4cae30 ¤   ¤   ¤   ¤   ¤
8a2a49 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_SMIME_ENCRYPT);
574370 ¤   ¤   ¤   ¤   ¤   SetMenuItemInfo(plugin->hToolsMenu, ENCRYPT_SMIME_POS,·
5fd9b7 ¤   ¤   ¤   ¤   ¤   ¤   TRUE, &menuInfo);
f5ae30 ¤   ¤   ¤   ¤   ¤
ae6a2f ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_SMIME_SIGN);
d52aaa ¤   ¤   ¤   ¤   ¤   SetMenuItemInfo(plugin->hToolsMenu, SIGN_SMIME_POS,·
f9d9b7 ¤   ¤   ¤   ¤   ¤   ¤   TRUE, &menuInfo);
572613 ¤   ¤   ¤   ¤   }
a9fa07 ¤   ¤   ¤   ¤   else
8072c3 ¤   ¤   ¤   ¤   {
9c59e2 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGP_ENCRYPT);
e26fa7 ¤   ¤   ¤   ¤   ¤   AppendMenu(plugin->hToolsMenu, MF_STRING,·
453bf3 ¤   ¤   ¤   ¤   ¤   ¤   IDC_ENCRYPT_PGP, szText);
e7ae30 ¤   ¤   ¤   ¤   ¤
1f4695 ¤   ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGP_SIGN);
4a6fa7 ¤   ¤   ¤   ¤   ¤   AppendMenu(plugin->hToolsMenu, MF_STRING,·
519461 ¤   ¤   ¤   ¤   ¤   ¤   IDC_SIGN_PGP, szText);
462613 ¤   ¤   ¤   ¤   }
b4af5a
12c31e ¤   ¤   ¤   ¤   hbmpEncrypt = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_ENCRYPT));
03383a ¤   ¤   ¤   ¤   nEncryptBMP = ImageList_AddMasked(hilToolbar, hbmpEncrypt,·
--f224 000dd5920c04011023b Page 3 of UnknownWndProc.cpp
fca68b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRANSPARENT_COLOR);·
08a245 ¤   ¤   ¤   ¤   DeleteObject(hbmpEncrypt);
19af5a
046baa ¤   ¤   ¤   ¤   hbmpSign = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIGN));
969b47 ¤   ¤   ¤   ¤   nSignBMP = ImageList_AddMasked(hilToolbar, hbmpSign,·
2aa68b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRANSPARENT_COLOR);·
92f344 ¤   ¤   ¤   ¤   DeleteObject(hbmpSign);
84af5a
a2f414 ¤   ¤   ¤   ¤   tbb[1].iBitmap = nEncryptBMP;
ed1ee8 ¤   ¤   ¤   ¤   tbb[1].idCommand = IDC_ENCRYPT_PGP;
019b5e ¤   ¤   ¤   ¤   tbb[1].fsState = TBSTATE_ENABLED;
d0ff7b ¤   ¤   ¤   ¤   tbb[1].fsStyle = TBSTYLE_CHECK;
45c273 ¤   ¤   ¤   ¤   tbb[1].dwData = 0;
cd85d5 ¤   ¤   ¤   ¤   tbb[1].iString = -1;
65af5a
7d5fce ¤   ¤   ¤   ¤   tbb[2].iBitmap = nSignBMP;
4a3f4c ¤   ¤   ¤   ¤   tbb[2].idCommand = IDC_SIGN_PGP;
e0fa4b ¤   ¤   ¤   ¤   tbb[2].fsState = TBSTATE_ENABLED;
21a548 ¤   ¤   ¤   ¤   tbb[2].fsStyle = TBSTYLE_CHECK;
611a0d ¤   ¤   ¤   ¤   tbb[2].dwData = 0;
4cb5c4 ¤   ¤   ¤   ¤   tbb[2].iString = -1;
e8af5a
b3d749 ¤   ¤   ¤   ¤   plugin->bEncrypt = ByDefaultEncrypt(plugin->memoryMgr);
0bb91b ¤   ¤   ¤   ¤   plugin->bSign = ByDefaultSign(plugin->memoryMgr);
d4af5a
c066a6 ¤   ¤   ¤   ¤   SetTimer(hDlg, PASTE_REPLY_TIMER, 250, 0);
54a3a6 ¤   ¤   ¤   }
54bb8c ¤   ¤   ¤   else
82f776 ¤   ¤   ¤   {
c82d7e ¤   ¤   ¤   ¤   int nDecryptBMP;
5cd4f0 ¤   ¤   ¤   ¤   HBITMAP hbmpDecrypt;
08af5a
d856e4 ¤   ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_DECRYPT);
ee1d5e ¤   ¤   ¤   ¤   AppendMenu(plugin->hPGPMenu, MF_STRING, IDC_DECRYPT,·
7f6c4c ¤   ¤   ¤   ¤   ¤   szText);
76af5a
50b073 ¤   ¤   ¤   ¤   AppendMenu(plugin->hPGPMenu, MF_SEPARATOR, NULL, NULL);
85af5a
bbe38c ¤   ¤   ¤   ¤   hbmpDecrypt = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_DECRYPT));
4dd593 ¤   ¤   ¤   ¤   nDecryptBMP = ImageList_AddMasked(hilToolbar, hbmpDecrypt,·
a8a25b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRANSPARENT_COLOR);
2b27af ¤   ¤   ¤   ¤   DeleteObject(hbmpDecrypt);
95af5a
873358 ¤   ¤   ¤   ¤   tbb[1].iBitmap = nDecryptBMP;
91245f ¤   ¤   ¤   ¤   tbb[1].idCommand = IDC_DECRYPT;
1e9b5e ¤   ¤   ¤   ¤   tbb[1].fsState = TBSTATE_ENABLED;
cade3c ¤   ¤   ¤   ¤   tbb[1].fsStyle = TBSTYLE_BUTTON;
bfc273 ¤   ¤   ¤   ¤   tbb[1].dwData = 0;
4e85d5 ¤   ¤   ¤   ¤   tbb[1].iString = -1;
dcaf5a
54611b ¤   ¤   ¤   ¤   tbb[2].iBitmap = -1;
f0aca4 ¤   ¤   ¤   ¤   tbb[2].idCommand = -1;
577d3e ¤   ¤   ¤   ¤   tbb[2].fsState = TBSTATE_HIDDEN;
db4015 ¤   ¤   ¤   ¤   tbb[2].fsStyle = TBSTYLE_SEP;
5c1a0d ¤   ¤   ¤   ¤   tbb[2].dwData = 0;
4db5c4 ¤   ¤   ¤   ¤   tbb[2].iString = -1;
e5af5a
25f6a1 ¤   ¤   ¤   ¤   if (AutoDecrypt(plugin->memoryMgr))
998aa7 ¤   ¤   ¤   ¤   ¤   SetTimer(hDlg, AUTO_DECRYPT_TIMER, 500, 0);
69a3a6 ¤   ¤   ¤   }
ebaf5a
a48a8e ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_PREFS);
e9a186 ¤   ¤   ¤   AppendMenu(plugin->hPGPMenu, MF_STRING, IDC_PREFS,·
cf5811 ¤   ¤   ¤   ¤   szText);
9eaf5a
3270de ¤   ¤   ¤   UIGetString(szText, 254, IDS_MENU_PGPKEYS);
2ca110 ¤   ¤   ¤   AppendMenu(plugin->hPGPMenu, MF_STRING, IDC_PGPKEYS,·
f45811 ¤   ¤   ¤   ¤   szText);
c2af5a
4829df ¤   ¤   ¤   DrawMenuBar(hDlg);
42af5a
dd6d5b ¤   ¤   ¤   hbmpPGPkeys = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PGPKEYS));
--7cd9 001a773e96b4011023b Page 4 of UnknownWndProc.cpp
f8fd84 ¤   ¤   ¤   nPGPkeysBMP = ImageList_AddMasked(hilToolbar, hbmpPGPkeys,·
37f7f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRANSPARENT_COLOR);
6dc147 ¤   ¤   ¤   DeleteObject(hbmpPGPkeys);
3daf5a
86eb35 ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_SETIMAGELIST, 0,·
81762a ¤   ¤   ¤   ¤   (LPARAM) hilToolbar);
c4af5a
c07c6d ¤   ¤   ¤   tbb[0].iBitmap = -1;
c3c3d4 ¤   ¤   ¤   tbb[0].idCommand = -1;
85f493 ¤   ¤   ¤   tbb[0].fsState = TBSTATE_ENABLED;
c1eb61 ¤   ¤   ¤   tbb[0].fsStyle = TBSTYLE_SEP;
9d0626 ¤   ¤   ¤   tbb[0].dwData = 0;
67a8b2 ¤   ¤   ¤   tbb[0].iString = -1;
dbaf5a
d63bf5 ¤   ¤   ¤   tbb[3].iBitmap = nPGPkeysBMP;
36af4e ¤   ¤   ¤   tbb[3].idCommand = IDC_PGPKEYS;
c89586 ¤   ¤   ¤   tbb[3].fsState = TBSTATE_ENABLED;
4976d2 ¤   ¤   ¤   tbb[3].fsStyle = TBSTYLE_BUTTON;
a3de58 ¤   ¤   ¤   tbb[3].dwData = 0;
1d98a3 ¤   ¤   ¤   tbb[3].iString = -1;
24af5a
9d063d ¤   ¤   ¤   SendMessage(plugin->hToolbar, TB_ADDBUTTONS, 4, (LPARAM) &tbb);
31af5a
585513 ¤   ¤   ¤   if (bSend)
037041 ¤   ¤   ¤   ¤   SetTimer(hDlg, CORRECT_TOOLBAR_TIMER, 250, 0);
a7af5a
52cdcb ¤   ¤   ¤   break;
290fe4 ¤   ¤   }
8aaf5a
926b08 ¤   case WM_DESTROY:
9f5b34 ¤   ¤   {
d2bb3f ¤   ¤   ¤   FreePluginInfo(plugin);
5ecdcb ¤   ¤   ¤   break;
640fe4 ¤   ¤   }
0a9371 ¤   }
ecaf5a
576a22 ¤   return CallWindowProc(lpOldProc, hDlg, msg, wParam, lParam);
f4efe6 }
63af5a
cfaf5a
ba7e4d /*__Editor_settings____
d9af5a
fe4126 ¤   Local Variables:
c97b17 ¤   tab-width: 4
270e6c ¤   End:
2b5f8c ¤   vi: ts=4 sw=4
c89e9b ¤   vim: si
a7d062 _____________________*/
--122f 00016b4a3fd4011023c Page 1 of main.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8daa02 ¤   $Id: main.cpp,v 1.2.12.1 1998/11/12 03:12:52 heller Exp $
90f7f7 ____________________________________________________________________________*/
acaf5a
5e5655 #include <windows.h>
bf8d66 #include "HookProcs.h"
24adf9 #include "UIutils.h"
13af5a
87880c HHOOK g_hHook[10];
e6b380 int g_nNumHooks = 0;
47313a DWORD g_dwThreadID[10];
4eaf5a
5c4a5a UINT WM_PGP_KILL_OELOADER = 0;
abaf5a
956dad extern "C" {
396f1c __declspec(dllexport) void HookOutlookExpressPlugin(DWORD ThreadId);
4982f7 };
3daf5a
c7af5a
c6a989 BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID)
efbb36 {
588fe1 ·¤  if (DLL_PROCESS_ATTACH == fdwReason)
b32e29 ·¤  {
899a4a ¤   ¤   UISetInstance(hinstDll);
12e594 ¤   ¤   WM_PGP_KILL_OELOADER =·
95ff88 ¤   ¤   ¤   RegisterWindowMessage("PGP Kill OE Loader");
3f7af9 ·¤  }
24af5a
0a27d6 ·¤  if (DLL_PROCESS_DETACH == fdwReason)
ec2e29 ·¤  {
da6bbb ¤   ¤   int nIndex;
a73203 ¤   ¤   DWORD dwThreadID;
ddaf5a
866197 ¤   ¤   dwThreadID = GetCurrentThreadId();
231b52 ¤   ¤
9d2c5a ¤   ¤   for (nIndex=0; nIndex<g_nNumHooks; nIndex++)
d35b34 ¤   ¤   {
30cdfa ¤   ¤   ¤   if (g_dwThreadID[nIndex] == dwThreadID)
cff622 ¤   ¤   ¤   ¤   break;
fd0fe4 ¤   ¤   }
37af5a
576336 ¤   ¤   if (nIndex < g_nNumHooks)
1e5b34 ¤   ¤   {
260ead ¤   ¤   ¤   UnhookWindowsHookEx(g_hHook[nIndex]);
941737 ¤   ¤   ¤   g_nNumHooks--;
b3045b ¤   ¤   ¤   for (; nIndex<g_nNumHooks; nIndex++)
a0f776 ¤   ¤   ¤   {
ccac96 ¤   ¤   ¤   ¤   g_dwThreadID[nIndex] == g_dwThreadID[nIndex+1];
4a5141 ¤   ¤   ¤   ¤   g_hHook[nIndex] = g_hHook[nIndex+1];
39a3a6 ¤   ¤   ¤   }
6b0fe4 ¤   ¤   }
00af5a
42411b ¤   ¤   if (!g_nNumHooks)
152531 ¤   ¤   ¤   PostMessage(HWND_BROADCAST, WM_PGP_KILL_OELOADER, 0, 0);
227af9 ·¤  }
f7af5a
25c2e7 ¤   return TRUE;
f1efe6 }
8eaf5a
deaf5a
53dcd2 __declspec(dllexport) void HookOutlookExpressPlugin(DWORD dwThreadId)
f4bb36 {
c9e9e8 ¤   g_hHook[g_nNumHooks] = SetWindowsHookEx(WH_CBT, (HOOKPROC) CBTProc,·
38187b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UIGetInstance(), dwThreadId);
b4537c ¤   g_nNumHooks++;
61830f ¤   return;
16efe6 }
--93a1 00154a9f3aa4011023c Page 2 of main.cpp
e0af5a
1aaf5a
dd7e4d /*__Editor_settings____
96af5a
e44126 ¤   Local Variables:
997b17 ¤   tab-width: 4
f90e6c ¤   End:
f75f8c ¤   vi: ts=4 sw=4
8b9e9b ¤   vim: si
54d062 _____________________*/
--3bd2 0012dc7d4bd4011023d Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
410ea9 // Used by PGP55oe.rc
7f465d //
6e839d #define IDS_TITLE ······················1
acd4a7 #define IDS_E_EXPIRED ··················2
b8b460 #define IDS_STATUS_PGP ·················3
ac0710 #define IDS_STATUS_PREFS ···············4
21e87a #define IDS_STATUS_PGPKEYS ·············5
f13646 #define IDS_LOGNAME ····················6
074317 #define IDS_SIGKEYREVOKED ··············7
f24bdd #define IDS_SIGKEYDISABLED ·············8
b915ac #define IDS_SIGKEYEXPIRED ··············9
908e54 #define IDS_E_NOPGP ····················10
5dd297 #define IDS_E_NOKEYS ···················11
3a7e9c #define IDS_STATUS_SMIME_ENCRYPT ·······12
a1595d #define IDS_STATUS_PGP_ENCRYPT ·········13
b5e20b #define IDS_STATUS_SMIME_SIGN ··········14
1c4ca7 #define IDS_STATUS_PGP_SIGN ············15
34d02b #define IDS_STATUS_DECRYPT ·············16
cf33e3 #define IDS_STATUS_ADDKEYS ·············17
f6841d #define IDB_PGPKEYSLARGE ···············18
0b3014 #define IDS_MENU_PREFS ·················18
783eee #define IDS_MENU_PGPKEYS ···············19
960f2d #define IDS_MENU_SMIME_ENCRYPT ·········20
a08c81 #define IDS_MENU_PGP_ENCRYPT ···········21
9e7db7 #define IDS_MENU_SMIME_SIGN ············22
d732ff #define IDS_MENU_PGP_SIGN ··············23
2621b3 #define IDS_MENU_DECRYPT ···············24
7bf52f #define IDS_MENU_ADDKEYS ···············25
97786f #define IDS_TOOLTIP_PGPKEYS ············26
e920c1 #define IDS_TOOLTIP_SMIME_ENCRYPT ······27
f341c6 #define IDS_TOOLTIP_PGP_ENCRYPT ········28
5781ff #define IDS_TOOLTIP_SMIME_SIGN ·········29
5be3a9 #define IDS_TOOLTIP_PGP_SIGN ···········30
078df2 #define IDS_TOOLTIP_DECRYPT ············31
7850b7 #define IDS_TOOLTIP_ADDKEYS ············32
437e24 #define IDS_WARNING_REGKEY ·············33
b1831b #define IDS_W_ATTACHMENT ···············34
d564e1 #define IDS_E_NOPGPKEYS ················35
d8deba #define IDS_E_BUFFERTOOBIG ·············36
c3c0ab #define IDS_PGPKEYSEXE ·················37
f0d0e6 #define IDS_EXE ························38
86981a #define IDS_DLL ························39
2eca9b #define IDS_RECIPIENTDIALOG ············40
dceca7 #define IDD_WARN ·······················42
b02f31 #define IDD_HEXDUMP ····················101
618b3d #define IDB_DECRYPT ····················501
b288bc #define IDB_ENCRYPT ····················502
427f55 #define IDB_PGPKEYS ····················503
5dd0fb #define IDB_ADDKEYS ····················504
b17ec7 #define IDB_SIGN ·······················505
35347c #define IDB_PGPKEYSOFF ·················506
d04a26 #define IDB_PGPKEYSLARGE4 ··············507
3c5b1c #define IDB_PGPKEYSOFF4 ················508
c1e2ce #define IDC_DUMP ·······················1002
1cfc61 #define IDC_YESCONTINUE ················1031
1782b0 #define IDC_NOCONTINUE ·················1032
9a8fff #define IDC_NOWARN ·····················1033
9ece0d #define IDC_WARNING ····················1034
55af5a
2d11aa // Next default values for new objects
c4ac6a //·
3df860 #ifdef APSTUDIO_INVOKED
1e3f23 #ifndef APSTUDIO_READONLY_SYMBOLS
1601b7 #define _APS_NEXT_RESOURCE_VALUE ·······32
ea611c #define _APS_NEXT_COMMAND_VALUE ········40001
aa918c #define _APS_NEXT_CONTROL_VALUE ········1004
d71285 #define _APS_NEXT_SYMED_VALUE ··········101
a97454 #endif
2d7454 #endif
--eef8 0017dfda6cc4011023e Page 1 of main.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e7291b ¤   $Id: main.c,v 1.1.18.1 1998/11/12 03:12:54 heller Exp $
faf7f7 ____________________________________________________________________________*/
7daf5a
--e00a 001735f6fda4011023f Page 1 of CTXMENU.DEF
b7e8ad LIBRARY ·····PGP60mn
154e98 DESCRIPTION ·'PGP Shell Extension'
41af5a
8def2b EXPORTS
dab50c ····DllCanUnloadNow ············@2 PRIVATE ·········;DLL unloading
8390d0 ····DllGetClassObject ··········@3 PRIVATE ·········;Component object model
73af5a
--c122 0001185e9c340110240 Page 1 of Ctxmenu.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ddff82 ¤   $Id: Ctxmenu.cpp,v 1.21.2.3.2.1 1998/11/12 03:12:55 heller Exp $
5ef7f7 ____________________________________________________________________________*/
3baf5a
26fb02 // ·MODULE: ··ctxmenu.cpp
34465d //
db0781 // ·PURPOSE: ··Implements the IContextMenu member·
a7334f // ············functions necessary to support
1d01d9 // ············the context menu portions of this·
cb9c18 // ············shell extension. ·Context menu
599d97 // ············shell extensions are called when·
72025b // ············the user right clicks on a file
ad2cc6 // ············(of the type registered for the·
bcf86c // ············shell extension--see SHELLEXT.REG
83bb69 // ············for details on the registry entries.
a75333 // ············In this sample, the relevant
2c9c96 // ············files are of type .GAK) in the·
57930c // ············Explorer, or selects the File menu·
fd66de // ············item.
d3465d //
f15ed8 #include "precomp.h"
84af5a
4f88d0 #include <tchar.h>
955655 #include <windows.h>
2d11a9 #include <process.h>
adbb5f #include <assert.h>
5bfeb2 #include <stdio.h>
e8af5a
5cc2cc extern HMENU¤   ¤   hPlaintextMenu;
24e9d5 extern HMENU¤   ¤   hEncryptedMenu;
49d428 extern HMENU¤   ¤   hKeyfileMenu;
699762 extern HINSTANCE¤   g_hmodThisDll; // Handle to this DLL itself.
a36bcd extern void *PGPsc;
c15f33 extern void *PGPtls;
8eaf5a
aa8031 #include "resource.h"
607e4e #include "priv.h"
5e6e17 #include "pgpwctx.hpp"
3fb277 #include "pgpCodes.hpp"
1aaf5a
51f58b #define NONCONCURRENT
37af5a
e4c9d0 HWND g_hwndShell=NULL;
91af5a
199b46 typedef struct _pgpthreadcontrol
e5bb36 {
94c3bf ¤   UINT ActionCode;
4db28d ¤   STGMEDIUM Medium;
94cab3 #ifdef NONCONCURRENT
8aab10 ¤   HANDLE hPGPCTXSemaphore;
3e7454 #endif
c0152a }PGPTHREADCONTROL;
2baf5a
642be8 #define STACK_SIZE 0x8000
b581f2 #define PGPCTX_SEMAPHORE ·"PGP_50_CONTEXT_MENU_SEMAPHORE"
d7af5a
44ae9b void CallPGPThread(void *Arg);
ed66c3 HRESULT CallPGP(STGMEDIUM *pMedium, UINT ActionCode);
deaf5a
dfa863 extern HINSTANCE g_hmodThisDll;
272dfc extern HANDLE hPGPThreadMutex;
15af5a
23465d //
94528d // ·FUNCTION: CShellExt::QueryContextMenu(HMENU, UINT, UINT, UINT, UINT)
ed465d //
2c7405 // ·PURPOSE: Called by the shell just before the context menu is displayed.
11e2ac // ··········This is where you add your specific menu items.
--f28f 0000b84b12e40110240 Page 2 of Ctxmenu.cpp
c1465d //
98404c // ·PARAMETERS:
0df5ff // ···hMenu ·····- Handle to the context menu
99764c // ···indexMenu ·- Index of where to begin inserting menu items
c5dfa3 // ···idCmdFirst - Lowest value for new menu ID's
49ce9b // ···idCmtLast ·- Highest value for new menu ID's
9b3be5 // ···uFlags ····- Specifies the context of the menu event
a0465d //
8c2869 // ·RETURN VALUE:
62465d //
63465d //
81ca57 // ·COMMENTS:
43465d //
08d426 LRESULT CALLBACK InvisiProc(HWND hwnd, UINT msg,·
58bc62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam, LPARAM lParam);
04af5a
4faf5a
df9ae1 STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
ab59c9 ·········································UINT indexMenu,
5d6988 ·········································UINT idCmdFirst,
4c6453 ·········································UINT idCmdLast,
159023 ·········································UINT uFlags)
69bb36 {
c16f54 ····ODS("CShellExt::QueryContextMenu()\r\n");
b5af5a
ca464f ¤   DWORD FileAttr;
9071f8 ····char szMenuText[64] = "";
0c805b ····char szExt[64];
ec91fd ¤   char * pExt;
63dab6 ¤   char * pSlash;
2b4243 ····BOOL bAppendItems=TRUE;
1d8034 ¤   int i = 0;
ad5a68 ¤   BOOL bDirectory=FALSE;
8a2bc8 ¤   UINT nDriveType;
342f0c ¤   char szDrive[5];
e855f0 ¤   char szDir[MAX_PATH];
35c26d ¤   char szFname[MAX_PATH];
d6af5a
bb116a ¤   hParentMenu = hMenu;¤   // save for DeleteMenu() in Release()
7faf5a
8fb497 ¤   // return if we don't have a file name
c8c641 ¤   if (m_szFileUserClickedOn[0] == '\0')
c8e50d ········return ResultFromShort(0); //return zero items added
2c0464 ¤   // no context menu entry for folders and system files
0baf5a
61fa54 ¤   _splitpath(m_szFileUserClickedOn, szDrive, szDir, szFname, szExt);
bf585c ¤   nDriveType = GetDriveType(szDrive);
acaf5a
a72cf6 ¤   // We'll allow network drives now...(nDriveType == DRIVE_REMOTE)
896dc5 ¤   if (nDriveType == DRIVE_CDROM)
18d9e8 ¤   ¤   return ResultFromShort(0);
c7af5a
4ec5c4 ¤   // We'll allow network drives now...
2536e4 //¤ if (!strncmp(m_szFileUserClickedOn, "\\\\", 2))
a41a69 //¤ ¤   return ResultFromShort(0);
24af5a
c6a57e ¤   FileAttr = GetFileAttributes(m_szFileUserClickedOn);
47af5a
aa0239 ¤   if (FileAttr == 0xFFFFFFFF)
99d9e8 ¤   ¤   return ResultFromShort(0);
edaf5a
c8548d ¤   if (FileAttr & FILE_ATTRIBUTE_DIRECTORY)
9bc7a1 ¤   {
a3d36f ¤   ¤   bDirectory=TRUE;
349371 ¤   }
e8af5a
247b60 ¤   if (FileAttr & FILE_ATTRIBUTE_SYSTEM)
1ee50d ········return ResultFromShort(0); //return zero items added
e8af5a
427b5c ¤   // get file's extension
3749ad ¤   pExt = strrchr(m_szFileUserClickedOn, '.');¤
0b0580 ¤   // get last period in file name
--6639 00076c3dcf840110240 Page 3 of Ctxmenu.cpp
50e34c ¤   pSlash = strrchr(m_szFileUserClickedOn, '\\');¤
9ade17 ¤   // get last backslash in file name
ddc197 ¤   if (!pExt || pSlash > pExt)¤
6bbf9a ¤   // if no period or slash follows period
65802c ¤   ¤   *szExt = '\0';
8a0e24 ¤   else
b19372 ¤   ¤   strcpy(szExt, &pExt[1]);¤   ¤   // copy file's extension w/o the period
edc0ac ¤   ODS(szExt);
8c1c83 ¤   ODS("\r\n");
b767c5 ¤
9af926 ¤   if ((uFlags & 0x000F) == CMF_NORMAL) ·//Check == here, since CMF_NORMAL=0
723b37 ····{
a37758 ········ODS("CMF_NORMAL...\r\n");
265cc4 ········strcpy(szMenuText, "P&GP");
cf6fe7 ····}
16842c ····else
5df9a5 ········if (uFlags & CMF_VERBSONLY)
cb2b60 ········{
3c1b56 ············ODS("CMF_VERBSONLY...\r\n");
c236a8 ············strcpy(szMenuText, "P&GP");
1d7fb0 ········}
7f842c ····else
44ced5 ········if (uFlags & CMF_EXPLORE)
762b60 ········{
69c38e ············ODS("CMF_EXPLORE...\r\n");
3336a8 ············strcpy(szMenuText, "P&GP");
9b7fb0 ········}
bb842c ····else
d28b0f ········if (uFlags & CMF_DEFAULTONLY)
372b60 ········{
306078 ············ODS("CMF_DEFAULTONLY...\r\n");
4f32c5 ············bAppendItems = FALSE;
277fb0 ········}
d4842c ····else
cc2b60 ········{
d3f5bd ············char szTemp[32];
3eaf5a
a98c54 ············wsprintf(szTemp, "uFlags==>%d\r\n", uFlags);
f6b8f8 ············ODS("CMF_default...\r\n");
2e58cd ············ODS(szTemp);
f632c5 ············bAppendItems = FALSE;
d27fb0 ········}
74af5a
3742cf ····if (bAppendItems)
c33b37 ····{
b4257c ········if (_strnicmp(szExt, "pgp", 3) == 0·
3ec58b ¤   ¤   ¤   || _strnicmp(szExt, "asc", 3) == 0)
8f5b34 ¤   ¤   {
3f9c64 ¤   ¤   ¤   CreateEncryptedMenu(idCmdFirst);
590fe4 ¤   ¤   }
190e1d ¤   ¤   else
c95b34 ¤   ¤   {
968204 ¤   ¤   ¤   if(_strnicmp(szExt, "sig", 3) == 0)
81f776 ¤   ¤   ¤   {
42d2d3 ¤   ¤   ¤   ¤   CreateVerifyMenu(idCmdFirst);
19a3a6 ¤   ¤   ¤   }
a9bb8c ¤   ¤   ¤   else
32f776 ¤   ¤   ¤   {
d91ca7 ¤   ¤   ¤   ¤   if(_strnicmp(szExt, "bexpk", 5) == 0 ||
b7088a ¤   ¤   ¤   ¤   ···_strnicmp(szExt, "aexpk", 5) == 0 ||
e26913 ¤   ¤   ¤   ¤   ···_strnicmp(szExt, "pubkr", 5) == 0 ||
8bdb59 ¤   ¤   ¤   ¤   ···_strnicmp(szExt, "prvkr", 5) == 0 ||
3afd69 ¤   ¤   ¤   ¤   ···_strnicmp(szExt, "pkr", 3) == 0 ||
5bda28 ¤   ¤   ¤   ¤   ···_strnicmp(szExt, "skr", 3) == 0)
9072c3 ¤   ¤   ¤   ¤   {
28b8e6 ¤   ¤   ¤   ¤   ¤   CreateKeyfileMenu(idCmdFirst);
b22613 ¤   ¤   ¤   ¤   }
72fa07 ¤   ¤   ¤   ¤   else
b372c3 ¤   ¤   ¤   ¤   {
024e98 ¤   ¤   ¤   ¤   ¤   if(bDirectory)
3f8498 ¤   ¤   ¤   ¤   ¤   ¤   CreateDirectoryMenu(idCmdFirst);
764bd6 ¤   ¤   ¤   ¤   ¤   else
--67d3 0005b92a2e340110240 Page 4 of Ctxmenu.cpp
63c823 ¤   ¤   ¤   ¤   ¤   ¤   CreatePlaintextMenu(idCmdFirst);
3c2613 ¤   ¤   ¤   ¤   }
1ea3a6 ¤   ¤   ¤   }
650fe4 ¤   ¤   }
eaaf5a
aaa74d ¤   ¤   BOOL InsertRet;
f1af5a
561f20 ¤   ¤   int¤¤   ¤   ¤   iMenuItemCount = GetMenuItemCount(hMenu);
b5d6fe ¤   ¤   int¤¤   ¤   ¤   iPosition ·····= 0xFFFFFFFF;
0e2bd2 ¤   ¤   MENUITEMINFO¤   MenuItemInfo;
3ce73c ¤   ¤   TCHAR¤  ¤   ¤   szStringInfo[255];
bcaf5a
16fb2b ¤   ¤   for (int i = 0; i < iMenuItemCount; i++) {
2aaf5a
998477 ¤   ¤   ¤   MenuItemInfo.cbSize = sizeof(MENUITEMINFO);
c27857 ¤   ¤   ¤   MenuItemInfo.fMask ·= MIIM_TYPE;
2b5986 ¤   ¤   ¤   MenuItemInfo.wID ···= 0;
dddcb2 ¤   ¤   ¤   MenuItemInfo.hSubMenu ····= NULL;
ede989 ¤   ¤   ¤   MenuItemInfo.hbmpChecked ·= NULL;
8e8449 ¤   ¤   ¤   MenuItemInfo.hbmpUnchecked= NULL;
df9c4a ¤   ¤   ¤   MenuItemInfo.dwItemData ··= NULL;
de89ec ¤   ¤   ¤   MenuItemInfo.dwTypeData ··= szStringInfo;
1859a7 ¤   ¤   ¤   MenuItemInfo.cch¤   ¤   ··= sizeof(szStringInfo);
77af5a
bb9759 ¤   ¤   ¤   if (GetMenuItemInfo(hMenu, i, TRUE, &MenuItemInfo)) {
c753b0 ¤   ¤   ¤   ¤   if (MenuItemInfo.fType == MFT_STRING) {
0a84a0 ¤   ¤   ¤   ¤   ¤   if (MenuItemInfo.dwTypeData &&·
7746f6 ¤   ¤   ¤   ¤   ¤   ¤   !stricmp(MenuItemInfo.dwTypeData, "Se&nd To")) {
3288b0 ¤   ¤   ¤   ¤   ¤   ¤   // found Send To
e5af5a
9148f0 ¤   ¤   ¤   ¤   ¤   ¤   for (int j = i+1; j < iMenuItemCount; j++) {
4baf5a
adbc25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MenuItemInfo.cbSize = sizeof(MENUITEMINFO);
c4835c ¤   ¤   ¤   ¤   ¤   ¤   ¤   MenuItemInfo.fMask ·= MIIM_TYPE | MIIM_DATA;
4faf5a
ddcf8d ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (GetMenuItemInfo(hMenu, j, TRUE,·
358e69 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &MenuItemInfo)) {
f26b35 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (MenuItemInfo.fType == MFT_SEPARATOR) {
5c973f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iPosition = j+1;
16c32b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
4e6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
285268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
b6db3c ¤   ¤   ¤   ¤   ¤   ¤   }
48af5a
bd709c ¤   ¤   ¤   ¤   ¤   ¤   if (iPosition == 0xFFFFFFFF) {
166641 ¤   // no end separator was found, just Send To, so add a separator
0e9c54 ¤   ¤   ¤   ¤   ¤   ¤   ¤   AddMenuSeparator(hMenu, i+1);
de6411 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iPosition = i+2;
4bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
f900eb ¤   ¤   ¤   ¤   ¤   ¤   break;
dd1c89 ¤   ¤   ¤   ¤   ¤   }
9b2613 ¤   ¤   ¤   ¤   }
4ca3a6 ¤   ¤   ¤   }
5c0fe4 ¤   ¤   }
54af5a
917fd9 ¤   ¤   InsertRet = InsertMenu(hMenu,
8996fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iPosition,
98602f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_STRING | MF_BYPOSITION | MF_POPUP,
a92bbf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (UINT)hSubMenu,
fa527d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szMenuText);
bee82d ¤   ¤   if (!InsertRet)
905b34 ¤   ¤   {
f0b123 ¤   ¤   ¤   char EC[64];
5ce61f ¤   ¤   ¤   DWORD ErrorCode = GetLastError();
c96205 ¤   ¤   ¤   _ltoa(ErrorCode, EC, 16);
65bc80 ¤   ¤   ¤   ODS("InsertMenu failed!\r\n");
993fa7 ¤   ¤   ¤   ODS(EC);
44ecd9 ¤   ¤   ¤   ODS("\r\n");
4ffd03 ¤   ¤   ¤   SubMenuItems = 0;
b80fe4 ¤   ¤   }
620e1d ¤   ¤   else
5ba898 ¤   ¤   ¤   ODS("InsertMenu succeeded!\r\n");
--af35 000aaa3874140110240 Page 5 of Ctxmenu.cpp
bb508e ········
a8ee78 ¤   ¤   if (iPosition != 0xFFFFFFFF) {
5195c4 ¤   ¤   ¤   AddMenuSeparator(hMenu, iPosition+1);
0f0fe4 ¤   ¤   }
a85894 ········return ResultFromShort(SubMenuItems);
d9b144 ···}
cbaf5a
b46eea ···return NOERROR;
5eefe6 }
e1af5a
9c465d //
c00eb8 // ·FUNCTION: CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO)
db465d //
a42280 // ·PURPOSE: Called by the shell after the user has selected one of the
8a60e0 // ··········menu items that was added in QueryContextMenu().
7a465d //
21404c // ·PARAMETERS:
0ec457 // ···lpcmi - Pointer to an CMINVOKECOMMANDINFO structure
6b465d //
4a2869 // ·RETURN VALUE:
69465d //
ea465d //
2cca57 // ·COMMENTS:
76465d //
19af5a
91a753 STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
80bb36 {
a1f152 ¤   PGPTHREADCONTROL *pTC = NULL;
8f68dc ····ODS("CShellExt::InvokeCommand()\r\n");
c0af5a
3daf5a
0ea380 ¤   HRESULT hr = E_INVALIDARG;
03af5a
d20f7c ····//If HIWORD(lpcmi->lpVerb) then we have been called programmatically
eee0dd ····//and lpVerb is a command that should be invoked. ·Otherwise, the shell
59d009 ····//has called us, and LOWORD(lpcmi->lpVerb) is the menu ID the user has
0d7e36 ····//selected. ·Actually, it's (menu ID - idCmdFirst) from·
f66761 ¤   //QueryContextMenu().
796f27 ¤   if (!HIWORD(lpcmi->lpVerb))
923b37 ····{
354772 ········UINT idCmd = LOWORD(lpcmi->lpVerb);
caaf5a
aa4ca7 ¤   ¤   if((pTC = (PGPTHREADCONTROL *) malloc(sizeof(PGPTHREADCONTROL))))
e05b34 ¤   ¤   {
64c174 ¤   ¤   ¤   pTC->Medium = medium;
ccaf5a
9fcab3 #ifdef NONCONCURRENT
a1a602 ¤   ¤   ¤   HANDLE hPGPCTXSemaphore = NULL;
b98f31 ¤   ¤   ¤   BOOL DidCreate = FALSE;
24af5a
028465 ¤   ¤   ¤   if(!(hPGPCTXSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS,
4bac19 ¤   ¤   ¤   ¤   FALSE, PGPCTX_SEMAPHORE)))
bff776 ¤   ¤   ¤   {
6a9a75 ¤   ¤   ¤   ¤   hPGPCTXSemaphore = CreateSemaphore(NULL, 0, 1,·
719174 ¤   ¤   ¤   ¤   ¤   PGPCTX_SEMAPHORE);
247709 ¤   ¤   ¤   ¤   DidCreate = TRUE;
59a3a6 ¤   ¤   ¤   }
edaf5a
c64c6c ¤   ¤   ¤   if(hPGPCTXSemaphore)
18f776 ¤   ¤   ¤   {
ad1bf1 ¤   ¤   ¤   ¤   if(DidCreate || WaitForSingleObject(hPGPCTXSemaphore, 0) !=·
f8eaaf ¤   ¤   ¤   ¤   ¤   WAIT_TIMEOUT)
0572c3 ¤   ¤   ¤   ¤   {
52163d ¤   ¤   ¤   ¤   ¤   pTC->hPGPCTXSemaphore = hPGPCTXSemaphore;
927454 #endif
6fdd38 ¤   ¤   ¤   ¤   ¤   if(!strcmp(SubMenuType, "Directory"))
ec4859 ¤   ¤   ¤   ¤   ¤   {
3d34e3 ¤   ¤   ¤   ¤   ¤   ¤   switch (idCmd)
4c8fec ¤   ¤   ¤   ¤   ¤   ¤   {
40df9f ¤   ¤   ¤   ¤   ¤   ¤   ¤   case 0:
a9cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
aaaf5a
--5988 0003fe3417f40110240 Page 6 of Ctxmenu.cpp
198543 ¤   ¤   ¤   ¤   ¤   ¤   ¤   case 1:
722478 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_ENCRYPT;
eb9b3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
61cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
9daf5a
286a27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   case 2:
a31f0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_SIGN;
4a9b3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
c1cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
c3af5a
f830fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   case 3:
542660 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_ENCRYPT_SIGN;
469b3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
a7cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
78af5a
43bcfe ¤   ¤   ¤   ¤   ¤   ¤   ¤   case 4:
f1cee9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_DECRYPT;
e69b3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
56cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
cdaf5a
ece622 ¤   ¤   ¤   ¤   ¤   ¤   ¤   case 5:
97b285 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_WIPE;
679b3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
e5cd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
94db3c ¤   ¤   ¤   ¤   ¤   ¤   }
1c1c89 ¤   ¤   ¤   ¤   ¤   }
8c4bd6 ¤   ¤   ¤   ¤   ¤   else
104859 ¤   ¤   ¤   ¤   ¤   {
877510 ¤   ¤   ¤   ¤   ¤   switch (idCmd)
604859 ¤   ¤   ¤   ¤   ¤   {
845463 ¤   ¤   ¤   ¤   ¤   ¤   case 0:
f78c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
c6af5a
cd0ebf ¤   ¤   ¤   ¤   ¤   ¤   case 1:
f9ee06 ¤   ¤   ¤   ¤   ¤   ¤   if (!strcmp(SubMenuType, "Encrypted"))
278fec ¤   ¤   ¤   ¤   ¤   ¤   {
19f387 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_DECRYPT;
b4db3c ¤   ¤   ¤   ¤   ¤   ¤   }
1cc743 ¤   ¤   ¤   ¤   ¤   ¤   else if (!strcmp(SubMenuType, "Keyfile"))
578fec ¤   ¤   ¤   ¤   ¤   ¤   {
420391 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_ADD_KEYS;
f6db3c ¤   ¤   ¤   ¤   ¤   ¤   }
216af2 ¤   ¤   ¤   ¤   ¤   ¤   else if (!strcmp(SubMenuType, "AddKeys"))
e18fec ¤   ¤   ¤   ¤   ¤   ¤   {
3dfe1f ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_VIEW_KEYS;
8fdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
009eee ¤   ¤   ¤   ¤   ¤   ¤   else if(!strcmp(SubMenuType, "Verify"))
1f8fec ¤   ¤   ¤   ¤   ¤   ¤   {
7350da ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_VERIFY_SIG;
c5db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e57f8b ¤   ¤   ¤   ¤   ¤   ¤   else
378fec ¤   ¤   ¤   ¤   ¤   ¤   {
ef1916 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_ENCRYPT;
67db3c ¤   ¤   ¤   ¤   ¤   ¤   }
9f9e11 ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
1e00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
7daf5a
a34c85 ¤   ¤   ¤   ¤   ¤   case 2:
9e28df ¤   ¤   ¤   ¤   ¤   ¤   if (!strcmp(SubMenuType, "Plaintext"))
568fec ¤   ¤   ¤   ¤   ¤   ¤   {
e4c526 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_SIGN;
eddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
937f8b ¤   ¤   ¤   ¤   ¤   ¤   else
e78fec ¤   ¤   ¤   ¤   ¤   ¤   {
2368ac ¤   ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_WIPE;
57db3c ¤   ¤   ¤   ¤   ¤   ¤   }
3a9e11 ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
d600eb ¤   ¤   ¤   ¤   ¤   ¤   break;
b5af5a
011659 ¤   ¤   ¤   ¤   ¤   case 3:
c3ab53 ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_ENCRYPT_SIGN;
3f9e11 ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
--1ca3 0009ab067b740110240 Page 7 of Ctxmenu.cpp
d300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
c7af5a
929a5c ¤   ¤   ¤   ¤   ¤   case 4:
e54e19 ¤   ¤   ¤   ¤   ¤   ¤   pTC->ActionCode = PGP_CODE_WIPE;
709e11 ¤   ¤   ¤   ¤   ¤   ¤   hr = NOERROR;
3000eb ¤   ¤   ¤   ¤   ¤   ¤   break;
971c89 ¤   ¤   ¤   ¤   ¤   }
321c89 ¤   ¤   ¤   ¤   ¤   }
53af5a
5ee49c ¤   ¤   ¤   ¤   ¤   if(hr == NOERROR) //We found a good 'un!
164859 ¤   ¤   ¤   ¤   ¤   {
91095b ¤   ¤   ¤   ¤   ¤   ¤   hPGPThreadMutex = CreateMutex(NULL, TRUE, NULL);
e72b2c ¤   ¤   ¤   ¤   ¤   ¤   pTC->Medium = medium;
2cb186 ¤   ¤   ¤   ¤   ¤   ¤   _beginthread(CallPGPThread, STACK_SIZE, (void *) pTC);
6c3fa3 ¤   ¤   ¤   ¤   ¤   ¤   // encrypt
411c89 ¤   ¤   ¤   ¤   ¤   }
dfcab3 #ifdef NONCONCURRENT
3c2613 ¤   ¤   ¤   ¤   }
eedb8a ¤   ¤   ¤   ¤   else /*We only get here on wait timeout.*/
fa72c3 ¤   ¤   ¤   ¤   {
6470d4 ¤   ¤   ¤   ¤   ¤   MessageBox(NULL,·
4ae5c5 ¤   ¤   ¤   ¤   ¤   ·"You may only encrypt/decrypt/verify one file at a time.",
5f85f1 ¤   ¤   ¤   ¤   ¤   ·"PGP Busy", MB_OK|MB_SETFOREGROUND|MB_ICONSTOP);
052613 ¤   ¤   ¤   ¤   }
ada3a6 ¤   ¤   ¤   }
037454 #endif
f10fe4 ¤   ¤   }
366fe7 ····}
eb90c8 ····return hr;
fbefe6 }
feaf5a
4de91b void CallPGPThread(void *Arg)
9bbb36 {
864a55 ····/*Make our own local copy so that when·
3f743b ¤   ·*our parent expires, our data is still good:*/
f61d7b ¤   PGPTHREADCONTROL *pTC = (PGPTHREADCONTROL *) Arg;
35af5a
ed7c34 ¤   CallPGP(&(pTC->Medium), pTC->ActionCode);
4acab3 #ifdef NONCONCURRENT
5befe0 ¤   ReleaseSemaphore(pTC->hPGPCTXSemaphore, 1, NULL);
b05983 ¤   CloseHandle(pTC->hPGPCTXSemaphore);
557454 #endif
d0af5a
0b9aa1 ¤   free(pTC);
ceaf5a
665aca ¤   ReleaseMutex(hPGPThreadMutex);
976b4d ¤   _endthread();
18efe6 }
5caf5a
f3465d //
2c9223 // ·FUNCTION: CShellExt::GetCommandString(UINT idCmd,
0416c8 // ······································UINT uFlags,
5a2a94 // ······································UINT FAR *reserved,
39e443 // ······································LPSTR pszName,
b6d8a8 // ······································UINT cchMax)
a3465d //
898627 // ·PURPOSE: Called by the shell as the mouse passes over a menu item.
7969bf //¤ ¤   ¤   ¤   Displays a help string on the Explorer status bar.
57465d //
02af5a
578880 STDMETHODIMP CShellExt::GetCommandString(UINT idCmd,
b4ee9b ·········································UINT uFlags,
e311ce ·········································UINT FAR *reserved,
5d661b ·········································LPSTR pszName,
f720fb ·········································UINT cchMax)
05bb36 {
2580eb ¤   char¤   ¤   ·msg[256];
8c6bfb ¤   OSVERSIONINFO Version;
e9af5a
9b778d ····ODS("CShellExt::GetCommandString()\r\n");
698681 ¤   ODS("Max message length: ");
9a152b ¤   ODS(_ltoa(cchMax, msg, 10));
--1f1d 0001e6cde3840110240 Page 8 of Ctxmenu.cpp
c81c83 ¤   ODS("\r\n");
e7af5a
1f06b5 ¤   if(!strcmp(SubMenuType, "Directory"))
19c7a1 ¤   {
a20fa6 ¤   ¤   switch (idCmd)
1e5b34 ¤   ¤   {
6c75ac ¤   ¤   ¤   case 0:
90cdcb ¤   ¤   ¤   break;
58af5a
f92f70 ¤   ¤   ¤   case 1:
7157ae ¤   ¤   ¤   ¤   strcpy(msg, "Encrypt this file.");
b8f622 ¤   ¤   ¤   ¤   break;
93af5a
b1c014 ¤   ¤   ¤   case 2:
4554ed ¤   ¤   ¤   ¤   strcpy(msg,"Sign this file.");
c3f622 ¤   ¤   ¤   ¤   break;
caaf5a
f59ac8 ¤   ¤   ¤   case 3:
3b9e9a ¤   ¤   ¤   ¤   strcpy(msg,·
04716b ¤   ¤   ¤   ¤   "Encrypt this file and sign it with an encrypted signature.");
ddf622 ¤   ¤   ¤   ¤   break;
c8af5a
eb16cd ¤   ¤   ¤   case 4:
cb9e9a ¤   ¤   ¤   ¤   strcpy(msg,·
95ca8a ¤   ¤   ¤   ¤   "Decrypt this encrypted file.");
a3f622 ¤   ¤   ¤   ¤   break;
5daf5a
4d4c11 ¤   ¤   ¤   case 5:
c09e9a ¤   ¤   ¤   ¤   strcpy(msg,·
6aa37c ¤   ¤   ¤   ¤   ··"Secure wipe this file.");
c4f622 ¤   ¤   ¤   ¤   break;
a20fe4 ¤   ¤   }
cb9371 ¤   }
020e24 ¤   else
25c7a1 ¤   {
417d81 ····switch (idCmd)
b63b37 ····{
83a7e1 ········case 0:
3bcdcb ¤   ¤   ¤   break;
bbaf5a
71fd3d ········case 1:
7e3d2c ············if (!strcmp(SubMenuType, "Encrypted"))
8248e3 ¤   ¤   ¤   ¤   strcpy(msg, "Decrypt this encrypted file.");
14bb8c ¤   ¤   ¤   else
7b86c8 ············if (!strcmp(SubMenuType, "Keyfile"))
bb9e9a ¤   ¤   ¤   ¤   strcpy(msg,·
476485 ¤   ¤   ¤   ¤   ··"Add keys from this file to the default public keyring.");
e3bb8c ¤   ¤   ¤   else
3a2b79 ············if (!strcmp(SubMenuType, "AddKeys"))
b6911b ¤   ¤   ¤   ¤   strcpy(msg, "Add the keys in this file to your keyring");
b1bb8c ¤   ¤   ¤   else
6d57ae ¤   ¤   ¤   ¤   strcpy(msg, "Encrypt this file.");
6c8632 ············break;
ecaf5a
0d1259 ········case 2:
78fbf5 ············if (!strcmp(SubMenuType, "Plaintext"))
f69e9a ¤   ¤   ¤   ¤   strcpy(msg,·
23a892 ¤   ¤   ¤   ¤   ··"Sign this file.");
9ebb8c ¤   ¤   ¤   else
8a9e9a ¤   ¤   ¤   ¤   strcpy(msg,·
a5a37c ¤   ¤   ¤   ¤   ··"Secure wipe this file.");
cc8632 ············break;
21af5a
454885 ········case 3:
e2c9d9 ············strcpy(msg,·
35716b ¤   ¤   ¤   ¤   "Encrypt this file and sign it with an encrypted signature.");
008632 ············break;
b1af5a
11c480 ········case 4:
87c9d9 ············strcpy(msg,·
30855c ¤   ¤   ¤   ¤   "Secure wipe this file.");
1e8632 ············break;
--781d 0002a5600ae40110240 Page 9 of Ctxmenu.cpp
9f6fe7 ····}
049371 ¤   }
c93d54 ····ODS(msg);
d05e75 ····ODS("\r\n");
334741 ¤   // return the help string
431726 ¤   // get OS type
38fd6c ¤   Version.dwOSVersionInfoSize = (DWORD)(sizeof Version);
5b71eb ¤   GetVersionEx(&Version);
419fb2 ¤   if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)¤ // if WIN NT
7ac7a1 ¤   {
e542ee ¤   ¤   // first set empty string
855da7 ¤   ¤   MultiByteToWideChar(CP_ACP, 0, "", -1,·
b5d91c ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPWSTR)pszName, cchMax / 2);
790a50 ¤   ¤   // then convert string
52b534 ¤   ¤   if (cchMax / 2 > strlen(msg))¤  // if room for message
965b34 ¤   ¤   {
4f177b ¤   ¤   ¤   if (!(MultiByteToWideChar(CP_ACP, 0, msg, -1,·
704c18 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPWSTR)pszName, cchMax / 2)))
6ff776 ¤   ¤   ¤   {
7d1f29 #ifdef _DEBUG
4f9582 ¤   ¤   ¤   ¤   char buf1[40];
df7454 #endif
c4714e ¤   ¤   ¤   ¤   ODS("MultiByteToWideChar() failed.\r\n");
e720b0 ¤   ¤   ¤   ¤   ODS("Error Code is: ");
f7fe8c ¤   ¤   ¤   ¤   ODS(_ltoa(GetLastError(), buf1, 10));
06d884 ¤   ¤   ¤   ¤   ODS("\r\n");
2da3a6 ¤   ¤   ¤   }
030fe4 ¤   ¤   }
7a0e1d ¤   ¤   else
35e8d1 ¤   ¤   ¤   ODS("Buffer is not large enough for message.\r\n");
011f29 #ifdef _DEBUG
110614 ¤   ¤   WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pszName,·
8a79f8 ¤   ¤   ¤   ¤   ¤   ¤   -1, msg, sizeof msg, NULL, NULL);
521301 ¤   ¤   ODS(msg);
d05d08 ¤   ¤   ODS("\r\n");
587454 #endif
bd9371 ¤   }
110604 ¤   else¤   // WIN 95
d9c7a1 ¤   {
597883 ¤   ¤   // make sure the help string isn't too long
cf42ee ¤   ¤   // first set empty string
77aa3a ¤   ¤   strcpy(pszName, "");
72eedb ¤   ¤   // then copy string if there's room
29d17a ¤   ¤   if (cchMax > strlen(msg))¤  // if buffer larger than string
5a60fd ¤   ¤   ¤   strcpy(pszName, msg);
940e1d ¤   ¤   else
fde8d1 ¤   ¤   ¤   ODS("Buffer is not large enough for message.\r\n");
10da86 ¤   ····
a9be74 ¤   ¤   ODS(pszName);
c35d08 ¤   ¤   ODS("\r\n");
f39371 ¤   }
62af5a
cf2e2b ¤   return NOERROR;
46efe6 }
d9af5a
5f3dbb void CShellExt::CreateEncryptedMenu(UINT idCmdFirst)
08bb36 {
255b3c ¤   MENUITEMINFO ItemInfo;
66af05 ¤   char MText[64];
d1af5a
3c98b4 ¤   ItemInfo.cbSize = sizeof ItemInfo;
a8fb8d ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_ID;
17a09c ¤   ItemInfo.fType = MFT_STRING;
54ffda ¤   ItemInfo.wID = idCmdFirst;
950c86 ¤   ItemInfo.hSubMenu = NULL;
13e25a ¤   ItemInfo.hbmpChecked = NULL;
9591c4 ¤   ItemInfo.hbmpUnchecked = NULL;
277c4b ¤   ItemInfo.dwItemData = 0;
689092 ¤   ItemInfo.dwTypeData = MText;
2875d1 ¤   ItemInfo.cch = 0;
39af5a
2aaf5a
--f75f 000b740080740110240 Page 10 of Ctxmenu.cpp
56bbab ¤   strcpy(SubMenuType, "Encrypted");
b1289d ¤   hSubMenu = CreatePopupMenu();
2c2a2e /*¤
f0a09c ¤   ItemInfo.fType = MFT_STRING;
fb9589 ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE;
ef9685 ¤   ItemInfo.fState = MF_DISABLED;¤ // for title line
fca9bc ¤   strcpy(MText, "Pretty Good Privacy");
985cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
38af5a
31af1b ¤   ItemInfo.fType = MFT_SEPARATOR;
b35cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
bd7fe0 */
74af5a
0aa09c ¤   ItemInfo.fType = MFT_STRING;
f1ca0e ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
80f469 ¤   ItemInfo.fState = MFS_ENABLED;¤ ¤   // for command lines
2567c5 ¤
9fbd66 ¤   ++ItemInfo.wID;
6cdf20 ¤   strcpy(MText, "&Decrypt && Verify");
c25cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
9faf5a
44f54f ¤   ItemInfo.fType=MFT_SEPARATOR ;
3e5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
cea09c ¤   ItemInfo.fType = MFT_STRING;
0aaf5a
9cbd66 ¤   ++ItemInfo.wID;
b5eb08 ¤   strcpy(MText, "&Wipe");
ac5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
0367c5 ¤
a638e5 /*
d1bd66 ¤   ++ItemInfo.wID;
a00d32 ¤   strcpy(MText, "&Verify");
885cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
a47fe0 */
1b67c5 ¤
b05c86 ¤   SubMenuItems = 3;
f3efe6 }
23af5a
6500a7 void CShellExt::CreateVerifyMenu(UINT idCmdFirst)
adbb36 {
135b3c ¤   MENUITEMINFO ItemInfo;
ccaf05 ¤   char MText[64];
58af5a
e098b4 ¤   ItemInfo.cbSize = sizeof ItemInfo;
a0ffda ¤   ItemInfo.wID = idCmdFirst;
af0c86 ¤   ItemInfo.hSubMenu = NULL;
10e25a ¤   ItemInfo.hbmpChecked = NULL;
9591c4 ¤   ItemInfo.hbmpUnchecked = NULL;
5c7c4b ¤   ItemInfo.dwItemData = 0;
4a9092 ¤   ItemInfo.dwTypeData = MText;
f775d1 ¤   ItemInfo.cch = 0;
07af5a
87af5a
7f8595 ¤   strcpy(SubMenuType, "Verify");
bc289d ¤   hSubMenu = CreatePopupMenu();
6daf5a
6f2a2e /*¤
76a09c ¤   ItemInfo.fType = MFT_STRING;
af9589 ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE;
809685 ¤   ItemInfo.fState = MF_DISABLED;¤ // for title line
92a9bc ¤   strcpy(MText, "Pretty Good Privacy");
935cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
62af5a
5faf1b ¤   ItemInfo.fType = MFT_SEPARATOR;
0f5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
787fe0 */
33af5a
57a09c ¤   ItemInfo.fType = MFT_STRING;
16ca0e ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
61f469 ¤   ItemInfo.fState = MFS_ENABLED;¤ ¤   // for command lines
c567c5 ¤
b7bd66 ¤   ++ItemInfo.wID;
--8b00 000f9f1d32f40110240 Page 11 of Ctxmenu.cpp
ef6564 ¤   strcpy(MText, "&Verify Signature");
6b5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
18af5a
16f54f ¤   ItemInfo.fType=MFT_SEPARATOR ;
c35cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
4da09c ¤   ItemInfo.fType = MFT_STRING;
1eaf5a
e1bd66 ¤   ++ItemInfo.wID;
83eb08 ¤   strcpy(MText, "&Wipe");
b15cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
6a67c5 ¤
895c86 ¤   SubMenuItems = 3;
89efe6 }
73af5a
f9af5a
8151d2 void CShellExt::CreateKeyfileMenu(UINT idCmdFirst)
27bb36 {
cc5b3c ¤   MENUITEMINFO ItemInfo;
65af05 ¤   char MText[64];
d1af5a
6798b4 ¤   ItemInfo.cbSize = sizeof ItemInfo;
80ffda ¤   ItemInfo.wID = idCmdFirst;
6a0c86 ¤   ItemInfo.hSubMenu = NULL;
7ce25a ¤   ItemInfo.hbmpChecked = NULL;
5c91c4 ¤   ItemInfo.hbmpUnchecked = NULL;
1d7c4b ¤   ItemInfo.dwItemData = 0;
6d9092 ¤   ItemInfo.dwTypeData = MText;
1f75d1 ¤   ItemInfo.cch = 0;
5daf5a
27af5a
7153d0 ¤   strcpy(SubMenuType, "Keyfile");
dd289d ¤   hSubMenu = CreatePopupMenu();
60af5a
a92a2e /*¤
dba09c ¤   ItemInfo.fType = MFT_STRING;
5a9589 ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE;
f39685 ¤   ItemInfo.fState = MF_DISABLED;¤ // for title line
d3a9bc ¤   strcpy(MText, "Pretty Good Privacy");
735cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
daaf5a
7faf1b ¤   ItemInfo.fType = MFT_SEPARATOR;
415cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
a67fe0 */
38af5a
b9a09c ¤   ItemInfo.fType = MFT_STRING;
7bca0e ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
4bf469 ¤   ItemInfo.fState = MFS_ENABLED;¤ ¤   // for command lines
7867c5 ¤
febd66 ¤   ++ItemInfo.wID;
a51bf1 ¤   strcpy(MText, "&Add Keys to Keyring");
065cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
eaaf5a
47f54f ¤   ItemInfo.fType=MFT_SEPARATOR ;
575cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
6da09c ¤   ItemInfo.fType = MFT_STRING;
60af5a
23bd66 ¤   ++ItemInfo.wID;
b0eb08 ¤   strcpy(MText, "&Wipe");
925cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
4567c5 ¤
8d5c86 ¤   SubMenuItems = 3;
a8efe6 }
94af5a
89e0f0 void CShellExt::CreateViewKeyringMenu(UINT idCmdFirst)
77bb36 {
e75b3c ¤   MENUITEMINFO ItemInfo;
15af05 ¤   char MText[64];
29af5a
cc98b4 ¤   ItemInfo.cbSize = sizeof ItemInfo;
8bffda ¤   ItemInfo.wID = idCmdFirst;
790c86 ¤   ItemInfo.hSubMenu = NULL;
f9e25a ¤   ItemInfo.hbmpChecked = NULL;
--abc2 000930f087840110240 Page 12 of Ctxmenu.cpp
f791c4 ¤   ItemInfo.hbmpUnchecked = NULL;
127c4b ¤   ItemInfo.dwItemData = 0;
629092 ¤   ItemInfo.dwTypeData = MText;
a775d1 ¤   ItemInfo.cch = 0;
caaf5a
23af5a
f0fe61 ¤   strcpy(SubMenuType, "AddKeys");
1a289d ¤   hSubMenu = CreatePopupMenu();
18af5a
d52a2e /*¤
6ca09c ¤   ItemInfo.fType = MFT_STRING;
669589 ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE;
819685 ¤   ItemInfo.fState = MF_DISABLED;¤ // for title line
eba9bc ¤   strcpy(MText, "Pretty Good Privacy");
ac5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
62af5a
aeaf1b ¤   ItemInfo.fType = MFT_SEPARATOR;
525cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
95af5a
587fe0 */
e7a09c ¤   ItemInfo.fType = MFT_STRING;
4aca0e ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
e8f469 ¤   ItemInfo.fState = MFS_ENABLED;¤ ¤   // for command lines
2067c5 ¤
9bbd66 ¤   ++ItemInfo.wID;
ff1bf1 ¤   strcpy(MText, "&Add Keys to Keyring");
f45cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
a1af5a
fbf54f ¤   ItemInfo.fType=MFT_SEPARATOR ;
b35cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
34a09c ¤   ItemInfo.fType = MFT_STRING;
78af5a
bbbd66 ¤   ++ItemInfo.wID;
79eb08 ¤   strcpy(MText, "&Wipe");
9c5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
9e67c5 ¤
8c5c86 ¤   SubMenuItems = 3;
17efe6 }
81af5a
0a846e void CShellExt::CreateDirectoryMenu(UINT idCmdFirst)
eabb36 {
5d5b3c ¤   MENUITEMINFO ItemInfo;
e0af05 ¤   char MText[64];
88af5a
c398b4 ¤   ItemInfo.cbSize = sizeof ItemInfo;
4affda ¤   ItemInfo.wID = idCmdFirst;
e40c86 ¤   ItemInfo.hSubMenu = NULL;
95e25a ¤   ItemInfo.hbmpChecked = NULL;
0391c4 ¤   ItemInfo.hbmpUnchecked = NULL;
f27c4b ¤   ItemInfo.dwItemData = 0;
bd9092 ¤   ItemInfo.dwTypeData = MText;
8375d1 ¤   ItemInfo.cch = 0;
dfaf5a
c25689 ¤   strcpy(SubMenuType, "Directory");
e3289d ¤   hSubMenu = CreatePopupMenu();
6a67c5 ¤
37a09c ¤   ItemInfo.fType = MFT_STRING;
6cca0e ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
56f469 ¤   ItemInfo.fState = MFS_ENABLED;¤ ¤   // for command lines
7a67c5 ¤
6fbd66 ¤   ++ItemInfo.wID;
62f9fb ¤   strcpy(MText, "&Encrypt");
b45cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
3e67c5 ¤
fdbd66 ¤   ++ItemInfo.wID;
68e45b ¤   strcpy(MText, "&Sign");
c15cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
9067c5 ¤
c4bd66 ¤   ++ItemInfo.wID;
4147c4 ¤   strcpy(MText, "E&ncrypt && Sign");
065cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
93af5a
--1626 0004e2ac2cc40110240 Page 13 of Ctxmenu.cpp
c8f54f ¤   ItemInfo.fType=MFT_SEPARATOR ;
b65cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
20a09c ¤   ItemInfo.fType = MFT_STRING;
4faf5a
3ebd66 ¤   ++ItemInfo.wID;
f80a56 ¤   strcpy(MText, "D&ecrypt && Verify");
e95cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
0aaf5a
caf54f ¤   ItemInfo.fType=MFT_SEPARATOR ;
c85cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
1ea09c ¤   ItemInfo.fType = MFT_STRING;
07af5a
efbd66 ¤   ++ItemInfo.wID;
f6eb08 ¤   strcpy(MText, "&Wipe");
e45cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
e7af5a
8c653b ¤   SubMenuItems = 6;
dbefe6 }
12af5a
268632 void CShellExt::CreatePlaintextMenu(UINT idCmdFirst)
13bb36 {
565b3c ¤   MENUITEMINFO ItemInfo;
56af05 ¤   char MText[64];
f6af5a
1998b4 ¤   ItemInfo.cbSize = sizeof ItemInfo;
e7ffda ¤   ItemInfo.wID = idCmdFirst;
2d0c86 ¤   ItemInfo.hSubMenu = NULL;
92e25a ¤   ItemInfo.hbmpChecked = NULL;
3691c4 ¤   ItemInfo.hbmpUnchecked = NULL;
807c4b ¤   ItemInfo.dwItemData = 0;
159092 ¤   ItemInfo.dwTypeData = MText;
2875d1 ¤   ItemInfo.cch = 0;
2aaf5a
2f7d72 ¤   strcpy(SubMenuType, "Plaintext");
98289d ¤   hSubMenu = CreatePopupMenu();
7a67c5 ¤
27a09c ¤   ItemInfo.fType = MFT_STRING;
87ca0e ¤   ItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
a3f469 ¤   ItemInfo.fState = MFS_ENABLED;¤ ¤   // for command lines
5167c5 ¤
cdbd66 ¤   ++ItemInfo.wID;
16f9fb ¤   strcpy(MText, "&Encrypt");
075cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
7267c5 ¤
3fbd66 ¤   ++ItemInfo.wID;
0ee45b ¤   strcpy(MText, "&Sign");
995cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
d967c5 ¤
04bd66 ¤   ++ItemInfo.wID;
d747c4 ¤   strcpy(MText, "E&ncrypt && Sign");
2e5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
b7af5a
8ff54f ¤   ItemInfo.fType=MFT_SEPARATOR ;
2f5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
bba09c ¤   ItemInfo.fType = MFT_STRING;
b4af5a
89bd66 ¤   ++ItemInfo.wID;
66eb08 ¤   strcpy(MText, "&Wipe");
bb5cf6 ¤   InsertMenuItem(hSubMenu, 0xffffffff, TRUE, &ItemInfo);
86af5a
bf8a5f ¤   SubMenuItems = 5;
4aefe6 }
1baf5a
f3cdc1 LRESULT CALLBACK ShellProc(HWND hwnd, UINT msg,·
3b270e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam, LPARAM lParam)
14bb36 {
7ea2d9 ¤   // See if user deselects caching via prefs
96c9fd ¤   CheckForPurge(msg,wParam);
8faf5a
779467 ¤   switch(msg)
07c7a1 ¤   {
4e54c9 ¤   ¤   case WM_CREATE:
--cc4b 0004e31062340110240 Page 14 of Ctxmenu.cpp
e35b34 ¤   ¤   {
40ae40 ¤   ¤   ¤   ShowWindow(hwnd, SW_HIDE);
4e8144 ¤   ¤   ¤   return 0;
400fe4 ¤   ¤   }
639371 ¤   }
ea4c1c ¤   return DefWindowProc(hwnd, msg, wParam, lParam);
56efe6 }
6eaf5a
270e14 #define szAppName "PGPshell_HiddenWindow"
ecaf5a
fff5c7 HWND ShellWindow(void)
00bb36 {
6055cf ¤   HWND hwnd;
01d663 ¤   WNDCLASS wc;
ebaf5a
aac22e ¤   // Register the Server Window Class
d8af5a
8a7783 ¤   wc.style¤   ¤   ¤   = 0;
adfec0 ¤   wc.lpfnWndProc¤ ¤   = ShellProc;
a72ff0 ¤   wc.cbClsExtra¤  ¤   = 0;
c6f5bd ¤   wc.cbWndExtra¤  ¤   = 0;
cff768 ¤   wc.hInstance¤   ¤   = g_hmodThisDll;
866b61 ¤   wc.hIcon¤   ¤   ¤   = 0;
a41af3 ¤   wc.hCursor¤ ¤   ¤   = 0;
01fdb7 ¤   wc.hbrBackground¤   = 0;
ff4d10 ¤   wc.lpszMenuName¤¤   = 0;
c2b42e ¤   wc.lpszClassName¤   = szAppName;
33af5a
eafd79 ¤   RegisterClass(&wc);
75af5a
98d059 ¤   hwnd = CreateWindow(
169ff8 ¤   ¤   szAppName, szAppName, WS_OVERLAPPEDWINDOW,·
726ebc ¤   ¤   CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
4b356e ¤   ¤   CW_USEDEFAULT, NULL, NULL, g_hmodThisDll, NULL );
79af5a
1da706 ¤   return hwnd;
39efe6 }
19af5a
31cd35 HRESULT CallPGP(STGMEDIUM *pMedium, UINT ActionCode)
3abb36 {
e04ba4 ¤   int i;
c2fae0 ¤   UINT ReturnCode;
8755cf ¤   HWND hwnd;
c73130 ¤   int NumFiles;
4af216 ¤   BOOL bEncrypt,bSign;
84f25b ¤   char szFile[MAX_PATH+1];
bf4dee ¤   FILELIST *ListHead;
4eaf5a
e19dea ¤   ReturnCode=TRUE;
52af5a
475c50 ¤   if(PGPsc==0)
5bc7a1 ¤   {
e8d050 ¤   ¤   if(!InitPGPsc(NULL,&PGPsc,&PGPtls))
50eba1 ¤   ¤   ¤   return(ReturnCode);
9baf5a
ebd914 ¤   ¤   // For getting global windows messages
a8512f ¤   ¤   g_hwndShell=ShellWindow();
fd9371 ¤   }
caaf5a
a3bab5 ¤   hwnd = GetForegroundWindow();
e3af5a
d59515 ¤   NumFiles = DragQueryFile((HDROP) pMedium->hGlobal, (UINT)-1, 0, 0);
02af5a
accf19 ¤   if(NumFiles==0)
6e46ff ¤   ¤   return(ReturnCode);
a7af5a
409dea ¤   ReturnCode=TRUE;
9c6edf ¤   bEncrypt=bSign=FALSE;
d9af5a
b94834 ¤   if(ActionCode==PGP_CODE_ENCRYPT)
35a17a ¤   ¤   bEncrypt = TRUE;
4eaf5a
--1d09 000357ca33540110240 Page 15 of Ctxmenu.cpp
50886a ¤   if(ActionCode==PGP_CODE_SIGN)
961a7a ¤   ¤   bSign = TRUE;
d3af5a
7bbaf1 ¤   if(ActionCode==PGP_CODE_ENCRYPT_SIGN)
35a6a3 ¤   ¤   bEncrypt = bSign = TRUE;
1faf5a
aaa238 ¤   if ((ActionCode==PGP_CODE_ENCRYPT)||
38b767 ¤   ¤   (ActionCode==PGP_CODE_SIGN) ··||
0881ae ¤   ¤   (ActionCode==PGP_CODE_ENCRYPT_SIGN))
3cc7a1 ¤   {
5e3682 ¤   ¤   ListHead=0;
9eaf5a
35f6ed ¤   ¤   for(i=0;i<NumFiles && ReturnCode == TRUE;i++)
e95b34 ¤   ¤   {
0706fe ¤   ¤   ¤   DragQueryFile((HDROP) pMedium->hGlobal,·
2b3e06 ·························i,szFile,MAX_PATH);
9bbdb8 ¤   ¤   ¤   AddToFileList(&ListHead,szFile,NULL);
4a0fe4 ¤   ¤   }
69af5a
c7571e ¤   ¤   ReturnCode = EncryptFileList(hwnd,PGPsc,PGPtls,
76a689 ¤   ¤   ¤   ListHead,
71e7b8 ¤   ¤   ¤   bEncrypt,·
b3d072 ¤   ¤   ¤   bSign);
e99371 ¤   }
8aaf5a
fa1a2d ¤   if((ActionCode==PGP_CODE_DECRYPT)||
cdba64 ¤   ···(ActionCode==PGP_CODE_VERIFY_SIG)||
523a03 ¤   ···(ActionCode==PGP_CODE_VERIFY))
59c7a1 ¤   {
343682 ¤   ¤   ListHead=0;
9daf5a
8af6ed ¤   ¤   for(i=0;i<NumFiles && ReturnCode == TRUE;i++)
075b34 ¤   ¤   {
e506fe ¤   ¤   ¤   DragQueryFile((HDROP) pMedium->hGlobal,·
b1c63b ··························i,szFile,MAX_PATH);
8fbdb8 ¤   ¤   ¤   AddToFileList(&ListHead,szFile,NULL);
df0fe4 ¤   ¤   }
efaf5a
5f368a ¤   ¤   ReturnCode = DecryptFileList(hwnd,PGPsc,PGPtls,
5f20f2 ¤   ¤   ¤   ListHead);
479371 ¤   }
d9af5a
e125e0 ¤   if(ActionCode==PGP_CODE_WIPE)
dfc7a1 ¤   {
063cbb ¤   ¤   DWORD FileAttr;
f1af5a
383682 ¤   ¤   ListHead=0;
b5af5a
81f6ed ¤   ¤   for(i=0;i<NumFiles && ReturnCode == TRUE;i++)
5e5b34 ¤   ¤   {
a206fe ¤   ¤   ¤   DragQueryFile((HDROP) pMedium->hGlobal,·
1092a6 ¤   ¤   ¤   ¤   i,szFile,MAX_PATH);
c72b85 ¤   ¤   ¤   ¤
83120b ¤   ¤   ¤   FileAttr = GetFileAttributes(szFile);
b9af5a
094c90 ¤   ¤   ¤   if (FileAttr == 0xFFFFFFFF)
d034a5 ¤   ¤   ¤   ¤   ;
d97dd7 ¤   ¤   ¤   else if (FileAttr & FILE_ATTRIBUTE_SYSTEM)
5c34a5 ¤   ¤   ¤   ¤   ;
ee3894 ¤   ¤   ¤   else if (FileAttr & FILE_ATTRIBUTE_READONLY)
a934a5 ¤   ¤   ¤   ¤   ;
6bbb8c ¤   ¤   ¤   else
5813b9 ¤   ¤   ¤   ¤   AddToFileList(&ListHead,szFile,NULL);
a50fe4 ¤   ¤   }
4faf5a
935193 ¤   ¤   ReturnCode = WipeFileList(hwnd,PGPsc,
1220f2 ¤   ¤   ¤   ListHead);
409371 ¤   }
30af5a
1d902a ¤   ReleaseStgMedium(pMedium);
3baf5a
3592ac ¤   return ReturnCode;
--5481 0015ed9ddea40110240 Page 16 of Ctxmenu.cpp
7aefe6 }
46af5a
f3c23b BOOL CShellExt::AddMenuSeparator(HMENU hMenu, int iPosition)
cabb36 {
9b1a35 ¤   MENUITEMINFO MenuItemInfo;
2de50a ¤   BOOL¤   ¤   ·bRC;
bbaf5a
ed479a ¤   MenuItemInfo.cbSize = sizeof(MENUITEMINFO);
337b02 ¤   MenuItemInfo.fMask ·= MIIM_TYPE;
63b1bb ¤   MenuItemInfo.fType ·= MFT_SEPARATOR;
a6af5a
53c7e4 ¤   bRC = InsertMenuItem(hMenu,
d8acf4 ¤   ¤   ¤   ··¤ ¤   ¤   ¤   ···iPosition,
776d46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···TRUE,
56abdb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···&MenuItemInfo);
45af5a
fae9f2 ¤   if (!bRC) {
39fb60 ¤   ¤   // wow, we couldn't add the separator after Send To...
f38d12 ¤   ¤   ODS("Insert Separator failed...\r\n");
ce98aa ¤   ¤   return FALSE;
de9371 ¤   }
c3c2e7 ¤   return TRUE;
85efe6 }
e1af5a
8cd426 LRESULT CALLBACK InvisiProc(HWND hwnd, UINT msg,·
2b8129 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam, LPARAM lParam)
82bb36 {
039467 ¤   switch(msg)
4cc7a1 ¤   {
fb54c9 ¤   ¤   case WM_CREATE:
965b34 ¤   ¤   {
d68144 ¤   ¤   ¤   return 0;
3e0fe4 ¤   ¤   }
4baf5a
b351d8 ¤   ¤   case WM_QUERYOPEN:
0e5b34 ¤   ¤   {
6d8144 ¤   ¤   ¤   return 0;
290fe4 ¤   ¤   }
f9af5a
b2bd2b #if 0¤  ¤
e32c97 ¤   ¤   case WM_CLOSE:
b0ed49 ¤   ¤   {¤
b446de ¤   ¤   ¤   PostQuitMessage(0);
fa67c5 ¤
2e8144 ¤   ¤   ¤   return 0;
2d0fe4 ¤   ¤   }
9d7454 #endif
709371 ¤   }
514c1c ¤   return DefWindowProc(hwnd, msg, wParam, lParam);
baefe6 }
23af5a
99af5a
1b7e4d /*__Editor_settings____
fcaf5a
e74126 ¤   Local Variables:
947b17 ¤   tab-width: 4
4f0e6c ¤   End:
115f8c ¤   vi: ts=4 sw=4
019e9b ¤   vim: si
07d062 _____________________*/
5eaf5a
--2ac8 001f8d4cc4740110241 Page 1 of FolderContext.reg
98fb29 REGEDIT4
a0af5a
c5abdc [HKEY_CLASSES_ROOT\Folder\shellex\ContextMenuHandlers\{969223c0-26aa-11d0-90ee-¶
d32977 444553540000}]
b60f05 @=""
f8af5a
--fe46 0006b4be93440110242 Page 1 of PGPwctx.reg
98fb29 REGEDIT4
a0af5a
9ba14b [HKEY_CLASSES_ROOT\PGP Armored Encrypted File]
321365 @="PGP Armored Encrypted File"
eeaf5a
6d4671 [HKEY_CLASSES_ROOT\PGP Armored Encrypted File\DefaultIcon]
d63f8b @="pgpsc.dll,-143"
ccaf5a
5b5c5b [HKEY_CLASSES_ROOT\PGP Armored Encrypted File\shell]
d8af5a
84478c [HKEY_CLASSES_ROOT\PGP Armored Encrypted File\shell\open]
4faf5a
04926b [HKEY_CLASSES_ROOT\PGP Armored Encrypted File\shell\open\command]
e5dddb @="C:\\PROGRA~1\\PGP\\PGP50\\pgptools.exe %1"
61af5a
a4bb65 [HKEY_CLASSES_ROOT\PGP Armored Extracted Public Key]
f2056c @="PGP Armored Extracted Public Key"
91af5a
46062d [HKEY_CLASSES_ROOT\PGP Armored Extracted Public Key\DefaultIcon]
705cea @="pgpsc.dll,-147"
b6af5a
d91871 [HKEY_CLASSES_ROOT\PGP Armored Extracted Public Key\shell]
47af5a
630fee [HKEY_CLASSES_ROOT\PGP Armored Extracted Public Key\shell\open]
8eaf5a
8e53ef [HKEY_CLASSES_ROOT\PGP Armored Extracted Public Key\shell\open\command]
75dddb @="C:\\PROGRA~1\\PGP\\PGP50\\pgptools.exe %1"
9faf5a
fb4189 [HKEY_CLASSES_ROOT\PGP Binary Extracted Public Key]
3563fe @="PGP Binary Extracted Public Key"
d6af5a
8d00fe [HKEY_CLASSES_ROOT\PGP Binary Extracted Public Key\DefaultIcon]
af5cea @="pgpsc.dll,-147"
ccaf5a
b87898 [HKEY_CLASSES_ROOT\PGP Binary Extracted Public Key\shell]
dfaf5a
58ec88 [HKEY_CLASSES_ROOT\PGP Binary Extracted Public Key\shell\open]
41af5a
0c17a9 [HKEY_CLASSES_ROOT\PGP Binary Extracted Public Key\shell\open\command]
eddddb @="C:\\PROGRA~1\\PGP\\PGP50\\pgptools.exe %1"
d9af5a
a96fd9 [HKEY_CLASSES_ROOT\PGP Detached Signature File]
7e1e04 @="PGP Detached Signature File"
e1af5a
1fe911 [HKEY_CLASSES_ROOT\PGP Detached Signature File\DefaultIcon]
756557 @="pgpsc.dll,-142"
26af5a
c739d0 [HKEY_CLASSES_ROOT\PGP Detached Signature File\shell]
81af5a
e27d86 [HKEY_CLASSES_ROOT\PGP Detached Signature File\shell\open]
dcaf5a
3c8ba5 [HKEY_CLASSES_ROOT\PGP Detached Signature File\shell\open\command]
10dddb @="C:\\PROGRA~1\\PGP\\PGP50\\pgptools.exe %1"
d8af5a
2bfcbd [HKEY_CLASSES_ROOT\PGP Encrypted File]
854ce5 @="PGP Encrypted File"
69af5a
e28d5a [HKEY_CLASSES_ROOT\PGP Encrypted File\DefaultIcon]
86b38e @="pgpsc.dll,-144"
d8af5a
5d8d14 [HKEY_CLASSES_ROOT\PGP Encrypted File\shell]
0baf5a
2a0891 [HKEY_CLASSES_ROOT\PGP Encrypted File\shell\open]
7baf5a
40ad3c [HKEY_CLASSES_ROOT\PGP Encrypted File\shell\open\command]
0adddb @="C:\\PROGRA~1\\PGP\\PGP50\\pgptools.exe %1"
6aaf5a
c057b1 [HKEY_CLASSES_ROOT\PGP Private Keyring]
d330df @="PGP Private Keyring"
2eaf5a
8cb048 [HKEY_CLASSES_ROOT\PGP Private Keyring\DefaultIcon]
6be952 @="pgpsc.dll,-145"
--d078 0013755378b40110242 Page 2 of PGPwctx.reg
e0af5a
df11c8 [HKEY_CLASSES_ROOT\PGP Private Keyring\shell]
feaf5a
cff96d [HKEY_CLASSES_ROOT\PGP Private Keyring\shell\open]
30af5a
5ddd41 [HKEY_CLASSES_ROOT\PGP Private Keyring\shell\open\command]
86d546 @="C:\\PROGRA~1\\PGP\\PGP50\\pgpkeys.exe %1"
23af5a
b0a89f [HKEY_CLASSES_ROOT\PGP Public Keyring]
d218c7 @="PGP Public Keyring"
afaf5a
6d4644 [HKEY_CLASSES_ROOT\PGP Public Keyring\DefaultIcon]
a90636 @="pgpsc.dll,-146"
eaaf5a
a05850 [HKEY_CLASSES_ROOT\PGP Public Keyring\shell]
dfaf5a
9b728c [HKEY_CLASSES_ROOT\PGP Public Keyring\shell\open]
6aaf5a
c5b482 [HKEY_CLASSES_ROOT\PGP Public Keyring\shell\open\command]
8dd546 @="C:\\PROGRA~1\\PGP\\PGP50\\pgpkeys.exe %1"
37af5a
--7e0d 0013410038740110243 Page 1 of PGPwctxVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
ecf7e9 ············VALUE "FileDescription", "PGP Shell Menu Extensions\0"
2ac1dd ············VALUE "FileVersion", PGPVERSIONSTRING
5faea3 ············VALUE "InternalName", "PGP60mn\0"
ad8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
132bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
89c95f ············VALUE "OriginalFilename", "PGP60mn.dll\0"
549317 ············VALUE "ProductName", PGPPRODUCTNAME
00d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
10f37f ········END
bb7d01 ····END
7a26ab ····BLOCK "VarFileInfo"
175574 ····BEGIN
bf4b11 ········VALUE "Translation", 0x409, 1200
187d01 ····END
6ce0d1 END
6baf5a
7eaf5a
34af5a
--f839 001158305f740110244 Page 1 of PRECOMP.H
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
adffa8 ¤   $Id: PRECOMP.H,v 1.11.8.1 1998/11/12 03:12:56 heller Exp $
8ef7f7 ____________________________________________________________________________*/
cb519a #ifndef Included_PRECOMP_h¤ /* [ */
2d5498 #define Included_PRECOMP_h
911bcc /*++
78af5a
9c4678 Module Name:
39af5a
773fd4 ····precomp.h
faaf5a
0d57d7 Abstract:
82af5a
6ecab2 ····This file includes all the headers required to build the dll
a23a9d ····to ease the process of building a precompiled header.
01af5a
35d16a Author:
08af5a
6faf5a
4a8999 Revision History:
6aaf5a
78af5a
1367d9 --*/
19af5a
ab2a68 #define WIN32_LEAN_AND_MEAN
bbf451 #define PGPExport __declspec( dllimport )
1caf5a
f02de6 // System headers
f85655 #include <windows.h>
683d0b #include <windowsx.h>
e8bea3 #include <stdlib.h>
56feb2 #include <stdio.h>
1bbea3 #include <stdlib.h>
4c8f85 #include <assert.h>·
f8324c #include <string.h>
007609 #include <ShellAPI.h>
9657d1 #include <Direct.h>
75af5a
38fee6 #define UNFINISHED_CODE_ALLOWED 1
12af5a
4f8cbe // PGPlib headers
8baf5a
ac9de0 #include "..\include\PGPsc.h"
e7af5a
2341ed #endif /* ] Included_PRECOMP_h */
4daf5a
8caf5a
317e4d /*__Editor_settings____
ffaf5a
7d4126 ¤   Local Variables:
e07b17 ¤   tab-width: 4
e60e6c ¤   End:
355f8c ¤   vi: ts=4 sw=4
6a9e9b ¤   vim: si
59d062 _____________________*/
15af5a
--47e9 000311e9fa540110245 Page 1 of Pgpwctx.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
28195d ¤   $Id: Pgpwctx.cpp,v 1.12.8.1 1998/11/12 03:12:57 heller Exp $
51f7f7 ____________________________________________________________________________*/
9caf5a
6e8bef // pgpwctx.cpp¤ ¤   Context Menu Handler
5eaf5a
e81f3d // Copied from shellext.cpp in Microsoft Shellext sample.
beaf5a
fa10d5 // Purpose: ·Implements the class factory code as well as CShellExt::QI,
dbddc9 // ··········CShellExt::AddRef and CShellExt::Release code.
245ed8 #include "precomp.h"
c8af5a
f27e4e #include "priv.h"
45ad3a //#include "pgpwctx.hpp"
a88031 #include "resource.h"
b8af5a
60465d //
e12897 // Initialize GUIDs (should be done only and at-least once per DLL/EXE)
6f465d //
90c28b #pragma data_seg(".text")
c9841d #define INITGUID
cb0cbc #include <initguid.h>
48961d #include <shlguid.h>
e11abb DEFINE_GUID(CLSID_PGPext, 0x969223c0, 0x26aa, 0x11d0,
decf7d ¤   ¤   ¤   0x90, 0xee, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
38d116 #pragma data_seg()
f26e17 #include "pgpwctx.hpp"
08af5a
17a110 extern HWND g_hwndShell;
f1af5a
05465d //
b4e49e // Global variables
4e465d //
c69c44 UINT ·····g_cRefThisDll = 0; ···// Reference count of this DLL.
511fbf HINSTANCE g_hmodThisDll = NULL;¤// Handle to this DLL itself.
274c85 HMENU¤  ¤   hPlaintextMenu;
68679c HMENU¤  ¤   hEncryptedMenu;
be7729 HMENU¤  ¤   hKeyfileMenu;
fcf776 HANDLE¤ ¤   hPGPThreadMutex = NULL;
8f35e2 void¤   ¤   *PGPsc=NULL;
7efc66 void¤   ¤   *PGPtls=NULL;
afaf5a
255f3b static FILE * pLog = NULL;
cdaf5a
3c2e71 //extern "C" int APIENTRY
952f19 extern int APIENTRY
30a426 DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
59bb36 {
32a737 ····if (dwReason == DLL_PROCESS_ATTACH)
cd3b37 ····{
e41f29 #ifdef _DEBUG
76f098 //¤ ¤   pLog = fopen("d:\\CtxLog.txt", "wb");
974068 ········ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
987454 #endif
62f59b ········// Extension DLL one-time initialization
4aaf5a
0cbbc1 ········g_hmodThisDll = hInstance;
9baf5a
1b6fe7 ····}
605737 ····else if (dwReason == DLL_PROCESS_DETACH)
353b37 ····{
4a9246 ········ODS("In DLLMain, DLL_PROCESS_DETACH\r\n");
afa5da ¤   ¤   if (pLog)
f6eec5 ¤   ¤   ¤   fclose(pLog);
bcaf5a
706fe7 ····}
31af5a
--4a99 0009001673240110245 Page 2 of Pgpwctx.cpp
7998b0 ····return 1; ··// ok
d0efe6 }
0eaf5a
f2e221 //---------------------------------------------------------------------------
3120a3 // DllCanUnloadNow
56e221 //---------------------------------------------------------------------------
27af5a
fd02f4 STDAPI DllCanUnloadNow(void)
c1bb36 {
10e56f ····ODS("In DLLCanUnloadNow\r\n");
eb5d6a ¤   BOOL CanUnload = S_FALSE;
b29dd1 ¤   UINT CacheSecs=0;
8e38f2 ¤   /*We don't want to unload until there are no·
ea7cdc ¤   ·*more references to this DLL, and until
45b88d ¤   ·*the PGP pass phrase caching thread has ended.
faa4e3 ¤   ·*/
4f9f20 ¤   if(PGPsc!=0)
978fa5 ¤   ¤   CacheSecs=PGPscQueryCacheSecsRemaining();
11af5a
e8d008 ¤   if(!g_cRefThisDll &&
fa09bb ¤   ···(CacheSecs==0) &&
ba6d3f ¤   ···(!hPGPThreadMutex ||·
816918 ¤   ···(WaitForSingleObject(hPGPThreadMutex, 0) != WAIT_TIMEOUT)))
f0c7a1 ¤   {
283bb8 ¤   ¤   CanUnload = S_OK;
15deab ¤   ¤   if(PGPsc!=0)
385b34 ¤   ¤   {
6adceb ¤   ¤   ¤   // Since the cache will be gone, we don't have to
8a58dc ¤   ¤   ¤   // worry about looking for messages
bd3c95 ¤   ¤   ¤   DestroyWindow(g_hwndShell);
c87d9e ¤   ¤   ¤   g_hwndShell=NULL;
3caf5a
06f790 ¤   ¤   ¤   UninitPGPsc(NULL,PGPsc,PGPtls);
fa0fe4 ¤   ¤   }
00eeef ¤   ¤   PGPsc=0;
98e715 ¤   ¤   PGPtls=0;
8e9371 ¤   }
1daf5a
cff75c ····return (CanUnload);
fa17b5 /*¤ return(S_FALSE);*/
36efe6 }
2baf5a
583e26 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
b9bb36 {
6f4e7f ····HRESULT hRes;
86da63 ¤   ODS("In DllGetClassObject\r\n");
77af5a
3d1825 ····if (g_cRefThisDll)¤ ¤   // if factory or extension still active
ac6a5b ¤   ¤   return CLASS_E_CLASSNOTAVAILABLE;
a3af5a
cf2c76 ¤   *ppvOut = NULL;
a6af5a
a9486d ····if (IsEqualIID(rclsid, CLSID_PGPext))
c63b37 ····{
b7d251 ········CPGPClassFactory *pcf = new CPGPClassFactory;
f7af5a
1f6649 ········if (pcf)
2a5b34 ¤   ¤   {
bcfb68 ¤   ¤   ¤   hRes = pcf->QueryInterface(riid, ppvOut);
f0d81c ¤   ¤   ¤   return hRes;
080fe4 ¤   ¤   }
7e6fe7 ····}
6eaf5a
2b5ad5 ····return CLASS_E_CLASSNOTAVAILABLE;
c2efe6 }
31af5a
64914e CPGPClassFactory::CPGPClassFactory()
95bb36 {
6127a8 ····ODS("CPGPClassFactory::CPGPClassFactory()\r\n");
8caf5a
be91e8 ····m_cRef = 0L;
90af5a
--0ff1 0002f5eb0a440110245 Page 3 of Pgpwctx.cpp
6fdd1f ····g_cRefThisDll++;¤
bdefe6 }
a90753 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
79f554 CPGPClassFactory::~CPGPClassFactory()¤  ¤   ¤   ¤
2ebb36 {
4e44cd ····ODS("CPGPClassFactory::~CPGPClassFactory()\r\n");
9e1b56 ····g_cRefThisDll--;
5defe6 }
3faf5a
8b05e1 STDMETHODIMP CPGPClassFactory::QueryInterface(REFIID riid,
bd905f ···················································LPVOID FAR *ppv)
5fbb36 {
76175e ····ODS("CPGPClassFactory::QueryInterface()\r\n");
2caf5a
74e0d5 ····*ppv = NULL;
f8af5a
4fb04f ····// Any interface on this object is the object pointer
8aaf5a
5e5449 ····if (IsEqualIID(riid, IID_IUnknown) ||·
2225ab ¤   ¤   IsEqualIID(riid, IID_IClassFactory))
e83b37 ····{
3c7c66 ········*ppv = (LPCLASSFACTORY)this;
bdaf5a
57c247 ········AddRef();
1eaf5a
acbeff ········return NOERROR;
586fe7 ····}
cfaf5a
dd2438 ····return E_NOINTERFACE;
6b1862 }¤
f4af5a
c785b4 STDMETHODIMP_(ULONG) CPGPClassFactory::AddRef()
d6bb36 {
6e86e9 ····return ++m_cRef;
2befe6 }
93af5a
cec75f STDMETHODIMP_(ULONG) CPGPClassFactory::Release()
f7bb36 {
95f4d0 ····ODS("CPGPClassFactory::Release()\r\n");
95e8c3 ····if (--m_cRef)
882ec3 ········return m_cRef;
f9af5a
8c4d49 ····delete this;
47af5a
d836b3 ····return 0L;
1cefe6 }
4caf5a
fc48ef STDMETHODIMP CPGPClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
a3490e ······················································REFIID riid,
f28761 ······················································LPVOID *ppvObj)
2cbb36 {
ec17be ····ODS("CPGPClassFactory::CreateInstance()\r\n");
deaf5a
2d8147 ····*ppvObj = NULL;
a3af5a
abde9d ····// Shell extensions typically don't support aggregation (inheritance)
58af5a
a54990 ····if (pUnkOuter)
5bb6c0 ····¤   return CLASS_E_NOAGGREGATION;
acaf5a
a2cbe4 ····// Create the main shell extension object. ·
fc19fe ¤   // The shell will then call
5df50b ····// QueryInterface with IID_IShellExtInit--
82d8ef ¤   // this is how shell extensions are
1396df ····// initialized.
f0af5a
a81965 ····LPCSHELLEXT pShellExt = new CShellExt(); ·//Create the CShellExt object
faaf5a
b8eccc ····if (NULL == pShellExt)
3e35de ····¤   return E_OUTOFMEMORY;
95af5a
2f8e70 ····return pShellExt->QueryInterface(riid, ppvObj);
--3b26 00026cd649240110245 Page 4 of Pgpwctx.cpp
7aefe6 }
46af5a
8eaf5a
8e6273 STDMETHODIMP CPGPClassFactory::LockServer(BOOL fLock)
a8bb36 {
e00110 ····return NOERROR;
74efe6 }
92af5a
8eb516 // *********************** CShellExt *************************
37eb1a CShellExt::CShellExt()
05bb36 {
d491d8 ····ODS("CShellExt::CShellExt()\r\n");
5faf5a
8091e8 ····m_cRef = 0L;
2198fe ····m_pDataObj = NULL;
47af5a
9c8615 ····g_cRefThisDll++;
fdefe6 }
baaf5a
e474e0 CShellExt::~CShellExt()
ddbb36 {
f9f538 ····ODS("CShellExt::~CShellExt()\r\n");
e0af5a
121b56 ····g_cRefThisDll--;
fbefe6 }
2daf5a
e992cd STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
68bb36 {
d5e0d5 ····*ppv = NULL;
5faf5a
219b94 ····if (IsEqualIID(riid, IID_IShellExtInit) ||
ac13bd ¤   ¤   IsEqualIID(riid, IID_IUnknown))
383b37 ····{
455494 ········ODS("CShellExt::QueryInterface()==>IID_IShellExtInit\r\n");
17af5a
8cf46a ····¤   *ppv = (LPSHELLEXTINIT)this;
e96fe7 ····}
daaf22 ····else if (IsEqualIID(riid, IID_IContextMenu))
133b37 ····{
84f53f ········ODS("CShellExt::QueryInterface()==>IID_IContextMenu\r\n");
e7af5a
151fe2 ········*ppv = (LPCONTEXTMENU)this;
f56fe7 ····}
3def10 ····if (*ppv)
573b37 ····{
99c247 ········AddRef();
64af5a
53beff ········return NOERROR;
2f6fe7 ····}
6daf5a
49e50a ····ODS("CShellExt::QueryInterface()==>Unknown Interface!\r\n");
b8af5a
055ee8 //¤ delete this; ·removed by wjb for IE4?
8aaf5a
80c4a0 ¤   return E_NOINTERFACE;
49efe6 }
88af5a
1cb6a1 STDMETHODIMP_(ULONG) CShellExt::AddRef()
57bb36 {
bc7b89 ····ODS("CShellExt::AddRef()\r\n");
52af5a
c186e9 ····return ++m_cRef;
e9efe6 }
dcaf5a
dc8040 STDMETHODIMP_(ULONG) CShellExt::Release()
d4bb36 {
c25ec9 ····ODS("CShellExt::Release()\r\n");
91af5a
98e8c3 ····if (--m_cRef)
dd2ec3 ········return m_cRef;
19af5a
266cf2 ····if (hSubMenu)
--c8e2 0019b95cc7840110245 Page 5 of Pgpwctx.cpp
1656a5 ¤   ¤   if (!(DeleteMenu(hParentMenu, (UINT)hSubMenu, MF_BYCOMMAND)))
190b0e ¤   ¤   ¤   ODS("DeleteMenu() failed.\r\n");
d60e1d ¤   ¤   else
1ddd55 ¤   ¤   ¤   ODS("DeleteMenu() succeeded.\r\n");
8faf5a
1dc173 ····if (m_pDataObj)
77225a ········m_pDataObj->Release();
f4af5a
4e0fbf ¤   delete this;
a7af5a
4736b3 ····return 0L;
99efe6 }
6baf5a
4c1f29 #ifdef _DEBUG
551be9 void ODS(LPCSTR msg)
dcbb36 {
34a7cd ¤   //MessageBox(NULL, msg, "Hmmmm", MB_OK);
64efe6 }
017454 #endif
d1af5a
b2af5a
cd7e4d /*__Editor_settings____
a2af5a
334126 ¤   Local Variables:
f37b17 ¤   tab-width: 4
340e6c ¤   End:
5c5f8c ¤   vi: ts=4 sw=4
189e9b ¤   vim: si
9bd062 _____________________*/
--4009 00038bf3fd740110246 Page 1 of Pgpwctx.hpp
2c461b /*¤ Confidential to PGP.¤   */
4fe8a8 /*¤ Copyright (c) 1995 PGP.¤*/
70fac2 /* ·$Id: Pgpwctx.hpp,v 1.4 1997/08/06 22:29:24 wjb Exp $ */
23af5a
486f07 // pgpwctx.hpp¤ ¤   Context Menu Handler header file
1caf5a
a1465d //
401d1f // The class ID of this Shell extension class.
be465d //
48d4c8 // class id: ·969223c0-26aa-11d0-90ee-444553540000
2b465d //
a0465d //
09940b // NOTE!!! ·If you use this shell extension as a starting point,·
731f56 // ·········you MUST change the GUID below. ·Simply run UUIDGEN.EXE
e9be73 // ·········to generate a new GUID.
3f465d //
1a1e72 ··································
d15a6b //#define ODS(sz) OutputDebugString(sz)
dc6b3e //#define ODS(sz) MessageBox(GetFocus(), sz, "PGP Shell Extension", MB_OK)
d51f29 #ifdef _DEBUG
6f7af4 void ODS(LPCSTR msg);
21db21 #else
8551dc #define ODS(sz)
707454 #endif
c9af5a
497f13 #ifndef _PGPWCTX_HPP
4b8fad #define _PGPWCTX_HPP
5baf5a
c67509 // this class factory object creates·
e506c9 // context menu handlers for Windows 95 shell
ab26cb class CPGPClassFactory : public IClassFactory
debb36 {
17a2d3 protected:
ebf8a8 ¤   ULONG¤  m_cRef;
baaf5a
465ed4 public:
9539af ¤   CPGPClassFactory();
e3f25b ¤   ~CPGPClassFactory();
1baf5a
9d06e7 ¤   //IUnknown members
2b2893 ¤   STDMETHODIMP¤   ¤   ¤   QueryInterface(REFIID, LPVOID FAR *);
ffb279 ¤   STDMETHODIMP_(ULONG)¤   AddRef();
01ebc8 ¤   STDMETHODIMP_(ULONG)¤   Release();
5baf5a
acb8cb ¤   //IClassFactory members
0367c1 ¤   STDMETHODIMP¤   ¤   CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *);
079fae ¤   STDMETHODIMP¤   ¤   LockServer(BOOL);
dfaf5a
4782f7 };
01b046 typedef CPGPClassFactory *LPCPGPCLASSFACTORY;
37af5a
521946 // this is the actual OLE Shell context menu handler
4eb036 class CShellExt : public IContextMenu,·
b9f9ce ·························IShellExtInit·
3fbb36 {
3b5ed4 public:
eaaf5a
58a2d3 protected:
2ee3c2 ¤   ULONG ·······m_cRef;
e79bf0 ¤   LPDATAOBJECT m_pDataObj;
77ab3a ····STGMEDIUM¤  ·medium;
018406 ····char ········m_szFileUserClickedOn[MAX_PATH];
20af5a
a8b99e ¤   HMENU¤  ¤   ·hParentMenu;
7fe7d8 ¤   HMENU¤  ¤   ·hSubMenu;
cf496e ¤   UINT¤   ¤   ·SubMenuItems;
0e0eb1 ¤   char¤   ¤   ·SubMenuType[64];
141028 ¤   void CreateEncryptedMenu(UINT idCmdFirst);
5cdd4f ¤   void CreateKeyfileMenu(UINT idCmdFirst);
c28c30 ¤   void CreateViewKeyringMenu(UINT idCmdFirst);
41095a ¤   void CreatePlaintextMenu(UINT idCmdFirst);
383a2c ¤   void CreateVerifyMenu(UINT idCmdFirst);
--5980 0012aed52e740110246 Page 2 of Pgpwctx.hpp
fe91b1 ¤   void CreateDirectoryMenu(UINT idCmdFirst);
a5af5a
725ed4 public:
beb5c6 ¤   CShellExt();
e654eb ¤   ~CShellExt();
a6af5a
8a06e7 ¤   //IUnknown members
ea2893 ¤   STDMETHODIMP¤   ¤   ¤   QueryInterface(REFIID, LPVOID FAR *);
49b279 ¤   STDMETHODIMP_(ULONG)¤   AddRef();
7debc8 ¤   STDMETHODIMP_(ULONG)¤   Release();
40af5a
5d0b24 ¤   //IShell members
8af665 ¤   STDMETHODIMP¤   ¤   ¤   QueryContextMenu(HMENU hMenu,
fb9cd8 ¤   ·········································UINT indexMenu,·
7b8b88 ¤   ·········································UINT idCmdFirst,
78ae71 ·············································UINT idCmdLast,·
1cd594 ·············································UINT uFlags);
69af5a
97f8d3 ¤   STDMETHODIMP¤   ¤   ¤   InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
41af5a
60cd48 ¤   STDMETHODIMP¤   ¤   ¤   GetCommandString(UINT idCmd,·
ad08c3 ¤   ·········································UINT uFlags,·
b3b636 ¤   ·········································UINT FAR *reserved,·
5aa254 ·············································LPSTR pszName,·
578fe1 ·············································UINT cchMax);
c4af5a
675468 ¤   //IShellExtInit methods
3a7bed ¤   STDMETHODIMP¤   ¤   ····Initialize(LPCITEMIDLIST pIDFolder,·
b6595f ¤   ···································LPDATAOBJECT pDataObj,·
275949 ¤   ···································HKEY hKeyID);
02af5a
9f0fb9 private:
55dffb ¤   BOOL AddMenuSeparator(HMENU hMenu, int iPosition);
c382f7 };
07e3d6 typedef CShellExt *LPCSHELLEXT;
29af5a
2ac2fc #endif // _PGPWCTX_HPP
--79dc 001c2d378f340110247 Page 1 of Priv.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7cb75f ¤   $Id: Priv.h,v 1.3.16.1 1998/11/12 03:12:57 heller Exp $
cef7f7 ____________________________________________________________________________*/
94eaab #ifndef Included_PRIV_h¤/* [ */
6e9ec4 #define Included_PRIV_h
8aaf5a
fa7878 //--------------------------------------------------------------
e6a798 // common user interface routines
bf465d //
e9465d //
897878 //--------------------------------------------------------------
acaf5a
5dbf87 #ifndef STRICT
11a585 #define STRICT
6e7454 #endif
f8af5a
9a72c7 #define INC_OLE2 ·······// WIN32, get ole2 from windows.h
46af5a
f15655 #include <windows.h>
c53d0b #include <windowsx.h>
11f3cf #include <shlobj.h>
c4af5a
ed3753 #define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USH¶
d992cc ORT)(i)))
aeaf5a
51af5a
e4a981 #endif /* ] Included_PRIV_h */
f8af5a
3caf5a
197e4d /*__Editor_settings____
25af5a
164126 ¤   Local Variables:
557b17 ¤   tab-width: 4
a70e6c ¤   End:
425f8c ¤   vi: ts=4 sw=4
499e9b ¤   vim: si
c2d062 _____________________*/
--4cbd 0012c9fb06d40110248 Page 1 of RESOURCE.H
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
d05492 // Used by pgpwctx.rc
ea465d //
e48597 #define IDD_WORKING ····················101
9547a7 #define IDI_ICON_SIG ···················102
e49a4d #define IDI_ICON_ASC ···················103
535a5a #define IDI_ICON_PGP ···················104
155683 #define IDI_ICON_PRVKR ·················105
865825 #define IDI_ICON_PUBKR ·················106
3a4634 #define IDI_ICON_AEXPK ·················107
7b1779 #define IDD_RESULTS ····················124
7ce3f1 #define IDC_PROGRESS ···················1000
4b1b2c #define IDC_FOO_A_RAMA ·················1001
f51c93 #define IDC_PROGRESS_TEXT ··············1001
36ea43 #define IDC_DECRYPTION_RESULTS ·········1005
c213af #define IDS_SIGNATURE_ERROR ············5000
d58c61 #define IDS_OUT_OF_MEMORY ··············5001
47ab84 #define IDS_FUNCTION_NOT_ENABLED ·······5002
1c7e2e #define IDS_CANNOT_SIGN_WITH_UNCERTIFIED_KEY 5003
c9b40a #define IDS_CANNOT_DECRYPT_WITH_UNCERTIFIED_KEY 5004
c02f90 #define IDS_CANNOT_ENCRYPT_WITH_UNCERTIFIED_KEY 5005
434878 #define IDS_CATCHALL_ERROR_MESSAGE ·····5006
0bda91 #define IDS_UNABLE_TO_MATCH_ID ·········5007
2f9234 #define IDS_RSA_ENCR_ERROR ·············5008
477539 #define IDS_INVALID_FILE_OP_ERROR ······5009
1f7faf #define IDS_NO_PGP_DATA ················5010
43037b #define IDS_NO_DATA_TO_ENCRYPT ·········5011
63a402 #define IDS_ENTER_PHRASE ···············5012
44ce37 #define IDS_WRONG_PHRASE ···············5013
cbaf5a
af11aa // Next default values for new objects
65ac6a //·
3cf860 #ifdef APSTUDIO_INVOKED
e53f23 #ifndef APSTUDIO_READONLY_SYMBOLS
f57e6b #define _APS_NEXT_RESOURCE_VALUE ·······109
01611c #define _APS_NEXT_COMMAND_VALUE ········40001
cdc55c #define _APS_NEXT_CONTROL_VALUE ········1002
951285 #define _APS_NEXT_SYMED_VALUE ··········101
e67454 #endif
2c7454 #endif
--b77b 00097f20bd440110249 Page 1 of SClink.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
5fc25a ¤   SClink.cpp
b6af5a
349fe7 ¤   Provides soft linking here so no delay on menu right clicks
6baf5a
75a5bf ¤   $Id: SClink.cpp,v 1.6.2.1.2.1 1998/11/12 03:12:58 heller Exp $
05f7f7 ____________________________________________________________________________*/
86af5a
545ed8 #include "precomp.h"
9daf5a
e29daa HINSTANCE hSC_DLL=NULL;
5caf5a
4a1f9f typedef BOOL (*ENCRYPTFILELIST)(HWND,void *,void *,
b7846e ¤   ¤   ¤   ¤   ¤   ·FILELIST *,BOOL,BOOL);
1faf5a
0d9260 BOOL EncryptFileList(HWND hwnd,void *PGPsc,void *PGPtls,
ace61f ¤   ¤   ¤   ¤   ¤   ·FILELIST *ListHead,BOOL bEncrypt,BOOL bSign)
e9bb36 {
d3aa3b ¤   ENCRYPTFILELIST SCEncryptFileList;
c28e46 ¤   BOOL RetVal;
eeaf5a
5ca118 ¤   SCEncryptFileList ·= (ENCRYPTFILELIST)GetProcAddress(hSC_DLL,"EncryptFileLi¶
0225cf st");
6aaf5a
f90099 ¤   RetVal=(SCEncryptFileList)(hwnd,PGPsc,PGPtls,
b84812 ¤   ¤   ¤   ¤   ¤   ·ListHead,bEncrypt,bSign);
8baf5a
9342d7 ¤   return RetVal;
bbefe6 }
b1af5a
06f82c typedef BOOL (*DECRYPTFILELIST)(HWND,void *,void *,FILELIST *);
16af5a
272d83 BOOL DecryptFileList(HWND hwnd,void *PGPsc,void *PGPtls,FILELIST *ListHead)
8ebb36 {
0b1145 ¤   DECRYPTFILELIST SCDecryptFileList;
a78e46 ¤   BOOL RetVal;
00af5a
d1a841 ¤   SCDecryptFileList ·= (DECRYPTFILELIST)GetProcAddress(hSC_DLL,"DecryptFileLi¶
b325cf st");
09af5a
20d6c2 ¤   RetVal=(SCDecryptFileList)(hwnd,PGPsc,PGPtls,ListHead);
40af5a
8b42d7 ¤   return RetVal;
8cefe6 }
d8af5a
65b0b6 typedef BOOL (*WIPEFILELIST)(HWND,void *,FILELIST *);
04af5a
8d84fe BOOL WipeFileList(HWND hwnd,void *PGPsc,FILELIST *ListHead)
01bb36 {
e03137 ¤   WIPEFILELIST SCWipeFileList;
bd8e46 ¤   BOOL RetVal;
abaf5a
fe589e ¤   SCWipeFileList ·= (WIPEFILELIST)GetProcAddress(hSC_DLL,"WipeFileList");
52af5a
6e7ae3 ¤   RetVal=(SCWipeFileList)(hwnd,PGPsc,ListHead);
abaf5a
5142d7 ¤   return RetVal;
f6efe6 }
8daf5a
ab22d7 typedef BOOL (*ADDTOFILELIST)(FILELIST **,char *,BOOL *);
c5af5a
9f8896 BOOL AddToFileList(FILELIST **filelist,char *filename,BOOL *UserCancel)
6dbb36 {
85725f ¤   ADDTOFILELIST SCAddToFileList;
c18e46 ¤   BOOL RetVal;
e1af5a
a29b8e ¤   SCAddToFileList ·= (ADDTOFILELIST)GetProcAddress(hSC_DLL,"AddToFileList");
b3af5a
97a9f2 ¤   RetVal=(SCAddToFileList)(filelist,filename,UserCancel);
--027e 0005dd2c5c740110249 Page 2 of SClink.cpp
e0af5a
1a42d7 ¤   return RetVal;
c1efe6 }
cbaf5a
50d513 typedef BOOL (*FREEFILELIST)(FILELIST *);
39af5a
ed21ef BOOL FreeFileList(FILELIST *FileList)
2dbb36 {
32e345 ¤   FREEFILELIST SCFreeFileList;
5d8e46 ¤   BOOL RetVal;
19af5a
f2f545 ¤   SCFreeFileList ·= (FREEFILELIST)GetProcAddress(hSC_DLL,"FreeFileList");
56af5a
2a890e ¤   RetVal=(SCFreeFileList)(FileList);
d2af5a
2742d7 ¤   return RetVal;
8defe6 }
36af5a
6189aa typedef BOOL (*INITPGPSC)(HWND,void **,void **);
7faf5a
6d0af7 BOOL InitPGPsc(HWND hwnd,void **PGPsc,void **PGPtls)
62bb36 {
94eb50 ¤   INITPGPSC SCInitPGPsc;
6c8e46 ¤   BOOL RetVal;
9eaf5a
308af5 ····hSC_DLL = LoadLibrary("PGP60SC.DLL");
c06ea8 ····if (hSC_DLL == 0)·
e2c7a1 ¤   {
e0a8c3 ¤   ¤   MessageBox(hwnd,"LoadLibrary() failed: Unable to locate PGP60SC.DLL!",
0a535d ¤   ¤   ¤   "PGP Error",MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
74af5a
6798aa ¤   ¤   return FALSE;
db6fe7 ····}
fdaf5a
7d82e4 ¤   SCInitPGPsc ·= (INITPGPSC)GetProcAddress(hSC_DLL,"InitPGPsc");
a2af5a
d687f2 ¤   RetVal=(SCInitPGPsc)(hwnd,PGPsc,PGPtls);
95af5a
6542d7 ¤   return RetVal;
9eefe6 }
2daf5a
5e3375 typedef BOOL (*UNINITPGPSC)(HWND,void *,void *);
bdaf5a
312650 BOOL UninitPGPsc(HWND hwnd,void *PGPsc,void *PGPtls)
e0bb36 {
52f267 ¤   UNINITPGPSC SCUninitPGPsc;
6542a8 ¤   BOOL RetVal=TRUE;
52af5a
d2edf6 ¤   if(PGPsc)
e5c7a1 ¤   {
ec00a0 ¤   ¤   SCUninitPGPsc ·= (UNINITPGPSC)GetProcAddress(hSC_DLL,"UninitPGPsc");
b6af5a
e0dafa ¤   ¤   RetVal=(SCUninitPGPsc)(hwnd,PGPsc,PGPtls);
189371 ¤   }
56af5a
0cabe1 ¤   if(hSC_DLL)
4ac7a1 ¤   {
ee954c ¤   ¤   FreeLibrary(hSC_DLL);
b1a716 ¤   ¤   hSC_DLL=NULL;
bf9371 ¤   }
a7af5a
2142d7 ¤   return RetVal;
29efe6 }
ebaf5a
cd5f4d typedef UINT (*PGPSCQUERYCACHESECSREMAINING)(void);
2baf5a
ccb35f UINT PGPscQueryCacheSecsRemaining (void)
2cbb36 {
f85069 ¤   PGPSCQUERYCACHESECSREMAINING SCPGPscQueryCacheSecsRemaining;
8925f2 ¤   UINT RetVal;
84af5a
5d5aad ¤   SCPGPscQueryCacheSecsRemaining ·=·
--5903 001bd5dbe9240110249 Page 3 of SClink.cpp
ce4fb2 ¤   ¤   (PGPSCQUERYCACHESECSREMAINING)GetProcAddress(hSC_DLL,"PGPscQueryCacheSe¶
dee4fd csRemaining");
4caf5a
557d23 ¤   RetVal=(SCPGPscQueryCacheSecsRemaining)();
e7af5a
fb42d7 ¤   return RetVal;
e4efe6 }
c6af5a
e8548d typedef BOOL (*CHECKFORPURGE)(UINT,WPARAM);
39af5a
7b6c0e BOOL CheckForPurge (UINT uMsg,WPARAM wParam)
edbb36 {
67a150 ¤   CHECKFORPURGE SCCheckForPurge;
e925f2 ¤   UINT RetVal;
ddaf5a
1cc71b ¤   SCCheckForPurge ·=·
ef7c94 ¤   ¤   (CHECKFORPURGE)GetProcAddress(hSC_DLL,"CheckForPurge");
8eaf5a
213d04 ¤   RetVal=(SCCheckForPurge)(uMsg,wParam);
d2af5a
b542d7 ¤   return RetVal;
6cefe6 }
42af5a
d57e4d /*__Editor_settings____
b0af5a
a54126 ¤   Local Variables:
eb7b17 ¤   tab-width: 4
b50e6c ¤   End:
7a5f8c ¤   vi: ts=4 sw=4
6b9e9b ¤   vim: si
e0d062 _____________________*/
bdaf5a
--69e7 000fcf4cdf24011024a Page 1 of Shexinit.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8df0b0 ¤   $Id: Shexinit.cpp,v 1.5.16.1 1998/11/12 03:12:59 heller Exp $
51f7f7 ____________________________________________________________________________*/
d2af5a
923f7e // ·MODULE: ··shexinit.cpp
e8465d //
fc57bd // ·PURPOSE: ··Implements the IShellExtInit member·
9a0783 // ············function necessary to support
36bf56 // ············the context menu and property sheet
4d0655 // ············portions of this shell extension. ·
0c465d //
9b5ed8 #include "precomp.h"
6aaf5a
4caf5a
417e4e #include "priv.h"
f26e17 #include "pgpwctx.hpp"
96af5a
1a465d //
154668 // ·FUNCTION: CShellExt::Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY)
91465d //
c69f03 // ·PURPOSE: Called by the shell when initializing a context menu or property
c21071 // ··········sheet extension.
95465d //
d8404c // ·PARAMETERS:
7d4fc0 // ···pIDFolder - Specifies the parent folder
5a6947 // ···pDataObj ·- Spefifies the set of items selected in that folder.
953491 // ···hRegKey ··- Specifies the type of the focused item in the selection.
07465d //
5f2869 // ·RETURN VALUE:
01465d //
59720d // ···NOERROR in all cases.
36465d //
b1a8d6 // ·COMMENTS: ··Note that at the time this function is called,·
1c7aa6 // ·············we don't know (or care) what type of shell extension
e28bea // ·············is being initialized. It could be a context menu or
9a114a // ·············a property sheet.
7f465d //
56af5a
e62828 STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder,
590e8f ···································LPDATAOBJECT pDataObj,
3f2699 ···································HKEY hRegKey)
52bb36 {
2e3ccb ····FORMATETC fmte = {CF_HDROP,
4ca1db ········¤   ··········(DVTARGETDEVICE FAR *)NULL,
5917c7 ········¤   ··········DVASPECT_CONTENT,
064994 ········¤   ··········-1,
05f32a ········¤   ··········TYMED_HGLOBAL·
55baf3 ········¤   ·········};
8bfd22 ¤   HRESULT hres = 0;
1eaf5a
4ee7de ····ODS("CShellExt::Initialize()\r\n");
ddaf5a
7972fe ····// Initialize can be called more than once
dcaf5a
b0c173 ····if (m_pDataObj)
1d3a7b ····¤   m_pDataObj->Release();
a1af5a
a5299f ····// duplicate the object pointer and registry handle
f5af5a
12a196 ····if (pDataObj)
ca3b37 ····{
80a676 ····¤   m_pDataObj = pDataObj;
e75f58 ····¤   pDataObj->AddRef();
cd6fe7 ····}
a4af5a
a27cf3 ····// get the file name
fcc310 ¤   m_szFileUserClickedOn[0] = '\0';¤   // start with empty string
--364d 001438a270d4011024a Page 2 of Shexinit.cpp
c5df1a ¤   medium.tymed = TYMED_HGLOBAL;
f31a1d ¤   medium.pUnkForRelease = NULL;
50b9ed ¤   medium.hGlobal = NULL;
302eab ¤   if (m_pDataObj) ·
e9b279 ¤   ¤   //Paranoid check, m_pDataObj should have something by now...
7dd73e ·······hres = m_pDataObj->GetData(&fmte, &medium);
63af5a
94a81c ····if (SUCCEEDED(hres))
313b37 ····{
f30e68 ········//Find out how many files the user has selected...
100f36 ········UINT cbFiles = 0;
58e514 ········if (medium.hGlobal)
96923d ············cbFiles = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, 0, 0);
8daf5a
4a5b23 ········//Get the name of the first file the user has clicked on
1a61e2 ¤   ¤   if (cbFiles)
eba5e6 ¤   ¤   ¤   DragQueryFile((HDROP)medium.hGlobal,·
0070be ·····························0,·
7c2264 ·····························m_szFileUserClickedOn,
435e00 ·····························sizeof(m_szFileUserClickedOn));
70af5a
5c63d0 ¤   ¤   ODS(m_szFileUserClickedOn);
075d08 ¤   ¤   ODS("\r\n");
889371 ¤   }
17d83c ·
ec2e2b ¤   return NOERROR;
64efe6 }
8daf5a
d3af5a
217e4d /*__Editor_settings____
f1af5a
b94126 ¤   Local Variables:
b47b17 ¤   tab-width: 4
9c0e6c ¤   End:
b85f8c ¤   vi: ts=4 sw=4
e49e9b ¤   vim: si
43d062 _____________________*/
--0914 00187eae3d14011024b Page 1 of pgpCodes.hpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
a8bb74 ¤   $Id: pgpCodes.hpp,v 1.5.16.1 1998/11/12 03:12:59 heller Exp $
a0f7f7 ____________________________________________________________________________*/
38c976 #ifndef Included_PGPCODES_h¤/* [ */
cc08b7 #define Included_PGPCODES_h
b6af5a
a2af5a
952b56 #define PGP_CODE_ENCRYPT¤   ¤   2
a65ad7 #define PGP_CODE_SIGN¤  ¤   ¤   4
da6e02 #define PGP_CODE_ENCRYPT_SIGN¤  8
e8202a #define PGP_CODE_DECRYPT¤   ¤   16
955fec #define PGP_CODE_VERIFY¤¤   ¤   32
e19922 #define PGP_CODE_ADD_KEYS¤  ¤   64
06f565 #define PGP_CODE_VIEW_KEYS¤ ¤   128
ad2976 #define PGP_CODE_ENCRYPT_SEND¤  256
3bfd56 #define PGP_CODE_VERIFY_SIG ····512
b20f11 #define PGP_CODE_WIPE¤  ¤   ¤   1024
cdaf5a
9baf5a
6cf8ed #endif /* ] Included_PGPCODES_h */
54af5a
26af5a
497e4d /*__Editor_settings____
68af5a
014126 ¤   Local Variables:
977b17 ¤   tab-width: 4
110e6c ¤   End:
455f8c ¤   vi: ts=4 sw=4
5a9e9b ¤   vim: si
87d062 _____________________*/
--f045 00175e2bfec4011024c Page 1 of pgpwctx.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
19f860 #ifdef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
66465d //
df5733 // TEXTINCLUDE
a2465d //
99af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
2d4523 BEGIN
70541e ····"resource.h\0"
48e0d1 END
85af5a
467037 2 TEXTINCLUDE DISCARDABLE·
044523 BEGIN
c3eb23 ····"#include ""afxres.h""\r\n"
98db5c ····"\0"
97e0d1 END
5aaf5a
ea227f 3 TEXTINCLUDE DISCARDABLE·
024523 BEGIN
f15e75 ····"#include ""PGPwctxVer.rc""\r\n"
46db5c ····"\0"
4ae0d1 END
f6af5a
e069ab #endif ···// APSTUDIO_INVOKED
c2af5a
231b3a #endif ···// English (U.S.) resources
636c0e /////////////////////////////////////////////////////////////////////////////
2caf5a
54af5a
a0af5a
dece8c #ifndef APSTUDIO_INVOKED
f36c0e /////////////////////////////////////////////////////////////////////////////
54465d //
668464 // Generated from the TEXTINCLUDE 3 resource.
62465d //
736bbd #include "PGPwctxVer.rc"
21af5a
596c0e /////////////////////////////////////////////////////////////////////////////
888072 #endif ···// not APSTUDIO_INVOKED
75af5a
--8f78 000f553890e4011024d Page 1 of AdditionalDecryption.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d6167d ¤   $Id: AdditionalDecryption.cpp,v 1.4.8.1 1998/11/12 03:13:01 heller Exp $
a1f7f7 ____________________________________________________________________________*/
3aaf5a
ff5655 #include <windows.h>
52fb83 #include "PGPadmin.h"
bb90fb #include <commctrl.h>
268031 #include "resource.h"
973bb4 #include "Utils.h"
800d08 #include "pgpMem.h"
1d7528 #include "pgpImage.h"
63af5a
00b779 #define ID_TIMER¤   42
daaf5a
b1afc0 static BOOL bNextEnabled = FALSE;
edaf5a
a91b1c BOOL CALLBACK ADKIntroDlgProc(HWND hwndDlg,·
d10d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
a38347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
9fb0d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
60bb36 {
3b0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
438ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
e8af5a
cb6357 ¤   g_hCurrentDlgWnd = hwndDlg;
dbaf5a
ac9450 ¤   if (uMsg != WM_INITDIALOG)
67e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
f6af5a
94c08d ¤   switch(uMsg)
90c7a1 ¤   {
162940 ¤   case WM_INITDIALOG:
255b34 ¤   ¤   {
acafc0 ¤   ¤   ¤   RECT rc;
a1313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
7caf5a
ce015a ¤   ¤   ¤   // center dialog on screen
2dd4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
713d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
ce0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
37004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
69f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
fdaf5a
bb3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
c9ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
86cdcb ¤   ¤   ¤   break;
5b0fe4 ¤   ¤   }
75af5a
cb93f9 ¤   case WM_PAINT:
8cc334 ¤   ¤   if (pConfig->hPalette)
135b34 ¤   ¤   {
92f431 ¤   ¤   ¤   PAINTSTRUCT ps;
ab60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
764fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
ac9ffe ¤   ¤   ¤   RealizePalette (hDC);
66438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
fe0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
d60fe4 ¤   ¤   }
8e2f68 ¤   ¤   break;
7a1b52 ¤   ¤
dec93c ¤   case WM_NOTIFY:
c15b34 ¤   ¤   {
51a08b ¤   ¤   ¤   LPNMHDR pnmh;
f1af5a
452b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
42b7b0 ¤   ¤   ¤   switch(pnmh->code)
f5f776 ¤   ¤   ¤   {
--bfe9 0003fd8b3cd4011024d Page 2 of AdditionalDecryption.cpp
d566bc ¤   ¤   ¤   case PSN_SETACTIVE:
2972c3 ¤   ¤   ¤   ¤   {
367182 ¤   ¤   ¤   ¤   ¤   // Initialize window
54bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
f4c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
f3af5a
cd9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
84670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
95af5a
224149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
2e14c3 ¤   ¤   ¤   ¤   ¤   break;
de2613 ¤   ¤   ¤   ¤   }
69af5a
8dd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
1472c3 ¤   ¤   ¤   ¤   {
7166b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
f814c3 ¤   ¤   ¤   ¤   ¤   break;
e22613 ¤   ¤   ¤   ¤   }
dbaf5a
4bb546 ¤   ¤   ¤   case PSN_WIZFINISH:
8172c3 ¤   ¤   ¤   ¤   {
529a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
3d14c3 ¤   ¤   ¤   ¤   ¤   break;
8d2613 ¤   ¤   ¤   ¤   }
24af5a
d26122 ¤   ¤   ¤   case PSN_HELP:
3772c3 ¤   ¤   ¤   ¤   {
99f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
3114c3 ¤   ¤   ¤   ¤   ¤   break;
ca2613 ¤   ¤   ¤   ¤   }
f9af5a
548f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
6f72c3 ¤   ¤   ¤   ¤   {
826b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
55014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
7f14c3 ¤   ¤   ¤   ¤   ¤   break;
782613 ¤   ¤   ¤   ¤   }
76a3a6 ¤   ¤   ¤   }
0587c7 ¤   ¤   ¤
88cdcb ¤   ¤   ¤   break;
5b0fe4 ¤   ¤   }
c0af5a
2c9371 ¤   }
8caf5a
8f48b1 ¤   return(bReturnCode);
d4efe6 }
05af5a
14af5a
0b0524 BOOL CALLBACK ADKIncomingDlgProc(HWND hwndDlg,·
e60d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
ed8347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
bbb0d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
12bb36 {
e50f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
888ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
fcaf5a
c96357 ¤   g_hCurrentDlgWnd = hwndDlg;
14af5a
f29450 ¤   if (uMsg != WM_INITDIALOG)
8de72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
e1af5a
f4c08d ¤   switch(uMsg)
54c7a1 ¤   {
cf2940 ¤   case WM_INITDIALOG:
945b34 ¤   ¤   {
72afc0 ¤   ¤   ¤   RECT rc;
77313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
e3af5a
ac015a ¤   ¤   ¤   // center dialog on screen
f3d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
173d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
3f0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
--64d6 00019d2faac4011024d Page 3 of AdditionalDecryption.cpp
38004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
3bf9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
59af5a
c23970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
32ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
88cdcb ¤   ¤   ¤   break;
250fe4 ¤   ¤   }
87af5a
e393f9 ¤   case WM_PAINT:
64c334 ¤   ¤   if (pConfig->hPalette)
105b34 ¤   ¤   {
45f431 ¤   ¤   ¤   PAINTSTRUCT ps;
db60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
4d4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
389ffe ¤   ¤   ¤   RealizePalette (hDC);
6e438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
160fe0 ¤   ¤   ¤   bReturnCode = TRUE;
180fe4 ¤   ¤   }
442f68 ¤   ¤   break;
141b52 ¤   ¤
60c93c ¤   case WM_NOTIFY:
0c5b34 ¤   ¤   {
eca08b ¤   ¤   ¤   LPNMHDR pnmh;
dcaf5a
292b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
fdb7b0 ¤   ¤   ¤   switch(pnmh->code)
0ff776 ¤   ¤   ¤   {
a066bc ¤   ¤   ¤   case PSN_SETACTIVE:
4c72c3 ¤   ¤   ¤   ¤   {
bd7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
f9bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
cac365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
6baf5a
0e9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
33670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
4baf5a
10cd32 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseIncomingADK)
6b4859 ¤   ¤   ¤   ¤   ¤   {
6a9250 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USE_INADK, BST_CHECKED);
191c89 ¤   ¤   ¤   ¤   ¤   }
5a4bd6 ¤   ¤   ¤   ¤   ¤   else
be4859 ¤   ¤   ¤   ¤   ¤   {
b3b868 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USE_INADK, BST_UNCHECKED);
991c89 ¤   ¤   ¤   ¤   ¤   }
04af5a
964149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9814c3 ¤   ¤   ¤   ¤   ¤   break;
8a2613 ¤   ¤   ¤   ¤   }
96af5a
9ed105 ¤   ¤   ¤   case PSN_KILLACTIVE:
6272c3 ¤   ¤   ¤   ¤   {
3e66b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
5a14c3 ¤   ¤   ¤   ¤   ¤   break;
912613 ¤   ¤   ¤   ¤   }
c0af5a
4e99a3 ¤   ¤   ¤   case PSN_WIZNEXT:
4a72c3 ¤   ¤   ¤   ¤   {
db7934 ¤   ¤   ¤   ¤   ¤   // Determine if we should go to incoming ADK key·
4bbd6d ¤   ¤   ¤   ¤   ¤   // selection or skip to outgoing ADK
49af5a
6e6c8b ¤   ¤   ¤   ¤   ¤   if (!pConfig->bUseIncomingADK)
da1039 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT,·
16434e ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDD_ADK_OUTGOING);
45af5a
5d4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c114c3 ¤   ¤   ¤   ¤   ¤   break;
e32613 ¤   ¤   ¤   ¤   }
14af5a
166122 ¤   ¤   ¤   case PSN_HELP:
2472c3 ¤   ¤   ¤   ¤   {
6bf1f2 ¤   ¤   ¤   ¤   ¤   // Display help
1914c3 ¤   ¤   ¤   ¤   ¤   break;
--6130 0003b867fcf4011024d Page 4 of AdditionalDecryption.cpp
862613 ¤   ¤   ¤   ¤   }
fdaf5a
fd8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
fa72c3 ¤   ¤   ¤   ¤   {
8e6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
19014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
0114c3 ¤   ¤   ¤   ¤   ¤   break;
922613 ¤   ¤   ¤   ¤   }
c7a3a6 ¤   ¤   ¤   }
7687c7 ¤   ¤   ¤
66cdcb ¤   ¤   ¤   break;
5f0fe4 ¤   ¤   }
c0af5a
343fcf ¤   case WM_COMMAND:
0372a4 ¤   ¤   switch (LOWORD(wParam))
2e5b34 ¤   ¤   {
3bcc91 ¤   ¤   case IDC_USE_INADK:
a9f776 ¤   ¤   ¤   {
d9fddd ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_USE_INADK) == BST_CHECKED)
bc72c3 ¤   ¤   ¤   ¤   {
557e2c ¤   ¤   ¤   ¤   ¤   pConfig->bUseIncomingADK = TRUE;
392613 ¤   ¤   ¤   ¤   }
fdfa07 ¤   ¤   ¤   ¤   else
f172c3 ¤   ¤   ¤   ¤   {
d0da53 ¤   ¤   ¤   ¤   ¤   pConfig->bUseIncomingADK = FALSE;
d5a243 ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceIncomingADK = FALSE;
292613 ¤   ¤   ¤   ¤   }
e1af5a
8a841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c3f622 ¤   ¤   ¤   ¤   break;
e2a3a6 ¤   ¤   ¤   }
fc0fe4 ¤   ¤   }
03af5a
d32f68 ¤   ¤   break;
849371 ¤   }
18af5a
5a48b1 ¤   return(bReturnCode);
0aefe6 }
baaf5a
e6af5a
c387f4 BOOL CALLBACK ADKInSelectDlgProc(HWND hwndDlg,·
400d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
f88347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
34b0d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
34bb36 {
650f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
d38ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
ba429d ¤   HWND¤   ¤   ¤   hList;
e7af5a
d76357 ¤   g_hCurrentDlgWnd = hwndDlg;
51af5a
7c9450 ¤   if (uMsg != WM_INITDIALOG)
aee72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
3daf5a
4c4c7d ¤   hList = GetDlgItem(hwndDlg, IDC_INADK_ID);
45af5a
1fc08d ¤   switch(uMsg)
e5c7a1 ¤   {
e02940 ¤   case WM_INITDIALOG:
015b34 ¤   ¤   {
d9afc0 ¤   ¤   ¤   RECT rc;
13313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
14af5a
97015a ¤   ¤   ¤   // center dialog on screen
ead4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
d33d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
e00971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
67004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
c0f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
b7af5a
113970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
3bad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
--74d9 000643071154011024d Page 5 of AdditionalDecryption.cpp
e0af5a
4043f5 ¤   ¤   ¤   ShowKeyring(hwndDlg, IDC_INADK_ID, pConfig->pgpContext,·
a64b65 ¤   ¤   ¤   ¤   NULL, FALSE, TRUE, TRUE, FALSE);
4b021f ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
16cdcb ¤   ¤   ¤   break;
d70fe4 ¤   ¤   }
7daf5a
046b08 ¤   case WM_DESTROY:
29ff59 ¤   ¤   FreeKeyring(hwndDlg, IDC_INADK_ID);
b02f68 ¤   ¤   break;
d2af5a
2593f9 ¤   case WM_PAINT:
29c334 ¤   ¤   if (pConfig->hPalette)
4b5b34 ¤   ¤   {
5cf431 ¤   ¤   ¤   PAINTSTRUCT ps;
4c60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
d04fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
279ffe ¤   ¤   ¤   RealizePalette (hDC);
60438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
530fe0 ¤   ¤   ¤   bReturnCode = TRUE;
4a0fe4 ¤   ¤   }
e42f68 ¤   ¤   break;
521b52 ¤   ¤
1cc93c ¤   case WM_NOTIFY:
495b34 ¤   ¤   {
64a08b ¤   ¤   ¤   LPNMHDR pnmh;
abaf5a
9c2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
6bb7b0 ¤   ¤   ¤   switch(pnmh->code)
eff776 ¤   ¤   ¤   {
5666bc ¤   ¤   ¤   case PSN_SETACTIVE:
fe72c3 ¤   ¤   ¤   ¤   {
9e4a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
dbaf5a
1a7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
c35c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
56abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
6a4859 ¤   ¤   ¤   ¤   ¤   {
ede898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
c7ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
633cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
541c89 ¤   ¤   ¤   ¤   ¤   }
964bd6 ¤   ¤   ¤   ¤   ¤   else
4a4859 ¤   ¤   ¤   ¤   ¤   {
24e898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
5b8e3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
51d359 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
0b1c89 ¤   ¤   ¤   ¤   ¤   }
38af5a
739908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
2f670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
2aaf5a
22c394 ¤   ¤   ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
604149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9514c3 ¤   ¤   ¤   ¤   ¤   break;
a42613 ¤   ¤   ¤   ¤   }
5faf5a
6ed105 ¤   ¤   ¤   case PSN_KILLACTIVE:
8872c3 ¤   ¤   ¤   ¤   {
05197b ¤   ¤   ¤   ¤   ¤   KillTimer(hwndDlg, ID_TIMER);
704149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
1c14c3 ¤   ¤   ¤   ¤   ¤   break;
c62613 ¤   ¤   ¤   ¤   }
7faf5a
6d99a3 ¤   ¤   ¤   case PSN_WIZNEXT:
4672c3 ¤   ¤   ¤   ¤   {
388511 ¤   ¤   ¤   ¤   ¤   int¤¤   nIndex;
d35283 ¤   ¤   ¤   ¤   ¤   LV_ITEM lviKey;
d8e438 ¤   ¤   ¤   ¤   ¤   char *szKeyID;
36bd59 ¤   ¤   ¤   ¤   ¤   char szUserID[kPGPMaxUserIDSize+1];
0eaf5a
643c05 ¤   ¤   ¤   ¤   ¤   if (pConfig->szIncomingADKID != NULL)
--085d 000204aa3be4011024d Page 6 of AdditionalDecryption.cpp
e04859 ¤   ¤   ¤   ¤   ¤   {
88e33a ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szIncomingADKID);
8e64de ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szIncomingADKID = NULL;
c41c89 ¤   ¤   ¤   ¤   ¤   }
5daf5a
04e25b ¤   ¤   ¤   ¤   ¤   if (pConfig->szIncomingADK != NULL)
ba4859 ¤   ¤   ¤   ¤   ¤   {
c56ab7 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szIncomingADK);
296c63 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szIncomingADK = NULL;
7c1c89 ¤   ¤   ¤   ¤   ¤   }
06af5a
e666b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
475c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
03abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
744859 ¤   ¤   ¤   ¤   ¤   {
11f974 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.mask = LVIF_PARAM | LVIF_TEXT;
32b282 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iItem = nIndex;
7c9588 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iSubItem = 0;
3c77b4 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.pszText = szUserID;
799c1d ¤   ¤   ¤   ¤   ¤   ¤   lviKey.cchTextMax = kPGPMaxUserIDSize;
e12337 ¤   ¤   ¤   ¤   ¤   ¤   ListView_GetItem(hList, &lviKey);
bf9e35 ¤   ¤   ¤   ¤   ¤   ¤   szKeyID = (char *) lviKey.lParam;
40af5a
217d31 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szIncomingADKID =·
2acd77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szKeyID)+1);
5bbbf0 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szIncomingADKID, szKeyID);
ccaf5a
fbf55f ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szIncomingADK =·
dee764 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szUserID)+1);
c2c2f9 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szIncomingADK, szUserID);
391c89 ¤   ¤   ¤   ¤   ¤   }
d9af5a
cb4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
be14c3 ¤   ¤   ¤   ¤   ¤   break;
2f2613 ¤   ¤   ¤   ¤   }
1faf5a
5a6122 ¤   ¤   ¤   case PSN_HELP:
f672c3 ¤   ¤   ¤   ¤   {
9af1f2 ¤   ¤   ¤   ¤   ¤   // Display help
5214c3 ¤   ¤   ¤   ¤   ¤   break;
6d2613 ¤   ¤   ¤   ¤   }
9baf5a
c78f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
9c72c3 ¤   ¤   ¤   ¤   {
0d6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
94014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
7a14c3 ¤   ¤   ¤   ¤   ¤   break;
5b2613 ¤   ¤   ¤   ¤   }
03af5a
5db108 ¤   ¤   ¤   case NM_CLICK:
9031c1 ¤   ¤   ¤   case NM_RCLICK:
f8168c ¤   ¤   ¤   case NM_DBLCLK:
904dc1 ¤   ¤   ¤   case NM_RDBLCLK:
89f300 ¤   ¤   ¤   ¤   if (pnmh->idFrom == IDC_INADK_ID)
1972c3 ¤   ¤   ¤   ¤   {
024a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
6aaf5a
ca5c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
0babcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
af4859 ¤   ¤   ¤   ¤   ¤   {
42b2ca ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
bdba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
1e3cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
ca1c89 ¤   ¤   ¤   ¤   ¤   }
284149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
072613 ¤   ¤   ¤   ¤   }
1df622 ¤   ¤   ¤   ¤   break;
cea3a6 ¤   ¤   ¤   }
c387c7 ¤   ¤   ¤
c4cdcb ¤   ¤   ¤   break;
250fe4 ¤   ¤   }
20af5a
--cf81 0008129a3634011024d Page 7 of AdditionalDecryption.cpp
e3e60b ¤   case WM_TIMER:
635b34 ¤   ¤   {
f3114f ¤   ¤   ¤   int nIndex;
61af5a
65c6b0 ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
8b2df5 ¤   ¤   ¤   if (nIndex > -1)
0ef776 ¤   ¤   ¤   {
9b5454 ¤   ¤   ¤   ¤   if (!bNextEnabled)
6d72c3 ¤   ¤   ¤   ¤   {
b2e766 ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
30c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
bd3a0d ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
212613 ¤   ¤   ¤   ¤   }
32a3a6 ¤   ¤   ¤   }
3939bb ¤   ¤   ¤   else if (bNextEnabled)
29f776 ¤   ¤   ¤   {
d87127 ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
38c577 ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
0ed672 ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
f9a3a6 ¤   ¤   ¤   }
5faf5a
4d0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
af196f ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
dccdcb ¤   ¤   ¤   break;
d70fe4 ¤   ¤   }
c5af5a
ca9371 ¤   }
88af5a
ae48b1 ¤   return(bReturnCode);
8defe6 }
18af5a
97af5a
940a6c BOOL CALLBACK ADKOutgoingDlgProc(HWND hwndDlg,·
f3baeb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
da40d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
be0142 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
ccbb36 {
fe0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
918ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
7daf5a
386357 ¤   g_hCurrentDlgWnd = hwndDlg;
d8af5a
1d9450 ¤   if (uMsg != WM_INITDIALOG)
6be72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
4baf5a
9fc08d ¤   switch(uMsg)
80c7a1 ¤   {
4e2940 ¤   case WM_INITDIALOG:
0e5b34 ¤   ¤   {
eaafc0 ¤   ¤   ¤   RECT rc;
45313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
19af5a
60015a ¤   ¤   ¤   // center dialog on screen
17d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
f33d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
270971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
4d004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
a8f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
9daf5a
733970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
baad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
8fcdcb ¤   ¤   ¤   break;
450fe4 ¤   ¤   }
37af5a
b793f9 ¤   case WM_PAINT:
2dc334 ¤   ¤   if (pConfig->hPalette)
955b34 ¤   ¤   {
a3f431 ¤   ¤   ¤   PAINTSTRUCT ps;
2660df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
9e4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
c69ffe ¤   ¤   ¤   RealizePalette (hDC);
81438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
--86ee 000bfe2f1284011024d Page 8 of AdditionalDecryption.cpp
f50fe0 ¤   ¤   ¤   bReturnCode = TRUE;
4c0fe4 ¤   ¤   }
9c2f68 ¤   ¤   break;
0d1b52 ¤   ¤
20c93c ¤   case WM_NOTIFY:
ae5b34 ¤   ¤   {
8fa08b ¤   ¤   ¤   LPNMHDR pnmh;
26af5a
b12b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
5fb7b0 ¤   ¤   ¤   switch(pnmh->code)
4ff776 ¤   ¤   ¤   {
0766bc ¤   ¤   ¤   case PSN_SETACTIVE:
5772c3 ¤   ¤   ¤   ¤   {
2c7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
35bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
40c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
cbaf5a
ab9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
93670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
a9af5a
1b6b76 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseOutgoingADK)
c64859 ¤   ¤   ¤   ¤   ¤   {
320c0f ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USE_OUTADK,·
cb94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
ec1c89 ¤   ¤   ¤   ¤   ¤   }
dc4bd6 ¤   ¤   ¤   ¤   ¤   else
b34859 ¤   ¤   ¤   ¤   ¤   {
6b0c0f ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USE_OUTADK,·
5dd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
b01c89 ¤   ¤   ¤   ¤   ¤   }
70af5a
0e4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
8a14c3 ¤   ¤   ¤   ¤   ¤   break;
102613 ¤   ¤   ¤   ¤   }
8caf5a
c1d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
6e72c3 ¤   ¤   ¤   ¤   {
2666b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
3214c3 ¤   ¤   ¤   ¤   ¤   break;
b62613 ¤   ¤   ¤   ¤   }
70af5a
1999a3 ¤   ¤   ¤   case PSN_WIZNEXT:
2772c3 ¤   ¤   ¤   ¤   {
782ab7 ¤   ¤   ¤   ¤   ¤   // Determine if we should go to RSA key selection
492cd6 ¤   ¤   ¤   ¤   ¤   // or skip past it
29af5a
a4cacf ¤   ¤   ¤   ¤   ¤   if (!pConfig->bUseOutgoingADK)
a34739 //¤ ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseIncomingADK)
a29dc5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT,·
018c0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDD_ADK_ENFORCE);
3b38e5 /*
f37f8b ¤   ¤   ¤   ¤   ¤   ¤   else
a39dc5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT,·
73993d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDD_PASSPHRASE);
a87fe0 */
91af5a
c24149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
8014c3 ¤   ¤   ¤   ¤   ¤   break;
732613 ¤   ¤   ¤   ¤   }
d7af5a
1b49a1 ¤   ¤   ¤   case PSN_WIZBACK:
4372c3 ¤   ¤   ¤   ¤   {
f17934 ¤   ¤   ¤   ¤   ¤   // Determine if we should go to incoming ADK key·
018129 ¤   ¤   ¤   ¤   ¤   // selection or skip back to incoming ADK
cbaf5a
006c8b ¤   ¤   ¤   ¤   ¤   if (!pConfig->bUseIncomingADK)
c41039 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT,·
4a755a ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDD_ADK_INCOMING);
d1af5a
fe4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
f914c3 ¤   ¤   ¤   ¤   ¤   break;
bf2613 ¤   ¤   ¤   ¤   }
--7b8d 00042b70c684011024d Page 9 of AdditionalDecryption.cpp
e0af5a
d26122 ¤   ¤   ¤   case PSN_HELP:
c572c3 ¤   ¤   ¤   ¤   {
d7f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
9414c3 ¤   ¤   ¤   ¤   ¤   break;
a12613 ¤   ¤   ¤   ¤   }
01af5a
068f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
2972c3 ¤   ¤   ¤   ¤   {
db6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
7f014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
1614c3 ¤   ¤   ¤   ¤   ¤   break;
d02613 ¤   ¤   ¤   ¤   }
0fa3a6 ¤   ¤   ¤   }
c087c7 ¤   ¤   ¤
86cdcb ¤   ¤   ¤   break;
420fe4 ¤   ¤   }
69af5a
113fcf ¤   case WM_COMMAND:
5072a4 ¤   ¤   switch (LOWORD(wParam))
5c5b34 ¤   ¤   {
775a50 ¤   ¤   case IDC_USE_OUTADK:
6cf776 ¤   ¤   ¤   {
a468e8 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_USE_OUTADK) ==·
cd2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
e872c3 ¤   ¤   ¤   ¤   {
7e4e64 ¤   ¤   ¤   ¤   ¤   pConfig->bUseOutgoingADK = TRUE;
242613 ¤   ¤   ¤   ¤   }
19fa07 ¤   ¤   ¤   ¤   else
5172c3 ¤   ¤   ¤   ¤   {
c0142f ¤   ¤   ¤   ¤   ¤   pConfig->bUseOutgoingADK = FALSE;
8e6c3f ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceOutgoingADK = FALSE;
192613 ¤   ¤   ¤   ¤   }
d0af5a
89841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
00f622 ¤   ¤   ¤   ¤   break;
eaa3a6 ¤   ¤   ¤   }
3caf5a
0c0fe4 ¤   ¤   }
ebaf5a
be2f68 ¤   ¤   break;
0b9371 ¤   }
1faf5a
6e48b1 ¤   return(bReturnCode);
72efe6 }
94af5a
b8af5a
708cf9 BOOL CALLBACK ADKOutSelectDlgProc(HWND hwndDlg,·
695f89 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
29d05c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
252696 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
83bb36 {
bf8d02 ¤   BOOL bReturnCode = FALSE;
4c6930 ¤   pgpConfigInfo *pConfig = NULL;
1b3c96 ¤   HWND hList;
d5af5a
486357 ¤   g_hCurrentDlgWnd = hwndDlg;
83af5a
ea9450 ¤   if (uMsg != WM_INITDIALOG)
3ae72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
4faf5a
96cf1b ¤   hList = GetDlgItem(hwndDlg, IDC_OUTADK_ID);
52af5a
adc08d ¤   switch(uMsg)
1ac7a1 ¤   {
7b2940 ¤   case WM_INITDIALOG:
9d5b34 ¤   ¤   {
b1afc0 ¤   ¤   ¤   RECT rc;
b0313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
60af5a
40015a ¤   ¤   ¤   // center dialog on screen
42d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
--8520 000c38467cb4011024d Page 10 of AdditionalDecryption.cpp
8a3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
020971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
3a004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
84f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
5baf5a
7f3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
d0ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
10af5a
c2b64c ¤   ¤   ¤   ShowKeyring(hwndDlg, IDC_OUTADK_ID, pConfig->pgpContext,·
f65d91 ¤   ¤   ¤   ¤   NULL, TRUE, TRUE, TRUE, FALSE);
92021f ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
22cdcb ¤   ¤   ¤   break;
370fe4 ¤   ¤   }
d9af5a
1f6b08 ¤   case WM_DESTROY:
f1a88e ¤   ¤   FreeKeyring(hwndDlg, IDC_OUTADK_ID);
652f68 ¤   ¤   break;
81af5a
9893f9 ¤   case WM_PAINT:
38c334 ¤   ¤   if (pConfig->hPalette)
825b34 ¤   ¤   {
89f431 ¤   ¤   ¤   PAINTSTRUCT ps;
8560df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
394fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
549ffe ¤   ¤   ¤   RealizePalette (hDC);
7e438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
4d0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
350fe4 ¤   ¤   }
962f68 ¤   ¤   break;
9f1b52 ¤   ¤
d4c93c ¤   case WM_NOTIFY:
be5b34 ¤   ¤   {
0da08b ¤   ¤   ¤   LPNMHDR pnmh;
45af5a
6d2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
f8b7b0 ¤   ¤   ¤   switch(pnmh->code)
2ff776 ¤   ¤   ¤   {
9c66bc ¤   ¤   ¤   case PSN_SETACTIVE:
a172c3 ¤   ¤   ¤   ¤   {
d64a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
d2af5a
8e7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
e65c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
f5abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
524859 ¤   ¤   ¤   ¤   ¤   {
e2e898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
03ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
653cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
441c89 ¤   ¤   ¤   ¤   ¤   }
8f4bd6 ¤   ¤   ¤   ¤   ¤   else
ee4859 ¤   ¤   ¤   ¤   ¤   {
3de898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
5a8e3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
cbd359 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
271c89 ¤   ¤   ¤   ¤   ¤   }
bfaf5a
a49908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
5c670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
fcaf5a
2cc394 ¤   ¤   ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
444149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
cf14c3 ¤   ¤   ¤   ¤   ¤   break;
282613 ¤   ¤   ¤   ¤   }
04af5a
d3d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
2b72c3 ¤   ¤   ¤   ¤   {
cd197b ¤   ¤   ¤   ¤   ¤   KillTimer(hwndDlg, ID_TIMER);
534149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
a814c3 ¤   ¤   ¤   ¤   ¤   break;
ff2613 ¤   ¤   ¤   ¤   }
78af5a
c399a3 ¤   ¤   ¤   case PSN_WIZNEXT:
--bec8 000604c52474011024d Page 11 of AdditionalDecryption.cpp
d072c3 ¤   ¤   ¤   ¤   {
224a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
575283 ¤   ¤   ¤   ¤   ¤   LV_ITEM lviKey;
9fe438 ¤   ¤   ¤   ¤   ¤   char *szKeyID;
ecbd59 ¤   ¤   ¤   ¤   ¤   char szUserID[kPGPMaxUserIDSize+1];
03af5a
f94a13 ¤   ¤   ¤   ¤   ¤   if (pConfig->szOutgoingADKID != NULL)
894859 ¤   ¤   ¤   ¤   ¤   {
667d02 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szOutgoingADKID);
f3ddfb ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szOutgoingADKID = NULL;
741c89 ¤   ¤   ¤   ¤   ¤   }
64af5a
962c27 ¤   ¤   ¤   ¤   ¤   if (pConfig->szOutgoingADK != NULL)
f84859 ¤   ¤   ¤   ¤   ¤   {
5e6e31 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szOutgoingADK);
285c2b ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szOutgoingADK = NULL;
191c89 ¤   ¤   ¤   ¤   ¤   }
e7af5a
5066b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
915c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
f9abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
1c4859 ¤   ¤   ¤   ¤   ¤   {
962902 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
fbb282 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iItem = nIndex;
bd9588 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iSubItem = 0;
e677b4 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.pszText = szUserID;
589c1d ¤   ¤   ¤   ¤   ¤   ¤   lviKey.cchTextMax = kPGPMaxUserIDSize;
e72337 ¤   ¤   ¤   ¤   ¤   ¤   ListView_GetItem(hList, &lviKey);
469e35 ¤   ¤   ¤   ¤   ¤   ¤   szKeyID = (char *) lviKey.lParam;
61af5a
fbc064 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szOutgoingADKID =·
94cd77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szKeyID)+1);
986c00 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szOutgoingADKID, szKeyID);
bbaf5a
231465 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szOutgoingADK =·
5fe764 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szUserID)+1);
feb738 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szOutgoingADK, szUserID);
11af5a
3540ef ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_RSAPUBKEY)
90aace ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->outgoingADKKeyType =·
dbc69d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA;
bec4dd ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_DSAPUBKEY)
e9aace ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->outgoingADKKeyType =·
0f4945 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_DSA;
1f1c89 ¤   ¤   ¤   ¤   ¤   }
91af5a
c04149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
8b14c3 ¤   ¤   ¤   ¤   ¤   break;
062613 ¤   ¤   ¤   ¤   }
73af5a
c8b546 ¤   ¤   ¤   case PSN_WIZFINISH:
4272c3 ¤   ¤   ¤   ¤   {
d79a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
d714c3 ¤   ¤   ¤   ¤   ¤   break;
412613 ¤   ¤   ¤   ¤   }
c4af5a
5b6122 ¤   ¤   ¤   case PSN_HELP:
2372c3 ¤   ¤   ¤   ¤   {
4af1f2 ¤   ¤   ¤   ¤   ¤   // Display help
a814c3 ¤   ¤   ¤   ¤   ¤   break;
612613 ¤   ¤   ¤   ¤   }
28af5a
d08f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
7672c3 ¤   ¤   ¤   ¤   {
c86b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
cd014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
d814c3 ¤   ¤   ¤   ¤   ¤   break;
fc2613 ¤   ¤   ¤   ¤   }
0aaf5a
28b108 ¤   ¤   ¤   case NM_CLICK:
6831c1 ¤   ¤   ¤   case NM_RCLICK:
60168c ¤   ¤   ¤   case NM_DBLCLK:
--5666 00085bcd6694011024d Page 12 of AdditionalDecryption.cpp
974dc1 ¤   ¤   ¤   case NM_RDBLCLK:
9733f7 ¤   ¤   ¤   ¤   if (pnmh->idFrom == IDC_OUTADK_ID)
5472c3 ¤   ¤   ¤   ¤   {
654a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
95af5a
4f5c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
97abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
fa4859 ¤   ¤   ¤   ¤   ¤   {
5bb2ca ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
84ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
213cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
c61c89 ¤   ¤   ¤   ¤   ¤   }
0c4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ae2613 ¤   ¤   ¤   ¤   }
7bf622 ¤   ¤   ¤   ¤   break;
e8af5a
1ca3a6 ¤   ¤   ¤   }
2087c7 ¤   ¤   ¤
f5cdcb ¤   ¤   ¤   break;
400fe4 ¤   ¤   }
dbaf5a
d7e60b ¤   case WM_TIMER:
a25b34 ¤   ¤   {
65114f ¤   ¤   ¤   int nIndex;
6baf5a
5bc6b0 ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
b52df5 ¤   ¤   ¤   if (nIndex > -1)
92f776 ¤   ¤   ¤   {
f25454 ¤   ¤   ¤   ¤   if (!bNextEnabled)
0f72c3 ¤   ¤   ¤   ¤   {
2ee766 ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
a9c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
963a0d ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
752613 ¤   ¤   ¤   ¤   }
95a3a6 ¤   ¤   ¤   }
cb39bb ¤   ¤   ¤   else if (bNextEnabled)
26f776 ¤   ¤   ¤   {
7e7127 ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
dfc577 ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
a1d672 ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
f0a3a6 ¤   ¤   ¤   }
2baf5a
d20fe0 ¤   ¤   ¤   bReturnCode = TRUE;
40196f ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
2acdcb ¤   ¤   ¤   break;
040fe4 ¤   ¤   }
f2af5a
2d9371 ¤   }
80af5a
0c48b1 ¤   return(bReturnCode);
74efe6 }
45af5a
84af5a
3c2d80 BOOL CALLBACK ADKEnforceDlgProc(HWND hwndDlg,·
d3218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
cb2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
8275ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
e0bb36 {
920f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
8a8ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
73af5a
976357 ¤   g_hCurrentDlgWnd = hwndDlg;
8faf5a
609450 ¤   if (uMsg != WM_INITDIALOG)
03e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
f6af5a
e4c08d ¤   switch(uMsg)
67c7a1 ¤   {
ae2940 ¤   case WM_INITDIALOG:
6c5b34 ¤   ¤   {
2cafc0 ¤   ¤   ¤   RECT rc;
85313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
--d9f2 00002bb46bb4011024d Page 13 of AdditionalDecryption.cpp
e0af5a
07015a ¤   ¤   ¤   // center dialog on screen
54d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
3b3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
8e0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
f5004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
48f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
eaaf5a
d93970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
74ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
a9cdcb ¤   ¤   ¤   break;
e20fe4 ¤   ¤   }
37af5a
7d93f9 ¤   case WM_PAINT:
09c334 ¤   ¤   if (pConfig->hPalette)
5d5b34 ¤   ¤   {
a0f431 ¤   ¤   ¤   PAINTSTRUCT ps;
f060df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
f24fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
1f9ffe ¤   ¤   ¤   RealizePalette (hDC);
bd438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
f60fe0 ¤   ¤   ¤   bReturnCode = TRUE;
ea0fe4 ¤   ¤   }
222f68 ¤   ¤   break;
381b52 ¤   ¤
f7c93c ¤   case WM_NOTIFY:
a85b34 ¤   ¤   {
e9a08b ¤   ¤   ¤   LPNMHDR pnmh;
f2af5a
8b2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
0eb7b0 ¤   ¤   ¤   switch(pnmh->code)
b2f776 ¤   ¤   ¤   {
9866bc ¤   ¤   ¤   case PSN_SETACTIVE:
6872c3 ¤   ¤   ¤   ¤   {
f07182 ¤   ¤   ¤   ¤   ¤   // Initialize window
28bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
0dc365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
feaf5a
139908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
07670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
4eaf5a
90cd32 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseIncomingADK)
a27237 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ENFORCE_INADK),
5a1dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
e04bd6 ¤   ¤   ¤   ¤   ¤   else
824859 ¤   ¤   ¤   ¤   ¤   {
667237 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ENFORCE_INADK),
107f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
ed4043 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceIncomingADK = FALSE;
971c89 ¤   ¤   ¤   ¤   ¤   }
09af5a
fd6b76 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseOutgoingADK)
3067c2 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ENFORCE_OUTADK),
b61dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
194bd6 ¤   ¤   ¤   ¤   ¤   else
a14859 ¤   ¤   ¤   ¤   ¤   {
bf67c2 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ENFORCE_OUTADK),
247f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
d78e3f ¤   ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceOutgoingADK = FALSE;
321c89 ¤   ¤   ¤   ¤   ¤   }
0faf5a
9dd440 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceIncomingADK)
0e4859 ¤   ¤   ¤   ¤   ¤   {
2dc7c7 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_INADK,·
bf94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
f31c89 ¤   ¤   ¤   ¤   ¤   }
0e4bd6 ¤   ¤   ¤   ¤   ¤   else
bc4859 ¤   ¤   ¤   ¤   ¤   {
5ac7c7 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_INADK,·
c2d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
d61c89 ¤   ¤   ¤   ¤   ¤   }
02af5a
--0e6c 000b0e0ccac4011024d Page 14 of AdditionalDecryption.cpp
357204 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceOutgoingADK)
b04859 ¤   ¤   ¤   ¤   ¤   {
749a38 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_OUTADK,·
c194bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
7c1c89 ¤   ¤   ¤   ¤   ¤   }
a94bd6 ¤   ¤   ¤   ¤   ¤   else
ab4859 ¤   ¤   ¤   ¤   ¤   {
6e9a38 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_OUTADK,·
1bd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
871c89 ¤   ¤   ¤   ¤   ¤   }
75af5a
0448a6 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceRemoteADK)
e94859 ¤   ¤   ¤   ¤   ¤   {
4a9f6f ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_REMOTEADK,·
ae94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
941c89 ¤   ¤   ¤   ¤   ¤   }
af4bd6 ¤   ¤   ¤   ¤   ¤   else
104859 ¤   ¤   ¤   ¤   ¤   {
0b9f6f ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_REMOTEADK,·
72d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
721c89 ¤   ¤   ¤   ¤   ¤   }
034149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9f14c3 ¤   ¤   ¤   ¤   ¤   break;
bf2613 ¤   ¤   ¤   ¤   }
71af5a
44d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
2f72c3 ¤   ¤   ¤   ¤   {
a966b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
fe14c3 ¤   ¤   ¤   ¤   ¤   break;
1c2613 ¤   ¤   ¤   ¤   }
24af5a
8c49a1 ¤   ¤   ¤   case PSN_WIZBACK:
d872c3 ¤   ¤   ¤   ¤   {
dd7ca1 ¤   ¤   ¤   ¤   ¤   // Determine if we should go to outgoing ADK key·
3b7b37 ¤   ¤   ¤   ¤   ¤   // selection or skip past it
f5af5a
4fcacf ¤   ¤   ¤   ¤   ¤   if (!pConfig->bUseOutgoingADK)
021039 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT,·
d3434e ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDD_ADK_OUTGOING);
bcaf5a
944149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
3714c3 ¤   ¤   ¤   ¤   ¤   break;
c12613 ¤   ¤   ¤   ¤   }
b4af5a
7d6122 ¤   ¤   ¤   case PSN_HELP:
eb72c3 ¤   ¤   ¤   ¤   {
43f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
b114c3 ¤   ¤   ¤   ¤   ¤   break;
ac2613 ¤   ¤   ¤   ¤   }
d8af5a
728f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
ac72c3 ¤   ¤   ¤   ¤   {
266b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
fe014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
4f14c3 ¤   ¤   ¤   ¤   ¤   break;
782613 ¤   ¤   ¤   ¤   }
b8a3a6 ¤   ¤   ¤   }
1487c7 ¤   ¤   ¤
f6cdcb ¤   ¤   ¤   break;
610fe4 ¤   ¤   }
1baf5a
213fcf ¤   case WM_COMMAND:
fa72a4 ¤   ¤   switch (LOWORD(wParam))
ad5b34 ¤   ¤   {
a09e85 ¤   ¤   case IDC_ENFORCE_INADK:
f9f776 ¤   ¤   ¤   {
33a025 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ENFORCE_INADK) ==·
8c2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
a172c3 ¤   ¤   ¤   ¤   {
77b1e7 ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceIncomingADK = TRUE;
d72613 ¤   ¤   ¤   ¤   }
b0fa07 ¤   ¤   ¤   ¤   else
--cc59 000ec593f934011024d Page 15 of AdditionalDecryption.cpp
d072c3 ¤   ¤   ¤   ¤   {
dfa243 ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceIncomingADK = FALSE;
342613 ¤   ¤   ¤   ¤   }
76af5a
d9841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
baf622 ¤   ¤   ¤   ¤   break;
6aa3a6 ¤   ¤   ¤   }
ab1b52 ¤   ¤
0a0ca7 ¤   ¤   case IDC_ENFORCE_OUTADK:
11f776 ¤   ¤   ¤   {
baeb7e ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ENFORCE_OUTADK) ==·
0b2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
db72c3 ¤   ¤   ¤   ¤   {
c781af ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceOutgoingADK = TRUE;
692613 ¤   ¤   ¤   ¤   }
abfa07 ¤   ¤   ¤   ¤   else
e072c3 ¤   ¤   ¤   ¤   {
e16c3f ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceOutgoingADK = FALSE;
d72613 ¤   ¤   ¤   ¤   }
7aaf5a
eb841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c7f622 ¤   ¤   ¤   ¤   break;
86a3a6 ¤   ¤   ¤   }
011b52 ¤   ¤
216e7c ¤   ¤   case IDC_ENFORCE_REMOTEADK:
46f776 ¤   ¤   ¤   {
cd538f ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ENFORCE_REMOTEADK) ==·
3c2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
8372c3 ¤   ¤   ¤   ¤   {
4ae6d8 ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceRemoteADK = TRUE;
a62613 ¤   ¤   ¤   ¤   }
a9fa07 ¤   ¤   ¤   ¤   else
4e72c3 ¤   ¤   ¤   ¤   {
276b60 ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceRemoteADK = FALSE;
832613 ¤   ¤   ¤   ¤   }
86af5a
3d841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
90f622 ¤   ¤   ¤   ¤   break;
e8a3a6 ¤   ¤   ¤   }
ee0fe4 ¤   ¤   }
ecaf5a
132f68 ¤   ¤   break;
d59371 ¤   }
6daf5a
8048b1 ¤   return(bReturnCode);
12efe6 }
44af5a
57af5a
628a81 BOOL CALLBACK ADKDiskDlgProc(HWND hwndDlg,·
a60bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
10d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
15a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
c8bb36 {
370f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
678ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
2faf5a
286357 ¤   g_hCurrentDlgWnd = hwndDlg;
04af5a
f19450 ¤   if (uMsg != WM_INITDIALOG)
a3e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
07af5a
bec08d ¤   switch(uMsg)
cec7a1 ¤   {
b02940 ¤   case WM_INITDIALOG:
935b34 ¤   ¤   {
a4afc0 ¤   ¤   ¤   RECT rc;
2c313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
b0af5a
42015a ¤   ¤   ¤   // center dialog on screen
e2d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
1d3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
ec0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
--ad59 000cf406ca74011024d Page 16 of AdditionalDecryption.cpp
38004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
3bf9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
59af5a
c23970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
32ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
88cdcb ¤   ¤   ¤   break;
250fe4 ¤   ¤   }
87af5a
e393f9 ¤   case WM_PAINT:
64c334 ¤   ¤   if (pConfig->hPalette)
105b34 ¤   ¤   {
45f431 ¤   ¤   ¤   PAINTSTRUCT ps;
db60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
4d4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
389ffe ¤   ¤   ¤   RealizePalette (hDC);
6e438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
160fe0 ¤   ¤   ¤   bReturnCode = TRUE;
180fe4 ¤   ¤   }
442f68 ¤   ¤   break;
141b52 ¤   ¤
60c93c ¤   case WM_NOTIFY:
0c5b34 ¤   ¤   {
eca08b ¤   ¤   ¤   LPNMHDR pnmh;
dcaf5a
292b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
fdb7b0 ¤   ¤   ¤   switch(pnmh->code)
0ff776 ¤   ¤   ¤   {
a066bc ¤   ¤   ¤   case PSN_SETACTIVE:
4c72c3 ¤   ¤   ¤   ¤   {
bd7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
f9bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
cac365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
6baf5a
0e9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
33670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
4baf5a
074431 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseDiskADK)
3d4859 ¤   ¤   ¤   ¤   ¤   {
361a74 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USE_DISKADK,·
f294bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
391c89 ¤   ¤   ¤   ¤   ¤   }
dc4bd6 ¤   ¤   ¤   ¤   ¤   else
5d4859 ¤   ¤   ¤   ¤   ¤   {
291a74 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USE_DISKADK,·
ebd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
741c89 ¤   ¤   ¤   ¤   ¤   }
e6af5a
7b4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
f314c3 ¤   ¤   ¤   ¤   ¤   break;
2d2613 ¤   ¤   ¤   ¤   }
3eaf5a
aad105 ¤   ¤   ¤   case PSN_KILLACTIVE:
0b72c3 ¤   ¤   ¤   ¤   {
9666b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
ef14c3 ¤   ¤   ¤   ¤   ¤   break;
3e2613 ¤   ¤   ¤   ¤   }
a0af5a
cb99a3 ¤   ¤   ¤   case PSN_WIZNEXT:
1172c3 ¤   ¤   ¤   ¤   {
f2266c ¤   ¤   ¤   ¤   ¤   // Determine if we should go to PGPdisk key selection
d72cd6 ¤   ¤   ¤   ¤   ¤   // or skip past it
f0af5a
5aa6e9 ¤   ¤   ¤   ¤   ¤   if (!pConfig->bUseDiskADK)
251039 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT,·
c2cba0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDD_PASSPHRASE);
65af5a
be4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
0a14c3 ¤   ¤   ¤   ¤   ¤   break;
592613 ¤   ¤   ¤   ¤   }
abaf5a
6c49a1 ¤   ¤   ¤   case PSN_WIZBACK:
cf72c3 ¤   ¤   ¤   ¤   {
--d2f3 00010df37ee4011024d Page 17 of AdditionalDecryption.cpp
f014c3 ¤   ¤   ¤   ¤   ¤   break;
092613 ¤   ¤   ¤   ¤   }
5baf5a
7a6122 ¤   ¤   ¤   case PSN_HELP:
7c72c3 ¤   ¤   ¤   ¤   {
0cf1f2 ¤   ¤   ¤   ¤   ¤   // Display help
2f14c3 ¤   ¤   ¤   ¤   ¤   break;
ac2613 ¤   ¤   ¤   ¤   }
1caf5a
2b8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
3372c3 ¤   ¤   ¤   ¤   {
846b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
d3014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
5a14c3 ¤   ¤   ¤   ¤   ¤   break;
182613 ¤   ¤   ¤   ¤   }
01a3a6 ¤   ¤   ¤   }
6387c7 ¤   ¤   ¤
e0cdcb ¤   ¤   ¤   break;
ec0fe4 ¤   ¤   }
5daf5a
cc3fcf ¤   case WM_COMMAND:
5672a4 ¤   ¤   switch (LOWORD(wParam))
8c5b34 ¤   ¤   {
89224f ¤   ¤   case IDC_USE_DISKADK:
95f776 ¤   ¤   ¤   {
4d247b ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_USE_DISKADK) ==·
212a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
6072c3 ¤   ¤   ¤   ¤   {
1d9f0a ¤   ¤   ¤   ¤   ¤   pConfig->bUseDiskADK = TRUE;
b82613 ¤   ¤   ¤   ¤   }
d9fa07 ¤   ¤   ¤   ¤   else
0372c3 ¤   ¤   ¤   ¤   {
e79e86 ¤   ¤   ¤   ¤   ¤   pConfig->bUseDiskADK = FALSE;
202613 ¤   ¤   ¤   ¤   }
f2af5a
82841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
0ef622 ¤   ¤   ¤   ¤   break;
6da3a6 ¤   ¤   ¤   }
2eaf5a
da0fe4 ¤   ¤   }
1eaf5a
632f68 ¤   ¤   break;
f39371 ¤   }
2aaf5a
9a48b1 ¤   return(bReturnCode);
52efe6 }
88af5a
78af5a
8a53d3 BOOL CALLBACK ADKDiskSelectDlgProc(HWND hwndDlg,·
d7218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
ce2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
d475ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
c3bb36 {
c48d02 ¤   BOOL bReturnCode = FALSE;
2b6930 ¤   pgpConfigInfo *pConfig = NULL;
743c96 ¤   HWND hList;
30af5a
be6357 ¤   g_hCurrentDlgWnd = hwndDlg;
b8af5a
0d9450 ¤   if (uMsg != WM_INITDIALOG)
48e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
71af5a
f21b8c ¤   hList = GetDlgItem(hwndDlg, IDC_DISKADK_ID);
b9af5a
71c08d ¤   switch(uMsg)
6ec7a1 ¤   {
8a2940 ¤   case WM_INITDIALOG:
b25b34 ¤   ¤   {
1bafc0 ¤   ¤   ¤   RECT rc;
05313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
5baf5a
10015a ¤   ¤   ¤   // center dialog on screen
--e0db 000489625314011024d Page 18 of AdditionalDecryption.cpp
c0d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
fe3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
220971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
15004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
8af9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
bbaf5a
fd3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
6aad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
6daf5a
b31edf ¤   ¤   ¤   ShowKeyring(hwndDlg, IDC_DISKADK_ID, pConfig->pgpContext,·
695d91 ¤   ¤   ¤   ¤   NULL, TRUE, TRUE, TRUE, FALSE);
c3021f ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
c1cdcb ¤   ¤   ¤   break;
790fe4 ¤   ¤   }
20af5a
6d6b08 ¤   case WM_DESTROY:
13d8cf ¤   ¤   FreeKeyring(hwndDlg, IDC_DISKADK_ID);
862f68 ¤   ¤   break;
1caf5a
9b93f9 ¤   case WM_PAINT:
a3c334 ¤   ¤   if (pConfig->hPalette)
685b34 ¤   ¤   {
c7f431 ¤   ¤   ¤   PAINTSTRUCT ps;
c060df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
934fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
249ffe ¤   ¤   ¤   RealizePalette (hDC);
4d438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
af0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
c00fe4 ¤   ¤   }
9f2f68 ¤   ¤   break;
3a1b52 ¤   ¤
ecc93c ¤   case WM_NOTIFY:
675b34 ¤   ¤   {
b7a08b ¤   ¤   ¤   LPNMHDR pnmh;
c4af5a
df2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
49b7b0 ¤   ¤   ¤   switch(pnmh->code)
d5f776 ¤   ¤   ¤   {
c566bc ¤   ¤   ¤   case PSN_SETACTIVE:
a272c3 ¤   ¤   ¤   ¤   {
5f4a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
25af5a
2b7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
6f5c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
17abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
354859 ¤   ¤   ¤   ¤   ¤   {
47e898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
45ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
b03cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
021c89 ¤   ¤   ¤   ¤   ¤   }
f64bd6 ¤   ¤   ¤   ¤   ¤   else
7c4859 ¤   ¤   ¤   ¤   ¤   {
1fe898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
898e3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
9dd359 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
531c89 ¤   ¤   ¤   ¤   ¤   }
fcaf5a
a59908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
40670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
f6af5a
c4c394 ¤   ¤   ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
ab4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9a14c3 ¤   ¤   ¤   ¤   ¤   break;
2d2613 ¤   ¤   ¤   ¤   }
f0af5a
9dd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
2972c3 ¤   ¤   ¤   ¤   {
11197b ¤   ¤   ¤   ¤   ¤   KillTimer(hwndDlg, ID_TIMER);
284149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
eb14c3 ¤   ¤   ¤   ¤   ¤   break;
242613 ¤   ¤   ¤   ¤   }
48af5a
--dd71 0008598de2e4011024d Page 19 of AdditionalDecryption.cpp
6999a3 ¤   ¤   ¤   case PSN_WIZNEXT:
6872c3 ¤   ¤   ¤   ¤   {
8d4a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
c05283 ¤   ¤   ¤   ¤   ¤   LV_ITEM lviKey;
31e438 ¤   ¤   ¤   ¤   ¤   char *szKeyID;
9bbd59 ¤   ¤   ¤   ¤   ¤   char szUserID[kPGPMaxUserIDSize+1];
d4af5a
5bbe20 ¤   ¤   ¤   ¤   ¤   if (pConfig->szDiskADKID != NULL)
ca4859 ¤   ¤   ¤   ¤   ¤   {
8dec13 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szDiskADKID);
022c89 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szDiskADKID = NULL;
031c89 ¤   ¤   ¤   ¤   ¤   }
19af5a
89ed96 ¤   ¤   ¤   ¤   ¤   if (pConfig->szDiskADK != NULL)
8e4859 ¤   ¤   ¤   ¤   ¤   {
d608d4 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szDiskADK);
179e50 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szDiskADK = NULL;
8d1c89 ¤   ¤   ¤   ¤   ¤   }
84af5a
5766b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
165c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
ccabcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
874859 ¤   ¤   ¤   ¤   ¤   {
752902 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
15b282 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iItem = nIndex;
cb9588 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iSubItem = 0;
b677b4 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.pszText = szUserID;
559c1d ¤   ¤   ¤   ¤   ¤   ¤   lviKey.cchTextMax = kPGPMaxUserIDSize;
3e2337 ¤   ¤   ¤   ¤   ¤   ¤   ListView_GetItem(hList, &lviKey);
4a9e35 ¤   ¤   ¤   ¤   ¤   ¤   szKeyID = (char *) lviKey.lParam;
1eaf5a
3087cc ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szDiskADKID =·
e9cd77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szKeyID)+1);
1b1c05 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szDiskADKID, szKeyID);
cdaf5a
0409e5 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szDiskADK =·
4be764 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szUserID)+1);
002d7b ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szDiskADK, szUserID);
16af5a
b840ef ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_RSAPUBKEY)
4ff84c ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->diskADKKeyType =·
fac69d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA;
c1c4dd ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_DSAPUBKEY)
f5f84c ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->diskADKKeyType =·
4b4945 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_DSA;
a61c89 ¤   ¤   ¤   ¤   ¤   }
e4af5a
f94149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
4814c3 ¤   ¤   ¤   ¤   ¤   break;
c62613 ¤   ¤   ¤   ¤   }
9daf5a
73b546 ¤   ¤   ¤   case PSN_WIZFINISH:
8272c3 ¤   ¤   ¤   ¤   {
d39a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
6014c3 ¤   ¤   ¤   ¤   ¤   break;
dc2613 ¤   ¤   ¤   ¤   }
cbaf5a
3a6122 ¤   ¤   ¤   case PSN_HELP:
2e72c3 ¤   ¤   ¤   ¤   {
11f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
0c14c3 ¤   ¤   ¤   ¤   ¤   break;
4e2613 ¤   ¤   ¤   ¤   }
97af5a
218f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
1b72c3 ¤   ¤   ¤   ¤   {
ae6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
d6014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
8314c3 ¤   ¤   ¤   ¤   ¤   break;
2d2613 ¤   ¤   ¤   ¤   }
dfaf5a
61b108 ¤   ¤   ¤   case NM_CLICK:
8531c1 ¤   ¤   ¤   case NM_RCLICK:
--c14b 0013e819a324011024d Page 20 of AdditionalDecryption.cpp
81168c ¤   ¤   ¤   case NM_DBLCLK:
ee4dc1 ¤   ¤   ¤   case NM_RDBLCLK:
063993 ¤   ¤   ¤   ¤   if (pnmh->idFrom == IDC_DISKADK_ID)
1a72c3 ¤   ¤   ¤   ¤   {
874a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
56af5a
0b5c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
7babcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
384859 ¤   ¤   ¤   ¤   ¤   {
e1b2ca ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
60ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
8f3cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
1a1c89 ¤   ¤   ¤   ¤   ¤   }
9c4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
e22613 ¤   ¤   ¤   ¤   }
edf622 ¤   ¤   ¤   ¤   break;
99af5a
a4a3a6 ¤   ¤   ¤   }
4987c7 ¤   ¤   ¤
3fcdcb ¤   ¤   ¤   break;
9e0fe4 ¤   ¤   }
eeaf5a
95e60b ¤   case WM_TIMER:
a85b34 ¤   ¤   {
ea114f ¤   ¤   ¤   int nIndex;
faaf5a
cfc6b0 ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
ab2df5 ¤   ¤   ¤   if (nIndex > -1)
ccf776 ¤   ¤   ¤   {
e55454 ¤   ¤   ¤   ¤   if (!bNextEnabled)
5c72c3 ¤   ¤   ¤   ¤   {
00e766 ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
aec365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
9a3a0d ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
422613 ¤   ¤   ¤   ¤   }
34a3a6 ¤   ¤   ¤   }
1c39bb ¤   ¤   ¤   else if (bNextEnabled)
bcf776 ¤   ¤   ¤   {
207127 ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
61c577 ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
1dd672 ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
fda3a6 ¤   ¤   ¤   }
adaf5a
8a0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
50196f ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
50cdcb ¤   ¤   ¤   break;
390fe4 ¤   ¤   }
33af5a
1c9371 ¤   }
7aaf5a
9248b1 ¤   return(bReturnCode);
d4efe6 }
79af5a
e9af5a
077e4d /*__Editor_settings____
73af5a
524126 ¤   Local Variables:
647b17 ¤   tab-width: 4
1e0e6c ¤   End:
995f8c ¤   vi: ts=4 sw=4
c69e9b ¤   vim: si
3ed062 _____________________*/
--b42f 000041a27154011024e Page 1 of ClientPrefs.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c69a65 ¤   $Id: ClientPrefs.cpp,v 1.9.8.1 1998/11/12 03:13:02 heller Exp $
92f7f7 ____________________________________________________________________________*/
bdaf5a
255655 #include <windows.h>
35fb83 #include "PGPadmin.h"
9b8031 #include "resource.h"
bec97b #include "pgpClientPrefs.h"
f84919 #include "pgpUtilities.h"
0f91b9 #include "pgpSDKPrefs.h"
a1af5a
77c8cd BOOL CALLBACK ClientPrefsDlgProc(HWND hwndDlg,·
370d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
918347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
26b0d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
a6bb36 {
d80f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
f48ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
42af5a
b76357 ¤   g_hCurrentDlgWnd = hwndDlg;
adaf5a
4a9450 ¤   if (uMsg != WM_INITDIALOG)
8fe72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
27af5a
e8c08d ¤   switch(uMsg)
13c7a1 ¤   {
cf2940 ¤   case WM_INITDIALOG:
535b34 ¤   ¤   {
a4afc0 ¤   ¤   ¤   RECT rc;
21313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
6daf5a
fc015a ¤   ¤   ¤   // center dialog on screen
15d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
79b2c2 ¤   ¤   ¤   SetWindowPos (GetParent(hwndDlg), NULL,
f00971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
89004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
21f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
faaf5a
7c3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
9cad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
4ecdcb ¤   ¤   ¤   break;
e80fe4 ¤   ¤   }
c3af5a
5593f9 ¤   case WM_PAINT:
66c334 ¤   ¤   if (pConfig->hPalette)
d55b34 ¤   ¤   {
88f431 ¤   ¤   ¤   PAINTSTRUCT ps;
5960df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
1d4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
ea9ffe ¤   ¤   ¤   RealizePalette (hDC);
99438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
460fe0 ¤   ¤   ¤   bReturnCode = TRUE;
290fe4 ¤   ¤   }
962f68 ¤   ¤   break;
171b52 ¤   ¤
b6c93c ¤   case WM_NOTIFY:
cc5b34 ¤   ¤   {
c8a08b ¤   ¤   ¤   LPNMHDR pnmh;
39af5a
dd2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
a5b7b0 ¤   ¤   ¤   switch(pnmh->code)
5af776 ¤   ¤   ¤   {
4c66bc ¤   ¤   ¤   case PSN_SETACTIVE:
0672c3 ¤   ¤   ¤   ¤   {
787182 ¤   ¤   ¤   ¤   ¤   // Initialize window
ac5256 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),·
04c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
--0474 000af3e3d874011024e Page 2 of ClientPrefs.cpp
e0af5a
7f9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
b3670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
e2af5a
6efa72 ¤   ¤   ¤   ¤   ¤   if (pConfig->bCopyClientPrefs)
404859 ¤   ¤   ¤   ¤   ¤   {
31f5d3 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USECURRENT,·
c594bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
eb1c89 ¤   ¤   ¤   ¤   ¤   }
9e4bd6 ¤   ¤   ¤   ¤   ¤   else
544859 ¤   ¤   ¤   ¤   ¤   {
94f5d3 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_USECURRENT,·
21d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
551c89 ¤   ¤   ¤   ¤   ¤   }
33af5a
5f4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
6814c3 ¤   ¤   ¤   ¤   ¤   break;
532613 ¤   ¤   ¤   ¤   }
afaf5a
b9d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
a572c3 ¤   ¤   ¤   ¤   {
3466b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
2514c3 ¤   ¤   ¤   ¤   ¤   break;
b42613 ¤   ¤   ¤   ¤   }
39af5a
2f6122 ¤   ¤   ¤   case PSN_HELP:
af72c3 ¤   ¤   ¤   ¤   {
3cf1f2 ¤   ¤   ¤   ¤   ¤   // Display help
5314c3 ¤   ¤   ¤   ¤   ¤   break;
f32613 ¤   ¤   ¤   ¤   }
1daf5a
778f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
0f72c3 ¤   ¤   ¤   ¤   {
8c6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
eb014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
5114c3 ¤   ¤   ¤   ¤   ¤   break;
612613 ¤   ¤   ¤   ¤   }
c6a3a6 ¤   ¤   ¤   }
cd87c7 ¤   ¤   ¤
f8cdcb ¤   ¤   ¤   break;
7f0fe4 ¤   ¤   }
04af5a
663fcf ¤   case WM_COMMAND:
3e72a4 ¤   ¤   switch (LOWORD(wParam))
ee5b34 ¤   ¤   {
54794e ¤   ¤   case IDC_USECURRENT:
b9f776 ¤   ¤   ¤   {
9ee954 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_USECURRENT) ==·
e22a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
8572c3 ¤   ¤   ¤   ¤   {
75f9a7 ¤   ¤   ¤   ¤   ¤   pConfig->bCopyClientPrefs = TRUE;
372613 ¤   ¤   ¤   ¤   }
a8fa07 ¤   ¤   ¤   ¤   else
8e72c3 ¤   ¤   ¤   ¤   {
b4e00f ¤   ¤   ¤   ¤   ¤   pConfig->bCopyClientPrefs = FALSE;
ed2613 ¤   ¤   ¤   ¤   }
b6af5a
64841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
29f622 ¤   ¤   ¤   ¤   break;
0aa3a6 ¤   ¤   ¤   }
5c0fe4 ¤   ¤   }
c0af5a
6e2f68 ¤   ¤   break;
c99371 ¤   }
e7af5a
c848b1 ¤   return(bReturnCode);
2befe6 }
deaf5a
04af5a
757e4d /*__Editor_settings____
61af5a
af4126 ¤   Local Variables:
--232b 001d090f0b54011024e Page 3 of ClientPrefs.cpp
2f7b17 ¤   tab-width: 4
030e6c ¤   End:
9e5f8c ¤   vi: ts=4 sw=4
269e9b ¤   vim: si
d0d062 _____________________*/
--5eac 000f7ea554b4011024f Page 1 of CopyInstaller.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
73fbfa ¤   $Id: CopyInstaller.cpp,v 1.4.8.1 1998/11/12 03:13:02 heller Exp $
f3f7f7 ____________________________________________________________________________*/
d2af5a
635655 #include <windows.h>
61fb83 #include "PGPadmin.h"
1f90fb #include <commctrl.h>
858031 #include "resource.h"
8daf5a
f4af5a
1d97e5 static
9b0b4f DWORD FindInstallerFile(HWND hwnd,
a6d596 ¤   ¤   ¤   ¤   ¤   ¤   char *szFindFile,·
9164c7 ¤   ¤   ¤   ¤   ¤   ¤   HANDLE hFind,
7b5774 ¤   ¤   ¤   ¤   ¤   ¤   WIN32_FIND_DATA *findData,
264caa ¤   ¤   ¤   ¤   ¤   ¤   DWORD *pdwFile,
87a3be ¤   ¤   ¤   ¤   ¤   ¤   DWORD *pdwTotalFiles,
585ba6 ¤   ¤   ¤   ¤   ¤   ¤   char *szPGPPath,·
15235a ¤   ¤   ¤   ¤   ¤   ¤   char *szInstallDir,
643797 ¤   ¤   ¤   ¤   ¤   ¤   BOOL bCopy);
c9af5a
b297e5 static
f24569 void ReportCopyProgress(HWND hwnd,·
7d3b23 ¤   ¤   ¤   ¤   ¤   ¤   char *szFileName,·
2ac5f2 ¤   ¤   ¤   ¤   ¤   ¤   DWORD dwFile,·
8b8a11 ¤   ¤   ¤   ¤   ¤   ¤   DWORD dwTotalFiles);
45af5a
4d46ec BOOL CALLBACK CopyProgressProc(HWND hwndDlg,·
7db014 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
d4f67a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
a2d79f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
2aaf5a
40af5a
a2d7b6 DWORD CopyInstaller(HWND hwnd, char *szClientInstaller, char *szInstallDir)
6fbb36 {
2bc7be ¤   char¤   ¤   ¤   szFindFile[MAX_PATH];
922f48 ¤   char¤   ¤   ¤   szTitle[255];
439816 ¤   WIN32_FIND_DATA findData;
b7ed83 ¤   HANDLE¤ ¤   ¤   hFind;
08c78d ¤   DWORD¤  ¤   ¤   dwFile;
38e859 ¤   DWORD¤  ¤   ¤   dwTotalFiles;
07c461 ¤   DWORD¤  ¤   ¤   dwLastError;
43753a ¤   char¤   ¤   ¤   szError[255];
7b4a2a ¤   HWND¤   ¤   ¤   hwndDlg;
32af5a
c0eecb ¤   strcpy(szFindFile, szClientInstaller);
f7221b ¤   strcat(szFindFile, "*.*");
d9af5a
6840da ¤   SetLastError(0);
7c89b0 ¤   hFind = FindFirstFile(szFindFile, &findData);
1438d0 ¤   dwLastError = GetLastError();
a3af5a
83cac2 ¤   if (dwLastError)
c4c7a1 ¤   {
819f71 ¤   ¤   FormatMessage(¤ FORMAT_MESSAGE_FROM_SYSTEM |·
43c8ab ¤   ¤   ¤   ¤   ¤   ¤   FORMAT_MESSAGE_ARGUMENT_ARRAY,
5c12a6 ¤   ¤   ¤   ¤   ¤   ¤   NULL, dwLastError, 0, szError, 254, NULL);
5967c5 ¤
2c5ecf ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
7f3592 ¤   ¤   MessageBox(hwnd, szError, szTitle, MB_ICONEXCLAMATION);
f9af5a
05e70d ¤   ¤   return dwLastError;
4e9371 ¤   }
58af5a
b9736b ¤   // First, just find files and count up the total
68af5a
f762d3 ¤   dwFile = 0;
--ca24 00091e947034011024f Page 2 of CopyInstaller.cpp
7552cc ¤   dwTotalFiles = 0;
8730d9 ¤   dwLastError = 0;
2267c5 ¤
c98153 ¤   while (!dwLastError)
0dc7a1 ¤   {
3336ee ¤   ¤   dwLastError = FindInstallerFile(hwnd, szFindFile, hFind,·
541d07 ¤   ¤   ¤   ¤   ¤   ¤   &findData, &dwFile, &dwTotalFiles,·
254e61 ¤   ¤   ¤   ¤   ¤   ¤   szClientInstaller, szInstallDir, FALSE);
379371 ¤   }
8e67c5 ¤
c10d77 ¤   FindClose(hFind);
49f52e ¤   hwndDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_COPYPROGRESS),·
16b948 ¤   ¤   ¤   ¤   hwnd, (DLGPROC) CopyProgressProc);
461a36 ¤   ShowWindow(hwndDlg, SW_SHOW);
73af5a
acb515 ¤   // Now, do the actual copying of files
c3af5a
a289b0 ¤   hFind = FindFirstFile(szFindFile, &findData);
3062d3 ¤   dwFile = 0;
c930d9 ¤   dwLastError = 0;
8867c5 ¤
898153 ¤   while (!dwLastError)
aec7a1 ¤   {
b55844 ¤   ¤   dwLastError = FindInstallerFile(hwndDlg, szFindFile, hFind,·
ce1d07 ¤   ¤   ¤   ¤   ¤   ¤   &findData, &dwFile, &dwTotalFiles,·
7282e3 ¤   ¤   ¤   ¤   ¤   ¤   szClientInstaller, szInstallDir, TRUE);
f09371 ¤   }
8b67c5 ¤
fc0d77 ¤   FindClose(hFind);
c3f40a ¤   DestroyWindow(hwndDlg);
d13e6b ¤   return 0;
70efe6 }
90af5a
ccaf5a
080b4f DWORD FindInstallerFile(HWND hwnd,
42d596 ¤   ¤   ¤   ¤   ¤   ¤   char *szFindFile,·
bf64c7 ¤   ¤   ¤   ¤   ¤   ¤   HANDLE hFind,
255774 ¤   ¤   ¤   ¤   ¤   ¤   WIN32_FIND_DATA *findData,
384caa ¤   ¤   ¤   ¤   ¤   ¤   DWORD *pdwFile,
2ea3be ¤   ¤   ¤   ¤   ¤   ¤   DWORD *pdwTotalFiles,
6e5ba6 ¤   ¤   ¤   ¤   ¤   ¤   char *szPGPPath,·
3a235a ¤   ¤   ¤   ¤   ¤   ¤   char *szInstallDir,
0f0456 ¤   ¤   ¤   ¤   ¤   ¤   BOOL bCopy)
b1bb36 {
2cb09a ¤   char szOrigFile[MAX_PATH];
0dc9c4 ¤   char szNewFile[MAX_PATH];
ac5c1d ¤   char szFindSubFile[MAX_PATH];
de8b71 ¤   char szError[255];
0ad103 ¤   char szTitle[255];
cd58e3 ¤   HANDLE hFindSub;
08df1f ¤   DWORD dwLastError;
d9af5a
18654d ¤   // Ignore "." and ".."
f3af5a
5250b4 ¤   if (!strcmp(findData->cFileName, ".") ||·
b478fe ¤   ¤   !strcmp(findData->cFileName, ".."))
b1c7a1 ¤   {
f1f10b ¤   ¤   SetLastError(0);
b6267c ¤   ¤   FindNextFile(hFind, findData);
add7a3 ¤   ¤   dwLastError = GetLastError();
c9e70d ¤   ¤   return dwLastError;
c69371 ¤   }
8baf5a
43b6bf ¤   strcpy(szOrigFile, szPGPPath);
d5722d ¤   strcpy(szNewFile, szInstallDir);
540811 ¤   strcat(szOrigFile, findData->cFileName);
ba312d ¤   strcat(szNewFile, findData->cFileName);
b2af5a
570457 ¤   // If it's a directory, create a copy, and start finding
36f781 ¤   // files within that directory
7daf5a
911686 ¤   if (findData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
--afbe 000bab8de434011024f Page 3 of CopyInstaller.cpp
f7c7a1 ¤   {
f46752 ¤   ¤   CreateDirectory(szNewFile, NULL);
a32a27 ¤   ¤   strcat(szOrigFile, "\\");
89b4dc ¤   ¤   strcat(szNewFile, "\\");
f84753 ¤   ¤   strcpy(szFindSubFile, szOrigFile);
d8330c ¤   ¤   strcat(szFindSubFile, "*.*");
96f10b ¤   ¤   SetLastError(0);
6f5b6a ¤   ¤   hFindSub = FindFirstFile(szFindSubFile, findData);
21d7a3 ¤   ¤   dwLastError = GetLastError();
ff1b52 ¤   ¤
837b13 ¤   ¤   if (dwLastError)
e25b34 ¤   ¤   {
769c06 ¤   ¤   ¤   FormatMessage(¤ FORMAT_MESSAGE_FROM_SYSTEM |·
c9013e ¤   ¤   ¤   ¤   FORMAT_MESSAGE_ARGUMENT_ARRAY,
729fb8 ¤   ¤   ¤   ¤   NULL, dwLastError, 0, szError, 254, NULL);
bc87c7 ¤   ¤   ¤
d9bccf ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
0508fc ¤   ¤   ¤   MessageBox(hwnd, szError, szTitle, MB_ICONEXCLAMATION);
8487c7 ¤   ¤   ¤
634a53 ¤   ¤   ¤   return dwLastError;
f20fe4 ¤   ¤   }
7daf5a
bcb50e ¤   ¤   while (!dwLastError)
ef5b34 ¤   ¤   {
d5f80b ¤   ¤   ¤   dwLastError = FindInstallerFile(hwnd, szFindSubFile, hFindSub,·
b98623 ¤   ¤   ¤   ¤   ¤   ¤   ¤   findData, pdwFile, pdwTotalFiles,·
8b0581 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szOrigFile, szNewFile, bCopy);
c00fe4 ¤   ¤   }
b3af5a
6ada24 ¤   ¤   FindClose(hFindSub);
b79371 ¤   }
59af5a
6b73e3 ¤   // If it's a file, copy it
e6af5a
4a0e24 ¤   else
2fc7a1 ¤   {
f977eb ¤   ¤   if (bCopy)
ba5b34 ¤   ¤   {
1faaa8 ¤   ¤   ¤   ReportCopyProgress(hwnd, szNewFile, *pdwFile, *pdwTotalFiles);
73838b ¤   ¤   ¤   CopyFile(szOrigFile, szNewFile, FALSE);
cc0fe4 ¤   ¤   }
9e0e1d ¤   ¤   else
1b59ea ¤   ¤   ¤   (*pdwTotalFiles)++;
d6af5a
2a87f3 ¤   ¤   (*pdwFile)++;
ac9371 ¤   }
02af5a
d340da ¤   SetLastError(0);
f5678f ¤   FindNextFile(hFind, findData);
2438d0 ¤   dwLastError = GetLastError();
541168 ¤   return dwLastError;
e8efe6 }
86af5a
15af5a
ae4569 void ReportCopyProgress(HWND hwnd,·
3f3b23 ¤   ¤   ¤   ¤   ¤   ¤   char *szFileName,·
1dc5f2 ¤   ¤   ¤   ¤   ¤   ¤   DWORD dwFile,·
0c496e ¤   ¤   ¤   ¤   ¤   ¤   DWORD dwTotalFiles)
88bb36 {
fbbbbc ¤   DWORD dwPos;
95af5a
7e2493 ¤   dwPos = 100 * dwFile / dwTotalFiles;
189f12 ¤   SendMessage(GetDlgItem(hwnd, IDC_PROGRESS), PBM_SETPOS, dwPos, 0);
05e6ed ¤   SetWindowText(GetDlgItem(hwnd, IDC_FILENAME), szFileName);
8666e6 ¤   UpdateWindow(hwnd);
59af5a
85830f ¤   return;
74efe6 }
75af5a
0baf5a
8b46ec BOOL CALLBACK CopyProgressProc(HWND hwndDlg,·
bab014 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
--9b6d 001ed4ae2a84011024f Page 4 of CopyInstaller.cpp
b4f67a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
873ac1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
8ebb36 {
1cc08d ¤   switch(uMsg)
d2c7a1 ¤   {
c22940 ¤   case WM_INITDIALOG:
015b34 ¤   ¤   {
66afc0 ¤   ¤   ¤   RECT rc;
37af5a
cd015a ¤   ¤   ¤   // center dialog on screen
a8d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
fa3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
ae0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
1e004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
90f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
3daf5a
25cdcb ¤   ¤   ¤   break;
5b0fe4 ¤   ¤   }
cb9371 ¤   }
f0af5a
953e6b ¤   return 0;
37efe6 }
47af5a
00af5a
d17e4d /*__Editor_settings____
2caf5a
c54126 ¤   Local Variables:
187b17 ¤   tab-width: 4
4b0e6c ¤   End:
ca5f8c ¤   vi: ts=4 sw=4
599e9b ¤   vim: si
edd062 _____________________*/
--b6ee 00132df24c240110250 Page 1 of CopyInstaller.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e3a030 ¤   $Id: CopyInstaller.h,v 1.2.18.1 1998/11/12 03:13:03 heller Exp $
a6f7f7 ____________________________________________________________________________*/
2ccef2 #ifndef Included_CopyInstaller_h¤   /* [ */
27bed9 #define Included_CopyInstaller_h
70af5a
27d04a DWORD CopyInstaller(HWND hwnd, char *szClientInstaller, char *szInstallDir);
96af5a
96eec8 #endif /* ] Included_CopyInstaller_h */
f3af5a
e6af5a
297e4d /*__Editor_settings____
0aaf5a
314126 ¤   Local Variables:
187b17 ¤   tab-width: 4
450e6c ¤   End:
915f8c ¤   vi: ts=4 sw=4
2c9e9b ¤   vim: si
32d062 _____________________*/
--165d 0004da0f23440110251 Page 1 of CorpKey.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
387070 ¤   $Id: CorpKey.cpp,v 1.20.8.1 1998/11/12 03:13:03 heller Exp $
daf7f7 ____________________________________________________________________________*/
9faf5a
815655 #include <windows.h>
87fb83 #include "PGPadmin.h"
ac90fb #include <commctrl.h>
518031 #include "resource.h"
173bb4 #include "Utils.h"
a20d08 #include "pgpMem.h"
4d7528 #include "pgpImage.h"
6aaf5a
99b779 #define ID_TIMER¤   42
3eaf5a
fcafc0 static BOOL bNextEnabled = FALSE;
2faf5a
f132b9 BOOL CALLBACK CorpKeyDlgProc(HWND hwndDlg,·
cc0bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
44d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
89a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
87bb36 {
951d63 ¤   BOOL¤   ¤   ¤   bReturnCode¤= FALSE;
968ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
b3af5a
866357 ¤   g_hCurrentDlgWnd = hwndDlg;
08af5a
af9450 ¤   if (uMsg != WM_INITDIALOG)
c0e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
91af5a
8bc08d ¤   switch(uMsg)
44c7a1 ¤   {
982940 ¤   case WM_INITDIALOG:
8a5b34 ¤   ¤   {
96afc0 ¤   ¤   ¤   RECT rc;
af313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
56af5a
5a015a ¤   ¤   ¤   // center dialog on screen
e4d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
ca3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
320971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
ae004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
c1f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
b1af5a
093970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
a3ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
ddcdcb ¤   ¤   ¤   break;
6f0fe4 ¤   ¤   }
1b1b52 ¤   ¤
8993f9 ¤   case WM_PAINT:
a4c334 ¤   ¤   if (pConfig->hPalette)
155b34 ¤   ¤   {
42f431 ¤   ¤   ¤   PAINTSTRUCT ps;
c360df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
b14fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
ec9ffe ¤   ¤   ¤   RealizePalette (hDC);
28438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
ea0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
6d0fe4 ¤   ¤   }
ff2f68 ¤   ¤   break;
811b52 ¤   ¤
18c93c ¤   case WM_NOTIFY:
c05b34 ¤   ¤   {
92a08b ¤   ¤   ¤   LPNMHDR pnmh;
e6af5a
e12b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
d6b7b0 ¤   ¤   ¤   switch(pnmh->code)
4df776 ¤   ¤   ¤   {
--e70e 00048312dbf40110251 Page 2 of CorpKey.cpp
d566bc ¤   ¤   ¤   case PSN_SETACTIVE:
2972c3 ¤   ¤   ¤   ¤   {
367182 ¤   ¤   ¤   ¤   ¤   // Initialize window
54bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
f4c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
f3af5a
cd9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
84670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
95af5a
aba7b9 ¤   ¤   ¤   ¤   ¤   if (pConfig->bAutoSignTrustCorp)
834859 ¤   ¤   ¤   ¤   ¤   {
b7d59a ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_AUTOSIGNTRUST,·
9b94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
43a0e5 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_METAINTRODUCER),
6c1dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
1af988 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_WARN_NOTCERT),
bb1dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
f81c89 ¤   ¤   ¤   ¤   ¤   }
b64bd6 ¤   ¤   ¤   ¤   ¤   else
d74859 ¤   ¤   ¤   ¤   ¤   {
7dd59a ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_AUTOSIGNTRUST,·
17d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
24a0e5 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_METAINTRODUCER),
597f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
02f988 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_WARN_NOTCERT),
e97f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
8b1c89 ¤   ¤   ¤   ¤   ¤   }
a4af5a
799de2 ¤   ¤   ¤   ¤   ¤   if (pConfig->bMetaIntroducerCorp)
ea4859 ¤   ¤   ¤   ¤   ¤   {
e45d1f ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_METAINTRODUCER,·
cb94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
4d1c89 ¤   ¤   ¤   ¤   ¤   }
3a4bd6 ¤   ¤   ¤   ¤   ¤   else
c44859 ¤   ¤   ¤   ¤   ¤   {
285d1f ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_METAINTRODUCER,·
00d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
1b1c89 ¤   ¤   ¤   ¤   ¤   }
00af5a
aceacc ¤   ¤   ¤   ¤   ¤   if (pConfig->bWarnNotCertByCorp)
be4859 ¤   ¤   ¤   ¤   ¤   {
3b1292 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_WARN_NOTCERT,·
7894bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
a51c89 ¤   ¤   ¤   ¤   ¤   }
904bd6 ¤   ¤   ¤   ¤   ¤   else
f74859 ¤   ¤   ¤   ¤   ¤   {
411292 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_WARN_NOTCERT,·
bbd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
881c89 ¤   ¤   ¤   ¤   ¤   }
1baf5a
c44149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
1c14c3 ¤   ¤   ¤   ¤   ¤   break;
c62613 ¤   ¤   ¤   ¤   }
efaf5a
1cd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
8c72c3 ¤   ¤   ¤   ¤   {
dd66b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
6a14c3 ¤   ¤   ¤   ¤   ¤   break;
842613 ¤   ¤   ¤   ¤   }
27af5a
6999a3 ¤   ¤   ¤   case PSN_WIZNEXT:
6072c3 ¤   ¤   ¤   ¤   {
6814df ¤   ¤   ¤   ¤   ¤   // Determine if we should go to corp key selection
9d291a ¤   ¤   ¤   ¤   ¤   // or skip to next page
13af5a
b707c2 ¤   ¤   ¤   ¤   ¤   if (!pConfig->bAutoSignTrustCorp)
790cd4 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_REVOKER);
daaf5a
184149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c014c3 ¤   ¤   ¤   ¤   ¤   break;
832613 ¤   ¤   ¤   ¤   }
48af5a
--3712 0005c2ba14340110251 Page 3 of CorpKey.cpp
dc6122 ¤   ¤   ¤   case PSN_HELP:
7272c3 ¤   ¤   ¤   ¤   {
63f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
5814c3 ¤   ¤   ¤   ¤   ¤   break;
092613 ¤   ¤   ¤   ¤   }
22af5a
158f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
0c72c3 ¤   ¤   ¤   ¤   {
4b6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
12014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
e314c3 ¤   ¤   ¤   ¤   ¤   break;
562613 ¤   ¤   ¤   ¤   }
d2a3a6 ¤   ¤   ¤   }
2b87c7 ¤   ¤   ¤
1acdcb ¤   ¤   ¤   break;
ae0fe4 ¤   ¤   }
89af5a
ff3fcf ¤   case WM_COMMAND:
f172a4 ¤   ¤   switch (LOWORD(wParam))
2b5b34 ¤   ¤   {
ef52b7 ¤   ¤   case IDC_AUTOSIGNTRUST:
0ef776 ¤   ¤   ¤   {
2e7a98 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_AUTOSIGNTRUST) ==·
572a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
3e72c3 ¤   ¤   ¤   ¤   {
91fa49 ¤   ¤   ¤   ¤   ¤   pConfig->bAutoSignTrustCorp = TRUE;
5cd9af ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_METAINTRODUCER),
6c91ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
94e281 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_WARN_NOTCERT),
ed91ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
3a2613 ¤   ¤   ¤   ¤   }
68fa07 ¤   ¤   ¤   ¤   else
4472c3 ¤   ¤   ¤   ¤   {
8eee7c ¤   ¤   ¤   ¤   ¤   pConfig->bAutoSignTrustCorp = FALSE;
755201 ¤   ¤   ¤   ¤   ¤   pConfig->bMetaIntroducerCorp = FALSE;
60182d ¤   ¤   ¤   ¤   ¤   pConfig->bWarnNotCertByCorp = FALSE;
3faf5a
2dd9af ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_METAINTRODUCER),
f8f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
dfd75a ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_METAINTRODUCER,·
395809 ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
d2af5a
0ee281 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_WARN_NOTCERT),
41f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
979f6e ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_WARN_NOTCERT,·
0b5809 ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
b82613 ¤   ¤   ¤   ¤   }
00af5a
c9841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
94f622 ¤   ¤   ¤   ¤   break;
4aa3a6 ¤   ¤   ¤   }
d5af5a
522f76 ¤   ¤   case IDC_METAINTRODUCER:
34f776 ¤   ¤   ¤   {
91e3e2 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_METAINTRODUCER) ==·
af2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
3672c3 ¤   ¤   ¤   ¤   {
d64460 ¤   ¤   ¤   ¤   ¤   pConfig->bMetaIntroducerCorp = TRUE;
da2613 ¤   ¤   ¤   ¤   }
98fa07 ¤   ¤   ¤   ¤   else
6a72c3 ¤   ¤   ¤   ¤   {
215201 ¤   ¤   ¤   ¤   ¤   pConfig->bMetaIntroducerCorp = FALSE;
342613 ¤   ¤   ¤   ¤   }
feaf5a
3e841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
6df622 ¤   ¤   ¤   ¤   break;
e6a3a6 ¤   ¤   ¤   }
ddaf5a
4f7ab2 ¤   ¤   case IDC_WARN_NOTCERT:
7ff776 ¤   ¤   ¤   {
e95a81 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_WARN_NOTCERT) ==·
5c2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
--f181 000cc594aba40110251 Page 4 of CorpKey.cpp
d072c3 ¤   ¤   ¤   ¤   {
0d2ca8 ¤   ¤   ¤   ¤   ¤   pConfig->bWarnNotCertByCorp = TRUE;
0e2613 ¤   ¤   ¤   ¤   }
eafa07 ¤   ¤   ¤   ¤   else
1872c3 ¤   ¤   ¤   ¤   {
69182d ¤   ¤   ¤   ¤   ¤   pConfig->bWarnNotCertByCorp = FALSE;
252613 ¤   ¤   ¤   ¤   }
53af5a
1a841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
7cf622 ¤   ¤   ¤   ¤   break;
9ca3a6 ¤   ¤   ¤   }
fa0fe4 ¤   ¤   }
aaaf5a
b42f68 ¤   ¤   break;
a19371 ¤   }
d8af5a
1848b1 ¤   return(bReturnCode);
f5efe6 }
a2af5a
f3af5a
81b1ff BOOL CALLBACK CorpKeySelectDlgProc(HWND hwndDlg,·
fd218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
ff2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
cf75ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
75bb36 {
4c0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
c88ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
7b3c96 ¤   HWND hList;
f3af5a
476357 ¤   g_hCurrentDlgWnd = hwndDlg;
7daf5a
6d9450 ¤   if (uMsg != WM_INITDIALOG)
e6e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
afaf5a
91797c ¤   hList = GetDlgItem(hwndDlg, IDC_CORPKEY_ID);
a2af5a
8cc08d ¤   switch(uMsg)
8ec7a1 ¤   {
a02940 ¤   case WM_INITDIALOG:
d35b34 ¤   ¤   {
eeafc0 ¤   ¤   ¤   RECT rc;
11313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
aaaf5a
37015a ¤   ¤   ¤   // center dialog on screen
8bd4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
f23d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
6b0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
ab004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
97f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
a2af5a
d53970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
baad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
cdaf5a
5992bc ¤   ¤   ¤   ShowKeyring(hwndDlg, IDC_CORPKEY_ID, pConfig->pgpContext,·
fb0f59 ¤   ¤   ¤   ¤   NULL, TRUE, TRUE, FALSE, TRUE);
29021f ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
9dcdcb ¤   ¤   ¤   break;
6d0fe4 ¤   ¤   }
4baf5a
e56b08 ¤   case WM_DESTROY:
60ba3f ¤   ¤   FreeKeyring(hwndDlg, IDC_CORPKEY_ID);
292f68 ¤   ¤   break;
6eaf5a
a293f9 ¤   case WM_PAINT:
4fc334 ¤   ¤   if (pConfig->hPalette)
6d5b34 ¤   ¤   {
02f431 ¤   ¤   ¤   PAINTSTRUCT ps;
dd60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
fb4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
c89ffe ¤   ¤   ¤   RealizePalette (hDC);
60438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
cc0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
--074c 00014826ef940110251 Page 5 of CorpKey.cpp
b50fe4 ¤   ¤   }
892f68 ¤   ¤   break;
221b52 ¤   ¤
21c93c ¤   case WM_NOTIFY:
495b34 ¤   ¤   {
93a08b ¤   ¤   ¤   LPNMHDR pnmh;
7faf5a
f22b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
a5b7b0 ¤   ¤   ¤   switch(pnmh->code)
38f776 ¤   ¤   ¤   {
6166bc ¤   ¤   ¤   case PSN_SETACTIVE:
5b72c3 ¤   ¤   ¤   ¤   {
114a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
23af5a
847182 ¤   ¤   ¤   ¤   ¤   // Initialize window
565c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
60abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
f54859 ¤   ¤   ¤   ¤   ¤   {
8fe898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
01ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
923cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
841c89 ¤   ¤   ¤   ¤   ¤   }
894bd6 ¤   ¤   ¤   ¤   ¤   else
664859 ¤   ¤   ¤   ¤   ¤   {
eae898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
1f8e3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
8cd359 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
d51c89 ¤   ¤   ¤   ¤   ¤   }
53af5a
449908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
ac670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
d5af5a
38c394 ¤   ¤   ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
0a4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ad14c3 ¤   ¤   ¤   ¤   ¤   break;
2d2613 ¤   ¤   ¤   ¤   }
87af5a
10d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
5372c3 ¤   ¤   ¤   ¤   {
6f197b ¤   ¤   ¤   ¤   ¤   KillTimer(hwndDlg, ID_TIMER);
be4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
8e14c3 ¤   ¤   ¤   ¤   ¤   break;
d82613 ¤   ¤   ¤   ¤   }
bcaf5a
b199a3 ¤   ¤   ¤   case PSN_WIZNEXT:
9a72c3 ¤   ¤   ¤   ¤   {
b24a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
dd5283 ¤   ¤   ¤   ¤   ¤   LV_ITEM lviKey;
a4e438 ¤   ¤   ¤   ¤   ¤   char *szKeyID;
d6bd59 ¤   ¤   ¤   ¤   ¤   char szUserID[kPGPMaxUserIDSize+1];
ffaf5a
f7d9a7 ¤   ¤   ¤   ¤   ¤   if (pConfig->szCorpKeyID != NULL)
974859 ¤   ¤   ¤   ¤   ¤   {
5af481 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szCorpKeyID);
ee8dad ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szCorpKeyID = NULL;
0f1c89 ¤   ¤   ¤   ¤   ¤   }
28af5a
50e372 ¤   ¤   ¤   ¤   ¤   if (pConfig->szCorpKey != NULL)
414859 ¤   ¤   ¤   ¤   ¤   {
6f1d95 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szCorpKey);
dc0abe ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szCorpKey = NULL;
341c89 ¤   ¤   ¤   ¤   ¤   }
69af5a
0f66b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
b45c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
eaabcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
f74859 ¤   ¤   ¤   ¤   ¤   {
472902 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
d9b282 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iItem = nIndex;
e69588 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iSubItem = 0;
e577b4 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.pszText = szUserID;
149c1d ¤   ¤   ¤   ¤   ¤   ¤   lviKey.cchTextMax = kPGPMaxUserIDSize;
--3357 00068eeeae440110251 Page 6 of CorpKey.cpp
ff2337 ¤   ¤   ¤   ¤   ¤   ¤   ListView_GetItem(hList, &lviKey);
9c9e35 ¤   ¤   ¤   ¤   ¤   ¤   szKeyID = (char *) lviKey.lParam;
62af5a
02304f ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szCorpKeyID =·
14cd77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szKeyID)+1);
07ca78 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szCorpKeyID, szKeyID);
baaf5a
d75a7d ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szCorpKey =·
9ee764 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szUserID)+1);
7addab ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szCorpKey, szUserID);
78af5a
3a40ef ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_RSAPUBKEY)
8d7f20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->corpKeyType = kPGPPublicKeyAlgorithm_RSA;
02c4dd ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_DSAPUBKEY)
64f0f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->corpKeyType = kPGPPublicKeyAlgorithm_DSA;
181c89 ¤   ¤   ¤   ¤   ¤   }
afaf5a
bb4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
1c14c3 ¤   ¤   ¤   ¤   ¤   break;
732613 ¤   ¤   ¤   ¤   }
e1af5a
2e6122 ¤   ¤   ¤   case PSN_HELP:
f072c3 ¤   ¤   ¤   ¤   {
04f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
ce14c3 ¤   ¤   ¤   ¤   ¤   break;
eb2613 ¤   ¤   ¤   ¤   }
53af5a
e28f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
a472c3 ¤   ¤   ¤   ¤   {
246b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
ed014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
e814c3 ¤   ¤   ¤   ¤   ¤   break;
d02613 ¤   ¤   ¤   ¤   }
48af5a
36b108 ¤   ¤   ¤   case NM_CLICK:
6831c1 ¤   ¤   ¤   case NM_RCLICK:
f2168c ¤   ¤   ¤   case NM_DBLCLK:
664dc1 ¤   ¤   ¤   case NM_RDBLCLK:
afc7e2 ¤   ¤   ¤   ¤   if (pnmh->idFrom == IDC_CORPKEY_ID)
eb72c3 ¤   ¤   ¤   ¤   {
2e4a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
f4af5a
c55c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
ebabcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
4d4859 ¤   ¤   ¤   ¤   ¤   {
27b2ca ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
15ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
533cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
ac1c89 ¤   ¤   ¤   ¤   ¤   }
cf4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9a2613 ¤   ¤   ¤   ¤   }
52f622 ¤   ¤   ¤   ¤   break;
a0a3a6 ¤   ¤   ¤   }
6687c7 ¤   ¤   ¤
d4cdcb ¤   ¤   ¤   break;
9a0fe4 ¤   ¤   }
33af5a
bee60b ¤   case WM_TIMER:
a85b34 ¤   ¤   {
71114f ¤   ¤   ¤   int nIndex;
9daf5a
eec6b0 ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
1e2df5 ¤   ¤   ¤   if (nIndex > -1)
e9f776 ¤   ¤   ¤   {
465454 ¤   ¤   ¤   ¤   if (!bNextEnabled)
6872c3 ¤   ¤   ¤   ¤   {
a2e766 ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
7ac365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
733a0d ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
a52613 ¤   ¤   ¤   ¤   }
baa3a6 ¤   ¤   ¤   }
6839bb ¤   ¤   ¤   else if (bNextEnabled)
--838d 001dcd42a0f40110251 Page 7 of CorpKey.cpp
99f776 ¤   ¤   ¤   {
a17127 ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
27c577 ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
d0d672 ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
f1a3a6 ¤   ¤   ¤   }
7aaf5a
d40fe0 ¤   ¤   ¤   bReturnCode = TRUE;
14196f ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
75cdcb ¤   ¤   ¤   break;
810fe4 ¤   ¤   }
679371 ¤   }
a0af5a
4b48b1 ¤   return(bReturnCode);
87efe6 }
55af5a
567e4d /*__Editor_settings____
ddaf5a
a34126 ¤   Local Variables:
d47b17 ¤   tab-width: 4
380e6c ¤   End:
995f8c ¤   vi: ts=4 sw=4
0f9e9b ¤   vim: si
dcd062 _____________________*/
--2f79 0000f81f01d40110252 Page 1 of CreateWiz.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ebf772 ¤   $Id: CreateWiz.cpp,v 1.66.8.1 1998/11/12 03:13:04 heller Exp $
f6f7f7 ____________________________________________________________________________*/
48af5a
b65655 #include <windows.h>
d7fb83 #include "PGPadmin.h"
9b8031 #include "resource.h"
4c6867 #include "CreateWiz.h"
6bae72 #include "FindInstaller.h"
8b3d8e #include "CopyInstaller.h"
ee3bb4 #include "Utils.h"
5ee8b2 #include "pflPrefs.h"
0f4720 #include "pflPrefTypes.h"
160d08 #include "pgpMem.h"
dc894b #include "pgpFileSpec.h"
62a076 #include "pgpKeys.h"
ce3991 #include "pgpAdminPrefs.h"
a54919 #include "pgpUtilities.h"
a4bd2c #include "pgpVersion.h"
275ab2 #include "PGPcl.h"
41af5a
b86dad extern "C" {
5b8e25 #include "pgpVersionHeader.h"
ec82f7 };
feaf5a
fe8844 static pgpConfigInfo Config;
9faf5a
1d597e static HPALETTE·
aecef8 CreateDIBPalette (LPBITMAPINFO lpbmi,·
905586 ¤   ¤   ¤   ¤   ··LPINT lpiNumColors);
6baf5a
66fb93 static HBITMAP·
80d9f1 LoadResourceBitmap (HINSTANCE hInstance,·
09d7f9 ¤   ¤   ¤   ¤   ¤   LPSTR lpString,
ff2207 ¤   ¤   ¤   ¤   ¤   HPALETTE FAR* lphPalette);
3daf5a
daa05c #define DEFAULT_USERINSTALLDIR "C:\\Program Files\\Network Associates\\PGP60"
69af5a
e17264 void CreateWiz(HWND hwndMain)
45bb36 {
c9f4fb ¤   PROPSHEETPAGE¤  pspWiz[NUM_WIZ_PAGES];
6d4a77 ¤   PROPSHEETHEADER pshWiz;
1792c3 ¤   int¤¤   ¤   ¤   nIndex;
c27963 ¤   int iNumBits,¤  iBitmap;
5907aa ¤   HDC¤¤   ¤   ¤   hDC;
592f48 ¤   char¤   ¤   ¤   szTitle[255];
4be78d ¤   char¤   ¤   ¤   szMsg[255];
0b9cab ¤   char¤   ¤   ¤   szClientInstaller[MAX_PATH];
032e18 ¤   char¤   ¤   ¤   szDisk[255];
298292 ¤   char¤   ¤   ¤   szPGPPath[MAX_PATH];
6ced83 ¤   HANDLE¤ ¤   ¤   hFind;
909816 ¤   WIN32_FIND_DATA findData;
f37373 ¤   BOOL¤   ¤   ¤   bCancel;
67fb19 ¤   PGPError¤   ¤   err;
4baf5a
acb1b3 ¤   // Make sure SDK isn't expired·
00af5a
3d4c9d ¤   err = PGPNewContext(kPGPsdkAPIVersion, &(Config.pgpContext));
fa82f0 ¤   if (IsPGPError(err))
bbc7a1 ¤   {
5132d7 ¤   ¤   if (err == kPGPError_FeatureNotAvailable)
db5b34 ¤   ¤   {
b834f0 ¤   ¤   ¤   LoadString(g_hInstance, IDS_E_EXPIRED, szMsg, 254);
a0bccf ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
cf0f96 ¤   ¤   ¤   MessageBox(hwndMain, szMsg, szTitle, MB_ICONWARNING);
b10fe4 ¤   ¤   }
0f0e1d ¤   ¤   else
--ef38 000094d47e540110252 Page 2 of CreateWiz.cpp
60a729 ¤   ¤   ¤   PGPclErrorBox(hwndMain, err);
66af5a
f03f77 ¤   ¤   g_bGotReloadMsg = FALSE;
1c99bf ¤   ¤   return;
3d9371 ¤   }
2baf5a
2661eb ¤   err = PGPclInitLibrary(Config.pgpContext);
fc82f0 ¤   if (IsPGPError(err))
e5c7a1 ¤   {
564fc6 ¤   ¤   PGPclErrorBox (hwndMain, err);
883f77 ¤   ¤   g_bGotReloadMsg = FALSE;
2c99bf ¤   ¤   return;
799371 ¤   }
76af5a
cf9c6d ¤   // Check for beta/demo expiration
19af5a
dc56e5 ¤   if (PGPclIsExpired(hwndMain) != kPGPError_NoErr)
65c7a1 ¤   {
473f77 ¤   ¤   g_bGotReloadMsg = FALSE;
4d99bf ¤   ¤   return;
ad9371 ¤   }
a967c5 ¤
89910d ¤   // Check to make sure the ClientInstaller directory
2e93b1 ¤   // is present in the PGP directory
6167c5 ¤
a74544 ¤   PGPclGetPGPPath(szPGPPath, MAX_PATH-1);
e0455c ¤   LoadString(g_hInstance, IDS_CLIENTINSTALLER, szClientInstaller,
d3b840 ¤   ¤   MAX_PATH-1);
52c23e ¤   LoadString(g_hInstance, IDS_INSTALLDISK, szDisk, 254);
86fe51 ¤   strcat(szPGPPath, szClientInstaller);
91b2fd ¤   strcpy(szClientInstaller, szPGPPath);
f00431 ¤   strcat(szPGPPath, szDisk);
c6af5a
b32db3 ¤   bCancel = FALSE;
43c37a ¤   LoadString(g_hInstance, IDS_E_CLIENTINSTALLER, szMsg, 254);
645db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
cbcfa1 ¤   do
a4c7a1 ¤   {
a0056f ¤   ¤   hFind = FindFirstFile(szPGPPath, &findData);
01dacf ¤   ¤   if (hFind == INVALID_HANDLE_VALUE)
d85b34 ¤   ¤   {
3ce016 ¤   ¤   ¤   MessageBox(hwndMain, szMsg, szTitle, MB_ICONEXCLAMATION);
09af5a
3fbaf4 ¤   ¤   ¤   bCancel = DialogBoxParam(g_hInstance,·
58d5f8 ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_FINDINSTALLER),
c6f6a3 ¤   ¤   ¤   ¤   ¤   ¤   hwndMain, (DLGPROC) FindInstallerDlgProc,·
46b68c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) szClientInstaller);
cfaf5a
1db636 ¤   ¤   ¤   strcpy(szPGPPath, szClientInstaller);
dfc9bd ¤   ¤   ¤   strcat(szPGPPath, szDisk);
e70fe4 ¤   ¤   }
bd9371 ¤   }
588ec9 ¤   while ((hFind == INVALID_HANDLE_VALUE) && (bCancel == FALSE));
78af5a
4a473f ¤   if (bCancel)
06c7a1 ¤   {
3d3f77 ¤   ¤   g_bGotReloadMsg = FALSE;
54e95e ¤   ¤   if (Config.pgpContext)
156284 ¤   ¤   ¤   PGPFreeContext(Config.pgpContext);
f1af5a
7899bf ¤   ¤   return;
189371 ¤   }
a04264 ¤   else·
32cac2 ¤   ¤   FindClose(hFind);
5daf5a
53686b ¤   // Set defaults here:
01af5a
3e6637 ¤   Config.memoryMgr = PGPGetContextMemoryMgr(Config.pgpContext);
b3e223 ¤   Config.hBitmap = NULL;
485209 ¤   Config.hPalette = NULL;
0d1f32 ¤   Config.szLicenseNum = NULL;
093f23 ¤   Config.bUseOutgoingADK = FALSE;
--03f6 000ec4d39a540110252 Page 3 of CreateWiz.cpp
e5f15f ¤   Config.bUseIncomingADK = FALSE;
f9d5ab ¤   Config.bUseDiskADK = FALSE;
b3ec42 ¤   Config.szOutgoingADKID = NULL;
ceb7a0 ¤   Config.szOutgoingADK = NULL;
6e5567 ¤   Config.szIncomingADKID = NULL;
7487e8 ¤   Config.szIncomingADK = NULL;
c51e4b ¤   Config.szDiskADKID = NULL;
4a40bb ¤   Config.szDiskADK = NULL;
031fea ¤   Config.bEnforceIncomingADK = FALSE;
13d196 ¤   Config.bEnforceOutgoingADK = FALSE;
b02c9f ¤   Config.bEnforceRemoteADK = TRUE;
1b20d9 ¤   Config.bEnforceMinChars = FALSE;
d4559a ¤   Config.nMinChars = 8;
5f63f0 ¤   Config.bEnforceMinQuality = FALSE;
b5a381 ¤   Config.nMinQuality = 20;
3bbf6f ¤   Config.szCorpKeyID = NULL;
3bd455 ¤   Config.szCorpKey = NULL;
3f5b7a ¤   Config.corpKeyType = (PGPPublicKeyAlgorithm) 0;
ac596d ¤   Config.outgoingADKKeyType = (PGPPublicKeyAlgorithm) 0;
8df151 ¤   Config.diskADKKeyType = (PGPPublicKeyAlgorithm) 0;
8a7a15 ¤   Config.bWarnNotCertByCorp = FALSE;
618c44 ¤   Config.bAutoSignTrustCorp = FALSE;
fcefa8 ¤   Config.bMetaIntroducerCorp = FALSE;
290747 ¤   Config.bAutoAddRevoker = FALSE;
e9c28a ¤   Config.szRevokerKeyID = NULL;
4cdb67 ¤   Config.szRevokerKey = NULL;
af0baa ¤   Config.revokerKeyType = (PGPPublicKeyAlgorithm) 0;
832636 ¤   Config.bAllowKeyGen = TRUE;
b95854 ¤   Config.bAllowRSAKeyGen = FALSE;
ab5d59 ¤   Config.nMinKeySize = 768;
dc0b07 ¤   Config.bUpdateAllKeys = FALSE;
ce84e9 ¤   Config.bUpdateTrustedIntroducers = FALSE;
81777a ¤   Config.nDaysUpdateAllKeys = 1;
f4c36f ¤   Config.nDaysUpdateTrustedIntroducers = 1;
337e6f ¤   Config.bAllowConventionalEncryption = TRUE;
f34d4b ¤   Config.szComments = NULL;
6d5a21 ¤   Config.nCommentLength = 0;
6ae13e ¤   Config.defaultKeySet = NULL;
1d271d ¤   Config.szInstallDir = (char *) PGPNewData(Config.memoryMgr,
7edf6e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen("C:\\")+1,·
e6e023 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
0ebecb ¤   strcpy(Config.szInstallDir, "C:\\");
4a2a48 ¤   Config.bCopyClientPrefs = FALSE;
24e9b5 ¤   Config.bPreselectInstall = FALSE;
7c06c4 ¤   Config.szUserInstallDir = (char *) PGPNewData(Config.memoryMgr,
9bef0f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen(DEFAULT_USERINSTALLDIR)+1,·
9a6ddf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
acb9d2 ¤   strcpy(Config.szUserInstallDir, DEFAULT_USERINSTALLDIR);
ddf47b ¤   Config.bInstallPrograms = TRUE;
0bd7e9 ¤   Config.bInstallDisk = TRUE;
fe4b8a ¤   Config.bInstallEudora = TRUE;
ff3b80 ¤   Config.bInstallOutlook = TRUE;
a547a2 ¤   Config.bInstallOutExpress = TRUE;
1f7e4f ¤   Config.bInstallManual = TRUE;
44b56a ¤   Config.bUninstallOld = TRUE;
12d1ae ¤   Config.bSave = FALSE;
91af5a
a1c81b ¤   // Determine which bitmap will be displayed in the wizard
4baf5a
277f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
fc89fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
90e693 ¤   ReleaseDC (NULL, hDC);
5eaf5a
5001be ¤   if (iNumBits <= 1)
deeff7 ¤   ¤   iBitmap = IDB_ADMINWIZ1;
09f2dd ¤   else if (iNumBits <= 4)·
d7d64a ¤   ¤   iBitmap = IDB_ADMINWIZ4;
e765e9 ¤   else if (iNumBits <= 8)·
b773e9 ¤   ¤   iBitmap = IDB_ADMINWIZ8;
824264 ¤   else·
2eecf5 ¤   ¤   iBitmap = IDB_ADMINWIZ24;
ecaf5a
--b962 00002b081f040110252 Page 4 of CreateWiz.cpp
af280f ¤   Config.hBitmap = LoadResourceBitmap(g_hInstance, MAKEINTRESOURCE(iBitmap),
7b2948 ¤   ¤   ¤   ¤   ¤   ¤   &(Config.hPalette));
c0af5a
9e667e ¤   // Set the values common to all pages
e1af5a
c1ade0 ¤   for (nIndex=0; nIndex<NUM_WIZ_PAGES; nIndex++)
29c7a1 ¤   {
4c2778 ¤   ¤   pspWiz[nIndex].dwSize¤  ¤   = sizeof(PROPSHEETPAGE);
78af94 ¤   ¤   pspWiz[nIndex].dwFlags¤ ¤   = PSP_DEFAULT;
b0541b ¤   ¤   pspWiz[nIndex].hInstance¤   = g_hInstance;
ae3e30 ¤   ¤   pspWiz[nIndex].pszTemplate¤ = NULL;
606dd2 ¤   ¤   pspWiz[nIndex].hIcon¤   ¤   = NULL;
4145b7 ¤   ¤   pspWiz[nIndex].pszTitle¤¤   = NULL;
c5df91 ¤   ¤   pspWiz[nIndex].pfnDlgProc¤  = NULL;
80675d ¤   ¤   pspWiz[nIndex].lParam¤  ¤   = (LPARAM) &Config;
ce1e37 ¤   ¤   pspWiz[nIndex].pfnCallback¤ = NULL;
e0d422 ¤   ¤   pspWiz[nIndex].pcRefParent¤ = NULL;
8c9371 ¤   }
85af5a
46c119 ¤   // Set up the license number page
f5af5a
1c023a ¤   pspWiz[Wiz_License].pszTemplate¤= MAKEINTRESOURCE(IDD_LICENSE);
70b5c2 ¤   pspWiz[Wiz_License].pfnDlgProc¤ = (DLGPROC) LicenseDlgProc;
1767c5 ¤
45c8da ¤   // Set up the intro page
1caf5a
8c9dfa ¤   pspWiz[Wiz_Intro].pszTemplate¤  = MAKEINTRESOURCE(IDD_INTRO);
9f0cc6 ¤   pspWiz[Wiz_Intro].pfnDlgProc¤   = (DLGPROC) IntroDlgProc;
8667c5 ¤
25baef ¤   // Set up the additional decryption key intro page
a4af5a
fcc625 ¤   pspWiz[Wiz_ADKIntro].pszTemplate = MAKEINTRESOURCE(IDD_ADK);
c89080 ¤   pspWiz[Wiz_ADKIntro].pfnDlgProc¤= (DLGPROC) ADKIntroDlgProc;
b767c5 ¤
8b12df ¤   // Set up the incoming additional decryption key page
13af5a
94c3c9 ¤   pspWiz[Wiz_ADKIncoming].pszTemplate¤= MAKEINTRESOURCE(IDD_ADK_INCOMING);
edb986 ¤   pspWiz[Wiz_ADKIncoming].pfnDlgProc¤ = (DLGPROC) ADKIncomingDlgProc;
6567c5 ¤
48f2c8 ¤   // Set up the incoming additional decryption key selection page
f8af5a
6d67b4 ¤   pspWiz[Wiz_ADKInSelect].pszTemplate =MAKEINTRESOURCE(IDD_ADK_INSEL);
4e778b ¤   pspWiz[Wiz_ADKInSelect].pfnDlgProc ·=(DLGPROC) ADKInSelectDlgProc;
3467c5 ¤
b23ac4 ¤   // Set up the outgoing additional decryption key page
85af5a
fd59f8 ¤   pspWiz[Wiz_ADKOutgoing].pszTemplate =·
23cef8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_ADK_OUTGOING);
191930 ¤   pspWiz[Wiz_ADKOutgoing].pfnDlgProc ·= (DLGPROC) ADKOutgoingDlgProc;
3967c5 ¤
c0b529 ¤   // Set up the outgoing additional decryption key selection page
97af5a
16a0cf ¤   pspWiz[Wiz_ADKOutSelect].pszTemplate =·
7872cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_ADK_OUTSEL);
1f8547 ¤   pspWiz[Wiz_ADKOutSelect].pfnDlgProc = (DLGPROC) ADKOutSelectDlgProc;
d967c5 ¤
327f76 ¤   // Set up the additional decryption key enforcement page
23af5a
c237f8 ¤   pspWiz[Wiz_ADKEnforce].pszTemplate =·
953528 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_ADK_ENFORCE);
2de3bd ¤   pspWiz[Wiz_ADKEnforce].pfnDlgProc = (DLGPROC) ADKEnforceDlgProc;
be67c5 ¤
22b337 ¤   // Set up the PGPdisk additional decryption key page
2aaf5a
2845ef ¤   pspWiz[Wiz_ADKDisk].pszTemplate = MAKEINTRESOURCE(IDD_ADK_DISK);
78c4de ¤   pspWiz[Wiz_ADKDisk].pfnDlgProc ·= (DLGPROC) ADKDiskDlgProc;
7967c5 ¤
08baca ¤   // Set up the PGPdisk additional decryption key selection page
39af5a
991f38 ¤   pspWiz[Wiz_ADKDiskSelect].pszTemplate =·
1f9552 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_ADK_DISKSEL);
02fc4a ¤   pspWiz[Wiz_ADKDiskSelect].pfnDlgProc = (DLGPROC) ADKDiskSelectDlgProc;
--ed62 0008204d17040110252 Page 5 of CreateWiz.cpp
2a67c5 ¤
a88124 ¤   // Set up the pass phrase page
60af5a
f61b96 ¤   pspWiz[Wiz_PassPhrase].pszTemplate¤ = MAKEINTRESOURCE(IDD_PASSPHRASE);
744f06 ¤   pspWiz[Wiz_PassPhrase].pfnDlgProc¤  = (DLGPROC) PassPhraseDlgProc;
2367c5 ¤
52f0bd ¤   // Set up the corporate key page
a2af5a
465059 ¤   pspWiz[Wiz_CorpKey].pszTemplate = MAKEINTRESOURCE(IDD_CORPKEY);
8f7ee4 ¤   pspWiz[Wiz_CorpKey].pfnDlgProc¤ = (DLGPROC) CorpKeyDlgProc;
5d67c5 ¤
93193f ¤   // Set up the corporate key selection page
03af5a
f24d74 ¤   pspWiz[Wiz_CorpKeySelect].pszTemplate¤  = MAKEINTRESOURCE(IDD_CORPKEYSEL);
cc7519 ¤   pspWiz[Wiz_CorpKeySelect].pfnDlgProc¤   = (DLGPROC) CorpKeySelectDlgProc;
aa67c5 ¤
a4edf3 ¤   // Set up the revoker key page
2caf5a
07d34d ¤   pspWiz[Wiz_Revoker].pszTemplate = MAKEINTRESOURCE(IDD_REVOKER);
d4c49b ¤   pspWiz[Wiz_Revoker].pfnDlgProc¤ = (DLGPROC) RevokerDlgProc;
3e67c5 ¤
ad3bf9 ¤   // Set up the revoker key selection page
acaf5a
7fb621 ¤   pspWiz[Wiz_RevokerSelect].pszTemplate¤  = MAKEINTRESOURCE(IDD_REVOKERSEL);
6561e3 ¤   pspWiz[Wiz_RevokerSelect].pfnDlgProc¤   = (DLGPROC) RevokerSelectDlgProc;
8167c5 ¤
8458b0 ¤   // Set up the key generation page
c9af5a
f0de30 ¤   pspWiz[Wiz_KeyGen].pszTemplate¤ = MAKEINTRESOURCE(IDD_KEYGEN);
b13589 ¤   pspWiz[Wiz_KeyGen].pfnDlgProc¤  = (DLGPROC) KeyGenDlgProc;
d367c5 ¤
a16aaf ¤   // Set up the default key selection page
a9af5a
1a3789 ¤   pspWiz[Wiz_DefaultKeys].pszTemplate = MAKEINTRESOURCE(IDD_DEFKEYSEL);
8cbdf5 ¤   pspWiz[Wiz_DefaultKeys].pfnDlgProc¤ = (DLGPROC) DefaultKeysDlgProc;
e767c5 ¤
fe0ccd ¤   // Set up the server updates page
bbaf5a
180c19 ¤   pspWiz[Wiz_ServerUpdates].pszTemplate =·
b5c9b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_SERVERUPDATES);
51325f ¤   pspWiz[Wiz_ServerUpdates].pfnDlgProc ·= (DLGPROC) ServerUpdatesDlgProc;
7d67c5 ¤
3b4f84 ¤   // Set up the miscellaneous page
a9af5a
f1d223 ¤   pspWiz[Wiz_Misc].pszTemplate¤   = MAKEINTRESOURCE(IDD_MISC);
292bda ¤   pspWiz[Wiz_Misc].pfnDlgProc¤¤   = (DLGPROC) MiscDlgProc;
4f67c5 ¤
20764f ¤   // Set up the review page
daaf5a
dd3c5d ¤   pspWiz[Wiz_Review].pszTemplate¤ = MAKEINTRESOURCE(IDD_REVIEW);
c91b6e ¤   pspWiz[Wiz_Review].pfnDlgProc¤  = (DLGPROC) ReviewDlgProc;
3867c5 ¤
1a1815 ¤   // Set up the client prefs page
7eaf5a
b83b43 ¤   pspWiz[Wiz_ClientPrefs].pszTemplate¤= MAKEINTRESOURCE(IDD_CLIENTPREFS);
a50713 ¤   pspWiz[Wiz_ClientPrefs].pfnDlgProc¤ = (DLGPROC) ClientPrefsDlgProc;
7567c5 ¤
44a505 ¤   // Set up the install options page
bfaf5a
304b65 ¤   pspWiz[Wiz_InstallOptions].pszTemplate =
0e5ad8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_INSTALLOPTIONS);
5e5d48 ¤   pspWiz[Wiz_InstallOptions].pfnDlgProc ·= (DLGPROC) InstallOptionsDlgProc;
6367c5 ¤
7afdd0 ¤   // Set up the finishing page
c8af5a
32c8cc ¤   pspWiz[Wiz_Finish].pszTemplate¤ = MAKEINTRESOURCE(IDD_FINISH);
0ef949 ¤   pspWiz[Wiz_Finish].pfnDlgProc¤  = (DLGPROC) FinishDlgProc;
4767c5 ¤
f3fe81 ¤   // Create the header
e9af5a
2879d3 ¤   pshWiz.dwSize¤  ¤   = sizeof(PROPSHEETHEADER);
82abcc ¤   pshWiz.dwFlags¤ ¤   = PSH_WIZARD | PSH_PROPSHEETPAGE;
--4ab8 0001d4a9d8540110252 Page 6 of CreateWiz.cpp
e80667 ¤   pshWiz.hwndParent¤  = hwndMain;
fd34fc ¤   pshWiz.hInstance¤   = g_hInstance;
4bac7c ¤   pshWiz.hIcon¤   ¤   = NULL;
277482 ¤   pshWiz.pszCaption¤  = NULL;
5d7f64 ¤   pshWiz.nPages¤  ¤   = NUM_WIZ_PAGES;
3e8212 ¤   pshWiz.nStartPage¤  = Wiz_Start;
d9db1b ¤   pshWiz.ppsp¤¤   ¤   = pspWiz;
b3df99 ¤   pshWiz.pfnCallback¤ = NULL;
2caf5a
1b4a5a ¤   // Execute the Wizard - doesn't return until Cancel or Save
21af5a
10afce ¤   PropertySheet(&pshWiz);
8aaf5a
488b53 ¤   // Save settings
99af5a
f55270 ¤   if (Config.bSave)
5bc7a1 ¤   {
2dd65b ¤   ¤   PFLFileSpecRef ·adminPrefFile;
d415c8 ¤   ¤   PGPPrefRef¤ ¤   prefRef;
cad4d7 ¤   ¤   PGPKeyID¤   ¤   keyID;
741b6e ¤   ¤   PGPByte¤¤   ¤   exportedKeyID[kPGPMaxExportedKeyIDSize];
e8c937 ¤   ¤   PGPSize¤¤   ¤   keyIDSize;
b18358 ¤   ¤   char¤   ¤   ¤   szFile[MAX_PATH];
6015b6 ¤   ¤   char¤   ¤   ¤   szPrefFile[MAX_PATH];
dd5ab2 ¤   ¤   char¤   ¤   ¤   szOrigFile[MAX_PATH];
7287f9 ¤   ¤   char¤   ¤   ¤   szNewFile[MAX_PATH];
859323 ¤   ¤   char¤   ¤   ¤   szInstallDir[MAX_PATH];
851370 ¤   ¤   char¤   ¤   ¤   szDisk[255];
b2af5a
24cb80 ¤   ¤   // Add a directory to the install directory
ebaf5a
197fcd ¤   ¤   CreateDirectory(Config.szInstallDir, NULL);
734d8f ¤   ¤   LoadString(g_hInstance, IDS_INSTALLDIR, szPrefFile, MAX_PATH-1);
78af5a
cd4752 ¤   ¤   wsprintf(szInstallDir, szPrefFile,·
022a75 ¤   ¤   ¤   Config.szInstallDir, PGPVERSIONSTRING);
53af5a
facbe0 ¤   ¤   PGPFreeData(Config.szInstallDir);
5c1a73 ¤   ¤   Config.szInstallDir = (char *) PGPNewData(Config.memoryMgr,
fcb834 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen(szInstallDir)+1,·
126ddf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
7caf5a
4451f7 ¤   ¤   strcpy(Config.szInstallDir, szInstallDir);
2a7fcd ¤   ¤   CreateDirectory(Config.szInstallDir, NULL);
35af5a
ddc2dc ¤   ¤   LoadString(g_hInstance, IDS_INSTALLDISK, szDisk, 254);
b3e35a ¤   ¤   strcpy(szNewFile, Config.szInstallDir);
4e437d ¤   ¤   strcat(szNewFile, szDisk);
ef6752 ¤   ¤   CreateDirectory(szNewFile, NULL);
ebaf5a
2a08a8 ¤   ¤   if (Config.bCopyClientPrefs)
ed5b34 ¤   ¤   {
750812 ¤   ¤   ¤   // Copy default prefs to install directory
6487c7 ¤   ¤   ¤
18fbb2 ¤   ¤   ¤   LoadString(g_hInstance, IDS_CLIENTPREFFILE, szPrefFile,·
783dcc ¤   ¤   ¤   ¤   MAX_PATH-1);
b287c7 ¤   ¤   ¤
78ab70 ¤   ¤   ¤   PGPclGetPGPPath(szOrigFile, MAX_PATH-1);
1c87c7 ¤   ¤   ¤
fe89b4 ¤   ¤   ¤   strcat(szNewFile, "\\");
1bf96a ¤   ¤   ¤   strcat(szOrigFile, szPrefFile);
29cd6b ¤   ¤   ¤   strcat(szNewFile, szPrefFile);
fc87c7 ¤   ¤   ¤
98838b ¤   ¤   ¤   CopyFile(szOrigFile, szNewFile, FALSE);
4a0fe4 ¤   ¤   }
69af5a
455d82 ¤   ¤   // Save the admin prefs
bcaf5a
0ea968 ¤   ¤   LoadString(g_hInstance, IDS_ADMINPREFFILE, szPrefFile, MAX_PATH-1);
54af5a
b93c79 ¤   ¤   strcpy(szFile, Config.szInstallDir);
1dab9a ¤   ¤   strcat(szFile, szDisk);
--8da7 000c1607cd940110252 Page 7 of CreateWiz.cpp
d00a19 ¤   ¤   strcat(szFile, "\\");
d6f86b ¤   ¤   PGPclGetPGPPath(szOrigFile, MAX_PATH-1);
60efef ¤   ¤   strcat(szFile, szPrefFile);
1b710c ¤   ¤   strcat(szOrigFile, szPrefFile);
61af5a
0a700d ¤   ¤   err = PFLNewFileSpecFromFullPath(Config.memoryMgr, szFile,
4db079 ¤   ¤   ¤   ¤   &adminPrefFile);
6ab6ad ¤   ¤   if (IsPGPError(err))
425b34 ¤   ¤   {
aea729 ¤   ¤   ¤   PGPclErrorBox(hwndMain, err);
f5ed19 ¤   ¤   ¤   goto error;
ed0fe4 ¤   ¤   }
1eaf5a
33e703 ¤   ¤   err = PFLFileSpecCreate(adminPrefFile);
57b6ad ¤   ¤   if (IsPGPError(err))
055b34 ¤   ¤   {
0299a9 ¤   ¤   ¤   PFLFreeFileSpec(adminPrefFile);
a7a729 ¤   ¤   ¤   PGPclErrorBox(hwndMain, err);
feed19 ¤   ¤   ¤   goto error;
860fe4 ¤   ¤   }
c5af5a
0a454d ¤   ¤   err = PGPOpenPrefFile(adminPrefFile, NULL, 0, &prefRef);
76b6ad ¤   ¤   if (IsPGPError(err))
835b34 ¤   ¤   {
7b99a9 ¤   ¤   ¤   PFLFreeFileSpec(adminPrefFile);
08a729 ¤   ¤   ¤   PGPclErrorBox(hwndMain, err);
cfed19 ¤   ¤   ¤   goto error;
ea0fe4 ¤   ¤   }
b5af5a
b0dfba ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefUseOutgoingADK,·
0e3a8b ¤   ¤   ¤   Config.bUseOutgoingADK);
0175a1 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefUseDHADK, Config.bUseIncomingADK);
0fde2e ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefUsePGPdiskADK,·
1075bb ¤   ¤   ¤   Config.bUseDiskADK);
331ae7 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefEnforceIncomingADK,·
eda296 ¤   ¤   ¤   Config.bEnforceIncomingADK);
b91e61 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefEnforceOutgoingADK,·
f7a610 ¤   ¤   ¤   Config.bEnforceOutgoingADK);
177d6c ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefEnforceRemoteADKClass,·
b3c226 ¤   ¤   ¤   Config.bEnforceRemoteADK);
a7461d ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefEnforceMinChars,
c41548 ¤   ¤   ¤   Config.bEnforceMinChars);
487e51 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefEnforceMinQuality,
0fd85e ¤   ¤   ¤   Config.bEnforceMinQuality);
da15d1 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefWarnNotCertByCorp,
065c3d ¤   ¤   ¤   Config.bWarnNotCertByCorp);
9258a4 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefAutoSignTrustCorp,
a3785a ¤   ¤   ¤   Config.bAutoSignTrustCorp);
f0117c ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefMetaIntroducerCorp,
5424c7 ¤   ¤   ¤   Config.bMetaIntroducerCorp);
77e9cf ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefAllowKeyGen,¤Config.bAllowKeyGen);
886a97 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefAllowRSAKeyGen,
902021 ¤   ¤   ¤   Config.bAllowRSAKeyGen);
51a4b7 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefAllowConventionalEncryption,
15a02f ¤   ¤   ¤   Config.bAllowConventionalEncryption);
46ce3f ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefUpdateAllKeys,
a2ef39 ¤   ¤   ¤   Config.bUpdateAllKeys);
6b1842 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefUpdateTrustedIntroducers,
a21f85 ¤   ¤   ¤   Config.bUpdateTrustedIntroducers);
e8d284 ¤   ¤   PGPSetPrefBoolean(prefRef, kPGPPrefAutoAddRevoker,
ff0283 ¤   ¤   ¤   Config.bAutoAddRevoker);
f1af5a
2980d8 ¤   ¤   PGPSetPrefNumber(prefRef, kPGPAdminPrefVersion, PGP_ADMINPREFVERSION);
23071f ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefMinChars, Config.nMinChars);
6e95ca ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefMinQuality, Config.nMinQuality);
5942bc ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefMinimumKeySize, Config.nMinKeySize);
6661ab ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefCorpKeyPublicKeyAlgorithm,
700701 ¤   ¤   ¤   Config.corpKeyType);
319f76 ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefOutADKPublicKeyAlgorithm,
57b207 ¤   ¤   ¤   Config.outgoingADKKeyType);
a64705 ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefPGPdiskADKPublicKeyAlgorithm,
c1b35e ¤   ¤   ¤   Config.diskADKKeyType);
--0822 000c63dc99f40110252 Page 8 of CreateWiz.cpp
becc0b ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefDaysUpdateAllKeys,
963622 ¤   ¤   ¤   Config.nDaysUpdateAllKeys);
a88d96 ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefDaysUpdateTrustedIntroducers,
5a4808 ¤   ¤   ¤   Config.nDaysUpdateTrustedIntroducers);
6b62b3 ¤   ¤   PGPSetPrefNumber(prefRef, kPGPPrefRevokerPublicKeyAlgorithm,
ca7792 ¤   ¤   ¤   Config.revokerKeyType);
a4af5a
b58be0 ¤   ¤   if (Config.szLicenseNum != NULL)
f43855 ¤   ¤   ¤   PGPSetPrefString(prefRef, kPGPPrefAdminCompanyName,·
c73a95 ¤   ¤   ¤   ¤   Config.szLicenseNum);
990e1d ¤   ¤   else
c44e0f ¤   ¤   ¤   PGPSetPrefString(prefRef, kPGPPrefAdminCompanyName, "");
a7af5a
6b1965 ¤   ¤   if (Config.szComments != NULL)
c1cfe1 ¤   ¤   ¤   PGPSetPrefString(prefRef, kPGPPrefComments, Config.szComments);
810e1d ¤   ¤   else
26dd8e ¤   ¤   ¤   PGPSetPrefString(prefRef, kPGPPrefComments,¤"");
2faf5a
feec57 ¤   ¤   if ((Config.szOutgoingADKID != NULL) && (Config.bUseOutgoingADK))
3d5b34 ¤   ¤   {
c6111c ¤   ¤   ¤   PGPGetKeyIDFromString(Config.szOutgoingADKID, &keyID);
100209 ¤   ¤   ¤   PGPExportKeyID(&keyID, exportedKeyID, &keyIDSize);
6e4954 ¤   ¤   ¤   PGPSetPrefData(prefRef, kPGPPrefOutgoingADKID, keyIDSize,·
3dffaa ¤   ¤   ¤   ¤   exportedKeyID);
010fe4 ¤   ¤   }
42af5a
022e2b ¤   ¤   if ((Config.szIncomingADKID != NULL) && (Config.bUseIncomingADK))
ce5b34 ¤   ¤   {
5b64dd ¤   ¤   ¤   PGPGetKeyIDFromString(Config.szIncomingADKID, &keyID);
b20209 ¤   ¤   ¤   PGPExportKeyID(&keyID, exportedKeyID, &keyIDSize);
b8acd5 ¤   ¤   ¤   PGPSetPrefData(prefRef, kPGPPrefDHADKID, keyIDSize,·
73ffaa ¤   ¤   ¤   ¤   exportedKeyID);
0b0fe4 ¤   ¤   }
9f1b52 ¤   ¤
903fa0 ¤   ¤   if ((Config.szDiskADKID != NULL) && (Config.bUseDiskADK))
1f5b34 ¤   ¤   {
c85fa5 ¤   ¤   ¤   PGPGetKeyIDFromString(Config.szDiskADKID, &keyID);
300209 ¤   ¤   ¤   PGPExportKeyID(&keyID, exportedKeyID, &keyIDSize);
9b6417 ¤   ¤   ¤   PGPSetPrefData(prefRef, kPGPPrefPGPdiskADKKeyID, keyIDSize,·
18ffaa ¤   ¤   ¤   ¤   exportedKeyID);
cc0fe4 ¤   ¤   }
0e1b52 ¤   ¤
ee9ea2 ¤   ¤   if ((Config.szCorpKeyID != NULL) && (Config.bAutoSignTrustCorp))
895b34 ¤   ¤   {
b3af75 ¤   ¤   ¤   PGPGetKeyIDFromString(Config.szCorpKeyID, &keyID);
bb0209 ¤   ¤   ¤   PGPExportKeyID(&keyID, exportedKeyID, &keyIDSize);
cffafa ¤   ¤   ¤   PGPSetPrefData(prefRef, kPGPPrefCorpKeyID, keyIDSize,·
0fffaa ¤   ¤   ¤   ¤   exportedKeyID);
490fe4 ¤   ¤   }
aaaf5a
d647a2 ¤   ¤   if ((Config.szRevokerKeyID != NULL) && (Config.bAutoAddRevoker))
c45b34 ¤   ¤   {
82486c ¤   ¤   ¤   PGPGetKeyIDFromString(Config.szRevokerKeyID, &keyID);
a50209 ¤   ¤   ¤   PGPExportKeyID(&keyID, exportedKeyID, &keyIDSize);
99c934 ¤   ¤   ¤   PGPSetPrefData(prefRef, kPGPPrefRevokerKeyID, keyIDSize,·
9effaa ¤   ¤   ¤   ¤   exportedKeyID);
250fe4 ¤   ¤   }
f7af5a
33bb3d ¤   ¤   // Save the default keys if any were specified
dfaf5a
86ac44 ¤   ¤   if (Config.defaultKeySet != NULL)
e65b34 ¤   ¤   {
57902c ¤   ¤   ¤   char *¤ ¤   ¤   ¤   szKeyBlock;
85dced ¤   ¤   ¤   PGPSize¤¤   ¤   ¤   nKeyBlockSize;
3292f9 ¤   ¤   ¤   PGPOptionListRef¤   comments;
2ec03f ¤   ¤   ¤   char¤   ¤   ¤   ¤   szComment[255];
40af5a
05c3a1 ¤   ¤   ¤   if (GetCommentString(Config.memoryMgr, szComment,·
06dc90 ¤   ¤   ¤   ¤   ¤   sizeof(szComment)))
cbe4b9 ¤   ¤   ¤   ¤   PGPBuildOptionList(Config.pgpContext, &comments,
9a6bde ¤   ¤   ¤   ¤   ¤   PGPOCommentString(Config.pgpContext, szComment),
c6dc1a ¤   ¤   ¤   ¤   ¤   PGPOLastOption(Config.pgpContext));
--9587 000d62c3d6f40110252 Page 9 of CreateWiz.cpp
b1bb8c ¤   ¤   ¤   else
e7360f ¤   ¤   ¤   ¤   PGPBuildOptionList(Config.pgpContext,·
eba7f1 ¤   ¤   ¤   ¤   ¤   &comments,·
18dc1a ¤   ¤   ¤   ¤   ¤   PGPOLastOption(Config.pgpContext));
3eaf5a
f11141 ¤   ¤   ¤   err = PGPExportKeySet(Config.defaultKeySet,
03fc29 ¤   ¤   ¤   ¤   ¤   PGPOAllocatedOutputBuffer(Config.pgpContext,
e25e86 ¤   ¤   ¤   ¤   ¤   ¤   (void **) &szKeyBlock, INT_MAX, &nKeyBlockSize),
3fb064 ¤   ¤   ¤   ¤   ¤   PGPOVersionString(Config.pgpContext,·
3d97ed ¤   ¤   ¤   ¤   ¤   ¤   pgpVersionHeaderString),
8981ae ¤   ¤   ¤   ¤   ¤   comments,
9edc1a ¤   ¤   ¤   ¤   ¤   PGPOLastOption(Config.pgpContext));
aeaf5a
d467bf ¤   ¤   ¤   PGPFreeOptionList(comments);
41af5a
480dfb ¤   ¤   ¤   if (IsPGPError(err))
08f776 ¤   ¤   ¤   {
389eec ¤   ¤   ¤   ¤   PGPclErrorBox(hwndMain, err);
8e1b7c ¤   ¤   ¤   ¤   goto error;
87a3a6 ¤   ¤   ¤   }
3baf5a
f156a8 ¤   ¤   ¤   PGPSetPrefString(prefRef, kPGPPrefDefaultKeys, szKeyBlock);
ad1eea ¤   ¤   ¤   PGPFreeData(szKeyBlock);
d10fe4 ¤   ¤   }
fc0e1d ¤   ¤   else
4cddba ¤   ¤   ¤   PGPSetPrefString(prefRef, kPGPPrefDefaultKeys, "");
7aaf5a
8f1d8b ¤   ¤   // Save and close the admin prefs file
36af5a
65cef9 ¤   ¤   PGPSavePrefFile(prefRef);
ecfbc0 ¤   ¤   PGPClosePrefFile(prefRef);
ea11cf ¤   ¤   PFLFreeFileSpec(adminPrefFile);
988da7 ¤   ¤   CopyFile(szFile, szOrigFile, FALSE);
b7af5a
495f13 ¤   ¤   // Now copy the Non-Admin installer
85af5a
1ea388 ¤   ¤   if (!CopyInstaller(hwndMain, szClientInstaller, Config.szInstallDir))
7c5b34 ¤   ¤   {
c09de4 ¤   ¤   ¤   char szLicNum[3];
8cacaf ¤   ¤   ¤   char szSetupIni[MAX_PATH];
18af5a
17cf03 ¤   ¤   ¤   strcpy(szSetupIni, Config.szInstallDir);
bd6fd8 ¤   ¤   ¤   strcat(szSetupIni, szDisk);
8b2cd6 ¤   ¤   ¤   strcat(szSetupIni, "\\setup.ini");
69af5a
15ce61 ¤   ¤   ¤   // Modify the setup.ini file to let the installer know if it
508743 ¤   ¤   ¤   // needs to ask for the license number or not
53af5a
2f8d58 ¤   ¤   ¤   if (Config.szLicenseNum != NULL)
6971ab ¤   ¤   ¤   ¤   strcpy(szLicNum, "1");
fcbb8c ¤   ¤   ¤   else
f57aef ¤   ¤   ¤   ¤   strcpy(szLicNum, "0");
26af5a
1f64bd ¤   ¤   ¤   WritePrivateProfileString("Startup", "CompanyName",·
3eb97c ¤   ¤   ¤   ¤   Config.szLicenseNum, szSetupIni);
acaf5a
f8d59f ¤   ¤   ¤   // Write the installation options if applicable
50af5a
579795 ¤   ¤   ¤   if (Config.bPreselectInstall)
50f776 ¤   ¤   ¤   {
d7cadb ¤   ¤   ¤   ¤   char szPrograms[3];
c293bb ¤   ¤   ¤   ¤   char szDisk[3];
ff6071 ¤   ¤   ¤   ¤   char szEudora[3];
ce9c88 ¤   ¤   ¤   ¤   char szExchangeOutlook[3];
6e8280 ¤   ¤   ¤   ¤   char szOutlookExpress[3];
0a0ff6 ¤   ¤   ¤   ¤   char szManual[3];
c91c25 ¤   ¤   ¤   ¤   char szUninstallOld[3];
22af5a
76835b ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "EasyInstall", "1",
5e30eb ¤   ¤   ¤   ¤   ¤   szSetupIni);
30af5a
d693fb ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "InstallDir",
--89e1 000c37245b840110252 Page 10 of CreateWiz.cpp
6a60de ¤   ¤   ¤   ¤   ¤   Config.szUserInstallDir, szSetupIni);
49af5a
8fdde3 ¤   ¤   ¤   ¤   wsprintf(szPrograms, "%d", Config.bInstallPrograms);
2f461d ¤   ¤   ¤   ¤   wsprintf(szDisk, "%d", Config.bInstallDisk);
bcd99f ¤   ¤   ¤   ¤   wsprintf(szEudora, "%d", Config.bInstallEudora);
c609ca ¤   ¤   ¤   ¤   wsprintf(szExchangeOutlook, "%d", Config.bInstallOutlook);
97e302 ¤   ¤   ¤   ¤   wsprintf(szOutlookExpress, "%d", Config.bInstallOutExpress);
3b16b7 ¤   ¤   ¤   ¤   wsprintf(szManual, "%d", Config.bInstallManual);
f8dd85 ¤   ¤   ¤   ¤   wsprintf(szUninstallOld, "%d", Config.bUninstallOld);
e4af5a
028dfc ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "ProgramFiles",
0495d4 ¤   ¤   ¤   ¤   ¤   szPrograms, szSetupIni);
e4e9b5 ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "PGPdisk",
bd1805 ¤   ¤   ¤   ¤   ¤   szDisk, szSetupIni);
13954b ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "EudoraPlugin",
83a792 ¤   ¤   ¤   ¤   ¤   szEudora, szSetupIni);
f04e65 ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "ExchangeOutlookPlugin",
db133e ¤   ¤   ¤   ¤   ¤   szExchangeOutlook, szSetupIni);
ec255f ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "OutlookExpressPlugin",
9432c9 ¤   ¤   ¤   ¤   ¤   szOutlookExpress, szSetupIni);
f7cf48 ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "UserManual",
6346e3 ¤   ¤   ¤   ¤   ¤   szManual, szSetupIni);
3dc21b ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "UninstallOld",
2400be ¤   ¤   ¤   ¤   ¤   szUninstallOld, szSetupIni);
c2a3a6 ¤   ¤   ¤   }
40bb8c ¤   ¤   ¤   else
7d9fe0 ¤   ¤   ¤   ¤   WritePrivateProfileString("Startup", "EasyInstall", "0",
b030eb ¤   ¤   ¤   ¤   ¤   szSetupIni);
1daf5a
794475 ¤   ¤   ¤   // We're done!
e387c7 ¤   ¤   ¤
4e9b66 ¤   ¤   ¤   LoadString(g_hInstance, IDS_DONE, szMsg, 254);
28bccf ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
2c6359 ¤   ¤   ¤   MessageBox(hwndMain, szMsg, szTitle, MB_ICONINFORMATION);
320fe4 ¤   ¤   }
330e1d ¤   ¤   else
9a5b34 ¤   ¤   {
6c8ad1 ¤   ¤   ¤   // Copying failed
9f87c7 ¤   ¤   ¤
481185 ¤   ¤   ¤   LoadString(g_hInstance, IDS_FAILED, szMsg, 254);
98bccf ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
ebe016 ¤   ¤   ¤   MessageBox(hwndMain, szMsg, szTitle, MB_ICONEXCLAMATION);
9f0fe4 ¤   ¤   }
b29371 ¤   }
700e24 ¤   else
c8c7a1 ¤   {
cd73e1 ¤   ¤   char szPrefFile[MAX_PATH];
5a3ce5 ¤   ¤   char szOrigFile[MAX_PATH];
56af5a
1f2ba8 ¤   ¤   // Delete user's prefs file that was going to be installed
d9af5a
702981 ¤   ¤   LoadString(g_hInstance, IDS_NEWPREFFILE,·
618c64 ¤   ¤   ¤   ¤   szPrefFile, MAX_PATH-1);
92f86b ¤   ¤   PGPclGetPGPPath(szOrigFile, MAX_PATH-1);
d0710c ¤   ¤   strcat(szOrigFile, szPrefFile);
02eb33 ¤   ¤   DeleteFile(szOrigFile);
039371 ¤   }
34af5a
7a60ff error:
992c6a ¤   // Free allocated memory and objects
7aaf5a
4834cb ¤   if (Config.szLicenseNum)
56c7a1 ¤   {
f873ac ¤   ¤   PGPFreeData(Config.szLicenseNum);
3d94ce ¤   ¤   Config.szLicenseNum = NULL;
779371 ¤   }
faaf5a
49b86c ¤   if (Config.szComments)
2dc7a1 ¤   {
5ae12c ¤   ¤   PGPFreeData(Config.szComments);
317a43 ¤   ¤   Config.szComments = NULL;
c39371 ¤   }
--63ab 0001b6b61aa40110252 Page 11 of CreateWiz.cpp
e0af5a
d10637 ¤   if (Config.szOutgoingADKID)
10c7a1 ¤   {
b493d3 ¤   ¤   pgpFree(Config.szOutgoingADKID);
57adb1 ¤   ¤   Config.szOutgoingADKID = NULL;
bc9371 ¤   }
02af5a
9e9a71 ¤   if (Config.szOutgoingADK)
61c7a1 ¤   {
338692 ¤   ¤   pgpFree(Config.szOutgoingADK);
b58ac8 ¤   ¤   Config.szOutgoingADK = NULL;
ab9371 ¤   }
4faf5a
d1e70d ¤   if (Config.szIncomingADKID)
23c7a1 ¤   {
800deb ¤   ¤   pgpFree(Config.szIncomingADKID);
d21494 ¤   ¤   Config.szIncomingADKID = NULL;
459371 ¤   }
ccaf5a
9e3c35 ¤   if (Config.szIncomingADK)
67c7a1 ¤   {
c28214 ¤   ¤   pgpFree(Config.szIncomingADK);
c8ba80 ¤   ¤   Config.szIncomingADK = NULL;
149371 ¤   }
22af5a
720acf ¤   if (Config.szDiskADKID)
67c7a1 ¤   {
bf66f0 ¤   ¤   pgpFree(Config.szDiskADKID);
1b9234 ¤   ¤   Config.szDiskADKID = NULL;
959371 ¤   }
12af5a
b6bf2d ¤   if (Config.szDiskADK)
a5c7a1 ¤   {
3597bb ¤   ¤   pgpFree(Config.szDiskADK);
93fbed ¤   ¤   Config.szDiskADK = NULL;
739371 ¤   }
9eaf5a
455957 ¤   if (Config.szCorpKeyID)
f2c7a1 ¤   {
677e62 ¤   ¤   pgpFree(Config.szCorpKeyID);
fd3310 ¤   ¤   Config.szCorpKeyID = NULL;
7e9371 ¤   }
05af5a
d65768 ¤   if (Config.szCorpKey)
fdc7a1 ¤   {
0d82fa ¤   ¤   pgpFree(Config.szCorpKey);
c96f03 ¤   ¤   Config.szCorpKey = NULL;
909371 ¤   }
16af5a
1a282e ¤   if (Config.szRevokerKeyID)
63c7a1 ¤   {
6d8ca4 ¤   ¤   pgpFree(Config.szRevokerKeyID);
ee2df9 ¤   ¤   Config.szRevokerKeyID = NULL;
ff9371 ¤   }
b5af5a
d94311 ¤   if (Config.szRevokerKey)
56c7a1 ¤   {
6b31b8 ¤   ¤   pgpFree(Config.szRevokerKey);
8e509b ¤   ¤   Config.szRevokerKey = NULL;
409371 ¤   }
0daf5a
d790aa ¤   if (Config.defaultKeySet != NULL)
45c7a1 ¤   {
76df69 ¤   ¤   PGPFreeKeySet(Config.defaultKeySet);
fbdc56 ¤   ¤   Config.defaultKeySet = NULL;
6c9371 ¤   }
3eaf5a
319ba6 ¤   if (Config.szInstallDir)
0cc7a1 ¤   {
dbcbe0 ¤   ¤   PGPFreeData(Config.szInstallDir);
45a34f ¤   ¤   Config.szInstallDir = NULL;
1b9371 ¤   }
--92ec 000c045091a40110252 Page 12 of CreateWiz.cpp
e0af5a
149d54 ¤   if (Config.szUserInstallDir)
01c7a1 ¤   {
c0f37f ¤   ¤   PGPFreeData(Config.szUserInstallDir);
1d1778 ¤   ¤   Config.szUserInstallDir = NULL;
c49371 ¤   }
59af5a
f3d6df ¤   PGPclCloseLibrary();
dbfd50 ¤   PGPFreeContext(Config.pgpContext);
421fac ¤   DeleteObject(Config.hBitmap);
9eaf5a
3f830f ¤   return;
e9efe6 }
1daf5a
32af5a
bfaded //-------------------------------------------------------------------|
4d8349 // Load DIB bitmap and associated palette
f9af5a
15597e static HPALETTE·
a0cef8 CreateDIBPalette (LPBITMAPINFO lpbmi,·
bc70ea ¤   ¤   ¤   ¤   ··LPINT lpiNumColors)·
dcbb36 {
b5e3ed ¤   LPBITMAPINFOHEADER lpbi;
080377 ¤   LPLOGPALETTE lpPal;
17dcb6 ¤   HANDLE hLogPal;
d6abc2 ¤   HPALETTE hPal = NULL;
39cdd6 ¤   INT i;
fbd83c ·
f77407 ¤   lpbi = (LPBITMAPINFOHEADER)lpbmi;
6eff30 ¤   if (lpbi->biBitCount <= 8) {
825406 ¤   ¤   *lpiNumColors = (1 << lpbi->biBitCount);
a19371 ¤   }
a30e24 ¤   else
f421cc ¤   ¤   *lpiNumColors = 0; ·// No palette needed for 24 BPP DIB
7dd83c ·
4cf623 ¤   if (*lpiNumColors) {
d80012 ¤   ¤   hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
ed440c ·····························sizeof (PALETTEENTRY) * (*lpiNumColors));
8bd92a ¤   ¤   lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
905442 ¤   ¤   lpPal->palVersion = 0x300;
f04b35 ¤   ¤   lpPal->palNumEntries = *lpiNumColors;
dcd83c ·
eaa249 ¤   ¤   for (i = 0; ·i < *lpiNumColors; ·i++) {
2ad118 ¤   ¤   ¤   lpPal->palPalEntry[i].peRed ··= lpbmi->bmiColors[i].rgbRed;
8fdc94 ¤   ¤   ¤   lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
e21adf ¤   ¤   ¤   lpPal->palPalEntry[i].peBlue ·= lpbmi->bmiColors[i].rgbBlue;
87089b ¤   ¤   ¤   lpPal->palPalEntry[i].peFlags = 0;
6f0fe4 ¤   ¤   }
1f898e ¤   ¤   hPal = CreatePalette (lpPal);
8293f7 ¤   ¤   GlobalUnlock (hLogPal);
eab50d ¤   ¤   GlobalFree (hLogPal);
2cb144 ···}
3bef80 ···return hPal;
40efe6 }
d4af5a
11af5a
93fb93 static HBITMAP·
fad9f1 LoadResourceBitmap (HINSTANCE hInstance,·
73d7f9 ¤   ¤   ¤   ¤   ¤   LPSTR lpString,
9e076b ¤   ¤   ¤   ¤   ¤   HPALETTE FAR* lphPalette)·
02bb36 {
dfef32 ¤   HRSRC ·hRsrc;
069627 ¤   HGLOBAL hGlobal;
50cfb4 ¤   HBITMAP hBitmapFinal = NULL;
c0e3ed ¤   LPBITMAPINFOHEADER lpbi;
ec0755 ¤   HDC hdc;
4e5789 ····INT iNumColors;
2bd83c ·
6be2a3 ¤   if (hRsrc = FindResource (hInstance, lpString, RT_BITMAP)) {
1daa39 ¤   ¤   hGlobal = LoadResource (hInstance, hRsrc);
6a26b6 ¤   ¤   lpbi = (LPBITMAPINFOHEADER)LockResource (hGlobal);
c0d83c ·
--3e0e 001347b9f2b40110252 Page 13 of CreateWiz.cpp
41002d ¤   ¤   hdc = GetDC(NULL);
2f2e56 ¤   ¤   *lphPalette = ·CreateDIBPalette ((LPBITMAPINFO)lpbi, &iNumColors);
dfc904 ¤   ¤   if (*lphPalette) {
095e33 ¤   ¤   ¤   SelectPalette (hdc,*lphPalette,FALSE);
38703c ¤   ¤   ¤   RealizePalette (hdc);
330fe4 ¤   ¤   }
bfd83c ·
5b259d ¤   ¤   hBitmapFinal = CreateDIBitmap (hdc,
1414f2 ···················(LPBITMAPINFOHEADER)lpbi,
d0e478 ···················(LONG)CBM_INIT,
cad8e7 ···················(LPSTR)lpbi + lpbi->biSize + iNumColors * sizeof(RGBQUAD),
d8e564 ···················(LPBITMAPINFO)lpbi,
8ca1a1 ···················DIB_RGB_COLORS );
45d83c ·
1a6078 ¤   ¤   ReleaseDC (NULL,hdc);
ad66f7 ¤   ¤   UnlockResource (hGlobal);
7f1d90 ¤   ¤   FreeResource (hGlobal);
e59371 ¤   }
81aa7e ¤   return (hBitmapFinal);
bcefe6 }
d2af5a
b87e4d /*__Editor_settings____
7aaf5a
f54126 ¤   Local Variables:
c47b17 ¤   tab-width: 4
ac0e6c ¤   End:
725f8c ¤   vi: ts=4 sw=4
d39e9b ¤   vim: si
34d062 _____________________*/
--e8b2 001355b09cf40110253 Page 1 of CreateWiz.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ea2d3a ¤   $Id: CreateWiz.h,v 1.2.16.1 1998/11/12 03:13:05 heller Exp $
8af7f7 ____________________________________________________________________________*/
fe9759 #ifndef Included_CreateWiz_h¤   /* [ */
df33a3 #define Included_CreateWiz_h
c3af5a
492570 void CreateWiz(HWND hwndMain);
c8af5a
1c5740 #endif /* ] Included_CreateWiz_h */
76af5a
67af5a
517e4d /*__Editor_settings____
e7af5a
9d4126 ¤   Local Variables:
837b17 ¤   tab-width: 4
d10e6c ¤   End:
f55f8c ¤   vi: ts=4 sw=4
a19e9b ¤   vim: si
35d062 _____________________*/
--5603 0001d1ccd3c40110254 Page 1 of DefaultKeys.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e44609 ¤   $Id: DefaultKeys.cpp,v 1.13.8.1 1998/11/12 03:13:06 heller Exp $
fbf7f7 ____________________________________________________________________________*/
0baf5a
b35655 #include <windows.h>
e7fb83 #include "PGPadmin.h"
7390fb #include <commctrl.h>
5a8031 #include "resource.h"
aa3bb4 #include "Utils.h"
c70d08 #include "pgpMem.h"
6caf5a
91af5a
2238a9 BOOL CALLBACK DefaultKeysDlgProc(HWND hwndDlg,·
290d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
4e8347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
6bb0d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
a0bb36 {
040f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
fe8ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
4a429d ¤   HWND¤   ¤   ¤   hList;
11af5a
936357 ¤   g_hCurrentDlgWnd = hwndDlg;
6caf5a
889450 ¤   if (uMsg != WM_INITDIALOG)
98e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
8caf5a
b85ebd ¤   hList = GetDlgItem(hwndDlg, IDC_DEFKEY_ID);
9eaf5a
b4c08d ¤   switch(uMsg)
e1c7a1 ¤   {
6f2940 ¤   case WM_INITDIALOG:
315b34 ¤   ¤   {
12afc0 ¤   ¤   ¤   RECT rc;
19313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
ceaf5a
a7015a ¤   ¤   ¤   // center dialog on screen
abd4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
5a3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
a90971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
7f004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
6cf9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
40af5a
b73970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
9bad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
e3af5a
38382e ¤   ¤   ¤   ShowKeyring(hwndDlg, IDC_DEFKEY_ID, pConfig->pgpContext,·
8b543d ¤   ¤   ¤   ¤   NULL, TRUE, TRUE, FALSE, FALSE);
ab021f ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
e8cdcb ¤   ¤   ¤   break;
200fe4 ¤   ¤   }
91af5a
d36b08 ¤   case WM_DESTROY:
a53928 ¤   ¤   FreeKeyring(hwndDlg, IDC_DEFKEY_ID);
c52f68 ¤   ¤   break;
62af5a
c193f9 ¤   case WM_PAINT:
f0c334 ¤   ¤   if (pConfig->hPalette)
145b34 ¤   ¤   {
d9f431 ¤   ¤   ¤   PAINTSTRUCT ps;
7a60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
e94fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
699ffe ¤   ¤   ¤   RealizePalette (hDC);
1f438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
f10fe0 ¤   ¤   ¤   bReturnCode = TRUE;
040fe4 ¤   ¤   }
462f68 ¤   ¤   break;
1d1b52 ¤   ¤
--6606 0016d788cf140110254 Page 2 of DefaultKeys.cpp
dfc93c ¤   case WM_NOTIFY:
995b34 ¤   ¤   {
67a08b ¤   ¤   ¤   LPNMHDR pnmh;
cfaf5a
e82b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
edb7b0 ¤   ¤   ¤   switch(pnmh->code)
fff776 ¤   ¤   ¤   {
c666bc ¤   ¤   ¤   case PSN_SETACTIVE:
fa72c3 ¤   ¤   ¤   ¤   {
da7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
03bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
eac365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
b4af5a
7b9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
eb670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
abaf5a
7c3fb4 ¤   ¤   ¤   ¤   ¤   SelectKeys(hwndDlg, IDC_DEFKEY_ID, pConfig);
d54149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
5414c3 ¤   ¤   ¤   ¤   ¤   break;
e22613 ¤   ¤   ¤   ¤   }
9eaf5a
b9d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
1372c3 ¤   ¤   ¤   ¤   {
eb66b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
cbaf5a
80fe4c ¤   ¤   ¤   ¤   ¤   AddSelectedKeys(hwndDlg, IDC_DEFKEY_ID,·
f6fb42 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->pgpContext, &(pConfig->defaultKeySet));
a3af5a
ad4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ed14c3 ¤   ¤   ¤   ¤   ¤   break;
a82613 ¤   ¤   ¤   ¤   }
5aaf5a
9a6122 ¤   ¤   ¤   case PSN_HELP:
1972c3 ¤   ¤   ¤   ¤   {
7df1f2 ¤   ¤   ¤   ¤   ¤   // Display help
e414c3 ¤   ¤   ¤   ¤   ¤   break;
282613 ¤   ¤   ¤   ¤   }
f4af5a
f78f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
1e72c3 ¤   ¤   ¤   ¤   {
a56b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
f5014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
9714c3 ¤   ¤   ¤   ¤   ¤   break;
a12613 ¤   ¤   ¤   ¤   }
3ba3a6 ¤   ¤   ¤   }
2887c7 ¤   ¤   ¤
9dcdcb ¤   ¤   ¤   break;
120fe4 ¤   ¤   }
a5af5a
209371 ¤   }
aaaf5a
f648b1 ¤   return(bReturnCode);
b3efe6 }
04af5a
917e4d /*__Editor_settings____
05af5a
dc4126 ¤   Local Variables:
777b17 ¤   tab-width: 4
eb0e6c ¤   End:
e45f8c ¤   vi: ts=4 sw=4
db9e9b ¤   vim: si
6dd062 _____________________*/
--8460 000a9e2280040110255 Page 1 of FindInstaller.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
839a53 ¤   $Id: FindInstaller.cpp,v 1.2.8.1 1998/11/12 03:13:06 heller Exp $
dbf7f7 ____________________________________________________________________________*/
3eaf5a
b15655 #include <windows.h>
aafb83 #include "PGPadmin.h"
49f3cf #include <shlobj.h>
988031 #include "resource.h"
11af5a
0b6284 static char *szClientInstaller = NULL;
2daf5a
7efacf BOOL CALLBACK FindInstallerDlgProc(HWND hwndDlg,·
d1218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
0a2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
d275ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
24bb36 {
0a8d02 ¤   BOOL bReturnCode = FALSE;
8caf5a
26c08d ¤   switch(uMsg)
6ec7a1 ¤   {
aa2940 ¤   case WM_INITDIALOG:
c75b34 ¤   ¤   {
3dafc0 ¤   ¤   ¤   RECT rc;
1caf5a
5a015a ¤   ¤   ¤   // center dialog on screen
b4d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
3d3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
ab0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
31004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
dff9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
0baf5a
714912 ¤   ¤   ¤   szClientInstaller = (char *) lParam;
ba06d4 ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_CLIENTINSTALL),
54b938 ¤   ¤   ¤   ¤   szClientInstaller);
6caf5a
24cdcb ¤   ¤   ¤   break;
e10fe4 ¤   ¤   }
d8af5a
1d3fcf ¤   case WM_COMMAND:
7772a4 ¤   ¤   switch (LOWORD(wParam))
a65b34 ¤   ¤   {
713860 ¤   ¤   case IDOK:
a17664 ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_CLIENTINSTALL),
cb6c1a ¤   ¤   ¤   ¤   szClientInstaller, MAX_PATH-1);
66796b ¤   ¤   ¤   EndDialog(hwndDlg, FALSE);
7e0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
a7cdcb ¤   ¤   ¤   break;
ceaf5a
a471eb ¤   ¤   case IDCANCEL:
af3bb5 ¤   ¤   ¤   EndDialog(hwndDlg, TRUE);
3e0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
99cdcb ¤   ¤   ¤   break;
0daf5a
cba7c8 ¤   ¤   case IDC_CLIENTINSTALL:
01f776 ¤   ¤   ¤   {
47f52f ¤   ¤   ¤   ¤   char szFilePath[MAX_PATH];
9baf5a
2c6347 ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_CLIENTINSTALL),
f24d6a ¤   ¤   ¤   ¤   ¤   szFilePath, MAX_PATH-1);
b5af5a
c6b03f ¤   ¤   ¤   ¤   if (strlen(szFilePath) > 0)
b0394d ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
befa07 ¤   ¤   ¤   ¤   else
4a02ae ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
12af5a
fd841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
a9f622 ¤   ¤   ¤   ¤   break;
--7354 0010e30095a40110255 Page 2 of FindInstaller.cpp
cfa3a6 ¤   ¤   ¤   }
ccaf5a
c8481c ¤   ¤   case IDC_BROWSE:
90f776 ¤   ¤   ¤   {
b10cea ¤   ¤   ¤   ¤   LPMALLOC pMalloc;
b3d05b ¤   ¤   ¤   ¤   BROWSEINFO bi;
f13574 ¤   ¤   ¤   ¤   LPITEMIDLIST pidlInstallDir;
6708b9 ¤   ¤   ¤   ¤   char szInstallDir[MAX_PATH];
85e06b ¤   ¤   ¤   ¤   int nDirLength;
09af5a
c92a5e ¤   ¤   ¤   ¤   SHGetMalloc(&pMalloc);
0f2b85 ¤   ¤   ¤   ¤
d2fb9b ¤   ¤   ¤   ¤   bi.hwndOwner = hwndDlg;
895bd9 ¤   ¤   ¤   ¤   bi.pidlRoot = NULL;
4ed74d ¤   ¤   ¤   ¤   bi.pszDisplayName = szInstallDir;
0b1451 ¤   ¤   ¤   ¤   bi.lpszTitle = NULL;
e77795 ¤   ¤   ¤   ¤   bi.ulFlags = 0;
79a248 ¤   ¤   ¤   ¤   bi.lpfn = NULL;
dcf108 ¤   ¤   ¤   ¤   bi.lParam = 0;
c6af5a
460338 ¤   ¤   ¤   ¤   pidlInstallDir = SHBrowseForFolder(&bi);
13641d ¤   ¤   ¤   ¤   if (pidlInstallDir != NULL)
0b72c3 ¤   ¤   ¤   ¤   {
b6c0ec ¤   ¤   ¤   ¤   ¤   SHGetPathFromIDList(pidlInstallDir, szInstallDir);
365dfe ¤   ¤   ¤   ¤   ¤   nDirLength = strlen(szInstallDir);
a8250c ¤   ¤   ¤   ¤   ¤   if (szInstallDir[nDirLength-1] != '\\')
15a9e1 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szInstallDir, "\\");
edaf5a
b40541 ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_CLIENTINSTALL),
712b65 ¤   ¤   ¤   ¤   ¤   ¤   szInstallDir);
5af868 ¤   ¤   ¤   ¤   ¤   pMalloc->Free(pidlInstallDir);
92af5a
80394d ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
392613 ¤   ¤   ¤   ¤   }
05af5a
fb841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
52f622 ¤   ¤   ¤   ¤   break;
b0a3a6 ¤   ¤   ¤   }
030fe4 ¤   ¤   }
0f1b52 ¤   ¤
3e2f68 ¤   ¤   break;
cf9371 ¤   }
6eaf5a
5248b1 ¤   return(bReturnCode);
ecefe6 }
f4af5a
67af5a
7baf5a
4b7e4d /*__Editor_settings____
00af5a
954126 ¤   Local Variables:
217b17 ¤   tab-width: 4
e10e6c ¤   End:
e65f8c ¤   vi: ts=4 sw=4
c09e9b ¤   vim: si
0ed062 _____________________*/
--2945 00195dbe2a040110256 Page 1 of FindInstaller.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7f30bf ¤   $Id: FindInstaller.h,v 1.1.18.1 1998/11/12 03:13:07 heller Exp $
8bf7f7 ____________________________________________________________________________*/
547769 #ifndef Included_FindInstaller_h¤   /* [ */
e6f33e #define Included_FindInstaller_h
eeaf5a
20facf BOOL CALLBACK FindInstallerDlgProc(HWND hwndDlg,·
a6218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
3d2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
7c0f2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
bbaf5a
ef9d72 #endif /* ] Included_FindInstaller_h */
0caf5a
daaf5a
e67e4d /*__Editor_settings____
b6af5a
c14126 ¤   Local Variables:
a37b17 ¤   tab-width: 4
670e6c ¤   End:
355f8c ¤   vi: ts=4 sw=4
1c9e9b ¤   vim: si
95d062 _____________________*/
--ed1a 0009822f98b40110257 Page 1 of Finish.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c21934 ¤   $Id: Finish.cpp,v 1.16.8.1 1998/11/12 03:13:07 heller Exp $
3ef7f7 ____________________________________________________________________________*/
36af5a
9f5655 #include <windows.h>
2bfb83 #include "PGPadmin.h"
11f3cf #include <shlobj.h>
bf8031 #include "resource.h"
eaa076 #include "pgpKeys.h"
e40d08 #include "pgpMem.h"
b35ab2 #include "PGPcl.h"
edaf5a
382d1c BOOL CALLBACK FinishDlgProc(HWND hwndDlg,·
7e2add ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
bdcec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
234868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
c1bb36 {
a71d63 ¤   BOOL¤   ¤   ¤   bReturnCode¤= FALSE;
0d8ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
77af5a
636357 ¤   g_hCurrentDlgWnd = hwndDlg;
eaaf5a
969450 ¤   if (uMsg != WM_INITDIALOG)
a7e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
83af5a
a1c08d ¤   switch(uMsg)
6cc7a1 ¤   {
d42940 ¤   case WM_INITDIALOG:
a25b34 ¤   ¤   {
16afc0 ¤   ¤   ¤   RECT rc;
8e313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
34af5a
4b015a ¤   ¤   ¤   // center dialog on screen
06d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
fb3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
3a0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
c7004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
6bf9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
14af5a
e23970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
82ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
00021f ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
7ecdcb ¤   ¤   ¤   break;
bc0fe4 ¤   ¤   }
99af5a
1b93f9 ¤   case WM_PAINT:
4dc334 ¤   ¤   if (pConfig->hPalette)
815b34 ¤   ¤   {
cff431 ¤   ¤   ¤   PAINTSTRUCT ps;
4760df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
7f4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
5e9ffe ¤   ¤   ¤   RealizePalette (hDC);
d6438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
c90fe0 ¤   ¤   ¤   bReturnCode = TRUE;
330fe4 ¤   ¤   }
3d2f68 ¤   ¤   break;
fb1b52 ¤   ¤
dcc93c ¤   case WM_NOTIFY:
2a5b34 ¤   ¤   {
1ba08b ¤   ¤   ¤   LPNMHDR pnmh;
a9af5a
9a2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
22b7b0 ¤   ¤   ¤   switch(pnmh->code)
70f776 ¤   ¤   ¤   {
9766bc ¤   ¤   ¤   case PSN_SETACTIVE:
9672c3 ¤   ¤   ¤   ¤   {
987182 ¤   ¤   ¤   ¤   ¤   // Initialize window
--96a6 000ba27885c40110257 Page 2 of Finish.cpp
57bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
825c42 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETFINISHTEXT, 0, (LPARAM) "&Save");
adaf5a
aa9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
1d670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
a7af5a
63bcb7 ¤   ¤   ¤   ¤   ¤   if (pConfig->szInstallDir == NULL)
b64859 ¤   ¤   ¤   ¤   ¤   {
eef1d6 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg), PSM_SETWIZBUTTONS, 0,·
ca2552 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_DISABLEDFINISH | PSWIZB_BACK);
50c9f1 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_INSTALLDIR),
8134a8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "");
721c89 ¤   ¤   ¤   ¤   ¤   }
804bd6 ¤   ¤   ¤   ¤   ¤   else
664859 ¤   ¤   ¤   ¤   ¤   {
4df1d6 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg), PSM_SETWIZBUTTONS, 0,·
f59367 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_FINISH | PSWIZB_BACK);
e5c383 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_INSTALLDIR),·
b61cc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir);
741c89 ¤   ¤   ¤   ¤   ¤   }
64af5a
db4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c814c3 ¤   ¤   ¤   ¤   ¤   break;
a92613 ¤   ¤   ¤   ¤   }
08af5a
9eb546 ¤   ¤   ¤   case PSN_WIZFINISH:
2372c3 ¤   ¤   ¤   ¤   {
646b97 ¤   ¤   ¤   ¤   ¤   int nDirLength;
df1747 ¤   ¤   ¤   ¤   ¤   char szPGPPath[MAX_PATH];
9722ad ¤   ¤   ¤   ¤   ¤   char szClientInstaller[255];
cac537 ¤   ¤   ¤   ¤   ¤   char szMsg[255];
9bea46 ¤   ¤   ¤   ¤   ¤   char szTitle[255];
31ae30 ¤   ¤   ¤   ¤   ¤
d6fee5 ¤   ¤   ¤   ¤   ¤   if (g_bGotReloadMsg == TRUE)
6b00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
29af5a
22a95b ¤   ¤   ¤   ¤   ¤   if (pConfig->szInstallDir)
ae4859 ¤   ¤   ¤   ¤   ¤   {
9df024 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(pConfig->szInstallDir);
d2cd9f ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir = NULL;
4a1c89 ¤   ¤   ¤   ¤   ¤   }
efae30 ¤   ¤   ¤   ¤   ¤
71896d ¤   ¤   ¤   ¤   ¤   nDirLength = GetWindowTextLength(GetDlgItem(hwndDlg,·
2b79bd ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLDIR));
46ae30 ¤   ¤   ¤   ¤   ¤
0ea486 ¤   ¤   ¤   ¤   ¤   if (nDirLength > 0)
ad4859 ¤   ¤   ¤   ¤   ¤   {
02a8d1 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir = (char *)
8531b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPNewData(pConfig->memoryMgr,
27a5ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   nDirLength + 2,
20e7fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
2f94aa ¤   ¤   ¤   ¤   ¤   ¤
8f84c1 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_INSTALLDIR),
ea4c90 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir, nDirLength+1);
16af5a
a9163b ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->szInstallDir[nDirLength-1] != '\\')
bd8fec ¤   ¤   ¤   ¤   ¤   ¤   {
683490 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(pConfig->szInstallDir, "\\");
79bc49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nDirLength++;
46db3c ¤   ¤   ¤   ¤   ¤   ¤   }
73af5a
06a1c1 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir[nDirLength] = 0;
e2af5a
edd5b2 ¤   ¤   ¤   ¤   ¤   ¤   PGPclGetPGPPath(szPGPPath, MAX_PATH-1);
40cb44 ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_CLIENTINSTALLER,
3e0d7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   szClientInstaller, 254);
0cc7dc ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPGPPath, szClientInstaller);
06af5a
04aef6 ¤   ¤   ¤   ¤   ¤   ¤   if (strstr(pConfig->szInstallDir, szPGPPath) != NULL)
6a8fec ¤   ¤   ¤   ¤   ¤   ¤   {
b4a0a1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_E_INSTALLDIR,
ba412b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szMsg, 254);
--0568 0005c0541ee40110257 Page 3 of Finish.cpp
777a09 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
7850fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(hwndDlg, szMsg, szTitle,·
f3295b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_ICONEXCLAMATION);
fd67c5 ¤
691a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
7bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
2d7f8b ¤   ¤   ¤   ¤   ¤   ¤   else
a8afce ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->bSave = TRUE;
0a1c89 ¤   ¤   ¤   ¤   ¤   }
91ae30 ¤   ¤   ¤   ¤   ¤
9b4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9914c3 ¤   ¤   ¤   ¤   ¤   break;
312613 ¤   ¤   ¤   ¤   }
a6af5a
88d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
0e72c3 ¤   ¤   ¤   ¤   {
e06b97 ¤   ¤   ¤   ¤   ¤   int nDirLength;
deaf5a
56a95b ¤   ¤   ¤   ¤   ¤   if (pConfig->szInstallDir)
834859 ¤   ¤   ¤   ¤   ¤   {
eef024 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(pConfig->szInstallDir);
c3cd9f ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir = NULL;
581c89 ¤   ¤   ¤   ¤   ¤   }
beaf5a
e5896d ¤   ¤   ¤   ¤   ¤   nDirLength = GetWindowTextLength(GetDlgItem(hwndDlg,·
1cffbc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLDIR));
a0af5a
95a486 ¤   ¤   ¤   ¤   ¤   if (nDirLength > 0)
e74859 ¤   ¤   ¤   ¤   ¤   {
a6a8d1 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir = (char *)
1931b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPNewData(pConfig->memoryMgr,
455299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nDirLength + 1,
10e0c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
41af5a
2784c1 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_INSTALLDIR),
3d4c90 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir, nDirLength+1);
43af5a
54163b ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->szInstallDir[nDirLength-1] != '\\')
1d8fec ¤   ¤   ¤   ¤   ¤   ¤   {
163490 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(pConfig->szInstallDir, "\\");
65bc49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nDirLength++;
8fdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
42af5a
d5a1c1 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szInstallDir[nDirLength] = 0;
d11c89 ¤   ¤   ¤   ¤   ¤   }
35ae30 ¤   ¤   ¤   ¤   ¤
c64149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
8614c3 ¤   ¤   ¤   ¤   ¤   break;
6d2613 ¤   ¤   ¤   ¤   }
beaf5a
3a6122 ¤   ¤   ¤   case PSN_HELP:
a572c3 ¤   ¤   ¤   ¤   {
f0f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
3514c3 ¤   ¤   ¤   ¤   ¤   break;
cb2613 ¤   ¤   ¤   ¤   }
d1af5a
668f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
7f72c3 ¤   ¤   ¤   ¤   {
fa6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
c0014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
7f14c3 ¤   ¤   ¤   ¤   ¤   break;
8f2613 ¤   ¤   ¤   ¤   }
fba3a6 ¤   ¤   ¤   }
6587c7 ¤   ¤   ¤
6bcdcb ¤   ¤   ¤   break;
380fe4 ¤   ¤   }
79af5a
a13fcf ¤   case WM_COMMAND:
cf72a4 ¤   ¤   switch (LOWORD(wParam))
ce5b34 ¤   ¤   {
100631 ¤   ¤   case IDC_INSTALLDIR:
5cf776 ¤   ¤   ¤   {
--309f 0017b655a8b40110257 Page 4 of Finish.cpp
35f52f ¤   ¤   ¤   ¤   char szFilePath[MAX_PATH];
d7af5a
5647e6 ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_INSTALLDIR),
c84d6a ¤   ¤   ¤   ¤   ¤   szFilePath, MAX_PATH-1);
3daf5a
d9b03f ¤   ¤   ¤   ¤   if (strlen(szFilePath) > 0)
5d438e ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg), PSM_SETWIZBUTTONS, 0,·
f89010 ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_FINISH | PSWIZB_BACK);
20fa07 ¤   ¤   ¤   ¤   else
a0438e ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg), PSM_SETWIZBUTTONS, 0,·
50994b ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_DISABLEDFINISH | PSWIZB_BACK);
06af5a
d9841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
93f622 ¤   ¤   ¤   ¤   break;
dfa3a6 ¤   ¤   ¤   }
9baf5a
25481c ¤   ¤   case IDC_BROWSE:
c2f776 ¤   ¤   ¤   {
770cea ¤   ¤   ¤   ¤   LPMALLOC pMalloc;
41d05b ¤   ¤   ¤   ¤   BROWSEINFO bi;
283574 ¤   ¤   ¤   ¤   LPITEMIDLIST pidlInstallDir;
4108b9 ¤   ¤   ¤   ¤   char szInstallDir[MAX_PATH];
c91afe ¤   ¤   ¤   ¤   char szInstallTitle[255];
27e06b ¤   ¤   ¤   ¤   int nDirLength;
b1af5a
742a5e ¤   ¤   ¤   ¤   SHGetMalloc(&pMalloc);
faee2f ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_CHOOSEDIR, szInstallTitle,·
742925 ¤   ¤   ¤   ¤   ¤   254);
562b85 ¤   ¤   ¤   ¤
42fb9b ¤   ¤   ¤   ¤   bi.hwndOwner = hwndDlg;
c35bd9 ¤   ¤   ¤   ¤   bi.pidlRoot = NULL;
9ad74d ¤   ¤   ¤   ¤   bi.pszDisplayName = szInstallDir;
ecc609 ¤   ¤   ¤   ¤   bi.lpszTitle = szInstallTitle;
277795 ¤   ¤   ¤   ¤   bi.ulFlags = 0;
c3a248 ¤   ¤   ¤   ¤   bi.lpfn = NULL;
5af108 ¤   ¤   ¤   ¤   bi.lParam = 0;
cdaf5a
810338 ¤   ¤   ¤   ¤   pidlInstallDir = SHBrowseForFolder(&bi);
96641d ¤   ¤   ¤   ¤   if (pidlInstallDir != NULL)
8172c3 ¤   ¤   ¤   ¤   {
b5c0ec ¤   ¤   ¤   ¤   ¤   SHGetPathFromIDList(pidlInstallDir, szInstallDir);
6a5dfe ¤   ¤   ¤   ¤   ¤   nDirLength = strlen(szInstallDir);
1a250c ¤   ¤   ¤   ¤   ¤   if (szInstallDir[nDirLength-1] != '\\')
31a9e1 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szInstallDir, "\\");
68af5a
4c195a ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_INSTALLDIR),
062b65 ¤   ¤   ¤   ¤   ¤   ¤   szInstallDir);
f9f868 ¤   ¤   ¤   ¤   ¤   pMalloc->Free(pidlInstallDir);
c1af5a
c4438e ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg), PSM_SETWIZBUTTONS, 0,·
629010 ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_FINISH | PSWIZB_BACK);
f42613 ¤   ¤   ¤   ¤   }
dfaf5a
a6841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
cdf622 ¤   ¤   ¤   ¤   break;
f3a3a6 ¤   ¤   ¤   }
770fe4 ¤   ¤   }
961b52 ¤   ¤
142f68 ¤   ¤   break;
e79371 ¤   }
a3af5a
fb48b1 ¤   return(bReturnCode);
92efe6 }
97af5a
897e4d /*__Editor_settings____
55af5a
174126 ¤   Local Variables:
627b17 ¤   tab-width: 4
b60e6c ¤   End:
675f8c ¤   vi: ts=4 sw=4
a69e9b ¤   vim: si
7bd062 _____________________*/
--f0b9 000f6a8d6d140110258 Page 1 of InstallOptions.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
152e39 ¤   $Id: InstallOptions.cpp,v 1.4.8.1 1998/11/12 03:13:08 heller Exp $
f8f7f7 ____________________________________________________________________________*/
03af5a
935655 #include <windows.h>
9efb83 #include "PGPadmin.h"
478031 #include "resource.h"
eac97b #include "pgpClientPrefs.h"
734919 #include "pgpUtilities.h"
f091b9 #include "pgpSDKPrefs.h"
64af5a
6444e0 BOOL CALLBACK InstallOptionsDlgProc(HWND hwndDlg,·
71baeb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
0c40d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
d60142 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
0cbb36 {
430f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
9f8ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
26af5a
936357 ¤   g_hCurrentDlgWnd = hwndDlg;
f8af5a
709450 ¤   if (uMsg != WM_INITDIALOG)
d8e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
11af5a
97c08d ¤   switch(uMsg)
9bc7a1 ¤   {
a52940 ¤   case WM_INITDIALOG:
a05b34 ¤   ¤   {
d3afc0 ¤   ¤   ¤   RECT rc;
47313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
09af5a
79015a ¤   ¤   ¤   // center dialog on screen
66d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
61b2c2 ¤   ¤   ¤   SetWindowPos (GetParent(hwndDlg), NULL,
7c0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
b5004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
c6f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
89af5a
903970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
79ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
a5cdcb ¤   ¤   ¤   break;
8e0fe4 ¤   ¤   }
f7af5a
1793f9 ¤   case WM_PAINT:
09c334 ¤   ¤   if (pConfig->hPalette)
2c5b34 ¤   ¤   {
cdf431 ¤   ¤   ¤   PAINTSTRUCT ps;
1c60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
964fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
4b9ffe ¤   ¤   ¤   RealizePalette (hDC);
fb438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
ac0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
930fe4 ¤   ¤   }
922f68 ¤   ¤   break;
671b52 ¤   ¤
50c93c ¤   case WM_NOTIFY:
845b34 ¤   ¤   {
1ba08b ¤   ¤   ¤   LPNMHDR pnmh;
40af5a
5c2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
3bb7b0 ¤   ¤   ¤   switch(pnmh->code)
34f776 ¤   ¤   ¤   {
3266bc ¤   ¤   ¤   case PSN_SETACTIVE:
4872c3 ¤   ¤   ¤   ¤   {
bb7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
0e5256 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),·
f6c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
--ee56 000272b9d9a40110258 Page 2 of InstallOptions.cpp
e0af5a
7f9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
b3670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
e2af5a
4ad25e ¤   ¤   ¤   ¤   ¤   if (pConfig->bPreselectInstall)
be4859 ¤   ¤   ¤   ¤   ¤   {
378c31 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_PRESELECT, BST_CHECKED);
21ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
b068a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR), TRUE);
92ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
f28d92 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLPROGRAMS), TRUE);
c2ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
cbc55e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLDISK), TRUE);
77ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
205015 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLEUDORA), TRUE);
f3ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
62a75f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTLOOK), TRUE);
1dec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
50744d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTEXPRESS), TRUE);
f7ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
2ec181 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLMANUAL), TRUE);
52ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
62d412 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_UNINSTALL), TRUE);
701c89 ¤   ¤   ¤   ¤   ¤   }
fe4bd6 ¤   ¤   ¤   ¤   ¤   else
474859 ¤   ¤   ¤   ¤   ¤   {
95a119 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_PRESELECT,·
b2d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
38ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
3e4aab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR), FALSE);
5fec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
0f2c60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLPROGRAMS), FALSE);
43ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
6b2048 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLDISK), FALSE);
38ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
cfdc0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLEUDORA), FALSE);
4fec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
d131a3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTLOOK), FALSE);
abec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
6a02e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTEXPRESS), FALSE);
d7ec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
090e36 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLMANUAL), FALSE);
0fec2d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
37a831 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_UNINSTALL), FALSE);
191c89 ¤   ¤   ¤   ¤   ¤   }
9caf5a
99c1d3 ¤   ¤   ¤   ¤   ¤   if (pConfig->szUserInstallDir == NULL)
674859 ¤   ¤   ¤   ¤   ¤   {
858b78 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg,·
45063d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR), "");
151c89 ¤   ¤   ¤   ¤   ¤   }
a74bd6 ¤   ¤   ¤   ¤   ¤   else
e44859 ¤   ¤   ¤   ¤   ¤   {
e78b78 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg,·
b398fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR),·
834299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szUserInstallDir);
2f1c89 ¤   ¤   ¤   ¤   ¤   }
64af5a
1586d0 ¤   ¤   ¤   ¤   ¤   if (pConfig->bInstallPrograms)
914859 ¤   ¤   ¤   ¤   ¤   {
ebd4cf ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLPROGRAMS,·
ba94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
df1c89 ¤   ¤   ¤   ¤   ¤   }
ba4bd6 ¤   ¤   ¤   ¤   ¤   else
664859 ¤   ¤   ¤   ¤   ¤   {
05d4cf ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLPROGRAMS,·
51d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
6a1c89 ¤   ¤   ¤   ¤   ¤   }
32af5a
95c21f ¤   ¤   ¤   ¤   ¤   if (pConfig->bInstallDisk)
c34859 ¤   ¤   ¤   ¤   ¤   {
275c8d ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLDISK,·
--0da2 00074692dc840110258 Page 3 of InstallOptions.cpp
b994bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
5a1c89 ¤   ¤   ¤   ¤   ¤   }
3e4bd6 ¤   ¤   ¤   ¤   ¤   else
4b4859 ¤   ¤   ¤   ¤   ¤   {
4a5c8d ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLDISK,·
85d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
c81c89 ¤   ¤   ¤   ¤   ¤   }
61af5a
576743 ¤   ¤   ¤   ¤   ¤   if (pConfig->bInstallEudora)
a04859 ¤   ¤   ¤   ¤   ¤   {
cbaee3 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLEUDORA,·
5894bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
241c89 ¤   ¤   ¤   ¤   ¤   }
d04bd6 ¤   ¤   ¤   ¤   ¤   else
d74859 ¤   ¤   ¤   ¤   ¤   {
6faee3 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLEUDORA,·
16d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
e61c89 ¤   ¤   ¤   ¤   ¤   }
eeaf5a
a75ec5 ¤   ¤   ¤   ¤   ¤   if (pConfig->bInstallOutlook)
d24859 ¤   ¤   ¤   ¤   ¤   {
7b4acb ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLOUTLOOK,·
8394bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
d21c89 ¤   ¤   ¤   ¤   ¤   }
9e4bd6 ¤   ¤   ¤   ¤   ¤   else
744859 ¤   ¤   ¤   ¤   ¤   {
0e4acb ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLOUTLOOK,·
42d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
6c1c89 ¤   ¤   ¤   ¤   ¤   }
e0af5a
8392bf ¤   ¤   ¤   ¤   ¤   if (pConfig->bInstallOutExpress)
724859 ¤   ¤   ¤   ¤   ¤   {
5f238d ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLOUTEXPRESS,·
6994bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
b21c89 ¤   ¤   ¤   ¤   ¤   }
704bd6 ¤   ¤   ¤   ¤   ¤   else
f14859 ¤   ¤   ¤   ¤   ¤   {
52238d ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLOUTEXPRESS,·
bfd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
2b1c89 ¤   ¤   ¤   ¤   ¤   }
24af5a
6e58b5 ¤   ¤   ¤   ¤   ¤   if (pConfig->bInstallManual)
0e4859 ¤   ¤   ¤   ¤   ¤   {
a03c65 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLMANUAL,·
cc94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
f21c89 ¤   ¤   ¤   ¤   ¤   }
fc4bd6 ¤   ¤   ¤   ¤   ¤   else
6f4859 ¤   ¤   ¤   ¤   ¤   {
0b3c65 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLMANUAL,·
c9d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
271c89 ¤   ¤   ¤   ¤   ¤   }
25af5a
cdeb44 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUninstallOld)
274859 ¤   ¤   ¤   ¤   ¤   {
74e8b6 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_UNINSTALL,·
8194bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
111c89 ¤   ¤   ¤   ¤   ¤   }
d84bd6 ¤   ¤   ¤   ¤   ¤   else
b64859 ¤   ¤   ¤   ¤   ¤   {
efe8b6 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_UNINSTALL,·
a4d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
641c89 ¤   ¤   ¤   ¤   ¤   }
edaf5a
d84149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
3014c3 ¤   ¤   ¤   ¤   ¤   break;
9e2613 ¤   ¤   ¤   ¤   }
0caf5a
8dd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
8872c3 ¤   ¤   ¤   ¤   {
53101f ¤   ¤   ¤   ¤   ¤   int nLength;
7eaf5a
7452e6 ¤   ¤   ¤   ¤   ¤   if (pConfig->szUserInstallDir)
--bb9c 000b2a24d9e40110258 Page 4 of InstallOptions.cpp
e04859 ¤   ¤   ¤   ¤   ¤   {
e21542 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(pConfig->szUserInstallDir);
4efa56 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szUserInstallDir = NULL;
5e1c89 ¤   ¤   ¤   ¤   ¤   }
58af5a
af4925 ¤   ¤   ¤   ¤   ¤   nLength = GetWindowTextLength(GetDlgItem(hwndDlg,·
9d3ba0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR));
ffaf5a
7e37ee ¤   ¤   ¤   ¤   ¤   if (nLength)
8c4859 ¤   ¤   ¤   ¤   ¤   {
fdc5ff ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szUserInstallDir = (char *)
8131b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPNewData(pConfig->memoryMgr,
436c95 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nLength+1, kPGPMemoryMgrFlags_Clear);
74af5a
686c0c ¤   ¤   ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg,·
547a38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR),
445e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szUserInstallDir,·
ca93be ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nLength+1);
4de4ad ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szUserInstallDir[nLength] = 0;
c51c89 ¤   ¤   ¤   ¤   ¤   }
a5af5a
2f14c3 ¤   ¤   ¤   ¤   ¤   break;
0d2613 ¤   ¤   ¤   ¤   }
c0af5a
fb6122 ¤   ¤   ¤   case PSN_HELP:
3072c3 ¤   ¤   ¤   ¤   {
1cf1f2 ¤   ¤   ¤   ¤   ¤   // Display help
7814c3 ¤   ¤   ¤   ¤   ¤   break;
af2613 ¤   ¤   ¤   ¤   }
a9af5a
c08f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
8672c3 ¤   ¤   ¤   ¤   {
166b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
24014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
a714c3 ¤   ¤   ¤   ¤   ¤   break;
312613 ¤   ¤   ¤   ¤   }
1ea3a6 ¤   ¤   ¤   }
b387c7 ¤   ¤   ¤
cecdcb ¤   ¤   ¤   break;
e40fe4 ¤   ¤   }
87af5a
683fcf ¤   case WM_COMMAND:
6872a4 ¤   ¤   switch (LOWORD(wParam))
f85b34 ¤   ¤   {
8fdcbf ¤   ¤   case IDC_PRESELECT:
7ff776 ¤   ¤   ¤   {
63a256 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_PRESELECT) ==·
df2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
f572c3 ¤   ¤   ¤   ¤   {
9bc179 ¤   ¤   ¤   ¤   ¤   pConfig->bPreselectInstall = TRUE;
feef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
2855c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR), TRUE);
06ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
de07d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLPROGRAMS), TRUE);
64ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
dc1f77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLDISK), TRUE);
68ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
0ddde9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLEUDORA), TRUE);
c6ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
f09a31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTLOOK), TRUE);
3aef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
be67c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTEXPRESS), TRUE);
c4ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
274c7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLMANUAL), TRUE);
f1ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
12d4f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_UNINSTALL), TRUE);
e82613 ¤   ¤   ¤   ¤   }
2dfa07 ¤   ¤   ¤   ¤   else
c272c3 ¤   ¤   ¤   ¤   {
badfc4 ¤   ¤   ¤   ¤   ¤   pConfig->bPreselectInstall = FALSE;
63ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
b2c0ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_USERINSTALLDIR), FALSE);
--aa7e 00091aafc6c40110258 Page 5 of InstallOptions.cpp
a9ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
ec3943 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLPROGRAMS), FALSE);
54ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
a99c51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLDISK), FALSE);
66ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
f4e164 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLEUDORA), FALSE);
b3ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
2ebbe6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTLOOK), FALSE);
d7ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
464c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLOUTEXPRESS), FALSE);
77ef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
7f3358 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_INSTALLMANUAL), FALSE);
2cef5a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
356c2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_UNINSTALL), FALSE);
212613 ¤   ¤   ¤   ¤   }
feaf5a
7c841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
33f622 ¤   ¤   ¤   ¤   break;
62a3a6 ¤   ¤   ¤   }
feaf5a
15c056 ¤   ¤   case IDC_INSTALLPROGRAMS:
bbf776 ¤   ¤   ¤   {
94626a ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_INSTALLPROGRAMS) ==·
ab2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
d472c3 ¤   ¤   ¤   ¤   {
a9df77 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallPrograms = TRUE;
612613 ¤   ¤   ¤   ¤   }
81fa07 ¤   ¤   ¤   ¤   else
6772c3 ¤   ¤   ¤   ¤   {
1336a4 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallPrograms = FALSE;
c044d0 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallEudora = FALSE;
c09e7c ¤   ¤   ¤   ¤   ¤   pConfig->bInstallOutlook = FALSE;
afd524 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallOutExpress = FALSE;
a19236 ¤   ¤   ¤   ¤   ¤   pConfig->bUninstallOld = FALSE;
26af5a
4c938d ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLEUDORA,·
a45809 ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
4cc08e ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLOUTLOOK,·
ab5809 ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
336dfa ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLOUTEXPRESS,·
ef5809 ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
6d2caa ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_UNINSTALL,·
055809 ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
ba2613 ¤   ¤   ¤   ¤   }
bcaf5a
32841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
40f622 ¤   ¤   ¤   ¤   break;
2aa3a6 ¤   ¤   ¤   }
baaf5a
25ec4f ¤   ¤   case IDC_INSTALLEUDORA:
21f776 ¤   ¤   ¤   {
877232 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_INSTALLEUDORA) ==·
ad2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
ac72c3 ¤   ¤   ¤   ¤   {
d12416 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallEudora = TRUE;
10df77 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallPrograms = TRUE;
14c1ec ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLPROGRAMS,·
aba855 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
9d2613 ¤   ¤   ¤   ¤   }
fefa07 ¤   ¤   ¤   ¤   else
a472c3 ¤   ¤   ¤   ¤   {
ce44d0 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallEudora = FALSE;
8b2613 ¤   ¤   ¤   ¤   }
80af5a
54841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
3ef622 ¤   ¤   ¤   ¤   break;
aba3a6 ¤   ¤   ¤   }
65af5a
5b4211 ¤   ¤   case IDC_INSTALLOUTLOOK:
90f776 ¤   ¤   ¤   {
1cd715 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_INSTALLOUTLOOK) ==·
912a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
--fc9f 0006b71c5e540110258 Page 6 of InstallOptions.cpp
d072c3 ¤   ¤   ¤   ¤   {
37650a ¤   ¤   ¤   ¤   ¤   pConfig->bInstallOutlook = TRUE;
8bdf77 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallPrograms = TRUE;
1ec1ec ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLPROGRAMS,·
dda855 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
102613 ¤   ¤   ¤   ¤   }
e5fa07 ¤   ¤   ¤   ¤   else
ba72c3 ¤   ¤   ¤   ¤   {
c59e7c ¤   ¤   ¤   ¤   ¤   pConfig->bInstallOutlook = FALSE;
422613 ¤   ¤   ¤   ¤   }
b8af5a
2b841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
a1f622 ¤   ¤   ¤   ¤   break;
8ea3a6 ¤   ¤   ¤   }
23af5a
454f55 ¤   ¤   case IDC_INSTALLOUTEXPRESS:
5bf776 ¤   ¤   ¤   {
6b7c58 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_INSTALLOUTEXPRESS) ==·
ff2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
6172c3 ¤   ¤   ¤   ¤   {
e371d3 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallOutExpress = TRUE;
f0df77 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallPrograms = TRUE;
e3c1ec ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLPROGRAMS,·
eba855 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
492613 ¤   ¤   ¤   ¤   }
ddfa07 ¤   ¤   ¤   ¤   else
a672c3 ¤   ¤   ¤   ¤   {
9ad524 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallOutExpress = FALSE;
8a2613 ¤   ¤   ¤   ¤   }
93af5a
51841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
d9f622 ¤   ¤   ¤   ¤   break;
d2a3a6 ¤   ¤   ¤   }
85af5a
40d3b9 ¤   ¤   case IDC_INSTALLMANUAL:
9df776 ¤   ¤   ¤   {
2182ea ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_INSTALLMANUAL) ==·
6f2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
3672c3 ¤   ¤   ¤   ¤   {
3b11d3 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallManual = TRUE;
c42613 ¤   ¤   ¤   ¤   }
ccfa07 ¤   ¤   ¤   ¤   else
b272c3 ¤   ¤   ¤   ¤   {
59d544 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallManual = FALSE;
772613 ¤   ¤   ¤   ¤   }
c0af5a
11841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
a4f622 ¤   ¤   ¤   ¤   break;
75a3a6 ¤   ¤   ¤   }
14af5a
52ff4b ¤   ¤   case IDC_INSTALLDISK:
aaf776 ¤   ¤   ¤   {
bb26e7 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_INSTALLDISK) ==·
1b2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
5c72c3 ¤   ¤   ¤   ¤   {
e49cc4 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallDisk = TRUE;
3e2613 ¤   ¤   ¤   ¤   }
54fa07 ¤   ¤   ¤   ¤   else
3872c3 ¤   ¤   ¤   ¤   {
48b1f7 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallDisk = FALSE;
d12613 ¤   ¤   ¤   ¤   }
e5af5a
49841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
11f622 ¤   ¤   ¤   ¤   break;
64a3a6 ¤   ¤   ¤   }
78af5a
332f44 ¤   ¤   case IDC_UNINSTALL:
1ef776 ¤   ¤   ¤   {
5b7638 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_UNINSTALL) ==·
362a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
9272c3 ¤   ¤   ¤   ¤   {
6b4fc6 ¤   ¤   ¤   ¤   ¤   pConfig->bUninstallOld = TRUE;
--317b 001ef80717f40110258 Page 7 of InstallOptions.cpp
7cdf77 ¤   ¤   ¤   ¤   ¤   pConfig->bInstallPrograms = TRUE;
88c1ec ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_INSTALLPROGRAMS,·
6ca855 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
182613 ¤   ¤   ¤   ¤   }
fffa07 ¤   ¤   ¤   ¤   else
5972c3 ¤   ¤   ¤   ¤   {
339236 ¤   ¤   ¤   ¤   ¤   pConfig->bUninstallOld = FALSE;
792613 ¤   ¤   ¤   ¤   }
01af5a
27841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
46f622 ¤   ¤   ¤   ¤   break;
e5a3a6 ¤   ¤   ¤   }
be0fe4 ¤   ¤   }
dbaf5a
402f68 ¤   ¤   break;
689371 ¤   }
e2af5a
d948b1 ¤   return(bReturnCode);
0befe6 }
18af5a
ceaf5a
fd7e4d /*__Editor_settings____
65af5a
f84126 ¤   Local Variables:
827b17 ¤   tab-width: 4
4f0e6c ¤   End:
bb5f8c ¤   vi: ts=4 sw=4
da9e9b ¤   vim: si
efd062 _____________________*/
--9055 000353ae35540110259 Page 1 of Intro.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
df5331 ¤   $Id: Intro.cpp,v 1.9.8.1 1998/11/12 03:13:08 heller Exp $
99f7f7 ____________________________________________________________________________*/
81af5a
5f5655 #include <windows.h>
29fb83 #include "PGPadmin.h"
068031 #include "resource.h"
ed3bb4 #include "Utils.h"
1aaf5a
7acc5e BOOL CALLBACK IntroDlgProc(HWND hwndDlg,·
d1be58 ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
2e67e2 ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
bf0304 ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
82bb36 {
970f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
a58ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
27af5a
e96357 ¤   g_hCurrentDlgWnd = hwndDlg;
6daf5a
be9450 ¤   if (uMsg != WM_INITDIALOG)
d0e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
35af5a
14c08d ¤   switch(uMsg)
a6c7a1 ¤   {
a02940 ¤   case WM_INITDIALOG:
815b34 ¤   ¤   {
78afc0 ¤   ¤   ¤   RECT rc;
62313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
50af5a
e5015a ¤   ¤   ¤   // center dialog on screen
79d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
66b2c2 ¤   ¤   ¤   SetWindowPos (GetParent(hwndDlg), NULL,
510971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
ef004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
b9f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
96af5a
bb3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
01ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
6dcdcb ¤   ¤   ¤   break;
270fe4 ¤   ¤   }
43af5a
5093f9 ¤   case WM_PAINT:
8ec334 ¤   ¤   if (pConfig->hPalette)
e55b34 ¤   ¤   {
81f431 ¤   ¤   ¤   PAINTSTRUCT ps;
0760df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
874fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
d49ffe ¤   ¤   ¤   RealizePalette (hDC);
54438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
2d0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
100fe4 ¤   ¤   }
6a2f68 ¤   ¤   break;
4f1b52 ¤   ¤
eec93c ¤   case WM_NOTIFY:
755b34 ¤   ¤   {
f8a08b ¤   ¤   ¤   LPNMHDR pnmh;
bcaf5a
512b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
82b7b0 ¤   ¤   ¤   switch(pnmh->code)
ecf776 ¤   ¤   ¤   {
a466bc ¤   ¤   ¤   case PSN_SETACTIVE:
2972c3 ¤   ¤   ¤   ¤   {
5f7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
625256 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),·
57c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
8daf5a
359908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
--b4eb 00185d2e20e40110259 Page 2 of Intro.cpp
0f670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
66af5a
374149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ac14c3 ¤   ¤   ¤   ¤   ¤   break;
5f2613 ¤   ¤   ¤   ¤   }
5aaf5a
98d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
9e72c3 ¤   ¤   ¤   ¤   {
9566b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
f614c3 ¤   ¤   ¤   ¤   ¤   break;
392613 ¤   ¤   ¤   ¤   }
4caf5a
d1b546 ¤   ¤   ¤   case PSN_WIZFINISH:
5772c3 ¤   ¤   ¤   ¤   {
a49a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
1c14c3 ¤   ¤   ¤   ¤   ¤   break;
f22613 ¤   ¤   ¤   ¤   }
56af5a
d06122 ¤   ¤   ¤   case PSN_HELP:
d572c3 ¤   ¤   ¤   ¤   {
a5f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
c414c3 ¤   ¤   ¤   ¤   ¤   break;
4c2613 ¤   ¤   ¤   ¤   }
0faf5a
2d8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
f072c3 ¤   ¤   ¤   ¤   {
996b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
74014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
5d14c3 ¤   ¤   ¤   ¤   ¤   break;
c22613 ¤   ¤   ¤   ¤   }
09a3a6 ¤   ¤   ¤   }
a287c7 ¤   ¤   ¤
efcdcb ¤   ¤   ¤   break;
f10fe4 ¤   ¤   }
78af5a
f79371 ¤   }
46af5a
7848b1 ¤   return(bReturnCode);
4cefe6 }
bfaf5a
847e4d /*__Editor_settings____
5caf5a
344126 ¤   Local Variables:
fa7b17 ¤   tab-width: 4
310e6c ¤   End:
485f8c ¤   vi: ts=4 sw=4
e69e9b ¤   vim: si
85d062 _____________________*/
--8e92 000eb0b9d8a4011025a Page 1 of KeyGen.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
234de9 ¤   $Id: KeyGen.cpp,v 1.16.2.1.2.1 1998/11/12 03:13:09 heller Exp $
42f7f7 ____________________________________________________________________________*/
f0af5a
555655 #include <windows.h>
88fb83 #include "PGPadmin.h"
1e8031 #include "resource.h"
c281a4 #include "pgpBuildFlags.h"
de5ab2 #include "PGPcl.h"
62af5a
e9af5a
ad094a BOOL CALLBACK KeyGenDlgProc(HWND hwndDlg,·
232add ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
05cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
094868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
fabb36 {
170f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
888ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
956882 ¤   char¤   ¤   ¤   szMinKeySize[10];
bcaf5a
856357 ¤   g_hCurrentDlgWnd = hwndDlg;
11af5a
309450 ¤   if (uMsg != WM_INITDIALOG)
57e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
d8af5a
42c08d ¤   switch(uMsg)
3fc7a1 ¤   {
902940 ¤   case WM_INITDIALOG:
175b34 ¤   ¤   {
faafc0 ¤   ¤   ¤   RECT rc;
11313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
1baf5a
59015a ¤   ¤   ¤   // center dialog on screen
51d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
753d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
a70971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
cb004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
62f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
7daf5a
b33970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
a6ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
afcdcb ¤   ¤   ¤   break;
f40fe4 ¤   ¤   }
44af5a
c493f9 ¤   case WM_PAINT:
a0c334 ¤   ¤   if (pConfig->hPalette)
af5b34 ¤   ¤   {
27f431 ¤   ¤   ¤   PAINTSTRUCT ps;
8e60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
974fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
5e9ffe ¤   ¤   ¤   RealizePalette (hDC);
de438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
bc0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
260fe4 ¤   ¤   }
382f68 ¤   ¤   break;
d21b52 ¤   ¤
dfc93c ¤   case WM_NOTIFY:
175b34 ¤   ¤   {
76a08b ¤   ¤   ¤   LPNMHDR pnmh;
98af5a
3c2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
7cb7b0 ¤   ¤   ¤   switch(pnmh->code)
b9f776 ¤   ¤   ¤   {
6366bc ¤   ¤   ¤   case PSN_SETACTIVE:
5672c3 ¤   ¤   ¤   ¤   {
fa7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
ebbd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
--7069 000f917191a4011025a Page 2 of KeyGen.cpp
70c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
6caf5a
a99908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
6f670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
4baf5a
353d3b ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowKeyGen)
f84859 ¤   ¤   ¤   ¤   ¤   {
6cac40 ¤   ¤   ¤   ¤   ¤   ¤   PGPError err;
deaf5a
e6ed0e ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ALLOW_KEYGEN,·
6694bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
47ae30 ¤   ¤   ¤   ¤   ¤
59d0c0 ¤   ¤   ¤   ¤   ¤   ¤   err = PGPclCheckSDKSupportForPKAlg(
6eb6e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA, FALSE, FALSE);
97af5a
759e7a #if NO_RSA_KEYGEN
6fc5e5 ¤   ¤   ¤   ¤   ¤   ¤   err = kPGPError_FeatureNotAvailable;
4b7454 #endif
adaf5a
d3b0eb ¤   ¤   ¤   ¤   ¤   ¤   if (IsntPGPError(err))
a90e2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
e2ab00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_ALLOW_RSAKEYGEN), TRUE);
e77f8b ¤   ¤   ¤   ¤   ¤   ¤   else
150e2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg,·
5b9bdd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_ALLOW_RSAKEYGEN), FALSE);
f0af5a
b661ba ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL),
a21dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
b0f800 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL2),
f31dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
90043e ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINKEYSIZE),
c61dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
c41c89 ¤   ¤   ¤   ¤   ¤   }
b44bd6 ¤   ¤   ¤   ¤   ¤   else
864859 ¤   ¤   ¤   ¤   ¤   {
2ded0e ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ALLOW_KEYGEN,·
c0d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
5cb581 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLOW_RSAKEYGEN),
9a7f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
d361ba ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL),
a67f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
fdf800 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL2),
ac7f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
7e043e ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINKEYSIZE),
297f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
181c89 ¤   ¤   ¤   ¤   ¤   }
53af5a
1910cc ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowRSAKeyGen)
184859 ¤   ¤   ¤   ¤   ¤   {
f1e769 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ALLOW_RSAKEYGEN,·
3394bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
9b1c89 ¤   ¤   ¤   ¤   ¤   }
e54bd6 ¤   ¤   ¤   ¤   ¤   else
9f4859 ¤   ¤   ¤   ¤   ¤   {
69e769 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ALLOW_RSAKEYGEN,·
1ed06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
5b1c89 ¤   ¤   ¤   ¤   ¤   }
f0af5a
61d731 ¤   ¤   ¤   ¤   ¤   wsprintf(szMinKeySize, "%d", pConfig->nMinKeySize);
a8f2aa ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_MINKEYSIZE),·
ea1ba8 ¤   ¤   ¤   ¤   ¤   ¤   szMinKeySize);
64af5a
5a4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
de14c3 ¤   ¤   ¤   ¤   ¤   break;
c62613 ¤   ¤   ¤   ¤   }
4faf5a
3cd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
ca72c3 ¤   ¤   ¤   ¤   {
7014c3 ¤   ¤   ¤   ¤   ¤   break;
652613 ¤   ¤   ¤   ¤   }
7eaf5a
f949a1 ¤   ¤   ¤   case PSN_WIZBACK:
--f383 0000e4a94a54011025a Page 3 of KeyGen.cpp
d072c3 ¤   ¤   ¤   ¤   {
e24427 ¤   ¤   ¤   ¤   ¤   // Determine if we should go to revoker key selection
495f96 ¤   ¤   ¤   ¤   ¤   // or skip to revoker key options
7aaf5a
c40966 ¤   ¤   ¤   ¤   ¤   if (!pConfig->bAutoAddRevoker)
870cd4 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_REVOKER);
f7af5a
f14149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
4114c3 ¤   ¤   ¤   ¤   ¤   break;
622613 ¤   ¤   ¤   ¤   }
b0af5a
e899a3 ¤   ¤   ¤   case PSN_WIZNEXT:
1b72c3 ¤   ¤   ¤   ¤   {
46fdba ¤   ¤   ¤   ¤   ¤   char szErrorMsg[255];
77ea46 ¤   ¤   ¤   ¤   ¤   char szTitle[255];
0e75ac ¤   ¤   ¤   ¤   ¤   BOOL bError = FALSE;
93af5a
0c4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
1115f5 ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
a8af5a
37a809 ¤   ¤   ¤   ¤   ¤   // Check data validity
58af5a
ae3d3b ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowKeyGen)
ad4859 ¤   ¤   ¤   ¤   ¤   {
20becd ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowRSAKeyGen)
578fec ¤   ¤   ¤   ¤   ¤   ¤   {
522f98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if ((pConfig->nMinKeySize < 768) ||·
1e6d8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pConfig->nMinKeySize > 2048))
f606b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
fadabb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance,·
592dcf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_E_MINKEYSIZERANGERSA, szErrorMsg, 254);
cbd413 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bError = TRUE;
675268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
27db3c ¤   ¤   ¤   ¤   ¤   ¤   }
d87f8b ¤   ¤   ¤   ¤   ¤   ¤   else
9b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
992f98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if ((pConfig->nMinKeySize < 768) ||·
aee770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pConfig->nMinKeySize > 4096))
2f06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
abdabb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance,·
b5c0e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_E_MINKEYSIZERANGE, szErrorMsg, 254);
79d413 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bError = TRUE;
245268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
6bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
c3af5a
0c4ecc ¤   ¤   ¤   ¤   ¤   ¤   if (bError)
ab8fec ¤   ¤   ¤   ¤   ¤   ¤   {
8374d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(hwndDlg, szErrorMsg, szTitle, MB_OK);
3f1a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
85db3c ¤   ¤   ¤   ¤   ¤   ¤   }
891c89 ¤   ¤   ¤   ¤   ¤   }
8baf5a
4d14c3 ¤   ¤   ¤   ¤   ¤   break;
1f2613 ¤   ¤   ¤   ¤   }
12af5a
516122 ¤   ¤   ¤   case PSN_HELP:
9272c3 ¤   ¤   ¤   ¤   {
51f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
fd14c3 ¤   ¤   ¤   ¤   ¤   break;
152613 ¤   ¤   ¤   ¤   }
43af5a
8f8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
0072c3 ¤   ¤   ¤   ¤   {
ac6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
2c014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
b714c3 ¤   ¤   ¤   ¤   ¤   break;
ce2613 ¤   ¤   ¤   ¤   }
56a3a6 ¤   ¤   ¤   }
bf87c7 ¤   ¤   ¤
83cdcb ¤   ¤   ¤   break;
910fe4 ¤   ¤   }
0eaf5a
--a90e 0007442a2234011025a Page 4 of KeyGen.cpp
fd3fcf ¤   case WM_COMMAND:
da72a4 ¤   ¤   switch (LOWORD(wParam))
b75b34 ¤   ¤   {
e329ca ¤   ¤   case IDC_ALLOW_KEYGEN:
98f776 ¤   ¤   ¤   {
dc899b ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ALLOW_KEYGEN) ==·
252a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
3d72c3 ¤   ¤   ¤   ¤   {
634333 ¤   ¤   ¤   ¤   ¤   PGPError err;
dcaf5a
456d1b ¤   ¤   ¤   ¤   ¤   pConfig->bAllowKeyGen = TRUE;
0fae30 ¤   ¤   ¤   ¤   ¤
df5f97 ¤   ¤   ¤   ¤   ¤   err = PGPclCheckSDKSupportForPKAlg(
fd664b ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA, FALSE, FALSE);
bfaf5a
af9e7a #if NO_RSA_KEYGEN
07e350 ¤   ¤   ¤   ¤   ¤   err = kPGPError_FeatureNotAvailable;
807454 #endif
34af5a
5e2173 ¤   ¤   ¤   ¤   ¤   if (IsntPGPError(err))
a2b581 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLOW_RSAKEYGEN),
771dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
364bd6 ¤   ¤   ¤   ¤   ¤   else
16b581 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLOW_RSAKEYGEN),
3c7f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
33af5a
59fc60 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL),
7791ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
b7814a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL2),
6391ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
591288 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINKEYSIZE),
c691ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
3d2613 ¤   ¤   ¤   ¤   }
a3fa07 ¤   ¤   ¤   ¤   else
d572c3 ¤   ¤   ¤   ¤   {
319f7c ¤   ¤   ¤   ¤   ¤   pConfig->bAllowKeyGen = FALSE;
9658a6 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLOW_RSAKEYGEN),
a3f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
edfc60 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL),
a4f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
5e814a ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_KEYSIZE_LABEL2),
adf481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
771288 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINKEYSIZE),
31f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
642613 ¤   ¤   ¤   ¤   }
24af5a
a0841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
e8f622 ¤   ¤   ¤   ¤   break;
c9a3a6 ¤   ¤   ¤   }
7aaf5a
a0f544 ¤   ¤   case IDC_ALLOW_RSAKEYGEN:
78f776 ¤   ¤   ¤   {
8d27ae ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ALLOW_RSAKEYGEN) ==·
072a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
2372c3 ¤   ¤   ¤   ¤   {
721f40 ¤   ¤   ¤   ¤   ¤   pConfig->bAllowRSAKeyGen = TRUE;
ba2613 ¤   ¤   ¤   ¤   }
81fa07 ¤   ¤   ¤   ¤   else
5072c3 ¤   ¤   ¤   ¤   {
da7358 ¤   ¤   ¤   ¤   ¤   pConfig->bAllowRSAKeyGen = FALSE;
e32613 ¤   ¤   ¤   ¤   }
57af5a
bf841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
d0f622 ¤   ¤   ¤   ¤   break;
f1a3a6 ¤   ¤   ¤   }
c8af5a
9552d8 ¤   ¤   case IDC_MINKEYSIZE:
1ef776 ¤   ¤   ¤   {
728d13 ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_MINKEYSIZE),·
16c716 ¤   ¤   ¤   ¤   ¤   szMinKeySize, 10);
be1b27 ¤   ¤   ¤   ¤   pConfig->nMinKeySize = atoi(szMinKeySize);
74841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
--64fb 00132741c354011025a Page 5 of KeyGen.cpp
72f622 ¤   ¤   ¤   ¤   break;
36a3a6 ¤   ¤   ¤   }
7b0fe4 ¤   ¤   }
3eaf5a
c32f68 ¤   ¤   break;
dc9371 ¤   }
70af5a
6148b1 ¤   return(bReturnCode);
5eefe6 }
beaf5a
557e4d /*__Editor_settings____
f5af5a
124126 ¤   Local Variables:
6b7b17 ¤   tab-width: 4
a50e6c ¤   End:
da5f8c ¤   vi: ts=4 sw=4
bf9e9b ¤   vim: si
32d062 _____________________*/
--8a05 0001b7b591a4011025b Page 1 of License.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
6de8c1 ¤   $Id: License.cpp,v 1.4.8.1 1998/11/12 03:13:10 heller Exp $
14f7f7 ____________________________________________________________________________*/
b2af5a
325655 #include <windows.h>
01fb83 #include "PGPadmin.h"
728031 #include "resource.h"
4d3bb4 #include "Utils.h"
a8af5a
3c67e5 BOOL CALLBACK LicenseDlgProc(HWND hwndDlg,·
f09adf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,
bfd1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
dca887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
acbb36 {
230f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
518ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
65af5a
6a6357 ¤   g_hCurrentDlgWnd = hwndDlg;
bdaf5a
179450 ¤   if (uMsg != WM_INITDIALOG)
6be72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
9daf5a
79c08d ¤   switch(uMsg)
82c7a1 ¤   {
922940 ¤   case WM_INITDIALOG:
325b34 ¤   ¤   {
c8afc0 ¤   ¤   ¤   RECT rc;
86313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
15af5a
d4015a ¤   ¤   ¤   // center dialog on screen
5dd4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
0fb2c2 ¤   ¤   ¤   SetWindowPos (GetParent(hwndDlg), NULL,
9a0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
52004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
75f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
0eaf5a
e73970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
8ead17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
08cdcb ¤   ¤   ¤   break;
060fe4 ¤   ¤   }
b8af5a
fa93f9 ¤   case WM_PAINT:
c3c334 ¤   ¤   if (pConfig->hPalette)
805b34 ¤   ¤   {
50f431 ¤   ¤   ¤   PAINTSTRUCT ps;
4360df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
3b4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
aa9ffe ¤   ¤   ¤   RealizePalette (hDC);
6f438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
f10fe0 ¤   ¤   ¤   bReturnCode = TRUE;
c40fe4 ¤   ¤   }
cd2f68 ¤   ¤   break;
cb1b52 ¤   ¤
2dc93c ¤   case WM_NOTIFY:
035b34 ¤   ¤   {
6fa08b ¤   ¤   ¤   LPNMHDR pnmh;
63af5a
e42b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
70b7b0 ¤   ¤   ¤   switch(pnmh->code)
03f776 ¤   ¤   ¤   {
8b66bc ¤   ¤   ¤   case PSN_SETACTIVE:
ca72c3 ¤   ¤   ¤   ¤   {
e57182 ¤   ¤   ¤   ¤   ¤   // Initialize window
b45256 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),·
8669e2 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
1caf5a
1b9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
--e757 0005756d5354011025b Page 2 of License.cpp
0f670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
66af5a
b32901 ¤   ¤   ¤   ¤   ¤   if (pConfig->szLicenseNum == NULL)
e94859 ¤   ¤   ¤   ¤   ¤   {
1971bd ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_LICENSENUM),
4f34a8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "");
c71c89 ¤   ¤   ¤   ¤   ¤   }
c74bd6 ¤   ¤   ¤   ¤   ¤   else
074859 ¤   ¤   ¤   ¤   ¤   {
cc4b53 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_LICENSENUM),·
9ca48a ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szLicenseNum);
cc1c89 ¤   ¤   ¤   ¤   ¤   }
9aaf5a
f84149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ee14c3 ¤   ¤   ¤   ¤   ¤   break;
a62613 ¤   ¤   ¤   ¤   }
75af5a
ecd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
0f72c3 ¤   ¤   ¤   ¤   {
90101f ¤   ¤   ¤   ¤   ¤   int nLength;
71af5a
340636 ¤   ¤   ¤   ¤   ¤   if (pConfig->szLicenseNum)
444859 ¤   ¤   ¤   ¤   ¤   {
d04868 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(pConfig->szLicenseNum);
34fa1e ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szLicenseNum = NULL;
5d1c89 ¤   ¤   ¤   ¤   ¤   }
74af5a
1e4925 ¤   ¤   ¤   ¤   ¤   nLength = GetWindowTextLength(GetDlgItem(hwndDlg,·
7b61da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_LICENSENUM));
94af5a
d037ee ¤   ¤   ¤   ¤   ¤   if (nLength)
704859 ¤   ¤   ¤   ¤   ¤   {
92054b ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szLicenseNum = (char *)
7e31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPNewData(pConfig->memoryMgr,
876c95 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nLength+1, kPGPMemoryMgrFlags_Clear);
6baf5a
1e3c8d ¤   ¤   ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_LICENSENUM),
d0b06b ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szLicenseNum, nLength+1);
a7c724 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szLicenseNum[nLength] = 0;
c31c89 ¤   ¤   ¤   ¤   ¤   }
d3af5a
fd14c3 ¤   ¤   ¤   ¤   ¤   break;
d82613 ¤   ¤   ¤   ¤   }
81af5a
cab546 ¤   ¤   ¤   case PSN_WIZFINISH:
de72c3 ¤   ¤   ¤   ¤   {
f79a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
5114c3 ¤   ¤   ¤   ¤   ¤   break;
272613 ¤   ¤   ¤   ¤   }
03af5a
d36122 ¤   ¤   ¤   case PSN_HELP:
3472c3 ¤   ¤   ¤   ¤   {
a5f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
a114c3 ¤   ¤   ¤   ¤   ¤   break;
6f2613 ¤   ¤   ¤   ¤   }
e7af5a
8f8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
2972c3 ¤   ¤   ¤   ¤   {
916b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
6a014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
dc14c3 ¤   ¤   ¤   ¤   ¤   break;
762613 ¤   ¤   ¤   ¤   }
34a3a6 ¤   ¤   ¤   }
cd87c7 ¤   ¤   ¤
28cdcb ¤   ¤   ¤   break;
900fe4 ¤   ¤   }
c5af5a
1b9371 ¤   }
79af5a
bc48b1 ¤   return(bReturnCode);
3eefe6 }
57af5a
--51b8 001dffab6e24011025b Page 3 of License.cpp
217e4d /*__Editor_settings____
c9af5a
864126 ¤   Local Variables:
f87b17 ¤   tab-width: 4
5c0e6c ¤   End:
b85f8c ¤   vi: ts=4 sw=4
a09e9b ¤   vim: si
dfd062 _____________________*/
--72bd 0006d67e82e4011025c Page 1 of Misc.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
a305ca ¤   $Id: Misc.cpp,v 1.11.8.1 1998/11/12 03:13:10 heller Exp $
6bf7f7 ____________________________________________________________________________*/
4baf5a
8c5655 #include <windows.h>
fcfb83 #include "PGPadmin.h"
d58031 #include "resource.h"
350d08 #include "pgpMem.h"
26af5a
ad5768 BOOL CALLBACK MiscDlgProc(HWND hwndDlg,·
c6556d ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
3a6540 ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
03b126 ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
01bb36 {
7a0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
d38ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
11af5a
896357 ¤   g_hCurrentDlgWnd = hwndDlg;
aaaf5a
509450 ¤   if (uMsg != WM_INITDIALOG)
0ee72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
f1af5a
48c08d ¤   switch(uMsg)
45c7a1 ¤   {
c12940 ¤   case WM_INITDIALOG:
4c5b34 ¤   ¤   {
62afc0 ¤   ¤   ¤   RECT rc;
14313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
c2af5a
79015a ¤   ¤   ¤   // center dialog on screen
09d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
a13d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
300971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
0f004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
46f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
f4af5a
4f3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
b9ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
7ccdcb ¤   ¤   ¤   break;
6d0fe4 ¤   ¤   }
33af5a
e693f9 ¤   case WM_PAINT:
bfc334 ¤   ¤   if (pConfig->hPalette)
875b34 ¤   ¤   {
adf431 ¤   ¤   ¤   PAINTSTRUCT ps;
bc60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
a34fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
529ffe ¤   ¤   ¤   RealizePalette (hDC);
b5438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
960fe0 ¤   ¤   ¤   bReturnCode = TRUE;
590fe4 ¤   ¤   }
e12f68 ¤   ¤   break;
671b52 ¤   ¤
84c93c ¤   case WM_NOTIFY:
dc5b34 ¤   ¤   {
18a08b ¤   ¤   ¤   LPNMHDR pnmh;
a0af5a
0c2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
d1b7b0 ¤   ¤   ¤   switch(pnmh->code)
47f776 ¤   ¤   ¤   {
3e66bc ¤   ¤   ¤   case PSN_SETACTIVE:
1a72c3 ¤   ¤   ¤   ¤   {
f97182 ¤   ¤   ¤   ¤   ¤   // Initialize window
f8bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
79c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
2baf5a
6d9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
--16b1 00059b438fc4011025c Page 2 of Misc.cpp
0f670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
66af5a
08d05a ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_COMMENTS, EM_SETLIMITTEXT,·
7749fd ¤   ¤   ¤   ¤   ¤   ¤   60, 0);
5eaf5a
69c1dd ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowConventionalEncryption)
ca4859 ¤   ¤   ¤   ¤   ¤   {
6524ee ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ALLOW_CONVENTIONAL,·
8994bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
e01c89 ¤   ¤   ¤   ¤   ¤   }
fc4bd6 ¤   ¤   ¤   ¤   ¤   else
664859 ¤   ¤   ¤   ¤   ¤   {
7924ee ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ALLOW_CONVENTIONAL,·
fdd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
811c89 ¤   ¤   ¤   ¤   ¤   }
1eaf5a
c46b3b ¤   ¤   ¤   ¤   ¤   if (pConfig->nCommentLength)
7c4859 ¤   ¤   ¤   ¤   ¤   {
024eb6 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_COMMENTS),·
fe1aea ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szComments);
e41c89 ¤   ¤   ¤   ¤   ¤   }
084bd6 ¤   ¤   ¤   ¤   ¤   else
664859 ¤   ¤   ¤   ¤   ¤   {
a78949 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_COMMENTS), "");
5c1c89 ¤   ¤   ¤   ¤   ¤   }
82af5a
304149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
4e14c3 ¤   ¤   ¤   ¤   ¤   break;
042613 ¤   ¤   ¤   ¤   }
cfaf5a
b0d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
df72c3 ¤   ¤   ¤   ¤   {
a99559 ¤   ¤   ¤   ¤   ¤   if (pConfig->szComments)
cd4859 ¤   ¤   ¤   ¤   ¤   {
09c24b ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(pConfig->szComments);
841448 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szComments = NULL;
731c89 ¤   ¤   ¤   ¤   ¤   }
08af5a
21083d ¤   ¤   ¤   ¤   ¤   pConfig->nCommentLength =·
92b4a0 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowTextLength(GetDlgItem(hwndDlg,·
5906ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_COMMENTS));
01af5a
556b3b ¤   ¤   ¤   ¤   ¤   if (pConfig->nCommentLength)
294859 ¤   ¤   ¤   ¤   ¤   {
c523f8 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szComments = (char *)
1031b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPNewData(pConfig->memoryMgr,
e15ed0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->nCommentLength+1,
08e0c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
6eaf5a
6a7746 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_COMMENTS),
49a9dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szComments, pConfig->nCommentLength+1);
2c6f3f ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szComments[pConfig->nCommentLength] = 0;
a11c89 ¤   ¤   ¤   ¤   ¤   }
04af5a
7914c3 ¤   ¤   ¤   ¤   ¤   break;
0d2613 ¤   ¤   ¤   ¤   }
abaf5a
a36122 ¤   ¤   ¤   case PSN_HELP:
d472c3 ¤   ¤   ¤   ¤   {
2af1f2 ¤   ¤   ¤   ¤   ¤   // Display help
9e14c3 ¤   ¤   ¤   ¤   ¤   break;
512613 ¤   ¤   ¤   ¤   }
99af5a
098f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
7b72c3 ¤   ¤   ¤   ¤   {
626b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
06014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
9214c3 ¤   ¤   ¤   ¤   ¤   break;
892613 ¤   ¤   ¤   ¤   }
dda3a6 ¤   ¤   ¤   }
0087c7 ¤   ¤   ¤
59cdcb ¤   ¤   ¤   break;
--d7a4 001ce166d4c4011025c Page 3 of Misc.cpp
b50fe4 ¤   ¤   }
e6af5a
e23fcf ¤   case WM_COMMAND:
3772a4 ¤   ¤   switch (LOWORD(wParam))
d35b34 ¤   ¤   {
403bba ¤   ¤   case IDC_ALLOW_CONVENTIONAL:
cff776 ¤   ¤   ¤   {
a61ab1 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ALLOW_CONVENTIONAL) ==·
a22a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
4072c3 ¤   ¤   ¤   ¤   {
33d166 ¤   ¤   ¤   ¤   ¤   pConfig->bAllowConventionalEncryption = TRUE;
ef2613 ¤   ¤   ¤   ¤   }
51fa07 ¤   ¤   ¤   ¤   else
dd72c3 ¤   ¤   ¤   ¤   {
8537a2 ¤   ¤   ¤   ¤   ¤   pConfig->bAllowConventionalEncryption = FALSE;
382613 ¤   ¤   ¤   ¤   }
28af5a
55841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
7bf622 ¤   ¤   ¤   ¤   break;
2ba3a6 ¤   ¤   ¤   }
970fe4 ¤   ¤   }
2aaf5a
972f68 ¤   ¤   break;
119371 ¤   }
4daf5a
0c48b1 ¤   return(bReturnCode);
6eefe6 }
61af5a
557e4d /*__Editor_settings____
84af5a
e74126 ¤   Local Variables:
227b17 ¤   tab-width: 4
930e6c ¤   End:
7a5f8c ¤   vi: ts=4 sw=4
3f9e9b ¤   vim: si
ced062 _____________________*/
--2b1d 000c9ac0ca34011025d Page 1 of PGPadmin.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
81662e ¤   $Id: PGPadmin.cpp,v 1.9.8.1 1998/11/12 03:13:11 heller Exp $
fbf7f7 ____________________________________________________________________________*/
aeaf5a
005655 #include <windows.h>
be8031 #include "resource.h"
966867 #include "CreateWiz.h"
29a076 #include "pgpKeys.h"
cf5ab2 #include "PGPcl.h"
b3af5a
7bb380 HINSTANCE g_hInstance = NULL;
b02f33 HWND g_hCurrentDlgWnd = NULL;
f789e5 BOOL g_bGotReloadMsg = FALSE;
ffaf5a
d8604f static UINT g_ReloadKeyringMsg = 0;
41af5a
5b37fd LRESULT CALLBACK MainWndProc(HWND hwnd,·
2b0bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
fdd1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
eaf03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
bdaf5a
acbcce int WINAPI WinMain(
92f2b0 ····HINSTANCE hInstance,¤   // handle to current instance
5be9d2 ····HINSTANCE hPrevInstance,¤   // handle to previous instance
bb145b ····LPSTR lpCmdLine,¤   // pointer to command line
f6c029 ····int nCmdShow ¤  // show state of window
2205d3 ···)
0ebb36 {
54f567 ····MSG msg;·
93e6fc ····WNDCLASS wc;·
95805b ¤   HWND hwndMain;
53e89b ····UNREFERENCED_PARAMETER(lpCmdLine);·
4dd83c ·
59e83d ····g_hInstance = hInstance; ·/* save instance handle */·
6daf5a
da8752 ¤   /* Register "Reload Keyring" message */
aeaf5a
00b145 ¤   g_ReloadKeyringMsg = RegisterWindowMessage(RELOADKEYRINGMSG);
e0af5a
6ade18 ····/* Register the window class for the main window. */·
add83c ·
711338 ····if (!hPrevInstance) {·
faa0d2 ········wc.style = 0;·
74b06e ········wc.lpfnWndProc = (WNDPROC) MainWndProc;·
69af43 ········wc.cbClsExtra = 0;·
f79a59 ········wc.cbWndExtra = 0;·
16c09c ········wc.hInstance = hInstance;·
bd4a3d ········wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ADMIN));·
84d504 ········wc.hCursor = LoadCursor((HINSTANCE) NULL,·
8482fa ············IDC_ARROW);·
adb6ed ········wc.hbrBackground = GetStockObject(WHITE_BRUSH);·
c037f7 ········wc.lpszMenuName = ·MAKEINTRESOURCE(IDR_MENU);·
b501b6 ········wc.lpszClassName = "PGPAdminWizardClass";·
f4d83c ·
861f77 ········if (!RegisterClass(&wc))·
519379 ············return FALSE;·
19b692 ····}·
d4d83c ·
b46288 ····/* Create the main window. */·
f9d83c ·
224ea5 ····hwndMain = CreateWindow("PGPAdminWizardClass", "PGPAdminWizard",·
38189b ········WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,·
7110e0 ········CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL,·
1e12e2 ········(HMENU) NULL, hInstance, (LPVOID) NULL);·
8ad83c ·
f40807 ····/*·
c9dc85 ·····* If the main window cannot be created, terminate·
--2d62 000d6d115804011025d Page 2 of PGPadmin.cpp
7c2815 ·····* the application.·
e47a75 ·····*/·
f3d83c ·
3fdb2c ····if (!hwndMain)·
f569b9 ········return FALSE;·
f6d83c ·
f8a511 ····/* Show the window and paint its contents. */·
acd83c ·
6b3c3f ····ShowWindow(hwndMain, SW_HIDE);·
b070a6 ····UpdateWindow(hwndMain);·
fbd83c ·
5e04b8 ····/* Start the message loop. */·
d8d83c ·
387b2a ····while (GetMessage(&msg, (HWND) NULL, 0, 0))·
ddc7a1 ¤   {
c09e81 ¤   ¤   TranslateMessage(&msg);·
dfe711 ¤   ¤   DispatchMessage(&msg);·
b2b692 ····}·
bfd83c ·
ae9262 ····/* Return the exit code to Windows. */·
d1d83c ·
241934 ····return msg.wParam;·
e6efe6 }
e6af5a
92af5a
2c37fd LRESULT CALLBACK MainWndProc(HWND hwnd,·
4a0bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
ddd1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
cba887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
c1bb36 {
c8375e //¤ SHORT vkHotKey;
cbaf5a
a17cd1 ¤   switch (uMsg)
30c7a1 ¤   {
072e3d ¤   case WM_CREATE:
8d26a6 ¤   ¤   // Send the message to start the wizard as soon as possible
d5c70c ¤   ¤   PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_WIZARD, 0), 0);
77bbde ¤   ¤   return 0;
52af5a
fc3fcf ¤   case WM_COMMAND:
d272a4 ¤   ¤   switch (LOWORD(wParam))
5b5b34 ¤   ¤   {
6c593d ¤   ¤   case IDM_WIZARD:
eccb24 ¤   ¤   ¤   // Launch the wizard. When it ends, close the program
dd86dc ¤   ¤   ¤   // If the keyring reload message was received, restart
7498ad ¤   ¤   ¤   // the wizard
d56da3 ¤   ¤   ¤   do
a2f776 ¤   ¤   ¤   {
5d0a47 ¤   ¤   ¤   ¤   g_bGotReloadMsg = TRUE;
be93c1 ¤   ¤   ¤   ¤   CreateWiz(hwnd);
74a3a6 ¤   ¤   ¤   }
44fd3d ¤   ¤   ¤   while (g_bGotReloadMsg == TRUE);
a3fa9e ¤   ¤   ¤   PostMessage(hwnd, WM_CLOSE, 0, 0);
648144 ¤   ¤   ¤   return 0;
f4af5a
0f78e4 ¤   ¤   case IDM_EXIT:
99fa9e ¤   ¤   ¤   PostMessage(hwnd, WM_CLOSE, 0, 0);
a68144 ¤   ¤   ¤   return 0;
8e0fe4 ¤   ¤   }
2f2f68 ¤   ¤   break;
2caf5a
ff177e ¤   case WM_CLOSE:
de9ad2 ¤   ¤   DestroyWindow(hwnd);
26bbde ¤   ¤   return 0;
edaf5a
c46b08 ¤   case WM_DESTROY:
63eb80 ¤   ¤   PostQuitMessage(0);
8abbde ¤   ¤   return 0;
1aaf5a
012f72 ¤   default:
3be469 ¤   ¤   if (uMsg == g_ReloadKeyringMsg)
d65b34 ¤   ¤   {
--a9af 0018184538b4011025d Page 3 of PGPadmin.cpp
bd1897 ¤   ¤   ¤   if (!g_bGotReloadMsg)
b2f776 ¤   ¤   ¤   {
78f85f ¤   ¤   ¤   ¤   char szMsg[255];
d2abb5 ¤   ¤   ¤   ¤   char szTitle[255];
8f2b85 ¤   ¤   ¤   ¤
d2c4dc ¤   ¤   ¤   ¤   SendMessage(GetParent(g_hCurrentDlgWnd), PSM_SETFINISHTEXT,·
5a9856 ¤   ¤   ¤   ¤   ¤   0, (LPARAM) "Restart");
039c03 ¤   ¤   ¤   ¤   SendMessage(GetParent(g_hCurrentDlgWnd), PSM_SETWIZBUTTONS,·
781a11 ¤   ¤   ¤   ¤   ¤   0, PSWIZB_FINISH);
792b85 ¤   ¤   ¤   ¤
3e0a47 ¤   ¤   ¤   ¤   g_bGotReloadMsg = TRUE;
29f0b3 ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_E_RELOADKEYRING, szMsg, 254);
0b00d6 ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
84cb98 ¤   ¤   ¤   ¤   MessageBox(hwnd, szMsg, szTitle, MB_ICONEXCLAMATION);
29a3a6 ¤   ¤   ¤   }
7e2b85 ¤   ¤   ¤   ¤
d18144 ¤   ¤   ¤   return 0;
650fe4 ¤   ¤   }
7c9371 ¤   }
90af5a
e900bb ¤   return DefWindowProc(hwnd, uMsg, wParam, lParam);
2befe6 }
9baf5a
367e4d /*__Editor_settings____
baaf5a
7f4126 ¤   Local Variables:
397b17 ¤   tab-width: 4
cf0e6c ¤   End:
785f8c ¤   vi: ts=4 sw=4
f69e9b ¤   vim: si
81d062 _____________________*/
--5480 00094c488484011025e Page 1 of PGPadmin.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
06d706 ¤   $Id: PGPadmin.h,v 1.25.8.1 1998/11/12 03:13:11 heller Exp $
12f7f7 ____________________________________________________________________________*/
605c7e #ifndef Included_PGPadmin_h¤/* [ */
eed0e6 #define Included_PGPadmin_h
61af5a
df9d2d extern HINSTANCE g_hInstance;
83c1f2 extern HWND g_hCurrentDlgWnd;
730572 extern BOOL g_bGotReloadMsg;
98af5a
85c5d5 #include "pgpBase.h"
2fa076 #include "pgpKeys.h"
6aaf5a
d39108 // Wizard pages
eeaf5a
9a427a typedef enum _AdminWizPage
aabb36 {
78fb24 ¤   Wiz_Start=0,
cbcd4c ¤   Wiz_License=Wiz_Start,
2849a6 ¤   Wiz_Intro,
8a3015 ¤   Wiz_ADKIntro,
b3fed3 ¤   Wiz_ADKIncoming,
2c6869 ¤   Wiz_ADKInSelect,
135194 ¤   Wiz_ADKOutgoing,
b67ce2 ¤   Wiz_ADKOutSelect,
6a69a1 ¤   Wiz_ADKEnforce,
a3fdb8 ¤   Wiz_ADKDisk,
0bcfb9 ¤   Wiz_ADKDiskSelect,
9dedf8 ¤   Wiz_PassPhrase,
e4f9de ¤   Wiz_CorpKey,
2f7de2 ¤   Wiz_CorpKeySelect,
c3341c ¤   Wiz_Revoker,
7745c4 ¤   Wiz_RevokerSelect,
cbcd1b ¤   Wiz_KeyGen,
796f29 ¤   Wiz_DefaultKeys,
102e2b ¤   Wiz_ServerUpdates,
fc7ad3 ¤   Wiz_Misc,
c81f4b ¤   Wiz_Review,
f3eb90 ¤   Wiz_ClientPrefs,
257404 ¤   Wiz_InstallOptions,
ddc7f6 ¤   Wiz_Finish,
fc3299 ¤   NUM_WIZ_PAGES
d0e445 } AdminWizPage;
05af5a
805dda // Configuration information
32af5a
825196 typedef struct _pgpConfigInfo
63bb36 {
e7a4d6 ¤   HBITMAP¤¤   ¤   ¤   ¤   hBitmap;
e133be ¤   HPALETTE¤   ¤   ¤   ¤   hPalette;
0488c5 ¤   PGPContextRef¤  ¤   ¤   pgpContext;
83b586 ¤   PGPMemoryMgrRef¤¤   ¤   memoryMgr;
18f55a ¤   char *¤ ¤   ¤   ¤   ¤   szLicenseNum;
0678c0 ¤   PGPBoolean¤ ¤   ¤   ¤   bUseOutgoingADK;
44de84 ¤   PGPBoolean¤ ¤   ¤   ¤   bUseIncomingADK;
899d63 ¤   PGPBoolean¤ ¤   ¤   ¤   bUseDiskADK;
6053db ¤   char *¤ ·¤  ¤   ¤   ¤   szOutgoingADKID;
fc89bc ¤   char *¤ ¤   ¤   ¤   ¤   szOutgoingADK;
c5b2e1 ¤   char *¤ ·¤  ¤   ¤   ¤   szIncomingADKID;
202ff8 ¤   char *¤ ¤   ¤   ¤   ¤   szIncomingADK;
163aca ¤   char *¤ ¤   ¤   ¤   ¤   szDiskADKID;
7b6034 ¤   char *¤ ¤   ¤   ¤   ¤   szDiskADK;
157870 ¤   PGPBoolean¤ ¤   ¤   ¤   bEnforceIncomingADK;
f0de34 ¤   PGPBoolean¤ ¤   ¤   ¤   bEnforceOutgoingADK;
0658f4 ¤   PGPBoolean¤ ¤   ¤   ¤   bEnforceRemoteADK;
a5ab96 ¤   PGPBoolean¤ ¤   ¤   ¤   bEnforceMinChars;
9410b8 ¤   PGPUInt32¤  ¤   ¤   ¤   nMinChars;
--fae7 000f041237e4011025e Page 2 of PGPadmin.h
0f66c7 ¤   PGPBoolean¤ ¤   ¤   ¤   bEnforceMinQuality;
a8d4bc ¤   PGPUInt32¤  ¤   ¤   ¤   nMinQuality;
4c8890 ¤   char *¤ ·¤  ¤   ¤   ¤   szCorpKeyID;
a78871 ¤   char *¤ ¤   ¤   ¤   ¤   szCorpKey;
6d1efe ¤   PGPPublicKeyAlgorithm¤  corpKeyType;
148d7d ¤   PGPPublicKeyAlgorithm¤  outgoingADKKeyType;
fb1cc5 ¤   PGPPublicKeyAlgorithm¤  diskADKKeyType;
ca0d47 ¤   PGPBoolean¤ ¤   ¤   ¤   bWarnNotCertByCorp;
b24032 ¤   PGPBoolean¤ ¤   ¤   ¤   bAutoSignTrustCorp;
a831d2 ¤   PGPBoolean¤ ¤   ¤   ¤   bMetaIntroducerCorp;
debb69 ¤   PGPBoolean¤ ¤   ¤   ¤   bAutoAddRevoker;
c8a3d8 ¤   char *¤ ¤   ¤   ¤   ¤   szRevokerKeyID;
d58280 ¤   char *¤ ¤   ¤   ¤   ¤   szRevokerKey;
02cc27 ¤   PGPPublicKeyAlgorithm¤  revokerKeyType;
fada79 ¤   PGPBoolean¤ ¤   ¤   ¤   bAllowKeyGen;
ed037a ¤   PGPBoolean¤ ¤   ¤   ¤   bAllowRSAKeyGen;
fa8b68 ¤   PGPUInt32¤  ¤   ¤   ¤   nMinKeySize;
1dc952 ¤   PGPBoolean¤ ¤   ¤   ¤   bUpdateAllKeys;
06de5c ¤   PGPBoolean¤ ¤   ¤   ¤   bUpdateTrustedIntroducers;
c8c45b ¤   PGPUInt32¤  ¤   ¤   ¤   nDaysUpdateAllKeys;
77c2f5 ¤   PGPUInt32¤  ¤   ¤   ¤   nDaysUpdateTrustedIntroducers;
93f346 ¤   PGPBoolean¤ ¤   ¤   ¤   bAllowConventionalEncryption;
95a3ff ¤   char *¤ ¤   ¤   ¤   ¤   szComments;
430eec ¤   PGPUInt32¤  ¤   ¤   ¤   nCommentLength;
a05767 ¤   PGPKeySetRef¤   ¤   ¤   userKeySet;
8fa6b0 ¤   PGPKeySetRef¤   ¤   ¤   defaultKeySet;
5b38e5 /*
6e9f9e ¤   char *¤ ¤   ¤   ¤   ¤   szKeySetFile;
ed6048 ¤   char *¤ ¤   ¤   ¤   ¤   szPrefFile;
897fe0 */
e45a37 ¤   char *¤ ¤   ¤   ¤   ¤   szInstallDir;
2cbcd0 ¤   PGPBoolean¤ ¤   ¤   ¤   bCopyClientPrefs;
b7c20c ¤   PGPBoolean¤ ¤   ¤   ¤   bPreselectInstall;
18d3a1 ¤   char *¤ ¤   ¤   ¤   ¤   szUserInstallDir;
26c072 ¤   PGPBoolean¤ ¤   ¤   ¤   bInstallPrograms;
79255d ¤   PGPBoolean¤ ¤   ¤   ¤   bInstallDisk;
0dddd2 ¤   PGPBoolean¤ ¤   ¤   ¤   bInstallEudora;
284d73 ¤   PGPBoolean¤ ¤   ¤   ¤   bInstallOutlook;
877534 ¤   PGPBoolean¤ ¤   ¤   ¤   bInstallOutExpress;
ede224 ¤   PGPBoolean¤ ¤   ¤   ¤   bInstallManual;
571cb9 ¤   PGPBoolean¤ ¤   ¤   ¤   bUninstallOld;
f38fc2 ¤   PGPBoolean¤ ¤   ¤   ¤   bSave;
ab7ebb } pgpConfigInfo;
c4af5a
01e49e // Global variables
1faf5a
f67199 extern HWND g_hInstance;
04af5a
f1879a // Wizard page dialog procedures
8daf5a
6a67e5 BOOL CALLBACK LicenseDlgProc(HWND hwndDlg,·
579adf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,
1fd1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
7df03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
03af5a
f7cc5e BOOL CALLBACK IntroDlgProc(HWND hwndDlg,·
98e56f ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,
b967e2 ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
444607 ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
afaf5a
80abcf BOOL CALLBACK ADKIntroDlgProc(HWND hwndDlg,
b312b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,
201993 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,
95a2a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
7caf5a
3b6231 BOOL CALLBACK ADKIncomingDlgProc(HWND hwndDlg,
f40d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
698347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
6ea2a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
22af5a
8487f4 BOOL CALLBACK ADKInSelectDlgProc(HWND hwndDlg,·
f00d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
--6d87 000e7f03fa64011025e Page 3 of PGPadmin.h
428347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
12a2a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
1caf5a
f40a6c BOOL CALLBACK ADKOutgoingDlgProc(HWND hwndDlg,·
d8baeb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
1c40d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
6a6137 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
75af5a
bc8cf9 BOOL CALLBACK ADKOutSelectDlgProc(HWND hwndDlg,·
dd5f89 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
c1d05c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
5cf1b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
c0af5a
088c88 BOOL CALLBACK ADKEnforceDlgProc(HWND hwndDlg,
3fe044 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,
c9dcbb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,
670f2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
6baf5a
528a81 BOOL CALLBACK ADKDiskDlgProc(HWND hwndDlg,·
200bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
c2d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
31f03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
5eaf5a
1953d3 BOOL CALLBACK ADKDiskSelectDlgProc(HWND hwndDlg,·
84218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
7b2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
a30f2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
a9af5a
96dc74 BOOL CALLBACK PassPhraseDlgProc(HWND hwndDlg,·
cea2bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
1ad693 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
32f776 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
75af5a
5932b9 BOOL CALLBACK CorpKeyDlgProc(HWND hwndDlg,·
de0bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
8ed1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
6bf03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
aeaf5a
08b1ff BOOL CALLBACK CorpKeySelectDlgProc(HWND hwndDlg,·
1d218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
7a2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
860f2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
70af5a
a65b86 BOOL CALLBACK RevokerDlgProc(HWND hwndDlg,·
840bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
3ed1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
91f03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
89af5a
debb71 BOOL CALLBACK RevokerSelectDlgProc(HWND hwndDlg,·
60218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
412ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
b90f2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
72af5a
bc094a BOOL CALLBACK KeyGenDlgProc(HWND hwndDlg,·
752add ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
24cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
f3ef26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
85af5a
1938a9 BOOL CALLBACK DefaultKeysDlgProc(HWND hwndDlg,·
a90d14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
c38347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
11a2a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
54af5a
bb7b14 BOOL CALLBACK ServerUpdatesDlgProc(HWND hwndDlg,·
65218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
792ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
4c0f2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam);
19af5a
cd5768 BOOL CALLBACK MiscDlgProc(HWND hwndDlg,·
79556d ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
c06540 ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
e744a5 ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
--972c 0010bba6f534011025e Page 4 of PGPadmin.h
e0af5a
f2541e BOOL CALLBACK ReviewDlgProc(HWND hwndDlg,·
46e9ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,
dbcec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
38ef26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
63af5a
54c8cd BOOL CALLBACK ClientPrefsDlgProc(HWND hwndDlg,·
e912b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,
128347 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
9ca2a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
e7af5a
9b44e0 BOOL CALLBACK InstallOptionsDlgProc(HWND hwndDlg,·
47baeb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
ff40d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
6e6137 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
43af5a
8f2d1c BOOL CALLBACK FinishDlgProc(HWND hwndDlg,·
272add ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
c2cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
d9ef26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
6eaf5a
eeb029 #endif /* ] Included_PGPadmin_h */
98af5a
58af5a
677e4d /*__Editor_settings____
37af5a
774126 ¤   Local Variables:
0b7b17 ¤   tab-width: 4
af0e6c ¤   End:
7a5f8c ¤   vi: ts=4 sw=4
cd9e9b ¤   vim: si
0bd062 _____________________*/
--2486 000fb08c6244011025f Page 1 of PGPadmin.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
69e19b // $Id: PGPadmin.rc,v 1.50 1998/07/30 15:55:10 dgal Exp $
f4af5a
a36c0e /////////////////////////////////////////////////////////////////////////////
f27b93 #undef APSTUDIO_READONLY_SYMBOLS
d6af5a
176c0e /////////////////////////////////////////////////////////////////////////////
a3f930 // English (U.S.) resources
e3af5a
251201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
c4ec08 #ifdef _WIN32
83e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
339c1c #pragma code_page(1252)
081f8e #endif //_WIN32
a0af5a
836c0e /////////////////////////////////////////////////////////////////////////////
88465d //
12b090 // Dialog
e0465d //
8aaf5a
6e4d23 IDD_INTRO DIALOG DISCARDABLE ·0, 0, 350, 222
916b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
a95aed CAPTION "PGPadmin - Introduction"
93309f FONT 8, "MS Sans Serif"
3a4523 BEGIN
ea9dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
36d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
ed20f6 ····LTEXT ··········"This Administration Wizard will help you set up the config¶
0245ee uration that will be used for all installations of PGP within your organization¶
14b25b .",
27e3c6 ····················IDC_STATIC,99,9,240,19
8b86b1 ····LTEXT ··········"Each step will explain about a feature and allow you to de¶
a368e8 termine the appropriate choice for your users.",
70ecd9 ····················IDC_STATIC,100,32,240,17
d8b031 ····LTEXT ··········"Once you have completed all steps, the choices you have ma¶
e62505 de will be saved into a format that the PGP installer will use when installing ¶
d97847 PGP Desktop Security on users' workstations.",
79a89e ····················IDC_STATIC,100,53,240,31
9784f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
cc37c1 ····················SS_SUNKEN,7,9,81,161
22e0d1 END
f0af5a
c9f2b4 IDD_ADK DIALOG DISCARDABLE ·0, 0, 350, 222
6c6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
f6aab5 CAPTION "PGPadmin - Additional Decryption Key"
b3309f FONT 8, "MS Sans Serif"
504523 BEGIN
5584f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
b637c1 ····················SS_SUNKEN,7,9,81,161
839dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
7ad675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
3fd33b ····LTEXT ··········"An Additional Decryption Key (ADK) is a powerful tool that¶
b48cc2 ·allows an organization to decrypt messages that are encrypted to someone withi¶
23b2b8 n the organization. This is accomplished by noting an ADK within the user's pub¶
6cb3e0 lic key.",
e2f08e ····················IDC_STATIC,99,9,242,34
73f826 ····LTEXT ··········"An ADK can pose a serious security threat. If the ADK is e¶
6423b6 ver compromised, all encrypted messages sent to users with this feature enabled¶
10d908 ·will be decryptable by the attacker.",
40c8bd ····················IDC_STATIC,99,75,242,26
9cd371 ····LTEXT ··········"With this association, any message encrypted to the user's¶
fbe280 ·public key will also be encrypted to the ADK. This allows the owner of the ADK¶
--40b6 0007076de634011025f Page 2 of PGPadmin.rc
6bd7af ·to decrypt any message sent to the user.",
fd40bb ····················IDC_STATIC,99,46,242,25
3b5925 ····LTEXT ··········"In light of this security threat, take great care when dec¶
d619d8 iding whether to use an ADK. If used, the ADK must be secured both physically a¶
3c4d9a nd electronically in order to prevent a security breach.",
c276c6 ····················IDC_STATIC,99,106,242,25
419865 ····LTEXT ··········"It is a good idea in large organizations to have multiple ¶
ed4bfb Additional Decryption Keys, possibly spread out by department.",
e55db3 ····················IDC_STATIC,99,136,242,18
91e0d1 END
11af5a
3be6d7 IDD_PASSPHRASE DIALOG DISCARDABLE ·0, 0, 350, 222
bc6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
3041d2 CAPTION "PGPadmin - Passphrase Length and Quality"
b1309f FONT 8, "MS Sans Serif"
8a4523 BEGIN
f484f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
4237c1 ····················SS_SUNKEN,7,9,81,161
689dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
19d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
187fa4 ····CONTROL ········"Enforce minimum number of &characters",
1fdfd5 ····················IDC_ENFORCE_MINCHARS,"Button",BS_AUTOCHECKBOX |·
ba91b2 ····················WS_TABSTOP,99,44,163,11
2fe177 ····EDITTEXT ·······IDC_MINCHARS,219,56,18,12,ES_AUTOHSCROLL
e16810 ····LTEXT ··········"The passphrase must be at least",IDC_PASSLABEL1,111,58,
aa722d ····················107,10
843bfb ····LTEXT ··········"characters long",IDC_PASSLABEL2,239,58,52,10
7c08f9 ····CONTROL ········"Enforce minimum amount of &quality",
fc73a7 ····················IDC_ENFORCE_MINQUALITY,"Button",BS_AUTOCHECKBOX |·
a0df90 ····················WS_TABSTOP,99,146,163,11
6abb2b ····EDITTEXT ·······IDC_MINQUALITY,189,157,18,12,ES_AUTOHSCROLL
0a266f ····LTEXT ··········"Quality must be at least",IDC_QUALLABEL1,111,159,77,10
1d81e6 ····LTEXT ··········"out of 100",IDC_QUALLABEL2,211,159,52,10
d1aa47 ····LTEXT ··········"To make PGP more secure, it is helpful to minimize the sec¶
01529d urity risks associated with a user's passphrase. Longer passphrases are general¶
9f47de ly harder to break. You have the option of forcing users to use a minimum passp¶
023644 hrase length.",
e6ab0e ····················IDC_STATIC,99,9,240,33
b85b15 ····LTEXT ··········"Some passphrases are better than others. This is a measure¶
09e9fd ·of the quality of a given passphrase. The passphrase is potentially the weakes¶
38f012 t link of PGP security, so it is important for users to have high-quality passp¶
673105 hrases in order to make PGP effective.",
2ed6a9 ····················IDC_STATIC,99,74,237,34
76fc64 ····LTEXT ··········"When the user creates a key or changes their passphrase on¶
c36308 ·a key, a quality bar will show the quality of the new passphrase. The quality ¶
d56a6f of a passphrase is usually higher when there is a mixture of lower- and upper-c¶
993c30 ase letters, numbers, and punctuation.",
86e0af ····················IDC_STATIC,99,109,233,32
f4e0d1 END
efaf5a
a268cf IDD_CORPKEY DIALOG DISCARDABLE ·0, 0, 350, 222
606b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
f0a79a CAPTION "PGPadmin - Corporate Signing Key"
58309f FONT 8, "MS Sans Serif"
d14523 BEGIN
4c9dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
10d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
6e2c1b ····LTEXT ··········"A Corporate Signing Key (CSK) is a system-wide public key ¶
787bf5 that establishes the validity of other keys in your organization. Key generatio¶
f0ddfb n by users can be configured to automatically sign the CSK making it valid and ¶
9cef63 trusted so that any",
f9b38a ····················IDC_STATIC,99,9,242,25
37a8a5 ····CONTROL ········"&Automatically sign Corporate Key",IDC_AUTOSIGNTRUST,
aaaf4a ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,141,244,9
ed031e ····CONTROL ········"&Warn if encrypting to keys not signed by Corporate Key",
cef800 ····················IDC_WARN_NOTCERT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
5bb2d7 ····················111,165,203,9
0236e8 ····LTEXT ··········"You can also display a warning to the user when encrypting¶
e4aaed ·to a key not signed by the CSK. This is generally made obvious regardless from¶
977027 ·the PGP interface, but can be useful in high security situations.",
770f26 ····················IDC_STATIC,99,89,242,25
70457f ····LTEXT ··········"If you select the first option below, you will be prompted¶
--8dbd 00068221fad4011025f Page 3 of PGPadmin.rc
054339 ·to select the CSK on the next page. Otherwise, the CSK selection page will be ¶
265761 skipped.",
814800 ····················IDC_STATIC,99,117,242,18
4084f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
e137c1 ····················SS_SUNKEN,7,9,81,161
9399f4 ····LTEXT ··········"The signature made by the user on the CSK can optionally d¶
e5296d esignate the CSK as a Meta-Introducer. This means that keys designated by the C¶
d35460 SK as Trusted Introducers would be automatically trusted as introducers by the ¶
27842c user.",
b24458 ····················IDC_STATIC,99,53,242,35
c13326 ····LTEXT ··········"any other keys signed by the CSK will be considered valid ¶
2432c6 by the user's installation of PGP.",
b9420f ····················IDC_STATIC,99,33,239,15
a49175 ····CONTROL ········"Designate Corporate Key as a &Meta-Introducer",
49f462 ····················IDC_METAINTRODUCER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
5b7961 ····················111,153,203,9
0de0d1 END
adaf5a
37df9f IDD_MISC DIALOG DISCARDABLE ·0, 0, 350, 222
a36b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
87fc95 CAPTION "PGPadmin - Miscellaneous options"
6e309f FONT 8, "MS Sans Serif"
5f4523 BEGIN
6a84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
4537c1 ····················SS_SUNKEN,7,9,81,161
529dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
54d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
c6be78 ····LTEXT ··········"Conventional encryption is simply the encrypting of a mess¶
7a7759 age or document using a passphrase entered at the time of encryption. This form¶
a85a90 ·of encryption does not use public keys. It relies solely on the passphrase to ¶
80e0f8 encrypt the data.",
88ab0e ····················IDC_STATIC,99,9,240,33
e7e9df ····CONTROL ········"Allow &conventional encryption",IDC_ALLOW_CONVENTIONAL,
a07dad ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,73,131,10
567ceb ····LTEXT ··········"In any PGP message, there is a line reserved for custom co¶
3b2e0e mments. You may optionally specify a specific line of text to be used in the co¶
8aff88 mment line. This will not affect the processing of encrypted or signed messages¶
fe5531 ·in any way.",
63e4c4 ····················IDC_STATIC,98,100,242,27
c8e011 ····LTEXT ··········"Message Header Comment:",IDC_STATIC,98,160,120,9
d4d5a6 ····EDITTEXT ·······IDC_COMMENTS,98,170,241,14,ES_AUTOHSCROLL
c5095b ····LTEXT ··········"Unlike the normal usage of PGP, this allows anyone who kno¶
12f9ac ws (or can guess) the passphrase to decrypt the information. Care should be tak¶
11fca4 en in deciding whether or not to allow Conventional Encryption.",
e76469 ····················IDC_STATIC,99,44,240,29
e4946e ····LTEXT ··········"Typical uses for the comment line include such examples as¶
e88830 ·the company/organization name, WWW home page URL, or disclaimer notices. If yo¶
243dbe u do not wish to have a comment line, leave the field below blank.",
10bd0d ····················IDC_STATIC,98,129,242,25
cfe0d1 END
28af5a
963fdc IDD_ADK_INCOMING DIALOG DISCARDABLE ·0, 0, 350, 222
d06b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
5ea502 CAPTION "PGPadmin - Incoming Additional Decryption Key"
82309f FONT 8, "MS Sans Serif"
314523 BEGIN
2f84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
4837c1 ····················SS_SUNKEN,7,9,81,161
189dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
1cd675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
fe279f ····CONTROL ········"Use an &Incoming Additional Decryption Key",
e3fec8 ····················IDC_USE_INADK,"Button",BS_AUTOCHECKBOX | BS_NOTIFY |·
20ec66 ····················WS_TABSTOP,99,131,152,10
6ebb2e ····LTEXT ··········"For Diffie-Hellman keys, the Incoming Additonal Decryption¶
afd5e4 ·Key feature works by designating an Additional Decryption Key inside each user¶
093c8a 's public key. This means that the ADK request will travel with the user's publ¶
9d214e ic key to ",
9f781f ····················IDC_STATIC,99,10,242,25
7997f0 ····LTEXT ··········"When someone inside or outside the organization encrypts a¶
222558 ·message to the user, the associated ADK will be added to the sender's list of ¶
a66a30 recipients automatically - at which time the sender is by default warned that t¶
681f11 his is taking place.",
--b883 000459f902f4011025f Page 4 of PGPadmin.rc
2903bf ····················IDC_STATIC,99,46,242,34
f381b0 ····LTEXT ··········"Note that only a Diffie-Hellman key can be used as the Inc¶
fb9f37 oming ADK.",
f77aca ····················IDC_STATIC,99,83,242,10
c65f79 ····LTEXT ··········"If you choose to use an Incoming ADK, this key must alread¶
986ee6 y be on your keyring before going to the next page. If it is not, generate the ¶
ccab5c key you intend to use for Incoming ADK, then press the Next button.",
cdf8d4 ····················IDC_STATIC,99,97,242,25
afd39e ····LTEXT ··········"anyone inside or outside the organization.",IDC_STATIC,
b254b1 ····················99,34,219,8
f3e0d1 END
feaf5a
bb55f6 IDD_ADK_INSEL DIALOG DISCARDABLE ·0, 0, 350, 222
946b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
e17091 CAPTION "PGPadmin - Incoming Additional Decryption Key selection"
3f309f FONT 8, "MS Sans Serif"
f84523 BEGIN
7d84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
6b37c1 ····················SS_SUNKEN,7,9,81,161
9d9dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
bad675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
d76c70 ····LTEXT ··········"The following list shows all Diffie-Hellman keys on your k¶
0d3c71 eyring. Please choose the key you wish to use as the Incoming Additional Decryp¶
8fe394 tion Key:",
178601 ····················IDC_STATIC,97,13,240,27
d26942 ····CONTROL ········"List1",IDC_INADK_ID,"SysListView32",LVS_REPORT |·
e73ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
2dd53a ····················WS_TABSTOP,97,45,240,142
7be0d1 END
c5af5a
c0f991 IDD_ADK_OUTGOING DIALOG DISCARDABLE ·0, 0, 350, 222
d86b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
878cf9 CAPTION "PGPadmin - Outgoing Additional Decryption Key"
8f309f FONT 8, "MS Sans Serif"
ad4523 BEGIN
0a84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
d937c1 ····················SS_SUNKEN,7,9,81,161
9a9dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
31d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
206eea ····CONTROL ········"Use an &Outgoing Additional Decryption Key",
9341a7 ····················IDC_USE_OUTADK,"Button",BS_AUTOCHECKBOX | BS_NOTIFY |·
311951 ····················WS_TABSTOP,100,140,186,10
6b303c ····LTEXT ··········"While a Diffie-Hellman key enables an Incoming ADK feature¶
f4d29c , another option is to have an Outgoing Additional Decryption Key.",
362703 ····················IDC_STATIC,99,10,242,18
0aaa83 ····LTEXT ··········"When someone inside the organization encrypts a message to¶
8cd2d4 ·the user, the message will also be encrypted to the Outgoing ADK. However, enc¶
9555d6 rypted messages from someone outside the organization to an internal user will ¶
e01f5c not be encrypted to the Outgoing ADK.",
042ea8 ····················IDC_STATIC,99,31,242,34
272c37 ····LTEXT ··········"This feature works with all key types on all encryptions. ¶
99c7d4 When used in combination with Incoming ADK, these two features provide an ADK f¶
b8bc50 or all incoming and outgoing messages. All keys must be Diffie-Hellman keys to ¶
a3d873 combine these features.",
05cd2c ····················IDC_STATIC,99,68,242,33
027682 ····LTEXT ··········"If you choose to use an Outgoing ADK, this key must alread¶
166ee6 y be on your keyring before going to the next page. If it is not, generate the ¶
0c6d11 key you intend to use for Outgoing ADK, then press the Next button.",
64a0c1 ····················IDC_STATIC,99,105,242,25
b4e0d1 END
32af5a
6e5733 IDD_ADK_OUTSEL DIALOG DISCARDABLE ·0, 0, 350, 222
fd6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
ea25b5 CAPTION "PGPadmin - Outgoing Additional Decryption Key selection"
67309f FONT 8, "MS Sans Serif"
704523 BEGIN
5e84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
9537c1 ····················SS_SUNKEN,7,9,81,161
339dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
84d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
d52529 ····LTEXT ··········"The following list shows all keys on your keyring. Please ¶
450e94 choose the key you wish to use as the Outgoing Additional Decryption Key:",
--dfe4 0006cc1e8374011025f Page 5 of PGPadmin.rc
6765ae ····················IDC_STATIC,99,11,240,19
afaeb2 ····CONTROL ········"List1",IDC_OUTADK_ID,"SysListView32",LVS_REPORT |·
fa3ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
9bb0c8 ····················WS_TABSTOP,99,38,240,142
37e0d1 END
97af5a
0b5d8e IDD_CORPKEYSEL DIALOG DISCARDABLE ·0, 0, 350, 222
986b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
0ef2e6 CAPTION "PGPadmin - Corporate Signing Key selection"
9c309f FONT 8, "MS Sans Serif"
3e4523 BEGIN
4e84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
e637c1 ····················SS_SUNKEN,7,9,81,161
4d9dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
04d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
852529 ····LTEXT ··········"The following list shows all keys on your keyring. Please ¶
861062 choose the key you wish to use for the Corporate Signing Key:",
bd65ae ····················IDC_STATIC,99,11,240,19
6fb6fc ····CONTROL ········"List1",IDC_CORPKEY_ID,"SysListView32",LVS_REPORT |·
ff3ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
15b0c8 ····················WS_TABSTOP,99,38,240,142
3ce0d1 END
edaf5a
01d000 IDD_KEYGEN DIALOG DISCARDABLE ·0, 0, 350, 222
966b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
eeaef1 CAPTION "PGPadmin - Key Generation"
1f309f FONT 8, "MS Sans Serif"
744523 BEGIN
1484f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
f137c1 ····················SS_SUNKEN,7,9,81,161
309dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
71d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
fd155e ····LTEXT ··········"Normally, PGP users generate their own keys. This allows e¶
fea3f9 ach user to choose their own passphrase and be responsible for their own keys.",
4fe3c6 ····················IDC_STATIC,99,9,240,19
93957a ····CONTROL ········"Allow key &generation",IDC_ALLOW_KEYGEN,"Button",
34c631 ····················BS_AUTOCHECKBOX | WS_TABSTOP,100,106,87,10
65357b ····LTEXT ··········"You may optionally choose to disable key generation for us¶
535228 ers. This means that a Security Officer within your organization will be respon¶
7d50b2 sible for generating all users' keys and handing them out. In a large organizat¶
2a14a2 ion,",
d16534 ····················IDC_STATIC,99,28,240,25
cb740c ····LTEXT ··········"Disabling key generation is strongly discouraged because i¶
3919ac t can introduce massive security holes. This feature should only be used if all¶
8a8ec9 ·the threats and implications of doing this have been carefully considered.",
0f63f2 ····················IDC_STATIC,99,73,240,27
d638c2 ····CONTROL ········"Allow &RSA key generation",IDC_ALLOW_RSAKEYGEN,"Button",
0dfa57 ····················BS_AUTOCHECKBOX | WS_TABSTOP,112,120,106,10
98a21a ····LTEXT ··········"this sort of operation could take a long time to complete ¶
098a8d and requires extensive processes to ensure security of the key.",
75a3a0 ····················IDC_STATIC,99,52,235,17
13ea98 ····LTEXT ··········"New keys must be at least",IDC_KEYSIZE_LABEL,112,135,87,
8eff3f ····················9
9e9a62 ····EDITTEXT ·······IDC_MINKEYSIZE,199,133,24,12,ES_AUTOHSCROLL
e5de22 ····LTEXT ··········"bits long",IDC_KEYSIZE_LABEL2,228,135,31,9
1ee0d1 END
1aaf5a
4e11cc IDD_DEFKEYSEL DIALOG DISCARDABLE ·0, 0, 350, 222
936b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
c7e3a5 CAPTION "PGPadmin - Default Keys selection"
14309f FONT 8, "MS Sans Serif"
a74523 BEGIN
2684f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
c737c1 ····················SS_SUNKEN,7,9,81,161
5e9dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
b8d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
919614 ····LTEXT ··········"The following list shows all keys on your keyring. You may¶
a1beab ·choose one or more keys to appear on all users' keyrings when they install PGP¶
c9c863 . If you selected a Corporate Key or any Additional Decryption Keys in the prev¶
f42398 ious steps, you must select them here.",
2634be ····················IDC_STATIC,99,11,240,32
6c018c ····CONTROL ········"List1",IDC_DEFKEY_ID,"SysListView32",LVS_REPORT |·
--9220 000a735dfa94011025f Page 6 of PGPadmin.rc
56c303 ····················LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,99,47,240,133
e9e0d1 END
abaf5a
cacff0 IDD_FINISH DIALOG DISCARDABLE ·0, 0, 350, 222
966b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
280d46 CAPTION "PGPadmin - Create Non-Admin PGP Installer"
87309f FONT 8, "MS Sans Serif"
9f4523 BEGIN
7c84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
a037c1 ····················SS_SUNKEN,7,9,81,161
789dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
74d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
8fb383 ····LTEXT ··········"You have completed all the steps in administrating the ins¶
19111a tallation of PGP. The options that you have chosen will be saved in a file and ¶
ad2fc0 distributed in the Non-Admin installation of PGP.",
77513a ····················IDC_STATIC,99,15,239,25
84b992 ····LTEXT ··········"To provide the Non-Admin version of PGP for your users, yo¶
ef62fe u must specify where to create the Non-Admin PGP installation program.",
925422 ····················IDC_STATIC,99,43,239,31
a00350 ····LTEXT ··········"Create Non-Admin installer in this directory:",
528cd0 ····················IDC_STATIC,99,79,192,8
1bf35f ····PUSHBUTTON ·····"&Browse...",IDC_BROWSE,275,88,65,13
bd73c3 ····EDITTEXT ·······IDC_INSTALLDIR,99,88,166,13,ES_AUTOHSCROLL
4ae0d1 END
46af5a
2124e0 IDD_ADK_ENFORCE DIALOG DISCARDABLE ·0, 0, 350, 222
ed6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
cbb40b CAPTION "PGPadmin - Additional Decryption Key enforcement"
68309f FONT 8, "MS Sans Serif"
274523 BEGIN
5284f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
7037c1 ····················SS_SUNKEN,7,9,81,161
a5a07a ····LTEXT ··········"If you have enabled an Additional Decryption Key within yo¶
ccada2 ur organization, it will cause the ADK to appear in the recipient list when (1)¶
df338a ·someone encrypts data to a user within your organization, and/or (2) an intern¶
eb58f3 al user encrypts ",
c4781f ····················IDC_STATIC,99,10,242,25
f2cfd1 ····LTEXT ··········"As with any key in the recipient list, the ADK(s) can be r¶
3b6e1b emoved from the list by the user before encrypting the data. If a mischievous u¶
048951 ser chooses to do this, you will not be able to decrypt the data using the asso¶
59e5c1 ciated ADK.",
0df766 ····················IDC_STATIC,99,54,242,25
1c8202 ····LTEXT ··········"If you wish to prevent users from removing the ADK(s) from¶
109498 ·the recipient list, you must select the option of enforcing ADK below.",
3d37c2 ····················IDC_STATIC,99,83,242,17
12c9cc ····CONTROL ········"Enforce &Incoming Additional Decryption Key",
a4db2b ····················IDC_ENFORCE_INADK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
2afc10 ····················99,167,219,11
f7c75a ····LTEXT ··········"data. This is dependent on whether you have enabled Incomi¶
2fa70f ng or Outgoing ADK or both.",
d0c360 ····················IDC_STATIC,99,34,242,17
cd80b9 ····CONTROL ········"Enforce &Outgoing Additional Decryption Key",
3ca74b ····················IDC_ENFORCE_OUTADK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
fd8590 ····················99,178,165,11
3e426e ····CONTROL ········"Enforce &remote Additional Decryption Key strictness",
f014f0 ····················IDC_ENFORCE_REMOTEADK,"Button",BS_AUTOCHECKBOX |·
862099 ····················WS_TABSTOP,99,189,203,11
7361c6 ····LTEXT ··········"You should also decide whether or not to enforce the ADK p¶
a4df92 olicies of outside organizations. When an internal user encrypts to a user in a¶
d237b2 nother organization whose key was generated with Enforced ADK, you have the",
a6ed3c ····················IDC_STATIC,99,104,242,25
4e8619 ····LTEXT ··········"option of either forcing your users to respect the enforce¶
e60a40 ment requested by outside organizations or allowing your users to remove any AD¶
525310 K(s) associated with that key from the recipient list. The enforcement features¶
5bb45a ·are designed",
d8f55d ····················IDC_STATIC,99,128,242,25
243566 ····LTEXT ··········"as helpful guides for the users, and are not foolproof.",
372035 ····················IDC_STATIC,99,152,242,9
7ae0d1 END
60af5a
95e80b IDD_CLIENTPREFS DIALOG DISCARDABLE ·0, 0, 350, 222
a76b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
--96b8 0003d2863ff4011025f Page 7 of PGPadmin.rc
bd2151 CAPTION "PGPadmin - User Preferences"
41309f FONT 8, "MS Sans Serif"
0f4523 BEGIN
a49dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
32d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
aaf249 ····LTEXT ··········"Client preferences such as using the passphrase cache and ¶
8c9e32 which keyservers to use are usually set by each user. However, it may be helpfu¶
a66314 l to have certain defaults preset for a large group of users within your organi¶
5bf12f zation.",
1dffde ····················IDC_STATIC,99,9,240,35
f884f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
8c37c1 ····················SS_SUNKEN,7,9,81,161
66f232 ····LTEXT ··········"You may choose to add a copy of your current client prefer¶
b0f82e ences to the installer. All users installing PGP with this installer will start¶
fb97e6 ·with these client preferences as their default.",
9eabb6 ····················IDC_STATIC,99,47,240,28
cddabf ····CONTROL ········"&Copy client preferences to installer",IDC_USECURRENT,
142b03 ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,82,200,11
4ce0d1 END
a3af5a
26a7b0 IDD_COPYPROGRESS DIALOG DISCARDABLE ·0, 0, 186, 71
1b5b1a STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
31dcf0 CAPTION "PGP Administration Wizard"
88309f FONT 8, "MS Sans Serif"
f04523 BEGIN
05cb20 ····CONTROL ········"Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,
1202b8 ····················53,172,12
b6995f ····CTEXT ··········"Creating PGP Installer...",IDC_STATIC,7,7,172,9
dc141d ····CONTROL ········"c:\\file",IDC_FILENAME,"Static",SS_LEFTNOWORDWRAP |·
876952 ····················SS_CENTERIMAGE | SS_SUNKEN | WS_BORDER | WS_GROUP,7,30,
cc7b18 ····················172,12
58e0d1 END
98af5a
246b6b IDD_FINDINSTALLER DIALOG DISCARDABLE ·0, 0, 217, 79
82e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
c0dcf0 CAPTION "PGP Administration Wizard"
c6309f FONT 8, "MS Sans Serif"
524523 BEGIN
ee7d8f ····DEFPUSHBUTTON ··"OK",IDOK,104,58,50,14
faa07a ····PUSHBUTTON ·····"Cancel",IDCANCEL,160,58,50,14
fdf36a ····LTEXT ··········"Please locate the directory containing the files necessary¶
e2911e ·to create the Non-Admin PGP installer:",
c684c7 ····················IDC_STATIC,7,7,203,18
bc633e ····EDITTEXT ·······IDC_CLIENTINSTALL,7,28,146,14,ES_AUTOHSCROLL
2ff028 ····PUSHBUTTON ·····"&Browse...",IDC_BROWSE,160,28,50,14
8de0d1 END
58af5a
28221b IDD_REVIEW DIALOG DISCARDABLE ·0, 0, 350, 222
006b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
a51dea CAPTION "PGPadmin - Review of options selected"
c4309f FONT 8, "MS Sans Serif"
9c4523 BEGIN
5284f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
1d37c1 ····················SS_SUNKEN,7,9,81,161
0c83dd ····LTEXT ··········"These are the options you have set. To change them, use th¶
426055 e Back button.",
c87937 ····················IDC_STATIC,100,6,244,11
02114a ····LTEXT ··········"ADK: Addtional Decryption Key\n\nCSK: Corporate Signing Ke¶
fe306c y",
3697b8 ····················IDC_STATIC,7,176,81,42,SS_SUNKEN
528ca6 ····EDITTEXT ·······IDC_PANEL,100,25,244,192,ES_MULTILINE | ES_READONLY |·
8a1086 ····················WS_VSCROLL | NOT WS_TABSTOP
2de0d1 END
a8af5a
a6bd50 IDD_LICENSE DIALOG DISCARDABLE ·0, 0, 350, 222
986b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
00e95b CAPTION "PGPadmin - Company Name"
e9309f FONT 8, "MS Sans Serif"
554523 BEGIN
c19dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
45d047 ····················-1,92,0,254,189,NOT WS_VISIBLE
3dc9a7 ····LTEXT ··········"Please enter the name of your company in the field below:",
--b3fc 0002ebcad274011025f Page 8 of PGPadmin.rc
7870a3 ····················-1,99,52,240,10
7384f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
e037c1 ····················SS_SUNKEN,7,9,81,161
094615 ····EDITTEXT ·······IDC_LICENSENUM,99,63,240,12,ES_AUTOHSCROLL
5ee0d1 END
2eaf5a
fc413e IDD_SERVERUPDATES DIALOG DISCARDABLE ·0, 0, 350, 222
b76b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
acf481 CAPTION "PGPadmin - Server Updates"
db309f FONT 8, "MS Sans Serif"
d84523 BEGIN
213d8e ····CONTROL ········"Automatically update &all keys every",IDC_UPDATEALL,
c4d866 ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,83,124,13
93fe98 ····EDITTEXT ·······IDC_ALLDAYS,226,83,29,13,ES_AUTOHSCROLL
3e2a2c ····CONTROL ········"Spin1",IDC_ALLSPIN,"msctls_updown32",UDS_SETBUDDYINT |·
86808f ····················UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |·
753c03 ····················UDS_NOTHOUSANDS,256,83,9,13
7a5e65 ····CONTROL ········"Automatically update all &Trusted Introducers every",
7b99f1 ····················IDC_UPDATETRUSTED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
022b18 ····················99,98,170,14
9118ad ····EDITTEXT ·······IDC_TRUSTEDDAYS,271,98,29,13,ES_AUTOHSCROLL
b5536a ····CONTROL ········"Spin1",IDC_TRUSTEDSPIN,"msctls_updown32",
184d6b ····················UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |·
0b2358 ····················UDS_ARROWKEYS | UDS_NOTHOUSANDS,301,98,9,13
ab84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
b637c1 ····················SS_SUNKEN,7,9,81,161
699dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
f5d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
f7e600 ····LTEXT ··········"Keys can change over time. Their owners may add or delete ¶
7a0c3f user IDs, and signatures may be added or revoked. The keys themselves may be re¶
de6b05 voked if compromised. To avoid outdated keys, you can choose to have automatic ¶
ae7d8e updates scheduled for your users.",
7bab0e ····················IDC_STATIC,99,9,240,33
ee94a6 ····LTEXT ··········"There are two types of updates you can schedule. Updating ¶
d0e48b Trusted Introducers will fetch the latest copies of the Trusted Introducers' ke¶
12a0e8 ys, plus any keys that they have signed. Updating all keys will simply get the ¶
cd7795 latest copy of each key on the keyring.",
718e38 ····················IDC_STATIC,99,45,240,33
a71a8e ····LTEXT ··········"days",IDC_STATIC,268,85,20,9
3bbff2 ····LTEXT ··········"days",IDC_STATIC,313,100,20,9
1ce0d1 END
5aaf5a
e0ced9 IDD_REVIEWOLD DIALOG DISCARDABLE ·0, 0, 350, 222
d56b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
9e1dea CAPTION "PGPadmin - Review of options selected"
e0309f FONT 8, "MS Sans Serif"
0c4523 BEGIN
c984f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
4237c1 ····················SS_SUNKEN,7,9,81,161
02e78a ····LTEXT ··········"Incoming ADK <inadk@pgp.com>",IDC_INADK,169,20,171,12,
2f8f28 ····················SS_CENTERIMAGE | SS_SUNKEN | WS_BORDER
a7a593 ····LTEXT ··········"Outgoing ADK <outadk@pgp.com>",IDC_OUTADK,169,38,171,12,
028f28 ····················SS_CENTERIMAGE | SS_SUNKEN | WS_BORDER
dca35b ····LTEXT ··········"Corp Key <corp@pgp.com>",IDC_CORPKEY,189,67,151,12,
568f28 ····················SS_CENTERIMAGE | SS_SUNKEN | WS_BORDER
edfd62 ····CHECKBOX ·······"Incoming ADK:",IDC_INADK_CHECK,100,21,67,11,BS_TOP |·
c01e27 ····················BS_MULTILINE
e815d9 ····CHECKBOX ·······"Outgoing ADK:",IDC_OUTADK_CHECK,100,39,68,10,BS_TOP |·
c11e27 ····················BS_MULTILINE
b19d0d ····CHECKBOX ·······"Incoming ADK",IDC_ENFORCEINADK_CHECK,129,53,66,10
dd5151 ····CHECKBOX ·······"Corporate Signing Key:",IDC_CORPKEY_CHECK,100,68,85,10
cad962 ····CHECKBOX ·······"Warn on keys not signed by CSK",IDC_WARN_NOTCERT_CHECK,
506b66 ····················222,82,118,9
d1c855 ····CHECKBOX ·······"CSK is a Meta-Introducer",IDC_METAINTRODUCER_CHECK,112,
2c7669 ····················82,98,9
4c2cb4 ····CHECKBOX ·······"Passphrase minimum length:",IDC_PASSPHRASE_CHECK,100,96,
d05479 ····················102,10
9db09a ····CHECKBOX ·······"Minimum quality:",IDC_QUALITY_CHECK,252,96,66,10
e331de ····CHECKBOX ·······"Allow conventional encryption",IDC_CONVENTIONAL_CHECK,
d0d87f ····················100,138,131,10
f8fbe3 ····CHECKBOX ·······"Message Header comment:",IDC_COMMENT_CHECK,100,151,102,
2eebc1 ····················10
--2a68 0005cff14e64011025f Page 9 of PGPadmin.rc
ffa1ce ····LTEXT ··········"Comments",IDC_COMMENT,206,150,134,12,SS_CENTERIMAGE |·
cf2359 ····················SS_SUNKEN | WS_BORDER
58cf3e ····CONTROL ········"List1",IDC_DEFKEYS,"SysListView32",LVS_REPORT |·
a63ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
5b35f8 ····················WS_TABSTOP,100,176,240,44
515f9a ····LTEXT ··········"Default keys:",IDC_STATIC,100,166,44,10
244924 ····CHECKBOX ·······"Allow key generation",IDC_KEYGEN_CHECK,100,111,87,10
d123b8 ····CHECKBOX ·······"Allow RSA key generation",IDC_RSAKEYGEN_CHECK,194,111,
bc2c08 ····················99,10
458eea ····LTEXT ··········"8",IDC_MINCHARS_CHECK,205,95,17,12,SS_CENTERIMAGE |·
2e2359 ····················SS_SUNKEN | WS_BORDER
330c9f ····LTEXT ··········"20",IDC_MINQUALITY_CHECK,321,95,17,12,SS_CENTERIMAGE |·
192359 ····················SS_SUNKEN | WS_BORDER
910683 ····CHECKBOX ·······"Minimum key size:",IDC_KEYSIZE_CHECK,100,125,72,10
c157a3 ····LTEXT ··········"1024",IDC_MINKEYSIZE_CHECK,172,124,22,12,SS_CENTERIMAGE |·
8c2359 ····················SS_SUNKEN | WS_BORDER
7f83dd ····LTEXT ··········"These are the options you have set. To change them, use th¶
536055 e Back button.",
d87937 ····················IDC_STATIC,100,6,244,11
a5114a ····LTEXT ··········"ADK: Addtional Decryption Key\n\nCSK: Corporate Signing Ke¶
6e306c y",
2f97b8 ····················IDC_STATIC,7,176,81,42,SS_SUNKEN
21ce2d ····CHECKBOX ·······"Outgoing ADK",IDC_ENFORCEOUTADK_CHECK,204,53,65,10
91926c ····CHECKBOX ·······"Remote ADK",IDC_ENFORCEREMOTEADK_CHECK,278,53,61,10
3ebabb ····LTEXT ··········"Enforce:",IDC_ENFORCELABEL,99,53,28,8
95e0d1 END
bfaf5a
b754a4 IDD_REVOKER DIALOG DISCARDABLE ·0, 0, 350, 222
166b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
d6a6a9 CAPTION "PGPadmin - Designated Revoker"
b1309f FONT 8, "MS Sans Serif"
fb4523 BEGIN
f59dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
57d047 ····················-1,92,0,254,189,NOT WS_VISIBLE
535411 ····LTEXT ··········"One problem that can occur is the loss of a user's private¶
a6e859 ·key. If the user's hard drive crashes, and they had not made a backup of their¶
05516c ·private key, there is no way they can ever gain access to their encrypted mess¶
e6b633 ages ",
5f3f3b ····················-1,99,9,242,25
a34ddf ····CONTROL ········"Enable a Designated &Revoker key",IDC_ENABLEREVOKER,
1746a8 ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,131,244,9
b3e0aa ····LTEXT ··········"Designated Revoker key, and have the user generate a new k¶
50dd62 ey. Since this key will be able to revoke any key in your organization, it must¶
f143d1 ·be kept very secure from theft, and it should have a strong passphrase.",
7cedc8 ····················-1,99,95,242,26
8784f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
b537c1 ····················SS_SUNKEN,7,9,81,161
c62859 ····LTEXT ··········"To avoid this problem, you can select a key to be the Desi¶
c3369c gnated Revoker. This key will be able to revoke any key generated by the user u¶
591c8b nder this installation. If any user loses their key, you can revoke it using th¶
e99bfe e ",
4a79be ····················-1,99,71,242,25
f9651a ····LTEXT ··········"again. More importantly, other users will continue to encr¶
713dd6 ypt to the public key because there is no way to revoke it when the private key¶
4e4c43 ·is lost, and there's no way to tell other users that the key is lost, short of¶
073215 ·sending each user a message.",
d54ae1 ····················-1,99,33,239,34
0fe0d1 END
ffaf5a
806e67 IDD_REVOKERSEL DIALOG DISCARDABLE ·0, 0, 350, 222
756b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
4bceb9 CAPTION "PGPadmin - Designated Revoker key selection"
11309f FONT 8, "MS Sans Serif"
4d4523 BEGIN
a684f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
d037c1 ····················SS_SUNKEN,7,9,81,161
3e9dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
e9d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
5c6c70 ····LTEXT ··········"The following list shows all Diffie-Hellman keys on your k¶
d06d99 eyring. Please choose the key you wish to use for the Designated Revoker key:",
2365ae ····················IDC_STATIC,99,11,240,19
5c7338 ····CONTROL ········"List1",IDC_REVOKER_ID,"SysListView32",LVS_REPORT |·
--d588 0000433a7544011025f Page 10 of PGPadmin.rc
4a3ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
ebb0c8 ····················WS_TABSTOP,99,38,240,142
c3e0d1 END
9eaf5a
883c2e IDD_ADK_DISK DIALOG DISCARDABLE ·0, 0, 350, 222
3b6b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
0a6fb6 CAPTION "PGPadmin - PGPdisk Additional Decryption Key"
f6309f FONT 8, "MS Sans Serif"
344523 BEGIN
7d84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
0f37c1 ····················SS_SUNKEN,7,9,81,161
329dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
54d047 ····················-1,92,0,254,189,NOT WS_VISIBLE
11b0af ····CONTROL ········"Use a PGP&disk Additional Decryption Key",
1ea52e ····················IDC_USE_DISKADK,"Button",BS_AUTOCHECKBOX | BS_NOTIFY |·
7f6c77 ····················WS_TABSTOP,99,102,147,10
c02800 ····LTEXT ··········"If your organization uses PGPdisk, you may configure PGP t¶
9a384a o automatically add an Additional Decryption Key to all new PGPdisks created by¶
4e9e67 ·the client version of PGP generated here. ·This will allow the owner of the AD¶
5bb450 K to",
20c549 ····················-1,99,10,242,24
8c419f ····LTEXT ··········"If you choose to use a PGPdisk ADK, the key must already b¶
cab6a8 e on your keyring before going to the next page. ·If it is not, generate the ke¶
c4726c y you intend to use for the PGPdisk ADK, then press the Next button.",
ae6a7c ····················-1,99,65,242,25
67a535 ····LTEXT ··········"recover data from PGPdisks in an emergency. ·As with any A¶
af1fa2 DK, the security of the ADK private key is critical, and thus it must be kept v¶
0d90a1 ery secure.",
5adbe1 ····················-1,99,34,219,27
e9e0d1 END
74af5a
6dba64 IDD_ADK_DISKSEL DIALOG DISCARDABLE ·0, 0, 350, 222
426b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
d9da98 CAPTION "PGPadmin - PGPdisk Additional Decryption Key selection"
a5309f FONT 8, "MS Sans Serif"
cd4523 BEGIN
8784f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
2137c1 ····················SS_SUNKEN,7,9,81,161
209dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
ead675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
952529 ····LTEXT ··········"The following list shows all keys on your keyring. Please ¶
d4f8ea choose the key you wish to use as the PGPdisk Additional Decryption Key:",
738601 ····················IDC_STATIC,97,13,240,27
b98e41 ····CONTROL ········"List1",IDC_DISKADK_ID,"SysListView32",LVS_REPORT |·
533ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
0dd53a ····················WS_TABSTOP,97,45,240,142
b6e0d1 END
96af5a
bbff4a IDD_INSTALLOPTIONS DIALOG DISCARDABLE ·0, 0, 350, 222
a26b77 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
af60d4 CAPTION "PGPadmin - Installation Options"
5a309f FONT 8, "MS Sans Serif"
cf4523 BEGIN
f49431 ····CONTROL ········"Pre-&select installation options for user",
69479b ····················IDC_PRESELECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,
e8c16b ····················67,200,11
2b7c56 ····EDITTEXT ·······IDC_USERINSTALLDIR,112,90,213,13,ES_AUTOHSCROLL
3439a6 ····CONTROL ········"Install &program files (PGPkeys, PGPtools, PGPtray)",
75e63d ····················IDC_INSTALLPROGRAMS,"Button",BS_AUTOCHECKBOX |·
52ba50 ····················WS_TABSTOP,112,108,195,10
002711 ····CONTROL ········"Install PGP&disk",IDC_INSTALLDISK,"Button",
2484b6 ····················BS_AUTOCHECKBOX | WS_TABSTOP,112,119,195,10
66ed3f ····CONTROL ········"Install &Eudora plug-in",IDC_INSTALLEUDORA,"Button",
c0eecf ····················BS_AUTOCHECKBOX | WS_TABSTOP,112,130,195,10
da5a78 ····CONTROL ········"Install Exchange/&Outlook plug-in",IDC_INSTALLOUTLOOK,
6798a9 ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,141,195,10
d6238f ····CONTROL ········"Install Outlook E&xpress plug-in",IDC_INSTALLOUTEXPRESS,
a16289 ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,152,195,10
ef32ce ····CONTROL ········"Install User's &Manual",IDC_INSTALLMANUAL,"Button",
c5a473 ····················BS_AUTOCHECKBOX | WS_TABSTOP,112,163,195,10
749dc0 ····GROUPBOX ·······"Body should be inside this frame. This frame is invisible",
04d675 ····················IDC_STATIC,92,0,254,189,NOT WS_VISIBLE
--af58 0009fa9e8864011025f Page 11 of PGPadmin.rc
9eea7b ····LTEXT ··········"To make it easier for users to install PGP, you can pre-se¶
82ff7a lect such options as the installation directory, and which components will be i¶
f4068d nstalled. If you choose to do this, the installer will use the options you spec¶
b1a078 ify and won't",
fea502 ····················IDC_STATIC,99,9,240,25
dd84f5 ····CONTROL ········105,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
f637c1 ····················SS_SUNKEN,7,9,81,161
a55d48 ····LTEXT ··········"ask the user for this information.",IDC_STATIC,99,33,
3c843e ····················240,9
697ac7 ····LTEXT ··········"Directory to install user's copy of PGP (including drive l¶
a6856b etter):",
daab23 ····················IDC_STATIC,112,81,202,8
700fdb ····LTEXT ··········"NOTE: Installation of the program files is required if you¶
6b6368 ·want to install any of the plug-ins.",
bf5ce0 ····················IDC_STATIC,99,45,240,17
739e75 ····CONTROL ········"&Un-install old versions of PGP",IDC_UNINSTALL,"Button",
a861b6 ····················BS_AUTOCHECKBOX | WS_TABSTOP,112,174,195,10
99e0d1 END
9faf5a
74af5a
0ef860 #ifdef APSTUDIO_INVOKED
7a6c0e /////////////////////////////////////////////////////////////////////////////
0e465d //
6a5733 // TEXTINCLUDE
e2465d //
28af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
604523 BEGIN
7b541e ····"resource.h\0"
f9e0d1 END
a3af5a
037037 2 TEXTINCLUDE DISCARDABLE·
b74523 BEGIN
abeb23 ····"#include ""afxres.h""\r\n"
dbe851 ····"\r\n"
9ee856 ····"// $Id: PGPadmin.rc,v 1.50 1998/07/30 15:55:10 dgal Exp $\r\n"
9fdb5c ····"\0"
31e0d1 END
70af5a
5b227f 3 TEXTINCLUDE DISCARDABLE·
734523 BEGIN
cf92e3 ····"#include ""PGPadminVer.rc""\r\n"
d3db5c ····"\0"
0ee0d1 END
68af5a
d969ab #endif ···// APSTUDIO_INVOKED
62af5a
8caf5a
c46c0e /////////////////////////////////////////////////////////////////////////////
79465d //
f586c0 // Menu
ce465d //
a2af5a
684d45 IDR_MENU MENU DISCARDABLE·
c14523 BEGIN
20b474 ····POPUP "&File"
305574 ····BEGIN
b7541c ········MENUITEM "&Wizard", ····················IDM_WIZARD
95645b ········MENUITEM "E&xit", ······················IDM_EXIT
437d01 ····END
c5e0d1 END
b1af5a
9caf5a
176c0e /////////////////////////////////////////////////////////////////////////////
e9465d //
92ae70 // Bitmap
cb465d //
1eaf5a
d33eaf IDB_ADMINWIZ8 ··········BITMAP ·DISCARDABLE ····"Res\\AdminWiz8bit.bmp"
e14ae7 IDB_ADMINWIZ24 ·········BITMAP ·DISCARDABLE ····"Res\\AdminWiz24bit.bmp"
2e526a IDB_ADMINWIZ4 ··········BITMAP ·DISCARDABLE ····"Res\\AdminWiz4bit.bmp"
9fb935 IDB_ADMINWIZ1 ··········BITMAP ·DISCARDABLE ····"Res\\AdminWiz1bit.bmp"
--953a 000d91abe964011025f Page 12 of PGPadmin.rc
c324e2 IDB_IMAGES24BIT ········BITMAP ·DISCARDABLE ····"..\\shared\\images24.bmp"
33fed3 IDB_IMAGES4BIT ·········BITMAP ·DISCARDABLE ····"..\\shared\\images4.bmp"
70af5a
166c0e /////////////////////////////////////////////////////////////////////////////
75465d //
6ecbaf // Icon
99465d //
a6af5a
0a2951 // Icon with lowest ID value placed first to ensure application icon
130f06 // remains consistent on all systems.
fbdbc8 IDI_ADMIN ··············ICON ···DISCARDABLE ····"res\\admin.ico"
b8af5a
246c0e /////////////////////////////////////////////////////////////////////////////
36465d //
906077 // DESIGNINFO
ec465d //
57af5a
4df860 #ifdef APSTUDIO_INVOKED
f670e4 GUIDELINES DESIGNINFO DISCARDABLE·
034523 BEGIN
9f9420 ····IDD_COPYPROGRESS, DIALOG
f65574 ····BEGIN
a2c975 ········LEFTMARGIN, 7
7b235c ········RIGHTMARGIN, 179
4787e9 ········TOPMARGIN, 7
452d02 ········BOTTOMMARGIN, 64
e27d01 ····END
02af5a
6e1e39 ····IDD_FINDINSTALLER, DIALOG
685574 ····BEGIN
02c975 ········LEFTMARGIN, 7
700750 ········RIGHTMARGIN, 210
4387e9 ········TOPMARGIN, 7
d4230e ········BOTTOMMARGIN, 72
fa7d01 ····END
7ee0d1 END
7869ab #endif ···// APSTUDIO_INVOKED
d3af5a
acaf5a
fa6c0e /////////////////////////////////////////////////////////////////////////////
ba465d //
9c5e87 // String Table
ac465d //
dcaf5a
0a6f6c STRINGTABLE DISCARDABLE·
574523 BEGIN
01531b ····IDS_USERID ·············"User ID"
05a844 ····IDS_CREATION ···········"Creation"
1839b1 ····IDS_KEYSIZE ············"Size"
42321e ····IDS_SAVEADMINTITLE ·····"Save Administrative Preferences file as..."
ce6acf ····IDS_SAVEDEFKEYSTITLE ···"Save Default Keyring file as..."
d4fb40 ····IDS_ADMINPREFFILE ······"PGP_Admin.prf"
47a44c ····IDS_DEFKEYSFILE ········"pubring.pkr"
b1d4a7 ····IDS_CHOOSEDIR ··········"Select the directory where the installation files ¶
01c9a8 will be kept:"
bc212c ····IDS_CLIENTPREFFILE ·····"PGP_Client.prf"
4e5099 ····IDS_TEMPPREFFILE ·······"temp.prf"
33c10f ····IDS_TITLE ··············"PGP Administration Wizard"
92e0d1 END
b5af5a
e76f6c STRINGTABLE DISCARDABLE·
df4523 BEGIN
163539 ····IDS_E_MINCHARS_TOOSMALL "If you choose to enforce a minimum number of chara¶
4bf53d cters, the minimum must be at least 8."
6c7dda ····IDS_E_MINCHARS_TOOLARGE "You can not enforce a minimum of more than 128 cha¶
344fa2 racters."
21b2c1 ····IDS_E_MINQUAL_TOOSMALL ·"If you choose to enforce a minimum quality rating,¶
3e9de0 ·the minimum must be at least 20."
12de71 ····IDS_E_MINQUAL_TOOLARGE ·"You can not enforce a minimum quality rating of mo¶
a29cfa re than 100."
04f40e ····IDS_E_RELOADKEYRING ····"Your keyring has been modified, invalidating the o¶
d99f50 ptions that you have just set. Click OK, then either restart or cancel the Admi¶
--10c4 001626a442a4011025f Page 13 of PGPadmin.rc
5d7afb n Wizard."
245115 ····IDS_NEWPREFFILE ········"defclient.prf"
6e44f5 ····IDS_DONE ···············"The PGP installer was successfully created"
b28b84 ····IDS_FAILED ·············"The creation of the ·PGP installer failed"
bb7200 ····IDS_DEFAULTPATH ········"C:\\"
adf363 ····IDS_INSTALLDIR ·········"%sPGP%sClientInstall\\"
26a993 ····IDS_INSTALLDISK ········"Disk1"
0b9662 ····IDS_CLIENTINSTALLER ····"ClientInstaller\\"
01998b ····IDS_E_MINCHARSRANGE ····"The minimum number of chacters must be between 8 a¶
1168a2 nd 128."
fe5165 ····IDS_E_MINQUALRANGE ·····"The minimum quality must be between 20 and 100."
50bd4e ····IDS_E_INSTALLDIR ·······"You can't create the Non-Admin PGP installer insid¶
fa682e e the ClientInstaller directory. Please choose another directory."
e5410e ····IDS_E_CLIENTINSTALLER ··"The files necessary to create the Non-Admin PGP In¶
f62ed6 staller were not found."
77e0d1 END
0caf5a
5e6f6c STRINGTABLE DISCARDABLE·
b44523 BEGIN
6af608 ····IDS_E_MINKEYSIZERANGE ··"The minimum key size must be between 768 and 4096 ¶
36da6e bits."
77f4c8 ····IDS_E_EXPIRED ··········"This version of PGP has expired. You will not be a¶
3747ee ble to run the Admin Wizard."
62c76c ····IDS_E_MINKEYSIZERANGERSA·
a90497 ····························"The minimum key size must be between 768 and 2048 ¶
aeda6e bits."
f21f37 ····IDS_E_DAYSRANGE ········"The number of days must be between 1 and 999."
51e0d1 END
97af5a
ec1b3a #endif ···// English (U.S.) resources
a56c0e /////////////////////////////////////////////////////////////////////////////
44af5a
8aaf5a
a3af5a
c4ce8c #ifndef APSTUDIO_INVOKED
396c0e /////////////////////////////////////////////////////////////////////////////
b3465d //
178464 // Generated from the TEXTINCLUDE 3 resource.
4b465d //
891d98 #include "PGPadminVer.rc"
12af5a
0e6c0e /////////////////////////////////////////////////////////////////////////////
b78072 #endif ···// not APSTUDIO_INVOKED
62af5a
--4e0b 0018113f76840110260 Page 1 of PGPadminVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
efcbdb ············VALUE "FileDescription", "PGP Administration Wizard\0"
7ac1dd ············VALUE "FileVersion", PGPVERSIONSTRING
d4eda1 ············VALUE "InternalName", "PGPadmin\0"
5e8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
0b2bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
4747c7 ············VALUE "OriginalFilename", "PGPadmin.exe\0"
629317 ············VALUE "ProductName", PGPPRODUCTNAME
5dd1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
f2f37f ········END
e97d01 ····END
8b26ab ····BLOCK "VarFileInfo"
095574 ····BEGIN
9c4b11 ········VALUE "Translation", 0x409, 1200
ea7d01 ····END
fee0d1 END
86af5a
adaf5a
81af5a
--ba00 000d869e35840110261 Page 1 of PassPhrase.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c1cb00 ¤   $Id: PassPhrase.cpp,v 1.13.8.1 1998/11/12 03:13:12 heller Exp $
6af7f7 ____________________________________________________________________________*/
c0af5a
ee5655 #include <windows.h>
fafb83 #include "PGPadmin.h"
988031 #include "resource.h"
2baf5a
9bdc74 BOOL CALLBACK PassPhraseDlgProc(HWND hwndDlg,·
90a2bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
e9d693 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
37d9f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
2fbb36 {
6c0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
088ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
e14c42 ¤   char¤   ¤   ¤   szMinChars[10];
c82b32 ¤   char¤   ¤   ¤   szMinQuality[10];
c8af5a
256357 ¤   g_hCurrentDlgWnd = hwndDlg;
94af5a
489450 ¤   if (uMsg != WM_INITDIALOG)
70e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
49af5a
3fc08d ¤   switch(uMsg)
43c7a1 ¤   {
0c2940 ¤   case WM_INITDIALOG:
915b34 ¤   ¤   {
85afc0 ¤   ¤   ¤   RECT rc;
c5313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
5caf5a
b4015a ¤   ¤   ¤   // center dialog on screen
a9d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
8cb2c2 ¤   ¤   ¤   SetWindowPos (GetParent(hwndDlg), NULL,
220971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
e8004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
edf9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
ebaf5a
4e3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
98ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
fdcdcb ¤   ¤   ¤   break;
5c0fe4 ¤   ¤   }
a1af5a
d093f9 ¤   case WM_PAINT:
3bc334 ¤   ¤   if (pConfig->hPalette)
c65b34 ¤   ¤   {
72f431 ¤   ¤   ¤   PAINTSTRUCT ps;
6d60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
654fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
d39ffe ¤   ¤   ¤   RealizePalette (hDC);
f7438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
d20fe0 ¤   ¤   ¤   bReturnCode = TRUE;
bf0fe4 ¤   ¤   }
5f2f68 ¤   ¤   break;
cc1b52 ¤   ¤
e4c93c ¤   case WM_NOTIFY:
de5b34 ¤   ¤   {
b0a08b ¤   ¤   ¤   LPNMHDR pnmh;
5daf5a
c02b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
7eb7b0 ¤   ¤   ¤   switch(pnmh->code)
baf776 ¤   ¤   ¤   {
1466bc ¤   ¤   ¤   case PSN_SETACTIVE:
ff72c3 ¤   ¤   ¤   ¤   {
817182 ¤   ¤   ¤   ¤   ¤   // Initialize window
035256 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),·
64c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
d8af5a
--8350 000e841caeb40110261 Page 2 of PassPhrase.cpp
da9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
ac670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
88af5a
57ed34 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceMinChars)
f94859 ¤   ¤   ¤   ¤   ¤   {
d0d4d8 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_MINCHARS,·
d094bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
6ffa66 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL1),·
01c147 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);·
5ee7aa ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL2),·
aec147 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);·
b46d1d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINCHARS),·
1ac147 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);·
771c89 ¤   ¤   ¤   ¤   ¤   }
fa4bd6 ¤   ¤   ¤   ¤   ¤   else
1c4859 ¤   ¤   ¤   ¤   ¤   {
07d4d8 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_MINCHARS,·
02d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
76fa66 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL1),·
6d8d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);·
30e7aa ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL2),·
df8d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);·
c36d1d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINCHARS),·
278d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);·
0b1c89 ¤   ¤   ¤   ¤   ¤   }
90af5a
be814c ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceMinQuality)
274859 ¤   ¤   ¤   ¤   ¤   {
04799b ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_MINQUALITY,·
1d94bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
0eb282 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL1),·
91c147 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);·
0aaf4e ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL2),·
24c147 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);·
5ad96c ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINQUALITY),·
90c147 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);·
ff1c89 ¤   ¤   ¤   ¤   ¤   }
814bd6 ¤   ¤   ¤   ¤   ¤   else
404859 ¤   ¤   ¤   ¤   ¤   {
66799b ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENFORCE_MINQUALITY,·
34d06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
96b282 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL1),·
ae8d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);·
f6af4e ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL2),·
fd8d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);·
abd96c ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINQUALITY),·
ec8d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);·
ed1c89 ¤   ¤   ¤   ¤   ¤   }
aeaf5a
741b2f ¤   ¤   ¤   ¤   ¤   wsprintf(szMinChars, "%d", pConfig->nMinChars);
0ab439 ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_MINCHARS),·
6a1451 ¤   ¤   ¤   ¤   ¤   ¤   szMinChars);
59af5a
812f0f ¤   ¤   ¤   ¤   ¤   wsprintf(szMinQuality, "%d", pConfig->nMinQuality);
b9d673 ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_MINQUALITY),·
438b5e ¤   ¤   ¤   ¤   ¤   ¤   szMinQuality);
a5af5a
2f4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
6b14c3 ¤   ¤   ¤   ¤   ¤   break;
082613 ¤   ¤   ¤   ¤   }
a6af5a
1799a3 ¤   ¤   ¤   case PSN_WIZNEXT:
dd72c3 ¤   ¤   ¤   ¤   {
40fdba ¤   ¤   ¤   ¤   ¤   char szErrorMsg[255];
4fea46 ¤   ¤   ¤   ¤   ¤   char szTitle[255];
4075ac ¤   ¤   ¤   ¤   ¤   BOOL bError = FALSE;
95af5a
014149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
3715f5 ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
29af5a
f9a809 ¤   ¤   ¤   ¤   ¤   // Check data validity
e8af5a
--5bc1 000d0223d6840110261 Page 3 of PassPhrase.cpp
82ed34 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceMinChars)
a84859 ¤   ¤   ¤   ¤   ¤   {
5d177a ¤   ¤   ¤   ¤   ¤   ¤   if ((pConfig->nMinChars < 8) ||·
ada281 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pConfig->nMinChars > 128))
058fec ¤   ¤   ¤   ¤   ¤   ¤   {
eb1332 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_E_MINCHARSRANGE,
896b2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szErrorMsg, 254);
2e458b ¤   ¤   ¤   ¤   ¤   ¤   ¤   bError = TRUE;
85db3c ¤   ¤   ¤   ¤   ¤   ¤   }
f91c89 ¤   ¤   ¤   ¤   ¤   }
03af5a
e6c8a3 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceMinQuality && !bError)
a94859 ¤   ¤   ¤   ¤   ¤   {
8cb429 ¤   ¤   ¤   ¤   ¤   ¤   if ((pConfig->nMinQuality < 20) ||
694b89 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pConfig->nMinQuality > 100))
7f8fec ¤   ¤   ¤   ¤   ¤   ¤   {
bd3cbd ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_E_MINQUALRANGE,
396b2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szErrorMsg, 254);
fc458b ¤   ¤   ¤   ¤   ¤   ¤   ¤   bError = TRUE;
5fdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
2e1c89 ¤   ¤   ¤   ¤   ¤   }
d4af5a
f8c530 ¤   ¤   ¤   ¤   ¤   if (bError)
254859 ¤   ¤   ¤   ¤   ¤   {
5ee909 ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(hwndDlg, szErrorMsg, szTitle, MB_OK);
a309b6 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
2e1c89 ¤   ¤   ¤   ¤   ¤   }
d614c3 ¤   ¤   ¤   ¤   ¤   break;
f52613 ¤   ¤   ¤   ¤   }
a8af5a
6749a1 ¤   ¤   ¤   case PSN_WIZBACK:
cb72c3 ¤   ¤   ¤   ¤   {
631dba ¤   ¤   ¤   ¤   ¤   // Determine if we should go to PGPdisk ADK selection
122cd6 ¤   ¤   ¤   ¤   ¤   // or skip past it
02af5a
4ca6e9 ¤   ¤   ¤   ¤   ¤   if (!pConfig->bUseDiskADK)
931039 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT,·
218b1b ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDD_ADK_DISK);
81af5a
2a4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ed14c3 ¤   ¤   ¤   ¤   ¤   break;
dc2613 ¤   ¤   ¤   ¤   }
80af5a
cd6122 ¤   ¤   ¤   case PSN_HELP:
8c72c3 ¤   ¤   ¤   ¤   {
bdf1f2 ¤   ¤   ¤   ¤   ¤   // Display help
4514c3 ¤   ¤   ¤   ¤   ¤   break;
842613 ¤   ¤   ¤   ¤   }
6eaf5a
bf8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
df72c3 ¤   ¤   ¤   ¤   {
3a6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
94014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
bd14c3 ¤   ¤   ¤   ¤   ¤   break;
a12613 ¤   ¤   ¤   ¤   }
dea3a6 ¤   ¤   ¤   }
a587c7 ¤   ¤   ¤
9ecdcb ¤   ¤   ¤   break;
d30fe4 ¤   ¤   }
5caf5a
953fcf ¤   case WM_COMMAND:
5772a4 ¤   ¤   switch (LOWORD(wParam))
985b34 ¤   ¤   {
ac7f6b ¤   ¤   case IDC_ENFORCE_MINCHARS:
31f776 ¤   ¤   ¤   {
960bb1 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ENFORCE_MINCHARS) ==·
662a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
1d72c3 ¤   ¤   ¤   ¤   {
d1e8ff ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL1), TRUE);·
386f11 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL2), TRUE);·
50577d ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINCHARS), TRUE);·
d0380d ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceMinChars = TRUE;
--db8e 0013b95a1c640110261 Page 4 of PassPhrase.cpp
862613 ¤   ¤   ¤   ¤   }
7dfa07 ¤   ¤   ¤   ¤   else
8772c3 ¤   ¤   ¤   ¤   {
59b4bb ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL1), FALSE);·
86ba4c ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_PASSLABEL2), FALSE);·
b9131e ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINCHARS), FALSE);·
7aea9e ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceMinChars = FALSE;
902613 ¤   ¤   ¤   ¤   }
961b52 ¤   ¤
22841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
77f622 ¤   ¤   ¤   ¤   break;
28a3a6 ¤   ¤   ¤   }
53af5a
69b315 ¤   ¤   case IDC_ENFORCE_MINQUALITY:
3bf776 ¤   ¤   ¤   {
83c05b ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ENFORCE_MINQUALITY) ==·
922a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
b672c3 ¤   ¤   ¤   ¤   {
c38698 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL1), TRUE);·
950176 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL2), TRUE);·
5188b5 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINQUALITY), TRUE);·
630021 ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceMinQuality = TRUE;
2e2613 ¤   ¤   ¤   ¤   }
c1fa07 ¤   ¤   ¤   ¤   else
4572c3 ¤   ¤   ¤   ¤   {
87a36c ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL1), FALSE);·
d9ad9b ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_QUALLABEL2), FALSE);·
e75985 ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_MINQUALITY), FALSE);·
0401c8 ¤   ¤   ¤   ¤   ¤   pConfig->bEnforceMinQuality = FALSE;
fa2613 ¤   ¤   ¤   ¤   }
fe67c5 ¤
b9841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
2bf622 ¤   ¤   ¤   ¤   break;
bba3a6 ¤   ¤   ¤   }
c3af5a
f09734 ¤   ¤   case IDC_MINCHARS:
08f776 ¤   ¤   ¤   {
1eeda5 ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_MINCHARS),·
b20838 ¤   ¤   ¤   ¤   ¤   szMinChars, 10);
bd868f ¤   ¤   ¤   ¤   pConfig->nMinChars = atoi(szMinChars);
b2841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
bef622 ¤   ¤   ¤   ¤   break;
88a3a6 ¤   ¤   ¤   }
7caf5a
8a886c ¤   ¤   case IDC_MINQUALITY:
89f776 ¤   ¤   ¤   {
e8a9ca ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_MINQUALITY),·
2f72de ¤   ¤   ¤   ¤   ¤   szMinQuality, 10);
a0d9d9 ¤   ¤   ¤   ¤   pConfig->nMinQuality = atoi(szMinQuality);
bf841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9bf622 ¤   ¤   ¤   ¤   break;
c4a3a6 ¤   ¤   ¤   }
f10fe4 ¤   ¤   }
a7af5a
4e2f68 ¤   ¤   break;
869371 ¤   }
21af5a
4e48b1 ¤   return(bReturnCode);
e3efe6 }
deaf5a
f57e4d /*__Editor_settings____
9eaf5a
a24126 ¤   Local Variables:
5f7b17 ¤   tab-width: 4
1a0e6c ¤   End:
a85f8c ¤   vi: ts=4 sw=4
f99e9b ¤   vim: si
3bd062 _____________________*/
--925f 000cf6e1ffe40110262 Page 1 of Review.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c4f5e3 ¤   $Id: Review.cpp,v 1.13.8.1 1998/11/12 03:13:12 heller Exp $
e7f7f7 ____________________________________________________________________________*/
62af5a
a15655 #include <windows.h>
e1fb83 #include "PGPadmin.h"
ba90fb #include <commctrl.h>
b08031 #include "resource.h"
bd0d08 #include "pgpMem.h"
1caf5a
77541e BOOL CALLBACK ReviewDlgProc(HWND hwndDlg,·
8c2add ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT uMsg,·
92cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
7f4868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
0bbb36 {
840f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
c28ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
87c94a ¤   DWORD¤  ¤   ¤   dwStart;
926c19 ¤   DWORD¤  ¤   ¤   dwEnd;
d4af5a
016357 ¤   g_hCurrentDlgWnd = hwndDlg;
fdaf5a
189450 ¤   if (uMsg != WM_INITDIALOG)
18e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
7eaf5a
ffc08d ¤   switch(uMsg)
b3c7a1 ¤   {
da2940 ¤   case WM_INITDIALOG:
fb5b34 ¤   ¤   {
89afc0 ¤   ¤   ¤   RECT rc;
d4313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
06af5a
72015a ¤   ¤   ¤   // center dialog on screen
e0d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
b33d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
600971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
49004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
9ef9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
48af5a
2a3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
1dad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
34cdcb ¤   ¤   ¤   break;
ff0fe4 ¤   ¤   }
66af5a
e693f9 ¤   case WM_PAINT:
2ac334 ¤   ¤   if (pConfig->hPalette)
175b34 ¤   ¤   {
6df431 ¤   ¤   ¤   PAINTSTRUCT ps;
4360df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
844fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
6e9ffe ¤   ¤   ¤   RealizePalette (hDC);
a8438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
e40fe0 ¤   ¤   ¤   bReturnCode = TRUE;
f10fe4 ¤   ¤   }
bdaf5a
1a73d0 ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_PANEL, EM_GETSEL, (WPARAM) &dwStart,
87025f ¤   ¤   ¤   (LPARAM) &dwEnd);
f4af5a
1dbd47 ¤   ¤   if (dwStart != -1)
f7cd69 ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_PANEL, EM_SETSEL, -1, 0);
2e2f68 ¤   ¤   break;
131b52 ¤   ¤
70c93c ¤   case WM_NOTIFY:
975b34 ¤   ¤   {
28a08b ¤   ¤   ¤   LPNMHDR pnmh;
f1af5a
cf2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
--5504 000cfd9f1b540110262 Page 2 of Review.cpp
f6b7b0 ¤   ¤   ¤   switch(pnmh->code)
6af776 ¤   ¤   ¤   {
2066bc ¤   ¤   ¤   case PSN_SETACTIVE:
4772c3 ¤   ¤   ¤   ¤   {
436edd ¤   ¤   ¤   ¤   ¤   char *szPanel;
706183 ¤   ¤   ¤   ¤   ¤   char szTemp[256];
4fb93b ¤   ¤   ¤   ¤   ¤   int nTabSize;
fcaf5a
8c5132 ¤   ¤   ¤   ¤   ¤   szPanel = (char *) calloc(1, 8192);
cf406e ¤   ¤   ¤   ¤   ¤   if (szPanel == NULL)
090e30 ¤   ¤   ¤   ¤   ¤   ¤   return FALSE;
f1af5a
897182 ¤   ¤   ¤   ¤   ¤   // Initialize window
1ebd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
3dc365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
84af5a
b09908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
82670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
0aaf5a
9e1cf4 ¤   ¤   ¤   ¤   ¤   nTabSize = 20;
89f1b5 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_PANEL, EM_SETTABSTOPS,·
6e7129 ¤   ¤   ¤   ¤   ¤   ¤   1, (LPARAM) &nTabSize);
81af5a
75da3c ¤   ¤   ¤   ¤   ¤   strcpy(szPanel, "Company Name:\r\n");
31ae30 ¤   ¤   ¤   ¤   ¤
7496ba ¤   ¤   ¤   ¤   ¤   if (pConfig->szLicenseNum != NULL)
1dc329 ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%s\r\n\r\n",·
35a48a ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szLicenseNum);
d84bd6 ¤   ¤   ¤   ¤   ¤   else
20841a ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szTemp, "\t<none>\r\n\r\n");
d7af5a
7e1cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
902475 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Incoming ADK:\r\n");
ffae30 ¤   ¤   ¤   ¤   ¤
e7cd32 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseIncomingADK)
5c4859 ¤   ¤   ¤   ¤   ¤   {
0440f0 ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%s\r\n", pConfig->szIncomingADK);
26d737 ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceIncomingADK)
a2520e ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szTemp, "\tEnforced\r\n\r\n");
2b7f8b ¤   ¤   ¤   ¤   ¤   ¤   else
b13c02 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szTemp, "\tNot Enforced\r\n\r\n");
771c89 ¤   ¤   ¤   ¤   ¤   }
314bd6 ¤   ¤   ¤   ¤   ¤   else
5f841a ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szTemp, "\t<none>\r\n\r\n");
9eaf5a
ec1cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
ccea09 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Outgoing ADK:\r\n");
8bae30 ¤   ¤   ¤   ¤   ¤
0f6b76 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseOutgoingADK)
744859 ¤   ¤   ¤   ¤   ¤   {
924476 ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%s\r\n", pConfig->szOutgoingADK);
f07173 ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceOutgoingADK)
f0520e ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szTemp, "\tEnforced\r\n\r\n");
787f8b ¤   ¤   ¤   ¤   ¤   ¤   else
d93c02 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szTemp, "\tNot Enforced\r\n\r\n");
3b1c89 ¤   ¤   ¤   ¤   ¤   }
504bd6 ¤   ¤   ¤   ¤   ¤   else
b6841a ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szTemp, "\t<none>\r\n\r\n");
b0af5a
6a1cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
1af7f5 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Enforce Remote ADK:\r\n");
7eae30 ¤   ¤   ¤   ¤   ¤
2148a6 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceRemoteADK)
4f0613 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tYes\r\n\r\n");
1e4bd6 ¤   ¤   ¤   ¤   ¤   else
094654 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tNo\r\n\r\n");
0caf5a
019e0c ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "PGPdisk ADK:\r\n");
6dae30 ¤   ¤   ¤   ¤   ¤
3f4431 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUseDiskADK)
6ad57e ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%s\r\n\r\n", pConfig->szDiskADK);
cf4bd6 ¤   ¤   ¤   ¤   ¤   else
--e671 000c024b57640110262 Page 3 of Review.cpp
86841a ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szTemp, "\t<none>\r\n\r\n");
96af5a
ab1cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
8a6ef7 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Enforce Minimum Passphrase "
2a0ea0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Length:\r\n");
a5af5a
7ced34 ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceMinChars)
9bc913 ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\tYes\t%d characters\r\n\r\n",
cbc3b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->nMinChars);
b34bd6 ¤   ¤   ¤   ¤   ¤   else
91acf5 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szTemp, "\tNo\r\n\r\n");
63af5a
801cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
cb6ef7 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Enforce Minimum Passphrase "
039a8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Quality:\r\n");
8eaf5a
37814c ¤   ¤   ¤   ¤   ¤   if (pConfig->bEnforceMinQuality)
ec905c ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\tYes\t%d%%\r\n\r\n",
48d92d ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->nMinQuality);
d04bd6 ¤   ¤   ¤   ¤   ¤   else
2dacf5 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szTemp, "\tNo\r\n\r\n");
f5af5a
881cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
14d2db ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Corporate Key:\r\n");
71af5a
ada7b9 ¤   ¤   ¤   ¤   ¤   if (pConfig->bAutoSignTrustCorp)
9b4859 ¤   ¤   ¤   ¤   ¤   {
3678d5 ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%s\r\n", pConfig->szCorpKey);
c63244 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szTemp, "\tAuto-Sign\r\n");
fb9e95 ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->bMetaIntroducerCorp)
46db7f ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szTemp, "\tMeta-Introducer\r\n");
9d4e42 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szTemp, "\r\n");
811c89 ¤   ¤   ¤   ¤   ¤   }
fa4bd6 ¤   ¤   ¤   ¤   ¤   else
8371fb ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t<none>\r\n\r\n");
95af5a
661cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
6eaf5a
39a7b9 ¤   ¤   ¤   ¤   ¤   if (pConfig->bAutoSignTrustCorp)
8b4859 ¤   ¤   ¤   ¤   ¤   {
1e41d0 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Encrypt to Keys Not Signed by "
ecb31c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Corporate Key:\r\n");
d3af5a
e885ff ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->bWarnNotCertByCorp)
be2efb ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tWarn\r\n\r\n");
877f8b ¤   ¤   ¤   ¤   ¤   ¤   else
73e92d ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tDo Not Warn\r\n\r\n");
381c89 ¤   ¤   ¤   ¤   ¤   }
04af5a
dacaef ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Designated Revoker key:\r\n");
6caf5a
c5a8df ¤   ¤   ¤   ¤   ¤   if (pConfig->bAutoAddRevoker)
45c329 ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%s\r\n\r\n",·
32dd2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szRevokerKey);
7e4bd6 ¤   ¤   ¤   ¤   ¤   else
c771fb ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t<none>\r\n\r\n");
68af5a
031cfa ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
0271cd ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Automatic Updates:\r\n");
f2af5a
1d724e ¤   ¤   ¤   ¤   ¤   if (pConfig->bUpdateTrustedIntroducers)
f24859 ¤   ¤   ¤   ¤   ¤   {
5ec1cf ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\tEvery %d days, "
d73729 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Trusted Introducers\r\n",·
be4891 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->nDaysUpdateTrustedIntroducers);
7aaf5a
ff4e67 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
3b1c89 ¤   ¤   ¤   ¤   ¤   }
86af5a
aa73c3 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUpdateAllKeys)
b04859 ¤   ¤   ¤   ¤   ¤   {
c0817a ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\tEvery %d days, All Keys\r\n\r\n",
--521d 00029fc299140110262 Page 4 of Review.cpp
da9ed0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->nDaysUpdateAllKeys);
88af5a
2f4e67 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
711c89 ¤   ¤   ¤   ¤   ¤   }
cf4bd6 ¤   ¤   ¤   ¤   ¤   else
ed996d ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\r\n");
38af5a
d4227a ¤   ¤   ¤   ¤   ¤   if (!pConfig->bUpdateAllKeys &&·
bbfab6 ¤   ¤   ¤   ¤   ¤   ¤   !pConfig->bUpdateTrustedIntroducers)
074047 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\t<none>\r\n\r\n");
1caf5a
a8ec85 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Key Generation:\r\n");
0aaf5a
e93d3b ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowKeyGen)
774859 ¤   ¤   ¤   ¤   ¤   {
eb8262 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tAllowed");
6194aa ¤   ¤   ¤   ¤   ¤   ¤
cfbecd ¤   ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowRSAKeyGen)
f67d7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tRSA Algorithm "
749f73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Enabled\r\n\r\n");
c97f8b ¤   ¤   ¤   ¤   ¤   ¤   else
857d7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tRSA Algorithm "
6a5a8e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "Disabled\r\n\r\n");
88af5a
05587b ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Minimum Key Generation Size:\r\n");
3681ba ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%d\r\n\r\n",·
bd49db ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->nMinKeySize);
094e67 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
f71c89 ¤   ¤   ¤   ¤   ¤   }
554bd6 ¤   ¤   ¤   ¤   ¤   else
d43e1f ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tNot Allowed\r\n\r\n");
56af5a
505e38 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Allow Conventional Encryption:\r\n");
99af5a
27c1dd ¤   ¤   ¤   ¤   ¤   if (pConfig->bAllowConventionalEncryption)
a90613 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tYes\r\n\r\n");
3c4bd6 ¤   ¤   ¤   ¤   ¤   else
9a4654 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\tNo\r\n\r\n");
87af5a
21d539 ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Message Header Comment:\r\n");
18af5a
886b3b ¤   ¤   ¤   ¤   ¤   if (pConfig->nCommentLength)
9b4859 ¤   ¤   ¤   ¤   ¤   {
db1bcf ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\t");
7f66de ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, pConfig->szComments);
9878a6 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\r\n\r\n");
511c89 ¤   ¤   ¤   ¤   ¤   }
0c4bd6 ¤   ¤   ¤   ¤   ¤   else
9a4047 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\t<none>\r\n\r\n");
4caf5a
4e412b ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "Pre-Loaded Keys:\r\n");
78af5a
7b5186 ¤   ¤   ¤   ¤   ¤   if (pConfig->defaultKeySet != NULL)
494859 ¤   ¤   ¤   ¤   ¤   {
1a83b3 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyListRef¤  keyList;
2e91b5 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyIterRef¤  keyIter;
93a434 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyRef¤  ¤   key;
651d59 ¤   ¤   ¤   ¤   ¤   ¤   PGPUInt32¤  ¤   nLength;
453ba0 ¤   ¤   ¤   ¤   ¤   ¤   char *¤ ¤   ¤   szUserID[kPGPMaxUserIDSize+1];
b4af5a
4d36b9 ¤   ¤   ¤   ¤   ¤   ¤   PGPOrderKeySet(pConfig->defaultKeySet,
b0c6a3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPUserIDOrdering, &keyList);
599caa ¤   ¤   ¤   ¤   ¤   ····PGPNewKeyIter(keyList, &keyIter);
d8783f ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyIterNext(keyIter, &key);
cf6370 ¤   ¤   ¤   ¤   ¤   ¤   while (key)
288fec ¤   ¤   ¤   ¤   ¤   ¤   {
dcc878 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer(key,
75c8b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMaxUserIDSize, (char*)szUserID,
889b73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &nLength);
fcaf5a
3fdb0b ¤   ¤   ¤   ¤   ¤   ¤   ¤   wsprintf(szTemp, "\t%s\r\n", szUserID);
291d7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, szTemp);
--fb7e 001c324b3c040110262 Page 5 of Review.cpp
4b7f04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyIterNext(keyIter, &key);
bfdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
8caf5a
9e7c1c ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeyIter(keyIter);
57ab15 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeyList(keyList);
4d996d ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\r\n");
c81c89 ¤   ¤   ¤   ¤   ¤   }
544bd6 ¤   ¤   ¤   ¤   ¤   else
564047 ¤   ¤   ¤   ¤   ¤   ¤   strcat(szPanel, "\t<none>\r\n\r\n");
65af5a
504e8e ¤   ¤   ¤   ¤   ¤   SetDlgItemText(hwndDlg, IDC_PANEL, szPanel);
766611 ¤   ¤   ¤   ¤   ¤   free(szPanel);
d64149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ae14c3 ¤   ¤   ¤   ¤   ¤   break;
b32613 ¤   ¤   ¤   ¤   }
45af5a
426122 ¤   ¤   ¤   case PSN_HELP:
9972c3 ¤   ¤   ¤   ¤   {
22f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
9b14c3 ¤   ¤   ¤   ¤   ¤   break;
9d2613 ¤   ¤   ¤   ¤   }
67af5a
038f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
7972c3 ¤   ¤   ¤   ¤   {
7b6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
5c014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
5414c3 ¤   ¤   ¤   ¤   ¤   break;
592613 ¤   ¤   ¤   ¤   }
71a3a6 ¤   ¤   ¤   }
0187c7 ¤   ¤   ¤
57cdcb ¤   ¤   ¤   break;
d80fe4 ¤   ¤   }
ee9371 ¤   }
84af5a
f248b1 ¤   return(bReturnCode);
d5efe6 }
d6af5a
f67e4d /*__Editor_settings____
e6af5a
2e4126 ¤   Local Variables:
997b17 ¤   tab-width: 4
060e6c ¤   End:
165f8c ¤   vi: ts=4 sw=4
6d9e9b ¤   vim: si
c3d062 _____________________*/
--6bf1 0002e14fb3340110263 Page 1 of Revoker.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
31cfe9 ¤   $Id: Revoker.cpp,v 1.1.8.1 1998/11/12 03:13:13 heller Exp $
e5f7f7 ____________________________________________________________________________*/
d7af5a
965655 #include <windows.h>
73fb83 #include "PGPadmin.h"
8690fb #include <commctrl.h>
df8031 #include "resource.h"
d83bb4 #include "Utils.h"
6f0d08 #include "pgpMem.h"
d77528 #include "pgpImage.h"
f2af5a
42b779 #define ID_TIMER¤   42
0aaf5a
a4afc0 static BOOL bNextEnabled = FALSE;
f6af5a
6b5b86 BOOL CALLBACK RevokerDlgProc(HWND hwndDlg,·
a00bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
71d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
84a887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
72bb36 {
c61d63 ¤   BOOL¤   ¤   ¤   bReturnCode¤= FALSE;
368ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
08af5a
1b6357 ¤   g_hCurrentDlgWnd = hwndDlg;
20af5a
879450 ¤   if (uMsg != WM_INITDIALOG)
3ee72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
eeaf5a
08c08d ¤   switch(uMsg)
b0c7a1 ¤   {
442940 ¤   case WM_INITDIALOG:
e65b34 ¤   ¤   {
b3afc0 ¤   ¤   ¤   RECT rc;
6c313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
e2af5a
94015a ¤   ¤   ¤   // center dialog on screen
2bd4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
1a3d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
ba0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
e7004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
54f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
deaf5a
1f3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
50ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
06cdcb ¤   ¤   ¤   break;
000fe4 ¤   ¤   }
441b52 ¤   ¤
5393f9 ¤   case WM_PAINT:
42c334 ¤   ¤   if (pConfig->hPalette)
e55b34 ¤   ¤   {
77f431 ¤   ¤   ¤   PAINTSTRUCT ps;
a960df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
1a4fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
cd9ffe ¤   ¤   ¤   RealizePalette (hDC);
99438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
230fe0 ¤   ¤   ¤   bReturnCode = TRUE;
c40fe4 ¤   ¤   }
642f68 ¤   ¤   break;
071b52 ¤   ¤
bdc93c ¤   case WM_NOTIFY:
e05b34 ¤   ¤   {
f7a08b ¤   ¤   ¤   LPNMHDR pnmh;
33af5a
8c2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
8eb7b0 ¤   ¤   ¤   switch(pnmh->code)
2ef776 ¤   ¤   ¤   {
--0415 000dfb9290740110263 Page 2 of Revoker.cpp
d566bc ¤   ¤   ¤   case PSN_SETACTIVE:
2972c3 ¤   ¤   ¤   ¤   {
367182 ¤   ¤   ¤   ¤   ¤   // Initialize window
54bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
f4c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
f3af5a
cd9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
84670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
95af5a
50a8df ¤   ¤   ¤   ¤   ¤   if (pConfig->bAutoAddRevoker)
5c042b ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENABLEREVOKER,·
a294bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
4e4bd6 ¤   ¤   ¤   ¤   ¤   else
fd042b ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_ENABLEREVOKER,·
5dd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
ecaf5a
884149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c314c3 ¤   ¤   ¤   ¤   ¤   break;
7c2613 ¤   ¤   ¤   ¤   }
a4af5a
c2d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
8572c3 ¤   ¤   ¤   ¤   {
9d66b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
5a14c3 ¤   ¤   ¤   ¤   ¤   break;
e52613 ¤   ¤   ¤   ¤   }
1faf5a
4949a1 ¤   ¤   ¤   case PSN_WIZBACK:
1f72c3 ¤   ¤   ¤   ¤   {
5514df ¤   ¤   ¤   ¤   ¤   // Determine if we should go to corp key selection
dacf87 ¤   ¤   ¤   ¤   ¤   // or skip to corporate key options
f2af5a
dd07c2 ¤   ¤   ¤   ¤   ¤   if (!pConfig->bAutoSignTrustCorp)
8b6c67 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CORPKEY);
7daf5a
374149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
9614c3 ¤   ¤   ¤   ¤   ¤   break;
4f2613 ¤   ¤   ¤   ¤   }
d9af5a
5a99a3 ¤   ¤   ¤   case PSN_WIZNEXT:
5372c3 ¤   ¤   ¤   ¤   {
fd4427 ¤   ¤   ¤   ¤   ¤   // Determine if we should go to revoker key selection
4c291a ¤   ¤   ¤   ¤   ¤   // or skip to next page
89af5a
660966 ¤   ¤   ¤   ¤   ¤   if (!pConfig->bAutoAddRevoker)
7dcf31 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_KEYGEN);
94af5a
634149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
4d14c3 ¤   ¤   ¤   ¤   ¤   break;
352613 ¤   ¤   ¤   ¤   }
56af5a
126122 ¤   ¤   ¤   case PSN_HELP:
bf72c3 ¤   ¤   ¤   ¤   {
84f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
aa14c3 ¤   ¤   ¤   ¤   ¤   break;
d92613 ¤   ¤   ¤   ¤   }
96af5a
e28f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
0872c3 ¤   ¤   ¤   ¤   {
406b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
7b014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
1514c3 ¤   ¤   ¤   ¤   ¤   break;
c12613 ¤   ¤   ¤   ¤   }
dea3a6 ¤   ¤   ¤   }
c987c7 ¤   ¤   ¤
4dcdcb ¤   ¤   ¤   break;
960fe4 ¤   ¤   }
46af5a
973fcf ¤   case WM_COMMAND:
ca72a4 ¤   ¤   switch (LOWORD(wParam))
8e5b34 ¤   ¤   {
d35610 ¤   ¤   case IDC_ENABLEREVOKER:
dff776 ¤   ¤   ¤   {
--5c5a 000901dcae640110263 Page 3 of Revoker.cpp
04ece5 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_ENABLEREVOKER) ==·
ee2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
8272c3 ¤   ¤   ¤   ¤   {
fae1cd ¤   ¤   ¤   ¤   ¤   pConfig->bAutoAddRevoker = TRUE;
e62613 ¤   ¤   ¤   ¤   }
d8fa07 ¤   ¤   ¤   ¤   else
8572c3 ¤   ¤   ¤   ¤   {
2c2c4b ¤   ¤   ¤   ¤   ¤   pConfig->bAutoAddRevoker = FALSE;
112613 ¤   ¤   ¤   ¤   }
51af5a
82841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
85f622 ¤   ¤   ¤   ¤   break;
e7a3a6 ¤   ¤   ¤   }
6f0fe4 ¤   ¤   }
43af5a
a22f68 ¤   ¤   break;
ed9371 ¤   }
13af5a
3c48b1 ¤   return(bReturnCode);
d2efe6 }
54af5a
a2af5a
eabb71 BOOL CALLBACK RevokerSelectDlgProc(HWND hwndDlg,·
1f218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
0c2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
9f75ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
e9bb36 {
110f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
868ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
613c96 ¤   HWND hList;
28af5a
816357 ¤   g_hCurrentDlgWnd = hwndDlg;
beaf5a
779450 ¤   if (uMsg != WM_INITDIALOG)
7ae72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
b7af5a
f6790f ¤   hList = GetDlgItem(hwndDlg, IDC_REVOKER_ID);
b5af5a
fec08d ¤   switch(uMsg)
f6c7a1 ¤   {
1a2940 ¤   case WM_INITDIALOG:
6c5b34 ¤   ¤   {
26afc0 ¤   ¤   ¤   RECT rc;
d2313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
e0af5a
59015a ¤   ¤   ¤   // center dialog on screen
a9d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
933d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
750971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
51004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
c4f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
f0af5a
b23970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
e3ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
2eaf5a
cecbc0 ¤   ¤   ¤   ShowKeyring(hwndDlg, IDC_REVOKER_ID, pConfig->pgpContext,·
0819ad ¤   ¤   ¤   ¤   NULL, FALSE, TRUE, FALSE, TRUE);
aa021f ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
11cdcb ¤   ¤   ¤   break;
220fe4 ¤   ¤   }
acaf5a
1c6b08 ¤   case WM_DESTROY:
83ba4c ¤   ¤   FreeKeyring(hwndDlg, IDC_REVOKER_ID);
522f68 ¤   ¤   break;
bcaf5a
d593f9 ¤   case WM_PAINT:
aac334 ¤   ¤   if (pConfig->hPalette)
fa5b34 ¤   ¤   {
e3f431 ¤   ¤   ¤   PAINTSTRUCT ps;
5060df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
064fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
909ffe ¤   ¤   ¤   RealizePalette (hDC);
--762f 000eab4cf8f40110263 Page 4 of Revoker.cpp
4a438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
f70fe0 ¤   ¤   ¤   bReturnCode = TRUE;
a40fe4 ¤   ¤   }
2c2f68 ¤   ¤   break;
be1b52 ¤   ¤
bdc93c ¤   case WM_NOTIFY:
c15b34 ¤   ¤   {
fca08b ¤   ¤   ¤   LPNMHDR pnmh;
f4af5a
862b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
9bb7b0 ¤   ¤   ¤   switch(pnmh->code)
74f776 ¤   ¤   ¤   {
f966bc ¤   ¤   ¤   case PSN_SETACTIVE:
af72c3 ¤   ¤   ¤   ¤   {
8a4a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
1caf5a
a27182 ¤   ¤   ¤   ¤   ¤   // Initialize window
3d5c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
98abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
b14859 ¤   ¤   ¤   ¤   ¤   {
54e898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
aaba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
283cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
7f1c89 ¤   ¤   ¤   ¤   ¤   }
324bd6 ¤   ¤   ¤   ¤   ¤   else
644859 ¤   ¤   ¤   ¤   ¤   {
a0e898 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
2e8e3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
08d359 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
de1c89 ¤   ¤   ¤   ¤   ¤   }
b4af5a
759908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
44670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
9faf5a
00c394 ¤   ¤   ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
894149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
f614c3 ¤   ¤   ¤   ¤   ¤   break;
e82613 ¤   ¤   ¤   ¤   }
56af5a
38d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
b272c3 ¤   ¤   ¤   ¤   {
6d197b ¤   ¤   ¤   ¤   ¤   KillTimer(hwndDlg, ID_TIMER);
ff4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
0c14c3 ¤   ¤   ¤   ¤   ¤   break;
212613 ¤   ¤   ¤   ¤   }
d3af5a
0a99a3 ¤   ¤   ¤   case PSN_WIZNEXT:
6572c3 ¤   ¤   ¤   ¤   {
dc4a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
c65283 ¤   ¤   ¤   ¤   ¤   LV_ITEM lviKey;
f5e438 ¤   ¤   ¤   ¤   ¤   char *szKeyID;
aabd59 ¤   ¤   ¤   ¤   ¤   char szUserID[kPGPMaxUserIDSize+1];
beaf5a
e9ee73 ¤   ¤   ¤   ¤   ¤   if (pConfig->szRevokerKeyID != NULL)
5e4859 ¤   ¤   ¤   ¤   ¤   {
971bdd ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szRevokerKeyID);
21f8ba ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szRevokerKeyID = NULL;
be1c89 ¤   ¤   ¤   ¤   ¤   }
55af5a
bb9356 ¤   ¤   ¤   ¤   ¤   if (pConfig->szRevokerKey != NULL)
6d4859 ¤   ¤   ¤   ¤   ¤   {
afe4a7 ¤   ¤   ¤   ¤   ¤   ¤   pgpFree(pConfig->szRevokerKey);
d63e4b ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szRevokerKey = NULL;
141c89 ¤   ¤   ¤   ¤   ¤   }
f3af5a
8666b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
115c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
f2abcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
fe4859 ¤   ¤   ¤   ¤   ¤   {
8d2902 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
e1b282 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iItem = nIndex;
ea9588 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.iSubItem = 0;
--d552 000c983089840110263 Page 5 of Revoker.cpp
b377b4 ¤   ¤   ¤   ¤   ¤   ¤   lviKey.pszText = szUserID;
d59c1d ¤   ¤   ¤   ¤   ¤   ¤   lviKey.cchTextMax = kPGPMaxUserIDSize;
942337 ¤   ¤   ¤   ¤   ¤   ¤   ListView_GetItem(hList, &lviKey);
2c9e35 ¤   ¤   ¤   ¤   ¤   ¤   szKeyID = (char *) lviKey.lParam;
f3af5a
ad848b ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szRevokerKeyID =·
d1cd77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szKeyID)+1);
e174b5 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szRevokerKeyID, szKeyID);
d1af5a
a4d768 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->szRevokerKey =·
7fe764 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pgpAlloc(strlen(szUserID)+1);
d8c3a0 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(pConfig->szRevokerKey, szUserID);
85af5a
4940ef ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_RSAPUBKEY)
09f4e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->revokerKeyType =·
a26a91 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA;
07c4dd ¤   ¤   ¤   ¤   ¤   ¤   if (lviKey.iImage == IDX_DSAPUBKEY)
5cf4e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pConfig->revokerKeyType =·
57e549 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_DSA;
4f1c89 ¤   ¤   ¤   ¤   ¤   }
36af5a
254149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
5214c3 ¤   ¤   ¤   ¤   ¤   break;
792613 ¤   ¤   ¤   ¤   }
68af5a
1b6122 ¤   ¤   ¤   case PSN_HELP:
0972c3 ¤   ¤   ¤   ¤   {
c6f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
ab14c3 ¤   ¤   ¤   ¤   ¤   break;
912613 ¤   ¤   ¤   ¤   }
a0af5a
8c8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
6972c3 ¤   ¤   ¤   ¤   {
036b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
f3014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
2c14c3 ¤   ¤   ¤   ¤   ¤   break;
5b2613 ¤   ¤   ¤   ¤   }
d9af5a
7db108 ¤   ¤   ¤   case NM_CLICK:
2831c1 ¤   ¤   ¤   case NM_RCLICK:
70168c ¤   ¤   ¤   case NM_DBLCLK:
fc4dc1 ¤   ¤   ¤   case NM_RDBLCLK:
2cb4e2 ¤   ¤   ¤   ¤   if (pnmh->idFrom == IDC_REVOKER_ID)
f272c3 ¤   ¤   ¤   ¤   {
304a74 ¤   ¤   ¤   ¤   ¤   int nIndex;
4faf5a
145c1c ¤   ¤   ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
4babcb ¤   ¤   ¤   ¤   ¤   if (nIndex > -1)
d14859 ¤   ¤   ¤   ¤   ¤   {
3db2ca ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
72ba2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
163cb5 ¤   ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
131c89 ¤   ¤   ¤   ¤   ¤   }
e44149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
192613 ¤   ¤   ¤   ¤   }
a7f622 ¤   ¤   ¤   ¤   break;
e8a3a6 ¤   ¤   ¤   }
2b87c7 ¤   ¤   ¤
35cdcb ¤   ¤   ¤   break;
230fe4 ¤   ¤   }
5baf5a
f5e60b ¤   case WM_TIMER:
8c5b34 ¤   ¤   {
70114f ¤   ¤   ¤   int nIndex;
d1af5a
47c6b0 ¤   ¤   ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
7b2df5 ¤   ¤   ¤   if (nIndex > -1)
41f776 ¤   ¤   ¤   {
485454 ¤   ¤   ¤   ¤   if (!bNextEnabled)
5d72c3 ¤   ¤   ¤   ¤   {
61e766 ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
c9c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
--eda3 0011bbbe76840110263 Page 6 of Revoker.cpp
673a0d ¤   ¤   ¤   ¤   ¤   bNextEnabled = TRUE;
3a2613 ¤   ¤   ¤   ¤   }
b6a3a6 ¤   ¤   ¤   }
8739bb ¤   ¤   ¤   else if (bNextEnabled)
14f776 ¤   ¤   ¤   {
e77127 ¤   ¤   ¤   ¤   SendMessage(GetParent(hwndDlg),
e7c577 ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
65d672 ¤   ¤   ¤   ¤   bNextEnabled = FALSE;
e2a3a6 ¤   ¤   ¤   }
a8af5a
bb0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
22196f ¤   ¤   ¤   SetTimer(hwndDlg, ID_TIMER, 500, NULL);
bbcdcb ¤   ¤   ¤   break;
290fe4 ¤   ¤   }
379371 ¤   }
45af5a
0848b1 ¤   return(bReturnCode);
eeefe6 }
40af5a
417e4d /*__Editor_settings____
21af5a
da4126 ¤   Local Variables:
2c7b17 ¤   tab-width: 4
8e0e6c ¤   End:
955f8c ¤   vi: ts=4 sw=4
939e9b ¤   vim: si
1bd062 _____________________*/
--e5f3 00091f3f30d40110264 Page 1 of ServerUpdates.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8a931b ¤   $Id: ServerUpdates.cpp,v 1.1.8.1 1998/11/12 03:13:14 heller Exp $
7df7f7 ____________________________________________________________________________*/
6faf5a
c05655 #include <windows.h>
e6fb83 #include "PGPadmin.h"
a890fb #include <commctrl.h>
208031 #include "resource.h"
e2af5a
5d7b14 BOOL CALLBACK ServerUpdatesDlgProc(HWND hwndDlg,·
3b218c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
5c2ec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
ed75ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)
81bb36 {
c40f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
658ce8 ¤   pgpConfigInfo *¤pConfig¤¤   = NULL;
52af5a
456357 ¤   g_hCurrentDlgWnd = hwndDlg;
cdaf5a
459450 ¤   if (uMsg != WM_INITDIALOG)
35e72e ¤   ¤   pConfig = (pgpConfigInfo *) GetWindowLong(hwndDlg, GWL_USERDATA);
f6af5a
5cc08d ¤   switch(uMsg)
8dc7a1 ¤   {
ff2940 ¤   case WM_INITDIALOG:
8e5b34 ¤   ¤   {
e1afc0 ¤   ¤   ¤   RECT rc;
ab313b ¤   ¤   ¤   PROPSHEETPAGE *ppspConfig = (PROPSHEETPAGE *) lParam;
d4af5a
48015a ¤   ¤   ¤   // center dialog on screen
04d4e1 ¤   ¤   ¤   GetWindowRect(GetParent(hwndDlg), &rc);
933d5e ¤   ¤   ¤   SetWindowPos(GetParent(hwndDlg), NULL,
110971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
87004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
f4f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
a1af5a
2c3970 ¤   ¤   ¤   pConfig = (pgpConfigInfo *) ppspConfig->lParam;
40ad17 ¤   ¤   ¤   SetWindowLong(hwndDlg, GWL_USERDATA, (LPARAM) pConfig);
2acdcb ¤   ¤   ¤   break;
550fe4 ¤   ¤   }
26af5a
3893f9 ¤   case WM_PAINT:
45c334 ¤   ¤   if (pConfig->hPalette)
6e5b34 ¤   ¤   {
09f431 ¤   ¤   ¤   PAINTSTRUCT ps;
2a60df ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwndDlg, &ps);
524fb6 ¤   ¤   ¤   SelectPalette (hDC, pConfig->hPalette, FALSE);
2f9ffe ¤   ¤   ¤   RealizePalette (hDC);
cf438b ¤   ¤   ¤   EndPaint (hwndDlg, &ps);
d10fe0 ¤   ¤   ¤   bReturnCode = TRUE;
ed0fe4 ¤   ¤   }
eb2f68 ¤   ¤   break;
381b52 ¤   ¤
a4c93c ¤   case WM_NOTIFY:
395b34 ¤   ¤   {
90a08b ¤   ¤   ¤   LPNMHDR pnmh;
ceaf5a
092b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
6cb7b0 ¤   ¤   ¤   switch(pnmh->code)
d1f776 ¤   ¤   ¤   {
da66bc ¤   ¤   ¤   case PSN_SETACTIVE:
1172c3 ¤   ¤   ¤   ¤   {
717320 ¤   ¤   ¤   ¤   ¤   char szBuffer[4];
35af5a
747182 ¤   ¤   ¤   ¤   ¤   // Initialize window
53bd34 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwndDlg),
91c365 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
--6778 000a37668d640110264 Page 2 of ServerUpdates.cpp
e0af5a
7f9908 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hwndDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
b3670a ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pConfig->hBitmap);
e2af5a
3fc5e2 ¤   ¤   ¤   ¤   ¤   SendMessage(GetDlgItem(hwndDlg, IDC_ALLSPIN),·
29c8a9 ¤   ¤   ¤   ¤   ¤   ¤   UDM_SETRANGE, 0, MAKELONG(999, 1));
33496b ¤   ¤   ¤   ¤   ¤   SendMessage(GetDlgItem(hwndDlg, IDC_TRUSTEDSPIN),·
4fc8a9 ¤   ¤   ¤   ¤   ¤   ¤   UDM_SETRANGE, 0, MAKELONG(999, 1));
efaf5a
5373c3 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUpdateAllKeys)
ae4859 ¤   ¤   ¤   ¤   ¤   {
060586 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_UPDATEALL,·
e794bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
e6bb03 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLDAYS),
531dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
5e1c89 ¤   ¤   ¤   ¤   ¤   }
da4bd6 ¤   ¤   ¤   ¤   ¤   else
004859 ¤   ¤   ¤   ¤   ¤   {
ff0586 ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_UPDATEALL,·
efd06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
61bb03 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLDAYS),
457f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
b71c89 ¤   ¤   ¤   ¤   ¤   }
d1af5a
d0724e ¤   ¤   ¤   ¤   ¤   if (pConfig->bUpdateTrustedIntroducers)
3f4859 ¤   ¤   ¤   ¤   ¤   {
84f56d ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_UPDATETRUSTED,·
e994bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
7fd020 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_TRUSTEDDAYS),
361dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
221c89 ¤   ¤   ¤   ¤   ¤   }
f64bd6 ¤   ¤   ¤   ¤   ¤   else
a54859 ¤   ¤   ¤   ¤   ¤   {
1ff56d ¤   ¤   ¤   ¤   ¤   ¤   CheckDlgButton(hwndDlg, IDC_UPDATETRUSTED,·
cad06f ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_UNCHECKED);
aad020 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_TRUSTEDDAYS),
fe7f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
761c89 ¤   ¤   ¤   ¤   ¤   }
16af5a
a43292 ¤   ¤   ¤   ¤   ¤   wsprintf(szBuffer, "%d", pConfig->nDaysUpdateAllKeys);
91c643 ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_ALLDAYS),·
55fbe7 ¤   ¤   ¤   ¤   ¤   ¤   szBuffer);
62af5a
ea3f73 ¤   ¤   ¤   ¤   ¤   wsprintf(szBuffer, "%d",·
40c2d4 ¤   ¤   ¤   ¤   ¤   ¤   pConfig->nDaysUpdateTrustedIntroducers);
70ece7 ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_TRUSTEDDAYS),·
f7fbe7 ¤   ¤   ¤   ¤   ¤   ¤   szBuffer);
35af5a
bb4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
fa14c3 ¤   ¤   ¤   ¤   ¤   break;
442613 ¤   ¤   ¤   ¤   }
08af5a
52d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
4f72c3 ¤   ¤   ¤   ¤   {
4d14c3 ¤   ¤   ¤   ¤   ¤   break;
b52613 ¤   ¤   ¤   ¤   }
c2af5a
6b49a1 ¤   ¤   ¤   case PSN_WIZBACK:
4472c3 ¤   ¤   ¤   ¤   {
9314c3 ¤   ¤   ¤   ¤   ¤   break;
d52613 ¤   ¤   ¤   ¤   }
bcaf5a
0b99a3 ¤   ¤   ¤   case PSN_WIZNEXT:
1d72c3 ¤   ¤   ¤   ¤   {
89fdba ¤   ¤   ¤   ¤   ¤   char szErrorMsg[255];
3eea46 ¤   ¤   ¤   ¤   ¤   char szTitle[255];
9075ac ¤   ¤   ¤   ¤   ¤   BOOL bError = FALSE;
6daf5a
6b4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
4915f5 ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
6caf5a
a3a809 ¤   ¤   ¤   ¤   ¤   // Check data validity
--685c 00024f4f69e40110264 Page 3 of ServerUpdates.cpp
e0af5a
a573c3 ¤   ¤   ¤   ¤   ¤   if (pConfig->bUpdateAllKeys)
e04859 ¤   ¤   ¤   ¤   ¤   {
a51814 ¤   ¤   ¤   ¤   ¤   ¤   if ((pConfig->nDaysUpdateAllKeys < 1) ||·
ba67ac ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pConfig->nDaysUpdateAllKeys > 999))
818fec ¤   ¤   ¤   ¤   ¤   ¤   {
14fed8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_E_DAYSRANGE,·
a26b2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szErrorMsg, 254);
fd458b ¤   ¤   ¤   ¤   ¤   ¤   ¤   bError = TRUE;
afdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
fa1c89 ¤   ¤   ¤   ¤   ¤   }
b9af5a
05724e ¤   ¤   ¤   ¤   ¤   if (pConfig->bUpdateTrustedIntroducers)
554859 ¤   ¤   ¤   ¤   ¤   {
7854b7 ¤   ¤   ¤   ¤   ¤   ¤   if ((pConfig->nDaysUpdateTrustedIntroducers < 1) ||·
141d60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pConfig->nDaysUpdateTrustedIntroducers > 999))
a68fec ¤   ¤   ¤   ¤   ¤   ¤   {
bcfed8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LoadString(g_hInstance, IDS_E_DAYSRANGE,·
a26b2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szErrorMsg, 254);
89458b ¤   ¤   ¤   ¤   ¤   ¤   ¤   bError = TRUE;
91db3c ¤   ¤   ¤   ¤   ¤   ¤   }
611c89 ¤   ¤   ¤   ¤   ¤   }
e7af5a
9bc530 ¤   ¤   ¤   ¤   ¤   if (bError)
b34859 ¤   ¤   ¤   ¤   ¤   {
dce909 ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(hwndDlg, szErrorMsg, szTitle, MB_OK);
7309b6 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
571c89 ¤   ¤   ¤   ¤   ¤   }
20af5a
2814c3 ¤   ¤   ¤   ¤   ¤   break;
722613 ¤   ¤   ¤   ¤   }
cdaf5a
e16122 ¤   ¤   ¤   case PSN_HELP:
4c72c3 ¤   ¤   ¤   ¤   {
d8f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
0014c3 ¤   ¤   ¤   ¤   ¤   break;
f22613 ¤   ¤   ¤   ¤   }
dcaf5a
508f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
aa72c3 ¤   ¤   ¤   ¤   {
b26b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
bc014a ¤   ¤   ¤   ¤   ¤   g_bGotReloadMsg = FALSE;
6c14c3 ¤   ¤   ¤   ¤   ¤   break;
012613 ¤   ¤   ¤   ¤   }
eea3a6 ¤   ¤   ¤   }
b687c7 ¤   ¤   ¤
57cdcb ¤   ¤   ¤   break;
650fe4 ¤   ¤   }
e5af5a
ee3fcf ¤   case WM_COMMAND:
6c7676 ¤   ¤   if (pConfig == NULL)
29cdcb ¤   ¤   ¤   break;
39af5a
c572a4 ¤   ¤   switch (LOWORD(wParam))
ab5b34 ¤   ¤   {
10410e ¤   ¤   case IDC_UPDATEALL:
fcf776 ¤   ¤   ¤   {
f6a977 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_UPDATEALL) ==·
a72a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
0e72c3 ¤   ¤   ¤   ¤   {
3ef017 ¤   ¤   ¤   ¤   ¤   pConfig->bUpdateAllKeys = TRUE;
3ba88f ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLDAYS),
b591ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
052613 ¤   ¤   ¤   ¤   }
39fa07 ¤   ¤   ¤   ¤   else
1f72c3 ¤   ¤   ¤   ¤   {
6a558d ¤   ¤   ¤   ¤   ¤   pConfig->bUpdateAllKeys = FALSE;
f6a88f ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_ALLDAYS),
eaf481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
202613 ¤   ¤   ¤   ¤   }
21af5a
24841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
--c4fc 0019db2336e40110264 Page 4 of ServerUpdates.cpp
72f622 ¤   ¤   ¤   ¤   break;
36a3a6 ¤   ¤   ¤   }
0eaf5a
e4af86 ¤   ¤   case IDC_UPDATETRUSTED:
68f776 ¤   ¤   ¤   {
dd599a ¤   ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_UPDATETRUSTED) ==·
bf2a15 ¤   ¤   ¤   ¤   ¤   BST_CHECKED)
e672c3 ¤   ¤   ¤   ¤   {
737003 ¤   ¤   ¤   ¤   ¤   pConfig->bUpdateTrustedIntroducers = TRUE;
0c008b ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_TRUSTEDDAYS),
6b91ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
3b2613 ¤   ¤   ¤   ¤   }
55fa07 ¤   ¤   ¤   ¤   else
f672c3 ¤   ¤   ¤   ¤   {
8103a8 ¤   ¤   ¤   ¤   ¤   pConfig->bUpdateTrustedIntroducers = FALSE;
4a008b ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwndDlg, IDC_TRUSTEDDAYS),
4bf481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
222613 ¤   ¤   ¤   ¤   }
ddaf5a
e5841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
e4f622 ¤   ¤   ¤   ¤   break;
e7a3a6 ¤   ¤   ¤   }
c5af5a
c8f782 ¤   ¤   case IDC_ALLDAYS:
98f776 ¤   ¤   ¤   {
b89c53 ¤   ¤   ¤   ¤   char szBuffer[4];
7daf5a
9f87a8 ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_ALLDAYS),·
799599 ¤   ¤   ¤   ¤   ¤   szBuffer, 4);
6bd254 ¤   ¤   ¤   ¤   pConfig->nDaysUpdateAllKeys = atoi(szBuffer);
67841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
09f622 ¤   ¤   ¤   ¤   break;
94a3a6 ¤   ¤   ¤   }
e7af5a
398a90 ¤   ¤   case IDC_TRUSTEDDAYS:
51f776 ¤   ¤   ¤   {
2e9c53 ¤   ¤   ¤   ¤   char szBuffer[4];
64af5a
11c4d2 ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hwndDlg, IDC_TRUSTEDDAYS),·
a09599 ¤   ¤   ¤   ¤   ¤   szBuffer, 4);
bdca2d ¤   ¤   ¤   ¤   pConfig->nDaysUpdateTrustedIntroducers = atoi(szBuffer);
b3841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
52f622 ¤   ¤   ¤   ¤   break;
f0a3a6 ¤   ¤   ¤   }
8d0fe4 ¤   ¤   }
b2af5a
662f68 ¤   ¤   break;
399371 ¤   }
c6af5a
c548b1 ¤   return(bReturnCode);
92efe6 }
c4af5a
807e4d /*__Editor_settings____
35af5a
284126 ¤   Local Variables:
527b17 ¤   tab-width: 4
150e6c ¤   End:
db5f8c ¤   vi: ts=4 sw=4
da9e9b ¤   vim: si
9dd062 _____________________*/
--8c80 00050f93d4640110265 Page 1 of Utils.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c3a8c8 ¤   $Id: Utils.cpp,v 1.31.8.1 1998/11/12 03:13:14 heller Exp $
3af7f7 ____________________________________________________________________________*/
c3af5a
2a5655 #include <windows.h>
d5fb83 #include "PGPadmin.h"
b890fb #include <commctrl.h>
4e8031 #include "resource.h"
b1e2ff #include "pgpConfig.h"
cc2f8d #include "pgpErrors.h"
109f63 #include "pgpEncode.h"
aee82c #include "pgpPubTypes.h"
844919 #include "pgpUtilities.h"
3091b9 #include "pgpSDKPrefs.h"
62a076 #include "pgpKeys.h"
300d08 #include "pgpMem.h"
6d5ab2 #include "PGPcl.h"
2d7528 #include "pgpImage.h"
6681a4 #include "pgpBuildFlags.h"
313991 #include "pgpAdminPrefs.h"
b6c97b #include "pgpClientPrefs.h"
a13bb4 #include "Utils.h"
98af5a
fbaf5a
d2ad7f void ShowKeyring(HWND hWnd,·
d89205 ¤   ¤   ¤   ¤   ·int nListCtrl,·
8fc4ec ¤   ¤   ¤   ¤   ·PGPContextRef pgpContext,
140291 ¤   ¤   ¤   ¤   ·PGPKeySetRef onlyThisKeySet,
dcabf3 ¤   ¤   ¤   ¤   ·PGPBoolean bShowRSA,·
f491fb ¤   ¤   ¤   ¤   ·PGPBoolean bShowDH,
463c19 ¤   ¤   ¤   ¤   ·PGPBoolean bMustEncrypt,
7eaa70 ¤   ¤   ¤   ¤   ·PGPBoolean bMustSign)
e3bb36 {
b34068 ····PGPKeyRef ······newKey¤ ¤   = NULL;
6c6a88 ¤   PGPKeyID¤   ¤   newKeyID;
a60c05 ¤   PGPSubKeyRef¤   newSubKey¤  = NULL;
48c1f9 ····PGPError ·······err;
97b75a ¤   PGPKeySetRef¤   userKeySet¤ = NULL;
4a9410 ····PGPKeyListRef¤  klist;
a40528 ····PGPKeyIterRef¤  kiter;
5aaf5a
f9962f ¤   unsigned char¤  szUserID[kPGPMaxUserIDSize+1];
01479f ¤   char¤   ¤   ¤   szTempKeyID[kPGPMaxKeyIDStringSize+1];
01bdfb ¤   char¤   ¤   ¤   szSize[64];
bb5c97 ¤   char¤   ¤   ¤   szCreation[64];
0f2f48 ¤   char¤   ¤   ¤   szTitle[255];
16dba5 ¤   UINT¤   ¤   ¤   nLength;
f9429d ¤   HWND¤   ¤   ¤   hList;
3a07aa ¤   HDC¤¤   ¤   ¤   hDC;
05a40e ¤   int¤¤   ¤   ¤   iNumBits;
f44a5d ¤   LV_ITEM¤¤   ¤   lviKey;
e1efe9 ¤   LV_COLUMN¤  ¤   lvcKey;
ee8e0f ¤   UINT¤   ¤   ¤   nItem;
7f7cd5 ¤   HIMAGELIST¤ ¤   hImages;
9f91d1 ¤   HBITMAP¤¤   ¤   hBmp;
760e16 ¤   PGPInt32¤   ¤   nSignSize;
3c1c3e ¤   PGPInt32¤   ¤   nEncryptSize;
f5cdaf ¤   PGPTime¤¤   ¤   tCreation;
3c65e3 ¤   PGPUInt16¤  ¤   year, month, day;
83695a ¤   PGPBoolean¤ ¤   bIsRevoked;
2837f1 ¤   PGPBoolean¤ ¤   bIsDisabled;
813b9a ¤   PGPBoolean¤ ¤   bIsExpired;
dba397 ¤   PGPBoolean¤ ¤   bIsEncryptKey;
73381e ¤   PGPBoolean¤ ¤   bIsSigningKey;
57af5a
fcc3dc ¤   PGPPublicKeyAlgorithm lAlg;
50af5a
--f273 000a72b80a540110265 Page 2 of Utils.cpp
02cf4e ····if(IsPGPError(err = PGPOpenDefaultKeyRings(pgpContext,·
3e10ce ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPKeyRingOpenFlags) 0, &userKeySet)))
d9c7a1 ¤   {
4750bd ¤   ¤   MessageBox(NULL, "PGPOpenDefaultKeyRings error", "debug", MB_OK);
d599bf ¤   ¤   return;
289371 ¤   }
e2af5a
e7f1eb ¤   hList = GetDlgItem(hWnd, nListCtrl);
e39009 ¤   ListView_DeleteAllItems(hList);
ae9387 ¤   ListView_DeleteColumn(hList, 2);
b1b64a ¤   ListView_DeleteColumn(hList, 1);
90aaf1 ¤   ListView_DeleteColumn(hList, 0);
0f67c5 ¤
077f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
aa89fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
8ae693 ¤   ReleaseDC (NULL, hDC);
52af5a
d080db ¤   if (iNumBits <= 8)·
05c7a1 ¤   {
ad8bae ¤   ¤   hImages = ImageList_Create (16, 16, ILC_COLOR | ILC_MASK,·
8c8ae5 ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
fa1ea7 ¤   ¤   hBmp = LoadBitmap (g_hInstance, MAKEINTRESOURCE (IDB_IMAGES4BIT));
310446 ¤   ¤   ImageList_AddMasked (hImages, hBmp, RGB(255, 0, 255));
d35c8d ¤   ¤   DeleteObject (hBmp);
309371 ¤   }
d64264 ¤   else·
7ac7a1 ¤   {
977655 ¤   ¤   hImages = ImageList_Create (16, 16, ILC_COLOR24 | ILC_MASK,·
c68ae5 ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
6cb81b ¤   ¤   hBmp = LoadBitmap (g_hInstance, MAKEINTRESOURCE (IDB_IMAGES24BIT));
020446 ¤   ¤   ImageList_AddMasked (hImages, hBmp, RGB(255, 0, 255));
515c8d ¤   ¤   DeleteObject (hBmp);
829371 ¤   }
48af5a
72753d ¤   ListView_SetImageList(hList, hImages, LVSIL_SMALL);
99af5a
f88338 ¤   // Setup the list control columns
ad8f65 ¤   LoadString(g_hInstance, IDS_USERID, szTitle, 254);·
41089c ¤   lvcKey.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
6dc094 ¤   lvcKey.fmt = LVCFMT_LEFT;
230f4b ¤   lvcKey.cx = 175;
9e2ec8 ¤   lvcKey.pszText = szTitle;
591bce ¤   lvcKey.iSubItem = -1;
f2135f ¤   ListView_InsertColumn(hList, 0, &lvcKey);
d967c5 ¤
01c22f ¤   LoadString(g_hInstance, IDS_CREATION, szTitle, 254);·
2a089c ¤   lvcKey.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
3264ad ¤   lvcKey.fmt = LVCFMT_CENTER;
6377cd ¤   lvcKey.cx = 75;
cc2ec8 ¤   lvcKey.pszText = szTitle;
a7eaed ¤   lvcKey.iSubItem = 1;
4c16f2 ¤   ListView_InsertColumn(hList, 1, &lvcKey);
9567c5 ¤
ad1834 ¤   LoadString(g_hInstance, IDS_KEYSIZE, szTitle, 254);·
bb089c ¤   lvcKey.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
db64ad ¤   lvcKey.fmt = LVCFMT_CENTER;
a277cd ¤   lvcKey.cx = 75;
0a2ec8 ¤   lvcKey.pszText = szTitle;
7f0589 ¤   lvcKey.iSubItem = 2;
d31805 ¤   ListView_InsertColumn(hList, 2, &lvcKey);
11af5a
590660 ····/* Initialize keyrings */
46af5a
8750bb ····PGPOrderKeySet(userKeySet, kPGPUserIDOrdering, &klist);
219423 ····PGPNewKeyIter(klist, &kiter);
2700ff ¤   PGPKeyIterNext(kiter, &newKey);
e9af5a
0fd574 ¤   nItem = 0;
ddba1b ¤   while (newKey)
9dc7a1 ¤   {
fee5a7 ¤   ¤   PGPGetKeyBoolean(newKey, kPGPKeyPropIsRevoked, &bIsRevoked);
a739f0 ¤   ¤   PGPGetKeyBoolean(newKey, kPGPKeyPropIsDisabled, &bIsDisabled);
--a1c6 0002311c09240110265 Page 3 of Utils.cpp
2fd493 ¤   ¤   PGPGetKeyBoolean(newKey, kPGPKeyPropIsExpired, &bIsExpired);
9c784a ¤   ¤   PGPGetKeyBoolean(newKey, kPGPKeyPropIsEncryptionKey, &bIsEncryptKey);
cc5289 ¤   ¤   PGPGetKeyBoolean(newKey, kPGPKeyPropIsSigningKey, &bIsSigningKey);
c7af5a
cb0465 ¤   ¤   if ((bIsRevoked || bIsDisabled || bIsExpired) ||
f58f53 ¤   ¤   ¤   (!bIsEncryptKey && bMustEncrypt) ||
01031f ¤   ¤   ¤   (!bIsSigningKey && bMustSign))
975b34 ¤   ¤   {
c54dcc ¤   ¤   ¤   PGPKeyIterNext(kiter, &newKey);
9417f5 ¤   ¤   ¤   continue;
e70fe4 ¤   ¤   }
00af5a
916d02 ¤   ¤   PGPGetKeyNumber(newKey, kPGPKeyPropAlgID, (PGPInt32 *) &lAlg);
6233ac ¤   ¤   if ((bShowRSA && (lAlg == kPGPPublicKeyAlgorithm_RSA)) ||
570e30 ¤   ¤   ¤   (bShowDH && (lAlg == kPGPPublicKeyAlgorithm_DSA)))
7c5b34 ¤   ¤   {
07737d ¤   ¤   ¤   if (IsPGPError(PGPGetPrimaryUserIDNameBuffer(newKey,
0a01d6 ¤   ¤   ¤   ¤   ¤   kPGPMaxUserIDSize, (char*)szUserID, ·&nLength)))
33f776 ¤   ¤   ¤   {
82559c ¤   ¤   ¤   ¤   PGPKeyIterNext(kiter, &newKey);
afd040 ¤   ¤   ¤   ¤   continue;
79a3a6 ¤   ¤   ¤   }
fe059b ¤   ¤   ¤   szUserID[nLength] = 0;
0aaf5a
a10e27 ¤   ¤   ¤   if (IsPGPError(PGPGetKeyNumber(newKey, kPGPKeyPropBits,·
5620c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &nSignSize)))
c7f776 ¤   ¤   ¤   {
a6559c ¤   ¤   ¤   ¤   PGPKeyIterNext(kiter, &newKey);
9ad040 ¤   ¤   ¤   ¤   continue;
8da3a6 ¤   ¤   ¤   }
2aaf5a
746ad2 ¤   ¤   ¤   if (lAlg == kPGPPublicKeyAlgorithm_DSA)
bdf776 ¤   ¤   ¤   {
1a5806 ¤   ¤   ¤   ¤   PGPKeyIterNextSubKey(kiter, &newSubKey);
17c47d ¤   ¤   ¤   ¤   if (newSubKey) {
3ca8c5 ¤   ¤   ¤   ¤   ¤   if (IsPGPError(PGPGetSubKeyNumber(newSubKey,·
bdeb72 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyPropBits, &nEncryptSize)))
434859 ¤   ¤   ¤   ¤   ¤   {
5e9671 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyIterNext(kiter, &newKey);
9a6e1c ¤   ¤   ¤   ¤   ¤   ¤   continue;
841c89 ¤   ¤   ¤   ¤   ¤   }
82da28 ¤   ¤   ¤   ¤   ¤   wsprintf(szSize, "%d/%d", nEncryptSize, nSignSize);
2f2613 ¤   ¤   ¤   ¤   }
bdfa07 ¤   ¤   ¤   ¤   else
9b7447 ¤   ¤   ¤   ¤   ¤   wsprintf(szSize, "%d", nSignSize);
afa3a6 ¤   ¤   ¤   }
77bb8c ¤   ¤   ¤   else
d06560 ¤   ¤   ¤   ¤   wsprintf(szSize, "%d", nSignSize);
23af5a
4cfa65 ¤   ¤   ¤   if (IsPGPError(PGPGetKeyTime(newKey, kPGPKeyPropCreation,·
dc8fe4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tCreation)))
bdf776 ¤   ¤   ¤   {
fb559c ¤   ¤   ¤   ¤   PGPKeyIterNext(kiter, &newKey);
69d040 ¤   ¤   ¤   ¤   continue;
03a3a6 ¤   ¤   ¤   }
820c1e ¤   ¤   ¤   PGPGetYMDFromPGPTime(tCreation, &year, &month, &day);
8eaee0 ¤   ¤   ¤   wsprintf(szCreation, "%d/%d/%d", month, day, year);
99af5a
429ac8 ¤   ¤   ¤   if (onlyThisKeySet != NULL)
1ff776 ¤   ¤   ¤   {
236524 ¤   ¤   ¤   ¤   if (!PGPKeySetIsMember(newKey, onlyThisKeySet))
d172c3 ¤   ¤   ¤   ¤   {
b3c3dd ¤   ¤   ¤   ¤   ¤   PGPKeyIterNext(kiter, &newKey);
465914 ¤   ¤   ¤   ¤   ¤   continue;
982613 ¤   ¤   ¤   ¤   }
1fa3a6 ¤   ¤   ¤   }
66af5a
8c74b6 ¤   ¤   ¤   PGPGetKeyIDFromKey(newKey, &newKeyID);
79b759 ¤   ¤   ¤   PGPGetKeyIDString(&newKeyID, kPGPKeyIDString_Full, szTempKeyID);
2b87c7 ¤   ¤   ¤
b73176 ¤   ¤   ¤   lviKey.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
23152c ¤   ¤   ¤   lviKey.pszText = (char *) szUserID;
--9a43 000ff3a29c840110265 Page 4 of Utils.cpp
48b500 ¤   ¤   ¤   lviKey.iItem = nItem;
cbabb5 ¤   ¤   ¤   lviKey.iSubItem = 0;
9ae50a ¤   ¤   ¤   if (lAlg == kPGPPublicKeyAlgorithm_RSA)
3b0e49 ¤   ¤   ¤   ¤   lviKey.iImage = IDX_RSAPUBKEY;
636ad2 ¤   ¤   ¤   if (lAlg == kPGPPublicKeyAlgorithm_DSA)
718a7b ¤   ¤   ¤   ¤   lviKey.iImage = IDX_DSAPUBKEY;
d4d17d ¤   ¤   ¤   lviKey.lParam = (long) pgpAlloc(strlen(szTempKeyID)+1);
94b28a ¤   ¤   ¤   strcpy((char *) lviKey.lParam, szTempKeyID);
5eb68e ¤   ¤   ¤   ListView_InsertItem(hList, &lviKey);
2caf5a
3fcbe8 ¤   ¤   ¤   lviKey.mask = LVIF_TEXT;
afe5be ¤   ¤   ¤   lviKey.pszText = szCreation;
1cb500 ¤   ¤   ¤   lviKey.iItem = nItem;
62f169 ¤   ¤   ¤   lviKey.iSubItem = 1;
ab9723 ¤   ¤   ¤   ListView_SetItem(hList, &lviKey);
b9af5a
32cbe8 ¤   ¤   ¤   lviKey.mask = LVIF_TEXT;
9f0604 ¤   ¤   ¤   lviKey.pszText = szSize;
73b500 ¤   ¤   ¤   lviKey.iItem = nItem;
581e0d ¤   ¤   ¤   lviKey.iSubItem = 2;
319723 ¤   ¤   ¤   ListView_SetItem(hList, &lviKey);
9faf5a
795f1e ¤   ¤   ¤   nItem++;
7e0fe4 ¤   ¤   }
18c5aa ¤   ¤   PGPKeyIterNext(kiter, &newKey);
eb9371 ¤   }
dab11e ¤   PGPFreeKeyIter( kiter );
0948ac ¤   PGPFreeKeyList( klist );
f4af5a
403cab ····/* Everything was OK */
587cb2 ····err = kPGPError_NoErr;
91271c ¤   PGPFreeKeySet(userKeySet);
d4830f ¤   return;
daefe6 }
03af5a
16af5a
da9c83 BOOL SelectKeys(HWND hWnd,
dc3772 ¤   ¤   ¤   ¤   int nListCtrl,
0a5952 ¤   ¤   ¤   ¤   pgpConfigInfo *pConfig)
66bb36 {
1e2f22 ¤   int¤¤   nIndex;
8983c9 ¤   int¤¤   nNumItems;
2b941c ¤   HANDLE¤ hList;
340382 ¤   LV_ITEM¤lviKey;
ad0e6a ¤   char *¤ szKeyID;
24aa41 ¤   BOOL¤   bSelected = FALSE;
5ecfa1 ¤   PGPPublicKeyAlgorithm¤  keyAlg;
c3af5a
40f1eb ¤   hList = GetDlgItem(hWnd, nListCtrl);
9c5fea ¤   nNumItems = ListView_GetItemCount(hList);
15af5a
d7f30b ¤   for (nIndex=0; nIndex<nNumItems; nIndex++)
31c7a1 ¤   {
dfd263 ¤   ¤   lviKey.mask = LVIF_PARAM | LVIF_IMAGE;
07e0da ¤   ¤   lviKey.iItem = nIndex;
c010e3 ¤   ¤   lviKey.iSubItem = 0;
33f8ba ¤   ¤   ListView_GetItem(hList, &lviKey);
40af5a
3a45b8 ¤   ¤   szKeyID = (char *) lviKey.lParam;
a2dbac ¤   ¤   switch (lviKey.iImage)
225b34 ¤   ¤   {
4dcef6 ¤   ¤   case IDX_RSAPUBKEY:
d835ab ¤   ¤   ¤   keyAlg = kPGPPublicKeyAlgorithm_RSA;
d2cdcb ¤   ¤   ¤   break;
fbaf5a
4b4ac4 ¤   ¤   case IDX_DSAPUBKEY:
a3ba73 ¤   ¤   ¤   keyAlg = kPGPPublicKeyAlgorithm_DSA;
e0cdcb ¤   ¤   ¤   break;
690fe4 ¤   ¤   }
13af5a
a0015d ¤   ¤   if (pConfig->szCorpKeyID != NULL)
ff5b34 ¤   ¤   {
--dce9 0003adbd82b40110265 Page 5 of Utils.cpp
050599 ¤   ¤   ¤   if ((!strcmp(szKeyID, pConfig->szCorpKeyID)) &&
6edfc0 ¤   ¤   ¤   ¤   (keyAlg == pConfig->corpKeyType))
75f776 ¤   ¤   ¤   {
d6a9cf ¤   ¤   ¤   ¤   ListView_SetItemState(hList, nIndex, LVIS_SELECTED, 0);
886df9 ¤   ¤   ¤   ¤   bSelected = TRUE;
38a3a6 ¤   ¤   ¤   }
840fe4 ¤   ¤   }
63f018 ¤   ¤   else if (pConfig->szIncomingADKID != NULL)
fb5b34 ¤   ¤   {
1533ac ¤   ¤   ¤   if ((!strcmp(szKeyID, pConfig->szIncomingADKID)) &&
3bc35c ¤   ¤   ¤   ¤   (keyAlg == kPGPPublicKeyAlgorithm_DSA))
f4f776 ¤   ¤   ¤   {
51a9cf ¤   ¤   ¤   ¤   ListView_SetItemState(hList, nIndex, LVIS_SELECTED, 0);
d56df9 ¤   ¤   ¤   ¤   bSelected = TRUE;
65a3a6 ¤   ¤   ¤   }
650fe4 ¤   ¤   }
7e860e ¤   ¤   else if (pConfig->szOutgoingADKID != NULL)
895b34 ¤   ¤   {
99f08d ¤   ¤   ¤   if ((!strcmp(szKeyID, pConfig->szOutgoingADKID)) &&
bdca1d ¤   ¤   ¤   ¤   (keyAlg == pConfig->outgoingADKKeyType))
1bf776 ¤   ¤   ¤   {
9aa9cf ¤   ¤   ¤   ¤   ListView_SetItemState(hList, nIndex, LVIS_SELECTED, 0);
306df9 ¤   ¤   ¤   ¤   bSelected = TRUE;
c3a3a6 ¤   ¤   ¤   }
c10fe4 ¤   ¤   }
7f9371 ¤   }
9daf5a
e84354 ¤   return bSelected;
17efe6 }
17af5a
84af5a
b4e164 void AddSelectedKeys(HWND hWnd,·
e8af6d ¤   ¤   ¤   ¤   ¤   ·int nListCtrl,·
835574 ¤   ¤   ¤   ¤   ¤   ·PGPContextRef pgpContext,
c3ac61 ¤   ¤   ¤   ¤   ¤   ·PGPKeySetRef *pKeySet)
cfbb36 {
0c92c3 ¤   int¤¤   ¤   ¤   nIndex;
bc4a5d ¤   LV_ITEM¤¤   ¤   lviKey;
30429d ¤   HWND¤   ¤   ¤   hList;
f52f2a ¤   PGPKeyRef¤  ¤   newKey;
200476 ¤   PGPKeySetRef¤   userKeySet;
73fd2d ¤   PGPKeySetRef¤   newKeySet;
e16a88 ¤   PGPKeyID¤   ¤   newKeyID;
04fb19 ¤   PGPError¤   ¤   err;
3aaf5a
862fbd ¤   PGPPublicKeyAlgorithm¤  newKeyAlg;
04af5a
d7cf4e ····if(IsPGPError(err = PGPOpenDefaultKeyRings(pgpContext,·
d410ce ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPKeyRingOpenFlags) 0, &userKeySet)))
18c7a1 ¤   {
d750bd ¤   ¤   MessageBox(NULL, "PGPOpenDefaultKeyRings error", "debug", MB_OK);
6999bf ¤   ¤   return;
b29371 ¤   }
3eaf5a
44f1eb ¤   hList = GetDlgItem(hWnd, nListCtrl);
3aaf5a
77453b ¤   if (*pKeySet != NULL)
07e276 ¤   ¤   PGPFreeKeySet(*pKeySet);
2d67c5 ¤
745bcc ¤   *pKeySet = NULL;
0067c5 ¤
fe96dc ¤   nIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
14f80b ¤   if (nIndex != -1)
cfb455 ¤   ¤   PGPNewKeySet(pgpContext, pKeySet);
ca67c5 ¤
210717 ¤   while (nIndex > -1)
efc7a1 ¤   {
0cd263 ¤   ¤   lviKey.mask = LVIF_PARAM | LVIF_IMAGE;
38e0da ¤   ¤   lviKey.iItem = nIndex;
0110e3 ¤   ¤   lviKey.iSubItem = 0;
f2f8ba ¤   ¤   ListView_GetItem(hList, &lviKey);
3a1b52 ¤   ¤
--c706 000acb098ed40110265 Page 6 of Utils.cpp
1ffd18 ¤   ¤   PGPGetKeyIDFromString((char *) lviKey.lParam, &newKeyID);
e5af5a
e7dbac ¤   ¤   switch (lviKey.iImage)
c75b34 ¤   ¤   {
83cef6 ¤   ¤   case IDX_RSAPUBKEY:
89622e ¤   ¤   ¤   newKeyAlg = kPGPPublicKeyAlgorithm_RSA;
accdcb ¤   ¤   ¤   break;
c4af5a
404ac4 ¤   ¤   case IDX_DSAPUBKEY:
c4edf6 ¤   ¤   ¤   newKeyAlg = kPGPPublicKeyAlgorithm_DSA;
94cdcb ¤   ¤   ¤   break;
74af5a
c49ae3 ¤   ¤   default:
4fa745 ¤   ¤   ¤   pgpDebugMsg("Image index isn't RSA or DSA!");
990fe4 ¤   ¤   }
62af5a
792076 ¤   ¤   err = PGPGetKeyByKeyID(userKeySet, &newKeyID, newKeyAlg, &newKey);
d8af5a
112dee ¤   ¤   if ((newKey != NULL) && (IsntPGPError(err)))
315b34 ¤   ¤   {
0d531c ¤   ¤   ¤   PGPNewSingletonKeySet(newKey, &newKeySet);
a51fbc ¤   ¤   ¤   PGPAddKeys( newKeySet, *pKeySet);
1abe7d ¤   ¤   ¤   PGPFreeKeySet(newKeySet);
f90fe4 ¤   ¤   }
651b52 ¤   ¤
84b2f8 ¤   ¤   nIndex = ListView_GetNextItem(hList,·
9737d9 ¤   ¤   ¤   nIndex, LVNI_SELECTED);
169371 ¤   }
27af5a
48271c ¤   PGPFreeKeySet(userKeySet);
83830f ¤   return;
1fefe6 }
b4af5a
bfaf5a
609e85 void FreeKeyring(HWND hWnd,·
4cac2a ¤   ¤   ¤   ¤   ·int nListCtrl)
66bb36 {
c50382 ¤   LV_ITEM¤lviKey;
ef2f22 ¤   int¤¤   nIndex;
e818ec ¤   int¤¤   nCount;
13d7df ¤   HWND¤   hList;
0baf5a
9c793a ¤   hList¤  = GetDlgItem(hWnd, nListCtrl);
aadd98 ¤   nCount¤ = ListView_GetItemCount(hWnd);
55af5a
74e0fc ¤   for (nIndex=0; nIndex<nCount; nIndex++)
7fc7a1 ¤   {
0e4c5b ¤   ¤   lviKey.mask = LVIF_PARAM;
a5e0da ¤   ¤   lviKey.iItem = nIndex;
8910e3 ¤   ¤   lviKey.iSubItem = 0;
54f8ba ¤   ¤   ListView_GetItem(hList, &lviKey);
6407fa ¤   ¤   pgpFree((void *) lviKey.lParam);
c99371 ¤   }
06af5a
b7830f ¤   return;
8cefe6 }
e5af5a
9baf5a
b97c46 void PaintWizBitmap(HWND hWnd, HBITMAP hBitmap)
a0bb36 {
d10586 ¤   HDC¤¤   ¤   hDC,·
a5e72b ¤   ¤   ¤   ¤   hMemDC;
9b78a0 ¤   PAINTSTRUCT ps;
6c7cec ¤   HBITMAP¤¤   hBitmapOld;
47c156 ¤   BITMAP¤ ¤   bm;
ecfa01 ¤   UINT¤   ¤   uXsize,·
929c39 ¤   ¤   ¤   ¤   uYsize;
662152 ¤   UINT¤   ¤   uXpos,·
ea53b7 ¤   ¤   ¤   ¤   uYpos;
82af5a
0c763b ¤   GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
acaf5a
--2d08 001acdcde8340110265 Page 7 of Utils.cpp
6526dd ¤   uXsize = bm.bmWidth;
14b1b0 ¤   uYsize = bm.bmHeight;
e93283 ¤   uXpos = 0;
9f3969 ¤   uYpos = 13;
c8af5a
a23092 ¤   hDC = BeginPaint (hWnd, &ps);
430689 ¤   hMemDC = CreateCompatibleDC (hDC);
bc11ad ¤   hBitmapOld = SelectObject (hMemDC, hBitmap);
0d30a0 ¤   BitBlt (hDC, uXpos, uYpos, uXsize, uYsize, hMemDC, 0, 0, SRCCOPY);
5d7f32 ¤   SelectObject (hMemDC, hBitmapOld);
e76ce0 ¤   DeleteDC (hMemDC);
21e23b ¤   EndPaint (hWnd, &ps);
7cefe6 }
74af5a
6baf5a
4ec663 BOOL GetCommentString(PGPMemoryMgrRef memoryMgr,·
976a31 ¤   ¤   ¤   ¤   ¤   ··char *szComment,·
d97abc ¤   ¤   ¤   ¤   ¤   ··int nLength)
72bb36 {
792321 ¤   PGPBoolean¤ bGotString¤ = FALSE;
2e1b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
44af5a
71be29 #if PGP_BUSINESS_SECURITY
11af5a
55d0d3 #if PGP_BUSINESS_SECURITY && PGP_ADMIN_BUILD
50fb17 ¤   PGPclOpenAdminPrefs(memoryMgr, &prefRef, TRUE);
75db21 #else
16ffb3 ¤   PGPclOpenAdminPrefs(memoryMgr, &prefRef, FALSE);
c27454 #endif
a3af5a
aa8368 ¤   PGPGetPrefStringBuffer(prefRef, kPGPPrefComments, nLength, szComment);
ae9327 ¤   if (strlen(szComment) > 0)
01d931 ¤   ¤   bGotString = TRUE;
f05bbe ¤   PGPclCloseAdminPrefs(prefRef, FALSE);
acaf5a
e94798 ¤   if (bGotString)
d3745f ¤   ¤   return (BOOL) bGotString;
99af5a
2654cb #endif¤ /* PGP_BUSINESS_SECURITY */
1caf5a
a13bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
543a25 ¤   PGPGetPrefStringBuffer(prefRef, kPGPPrefComment, nLength, szComment);
c29327 ¤   if (strlen(szComment) > 0)
9cd931 ¤   ¤   bGotString = TRUE;
724a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
a4af5a
544357 ¤   return (BOOL) bGotString;
42efe6 }
f1af5a
837e4d /*__Editor_settings____
c5af5a
044126 ¤   Local Variables:
377b17 ¤   tab-width: 4
b00e6c ¤   End:
7e5f8c ¤   vi: ts=4 sw=4
ff9e9b ¤   vim: si
acd062 _____________________*/
--3319 0017fff7f7c40110266 Page 1 of Utils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
702ced ¤   $Id: Utils.h,v 1.14.8.1 1998/11/12 03:13:15 heller Exp $
b6f7f7 ____________________________________________________________________________*/
145648 #ifndef Included_Utils_h¤   /* [ */
e8daf3 #define Included_Utils_h
d8af5a
6ec5d5 #include "pgpBase.h"
e6a076 #include "pgpKeys.h"
0daf5a
b9ad7f void ShowKeyring(HWND hWnd,·
dad292 ¤   ¤   ¤   ¤   ·int nListCtrl,
0ac4ec ¤   ¤   ¤   ¤   ·PGPContextRef pgpContext,
c50291 ¤   ¤   ¤   ¤   ·PGPKeySetRef onlyThisKeySet,
18abf3 ¤   ¤   ¤   ¤   ·PGPBoolean bShowRSA,·
cf91fb ¤   ¤   ¤   ¤   ·PGPBoolean bShowDH,
4e3c19 ¤   ¤   ¤   ¤   ·PGPBoolean bMustEncrypt,
c6730d ¤   ¤   ¤   ¤   ·PGPBoolean bMustSign);
50af5a
f99c83 BOOL SelectKeys(HWND hWnd,
0e3772 ¤   ¤   ¤   ¤   int nListCtrl,
ad71ee ¤   ¤   ¤   ¤   pgpConfigInfo *pConfig);
45af5a
c4e164 void AddSelectedKeys(HWND hWnd,·
26af6d ¤   ¤   ¤   ¤   ¤   ·int nListCtrl,·
8b5574 ¤   ¤   ¤   ¤   ¤   ·PGPContextRef pgpContext,
e07203 ¤   ¤   ¤   ¤   ¤   ·PGPKeySetRef *pKeySet);
cdaf5a
4e9e85 void FreeKeyring(HWND hWnd,·
d88ed4 ¤   ¤   ¤   ¤   ·int nListCtrl);
ccaf5a
39276e void PaintWizBitmap(HWND hWnd, HBITMAP hBitmap);
4aaf5a
c7c663 BOOL GetCommentString(PGPMemoryMgrRef memoryMgr,·
ad6a31 ¤   ¤   ¤   ¤   ¤   ··char *szComment,·
117fbd ¤   ¤   ¤   ¤   ¤   ··int nLength);
33af5a
b56331 #endif /* ] Included_Utils_h */
b3af5a
afaf5a
be7e4d /*__Editor_settings____
14af5a
004126 ¤   Local Variables:
e57b17 ¤   tab-width: 4
470e6c ¤   End:
3e5f8c ¤   vi: ts=4 sw=4
449e9b ¤   vim: si
7fd062 _____________________*/
--c4b8 000e8d2921b40110267 Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
9fe6f0 // Used by PGPadmin.rc
cd465d //
524cd5 #define IDS_USERID ·····················1
b63818 #define IDS_CREATION ···················2
37498e #define IDS_KEYSIZE ····················3
95bbc5 #define IDS_SAVEADMINTITLE ·············4
3f161b #define IDS_SAVEDEFKEYSTITLE ···········5
ce11b5 #define IDS_PREFFILTERDESC ·············6
f7c880 #define IDS_PREFFILTER ·················7
417c38 #define IDS_KEYFILTERDESC ··············8
4659cb #define IDS_KEYFILTER ··················9
04c82b #define IDS_ADMINPREFFILE ··············10
ef19aa #define IDS_DEFKEYSFILE ················11
0eeacd #define IDS_CHOOSEDIR ··················12
15ef0f #define IDS_CLIENTPREFFILE ·············13
24a1c3 #define IDS_TEMPPREFFILE ···············14
f4d5df #define IDS_TITLE ······················15
025cfa #define IDS_E_MINCHARS_TOOSMALL ········16
09fb32 #define IDS_E_MINCHARS_TOOLARGE ········17
a58a69 #define IDS_E_MINQUAL_TOOSMALL ·········18
92838e #define IDS_E_MINQUAL_TOOLARGE ·········19
394834 #define IDS_E_RELOADKEYRING ············20
eacf64 #define IDS_NEWPREFFILE ················21
109012 #define IDS_DONE ·······················22
11315a #define IDS_FAILED ·····················23
4cc76c #define IDS_DEFAULTPATH ················24
8231db #define IDS_INSTALLDIR ·················25
786a81 #define IDS_INSTALLDISK ················26
df481c #define IDS_CLIENTINSTALLER ············27
4501dc #define IDS_E_MINCHARSRANGE ············28
040d6a #define IDS_E_MINQUALRANGE ·············29
960951 #define IDS_E_INSTALLDIR ···············30
a84b9b #define IDS_E_CLIENTINSTALLER ··········31
69830b #define IDS_E_MINKEYSIZERANGE ··········32
65455d #define IDS_E_EXPIRED ··················33
ea9f52 #define IDS_E_MINKEYSIZERANGERSA ·······34
80ce93 #define IDS_E_DAYSRANGE ················35
1babea #define IDR_MENU ·······················101
0bfdcd #define IDB_ADMINWIZ8 ··················102
40ebed #define IDB_ADMINWIZ24 ·················103
f4061e #define IDB_ADMINWIZ4 ··················104
722183 #define IDB_ADMINWIZ1 ··················105
f66a1d #define IDD_PROPPAGE_LARGE ·············107
9bfa1b #define IDD_INTRO ······················107
a2eca3 #define IDB_RSAPUBMSK ··················107
35e100 #define IDD_ADK ························108
171a61 #define IDB_DSAPUBMSK ··················108
b62a74 #define IDD_PASSPHRASE ·················109
9ec757 #define IDB_RSAPUB ·····················109
48f470 #define IDD_CORPKEY ····················110
2e3f99 #define IDB_DSAPUB ·····················110
6b6386 #define IDD_MISC ·······················111
b50866 #define IDB_IMAGES24BIT ················111
4f3c32 #define IDD_ADK_INCOMING ···············112
430b8c #define IDB_IMAGES4BIT ·················112
84761b #define IDD_ADK_INSEL ··················113
da986d #define IDI_ADMIN ······················113
e1f6e5 #define IDD_ADK_OUTGOING ···············114
6d4aa8 #define IDD_ADK_OUTSEL ·················115
f578f6 #define IDD_CORPKEYSEL ·················116
038afa #define IDD_KEYGEN ·····················117
0e9533 #define IDD_DEFKEYSEL ··················118
0dde4c #define IDD_FINISH ·····················119
89eca8 #define IDD_ADK_ENFORCE ················120
9b6814 #define IDD_CLIENTPREFS ················121
580f23 #define IDD_COPYPROGRESS ···············122
980e58 #define IDD_FINDINSTALLER ··············123
321334 #define IDD_REVIEW ·····················124
57109a #define IDD_LICENSE ····················125
e89cc0 #define IDD_SERVERUPDATES ··············126
--0043 0001667bf6a40110267 Page 2 of resource.h
7021cf #define IDD_REVIEWOLD ··················127
511430 #define IDD_REVOKER ····················128
71d5be #define IDD_REVOKERSEL ·················129
9d9c9f #define IDD_ADK_DISK ···················130
8c2e79 #define IDD_ADK_DISKSEL ················131
7367ea #define IDD_INSTALLOPTIONS ·············132
ccda3f #define IDC_USE_OUTADK ·················1000
6d41ad #define IDC_USE_INADK ··················1001
9d341f #define IDC_OUTADK_ID ··················1002
b57b75 #define IDC_SELECT_OUTGOING ············1003
9464d7 #define IDC_INADK_ID ···················1004
74d8fd #define IDC_SELECT_INCOMING ············1005
6f70a2 #define IDC_ENFORCE_ADK ················1006
0dba15 #define IDC_ENFORCE_MINCHARS ···········1007
b6f1cb #define IDC_MINCHARS ···················1008
e82031 #define IDC_PASSLABEL1 ·················1009
eb4039 #define IDC_PASSLABEL2 ·················1010
64db45 #define IDC_ENFORCE_MINQUALITY ·········1011
055a6a #define IDC_WARN_NOTCERT ···············1011
8feefd #define IDC_MINQUALITY ·················1012
43c183 #define IDC_CORPKEY ····················1012
1fd48c #define IDC_METAINTRODUCER ·············1012
911f87 #define IDC_QUALLABEL1 ·················1013
0aba29 #define IDC_SELECT_CORPKEY ·············1013
94c1b1 #define IDC_METAINTRODUCER_CHECK ·······1013
01bf43 #define IDC_QUALLABEL2 ·················1014
181adf #define IDC_AUTOSIGNTRUST ··············1014
f8c553 #define IDC_MINQUALITY_CHECK ···········1014
fa0246 #define IDC_WARNLABEL ··················1015
52220e #define IDC_COMMENT ····················1015
5529a9 #define IDC_FORCELABEL ·················1016
2a951a #define IDC_QUALLABEL_CHECK ············1016
46fd20 #define IDC_ALLOW_KEYGEN ···············1017
3cf780 #define IDC_ALLOW_CONVENTIONAL ·········1019
398a17 #define IDC_COMMENTS ···················1020
ec7de9 #define IDC_NUMKEYS ····················1021
9787ab #define IDC_ADD_DEFKEYS ················1022
5258a0 #define IDC_CLIENTINSTALL ··············1022
c5c2ff #define IDC_CORPKEY_ID ·················1024
bc42cd #define IDC_DEFKEY_ID ··················1025
98f629 #define IDC_WIZBITMAP ··················1026
74f82d #define IDC_ALLOW_RSAKEYGEN ············1027
fa128c #define IDC_ENFORCE_INADK ··············1028
acb51e #define IDC_INSTALLDIR ·················1029
a17202 #define IDC_ENFORCE_OUTADK ·············1029
02e459 #define IDC_BROWSE ·····················1030
ae96a1 #define IDC_ENFORCE_REMOTEADK ··········1030
fd18e9 #define IDC_USECURRENT ·················1031
163f25 #define IDC_PROGRESS ···················1032
3e5c1f #define IDC_FILENAME ···················1033
c9afc2 #define IDC_INADK ······················1035
5cf6e7 #define IDC_OUTADK ·····················1036
bad850 #define IDC_INADK_CHECK ················1041
d6239a #define IDC_OUTADK_CHECK ···············1042
21a9ed #define IDC_ENFORCEADK_CHECK ···········1043
9f6aad #define IDC_ENFORCEINADK_CHECK ·········1043
124f21 #define IDC_CORPKEY_CHECK ··············1044
cf59fa #define IDC_WARN_NOTCERT_CHECK ·········1045
e6267f #define IDC_PASSPHRASE_CHECK ···········1046
2f2d65 #define IDC_PASSLABEL_CHECK ············1047
348a3d #define IDC_KEYSIZE_CHECK ··············1047
601154 #define IDC_QUALITY_CHECK ··············1048
3b6ad6 #define IDC_MINCHARS_CHECK ·············1049
789751 #define IDC_CONVENTIONAL_CHECK ·········1050
9fc5c0 #define IDC_COMMENT_CHECK ··············1051
7058a4 #define IDC_DEFKEYS ····················1052
d1220b #define IDC_KEYGEN_CHECK ···············1053
db0e11 #define IDC_RSAKEYGEN_CHECK ············1054
c4f448 #define IDC_MINKEYSIZE_CHECK ···········1055
e8821b #define IDC_KEYSIZE_LABEL ··············1055
ada15e #define IDC_MINKEYSIZE ·················1056
1694e1 #define IDC_ENFORCEOUTADK_CHECK ········1056
--5414 00167230b6240110267 Page 3 of resource.h
07fe15 #define IDC_KEYSIZE_LABEL2 ·············1057
23e6d7 #define IDC_ENFORCEREMOTEADK_CHECK ·····1057
5475ab #define IDC_ENFORCELABEL ···············1058
29361c #define IDC_LICENSENUM ·················1059
f0427b #define IDC_UPDATEALL ··················1060
40aee1 #define IDC_UPDATETRUSTED ··············1061
fea067 #define IDC_ALLDAYS ····················1062
a0eb88 #define IDC_TRUSTEDDAYS ················1063
4cb2db #define IDC_TRUSTEDSPIN ················1064
b01e98 #define IDC_ALLSPIN ····················1065
65ab08 #define IDC_PANEL ······················1066
f66f19 #define IDC_ENABLEREVOKER ··············1067
0fa9d5 #define IDC_REVOKER_ID ·················1068
3f5c0c #define IDC_USE_DISKADK ················1069
d7b72a #define IDC_DISKADK_ID ·················1070
88acfe #define IDC_PRESELECT ··················1071
3521f9 #define IDC_USERINSTALLDIR ·············1072
e19ce7 #define IDC_INSTALLPROGRAMS ············1073
07d0b8 #define IDC_INSTALLEUDORA ··············1074
d02683 #define IDC_INSTALLOUTLOOK ·············1075
0e252b #define IDC_INSTALLOUTEXPRESS ··········1076
f64c56 #define IDC_INSTALLMANUAL ··············1077
e77267 #define IDC_INSTALLDISK ················1078
2e9450 #define IDC_UNINSTALL ··················1079
ffeea8 #define IDM_WIZARD ·····················40001
b23048 #define IDM_EXIT ·······················40002
c0af5a
bf11aa // Next default values for new objects
39ac6a //·
4df860 #ifdef APSTUDIO_INVOKED
c93f23 #ifndef APSTUDIO_READONLY_SYMBOLS
667bab #define _APS_NEXT_RESOURCE_VALUE ·······124
5652ac #define _APS_NEXT_COMMAND_VALUE ········40003
8e1d89 #define _APS_NEXT_CONTROL_VALUE ········1074
b21285 #define _APS_NEXT_SYMED_VALUE ··········101
d87454 #endif
677454 #endif
--eea3 000a09b599d40110268 Page 1 of AddKey.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e027af ¤   $Id: AddKey.c,v 1.41.8.1 1998/11/12 03:13:23 heller Exp $
33f7f7 ____________________________________________________________________________*/
575ed8 #include "precomp.h"
afaf5a
dac77d PGPError
e016e9 AddEvents(
68bc3b ¤   PGPContextRef context,
93b55d ¤   PGPEvent *event,
f88878 ¤   PGPUserValue userValue
5127e6 ¤   )
a9bb36 {
980d17 ¤   MYSTATE *s;
9b6d02 ¤   (void) context;
9daf5a
a393b0 ¤   s = (MYSTATE *)userValue;
4caf5a
ec497e ¤   if(s->ws.CancelPending)
3674be ¤   ¤   return kPGPError_UserAbort;
e5af5a
c67244 ¤   switch( event->type )·
79c7a1 ¤   {
de7813 ¤   case kPGPEvent_NullEvent:
955934 ¤   ¤   {¤  PGPEventNullData *d = &event->data.nullData;
629f0f ¤   ¤   ¤   BOOL CancelOperation;
eaaf5a
5a3546 ¤   ¤   ¤   CancelOperation=WorkingCallback (s->hwndWorking ,·
d53075 ¤   ¤   ¤   ¤   (unsigned long)d->bytesWritten, (unsigned long)d->bytesTotal) ;
a9af5a
0dc1bf ¤   ¤   ¤   if(CancelOperation)
90398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
9c0fe4 ¤   ¤   }
f72f68 ¤   ¤   break;
ad9c31 ¤   case kPGPEvent_ErrorEvent:
5903d0 ¤   ¤   {¤  PGPEventErrorData *d = &event->data.errorData;
52af5a
f340e7 ¤   ¤   ¤   if((d->error!=kPGPError_BadPassphrase)&&
5b0551 ¤   ¤   ¤   ¤   (d->error!=kPGPError_UserAbort))
71d3a6 ¤   ¤   ¤   ¤   PGPclEncDecErrorBox(s->hwndWorking,d->error);
f20fe4 ¤   ¤   }
212f68 ¤   ¤   break;
effcd5 ¤   case kPGPEvent_WarningEvent:
742071 ¤   ¤   {¤  PGPEventWarningData *d = &event->data.warningData;
a1af5a
3f0fe4 ¤   ¤   }
9d2f68 ¤   ¤   break;
37311c ¤   case kPGPEvent_AnalyzeEvent:
fef631 ¤   ¤   {¤  PGPEventAnalyzeData *d = &event->data.analyzeData;
05af5a
bddb37 ¤   ¤   ¤   if(d->sectionType!=kPGPAnalyze_Key)
6c8d2f ¤   ¤   ¤   ¤   return kPGPError_SkipSection;
b9af5a
3ba0ba ¤   ¤   ¤   s->FoundPGPData=TRUE;
d60fe4 ¤   ¤   }
562f68 ¤   ¤   break;
902f72 ¤   default:
ce2f68 ¤   ¤   break;
e09371 ¤   }
e12b85 ¤   ¤   ¤   ¤
1e151e ¤   return kPGPError_NoErr;
20efe6 }
bbaf5a
a86864 PGPError GenericAddKey(MYSTATE *ms,
2ad421 ¤   ¤   ¤   ¤   ¤   PGPOptionListRef opts,
bb99eb ¤   ¤   ¤   ¤   ¤   char *OperationTarget)
75bb36 {
a0c105 ¤   PGPKeySetRef AddKeySet;
--b965 0006c75e0d640110268 Page 2 of AddKey.c
0d8a97 ¤   PGPContextRef¤  context;
f66672 ¤   char StrRes[500];
de0040 ¤   PGPError err;
25af5a
a64ead ¤   err=kPGPError_NoErr;
d9af5a
fd2d85 ¤   context=ms->context;
04af5a
bdffdb ¤   ms->fileName=OperationTarget;
2aaf5a
afc83c ¤   LoadString (g_hinst, IDS_ADDINGFILE, StrRes, sizeof(StrRes));
7e6a79 ¤   sprintf(ms->ws.TitleText,StrRes,JustFile(ms->fileName));
950719 ¤   strcpy(ms->ws.StartText,"");
575f11 ¤   LoadString (g_hinst, IDS_FINISHEDREADINGKEYS, ms->ws.EndText, sizeof(ms->ws¶
070654 .EndText));
4aaf5a
cfb930 ¤   SendMessage(ms->hwndWorking, PGPM_PROGRESS_UPDATE,
c8ccdd ¤   ¤   (WPARAM)PGPSC_WORK_NEWFILE,0);
e4af5a
802b5f ¤   err=PGPImportKeySet(context,&AddKeySet,
48fdc0 ¤   ¤   opts,
cdf860 ¤   ¤   PGPOSendNullEvents(context,75),
11d9f1 ¤   ¤   PGPOEventHandler(context,AddEvents,ms),
8c0a8c ¤   ¤   PGPOLastOption(context));
63af5a
55348d ¤   WorkingCallback (ms->hwndWorking,·
e094c9 ¤   ¤   ms->ws.total,ms->ws.total);
26af5a
0cf309 ¤   if(IsntPGPError(err))·
61c7a1 ¤   {
8fc390 ¤   ¤   PGPUInt32¤  numKeys;
81af5a
7e514e ¤   ¤   PGPCountKeys( AddKeySet, &numKeys);
4a3a8f ¤   ¤   if ( numKeys > 0)·
9ced49 ¤   ¤   {¤
c13a70 ¤   ¤   ¤   err=PGPclQueryAddKeys (context,·
1ba030 ¤   ¤   ¤   ¤   ¤   ms->tlsContext,ms->hwndWorking,AddKeySet,NULL);
0e0fe4 ¤   ¤   }
771032 ¤   ¤   PGPFreeKeySet (AddKeySet);
2a9371 ¤   }
85af5a
795ea8 ¤   return err;
12efe6 }
f2af5a
654704 PGPError AddKeyFileListStub (MYSTATE *ms)·
a6bb36 {
6564a2 ¤   PGPContextRef context;
83fa35 ¤   PGPFileSpecRef inref;
60db50 ¤   PGPOptionListRef opts;
4a0e89 ¤   FILELIST *FileCurrent;
d10040 ¤   PGPError err;
acaf5a
f74ead ¤   err=kPGPError_NoErr;
d4af5a
742d85 ¤   context=ms->context;
c7af5a
cd820b ¤   FileCurrent=ms->ListHead;
6baf5a
11935f ¤   while(!(ms->ws.CancelPending)&&(FileCurrent!=0)&&(IsntPGPError(err)))
a9fce6 ¤   { ···
c77505 ¤   ¤   if(FileCurrent->IsDirectory)
b45b34 ¤   ¤   {
b1f94b ¤   ¤   ¤   FileCurrent=FileCurrent->next;
af17f5 ¤   ¤   ¤   continue;
d30fe4 ¤   ¤   }
c8af5a
0c61d4 ¤   ¤   PGPNewFileSpecFromFullPath (context,·
330fc0 ¤   ¤   ¤   FileCurrent->name, &inref);
9caf5a
0fdeef ¤   ¤   PGPBuildOptionList(context,&opts,
2bd04d ¤   ¤   ¤   PGPOInputFile(context,inref),
6ce5ff ¤   ¤   ¤   PGPOLastOption(context));
--2f3a 000df70f06d40110268 Page 3 of AddKey.c
e0af5a
9d73cc ¤   ¤   err=GenericAddKey(ms,opts,FileCurrent->name);
ffaf5a
c0041f ¤   ¤   PGPFreeOptionList(opts);
6faf5a
7639a5 ¤   ¤   PGPFreeFileSpec( inref );
5167c5 ¤
db0465 ¤   ¤   FileCurrent=FileCurrent->next;¤ ¤   ¤   ¤
099371 ¤   }
10af5a
cd5ea8 ¤   return err;
baefe6 }
58af5a
8009eb BOOL AddKeyFileList(HWND hwnd,void *PGPsc,void *PGPtls,FILELIST *ListHead)
8dbb36 {
f464a2 ¤   PGPContextRef context;
50b767 ¤   PGPtlsContextRef tls;
16c944 ¤   MYSTATE *ms;
b80040 ¤   PGPError err;
54af5a
f84ead ¤   err=kPGPError_NoErr;
9baf5a
31625b ¤   context=(PGPContextRef)PGPsc;
61db07 ¤   tls=(PGPtlsContextRef)PGPtls;
7caf5a
7fc933 ¤   if(IsPGPError(PGPclEvalExpired(hwnd, PGPCL_ALLEXPIRED)))
9c98aa ¤   ¤   return FALSE;
1aaf5a
5f229d ¤   ms=(MYSTATE *)malloc(sizeof(MYSTATE));
6aaf5a
63a558 ¤   if(ms)
08c7a1 ¤   {
c0e546 ¤   ¤   memset(ms, 0x00, sizeof(MYSTATE) );
5faf5a
f4e914 ¤   ¤   ms->context=context;
404e1f ¤   ¤   ms->tlsContext=tls;
2957fa ¤   ¤   ms->ListHead=ListHead;
e2ebda ¤   ¤   ms->Operation=MS_ADDKEYFILELIST;
3aaf5a
43fca7 ¤   ¤   if(OpenRings(hwnd,context,&(ms->KeySet)))
be5b34 ¤   ¤   {
c17220 ¤   ¤   ¤   err=DoWork(hwnd,ms);
9daf5a
2ed04b ¤   ¤   ¤   if(!(ms->FoundPGPData))
f88812 ¤   ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOPGPKEYSINFILE,
f4320a ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);¤
7267c5 ¤
f06449 ¤   ¤   ¤   PGPFreeKeySet(ms->KeySet);
9c0fe4 ¤   ¤   }
df3d9b ¤   ¤   free(ms);
729371 ¤   }
b0af5a
e92133 ¤   FreeFileList(ListHead);
eeaf5a
eeee15 ¤   if(IsPGPError(err))
b098aa ¤   ¤   return FALSE;
eaaf5a
14c2e7 ¤   return TRUE;
9fefe6 }
a9af5a
1e03ba PGPError AddKeyClipboardStub (MYSTATE *ms)·
49bb36 {
0cdb50 ¤   PGPOptionListRef opts;
7f64a2 ¤   PGPContextRef context;
b776de ¤   char StrRes[100];
7f0040 ¤   PGPError err;
bdaf5a
6e4ead ¤   err=kPGPError_NoErr;
24af5a
842d85 ¤   context=ms->context;
5eaf5a
dfe201 ¤   PGPBuildOptionList(context,&opts,
--4235 000ca5e851f40110268 Page 4 of AddKey.c
0cd3cd ¤   ¤   PGPOInputBuffer(context,ms->pInput,ms->dwInputSize),
fb0a8c ¤   ¤   PGPOLastOption(context));
b1af5a
c7dbec ¤   LoadString (g_hinst, IDS_CLIPBOARD, StrRes, sizeof(StrRes));
13af5a
dfeb83 ¤   err=GenericAddKey(ms,opts,StrRes);
09af5a
ccbf49 ¤   PGPFreeOptionList(opts);
5caf5a
3c5ea8 ¤   return err;
feefe6 }
8eaf5a
aaaa84 BOOL AddKeyClipboard(HWND hwnd,void *PGPsc,void *PGPtls)
36bb36 {
ad64a2 ¤   PGPContextRef context;
f2274e ¤   char *pInput;
1bb1a1 ¤   DWORD dwInputSize;
fa6a53 ¤   UINT ClipboardFormat;
6bc944 ¤   MYSTATE *ms;
ebb767 ¤   PGPtlsContextRef tls;
3c0040 ¤   PGPError err;
01af5a
b9acbf ¤   // Check for files copied into clipboard from explorer
758489 ¤   if(OpenClipboard(hwnd))·
3dc7a1 ¤   {
c0ae67 ¤   ¤   if(IsClipboardFormatAvailable(CF_HDROP))
6a5b34 ¤   ¤   {
6b16d5 ¤   ¤   ¤   FILELIST *ListHead;
e820dc ¤   ¤   ¤   HDROP hDrop;
19af5a
f40224 ¤   ¤   ¤   hDrop=(HDROP)GetClipboardData(CF_HDROP);
fa0137 ¤   ¤   ¤   ListHead=HDropToFileList(hDrop);
cdaf5a
06a801 ¤   ¤   ¤   if(ListHead!=0)
02f776 ¤   ¤   ¤   {
d7e73d ¤   ¤   ¤   ¤   CloseClipboard();
05af5a
fde7c2 ¤   ¤   ¤   ¤   return AddKeyFileList(hwnd,
44d67a ¤   ¤   ¤   ¤   ¤   PGPsc,PGPtls,ListHead);
dda3a6 ¤   ¤   ¤   }
d20fe4 ¤   ¤   }
bf5961 ¤   ¤   CloseClipboard();
779371 ¤   }
57af5a
cc4ead ¤   err=kPGPError_NoErr;
68af5a
52625b ¤   context=(PGPContextRef)PGPsc;
f7db07 ¤   tls=(PGPtlsContextRef)PGPtls;
e6af5a
bec933 ¤   if(IsPGPError(PGPclEvalExpired(hwnd, PGPCL_ALLEXPIRED)))
7d98aa ¤   ¤   return FALSE;
2faf5a
113a14 ¤   pInput=RetrieveClipboardData(hwnd, &ClipboardFormat,·
9e1c44 ¤   ¤   ¤   ·····················&dwInputSize);
f9af5a
976505 ¤   if(!pInput)
dac7a1 ¤   {
4be6fe ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOCLIPBOARDCONTENTS,
f92d15 ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
169371 ¤   }
7d0e24 ¤   else
4dc7a1 ¤   {
d46096 ¤   ¤   if((ClipboardFormat != CF_TEXT)||(*pInput==0))
945b34 ¤   ¤   {
8582f4 ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOCLIPBOARDTEXT,
a0e840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
b80fe4 ¤   ¤   }
b90e1d ¤   ¤   else
1c5b34 ¤   ¤   {
f56bb7 ¤   ¤   ¤   ms=(MYSTATE *)malloc(sizeof(MYSTATE));
d8af5a
ca2641 ¤   ¤   ¤   if(ms)
--15a9 001356cd50740110268 Page 5 of AddKey.c
99f776 ¤   ¤   ¤   {
ff6b57 ¤   ¤   ¤   ¤   memset(ms, 0x00, sizeof(MYSTATE) );
d4af5a
ef6f2a ¤   ¤   ¤   ¤   ms->context=context;
ca68bd ¤   ¤   ¤   ¤   ms->tlsContext=tls;
1ccb21 ¤   ¤   ¤   ¤   ms->pInput=pInput;
ee7a1e ¤   ¤   ¤   ¤   ms->dwInputSize=dwInputSize;
059b0f ¤   ¤   ¤   ¤   ms->Operation=MS_ADDKEYCLIPBOARD;
c6af5a
e951d1 ¤   ¤   ¤   ¤   if(OpenRings(hwnd,context,&(ms->KeySet)))
7c72c3 ¤   ¤   ¤   ¤   {
774aa5 ¤   ¤   ¤   ¤   ¤   err=DoWork(hwnd,ms);
95af5a
bb129a // If no PGP data in clipboard, warn....
d39d78 ¤   ¤   ¤   ¤   ¤   if(!(ms->FoundPGPData))
e2ba55 ¤   ¤   ¤   ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOPGPKEYSINCLIPB¶
8e5980 OARD,
f114e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
5baf5a
acfb9d ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(ms->KeySet);
1e2613 ¤   ¤   ¤   ¤   }
5fc0b4 ¤   ¤   ¤   ¤   free(ms);
89a3a6 ¤   ¤   ¤   }
e00fe4 ¤   ¤   }
2e0559 ¤   ¤   memset(pInput,0x00,dwInputSize);
3f742f ¤   ¤   free(pInput);
a59371 ¤   }
8faf5a
78ee15 ¤   if(IsPGPError(err))
ee98aa ¤   ¤   return FALSE;
5faf5a
d7c2e7 ¤   return TRUE;
d1efe6 }
abaf5a
9daf5a
fc7e4d /*__Editor_settings____
9faf5a
0f4126 ¤   Local Variables:
357b17 ¤   tab-width: 4
c50e6c ¤   End:
e85f8c ¤   vi: ts=4 sw=4
af9e9b ¤   vim: si
35d062 _____________________*/
--df13 0008165509540110269 Page 1 of ClVwClip.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
2af26a ¤   $Id: ClVwClip.c,v 1.10.2.1.2.1 1998/11/12 03:13:23 heller Exp $
7cf7f7 ____________________________________________________________________________*/
2f5ed8 #include "precomp.h"
1faf5a
3fa4a2 char* m_pDialogOutput = NULL;
543eaa DWORD m_dwDialogOuputSize = 0;
e2af5a
545178 BOOL WINAPI ClipboardViewProc(HWND hdlg, UINT uMsg,·
6a32e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam, LPARAM lParam);
ffaf5a
ffaf5a
ca2680 UINT EnclyptorViewClipboard(HWND hwnd, void* pInput,DWORD dwInSize,·
a3b9c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   void** ppOutput, DWORD* pOutSize)
90bb36 {
1e6daf ¤   UINT ReturnValue = FALSE;
24a215 ¤   BOOL DialogReturn = FALSE;
079b7c ¤   char* szDialogInput = NULL;
1567c5 ¤
5c0912 ¤   assert(pInput);
f315c6 ¤   assert(ppOutput);
01af5a
f31277 ¤   DialogReturn = DialogBoxParam(g_hinst,·
943855 ¤   ¤   MAKEINTRESOURCE(IDD_CLIPBOARDVIEWER), hwnd,·
eed301 ¤   ¤   ClipboardViewProc, (LPARAM) pInput);
4caf5a
406da8 ¤   if(DialogReturn && m_pDialogOutput)
10c7a1 ¤   {
0b8152 ¤   ¤   *ppOutput = m_pDialogOutput;
2d0419 ¤   ¤   *pOutSize = m_dwDialogOuputSize;
caaf5a
959e7f ¤   ¤   ReturnValue = TRUE;
259371 ¤   }
2baf5a
7d1965 ¤   return ReturnValue;
58efe6 }
33af5a
6290ce void SizeEditClip(HWND hdlg,int Width,int Height)
5dbb36 {
387d23 ¤   InvalidateRect(GetDlgItem(hdlg, IDC_EDIT1),NULL,TRUE);
dcaf5a
b9f959 ¤   MoveWindow(GetDlgItem(hdlg, IDC_EDIT1),
78c8c2 ¤   ¤   10,10,
bd37d3 ¤   ¤   Width-20,Height-55,
febe2f ¤   ¤   TRUE);
3eaf5a
e8455b ¤   InvalidateRect(GetDlgItem(hdlg, IDCANCEL),NULL,TRUE);
46af5a
248fa0 ¤   MoveWindow(GetDlgItem(hdlg, IDCANCEL),
6a4474 ¤   ¤   Width-130,Height-35,
659159 ¤   ¤   120,25,
00be2f ¤   ¤   TRUE);
abaf5a
ccf949 ¤   InvalidateRect(GetDlgItem(hdlg, IDOK),NULL,TRUE);
bbaf5a
c84e22 ¤   MoveWindow(GetDlgItem(hdlg, IDOK),
5f1159 ¤   ¤   Width-260,Height-35,
829159 ¤   ¤   120,25,
c7be2f ¤   ¤   TRUE);
79efe6 }
4daf5a
bb5178 BOOL WINAPI ClipboardViewProc(HWND hdlg, UINT uMsg,·
bc5b03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam, LPARAM lParam)
49bb36 {
edc08d ¤   switch(uMsg)
1cc7a1 ¤   {
81df25 ¤   ¤   case WM_INITDIALOG:
--b9cd 0001d96b82140110269 Page 2 of ClVwClip.c
e35b34 ¤   ¤   {
6eafc0 ¤   ¤   ¤   RECT rc;
fdaf5a
1ef444 ¤   ¤   ¤   SetWindowText(GetDlgItem(hdlg,IDC_EDIT1), (char*)lParam);
c82d5c ¤   ¤   ¤   GetClientRect(hdlg,&rc);
3f7c81 ¤   ¤   ¤   SizeEditClip(hdlg,rc.right-rc.left,rc.bottom-rc.top);
154475 ¤   ¤   ¤   SetFocus(GetDlgItem(hdlg,IDC_EDIT1));
34af5a
7a30b6 ············GetWindowRect (hdlg, &rc);
586d5c ············SetWindowPos (hdlg, NULL,
8e16ae ················(GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
ebbe05 ················(GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2,
153567 ················0, 0, SWP_NOSIZE | SWP_NOZORDER);
5eaf5a
93e3e2 ¤   ¤   ¤   SetForegroundWindow(hdlg);
b25f1f ¤   ¤   ¤   return FALSE;
f00fe4 ¤   ¤   }
1767c5 ¤
e7d725 ¤   ¤   case WM_QUIT:
e62c97 ¤   ¤   case WM_CLOSE:
935b34 ¤   ¤   {
cad720 ¤   ¤   ¤   EndDialog(hdlg, FALSE);
facdcb ¤   ¤   ¤   break;
828469 ¤   ¤   }·
5c1b52 ¤   ¤
6f4e34 ¤   ¤   case WM_GETMINMAXINFO:
f05b34 ¤   ¤   {
7c8590 ¤   ¤   ¤   MINMAXINFO* lpmmi;
63af5a
77b98a ¤   ¤   ····lpmmi = (MINMAXINFO*) lParam;
222c13 ····¤   ¤   lpmmi->ptMinTrackSize.x = 300;
386aaa ····¤   ¤   lpmmi->ptMinTrackSize.y = 200;
9a8632 ············break;
520fe4 ¤   ¤   }
14af5a
ce9dfe ¤   ¤   case WM_CTLCOLOR:
b7c329 ¤   ¤   { ·········
291fa7 ·¤  ¤   ¤   if((wParam!=0)&&(HIWORD(lParam)!=CTLCOLOR_EDIT))
a9330a ¤   ¤   ¤   {·
c32276 ¤   ¤   ¤   ¤   DWORD color;
c0a03d ¤   ¤   ¤   ¤   color=GetSysColor(COLOR_BTNFACE);
262b85 ¤   ¤   ¤   ¤
857c37 ¤   ¤   ¤   ··¤ SetBkColor ((HDC)wParam, color);
a52eb0 ¤   ¤   ¤   ··¤ SetTextColor ((HDC)wParam,·
feea6f ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_WINDOWTEXT)); ·····
3237bc ¤   ¤   ¤   ··¤ return (BOOL)CreateSolidBrush (color);
bb2efb ¤   ¤   ¤   } ¤ ·
26cdcb ¤   ¤   ¤   break;
770fe4 ¤   ¤   }
bbaf5a
d62526 ¤   ¤   case WM_SIZE:
d75b34 ¤   ¤   {
2107da ¤   ¤   ¤   unsigned short Width, Height;
51d850 ¤   ¤   ¤   Width = LOWORD(lParam); ·// width of client area·
05d81f ¤   ¤   ¤   Height = HIWORD(lParam); // height of client area·
bfaf5a
b11a63 ¤   ¤   ¤   SizeEditClip(hdlg,Width,Height);
31cdcb ¤   ¤   ¤   break;
5a0fe4 ¤   ¤   }
3faf5a
788e1e ¤   ¤   case WM_COMMAND:
035b34 ¤   ¤   {
d44afd ¤   ¤   ¤   switch(wParam)
def776 ¤   ¤   ¤   {
bae168 ¤   ¤   ¤   ¤   case IDOK:
0872c3 ¤   ¤   ¤   ¤   {
de40f5 ¤   ¤   ¤   ¤   ¤   DWORD TextLength = 0;
33af5a
1f68d7 ¤   ¤   ¤   ¤   ¤   TextLength=GetWindowTextLength(GetDlgItem(hdlg, IDC_EDIT1));
f68937 ¤   ¤   ¤   ¤   ¤   TextLength=TextLength+1; // Bug in GetWindowTextLength
5eaf5a
1d7d3f ¤   ¤   ¤   ¤   ¤   if(TextLength)
--83f4 0003d40c05740110269 Page 3 of ClVwClip.c
e04859 ¤   ¤   ¤   ¤   ¤   {
fc42e2 ¤   ¤   ¤   ¤   ¤   ¤   m_pDialogOutput = (char*) malloc( TextLength+1 );
d57d70 ¤   ¤   ¤   ¤   ¤   ¤   memset(m_pDialogOutput,0x00,TextLength+1);
4314bb ¤   ¤   ¤   ¤   ¤   ¤   m_dwDialogOuputSize = TextLength;
aaaf5a
c226c5 ¤   ¤   ¤   ¤   ¤   ¤   if(m_pDialogOutput)
258fec ¤   ¤   ¤   ¤   ¤   ¤   {
32b448 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetWindowText(GetDlgItem(hdlg, IDC_EDIT1),
7f814f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··m_pDialogOutput, TextLength);
b4af5a
8d0693 ¤   ¤   ¤   ¤   ¤   ¤   ¤   m_pDialogOutput[TextLength]=0; // Trailing NULL
12db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ba1c89 ¤   ¤   ¤   ¤   ¤   }
5a4bd6 ¤   ¤   ¤   ¤   ¤   else
6f4859 ¤   ¤   ¤   ¤   ¤   {
b68b24 ¤   ¤   ¤   ¤   ¤   ¤   m_pDialogOutput = (char *) malloc(1);
77d170 ¤   ¤   ¤   ¤   ¤   ¤   m_dwDialogOuputSize=0;
e73d7d ¤   ¤   ¤   ¤   ¤   ¤   *m_pDialogOutput = '\0';
531c89 ¤   ¤   ¤   ¤   ¤   }
28af5a
456d11 ¤   ¤   ¤   ¤   ¤   EndDialog(hdlg, TRUE);
b914c3 ¤   ¤   ¤   ¤   ¤   break;
c42613 ¤   ¤   ¤   ¤   }
3daf5a
6a8722 ¤   ¤   ¤   ¤   case IDCANCEL:
3972c3 ¤   ¤   ¤   ¤   {
b29a13 ¤   ¤   ¤   ¤   ¤   EndDialog(hdlg, FALSE);
bd14c3 ¤   ¤   ¤   ¤   ¤   break;
4b2613 ¤   ¤   ¤   ¤   }
ddaf5a
dfa3a6 ¤   ¤   ¤   }
4d32bd ¤   ¤   ¤   return TRUE;
130fe4 ¤   ¤   }
40af5a
279371 ¤   }
1da230 ¤   return FALSE;
f6efe6 }
5baf5a
f0f444 void TextViewer(HWND hwnd,char *szInText,DWORD dwInSize)
c7bb36 {
ef9911 ¤   DWORD dwOutSize = 0;
b331a0 ¤   char* szOutText = NULL;
5d2c65 ·¤  BOOL WinNT;
c0af5a
b4ff3a ····WinNT=FALSE;
40869e ····
10c7a1 ¤   {
84290b #ifdef _WIN32¤  ¤
220410 ¤   ¤   OSVERSIONINFO osid;
c88161 ¤   ¤   osid.dwOSVersionInfoSize = sizeof (osid);
b08f7a ¤   ¤   GetVersionEx (&osid); ··
a7654b ¤   ¤   WinNT=(osid.dwPlatformId == VER_PLATFORM_WIN32_NT);
c05c57 #endif // WIN32 ···¤¤
899a05 ¤   ¤   if (WinNT || (dwInSize < 65535))
f45b34 ¤   ¤   {
6c4fa8 ¤   ¤   ¤   if(EnclyptorViewClipboard(hwnd,szInText,dwInSize,·
7f2aaa ¤   ¤   ¤   ¤   &szOutText,&dwOutSize) == TRUE)
e3f776 ¤   ¤   ¤   {
19d500 ¤   ¤   ¤   ¤   StoreClipboardData(hwnd,szOutText,dwOutSize);
0690c6 ¤   ¤   ¤   ¤   memset(szOutText,0x00,dwOutSize);
9dd2ce ¤   ¤   ¤   ¤   free(szOutText);
b9a3a6 ¤   ¤   ¤   }
580fe4 ¤   ¤   }
48ee26 ¤   ¤   else·
c15b34 ¤   ¤   {
ad143c ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_CLIPBOARDEXCEEDED,
9e2d15 ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
ae0fe4 ¤   ¤   }
359371 ¤   }
d9efe6 }
f6af5a
3d8fcb void LaunchInternalViewer(HWND hwnd)
--cd0c 001779169b340110269 Page 4 of ClVwClip.c
2cbb36 {
f5d29b ¤   void *pClipboardData;
6df9d9 ¤   UINT ClipboardFormat = 0;
f2f745 ¤   DWORD dwDataSize = 0;
a624d4 ¤   DWORD dwOutputSize = 0;
808dd4 ¤   void* pOutputBuffer = NULL;
432c65 ·¤  BOOL WinNT;
b9af5a
d1bd67 ¤   pClipboardData = RetrieveClipboardData(hwnd, &ClipboardFormat,·
b2dc60 ¤   ¤   ¤   ¤   ¤   ¤   &dwDataSize);
6bde7b ··
e1e0b8 ¤   if(pClipboardData==0)
a2c7a1 ¤   {
00eacc ¤   ¤   pClipboardData=(void *)malloc(1);
0dc82a ¤   ¤   memset(pClipboardData,0x00,1);
dc9371 ¤   }
16af5a
2dff3a ····WinNT=FALSE;
a5869e ····
4fa00e ¤   if(pClipboardData)
ecc7a1 ¤   {
a28243 ¤   ¤   if(ClipboardFormat == CF_TEXT)
4850a4 ¤   ¤   { ···
5a5af4 //¤ ¤   ¤   TempestViewer(hwnd,pClipboardData,dwDataSize);
f4af5a
3e80f6 ¤   ¤   ¤   TextViewer(hwnd,
adb494 ¤   ¤   ¤   ¤   pClipboardData,dwDataSize);
cb0fe4 ¤   ¤   }
5660c4 ¤   ¤   memset(pClipboardData,0x00,dwDataSize);
a9c14f ¤   ¤   free(pClipboardData);
2d9371 ¤   }
4fefe6 }
bcaf5a
c77e4d /*__Editor_settings____
4faf5a
444126 ¤   Local Variables:
b87b17 ¤   tab-width: 4
3b0e6c ¤   End:
3e5f8c ¤   vi: ts=4 sw=4
649e9b ¤   vim: si
96d062 _____________________*/
77af5a
--d965 001e20821064011026a Page 1 of ClVwClip.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
1c09c3 ¤   $Id: ClVwClip.h,v 1.3.16.1 1998/11/12 03:13:24 heller Exp $
1ef7f7 ____________________________________________________________________________*/
f43590 #ifndef Included_CLVWCLIP_h¤/* [ */
beb187 #define Included_CLVWCLIP_h
68af5a
626274 UINT EnclyptorViewClipboard(HWND hwnd,void* pInput,DWORD dwInSize,
f69c79 ¤   ¤   ¤   ¤   ¤   ¤   ¤   void** ppOutput,DWORD* pOutSize);
a5af5a
fca7af void TextViewer(HWND hwnd,char *pClipboardData,DWORD dwDataSize);
35af5a
649335 #endif /* ] Included_CLVWCLIP_h */
acaf5a
31af5a
3d7e4d /*__Editor_settings____
a7af5a
404126 ¤   Local Variables:
6f7b17 ¤   tab-width: 4
460e6c ¤   End:
d55f8c ¤   vi: ts=4 sw=4
259e9b ¤   vim: si
b0d062 _____________________*/
e2af5a
--bfae 0005ec85d5c4011026b Page 1 of Clipbrd.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
2018eb ¤   $Id: Clipbrd.c,v 1.5.18.1 1998/11/12 03:13:25 heller Exp $
e6f7f7 ____________________________________________________________________________*/
765ed8 #include "precomp.h"
a4af5a
1a3c99 void* RetrieveClipboardData(HWND hwnd, UINT* pClipboardFormat,·
d6056c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DWORD* pDataSize)
50bb36 {
610e50 ¤   void* ReturnValue = 0;
745ef0 ¤   DWORD dwBufferSize = 0;
b29ab2 ¤   void* pLocalDataBuffer = NULL;
290b3a ¤   void* pClipboardBuffer = NULL;
d8f8e7 ¤   HANDLE hClipboardData = NULL;
e6af5a
b37bdd ¤   // See if we can gain access to the clipboard
1a8489 ¤   if(OpenClipboard(hwnd))·
97c7a1 ¤   {
ef2eb4 ¤   ¤   *pClipboardFormat = CF_TEXT;
4baf5a
b80813 ¤   ¤   hClipboardData = GetClipboardData(*pClipboardFormat);
0caf5a
b5e4ff ¤   ¤   if(hClipboardData && IsClipboardFormatAvailable(CF_TEXT))
635b34 ¤   ¤   {
57d4fd ¤   ¤   ¤   dwBufferSize = GlobalSize(hClipboardData);
a8af5a
8e4ae2 ¤   ¤   ¤   // For Some Reason Windows is returning 1 bytes more than the data
3607df ¤   ¤   ¤   // and it is not a NULL Byte ...grrrrrr
9cc129 ¤   ¤   ¤   dwBufferSize--;
f6af5a
a72fd4 ¤   ¤   ¤   //vErrorOut(fg_white, "BufferSize = %lu\n", dwBufferSize);
d3af5a
f62265 ¤   ¤   ¤   pClipboardBuffer = GlobalLock(hClipboardData);
4eaf5a
bb91cd ¤   ¤   ¤   if(pClipboardBuffer)
faf776 ¤   ¤   ¤   {
92b377 ¤   ¤   ¤   ¤   pLocalDataBuffer = malloc(dwBufferSize + 1);
beafd4 ¤   ¤   ¤   ¤   memset(pLocalDataBuffer, '\0',·
dce07d ¤   ¤   ¤   ¤   ¤   (dwBufferSize + 1) * sizeof(BYTE));
f1af5a
5ea334 ¤   ¤   ¤   ¤   if(pLocalDataBuffer)
2372c3 ¤   ¤   ¤   ¤   {
0f81be ¤   ¤   ¤   ¤   ¤   *pDataSize = dwBufferSize;
9ccaaf ¤   ¤   ¤   ¤   ¤   memcpy(pLocalDataBuffer, pClipboardBuffer, dwBufferSize);
88b044 ¤   ¤   ¤   ¤   ¤   if(strlen((char *) pLocalDataBuffer) < dwBufferSize)
4cd538 ¤   ¤   ¤   ¤   ¤   ¤   *pDataSize = strlen((char *) pLocalDataBuffer);
faaf5a
78f2f6 ¤   ¤   ¤   ¤   ¤   ReturnValue = pLocalDataBuffer;
0f2613 ¤   ¤   ¤   ¤   }
e9af5a
9e0461 ¤   ¤   ¤   ¤   GlobalUnlock(hClipboardData);
66a3a6 ¤   ¤   ¤   }
920fe4 ¤   ¤   }
015961 ¤   ¤   CloseClipboard();
a29371 ¤   }
7d1965 ¤   return ReturnValue;
f0efe6 }
03af5a
26af5a
fece11 void StoreClipboardData(HWND hwnd, void* pData, DWORD dwDataSize)
58bb36 {
00f8e7 ¤   HANDLE hClipboardData = NULL;
940b3a ¤   void* pClipboardBuffer = NULL;
7dbcd4 ¤   UINT ClipboardFormat = CF_TEXT;
51af5a
4b2fbf ¤   assert(pData);
d2af5a
5ebf04 ¤   if(pData)
--685a 001ff53a7db4011026b Page 2 of Clipbrd.c
f7c7a1 ¤   {
0c3fdf ¤   ¤   if(OpenClipboard(hwnd))·
735b34 ¤   ¤   {
1a795c ¤   ¤   ¤   if(EmptyClipboard())
15f776 ¤   ¤   ¤   {
2d1d97 ¤   ¤   ¤   ¤   if(ClipboardFormat == CF_TEXT)
5172c3 ¤   ¤   ¤   ¤   {
e45aa5 ¤   ¤   ¤   ¤   ¤   hClipboardData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,·
529e81 ¤   ¤   ¤   ¤   ¤   ¤   dwDataSize + 1);
492613 ¤   ¤   ¤   ¤   }
80af5a
aa2bf4 ¤   ¤   ¤   ¤   if(hClipboardData)
c572c3 ¤   ¤   ¤   ¤   {
49e541 ¤   ¤   ¤   ¤   ¤   pClipboardBuffer = ¤GlobalLock(hClipboardData);
4aaf5a
bfa948 ¤   ¤   ¤   ¤   ¤   if(pClipboardBuffer)
f24859 ¤   ¤   ¤   ¤   ¤   {
d3778b ¤   ¤   ¤   ¤   ¤   ¤   memcpy(pClipboardBuffer, pData, dwDataSize);
4ed402 ¤   ¤   ¤   ¤   ¤   ¤   if(ClipboardFormat == CF_TEXT)
a78fec ¤   ¤   ¤   ¤   ¤   ¤   {
d1a62a ¤   ¤   ¤   ¤   ¤   ¤   ¤   *((char *) pClipboardBuffer + dwDataSize) = '\0';
b7db3c ¤   ¤   ¤   ¤   ¤   ¤   }
44e55e ¤   ¤   ¤   ¤   ¤   ¤   GlobalUnlock(hClipboardData);
f3af5a
c3c8a3 ¤   ¤   ¤   ¤   ¤   ¤   SetClipboardData(ClipboardFormat, hClipboardData);
f31c89 ¤   ¤   ¤   ¤   ¤   }
b52613 ¤   ¤   ¤   ¤   }
38a3a6 ¤   ¤   ¤   }
fa2a31 ¤   ¤   ¤   // Close the clipboard when we are done with it.
b0d035 ¤   ¤   ¤   CloseClipboard();
900fe4 ¤   ¤   }
2d9371 ¤   }
acefe6 }
14869e ····
3faf5a
447e4d /*__Editor_settings____
caaf5a
224126 ¤   Local Variables:
c27b17 ¤   tab-width: 4
0c0e6c ¤   End:
115f8c ¤   vi: ts=4 sw=4
539e9b ¤   vim: si
ffd062 _____________________*/
--e413 001518d9f974011026c Page 1 of Clipbrd.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
12f082 ¤   $Id: Clipbrd.h,v 1.2.18.1 1998/11/12 03:13:25 heller Exp $
a8f7f7 ____________________________________________________________________________*/
1754b2 #ifndef Included_CLIPBRD_h¤ /* [ */
16aa09 #define Included_CLIPBRD_h
ccaf5a
083c99 void* RetrieveClipboardData(HWND hwnd, UINT* pClipboardFormat,·
b3a94f ¤   ¤   ¤   ¤   ¤   ¤   ¤   DWORD* pDataSize);
3601e6 void StoreClipboardData(HWND hwnd, void* pData, DWORD dwDataSize);
d4af5a
faaf5a
767450 #endif /* ] Included_CLIPBRD_h */
68af5a
77af5a
527e4d /*__Editor_settings____
4faf5a
e14126 ¤   Local Variables:
9d7b17 ¤   tab-width: 4
bb0e6c ¤   End:
2e5f8c ¤   vi: ts=4 sw=4
ec9e9b ¤   vim: si
51d062 _____________________*/
--5925 000b2d71a294011026d Page 1 of DDElog.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
2c4330 ¤   $Id: DDElog.c,v 1.14.8.1 1998/11/12 03:13:26 heller Exp $
e4f7f7 ____________________________________________________________________________*/
0e5ed8 #include "precomp.h"
322109 #include <ddeml.h>
1baf5a
e08841 HDDEDATA CALLBACK myDdeCallback(UINT type,UINT fmt,HCONV hconv,
1c1eb6 ································HSZ hsz1, HSZ hsz2, HDDEDATA hData,
bbd021 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DWORD dwData1, DWORD dwData2)
7cbb36 {
db3f59 ¤   return NULL;
ebefe6 }
85af5a
1e45f2 void InitPGPlogDDE(DWORD *pidInst)
cebb36 {
5d525f ¤   DdeInitialize(pidInst,(PFNCALLBACK) myDdeCallback,
e0f56d ¤   ¤   CBF_SKIP_ALLNOTIFICATIONS,0);
a6efe6 }
7eaf5a
fa5a21 void UninitPGPlogDDE(DWORD idInst)
6dbb36 {
c88ce4 ¤   DdeUninitialize(idInst);
58efe6 }
04af5a
90d092 BOOL PGPLogWindowExists (LPSTR lpszClassName, LPSTR lpszWindowTitle)·
aabb36 {
948ccc ¤   HWND hWndMe;
60af5a
685ce6 ···¤hWndMe = FindWindow (lpszClassName, lpszWindowTitle);
3a210a ····if (hWndMe)·
043b37 ····{
18810a ¤   ¤   if (!IsZoomed (hWndMe))·
759e9e ¤   ¤   ¤   ShowWindow (hWndMe, SW_RESTORE);
16bbbd ¤   ¤   SetWindowPos( hWndMe,HWND_TOP,0,0,0,0,
0e73fa ¤   ¤   ¤   SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOSIZE);
c14ee5 ········return TRUE;
64e773 ¤   } ·
bf0e24 ¤   else
4298aa ¤   ¤   return FALSE;
2eefe6 }
3aaf5a
913ec4 BOOL SendPGPlogMsg(HWND hwnd,char* szMsg)
1fbb36 {
4452f4 ¤   HSZ hszServName;
28a2b2 ¤   HSZ hszSysTopic;
169327 ¤   HCONV hConv; ········// conversation handle·
11cb61 ¤   HDDEDATA hdded;
34a5cd ¤   HDDEDATA ddemsg;
50f830 ¤   DWORD idInst;
9d6672 ¤   char StrRes[500];
fac5c7 ¤   int error;
8dde7b ··
916dad ¤   if(!PGPLogWindowExists (DDElogServer,DDElogServer))
c79727 ¤   { ···········
d2b960 ¤   ¤   char PGPlog[MAX_PATH];
4c1b52 ¤   ¤
6b5cc9 ¤   ¤   PGPpath(PGPlog);
236620 ¤   ¤   strcat(PGPlog,DDElogServer);
831b52 ¤   ¤
925444 ¤   ¤   error=WinExec(PGPlog,SW_SHOWNA);
c5af5a
11f061 ¤   ¤   if(error<=31)
f65b34 ¤   ¤   {
54a02f ¤   ¤   ¤   LoadString (g_hinst, IDS_CANTLOCATELOG, StrRes, sizeof(StrRes));
9baf5a
5fecab ¤   ¤   ¤   MessageBox(hwnd,szMsg,StrRes,
b20b2d ¤   ¤   ¤   ¤   MB_ICONEXCLAMATION|MB_OK|MB_SETFOREGROUND);
--2bbf 00193403fd34011026d Page 2 of DDElog.c
e05f1f ¤   ¤   ¤   return FALSE;
690fe4 ¤   ¤   }
ca9371 ¤   }
b767c5 ¤
c66e11 ¤   // Sigh... just in case log gets stuck in a silly
51cee1 ¤   // can't find memlock driver message box, we'll wait
11bb3b ¤   // here until the user lets log through
223f4a ¤   while(!PGPLogWindowExists (DDElogServer,DDElogServer))
4bc7a1 ¤   {
a89bc5 ¤   ¤   Sleep(500);
8c9371 ¤   }
1eaf5a
ae9c77 ¤   idInst=0;
5eaf5a
77ac7a ¤   InitPGPlogDDE(&idInst);
76af5a
b6bf23 ¤   hszServName = DdeCreateStringHandle(idInst,DDElogServer,CP_WINANSI);
7ece8c ¤   hszSysTopic = DdeCreateStringHandle(idInst,DDElogTopic,CP_WINANSI);
80af5a
b881d6 ¤   ddemsg=DdeCreateDataHandle(idInst,szMsg,strlen(szMsg)+1,0,0L,CF_TEXT,0);
64af5a
fd6241 ¤   hConv = DdeConnect(idInst,hszServName,hszSysTopic,(PCONVCONTEXT) NULL);
55af5a
2c20fc ¤   if(hConv==NULL)
5c230c ¤   { ·············
5943a1 ¤   ¤   error=DdeGetLastError(idInst);
7c9381 ¤   ¤   UninitPGPlogDDE(idInst);
386edd ¤   ¤   LoadString (g_hinst, IDS_CANTCONNECTLOG, StrRes, sizeof(StrRes));
7aaf5a
c4d045 ¤   ¤   MessageBox(hwnd,szMsg,StrRes,
95847a ¤   ¤   ¤   MB_ICONEXCLAMATION|MB_OK|MB_SETFOREGROUND);
5398aa ¤   ¤   return FALSE;
cf9371 ¤   }
fdaf5a
caa2ef ¤   hdded = DdeClientTransaction((void *)ddemsg,0xFFFFFFFF,
7b71d6 ¤   ¤   hConv,(UINT)0, (UINT)0, XTYP_EXECUTE, TIMEOUT_ASYNC, NULL);
fbaf5a
7cdf3b ¤   DdeDisconnect(hConv);
10af5a
f928d7 ¤   UninitPGPlogDDE(idInst);
a4af5a
6c6023 ¤   if(hdded==0)
0fc7a1 ¤   {
edc791 ¤   ¤   LoadString (g_hinst, IDS_CANTTRANSMITLOG, StrRes, sizeof(StrRes));
ded045 ¤   ¤   MessageBox(hwnd,szMsg,StrRes,
49847a ¤   ¤   ¤   MB_ICONEXCLAMATION|MB_OK|MB_SETFOREGROUND);
a498aa ¤   ¤   return FALSE;
199371 ¤   }
27af5a
dec2e7 ¤   return TRUE;
0befe6 }
f5af5a
04af5a
eb7e4d /*__Editor_settings____
b9af5a
bb4126 ¤   Local Variables:
097b17 ¤   tab-width: 4
dd0e6c ¤   End:
185f8c ¤   vi: ts=4 sw=4
fd9e9b ¤   vim: si
93d062 _____________________*/
--d1a2 0003b902b284011026e Page 1 of PGPsc.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
c2729d #include "windows.h"
08af5a
396c0e /////////////////////////////////////////////////////////////////////////////
8c7b93 #undef APSTUDIO_READONLY_SYMBOLS
e2af5a
2a6c0e /////////////////////////////////////////////////////////////////////////////
00f930 // English (U.S.) resources
43af5a
3d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
96ec08 #ifdef _WIN32
5de912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
779c1c #pragma code_page(1252)
e81f8e #endif //_WIN32
24af5a
ac6c0e /////////////////////////////////////////////////////////////////////////////
e2465d //
70b090 // Dialog
25465d //
ceaf5a
1a0b85 IDD_TEMPEST DIALOG DISCARDABLE ·0, 0, 395, 257
de8059 STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
3fd1cb CAPTION "Secure Viewer"
566960 CLASS "PGPtempestClass"
a5309f FONT 8, "MS Sans Serif"
894523 BEGIN
c7634f ····CONTROL ········"&Use TEMPEST Attack Prevention Font",IDC_TEMPESTFONT,
847aa4 ····················"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,15,138,
7f0339 ····················149,10
a6e0d1 END
13af5a
b7d054 IDD_CLIPBOARDVIEWER DIALOG DISCARDABLE ·0, 0, 340, 236
297d87 STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME
4bf594 CAPTION "Text Viewer"
c9309f FONT 8, "MS Sans Serif"
574523 BEGIN
162684 ····DEFPUSHBUTTON ··"&Copy to Clipboard",IDOK,202,223,80,14
f67df8 ····PUSHBUTTON ·····"&OK",IDCANCEL,287,223,50,14
3afe8c ····EDITTEXT ·······IDC_EDIT1,0,4,337,214,ES_MULTILINE | ES_AUTOVSCROLL |·
655350 ····················ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
39e0d1 END
53af5a
e91ef3 IDD_DELETEDLG DIALOG DISCARDABLE ·0, 0, 290, 166
7cc125 STYLE DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME
c67609 CAPTION "Last Chance!"
24309f FONT 8, "MS Sans Serif"
9b4523 BEGIN
ed9b4b ····PUSHBUTTON ·····"&Yes",IDYES,87,145,50,14
147469 ····PUSHBUTTON ·····"&No",IDNO,154,145,50,14
209a8d ····LISTBOX ········IDC_FILELIST,7,28,276,109,LBS_SORT |·
31f48a ····················LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
89c27b ····CTEXT ··········"Are you really sure you want to secure delete these files?¶
ec934a ",
5f8ad8 ····················IDC_WIPEQUERY,7,7,276,8
d8e0d1 END
29af5a
b7b467 IDD_INTRO DIALOG DISCARDABLE ·0, 0, 280, 148
c75d93 STYLE DS_CENTER | WS_CHILD | WS_DISABLED | WS_CAPTION
972401 CAPTION "Wipe Free Space - Introduction"
df309f FONT 8, "MS Sans Serif"
cd4523 BEGIN
e0db3f ····LTEXT ··········"PGP Free Space Wiper",IDC_WELCOME,88,0,192,10
7c65b9 ····LTEXT ··········"When a file is deleted by your computer, the data that was¶
3ba460 ·in the file actually remains on your hard drive. Over time, this leads to a la¶
--5115 00075599dbd4011026e Page 2 of PGPsc.rc
f04de4 rge amount of potentially sensitive data left behind in random places on your d¶
22cdb1 rive. ",
861da3 ····················IDC_STATIC,88,14,191,35
bee112 ····LTEXT ··········"PGP's volume wiping cleans all the free space on your hard¶
b0fa05 ·drive which does not contain actual file data including all deleted files, the¶
f61f47 ir directory entries, and the little areas after the end of existing files whic¶
68d09e h may still have old data left behind.",
b5edf7 ····················IDC_STATIC,88,91,191,41
fcf0b9 ····CONTROL ········"",IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE,0,
10118b ····················0,80,148
a3503d ····LTEXT ··········"Using PGP's file wiping feature when you delete files solv¶
ad6a7e es only part of the problem because many files are created and deleted by appli¶
4e39bd cations or operating system without your knowledge.",
d35d05 ····················IDC_STATIC,88,53,191,34
cbe0d1 END
d8af5a
a40cbb IDD_INFO DIALOG DISCARDABLE ·0, 0, 280, 148
f65d93 STYLE DS_CENTER | WS_CHILD | WS_DISABLED | WS_CAPTION
5645b5 CAPTION "Wipe Free Space - Gathering Information"
1c309f FONT 8, "MS Sans Serif"
ca4523 BEGIN
01f0b9 ····CONTROL ········"",IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE,0,
97118b ····················0,80,148
ca3cf0 ····LTEXT ··········"Please select which volume you wish to wipe and the number¶
2bd58d ·of passes you wish to perform. The more passes you choose to perform, the more¶
3bbce1 ·securely the free space will be wiped.",
2bdb1c ····················IDC_STATIC,88,0,192,32
e87332 ····LTEXT ··········"Volumes often contain lots of freespace. The more freespac¶
943a35 e there is on a volume, the longer it will take to perform each pass. You shoul¶
6ca2af d balance out your need for security with the time needed to wipe a volume.",
23da03 ····················IDC_STATIC,88,36,192,34
f9538b ····COMBOBOX ·······IDC_DRIVECOMBO,152,124,41,58,CBS_DROPDOWNLIST | CBS_SORT |·
e6be8a ····················WS_VSCROLL | WS_TABSTOP
abb2e3 ····LTEXT ··········"Wipe drive:",IDC_STATIC,112,126,37,8
6c5ab9 ····LTEXT ··········"with ",IDC_STATIC,196,126,14,8
f44698 ····LTEXT ··········"passes.",IDC_STATIC,238,126,25,8
70c266 ····CONTROL ········"",IDC_STATIC,"Static",SS_BLACKFRAME | NOT WS_VISIBLE,88,
e739fb ····················119,191,1
9c9476 ····LTEXT ··········"PGP uses heavily researched techniques and patterns design¶
28dfb2 ed specifically for overwriting data on magnetic and optical media. Most users ¶
b745f7 should be fine with 1 to 3 passes; however, the wiping algorithms continue to i¶
69516e ncrease security up to 26 passes.",
251e14 ····················IDC_STATIC,88,74,191,41
452993 ····EDITTEXT ·······IDC_NUMPASSES,212,124,23,13,ES_NUMBER
24c038 ····CONTROL ········"Spin2",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |·
4eb3ad ····················UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,226,124,
b33b54 ····················10,14
cfe0d1 END
38af5a
b82e0e IDD_STATUS DIALOG DISCARDABLE ·0, 0, 280, 148
4f5d93 STYLE DS_CENTER | WS_CHILD | WS_DISABLED | WS_CAPTION
00fbd9 CAPTION "Wipe Free Space - Perform Wipe"
9e309f FONT 8, "MS Sans Serif"
874523 BEGIN
697aef ····RTEXT ··········"File System:",IDC_FS,115,9,63,8
dc824b ····RTEXT ··········"Number of Clusters:",IDC_NC,116,19,62,8
0365d8 ····RTEXT ··········"Sectors per Cluster:",IDC_SC,116,29,62,8
59ae06 ····RTEXT ··········"Bytes per Sector:",IDC_BS,115,39,63,8
170a23 ····LTEXT ··········"?",IDC_FSDATA,183,9,70,8
bff0a6 ····LTEXT ··········"?",IDC_NCDATA,183,19,70,8
d7723c ····LTEXT ··········"?",IDC_SCDATA,183,29,70,8
00ea4c ····LTEXT ··········"?",IDC_BSDATA,183,39,70,8
fcdc28 ····RTEXT ··········"Total Capacity:",IDC_TC,115,49,63,8
878f41 ····LTEXT ··········"?",IDC_TCDATA,183,49,70,8
e65111 ····GROUPBOX ·······"Disk Statistics",IDC_GROUP,109,0,151,60
0cb49f ····CONTROL ········"Progress1",IDC_PASS_PROGRESS,"msctls_progress32",
b1d672 ····················WS_BORDER,109,72,151,8
c2b2aa ····CTEXT ··········"Status",IDC_STATUS,88,95,192,24
eccb72 ····PUSHBUTTON ·····"Begin Wipe",IDC_BEGIN,159,134,50,14
9ef0b9 ····CONTROL ········"",IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE,0,
18118b ····················0,80,148
75bc55 ····CONTROL ········"Progress1",IDC_WIPE_PROGRESS,"msctls_progress32",
--96b5 000717b1e0b4011026e Page 3 of PGPsc.rc
19405a ····················WS_BORDER,109,82,151,8
04b727 ····LTEXT ··········"Pass: 0/0",IDC_STATIC_PASS,109,63,65,8
091e5b ····CTEXT ··········"Static",IDC_RESTARTINGTEXT,88,123,192,8
1ee0d1 END
65af5a
c8a6af IDD_NEWWORKING DIALOGEX 0, 0, 184, 58
e87844 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
f2f150 CAPTION "Working"
ac3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
a24523 BEGIN
08f2fe ····PUSHBUTTON ·····"&Cancel",IDCANCEL,67,38,50,14
217a0b ····CTEXT ··········"Setting up...",IDC_PROGRESS_TEXT,7,6,170,10
a9cb20 ····CONTROL ········"Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,
b1f4b6 ····················21,170,8,WS_EX_CLIENTEDGE
40e0d1 END
b2af5a
49af5a
956c0e /////////////////////////////////////////////////////////////////////////////
4d465d //
a5cbaf // Icon
62465d //
87af5a
e72951 // Icon with lowest ID value placed first to ensure application icon
2a0f06 // remains consistent on all systems.
163915 IDI_ICON_AEXPK ·········ICON ···DISCARDABLE ····"RES\\AEXPK.ICO"
b87445 IDI_ICON_ASC ···········ICON ···DISCARDABLE ····"RES\\ASC.ICO"
5c9383 IDI_ICON_PGP ···········ICON ···DISCARDABLE ····"RES\\PGP.ICO"
d67798 IDI_ICON_PRVKR ·········ICON ···DISCARDABLE ····"RES\\PRVKR.ICO"
9f7ee5 IDI_ICON_PUBKR ·········ICON ···DISCARDABLE ····"RES\\PUBKR.ICO"
4adf4d IDI_ICON_SIG ···········ICON ···DISCARDABLE ····"RES\\SIG.ICO"
f68fba IDI_ICON_SHF ···········ICON ···DISCARDABLE ····"res\\shf.ico"
69cfb8 IDI_ICON_RND ···········ICON ···DISCARDABLE ····"res\\rnd.ico"
04aee0 IDI_ICON_PGR ···········ICON ···DISCARDABLE ····"res\\pgr.ico"
9f06aa IDI_FYEO ···············ICON ···DISCARDABLE ····"res\\fyeo.ico"
4daf5a
bbf860 #ifdef APSTUDIO_INVOKED
596c0e /////////////////////////////////////////////////////////////////////////////
29465d //
6e5733 // TEXTINCLUDE
94465d //
d8af5a
4486ef 1 TEXTINCLUDE DISCARDABLE·
4e4523 BEGIN
5b541e ····"resource.h\0"
4ee0d1 END
66af5a
907037 2 TEXTINCLUDE DISCARDABLE·
4b4523 BEGIN
be766b ····"#include ""windows.h""\r\n"
0bdb5c ····"\0"
19e0d1 END
bcaf5a
04227f 3 TEXTINCLUDE DISCARDABLE·
2a4523 BEGIN
b0e16e ····"#include ""PGPscVer.rc""\r\n"
81db5c ····"\0"
51e0d1 END
65af5a
0169ab #endif ···// APSTUDIO_INVOKED
91af5a
c4af5a
9d6c0e /////////////////////////////////////////////////////////////////////////////
f1465d //
be6077 // DESIGNINFO
ea465d //
beaf5a
68f860 #ifdef APSTUDIO_INVOKED
0b70e4 GUIDELINES DESIGNINFO DISCARDABLE·
454523 BEGIN
c60468 ····IDD_CLIPBOARDVIEWER, DIALOG
da5574 ····BEGIN
71e35b ········RIGHTMARGIN, 337
--aa66 0001aeb369a4011026e Page 4 of PGPsc.rc
3e7d01 ····END
94af5a
8aded7 ····IDD_DELETEDLG, DIALOG
fe5574 ····BEGIN
e6c975 ········LEFTMARGIN, 7
c9b126 ········RIGHTMARGIN, 283
6e87e9 ········TOPMARGIN, 7
611d52 ········BOTTOMMARGIN, 159
c67d01 ····END
c5af5a
703197 ····IDD_INTRO, DIALOG
705574 ····BEGIN
2769b3 ········VERTGUIDE, 88
0b7d01 ····END
2aaf5a
398264 ····IDD_INFO, DIALOG
545574 ····BEGIN
1f69b3 ········VERTGUIDE, 88
157d01 ····END
80e0d1 END
9869ab #endif ···// APSTUDIO_INVOKED
d4af5a
e7af5a
6b6c0e /////////////////////////////////////////////////////////////////////////////
92465d //
05ae70 // Bitmap
72465d //
abaf5a
f3a1ff IDB_WIPEWIZ4 ···········BITMAP ·DISCARDABLE ····"res\\wipesidebar4.bmp"
72f001 IDB_WIPEWIZ1 ···········BITMAP ·DISCARDABLE ····"res\\wipesidebar1.bmp"
976357 IDB_WIPEWIZ8 ···········BITMAP ·DISCARDABLE ····"res\\wipesidebar8.bmp"
051771 IDB_MA13X24 ············BITMAP ·DISCARDABLE ····"res\\ma13x24.bmp"
8b2c19 IDB_MA8X14 ·············BITMAP ·DISCARDABLE ····"res\\ma8x14.bmp"
c1102f IDB_MB13X24 ············BITMAP ·DISCARDABLE ····"res\\mb13x24.bmp"
8ceaea IDB_MC13X24 ············BITMAP ·DISCARDABLE ····"res\\mc13x24.bmp"
c81e93 IDB_MD13X24 ············BITMAP ·DISCARDABLE ····"res\\md13x24.bmp"
bd4a6e IDB_MB8X14 ·············BITMAP ·DISCARDABLE ····"res\\mb8x14.bmp"
7d6843 IDB_MC8X14 ·············BITMAP ·DISCARDABLE ····"res\\mc8x14.bmp"
ee8680 IDB_MD8X14 ·············BITMAP ·DISCARDABLE ····"res\\md8x14.bmp"
8aaf5a
ef6c0e /////////////////////////////////////////////////////////////////////////////
99465d //
535e87 // String Table
4a465d //
06af5a
256f6c STRINGTABLE DISCARDABLE·
8e4523 BEGIN
9f6392 ····IDS_ENTER_PHRASE ·······"&Enter passphrase for"
5303d6 ····IDS_WRONG_PHRASE ·······"Incorrect passphrase. ·Please re-enter:"
888f3d ····IDS_WIPINGINFREEWARE ···"PGPfreeware does not support File Wiping. ·PGP for¶
820674 ·Personal Privacy and PGP for Business Security support File Wiping along with ¶
987ae0 many other new features."
fce48d ····IDS_ADDINGFILE ·········"Adding %s"
441dfd ····IDS_FINISHEDREADINGKEYS "Finished reading keys. Please wait."
5f10eb ····IDS_PGPERROR ···········"PGP Error"
2b1c8a ····IDS_NOPGPKEYSINFILE ····"Found no PGP keys in these file(s)."
54064e ····IDS_NOCLIPBOARDCONTENTS "Clipboard contents could not be obtained."
806b9d ····IDS_NOPGPKEYSINCLIPBOARD "Found no PGP keys in the clipboard."
0516c3 ····IDS_CLIPBOARDEXCEEDED ··"Sorry, the contents exceed the limits of the clipb¶
c47572 oard\nand/or viewer. Please try using a file operation instead."
2079a2 ····IDS_CLIPBOARD ··········"Clipboard"
5fe0d1 END
7eaf5a
b76f6c STRINGTABLE DISCARDABLE·
344523 BEGIN
fcf8d0 ····IDS_FSNOTSUPPORTED ·····"No FAT 12, FAT 16, ·FAT 32, or NTFS (NT only) volu¶
b97e12 me was found in this drive."
9d7a45 ····IDS_DRIVENOTSUPPORTED ··"CDROM, Networked, and RAM drives are not supported¶
2eacf9 ."
c6263b ····IDS_FATFAILED ··········"The file allocation table has invalid entries and ¶
9a579c the free space cannot be safely wiped."
1a54f5 ····IDS_COULDNOTLOCK ·······"Could not lock the volume."
--dcb3 000859bf4214011026e Page 5 of PGPsc.rc
37edf2 ····IDS_NODRIVESELECTED ····"Please make a selection in the drive combo box."
6bfc56 ····IDS_USERCANCEL ·········"The user pressed the cancel button (Shouldn't see ¶
8394fa this)."
5ae45f ····IDS_DISKMODIFIED ·······"Another process wrote to the volume being wiped. O¶
e140b4 peration aborted."
4873ef ····IDS_COULDNOTWRITE ······"Could not write sectors to the volume."
4504e5 ····IDS_COULDNOTREAD ·······"Could not read sectors from the volume."
714dcd ····IDS_OUTOFMEMORY ········"Could not allocate enough memory. Try closing some¶
7eec1f ·applications."
abb6d7 ····IDS_CLUSTERERROR ·······"An error was found in a file or directory's cluste¶
ffe38c r chain. Run scandisk first and try again."
db134a ····IDS_NTNOTSUPPORTED ·····"Free space wipe does not currently work under Wind¶
7e04de ows NT."
91db9d ····IDS_NTFSGREATER4K ······"Cannot wipe NT volumes with cluster sizes of great¶
91cba1 er than 4K."
33ae66 ····IDS_INVALPARAM ·········"Invalid parameter."
d1456a ····IDS_ALREADYCOMMIT ······"Cluster has already been committed by file system."
9de0d1 END
aaaf5a
4f6f6c STRINGTABLE DISCARDABLE·
1c4523 BEGIN
524433 ····IDS_CANTLOCATELOG ······"Can't locate PGPlog"
66e766 ····IDS_CANTCONNECTLOG ·····"Can't connect to PGPlog"
c1b8a4 ····IDS_CANTTRANSMITLOG ····"Can't transmit to PGPlog"
7710da ····IDS_DECODINGFILE ·······"Decoding %s"
477f99 ····IDS_SHAREFILEINFO ······"Share files should be stored in an encrypted form ¶
9043e2 until needed.\nYou will automatically be prompted to re-encrypt this file after¶
e1444c \ndecryption. ·At that time, you may encrypt the share file to\nanother public ¶
a3bf9a key or use conventional encryption."
bcfa86 ····IDS_SHARERDTITLE ·······"Share File Encryption Dialog"
444708 ····IDS_SHAREPASSPROMPT ····"&Enter new passphrase for share file:"
b92e9a ····IDS_STARTINGWORK ·······"Starting work..."
6d9c92 ····IDS_FINISHINGUP ········"Finishing up..."
3a94c0 ····IDS_NOPGPINFOINFILE ····"Found no PGP information in these file(s)."
66e7b7 ····IDS_NOPGPINFOCLIPBOARD ·"Found no PGP information in the clipboard."
2d21c9 ····IDS_PGPKEYSELDLG ·······"PGP - Key Selection Dialog"
23fb99 ····IDS_CONVPASSPROMPT ·····"&Enter conventional passphrase:"
374ac2 ····IDS_PASSPROMPTABOVEKEY ·"&Enter passphrase for above key:"
111a37 ····IDS_ENCODINGFILE ·······"Encoding %s"
2967c3 ····IDS_ENCFILENAMEPROMPT ··"Enter filename for encrypted file"
28e0d1 END
f7af5a
4a6f6c STRINGTABLE DISCARDABLE·
944523 BEGIN
46fc66 ····IDS_DECRYPTIONCOLON ····" decryption :"
98457f ····IDS_PRIVATEKEYCOLON ····" your private key :"
cc9701 ····IDS_ENTEROUTPUTFILENAME "Enter output filename"
1f03e9 ····IDS_SAVEFILTER ·········"All Files (*.*)@*.*@@"
43e2ab ····IDS_SELSIGNFILE ········"Select Signed File"
6b25a7 ····IDS_WRONGSDK ···········"Incompatible SDK API. You might try reinstalling."
642793 ····IDS_EVALEXPIRED ········"The evaluation period for PGP has passed."
6cb484 ····IDS_CANTOPENRINGS ······"Could not open default key rings. Another\napplica¶
addb68 tion might have them open?"
db8caf ····IDS_CANTOPENPGPKEYS ····"Could not open PGPkeys.exe"
307727 ····IDS_CANTOPENPGPTOOLS ···"Could not open PGPtools.exe"
162a92 ····IDS_CANTAUTOCOPY ·······"PGP could not automatically copy the text from you¶
2dc570 r window.\n\nPlease check to make sure your text is in the window that last\nha¶
7f7add d the input focus and try again. If PGP still can't copy the\ntext, the window ¶
5f6bcc you are trying to use may be a non-standard\ncontrol. Deselect the Use Current ¶
3b2614 Window option and perform the\ncopy/paste operation manually."
4fc216 ····IDS_SCANNINGDISK ·······"Scanning disk..."
361c40 ····IDS_PERCENTWRITTEN ·····"%ld of %ld cluster writes completed."
56019d ····IDS_READINGFAT ·········"Reading in file allocation table."
200310 ····IDS_WIPINGDELANDSLACK ··"Wiping deleted file entries and cluster slack."
c80419 ····IDS_WIPINGCLUSTERS ·····"Wiping unallocated clusters."
7be0d1 END
62af5a
f26f6c STRINGTABLE DISCARDABLE·
4d4523 BEGIN
f39722 ····IDS_READINGBOOT ········"Reading in boot sector."
885dc6 ····IDS_DISKSTAT ···········"Disk Statistics for Drive "
8538d2 ····IDS_BEGINWIPE ··········"Press ""Begin Wipe"" button to start wiping."
--e7fb 0017b076e9f4011026e Page 6 of PGPsc.rc
00ea08 ····IDS_DETECTEDWRITE ······"Detected write. Restarting pass...\n\nMake sure yo¶
60553b u have closed any programs running\non your system that would write to the disk¶
c2dbbb .\nIf you continue to get this error, you may not\nhave enough free memory to p¶
47f935 erform this operation."
4e8a61 ····IDS_WIPECONGRATS ·······"Congratulations! Drive %s has been wiped."
a77751 ····IDS_WIPECANCEL ·········"Wiping canceled."
ec21e0 ····IDS_WIPENOTSUCCESSFUL ··"Wiping could not be completed successfully. %s"
a5e4dd ····IDS_WIPENOTOPEN ········"File was not wiped because it could not be opened\¶
2f5845 nfor write access. Please check file permissions,\nand make sure that the file ¶
f13dcd isn't opened by\nanother program."
790020 ····IDS_WIPEUSERABORT ······"File was not wiped completely because of a user\na¶
347bfb bort"
dfc463 ····IDS_WIPENOSTATS ········"File was not wiped because _stat information about¶
5cb83e \nit could not be obtained."
4b9120 ····IDS_WIPENOREMOVE ·······"File was overwritten with random data, but could n¶
f29585 ot\nbe deleted."
77c340 ····IDS_WIPENOFLUSH ········"Stream was not flushed. File data may not have bee¶
12a2cb n\nproperly overwritten."
450350 ····IDS_WIPENOFILEMAP ······"File mapping could not be created."
580022 ····IDS_WIPENOMEMMAP ·······"File could not be mapped to memory."
227012 ····IDS_WIPEALREADYOPEN ····"File was not wiped because it has been opened\nby ¶
14f355 another program. Close any programs which might\nhave this file open before att¶
c60e0e empting to wipe it."
c20e7e ····IDS_WIPEPROTECT ········"The media on which the file is located is\nwrite-p¶
beadc3 roctected. The file cannot be wiped\nuntil the write protection is removed."
ebe0d1 END
95af5a
456f6c STRINGTABLE DISCARDABLE·
614523 BEGIN
131c88 ····IDS_DIRNOTREMOVED ······"Directory could not be removed. The directory path¶
9090c7 ·may\nbe invalid, or the directory may not be empty."
596c99 ····IDS_WIPINGFILE ·········"Wiping %s"
d81eab ····IDS_LASTCHANCE ·········"Last Chance"
c26ae1 ····IDS_REALLYWIPECLIPBOARD "Are you really sure you want to erase the clipboar¶
6a98b8 d?"
8ec231 ····IDS_WORKPERCENT ········"%dk of %dk"
406e28 ····IDS_PASSESOUTOFRANGE ···"Only values of 1 to 32 are valid entries for the\n¶
8bf34a number of wipe passes."
7abdfd ····IDS_CANTOPENPGPDISK ····"Could not open PGPdisk.exe"
d517a8 ····IDS_NOCLIPBOARDTEXT ····"The selected action could not be performed because¶
2033e7 \nthere is no text on the clipboard."
3aa82e ····IDS_FYEOCAPTION ········"Secure Viewer"
ee79b4 ····IDS_FYEOMSG ············"The message you are decrypting is for your eyes\no¶
3ed41b nly. It is recommended that this message only\nbe read under the most secure ci¶
884181 rcumstances."
0015c7 ····IDS_OUTOFMEM ···········"Could not allocate memory for message."
04e0d1 END
61af5a
b81b3a #endif ···// English (U.S.) resources
056c0e /////////////////////////////////////////////////////////////////////////////
a0af5a
efaf5a
b2af5a
6ece8c #ifndef APSTUDIO_INVOKED
0e6c0e /////////////////////////////////////////////////////////////////////////////
7a465d //
788464 // Generated from the TEXTINCLUDE 3 resource.
d0465d //
af5ca0 #include "PGPscVer.rc"
86af5a
fa6c0e /////////////////////////////////////////////////////////////////////////////
b68072 #endif ···// not APSTUDIO_INVOKED
7baf5a
--4bc8 001c6b9a69e4011026f Page 1 of PGPscVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
d52042 ·FILETYPE VFT_APP
817247 ·FILESUBTYPE VFT2_UNKNOWN
f44523 BEGIN
752c72 ····BLOCK "StringFileInfo"
095574 ····BEGIN
fe70ac ········BLOCK "040904b0"
2752d6 ········BEGIN
e980b6 ············VALUE "CompanyName", PGPCOMPANYNAME
f821d8 ············VALUE "FileDescription", "PGP Cryptographic Support Library\0"
1cc1dd ············VALUE "FileVersion", PGPVERSIONSTRING
3ea9c5 ············VALUE "InternalName", "PGP60sc\0"
898ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
f82bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
cd9724 ············VALUE "OriginalFilename", "PGP60sc.dll\0"
4d9317 ············VALUE "ProductName", PGPPRODUCTNAME
e0d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
a6f37f ········END
ce7d01 ····END
ee26ab ····BLOCK "VarFileInfo"
805574 ····BEGIN
774b11 ········VALUE "Translation", 0x409, 1200
857d01 ····END
e9e0d1 END
afaf5a
b5af5a
c6af5a
--3717 000f47dd60040110270 Page 1 of Precomp.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e44008 ¤   $Id: Precomp.h,v 1.38.8.1 1998/11/12 03:13:27 heller Exp $
d9f7f7 ____________________________________________________________________________*/
50519a #ifndef Included_PRECOMP_h¤ /* [ */
065498 #define Included_PRECOMP_h
89af5a
d31bcc /*++
0aaf5a
764678 Module Name:
48af5a
5f3fd4 ····precomp.h
cbaf5a
ce57d7 Abstract:
faaf5a
bfcab2 ····This file includes all the headers required to build the dll
983a9d ····to ease the process of building a precompiled header.
c5af5a
1bd16a Author:
94af5a
3baf5a
bc8999 Revision History:
86af5a
f2af5a
bd67d9 --*/
98af5a
982a68 #define WIN32_LEAN_AND_MEAN
bd7867 #define PGPExport __declspec( dllexport )
09af5a
762de6 // System headers
865655 #include <windows.h>
583d0b #include <windowsx.h>
3dbea3 #include <stdlib.h>
d9feb2 #include <stdio.h>
f0bea3 #include <stdlib.h>
248f85 #include <assert.h>·
8e324c #include <string.h>
7e7609 #include <ShellAPI.h>
ea57d1 #include <Direct.h>
cfeadd #include <CommDlg.h>
6e32c9 #include <OLE2.h>
db90fb #include <commctrl.h>
9111a9 #include <process.h>
37af5a
97f9d0 #include "resource.h" ···············
d9af5a
a9fee6 #define UNFINISHED_CODE_ALLOWED 1
bfaf5a
718cbe // PGPlib headers
24af5a
e521fd #include "..\..\shared\pgpVersionHeader.h"
8bfca7 #include "..\..\shared\pgpBuildFlags.h"
aaa076 #include "pgpKeys.h"
75e2ff #include "pgpConfig.h"
872f8d #include "pgpErrors.h"
009f63 #include "pgpEncode.h"
464919 #include "pgpUtilities.h"
7891b9 #include "pgpSDKPrefs.h"
654720 #include "pflPrefTypes.h"
90e82c #include "pgpPubTypes.h"
11af5a
a5e622 #include "pgpDiskWiper.h"
d1af5a
79af5a
157158 #ifndef WIN32
66af5a
daf9cb #define BST_CHECKED¤¤   ¤   1
f43c84 #define ULONG unsigned long
--a501 00028334ba840110270 Page 2 of Precomp.h
b623b0 #define USHORT unsigned short ···
58e290 #define LPTSTR ·char*·
53af5a
bcdad3 #define MAX_PATH 256
a8af5a
a967f0 #define CHAR char
b7ff9d #define INT int ·
2d2996 #define APIENTRY WINAPI ··
7f7a28 #define BST_CHECKED 1
f2640a #define BST_UNCHECKED 0 ················
81f74f #define UCHAR unsigned char
bfc950 #define LPCTSTR char *
43af5a
d57454 #endif
f6d83c ·
31b5ac #include "..\include\PGPcl.h"
58fb9d #include "..\..\shared\pgpClientPrefs.h"
c84492 #include "..\..\shared\pgpAdminPrefs.h"
51af5a
669e94 // PGPtray headers
d3af5a
255a2f #include "ClipBrd.h"
0d1aac #include "ClVwClip.h"
749de0 #include "..\include\PGPsc.h"
753218 #include "working.h"
e47615 #include "recpass.h"
80651f #include "events.h"
2836bc #include "saveopen.h"
668031 #include "resource.h"
8c81ff #include "..\shared\SigEvent.h"
24894b #include "pgpFileSpec.h"
6dadd5 #include "pgpShareFile.h"
c2af5a
f26e43 #define MAX_BUFFER_SIZE 500000
e1af5a
2f9950 #define OPENKEYRINGFLAGS 0
16af5a
0322ee HINSTANCE g_hinst;
90af5a
58156d #define FS_NOFS ·0
113ef1 #define FS_FAT ··1 // Could be FAT12 or FAT16...
f93340 #define FS_FAT12 2 // If clusters <= 4079
f27d65 #define FS_FAT16 3 // If clusters >= 4079
eebb89 #define FS_FAT32 4 // New for OSR2
6aaf5a
3ec821 #define FS_NTFS 5 // WindowsNT
42af5a
cdd453 #define WFE_NOERROR ············0
914bb2 #define WFE_FSNOTSUPPORTED ·····1
d47b53 #define WFE_DRIVENOTSUPPORTED ··2
2578a5 #define WFE_FATFAILED¤  ¤   ¤   3
87efee #define WFE_COULDNOTLOCK ·······4
8b883a #define WFE_NODRIVESELECTED ····5
b4f618 #define WFE_USERCANCEL ·········6
9d59cb #define WFE_DISKMODIFIED ·······7
604eef #define WFE_COULDNOTWRITE ······8
ce508a #define WFE_COULDNOTREAD ·······9
2941c6 #define WFE_OUTOFMEMORY ·······10
fc0b94 #define WFE_CLUSTERERROR ······11
f35d56 #define WFE_NTNOTSUPPORTED ····12
ffe071 #define WFE_NTFSGREATER4K ·····13
0c4fe9 #define WFE_INVALPARAM ········14 // temp error
061cfc #define WFE_ALREADYCOMMIT ·····15 // temp error
db09f7 BOOL bGlobalCancel;
a9af5a
fb1f39 typedef struct _DIRSTACK
44bb36 {
709dec ¤   DWORD dwStartCluster;
5f4ff5 ¤   struct _DIRSTACK *next;
c0a0e8 } DIRSTACK;
caaf5a
281741 typedef struct
--c894 00143e69d9440110270 Page 3 of Precomp.h
2cbb36 {
652d7d ¤   char *name;
f6b7d9 ¤   ULONGLONG Vcn;
90e27d ¤   ULONGLONG Orig;
7e6621 } SLACKMOVE;
d4af5a
43a107 #define SLACKBUFFER 2000
f6af5a
2522e2 typedef struct _VOLINFO
51bb36 {
b3739f ¤   PGPBoolean WinNT;
5aa481 ¤   FILELIST *FileList;
1622b4 ¤   SLACKMOVE *SlackMove;
4e6b14 ¤   DWORD SlackMoveIndex;
e95cda ¤   DWORD SlackMoveCount;
bc1f58 ¤   ULONGLONG SlackBuffer[SLACKBUFFER+1];
ac9c8a ¤   ULONGLONG PatternBuffer;
7ac55d ¤   DWORD SlackBufferIndex;
2055cf ¤   HWND hwnd;
9f5ae8 ¤   HANDLE hVWin32;
aebf0f ¤   HANDLE VolHandle;
7d599c ¤   DWORD vol0;
290340 ¤   DWORD vol1;
d644ce ¤   DWORD dwFS;
b7e684 ¤   DWORD dwStartSector;
cb01f8 ¤   unsigned short sectors_per_clus;
115be6 ¤   unsigned short sector_size;
b4afb0 ¤   unsigned short sectors_per_fat;
ad6251 ¤   int fat_count;
1f0271 ¤   DWORD dwReservedSectors;
a3cbad ¤   DWORD sectors_total;
89893d ¤   DWORD dwClusterSize;
b72def ¤   DWORD no_of_clusters;
25ce47 ¤   DWORD FAT32_DirCluster;
d17abe ¤   DWORD FAT_DirSector;
68e0c2 ¤   DWORD dwClustersWritten;
a4138f ¤   unsigned short FAT_DirSectorCount;
d935a9 ¤   unsigned char *pFatBuf;
1035d0 ¤   unsigned char *pClusterBuf;
69c3b8 ¤   float fTotalCapacity;
796a34 ¤   DIRSTACK *ds;
65d5d8 ¤   BOOL bCountClusters;
bca1a4 ¤   DWORD dwClusterCount;
1ac3a4 ¤   DWORD pattern_buffer[256];
cbaf5a
5931d2 } VOLINFO;
f1af5a
f9e7d5 #include "WFnt.h"
205a5e #include "WFfat.h"
6830a2 #include "WFwiz.h"
61af5a
93d136 BOOL DisplayDiskStats(VOLINFO *vi);
e218ce void StatusMessage(char *msg, BOOL bold);
de2591 void WipeProgress(int pos);
dd3f0a void PassProgress(int pass, int total);
95edeb DWORD WipeFree(HWND hwnd,VOLINFO *vi,char *szRoot,
95899f ¤   ¤   ¤   ···DWORD* pattern, BOOL StartWipe);
7caf5a
01af5a
d1af5a
b941ed #endif /* ] Included_PRECOMP_h */
e2af5a
18af5a
187e4d /*__Editor_settings____
9baf5a
fb4126 ¤   Local Variables:
437b17 ¤   tab-width: 4
c90e6c ¤   End:
5a5f8c ¤   vi: ts=4 sw=4
509e9b ¤   vim: si
43d062 _____________________*/
--0668 000aca62be040110271 Page 1 of ProgVal.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c75171 ¤   $Id: ProgVal.c,v 1.5.18.1 1998/11/12 03:13:27 heller Exp $
82f7f7 ____________________________________________________________________________*/
585ed8 #include "precomp.h"
e4af5a
2c3fbf WNDPROC origProgValProc;
c9af5a
75ebb3 void PaintProgValBar(HWND hwnd,HDC hDC)
4cbb36 {
1d1e7c ¤   RECT rcBar;
3e5aa7 ¤   HBRUSH hBrush;
28539d ¤   WORKSTRUCT *ws;
8faf5a
bf87d4 ¤   ws=(WORKSTRUCT *)GetWindowLong(GetParent(hwnd), DWL_USER);
afaf5a
fa1d3b ¤   GetClientRect(hwnd,&rcBar);
5d9ff2 ¤   hBrush=CreateSolidBrush (GetSysColor(COLOR_BTNFACE));
426d13 ¤   SelectObject(hDC,hBrush);¤  ¤   ¤   ············
44e323 ¤   Rectangle(hDC,rcBar.left,rcBar.top,rcBar.right,rcBar.bottom); ·
115be3 ¤   DeleteObject(hBrush);
8687c7 ¤   ¤   ¤
7b4656 ¤   if(ws->curpos!=0)
fe9108 ¤   {·
ad6821 ¤   ¤   unsigned long cx;
8287c7 ¤   ¤   ¤
6ac1e7 ¤   ¤   cx=ws->curpos;
49af5a
c9e7e1 ¤   ¤   if(cx>ws->maxpos)
11e0ba ¤   ¤   ¤   cx=ws->maxpos;
d8af5a
50641e ¤   ¤   rcBar.right=rcBar.left+3+
a364bc ¤   ¤   ¤   (int)((float)(rcBar.right-rcBar.left-6)*
f10915 ¤   ¤   ¤   ((float)cx/(float)ws->maxpos)); ···
22531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
88593d ¤   ¤   rcBar.left+=3;
ff4c4c ¤   ¤   rcBar.top+=3;
91dd5d ¤   ¤   rcBar.right-=3;
3444d9 ¤   ¤   rcBar.bottom-=3;
7587c7 ¤   ¤   ¤
832b40 ¤   ¤   hBrush=CreateSolidBrush (GetSysColor(COLOR_HIGHLIGHT));
7b5f06 ¤   ¤   FillRect(hDC,&rcBar,hBrush);
1be4aa ¤   ¤   DeleteObject(hBrush);·
159371 ¤   }
c7efe6 }
63af5a
1c1659 void UpdateProgValBar(HWND hwnd)
bebb36 {
db8b3d ¤   HDC hDC;
1aaf5a
2f383f ¤   hDC=GetDC(hwnd);
fd695d ¤   PaintProgValBar(hwnd,hDC);
041e24 ¤   ReleaseDC(hwnd,hDC);
28bccd ¤   ValidateRect(hwnd,NULL);
85efe6 }
4baf5a
afa5c3 LRESULT WINAPI MyProgressValidityWndProc(HWND hwnd, UINT msg,
54371e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam, LPARAM lParam)
45bb36 {
50d83c ·
4e8b3d ¤   HDC hDC;
777fa9 ¤   PAINTSTRUCT ps; ····
beaf5a
469467 ¤   switch(msg)
f5c7a1 ¤   {
3d692c ¤   ¤   case WM_PAINT: ··
67f48a ¤   ¤   {¤  ¤
ac8aa6 ¤   ¤   ¤   hDC=BeginPaint(hwnd, &ps);
--2e79 0016b933d7940110271 Page 2 of ProgVal.c
7ba4d1 ¤   ¤   ¤   PaintProgValBar(hwnd,hDC);
7dc15a ············EndPaint(hwnd, &ps);
4e7ba8 ·¤  ¤   ¤   break;
260fe4 ¤   ¤   }
406fe7 ····}
f3583d ·····
bfc543 ¤   // ·Pass all non-custom messages to old window proc
9a93c7 ¤   return CallWindowProc((FARPROC)origProgValProc, hwnd,
6a17d3 ¤   ¤   ¤   ¤   ¤   ¤   ··msg, wParam, lParam ) ;
2aefe6 }
6aaf5a
107e4d /*__Editor_settings____
98af5a
d54126 ¤   Local Variables:
737b17 ¤   tab-width: 4
530e6c ¤   End:
b85f8c ¤   vi: ts=4 sw=4
2c9e9b ¤   vim: si
6bd062 _____________________*/
--81f6 001e40a08cf40110272 Page 1 of ProgVal.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
0e1697 ¤   $Id: ProgVal.h,v 1.3.18.1 1998/11/12 03:13:28 heller Exp $
d6f7f7 ____________________________________________________________________________*/
f31ff4 #ifndef Included_PROGVAL_h¤ /* [ */
f6595b #define Included_PROGVAL_h
5faf5a
deaf5a
13d17e LRESULT WINAPI MyProgressValidityWndProc(HWND hwnd, UINT msg,·
bff9e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam, LPARAM lParam);
02af5a
22af5a
2faf5a
32146b #endif /* ] Included_PROGVAL_h */
4daf5a
f1af5a
937e4d /*__Editor_settings____
01af5a
4f4126 ¤   Local Variables:
077b17 ¤   tab-width: 4
ba0e6c ¤   End:
3e5f8c ¤   vi: ts=4 sw=4
b29e9b ¤   vim: si
e4d062 _____________________*/
--ef1a 0003e8fc35940110273 Page 1 of SaveOpen.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
a5ac5c ¤   $Id: SaveOpen.c,v 1.22.8.1 1998/11/12 03:13:29 heller Exp $
97af5a
4caf5a
b1af5a
83f7f7 ____________________________________________________________________________*/
4e5ed8 #include "precomp.h"
48af5a
4d5383 BOOL AlterEncryptedFileName(char *FileName,DWORD Actions)
26bb36 {
52f981 ¤   char DefaultExtension[5] = ".pgp";
ffaf5a
c67ef7 ¤   if((Actions & PGPCL_DETACHEDSIG) == PGPCL_DETACHEDSIG)
e1c7a1 ¤   {
101cb8 ¤   ¤   strcpy(DefaultExtension, ".sig");
379371 ¤   }
890e24 ¤   else
6bc7a1 ¤   {
06977e ¤   ¤   if((Actions & PGPCL_ASCIIARMOR) == PGPCL_ASCIIARMOR)
7e5b34 ¤   ¤   {
13e1a1 ¤   ¤   ¤   strcpy(DefaultExtension, ".asc");
cc0fe4 ¤   ¤   }
029371 ¤   }
8eaf5a
dc7ac0 ¤   strcat(FileName, DefaultExtension);
09af5a
fbc2e7 ¤   return TRUE;
57efe6 }
5eaf5a
b74664 BOOL AlterDecryptedFileName(char *FileName,char *SuggestedName)
13bb36 {
dc813a ¤   char *p;
feaf5a
48faae ¤   p = strrchr(FileName, '\\');
62af5a
36e4fd ¤   if(p!=0)
c6ef23 ¤   ¤   *(p+1)=0;
8c0e24 ¤   else
f2510e ¤   ¤   *FileName=0;
efaf5a
9ef472 ¤   strcat(FileName,SuggestedName);
01af5a
d1c2e7 ¤   return TRUE;
e1efe6 }
6eaf5a
5d829f BOOL ·SaveOutputFile(PGPContextRef Context,
76f393 ¤   ¤   ¤   ¤   ¤   ·HWND hwnd,·
f7176a ¤   ¤   ¤   ¤   ¤   ·char *Title,
467818 ¤   ¤   ¤   ¤   ¤   ·char *InputFile,·
c5599b ¤   ¤   ¤   ¤   ¤   ·PGPFileSpecRef *pOutputFileRef,
a06ef8 ¤   ¤   ¤   ¤   ¤   ·BOOL Force)
17bb36 {
fd813a ¤   char *p;
856c25 ¤   BOOL UserCancel = FALSE;
e7f720 ¤   OPENFILENAME SaveFileName;
6f59b4 ¤   FILE *ftest;
c16672 ¤   char StrRes[500];
80af5a
d2730c ¤   char FinalFile[MAX_PATH]="\0";
90fbca ¤   char DefaultExtension[MAX_PATH] = "\0";
504404 ¤   int FileStart = 0, FileExtensionStart = 0;
6eaf5a
af221b ¤   strcpy(FinalFile, InputFile);
13af5a
a86a46 ¤   if((p = strrchr(FinalFile, '\\')))
3eb00b ¤   ¤   FileStart = p - FinalFile + 1;
--88a8 000989ee13340110273 Page 2 of SaveOpen.c
e0af5a
6d2a60 ¤   if((p = strrchr(FinalFile, '.')))
650999 ¤   ¤   FileExtensionStart = p - FinalFile + 1;
5b67c5 ¤
6a45cd ¤   ftest=fopen(FinalFile,"rb");
b0af5a
aa0cba ¤   // If we could open the file, we need to ask the user
878ac1 ¤   if((ftest!=0)||(Force))
dec7a1 ¤   {
18b2bc ¤   ¤   if(ftest!=0)
2101ea ¤   ¤   ¤   fclose(ftest);
111b52 ¤   ¤
d71922 ¤   ¤   LoadString (g_hinst, IDS_SAVEFILTER, StrRes, sizeof(StrRes));
4c6a54 ¤   ¤   while (p = strrchr (StrRes, '@')) *p = '\0';
f5af5a
1f80a0 ¤   ¤   SaveFileName.lStructSize=sizeof(SaveFileName);·
2f1de9 ¤   ¤   SaveFileName.hwndOwner=hwnd;·
e928ad ¤   ····SaveFileName.hInstance=NULL;·
4b4302 ¤   ····SaveFileName.lpstrFilter=StrRes;
90d619 ¤   ¤   SaveFileName.lpstrCustomFilter=NULL;·
f92473 ¤   ····SaveFileName.nMaxCustFilter=0;·
63d6d8 ¤   ¤   SaveFileName.nFilterIndex=1;·
31d5e6 ··¤ ····SaveFileName.lpstrFile=FinalFile;·
c48871 ¤   ····SaveFileName.nMaxFile=MAX_PATH;·
a67cbe ¤   ····SaveFileName.lpstrFileTitle=NULL;·
f2853a ¤   ¤   SaveFileName.nMaxFileTitle=0;·
bd3965 ¤   ¤   SaveFileName.lpstrInitialDir=NULL;·
94dbc4 ¤   ¤   SaveFileName.lpstrTitle=Title;·
647748 ¤   ¤   SaveFileName.Flags= OFN_OVERWRITEPROMPT |·
bb6699 ¤   ¤   ¤   ¤   ¤   ¤   ¤   OFN_HIDEREADONLY |·
d2d6ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   OFN_NOREADONLYRETURN;
bc2664 #ifdef WIN32
17cfd8 ¤   ¤   SaveFileName.Flags=SaveFileName.Flags | OFN_EXPLORER;
a97454 #endif
6aa48d ¤   ¤   SaveFileName.nFileOffset=FileStart;·
0b8db6 ¤   ¤   SaveFileName.nFileExtension=FileExtensionStart;·
b2a7f8 ¤   ¤   SaveFileName.lpstrDefExt=DefaultExtension;·
c451a3 ¤   ¤   SaveFileName.lCustData=(long)NULL;·
2029a1 ¤   ¤   SaveFileName.lpfnHook=NULL;
326fb4 ¤   ¤   SaveFileName.lpTemplateName=NULL;·
bfaf5a
6bf393 ¤   ¤   UserCancel = !GetSaveFileName(&SaveFileName);
bb9371 ¤   }
a167c5 ¤
8eac61 ¤   if(!UserCancel)
a7c7a1 ¤   {
17adbe ¤   ¤   PGPNewFileSpecFromFullPath(Context,FinalFile,pOutputFileRef);
a59371 ¤   }
e9af5a
a32010 ¤   return(UserCancel);
acefe6 }
13af5a
3aa42c BOOL GetOriginalFileRef(HWND hwnd,PGPContextRef context,
de2763 ¤   ¤   ¤   ¤   ¤   ¤   char *InputFile,
b5e2ee ¤   ¤   ¤   ¤   ¤   ¤   char *OutputFile,
c94076 ¤   ¤   ¤   ¤   ¤   ¤   PGPFileSpecRef *OriginalFileRef,
4f2a43 ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndWorking)
aebb36 {
ca9ff3 ¤   char OriginalFile[MAX_PATH + 1], *p;
77415a ¤   char *pDefaultExtension;
39526c ¤   unsigned short FileStart, FileExtensionStart;
336c25 ¤   BOOL UserCancel = FALSE;
a7a404 ¤   OPENFILENAME OriginalFileName;
8759b4 ¤   FILE *ftest;
986672 ¤   char StrRes[500];
82d80d ¤   char StrRes2[500];
b1af5a
f55b70 ¤   assert(InputFile);
0208e7 ¤   assert(OriginalFileRef);
16af5a
4c5872 ¤   strcpy(OriginalFile, InputFile);
98af5a
--4911 0004af6d3c540110273 Page 3 of SaveOpen.c
e06c1d ¤   if((p = strrchr(OriginalFile, '\\')))
98fbe7 ¤   ¤   FileStart = p - OriginalFile + 1;
e60e24 ¤   else
993982 ¤   ¤   FileStart = 0;
e3af5a
b3c1ff ¤   // Get rid of the .sig extension
a9af5a
4b4106 ¤   if((p = strrchr(OriginalFile, '.')))
1ac7a1 ¤   {
593f17 ¤   ¤   *p = '\0';
b29371 ¤   }
30af5a
f2d452 ¤   ftest=fopen(OriginalFile,"rb");
91f337 ¤   if(ftest!=0)
04c7a1 ¤   {
e5e30b ¤   ¤   fclose(ftest);
a664f8 ¤   ¤   strcpy(OutputFile,OriginalFile);
e31638 ¤   ¤   PGPNewFileSpecFromFullPath( context,OriginalFile, OriginalFileRef);
b698aa ¤   ¤   return FALSE;
8a9371 ¤   }
bcaf5a
b345ed ¤   // Don't add any default extensions to the file
60af5a
ba547e ¤   pDefaultExtension=0;
95e211 ¤   FileExtensionStart=strlen(OriginalFile);
b7af5a
270c01 ¤   LoadString (g_hinst, IDS_SAVEFILTER, StrRes, sizeof(StrRes));
86394f ¤   while (p = strrchr (StrRes, '@')) *p = '\0';
c1af5a
39d173 ¤   LoadString (g_hinst, IDS_SELSIGNFILE, StrRes2, sizeof(StrRes2));
23af5a
31987e ¤   OriginalFileName.lStructSize=sizeof(OriginalFileName);·
f9719e ····OriginalFileName.hwndOwner=hwnd;·
17db64 ····OriginalFileName.hInstance=NULL;·
53a7f7 ····OriginalFileName.lpstrFilter=StrRes;·
85d771 ····OriginalFileName.lpstrCustomFilter=NULL;·
5efcd5 ····OriginalFileName.nMaxCustFilter=0;·
3abaaf ····OriginalFileName.nFilterIndex=1;·
c79db4 ····OriginalFileName.lpstrFile=OriginalFile;·
0c4895 ····OriginalFileName.nMaxFile=MAX_PATH;·
83344b ····OriginalFileName.lpstrFileTitle=NULL;·
51826e ····OriginalFileName.nMaxFileTitle=0;·
4d3636 ····OriginalFileName.lpstrInitialDir=NULL;·
79cf02 ····OriginalFileName.lpstrTitle=StrRes2;·
d6b805 ····OriginalFileName.Flags=OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
50e2f4 ¤   ¤   ¤   ¤   ¤   ¤   ···OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
f32664 #ifdef WIN32
8a78e7 ¤   OriginalFileName.Flags=OriginalFileName.Flags | OFN_EXPLORER;
c67454 #endif
f4c49c ····OriginalFileName.nFileOffset=FileStart;·
9832b4 ····OriginalFileName.nFileExtension=FileExtensionStart;·
e8adc9 ····OriginalFileName.lpstrDefExt=pDefaultExtension;·
585ef0 ····OriginalFileName.lCustData=(long)NULL;·
97fe38 ····OriginalFileName.lpfnHook=NULL;
7c444b ····OriginalFileName.lpTemplateName=NULL;·
44af5a
b8b623 ¤   if(GetOpenFileName(&OriginalFileName))
56c7a1 ¤   {
5064f8 ¤   ¤   strcpy(OutputFile,OriginalFile);
141638 ¤   ¤   PGPNewFileSpecFromFullPath( context,OriginalFile, OriginalFileRef);
199371 ¤   }
300e24 ¤   else
c7069e ¤   ¤   UserCancel = TRUE;
7aaf5a
472010 ¤   return(UserCancel);
0fefe6 }
d0af5a
baaf5a
f37e4d /*__Editor_settings____
7daf5a
da4126 ¤   Local Variables:
4a7b17 ¤   tab-width: 4
--5391 001aced8fb240110273 Page 4 of SaveOpen.c
490e6c ¤   End:
d25f8c ¤   vi: ts=4 sw=4
979e9b ¤   vim: si
51d062 _____________________*/
acaf5a
--76a9 0006562044740110274 Page 1 of Tempest.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
49cb05 ¤   $Id: Tempest.c,v 1.11.2.1.2.1 1998/11/12 03:13:29 heller Exp $
c7f7f7 ____________________________________________________________________________*/
d6af5a
185ed8 #include "precomp.h"
7baf5a
66484f #define DEACTIVATETIMERID 100
96027f #define DEACTIVATETIME 50
43af5a
25ca56 #define MINDLGX 300
d1d2c6 #define MINDLGY 200
ecaf5a
18aef1 #define MODX 16
44b3a6 #define XMARGIN 2
2fb5e9 #define YMARGIN 1
5b3e4c #define TABWIDTH 4
9daf5a
0a377d // This is our global tempest viewer variable structure
9a60ab // used in case we ever need to make this reentrant. Globals
057010 // are Very Bad (tm).
689d59 typedef struct _GTV {
5c2a51 ¤   HWND hdlg;
c17cca ¤   HWND hwndLB;
9c274e ¤   char *pInput;
6b1d33 ¤   HBITMAP hAlphaBmp;
906e0d ¤   HBITMAP hTempABmp;
da6270 ¤   HBITMAP hTempBBmp;
65665b ¤   HBITMAP hTempCBmp;
867a8a ¤   HBITMAP hTempDBmp;
dbe399 ¤   HFONT hFixedWidthFont;
a21ddf ¤   HBRUSH hBackBrush;
32f3ad ¤   int LtrX;
5da971 ¤   int LtrY;
e63788 ¤   COLORREF BackColor;
30bfb5 ¤   COLORREF TextColor;
ba9090 ¤   BOOL bDoTempest;
8b440d } GTV;
edaf5a
a16b0a void SizeTempest(HWND hdlg,int Width,int Height)
b6bb36 {
51768f ¤   InvalidateRect(GetDlgItem(hdlg, IDC_TEMPESTLIST),NULL,TRUE);
91af5a
59a089 ¤   MoveWindow(GetDlgItem(hdlg, IDC_TEMPESTLIST),
00c8c2 ¤   ¤   10,10,
eb2b68 ¤   ¤   Width-20,Height-45,
5cbe2f ¤   ¤   TRUE);
e6af5a
f64703 ¤   InvalidateRect(GetDlgItem(hdlg, IDC_TEMPESTFONT),NULL,TRUE);
8faf5a
4c9910 ¤   MoveWindow(GetDlgItem(hdlg, IDC_TEMPESTFONT),
465930 ¤   ¤   10,Height-25,
1e8840 ¤   ¤   300,15,
bfbe2f ¤   ¤   TRUE);
4eefe6 }
e0af5a
d5465d //
87728e // ·DrawListViewItem
7d465d //
e90917 // ·This routine, given a standard Windows LPDRAWITEMSTRUCT, draws the
fa03dd // ·elements of our custom listview.
69af5a
7e4f8a void DrawListBoxItem(GTV *gtv,LPDRAWITEMSTRUCT lpDrawItem)
85bb36 {
41ad69 ¤   HDC mDC;
859e86 ¤   UINT i;
9073ed ¤   char *szString;
65c071 ¤   int StringIndex;
--9171 0004bf6f20740110274 Page 2 of Tempest.c
acc67a ¤   int xCoord,yCoord;
a39700 ¤   int pos;
6baf5a
fda806 ¤   srand( (unsigned)time( NULL ) );
29af5a
eb4505 ¤   // ·Create a memory DC for bitmap work
766acf ¤   mDC = CreateCompatibleDC( lpDrawItem->hDC );
14869e ····
a190c4 ¤   if(!gtv->bDoTempest)
65c7a1 ¤   {
ef2773 ¤   ¤   SelectObject( mDC, gtv->hAlphaBmp); ·
089371 ¤   }
38af5a
93abed ¤   FillRect(lpDrawItem->hDC,&(lpDrawItem->rcItem),gtv->hBackBrush);
dfaf5a
dbc33d ¤   szString=(char *)lpDrawItem->itemData;
a3af5a
f7eee9 ¤   if(szString==NULL)
5d99bf ¤   ¤   return;
0caf5a
0bdc70 ¤   pos=0;
99104c ¤   i=0;
8aaf5a
ae9adf ¤   while((szString[i]!=0)&&(szString[i]!='\n'))
92c7a1 ¤   {
b97f3a ¤   ¤   StringIndex=szString[i];
1eaf5a
b1fe51 ¤   ¤   if(StringIndex=='\t')
2d5b34 ¤   ¤   {
ddcd87 ¤   ¤   ¤   pos=((pos/TABWIDTH)+1)*TABWIDTH;
420fe4 ¤   ¤   }
fd0e1d ¤   ¤   else
b95b34 ¤   ¤   {
a26ca3 ¤   ¤   ¤   // Randomly select through jittered fonts to
45ebd1 ¤   ¤   ¤   // confuse snoopers further
7d1abe ¤   ¤   ¤   if(gtv->bDoTempest)
2af776 ¤   ¤   ¤   {
cf70f9 ¤   ¤   ¤   ¤   switch((4*rand())/RAND_MAX)
de72c3 ¤   ¤   ¤   ¤   {
b9f93d ¤   ¤   ¤   ¤   ¤   case 0:
c26b22 ¤   ¤   ¤   ¤   ¤   ¤   SelectObject( mDC, gtv->hTempABmp); ·
4e00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
74a3e1 ¤   ¤   ¤   ¤   ¤   case 1:
07bd25 ¤   ¤   ¤   ¤   ¤   ¤   SelectObject( mDC, gtv->hTempBBmp); ·
6e00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
de4c85 ¤   ¤   ¤   ¤   ¤   case 2:
f4f0d8 ¤   ¤   ¤   ¤   ¤   ¤   SelectObject( mDC, gtv->hTempCBmp); ·
7300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
195ee4 ¤   ¤   ¤   ¤   ¤   default:
d5193a ¤   ¤   ¤   ¤   ¤   ¤   SelectObject( mDC, gtv->hTempDBmp); ·
ac00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
692613 ¤   ¤   ¤   ¤   }
1aa3a6 ¤   ¤   ¤   }
67af5a
115d19 ¤   ¤   ¤   xCoord=(StringIndex-' ')%MODX;
e5717a ¤   ¤   ¤   yCoord=(StringIndex-' ')/MODX;
91af5a
a59d47 ¤   ¤   ¤   BitBlt(lpDrawItem->hDC,// handle to destination device context·
0241ab ¤   ¤   ¤   ¤   lpDrawItem->rcItem.left + XMARGIN + pos * gtv->LtrX,
ec1bec ¤   ¤   ¤   ¤   // x-coordinate of destination rectangle's upper-left ·
84f763 ¤   ¤   ¤   ¤   lpDrawItem->rcItem.top + YMARGIN,
271bec ¤   ¤   ¤   ¤   // x-coordinate of destination rectangle's upper-left ·
44d905 ¤   ¤   ¤   ¤   gtv->LtrX, ··// width of destination rectangle·
5a4883 ¤   ¤   ¤   ¤   gtv->LtrY, ··// height of destination rectangle·
0f61b0 ¤   ¤   ¤   ¤   mDC, ···// handle to source device context·
0e16ee ¤   ¤   ¤   ¤   xCoord*gtv->LtrX,
09867c ¤   ¤   ¤   ¤   // x-coordinate of source rectangle's upper-left ··
eeb4d5 ¤   ¤   ¤   ¤   yCoord*gtv->LtrY,
dcaa24 ¤   ¤   ¤   ¤   // y-coordinate of source rectangle's upper-left·
5425e6 ¤   ¤   ¤   ¤   SRCCOPY);
46af5a
4b7b61 ¤   ¤   ¤   pos++;
--ac51 0006a130b5940110274 Page 3 of Tempest.c
b50fe4 ¤   ¤   }
94347d ¤   ¤   i++;
769371 ¤   }
14af5a
694f75 ¤   // ·Kill off the memory DC, unlocking passed BMP
4fb010 ¤   DeleteDC( mDC ); ·
59af5a
323471 ····return;
0defe6 }
1caf5a
ea1dd4 // Main_OnDrawItem
5c465d //
80b626 // Entry function for the message handler. Basically, we want to draw
8cb689 // the whole thing no matter what.
e5af5a
622199 BOOL Main_OnDrawItem(GTV *gtv, const DRAWITEMSTRUCT * lpDrawItem)
97bb36 {
048972 ····// Make sure the control is the listview control
17ae1e ····if (lpDrawItem->CtlType != ODT_LISTBOX)
bc81ae ········return FALSE;
7caf5a
8efb0f ····switch (lpDrawItem->itemAction)
0c3b37 ····{
1bbeb0 ········case ODA_DRAWENTIRE:
02d89d ········case ODA_FOCUS:
f82c3c ········case ODA_SELECT:
c027f7 ············DrawListBoxItem(gtv,(LPDRAWITEMSTRUCT)lpDrawItem);
5f8632 ············break;
446fe7 ····}
55af5a
248011 ····return TRUE;
78efe6 }
55af5a
d5d95e // Main_OnMeasureItem
2d465d //
804e61 // Entry function for the message handler. We need to get the width and
0ed969 // height of the font we're using.
2daf5a
5dd158 void Main_OnMeasureItem(GTV *gtv, MEASUREITEMSTRUCT * lpMeasureItem)
69bb36 {
34979a ·····// Make sure the control is the listview control
8e2b58 ····if (lpMeasureItem->CtlType != ODT_LISTBOX)
9ddc81 ········return;
65af5a
167b5f ····// Add a little extra space between items
57c2ea ····lpMeasureItem->itemHeight = gtv->LtrY + YMARGIN;
6eefe6 }
91af5a
a95f40 UINT TempestStringWidth(char *szString)
8abb36 {
5b6358 ¤   UINT pos,i;
53af5a
f4dc70 ¤   pos=0;
cbaf5a
7f104c ¤   i=0;
89af5a
2b9adf ¤   while((szString[i]!=0)&&(szString[i]!='\n'))
4dc7a1 ¤   {
64eece ¤   ¤   // Handle Tabs
d166e3 ¤   ¤   if(szString[i]=='\t')
075b34 ¤   ¤   {
0ccd87 ¤   ¤   ¤   pos=((pos/TABWIDTH)+1)*TABWIDTH;
da0fe4 ¤   ¤   }
da0e1d ¤   ¤   else
0f5b34 ¤   ¤   {
1e7b61 ¤   ¤   ¤   pos++;
a60fe4 ¤   ¤   }
30af5a
e4347d ¤   ¤   i++;
bf9371 ¤   }
57af5a
6ade4e ¤   return pos;
--5724 00033134ce340110274 Page 4 of Tempest.c
7aefe6 }
46af5a
b43c5c void AddListBoxLines(GTV *gtv)
ed7142 {·
922fb6 ¤   int width,maxwidth;
de3e0a ¤   char *szNew,*szOld;
a8af5a
f1f164 ¤   maxwidth=0;
f40cde ¤   szNew=gtv->pInput;
35af5a
fc1e73 ¤   while(szNew!=0)
5cc7a1 ¤   {
3a68c2 ¤   ¤   szOld=szNew;
3caf5a
4d2072 ¤   ¤   szNew=strstr(szOld,"\n");
02af5a
06d765 ¤   ¤   if(szNew!=0)
2e5b34 ¤   ¤   {
bd0df5 ¤   ¤   ¤   szNew++;
610fe4 ¤   ¤   }
20af5a
447f06 ¤   ¤   width=TempestStringWidth(szOld)*gtv->LtrX+2*XMARGIN;
6daf5a
acdfd5 ¤   ¤   if(width>maxwidth)
c25b34 ¤   ¤   {
222f25 ¤   ¤   ¤   maxwidth=width;
dd0fe4 ¤   ¤   }
9a2b85 ¤   ¤   ¤   ¤
9c3701 ¤   ¤   SendMessage(gtv->hwndLB,
05b5b4 ¤   ¤   ¤   LB_ADDSTRING,0,(LPARAM)szOld);
6c9371 ¤   }
4faf5a
758c57 ¤   SendMessage(gtv->hwndLB,
9d07bb ¤   ¤   LB_SETHORIZONTALEXTENT,(WPARAM)maxwidth,0);
8faf5a
fbefe6 }
e5af5a
3da2a9 void RedoTempestList(GTV *gtv)
b9bb36 {
eb5bda ¤   RECT rc;
4faf5a
873a5b ¤   if(gtv->hwndLB!=NULL)
5aa280 ¤   ¤   DestroyWindow(gtv->hwndLB);
83af5a
582861 ¤   gtv->hwndLB=CreateWindowEx (WS_EX_CLIENTEDGE,"listbox", NULL,
dcc4c7 ¤   ¤   WS_CHILD | WS_VISIBLE | WS_VSCROLL | ·WS_HSCROLL |
d09069 ¤   ¤   LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | WS_TABSTOP,
1a3d98 ¤   ¤   0,0,0,0,
f4386d ¤   ¤   gtv->hdlg, (HMENU)IDC_TEMPESTLIST,
001704 ¤   ¤   (HINSTANCE) g_hinst,
34f94c ¤   ¤   NULL) ;
58af5a
91b68a ¤   // Size the viewer
d865fe ¤   GetClientRect(gtv->hdlg,&rc);
00662e ¤   SizeTempest(gtv->hdlg,rc.right-rc.left,rc.bottom-rc.top);
dcaf5a
61bceb ¤   AddListBoxLines(gtv);
53efe6 }
13af5a
b3d5c8 // Get rid of all drawing elements to clean up
792db7 void UninitFontBitmap(GTV *gtv)
0fbb36 {
69d628 ¤   if(gtv->hFixedWidthFont!=NULL)
5817d0 ¤   ¤   DeleteObject(gtv->hFixedWidthFont);
e665e3 ¤   gtv->hFixedWidthFont=NULL;
56af5a
de4ed0 ¤   if(gtv->hBackBrush!=NULL)
ca1388 ¤   ¤   DeleteObject(gtv->hBackBrush);
de0e81 ¤   gtv->hBackBrush=NULL;
cbaf5a
a1d372 ¤   if(gtv->hAlphaBmp!=NULL)
33a45a ¤   ¤   DeleteObject(gtv->hAlphaBmp);
--25c2 000648799f240110274 Page 5 of Tempest.c
53ef8b ¤   gtv->hAlphaBmp=NULL;
fbaf5a
c2253f ¤   if(gtv->hTempABmp!=NULL)
0e7cd4 ¤   ¤   DeleteObject(gtv->hTempABmp);
8aa2d1 ¤   if(gtv->hTempBBmp!=NULL)
61d4ba ¤   ¤   DeleteObject(gtv->hTempBBmp);
d92784 ¤   if(gtv->hTempCBmp!=NULL)
4d4b6f ¤   ¤   DeleteObject(gtv->hTempCBmp);
cba51c ¤   if(gtv->hTempDBmp!=NULL)
f98c77 ¤   ¤   DeleteObject(gtv->hTempDBmp);
a1af5a
c3ef34 ¤   gtv->hTempABmp=gtv->hTempBBmp=gtv->hTempCBmp=gtv->hTempDBmp=NULL;
98efe6 }
24af5a
6498f7 // Render the font bitmaps (either normal or tempest)
6b4c32 // if they aren't done already. Create the background·
1afd2e // brush, and set the text and background colors.
e14495 void InitFontBitmap(HWND hwnd,GTV *gtv)
c1bb36 {
c2c1dd ¤   LOGFONT lf;
ae0dc1 ¤   TEXTMETRIC tm;
6c5d1d ¤   HDC hdc,hdcMem;
74af5a
fb0d7a ¤   // Get rid of all drawing elements to clean up
6be593 ¤   UninitFontBitmap(gtv);
97af5a
d01fc4 ¤   // **** Create either normal or load tempest fonts ****
6aeddc ¤   SystemParametersInfo (SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0);
60706f ¤   strcpy(lf.lfFaceName,"Courier"); ·// as per prz
51156d ¤   lf.lfPitchAndFamily=FF_MODERN|FIXED_PITCH;
94af5a
1a5853 ¤   gtv->hFixedWidthFont = CreateFontIndirect (&lf);
8aaf5a
eebbd4 ····hdc=GetDC(gtv->hdlg); // Get DC
c482a3 ¤   hdcMem=CreateCompatibleDC(hdc);
45af5a
bc17f0 ¤   SelectObject (hdcMem, gtv->hFixedWidthFont); // Font for non Tempest
44c125 ¤   GetTextMetrics (hdcMem, &tm);
ecaf5a
f94185 ¤   if(gtv->bDoTempest)
29c7a1 ¤   {
45857f ¤   ¤   if(tm.tmHeight>=19)
1c5b34 ¤   ¤   {
150fb4 ¤   ¤   ¤   gtv->hTempABmp = LoadBitmap (g_hinst,·
c995cc ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MA13X24));; // Tempest Font
2f0cf6 ¤   ¤   ¤   gtv->hTempBBmp = LoadBitmap (g_hinst,·
fc6314 ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MB13X24));; // Tempest Font
74f5c7 ¤   ¤   ¤   gtv->hTempCBmp = LoadBitmap (g_hinst,·
c6315c ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MC13X24));; // Tempest Font
c10a72 ¤   ¤   ¤   gtv->hTempDBmp = LoadBitmap (g_hinst,·
6c86b5 ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MD13X24));; // Tempest Font
f3af5a
1da336 ¤   ¤   ¤   gtv->LtrX=13;
410ed5 ¤   ¤   ¤   gtv->LtrY=24;
b20fe4 ¤   ¤   }
f20e1d ¤   ¤   else
975b34 ¤   ¤   {
710fb4 ¤   ¤   ¤   gtv->hTempABmp = LoadBitmap (g_hinst,·
f7cf53 ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MA8X14));; // Tempest Font
fd0cf6 ¤   ¤   ¤   gtv->hTempBBmp = LoadBitmap (g_hinst,·
ce90b2 ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MB8X14));; // Tempest Font
3cf5c7 ¤   ¤   ¤   gtv->hTempCBmp = LoadBitmap (g_hinst,·
e55de2 ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MC8X14));; // Tempest Font
2f0a72 ¤   ¤   ¤   gtv->hTempDBmp = LoadBitmap (g_hinst,·
d92f70 ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_MD8X14));; // Tempest Font
8faf5a
6087c7 ¤   ¤   ¤
bc7e18 ¤   ¤   ¤   gtv->LtrX=8;
812b18 ¤   ¤   ¤   gtv->LtrY=14;
860fe4 ¤   ¤   }
f1af5a
649675 ¤   ¤   gtv->TextColor=RGB(0,0,0); // White
--d3aa 000adbf49ae40110274 Page 6 of Tempest.c
e0af5a
6669ad ¤   ¤   SelectObject(hdcMem,gtv->hTempABmp); ·// Bitmap for hdcMem
30af5a
c6b2ca ¤   ¤   gtv->BackColor=GetPixel(hdcMem,0,0);
24b49f ¤   ¤   gtv->hBackBrush=CreateSolidBrush(gtv->BackColor); // Create the brush n¶
4a6e46 eeded
1d9371 ¤   }
760e24 ¤   else
fec7a1 ¤   {
c9212c ¤   ¤   char myChar;
56ee4b ¤   ¤   RECT rc;
2a2a1e ¤   ¤   int i;
43af5a
c89993 ¤   ¤   gtv->TextColor=GetSysColor (COLOR_WINDOWTEXT); // Text Color
816054 ¤   ¤   gtv->BackColor=GetSysColor (COLOR_WINDOW); // Window Color
27af5a
76b49f ¤   ¤   gtv->hBackBrush=CreateSolidBrush(gtv->BackColor); // Create the brush n¶
ab6e46 eeded
34af5a
acc624 ¤   ¤   gtv->LtrX=tm.tmMaxCharWidth;
3f2589 ¤   ¤   gtv->LtrY=tm.tmHeight;
d5af5a
001af7 ¤   ¤   rc.top=rc.left=0;
cd315b ¤   ¤   rc.right=MODX*gtv->LtrX; // 16 x 16 for 256 characters
8080b2 ¤   ¤   rc.bottom=MODX*gtv->LtrY;
e8af5a
adee88 ¤   ¤   gtv->hAlphaBmp=CreateCompatibleBitmap(hdc,rc.right,rc.bottom);·
16c81d ¤   ····SelectObject(hdcMem,gtv->hAlphaBmp); ·// Bitmap for hdcMem
08af5a
ad1b41 ¤   ¤   SetBkColor (hdcMem, gtv->BackColor);
5f8ba7 ¤   ¤   SetTextColor (hdcMem, gtv->TextColor);
73af5a
09b149 ¤   ¤   FillRect(hdcMem,&rc,gtv->hBackBrush);
8caf5a
52cdfb ¤   ¤   for(i=' ';i<256;i++) // Draw characters starting from ' ' like UK.
b55b34 ¤   ¤   {
829b3c ¤   ¤   ¤   if(isprint(i))
29f776 ¤   ¤   ¤   {
8f7597 ¤   ¤   ¤   ¤   myChar=(char)i;
03af5a
54ec28 ¤   ¤   ¤   ¤   TextOut(hdcMem,
b68f99 ¤   ¤   ¤   ¤   ¤   ((i-' ')%MODX)*gtv->LtrX,
ecd3d5 ¤   ¤   ¤   ¤   ¤   ((i-' ')/MODX)*gtv->LtrY,
a17be9 ¤   ¤   ¤   ¤   ¤   &myChar,
5211b5 ¤   ¤   ¤   ¤   ¤   1);
0fa3a6 ¤   ¤   ¤   }
8a0fe4 ¤   ¤   }
1f9371 ¤   }
bbaf5a
d3030b ¤   ReleaseDC(hwnd,hdc); // Release DC
8db72b ¤   DeleteDC(hdcMem);
a7af5a
149030 ¤   RedoTempestList(gtv);
9aefe6 }
c8af5a
e2ee2c BOOL WINAPI TempestDlgProc(HWND hdlg, UINT uMsg,·
d0d85e ·····························WPARAM wParam, LPARAM lParam)
a7bb36 {
cc827b ····switch(uMsg)
403b37 ····{
162aad ········case WM_INITDIALOG:
b84661 ········{·
7e5eb3 ¤   ¤   ¤   GTV *gtv;
61af5a
782674 ¤   ¤   ¤   gtv=(GTV *)lParam;
bc24a9 ¤   ¤   ¤   SetWindowLong(hdlg,GWL_USERDATA,(long)lParam);
c8af5a
070ff0 ¤   ¤   ¤   // Save some of our window handles
14c6ec ¤   ¤   ¤   gtv->hdlg=hdlg;
e11c68 ¤   ¤   ¤   gtv->hwndLB=GetDlgItem(hdlg,IDC_TEMPESTLIST);
dcaf5a
adba0d ¤   ¤   ¤   InitFontBitmap(gtv->hdlg,gtv);
--613e 000df90e9ab40110274 Page 7 of Tempest.c
002e6c ¤   ¤   ¤   RedoTempestList(gtv);
2baf5a
a42d57 ¤   ¤   ¤   // Stick text into owner drawn list box and setup checkbox
c77bdf ¤   ¤   ¤   Button_SetCheck(GetDlgItem(hdlg,IDC_TEMPESTFONT),gtv->bDoTempest);
44af5a
6aada9 ¤   ¤   ¤   // Force window to the foreground
ffe3e2 ¤   ¤   ¤   SetForegroundWindow(hdlg);
43b7b7 ¤   ¤   ¤   SetFocus(gtv->hwndLB);
bca683 ············return FALSE;
b67fb0 ········}
62af5a
764e34 ¤   ¤   case WM_GETMINMAXINFO:
aa5b34 ¤   ¤   {
0a8590 ¤   ¤   ¤   MINMAXINFO* lpmmi;
a4af5a
fdb98a ¤   ¤   ····lpmmi = (MINMAXINFO*) lParam;
a53d2d ····¤   ¤   lpmmi->ptMinTrackSize.x = MINDLGX;
f8625c ····¤   ¤   lpmmi->ptMinTrackSize.y = MINDLGY;
698632 ············break;
070fe4 ¤   ¤   }
39af5a
493c22 ········case WM_SIZE:
322b60 ········{
7c07da ¤   ¤   ¤   unsigned short Width, Height;
93d850 ¤   ¤   ¤   Width = LOWORD(lParam); ·// width of client area·
33d81f ¤   ¤   ¤   Height = HIWORD(lParam); // height of client area·
a5af5a
5f7854 ¤   ¤   ¤   SizeTempest(hdlg,Width,Height);
1bcdcb ¤   ¤   ¤   break;
ab7fb0 ········}
52af5a
ea2d38 ¤   ¤   // Make sure we set color to white/black for Tempest
199e6c ¤   ¤   case WM_CTLCOLORLISTBOX:
6fc329 ¤   ¤   { ·········
8f303a ¤   ¤   ¤   HDC hdcLB;
de8c90 ¤   ¤   ¤   HWND hwndLB;
8c5eb3 ¤   ¤   ¤   GTV *gtv;
56af5a
94cd01 ¤   ¤   ¤   gtv=(GTV *)GetWindowLong(hdlg,GWL_USERDATA);
7eaf5a
b860df ¤   ¤   ¤   hdcLB = (HDC) wParam;
26fc66 ¤   ¤   ¤   hwndLB = (HWND) lParam;
b7af5a
901b62 ¤   ¤   ¤   SetTextColor(hdcLB,gtv->TextColor);
8c044b ¤   ¤   ¤   SetBkColor(hdcLB, gtv->BackColor);
0967c5 ¤
66047b ¤   ¤   ··¤ return (BOOL)gtv->hBackBrush;
380fe4 ¤   ¤   }
31af5a
c0f777 ········case WM_SYSCOLORCHANGE:
755b34 ¤   ¤   {
db5eb3 ¤   ¤   ¤   GTV *gtv;
beaf5a
b4cd01 ¤   ¤   ¤   gtv=(GTV *)GetWindowLong(hdlg,GWL_USERDATA);
125b9a ¤   ¤   ¤   InitFontBitmap(hdlg,gtv);
008632 ············break;
647fb0 ········}
adaf5a
352267 ········case WM_DRAWITEM:·
4d2b60 ········{
4b5eb3 ¤   ¤   ¤   GTV *gtv;
e1af5a
8acd01 ¤   ¤   ¤   gtv=(GTV *)GetWindowLong(hdlg,GWL_USERDATA);
c1af5a
bbdf44 ············Main_OnDrawItem(gtv,(LPDRAWITEMSTRUCT) lParam);
5051a3 ············return TRUE;
4a7fb0 ········}
6faf5a
ac775f ········case WM_MEASUREITEM:
b75b34 ¤   ¤   {
f05eb3 ¤   ¤   ¤   GTV *gtv;
dfaf5a
--0741 0008b77e9ef40110274 Page 8 of Tempest.c
35cd01 ¤   ¤   ¤   gtv=(GTV *)GetWindowLong(hdlg,GWL_USERDATA);
61af5a
919e9b ············Main_OnMeasureItem(gtv,(LPMEASUREITEMSTRUCT) lParam);
7551a3 ············return TRUE;
0f0fe4 ¤   ¤   }
20af5a
ad5dc6 ¤   ¤   case WM_ACTIVATE:
535b34 ¤   ¤   {
3d7dde ¤   ¤   ¤   if(LOWORD(wParam)==WA_INACTIVE)
caf776 ¤   ¤   ¤   {
8e9bbb ¤   ¤   ¤   ¤   // Killing the window right away _really_ irks
3c8a0d ¤   ¤   ¤   ¤   // Win95, so we delay 50 ms (basically till everything
b2819d ¤   ¤   ¤   ¤   // gets cleaned up in the OS)
67a4d5 ¤   ¤   ¤   ¤   SetTimer(hdlg,DEACTIVATETIMERID,DEACTIVATETIME,NULL);
7ea3a6 ¤   ¤   ¤   }
54cdcb ¤   ¤   ¤   break;
190fe4 ¤   ¤   }
16af5a
3a98c6 ¤   ¤   // Here we kill the window from the timer...
2bdde2 ¤   ¤   case WM_TIMER:
d12c97 ¤   ¤   case WM_CLOSE:
d0dad9 ¤   ¤   case WM_DESTROY:
d9d725 ¤   ¤   case WM_QUIT:
d75b34 ¤   ¤   {
cfd720 ¤   ¤   ¤   EndDialog(hdlg, FALSE);
9dcdcb ¤   ¤   ¤   break;
910fe4 ¤   ¤   }
d1af5a
4baff6 ········case WM_COMMAND:
ad2b60 ········{
a014e1 ············switch(wParam)
dd2cc2 ············{
fe4c2f ¤   ¤   ¤   ¤   case IDC_TEMPESTFONT:
0b72c3 ¤   ¤   ¤   ¤   {
8c1052 ¤   ¤   ¤   ¤   ¤   GTV *gtv;
beaf5a
d7319d ¤   ¤   ¤   ¤   ¤   gtv=(GTV *)GetWindowLong(hdlg,GWL_USERDATA);
5faf5a
b886b6 ¤   ¤   ¤   ¤   ¤   gtv->bDoTempest=!gtv->bDoTempest;
8aaf5a
305eb1 ¤   ¤   ¤   ¤   ¤   InitFontBitmap(hdlg,gtv);
7eaf5a
2baa0e ¤   ¤   ¤   ¤   ¤   InvalidateRect(gtv->hwndLB,NULL,TRUE);
c8b8b3 ¤   ¤   ¤   ¤   ¤   UpdateWindow(gtv->hwndLB);
48f151 ¤   ¤   ¤   ¤   ····break;
f42613 ¤   ¤   ¤   ¤   }
f694aa ¤   ¤   ¤   ¤   ¤   ¤
9f8722 ¤   ¤   ¤   ¤   case IDCANCEL:
9272c3 ¤   ¤   ¤   ¤   {
159a13 ¤   ¤   ¤   ¤   ¤   EndDialog(hdlg, FALSE);
9414c3 ¤   ¤   ¤   ¤   ¤   break;
5a2613 ¤   ¤   ¤   ¤   }
fa7812 ············}
2751a3 ············return TRUE;
8f7fb0 ········}
a5af5a
9a6fe7 ····}
9830cb ····return FALSE;
96efe6 }
06af5a
01af5a
6d91f1 UINT TempestViewer(void *PGPsc,HWND hwnd,char *pInput,DWORD dwInSize)
49bb36 {
136daf ¤   UINT ReturnValue = FALSE;
61a215 ¤   BOOL DialogReturn = FALSE;
bed9e0 ¤   WNDCLASS wndclass;
b264a2 ¤   PGPContextRef context;
0d7694 ¤   PGPMemoryMgrRef¤memmgr;
bae19c ¤   GTV *gtv;
c9f5b4 ¤   int Response;
6598b7 ¤   char szCaption[100];
8b9839 ¤   char szMessage[256];
--7d4a 001114f88f140110274 Page 9 of Tempest.c
2a67c5 ¤
b523b8 ¤   LoadString (g_hinst, IDS_FYEOCAPTION, szCaption, sizeof(szCaption));
318779 ¤   LoadString (g_hinst, IDS_FYEOMSG, szMessage, sizeof(szMessage));
91af5a
167442 ¤   Response=MessageBox(hwnd,szMessage,szCaption,
ce443b ¤   ¤   MB_OKCANCEL|MB_SETFOREGROUND|MB_ICONEXCLAMATION);
0467c5 ¤
2641d3 ¤   if(Response==IDCANCEL)
b998aa ¤   ¤   return FALSE;
20af5a
7e0912 ¤   assert(pInput);
1baf5a
a1625b ¤   context=(PGPContextRef)PGPsc;
e044b8 ¤   memmgr = PGPGetContextMemoryMgr (context);
ccaf5a
64d79f ·¤  memset(&wndclass,0x00,sizeof(WNDCLASS));
aeaf5a
161e92 ····wndclass.style = CS_HREDRAW | CS_VREDRAW; ·····························
222469 ····wndclass.lpfnWndProc = (WNDPROC)DefDlgProc;·
c045f6 ····wndclass.cbClsExtra = 0; ·············
c900e3 ····wndclass.cbWndExtra = DLGWINDOWEXTRA; ·············
6d6c53 ····wndclass.hInstance = g_hinst; ······
ae6b04 ····wndclass.hIcon = LoadIcon (g_hinst, MAKEINTRESOURCE(IDI_FYEO));
f85135 ····wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
60258f ····wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
bd6f3c ····wndclass.lpszMenuName = NULL;
eefa32 ····wndclass.lpszClassName = "PGPtempestClass";
ceaf5a
1ca4ba ····RegisterClass (&wndclass);
c9af5a
fd7deb ¤   // Globals structure for re-entrancy
365a4a ¤   gtv=(GTV *)malloc(sizeof(GTV));
ca1984 ¤   memset(gtv,0x00,sizeof(GTV));
3caf5a
72ffb3 ¤   gtv->pInput=pInput;
49ac86 ¤   gtv->bDoTempest=TRUE; // Always use Tempest font by default
e9af5a
891277 ¤   DialogReturn = DialogBoxParam(g_hinst,·
e46c75 ¤   ¤   MAKEINTRESOURCE(IDD_TEMPEST), hwnd,·
e1eef4 ¤   ¤   TempestDlgProc, (LPARAM) gtv);
7aaf5a
6fe593 ¤   UninitFontBitmap(gtv);
01af5a
3186f4 ¤   free(gtv);
bbaf5a
befb18 ¤   return DialogReturn;
34efe6 }
43af5a
8d7e4d /*__Editor_settings____
f8af5a
ac4126 ¤   Local Variables:
d97b17 ¤   tab-width: 4
bd0e6c ¤   End:
265f8c ¤   vi: ts=4 sw=4
409e9b ¤   vim: si
11d062 _____________________*/
--142f 0000de8d09d40110275 Page 1 of Utils.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
3d68ee ¤   $Id: Utils.c,v 1.57.2.6.2.1 1998/11/12 03:13:30 heller Exp $
63f7f7 ____________________________________________________________________________*/
c25ed8 #include "precomp.h"
a2474b #include "PGPhk.h"
26af5a
57accf #define PGPPATHREG "Software\\Network Associates\\PGP60\\PGPkeys"
45af5a
8520c5 DWORD g_uPurgePassphraseCacheMessage;
44af5a
b5c640 #pragma data_seg(".SHARDAT")
3299b7 static UINT g_KeyArray[4]={0,0,0,0};
828898 static UINT * lpJournalKeys = 0;
5f790f static UINT g_KeyIndex = 0;
bfac37 static UINT g_NumKeys = 0;
63f4b6 static HHOOK ·g_hJournalHook=NULL ;
43d116 #pragma data_seg()
2daf5a
c46af7 #define LAUNCHKEYS_TIMER¤   ¤   53
f1596b #define MILLISECONDS_PER_DAY¤   86400000
58af5a
c2dab8 #define SK_KEYDOWN ·0x8000
4a4f69 #define SK_SYSKEY ··0x4000
b4af5a
cf9fef BOOL WINAPI SendKeys( UINT *lpKeys, UINT nKeys );
0caf5a
9c0218 LRESULT·
7cbbaa PGPscMessageBox (
d23172 ¤   ¤   ·HWND¤  hWnd,·
2f5442 ¤   ¤   ·INT¤   iCaption,·
7276b8 ¤   ¤   ·INT¤   iMessage,
c42954 ¤   ¤   ·ULONG¤ ulFlags)·
39bb36 {
9d01b5 ¤   CHAR szCaption [128];
20084e ¤   CHAR szMessage [500];
84af5a
2f15d7 ¤   LoadString (g_hinst, iCaption, szCaption, sizeof(szCaption));
80a96b ¤   LoadString (g_hinst, iMessage, szMessage, sizeof(szMessage));
60af5a
59897a ¤   ulFlags |= MB_SETFOREGROUND;
39729f ¤   return (MessageBox (hWnd, szMessage, szCaption, ulFlags));
a6efe6 }
3aaf5a
2ad979 BOOL WindowExists (LPSTR lpszClassName, LPSTR lpszWindowTitle)·
1abb36 {
6b8ccc ¤   HWND hWndMe;
32af5a
e05ce6 ···¤hWndMe = FindWindow (lpszClassName, lpszWindowTitle);
5b210a ····if (hWndMe)·
973b37 ····{
4f810a ¤   ¤   if (!IsZoomed (hWndMe))·
0c9e9e ¤   ¤   ¤   ShowWindow (hWndMe, SW_RESTORE);
39b18c ·······¤BringWindowToTop(hWndMe);
11b037 ¤   ¤   SetForegroundWindow(hWndMe);
2f4ee5 ········return TRUE;
35e773 ¤   } ·
160e24 ¤   else
db98aa ¤   ¤   return FALSE;
e5efe6 }
45af5a
ed0af7 BOOL InitPGPsc(HWND hwnd,void **PGPsc,void **PGPtls)
80bb36 {
0b0040 ¤   PGPError err;
0964a2 ¤   PGPContextRef context;
99b767 ¤   PGPtlsContextRef tls;
85444e ¤   DWORD OLERetVal;
0daf5a
--efe2 0008287450740110275 Page 2 of Utils.c
55c126 ¤   err=PGPNewContext( kPGPsdkAPIVersion, &context );
5baf5a
02bdc8 ¤   if( IsPGPError(err) )
70c7a1 ¤   {
b0c68b ¤   ¤   if(err == kPGPError_IncompatibleAPI)
e65b34 ¤   ¤   {
fe1b82 ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_WRONGSDK,
022d15 ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
9e0fe4 ¤   ¤   }
b60e1d ¤   ¤   else
163e38 ¤   ¤   if(err == kPGPError_FeatureNotAvailable)
e25b34 ¤   ¤   {
10f3a6 ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_EVALEXPIRED,
572d15 ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
510fe4 ¤   ¤   }
080e1d ¤   ¤   else
a709b6 ¤   ¤   ¤   PGPclErrorBox(hwnd,err);
d9af5a
f198aa ¤   ¤   return FALSE;
7d9371 ¤   }
95af5a
f7eb93 ¤   if(IsPGPError(PGPclIsExpired(hwnd)))
1098aa ¤   ¤   return FALSE;
67af5a
3df447 ¤   err=PGPNewTLSContext (context, &tls);
6baf5a
cbbdc8 ¤   if( IsPGPError(err) )
4dc7a1 ¤   {
e634de ¤   ¤   PGPclErrorBox(hwnd,err);
9198aa ¤   ¤   return FALSE;
1a9371 ¤   }
faaf5a
8b69ca ¤   err=PGPclInitLibrary(context);
37af5a
e0d4fd ¤   if(err==kPGPError_UserAbort)
6898aa ¤   ¤   return FALSE;
37af5a
36bdc8 ¤   if( IsPGPError(err) )
b9c7a1 ¤   {
8f34de ¤   ¤   PGPclErrorBox(hwnd,err);
d598aa ¤   ¤   return FALSE;
079371 ¤   }
c4af5a
71052b ¤   OLERetVal=OleInitialize (NULL);
d6af5a
9609c6 ¤   switch(OLERetVal)
85c7a1 ¤   {
b8a072 ¤   ¤   case S_OK:
a641a4 ¤   ¤   ¤   // The COM library and additional functionality were·
562e9e ¤   ¤   ¤   // initialized successfully on this apartment.·
aecdcb ¤   ¤   ¤   break;
9eaf5a
f12bf5 ¤   ¤   case S_FALSE:
c95b34 ¤   ¤   {
edf1f0 ¤   ¤   ¤   // The COM library is already initialized on this·
09ea1c ¤   ¤   ¤   // apartment.
abcdcb ¤   ¤   ¤   break;
c10fe4 ¤   ¤   }
ffaf5a
8485a4 ¤   ¤   case OLE_E_WRONGCOMPOBJ:
715b34 ¤   ¤   {
d23b46 ¤   ¤   ¤   MessageBox(hwnd,
7a1539 ¤   ¤   ¤   ¤   "The versions of COMPOBJ.DLL and OLE2.DLL on\n"
f30904 ¤   ¤   ¤   ¤   "your machine are incompatible with each other.",
39cd11 ¤   ¤   ¤   ¤   "OLE Error",MB_OK);
475f1f ¤   ¤   ¤   return FALSE;
470fe4 ¤   ¤   }
e9af5a
929ae3 ¤   ¤   default:
075b34 ¤   ¤   {
fa3b46 ¤   ¤   ¤   MessageBox(hwnd,
82589b ¤   ¤   ¤   ¤   "Error initializing OLE.",
--85e6 000921e378f40110275 Page 3 of Utils.c
19cd11 ¤   ¤   ¤   ¤   "OLE Error",MB_OK);
075f1f ¤   ¤   ¤   return FALSE;
1c0fe4 ¤   ¤   }
009371 ¤   }
52af5a
f33996 ¤   *PGPsc=(void *)context;
f86f42 ¤   *PGPtls=(void *)tls;
1aaf5a
73a4cd ¤   g_uPurgePassphraseCacheMessage =·
67fa17 ¤   ¤   RegisterWindowMessage (PURGEPASSPHRASECACEHMSG);
97af5a
ffc2e7 ¤   return TRUE;
bcefe6 }
0eaf5a
d52650 BOOL UninitPGPsc(HWND hwnd,void *PGPsc,void *PGPtls)
d8bb36 {
7b0040 ¤   PGPError err;
d664a2 ¤   PGPContextRef context;
85b767 ¤   PGPtlsContextRef tls;
64af5a
70625b ¤   context=(PGPContextRef)PGPsc;
e0db07 ¤   tls=(PGPtlsContextRef)PGPtls;
18af5a
ba583a ¤   PGPclCloseLibrary ();
06af5a
b634bd ¤   err=PGPFreeTLSContext(tls);
33af5a
1682b6 ¤   err=PGPFreeContext(context);
68af5a
0c9ef3 ¤   OleUninitialize();
7aaf5a
05c8d0 ¤   if(IsntPGPError(err))
9a836c ¤   ¤   return TRUE;
f3af5a
c5a230 ¤   return FALSE;
14efe6 }
caaf5a
ede608 BOOL CheckForPurge(UINT uMsg,WPARAM wParam)
8dbb36 {
3e5a70 ¤   if (uMsg == g_uPurgePassphraseCacheMessage)
abc7a1 ¤   {
3a6394 ¤   ¤   PGPclPurgeCachedPassphrase (wParam);
ce32bd ¤   ¤   ¤   return TRUE;
259371 ¤   }
74af5a
7fa230 ¤   return FALSE;
32efe6 }
90af5a
acdf32 OUTBUFFLIST *MakeOutBuffItem(OUTBUFFLIST **obl)
b6bb36 {
7d6b73 ¤   OUTBUFFLIST *nobl,*lastobl,*indexobl;
baaf5a
5714e3 ¤   nobl=(OUTBUFFLIST *)malloc(sizeof(OUTBUFFLIST));
597efe ¤   memset(nobl,0x00,sizeof(OUTBUFFLIST));
d1af5a
1c9d0a ¤   lastobl=indexobl=*obl;
cbaf5a
c6bc25 ¤   while(indexobl!=0)
15c7a1 ¤   {
ed84e2 ¤   ¤   lastobl=indexobl;
d66c56 ¤   ¤   indexobl=indexobl->next;
fa9371 ¤   }
abaf5a
e12ba0 ¤   if(lastobl==0)
7e34bf ¤   ¤   *obl=nobl;
bc0e24 ¤   else
ed0c0b ¤   ¤   lastobl->next=nobl;
86af5a
da006a ¤   return nobl;
83efe6 }
2daf5a
924bac BOOL ConcatOutBuffList(void *PGPsc,
--fe71 0006381b3cd40110275 Page 4 of Utils.c
70cefa ¤   ¤   ¤   ¤   ¤   ···OUTBUFFLIST *obl,
7c81a5 ¤   ¤   ¤   ¤   ¤   ···char **pBuff,
069a5d ¤   ¤   ¤   ¤   ¤   ···DWORD *dwBuffSize,
aa8483 ¤   ¤   ¤   ¤   ¤   ···BOOL *FYEO)
08bb36 {
054218 ¤   OUTBUFFLIST *indexobl,*prevobl;
5c2779 ¤   DWORD memindex;
e37694 ¤   PGPMemoryMgrRef¤memmgr;
7164a2 ¤   PGPContextRef context;
0baf5a
33625b ¤   context=(PGPContextRef)PGPsc;
9baf5a
55e9cc ¤   *pBuff=0;
95c955 ¤   *dwBuffSize=0;
5cd468 ¤   *FYEO=FALSE;
99af5a
aa61ab ¤   if(obl==NULL)
e0836c ¤   ¤   return TRUE;
1daf5a
1e44b8 ¤   memmgr = PGPGetContextMemoryMgr (context);
e4af5a
c85e74 ¤   // Find size and whether complete block is FYEO or not
9481ac ¤   indexobl=obl;
97c955 ¤   *dwBuffSize=0;
40d468 ¤   *FYEO=FALSE;
15af5a
f7bc25 ¤   while(indexobl!=0)
fdc7a1 ¤   {
06019b ¤   ¤   if(indexobl->FYEO)
b25b34 ¤   ¤   {
68d845 ¤   ¤   ¤   *FYEO=TRUE;
b00fe4 ¤   ¤   }
d578d9 ¤   ¤   *dwBuffSize=*dwBuffSize+indexobl->dwBuffSize;
ca6c56 ¤   ¤   indexobl=indexobl->next;
7c9371 ¤   }
96af5a
2c6a73 ¤   // Allocate new memory buffer
9fe152 ¤   if(*FYEO)
b1c7a1 ¤   {
aeebd5 ¤   ¤   *pBuff=PGPNewSecureData (memmgr, *dwBuffSize+1, 0);
d09371 ¤   }
3b0e24 ¤   else
45c7a1 ¤   {
7791c8 ¤   ¤   *pBuff=PGPNewData (memmgr, *dwBuffSize+1, 0);
459371 ¤   }
e7af5a
423bd6 ¤   if(*pBuff==NULL)
2bc7a1 ¤   {
6698aa ¤   ¤   return FALSE;
309371 ¤   }
a4af5a
eb6fa0 ¤   // +1 for terminating null
dbac62 ¤   memset(*pBuff,0x00,*dwBuffSize+1);
4aaf5a
5b4a89 ¤   // Concatenate memory blocks and free originals/linked list
3981ac ¤   indexobl=obl;
48ab4c ¤   memindex=0;
fcaf5a
98bc25 ¤   while(indexobl!=0)
9bc7a1 ¤   {
d48971 ¤   ¤   memcpy(&((*pBuff)[memindex]),indexobl->pBuff,indexobl->dwBuffSize);
333c22 ¤   ¤   memset(indexobl->pBuff,0x00,indexobl->dwBuffSize);
b48a96 ¤   ¤   PGPFreeData(indexobl->pBuff);
567cf0 ¤   ¤   memindex=memindex+indexobl->dwBuffSize;
17af5a
6f43f2 ¤   ¤   prevobl=indexobl;
5e6c56 ¤   ¤   indexobl=indexobl->next;
4d2bcb ¤   ¤   free(prevobl);
aa9371 ¤   }
5faf5a
d7c2e7 ¤   return TRUE;
63efe6 }
--2887 0004652f99640110275 Page 5 of Utils.c
e0af5a
e0b59e BOOL OpenRings(HWND hwnd,PGPContextRef context,PGPKeySetRef *pkeyset)
92bb36 {
210040 ¤   PGPError err;
8faf5a
d6ccdd ¤   PGPsdkLoadDefaultPrefs(context);
c2af5a
02298a ¤   err=PGPOpenDefaultKeyRings( context,
c6f6e1 ¤   ¤   OPENKEYRINGFLAGS,pkeyset);
2caf5a
bcee15 ¤   if(IsPGPError(err))
95c7a1 ¤   {
67c73a ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_CANTOPENRINGS,
6ee840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
1798aa ¤   ¤   return FALSE;
b19371 ¤   }
f767c5 ¤
66c2e7 ¤   return TRUE;
73efe6 }
47af5a
e2b5e2 void PGPpath(char *szPath)
dcbb36 {
a84a46 ¤   strcpy(szPath,"");
aeaf5a
1c5d08 ¤   PGPclGetPGPPath (szPath,MAX_PATH);
f7efe6 }
2daf5a
e0d52a char *JustFile(char *filename)
c0bb36 {
cf813a ¤   char *p;
02af5a
5d5ecc ¤   p = strrchr(filename, '\\');
fcaf5a
afe4fd ¤   if(p!=0)
4fe8e6 ¤   ¤   return (p+1);
8c0e24 ¤   else
9b29eb ¤   ¤   return filename;
c4efe6 }
84af5a
a09cea BOOL GetValidityDrawPrefs(void *PGPsc,
37d585 ¤   ¤   ¤   ¤   ¤   ¤   ··BOOL *pbInputBool)
89bb36 {
99559a ¤   PGPPrefRef¤ PrefRefClient=NULL;
3f61e0 ¤   PGPError¤   err;
9c6872 ¤   PGPBoolean ·bDisplayMarginal;
2fed37 ¤   PGPMemoryMgrRef memMgr;
e164a2 ¤   PGPContextRef context;
c3af5a
60625b ¤   context=(PGPContextRef)PGPsc;
77af5a
bc89c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
85af5a
d0aa48 ¤   bDisplayMarginal=FALSE;
c1af5a
9bf9bd ¤   err=PGPclOpenClientPrefs (memMgr,&PrefRefClient);
1767c5 ¤
54c8d0 ¤   if(IsntPGPError(err))
f2c7a1 ¤   {
cab251 ¤   ¤   PGPGetPrefBoolean (PrefRefClient,
ba6627 ¤   ¤   ¤   kPGPPrefDisplayMarginalValidity, &bDisplayMarginal);
9d59b8 ¤   ¤   PGPclCloseClientPrefs (PrefRefClient, FALSE);
68af5a
821d00 ¤   ¤   *pbInputBool=FALSE;
b1af5a
dd2e0c ¤   ¤   if(bDisplayMarginal)
043dd5 ¤   ¤   ¤   *pbInputBool=TRUE;
0faf5a
d8836c ¤   ¤   return TRUE;
619371 ¤   }
1daf5a
29a230 ¤   return FALSE;
46efe6 }
--5073 00083ef9db340110275 Page 6 of Utils.c
e0af5a
d69007 BOOL GetMarginalInvalidPref(void *PGPsc,
c07d5a ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL *pbInputBool)
02bb36 {
20559a ¤   PGPPrefRef¤ PrefRefClient=NULL;
ff61e0 ¤   PGPError¤   err;
6f4694 ¤   PGPBoolean ·bMarginalInvalid;
0ced37 ¤   PGPMemoryMgrRef memMgr;
a764a2 ¤   PGPContextRef context;
b8af5a
a0625b ¤   context=(PGPContextRef)PGPsc;
c4af5a
d289c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
80af5a
813188 ¤   bMarginalInvalid=FALSE;
ddaf5a
4ef9bd ¤   err=PGPclOpenClientPrefs (memMgr,&PrefRefClient);
b667c5 ¤
c9c8d0 ¤   if(IsntPGPError(err))
6cc7a1 ¤   {
bbb251 ¤   ¤   PGPGetPrefBoolean (PrefRefClient,
d51ee6 ¤   ¤   ¤   kPGPPrefMarginalIsInvalid, &bMarginalInvalid);
c659b8 ¤   ¤   PGPclCloseClientPrefs (PrefRefClient, FALSE);
22af5a
1a1d00 ¤   ¤   *pbInputBool=FALSE;
ceaf5a
d600ea ¤   ¤   if(bMarginalInvalid)
5d3dd5 ¤   ¤   ¤   *pbInputBool=TRUE;
131b52 ¤   ¤
7f836c ¤   ¤   return TRUE;
799371 ¤   }
e8af5a
b5a230 ¤   return FALSE;
29efe6 }
76af5a
528479 UINT FileListFromFile(FILELIST **filelist,char *filename,BOOL *UserCancel)
39bb36 {
41f345 ¤   FILELIST *Current;
9baf5a
3560be ¤   if(UserCancel!=NULL)
30c7a1 ¤   {
ecf50a ¤   ¤   if(*UserCancel)
995b34 ¤   ¤   {
745f1f ¤   ¤   ¤   return FALSE;
a00fe4 ¤   ¤   }
b49371 ¤   }
1faf5a
6ee39e ¤   Current=(FILELIST *)malloc(sizeof(FILELIST));
606c2e ····memset(Current,0x00,sizeof(FILELIST));
e2af5a
bf7a0b ¤   strcpy(Current->name,filename);
ed74e6 ¤   Current->next=*filelist;
afc82e ¤   *filelist=Current;
08af5a
93c2e7 ¤   return TRUE;
46efe6 }
7aaf5a
3d4ef3 UINT FileListFromDirectory(FILELIST **filelist,char *directory,BOOL *UserCancel)
c2bb36 {
897d10 ¤   HANDLE hFindFile;
9cc8b6 ¤   WIN32_FIND_DATA FindFileData;
ec1843 ¤   BOOL RetVal=FALSE;
738cec ¤   BOOL KeepGoing;
677eb0 ¤   char search[MAX_PATH];
2b58b2 ¤   char filename[MAX_PATH];
27af5a
bda11e ¤   if(directory[strlen(directory)]!='\\')
ab7378 ¤   ¤   strcat(directory,"\\");
0aaf5a
0add37 ¤   strcpy(search,directory);
b8af5a
832026 ¤   strcat(search,"*.*");
--d675 000a920114640110275 Page 7 of Utils.c
e0af5a
6cefbe ¤   hFindFile=FindFirstFile(search,&FindFileData);
52af5a
eea02e ¤   if(hFindFile!=INVALID_HANDLE_VALUE)
d9c7a1 ¤   {
75576a ¤   ¤   RetVal=TRUE;
2daf5a
920c97 ¤   ¤   while(RetVal==TRUE)
875b34 ¤   ¤   {
413c15 ¤   ¤   ¤   // Our quick fix callback to allow user to back out
7c99da ¤   ¤   ¤   // of operation
61efb5 ¤   ¤   ¤   if(UserCancel!=NULL)
faf776 ¤   ¤   ¤   {
deae31 ¤   ¤   ¤   ¤   if(*UserCancel)
1e72c3 ¤   ¤   ¤   ¤   {
ec6571 ¤   ¤   ¤   ¤   ¤   FindClose(hFindFile);
cbe143 ¤   ¤   ¤   ¤   ¤   return FALSE;
592613 ¤   ¤   ¤   ¤   }
0da3a6 ¤   ¤   ¤   }
b3af5a
a8b154 ¤   ¤   ¤   strcpy(filename,directory);
0e24e0 ¤   ¤   ¤   strcat(filename,FindFileData.cFileName);
09af5a
6963b7 ¤   ¤   ¤   if((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
ebe62e ¤   ¤   ¤   ¤   !=FILE_ATTRIBUTE_DIRECTORY)
c7f776 ¤   ¤   ¤   {
bc25df ¤   ¤   ¤   ¤   FileListFromFile(filelist,filename,UserCancel);
dfa3a6 ¤   ¤   ¤   }
35bb8c ¤   ¤   ¤   else
9ff776 ¤   ¤   ¤   {
51ff8a ¤   ¤   ¤   ¤   if((strcmp(FindFileData.cFileName,"."))&&
fa649b ¤   ¤   ¤   ¤   ¤   (strcmp(FindFileData.cFileName,"..")))
8e72c3 ¤   ¤   ¤   ¤   {
19877e ¤   ¤   ¤   ¤   ¤   KeepGoing=FileListFromFile(filelist,filename,UserCancel);
9d1863 ¤   ¤   ¤   ¤   ¤   if(!KeepGoing)
a74859 ¤   ¤   ¤   ¤   ¤   {
565cb4 ¤   ¤   ¤   ¤   ¤   ¤   FindClose(hFindFile);
5a0e30 ¤   ¤   ¤   ¤   ¤   ¤   return FALSE;
601c89 ¤   ¤   ¤   ¤   ¤   }
beaf5a
1f7dd4 ¤   ¤   ¤   ¤   ¤   (*filelist)->IsDirectory=TRUE;
09c6fb ¤   ¤   ¤   ¤   ¤   KeepGoing=FileListFromDirectory(filelist,filename,UserCance¶
a26ca5 l);
23af5a
d11863 ¤   ¤   ¤   ¤   ¤   if(!KeepGoing)
0a4859 ¤   ¤   ¤   ¤   ¤   {
6a5cb4 ¤   ¤   ¤   ¤   ¤   ¤   FindClose(hFindFile);
1d0e30 ¤   ¤   ¤   ¤   ¤   ¤   return FALSE;
951c89 ¤   ¤   ¤   ¤   ¤   }
9f2613 ¤   ¤   ¤   ¤   }
62a3a6 ¤   ¤   ¤   }
74d0e3 ¤   ¤   ¤   RetVal=FindNextFile(hFindFile,&FindFileData);·
f60fe4 ¤   ¤   }
a0af5a
f481e4 ¤   ¤   FindClose(hFindFile);
ee9371 ¤   }
f0af5a
94c2e7 ¤   return TRUE;
d1a79b }·
3eaf5a
e18896 BOOL AddToFileList(FILELIST **filelist,char *filename,BOOL *UserCancel)
61bb36 {
ff17b7 ¤   DWORD dwFileAttributes;
4b25f2 ¤   UINT RetVal;
78af5a
6b6cf1 ¤   dwFileAttributes=GetFileAttributes(filename);
67af5a
3355af ¤   if(dwFileAttributes==0xFFFFFFFF)
8c836c ¤   ¤   return TRUE;
e0af5a
06b4d1 ¤   if((dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
a94aec ¤   ¤   ==FILE_ATTRIBUTE_DIRECTORY)
--9a54 00035d4dc8e40110275 Page 8 of Utils.c
f7c7a1 ¤   {
1cefbb ¤   ¤   RetVal=FileListFromFile(filelist,filename,UserCancel);
df5f5d ¤   ¤   if(!RetVal)
ee5f1f ¤   ¤   ¤   return FALSE;
edaf5a
c63ab2 ¤   ¤   (*filelist)->IsDirectory=TRUE;
5a1f5c ¤   ¤   RetVal=FileListFromDirectory(filelist,filename,UserCancel);
929371 ¤   }
410e24 ¤   else
1dc7a1 ¤   {
c8efbb ¤   ¤   RetVal=FileListFromFile(filelist,filename,UserCancel);
1a9371 ¤   }
43af5a
e142d7 ¤   return RetVal;
55efe6 }
6baf5a
bb21ef BOOL FreeFileList(FILELIST *FileList)
d7bb36 {
acd782 ¤   FILELIST *FreeAtLast;
47af5a
c56191 ¤   while(FileList!=0)
a0c7a1 ¤   {
50429e ¤   ¤   FreeAtLast=FileList;
c466dd ¤   ¤   FileList=FileList->next;
c96872 ¤   ¤   memset(FreeAtLast,0x00,sizeof(FILELIST));
94975d ¤   ¤   free(FreeAtLast);
7b9371 ¤   }
aaaf5a
5fc2e7 ¤   return TRUE;
8befe6 }
ddaf5a
3e9197 FILELIST *HDropToFileList(HDROP hDrop)
12bb36 {
faf25b ¤   char szFile[MAX_PATH+1];
c1c49b ¤   int NumFiles,i,ReturnCode;
764dee ¤   FILELIST *ListHead;
b3af5a
e3a40d ¤   NumFiles=DragQueryFile(hDrop,0xFFFFFFFF,NULL,0);
82a1f1 ¤   ListHead=0;
939dea ¤   ReturnCode=TRUE;
92af5a
f9cf19 ¤   if(NumFiles==0)
8dbbde ¤   ¤   return 0;
54af5a
af58ec ¤   for(i=0;i<NumFiles && ReturnCode == TRUE;i++)
87c7a1 ¤   {
9577b1 ¤   ¤   DragQueryFile(hDrop,i,szFile,MAX_PATH);
a4f286 ¤   ¤   AddToFileList(&ListHead,szFile,NULL);
559371 ¤   }
b5af5a
aeb85c ¤   return ListHead;
eeefe6 }
12af5a
15ded1 FILELIST *CmdLineToFileList(char *szCmdLine)
4cbb36 {
dae82a ¤   char *szNext,*szNow;
394dee ¤   FILELIST *ListHead;
a7af5a
d3d4ea ¤   szNext=szCmdLine;
93a1f1 ¤   ListHead=0;
ffaf5a
5c9fb9 ¤   while(szNext!=NULL)
f5c7a1 ¤   {
ccc6c3 ¤   ¤   szNow=szNext;
dd87c7 ¤   ¤   ¤
cc16d1 ¤   ¤   szNext=strstr(szNext," ");
551b52 ¤   ¤
d28106 ¤   ¤   if(szNext!=NULL)
ec5b34 ¤   ¤   {
4b8eee ¤   ¤   ¤   szNext=strstr(szNext,":\\");
bbaf5a
35b55b ¤   ¤   ¤   if(szNext!=NULL)
--9745 00035bf665440110275 Page 9 of Utils.c
99f776 ¤   ¤   ¤   {
04fb50 ¤   ¤   ¤   ¤   szNext=szNext-2;
cde25e ¤   ¤   ¤   ¤   if(szNext>szCmdLine)
fc72c3 ¤   ¤   ¤   ¤   {
648bd3 ¤   ¤   ¤   ¤   ¤   *szNext=0;
66496c ¤   ¤   ¤   ¤   ¤   szNext++;
092613 ¤   ¤   ¤   ¤   }
93fa07 ¤   ¤   ¤   ¤   else
4472c3 ¤   ¤   ¤   ¤   {
1b8c01 ¤   ¤   ¤   ¤   ¤   szNext=NULL;
552613 ¤   ¤   ¤   ¤   }
67a3a6 ¤   ¤   ¤   }
f90fe4 ¤   ¤   }
3b4928 ¤   ¤   AddToFileList(&ListHead,szNow,NULL);
3e9371 ¤   }
8eaf5a
e7b85c ¤   return ListHead;
44efe6 }
cbaf5a
70b35f UINT PGPscQueryCacheSecsRemaining (void)
7abb36 {
91b62f ¤   UINT SignCacheSecs;
31c175 ¤   UINT DecCacheSecs;
f9af5a
2e06cf ¤   SignCacheSecs=PGPclQuerySigningCacheSecsRemaining();
89b36e ¤   DecCacheSecs=PGPclQueryDecryptionCacheSecsRemaining ();
96af5a
d03894 ¤   if(SignCacheSecs>DecCacheSecs)
cf373b ¤   ¤   return SignCacheSecs;
93af5a
4ac1fd ¤   return DecCacheSecs;
a8efe6 }
d6af5a
0696d6 BOOL PGPscPreferences(HWND hwnd,void *PGPsc,void *PGPtls)
0fbb36 {
ff64a2 ¤   PGPContextRef context;
0ab767 ¤   PGPtlsContextRef tls;
13af5a
3c625b ¤   context=(PGPContextRef)PGPsc;
8adb07 ¤   tls=(PGPtlsContextRef)PGPtls;
a8af5a
0bb7b0 ¤   PGPclPreferences(context,hwnd, 0, NULL);
5daf5a
9ec2e7 ¤   return TRUE;
e8efe6 }
38af5a
a5a6bd BOOL PGPscAbout (HWND hwnd,void *PGPsc)
dbbb36 {
d364a2 ¤   PGPContextRef context;
39af5a
11625b ¤   context=(PGPContextRef)PGPsc;
d8af5a
4caeb3 ¤   PGPclHelpAbout (context,hwnd,NULL,NULL,NULL);
1aaf5a
fcc2e7 ¤   return TRUE;
e7efe6 }
91af5a
3b9a40 BOOL DoLaunchKeys(HWND hwnd)
314157 { ·
3cec6a ¤   char PGPkeys[MAX_PATH];
76c5c7 ¤   int error;
046672 ¤   char StrRes[500];
b567c5 ¤
ba9e7f ¤   PGPpath(PGPkeys);
30af5a
bb3c6c // Since Windows can't handle tray launched from CD
fd5153 ¤   SetCurrentDirectory(PGPkeys);
f4af5a
9cb594 ¤   strcat(PGPkeys,"PGPkeys.exe /s");
81dfdc ¤   error=WinExec(PGPkeys, SW_SHOW);
a6d83c ·
35cafb ¤   if(error<=31)
--4982 0009ad64e9240110275 Page 10 of Utils.c
c69108 ¤   {·
f89649 ¤   ¤   LoadString (g_hinst, IDS_CANTOPENPGPKEYS, StrRes, sizeof(StrRes));
8faf5a
f35737 ¤   ¤   MessageBox(hwnd,PGPkeys,
156ddb ¤   ¤   ¤   StrRes,
4c2c85 ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
4caf5a
6998aa ¤   ¤   return FALSE;
f49371 ¤   }
42af5a
5bc2e7 ¤   return TRUE;
5cefe6 }
aeaf5a
9f10c0 BOOL DoLaunchTools(HWND hwnd)
704157 { ·
6745fc ¤   char PGPtools[MAX_PATH];
46c5c7 ¤   int error;
1c6672 ¤   char StrRes[500];
48af5a
913530 ¤   PGPpath(PGPtools);
f1af5a
263c6c // Since Windows can't handle tray launched from CD
a7de91 ¤   SetCurrentDirectory(PGPtools);
00af5a
fdf4e4 ¤   strcat(PGPtools,"PGPtools.exe");
0551c8 ¤   error=WinExec(PGPtools, SW_SHOW);
15d83c ·
d3cafb ¤   if(error<=31)
739108 ¤   {·
d1e3ab ¤   ¤   LoadString (g_hinst, IDS_CANTOPENPGPTOOLS, StrRes, sizeof(StrRes));
d4af5a
bd2f45 ¤   ¤   MessageBox(hwnd,PGPtools,
766ddb ¤   ¤   ¤   StrRes,
ef2c85 ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
7aaf5a
5498aa ¤   ¤   return FALSE;
c29371 ¤   }
caaf5a
fcc2e7 ¤   return TRUE;
05efe6 }
63af5a
936403 BOOL DoLaunchDisk(HWND hwnd)
574157 { ·
e345fc ¤   char PGPtools[MAX_PATH];
95c5c7 ¤   int error;
fc6672 ¤   char StrRes[500];
0eaf5a
203530 ¤   PGPpath(PGPtools);
eeaf5a
5e3c6c // Since Windows can't handle tray launched from CD
93de91 ¤   SetCurrentDirectory(PGPtools);
ccaf5a
9615f3 ¤   strcat(PGPtools,"PGPdisk.exe");
af51c8 ¤   error=WinExec(PGPtools, SW_SHOW);
b6d83c ·
96cafb ¤   if(error<=31)
189108 ¤   {·
a88252 ¤   ¤   LoadString (g_hinst, IDS_CANTOPENPGPDISK, StrRes, sizeof(StrRes));
a7af5a
de2f45 ¤   ¤   MessageBox(hwnd,PGPtools,
e56ddb ¤   ¤   ¤   StrRes,
2b2c85 ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
0daf5a
8098aa ¤   ¤   return FALSE;
0f9371 ¤   }
edaf5a
76c2e7 ¤   return TRUE;
95efe6 }
a0af5a
d8eacc BOOL CheckClipboard()
b5bb36 {
9a274e ¤   char *pInput;
--2571 000b0bcff3240110275 Page 11 of Utils.c
fcb1a1 ¤   DWORD dwInputSize;
286a53 ¤   UINT ClipboardFormat;
7d8e46 ¤   BOOL RetVal;
eaaf5a
dbc7d2 ¤   RetVal=FALSE;
82af5a
ee6510 ¤   pInput=RetrieveClipboardData
82b510 ¤   ¤   ¤   (NULL,&ClipboardFormat,&dwInputSize);
52af5a
2f3aab ¤   if((ClipboardFormat == CF_TEXT)&&(pInput!=0))
ddc7a1 ¤   {
1a0897 ¤   ¤   if(*pInput!=0)
705b34 ¤   ¤   {
e4e6bb ¤   ¤   ¤   RetVal=TRUE;
d70fe4 ¤   ¤   }
bc9371 ¤   }
94af5a
ef55d3 ¤   if(pInput!=0)
bbc7a1 ¤   {
d50559 ¤   ¤   memset(pInput,0x00,dwInputSize);
b5742f ¤   ¤   free(pInput);
489371 ¤   }
57af5a
3442d7 ¤   return RetVal;
09efe6 }
0faf5a
f40ed3 void ControlA(void)
0fbb36 {
3170a8 ¤   g_KeyArray[0]=VK_CONTROL|SK_KEYDOWN;
ab9dc9 ¤   g_KeyArray[1]='A'|SK_KEYDOWN;
e67ead ¤   g_KeyArray[2]='A';
242967 ¤   g_KeyArray[3]=VK_CONTROL;
f3af5a
f5ab0a ¤   SendKeys( g_KeyArray, 4 );
80efe6 }
f5af5a
fe05bc void ControlC(void)
20bb36 {
2370a8 ¤   g_KeyArray[0]=VK_CONTROL|SK_KEYDOWN;
a40d9d ¤   g_KeyArray[1]='C'|SK_KEYDOWN;
9747db ¤   g_KeyArray[2]='C';
a22967 ¤   g_KeyArray[3]=VK_CONTROL;
b2af5a
b6ab0a ¤   SendKeys( g_KeyArray, 4 );
edefe6 }
68af5a
69c9a5 void ControlV(void)
82bb36 {
4f70a8 ¤   g_KeyArray[0]=VK_CONTROL|SK_KEYDOWN;
59cfea ¤   g_KeyArray[1]='V'|SK_KEYDOWN;
76ea2d ¤   g_KeyArray[2]='V';
6f2967 ¤   g_KeyArray[3]=VK_CONTROL;
3baf5a
f4ab0a ¤   SendKeys( g_KeyArray, 4 );
24efe6 }
38af5a
686879 void EMSetSel(HWND hwndEdit)
b9bb36 {
339c09 ¤   SendMessage(hwndEdit,EM_SETSEL,0,-1);
4cefe6 }
10af5a
4a1011 void WMCopy(HWND hwndEdit)
23bb36 {
f5f304 ¤   SendMessage(hwndEdit,WM_COPY,0,0);
4befe6 }
32af5a
748825 BOOL DoCopy(HWND hwnd,void *PGPsc,BOOL bUseCurrent,HWND *hwndFocus)
83bb36 {
dd97f1 ¤   BOOL ClipOK;
7b71b8 ¤   HWND hwndEdit;
2342a8 ¤   BOOL RetVal=TRUE;
b063f4 ¤   char WinClass[256];
--9256 0005977f72440110275 Page 12 of Utils.c
cd64a2 ¤   PGPContextRef context;
856bab ¤   DWORD OtherAppThreadID;
e9a1fb ¤   DWORD OtherAppProcessID;
254d25 ¤   HWND hwndOldFocus;
d27f1d ¤   DWORD TrayThreadID;
e5af5a
7f625b ¤   context=(PGPContextRef)PGPsc;
71af5a
d105cb ¤   *hwndFocus=NULL;
b5af5a
c4a297 ¤   if(bUseCurrent)
80c7a1 ¤   {
516dc8 ¤   ¤   TrayThreadID=GetCurrentThreadId();
24a6ba ¤   ¤   hwndEdit=ReadCurrentFocus();
6c9cbe ¤   ¤   *hwndFocus=hwndEdit;
74af5a
86d397 ¤   ¤   GetClassName(hwndEdit,WinClass,255);
94af5a
45cfc4 ¤   ¤   ClipboardWipe(NULL,context);
d8af5a
6d408e ¤   ¤   // We can key off WinClass if something else
e78833 ¤   ¤   // needs to be done·
e8af5a
36e9c8 ¤   ¤   OtherAppThreadID = GetWindowThreadProcessId( hwndEdit,·
89ee8b ¤   ¤   ¤   &OtherAppProcessID);
5caf5a
66e037 ¤   ¤   AttachThreadInput( TrayThreadID, OtherAppThreadID, TRUE );
12af5a
55feac ¤   ¤   hwndOldFocus=SetFocus(hwndEdit);
a3af5a
1e631a ¤   ¤   WMCopy(hwndEdit);
79af5a
b34d9c ¤   ¤   ClipOK=CheckClipboard();
a746ea ¤   ¤   if(!ClipOK)
d75b34 ¤   ¤   {
2a2fbd ¤   ¤   ¤   // We can key off WinClass if something else
c53365 ¤   ¤   ¤   // needs to be done·
315903 ¤   ¤   ¤   EMSetSel(hwndEdit);
02ea4e ¤   ¤   ¤   WMCopy(hwndEdit);
68af5a
8c70f4 ¤   ¤   ¤   ClipOK=CheckClipboard();
e83c1e ¤   ¤   ¤   if(!ClipOK)
a3f776 ¤   ¤   ¤   {
ca1333 ¤   ¤   ¤   ¤   ControlC();
6b87c7 ¤   ¤   ¤
d77519 ¤   ¤   ¤   ¤   ClipOK=CheckClipboard();
15ca7b ¤   ¤   ¤   ¤   if(!ClipOK)
5672c3 ¤   ¤   ¤   ¤   {
d5a8e5 ¤   ¤   ¤   ¤   ¤   ControlA();
4dbe6d ¤   ¤   ¤   ¤   ¤   ControlC();
dbaf5a
f473a1 ¤   ¤   ¤   ¤   ¤   ClipOK=CheckClipboard();
9f6725 ¤   ¤   ¤   ¤   ¤   if(!ClipOK)
5b4859 ¤   ¤   ¤   ¤   ¤   {
126bd2 ¤   ¤   ¤   ¤   ¤   ¤   RetVal=FALSE;
091c89 ¤   ¤   ¤   ¤   ¤   }
442613 ¤   ¤   ¤   ¤   }
00a3a6 ¤   ¤   ¤   }
dc0fe4 ¤   ¤   }
cbaf5a
951029 ¤   ¤   AttachThreadInput( TrayThreadID, OtherAppThreadID, FALSE );
43dd5e ¤   ¤   SetFocus(hwndOldFocus);
799371 ¤   }
3caf5a
8ec82e ¤   if(!RetVal)
6fc7a1 ¤   {
3208d7 #if _DEBUG
326d55 ¤   ¤   MessageBox(hwnd,WinClass,"Couldn't get text. _DEBUG VERSION ONLY_ info",
812c85 ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
fbdb21 #else
743a7c ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_CANTAUTOCOPY,
5963bc ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
--6e1b 0008f8e3c5c40110275 Page 13 of Utils.c
a07454 #endif
879371 ¤   }
cc42d7 ¤   return RetVal;
b8efe6 }
74af5a
a5e61a void DoPaste(BOOL bUseCurrent,HWND hwndFocus)
c7bb36 {
aa71b8 ¤   HWND hwndEdit;
4963f4 ¤   char WinClass[256];
926bab ¤   DWORD OtherAppThreadID;
8fa1fb ¤   DWORD OtherAppProcessID;
937f1d ¤   DWORD TrayThreadID;
9baf5a
61a297 ¤   if(bUseCurrent)
a2c7a1 ¤   {
f16dc8 ¤   ¤   TrayThreadID=GetCurrentThreadId();
047d61 ¤   ¤   hwndEdit=hwndFocus;·
8dd397 ¤   ¤   GetClassName(hwndEdit,WinClass,255);
18af5a
59e9c8 ¤   ¤   OtherAppThreadID = GetWindowThreadProcessId( hwndEdit,·
45ee8b ¤   ¤   ¤   &OtherAppProcessID);
daaf5a
c4e037 ¤   ¤   AttachThreadInput( TrayThreadID, OtherAppThreadID, TRUE );
02af5a
4c408e ¤   ¤   // We can key off WinClass if something else
7a8833 ¤   ¤   // needs to be done·
5daf5a
18fb1f ¤   ¤   SetFocus(hwndEdit);
a8af5a
e90db6 ¤   ¤   ControlV();
a4af5a
5e1029 ¤   ¤   AttachThreadInput( TrayThreadID, OtherAppThreadID, FALSE );
f99371 ¤   }
2befe6 }
17af5a
33ea5f void DoFocus(BOOL bUseCurrent,HWND hwndFocus)
55bb36 {
b571b8 ¤   HWND hwndEdit;
1963f4 ¤   char WinClass[256];
486bab ¤   DWORD OtherAppThreadID;
90a1fb ¤   DWORD OtherAppProcessID;
5a7f1d ¤   DWORD TrayThreadID;
c5af5a
f0a297 ¤   if(bUseCurrent)
b6c7a1 ¤   {
7a6dc8 ¤   ¤   TrayThreadID=GetCurrentThreadId();
be7d61 ¤   ¤   hwndEdit=hwndFocus;·
c4d397 ¤   ¤   GetClassName(hwndEdit,WinClass,255);
42af5a
dae9c8 ¤   ¤   OtherAppThreadID = GetWindowThreadProcessId( hwndEdit,·
7cee8b ¤   ¤   ¤   &OtherAppProcessID);
e7af5a
05e037 ¤   ¤   AttachThreadInput( TrayThreadID, OtherAppThreadID, TRUE );
d5af5a
54408e ¤   ¤   // We can key off WinClass if something else
878833 ¤   ¤   // needs to be done·
1aaf5a
13fb1f ¤   ¤   SetFocus(hwndEdit);
9caf5a
ae1029 ¤   ¤   AttachThreadInput( TrayThreadID, OtherAppThreadID, FALSE );
f89371 ¤   }
79efe6 }
e3af5a
f6d6c2 void StartUpdateTimer(HWND hwnd, UINT *pnLaunchKeysTimer)
e0bb36 {
02979d ¤   if (pnLaunchKeysTimer != NULL)
c56f3a ¤   ¤   *pnLaunchKeysTimer = 0;
40af5a
750e78 ¤   if (hwnd == NULL)
5499bf ¤   ¤   return;
03af5a
8fcd68 ¤   UpdateTimerProc(hwnd, WM_TIMER, LAUNCHKEYS_TIMER, 0);
--799e 000cc3a0c8f40110275 Page 14 of Utils.c
e0af5a
c7f9a3 ¤   *pnLaunchKeysTimer = SetTimer(hwnd, LAUNCHKEYS_TIMER,·
8cf0d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MILLISECONDS_PER_DAY,
8c5bd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (TIMERPROC) UpdateTimerProc);
92830f ¤   return;
37efe6 }
90af5a
9aaf5a
540f6e VOID CALLBACK UpdateTimerProc(HWND hwnd,·
7a6983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
f4465b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT idEvent,·
97a5e4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··DWORD dwTime)
2dbb36 {
9472aa ¤   PGPMemoryMgrRef memoryMgr;
37fb35 ¤   PGPBoolean¤ ¤   bUpdateAllKeys;
35779c ¤   PGPBoolean¤ ¤   bUpdateTrustedIntroducers;
cf3bb5 ¤   PGPError¤   ¤   err = kPGPError_NoErr;
8daf5a
c38379 ¤   if (idEvent != LAUNCHKEYS_TIMER)
6b99bf ¤   ¤   return;
7daf5a
3bec65 ¤   err = PGPNewMemoryMgr(0, &memoryMgr);
5482f0 ¤   if (IsPGPError(err))
9ec7a1 ¤   {
ab730d ¤   ¤   PGPclErrorBox(hwnd, err);
5799bf ¤   ¤   return;
509371 ¤   }
99af5a
77abbc ¤   err = PGPclCheckAutoUpdate(memoryMgr, FALSE,·
5450df ¤   ¤   ¤   &bUpdateAllKeys, &bUpdateTrustedIntroducers);
c082f0 ¤   if (IsPGPError(err))
a5c7a1 ¤   {
1b730d ¤   ¤   PGPclErrorBox(hwnd, err);
2799bf ¤   ¤   return;
af9371 ¤   }
11af5a
1513e7 ¤   if (bUpdateAllKeys || bUpdateTrustedIntroducers)
4f97e6 ¤   ¤   DoLaunchKeys(hwnd);
00af5a
392049 ¤   PGPFreeMemoryMgr(memoryMgr);
da830f ¤   return;
fdefe6 }
b4d83c ·
ff72eb BOOL FileHasThisExtension(char *filename,char *extension)
cabb36 {
02813a ¤   char *p;
2eaf5a
e80919 ¤   if(filename!=NULL)
15c7a1 ¤   {
1311be ¤   ¤   if((p = strrchr(filename, '\\')))
d360e2 ¤   ¤   ¤   filename=p; // we just want the filename not path
4baf5a
931598 ¤   ¤   if((p = strrchr(filename, '.')))
9b5b34 ¤   ¤   {
5a64c8 ¤   ¤   ¤   p++;
3caf5a
4de4c5 ¤   ¤   ¤   if(!strcmpi(p,extension))
2406e0 ¤   ¤   ¤   ¤   return TRUE;
030fe4 ¤   ¤   }
3b9371 ¤   }
3caf5a
eba230 ¤   return FALSE;
ffefe6 }
ff67c5 ¤
a96fb1 LRESULT CALLBACK PlaybackHook( int nCode, WPARAM wParam,
e81cdc ·················LPARAM lParam )
7abb36 {
12c486 ···LPEVENTMSG lpEM;
7aaf5a
21b303 ···switch(nCode) {
486b6c ······case HC_SKIP:
cc4f46 ¤   ¤   ·g_KeyIndex++;
--a898 000e18d66e540110275 Page 15 of Utils.c
97f7b2 ·········if( g_KeyIndex == g_NumKeys ) { ·// no more keys?
7733db ············// remove hook
a3e6bf ············UnhookWindowsHookEx(g_hJournalHook);
2ce20d ············g_hJournalHook = NULL;
a2de82 ·········}
d01e69 ·········return 0;
00af5a
99a69e ······case HC_GETNEXT:
76cfe1 ·········lpEM = (LPEVENTMSG)lParam;
ef74c4 ·········if( lpJournalKeys[g_KeyIndex] & SK_KEYDOWN )
501f59 ············lpEM->message = lpJournalKeys[g_KeyIndex] & SK_SYSKEY
c5f401 ········································? WM_SYSKEYDOWN : WM_KEYDOWN;
1c9b6a ·········else
a6ea17 ············lpEM->message = lpJournalKeys[g_KeyIndex] & SK_SYSKEY·
9e17a3 ········································? WM_SYSKEYUP : WM_KEYUP;
d82e6f ·········lpEM->paramL = LOBYTE(lpJournalKeys[g_KeyIndex])
93e990 ···············| (MapVirtualKey(LOBYTE(lpJournalKeys[g_KeyIndex]),0)<<8);
49028a ·········lpEM->paramH = 1;
018841 ·········lpEM->time = GetCurrentTime();
551e69 ·········return 0;
f9af5a
821082 ······default:
c994f1 ·········return CallNextHookEx(g_hJournalHook,nCode,wParam,lParam);
f8b144 ···}
8eefe6 }
a9af5a
c5f943 #define KeyDown( uKey ) ( GetAsyncKeyState(uKey) & 0x8000 )
c4af5a
761e2b BOOL WINAPI SendKeys( UINT *lpKeys, UINT nKeys )
73bb36 {
2b3924 ···lpJournalKeys = lpKeys;
49b59a ···g_KeyIndex = ··0;
550ed0 ···g_NumKeys = ·nKeys;
043360 ···if( g_hJournalHook )
08c39d ······return FALSE;
2fa024 ···while( KeyDown(VK_MENU) || KeyDown(VK_SHIFT)
2997a0 ································|| KeyDown(VK_CONTROL) ) {
843308 ······MSG msg;
f2fd8a ······if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ) {
f737a2 ·········if( msg.message == WM_QUIT ) {
58b020 ············PostMessage(msg.hwnd,msg.message,msg.wParam,msg.lParam);
a9a683 ············return FALSE;
26de82 ·········}
45d374 ·········TranslateMessage(&msg);
0a4546 ·········DispatchMessage(&msg);
cb42cc ······}
6bb144 ···}
e8b7ca ···g_hJournalHook = SetWindowsHookEx(WH_JOURNALPLAYBACK,
5859ff ······(HOOKPROC)PlaybackHook,g_hinst,0);
1a58fd ···if(!g_hJournalHook) return FALSE;
302317 ···// while hook is installed, pump messages
39d87d ···while(g_hJournalHook) {
133308 ······MSG msg;
44fd8a ······if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ) {
a737a2 ·········if( msg.message == WM_QUIT ) {
878d71 ············if( g_hJournalHook )
d766eb ···············UnhookWindowsHookEx(g_hJournalHook);
afb020 ············PostMessage(msg.hwnd,msg.message,msg.wParam,msg.lParam);
ada683 ············return FALSE;
9fde82 ·········}
64d374 ·········TranslateMessage(&msg);
0a4546 ·········DispatchMessage(&msg);
fc42cc ······}
80b144 ···}
0fae17 ···return TRUE;
9befe6 }
c31b52 ¤   ¤
5c7e4d /*__Editor_settings____
4baf5a
134126 ¤   Local Variables:
fb7b17 ¤   tab-width: 4
e10e6c ¤   End:
--df33 0018e2c01f040110275 Page 16 of Utils.c
e65f8c ¤   vi: ts=4 sw=4
949e9b ¤   vim: si
8ed062 _____________________*/
--e485 0002a19f17840110276 Page 1 of WFfat.c
385ed8 #include "precomp.h"
e6af5a
542c37 void WritePattern(void* buf, DWORD* pattern, long size)
6dbb36 {
956ddc ¤   char* buffer = (char*)buf;
9363c5 ¤   int patternSize = sizeof(DWORD) * 256;
d4af5a
657b8d ¤   if(size <= patternSize)
97c7a1 ¤   {
3735a1 ¤   ¤   memcpy(buffer, pattern, size);
b99371 ¤   }
b20e24 ¤   else
edc7a1 ¤   {
23fb13 ¤   ¤   int passes = size / patternSize;
b83652 ¤   ¤   int remainder = size % patternSize;
7e2a1e ¤   ¤   int i;
e6af5a
d43fba ¤   ¤   for(i = 0; i < passes; i++)
bc5b34 ¤   ¤   {
5b9d6f ¤   ¤   ¤   memcpy(buffer + (i * patternSize), pattern, patternSize);
dd0fe4 ¤   ¤   }
f1af5a
efe64b ¤   ¤   memcpy(buffer + (i * patternSize), pattern, remainder);
c29371 ¤   }
5aefe6 }
1faf5a
3e801e DWORD ClusterToSector(VOLINFO *vi,DWORD Cluster)
47bb36 {
a226fb ¤   return ((Cluster-0x2)*vi->sectors_per_clus)+vi->dwStartSector;
9cefe6 }
7eaf5a
e1007f int ReadAbsoluteSectors( HANDLE hDev,int volume, DWORD start_sector,·
a0501f ·························WORD num_sectors, LPBYTE pBuf )·
37bb36 {
2c6249 ¤   DIOC_REGISTERS reg;
b1bd0f ¤   DISKIO di;
e130ad ¤   BOOL bResult;
81afe7 ¤   DWORD cb;
5eaf5a
c33950 ¤   reg.reg_EAX ·····= volume-1; ·// zero-based volume number
4b7f1c ¤   reg.reg_EBX ·····= (DWORD)&di;
79be10 ¤   reg.reg_ECX ·····= 0xffff; ·// use DISKIO structure
bea9d9 ¤   reg.reg_Flags ···= 1; ······// preset the carry flag
3d5927 ¤   di.diStartSector = start_sector;
405f48 ¤   di.diSectors ····= num_sectors;
9ff19a ¤   di.diBuffer ·····= (DWORD)pBuf;
eb8381 ¤   bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_INT25,
61b956 ··············&reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 );·
e0af5a
31c81b ¤   if ( !bResult || (reg.reg_Flags & 1) ) return -1;
7c3e6b ¤   return 0;
26efe6 }
48af5a
b9ba5a BOOL WriteAbsoluteSectors(HANDLE hDev,
bbf133 ··························int ···bDrive,
89c562 ··························DWORD ·dwStartSector,
1152d3 ··························WORD ··wSectors,
a33fb3 ··························LPBYTE lpSectBuff)
3abb36 {
b3eefa ¤   BOOL ··········fResult;
f765a0 ¤   DWORD ·········cb;
6e64a5 ¤   DIOC_REGISTERS reg = {0};
053ecf ¤   DISKIO ········di = {0};
99af5a
000895 //¤ if(bDrive!=1)
1c8de5 //¤ ¤   return FALSE;
33af5a
ba7a05 ¤   di.diStartSector = dwStartSector;
4ba65f ¤   di.diSectors ·····= wSectors;
450bf3 ¤   di.diBuffer ·····= (DWORD)lpSectBuff;
c3af5a
2ad22e ¤   reg.reg_EAX = bDrive - 1; ···// Int 26h drive numbers are 0-based.
--20ac 000649959f840110276 Page 2 of WFfat.c
ad9fdb ¤   reg.reg_EBX = (DWORD)&di;
fc354d ¤   reg.reg_ECX = 0xFFFF; ·······// use DISKIO struct
f7af5a
e35d87 ¤   fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_INT26,
89d6f0 ································&reg, sizeof(reg),
7e3c5a ································&reg, sizeof(reg), &cb, 0);
4eaf5a
3fba5f ······// Determine if the DeviceIoControl call and the write succeeded.
53d5bd ¤   fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);
5baf5a
448a84 ¤   return fResult;
9fefe6 }
b5af5a
33edd7 int ReadAbsoluteSectors32( HANDLE hDev,int volume, DWORD start_sector,·
e93a89 ···························WORD num_sectors, LPBYTE pBuf )·
a0bb36 {
6a6249 ¤   DIOC_REGISTERS reg;
6cbd0f ¤   DISKIO di;
9b30ad ¤   BOOL bResult;
69afe7 ¤   DWORD cb;
f6af5a
698eb8 ¤   reg.reg_EAX ·····= 0x7305; ·// Ext_ABSDiskReadWrite
667f1c ¤   reg.reg_EBX ·····= (DWORD)&di;
25be10 ¤   reg.reg_ECX ·····= 0xffff; ·// use DISKIO structure
0965b3 ¤   reg.reg_EDX ·····= volume; ·// one-based volume number
f6cc33 ¤   reg.reg_ESI ·····= 0; ······// READ operation
80f804 ¤   reg.reg_Flags ···= 0; ······// preset the carry flag
b25927 ¤   di.diStartSector = start_sector;
6e5f48 ¤   di.diSectors ····= num_sectors;
d7f19a ¤   di.diBuffer ·····= (DWORD)pBuf;
6eaf5a
1f0350 ¤   bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_DRIVEINFO,
f5b956 ··············&reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 );·
adaf5a
8cd677 ¤   if ( /*!bResult ||*/ (reg.reg_Flags & 1) ) return -1;
a33e6b ¤   return 0;
16efe6 }
38af5a
200948 BOOL WriteAbsoluteSectors32(HANDLE hDev,
d0cbf9 ····························int ···bDrive,
c783f0 ····························DWORD ·dwStartSector,
b9fbd0 ····························WORD ··wSectors,
3f2d10 ····························LPBYTE lpSectBuff)
45bb36 {
d1eefa ¤   BOOL ··········fResult;
8465a0 ¤   DWORD ·········cb;
1864a5 ¤   DIOC_REGISTERS reg = {0};
0e6b8a ¤   DISKIO ········di;
17af5a
e20895 //¤ if(bDrive!=1)
eb8de5 //¤ ¤   return FALSE;
d7af5a
5c7a05 ¤   di.diStartSector = dwStartSector;
65a65f ¤   di.diSectors ·····= wSectors;
57493a ¤   di.diBuffer ······= (DWORD)lpSectBuff;
e2af5a
a5dc7a ¤   reg.reg_EAX = 0x7305; ··// Ext_ABSDiskReadWrite
9a9fdb ¤   reg.reg_EBX = (DWORD)&di;
d4d7b4 ¤   reg.reg_ECX = -1;
d25b47 ¤   reg.reg_EDX = bDrive; ··// Int 21h, fn 7305h drive numbers are 1-based
7eaf5a
384238 ¤   reg.reg_ESI = 0x6001; ··// Normal file data (See function
6653c9 ·····························// documentation for other values)
2daf5a
56af5a
b97fb0 ¤   fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_DRIVEINFO,
22eca6 ·······························&reg, sizeof(reg),
ab4ae9 ·······························&reg, sizeof(reg), &cb, 0);
f8af5a
cc864b ¤   // Determine if the DeviceIoControl call and the write succeeded.
f2d5bd ¤   fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);
64af5a
--8fa1 00066b538bb40110276 Page 3 of WFfat.c
318a84 ¤   return fResult;
0eefe6 }
35af5a
17d5a1 BOOL UserPressedCancel(VOLINFO *vi)
2fbb36 {
200cf8 ¤   MSG msg;
22af5a
a0213b ¤   while(PeekMessage(&msg,vi->hwnd,0,0,PM_REMOVE))
65c7a1 ¤   {
ddf43d ¤   ¤   if(!IsDialogMessage(vi->hwnd,&msg))
495b34 ¤   ¤   {
ddbda2 ¤   ¤   ¤   TranslateMessage(&msg);
1cfdfb ¤   ¤   ¤   DispatchMessage(&msg);
f80fe4 ¤   ¤   }
159371 ¤   }
a3af5a
abe1cd ¤   if(bGlobalCancel)
17836c ¤   ¤   return TRUE;
39af5a
a8a230 ¤   return FALSE;
b3efe6 }
12af5a
8dac85 DWORD ReadSectors(VOLINFO *vi,DWORD start_sector,·
03f18b ·················WORD num_sectors,LPBYTE pBuf)·
17bb36 {
b5e87f ¤   DWORD RetVal;
6baf5a
af7655 ¤   RetVal=WFE_NOERROR;
cbaf5a
21954c ¤   if(vi->dwFS==FS_FAT32)·
6fc7a1 ¤   {
db6e92 ¤   ¤   if(ReadAbsoluteSectors32(vi->hVWin32,vi->vol1,
6312fd ¤   ¤   ¤   ¤   start_sector,num_sectors,pBuf)!=0)
e0b40a ¤   ¤   ¤   RetVal=WFE_COULDNOTREAD;
8d9371 ¤   }
f20e24 ¤   else
3dc7a1 ¤   {
eca728 ¤   ¤   if(ReadAbsoluteSectors(vi->hVWin32,vi->vol1,
9f8a79 ¤   ¤   ¤   ¤   start_sector,num_sectors,pBuf)<0)
d0b40a ¤   ¤   ¤   RetVal=WFE_COULDNOTREAD;
a79371 ¤   }
dbaf5a
abc804 ¤   if(UserPressedCancel(vi))
399bb8 ¤   ¤   RetVal=WFE_USERCANCEL;
ecaf5a
0c42d7 ¤   return RetVal;
03efe6 }
3faf5a
fd03ed int GetLockFlagState( HANDLE hDev,int volume,BOOL bFlatFAT )·
f8bb36 {
1f6249 ¤   DIOC_REGISTERS reg;
68dd75 ¤   BOOL bResult,fResult;
08afe7 ¤   DWORD cb;
60af5a
e26cd6 ¤   reg.reg_EAX = 0x440d; // generic IOCTL
ed27ae ¤   reg.reg_ECX = bFlatFAT ? 0x486c : 0x086c; // lock logical volume·
a2e826 ¤   reg.reg_EBX = volume; // 1 based
e62801 ¤   reg.reg_Flags = 1; // preset the carry flag
41af5a
38cd8e ¤   bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_IOCTL,
a6f0ec ¤   ¤   &reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 );·
e4af5a
684f2f ¤   fResult = bResult && !(reg.reg_Flags & CARRY_FLAG);
a3af5a
a4764c ¤   if(!fResult)
37043c ¤   ¤   return -1;
c6af5a
68c6a3 ¤   return (reg.reg_EAX & 0xffff);
fcefe6 }
b1af5a
479644 int LockLogicalVolume( HANDLE hDev,int volume, int lock_level,·
66959b ·······················int permissions, BOOL bFlatFAT )·
--04bc 0006241f50040110276 Page 4 of WFfat.c
2cbb36 {
866249 ¤   DIOC_REGISTERS reg;
c430ad ¤   BOOL bResult;
fcafe7 ¤   DWORD cb;
84af5a
7c6cd6 ¤   reg.reg_EAX = 0x440d; // generic IOCTL
ca3b33 ¤   reg.reg_ECX = bFlatFAT ? 0x484a : 0x084a; // lock logical volume·
ae15c1 ¤   reg.reg_EBX = volume | (lock_level << 8);
746977 ¤   reg.reg_EDX = permissions;
a02801 ¤   reg.reg_Flags = 1; // preset the carry flag
6baf5a
cecd8e ¤   bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_IOCTL,
7bb956 ··············&reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 );·
ebaf5a
29511e ¤   if(bResult)
9fbbde ¤   ¤   return 0;
27af5a
e5c6a3 ¤   return (reg.reg_EAX & 0xffff);
42af5a
2893b3 //¤ if ( !bResult || (reg.reg_Flags & 1) )·
c6537b //¤ ¤   return (reg.reg_EAX & 0xffff);
85af5a
563e6b ¤   return 0;
d7efe6 }
70af5a
2d42ca int UnlockLogicalVolume( HANDLE hDev,int volume, BOOL bFlatFAT )·
b6bb36 {
ce6249 ¤   DIOC_REGISTERS reg;
2430ad ¤   BOOL bResult;
72afe7 ¤   DWORD cb;
21af5a
c423d4 ¤   reg.reg_EAX = 0x440d;
ecd3b1 ¤   reg.reg_ECX = bFlatFAT ? 0x486a : 0x086a; // lock logical volume·
7888a8 ¤   reg.reg_EBX = volume;
2b2801 ¤   reg.reg_Flags = 1; // preset the carry flag
45af5a
6acd8e ¤   bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_IOCTL,
d0b956 ··············&reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 );·
17af5a
bdc81b ¤   if ( !bResult || (reg.reg_Flags & 1) ) return -1;
0a3e6b ¤   return 0;
83efe6 }
8aaf5a
32a70f DWORD WriteSectors(VOLINFO *vi,DWORD start_sector,·
71f18b ·················WORD num_sectors,LPBYTE pBuf)·
0abb36 {
53e87f ¤   DWORD RetVal;
0cf795 ¤   BOOL bFat32;
16869e ····
d17655 ¤   RetVal=WFE_NOERROR;
3adcbb ¤   bFat32=(vi->dwFS==FS_FAT32);
5eaf5a
22cbb2 ¤   if(vi->bCountClusters)
d2c7a1 ¤   {
00a1c7 ¤   ¤   char StrRes[500];
37af5a
52441a ¤   ¤   LoadString (g_hinst, IDS_SCANNINGDISK, StrRes, sizeof(StrRes));
aeaf5a
42a49b ¤   ¤   if(vi->dwClusterCount==0)
b771be ¤   ¤   ¤   StatusMessage(StrRes, FALSE);
15af5a
dd97ec ¤   ¤   vi->dwClusterCount++;
abff0c ¤   ¤   if(UserPressedCancel(vi))
0417c7 ¤   ¤   ¤   RetVal=WFE_USERCANCEL;
79793e ¤   ¤   return RetVal;
779371 ¤   }
98af5a
76d800 ¤   // Get Level2 Exclusive Volume Lock
df64db ¤   if(LockLogicalVolume(vi->hVWin32,vi->vol1,·
43bae8 ¤   ¤   LEVEL2_LOCK,·
b98095 ¤   ¤   0,
629cd5 ¤   ¤   bFat32)!=0)
--260f 00097a19b8340110276 Page 5 of WFfat.c
f7c7a1 ¤   {
b5cd69 ¤   ¤   RetVal=WFE_COULDNOTLOCK;
fb9371 ¤   }
1e0e24 ¤   else
28c7a1 ¤   {
a20b22 ¤   ¤   // Get Level3 Exclusive Volume Lock
66f29a ¤   ¤   if(LockLogicalVolume(vi->hVWin32,vi->vol1,·
9630a0 ¤   ¤   ¤   LEVEL3_LOCK,·
ace12f ¤   ¤   ¤   0,
5ae621 ¤   ¤   ¤   bFat32)!=0)
f45b34 ¤   ¤   {
31f001 ¤   ¤   ¤   RetVal=WFE_COULDNOTLOCK;
060fe4 ¤   ¤   }
510e1d ¤   ¤   else
335b34 ¤   ¤   {
92bc10 ¤   ¤   ¤   // Make sure nobody has been writing to the disk.
6c1449 ¤   ¤   ¤   if(GetLockFlagState(vi->hVWin32,vi->vol1,bFat32)!=0)
d7f776 ¤   ¤   ¤   {
ad187c ¤   ¤   ¤   ¤   RetVal=WFE_DISKMODIFIED;
89a3a6 ¤   ¤   ¤   }
42bb8c ¤   ¤   ¤   else
12f776 ¤   ¤   ¤   {
0efcce ¤   ¤   ¤   ¤   if(bFat32)
a072c3 ¤   ¤   ¤   ¤   {
81a092 ¤   ¤   ¤   ¤   ¤   if(!WriteAbsoluteSectors32(vi->hVWin32,
dd095b ¤   ¤   ¤   ¤   ¤   ¤   vi->vol1,start_sector,num_sectors,pBuf))
894859 ¤   ¤   ¤   ¤   ¤   {
10425b ¤   ¤   ¤   ¤   ¤   ¤   RetVal=WFE_COULDNOTWRITE;
8c1c89 ¤   ¤   ¤   ¤   ¤   }
212613 ¤   ¤   ¤   ¤   }
0dfa07 ¤   ¤   ¤   ¤   else
0b72c3 ¤   ¤   ¤   ¤   {
3ca6e8 ¤   ¤   ¤   ¤   ¤   if(!WriteAbsoluteSectors(vi->hVWin32,
22095b ¤   ¤   ¤   ¤   ¤   ¤   vi->vol1,start_sector,num_sectors,pBuf))
814859 ¤   ¤   ¤   ¤   ¤   {
a3425b ¤   ¤   ¤   ¤   ¤   ¤   RetVal=WFE_COULDNOTWRITE;
c01c89 ¤   ¤   ¤   ¤   ¤   }
882613 ¤   ¤   ¤   ¤   }
9aa3a6 ¤   ¤   ¤   }
8920f1 ¤   ¤   ¤   // Free Level 3 lock
f9157e ¤   ¤   ¤   UnlockLogicalVolume(
d458e7 ¤   ¤   ¤   ¤   vi->hVWin32,·
4565d5 ¤   ¤   ¤   ¤   vi->vol1,·
e38703 ¤   ¤   ¤   ¤   bFat32);
f40fe4 ¤   ¤   }
760472 ¤   ¤   // Free Level 2 lock
d7ae28 ¤   ¤   UnlockLogicalVolume(
01d1b3 ¤   ¤   ¤   vi->hVWin32,·
2b8734 ¤   ¤   ¤   vi->vol1,·
b036d2 ¤   ¤   ¤   bFat32);
f39371 ¤   }
a2af5a
7d85b5 ¤   if(RetVal==WFE_NOERROR)
d2c7a1 ¤   {
59a1c7 ¤   ¤   char StrRes[500];
fbc79a ¤   ¤   char statusmsg[500];
acaf5a
b3b23e ¤   ¤   vi->dwClustersWritten=vi->dwClustersWritten+1;
2a1b52 ¤   ¤
0a7380 ¤   ¤   if(vi->dwClustersWritten%10==0)
eb5b34 ¤   ¤   {
2ac4e7 ¤   ¤   ¤   float pos;
28af5a
fb3ff2 ¤   ¤   ¤   LoadString (g_hinst, IDS_PERCENTWRITTEN, StrRes, sizeof(StrRes));
b5af5a
c30908 ¤   ¤   ¤   sprintf(statusmsg,
05172f ¤   ¤   ¤   ¤   StrRes,
71851b ¤   ¤   ¤   ¤   vi->dwClustersWritten,vi->dwClusterCount);
aaaf5a
5c2678 ¤   ¤   ¤   StatusMessage(statusmsg, FALSE);
35af5a
975f3e ¤   ¤   ¤   pos = 10 +·
--5b36 00053bbe16040110276 Page 6 of WFfat.c
fa65b7 ¤   ¤   ¤   ¤   ( (float)vi->dwClustersWritten /·
97086a ¤   ¤   ¤   ¤   ··(float)vi->dwClusterCount )
df8d68 ¤   ¤   ¤   ¤   * 90;
ebaf5a
c89856 ¤   ¤   ¤   WipeProgress((int)pos);·
bb0fe4 ¤   ¤   }
6b9371 ¤   }
42af5a
21c804 ¤   if(UserPressedCancel(vi))
809bb8 ¤   ¤   RetVal=WFE_USERCANCEL;
9eaf5a
2342d7 ¤   return RetVal;
feefe6 }
bfaf5a
58e6f0 DWORD Fat32Item(unsigned char *FATbuffer,DWORD FlatIndex)
c3bb36 {
dbb5ac ¤   DWORD dwFat32index;
23c773 ¤   DWORD dwFat32value;
d14bd5 ¤   DWORD *pFat;
2baf5a
ac8eb9 ¤   dwFat32index=FlatIndex*32/8;
58dcb9 ¤   pFat = (DWORD *)(&(FATbuffer[dwFat32index]));
59af5a
7d46fd ¤   // upper 4 bits are masked off
7a63ea ¤   dwFat32value=0x0fffffff & (*pFat);
a0af5a
5ec085 ¤   return dwFat32value;
c0efe6 }
e7af5a
d66a38 DWORD Fat16Item(unsigned char *FATbuffer,DWORD FlatIndex)
68bb36 {
ec3888 ¤   DWORD dwFat16index;
3c4a57 ¤   DWORD dwFat16value;
319111 ¤   WORD *pFat;
f8af5a
232a71 ¤   dwFat16index=FlatIndex*16/8;
3d0071 ¤   pFat = (WORD *)(&(FATbuffer[dwFat16index]));
deaf5a
ace8d0 ¤   dwFat16value=0xffff & (DWORD)(*pFat);
0caf5a
7c4da1 ¤   return dwFat16value;
b9efe6 }
2caf5a
a757c1 DWORD Fat12Item(unsigned char *FATbuffer,DWORD FlatIndex)
96bb36 {
022e56 ¤   DWORD dwFat12index;
c55c89 ¤   DWORD dwFat12value;
4d30a2 ¤   DWORD nib;
278891 ¤   unsigned char* pFat;
8daf5a
0e08bb ¤   // Depending if we're odd or even, we may
295742 ¤   // get need 8 bits then 4 bits, or 4 bits
4db923 ¤   // then 8 bits.
303067 ¤   dwFat12index=FlatIndex*12/8;
282ae3 ¤   pFat = &(FATbuffer[dwFat12index]);
fcaf5a
cd91e2 ¤   if(FlatIndex%2==0) // Even
984467 ¤   { ··// Get the 8 bits
29db5f ¤   ¤   dwFat12value = 0xff & (DWORD)(*pFat);
ce17f0 ¤   ¤   pFat++;
2e3ad8 ¤   ¤   // Get the 4 bits
7c07fb ¤   ¤   nib = 0x0f & (DWORD)(*pFat);
d24aed ¤   ¤   // Shift the 4 bit portion as MSB.
f16ae5 ¤   ¤   nib <<= 8;
b8b9d2 ¤   ¤   dwFat12value |= nib;
569371 ¤   }
ce6876 ¤   else // Odd
7dc796 ¤   { ··// Get the 4 bits.
994100 ¤   ¤   nib = 0xf0 & (DWORD)(*pFat);
4117f0 ¤   ¤   pFat++;
cc8b42 ¤   ¤   // Get the 8 bits
53db5f ¤   ¤   dwFat12value = 0xff & (DWORD)(*pFat);
--d162 000dfe204be40110276 Page 7 of WFfat.c
9d6f4b ¤   ¤   // Shift the 8 bit portion MSB.
63d2e3 ¤   ¤   dwFat12value <<= 4;
e78305 ¤   ¤   // Shift the 4 bit portion LSB.
9ff0ab ¤   ¤   nib >>= 4;
76b9d2 ¤   ¤   dwFat12value |= nib;
bd9371 ¤   }
baaf5a
d45b7f ¤   return dwFat12value;
3aefe6 }
05af5a
cb4121 DWORD FatItem(VOLINFO *vi,DWORD index)
82bb36 {
8119ee ¤   switch(vi->dwFS)
7dc7a1 ¤   {
916c3c ¤   ¤   case FS_FAT12:
39b269 ¤   ¤   ¤   return(Fat12Item(vi->pFatBuf,index));
e8af5a
8c0f5d ¤   ¤   case FS_FAT16:
9af358 ¤   ¤   ¤   return(Fat16Item(vi->pFatBuf,index));
2daf5a
3c554a ¤   ¤   case FS_FAT32:
e72644 ¤   ¤   ¤   return(Fat32Item(vi->pFatBuf,index));
479371 ¤   }
e0efe6 }
11af5a
d9f847 BOOL IsntEnd(VOLINFO *vi,DWORD dwIndexCluster)
86bb36 {
e919ee ¤   switch(vi->dwFS)
c7c7a1 ¤   {
276c3c ¤   ¤   case FS_FAT12:
cb6ae4 ¤   ¤   ¤   if(dwIndexCluster<0xff0)
2906e0 ¤   ¤   ¤   ¤   return TRUE;
90cdcb ¤   ¤   ¤   break;
89af5a
460f5d ¤   ¤   case FS_FAT16:
ec8046 ¤   ¤   ¤   if(dwIndexCluster<0xfff0)
a706e0 ¤   ¤   ¤   ¤   return TRUE;
50cdcb ¤   ¤   ¤   break;
8daf5a
4c554a ¤   ¤   case FS_FAT32:
6af642 ¤   ¤   ¤   if(dwIndexCluster<0x0ffffff0)
bd06e0 ¤   ¤   ¤   ¤   return TRUE;
36cdcb ¤   ¤   ¤   break;
3d9371 ¤   }
96a230 ¤   return FALSE;
7eefe6 }
60af5a
66ef7b BOOL IsClusterError(VOLINFO *vi,DWORD dwIndexCluster)
17bb36 {
fd19ee ¤   switch(vi->dwFS)
54c7a1 ¤   {
2c6c3c ¤   ¤   case FS_FAT12:
2a999b ¤   ¤   ¤   if(dwIndexCluster==0xff7)
8706e0 ¤   ¤   ¤   ¤   return TRUE;
8acdcb ¤   ¤   ¤   break;
5aaf5a
380f5d ¤   ¤   case FS_FAT16:
3ad0e1 ¤   ¤   ¤   if(dwIndexCluster==0xfff7)
1f06e0 ¤   ¤   ¤   ¤   return TRUE;
99cdcb ¤   ¤   ¤   break;
9daf5a
c0554a ¤   ¤   case FS_FAT32:
8fcba0 ¤   ¤   ¤   if(dwIndexCluster==0x0ffffff7)
d406e0 ¤   ¤   ¤   ¤   return TRUE;
c4cdcb ¤   ¤   ¤   break;
039371 ¤   }
57a230 ¤   return FALSE;
cbefe6 }
dcaf5a
fcb6f5 BOOL PushDirStack(DIRSTACK **ds,
e31436 ¤   ¤   ¤   ¤   ··DWORD dwStartCluster)
dfbb36 {
--96e0 0009e89156640110276 Page 8 of WFfat.c
21ddaf ¤   DIRSTACK *newds;
f4af5a
4278b4 ¤   newds=(DIRSTACK *)malloc(sizeof(DIRSTACK));
0e71f3 ¤   if(newds)
02c7a1 ¤   {
5876f5 ¤   ¤   memset(newds,0x00,sizeof(DIRSTACK));
a04c46 ¤   ¤   newds->dwStartCluster=dwStartCluster;
9452f7 ¤   ¤   newds->next=*ds;
3db98c ¤   ¤   *ds=newds;
82836c ¤   ¤   return TRUE;
1d9371 ¤   }
cda230 ¤   return FALSE;
dbefe6 }
e7af5a
5a9973 BOOL PopDirStack(DIRSTACK **ds,
b227ad ¤   ¤   ¤   ¤   ·DWORD *dwStartCluster)
babb36 {
cf2d79 ¤   DIRSTACK *FreeAtLast;
efaf5a
571a4a ¤   if(*ds==0)
8f98aa ¤   ¤   return FALSE;
61af5a
08aa10 ¤   FreeAtLast=*ds;
7aaf5a
1b5e46 ¤   *dwStartCluster=(*ds)->dwStartCluster;
73282f ¤   *ds=(*ds)->next;
ffaf5a
ac50e8 ¤   free(FreeAtLast);
b5af5a
fdc2e7 ¤   return TRUE;
6befe6 }
a5af5a
b3250d DWORD DoFileSlack(VOLINFO *vi,
9979fa ¤   ¤   ¤   ¤   ·DWORD dwCluster,
68a78a ¤   ¤   ¤   ¤   ·DWORD dwLength)
57bb36 {
c9b893 ¤   DWORD dwLastCluster;
6c19f2 ¤   DWORD RetVal,err;
5caf5a
707655 ¤   RetVal=WFE_NOERROR;
1aaf5a
d15794 ¤   // Starting cluster is invalid? Something wrong
f2d748 ¤   if(!IsntEnd(vi,dwCluster))
8a54eb ¤   ¤   return WFE_CLUSTERERROR;
39af5a
3498b7 ¤   dwLastCluster=dwCluster;
86e42c ¤   dwCluster=FatItem(vi,dwCluster);
efaf5a
03d31d ¤   // Find the last cluster and the remainder length
f623ee ¤   while(IsntEnd(vi,dwCluster))
18c7a1 ¤   {
1e23e1 ¤   ¤   dwLastCluster=dwCluster;
92323e ¤   ¤   dwLength-=vi->dwClusterSize;
4fe1c1 ¤   ¤   dwCluster=FatItem(vi,dwCluster);
419371 ¤   }
16af5a
6e87d2 ¤   // Cluster with an error is in the chain
dd1841 ¤   if(IsClusterError(vi,dwCluster))
9b54eb ¤   ¤   return WFE_CLUSTERERROR;
05af5a
74e857 ¤   // File length and cluster chain don't agree
93b7bd ¤   // Since we're unsigned, less than zero is accounted for
964d9a ¤   if(dwLength>vi->dwClusterSize)
3354eb ¤   ¤   return WFE_CLUSTERERROR;
beaf5a
81a057 ¤   memset(vi->pClusterBuf,0x00,vi->dwClusterSize);
ceaf5a
3dcbb2 ¤   if(vi->bCountClusters)
79c7a1 ¤   {
a5ddc4 ¤   ¤   // Since we're just counting, no need to read in
637839 ¤   ¤   // the last sector.... it won't be written anyway.
9e947f ¤   ¤   // Speeds things up greatly.
--874f 00012783ebe40110276 Page 9 of WFfat.c
ee0c85 ¤   ¤   err=WFE_NOERROR;
b99371 ¤   }
b10e24 ¤   else
68c7a1 ¤   {
655d5e ¤   ¤   // Read in last cluster of file
09bee5 ¤   ¤   err=ReadSectors(vi,
ee6f38 ¤   ¤   ¤   ClusterToSector(vi,dwLastCluster),·
40a6cc ¤   ¤   ¤   vi->sectors_per_clus,
8ea427 ¤   ¤   ¤   vi->pClusterBuf);
cd9371 ¤   }
75af5a
cc78d0 ¤   if(err!=WFE_NOERROR)
30c7a1 ¤   {
e15229 ¤   ¤   RetVal=err;
499371 ¤   }
fc0e24 ¤   else
18c7a1 ¤   {
1d2245 ¤   ¤   // wipe off the slack
4c85d5 ¤   ¤   WritePattern(¤  &((vi->pClusterBuf)[dwLength]),
73af2e ¤   ¤   ¤   ¤   ¤   ¤   vi->pattern_buffer,
21d329 ¤   ¤   ¤   ¤   ¤   ¤   vi->dwClusterSize-dwLength);
2faf5a
1e58ce ¤   ¤   //memset(&((vi->pClusterBuf)[dwLength]),0x00,
294bb7 ¤   ¤   //¤ vi->dwClusterSize-dwLength);
9daf5a
04c096 ¤   ¤   // Write out last cluster of file
739b36 ¤   ¤   err=WriteSectors(vi,
3d6f38 ¤   ¤   ¤   ClusterToSector(vi,dwLastCluster),·
59a6cc ¤   ¤   ¤   vi->sectors_per_clus,
f5a427 ¤   ¤   ¤   vi->pClusterBuf);
3caf5a
ca4c8d ¤   ¤   if(err!=WFE_NOERROR)
a728dd ¤   ¤   ¤   RetVal=err;
659371 ¤   }
91af5a
db42d7 ¤   return RetVal;
8defe6 }
1baf5a
cbb4b0 DWORD DoDirAndSlack(VOLINFO *vi,
596bb0 ¤   ¤   ¤   ¤   ···char *pBuf,int bufsize)·
64bb36 {
d14188 ¤   unsigned char *pDir = pBuf;
d37c26 ¤   unsigned char *pEnd = pDir+bufsize;
119dec ¤   DWORD dwStartCluster;
53e9a4 ¤   DWORD dwTotalLength,err,RetVal;
40f3bc ¤   PDIRENTRY pd;
4caf5a
2b7655 ¤   RetVal=WFE_NOERROR;
09af5a
bb5f26 ¤   while((*pDir)&&(RetVal==WFE_NOERROR))·
85c7a1 ¤   {
2d5637 ¤   ¤   // Skip over and erase deleted directory entries
af164f ¤   ¤   if (*pDir == 0xe5)
115b34 ¤   ¤   {
5519e2 //¤ ¤   ¤   WritePattern(&(pDir[1]),vi->pattern_buffer,sizeof(DIRENTRY)-1);
1291ca //¤ ¤   ¤   Maybe this is a problem... yah.. long filenames are mislinked.¤ ¶
f287c7 ¤   ¤   ¤
d9157c ¤   ¤   ¤   memset(&(pDir[1]),0x00,sizeof(DIRENTRY)-1);
8310d7 ¤   ¤   ¤   pDir += sizeof( DIRENTRY );
fc0fe4 ¤   ¤   }
9d61e0 ¤   ¤   else if (*(pDir+0x0b) == 0xf && *(pDir+0x0c) == 0 )·
d45b34 ¤   ¤   {
e68c80 ¤   ¤   ¤   // Type 0 "long" directory entry
9a4fdc ¤   ¤   ¤   // We don't really care about these. leave em be.
f310d7 ¤   ¤   ¤   pDir += sizeof( DIRENTRY );
130fe4 ¤   ¤   }
b68675 ¤   ¤   // Other Type "long" directory entry
b7053d ¤   ····else if (*(pDir+0x0b) == 0xf && *(pDir+0x0c) != 0 )·
d15b34 ¤   ¤   {
1fd4e8 ¤   ¤   ¤   // Other Type "long" directory entry
96d22b ¤   ¤   ¤   // We don't care about these either.
1210d7 ¤   ¤   ¤   pDir += sizeof( DIRENTRY );
--8f65 000e44dfda740110276 Page 10 of WFfat.c
b50fe4 ¤   ¤   }
105b76 ¤   ¤   // "Short" directory entry
d7ee26 ¤   ¤   else·
835b34 ¤   ¤   {
741a85 ¤   ¤   ¤   // "Short" directory entry
1b7d6e ¤   ¤   ¤   // Every file has one of these. It has our info.
68808b ¤   ¤   ¤   pd = (PDIRENTRY)pDir;
aaaf5a
4c12bf ¤   ¤   ¤   dwTotalLength=pd->deFileSize;
6eaf5a
31afec ····¤   ¤   if (vi->dwFS!=FS_FAT32)
42f776 ¤   ¤   ¤   {
807155 ¤   ¤   ¤   ¤   dwStartCluster=((DWORD)(pd->deStartCluster))&0xfffff;
1ba3a6 ¤   ¤   ¤   }
fabb8c ¤   ¤   ¤   else
0ff776 ¤   ¤   ¤   {
3a3692 ¤   ¤   ¤   ¤   dwStartCluster=((DWORD)(pd->deEAhandle))&0xffff;
f3aeef ¤   ¤   ¤   ¤   dwStartCluster<<=16;
5539a1 ¤   ¤   ¤   ¤   dwStartCluster|=((DWORD)(pd->deStartCluster))&0xffff;
a5a3a6 ¤   ¤   ¤   }
a7af5a
0103be ¤   ¤   ¤   if((!strncmp(". ······",pd->deName,8))||
105ad6 ¤   ¤   ¤   ···(!strncmp(".. ·····",pd->deName,8)))
82f776 ¤   ¤   ¤   {
a651bd ¤   ¤   ¤   ¤   // same and parent directory
dea3a6 ¤   ¤   ¤   }
514f29 ¤   ¤   ¤   // Check d attrib to see if directory
3fd013 ¤   ¤   ¤   else if(pd->deAttributes & 0x10)
aaf776 ¤   ¤   ¤   {
42c4ea ¤   ¤   ¤   ¤   // Store dir on stack for later processing...
686471 ¤   ¤   ¤   ¤   PushDirStack(&(vi->ds),dwStartCluster);
8ba3a6 ¤   ¤   ¤   }
114304 ¤   ¤   ¤   else if(dwStartCluster>=2) // 0 and 1 are weird stuff
32f776 ¤   ¤   ¤   {
8603cb ¤   ¤   ¤   ¤   char eightthree[12];
58af5a
229a99 ¤   ¤   ¤   ¤   memset(eightthree,0x00,12);
c6b565 ¤   ¤   ¤   ¤   memcpy(eightthree,pd->deName,11);
19af5a
9935e4 ¤   ¤   ¤   ¤   // Wipe slack space for this file...
7b50ba //¤ ¤   ¤   ¤   vErrorOut(fg_yellow,"%s %8x %d\n",
6bdfc6 //¤ ¤   ¤   ¤   ¤   eightthree,dwStartCluster,dwTotalLength);
db400f ¤   ¤   ¤   ¤   err=DoFileSlack(vi,dwStartCluster,dwTotalLength);
0faf5a
d7cab3 ¤   ¤   ¤   ¤   if(err!=WFE_NOERROR)
7c73e6 ¤   ¤   ¤   ¤   ¤   RetVal=err;
94a3a6 ¤   ¤   ¤   }
a8af5a
3f10d7 ¤   ¤   ¤   pDir += sizeof( DIRENTRY );
210fe4 ¤   ¤   }
f2af5a
bebd35 ¤   ¤   if(pDir>=pEnd) ··// Just in case it's completely full
79fbc0 ¤   ¤   ¤   break; ······// and there is no terminating zero
f19371 ¤   }
1eaf5a
7be093 ¤   // We must keep trailing zero to show end of directory,
328615 ¤   // unless of course cluster is completely full
9d203b ¤   pDir++;
c0af5a
c44570 ¤   // Clear off slack at end of directory chain unless full
9c48a5 ¤   if(pDir<pEnd)
97c7a1 ¤   {
eb2e2c //¤ ¤   Patterns seem to be messing up directory structure
e9ae0d //¤ ¤   WritePattern(pDir,vi->pattern_buffer,pEnd-pDir);
461715 ¤   ¤   memset(pDir,0x00,pEnd-pDir);
369371 ¤   }
80af5a
7e42d7 ¤   return RetVal;
0eefe6 }
b5af5a
5bb6c3 DWORD DoOldFatRootDirectory(VOLINFO *vi)
e4bb36 {
--0ff0 00024d1d30440110276 Page 11 of WFfat.c
3d01a0 ¤   DWORD bufsize,err,RetVal;
81487c ¤   unsigned char *pReadBuf;
50af5a
177655 ¤   RetVal=WFE_NOERROR;
2baf5a
f4be0b ¤   bufsize = vi->FAT_DirSectorCount * vi->sector_size;
88b8ae ¤   pReadBuf = (BYTE *)malloc( bufsize );
088155 ¤   if(!pReadBuf)
ebc7a1 ¤   {
4fd6a7 ¤   ¤   RetVal=WFE_OUTOFMEMORY;
b89371 ¤   }
d10e24 ¤   else
4dc7a1 ¤   {
6d1599 //¤ ¤   This is just clearing the buffer
81354d //¤ ¤   WritePattern(pReadBuf,vi->pattern_buffer, bufsize);
33aa72 ¤   ¤   memset( pReadBuf, 0x00, bufsize );
55af5a
5b8e11 ¤   ¤   err=ReadSectors(vi,vi->FAT_DirSector,·
751dc1 ¤   ¤   ¤   vi->FAT_DirSectorCount,pReadBuf);
284c8d ¤   ¤   if(err!=WFE_NOERROR)
de5b34 ¤   ¤   {
fe28dd ¤   ¤   ¤   RetVal=err;
4f0fe4 ¤   ¤   }
b20e1d ¤   ¤   else
015b34 ¤   ¤   {
9ab729 ¤   ¤   ¤   err=DoDirAndSlack(vi,pReadBuf,bufsize);
b8f7db ¤   ¤   ¤   if(err!=WFE_NOERROR)
a7f776 ¤   ¤   ¤   {
7adeb8 ¤   ¤   ¤   ¤   RetVal=err;
5fa3a6 ¤   ¤   ¤   }
31bb8c ¤   ¤   ¤   else
dbf776 ¤   ¤   ¤   {
506a36 ¤   ¤   ¤   ¤   err=WriteSectors(vi,vi->FAT_DirSector,·
72fcfe ¤   ¤   ¤   ¤   ¤   vi->FAT_DirSectorCount,pReadBuf);
21cab3 ¤   ¤   ¤   ¤   if(err!=WFE_NOERROR)
db72c3 ¤   ¤   ¤   ¤   {
9d73e6 ¤   ¤   ¤   ¤   ¤   RetVal=err;
482613 ¤   ¤   ¤   ¤   }
3aa3a6 ¤   ¤   ¤   }
080fe4 ¤   ¤   }
6b91b2 ¤   ¤   free(pReadBuf);
e79371 ¤   }
1baf5a
4e42d7 ¤   return RetVal;
74efe6 }
d2af5a
2f338c DWORD GetBufferSize(VOLINFO *vi,
b61803 ¤   ¤   ¤   ¤   ¤   DWORD dwIndexCluster,
c4389e ¤   ¤   ¤   ¤   ¤   DWORD *bufsize)
b7bb36 {
438be6 ¤   *bufsize=0;
b467c5 ¤
1451d3 ¤   while(IsntEnd(vi,dwIndexCluster))
01c7a1 ¤   {
226024 ¤   ¤   *bufsize+=vi->dwClusterSize;
2c944e ¤   ¤   dwIndexCluster=FatItem(vi,dwIndexCluster);
fb9371 ¤   }
c7af5a
bd5d0c ¤   if(IsClusterError(vi,dwIndexCluster))
f354eb ¤   ¤   return WFE_CLUSTERERROR;
d0af5a
177bf7 ¤   return WFE_NOERROR;
49efe6 }
f0af5a
013364 DWORD ReadChainIntoBuffer(VOLINFO *vi,DWORD dwIndexCluster,
e4a21e ¤   ¤   ¤   ¤   ¤   ¤   ··unsigned char *pReadBuf)
79bb36 {
30853b ¤   DWORD dwIndexBuffer,RetVal,err;
d4af5a
a77655 ¤   RetVal=WFE_NOERROR;
652d0e ¤   dwIndexBuffer=0;
24af5a
--cc52 00018b993d840110276 Page 12 of WFfat.c
d3d53f ¤   while((IsntEnd(vi,dwIndexCluster))&&(RetVal==WFE_NOERROR))
97c7a1 ¤   {
d9bee5 ¤   ¤   err=ReadSectors(vi,
ad0c98 ¤   ¤   ¤   ClusterToSector(vi,dwIndexCluster),·
7ea6cc ¤   ¤   ¤   vi->sectors_per_clus,
177e18 ¤   ¤   ¤   &(pReadBuf[dwIndexBuffer]));
c7af5a
f54c8d ¤   ¤   if(err!=WFE_NOERROR)
c65b34 ¤   ¤   {
c928dd ¤   ¤   ¤   RetVal=err;
c90fe4 ¤   ¤   }
8e0e1d ¤   ¤   else
305b34 ¤   ¤   {
edfe16 ¤   ¤   ¤   dwIndexBuffer+=vi->dwClusterSize;
6a8569 ¤   ¤   ¤   dwIndexCluster=FatItem(vi,dwIndexCluster);
df0fe4 ¤   ¤   }
369371 ¤   }
63af5a
4942d7 ¤   return RetVal;
cfefe6 }
3eaf5a
52af0d DWORD WriteChainFromBuffer(VOLINFO *vi,DWORD dwIndexCluster,
e1a21e ¤   ¤   ¤   ¤   ¤   ¤   ··unsigned char *pReadBuf)
35bb36 {
86853b ¤   DWORD dwIndexBuffer,RetVal,err;
e1af5a
107655 ¤   RetVal=WFE_NOERROR;
722d0e ¤   dwIndexBuffer=0;
feaf5a
98d53f ¤   while((IsntEnd(vi,dwIndexCluster))&&(RetVal==WFE_NOERROR))
d4c7a1 ¤   {
e59b36 ¤   ¤   err=WriteSectors(vi,
410c98 ¤   ¤   ¤   ClusterToSector(vi,dwIndexCluster),·
efa6cc ¤   ¤   ¤   vi->sectors_per_clus,
fe7e18 ¤   ¤   ¤   &(pReadBuf[dwIndexBuffer]));
27af5a
b34c8d ¤   ¤   if(err!=WFE_NOERROR)
605b34 ¤   ¤   {
4428dd ¤   ¤   ¤   RetVal=err;
850fe4 ¤   ¤   }
a00e1d ¤   ¤   else
3b5b34 ¤   ¤   {
f0fe16 ¤   ¤   ¤   dwIndexBuffer+=vi->dwClusterSize;
938569 ¤   ¤   ¤   dwIndexCluster=FatItem(vi,dwIndexCluster);
ea0fe4 ¤   ¤   }
789371 ¤   }
78af5a
fc42d7 ¤   return RetVal;
37efe6 }
21af5a
cb1eb7 DWORD DoDirectories(VOLINFO *vi)
5fbb36 {
0c01a0 ¤   DWORD bufsize,err,RetVal;
d2487c ¤   unsigned char *pReadBuf;
269dec ¤   DWORD dwStartCluster;
6daf5a
6b7655 ¤   RetVal=WFE_NOERROR;
4d3786 ¤   vi->ds=0;
b0af5a
06b9a7 ¤   if(vi->dwFS!=FS_FAT32)
10c7a1 ¤   {
7484bc ¤   // Do the nonstandard FAT16/FAT12 root directory
140e98 ¤   ¤   err=DoOldFatRootDirectory(vi);
f34c8d ¤   ¤   if(err!=WFE_NOERROR)
b828dd ¤   ¤   ¤   RetVal=err;
ce9371 ¤   }
270e24 ¤   else
57c7a1 ¤   {
4aecde ¤   // FAT32 root is normal.. just push on stack.
5e1064 ¤   ¤   PushDirStack(&(vi->ds),vi->FAT32_DirCluster);
0e9371 ¤   }
18af5a
--b927 00011f8e8cc40110276 Page 13 of WFfat.c
b2b1ee ¤   // If no errors so far, do operations on the stack
117ee3 ¤   while((PopDirStack(&(vi->ds),&dwStartCluster))&&
49de3e ¤   ¤   ··(RetVal==WFE_NOERROR))
88c7a1 ¤   {
a50238 ¤   ¤   // Starting cluster is invalid? Something wrong
f58119 ¤   ¤   if(!IsntEnd(vi,dwStartCluster))
196983 ¤   ¤   ¤   return WFE_CLUSTERERROR;
9daf5a
87a5b1 ¤   ¤   // Get the size of the buffer we'll need
95d217 ¤   ¤   err=GetBufferSize(vi,dwStartCluster,&bufsize);
b7af5a
c24c8d ¤   ¤   if(err!=WFE_NOERROR)
d75b34 ¤   ¤   {
b828dd ¤   ¤   ¤   RetVal=err;
980fe4 ¤   ¤   }
e30e1d ¤   ¤   else
a45b34 ¤   ¤   {
de692e ¤   ¤   ¤   pReadBuf = (BYTE*)malloc( bufsize );
8b7c7a ¤   ¤   ¤   if(!pReadBuf)
65f776 ¤   ¤   ¤   {
ba980e ¤   ¤   ¤   ¤   RetVal=WFE_OUTOFMEMORY;
29a3a6 ¤   ¤   ¤   }
c2bb8c ¤   ¤   ¤   else
40f776 ¤   ¤   ¤   {
4b45be //¤ ¤   ¤   ¤   This is just clearing the buffer
e81913 //¤ ¤   ¤   ¤   WritePattern(pReadBuf,vi->pattern_buffer, bufsize);
52e358 ¤   ¤   ¤   ¤   memset( pReadBuf, 0x00, bufsize );
4daf5a
2e307c ¤   ¤   ¤   ¤   // Read it in
f4ef42 ¤   ¤   ¤   ¤   err=ReadChainIntoBuffer(vi,
73511b ¤   ¤   ¤   ¤   ¤   dwStartCluster,pReadBuf);
9b67c5 ¤
e5cab3 ¤   ¤   ¤   ¤   if(err!=WFE_NOERROR)
0272c3 ¤   ¤   ¤   ¤   {
9c73e6 ¤   ¤   ¤   ¤   ¤   RetVal=err;
3e2613 ¤   ¤   ¤   ¤   }
73fa07 ¤   ¤   ¤   ¤   else
d972c3 ¤   ¤   ¤   ¤   {
3d646d ¤   ¤   ¤   ¤   ¤   // Clear entries and wipe slack
192f9c ¤   ¤   ¤   ¤   ¤   err=DoDirAndSlack(vi,pReadBuf,
40cd70 ¤   ¤   ¤   ¤   ¤   ¤   bufsize);·
09cf5e ¤   ¤   ¤   ¤   ¤   if(err!=WFE_NOERROR)
5d4859 ¤   ¤   ¤   ¤   ¤   {
73f81a ¤   ¤   ¤   ¤   ¤   ¤   RetVal=err;
831c89 ¤   ¤   ¤   ¤   ¤   }
a24bd6 ¤   ¤   ¤   ¤   ¤   else
224859 ¤   ¤   ¤   ¤   ¤   {
9e251f ¤   ¤   ¤   ¤   ¤   ¤   // Write it out again.
bd5c75 ¤   ¤   ¤   ¤   ¤   ¤   err=WriteChainFromBuffer(vi,
6cb024 ¤   ¤   ¤   ¤   ¤   ¤   ¤   dwStartCluster,pReadBuf);
a3c9e6 ¤   ¤   ¤   ¤   ¤   ¤   if(err!=WFE_NOERROR)
253d4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   RetVal=err;
bd1c89 ¤   ¤   ¤   ¤   ¤   }
092613 ¤   ¤   ¤   ¤   }
98a3a6 ¤   ¤   ¤   }
50a916 ¤   ¤   ¤   free( pReadBuf );
c70fe4 ¤   ¤   }
779371 ¤   }
d0af5a
a042d7 ¤   return RetVal;
f7efe6 }
abaf5a
7aad57 BOOL IsFATOK(VOLINFO *vi)
15bb36 {
84cccc ¤   DWORD dwClusterValue,dwIndex;
89af5a
ea7ec4 ¤   // Two is the first valid cluster
cf8963 ¤   for(dwIndex=2;dwIndex<vi->no_of_clusters;dwIndex++)
31c7a1 ¤   {
4a3278 ¤   ¤   dwClusterValue=FatItem(vi,dwIndex);
1baf5a
11a83f ¤   ¤   switch(vi->dwFS)
--1311 0007aa4ef8e40110276 Page 14 of WFfat.c
e35b34 ¤   ¤   {
e88edd ¤   ¤   ¤   case FS_FAT12:
757969 ¤   ¤   ¤   ¤   if(!(((dwClusterValue>=0xff0)&&
f15957 ¤   ¤   ¤   ¤   ······(dwClusterValue<=0xfff))||
5abd47 ¤   ¤   ¤   ¤   ······(dwClusterValue<=vi->no_of_clusters)))
dee143 ¤   ¤   ¤   ¤   ¤   return FALSE;
80f622 ¤   ¤   ¤   ¤   break;
f4af5a
4bedbc ¤   ¤   ¤   case FS_FAT16:
11d431 ¤   ¤   ¤   ¤   if(!(((dwClusterValue>=0xfff0)&&
408926 ¤   ¤   ¤   ·¤  ······(dwClusterValue<=0xffff))||
e3bd47 ¤   ¤   ¤   ¤   ······(dwClusterValue<=vi->no_of_clusters)))
e5e143 ¤   ¤   ¤   ¤   ¤   return FALSE;
4df622 ¤   ¤   ¤   ¤   break;
8caf5a
b6b7ab ¤   ¤   ¤   case FS_FAT32:
bdb63c ¤   ¤   ¤   ¤   if(!(((dwClusterValue>=0x0ffffff0)&&
ecc2b8 ¤   ¤   ¤   ¤   ······(dwClusterValue<=0x0fffffff))||
f3bd47 ¤   ¤   ¤   ¤   ······(dwClusterValue<=vi->no_of_clusters)))
a2e143 ¤   ¤   ¤   ¤   ¤   return FALSE;
52f622 ¤   ¤   ¤   ¤   break;
4b0fe4 ¤   ¤   }
c69371 ¤   }
87c2e7 ¤   return TRUE;
6aefe6 }
fcaf5a
efb6a2 DWORD ReadFAT(VOLINFO *vi,DWORD start_sector)
2cbb36 {
e57378 ¤   DWORD bufsize,RetVal,err;
70af5a
867655 ¤   RetVal=WFE_NOERROR;
c8af5a
45497a ¤   bufsize=vi->sector_size*vi->sectors_per_fat;
b9583f ¤   vi->pFatBuf = (BYTE*)malloc(bufsize);
72af5a
ce1e64 ¤   if(!vi->pFatBuf)
d8c7a1 ¤   {
d0d6a7 ¤   ¤   RetVal=WFE_OUTOFMEMORY;
e39371 ¤   }
b60e24 ¤   else
6ac7a1 ¤   {
341599 //¤ ¤   This is just clearing the buffer
25db10 //¤ ¤   WritePattern(vi->pFatBuf,vi->pattern_buffer, bufsize);
6b9d71 ¤   ¤   memset(vi->pFatBuf,0x00,bufsize);
3baf5a
b20451 ¤   ¤   // Read in raw data
e8bfd2 ¤   ¤   err=ReadSectors(vi,start_sector,·
745a07 ¤   ¤   ¤   vi->sectors_per_fat,vi->pFatBuf);
b0af5a
1f4c8d ¤   ¤   if(err!=WFE_NOERROR)
3d5b34 ¤   ¤   {
c5e001 ¤   ¤   ¤   free(vi->pFatBuf);
dd28dd ¤   ¤   ¤   RetVal=err;
300fe4 ¤   ¤   }
4d0e1d ¤   ¤   else
b25b34 ¤   ¤   {
1acd91 ¤   ¤   ¤   if(!IsFATOK(vi))
f1f776 ¤   ¤   ¤   {
a4e7d0 ¤   ¤   ¤   ¤   RetVal=WFE_FATFAILED;
e3a3a6 ¤   ¤   ¤   }
160fe4 ¤   ¤   }
649371 ¤   }
ba42d7 ¤   return RetVal;
9fefe6 }
adaf5a
d4441d DWORD WipeFreeClusters(VOLINFO *vi)
92bb36 {
6f18c0 ¤   DWORD i,err;
3167c5 ¤
88fabc ¤   WritePattern(vi->pClusterBuf,vi->pattern_buffer, vi->dwClusterSize);
ce6c6e ¤   //memset(vi->pClusterBuf,0x00,vi->dwClusterSize);
7aaf5a
--eeba 000f69a3e0140110276 Page 15 of WFfat.c
c07ec4 ¤   // Two is the first valid cluster
9e0899 ¤   for(i=2;i<vi->no_of_clusters;i++)
22c7a1 ¤   {
c0af9a ¤   ¤   if(FatItem(vi,i)==0)
ae5b34 ¤   ¤   {
512060 ¤   ¤   ¤   err=WriteSectors(vi,
5115b5 ¤   ¤   ¤   ¤   ClusterToSector(vi,i),
ed49bf ¤   ¤   ¤   ¤   vi->sectors_per_clus,
84932f ¤   ¤   ¤   ¤   vi->pClusterBuf);
96f7db ¤   ¤   ¤   if(err!=WFE_NOERROR)
c4454a ¤   ¤   ¤   ¤   return err;
e70fe4 ¤   ¤   }
8b9371 ¤   }
5baf5a
187bf7 ¤   return WFE_NOERROR;
32efe6 }
71af5a
a90278 BOOL GetFileSystem(VOLINFO *vi,char *szRoot)
39bb36 {
144795 ¤   char szFSName[256],szVolName[256];
8e884f ¤   DWORD dwVolSerial,dwFileLen,dwFSFlags;
a2af5a
56b84f ¤   if(!GetVolumeInformation(szRoot,
69dabb ¤   ¤   szVolName,256,
54aaff ¤   ¤   &dwVolSerial,
0cf164 ¤   ¤   &dwFileLen,
b8cae1 ¤   ¤   &dwFSFlags,
07cd1d ¤   ¤   szFSName,256))
8698aa ¤   ¤   return FALSE;
c5af5a
6f2928 ¤   vi->dwFS=FS_NOFS;
a1af5a
04b3ab ¤   // NTFS is also supported under WinNT
b39688 ¤   // HPFS went away with 3.51, so we'll
79533b ¤   // forget about it
dcf8a4 ¤   if(vi->WinNT)
86c7a1 ¤   {
e12f74 ¤   ¤   if(!strcmp(szFSName,"NTFS"))
da9465 ¤   ¤   ¤   vi->dwFS=FS_NTFS;
c19371 ¤   }
69af5a
b9bebb ¤   if(!strcmp(szFSName,"FAT32"))
cd0fde ¤   ¤   vi->dwFS=FS_FAT32;
5def36 ¤   else if(!strcmp(szFSName,"FAT"))
e194a3 ¤   ¤   vi->dwFS=FS_FAT;
4e67c5 ¤
0a0216 ¤   if(vi->dwFS==FS_NOFS)
4b98aa ¤   ¤   return FALSE;
a6af5a
95c2e7 ¤   return TRUE;
b8efe6 }
cbaf5a
7ddb7a void GetFatInfo(VOLINFO *vi,BOOTSECTOR *bs)
59bb36 {
ce4100 ¤   vi->dwReservedSectors = bs->bsResSectors;·
59947a ¤   vi->sector_size = bs->bsBytesPerSec;
d4c6ea ¤   vi->sectors_per_fat = bs->bsFATsecs;
56fadf ¤   vi->fat_count=bs->bsFATs;
2ffb28 ¤   vi->sectors_per_clus = bs->bsSecPerClust;
81a4ab ¤   ·
6b8df7 ¤   vi->sectors_total= bs->bsSectors ;
ae35fd ¤   if (vi->sectors_total==0)
10f43b ¤   ¤   vi->sectors_total = bs->bsHugeSectors ;
b2af5a
784aa0 ¤   // Root direcory info
d2f50a ¤   vi->FAT_DirSectorCount=
e47cc2 ¤   ¤   ((32 * bs->bsRootDirEnts)+vi->sector_size - 1)/
e666f0 ¤   ¤   vi->sector_size;
7c989f ¤   vi->FAT_DirSector=vi->dwReservedSectors+·
129a2f ¤   ¤   vi->sectors_per_fat*vi->fat_count;
698e6d ¤   vi->dwStartSector=
f6b477 ¤   ¤   vi->FAT_DirSector+vi->FAT_DirSectorCount;
--9fdb 0008abce39e40110276 Page 16 of WFfat.c
7aefe6 }
46af5a
64b615 void GetFat32Info(VOLINFO *vi,BOOTSECTOR32 *bs32)
8fbb36 {
60a163 ¤   vi->dwReservedSectors=bs32->bpb.A_BF_BPB_ReservedSectors;
24d8b6 ¤   vi->sector_size=bs32->bpb.A_BF_BPB_BytesPerSector;
3e3ed7 ¤   vi->sectors_per_fat=
d11db8 ¤   ¤   (bs32->bpb.A_BF_BPB_BigSectorsPerFatHi<<16)+·
61a634 ¤   ¤   bs32->bpb.A_BF_BPB_BigSectorsPerFat;
47c27f ¤   vi->fat_count=bs32->bpb.A_BF_BPB_NumberOfFATs;
174a60 ¤   vi->sectors_per_clus=bs32->bpb.A_BF_BPB_SectorsPerCluster;
588278 ¤   vi->sectors_total=bs32->bpb.A_BF_BPB_TotalSectors;
ac369f ¤   if(vi->sectors_total==0)
fbc7a1 ¤   {
9641a5 ¤   ¤   vi->sectors_total=
94351b ¤   ¤   ¤   (bs32->bpb.A_BF_BPB_BigTotalSectorsHigh<<16)+
6f16c5 ¤   ¤   ¤   bs32->bpb.A_BF_BPB_BigTotalSectors;
489371 ¤   }
6eaf5a
cad681 ¤   // Root directory info
189f25 ¤   vi->FAT32_DirCluster=
4c1f8a ¤   ¤   (bs32->bpb.A_BF_BPB_RootDirStrtClusHi<<16)+·
3fa19f ¤   ¤   bs32->bpb.A_BF_BPB_RootDirStrtClus;
33dab0 ¤   vi->dwStartSector = vi->dwReservedSectors +·
df9a2f ¤   ¤   vi->sectors_per_fat*vi->fat_count;
69efe6 }
acaf5a
0adafc DWORD DoWipe(VOLINFO *vi)
9dbb36 {
ed19f2 ¤   DWORD RetVal,err;
ef6672 ¤   char StrRes[500];
c1af5a
cb7655 ¤   RetVal=WFE_NOERROR;
a6af5a
ef72cc ¤   vi->pClusterBuf=
2c44c7 ¤   ¤   (unsigned char *)malloc(vi->dwClusterSize);
9baf5a
7443dc ¤   if(!vi->pClusterBuf)
fac7a1 ¤   {
8bd6a7 ¤   ¤   RetVal=WFE_OUTOFMEMORY;
999371 ¤   }
da0e24 ¤   else
2ac7a1 ¤   {
307d52 ¤   ¤   LoadString (g_hinst, IDS_READINGFAT, StrRes, sizeof(StrRes));
26af5a
a94d50 ¤   ¤   StatusMessage(StrRes, FALSE);
baaf5a
c98d59 ¤   ¤   err=ReadFAT(vi,vi->dwReservedSectors);
97af5a
8a4c8d ¤   ¤   if(err!=WFE_NOERROR)
ea5b34 ¤   ¤   {
b728dd ¤   ¤   ¤   RetVal=err;
eb0fe4 ¤   ¤   }
9e0e1d ¤   ¤   else
105b34 ¤   ¤   {
59715e ¤   ¤   ¤   LoadString (g_hinst, IDS_WIPINGDELANDSLACK, StrRes, sizeof(StrRes));
a9af5a
ef71be ¤   ¤   ¤   StatusMessage(StrRes, FALSE);
1272f2 ¤   ¤   ¤   err=DoDirectories(vi);
a8af5a
8ae035 ¤   ¤   ¤   WipeProgress(5);
31af5a
2af7db ¤   ¤   ¤   if(err!=WFE_NOERROR)
a6f776 ¤   ¤   ¤   {
90deb8 ¤   ¤   ¤   ¤   RetVal=err;
61a3a6 ¤   ¤   ¤   }
c9bb8c ¤   ¤   ¤   else
c8f776 ¤   ¤   ¤   {
86437d ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_WIPINGCLUSTERS, StrRes, sizeof(StrRes)¶
6d6275 );
68af5a
8a487b ¤   ¤   ¤   ¤   StatusMessage(StrRes, FALSE);
--f92b 00036fe0b1640110276 Page 17 of WFfat.c
fd665d ¤   ¤   ¤   ¤   err=WipeFreeClusters(vi);
8aaf5a
d3a87a ¤   ¤   ¤   ¤   WipeProgress(10);·
94af5a
70cab3 ¤   ¤   ¤   ¤   if(err!=WFE_NOERROR)
4c72c3 ¤   ¤   ¤   ¤   {
d973e6 ¤   ¤   ¤   ¤   ¤   RetVal=err;
bf2613 ¤   ¤   ¤   ¤   }
52a3a6 ¤   ¤   ¤   }
6de001 ¤   ¤   ¤   free(vi->pFatBuf);
490fe4 ¤   ¤   }
3caf5a
10ebf4 ¤   ¤   free(vi->pClusterBuf);
d09371 ¤   }
2daf5a
e542d7 ¤   return RetVal;
24efe6 }
15af5a
17cf17 DWORD NinetyFiveWipeFree(HWND hwnd,VOLINFO *vi,char *szRoot,
08df5d ¤   ¤   ¤   ···DWORD* pattern, BOOL StartWipe)
b7bb36 {
d86aaa ¤   BYTE* pReadBuf;
bf19f2 ¤   DWORD RetVal,err;
a76672 ¤   char StrRes[500];
0eaf5a
97de79 ¤   // One-based volume, 'A'=1, 'B'=2, 'C'=3, etc.
83690c ¤   vi->vol1=toupper(szRoot[0])-'A'+1;
94d83c ·
f90063 ¤   // Open VWIN32
3959a4 ¤   vi->hVWin32 = CreateFile( "\\\\.\\vwin32",
0458fb ¤   ¤   0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL );
54af5a
ec35cc ¤   // Get Level1 Exclusive Volume Lock
1e64db ¤   if(LockLogicalVolume(vi->hVWin32,vi->vol1,·
e26cef ¤   ¤   LEVEL1_LOCK,·
be73b6 ¤   ¤   LOCK_MAX_PERMISSION,
623e26 ¤   ¤   (vi->dwFS==FS_FAT32))!=0)
94c7a1 ¤   {
53cd69 ¤   ¤   RetVal=WFE_COULDNOTLOCK;
689371 ¤   }
170e24 ¤   else
adc7a1 ¤   {
1ced11 ¤   ¤   LoadString (g_hinst, IDS_READINGBOOT, StrRes, sizeof(StrRes));
49af5a
ab4d50 ¤   ¤   StatusMessage(StrRes, FALSE);
9baf5a
6509de ¤   ¤   // Read in boot sector
c0b33a ¤   ¤   pReadBuf = (BYTE*)malloc( 2048 );
f2af5a
8533b9 ¤   ¤   memset(pReadBuf,0x00,2048);
b0af5a
5c5b09 ¤   ¤   err=ReadSectors(vi,0,1,pReadBuf);
54af5a
f84c8d ¤   ¤   if(err!=WFE_NOERROR)
605b34 ¤   ¤   {
8c28dd ¤   ¤   ¤   RetVal=err;
f90fe4 ¤   ¤   }
2f0e1d ¤   ¤   else
375b34 ¤   ¤   {
dbc28f ¤   ¤   ¤   // Store some disk parameters
543bb2 ¤   ¤   ¤   if(vi->dwFS==FS_FAT32)
0f5496 ¤   ¤   ¤   ¤   GetFat32Info(vi,
f71216 ¤   ¤   ¤   ¤   ¤   (BOOTSECTOR32 *)pReadBuf);
79bb8c ¤   ¤   ¤   else
b3e68f ¤   ¤   ¤   ¤   GetFatInfo(vi,
abf485 ¤   ¤   ¤   ¤   ¤   (BOOTSECTOR *)pReadBuf);
f0af5a
1067d7 ¤   ¤   ¤   free(pReadBuf);
e6af5a
191ae9 ¤   ¤   ¤   if(vi->sectors_per_clus==0)
318735 ¤   ¤   ¤   ¤   vi->no_of_clusters=0;
36bb8c ¤   ¤   ¤   else
--aa70 000b39f94ca40110276 Page 18 of WFfat.c
f30586 ¤   ¤   ¤   ¤   vi->no_of_clusters=
2a36b0 ¤   ¤   ¤   ¤   ¤   (vi->sectors_total-vi->dwStartSector)/
41adc8 ¤   ¤   ¤   ¤   ¤   vi->sectors_per_clus;
7baf5a
921580 ¤   ¤   ¤   vi->dwClusterSize=vi->sectors_per_clus*
a2e9fb ¤   ¤   ¤   ¤   vi->sector_size;
5eaf5a
d55ee2 ¤   ¤   ¤   vi->fTotalCapacity=(float)vi->no_of_clusters*
606b64 ¤   ¤   ¤   ¤   (float)vi->dwClusterSize;
49af5a
235341 ¤   ¤   ¤   if(vi->dwFS==FS_FAT)
a8f776 ¤   ¤   ¤   {
4805c5 ¤   ¤   ¤   ¤   // Microsoft says 4086 here
18280d ¤   ¤   ¤   ¤   // FIPs says 4079. 4079 makes more sense,
44758e ¤   ¤   ¤   ¤   // but probably won't matter either way
ad228e ¤   ¤   ¤   ¤   if(vi->no_of_clusters <= 4079)
65ef0c ¤   ¤   ¤   ¤   ¤   vi->dwFS=FS_FAT12;
3cfa07 ¤   ¤   ¤   ¤   else
2c8c6d ¤   ¤   ¤   ¤   ¤   vi->dwFS=FS_FAT16;
eba3a6 ¤   ¤   ¤   }
97af5a
82cc57 ¤   ¤   ¤   DisplayDiskStats(vi);
bbaf5a
4b38b9 ¤   ¤   ¤   // Do wipe if so. Otherwise report stats.
31085b ¤   ¤   ¤   if(StartWipe)
51f776 ¤   ¤   ¤   {
c5763f ¤   ¤   ¤   ¤   vi->bCountClusters=TRUE;
2b5a3a ¤   ¤   ¤   ¤   RetVal=DoWipe(vi);
fb6642 ¤   ¤   ¤   ¤   if(RetVal==WFE_NOERROR)
6572c3 ¤   ¤   ¤   ¤   {
a1c184 ¤   ¤   ¤   ¤   ¤   vi->bCountClusters=FALSE;
831bc9 ¤   ¤   ¤   ¤   ¤   RetVal=DoWipe(vi);
112613 ¤   ¤   ¤   ¤   }
27a3a6 ¤   ¤   ¤   }
2a0fe4 ¤   ¤   }
e2ac1c ¤   ¤   // Free Level 1 lock
9fae28 ¤   ¤   UnlockLogicalVolume(
9bd1b3 ¤   ¤   ¤   vi->hVWin32,·
5e8734 ¤   ¤   ¤   vi->vol1,·
7c6282 ¤   ¤   ¤   (vi->dwFS==FS_FAT32));
d347d1 ¤   }·
2f12d3 ¤   CloseHandle(vi->hVWin32);
3caf5a
9d42d7 ¤   return RetVal;
55efe6 }
07af5a
c7ed14 // WipeFree
24465d //
abe09c // Main entry point for Win95 and WinNT wiper. Does
18dcfe // idiot checking first, then branches off
7bedeb DWORD WipeFree(HWND hwnd,VOLINFO *vi,char *szRoot,
bfdf5d ¤   ¤   ¤   ···DWORD* pattern, BOOL StartWipe)
c0bb36 {
9ce87f ¤   DWORD RetVal;
10f275 ¤   OSVERSIONINFO osid;
30ab3b ¤   UINT DriveType;
99af5a
1b398c ¤   bGlobalCancel=FALSE;
2b7655 ¤   RetVal=WFE_NOERROR;
9caf5a
072946 ¤   memset(vi,0x00,sizeof(VOLINFO));
9f4105 ¤   vi->hwnd=hwnd;
d367c5 ¤
9f4ba9 ¤   if(pattern)
bec7a1 ¤   {
430704 ¤   ¤   memcpy(vi->pattern_buffer, pattern, 256 * sizeof(DWORD));
0c9371 ¤   }
55af5a
b2fae5 ¤   if(*szRoot==0)
0d72e3 ¤   ¤   return WFE_NODRIVESELECTED;
4baf5a
b382e7 ¤   DriveType=GetDriveType(szRoot);
--503d 001a93ed96440110276 Page 19 of WFfat.c
e0af5a
6938fc ¤   if((DriveType==DRIVE_REMOTE)||
2b0901 ¤   ¤   (DriveType==DRIVE_CDROM)||
666f6f ¤   ¤   (DriveType==DRIVE_UNKNOWN)||
170362 ¤   ¤   (DriveType==DRIVE_NO_ROOT_DIR)||
034fde ¤   ¤   (DriveType==DRIVE_RAMDISK))
fe6885 ¤   ¤   return WFE_DRIVENOTSUPPORTED;
5daf5a
f7ce5f ¤   osid.dwOSVersionInfoSize = sizeof (osid);
06342c ¤   GetVersionEx (&osid); ··
a9cd1f ¤   vi->WinNT=(osid.dwPlatformId == VER_PLATFORM_WIN32_NT);
cfaf5a
b1c2d8 ¤   if(!GetFileSystem(vi,szRoot))
2b695a ¤   ¤   return WFE_FSNOTSUPPORTED;
cdaf5a
e0fc4a ¤   // End of idiot testing. Time to do work
3af8a4 ¤   if(vi->WinNT)
7446c0 ¤   ¤   return NTWipeFree(hwnd,vi,szRoot,
10e7d4 ¤   ¤   ¤   ···pattern, StartWipe);
8e0e24 ¤   else
1e6297 ¤   ¤   return NinetyFiveWipeFree(hwnd,vi,szRoot,
7fe7d4 ¤   ¤   ¤   ···pattern, StartWipe);
a9efe6 }
--e159 000afcbe84840110277 Page 1 of WFfat.h
3cb4e1 #define VWIN32_DIOC_DOS_IOCTL ··1 ··// DOS ioctl calls 4400h-4411h
aee8fe #define VWIN32_DIOC_DOS_INT25 ··2 ··// absolute disk read, DOS int 25h
2cbbc3 #define VWIN32_DIOC_DOS_INT26 ··3 ··// absolute disk write, DOS int 26h
831f25 #define VWIN32_DIOC_DOS_DRIVEINFO 6 // OEM Service Release 2·
1df956 ····································// ··Int 21h, 73xxh extensions
7191e1 typedef struct _DIOC_REGISTERS {
508b22 ····DWORD reg_EBX;
0ec0b8 ····DWORD reg_EDX;
eb9799 ····DWORD reg_ECX;
62aeef ····DWORD reg_EAX;
af1ff1 ····DWORD reg_EDI;
198b71 ····DWORD reg_ESI;
5818f5 ····DWORD reg_Flags;
c56fe7 ····}
0e02ab ····DIOC_REGISTERS, *PDIOC_REGISTERS;
65af5a
1eac16 #define CARRY_FLAG 1
faaf5a
af742b #define ··LEVEL1_LOCK ··1
24a0f0 #define ··LEVEL2_LOCK ··2
bcecb9 #define ··LEVEL3_LOCK ··3
1daf5a
a1fbf1 // We'll allow everything since we just abort if things
06dc24 // change
960db7 #define ··LOCK_MAX_PERMISSION ·0x001·
61af5a
27fb94 /*********************************************************
fd092d ·**** Note: all MS-DOS data structures must be packed ****
346b80 ·**** ······on a one-byte boundary. ··················****
54b0ab ·*********************************************************/
35c86b #pragma pack(1)
cdaf5a
72d9f9 typedef struct _DISKIO {
508a4e ····DWORD diStartSector; ···// sector number to start at
99b4ef ····WORD ·diSectors; ·······// number of sectors
a740fd ····DWORD diBuffer; ········// address of buffer
266fe7 ····}
7523cd ····DISKIO, *PDISKIO;
1faf5a
29af5a
2997ba typedef struct _BOOTSECT {
cc16e8 ····BYTE ···bsJump[3]; ·····// jmp instruction
3d9100 ····char ···bsOemName[8]; ··// OEM name and version
04af5a
544e21 ¤   ··// This portion is the BPB (BIOS Parameter Block)
d525db ····WORD ···bsBytesPerSec;¤ ¤   // bytes per sector
2c2cf6 ····BYTE ···bsSecPerClust;¤ ¤   // sectors per cluster
7b3971 ····WORD ···bsResSectors;¤  ¤   ··// number of reserved sectors
8efbac ····BYTE ···bsFATs;¤¤   ¤   ¤   ····// number of file allocation tables
12fc76 ····WORD ···bsRootDirEnts;¤ ¤   // number of root-directory entries
d0d355 ····WORD ···bsSectors;¤ ¤   ¤   ··// total number of sectors
50babc ····BYTE ···bsMedia;¤   ¤   ¤   ····// media descriptor
859313 ····WORD ···bsFATsecs;¤ ¤   ¤   ··// number of sectors per FAT
47f82c ····WORD ···bsSecPerTrack;¤ ¤   // number of sectors per track
74c304 ····WORD ···bsHeads;¤   ¤   ¤   ····// number of read/write heads
db5dd7 ····DWORD ··bsHiddenSectors;¤   // number of hidden sectors
39432e ····DWORD ··bsHugeSectors;¤ ¤   // number of sectors if bsSectors==0 ···
144cfd ¤   ··// End of BPB
80af5a
5329d1 ····BYTE ···bsDriveNumber;¤ ¤   ··// 80h if first hard drive
b14713 ····BYTE ···bsReserved; ····
279544 ····BYTE ···bsBootSignature; ···// 29h if extended boot-signature record
9560bd ····DWORD ··bsVolumeID;¤¤   ¤   ····// volume ID number
20889d ····char ···bsVolumeLabel[11]; ·// volume label
3778a1 ····char ···bsFileSysType[8]; ··// file-system type (FAT12 or FAT16)
7c6fe7 ····}
0c3b97 ····BOOTSECTOR, *PBOOTSECTOR;
1faf5a
944b08 typedef struct _DIRENTRY {
30982a ····char ···deName[8];¤ ¤   ¤   ····// base name
0740fd ····char ···deExtension[3];¤¤   ··// extension
af93e9 ····BYTE ···deAttributes;¤  ¤   ····// file or directory attributes
--8577 0014384cb5d40110277 Page 2 of WFfat.h
9d946f ····BYTE ···deReserved[6];
d0f3e8 ····WORD ···deLastAccessDate;¤  ··// *New Win95* - last access date·
4f3a8e ····WORD ···deEAhandle;¤¤   ¤   ····// *New FAT32* - high word of starting clus¶
e37877 ter
29ae56 ····WORD ···deCreateTime;¤  ¤   ····// creation or last modification time
0d9668 ····WORD ···deCreateDate;¤  ¤   ····// creation or last modification date
a9a0da ····WORD ···deStartCluster;¤¤   ··// starting cluster of the file or directory
4c5189 ····DWORD ··deFileSize;¤¤   ¤   ····// size of the file in bytes
b76fe7 ····}
984d4e ····DIRENTRY, *PDIRENTRY;
cfaf5a
928785 typedef struct _LONGDIRENTRY {
b2e7cb ····char ···leSequence;¤¤   ¤   // sequence byte:1,2,3,..., last entry is or'ed¶
6e64f7 ·with 40h
c3b506 ····wchar_t leName[5];¤ ¤   ¤   // Unicode characters of name
7f68cd ····BYTE ···leAttributes;¤  ¤   // Attributes: 0fh
39675c ····BYTE ···leType;¤¤   ¤   ¤   ··// Long Entry Type: 0
0df131 ····BYTE ···leChksum;¤  ¤   ¤   ··// Checksum for matching short name alias
3dacb8 ····wchar_t leName2[6];¤¤   ¤   // More Unicode characters of name
031c5d ····WORD ···leZero;¤¤   ¤   ¤   ··// reserved
fc6ad4 ····wchar_t leName3[2];¤¤   ¤   // More Unicode characters of name
596fe7 ····}
7c00b1 ····LONGDIRENTRY, *PLONGDIRENTRY;
1faf5a
66aef7 ////////////////// FAT32 Structures ///////////////////
d4af5a
a148c6 // BPB for a Fat32 partition
686a62 typedef struct _A_BF_BPB {
e28836 ····WORD ···A_BF_BPB_BytesPerSector;
ce9c64 ····BYTE ···A_BF_BPB_SectorsPerCluster;
bca6f1 ····WORD ···A_BF_BPB_ReservedSectors;
4c8a38 ····BYTE ···A_BF_BPB_NumberOfFATs;
4baf9a ····WORD ···A_BF_BPB_RootEntries;
e92cbd ····WORD ···A_BF_BPB_TotalSectors;
9cc3ea ····BYTE ···A_BF_BPB_MediaDescriptor;
388734 ····WORD ···A_BF_BPB_SectorsPerFAT;
010820 ····WORD ···A_BF_BPB_SectorsPerTrack;
9bcdaf ····WORD ···A_BF_BPB_Heads;
a2bbe1 ····WORD ···A_BF_BPB_HiddenSectors;
8a8ecc ····WORD ···A_BF_BPB_HiddenSectorsHigh;
94000f ····WORD ···A_BF_BPB_BigTotalSectors;
3837e0 ····WORD ···A_BF_BPB_BigTotalSectorsHigh;
0e9de9 ····WORD ···A_BF_BPB_BigSectorsPerFat;
17191c ····WORD ···A_BF_BPB_BigSectorsPerFatHi;
5c6643 ····WORD ···A_BF_BPB_ExtFlags;
4d24f4 ····WORD ···A_BF_BPB_FS_Version;
25af05 ····WORD ···A_BF_BPB_RootDirStrtClus;
6b4bb4 ····WORD ···A_BF_BPB_RootDirStrtClusHi;
0a4582 ····WORD ···A_BF_BPB_FSInfoSec;
046ae7 ····WORD ···A_BF_BPB_BkUpBootSec;
160c7d ····WORD ···A_BF_BPB_Reserved[6];
f56fe7 ····}
a8457d ····A_BF_BPB, PA_BF_BPB;
8daf5a
e6aa07 typedef struct _BOOTSECT32 {
6816e8 ····BYTE ···bsJump[3]; ·····// jmp instruction
339100 ····char ···bsOemName[8]; ··// OEM name and version
3caf5a
d4e61a ¤   ··// This portion is the FAT32 BPB
5f319b ¤   ··A_BF_BPB ·bpb;
9eaf5a
c629d1 ····BYTE ···bsDriveNumber;¤ ¤   ··// 80h if first hard drive
854713 ····BYTE ···bsReserved; ····
679544 ····BYTE ···bsBootSignature; ···// 29h if extended boot-signature record
0660bd ····DWORD ··bsVolumeID;¤¤   ¤   ····// volume ID number
6f889d ····char ···bsVolumeLabel[11]; ·// volume label
f1244a ····char ···bsFileSysType[8]; ··// file-system type (FAT32)
1e6fe7 ····}
85d22d ····BOOTSECTOR32, *PBOOTSECTOR32;
95d83c ·
435fec #pragma pack()
--f20d 000a130496240110278 Page 1 of WFnt.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
f5c315 ¤   $Id: WFnt.c,v 1.8.2.1.2.1 1998/11/12 03:13:31 heller Exp $
38f7f7 ____________________________________________________________________________*/
af5ed8 #include "precomp.h"
7faf5a
10465d //
aed6dc // Invalid longlong number
4c465d //
f6aad7 #define LLINVALID¤  ¤   ((ULONGLONG) -1)
87af5a
72465d //
109460 // Size of the buffer we read file mapping information into.
3c9a4f // The buffer is big enough to hold the 16 bytes that·
96b5ac // come back at the head of the buffer (the number of entries·
8d5974 // and the starting virtual cluster), as well as 512 pairs
8e0ef5 // of [virtual cluster, logical cluster] pairs.
27465d //
ec514b #define¤FILEMAPSIZE¤¤   (512+2)
0faf5a
87465d //
c2c6f2 // Size of the bitmap buffer we pass in. Its large enough to
d876c6 // hold information for the 16-byte header that's returned
08e477 // plus the indicated number of bytes, each of which has 8 bits·
1b19ed // (imagine that!)
cb465d //
e62b11 #define BITMAPBYTES¤¤   4096
134cfb #define BITMAPSIZE¤ ¤   (BITMAPBYTES+2*sizeof(ULONGLONG))
e9af5a
a4465d //
1c504c // Bit shifting array for efficient processing of the bitmap
64465d //
07cf8c BYTE¤   ¤   BitShift[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
f7af5a
cb3bb3 // StatusToError
43465d //
5b2986 // Takes the status messages and turns them into our
30b881 // native wipe free codes.
db60e3 DWORD StatusToError( NTSTATUS Status )
d6bb36 {
45b9fb ¤   switch( Status )·
c8c7a1 ¤   {
9060cc ¤   case STATUS_SUCCESS:
7b8d92 ¤   ¤   return WFE_NOERROR;
4b492e ¤   case STATUS_INVALID_PARAMETER:
21c673 ¤   ¤   return WFE_INVALPARAM; // Must be the metafile
c0c6d1 ¤   case STATUS_BUFFER_TOO_SMALL:
19b293 ¤   ¤   return WFE_OUTOFMEMORY;
c373a1 ¤   case STATUS_ALREADY_COMMITTED:
df92af ¤   ¤   return WFE_ALREADYCOMMIT; // NTFS won't let us. Try anyway
80ec56 ¤   case STATUS_INVALID_DEVICE_REQUEST:
946885 ¤   ¤   return WFE_DRIVENOTSUPPORTED;
ff3b3f ¤   case STATUS_DEVICELOCKED:
7cbaaa ¤   ¤   return WFE_COULDNOTLOCK;
d12f72 ¤   default:
8754eb ¤   ¤   return WFE_CLUSTERERROR;
d14939 ¤   }¤  ¤   ··
b9efe6 }
70af5a
d9d3d5 // OpenVolume
64465d //
27167e // Grabs the handle of our logical volume
950c74 DWORD OpenVolume( VOLINFO *vi )·
7cbb36 {
3cea27 ¤   static char¤¤   ¤   volumeName[] = "\\\\.\\A:";
f3af5a
3ca617 ¤   //
a19b06 ¤   // open the volume
--693d 0007f98c97f40110278 Page 2 of WFnt.c
14a617 ¤   //
3fd79f ¤   volumeName[4] = (char)vi->vol0 + 'A';·
02dae1 ¤   vi->VolHandle = CreateFile( volumeName, GENERIC_READ,·
9a7193 ¤   ¤   ¤   ¤   ¤   FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,·
5ebb54 ¤   ¤   ¤   ¤   ¤   0, 0 );
2aa82c ¤   if( vi->VolHandle == INVALID_HANDLE_VALUE )¤{
13af5a
280351 ¤   ¤   return GetLastError();
a09371 ¤   }
39af5a
fa3b49 ¤   return ERROR_SUCCESS;
c4efe6 }
8faf5a
31722d // WipeCluster
47465d //
0f03ef // WipeCluster uses the patterns stored in filename to·
53e109 // eradicate the data in the target cluster of the logical
240f91 // drive specified.
bfaf5a
ce2a39 DWORD NTWipeCluster( VOLINFO *vi, char *fileName, ULONGLONG Vcn, ULONGLONG targ¶
fe4f7b et)
35bb36 {
42ea00 ¤   DWORD¤  ¤   ¤   ¤   ¤   ¤   status;
14adb5 ¤   IO_STATUS_BLOCK¤¤   ¤   ¤   ioStatus;
19fd3d ¤   HANDLE¤ ¤   ¤   ¤   ¤   ¤   sourceFile;
4ac105 ¤   LARGE_INTEGER¤  ¤   ¤   ¤   startVcn, targetLcn;
f4925e ¤   DWORD¤  ¤   ¤   ¤   ¤   ¤   numClusters;
5ab165 ¤   MOVEFILE_DESCRIPTOR¤¤   ¤   moveFile;
59af5a
0be87f ¤   DWORD RetVal;
e6af5a
9c7655 ¤   RetVal=WFE_NOERROR;
20af5a
59cbb2 ¤   if(vi->bCountClusters)
92c7a1 ¤   {
7b97ec ¤   ¤   vi->dwClusterCount++;
96af5a
a878ee ¤   ¤   if(vi->dwFS==FS_NTFS)
102dda ¤   ¤   ¤   // NTFS works with 16 cluster segments
3c6a01 ¤   ¤   ¤   vi->dwClusterCount=vi->dwClusterCount+15;·
d6af5a
6bff0c ¤   ¤   if(UserPressedCancel(vi))
2217c7 ¤   ¤   ¤   RetVal=WFE_USERCANCEL;
fd793e ¤   ¤   return RetVal;
339371 ¤   }
ffaf5a
3241d4 ¤   //·
e32fc0 ¤   // Get numeric parameters
7aa617 ¤   //
bb9a29 ¤   startVcn.QuadPart=Vcn;
e26848 ¤   targetLcn.QuadPart=target;
17f725 ¤   numClusters=1;
c2af5a
f4f1ba ¤   if(vi->dwFS==FS_NTFS)
3839ca ¤   ¤   numClusters=16; // NTFS works with 16 cluster segments
e1a617 ¤   //
f932d8 ¤   // Open the file
10a617 ¤   //
e25e58 ¤   sourceFile = CreateFile( fileName, GENERIC_READ,·
9f7193 ¤   ¤   ¤   ¤   ¤   FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,·
28d34e ¤   ¤   ¤   ¤   ¤   FILE_FLAG_NO_BUFFERING, 0 );
734560 ¤   if( sourceFile == INVALID_HANDLE_VALUE )·
94c7a1 ¤   {
50e26c ¤   ¤   // Could not open file
43186e ¤   ¤   return WFE_COULDNOTREAD ;
d39371 ¤   }
cdaf5a
f3a617 ¤   //
b6f7f8 ¤   // Setup movefile descriptor and make the call
f4a617 ¤   //
6d8c00 ¤   memset(&moveFile,0x00,sizeof(MOVEFILE_DESCRIPTOR));
7f02a3 ¤   memset(&ioStatus,0x00,sizeof(IO_STATUS_BLOCK));
--9a83 000dfce0d4140110278 Page 3 of WFnt.c
e0af5a
176a27 ¤   moveFile.FileHandle = sourceFile;
30c57e ¤   moveFile.StartVcn = startVcn;
f13845 ¤   moveFile.TargetLcn = targetLcn;
ebda20 ¤   moveFile.NumVcns = numClusters;
4aaf5a
4170b4 ¤   status = NtFsControlFile( vi->VolHandle, NULL, NULL, 0, &ioStatus,
99ad36 ¤   ¤   ¤   ¤   ¤   ¤   FSCTL_MOVE_FILE,
aa54fc ¤   ¤   ¤   ¤   ¤   ¤   &moveFile, sizeof( moveFile ),
f9cf5d ¤   ¤   ¤   ¤   ¤   ¤   NULL, 0 );
caaf5a
668f3d ¤   RetVal=StatusToError(status);
46af5a
1241d4 ¤   //·
56f574 ¤   // If the operation is pending, wait for it to finish
dba617 ¤   //
441c95 ¤   if( status == STATUS_PENDING )·
f8c7a1 ¤   {
a50fd1 ¤   ¤   WaitForSingleObject( sourceFile, INFINITE );·
6daf5a
12d4e1 ¤   ¤   RetVal=StatusToError(ioStatus.Status);
e59371 ¤   }
a9af5a
55985d ¤   CloseHandle(sourceFile);
9a67c5 ¤
b5c9dd ¤   // Handle our progress bars and look out for user cancel
09c7a1 ¤   {
0aa1c7 ¤   ¤   char StrRes[500];
0fc79a ¤   ¤   char statusmsg[500];
6eaf5a
20b23e ¤   ¤   vi->dwClustersWritten=vi->dwClustersWritten+1;
2e1b52 ¤   ¤
b778ee ¤   ¤   if(vi->dwFS==FS_NTFS)
322dda ¤   ¤   ¤   // NTFS works with 16 cluster segments
ff3692 ¤   ¤   ¤   vi->dwClustersWritten=vi->dwClustersWritten+15;·
8baf5a
247380 ¤   ¤   if(vi->dwClustersWritten%10==0)
ac5b34 ¤   ¤   {
17c4e7 ¤   ¤   ¤   float pos;
b1af5a
7e3ff2 ¤   ¤   ¤   LoadString (g_hinst, IDS_PERCENTWRITTEN, StrRes, sizeof(StrRes));
1aaf5a
03a317 ¤   ¤   ¤   if(RetVal==WFE_NOERROR)
09f776 ¤   ¤   ¤   {
a98577 ¤   ¤   ¤   ¤   sprintf(statusmsg,
68e14a ¤   ¤   ¤   ¤   ¤   StrRes,
af85f9 ¤   ¤   ¤   ¤   ¤   vi->dwClustersWritten,vi->dwClusterCount);
28a3a6 ¤   ¤   ¤   }
88bb8c ¤   ¤   ¤   else
e7f776 ¤   ¤   ¤   {
d58577 ¤   ¤   ¤   ¤   sprintf(statusmsg,
8fc4d7 ¤   ¤   ¤   ¤   ¤   "An error occurred... %d of %d",
6985f9 ¤   ¤   ¤   ¤   ¤   vi->dwClustersWritten,vi->dwClusterCount);
4fa3a6 ¤   ¤   ¤   }
15af5a
314fe6 ¤   ¤   ¤   if(vi->dwFS==FS_NTFS)
03f776 ¤   ¤   ¤   {
a875aa ¤   ¤   ¤   ¤   if(RetVal==WFE_INVALPARAM)
8172c3 ¤   ¤   ¤   ¤   {
76c484 ¤   ¤   ¤   ¤   ¤   sprintf(statusmsg,
a0b6dc ¤   ¤   ¤   ¤   ¤   ¤   "Skipping NTFS metadata. %d of %d.",
8c0805 ¤   ¤   ¤   ¤   ¤   ¤   vi->dwClustersWritten,vi->dwClusterCount);
8a2613 ¤   ¤   ¤   ¤   }
9c6c85 ¤   ¤   ¤   ¤   else if(RetVal==WFE_ALREADYCOMMIT)
3172c3 ¤   ¤   ¤   ¤   {
6fc484 ¤   ¤   ¤   ¤   ¤   sprintf(statusmsg,
2cca2e ¤   ¤   ¤   ¤   ¤   ¤   "NTFS won't release cluster. %d of %d.",
680805 ¤   ¤   ¤   ¤   ¤   ¤   vi->dwClustersWritten,vi->dwClusterCount);
742613 ¤   ¤   ¤   ¤   }
cba3a6 ¤   ¤   ¤   }
acaf5a
df2678 ¤   ¤   ¤   StatusMessage(statusmsg, FALSE);
--d3a6 00099ab0da440110278 Page 4 of WFnt.c
e0af5a
605f3e ¤   ¤   ¤   pos = 10 +·
f665b7 ¤   ¤   ¤   ¤   ( (float)vi->dwClustersWritten /·
c8086a ¤   ¤   ¤   ¤   ··(float)vi->dwClusterCount )
528d68 ¤   ¤   ¤   ¤   * 90;
dbaf5a
279856 ¤   ¤   ¤   WipeProgress((int)pos);·
250fe4 ¤   ¤   }
a09371 ¤   }
ecaf5a
e9c804 ¤   if(UserPressedCancel(vi))
2c9bb8 ¤   ¤   RetVal=WFE_USERCANCEL;
32af5a
ac42d7 ¤   return RetVal;
86efe6 }
4eaf5a
34da13 // WipeFreeClusters
ee465d //
8245eb // Given a logical drive number, routine iterates through free
2ba80e // clusters and calls WipeCluster to zap the information stored
92d9a1 // there. Note that if changes take place on the drive while
1ed492 // routine is executes, some clusters may be missed.
e7af5a
48cbd5 DWORD NTWipeFreeClusters( VOLINFO *vi)
cabb36 {
1e2475 ¤   DWORD¤  ¤   ¤   ¤   ¤   ¤   status,wipestatus;
a710e8 ¤   PBITMAP_DESCRIPTOR¤ ¤   ¤   bitMappings;
762b2b ¤   ULONGLONG¤  ¤   ¤   ¤   ¤   startLcn;
017c6a ¤   ULONGLONG¤  ¤   ¤   ¤   ¤   nextLcn;
4aadb5 ¤   IO_STATUS_BLOCK¤¤   ¤   ¤   ioStatus;
cebf6e ¤   ULONGLONG¤  ¤   ¤   ¤   ¤   i;
b37582 ¤   BYTE¤   ¤   ¤   ¤   ¤   ¤   BitMap[ BITMAPSIZE ];
725098 ¤   char¤   ¤   ¤   ¤   ¤   ¤   fileName[MAX_PATH];
3467c5 ¤
04a617 ¤   //
140ab2 ¤   // Make the name into a real pathname
33a617 ¤   //
d4d548 ¤   sprintf(fileName, "%C:\\%s", vi->vol0+'A', "PGPwipepattern.tmp" );
91af5a
8ba617 ¤   //
e070d2 ¤   // Start scanning at the cluster offset the user specifies
6fa617 ¤   //
5856c6 ¤   bitMappings = (PBITMAP_DESCRIPTOR) BitMap;
79d624 ¤   nextLcn = 0;
b9af5a
73f14e ¤   while( !(status = NtFsControlFile( vi->VolHandle, NULL, NULL, 0, &ioStatus,
66aba4 ¤   ¤   ¤   ¤   ¤   ¤   FSCTL_GET_VOLUME_BITMAP,
236348 ¤   ¤   ¤   ¤   ¤   ¤   &nextLcn, sizeof( ULONGLONG ),
991d1a ¤   ¤   ¤   ¤   ¤   ¤   bitMappings, BITMAPSIZE )) ||
6e322f ¤   ¤   ¤   ·status == STATUS_BUFFER_OVERFLOW ||
820852 ¤   ¤   ¤   ·status == STATUS_PENDING )·
48c7a1 ¤   {
65af5a
2d78d4 ¤   ¤   //·
d51774 ¤   ¤   // If the operation is pending, wait for it to finish
9365af ¤   ¤   //
c7d9c0 ¤   ¤   if( status == STATUS_PENDING )·
e75b34 ¤   ¤   {
da87c7 ¤   ¤   ¤
8734fd ¤   ¤   ¤   WaitForSingleObject( vi->VolHandle, INFINITE );
4d87c7 ¤   ¤   ¤
210415 ¤   ¤   ¤   //
702469 ¤   ¤   ¤   // Get the status from the status block
c50415 ¤   ¤   ¤   //
b10407 ¤   ¤   ¤   if( ioStatus.Status != STATUS_SUCCESS &&·
cd13c4 ¤   ¤   ¤   ¤   ioStatus.Status != STATUS_BUFFER_OVERFLOW )·
7af776 ¤   ¤   ¤   {
093180 ¤   ¤   ¤   ¤   // Error out
d0cf99 ¤   ¤   ¤   ¤   return StatusToError(ioStatus.Status);
3ba3a6 ¤   ¤   ¤   }
a20fe4 ¤   ¤   }
99af5a
--8156 000753cbfe140110278 Page 5 of WFnt.c
6165af ¤   ¤   //
61c4dd ¤   ¤   // Scan through the returned bitmap info, looking for empty clusters
ff65af ¤   ¤   //
6a5370 ¤   ¤   startLcn = bitMappings->StartLcn;
fe67c5 ¤
c47cb6 ¤   ¤   for( i = 0; i < min( bitMappings->ClustersToEndOfVol, 8*BITMAPBYTES); i¶
c94772 ++ )·
965b34 ¤   ¤   {
92af5a
988d0b ¤   ¤   ¤   if( !(bitMappings->Map[ i/8 ] & BitShift[ i % 8 ]))·
77f776 ¤   ¤   ¤   {
ed94b6 ¤   ¤   ¤   ¤   wipestatus=NTWipeCluster( vi, fileName, 0, startLcn + i);
d0af5a
bcfa21 ¤   ¤   ¤   ¤   if((wipestatus==WFE_NOERROR)&&(vi->SlackMove))
9072c3 ¤   ¤   ¤   ¤   {
4fb417 ¤   ¤   ¤   ¤   ¤   // Hey, we were able to do it. Save this cluster for·
d7a686 ¤   ¤   ¤   ¤   ¤   // later slack movement operations since we know its
c2b158 ¤   ¤   ¤   ¤   ¤   // free
ae15dc ¤   ¤   ¤   ¤   ¤   if(vi->PatternBuffer==0)
dd0e48 ¤   ¤   ¤   ¤   ¤   ¤   vi->PatternBuffer=startLcn+i;
c552a0 ¤   ¤   ¤   ¤   ¤   else if(vi->SlackBufferIndex<SLACKBUFFER)
ce4859 ¤   ¤   ¤   ¤   ¤   {
68239c ¤   ¤   ¤   ¤   ¤   ¤   vi->SlackBuffer[vi->SlackBufferIndex]=startLcn+i;
f73159 ¤   ¤   ¤   ¤   ¤   ¤   vi->SlackBufferIndex=vi->SlackBufferIndex+1;
531c89 ¤   ¤   ¤   ¤   ¤   }
b72613 ¤   ¤   ¤   ¤   }
fcaf5a
b347cc ¤   ¤   ¤   ¤   if(((wipestatus==WFE_ALREADYCOMMIT)||(wipestatus==WFE_INVALPARA¶
5d8461 M))&&(vi->dwFS==FS_NTFS))
9972c3 ¤   ¤   ¤   ¤   {
609c7e ¤   ¤   ¤   ¤   ¤   // Couldn't do the move because of MFT, or user is mucking
1a68a8 ¤   ¤   ¤   ¤   ¤   // around.... just skip it and we'll get it on the next pas¶
a979c5 s.
c258bd ¤   ¤   ¤   ¤   ¤   // Only applies to NTFS
826909 ¤   ¤   ¤   ¤   ¤   wipestatus=WFE_NOERROR;
f62613 ¤   ¤   ¤   ¤   }
5faf5a
93e8b8 ¤   ¤   ¤   ¤   if(wipestatus!=WFE_NOERROR)
d572c3 ¤   ¤   ¤   ¤   {
0e8060 ¤   ¤   ¤   ¤   ¤   return wipestatus;
f72613 ¤   ¤   ¤   ¤   }
d8e5d3 ¤   ¤   ¤   }·
42af5a
654fe6 ¤   ¤   ¤   if(vi->dwFS==FS_NTFS)
3aa16a ¤   ¤   ¤   ¤   i=i+15; // NTFS works with 16 cluster segments
760fe4 ¤   ¤   }
0c67c5 ¤
ab65af ¤   ¤   //
026872 ¤   ¤   // End of volume?
9665af ¤   ¤   //
d1b066 ¤   ¤   if( status != STATUS_BUFFER_OVERFLOW )·
325b34 ¤   ¤   {
c11b52 ¤   ¤
170efc ¤   ¤   ¤   return StatusToError(STATUS_SUCCESS);
f8c653 ¤   ¤   }¤  ¤   ¤   ¤
07af5a
c165af ¤   ¤   //
4c06dd ¤   ¤   // Move to the next block
bc65af ¤   ¤   //
4265fc ¤   ¤   nextLcn = bitMappings->StartLcn + i;
f49371 ¤   }
d5af5a
5da617 ¤   //
5c4407 ¤   // We only get here when there's an error
faa617 ¤   //
aeaf5a
23d4e2 ¤   return StatusToError(status);
2eefe6 }
00af5a
35af5a
e3af5a
75f89c // GetLastClusterOfFile
--307e 000d32a919140110278 Page 6 of WFnt.c
c1465d //
6888ea // Loops through till it finds the last cluster in the chain
31af5a
8e0c2a DWORD GetLastClusterOfFile(VOLINFO *vi, char *fileName, SLACKMOVE *sm)
8bbb36 {
bdea00 ¤   DWORD¤  ¤   ¤   ¤   ¤   ¤   status;
6617f4 ¤   int¤¤   ¤   ¤   ¤   ¤   ¤   i;
a9fd3d ¤   HANDLE¤ ¤   ¤   ¤   ¤   ¤   sourceFile;
05adb5 ¤   IO_STATUS_BLOCK¤¤   ¤   ¤   ioStatus;
c0d3c3 ¤   ULONGLONG¤  ¤   ¤   ¤   ¤   startVcn;
429846 ¤   PGET_RETRIEVAL_DESCRIPTOR¤  fileMappings;
1bfda2 ¤   int¤¤   ¤   ¤   ¤   ¤   ¤   lines = 0;
79a490 ¤   ULONGLONG¤  ¤   ¤   ¤   ¤   FileMap[ FILEMAPSIZE ];
1eaf5a
ec4b93 ¤   // Save name of file for later
6e39fa ¤   sm->name=fileName;
fdaf5a
0da617 ¤   //
2432d8 ¤   // Open the file
f6a617 ¤   //
b55e58 ¤   sourceFile = CreateFile( fileName, GENERIC_READ,·
727193 ¤   ¤   ¤   ¤   ¤   FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,·
93d34e ¤   ¤   ¤   ¤   ¤   FILE_FLAG_NO_BUFFERING, 0 );
b7af5a
ef4560 ¤   if( sourceFile == INVALID_HANDLE_VALUE )·
f3fea1 ¤   ¤   return WFE_COULDNOTREAD;
97af5a
47a617 ¤   //
43101c ¤   // Start dumping the mapping information. Go until we hit the end of the
714e2c ¤   // file.
cfa617 ¤   //
312081 ¤   startVcn = 0;
79fdf3 ¤   fileMappings = (PGET_RETRIEVAL_DESCRIPTOR) FileMap;
03a722 ¤   while( !(status = NtFsControlFile( sourceFile, NULL, NULL, 0, &ioStatus,
50fb18 ¤   ¤   ¤   ¤   ¤   ¤   FSCTL_GET_RETRIEVAL_POINTERS,
50ab2b ¤   ¤   ¤   ¤   ¤   ¤   &startVcn, sizeof( startVcn ),
4153c1 ¤   ¤   ¤   ¤   ¤   ¤   fileMappings, FILEMAPSIZE * sizeof(LARGE_INTEGER) ) ) ||
2c322f ¤   ¤   ¤   ·status == STATUS_BUFFER_OVERFLOW ||
390852 ¤   ¤   ¤   ·status == STATUS_PENDING )·
9dc7a1 ¤   {
7678d4 ¤   ¤   //·
cf1774 ¤   ¤   // If the operation is pending, wait for it to finish
8065af ¤   ¤   //
b185ef ¤   ¤   if( status == STATUS_PENDING ) {
1e87c7 ¤   ¤   ¤
e70ca6 ¤   ¤   ¤   WaitForSingleObject( sourceFile, INFINITE );·
a4af5a
a00415 ¤   ¤   ¤   //
1a2469 ¤   ¤   ¤   // Get the status from the status block
310415 ¤   ¤   ¤   //
110407 ¤   ¤   ¤   if( ioStatus.Status != STATUS_SUCCESS &&·
a713c4 ¤   ¤   ¤   ¤   ioStatus.Status != STATUS_BUFFER_OVERFLOW )·
86f776 ¤   ¤   ¤   {
113180 ¤   ¤   ¤   ¤   // Error out
c3cf99 ¤   ¤   ¤   ¤   return StatusToError(ioStatus.Status);
2fa3a6 ¤   ¤   ¤   }
190fe4 ¤   ¤   }
31af5a
1c65af ¤   ¤   //
89bc11 ¤   ¤   // Loop through the buffer of number/cluster pairs, printing them
a2d178 ¤   ¤   // out.
6265af ¤   ¤   //
aaa108 ¤   ¤   startVcn = fileMappings->StartVcn;
977939 ¤   ¤   for( i = 0; i < (ULONGLONG) fileMappings->NumberOfPairs; i++ )·
695b34 ¤   ¤   {
5f0415 ¤   ¤   ¤   //
e2d863 ¤   ¤   ¤   // On NT 4.0, a compressed virtual run (0-filled) is·
0c9f17 ¤   ¤   ¤   // identified with a cluster offset of -1
f40415 ¤   ¤   ¤   //
0d2481 ¤   ¤   ¤   if( fileMappings->Pair[i].Lcn == LLINVALID )·
56f776 ¤   ¤   ¤   {
d3c01b ¤   ¤   ¤   ¤   // Ignore virtual runs since OS is supposed to fill slack
--3cab 00063f19a1940110278 Page 7 of WFnt.c
ae58f0 ¤   ¤   ¤   ¤   // with zeros
1fe5d3 ¤   ¤   ¤   }·
556b93 ¤   ¤   ¤   else·
f0f776 ¤   ¤   ¤   {
de851a ¤   ¤   ¤   ¤   // This gives us the last cluster Vcn (First+Length-1)
d7cfcf ¤   ¤   ¤   ¤   sm->Vcn=startVcn+(fileMappings->Pair[i].Vcn - startVcn )-1;
261b52 ¤   ¤
daa095 ¤   ¤   ¤   ¤   if(vi->dwFS==FS_NTFS)
1a72c3 ¤   ¤   ¤   ¤   {
aaa359 ¤   ¤   ¤   ¤   ¤   // We need to 16 cluster align it if NTFS
4f8bce ¤   ¤   ¤   ¤   ¤   sm->Vcn=(sm->Vcn/16)*16;
572613 ¤   ¤   ¤   ¤   }
beaf5a
fe86dc ¤   ¤   ¤   ¤   // This gives us the last cluster Lcn (Start Location + offset)
e09e59 ¤   ¤   ¤   ¤   sm->Orig=fileMappings->Pair[i].Lcn+(sm->Vcn-startVcn);
90a3a6 ¤   ¤   ¤   }
2c22aa ¤   ¤   ¤   startVcn = fileMappings->Pair[i].Vcn;
700fe4 ¤   ¤   }
d2af5a
bc65af ¤   ¤   //
7f6d54 ¤   ¤   // If the buffer wasn't overflowed, then we're done
e165af ¤   ¤   //
51ec5d ¤   ¤   if( !status ) break;
579371 ¤   }
f8af5a
3c3512 ¤   CloseHandle( sourceFile );
c6af5a
86d4e2 ¤   return StatusToError(status);
25efe6 }
58af5a
eab62d DWORD GetOrigForFileList(VOLINFO *vi)
7bbb36 {
adc937 ¤   DWORD count;
cb6b43 ¤   FILELIST *index;
77e87f ¤   DWORD RetVal;
c1af5a
dc800f ¤   index=vi->FileList;
c07e4b ¤   count=0;
967655 ¤   RetVal=WFE_NOERROR;
c9af5a
4754b2 ¤   while(index!=NULL)
2dc7a1 ¤   {
621876 ¤   ¤   if(!index->IsDirectory)
035b34 ¤   ¤   {
86710e ¤   ¤   ¤   RetVal=GetLastClusterOfFile(vi,
a23c08 ¤   ¤   ¤   ¤   index->name,
e27665 ¤   ¤   ¤   ¤   &(vi->SlackMove[count]));
fcaf5a
cb1ad8 ¤   ¤   ¤   // Probably somebody has a lock on the file. ignore
fb03f4 ¤   ¤   ¤   //if(RetVal!=WFE_NOERROR)
1172a6 ¤   ¤   ¤   //¤ return RetVal;
e8af5a
00ae59 ¤   ¤   ¤   count++;
950fe4 ¤   ¤   }
41dd53 ¤   ¤   index=index->next;
239371 ¤   }
f3af5a
ffe1ab ¤   if(((RetVal==WFE_ALREADYCOMMIT)||(RetVal==WFE_INVALPARAM))&&(vi->dwFS==FS_N¶
219ef8 TFS))
74c7a1 ¤   {
00b27e ¤   ¤   // Couldn't do the move because of MFT, or user is mucking
034827 ¤   ¤   // around.... just skip it and we'll get it on the next pass.
ae9e72 ¤   ¤   // Only applies to NTFS
a68030 ¤   ¤   RetVal=WFE_NOERROR;
4f9371 ¤   }
7aaf5a
0b42d7 ¤   return RetVal;
41efe6 }
42af5a
649807 DWORD CountFileList(FILELIST *index)
06bb36 {
63c937 ¤   DWORD count;
--a55a 00071eda28040110278 Page 8 of WFnt.c
e0af5a
c67e4b ¤   count=0;
90af5a
7754b2 ¤   while(index!=NULL)
96c7a1 ¤   {
e21876 ¤   ¤   if(!index->IsDirectory)
ebae59 ¤   ¤   ¤   count++;
e2dd53 ¤   ¤   index=index->next;
cf9371 ¤   }
06af5a
cb1368 ¤   return count;
6aefe6 }
28af5a
8c6583 DWORD DoSlackMovements(VOLINFO *vi)
8abb36 {
bf13b3 ¤   char fileName[MAX_PATH];
7cea9f ¤   DWORD i;
22e87f ¤   DWORD RetVal;
3fec67 ¤   DWORD BufferLoop;
e84e52 ¤   DWORD Start,End,ModAmt;
a3af5a
7b7655 ¤   RetVal=WFE_NOERROR;
ded548 ¤   sprintf(fileName, "%C:\\%s", vi->vol0+'A', "PGPwipepattern.tmp" );
f6af5a
b99dfd ¤   ModAmt=SLACKBUFFER;
c9af5a
5634b1 ¤   if(vi->SlackBufferIndex<SLACKBUFFER)
473d37 ¤   ¤   ModAmt=vi->SlackBufferIndex;
55af5a
7a1547 ¤   if(ModAmt==0)
1113dd ¤   ¤   return WFE_COULDNOTWRITE;
54af5a
7cf855 ¤   // Move Pattern out of the way
62333e ¤   // in case its in the last temp
65dbd4 ¤   RetVal=NTWipeCluster( vi,·
00c43a ¤   ¤   ¤   ¤   fileName,
70038c ¤   ¤   ¤   ¤   0,
387a1b ¤   ¤   ¤   ¤   vi->PatternBuffer);
09af5a
aa2346 ¤   // Reuse our temp buffer in ModAmt increments
cf6d73 ¤   for(BufferLoop=0;BufferLoop<(vi->SlackMoveCount+ModAmt-1)/ModAmt;BufferLoop¶
333eaa ++)
d4c7a1 ¤   {
58262b ¤   ¤   Start=ModAmt*BufferLoop;
6db7e7 ¤   ¤   End=Start+ModAmt;
e2af5a
b0c216 ¤   ¤   if(vi->SlackMoveCount<End)
6b4e8f ¤   ¤   ¤   End=vi->SlackMoveCount;
68af5a
186000 ¤   ¤   // Move end of files to temp
19344f ¤   ¤   for(i=Start;i<End;i++)
b25b34 ¤   ¤   {
c3d2fe ¤   ¤   ¤   // Don't do bogus files
b16684 ¤   ¤   ¤   if(vi->SlackMove[i].Orig==0)
86f776 ¤   ¤   ¤   {
54a3a6 ¤   ¤   ¤   }
84bb8c ¤   ¤   ¤   else
49f776 ¤   ¤   ¤   {
9d1814 ¤   ¤   ¤   ¤   RetVal=NTWipeCluster( vi,·
8a01f0 ¤   ¤   ¤   ¤   ¤   vi->SlackMove[i].name,
ca75b2 ¤   ¤   ¤   ¤   ¤   vi->SlackMove[i].Vcn,
903ac0 ¤   ¤   ¤   ¤   ¤   vi->SlackBuffer[i%ModAmt]);
d1a3a6 ¤   ¤   ¤   }
ad0fe4 ¤   ¤   }
4caf5a
c66dcd ¤   ¤   // Wipe former location
59344f ¤   ¤   for(i=Start;i<End;i++)
2a5b34 ¤   ¤   {
56d2fe ¤   ¤   ¤   // Don't do bogus files
d56684 ¤   ¤   ¤   if(vi->SlackMove[i].Orig==0)
31f776 ¤   ¤   ¤   {
71a3a6 ¤   ¤   ¤   }
--2b23 000bfe5d0ef40110278 Page 9 of WFnt.c
b1bb8c ¤   ¤   ¤   else
89f776 ¤   ¤   ¤   {
651814 ¤   ¤   ¤   ¤   RetVal=NTWipeCluster( vi,·
1c4d6e ¤   ¤   ¤   ¤   ¤   fileName,
dc3865 ¤   ¤   ¤   ¤   ¤   0,
2368ee ¤   ¤   ¤   ¤   ¤   vi->SlackMove[i].Orig);
57a3a6 ¤   ¤   ¤   }
930fe4 ¤   ¤   }
22af5a
62b9a6 ¤   ¤   // Move Pattern out of the way
afe534 ¤   ¤   // since its in the last orig
bd57ab ¤   ¤   RetVal=NTWipeCluster( vi,·
334d6e ¤   ¤   ¤   ¤   ¤   fileName,
ac3865 ¤   ¤   ¤   ¤   ¤   0,
e2bf4e ¤   ¤   ¤   ¤   ¤   vi->PatternBuffer);
b4af5a
c536ec ¤   ¤   // Move back. Not necessary, but prevents fragmentation
ca344f ¤   ¤   for(i=Start;i<End;i++)
cb5b34 ¤   ¤   {
48d2fe ¤   ¤   ¤   // Don't do bogus files
866684 ¤   ¤   ¤   if(vi->SlackMove[i].Orig==0)
53f776 ¤   ¤   ¤   {
e3a3a6 ¤   ¤   ¤   }
d7bb8c ¤   ¤   ¤   else
fff776 ¤   ¤   ¤   {
681814 ¤   ¤   ¤   ¤   RetVal=NTWipeCluster( vi,·
3201f0 ¤   ¤   ¤   ¤   ¤   vi->SlackMove[i].name,
0975b2 ¤   ¤   ¤   ¤   ¤   vi->SlackMove[i].Vcn,
bc68ee ¤   ¤   ¤   ¤   ¤   vi->SlackMove[i].Orig);
baa3a6 ¤   ¤   ¤   }
350fe4 ¤   ¤   }
a79371 ¤   }
aaaf5a
ebd5fc ¤   // Not necessary, but wipe temp spots too
4d3fd8 ¤   for(i=0;i<ModAmt;i++)
99c7a1 ¤   {
9557ab ¤   ¤   RetVal=NTWipeCluster( vi,·
19038f ¤   ¤   ¤   fileName,
eee12f ¤   ¤   ¤   0,
037cdd ¤   ¤   ¤   vi->SlackBuffer[i]);
9b9371 ¤   }
18af5a
64e1ab ¤   if(((RetVal==WFE_ALREADYCOMMIT)||(RetVal==WFE_INVALPARAM))&&(vi->dwFS==FS_N¶
729ef8 TFS))
65c7a1 ¤   {
f4b27e ¤   ¤   // Couldn't do the move because of MFT, or user is mucking
5c4827 ¤   ¤   // around.... just skip it and we'll get it on the next pass.
0d9e72 ¤   ¤   // Only applies to NTFS
6e8030 ¤   ¤   RetVal=WFE_NOERROR;
b79371 ¤   }
22af5a
8642d7 ¤   return RetVal;
d2efe6 }
fcaf5a
4eab94 DWORD NTDoWipe(VOLINFO *vi)
9cbb36 {
c224b2 ¤   DWORD status,RetVal;
7120b4 ¤   char drivestr[50];
a3e3e8 ¤   DWORD memamt;
2c6672 ¤   char StrRes[500];
8aaf5a
ef7655 ¤   RetVal=WFE_NOERROR;
20af5a
3e0a6d ¤   LoadString (g_hinst, IDS_SCANNINGDISK, StrRes, sizeof(StrRes));
61a223 ¤   StatusMessage(StrRes, FALSE);
20af5a
f75933 ¤   sprintf(drivestr,"%c:\\",vi->vol0+'A');
30af5a
471fc8 ¤   // Get the NtFsControlFile entry point since undocumented
29aa38 ¤   if( !(NtFsControlFile = (void *) GetProcAddress( GetModuleHandle("ntdll.dll¶
670cc9 "),
bf12a6 ¤   ¤   ¤   "NtFsControlFile" )) )
--773c 000e916d69e40110278 Page 10 of WFnt.c
f7c7a1 ¤   {
63695a ¤   ¤   return WFE_FSNOTSUPPORTED;
189371 ¤   }
54af5a
5a68b7 ¤   vi->FileList=NULL;
aaaf5a
86b047 ¤   // Enumerate the files on the drive
0a0429 ¤   RetVal=AddToFileList(&(vi->FileList),drivestr,&bGlobalCancel);·
19af5a
30c82e ¤   if(!RetVal)
efc7a1 ¤   {
cecd50 ¤   ¤   FreeFileList(vi->FileList);
2a91af ¤   ¤   return WFE_USERCANCEL;
239371 ¤   }
5e67c5 ¤
391848 ¤   // Find the number of files
6a7f29 ¤   vi->SlackMoveCount=CountFileList(vi->FileList);·
49af5a
be4bcb ¤   // Allocate a slack movement array
8f4f91 ¤   memamt=vi->SlackMoveCount*sizeof(SLACKMOVE);·
5410bb ¤   vi->SlackMove=(SLACKMOVE *)malloc(memamt);
28d45c ¤   memset(vi->SlackMove,0x00,memamt);
89af5a
d1d007 ¤   // Open the volume
5f5a37 ¤   status = OpenVolume(vi);
af67c5 ¤
1626ae ¤   if( status != ERROR_SUCCESS )·
59c7a1 ¤   {
653b91 ¤   ¤   return StatusToError(status);
f89371 ¤   }
edaf5a
720b23 ¤   // Get the last cluster for each file (Orig)
8e45e5 ¤   RetVal=GetOrigForFileList(vi);
6eaf5a
cc85b5 ¤   if(RetVal==WFE_NOERROR)
d2c7a1 ¤   {
f26bdf ¤   ¤   // Now, wipe the free clusters, grabbing Temp along the way
b0fdf4 ¤   ¤   RetVal=NTWipeFreeClusters(vi);
6baf5a
8b28eb ¤   ¤   if(RetVal==WFE_NOERROR)
cb5b34 ¤   ¤   {
6b6630 ¤   ¤   ¤   // With this information, wipe the slack space
badd6a ¤   ¤   ¤   RetVal=DoSlackMovements(vi);
c90fe4 ¤   ¤   }
32af5a
a29371 ¤   }
01af5a
905f2d ¤   // Done with File List... Free it
9d46ac ¤   FreeFileList(vi->FileList);
45af5a
4c8c59 ¤   // Done with slack space info.. Free it
5c6bd6 ¤   if(vi->SlackMove)
f74849 ¤   ¤   free(vi->SlackMove);
3daf5a
1bee9a ¤   CloseHandle(vi->VolHandle);
5aaf5a
4b42d7 ¤   return RetVal;
81efe6 }
14af5a
5ac7ef void NTGetDriveInfo(VOLINFO *vi)
a6bb36 {
6d5918 ¤   int rst;
302753 ¤   DWORD NumFreeClusters;
88bedf ¤   DWORD SectorsPerCluster;
031b67 ¤   DWORD BytesPerSector;
e8e5c6 ¤   DWORD NumClusters;
2520b4 ¤   char drivestr[50];
3aaf5a
315933 ¤   sprintf(drivestr,"%c:\\",vi->vol0+'A');
ecaf5a
0fcde4 ¤   rst=GetDiskFreeSpace(drivestr,
e921bb ¤   ¤   &SectorsPerCluster,
--6106 0005d00b1a640110278 Page 11 of WFnt.c
5b460b ¤   ¤   &BytesPerSector,
ac5f6d ¤   ¤   &NumFreeClusters,
1f9d00 ¤   ¤   &NumClusters);
6faf5a
26824d ¤   vi->no_of_clusters=NumClusters;
81429e ¤   vi->sectors_per_clus=(USHORT)SectorsPerCluster;
b75904 ¤   vi->sector_size=(USHORT)BytesPerSector;
83af5a
77e003 ¤   vi->fTotalCapacity=(FLOAT)
87f84e ¤   ¤   vi->no_of_clusters*vi->sectors_per_clus*vi->sector_size;
d5af5a
80dc4a ¤   if(vi->dwFS==FS_FAT)
58c7a1 ¤   {
0748f6 ¤   ¤   // Microsoft says 4086 here
f3857b ¤   ¤   // FIPs says 4079. 4079 makes more sense,
b8b663 ¤   ¤   // but probably won't matter either way
b5bd5a ¤   ¤   if(vi->no_of_clusters <= 4079)
212280 ¤   ¤   ¤   vi->dwFS=FS_FAT12;
580e1d ¤   ¤   else
0641e1 ¤   ¤   ¤   vi->dwFS=FS_FAT16;
f69371 ¤   }
c2efe6 }
19af5a
02c09e DWORD NTWipeFree(HWND hwnd,VOLINFO *vi,char *szRoot,
8ddf5d ¤   ¤   ¤   ···DWORD* pattern, BOOL StartWipe)
aabb36 {
91e87f ¤   DWORD RetVal;
2658b2 ¤   char filename[MAX_PATH];
69480c ¤   char *PatternBuf;
3cce53 ¤   int memamt;
2ec426 ¤   FILE *fin;
2daf5a
1eaff9 ¤   // For clusters greater than 4K, defrag API is not supported
6a96a4 ¤   // because of msoft compression goof
2e430a ¤   if((vi->WinNT)&&(vi->dwFS==FS_NTFS)&&(vi->sectors_per_clus*vi->sector_size>¶
f73865 4096))
aa001c ¤   ¤   return WFE_NTFSGREATER4K;
f5af5a
e88843 ¤   // Zero-based volume, 'A'=0, 'B'=1, 'C'=2, etc.
c7d272 ¤   vi->vol0=toupper(szRoot[0])-'A';
87af5a
bb3de4 ¤   NTGetDriveInfo(vi);
3aaf5a
23720b ¤   DisplayDiskStats(vi);
44af5a
eed986 ¤   // Do wipe if so. Otherwise report stats.
76f574 ¤   if(StartWipe)
90c7a1 ¤   {
485b11 ¤   ¤   memamt=vi->sectors_per_clus*vi->sector_size;
7278ee ¤   ¤   if(vi->dwFS==FS_NTFS)
576060 ¤   ¤   ¤   memamt=memamt*16; // NTFS works with 16 cluster segments
1aaf5a
7e3d30 ¤   ¤   PatternBuf=(char *)malloc(memamt);
9aaf5a
e7f88a ¤   ¤   if(PatternBuf==0)
f35b34 ¤   ¤   {
be5d5b ¤   ¤   ¤   RetVal=WFE_OUTOFMEMORY;
500fe4 ¤   ¤   }
a10e1d ¤   ¤   else
5e5b34 ¤   ¤   {
f0c0b6 ¤   ¤   //¤ memset(PatternBuf,'o',memamt); // For testing
39af5a
65e5e1 ¤   ¤   ¤   WritePattern(PatternBuf,vi->pattern_buffer,memamt);
88af5a
e0f5f5 ¤   ¤   ¤   // Create our pattern file
d3d538 ¤   ¤   ¤   sprintf(filename,"%c:\\",vi->vol0+'A');
f69c90 ¤   ¤   ¤   strcat(filename,"PGPwipepattern.tmp");
33af5a
f76759 ¤   ¤   ¤   fin=fopen(filename,"wb");
03af5a
c8c4b3 ¤   ¤   ¤   if(fin==0)
5df776 ¤   ¤   ¤   {
--89f4 0012f3663e840110278 Page 12 of WFnt.c
7934a0 ¤   ¤   ¤   ¤   RetVal=WFE_COULDNOTWRITE;
49a3a6 ¤   ¤   ¤   }
afbb8c ¤   ¤   ¤   else
36f776 ¤   ¤   ¤   {
8776e6 ¤   ¤   ¤   ¤   fwrite(PatternBuf,1,memamt,fin);
c6275c ¤   ¤   ¤   ¤   fclose(fin);
65af5a
27efaf ¤   ¤   ¤   ¤   free(PatternBuf);
29af5a
8b763f ¤   ¤   ¤   ¤   vi->bCountClusters=TRUE;
2aaf5a
65cde2 ¤   ¤   ¤   ¤   RetVal=NTDoWipe(vi);
bcaf5a
ad6642 ¤   ¤   ¤   ¤   if(RetVal==WFE_NOERROR)
1772c3 ¤   ¤   ¤   ¤   {
4cc184 ¤   ¤   ¤   ¤   ¤   vi->bCountClusters=FALSE;
3bc80f ¤   ¤   ¤   ¤   ¤   RetVal=NTDoWipe(vi);
4e2613 ¤   ¤   ¤   ¤   }
7aaf5a
18b112 ¤   ¤   ¤   ¤   _unlink (filename);
d2a3a6 ¤   ¤   ¤   }
3f0fe4 ¤   ¤   }
8d9371 ¤   }
fa42d7 ¤   return RetVal;
8eefe6 }
bbaf5a
ee7e4d /*__Editor_settings____
71af5a
c54126 ¤   Local Variables:
8e7b17 ¤   tab-width: 4
880e6c ¤   End:
315f8c ¤   vi: ts=4 sw=4
999e9b ¤   vim: si
2fd062 _____________________*/
--8b04 0009424024040110279 Page 1 of WFnt.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e2ec64 ¤   $Id: WFnt.h,v 1.2.8.1 1998/11/12 03:13:32 heller Exp $
9bf7f7 ____________________________________________________________________________*/
ecaf5a
73b476 BOOL UserPressedCancel(VOLINFO *vi);
20ffed BOOL GetFileSystem(VOLINFO *vi,char *szRoot);
21c09e DWORD NTWipeFree(HWND hwnd,VOLINFO *vi,char *szRoot,
bb899f ¤   ¤   ¤   ···DWORD* pattern, BOOL StartWipe);
d34530 void WritePattern(void* buf, DWORD* pattern, long size);
28af5a
98465d //
784ca9 // File System Control commands related to defragging
fe465d //
a24161 #define¤FSCTL_READ_MFT_RECORD¤  ¤   ¤   0x90068
c003fd #define FSCTL_GET_VOLUME_BITMAP¤¤   ¤   0x9006F
94504c #define FSCTL_GET_RETRIEVAL_POINTERS¤   0x90073
ae34d7 #define FSCTL_MOVE_FILE¤¤   ¤   ¤   ¤   0x90074
73af5a
b8465d //
6f93ac // return code type
88465d //
186b50 typedef UINT NTSTATUS;
60af5a
d7465d //
7fa190 // Error codes returned by NtFsControlFile (see NTSTATUS.H)
e0465d //
0a24a1 #define STATUS_SUCCESS¤ ¤   ¤   ·········((NTSTATUS)0x00000000L)
d05b8b #define STATUS_BUFFER_OVERFLOW ··········((NTSTATUS)0x80000005L)
7a2441 #define STATUS_INVALID_PARAMETER ········((NTSTATUS)0xC000000DL)
29d991 #define STATUS_BUFFER_TOO_SMALL ·········((NTSTATUS)0xC0000023L)
eaaf9b #define STATUS_ALREADY_COMMITTED ········((NTSTATUS)0xC0000021L)
555c20 #define STATUS_INVALID_DEVICE_REQUEST ···((NTSTATUS)0xC0000010L)
84af5a
3cbc23 #define STATUS_DEVICELOCKED ·············((NTSTATUS)0x00000020L)
5caf5a
26465d //
636c63 // This is the definition for a VCN/LCN (virtual cluster/logical cluster)
e694eb // mapping pair that is returned in the buffer passed to·
e44f09 // FSCTL_GET_RETRIEVAL_POINTERS
f4465d //
a1f0f7 typedef struct {
20456c ¤   ULONGLONG¤  ¤   ¤   Vcn;
d7bd84 ¤   ULONGLONG¤  ¤   ¤   Lcn;
fca5fe } MAPPING_PAIR, *PMAPPING_PAIR;
c5af5a
fc465d //
cde4a5 // This is the definition for the buffer that FSCTL_GET_RETRIEVAL_POINTERS
9ea40d // returns. It consists of a header followed by mapping pairs
e1465d //
e5f0f7 typedef struct {
357af1 ¤   ULONG¤  ¤   ¤   ¤   NumberOfPairs;
7ef555 ¤   ULONGLONG¤  ¤   ¤   StartVcn;
914b9f ¤   MAPPING_PAIR¤   ¤   Pair[1];
209d5a } GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR;
15af5a
d4af5a
d9465d //
afe480 // This is the definition of the buffer that FSCTL_GET_VOLUME_BITMAP
42fbf4 // returns. It consists of a header followed by the actual bitmap data
4e465d //
03f0f7 typedef struct {
200dbd ¤   ULONGLONG¤  ¤   ¤   StartLcn;
5c9144 ¤   ULONGLONG¤  ¤   ¤   ClustersToEndOfVol;
6f92e0 ¤   BYTE¤   ¤   ¤   ¤   Map[1];
e60c16 } BITMAP_DESCRIPTOR, *PBITMAP_DESCRIPTOR;·
40af5a
94af5a
--6a6f 0018ef6c3aa40110279 Page 2 of WFnt.h
c1465d //
d67f39 // This is the definition for the data structure that is passed in to
f793c4 // FSCTL_MOVE_FILE
b5465d //
4ef0f7 typedef struct {
c7cb29 ·····HANDLE ···········FileHandle;·
280976 ·····ULONG ············Reserved; ··
117414 ·····LARGE_INTEGER ····StartVcn;·
e8c66b ·····LARGE_INTEGER ····TargetLcn;
7c859e ·····ULONG ············NumVcns;·
b29f99 ·····ULONG ············Reserved1;¤
b903fd } MOVEFILE_DESCRIPTOR, *PMOVEFILE_DESCRIPTOR;
a7af5a
49465d //
f21ab1 // Prototype for NtFsControlFile and data structures
bd840a // used in its definition
ff465d //
0eaf5a
06465d //
01f342 // Io Status block (see NTDDK.H)
79465d //
e7c9f8 typedef struct _IO_STATUS_BLOCK {
cdd4c0 ····NTSTATUS Status;
392e5e ····ULONG Information;
25cd3c } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
1eaf5a
d2af5a
dd465d //
8652d7 // Apc Routine (see NTDDK.H)
15465d //
f1701a typedef VOID (*PIO_APC_ROUTINE) (
219121 ¤   ¤   ¤   ¤   PVOID ApcContext,
80cd57 ¤   ¤   ¤   ¤   PIO_STATUS_BLOCK IoStatusBlock,
278bdc ¤   ¤   ¤   ¤   ULONG Reserved
b1203d ¤   ¤   ¤   );
4daf5a
51af5a
cb465d //
48c9c1 // The undocumented NtFsControlFile
3a465d //
932086 // This function is used to send File System Control (FSCTL)
00ccac // commands into file system drivers. Its definition is·
27c967 // in ntdll.dll (ntdll.lib), a file shipped with the NTDDK.
f3465d //
446dc5 NTSTATUS (__stdcall *NtFsControlFile)(·
631b42 ¤   ¤   ¤   ¤   ¤   HANDLE FileHandle,
df2d4b ¤   ¤   ¤   ¤   ¤   HANDLE Event,¤  ¤   ¤   ¤   ¤   // optional
068512 ¤   ¤   ¤   ¤   ¤   PIO_APC_ROUTINE ApcRoutine,¤¤   // optional
6ee520 ¤   ¤   ¤   ¤   ¤   PVOID ApcContext,¤  ¤   ¤   ¤   // optional
13ef59 ¤   ¤   ¤   ¤   ¤   PIO_STATUS_BLOCK IoStatusBlock,¤
d0b8d7 ¤   ¤   ¤   ¤   ¤   ULONG FsControlCode,
13f26a ¤   ¤   ¤   ¤   ¤   PVOID InputBuffer,¤ ¤   ¤   ¤   // optional
a5d5a9 ¤   ¤   ¤   ¤   ¤   ULONG InputBufferLength,
5f55e8 ¤   ¤   ¤   ¤   ¤   PVOID OutputBuffer,¤¤   ¤   ¤   // optional
211e8d ¤   ¤   ¤   ¤   ¤   ULONG OutputBufferLength
e5203d ¤   ¤   ¤   );
1baf5a
80af5a
977e4d /*__Editor_settings____
e8af5a
754126 ¤   Local Variables:
7c7b17 ¤   tab-width: 4
630e6c ¤   End:
d55f8c ¤   vi: ts=4 sw=4
219e9b ¤   vim: si
8ed062 _____________________*/
--a3bf 0000ac4d2f44011027a Page 1 of WFwiz.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
51b1d7 ¤   $Id: WFwiz.c,v 1.27.8.1 1998/11/12 03:13:32 heller Exp $
53f7f7 ____________________________________________________________________________*/
ae5ed8 #include "precomp.h"
9faf5a
aedcb3 BOOL CALLBACK IntroDlgProc(HWND,UINT,WPARAM,LPARAM);
4f9764 BOOL CALLBACK InfoDlgProc(HWND,UINT,WPARAM,LPARAM);
439673 BOOL CALLBACK StatusDlgProc(HWND,UINT,WPARAM,LPARAM);
36c98b BOOL CALLBACK FinishDlgProc(HWND,UINT,WPARAM,LPARAM);
8a6e0e void WipeThread(void* pvoid);
2caf5a
8a75da BOOL g_bWiping¤ ¤   ¤   = FALSE;
09841f HWND g_status¤  ¤   ¤   = NULL;
0bc352 HWND g_wipe_progress¤   = NULL;
6bacfc HWND g_pass_progress¤   = NULL;
808f80 HWND g_pass_status¤ ¤   = NULL;
26a3dd HFONT g_boldfont, g_defaultfont;
e9af5a
b0597e static HPALETTE·
45cef8 CreateDIBPalette (LPBITMAPINFO lpbmi,·
d65586 ¤   ¤   ¤   ¤   ··LPINT lpiNumColors);
65af5a
97fb93 static HBITMAP·
4ad9f1 LoadResourceBitmap (HINSTANCE hInstance,·
48d7f9 ¤   ¤   ¤   ¤   ¤   LPSTR lpString,
93a4a9 ¤   ¤   ¤   ¤   ¤   HPALETTE FAR* lppalette);
56af5a
03956d void FreeSpaceWipeWizard(HWND hwnd, void* PGPsc)
fdbb36 {
e80503 ¤   PROPSHEETPAGE¤  psp[NUM_PAGES];
102971 ¤   PROPSHEETHEADER psh;
9942a8 ¤   int¤¤   ¤   ¤   index;
16897e ¤   wizard_data¤¤   data;
ff9be1 ¤   LOGFONT¤¤   ¤   lf;
fb1765 ¤   PGPError¤   ¤   error;
e5ae9e ¤   PGPPrefRef¤ ¤   prefRef;
dd72aa ¤   PGPMemoryMgrRef memoryMgr;
1b51a8 ¤   PGPUInt32¤  ¤   passes = 1;
7ead38 ¤   HDC¤¤   ¤   ¤   hdc = NULL;
612dc6 ¤   int¤¤   ¤   ¤   bits, bmp;
ca8a97 ¤   PGPContextRef¤  context;
bdaf5a
b3625b ¤   context=(PGPContextRef)PGPsc;
d8af5a
5acc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
ccaf5a
07b399 ¤   error = PGPclOpenClientPrefs(¤  memoryMgr,
547b4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefRef );
7faf5a
2d5114 ¤   if(IsntPGPError(error) )
c6c7a1 ¤   {
28dcb1 ¤   ¤   PGPGetPrefNumber (¤ prefRef,
ada1d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefDiskWipePasses,·
854873 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUInt32*)&passes);
16af5a
cb06ad ¤   ¤   PGPclCloseClientPrefs (prefRef, FALSE);
1eaf5a
4a9371 ¤   }
c2af5a
e78114 ¤   // initialize the wizard data
8337bb ¤   memset(&data, 0x00, sizeof(data));
d8f3fc ¤   data.cookie = 0;
c7563e ¤   data.passes = passes;
9288e8 ¤   data.hinst = g_hinst;
c323a5 ¤   data.context = context;
6eaf5a
0ac81b ¤   // Determine which bitmap will be displayed in the wizard
--5c78 000e704cbdc4011027a Page 2 of WFwiz.c
e0af5a
60f3cc ¤   hdc = GetDC (NULL);¤¤   // DC for desktop
4f0f3b ¤   bits = GetDeviceCaps (hdc, BITSPIXEL) * GetDeviceCaps (hdc, PLANES);
740951 ¤   ReleaseDC (NULL, hdc);
1baf5a
498b6c ¤   if (bits <= 1)
76a642 ¤   ¤   bmp = IDB_WIPEWIZ1;
86d9e5 ¤   else if (bits <= 8)·
e19fff ¤   ¤   bmp = IDB_WIPEWIZ4;
773619 //¤ else if (bits <= 8) ····// No pallette cycling -wjb
069710 //¤ ¤   bmp = IDB_WIPEWIZ8;
9a4264 ¤   else·
d5e9f2 ¤   ¤   bmp = IDB_WIPEWIZ8; // save some space <grin>
9b02de ¤   ¤   //bmp = IDB_WIPEWIZ24;·
f6af5a
4178cf ¤   data.bmp = LoadResourceBitmap(g_hinst, MAKEINTRESOURCE(bmp),
40197b ¤   ¤   ¤   ¤   ¤   ¤   &(data.palette));
faaf5a
1baf5a
a6158b ¤   // Set the PROPSHEETPAGE values common to all pages
2faf5a
1f0df2 ¤   for (index=0; index < NUM_PAGES; index++)
5dc7a1 ¤   {
3ed5ae ¤   ¤   psp[index].dwSize¤  ¤   = sizeof(PROPSHEETPAGE);
633cc1 ¤   ¤   psp[index].dwFlags¤ ¤   = PSP_DEFAULT;
5adab5 ¤   ¤   psp[index].hInstance¤   = g_hinst;
1b2672 ¤   ¤   psp[index].pszTemplate¤ = NULL;
787590 ¤   ¤   psp[index].hIcon¤   ¤   = NULL;
405df5 ¤   ¤   psp[index].pszTitle¤¤   = NULL;
34c7d3 ¤   ¤   psp[index].pfnDlgProc¤  = NULL;
fa530f ¤   ¤   psp[index].lParam¤  ¤   = (LPARAM) &data;
7e0675 ¤   ¤   psp[index].pfnCallback¤ = NULL;
2ecc60 ¤   ¤   psp[index].pcRefParent¤ = NULL;
e49371 ¤   }
2eaf5a
86c8da ¤   // Set up the intro page
c08da4 ¤   psp[intro].pszTemplate¤ = MAKEINTRESOURCE(IDD_INTRO);
9d06d2 ¤   psp[intro].pfnDlgProc¤  = (DLGPROC) IntroDlgProc;
59af5a
1e860d ¤   // Set up the info page
dc2e02 ¤   psp[info].pszTemplate¤  = MAKEINTRESOURCE(IDD_INFO);
167b25 ¤   psp[info].pfnDlgProc¤   = (DLGPROC) InfoDlgProc;
e3af5a
440721 ¤   // Set up the status page
4886f5 ¤   psp[status].pszTemplate¤= MAKEINTRESOURCE(IDD_STATUS);
e3627e ¤   psp[status].pfnDlgProc¤ = (DLGPROC) StatusDlgProc;
5baf5a
c2d591 ¤   // Set up the finish page
68e2e5 ¤   psp[finish].pszTemplate¤= MAKEINTRESOURCE(IDD_FINISH);
45b0e2 ¤   psp[finish].pfnDlgProc¤ = (DLGPROC) FinishDlgProc;
39af5a
292604 ¤   // Fill out the header
d6cf83 ¤   psh.dwSize¤ ¤   = sizeof(PROPSHEETHEADER);
573423 ¤   psh.dwFlags¤¤   = PSH_WIZARD | PSH_PROPSHEETPAGE;
acb51f ¤   psh.hwndParent¤ = hwnd;
994577 ¤   psh.hInstance¤  = g_hinst;
c4775a ¤   psh.hIcon¤  ¤   = NULL;
d6139c ¤   psh.pszCaption¤ = NULL;
1a5549 ¤   psh.nPages¤ ¤   = NUM_PAGES;
272e58 ¤   psh.nStartPage¤ = intro;
8abb10 ¤   psh.ppsp¤   ¤   = psp;
e872d2 ¤   psh.pfnCallback¤= NULL;
07af5a
c6393e ¤   // set some convenient globals
e6a814 ¤   g_defaultfont = GetStockObject(DEFAULT_GUI_FONT);
98af5a
09c95c ¤   GetObject(g_defaultfont, sizeof(LOGFONT), &lf);
08af5a
61ddc1 ¤   lf.lfWeight = FW_BOLD;
7daf5a
bcff85 ¤   g_boldfont = CreateFontIndirect(&lf);
e7af5a
--b998 0002c4593ae4011027a Page 3 of WFwiz.c
8cc6b6 ¤   // Execute the Wizard - doesn't return until Cancel or Finish
59c877 ¤   PropertySheet(&psh);
6eaf5a
6a19d0 ¤   DeleteObject(g_boldfont);
6faf5a
94efe6 }
57af5a
7a1c21 BOOL CALLBACK IntroDlgProc(¤HWND hwnd,·
6a5c16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
d1cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
404868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
21bb36 {
c6d102 ¤   BOOL bReturnValue = FALSE;
820b3d ¤   static wizard_data* data = NULL;
27af5a
ce9467 ¤   switch(msg)
c6c7a1 ¤   {
5ddf25 ¤   ¤   case WM_INITDIALOG:
e65b34 ¤   ¤   {
742530 ¤   ¤   ¤   PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lParam;
9bae20 ¤   ¤   ¤   HWND welcome = GetDlgItem(hwnd, IDC_WELCOME);
c72445 ¤   ¤   ¤   HWND hwndParent = GetParent(hwnd);
e8793a ¤   ¤   ¤   int x,y;
aaf192 ¤   ¤   ¤   RECT rect;
36af5a
7c48b0 ¤   ¤   ¤   data = (wizard_data*) psp->lParam;
25af5a
47b7f3 ¤   ¤   ¤   SendMessage(welcome,·
fa39f2 ¤   ¤   ¤   ¤   ¤   ¤   WM_SETFONT,·
41cbab ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)g_boldfont,
42bd7f ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
eeaf5a
df3576 ¤   ¤   ¤   // center the wizard on the screen
bb7082 ¤   ¤   ¤   GetClientRect(hwndParent, &rect);
19af5a
a1ffaa ¤   ¤   ¤   x = (GetSystemMetrics (SM_CXFULLSCREEN) - rect.right) / 2;
d7dd27 ¤   ¤   ¤   y = (GetSystemMetrics (SM_CYFULLSCREEN) - rect.bottom) / 2;
59af5a
5aab77 ¤   ¤   ¤   SetWindowPos (¤ hwndParent,·
54c0c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   HWND_TOP,·
3cb98b ¤   ¤   ¤   ¤   ¤   ¤   ¤   x,·
5da530 ¤   ¤   ¤   ¤   ¤   ¤   ¤   y,·
aaceac ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
73ceac ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
f6a00f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE);
74af5a
582cd7 ¤   ¤   ¤   bReturnValue = TRUE;
5dcdcb ¤   ¤   ¤   break;
200fe4 ¤   ¤   }
b2af5a
c5dad9 ¤   ¤   case WM_DESTROY:
435b34 ¤   ¤   {
e2cdcb ¤   ¤   ¤   break;
2f0fe4 ¤   ¤   }
d9af5a
b7a810 ¤   ¤   case WM_PAINT:
935b34 ¤   ¤   {
3e29a7 ¤   ¤   ¤   if (data->palette)
6ef776 ¤   ¤   ¤   {
58596f ¤   ¤   ¤   ¤   PAINTSTRUCT ps;
47cf84 ¤   ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwnd, &ps);
d3b00a ¤   ¤   ¤   ¤   SelectPalette (hDC, data->palette, FALSE);
3f708d ¤   ¤   ¤   ¤   RealizePalette (hDC);
39519e ¤   ¤   ¤   ¤   EndPaint (hwnd, &ps);
b611bf ¤   ¤   ¤   ¤   bReturnValue = TRUE;
daa3a6 ¤   ¤   ¤   }
25af5a
bfcdcb ¤   ¤   ¤   break;
e70fe4 ¤   ¤   }
b7af5a
ebb3c8 ¤   ¤   case WM_NOTIFY:
2c5b34 ¤   ¤   {
--9a9c 000fc9fed2e4011027a Page 4 of WFwiz.c
cca08b ¤   ¤   ¤   LPNMHDR pnmh;
d3af5a
cd2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
e8af5a
67b7b0 ¤   ¤   ¤   switch(pnmh->code)
62f776 ¤   ¤   ¤   {
b3ed40 ¤   ¤   ¤   ¤   case PSN_SETACTIVE:
3272c3 ¤   ¤   ¤   ¤   {
597182 ¤   ¤   ¤   ¤   ¤   // Initialize window
d4a5eb ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwnd),·
0b6a65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS,·
d2c118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
ed971e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_NEXT);
e9af5a
dbc131 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(¤hwnd,·
af35b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_WIZBITMAP,·
eddc51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STM_SETIMAGE,·
89b3c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP,·
249f2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) data->bmp);
a5af5a
961452 ¤   ¤   ¤   ¤   ¤   bReturnValue = TRUE;
4914c3 ¤   ¤   ¤   ¤   ¤   break;
f62613 ¤   ¤   ¤   ¤   }
05a3a6 ¤   ¤   ¤   }
5887c7 ¤   ¤   ¤
facdcb ¤   ¤   ¤   break;
740fe4 ¤   ¤   }
4eaf5a
8a9371 ¤   }
9c5f5f ¤   return bReturnValue;
82efe6 }
2faf5a
94af5a
7a64c4 BOOL CALLBACK InfoDlgProc(¤ HWND hwnd,·
d35c16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
18cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
b34868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
4fbb36 {
cad102 ¤   BOOL bReturnValue = FALSE;
ac0b3d ¤   static wizard_data* data = NULL;
cda24a ¤   static HWND drivelist = NULL;
bf8572 ¤   static HWND numpasses = NULL;
0faf5a
309467 ¤   switch(msg)
93c7a1 ¤   {
b5df25 ¤   ¤   case WM_INITDIALOG:
b75b34 ¤   ¤   {
b42530 ¤   ¤   ¤   PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lParam;
d8c42d ¤   ¤   ¤   char buf[512] = {0x00};
a5062e ¤   ¤   ¤   int len;
20a72b ¤   ¤   ¤   char *drive;
6bddf3 ¤   ¤   ¤   HWND spin = GetDlgItem(hwnd, IDC_SPIN1);
e5af5a
5c24de ¤   ¤   ¤   SendMessage(spin,·
ba942d ¤   ¤   ¤   ¤   ¤   ¤   UDM_SETRANGE,·
92e7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
964f35 ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(32, 1)); ·
3caf5a
81b3fd ¤   ¤   ¤   drivelist = GetDlgItem(hwnd, IDC_DRIVECOMBO);
747c3e ¤   ¤   ¤   numpasses = GetDlgItem(hwnd, IDC_NUMPASSES);
65af5a
8d48b0 ¤   ¤   ¤   data = (wizard_data*) psp->lParam;
83af5a
d47a4e ¤   ¤   ¤   SetWindowLong(hwnd, GWL_USERDATA, (LPARAM) data);
e7af5a
ee53f5 ¤   ¤   ¤   len = GetLogicalDriveStrings(sizeof(buf), buf);
efaf5a
72eafd ¤   ¤   ¤   drive = buf;
dcaf5a
ad0412 ¤   ¤   ¤   while(*drive)
64f776 ¤   ¤   ¤   {
fc6594 ¤   ¤   ¤   ¤   *drive=(char)toupper((int)*drive);
--9330 000c2b97a644011027a Page 5 of WFwiz.c
e0af5a
ab63e4 ¤   ¤   ¤   ¤   SendMessage(drivelist,
62b1e6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_ADDSTRING,
99ceac ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
6839bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)drive);
62af5a
7e5e07 ¤   ¤   ¤   ¤   drive += strlen(drive) + 1;
72a3a6 ¤   ¤   ¤   }
12af5a
882217 ¤   ¤   ¤   SendMessage(drivelist,
0b512a ¤   ¤   ¤   ¤   ¤   ¤   CB_SETCURSEL,
37da84 ¤   ¤   ¤   ¤   ¤   ¤   0,
d8fb6b ¤   ¤   ¤   ¤   ¤   ¤   0);
f3af5a
783fa7 ¤   ¤   ¤   SendMessage(numpasses,
39ab7f ¤   ¤   ¤   ¤   ¤   ¤   EM_SETLIMITTEXT,
2e6f3c ¤   ¤   ¤   ¤   ¤   ¤   2,
d2fb6b ¤   ¤   ¤   ¤   ¤   ¤   0);
15af5a
63ea3e ¤   ¤   ¤   wsprintf(buf, "%d", data->passes);
abaf5a
88b18d ¤   ¤   ¤   SetWindowText(numpasses, buf);
f7947c ¤   ¤   ¤   ·
292cd7 ¤   ¤   ¤   bReturnValue = TRUE;
abcdcb ¤   ¤   ¤   break;
960fe4 ¤   ¤   }
e3af5a
078e1e ¤   ¤   case WM_COMMAND:
ee5b34 ¤   ¤   {
c68692 ¤   ¤   ¤   switch LOWORD(wParam)
1df776 ¤   ¤   ¤   {
7b4436 ¤   ¤   ¤   ¤   case IDC_STATIC_1:
92ab52 ¤   ¤   ¤   ¤   case IDC_STATIC_2:
88f18e ¤   ¤   ¤   ¤   case IDC_STATIC_3:
997d8b ¤   ¤   ¤   ¤   case IDC_STATIC_4:
d272c3 ¤   ¤   ¤   ¤   {
185d13 ¤   ¤   ¤   ¤   ¤   if( HIWORD(wParam) == BN_CLICKED )
b74859 ¤   ¤   ¤   ¤   ¤   {
4ef0be ¤   ¤   ¤   ¤   ¤   ¤   short alt = GetKeyState( VK_MENU ) & 0x8000;·
aeb339 ¤   ¤   ¤   ¤   ¤   ¤   short shift = GetKeyState( VK_SHIFT ) & 0x8000;·
1d2f7a ¤   ¤   ¤   ¤   ¤   ¤   short ctrl = GetKeyState( VK_CONTROL ) & 0x8000;·
d9af5a
63af5a
1a882b ¤   ¤   ¤   ¤   ¤   ¤   if(alt && ·shift && ctrl)
498fec ¤   ¤   ¤   ¤   ¤   ¤   {
7a5c17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwnd, IDC_STATIC_1), "Hugh¶
f3de5b ·Heffner:");
b7fa5c ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwnd, IDC_STATIC_2), "Go! ¶
fa63bd Computing:");
73f936 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwnd, IDC_STATIC_3), "Theo¶
f383a2 dore Kaczynski:");
03cc81 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwnd, IDC_STATIC_4), "Bene¶
5a67c8 dict Arnold:");
f8db3c ¤   ¤   ¤   ¤   ¤   ¤   }
c41c89 ¤   ¤   ¤   ¤   ¤   }
5e14c3 ¤   ¤   ¤   ¤   ¤   break;
1a2613 ¤   ¤   ¤   ¤   }
dda3a6 ¤   ¤   ¤   }
5fcdcb ¤   ¤   ¤   break;
4c0fe4 ¤   ¤   }
13af5a
eaa810 ¤   ¤   case WM_PAINT:
d45b34 ¤   ¤   {
6b29a7 ¤   ¤   ¤   if (data->palette)
3cf776 ¤   ¤   ¤   {
99596f ¤   ¤   ¤   ¤   PAINTSTRUCT ps;
77cf84 ¤   ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwnd, &ps);
3db00a ¤   ¤   ¤   ¤   SelectPalette (hDC, data->palette, FALSE);
33708d ¤   ¤   ¤   ¤   RealizePalette (hDC);
37519e ¤   ¤   ¤   ¤   EndPaint (hwnd, &ps);
9711bf ¤   ¤   ¤   ¤   bReturnValue = TRUE;
c2a3a6 ¤   ¤   ¤   }
--20ab 00073be3f924011027a Page 6 of WFwiz.c
e0af5a
29cdcb ¤   ¤   ¤   break;
290fe4 ¤   ¤   }
59af5a
68b3c8 ¤   ¤   case WM_NOTIFY:
605b34 ¤   ¤   {
55a08b ¤   ¤   ¤   LPNMHDR pnmh;
d9af5a
3a2b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
9faf5a
66b7b0 ¤   ¤   ¤   switch(pnmh->code)
14f776 ¤   ¤   ¤   {
f9ed40 ¤   ¤   ¤   ¤   case PSN_SETACTIVE:
6372c3 ¤   ¤   ¤   ¤   {
9e7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
d6a5eb ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwnd),·
e16a65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS,·
02c118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
9c1363 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_NEXT | PSWIZB_BACK);
4faf5a
21c131 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(¤hwnd,·
3135b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_WIZBITMAP,·
7fdc51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STM_SETIMAGE,·
21b3c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP,·
979f2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) data->bmp);
2daf5a
571452 ¤   ¤   ¤   ¤   ¤   bReturnValue = TRUE;
dd14c3 ¤   ¤   ¤   ¤   ¤   break;
7c2613 ¤   ¤   ¤   ¤   }
d0af5a
ceec6d ¤   ¤   ¤   ¤   case PSN_KILLACTIVE:
6872c3 ¤   ¤   ¤   ¤   {
8666b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
09891e ¤   ¤   ¤   ¤   ¤   char buf[512] = {0x00};
e0463b ¤   ¤   ¤   ¤   ¤   int passes;
81af5a
1ea0b2 ¤   ¤   ¤   ¤   ¤   GetWindowText(drivelist, buf, sizeof(buf));
1caf5a
3bbc9f ¤   ¤   ¤   ¤   ¤   strcpy(data->drive, buf);
91af5a
dfd65a ¤   ¤   ¤   ¤   ¤   GetWindowText(numpasses, buf, sizeof(buf));
07ae30 ¤   ¤   ¤   ¤   ¤
7bcacd ¤   ¤   ¤   ¤   ¤   passes = atoi(buf);
87af5a
fc1de2 ¤   ¤   ¤   ¤   ¤   data->passes = passes;
59af5a
9d14c3 ¤   ¤   ¤   ¤   ¤   break;
d22613 ¤   ¤   ¤   ¤   }
e9af5a
eeaeab ¤   ¤   ¤   ¤   case PSN_WIZNEXT:
f572c3 ¤   ¤   ¤   ¤   {
8e66b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
bc891e ¤   ¤   ¤   ¤   ¤   char buf[512] = {0x00};
d0463b ¤   ¤   ¤   ¤   ¤   int passes;
20af5a
b0d65a ¤   ¤   ¤   ¤   ¤   GetWindowText(numpasses, buf, sizeof(buf));
76ae30 ¤   ¤   ¤   ¤   ¤
52cacd ¤   ¤   ¤   ¤   ¤   passes = atoi(buf);
97af5a
691de2 ¤   ¤   ¤   ¤   ¤   data->passes = passes;
f3af5a
88d34c ¤   ¤   ¤   ¤   ¤   if((passes<1)||(passes>32))
ca4859 ¤   ¤   ¤   ¤   ¤   {
261415 ¤   ¤   ¤   ¤   ¤   ¤   char Caption[100];
c66584 ¤   ¤   ¤   ¤   ¤   ¤   char Message[500];
e8af5a
9e07a8 ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_PGPERROR, Caption, sizeof(Capt¶
4a8bca ion));
367fcc ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_PASSESOUTOFRANGE, Message, siz¶
913763 eof(Message));
64af5a
73a4f4 ¤   ¤   ¤   ¤   ¤   ¤   MessageBox(hwnd,Message,Caption,
--676d 000a2bb0ae24011027a Page 7 of WFwiz.c
b3ec31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
92af5a
b523dd ¤   ¤   ¤   ¤   ¤   ¤   if(passes<1)
d96403 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(numpasses, "1");
23af5a
452887 ¤   ¤   ¤   ¤   ¤   ¤   if(passes>32)
027ef1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetWindowText(numpasses, "32");
88af5a
55f286 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwnd,DWL_MSGRESULT,(LPARAM)-1); // Don't ¶
daa7f3 go on...
84af5a
1080de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
d11c89 ¤   ¤   ¤   ¤   ¤   }
9114c3 ¤   ¤   ¤   ¤   ¤   break;
232613 ¤   ¤   ¤   ¤   }
94af5a
ee3eba ¤   ¤   ¤   ¤   case PSN_WIZFINISH:
7f72c3 ¤   ¤   ¤   ¤   {
ab9a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
3014c3 ¤   ¤   ¤   ¤   ¤   break;
482613 ¤   ¤   ¤   ¤   }
90af5a
d0750a ¤   ¤   ¤   ¤   case PSN_HELP:
4472c3 ¤   ¤   ¤   ¤   {
bdf1f2 ¤   ¤   ¤   ¤   ¤   // Display help
4c14c3 ¤   ¤   ¤   ¤   ¤   break;
a52613 ¤   ¤   ¤   ¤   }
54af5a
e26035 ¤   ¤   ¤   ¤   case PSN_QUERYCANCEL:
5d72c3 ¤   ¤   ¤   ¤   {
476b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
5614c3 ¤   ¤   ¤   ¤   ¤   break;
112613 ¤   ¤   ¤   ¤   }
25a3a6 ¤   ¤   ¤   }
6b87c7 ¤   ¤   ¤
f9cdcb ¤   ¤   ¤   break;
700fe4 ¤   ¤   }
fbaf5a
f99371 ¤   }
22af5a
735f5f ¤   return bReturnValue;
d5efe6 }
e4af5a
1d9385 BOOL CALLBACK StatusDlgProc(HWND hwnd,·
705c16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
84cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
784868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
0abb36 {
4dd102 ¤   BOOL bReturnValue = FALSE;
b80b3d ¤   static wizard_data* data = NULL;
e4cc29 ¤   static HWND fsdata = NULL;
4c4b8c ¤   static HWND ncdata = NULL;
38d889 ¤   static HWND scdata = NULL;
47e490 ¤   static HWND bsdata = NULL;
a7284e ¤   static HWND tcdata = NULL;
5d27af ¤   static HWND group = NULL;
6daf5a
0faf5a
c19467 ¤   switch(msg)
32c7a1 ¤   {
a9df25 ¤   ¤   case WM_INITDIALOG:
f05b34 ¤   ¤   {
b02530 ¤   ¤   ¤   PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lParam;
7dc42d ¤   ¤   ¤   char buf[512] = {0x00};
e087c7 ¤   ¤   ¤
7148b0 ¤   ¤   ¤   data = (wizard_data*) psp->lParam;
f7af5a
ba41d3 ¤   ¤   ¤   fsdata = GetDlgItem(hwnd, IDC_FSDATA);
35de19 ¤   ¤   ¤   ncdata = GetDlgItem(hwnd, IDC_NCDATA);
398cee ¤   ¤   ¤   scdata = GetDlgItem(hwnd, IDC_SCDATA);
9f5d9f ¤   ¤   ¤   bsdata = GetDlgItem(hwnd, IDC_BSDATA);
a29997 ¤   ¤   ¤   tcdata = GetDlgItem(hwnd, IDC_TCDATA);
--df5e 000de900a244011027a Page 8 of WFwiz.c
eca6e4 ¤   ¤   ¤   group = GetDlgItem(hwnd, IDC_GROUP);
9baf5a
71879c ¤   ¤   ¤   g_status = GetDlgItem(hwnd, IDC_STATUS);
a911a3 ¤   ¤   ¤   g_wipe_progress = GetDlgItem(hwnd, IDC_WIPE_PROGRESS);
b7e3e5 ¤   ¤   ¤   g_pass_progress¤= GetDlgItem(hwnd, IDC_PASS_PROGRESS);
6bbfda ¤   ¤   ¤   g_pass_status = GetDlgItem(hwnd, IDC_STATIC_PASS);
d487c7 ¤   ¤   ¤
167a4e ¤   ¤   ¤   SetWindowLong(hwnd, GWL_USERDATA, (LPARAM) data);
70af5a
332cd7 ¤   ¤   ¤   bReturnValue = TRUE;
a4cdcb ¤   ¤   ¤   break;
e50fe4 ¤   ¤   }
9eaf5a
788e1e ¤   ¤   case WM_COMMAND:
955b34 ¤   ¤   {
7d9164 ¤   ¤   ¤   switch(LOWORD(wParam))
01f776 ¤   ¤   ¤   {
e5421c ¤   ¤   ¤   ¤   case IDC_BEGIN:
9b72c3 ¤   ¤   ¤   ¤   {
d49246 ¤   ¤   ¤   ¤   ¤   data->hwnd = hwnd;
edaf5a
76ef8b ¤   ¤   ¤   ¤   ¤   _beginthread(WipeThread, 0, (void*)data);
29af5a
861452 ¤   ¤   ¤   ¤   ¤   bReturnValue = TRUE;
6514c3 ¤   ¤   ¤   ¤   ¤   break;
912613 ¤   ¤   ¤   ¤   }
b0a3a6 ¤   ¤   ¤   }
92cdcb ¤   ¤   ¤   break;
270fe4 ¤   ¤   }
7caf5a
80dad9 ¤   ¤   case WM_DESTROY:
7c5b34 ¤   ¤   {
97cdcb ¤   ¤   ¤   break;
fe0fe4 ¤   ¤   }
d4af5a
bba810 ¤   ¤   case WM_PAINT:
d25b34 ¤   ¤   {
1529a7 ¤   ¤   ¤   if (data->palette)
fbf776 ¤   ¤   ¤   {
72596f ¤   ¤   ¤   ¤   PAINTSTRUCT ps;
1ccf84 ¤   ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwnd, &ps);
40b00a ¤   ¤   ¤   ¤   SelectPalette (hDC, data->palette, FALSE);
cb708d ¤   ¤   ¤   ¤   RealizePalette (hDC);
36519e ¤   ¤   ¤   ¤   EndPaint (hwnd, &ps);
7511bf ¤   ¤   ¤   ¤   bReturnValue = TRUE;
69a3a6 ¤   ¤   ¤   }
52af5a
7dcdcb ¤   ¤   ¤   break;
430fe4 ¤   ¤   }
23af5a
a0b3c8 ¤   ¤   case WM_NOTIFY:
025b34 ¤   ¤   {
05a08b ¤   ¤   ¤   LPNMHDR pnmh;
adaf5a
e52b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
e4af5a
5db7b0 ¤   ¤   ¤   switch(pnmh->code)
82f776 ¤   ¤   ¤   {
3fed40 ¤   ¤   ¤   ¤   case PSN_SETACTIVE:
5372c3 ¤   ¤   ¤   ¤   {
65f0e8 ¤   ¤   ¤   ¤   ¤   char StrRes[500];
f18488 ¤   ¤   ¤   ¤   ¤   VOLINFO vi;
64af5a
04f52a ¤   ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwnd,IDC_RESTARTINGTEXT),
538ffe ¤   ¤   ¤   ¤   ¤   ¤   "");
96af5a
b3085c ¤   ¤   ¤   ¤   ¤   WipeProgress(0);
8bd569 ¤   ¤   ¤   ¤   ¤   PassProgress(0, data->passes);
b0af5a
652aa3 ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_DISKSTAT, StrRes, sizeof(StrRes));
72af5a
deb938 ¤   ¤   ¤   ¤   ¤   strcat(StrRes, data->drive);
--3cc6 000839c125c4011027a Page 9 of WFwiz.c
96efc3 ¤   ¤   ¤   ¤   ¤   SetWindowText(group, StrRes);
3e67c5 ¤
924f8e ¤   ¤   ¤   ¤   ¤   WipeFree(hwnd,
efdbfb ¤   ¤   ¤   ¤   ¤   ¤   &vi,
ddc6e5 ¤   ¤   ¤   ¤   ¤   ¤   data->drive,
a1aec3 ¤   ¤   ¤   ¤   ¤   ¤   NULL,
67f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
80af5a
5dd12e ¤   ¤   ¤   ¤   ¤   DisplayDiskStats(&vi);
34af5a
6e3147 ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_BEGINWIPE, StrRes, sizeof(StrRes));
00af5a
b70745 ¤   ¤   ¤   ¤   ¤   StatusMessage(StrRes, FALSE);
c1085c ¤   ¤   ¤   ¤   ¤   WipeProgress(0);
82af5a
0e7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
3ba5eb ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwnd),·
6f6a65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS,·
5dc118 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
ada1c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSWIZB_DISABLEDFINISH|PSWIZB_BACK);
d9af5a
f7c131 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(¤hwnd,·
a735b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_WIZBITMAP,·
a7dc51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STM_SETIMAGE,·
a7b3c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP,·
159f2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) data->bmp);
e0af5a
921452 ¤   ¤   ¤   ¤   ¤   bReturnValue = TRUE;
9414c3 ¤   ¤   ¤   ¤   ¤   break;
972613 ¤   ¤   ¤   ¤   }
b5af5a
2aec6d ¤   ¤   ¤   ¤   case PSN_KILLACTIVE:
3f72c3 ¤   ¤   ¤   ¤   {
4566b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
7614c3 ¤   ¤   ¤   ¤   ¤   break;
352613 ¤   ¤   ¤   ¤   }
d6af5a
263eba ¤   ¤   ¤   ¤   case PSN_WIZFINISH:
c772c3 ¤   ¤   ¤   ¤   {
ad9a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
6c700e ¤   ¤   ¤   ¤   ¤   PGPContextRef¤  context = data->context;
b0c08d ¤   ¤   ¤   ¤   ¤   PGPError¤   ¤   error;
482bf5 ¤   ¤   ¤   ¤   ¤   PGPPrefRef¤ ¤   prefRef;
a220f2 ¤   ¤   ¤   ¤   ¤   PGPMemoryMgrRef memoryMgr;
d3af5a
e70c89 ¤   ¤   ¤   ¤   ¤   memoryMgr = PGPGetContextMemoryMgr(context);
46af5a
107dd5 ¤   ¤   ¤   ¤   ¤   error = PGPclOpenClientPrefs(¤  memoryMgr,
fd7b4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefRef );
67af5a
fbd47f ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(error) )
344859 ¤   ¤   ¤   ¤   ¤   {
9b46dd ¤   ¤   ¤   ¤   ¤   ¤   PGPSetPrefNumber (¤ prefRef,
5ab833 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefDiskWipePasses,·
8b4a41 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   data->passes);
cdaf5a
23d445 ¤   ¤   ¤   ¤   ¤   ¤   PGPclCloseClientPrefs (prefRef, TRUE);
18af5a
7c1c89 ¤   ¤   ¤   ¤   ¤   }
d8af5a
6914c3 ¤   ¤   ¤   ¤   ¤   break;
0b2613 ¤   ¤   ¤   ¤   }
1caf5a
87750a ¤   ¤   ¤   ¤   case PSN_HELP:
5872c3 ¤   ¤   ¤   ¤   {
e9f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
6e14c3 ¤   ¤   ¤   ¤   ¤   break;
2c2613 ¤   ¤   ¤   ¤   }
6aaf5a
b06035 ¤   ¤   ¤   ¤   case PSN_QUERYCANCEL:
a472c3 ¤   ¤   ¤   ¤   {
837212 ¤   ¤   ¤   ¤   ¤   NMHDR* nmhdr = (NMHDR*) lParam;
--3b1f 0004feb02864011027a Page 10 of WFwiz.c
e0af5a
3e6b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
763eb4 ¤   ¤   ¤   ¤   ¤   if( g_bWiping )
c54859 ¤   ¤   ¤   ¤   ¤   {
dd127c ¤   ¤   ¤   ¤   ¤   ¤   bGlobalCancel=TRUE;
9612ea ¤   ¤   ¤   ¤   ¤   ¤   bReturnValue = TRUE;
31ccb4 ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong(hwnd, DWL_MSGRESULT, TRUE);
121c89 ¤   ¤   ¤   ¤   ¤   }
9d14c3 ¤   ¤   ¤   ¤   ¤   break;
7b2613 ¤   ¤   ¤   ¤   }
eaa3a6 ¤   ¤   ¤   }
c987c7 ¤   ¤   ¤
dacdcb ¤   ¤   ¤   break;
7b0fe4 ¤   ¤   }
a4af5a
f59371 ¤   }
caaf5a
a75f5f ¤   return bReturnValue;
b6efe6 }
43af5a
4f924a BOOL CALLBACK FinishDlgProc(HWND hwnd,·
be5c16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
a1cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
3f4868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
39bb36 {
42d102 ¤   BOOL bReturnValue = FALSE;
3bd2df ¤   static HFONT boldfont;
0d0b3d ¤   static wizard_data* data = NULL;
2aaf5a
9e9467 ¤   switch(msg)
90c7a1 ¤   {
6cdf25 ¤   ¤   case WM_INITDIALOG:
725b34 ¤   ¤   {
852530 ¤   ¤   ¤   PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lParam;
e0ac89 ¤   ¤   ¤   HWND finish = GetDlgItem(hwnd, IDC_FINISH);
392445 ¤   ¤   ¤   HWND hwndParent = GetParent(hwnd);
459211 ¤   ¤   ¤   HFONT defaultfont;
4a8b1f ¤   ¤   ¤   LOGFONT¤lf;
26af5a
5848b0 ¤   ¤   ¤   data = (wizard_data*) psp->lParam;
58af5a
90763e ¤   ¤   ¤   defaultfont = GetStockObject(DEFAULT_GUI_FONT);
fcaf5a
de3513 ¤   ¤   ¤   GetObject(defaultfont, sizeof(LOGFONT), &lf);
06af5a
5d4596 ¤   ¤   ¤   lf.lfWeight = FW_BOLD;
c3af5a
7117ca ¤   ¤   ¤   boldfont = CreateFontIndirect(&lf);
45af5a
a15bf2 ¤   ¤   ¤   SendMessage(finish,·
d439f2 ¤   ¤   ¤   ¤   ¤   ¤   WM_SETFONT,·
2b49ca ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)boldfont,
74bd7f ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
86af5a
af2cd7 ¤   ¤   ¤   bReturnValue = TRUE;
37cdcb ¤   ¤   ¤   break;
bd0fe4 ¤   ¤   }
70af5a
23dad9 ¤   ¤   case WM_DESTROY:
fb5b34 ¤   ¤   {
41a428 ¤   ¤   ¤   DeleteObject(boldfont);
4ecdcb ¤   ¤   ¤   break;
d10fe4 ¤   ¤   }
edaf5a
99a810 ¤   ¤   case WM_PAINT:
325b34 ¤   ¤   {
c929a7 ¤   ¤   ¤   if (data->palette)
8bf776 ¤   ¤   ¤   {
6f596f ¤   ¤   ¤   ¤   PAINTSTRUCT ps;
2dcf84 ¤   ¤   ¤   ¤   HDC¤hDC = BeginPaint (hwnd, &ps);
ccb00a ¤   ¤   ¤   ¤   SelectPalette (hDC, data->palette, FALSE);
4f708d ¤   ¤   ¤   ¤   RealizePalette (hDC);
--32c3 000f08826454011027a Page 11 of WFwiz.c
f1519e ¤   ¤   ¤   ¤   EndPaint (hwnd, &ps);
bf11bf ¤   ¤   ¤   ¤   bReturnValue = TRUE;
caa3a6 ¤   ¤   ¤   }
8caf5a
74cdcb ¤   ¤   ¤   break;
550fe4 ¤   ¤   }
ffaf5a
2ab3c8 ¤   ¤   case WM_NOTIFY:
575b34 ¤   ¤   {
34a08b ¤   ¤   ¤   LPNMHDR pnmh;
95af5a
062b98 ¤   ¤   ¤   pnmh = (LPNMHDR) lParam;
c3af5a
deb7b0 ¤   ¤   ¤   switch(pnmh->code)
29f776 ¤   ¤   ¤   {
e5ed40 ¤   ¤   ¤   ¤   case PSN_SETACTIVE:
2072c3 ¤   ¤   ¤   ¤   {
bc7182 ¤   ¤   ¤   ¤   ¤   // Initialize window
f9a5eb ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hwnd),·
dfcdf1 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
a4af5a
8bc131 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(¤hwnd,·
8735b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_WIZBITMAP,·
b8dc51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STM_SETIMAGE,·
20b3c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP,·
e19f2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) data->bmp);
4baf5a
c81452 ¤   ¤   ¤   ¤   ¤   bReturnValue = TRUE;
ca14c3 ¤   ¤   ¤   ¤   ¤   break;
6a2613 ¤   ¤   ¤   ¤   }
43af5a
a3ec6d ¤   ¤   ¤   ¤   case PSN_KILLACTIVE:
5a72c3 ¤   ¤   ¤   ¤   {
0f66b4 ¤   ¤   ¤   ¤   ¤   // Save user data for this page
2314c3 ¤   ¤   ¤   ¤   ¤   break;
e52613 ¤   ¤   ¤   ¤   }
c3af5a
593eba ¤   ¤   ¤   ¤   case PSN_WIZFINISH:
9272c3 ¤   ¤   ¤   ¤   {
2a9a7e ¤   ¤   ¤   ¤   ¤   // Save user data for all pages
d714c3 ¤   ¤   ¤   ¤   ¤   break;
fa2613 ¤   ¤   ¤   ¤   }
b2af5a
87750a ¤   ¤   ¤   ¤   case PSN_HELP:
5c72c3 ¤   ¤   ¤   ¤   {
77f1f2 ¤   ¤   ¤   ¤   ¤   // Display help
2514c3 ¤   ¤   ¤   ¤   ¤   break;
9d2613 ¤   ¤   ¤   ¤   }
d7af5a
526035 ¤   ¤   ¤   ¤   case PSN_QUERYCANCEL:
2272c3 ¤   ¤   ¤   ¤   {
696b66 ¤   ¤   ¤   ¤   ¤   // User wants to quit
2014c3 ¤   ¤   ¤   ¤   ¤   break;
892613 ¤   ¤   ¤   ¤   }
9ea3a6 ¤   ¤   ¤   }
8387c7 ¤   ¤   ¤
56cdcb ¤   ¤   ¤   break;
a20fe4 ¤   ¤   }
f1af5a
799371 ¤   }
a1af5a
8f5f5f ¤   return bReturnValue;
2befe6 }
daaf5a
892f98 void StatusMessage(char *msg, BOOL bold)
7fbb36 {
f427ae ¤   if(bold)
6bc7a1 ¤   {
e76e0d ¤   ¤   SendMessage(g_status,·
95bfcc ¤   ¤   ¤   ¤   WM_SETFONT,·
268698 ¤   ¤   ¤   ¤   (WPARAM)g_boldfont,
f0b854 ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
--af8f 00067c49d684011027a Page 12 of WFwiz.c
a19371 ¤   }
0e0e24 ¤   else
96c7a1 ¤   {
5b6e0d ¤   ¤   SendMessage(g_status,·
1fbfcc ¤   ¤   ¤   ¤   WM_SETFONT,·
134d80 ¤   ¤   ¤   ¤   (WPARAM)g_defaultfont,
b8b854 ¤   ¤   ¤   ¤   MAKELPARAM(TRUE, 0));
599371 ¤   }
99af5a
d2137c ¤   SetWindowText(g_status, msg);
78efe6 }
4faf5a
699364 void WipeProgress(int pos)
22bb36 {
aa14de ¤   if(pos==10)
84c7a1 ¤   {
e7e02a ¤   ¤   SetWindowText(
b18939 ¤   ¤   ¤   GetDlgItem(GetParent(g_wipe_progress),IDC_RESTARTINGTEXT),
4f4bf9 ¤   ¤   ¤   "");
9f9371 ¤   }
c8af5a
8df50b ¤   SendMessage(g_wipe_progress,
8b541d ¤   ¤   ¤   ¤   PBM_SETPOS ,
f8b3e0 ¤   ¤   ¤   ¤   (WPARAM)pos,
92c217 ¤   ¤   ¤   ¤   0);¤
d6efe6 }
a2af5a
4dd9de void PassProgress(int pass, int total)
2bbb36 {
6c8384 ¤   char msg[] = "Pass: %d/%d";
c5658f ¤   char buf[128];
4aaf5a
25f64d ¤   SendMessage(g_pass_progress,
ed8232 ¤   ¤   ¤   ¤   PBM_SETRANGE,
be038c ¤   ¤   ¤   ¤   0,
b98ce9 ¤   ¤   ¤   ¤   MAKELPARAM(0, total));¤
36af5a
e0f64d ¤   SendMessage(g_pass_progress,
65541d ¤   ¤   ¤   ¤   PBM_SETPOS ,
a89798 ¤   ¤   ¤   ¤   (WPARAM)pass,
07c217 ¤   ¤   ¤   ¤   0);¤
57af5a
7aa2b9 ¤   pass=pass+1; ·// now one based instead of zero based
8e726b ¤   if(pass>total)
4f8ebc ¤   ¤   pass=total;
67af5a
622691 ¤   wsprintf(buf, msg, pass , total);·
33af5a
a8dd8f ¤   SetWindowText(g_pass_status, buf);
2aefe6 }
76af5a
55a3a7 BOOL DisplayDiskStats(VOLINFO *vi)
aabb36 {
7ef76c ¤   char buf[256];
fcaf5a
2419ee ¤   switch(vi->dwFS)
d7c7a1 ¤   {
176c3c ¤   ¤   case FS_FAT12:
1e6f0e ¤   ¤   ¤   strcpy(buf,"FAT 12");
e9cdcb ¤   ¤   ¤   break;
02af5a
7c0f5d ¤   ¤   case FS_FAT16:
c7421e ¤   ¤   ¤   strcpy(buf,"FAT 16");
e4cdcb ¤   ¤   ¤   break;
5faf5a
ea554a ¤   ¤   case FS_FAT32:
016758 ¤   ¤   ¤   strcpy(buf,"FAT 32");
35cdcb ¤   ¤   ¤   break;
47af5a
1244b8 ¤   ¤   case FS_NTFS:
dec9a0 ¤   ¤   ¤   strcpy(buf,"NTFS");
67cdcb ¤   ¤   ¤   break;
--f0e9 000dedf93264011027a Page 13 of WFwiz.c
e0af5a
a23750 ¤   ¤   default: // Should never get here
af30ed ¤   ¤   ¤   strcpy(buf,"Unknown");·
4f9371 ¤   }
2faf5a
083a3b ¤   SendMessage(GetDlgItem(vi->hwnd,IDC_FSDATA),
02f70b ¤   ¤   ¤   ¤   WM_SETTEXT,
4195db ¤   ¤   ¤   ¤   (WPARAM)0,
fcb897 ¤   ¤   ¤   ¤   (LPARAM)buf);
27af5a
f47966 ¤   sprintf(buf,"%d",vi->no_of_clusters);
ed1e89 ¤   SendMessage(GetDlgItem(vi->hwnd,IDC_NCDATA),
18f70b ¤   ¤   ¤   ¤   WM_SETTEXT,
7795db ¤   ¤   ¤   ¤   (WPARAM)0,
20b897 ¤   ¤   ¤   ¤   (LPARAM)buf);
baaf5a
5eb585 ¤   sprintf(buf,"%d",vi->sectors_per_clus);
e5eccf ¤   SendMessage(GetDlgItem(vi->hwnd,IDC_SCDATA),
9cf70b ¤   ¤   ¤   ¤   WM_SETTEXT,
9695db ¤   ¤   ¤   ¤   (WPARAM)0,
dab897 ¤   ¤   ¤   ¤   (LPARAM)buf);
d9af5a
557c4f ¤   sprintf(buf,"%d",vi->sector_size);
9f05de ¤   SendMessage(GetDlgItem(vi->hwnd,IDC_BSDATA),
36f70b ¤   ¤   ¤   ¤   WM_SETTEXT,
7095db ¤   ¤   ¤   ¤   (WPARAM)0,
d0b897 ¤   ¤   ¤   ¤   (LPARAM)buf);
36af5a
e64e3a ¤   sprintf(buf,"%.0f K",vi->fTotalCapacity/1024);
57052d ¤   SendMessage(GetDlgItem(vi->hwnd,IDC_TCDATA),
7ef70b ¤   ¤   ¤   ¤   WM_SETTEXT,
5595db ¤   ¤   ¤   ¤   (WPARAM)0,
3ab897 ¤   ¤   ¤   ¤   (LPARAM)buf);
a7af5a
36c2e7 ¤   return TRUE;
87efe6 }
5aaf5a
5440bd void WipeThread(void* pvoid)
55bb36 {
1f4df5 ¤   wizard_data* data = (wizard_data*)pvoid;
067ca1 ¤   HWND hwnd = data->hwnd;
d3bb91 ¤   HWND hwndParent = GetParent(hwnd);
5a3234 ¤   VOLINFO vi;
9a265e ¤   long err;
a2b441 ¤   char buf[512];
5099cf ¤   int passes = data->passes;
37eb39 ¤   PGPError¤   ¤   error¤  ¤   ¤   = kPGPError_NoErr;
59f6d5 ¤   PGPError¤   ¤   entropyErr¤ ¤   = kPGPError_NoErr;
825bab ¤   PGPDiskWipeRef¤ wipeRef¤¤   ¤   = kPGPInvalidRef;
09aa90 ¤   PGPInt32¤   ¤   pattern[256];
446672 ¤   char StrRes[500];
15af5a
29bd15 ¤   EnableWindow(GetDlgItem(hwnd, IDC_BEGIN), FALSE);
efaf5a
d45123 ¤   SendMessage(hwndParent,·
c24308 ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS,
d26b2b ¤   ¤   ¤   ¤   0,·
66e274 ¤   ¤   ¤   ¤   PSWIZB_DISABLEDFINISH);
7eaf5a
4ce2f4 ¤   g_bWiping = TRUE;
42af5a
dff20a ¤   do{
02f1e6 ¤   ¤   error = PGPCreateDiskWiper(data->context, &wipeRef, passes);
d2af5a
5ae212 ¤   ¤   if(error == kPGPError_OutOfEntropy)
0e5b34 ¤   ¤   {
1f9fc5 ¤   ¤   ¤   entropyErr = PGPclRandom(data->context, hwnd, 300);
7c0fe4 ¤   ¤   }
c9af5a
a54efa ¤   }while(¤error == kPGPError_OutOfEntropy &&·
667886 ¤   ¤   ¤   entropyErr != kPGPError_UserAbort);
de67c5 ¤
--5fa1 000223f76bc4011027a Page 14 of WFwiz.c
08f499 ¤   err = WFE_NOERROR;
ddaf5a
82f678 ¤   if( IsntPGPError(error) )
c1c7a1 ¤   {
b7f924 ¤   ¤   int count = 0;
6aaf5a
7a0c19 ¤   ¤   do
2a5b34 ¤   ¤   {
f98e62 ¤   ¤   ¤   WipeProgress(0);
933424 ¤   ¤   ¤   PassProgress(data->passes - passes, data->passes);
83af5a
2d5bb8 ¤   ¤   ¤   if(err != WFE_DISKMODIFIED)
3ef776 ¤   ¤   ¤   {
b018b1 ¤   ¤   ¤   ¤   PGPGetDiskWipeBuffer(wipeRef, pattern);
8ea3a6 ¤   ¤   ¤   }
20af5a
030260 ¤   ¤   ¤   err = WipeFree(¤hwnd,
4160ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   &vi,
26c308 ¤   ¤   ¤   ¤   ¤   ¤   ¤   data->drive,
e2343d ¤   ¤   ¤   ¤   ¤   ¤   ¤   pattern,
121dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
a0af5a
d05b8a ¤   ¤   ¤   if(err == WFE_DISKMODIFIED)
63f776 ¤   ¤   ¤   {
7ee6a6 ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwnd,IDC_RESTARTINGTEXT),
ba0379 ¤   ¤   ¤   ¤   ¤   "Write detected! ·Restarting pass.");
3eaf5a
72cefe //¤ ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_DETECTEDWRITE,
4fbb96 //¤ ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
6da3a6 ¤   ¤   ¤   }
1169f0 ¤   ¤   ¤   else if(err==WFE_NOERROR)
e7f776 ¤   ¤   ¤   {
57e6a6 ¤   ¤   ¤   ¤   SetWindowText(GetDlgItem(hwnd,IDC_RESTARTINGTEXT),
adbba3 ¤   ¤   ¤   ¤   ¤   "");
f8af5a
a282a9 ¤   ¤   ¤   ¤   passes--;
aca3a6 ¤   ¤   ¤   }
d3af5a
679245 ¤   ¤   }while(((err==WFE_NOERROR) || (err==WFE_DISKMODIFIED)) && (passes!=0) );
7daf5a
436bb8 ¤   ¤   SetWindowText(GetDlgItem(hwnd,IDC_RESTARTINGTEXT),
744bf9 ¤   ¤   ¤   "");
88af5a
930d24 ¤   ¤   error = PGPDestroyDiskWiper(wipeRef);
c89371 ¤   }
520e24 ¤   else
5dc7a1 ¤   {
4fc9b4 ¤   ¤   err = error;
8c9371 ¤   }
57af5a
89800a ¤   g_bWiping = FALSE;
6aaf5a
8e6ed4 ¤   switch(err)
55c7a1 ¤   {
8216f8 ¤   ¤   case WFE_NOERROR:
535b34 ¤   ¤   {
579e8d ¤   ¤   ¤   LoadString (g_hinst, IDS_WIPECONGRATS, StrRes, sizeof(StrRes));
01af5a
8294b7 ¤   ¤   ¤   wsprintf(buf, StrRes, data->drive);
fa87c7 ¤   ¤   ¤
becc5d ¤   ¤   ¤   // Success.. Enable finish button
7cd71d ¤   ¤   ¤   SendMessage(hwndParent,·
70a947 ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS,·
156b2b ¤   ¤   ¤   ¤   0,·
515d72 ¤   ¤   ¤   ¤   PSWIZB_BACK | PSWIZB_FINISH);
7ecdcb ¤   ¤   ¤   break;
370fe4 ¤   ¤   }
a4af5a
0f08f1 ¤   ¤   case WFE_USERCANCEL:
af5b34 ¤   ¤   {
3d72c2 ¤   ¤   ¤   LoadString (g_hinst, IDS_WIPECANCEL, StrRes, sizeof(StrRes));
22af5a
--d108 0005d238ac44011027a Page 15 of WFwiz.c
179e06 ¤   ¤   ¤   wsprintf(buf, StrRes);
84af5a
79d71d ¤   ¤   ¤   SendMessage(hwndParent,·
4ca947 ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS,·
176b2b ¤   ¤   ¤   ¤   0,·
8c665a ¤   ¤   ¤   ¤   PSWIZB_BACK | PSWIZB_DISABLEDFINISH);
a7cdcb ¤   ¤   ¤   break;
370fe4 ¤   ¤   }
35af5a
de9ae3 ¤   ¤   default:
a75b34 ¤   ¤   {
7ca618 ¤   ¤   ¤   char msg[256];
e6af5a
b20392 ¤   ¤   ¤   if(IsPGPError(error))
56f776 ¤   ¤   ¤   {
a126da ¤   ¤   ¤   ¤   PGPclErrorToString (error, msg, sizeof(msg));
711b52 ¤   ¤
c6a3a6 ¤   ¤   ¤   }
10bb8c ¤   ¤   ¤   else
e4f776 ¤   ¤   ¤   {
91af5a
2aae61 ¤   ¤   ¤   ¤   LoadString(¤data->hinst,
167f78 ¤   ¤   ¤   ¤   ¤   ¤   err -1 + IDS_FSNOTSUPPORTED,
442379 ¤   ¤   ¤   ¤   ¤   ¤   msg,
4005fd ¤   ¤   ¤   ¤   ¤   ¤   sizeof(msg));¤
74a3a6 ¤   ¤   ¤   }
e2af5a
99b36b ¤   ¤   ¤   LoadString (g_hinst, IDS_WIPENOTSUCCESSFUL, StrRes, sizeof(StrRes));
7d10d0 ¤   ¤   ¤   wsprintf(buf, StrRes, msg);
deaf5a
56d71d ¤   ¤   ¤   SendMessage(hwndParent,·
10a947 ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS,·
156b2b ¤   ¤   ¤   ¤   0,·
e5665a ¤   ¤   ¤   ¤   PSWIZB_BACK | PSWIZB_DISABLEDFINISH);
e0cdcb ¤   ¤   ¤   break;
990fe4 ¤   ¤   }
a49371 ¤   }
8faf5a
1f67c5 ¤
44fbc2 ¤   StatusMessage(buf, TRUE);
570bee ¤   WipeProgress(0);
cb33fd ¤   PassProgress(data->passes - passes, data->passes);
daaf5a
495957 ¤   EnableWindow(GetDlgItem(hwnd, IDC_BEGIN), TRUE);
d4efe6 }
2daf5a
67af5a
af597e static HPALETTE·
4fcef8 CreateDIBPalette (LPBITMAPINFO lpbmi,·
e770ea ¤   ¤   ¤   ¤   ··LPINT lpiNumColors)·
b1bb36 {
91e3ed ¤   LPBITMAPINFOHEADER lpbi;
780377 ¤   LPLOGPALETTE lpPal;
c1dcb6 ¤   HANDLE hLogPal;
25abc2 ¤   HPALETTE hPal = NULL;
7dcdd6 ¤   INT i;
79d83c ·
147407 ¤   lpbi = (LPBITMAPINFOHEADER)lpbmi;
a1ff30 ¤   if (lpbi->biBitCount <= 8) {
ca5406 ¤   ¤   *lpiNumColors = (1 << lpbi->biBitCount);
989371 ¤   }
a40e24 ¤   else
ed21cc ¤   ¤   *lpiNumColors = 0; ·// No palette needed for 24 BPP DIB
22d83c ·
cbf623 ¤   if (*lpiNumColors) {
7f0012 ¤   ¤   hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
7f440c ·····························sizeof (PALETTEENTRY) * (*lpiNumColors));
f0d92a ¤   ¤   lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
435442 ¤   ¤   lpPal->palVersion = 0x300;
e54b35 ¤   ¤   lpPal->palNumEntries = *lpiNumColors;
31d83c ·
5da249 ¤   ¤   for (i = 0; ·i < *lpiNumColors; ·i++) {
--10cc 001bbee46464011027a Page 16 of WFwiz.c
49d118 ¤   ¤   ¤   lpPal->palPalEntry[i].peRed ··= lpbmi->bmiColors[i].rgbRed;
a5dc94 ¤   ¤   ¤   lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
b81adf ¤   ¤   ¤   lpPal->palPalEntry[i].peBlue ·= lpbmi->bmiColors[i].rgbBlue;
ff089b ¤   ¤   ¤   lpPal->palPalEntry[i].peFlags = 0;
f70fe4 ¤   ¤   }
b5898e ¤   ¤   hPal = CreatePalette (lpPal);
fb93f7 ¤   ¤   GlobalUnlock (hLogPal);
f5b50d ¤   ¤   GlobalFree (hLogPal);
01b144 ···}
5aef80 ···return hPal;
bdefe6 }
ecaf5a
2faf5a
a6fb93 static HBITMAP·
c8d9f1 LoadResourceBitmap (HINSTANCE hInstance,·
55d7f9 ¤   ¤   ¤   ¤   ¤   LPSTR lpString,
7f81c5 ¤   ¤   ¤   ¤   ¤   HPALETTE FAR* lppalette)·
6dbb36 {
acef32 ¤   HRSRC ·hRsrc;
d99627 ¤   HGLOBAL hGlobal;
1ccfb4 ¤   HBITMAP hBitmapFinal = NULL;
b5e3ed ¤   LPBITMAPINFOHEADER lpbi;
900755 ¤   HDC hdc;
d65789 ····INT iNumColors;
cad83c ·
86e2a3 ¤   if (hRsrc = FindResource (hInstance, lpString, RT_BITMAP)) {
27aa39 ¤   ¤   hGlobal = LoadResource (hInstance, hRsrc);
9026b6 ¤   ¤   lpbi = (LPBITMAPINFOHEADER)LockResource (hGlobal);
05d83c ·
a2002d ¤   ¤   hdc = GetDC(NULL);
607d6a ¤   ¤   *lppalette = ·CreateDIBPalette ((LPBITMAPINFO)lpbi, &iNumColors);
78931f ¤   ¤   if (*lppalette) {
7907c3 ¤   ¤   ¤   SelectPalette (hdc,*lppalette,FALSE);
e5703c ¤   ¤   ¤   RealizePalette (hdc);
5a0fe4 ¤   ¤   }
f0d83c ·
88259d ¤   ¤   hBitmapFinal = CreateDIBitmap (hdc,
5e14f2 ···················(LPBITMAPINFOHEADER)lpbi,
a2e478 ···················(LONG)CBM_INIT,
24d8e7 ···················(LPSTR)lpbi + lpbi->biSize + iNumColors * sizeof(RGBQUAD),
d1e564 ···················(LPBITMAPINFO)lpbi,
48a1a1 ···················DIB_RGB_COLORS );
f6d83c ·
2f6078 ¤   ¤   ReleaseDC (NULL,hdc);
ef66f7 ¤   ¤   UnlockResource (hGlobal);
961d90 ¤   ¤   FreeResource (hGlobal);
e69371 ¤   }
15aa7e ¤   return (hBitmapFinal);
67efe6 }
2aaf5a
6daf5a
097e4d /*__Editor_settings____
5daf5a
934126 ¤   Local Variables:
7a7b17 ¤   tab-width: 4
c60e6c ¤   End:
ab5f8c ¤   vi: ts=4 sw=4
849e9b ¤   vim: si
bbd062 _____________________*/
--910a 0010c68db9f4011027b Page 1 of WFwiz.h
0a751f typedef enum Page
22bb36 {
2d3586 ¤   intro = 0,
c04661 ¤   info,
d1808d ¤   status,
f9c506 ¤   finish,
4b01a5 ¤   NUM_PAGES
0fb4d4 } Page;
b4af5a
17f3e3 typedef struct wizard_data
b1bb36 {
10207e ¤   HINSTANCE¤  ¤   hinst;
f1b162 ¤   HWND¤   ¤   ¤   hwnd;
fdf9e3 ¤   HBITMAP¤¤   ¤   bmp;
7d47fa ¤   HPALETTE¤   ¤   palette;
cd8a97 ¤   PGPContextRef¤  context;
a19059 ¤   int¤¤   ¤   ¤   cookie;
ec9e8c ¤   int¤¤   ¤   ¤   passes;
40c3fe ¤   char¤   ¤   ¤   drive[5];
0baf5a
0cc1c5 }wizard_data;
--fa27 0000b8e1fb24011027c Page 1 of decrypt.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
096a5c ¤   $Id: decrypt.c,v 1.85.2.1.2.1 1998/11/12 03:13:33 heller Exp $
c3f7f7 ____________________________________________________________________________*/
4b5ed8 #include "precomp.h"
baaf5a
70ea21 PGPError GenericDecVer(MYSTATE *ms,
53d421 ¤   ¤   ¤   ¤   ¤   PGPOptionListRef opts,
1999eb ¤   ¤   ¤   ¤   ¤   char *OperationTarget)
1cbb36 {
91fb19 ¤   PGPError¤   ¤   err;
ac065f ¤   PGPKeySetRef¤   AddKeySet;
52f51b ¤   PGPUInt32¤  ¤   numKeys;
2a8a97 ¤   PGPContextRef¤  context;
98ea1b ¤   char¤   ¤   ¤   StrRes[500];
49af5a
024ead ¤   err=kPGPError_NoErr;
b5af5a
9d2d85 ¤   context=ms->context;
b4af5a
98eeed ¤   // Use passphrase first if available
5f59af ¤   if(ms->PassPhrase)
e8c7a1 ¤   {
b03df4 ¤   ¤   PGPAppendOptionList(opts,
5d19cc ¤   ¤   ¤   PGPOPassphraseBuffer(context,
4a7122 ¤   ¤   ¤   ¤   ms->PassPhrase, strlen(ms->PassPhrase) ),
00e5ff ¤   ¤   ¤   PGPOLastOption(context));
a79371 ¤   }
7abd96 ¤   else if(ms->PassKey)
a0c7a1 ¤   {
373df4 ¤   ¤   PGPAppendOptionList(opts,
ed165c ¤   ¤   ¤   PGPOPasskeyBuffer(context,
41a3a2 ¤   ¤   ¤   ¤   ms->PassKey,ms->PassKeyLen),
7ae5ff ¤   ¤   ¤   PGPOLastOption(context));
249371 ¤   }
d7af5a
b1ffdb ¤   ms->fileName=OperationTarget;
6bcbaf ¤   strcpy((char *)ms->verifyName,ms->fileName);
c3894f ¤   ms->fileRef=0;
2219b1 ¤   ms->PassCount=0;
949eac ¤   ms->RecipientKeySet=0;
3cc9ac ¤   ms->RecipientKeyIDArray=0;
6d4fe7 ¤   ms->dwKeyIDCount=0;
4d8579 ¤   ms->obl=NULL;
9aaf5a
60aea7 ¤   LoadString (g_hinst, IDS_DECODINGFILE, StrRes, sizeof(StrRes));
1d6a79 ¤   sprintf(ms->ws.TitleText,StrRes,JustFile(ms->fileName));
35af5a
ccb930 ¤   SendMessage(ms->hwndWorking, PGPM_PROGRESS_UPDATE,
aeccdd ¤   ¤   (WPARAM)PGPSC_WORK_NEWFILE,0);
33af5a
76b23d ¤   PGPNewKeySet( context, &AddKeySet);
57af5a
0324ab ¤   err = PGPDecode( context,·
d7855a ¤   ¤   ¤   ¤   ¤   opts,
020dfc ¤   ¤   ¤   ¤   ¤   PGPOPassThroughIfUnrecognized(context,
870384 ¤   ¤   ¤   ¤   ¤   ¤   (PGPBoolean)(ms->Operation==MS_DECRYPTCLIPBOARD)),
c0c93d ¤   ¤   ¤   ¤   ¤   PGPOKeySetRef(context,ms->KeySet),
ec53e6 ¤   ¤   ¤   ¤   ¤   PGPOEventHandler(context,myEvents, ms),
e7202f ¤   ¤   ¤   ¤   ¤   PGPOImportKeysTo(context,AddKeySet),
b5fe17 ¤   ¤   ¤   ¤   ¤   PGPOSendNullEvents(context,75),
ab5927 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context) );
23af5a
61348d ¤   WorkingCallback (ms->hwndWorking,·
9c94c9 ¤   ¤   ms->ws.total,ms->ws.total);
4caf5a
ab7267 ¤   (void)PGPCountKeys( AddKeySet, &numKeys );
0bd86e ¤   if ( numKeys > 0)·
--135b 0006a39dc6d4011027c Page 2 of decrypt.c
a72ef1 ¤   {¤
5d0582 ¤   ¤   PGPclQueryAddKeys (context,ms->tlsContext,ms->hwndWorking,AddKeySet,NUL¶
6ce3f6 L);
f79371 ¤   }
8e9c4d ¤   PGPFreeKeySet (AddKeySet);
1baf5a
643f3d ¤   if(PGPRefIsValid(ms->AddedKeys))
ddc7a1 ¤   {
ad1ab5 ¤   ¤   (void)PGPCountKeys( ms->AddedKeys, &numKeys );
313a8f ¤   ¤   if ( numKeys > 0)·
00ed49 ¤   ¤   {¤
06a56b ¤   ¤   ¤   PGPclQueryAddKeys (context,ms->tlsContext,ms->hwndWorking,ms->Added¶
3761c5 Keys,NULL);
dd0fe4 ¤   ¤   }
3b2af3 ¤   ¤   PGPFreeKeySet (ms->AddedKeys);
f79371 ¤   }
acaf5a
3f7915 ¤   if(ms->RecipientKeySet)
62973a ¤   ¤   PGPFreeKeySet(ms->RecipientKeySet);
edaf5a
415b4d ¤   if(ms->RecipientKeyIDArray)
c98351 ¤   ¤   free(ms->RecipientKeyIDArray);
daaf5a
e85ea8 ¤   return err;
4eefe6 }
95af5a
2ebb18 PGPError DecryptShareFile (MYSTATE *ms,char *szFile)
bbbb36 {
4ca68d ¤   PFLFileSpecRef¤ ¤   fileref;
59d39f ¤   PGPShareFileRef¤¤   sharefileref;
5ff913 ¤   PGPOptionListRef¤   optionsDecode;
620e2e ¤   PGPOptionListRef¤   optionsEncode;
93c265 ¤   PGPShareRef¤¤   ¤   shares;
188f52 ¤   PGPError¤   ¤   ¤   err;
c6f7f4 ¤   PGPMemoryMgrRef¤¤   memoryMgr;
b7e853 ¤   BOOL¤   ¤   ¤   ¤   UserCancel;
fa7925 ¤   PGPContextRef¤  ¤   context;
e583f4 ¤   RECIPIENTDIALOGSTRUCT rds;
8e4fd2 ¤   PRECIPIENTDIALOGSTRUCT prds=&rds;
fdf341 ¤   PGPUInt32¤  ¤   ¤   numKeys;
42fdbe ¤   char¤   ¤   ¤   ¤   StrRes[500];
6caf5a
354ead ¤   err=kPGPError_NoErr;
c9af5a
142d85 ¤   context=ms->context;
ecaf5a
a3cc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
10af5a
f1aea7 ¤   LoadString (g_hinst, IDS_DECODINGFILE, StrRes, sizeof(StrRes));
0ed060 ¤   sprintf(ms->ws.TitleText,StrRes,JustFile(szFile));
09af5a
56b930 ¤   SendMessage(ms->hwndWorking, PGPM_PROGRESS_UPDATE,
30ccdd ¤   ¤   (WPARAM)PGPSC_WORK_NEWFILE,0);
bfaf5a
33a3b9 ¤   LoadString (g_hinst, IDS_SHAREFILEINFO, StrRes, sizeof(StrRes));
78af5a
4baa39 ¤   MessageBox(ms->hwndWorking,StrRes,
c5ad62 ¤   ¤   JustFile(szFile),MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);
b6af5a
271180 ¤   err = PFLNewFileSpecFromFullPath(memoryMgr, szFile, &fileref);
4faf5a
ddc8d0 ¤   if(IsntPGPError(err))
91c7a1 ¤   {
81a342 ¤   ¤   err = PGPOpenShareFile (fileref, &sharefileref);
8467c5 ¤
c84184 ¤   ¤   if(IsntPGPError(err))
a95b34 ¤   ¤   {
d09c3d ¤   ¤   ¤   ms->PassCount=0;
f906fb ¤   ¤   ¤   ms->RecipientKeySet=0;
480420 ¤   ¤   ¤   ms->RecipientKeyIDArray=0;
8914dc ¤   ¤   ¤   ms->dwKeyIDCount=0;
6aaf5a
--5f40 00069d4619f4011027c Page 3 of decrypt.c
46a037 ¤   ¤   ¤   // decrypt specified share file
a35fb6 ¤   ¤   ¤   PGPBuildOptionList (context, &optionsDecode,
67a117 ¤   ¤   ¤   ¤   PGPOKeySetRef (context, ms->KeySet),
776b65 ¤   ¤   ¤   ¤   PGPOEventHandler (context, myEvents, ms),
556a09 ¤   ¤   ¤   ¤   PGPOLastOption (context));
0067c5 ¤
45196e ¤   ¤   ¤   err = PGPCopySharesFromFile (context, sharefileref,·
67ec7d ¤   ¤   ¤   ¤   optionsDecode, &shares);
2567c5 ¤
cf3c68 ¤   ¤   ¤   if(PGPRefIsValid(ms->AddedKeys))
25f776 ¤   ¤   ¤   {
591d6c ¤   ¤   ¤   ¤   (void)PGPCountKeys( ms->AddedKeys, &numKeys );
2ca2d8 ¤   ¤   ¤   ¤   if ( numKeys > 0)·
426e50 ¤   ¤   ¤   ¤   {¤
e677db ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys (context,ms->tlsContext,ms->hwndWorking,
e1064f ¤   ¤   ¤   ¤   ¤   ¤   ms->AddedKeys,NULL);
dc2613 ¤   ¤   ¤   ¤   }
acb527 ¤   ¤   ¤   ¤   PGPFreeKeySet (ms->AddedKeys);
32a3a6 ¤   ¤   ¤   }
8faf5a
2e768c ¤   ¤   ¤   if(IsntPGPError(err))
19f776 ¤   ¤   ¤   {
7666ef ¤   ¤   ¤   ¤   memset(prds,0x00,sizeof(RECIPIENTDIALOGSTRUCT));
a9af5a
caed30 ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SHARERDTITLE, StrRes, sizeof(StrRes));
43af5a
7fbcc4 ¤   ¤   ¤   ¤   prds->Version=CurrentPGPrecipVersion;
1b6bde ¤   ¤   ¤   ¤   prds->hwndParent=ms->hwndWorking;
80ac3e ¤   ¤   ¤   ¤   prds->szTitle=StrRes;
8ed687 ¤   ¤   ¤   ¤   prds->Context=context;
4c5428 ¤   ¤   ¤   ¤   prds->tlsContext=ms->tlsContext;
4f439d ¤   ¤   ¤   ¤   prds->OriginalKeySetRef=ms->KeySet;
c16ecc ¤   ¤   ¤   ¤   prds->dwOptions=PGPCL_PASSONLY;
a7ffff ¤   ¤   ¤   ¤   prds->dwDisableFlags=PGPCL_DISABLE_ASCIIARMOR |
397e2a ¤   ¤   ¤   ¤   ¤   PGPCL_DISABLE_WIPEORIG |
39ed1f ¤   ¤   ¤   ¤   ¤   PGPCL_DISABLE_AUTOMODE |
08bad8 ¤   ¤   ¤   ¤   ¤   PGPCL_DISABLE_FYEO;
ecaf5a
177406 ¤   ¤   ¤   ¤   UserCancel = !(PGPclRecipientDialog(prds));
bbaf5a
7e8dae ¤   ¤   ¤   ¤   if(!UserCancel)
d872c3 ¤   ¤   ¤   ¤   {
d8494d ¤   ¤   ¤   ¤   ¤   if(prds->dwOptions & PGPCL_PASSONLY)
254859 ¤   ¤   ¤   ¤   ¤   {
895fd6 ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SHAREPASSPROMPT, StrRes, sizeo¶
c64a78 f(StrRes));
5daf5a
ccab6a ¤   ¤   ¤   ¤   ¤   ¤   UserCancel = PGPclGetPhrase (context,
ab1138 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ms->KeySet,
a9e5a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ms->hwndWorking,
fec7e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes,
5befc5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(ms->ConvPassPhrase),·
db99cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,
4d5d0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
fbceac ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
a999cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,
2c99cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,
47aafb ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_ENCRYPTION,
c85de3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,NULL,
e60082 ¤   ¤   ¤   ¤   ¤   ¤   ¤   1,0,ms->tlsContext,NULL);
21af5a
d3c307 ¤   ¤   ¤   ¤   ¤   ¤   if(!UserCancel)
058fec ¤   ¤   ¤   ¤   ¤   ¤   {
d701a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBuildOptionList( context, &optionsEncode,
bf222d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOConventionalEncrypt( context,
a904f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase( context, ms->ConvPassPhrase ),
ca0204 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) ),
61da9d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
8adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
951c89 ¤   ¤   ¤   ¤   ¤   }
544bd6 ¤   ¤   ¤   ¤   ¤   else
694859 ¤   ¤   ¤   ¤   ¤   {
--9ff8 0002fe11adb4011027c Page 4 of decrypt.c
2b01a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPBuildOptionList( context, &optionsEncode,
c457d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOEncryptToKeySet(context,prds->SelectedKeySe¶
d8d978 tRef),
acda9d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
781c89 ¤   ¤   ¤   ¤   ¤   }
012613 ¤   ¤   ¤   ¤   }
faaf5a
523c57 ¤   ¤   ¤   ¤   if(UserCancel)
3372c3 ¤   ¤   ¤   ¤   {
a4943d ¤   ¤   ¤   ¤   ¤   err=kPGPError_UserAbort;
122613 ¤   ¤   ¤   ¤   }
effa07 ¤   ¤   ¤   ¤   else
9d72c3 ¤   ¤   ¤   ¤   {
eb1858 ¤   ¤   ¤   ¤   ¤   err = PGPCopySharesToFile( context, sharefileref,·
3529db ¤   ¤   ¤   ¤   ¤   ¤   optionsEncode, shares );
c2af5a
f2a511 ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(err))
804859 ¤   ¤   ¤   ¤   ¤   {
4a9352 ¤   ¤   ¤   ¤   ¤   ¤   err = PGPSaveShareFile( sharefileref );
4d1c89 ¤   ¤   ¤   ¤   ¤   }
45af5a
268e00 ¤   ¤   ¤   ¤   ¤   PGPFreeOptionList(optionsEncode);
d92613 ¤   ¤   ¤   ¤   }
efaf5a
30b66d ¤   ¤   ¤   ¤   if(PGPRefIsValid(prds->AddedKeys))
2072c3 ¤   ¤   ¤   ¤   {
e4bad7 ¤   ¤   ¤   ¤   ¤   (void)PGPCountKeys( prds->AddedKeys, &numKeys );
b9e32b ¤   ¤   ¤   ¤   ¤   if ( numKeys > 0)·
cc55b9 ¤   ¤   ¤   ¤   ¤   {¤
e2ba6b ¤   ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys (context,ms->tlsContext,ms->hwndWorki¶
ce9b27 ng,
64ea13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   prds->AddedKeys,NULL);
2c1c89 ¤   ¤   ¤   ¤   ¤   }
51bd55 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (prds->AddedKeys);
672613 ¤   ¤   ¤   ¤   }
3aaf5a
9f835a ¤   ¤   ¤   ¤   if(ms->ConvPassPhrase)
be72c3 ¤   ¤   ¤   ¤   {
b44308 ¤   ¤   ¤   ¤   ¤   PGPclFreePhrase(ms->ConvPassPhrase);
12c95f ¤   ¤   ¤   ¤   ¤   ms->ConvPassPhrase=NULL;
352613 ¤   ¤   ¤   ¤   }
2eaf5a
0732ae ¤   ¤   ¤   ¤   if(prds->SelectedKeySetRef)
7015a0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
ccaf5a
341b37 ¤   ¤   ¤   ¤   PGPFreeShares (shares);
a8a3a6 ¤   ¤   ¤   }
fcaf5a
4fd44b ¤   ¤   if(ms->RecipientKeySet)
d78f6a ¤   ¤   ¤   PGPFreeKeySet(ms->RecipientKeySet);
f8af5a
9ad0b1 ¤   ¤   if(ms->RecipientKeyIDArray)
038d1d ¤   ¤   ¤   free(ms->RecipientKeyIDArray);
55af5a
12bc6b ¤   ¤   PGPFreeOptionList(optionsDecode);
4bd958 ¤   ¤   PGPFreeShareFile (sharefileref);
2c0fe4 ¤   ¤   }
f87e11 ¤   PFLFreeFileSpec (fileref);
b39371 ¤   }
c2af5a
1e5ea8 ¤   return err;
54efe6 }
c1af5a
c92960 PGPError MacBinaryConversion(PGPFileSpecRef fileRef)
d7bb36 {
390040 ¤   PGPError err;
3a441f ¤   PGPUInt32 macCreator,macTypeCode;
d32d33 ¤   PGPFileSpecRef deMacifiedFSpec;
32af5a
964ead ¤   err=kPGPError_NoErr;
f3af5a
2fbedc ¤   deMacifiedFSpec=0;
--e056 0003511553b4011027c Page 5 of decrypt.c
e0af5a
30f6cc ¤   err=PGPMacBinaryToLocal(fileRef,
d8308f ¤   ¤   &deMacifiedFSpec,
874a7d ¤   ¤   &macCreator,&macTypeCode );
fcaf5a
64074c ¤   if(deMacifiedFSpec)
6b7fb6 ¤   ¤   PGPFreeFileSpec(deMacifiedFSpec);
a9af5a
a85ea8 ¤   return err;
b7efe6 }
f5af5a
1e13e3 PGPError DecryptFileListStub (MYSTATE *ms)·
fcbb36 {
d064a2 ¤   PGPContextRef context;
40fa35 ¤   PGPFileSpecRef inref;
13db50 ¤   PGPOptionListRef opts;
130e89 ¤   FILELIST *FileCurrent;
880040 ¤   PGPError err;
46af5a
a54ead ¤   err=kPGPError_NoErr;
dcaf5a
772d85 ¤   context=ms->context;
09af5a
e3820b ¤   FileCurrent=ms->ListHead;
c9af5a
ed935f ¤   while(!(ms->ws.CancelPending)&&(FileCurrent!=0)&&(IsntPGPError(err)))
08fce6 ¤   { ···
677505 ¤   ¤   if(FileCurrent->IsDirectory)
c65b34 ¤   ¤   {
73f94b ¤   ¤   ¤   FileCurrent=FileCurrent->next;
1217f5 ¤   ¤   ¤   continue;
e10fe4 ¤   ¤   }
a0af5a
01ad41 ¤   ¤   if(FileHasThisExtension(FileCurrent->name,"shf"))
675b34 ¤   ¤   {
2a360d ¤   ¤   ¤   err=DecryptShareFile(ms,FileCurrent->name);
921b52 ¤   ¤
33619a ¤   ¤   ¤   FileCurrent=FileCurrent->next;¤ ¤   ¤
0c17f5 ¤   ¤   ¤   continue;
a80fe4 ¤   ¤   }
39af5a
ffa053 // events handler will ask for output file later...
ee79a5 ¤   ¤   PGPNewFileSpecFromFullPath( context,
ed0fc0 ¤   ¤   ¤   FileCurrent->name, &inref);
39af5a
25deef ¤   ¤   PGPBuildOptionList(context,&opts,
24d04d ¤   ¤   ¤   PGPOInputFile(context,inref),
dbc6f3 ¤   ¤   ¤   PGPOLastOption(context) );
73af5a
88f3e7 ¤   ¤   err=GenericDecVer(ms,opts,FileCurrent->name);
d2af5a
50041f ¤   ¤   PGPFreeOptionList(opts);
b6af5a
1f43b0 ¤   ¤   if((IsntPGPError(err))&&(ms->fileRef))
ac5b34 ¤   ¤   {
ff0262 ¤   ¤   ¤   err=MacBinaryConversion(ms->fileRef);
bfaf5a
6d206e ¤   ¤   ¤   // Try it.. if it's not, go on
ea2cb9 ¤   ¤   ¤   if(err=kPGPError_NotMacBinary)
29fcce ¤   ¤   ¤   ¤   err=kPGPError_NoErr;
30af5a
d60c0a ¤   ¤   ¤   PGPclEncDecErrorBox(ms->hwndWorking,err);
e50fe4 ¤   ¤   }
2aaf5a
306ee0 ¤   ¤   PGPFreeFileSpec(inref);
3aaf5a
6b3646 ¤   ¤   if(ms->fileRef)
475b35 ¤   ¤   ¤   PGPFreeFileSpec(ms->fileRef);
33af5a
0e0465 ¤   ¤   FileCurrent=FileCurrent->next;¤ ¤   ¤   ¤
a49371 ¤   }
35af5a
--b2bd 0004a4d6bfd4011027c Page 6 of decrypt.c
ec5ea8 ¤   return err;
2aefe6 }
e0af5a
a62d83 BOOL DecryptFileList(HWND hwnd,void *PGPsc,void *PGPtls,FILELIST *ListHead)
a6bb36 {
7964a2 ¤   PGPContextRef context;
5cc944 ¤   MYSTATE *ms;
f4b767 ¤   PGPtlsContextRef tls;
340040 ¤   PGPError err;
671375 ¤   char *pOutput;
55c2d1 ¤   DWORD dwOutputSize;
99414d ¤   BOOL FYEO;
8faf5a
514ead ¤   err=kPGPError_NoErr;
6faf5a
08625b ¤   context=(PGPContextRef)PGPsc;
a7db07 ¤   tls=(PGPtlsContextRef)PGPtls;
29af5a
49c933 ¤   if(IsPGPError(PGPclEvalExpired(hwnd, PGPCL_ALLEXPIRED)))
5498aa ¤   ¤   return FALSE;
a8af5a
55229d ¤   ms=(MYSTATE *)malloc(sizeof(MYSTATE));
15af5a
18a558 ¤   if(ms)
dfc7a1 ¤   {
f5e546 ¤   ¤   memset(ms, 0x00, sizeof(MYSTATE) );
1aaf5a
dbc589 ¤   ¤   LoadString (g_hinst, IDS_STARTINGWORK, ms->ws.StartText, sizeof(ms->ws.¶
833361 StartText));
7152f0 ¤   ¤   LoadString (g_hinst, IDS_FINISHINGUP, ms->ws.EndText, sizeof(ms->ws.End¶
33b48e Text));
5eaf5a
38e914 ¤   ¤   ms->context=context;
fd4e1f ¤   ¤   ms->tlsContext=tls;
1b57fa ¤   ¤   ms->ListHead=ListHead;
f5e24e ¤   ¤   ms->Operation=MS_DECRYPTFILELIST;
e3af5a
50fca7 ¤   ¤   if(OpenRings(hwnd,context,&(ms->KeySet)))
745b34 ¤   ¤   {
037220 ¤   ¤   ¤   err=DoWork(hwnd,ms);
1eaf5a
68f855 ¤   ¤   ¤   FreePhrases(ms);
9faf5a
e30ead // If we found no PGP data, warn....
89d04b ¤   ¤   ¤   if(!(ms->FoundPGPData))
320885 ¤   ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOPGPINFOINFILE,
ed14e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
e4af5a
f7156e ¤   ¤   ¤   if(!ConcatOutBuffList(context,ms->obl,&pOutput,&dwOutputSize,&FYEO))
86eb42 ¤   ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_OUTOFMEM,
0bbd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
40af5a
608cdc ¤   ¤   ¤   if(pOutput)
b9f776 ¤   ¤   ¤   {
425691 ¤   ¤   ¤   ¤   if((IsntPGPError(err))&&(FYEO))
a072c3 ¤   ¤   ¤   ¤   {
4a9835 ¤   ¤   ¤   ¤   ¤   TempestViewer((void *)context,hwnd,pOutput,dwOutputSize);
e32613 ¤   ¤   ¤   ¤   }
23af5a
cd3df1 ¤   ¤   ¤   ¤   memset(pOutput,0x00,dwOutputSize);
b81e0a ¤   ¤   ¤   ¤   PGPFreeData(pOutput); // Since auto alloced by CDK
dda3a6 ¤   ¤   ¤   }
87af5a
9d6449 ¤   ¤   ¤   PGPFreeKeySet(ms->KeySet);
da0fe4 ¤   ¤   }
d63d9b ¤   ¤   free(ms);
259371 ¤   }
042133 ¤   FreeFileList(ListHead);
0baf5a
3bee15 ¤   if(IsPGPError(err))
9298aa ¤   ¤   return FALSE;
4aaf5a
--399a 000de7004e54011027c Page 7 of decrypt.c
d6c2e7 ¤   return TRUE;
43efe6 }
7baf5a
75905f PGPError DecryptClipboardStub (MYSTATE *ms)·
72bb36 {
bfdb50 ¤   PGPOptionListRef opts;
c364a2 ¤   PGPContextRef context;
fc0040 ¤   PGPError err;
a16672 ¤   char StrRes[500];
c0af5a
d34ead ¤   err=kPGPError_NoErr;
65af5a
c52d85 ¤   context=ms->context;
91af5a
bee201 ¤   PGPBuildOptionList(context,&opts,
a2d3cd ¤   ¤   PGPOInputBuffer(context,ms->pInput,ms->dwInputSize),
988700 ¤   ¤   PGPOLastOption(context) );
57af5a
2edbec ¤   LoadString (g_hinst, IDS_CLIPBOARD, StrRes, sizeof(StrRes));
30af5a
ce2a37 ¤   err=GenericDecVer(ms,opts,StrRes);
abaf5a
ffbf49 ¤   PGPFreeOptionList(opts);
8767c5 ¤
355ea8 ¤   return err;
40efe6 }
44af5a
18d237 BOOL DecryptClipboard(HWND hwnd,void *PGPsc,void *PGPtls)
84bb36 {
827925 ¤   PGPContextRef¤  ¤   context;
75c944 ¤   MYSTATE *ms;
07274e ¤   char *pInput;
41b1a1 ¤   DWORD dwInputSize;
606a53 ¤   UINT ClipboardFormat;
ceb767 ¤   PGPtlsContextRef tls;
a00040 ¤   PGPError err;
851375 ¤   char *pOutput;
dbc2d1 ¤   DWORD dwOutputSize;
01414d ¤   BOOL FYEO;
b5af5a
58acbf ¤   // Check for files copied into clipboard from explorer
308489 ¤   if(OpenClipboard(hwnd))·
34c7a1 ¤   {
41ae67 ¤   ¤   if(IsClipboardFormatAvailable(CF_HDROP))
815b34 ¤   ¤   {
0816d5 ¤   ¤   ¤   FILELIST *ListHead;
db20dc ¤   ¤   ¤   HDROP hDrop;
baaf5a
c60224 ¤   ¤   ¤   hDrop=(HDROP)GetClipboardData(CF_HDROP);
db0137 ¤   ¤   ¤   ListHead=HDropToFileList(hDrop);
87af5a
43a801 ¤   ¤   ¤   if(ListHead!=0)
b6f776 ¤   ¤   ¤   {
a1e73d ¤   ¤   ¤   ¤   CloseClipboard();
04af5a
8161d9 ¤   ¤   ¤   ¤   return DecryptFileList(hwnd,
8ed67a ¤   ¤   ¤   ¤   ¤   PGPsc,PGPtls,ListHead);
f3a3a6 ¤   ¤   ¤   }
e90fe4 ¤   ¤   }
f15961 ¤   ¤   CloseClipboard();
df9371 ¤   }
ccaf5a
f84ead ¤   err=kPGPError_NoErr;
b2af5a
2a625b ¤   context=(PGPContextRef)PGPsc;
b8db07 ¤   tls=(PGPtlsContextRef)PGPtls;
99af5a
1ac933 ¤   if(IsPGPError(PGPclEvalExpired(hwnd, PGPCL_ALLEXPIRED)))
4898aa ¤   ¤   return FALSE;
b4af5a
6b3a14 ¤   pInput=RetrieveClipboardData(hwnd, &ClipboardFormat,·
de1c44 ¤   ¤   ¤   ·····················&dwInputSize);
--24d9 0006125b7da4011027c Page 8 of decrypt.c
e0af5a
826505 ¤   if(!pInput)
a4c7a1 ¤   {
0fe6fe ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOCLIPBOARDCONTENTS,
bc2d15 ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
a29371 ¤   }
610e24 ¤   else
16c7a1 ¤   {
766096 ¤   ¤   if((ClipboardFormat != CF_TEXT)||(*pInput==0))
655b34 ¤   ¤   {
e482f4 ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOCLIPBOARDTEXT,
44e840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
0c0fe4 ¤   ¤   }
2b0e1d ¤   ¤   else
a65b34 ¤   ¤   {
af6bb7 ¤   ¤   ¤   ms=(MYSTATE *)malloc(sizeof(MYSTATE));
3daf5a
952641 ¤   ¤   ¤   if(ms)
fdf776 ¤   ¤   ¤   {
086b57 ¤   ¤   ¤   ¤   memset(ms, 0x00, sizeof(MYSTATE) );
f4af5a
5f4341 ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_STARTINGWORK, ms->ws.StartText, sizeof¶
007fbd (ms->ws.StartText));
3fcdd3 ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_FINISHINGUP, ms->ws.EndText, sizeof(ms¶
787f17 ->ws.EndText));
ddaf5a
516f2a ¤   ¤   ¤   ¤   ms->context=context;
5e68bd ¤   ¤   ¤   ¤   ms->tlsContext=tls;
edcb21 ¤   ¤   ¤   ¤   ms->pInput=pInput;
877a1e ¤   ¤   ¤   ¤   ms->dwInputSize=dwInputSize;
97767a ¤   ¤   ¤   ¤   ms->Operation=MS_DECRYPTCLIPBOARD;
b4af5a
8851d1 ¤   ¤   ¤   ¤   if(OpenRings(hwnd,context,&(ms->KeySet)))
da72c3 ¤   ¤   ¤   ¤   {
834aa5 ¤   ¤   ¤   ¤   ¤   err=DoWork(hwnd,ms);
5467c5 ¤
077e6b ¤   ¤   ¤   ¤   ¤   FreePhrases(ms);
ceaf5a
b0129a // If no PGP data in clipboard, warn....
7e9d78 ¤   ¤   ¤   ¤   ¤   if(!(ms->FoundPGPData))
dff67f ¤   ¤   ¤   ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOPGPINFOCLIPBOA¶
3cacbe RD,
3714e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
0eaf5a
ee59ca ¤   ¤   ¤   ¤   ¤   if(!ConcatOutBuffList(context,ms->obl,&pOutput,&dwOutputSiz¶
1f0097 e,&FYEO))
eb6671 ¤   ¤   ¤   ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_OUTOFMEM,
a2bd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
4faf5a
bdd7e7 ¤   ¤   ¤   ¤   ¤   if(pOutput)
ec4859 ¤   ¤   ¤   ¤   ¤   {
659cd4 ¤   ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(err))
7b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
faf62e ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(FYEO)
7706b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
0d642e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TempestViewer((void *)context,hwnd,pOutput,dwOu¶
ad998c tputSize);
025268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
dbc4dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
1c06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
8b392c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TextViewer(hwnd,pOutput,dwOutputSize);
e15268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
cedb3c ¤   ¤   ¤   ¤   ¤   ¤   }
16af5a
bd2bed ¤   ¤   ¤   ¤   ¤   ¤   memset(pOutput,0x00,dwOutputSize);
676fb1 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(pOutput);·
941c89 ¤   ¤   ¤   ¤   ¤   }
99af5a
6afb9d ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(ms->KeySet);
bf2613 ¤   ¤   ¤   ¤   }
6057b5 ¤   ¤   ¤   ¤   free(ms);¤  ¤   ¤
61a3a6 ¤   ¤   ¤   }
--f0ef 001634cee4f4011027c Page 9 of decrypt.c
b50fe4 ¤   ¤   }
310559 ¤   ¤   memset(pInput,0x00,dwInputSize);
d0742f ¤   ¤   free(pInput);
829371 ¤   }
54af5a
f1ee15 ¤   if(IsPGPError(err))
7e98aa ¤   ¤   return FALSE;
4aaf5a
61c2e7 ¤   return TRUE;
74efe6 }
7caf5a
be7e4d /*__Editor_settings____
94af5a
a04126 ¤   Local Variables:
f67b17 ¤   tab-width: 4
650e6c ¤   End:
085f8c ¤   vi: ts=4 sw=4
4d9e9b ¤   vim: si
63d062 _____________________*/
--50a9 000bd37ef2e4011027d Page 1 of encrypt.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7dfab8 ¤   $Id: encrypt.c,v 1.119.2.2.2.1 1998/11/12 03:13:34 heller Exp $
3cf7f7 ____________________________________________________________________________*/
235ed8 #include "precomp.h"
d3af5a
682224 BOOL GetCommentLine(PGPContextRef context,
84842d ¤   ¤   ¤   ¤   ¤   char *comment,PGPSize size,PGPUInt32 *PrefAlg,
26c668 ¤   ¤   ¤   ¤   ¤   PGPCipherAlgorithm *pAllowedAlgs, int *pNumAlgs)
e5bb36 {
1c1fb9 ¤   PGPPrefRef¤ ClientPrefRef=NULL;
ea14c1 ¤   PGPPrefRef¤ AdminPrefRef=NULL;
4761e0 ¤   PGPError¤   err;
368e46 ¤   BOOL RetVal;
4eed37 ¤   PGPMemoryMgrRef memMgr;
10af5a
ad89c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
10af5a
c216e1 ¤   RetVal=TRUE;
44af5a
d0a378 ¤   *comment=0;
526e69 ¤   *PrefAlg=kPGPCipherAlgorithm_CAST5;
c3af5a
58f270 #if PGP_BUSINESS_SECURITY || PGP_ADMIN_BUILD
613580 #if PGP_ADMIN_BUILD¤¤   ¤   ¤
e20f31 ¤   err = PGPclOpenAdminPrefs (memMgr,&AdminPrefRef, TRUE);
9bdb21 #else
adbb73 ¤   err = PGPclOpenAdminPrefs (memMgr,&AdminPrefRef, FALSE);
5ed835 #endif¤ // PGP_BUSINESS_SECURITY_ADMIN
c00fc8 ¤   if (IsPGPError (err))·
b177d2 ¤   ¤   return FALSE;¤  // error-out
b0af5a
f4643c ¤   err=PGPGetPrefStringBuffer(AdminPrefRef,
fdb167 ¤   ···kPGPPrefComments,
1daef3 ¤   ···size,
cac320 ¤   ···comment);
a6af5a
1fd8e7 ¤   PGPclCloseAdminPrefs (AdminPrefRef, FALSE);
c797b2 #endif¤ // PGP_BUSINESS_SECURITY
9daf5a
e78ecc ¤   err=PGPclOpenClientPrefs (memMgr,&ClientPrefRef);
0ec8d0 ¤   if(IsntPGPError(err))
a6c7a1 ¤   {
df8b39 ¤   ¤   PGPCipherAlgorithm *pData;
310b1c ¤   ¤   PGPSize¤dataLength;
ac2a1e ¤   ¤   int i;
07af5a
ed039d ¤   ¤   PGPGetPrefNumber(ClientPrefRef,
33df32 ¤   ¤   ¤   kPGPPrefPreferredAlgorithm,·
a52191 ¤   ¤   ¤   PrefAlg);
4daf5a
602ca3 ¤   ¤   err = PGPGetPrefData(ClientPrefRef,
7b6df5 ¤   ¤   ¤   kPGPPrefAllowedAlgorithmsList,·
a5ab5f ¤   ¤   ¤   &dataLength, (void **) &pData);
afaf5a
9ce2b3 ¤   ¤   if (IsntPGPError(err))
135b34 ¤   ¤   {
e4b810 ¤   ¤   ¤   *pNumAlgs = dataLength / sizeof(PGPCipherAlgorithm);
46042b ¤   ¤   ¤   for (i=0; i<*pNumAlgs; i++)
165bff ¤   ¤   ¤   ¤   pAllowedAlgs[i] = pData[i];
54af5a
b9744c ¤   ¤   ¤   PGPDisposePrefData(ClientPrefRef, (void *) pData);
4b0fe4 ¤   ¤   }
ae0e1d ¤   ¤   else
fea622 ¤   ¤   ¤   *pNumAlgs = 0;
ddaf5a
6384df ¤   ¤   if(*comment==0)
bd5b34 ¤   ¤   {
--7b55 0003bef7b804011027d Page 2 of encrypt.c
bb2027 ¤   ¤   ¤   PGPGetPrefStringBuffer(ClientPrefRef,
8f4b1e ¤   ¤   ¤   ¤   kPGPPrefComment,
f22981 ¤   ¤   ¤   ¤   size,
ac20fa ¤   ¤   ¤   ¤   comment);
940fe4 ¤   ¤   }
0b0ef1 ¤   ¤   PGPclCloseClientPrefs (ClientPrefRef, FALSE);
309371 ¤   }
7c67c5 ¤
c742d7 ¤   return RetVal;
7cefe6 }
f7af5a
0c25c5 PGPError GenericEncSign(MYSTATE *ms,
e4d421 ¤   ¤   ¤   ¤   ¤   PGPOptionListRef opts,
fe99eb ¤   ¤   ¤   ¤   ¤   char *OperationTarget)
34bb36 {
d80040 ¤   PGPError err;
2fd7fd ¤   int UserCancel;
8d585a ¤   PGPBoolean DataIsASCII;
10c92b ¤   PGPUInt32 numKeys;
8928da ¤   PRECIPIENTDIALOGSTRUCT prds;
948a97 ¤   PGPContextRef¤  context;
016672 ¤   char StrRes[500];
3e593d ¤   PGPBoolean FYEO;
f9af5a
7ae414 ¤   err=kPGPError_NoErr;¤
6367c5 ¤
722d85 ¤   context=ms->context;
d8af5a
c682b0 ¤   prds=ms->prds;
5caf5a
f8304f ¤   // If this is first operation, put up recipient/sign dialog
28af5a
5ead7f ¤   if(ms->numDone==0)
b1c7a1 ¤   {
b9cc08 ¤   ¤   FreePhrases(ms);
63af5a
0b7645 ¤   ¤   if(ms->Encrypt)
f05b34 ¤   ¤   {
57afc2 ¤   ¤   ¤   int RecipientReturn;
7daf5a
5d981c ¤   ¤   ¤   LoadString (g_hinst, IDS_PGPKEYSELDLG, StrRes, sizeof(StrRes));
94af5a
8612c5 ¤   ¤   ¤   prds->Version=CurrentPGPrecipVersion;
0924e0 ¤   ¤   ¤   prds->hwndParent=ms->hwndWorking;
55434d ¤   ¤   ¤   prds->szTitle=StrRes;
943e2f ¤   ¤   ¤   prds->Context=ms->context;
5806b5 ¤   ¤   ¤   prds->tlsContext=ms->tlsContext;
fed5dc ¤   ¤   ¤   prds->OriginalKeySetRef=ms->KeySet;
12af5a
012175 ¤   ¤   ¤   prds->dwDisableFlags|=PGPCL_DISABLE_FYEO;
85af5a
e5686c ¤   ¤   ¤   // FYEO only for clipboard or text files
e45c12 ¤   ¤   ¤   if((ms->Operation==MS_ENCRYPTCLIPBOARD) ||
073cd9 ¤   ¤   ¤   ¤   (FileHasThisExtension(OperationTarget,"txt")))
0df776 ¤   ¤   ¤   {
6a11aa ¤   ¤   ¤   ¤   prds->dwDisableFlags&=(~PGPCL_DISABLE_FYEO);
72a3a6 ¤   ¤   ¤   }
d4af5a
f5aebd ¤   ¤   ¤   RecipientReturn = PGPclRecipientDialog(prds);
c7af5a
9d58e4 ¤   ¤   ¤   if(!RecipientReturn)
07398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
04af5a
957565 ¤   ¤   ¤   if(prds->dwOptions & PGPCL_PASSONLY)
adf776 ¤   ¤   ¤   {
707e4d ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_CONVPASSPROMPT, StrRes, sizeof(StrRes)¶
f26275 );
1eaf5a
7e4a1d ¤   ¤   ¤   ¤   UserCancel = PGPclGetPhrase (context,
c05f91 ¤   ¤   ¤   ¤   ¤   ms->KeySet,
dce6fc ¤   ¤   ¤   ¤   ¤   ms->hwndWorking,
3be14a ¤   ¤   ¤   ¤   ¤   StrRes,
--875a 000db9f27464011027d Page 3 of encrypt.c
5a61d4 ¤   ¤   ¤   ¤   ¤   &(ms->ConvPassPhrase),·
bf2797 ¤   ¤   ¤   ¤   ¤   NULL,
0cc55d ¤   ¤   ¤   ¤   ¤   NULL,·
4a3865 ¤   ¤   ¤   ¤   ¤   0,
b62797 ¤   ¤   ¤   ¤   ¤   NULL,
c32797 ¤   ¤   ¤   ¤   ¤   NULL,
ccafd0 ¤   ¤   ¤   ¤   ¤   PGPCL_ENCRYPTION,
6e906f ¤   ¤   ¤   ¤   ¤   NULL,NULL,
0ce1bd ¤   ¤   ¤   ¤   ¤   1,0,ms->tlsContext,NULL);
c3af5a
df3c57 ¤   ¤   ¤   ¤   if(UserCancel)
0821dd ¤   ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
59a3a6 ¤   ¤   ¤   }
b4af5a
d40fe4 ¤   ¤   }
f9af5a
f07fe9 ¤   ¤   if(ms->Sign)
b05b34 ¤   ¤   {
9345a6 ¤   ¤   ¤   DWORD *lpOptions;
50fd6f ¤   ¤   ¤   PGPError err;
33af5a
ba594b ¤   ¤   ¤   lpOptions=&(prds->dwOptions);
58af5a
7de0a8 ¤   ¤   ¤   if (ms->Encrypt || (ms->Operation==MS_ENCRYPTCLIPBOARD))
341291 ¤   ¤   ¤   ¤   lpOptions=0;
8aaf5a
deda18 ¤   ¤   ¤   LoadString (g_hinst, IDS_PASSPROMPTABOVEKEY, StrRes, sizeof(StrRes)¶
076275 );
c1af5a
0bb4fb ¤   ¤   ¤   err=PGPclGetCachedSigningPhrase (context,
b688ae ¤   ¤   ¤   ¤   ms->tlsContext,
f1f73a ¤   ¤   ¤   ¤   ms->hwndWorking,·
30172f ¤   ¤   ¤   ¤   StrRes,
c25f18 ¤   ¤   ¤   ¤   FALSE, // ForceEntry
168fe7 ¤   ¤   ¤   ¤   &ms->PassPhrase,
6ff2cf ¤   ¤   ¤   ¤   ms->KeySet,
65a841 ¤   ¤   ¤   ¤   &(ms->SignKey),
2ce022 ¤   ¤   ¤   ¤   NULL,
942aab ¤   ¤   ¤   ¤   lpOptions,
742f85 ¤   ¤   ¤   ¤   prds->dwFlags,
1585e7 ¤   ¤   ¤   ¤   &ms->PassKey,
73cde1 ¤   ¤   ¤   ¤   &ms->PassKeyLen,
753b6d ¤   ¤   ¤   ¤   NULL);
5287c7 ¤   ¤   ¤
58cf3e ¤   ¤   ¤   if(err != kPGPError_NoErr)
6af776 ¤   ¤   ¤   {
be0f7d ¤   ¤   ¤   ¤   PGPclEncDecErrorBox(ms->hwndWorking,err);
49afc9 ¤   ¤   ¤   ¤   return kPGPError_UserAbort; // UserCancel·
faa3a6 ¤   ¤   ¤   }
930fe4 ¤   ¤   }
7ba614 ¤   } // END of first operation recipient/sign dialog stuff
b5af5a
c3763b ¤   // if encrypting, throw in recipients
a30cb1 ¤   if(ms->Encrypt)
5fc7a1 ¤   {
0227f8 ¤   ¤   if(prds->dwOptions & PGPCL_PASSONLY)
c85b34 ¤   ¤   {
a88485 ¤   ¤   ¤   int ConvPassLen;
16af5a
e5b2ec ¤   ¤   ¤   ConvPassLen = strlen(ms->ConvPassPhrase);
c2af5a
8bd287 ¤   ¤   ¤   PGPAppendOptionList(opts,
aac811 ¤   ¤   ¤   ¤   PGPOConventionalEncrypt(context,·
eecd20 ¤   ¤   ¤   ¤   ¤   PGPOPassphraseBuffer(context,ms->ConvPassPhrase,
3a8dff ¤   ¤   ¤   ¤   ¤   ¤   ConvPassLen),
ab590c ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context) ),
7e06b5 ¤   ¤   ¤   ¤   PGPOCipherAlgorithm(context,ms->PrefAlg),
1ac8bf ¤   ¤   ¤   ¤   PGPOLastOption(context) );
d20fe4 ¤   ¤   }
d60e1d ¤   ¤   else
265b34 ¤   ¤   {
dbd287 ¤   ¤   ¤   PGPAppendOptionList(opts,
--b3eb 0003e5be3504011027d Page 4 of encrypt.c
852f98 ¤   ¤   ¤   ¤   PGPOEncryptToKeySet(context,prds->SelectedKeySetRef),
35c8bf ¤   ¤   ¤   ¤   PGPOLastOption(context) );
760fe4 ¤   ¤   }
ea9371 ¤   }
acaf5a
67ec0d ¤   if(ms->Sign) ·// If signing, throw in a passphrase and key
b4c7a1 ¤   {
099131 ¤   ¤   // Use passkey if available
196b49 ¤   ¤   if(ms->PassKey)
b65b34 ¤   ¤   {
1fd287 ¤   ¤   ¤   PGPAppendOptionList(opts,
508e4f ¤   ¤   ¤   ¤   PGPOSignWithKey(context,ms->SignKey,
6b8988 ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer(context,
94a224 ¤   ¤   ¤   ¤   ¤   ¤   ms->PassKey,ms->PassKeyLen),
5781be ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context) ),
71c8bf ¤   ¤   ¤   ¤   PGPOLastOption(context) );
760fe4 ¤   ¤   }
e70e1d ¤   ¤   else
1b5b34 ¤   ¤   {
f5d287 ¤   ¤   ¤   PGPAppendOptionList(opts,
6c8e4f ¤   ¤   ¤   ¤   PGPOSignWithKey(context,ms->SignKey,
4f81be ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context) ),
9bc8bf ¤   ¤   ¤   ¤   PGPOLastOption(context) );
8e0fe4 ¤   ¤   }
669371 ¤   }
a2af5a
0c1b3b ¤   if((prds->dwOptions & PGPCL_DETACHEDSIG) &&
393d38 ¤   ¤   !(ms->Operation==MS_ENCRYPTCLIPBOARD) &&·
d33a52 ¤   ¤   (ms->Sign) && !(ms->Encrypt))
c7c7a1 ¤   {
3f3df4 ¤   ¤   PGPAppendOptionList(opts,
0ce710 ¤   ¤   ¤   PGPODetachedSig(context,
c02d0d ¤   ¤   ¤   ¤   PGPOLastOption(context)),·
ade5ff ¤   ¤   ¤   PGPOLastOption(context));
119371 ¤   }
c10e24 ¤   else
3e7181 ¤   ¤   prds->dwOptions&=(~PGPCL_DETACHEDSIG);
26af5a
c64094 ¤   DataIsASCII=(ms->Operation==MS_ENCRYPTCLIPBOARD);
0aaf5a
f511f2 ¤   // If we have text out arguments....
2adfd8 ¤   if(prds->dwOptions & PGPCL_ASCIIARMOR)
63c7a1 ¤   {
eeba0e ¤   ¤   if((ms->Operation==MS_ENCRYPTCLIPBOARD) &&·
5c3fec ¤   ¤   ¤   (ms->Sign) && !(ms->Encrypt) &&·
be2828 ¤   ¤   ¤   ((prds->dwOptions & PGPCL_DETACHEDSIG)==0))·
42f01f ¤   ¤   { // Clearsign!
58d287 ¤   ¤   ¤   PGPAppendOptionList(opts,
d0ffc4 ¤   ¤   ¤   ¤   PGPOClearSign(context, TRUE),
a4d911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
910fe4 ¤   ¤   }
c197ec ¤   ¤   else if(!(ms->Operation==MS_ENCRYPTCLIPBOARD) &&·
463fec ¤   ¤   ¤   (ms->Sign) && !(ms->Encrypt) &&·
5a626a ¤   ¤   ¤   ((prds->dwOptions & PGPCL_DETACHEDSIG)==0)&&
afc7ae ¤   ¤   ··FileHasThisExtension(OperationTarget,"txt"))·
efba99 ¤   ¤   { // Clearsign a .txt file
5f599d ¤   ¤   ¤   DataIsASCII=TRUE; // Set to ASCII input
66af5a
24d287 ¤   ¤   ¤   PGPAppendOptionList(opts,
79ffc4 ¤   ¤   ¤   ¤   PGPOClearSign(context, TRUE),
3cd911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
318469 ¤   ¤   }·
e0c6eb ¤   ¤   else // Just Ascii Armor*/
0e5b34 ¤   ¤   {
0fd287 ¤   ¤   ¤   PGPAppendOptionList(opts,
86659c ¤   ¤   ¤   ¤   PGPOArmorOutput(context, TRUE),
8fd911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
670fe4 ¤   ¤   }
ab9371 ¤   }
1aaf5a
cca8ae ¤   if(*(ms->comment)!=0)
3ec7a1 ¤   {
--8140 000c801547f4011027d Page 5 of encrypt.c
8a3df4 ¤   ¤   PGPAppendOptionList(opts,
f474e1 ¤   ¤   ¤   PGPOCommentString(context,(ms->comment)),
59e5ff ¤   ¤   ¤   PGPOLastOption(context));
df9371 ¤   }
d5af5a
b0ffdb ¤   ms->fileName=OperationTarget;
4baf5a
f16d15 ¤   LoadString (g_hinst, IDS_ENCODINGFILE, StrRes, sizeof(StrRes));
186a79 ¤   sprintf(ms->ws.TitleText,StrRes,JustFile(ms->fileName));
22af5a
c0b930 ¤   SendMessage(ms->hwndWorking, PGPM_PROGRESS_UPDATE,
06ccdd ¤   ¤   (WPARAM)PGPSC_WORK_NEWFILE,0);
1eaf5a
991793 ¤   if(!(ms->Operation==MS_ENCRYPTCLIPBOARD))
51c7a1 ¤   {
10c8d5 ¤   ¤   char outname[MAX_PATH];
b4af5a
feb2a6 ¤   ¤   ms->fileRef=0;
1a82c1 ¤   ¤   strcpy(outname,ms->fileName);
d8af5a
b7af2d ¤   ¤   AlterEncryptedFileName(outname,prds->dwOptions);
85af5a
3d7983 ¤   ¤   LoadString (g_hinst, IDS_ENCFILENAMEPROMPT, StrRes, sizeof(StrRes));
75af5a
f95449 ¤   ¤   UserCancel=SaveOutputFile(context,
18c032 ¤   ¤   ¤   ms->hwndWorking,·
7c6ddb ¤   ¤   ¤   StrRes,
9e0dc5 ¤   ¤   ¤   outname,
a12036 ¤   ¤   ¤   &(ms->fileRef),
96d54e ¤   ¤   ¤   FALSE);
20af5a
0dca9e ¤   ¤   if(UserCancel)
7cb1eb ¤   ¤   ¤   return kPGPError_UserAbort;
3faf5a
d83df4 ¤   ¤   PGPAppendOptionList(opts,
75c56c ¤   ¤   ¤   PGPOOutputFile(context,ms->fileRef),
c1e5ff ¤   ¤   ¤   PGPOLastOption(context));
ff9371 ¤   }
82af5a
db60f5 ¤   // Assume False for For Your Eyes Only
f4e8db ¤   FYEO=FALSE;
8faf5a
809263 ¤   // These are the only situations we can have FYEO
629587 ¤   if((ms->Operation==MS_ENCRYPTCLIPBOARD) ||
1f3b00 ¤   ¤   (FileHasThisExtension(OperationTarget,"txt")))
78c7a1 ¤   {
eac5d9 ¤   ¤   // If the recipient dialog has selected it then we're OK
6afc3c ¤   ¤   if((prds->dwOptions & PGPCL_FYEO)==PGPCL_FYEO)
e95b34 ¤   ¤   {
43b465 ¤   ¤   ¤   FYEO=TRUE;
ae0fe4 ¤   ¤   }
e89371 ¤   }
a3af5a
fdac99 ¤   err = PGPEncode(context,
6dfdc0 ¤   ¤   opts,
c11383 ¤   ¤   PGPOPreferredAlgorithms(context,ms->allowedAlgs,ms->nNumAlgs),
0af860 ¤   ¤   PGPOSendNullEvents(context,75),
02bf45 ¤   ¤   PGPOEventHandler(context,myEvents,ms),
154380 ¤   ¤   PGPOVersionString(context,pgpVersionHeaderString),
3ddf3c ¤   ¤   PGPOAskUserForEntropy(context, TRUE),
a500b6 ¤   ¤   PGPODataIsASCII(context,DataIsASCII),
be3959 ¤   ¤   PGPOForYourEyesOnly(context,FYEO),
cd0a8c ¤   ¤   PGPOLastOption(context));
a0af5a
46348d ¤   WorkingCallback (ms->hwndWorking,·
fa94c9 ¤   ¤   ms->ws.total,ms->ws.total);
dbaf5a
b7f10b ¤   if(PGPRefIsValid(prds->AddedKeys))
00c7a1 ¤   {
4dcc0e ¤   ¤   (void)PGPCountKeys( prds->AddedKeys, &numKeys );
e73a8f ¤   ¤   if ( numKeys > 0)·
c8ed49 ¤   ¤   {¤
--b518 000b65725674011027d Page 6 of encrypt.c
284a57 ¤   ¤   ¤   PGPclQueryAddKeys (context,ms->tlsContext,ms->hwndWorking,
37ad75 ¤   ¤   ¤   ¤   prds->AddedKeys,NULL);
0d0fe4 ¤   ¤   }
72ba6b ¤   ¤   PGPFreeKeySet (prds->AddedKeys);
729371 ¤   }
6aaf5a
b85ea8 ¤   return err;
8aefe6 }
27af5a
9c7277 PGPError EncryptFileListStub (MYSTATE *ms)·
35bb36 {
2464a2 ¤   PGPContextRef context;
aafa35 ¤   PGPFileSpecRef inref;
2edb50 ¤   PGPOptionListRef opts;
ca0e89 ¤   FILELIST *FileCurrent;
5c0040 ¤   PGPError err;
4eaf5a
a94ead ¤   err=kPGPError_NoErr;
ecaf5a
222d85 ¤   context=ms->context;
cbaf5a
95820b ¤   FileCurrent=ms->ListHead;
c6af5a
ae935f ¤   while(!(ms->ws.CancelPending)&&(FileCurrent!=0)&&(IsntPGPError(err)))
fd5f2f ¤   { ··
437505 ¤   ¤   if(FileCurrent->IsDirectory)
545b34 ¤   ¤   {
4bf94b ¤   ¤   ¤   FileCurrent=FileCurrent->next;
8017f5 ¤   ¤   ¤   continue;
950fe4 ¤   ¤   }
e9af5a
a9be1b // We'll ask for output file in event handler later...
4679a5 ¤   ¤   PGPNewFileSpecFromFullPath( context,
fe0fc0 ¤   ¤   ¤   FileCurrent->name, &inref);
a2af5a
19deef ¤   ¤   PGPBuildOptionList(context,&opts,
b9d04d ¤   ¤   ¤   PGPOInputFile(context,inref),
a8e5ff ¤   ¤   ¤   PGPOLastOption(context));
eb67c5 ¤
60591d ¤   ¤   err=GenericEncSign(ms,opts,FileCurrent->name);
95af5a
75041f ¤   ¤   PGPFreeOptionList(opts);
59af5a
fe39a5 ¤   ¤   PGPFreeFileSpec( inref );
6baf5a
373646 ¤   ¤   if(ms->fileRef)
d85b35 ¤   ¤   ¤   PGPFreeFileSpec(ms->fileRef);
87af5a
dcfd0c ¤   ¤   if((IsntPGPError(err))&&(ms->prds->dwOptions & PGPCL_WIPEORIG))
d75b34 ¤   ¤   {
3bf7ca ¤   ¤   ¤   char TempStart[40];
f3738e ¤   ¤   ¤   char TempEnd[40];
3c10be ¤   ¤   ¤   UINT WipeReturn;
e7af5a
b2c317 ¤   ¤   ¤   strcpy(TempStart,ms->ws.StartText);
17baa1 ¤   ¤   ¤   strcpy(TempEnd,ms->ws.EndText);
10af5a
ca3f9c ¤   ¤   ¤   strcpy(ms->ws.StartText,"");
f97aa1 ¤   ¤   ¤   strcpy(ms->ws.EndText,"");
c3af5a
780192 ¤   ¤   ¤   WipeReturn=InternalFileWipe(ms->context,
a1db94 ¤   ¤   ¤   ¤   ms->hwndWorking,
e9eea3 ¤   ¤   ¤   ¤   FileCurrent->name);
55af5a
b48d91 ¤   ¤   ¤   if(WipeReturn!=WIPE_OK)
34f776 ¤   ¤   ¤   {
d4ee38 ¤   ¤   ¤   ¤   if (WipeError(ms->hwndWorking,
facdec ¤   ¤   ¤   ¤   ¤   FileCurrent,WipeReturn))
cd72c3 ¤   ¤   ¤   ¤   {
a97ac6 ¤   ¤   ¤   ¤   ¤   err=kPGPError_UnknownError;
6d2613 ¤   ¤   ¤   ¤   }
b6a3a6 ¤   ¤   ¤   }
--45db 0009bb7b6404011027d Page 7 of encrypt.c
e0af5a
08f3f5 ¤   ¤   ¤   strcpy(ms->ws.StartText,TempStart);
3d1b21 ¤   ¤   ¤   strcpy(ms->ws.EndText,TempEnd);
db0fe4 ¤   ¤   }
c4af5a
1793bd ¤   ¤   ms->numDone++;
970465 ¤   ¤   FileCurrent=FileCurrent->next;¤ ¤   ¤   ¤
009371 ¤   }
fbaf5a
8f5ea8 ¤   return err;
54efe6 }
62af5a
0f8096 BOOL EncryptFileList(HWND hwnd,
5863a5 ¤   ¤   ¤   ¤   ¤   ·void *PGPsc,
4e617c ¤   ¤   ¤   ¤   ¤   ·void *PGPtls,
83b166 ¤   ¤   ¤   ¤   ¤   ·FILELIST *ListHead,
a224f5 ¤   ¤   ¤   ¤   ¤   ·BOOL bEncrypt,·
063ccf ¤   ¤   ¤   ¤   ¤   ·BOOL bSign)
cbaf5a
90bb36 {
9e64a2 ¤   PGPContextRef context;
6b28da ¤   PRECIPIENTDIALOGSTRUCT prds;
c7c944 ¤   MYSTATE *ms;
aad00b ¤   char comment[80];
a8ee8d ¤   PGPUInt32 PrefAlg;
db62d5 ¤   PGPCipherAlgorithm allowedAlgs[3];
00c26e ¤   int nNumAlgs;
6fb767 ¤   PGPtlsContextRef tls;
1c0040 ¤   PGPError err;
c86672 ¤   char StrRes[500];
1aaf5a
584ead ¤   err=kPGPError_NoErr;
afaf5a
fd625b ¤   context=(PGPContextRef)PGPsc;
e4db07 ¤   tls=(PGPtlsContextRef)PGPtls;
a8af5a
f91a7b ¤   if(IsPGPError(PGPclEvalExpired(hwnd, PGPCL_ENCRYPTSIGNEXPIRED)))
a398aa ¤   ¤   return FALSE;
51af5a
d19ee0 ¤   if(!GetCommentLine(context,comment,sizeof(comment),&PrefAlg,
ee5da7 ¤   ¤   allowedAlgs, &nNumAlgs))
5798aa ¤   ¤   return FALSE;
d9af5a
baf020 ¤   prds=(PRECIPIENTDIALOGSTRUCT)
079284 ¤   ¤   malloc(sizeof(RECIPIENTDIALOGSTRUCT));
b2af5a
054934 ¤   if(prds)
26c7a1 ¤   {
919a73 ¤   ¤   memset(prds,0x00,sizeof(RECIPIENTDIALOGSTRUCT));
7caf5a
038315 ¤   ¤   LoadString (g_hinst, IDS_PGPKEYSELDLG, StrRes, sizeof(StrRes));
1daf5a
097445 ¤   ¤   prds->szTitle=StrRes;
c3a698 ¤   ¤   prds->dwDisableFlags=PGPCL_DISABLE_AUTOMODE;
f0aebc ¤   ¤   prds->dwOptions=PGPCL_DETACHEDSIG;
21af5a
fab305 ¤   ¤   ms=(MYSTATE *)malloc(sizeof(MYSTATE));
85af5a
6dc4e2 ¤   ¤   if(ms)
f65b34 ¤   ¤   {
9dfd16 ¤   ¤   ¤   memset(ms, 0x00, sizeof(MYSTATE) );
a4af5a
c380ca ¤   ¤   ¤   LoadString (g_hinst, IDS_STARTINGWORK, ms->ws.StartText, sizeof(ms-¶
51ec90 >ws.StartText));
e2d6b9 ¤   ¤   ¤   LoadString (g_hinst, IDS_FINISHINGUP, ms->ws.EndText, sizeof(ms->ws¶
e80654 .EndText));
6d5242 ¤   ¤   ¤   ms->context=context;
82e341 ¤   ¤   ¤   ms->tlsContext=tls;
8ddb85 ¤   ¤   ¤   ms->ListHead=ListHead;
8b0161 ¤   ¤   ¤   ms->Operation=MS_ENCRYPTFILELIST;
a19515 ¤   ¤   ¤   ms->prds=prds;
9b5bba ¤   ¤   ¤   ms->Encrypt=bEncrypt;·
--6f7b 000afab0f154011027d Page 8 of encrypt.c
872aea ¤   ¤   ¤   ms->Sign=bSign;
7a98e1 ¤   ¤   ¤   ms->comment=comment;
6f275b ¤   ¤   ¤   ms->PrefAlg=PrefAlg;
20f7dd ¤   ¤   ¤   ms->allowedAlgs=allowedAlgs;·
eb3af1 ¤   ¤   ¤   ms->nNumAlgs=nNumAlgs;
f1af5a
cf52a6 ¤   ¤   ¤   if(OpenRings(hwnd,context,&(ms->KeySet)))
408cf3 ¤   ¤   ¤   {¤
d34f48 ¤   ¤   ¤   ¤   err=DoWork(hwnd,ms);
30af5a
c432ae ¤   ¤   ¤   ¤   if(prds->SelectedKeySetRef)
fd15a0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
bdaf5a
0d4303 ¤   ¤   ¤   ¤   FreePhrases(ms);
79af5a
7c6a05 ¤   ¤   ¤   ¤   PGPFreeKeySet(ms->KeySet);
1ca3a6 ¤   ¤   ¤   }
540701 ¤   ¤   ¤   free(ms);
b90fe4 ¤   ¤   }
c5d708 ¤   ¤   free(prds);
079371 ¤   }
2d67c5 ¤
e32133 ¤   FreeFileList(ListHead);
d9af5a
f4ee15 ¤   if(IsPGPError(err))
1498aa ¤   ¤   return FALSE;
4eaf5a
6bc2e7 ¤   return TRUE;
a1efe6 }
b8af5a
517f6d BOOL WeNeedToWordWrap(PGPContextRef context,
ebd769 ¤   ¤   ¤   ¤   ¤   ··unsigned short* WordWrapThreshold)
c8bb36 {
55559a ¤   PGPPrefRef¤ PrefRefClient=NULL;
3f9dc2 ¤   PGPBoolean¤ bWrapReturn=TRUE;
f30189 ¤   PGPUInt32¤  WrapWidth=72;
eeed37 ¤   PGPMemoryMgrRef memMgr;
baaf5a
fc89c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
87af5a
6df5c7 ¤   PGPclOpenClientPrefs (memMgr,&PrefRefClient);
bb8ebf ¤   PGPGetPrefBoolean (PrefRefClient,
a67266 ¤   ¤   kPGPPrefWordWrapEnable, &bWrapReturn);
632a2a ¤   PGPGetPrefNumber (PrefRefClient,·
34a52e ¤   ¤   kPGPPrefWordWrapWidth, &WrapWidth);
c7f7b9 ¤   PGPclCloseClientPrefs (PrefRefClient, FALSE);
24af5a
1b43e2 ¤   *WordWrapThreshold=WrapWidth;
e8af5a
2ca3df ¤   return bWrapReturn;
9aefe6 }
3aaf5a
1f17f9 BOOL WrapBuffer(char **pszOutText,
faa3ee ¤   ¤   ¤   ¤   char *szInText,
7740db ¤   ¤   ¤   ¤   PGPUInt16 wrapLength)
4cbb36 {
2cfdb2 ¤   BOOL RetVal = FALSE;
8e0040 ¤   PGPError err;
6cd8fb ¤   char *cmdlgBuffer;
aaaf5a
9d4894 ¤   err=PGPclWrapBuffer(
f54916 ¤   ¤   ¤   ¤   ¤   szInText,
1b6675 ¤   ¤   ¤   ¤   ¤   wrapLength,
25d168 ¤   ¤   ¤   ¤   ¤   &cmdlgBuffer);
b8af5a
06ffd3 ¤   if(IsntPGPError (err))
cfc7a1 ¤   {
d0b37b ¤   ¤   int memamt,length;
4daf5a
fa4ff2 ¤   ¤   length=strlen(cmdlgBuffer);
a1313b ¤   ¤   memamt=length+1;
afaf5a
--3fe0 000a52c15f24011027d Page 9 of encrypt.c
cc46f5 ¤   ¤   *pszOutText=(char *)malloc(memamt);
6ebb4d ¤   ¤   memcpy(*pszOutText,cmdlgBuffer,length);
e3d70d ¤   ¤   (*pszOutText)[length]=0;
91bd5d ¤   ¤   PGPclFreeWrapBuffer(cmdlgBuffer);
7a135c ¤   ¤   RetVal = TRUE;
439371 ¤   }
0aaf5a
4142d7 ¤   return RetVal;
08efe6 }
8caf5a
65af5a
4d345b BOOL WrapIfNecessary(PGPContextRef context,
1cdda3 ¤   ¤   ¤   ¤   ¤   ·char **pszClipText,DWORD *dwClipSize)
53bb36 {
6a4ae2 ¤   unsigned short WordWrapThreshold;
e9de1f ¤   char* szWrappedText;
835438 ¤   DWORD dwWrappedSize;
2eaf5a
26ac57 ¤   if(WeNeedToWordWrap(context,&WordWrapThreshold))
1fc7a1 ¤   {
1482a1 ¤   ¤   if(TRUE == WrapBuffer(&szWrappedText,·
419c88 ¤   ¤   ¤   *pszClipText,WordWrapThreshold))
2ded49 ¤   ¤   {¤
8e0d45 ¤   ¤   ¤   dwWrappedSize = strlen(szWrappedText);
fdaf5a
5b72ea ¤   ¤   ¤   memset(*pszClipText,0x00,*dwClipSize);
25c0d9 ¤   ¤   ¤   free(*pszClipText);
0676de ¤   ¤   ¤   *pszClipText=szWrappedText;
94af5a
46cd6b ¤   ¤   ¤   *dwClipSize=dwWrappedSize;
520fe4 ¤   ¤   }
c29371 ¤   }
c5af5a
55c2e7 ¤   return TRUE;
35efe6 }
d0af5a
134293 PGPError EncryptClipboardStub (MYSTATE *ms)·
3fbb36 {
b1db50 ¤   PGPOptionListRef opts;
4364a2 ¤   PGPContextRef context;
2b0040 ¤   PGPError err;
7d76de ¤   char StrRes[100];
3caf5a
004ead ¤   err=kPGPError_NoErr;
5baf5a
e22d85 ¤   context=ms->context;
3faf5a
22e201 ¤   PGPBuildOptionList(context,&opts,
17d3cd ¤   ¤   PGPOInputBuffer(context,ms->pInput,ms->dwInputSize),
54d0bf ¤   ¤   PGPOAllocatedOutputBuffer(context,
a362f9 ¤   ¤   ¤   &(ms->pOutput),MAX_BUFFER_SIZE ,&(ms->dwOutputSize)),
980a8c ¤   ¤   PGPOLastOption(context));
feaf5a
47dbec ¤   LoadString (g_hinst, IDS_CLIPBOARD, StrRes, sizeof(StrRes));
54af5a
6af5b2 ¤   err=GenericEncSign(ms,opts,StrRes);
cfaf5a
17bf49 ¤   PGPFreeOptionList(opts);
0aaf5a
985ea8 ¤   return err;
15efe6 }
5caf5a
5a8bef BOOL EncryptClipboard(HWND hwnd,void *PGPsc,void *PGPtls,BOOL Encrypt,BOOL Sign)
f8bb36 {
f564a2 ¤   PGPContextRef context;
c528da ¤   PRECIPIENTDIALOGSTRUCT prds;
87274e ¤   char *pInput;
59b1a1 ¤   DWORD dwInputSize;
296a53 ¤   UINT ClipboardFormat;
cfd00b ¤   char comment[80];
dfee8d ¤   PGPUInt32 PrefAlg;
a562d5 ¤   PGPCipherAlgorithm allowedAlgs[3];
--9ea0 0007cb20dbf4011027d Page 10 of encrypt.c
5dc26e ¤   int nNumAlgs;
e3c944 ¤   MYSTATE *ms;
55b767 ¤   PGPtlsContextRef tls;
e20040 ¤   PGPError err;
876672 ¤   char StrRes[500];
68af5a
57acbf ¤   // Check for files copied into clipboard from explorer
288489 ¤   if(OpenClipboard(hwnd))·
09c7a1 ¤   {
d4ae67 ¤   ¤   if(IsClipboardFormatAvailable(CF_HDROP))
a75b34 ¤   ¤   {
cc16d5 ¤   ¤   ¤   FILELIST *ListHead;
c420dc ¤   ¤   ¤   HDROP hDrop;
20af5a
ea0224 ¤   ¤   ¤   hDrop=(HDROP)GetClipboardData(CF_HDROP);
470137 ¤   ¤   ¤   ListHead=HDropToFileList(hDrop);
57af5a
02a801 ¤   ¤   ¤   if(ListHead!=0)
eef776 ¤   ¤   ¤   {
fce73d ¤   ¤   ¤   ¤   CloseClipboard();
9caf5a
2c2241 ¤   ¤   ¤   ¤   return EncryptFileList(hwnd,
09e59a ¤   ¤   ¤   ¤   ¤   ·PGPsc,PGPtls,ListHead,
4076de ¤   ¤   ¤   ¤   ¤   ·Encrypt,Sign);
04a3a6 ¤   ¤   ¤   }
e50fe4 ¤   ¤   }
7c5961 ¤   ¤   CloseClipboard();
da9371 ¤   }
7daf5a
304ead ¤   err=kPGPError_NoErr;
52af5a
ac625b ¤   context=(PGPContextRef)PGPsc;
5fdb07 ¤   tls=(PGPtlsContextRef)PGPtls;
c2af5a
561a7b ¤   if(IsPGPError(PGPclEvalExpired(hwnd, PGPCL_ENCRYPTSIGNEXPIRED)))
a198aa ¤   ¤   return FALSE;
0faf5a
2e9ee0 ¤   if(!GetCommentLine(context,comment,sizeof(comment),&PrefAlg,
295da7 ¤   ¤   allowedAlgs, &nNumAlgs))
c898aa ¤   ¤   return FALSE;
54af5a
b83a14 ¤   pInput=RetrieveClipboardData(hwnd, &ClipboardFormat,·
c01c44 ¤   ¤   ¤   ·····················&dwInputSize);
deaf5a
e36505 ¤   if(!pInput)
d6c7a1 ¤   {
2ae6fe ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOCLIPBOARDCONTENTS,
d22d15 ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
109371 ¤   }
c80e24 ¤   else
9ac7a1 ¤   {
b76096 ¤   ¤   if((ClipboardFormat != CF_TEXT)||(*pInput==0))
df5b34 ¤   ¤   {
7782f4 ¤   ¤   ¤   PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_NOCLIPBOARDTEXT,
f7e840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
fe0fe4 ¤   ¤   }
5a0e1d ¤   ¤   else
c65b34 ¤   ¤   {
fbb1d7 ¤   ¤   ¤   WrapIfNecessary(context,&pInput,&dwInputSize);
dbaf5a
5923bd ¤   ¤   ¤   prds=(PRECIPIENTDIALOGSTRUCT)
595b11 ¤   ¤   ¤   ¤   malloc(sizeof(RECIPIENTDIALOGSTRUCT));
f8af5a
b9bd2e ¤   ¤   ¤   if(prds)
85f776 ¤   ¤   ¤   {
f866ef ¤   ¤   ¤   ¤   memset(prds,0x00,sizeof(RECIPIENTDIALOGSTRUCT));
9baf5a
c0cd4c ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_PGPKEYSELDLG, StrRes, sizeof(StrRes));
0faf5a
15ac3e ¤   ¤   ¤   ¤   prds->szTitle=StrRes;
2f1cb1 ¤   ¤   ¤   ¤   prds->dwOptions=PGPCL_ASCIIARMOR;
7cffff ¤   ¤   ¤   ¤   prds->dwDisableFlags=PGPCL_DISABLE_ASCIIARMOR |
--158a 0010a53faf94011027d Page 11 of encrypt.c
017e2a ¤   ¤   ¤   ¤   ¤   PGPCL_DISABLE_WIPEORIG |
2226c8 ¤   ¤   ¤   ¤   ¤   PGPCL_DISABLE_AUTOMODE;
41af5a
2d7a90 ¤   ¤   ¤   ¤   ms=(MYSTATE *)malloc(sizeof(MYSTATE));
7367c5 ¤
651da8 ¤   ¤   ¤   ¤   if(ms)
3072c3 ¤   ¤   ¤   ¤   {
e03efb ¤   ¤   ¤   ¤   ¤   memset(ms, 0x00, sizeof(MYSTATE) );
19af5a
d859de ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_STARTINGWORK, ms->ws.StartText, si¶
25976b zeof(ms->ws.StartText));
e4a7b5 ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_FINISHINGUP, ms->ws.EndText, sizeo¶
2e6ad3 f(ms->ws.EndText));
506ac7 ¤   ¤   ¤   ¤   ¤   ms->context=context;
e9ade8 ¤   ¤   ¤   ¤   ¤   ms->tlsContext=tls;
ad8ad2 ¤   ¤   ¤   ¤   ¤   ms->pInput=pInput;
392883 ¤   ¤   ¤   ¤   ¤   ms->dwInputSize=dwInputSize;
242fd3 ¤   ¤   ¤   ¤   ¤   ms->Operation=MS_ENCRYPTCLIPBOARD;
d80d42 ¤   ¤   ¤   ¤   ¤   ms->prds=prds;
3e0b35 ¤   ¤   ¤   ¤   ¤   ms->Encrypt=Encrypt;·
93cc5d ¤   ¤   ¤   ¤   ¤   ms->Sign=Sign;
32a064 ¤   ¤   ¤   ¤   ¤   ms->comment=comment;
ab1fde ¤   ¤   ¤   ¤   ¤   ms->PrefAlg=PrefAlg;
628126 ¤   ¤   ¤   ¤   ¤   ms->allowedAlgs=allowedAlgs;·
2f754e ¤   ¤   ¤   ¤   ¤   ms->nNumAlgs=nNumAlgs;
8caf5a
d1b3d1 ¤   ¤   ¤   ¤   ¤   if(OpenRings(hwnd,context,&(ms->KeySet)))
8e55b9 ¤   ¤   ¤   ¤   ¤   {¤
1c4c1d ¤   ¤   ¤   ¤   ¤   ¤   err=DoWork(hwnd,ms);
a3af5a
8bbcbf ¤   ¤   ¤   ¤   ¤   ¤   if(prds->SelectedKeySetRef)
77ecd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
36af5a
917b86 ¤   ¤   ¤   ¤   ¤   ¤   FreePhrases(ms);
4d2b85 ¤   ¤   ¤   ¤
7b38e8 ¤   ¤   ¤   ¤   ¤   ¤   if((ms->pOutput!=0) && (IsntPGPError(err)))
4e8fec ¤   ¤   ¤   ¤   ¤   ¤   {
2db283 ¤   ¤   ¤   ¤   ¤   ¤   ¤   StoreClipboardData(hwnd, ms->pOutput, ms->dwOutputS¶
936e5f ize);
96a4cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   memset(ms->pOutput,0x00,ms->dwOutputSize);
28103c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(ms->pOutput); // Since auto alloced by ¶
cd5bf9 CDK
a8db3c ¤   ¤   ¤   ¤   ¤   ¤   }
4daf5a
20232f ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(ms->KeySet);
4a1c89 ¤   ¤   ¤   ¤   ¤   }
e749e0 ¤   ¤   ¤   ¤   ¤   free(ms);
d92613 ¤   ¤   ¤   ¤   }
da5b99 ¤   ¤   ¤   ¤   free(prds);
72a3a6 ¤   ¤   ¤   }
3f0fe4 ¤   ¤   }
ff0559 ¤   ¤   memset(pInput,0x00,dwInputSize);
0e742f ¤   ¤   free(pInput);
8d9371 ¤   }
18af5a
cbee15 ¤   if(IsPGPError(err))
8598aa ¤   ¤   return FALSE;
caaf5a
4cc2e7 ¤   return TRUE;
e1efe6 }
65af5a
14af5a
b17e4d /*__Editor_settings____
7aaf5a
b84126 ¤   Local Variables:
7d7b17 ¤   tab-width: 4
0e0e6c ¤   End:
6c5f8c ¤   vi: ts=4 sw=4
f29e9b ¤   vim: si
0ad062 _____________________*/
--87d4 000473e1cbd4011027e Page 1 of events.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8988c0 ¤   $Id: events.c,v 1.76.2.2.2.1 1998/11/12 03:13:35 heller Exp $
b4f7f7 ____________________________________________________________________________*/
ad5ed8 #include "precomp.h"
56af5a
88667a BOOL SyncOnVerify(PGPMemoryMgrRef memoryMgr)
4dbb36 {
99cf4b ¤   PGPBoolean¤ bSync¤  ¤   = FALSE;
6a1b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
d4af5a
8f3bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
354d78 ¤   PGPGetPrefBoolean(prefRef, kPGPPrefKeyServerSyncOnVerify, &bSync);
a64a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
5faf5a
86498a ¤   return (BOOL) bSync;
87efe6 }
acaf5a
e36c1c /* Generic event handler */
1cc77d PGPError
703935 myEvents(
43bc3b ¤   PGPContextRef context,
bab55d ¤   PGPEvent *event,
c58878 ¤   PGPUserValue userValue
8b27e6 ¤   )
ffbb36 {
040d17 ¤   MYSTATE *s;
5b6d02 ¤   (void) context;
c9af5a
6a93b0 ¤   s = (MYSTATE *)userValue;
39af5a
3f497e ¤   if(s->ws.CancelPending)
4674be ¤   ¤   return kPGPError_UserAbort;
1eaf5a
f97244 ¤   switch( event->type )·
b6c7a1 ¤   {
fe7813 ¤   case kPGPEvent_NullEvent:
665934 ¤   ¤   {¤  PGPEventNullData *d = &event->data.nullData;
409f0f ¤   ¤   ¤   BOOL CancelOperation;
4baf5a
c53546 ¤   ¤   ¤   CancelOperation=WorkingCallback (s->hwndWorking ,·
c93075 ¤   ¤   ¤   ¤   (unsigned long)d->bytesWritten, (unsigned long)d->bytesTotal) ;
b6af5a
25c1bf ¤   ¤   ¤   if(CancelOperation)
4a398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
f80fe4 ¤   ¤   }
f12f68 ¤   ¤   break;
189c31 ¤   case kPGPEvent_ErrorEvent:
cb03d0 ¤   ¤   {¤  PGPEventErrorData *d = &event->data.errorData;
acaf5a
9c40e7 ¤   ¤   ¤   if((d->error!=kPGPError_BadPassphrase)&&
df0551 ¤   ¤   ¤   ¤   (d->error!=kPGPError_UserAbort))
9024d4 ¤   ¤   ¤   ¤   PGPclEncDecErrorBox (s->hwndWorking,d->error);·
6c0fe4 ¤   ¤   }
012f68 ¤   ¤   break;
92fcd5 ¤   case kPGPEvent_WarningEvent:
042071 ¤   ¤   {¤  PGPEventWarningData *d = &event->data.warningData;
93af5a
e60fe4 ¤   ¤   }
7d2f68 ¤   ¤   break;
97d16c ¤   case kPGPEvent_EntropyEvent:
0604f6 ¤   ¤   {¤  PGPEventEntropyData *d = &event->data.entropyData;
75fd6f ¤   ¤   ¤   PGPError err;
2faf5a
d44a47 ¤   ¤   ¤   err=PGPclRandom(context, s->hwndWorking,·
011323 ¤   ¤   ¤   ¤   d->entropyBitsNeeded);
d1af5a
47ec78 ¤   ¤   ¤   if(err==kPGPError_UserAbort)
--547f 000437ee1474011027e Page 2 of events.c
93398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
a90fe4 ¤   ¤   }
c42f68 ¤   ¤   break;
726062 ¤   case kPGPEvent_PassphraseEvent:
cf5b34 ¤   ¤   {
227b8d ¤   ¤   ¤   PGPEventPassphraseData *d = &event->data.passphraseData;
e169b9 ¤   ¤   ¤   BOOL UserCancel;
05d8c1 ¤   ¤   ¤   char DecryptPrompt[40];
c12893 ¤   ¤   ¤   char StrRes[500];
0faf5a
b34e64 ¤   ¤   ¤   // If multiple passphrase events, clear previous
2cc929 ¤   ¤   ¤   if(s->PassPhrase)
71f776 ¤   ¤   ¤   {
0401b8 ¤   ¤   ¤   ¤   PGPclFreeCachedPhrase (s->PassPhrase);
d956db ¤   ¤   ¤   ¤   s->PassPhrase=NULL;
daa3a6 ¤   ¤   ¤   }
1caf5a
04cd2e ¤   ¤   ¤   if(s->PassKey)
a5f776 ¤   ¤   ¤   {
dc1512 ¤   ¤   ¤   ¤   memset(s->PassKey,0x00,s->PassKeyLen);
2778a2 ¤   ¤   ¤   ¤   PGPFreeData(s->PassKey);
6b82cc ¤   ¤   ¤   ¤   s->PassKey=NULL;
d854a8 ¤   ¤   ¤   ¤   s->PassKeyLen=0;
dca3a6 ¤   ¤   ¤   }
46af5a
de4356 ¤   ¤   ¤   // Don't cache conventional passphrases
1dc8e2 ¤   ¤   ¤   if(d->fConventional)
a7f776 ¤   ¤   ¤   {
153e44 ¤   ¤   ¤   ¤   PGPError PhraseErr;
7eaf5a
98775c ¤   ¤   ¤   ¤   if(s->PassCount > 0)
8072c3 ¤   ¤   ¤   ¤   {
c863db ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_WRONG_PHRASE, DecryptPrompt, sizeof¶
eefbff (DecryptPrompt));
f12613 ¤   ¤   ¤   ¤   }
615109 ¤   ¤   ¤   ¤   else·
e272c3 ¤   ¤   ¤   ¤   {
a13362 ¤   ¤   ¤   ¤   ¤   LoadString(g_hinst, IDS_ENTER_PHRASE, DecryptPrompt, sizeof¶
0afbff (DecryptPrompt));
5f483a ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_DECRYPTIONCOLON, StrRes, sizeof(St¶
4c492e rRes));
48b06a ¤   ¤   ¤   ¤   ¤   lstrcat (DecryptPrompt, StrRes);
582613 ¤   ¤   ¤   ¤   }
e3af5a
34b29b ¤   ¤   ¤   ¤   PhraseErr=PGPclGetPhrase (context,
bd4bbb ¤   ¤   ¤   ¤   ¤   s->KeySet,
837b88 ¤   ¤   ¤   ¤   ¤   s->hwndWorking,
4e6233 ¤   ¤   ¤   ¤   ¤   DecryptPrompt,
3f3b53 ¤   ¤   ¤   ¤   ¤   &(s->PassPhrase),·
102797 ¤   ¤   ¤   ¤   ¤   NULL,
5ac55d ¤   ¤   ¤   ¤   ¤   NULL,·
d83865 ¤   ¤   ¤   ¤   ¤   0,
9f2797 ¤   ¤   ¤   ¤   ¤   NULL,
c92797 ¤   ¤   ¤   ¤   ¤   NULL,
dc689c ¤   ¤   ¤   ¤   ¤   PGPCL_DECRYPTION,
66906f ¤   ¤   ¤   ¤   ¤   NULL,NULL,
5b7ce7 ¤   ¤   ¤   ¤   ¤   1,0,s->tlsContext,NULL);
8eaf5a
905dfb ¤   ¤   ¤   ¤   UserCancel=IsPGPError(PhraseErr);
f0af5a
6a2883 ¤   ¤   ¤   ¤   s->PassCount++;
e6a3a6 ¤   ¤   ¤   }
babb8c ¤   ¤   ¤   else
91ceda ¤   ¤   ¤   // Go through caching otherwise
59f776 ¤   ¤   ¤   {
a8b7c8 ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_PRIVATEKEYCOLON, StrRes, sizeof(StrRes¶
f71445 ));
fedb81 ¤   ¤   ¤   ¤   strcpy(DecryptPrompt,StrRes);
81af5a
095c42 ¤   ¤   ¤   ¤   UserCancel=GetDecryptPhrase(context,
064bbb ¤   ¤   ¤   ¤   ¤   s->KeySet,
432d77 ¤   ¤   ¤   ¤   ¤   s->hwndWorking,·
--cafc 0000abeb9854011027e Page 3 of events.c
a4eefe ¤   ¤   ¤   ¤   ¤   &(s->PassPhrase),
2e1696 ¤   ¤   ¤   ¤   ¤   &(s->PassCount),
876233 ¤   ¤   ¤   ¤   ¤   DecryptPrompt,
507c9c ¤   ¤   ¤   ¤   ¤   s->RecipientKeySet,
c5dcc2 ¤   ¤   ¤   ¤   ¤   s->RecipientKeyIDArray,
de5670 ¤   ¤   ¤   ¤   ¤   s->dwKeyIDCount,
a23073 ¤   ¤   ¤   ¤   ¤   &(s->PassKey),
2d8b8a ¤   ¤   ¤   ¤   ¤   &(s->PassKeyLen),
feb65b ¤   ¤   ¤   ¤   ¤   s->tlsContext,
0e99c8 ¤   ¤   ¤   ¤   ¤   &(s->AddedKeys));
0fa3a6 ¤   ¤   ¤   }
1687c7 ¤   ¤   ¤
7f287f ¤   ¤   ¤   if(UserCancel)
50398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
4b67c5 ¤
a9bac8 ¤   ¤   ¤   // Use passphrase first if available
a5c929 ¤   ¤   ¤   if(s->PassPhrase)
c5f776 ¤   ¤   ¤   {
357eb7 ¤   ¤   ¤   ¤   PGPAddJobOptions( event->job,·
d26f37 ¤   ¤   ¤   ¤   ¤   PGPOPassphraseBuffer(context,
194a2f ¤   ¤   ¤   ¤   ¤   ¤   s->PassPhrase, strlen(s->PassPhrase) ),
e7e0d4 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
47a3a6 ¤   ¤   ¤   }
b62624 ¤   ¤   ¤   else if(s->PassKey)
3df776 ¤   ¤   ¤   {
b67eb7 ¤   ¤   ¤   ¤   PGPAddJobOptions( event->job,·
0d8988 ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer(context,
ec7514 ¤   ¤   ¤   ¤   ¤   ¤   s->PassKey,s->PassKeyLen),
98e0d4 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
afa3a6 ¤   ¤   ¤   }
510fe4 ¤   ¤   }
492f68 ¤   ¤   break;
9e84f0 ¤   case kPGPEvent_SignatureEvent:
ace70e ¤   ¤   {¤  PGPEventSignatureData *d = &event->data.signatureData;
b7af5a
0ed834 ¤   ¤   ¤   if ((d->signingKey == NULL) &&
51acc0 ¤   ¤   ¤   ¤   SyncOnVerify(PGPGetContextMemoryMgr(context)))
3bf776 ¤   ¤   ¤   {
4b5de4 ¤   ¤   ¤   ¤   PGPBoolean bGotKeys;
0faf5a
0f3192 ¤   ¤   ¤   ¤   PGPclLookupUnknownSigner(context,·
9fc66f ¤   ¤   ¤   ¤   ¤   s->KeySet,s->tlsContext,·
709a48 ¤   ¤   ¤   ¤   ¤   s->hwndWorking, event,·
308d49 ¤   ¤   ¤   ¤   ¤   d->signingKeyID, &bGotKeys);
00af5a
f2b168 ¤   ¤   ¤   ¤   if (bGotKeys)
c57e8f ¤   ¤   ¤   ¤   ¤   return kPGPError_NoErr;
dda3a6 ¤   ¤   ¤   }
76af5a
76c61f ¤   ¤   ¤   SigEvent(s->hwndWorking,context,d,(char *)s->verifyName);
ce0fe4 ¤   ¤   }
9c2f68 ¤   ¤   break;
15589b ¤   case kPGPEvent_RecipientsEvent:
b15b34 ¤   ¤   {
8b5119 ¤   ¤   ¤   PGPEventRecipientsData *d = &event->data.recipientsData;
f320fe ¤   ¤   ¤   PGPUInt32 i,memamt;
7187c7 ¤   ¤   ¤
095bee ¤   ¤   ¤   // Save recipient key set for passphrase dialog
7f6209 ¤   ¤   ¤   PGPIncKeySetRefCount(d->recipientSet);
765f2e ¤   ¤   ¤   s->RecipientKeySet=d->recipientSet;
94af5a
71c4df ¤   ¤   ¤   // Save unknown keyids
0e4e75 ¤   ¤   ¤   if(d->keyCount>0)
c2f776 ¤   ¤   ¤   {
dc2f8b ¤   ¤   ¤   ¤   s->dwKeyIDCount=d->keyCount;
956d0d ¤   ¤   ¤   ¤   memamt=s->dwKeyIDCount*sizeof(PGPKeyID);
37bcd4 ¤   ¤   ¤   ¤   s->RecipientKeyIDArray=(PGPKeyID *)malloc(memamt);
3e42c0 ¤   ¤   ¤   ¤   memset(s->RecipientKeyIDArray,0x00,memamt);
64af5a
3e46e6 ¤   ¤   ¤   ¤   for(i=0;i<s->dwKeyIDCount;i++)
0072c3 ¤   ¤   ¤   ¤   {
0a0511 ¤   ¤   ¤   ¤   ¤   s->RecipientKeyIDArray[i]=d->keyIDArray[i];
--3f6f 000412579b94011027e Page 4 of events.c
862613 ¤   ¤   ¤   ¤   }
2ba3a6 ¤   ¤   ¤   }
590fe4 ¤   ¤   }
802f68 ¤   ¤   break;
5e311c ¤   case kPGPEvent_AnalyzeEvent:
80f631 ¤   ¤   {¤  PGPEventAnalyzeData *d = &event->data.analyzeData;
2eaf5a
03e393 ¤   ¤   ¤   if(d->sectionType==kPGPAnalyze_Unknown)
a8f776 ¤   ¤   ¤   {
f7f28b ¤   ¤   ¤   ¤   // If its tray, we want to keep it
84fd09 ¤   ¤   ¤   ¤   if(s->Operation!=MS_DECRYPTCLIPBOARD)
cbc211 ¤   ¤   ¤   ¤   ¤   return kPGPError_SkipSection;
4fa3a6 ¤   ¤   ¤   }
88bb8c ¤   ¤   ¤   else
93f776 ¤   ¤   ¤   {
994fc9 ¤   ¤   ¤   ¤   s->FoundPGPData=TRUE;
81a3a6 ¤   ¤   ¤   }
240fe4 ¤   ¤   }
b72f68 ¤   ¤   break;
ecc0da ¤   case kPGPEvent_DetachedSignatureEvent:
d75b34 ¤   ¤   {
085b6c ¤   ¤   ¤   int UserCancel;
e0af5a
aca4cf ¤   ¤   ¤   UserCancel=GetOriginalFileRef(s->hwndWorking,context,
a63deb ¤   ¤   ¤   ¤   s->fileName,(char *)s->verifyName,
8933b5 ¤   ¤   ¤   ¤   &(s->fileRef),s->hwndWorking);
80af5a
eb287f ¤   ¤   ¤   if(UserCancel)
ae398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
d9af5a
e7723e ¤   ¤   ¤   PGPAddJobOptions(event->job,
8de2fd ¤   ¤   ¤   ¤   PGPODetachedSig(context,
65178f ¤   ¤   ¤   ¤   ¤   PGPOInputFile(context,s->fileRef),
c1384d ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context)),
a4d911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
df0fe4 ¤   ¤   }
e92f68 ¤   ¤   break;
acec8f ¤   case kPGPEvent_OutputEvent:
904cca ¤   ¤   {¤  PGPEventOutputData *d = &event->data.outputData;
105b6c ¤   ¤   ¤   int UserCancel;
eee1f3 ¤   ¤   ¤   char inname[MAX_PATH];
bf50e1 ¤   ¤   ¤   char guessName[MAX_PATH];
4e7120 ¤   ¤   ¤   char *suggestedName;
0dc4bf ¤   ¤   ¤   BOOL Force;
662893 ¤   ¤   ¤   char StrRes[500];
55dcb1 ¤   ¤   ¤   PGPBoolean FYEO;
cdc2cd ¤   ¤   ¤   OUTBUFFLIST *nobl;
d6af5a
bb192a ¤   ¤   ¤   FYEO=d->forYourEyesOnly;
7baf5a
14dfa0 ¤   ¤   ¤   // Since we need an output event to get eyes data,
b981af ¤   ¤   ¤   // even buffers need to be assigned...
d3679a ¤   ¤   ¤   if((s->Operation==MS_DECRYPTCLIPBOARD)||(FYEO))
f5f776 ¤   ¤   ¤   {
388682 ¤   ¤   ¤   ¤   nobl=MakeOutBuffItem(&(s->obl));
1caf5a
192720 ¤   ¤   ¤   ¤   nobl->FYEO=FYEO;
51af5a
e77486 ¤   ¤   ¤   ¤   PGPAddJobOptions(event->job,
93507b ¤   ¤   ¤   ¤   ¤   PGPOAllocatedOutputBuffer(context,&(nobl->pBuff),·
6efad3 ¤   ¤   ¤   ¤   ¤   ¤   MAX_BUFFER_SIZE ,&(nobl->dwBuffSize)),
41e0d4 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
ffaf5a
84f622 ¤   ¤   ¤   ¤   break;
e0a3a6 ¤   ¤   ¤   }
29af5a
f0a084 ¤   ¤   ¤   if(d->suggestedName!=0)
e4f776 ¤   ¤   ¤   {
649854 ¤   ¤   ¤   ¤   suggestedName=d->suggestedName;
36aeb6 ¤   ¤   ¤   ¤   Force=FALSE;
aaa3a6 ¤   ¤   ¤   }
416b93 ¤   ¤   ¤   else·
--f0e2 0017b55a4eb4011027e Page 5 of events.c
99f776 ¤   ¤   ¤   {
9bc4f1 ¤   ¤   ¤   ¤   char *p;
d7af5a
b85f4f ¤   ¤   ¤   ¤   strcpy(guessName,JustFile(s->fileName));
7faf5a
93e7f0 ¤   ¤   ¤   ¤   p = strrchr(guessName, '.');
4aaf5a
1ea136 ¤   ¤   ¤   ¤   if(p!=0)
364d53 ¤   ¤   ¤   ¤   ¤   *p=0;
e9af5a
61461a ¤   ¤   ¤   ¤   suggestedName=guessName;
32c8be ¤   ¤   ¤   ¤   Force=FALSE; // Let guess be OK too.
7da3a6 ¤   ¤   ¤   }
3faf5a
4d73d0 ¤   ¤   ¤   strcpy(inname,s->fileName);
3eaf5a
2d8e4f ¤   ¤   ¤   AlterDecryptedFileName(inname,suggestedName);
70af5a
8f5891 ¤   ¤   ¤   LoadString (g_hinst, IDS_ENTEROUTPUTFILENAME, StrRes, sizeof(StrRes¶
451445 ));
7baf5a
75c5d1 ¤   ¤   ¤   UserCancel=SaveOutputFile(context,
57101f ¤   ¤   ¤   ¤   s->hwndWorking,·
d6172f ¤   ¤   ¤   ¤   StrRes,
798c27 ¤   ¤   ¤   ¤   inname,
ff44a6 ¤   ¤   ¤   ¤   &(s->fileRef),
c5efe8 ¤   ¤   ¤   ¤   Force);
6eaf5a
a3287f ¤   ¤   ¤   if(UserCancel)
3a398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
05af5a
1f723e ¤   ¤   ¤   PGPAddJobOptions(event->job,
3f820d ¤   ¤   ¤   ¤   PGPOOutputFile(context,s->fileRef),
59d911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
460fe4 ¤   ¤   }
852f68 ¤   ¤   break;
b4846e ¤   case kPGPEvent_BeginLexEvent:
bfc81e ¤   ¤   {¤  PGPEventBeginLexData *d = &event->data.beginLexData;
65e310 ¤   ¤   ¤   s->sectionCount = d->sectionNumber;
2b0fe4 ¤   ¤   }
f42f68 ¤   ¤   break;
6f4086 ¤   case kPGPEvent_EndLexEvent:
0b352a ¤   ¤   {¤  PGPEventEndLexData *d = &event->data.endLexData;
4aaf5a
cd0fe4 ¤   ¤   }
cb2f68 ¤   ¤   break;
ee1b52 ¤   ¤
f12f72 ¤   default:
792f68 ¤   ¤   break;
999371 ¤   }
1f2b85 ¤   ¤   ¤   ¤
58151e ¤   return kPGPError_NoErr;
50efe6 }
81af5a
237e4d /*__Editor_settings____
a1af5a
9a4126 ¤   Local Variables:
147b17 ¤   tab-width: 4
160e6c ¤   End:
4f5f8c ¤   vi: ts=4 sw=4
7c9e9b ¤   vim: si
7bd062 _____________________*/
--1227 0009bab93454011027f Page 1 of events.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e4f032 ¤   $Id: events.h,v 1.23.2.1.2.1 1998/11/12 03:13:36 heller Exp $
01f7f7 ____________________________________________________________________________*/
7dd4a4 #ifndef Included_EVENTS_h¤  /* [ */
f9ec87 #define Included_EVENTS_h
ebaf5a
2f6916 typedef struct _WORKSTRUCT {
86f84f ¤   char¤   ¤   ¤   ·TitleText[MAX_PATH+40];
963b7c ¤   char¤   ¤   ¤   ·StartText[40];
af80cb ¤   char¤   ¤   ¤   ·EndText[40];
f4956e ¤   unsigned long¤  ·sofar;
4f064e ¤   unsigned long¤  ·newsofar;
5f6530 ¤   unsigned long¤  ·total;
482b15 ¤   unsigned long¤  ·maxpos;
2fe8a9 ¤   unsigned long¤  ·curpos;
691947 ¤   BOOL¤   ¤   ¤   ·CancelPending;
1cfe7e } WORKSTRUCT;
b3af5a
bdb574 typedef struct _MYSTATE {
e98a97 ¤   PGPContextRef¤  context;
f3b9c0 ¤   PGPtlsContextRef tlsContext;
3b28cc ¤   PGPKeySetRef¤   KeySet;
9ea2af ¤   char¤   ¤   ¤   *OperationTarget;
027df9 ¤   BOOL¤   ¤   ¤   FirstOperation;
ba1e31 ¤   FILELIST¤   ¤   *ListHead;
aa1d71 ¤   HANDLE¤ ¤   ¤   hSemaphore;
b4521d ¤   DWORD¤  ¤   ¤   dwThreadID;
0b5bca ¤   DWORD¤  ¤   ¤   numDone;
61d9f6 ¤   DWORD¤  ¤   ¤   Operation;
c7120d ¤   char¤   ¤   ¤   *pInput;
0faadf ¤   DWORD¤  ¤   ¤   dwInputSize;
819bbd ¤   OUTBUFFLIST¤¤   *obl;¤  ¤   ··// For decryption
10c61f ¤   char¤   ¤   ¤   *pOutput; ····// For encryption
850979 ¤   DWORD¤  ¤   ¤   dwOutputSize; // ...
bdfb19 ¤   PGPError¤   ¤   err;
30af5a
b6fde5 // encrypt
a028da ¤   PRECIPIENTDIALOGSTRUCT prds;
982667 ¤   BOOL¤   ¤   ¤   Encrypt;·
3f84b8 ¤   BOOL¤   ¤   ¤   Sign;
6461fa ¤   char¤   ¤   ¤   *comment;
b1d2bd ¤   PGPUInt32¤  ¤   PrefAlg;
696697 ¤   PGPCipherAlgorithm *allowedAlgs;·
d0acbe ¤   int¤¤   ¤   ¤   nNumAlgs;
73af5a
147f78 ¤   HWND¤   ¤   ¤   hwndWorking;
c0ddc4 ¤   PGPFileSpecRef¤ fileRef;
d754e0 ¤   char¤   ¤   ¤   *fileName;
6726f5 ¤   char¤   ¤   ¤   *verifyName[MAX_PATH+1];
26a3a0 ¤   PGPUInt32¤  ¤   sectionCount;
a3c576 ¤   PGPKeyID¤   ¤   *RecipientKeyIDArray;
7ec53d ¤   DWORD¤  ¤   ¤   dwKeyIDCount;
dc7216 ¤   PGPKeyRef¤  ¤   SignKey;
82ec3e ¤   unsigned short¤ PassCount;
fa86a3 ¤   WORKSTRUCT¤ ¤   ws;
79080c ¤   char¤   ¤   ¤   *ConvPassPhrase;
e465e2 ¤   char¤   ¤   ¤   *PassPhrase;
a52b5b ¤   PGPKeySetRef¤   RecipientKeySet;
b4d954 ¤   BOOL¤   ¤   ¤   FoundPGPData;
1d8e63 ¤   PGPByte¤¤   ¤   *PassKey;
b0db80 ¤   PGPUInt32¤  ¤   PassKeyLen;
0f6ddb ¤   PGPKeySetRef ···AddedKeys;
7a1941 } MYSTATE;
80af5a
d2dd6f PGPError myEvents(
26bc3b ¤   PGPContextRef context,
9bb55d ¤   PGPEvent *event,
--f87d 001e99f258c4011027f Page 2 of events.h
c88878 ¤   PGPUserValue userValue
da823f ¤   );
01af5a
51af5a
4da97f #endif /* ] Included_EVENTS_h */
c7af5a
dbaf5a
207e4d /*__Editor_settings____
2daf5a
5b4126 ¤   Local Variables:
037b17 ¤   tab-width: 4
460e6c ¤   End:
e25f8c ¤   vi: ts=4 sw=4
3f9e9b ¤   vim: si
e9d062 _____________________*/
--cd1b 001fcc38afa40110280 Page 1 of main.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
9a0d39 ¤   $Id: main.c,v 1.5.18.1 1998/11/12 03:13:37 heller Exp $
dcf7f7 ____________________________________________________________________________*/
295ed8 #include "precomp.h"
e9af5a
0e2664 #ifdef WIN32
23af5a
be2163 BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason,LPVOID lpvReserved)
5bbb36 {
2f5a5c ···switch (fdwReason) {
1ed340 ······case DLL_PROCESS_ATTACH:
2a923f ·········g_hinst = hinstDll;
e9a646 ¤   ¤   ·//vErrorOut(fg_white,"DLL_PROCESS_ATTACH\n");
5c5180 ·········break;
fb3ccb ······case DLL_THREAD_ATTACH:
0a462a ¤   ¤   ··//vErrorOut(fg_white,"DLL_THREAD_ATTACH\n");
955180 ·········break;
7b81b6 ······case DLL_THREAD_DETACH:
6bc867 ¤   ¤   ··//vErrorOut(fg_red,"DLL_THREAD_DETACH\n");
a52f68 ¤   ¤   break;
c16e3d ······case DLL_PROCESS_DETACH:
006f2f ¤   ¤   ··//vErrorOut(fg_red,"DLL_PROCESS_DETACH\n");
335180 ·········break;
e1b144 ···}
cd7921 ···return(TRUE);
29efe6 }
cdaf5a
fffac8 #else ·
17af5a
4bc3a4 int FAR PASCAL LibMain (HANDLE hInstance,
e16afc ························WORD wDataSeg,
e74013 ························WORD wHeapSize,
91d8cd ························LPSTR lpszCmdLine)
55bb36 {
fb920e ···g_hinst = hInstance;
fcaf5a
ed1422 ···if (wHeapSize != 0) ·// If DLL data seg is MOVEABLE
6052ee ······UnlockData (0);
78af5a
7cf45e ···return (1);
a7efe6 }
bfaf5a
977454 #endif
bdaf5a
b77e4d /*__Editor_settings____
77af5a
3f4126 ¤   Local Variables:
4d7b17 ¤   tab-width: 4
150e6c ¤   End:
4c5f8c ¤   vi: ts=4 sw=4
979e9b ¤   vim: si
fcd062 _____________________*/
--0c73 00119d543a940110281 Page 1 of pgpsc.def
639a90 ; PGP60sc.def : Declares the module parameters for the DLL.
7eaf5a
a45113 LIBRARY ·····"PGP60sc"
053e12 DESCRIPTION ·'PGP Shell/Clipboard Library'
cbaf5a
0b7665 SECTIONS
c2bfc7 ··········.SHARDAT READ WRITE SHARED
daaf5a
32ef2b EXPORTS
78010e ¤   ¤   PlaybackHook
49b3ce ¤   ¤   AddToFileList
1a57cc ¤   ¤   HDropToFileList
da2e57 ¤   ¤   CmdLineToFileList
8a9ea8 ¤   ¤   FreeFileList
1d3c77 ¤   ¤   PGPscQueryCacheSecsRemaining
0b0af2 ¤   ¤   PGPscPreferences
fca625 ¤   ¤   PGPscAbout
7c71c5 ¤   ¤   AddKeyFileList
021a71 ¤   ¤   DecryptFileList
3f1d6d ¤   ¤   EncryptFileList
f0238e ¤   ¤   WipeFileList
864a08 ¤   ¤   JustFile
2230f2 ¤   ¤   GetValidityDrawPrefs
48d819 ¤   ¤   GetMarginalInvalidPref
2cb963 ¤   ¤   LaunchInternalViewer
b61d67 ¤   ¤   InitPGPsc
12b12f ¤   ¤   UninitPGPsc
e07f1d ¤   ¤   EncryptClipboard
b8a5f7 ¤   ¤   DecryptClipboard
a85633 ¤   ¤   AddKeyClipboard
bb46dd ¤   ¤   DoLaunchKeys
c4f150 ¤   ¤   DoLaunchTools
9e933e ¤   ¤   DoLaunchDisk
22ef00 ¤   ¤   ClipboardWipe
495458 ¤   ¤   WindowExists
089580 ¤   ¤   SendPGPlogMsg
0b2a9c ¤   ¤   PGPpath
abaf5a
0fd46a ¤   ¤   ConcatOutBuffList
cfb6e7 ¤   ¤   MakeOutBuffItem
bc2195 ¤   ¤   TempestViewer
ccaf5a
f42ffe ¤   ¤   DoPaste
b24fe7 ¤   ¤   DoCopy
994c30 ¤   ¤   DoFocus
2aaf5a
95d34a ¤   ¤   StartUpdateTimer
16df39 ¤   ¤   UpdateTimerProc
181b52 ¤   ¤
86153c ¤   ¤   FreeSpaceWipeWizard
c0af5a
196294 ¤   ¤   CheckForPurge
--cb8d 000f5ebfc0140110282 Page 1 of recpass.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
dc2f0d ¤   $Id: recpass.c,v 1.19.8.1 1998/11/12 03:13:37 heller Exp $
7ef7f7 ____________________________________________________________________________*/
1a5ed8 #include "precomp.h"
ecaf5a
1863c9 void FreePhrases(MYSTATE *ms)
0dbb36 {
c959af ¤   if(ms->PassPhrase)
8ec7a1 ¤   {
3e44d5 ¤   ¤   PGPclFreeCachedPhrase(ms->PassPhrase);
6b4ef2 ¤   ¤   ms->PassPhrase=NULL;
999371 ¤   }
85af5a
ab11bd ¤   if(ms->PassKey)
e4c7a1 ¤   {
430973 ¤   ¤   memset(ms->PassKey,0x00,ms->PassKeyLen);
fc3be6 ¤   ¤   PGPFreeData(ms->PassKey);
f8dbb5 ¤   ¤   ms->PassKey=NULL;
8e9371 ¤   }
45af5a
a95afe ¤   if(ms->ConvPassPhrase)
b2c7a1 ¤   {
792dbd ¤   ¤   PGPclFreePhrase(ms->ConvPassPhrase);
6ef762 ¤   ¤   ms->ConvPassPhrase=NULL;
c29371 ¤   }
5fefe6 }
8daf5a
c1329a /*Returns TRUE if the user hit cancel*/
0eaf5a
1c54ac BOOL GetDecryptPhrase(PGPContextRef context,
783deb ¤   ¤   ¤   ¤   ¤   ··PGPKeySetRef MainKeySet,
567aa4 ¤   ¤   ¤   ¤   ¤   ··HWND hwnd,·
1e5ff1 ¤   ¤   ¤   ¤   ¤   ··char **EnteredOrCachedPhrase,
585d5a ¤   ¤   ¤   ¤   ¤   ··unsigned short *PassPhraseCount,
1c3854 ¤   ¤   ¤   ¤   ¤   ··char *KeyForPhrase,
5140b2 ¤   ¤   ¤   ¤   ¤   ··PGPKeySetRef KeySet,
0221a6 ¤   ¤   ¤   ¤   ¤   ··PGPKeyID *RecipientKeyIDArray,
3515f5 ¤   ¤   ¤   ¤   ¤   ··DWORD dwKeyIDCount,
667f69 ¤   ¤   ¤   ¤   ¤   ··PGPByte **PassKey,
0dda37 ¤   ¤   ¤   ¤   ¤   ··PGPUInt32 *PassKeyLen,
bb5c31 ¤   ¤   PGPtlsContextRef tlsContext,
1b4d51 ¤   ¤   PGPKeySetRef¤   *AddedKeys)
a0bb36 {
c26c25 ¤   BOOL UserCancel = FALSE;
c6aae6 ¤   BOOL ForceEntry = FALSE;
3928b3 ¤   char PhraseTitle[256];
afaf5a
b2156b ¤   assert(EnteredOrCachedPhrase);
aaaf5a
7b68e2 ¤   if(*EnteredOrCachedPhrase)
9ec7a1 ¤   {
fa8f92 ¤   ¤   PGPclFreeCachedPhrase(*EnteredOrCachedPhrase);
c817a3 ¤   ¤   *EnteredOrCachedPhrase = NULL;
a39371 ¤   }
4caf5a
15313c ¤   if(PassPhraseCount && *PassPhraseCount > 0)
fac7a1 ¤   {
3ca151 ¤   ¤   LoadString(g_hinst, IDS_WRONG_PHRASE, PhraseTitle, sizeof(PhraseTitle));
5cc95e ¤   ¤   ForceEntry = TRUE;
1e9371 ¤   }
fa4264 ¤   else·
dbc7a1 ¤   {
250200 ¤   ¤   LoadString(g_hinst, IDS_ENTER_PHRASE, PhraseTitle, sizeof(PhraseTitle));
a57bd7 ¤   ¤   lstrcat (PhraseTitle, KeyForPhrase);
369371 ¤   }
e4af5a
f5af5a
--2d5c 0014bbb92b340110282 Page 2 of recpass.c
42d229 ¤   if(PGPclGetCachedDecryptionPhrase (context,
ca0d23 ¤   ¤   ¤   ¤   ¤   tlsContext,
015656 ¤   ¤   ¤   ¤   ¤   MainKeySet,
806fb7 ¤   ¤   ¤   ¤   ¤   hwnd,·
d7c62f ¤   ¤   ¤   ¤   ¤   PhraseTitle,·
e2d0e4 ¤   ¤   ¤   ¤   ¤   ForceEntry,
1336ff ¤   ¤   ¤   ¤   ¤   EnteredOrCachedPhrase,
cd17f6 ¤   ¤   ¤   ¤   ¤   KeySet,
05ccc0 ¤   ¤   ¤   ¤   ¤   RecipientKeyIDArray,
94632c ¤   ¤   ¤   ¤   ¤   dwKeyIDCount,
c444e2 ¤   ¤   ¤   ¤   ¤   PassKey,PassKeyLen,
3b67b0 ¤   ¤   ¤   ¤   ¤   AddedKeys)!= kPGPError_NoErr)
2cc7a1 ¤   {
7c069e ¤   ¤   UserCancel = TRUE;
9f9371 ¤   }
b64a19 ¤   if(PassPhraseCount)
07ede4 ¤   ¤   ++(*PassPhraseCount);
44af5a
ce2010 ¤   return(UserCancel);
13efe6 }
00af5a
21af5a
457e4d /*__Editor_settings____
acaf5a
8a4126 ¤   Local Variables:
267b17 ¤   tab-width: 4
9f0e6c ¤   End:
5d5f8c ¤   vi: ts=4 sw=4
b59e9b ¤   vim: si
4bd062 _____________________*/
--2306 001f2ae996b40110283 Page 1 of recpass.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8ad417 ¤   $Id: recpass.h,v 1.12.8.1 1998/11/12 03:13:38 heller Exp $
90f7f7 ____________________________________________________________________________*/
6bf83b #ifndef Included_RECPASS_h¤ /* [ */
29d321 #define Included_RECPASS_h
7baf5a
27af5a
3754ac BOOL GetDecryptPhrase(PGPContextRef context,
ea3deb ¤   ¤   ¤   ¤   ¤   ··PGPKeySetRef MainKeySet,
7c7aa4 ¤   ¤   ¤   ¤   ¤   ··HWND hwnd,·
a55ff1 ¤   ¤   ¤   ¤   ¤   ··char **EnteredOrCachedPhrase,
9f5d5a ¤   ¤   ¤   ¤   ¤   ··unsigned short *PassPhraseCount,
d63854 ¤   ¤   ¤   ¤   ¤   ··char *KeyForPhrase,
af40b2 ¤   ¤   ¤   ¤   ¤   ··PGPKeySetRef KeySet,
a121a6 ¤   ¤   ¤   ¤   ¤   ··PGPKeyID *RecipientKeyIDArray,
e115f5 ¤   ¤   ¤   ¤   ¤   ··DWORD dwKeyIDCount,
297f69 ¤   ¤   ¤   ¤   ¤   ··PGPByte **PassKey,
66da37 ¤   ¤   ¤   ¤   ¤   ··PGPUInt32 *PassKeyLen,
74e0d1 ¤   ¤   ¤   ¤   ¤   ··PGPtlsContextRef tlsContext,
f104af ¤   ¤   ¤   ¤   ¤   ··PGPKeySetRef *AddedKeys);
0eaf5a
6c6d37 void FreePhrases(MYSTATE *myState);
15af5a
3f9675 #endif /* ] Included_RECPASS_h */
c9af5a
33af5a
857e4d /*__Editor_settings____
53af5a
0e4126 ¤   Local Variables:
957b17 ¤   tab-width: 4
2a0e6c ¤   End:
035f8c ¤   vi: ts=4 sw=4
229e9b ¤   vim: si
f2d062 _____________________*/
--332b 0004b1282db40110284 Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
014fd0 // Used by PGPsc.rc
e4465d //
63085b #define IDS_FSNOTSUPPORTED ·············1
2c194c #define IDS_DRIVENOTSUPPORTED ··········2
1969d8 #define IDS_FATFAILED ··················3
ca655b #define IDS_COULDNOTLOCK ···············4
0dd08c #define IDS_NODRIVESELECTED ············5
d4a47f #define IDS_USERCANCEL ·················6
3b1251 #define IDS_DISKMODIFIED ···············7
fbeeba #define IDS_COULDNOTWRITE ··············8
99accd #define IDS_COULDNOTREAD ···············9
5603b2 #define IDS_OUTOFMEMORY ················10
bb8ed4 #define IDS_CLUSTERERROR ···············11
bec079 #define IDS_NTNOTSUPPORTED ·············12
6f0e5c #define IDS_NTFSGREATER4K ··············13
5b0822 #define IDS_INVALPARAM ·················14
5193c9 #define IDS_ALREADYCOMMIT ··············15
45e664 #define IDD_DELETEDLG ··················101
dc84a3 #define IDD_INTRO ······················102
a025f8 #define IDD_INFO ·······················103
3f2dab #define IDB_WIPEWIZ4 ···················103
107680 #define IDD_CLIPBOARDVIEWER ············104
5d7534 #define IDB_WIPEWIZ1 ···················104
7b2d30 #define IDD_FINISH ·····················105
454b4f #define IDB_WIPEWIZ8 ···················105
491aef #define IDB_WIPEWIZ24 ··················106
0af034 #define IDI_ICON_SHF ···················107
71d5de #define IDI_ICON1 ······················108
5c3ad1 #define IDB_ALPHA ······················109
e82315 #define IDI_FYEO ·······················110
9338c5 #define IDB_MA13X24 ····················112
790ea4 #define IDB_MA8X14 ·····················113
462b58 #define IDB_MB13X24 ····················114
04f7b4 #define IDB_MC13X24 ····················115
e49672 #define IDB_MD13X24 ····················116
472e89 #define IDB_MB8X14 ·····················117
8a6875 #define IDB_MC8X14 ·····················118
ec3a03 #define IDB_MD8X14 ·····················119
1d7ec0 #define IDD_RESULTS_SMALL ··············131
980ef5 #define IDD_TEDDLG ·····················132
f8e6f6 #define IDD_WORKING ····················141
7824c6 #define IDI_ICON_SIG ···················142
fbcb52 #define IDD_WIPEFREE ···················142
acf92c #define IDI_ICON_ASC ···················143
802b3f #define IDD_STATUS ·····················143
43393b #define IDI_ICON_PGP ···················144
75bf0a #define IDD_NEWWORKING ·················144
8335e2 #define IDI_ICON_PRVKR ·················145
fd3b44 #define IDI_ICON_PUBKR ·················146
3f2555 #define IDI_ICON_AEXPK ·················147
e96800 #define IDD_RESULTS ····················148
b0f5e1 #define IDI_ICON_RND ···················148
c6e627 #define IDD_RESULTS1 ···················149
dc81b5 #define IDI_ICON_PGR ···················149
f336d3 #define IDD_VERBOSERESULTS ·············150
52421d #define IDD_TEMPEST ····················151
33307c #define IDC_FILELIST ···················1000
54fe71 #define IDC_EDIT1 ······················1001
1b3a71 #define IDC_HELPME ·····················1001
4bc675 #define IDC_WIPEQUERY ··················1002
ff8f82 #define IDC_DRIVECOMBO ·················1002
c1e9a7 #define IDVIEW_EXTERNAL ················1003
b5c581 #define IDVIEW_INTERNAL ················1004
abab02 #define IDC_STATIC_FS ··················1004
1daf8c #define IDC_STATIC_NC ··················1005
af8aed #define IDC_STATIC_SC ··················1006
bcac19 #define IDC_STATIC_BS ··················1007
572843 #define IDC_STATIC_FSDATA ··············1008
bb2ccd #define IDC_STATIC_NCDATA ··············1009
4bb92d #define IDC_PROGRESS ···················1010
--3044 00077880ecf40110284 Page 2 of resource.h
90ae00 #define IDC_STATIC_SCDATA ··············1010
f9464f #define IDC_PROGRESS_TEXT ··············1011
ae88f4 #define IDC_STATIC_BSDATA ··············1011
3ec5c3 #define IDC_STATIC_TC ··················1012
2df6fa #define IDC_STATIC_TCDATA ··············1013
2e636f #define IDC_STATIC_DS ··················1014
ebb09f #define IDC_DECRYPTION_RESULTS ·········1015
cc7405 #define IDC_WELCOME ····················1017
2530fc #define IDC_NUMPASSES ··················1019
ec1ca7 #define IDC_STATIC_1 ···················1020
7e748a #define IDC_PASS_PROGRESS ··············1020
416354 #define IDC_FINISH ·····················1021
3a5a9e #define IDC_STATIC_2 ···················1021
779d3c #define IDC_WIPE_PROGRESS ··············1021
d915f8 #define IDC_STATUS ·····················1022
0dbda6 #define IDC_STATIC_3 ···················1022
eea77c #define IDC_FS ·························1023
68d6ec #define IDC_STATIC_4 ···················1023
eeb719 #define IDC_NC ·························1024
4fd271 #define IDC_SC ·························1025
73d059 #define IDC_BS ·························1026
0c635d #define IDC_SPIN1 ······················1026
6028f9 #define IDC_TC ·························1027
836c39 #define IDC_WIZBITMAP ··················1028
fd924e #define IDC_BEGIN ······················1029
f1c6eb #define IDC_FSDATA ·····················1030
dd825e #define IDC_NCDATA ·····················1031
acd486 #define IDC_SCDATA ·····················1032
b3e51e #define IDC_BSDATA ·····················1033
58496e #define IDC_TCDATA ·····················1034
3dbca1 #define IDC_GROUP ······················1035
41b4b4 #define IDC_STATIC_PASS ················1036
0cdc8e #define IDC_WIPE_PROGRESS2 ·············1037
1a5c7f #define IDC_RESTARTINGTEXT ·············1038
e9edcb #define IDC_TEMPESTLIST ················1039
b40fc9 #define IDC_TEMPESTFONT ················1040
2bbdda #define IDS_ENTER_PHRASE ···············5013
1f833f #define IDS_WRONG_PHRASE ···············5014
1aef67 #define IDS_WIPINGINFREEWARE ···········5015
583bfe #define IDS_ADDINGFILE ·················5016
5f1deb #define IDS_FINISHEDREADINGKEYS ········5017
29bc41 #define IDS_PGPERROR ···················5018
f7c254 #define IDS_NOPGPKEYSINFILE ············5019
511938 #define IDS_NOCLIPBOARDCONTENTS ········5020
0d62c2 #define IDS_NOPGPKEYSINCLIPBOARD ·······5021
14c2ca #define IDS_CLIPBOARDEXCEEDED ··········5022
02c720 #define IDS_CLIPBOARD ··················5023
11fbdb #define IDS_CANTLOCATELOG ··············5024
dd0a74 #define IDS_CANTCONNECTLOG ·············5025
c63181 #define IDS_CANTTRANSMITLOG ············5026
586930 #define IDS_DECODINGFILE ···············5027
b3a5a7 #define IDS_SHAREFILEINFO ··············5028
15d4e5 #define IDS_SHARERDTITLE ···············5029
c86579 #define IDS_SHAREPASSPROMPT ············5030
d2e8e4 #define IDS_STARTINGWORK ···············5031
bcf71e #define IDS_FINISHINGUP ················5032
608237 #define IDS_NOPGPINFOINFILE ············5033
61be39 #define IDS_NOPGPINFOCLIPBOARD ·········5034
53c4dc #define IDS_PGPKEYSELDLG ···············5035
6b9c67 #define IDS_CONVPASSPROMPT ·············5036
b2978b #define IDS_PASSPROMPTABOVEKEY ·········5037
8ecac2 #define IDS_ENCODINGFILE ···············5038
71d17d #define IDS_ENCFILENAMEPROMPT ··········5039
82208b #define IDS_DECRYPTIONCOLON ············5040
f8c520 #define IDS_PRIVATEKEYCOLON ············5041
492c64 #define IDS_ENTEROUTPUTFILENAME ········5042
d95a8d #define IDS_SAVEFILTER ·················5043
d6873b #define IDS_SELSIGNFILE ················5044
d1699f #define IDS_WRONGSDK ···················5045
3a6bc4 #define IDS_EVALEXPIRED ················5046
090e5b #define IDS_CANTOPENRINGS ··············5047
77f0c2 #define IDS_CANTOPENPGPKEYS ············5048
--7602 001205b164f40110284 Page 3 of resource.h
b55205 #define IDS_CANTOPENPGPTOOLS ···········5049
f8d068 #define IDS_CANTAUTOCOPY ···············5050
115e1c #define IDS_SCANNINGDISK ···············5051
25aa21 #define IDS_PERCENTWRITTEN ·············5052
a528ea #define IDS_READINGFAT ·················5053
61d537 #define IDS_WIPINGDELANDSLACK ··········5054
be7507 #define IDS_WIPINGCLUSTERS ·············5055
bc5138 #define IDS_READINGBOOT ················5056
d5f4c7 #define IDS_DISKSTAT ···················5057
c54481 #define IDS_BEGINWIPE ··················5058
4d40e7 #define IDS_DETECTEDWRITE ··············5059
68a282 #define IDS_WIPECONGRATS ···············5060
255ba1 #define IDS_WIPECANCEL ·················5061
0a347b #define IDS_WIPENOTSUCCESSFUL ··········5062
13f49c #define IDS_WIPENOTOPEN ················5063
e44636 #define IDS_WIPEUSERABORT ··············5064
242f2f #define IDS_WIPENOSTATS ················5065
370eda #define IDS_WIPENOREMOVE ···············5066
ea12d6 #define IDS_WIPENOFLUSH ················5067
181f1b #define IDS_WIPENOFILEMAP ··············5068
46a2e1 #define IDS_WIPENOMEMMAP ···············5069
bc2cdd #define IDS_WIPEALREADYOPEN ············5070
a64e16 #define IDS_WIPEPROTECT ················5071
5bb4f0 #define IDS_DIRNOTREMOVED ··············5072
7a0207 #define IDS_WIPINGFILE ·················5073
a4d83b #define IDS_LASTCHANCE ·················5074
b8f0fe #define IDS_REALLYWIPECLIPBOARD ········5075
f8221a #define IDS_WORKPERCENT ················5076
15ef9a #define IDS_PASSESOUTOFRANGE ···········5077
61ef14 #define IDS_CANTOPENPGPDISK ············5078
6eac0b #define IDS_NOCLIPBOARDTEXT ············5079
65bf31 #define IDS_FYEOCAPTION ················5080
946739 #define IDS_FYEOMSG ····················5081
1cd4d6 #define IDS_OUTOFMEM ···················5082
8ce15b #define ID_ENCRYPTSIGN ·················40007
85377a #define ID_DECRYPTVERIFY ···············40008
70e36c #define ID_VIEWCLIPBOARD ···············40009
0ace55 #define ID_ENCRYPT ·····················40017
ebfce7 #define ID_SIGN ························40018
4d2c3e #define IDC_STATIC ·····················-1
23af5a
c011aa // Next default values for new objects
f5ac6a //·
75f860 #ifdef APSTUDIO_INVOKED
9e3f23 #ifndef APSTUDIO_READONLY_SYMBOLS
c61ccb #define _APS_NEXT_RESOURCE_VALUE ·······120
bd611c #define _APS_NEXT_COMMAND_VALUE ········40001
788c55 #define _APS_NEXT_CONTROL_VALUE ········1041
ad1285 #define _APS_NEXT_SYMED_VALUE ··········101
8b7454 #endif
207454 #endif
--d039 0014f9102e440110285 Page 1 of saveopen.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
9c8da4 ¤   $Id: saveopen.h,v 1.8.8.1 1998/11/12 03:13:39 heller Exp $
b3f7f7 ____________________________________________________________________________*/
3790c4 #ifndef Included_SAVEOPEN_h¤/* [ */
6abd4a #define Included_SAVEOPEN_h
6daf5a
7fb6e0 BOOL AlterEncryptedFileName(char *FileName,DWORD Actions);
efaf5a
7f2544 BOOL AlterDecryptedFileName(char *FileName,char *SuggestedName);
ebaf5a
51829f BOOL ·SaveOutputFile(PGPContextRef Context,
7af393 ¤   ¤   ¤   ¤   ¤   ·HWND hwnd,·
29176a ¤   ¤   ¤   ¤   ¤   ·char *Title,
667818 ¤   ¤   ¤   ¤   ¤   ·char *InputFile,·
c2599b ¤   ¤   ¤   ¤   ¤   ·PGPFileSpecRef *pOutputFileRef,
4a7b89 ¤   ¤   ¤   ¤   ¤   ·BOOL Force);
a3af5a
7ea42c BOOL GetOriginalFileRef(HWND hwnd,PGPContextRef context,
b12763 ¤   ¤   ¤   ¤   ¤   ¤   char *InputFile,
d2e2ee ¤   ¤   ¤   ¤   ¤   ¤   char *OutputFile,
004076 ¤   ¤   ¤   ¤   ¤   ¤   PGPFileSpecRef *OriginalFileRef,
807095 ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndWorking);
61af5a
87af5a
c5cf70 #endif /* ] Included_SAVEOPEN_h */
0eaf5a
d6af5a
3c7e4d /*__Editor_settings____
89af5a
2b4126 ¤   Local Variables:
4a7b17 ¤   tab-width: 4
880e6c ¤   End:
945f8c ¤   vi: ts=4 sw=4
239e9b ¤   vim: si
4fd062 _____________________*/
--9aa0 0009cdef6c040110286 Page 1 of wipe.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
295d93 ¤   $Id: wipe.c,v 1.47.8.1 1998/11/12 03:13:39 heller Exp $
31f7f7 ____________________________________________________________________________*/
f25ed8 #include "precomp.h"
da0a8b #include <time.h>
7ff15e #include <sys/types.h>
4fd4f4 #include <sys/stat.h>
3faf5a
679aad BOOL WipeError(HWND hwnd,FILELIST *FileEntry,UINT error)
7bbb36 {
e94844 ¤   int ErrMsg;
596672 ¤   char StrRes[500];
33b708 ¤   int nMsgBoxResult;
f422e5 ¤   BOOL bCancel = FALSE;
27d69f ¤   UINT MBoxFlag;
c5af5a
a6077a ¤   MBoxFlag=MB_OKCANCEL;
70af5a
5ff265 ¤   switch(error)
53c7a1 ¤   {
f6b748 ¤   ¤   case WIPE_NOTOPEN:
d486d2 ¤   ¤   ¤   ErrMsg=IDS_WIPENOTOPEN;
37cdcb ¤   ¤   ¤   break;
2f1420 ¤   ¤   case WIPE_USERABORT:
7cd564 ¤   ¤   ¤   ErrMsg=IDS_WIPEUSERABORT;
aa9d4d ¤   ¤   ¤   bCancel = TRUE;
09cdcb ¤   ¤   ¤   break;
a50531 ¤   ¤   case WIPE_NOSTATS:
f634ab ¤   ¤   ¤   ErrMsg=IDS_WIPENOSTATS;
0ecdcb ¤   ¤   ¤   break;
67af5a
6cf444 ¤   ¤   case WIPE_NOREMOVE:
948ca2 ¤   ¤   ¤   ErrMsg=IDS_WIPENOREMOVE;
d9cdcb ¤   ¤   ¤   break;
c267c5 ¤
dc41f1 ¤   ¤   case WIPE_NOFLUSH:
af706b ¤   ¤   ¤   ErrMsg=IDS_WIPENOFLUSH;
bccdcb ¤   ¤   ¤   break;
68af5a
9ba793 ¤   ¤   case WIPE_NOFILEMAP:
2766d7 ¤   ¤   ¤   ErrMsg=IDS_WIPENOFILEMAP;
7acdcb ¤   ¤   ¤   break;
52af5a
b120ae ¤   ¤   case WIPE_NOMEMMAP:
8e5848 ¤   ¤   ¤   ErrMsg=IDS_WIPENOMEMMAP;
72cdcb ¤   ¤   ¤   break;
d6af5a
21a0b3 ¤   ¤   case WIPE_ALREADYOPEN:
4a5353 ¤   ¤   ¤   ErrMsg=IDS_WIPEALREADYOPEN;
92cdcb ¤   ¤   ¤   break;
b9af5a
a3c95e ¤   ¤   case WIPE_WRITEPROTECT:
73c089 ¤   ¤   ¤   ErrMsg=IDS_WIPEPROTECT;
28cdcb ¤   ¤   ¤   break;
d89371 ¤   }
f5af5a
a99500 ¤   LoadString (g_hinst, ErrMsg, StrRes, sizeof(StrRes));
8baf5a
8dd2a0 ¤   // There is no next file, so we don't put up both...
edd845 ¤   if(FileEntry->next==NULL)
1737ef ¤   ¤   MBoxFlag=MB_OK;
52af5a
f20e79 ¤   nMsgBoxResult = MessageBox(hwnd,StrRes,JustFile(FileEntry->name),
f6e8eb ¤   ¤   ¤   ¤   ¤   ¤   MBoxFlag|MB_ICONSTOP|MB_SETFOREGROUND);
f0af5a
75421a ¤   if (nMsgBoxResult == IDCANCEL)
9c6b28 ¤   ¤   bCancel = TRUE;
--63d6 000877208d640110286 Page 2 of wipe.c
e0af5a
d64253 ¤   return bCancel;
52efe6 }
c6af5a
2faf5a
7a4518 BOOL ReadWipePref(PGPContextRef context,
2300c0 ¤   ¤   ¤   ¤   ··PGPBoolean *pbWarnOnWipe)
62bb36 {
cc559a ¤   PGPPrefRef¤ PrefRefClient=NULL;
1561e0 ¤   PGPError¤   err;
84ed37 ¤   PGPMemoryMgrRef memMgr;
45af5a
2789c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
01af5a
f5e7e0 ¤   *pbWarnOnWipe=TRUE;
ef67c5 ¤
bef9bd ¤   err=PGPclOpenClientPrefs (memMgr,&PrefRefClient);
8eaf5a
c5c8d0 ¤   if(IsntPGPError(err))
80c7a1 ¤   {
5fb251 ¤   ¤   PGPGetPrefBoolean (PrefRefClient,
c08de5 ¤   ¤   ¤   kPGPPrefWarnOnWipe, pbWarnOnWipe);
89af5a
cb59b8 ¤   ¤   PGPclCloseClientPrefs (PrefRefClient, FALSE);
49af5a
e8836c ¤   ¤   return TRUE;
ac9371 ¤   }
77a230 ¤   return FALSE;
33efe6 }
6faf5a
c99d77 #define MINDLGX 400
3fd2c6 #define MINDLGY 200
ec63ac #define DLGMARGIN 5
0daf5a
7bec90 int ResizeEm(HWND hdlg)
aebb36 {
2b5915 ····RECT dlgRect;
935558 ¤   int buttx;
406c36 ¤   HWND hwndText,hwndList,hwndYes,hwndNo;
daaf5a
2d07ae ····GetClientRect(hdlg, &dlgRect);
98af5a
b29e17 ····dlgRect.top+=DLGMARGIN;
919f8d ····dlgRect.bottom-=DLGMARGIN;
30a3e2 ····dlgRect.left+=DLGMARGIN;
7956bd ····dlgRect.right-=DLGMARGIN;
f667c5 ¤
0d6e2f ¤   hwndText=GetDlgItem(hdlg,IDC_WIPEQUERY);
c5af5a
b271cf ¤   InvalidateRect(hwndText,NULL,TRUE);
a6af5a
20d232 ¤   MoveWindow(hwndText,
533d96 ¤   ····dlgRect.left,dlgRect.top,
85ec00 ¤   ¤   dlgRect.right-dlgRect.left,30,TRUE);
4baf5a
6d1f5d ¤   hwndList=GetDlgItem(hdlg,IDC_FILELIST);
a9af5a
eb08fc ¤   InvalidateRect(hwndList,NULL,TRUE);
d3af5a
1b06ff ¤   MoveWindow(hwndList,
5d3656 ¤   ¤   dlgRect.left,40+dlgRect.top,
c1a8be ¤   ¤   dlgRect.right-dlgRect.left,dlgRect.bottom-dlgRect.top-80,TRUE);
f8af5a
aebc65 ¤   buttx=(dlgRect.right-dlgRect.left)/2-80+dlgRect.left;
65af5a
890175 ¤   hwndYes=GetDlgItem(hdlg,IDYES);
c2af5a
3cddd2 ¤   InvalidateRect(hwndYes,NULL,TRUE);
b2af5a
d6934f ¤   MoveWindow(hwndYes,
57bef6 ¤   ····buttx,dlgRect.bottom-25,
8770b4 ¤   ¤   75,25,TRUE);
--b8c7 000e1e0bd4240110286 Page 3 of wipe.c
e0af5a
0a098f ¤   hwndNo=GetDlgItem(hdlg,IDNO);
39af5a
b440d7 ¤   InvalidateRect(hwndNo,NULL,TRUE);
7daf5a
c60d1c ¤   MoveWindow(hwndNo,
d59af7 ¤   ····buttx+85,dlgRect.bottom-25,
9e70b4 ¤   ¤   75,25,TRUE);
4aaf5a
8cc2e7 ¤   return TRUE;
3defe6 }
8faf5a
6c2678 BOOL WINAPI DeleteDlgProc(HWND hdlg, UINT uMsg,·
eed85e ·····························WPARAM wParam, LPARAM lParam)
5ebb36 {
25827b ····switch(uMsg)
083b37 ····{
982aad ········case WM_INITDIALOG:
a35b34 ¤   ¤   {
6eae81 ¤   ¤   ¤   FILELIST *flist;
afaf5a
2aa569 ¤   ¤   ¤   flist=(FILELIST *)lParam;
06af5a
0b4c07 ¤   ¤   ¤   while(flist!=0)
1cf776 ¤   ¤   ¤   {
c15413 ¤   ¤   ¤   ¤   SendMessage(GetDlgItem(hdlg,IDC_FILELIST),
4ab156 ¤   ¤   ¤   ¤   ¤   LB_ADDSTRING,0,(LPARAM)flist->name);
2b2811 ¤   ¤   ¤   ¤   flist=flist->next;
50a3a6 ¤   ¤   ¤   }
b767c5 ¤
045bfb ¤   ¤   ¤   ResizeEm(hdlg);
80af5a
45c84b ¤   ¤   ¤   ShowWindow(hdlg,SW_SHOW);
6fe3e2 ¤   ¤   ¤   SetForegroundWindow(hdlg);
a1af5a
8832bd ¤   ¤   ¤   return TRUE;
430fe4 ¤   ¤   }
0faf5a
d14e34 ¤   ¤   case WM_GETMINMAXINFO:
ab5b34 ¤   ¤   {
6c8590 ¤   ¤   ¤   MINMAXINFO* lpmmi;
c1af5a
f0b98a ¤   ¤   ····lpmmi = (MINMAXINFO*) lParam;
7e3d2d ····¤   ¤   lpmmi->ptMinTrackSize.x = MINDLGX;
6b625c ····¤   ¤   lpmmi->ptMinTrackSize.y = MINDLGY;
358632 ············break;
360fe4 ¤   ¤   }
aaaf5a
e23c22 ········case WM_SIZE:
5b2b60 ········{
ab8148 ············ResizeEm(hdlg);
878632 ············break;
077fb0 ········}
9eaf5a
052c97 ¤   ¤   case WM_CLOSE:
66d725 ¤   ¤   case WM_QUIT:
acdad9 ¤   ¤   case WM_DESTROY:
225b34 ¤   ¤   {
21d720 ¤   ¤   ¤   EndDialog(hdlg, FALSE);
a5cdcb ¤   ¤   ¤   break;
840fe4 ¤   ¤   }
1eaf5a
8faff6 ········case WM_COMMAND:
af2b60 ········{
a914e1 ············switch(wParam)
4d2cc2 ············{
014e9e ¤   ¤   ¤   ¤   case IDYES:
6872c3 ¤   ¤   ¤   ¤   {
2e6d11 ¤   ¤   ¤   ¤   ¤   EndDialog(hdlg, TRUE);
e514c3 ¤   ¤   ¤   ¤   ¤   break;
ee2613 ¤   ¤   ¤   ¤   }
e1af5a
--ab6b 0006c57663540110286 Page 4 of wipe.c
bc9eb2 ¤   ¤   ¤   ¤   case IDNO:
1172c3 ¤   ¤   ¤   ¤   {
a19a13 ¤   ¤   ¤   ¤   ¤   EndDialog(hdlg, FALSE);
4c14c3 ¤   ¤   ¤   ¤   ¤   break;
6f2613 ¤   ¤   ¤   ¤   }
3aa3a6 ¤   ¤   ¤   }
2ccdcb ¤   ¤   ¤   break;
670fe4 ¤   ¤   }
749371 ¤   }
6ca230 ¤   return FALSE;
11efe6 }
31af5a
2a7b30 PGPError WipeFileListStub (MYSTATE *ms)·
9fbb36 {
8f64a2 ¤   PGPContextRef context;
6d0e89 ¤   FILELIST *FileCurrent;
a49532 ¤   UINT WipeReturn;
896672 ¤   char StrRes[500];
4d0040 ¤   PGPError err;
feaf5a
714ead ¤   err=kPGPError_NoErr;
d3af5a
432d85 ¤   context=ms->context;
afaf5a
81820b ¤   FileCurrent=ms->ListHead;
f3af5a
75935f ¤   while(!(ms->ws.CancelPending)&&(FileCurrent!=0)&&(IsntPGPError(err)))
cffce6 ¤   { ···
617505 ¤   ¤   if(FileCurrent->IsDirectory)
de5b34 ¤   ¤   {
ff37e7 ¤   ¤   ¤   int result;
a8af5a
28f608 ¤   ¤   ¤   result=_rmdir(FileCurrent->name);
36af5a
a9e709 ¤   ¤   ¤   if(result!=0)
a0f776 ¤   ¤   ¤   {
57e002 ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_DIRNOTREMOVED, StrRes, sizeof(StrRes));
8daf5a
2cc214 ¤   ¤   ¤   ¤   MessageBox(ms->hwndWorking,FileCurrent->name,StrRes,
3810ad ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
da6296 ¤   ¤   ¤   ¤   err=kPGPError_UnknownError;
baa3a6 ¤   ¤   ¤   }
36af5a
bbf94b ¤   ¤   ¤   FileCurrent=FileCurrent->next;
0417f5 ¤   ¤   ¤   continue;
de0fe4 ¤   ¤   }
c3af5a
685289 ¤   ¤   WipeReturn=InternalFileWipe(ms->context,
673136 ¤   ¤   ¤   ms->hwndWorking,FileCurrent->name);
21af5a
c2066d ¤   ¤   if(WipeReturn!=WIPE_OK)
885b34 ¤   ¤   {
066809 ¤   ¤   ¤   if (WipeError(ms->hwndWorking,FileCurrent,WipeReturn))
946296 ¤   ¤   ¤   ¤   err=kPGPError_UnknownError;
c40fe4 ¤   ¤   }
91af5a
820465 ¤   ¤   FileCurrent=FileCurrent->next;¤ ¤   ¤   ¤
569371 ¤   }
e3af5a
455ea8 ¤   return err;
48efe6 }
18af5a
ffaf5a
3f84fe BOOL WipeFileList(HWND hwnd,void *PGPsc,FILELIST *ListHead)
33bb36 {
bec944 ¤   MYSTATE *ms;
ca88d1 ¤   PGPBoolean bWarnOnWipe;
b046ec ¤   BOOL DeleteThem;
0764a2 ¤   PGPContextRef context;
280040 ¤   PGPError err;
20af5a
6c4ead ¤   err=kPGPError_NoErr;
--154c 000f03e912e40110286 Page 5 of wipe.c
e0af5a
eb625b ¤   context=(PGPContextRef)PGPsc;
deaf5a
b9df10 ¤   ReadWipePref(context,&bWarnOnWipe);
0faf5a
ce0d72 ¤   if(bWarnOnWipe)
90c7a1 ¤   {
6146ba ¤   ¤   DeleteThem=DialogBoxParam(g_hinst,·
6a5e71 ¤   ¤   ¤   MAKEINTRESOURCE( IDD_DELETEDLG),
ebfd46 ············hwnd,·
a4a7ba ············(DLGPROC) DeleteDlgProc,·
2087c9 ············(LPARAM) ListHead);
bfaf5a
c47c4c ¤   ¤   if(!DeleteThem)
c15b34 ¤   ¤   {
885f1f ¤   ¤   ¤   return FALSE;
3f0fe4 ¤   ¤   }
1a9371 ¤   }
d7af5a
c2229d ¤   ms=(MYSTATE *)malloc(sizeof(MYSTATE));
21af5a
0ba558 ¤   if(ms)
efc7a1 ¤   {
05e546 ¤   ¤   memset(ms, 0x00, sizeof(MYSTATE) );
e2af5a
8fc589 ¤   ¤   LoadString (g_hinst, IDS_STARTINGWORK, ms->ws.StartText, sizeof(ms->ws.¶
f93361 StartText));
2552f0 ¤   ¤   LoadString (g_hinst, IDS_FINISHINGUP, ms->ws.EndText, sizeof(ms->ws.End¶
06b48e Text));
f1af5a
62e914 ¤   ¤   ms->context=context;
7357fa ¤   ¤   ms->ListHead=ListHead;
426a7a ¤   ¤   ms->Operation=MS_WIPEFILELIST;
6467c5 ¤
7fc976 ¤   ¤   err=DoWork(hwnd,ms);
3eaf5a
b03d9b ¤   ¤   free(ms);
9f9371 ¤   }
d167c5 ¤
d12133 ¤   FreeFileList(ListHead);
7caf5a
07ee15 ¤   if(IsPGPError(err))
4198aa ¤   ¤   return FALSE;
a6af5a
eec2e7 ¤   return TRUE;
4defe6 }
43af5a
80318c UINT InternalFileWipe(PGPContextRef context,HWND hwnd,char *FileName)
d9bb36 {
0daf5a
932202 ¤   DWORD dwSize;
c0382e ¤   DWORD dwPageSize;
0e27e6 ¤   DWORD dwNumPages;
c6ad05 ¤   SYSTEM_INFO sysinfo;
5f48ec ¤   char NewFileName[200+_MAX_DIR];
2219a3 ¤   char szDrive[_MAX_DRIVE];
636518 ¤   char szDir[ _MAX_DIR];
80736b ¤   char szNewFile[200-_MAX_DRIVE];
f273f4 ¤   HANDLE hFile;
689895 ¤   HANDLE hMap;
e4343f ¤   LPSTR lpFile;
5cc2cd ¤   int count = 0;
8fc1cb ····BOOL CancelOperation;
4aa4cc ¤   BOOL bMoveFileSuccess;
689dff ····struct _stat buf;
52e71b ¤   UINT wipe_err = 0;
b6c944 ¤   MYSTATE *ms;
711f35 ¤   int staterror;
f16672 ¤   char StrRes[500];
37af5a
15eb39 ¤   PGPError¤   ¤   error¤  ¤   ¤   = kPGPError_NoErr;
f05bab ¤   PGPDiskWipeRef¤ wipeRef¤¤   ¤   = kPGPInvalidRef;
--f071 0007a3262c040110286 Page 6 of wipe.c
bd5f54 ¤   PGPInt32¤   ¤   buffer[256];
67216e ¤   PGPInt32¤   ¤   passes¤ ¤   ¤   = kPGPNumPatterns;
dc0ca3 ¤   PGPPrefRef¤ ¤   prefRef¤¤   ¤   = kPGPInvalidRef;
eaa9bb ¤   PGPMemoryMgrRef memMgr¤ ¤   ¤   = kPGPInvalidRef;
dcaf5a
9cf678 ¤   if( IsntPGPError(error) )
29c7a1 ¤   {
ab58f8 ¤   ¤   memMgr = PGPGetContextMemoryMgr(context);
ab67c5 ¤
63a04e ¤   ¤   error = PGPclOpenClientPrefs (memMgr, &prefRef);
50af5a
41e0b6 ¤   ¤   if(IsntPGPError(error))
fc5b34 ¤   ¤   {
80d95c ¤   ¤   ¤   PGPGetPrefNumber (¤ prefRef,
d70cab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefFileWipePasses,·
93e672 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUInt32*)&passes);
92af5a
9a90ec ¤   ¤   ¤   PGPclCloseClientPrefs (prefRef, FALSE);
98af5a
4e0fe4 ¤   ¤   }
cf9371 ¤   }
eaaf5a
4ddc20 ¤   GetSystemInfo(&sysinfo);
6aaf5a
e99e08 ¤   dwPageSize = sysinfo.dwPageSize;
1caf5a
0f7dca ¤   staterror=_stat(FileName, &buf );
81af5a
9c58f1 ¤   if(staterror!=0)
7c5783 ¤   ¤   return WIPE_NOTOPEN; // check to make sure still around
c7af5a
7d1099 ····if(hwnd!=NULL)
ed975c ¤   ¤   ms=(MYSTATE *)GetWindowLong(hwnd, GWL_USERDATA);
5f67c5 ¤
035957 ¤   if(hwnd!=NULL)
6ac7a1 ¤   {
3505ad ¤   ¤   LoadString (g_hinst, IDS_WIPINGFILE, StrRes, sizeof(StrRes));
d3af5a
f4e473 ¤   ¤   sprintf(ms->ws.TitleText,StrRes,JustFile(FileName));
631b52 ¤   ¤
e64fd9 ¤   ¤   SendMessage(hwnd, PGPM_PROGRESS_UPDATE,
84c291 ¤   ¤   ¤   (WPARAM)PGPSC_WORK_NEWFILE,0);
1e9371 ¤   }
4167c5 ¤
37d330 ¤   _splitpath(FileName, szDrive, szDir, NULL, NULL);
d6af5a
c3ab76 ¤   memset(szNewFile, 'a', sizeof(szNewFile)-1);
506ce7 ¤   szNewFile[sizeof(szNewFile)-1] = 0;
efaf1f ¤   strcpy(NewFileName, szDrive);
0985c3 ¤   strcat(NewFileName, szDir); // do in same directory
a1b37a ¤   strcat(NewFileName, szNewFile);
f2af5a
d7fff7 ¤   bMoveFileSuccess = MoveFile(FileName, NewFileName);
45fd5e ¤   if (!bMoveFileSuccess)
79c7a1 ¤   {
bd3dfe ¤   ¤   DWORD dwLastError;
d8af5a
04d7a3 ¤   ¤   dwLastError = GetLastError();
cbaf5a
925c8a ¤   ¤   switch (dwLastError)
435b34 ¤   ¤   {
f9b085 ¤   ¤   ¤   case ERROR_SHARING_VIOLATION:
ccddfa ¤   ¤   ¤   ¤   return WIPE_ALREADYOPEN;
7eaf5a
156221 ¤   ¤   ¤   case ERROR_WRITE_PROTECT:
cb55e2 ¤   ¤   ¤   ¤   return WIPE_WRITEPROTECT;
32af5a
2f38af ¤   ¤   ¤   case ERROR_REQUEST_ABORTED:
5640f2 ¤   ¤   ¤   ¤   return WIPE_USERABORT;
5daf5a
a3d01a ¤   ¤   ¤   case ERROR_ACCESS_DENIED:
7adb68 ¤   ¤   ¤   default:
--4446 00017fbbe9c40110286 Page 7 of wipe.c
2fbeb5 ¤   ¤   ¤   ¤   return WIPE_NOTOPEN;
ab0fe4 ¤   ¤   }
3f9371 ¤   }
48af5a
af5957 ¤   if(hwnd!=NULL)
a5c7a1 ¤   {
d23709 ¤   ¤   CancelOperation=WorkingCallback(hwnd,
557630 ¤   ¤   ¤   (int)(1.0*0.16*(float)buf.st_size),buf.st_size) ;
061b52 ¤   ¤
756ce1 ¤   ¤   if(CancelOperation)
3a5b34 ¤   ¤   {
1cfec0 ¤   ¤   ¤   MoveFile(NewFileName,FileName);
830101 ¤   ¤   ¤   return WIPE_USERABORT;
8a0fe4 ¤   ¤   }
289371 ¤   }
15af5a
a202a5 ¤   hFile = CreateFile(¤NewFileName,·
1e3dca ¤   ¤   ¤   ¤   ¤   ¤   GENERIC_READ | GENERIC_WRITE,
e8e7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
06aec3 ¤   ¤   ¤   ¤   ¤   ¤   NULL,
8f0b9e ¤   ¤   ¤   ¤   ¤   ¤   OPEN_EXISTING,·
43bd51 ¤   ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,·
da2a8d ¤   ¤   ¤   ¤   ¤   ¤   NULL );
7baf5a
9eeab9 ¤   if( hFile == INVALID_HANDLE_VALUE ) ·// ·If unable to open, skip it
12c7a1 ¤   {
46f0cf ¤   ¤   dwSize = GetLastError(); ······// ·These calls are for debugging
4876a6 ¤   ¤   MoveFile(NewFileName,FileName);
d5388b ¤   ¤   return WIPE_NOTOPEN;
2c9371 ¤   }
9faf5a
eb5957 ¤   if(hwnd!=NULL)
26c7a1 ¤   {
5d29f2 ¤   ¤   CancelOperation=WorkingCallback (hwnd,
bbfee8 ¤   ¤   ¤   (int)(2.0*0.16*(float)buf.st_size),buf.st_size) ;
671b52 ¤   ¤
ab6ce1 ¤   ¤   if(CancelOperation)
fa5b34 ¤   ¤   {
6ce7a8 ¤   ¤   ¤   CloseHandle( hFile );
92fec0 ¤   ¤   ¤   MoveFile(NewFileName,FileName);
c80101 ¤   ¤   ¤   return WIPE_USERABORT;
0d0fe4 ¤   ¤   }
5e9371 ¤   }
36af5a
105ff5 ¤   dwSize = GetFileSize( hFile, NULL ); ·······// ·Get the file's size
73af5a
e13217 ¤   if( dwSize==0 )·
4ec7a1 ¤   {
b9d0a0 ¤   ¤   CloseHandle( hFile );
9e1c2a ¤   ¤   DeleteFile( NewFileName );¤ ¤   // ·If nothing to erase, just kill it
f1af5a
69fa39 ¤   ¤   return WIPE_OK;
5f9371 ¤   }
aeaf5a
36efa4 ¤   /* we want to wipe out to next page boundary */
fcaf5a
f3128a ¤   // Get up to one more page to make fit
ae1bbf ¤   dwNumPages = (dwSize+dwPageSize-1)/dwPageSize;
4487c7 ¤   ¤   ¤
bd6673 ¤   dwSize = dwNumPages * dwPageSize;
d4af5a
725957 ¤   if(hwnd!=NULL)
6ec7a1 ¤   {
5f29f2 ¤   ¤   CancelOperation=WorkingCallback (hwnd,
6e7eaf ¤   ¤   ¤   (int)(3.0*0.16*(float)buf.st_size),buf.st_size) ;
9c1b52 ¤   ¤
8b6ce1 ¤   ¤   if(CancelOperation)
a55b34 ¤   ¤   {
60e7a8 ¤   ¤   ¤   CloseHandle( hFile );
64fec0 ¤   ¤   ¤   MoveFile(NewFileName,FileName);
e10101 ¤   ¤   ¤   return WIPE_USERABORT;
170fe4 ¤   ¤   }
--91e0 000f21904a440110286 Page 8 of wipe.c
a19371 ¤   }
93af5a
4fb069 ¤   // ·Create a file mapping object
cba279 ¤   hMap = CreateFileMapping( hFile, NULL, PAGE_READWRITE,·
7fdc96 ¤   ¤   ¤   ¤   ¤   ¤   ··0, 0, NULL );
042b86 ¤   if( ! hMap )
60c7a1 ¤   {
987912 ¤   ¤   dwSize = GetLastError(); ·······// ·If it didn't work, next file
0dd0a0 ¤   ¤   CloseHandle( hFile );
ae76a6 ¤   ¤   MoveFile(NewFileName,FileName);
6b3ecd ¤   ¤   return WIPE_NOFILEMAP;
929371 ¤   }
44af5a
175957 ¤   if(hwnd!=NULL)
68c7a1 ¤   {
2429f2 ¤   ¤   CancelOperation=WorkingCallback (hwnd,
37e749 ¤   ¤   ¤   (int)(4.0*0.16*(float)buf.st_size),buf.st_size) ;
4b1b52 ¤   ¤
426ce1 ¤   ¤   if(CancelOperation)
9c5b34 ¤   ¤   {
aae7a8 ¤   ¤   ¤   CloseHandle( hFile );
48fec0 ¤   ¤   ¤   MoveFile(NewFileName,FileName);
750101 ¤   ¤   ¤   return WIPE_USERABORT;
d10fe4 ¤   ¤   }
229371 ¤   }
d2af5a
3a7dac ¤   // ·Map the file into a memory space...
1d8c06 ¤   lpFile = MapViewOfFile( hMap, FILE_MAP_WRITE, 0, 0, 0 );
c7af5a
4211b6 ¤   if( lpFile == NULL )
68c7a1 ¤   {
74064e ¤   ¤   dwSize = GetLastError(); ·············// ·On error, back way out
25d0a0 ¤   ¤   CloseHandle( hFile );
22ebc3 ¤   ¤   CloseHandle( hMap );
ac76a6 ¤   ¤   MoveFile(NewFileName,FileName);
0597b2 ¤   ¤   return WIPE_NOMEMMAP;
f09371 ¤   }
a4af5a
c75957 ¤   if(hwnd!=NULL)
dac7a1 ¤   {
fc29f2 ¤   ¤   CancelOperation=WorkingCallback (hwnd,
24670e ¤   ¤   ¤   (int)(5.0*0.16*(float)buf.st_size),buf.st_size) ;
e51b52 ¤   ¤
cb6ce1 ¤   ¤   if(CancelOperation)
ae5b34 ¤   ¤   {
1ee7a8 ¤   ¤   ¤   CloseHandle( hFile );
6e5095 ¤   ¤   ¤   CloseHandle( hMap );
8bfec0 ¤   ¤   ¤   MoveFile(NewFileName,FileName);
a20101 ¤   ¤   ¤   return WIPE_USERABORT;
3f0fe4 ¤   ¤   }
c99371 ¤   }
ebaf5a
3c3ebd ¤   // we are now using Colin's patterns
4aaf5a
abe063 ¤   error = PGPCreateDiskWiper(¤context, &wipeRef, passes);
e567c5 ¤
24f678 ¤   if( IsntPGPError(error) )
5bc7a1 ¤   {
516ac4 ¤   ¤   while( IsntPGPError( PGPGetDiskWipeBuffer(wipeRef, buffer) ) )
e3ed49 ¤   ¤   {¤
38396d ¤   ¤   ¤   DWORD count;
6faf5a
eb5cbc ¤   ¤   ¤   for( count = 0; count < dwSize; count += 1024)
aaf776 ¤   ¤   ¤   {
7e7246 ¤   ¤   ¤   ¤   memcpy(lpFile + count, buffer, 1024);
1fa3a6 ¤   ¤   ¤   }
b5af5a
884bf0 ¤   ¤   ¤   FlushViewOfFile( lpFile, dwSize ); ·// ·Flush it to disk*/
42bdba ¤   ¤   ¤   FlushFileBuffers( hFile );
5d0fe4 ¤   ¤   }
93af5a
f20d24 ¤   ¤   error = PGPDestroyDiskWiper(wipeRef);
--04a6 001c054af1740110286 Page 9 of wipe.c
a19371 ¤   }
93af5a
f6863b ¤   UnmapViewOfFile( lpFile );¤ ¤   ¤   // ·Kill mapped area
c7af5a
e3b24e ¤   CloseHandle( hMap ); ···············// Close all the handles and...
ee7036 ¤   FlushFileBuffers( hFile );
7159f4 ¤   CloseHandle( hFile );
be0d1d ¤   DeleteFile( NewFileName ); ·········// ·...(finally) delete the file
57af5a
b35957 ¤   if(hwnd!=NULL)
00c7a1 ¤   {
8d29f2 ¤   ¤   CancelOperation=WorkingCallback (hwnd,
44206d ¤   ¤   ¤   buf.st_size,buf.st_size) ;
b69371 ¤   }
33af5a
0880cd ¤   return WIPE_OK;
6defe6 }
f8af5a
7a811f BOOL ClipboardWipe(HWND hwnd,void *PGPsc)
94bb36 {
60da60 ¤   int result;
cf88d1 ¤   PGPBoolean bWarnOnWipe;
c164a2 ¤   PGPContextRef context;
1f5918 ¤   int rst;
38af5a
f1625b ¤   context=(PGPContextRef)PGPsc;
50af5a
2e5957 ¤   if(hwnd!=NULL)
04c7a1 ¤   {
3f5776 ¤   ¤   ReadWipePref(context,&bWarnOnWipe);
1baf5a
dc7786 ¤   ¤   if(bWarnOnWipe)
965b34 ¤   ¤   {
e8a79f ¤   ¤   ¤   rst=PGPscMessageBox (hwnd,IDS_LASTCHANCE,IDS_REALLYWIPECLIPBOARD,
6ca25a ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_DEFBUTTON2|MB_ICONEXCLAMATION);¤
b0af5a
015143 ¤   ¤   ¤   if(rst==IDNO)
29d64b ¤   ¤   ¤   ¤   return FALSE;
000fe4 ¤   ¤   }
4f9371 ¤   }
7baf5a
87713f ¤   OpenClipboard(NULL);
16af5a
05def0 ¤   result=EmptyClipboard();
24af5a
7d9ed4 ¤   CloseClipboard();
eeaf5a
e45d73 ¤   return result;
6cefe6 }
9caf5a
d57e4d /*__Editor_settings____
d4af5a
174126 ¤   Local Variables:
527b17 ¤   tab-width: 4
0d0e6c ¤   End:
d55f8c ¤   vi: ts=4 sw=4
679e9b ¤   vim: si
c0d062 _____________________*/
--7894 000d1c89ff940110287 Page 1 of working.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
0c8b1b ¤   $Id: working.c,v 1.24.2.1.2.1 1998/11/12 03:13:40 heller Exp $
c4f7f7 ____________________________________________________________________________*/
385ed8 #include "precomp.h"
97af5a
8a4b3d int WorkingCallback (void* arg, unsigned long SoFar, unsigned long Total)·
41bb36 {
3f539d ¤   WORKSTRUCT *ws;
9755cf ¤   HWND hwnd;
10cd6f ¤   MYSTATE *myState;
77af5a
849be4 ¤   hwnd=(HWND)arg;
ece8c6 ···
5e5c6b ¤   myState = (MYSTATE *) GetWindowLong(hwnd, GWL_USERDATA);
e2d35b ¤   ws = &(myState->ws);
8aaf5a
6b5043 ¤   ws->newsofar=SoFar;
98fd11 ¤   ws->total=Total;
bbaf5a
b45789 ¤   SendMessage(hwnd, PGPM_PROGRESS_UPDATE,
b63713 ¤   ¤   (WPARAM)PGPSC_WORK_PROGRESS,0);
dbaf5a
3297ae ¤   if(ws->CancelPending)
77c7a1 ¤   {
44836c ¤   ¤   return TRUE;
989371 ¤   }
80af5a
19a230 ¤   return FALSE;
d6efe6 }
07af5a
6f55b9 DWORD WINAPI
6bcf46 DoWorkThread (LPVOID lpvoid)·
2dbb36 {
a2cd6f ¤   MYSTATE *myState;
e60040 ¤   PGPError err;
3b499b ¤   DWORD nOleErr;
58af5a
52396f ¤   myState=(MYSTATE *)lpvoid;
dbaf5a
11827c ¤   nOleErr = OleInitialize(NULL);
cfaf5a
dd0a36 ¤   if ((nOleErr == S_OK) || (nOleErr == S_FALSE))
7bc7a1 ¤   {
ca73b7 ¤   ¤   switch(myState->Operation)
555b34 ¤   ¤   {
50aa24 ¤   ¤   ¤   case MS_ENCRYPTFILELIST:
3a431f ¤   ¤   ¤   ¤   err=EncryptFileListStub (myState);
b4f622 ¤   ¤   ¤   ¤   break;
47af5a
c9b040 ¤   ¤   ¤   case MS_ENCRYPTCLIPBOARD:
c16674 ¤   ¤   ¤   ¤   err=EncryptClipboardStub (myState);
15f622 ¤   ¤   ¤   ¤   break;
6eaf5a
0670ce ¤   ¤   ¤   case MS_DECRYPTFILELIST:
1ce8b7 ¤   ¤   ¤   ¤   err=DecryptFileListStub (myState);
e5f622 ¤   ¤   ¤   ¤   break;
1daf5a
28f8ce ¤   ¤   ¤   case MS_DECRYPTCLIPBOARD:
1c4f9d ¤   ¤   ¤   ¤   err=DecryptClipboardStub (myState);
86f622 ¤   ¤   ¤   ¤   break;
eeaf5a
7bda7d ¤   ¤   ¤   case MS_ADDKEYFILELIST:
2a3e03 ¤   ¤   ¤   ¤   err=AddKeyFileListStub (myState);
7ff622 ¤   ¤   ¤   ¤   break;
b1af5a
747f74 ¤   ¤   ¤   case MS_ADDKEYCLIPBOARD:
d1bce4 ¤   ¤   ¤   ¤   err=AddKeyClipboardStub (myState);
--2035 00018e9f7aa40110287 Page 2 of working.c
72f622 ¤   ¤   ¤   ¤   break;
3faf5a
0669d6 ¤   ¤   ¤   case MS_WIPEFILELIST:
72536c ¤   ¤   ¤   ¤   err=WipeFileListStub (myState);
72f622 ¤   ¤   ¤   ¤   break;
d10fe4 ¤   ¤   }
d47c12 ¤   ¤   OleUninitialize();
599371 ¤   }
35af5a
35f63c ¤   myState->err=err;
40af5a
9db419 ¤   SendMessage(myState->hwndWorking,WM_DESTROY,0,0);
c8c22e ¤   ReleaseSemaphore(myState->hSemaphore, 1, NULL);
b53e6b ¤   return 0;
5befe6 }
26af5a
8faf5a
456ea8 BOOL CALLBACK WorkingDlgProc (HWND hDlg,·
af6983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
c41eda ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,
68b79e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
46bb36 {
facd6f ¤   MYSTATE *myState;
fe539d ¤   WORKSTRUCT *ws;
57af5a
73e234 ¤   switch (uMsg)·
55c7a1 ¤   {
56df25 ¤   ¤   case WM_INITDIALOG:
0950a4 ¤   ¤   { ···
4fafc0 ¤   ¤   ¤   RECT rc;
64af5a
e820eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
fd78f3 ¤   ¤   ¤   myState=(MYSTATE *)lParam;
c21c5c ¤   ¤   ¤   myState->hwndWorking=hDlg;
b7af5a
bad692 ¤   ¤   ¤   CreateThread (NULL, 0, DoWorkThread,·
5b04a9 ¤   ¤   ¤   ¤   (LPVOID)myState, 0, &(myState->dwThreadID));
edaf5a
9c59b9 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETRANGE, 0,·
f9d5e1 ¤   ¤   ¤   ¤   MAKELPARAM(0, 100));
3ff472 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS, 0, 0);
7aaf5a
f20e50 ·¤  ¤   ¤   GetWindowRect (hDlg, &rc);
2e1ebe ¤   ¤   ¤   SetWindowPos (hDlg, NULL,
2b73f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
5bdb5a ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2,
f9f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
83de7b ··
666682 ¤   ¤   ¤   SetForegroundWindow(hDlg);
b332bd ¤   ¤   ¤   return TRUE;
d30fe4 ¤   ¤   }
4faf5a
1a9dfe ¤   ¤   case WM_CTLCOLOR:
86c329 ¤   ¤   { ·········
db691e ·¤  ¤   ¤   if(wParam!=0)
3f330a ¤   ¤   ¤   {·
372276 ¤   ¤   ¤   ¤   DWORD color;
05af5a
29a03d ¤   ¤   ¤   ¤   color=GetSysColor(COLOR_BTNFACE);
6c2b85 ¤   ¤   ¤   ¤
597c37 ¤   ¤   ¤   ··¤ SetBkColor ((HDC)wParam, color);
86239d ¤   ¤   ¤   ··¤ SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOWTEXT));
0837bc ¤   ¤   ¤   ··¤ return (BOOL)CreateSolidBrush (color);
692efb ¤   ¤   ¤   } ¤ ·
00cdcb ¤   ¤   ¤   break;
3c0fe4 ¤   ¤   }
90af5a
813962 ¤   ¤   case PGPM_PROGRESS_UPDATE:
675b34 ¤   ¤   {
b4380b ¤   ¤   ¤   int done, total;
0eaf5a
18e481 ¤   ¤   ¤   myState = (MYSTATE *) GetWindowLong(hDlg, GWL_USERDATA);
--22b9 000797849fc40110287 Page 3 of working.c
075c50 ¤   ¤   ¤   ws = &(myState->ws);
05af5a
44b2db ¤   ¤   ¤   if(wParam==PGPSC_WORK_NEWFILE)
72f776 ¤   ¤   ¤   {
46170f ¤   ¤   ¤   ¤   SendMessage(hDlg, WM_SETTEXT, 0, (LPARAM)ws->TitleText);
0d4378 ¤   ¤   ¤   ¤   SetDlgItemText(hDlg, IDC_PROGRESS_TEXT,ws->StartText);
d1af5a
c83bba ¤   ¤   ¤   ¤   ws->sofar=0;
29e87f ¤   ¤   ¤   ¤   ws->newsofar=0;
cd85d2 ¤   ¤   ¤   ¤   ws->total=0;
25c15a ¤   ¤   ¤   ¤   ws->curpos=0;
3aaf5a
3a24cf ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS, ws->curpos,¶
9d40df ·0);
98af5a
17511a ¤   ¤   ¤   ¤   ShowWindow(hDlg,SW_SHOW);
c8f622 ¤   ¤   ¤   ¤   break;
dba3a6 ¤   ¤   ¤   }
56af5a
8cf15f ¤   ¤   ¤   if(ws->sofar != ws->total)
84f776 ¤   ¤   ¤   {
930c7f ¤   ¤   ¤   ¤   if(ws->newsofar!=ws->sofar)
ac72c3 ¤   ¤   ¤   ¤   {
b39c13 ¤   ¤   ¤   ¤   ¤   char completed[500];
88f0e8 ¤   ¤   ¤   ¤   ¤   char StrRes[500];
abaf5a
902c28 ¤   ¤   ¤   ¤   ¤   ws->sofar=ws->newsofar;
53af5a
309f87 ¤   ¤   ¤   ¤   ¤   done=ws->sofar;
e83c17 ¤   ¤   ¤   ¤   ¤   total=ws->total;
35af5a
c61bd0 ¤   ¤   ¤   ¤   ¤   ws->curpos = (long) (((float)done / (float)total) *
a03c70 ¤   ¤   ¤   ¤   ¤   (float)100.0);
a2af5a
a9e68c ¤   ¤   ¤   ¤   ¤   done /= 1024;
aeabdd ¤   ¤   ¤   ¤   ¤   total /= 1024;
60af5a
71a80e ¤   ¤   ¤   ¤   ¤   if(total==0)
0bc81a ¤   ¤   ¤   ¤   ¤   ¤   break; // Don't want 0 of 0K etc.
25af5a
3e09af ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_WORKPERCENT, StrRes, sizeof(StrRes¶
191445 ));
b4af5a
f7d164 ¤   ¤   ¤   ¤   ¤   sprintf(completed, StrRes, done, total);
4c4752 ¤   ¤   ¤   ¤   ¤   SetDlgItemText(hDlg, IDC_PROGRESS_TEXT, completed);
b6af5a
8b9803 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS, ws->cur¶
d4cfdd pos, 0);
d02613 ¤   ¤   ¤   ¤   }
f5f622 ¤   ¤   ¤   ¤   break;
72a3a6 ¤   ¤   ¤   }
bfaf5a
fd625a ¤   ¤   ¤   SetDlgItemText(hDlg, IDC_PROGRESS_TEXT,ws->EndText);
edaf5a
603c12 ¤   ¤   ¤   ws->curpos=100;·
0c9ce2 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS, ws->curpos, 0);
78cdcb ¤   ¤   ¤   break;
4d0fe4 ¤   ¤   }
dbaf5a
93618f //¤ ¤   case WM_SETCURSOR:
79af96 //¤ ¤   {
0eb951 //¤ ¤   ¤   SetCursor(LoadCursor(NULL,IDC_WAIT));
939525 //¤ ¤   ¤   return TRUE;
92fb46 //¤ ¤   }
edaf5a
e52c97 ¤   ¤   case WM_CLOSE:
8dd725 ¤   ¤   case WM_QUIT:
28dad9 ¤   ¤   case WM_DESTROY:
6b5b34 ¤   ¤   {
256280 ¤   ¤   ¤   EndDialog(hDlg, FALSE);
39cdcb ¤   ¤   ¤   break;
790fe4 ¤   ¤   }
--81fa 001d31bae7040110287 Page 4 of working.c
e0af5a
2f8e1e ¤   ¤   case WM_COMMAND:
a95b34 ¤   ¤   {
71256f ¤   ¤   ¤   switch(LOWORD (wParam))·
27f776 ¤   ¤   ¤   {
588722 ¤   ¤   ¤   ¤   case IDCANCEL:
e372c3 ¤   ¤   ¤   ¤   {
837e2d ¤   ¤   ¤   ¤   ¤   myState = (MYSTATE *) GetWindowLong(hDlg, GWL_USERDATA);
1f64d5 ¤   ¤   ¤   ¤   ¤   ws = &(myState->ws);
354f37 ¤   ¤   ¤   ¤   ¤   ws->CancelPending=TRUE;
9714c3 ¤   ¤   ¤   ¤   ¤   break;
d72613 ¤   ¤   ¤   ¤   }
d1a3a6 ¤   ¤   ¤   }
dccdcb ¤   ¤   ¤   break;
940fe4 ¤   ¤   }
4e9371 ¤   }
41a230 ¤   return FALSE;
a0efe6 }
daaf5a
efc487 PGPError DoWork(HWND hwndParent,MYSTATE *myState)
84bb36 {
004bba ¤   // Just to be sure, a semaphore reinforces the barrier
a758c2 ¤   // made by the DialogBox.
f7ab6f ¤   myState->hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
20af5a
916645 ¤   DialogBoxParam (g_hinst,·
22256e ¤   ¤   MAKEINTRESOURCE(IDD_NEWWORKING),
5ca79d ¤   ¤   hwndParent,·
bfbd1a ¤   ¤   (DLGPROC)WorkingDlgProc,·
05084a ¤   ¤   (LPARAM)myState);
80af5a
73b49d ¤   WaitForSingleObject (myState->hSemaphore, INFINITE);
4fcd8b ¤   CloseHandle (myState->hSemaphore);
a4af5a
811b6f ¤   return myState->err;
8fefe6 }
12af5a
887e4d /*__Editor_settings____
97af5a
614126 ¤   Local Variables:
e87b17 ¤   tab-width: 4
4c0e6c ¤   End:
aa5f8c ¤   vi: ts=4 sw=4
d19e9b ¤   vim: si
d3d062 _____________________*/
--c976 001a837f27040110288 Page 1 of working.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c22291 ¤   $Id: working.h,v 1.19.8.1 1998/11/12 03:13:41 heller Exp $
96f7f7 ____________________________________________________________________________*/
e2ea96 #ifndef Included_WORKING_h¤ /* [ */
d4ea07 #define Included_WORKING_h
5daf5a
77651f #include "events.h"
edaf5a
75fd65 #define PGPSC_WORK_PROGRESS 0
87dd78 #define PGPSC_WORK_NEWFILE 1
d5af5a
777cc6 #define PGPM_PROGRESS_UPDATE ·WM_USER + 100
3faf5a
1a4d2f #define MS_ENCRYPTFILELIST 1
35b9af #define MS_ENCRYPTCLIPBOARD 2
243611 #define MS_DECRYPTFILELIST 3
778041 #define MS_DECRYPTCLIPBOARD 4
b4da47 #define MS_ADDKEYFILELIST 5
235277 #define MS_ADDKEYCLIPBOARD 6
4ba71a #define MS_WIPEFILELIST 7
06af5a
e7d0da PGPError DecryptFileListStub (MYSTATE *ms) ;
49afbe PGPError DecryptClipboardStub (MYSTATE *ms) ;
7b0216 PGPError EncryptFileListStub (MYSTATE *ms) ;
44a30c PGPError EncryptClipboardStub (MYSTATE *ms) ;
28433f PGPError AddKeyFileListStub (MYSTATE *ms) ;
c11f8e PGPError AddKeyClipboardStub (MYSTATE *ms) ;
8534a4 PGPError WipeFileListStub (MYSTATE *ms) ;
93af5a
11f053 PGPError DoWork(HWND hwndParent,MYSTATE *myState);
92af5a
d3ef71 int WorkingCallback (void* arg, unsigned long SoFar, unsigned long Total) ;
7aaf5a
bb95c6 #define WIPE_OK 1
caf5e0 #define WIPE_NOTOPEN 2
d4c5c8 #define WIPE_USERABORT 3
0e4fc4 #define WIPE_NOSTATS 4
256471 #define WIPE_NOREMOVE 5
ebba3c #define WIPE_NOFLUSH 6
24250b #define WIPE_NOFILEMAP 7
b49c89 #define WIPE_NOMEMMAP 8
e618cd #define WIPE_ALREADYOPEN 9
7f75ba #define WIPE_WRITEPROTECT 10
2daf5a
ff7e55 BOOL WipeError(HWND hwnd,FILELIST *FileEntry,UINT error);
e84e75 UINT InternalFileWipe(PGPContextRef context,HWND hwnd,char *FileName);
e17d62 BOOL OpenRings(HWND hwnd,PGPContextRef context,PGPKeySetRef *pkeyset);
31598f BOOL FileHasThisExtension(char *filename,char *extension);
44af5a
df0218 LRESULT·
0fbbaa PGPscMessageBox (
713172 ¤   ¤   ·HWND¤  hWnd,·
495442 ¤   ¤   ·INT¤   iCaption,·
7776b8 ¤   ¤   ·INT¤   iMessage,
8911d4 ¤   ¤   ·ULONG¤ ulFlags) ;
40af5a
df222d #endif /* ] Included_WORKING_h */
23af5a
56af5a
797e4d /*__Editor_settings____
2eaf5a
274126 ¤   Local Variables:
f87b17 ¤   tab-width: 4
620e6c ¤   End:
715f8c ¤   vi: ts=4 sw=4
b69e9b ¤   vim: si
a8d062 _____________________*/
--6191 0003b8ff94940110289 Page 1 of CLabout.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
2d23a5 ¤   CLabout.c - display "help about" dialog
ae67c5 ¤
47af5a
5d01cd ¤   $Id: CLabout.c,v 1.12 1998/08/11 14:43:04 pbj Exp $
edf7f7 ____________________________________________________________________________*/
9be610 #include "pgpPFLConfig.h"
37af5a
d0c917 // project header files
d75fcd #include "pgpclx.h"
3caf5a
e1fc2c // system header files
c9dbcb #include <shellapi.h>
4b67c5 ¤
1836e7 #define ADDWIDTH¤   2
0139c7 #define ADDHEIGHT¤  2
ea9848 #define XINCREMENT¤ 6
6dee73 #define YINCREMENT¤ 10
a8ea45 #define EDGEWIDTH¤  6
61af5a
232d7e #define VERSIONX¤   32
fd917d #define VERSIONY¤   26
caaf5a
884c4f typedef struct _DIALOGINFOSTRUCT {
e78a97 ¤   PGPContextRef¤  context;
c9fd38 ¤   HWND¤   ¤   ¤   hWndParent;
97f79f ¤   LPSTR¤  ¤   ¤   szVersionInfo;
f11cc5 ¤   CHAR¤   ¤   ¤   szWebLink[128];
e9d003 ¤   LPSTR¤  ¤   ¤   szWebLinkText;
080b46 ¤   HBITMAP¤¤   ¤   hBitmapMain;
98a3ef ¤   HBITMAP¤¤   ¤   hBitmapCredits;
b25b2e ¤   COLORREF¤   ¤   crVersionTextColor;
02ce2f ¤   HPALETTE¤   ¤   hPaletteMain;
888eae ¤   HPALETTE¤   ¤   hPaletteCredits;
fb42c8 ¤   UINT¤   ¤   ¤   uXsize;
36dd1d ¤   UINT¤   ¤   ¤   uYsize;
776fef ¤   UINT¤   ¤   ¤   uXpos;
9d6bc4 ¤   UINT¤   ¤   ¤   uYpos;
fa6b49 ¤   BOOL¤   ¤   ¤   bCredits;
a16848 } DIALOGINFOSTRUCT, *PDIALOGINFOSTRUCT;
fdaf5a
8193ed // external globals
aca009 extern HINSTANCE¤   g_hInst;
96cef3 extern CHAR¤¤   ¤   g_szHelpFile[MAX_PATH];
eeaf5a
a70382 //¤ ______________________________________
c2465d //
0a6da0 //¤ Thread routine to delay and then open URL.
a77a2d //¤ If we don't wait for calling dialog box to
8f2566 //¤ close, browser will be launched and then forced
5838e7 //¤ to background as parent window of calling
b78f2a //¤ dialog box is activated.
8baf5a
4fe9c9 #define THREAD_DELAY_MS¤150
0faf5a
7a55b9 DWORD WINAPI
d15c7b ExecuteShellThread (LPVOID lpvoid)·
27bb36 {
09d41b ¤   LPSTR pszURL;
1d8be7 ¤   pszURL = (LPSTR)lpvoid;
03af5a
40f897 ¤   // delay to allow calling dialog box to close
e619e5 ¤   // and activate parent
3e595b ¤   Sleep (THREAD_DELAY_MS);
9daf5a
d3729b ¤   // now that parent is active, open the URL
fe9191 ¤   if ((ULONG)ShellExecute (NULL, "open", pszURL, NULL,·
aad931 ¤   ¤   ¤   ¤   ··"C:\\", SW_SHOWNORMAL) <= 32) {
3b2e9b ¤   ¤   PGPclMessageBox (NULL, IDS_CAPTION,·
--b25e 000a0247fb740110289 Page 2 of CLabout.c
79e616 ¤   ¤   ¤   IDS_BROWSERERROR, MB_OK|MB_ICONHAND);
199371 ¤   }
d1af5a
b39f7d ¤   free (pszURL);
0eaf5a
f13e6b ¤   return 0;
94efe6 }
dbaf5a
a09268 //¤ _______________________________________________
46465d //
768b1b //¤ launch web browser with specified link
86af5a
be9d43 PGPError PGPclExport·
077481 PGPclWebBrowse (LPSTR pszURL)
1abb36 {
71504a ¤   DWORD¤  dwThreadID;
ce4c23 ¤   LPSTR¤  pszURLbuffer;
61af5a
0b6fa9 ¤   if (!pszURL) return kPGPError_BadParams;
c0af5a
6f826d ¤   pszURLbuffer = malloc (lstrlen(pszURL) +1);
0e7a61 ¤   lstrcpy (pszURLbuffer, pszURL);
61af5a
18df9a ¤   CreateThread (NULL, 0, ExecuteShellThread,·
0959e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPVOID)pszURLbuffer, 0, &dwThreadID);
74af5a
86151e ¤   return kPGPError_NoErr;
cbefe6 }
51af5a
f50382 //¤ ______________________________________
4f465d //
568bbb //¤ Dialog procedure for Help About dialog
9daf5a
259993 BOOL CALLBACK·
025cfb HelpAboutDlgProc (
673a3a ¤   ¤   HWND¤   hDlg,·
9beb77 ¤   ¤   UINT¤   uMsg,·
8c0303 ¤   ¤   WPARAM¤ wParam,
a2c0b8 ¤   ¤   LPARAM¤ lParam)·
e1bb36 {
78146b ¤   PDIALOGINFOSTRUCT¤  pdis;
74b697 ¤   CHAR¤   ¤   ¤   ¤   sz[256];
d9af5a
4431cf ¤   switch(uMsg) {
e2af5a
e52940 ¤   case WM_INITDIALOG:
935b34 ¤   ¤   {
72b4af ¤   ¤   ¤   HWND¤   hWndControl;
0feb01 ¤   ¤   ¤   RECT¤   rc;
7a86dd ¤   ¤   ¤   UINT¤   uX;
13dc01 ¤   ¤   ¤   UINT¤   uY;
e8af5a
8820eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
d0d761 ¤   ¤   ¤   pdis = (PDIALOGINFOSTRUCT)lParam;
8eaf5a
4ad650 ¤   ¤   ¤   pdis->bCredits = FALSE;
0b46a1 ¤   ¤   ¤   SetWindowPos (hDlg, HWND_TOP, pdis->uXpos, pdis->uYpos,·
fc0c2f ¤   ¤   ¤   ¤   ¤   ¤   pdis->uXsize+ADDWIDTH, pdis->uYsize+ADDHEIGHT, 0);
44af5a
8b8be5 ¤   ¤   ¤   hWndControl = GetDlgItem (hDlg, IDOK);
bc9295 ¤   ¤   ¤   GetClientRect (hWndControl, &rc);
fb1f72 ¤   ¤   ¤   uY = pdis->uYsize + ADDHEIGHT - YINCREMENT - rc.bottom;
af06f4 ¤   ¤   ¤   uX = pdis->uXsize - XINCREMENT - rc.right;
3321c2 ¤   ¤   ¤   SetWindowPos (hWndControl, NULL, uX, uY,·
a31d94 ¤   ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
9faf5a
01e403 ¤   ¤   ¤   hWndControl = GetDlgItem (hDlg, IDC_WWWLINK);
3c9295 ¤   ¤   ¤   GetClientRect (hWndControl, &rc);
561f72 ¤   ¤   ¤   uY = pdis->uYsize + ADDHEIGHT - YINCREMENT - rc.bottom;
89e07b ¤   ¤   ¤   uX = uX - XINCREMENT - rc.right;
6e21c2 ¤   ¤   ¤   SetWindowPos (hWndControl, NULL, uX, uY,·
a01d94 ¤   ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
--513d 000277da28740110289 Page 3 of CLabout.c
e0af5a
e0a4bf ¤   ¤   ¤   hWndControl = GetDlgItem (hDlg, IDC_CREDITS);
779295 ¤   ¤   ¤   GetClientRect (hWndControl, &rc);
911f72 ¤   ¤   ¤   uY = pdis->uYsize + ADDHEIGHT - YINCREMENT - rc.bottom;
a4e07b ¤   ¤   ¤   uX = uX - XINCREMENT - rc.right;
4321c2 ¤   ¤   ¤   SetWindowPos (hWndControl, NULL, uX, uY,·
0a1d94 ¤   ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
a2af5a
141e53 ¤   ¤   ¤   if (pdis->szWebLinkText)·
bfcd80 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_WWWLINK, pdis->szWebLinkText);
630fe4 ¤   ¤   }
c7836c ¤   ¤   return TRUE;
8baf5a
1c93f9 ¤   case WM_PAINT:
7b5b34 ¤   ¤   {
d59d24 ¤   ¤   ¤   HDC¤¤   ¤   hDC;
fcf791 ¤   ¤   ¤   HDC¤¤   ¤   hMemDC;
fa5374 ¤   ¤   ¤   PAINTSTRUCT¤ps;
805a4e ¤   ¤   ¤   HBITMAP¤¤   hBitmapOld;
b4af5a
cc6b0c ¤   ¤   ¤   pdis = (PDIALOGINFOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
66af5a
25e2b0 ¤   ¤   ¤   hDC = BeginPaint (hDlg, &ps);
e4995d ¤   ¤   ¤   hMemDC = CreateCompatibleDC (hDC);
54ef3a ¤   ¤   ¤   if (pdis->bCredits) {
e43fc5 ¤   ¤   ¤   ¤   if (pdis->hPaletteCredits) {
745a42 ¤   ¤   ¤   ¤   ¤   SelectPalette (hDC, pdis->hPaletteCredits, FALSE);
934c63 ¤   ¤   ¤   ¤   ¤   RealizePalette (hDC);
e12613 ¤   ¤   ¤   ¤   }
d38841 ¤   ¤   ¤   ¤   hBitmapOld = SelectObject (hMemDC, pdis->hBitmapCredits);
55a3a6 ¤   ¤   ¤   }
66e543 ¤   ¤   ¤   else {
5d2116 ¤   ¤   ¤   ¤   if (pdis->hPaletteMain) {
4a694c ¤   ¤   ¤   ¤   ¤   SelectPalette (hDC, pdis->hPaletteMain, FALSE);
034c63 ¤   ¤   ¤   ¤   ¤   RealizePalette (hDC);
692613 ¤   ¤   ¤   ¤   }
99fd81 ¤   ¤   ¤   ¤   hBitmapOld = SelectObject (hMemDC, pdis->hBitmapMain);
e0ce8e ¤   ¤   ¤   ¤   CLPaintUserInfo (PGPGetContextMemoryMgr (pdis->context),
b3e96a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, hMemDC, pdis->szVersionInfo);
e8a3a6 ¤   ¤   ¤   }
e451c3 ¤   ¤   ¤   BitBlt (hDC, 0, 0, pdis->uXsize, pdis->uYsize,·
29a3b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hMemDC, 0, 0, SRCCOPY);
7de0e6 ¤   ¤   ¤   SelectObject (hMemDC, hBitmapOld);
7f9a29 ¤   ¤   ¤   DeleteDC (hMemDC);
d85dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
980fe4 ¤   ¤   }
3f98aa ¤   ¤   return FALSE;
1baf5a
af3fcf ¤   case WM_COMMAND:
877dba ¤   ¤   pdis = (PDIALOGINFOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
bcaf5a
841185 ¤   ¤   switch (LOWORD (wParam)) {
93af5a
4a8566 ¤   ¤   case IDC_WWWLINK :
71c7bd ¤   ¤   ¤   PGPclWebBrowse (pdis->szWebLink);
18ef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
26cdcb ¤   ¤   ¤   break;
2daf5a
7cc5da ¤   ¤   case IDC_CREDITS :
1f13da ¤   ¤   ¤   pdis->bCredits = !pdis->bCredits;
a1ef3a ¤   ¤   ¤   if (pdis->bCredits) {
5c7602 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_INFOTEXT, sz, sizeof(sz));
d2bc91 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_CREDITS, sz);
c9a3a6 ¤   ¤   ¤   }
02e543 ¤   ¤   ¤   else {
dc84d7 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_CREDITTEXT, sz, sizeof(sz));
eabc91 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_CREDITS, sz);
71a3a6 ¤   ¤   ¤   }
a4f217 ¤   ¤   ¤   InvalidateRect (hDlg, NULL, FALSE);
17cdcb ¤   ¤   ¤   break;
8eaf5a
274672 ¤   ¤   case IDOK:·
--3309 000eb2a9adc40110289 Page 4 of CLabout.c
bdef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
6ecdcb ¤   ¤   ¤   break;
800fe4 ¤   ¤   }
45836c ¤   ¤   return TRUE;
959371 ¤   }
cea230 ¤   return FALSE;
03efe6 }
d3af5a
2a9268 //¤ _______________________________________________
da465d //
7586ab //¤ Post Help About dialog with button for web link
10de0b //¤ to specified URL.
2eaf5a
9d9d43 PGPError PGPclExport·
8d9a17 PGPclHelpAbout (
84e958 ¤   ¤   PGPContextRef¤  context,
1ffd31 ¤   ¤   HWND¤   ¤   ¤   hWnd,·
167ad2 ¤   ¤   LPSTR¤  ¤   ¤   szVersion,·
b5686c ¤   ¤   LPSTR¤  ¤   ¤   szLinkText,·
cb104a ¤   ¤   LPSTR¤  ¤   ¤   szLink)·
6dbb36 {
fb9bdd ¤   DIALOGINFOSTRUCT¤   dis;
36efa5 ¤   BITMAP¤ ¤   ¤   ¤   bm;
cbf18e ¤   HDC¤¤   ¤   ¤   ¤   hDC;
a11498 ¤   INT¤¤   ¤   ¤   ¤   iAboutBitmap;
6a7223 ¤   INT¤¤   ¤   ¤   ¤   iCreditBitmap;
cf2b61 ¤   INT¤¤   ¤   ¤   ¤   iNumBits;
04af5a
c90745 ¤   dis.context = context;
59c6c9 ¤   dis.hWndParent = hWnd;
8e4638 ¤   dis.szVersionInfo = szVersion;
cd8b70 ¤   if (szLink)·
a41f49 ¤   ¤   lstrcpy (dis.szWebLink, szLink);
1f4264 ¤   else·
445016 ¤   ¤   LoadString (g_hInst, IDS_WEBLINK,·
2a55fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   dis.szWebLink, sizeof (dis.szWebLink));
536123 ¤   dis.szWebLinkText = szLinkText;
35af5a
a17f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
f489fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
54e693 ¤   ReleaseDC (NULL, hDC);
5aaf5a
d77a80 ¤   if (iNumBits <= 1) {
385c69 ¤   ¤   iAboutBitmap = IDB_SPLASH1;
be61b9 ¤   ¤   iCreditBitmap = IDB_CREDITS1;
a60c12 ¤   ¤   dis.crVersionTextColor = RGB (255,255,255);
b69371 ¤   }
ff4ea0 ¤   else if (iNumBits <= 4) {
7265d4 ¤   ¤   iAboutBitmap = IDB_SPLASH4;
1e5804 ¤   ¤   iCreditBitmap = IDB_CREDITS4;
2a1b58 ¤   ¤   dis.crVersionTextColor = RGB (0,0,0);
3d9371 ¤   }
9d665a ¤   else {
cec077 ¤   ¤   iAboutBitmap = IDB_SPLASH8;
1afda7 ¤   ¤   iCreditBitmap = IDB_CREDITS8;
bf1b58 ¤   ¤   dis.crVersionTextColor = RGB (0,0,0);
e79371 ¤   }
96af5a
623f5e ¤   dis.hBitmapMain = CLLoadResourceBitmap (g_hInst,·
dd46d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (iAboutBitmap),
b5509e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dis.hPaletteMain);
162491 ¤   GetObject (dis.hBitmapMain, sizeof(BITMAP), (LPSTR)&bm);
4faf5a
cfb6da ¤   dis.hBitmapCredits = CLLoadResourceBitmap (g_hInst,·
8a5ddb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (iCreditBitmap),
4a5894 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dis.hPaletteCredits);
68af5a
847382 ¤   dis.uXsize = bm.bmWidth;
921b97 ¤   dis.uYsize = bm.bmHeight;
9faf5a
2d910e ¤   dis.uXpos = (GetSystemMetrics (SM_CXFULLSCREEN)·
eb6090 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   - dis.uXsize - EDGEWIDTH) / 2;
--4a5c 000f0c5159e40110289 Page 5 of CLabout.c
286fa3 ¤   dis.uYpos = (GetSystemMetrics (SM_CYFULLSCREEN)·
4d4ee2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   - dis.uYsize) / 2;
8eaf5a
6adc15 ¤   DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_HELPABOUT),·
f23ed5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hWnd, HelpAboutDlgProc, (LPARAM)&dis);
caaf5a
6f73b4 ¤   DeleteObject (dis.hBitmapMain);
1d218e ¤   DeleteObject (dis.hBitmapCredits);
fa0e6f ¤   DeleteObject (dis.hPaletteMain);
ddc79b ¤   DeleteObject (dis.hPaletteCredits);
8faf5a
ff151e ¤   return kPGPError_NoErr;
75efe6 }
a4af5a
c7d673 #if PGP_DEMO
339f11 //¤ _____________________________________
4f465d //
ded982 //¤ Dialog procedure for nag dialog
39af5a
4d9993 BOOL CALLBACK·
f953ca NagDlgProc (
e13a3a ¤   ¤   HWND¤   hDlg,·
12eb77 ¤   ¤   UINT¤   uMsg,·
060303 ¤   ¤   WPARAM¤ wParam,
9cc0b8 ¤   ¤   LPARAM¤ lParam)·
fcbb36 {
e5146b ¤   PDIALOGINFOSTRUCT¤  pdis;
e1af5a
4f31cf ¤   switch(uMsg) {
88af5a
ef2940 ¤   case WM_INITDIALOG:
6f5b34 ¤   ¤   {
2fb4af ¤   ¤   ¤   HWND¤   hWndControl;
c4eb01 ¤   ¤   ¤   RECT¤   rc;
ca0d25 ¤   ¤   ¤   UINT¤   uX, uY;
4eaf5a
3d20eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
44d761 ¤   ¤   ¤   pdis = (PDIALOGINFOSTRUCT)lParam;
0aaf5a
b746a1 ¤   ¤   ¤   SetWindowPos (hDlg, HWND_TOP, pdis->uXpos, pdis->uYpos,·
ac5eb5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pdis->uXsize+6, pdis->uYsize+ADDHEIGHT, 0);
ccaf5a
6e8be5 ¤   ¤   ¤   hWndControl = GetDlgItem (hDlg, IDOK);
b49295 ¤   ¤   ¤   GetClientRect (hWndControl, &rc);
9aabae ¤   ¤   ¤   uY = pdis->uYsize * 54 / 100;
04ac09 ¤   ¤   ¤   uX = pdis->uXsize * 61 / 100;
6521c2 ¤   ¤   ¤   SetWindowPos (hWndControl, NULL, uX, uY,·
0b1d94 ¤   ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
0faf5a
5fe403 ¤   ¤   ¤   hWndControl = GetDlgItem (hDlg, IDC_WWWLINK);
ff9295 ¤   ¤   ¤   GetClientRect (hWndControl, &rc);
d26e6b ¤   ¤   ¤   uY = pdis->uYsize * 43 / 100;
63ac09 ¤   ¤   ¤   uX = pdis->uXsize * 61 / 100;
1021c2 ¤   ¤   ¤   SetWindowPos (hWndControl, NULL, uX, uY,·
4a1d94 ¤   ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
68af5a
9d1e53 ¤   ¤   ¤   if (pdis->szWebLinkText)·
3acd80 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_WWWLINK, pdis->szWebLinkText);
840fe4 ¤   ¤   }
a9836c ¤   ¤   return TRUE;
13af5a
a093f9 ¤   case WM_PAINT:
7e5b34 ¤   ¤   {
4c9107 ¤   ¤   ¤   HDC¤¤   ¤   hDC, hMemDC;
a45374 ¤   ¤   ¤   PAINTSTRUCT¤ps;
705a4e ¤   ¤   ¤   HBITMAP¤¤   hBitmapOld;
25af5a
086b0c ¤   ¤   ¤   pdis = (PDIALOGINFOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
1daf5a
efe2b0 ¤   ¤   ¤   hDC = BeginPaint (hDlg, &ps);
a9995d ¤   ¤   ¤   hMemDC = CreateCompatibleDC (hDC);
f01df8 ¤   ¤   ¤   if (pdis->hPaletteMain) {
--1fae 0009691aa8040110289 Page 6 of CLabout.c
675422 ¤   ¤   ¤   ¤   SelectPalette (hDC, pdis->hPaletteMain, FALSE);
00708d ¤   ¤   ¤   ¤   RealizePalette (hDC);
c8a3a6 ¤   ¤   ¤   }
14af5a
6bee0d ¤   ¤   ¤   hBitmapOld = SelectObject (hMemDC, pdis->hBitmapMain);
fe51c3 ¤   ¤   ¤   BitBlt (hDC, 0, 0, pdis->uXsize, pdis->uYsize,·
49a3b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hMemDC, 0, 0, SRCCOPY);
b1e0e6 ¤   ¤   ¤   SelectObject (hMemDC, hBitmapOld);
9a9a29 ¤   ¤   ¤   DeleteDC (hMemDC);
3b5dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
270fe4 ¤   ¤   }
6a98aa ¤   ¤   return FALSE;
5aaf5a
803fcf ¤   case WM_COMMAND:
25379d ¤   ¤   switch(LOWORD (wParam)) {
f4af5a
f08566 ¤   ¤   case IDC_WWWLINK :
8d6b0c ¤   ¤   ¤   pdis = (PDIALOGINFOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
a4c7bd ¤   ¤   ¤   PGPclWebBrowse (pdis->szWebLink);
6fef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
3ecdcb ¤   ¤   ¤   break;
64af5a
8e4672 ¤   ¤   case IDOK:·
cfef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
40cdcb ¤   ¤   ¤   break;
bc0fe4 ¤   ¤   }
42836c ¤   ¤   return TRUE;
879371 ¤   }
05a230 ¤   return FALSE;
afefe6 }
90af5a
51f528 //¤ _________________________________________________________
af465d //
19a8f3 //¤ Post nag dialog with button for web link to specified URL
98af5a
969d43 PGPError PGPclExport·
13e6ab PGPclNag(
801aa3 ¤   ¤   ·HWND¤  ¤   ¤   hWnd,·
f13a4d ¤   ¤   ·LPSTR¤ ¤   ¤   szLinkText,·
30eb2f ¤   ¤   ·LPSTR¤ ¤   ¤   szLink)·
4cbb36 {
2b9bdd ¤   DIALOGINFOSTRUCT¤   dis;
c1efa5 ¤   BITMAP¤ ¤   ¤   ¤   bm;
65f18e ¤   HDC¤¤   ¤   ¤   ¤   hDC;
d0b710 ¤   INT¤¤   ¤   ¤   ¤   iNagBitmap;
562b61 ¤   INT¤¤   ¤   ¤   ¤   iNumBits;
c7af5a
201ae7 ¤   dis.context = NULL;
5cc6c9 ¤   dis.hWndParent = hWnd;
c3b1c0 ¤   if (szLink) lstrcpy (dis.szWebLink, szLink);
decc6e ¤   else LoadString (g_hInst, IDS_WEBLINK,·
0a1b8d ¤   ¤   ¤   ¤   ¤   ¤   ¤   dis.szWebLink, sizeof (dis.szWebLink));
c46123 ¤   dis.szWebLinkText = szLinkText;
b5af5a
567f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
373b34 ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);·
19e693 ¤   ReleaseDC (NULL, hDC);
abaf5a
057a80 ¤   if (iNumBits <= 1) {
38fa83 ¤   ¤   iNagBitmap = IDB_NAG1;
689371 ¤   }
d84ea0 ¤   else if (iNumBits <= 4) {
bac33e ¤   ¤   iNagBitmap = IDB_NAG4;
5e9371 ¤   }
fb665a ¤   else {
9a669d ¤   ¤   iNagBitmap = IDB_NAG8;
de9371 ¤   }
48af5a
a13f5e ¤   dis.hBitmapMain = CLLoadResourceBitmap (g_hInst,·
f7c6d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···MAKEINTRESOURCE (iNagBitmap),
2dd2ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···&dis.hPaletteMain);
962491 ¤   GetObject (dis.hBitmapMain, sizeof(BITMAP), (LPSTR)&bm);
--50f9 001fc51c98f40110289 Page 7 of CLabout.c
e0af5a
967382 ¤   dis.uXsize = bm.bmWidth;
061b97 ¤   dis.uYsize = bm.bmHeight;
e5af5a
3df1fc ¤   dis.uXpos = (GetSystemMetrics (SM_CXFULLSCREEN) -·
376552 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   dis.uXsize - EDGEWIDTH) / 2;
b553e3 ¤   dis.uYpos = (GetSystemMetrics (SM_CYFULLSCREEN) -
615e88 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   dis.uYsize) / 2;
5eaf5a
a02261 ¤   DialogBox (g_hInst, MAKEINTRESOURCE (IDD_NAG),·
67e6e1 ¤   ¤   ¤   ···hWnd, NagDlgProc);
f7af5a
8473b4 ¤   DeleteObject (dis.hBitmapMain);
4f0e6f ¤   DeleteObject (dis.hPaletteMain);
3daf5a
d4151e ¤   return kPGPError_NoErr;
aeefe6 }
8daf5a
e82d33 #endif¤ // PGP_DEMO
fcaf5a
--942a 000db347eb34011028a Page 1 of CLcache.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
3ffb28 ¤   CLcache.c - passphrase caching routines
7f67c5 ¤
11675c ¤   Passphrase caching is implemented as user convenience.
263f3b ¤   The pgplib preferences control whether caching is·
da3884 ¤   enabled and for how long. ·The code in this file implements
b3ebcc ¤   the passphrase cache by keeping a global counter and a
6ca975 ¤   global pointer variable to the phrase. ·When the
b16a77 ¤   phrase is entered or accessed, the counter is set to the
a5732c ¤   current timeout value specified by the library preferences.
585329 ¤   A separate thread is created which awakes every second and
801b75 ¤   decrements the counter. ·When the counter reaches zero, the
347175 ¤   cache (string) is wiped, the string freed and the thread·
ab33ac ¤   terminates.·
b4af5a
7314ef ¤   The caller to PGPclGetCachedPhrase is responsible for freeing
de2c8b ¤   the returned string buffer with PGPFreePhrase.
6a67c5 ¤
8faf5a
c13cfa ¤   $Id: CLcache.c,v 1.5.2.1 1998/09/15 20:35:47 pbj Exp $
aef7f7 ____________________________________________________________________________*/
de8ad2 #include "pgpPFLConfig.h"¤
7eaf5a
4c5fcd #include "pgpclx.h"
3811a9 #include <process.h>
33af5a
7084a0 #define SCRAMBLERLENGTH¤¤   256
679ecb #define CACHECLOCKPERIOD¤   500¤¤   ¤   ¤   // in milliseconds
83af5a
615bee // typedefs
18f0f7 typedef struct {
aa999b ¤   BOOL¤   ¤   ¤   ¤   bCacheActive;
72ba7c ¤   INT¤¤   ¤   ¤   ¤   iCacheCounter;
4abb0e ¤   LPSTR¤  ¤   ¤   ¤   pszCachedPassphrase;
c76752 ¤   PGPUInt32¤  ¤   ¤   iCachedPassphraseLength;
efbb6d ¤   PGPByte*¤   ¤   ¤   pCachedPasskey;
fdf0b2 ¤   PGPUInt32¤  ¤   ¤   iCachedPasskeyLength;
e6af5a
a6c90b ¤   PGPByte¤¤   ¤   ¤   CachedKeyID[kPGPMaxExportedKeyIDSize];
3c2bdd ¤   PGPInt32¤   ¤   ¤   CachedKeyAlg;
f5d149 ¤   PGPHashAlgorithm¤   CachedHashAlg;
a107f1 ¤   UINT¤   ¤   ¤   ¤   uCachedOptions;
d2bf12 } CACHE, *PCACHE;
f9af5a
7d11d2 static CACHE¤   cacheDecryption;
5ba836 static CACHE¤   cacheSigning;
80af5a
527dfc static CHAR¤¤   szScrambler[SCRAMBLERLENGTH];
562eab static BOOL¤¤   bScramblerInitialized = FALSE;
f6af5a
107562 CRITICAL_SECTION¤   criticalSectionCache;
98af5a
630b1a //___________________________
7b465d //
c8ebb5 // Memory allocation routines
09465d //
2aaf5a
a850e1 static VOID*·
4e1e0a secAlloc (PGPContextRef context, UINT uBytes)·
7abb36 {
702d29 ¤   return (PGPNewSecureData (PGPGetContextMemoryMgr (context), uBytes, 0));
59efe6 }
3baf5a
edaf5a
b3b333 static VOID·
17d91b secFree (VOID* p)·
0dbb36 {
d2fa6e ¤   PGPFreeData (p);
dbefe6 }
--8619 0006b03942c4011028a Page 2 of CLcache.c
e0af5a
1aaf5a
2cd287 //_____________________________________________________
0d465d //
7baf5a
dfe6b2 static VOID
6dc4e1 sEmptyCache (PCACHE pcache)
33bb36 {
9ba628 ¤   if (pcache->pszCachedPassphrase)·
09c7a1 ¤   {
a5dc93 ¤   ¤   secFree (pcache->pszCachedPassphrase);
200559 ¤   ¤   pcache->pszCachedPassphrase = NULL;
511423 ¤   ¤   pcache->iCachedPassphraseLength = 0;
459371 ¤   }
42af5a
6259a5 ¤   if (pcache->pCachedPasskey)·
bac7a1 ¤   {
73cd74 ¤   ¤   secFree (pcache->pCachedPasskey);
3faf5a
1761ba ¤   ¤   pcache->pCachedPasskey = NULL;
df5f85 ¤   ¤   pcache->iCachedPasskeyLength = 0;
079371 ¤   }
1567c5 ¤
d23b20 ¤   pgpClearMemory (pcache->CachedKeyID, kPGPMaxExportedKeyIDSize);
1bcc48 ¤   pcache->CachedKeyAlg = 0;
d233d7 ¤   pcache->CachedHashAlg = 0;
0de6e8 ¤   pcache->uCachedOptions = 0;
08efe6 }
dcaf5a
08d287 //_____________________________________________________
15465d //
b3af5a
72b333 static VOID·
bad314 sSetCacheDuration (PCACHE pcache, UINT uSecs)
ebbb36 {
d399e3 ¤   pcache->iCacheCounter = (uSecs * 1000) / CACHECLOCKPERIOD;
89efe6 }
e7af5a
bed287 //_____________________________________________________
0d465d //
11af5a
ff6c77 static BOOL·
7f5c4f sIsCacheValid (PCACHE pcache)
28bb36 {
4dd613 ¤   if (pcache->bCacheActive) {
a0813c ¤   ¤   if (pcache->pszCachedPassphrase ||·
7bba66 ¤   ¤   ¤   pcache->pCachedPasskey)·
375b34 ¤   ¤   {
6432bd ¤   ¤   ¤   return TRUE;
180fe4 ¤   ¤   }
8f9371 ¤   }
6caf5a
75a230 ¤   return FALSE;
89efe6 }
d2af5a
12d287 //_____________________________________________________
d3465d //
56af5a
2cb333 static VOID·
0c7a83 sScrambleCache (PCACHE pcache)
c0bb36 {
d5cdd6 ¤   INT i;
edc530 ¤   INT iLen;
c9af5a
37056f ¤   iLen = lstrlen (pcache->pszCachedPassphrase);
8f85d8 ¤   pcache->iCachedPassphraseLength = iLen;
9d904f ¤   for (i=0; i<iLen; i++)·
748845 ¤   ¤   pcache->pszCachedPassphrase[i] ^= szScrambler[i%SCRAMBLERLENGTH];
b8af5a
0e5da0 ¤   iLen = pcache->iCachedPasskeyLength;
ad904f ¤   for (i=0; i<iLen; i++)·
6bc71b ¤   ¤   pcache->pCachedPasskey[i] ^= szScrambler[i%SCRAMBLERLENGTH];
--faed 00021914f394011028a Page 3 of CLcache.c
7aefe6 }
46af5a
8eaf5a
f4d287 //_____________________________________________________
1b465d //
23af5a
ed69c9 static PGPError·
7480f1 sCopyCache (
08f77b ¤   ¤   PCACHE¤ ¤   ¤   pcache,
b8e958 ¤   ¤   PGPContextRef¤  context,
8e3663 ¤   ¤   LPSTR*¤ ¤   ¤   pszPassphraseBuffer,
73e873 ¤   ¤   PGPByte**¤  ¤   ppPasskeyBuffer,
e9d58e ¤   ¤   PGPUInt32*¤ ¤   piPasskeyLength)
8bbb36 {
5930d4 ¤   PGPError¤   err¤¤   = kPGPError_NoErr;
242aea ¤   INT¤¤   ¤   i;
2142ac ¤   INT¤¤   ¤   iLen;
b5af5a
b5347a ¤   if ((pcache->pCachedPasskey) && (ppPasskeyBuffer))·
63c7a1 ¤   {
675b18 ¤   ¤   iLen = pcache->iCachedPasskeyLength;
e162c9 ¤   ¤   *ppPasskeyBuffer = secAlloc (context, iLen);
daaf5a
540532 ¤   ¤   if(*ppPasskeyBuffer) {
44b6ed ¤   ¤   ¤   for (i=0; i<iLen; i++)·
c7f776 ¤   ¤   ¤   {
7cc445 ¤   ¤   ¤   ¤   (*ppPasskeyBuffer)[i] =·
7bf7c7 ¤   ¤   ¤   ¤   ¤   ¤   pcache->pCachedPasskey[i] ^·
844faf ¤   ¤   ¤   ¤   ¤   ¤   ¤   szScrambler[i%SCRAMBLERLENGTH];
4aa3a6 ¤   ¤   ¤   }
68c051 ¤   ¤   ¤   *piPasskeyLength = iLen;
4f0fe4 ¤   ¤   }
6aee26 ¤   ¤   else·
d7b90c ¤   ¤   ¤   err = kPGPError_OutOfMemory;
a19371 ¤   }
5aaf5a
0d5b2e ¤   if ((pcache->pszCachedPassphrase) && (pszPassphraseBuffer))·
87c7a1 ¤   {
9b50a8 ¤   ¤   iLen = pcache->iCachedPassphraseLength;
0c7713 ¤   ¤   *pszPassphraseBuffer = secAlloc (context, iLen+1);
53af5a
8cb938 ¤   ¤   if (*pszPassphraseBuffer)·
d15b34 ¤   ¤   {
32b6ed ¤   ¤   ¤   for (i=0; i<iLen; i++)·
a7f776 ¤   ¤   ¤   {
b9829e ¤   ¤   ¤   ¤   (*pszPassphraseBuffer)[i] =·
b6ecf2 ¤   ¤   ¤   ¤   ¤   ¤   pcache->pszCachedPassphrase[i] ^·
734faf ¤   ¤   ¤   ¤   ¤   ¤   ¤   szScrambler[i%SCRAMBLERLENGTH];
aba3a6 ¤   ¤   ¤   }
5b6418 ¤   ¤   ¤   (*pszPassphraseBuffer)[iLen] = '\0';
c70fe4 ¤   ¤   }
850e1d ¤   ¤   else
0fb90c ¤   ¤   ¤   err = kPGPError_OutOfMemory;
e79371 ¤   }
07af5a
fd5ea8 ¤   return err;
08efe6 }
daaf5a
31af5a
dbd287 //_____________________________________________________
8c465d //
f18213 // ·thread to clear cache after delay period
359fe4 //¤ This routine is executed as a separate thread. ·The
ca03d6 //¤ routine wakes up every second and decrements the
50c75b //¤ counter. ·Whenthe counter reaches zero, the cache·
cda84d //¤ is purged and the flag is set to indicate cache is·
114ae0 //¤ not active.
0eaf5a
0be6b2 static VOID
25cdb2 sClearDecryptionCacheThread (PVOID pvoid)·
06bb36 {
2107b9 ¤   while (cacheDecryption.iCacheCounter > 0) {
--1491 0008452d0774011028a Page 4 of CLcache.c
da132d ¤   ¤   Sleep (CACHECLOCKPERIOD);
a6b26f ¤   ¤   cacheDecryption.iCacheCounter--;
b69371 ¤   }
d6af5a
74a191 ¤   EnterCriticalSection (&criticalSectionCache);
25af5a
53762b ¤   sEmptyCache (&cacheDecryption);
cc3848 ¤   cacheDecryption.bCacheActive = FALSE;
16af5a
1630f1 ¤   LeaveCriticalSection (&criticalSectionCache);
dcefe6 }
2aaf5a
3367c5 ¤
56d287 //_____________________________________________________
70465d //
90221a // ·thread to clear signing cache after delay period
399fe4 //¤ This routine is executed as a separate thread. ·The
b003d6 //¤ routine wakes up every second and decrements the
0dc75b //¤ counter. ·Whenthe counter reaches zero, the cache·
31a84d //¤ is purged and the flag is set to indicate cache is·
b14ae0 //¤ not active.
65af5a
c9b333 static VOID·
01ab9e sClearSigningCacheThread (PVOID pvoid)·
e4bb36 {
78d3dd ¤   while (cacheSigning.iCacheCounter > 0) {
4f132d ¤   ¤   Sleep (CACHECLOCKPERIOD);
80da4e ¤   ¤   cacheSigning.iCacheCounter--;
b59371 ¤   }
34af5a
82a191 ¤   EnterCriticalSection (&criticalSectionCache);
14af5a
d32b8d ¤   sEmptyCache (&cacheSigning);
491828 ¤   cacheSigning.bCacheActive = FALSE;
eaaf5a
a830f1 ¤   LeaveCriticalSection (&criticalSectionCache);
6aefe6 }
44af5a
a667c5 ¤
1cd287 //_____________________________________________________
9b465d //
3f9c90 //¤ PGPGetCachedDecryptionPhrase
f65471 //¤ This routine is called to get either cached phrase·
a5f11e //¤ (if available) or prompt user for phrase.
29465d //
e9465d //
d8af5a
33ec6d PGPError PGPclExport
807cb8 PGPclGetCachedDecryptionPhrase (
c5b579 ¤   ¤   PGPContextRef¤  ¤   context,·
bea960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
2d809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
5f8d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
6aa3e3 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,·
0555cb ¤   ¤   BOOL¤   ¤   ¤   ¤   bForceUserInput,
a7f6f4 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   pszBuffer,
216077 ¤   ¤   PGPKeySetRef¤   ¤   keysetEncryptedTo,
318416 ¤   ¤   PGPKeyID*¤  ¤   ¤   pkeyidEncryptedTo,
875866 ¤   ¤   UINT¤   ¤   ¤   ¤   uKeyIDCount,
be1229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
6a2c7e ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength,
b39b49 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetAdded)·
3ebb36 {
6f4afd ¤   PGPBoolean¤ ¤   bCacheEnabled¤  ¤   = FALSE;
f80f0c ¤   PGPUInt32¤  ¤   uCacheSecs¤ ¤   ¤   = 0;
6b7f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
acaf5a
b9eb44 ¤   DWORD¤  ¤   ¤   dw;
5dce0f ¤   PGPPrefRef¤ ¤   prefref;
e0af5a
4d13e4 ¤   // Get needed preferences
846f41 ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (context), &prefref);
--e0ec 00057b13f894011028a Page 5 of CLcache.c
cf033a ¤   if (IsntPGPError (err))
34c7a1 ¤   {
3b97f5 ¤   ¤   PGPGetPrefBoolean (prefref,·
322a46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefDecryptCacheEnable, &bCacheEnabled);
a88c94 ¤   ¤   PGPGetPrefNumber (prefref,·
8cd6d8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefDecryptCacheSeconds, &uCacheSecs);
6ab30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
f09371 ¤   }
edaf5a
89a191 ¤   EnterCriticalSection (&criticalSectionCache);
fcaf5a
835df6 ¤   // use phrase from cache
4b4a12 ¤   if (!bForceUserInput &&·
29c9be ¤   ¤   bCacheEnabled &&·
26cbaf ¤   ¤   sIsCacheValid (&cacheDecryption))
16c7a1 ¤   {
6e85ca ¤   ¤   // copy passphrase/passkey to caller's buffers
ca9b78 ¤   ¤   err = sCopyCache (&cacheDecryption, context, pszBuffer,·
d86db3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppPasskeyBuffer, piPasskeyLength);
cbe63d ¤   ¤   // reset cache duration
f8dae8 ¤   ¤   sSetCacheDuration (&cacheDecryption, uCacheSecs);
e29371 ¤   }
6eaf5a
88010a ¤   // cache is disabled or empty, get phrase from user
8a4264 ¤   else·
89c7a1 ¤   {
21b37e ¤   ¤   sEmptyCache (&cacheDecryption);
d5af5a
01d641 ¤   ¤   err = PGPclGetPhrase (context, keysetMain, hwnd, szPrompt,·
1ea70c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &cacheDecryption.pszCachedPassphrase,·
fa58b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetEncryptedTo,·
cbb5c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkeyidEncryptedTo, uKeyIDCount,
6cfe6c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, NULL, PGPCL_DECRYPTION,
5294c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &cacheDecryption.pCachedPasskey,
ce9972 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &cacheDecryption.iCachedPasskeyLength,
047769 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0, tlsContext, pkeysetAdded);
aaaf5a
ee7810 ¤   ¤   // user entered phrase -- setup cache
576705 ¤   ¤   if ((IsntPGPError (err)) &&·
e8ec75 ¤   ¤   ¤   (cacheDecryption.pszCachedPassphrase ||·
679e7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   cacheDecryption.pCachedPasskey))·
e85b34 ¤   ¤   {
74d668 ¤   ¤   ¤   // scramble cache contents
76193b ¤   ¤   ¤   sScrambleCache (&cacheDecryption);
15af5a
62659e ¤   ¤   ¤   // copy data to caller's buffers
75113d ¤   ¤   ¤   err = sCopyCache (&cacheDecryption, context, pszBuffer,·
3abd18 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppPasskeyBuffer, piPasskeyLength);
b1af5a
aea8f1 ¤   ¤   ¤   if (bCacheEnabled) {
335e7c ¤   ¤   ¤   ¤   // set cache duration
3b84f1 ¤   ¤   ¤   ¤   sSetCacheDuration (&cacheDecryption, uCacheSecs);
99af5a
d13fbc ¤   ¤   ¤   ¤   // start thread to purge cache after delay
2ad8fd ¤   ¤   ¤   ¤   if (!cacheDecryption.bCacheActive) {
962b94 ¤   ¤   ¤   ¤   ¤   cacheDecryption.bCacheActive = TRUE;
519cee ¤   ¤   ¤   ¤   ¤   _beginthreadex (NULL, 0,·
e316a3 ¤   ¤   ¤   ¤   ¤   ¤   (LPTHREAD_START_ROUTINE)sClearDecryptionCacheThread,·
932dcc ¤   ¤   ¤   ¤   ¤   ¤   0, 0, &dw);
f42613 ¤   ¤   ¤   ¤   }
37a3a6 ¤   ¤   ¤   }
8fbb8c ¤   ¤   ¤   else
952348 ¤   ¤   ¤   ¤   sEmptyCache (&cacheDecryption);
140fe4 ¤   ¤   }
c4af5a
c91765 ¤   ¤   // problem (cancel or other error) -- flush cache
4207e0 ¤   ¤   else {
173b18 ¤   ¤   ¤   sEmptyCache (&cacheDecryption);
b72920 ¤   ¤   ¤   sSetCacheDuration (&cacheDecryption, 0);
05af5a
5411fd ¤   ¤   ¤   if (err == kPGPError_NoErr)·
574067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
--d661 000486fcc3e4011028a Page 6 of CLcache.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
1230f1 ¤   LeaveCriticalSection (&criticalSectionCache);
dcaf5a
a1326f //¤ MessageBox(hwnd,*pszBuffer,"Passphrase",MB_OK);
6caf5a
d85ea8 ¤   return err;
1defe6 }
b2af5a
b9d287 //_____________________________________________________
d3465d //
c65735 //¤ PGPGetCachedSigningPhrase
d8262b //¤ This routine is called to get either signing cached phrase·
c8f11e //¤ (if available) or prompt user for phrase.
67465d //
1daf5a
9cec6d PGPError PGPclExport
f1d296 PGPclGetCachedSigningPhrase (
0eb579 ¤   ¤   PGPContextRef¤  ¤   context,·
7fa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
34317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
acb7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
435dc6 ¤   ¤   BOOL¤   ¤   ¤   ¤   bForceUserInput,·
499411 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   pszBuffer,·
cc3a8d ¤   ¤   PGPKeySetRef¤   ¤   keysetSigning,
bd6ea9 ¤   ¤   PGPKeyRef*¤ ¤   ¤   pkeySigning,
28809a ¤   ¤   PGPHashAlgorithm*¤  pulHashAlg,
1f4582 ¤   ¤   UINT*¤  ¤   ¤   ¤   puOptions,·
680a6a ¤   ¤   UINT¤   ¤   ¤   ¤   uFlags,
0c1229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
142c7e ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength,
22d60b ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetAdded)
c6bb36 {
72177d ¤   PGPBoolean¤ ¤   bCacheEnabled¤  = FALSE;
d4f90a ¤   PGPUInt32¤  ¤   uCacheSecs¤ ¤   = 0;
721e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
0a9065 ¤   PGPBoolean¤ ¤   bWarnRSADSA¤¤   = FALSE;
37aeff ¤   BOOL¤   ¤   ¤   bAskUser¤   ¤   = TRUE;
092f6a ¤   PGPSize¤¤   ¤   size;
39ce0f ¤   PGPPrefRef¤ ¤   prefref;
f04c97 ¤   PGPKeyID¤   ¤   keyid;
9deb44 ¤   DWORD¤  ¤   ¤   dw;
25af5a
7713e4 ¤   // Get needed preferences
076f41 ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (context), &prefref);
07033a ¤   if (IsntPGPError (err))
f4c7a1 ¤   {
8b7907 ¤   ¤   PGPGetPrefBoolean (prefref, kPGPPrefSignCacheEnable, &bCacheEnabled);
2ecbc1 ¤   ¤   PGPGetPrefNumber (prefref, kPGPPrefSignCacheSeconds, &uCacheSecs);
aa48ba ¤   ¤   // Need a never show again box?
bd97f5 ¤   ¤   PGPGetPrefBoolean (prefref,·
e0bcd7 ¤   ¤   ¤   ¤   ¤   kPGPPrefWarnOnRSARecipAndNonRSASigner, &bWarnRSADSA);
2ab30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
a29371 ¤   }
2faf5a
ffa191 ¤   EnterCriticalSection (&criticalSectionCache);
c2af5a
ec5df6 ¤   // use phrase from cache
754a12 ¤   if (!bForceUserInput &&·
e2c9be ¤   ¤   bCacheEnabled &&·
a41e28 ¤   ¤   sIsCacheValid (&cacheSigning))·
4fc7a1 ¤   {
1770bb ¤   ¤   err = kPGPError_NoErr;
efaf5a
5fe8e6 ¤   ¤   if (bWarnRSADSA &&·
562a3a ¤   ¤   ¤   (cacheSigning.CachedKeyAlg != kPGPPublicKeyAlgorithm_RSA) &&·
91e0b8 ¤   ¤   ¤   (uFlags & PGPCL_RSAENCRYPT))·
845b34 ¤   ¤   {
e93bf0 ¤   ¤   ¤   PGPBoolean bNeverShowAgain¤ = FALSE;
4faf5a
480164 ¤   ¤   ¤   err = PGPclRSADSAMixWarning (hwnd, &bNeverShowAgain);
--5f4e 0008e8cd1e74011028a Page 7 of CLcache.c
e0af5a
f13809 ¤   ¤   ¤   switch (err) {
95271c ¤   ¤   ¤   case kPGPError_NoErr :
e44d92 ¤   ¤   ¤   ¤   bAskUser = TRUE;
f5e2ad ¤   ¤   ¤   ¤   if (bNeverShowAgain) {
e3a695 ¤   ¤   ¤   ¤   ¤   err = PGPclOpenClientPrefs (
dba429 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (context), &prefref);
5e68ab ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err))
924859 ¤   ¤   ¤   ¤   ¤   {
de0d99 ¤   ¤   ¤   ¤   ¤   ¤   PGPSetPrefBoolean (prefref,·
0938da ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefWarnOnRSARecipAndNonRSASigner, FALSE);
56fff5 ¤   ¤   ¤   ¤   ¤   ¤   PGPclCloseClientPrefs (prefref, TRUE);
7c1c89 ¤   ¤   ¤   ¤   ¤   }
ea2613 ¤   ¤   ¤   ¤   }
15f622 ¤   ¤   ¤   ¤   break;
ceaf5a
433fb4 ¤   ¤   ¤   case kPGPError_UserAbort :
8c8695 ¤   ¤   ¤   ¤   bAskUser = FALSE;
c7f622 ¤   ¤   ¤   ¤   break;
44a3a6 ¤   ¤   ¤   }
8c0fe4 ¤   ¤   }
1caf5a
da53af ¤   ¤   if (err == kPGPError_NoErr) {
c96dc1 ¤   ¤   ¤   // reset cache duration
d1e3b6 ¤   ¤   ¤   sSetCacheDuration (&cacheSigning, uCacheSecs);
0caf5a
fffea1 ¤   ¤   ¤   // see if cached key is in keyset
c3f314 ¤   ¤   ¤   if (pkeySigning) {
e169b4 ¤   ¤   ¤   ¤   err = PGPImportKeyID (&cacheSigning.CachedKeyID, &keyid);
5056ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
7eaf5a
25cdf6 ¤   ¤   ¤   ¤   ¤   // if so, get keyref for this keyid
e8ff6f ¤   ¤   ¤   ¤   ¤   err = PGPGetKeyByKeyID (keysetSigning, &keyid,·
248dd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_Invalid, pkeySigning);
c7d820 ¤   ¤   ¤   ¤   ¤   if (IsPGPError (err))·
e08bc5 ¤   ¤   ¤   ¤   ¤   ¤   *pkeySigning = NULL;
ee2613 ¤   ¤   ¤   ¤   }
43af5a
d949fe ¤   ¤   ¤   ¤   err = sCopyCache (&cacheSigning, context, pszBuffer,·
72bd18 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppPasskeyBuffer, piPasskeyLength);
a5af5a
76d6df ¤   ¤   ¤   ¤   if (pulHashAlg)·
c7047d ¤   ¤   ¤   ¤   ¤   *pulHashAlg = cacheSigning.CachedHashAlg;
d8f14c ¤   ¤   ¤   ¤   if (puOptions)·
11653f ¤   ¤   ¤   ¤   ¤   *puOptions = cacheSigning.uCachedOptions;
b1af5a
f58695 ¤   ¤   ¤   ¤   bAskUser = FALSE;
b1a3a6 ¤   ¤   ¤   }
9c0fe4 ¤   ¤   }
619371 ¤   }
deaf5a
07ad5d ¤   // otherwise, get phrase from user
970c59 ¤   if (bAskUser)·
81c7a1 ¤   {
3116e5 ¤   ¤   sEmptyCache (&cacheSigning);
e8af5a
dea195 ¤   ¤   // call PGPcl routine to post passphrase dialog
ac6092 ¤   ¤   err = PGPclGetPhrase (context, keysetSigning, hwnd, szPrompt,·
efb983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·&cacheSigning.pszCachedPassphrase,·
5f3a7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·NULL, NULL, 0, pkeySigning, puOptions,·
17c98d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·uFlags,
3d2c85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·&cacheSigning.pCachedPasskey,
a187fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·&cacheSigning.iCachedPasskeyLength,
2fdfe3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·0, 0, tlsContext, pkeysetAdded);
f4af5a
887810 ¤   ¤   // user entered phrase -- setup cache
f73c66 ¤   ¤   if ((err == kPGPError_NoErr) &&·
4573ed ¤   ¤   ¤   (cacheSigning.pszCachedPassphrase ||·
8bc154 ¤   ¤   ¤   ¤   ¤   ¤   cacheSigning.pCachedPasskey))·
285b34 ¤   ¤   {
e5d668 ¤   ¤   ¤   // scramble cache contents
8e16be ¤   ¤   ¤   sScrambleCache (&cacheSigning);
--52b5 0006fc549dd4011028a Page 8 of CLcache.c
e0af5a
0ba8f1 ¤   ¤   ¤   if (bCacheEnabled) {
efe354 ¤   ¤   ¤   ¤   sSetCacheDuration (&cacheSigning, uCacheSecs);
0aaf5a
af83a7 ¤   ¤   ¤   ¤   if (!cacheSigning.bCacheActive) {
17cdbc ¤   ¤   ¤   ¤   ¤   cacheSigning.bCacheActive = TRUE;
e99cee ¤   ¤   ¤   ¤   ¤   _beginthreadex (NULL, 0,·
8a01ae ¤   ¤   ¤   ¤   ¤   ¤   (LPTHREAD_START_ROUTINE)sClearSigningCacheThread,·
482dcc ¤   ¤   ¤   ¤   ¤   ¤   0, 0, &dw);
9f2613 ¤   ¤   ¤   ¤   }
0ba3a6 ¤   ¤   ¤   }
98af5a
959e3c ¤   ¤   ¤   // copy to caller's buffers
745cdd ¤   ¤   ¤   err = sCopyCache (&cacheSigning, context, pszBuffer,·
657e3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppPasskeyBuffer, piPasskeyLength);
44af5a
d8a8c1 ¤   ¤   ¤   PGPGetHashAlgUsed (*pkeySigning, &cacheSigning.CachedHashAlg);
ae6d89 ¤   ¤   ¤   if (pulHashAlg)·
ade67d ¤   ¤   ¤   ¤   *pulHashAlg = cacheSigning.CachedHashAlg;
3aaf5a
23a8f1 ¤   ¤   ¤   if (bCacheEnabled) {
b8f14c ¤   ¤   ¤   ¤   if (puOptions)·
10e338 ¤   ¤   ¤   ¤   ¤   cacheSigning.uCachedOptions = *puOptions;
0a5109 ¤   ¤   ¤   ¤   else·
4a762e ¤   ¤   ¤   ¤   ¤   cacheSigning.uCachedOptions = 0;
12af5a
0f7895 ¤   ¤   ¤   ¤   PGPGetKeyIDFromKey (*pkeySigning, &keyid);
615b3b ¤   ¤   ¤   ¤   PGPExportKeyID (&keyid,·
099007 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   cacheSigning.CachedKeyID, &size);
0caf5a
eda644 ¤   ¤   ¤   ¤   PGPGetKeyNumber (*pkeySigning,·
96a0f3 ¤   ¤   ¤   ¤   ¤   kPGPKeyPropAlgID, &cacheSigning.CachedKeyAlg);
63a3a6 ¤   ¤   ¤   }
d56b93 ¤   ¤   ¤   else·
b4f776 ¤   ¤   ¤   {
cf15b0 ¤   ¤   ¤   ¤   sEmptyCache (&cacheSigning);
78a3a6 ¤   ¤   ¤   }
260fe4 ¤   ¤   }
85af5a
9b1765 ¤   ¤   // problem (cancel or other error) -- flush cache
b807e0 ¤   ¤   else {
7e1308 ¤   ¤   ¤   sEmptyCache (&cacheSigning);
fa896c ¤   ¤   ¤   sSetCacheDuration (&cacheSigning, 0);
16af5a
5e1a65 ¤   ¤   ¤   if (err == kPGPError_NoErr)
ca4067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
c20fe4 ¤   ¤   }
1c9371 ¤   }
46af5a
5930f1 ¤   LeaveCriticalSection (&criticalSectionCache);
52af5a
e15ea8 ¤   return err;
c6efe6 }
d7af5a
7f4265 //¤ ___________________________________________________
5f465d //
94b8a0 //¤ Broadcast purge message
48af5a
ac5860 VOID PGPclExport·
efb634 PGPclNotifyPurgePassphraseCache (
a6d425 ¤   ¤   WPARAM wParam,
8c7d61 ¤   ¤   LPARAM lParam)
43bb36 {
8e4b96 ¤   UINT uMessageID;
79af5a
67fe88 ¤   uMessageID = RegisterWindowMessage (PURGEPASSPHRASECACEHMSG);
ce2e91 ¤   PostMessage (HWND_BROADCAST, uMessageID, wParam, lParam);
78efe6 }
a2af5a
54b71e //___________________________________
cf465d //
6f9cf3 //¤ PGPPurgeCachedDecryptionPhrase
--058c 00087dc807f4011028a Page 9 of CLcache.c
e652ef //¤ Called to purge phrase from cache.
72af5a
39c4cd BOOL PGPclExport
299ab4 PGPclPurgeCachedPassphrase (DWORD dwFlags)·
79bb36 {
c335f5 ¤   BOOL¤   bReturn¤¤   = FALSE;
acaf5a
b8a191 ¤   EnterCriticalSection (&criticalSectionCache);
68af5a
3705ff ¤   if (dwFlags & PGPCL_DECRYPTIONCACHE) {
c6b37e ¤   ¤   sEmptyCache (&cacheDecryption);
817a3b ¤   ¤   sSetCacheDuration (&cacheDecryption, 0);
604e62 ¤   ¤   bReturn |= cacheDecryption.bCacheActive;
409371 ¤   }
95af5a
88675b ¤   if (dwFlags & PGPCL_SIGNINGCACHE) {
5e16e5 ¤   ¤   sEmptyCache (&cacheSigning);
4ec652 ¤   ¤   sSetCacheDuration (&cacheSigning, 0);
d0e22d ¤   ¤   bReturn |= cacheSigning.bCacheActive;
369371 ¤   }
f4af5a
b030f1 ¤   LeaveCriticalSection (&criticalSectionCache);
5aaf5a
f332bc ¤   return bReturn;
d7efe6 }
f7af5a
4d7015 //________________________________________________
fa465d //
2e276f //¤ PGPFreeCachedPhrase
400e82 //¤ Called to wipe and free the phrase returned by
a41917 //¤ PGPGetCachedPhrase.
3aaf5a
2fdb9e VOID PGPclExport
99e2d5 PGPclFreeCachedPhrase (LPSTR szPhrase)·
34bb36 {
473ab2 ¤   pgpClearMemory (szPhrase, lstrlen (szPhrase));
7b3088 ¤   secFree (szPhrase);
16efe6 }
57af5a
f44260 //_________________________________________________________
ef465d //
6f7ab1 //¤ PGPQueryDecryptCacheSecsRemaining
3fa70d //¤ Returns number of seconds remaining until cache expires
71af5a
f21e15 INT PGPclExport·
6d68a7 PGPclQueryDecryptionCacheSecsRemaining (VOID)·
e6bb36 {
377542 ¤   return (cacheDecryption.iCacheCounter);¤
38efe6 }
0caf5a
cb4260 //_________________________________________________________
2a465d //
ac44a2 //¤ PGPQuerySignCacheSecsRemaining
76a70d //¤ Returns number of seconds remaining until cache expires
f7af5a
278a9a INT PGPclExport
d58c6c PGPclQuerySigningCacheSecsRemaining (VOID)·
9bbb36 {
92a1ae ¤   return (cacheSigning.iCacheCounter);¤
6defe6 }
63af5a
5eaf5a
d8d287 //_____________________________________________________
5a465d //
48af5a
62fe80 VOID
f2a215 PGPInitPassphraseCaches (PGPContextRef context)
17bb36 {
41add0 ¤   if (!bScramblerInitialized) {
659ea2 ¤   ¤   PGPContextGetRandomBytes (context,·
8c9a7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   szScrambler, sizeof(szScrambler));
87e61a ¤   ¤   bScramblerInitialized = TRUE;
--be6c 001a9deb58e4011028a Page 10 of CLcache.c
a19371 ¤   }
93af5a
7b0dd9 ¤   pgpClearMemory (&cacheDecryption, sizeof(CACHE));
a7a904 ¤   pgpClearMemory (&cacheSigning, sizeof(CACHE));
ecaf5a
12af5a
10735d ¤   InitializeCriticalSection (&criticalSectionCache);
93efe6 }
1eaf5a
6ed287 //_____________________________________________________
09465d //
21af5a
78fe80 VOID
2ee044 PGPClosePassphraseCaches (VOID)
49bb36 {
6b957e ¤   while (
210ecd ¤   ¤   PGPclPurgeCachedPassphrase (
d3ec6a ¤   ¤   ¤   PGPCL_DECRYPTIONCACHE|PGPCL_SIGNINGCACHE))·
7dc7a1 ¤   {
a82599 ¤   ¤   Sleep (200);
9d9371 ¤   }
83af5a
c60dd9 ¤   pgpClearMemory (&cacheDecryption, sizeof(CACHE));
4ca904 ¤   pgpClearMemory (&cacheSigning, sizeof(CACHE));
eceac7 ¤   DeleteCriticalSection (&criticalSectionCache);
c6efe6 }
62af5a
a9af5a
--401e 000d03e91904011028b Page 1 of CLerror.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
3677df ¤   CLerror.c - convert error codes to strings and display in messagebox
3a67c5 ¤
b4af5a
a6d2d4 ¤   $Id: CLerror.c,v 1.10 1998/08/11 14:43:07 pbj Exp $
1ff7f7 ____________________________________________________________________________*/
dbe610 #include "pgpPFLConfig.h"
c2af5a
e9c917 // project header files
f65fcd #include "pgpclx.h"
b9af5a
3693ed // external globals
259cad extern HINSTANCE g_hInst;
a9af5a
c09f11 //¤ _____________________________________
ff465d //
5d70d9 //¤ get descriptive string for error code
caaf5a
559d43 PGPError PGPclExport·
e05e56 PGPclErrorToString (
d7422d ¤   ¤   INT¤¤   iCode,·
b60a6b ¤   ¤   LPSTR¤  szString,·
a1a05a ¤   ¤   UINT¤   uLen)·
22bb36 {
e67f23 ¤   PGPError¤   err¤¤   ¤   = kPGPError_NoErr;
efd140 ¤   UINT¤   ¤   uIDS;
05af5a
4a5c05 ¤   if (IsntPGPError (iCode)) return FALSE;
17af5a
2cafae ¤   switch (iCode) {
957e47 ¤   ¤   case kPGPError_UserAbort :
4ec9f4 ¤   ¤   case kPGPError_Interrupted :
d51655 ¤   ¤   case kPGPError_Win32_AlreadyOpen :
a2b32f ¤   ¤   ¤   return err;
feaf5a
26c8dd ¤   ¤   case kPGPError_Win32_NoSecretKeys :
b9f806 ¤   ¤   ¤   uIDS = IDS_ERR_NOSECRETKEYS;
50cdcb ¤   ¤   ¤   break;
e9af5a
566b3e ¤   ¤   case kPGPError_Win32_Expired :
8e0932 ¤   ¤   ¤   uIDS = IDS_ERR_EXPIRED;
43cdcb ¤   ¤   ¤   break;
06af5a
05de74 ¤   ¤   case kPGPError_Win32_NoSigningKey :
5b5050 ¤   ¤   ¤   uIDS = IDS_ERR_NOSIGNINGKEYFORSEARCH;
fecdcb ¤   ¤   ¤   break;
7caf5a
ea1921 ¤   ¤   case kPGPError_Win32_ImageTooBig :
a28ef9 ¤   ¤   ¤   uIDS = IDS_ERR_IMAGETOOBIG;
f1cdcb ¤   ¤   ¤   break;
81af5a
355ae8 ¤   ¤   case kPGPError_Win32_InvalidImage :
bcb9a3 ¤   ¤   ¤   uIDS = IDS_ERR_INVALIDIMAGE;
96cdcb ¤   ¤   ¤   break;
04af5a
b7fe17 ¤   ¤   case kPGPError_Win32_InvalidComctl32 :
580356 ¤   ¤   ¤   uIDS = IDS_ERR_INVALIDCOMMONCONTROLS;
43cdcb ¤   ¤   ¤   break;
3baf5a
ebd446 ¤   ¤   case kPGPError_OutOfMemory :
81b5b8 ¤   ¤   ¤   uIDS = IDS_ERR_OUTOFMEMORY;
84cdcb ¤   ¤   ¤   break;
3aaf5a
09f613 ¤   ¤   case kPGPError_CantOpenFile :
b364ef ¤   ¤   case kPGPError_FileNotFound :¤  ¤   //???
dacb81 ¤   ¤   ¤   uIDS = IDS_ERR_NOFILE;
d0cdcb ¤   ¤   ¤   break;
ffaf5a
d034cd ¤   ¤   case kPGPError_FilePermissions :
--0826 000f385617e4011028b Page 2 of CLerror.c
f3d5ef ¤   ¤   case kPGPError_FileLocked :
d9cc46 ¤   ¤   ¤   uIDS = IDS_ERR_FILEPERMISSIONS;
f9cdcb ¤   ¤   ¤   break;
d8af5a
b7dfb3 ¤   ¤   case kPGPError_WriteFailed :
c5dfa6 ¤   ¤   case kPGPError_DiskFull :¤  ¤   ¤   //???
6634ef ¤   ¤   ¤   uIDS = IDS_ERR_KEYIOWRITING;
a0cdcb ¤   ¤   ¤   break;
3baf5a
532876 ¤   ¤   case kPGPError_IllegalFileOp:
315615 ¤   ¤   ¤   uIDS = IDS_ERR_INVALIDFILEOPERROR;
95cdcb ¤   ¤   ¤   break;
28af5a
39408e ¤   ¤   case kPGPError_IncompatibleAPI :
c9443f ¤   ¤   ¤   uIDS = IDS_ERR_INCOMPATIBLESDKAPI;
0ccdcb ¤   ¤   ¤   break;
3faf5a
17b3fa ¤   ¤   case kPGPError_BadPassphrase :
ba8c74 ¤   ¤   case kPGPError_MissingPassphrase :
f7718b ¤   ¤   ¤   uIDS = IDS_ERR_WRONGKEYPASSPHRASE;
9dcdcb ¤   ¤   ¤   break;
51af5a
75ce91 ¤   ¤   case kPGPError_BadPacket :
642afd ¤   ¤   ¤   uIDS = IDS_ERR_CORRUPTPACKET;
cacdcb ¤   ¤   ¤   break;
15af5a
31377e ¤   ¤   case kPGPError_DuplicateUserID :
f4e84d ¤   ¤   ¤   uIDS = IDS_ERR_DUPLICATEUSERID;
67cdcb ¤   ¤   ¤   break;
66af5a
f60dd6 ¤   ¤   case kPGPError_DuplicateCert :
4f3964 ¤   ¤   ¤   uIDS = IDS_ERR_DUPLICATECERT;
62cdcb ¤   ¤   ¤   break;
7daf5a
c6bd5f ¤   ¤   case kPGPError_NoDecryptionKeyFound :
56ce56 ¤   ¤   ¤   uIDS = IDS_ERR_EXTRACTKEYNOTEXIST;
d9cdcb ¤   ¤   ¤   break;
13af5a
38cd48 ¤   ¤   case kPGPError_DetachedSignatureFound :
844e4c ¤   ¤   ¤   uIDS = IDS_ERR_DETSIGFOUND;
aacdcb ¤   ¤   ¤   break;
7caf5a
e96846 ¤   ¤   case kPGPError_KeyUnusableForEncryption :
79652b ¤   ¤   ¤   uIDS = IDS_ERR_SIGONLYKEY;
becdcb ¤   ¤   ¤   break;
04af5a
ddd891 ¤   ¤   case kPGPError_KeyUnusableForSignature :
507af5 ¤   ¤   ¤   uIDS = IDS_ERR_ENCRYPTONLYKEY;
76cdcb ¤   ¤   ¤   break;
2aaf5a
b2c7a6 ¤   ¤   case kPGPError_RandomSeedTooSmall :
1a6e96 ¤   ¤   case kPGPError_OutOfEntropy :
b31b8d ¤   ¤   ¤   uIDS = IDS_ERR_RNGNOTSEEDED;
e9cdcb ¤   ¤   ¤   break;
1baf5a
0a6121 ¤   ¤   case kPGPError_InputFile :
3a4271 ¤   ¤   ¤   uIDS = IDS_ERR_INPUTFILENOTEXIST;
4dcdcb ¤   ¤   ¤   break;
88af5a
749384 ¤   ¤   case kPGPError_OutputBufferTooSmall :
8c5588 ¤   ¤   ¤   uIDS = IDS_ERR_OUTPUTBUFFERTOOSMALL;
d0cdcb ¤   ¤   ¤   break;
67af5a
522c67 ¤   ¤   case kPGPError_KeyInvalid :
a795fe ¤   ¤   ¤   uIDS = IDS_ERR_CANNOTUSEUNTRUSTEDKEY;
74cdcb ¤   ¤   ¤   break;
88af5a
765197 ¤   ¤   case kPGPError_FileOpFailed :
b81ee5 ¤   ¤   ¤   uIDS = IDS_ERR_FILEOPFAILED;
00cdcb ¤   ¤   ¤   break;
12af5a
f32ce3 ¤   ¤   case kPGPError_ReadFailed :
--47e8 000488dc9f64011028b Page 3 of CLerror.c
1dd56f ¤   ¤   case kPGPError_EOF :
968859 ¤   ¤   ¤   uIDS = IDS_ERR_KEYRINGCORRUPT;
d4cdcb ¤   ¤   ¤   break;
5caf5a
f76407 ¤   ¤   case kPGPError_ServerKeyFailedPolicy :
bf700f ¤   ¤   ¤   uIDS = IDS_ERR_KEYFAILEDPOLICY;
cacdcb ¤   ¤   ¤   break;
a6af5a
b3d12f ¤   ¤   case kPGPError_UnsupportedHKPFilter :
1d8ba0 ¤   ¤   ¤   uIDS = IDS_ERR_UNSUPPORTEDHTTPFILTER;
92cdcb ¤   ¤   ¤   break;
81af5a
e19ae3 ¤   ¤   default:
4b67eb ¤   ¤   ¤   uIDS = IDS_ERR_CATCHALL;
0ecdcb ¤   ¤   ¤   break;
4a9371 ¤   }
f3af5a
5d5da1 ¤   if (uIDS == IDS_ERR_CATCHALL) {
a10260 ¤   ¤   CHAR¤   sz1[256];
d581b2 ¤   ¤   err = PGPGetClientErrorString (iCode, sizeof(sz1), sz1);
f98536 ¤   ¤   if (IsntPGPError (err)) {
bd01e4 ¤   ¤   ¤   CHAR¤   sz2[256];
caf6c8 ¤   ¤   ¤   LoadString (g_hInst, IDS_ERRORPREFIX, sz2, sizeof(sz2));
cac54c ¤   ¤   ¤   lstrcat (sz2, sz1);
5188a4 ¤   ¤   ¤   lstrcpyn (szString, sz2, uLen);
3a6a48 ¤   ¤   ¤   szString[uLen-1] = '\0';
4d0fe4 ¤   ¤   }
e407e0 ¤   ¤   else {
e462f8 ¤   ¤   ¤   LoadString (g_hInst, uIDS, szString, uLen);
14388d ¤   ¤   ¤   wsprintf (sz1, szString, iCode);
f3bb32 ¤   ¤   ¤   strncpy (szString, sz1, uLen);
306a48 ¤   ¤   ¤   szString[uLen-1] = '\0';
f40fe4 ¤   ¤   }
d59371 ¤   }
040da8 ¤   else LoadString (g_hInst, uIDS, szString, uLen);
e8af5a
a33124 ¤   return kPGPError_UnknownError;
b2efe6 }
71af5a
7c9f11 //¤ _____________________________________
1f465d //
359d26 //¤ putup error messagebox (if necessary)
84af5a
dd9d43 PGPError PGPclExport·
3dddaf PGPclErrorBox (
750f64 ¤   ¤   HWND hWnd,
398315 ¤   ¤   INT iCode)·
62bb36 {
1a1398 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
7d8446 ¤   CHAR¤   ¤   szMessage[512];
554856 ¤   CHAR¤   ¤   szCaption[64];
9eaf5a
3fdf0c ¤   err = PGPclErrorToString (iCode, szMessage, sizeof(szMessage));
940971 ¤   if (IsPGPError (err)) {
5644cf ¤   ¤   LoadString (g_hInst, IDS_ERRORMESSAGECAPTION, szCaption,·
76b559 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szCaption));
04e722 ¤   ¤   MessageBox (hWnd, szMessage, szCaption,·
612e08 ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|
8af0c3 ¤   ¤   ¤   ¤   ¤   ¤   MB_TASKMODAL|MB_TOPMOST);
889371 ¤   }
33af5a
ad5ea8 ¤   return err;
ceefe6 }
ccaf5a
d49f11 //¤ _____________________________________
fd465d //
4970d9 //¤ get descriptive string for error code
5baf5a
009d43 PGPError PGPclExport·
dc9e39 PGPclEncDecErrorToString (
e6422d ¤   ¤   INT¤¤   iCode,·
480a6b ¤   ¤   LPSTR¤  szString,·
--910e 001901d77124011028b Page 4 of CLerror.c
52a05a ¤   ¤   UINT¤   uLen)·
50bb36 {
cc7f23 ¤   PGPError¤   err¤¤   ¤   = kPGPError_NoErr;
6ad140 ¤   UINT¤   ¤   uIDS;
d6af5a
1b5c05 ¤   if (IsntPGPError (iCode)) return FALSE;
c4af5a
9bafae ¤   switch (iCode) {
c87e47 ¤   ¤   case kPGPError_UserAbort :
c9c9f4 ¤   ¤   case kPGPError_Interrupted :
85b32f ¤   ¤   ¤   return err;
14af5a
889ae3 ¤   ¤   default:
6c67eb ¤   ¤   ¤   uIDS = IDS_ERR_CATCHALL;
c1cdcb ¤   ¤   ¤   break;
b49371 ¤   }
27af5a
cb5da1 ¤   if (uIDS == IDS_ERR_CATCHALL) {
1d0260 ¤   ¤   CHAR¤   sz1[256];
1781b2 ¤   ¤   err = PGPGetClientErrorString (iCode, sizeof(sz1), sz1);
388536 ¤   ¤   if (IsntPGPError (err)) {
2b01e4 ¤   ¤   ¤   CHAR¤   sz2[256];
74f6c8 ¤   ¤   ¤   LoadString (g_hInst, IDS_ERRORPREFIX, sz2, sizeof(sz2));
b6c54c ¤   ¤   ¤   lstrcat (sz2, sz1);
d888a4 ¤   ¤   ¤   lstrcpyn (szString, sz2, uLen);
f86a48 ¤   ¤   ¤   szString[uLen-1] = '\0';
750fe4 ¤   ¤   }
3907e0 ¤   ¤   else {
b262f8 ¤   ¤   ¤   LoadString (g_hInst, uIDS, szString, uLen);
1c388d ¤   ¤   ¤   wsprintf (sz1, szString, iCode);
3cbb32 ¤   ¤   ¤   strncpy (szString, sz1, uLen);
286a48 ¤   ¤   ¤   szString[uLen-1] = '\0';
8a0fe4 ¤   ¤   }
f79371 ¤   }
280da8 ¤   else LoadString (g_hInst, uIDS, szString, uLen);
b1af5a
f03124 ¤   return kPGPError_UnknownError;
09efe6 }
02af5a
d79f11 //¤ _____________________________________
76465d //
349d26 //¤ putup error messagebox (if necessary)
b9af5a
559d43 PGPError PGPclExport·
98678c PGPclEncDecErrorBox (
eb0f64 ¤   ¤   HWND hWnd,
558315 ¤   ¤   INT iCode)·
e0bb36 {
a01398 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
248446 ¤   CHAR¤   ¤   szMessage[512];
bc4856 ¤   CHAR¤   ¤   szCaption[64];
39af5a
65f73c ¤   err = PGPclEncDecErrorToString (iCode, szMessage, sizeof(szMessage));
cd0971 ¤   if (IsPGPError (err)) {
2844cf ¤   ¤   LoadString (g_hInst, IDS_ERRORMESSAGECAPTION, szCaption,·
96b559 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szCaption));
20e722 ¤   ¤   MessageBox (hWnd, szMessage, szCaption,·
ed2e08 ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|
e6f0c3 ¤   ¤   ¤   ¤   ¤   ¤   MB_TASKMODAL|MB_TOPMOST);
4c9371 ¤   }
c2af5a
9f5ea8 ¤   return err;
a2efe6 }
90af5a
--36e9 000716b01a84011028c Page 1 of CLexpire.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
3720d8 ¤   CLexpire.c - product timeout routines (from Brett Thomas)
6967c5 ¤
e3af5a
36c1d1 ¤   $Id: CLexpire.c,v 1.7.2.2 1998/10/26 18:56:24 build Exp $
d1f7f7 ____________________________________________________________________________*/
d1e610 #include "pgpPFLConfig.h"
beaf5a
6ac917 // project header files
3e5fcd #include "pgpclx.h"
dbaf5a
15fc2c // system header files
29feb2 #include <stdio.h>
abbea3 #include <stdlib.h>
130a8b #include <time.h>
95b1cb #include <ctype.h>
39324c #include <string.h>
03bb5f #include <assert.h>
ccaf5a
c46503 #define PGP_DEMO_DAYS_EVAL¤ ¤   30
b2de56 #define PGP_DEMO_DAYS_PREDELETE¤30
24af5a
6e9cad extern HINSTANCE g_hInst;
a0af5a
d4d673 #if PGP_DEMO
afaf5a
9fcecc /* Windows registry key for expiration date */
54af5a
e75f79 #define EVAL_TIMEOUT_KEY¤   "Software\\PGP\\PGP"
2a7bb0 #define EVAL_TIMEOUT_VALUE¤ "60Trial"
17af5a
3c37eb /* RunOnce settings to delete library files */
f6af5a
592daa #define RUN_ONCE¤   "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce"
9daf5a
3c6ab5 static void DeleteTimeoutFile(char *szDelFile);
05af5a
042d33 #endif¤ // PGP_DEMO
35af5a
3c148a char Months[14][4] = {"\0",
df1c08 ¤   ¤   ¤   ¤   ¤   ·"JAN",
c097d8 ¤   ¤   ¤   ¤   ¤   ·"FEB",
69544c ¤   ¤   ¤   ¤   ¤   ·"MAR",
39dabc ¤   ¤   ¤   ¤   ¤   ·"APR",
809459 ¤   ¤   ¤   ¤   ¤   ·"MAY",
918558 ¤   ¤   ¤   ¤   ¤   ·"JUN",
aebc2e ¤   ¤   ¤   ¤   ¤   ·"JUL",
ca511e ¤   ¤   ¤   ¤   ¤   ·"AUG",
bc3b38 ¤   ¤   ¤   ¤   ¤   ·"SEP",
660108 ¤   ¤   ¤   ¤   ¤   ·"OCT",
834b65 ¤   ¤   ¤   ¤   ¤   ·"NOV",
408335 ¤   ¤   ¤   ¤   ¤   ·"DEC",
f24798 ¤   ¤   ¤   ¤   ¤   ·"\0"};
62af5a
10e604 static void TranslateDate(unsigned short *Month,
f00921 ¤   ¤   ¤   ¤   ···unsigned short *Day,
3f07c5 ¤   ¤   ¤   ¤   ···unsigned short *Year,
de3a80 ¤   ¤   ¤   ¤   ···char *DateString);
acaf5a
994ab0 static unsigned short FindMonth(char *MonthName);
81e037 static void DisplayTimeoutMessage(HWND hwnd);
c1af5a
bc533a // This just makes sure that BETA_TIMEOUT isn't > 0 at the same
891059 // time PGP_DEMO is defined
1daf5a
75d673 #if PGP_DEMO
db7c9e #define BETA_TIMEOUT ·······0
29db21 #else
715bbe // This is the value to change for beta timeout
--ad47 000a3e1de7f4011028c Page 2 of CLexpire.c
5f8d9d #define BETA_TIMEOUT¤   ¤   0 ··// This number represents the number of days
ce7b63 #endif ·························//¤ ¤   till the beta expires from compile date
1085cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // Setting this to 0 will turn off the time out¶
fe4e91 ·feature,
d8ae8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //¤ ¤   the default time out lenghth is 60 days
afaf5a
da9d43 PGPError PGPclExport·
cedc14 PGPclIsExpired(HWND hwnd)
ebbb36 {
82c55b ¤   PGPError err = kPGPError_NoErr;
ba8c8a #if BETA_TIMEOUT > 0
1ba721 ¤   unsigned short month, day, year;
477397 ¤   struct tm tm, *ptm;
1fb340 ¤   time_t TimeNow, TimeoutTime;
bdaf5a
acd5e9 ¤   //Get the compile date, in usable form:
c179f9 ¤   TranslateDate(&month, &day, &year, __DATE__);
b5af5a
3e4fcb ¤   //Seed the tm structure with the current time:
8fc90f ¤   time(&TimeNow);
08f298 ¤   ptm = localtime(&TimeNow);
c35a44 ¤   memcpy(&tm, ptm, sizeof(tm));
acaf5a
e64eee ¤   //Set the dates to the compile time:
037998 ¤   tm.tm_mon = month - 1;
77a877 ¤   tm.tm_mday = day;
82415b ¤   tm.tm_year = year - 1900;
f6af5a
b4a5c1 ¤   //Turn the compile time into number of secs since 1/1/1970:
feafd9 ¤   TimeoutTime = mktime(&tm);
47af5a
402f56 ¤   //Increment it plus the number of days in the beta timeout times the·
9874b6 ¤   TimeoutTime += BETA_TIMEOUT * (60 * 60 * 24); //number of seconds in a day
57af5a
b1d6f4 ¤   if(TimeoutTime < TimeNow)
d9c7a1 ¤   {
098de5 ¤   ¤   err = kPGPError_FeatureNotAvailable;
7643dc ¤   ¤   DisplayTimeoutMessage(hwnd);
479371 ¤   }
c908a8 #endif¤ // BETA_TIMEOUT > 0
94af5a
e2d673 #if PGP_DEMO
eeaf5a
ceed9d ¤   // The timeout starts at 30 days, which only disables encrypt and sign
2dfac4 ¤   // After 30 days, display nag screen
65bc3f ¤   // After 60 days (TimeOut + 30 days), time out everything and·
d78eb5 ¤   //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   delete library DLL's
9567c5 ¤
9a846f ¤   err = PGPclEvalExpired(hwnd, PGPCOMDLG_ALLEXPIRED);
d5de9b ¤   if (IsPGPError (err))
07c7a1 ¤   {
7590c1 ¤   ¤   pgpFixBeforeShip ("eval version file deletion");
2a9990 ///???¤ ¤   DeleteTimeoutFile("pgpsdk.dll");
14cae3 ///???¤ ¤   DeleteTimeoutFile("pgp.dll");
5443dc ¤   ¤   DisplayTimeoutMessage(hwnd);
fc9371 ¤   }
a1af5a
f2bf39 ¤   if (IsPGPError(PGPclEvalExpired(hwnd, PGPCOMDLG_ENCRYPTSIGNEXPIRED)) &&·
bbf881 ¤   ¤   ¤   !IsntPGPError (err))
af606e ¤   ¤   PGPclNag(hwnd, NULL, NULL);
bdaf5a
d92d33 #endif¤ // PGP_DEMO
4faf5a
4b5ea8 ¤   return err;
27efe6 }
5eaf5a
adaf5a
b4d673 #if PGP_DEMO
c5af5a
7f9d43 PGPError PGPclExport·
b61071 PGPclEvalExpired (HWND hwnd, int nIndex)
a3bb36 {
--5ed4 0008b26b1444011028c Page 3 of CLexpire.c
b06fcf ¤   HKEY hkey;
e93ab0 ¤   PGPTime TimeOut = 0;
d15150 ¤   PGPTime Today = 0;
cd0fc0 ¤   BOOL NeedInitialization = TRUE;
278cdc ¤   DWORD disposition;
75c55b ¤   PGPError err = kPGPError_NoErr;
16af5a
a3d735 ····TimeOut = pgpGetTime();
7fb537 ¤   Today = TimeOut;
4daf5a
4ea390 ¤   TimeOut += PGP_DEMO_DAYS_EVAL * (60 * 60 * 24);
86af5a
15f001 ¤   if(RegCreateKeyEx(HKEY_CURRENT_USER,
98dba8 ¤   ¤   ¤   ¤   ¤   ··EVAL_TIMEOUT_KEY,
69e268 ¤   ¤   ¤   ¤   ¤   ··0,
f7ddd9 ¤   ¤   ¤   ¤   ¤   ··"",
de1cfe ¤   ¤   ¤   ¤   ¤   ··REG_OPTION_NON_VOLATILE,
1869f4 ¤   ¤   ¤   ¤   ¤   ··KEY_ALL_ACCESS,
5f7aa3 ¤   ¤   ¤   ¤   ¤   ··NULL,
ef5b17 ¤   ¤   ¤   ¤   ¤   ··&hkey,
49cb49 ¤   ¤   ¤   ¤   ¤   ··&disposition) == ERROR_SUCCESS)
4bc7a1 ¤   {
99f31e ¤   ¤   DWORD Size,Type;
6aaf5a
7adf07 ¤   ¤   Size = sizeof(TimeOut);
2d5f0f ¤   ¤   if(RegQueryValueEx(hkey,·
a760bd ¤   ¤   ¤   ¤   ¤   ¤   ···EVAL_TIMEOUT_VALUE,·
a1b168 ¤   ¤   ¤   ¤   ¤   ¤   ···NULL,·
389466 ¤   ¤   ¤   ¤   ¤   ¤   ···&Type,·
2df99d ¤   ¤   ¤   ¤   ¤   ¤   ···(BYTE*) &TimeOut,·
dbb458 ¤   ¤   ¤   ¤   ¤   ¤   ···&Size) != ERROR_SUCCESS)
385b34 ¤   ¤   {
cbc6bc ¤   ¤   ¤   /*Assume it's a new key...*/
d94eb6 ¤   ¤   ¤   RegSetValueEx(hkey,
9de3c4 ¤   ¤   ¤   ¤   ¤   ¤   ··EVAL_TIMEOUT_VALUE,
2ad635 ¤   ¤   ¤   ¤   ¤   ¤   ··0,
0b7db1 ¤   ¤   ¤   ¤   ¤   ¤   ··REG_DWORD,
873c2b ¤   ¤   ¤   ¤   ¤   ¤   ··(BYTE *) &TimeOut,
f05ace ¤   ¤   ¤   ¤   ¤   ¤   ··sizeof(TimeOut));
010fe4 ¤   ¤   }
568e93 ¤   ¤   RegCloseKey(hkey);
eb9371 ¤   }
0caf5a
95ed9d ¤   // The timeout starts at 30 days, which only disables encrypt and sign
c1fac4 ¤   // After 30 days, display nag screen
64bc3f ¤   // After 60 days (TimeOut + 30 days), time out everything and·
bf8eb5 ¤   //¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   delete library DLL's
3c288b ¤   if (nIndex == PGPCOMDLG_ALLEXPIRED)
3abe09 ¤   ¤   TimeOut += PGP_DEMO_DAYS_PREDELETE*24*60*60;
89af5a
8793e0 ¤   if (Today > TimeOut)
7b8de5 ¤   ¤   err = kPGPError_FeatureNotAvailable;
89af5a
805ea8 ¤   return err;
69efe6 }
52af5a
cf2d33 #endif¤ // PGP_DEMO
8caf5a
cfaf5a
cde604 static void TranslateDate(unsigned short *Month,
8a0921 ¤   ¤   ¤   ¤   ···unsigned short *Day,
4a07c5 ¤   ¤   ¤   ¤   ···unsigned short *Year,
6e7b8b ¤   ¤   ¤   ¤   ···char *DateString)
63bb36 {
3e5cba ¤   char *BlockStart, *BlockEnd, *TempBuffer;
00af5a
07a93a ¤   assert(DateString);
496330 ¤   assert(Year);
3b6602 ¤   assert(Day);
bfa901 ¤   assert(Month);
adaf5a
8b81e4 ¤   *Month = *Day = *Year = 0;
--8fd3 000535bd5d94011028c Page 4 of CLexpire.c
e0af5a
053706 ¤   if(TempBuffer = malloc((strlen(DateString) + 1) * sizeof(char)))
80c7a1 ¤   {
52df54 ¤   ¤   strcpy(TempBuffer, DateString);
c4a608 ¤   ¤   BlockStart = BlockEnd = TempBuffer;
44085c ¤   ¤   while(BlockEnd && *BlockEnd && !isspace(*BlockEnd))
502636 ¤   ¤   ¤   ++BlockEnd;
46af5a
d5b9d3 ¤   ¤   if(BlockEnd && *BlockEnd)
b65b34 ¤   ¤   {
9a4c56 ¤   ¤   ¤   *BlockEnd = '\0';
7c2123 ¤   ¤   ¤   *Month = FindMonth(BlockStart);
96af5a
1fa231 ¤   ¤   ¤   BlockStart = ++BlockEnd;
99b9ac ¤   ¤   ¤   while(BlockStart && *BlockStart && isspace(*BlockStart))
f80dbb ¤   ¤   ¤   ¤   ++BlockStart;
c4af5a
809ff9 ¤   ¤   ¤   BlockEnd = BlockStart;
65af5a
70cc40 ¤   ¤   ¤   while(BlockEnd && *BlockEnd && !isspace(*BlockEnd))
4fd053 ¤   ¤   ¤   ¤   ++BlockEnd;
16af5a
4756a0 ¤   ¤   ¤   if(BlockEnd && *BlockEnd)
dcf776 ¤   ¤   ¤   {
747b5e ¤   ¤   ¤   ¤   *BlockEnd = '\0';
8c3b9a ¤   ¤   ¤   ¤   *Day = atoi(BlockStart);
6caf5a
e8a7dc ¤   ¤   ¤   ¤   BlockStart = ++BlockEnd;
3aaf5a
9c62b3 ¤   ¤   ¤   ¤   *Year = atoi(BlockStart);
57a3a6 ¤   ¤   ¤   }
6daf5a
c70fe4 ¤   ¤   }
c1f699 ¤   ¤   free(TempBuffer);¤  ¤
919371 ¤   }
efefe6 }
daaf5a
3cd4c8 static unsigned short FindMonth(char *MonthName)
09bb36 {
5a147e ¤   unsigned short MonthNum = 0;
ab94ed ¤   int x;
8faf5a
5f8129 ¤   assert(MonthName);
11af5a
cce135 ¤   for(x = 1; Months[x][0] && !MonthNum; ++x)
a5c7a1 ¤   {
ad9297 ¤   ¤   if(stricmp(Months[x], MonthName) == 0)
4dee2e ¤   ¤   ¤   MonthNum = x;
219371 ¤   }
b2af5a
6c4640 ¤   return(MonthNum);
7defe6 }
06af5a
d22197 static void DisplayTimeoutMessage(HWND hwnd)
7bbb36 {
c18c8a #if BETA_TIMEOUT > 0
897186 ¤   char buf1[512];
c5fb56 ¤   char buf2[512];
7b7e2d #elif PGP_DEMO
be7186 ¤   char buf1[512];
80fb56 ¤   char buf2[512];
ce7454 #endif
9aaf5a
f98c8a #if BETA_TIMEOUT > 0
04af5a
5894bc ¤   LoadString (g_hInst, IDS_BETATIMEOUT, buf1, sizeof(buf1));
ec20e1 ¤   wsprintf (buf2, buf1, BETA_TIMEOUT);
e65ab7 ¤   MessageBox (hwnd, buf2, "Beta Expiration", MB_OK);
bdaf5a
1f08a8 #endif¤ // BETA_TIMEOUT > 0
58af5a
53d673 #if PGP_DEMO
--e3f9 001ce04c2554011028c Page 5 of CLexpire.c
e0af5a
87f3d2 ¤   LoadString (g_hInst, IDS_EVALTIMEOUT, buf1, sizeof(buf1));
e7e486 ¤   wsprintf (buf2, buf1, PGP_DEMO_DAYS_EVAL + PGP_DEMO_DAYS_PREDELETE);
0146e5 ¤   MessageBox(hwnd, buf2, "Evaluation Expiration", MB_OK);
67af5a
fa2d33 #endif¤ // PGP_DEMO
94efe6 }
5caf5a
31af5a
b6d673 #if PGP_DEMO
6caf5a
abdbf9 static void DeleteTimeoutFile(char *szDelFile)
66bb36 {
f86fcf ¤   HKEY hkey;
87ed07 ¤   char szSystemDir[MAX_PATH];
1fd2a6 ¤   char szCommand[MAX_PATH*2];
2dc186 ¤   DWORD Size;
751e1a ¤   int nError;
51af5a
19ceb4 ¤   GetSystemDirectory(szSystemDir, MAX_PATH);
9317c1 ¤   wsprintf(szCommand, "command /c del %s\\%s", szSystemDir, szDelFile);
3faf5a
9c9381 ¤   if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
5027fb ¤   ¤   ¤   ¤   ¤   ··RUN_ONCE,
77e268 ¤   ¤   ¤   ¤   ¤   ··0,
a30a59 ¤   ¤   ¤   ¤   ¤   ··KEY_SET_VALUE,
2d4cc8 ¤   ¤   ¤   ¤   ¤   ··&hkey) == ERROR_SUCCESS)
b9c7a1 ¤   {
8554cc ¤   ¤   Size = strlen(szCommand)+1;
697dbf ¤   ¤   nError = RegSetValueEx(¤hkey,
3a4697 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDelFile,
d342d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
f6fdf3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   REG_SZ,
b987bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szCommand,
98f4f3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   Size);
c58e93 ¤   ¤   RegCloseKey(hkey);
839371 ¤   }
b267c5 ¤
12830f ¤   return;
83efe6 }
a3af5a
ce2d33 #endif¤ // PGP_DEMO
--58a0 000784043814011028d Page 1 of CLgroups.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
7453f6 ¤   CLgroups.c - Open/close group file
9067c5 ¤
ebaf5a
0ac420 ¤   $Id: CLgroups.c,v 1.4 1998/08/11 14:43:08 pbj Exp $
b0f7f7 ____________________________________________________________________________*/
b5e610 #include "pgpPFLConfig.h"
16af5a
ccc917 // project header files
775fcd #include "pgpclx.h"
f2af5a
4e93ed // external globals
069cad extern HINSTANCE g_hInst;
7daf5a
ed9f11 //¤ _____________________________________
11465d //
87f226 //¤ open group file and return groupfile object
67af5a
48ec6d PGPError PGPclExport
7e5386 PGPclOpenGroupFile (
ac9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
fa5085 ¤   ¤   PGPclGROUPFILE**¤   ppGroup)
5dbb36 {
9aa88e ¤   CHAR¤   ¤   ¤   szPath[MAX_PATH];
db4ad1 ¤   CHAR¤   ¤   ¤   szFile[64];
dff366 ¤   PGPFileSpecRef¤ filespec;
a2fb19 ¤   PGPError¤   ¤   err;
4c05f5 ¤   PGPGroupSetRef¤ groupset;
35af5a
aa9deb ¤   *ppGroup = 0;
bd0cf0 ¤   groupset = NULL;
f5af5a
61685b ¤   PGPclGetPGPPath (szPath, sizeof(szPath));
cdd6a1 ¤   LoadString (g_hInst, IDS_GROUPFILENAME, szFile, sizeof(szFile));
a30125 ¤   strcat (szPath, szFile);
d1af5a
800d5b ¤   err = PGPNewFileSpecFromFullPath (context, szPath, &filespec);
19ffd3 ¤   if(IsntPGPError (err))
99c7a1 ¤   {
651d64 ¤   ¤   err = PGPNewGroupSetFromFile (context, filespec, &groupset);
5da42f ¤   ¤   if (IsPGPError (err)) {
e82ac8 ¤   ¤   ¤   err = PGPNewGroupSet (context, &groupset);
9a0fe4 ¤   ¤   }
821b52 ¤   ¤
b19b50 ¤   ¤   *ppGroup = (PGPclGROUPFILE *)malloc (sizeof(PGPclGROUPFILE));
0fd4be ¤   ¤   if (*ppGroup) {
34a100 ¤   ¤   ¤   (*ppGroup)->filespec = filespec;
77b28f ¤   ¤   ¤   (*ppGroup)->groupset = groupset;
e20fe4 ¤   ¤   }
3c07e0 ¤   ¤   else {
08b90c ¤   ¤   ¤   err = kPGPError_OutOfMemory;
f7c291 ¤   ¤   ¤   PGPFreeGroupSet (groupset);
16f1f4 ¤   ¤   ¤   PGPFreeFileSpec (filespec);
f70fe4 ¤   ¤   }
f59371 ¤   }
16af5a
ab5ea8 ¤   return err;
6aefe6 }
50af5a
97af5a
6a9f11 //¤ _____________________________________
9e465d //
b624ac //¤ write group data to file
d3af5a
a4ec6d PGPError PGPclExport
0f831c PGPclSaveGroupFile (PGPclGROUPFILE* pGroup)
39bb36 {
47d166 ¤   if (!pGroup) return kPGPError_BadParams;
78af5a
--1677 001aa7418e24011028d Page 2 of CLgroups.c
3933dc ¤   return (PGPSaveGroupSetToFile (pGroup->groupset, pGroup->filespec));
32efe6 }
90af5a
05af5a
cd9f11 //¤ _____________________________________
44465d //
bbd194 //¤ close down group file
c6af5a
d5ec6d PGPError PGPclExport
c010c2 PGPclCloseGroupFile (PGPclGROUPFILE* pGroup)
fbbb36 {
06d166 ¤   if (!pGroup) return kPGPError_BadParams;
89af5a
cf05ce ¤   if(pGroup->groupset)
0dc550 ¤   ¤   PGPFreeGroupSet (pGroup->groupset);
b1af5a
365888 ¤   if(pGroup->filespec)
cb1e53 ¤   ¤   PGPFreeFileSpec (pGroup->filespec);
97af5a
06df92 ¤   free (pGroup);
cbaf5a
14151e ¤   return kPGPError_NoErr;
7eefe6 }
aaaf5a
--c700 000bd3e81f94011028e Page 1 of CLkspref.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
160fc0 ¤   CLksPref.c - handle keyserver preferences dialogs
5a67c5 ¤
fbaf5a
bd5377 ¤   $Id: CLkspref.c,v 1.31 1998/08/11 14:43:09 pbj Exp $
03f7f7 ____________________________________________________________________________*/
04e610 #include "pgpPFLConfig.h"
daaf5a
c0c917 // project header files
515fcd #include "pgpclx.h"
518ddf #include "..\Include\treelist.h"
69af5a
da5584 // constant definitions
b0ffd5 #define BITMAP_WIDTH 16
f5c2a0 #define BITMAP_HEIGHT 16
16af5a
07128d #define BUTTONOFFSETY¤  10
3caf5a
1b3702 #define DOMAINLISTWIDTH 80
4b612d #define CHECKLISTWIDTH¤ 48
59af5a
b32815 #define IDX_NONE¤   ¤   ¤   ¤   -1
f4d246 #define IDX_UNCHECKED¤  ¤   ¤   0
0c1780 #define IDX_UNCHECKEDPUSHED¤¤   1
87c2bf #define IDX_CHECKED¤¤   ¤   ¤   2
cd04bc #define IDX_CHECKEDPUSHED¤  ¤   3
dd2818 #define IDX_WORLDDOMAIN¤¤   ¤   4
355b32 #define IDX_SERVER¤ ¤   ¤   ¤   5
8f6e0c #define NUM_BITMAPS¤¤   ¤   ¤   6
e9af5a
8b5bee // typedefs
87f0f7 typedef struct {
b1cef5 ¤   HWND¤   ¤   ¤   ¤   ¤   hWndTree;
4e72a8 ¤   BOOL¤   ¤   ¤   ¤   ¤   bEdit;
5834bd ¤   CHAR¤   ¤   ¤   ¤   ¤   szServer[256];
718342 ¤   PGPUInt16¤  ¤   ¤   ¤   iPort;
4bf747 ¤   PGPKeyServerType¤   ¤   iType;
6fb8db ¤   CHAR¤   ¤   ¤   ¤   ¤   szKeyIDAuth[kPGPMaxKeyIDStringSize];
d37fc8 ¤   PGPPublicKeyAlgorithm¤  authAlg;
104613 ¤   CHAR¤   ¤   ¤   ¤   ¤   szUserIDAuth[kPGPMaxUserIDSize +1];
1c25e2 ¤   CHAR¤   ¤   ¤   ¤   ¤   szDomain[256];
844b0a ¤   BOOL¤   ¤   ¤   ¤   ¤   bListed;
c120bf ¤   BOOL¤   ¤   ¤   ¤   ¤   bRoot;
c3c1e7 ¤   VOID*¤  ¤   ¤   ¤   ¤   pOrigStruct;
3b21ec } KEYSERVERSTRUCT, *PKEYSERVERSTRUCT;
8faf5a
fb93ed // external globals
419cad extern HINSTANCE g_hInst;
a30afe extern CHAR g_szHelpFile[MAX_PATH];
39af5a
42492e // local globals
a0e740 static HIMAGELIST hIml;
ba5543 static HTLITEM hTSelected;
6e177d static HTLITEM hTDefault;
5c24e0 static INT iSelectedType;
f5f896 static BOOL bSelectedRoot;
f7206b static UINT uNumberOfServers;
d1af5a
1a0a84 static DWORD aIds[] = {¤¤   ¤   // Help IDs
1a2a8b ¤   IDC_PROTOCOL,¤  ¤   IDH_PGPCLPREF_SERVERPROTOCOL,
8d65fe ····IDC_SERVERNAME,¤¤   IDH_PGPCLPREF_SERVERNAME,·
9be674 ¤   IDC_PORT,¤  ¤   ¤   IDH_PGPCLPREF_SERVERPORT,
f1eb70 ¤   IDC_SERVERKEY,¤ ¤   IDH_PGPCLPREF_SERVERAUTHKEY,
ec4789 ¤   IDC_ANYDOMAIN,¤ ¤   IDH_PGPCLPREF_SERVERNODOMAIN,
5e5962 ····IDC_DOMAIN,¤¤   ¤   IDH_PGPCLPREF_SERVERDOMAIN,·
aad7de ····IDC_SPECIFIEDDOMAIN,IDH_PGPCLPREF_SERVERDOMAIN,·
9605fe ····IDC_LISTED,¤¤   ¤   IDH_PGPCLPREF_SERVERLISTED,·
6f4434 ····0,0·
bda6fe };·
--37c0 0005d2c39424011028e Page 2 of CLkspref.c
e0af5a
713fc0 //¤ _____________________________________________________
18465d //
4b6561 // ·concatenate protocol and server names
f4af5a
98e6b2 static VOID
455537 sURLfromInfo (
dfa1f6 ¤   ¤   PGPKeyServerType¤   iType,·
7f9f0f ¤   ¤   LPSTR¤  ¤   ¤   ¤   szServer,·
9104b8 ¤   ¤   PGPUInt16¤  ¤   ¤   iPort,·
eee13e ¤   ¤   LPSTR¤  ¤   ¤   ¤   szURL)
b1bb36 {
fed7c0 ¤   switch (iType) {
3df820 ¤   case kPGPKeyServerType_LDAP :¤  lstrcpy (szURL, "ldap://"); break;
d7174e ¤   case kPGPKeyServerType_LDAPS :¤ lstrcpy (szURL, "ldaps://"); break;
e66ce2 ¤   case kPGPKeyServerType_HTTPS :¤ lstrcpy (szURL, "https://"); break;
965617 ¤   default :¤  ¤   ¤   ¤   ¤   ¤   lstrcpy (szURL, "http://"); break;
829371 ¤   }
1baf5a
360612 ¤   lstrcat (szURL, szServer);
b7af5a
3d6897 ¤   if (iPort != 0) {
b9237e ¤   ¤   CHAR szPort[8];
66e99c ¤   ¤   wsprintf (szPort, ":%i", iPort);
e1545a ¤   ¤   lstrcat (szURL, szPort);
7e9371 ¤   }
cfefe6 }
d1af5a
983fc0 //¤ _____________________________________________________
98465d //
24be01 // ·put data for one keyserver into treelist
03af5a
985fa5 static HTLITEM
dee3fe sSetOneKSItem (HWND hWndTree, PKEYSERVERSTRUCT pkss)
0bbb36 {
014aea ¤   TL_TREEITEM¤¤   tlI;
02b50a ¤   TL_LISTITEM¤¤   tlL;
75e1c1 ¤   TL_INSERTSTRUCT tlIns;
3db5c5 ¤   HTLITEM¤¤   ¤   hTNew;
de2a4f ¤   CHAR¤   ¤   ¤   sz[256];
acaf5a
f89d26 ¤   sURLfromInfo (pkss->iType, pkss->szServer, pkss->iPort, sz);
8aaf5a
7378ca ¤   tlI.hItem = NULL;
5f90ac ¤   tlI.mask = TLIF_TEXT | TLIF_IMAGE | TLIF_STATE | TLIF_PARAM;
6dc86a ¤   tlI.stateMask = TLIS_BOLD;
319d88 ¤   if (pkss->bRoot)·
b02d39 ¤   ¤   tlI.state = TLIS_BOLD;
d80e24 ¤   else
396244 ¤   ¤   tlI.state = 0;
e0d102 ¤   tlI.pszText = sz;
8b8750 ¤   tlI.cchTextMax = lstrlen (sz);
927e89 ¤   tlI.iImage = IDX_SERVER;
588a38 ¤   tlI.iSelectedImage = IDX_SERVER;
2755a8 ¤   tlI.lParam = (LPARAM)pkss;
1daf5a
c3b710 ¤   tlIns.item = tlI;
58ce45 ¤   tlIns.hInsertAfter = (HTLITEM)TLI_LAST;
997957 ¤   tlIns.hParent = NULL;
1d03a1 ¤   hTNew = TreeList_InsertItem (hWndTree, &tlIns);
23af5a
7fe567 ¤   if (lstrlen (pkss->szDomain))
697470 ¤   ¤   tlL.pszText = pkss->szDomain;
2e4264 ¤   else·
91d960 ¤   ¤   tlL.pszText = NULL;
9bc535 ¤   tlL.hItem = hTNew;
9b030b ¤   tlL.stateMask = TLIS_VISIBLE;
090db3 ¤   tlL.iSubItem = 1;
6afc6d ¤   tlL.mask = TLIF_DATAVALUE | TLIF_TEXT | TLIF_STATE;
3f1fb5 ¤   tlL.state = TLIS_VISIBLE;
44be31 ¤   tlL.lDataValue = IDX_WORLDDOMAIN;
5daf5a
--1605 00043f344554011028e Page 3 of CLkspref.c
928dbd ¤   TreeList_SetListItem (hWndTree, &tlL, FALSE);
36af5a
a52f05 ¤   tlL.pszText = NULL;
d4c535 ¤   tlL.hItem = hTNew;
d2030b ¤   tlL.stateMask = TLIS_VISIBLE;
b8e2d7 ¤   tlL.iSubItem = 2;
3fcaf3 ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
2b1fb5 ¤   tlL.state = TLIS_VISIBLE;
cdaf5a
3e91d1 ¤   if (pkss->bListed) tlL.lDataValue = IDX_CHECKED;
ce3b9a ¤   else tlL.lDataValue = IDX_UNCHECKED;
03af5a
708dbd ¤   TreeList_SetListItem (hWndTree, &tlL, FALSE);
e0af5a
fb3353 ¤   return hTNew;
0befe6 }
82af5a
d93fc0 //¤ _____________________________________________________
8c465d //
9eeacd // ·populate keyserver treelist with data from preferences
c0af5a
6611ec static INT
4b2b74 sFillTreeList (
bbca38 ¤   ¤   PGPPrefRef¤ ¤   PrefRef,·
1efb68 ¤   ¤   PGPContextRef¤  context,·
d4ab5c ¤   ¤   HWND¤   ¤   ¤   hWndTree,
0a11cc ¤   ¤   PGPKeySetRef¤   keysetMain)·
6abb36 {
af476b ¤   PGPKeyServerEntry*¤ keyserverList;
8d23e3 ¤   PGPKeyRef¤  ¤   ¤   key;
5e958b ¤   PGPUInt32¤  ¤   ¤   u, u2;
d78f52 ¤   PGPError¤   ¤   ¤   err;
d94332 ¤   PKEYSERVERSTRUCT¤   pkss;
a4b604 ¤   PGPKeySetRef¤   ¤   keyset;
82e568 ¤   PGPKeyID¤   ¤   ¤   keyid;
30af5a
523677 ¤   // load keyserverprefs
ef7bb0 ¤   err = PGPGetKeyServerPrefs (PrefRef, &keyserverList, &uNumberOfServers);
050fc8 ¤   if (IsPGPError (err))·
ced2a4 ¤   ¤   uNumberOfServers = 0;
6caf5a
34bfce ¤   // get keyset for resolving auth key information
c08cfd ¤   if (keysetMain == NULL) {
f80013 ¤   ¤   err = PGPOpenDefaultKeyRings (context, 0, &keyset);
051be0 ¤   ¤   if (IsPGPError (err))·
2d8aaa ¤   ¤   ¤   keyset = NULL;
899371 ¤   }
8d4264 ¤   else·
671c73 ¤   ¤   keyset = keysetMain;
41af5a
d822aa ¤   for (u=0; u<uNumberOfServers; u++) {
9aaf5a
91bb77 ¤   ¤   pkss = clAlloc (sizeof(KEYSERVERSTRUCT));
b3d514 ¤   ¤   if (pkss) {
dd2c2b ¤   ¤   ¤   pkss->hWndTree = hWndTree;
ac27bf ¤   ¤   ¤   pkss->bEdit = FALSE;
f76b77 ¤   ¤   ¤   lstrcpy (pkss->szServer, keyserverList[u].serverDNS);
59ab70 ¤   ¤   ¤   pkss->iPort = keyserverList[u].serverPort;
52d444 ¤   ¤   ¤   pkss->iType = keyserverList[u].protocol;
3cef8d ¤   ¤   ¤   lstrcpy (pkss->szDomain, keyserverList[u].domain);
f53c31 ¤   ¤   ¤   pkss->bListed = (keyserverList[u].flags & kKeyServerListed);
68d6d0 ¤   ¤   ¤   pkss->authAlg = keyserverList[u].authAlg;
65ea18 ¤   ¤   ¤   pkss->bRoot = (keyserverList[u].flags & kKeyServerIsRoot);
b8af5a
621c77 ¤   ¤   ¤   // get auth key userid
82a39d ¤   ¤   ¤   pkss->szUserIDAuth[0] = '\0';
da40a6 ¤   ¤   ¤   if ((pkss->authAlg != kPGPPublicKeyAlgorithm_Invalid) &&
b9240c ¤   ¤   ¤   ¤   ¤   keyserverList[u].authKeyIDString[0]) {
09a093 ¤   ¤   ¤   ¤   lstrcpy (pkss->szKeyIDAuth,·
aeebee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[u].authKeyIDString);
5cce20 ¤   ¤   ¤   ¤   err = PGPGetKeyIDFromString (
437580 ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[u].authKeyIDString, &keyid);
--1c31 000070a66494011028e Page 4 of CLkspref.c
6356ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
1144af ¤   ¤   ¤   ¤   ¤   err = PGPGetKeyByKeyID (keyset, &keyid,·
0620f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[u].authAlg, &key);
876f6e ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
dfa0f0 ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (key,·
83d965 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(pkss->szUserIDAuth),·
3066ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkss->szUserIDAuth, &u2);
a51c89 ¤   ¤   ¤   ¤   ¤   }
623c4b ¤   ¤   ¤   ¤   ¤   else {
2ecacf ¤   ¤   ¤   ¤   ¤   ¤   lstrcpy (pkss->szUserIDAuth,·
3cebee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[u].authKeyIDString);
701c89 ¤   ¤   ¤   ¤   ¤   }
592613 ¤   ¤   ¤   ¤   }
eca3a6 ¤   ¤   ¤   }
52722b ¤   ¤   ¤   if (pkss->szUserIDAuth[0] == '\0') {
51fce5 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWNKEY, pkss->szUserIDAuth,·
463928 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(pkss->szUserIDAuth));
80a3a6 ¤   ¤   ¤   }
c2af5a
985abc ¤   ¤   ¤   sSetOneKSItem (hWndTree, pkss);·
720fe4 ¤   ¤   }
de9371 ¤   }
bcaf5a
030793 ¤   if (keysetMain == NULL)
e38346 ¤   ¤   PGPFreeKeySet (keyset);
d1af5a
640a66 ¤   if (keyserverList) PGPDisposePrefData (PrefRef, keyserverList);
9faf5a
0a3e6b ¤   return 0;
5befe6 }
31af5a
45af5a
ba3fc0 //¤ _____________________________________________________
59465d //
e23e91 // ·add columns to treelist
dcaf5a
6d6c77 static BOOL·
da88d2 sAddColumns (HWND hWndTree, INT iWidth) {
a77894 ¤   TL_COLUMN tlc;
f4f61c ¤   CHAR sz[64];
b2af5a
ff7a7a ¤   TreeList_DeleteAllColumns (hWndTree);
80af5a
e743d5 ¤   tlc.mask = TLCF_FMT | TLCF_WIDTH | TLCF_TEXT |·
62d085 ¤   ¤   ¤   ¤   TLCF_SUBITEM | TLCF_DATATYPE | TLCF_DATAMAX |
2be832 ¤   ¤   ¤   ¤   TLCF_MOUSENOTIFY;
33def6 ¤   tlc.pszText = sz;
60af5a
f5fee9 ¤   tlc.iSubItem = 0;
4eb741 ¤   tlc.fmt = TLCFMT_LEFT;
b6737a ¤   tlc.iDataType = TLC_DATASTRING;
141e1f ¤   tlc.cx = iWidth - DOMAINLISTWIDTH - CHECKLISTWIDTH - 20;
b98305 ¤   tlc.bMouseNotify = FALSE;
75e445 ¤   LoadString (g_hInst, IDS_SERVER, sz, sizeof(sz));
0d6e63 ¤   TreeList_InsertColumn (hWndTree, 0, &tlc);
15af5a
dbc492 ¤   tlc.fmt = TLCFMT_IMAGE;
0e7ae7 ¤   tlc.iDataType = TLC_DATALONG;
8f11de ¤   tlc.cx = DOMAINLISTWIDTH;
d38305 ¤   tlc.bMouseNotify = FALSE;
c20a5d ¤   LoadString (g_hInst, IDS_DOMAIN, sz, sizeof(sz));
b14244 ¤   TreeList_InsertColumn (hWndTree, 1, &tlc);
ecaf5a
c7c492 ¤   tlc.fmt = TLCFMT_IMAGE;
7d7ae7 ¤   tlc.iDataType = TLC_DATALONG;
eef507 ¤   tlc.cx = CHECKLISTWIDTH;
a7f5c7 ¤   tlc.bMouseNotify = TRUE;
33af46 ¤   LoadString (g_hInst, IDS_LISTED, sz, sizeof(sz));
cb362d ¤   TreeList_InsertColumn (hWndTree, 2, &tlc);
79af5a
7fc2e7 ¤   return TRUE;
07efe6 }
--c0c8 000c59f9ca94011028e Page 5 of CLkspref.c
e0af5a
1aaf5a
df3fc0 //¤ _____________________________________________________
51465d //
9372b9 // ·create new treelist control for keyserver prefs
d4af5a
e38104 HWND
c76bd2 CLCreateKeyserverTreeList (
adca38 ¤   ¤   PGPPrefRef¤ ¤   PrefRef,·
93fb68 ¤   ¤   PGPContextRef¤  context,·
7cae5d ¤   ¤   HWND¤   ¤   ¤   hWndParent,
e811cc ¤   ¤   PGPKeySetRef¤   keysetMain)·
1dbb36 {
d35efa ¤   HBITMAP hBmp; ·····// handle to a bitmap
858b3d ¤   HDC hDC;
c707bf ¤   HWND hWndTree;
465bda ¤   RECT rc;
332b7e ¤   INT iy, iNumBits;
65a305 ¤   POINT pt;
67af5a
ec605e ¤   // Ensure that the common control DLL is loaded.
883500 ¤   InitCommonControls ();
d8af5a
f02593 ¤   // Ensure that the custom control DLL is loaded.
2728bd ¤   InitTreeListControl ();
98af5a
9bb809 ¤   // initialize flags
c1794a ¤   iSelectedType = IDX_NONE;
e50e1c ¤   bSelectedRoot = FALSE;
78af5a
ca1239 ¤   // create tree view window
629987 ¤   GetWindowRect (GetDlgItem (hWndParent, IDC_NEWKEYSERVER), &rc);
e2c5e0 ¤   pt.x = rc.left;
93f58a ¤   pt.y = rc.top;
e92c2b ¤   ScreenToClient (hWndParent, &pt);
f38b4c ¤   iy = pt.y - BUTTONOFFSETY;
2eaf5a
119130 ¤   GetClientRect (hWndParent, &rc);
19af5a
4fa80a ¤   hWndTree = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREELIST, "",
6663f8 ¤   ¤   ¤   WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_GROUP |
348f8e ¤   ¤   ¤   TLS_AUTOSCROLL | TLS_SINGLESELECT,
c9781f ¤   ¤   ¤   rc.left, rc.top, rc.right-rc.left, iy,
149238 ¤   ¤   ¤   hWndParent, (HMENU)IDC_KSTREELIST, g_hInst, NULL);
54af5a
4b5167 ¤   if (hWndTree == NULL) return NULL;
05af5a
fdacf4 ¤   // Initialize the tree view window.
e925bf ¤   // First create imagelist and load the appropriate bitmaps based on·
930bd4 ¤   // current display capabilities.
0c7f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
fd89fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
48e693 ¤   ReleaseDC (NULL, hDC);
02af5a
7f2be4 ¤   if (iNumBits <= 8) {
9ef519 ¤   ¤   hIml =¤ ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
276d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
57f227 ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4));
c41b54 ¤   ¤   ImageList_AddMasked (hIml, hBmp, RGB(255, 0, 255));
075c8d ¤   ¤   DeleteObject (hBmp);
c59371 ¤   }
e0665a ¤   else {
aa45c9 ¤   ¤   hIml =¤ ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
eb6d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
dbb58c ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24));
c01b54 ¤   ¤   ImageList_AddMasked (hIml, hBmp, RGB(255, 0, 255));
f75c8d ¤   ¤   DeleteObject (hBmp);
fe9371 ¤   }
55af5a
5c4110 ¤   // Associate the image list with the tree view control.
da872b ¤   TreeList_SetImageList (hWndTree, hIml);
c5359c ¤   sAddColumns (hWndTree, rc.right);
--23a2 000f16d6deb4011028e Page 6 of CLkspref.c
0c7c0e ¤   sFillTreeList (PrefRef, context, hWndTree, keysetMain);
91af5a
39fc89 ¤   return hWndTree;
86efe6 }
ffaf5a
f23fc0 //¤ _____________________________________________________
fc465d //
1113e1 // ·destroy treelist control for keyserver prefs
ecaf5a
a5e274 INT
db3a4a CLDestroyKeyserverTreeList (HWND hWndTree)·
a3bb36 {
d51418 ¤   HTLITEM¤¤   hTServer;
d2e418 ¤   TL_TREEITEM tlI;
33af5a
ab7098 ¤   // free all KEYSERVERSTRUCT structures
f50d90 ¤   hTServer = TreeList_GetFirstItem (hWndTree);
b06793 ¤   while (hTServer) {
679331 ¤   ¤   tlI.hItem = hTServer;
55f9f3 ¤   ¤   tlI.mask = TLIF_NEXTHANDLE | TLIF_PARAM;
64ce72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
7faf5a
db3ad9 ¤   ¤   clFree ((VOID*)(tlI.lParam));
6faf5a
d1aed1 ¤   ¤   hTServer = tlI.hItem;
509371 ¤   }
9aaf5a
6b756d ¤   // close treelist
186616 ¤   SendMessage (hWndTree, WM_CLOSE, 0, 0);
263e6b ¤   return 0;
ceefe6 }
a6af5a
293fc0 //¤ _____________________________________________________
db465d //
946aaf // ·check if specified server is already in list
03af5a
e467fb static BOOL
935f8c sIsThisServerAlreadyInList (PKEYSERVERSTRUCT pkssThis)
93bb36 {
a80911 ¤   TL_TREEITEM¤¤   ¤   tlI;
d7716c ¤   HTLITEM¤¤   ¤   ¤   hTServer;
09f090 ¤   INT¤¤   ¤   ¤   ¤   iServerCount;
664332 ¤   PKEYSERVERSTRUCT¤   pkss;
dfaf5a
e1f62a ¤   // count number of servers
32b5f1 ¤   iServerCount = 0;
db79b8 ¤   hTServer = TreeList_GetFirstItem (pkssThis->hWndTree);
d96793 ¤   while (hTServer) {
f80920 ¤   ¤   ++iServerCount;
349331 ¤   ¤   tlI.hItem = hTServer;
fde99e ¤   ¤   tlI.mask = TLIF_NEXTHANDLE;
9348f1 ¤   ¤   TreeList_GetItem (pkssThis->hWndTree, &tlI);
0aaed1 ¤   ¤   hTServer = tlI.hItem;
309371 ¤   }
4caf5a
8879b8 ¤   hTServer = TreeList_GetFirstItem (pkssThis->hWndTree);
766793 ¤   while (hTServer) {
5118b9 ¤   ¤   // get server structure
f99331 ¤   ¤   tlI.hItem = hTServer;
34660c ¤   ¤   tlI.mask = TLIF_PARAM | TLIF_NEXTHANDLE;
bd48f1 ¤   ¤   TreeList_GetItem (pkssThis->hWndTree, &tlI);
7caf5a
783c02 ¤   ¤   pkss = (PKEYSERVERSTRUCT)(tlI.lParam);
10af5a
7f3115 ¤   ¤   if (pkss != (PKEYSERVERSTRUCT)pkssThis->pOrigStruct) {
aca230 ¤   ¤   ¤   if (!lstrcmpi (pkss->szServer, pkssThis->szServer)) {
c1985b ¤   ¤   ¤   ¤   if (pkss->iType == pkssThis->iType) {
7b533c ¤   ¤   ¤   ¤   ¤   if (pkss->iPort == pkssThis->iPort) {
8880de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
ea1c89 ¤   ¤   ¤   ¤   ¤   }
632613 ¤   ¤   ¤   ¤   }
f1a3a6 ¤   ¤   ¤   }
--9484 0006b80f51a4011028e Page 7 of CLkspref.c
b50fe4 ¤   ¤   }
e6af5a
01af83 ¤   ¤   // step to next server
31aed1 ¤   ¤   hTServer = tlI.hItem;
7d9371 ¤   }
02af5a
08a230 ¤   return FALSE;
36efe6 }
0eaf5a
c73fc0 //¤ _____________________________________________________
08465d //
d5d7a4 // ·find out if there are any domain-less servers among those
4948e2 // ·which are not selected.
73af5a
9467fb static BOOL
7f793c sIsThisTheOnlyWorldServer (HWND hWndTree)
3fbb36 {
a2716c ¤   HTLITEM¤¤   ¤   ¤   hTServer;
640911 ¤   TL_TREEITEM¤¤   ¤   tlI;
cc4332 ¤   PKEYSERVERSTRUCT¤   pkss;
69af5a
719d63 ¤   // is the selected server a "world" server?
8862d4 ¤   tlI.hItem = hTSelected;
46638d ¤   tlI.mask = TLIF_PARAM;
c4c03e ¤   TreeList_GetItem (hWndTree, &tlI);
de63be ¤   pkss = (PKEYSERVERSTRUCT)tlI.lParam;
22af5a
11d8f0 ¤   // if server has a domain, then it's not a "world" server.
2550a9 ¤   if (pkss->szDomain[0])·
2b98aa ¤   ¤   return FALSE;
92af5a
2ef50d ¤   // interate through tree
f10d90 ¤   hTServer = TreeList_GetFirstItem (hWndTree);
c06793 ¤   while (hTServer) {
7faf5a
325e6d ¤   ¤   if (hTServer != hTSelected) {
924a74 ¤   ¤   ¤   // get keyserver structure
15a439 ¤   ¤   ¤   tlI.hItem = hTServer;
58fbda ¤   ¤   ¤   tlI.mask = TLIF_PARAM;
7f5fea ¤   ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
5caf5a
30379b ¤   ¤   ¤   pkss = (PKEYSERVERSTRUCT)tlI.lParam;
f2af5a
1fe046 ¤   ¤   ¤   // if this server doesn't have a domain, then the
77e1d3 ¤   ¤   ¤   // selected server isn't the last "world" server
f04d00 ¤   ¤   ¤   if (pkss->szDomain[0] == 0)
d5d64b ¤   ¤   ¤   ¤   return FALSE;
170fe4 ¤   ¤   }
90af5a
7439d3 ¤   ¤   // get next server
6e9331 ¤   ¤   tlI.hItem = hTServer;
d2e99e ¤   ¤   tlI.mask = TLIF_NEXTHANDLE;
5cce72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
62af5a
9caed1 ¤   ¤   hTServer = tlI.hItem;
889371 ¤   }
1b67c5 ¤
060dd8 ¤   // didn't find any other "world" servers
6bc2e7 ¤   return TRUE;
a9efe6 }
a6af5a
38a3c6 //¤ ___________________________________________
66465d //
362016 // ·New/Edit Keyserver Dialog Message procedure
9baf5a
d83f64 static BOOL CALLBACK·
faba20 sEditServerDlgProc (
c23a3a ¤   ¤   HWND¤   hDlg,·
81eb77 ¤   ¤   UINT¤   uMsg,·
d20303 ¤   ¤   WPARAM¤ wParam,
aac0b8 ¤   ¤   LPARAM¤ lParam)·
6bbb36 {
--748f 0006602b9c34011028e Page 8 of CLkspref.c
654332 ¤   PKEYSERVERSTRUCT¤   pkss;
74b697 ¤   CHAR¤   ¤   ¤   ¤   sz[256];
905c90 ¤   LPSTR¤  ¤   ¤   ¤   p;
27b280 ¤   INT¤¤   ¤   ¤   ¤   i, iSelected;
19af5a
42347f ¤   switch (uMsg) {
2aaf5a
44ad3a ¤   case WM_INITDIALOG :
017547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
3f1aa3 ¤   ¤   pkss = (PKEYSERVERSTRUCT)lParam;
ad0008 ¤   ¤   if (pkss->bEdit) {
cdefde ¤   ¤   ¤   LoadString (g_hInst, IDS_EDITSERVERTITLE, sz, sizeof(sz));
c8964a ¤   ¤   ¤   SetWindowText (hDlg, sz);
fe0fe4 ¤   ¤   }
e9af5a
06c862 ¤   ¤   // load protocol combo box
08eb36 ¤   ¤   LoadString (g_hInst, IDS_LDAP, sz, sizeof(sz));
47a2a5 ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_ADDSTRING,·
32d191 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)sz);
efbc84 ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_SETITEMDATA,·
60f4e5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   i, (LPARAM)kPGPKeyServerType_LDAP);
6ff79f ¤   ¤   if (pkss->iType == kPGPKeyServerType_LDAP) iSelected = i;
8d1b52 ¤   ¤
aed0b5 ¤   ¤   LoadString (g_hInst, IDS_LDAPS, sz, sizeof(sz));
a5a2a5 ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_ADDSTRING,·
4dd191 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)sz);
debc84 ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_SETITEMDATA,·
6e06b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   i, (LPARAM)kPGPKeyServerType_LDAPS);
f289d7 ¤   ¤   if (pkss->iType == kPGPKeyServerType_LDAPS) iSelected = i;
c61b52 ¤   ¤
e49d65 ¤   ¤   LoadString (g_hInst, IDS_HTTP, sz, sizeof(sz));
e5a2a5 ¤   ¤   i = SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_ADDSTRING,·
08d191 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)sz);
40bc84 ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_SETITEMDATA,·
6a4b37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   i, (LPARAM)kPGPKeyServerType_HTTP);
6a05d4 ¤   ¤   if (pkss->iType == kPGPKeyServerType_HTTP) iSelected = i;
adaf5a
46e617 ¤   ¤   // initialize protocol combo box
f98d57 ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_SETCURSEL, iSelected, 0);
ffaf5a
257995 ¤   ¤   // initialize server name
a3a725 ¤   ¤   SetDlgItemText (hDlg, IDC_SERVERNAME, pkss->szServer);
31af5a
a7f676 ¤   ¤   // initialize port number
e74bd2 ¤   ¤   if (pkss->iPort != 0)
00f482 ¤   ¤   ¤   SetDlgItemInt (hDlg, IDC_PORT, pkss->iPort, FALSE);
94af5a
9faf5a
fedee8 ¤   ¤   // initialize authentication key name
03b268 ¤   ¤   SetDlgItemText (hDlg, IDC_SERVERKEY, pkss->szUserIDAuth);
d5af5a
986826 ¤   ¤   // initialize domain buttons
c3c0f7 ¤   ¤   if (pkss->szDomain[0]) {
064172 ¤   ¤   ¤   CheckRadioButton (hDlg, IDC_ANYDOMAIN, IDC_SPECIFIEDDOMAIN,
749d6e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_SPECIFIEDDOMAIN);
146bc6 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_DOMAIN, pkss->szDomain);
e90fe4 ¤   ¤   }
d507e0 ¤   ¤   else {
354172 ¤   ¤   ¤   CheckRadioButton (hDlg, IDC_ANYDOMAIN, IDC_SPECIFIEDDOMAIN,
fd677f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_ANYDOMAIN);
ee952f ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_DOMAIN, "");
e146ec ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN), FALSE);
e10fe4 ¤   ¤   }
3caf5a
6f0c0d ¤   ¤   // initialize checkboxes
f29962 ¤   ¤   if (pkss->bListed)·
2e1d9f ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_LISTED, BST_CHECKED);
c90e1d ¤   ¤   else
808df5 ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_LISTED, BST_UNCHECKED);
df87c7 ¤   ¤   ¤
4d87de ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_SERVERNAME));
66836c ¤   ¤   return TRUE;
--2014 000d2e3f5074011028e Page 9 of CLkspref.c
e0af5a
f18a25 ¤   case WM_HELP:·
e0fb42 ¤   ····WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
0ad0c3 ¤   ········HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
7a7d53 ¤   ····break;·
35af5a
3baf40 ¤   case WM_CONTEXTMENU:·
ab082b ¤   ¤   WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
3e9517 ¤   ¤   ····(DWORD) (LPVOID) aIds);·
4dca2d ¤   ¤   break;·
a0af5a
8ed1d3 ¤   case WM_COMMAND :
4a379d ¤   ¤   switch(LOWORD (wParam)) {
c1af5a
55461c ¤   ¤   case IDC_ANYDOMAIN :
0c46ec ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN), FALSE);
6dcdcb ¤   ¤   ¤   break;
34af5a
a64b39 ¤   ¤   case IDC_SPECIFIEDDOMAIN :
c40106 ¤   ¤   ¤   pkss = (PKEYSERVERSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
273fd9 ¤   ¤   ¤   if ((pkss->bEdit) &&
471051 ¤   ¤   ¤   ¤   (sIsThisTheOnlyWorldServer (pkss->hWndTree)))·
d7f776 ¤   ¤   ¤   {
0c5601 ¤   ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_PROPCAPTION,·
499a9e ¤   ¤   ¤   ¤   ¤   IDS_MUSTHAVEDEFAULTSERVER, MB_OK|MB_ICONEXCLAMATION);
0e5a7b ¤   ¤   ¤   ¤   CheckRadioButton (hDlg, IDC_ANYDOMAIN, IDC_SPECIFIEDDOMAIN,
59f13e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_ANYDOMAIN);
9fa3a6 ¤   ¤   ¤   }
986b93 ¤   ¤   ¤   else·
b77205 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN), TRUE);
adcdcb ¤   ¤   ¤   break;
fcaf5a
1e8c29 ¤   ¤   case IDOK :
9b0106 ¤   ¤   ¤   pkss = (PKEYSERVERSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
102b85 ¤   ¤   ¤   ¤
2a3b9b ¤   ¤   ¤   // get protocol
370b1b ¤   ¤   ¤   iSelected =·
ce0d2a ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_GETCURSEL, 0, 0);
633476 ¤   ¤   ¤   pkss->iType =·
1f14d9 ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROTOCOL, CB_GETITEMDATA,·
dfd28f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iSelected, 0);
99af5a
992ac9 ¤   ¤   ¤   // get server name
441bfa ¤   ¤   ¤   if (!GetDlgItemText (hDlg, IDC_SERVERNAME, sz, sizeof (sz))) {
89ba67 ¤   ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_PROPCAPTION, IDS_NOSERVERNAME,
70dd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
7966a9 ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_SERVERNAME));
7606e0 ¤   ¤   ¤   ¤   return TRUE;
57a3a6 ¤   ¤   ¤   }
a2e543 ¤   ¤   ¤   else {
afd8d3 ¤   ¤   ¤   ¤   // make sure user didn't type in prefix
05fb5f ¤   ¤   ¤   ¤   p = strstr (sz, "//");
a3c865 ¤   ¤   ¤   ¤   if (!p) p = strstr (sz, "\\\\");
1476b6 ¤   ¤   ¤   ¤   if (p) p += 2;
363c41 ¤   ¤   ¤   ¤   else p = &sz[0];
1072c1 ¤   ¤   ¤   ¤   lstrcpy (pkss->szServer, p);
d5a3a6 ¤   ¤   ¤   }
d4af5a
98a52a ¤   ¤   ¤   // get port number
62eb69 ¤   ¤   ¤   pkss->iPort = GetDlgItemInt (hDlg, IDC_PORT, NULL, FALSE);
efaf5a
b5fcc8 ¤   ¤   ¤   // get domain name
69011c ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_SPECIFIEDDOMAIN)) {
9fb7db ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_DOMAIN, pkss->szDomain,·
f89131 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof (pkss->szDomain));
b5a3a6 ¤   ¤   ¤   }
f16b93 ¤   ¤   ¤   else·
38e8e4 ¤   ¤   ¤   ¤   pkss->szDomain[0] = '\0';
8caf5a
6935f2 ¤   ¤   ¤   // get checkbox states¤ ¤   ¤
36303f ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_LISTED) == BST_CHECKED)·
d28aef ¤   ¤   ¤   ¤   pkss->bListed = TRUE;
--eb56 00002d952fe4011028e Page 10 of CLkspref.c
5f6b93 ¤   ¤   ¤   else·
7f2e30 ¤   ¤   ¤   ¤   pkss->bListed = FALSE;
e0af5a
c64cbd ¤   ¤   ¤   if (sIsThisServerAlreadyInList (pkss)) {
948f59 ¤   ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_PROPCAPTION, IDS_DUPLICATESERVER,
fcdd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
4f66a9 ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_SERVERNAME));
9806e0 ¤   ¤   ¤   ¤   return TRUE;
c8a3a6 ¤   ¤   ¤   }
a8af5a
28f3d5 ¤   ¤   ¤   EndDialog (hDlg, 1);
8ccdcb ¤   ¤   ¤   break;
63af5a
1871eb ¤   ¤   case IDCANCEL:
70ef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
dbcdcb ¤   ¤   ¤   break;
e00fe4 ¤   ¤   }
b1836c ¤   ¤   return TRUE;
059371 ¤   }
eda230 ¤   return FALSE;
e9efe6 }
c1af5a
e93fc0 //¤ _____________________________________________________
3d465d //
b57c93 // ·set all text to non-bold
24af5a
a0e6b2 static VOID
148c71 sRemoveAllRoots (HWND hWndTree)·
d2bb36 {
9a716c ¤   HTLITEM¤¤   ¤   ¤   hTServer;
6f0911 ¤   TL_TREEITEM¤¤   ¤   tlI;
ec4332 ¤   PKEYSERVERSTRUCT¤   pkss;
1daf5a
7bf50d ¤   // interate through tree
a20d90 ¤   hTServer = TreeList_GetFirstItem (hWndTree);
226793 ¤   while (hTServer) {
e3d57f ¤   ¤   // get current state
1c9331 ¤   ¤   tlI.hItem = hTServer;
60a729 ¤   ¤   tlI.mask = TLIF_STATE | TLIF_PARAM;
53ce72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
61af5a
f3be37 ¤   ¤   // make non-root
f06506 ¤   ¤   pkss = (PKEYSERVERSTRUCT)tlI.lParam;
b91eeb ¤   ¤   pkss->bRoot = FALSE;
fdaf5a
faed2d ¤   ¤   // remove "bold" property
5ab723 ¤   ¤   tlI.state &= ~TLIS_BOLD;
ca4415 ¤   ¤   tlI.stateMask = TLIS_BOLD;
2556cd ¤   ¤   TreeList_SetItem (hWndTree, &tlI);
19af5a
6af7c8 ¤   ¤   // get next item
509331 ¤   ¤   tlI.hItem = hTServer;
cfe99e ¤   ¤   tlI.mask = TLIF_NEXTHANDLE;
14ce72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
85af5a
32aed1 ¤   ¤   hTServer = tlI.hItem;
229371 ¤   }
94efe6 }
ebaf5a
433fc0 //¤ _____________________________________________________
06465d //
27929d // ·create new keyserver and add to treelist
31af5a
bbe274 INT
5af26e CLNewKeyserver (HWND hWndParent, HWND hWndTree)
1ebb36 {
27db4c ¤   PKEYSERVERSTRUCT pkss;
20af5a
7f3db0 ¤   pkss = (PKEYSERVERSTRUCT)clAlloc (sizeof(KEYSERVERSTRUCT));
dfa276 ¤   if (!pkss) return 1;
82af5a
02e1a7 ¤   pkss->hWndTree = hWndTree;
--6712 000e1ad2fd64011028e Page 11 of CLkspref.c
cca8b4 ¤   pkss->bEdit = FALSE;
71af5a
22ccf5 ¤   pkss->szServer[0] = '\0';
682d31 ¤   pkss->iPort = 0;
e9d948 ¤   pkss->iType = kPGPKeyServerType_LDAP;
854369 ¤   LoadString (g_hInst, IDS_UNKNOWNKEY, pkss->szUserIDAuth,·
5b0500 ¤   ¤   ¤   ¤   ¤   sizeof(pkss->szUserIDAuth));
050c71 ¤   pkss->szDomain[0] = '\0';
91dbc0 ¤   pkss->bListed = TRUE;
032ab6 ¤   pkss->bRoot = FALSE;
20a727 ¤   pkss->authAlg = kPGPPublicKeyAlgorithm_Invalid;
052f8e ¤   pkss->pOrigStruct = NULL;
46af5a
a1176a ¤   if (!DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_NEWSERVER), hWndParent,·
99fd59 ¤   ¤   ¤   ¤   sEditServerDlgProc, (LPARAM)pkss)) {
8dbf08 ¤   ¤   clFree (pkss);
efa04f ¤   ¤   SetFocus (hWndTree);
5ebbde ¤   ¤   return 0;
b19371 ¤   }
8baf5a
a559e9 ¤   sSetOneKSItem (hWndTree, pkss);·
2853e2 ¤   InvalidateRect (hWndTree, NULL, TRUE);
0daf5a
bb4eb2 ¤   ++uNumberOfServers;
88af5a
c8c7b1 ¤   EnableWindow (GetDlgItem (hWndParent, IDC_REMOVEKEYSERVER),·
a0f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
5b9318 ¤   EnableWindow (GetDlgItem (hWndParent, IDC_EDITKEYSERVER),
eaf481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
89bee4 ¤   EnableWindow (GetDlgItem (hWndParent, IDC_SETASROOT),
23f481 ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
d1af5a
863e6b ¤   return 0;
30efe6 }
0baf5a
f13fc0 //¤ _____________________________________________________
2b465d //
fed311 // ·edit existing keyserver params
1aaf5a
3bfe80 VOID
216bce CLEditKeyserver (HWND hWndParent, HWND hWndTree)
11bb36 {
500911 ¤   TL_TREEITEM¤¤   ¤   tlI;
fbb276 ¤   TL_LISTITEM¤¤   ¤   tlL;
af37b6 ¤   KEYSERVERSTRUCT¤¤   kss;
594332 ¤   PKEYSERVERSTRUCT¤   pkss;
7ab697 ¤   CHAR¤   ¤   ¤   ¤   sz[256];
fdaf5a
0b6de0 ¤   // get server struct
ce62d4 ¤   tlI.hItem = hTSelected;
32638d ¤   tlI.mask = TLIF_PARAM;
a3c03e ¤   TreeList_GetItem (hWndTree, &tlI);
cbaf5a
e263be ¤   pkss = (PKEYSERVERSTRUCT)tlI.lParam;
1ceb3b ¤   memcpy (&kss, pkss, sizeof(KEYSERVERSTRUCT));
4169fb ¤   kss.bEdit = TRUE;
3661fa ¤   kss.pOrigStruct = (VOID*)pkss;
f8af5a
8bf9f0 ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_NEWSERVER), hWndParent,·
574137 ¤   ¤   sEditServerDlgProc, (LPARAM)&kss)) {
e7af5a
63f34f ¤   ¤   memcpy (pkss, &kss, sizeof(KEYSERVERSTRUCT));
aeaf5a
331763 ¤   ¤   sURLfromInfo (pkss->iType, pkss->szServer, pkss->iPort, sz);
8ef28b ¤   ¤   pkss->authAlg = kPGPPublicKeyAlgorithm_Invalid;
6faf5a
309332 ¤   ¤   // insert new server text into treelist
28cf8a ¤   ¤   tlI.hItem = hTSelected;
5829d7 ¤   ¤   tlI.mask = TLIF_TEXT | TLIF_STATE;
c14415 ¤   ¤   tlI.stateMask = TLIS_BOLD;
c45a3d ¤   ¤   if (pkss->bRoot)·
e1a146 ¤   ¤   ¤   tlI.state = TLIS_BOLD;
--e1b3 000202de14f4011028e Page 12 of CLkspref.c
040e1d ¤   ¤   else
6780a5 ¤   ¤   ¤   tlI.state = 0;
f9c6a3 ¤   ¤   tlI.cchTextMax = lstrlen (sz);
9f16b7 ¤   ¤   tlI.pszText = sz;
ea56cd ¤   ¤   TreeList_SetItem (hWndTree, &tlI);
c9af5a
8b2777 ¤   ¤   // set new domain text
35d381 ¤   ¤   tlL.hItem = hTSelected;
fc6127 ¤   ¤   tlL.mask = TLIF_TEXT;
12ca06 ¤   ¤   tlL.iSubItem = 1;
c321e2 ¤   ¤   tlL.cchTextMax = lstrlen (pkss->szDomain);
e40999 ¤   ¤   if (tlL.cchTextMax)
2f489e ¤   ¤   ¤   tlL.pszText = pkss->szDomain;
a90e1d ¤   ¤   else
4a743e ¤   ¤   ¤   tlL.pszText = NULL;
2823bc ¤   ¤   TreeList_SetListItem (hWndTree, &tlL, FALSE);
abaf5a
8d71d2 ¤   ¤   // set listed state
b0d381 ¤   ¤   tlL.hItem = hTSelected;
d7f20b ¤   ¤   tlL.mask = TLIF_DATAVALUE;
132562 ¤   ¤   tlL.iSubItem = 2;
84fee2 ¤   ¤   if (pkss->bListed) tlL.lDataValue = IDX_CHECKED;
913d22 ¤   ¤   else tlL.lDataValue = IDX_UNCHECKED;
7e23bc ¤   ¤   TreeList_SetListItem (hWndTree, &tlL, FALSE);
b39371 ¤   }
a5af5a
4a9412 ¤   SetFocus (hWndTree);
5aefe6 }
06af5a
133fc0 //¤ _____________________________________________________
35465d //
d5554c // ·remove selected keyserver from treelist
7caf5a
0afe80 VOID
40fe3a CLRemoveKeyserver (HWND hWndParent, HWND hWndTree)
cebb36 {
ddca7f ¤   CHAR sz0[256];
ac4bc0 ¤   CHAR sz1[256];
fbc110 ¤   CHAR sz2[256];
48e418 ¤   TL_TREEITEM tlI;
fbfd72 ¤   HTLITEM hTParent;
aeaf5a
227287 ¤   if (sIsThisTheOnlyWorldServer (hWndTree)) {
053e6a ¤   ¤   PGPclMessageBox (hWndParent, IDS_PROPCAPTION,·
ed8c28 ¤   ¤   ¤   ¤   IDS_MUSTHAVEDEFAULTSERVER, MB_OK|MB_ICONEXCLAMATION);
8a99bf ¤   ¤   return;
f59371 ¤   }
acaf5a
6762d4 ¤   tlI.hItem = hTSelected;
9a1b7a ¤   tlI.mask = TLIF_TEXT | TLIF_PARAM;
bc5099 ¤   tlI.pszText = sz1;
bd4430 ¤   tlI.cchTextMax = sizeof(sz1);
10c03e ¤   TreeList_GetItem (hWndTree, &tlI);
3f5990 ¤   hTParent = tlI.hItem;
ecaf5a
819ffc ¤   LoadString (g_hInst, IDS_DELKSPROMPT, sz0, sizeof(sz0));
15e97a ¤   wsprintf (sz2, sz0, sz1);
15af5a
2fb5cc ¤   LoadString (g_hInst, IDS_PROPCAPTION, sz1, sizeof(sz1));
37ce6f ¤   if (MessageBox (hWndParent, sz2, sz1,·
905475 ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDYES) {
a2af5a
34b699 ¤   ¤   // free KEYSERVERSTRUCT
5c3ad9 ¤   ¤   clFree ((VOID*)(tlI.lParam));
7daf5a
09ee40 ¤   ¤   // delete selected item
61cf8a ¤   ¤   tlI.hItem = hTSelected;
1057d4 ¤   ¤   TreeList_DeleteItem (hWndTree, &tlI);
eeaf5a
44a1e7 ¤   ¤   hTSelected = NULL;
654e42 ¤   ¤   iSelectedType = IDX_NONE;
201a34 ¤   ¤   bSelectedRoot = FALSE;
--ddf9 000f85bc2394011028e Page 13 of CLkspref.c
e0af5a
625e59 ¤   ¤   // finish up
52c27a ¤   ¤   InvalidateRect (hWndTree, NULL, TRUE);
0f4df4 ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_REMOVEKEYSERVER),·
be7f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
132f01 ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_EDITKEYSERVER),
4c7f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
c15ce4 ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_SETASROOT),
387f7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
6f1884 ¤   ¤   --uNumberOfServers;
739371 ¤   }
834264 ¤   else·
01a04f ¤   ¤   SetFocus (hWndTree);
b0efe6 }
acaf5a
e0af5a
e33fc0 //¤ _____________________________________________________
3a465d //
5deb70 // ·set selected server as root server
25af5a
7bfe80 VOID
be08a1 CLSetKeyserverAsRoot (HWND hWndParent, HWND hWndTree)
b7bb36 {
7a0911 ¤   TL_TREEITEM¤¤   ¤   tlI;
4b4332 ¤   PKEYSERVERSTRUCT¤   pkss;
91af5a
4c7a54 ¤   sRemoveAllRoots (hWndTree);
88af5a
2d62d4 ¤   tlI.hItem = hTSelected;
00638d ¤   tlI.mask = TLIF_PARAM;
c4c03e ¤   TreeList_GetItem (hWndTree, &tlI);
3063be ¤   pkss = (PKEYSERVERSTRUCT)tlI.lParam;
33af5a
632cab ¤   pkss->bRoot = TRUE;
abaf5a
ff62d4 ¤   tlI.hItem = hTSelected;
62c86a ¤   tlI.stateMask = TLIS_BOLD;
293911 ¤   tlI.state = TLIS_BOLD;
e95f6c ¤   tlI.mask = TLIF_STATE;
405881 ¤   TreeList_SetItem (hWndTree, &tlI);
33af5a
29aacf ¤   EnableWindow (GetDlgItem (hWndParent, IDC_SETASROOT), FALSE);
b09412 ¤   SetFocus (hWndTree);
b8efe6 }
5daf5a
31af5a
1d3fc0 //¤ _____________________________________________________
b5465d //
dc94ae // ·process treelist notification
1caf5a
76e6b2 static VOID
b2fea8 sServerContextMenu (HWND hwnd, INT iX, INT iY)
9fbb36 {
18a46f ¤   HMENU¤  hMC;
8ecad4 ¤   HMENU¤  hMenuTrackPopup;
035c98 #if PGP_DEBUG
839da3 ¤   BOOL¤   bControl;
f1af5a
6a7dde ¤   /// <ctrl> key allows removing last keyserver (for testing purposes)
932ab0 ¤   if (GetKeyState (VK_CONTROL) & 0x80000000)
6bf1ad ¤   ¤   bControl = TRUE;
990e24 ¤   else
014f5d ¤   ¤   bControl = FALSE;
170a26 #endif PGP_DEBUG
4caf5a
87bc72 ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUEDITSERVER));
ea1c53 ¤   if (iSelectedType == IDX_SERVER) {
b05c98 #if PGP_DEBUG
a5673e ¤   ¤   if (uNumberOfServers > 1 || bControl)
bcdb21 #else
c99eb8 ¤   ¤   if (uNumberOfServers > 1)
f87454 #endif
--d77e 000851d36294011028e Page 14 of CLkspref.c
2ab20f ¤   ¤   ¤   EnableMenuItem (hMC, IDM_REMOVESERVER, MF_BYCOMMAND|MF_ENABLED);
420e1d ¤   ¤   else
71197e ¤   ¤   ¤   EnableMenuItem (hMC, IDM_REMOVESERVER, MF_BYCOMMAND|MF_GRAYED);
65af5a
42b521 ¤   ¤   EnableMenuItem (hMC, IDM_EDITSERVER, MF_BYCOMMAND|MF_ENABLED);
0f9371 ¤   }
8f665a ¤   else {
f10277 ¤   ¤   EnableMenuItem (hMC, IDM_REMOVESERVER, MF_BYCOMMAND|MF_GRAYED);
d20f09 ¤   ¤   EnableMenuItem (hMC, IDM_EDITSERVER, MF_BYCOMMAND|MF_GRAYED);
239371 ¤   }
67af5a
c8381e ¤   if (bSelectedRoot)
ae1798 ¤   ¤   EnableMenuItem (hMC, IDM_SETASROOT, MF_BYCOMMAND|MF_GRAYED);
630e24 ¤   else
d53039 ¤   ¤   EnableMenuItem (hMC, IDM_SETASROOT, MF_BYCOMMAND|MF_ENABLED);
ddaf5a
937e92 ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
55af5a
1b966f ¤   TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
d612d7 ¤   ¤   ¤   ¤   ¤   iX, iY, 0, hwnd, NULL);
d2af5a
e885ee ¤   DestroyMenu (hMC);
9befe6 }
74af5a
d03fc0 //¤ _____________________________________________________
5f465d //
b894ae // ·process treelist notification
3aaf5a
10e274 INT
ce507c CLProcessKeyserverTreeList (HWND hWndParent, HWND hWndTree,·
fb8129 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam, LPARAM lParam)
f4bb36 {
dc0911 ¤   TL_TREEITEM¤¤   ¤   tlI;
dcb276 ¤   TL_LISTITEM¤¤   ¤   tlL;
a58a39 ¤   BOOL¤   ¤   ¤   ¤   bEnable;
124332 ¤   PKEYSERVERSTRUCT¤   pkss;
b1af5a
050600 ¤   switch (((LPNM_TREELIST)lParam)->hdr.code) {
81af5a
1c39a9 ¤   case TLN_SELCHANGED :
d2b509 ¤   ¤   hTSelected = ((LPNM_TREELIST)lParam)->itemNew.hItem;
f5af5a
26ac0f ¤   ¤   if (!hTSelected) {
24a131 ¤   ¤   ¤   iSelectedType = IDX_NONE;
ba964b ¤   ¤   ¤   bSelectedRoot = FALSE;
873a22 ¤   ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_EDITKEYSERVER),
84ba28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
044a82 ¤   ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_REMOVEKEYSERVER),·
9eba28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
1d09c6 ¤   ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_SETASROOT),·
31ba28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
0fcdcb ¤   ¤   ¤   break;
fe0fe4 ¤   ¤   }
83af5a
f9cf8a ¤   ¤   tlI.hItem = hTSelected;
4e17a2 ¤   ¤   tlI.mask = TLIF_IMAGE | TLIF_STATE;
3ace72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
6c2f3a ¤   ¤   iSelectedType = tlI.iImage;
68d7b1 ¤   ¤   bSelectedRoot = tlI.state & TLIS_BOLD;
b367c5 ¤
d75513 ¤   ¤   switch (iSelectedType) {
0ef704 ¤   ¤   case IDX_SERVER :
0f3a22 ¤   ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_EDITKEYSERVER),
f75c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
88af5a
0d71cb ¤   ¤   ¤   if (uNumberOfServers > 1)
170b51 ¤   ¤   ¤   ¤   bEnable = TRUE;
506b93 ¤   ¤   ¤   else·
b47244 ¤   ¤   ¤   ¤   bEnable = FALSE;
044a82 ¤   ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_REMOVEKEYSERVER),·
789c1c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEnable);
85af5a
--c426 0001a164f324011028e Page 15 of CLkspref.c
abced7 ¤   ¤   ¤   if (bSelectedRoot)
2e7244 ¤   ¤   ¤   ¤   bEnable = FALSE;
e9bb8c ¤   ¤   ¤   else
be0b51 ¤   ¤   ¤   ¤   bEnable = TRUE;
e37d72 ¤   ¤   ¤   EnableWindow (GetDlgItem (hWndParent, IDC_SETASROOT), bEnable);
a8af5a
17cdcb ¤   ¤   ¤   break;
fd0fe4 ¤   ¤   }
e22f68 ¤   ¤   break;
61af5a
1b4a71 ¤   case TLN_LISTITEMCLICKED :·
82cf8a ¤   ¤   tlI.hItem = hTSelected;
b777a5 ¤   ¤   tlI.mask = TLIF_PARAM;
0cce72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
3faf5a
583c02 ¤   ¤   pkss = (PKEYSERVERSTRUCT)(tlI.lParam);
dc699a ¤   ¤   pkss->bListed = !pkss->bListed;
1faf5a
37d381 ¤   ¤   tlL.hItem = hTSelected;
fc2562 ¤   ¤   tlL.iSubItem = 2;
2af20b ¤   ¤   tlL.mask = TLIF_DATAVALUE;
6faf5a
0f9962 ¤   ¤   if (pkss->bListed)·
230cf8 ¤   ¤   ¤   tlL.lDataValue = IDX_CHECKED;
14ee26 ¤   ¤   else·
a7fc2a ¤   ¤   ¤   tlL.lDataValue = IDX_UNCHECKED;
efaf5a
e123bc ¤   ¤   TreeList_SetListItem (hWndTree, &tlL, FALSE);
092f68 ¤   ¤   break;
2eaf5a
08206f ¤   case TLN_CONTEXTMENU :
e10f36 ¤   ¤   sServerContextMenu (hWndParent,
1fcaa3 ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.x,
8fb27d ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.y);
af2f68 ¤   ¤   break;
77af5a
979371 ¤   }
143e6b ¤   return 0;
edefe6 }
27af5a
e53fc0 //¤ _____________________________________________________
7e465d //
0b3316 // ·traverse treelist and save contents to preferences
cfaf5a
52e274 INT
fb1411 CLSaveKeyserverPrefs (PGPPrefRef PrefRef, HWND hWndParent, HWND hWndTree)
a1bb36 {
030911 ¤   TL_TREEITEM¤¤   ¤   tlI;
17716c ¤   HTLITEM¤¤   ¤   ¤   hTServer;
f7476b ¤   PGPKeyServerEntry*¤ keyserverList;
200b21 ¤   INT¤¤   ¤   ¤   ¤   iServer, iServerCount;
7b4332 ¤   PKEYSERVERSTRUCT¤   pkss;
a0af5a
4df62a ¤   // count number of servers
8ab5f1 ¤   iServerCount = 0;
cc0d90 ¤   hTServer = TreeList_GetFirstItem (hWndTree);
c36793 ¤   while (hTServer) {
f50920 ¤   ¤   ++iServerCount;
4b9331 ¤   ¤   tlI.hItem = hTServer;
64e99e ¤   ¤   tlI.mask = TLIF_NEXTHANDLE;
f2ce72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
28aed1 ¤   ¤   hTServer = tlI.hItem;
469371 ¤   }
daaf5a
aff177 ¤   keyserverList = clAlloc (iServerCount * sizeof(PGPKeyServerEntry));
c07706 ¤   if (!keyserverList) return kPGPError_OutOfMemory;
30af5a
292c44 ¤   iServer = 0;
ec0d90 ¤   hTServer = TreeList_GetFirstItem (hWndTree);
2a6793 ¤   while (hTServer) {
2a18b9 ¤   ¤   // get server structure
1a9331 ¤   ¤   tlI.hItem = hTServer;
--5340 001cbe7ac174011028e Page 16 of CLkspref.c
3f660c ¤   ¤   tlI.mask = TLIF_PARAM | TLIF_NEXTHANDLE;
08ce72 ¤   ¤   TreeList_GetItem (hWndTree, &tlI);
86af5a
ea3c02 ¤   ¤   pkss = (PKEYSERVERSTRUCT)(tlI.lParam);
65af5a
eada38 ¤   ¤   keyserverList[iServer].protocol = pkss->iType;
9575fa ¤   ¤   lstrcpy (keyserverList[iServer].domain, pkss->szDomain);
5d58a3 ¤   ¤   lstrcpy (keyserverList[iServer].serverDNS, pkss->szServer);
f7aaff ¤   ¤   keyserverList[iServer].serverPort = pkss->iPort;
a6af5a
3c7f46 ¤   ¤   // authentication key
22d0af ¤   ¤   if (pkss->authAlg != kPGPPublicKeyAlgorithm_Invalid) {
bc4ed8 ¤   ¤   ¤   keyserverList[iServer].authAlg = pkss->authAlg;
f3d289 ¤   ¤   ¤   lstrcpy (keyserverList[iServer].authKeyIDString,·
accce0 ¤   ¤   ¤   ¤   ¤   ¤   pkss->szKeyIDAuth);
520fe4 ¤   ¤   }
3607e0 ¤   ¤   else {
d15a8a ¤   ¤   ¤   keyserverList[iServer].authAlg = kPGPPublicKeyAlgorithm_Invalid;
079b1f ¤   ¤   ¤   keyserverList[iServer].authKeyIDString[0] = '\0';
450fe4 ¤   ¤   }
2daf5a
c6c363 ¤   ¤   // listed flag
971675 ¤   ¤   keyserverList[iServer].flags = 0;
d19962 ¤   ¤   if (pkss->bListed)·
b707ed ¤   ¤   ¤   keyserverList[iServer].flags |= kKeyServerListed;
a85a3d ¤   ¤   if (pkss->bRoot)·
65e7ce ¤   ¤   ¤   keyserverList[iServer].flags |= kKeyServerIsRoot;
a3af5a
afaf83 ¤   ¤   // step to next server
518dd2 ¤   ¤   ++iServer;
11aed1 ¤   ¤   hTServer = tlI.hItem;
469371 ¤   }
5baf5a
70fc96 ¤   // done, set preferences
a23244 ¤   PGPSetKeyServerPrefs (PrefRef, keyserverList, iServerCount);
d8af5a
ca290d ¤   clFree (keyserverList);
b5af5a
c63e6b ¤   return 0;
ccefe6 }
86af5a
cbaf5a
--144d 0007cebf8984011028f Page 1 of CLmisc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
370fc7 ¤   CLmisc.c - PGP ClientLib DLL miscellaneous routines
e467c5 ¤
ffaf5a
aebbe3 ¤   $Id: CLmisc.c,v 1.36 1998/08/11 14:43:10 pbj Exp $
4df7f7 ____________________________________________________________________________*/
048ad2 #include "pgpPFLConfig.h"¤
f7af5a
1ac917 // project header files
0c5fcd #include "pgpclx.h"
7c850a #include "pgpkmx.h"
27b782 #include "..\include\PGPversion.h"
59cbbd #include "..\include\PGPpk.h"
66af5a
b44b8d // constants
ab8698 #define TEXTXPOS¤   0.65
de8d39 #define TEXTYPOS¤   0.73
b7af5a
9bf0f7 typedef struct {
aa8a97 ¤   PGPContextRef¤  context;
792ecd ¤   LPSTR¤  ¤   ¤   pszRemoteHost;
5b43f7 ¤   PGPKeyRef¤  ¤   keyAuthenticating;
bf06b8 ¤   PGPKeySetRef¤   keysetMain;
f7d9ec ¤   CHAR¤   ¤   ¤   szName[kPGPMaxUserIDSize];
a04f5b ¤   UINT¤   ¤   ¤   uFlags;
baeb1b ¤   PGPValidity¤¤   validityThreshold;
d233b3 } CONFIRMAUTHSTRUCT, *PCONFIRMAUTHSTRUCT;
2aaf5a
8893ed // external globals
169cad extern HINSTANCE g_hInst;
dd0afe extern CHAR g_szHelpFile[MAX_PATH];
c3af5a
b3492e // local globals
ac0a84 static DWORD aIds[] = {¤¤   ¤   // Help IDs
2a3907 ····IDC_SERVERNAME,¤IDH_PGPCLMISC_AUTHSERVERNAME,·
c514b1 ····IDC_KEYNAME,¤   IDH_PGPCLMISC_AUTHKEYNAME,·
d26523 ····IDC_FINGERPRINT,IDH_PGPCLMISC_AUTHKEYFINGERPRINT,·
7c958e ····IDC_VALIDITY,¤  IDH_PGPCLMISC_AUTHKEYVALIDITY,·
fa07da ····IDC_IMPORTKEY,¤ IDH_PGPCLMISC_AUTHIMPORTKEY,·
abbeb2 ¤   IDOK,¤  ¤   ¤   IDH_PGPCLMISC_AUTHCONFIRM,
194434 ····0,0·
c7a6fe };·
b8af5a
fb4265 //¤ ___________________________________________________
00465d //
3adc61 //¤ Internal memory allocation routines
48465d //
28af5a
b2493a VOID*·
07732c clAlloc (UINT uBytes)·
afbb36 {
d12332 ¤   VOID* p;
2ca1e9 ¤   p = malloc (uBytes);
5af191 ¤   if (p) {
dc1217 ¤   ¤   memset (p, 0, uBytes);
6e9371 ¤   }
a4381d ¤   return p;
09efe6 }
1baf5a
0faf5a
82a1ba VOID·
aaeada clFree (VOID* p)·
a5bb36 {
5668fc ¤   if (p)
dede78 ¤   ¤   free (p);
71efe6 }
13af5a
ae4265 //¤ ___________________________________________________
7c465d //
--3f61 000bcb6bcb84011028f Page 2 of CLmisc.c
779a91 //¤ Message box routine using string table resource IDs
30af5a
fa0218 LRESULT·
5786aa PGPclMessageBox (
493172 ¤   ¤   ·HWND¤  hWnd,·
cb5442 ¤   ¤   ·INT¤   iCaption,·
da76b8 ¤   ¤   ·INT¤   iMessage,
152954 ¤   ¤   ·ULONG¤ ulFlags)·
08bb36 {
b501b5 ¤   CHAR szCaption [128];
717951 ¤   CHAR szMessage [256];
b3af5a
aac237 ¤   LoadString (g_hInst, iCaption, szCaption, sizeof(szCaption));
d07e8b ¤   LoadString (g_hInst, iMessage, szMessage, sizeof(szMessage));
f2af5a
8e897a ¤   ulFlags |= MB_SETFOREGROUND;
be729f ¤   return (MessageBox (hWnd, szMessage, szCaption, ulFlags));
1defe6 }
3faf5a
5b4265 //¤ ___________________________________________________
ca465d //
677cc2 //¤ convert SYSTEMTIME structure to number of days from today
03af5a
ddec6d PGPError PGPclExport
5087ca PGPclSystemTimeToDays (
0a600d ¤   ¤   ·SYSTEMTIME*¤   pst,·
af2473 ¤   ¤   ·INT*¤  ¤   ¤   piDays)·
acbb36 {
3f1ce4 ¤   SYSTEMTIME¤ stToday;
7baf70 ¤   struct tm¤  tmstruct;
b02a88 ¤   time_t¤ ¤   timeToday;
60ddbc ¤   time_t¤ ¤   timeInQuestion;
47035c ¤   UINT¤   ¤   uDayToday;
8d79ab ¤   UINT¤   ¤   uDayInQuestion;
57af5a
2feeb3 ¤   pgpAssert (pst != NULL);
76601a ¤   pgpAssert (piDays != NULL);
34af5a
2a05ff ¤   *piDays = -1;
5eaf5a
56788f ¤   if (pst->wYear > 2037)·
f962b5 ¤   ¤   return kPGPError_BadParams;
64af5a
3de9e8 ¤   GetLocalTime (&stToday);
66af5a
e2a6d9 ¤   tmstruct.tm_mday = stToday.wDay;
1032f3 ¤   tmstruct.tm_mon = stToday.wMonth -1;
0df369 ¤   tmstruct.tm_year = stToday.wYear -1900;
77f497 ¤   tmstruct.tm_hour = 12;
8168da ¤   tmstruct.tm_min = 0;
5c59b6 ¤   tmstruct.tm_sec = 0;
6d3c1d ¤   tmstruct.tm_isdst = -1;
4faf5a
fb759b ¤   timeToday = mktime (&tmstruct);
f7e68d ¤   if (timeToday == (time_t)-1) return kPGPError_BadParams;
38af5a
062939 ¤   tmstruct.tm_mday = pst->wDay;
608a11 ¤   tmstruct.tm_mon = pst->wMonth -1;
34a9f3 ¤   tmstruct.tm_year = pst->wYear -1900;
17f497 ¤   tmstruct.tm_hour = 12;
6b68da ¤   tmstruct.tm_min = 0;
7a59b6 ¤   tmstruct.tm_sec = 0;
ee3c1d ¤   tmstruct.tm_isdst = -1;
33af5a
f4650a ¤   timeInQuestion = mktime (&tmstruct);
00f1b2 ¤   if (timeInQuestion == (time_t)-1) return kPGPError_BadParams;
36af5a
474107 ¤   uDayToday = timeToday / 86400;·
df25d2 ¤   uDayInQuestion = timeInQuestion / 86400;·
98af5a
d0b8ec ¤   *piDays = uDayInQuestion - uDayToday;
bcaf5a
--79ab 00031b5b4be4011028f Page 3 of CLmisc.c
cd151e ¤   return kPGPError_NoErr;
00efe6 }
23af5a
7caf5a
bf4265 //¤ ___________________________________________________
77465d //
e2e5f7 //¤ create logical palette from bitmap color table
6daf5a
27597e static HPALETTE·
0d3928 sCreateDIBPalette (
904159 ¤   ¤   ··LPBITMAPINFO¤ lpbmi,·
683f42 ¤   ¤   ··LPINT¤¤   ¤   lpiNumColors)·
cebb36 {
beb04a ¤   LPBITMAPINFOHEADER¤ lpbi;
8fa52a ¤   LPLOGPALETTE¤   ¤   lpPal;
c3795c ¤   HANDLE¤ ¤   ¤   ¤   hLogPal;
a9bb8f ¤   HPALETTE¤   ¤   ¤   hPal = NULL;
4fb236 ¤   INT¤¤   ¤   ¤   ¤   i;
d9d83c ·
177407 ¤   lpbi = (LPBITMAPINFOHEADER)lpbmi;
07335b ¤   if (lpbi->biBitCount <= 8)
215406 ¤   ¤   *lpiNumColors = (1 << lpbi->biBitCount);
590e24 ¤   else
f221cc ¤   ¤   *lpiNumColors = 0; ·// No palette needed for 24 BPP DIB
58d83c ·
aff623 ¤   if (*lpiNumColors) {
500012 ¤   ¤   hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
e1440c ·····························sizeof (PALETTEENTRY) * (*lpiNumColors));
a3d92a ¤   ¤   lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
035442 ¤   ¤   lpPal->palVersion = 0x300;
db4b35 ¤   ¤   lpPal->palNumEntries = *lpiNumColors;
f4d83c ·
11a249 ¤   ¤   for (i = 0; ·i < *lpiNumColors; ·i++) {
54d118 ¤   ¤   ¤   lpPal->palPalEntry[i].peRed ··= lpbmi->bmiColors[i].rgbRed;
3fdc94 ¤   ¤   ¤   lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
891adf ¤   ¤   ¤   lpPal->palPalEntry[i].peBlue ·= lpbmi->bmiColors[i].rgbBlue;
44089b ¤   ¤   ¤   lpPal->palPalEntry[i].peFlags = 0;
f20fe4 ¤   ¤   }
ba898e ¤   ¤   hPal = CreatePalette (lpPal);
0b93f7 ¤   ¤   GlobalUnlock (hLogPal);
3db50d ¤   ¤   GlobalFree (hLogPal);
adb144 ···}
e0ef80 ···return hPal;
25efe6 }
90d83c ·
7c4265 //¤ ___________________________________________________
89465d //
f908c3 //¤ Load DIB bitmap and associated palette
7aaf5a
8b7a1f HBITMAP
0fbffd CLLoadResourceBitmap (
94ab83 ¤   ¤   HINSTANCE¤  ¤   hInstance,·
a07450 ¤   ¤   LPSTR¤  ¤   ¤   lpString,
1e758c ¤   ¤   HPALETTE FAR*¤  lphPalette)·
76bb36 {
c4646d ¤   HRSRC¤  ¤   ¤   ¤   hRsrc;
571755 ¤   HGLOBAL¤¤   ¤   ¤   hGlobal;
bbf49d ¤   HBITMAP¤¤   ¤   ¤   hBitmapFinal = NULL;
28b04a ¤   LPBITMAPINFOHEADER¤ lpbi;
d17de6 ¤   HDC¤¤   ¤   ¤   ¤   hdc;
d658f4 ····INT¤¤   ¤   ¤   ¤   iNumColors;
2fd83c ·
5ee2a3 ¤   if (hRsrc = FindResource (hInstance, lpString, RT_BITMAP)) {
ffaa39 ¤   ¤   hGlobal = LoadResource (hInstance, hRsrc);
a526b6 ¤   ¤   lpbi = (LPBITMAPINFOHEADER)LockResource (hGlobal);
b9d83c ·
d2002d ¤   ¤   hdc = GetDC(NULL);
d5c28e ¤   ¤   *lphPalette = ·sCreateDIBPalette ((LPBITMAPINFO)lpbi, &iNumColors);
f5c904 ¤   ¤   if (*lphPalette) {
845e33 ¤   ¤   ¤   SelectPalette (hdc,*lphPalette,FALSE);
c6703c ¤   ¤   ¤   RealizePalette (hdc);
310fe4 ¤   ¤   }
--9734 00045dd6bdb4011028f Page 4 of CLmisc.c
4bd83c ·
d0259d ¤   ¤   hBitmapFinal = CreateDIBitmap (hdc,
de14f2 ···················(LPBITMAPINFOHEADER)lpbi,
1ce478 ···················(LONG)CBM_INIT,
f1d8e7 ···················(LPSTR)lpbi + lpbi->biSize + iNumColors * sizeof(RGBQUAD),
aae564 ···················(LPBITMAPINFO)lpbi,
49a1a1 ···················DIB_RGB_COLORS );
77d83c ·
256078 ¤   ¤   ReleaseDC (NULL,hdc);
4266f7 ¤   ¤   UnlockResource (hGlobal);
171d90 ¤   ¤   FreeResource (hGlobal);
259371 ¤   }
f5aa7e ¤   return (hBitmapFinal);
6defe6 }
14d83c ·
72af5a
c04265 //¤ ___________________________________________________
72465d //
912df1 //¤ Paint user info and registration number·
a3af5a
6ed8e2 #define YTEXTINC¤   14
e9af5a
aaa1ba VOID·
a3b0c1 CLPaintUserInfo (
4c63c2 ¤   ¤   PGPMemoryMgrRef¤memMgr,
d4e0af ¤   ¤   HWND¤   ¤   ¤   hwnd,
5f401d ¤   ¤   HDC¤¤   ¤   ¤   hdc,·
739b10 ¤   ¤   LPSTR¤  ¤   ¤   pszVersion)
42bb36 {
46374a ¤   HFONT¤  ¤   hFontOld;
cba722 ¤   UINT¤   ¤   uTAOld;
eacdba ¤   CHAR¤   ¤   sz[256];
ea61e0 ¤   PGPError¤   err;
8b06a2 ¤   PGPPrefRef¤ PrefRef;
4e0079 ¤   RECT¤   ¤   rc;
20cbeb ¤   INT¤¤   ¤   iXpos, iYpos;
d4af5a
ad47d1 ¤   GetClientRect (hwnd, &rc);
a86a90 ¤   iXpos = (INT)(TEXTXPOS * rc.right);
8380d9 ¤   iYpos = (INT)(TEXTYPOS * rc.bottom);
4caf5a
a9cb27 ¤   SetTextColor (hdc, RGB (255, 255, 255));
fe9f77 ¤   SetBkMode (hdc, TRANSPARENT);
f17970 ¤   uTAOld = SetTextAlign (hdc, TA_LEFT);
0040d5 ¤   hFontOld = SelectObject (hdc, GetStockObject (DEFAULT_GUI_FONT));
b6af5a
f8d0c1 ¤   sz[0] = '\0';
2ebe29 #if PGP_BUSINESS_SECURITY
b71264 ¤   if (PGPclOpenAdminPrefs (memMgr, &PrefRef, FALSE) != kPGPError_NoErr)
6899bf ¤   ¤   return;
1b2377 ¤   err = PGPGetPrefStringBuffer (PrefRef, kPGPPrefAdminCompanyName,·
ffce55 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz);
e12a7a ¤   if (IsPGPError (err)) sz[0] = '\0';
01ed08 ¤   PGPclCloseAdminPrefs (PrefRef, FALSE);
517454 #endif
b8af5a
aac0d6 ¤   if (PGPclOpenClientPrefs (memMgr, &PrefRef) != kPGPError_NoErr)
c099bf ¤   ¤   return;
9caf5a
4d8d96 ¤   // company name
e40a92 ¤   if (sz[0] == '\0') {
779ca9 ¤   ¤   err = PGPGetPrefStringBuffer (PrefRef, kPGPPrefCompanyName,·
d9ce55 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz);
639371 ¤   }
982a7a ¤   if (IsPGPError (err)) sz[0] = '\0';
6bcb8b ¤   rc.left = iXpos;
ac6eee ¤   rc.right -= 4;
4a6c84 ¤   rc.top = iYpos + (2*YTEXTINC);
090d3f ¤   rc.bottom = rc.top + YTEXTINC;
095ecd ¤   DrawTextEx (hdc, sz, lstrlen (sz), &rc, DT_END_ELLIPSIS, NULL);
a5af5a
45139c ¤   // user name
--e203 00024cad4f64011028f Page 5 of CLmisc.c
d3d0c1 ¤   sz[0] = '\0';
b110ef ¤   err = PGPGetPrefStringBuffer (PrefRef, kPGPPrefOwnerName,·
59ce55 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz);
fb6273 ¤   rc.top = iYpos + (1*YTEXTINC);
c10d3f ¤   rc.bottom = rc.top + YTEXTINC;
6e5ecd ¤   DrawTextEx (hdc, sz, lstrlen (sz), &rc, DT_END_ELLIPSIS, NULL);
14af5a
bb8ad7 ¤   // version number
1305d5 ¤   if (pszVersion)·
4acc8f ¤   ¤   lstrcpy (sz, pszVersion);
400e24 ¤   else
6dfd09 ¤   ¤   lstrcpy (sz, PGPVERSIONSTRING);
0faccb ¤   TextOut (hdc, iXpos, iYpos, sz, lstrlen (sz));
93af5a
fa79df ¤   // labels
378f8d ¤   uTAOld = SetTextAlign (hdc, TA_RIGHT);
45c2a9 ¤   LoadString (g_hInst, IDS_VERSION, sz, sizeof(sz));
5ff5c5 ¤   TextOut (hdc, iXpos-8, iYpos, sz, lstrlen (sz));
efaf5a
924bbe ¤   LoadString (g_hInst, IDS_LICENSEDTO, sz, sizeof(sz));
11287d ¤   TextOut (hdc, iXpos-8, iYpos+YTEXTINC, sz, lstrlen (sz));
f4af5a
c2c18f ¤   SetTextAlign (hdc, uTAOld);
e373c2 ¤   SelectObject (hdc, hFontOld);
a10f3f ¤   PGPclCloseClientPrefs (PrefRef, FALSE);
aaefe6 }
31af5a
8b4265 //¤ ___________________________________________________
92465d //
fb021d //¤ Broadcast reload message
40af5a
d75860 VOID PGPclExport·
566243 PGPclNotifyKeyringChanges (LPARAM lParam)·
b8bb36 {
8d4b96 ¤   UINT uMessageID;
a1af5a
b3b8ba ¤   uMessageID = RegisterWindowMessage (RELOADKEYRINGMSG);
94bbac ¤   PostMessage (HWND_BROADCAST, uMessageID, 0, lParam);
87efe6 }
1baf5a
034265 //¤ ___________________________________________________
ee465d //
34021d //¤ Broadcast reload message
cfaf5a
ea5860 VOID PGPclExport·
a0a3d4 PGPclNotifyPrefsChanges (LPARAM lParam)·
3bbb36 {
3d4b96 ¤   UINT uMessageID;
3faf5a
1ec174 ¤   uMessageID = RegisterWindowMessage (RELOADPREFSMSG);
a6bbac ¤   PostMessage (HWND_BROADCAST, uMessageID, 0, lParam);
a3efe6 }
e7af5a
d64265 //¤ ___________________________________________________
27465d //
f8fe44 //¤ Broadcast messages indicating keyserver prefs may have changed
2eaf5a
375860 VOID PGPclExport·
03c991 PGPclNotifyKeyserverPrefsChanges (LPARAM lParam)·
3cbb36 {
0d4b96 ¤   UINT uMessageID;
5caf5a
77c7b9 ¤   uMessageID = RegisterWindowMessage (RELOADKEYSERVERPREFSMSG);
8dbbac ¤   PostMessage (HWND_BROADCAST, uMessageID, 0, lParam);
7eefe6 }
7eaf5a
a04265 //¤ ___________________________________________________
f4465d //
7ef6af //¤ get path of PGP installation from registry key·
7c2120 //¤ note: includes trailing '\'
80af5a
249d43 PGPError PGPclExport·
--848c 000cd87e49c4011028f Page 6 of CLmisc.c
b645a2 PGPclGetPGPPath (LPSTR szPath, UINT uLen)·
d5bb36 {
15829c ¤   HKEY¤   ¤   hKey;
07aa96 ¤   LONG¤   ¤   lResult;
d4bc4a ¤   CHAR*¤  ¤   p;
93878a ¤   DWORD¤  ¤   dwValueType, dwSize;
03669d ¤   CHAR¤   ¤   szKey[128];
0f61e0 ¤   PGPError¤   err;
bcaf5a
2f083a ¤   err = kPGPError_FileNotFound;
35af5a
e8d499 ¤   lstrcpy (szPath, "");
33af5a
7a18c7 ¤   LoadString (g_hInst, IDS_REGISTRYKEY, szKey, sizeof(szKey));
13f87b ¤   lResult = RegOpenKeyEx (HKEY_CURRENT_USER, szKey, 0, KEY_READ, &hKey);
34af5a
4faebc ¤   if (lResult == ERROR_SUCCESS) {
50ba40 ¤   ¤   err = kPGPError_OutputBufferTooSmall;
a230fe ¤   ¤   dwSize = uLen;
eb3e2f ¤   ¤   lResult = RegQueryValueEx (hKey, "ExePath", 0, &dwValueType,·
8a1a1e ¤   ¤   ¤   (LPBYTE)szPath, &dwSize);
588e60 ¤   ¤   RegCloseKey (hKey);
9a6be9 ¤   ¤   if (lResult == ERROR_SUCCESS) {
0af8e7 ¤   ¤   ¤   p = strrchr (szPath, '\\');
6e058b ¤   ¤   ¤   if (p) {
be2543 ¤   ¤   ¤   ¤   p++;
17e61f ¤   ¤   ¤   ¤   *p = '\0';
95a3a6 ¤   ¤   ¤   }
e6fcc4 ¤   ¤   ¤   err = kPGPError_NoErr;
9e0fe4 ¤   ¤   }
dd9371 ¤   }
49af5a
c95ea8 ¤   return err;
40efe6 }
cfaf5a
694265 //¤ ___________________________________________________
49465d //
cbfacb //¤ get keyring and randseed file paths from SDK·
bfaf5a
939d43 PGPError PGPclExport·
d6228c PGPclGetSDKFilePaths (
300597 ¤   ¤   LPSTR¤  pszPubRingPath,
964a69 ¤   ¤   INT¤¤   iPubRingLen,
00466d ¤   ¤   LPSTR¤  pszPrivRingPath,
fa6ca0 ¤   ¤   INT¤¤   iPrivRingLen,
48d46b ¤   ¤   LPSTR¤  pszRandSeedPath,
c82b91 ¤   ¤   INT¤¤   iRandSeedLen)·
a7bb36 {
8a0040 ¤   PGPError err;
17bd55 ¤   PGPFileSpecRef¤ fileref;
3c8a97 ¤   PGPContextRef¤  context;
6eb47b ¤   LPSTR¤  ¤   ¤   lpsz;
aeaf5a
4a5bb0 ¤   err = PGPNewContext ( kPGPsdkAPIVersion, &context);
f52560 ¤   PGPsdkLoadDefaultPrefs (context);
8daf5a
55b23e ¤   if (IsntPGPError (err)) {
6a67c5 ¤
b1fb17 ¤   ¤   if (pszPubRingPath) {
81f5e2 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (context, kPGPsdkPref_PublicKeyring,
fa7b13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileref);
22afb0 ¤   ¤   ¤   if (IsntPGPError (err) && fileref) {
7881be ¤   ¤   ¤   ¤   err = PGPGetFullPathFromFileSpec (fileref, &lpsz);
a856ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
89bde3 ¤   ¤   ¤   ¤   ¤   lstrcpyn (pszPubRingPath, lpsz, iPubRingLen);
4243cf ¤   ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
2b2613 ¤   ¤   ¤   ¤   }
750505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
63a3a6 ¤   ¤   ¤   }
580fe4 ¤   ¤   }
59af5a
cddad6 ¤   ¤   if (pszPrivRingPath && IsntPGPError (err)) {
--ec7d 0004b7407a24011028f Page 7 of CLmisc.c
f8b9a7 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (context, kPGPsdkPref_PrivateKeyring,
927b13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileref);
39afb0 ¤   ¤   ¤   if (IsntPGPError (err) && fileref) {
8c81be ¤   ¤   ¤   ¤   err = PGPGetFullPathFromFileSpec (fileref, &lpsz);
ca56ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
b1b93c ¤   ¤   ¤   ¤   ¤   lstrcpyn (pszPrivRingPath, lpsz, iPrivRingLen);
b143cf ¤   ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
4a2613 ¤   ¤   ¤   ¤   }
340505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
67a3a6 ¤   ¤   ¤   }
d00fe4 ¤   ¤   }
10af5a
be1e62 ¤   ¤   if (pszRandSeedPath && IsntPGPError (err)) {
d019b3 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (context, kPGPsdkPref_RandomSeedFile,
6e7b13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileref);
b6afb0 ¤   ¤   ¤   if (IsntPGPError (err) && fileref) {
3381be ¤   ¤   ¤   ¤   err = PGPGetFullPathFromFileSpec (fileref, &lpsz);
d956ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
007efe ¤   ¤   ¤   ¤   ¤   lstrcpyn (pszRandSeedPath, lpsz, iRandSeedLen);
ff43cf ¤   ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
642613 ¤   ¤   ¤   ¤   }
e50505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
5ca3a6 ¤   ¤   ¤   }
ae0fe4 ¤   ¤   }
0b669e ¤   ¤   PGPFreeContext (context);
e59371 ¤   }
c5af5a
675ea8 ¤   return err;
d8efe6 }
c7af5a
6e4265 //¤ ___________________________________________________
ec465d //
7077eb //¤ set keyring and randseed file paths using SDK·
11af5a
889d43 PGPError PGPclExport·
172fac PGPclSetSDKFilePaths (
970597 ¤   ¤   LPSTR¤  pszPubRingPath,
b3466d ¤   ¤   LPSTR¤  pszPrivRingPath,
55d46b ¤   ¤   LPSTR¤  pszRandSeedPath,
c1f23f ¤   ¤   BOOL¤   bCreateFiles)
a8bb36 {
78b2ea ¤   PGPKeySetRef¤   keysetDummy¤¤   = kInvalidPGPKeySetRef;
a9ae89 ¤   PGPFileSpecRef¤ fileref¤¤   ¤   = kInvalidPGPFileSpecRef;
afe6a2 ¤   PGPContextRef¤  context¤¤   ¤   = kInvalidPGPContextRef;
e91e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
a5af5a
f8f2a0 ¤   err = PGPNewContext (kPGPsdkAPIVersion, &context);
7d2560 ¤   PGPsdkLoadDefaultPrefs (context);
2faf5a
78b23e ¤   if (IsntPGPError (err)) {
b567c5 ¤
a4fb17 ¤   ¤   if (pszPubRingPath) {
e80845 ¤   ¤   ¤   err = PGPNewFileSpecFromFullPath (context,·
13bf9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pszPubRingPath, &fileref); CKERR;
da2bc6 ¤   ¤   ¤   if (PGPFileSpecRefIsValid (fileref)) {
dcd333 ¤   ¤   ¤   ¤   err = PGPsdkPrefSetFileSpec (context,·
5fffe5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PublicKeyring, fileref);
950505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
8f543c ¤   ¤   ¤   ¤   fileref = kInvalidPGPFileSpecRef;
5ca3a6 ¤   ¤   ¤   }
a360c5 ¤   ¤   } CKERR;
0baf5a
e66999 ¤   ¤   if (pszPrivRingPath) {
a10845 ¤   ¤   ¤   err = PGPNewFileSpecFromFullPath (context,·
114926 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pszPrivRingPath, &fileref); CKERR;
fa2bc6 ¤   ¤   ¤   if (PGPFileSpecRefIsValid (fileref)) {
78d333 ¤   ¤   ¤   ¤   err = PGPsdkPrefSetFileSpec (context,·
355925 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PrivateKeyring, fileref);
670505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
72543c ¤   ¤   ¤   ¤   fileref = kInvalidPGPFileSpecRef;
9ba3a6 ¤   ¤   ¤   }
4b60c5 ¤   ¤   } CKERR;
--5b71 000d4b524ff4011028f Page 8 of CLmisc.c
e0af5a
228ad2 ¤   ¤   if (pszRandSeedPath) {
2d0845 ¤   ¤   ¤   err = PGPNewFileSpecFromFullPath (context,·
a424a1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pszRandSeedPath, &fileref); CKERR;
ea2bc6 ¤   ¤   ¤   if (PGPFileSpecRefIsValid (fileref)) {
fcd333 ¤   ¤   ¤   ¤   err = PGPsdkPrefSetFileSpec (context,·
d20805 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_RandomSeedFile, fileref);
760505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
ea543c ¤   ¤   ¤   ¤   fileref = kInvalidPGPFileSpecRef;
d6a3a6 ¤   ¤   ¤   }
aa60c5 ¤   ¤   } CKERR;
64af5a
7a5936 ¤   ¤   PGPsdkSavePrefs (context);
07af5a
73f1e5 ¤   ¤   if (IsntPGPError (err) && bCreateFiles) {
bbc0ed ¤   ¤   ¤   err = PGPOpenDefaultKeyRings (context,·
d409cd ¤   ¤   ¤   ¤   kPGPKeyRingOpenFlags_Create|kPGPKeyRingOpenFlags_Mutable,·
315f7e ¤   ¤   ¤   ¤   &keysetDummy);
a36f0e ¤   ¤   ¤   if (PGPKeySetRefIsValid (keysetDummy))
205e43 ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetDummy);
7a0fe4 ¤   ¤   }
c0af5a
fd9371 ¤   }
efa1c0 done :
68d420 ¤   if (PGPFileSpecRefIsValid (fileref))·
fa4aba ¤   ¤   PGPFreeFileSpec (fileref);
452739 ¤   if (PGPContextRefIsValid (context))
66669e ¤   ¤   PGPFreeContext (context);
7aaf5a
745ea8 ¤   return err;
64efe6 }
00af5a
99af5a
9d6462 //¤ __________________________________________________
d6465d //
d9d90c //¤ save user information to preferences file·
fcaf5a
c19d43 PGPError PGPclExport·
8a04fe PGPclSetUserInfo (
a81a2e ¤   ¤   LPSTR¤  szOwnerName,
f7a24e ¤   ¤   LPSTR¤  szCompanyName,
10cc20 ¤   ¤   LPSTR¤  szLicenseNumber)
febb36 {
39fb19 ¤   PGPError¤   ¤   err;
a1ce0f ¤   PGPPrefRef¤ ¤   prefref;
898a97 ¤   PGPContextRef¤  context;
13af5a
20f2a0 ¤   err = PGPNewContext (kPGPsdkAPIVersion, &context);
778616 ¤   if (IsPGPError (err)) return err;
03af5a
9b6f41 ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (context), &prefref);
fc0971 ¤   if (IsPGPError (err)) {
99669e ¤   ¤   PGPFreeContext (context);
27c9db ¤   ¤   return err;
909371 ¤   }
d7af5a
c4e95c ¤   if (szOwnerName) {
96d0d4 ¤   ¤   PGPSetPrefString (prefref, kPGPPrefOwnerName, szOwnerName);
429371 ¤   }
42af5a
2cf9bc ¤   if (szCompanyName) {
ca8785 ¤   ¤   PGPSetPrefString (prefref, kPGPPrefCompanyName, szCompanyName);
359371 ¤   }
fdaf5a
2c65ce #if (PGP_NO_LICENSE_NUMBER == 0)
2bceaa ¤   if (szLicenseNumber) {
5cd96a ¤   ¤   PGPSetPrefString (prefref, kPGPPrefLicenseNumber, szLicenseNumber);
c29371 ¤   }
e5f1f4 #endif //PGP_NO_LICENSE_NUMBER
aaaf5a
0e88f8 ¤   err = PGPclCloseClientPrefs (prefref, TRUE);
d4af5a
--a0f4 000ef5002e24011028f Page 9 of CLmisc.c
325196 ¤   PGPFreeContext (context);
0a5ea8 ¤   return err;
e9efe6 }
9aaf5a
b7af5a
a95935 //¤ _________________________________________________
1e465d //
502e7f //¤ Wrapper routine for platform independent·
43f413 //¤ word wrap code.
f5af5a
f89d43 PGPError PGPclExport·
b01f8b PGPclWrapBuffer (
7967ec ¤   ¤   LPSTR¤  ¤   szInText,
4d4429 ¤   ¤   PGPUInt16¤  wrapColumn,
a0b5c6 ¤   ¤   LPSTR*¤ ¤   pszOutText)
80bb36 {
671e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
25ab58 ¤   PGPIORef¤   ¤   inRef, outRef;
6f1605 ¤   PGPMemoryMgrRef¤memMgr;
44ff49 ¤   PGPFileOffset¤  outSize;
c9821a ¤   PGPSize¤¤   ¤   outRead;
dd9b90 ¤   INT¤¤   ¤   ¤   InSize;
62af5a
a047ff ¤   outRead = 0;
66af5a
847114 ¤   err = PGPNewMemoryMgr ( 0, &memMgr);
66af5a
5e033a ¤   if (IsntPGPError (err))
f7c7a1 ¤   {
ba9c0b ¤   ¤   PGPNewMemoryIO (
27586d ¤   ¤   ¤   memMgr,
2388af ¤   ¤   ¤   (PGPMemoryIORef *)(&inRef));
d9af5a
089ca9 ¤   ¤   InSize = strlen (szInText);
239901 ¤   ¤   PGPIOWrite (inRef,
8c7c8c ¤   ¤   ¤   InSize,
87baaa ¤   ¤   ¤   szInText);
04a160 ¤   ¤   PGPIOFlush (inRef);
4f0496 ¤   ¤   PGPIOSetPos (inRef,0);
e8af5a
0c9c0b ¤   ¤   PGPNewMemoryIO (
ad586d ¤   ¤   ¤   memMgr,
26ce43 ¤   ¤   ¤   (PGPMemoryIORef *)(&outRef));
52af5a
477dbf ¤   ¤   err = pgpWordWrapIO(
80242b ¤   ¤   ¤   ··inRef,outRef,
c41823 ¤   ¤   ¤   ··wrapColumn,
272b37 ¤   ¤   ¤   ··"\r\n");
15af5a
26ae64 ¤   ¤   if (IsntPGPError (err))
745b34 ¤   ¤   {
85465b ¤   ¤   ¤   INT memamt;
17af5a
1d6895 ¤   ¤   ¤   PGPIOGetPos (outRef, &outSize);
b9af5a
da7439 ¤   ¤   ¤   memamt = (INT)outSize+1;
014579 ¤   ¤   ¤   *pszOutText = (CHAR *)malloc (memamt);
7baf5a
b6056d ¤   ¤   ¤   if (*pszOutText)
fbf776 ¤   ¤   ¤   {
7c9417 ¤   ¤   ¤   ¤   memset (*pszOutText, 0x00, memamt);
49af5a
8cedd9 ¤   ¤   ¤   ¤   PGPIOSetPos (outRef,0);
439127 ¤   ¤   ¤   ¤   PGPIORead (outRef,
515328 ¤   ¤   ¤   ¤   ¤   (INT)outSize,
8633cc ¤   ¤   ¤   ¤   ¤   *pszOutText,·
d6fe6f ¤   ¤   ¤   ¤   ¤   &outRead);
8ad452 ¤   ¤   ¤   ¤   PGPIOFlush (outRef);
6ea3a6 ¤   ¤   ¤   }
579877 ¤   ¤   ¤   else err = kPGPError_OutOfMemory;
d50fe4 ¤   ¤   }
ef937e ¤   ¤   PGPFreeIO (inRef);·
--500a 000084718fd4011028f Page 10 of CLmisc.c
0b87f9 ¤   ¤   PGPFreeIO (outRef);
cb9371 ¤   }
d166ed ¤   PGPFreeMemoryMgr (memMgr);
03af5a
fd5ea8 ¤   return err;
f6efe6 }
2eaf5a
5f6462 //¤ __________________________________________________
7c465d //
bce5f3 //¤ free previously-wrapped buffer
51af5a
b49d43 PGPError PGPclExport·
912488 PGPclFreeWrapBuffer (LPSTR textBuffer)
efbb36 {
7fc426 ¤   memset (textBuffer, 0x00, lstrlen (textBuffer));
23e23f ¤   free (textBuffer);
f5af5a
21151e ¤   return kPGPError_NoErr;
b3efe6 }
fcaf5a
3c4a83 //¤ ________________________
cd465d //
55f4b2 //¤ Get keyid string from key
e3af5a
c69d43 PGPError PGPclExport·
e50021 PGPclGetKeyFromKeyID (
5ce958 ¤   ¤   PGPContextRef¤  context,
9f8b6a ¤   ¤   PGPKeySetRef¤   keyset,
afd0ce ¤   ¤   LPSTR¤  ¤   ¤   szID,
ed07b4 ¤   ¤   UINT¤   ¤   ¤   uAlg,
3ff549 ¤   ¤   PGPKeyRef*¤ ¤   pkey)·
5ebb36 {
7ba8f7 ¤   PGPError¤   ¤   err;·
0ac0ff ¤   PGPKeyID¤   ¤   keyID;
02af5a
27f317 ¤   err = PGPImportKeyID (szID, &keyID);
12b23e ¤   if (IsntPGPError (err)) {
c6d0fd ¤   ¤   err = PGPGetKeyByKeyID (keyset, &keyID, uAlg, pkey);
c3b740 ¤   ¤   if (!(*pkey))·
c513f1 ¤   ¤   ¤   err = kPGPError_ItemNotFound;
2f9371 ¤   }
2baf5a
d05ea8 ¤   return err;
c1efe6 }
beaf5a
c44a83 //¤ ________________________
bc465d //
566b19 //¤ find out if SDK supports the specified public key algorithm
04af5a
0b9d43 PGPError PGPclExport·
2cfa6d PGPclCheckSDKSupportForPKAlg (
92a72a ¤   ¤   PGPPublicKeyAlgorithm alg,
6e6e99 ¤   ¤   PGPBoolean mustEncrypt,
0920bb ¤   ¤   PGPBoolean mustSign)
10bb36 {
e307a4 ¤   PGPError¤   err¤¤   ¤   = kPGPError_FeatureNotAvailable;
c5af5a
b5b1f2 ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   i, iNumAlgs;
3df474 ¤   PGPPublicKeyAlgorithmInfo¤  alginfo;
1aaf5a
2f6adc ¤   err = PGPCountPublicKeyAlgorithms (&iNumAlgs);
670c70 ¤   if (IsPGPError (err)) return kPGPError_FeatureNotAvailable;
e0af5a
9168a1 ¤   for (i=0; i<iNumAlgs; i++) {
686522 ¤   ¤   err = PGPGetIndexedPublicKeyAlgorithmInfo (i, &alginfo);
a68536 ¤   ¤   if (IsntPGPError (err)) {
c64d0d ¤   ¤   ¤   if (alginfo.algID == alg) {
7ebd37 ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
1a8dae ¤   ¤   ¤   ¤   if (mustEncrypt && !(alginfo.canEncrypt))
74e350 ¤   ¤   ¤   ¤   ¤   err = kPGPError_FeatureNotAvailable;
08dbef ¤   ¤   ¤   ¤   if (mustSign && !(alginfo.canSign))
08e350 ¤   ¤   ¤   ¤   ¤   err = kPGPError_FeatureNotAvailable;
--a75e 00056523ce04011028f Page 11 of CLmisc.c
28454a ¤   ¤   ¤   ¤   return err;
02a3a6 ¤   ¤   ¤   }
6b0fe4 ¤   ¤   }
109371 ¤   }
27af5a
06e63f ¤   return kPGPError_FeatureNotAvailable;
f0efe6 }
1caf5a
134a83 //¤ ________________________
49465d //
15064d //¤ find out if SDK supports the specified cipher algorithm
7daf5a
759d43 PGPError PGPclExport·
d3daa4 PGPclCheckSDKSupportForCipherAlg (PGPCipherAlgorithm alg)
86bb36 {
7b9780 ¤   PGPError¤   err¤¤   = kPGPError_FeatureNotAvailable;
f2af5a
a2b1f2 ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   i, iNumAlgs;
264519 ¤   PGPSymmetricCipherInfo¤ ¤   cipherinfo;
b7af5a
1572d3 ¤   err = PGPCountSymmetricCiphers (&iNumAlgs);
c10c70 ¤   if (IsPGPError (err)) return kPGPError_FeatureNotAvailable;
08af5a
3b68a1 ¤   for (i=0; i<iNumAlgs; i++) {
4675e9 ¤   ¤   err = PGPGetIndexedSymmetricCipherInfo (i, &cipherinfo);
b88536 ¤   ¤   if (IsntPGPError (err)) {
500373 ¤   ¤   ¤   if (cipherinfo.algID == alg) {
caf6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
46a3a6 ¤   ¤   ¤   }
290fe4 ¤   ¤   }
d79371 ¤   }
5aaf5a
afe63f ¤   return kPGPError_FeatureNotAvailable;
41efe6 }
d0af5a
024a83 //¤ ________________________
35465d //
46ccae //¤ sync up keysets to resolve trust information
65af5a
db9d43 PGPError PGPclExport·
b92981 PGPclSyncKeySets (
95a813 ¤   ¤   PGPContextRef context,
49986f ¤   ¤   PGPKeySetRef keysetMain,
7933a2 ¤   ¤   PGPKeySetRef keysetNew)
2ebb36 {
9eaf5a
c707ac ¤   PGPKeySetRef¤   keysetCombined;
fd3b94 ¤   PGPKeySetRef¤   keysetSync;
2efb19 ¤   PGPError¤   ¤   err;
e1af5a
d285da ¤   if (!PGPRefIsValid (keysetNew)) return kPGPError_NoErr;
dfaf5a
c07900 ¤   if (!PGPRefIsValid (keysetMain)) {
da198e ¤   ¤   PGPsdkLoadDefaultPrefs (context);
18460f ¤   ¤   err = PGPOpenDefaultKeyRings (context, 0, &keysetSync);
3da86b ¤   ¤   if (IsPGPError (err) || !PGPRefIsValid (keysetSync)) return err;
199371 ¤   }
4ebc8a ¤   else keysetSync = keysetMain;
d3af5a
9f4dd5 ¤   err = PGPNewKeySet (context, &keysetCombined);
55b23e ¤   if (IsntPGPError (err)) {
01af5a
422ea2 ¤   ¤   err = PGPAddKeys (keysetNew, keysetCombined);
2d8536 ¤   ¤   if (IsntPGPError (err)) {
7caf5a
78e80d ¤   ¤   ¤   err = PGPAddKeys (keysetSync, keysetCombined);
fd6a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
3baf5a
4e0d99 ¤   ¤   ¤   ¤   err = PGPCheckKeyRingSigs (keysetNew,·
f9841f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetCombined, FALSE, NULL, 0);
3eaf5a
5656ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
--ed2c 00025c722224011028f Page 12 of CLmisc.c
9ab294 ¤   ¤   ¤   ¤   ¤   err = PGPPropagateTrust (keysetCombined);
402613 ¤   ¤   ¤   ¤   }
17a3a6 ¤   ¤   ¤   }
030fe4 ¤   ¤   }
39af5a
752862 ¤   ¤   PGPFreeKeySet (keysetCombined);
dc9371 ¤   }
b2af5a
626266 ¤   if (!PGPRefIsValid (keysetMain)) PGPFreeKeySet (keysetSync);
43af5a
ff5ea8 ¤   return err;
47efe6 }
97af5a
76afaa //¤ __________________________________________________________
01465d //
48a223 // ·Check to see if it's time to auto-update keys
c5af5a
24ec6d PGPError PGPclExport
cdbd80 PGPclCheckAutoUpdate(PGPMemoryMgrRef memoryMgr,·
619d00 ¤   ¤   ¤   ¤   ¤   ·PGPBoolean bResetDates,
e68dc6 ¤   ¤   ¤   ¤   ¤   ·PGPBoolean *pbUpdateAllKeys,
b86602 ¤   ¤   ¤   ¤   ¤   ·PGPBoolean *pbUpdateTrustedIntroducers)
22bb36 {
ad8e12 ¤   PGPError¤   err = kPGPError_NoErr;
47af5a
bfbe29 #if PGP_BUSINESS_SECURITY
c30448 ¤   PGPPrefRef¤ adminPrefs;
fcfaef ¤   PGPBoolean¤ bUpdateAllKeys;
c16268 ¤   PGPBoolean¤ bUpdateTrustedIntroducers;
7797e4 ¤   PGPInt32¤   nDaysUpdateAllKeys;
2a282d ¤   PGPInt32¤   nDaysUpdateTrustedIntroducers;
8611ac ¤   PGPUInt32¤  nLastUpdate;
fb4380 ¤   time_t¤ ¤   tToday;
d6b516 ¤   time_t¤ ¤   tLastUpdate;
55ab28 ¤   struct tm ¤ tmToday;
9d54a0 ¤   struct tm ¤ tmLastUpdate;
800863 #endif //PGP_BUSINESS_SECURITY
54af5a
24b3fd ¤   if (pbUpdateAllKeys != NULL)
c3c643 ¤   ¤   *pbUpdateAllKeys = FALSE;
0baf5a
f68875 ¤   if (pbUpdateTrustedIntroducers != NULL)
c511a6 ¤   ¤   *pbUpdateTrustedIntroducers = FALSE;
85af5a
e0be29 #if PGP_BUSINESS_SECURITY
0daf5a
d297d8 ¤   err = PGPclOpenAdminPrefs(memoryMgr, &adminPrefs, TRUE);
a3af5a
8482f0 ¤   if (IsPGPError(err))
a8c9db ¤   ¤   return err;
efaf5a
07b32d ¤   tToday = PGPGetStdTimeFromPGPTime(PGPGetTime());
83a5a2 ¤   memcpy(&tmToday, localtime(&tToday), sizeof(struct tm));
baaf5a
624efb ¤   err = PGPGetPrefBoolean(adminPrefs, kPGPPrefUpdateAllKeys,·
f455b9 ¤   ¤   ¤   &bUpdateAllKeys);
6682f0 ¤   if (IsPGPError(err))
f8c7a1 ¤   {
ca56fb ¤   ¤   bUpdateAllKeys = FALSE;
d670bb ¤   ¤   err = kPGPError_NoErr;
529371 ¤   }
d6af5a
87a521 ¤   err = PGPGetPrefBoolean(adminPrefs, kPGPPrefUpdateTrustedIntroducers,·
2f60e8 ¤   ¤   ¤   &bUpdateTrustedIntroducers);
c682f0 ¤   if (IsPGPError(err))
99c7a1 ¤   {
dbdc7c ¤   ¤   bUpdateTrustedIntroducers = FALSE;
3270bb ¤   ¤   err = kPGPError_NoErr;
159371 ¤   }
74af5a
d5ac1e ¤   if (bUpdateAllKeys)
25c7a1 ¤   {
--8022 00085437cd84011028f Page 13 of CLmisc.c
bae25b ¤   ¤   err = PGPGetPrefNumber(adminPrefs, kPGPPrefDaysUpdateAllKeys,
7e0d07 ¤   ¤   ¤   ¤   &nDaysUpdateAllKeys);
6bb6ad ¤   ¤   if (IsPGPError(err))
605b34 ¤   ¤   {
e1fba6 ¤   ¤   ¤   nDaysUpdateAllKeys = 0;
11fcc4 ¤   ¤   ¤   err = kPGPError_NoErr;
470fe4 ¤   ¤   }
fbaf5a
612613 ¤   ¤   if (nDaysUpdateAllKeys > 0)
395b34 ¤   ¤   {
0fa69d ¤   ¤   ¤   err = PGPGetPrefNumber(adminPrefs, kPGPPrefLastAllKeysUpdate,
46c9bd ¤   ¤   ¤   ¤   ¤   &nLastUpdate);
d20dfb ¤   ¤   ¤   if (IsPGPError(err))
96f776 ¤   ¤   ¤   {
ff6a49 ¤   ¤   ¤   ¤   nLastUpdate = 0;
eabd37 ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
20a3a6 ¤   ¤   ¤   }
1daf5a
78373c ¤   ¤   ¤   tLastUpdate = PGPGetStdTimeFromPGPTime(nLastUpdate);
63f59e ¤   ¤   ¤   memcpy(&tmLastUpdate, localtime(&tLastUpdate), sizeof(struct tm));
c5af5a
24f326 ¤   ¤   ¤   if (tmToday.tm_year > tmLastUpdate.tm_year)
5398a7 ¤   ¤   ¤   ¤   tmToday.tm_yday += 366;
34af5a
33775b ¤   ¤   ¤   if ((tmToday.tm_yday - tmLastUpdate.tm_yday) >=
8a88d2 ¤   ¤   ¤   ¤   nDaysUpdateAllKeys)
f0f776 ¤   ¤   ¤   {
e3b775 ¤   ¤   ¤   ¤   *pbUpdateAllKeys = TRUE;
24f4b1 ¤   ¤   ¤   ¤   if (bResetDates)
9172c3 ¤   ¤   ¤   ¤   {
edc198 ¤   ¤   ¤   ¤   ¤   PGPSetPrefNumber(adminPrefs, kPGPPrefLastAllKeysUpdate,
91d19b ¤   ¤   ¤   ¤   ¤   ¤   PGPGetTime());
6f2613 ¤   ¤   ¤   ¤   }
8fa3a6 ¤   ¤   ¤   }
a70fe4 ¤   ¤   }
209371 ¤   }
30af5a
246778 ¤   if (bUpdateTrustedIntroducers)
02c7a1 ¤   {
185f82 ¤   ¤   err = PGPGetPrefNumber(adminPrefs,·
e59020 ¤   ¤   ¤   ¤   kPGPPrefDaysUpdateTrustedIntroducers,
17c2e1 ¤   ¤   ¤   ¤   &nDaysUpdateTrustedIntroducers);
32b6ad ¤   ¤   if (IsPGPError(err))
b85b34 ¤   ¤   {
4950be ¤   ¤   ¤   nDaysUpdateTrustedIntroducers = 0;
4cfcc4 ¤   ¤   ¤   err = kPGPError_NoErr;
aa0fe4 ¤   ¤   }
beaf5a
38fea5 ¤   ¤   if (nDaysUpdateTrustedIntroducers > 0)
ae5b34 ¤   ¤   {
fa47d2 ¤   ¤   ¤   err = PGPGetPrefNumber(adminPrefs,·
f3e2c4 ¤   ¤   ¤   ¤   ¤   kPGPPrefLastTrustedIntroducersUpdate,
5ac9bd ¤   ¤   ¤   ¤   ¤   &nLastUpdate);
6a0dfb ¤   ¤   ¤   if (IsPGPError(err))
3bf776 ¤   ¤   ¤   {
616a49 ¤   ¤   ¤   ¤   nLastUpdate = 0;
1cbd37 ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
8da3a6 ¤   ¤   ¤   }
e5af5a
73373c ¤   ¤   ¤   tLastUpdate = PGPGetStdTimeFromPGPTime(nLastUpdate);
11f59e ¤   ¤   ¤   memcpy(&tmLastUpdate, localtime(&tLastUpdate), sizeof(struct tm));
2faf5a
87f326 ¤   ¤   ¤   if (tmToday.tm_year > tmLastUpdate.tm_year)
b398a7 ¤   ¤   ¤   ¤   tmToday.tm_yday += 366;
b2af5a
93775b ¤   ¤   ¤   if ((tmToday.tm_yday - tmLastUpdate.tm_yday) >=
56c6b0 ¤   ¤   ¤   ¤   nDaysUpdateTrustedIntroducers)
8df776 ¤   ¤   ¤   {
ab6120 ¤   ¤   ¤   ¤   *pbUpdateTrustedIntroducers = TRUE;
3681ba ¤   ¤   ¤   ¤   if (bResetDates)·
3072c3 ¤   ¤   ¤   ¤   {
8542d5 ¤   ¤   ¤   ¤   ¤   PGPSetPrefNumber(adminPrefs,·
--259d 0008e575c9d4011028f Page 14 of CLmisc.c
4f00c4 ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefLastTrustedIntroducersUpdate,
b8d19b ¤   ¤   ¤   ¤   ¤   ¤   PGPGetTime());
f32613 ¤   ¤   ¤   ¤   }
23a3a6 ¤   ¤   ¤   }
320fe4 ¤   ¤   }
cc9371 ¤   }
b4af5a
70f96f ¤   PGPclCloseAdminPrefs(adminPrefs, TRUE);
51af5a
0597b2 #endif¤ // PGP_BUSINESS_SECURITY
57af5a
925ea8 ¤   return err;
fbefe6 }
faaf5a
d4af5a
98bf56 //----------------------------------------------------|
46bb22 // Sign key dialog message procedure
0caf5a
033f64 static BOOL CALLBACK·
c22af8 sConfirmAuthDlgProc (
80f178 ¤   ¤   ¤   ¤   HWND hDlg,·
91c92a ¤   ¤   ¤   ¤   UINT uMsg,·
13080c ¤   ¤   ¤   ¤   WPARAM wParam,·
580c85 ¤   ¤   ¤   ¤   LPARAM lParam)·
bbbb36 {
fdc2d3 ¤   PCONFIRMAUTHSTRUCT¤ pcas;
0e0846 ¤   CHAR¤   ¤   ¤   ¤   sz[64];
0ab236 ¤   INT¤¤   ¤   ¤   ¤   i;
7eb7ba ¤   PGPValidity¤¤   ¤   validity;
7ff37a ¤   PGPUInt32¤  ¤   ¤   uAlgorithm;
46ebdf ¤   UINT¤   ¤   ¤   ¤   uIDS;
ccaf5a
2d347f ¤   switch (uMsg) {
abaf5a
d1ad3a ¤   case WM_INITDIALOG :
347547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
24b02b ¤   ¤   pcas = (PCONFIRMAUTHSTRUCT)lParam;
9caf5a
f1eab5 ¤   ¤   // initialize validity bar
5dbe9e ¤   ¤   i = KMConvertFromPGPValidity (kPGPValidity_Complete);
2b83c0 ¤   ¤   SendMessage (GetDlgItem (hDlg, IDC_VALIDITY), PBM_SETRANGE,·
cb2453 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, MAKELPARAM (0,i));
b52aa2 ¤   ¤   PGPGetKeyNumber (pcas->keyAuthenticating, kPGPKeyPropValidity,·
70821c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &validity);
8bc942 ¤   ¤   i = KMConvertFromPGPValidity (validity);
c14c97 ¤   ¤   SendMessage (GetDlgItem (hDlg, IDC_VALIDITY), PBM_SETPOS,·
14330b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)i, 0);
bdaf5a
971b19 ¤   ¤   // initialize text
683e62 ¤   ¤   uIDS = 0;
80dcf2 ¤   ¤   switch (pcas->uFlags) {
df5b43 ¤   ¤   case PGPCL_SHOWAUTHENTICATION :
3641ba ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDOK), SW_HIDE);
b68bd3 ¤   ¤   ¤   LoadString (g_hInst, IDS_DONE, sz, sizeof(sz));
b54e56 ¤   ¤   ¤   SetDlgItemText (hDlg, IDCANCEL, sz);
c2cdcb ¤   ¤   ¤   break;
3faf5a
83b26f ¤   ¤   case PGPCL_AUTHEXPECTEDKEY :
9d30e7 ¤   ¤   ¤   if (validity >= pcas->validityThreshold) {
24cebd ¤   ¤   ¤   ¤   EndDialog (hDlg, 1);
67d64b ¤   ¤   ¤   ¤   return FALSE;
47a3a6 ¤   ¤   ¤   }
826b93 ¤   ¤   ¤   else·
8ab2bb ¤   ¤   ¤   ¤   uIDS = IDS_INVALIDAUTHKEY;
11cdcb ¤   ¤   ¤   break;
6aaf5a
b19005 ¤   ¤   case PGPCL_AUTHRECONSTITUTING :
fa6013 ¤   ¤   ¤   if (validity < pcas->validityThreshold)
bab2bb ¤   ¤   ¤   ¤   uIDS = IDS_INVALIDAUTHKEY;
1d6b93 ¤   ¤   ¤   else·
91c17b ¤   ¤   ¤   ¤   uIDS = IDS_VALIDAUTHKEY;
8ecdcb ¤   ¤   ¤   break;
--c8d2 000d85f43054011028f Page 15 of CLmisc.c
e0af5a
dbcd6d ¤   ¤   case PGPCL_AUTHNEWKEY :
21e6fa ¤   ¤   ¤   uIDS = IDS_NEWAUTHKEY;
3fcdcb ¤   ¤   ¤   break;
f8af5a
ca1f3d ¤   ¤   case PGPCL_AUTHUNEXPECTEDKEY :
d9c0df ¤   ¤   ¤   uIDS = IDS_UNEXPECTEDAUTHKEY;
fdcdcb ¤   ¤   ¤   break;
e10fe4 ¤   ¤   }
a6af5a
dfaddd ¤   ¤   if (uIDS) {
f7bba1 ¤   ¤   ¤   CHAR¤   szText[256];
96af5a
e3f79b ¤   ¤   ¤   LoadString (g_hInst, uIDS, szText, sizeof(szText));
b8bbc4 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_AUTHTEXT, szText);
df0fe4 ¤   ¤   }
84af5a
437995 ¤   ¤   // initialize server name
7b6cd4 ¤   ¤   SetDlgItemText (hDlg, IDC_SERVERNAME, pcas->pszRemoteHost);
5eaf5a
cc772c ¤   ¤   // initialize key name
2fb4fe ¤   ¤   SetDlgItemText (hDlg, IDC_KEYNAME, pcas->szName);
95af5a
1c7382 ¤   ¤   // initialize fingerprint edit control
7e665c ¤   ¤   PGPGetKeyPropertyBuffer (pcas->keyAuthenticating,·
67eec7 ¤   ¤   ¤   ¤   kPGPKeyPropFingerprint, sizeof (sz), sz, &i);
79fc53 ¤   ¤   PGPGetKeyNumber (pcas->keyAuthenticating,·
c15e75 ¤   ¤   ¤   ¤   kPGPKeyPropAlgID, &uAlgorithm);
7fa9bf ¤   ¤   KMConvertStringFingerprint (uAlgorithm, sz);
1e3b85 ¤   ¤   SetDlgItemText (hDlg, IDC_FINGERPRINT, sz);
87af5a
2e836c ¤   ¤   return TRUE;
cdaf5a
828a25 ¤   case WM_HELP:·
84fb42 ¤   ····WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
a7d0c3 ¤   ········HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
0e7d53 ¤   ····break;·
c7af5a
19af40 ¤   case WM_CONTEXTMENU:·
c6082b ¤   ¤   WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
aa9517 ¤   ¤   ····(DWORD) (LPVOID) aIds);·
40ca2d ¤   ¤   break;·
efaf5a
29d1d3 ¤   case WM_COMMAND :
aa537d ¤   ¤   switch (LOWORD(wParam)) {
11b6bb ¤   ¤   case IDCANCEL :
eaef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
83cdcb ¤   ¤   ¤   break;
78af5a
658c29 ¤   ¤   case IDOK :
04f3d5 ¤   ¤   ¤   EndDialog (hDlg, 1);
67cdcb ¤   ¤   ¤   break;
c0af5a
60816b ¤   ¤   case IDC_IMPORTKEY :
e5e699 ¤   ¤   ¤   pcas = (PCONFIRMAUTHSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
c7f776 ¤   ¤   ¤   {
3efe62 ¤   ¤   ¤   ¤   PGPKeySetRef¤   ¤   keysetAuth;
4fb0c1 ¤   ¤   ¤   ¤   PGPError¤   ¤   ¤   err;·
b7af5a
9e6894 ¤   ¤   ¤   ¤   err = PGPNewSingletonKeySet (
9c5563 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pcas->keyAuthenticating, &keysetAuth);
83f61a ¤   ¤   ¤   ¤   if (IsntPGPError (err) && PGPKeySetRefIsValid (keysetAuth))·
ae72c3 ¤   ¤   ¤   ¤   {
d52cc5 ¤   ¤   ¤   ¤   ¤   err = CLAddKeysToMain (
dd5715 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pcas->context,
e94efb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg,·
cc2ce9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetAuth,
29e0ca ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pcas->keysetMain);
f8c0de ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetAuth);
ff2613 ¤   ¤   ¤   ¤   }
3da3a6 ¤   ¤   ¤   }
d8cdcb ¤   ¤   ¤   break;
--7cd2 00007a863184011028f Page 16 of CLmisc.c
b50fe4 ¤   ¤   }
ab836c ¤   ¤   return TRUE;
059371 ¤   }
a0a230 ¤   return FALSE;
d7efe6 }
85af5a
4cbf56 //----------------------------------------------------|
6a26ed // ·post confirmation dialog for authentication key
dfaf5a
f5ec6d PGPError PGPclExport
0e1fdb PGPclConfirmRemoteAuthentication (
42e958 ¤   ¤   PGPContextRef¤  context,
468732 ¤   ¤   HWND¤   ¤   ¤   hwndParent,·
99dbc1 ¤   ¤   LPSTR¤  ¤   ¤   pszServer,
5663e7 ¤   ¤   PGPKeyRef¤  ¤   keyAuth,
8355dd ¤   ¤   PGPKeySetRef¤   keysetMain,
954424 ¤   ¤   UINT¤   ¤   ¤   uFlags)
51bb36 {
044d65 ¤   CONFIRMAUTHSTRUCT¤  cas;
8ae744 ¤   UINT¤   ¤   ¤   ¤   u;
3c20f1 ¤   PGPPrefRef¤ ¤   ¤   prefs;
979f46 ¤   PGPBoolean¤ ¤   ¤   bMargIsInvalid;
8eaf5a
397943 ¤   cas.context¤¤   ¤   ¤   = context;
a0caaf ¤   cas.pszRemoteHost¤  ¤   = pszServer;
4d98a1 ¤   cas.keyAuthenticating¤  = keyAuth;
c46abf ¤   cas.keysetMain¤ ¤   ¤   = keysetMain;
ee78e6 ¤   cas.uFlags¤ ¤   ¤   ¤   = uFlags;
db05e8 ¤   cas.szName[0]¤  ¤   ¤   = '\0';
20af5a
8b5857 ¤   if (PGPKeyRefIsValid (keyAuth))
df8189 ¤   ¤   PGPGetPrimaryUserIDNameBuffer (keyAuth, kPGPMaxUserIDSize,
d54da9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   cas.szName, &u);
35af5a
d664a3 ¤   // use prefs to determine validity threshold
2594e0 ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (context), &prefs);
9e326e ¤   PGPGetPrefBoolean (prefs, kPGPPrefMarginalIsInvalid, &bMargIsInvalid);
30432d ¤   PGPclCloseClientPrefs (prefs, FALSE);
d23243 ¤   if (bMargIsInvalid)·
e43303 ¤   ¤   cas.validityThreshold = kPGPValidity_Complete;
7e0e24 ¤   else
7193b5 ¤   ¤   cas.validityThreshold = kPGPValidity_Marginal;
daaf5a
0029c9 ¤   if (DialogBoxParam (g_hInst,·
944536 ¤   ¤   MAKEINTRESOURCE(IDD_CONFIRMAUTHENTICATION),
bf5ecb ¤   ¤   hwndParent, sConfirmAuthDlgProc, (LPARAM)&cas))
76b840 ¤   ¤   return kPGPError_NoErr;
260e24 ¤   else
4674be ¤   ¤   return kPGPError_UserAbort;
77af5a
fbefe6 }
5caf5a
7fbf56 //----------------------------------------------------|
040fe7 // ·find unknown signer key
d4af5a
58ec6d PGPError PGPclExport
7b0ecd PGPclLookupUnknownSigner(
489cd4 ¤   ¤   PGPContextRef¤  ¤   context,
f35c17 ¤   ¤   PGPKeySetRef¤   ¤   KeySetMain,
e2a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
fb317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
813b5f ¤   ¤   PGPEvent¤   ¤   ¤   *event,
e854ea ¤   ¤   PGPKeyID¤   ¤   ¤   signingKeyID,
5ab8ec ¤   ¤   PGPBoolean*¤¤   ¤   pbGotKeys)
edbb36 {
3acb95 ¤   PGPKeySetRef newKeySet = NULL;
aaa6f7 ¤   PGPUInt32 numKeys = 0;
fc8129 ¤   PGPError lookupErr;
8a42ee ¤   int nOleErr;
19af5a
872b48 ¤   if (pbGotKeys == NULL)
0762b5 ¤   ¤   return kPGPError_BadParams;
--dac6 000a7d0cac64011028f Page 17 of CLmisc.c
e0af5a
4d0955 ¤   *pbGotKeys = FALSE;
ceaf5a
cebe1e ¤   lookupErr = PGPclSearchServerForKeyIDs(context,
62d541 ¤   ¤   ¤   ¤   ¤   NULL, hwnd, &signingKeyID, 1,·
495826 ¤   ¤   ¤   ¤   ¤   PGPCL_DEFAULTSERVER, KeySetMain, &newKeySet);
bb2b85 ¤   ¤   ¤   ¤
14000f ¤   if (IsPGPError(lookupErr))
cc97a7 ¤   ¤   PGPclErrorBox(hwnd, lookupErr);
1d0e24 ¤   else
7ac7a1 ¤   {
263d87 ¤   ¤   PGPCountKeys(newKeySet, &numKeys);
9ef327 ¤   ¤   if (numKeys > 0)
145b34 ¤   ¤   {
74cdc3 ¤   ¤   ¤   nOleErr = OleInitialize(NULL);
9b1c2a ¤   ¤   ¤   if ((nOleErr == S_OK) || (nOleErr == S_FALSE))
82f776 ¤   ¤   ¤   {
be3f57 ¤   ¤   ¤   ¤   PGPclQueryAddKeys(context, tlsContext, hwnd, newKeySet,·
a1d98c ¤   ¤   ¤   ¤   ¤   NULL);
fae445 ¤   ¤   ¤   ¤   OleUninitialize();
95a3a6 ¤   ¤   ¤   }
a287c7 ¤   ¤   ¤
ff723e ¤   ¤   ¤   PGPAddJobOptions(event->job,
677ff7 ¤   ¤   ¤   ¤   PGPOKeySetRef(context, newKeySet),
e8d911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
d4af5a
2ebe7d ¤   ¤   ¤   PGPFreeKeySet(newKeySet);
832b60 ¤   ¤   ¤   *pbGotKeys = TRUE;
dd0fe4 ¤   ¤   }
559371 ¤   }
c2af5a
7a151e ¤   return kPGPError_NoErr;
a6efe6 }
03af5a
e8af5a
63c509 //¤ ____________________________________
7b465d //
534e23 //¤ Get HWND of PGPkeys application
64af5a
087160 static HWND·
8f4006 sGetPGPkeysWindow (VOID)
ddbb36 {
2188bb ····HWND¤   ¤   ¤   hWndMe¤ ¤   = NULL;
90a7a9 ····HANDLE¤ ¤   ¤   hSem;
c5af5a
8718c5 ····// Create or open a named semaphore.·
6819a2 ····hSem = CreateSemaphore (NULL, 0, 1, SEMAPHORENAME);
bdaf5a
d1be1f ····// return HWND if existing semaphore was opened.
356b54 ····if (hSem != NULL) {
d41214 ¤   ¤   if (GetLastError() == ERROR_ALREADY_EXISTS) {
d2e190 ¤   ¤   ····hWndMe = FindWindow (WINCLASSNAME, WINDOWTITLE);
820fe4 ¤   ¤   }
1f5806 ········CloseHandle(hSem);
929371 ¤   }
21af5a
b445e3 ¤   return hWndMe;
45efe6 }
14af5a
88bf56 //----------------------------------------------------|
50aa50 // Add keys in specified keyset to main keyset
98af5a
7a7efe BOOL·
b62bf6 CLAddKeysToMain (
6afb68 ¤   ¤   PGPContextRef¤  context,·
61e0af ¤   ¤   HWND¤   ¤   ¤   hwnd,
a73e7d ¤   ¤   PGPKeySetRef¤   keysetToAdd,
b411cc ¤   ¤   PGPKeySetRef¤   keysetMain)·
b4bb36 {
3a3c26 ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   ¤   = 0;
dcaf18 ¤   PGPKeySetRef¤   ¤   keyset¤ ¤   ¤   ¤   = kInvalidPGPKeySetRef;
a7c7b2 ¤   UINT¤   ¤   ¤   ¤   uReloadMessage;
--4e38 0005debf6124011028f Page 18 of CLmisc.c
81e6ae ¤   HWND¤   ¤   ¤   ¤   hwndPGPkeys;
d2ef37 ¤   LPVOID¤ ¤   ¤   ¤   pBuffer;
cab4b2 ¤   INT¤¤   ¤   ¤   ¤   slen;
fe0b62 ¤   COPYDATASTRUCT¤ ¤   cds;
9b54d9 ¤   HCURSOR¤¤   ¤   ¤   hCursorOld;
42af5a
02af5a
20d4a0 ¤   if (PGPKeySetRefIsValid (keysetMain)) {
90c016 ¤   ¤   err = PGPAddKeys (keysetToAdd, keysetMain);
f08536 ¤   ¤   if (IsntPGPError (err)) {
104a25 ¤   ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
c3e817 ¤   ¤   ¤   err = PGPCommitKeyRingChanges (keysetMain);
dafac5 ¤   ¤   ¤   SetCursor (hCursorOld);
00af5a
936a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
1e5973 ¤   ¤   ¤   ¤   uReloadMessage = RegisterWindowMessage (RELOADKEYRINGMSG);
f4e471 ¤   ¤   ¤   ¤   PostMessage (HWND_BROADCAST, uReloadMessage,·
bac4e2 ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (LOWORD (hwnd), TRUE),·
bb2d68 ¤   ¤   ¤   ¤   ¤   ¤   GetCurrentProcessId ());
cca3a6 ¤   ¤   ¤   }
e60fe4 ¤   ¤   }
829371 ¤   }
809659 ¤   // no main keyset, we're supposed to try to add it to default keyring
2c665a ¤   else {
05996e ¤   ¤   hwndPGPkeys = sGetPGPkeysWindow ();
ce1525 ¤   ¤   // PGPkeys is running ... send it the key block
50b157 ¤   ¤   if (hwndPGPkeys) {
9b074f ¤   ¤   ¤   err = PGPExportKeySet (keysetToAdd,·
6d34c6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOAllocatedOutputBuffer (context,
c448f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pBuffer, 0x40000000, &slen),
925c69 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOExportPrivateKeys (context, TRUE),
a0603b ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOExportFormat (context,·
5d1d4c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPExportFormat_Complete),
c33204 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
906a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
6e10b9 ¤   ¤   ¤   ¤   cds.dwData = PGPPK_IMPORTKEYBUFFER;
aaea52 ¤   ¤   ¤   ¤   cds.cbData = slen+1;
4118d5 ¤   ¤   ¤   ¤   cds.lpData = pBuffer;
9d4963 ¤   ¤   ¤   ¤   err = SendMessage (hwndPGPkeys, WM_COPYDATA,·
b09b54 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&cds);
637fc2 ¤   ¤   ¤   ¤   if (err) err = kPGPError_NoErr;
ef9e06 ¤   ¤   ¤   ¤   else err = kPGPError_UnknownError;
285527 ¤   ¤   ¤   ¤   PGPFreeData (pBuffer);
30a3a6 ¤   ¤   ¤   }
f80fe4 ¤   ¤   }
36af5a
c5abf7 ¤   ¤   // PGPkeys is not running ... try to add keys to default keyring
9f07e0 ¤   ¤   else {
f2204b ¤   ¤   ¤   PGPsdkLoadDefaultPrefs (context);
5c8d82 ¤   ¤   ¤   err = PGPOpenDefaultKeyRings (¤ context,·
8c8689 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyRingOpenFlags_Mutable,·
db8d41 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);
a7f2c4 ¤   ¤   ¤   if (IsntPGPError (err) && keyset) {
6420f3 ¤   ¤   ¤   ¤   err = PGPAddKeys (keysetToAdd, keyset);
f156ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
ffcfe1 ¤   ¤   ¤   ¤   ¤   err = PGPCommitKeyRingChanges (keyset);
256f6e ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
6f665a ¤   ¤   ¤   ¤   ¤   ¤   uReloadMessage =·
305c5c ¤   ¤   ¤   ¤   ¤   ¤   ¤   RegisterWindowMessage (RELOADKEYRINGMSG);
fd4d4b ¤   ¤   ¤   ¤   ¤   ¤   PostMessage (HWND_BROADCAST, uReloadMessage,·
bf26ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (LOWORD (hwnd), FALSE),·
e67e73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetCurrentProcessId ());
0c1c89 ¤   ¤   ¤   ¤   ¤   }
142613 ¤   ¤   ¤   ¤   }
c3cdef ¤   ¤   ¤   ¤   PGPFreeKeySet (keyset);
6da3a6 ¤   ¤   ¤   }
f00fe4 ¤   ¤   }
969371 ¤   }
24af5a
c20971 ¤   if (IsPGPError (err)) {
d1d229 ¤   ¤   PGPclMessageBox (hwnd, IDS_CAPTION, IDS_IMPORTKEYERROR,
5d14e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
--cbc4 00191dc7b164011028f Page 19 of CLmisc.c
a19371 ¤   }
2eac2a ¤   return (IsntPGPError (err));
b8efe6 }
91af5a
--1bb6 001046cfe4340110290 Page 1 of CLnag.rc
2dd673 #if PGP_DEMO
f6af5a
c46c0e /////////////////////////////////////////////////////////////////////////////
d1465d //
34ae70 // Bitmap
9d465d //
f2af5a
d5163e IDB_NAG1 ············BITMAP ·DISCARDABLE ····"res\\eval1bit.bmp"
9bb2d4 IDB_NAG4 ············BITMAP ·DISCARDABLE ····"res\\eval4bit.bmp"
cd345d IDB_NAG8 ············BITMAP ·DISCARDABLE ····"res\\eval8bit.bmp"
8aaf5a
b72d33 #endif¤ // PGP_DEMO
04af5a
--21e3 000f89dd24340110291 Page 1 of CLphrase.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
6df343 ¤   CLphrase.c - get passphrase from user
a8af5a
fa8df5 ¤   Glue code to interface with PGPsdkUI
d8af5a
eff935 ¤   $Id: CLphrase.c,v 1.40 1998/08/11 14:43:10 pbj Exp $
55f7f7 ____________________________________________________________________________*/
08e610 #include "pgpPFLConfig.h"
b4af5a
535fcd #include "pgpclx.h"
79e684 #include "pgpUserInterface.h"
059cad extern HINSTANCE g_hInst;
25af5a
2c0b1a //___________________________
c7465d //
b2c415 // Secure memory allocation routines
92465d //
f0af5a
d4493a VOID*·
771e0a secAlloc (PGPContextRef context, UINT uBytes)·
18bb36 {
317694 ¤   PGPMemoryMgrRef¤memmgr;
9aaf5a
8344b8 ¤   memmgr = PGPGetContextMemoryMgr (context);
623fdc ¤   return (PGPNewSecureData (memmgr, uBytes, 0));
7aefe6 }
dbaf5a
47af5a
8ba1ba VOID·
abd91b secFree (VOID* p)·
a5bb36 {
5df191 ¤   if (p) {
df1efa ¤   ¤   FillMemory (p, lstrlen (p), 0x00);
1d4bbf ¤   ¤   PGPFreeData (p);
459371 ¤   }
b7efe6 }
59af5a
7d4a83 //¤ ________________________
71465d //
95b84e // ·wipe and free passphrase·
06af5a
7f5860 VOID PGPclExport·
b3d968 PGPclFreePhrase (LPSTR pszPhrase)·
58bb36 {
64fb33 ¤   if (pszPhrase) {
01acf1 ¤   ¤   secFree (pszPhrase);
d39371 ¤   }
c2efe6 }
dcaf5a
f246e5 //¤ _______________________________________________________
ed465d //
169c48 // ·Entry point called by app to post dialog and get phrase
adac6a //·
55e0b1 // ·This used to be the main entry point for passphrase·
1a6128 // ·dialogs. Now it is used to convert the calling parameters
6e2a54 // ·to the new PGP UI Library, and then massage the output
884dd6 // ·back into something the old client code can understand.
f8ecc0 // ·
1d14e1 // ·wjb
9aaf5a
f59d43 PGPError PGPclExport·
9f2c3b PGPclGetPhrase (
39e958 ¤   ¤   PGPContextRef¤  context,
59dffe ¤   ¤   PGPKeySetRef¤   MainKeySet,
57ac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
4e609e ¤   ¤   LPSTR¤  ¤   ¤   szPrompt,
44930f ¤   ¤   LPSTR*¤ ¤   ¤   ppszPhrase,·
de5d0b ¤   ¤   PGPKeySetRef¤   KeySet,
f8975f ¤   ¤   PGPKeyID*¤  ¤   pKeyIDs,
--f525 00008de934340110291 Page 2 of CLphrase.c
c1a0a6 ¤   ¤   UINT¤   ¤   ¤   uKeyCount,
a94994 ¤   ¤   PGPKeyRef*¤ ¤   pKey,·
043b17 ¤   ¤   UINT*¤  ¤   ¤   puOptions,·
f93a9c ¤   ¤   UINT¤   ¤   ¤   uFlags,
afe873 ¤   ¤   PGPByte**¤  ¤   ppPasskeyBuffer,
68ab36 ¤   ¤   PGPUInt32*¤ ¤   piPasskeyLength,
b5f6f0 ¤   ¤   PGPUInt32¤  ¤   MinLength,
a594d0 ¤   ¤   PGPUInt32¤  ¤   MinQuality,
f35c31 ¤   ¤   PGPtlsContextRef tlsContext,
683e2c ¤   ¤   PGPKeySetRef¤   *AddedKeys
bc64eb ¤   ¤   )·
dfd689 {¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
0949ce ¤   PGPError¤   ¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
a18dda ¤   PGPOptionListRef¤   ¤   ¤   optionList¤ ¤   = kInvalidPGPOptionListRef;
21b1e5 ¤   PGPKeyServerEntry¤  ¤   ¤   *ksEntries¤ ¤   = NULL;
ea566e ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   numKSEntries¤   = 0;
697dd8 ¤   PGPKeyServerSpec¤   ¤   ¤   *serverList¤¤   = NULL;
f8e56a ¤   PGPKeySetRef¤   ¤   ¤   ¤   foundKeys¤  ¤   = kInvalidPGPKeySetRef;
58790d ¤   PGPPrefRef¤ ¤   ¤   ¤   ¤   clientPrefsRef¤ = kInvalidPGPPrefRef;
402204 ¤   PGPMemoryMgrRef¤¤   ¤   ¤   memMgr¤ ¤   ¤   = kInvalidPGPMemoryMgrRef;
d72a7c ¤   PCLIENTSERVERSTRUCT¤¤   ¤   pcss¤   ¤   ¤   = NULL;
c9af5a
bf8f4a ¤   CHAR¤   ¤   ¤   ¤   ¤   ¤   StrRes1[100],StrRes2[100];
eddfd0 ¤   PGPKeyRef ¤ ¤   ¤   ¤   ¤   decryptionKey;¤ // dummy, we don't care
2467c5 ¤
708be9 ¤   memMgr = PGPGetContextMemoryMgr (context);
068b22 ¤   err = PGPclOpenClientPrefs (memMgr,&clientPrefsRef);
0faf5a
a8f69b ¤   if (IsntPGPError(err))
f7c7a1 ¤   {
ecdb03 ¤   ¤   err=CLInitKeyServerPrefs(PGPCL_DEFAULTSERVER,NULL,
ff0eb6 ¤   ¤   ¤   hWndParent,context,MainKeySet,clientPrefsRef,"",
1ba87d ¤   ¤   ¤   &pcss,&ksEntries,&serverList,&numKSEntries);
5eaf5a
4ab7bb ¤   ¤   PGPclCloseClientPrefs (clientPrefsRef, FALSE);
649371 ¤   }
c5af5a
7e2d4e ¤   optionList = kInvalidPGPOptionListRef;
19af5a
0b71ce ¤   // Everybody needs a passphrase buffer and a hwnd
2aa3d4 ¤   // If no length quality needed, zeros are default anyway
a59b1f ¤   err = PGPBuildOptionList( context, &optionList,
51390b ¤   ¤   ¤   PGPOUIOutputPassphrase( context, ppszPhrase ),
3fee83 ¤   ¤   ¤   PGPOUIParentWindowHandle( context, hWndParent ),
ce3e62 ¤   ¤   ¤   PGPOUIMinimumPassphraseLength(context,MinLength),
c93d86 ¤   ¤   ¤   PGPOUIMinimumPassphraseQuality(context,MinQuality),
619425 ¤   ¤   ¤   PGPOLastOption( context ) );
c3af5a
45b1f0 ¤   if( IsntPGPError( err ) )
cec7a1 ¤   {
d0b64a ¤   ¤   PGPUInt32¤  detachedSignature¤  = 0;
491a24 ¤   ¤   PGPUInt32¤  textOutput¤ ¤   ¤   = 0;
9222b7 ¤   ¤   Boolean¤¤   haveFileOptions ¤   = FALSE;
9caf5a
d9dfd0 ¤   ¤   // If we have a prompt, use it
545143 ¤   ¤   if( IsntNull( szPrompt ) )
205b34 ¤   ¤   {
43bab6 ¤   ¤   ¤   err = PGPAppendOptionList( optionList,
902c0f ¤   ¤   ¤   ¤   PGPOUIDialogPrompt( context, szPrompt ),
52929d ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
040fe4 ¤   ¤   }
451b52 ¤   ¤
e1e930 ¤   ¤   // If we have options, convert them to new options API
98ed32 ¤   ¤   if( IsntPGPError( err ) && ( puOptions != 0 ))
065b34 ¤   ¤   {
fe9a0b ¤   ¤   ¤   haveFileOptions = TRUE;
7baf5a
a50eba ¤   ¤   ¤   if( (*puOptions & PGPCL_DETACHEDSIG) != 0 )
0be65f ¤   ¤   ¤   ¤   detachedSignature = 1;
3baf5a
c8d9ed ¤   ¤   ¤   if( (*puOptions & PGPCL_ASCIIARMOR) != 0 )
08081e ¤   ¤   ¤   ¤   textOutput = 1;
--60f1 000c30ce0fc40110291 Page 3 of CLphrase.c
f11b52 ¤   ¤
5fe9c7 ¤   ¤   ¤   LoadString (g_hInst, IDS_DETACHEDSIG, StrRes1, sizeof(StrRes1));
0e7836 ¤   ¤   ¤   LoadString (g_hInst, IDS_TEXTOUTPUT, StrRes2, sizeof(StrRes2));
caaf5a
d0bab6 ¤   ¤   ¤   err = PGPAppendOptionList( optionList,
20afce ¤   ¤   ¤   ¤   ¤   PGPOUIDialogOptions( context,
946250 ¤   ¤   ¤   ¤   ¤   ¤   PGPOUICheckbox( context, 804,
426dd1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes1,NULL,
5ee6b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   detachedSignature, &detachedSignature ),
d75bed ¤   ¤   ¤   ¤   ¤   ¤   PGPOUICheckbox( context, 801,
38e701 ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes2,NULL,
e9b97c ¤   ¤   ¤   ¤   ¤   ¤   ¤   textOutput, &textOutput ),
e31899 ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) ),
77c000 ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
b80fe4 ¤   ¤   }
75af5a
bd86f8 ¤   ¤   if( IsntPGPError( err ) )
825b34 ¤   ¤   {
0a28ab ¤   ¤   ¤   // Conventional encryption passphrase needed
f0e7cd ¤   ¤   ¤   if(uFlags&PGPCL_ENCRYPTION)
1df776 ¤   ¤   ¤   {
f687ce ¤   ¤   ¤   ¤   PGPAppendOptionList( optionList,
ce3957 ¤   ¤   ¤   ¤   ¤   PGPOUIShowPassphraseQuality(context,TRUE),
cdc000 ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
35af5a
7141ab ¤   ¤   ¤   ¤   err=PGPConventionalEncryptionPassphraseDialog(context,
118012 ¤   ¤   ¤   ¤   ¤   optionList,
4ec000 ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
4aa3a6 ¤   ¤   ¤   }
b77d8f ¤   ¤   ¤   // We're decoding......
3859a1 ¤   ¤   ¤   else if(uFlags&PGPCL_DECRYPTION)
38f776 ¤   ¤   ¤   {
b8e72b ¤   ¤   ¤   ¤   PGPInt32 numKeys;
abaf5a
075199 ¤   ¤   ¤   ¤   numKeys=0;
5baf5a
023ac9 ¤   ¤   ¤   ¤   if(PGPRefIsValid(KeySet))
26c9ac ¤   ¤   ¤   ¤   ¤   PGPCountKeys( KeySet, &numKeys );
24af5a
1f1e0c ¤   ¤   ¤   ¤   // A conventionally encrypted file
446a08 ¤   ¤   ¤   ¤   if((numKeys==0)&&(uKeyCount==0))
7672c3 ¤   ¤   ¤   ¤   {
8d43cc ¤   ¤   ¤   ¤   ¤   err=PGPConventionalDecryptionPassphraseDialog(context,
f20bee ¤   ¤   ¤   ¤   ¤   ¤   optionList,
06931b ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
4a2613 ¤   ¤   ¤   ¤   }
385d55 ¤   ¤   ¤   ¤   // A RSA or DH encrypted file
08fa07 ¤   ¤   ¤   ¤   else
d872c3 ¤   ¤   ¤   ¤   {
95f910 ¤   ¤   ¤   ¤   ¤   if(pKey==NULL)
11e098 ¤   ¤   ¤   ¤   ¤   ¤   pKey=&decryptionKey;
d32b85 ¤   ¤   ¤   ¤
b7c85c ¤   ¤   ¤   ¤   ¤   err=PGPDecryptionPassphraseDialog(
434ed0 ¤   ¤   ¤   ¤   ¤   ¤   context,¤   ¤   ¤   ¤   ¤   ¤   ¤
59baa8 ¤   ¤   ¤   ¤   ¤   ¤   KeySet,
0b8b6a ¤   ¤   ¤   ¤   ¤   ¤   uKeyCount,
47ec96 ¤   ¤   ¤   ¤   ¤   ¤   pKeyIDs,
1e2b80 ¤   ¤   ¤   ¤   ¤   ¤   pKey, // for recon dialog
d90bee ¤   ¤   ¤   ¤   ¤   ¤   optionList,
15aabf ¤   ¤   ¤   ¤   ¤   ¤   PGPOUIKeyServerUpdateParams(context,
0ebed9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   numKSEntries, serverList,
94021b ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,FALSE,&foundKeys,
9d24b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) ),
b3931b ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
572613 ¤   ¤   ¤   ¤   }
a0a3a6 ¤   ¤   ¤   }
542e17 ¤   ¤   ¤   else if(uFlags&PGPCL_KEYPASSPHRASE)
f5f776 ¤   ¤   ¤   {
2ce393 ¤   ¤   ¤   ¤   err=PGPKeyPassphraseDialog(
9add42 ¤   ¤   ¤   ¤   ¤   context,
3d9e0e ¤   ¤   ¤   ¤   ¤   *pKey,
c38012 ¤   ¤   ¤   ¤   ¤   optionList,
--ff59 0002d21e6a440110291 Page 4 of CLphrase.c
96258c ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );·
37a3a6 ¤   ¤   ¤   }
e87c38 ¤   ¤   ¤   // We're signing something and need the combo box
45bb8c ¤   ¤   ¤   else
32f776 ¤   ¤   ¤   {
e2d3e5 ¤   ¤   ¤   ¤   err = PGPSigningPassphraseDialog( context, MainKeySet,
3ec53e ¤   ¤   ¤   ¤   ¤   pKey,
bf8012 ¤   ¤   ¤   ¤   ¤   optionList,
1ca3ce ¤   ¤   ¤   ¤   ¤   PGPOUIDefaultKey( context, *pKey ),
43c000 ¤   ¤   ¤   ¤   ¤   PGPOLastOption( context ) );
07a3a6 ¤   ¤   ¤   }
080fe4 ¤   ¤   }
c5af5a
261d72 ¤   ¤   // Shared key has been selected. Go to reconstitution dialog
ca7aba ¤   ¤   if(((err==kPGPError_KeyUnusableForSignature)||
24cc70 ············(err==kPGPError_KeyUnusableForDecryption)) &&
59f7eb ¤   ¤   ····(!(uFlags & PGPCL_REJECTSPLITKEYS)))
9f5b34 ¤   ¤   {
bb8f66 ¤   ¤   ¤   if((ppPasskeyBuffer!=NULL)&&(piPasskeyLength!=NULL)&&(pKey!=NULL))
55f776 ¤   ¤   ¤   {
551872 ¤   ¤   ¤   ¤   err=PGPclReconstituteKey(
4add42 ¤   ¤   ¤   ¤   ¤   context,
530d23 ¤   ¤   ¤   ¤   ¤   tlsContext,
012aa3 ¤   ¤   ¤   ¤   ¤   hWndParent,
025656 ¤   ¤   ¤   ¤   ¤   MainKeySet,
9c9e0e ¤   ¤   ¤   ¤   ¤   *pKey,
537458 ¤   ¤   ¤   ¤   ¤   ppPasskeyBuffer,
5685d3 ¤   ¤   ¤   ¤   ¤   piPasskeyLength);
0da3a6 ¤   ¤   ¤   }
580fe4 ¤   ¤   }
21af5a
02247d ¤   ¤   if( (IsntPGPError(err)) &&·
578194 ¤   ¤   ¤   (ppPasskeyBuffer!=NULL) &&
31cd3f ¤   ¤   ¤   (piPasskeyLength!=NULL) &&
6f2149 ¤   ¤   ¤   (pKey!=NULL))
505b34 ¤   ¤   {
70e6d2 ¤   ¤   ¤   // Convert passphrase to passkey
afa563 ¤   ¤   ¤   if((*ppPasskeyBuffer==NULL)&&(*pKey!=NULL)&&(*ppszPhrase!=NULL))
9f2b85 ¤   ¤   ¤   ¤
04f776 ¤   ¤   ¤   {
e7e8e7 ¤   ¤   ¤   ¤   if (lstrlen(*ppszPhrase)>0)·
7772c3 ¤   ¤   ¤   ¤   {
43d87b ¤   ¤   ¤   ¤   ¤   PGPUInt32 uKeyLockingBits;
8caf5a
576e5f ¤   ¤   ¤   ¤   ¤   PGPGetKeyNumber (*pKey, kPGPKeyPropLockingBits,·
cded2b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &uKeyLockingBits);
3faf5a
9de7b4 ¤   ¤   ¤   ¤   ¤   *piPasskeyLength=(uKeyLockingBits+7)/8; // Bits to bytes
6af5b7 ¤   ¤   ¤   ¤   ¤   *ppPasskeyBuffer=
28448b ¤   ¤   ¤   ¤   ¤   ¤   (PGPByte *)secAlloc(context,*piPasskeyLength);
85af5a
e7ebb0 ¤   ¤   ¤   ¤   ¤   err = PGPGetKeyPasskeyBuffer(*pKey, *ppPasskeyBuffer,
7679a9 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase(context, *ppszPhrase),
96afea ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
342613 ¤   ¤   ¤   ¤   }
605109 ¤   ¤   ¤   ¤   else·
e572c3 ¤   ¤   ¤   ¤   {
b55c92 ¤   ¤   ¤   ¤   ¤   *piPasskeyLength=0;
34e969 ¤   ¤   ¤   ¤   ¤   *ppPasskeyBuffer=NULL;
ee2613 ¤   ¤   ¤   ¤   }
6ba3a6 ¤   ¤   ¤   }
2d0fe4 ¤   ¤   }
baaf5a
591c41 ¤   ¤   // If we had options, read the results and send em back
de3f05 ¤   ¤   if( IsntPGPError( err ) && haveFileOptions )
e95b34 ¤   ¤   {
575ed4 ¤   ¤   ¤   *puOptions = 0;
0b87c7 ¤   ¤   ¤
59f335 ¤   ¤   ¤   if( detachedSignature != 0 )
234d79 ¤   ¤   ¤   ¤   *puOptions |= PGPCL_DETACHEDSIG;
292b85 ¤   ¤   ¤   ¤
2d066c ¤   ¤   ¤   if( textOutput != 0 )
--89b0 001aad28f1640110291 Page 5 of CLphrase.c
5a81ee ¤   ¤   ¤   ¤   *puOptions |= PGPCL_ASCIIARMOR;
7b0fe4 ¤   ¤   }
141b52 ¤   ¤
6b153d ¤   ¤   PGPFreeOptionList( optionList );
909371 ¤   }
a5af5a
1c6682 ¤   CLUninitKeyServerPrefs(PGPCL_DEFAULTSERVER,
22cfdc ¤   ¤   pcss,ksEntries,serverList,numKSEntries);
daaf5a
8ab28f ¤   if(AddedKeys!=NULL)
6bc7a1 ¤   {
e8919c ¤   ¤   *AddedKeys=foundKeys;
8f9371 ¤   }
dc0e24 ¤   else
78c7a1 ¤   {
ccdb0a ¤   ¤   if(PGPRefIsValid(foundKeys))
755543 ¤   ¤   ¤   PGPFreeKeySet(foundKeys);
0a9371 ¤   }
5eaf5a
03c7fd ¤   return(err);
d8efe6 }
aaaf5a
--1b11 000c386cb9540110292 Page 1 of CLprefs.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
bfca9a ¤   CLprefs.c - handle PGP preferences dialogs
5367c5 ¤
6baf5a
d613a2 ¤   $Id: CLprefs.c,v 1.44 1998/08/11 14:43:11 pbj Exp $
5af7f7 ____________________________________________________________________________*/
c1e610 #include "pgpPFLConfig.h"
80fb64 #include <direct.h>
71af5a
c4c917 // project header files
4a5fcd #include "pgpclx.h"
cfaf5a
01fc2c // system header files
e66bd4 #include <commdlg.h>
82af5a
97ec79 #define MAXCACHETIMELIMIT¤  ¤   360000
342cb4 #define MAXWIPEPASSES¤  ¤   ¤   32
13af5a
8e0401 #define PREFSEMAPHORENAME¤  ("PGPprefsInstSem")
8caf5a
2e76ea // default preferences
82f7a6 #define DEFAULT_ENCRYPTTOSELF¤  ¤   ¤   FALSE
9f8457 #define DEFAULT_DECRYPTCACHEENABLE¤ ¤   TRUE
ed3e9f #define DEFAULT_DECRYPTCACHESECONDS¤¤   120
8ec5ab #define DEFAULT_SIGNCACHEENABLE¤¤   ¤   FALSE
db4d8a #define DEFAULT_SIGNCACHESECONDS¤   ¤   120
22d62b #define DEFAULT_USEFASTKEYGEN¤  ¤   ¤   TRUE
e364a2 #define¤DEFAULT_WIPECONFIRM¤¤   ¤   ¤   TRUE
25da4e #define DEFAULT_MAILENCRYPTPGPMIME¤ ¤   FALSE
23b4f6 #define DEFAULT_WORDWRAPWIDTH¤  ¤   ¤   70
438fd7 #define DEFAULT_WORDWRAPENABLE¤ ¤   ¤   TRUE
68e843 #define DEFAULT_MAILENCRYPTDEFAULT¤ ¤   FALSE
ce291e #define DEFAULT_MAILSIGNDEFAULT¤¤   ¤   FALSE
2148bd #define DEFAULT_AUTODECRYPT¤¤   ¤   ¤   FALSE
88096c #define DEFAULT_KEYSERVERSYNCONUNKNOWN¤ FALSE
6da788 #define DEFAULT_KEYSERVERSYNCONADDNAME¤ FALSE
dcc7f2 #define DEFAULT_KEYSERVERSYNCONKEYSIGN¤ FALSE
114cca #define DEFAULT_KEYSERVERSYNCONREVOKE¤  FALSE
7dc983 #define DEFAULT_KEYSERVERSYNCONVERIFY¤  FALSE
65771f #define DEFAULT_PREFERREDALGORITHM¤ ¤   kPGPCipherAlgorithm_CAST5
20bcd4 #define DEFAULT_DISPLAYMARGVALIDITY¤¤   TRUE
b20bb5 #define DEFAULT_MARGVALIDISINVALID¤ ¤   TRUE
6aa47b #define DEFAULT_WARNONADK¤  ¤   ¤   ¤   TRUE
b6d0e1 #define DEFAULT_WIPEPASSES¤ ¤   ¤   ¤   1
220ade #define DEFAULT_EXPORTCOMPATIBLE¤   ¤   TRUE
c0af5a
7f3ff6 #define COMMENTBLOCK_MAX_LENGTH¤¤   ¤   60
d9af5a
6b93ed // external globals
809cad extern HINSTANCE g_hInst;
e70afe extern CHAR g_szHelpFile[MAX_PATH];
86af5a
c7492e // local globals
79018f static PGPContextRef¤   ContextRef;
8aaf5a
7ca5dd static HWND¤¤   ¤   ¤   hWndParent;
a635ec static HWND¤¤   ¤   ¤   hWndTree;
2ddcb0 static PGPKeySetRef¤¤   keysetMain;
8e8666 static PGPError¤¤   ¤   returnErr;
9b8a48 static BOOL¤¤   ¤   ¤   bNeedsCentering;
874340 static BOOL¤¤   ¤   ¤   bPrefsWritten;
b065cb static BOOL¤¤   ¤   ¤   bReloadKeyring;
4a78a7 static BOOL¤¤   ¤   ¤   bKeyserverPrefsWritten;
ea2e4a static PGPPrefRef¤  ¤   PrefRefClient;
de79b6 static PGPPrefRef¤  ¤   PrefRefAdmin;
b5ef90 static CHAR¤¤   ¤   ¤   szInitDir[MAX_PATH];
cbaf5a
88f0f7 typedef struct {
c39e62 ¤   HWND¤   ¤   hwndDecryptDuration;
--88b2 000a167d40440110292 Page 2 of CLprefs.c
e55746 ¤   SYSTEMTIME¤ stDecryptDuration;
2e0609 ¤   HWND¤   ¤   hwndSignDuration;
dc0656 ¤   SYSTEMTIME¤ stSignDuration;
34e0dd } CACHEDURATIONSTRUCT, *PCACHEDURATIONSTRUCT;
f5af5a
a2af5a
5777e3 static DWORD aGeneralIds[] = {¤ ¤   ¤   // Help IDs
94b8a3 ····IDC_ENCRYPTTOSELF,¤ ¤   IDH_PGPCLPREF_ENCRYPTTOSELF,·
3d17d8 ¤   IDC_USEFASTKEYGEN,¤ ¤   IDH_PGPCLPREF_USEFASTKEYGEN,
c56380 ¤   IDC_DECRYPTCACHEENABLE,¤IDH_PGPCLPREF_PASSCACHEENABLE,
6d39e0 ¤   IDC_DECRYPTCACHETIME,¤  IDH_PGPCLPREF_PASSCACHETIME,
46e9e9 ¤   IDC_SIGNCACHEENABLE,¤   IDH_PGPCLPREF_SIGNCACHEENABLE,
10243a ¤   IDC_SIGNCACHETIME,¤ ¤   IDH_PGPCLPREF_SIGNCACHETIME,
cc523f ¤   IDC_COMMENTBLOCK,¤  ¤   IDH_PGPCLPREF_COMMENTBLOCK,
7c422b ¤   IDC_WIPECONFIRM,¤   ¤   IDH_PGPCLPREF_WIPECONFIRM,
e5b512 ¤   IDC_NUMPASSES,¤ ¤   ¤   IDH_PGPCLPREF_NUMWIPEPASSES,
0f3ee4 ¤   IDC_NUMPASSESSPIN,¤ ¤   IDH_PGPCLPREF_NUMWIPEPASSESSPIN,
3e87cd ¤   IDC_NUMPASSESTEXT,¤ ¤   IDH_PGPCLPREF_NUMWIPEPASSES,
801e2c ¤   0,0
7982f7 };
c3af5a
934e01 static DWORD aFileIds[] = {¤¤   ¤   // Help IDs
a177a2 ····IDC_PRIVATEKEYRING,¤¤   IDH_PGPCLPREF_PRIVATEKEYRING,·
8ab64a ¤   IDC_SETPRIVATEKEYRING,¤ IDH_PGPCLPREF_BROWSEPRIVATEKEYRING,
737f73 ····IDC_PUBLICKEYRING,¤ ¤   IDH_PGPCLPREF_PUBLICKEYRING,·
8a19cf ¤   IDC_SETPUBLICKEYRING,¤  IDH_PGPCLPREF_BROWSEPUBLICKEYRING,
3cdfe4 ¤   IDC_RNGSEEDFILE,¤   ¤   IDH_PGPCLPREF_RANDOMSEEDFILE,
ea4ebb ¤   IDC_SETRNGSEEDFILE,¤¤   IDH_PGPCLPREF_BROWSERANDOMSEEDFILE,
fb1e2c ¤   0,0
c582f7 };
b4af5a
f8e9ef static DWORD aEmailIds[] = {¤   ¤   ¤   // Help IDs
9a8425 ¤   IDC_USEPGPMIME,¤¤   IDH_PGPCLPREF_USEPGPMIME,
829d96 ¤   IDC_ENCRYPTBYDEFAULT,¤  IDH_PGPCLPREF_ENCRYPTBYDEFAULT,
234c54 ¤   IDC_SIGNBYDEFAULT,¤ ¤   IDH_PGPCLPREF_SIGNBYDEFAULT,
42f851 ¤   IDC_AUTODECRYPT,¤   ¤   IDH_PGPCLPREF_AUTODECRYPT,
657ab3 ¤   IDC_WRAPENABLE,¤¤   ¤   IDH_PGPCLPREF_WORDWRAPENABLE,
20ef65 ¤   IDC_WRAPNUMBER,¤¤   ¤   IDH_PGPCLPREF_WORDWRAPCOLUMN,
2f1e2c ¤   0,0
5182f7 };
abaf5a
9618c8 static DWORD aServerIds[] = {¤  ¤   ¤   // Help IDs
5b72ec ¤   IDC_NEWKEYSERVER,¤  ¤   IDH_PGPCLPREF_CREATESERVER,
870be1 ¤   IDC_REMOVEKEYSERVER,¤   IDH_PGPCLPREF_REMOVESERVER,
2b2587 ¤   IDC_EDITKEYSERVER,¤ ¤   IDH_PGPCLPREF_EDITSERVER,
eac88a ¤   IDC_SETASROOT,¤ ¤   ¤   IDH_PGPCLPREF_SETROOTSERVER,
cd3b4d ¤   IDC_SYNCONUNKNOWN,¤ ¤   IDH_PGPCLPREF_SYNCONUNKNOWNKEYS,
0bd90d ¤   IDC_SYNCONADDNAME,¤ ¤   IDH_PGPCLPREF_SYNCONADDNAME,
a6db7a ¤   IDC_SYNCONKEYSIGN,¤ ¤   IDH_PGPCLPREF_SYNCONSIGN,
cfd54b ¤   IDC_SYNCONREVOKE,¤  ¤   IDH_PGPCLPREF_SYNCONREVOKE,
d0c670 ¤   IDC_SYNCONVERIFY,¤  ¤   IDH_PGPCLPREF_SYNCONVERIFY,
45d947 ¤   IDC_KSTREELIST,¤¤   ¤   IDH_PGPCLPREF_SERVERLIST,
761e2c ¤   0,0
9782f7 };
86af5a
86509d static DWORD aAdvancedIds[] = {¤¤   ¤   // Help IDs
6a7858 ¤   IDC_PREFERREDALG,¤  ¤   IDH_PGPCLPREF_PREFERREDALG,
7d80ee ¤   IDC_ENABLECAST,¤¤   ¤   IDH_PGPCLPREF_ENABLECAST,
3d9187 ¤   IDC_ENABLE3DES,¤¤   ¤   IDH_PGPCLPREF_ENABLE3DES,
4b1ba7 ¤   IDC_ENABLEIDEA,¤¤   ¤   IDH_PGPCLPREF_ENABLEIDEA,
9592a6 ¤   IDC_DISPMARGVALIDITY,¤  IDH_PGPCLPREF_DISPMARGVALIDITY,
66bf9e ¤   IDC_MARGVALIDISINVALID,¤IDH_PGPCLPREF_WARNONMARGINAL,
bfca39 ¤   IDC_WARNONADK,¤ ¤   ¤   IDH_PGPCLPREF_WARNONADK,
36f4be ¤   IDC_EXPORTCOMPATIBLE,¤  IDH_PGPCLPREF_EXPORTCOMPATIBLE,
fd046c ¤   IDC_EXPORTCOMPLETE,¤¤   IDH_PGPCLPREF_EXPORTCOMPLETE,
9a4434 ····0,0·
82a6fe };·
fcaf5a
40d4d4 //¤ ______________________________________________
c0465d //
b6897b // ·Get standard client preferences file reference
a1af5a
--0f03 000f60a086240110292 Page 3 of CLprefs.c
22ec6d PGPError PGPclExport
7638a9 PGPclOpenClientPrefs (
1cc031 ¤   ¤   PGPMemoryMgrRef¤memMgr,·
8e9535 ¤   ¤   PGPPrefRef*¤¤   pPrefRef)·
31bb36 {
09a88e ¤   CHAR¤   ¤   ¤   szPath[MAX_PATH];
28195e ¤   CHAR¤   ¤   ¤   sz[64];
ecfb19 ¤   PGPError¤   ¤   err;
81f4ab ¤   PFLFileSpecRef¤ FileRef;
fd3bc6 ¤   PGPPrefRef¤ ¤   ClientPrefRef;
2867c5 ¤
1796b9 ¤   err = PGPclGetPGPPath (szPath, sizeof(szPath));
e70971 ¤   if (IsPGPError (err)) {
595260 ¤   ¤   GetWindowsDirectory (szPath, sizeof(szPath));
b8a610 ¤   ¤   if (szPath[lstrlen(szPath)-1] != '\\') lstrcat (szPath, "\\");
639371 ¤   }
96af5a
eda288 ¤   LoadString (g_hInst, IDS_CLIENTPREFSFILE, sz, sizeof(sz));
aa7429 ¤   lstrcat (szPath, sz);
b7af5a
60249d ¤   PFLNewFileSpecFromFullPath (memMgr, szPath, &FileRef);
5baf5a
2aee36 ¤   err = PGPOpenPrefFile (FileRef, clientDefaults, clientDefaultsSize,·
72e455 ¤   ¤   ¤   &ClientPrefRef);
d2d57d ¤   if ((err == kPGPError_FileOpFailed) ||
03bfea ¤   ¤   (err == kPGPError_FileNotFound)) {
36ddf6 ¤   ¤   err = PFLFileSpecCreate (FileRef);
08e50b ¤   ¤   pgpAssert (IsntPGPError (err));
9d1f4b ¤   ¤   err = PGPOpenPrefFile(FileRef, clientDefaults, clientDefaultsSize,
8d5f03 ¤   ¤   ¤   ¤   &ClientPrefRef);
a2e50b ¤   ¤   pgpAssert (IsntPGPError (err));
279371 ¤   }
b157c4 ¤   PFLFreeFileSpec (FileRef);
01af5a
550971 ¤   if (IsPGPError (err)) {
8c3609 ¤   ¤   if (PGPRefIsValid (ClientPrefRef))·
98dc9f ¤   ¤   ¤   PGPClosePrefFile (ClientPrefRef);
059371 ¤   }
c4670c ¤   else {¤
817a67 ¤   ¤   *pPrefRef = ClientPrefRef;
ff9371 ¤   }
58af5a
2c5ea8 ¤   return err;
9aefe6 }
90af5a
48d4d4 //¤ ______________________________________________
b7465d //
acdf0e // ·Get standard admin preferences file reference
1aaf5a
4fec6d PGPError PGPclExport
5b5eef PGPclOpenAdminPrefs (
a863c2 ¤   ¤   PGPMemoryMgrRef¤memMgr,
44ac88 ¤   ¤   PGPPrefRef*¤¤   pPrefRef,·
d28786 ¤   ¤   BOOL¤   ¤   ¤   bLoadDefaults)·
1cbb36 {
837f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
7af450 ¤   PGPPrefRef¤ ¤   AdminPrefRef¤   ¤   = kInvalidPGPPrefRef;
76a88e ¤   CHAR¤   ¤   ¤   szPath[MAX_PATH];
1e195e ¤   CHAR¤   ¤   ¤   sz[64];
47f4ab ¤   PFLFileSpecRef¤ FileRef;
f1eb44 ¤   DWORD¤  ¤   ¤   dw;
29af5a
0696b9 ¤   err = PGPclGetPGPPath (szPath, sizeof(szPath));
8b0971 ¤   if (IsPGPError (err)) {
1e5260 ¤   ¤   GetWindowsDirectory (szPath, sizeof(szPath));
cea610 ¤   ¤   if (szPath[lstrlen(szPath)-1] != '\\') lstrcat (szPath, "\\");
8a9371 ¤   }
afaf5a
44a156 ¤   LoadString (g_hInst, IDS_ADMINPREFSFILE, sz, sizeof(sz));
e77429 ¤   lstrcat (szPath, sz);
e9af5a
f697a8 ¤   // check for file existence
--1431 00050328fd040110292 Page 4 of CLprefs.c
511d52 ¤   dw = GetFileAttributes (szPath);
f08d97 ¤   if ((dw == 0xFFFFFFFF) || (dw & FILE_ATTRIBUTE_DIRECTORY)) {
0d1081 ¤   ¤   if (!bLoadDefaults)
f4dba7 ¤   ¤   ¤   err = kPGPError_FileNotFound;
5e9371 ¤   }
77af5a
6eb23e ¤   if (IsntPGPError (err)) {
51247f ¤   ¤   PFLNewFileSpecFromFullPath (memMgr, szPath, &FileRef);
5baf5a
d9e529 ¤   ¤   err = PGPOpenPrefFile (FileRef, adminDefaults, adminDefaultsSize,
224b4a ¤   ¤   ¤   ¤   &AdminPrefRef);
04af5a
b2dbbb ¤   ¤   PFLFreeFileSpec (FileRef);
b29371 ¤   }
9eaf5a
9d0971 ¤   if (IsPGPError (err)) {
304e4c ¤   ¤   PGPclMessageBox (NULL, IDS_CAPTIONERROR, IDS_NOADMINFILE,
d97ece ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
4ddd75 ¤   ¤   if (PGPRefIsValid (AdminPrefRef))·
55e7bd ¤   ¤   ¤   PGPClosePrefFile (AdminPrefRef);
549371 ¤   }
ee670c ¤   else {¤
69daca ¤   ¤   *pPrefRef = AdminPrefRef;
149371 ¤   }
35af5a
2b5ea8 ¤   return err;
86efe6 }
ffaf5a
e3a50c //¤ _______________________________________
d1465d //
85c662 // ·Save and close down client preferences file
95af5a
1aec6d PGPError PGPclExport
68b835 PGPclCloseClientPrefs (
a52396 ¤   ¤   PGPPrefRef¤ PrefRef,·
72e63c ¤   ¤   BOOL¤   ¤   bSave)·
16bb36 {
a9fb19 ¤   PGPError¤   ¤   err;
e7af5a
438626 ¤   if (bSave) {
9b3ea4 ¤   ¤   err = PGPSavePrefFile (PrefRef);
351c74 ¤   ¤   pgpAssert (IsntPGPError(err));
939371 ¤   }
93af5a
6c6ec4 ¤   err = PGPClosePrefFile (PrefRef);
595d87 ¤   pgpAssert (IsntPGPError(err));
a5af5a
2c5ea8 ¤   return err;
97efe6 }
4daf5a
37a50c //¤ _______________________________________
2a465d //
7e9da7 // ·Save and close down admin preferences file
b9af5a
3aec6d PGPError PGPclExport
40ea2b PGPclCloseAdminPrefs (
ff2396 ¤   ¤   PGPPrefRef¤ PrefRef,·
47e63c ¤   ¤   BOOL¤   ¤   bSave)·
6cbb36 {
3bfb19 ¤   PGPError¤   ¤   err;
79af5a
048626 ¤   if (bSave) {
7a3ea4 ¤   ¤   err = PGPSavePrefFile (PrefRef);
291c74 ¤   ¤   pgpAssert (IsntPGPError(err));
9a9371 ¤   }
8faf5a
136ec4 ¤   err = PGPClosePrefFile (PrefRef);
da5d87 ¤   pgpAssert (IsntPGPError(err));
35af5a
0e5ea8 ¤   return err;
37efe6 }
50af5a
--87df 000a98cf73440110292 Page 5 of CLprefs.c
917f37 //¤ ____________________________
7c465d //
b5b5ef // ·Check for illegal file names
1eaf5a
8e6c77 static BOOL·
860561 sIsFileNameOK (LPSTR sz)·
02bb36 {
8a8a2a ¤   UINT¤   uLen;
abb251 ¤   DWORD¤  dwAttrib;
b0af5a
a6a8b8 ¤   uLen = lstrlen (sz);
afaf5a
a310d3 ¤   if (uLen < 4) return FALSE;
8bf77a ¤   if ((sz[1] != ':') && (sz[1] != '\\')) return FALSE;
88dc6f ¤   if ((sz[1] == ':') && (sz[2] != '\\')) return FALSE;
17e3a4 ¤   if (strcspn (sz, "/*?""<>|") != uLen) return FALSE;
218940 ¤   if (sz[uLen-1] == ':') return FALSE;
719987 ¤   if (sz[uLen-1] == '\\') return FALSE;
b7af5a
76c861 ¤   dwAttrib = GetFileAttributes (sz);
e3f427 ¤   if (dwAttrib == 0xFFFFFFFF) return TRUE;¤   // file doesn't exist
1452d0 ¤   if (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) return FALSE;
5ce912 ¤   if (dwAttrib & FILE_ATTRIBUTE_SYSTEM) return FALSE;
eeaf5a
73c2e7 ¤   return TRUE;
1defe6 }
04af5a
363fc0 //¤ _____________________________________________________
62465d //
ecc353 // ·verify that file or backup of file exists. ·
d66998 //¤ if not, replace with default file name in install dir
0b6db8 //¤ if no install dir found, use Windows dir
bbaf5a
70e6b2 static VOID
9c88b5 sVerifyFileExists (LPSTR lpszFile, PGPBoolean KeyRing)
51bb36 {
a0c9fb ¤   CHAR¤   sz[MAX_PATH];
d1b251 ¤   DWORD¤  dwAttrib;
737cd6 ¤   CHAR*¤  p;
81af5a
884031 ¤   dwAttrib = GetFileAttributes (lpszFile);
4188c8 ¤   if ((dwAttrib == 0xFFFFFFFF) ||·
332efb ¤   ¤   ¤   (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
8e1e41 ¤   ¤   lstrcpy (sz, lpszFile);
523a8c ¤   ¤   p = strrchr (sz, '\\');
a422cf ¤   ¤   if (p) p++;
707c93 ¤   ¤   else p = sz;
01af5a
6c14c4 ¤   ¤   if (IsPGPError (PGPclGetPGPPath (lpszFile, MAX_PATH)))·
ae46f2 ¤   ¤   ¤   GetWindowsDirectory (lpszFile, MAX_PATH);
5f0e1d ¤   ¤   else
8f5b34 ¤   ¤   {
d01dfe ¤   ¤   ¤   if(KeyRing)
e9f776 ¤   ¤   ¤   {
01415f ¤   ¤   ¤   ¤   // We don't really want install directory.. we want·
4d85c1 ¤   ¤   ¤   ¤   // PGP Keyrings subdirectory. Otherwise we'll just·
b51fdb ¤   ¤   ¤   ¤   // take windows like everything else -wjb
d3af5a
c4a40f ¤   ¤   ¤   ¤   CHAR¤   sz2[128];
6aaf5a
47e291 ¤   ¤   ¤   ¤   if (lpszFile[lstrlen (lpszFile) -1] != '\\')·
c95ac2 ¤   ¤   ¤   ¤   ¤   lstrcat (lpszFile, "\\");
72af5a
3ac760 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KEYRINGFOLDER, sz2, sizeof(sz2));
b08602 ¤   ¤   ¤   ¤   lstrcat (lpszFile, sz2);
b4af5a
ce6c9c ¤   ¤   ¤   ¤   _mkdir (lpszFile); // just in case user deleted it
0ca3a6 ¤   ¤   ¤   }
2e0fe4 ¤   ¤   }
13af5a
8203e6 ¤   ¤   if (lpszFile[lstrlen (lpszFile) -1] != '\\')·
a95fe9 ¤   ¤   ¤   lstrcat (lpszFile, "\\");
--9195 00085c03f3740110292 Page 6 of CLprefs.c
9339c6 ¤   ¤   lstrcat (lpszFile, p);
d19371 ¤   }
bdefe6 }
c1af5a
383fc0 //¤ _____________________________________________________
f5465d //
4c999d // ·Message processing function for property sheet dialog
d9af5a
e85678 static LRESULT WINAPI·
fb7eab sFilePropDlgProc (
403a3a ¤   ¤   HWND¤   hDlg,·
a8eb77 ¤   ¤   UINT¤   uMsg,·
3217d4 ¤   ¤   WPARAM¤ wParam,·
67c0b8 ¤   ¤   LPARAM¤ lParam)·
14bb36 {
080b76 ¤   OPENFILENAME¤   OpenFileName;
d563e2 ¤   CHAR¤   ¤   ¤   szFile[MAX_PATH];
791c86 ¤   CHAR¤   ¤   ¤   szRing[MAX_PATH];
de98b3 ¤   CHAR¤   ¤   ¤   szTemp[MAX_PATH];
f99eff ¤   CHAR¤   ¤   ¤   szFilter[128];
e96a6e ¤   CHAR¤   ¤   ¤   szTitle[128];
0fc93b ¤   CHAR¤   ¤   ¤   szDefExt[8];
e3cf2b ¤   CHAR*¤  ¤   ¤   p;
1e1b38 ¤   HWND¤   ¤   ¤   hParent;
5b1372 ¤   RECT¤   ¤   ¤   rc;
37fb19 ¤   PGPError¤   ¤   err;
63ddc4 ¤   PGPFileSpecRef¤ fileRef;
3eb47b ¤   LPSTR¤  ¤   ¤   lpsz;
2b0b49 ¤   HANDLE¤ ¤   ¤   hfile;
a467c5 ¤
79347f ¤   switch (uMsg) {
89af5a
f22940 ¤   case WM_INITDIALOG:
2a4433 ¤   ¤   if (bNeedsCentering) {
b59ecf ¤   ¤   ¤   hParent = GetParent (hDlg);
58d699 ¤   ¤   ¤   GetWindowRect (hParent, &rc);
faa58a ¤   ¤   ¤   SetWindowPos (hParent, NULL,
7373f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
c98186 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
11f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
4323ad ¤   ¤   ¤   bNeedsCentering = FALSE;
370fe4 ¤   ¤   }
0baf5a
e62869 ¤   ¤   err = PGPsdkPrefGetFileSpec (ContextRef, kPGPsdkPref_PublicKeyring,
b1fe73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileRef);
409eae ¤   ¤   if (IsntPGPError (err) && fileRef) {
e9d812 ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileRef, &lpsz);
746350 ¤   ¤   ¤   lstrcpy (szTemp, lpsz);
570d66 ¤   ¤   ¤   PGPFreeData (lpsz);
448e29 ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
41af5a
833a67 ¤   ¤   ¤   sVerifyFileExists (szTemp, TRUE);
5ec336 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PUBLICKEYRING, szTemp);
2c0fe4 ¤   ¤   }
44af5a
dd83a1 ¤   ¤   err = PGPsdkPrefGetFileSpec (ContextRef, kPGPsdkPref_PrivateKeyring,
28fe73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileRef);
079eae ¤   ¤   if (IsntPGPError (err) && fileRef) {
59d812 ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileRef, &lpsz);
b36350 ¤   ¤   ¤   lstrcpy (szTemp, lpsz);
340d66 ¤   ¤   ¤   PGPFreeData (lpsz);
608e29 ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
2faf5a
e63a67 ¤   ¤   ¤   sVerifyFileExists (szTemp, TRUE);
5b56ad ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PRIVATEKEYRING, szTemp);
960fe4 ¤   ¤   }
81af5a
9f23b5 ¤   ¤   err = PGPsdkPrefGetFileSpec (ContextRef, kPGPsdkPref_RandomSeedFile,
05fe73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileRef);
0c9eae ¤   ¤   if (IsntPGPError (err) && fileRef) {
74d812 ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileRef, &lpsz);
856350 ¤   ¤   ¤   lstrcpy (szTemp, lpsz);
--7f61 000203345f540110292 Page 7 of CLprefs.c
a20d66 ¤   ¤   ¤   PGPFreeData (lpsz);
278e29 ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
95af5a
808cf5 ¤   ¤   ¤   sVerifyFileExists (szTemp, FALSE);
05acf2 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RNGSEEDFILE, szTemp);
920fe4 ¤   ¤   }
c1af5a
ba9a7b ¤   ¤   szInitDir[0] = '\0';
cfaf5a
00836c ¤   ¤   return TRUE;
beaf5a
59c3eb ····case WM_HELP:·
46b426 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
30c1f8 ············HELP_WM_HELP, (DWORD) (LPSTR) aFileIds);·
888f13 ········break;·
56d83c ·
734fd8 ····case WM_CONTEXTMENU:·
045ad9 ········WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
037c4e ············(DWORD) (LPVOID) aFileIds);·
428f13 ········break;·
93af5a
4bd1d3 ¤   case WM_COMMAND :
721185 ¤   ¤   switch (LOWORD (wParam)) {
9a2fa5 ¤   ¤   case IDC_SETPRIVATEKEYRING :
66c632 ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PRIVATEKEYRING, szFile, sizeof(szFile));
215b2c ¤   ¤   ¤   if (GetFileAttributes (szFile) & FILE_ATTRIBUTE_DIRECTORY) {
84f70c ¤   ¤   ¤   ¤   lstrcpy (szInitDir, szFile);
c71fdb ¤   ¤   ¤   ¤   szFile[0] = '\0';
14a3a6 ¤   ¤   ¤   }
7ae543 ¤   ¤   ¤   else {
10aa0a ¤   ¤   ¤   ¤   if (szInitDir[0])
d5f0a8 ¤   ¤   ¤   ¤   ¤   szFile[0] = '\0';
e6a3a6 ¤   ¤   ¤   }
a6d539 ¤   ¤   ¤   LoadString (g_hInst, IDS_PRIVKEYRINGFILTER, szFilter,·
126fac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szFilter));
c1befa ¤   ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
21d528 ¤   ¤   ¤   LoadString (g_hInst, IDS_PRIVKEYCAPTION, szTitle,·
d2352d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTitle));
ba3cef ¤   ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
61b88c ¤   ¤   ¤   OpenFileName.hwndOwner ········= hDlg;
5c06b2 ¤   ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
33b8af ¤   ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
1d19f8 ¤   ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
3f36b9 ¤   ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
fa5fd3 ¤   ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
9d7ce9 ¤   ¤   ¤   OpenFileName.lpstrFile ········= szFile;
6d42f3 ¤   ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (szFile);
a8e4e1 ¤   ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
22277d ¤   ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
ae0830 ¤   ¤   ¤   OpenFileName.lpstrInitialDir ··= szInitDir;
88cd08 ¤   ¤   ¤   OpenFileName.lpstrTitle ·······= szTitle;
b4cb1d ¤   ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_HIDEREADONLY;
faad67 ¤   ¤   ¤   OpenFileName.nFileOffset ······= 0;
ab64ba ¤   ¤   ¤   OpenFileName.nFileExtension ···= 0;
4fafea ¤   ¤   ¤   LoadString (g_hInst, IDS_DEFPRIVRINGEXT, szDefExt,·
2e5476 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szDefExt));
dfb206 ¤   ¤   ¤   OpenFileName.lpstrDefExt ······= szDefExt;
0a4b9d ¤   ¤   ¤   OpenFileName.lCustData ········= 0;
b37ded ¤   ¤   ¤   if (GetOpenFileName (&OpenFileName)) {
7dce65 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PRIVATEKEYRING, szFile);
2ac301 ¤   ¤   ¤   ¤   if (OpenFileName.nFileOffset > 0)·
909201 ¤   ¤   ¤   ¤   ¤   szFile[OpenFileName.nFileOffset-1] = '\0';
35f70c ¤   ¤   ¤   ¤   lstrcpy (szInitDir, szFile);
36a3a6 ¤   ¤   ¤   }
79cdcb ¤   ¤   ¤   break;
a9af5a
5ed645 ¤   ¤   case IDC_SETPUBLICKEYRING :
86faf0 ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PUBLICKEYRING, szFile, sizeof(szFile));
4e5b2c ¤   ¤   ¤   if (GetFileAttributes (szFile) & FILE_ATTRIBUTE_DIRECTORY) {
99f70c ¤   ¤   ¤   ¤   lstrcpy (szInitDir, szFile);
871fdb ¤   ¤   ¤   ¤   szFile[0] = '\0';
20a3a6 ¤   ¤   ¤   }
--b947 0005cbcc09640110292 Page 8 of CLprefs.c
6ee543 ¤   ¤   ¤   else {
0faa0a ¤   ¤   ¤   ¤   if (szInitDir[0])
bcf0a8 ¤   ¤   ¤   ¤   ¤   szFile[0] = '\0';
6aa3a6 ¤   ¤   ¤   }
8da5d9 ¤   ¤   ¤   LoadString (g_hInst, IDS_PUBKEYRINGFILTER, szFilter,·
c16fac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szFilter));
04befa ¤   ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
5aec1a ¤   ¤   ¤   LoadString (g_hInst, IDS_PUBKEYCAPTION, szTitle, sizeof(szTitle));
b53cef ¤   ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
c1b88c ¤   ¤   ¤   OpenFileName.hwndOwner ········= hDlg;
7c06b2 ¤   ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
27b8af ¤   ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
be19f8 ¤   ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
4036b9 ¤   ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
095fd3 ¤   ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
5b7ce9 ¤   ¤   ¤   OpenFileName.lpstrFile ········= szFile;
b142f3 ¤   ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (szFile);
bae4e1 ¤   ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
91277d ¤   ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
470830 ¤   ¤   ¤   OpenFileName.lpstrInitialDir ··= szInitDir;
74cd08 ¤   ¤   ¤   OpenFileName.lpstrTitle ·······= szTitle;
becb1d ¤   ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_HIDEREADONLY;
03ad67 ¤   ¤   ¤   OpenFileName.nFileOffset ······= 0;
3664ba ¤   ¤   ¤   OpenFileName.nFileExtension ···= 0;
a4768e ¤   ¤   ¤   LoadString (g_hInst, IDS_DEFPUBRINGEXT, szDefExt,·
4d5476 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szDefExt));
64b206 ¤   ¤   ¤   OpenFileName.lpstrDefExt ······= szDefExt;
f94b9d ¤   ¤   ¤   OpenFileName.lCustData ········= 0;
f07ded ¤   ¤   ¤   if (GetOpenFileName (&OpenFileName)) {
566a1b ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PUBLICKEYRING, szFile);
d8c301 ¤   ¤   ¤   ¤   if (OpenFileName.nFileOffset > 0)·
469201 ¤   ¤   ¤   ¤   ¤   szFile[OpenFileName.nFileOffset-1] = '\0';
48f70c ¤   ¤   ¤   ¤   lstrcpy (szInitDir, szFile);
68a3a6 ¤   ¤   ¤   }
22cdcb ¤   ¤   ¤   break;
d9af5a
1e701d ¤   ¤   case IDC_SETRNGSEEDFILE :
58ebe6 ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_RNGSEEDFILE, szFile, sizeof(szFile));
785b2c ¤   ¤   ¤   if (GetFileAttributes (szFile) & FILE_ATTRIBUTE_DIRECTORY) {
0af70c ¤   ¤   ¤   ¤   lstrcpy (szInitDir, szFile);
211fdb ¤   ¤   ¤   ¤   szFile[0] = '\0';
5fa3a6 ¤   ¤   ¤   }
13e543 ¤   ¤   ¤   else {
1baa0a ¤   ¤   ¤   ¤   if (szInitDir[0])
f6f0a8 ¤   ¤   ¤   ¤   ¤   szFile[0] = '\0';
cca3a6 ¤   ¤   ¤   }
0a8362 ¤   ¤   ¤   LoadString (g_hInst, IDS_SEEDFILEFILTER, szFilter,·
0a6fac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szFilter));
dbbefa ¤   ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
c248b7 ¤   ¤   ¤   LoadString (g_hInst, IDS_SEEDFILECAPTION, szTitle,·
ee352d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szTitle));
193cef ¤   ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
6db88c ¤   ¤   ¤   OpenFileName.hwndOwner ········= hDlg;
d306b2 ¤   ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
78b8af ¤   ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
2b19f8 ¤   ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
e836b9 ¤   ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
8b5fd3 ¤   ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
c87ce9 ¤   ¤   ¤   OpenFileName.lpstrFile ········= szFile;
1442f3 ¤   ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (szFile);
cae4e1 ¤   ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
9a277d ¤   ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
d80830 ¤   ¤   ¤   OpenFileName.lpstrInitialDir ··= szInitDir;
92cd08 ¤   ¤   ¤   OpenFileName.lpstrTitle ·······= szTitle;
a2cb1d ¤   ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_HIDEREADONLY;
baad67 ¤   ¤   ¤   OpenFileName.nFileOffset ······= 0;
3e64ba ¤   ¤   ¤   OpenFileName.nFileExtension ···= 0;
5dcda5 ¤   ¤   ¤   LoadString (g_hInst, IDS_DEFSEEDFILEEXT, szDefExt,·
2c5476 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szDefExt));
feb206 ¤   ¤   ¤   OpenFileName.lpstrDefExt ······= szDefExt;
304b9d ¤   ¤   ¤   OpenFileName.lCustData ········= 0;
5c7ded ¤   ¤   ¤   if (GetOpenFileName (&OpenFileName)) {
--85f9 00022b0038640110292 Page 9 of CLprefs.c
6d7dda ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RNGSEEDFILE, szFile);
85c301 ¤   ¤   ¤   ¤   if (OpenFileName.nFileOffset > 0)·
199201 ¤   ¤   ¤   ¤   ¤   szFile[OpenFileName.nFileOffset-1] = '\0';
8af70c ¤   ¤   ¤   ¤   lstrcpy (szInitDir, szFile);
bfa3a6 ¤   ¤   ¤   }
a6cdcb ¤   ¤   ¤   break;
7d0fe4 ¤   ¤   }
8d2f68 ¤   ¤   break;
7eaf5a
ce1431 ¤   case WM_NOTIFY :
230f7c ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
59af5a
2d2bc0 ¤   ¤   case PSN_SETACTIVE :
a3cdcb ¤   ¤   ¤   break;
cfaf5a
681b03 ¤   ¤   case PSN_HELP :
c3da62 ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
885315 ¤   ¤   ¤   ¤   IDH_PGPCLPREF_FILEDIALOG);·
83cdcb ¤   ¤   ¤   break;
cdaf5a
0e27ec ¤   ¤   case PSN_APPLY :
a3d85e ¤   ¤   ¤   // get current private keyring file
095799 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (ContextRef,·
dafbe7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PrivateKeyring, &fileRef);
27cc33 ¤   ¤   ¤   if (IsntPGPError (err) && fileRef) {
bcfea7 ¤   ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileRef, &lpsz);
eb5c65 ¤   ¤   ¤   ¤   lstrcpy (szRing, lpsz);
be869a ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
a9996a ¤   ¤   ¤   ¤   // compare with selected file and set pref if different
6f9f84 ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PRIVATEKEYRING, szFile,·
7fb856 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szFile));
d63eaa ¤   ¤   ¤   ¤   // create file if it doesn't exist -wjb
d4559c ¤   ¤   ¤   ¤   hfile = CreateFile (szFile, GENERIC_READ|GENERIC_WRITE,·
f46e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,·
d50028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
07f4d7 ¤   ¤   ¤   ¤   CloseHandle (hfile);
abaf5a
8cd92b ¤   ¤   ¤   ¤   if (lstrcmpi (szFile, szRing) != 0) {
a71c55 ¤   ¤   ¤   ¤   ¤   if (!sIsFileNameOK (szFile)) {
280e6d ¤   ¤   ¤   ¤   ¤   ¤   PGPclMessageBox (GetParent (hDlg),·
2241dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_CAPTION, IDS_ILLEGALFILENAME,
4197c6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK | MB_ICONHAND);
f4e23a ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT,·
50a132 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSNRET_INVALID_NOCHANGEPAGE);
9dc94f ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
7780de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
0b1c89 ¤   ¤   ¤   ¤   ¤   }
e311fd ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
dbbf2d ¤   ¤   ¤   ¤   ¤   err = PGPNewFileSpecFromFullPath (ContextRef, szFile,·
51bdc3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileRef);
1ba4e8 ¤   ¤   ¤   ¤   ¤   if (PGPclErrorBox (hDlg, err)) return TRUE;
cbaf5a
8c59c1 ¤   ¤   ¤   ¤   ¤   // create file if it doesn't exist·
52c846 ¤   ¤   ¤   ¤   ¤   hfile = CreateFile (szFile, GENERIC_READ|GENERIC_WRITE,·
966e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,·
290028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
e9f13a ¤   ¤   ¤   ¤   ¤   CloseHandle (hfile);
e6af5a
862e51 ¤   ¤   ¤   ¤   ¤   err = PGPsdkPrefSetFileSpec (ContextRef,·
e8c966 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PrivateKeyring, fileRef);
0d1a2d ¤   ¤   ¤   ¤   ¤   if (!PGPclErrorBox (hDlg, err))·
a1950f ¤   ¤   ¤   ¤   ¤   ¤   bReloadKeyring = TRUE;
e22613 ¤   ¤   ¤   ¤   }
a48065 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
98a3a6 ¤   ¤   ¤   }
abaf5a
c1b2bf ¤   ¤   ¤   // get current public keyring file
4e5799 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (ContextRef,·
f23be2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PublicKeyring, &fileRef);
f8cc33 ¤   ¤   ¤   if (IsntPGPError (err) && fileRef) {
31fea7 ¤   ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileRef, &lpsz);
225c65 ¤   ¤   ¤   ¤   lstrcpy (szRing, lpsz);
--8702 000e0ac61df40110292 Page 10 of CLprefs.c
58869a ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
12996a ¤   ¤   ¤   ¤   // compare with selected file and set pref if different
143a75 ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_PUBLICKEYRING, szFile,·
deb856 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szFile));
6f3eaa ¤   ¤   ¤   ¤   // create file if it doesn't exist -wjb
24559c ¤   ¤   ¤   ¤   hfile = CreateFile (szFile, GENERIC_READ|GENERIC_WRITE,·
2f6e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,·
c00028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
52f4d7 ¤   ¤   ¤   ¤   CloseHandle (hfile);
d8af5a
bbd92b ¤   ¤   ¤   ¤   if (lstrcmpi (szFile, szRing) != 0) {
8c1c55 ¤   ¤   ¤   ¤   ¤   if (!sIsFileNameOK (szFile)) {
5b0e6d ¤   ¤   ¤   ¤   ¤   ¤   PGPclMessageBox (GetParent (hDlg),·
f841dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_CAPTION, IDS_ILLEGALFILENAME,
bb97c6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK | MB_ICONHAND);
b3e23a ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT,·
aea132 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSNRET_INVALID_NOCHANGEPAGE);
80c94f ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
8480de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
bb1c89 ¤   ¤   ¤   ¤   ¤   }
3411fd ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
3bbf2d ¤   ¤   ¤   ¤   ¤   err = PGPNewFileSpecFromFullPath (ContextRef, szFile,·
60bdc3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileRef);
a2a4e8 ¤   ¤   ¤   ¤   ¤   if (PGPclErrorBox (hDlg, err)) return TRUE;
28af5a
10728f ¤   ¤   ¤   ¤   ¤   // create file if it doesn't exist
67c846 ¤   ¤   ¤   ¤   ¤   hfile = CreateFile (szFile, GENERIC_READ|GENERIC_WRITE,·
556e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,·
330028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
a2f13a ¤   ¤   ¤   ¤   ¤   CloseHandle (hfile);
3caf5a
6f2e51 ¤   ¤   ¤   ¤   ¤   err = PGPsdkPrefSetFileSpec (ContextRef,·
d2f0c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PublicKeyring, fileRef);
cf1a2d ¤   ¤   ¤   ¤   ¤   if (!PGPclErrorBox (hDlg, err))·
61950f ¤   ¤   ¤   ¤   ¤   ¤   bReloadKeyring = TRUE;
d42613 ¤   ¤   ¤   ¤   }
1a8065 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
c4a3a6 ¤   ¤   ¤   }
9caf5a
38afcc ¤   ¤   ¤   // get RNG seed file
ac5799 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (ContextRef,·
37dab4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_RandomSeedFile, &fileRef);
ddcc33 ¤   ¤   ¤   if (IsntPGPError (err) && fileRef) {
ecfea7 ¤   ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileRef, &lpsz);
f25c65 ¤   ¤   ¤   ¤   lstrcpy (szRing, lpsz);
f7869a ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
64996a ¤   ¤   ¤   ¤   // compare with selected file and set pref if different
7fab16 ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_RNGSEEDFILE, szFile,·
06b856 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szFile));
503eaa ¤   ¤   ¤   ¤   // create file if it doesn't exist -wjb
c5559c ¤   ¤   ¤   ¤   hfile = CreateFile (szFile, GENERIC_READ|GENERIC_WRITE,·
d76e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,·
e90028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
d5f4d7 ¤   ¤   ¤   ¤   CloseHandle (hfile);
b3af5a
44d92b ¤   ¤   ¤   ¤   if (lstrcmpi (szFile, szRing) != 0) {
281c55 ¤   ¤   ¤   ¤   ¤   if (!sIsFileNameOK (szFile)) {
200e6d ¤   ¤   ¤   ¤   ¤   ¤   PGPclMessageBox (GetParent (hDlg),·
7641dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_CAPTION, IDS_ILLEGALFILENAME,
4b97c6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK | MB_ICONHAND);
dae23a ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT,·
7ea132 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSNRET_INVALID_NOCHANGEPAGE);
83c94f ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
e780de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
f91c89 ¤   ¤   ¤   ¤   ¤   }
0b11fd ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
03bf2d ¤   ¤   ¤   ¤   ¤   err = PGPNewFileSpecFromFullPath (ContextRef, szFile,·
29bdc3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fileRef);
2aa4e8 ¤   ¤   ¤   ¤   ¤   if (PGPclErrorBox (hDlg, err)) return TRUE;
f7af5a
5f728f ¤   ¤   ¤   ¤   ¤   // create file if it doesn't exist
e0c846 ¤   ¤   ¤   ¤   ¤   hfile = CreateFile (szFile, GENERIC_READ|GENERIC_WRITE,·
--898c 000fd6599da40110292 Page 11 of CLprefs.c
616e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,·
5c0028 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
e2f13a ¤   ¤   ¤   ¤   ¤   CloseHandle (hfile);
19af5a
f94540 ¤   ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPsdkPrefSetFileSpec (ContextRef,·
f217a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_RandomSeedFile, fileRef));
732613 ¤   ¤   ¤   ¤   }
248065 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileRef);
caa3a6 ¤   ¤   ¤   }
eaaf5a
f7358d ¤   ¤   ¤   returnErr = kPGPError_NoErr;
86c04d ············SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
ccaf5a
d1f6d1 ¤   ¤   ¤   if (bReloadKeyring) {
63eb8e ¤   ¤   ¤   ¤   // reset warn flag
44b416 ¤   ¤   ¤   ¤   PGPSetPrefBoolean (PrefRefClient,·
0f2d68 ¤   ¤   ¤   ¤   ¤   kPGPPrefWarnOnReadOnlyKeyRings, (PGPBoolean)TRUE);
1fa3a6 ¤   ¤   ¤   }
3632bd ¤   ¤   ¤   return TRUE;
4f8632 ············break;
96af5a
108f63 ¤   ¤   case PSN_KILLACTIVE :
0dd12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
f951a3 ············return TRUE;
83cdcb ¤   ¤   ¤   break;
f9af5a
1d65b8 ¤   ¤   case PSN_RESET :
95377b ¤   ¤   ¤   returnErr = kPGPError_UserAbort;
f3d12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
afcdcb ¤   ¤   ¤   break;
2e0fe4 ¤   ¤   }
30af5a
5f9371 ¤   }
cba230 ¤   return FALSE;
09af5a
e3efe6 }
72af5a
ae3fc0 //¤ _____________________________________________________
d6465d //
c6999d // ·Message processing function for property sheet dialog
82af5a
e35678 static LRESULT WINAPI·
3a7d82 sEncryptPropDlgProc (
493a3a ¤   ¤   HWND¤   hDlg,·
07eb77 ¤   ¤   UINT¤   uMsg,·
2c17d4 ¤   ¤   WPARAM¤ wParam,·
6bc0b8 ¤   ¤   LPARAM¤ lParam)·
7bbb36 {
985b56 ¤   HWND¤   ¤   ¤   ¤   ¤   hParent;
36035d ¤   RECT¤   ¤   ¤   ¤   ¤   rc;
6622da ¤   UINT¤   ¤   ¤   ¤   ¤   u, uSec, uEncrypt, uSign;
5d5596 ¤   PGPBoolean¤ ¤   ¤   ¤   b;
fff176 ¤   CHAR¤   ¤   ¤   ¤   ¤   sz[64];
c36338 ¤   PCACHEDURATIONSTRUCT¤   pcds;
43af5a
60347f ¤   switch (uMsg) {
d0af5a
ba2940 ¤   case WM_INITDIALOG:
941b52 ¤   ¤
3e3052 ¤   ¤   pcds = clAlloc (sizeof(CACHEDURATIONSTRUCT));
6b3461 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LONG)pcds);
b94433 ¤   ¤   if (bNeedsCentering) {
709ecf ¤   ¤   ¤   hParent = GetParent (hDlg);
d0d699 ¤   ¤   ¤   GetWindowRect (hParent, &rc);
67a58a ¤   ¤   ¤   SetWindowPos (hParent, NULL,
7e73f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
a58186 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
ccf9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
1923ad ¤   ¤   ¤   bNeedsCentering = FALSE;
a90fe4 ¤   ¤   }
23af5a
fdee9e ¤   ¤   // initialize decrypt to self
--1b02 000991766ee40110292 Page 12 of CLprefs.c
4e0b7a ¤   ¤   b = DEFAULT_ENCRYPTTOSELF;
99bfb9 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefEncryptToSelf, &b);
408bc8 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_ENCRYPTTOSELF, BST_CHECKED);
61baac ¤   ¤   else CheckDlgButton (hDlg, IDC_ENCRYPTTOSELF, BST_UNCHECKED);
a9af5a
347918 ¤   ¤   // create and initialize decryption date/time picker control
efa824 ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_DECRYPTCACHETIME), &rc);
aa4f66 ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
c071d8 ¤   ¤   pcds->hwndDecryptDuration = CreateWindowEx (0, DATETIMEPICK_CLASS,
2e3d5e ·····························"DateTime",
fc6544 ·····························WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP|
e7153f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·DTS_TIMEFORMAT,
13d631 ·····························rc.left, rc.top,·
bb79ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·rc.right-rc.left, rc.bottom-rc.top,·
8b446b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hDlg, (HMENU)IDC_DECRYPTCACHETIME,·
ecd5a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·g_hInst, NULL);
0f5f86 ¤   ¤   SendMessage (pcds->hwndDecryptDuration, DTM_SETFORMAT, 0,·
d40602 ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)"HH' : 'mm' : 'ss");
da5935 ¤   ¤   SetWindowPos (pcds->hwndDecryptDuration,·
61dede ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_DECRYPTCACHEENABLE),
88e226 ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1a1b52 ¤   ¤
c92724 ¤   ¤   GetSystemTime (&(pcds->stDecryptDuration));
f06b6a ¤   ¤   uSec = DEFAULT_DECRYPTCACHESECONDS;
eacf62 ¤   ¤   PGPGetPrefNumber (PrefRefClient,kPGPPrefDecryptCacheSeconds, &uSec);
c0dd3e ¤   ¤   u = uSec / 3600;
c64241 ¤   ¤   pcds->stDecryptDuration.wHour = u;
3daf5a
a154c2 ¤   ¤   uSec -= (u * 3600);
03cde8 ¤   ¤   u = uSec / 60;
cb4681 ¤   ¤   pcds->stDecryptDuration.wMinute = u;
5faf5a
7d187b ¤   ¤   uSec -= (u * 60);
b4bdc4 ¤   ¤   pcds->stDecryptDuration.wSecond = uSec;
f0af5a
e72961 ¤   ¤   pcds->stDecryptDuration.wMilliseconds = 0;
95af5a
c776d4 ¤   ¤   SendMessage (pcds->hwndDecryptDuration, DTM_SETSYSTEMTIME, GDT_VALID,·
3631eb ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pcds->stDecryptDuration));
54af5a
4212ff ¤   ¤   // initialize decrypt cache on/off
c468f5 ¤   ¤   b = DEFAULT_DECRYPTCACHEENABLE;
b90c7b ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefDecryptCacheEnable, &b);
e5e6c8 ¤   ¤   if (b) {
1fc867 ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_DECRYPTCACHEENABLE, BST_CHECKED);
3c3ca2 ¤   ¤   ¤   EnableWindow (pcds->hwndDecryptDuration, TRUE);
180fe4 ¤   ¤   }
4e07e0 ¤   ¤   else {
e6be1d ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_DECRYPTCACHEENABLE, BST_UNCHECKED);
be1d52 ¤   ¤   ¤   EnableWindow (pcds->hwndDecryptDuration, FALSE);
490fe4 ¤   ¤   }
ecaf5a
daaf5a
7e4ad3 ¤   ¤   // create and initialize sign date/time picker control
c98d18 ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_SIGNCACHETIME), &rc);
bb4f66 ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
042f3b ¤   ¤   pcds->hwndSignDuration = CreateWindowEx (0, DATETIMEPICK_CLASS,
403d5e ·····························"DateTime",
8e6544 ·····························WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP|
7f153f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·DTS_TIMEFORMAT,
ddd631 ·····························rc.left, rc.top,·
6f79ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·rc.right-rc.left, rc.bottom-rc.top,·
03927a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hDlg, (HMENU)IDC_SIGNCACHETIME,·
1dd5a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·g_hInst, NULL);
498819 ¤   ¤   SendMessage (pcds->hwndSignDuration, DTM_SETFORMAT, 0,·
640602 ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)"HH' : 'mm' : 'ss");
4e43f1 ¤   ¤   SetWindowPos (pcds->hwndSignDuration,·
49f7dd ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_SIGNCACHEENABLE),
ace226 ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
f81b52 ¤   ¤
2e4326 ¤   ¤   GetSystemTime (&(pcds->stSignDuration));
996b6a ¤   ¤   uSec = DEFAULT_DECRYPTCACHESECONDS;
--76e9 0008ac3d27a40110292 Page 13 of CLprefs.c
98053b ¤   ¤   PGPGetPrefNumber (PrefRefClient,kPGPPrefSignCacheSeconds, &uSec);
c1dd3e ¤   ¤   u = uSec / 3600;
b9db71 ¤   ¤   pcds->stSignDuration.wHour = u;
e0af5a
3954c2 ¤   ¤   uSec -= (u * 3600);
59cde8 ¤   ¤   u = uSec / 60;
29f96b ¤   ¤   pcds->stSignDuration.wMinute = u;
1baf5a
10187b ¤   ¤   uSec -= (u * 60);
da7eb9 ¤   ¤   pcds->stSignDuration.wSecond = uSec;
67af5a
6ab604 ¤   ¤   pcds->stSignDuration.wMilliseconds = 0;
c2af5a
86cb05 ¤   ¤   SendMessage (pcds->hwndSignDuration, DTM_SETSYSTEMTIME, GDT_VALID,·
140f6b ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pcds->stSignDuration));
87af5a
1d996a ¤   ¤   // initialize sign cache on/off
3dcd49 ¤   ¤   b = DEFAULT_SIGNCACHEENABLE;
4607fe ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefSignCacheEnable, &b);
ebe6c8 ¤   ¤   if (b) {
4899c8 ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_SIGNCACHEENABLE, BST_CHECKED);
db9a23 ¤   ¤   ¤   EnableWindow (pcds->hwndSignDuration, TRUE);
f10fe4 ¤   ¤   }
6d07e0 ¤   ¤   else {
f9d126 ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_SIGNCACHEENABLE, BST_UNCHECKED);
e18875 ¤   ¤   ¤   EnableWindow (pcds->hwndSignDuration, FALSE);
0b0fe4 ¤   ¤   }
c5af5a
2cffc9 ¤   ¤   // comment block text
4490ba ¤   ¤   SendDlgItemMessage (hDlg, IDC_COMMENTBLOCK, EM_SETLIMITTEXT,·
629002 ¤   ¤   ¤   ¤   ¤   ¤   ¤   COMMENTBLOCK_MAX_LENGTH, 0);
ffea5b ¤   ¤   sz[0] = '\0';
51be29 #if PGP_BUSINESS_SECURITY
923172 ¤   ¤   PGPGetPrefStringBuffer (PrefRefAdmin, kPGPPrefComments,·
03f27d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz);
767454 #endif
22dab3 ¤   ¤   if (sz[0])·
6749be ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_COMMENTBLOCK), FALSE);
03ee26 ¤   ¤   else·
794816 ¤   ¤   ¤   PGPGetPrefStringBuffer (PrefRefClient, kPGPPrefComment,·
cba166 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz);
b1b08a ¤   ¤   SetDlgItemText (hDlg, IDC_COMMENTBLOCK, sz);
c9af5a
9ad238 ¤   ¤   b = DEFAULT_WIPECONFIRM;
222fb6 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefWarnOnWipe, &b);
3e15e9 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_WIPECONFIRM, BST_CHECKED);
a303c3 ¤   ¤   else CheckDlgButton (hDlg, IDC_WIPECONFIRM, BST_UNCHECKED);
25af5a
412fb0 ¤   ¤   // initialize fast key gen preference
f6aa05 ¤   ¤   b = DEFAULT_USEFASTKEYGEN;
3c8c5d ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefFastKeyGen, &b);
285284 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_USEFASTKEYGEN, BST_CHECKED);
ab1e26 ¤   ¤   else CheckDlgButton (hDlg, IDC_USEFASTKEYGEN, BST_UNCHECKED);
ccaf5a
480702 ¤   ¤   // initialize wipe preferences
a29546 ¤   ¤   SendDlgItemMessage (hDlg, IDC_NUMPASSESSPIN, UDM_SETRANGE,
cd21c5 ¤   ¤   ¤   ¤   0, (LPARAM)MAKELONG (MAXWIPEPASSES, 1));
31af5a
357a42 ¤   ¤   u = DEFAULT_WIPEPASSES;
3deabb ¤   ¤   PGPGetPrefNumber (PrefRefClient, kPGPPrefFileWipePasses, &u);
4276d3 ¤   ¤   SendDlgItemMessage (hDlg, IDC_NUMPASSESSPIN, UDM_SETPOS,
c42b4c ¤   ¤   ¤   ¤   0, (LPARAM)MAKELONG (u, 0));
21af5a
58836c ¤   ¤   return TRUE;
e7af5a
00c3eb ····case WM_HELP:·
2db426 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
f547dc ············HELP_WM_HELP, (DWORD) (LPSTR) aGeneralIds);·
248f13 ········break;·
a6d83c ·
5b4fd8 ····case WM_CONTEXTMENU:·
8a5ad9 ········WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
--3eab 0002248432240110292 Page 14 of CLprefs.c
049151 ············(DWORD) (LPVOID) aGeneralIds);·
6a8f13 ········break;·
09af5a
67d1d3 ¤   case WM_COMMAND :
d91185 ¤   ¤   switch (LOWORD (wParam)) {
d6af5a
230096 ¤   ¤   case IDC_DECRYPTCACHEENABLE :
1f8121 ¤   ¤   ¤   pcds = (PCACHEDURATIONSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
b388dd ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg,·
3d5340 ¤   ¤   ¤   ¤   ¤   ¤   IDC_DECRYPTCACHEENABLE) == BST_CHECKED)·
bcf8be ¤   ¤   ¤   ¤   EnableWindow (pcds->hwndDecryptDuration, TRUE);
026b93 ¤   ¤   ¤   else·
15c77b ¤   ¤   ¤   ¤   EnableWindow (pcds->hwndDecryptDuration, FALSE);
e4cdcb ¤   ¤   ¤   break;
ffaf5a
68f871 ¤   ¤   case IDC_SIGNCACHEENABLE :
8b8121 ¤   ¤   ¤   pcds = (PCACHEDURATIONSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
1bdb28 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg,
0beeb2 ¤   ¤   ¤   ¤   ¤   ¤   IDC_SIGNCACHEENABLE) == BST_CHECKED)·
fdbc96 ¤   ¤   ¤   ¤   EnableWindow (pcds->hwndSignDuration, TRUE);
8f6b93 ¤   ¤   ¤   else·
026a75 ¤   ¤   ¤   ¤   EnableWindow (pcds->hwndSignDuration, FALSE);
a0cdcb ¤   ¤   ¤   break;
fd0fe4 ¤   ¤   }
fc2f68 ¤   ¤   break;
68af5a
af1431 ¤   case WM_NOTIFY :
4e0f7c ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
7c2bc0 ¤   ¤   case PSN_SETACTIVE :
b0cdcb ¤   ¤   ¤   break;
e1af5a
d41b03 ¤   ¤   case PSN_HELP :
61da62 ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
a15741 ¤   ¤   ¤   ¤   IDH_PGPCLPREF_ENCRYPTDIALOG);·
ebcdcb ¤   ¤   ¤   break;
ddaf5a
a827ec ¤   ¤   case PSN_APPLY :
9c8121 ¤   ¤   ¤   pcds = (PCACHEDURATIONSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
35af5a
f314e8 ¤   ¤   ¤   SendMessage (pcds->hwndDecryptDuration, DTM_GETSYSTEMTIME, 0,·
c531eb ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pcds->stDecryptDuration));
64ab11 ¤   ¤   ¤   uEncrypt = pcds->stDecryptDuration.wHour * 3600;
51fb6c ¤   ¤   ¤   uEncrypt += (pcds->stDecryptDuration.wMinute * 60);
6de410 ¤   ¤   ¤   uEncrypt += pcds->stDecryptDuration.wSecond;
bdaf5a
53d508 ¤   ¤   ¤   SendMessage (pcds->hwndSignDuration, DTM_GETSYSTEMTIME, 0,·
580f6b ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pcds->stSignDuration));
bcb3eb ¤   ¤   ¤   uSign = pcds->stSignDuration.wHour * 3600;
5a94c0 ¤   ¤   ¤   uSign += (pcds->stSignDuration.wMinute * 60);
3a6d39 ¤   ¤   ¤   uSign += pcds->stSignDuration.wSecond;
9eaf5a
68d815 ¤   ¤   ¤   if ((uEncrypt > MAXCACHETIMELIMIT)||(uSign > MAXCACHETIMELIMIT)) {
716444 ¤   ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_CAPTION,·
d70885 ¤   ¤   ¤   ¤   ¤   IDS_INVALIDCACHEVALUE, MB_OK|MB_ICONHAND);
90abbc ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT,·
7b0c44 ¤   ¤   ¤   ¤   ¤   PSNRET_INVALID_NOCHANGEPAGE);
c806e0 ¤   ¤   ¤   ¤   return TRUE;
e2a3a6 ¤   ¤   ¤   }
55af5a
3405c1 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENCRYPTTOSELF) == BST_CHECKED)
f8f84a ¤   ¤   ¤   ¤   b = TRUE;
686b93 ¤   ¤   ¤   else·
6cdce5 ¤   ¤   ¤   ¤   b = FALSE;
ae58ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
d1e2f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefEncryptToSelf, b));
6587c7 ¤   ¤   ¤
387826 ¤   ¤   ¤   u = 0;
943e04 ¤   ¤   ¤   b = FALSE;
49c307 ¤   ¤   ¤   if (uEncrypt > 0) {
f45e39 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_DECRYPTCACHEENABLE) ==
b1b1d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
22711e ¤   ¤   ¤   ¤   ¤   b = TRUE;
--a81a 0008ca0aa6f40110292 Page 15 of CLprefs.c
cfa3a6 ¤   ¤   ¤   }
1558ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
4fe7a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefDecryptCacheEnable, b));
04c22f ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefNumber (PrefRefClient,
eaf0e5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefDecryptCacheSeconds, uEncrypt));
8c800f ¤   ¤   ¤   if (!b) u |= PGPCL_DECRYPTIONCACHE;
a3af5a
8f3e04 ¤   ¤   ¤   b = FALSE;
17961a ¤   ¤   ¤   if (uSign > 0) {
a58ab6 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_SIGNCACHEENABLE) ==
8ab1d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
8f711e ¤   ¤   ¤   ¤   ¤   b = TRUE;
2da3a6 ¤   ¤   ¤   }
c958ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
1e4a3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefSignCacheEnable, b));
fec22f ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefNumber (PrefRefClient,
ce0ea3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefSignCacheSeconds, uSign));
6fd612 ¤   ¤   ¤   if (!b) u |= PGPCL_SIGNINGCACHE;
2aaf5a
b4fd19 ¤   ¤   ¤   if (u != 0)
da1381 ¤   ¤   ¤   ¤   PGPclNotifyPurgePassphraseCache (u, 0);
ce87c7 ¤   ¤   ¤
a4c973 ¤   ¤   ¤   if (!GetDlgItemText (hDlg, IDC_COMMENTBLOCK, sz, sizeof(sz))) {
eda4ba ¤   ¤   ¤   ¤   sz[0] = '\0';
a5a3a6 ¤   ¤   ¤   }
916f13 ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefString (PrefRefClient,
aaa210 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefComment, sz));
6787c7 ¤   ¤   ¤
63844d ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_USEFASTKEYGEN) ==
d48d39 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
e2f84a ¤   ¤   ¤   ¤   b = TRUE;
f26b93 ¤   ¤   ¤   else·
e1dce5 ¤   ¤   ¤   ¤   b = FALSE;
d458ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
d66b75 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefFastKeyGen, b));
e7caf9 ············
5ae886 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_WIPECONFIRM) ==
8f8d39 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
7df84a ¤   ¤   ¤   ¤   b = TRUE;
bb6b93 ¤   ¤   ¤   else·
19dce5 ¤   ¤   ¤   ¤   b = FALSE;
2e58ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
30c89e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefWarnOnWipe, b));
85af5a
04b5e6 ¤   ¤   ¤   u = GetDlgItemInt (hDlg, IDC_NUMPASSES, NULL, FALSE);
e6c9f4 ¤   ¤   ¤   if (u < 1) u = 1;
761200 ¤   ¤   ¤   if (u > MAXWIPEPASSES) u = MAXWIPEPASSES;
07c22f ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefNumber (PrefRefClient,
272d2b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefFileWipePasses, u));
29af5a
5a358d ¤   ¤   ¤   returnErr = kPGPError_NoErr;
34c04d ············SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
6a51a3 ············return TRUE;
bcaf5a
208f63 ¤   ¤   case PSN_KILLACTIVE :
7ad12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
9151a3 ············return TRUE;
86af5a
c565b8 ¤   ¤   case PSN_RESET :
74377b ¤   ¤   ¤   returnErr = kPGPError_UserAbort;
95d12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
4bcdcb ¤   ¤   ¤   break;
2c0fe4 ¤   ¤   }
829371 ¤   }
14af5a
dca230 ¤   return FALSE;
4faf5a
ffefe6 }
bfaf5a
853fc0 //¤ _____________________________________________________
7c465d //
8c999d // ·Message processing function for property sheet dialog
--1c37 000e97711da40110292 Page 16 of CLprefs.c
e0af5a
925678 static LRESULT WINAPI·
2b0cf4 sEmailPropDlgProc (
bd3a3a ¤   ¤   HWND¤   hDlg,·
e3eb77 ¤   ¤   UINT¤   uMsg,·
4917d4 ¤   ¤   WPARAM¤ wParam,·
a2c0b8 ¤   ¤   LPARAM¤ lParam)·
20bb36 {
0df394 ¤   HWND¤   ¤   hParent;
8f0079 ¤   RECT¤   ¤   rc;
0c72e2 ¤   PGPBoolean¤ b;
191a5e ¤   UINT¤   ¤   u;
48af5a
8e347f ¤   switch (uMsg) {
f8af5a
dc2940 ¤   case WM_INITDIALOG:
604433 ¤   ¤   if (bNeedsCentering) {
8c9ecf ¤   ¤   ¤   hParent = GetParent (hDlg);
dcd699 ¤   ¤   ¤   GetWindowRect (hParent, &rc);
e7a58a ¤   ¤   ¤   SetWindowPos (hParent, NULL,
6173f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
5f8186 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
17f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
d823ad ¤   ¤   ¤   bNeedsCentering = FALSE;
510fe4 ¤   ¤   }
d367c5 ¤
8de1ad ¤   ¤   b = DEFAULT_MAILENCRYPTPGPMIME;
c54e24 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefMailEncryptPGPMIME, &b);
354d0f ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_ENCRYPTPGPMIME, BST_CHECKED);
8c4b35 ¤   ¤   else CheckDlgButton (hDlg, IDC_ENCRYPTPGPMIME, BST_UNCHECKED);
13af5a
360608 ¤   ¤   u = DEFAULT_WORDWRAPWIDTH;
fd77b7 ¤   ¤   PGPGetPrefNumber (PrefRefClient, kPGPPrefWordWrapWidth, &u);
e845c1 ¤   ¤   SetDlgItemInt (hDlg, IDC_WRAPNUMBER, u, FALSE);
c8af5a
839945 ¤   ¤   b = DEFAULT_WORDWRAPENABLE;
29eb4b ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefWordWrapEnable, &b);
6fe6c8 ¤   ¤   if (b) {
609d4e ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_WRAPENABLE, BST_CHECKED);
31a4ec ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_WRAPNUMBER), TRUE);
140fe4 ¤   ¤   }
9707e0 ¤   ¤   else {
714f1e ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_WRAPENABLE, BST_UNCHECKED);
6eb6b0 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_WRAPNUMBER), FALSE);
2b0fe4 ¤   ¤   }
a3af5a
95f6c1 ¤   ¤   b = DEFAULT_MAILENCRYPTDEFAULT;
1d9dc1 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefMailEncryptDefault, &b);
61638e ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_ENCRYPTBYDEFAULT, BST_CHECKED);
889ff9 ¤   ¤   else CheckDlgButton (hDlg, IDC_ENCRYPTBYDEFAULT, BST_UNCHECKED);
caaf5a
cf4f02 ¤   ¤   b = DEFAULT_MAILSIGNDEFAULT;
0b8537 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefMailSignDefault, &b);
772dc4 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_SIGNBYDEFAULT, BST_CHECKED);
d1d330 ¤   ¤   else CheckDlgButton (hDlg, IDC_SIGNBYDEFAULT, BST_UNCHECKED);
9caf5a
efc7a9 ¤   ¤   b = DEFAULT_AUTODECRYPT;
072703 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefAutoDecrypt, &b);
f272c3 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_AUTODECRYPT, BST_CHECKED);
21ca39 ¤   ¤   else CheckDlgButton (hDlg, IDC_AUTODECRYPT, BST_UNCHECKED);
eaaf5a
4f836c ¤   ¤   return TRUE;
5caf5a
4fc3eb ····case WM_HELP:·
b2b426 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
d96a22 ············HELP_WM_HELP, (DWORD) (LPSTR) aEmailIds);·
848f13 ········break;·
c6d83c ·
a84fd8 ····case WM_CONTEXTMENU:·
d35ad9 ········WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
c9ba22 ············(DWORD) (LPVOID) aEmailIds);·
e98f13 ········break;·
--ffaa 0007162c1e240110292 Page 17 of CLprefs.c
e0af5a
76d1d3 ¤   case WM_COMMAND :
251185 ¤   ¤   switch (LOWORD (wParam)) {
66651f ¤   ¤   case IDC_WRAPENABLE :
ca1614 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_WRAPENABLE) == BST_CHECKED)
17ea9b ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_WRAPNUMBER), TRUE);
71bb8c ¤   ¤   ¤   else
19b1c6 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_WRAPNUMBER), FALSE);
e5cdcb ¤   ¤   ¤   break;
f60fe4 ¤   ¤   }
432f68 ¤   ¤   break;
8faf5a
fb1431 ¤   case WM_NOTIFY :
3a0f7c ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
f92bc0 ¤   ¤   case PSN_SETACTIVE :
97cdcb ¤   ¤   ¤   break;
d3af5a
ca1b03 ¤   ¤   case PSN_HELP :
46da62 ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
99ee95 ¤   ¤   ¤   ¤   IDH_PGPCLPREF_EMAILDIALOG);·
cacdcb ¤   ¤   ¤   break;
7daf5a
5327ec ¤   ¤   case PSN_APPLY :
ab73ff ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_WRAPENABLE) == BST_CHECKED)·
97f84a ¤   ¤   ¤   ¤   b = TRUE;
f56b93 ¤   ¤   ¤   else·
25dce5 ¤   ¤   ¤   ¤   b = FALSE;
3258ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
45afaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefWordWrapEnable, b));
2087c7 ¤   ¤   ¤
78a743 ¤   ¤   ¤   if (b) {
ef6cd0 ¤   ¤   ¤   ¤   u = GetDlgItemInt (hDlg, IDC_WRAPNUMBER, NULL, FALSE);
6e4cda ¤   ¤   ¤   ¤   if (u == 0) {
f90b77 ¤   ¤   ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_CAPTION,·
eeb34e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_INVALIDWRAP, MB_OK|MB_ICONHAND);
21c48f ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT,·
6dea08 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PSNRET_INVALID_NOCHANGEPAGE);
41bdb6 ¤   ¤   ¤   ¤   ¤   return TRUE;
132613 ¤   ¤   ¤   ¤   }
32d70c ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefNumber (PrefRefClient,
b9221f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefWordWrapWidth, u));
54a3a6 ¤   ¤   ¤   }
8aaf5a
8d8cb1 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENCRYPTPGPMIME) ==
0d8d39 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
b6f84a ¤   ¤   ¤   ¤   b = TRUE;
616b93 ¤   ¤   ¤   else·
e3dce5 ¤   ¤   ¤   ¤   b = FALSE;
ba58ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
e8a289 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefMailEncryptPGPMIME, b));
9458ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
790e32 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefMailSignPGPMIME, b));
fb94aa ¤   ¤   ¤   ¤   ¤   ¤
6c9632 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENCRYPTBYDEFAULT) ==·
f98d39 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
7ef84a ¤   ¤   ¤   ¤   b = TRUE;
2f6b93 ¤   ¤   ¤   else·
b5dce5 ¤   ¤   ¤   ¤   b = FALSE;
0058ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
3b716c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefMailEncryptDefault, b));
8987c7 ¤   ¤   ¤
69036a ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_SIGNBYDEFAULT) ==·
d38d39 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
dbf84a ¤   ¤   ¤   ¤   b = TRUE;
b66b93 ¤   ¤   ¤   else·
addce5 ¤   ¤   ¤   ¤   b = FALSE;
b958ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
eeddd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefMailSignDefault, b));
b91b52 ¤   ¤
1d8ac6 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_AUTODECRYPT) ==·
4b8d39 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
71f84a ¤   ¤   ¤   ¤   b = TRUE;
--16a1 0005bf4273140110292 Page 18 of CLprefs.c
5f6b93 ¤   ¤   ¤   else·
a5dce5 ¤   ¤   ¤   ¤   b = FALSE;
3358ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
769894 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefAutoDecrypt, b));
8c87c7 ¤   ¤   ¤
b5358d ¤   ¤   ¤   returnErr = kPGPError_NoErr;
92c04d ············SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
0793f8 ············return PSNRET_NOERROR;
d7af5a
598f63 ¤   ¤   case PSN_KILLACTIVE :
66d12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
6851a3 ············return TRUE;
26af5a
9165b8 ¤   ¤   case PSN_RESET :
6c377b ¤   ¤   ¤   returnErr = kPGPError_UserAbort;
bdd12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
bfcdcb ¤   ¤   ¤   break;
8c0fe4 ¤   ¤   }
649371 ¤   }
daaf5a
4da230 ¤   return FALSE;
2caf5a
5aefe6 }
0aaf5a
ee3fc0 //¤ _____________________________________________________
92465d //
d08bac // ·Initialize preferred algorithm combo box on basis of
0adab5 //¤ enabled algorithms
0daf5a
a9e6b2 static VOID
57cf75 sInitPreferredAlgComboBox (HWND hDlg, UINT uInit) {
c6af5a
444019 ¤   INT¤¤   iIdx, iPrevAlg;
e6cd6d ¤   CHAR¤   sz[32];
f9d75b ¤   UINT¤   uIndex;
6baf5a
b4a08a ¤   if (uInit) iPrevAlg = uInit;
ec665a ¤   else {
a95192 ¤   ¤   iIdx = SendDlgItemMessage (hDlg, IDC_PREFERREDALG,·
697daa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_GETCURSEL, 0, 0);¤
dab897 ¤   ¤   if (iIdx != CB_ERR)·
111c61 ¤   ¤   ¤   iPrevAlg = SendDlgItemMessage (hDlg, IDC_PREFERREDALG,·
021f4d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_GETITEMDATA, iIdx, 0);
a8ee26 ¤   ¤   else·
c6e55e ¤   ¤   ¤   iPrevAlg = kPGPCipherAlgorithm_None;
ed9371 ¤   }
3bb56d ¤   SendDlgItemMessage (hDlg, IDC_PREFERREDALG, CB_RESETCONTENT, 0, 0);
e1af5a
46ece2 ¤   iIdx = -1;
23af5a
502f6c ¤   // put item into combobox for each enabled algorithm
f72dc0 ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLECAST) == BST_CHECKED) {
f7593d ¤   ¤   LoadString (g_hInst, IDS_CAST, sz, sizeof(sz));
b0e142 ¤   ¤   uIndex = SendDlgItemMessage (hDlg, IDC_PREFERREDALG,·
32b731 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_ADDSTRING, 0, (LPARAM)sz);
1ea60e ¤   ¤   if (uIndex != CB_ERR)
f36491 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PREFERREDALG, CB_SETITEMDATA,·
fcc5b1 ¤   ¤   ¤   ¤   uIndex, (LPARAM)kPGPCipherAlgorithm_CAST5);
8f32e6 ¤   ¤   if (iPrevAlg == kPGPCipherAlgorithm_CAST5) iIdx = uIndex;
6f9371 ¤   }
f5af5a
05412d ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLEIDEA) == BST_CHECKED) {
99caa2 ¤   ¤   LoadString (g_hInst, IDS_IDEA, sz, sizeof(sz));
c9e142 ¤   ¤   uIndex = SendDlgItemMessage (hDlg, IDC_PREFERREDALG,·
0eb731 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_ADDSTRING, 0, (LPARAM)sz);
88a60e ¤   ¤   if (uIndex != CB_ERR)
b76491 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PREFERREDALG, CB_SETITEMDATA,·
76dc1a ¤   ¤   ¤   ¤   uIndex, (LPARAM)kPGPCipherAlgorithm_IDEA);
cfa479 ¤   ¤   if (iPrevAlg == kPGPCipherAlgorithm_IDEA) iIdx = uIndex;
fe9371 ¤   }
f9af5a
5bf1d4 ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLE3DES) == BST_CHECKED) {
--e4fe 0008bbdc97540110292 Page 19 of CLprefs.c
099047 ¤   ¤   LoadString (g_hInst, IDS_3DES, sz, sizeof(sz));
0ce142 ¤   ¤   uIndex = SendDlgItemMessage (hDlg, IDC_PREFERREDALG,·
28b731 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_ADDSTRING, 0, (LPARAM)sz);
17a60e ¤   ¤   if (uIndex != CB_ERR)
c16491 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PREFERREDALG, CB_SETITEMDATA,·
44ded6 ¤   ¤   ¤   ¤   uIndex, (LPARAM)kPGPCipherAlgorithm_3DES);
0d7648 ¤   ¤   if (iPrevAlg == kPGPCipherAlgorithm_3DES) iIdx = uIndex;
879371 ¤   }
f1af5a
5fb6ee ¤   if (iIdx < 0) iIdx = 0;
c28829 ¤   SendDlgItemMessage (hDlg, IDC_PREFERREDALG, CB_SETCURSEL, iIdx, 0);
b7af5a
0fefe6 }
f4af5a
4f3fc0 //¤ _____________________________________________________
ef465d //
02999d // ·Message processing function for property sheet dialog
6aaf5a
745678 static LRESULT WINAPI·
919a02 sAdvancedPropDlgProc (
793a3a ¤   ¤   HWND¤   hDlg,·
14eb77 ¤   ¤   UINT¤   uMsg,·
b317d4 ¤   ¤   WPARAM¤ wParam,·
d7c0b8 ¤   ¤   LPARAM¤ lParam)·
37bb36 {
88e152 ¤   HWND¤   ¤   ¤   ¤   hParent;
89b996 ¤   RECT¤   ¤   ¤   ¤   rc;
535816 ¤   PGPBoolean¤ ¤   ¤   b;
be28d9 ¤   UINT¤   ¤   ¤   ¤   u, uNumAlgs;
30d63e ¤   INT¤¤   ¤   ¤   ¤   iIdx;
46a62b ¤   PGPCipherAlgorithm*¤pAlgs;
348f52 ¤   PGPError¤   ¤   ¤   err;
20ca8a ¤   PGPSize¤¤   ¤   ¤   size;
65af5a
45347f ¤   switch (uMsg) {
afaf5a
702940 ¤   case WM_INITDIALOG:
f24433 ¤   ¤   if (bNeedsCentering) {
8a9ecf ¤   ¤   ¤   hParent = GetParent (hDlg);
3dd699 ¤   ¤   ¤   GetWindowRect (hParent, &rc);
50a58a ¤   ¤   ¤   SetWindowPos (hParent, NULL,
a173f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
138186 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
80f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
2123ad ¤   ¤   ¤   bNeedsCentering = FALSE;
450fe4 ¤   ¤   }
11af5a
ae549f ¤   ¤   // enable checkboxes of those ciphers supported by SDK
8216b6 ¤   ¤   err =·
2f42c8 ¤   ¤   ¤   PGPclCheckSDKSupportForCipherAlg (kPGPCipherAlgorithm_CAST5);
fbae64 ¤   ¤   if (IsntPGPError (err))
df825e ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLECAST), TRUE);
5e16b6 ¤   ¤   err =·
73b765 ¤   ¤   ¤   PGPclCheckSDKSupportForCipherAlg (kPGPCipherAlgorithm_3DES);
c0ae64 ¤   ¤   if (IsntPGPError (err))
c413b3 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLE3DES), TRUE);
fd16b6 ¤   ¤   err =·
75b5a9 ¤   ¤   ¤   PGPclCheckSDKSupportForCipherAlg (kPGPCipherAlgorithm_IDEA);
10ae64 ¤   ¤   if (IsntPGPError (err))
32eb64 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLEIDEA), TRUE);
ae1b52 ¤   ¤
1aea8f ¤   ¤   // check boxes of enabled algorithms
c22db5 ¤   ¤   PGPGetPrefData (PrefRefClient, kPGPPrefAllowedAlgorithmsList,
d50db4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··&size, &pAlgs);
c24be3 ¤   ¤   uNumAlgs = size / sizeof(PGPCipherAlgorithm);
34af5a
15312a ¤   ¤   for (u=0; u<uNumAlgs; u++) {
0735bf ¤   ¤   ¤   err = PGPclCheckSDKSupportForCipherAlg (pAlgs[u]);
706a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
320d53 ¤   ¤   ¤   ¤   switch (pAlgs[u]) {
74fa38 ¤   ¤   ¤   ¤   case kPGPCipherAlgorithm_CAST5 :
8bbade ¤   ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLECAST, BST_CHECKED);
--fde0 000c908ce9240110292 Page 20 of CLprefs.c
f014c3 ¤   ¤   ¤   ¤   ¤   break;
56af5a
87e75f ¤   ¤   ¤   ¤   case kPGPCipherAlgorithm_3DES :
f93843 ¤   ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLE3DES, BST_CHECKED);
2614c3 ¤   ¤   ¤   ¤   ¤   break;
58af5a
08e593 ¤   ¤   ¤   ¤   case kPGPCipherAlgorithm_IDEA :
9ea4d7 ¤   ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLEIDEA, BST_CHECKED);
a814c3 ¤   ¤   ¤   ¤   ¤   break;
c32613 ¤   ¤   ¤   ¤   }
a9a3a6 ¤   ¤   ¤   }
360fe4 ¤   ¤   }
22eda3 ¤   ¤   if (pAlgs) PGPDisposePrefData (PrefRefClient, pAlgs);
c2af5a
634c94 ¤   ¤   // initialize preferred algorithm
fc2693 ¤   ¤   u = DEFAULT_PREFERREDALGORITHM;
e4106e ¤   ¤   PGPGetPrefNumber (PrefRefClient, kPGPPrefPreferredAlgorithm, &u);
4a04f4 ¤   ¤   sInitPreferredAlgComboBox (hDlg, u);
5faf5a
156e32 ¤   ¤   // initialize trust model preferences
2fbc79 ¤   ¤   b = DEFAULT_DISPLAYMARGVALIDITY;
e8beec ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefDisplayMarginalValidity,&b);
c917ac ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_DISPMARGVALIDITY, BST_CHECKED);
29bad9 ¤   ¤   else CheckDlgButton (hDlg, IDC_DISPMARGVALIDITY, BST_UNCHECKED);
9eaf5a
d6e0ea ¤   ¤   b = DEFAULT_MARGVALIDISINVALID;
18bdd2 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefMarginalIsInvalid, &b);
e32900 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_MARGVALIDISINVALID, BST_CHECKED);
9cb52d ¤   ¤   else CheckDlgButton (hDlg, IDC_MARGVALIDISINVALID, BST_UNCHECKED);
18af5a
099d70 ¤   ¤   b = DEFAULT_WARNONADK;
1e0fb8 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefWarnOnADK, &b);
9fb02b ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_WARNONADK, BST_CHECKED);
f4e2df ¤   ¤   else CheckDlgButton (hDlg, IDC_WARNONADK, BST_UNCHECKED);
e6af5a
4ad5fa ¤   ¤   // initialize export format
e01c8a ¤   ¤   b = DEFAULT_EXPORTCOMPATIBLE;
b70ec4 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefExportKeysCompatible, &b);
80f8a0 ¤   ¤   if (b)·
69530d ¤   ¤   ¤   CheckRadioButton (hDlg, IDC_EXPORTCOMPATIBLE,·
08ce4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_EXPORTCOMPLETE, IDC_EXPORTCOMPATIBLE);
aeee26 ¤   ¤   else·
8a530d ¤   ¤   ¤   CheckRadioButton (hDlg, IDC_EXPORTCOMPATIBLE,·
d0e874 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_EXPORTCOMPLETE, IDC_EXPORTCOMPLETE);
a7af5a
bc836c ¤   ¤   return TRUE;
38af5a
63c3eb ····case WM_HELP:·
bab426 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
ff0132 ············HELP_WM_HELP, (DWORD) (LPSTR) aAdvancedIds);·
328f13 ········break;·
13d83c ·
944fd8 ····case WM_CONTEXTMENU:·
115ad9 ········WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
d25e09 ············(DWORD) (LPVOID) aAdvancedIds);·
a58f13 ········break;·
beaf5a
68d1d3 ¤   case WM_COMMAND :
0d1185 ¤   ¤   switch (LOWORD (wParam)) {
ad0bf0 ¤   ¤   case IDC_ENABLECAST :
40f7fb ¤   ¤   ¤   // if unchecked, check it
033514 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLECAST) == BST_UNCHECKED) {
2af4a9 ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLECAST, BST_CHECKED);
227d92 ¤   ¤   ¤   ¤   sInitPreferredAlgComboBox (hDlg, 0);
89f622 ¤   ¤   ¤   ¤   break;
47a3a6 ¤   ¤   ¤   }
26cddc ¤   ¤   ¤   // if checked, make sure it's not the "last" one
2065bf ¤   ¤   ¤   if ((IsDlgButtonChecked (hDlg, IDC_ENABLE3DES) == BST_CHECKED) ||
506da7 ¤   ¤   ¤   ¤   (IsDlgButtonChecked (hDlg, IDC_ENABLEIDEA) == BST_CHECKED)) {
f41548 ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLECAST, BST_UNCHECKED);
ac7d92 ¤   ¤   ¤   ¤   sInitPreferredAlgComboBox (hDlg, 0);
c9f622 ¤   ¤   ¤   ¤   break;
--e86b 0005db8088240110292 Page 21 of CLprefs.c
cfa3a6 ¤   ¤   ¤   }
8af63d ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_CAPTION, IDS_NEEDALGORITHM,
dd13d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
0acdcb ¤   ¤   ¤   break;
93af5a
39d6c2 ¤   ¤   case IDC_ENABLE3DES :
ddf7fb ¤   ¤   ¤   // if unchecked, check it
a4db04 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLE3DES) == BST_UNCHECKED) {
527634 ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLE3DES, BST_CHECKED);
b37d92 ¤   ¤   ¤   ¤   sInitPreferredAlgComboBox (hDlg, 0);
f7f622 ¤   ¤   ¤   ¤   break;
3ea3a6 ¤   ¤   ¤   }
67cddc ¤   ¤   ¤   // if checked, make sure it's not the "last" one
b533c6 ¤   ¤   ¤   if ((IsDlgButtonChecked (hDlg, IDC_ENABLECAST) == BST_CHECKED) ||
576da7 ¤   ¤   ¤   ¤   (IsDlgButtonChecked (hDlg, IDC_ENABLEIDEA) == BST_CHECKED)) {
751b77 ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLE3DES, BST_UNCHECKED);
aa7d92 ¤   ¤   ¤   ¤   sInitPreferredAlgComboBox (hDlg, 0);
46f622 ¤   ¤   ¤   ¤   break;
4aa3a6 ¤   ¤   ¤   }
a0f63d ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_CAPTION, IDS_NEEDALGORITHM,
6813d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
c7cdcb ¤   ¤   ¤   break;
46af5a
23d40e ¤   ¤   case IDC_ENABLEIDEA :
41f7fb ¤   ¤   ¤   // if unchecked, check it
aec59f ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLEIDEA) == BST_UNCHECKED) {
9feaa0 ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLEIDEA, BST_CHECKED);
f77d92 ¤   ¤   ¤   ¤   sInitPreferredAlgComboBox (hDlg, 0);
64f622 ¤   ¤   ¤   ¤   break;
3ca3a6 ¤   ¤   ¤   }
3fcddc ¤   ¤   ¤   // if checked, make sure it's not the "last" one
6f33c6 ¤   ¤   ¤   if ((IsDlgButtonChecked (hDlg, IDC_ENABLECAST) == BST_CHECKED) ||
1b0759 ¤   ¤   ¤   ¤   (IsDlgButtonChecked (hDlg, IDC_ENABLE3DES) == BST_CHECKED)) {
683baf ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLEIDEA, BST_UNCHECKED);
e47d92 ¤   ¤   ¤   ¤   sInitPreferredAlgComboBox (hDlg, 0);
f7f622 ¤   ¤   ¤   ¤   break;
66a3a6 ¤   ¤   ¤   }
64f63d ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_CAPTION, IDS_NEEDALGORITHM,
f313d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
a9cdcb ¤   ¤   ¤   break;
630fe4 ¤   ¤   }
222f68 ¤   ¤   break;
c3af5a
d81431 ¤   case WM_NOTIFY :
a10f7c ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
6b2bc0 ¤   ¤   case PSN_SETACTIVE :
16cdcb ¤   ¤   ¤   break;
f0af5a
361b03 ¤   ¤   case PSN_HELP :
abda62 ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
8118e5 ¤   ¤   ¤   ¤   IDH_PGPCLPREF_ADVANCEDDIALOG);·
3fcdcb ¤   ¤   ¤   break;
f2af5a
ad27ec ¤   ¤   case PSN_APPLY :
8e93de ¤   ¤   ¤   // get preferred algorithm
3c958e ¤   ¤   ¤   iIdx = SendDlgItemMessage (hDlg, IDC_PREFERREDALG,·
119faa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_GETCURSEL, 0, 0);¤
fb03c1 ¤   ¤   ¤   if (iIdx != CB_ERR)·
351644 ¤   ¤   ¤   ¤   u = SendDlgItemMessage (hDlg, IDC_PREFERREDALG,·
321f4d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   CB_GETITEMDATA, iIdx, 0);
e46b93 ¤   ¤   ¤   else·
b1ae7b ¤   ¤   ¤   ¤   u = kPGPCipherAlgorithm_None;
a3fc7b ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefNumber (PrefRefClient,·
b19fdf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefPreferredAlgorithm, u));
7c87c7 ¤   ¤   ¤
ff6ba5 ¤   ¤   ¤   // save enabled ciphers
c21c21 ¤   ¤   ¤   pAlgs = clAlloc (3 * sizeof(PGPCipherAlgorithm));
570ef0 ¤   ¤   ¤   pAlgs[0] = u;¤  // first element is preferred
52af5a
05f4fa ¤   ¤   ¤   if (pAlgs[0] == kPGPCipherAlgorithm_None) u = 0;
d02aa8 ¤   ¤   ¤   else u = 1;
5daf5a
--a698 0001fc4f6e540110292 Page 22 of CLprefs.c
ad78be ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLECAST) == BST_CHECKED) {
92cdc9 ¤   ¤   ¤   ¤   if (pAlgs[0] != kPGPCipherAlgorithm_CAST5)·
4d3d21 ¤   ¤   ¤   ¤   ¤   pAlgs[u++] = kPGPCipherAlgorithm_CAST5;
16a3a6 ¤   ¤   ¤   }
14a4aa ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLE3DES) == BST_CHECKED) {
e78d56 ¤   ¤   ¤   ¤   if (pAlgs[0] != kPGPCipherAlgorithm_3DES)·
929f87 ¤   ¤   ¤   ¤   ¤   pAlgs[u++] = kPGPCipherAlgorithm_3DES;
d5a3a6 ¤   ¤   ¤   }
d01453 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_ENABLEIDEA) == BST_CHECKED) {
948f9a ¤   ¤   ¤   ¤   if (pAlgs[0] != kPGPCipherAlgorithm_IDEA)·
de43a5 ¤   ¤   ¤   ¤   ¤   pAlgs[u++] = kPGPCipherAlgorithm_IDEA;
8da3a6 ¤   ¤   ¤   }
683fc2 ¤   ¤   ¤   PGPSetPrefData (PrefRefClient, kPGPPrefAllowedAlgorithmsList,
f2372c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··u * sizeof(PGPCipherAlgorithm), pAlgs);
4a2f9a ¤   ¤   ¤   clFree (pAlgs);
73af5a
9693db ¤   ¤   ¤   // save trust model preferences
f9544d ¤   ¤   ¤   if (IsDlgButtonChecked (
909368 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_DISPMARGVALIDITY) == BST_CHECKED)·
f1f84a ¤   ¤   ¤   ¤   b = TRUE;
86bb8c ¤   ¤   ¤   else
b0dce5 ¤   ¤   ¤   ¤   b = FALSE;
f658ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
fd6726 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefDisplayMarginalValidity, b));
18544d ¤   ¤   ¤   if (IsDlgButtonChecked (
97a690 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_MARGVALIDISINVALID) == BST_CHECKED)·
eef84a ¤   ¤   ¤   ¤   b = TRUE;
8bbb8c ¤   ¤   ¤   else
75dce5 ¤   ¤   ¤   ¤   b = FALSE;
0758ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
c779e5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefMarginalIsInvalid, b));
a7af5a
5f544d ¤   ¤   ¤   if (IsDlgButtonChecked (
7848bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_WARNONADK) == BST_CHECKED)·
e2f84a ¤   ¤   ¤   ¤   b = TRUE;
98bb8c ¤   ¤   ¤   else
5adce5 ¤   ¤   ¤   ¤   b = FALSE;
4058ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
de5843 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefWarnOnADK, b));
c3af5a
37e72c ¤   ¤   ¤   // save export format preferences
dc544d ¤   ¤   ¤   if (IsDlgButtonChecked (
92e482 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_EXPORTCOMPATIBLE) == BST_CHECKED)·
d6f84a ¤   ¤   ¤   ¤   b = TRUE;
efbb8c ¤   ¤   ¤   else
9fdce5 ¤   ¤   ¤   ¤   b = FALSE;
7c58ee ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
20519e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefExportKeysCompatible, b));
c8af5a
92358d ¤   ¤   ¤   returnErr = kPGPError_NoErr;
83c04d ············SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
2baf5a
22070c ¤   ¤   ¤   return PSNRET_NOERROR;
f0af5a
338f63 ¤   ¤   case PSN_KILLACTIVE :
2fd12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
d451a3 ············return TRUE;
adaf5a
9f65b8 ¤   ¤   case PSN_RESET :
95377b ¤   ¤   ¤   returnErr = kPGPError_UserAbort;
85d12b ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
26cdcb ¤   ¤   ¤   break;
840fe4 ¤   ¤   }
419371 ¤   }
6baf5a
c1a230 ¤   return FALSE;
82af5a
88efe6 }
a3af5a
0baf5a
c83fc0 //¤ _____________________________________________________
1f465d //
--a90c 000728d3d7e40110292 Page 23 of CLprefs.c
f4999d // ·Message processing function for property sheet dialog
5daf5a
155678 static LRESULT WINAPI·
a3eec1 sKeyserverPropDlgProc (
ed3a3a ¤   ¤   HWND¤   hDlg,·
bfeb77 ¤   ¤   UINT¤   uMsg,·
0017d4 ¤   ¤   WPARAM¤ wParam,·
3cc0b8 ¤   ¤   LPARAM¤ lParam)·
2fbb36 {
89f394 ¤   HWND¤   ¤   hParent;
410079 ¤   RECT¤   ¤   rc;
e872e2 ¤   PGPBoolean¤ b;
21af5a
9b347f ¤   switch (uMsg) {
82af5a
392940 ¤   case WM_INITDIALOG:
874433 ¤   ¤   if (bNeedsCentering) {
189ecf ¤   ¤   ¤   hParent = GetParent (hDlg);
2ad699 ¤   ¤   ¤   GetWindowRect (hParent, &rc);
f6a58a ¤   ¤   ¤   SetWindowPos (hParent, NULL,
1e73f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
aa8186 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
00f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
9123ad ¤   ¤   ¤   bNeedsCentering = FALSE;
3c0fe4 ¤   ¤   }
ff757d ¤   ¤   hWndTree = CLCreateKeyserverTreeList (PrefRefClient,·
6a2d6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ContextRef, hDlg, keysetMain);
923339 ¤   ¤   SetWindowPos (hWndTree, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
31af5a
234d99 ¤   ¤   // initialize "Sync On ..." checkboxes
fdfeef ¤   ¤   b = DEFAULT_KEYSERVERSYNCONUNKNOWN;
7366f2 ¤   ¤   PGPGetPrefBoolean (PrefRefClient,·
5c3ac7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefKeyServerSyncUnknownKeys, &b);
4ff708 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_SYNCONUNKNOWN, BST_CHECKED);
7dc9ed ¤   ¤   else CheckDlgButton (hDlg, IDC_SYNCONUNKNOWN, BST_UNCHECKED);
b2af5a
2356a8 ¤   ¤   b = DEFAULT_KEYSERVERSYNCONADDNAME;
80a73a ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefKeyServerSyncOnAdd, &b);
459a8a ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_SYNCONADDNAME, BST_CHECKED);
27ce72 ¤   ¤   else CheckDlgButton (hDlg, IDC_SYNCONADDNAME, BST_UNCHECKED);
05af5a
2970e6 ¤   ¤   b = DEFAULT_KEYSERVERSYNCONKEYSIGN;
8917fc ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefKeyServerSyncOnKeySign, &b);
7390a5 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_SYNCONKEYSIGN, BST_CHECKED);
eac1d3 ¤   ¤   else CheckDlgButton (hDlg, IDC_SYNCONKEYSIGN, BST_UNCHECKED);
0daf5a
245273 ¤   ¤   b = DEFAULT_KEYSERVERSYNCONREVOKE;
7f66f2 ¤   ¤   PGPGetPrefBoolean (PrefRefClient,·
ed4c27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefKeyServerSyncOnRevocation, &b);
72d2a9 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_SYNCONREVOKE, BST_CHECKED);
2a9d86 ¤   ¤   else CheckDlgButton (hDlg, IDC_SYNCONREVOKE, BST_UNCHECKED);
6baf5a
45c420 ¤   ¤   b = DEFAULT_KEYSERVERSYNCONVERIFY;
bae679 ¤   ¤   PGPGetPrefBoolean (PrefRefClient, kPGPPrefKeyServerSyncOnVerify, &b);
d445b3 ¤   ¤   if (b) CheckDlgButton (hDlg, IDC_SYNCONVERIFY, BST_CHECKED);
f31551 ¤   ¤   else CheckDlgButton (hDlg, IDC_SYNCONVERIFY, BST_UNCHECKED);
adaf5a
c6836c ¤   ¤   return TRUE;
d8af5a
5f507d ¤   case WM_KEYDOWN :
8ea283 ¤   case WM_SYSKEYDOWN :
90d558 ¤   case WM_KEYUP :
1b4621 ¤   case WM_CHAR :
f92c68 ¤   ¤   if (GetFocus () == hWndTree)
f06e4d ¤   ¤   ¤   SendMessage (hWndTree, uMsg, wParam, lParam);
d32f68 ¤   ¤   break;
faaf5a
f9c3eb ····case WM_HELP:·
33b426 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
139bb0 ············HELP_WM_HELP, (DWORD) (LPSTR) aServerIds);·
3f8f13 ········break;·
72d83c ·
--75e0 00052b2db0c40110292 Page 24 of CLprefs.c
0a4fd8 ····case WM_CONTEXTMENU:·
1c5ad9 ········WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
7b9b60 ············(DWORD) (LPVOID) aServerIds);·
f28f13 ········break;·
58af5a
b7d1d3 ¤   case WM_COMMAND :
b01185 ¤   ¤   switch (LOWORD (wParam)) {
fe0dd8 ¤   ¤   case IDM_NEWSERVER :
071c0a ¤   ¤   case IDC_NEWKEYSERVER :
0ec214 ¤   ¤   ¤   CLNewKeyserver (hDlg, hWndTree);
c7cdcb ¤   ¤   ¤   break;
8daf5a
54dafa ¤   ¤   case IDM_REMOVESERVER :
9441e0 ¤   ¤   case IDC_REMOVEKEYSERVER :
3fbc7c ¤   ¤   ¤   CLRemoveKeyserver (hDlg, hWndTree);
f0cdcb ¤   ¤   ¤   break;
2faf5a
5eb591 ¤   ¤   case IDM_EDITSERVER :
406fa9 ¤   ¤   case IDC_EDITKEYSERVER :
2e4fe1 ¤   ¤   ¤   CLEditKeyserver (hDlg, hWndTree);
4bcdcb ¤   ¤   ¤   break;
25af5a
ffa4f0 ¤   ¤   case IDM_SETASROOT :
5245fe ¤   ¤   case IDC_SETASROOT :
f856fb ¤   ¤   ¤   CLSetKeyserverAsRoot (hDlg, hWndTree);
40cdcb ¤   ¤   ¤   break;
02af5a
d30fe4 ¤   ¤   }
d02f68 ¤   ¤   break;
faaf5a
881431 ¤   case WM_NOTIFY :
1c59d1 ¤   ¤   if (((NMHDR FAR *) lParam)->hwndFrom == hWndTree) {
05b42b ¤   ¤   ¤   CLProcessKeyserverTreeList (hDlg, hWndTree, wParam, lParam);
2c0fe4 ¤   ¤   }
c507e0 ¤   ¤   else {
1b993d ¤   ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
4d9096 ¤   ¤   ¤   case PSN_SETACTIVE :
69f622 ¤   ¤   ¤   ¤   break;
eb67c5 ¤
43ed66 ¤   ¤   ¤   case PSN_HELP :
075535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
f3b139 ¤   ¤   ¤   ¤   ¤   IDH_PGPCLPREF_KEYSERVERDIALOG);·
04f622 ¤   ¤   ¤   ¤   break;
b267c5 ¤
7a3ea4 ¤   ¤   ¤   case PSN_APPLY :¤
50e3ee ¤   ¤   ¤   ¤   CLSaveKeyserverPrefs (PrefRefClient, hDlg, hWndTree);
77a825 ¤   ¤   ¤   ¤   CLDestroyKeyserverTreeList (hWndTree);
73af5a
2a8511 ¤   ¤   ¤   ¤   // get and save checkbox values
f84db9 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg,IDC_SYNCONUNKNOWN)==BST_CHECKED)·
be711e ¤   ¤   ¤   ¤   ¤   b = TRUE;
c05109 ¤   ¤   ¤   ¤   else·
2fc8cd ¤   ¤   ¤   ¤   ¤   b = FALSE;
e24b62 ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
46ed70 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefKeyServerSyncUnknownKeys, b));
e987c7 ¤   ¤   ¤
13672d ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg,IDC_SYNCONADDNAME) ==
d837d6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
c0711e ¤   ¤   ¤   ¤   ¤   b = TRUE;
4d5109 ¤   ¤   ¤   ¤   else·
2fc8cd ¤   ¤   ¤   ¤   ¤   b = FALSE;
e14b62 ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
ee4ce1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefKeyServerSyncOnAdd, b));
a487c7 ¤   ¤   ¤
4406a3 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg,IDC_SYNCONKEYSIGN) ==
5537d6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
f7711e ¤   ¤   ¤   ¤   ¤   b = TRUE;
375109 ¤   ¤   ¤   ¤   else·
94c8cd ¤   ¤   ¤   ¤   ¤   b = FALSE;
114b62 ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
092e1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefKeyServerSyncOnKeySign, b));
5287c7 ¤   ¤   ¤
--ac57 000ea6632f440110292 Page 25 of CLprefs.c
1a41e7 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg,IDC_SYNCONREVOKE) ==·
4137d6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
69711e ¤   ¤   ¤   ¤   ¤   b = TRUE;
ab5109 ¤   ¤   ¤   ¤   else·
6ec8cd ¤   ¤   ¤   ¤   ¤   b = FALSE;
054b62 ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
566dbe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefKeyServerSyncOnRevocation, b));
2787c7 ¤   ¤   ¤
b8ee9c ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg,IDC_SYNCONVERIFY) ==·
0437d6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
d0711e ¤   ¤   ¤   ¤   ¤   b = TRUE;
715109 ¤   ¤   ¤   ¤   else·
d4c8cd ¤   ¤   ¤   ¤   ¤   b = FALSE;
b34b62 ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, PGPSetPrefBoolean (PrefRefClient,
7db5da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefKeyServerSyncOnVerify, b));
ee2b85 ¤   ¤   ¤   ¤
724fea ¤   ¤   ¤   ¤   bKeyserverPrefsWritten = TRUE;
16af5a
383335 ¤   ¤   ¤   ¤   returnErr = kPGPError_NoErr;
654a08 ¤   ············SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
02d20b ¤   ············return PSNRET_NOERROR;
5167c5 ¤
68b86b ¤   ¤   ¤   case PSN_KILLACTIVE :
b85e7c ¤   ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
6265fe ¤   ············return TRUE;
be67c5 ¤
1a51e5 ¤   ¤   ¤   case PSN_RESET :
f3a825 ¤   ¤   ¤   ¤   CLDestroyKeyserverTreeList (hWndTree);
e665e6 ¤   ¤   ¤   ¤   returnErr = kPGPError_UserAbort;
c05e7c ¤   ············SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
bff622 ¤   ¤   ¤   ¤   break;
39a3a6 ¤   ¤   ¤   }
1f0fe4 ¤   ¤   }
f79371 ¤   }
03af5a
80a230 ¤   return FALSE;
f4af5a
58efe6 }
3faf5a
4aaf5a
330382 //¤ ______________________________________
2a465d //
cb4795 //¤ Check for previously running instances
4aaf5a
f4c9ec static HANDLE·
8c42a5 sShowExistingPropertySheet (
c94b79 ¤   ¤   LPSTR lpszSemName,·
c8d63d ¤   ¤   LPSTR lpszWindowTitle)·
25bb36 {
523ec3 ····HANDLE¤ hSem;
9d7cd9 ····HWND¤   hWndMe;
4baf5a
a518c5 ····// Create or open a named semaphore.·
da0aa8 ····hSem = CreateSemaphore (NULL, 0, 1, lpszSemName);
7eaf5a
43ec6d ····// Close handle and return NULL if existing semaphore was opened.
4057a9 ····if ((hSem != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
4d5806 ········CloseHandle(hSem);
0f746b ········hWndMe = FindWindow ((LPCTSTR)32770L, lpszWindowTitle);
0b5d24 ········if (hWndMe) {
1889c6 ¤   ¤   ¤   SetForegroundWindow (hWndMe);
0f0fe4 ¤   ¤   }
cfb35b ········return NULL;
1b6fe7 ····}
aeaf5a
1f77c9 ····// If new semaphore was created, return FALSE.
39f47a ····return hSem;
4eefe6 }
00d83c ·
ea7f37 //¤ ____________________________
44465d //
eafdd5 // ·Create property sheet dialog
--e001 000341fc1a640110292 Page 26 of CLprefs.c
e0af5a
df9d43 PGPError PGPclExport·
a00b3f PGPclPreferences (
a257dd ¤   ¤   PGPContextRef¤  Context,·
6bfd31 ¤   ¤   HWND¤   ¤   ¤   hWnd,·
918e77 ¤   ¤   INT¤¤   ¤   ¤   startsheet,
3bd026 ¤   ¤   PGPKeySetRef¤   keyset)·
e3bb36 {
62a463 ····PROPSHEETPAGE¤  psp[5];
7b87e6 ····PROPSHEETHEADER psh;
e04bed ¤   UINT¤   ¤   ¤   uNumPages = 0;
856a6e ¤   CHAR¤   ¤   ¤   szTitle[128];
c21d71 ¤   HANDLE¤ ¤   ¤   hSemaphore;
e3fb19 ¤   PGPError¤   ¤   err;
50af5a
9d378f ¤   //assume no KeyServer page
eec169 ¤   uNumPages = (sizeof(psp) / sizeof(PROPSHEETPAGE));·
14af5a
43296a ¤   // get title of property sheet
00014e ¤   LoadString (g_hInst, IDS_PROPCAPTION, szTitle, sizeof(szTitle));
62af5a
643ccf ¤   // if preferences dialog already exists, move it to the foreground
bf8892 ¤   hSemaphore = sShowExistingPropertySheet (PREFSEMAPHORENAME, szTitle);
abaa01 ¤   if (!hSemaphore) return kPGPError_Win32_AlreadyOpen;
78af5a
a2c77c ¤   hWndParent = hWnd;
536bd9 ¤   keysetMain = keyset;
9faf5a
e27ac3 ¤   if (Context != NULL)
dc671e ¤   ¤   ContextRef = Context;
120e24 ¤   else
e24463 ¤   ¤   PGPNewContext (kPGPsdkAPIVersion, &ContextRef);
3baf5a
6d7d3d ¤   PGPsdkLoadDefaultPrefs (ContextRef);
fbaf5a
17dff7 ¤   psp[0].dwSize = sizeof(PROPSHEETPAGE);
8c3842 ¤   psp[0].dwFlags = PSP_USETITLE|PSP_HASHELP;
1963c3 ¤   psp[0].hInstance = g_hInst;
beaff0 ¤   psp[0].pszTemplate = MAKEINTRESOURCE(IDD_PREF0);
17c399 ¤   psp[0].pszIcon = NULL;
cfea50 ¤   psp[0].pfnDlgProc = sEncryptPropDlgProc;
39e7b3 ¤   psp[0].pszTitle = (LPSTR)IDS_TITLE0;
baa7e0 ¤   psp[0].lParam = 0;
e76b49 ¤   psp[0].pfnCallback = NULL;
61af5a
acd2ce ¤   psp[1].dwSize = sizeof(PROPSHEETPAGE);
b072ac ¤   psp[1].dwFlags = PSP_USETITLE|PSP_HASHELP;
8f3887 ¤   psp[1].hInstance = g_hInst;
b58570 ¤   psp[1].pszTemplate = MAKEINTRESOURCE(IDD_PREF1);
4950d0 ¤   psp[1].pszIcon = NULL;
231aa6 ¤   psp[1].pfnDlgProc = sFilePropDlgProc;
78fd0c ¤   psp[1].pszTitle = (LPSTR)IDS_TITLE1;
6cefca ¤   psp[1].lParam = 0;
92e280 ¤   psp[1].pfnCallback = NULL;
3aaf5a
2bc585 ¤   psp[2].dwSize = sizeof(PROPSHEETPAGE);
2dad9e ¤   psp[2].dwFlags = PSP_USETITLE|PSP_HASHELP;
66d54b ¤   psp[2].hInstance = g_hInst;
4dfaf0 ¤   psp[2].pszTemplate = MAKEINTRESOURCE(IDD_PREF2);
87ed1a ¤   psp[2].pszIcon = NULL;
f15dc3 ¤   psp[2].pfnDlgProc = sEmailPropDlgProc;
19d2cd ¤   psp[2].pszTitle = (LPSTR)IDS_TITLE2;
4237b4 ¤   psp[2].lParam = 0;
ef70ca ¤   psp[2].pfnCallback = NULL;
afaf5a
abc8bc ¤   psp[3].dwSize = sizeof(PROPSHEETPAGE);
68e770 ¤   psp[3].dwFlags = PSP_USETITLE|PSP_HASHELP;
008e0f ¤   psp[3].hInstance = g_hInst;
fdd070 ¤   psp[3].pszTemplate = MAKEINTRESOURCE(IDD_PREF3);
c47e53 ¤   psp[3].pszIcon = NULL;
365feb ¤   psp[3].pfnDlgProc = sKeyserverPropDlgProc;
34c872 ¤   psp[3].pszTitle = (LPSTR)IDS_TITLE3;
--62f8 0009158fabb40110292 Page 27 of CLprefs.c
e07f9e ¤   psp[3].lParam = 0;
25f903 ¤   psp[3].pfnCallback = NULL;
68af5a
8aeb13 ¤   psp[4].dwSize = sizeof(PROPSHEETPAGE);
b11beb ¤   psp[4].dwFlags = PSP_USETITLE|PSP_HASHELP;
d006c2 ¤   psp[4].hInstance = g_hInst;
8705f0 ¤   psp[4].pszTemplate = MAKEINTRESOURCE(IDD_PREF4);
7c9e9f ¤   psp[4].pszIcon = NULL;
970f58 ¤   psp[4].pfnDlgProc = sAdvancedPropDlgProc;
c58d4f ¤   psp[4].pszTitle = (LPSTR)IDS_TITLE4;
c68f59 ¤   psp[4].lParam = 0;
655c4f ¤   psp[4].pfnCallback = NULL;
2767c5 ¤
43dbf6 ¤   psh.dwSize = sizeof(PROPSHEETHEADER);
e24f22 ¤   psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
dd9da1 ¤   psh.hwndParent = hWndParent;
265bea ¤   psh.hInstance = g_hInst;
f623fd ¤   psh.pszIcon = NULL;
7b7db8 ¤   psh.pszCaption = (LPSTR) szTitle;
0a3403 ¤   psh.nPages = uNumPages;
f99931 ¤   psh.nStartPage = startsheet;
691328 ¤   psh.ppsp = (LPCPROPSHEETPAGE) &psp;
5a89e0 ¤   psh.pfnCallback = NULL;
21af5a
4a5990 ¤   bNeedsCentering = TRUE;
83bae0 ¤   bReloadKeyring = FALSE;
782c3b ¤   bKeyserverPrefsWritten = FALSE;
d6af5a
f16493 ¤   err = kPGPError_NoErr;
4fbe29 #if PGP_BUSINESS_SECURITY
0e164e #if PGP_ADMIN_BUILD
08654a ¤   err = PGPclOpenAdminPrefs (
afbfe4 ¤   ¤   ¤   PGPGetContextMemoryMgr (ContextRef),
d7c194 ¤   ¤   ¤   &PrefRefAdmin,·
3d5c8c ¤   ¤   ¤   TRUE);
a9db21 #else
fa654a ¤   err = PGPclOpenAdminPrefs (
25bfe4 ¤   ¤   ¤   PGPGetContextMemoryMgr (ContextRef),
9dc194 ¤   ¤   ¤   &PrefRefAdmin,·
b9d54e ¤   ¤   ¤   FALSE);
b57454 #endif
6b7454 #endif
abaf5a
7bb23e ¤   if (IsntPGPError (err)) {
32b40a ¤   ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (ContextRef),
1f17c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &PrefRefClient);
32fc2a ¤   ¤   PropertySheet(&psh);
34af5a
ec7163 ¤   ¤   PGPsdkSavePrefs (ContextRef);
ace284 ¤   ¤   PGPclCloseClientPrefs (PrefRefClient, TRUE);
1e9371 ¤   }
6bbe29 #if PGP_BUSINESS_SECURITY
addf08 ¤   PGPclCloseAdminPrefs (PrefRefAdmin, FALSE);
117454 #endif
7eaf5a
74488d ¤   if (bReloadKeyring) {
ce4c36 ¤   ¤   PGPclNotifyKeyringChanges (0);
be9371 ¤   }
0eaf5a
d8fd4f ¤   if (bKeyserverPrefsWritten) {
33cad3 ¤   ¤   PGPclNotifyKeyserverPrefsChanges (0);¤
709371 ¤   }
38af5a
c34bb3 ¤   PGPclNotifyPrefsChanges (0);
59af5a
71c578 ¤   if (Context == NULL)
83a006 ¤   ¤   PGPFreeContext(ContextRef);
9faf5a
592c6f ¤   CloseHandle (hSemaphore);
49af5a
95359e ····return returnErr;
91efe6 }
--6e70 0019708f26140110292 Page 28 of CLprefs.c
4bd83c ·
daaf5a
97af5a
--ce6e 000200c79de40110293 Page 1 of CLquery.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
264c0f ¤   CLquery.c - selective import dialog
4967c5 ¤
1faf5a
85a44d ¤   $Id: CLquery.c,v 1.10 1998/08/11 14:43:12 pbj Exp $
92f7f7 ____________________________________________________________________________*/
c1e610 #include "pgpPFLConfig.h"
2caf5a
e4c917 // project header files
7c850a #include "pgpkmx.h"
a2af5a
33ad8c // pgp header files
19c97b #include "pgpClientPrefs.h"
b3af5a
77fc2c // system header files
c23ef0 #include <zmouse.h>
d0af5a
ee822f // External globals
10a009 extern HINSTANCE¤   g_hInst;
66579d extern UINT¤¤   ¤   g_uMouseWheelMessage;
ccaf5a
c9f0f7 typedef struct {
b18e1c ¤   PGPContextRef¤  ¤   Context;
7ab4ac ¤   PGPtlsContextRef¤   tlsContext;
b0be7e ¤   LPSTR¤  ¤   ¤   ¤   pszPrompt;
328a56 ¤   PGPKeySetRef¤   ¤   KeySetToAdd;
c441db ¤   PGPKeySetRef¤   ¤   KeySetMain;
8aa30a ¤   HKEYMAN¤¤   ¤   ¤   hKM;
4ce9d6 ¤   KMCONFIG¤   ¤   ¤   KMConfig;
c96329 ¤   CHAR¤   ¤   ¤   ¤   szHelpFile[MAX_PATH];
73886b ¤   HWND¤   ¤   ¤   ¤   hWndTree;
1549cc ¤   INT¤¤   ¤   ¤   ¤   iyOffset;
98705a ¤   INT¤¤   ¤   ¤   ¤   iyTop;
39b449 } QUERYSTRUCT;
eaaf5a
38b4f1 #define IDC_QUERYTREELIST¤  ¤   0x0101
02eef2 #define BUTTONOFFSETX¤  ¤   ¤   20
d849bc #define BUTTONOFFSETY¤  ¤   ¤   10
e5bdd8 #define DIALOGMINWIDTH¤ ¤   ¤   400
941fea #define DIALOGMINHEIGHT¤¤   ¤   140
2eaf5a
1e492e // local globals
cc0a84 static DWORD aIds[] = {¤¤   ¤   // Help IDs
8e3321 ¤   IDOK,¤  ¤   ¤   ¤   IDH_PGPKM_IMPORT,
aaf96a ¤   IDC_SELECTALL,¤ ¤   IDH_PGPKM_IMPORTSELALL,
6d870f ¤   IDC_UNSELECTALL,¤   IDH_PGPKM_IMPORTUNSELALL,
c5a99c ¤   IDC_QUERYTREELIST,¤ IDH_PGPKM_IMPORTLIST,
d74434 ····0,0·
6ca6fe };·
a2af5a
904265 //¤ ___________________________________________________
3f465d //
9aa743 // ·Put up appropriate context menu on basis of selection flags.
e35ff8 // ·Called in response to right mouse click.
c8465d //
e25d68 //¤ hWnd¤   ¤   = handle of parent window
63d58a //¤ uSelFlags¤  = bits indicate what types of objects are selected
f5ee2d //¤ x, y¤   ¤   = mouse position when right button clicked (screen coords)
30af5a
37b333 static VOID·
a8f086 sQueryContextMenu (
c147b2 ¤   ¤   HWND¤   hWnd,·
832b66 ¤   ¤   HKEYMAN hKM,·
5ab730 ¤   ¤   UINT¤   uSelFlags,·
08c2fb ¤   ¤   INT¤¤   x,·
62e7fd ¤   ¤   INT¤¤   y)·
e5bb36 {
d7a46f ¤   HMENU¤  hMC;
20cad4 ¤   HMENU¤  hMenuTrackPopup;
--f175 000030b47b140110293 Page 2 of CLquery.c
97218e ¤   PKEYMAN pKM = (PKEYMAN)hKM;
0baf5a
2c3189 ¤   switch (uSelFlags) {
af8696 ¤   case PGPKM_KEYFLAG :
04c20e ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUIMPORT));
172f68 ¤   ¤   break;
f0af5a
4abfad ¤   default :
cdd02a ¤   ¤   hMC = NULL;
1f2f68 ¤   ¤   break;
d69371 ¤   }
f8af5a
4975a4 ¤   if (!hMC) return;
29aae5 ··¤ hMenuTrackPopup = GetSubMenu (hMC, 0);
088022 ¤   if (KMMultipleSelected (pKM)) {
2f94cb ¤   ¤   EnableMenuItem (hMenuTrackPopup, IDM_KEYPROPERTIES,·
697087 ¤   ¤   ¤   MF_BYCOMMAND|MF_GRAYED);
539371 ¤   }
3caf5a
04966f ¤   TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
818dd9 ¤   ¤   ¤   ¤   ¤   x, y, 0, hWnd, NULL);
95af5a
1a85ee ¤   DestroyMenu (hMC);
4defe6 }
9daf5a
dec509 //¤ ____________________________________
c7465d //
23107a // ·get number of wheel scroll lines and pass to treelist controls
0eaf5a
6ee6b2 static VOID
b5f556 sUpdateWheelScrollLines (QUERYSTRUCT* pqs)
efbb36 {
1f6996 ¤   UINT uLines;
a0af5a
6ead81 ¤   if (!SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &uLines, 0))·
54c7a1 ¤   {
b238a3 ¤   ¤   HWND hwnd = NULL;
58b309 ¤   ¤   UINT umsg = 0;
10af5a
4fc5ed ¤   ¤   umsg = RegisterWindowMessage (MSH_SCROLL_LINES);
87f294 ¤   ¤   hwnd = FindWindow (MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE);
fbaf5a
8f160c ¤   ¤   if (hwnd && umsg)·
4bff8e ¤   ¤   ¤   uLines = (UINT)SendMessage (hwnd, umsg, 0, 0);
ac9371 ¤   }
40af5a
71737e ¤   TreeList_SetWheelScrollLines (pqs->hWndTree, uLines);
d2efe6 }
baaf5a
934265 //¤ ___________________________________________________
63465d //
31f7fc // ·Selective import dialog message procedure
1faf5a
033f64 static BOOL CALLBACK·
044142 sQueryAddDlgProc (
463a3a ¤   ¤   HWND¤   hDlg,·
4aeb77 ¤   ¤   UINT¤   uMsg,·
0d17d4 ¤   ¤   WPARAM¤ wParam,·
b7c0b8 ¤   ¤   LPARAM¤ lParam)·
50bb36 {
131372 ¤   RECT¤   ¤   ¤   rc;
3a96f2 ¤   QUERYSTRUCT*¤   pqs;
516ef0 ¤   INT¤¤   ¤   ¤   ix, iy;
51e0e3 ¤   POINT¤  ¤   ¤   pt;
de02d2 ¤   HWND¤   ¤   ¤   hwndControl;
e52010 ¤   PGPBoolean¤ ¤   b;
c8ae9e ¤   PGPPrefRef¤ ¤   prefRef;
73fa50 ¤   HCURSOR¤¤   ¤   hCursorOld;
8510f4 ¤   CHAR¤   ¤   ¤   sz[16];
80af5a
bd347f ¤   switch (uMsg) {
03af5a
--25bd 0005163574040110293 Page 3 of CLquery.c
b4ad3a ¤   case WM_INITDIALOG :
7f7547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
abe354 ¤   ¤   pqs = (QUERYSTRUCT*)lParam;
20af5a
41dc34 ¤   ¤   // change "OK" button to "Import"
776d96 ¤   ¤   LoadString (g_hInst, IDS_IMPORT, sz, sizeof(sz));
e26788 ¤   ¤   SetDlgItemText (hDlg, IDOK, sz);
f8af5a
e3be6e ¤   ¤   // set prompt text
ec2e62 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_PROMPT);
3de455 ¤   ¤   SetWindowText (hwndControl, pqs->pszPrompt);
73af5a
666a3b ¤   ¤   // create keymanager window
2aee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
99bf14 ¤   ¤   pt.x = rc.left;
6eb7f9 ¤   ¤   pt.y = rc.bottom;
4c8590 ¤   ¤   ScreenToClient (hDlg, &pt);
974b4b ¤   ¤   pqs->iyTop = pt.y;
42af5a
b5390e ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_SELECTALL);
83ee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
5cbf14 ¤   ¤   pt.x = rc.left;
95ce63 ¤   ¤   pt.y = rc.top;
e78590 ¤   ¤   ScreenToClient (hDlg, &pt);
76d1b5 ¤   ¤   iy = pt.y;
bd289b ¤   ¤   GetClientRect (hDlg, &rc);
944daf ¤   ¤   pqs->iyOffset = rc.bottom - (iy - BUTTONOFFSETY) + pqs->iyTop;
bac4a9 ¤   ¤   pqs->hKM = PGPkmCreateKeyManager (pqs->Context, pqs->tlsContext,
0e5e30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_QUERYTREELIST, NULL, 0, pqs->iyTop,·
704d67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right-rc.left,·
7470d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.bottom-pqs->iyOffset);
82af5a
4ad923 ¤   ¤   // configure key manager window
246f1a ¤   ¤   pqs->KMConfig.lpszHelpFile = NULL;
d9d4a2 ¤   ¤   pqs->KMConfig.keyserver.structSize = 0;
c95dd3 ¤   ¤   pqs->KMConfig.hWndStatusBar = NULL;
55e0aa ¤   ¤   pqs->KMConfig.ulDisableActions = KM_ALLACTIONS &·
83eb9b ¤   ¤   ¤   ¤   ~(KM_ADDTOMAIN|KM_SELECTALL|KM_UNSELECTALL|KM_PROPERTIES);
0531f0 ¤   ¤   pqs->KMConfig.ulShowColumns = 0;
6ca567 ¤   ¤   pqs->KMConfig.ulHideColumns = 0;
82a823 ¤   ¤   pqs->KMConfig.ulOptionFlags =·
479d48 ¤   ¤   ¤   KMF_ONLYSELECTKEYS|KMF_READONLY|KMF_MODALPROPERTIES;
9eaf5a
20568e ¤   ¤   // get those options which are based on prefs
451bb7 ¤   ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pqs->Context),
2e96c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefRef);
b94b26 ¤   ¤   PGPGetPrefBoolean (prefRef, kPGPPrefDisplayMarginalValidity, &b);
6fa072 ¤   ¤   if (!b) pqs->KMConfig.ulOptionFlags |= KMF_NOVICEMODE;
3c81e6 ¤   ¤   PGPGetPrefBoolean (prefRef, kPGPPrefMarginalIsInvalid, &b);
256a69 ¤   ¤   if (b) pqs->KMConfig.ulOptionFlags |= KMF_MARGASINVALID;
8006ad ¤   ¤   PGPclCloseClientPrefs (prefRef, FALSE);
21af5a
bb1704 ¤   ¤   pqs->KMConfig.ulMask = PGPKM_ALLITEMS;
ed838a ¤   ¤   PGPkmConfigure (pqs->hKM, &pqs->KMConfig);
c91b52 ¤   ¤
8f2257 ¤   ¤   // will be useful later to have HWND of keymanager
76cecf ¤   ¤   pqs->hWndTree = PGPkmGetManagerWindow (pqs->hKM);
f8af5a
b21b18 ¤   ¤   // initialize keymanager
a25e5e ¤   ¤   PGPkmLoadKeySet (pqs->hKM, pqs->KeySetToAdd, pqs->KeySetMain);
cfce85 ¤   ¤   PGPkmPerformAction (pqs->hKM, KM_SELECTALL);
daaf5a
a9be7e ¤   ¤   // initialize wheel scrolling
b4bc0e ¤   ¤   sUpdateWheelScrollLines (pqs);
94af5a
83dc48 ¤   ¤   // post message to sync keysets
f3f29a ¤   ¤   PostMessage (hDlg, WM_APP, 0, 0);
c9af5a
ac98aa ¤   ¤   return FALSE;
21af5a
5d5020 ¤   case WM_APP :
519602 ¤   ¤   // this syncs the import keyset with the main one
--78a3 000b1aa11cd40110293 Page 4 of CLquery.c
c25a72 ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
7aaf5a
a2f63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
d4ea95 ¤   ¤   PGPclSyncKeySets (pqs->Context,·
0d7041 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pqs->KeySetMain, pqs->KeySetToAdd);
d65e5e ¤   ¤   PGPkmLoadKeySet (pqs->hKM, pqs->KeySetToAdd, pqs->KeySetMain);
90ce85 ¤   ¤   PGPkmPerformAction (pqs->hKM, KM_SELECTALL);
cf7139 ¤   ¤   SetCursor (hCursorOld);
0aaf5a
76c127 ¤   ¤   SetForegroundWindow (hDlg);
effbe3 ¤   ¤   SetFocus (pqs->hWndTree);
472f68 ¤   ¤   break;
1aaf5a
58ae91 ¤   case WM_ACTIVATE :
6d5a72 ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
0afbe3 ¤   ¤   SetFocus (pqs->hWndTree);
052f68 ¤   ¤   break;
6caf5a
df90ef ¤   case WM_SIZE :
e45a72 ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
1caf11 ¤   ¤   // resize keymanager window
1daa7d ¤   ¤   SetWindowPos (pqs->hWndTree, NULL, 0, pqs->iyTop,·
5394cd ¤   ¤   ¤   LOWORD(lParam), HIWORD(lParam) - pqs->iyOffset,·
fbda22 ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);
59af5a
a0d7ce ¤   ¤   // reposition buttons
a5390e ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_SELECTALL);
0bee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
e9bf14 ¤   ¤   pt.x = rc.left;
40ce63 ¤   ¤   pt.y = rc.top;
ef8590 ¤   ¤   ScreenToClient (hDlg, &pt);
60a74e ¤   ¤   ix = pt.x;
0e7681 ¤   ¤   iy = HIWORD(lParam) - pqs->iyOffset + pqs->iyTop + BUTTONOFFSETY;
28330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
0c63ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
feaf5a
a957a0 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_UNSELECTALL);
64ee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
96bf14 ¤   ¤   pt.x = rc.left;
10ce63 ¤   ¤   pt.y = rc.top;
d88590 ¤   ¤   ScreenToClient (hDlg, &pt);
aaa74e ¤   ¤   ix = pt.x;
4a7681 ¤   ¤   iy = HIWORD(lParam) - pqs->iyOffset + pqs->iyTop + BUTTONOFFSETY;
b5330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
2763ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
c0af5a
97b374 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDCANCEL);
2dee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
d0bf14 ¤   ¤   pt.x = rc.left;
91ce63 ¤   ¤   pt.y = rc.top;
d98590 ¤   ¤   ScreenToClient (hDlg, &pt);
1ba74e ¤   ¤   ix = pt.x;
8d7681 ¤   ¤   iy = HIWORD(lParam) - pqs->iyOffset + pqs->iyTop + BUTTONOFFSETY;
99330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
9063ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
c7af5a
81a312 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDOK);
83ee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
cabf14 ¤   ¤   pt.x = rc.left;
15ce63 ¤   ¤   pt.y = rc.top;
1b8590 ¤   ¤   ScreenToClient (hDlg, &pt);
dea74e ¤   ¤   ix = pt.x;
677681 ¤   ¤   iy = HIWORD(lParam) - pqs->iyOffset + pqs->iyTop + BUTTONOFFSETY;
54330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
d063ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
01bbde ¤   ¤   return 0;
aaaf5a
609a87 ¤   case WM_SYSCOLORCHANGE :
ea5a72 ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
2572ca ¤   ¤   PostMessage (pqs->hWndTree, WM_SYSCOLORCHANGE, 0, 0);
a12f68 ¤   ¤   break;
b1af5a
--18ad 000a008ce5d40110293 Page 5 of CLquery.c
4936bc ¤   case WM_SETTINGCHANGE :
885a72 ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
aad6e5 ¤   ¤   if (wParam == SPI_SETWHEELSCROLLLINES)
4eb242 ¤   ¤   ¤   sUpdateWheelScrollLines (pqs);
10ee26 ¤   ¤   else·
9fced3 ¤   ¤   ¤   PostMessage (pqs->hWndTree, WM_SYSCOLORCHANGE, 0, 0);
622f68 ¤   ¤   break;
a3af5a
2bc3eb ····case WM_HELP:·
01f26f ·¤  ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
eba9c1 ¤   ¤   WinHelp (((LPHELPINFO) lParam)->hItemHandle, pqs->szHelpFile,·
bb8e1f ¤   ¤   ¤   HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
3a8f13 ········break;·
61d83c ·
474fd8 ····case WM_CONTEXTMENU:·
e6f26f ·¤  ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
af4ac9 ¤   ¤   WinHelp ((HWND) wParam, pqs->szHelpFile, HELP_CONTEXTMENU,·
413335 ¤   ¤   ¤   (DWORD) (LPVOID) aIds);·
408f13 ········break;·
e0af5a
801431 ¤   case WM_NOTIFY :
973404 ¤   ¤   if (wParam == IDC_QUERYTREELIST) {
9d671c ¤   ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
f37e04 ¤   ¤   ¤   // let keymanager have first whack at the notification
4ff2ab ¤   ¤   ¤   PGPkmDefaultNotificationProc (pqs->hKM, lParam);
7baf5a
523a28 ¤   ¤   ¤   switch (((LPNM_TREELIST)lParam)->hdr.code) {
22a59b ¤   ¤   ¤   // post the context menu
0db838 ¤   ¤   ¤   case TLN_CONTEXTMENU :
9b73bc ¤   ¤   ¤   ¤   sQueryContextMenu (hDlg, pqs->hKM,
77e122 ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->flags,
cbcaa3 ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.x,
d9b27d ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.y);
f7f622 ¤   ¤   ¤   ¤   break;
67af5a
2a76f6 ¤   ¤   ¤   // enable or disable the "import" button depending on whether
2ece7c ¤   ¤   ¤   // item(s) are selected or not
5d87f5 ¤   ¤   ¤   case TLN_SELCHANGED :
463fe0 ¤   ¤   ¤   ¤   if ((((LPNM_TREELIST)lParam)->itemNew.hItem) ||
dccfe4 ¤   ¤   ¤   ¤   ¤   (((LPNM_TREELIST)lParam)->flags & TLC_MULTIPLE))·
83278e ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
c0fa07 ¤   ¤   ¤   ¤   else
bcf627 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
64f622 ¤   ¤   ¤   ¤   break;
4aaf5a
770082 ¤   ¤   ¤   default :
6df622 ¤   ¤   ¤   ¤   break;
c6a3a6 ¤   ¤   ¤   }
4d0fe4 ¤   ¤   }
892f68 ¤   ¤   break;
56af5a
ce84e1 ¤   case KM_M_REQUESTSDKACCESS :
33f26f ·¤  ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
9dcd39 ¤   ¤   PGPkmSynchronizeThreadAccessToSDK (pqs->hKM);
492f68 ¤   ¤   break;
48af5a
be3fcf ¤   case WM_COMMAND:
8caf5a
67537d ¤   ¤   switch (LOWORD(wParam)) {
8eaf5a
458c29 ¤   ¤   case IDOK :
a3671c ¤   ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
487b1d ¤   ¤   ¤   if (PGPkmIsActionEnabled (pqs->hKM, KM_ADDTOMAIN)) {
b9ce01 ¤   ¤   ¤   ¤   PGPkmPerformAction (pqs->hKM, KM_ADDTOMAIN);
89e0a6 ¤   ¤   ¤   ¤   PGPkmDestroyKeyManager (pqs->hKM, FALSE);
5c04ab ¤   ¤   ¤   ¤   KMFree (pqs->hKM);
5273b2 ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_NoErr);
92a3a6 ¤   ¤   ¤   }
59cdcb ¤   ¤   ¤   break;
18af5a
42b6bb ¤   ¤   case IDCANCEL :
a0671c ¤   ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
--45f0 00063907c7a40110293 Page 6 of CLquery.c
53e3d1 ¤   ¤   ¤   PGPkmDestroyKeyManager (pqs->hKM, FALSE);
af88d4 ¤   ¤   ¤   KMFree (pqs->hKM);
c102ba ¤   ¤   ¤   EndDialog (hDlg, kPGPError_UserAbort);
1acdcb ¤   ¤   ¤   break;
05af5a
a0c0c2 ¤   ¤   case IDC_SELECTALL :
37671c ¤   ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
87f550 ¤   ¤   ¤   PGPkmPerformAction (pqs->hKM, KM_SELECTALL);·
d37997 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
7e1490 ¤   ¤   ¤   SetFocus (pqs->hWndTree);
4fcdcb ¤   ¤   ¤   break;
7aaf5a
dc96fd ¤   ¤   case IDC_UNSELECTALL :
05671c ¤   ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
391b0c ¤   ¤   ¤   PGPkmPerformAction (pqs->hKM, KM_UNSELECTALL);·
9f7b39 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
46cdcb ¤   ¤   ¤   break;
09af5a
5b191d ¤   ¤   case IDM_KEYPROPERTIES :
0b671c ¤   ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
451439 ¤   ¤   ¤   PGPkmPerformAction (pqs->hKM, KM_PROPERTIES);·
fdcdcb ¤   ¤   ¤   break;
a4af5a
b23a18 ¤   ¤   default :
09cdcb ¤   ¤   ¤   break;
7d0fe4 ¤   ¤   }
95836c ¤   ¤   return TRUE;
f8af5a
76bfad ¤   default :
bc2f16 ¤   ¤   if (uMsg == g_uMouseWheelMessage) {
dfa20e ¤   ¤   ¤   WORD iDelta;
feaf5a
04671c ¤   ¤   ¤   pqs = (QUERYSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
c1de65 ¤   ¤   ¤   iDelta = (WORD)wParam;
8187c7 ¤   ¤   ¤
157d21 ¤   ¤   ¤   SendMessage (pqs->hWndTree,·
1ee614 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_MOUSEWHEEL, MAKEWPARAM (0, iDelta), 0);
235f1f ¤   ¤   ¤   return FALSE;
bb0fe4 ¤   ¤   }
ac2f68 ¤   ¤   break;
ff9371 ¤   }
bea230 ¤   return FALSE;
c9efe6 }
b9af5a
434265 //¤ ___________________________________________________
08465d //
f8d375 // ·Display and handle selective import dialog
5faf5a
809d43 PGPError PGPclExport·
366b61 PGPclQueryAddKeys (
346bed ¤   ¤   PGPContextRef¤  ¤   Context,
50a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
cf2e03 ¤   ¤   HWND¤   ¤   ¤   ¤   hWndParent,·
4878e4 ¤   ¤   PGPKeySetRef¤   ¤   KeySetToAdd,¤   ¤   ¤
1b7893 ¤   ¤   PGPKeySetRef¤   ¤   KeySetMain)·
e1bb36 {
c9d97b ¤   QUERYSTRUCT¤¤   QueryStruct;
c82a4f ¤   CHAR¤   ¤   ¤   sz[256];
b3af5a
5b793c ¤   QueryStruct.hKM = NULL;
fb41a5 ¤   QueryStruct.Context = Context;
886560 ¤   QueryStruct.tlsContext = tlsContext;
05bd06 ¤   QueryStruct.KeySetToAdd = KeySetToAdd;
7b2878 ¤   QueryStruct.KeySetMain = KeySetMain;
07af5a
72eca7 ¤   PGPclGetPGPPath (QueryStruct.szHelpFile,·
e8463c ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(QueryStruct.szHelpFile));
d8e7c6 ¤   LoadString (g_hInst, IDS_HELPFILENAME, sz, sizeof(sz));
db6822 ¤   lstrcat (QueryStruct.szHelpFile, sz);
b9af5a
a9bcb7 ¤   LoadString (g_hInst, IDS_QUERYADDPROMPT, sz, sizeof(sz));
63c4ff ¤   QueryStruct.pszPrompt = sz;
--7a2b 001e5ba9c2540110293 Page 7 of CLquery.c
e0af5a
ff71ed ¤   return (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_QUERYADD),·
a0f9ca ¤   ¤   ¤   ¤   ¤   hWndParent, sQueryAddDlgProc, (LPARAM)&QueryStruct));
8daf5a
6fefe6 }
e5af5a
--898e 001514a0e4b40110294 Page 1 of CLrand.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
a06bf4 ¤   CLrand.c - post dialog to get entropy from mouse and keyboard
cb67c5 ¤
efaf5a
ca90fe ¤   $Id: CLrand.c,v 1.7 1998/08/11 14:43:13 pbj Exp $
1ff7f7 ____________________________________________________________________________*/
08e610 #include "pgpPFLConfig.h"
46af5a
5ec917 // project header files
a25fcd #include "pgpclx.h"
00af5a
c8ad8c // pgp header files
d4c9be #include "pgpRandomPool.h"
0be684 #include "pgpUserInterface.h"
94af5a
6bd4d4 //¤ ______________________________________________
b2465d //
a4c12c // ·Entropy collection routine -- posts dialog for·
07fe8f // ·mouse/keyboard entropy collection.
b3af5a
0f9d43 PGPError PGPclExport·
29a4e9 PGPclRandom (
92e958 ¤   ¤   PGPContextRef¤  context,
707851 ¤   ¤   HWND¤   ¤   ¤   hwnd,·
63d632 ¤   ¤   UINT¤   ¤   ¤   uNeeded)·
b9bb36 {
538d06 ¤   PGPError err¤   = kPGPError_NoErr;
15af5a
0abd8f ¤   if ((uNeeded != 0) ||
617515 ¤   ¤   !PGPGlobalRandomPoolHasMinimumEntropy ())
f8c7a1 ¤   {
14eafd ¤   ¤   err=PGPCollectRandomDataDialog (
cc58ce ¤   ¤   ¤   context,
24c2ec ¤   ¤   ¤   uNeeded,
a54704 ¤   ¤   ¤   PGPOUIParentWindowHandle (context, hwnd),
826445 ¤   ¤   ¤   PGPOLastOption (context));
b19371 ¤   }
45af5a
6a5ea8 ¤   return err;
51efe6 }
--2886 00052c7aeaa40110295 Page 1 of CLrecip.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
e6e996 ¤   CLrecip.c - Glue code to allow clients to access
d228b3 ¤   ············recipient dialog in PGPsdkUI
05af5a
fe5e0b ¤   $Id: CLrecip.c,v 1.36.2.2 1998/10/01 19:37:24 wjb Exp $
f3f7f7 ____________________________________________________________________________*/
d9e610 #include "pgpPFLConfig.h"
44af5a
d65fcd #include "pgpclx.h"
ade684 #include "pgpUserInterface.h"
8d9cad extern HINSTANCE g_hInst;
6eaf5a
a138e5 /*
64b555 old RECIPIENTDIALOGSTRUCT for reference
daaf5a
ce0846 typedef struct _recipientdialogstruct
f2bb36 {
750e6c ¤   DWORD¤  ¤   ¤   Version;
ca1fb2 ¤   HWND¤   ¤   ¤   hwndParent;
e63bdf ¤   char *¤ ¤   ¤   szTitle;
2c7dae ¤   PGPContextRef¤  Context;
b0cef3 ¤   PGPKeySetRef ¤  OriginalKeySetRef;
de04f4 ¤   PGPKeySetRef ¤  SelectedKeySetRef;
187fe5 ¤   char **¤¤   ¤   szRecipientArray;
7333b7 ¤   DWORD¤  ¤   ¤   dwNumRecipients;
74ca3a ¤   DWORD¤  ¤   ¤   dwOptions;
09ce3b ¤   DWORD¤  ¤   ¤   dwFlags;
a02143 ¤   DWORD¤  ¤   ¤   dwDisableFlags;
8150ec } RECIPIENTDIALOGSTRUCT, *PRECIPIENTDIALOGSTRUCT;
3f7fe0 */
3caf5a
d4484e BOOL DefaultKeyCheck(HWND hwnd,
128382 ¤   ¤   ¤   ¤   PGPKeyRef DefaultKey,
ce85cb ¤   ¤   ¤   ¤   PGPKeySetRef SelectedKeySet)
62bb36 {
6543d6 ····PGPKeyRef key;
e00040 ¤   PGPError err;
e0d83c ·
122b33 ¤   // We don't even know their default key!
b3e840 ¤   if(!PGPKeyRefIsValid(DefaultKey))
4d98aa ¤   ¤   return FALSE;
a2af5a
4e4117 ¤   err=PGPGetDefaultPrivateKey(SelectedKeySet,&key);
aaaf5a
e6ee15 ¤   if(IsPGPError(err))
d898aa ¤   ¤   return FALSE;
ccaf5a
bdc2e7 ¤   return TRUE;
6defe6 }
45af5a
26a309 BOOL RSACheck(HWND hwnd,
348a07 ¤   ¤   ¤   ···PGPKeySetRef SelectedKeySet)
e6bb36 {
b590ab ····PGPKeyListRef list;
861c6a ····PGPKeyIterRef iter;
6443d6 ····PGPKeyRef key;
c567b5 ¤   PGPBoolean FoundRSAKey;
0dcf9d ¤   PGPInt32 algorithm;
31de7b ··
bd9f43 ····PGPOrderKeySet(SelectedKeySet,kPGPReverseUserIDOrdering,&list);
4a0e30 ····PGPNewKeyIter(list,&iter);
14af5a
7042da ¤   FoundRSAKey=FALSE;
76af5a
f01ff6 ····while (IsntPGPError(PGPKeyIterNext(iter,&key)))
923b37 ····{
664be4 ¤   ¤   PGPGetKeyNumber( key, kPGPKeyPropAlgID, &algorithm );
24ba41 ¤   ¤   if(algorithm == kPGPPublicKeyAlgorithm_RSA)
525091 ¤   ¤   ¤   FoundRSAKey=TRUE;
--d71e 0007c16c55f40110295 Page 2 of CLrecip.c
a19371 ¤   }
93af5a
064560 ¤   PGPFreeKeyIter(iter);
793ee1 ····PGPFreeKeyList(list);
2cd83c ·
b68cad ¤   return FoundRSAKey;
bbefe6 }
c5af5a
d463f4 BOOL CorpCheck(HWND hwnd,
654055 ¤   ¤   ¤   ···PGPKeySetRef MainKeySet,
8df4bf ¤   ¤   ¤   ···PGPKeySetRef SelectedKeySet,
6cb7fe ¤   ¤   ¤   ···PGPKeyRef CorpKey)
e5bb36 {
a6ee5c ····PGPUserIDRef userID;
2190ab ····PGPKeyListRef list;
251c6a ····PGPKeyIterRef iter;
0443d6 ····PGPKeyRef key;
9c34f5 ¤   char UserIDStr[kPGPMaxUserIDSize];
95f234 ¤   int len;
5c63a9 ¤   PGPBoolean SignedByCorp;
9b0040 ¤   PGPError err;
110e40 ··¤ PGPSigRef sig;
285fdf ¤   PGPKeyRef certifierKey;
15d83c ·
539f43 ····PGPOrderKeySet(SelectedKeySet,kPGPReverseUserIDOrdering,&list);
5d0e30 ····PGPNewKeyIter(list,&iter);
35af5a
f41ff6 ····while (IsntPGPError(PGPKeyIterNext(iter,&key)))
c33b37 ····{
5c9763 ¤   ¤   SignedByCorp=FALSE;
c269e2 ¤   ¤   strcpy(UserIDStr,"");
baaf5a
7c1126 ········while (IsntPGPError(PGPKeyIterNextUserID(iter, &userID)))
c62b60 ········{
3a3aa5 ¤   ¤   ¤   if(!strcmp(UserIDStr,""))
52f776 ¤   ¤   ¤   {
4d8a53 ¤   ¤   ¤   ¤   PGPGetUserIDStringBuffer(userID, kPGPUserIDPropName,
2beef5 ····¤   ¤   ¤   ¤   kPGPMaxUserIDSize-1, UserIDStr, &len);
28a3a6 ¤   ¤   ¤   }
5caf5a
8480a6 ¤   ¤   ¤   while(IsntPGPError(err=PGPKeyIterNextUIDSig(iter,&sig)))
0cf776 ¤   ¤   ¤   {
16f4df ¤   ¤   ¤   ¤   err = PGPGetSigCertifierKey(
ecb00c ¤   ¤   ¤   ¤   ¤   sig, MainKeySet, &certifierKey);
6baf5a
2699ff ¤   ¤   ¤   ¤   if(IsntPGPError(err))
d772c3 ¤   ¤   ¤   ¤   {
2130da ¤   ¤   ¤   ¤   ¤   if(certifierKey == CorpKey)
19e57b ¤   ¤   ¤   ¤   ¤   ¤   SignedByCorp=TRUE;
fe2613 ¤   ¤   ¤   ¤   }
57a3a6 ¤   ¤   ¤   }
cb0fe4 ¤   ¤   }
221b52 ¤   ¤
15ed25 ¤   ¤   if(!SignedByCorp)
c25b34 ¤   ¤   {
30de5a ¤   ¤   ¤   UINT msgrst;
c42893 ¤   ¤   ¤   char StrRes[500];
73af5a
25d3cc ¤   ¤   ¤   LoadString (g_hInst, IDS_KEYNOTSIGNEDBYCORP,·
7771fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes, sizeof(StrRes));
d1af5a
f86a34 ¤   ¤   ¤   msgrst=MessageBox(hwnd,StrRes,UserIDStr,
750267 ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND);
53af5a
55d770 ¤   ¤   ¤   if(msgrst==IDNO)
0cf776 ¤   ¤   ¤   {
d0144f ¤   ¤   ¤   ¤   PGPFreeKeyIter(iter);
f38f56 ¤   ¤   ¤   ¤   PGPFreeKeyList(list);
56af5a
8fd64b ¤   ¤   ¤   ¤   return FALSE;
07a3a6 ¤   ¤   ¤   }
7c0fe4 ¤   ¤   }
--9d3c 000cc61d92140110295 Page 3 of CLrecip.c
a19371 ¤   }
93af5a
064560 ¤   PGPFreeKeyIter(iter);
793ee1 ····PGPFreeKeyList(list);
2cd83c ·
a4c2e7 ¤   return TRUE;
01efe6 }
f2af5a
c376d6 typedef struct·
6ebb36 {
8cf133 ¤   // Admins Prefs
bd9831 ¤   PGPBoolean allowConvEncrypt;
214a8a ¤   PGPBoolean WarnNotCorpSigned;
a3565c ¤   PGPBoolean haveOutgoingADK;
da9c24 ¤   PGPBoolean enforceOutgoingADK;
0d6543 ¤   PGPBoolean enforceRemoteADKClass;
da892f ¤   PGPKeyRef corpKey;
02a834 ¤   PGPKeyRef outgoingADK;
01af5a
b0eb6b ¤   // Client Prefs
5cf4a7 ¤   PGPBoolean bWarnOnADK;
febca0 ¤   PGPBoolean showMarginalValidity;
38ce5d ¤   PGPBoolean marginalIsInvalid;
1dca6a ¤   PGPBoolean encryptToSelf;
1b5055 ¤   PGPBoolean synchUnknown;
e52184 ¤   PGPKeyRef defaultKey;
daaf5a
70fd74 ¤   // KeyServer (Client) Prefs
53e903 ¤   PGPKeyServerEntry *ksEntries;
ba75f6 ¤   PGPUInt32 numKSEntries;
1261ae ¤   PGPKeyServerSpec *serverList;
d388f6 ¤   PCLIENTSERVERSTRUCT¤pcss;
ee7bab } APREF;
7eaf5a
26041f void NoDefaultKey(HWND hwnd)
9cbb36 {
c2aec5 ¤   PGPclMessageBox(hwnd,IDS_CAPTIONERROR,IDS_NOVALIDDEFAULTKEY,
73035a ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
0cefe6 }
d9af5a
52828d void NoOutADKKey(HWND hwnd)
93bb36 {
179dd5 ¤   PGPclMessageBox(hwnd,IDS_CAPTIONERROR,IDS_NOOUTADK,
d3cee2 ¤   ¤   MB_OK|MB_ICONSTOP);
e8efe6 }
38af5a
05eaec void NoCorpKey(HWND hwnd)
9cbb36 {
a2880b ¤   PGPclMessageBox(hwnd,IDS_CAPTIONERROR,IDS_NOCORPSIGNKEY,
77cee2 ¤   ¤   MB_OK|MB_ICONSTOP);
e3efe6 }
59af5a
1eae18 PGPError GrabRecipClientPrefs(HWND hwndParent,
c0f276 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPContextRef context,
a7dff9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPKeySetRef keyset,
e7f22a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··APREF *apref)
f2bb36 {
931605 ¤   PGPMemoryMgrRef¤memMgr;
14597c ¤   PGPPrefRef¤ clientPrefsRef;
7761e0 ¤   PGPError¤   err;
44af5a
f489c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
27af5a
d1b3f4 ¤   err=PGPclOpenClientPrefs (memMgr,&clientPrefsRef);
faaf5a
4ac8d0 ¤   if(IsntPGPError(err))
26c7a1 ¤   {
2dbc31 ¤   ¤   err=CLInitKeyServerPrefs(
924d11 ¤   ¤   ¤   PGPCL_DEFAULTSERVER,NULL,
329312 ¤   ¤   ¤   hwndParent,
ec58ce ¤   ¤   ¤   context,
cc4d06 ¤   ¤   ¤   keyset,
--f2ce 0006d880e3a40110295 Page 4 of CLrecip.c
9ae1ce ¤   ¤   ¤   clientPrefsRef,"",
9e4e51 ¤   ¤   ¤   &(apref->pcss),
a3f2ca ¤   ¤   ¤   &(apref->ksEntries),
0d2b7b ¤   ¤   ¤   &(apref->serverList),
22f155 ¤   ¤   ¤   &(apref->numKSEntries));
93af5a
a38a6c ¤   ¤   PGPGetPrefBoolean( clientPrefsRef, kPGPPrefWarnOnADK,·
0b4886 ¤   ¤   ¤   ¤   &(apref->bWarnOnADK));
4767d4 ¤   ¤   PGPGetPrefBoolean( clientPrefsRef, kPGPPrefDisplayMarginalValidity,
9a4997 ¤   ¤   ¤   ¤   &(apref->showMarginalValidity));
72e017 ¤   ¤   PGPGetPrefBoolean( clientPrefsRef, kPGPPrefMarginalIsInvalid,
57503d ¤   ¤   ¤   ¤   &(apref->marginalIsInvalid));
3f1404 ¤   ¤   PGPGetPrefBoolean( clientPrefsRef, kPGPPrefEncryptToSelf,
e0d31b ¤   ¤   ¤   ¤   &(apref->encryptToSelf));
bc009a ¤   ¤   PGPGetPrefBoolean( clientPrefsRef, kPGPPrefKeyServerSyncUnknownKeys,
0ad02d ¤   ¤   ¤   ¤   &(apref->synchUnknown));
43b7bb ¤   ¤   PGPclCloseClientPrefs (clientPrefsRef, FALSE);
0f9371 ¤   }
08af5a
a4c8d0 ¤   if(IsntPGPError(err))
46c7a1 ¤   {
41c613 ¤   ¤   err=PGPGetDefaultPrivateKey(keyset,&(apref->defaultKey));
09af5a
241870 ¤   ¤   if(IsPGPError(err))
e75b34 ¤   ¤   {
9430b4 ¤   ¤   ¤   // Warning message here
3cf836 ¤   ¤   ¤   apref->defaultKey=NULL;
52c1a6 ¤   ¤   ¤   err=kPGPError_NoErr;
640fe4 ¤   ¤   }
d09371 ¤   }
3baf5a
e35ea8 ¤   return err;
d9efe6 }
41af5a
66ab52 PGPError GrabRecipAdminPrefs(HWND hwndParent,
02a930 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPContextRef context,
ba6686 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPKeySetRef keyset,
9412c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·APREF *apref)
53bb36 {
4e2196 ¤   PGPByte¤¤   *adKeyID;
60b7e8 ¤   PGPSize¤¤   adKeyIDSize;
5f0502 ¤   PGPUInt32¤  adKeyAlgorithm;
2a4829 ¤   PGPByte¤¤   *corpKeyID;
415f2a ¤   PGPSize¤¤   corpKeyIDSize;
09ad7a ¤   PGPUInt32¤  corpKeyAlgorithm;
231605 ¤   PGPMemoryMgrRef¤memMgr;
0052da ¤   PGPPrefRef¤ adminPrefsRef;
a361e0 ¤   PGPError¤   err;
efaf5a
a489c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
f2af5a
f831d9 #if PGP_ADMIN_BUILD¤
9f20bb ¤   err = PGPclOpenAdminPrefs (memMgr,&adminPrefsRef, TRUE);
4edb21 #else
6f900e ¤   err = PGPclOpenAdminPrefs (memMgr,&adminPrefsRef, FALSE);
f4d835 #endif¤ // PGP_BUSINESS_SECURITY_ADMIN
33af5a
cdc8d0 ¤   if(IsntPGPError(err))
53c7a1 ¤   {
073173 ¤   ¤   // Allow Conventional
70d6dc ¤   ¤   PGPGetPrefBoolean( adminPrefsRef,
6647e5 ¤   ¤   ¤   kPGPPrefAllowConventionalEncryption,
22cd2b ¤   ¤   ¤   &(apref->allowConvEncrypt));
a3af5a
f77f99 ¤   ¤   // Warn if recipient not signed by corp key
94d6dc ¤   ¤   PGPGetPrefBoolean( adminPrefsRef,
804a65 ¤   ¤   ¤   kPGPPrefWarnNotCertByCorp,
22b9e7 ¤   ¤   ¤   &(apref->WarnNotCorpSigned));
19af5a
5afa29 ¤   ¤   // Use an outgoing ADK
5f397b ¤   ¤   PGPGetPrefBoolean( adminPrefsRef,·
6d6f5f ¤   ¤   ¤   kPGPPrefUseOutgoingADK,
--0d6b 0002336ec4840110295 Page 5 of CLrecip.c
1f4ff9 ¤   ¤   ¤   &(apref->haveOutgoingADK));
64af5a
76b888 ¤   ¤   // Enforce this outgoing ADK
56397b ¤   ¤   PGPGetPrefBoolean( adminPrefsRef,·
e50d6a ¤   ¤   ¤   kPGPPrefEnforceOutgoingADK,
7cfcc8 ¤   ¤   ¤   &(apref->enforceOutgoingADK));
49af5a
cec730 ¤   ¤   // Enforce remote ADKs
f3d6dc ¤   ¤   PGPGetPrefBoolean( adminPrefsRef,
912fae ¤   ¤   ¤   kPGPPrefEnforceRemoteADKClass,
5eda0b ¤   ¤   ¤   &(apref->enforceRemoteADKClass));
5aaf5a
518f7b ¤   ¤   // Get corp key ref
672518 ¤   ¤   PGPGetPrefData(adminPrefsRef,·
97b562 ¤   ¤   ¤   kPGPPrefCorpKeyID,·
635f06 ¤   ¤   ¤   &corpKeyIDSize,·
c85cc5 ¤   ¤   ¤   &corpKeyID);
caaf5a
907f9f ¤   ¤   PGPGetPrefNumber( adminPrefsRef,
e28838 ¤   ¤   ¤   kPGPPrefCorpKeyPublicKeyAlgorithm,·
777c2a ¤   ¤   ¤   &corpKeyAlgorithm);
37af5a
8d1892 ¤   ¤   // Get outgoing adk key
36f8fe ¤   ¤   PGPGetPrefData( adminPrefsRef,·
62fbbf ¤   ¤   ¤   kPGPPrefOutgoingADKID,
700384 ¤   ¤   ¤   &adKeyIDSize, &adKeyID );
1eaf5a
647f9f ¤   ¤   PGPGetPrefNumber( adminPrefsRef,
8ff1fb ¤   ¤   ¤   kPGPPrefOutADKPublicKeyAlgorithm,
a98872 ¤   ¤   ¤   &adKeyAlgorithm );
40af5a
f111db ¤   ¤   PGPclCloseAdminPrefs (adminPrefsRef, FALSE);
1f9371 ¤   }
e7af5a
b7d1d9 ¤   if((apref->haveOutgoingADK)&&(IsntPGPError(err)))
dac7a1 ¤   {
2aac89 ¤   ¤   err=PGPclGetKeyFromKeyID (
fb58ce ¤   ¤   ¤   context,
4f4d06 ¤   ¤   ¤   keyset,
aaa474 ¤   ¤   ¤   adKeyID,
9283bd ¤   ¤   ¤   adKeyAlgorithm,
4d6130 ¤   ¤   ¤   &(apref->outgoingADK));
8daf5a
121870 ¤   ¤   if(IsPGPError(err))
975b34 ¤   ¤   {
8f30b4 ¤   ¤   ¤   // Warning message here
9ad6fc ¤   ¤   ¤   apref->outgoingADK=NULL;
58c1a6 ¤   ¤   ¤   err=kPGPError_NoErr;
7e0fe4 ¤   ¤   }
f99371 ¤   }
f767c5 ¤
9dd852 ¤   if(adKeyID)
6946f1 ¤   ¤   PGPDisposePrefData( adminPrefsRef, adKeyID);
99af5a
0c88b3 ¤   if((apref->WarnNotCorpSigned)&&(IsntPGPError(err)))
32c7a1 ¤   {
9eac89 ¤   ¤   err=PGPclGetKeyFromKeyID (
8d58ce ¤   ¤   ¤   context,
4e4d06 ¤   ¤   ¤   keyset,
4d0dbc ¤   ¤   ¤   corpKeyID,
69b9fb ¤   ¤   ¤   corpKeyAlgorithm,
3fe648 ¤   ¤   ¤   &(apref->corpKey));
16af5a
bf1870 ¤   ¤   if(IsPGPError(err))
225b34 ¤   ¤   {
a530b4 ¤   ¤   ¤   // Warning message here
9dc711 ¤   ¤   ¤   apref->corpKey=NULL;
5ec1a6 ¤   ¤   ¤   err=kPGPError_NoErr;
140fe4 ¤   ¤   }
4e9371 ¤   }
64af5a
23d35b ¤   if(corpKeyID)
--98bc 000e784653340110295 Page 6 of CLrecip.c
f72ad4 ¤   ¤   PGPDisposePrefData( adminPrefsRef, corpKeyID);
89af5a
455ea8 ¤   return err;
60efe6 }
19af5a
3eb561 UINT PGPclExport PGPclRecipientDialog(PRECIPIENTDIALOGSTRUCT prds)
2abb36 {
fee4f3 ¤   PGPOptionListRef¤   ¤   ¤   rdoptionList;
24613c ¤   PGPOptionListRef¤   ¤   ¤   optionList;
ed3a03 ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   conventionalEncrypt,
0cb2f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   textOutput,
9828d4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wipeOriginal,
4487d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   fyeo;
75cf7e ¤   Boolean¤¤   ¤   ¤   ¤   ¤   haveFileOptions;
be5ab3 ¤   PGPclGROUPFILE¤ ¤   ¤   ¤   *pGroup;
1090b8 ¤   PGPKeySetRef¤   ¤   ¤   ¤   foundKeys;
ac6cb7 ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   numKeys;
7e385c ¤   APREF¤  ¤   ¤   ¤   ¤   ¤   apref;
3d42a5 ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   arrEnforcement;
eb06ee ¤   PGPError¤   ¤   ¤   ¤   ¤   err;
522ff9 ¤   char¤   ¤   ¤   ¤   ¤   ¤   StrRes1[100],StrRes2[300],StrRes3[100];
0baf5a
fe1a4c ¤   memset(&apref,0x00,sizeof(APREF));
cc27b6 ¤   apref.allowConvEncrypt = TRUE;
73af5a
0c125b ¤   pGroup=NULL;
d64ead ¤   err=kPGPError_NoErr;
95bc43 ¤   foundKeys=kPGPInvalidRef;
5f10a3 ¤   rdoptionList = kInvalidPGPOptionListRef;
072d4e ¤   optionList = kInvalidPGPOptionListRef;
cb5242 ¤   haveFileOptions=FALSE;
469ae6 ¤   arrEnforcement = kPGPARREnforcement_Warn;
0aac66 ¤   textOutput=conventionalEncrypt=wipeOriginal=fyeo=0;
6caf5a
1bd33d ¤   // Create Null Option List for recipient dialog
aa2662 ¤   err = PGPBuildOptionList( prds->Context, &rdoptionList,
72bc14 ¤   ¤   PGPOLastOption( prds->Context ) );
baaf5a
4311b8 // ******************BUSINESS SECURITY***********************
91f270 #if PGP_BUSINESS_SECURITY || PGP_ADMIN_BUILD
1daf5a
48c8d0 ¤   if(IsntPGPError(err))
bdc7a1 ¤   {
8a3323 ¤   ¤   err=GrabRecipAdminPrefs(prds->hwndParent,
dcc52f ¤   ¤   ¤   ¤   ¤   prds->Context,
4f3ad5 ¤   ¤   ¤   ¤   ¤   prds->OriginalKeySetRef,
359bc0 ¤   ¤   ¤   ¤   ¤   &apref);
339371 ¤   }
c3af5a
1dc8d0 ¤   if(IsntPGPError(err))
a7c7a1 ¤   {
f5d5d8 ¤   ¤   arrEnforcement = kPGPARREnforcement_Warn;
91af5a
889885 ¤   ¤   if(apref.enforceRemoteADKClass)
e89bc4 ¤   ¤   ¤   arrEnforcement=kPGPARREnforcement_Strict;
acaf5a
3a5130 ¤   ¤   if(apref.WarnNotCorpSigned)
2d5b34 ¤   ¤   {
ee82d3 ¤   ¤   ¤   if(apref.corpKey==NULL)
06f776 ¤   ¤   ¤   {
a1dfd1 // Warn if we can't find it AND exit since required.
9ba988 ¤   ¤   ¤   ¤   NoCorpKey(prds->hwndParent);
12d64b ¤   ¤   ¤   ¤   return FALSE;
b9a3a6 ¤   ¤   ¤   }
720fe4 ¤   ¤   }
83af5a
005d0f ¤   ¤   if(apref.haveOutgoingADK)
c45b34 ¤   ¤   {
cd364e ¤   ¤   ¤   if(PGPKeyRefIsValid(apref.outgoingADK))
4ff776 ¤   ¤   ¤   {
d3676a ¤   ¤   ¤   ¤   PGPRecipientSpec¤   spec;
e71b52 ¤   ¤
--6b25 0000ae9eebe40110295 Page 7 of CLrecip.c
f4ab18 ¤   ¤   ¤   ¤   pgpClearMemory( &spec, sizeof( spec ) );
642b85 ¤   ¤   ¤   ¤
e5b050 ¤   ¤   ¤   ¤   spec.type¤  = kPGPRecipientSpecType_Key;
9501dc ¤   ¤   ¤   ¤   spec.locked¤= apref.enforceOutgoingADK;
25a355 ¤   ¤   ¤   ¤   spec.u.key¤ = apref.outgoingADK;
1587c7 ¤   ¤   ¤
85de3b ¤   ¤   ¤   ¤   err = PGPAppendOptionList( rdoptionList,
27e0d6 ¤   ¤   ¤   ¤   ¤   PGPOUIDefaultRecipients( prds->Context, 1, &spec ),
2ae419 ¤   ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
31a3a6 ¤   ¤   ¤   }
29bb8c ¤   ¤   ¤   else
daf776 ¤   ¤   ¤   {
da13b7 ¤   ¤   ¤   ¤   if(apref.enforceOutgoingADK)
8572c3 ¤   ¤   ¤   ¤   {
004835 ¤   ¤   ¤   ¤   ¤   // HaveOutgoing, Enforced, but no key? No way!
d282ee ¤   ¤   ¤   ¤   ¤   NoOutADKKey(prds->hwndParent);
dbd1ff ¤   ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
532613 ¤   ¤   ¤   ¤   }
d2fa07 ¤   ¤   ¤   ¤   else
7c72c3 ¤   ¤   ¤   ¤   {
04b37b ¤   ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
f32613 ¤   ¤   ¤   ¤   }
52a3a6 ¤   ¤   ¤   }
fe0fe4 ¤   ¤   }
d59371 ¤   }
bd8e60 #endif¤
9e44f3 // ******************END BUSINESS SECURITY*******************
9faf5a
09b5c8 ¤   // Get client prefs
e8c8d0 ¤   if(IsntPGPError(err))
23c7a1 ¤   {
ebfa90 ¤   ¤   err=GrabRecipClientPrefs(prds->hwndParent,
d25d78 ¤   ¤   ¤   prds->Context,
f53980 ¤   ¤   ¤   prds->OriginalKeySetRef,
931e4c ¤   ¤   ¤   &apref);
6c9371 ¤   }
94af5a
f0e49d ¤   // Add recipients
ba7f61 ¤   if((IsntPGPError(err))&&
6732de ¤   ¤   (prds->szRecipientArray!=NULL)&&
28302b ¤   ¤   (prds->dwNumRecipients!=0))
b8c7a1 ¤   {
7c2080 ¤   ¤   PGPRecipientSpec¤   *spec;
256f8e ¤   ¤   int memamt,i;
79af5a
04f986 ¤   ¤   memamt=sizeof(PGPRecipientSpec)*prds->dwNumRecipients;
0743fe ¤   ¤   spec=(PGPRecipientSpec *)malloc(memamt);
f264f5 ¤   ¤   memset(spec,0x00,memamt);
02af5a
d4bbc4 ¤   ¤   for(i=0;i<(int)prds->dwNumRecipients;i++)
b95b34 ¤   ¤   {
0533d8 ¤   ¤   ¤   spec[i].type=kPGPRecipientSpecType_UserID;
38ae0c ¤   ¤   ¤   strcpy(spec[i].u.userIDStr,prds->szRecipientArray[i]);
ac0fe4 ¤   ¤   }
53ae30 ¤   ¤   ¤   ¤   ¤
bae213 ¤   ¤   err = PGPAppendOptionList( rdoptionList,
dee604 ¤   ¤   ¤   PGPOUIDefaultRecipients( prds->Context,
d8ce7f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prds->dwNumRecipients,spec),
712d8c ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
3d87c7 ¤   ¤   ¤
bcbfd5 ¤   ¤   free(spec);
b99371 ¤   }
a7af5a
f3fe62 ¤   // Open groups file
3cb1f0 ¤   if( IsntPGPError( err ) )
a2c7a1 ¤   {
ebdb46 ¤   ¤   err=PGPclOpenGroupFile (prds->Context,&pGroup);
ca87c7 ¤   ¤   ¤
274184 ¤   ¤   if(IsntPGPError(err))
cc5b34 ¤   ¤   {
5ab108 ¤   ¤   ¤   err = PGPAppendOptionList( rdoptionList,
0a1df6 ¤   ¤   ¤   ¤   PGPOUIRecipientGroups( prds->Context, pGroup->groupset ),
--4bd2 000cad14ddc40110295 Page 8 of CLrecip.c
c5f53e ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
ca0fe4 ¤   ¤   }
479371 ¤   }
72af5a
5dd866 ¤   // AddDefaultKey
92a264 ¤   if( IsntPGPError( err ) && apref.encryptToSelf )
c6c7a1 ¤   {
e26452 ¤   ¤   if(PGPKeyRefIsValid(apref.defaultKey))
6e5b34 ¤   ¤   {
255b84 ¤   ¤   ¤   PGPRecipientSpec¤   spec;
b82b85 ¤   ¤   ¤   ¤
2ac42b ¤   ¤   ¤   pgpClearMemory( &spec, sizeof( spec ) );
a5ae30 ¤   ¤   ¤   ¤   ¤
d3df63 ¤   ¤   ¤   spec.type¤  = kPGPRecipientSpecType_Key;
06006f ¤   ¤   ¤   spec.u.key¤ = apref.defaultKey;
c494aa ¤   ¤   ¤   ¤   ¤   ¤
e2b108 ¤   ¤   ¤   err = PGPAppendOptionList( rdoptionList,
39aea1 ¤   ¤   ¤   ¤   PGPOUIDefaultRecipients( prds->Context, 1, &spec ),
98f53e ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
280fe4 ¤   ¤   }
e50e1d ¤   ¤   else
ea5b34 ¤   ¤   {
1d3cf3 ¤   ¤   ¤   NoDefaultKey(prds->hwndParent);
2f0fe4 ¤   ¤   }
839371 ¤   }
3caf5a
014a18 ¤   // Make options control
1cb1f0 ¤   if( IsntPGPError( err ) )
b9c7a1 ¤   {
d1148a ¤   ¤   err = PGPBuildOptionList( prds->Context, &optionList,
702d8c ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
c3af5a
186e81 ¤   ¤   if(prds->dwOptions&PGPCL_ASCIIARMOR)
81fd17 ¤   ¤   ¤   textOutput=1;
59af5a
290456 ¤   ¤   if((prds->dwOptions&PGPCL_PASSONLY)&&(apref.allowConvEncrypt))
8be623 ¤   ¤   ¤   conventionalEncrypt=1;
c8af5a
c496a7 ¤   ¤   if(prds->dwOptions&PGPCL_WIPEORIG)
bd6b92 ¤   ¤   ¤   wipeOriginal=1;
ccaf5a
b1b36b ¤   ¤   if(prds->dwOptions&PGPCL_FYEO)
9f9420 ¤   ¤   ¤   fyeo=1;
8faf5a
f19275 ¤   ¤   if(!(prds->dwDisableFlags&PGPCL_DISABLE_ASCIIARMOR))
af5b34 ¤   ¤   {
dab93c ¤   ¤   ¤   haveFileOptions=TRUE;
d33c4e ¤   ¤   ¤   LoadString (g_hInst, IDS_TEXTOUTPUT, StrRes1, sizeof(StrRes1));
60af5a
f4bab6 ¤   ¤   ¤   err = PGPAppendOptionList( optionList,
11aced ¤   ¤   ¤   ¤   ¤   ¤   PGPOUICheckbox( prds->Context, 801,
4a6dd1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes1,NULL,
d8b97c ¤   ¤   ¤   ¤   ¤   ¤   ¤   textOutput, &textOutput ),
71e322 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
b40fe4 ¤   ¤   }
f4af5a
3eaa8e ¤   ¤   if((!(prds->dwDisableFlags&PGPCL_DISABLE_PASSONLY))&&
3023a4 ¤   ¤   ¤   (apref.allowConvEncrypt))
915b34 ¤   ¤   {
33b93c ¤   ¤   ¤   haveFileOptions=TRUE;
4fda60 ¤   ¤   ¤   LoadString (g_hInst, IDS_CONVENCRYPTION,·
b3b3b7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes2, sizeof(StrRes2));
eaaf5a
4abab6 ¤   ¤   ¤   err = PGPAppendOptionList( optionList,
ba4389 ¤   ¤   ¤   ¤   ¤   ¤   PGPOUICheckbox( prds->Context, 802,
a9e701 ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes2,NULL,
bbdbbb ¤   ¤   ¤   ¤   ¤   ¤   ¤   conventionalEncrypt, &conventionalEncrypt ),
75e322 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
920fe4 ¤   ¤   }
4baf5a
0538d6 ¤   ¤   if(!(prds->dwDisableFlags&PGPCL_DISABLE_WIPEORIG))
ca5b34 ¤   ¤   {
--ab5c 000ad8f1bbf40110295 Page 9 of CLrecip.c
91b93c ¤   ¤   ¤   haveFileOptions=TRUE;
970f52 ¤   ¤   ¤   LoadString (g_hInst, IDS_WIPEORIGINAL, StrRes3, sizeof(StrRes3));
41af5a
3ebab6 ¤   ¤   ¤   err = PGPAppendOptionList( optionList,
791955 ¤   ¤   ¤   ¤   ¤   ¤   PGPOUICheckbox( prds->Context, 803,
1466be ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes3,NULL,
1f0699 ¤   ¤   ¤   ¤   ¤   ¤   ¤   wipeOriginal, &wipeOriginal ),
cde322 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
9d0fe4 ¤   ¤   }
69af5a
6452c3 ¤   ¤   if(!(prds->dwDisableFlags&PGPCL_DISABLE_FYEO))
1d5b34 ¤   ¤   {
9db93c ¤   ¤   ¤   haveFileOptions=TRUE;
d583c7 ¤   ¤   ¤   LoadString (g_hInst, IDS_FYEO, StrRes3, sizeof(StrRes3));
fbaf5a
78bab6 ¤   ¤   ¤   err = PGPAppendOptionList( optionList,
e2cf8c ¤   ¤   ¤   ¤   ¤   ¤   PGPOUICheckbox( prds->Context, 805,
a966be ¤   ¤   ¤   ¤   ¤   ¤   ¤   StrRes3,NULL,
245559 ¤   ¤   ¤   ¤   ¤   ¤   ¤   wipeOriginal, &fyeo ),
01e322 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
fd0fe4 ¤   ¤   }
0c9371 ¤   }
19af5a
72df9b ¤   if( IsntPGPError( err ) && ( haveFileOptions ))
99c7a1 ¤   {
24e213 ¤   ¤   err = PGPAppendOptionList( rdoptionList,
f2a7ae ¤   ¤   ¤   ¤   PGPOUIDialogOptions( prds->Context,
988012 ¤   ¤   ¤   ¤   ¤   optionList,
013c80 ¤   ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) ),
cdf53e ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
7b9371 ¤   }
f9af5a
fd45fb ¤   // Call recipient dialog
9c9f7f ¤   if( IsntPGPError( err ))
7cc7a1 ¤   {
3c732b ¤   ¤   err=PGPRecipientDialog(prds->Context,
5f3980 ¤   ¤   ¤   prds->OriginalKeySetRef,
57b6d5 ¤   ¤   ¤   (unsigned char)(prds->dwDisableFlags&PGPCL_DISABLE_AUTOMODE),
c0867f ¤   ¤   ¤   &(prds->SelectedKeySetRef),
335912 ¤   ¤   ¤   rdoptionList,
e1eac2 ¤   ¤   ¤   PGPOUIParentWindowHandle(prds->Context,prds->hwndParent),
cc44c5 ¤   ¤   ¤   PGPOUIWindowTitle(prds->Context,prds->szTitle),
d74851 ¤   ¤   ¤   PGPOUIDisplayMarginalValidity( prds->Context,·
140204 ¤   ¤   ¤   ¤   apref.showMarginalValidity ),
d9012c ¤   ¤   ¤   PGPOUIIgnoreMarginalValidity( prds->Context,·
b953da ¤   ¤   ¤   ¤   apref.marginalIsInvalid ),
a19f59 ¤   ¤   ¤   PGPOUIKeyServerUpdateParams(prds->Context,
e1cc6b ¤   ¤   ¤   ¤   apref.numKSEntries,
a12583 ¤   ¤   ¤   ¤   apref.serverList, prds->tlsContext,
60f572 ¤   ¤   ¤   ¤   apref.synchUnknown,&foundKeys,
a82da7 ¤   ¤   ¤   ¤   PGPOLastOption( prds->Context ) ),
9eb542 ¤   ¤   ¤   PGPOUIEnforceAdditionalRecipientRequests( prds->Context,
e0c547 ¤   ¤   ¤   ¤   arrEnforcement, apref.bWarnOnADK ),
852d8c ¤   ¤   ¤   PGPOLastOption( prds->Context ) );
24af5a
ad1c41 ¤   ¤   // If we had options, read the results and send em back
7d3f05 ¤   ¤   if( IsntPGPError( err ) && haveFileOptions )
695b34 ¤   ¤   {
e2acc8 ¤   ¤   ¤   prds->dwOptions&=(~PGPCL_ASCIIARMOR);
1d87c7 ¤   ¤   ¤
bf066c ¤   ¤   ¤   if( textOutput != 0 )
2e5e7a ¤   ¤   ¤   ¤   prds->dwOptions |= PGPCL_ASCIIARMOR;
8caf5a
ad1413 ¤   ¤   ¤   prds->dwOptions&=(~PGPCL_PASSONLY);
78af5a
d1ca70 ¤   ¤   ¤   if( conventionalEncrypt != 0 )
776a95 ¤   ¤   ¤   ¤   prds->dwOptions |= PGPCL_PASSONLY;
6eaf5a
9d75e1 ¤   ¤   ¤   prds->dwOptions&=(~PGPCL_WIPEORIG);
b3af5a
55760f ¤   ¤   ¤   if( wipeOriginal != 0 )
ad8ed7 ¤   ¤   ¤   ¤   prds->dwOptions |= PGPCL_WIPEORIG;
--d0e9 000fa53cb2140110295 Page 10 of CLrecip.c
e0af5a
757ef5 ¤   ¤   ¤   prds->dwOptions&=(~PGPCL_FYEO);
96af5a
2f6fa4 ¤   ¤   ¤   if( fyeo != 0 )
21b05c ¤   ¤   ¤   ¤   prds->dwOptions |= PGPCL_FYEO;
610fe4 ¤   ¤   }
2d9371 ¤   }
89af5a
f16682 ¤   CLUninitKeyServerPrefs(PGPCL_DEFAULTSERVER,
ead1b7 ¤   ¤   apref.pcss,apref.ksEntries,
cae83d ¤   ¤   apref.serverList,apref.numKSEntries);
4caf5a
560f43 ¤   if(optionList)
03153d ¤   ¤   PGPFreeOptionList( optionList );
b8af5a
fb4171 ¤   if(rdoptionList)
28cd05 ¤   ¤   PGPFreeOptionList( rdoptionList );
3baf5a
785b25 ¤   if(pGroup)
8637d9 ¤   ¤   PGPclCloseGroupFile(pGroup);
4baf5a
c7d79f ¤   prds->AddedKeys=foundKeys;
d3af5a
a3cdfc ¤   // Do some last minute checks
6fc8d0 ¤   if(IsntPGPError(err))
b2c7a1 ¤   {
1ea189 ¤   ¤   PGPCountKeys( prds->SelectedKeySetRef, &numKeys );
47af5a
55c35b ¤   ¤   if((numKeys==0)&&(!conventionalEncrypt))
a25b34 ¤   ¤   {
ada8f1 ¤   ¤   ¤   PGPclMessageBox(prds->hwndParent,
c4a8aa ¤   ¤   ¤   ¤   IDS_CAPTIONERROR,IDS_ATLEASTONEORCONV,
e4e840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
3d5f1f ¤   ¤   ¤   return FALSE;
e60fe4 ¤   ¤   }
b8af5a
7e948b ¤   ¤   // Check to make sure they have encrypted to
0e03fc ¤   ¤   // themselves if WIPEORIG is checked.
bb98e1 ¤   ¤   if((prds->dwOptions&PGPCL_WIPEORIG)&&
abbf4e ¤   ¤   ¤   ((prds->dwOptions&PGPCL_PASSONLY)==0))
4a5b34 ¤   ¤   {
c030b1 ¤   ¤   ¤   if(!DefaultKeyCheck(prds->hwndParent,
de9664 ¤   ¤   ¤   ¤   apref.defaultKey,
585316 ¤   ¤   ¤   ¤   prds->SelectedKeySetRef))
03f776 ¤   ¤   ¤   {
ced5d4 ¤   ¤   ¤   ¤   int msgrst;
f667c5 ¤
641a36 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_CAPTION,·
cbb47f ¤   ¤   ¤   ¤   ¤   StrRes1, sizeof(StrRes1));
5be2de ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_WIPEWODEFAULT,·
3bf007 ¤   ¤   ¤   ¤   ¤   StrRes2, sizeof(StrRes2));
70af5a
76ca9e ¤   ¤   ¤   ¤   msgrst=MessageBox(prds->hwndParent,StrRes2,StrRes1,
0b8f9b ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND);
e2af5a
716c26 ¤   ¤   ¤   ¤   if(msgrst==IDNO)
3ee143 ¤   ¤   ¤   ¤   ¤   return FALSE;
3ea3a6 ¤   ¤   ¤   }
8d0fe4 ¤   ¤   }
0daf5a
15a67e ¤   ¤   prds->dwFlags&=(~PGPCL_RSAENCRYPT);
32af5a
da6e60 ¤   ¤   // So passphrase dialog can check for DSS/RSA combo
f5f0e8 ¤   ¤   if(RSACheck(prds->hwndParent,
426ff8 ¤   ¤   ¤   prds->SelectedKeySetRef))
015b34 ¤   ¤   {
307a53 ¤   ¤   ¤   prds->dwFlags |= PGPCL_RSAENCRYPT;
170fe4 ¤   ¤   }
84af5a
d911b8 // ******************BUSINESS SECURITY***********************
e4f270 #if PGP_BUSINESS_SECURITY || PGP_ADMIN_BUILD
fab045 ¤   ¤   if((apref.WarnNotCorpSigned)&&(!conventionalEncrypt))
--2907 001bd3cc86740110295 Page 11 of CLrecip.c
e35b34 ¤   ¤   {
c446a5 ¤   ¤   ¤   if(!CorpCheck(prds->hwndParent,
ec3c6d ¤   ¤   ¤   ¤   prds->OriginalKeySetRef,
51f66a ¤   ¤   ¤   ¤   prds->SelectedKeySetRef,
901abf ¤   ¤   ¤   ¤   apref.corpKey))
569285 ¤   ¤   ¤   ¤   err=kPGPError_UserAbort;
240fe4 ¤   ¤   }
a88e60 #endif¤
7c44f3 // ******************END BUSINESS SECURITY*******************
e99371 ¤   }
50af5a
fcee15 ¤   if(IsPGPError(err))
b098aa ¤   ¤   return FALSE;
bbaf5a
d3c2e7 ¤   return TRUE;
81efe6 }
bdaf5a
--663c 00086e21db840110296 Page 1 of CLrecon.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
6d490e ¤   CLrecon.c - reconstitute key shares routines
a967c5 ¤
74af5a
779ba5 ¤   $Id: CLrecon.c,v 1.39 1998/08/11 14:43:14 pbj Exp $
2af7f7 ____________________________________________________________________________*/
4f2194 #include "pgpPFLConfig.h"¤  /* or pgpConfig.h in the CDK */
78af5a
b4c917 // project header files
415fcd #include "pgpclx.h"
3b850a #include "pgpkmx.h"
bcaf5a
36ad8c // pgp header files
7931ed #include "PGPskep.h"
74add5 #include "pgpShareFile.h"
ffaf5a
63fc2c // system header files
166bd4 #include <commdlg.h>
bcaf5a
c793ed // external globals
31eec0 extern HINSTANCE¤   ¤   g_hInst;
050afe extern CHAR g_szHelpFile[MAX_PATH];
f3af5a
a55584 // constant definitions
476b7d #define INITIAL_SHAREKEY_COLUMNWIDTH¤   250
b06a6a #define UNKNOWN_SHARES_NEEDED¤  ¤   ¤   999999
1caf5a
1a5bee // typedefs
d1f0f7 typedef struct {
db7925 ¤   PGPContextRef¤  ¤   context;
6eb4ac ¤   PGPtlsContextRef¤   tlsContext;
d0b040 ¤   HWND¤   ¤   ¤   ¤   hwndDlg;
0cb864 ¤   HWND¤   ¤   ¤   ¤   hwndList;
2447fb ¤   HIMAGELIST¤ ¤   ¤   hIml;
6fb604 ¤   PGPKeySetRef¤   ¤   keyset;
c08486 ¤   PGPKeyRef¤  ¤   ¤   keyToReconstitute;
93d618 ¤   PGPKeyID¤   ¤   ¤   keyidToReconstitute;
6eaf8d ¤   PGPKeyRef¤  ¤   ¤   keyAuthenticating;
cd2582 ¤   PGPKeySetRef¤   ¤   keysetDecryption;
72e8d1 ¤   PGPUInt32¤  ¤   ¤   iKeyIDCount;
6de19a ¤   PGPKeyID*¤  ¤   ¤   keyidsDecryption;
e99343 ¤   PGPKeySetRef¤   ¤   keysetToAdd;
d62402 ¤   CHAR¤   ¤   ¤   ¤   szAuthUserID[kPGPMaxUserIDSize+1];
ec4ac6 ¤   LPSTR¤  ¤   ¤   ¤   pszPhraseAuth;
b5516f ¤   PGPByte*¤   ¤   ¤   pPasskeyAuth;
4537e0 ¤   PGPSize¤¤   ¤   ¤   sizePasskeyAuth;
f6f887 ¤   UINT¤   ¤   ¤   ¤   uNeededShares;
bc6d8b ¤   UINT¤   ¤   ¤   ¤   uCollectedShares;
b4e3d3 ¤   PGPShareRef¤¤   ¤   sharesCombined;
448b18 ¤   PGPskepRef¤ ¤   ¤   skep;
285097 ¤   INT¤¤   ¤   ¤   ¤   iIconIndex;
dd5227 ¤   BOOL¤   ¤   ¤   ¤   bServerMode;
3d418b ¤   BOOL¤   ¤   ¤   ¤   bStop;
4b30f4 ¤   BOOL¤   ¤   ¤   ¤   bUserCancel;
e25795 ¤   BOOL¤   ¤   ¤   ¤   bUserOK;
0de23a ¤   BOOL¤   ¤   ¤   ¤   bBadPassphrase;
78712e ¤   CRITICAL_SECTION¤   critsecAddShare;
a4c60e } RECONKEYSTRUCT, *PRECONKEYSTRUCT;
a3af5a
8394fd // help IDs
87406f static DWORD aIds[] = {¤
affea0 ¤   IDC_NETWORK,¤   ¤   IDH_PGPCLRECON_STARTNETWORK, // must be first ID
7f4e41 ¤   IDC_KEYTORECON,¤¤   IDH_PGPCLRECON_KEYTORECON,
f74b89 ¤   IDC_SHAREHOLDERS,¤  IDH_PGPCLRECON_SHAREHOLDERLIST,
4234e7 ¤   IDC_SHARESCOLLECTED,IDH_PGPCLRECON_SHARESCOLLECTED,
dbb47b ¤   IDC_SHARESNEEDED,¤  IDH_PGPCLRECON_SHARESNEEDED,
6fffe0 ¤   IDC_STATUS,¤¤   ¤   IDH_PGPCLRECON_NETWORKSTATUS,
1fb682 ¤   IDC_AUTHENTICATION,¤IDH_PGPCLRECON_NETWORKAUTHENTICATION,
860440 ¤   IDC_SHAREFILE,¤ ¤   IDH_PGPCLRECON_SELECTSHAREFILE,
--4ef9 0004470720b40110296 Page 2 of CLrecon.c
364434 ····0,0·
5fa6fe };·
d0af5a
53af5a
b4d4d4 //¤ ______________________________________________
b6465d //
77f6d2 // ·Initialize ListView
d6af5a
56b333 static VOID·
e6089c sInitKeyList (PRECONKEYSTRUCT prks)·
b8bb36 {
7faf5a
7ec89d ¤   LV_COLUMN¤  lvC;·
84cdba ¤   CHAR¤   ¤   sz[256];
20f493 ¤   HBITMAP¤¤   hBmp;
7e18a8 ¤   HDC¤¤   ¤   hDC;
870863 ¤   INT¤¤   ¤   iNumBits;
bcaf5a
384f7a ¤   // create image list
7c7f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
1589fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
4ee693 ¤   ReleaseDC (NULL, hDC);
5caf5a
342be4 ¤   if (iNumBits <= 8) {
91123f ¤   ¤   prks->hIml = ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
856d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
8c9694 ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
43d470 ¤   ¤   ImageList_AddMasked (prks->hIml, hBmp, RGB(255, 0, 255));
685c8d ¤   ¤   DeleteObject (hBmp);
589371 ¤   }
f1665a ¤   else {
a5a19b ¤   ¤   prks->hIml = ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
8f6d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
f7bb8b ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
cdd470 ¤   ¤   ImageList_AddMasked (prks->hIml, hBmp, RGB(255, 0, 255));
a95c8d ¤   ¤   DeleteObject (hBmp);
819371 ¤   }
6faf5a
2df039 ¤   ListView_SetImageList (prks->hwndList, prks->hIml, LVSIL_SMALL);
feaf5a
613e53 ¤   lvC.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
c24e45 ¤   lvC.fmt = LVCFMT_LEFT;·
a934b0 ¤   lvC.pszText = sz;
e0af5a
9e5e6b ¤   LoadString (g_hInst, IDS_USERID, sz, sizeof(sz));
8ddae1 ¤   lvC.cx = INITIAL_SHAREKEY_COLUMNWIDTH; ··
5114af ¤   lvC.iSubItem = 0;
4411c9 ¤   if (ListView_InsertColumn (prks->hwndList, 0, &lvC) == -1) return;
b6af5a
2e3450 ¤   LoadString (g_hInst, IDS_SHARES, sz, sizeof(sz));
599e8b ¤   lvC.cx = 50; ··
de4e73 ¤   lvC.iSubItem = 1;
394a8d ¤   if (ListView_InsertColumn (prks->hwndList, 1, &lvC) == -1) return;
76efe6 }
d5af5a
2daf5a
a3d4d4 //¤ ______________________________________________
fb465d //
584fee // ·decode event handler
61af5a
8ff1ae static PGPError
89a4ce sHandlerDecode (
27e958 ¤   ¤   PGPContextRef¤  context,
7e5b49 ¤   ¤   PGPEvent*¤  ¤   event,
59c05f ¤   ¤   PGPUserValue¤   userValue)
b6bb36 {
607637 ¤   PGPError¤   ¤   err¤¤   = kPGPError_NoErr;
0965fc ¤   PRECONKEYSTRUCT¤prks;
50af5a
bfa48f ¤   switch (event->type) {
866062 ¤   case kPGPEvent_PassphraseEvent:
445b34 ¤   ¤   {
--0736 0003fdbf7eb40110296 Page 3 of CLrecon.c
ac1fc9 ¤   ¤   ¤   LPSTR¤  ¤   psz¤¤   ¤   = NULL;
523f7c ¤   ¤   ¤   PGPByte*¤   pbyte¤  ¤   = NULL;
cc28f8 ¤   ¤   ¤   PGPSize¤¤   size;
2153cc ¤   ¤   ¤   UINT¤   ¤   uLen;
eefe7c ¤   ¤   ¤   CHAR¤   ¤   szPrompt[64];
6aaf5a
108d0d ¤   ¤   ¤   prks = (PRECONKEYSTRUCT)userValue;
b5af5a
c1cb51 ¤   ¤   ¤   if (!prks->bBadPassphrase)
820c77 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_DECRYPTSHARESPROMPT,·
bdc2b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szPrompt, sizeof(szPrompt));
20bb8c ¤   ¤   ¤   else
5dc0ad ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_BADSHAREFILEPASSPHRASE,·
d8c2b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szPrompt, sizeof(szPrompt));
ffaf5a
629222 ¤   ¤   ¤   if (event->data.passphraseData.fConventional) {
55e5fa ¤   ¤   ¤   ¤   err = KMGetKeyPhrase (context, prks->tlsContext,·
441865 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->hwndDlg, szPrompt, prks->keyset,·
7a9620 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, &psz, &pbyte, &size);
7a0ea2 ¤   ¤   ¤   ¤   prks->iIconIndex = IDX_HEAD;
69a3a6 ¤   ¤   ¤   }
d8e543 ¤   ¤   ¤   else {
2220e7 ¤   ¤   ¤   ¤   err = KMGetDecryptionPhrase (context, prks->tlsContext,·
261865 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->hwndDlg, szPrompt, prks->keyset,·
3f7571 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, prks->keysetDecryption,
8b1464 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->iKeyIDCount, prks->keyidsDecryption,
e3c74f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prks->keysetToAdd, &psz, &pbyte, &size);
3f01fe ¤   ¤   ¤   ¤   prks->iIconIndex = IDX_DSAUSERID;
78a3a6 ¤   ¤   ¤   }
b2af5a
e96a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
ceaa9a ¤   ¤   ¤   ¤   if (psz) {
f7c965 ¤   ¤   ¤   ¤   ¤   uLen = lstrlen (psz);
0b1814 ¤   ¤   ¤   ¤   ¤   PGPAddJobOptions (event->job,·
0df3df ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphraseBuffer (context, psz, uLen),
992323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
8c2613 ¤   ¤   ¤   ¤   }
a3deaa ¤   ¤   ¤   ¤   else {
2c1814 ¤   ¤   ¤   ¤   ¤   PGPAddJobOptions (event->job,·
0e5906 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pbyte, size),
ac2323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
942613 ¤   ¤   ¤   ¤   }
bea3a6 ¤   ¤   ¤   }
edaf5a
c319bb ¤   ¤   ¤   if (psz)·
9891e5 ¤   ¤   ¤   ¤   KMFreePhrase (psz);
ccaf5a
209239 ¤   ¤   ¤   if (pbyte)
f5c535 ¤   ¤   ¤   ¤   KMFreePasskey (pbyte, size);
c0af5a
3661db ¤   ¤   ¤   // If passphrase event comes up again, the passphrase
729910 ¤   ¤   ¤   // must have been bad
29af5a
d616c5 ¤   ¤   ¤   prks->bBadPassphrase = TRUE;
450fe4 ¤   ¤   }
212f68 ¤   ¤   break;
d7af5a
ac589b ¤   case kPGPEvent_RecipientsEvent:
715b34 ¤   ¤   {
7fde29 ¤   ¤   ¤   PGPUInt32¤  i;
79af5a
101b50 ¤   ¤   ¤   PGPEventRecipientsData *pData = &event->data.recipientsData;
5d8d0d ¤   ¤   ¤   prks = (PRECONKEYSTRUCT)userValue;
f01b52 ¤   ¤
825bee ¤   ¤   ¤   // Save recipient key set for passphrase dialog
b10140 ¤   ¤   ¤   prks->keysetDecryption = pData->recipientSet;
ec3318 ¤   ¤   ¤   PGPIncKeySetRefCount (prks->keysetDecryption);
cbaf5a
78c4df ¤   ¤   ¤   // Save unknown keyids
f46e21 ¤   ¤   ¤   if (pData->keyCount > 0) {
8da402 ¤   ¤   ¤   ¤   prks->iKeyIDCount = pData->keyCount;
3fc1d1 ¤   ¤   ¤   ¤   prks->keyidsDecryption =·
--aab9 00095ad24b340110296 Page 4 of CLrecon.c
6562c5 ¤   ¤   ¤   ¤   ¤   (PGPKeyID *)clAlloc (pData->keyCount * sizeof(PGPKeyID));
49af5a
baa1a5 ¤   ¤   ¤   ¤   for (i=0; i<pData->keyCount; i++) {
ad5143 ¤   ¤   ¤   ¤   ¤   prks->keyidsDecryption[i] = pData->keyIDArray[i];
ac2613 ¤   ¤   ¤   ¤   }
a0a3a6 ¤   ¤   ¤   }
0a0fe4 ¤   ¤   }
7b2f68 ¤   ¤   break;
e09371 ¤   }
a7af5a
b35ea8 ¤   return err;
73efe6 }
f5af5a
24af5a
8ed4d4 //¤ ______________________________________________
ac465d //
995df7 // ·add shareholder to listview control
6baf5a
d36c77 static BOOL·
295a74 sAddShareHolderToList (
2bd84e ¤   ¤   PRECONKEYSTRUCT prks,·
21023e ¤   ¤   LPSTR¤  ¤   ¤   pszName,
9888ba ¤   ¤   UINT¤   ¤   ¤   uShares)
19bb36 {
ec2329 ¤   LV_ITEM¤¤   lvI;
d7b3a6 ¤   INT¤¤   ¤   iItem;¤
9ceb14 ¤   CHAR¤   ¤   sz[16];
6daf5a
385161 ¤   // figure item index to use
61f1a8 ¤   iItem = ListView_GetItemCount (prks->hwndList);
57af5a
78ba62 ¤   // insert listview item
6210fd ¤   lvI.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE;
707fa6 ¤   lvI.state = 0; ·····
fe9ef0 ¤   lvI.stateMask = 0;
b25f3b ¤   lvI.iImage = prks->iIconIndex;
22af5a
356d1a ¤   lvI.iItem = iItem;
d1505a ¤   lvI.iSubItem = 0;
d10709 ¤   lvI.pszText¤= pszName;·
0cfa85 ¤   lvI.cchTextMax = 0;
4eaf5a
19a1be ¤   iItem = ListView_InsertItem (prks->hwndList, &lvI);
0de2a5 ¤   if (iItem == -1) {
7a98aa ¤   ¤   return FALSE;
c79371 ¤   }
d2665a ¤   else {
fe2c02 ¤   ¤   // add strings for Shares column
80f196 ¤   ¤   wsprintf (sz, "%i", uShares);
6b979b ¤   ¤   ListView_SetItemText (prks->hwndList, iItem, 1, sz);
51836c ¤   ¤   return TRUE;
309371 ¤   }
f6efe6 }
deaf5a
5caf5a
6cd4d4 //¤ ______________________________________________
f2465d //
0e8325 // ·add share file to list
c4af5a
dcb333 static VOID·
1a0b7b sAddShareFile (
8f7851 ¤   ¤   HWND¤   ¤   ¤   hwnd,·
3e4a89 ¤   ¤   PRECONKEYSTRUCT¤prks)
33bb36 {
449a58 ¤   PFLFileSpecRef¤ ¤   fileref¤¤   ¤   ¤   = NULL;
677f56 ¤   PGPShareFileRef¤¤   sharefileref¤   ¤   = NULL;
8f984f ¤   PGPOptionListRef¤   optionsDecode¤  ¤   = NULL;
2d0c85 ¤   PGPShareRef¤¤   ¤   shares¤ ¤   ¤   ¤   = NULL;
7d4910 ¤   PGPShareRef¤¤   ¤   sharesTemp¤ ¤   ¤   = NULL;
4c3f1b ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
5baf5a
957b0b ¤   OPENFILENAME¤   ofn;
--4b61 0008ababc9140110296 Page 5 of CLrecon.c
c2ad7a ¤   LPSTR¤  ¤   ¤   p;
c863e2 ¤   CHAR¤   ¤   ¤   szFile[MAX_PATH];
a10b06 ¤   CHAR¤   ¤   ¤   szName[kPGPMaxUserIDSize+1];
d02a4f ¤   CHAR¤   ¤   ¤   sz[256];
2876ca ¤   CHAR¤   ¤   ¤   szTitle[64];
073d81 ¤   PGPUInt32¤  ¤   size;
cfb6a6 ¤   PGPUInt32¤  ¤   uNumShares;
904fe2 ¤   UINT¤   ¤   ¤   uThreshold;
aa4c97 ¤   PGPKeyID¤   ¤   keyid;
59af5a
7c84a9 ¤   // initialize
3763cf ¤   prks->keysetToAdd¤  ¤   = kInvalidPGPKeySetRef;
6f4e04 ¤   prks->keysetDecryption¤ = kInvalidPGPKeySetRef;
0d56a4 ¤   prks->iKeyIDCount¤  ¤   = 0;
d46432 ¤   prks->keyidsDecryption¤ = NULL;
79af5a
d4a673 ¤   // prompt user for name of share file to send
156632 ¤   szFile[0] = '\0';
c365df ¤   LoadString (g_hInst, IDS_SHAREFILEFILTER, sz, sizeof(sz));
3868d7 ¤   while (p = strrchr (sz, '@')) *p = '\0';
6348d3 ¤   LoadString (g_hInst, IDS_SHAREFILECAPTION, szTitle, sizeof(szTitle));
80af5a
444fd0 ¤   ofn.lStructSize ······= sizeof (OPENFILENAME);
6b9214 ¤   ofn.hwndOwner ········= hwnd;
bba756 ¤   ofn.hInstance ········= (HANDLE)g_hInst;
10d0b3 ¤   ofn.lpstrFilter ······= sz;
ab3385 ¤   ofn.lpstrCustomFilter = (LPTSTR)NULL;
afe9dc ¤   ofn.nMaxCustFilter ···= 0L;
2280b6 ¤   ofn.nFilterIndex ·····= 1L;
054e92 ¤   ofn.lpstrFile ········= szFile;
8ae317 ¤   ofn.nMaxFile ·········= sizeof (szFile);
e6d176 ¤   ofn.lpstrFileTitle ···= NULL;
1d8734 ¤   ofn.nMaxFileTitle ····= 0;
a93225 ¤   ofn.lpstrInitialDir ··= NULL;
48006e ¤   ofn.lpstrTitle ·······= szTitle;
cbac75 ¤   ofn.Flags¤  ¤   ¤   ··= OFN_HIDEREADONLY;
7d0d2e ¤   ofn.nFileOffset ······= 0;
eac4f3 ¤   ofn.nFileExtension ···= 0;
642fcb ¤   ofn.lpstrDefExt ······= "";
52ebd4 ¤   ofn.lCustData ········= 0;
feaf5a
3f09d1 ¤   EnterCriticalSection (&prks->critsecAddShare);
5eaf5a
0463b6 ¤   if (GetOpenFileName (&ofn)) {
7b08dc ¤   ¤   err = PFLNewFileSpecFromFullPath (
aba8f7 ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (prks->context), szFile, &fileref);
c57755 ¤   ¤   if (IsPGPError (err)) goto AddCleanup;
16d83c ·
78a342 ¤   ¤   err = PGPOpenShareFile (fileref, &sharefileref);
c27755 ¤   ¤   if (IsPGPError (err)) goto AddCleanup;
97af5a
a8556d ¤   ¤   err = PGPGetShareFileSharedKeyID (sharefileref, &keyid);
0f7755 ¤   ¤   if (IsPGPError (err)) goto AddCleanup;
51af5a
19b080 ¤   ¤   if (PGPCompareKeyIDs (&keyid, &(prks->keyidToReconstitute))) {
367276 ¤   ¤   ¤   PGPclMessageBox (prks->hwndDlg, IDS_CAPTION,·
dbeb68 ¤   ¤   ¤   ¤   ¤   ¤   IDS_SHAREKEYMISMATCH, MB_OK|MB_ICONEXCLAMATION);
f541dd ¤   ¤   ¤   goto AddCleanup;
230fe4 ¤   ¤   }
a7af5a
3c5cb7 ¤   ¤   // check that threshold corresponds to other share files
c61fd2 ¤   ¤   uThreshold = PGPGetShareThresholdInFile (sharefileref);
d6af68 ¤   ¤   if (prks->uNeededShares != UNKNOWN_SHARES_NEEDED) {
f3339c ¤   ¤   ¤   if (uThreshold != prks->uNeededShares) {
a19076 ¤   ¤   ¤   ¤   PGPclMessageBox (prks->hwndDlg, IDS_CAPTION,·
231436 ¤   ¤   ¤   ¤   ¤   ¤   IDS_SHARENUMMISMATCH, MB_OK|MB_ICONEXCLAMATION);
65fa8b ¤   ¤   ¤   ¤   goto AddCleanup;
53a3a6 ¤   ¤   ¤   }
b20fe4 ¤   ¤   }
ecaf5a
b43c62 ¤   ¤   err = PGPGetShareFileUserID (sharefileref,
8a51e9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szName), szName, &size);
--ca8e 000ec9fafc640110296 Page 6 of CLrecon.c
d37755 ¤   ¤   if (IsPGPError (err)) goto AddCleanup;
f7af5a
569d22 ¤   ¤   uNumShares = PGPGetNumSharesInFile (sharefileref);
54af5a
292851 ¤   ¤   // decrypt specified share file
5c9c1a ¤   ¤   prks->bBadPassphrase = FALSE;
1f8f1b ¤   ¤   PGPBuildOptionList (prks->context, &optionsDecode,
62cb58 ¤   ¤   ¤   ¤   ¤   PGPOKeySetRef (prks->context, prks->keyset),
96852b ¤   ¤   ¤   ¤   ¤   PGPOEventHandler (prks->context, sHandlerDecode, prks),
023c7b ¤   ¤   ¤   ¤   ¤   PGPOLastOption (prks->context));
f22d6a ¤   ¤   err = PGPCopySharesFromFile (prks->context, sharefileref,·
65b858 ¤   ¤   ¤   ¤   ¤   ¤   optionsDecode, &shares);
0b7755 ¤   ¤   if (IsPGPError (err)) goto AddCleanup;
7daf5a
628362 ¤   ¤   // add shares to collection
40fd9e ¤   ¤   if (prks->sharesCombined) {
4d25fb ¤   ¤   ¤   err = PGPCombineShares (shares,·
8220e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->sharesCombined, &sharesTemp);
be979f ¤   ¤   ¤   if (IsPGPError (err))·
19fa8b ¤   ¤   ¤   ¤   goto AddCleanup;
97a82c ¤   ¤   ¤   PGPFreeShares (prks->sharesCombined);
2ae4ee ¤   ¤   ¤   prks->sharesCombined = sharesTemp;
370fe4 ¤   ¤   }
b407e0 ¤   ¤   else {
42b68d ¤   ¤   ¤   prks->sharesCombined = shares;
e22d14 ¤   ¤   ¤   shares = NULL;
7f0fe4 ¤   ¤   }
31af5a
0e5b69 ¤   ¤   // share is OK, add it to list
a7956c ¤   ¤   prks->uNeededShares = uThreshold;
2d42d7 ¤   ¤   SetDlgItemInt (prks->hwndDlg, IDC_SHARESNEEDED,·
d6937c ¤   ¤   ¤   ¤   ¤   prks->uNeededShares, FALSE);
02af5a
abacca ¤   ¤   prks->uCollectedShares += uNumShares;
c17742 ¤   ¤   SetDlgItemInt (hwnd, IDC_SHARESCOLLECTED,·
f6b21a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->uCollectedShares, FALSE);
9a5a7a ¤   ¤   sAddShareHolderToList (prks, szName, uNumShares);
f79371 ¤   }
09af5a
ef5595 AddCleanup :
066a46 ¤   LeaveCriticalSection (&prks->critsecAddShare);
42af5a
c398ab ¤   if (shares)·
c9559e ¤   ¤   PGPFreeShares (shares);
e9af5a
590a07 ¤   if (sharefileref)
0ed958 ¤   ¤   PGPFreeShareFile (sharefileref);
9baf5a
5d27ed ¤   if (fileref)
31f26e ¤   ¤   PFLFreeFileSpec (fileref);
15af5a
698fe5 ¤   if (optionsDecode)
e9bc6b ¤   ¤   PGPFreeOptionList(optionsDecode);
e6af5a
4bae38 ¤   if (PGPKeySetRefIsValid (prks->keysetDecryption))
3f53a2 ¤   ¤   PGPFreeKeySet (prks->keysetDecryption);
ecaf5a
f719a0 ¤   if (prks->keyidsDecryption)
9de32d ¤   ¤   clFree (prks->keyidsDecryption);
17af5a
00e101 ¤   switch (err) {
1780d8 ¤   ¤   case kPGPClientError_IdenticalShares :
9636ac ¤   ¤   ¤   PGPclMessageBox (hwnd, IDS_CAPTION, IDS_DUPLICATESHARES,
acdd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
b9cdcb ¤   ¤   ¤   break;
67af5a
841fbe ¤   ¤   case kPGPClientError_DifferentSharePool :
f6e7a6 ¤   ¤   ¤   PGPclMessageBox (hwnd, IDS_CAPTION, IDS_SHARENUMMISMATCH,·
5fdd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
64cdcb ¤   ¤   ¤   break;
6baf5a
ecbf98 ¤   ¤   case kPGPClientError_DifferentSplitKeys :
--05b3 000c123784f40110296 Page 7 of CLrecon.c
b6208b ¤   ¤   ¤   PGPclMessageBox (hwnd, IDS_CAPTION, IDS_SHAREKEYMISMATCH,·
e0dd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
c1cdcb ¤   ¤   ¤   break;
edaf5a
c49ae3 ¤   ¤   default:
77cce3 ¤   ¤   ¤   PGPclErrorBox (hwnd, err);
139371 ¤   }
4baf5a
221b16 ¤   if (PGPKeySetRefIsValid (prks->keysetToAdd)) {
f08536 ¤   ¤   if (IsntPGPError (err)) {
34bee4 ¤   ¤   ¤   PGPclQueryAddKeys (prks->context, prks->tlsContext, hwnd,
eef919 ¤   ¤   ¤   ¤   ¤   prks->keysetToAdd, prks->keyset);
e70fe4 ¤   ¤   }
d200d5 ¤   ¤   PGPFreeKeySet (prks->keysetToAdd);
f89371 ¤   }
38efe6 }
afaf5a
4faf5a
39d4d4 //¤ ______________________________________________
61465d //
2ac268 // ·SKEP event handler
8daf5a
26f1ae static PGPError
bb9102 sHandlerSKEP (
1fc699 ¤   ¤   PGPskepRef¤ ¤   skep,
0b8452 ¤   ¤   PGPskepEvent*¤  event,
5bc05f ¤   ¤   PGPUserValue¤   userValue)
9dbb36 {
872805 ¤   BOOL¤   ¤   ¤   ¤   bCancel¤¤   = FALSE;
317ca7 ¤   PRECONKEYSTRUCT¤¤   prks;
3d3ab9 ¤   UINT¤   ¤   ¤   ¤   uID;
7de744 ¤   UINT¤   ¤   ¤   ¤   u;
fb0846 ¤   CHAR¤   ¤   ¤   ¤   sz[64];
fc0f53 ¤   LPSTR¤  ¤   ¤   ¤   psz;
9daf5a
fe12d9 ¤   prks = (PRECONKEYSTRUCT)userValue;
2aaf5a
af2405 ¤   uID = 0;
aeaf5a
9fa48f ¤   switch (event->type) {
c86ed7 ¤   case kPGPskepEvent_ConnectEvent :
53b027 ¤   ¤   uID = IDS_STATUSCONNECTED;
542f68 ¤   ¤   break;
f7af5a
4394f1 ¤   case kPGPskepEvent_AuthenticateEvent :
99c19a ¤   ¤   if (event->data.ad.remoteHostname)
1f80a4 ¤   ¤   ¤   psz = (LPSTR)event->data.ad.remoteHostname;
6ffb40 ¤   ¤   else if (event->data.ad.remoteIPAddress)
b3183e ¤   ¤   ¤   psz = (LPSTR)event->data.ad.remoteIPAddress;
b907e0 ¤   ¤   else {
3a23ec ¤   ¤   ¤   LoadString (g_hInst, IDS_UNIDENTIFIEDHOST, sz, sizeof(sz));
ea2af5 ¤   ¤   ¤   psz = sz;
d30fe4 ¤   ¤   }
baaf5a
1b79af ¤   ¤   if (IsntPGPError (PGPclConfirmRemoteAuthentication (
c3d91a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->context,
5c4cee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->hwndDlg,·
342c13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psz,·
dc33ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   event->data.ad.remoteKey,
2ab9d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->keyset,
0c8947 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHRECONSTITUTING)))·
745b34 ¤   ¤   {
4f62fd ¤   ¤   ¤   uID = IDS_STATUSAUTHENTICATED;
e766a2 ¤   ¤   ¤   if (IsntPGPError (PGPGetPrimaryUserIDNameBuffer (
fe002d ¤   ¤   ¤   ¤   ¤   ¤   event->data.ad.remoteKey, kPGPMaxUserIDSize,·
409b08 ¤   ¤   ¤   ¤   ¤   ¤   prks->szAuthUserID, &u))) {
ac5d61 ¤   ¤   ¤   ¤   SetDlgItemText (prks->hwndDlg,·
1366ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_AUTHENTICATION, prks->szAuthUserID);
f0a3a6 ¤   ¤   ¤   }
260fe4 ¤   ¤   }
730e1d ¤   ¤   else
c15b34 ¤   ¤   {
--c3df 000f2b3437240110296 Page 8 of CLrecon.c
219d4d ¤   ¤   ¤   bCancel = TRUE;
9c583d ¤   ¤   ¤   uID = IDS_STATUSLISTENING;
cb0fe4 ¤   ¤   }
de2f68 ¤   ¤   break;
a7af5a
599010 ¤   case kPGPskepEvent_ShareEvent:
ae5b34 ¤   ¤   {
5d8ccc ¤   ¤   ¤   PGPShareRef¤¤   ¤   shares;
281b36 ¤   ¤   ¤   PGPShareRef¤¤   ¤   sharesTemp;
57f010 ¤   ¤   ¤   UINT¤   ¤   ¤   ¤   uNumShares;
10f667 ¤   ¤   ¤   UINT¤   ¤   ¤   ¤   uThreshold;
69b4c3 ¤   ¤   ¤   PGPError¤   ¤   ¤   err = kPGPError_NoErr;
fe28e4 ¤   ¤   ¤   PGPKeyID¤   ¤   ¤   keyid;
741b52 ¤   ¤
ec51cd ¤   ¤   ¤   shares = event->data.sd.shares;
461fcd ¤   ¤   ¤   EnterCriticalSection (&prks->critsecAddShare);
5087c7 ¤   ¤   ¤
30e6d1 ¤   ¤   ¤   uNumShares = PGPGetNumberOfShares (shares);
b287c7 ¤   ¤   ¤
2e7839 ¤   ¤   ¤   // check that shares belong to this key
19c6c1 ¤   ¤   ¤   err = PGPGetKeyIDFromShares (shares, &keyid);
e174d6 ¤   ¤   ¤   if (IsPGPError (err)) goto NetContinue;
6d87c7 ¤   ¤   ¤
ca602b ¤   ¤   ¤   if (PGPCompareKeyIDs (&keyid, &(prks->keyidToReconstitute))) {
ea9076 ¤   ¤   ¤   ¤   PGPclMessageBox (prks->hwndDlg, IDS_CAPTION,·
ffec1e ¤   ¤   ¤   ¤   ¤   IDS_SHAREKEYMISMATCH, MB_OK|MB_ICONEXCLAMATION);
00dde9 ¤   ¤   ¤   ¤   goto NetContinue;
36a3a6 ¤   ¤   ¤   }
0087c7 ¤   ¤   ¤
2fd6f2 ¤   ¤   ¤   // check that threshold corresponds to other share files
2ab708 ¤   ¤   ¤   uThreshold = PGPGetShareThreshold (shares);
556b74 ¤   ¤   ¤   if (prks->uNeededShares != UNKNOWN_SHARES_NEEDED) {
af5caf ¤   ¤   ¤   ¤   if (uThreshold != prks->uNeededShares) {
f32c6f ¤   ¤   ¤   ¤   ¤   PGPclMessageBox (prks->hwndDlg, IDS_CAPTION,·
031436 ¤   ¤   ¤   ¤   ¤   ¤   IDS_SHARENUMMISMATCH, MB_OK|MB_ICONEXCLAMATION);
60329a ¤   ¤   ¤   ¤   ¤   goto NetContinue;
c22613 ¤   ¤   ¤   ¤   }
e5a3a6 ¤   ¤   ¤   }
1a87c7 ¤   ¤   ¤
764637 ¤   ¤   ¤   // add shares to collection
ab38cb ¤   ¤   ¤   if (prks->sharesCombined) {
617766 ¤   ¤   ¤   ¤   err = PGPCombineShares (shares,·
0618ba ¤   ¤   ¤   ¤   ¤   prks->sharesCombined, &sharesTemp);
aa217a ¤   ¤   ¤   ¤   if (IsPGPError (err)) goto NetContinue;
26062d ¤   ¤   ¤   ¤   PGPFreeShares (prks->sharesCombined);
5b3c5c ¤   ¤   ¤   ¤   prks->sharesCombined = sharesTemp;
84a3a6 ¤   ¤   ¤   }
b8e543 ¤   ¤   ¤   else {
6b2715 ¤   ¤   ¤   ¤   prks->sharesCombined = shares;
bf393c ¤   ¤   ¤   ¤   shares = NULL;
7aa3a6 ¤   ¤   ¤   }
a087c7 ¤   ¤   ¤
c85525 ¤   ¤   ¤   // share is OK, add it to list
75aca9 ¤   ¤   ¤   prks->uNeededShares = uThreshold;
436462 ¤   ¤   ¤   SetDlgItemInt (prks->hwndDlg, IDC_SHARESNEEDED,·
cac1e1 ¤   ¤   ¤   ¤   prks->uNeededShares, FALSE);
3f87c7 ¤   ¤   ¤
20e3f4 ¤   ¤   ¤   prks->uCollectedShares += uNumShares;
b7797d ¤   ¤   ¤   SetDlgItemInt (prks->hwndDlg, IDC_SHARESCOLLECTED,·
bc3abc ¤   ¤   ¤   ¤   prks->uCollectedShares, FALSE);
9c6067 ¤   ¤   ¤   sAddShareHolderToList (prks, prks->szAuthUserID, uNumShares);
b387c7 ¤   ¤   ¤
51bfae ¤   ¤   ¤   if (prks->uCollectedShares >= prks->uNeededShares)
fcfef7 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (prks->hwndDlg, IDOK), TRUE);
5faf5a
a31e4e NetContinue:
577c5a ¤   ¤   ¤   LeaveCriticalSection (&prks->critsecAddShare);
bd1b52 ¤   ¤
acc1bf ¤   ¤   ¤   if (shares)
871b37 ¤   ¤   ¤   ¤   PGPFreeShares (shares);
713e2a ¤   ¤   ¤   PGPclErrorBox (prks->hwndDlg, err);
f2583d ¤   ¤   ¤   uID = IDS_STATUSLISTENING;
--c173 000f154839340110296 Page 9 of CLrecon.c
b50fe4 ¤   ¤   }
892f68 ¤   ¤   break;
11af5a
85b170 ¤   case kPGPskepEvent_ProgressEvent :
1f0fc2 ¤   ¤   uID = IDS_STATUSRECEIVING;
142f68 ¤   ¤   break;
ebaf5a
40c55a ¤   case kPGPskepEvent_CloseEvent :
1bd231 ¤   ¤   uID = IDS_STATUSCLOSING;
d0a6bf ¤   ¤   SetDlgItemText (prks->hwndDlg, IDC_AUTHENTICATION, "");
e42f68 ¤   ¤   break;
38af5a
869371 ¤   }
75af5a
134c58 ¤   if (uID != 0) {
c7b833 ¤   ¤   LoadString (g_hInst, uID, sz, sizeof(sz));
8fcb6a ¤   ¤   SetDlgItemText (prks->hwndDlg, IDC_STATUS, sz);
cb9371 ¤   }
97af5a
55e271 ¤   if (prks->bStop || bCancel)
3d74be ¤   ¤   return kPGPError_UserAbort;
550e24 ¤   else
1fb840 ¤   ¤   return kPGPError_NoErr;
d4efe6 }
0aaf5a
a4af5a
89d4d4 //¤ ______________________________________________
5f465d //
431087 // thread for actually receiving the shares
f0af5a
5be8c0 static DWORD WINAPI·
24e0cd sNetworkThreadRoutine (LPVOID lpvoid)
8ebb36 {
62fe84 ¤   PRECONKEYSTRUCT¤¤   prks¤   ¤   = (PRECONKEYSTRUCT)lpvoid;
f38f52 ¤   PGPError¤   ¤   ¤   err;
230846 ¤   CHAR¤   ¤   ¤   ¤   sz[64];
b6af5a
9b310a ¤   err = PGPskepSetEventHandler (prks->skep,
6060d8 ¤   ¤   ¤   ¤   ¤   (PGPskepEventHandler)sHandlerSKEP, (PGPUserValue)prks);
d7af5a
89cfa1 ¤   do
bbc7a1 ¤   {
1bd13c ¤   ¤   LoadString (g_hInst, IDS_STATUSLISTENING, sz, sizeof(sz));
34cb6a ¤   ¤   SetDlgItemText (prks->hwndDlg, IDC_STATUS, sz);
03af5a
9d5bc8 ¤   ¤   err = PGPskepReceiveShares (prks->skep,
68b4bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->keyAuthenticating,
a4c898 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->pszPhraseAuth);
a7af5a
6e7862 ¤   ¤   if (err != kPGPError_UserAbort)
123e2a ¤   ¤   ¤   PGPclErrorBox (prks->hwndDlg, err);
b7af5a
56a6bf ¤   ¤   SetDlgItemText (prks->hwndDlg, IDC_AUTHENTICATION, "");
d09371 ¤   }
77aa05 ¤   while (err == kPGPClientError_RejectedSKEPAuthentication);
a5af5a
c7078d ¤   LoadString (g_hInst, IDS_STATUSNOTCONNECTED, sz, sizeof(sz));
a39ec6 ¤   SetDlgItemText (prks->hwndDlg, IDC_STATUS, sz);
bfaf5a
301c1b ¤   PostMessage (prks->hwndDlg, WM_APP, 0, 0);
f9af5a
ee3e6b ¤   return 0;
ceefe6 }
e4af5a
1faf5a
f8d4d4 //¤ ______________________________________________
bf465d //
d64b40 //¤ Reconstitute key dialog message procedure
a5af5a
0b3f64 static BOOL CALLBACK·
d124d1 sReconKeyDlgProc (
f13a3a ¤   ¤   HWND¤   hDlg,·
--477c 00079da75dc40110296 Page 10 of CLrecon.c
0deb77 ¤   ¤   UINT¤   uMsg,·
bb17d4 ¤   ¤   WPARAM¤ wParam,·
10c0b8 ¤   ¤   LPARAM¤ lParam)·
c9bb36 {
a37ca7 ¤   PRECONKEYSTRUCT¤¤   prks;
056a12 ¤   CHAR¤   ¤   ¤   ¤   sz[kPGPMaxUserIDSize];
4b06b1 ¤   DWORD¤  ¤   ¤   ¤   dw;
ed8f52 ¤   PGPError¤   ¤   ¤   err;
c0af5a
d1347f ¤   switch (uMsg) {
66af5a
9aad3a ¤   case WM_INITDIALOG :
0dc7a1 ¤   {
73ea10 ¤   ¤   CHAR¤   ¤   szTitle[kPGPMaxUserIDSize + 32];
4d40eb ¤   ¤   PGPUInt32¤  size;
e7af5a
b8e3ba ¤   ¤   // save address of struct
847547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
68ed6a ¤   ¤   prks = (PRECONKEYSTRUCT)lParam;
be2615 ¤   ¤   prks->hwndDlg = hDlg;
aeaf5a
d43027 ¤   ¤   // initialize shareholder list
d3aa63 ¤   ¤   prks->hwndList = GetDlgItem (hDlg, IDC_SHAREHOLDERS);
90a8fb ¤   ¤   sInitKeyList (prks);
17af5a
5e43ca ¤   ¤   // initialize name of key to reconstitute
60d2f4 ¤   ¤   LoadString (g_hInst, IDS_RECONKEYTITLE, szTitle, sizeof(szTitle));
24a9f8 ¤   ¤   PGPGetPrimaryUserIDNameBuffer (prks->keyToReconstitute,·
4b2cb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz, &size);
0e7a5b ¤   ¤   SetDlgItemText (hDlg, IDC_KEYTORECON, sz);
248b60 ¤   ¤   lstrcat (szTitle, sz);
ddeea5 ¤   ¤   SetWindowText (hDlg, szTitle);
9faf5a
d2314f ¤   ¤   // initialize numbers of shares
bf059f ¤   ¤   SetDlgItemText (hDlg, IDC_SHARESNEEDED, "?");
540ad9 ¤   ¤   SetDlgItemInt (hDlg, IDC_SHARESCOLLECTED,·
fbda0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   prks->uCollectedShares, FALSE);
1baf5a
e52a6c ¤   ¤   // initialize Network controls
c2dd16 ¤   ¤   LoadString (g_hInst, IDS_STARTNETWORK, sz, sizeof(sz));
887aad ¤   ¤   SetDlgItemText (hDlg, IDC_NETWORK, sz);
bf0248 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATUS), SW_HIDE);
3ac0f7 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATUSTEXT), SW_HIDE);
450010 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_AUTHENTICATION), SW_HIDE);
244581 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_AUTHENTICATIONTEXT), SW_HIDE);
76cbe4 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_NETWORKINSTRUCTIONS), SW_SHOW);
4baf5a
fb825a ¤   ¤   // OK button is initially disabled
8b7c02 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
c2af5a
8b836c ¤   ¤   return TRUE;
429371 ¤   }
2caf5a
e98a25 ¤   case WM_HELP:·
73fb42 ¤   ····WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
2ad0c3 ¤   ········HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
e27d53 ¤   ····break;·
8daf5a
b0af40 ¤   case WM_CONTEXTMENU:·
a8082b ¤   ¤   WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
109517 ¤   ¤   ····(DWORD) (LPVOID) aIds);·
9fca2d ¤   ¤   break;·
fbaf5a
c66334 ¤   case WM_DESTROY :
e54224 ¤   ¤   prks = (PRECONKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
d7f90a ¤   ¤   ImageList_Destroy (prks->hIml);
542f68 ¤   ¤   break;
26af5a
b15020 ¤   case WM_APP :
734224 ¤   ¤   prks = (PRECONKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
84af5a
794fa4 ¤   ¤   // event signaling end of thread
--c7d9 000d95990cf40110296 Page 11 of CLrecon.c
81a767 ¤   ¤   if (prks->skep != NULL)
165b34 ¤   ¤   {
f8f734 ¤   ¤   ¤   PGPFreeSKEP (prks->skep);
721ffa ¤   ¤   ¤   prks->skep = NULL;
540fe4 ¤   ¤   }
91af5a
a745a0 ¤   ¤   // reset controls
f72c92 ¤   ¤   prks->bServerMode = FALSE;
ccdd16 ¤   ¤   LoadString (g_hInst, IDS_STARTNETWORK, sz, sizeof(sz));
f37aad ¤   ¤   SetDlgItemText (hDlg, IDC_NETWORK, sz);
530248 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATUS), SW_HIDE);
87c0f7 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATUSTEXT), SW_HIDE);
a00010 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_AUTHENTICATION), SW_HIDE);
d54581 ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_AUTHENTICATIONTEXT), SW_HIDE);
1ad0ed ¤   ¤   ShowWindow (
8d5ffa ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_NETWORKINSTRUCTIONS), SW_SHOW);
94af5a
0fbf4c ¤   ¤   if (prks->uCollectedShares >= prks->uNeededShares)
627997 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
70af5a
95227a ¤   ¤   if (prks->bUserCancel)
3cef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
040df9 ¤   ¤   if (prks->bUserOK)
22f3d5 ¤   ¤   ¤   EndDialog (hDlg, 1);
a02f68 ¤   ¤   break;
7baf5a
443fcf ¤   case WM_COMMAND:
45af5a
8a537d ¤   ¤   switch (LOWORD(wParam)) {
15b6bb ¤   ¤   case IDCANCEL :
180c53 ¤   ¤   ¤   prks = (PRECONKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
51ccfc ¤   ¤   ¤   if (prks->bServerMode) {
e28d0b ¤   ¤   ¤   ¤   prks->bStop = TRUE;
70380b ¤   ¤   ¤   ¤   prks->bUserCancel = TRUE;
dfe9ce ¤   ¤   ¤   ¤   if (prks->skep != NULL)
118cd5 ¤   ¤   ¤   ¤   ¤   PGPskepCancel (prks->skep);
5ba3a6 ¤   ¤   ¤   }
23e543 ¤   ¤   ¤   else {
bdd206 ¤   ¤   ¤   ¤   EndDialog (hDlg, 0);
27a3a6 ¤   ¤   ¤   }
0fcdcb ¤   ¤   ¤   break;
adaf5a
e58c29 ¤   ¤   case IDOK :
010c53 ¤   ¤   ¤   prks = (PRECONKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
d4ccfc ¤   ¤   ¤   if (prks->bServerMode) {
0e8d0b ¤   ¤   ¤   ¤   prks->bStop = TRUE;
d6fc2e ¤   ¤   ¤   ¤   prks->bUserOK = TRUE;
9ee9ce ¤   ¤   ¤   ¤   if (prks->skep != NULL)
858cd5 ¤   ¤   ¤   ¤   ¤   PGPskepCancel (prks->skep);
7ca3a6 ¤   ¤   ¤   }
11e543 ¤   ¤   ¤   else {
49cebd ¤   ¤   ¤   ¤   EndDialog (hDlg, 1);
30a3a6 ¤   ¤   ¤   }
8acdcb ¤   ¤   ¤   break;
06af5a
1ee445 ¤   ¤   case IDC_NETWORK :
d50c53 ¤   ¤   ¤   prks = (PRECONKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
29e501 ¤   ¤   ¤   prks->bServerMode = !prks->bServerMode;
0baf5a
e3ccfc ¤   ¤   ¤   if (prks->bServerMode) {
b80081 ¤   ¤   ¤   ¤   // if this is a retry, free phrase and passkey
96db7f ¤   ¤   ¤   ¤   if (prks->pszPhraseAuth) {
7a5d87 ¤   ¤   ¤   ¤   ¤   KMFreePhrase (prks->pszPhraseAuth);
aeedaa ¤   ¤   ¤   ¤   ¤   prks->pszPhraseAuth = NULL;
8a2613 ¤   ¤   ¤   ¤   }
e4477f ¤   ¤   ¤   ¤   if (prks->pPasskeyAuth) {
cda6ea ¤   ¤   ¤   ¤   ¤   KMFreePasskey (prks->pPasskeyAuth,prks->sizePasskeyAuth);
4d03af ¤   ¤   ¤   ¤   ¤   prks->pPasskeyAuth = NULL;
6e2613 ¤   ¤   ¤   ¤   }
13af5a
103721 ¤   ¤   ¤   ¤   // get authentication key and phrase
d947b6 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_RECONAUTHPROMPT, sz, sizeof(sz));
--93c7 0009e565b4040110296 Page 12 of CLrecon.c
4d671c ¤   ¤   ¤   ¤   err = KMGetSigningKeyPhrase (prks->context,·
1b2414 ¤   ¤   ¤   ¤   ¤   ¤   prks->tlsContext, hDlg, sz,·
c1eeab ¤   ¤   ¤   ¤   ¤   ¤   prks->keyset, TRUE, &(prks->keyAuthenticating),
834095 ¤   ¤   ¤   ¤   ¤   ¤   &(prks->pszPhraseAuth), &(prks->pPasskeyAuth),
7e730c ¤   ¤   ¤   ¤   ¤   ¤   &(prks->sizePasskeyAuth));
2d8fb4 ¤   ¤   ¤   ¤   if (IsPGPError (err))
8d72c3 ¤   ¤   ¤   ¤   {
fef2b5 ¤   ¤   ¤   ¤   ¤   prks->bServerMode = FALSE;
5d14c3 ¤   ¤   ¤   ¤   ¤   break;
902613 ¤   ¤   ¤   ¤   }
25af5a
c2e018 ¤   ¤   ¤   ¤   // setup controls
1c378f ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_STOPNETWORK, sz, sizeof(sz));
b9b940 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_NETWORK, sz);
fc287f ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATUS), SW_SHOW);
68379f ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATUSTEXT), SW_SHOW);
99e0e7 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_AUTHENTICATION), SW_SHOW);
865561 ¤   ¤   ¤   ¤   ShowWindow (
f5a84a ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_AUTHENTICATIONTEXT), SW_SHOW);
fe5561 ¤   ¤   ¤   ¤   ShowWindow (
be25a1 ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_NETWORKINSTRUCTIONS), SW_HIDE);
c4af5a
24ac49 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_STATUS, "");
238d7a ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_AUTHENTICATION, "");
f3af5a
507bdb ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
16af5a
603b14 ¤   ¤   ¤   ¤   // start the thread
3b8f1d ¤   ¤   ¤   ¤   prks->bStop = FALSE;
5e395c ¤   ¤   ¤   ¤   PGPNewSKEP (prks->context, prks->tlsContext, &prks->skep);
738348 ¤   ¤   ¤   ¤   CreateThread (NULL, 0, sNetworkThreadRoutine, prks, 0, &dw);
5ca3a6 ¤   ¤   ¤   }
3ae543 ¤   ¤   ¤   else {
85365f ¤   ¤   ¤   ¤   // set flag which will stop thread
dd8d0b ¤   ¤   ¤   ¤   prks->bStop = TRUE;
9ce9ce ¤   ¤   ¤   ¤   if (prks->skep != NULL)
458cd5 ¤   ¤   ¤   ¤   ¤   PGPskepCancel (prks->skep);
4aa3a6 ¤   ¤   ¤   }
dfaf5a
8b7a80 ¤   ¤   ¤   // change the help ID based on if the button says start or stop
96ccfc ¤   ¤   ¤   if (prks->bServerMode) {
24650d ¤   ¤   ¤   ¤   aIds[1] = IDH_PGPCLRECON_STOPNETWORK;
0ba3a6 ¤   ¤   ¤   }
61e543 ¤   ¤   ¤   else {
905434 ¤   ¤   ¤   ¤   aIds[1] = IDH_PGPCLRECON_STARTNETWORK;
13a3a6 ¤   ¤   ¤   }
feaf5a
a0cdcb ¤   ¤   ¤   break;
afaf5a
54d3b0 ¤   ¤   case IDC_SHAREFILE :
b20c53 ¤   ¤   ¤   prks = (PRECONKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
83184d ¤   ¤   ¤   sAddShareFile (hDlg, prks);
efbfae ¤   ¤   ¤   if (prks->uCollectedShares >= prks->uNeededShares)
b59b97 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
6dcdcb ¤   ¤   ¤   break;
ceaf5a
840fe4 ¤   ¤   }
c2836c ¤   ¤   return TRUE;
4f9371 ¤   }
eca230 ¤   return FALSE;
dfefe6 }
00af5a
3daf5a
73d4d4 //¤ ______________________________________________
47465d //
e59648 // ·Reconstitute specified key
78af5a
c8ec6d PGPError PGPclExport
54ca81 PGPclReconstituteKey (
159cd4 ¤   ¤   PGPContextRef¤  ¤   context,
aaa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
9e317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
--87a6 00191f46c1940110296 Page 13 of CLrecon.c
dde561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
a2402c ¤   ¤   PGPKeyRef¤  ¤   ¤   key,
299e51 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskey,
9c8624 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength)·
b1bb36 {
5f1a49 ¤   RECONKEYSTRUCT¤ ¤   rks;
7f8f52 ¤   PGPError¤   ¤   ¤   err;
3eaf5a
cca8bb ¤   // initialize struct
4d9a9a ¤   rks.context¤¤   ¤   ¤   = context;
25c9bc ¤   rks.tlsContext¤ ¤   ¤   = tlsContext;
ca2886 ¤   rks.keyset¤ ¤   ¤   ¤   = keyset;
7bf2bd ¤   rks.keyToReconstitute¤  = key;
bda91d ¤   PGPGetKeyIDFromKey (key, &(rks.keyidToReconstitute));
b65d18 ¤   rks.uCollectedShares¤   = 0;
c8ab81 ¤   rks.uNeededShares¤  ¤   = UNKNOWN_SHARES_NEEDED;
034bd7 ¤   rks.sharesCombined¤ ¤   = NULL;
e6fbb9 ¤   rks.bServerMode¤¤   ¤   = FALSE;
c73438 ¤   rks.bUserCancel¤¤   ¤   = FALSE;
fb9ce8 ¤   rks.bUserOK¤¤   ¤   ¤   = FALSE;
675393 ¤   rks.bBadPassphrase¤ ¤   = FALSE;
8809d4 ¤   rks.pszPhraseAuth¤  ¤   = NULL;
465f5b ¤   rks.pPasskeyAuth¤   ¤   = NULL;
ce296b ¤   rks.skep¤   ¤   ¤   ¤   = NULL;
929181 ¤   rks.iIconIndex¤ ¤   ¤   = -1;
00af5a
452230 ¤   InitializeCriticalSection (&rks.critsecAddShare);
41af5a
0e43ab ¤   do {
fbb1e6 ¤   ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_RECONSTITUTEKEY),·
8c451e ¤   ¤   ¤   hwnd, sReconKeyDlgProc, (LPARAM)&rks)) {
6a631d ¤   ¤   ¤   err = PGPGetPasskeyFromShares (rks.sharesCombined,·
f02c17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppPasskey, piPasskeyLength);
c2cce3 ¤   ¤   ¤   PGPclErrorBox (hwnd, err);
f0af5a
d767f8 ¤   ¤   ¤   if (!PGPPassphraseIsValid (key,·
5d2085 ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context,·
5f4251 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *ppPasskey, *piPasskeyLength),
1b7879 ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context))) {
cc7ba3 ¤   ¤   ¤   ¤   PGPclMessageBox (hwnd, IDS_CAPTION, IDS_BADPASSKEY,·
807ece ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
ef4e98 ¤   ¤   ¤   ¤   err = kPGPError_BadPassphrase;
c0a3a6 ¤   ¤   ¤   }
6d0fe4 ¤   ¤   }
eb07e0 ¤   ¤   else {
611916 ¤   ¤   ¤   *ppPasskey = NULL;
e661b2 ¤   ¤   ¤   *piPasskeyLength = 0;
f44e2b ¤   ¤   ¤   err = kPGPError_UserAbort;
ac0fe4 ¤   ¤   }
514ba9 ¤   } while (err == kPGPError_BadPassphrase);
37af5a
a3597d ¤   DeleteCriticalSection (&rks.critsecAddShare);
45af5a
e1a545 ¤   if (rks.sharesCombined)
48d913 ¤   ¤   PGPFreeShares (rks.sharesCombined);
fcaf5a
cd7bfc ¤   if (rks.pszPhraseAuth)
d2ae2e ¤   ¤   KMFreePhrase (rks.pszPhraseAuth);
a7af5a
56e5d9 ¤   if (rks.pPasskeyAuth)
54eb47 ¤   ¤   KMFreePasskey (rks.pPasskeyAuth, rks.sizePasskeyAuth);
30af5a
435ea8 ¤   return err;
90efe6 }
91af5a
--b8bf 000bc2ca99240110297 Page 1 of CLsdksrv.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
386884 ¤   CLsdksrv.c - wrapper functions for sdkui keyserver calls
6a67c5 ¤
f8af5a
d85193 ¤   $Id: CLsdksrv.c,v 1.20 1998/08/11 14:43:15 pbj Exp $
aaf7f7 ____________________________________________________________________________*/
85e610 #include "pgpPFLConfig.h"
72af5a
3ec917 // project header files
ac5fcd #include "pgpclx.h"
0daf5a
af93ed // external globals
e59cad extern HINSTANCE g_hInst;
b8af5a
684265 //¤ ___________________________________________________
b5465d //
055178 //¤ all keyserver queries are funneled through here
2faf5a
54f1ae static PGPError
b2d23c sQueryServerInternal (
5c941b ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,
4f9a06 ¤   PGPContextRef¤  ¤   ¤   context,
295175 ¤   PGPtlsContextRef¤   ¤   tlsContext,
3b097a ¤   PGPOptionListRef¤   ¤   optionSearch,
419ee4 ¤   UINT¤   ¤   ¤   ¤   ¤   uServer,
5de9d9 ¤   LPSTR¤  ¤   ¤   ¤   ¤   pszUserID,
678d30 ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
1c1c4a ¤   PGPKeySetRef*¤  ¤   ¤   pkeysetResult)
80bb36 {
903384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
70dbb1 ¤   PGPKeyServerEntry*¤ ¤   pentryList¤ ¤   = NULL;
47e364 ¤   PGPKeyServerSpec*¤  ¤   pserverList¤¤   = NULL;
9ebcd9 ¤   PGPInt32¤   ¤   ¤   ¤   iNumEntries¤¤   = 0;
07e4cc ¤   PCLIENTSERVERSTRUCT¤¤   pcss¤   ¤   ¤   = NULL;
d7a558 ¤   PGPMemoryMgrRef¤¤   ¤   memMgr;
929bc9 ¤   PGPPrefRef¤ ¤   ¤   ¤   clientPrefsRef;
04af5a
efbc63 ¤   PGPValidatePtr (pkeysetResult);
ed7cc6 ¤   PGPValidatePtr (context);
f563a2 ¤   PGPValidatePtr (pszUserID);
1b1b52 ¤   ¤
f389c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
03b3f4 ¤   err=PGPclOpenClientPrefs (memMgr,&clientPrefsRef);
a4af5a
c8c8d0 ¤   if(IsntPGPError(err))
61c7a1 ¤   {
387eb8 ¤   ¤   err=CLInitKeyServerPrefs(uServer,NULL,
6c2940 ¤   ¤   ¤   hwndParent,context,keysetMain,clientPrefsRef,pszUserID,
22e6b7 ¤   ¤   ¤   &pcss,&pentryList,&pserverList,&iNumEntries);
edaf5a
21b7bb ¤   ¤   PGPclCloseClientPrefs (clientPrefsRef, FALSE);
209371 ¤   }
99af5a
3abb96 ¤   if (IsntPGPError (err))·
7fc7a1 ¤   {
7218ef ¤   ¤   err = PGPSearchKeyServerDialog (context, iNumEntries,
2fb08b ¤   ¤   ¤   pserverList, tlsContext,·
747369 ¤   ¤   ¤   FALSE, pkeysetResult, optionSearch,
4cec5f ¤   ¤   ¤   PGPOUIParentWindowHandle (context, hwndParent),
876445 ¤   ¤   ¤   PGPOLastOption (context));
a29371 ¤   }
9eaf5a
2d91ce ¤   CLUninitKeyServerPrefs(uServer,
670f29 ¤   ¤   pcss,pentryList,pserverList,iNumEntries);
5967c5 ¤
465ea8 ¤   return err;
5aefe6 }
94af5a
bc4265 //¤ ___________________________________________________
--6e04 000f25a00c740110297 Page 2 of CLsdksrv.c
c1465d //
feda7d //¤ all keyserver sends are funneled through here
83af5a
06f1ae static PGPError
149548 sSendToServerInternal (
511c7d ¤   ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,
549feb ¤   ¤   PGPContextRef¤  ¤   ¤   context,
5fd913 ¤   ¤   PGPtlsContextRef¤   ¤   tlsContext,
cb9b09 ¤   ¤   UINT¤   ¤   ¤   ¤   ¤   uServer,
4dae08 ¤   ¤   PGPKeyServerEntry*¤ ¤   pkeyserver,
ade795 ¤   ¤   LPSTR¤  ¤   ¤   ¤   ¤   pszUserID,
820556 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
246904 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetToSend)
a2bb36 {
6b3384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
47dbb1 ¤   PGPKeyServerEntry*¤ ¤   pentryList¤ ¤   = NULL;
40e364 ¤   PGPKeyServerSpec*¤  ¤   pserverList¤¤   = NULL;
5ebcd9 ¤   PGPInt32¤   ¤   ¤   ¤   iNumEntries¤¤   = 0;
2ee4cc ¤   PCLIENTSERVERSTRUCT¤¤   pcss¤   ¤   ¤   = NULL;
cbeba8 ¤   PGPKeySetRef¤   ¤   ¤   keysetFailed¤   = kInvalidPGPKeySetRef;
d9a558 ¤   PGPMemoryMgrRef¤¤   ¤   memMgr;
629bc9 ¤   PGPPrefRef¤ ¤   ¤   ¤   clientPrefsRef;
68af5a
eee1bb ¤   PGPValidatePtr (keysetToSend);
c27cc6 ¤   PGPValidatePtr (context);
ab63a2 ¤   PGPValidatePtr (pszUserID);
2b1b52 ¤   ¤
7589c8 ¤   memMgr=PGPGetContextMemoryMgr(context);
21b3f4 ¤   err=PGPclOpenClientPrefs (memMgr,&clientPrefsRef);
0baf5a
c3c8d0 ¤   if(IsntPGPError(err))
4dc7a1 ¤   {
eddb58 ¤   ¤   err=CLInitKeyServerPrefs(uServer,pkeyserver,
af2940 ¤   ¤   ¤   hwndParent,context,keysetMain,clientPrefsRef,pszUserID,
22e6b7 ¤   ¤   ¤   &pcss,&pentryList,&pserverList,&iNumEntries);
3baf5a
d3b7bb ¤   ¤   PGPclCloseClientPrefs (clientPrefsRef, FALSE);
9c9371 ¤   }
f2af5a
38bb96 ¤   if (IsntPGPError (err))·
e8c7a1 ¤   {
554e99 ¤   ¤   err = PGPSendToKeyServerDialog (context, &(pserverList[0]),
3c8aa9 ¤   ¤   ¤   tlsContext, keysetToSend, &keysetFailed,·
f4ec5f ¤   ¤   ¤   PGPOUIParentWindowHandle (context, hwndParent),
d06445 ¤   ¤   ¤   PGPOLastOption (context));
3baf5a
4a3a18 ¤   ¤   if (PGPKeySetRefIsValid (keysetFailed))
c89a40 ¤   ¤   ¤   PGPFreeKeySet (keysetFailed);
559371 ¤   }
91af5a
5991ce ¤   CLUninitKeyServerPrefs(uServer,
e80f29 ¤   ¤   pcss,pentryList,pserverList,iNumEntries);
7567c5 ¤
525ea8 ¤   return err;
dbefe6 }
29af5a
294265 //¤ ___________________________________________________
c9465d //
19588b //¤ send keyset to keyserver
d4af5a
949d43 PGPError PGPclExport·
2e5a73 PGPclSendKeysToServer (
089cd4 ¤   ¤   PGPContextRef¤  ¤   context,
e7a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
7f05b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
5573c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
e31f76 ¤   ¤   PGPKeyServerEntry*¤ pkeyserver,
14809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
37becb ¤   ¤   PGPKeySetRef¤   ¤   keysetToSend)
e6bb36 {
0d3384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
f29593 ¤   PGPKeySetRef¤   ¤   ¤   keyset¤ ¤   ¤   = kInvalidPGPKeySetRef;
--8633 0003db8b41440110297 Page 3 of CLsdksrv.c
4589b0 ¤   PGPKeyListRef¤  ¤   ¤   keylist¤¤   ¤   = kInvalidPGPKeyListRef;
9075f6 ¤   PGPKeyIterRef¤  ¤   ¤   keyiter¤¤   ¤   = kInvalidPGPKeyIterRef;
8daf5a
17e1bb ¤   PGPValidatePtr (keysetToSend);
307cc6 ¤   PGPValidatePtr (context);
a135c4 ¤   PGPValidatePtr (pkeyserver);
1667c5 ¤
9dece0 ¤   // derive server from userid
a644f2 ¤   if (uServer == PGPCL_USERIDBASEDSERVER) {
7df685 ¤   ¤   PGPKeyRef¤  ¤   key¤¤   ¤   = kInvalidPGPKeyRef;
5baf5a
469496 ¤   ¤   CHAR¤   ¤   ¤   szUserID[kPGPMaxUserIDSize+1];
03a63e ¤   ¤   PGPSize¤¤   ¤   size;
8caf5a
378338 ¤   ¤   err = PGPOrderKeySet (keysetToSend,·
d25e6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAnyOrdering, &keylist); CKERR;
be9b62 ¤   ¤   err = PGPNewKeyIter (keylist, &keyiter); CKERR;
92af5a
1ee0ed ¤   ¤   while (¤IsntPGPError (PGPKeyIterNext (keyiter, &key)) &&·
f5b76e ¤   ¤   ¤   ¤   PGPKeyRefIsValid (key))
d45b34 ¤   ¤   {
bc3a0c ¤   ¤   ¤   err = PGPNewSingletonKeySet (key, &keyset); CKERR;
1eaf5a
93ccc3 ¤   ¤   ¤   err = PGPGetPrimaryUserIDNameBuffer (key, kPGPMaxUserIDSize,
e86a52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szUserID, &size); CKERR;
22af5a
572335 ¤   ¤   ¤   err = sSendToServerInternal (hwndParent,
c759af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
f21051 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,
8d8dcd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uServer,
915ac5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkeyserver,
591f65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szUserID,
7cc107 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain,
c72419 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyset); CKERR;
090fe4 ¤   ¤   }
0f9371 ¤   }
17af5a
39b665 ¤   // use indicated or caller-supplied server
99665a ¤   else {
ef702e ¤   ¤   err = sSendToServerInternal (hwndParent,
1b5829 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
81d3bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,
a78c4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uServer,
0f9928 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkeyserver,
451374 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "",
e702ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain,
192484 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetToSend);
509371 ¤   }
30af5a
3f5c18 done :¤
f8774a ¤   if (PGPKeyListRefIsValid (keylist))
125a47 ¤   ¤   PGPFreeKeyList (keylist);
f3c601 ¤   if (PGPKeyIterRefIsValid (keyiter))
19e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
90ce74 ¤   if (PGPKeySetRefIsValid (keyset))
868346 ¤   ¤   PGPFreeKeySet (keyset);
c8af5a
da5ea8 ¤   return err;
9eefe6 }
e9af5a
8c4265 //¤ ___________________________________________________
1b465d //
43413d //¤ search keyserver(s) for userid
56af5a
039d43 PGPError PGPclExport·
8caa01 PGPclSearchServerForUserID (
c49cd4 ¤   ¤   PGPContextRef¤  ¤   context,
d0a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
9205b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
037b9b ¤   ¤   LPSTR¤  ¤   ¤   ¤   szUserID,
5c73c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
3d809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
--89d0 000d3f77de140110297 Page 4 of CLsdksrv.c
f9ff84 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetResult)·
10bb36 {
403384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
0f9593 ¤   PGPKeySetRef¤   ¤   ¤   keyset¤ ¤   ¤   = kInvalidPGPKeySetRef;
784291 ¤   PGPOptionListRef¤   ¤   optionSearch¤   = kInvalidPGPOptionListRef;
91d944 ¤   PGPFilterRef¤   ¤   ¤   filter¤ ¤   ¤   = kInvalidPGPFilterRef;
de67c5 ¤
82aac7 ¤   // initialize return keyset
8fbc63 ¤   PGPValidatePtr (pkeysetResult);
188ad6 ¤   *pkeysetResult = kInvalidPGPKeySetRef;
a5af5a
00a781 ¤   err = PGPNewUserIDStringFilter (context, szUserID,·
07aa3c ¤   ¤   ¤   ¤   ¤   kPGPMatchSubString, &filter);
3eaf5a
948014 ¤   if (IsntPGPError (err) && PGPFilterRefIsValid (filter)) {
d7af5a
990b3e ¤   ¤   optionSearch = PGPOUIKeyServerSearchFilter (context, filter);
8baf5a
272fc3 ¤   ¤   if (PGPOptionListRefIsValid (optionSearch)) {
80af5a
403e47 ¤   ¤   ¤   err = sQueryServerInternal (hwndParent,
bf0ab4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
ff45fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,
423212 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   optionSearch,
00ded6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uServer,
8cb164 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szUserID,
e994ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain,
ca2340 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);
56af5a
4b3da8 ¤   ¤   ¤   if (IsntPGPError (err))·
e08cf3 ¤   ¤   ¤   {¤
44f689 ¤   ¤   ¤   ¤   *pkeysetResult = keyset;
5ec308 ¤   ¤   ¤   ¤   keyset = kInvalidPGPKeySetRef;
74a3a6 ¤   ¤   ¤   }
1f0fe4 ¤   ¤   }
ab9371 ¤   }
93af5a
50ce74 ¤   if (PGPKeySetRefIsValid (keyset))
f48346 ¤   ¤   PGPFreeKeySet (keyset);
410947 ¤   if (PGPFilterRefIsValid (filter))
861fb8 ¤   ¤   PGPFreeFilter (filter);
d7af5a
15af5a
bd5ea8 ¤   return err;
e9efe6 }
0caf5a
cf4265 //¤ ___________________________________________________
b9465d //
6e1a5b //¤ Update keyset from specified keyserver
efaf5a
b89d43 PGPError PGPclExport·
2e9078 PGPclUpdateKeySetFromServer (
c89cd4 ¤   ¤   PGPContextRef¤  ¤   context,
bca960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
fe05b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
7711ac ¤   ¤   PGPKeySetRef¤   ¤   keysetToUpdate,
6f73c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
12809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
f6251c ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetResult)
83bb36 {
dc3384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
76a93c ¤   PGPKeySetRef¤   ¤   ¤   keysetCollect¤  = kInvalidPGPKeySetRef;
cc4291 ¤   PGPOptionListRef¤   ¤   optionSearch¤   = kInvalidPGPOptionListRef;
eb89b0 ¤   PGPKeyListRef¤  ¤   ¤   keylist¤¤   ¤   = kInvalidPGPKeyListRef;
b875f6 ¤   PGPKeyIterRef¤  ¤   ¤   keyiter¤¤   ¤   = kInvalidPGPKeyIterRef;
969593 ¤   PGPKeySetRef¤   ¤   ¤   keyset¤ ¤   ¤   = kInvalidPGPKeySetRef;
a3af5a
bbb373 ¤   PGPKeyID¤   ¤   ¤   ¤   keyid;
59af5a
01aac7 ¤   // initialize return keyset
43bc63 ¤   PGPValidatePtr (pkeysetResult);
d38ad6 ¤   *pkeysetResult = kInvalidPGPKeySetRef;
--510e 0009d79acbf40110297 Page 5 of CLsdksrv.c
e0af5a
d044f2 ¤   if (uServer == PGPCL_USERIDBASEDSERVER) {
89f685 ¤   ¤   PGPKeyRef¤  ¤   key¤¤   ¤   = kInvalidPGPKeyRef;
e2af5a
329496 ¤   ¤   CHAR¤   ¤   ¤   szUserID[kPGPMaxUserIDSize+1];
eda63e ¤   ¤   PGPSize¤¤   ¤   size;
1caf5a
9ba301 ¤   ¤   err = PGPNewKeySet (context, &keysetCollect); CKERR;
d1b8b5 ¤   ¤   err = PGPOrderKeySet (keysetToUpdate,·
7e5e6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAnyOrdering, &keylist); CKERR;
1a9b62 ¤   ¤   err = PGPNewKeyIter (keylist, &keyiter); CKERR;
b3af5a
d4cb32 ¤   ¤   while (¤IsntPGPError (err) &&
c0158c ¤   ¤   ¤   ¤   IsntPGPError (PGPKeyIterNext (keyiter, &key)) &&·
4fb76e ¤   ¤   ¤   ¤   PGPKeyRefIsValid (key))
9f5b34 ¤   ¤   {
a3ccc3 ¤   ¤   ¤   err = PGPGetPrimaryUserIDNameBuffer (key, kPGPMaxUserIDSize,
9f6a52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szUserID, &size); CKERR;
ccaf5a
a36196 ¤   ¤   ¤   err = PGPGetKeyIDFromKey (key, &keyid); CKERR;
74af5a
b7568b ¤   ¤   ¤   optionSearch = PGPOUIKeyServerSearchKeyIDList (context,
fa978b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   1, &keyid);
b4af5a
cc2cb4 ¤   ¤   ¤   if (PGPOptionListRefIsValid (optionSearch)) {
92af5a
d86beb ¤   ¤   ¤   ¤   err = sQueryServerInternal (hwndParent,
1d59af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
0f1051 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,
a03165 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   optionSearch,
c58dcd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uServer,
861f65 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szUserID,
ddc107 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain,
78764c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);·
6eaf5a
0e554c ¤   ¤   ¤   ¤   if (IsPGPError (PGPclErrorBox (hwndParent, err)))
e2b37b ¤   ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
86af5a
bae0cd ¤   ¤   ¤   ¤   if (IsntPGPError (err))
4172c3 ¤   ¤   ¤   ¤   {
c82a60 ¤   ¤   ¤   ¤   ¤   if (PGPKeySetRefIsValid (keyset))
f955b9 ¤   ¤   ¤   ¤   ¤   {¤
625bfc ¤   ¤   ¤   ¤   ¤   ¤   err = PGPAddKeys (keyset, keysetCollect);
a39889 ¤   ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (hwndParent, err)))·
558fec ¤   ¤   ¤   ¤   ¤   ¤   {
571011 ¤   ¤   ¤   ¤   ¤   ¤   ¤   err = PGPCommitKeyRingChanges (keysetCollect);
043580 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclErrorBox (hwndParent, err);
e9db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ef1c89 ¤   ¤   ¤   ¤   ¤   }
d42613 ¤   ¤   ¤   ¤   }
b4af5a
d88461 ¤   ¤   ¤   ¤   if (PGPKeySetRefIsValid (keyset))
9972c3 ¤   ¤   ¤   ¤   {
d54589 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keyset);
a01bba ¤   ¤   ¤   ¤   ¤   keyset = kInvalidPGPKeySetRef;
492613 ¤   ¤   ¤   ¤   }
10a3a6 ¤   ¤   ¤   }
750fe4 ¤   ¤   }
62af5a
071c0b ¤   ¤   if (PGPKeySetRefIsValid (keysetCollect))·
36ed49 ¤   ¤   {¤
f15434 ¤   ¤   ¤   *pkeysetResult = keysetCollect;
97d4d7 ¤   ¤   ¤   keysetCollect = kInvalidPGPKeySetRef;
740fe4 ¤   ¤   }
d99371 ¤   }
eaaf5a
e4d8f5 ¤   else {·
c3d267 ¤   ¤   optionSearch = PGPOUIKeyServerSearchKeySet (context, keysetToUpdate);
a6af5a
802fc3 ¤   ¤   if (PGPOptionListRefIsValid (optionSearch)) {
afaf5a
9d3e47 ¤   ¤   ¤   err = sQueryServerInternal (hwndParent,
--7eef 0008b2c274d40110297 Page 6 of CLsdksrv.c
4e0ab4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
fc45fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,
d43212 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   optionSearch,
f3ded6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uServer,
a29b12 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "",
c394ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain,
7f1a9a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keysetCollect);
97af5a
b33da8 ¤   ¤   ¤   if (IsntPGPError (err))·
bc8cf3 ¤   ¤   ¤   {¤
724c64 ¤   ¤   ¤   ¤   *pkeysetResult = keysetCollect;
387ad6 ¤   ¤   ¤   ¤   keysetCollect = kInvalidPGPKeySetRef;
84a3a6 ¤   ¤   ¤   }
2e0fe4 ¤   ¤   }
6c9371 ¤   }
13af5a
c2a1c0 done :
37774a ¤   if (PGPKeyListRefIsValid (keylist))
2e5a47 ¤   ¤   PGPFreeKeyList (keylist);
5cc601 ¤   if (PGPKeyIterRefIsValid (keyiter))
09e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
c0ce74 ¤   if (PGPKeySetRefIsValid (keyset))
038346 ¤   ¤   PGPFreeKeySet (keyset);
51d625 ¤   if (PGPKeySetRefIsValid (keysetCollect))
02c295 ¤   ¤   PGPFreeKeySet (keysetCollect);
5eaf5a
805ea8 ¤   return err;
eaefe6 }
34af5a
144265 //¤ ___________________________________________________
19465d //
82d702 //¤ search keyserver for keys with these keyids
9caf5a
5f9d43 PGPError PGPclExport·
5c4188 PGPclSearchServerForKeyIDs (
069cd4 ¤   ¤   PGPContextRef¤  ¤   context,
e0a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
1d05b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
0b7d4a ¤   ¤   PGPKeyID*¤  ¤   ¤   pkeyidList,
9a4785 ¤   ¤   INT¤¤   ¤   ¤   ¤   iNumKeyIDs,
e873c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
cc809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
9b251c ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetResult)
8ccebb {¤
c23384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
a09593 ¤   PGPKeySetRef¤   ¤   ¤   keyset¤ ¤   ¤   = kInvalidPGPKeySetRef;
054291 ¤   PGPOptionListRef¤   ¤   optionSearch¤   = kInvalidPGPOptionListRef;
25af5a
2aaac7 ¤   // initialize return keyset
94bc63 ¤   PGPValidatePtr (pkeysetResult);
798ad6 ¤   *pkeysetResult = kInvalidPGPKeySetRef;
66af5a
a2aff9 ¤   optionSearch = PGPOUIKeyServerSearchKeyIDList (context,
c618c5 ¤   ¤   ¤   ¤   ¤   ¤   iNumKeyIDs, pkeyidList );
6baf5a
6a81c2 ¤   if (PGPOptionListRefIsValid (optionSearch)) {
8baf5a
25a806 ¤   ¤   err = sQueryServerInternal (hwndParent,
395829 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
add3bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,
e29c13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   optionSearch,
b08c4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uServer,
ee1374 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "",
d702ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain,
516c7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);
8aaf5a
2b00c0 ¤   ¤   if (IsntPGPError (err))·
18ed49 ¤   ¤   {¤
05f364 ¤   ¤   ¤   *pkeysetResult = keyset;
4e5290 ¤   ¤   ¤   keyset = kInvalidPGPKeySetRef;
cb0fe4 ¤   ¤   }
8b9371 ¤   }
--9993 00122cce0b740110297 Page 7 of CLsdksrv.c
e0af5a
0ace74 ¤   if (PGPKeySetRefIsValid (keyset))
c68346 ¤   ¤   PGPFreeKeySet (keyset);
2baf5a
4a5ea8 ¤   return err;
68efe6 }
45af5a
ec4265 //¤ ___________________________________________________
da465d //
11abf2 //¤ search specified keyserver using specified filter
adaf5a
239d43 PGPError PGPclExport·
18490f PGPclSearchServerWithFilter (
c89cd4 ¤   ¤   PGPContextRef¤  ¤   context,
1fa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
9405b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
85b21c ¤   ¤   PGPFilterRef¤   ¤   filter,
fb73c5 ¤   ¤   UINT¤   ¤   ¤   ¤   uServer,
00809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
87ff84 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetResult)·
27bb36 {
513384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
8e9593 ¤   PGPKeySetRef¤   ¤   ¤   keyset¤ ¤   ¤   = kInvalidPGPKeySetRef;
4f4291 ¤   PGPOptionListRef¤   ¤   optionSearch¤   = kInvalidPGPOptionListRef;
4667c5 ¤
f5aac7 ¤   // initialize return keyset
28bc63 ¤   PGPValidatePtr (pkeysetResult);
748ad6 ¤   *pkeysetResult = kInvalidPGPKeySetRef;
1baf5a
4d1e1d ¤   optionSearch = PGPOUIKeyServerSearchFilter (context, filter);
5e7796 ¤   if (PGPOptionListRefIsValid (optionSearch))
d2c7a1 ¤   {
227b32 ¤   ¤   err = sQueryServerInternal (¤   hwndParent,
1c0ab4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
5f45fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tlsContext,
d03212 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   optionSearch,
baded6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uServer,
fc9b12 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "",
0e94ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain,
61676b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);·
2f00c0 ¤   ¤   if (IsntPGPError (err))·
31ed49 ¤   ¤   {¤
58f364 ¤   ¤   ¤   *pkeysetResult = keyset;
a95290 ¤   ¤   ¤   keyset = kInvalidPGPKeySetRef;
8c0fe4 ¤   ¤   }
f29371 ¤   }
3caf5a
24ce74 ¤   if (PGPKeySetRefIsValid (keyset))
0e8346 ¤   ¤   PGPFreeKeySet (keyset);
b0af5a
225ea8 ¤   return err;
97efe6 }
ceaf5a
22af5a
--0f3c 000e1d0faff40110298 Page 1 of CLselect.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
264c0f ¤   CLquery.c - selective import dialog
4967c5 ¤
1faf5a
71c57a ¤   $Id: CLselect.c,v 1.7 1998/08/11 14:43:16 pbj Exp $
91f7f7 ____________________________________________________________________________*/
12e610 #include "pgpPFLConfig.h"
7baf5a
41c917 // project header files
1b850a #include "pgpkmx.h"
2eaf5a
add495 // PGP SDK header files
eec97b #include "pgpClientPrefs.h"
3caf5a
14fc2c // system header files
013ef0 #include <zmouse.h>
48af5a
5f822f // External globals
35a009 extern HINSTANCE¤   g_hInst;
05579d extern UINT¤¤   ¤   g_uMouseWheelMessage;
86af5a
95f0f7 typedef struct {
8c7925 ¤   PGPContextRef¤  ¤   context;
dcb4ac ¤   PGPtlsContextRef¤   tlsContext;
4cbe7e ¤   LPSTR¤  ¤   ¤   ¤   pszPrompt;
033e65 ¤   PGPKeySetRef¤   ¤   keysetToDisplay;
859d52 ¤   PGPKeySetRef¤   ¤   keysetMain;
476e74 ¤   PGPKeySetRef¤   ¤   keysetSelected;
fca30a ¤   HKEYMAN¤¤   ¤   ¤   hKM;
53e9d6 ¤   KMCONFIG¤   ¤   ¤   KMConfig;
f26329 ¤   CHAR¤   ¤   ¤   ¤   szHelpFile[MAX_PATH];
f87f52 ¤   HWND¤   ¤   ¤   ¤   hwndTree;
dd49cc ¤   INT¤¤   ¤   ¤   ¤   iyOffset;
aa705a ¤   INT¤¤   ¤   ¤   ¤   iyTop;
d5a058 } SELECTSTRUCT;
f2af5a
d0b4f1 #define IDC_QUERYTREELIST¤  ¤   0x0101
15eef2 #define BUTTONOFFSETX¤  ¤   ¤   20
8049bc #define BUTTONOFFSETY¤  ¤   ¤   10
b0bdd8 #define DIALOGMINWIDTH¤ ¤   ¤   400
001fea #define DIALOGMINHEIGHT¤¤   ¤   140
86af5a
a2492e // local globals
6d0a84 static DWORD aIds[] = {¤¤   ¤   // Help IDs
7c7090 ¤   IDOK,¤  ¤   ¤   ¤   IDH_PGPKM_SELECT,
3ee3dd ¤   IDC_SELECTALL,¤ ¤   IDH_PGPKM_SELECTSELALL,
fa4fb2 ¤   IDC_UNSELECTALL,¤   IDH_PGPKM_SELECTUNSELALL,
e33da9 ¤   IDC_QUERYTREELIST,¤ IDH_PGPKM_SELECTLIST,
fbce3c ¤   0,0·
1da6fe };·
bbaf5a
444265 //¤ ___________________________________________________
09465d //
3da743 // ·Put up appropriate context menu on basis of selection flags.
ac5ff8 // ·Called in response to right mouse click.
73465d //
e85d68 //¤ hWnd¤   ¤   = handle of parent window
b6d58a //¤ uSelFlags¤  = bits indicate what types of objects are selected
91ee2d //¤ x, y¤   ¤   = mouse position when right button clicked (screen coords)
deaf5a
46b333 static VOID·
fbf086 sQueryContextMenu (
a047b2 ¤   ¤   HWND¤   hWnd,·
612b66 ¤   ¤   HKEYMAN hKM,·
99b730 ¤   ¤   UINT¤   uSelFlags,·
c4c2fb ¤   ¤   INT¤¤   x,·
39e7fd ¤   ¤   INT¤¤   y)·
45bb36 {
e1a46f ¤   HMENU¤  hMC;
--6142 000fa9eb9ee40110298 Page 2 of CLselect.c
90cad4 ¤   HMENU¤  hMenuTrackPopup;
8c218e ¤   PKEYMAN pKM = (PKEYMAN)hKM;
8faf5a
903189 ¤   switch (uSelFlags) {
4e8696 ¤   case PGPKM_KEYFLAG :
64c20e ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUIMPORT));
e82f68 ¤   ¤   break;
abaf5a
3abfad ¤   default :
ffd02a ¤   ¤   hMC = NULL;
542f68 ¤   ¤   break;
519371 ¤   }
faaf5a
8d75a4 ¤   if (!hMC) return;
ecaae5 ··¤ hMenuTrackPopup = GetSubMenu (hMC, 0);
488022 ¤   if (KMMultipleSelected (pKM)) {
f994cb ¤   ¤   EnableMenuItem (hMenuTrackPopup, IDM_KEYPROPERTIES,·
437087 ¤   ¤   ¤   MF_BYCOMMAND|MF_GRAYED);
999371 ¤   }
c6af5a
40966f ¤   TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
c28dd9 ¤   ¤   ¤   ¤   ¤   x, y, 0, hWnd, NULL);
8baf5a
f185ee ¤   DestroyMenu (hMC);
8cefe6 }
2baf5a
08c509 //¤ ____________________________________
f6465d //
71107a // ·get number of wheel scroll lines and pass to treelist controls
2caf5a
c9e6b2 static VOID
6fa0b3 sUpdateWheelScrollLines (SELECTSTRUCT* pss)
24bb36 {
4c6996 ¤   UINT uLines;
97af5a
ccad81 ¤   if (!SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &uLines, 0))·
4cc7a1 ¤   {
5b38a3 ¤   ¤   HWND hwnd = NULL;
cdb309 ¤   ¤   UINT umsg = 0;
e7af5a
17c5ed ¤   ¤   umsg = RegisterWindowMessage (MSH_SCROLL_LINES);
6bf294 ¤   ¤   hwnd = FindWindow (MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE);
baaf5a
cc160c ¤   ¤   if (hwnd && umsg)·
5bff8e ¤   ¤   ¤   uLines = (UINT)SendMessage (hwnd, umsg, 0, 0);
c89371 ¤   }
03af5a
d28df2 ¤   TreeList_SetWheelScrollLines (pss->hwndTree, uLines);
a9efe6 }
16af5a
4f4265 //¤ ___________________________________________________
6d465d //
f3ca7c // ·Select keys dialog message procedure
34af5a
003f64 static BOOL CALLBACK·
ac85f6 sSelectKeysDlgProc (
173a3a ¤   ¤   HWND¤   hDlg,·
93eb77 ¤   ¤   UINT¤   uMsg,·
d917d4 ¤   ¤   WPARAM¤ wParam,·
99c0b8 ¤   ¤   LPARAM¤ lParam)·
18bb36 {
4c1372 ¤   RECT¤   ¤   ¤   rc;
af2a7e ¤   SELECTSTRUCT*¤  pss;
e86ef0 ¤   INT¤¤   ¤   ¤   ix, iy;
03e0e3 ¤   POINT¤  ¤   ¤   pt;
c902d2 ¤   HWND¤   ¤   ¤   hwndControl;
702010 ¤   PGPBoolean¤ ¤   b;
71ae9e ¤   PGPPrefRef¤ ¤   prefRef;
b1fa50 ¤   HCURSOR¤¤   ¤   hCursorOld;
92fb19 ¤   PGPError¤   ¤   err;
bcaf5a
fa347f ¤   switch (uMsg) {
--fe93 000cffbe86d40110298 Page 3 of CLselect.c
e0af5a
f4ad3a ¤   case WM_INITDIALOG :
df7547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
975a08 ¤   ¤   pss = (SELECTSTRUCT*)lParam;
7caf5a
191338 ¤   ¤   // set window title
c02e62 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_PROMPT);
1cf064 ¤   ¤   SetWindowText (hwndControl, pss->pszPrompt);
0daf5a
aa6a3b ¤   ¤   // create keymanager window
c1ee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
3bbf14 ¤   ¤   pt.x = rc.left;
f8b7f9 ¤   ¤   pt.y = rc.bottom;
fa8590 ¤   ¤   ScreenToClient (hDlg, &pt);
0bb294 ¤   ¤   pss->iyTop = pt.y;
48af5a
ef390e ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_SELECTALL);
bfee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
a1bf14 ¤   ¤   pt.x = rc.left;
66ce63 ¤   ¤   pt.y = rc.top;
028590 ¤   ¤   ScreenToClient (hDlg, &pt);
14d1b5 ¤   ¤   iy = pt.y;
31289b ¤   ¤   GetClientRect (hDlg, &rc);
cf19ad ¤   ¤   pss->iyOffset = rc.bottom - (iy - BUTTONOFFSETY) + pss->iyTop;
89debc ¤   ¤   pss->hKM = PGPkmCreateKeyManager (pss->context, pss->tlsContext,
aa5c8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_QUERYTREELIST, NULL, 0, pss->iyTop,·
d04d67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right-rc.left,·
5be087 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.bottom-pss->iyOffset);
11af5a
5bd923 ¤   ¤   // configure key manager window
51cca0 ¤   ¤   pss->KMConfig.lpszHelpFile = NULL;
b9417e ¤   ¤   pss->KMConfig.keyserver.structSize = 0;
0247a1 ¤   ¤   pss->KMConfig.hWndStatusBar = NULL;
a6519b ¤   ¤   pss->KMConfig.ulDisableActions = KM_ALLACTIONS &·
b91e46 ¤   ¤   ¤   ¤   ~(KM_SELECTALL|KM_UNSELECTALL|KM_PROPERTIES);
17df34 ¤   ¤   pss->KMConfig.ulShowColumns = 0;
644ba3 ¤   ¤   pss->KMConfig.ulHideColumns = 0;
64e9c5 ¤   ¤   pss->KMConfig.ulOptionFlags =·
529d48 ¤   ¤   ¤   KMF_ONLYSELECTKEYS|KMF_READONLY|KMF_MODALPROPERTIES;
73af5a
0c568e ¤   ¤   // get those options which are based on prefs
a84ad6 ¤   ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pss->context),
1696c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefRef);
cf4b26 ¤   ¤   PGPGetPrefBoolean (prefRef, kPGPPrefDisplayMarginalValidity, &b);
bab6af ¤   ¤   if (!b) pss->KMConfig.ulOptionFlags |= KMF_NOVICEMODE;
9881e6 ¤   ¤   PGPGetPrefBoolean (prefRef, kPGPPrefMarginalIsInvalid, &b);
9bdb58 ¤   ¤   if (b) pss->KMConfig.ulOptionFlags |= KMF_MARGASINVALID;
7906ad ¤   ¤   PGPclCloseClientPrefs (prefRef, FALSE);
4caf5a
884a85 ¤   ¤   pss->KMConfig.ulMask = PGPKM_ALLITEMS;
ea816f ¤   ¤   PGPkmConfigure (pss->hKM, &pss->KMConfig);
4b1b52 ¤   ¤
6a2257 ¤   ¤   // will be useful later to have HWND of keymanager
eaae40 ¤   ¤   pss->hwndTree = PGPkmGetManagerWindow (pss->hKM);
33af5a
ee1b18 ¤   ¤   // initialize keymanager
50c724 ¤   ¤   PGPkmLoadKeySet (pss->hKM, pss->keysetToDisplay, pss->keysetMain);
6eaf5a
26be7e ¤   ¤   // initialize wheel scrolling
3caa86 ¤   ¤   sUpdateWheelScrollLines (pss);
96af5a
cedc48 ¤   ¤   // post message to sync keysets
15f29a ¤   ¤   PostMessage (hDlg, WM_APP, 0, 0);
c2af5a
7334a5 ¤   ¤   // no keys initially selected => disable "OK" button
d87c02 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
4baf5a
4d98aa ¤   ¤   return FALSE;
b3af5a
df5020 ¤   case WM_APP :
c59602 ¤   ¤   // this syncs the import keyset with the main one
cf0cec ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
--704f 0001462c61240110298 Page 4 of CLselect.c
e0af5a
79f63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
aabbf4 ¤   ¤   PGPclSyncKeySets (pss->context,·
96c0bf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pss->keysetMain, pss->keysetToDisplay);
f0c724 ¤   ¤   PGPkmLoadKeySet (pss->hKM, pss->keysetToDisplay, pss->keysetMain);
857139 ¤   ¤   SetCursor (hCursorOld);
0baf5a
abc127 ¤   ¤   SetForegroundWindow (hDlg);
60c702 ¤   ¤   SetFocus (pss->hwndTree);
982f68 ¤   ¤   break;
17af5a
c0ae91 ¤   case WM_ACTIVATE :
760cec ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
f4c702 ¤   ¤   SetFocus (pss->hwndTree);
1c2f68 ¤   ¤   break;
94af5a
be90ef ¤   case WM_SIZE :
500cec ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
93af11 ¤   ¤   // resize keymanager window
2f9f51 ¤   ¤   SetWindowPos (pss->hwndTree, NULL, 0, pss->iyTop,·
350499 ¤   ¤   ¤   LOWORD(lParam), HIWORD(lParam) - pss->iyOffset,·
52da22 ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);
4baf5a
bad7ce ¤   ¤   // reposition buttons
da390e ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_SELECTALL);
d4ee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
b7bf14 ¤   ¤   pt.x = rc.left;
b5ce63 ¤   ¤   pt.y = rc.top;
e58590 ¤   ¤   ScreenToClient (hDlg, &pt);
7ca74e ¤   ¤   ix = pt.x;
230d99 ¤   ¤   iy = HIWORD(lParam) - pss->iyOffset + pss->iyTop + BUTTONOFFSETY;
b2330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
fb63ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
a5af5a
0657a0 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_UNSELECTALL);
4bee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
2dbf14 ¤   ¤   pt.x = rc.left;
7dce63 ¤   ¤   pt.y = rc.top;
f18590 ¤   ¤   ScreenToClient (hDlg, &pt);
ada74e ¤   ¤   ix = pt.x;
7e0d99 ¤   ¤   iy = HIWORD(lParam) - pss->iyOffset + pss->iyTop + BUTTONOFFSETY;
74330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
2163ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
f0af5a
03b374 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDCANCEL);
3cee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
34bf14 ¤   ¤   pt.x = rc.left;
bcce63 ¤   ¤   pt.y = rc.top;
fb8590 ¤   ¤   ScreenToClient (hDlg, &pt);
a8a74e ¤   ¤   ix = pt.x;
320d99 ¤   ¤   iy = HIWORD(lParam) - pss->iyOffset + pss->iyTop + BUTTONOFFSETY;
5e330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
7e63ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
b0af5a
32a312 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDOK);
d6ee0d ¤   ¤   GetWindowRect (hwndControl, &rc);
9abf14 ¤   ¤   pt.x = rc.left;
a1ce63 ¤   ¤   pt.y = rc.top;
c98590 ¤   ¤   ScreenToClient (hDlg, &pt);
0aa74e ¤   ¤   ix = pt.x;
ae0d99 ¤   ¤   iy = HIWORD(lParam) - pss->iyOffset + pss->iyTop + BUTTONOFFSETY;
31330a ¤   ¤   SetWindowPos (hwndControl, NULL, ix, iy, 0, 0,·
ab63ef ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
0cbbde ¤   ¤   return 0;
21af5a
739a87 ¤   case WM_SYSCOLORCHANGE :
680cec ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
25c18f ¤   ¤   PostMessage (pss->hwndTree, WM_SYSCOLORCHANGE, 0, 0);
112f68 ¤   ¤   break;
aaaf5a
7736bc ¤   case WM_SETTINGCHANGE :
140cec ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
--37e3 000e12d1a9a40110298 Page 5 of CLselect.c
7ad6e5 ¤   ¤   if (wParam == SPI_SETWHEELSCROLLLINES)
83a4ca ¤   ¤   ¤   sUpdateWheelScrollLines (pss);
acee26 ¤   ¤   else·
647d96 ¤   ¤   ¤   PostMessage (pss->hwndTree, WM_SYSCOLORCHANGE, 0, 0);
c22f68 ¤   ¤   break;
5faf5a
9dc3eb ····case WM_HELP:·
1bc720 ·¤  ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
0689df ¤   ¤   WinHelp (((LPHELPINFO) lParam)->hItemHandle, pss->szHelpFile,·
a68e1f ¤   ¤   ¤   HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
f78f13 ········break;·
4ed83c ·
094fd8 ····case WM_CONTEXTMENU:·
c6c720 ·¤  ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
9250bb ¤   ¤   WinHelp ((HWND) wParam, pss->szHelpFile, HELP_CONTEXTMENU,·
143335 ¤   ¤   ¤   (DWORD) (LPVOID) aIds);·
1e8f13 ········break;·
3daf5a
621431 ¤   case WM_NOTIFY :
a53404 ¤   ¤   if (wParam == IDC_QUERYTREELIST) {
4b86a9 ¤   ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
d97e04 ¤   ¤   ¤   // let keymanager have first whack at the notification
4d0b74 ¤   ¤   ¤   PGPkmDefaultNotificationProc (pss->hKM, lParam);
feaf5a
853a28 ¤   ¤   ¤   switch (((LPNM_TREELIST)lParam)->hdr.code) {
54a59b ¤   ¤   ¤   // post the context menu
83b838 ¤   ¤   ¤   case TLN_CONTEXTMENU :
a9e846 ¤   ¤   ¤   ¤   sQueryContextMenu (hDlg, pss->hKM,
ffe122 ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->flags,
d5caa3 ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.x,
05b27d ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.y);
1af622 ¤   ¤   ¤   ¤   break;
58af5a
0d76f6 ¤   ¤   ¤   // enable or disable the "import" button depending on whether
b0ce7c ¤   ¤   ¤   // item(s) are selected or not
0e87f5 ¤   ¤   ¤   case TLN_SELCHANGED :
1f3fe0 ¤   ¤   ¤   ¤   if ((((LPNM_TREELIST)lParam)->itemNew.hItem) ||
abcfe4 ¤   ¤   ¤   ¤   ¤   (((LPNM_TREELIST)lParam)->flags & TLC_MULTIPLE))·
ec278e ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
fafa07 ¤   ¤   ¤   ¤   else
06f627 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
8af622 ¤   ¤   ¤   ¤   break;
b4af5a
230082 ¤   ¤   ¤   default :
f5f622 ¤   ¤   ¤   ¤   break;
06a3a6 ¤   ¤   ¤   }
5b0fe4 ¤   ¤   }
fa2f68 ¤   ¤   break;
53af5a
3d84e1 ¤   case KM_M_REQUESTSDKACCESS :
1ac720 ·¤  ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
3d9577 ¤   ¤   PGPkmSynchronizeThreadAccessToSDK (pss->hKM);
542f68 ¤   ¤   break;
b6af5a
fc3fcf ¤   case WM_COMMAND:
10af5a
c0537d ¤   ¤   switch (LOWORD(wParam)) {
56af5a
6a8c29 ¤   ¤   case IDOK :
a686a9 ¤   ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
f2b68b ¤   ¤   ¤   err = PGPkmGetSelectedKeys (pss->hKM, &pss->keysetSelected);
f5c3cf ¤   ¤   ¤   PGPkmDestroyKeyManager (pss->hKM, FALSE);
fed09a ¤   ¤   ¤   KMFree (pss->hKM);
03780f ¤   ¤   ¤   EndDialog (hDlg, err);
e4cdcb ¤   ¤   ¤   break;
dcaf5a
c0b6bb ¤   ¤   case IDCANCEL :
5586a9 ¤   ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
03c3cf ¤   ¤   ¤   PGPkmDestroyKeyManager (pss->hKM, FALSE);
dbd09a ¤   ¤   ¤   KMFree (pss->hKM);
c602ba ¤   ¤   ¤   EndDialog (hDlg, kPGPError_UserAbort);
e1cdcb ¤   ¤   ¤   break;
--b13d 000655506e140110298 Page 6 of CLselect.c
e0af5a
46c0c2 ¤   ¤   case IDC_SELECTALL :
9486a9 ¤   ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
a4fda6 ¤   ¤   ¤   PGPkmPerformAction (pss->hKM, KM_SELECTALL);·
b27997 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
ee2871 ¤   ¤   ¤   SetFocus (pss->hwndTree);
81cdcb ¤   ¤   ¤   break;
9eaf5a
a096fd ¤   ¤   case IDC_UNSELECTALL :
b986a9 ¤   ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
f3bf9c ¤   ¤   ¤   PGPkmPerformAction (pss->hKM, KM_UNSELECTALL);·
127b39 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
3bcdcb ¤   ¤   ¤   break;
6aaf5a
28191d ¤   ¤   case IDM_KEYPROPERTIES :
2586a9 ¤   ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
a48688 ¤   ¤   ¤   PGPkmPerformAction (pss->hKM, KM_PROPERTIES);·
b0cdcb ¤   ¤   ¤   break;
19af5a
883a18 ¤   ¤   default :
f5cdcb ¤   ¤   ¤   break;
f40fe4 ¤   ¤   }
ee836c ¤   ¤   return TRUE;
c4af5a
79bfad ¤   default :
932f16 ¤   ¤   if (uMsg == g_uMouseWheelMessage) {
6ca20e ¤   ¤   ¤   WORD iDelta;
c1af5a
8986a9 ¤   ¤   ¤   pss = (SELECTSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
c6de65 ¤   ¤   ¤   iDelta = (WORD)wParam;
1887c7 ¤   ¤   ¤
9841c0 ¤   ¤   ¤   SendMessage (pss->hwndTree,·
81e614 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_MOUSEWHEEL, MAKEWPARAM (0, iDelta), 0);
ee5f1f ¤   ¤   ¤   return FALSE;
d90fe4 ¤   ¤   }
d62f68 ¤   ¤   break;
b19371 ¤   }
eba230 ¤   return FALSE;
bdefe6 }
16af5a
a14265 //¤ ___________________________________________________
68465d //
e14200 // ·Display and handle select keys dialog
6daf5a
da9d43 PGPError PGPclExport·
b2c2f9 PGPclSelectKeys (
8b9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
91a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
1205b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
432714 ¤   ¤   LPSTR¤  ¤   ¤   ¤   pszPrompt,
3977c5 ¤   ¤   PGPKeySetRef¤   ¤   keysetToDisplay,¤   ¤   ¤
fc809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
c1c5b1 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetSelected)·
95bb36 {
3dbb74 ¤   SELECTSTRUCT¤   ss;
50195e ¤   CHAR¤   ¤   ¤   sz[64];
82fb19 ¤   PGPError¤   ¤   err;
72af5a
a18e89 ¤   PGPValidatePtr (pkeysetSelected);
d4af5a
aa5128 ¤   ss.hKM = NULL;
263009 ¤   ss.context = context;
480858 ¤   ss.tlsContext = tlsContext;
8b7e2b ¤   ss.pszPrompt = pszPrompt;
ac5a44 ¤   ss.keysetToDisplay = keysetToDisplay;
f5944c ¤   ss.keysetMain = keysetMain;
24af5a
c0cabb ¤   PGPclGetPGPPath (ss.szHelpFile, sizeof(ss.szHelpFile));
8be7c6 ¤   LoadString (g_hInst, IDS_HELPFILENAME, sz, sizeof(sz));
82ffe3 ¤   lstrcat (ss.szHelpFile, sz);
14af5a
658585 ¤   err = DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_QUERYADD),·
--d5a6 0016b257ba540110298 Page 7 of CLselect.c
0c466a ¤   ¤   ¤   ¤   ¤   hwndParent, sSelectKeysDlgProc, (LPARAM)&ss);
b7af5a
f9b23e ¤   if (IsntPGPError (err)) {
d7615d ¤   ¤   *pkeysetSelected = ss.keysetSelected;
3e9371 ¤   }
7caf5a
665ea8 ¤   return err;
4eefe6 }
6baf5a
--90dd 0004ec55d6040110299 Page 1 of CLsend.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
b3619b ¤   CLsend.c - send key shares routines
4e67c5 ¤
b1af5a
abf124 ¤   $Id: CLsend.c,v 1.27 1998/08/13 19:19:59 pbj Exp $
c6f7f7 ____________________________________________________________________________*/
d62194 #include "pgpPFLConfig.h"¤  /* or pgpConfig.h in the CDK */
06af5a
a8c917 // project header files
0a5fcd #include "pgpclx.h"
73850a #include "pgpkmx.h"
6eaf5a
2aad8c // pgp header files
7931ed #include "PGPskep.h"
35add5 #include "pgpShareFile.h"
27af5a
e5fc2c // system header files
d86bd4 #include <commdlg.h>
6daf5a
195bee // typedefs
3ff0f7 typedef struct {
8e7925 ¤   PGPContextRef¤  ¤   context;
5ab4ac ¤   PGPtlsContextRef¤   tlsContext;
2db604 ¤   PGPKeySetRef¤   ¤   keyset;
2fdeec ¤   HWND¤   ¤   ¤   ¤   hwnd;
bae8fd ¤   HWND¤   ¤   ¤   ¤   hwndParent;
fd183b ¤   LPSTR¤  ¤   ¤   ¤   pszPhrase;
de0b24 ¤   PGPByte*¤   ¤   ¤   pPasskey;
9e0de9 ¤   PGPSize¤¤   ¤   ¤   sizePasskey;
6e1181 ¤   CHAR¤   ¤   ¤   ¤   szName[kPGPMaxUserIDSize];
b9bd23 ¤   UINT¤   ¤   ¤   ¤   uNumShares;
486dca ¤   LPSTR¤  ¤   ¤   ¤   pszRemoteHost;
fc2582 ¤   PGPKeySetRef¤   ¤   keysetDecryption;
4fe8d1 ¤   PGPUInt32¤  ¤   ¤   iKeyIDCount;
13e19a ¤   PGPKeyID*¤  ¤   ¤   keyidsDecryption;
b89343 ¤   PGPKeySetRef¤   ¤   keysetToAdd;
4baf8d ¤   PGPKeyRef¤  ¤   ¤   keyAuthenticating;
cac265 ¤   PGPShareRef¤¤   ¤   shares;
d88b18 ¤   PGPskepRef¤ ¤   ¤   skep;
ca1e43 ¤   BOOL¤   ¤   ¤   ¤   bConventional;
a027f2 ¤   BOOL¤   ¤   ¤   ¤   bThreadRunning;
fa804c ¤   BOOL¤   ¤   ¤   ¤   bFinished;
bb4bba } SENDSHARESSTRUCT, *PSENDSHARESSTRUCT;
06af5a
fb3fb5 // external global variables
f3eec0 extern HINSTANCE¤   ¤   g_hInst;
ccfc00 extern PGPContextRef¤   g_ContextRef;
330afe extern CHAR g_szHelpFile[MAX_PATH];
ebaf5a
27492e // local globals
6b0a84 static DWORD aIds[] = {¤¤   ¤   // Help IDs
8e0458 ¤   IDC_SENDSHARES,¤¤   IDH_PGPCLSEND_SENDSHARES,¤  // must be first in list
2a9df1 ¤   IDC_SHAREFILE,¤ ¤   IDH_PGPCLSEND_SHAREFILE,
9cda1e ¤   IDC_NUMSHARES,¤ ¤   IDH_PGPCLSEND_NUMSHARESINFILE,
1dab33 ¤   IDC_REMOTECOMPUTER,¤IDH_PGPCLSEND_REMOTECOMPUTER,
51972b ¤   IDC_NETSTATUS,¤ ¤   IDH_PGPCLSEND_NETWORKSTATUS,
f1a9b4 ¤   IDC_AUTHENTICATION,¤IDH_PGPCLSEND_NETWORKAUTHENTICATION,
fe4434 ····0,0·
9fa6fe };·
f3af5a
deaf5a
234265 //¤ ___________________________________________________
d9465d //
d2c268 // ·SKEP event handler
95af5a
7af1ae static PGPError
719102 sHandlerSKEP (
3ac699 ¤   ¤   PGPskepRef¤ ¤   skep,
4e8452 ¤   ¤   PGPskepEvent*¤  event,
--06b7 0006b3f5ec740110299 Page 2 of CLsend.c
d4c05f ¤   ¤   PGPUserValue¤   userValue)
cdbb36 {
242805 ¤   BOOL¤   ¤   ¤   ¤   bCancel¤¤   = FALSE;
11b4ef ¤   PSENDSHARESSTRUCT¤  psss;
013ab9 ¤   UINT¤   ¤   ¤   ¤   uID;
6e0846 ¤   CHAR¤   ¤   ¤   ¤   sz[64];
29e744 ¤   UINT¤   ¤   ¤   ¤   u;
a6af5a
f618f0 ¤   psss = (PSENDSHARESSTRUCT)userValue;
eaaf5a
6c2405 ¤   uID = 0;
9eaf5a
3ea48f ¤   switch (event->type) {
636ed7 ¤   case kPGPskepEvent_ConnectEvent :
3eb027 ¤   ¤   uID = IDS_STATUSCONNECTED;
7a2f68 ¤   ¤   break;
ffaf5a
5094f1 ¤   case kPGPskepEvent_AuthenticateEvent :
8c79af ¤   ¤   if (IsntPGPError (PGPclConfirmRemoteAuthentication (
ded048 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->context,
7abcc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->hwnd,·
157d72 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->pszRemoteHost,·
6b33ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   event->data.ad.remoteKey,
e8a34a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->keyset,
df8947 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHRECONSTITUTING)))·
6f5b34 ¤   ¤   {
0d62fd ¤   ¤   ¤   uID = IDS_STATUSAUTHENTICATED;
5366a2 ¤   ¤   ¤   if (IsntPGPError (PGPGetPrimaryUserIDNameBuffer (
12b9c3 ¤   ¤   ¤   ¤   ¤   ¤   event->data.ad.remoteKey, sizeof(sz), sz, &u))) {
87787c ¤   ¤   ¤   ¤   SetDlgItemText (psss->hwnd, IDC_AUTHENTICATION, sz);
31a3a6 ¤   ¤   ¤   }
700fe4 ¤   ¤   }
140e1d ¤   ¤   else
3a9d4d ¤   ¤   ¤   bCancel = TRUE;
fc2f68 ¤   ¤   break;
e4af5a
e2b170 ¤   case kPGPskepEvent_ProgressEvent :
dc4012 ¤   ¤   uID = IDS_STATUSSENDING;
802f68 ¤   ¤   break;
4baf5a
ecc55a ¤   case kPGPskepEvent_CloseEvent :
dfd231 ¤   ¤   uID = IDS_STATUSCLOSING;
b82f68 ¤   ¤   break;
9caf5a
d19371 ¤   }
29af5a
154c58 ¤   if (uID != 0) {
f0b833 ¤   ¤   LoadString (g_hInst, uID, sz, sizeof(sz));
ce60a4 ¤   ¤   SetDlgItemText (psss->hwnd, IDC_NETSTATUS, sz);
c59371 ¤   }
23af5a
0d473f ¤   if (bCancel)
7a74be ¤   ¤   return kPGPError_UserAbort;
a10e24 ¤   else
c5b840 ¤   ¤   return kPGPError_NoErr;
8eefe6 }
85af5a
f7af5a
724265 //¤ ___________________________________________________
14465d //
af6bf6 // thread for actually sending the shares
87af5a
9ce8c0 static DWORD WINAPI·
c0ba92 sSendSharesThreadRoutine (LPVOID lpvoid)
14bb36 {
894172 ¤   PSENDSHARESSTRUCT¤  psss¤   ¤   = (PSENDSHARESSTRUCT)lpvoid;
538f52 ¤   PGPError¤   ¤   ¤   err;
36af5a
99dfe0 ¤   err = PGPskepSetEventHandler (psss->skep,
e48a93 ¤   ¤   ¤   ¤   ¤   (PGPskepEventHandler)sHandlerSKEP, (PGPUserValue)psss);
b5af5a
6bb23e ¤   if (IsntPGPError (err)) {
--4fcf 000843bc37640110299 Page 3 of CLsend.c
078137 ¤   ¤   err = PGPskepSendShares (psss->skep,·
e35dec ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->keyAuthenticating,
b3d58a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->pszPhrase,·
fa12af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->shares,·
cf62d4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->pszRemoteHost);
449371 ¤   }
09af5a
3247f4 ¤   SendMessage (psss->hwnd, WM_APP, 0, (LPARAM)err);
16af5a
0579f5 ¤   psss->bThreadRunning = FALSE;
693e6b ¤   return 0;
40efe6 }
94af5a
d7af5a
014265 //¤ ___________________________________________________
89465d //
85bb22 // Sign key dialog message procedure
61af5a
0c3f64 static BOOL CALLBACK·
b6a4b7 sSendKeySharesDlgProc (
f8f178 ¤   ¤   ¤   ¤   HWND hDlg,·
77c92a ¤   ¤   ¤   ¤   UINT uMsg,·
c0080c ¤   ¤   ¤   ¤   WPARAM wParam,·
610c85 ¤   ¤   ¤   ¤   LPARAM lParam)·
7cbb36 {
11b4ef ¤   PSENDSHARESSTRUCT¤  psss;
cb0846 ¤   CHAR¤   ¤   ¤   ¤   sz[64];
69b236 ¤   INT¤¤   ¤   ¤   ¤   i;
9c06b1 ¤   DWORD¤  ¤   ¤   ¤   dw;
378f52 ¤   PGPError¤   ¤   ¤   err;
69af5a
f1347f ¤   switch (uMsg) {
51af5a
6cad3a ¤   case WM_INITDIALOG :
ea7547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
f8394f ¤   ¤   psss = (PSENDSHARESSTRUCT)lParam;
afaf5a
12bf26 ¤   ¤   psss->hwnd = hDlg;
02a2cb ¤   ¤   SetDlgItemText (hDlg, IDC_SHAREFILE, psss->szName);
5d22aa ¤   ¤   SetDlgItemInt (hDlg, IDC_NUMSHARES, psss->uNumShares, FALSE);
d6af5a
fe12ae ¤   ¤   LoadString (g_hInst, IDS_STATUSNOTCONNECTED, sz, sizeof(sz));
944381 ¤   ¤   SetDlgItemText (hDlg, IDC_NETSTATUS, sz);
a7af5a
548245 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SENDSHARES), FALSE);
c0836c ¤   ¤   return TRUE;
4daf5a
c08a25 ¤   case WM_HELP:·
c8fb42 ¤   ····WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
00d0c3 ¤   ········HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
a37d53 ¤   ····break;·
1caf5a
24af40 ¤   case WM_CONTEXTMENU:·
4a082b ¤   ¤   WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
259517 ¤   ¤   ····(DWORD) (LPVOID) aIds);·
81ca2d ¤   ¤   break;·
49af5a
235020 ¤   case WM_APP :
52be20 ¤   ¤   psss = (PSENDSHARESSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
5cd655 ¤   ¤   err = (PGPError)lParam;
f5a42f ¤   ¤   if (IsPGPError (err)) {
ea8d98 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_AUTHENTICATION, "");
3c0418 ¤   ¤   ¤   LoadString (g_hInst, IDS_STATUSNOTCONNECTED, sz, sizeof(sz));
f7ed80 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_NETSTATUS, sz);
4d2fd6 ¤   ¤   ¤   PGPclErrorBox (hDlg, err);
9467c5 ¤
73c7e7 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SENDSHARES), TRUE);
f50fe4 ¤   ¤   }
7707e0 ¤   ¤   else {
346c9e ¤   ¤   ¤   LoadString (g_hInst, IDS_STATUSFINISHED, sz, sizeof(sz));
7ced80 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_NETSTATUS, sz);
8456f3 ¤   ¤   ¤   PGPclMessageBox (hDlg, IDS_PGP, IDS_SENDSUCCESS, MB_OK);
--b990 000669429f240110299 Page 4 of CLsend.c
e0af5a
1b8bd3 ¤   ¤   ¤   LoadString (g_hInst, IDS_DONE, sz, sizeof(sz));
28be27 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_SENDSHARES, sz);
524ba1 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDCANCEL), FALSE);
aac7e7 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SENDSHARES), TRUE);
70673d ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_SENDSHARES));
24cda7 ¤   ¤   ¤   aIds[1] = IDH_PGPCLSEND_DONE;¤  // change help ID for this button
3fa681 ¤   ¤   ¤   psss->bFinished = TRUE;
520fe4 ¤   ¤   }
66af5a
0a50fd ¤   ¤   PGPFreeSKEP (psss->skep);
5d2f68 ¤   ¤   break;
16af5a
add1d3 ¤   case WM_COMMAND :
e4537d ¤   ¤   switch (LOWORD(wParam)) {
a5b6bb ¤   ¤   case IDCANCEL :
97a896 ¤   ¤   ¤   psss = (PSENDSHARESSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
6a0d10 ¤   ¤   ¤   if (psss->bThreadRunning)·
52dc3f ¤   ¤   ¤   ¤   PGPskepCancel (psss->skep);
2abb8c ¤   ¤   ¤   else
0dd206 ¤   ¤   ¤   ¤   EndDialog (hDlg, 0);
72cdcb ¤   ¤   ¤   break;
53af5a
cf47bc ¤   ¤   case IDC_SENDSHARES :
66a896 ¤   ¤   ¤   psss = (PSENDSHARESSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
4eaf5a
2212c0 ¤   ¤   ¤   if (psss->bFinished) {
49d206 ¤   ¤   ¤   ¤   EndDialog (hDlg, 0);
71f622 ¤   ¤   ¤   ¤   break;
5da3a6 ¤   ¤   ¤   }
8daf5a
970800 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SENDSHARES), FALSE);
743afe ¤   ¤   ¤   if (psss->pszRemoteHost)·
2f8c8b ¤   ¤   ¤   ¤   clFree (psss->pszRemoteHost);
58af5a
abf4a4 ¤   ¤   ¤   i = GetWindowTextLength (GetDlgItem (hDlg, IDC_REMOTECOMPUTER))+1;
82835c ¤   ¤   ¤   psss->pszRemoteHost = clAlloc (i);
6a8181 ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_REMOTECOMPUTER, psss->pszRemoteHost, i);
c9af5a
3aa92c ¤   ¤   ¤   LoadString (g_hInst, IDS_STATUSCONNECTING, sz, sizeof(sz));
aded80 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_NETSTATUS, sz);
18af5a
ddda6f ¤   ¤   ¤   psss->bThreadRunning = TRUE;
4039ce ¤   ¤   ¤   PGPNewSKEP (psss->context, psss->tlsContext, &psss->skep);
5763b3 ¤   ¤   ¤   CreateThread (NULL, 0, sSendSharesThreadRoutine,·
7bff84 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (void*)psss, 0, &dw);
a9cdcb ¤   ¤   ¤   break;
f0af5a
38cc72 ¤   ¤   case IDC_REMOTECOMPUTER :
5c4348 ¤   ¤   ¤   if (HIWORD (wParam) == EN_CHANGE) {
824211 ¤   ¤   ¤   ¤   if (GetWindowTextLength ((HWND)lParam) > 0)
a39299 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SENDSHARES), TRUE);
b7fa07 ¤   ¤   ¤   ¤   else
6b92ac ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SENDSHARES), FALSE);
5ba3a6 ¤   ¤   ¤   }
78cdcb ¤   ¤   ¤   break;
220fe4 ¤   ¤   }
d0836c ¤   ¤   return TRUE;
a09371 ¤   }
c6a230 ¤   return FALSE;
60efe6 }
0daf5a
a8af5a
bf4265 //¤ ___________________________________________________
33465d //
404fee // ·decode event handler
19af5a
caf1ae static PGPError
d9a4ce sHandlerDecode (
aee958 ¤   ¤   PGPContextRef¤  context,
185b49 ¤   ¤   PGPEvent*¤  ¤   event,
66c05f ¤   ¤   PGPUserValue¤   userValue)
--c756 000145ca17b40110299 Page 5 of CLsend.c
2cbb36 {
12b4ef ¤   PSENDSHARESSTRUCT¤  psss;
318f52 ¤   PGPError¤   ¤   ¤   err;
b2af5a
73a48f ¤   switch (event->type) {
256062 ¤   case kPGPEvent_PassphraseEvent:
1c5b34 ¤   ¤   {
e7a136 ¤   ¤   ¤   PGPEventPassphraseData¤ *pData = &event->data.passphraseData;
feaf5a
8153cc ¤   ¤   ¤   UINT¤   ¤   uLen;
b0fe7c ¤   ¤   ¤   CHAR¤   ¤   szPrompt[64];
05af5a
6d4cd5 ¤   ¤   ¤   psss = (PSENDSHARESSTRUCT)userValue;
2643d0 ¤   ¤   ¤   psss->bConventional = pData->fConventional;
62af5a
b20c95 ¤   ¤   ¤   LoadString (g_hInst, IDS_DECRYPTSHARESPROMPT,·
d0c5c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szPrompt, sizeof(szPrompt));
22af5a
a40d98 ¤   ¤   ¤   // free phrase if this is a retry
62519e ¤   ¤   ¤   if (psss->pszPhrase) {
71eb72 ¤   ¤   ¤   ¤   KMFreePhrase (psss->pszPhrase);
8fb9ca ¤   ¤   ¤   ¤   psss->pszPhrase = NULL;
64a3a6 ¤   ¤   ¤   }
dbed50 ¤   ¤   ¤   if (psss->pPasskey) {
694cea ¤   ¤   ¤   ¤   KMFreePasskey (psss->pPasskey, psss->sizePasskey);
4275c0 ¤   ¤   ¤   ¤   psss->pPasskey = NULL;
12a3a6 ¤   ¤   ¤   }
11af5a
6d9222 ¤   ¤   ¤   if (event->data.passphraseData.fConventional) {
229584 ¤   ¤   ¤   ¤   err = KMGetKeyPhrase (context, psss->tlsContext,·
8aef24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->hwndParent, szPrompt, psss->keyset,·
17cf77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, &(psss->pszPhrase),·
8026d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(psss->pPasskey), &(psss->sizePasskey));
38a3a6 ¤   ¤   ¤   }
47e543 ¤   ¤   ¤   else {
36b61d ¤   ¤   ¤   ¤   psss->keyAuthenticating = NULL;
d55099 ¤   ¤   ¤   ¤   err = KMGetDecryptionPhrase (context, psss->tlsContext,·
d5ef24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->hwndParent, szPrompt, psss->keyset,·
1528ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &psss->keyAuthenticating,·
863757 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->keysetDecryption,
32ebd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->iKeyIDCount, psss->keyidsDecryption,
e8343f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &psss->keysetToAdd,·
0100fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(psss->pszPhrase),·
4b26d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(psss->pPasskey), &(psss->sizePasskey));
e8a3a6 ¤   ¤   ¤   }
73af5a
da60c7 ¤   ¤   ¤   if (IsPGPError (err))
1a454a ¤   ¤   ¤   ¤   return err;
85af5a
85519e ¤   ¤   ¤   if (psss->pszPhrase) {
ebeb59 ¤   ¤   ¤   ¤   uLen = lstrlen (psss->pszPhrase);
00c0a6 ¤   ¤   ¤   ¤   PGPAddJobOptions (event->job,·
f17ee3 ¤   ¤   ¤   ¤   ¤   PGPOPassphraseBuffer (context, psss->pszPhrase, uLen),
5cfb91 ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
fca3a6 ¤   ¤   ¤   }
01e543 ¤   ¤   ¤   else {
38c0a6 ¤   ¤   ¤   ¤   PGPAddJobOptions (event->job,·
812085 ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context,·
82f34c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psss->pPasskey, psss->sizePasskey),
a9fb91 ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
06a3a6 ¤   ¤   ¤   }
930fe4 ¤   ¤   }
142f68 ¤   ¤   break;
f4af5a
5a589b ¤   case kPGPEvent_RecipientsEvent:
2f5b34 ¤   ¤   {
2a1d43 ¤   ¤   ¤   PGPEventRecipientsData¤ *pData = &event->data.recipientsData;
1a13f0 ¤   ¤   ¤   PGPUInt32¤  ¤   ¤   ¤   i;
a687c7 ¤   ¤   ¤
484cd5 ¤   ¤   ¤   psss = (PSENDSHARESSTRUCT)userValue;
5b6dbc ¤   ¤   ¤   psss->keyAuthenticating = kPGPInvalidRef;
141b52 ¤   ¤
--0ec6 000ec1604f540110299 Page 6 of CLsend.c
135bee ¤   ¤   ¤   // Save recipient key set for passphrase dialog
9951ff ¤   ¤   ¤   psss->keysetDecryption = pData->recipientSet;
30da48 ¤   ¤   ¤   PGPIncKeySetRefCount (psss->keysetDecryption);
a5af5a
98c4df ¤   ¤   ¤   // Save unknown keyids
a16e21 ¤   ¤   ¤   if (pData->keyCount > 0) {
fab215 ¤   ¤   ¤   ¤   psss->iKeyIDCount = pData->keyCount;
6693bd ¤   ¤   ¤   ¤   psss->keyidsDecryption =·
3162c5 ¤   ¤   ¤   ¤   ¤   (PGPKeyID *)clAlloc (pData->keyCount * sizeof(PGPKeyID));
80af5a
41a1a5 ¤   ¤   ¤   ¤   for (i=0; i<pData->keyCount; i++) {
1b01c5 ¤   ¤   ¤   ¤   ¤   psss->keyidsDecryption[i] = pData->keyIDArray[i];
1f2613 ¤   ¤   ¤   ¤   }
74a3a6 ¤   ¤   ¤   }
dd0fe4 ¤   ¤   }
042f68 ¤   ¤   break;
289371 ¤   }
d0af5a
3e151e ¤   return kPGPError_NoErr;
dfefe6 }
a3af5a
84af5a
8b4265 //¤ ___________________________________________________
e8465d //
10601a // ·send shares
0eaf5a
e1ec6d PGPError PGPclExport
c83a8e PGPclSendShares (
c3b579 ¤   ¤   PGPContextRef¤  ¤   context,·
5ba960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
e1f531 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,
d76e9b ¤   ¤   PGPKeySetRef¤   ¤   keyset)·
bcbb36 {
339a58 ¤   PFLFileSpecRef¤ ¤   fileref¤¤   ¤   ¤   = NULL;
727f56 ¤   PGPShareFileRef¤¤   sharefileref¤   ¤   = NULL;
2f984f ¤   PGPOptionListRef¤   optionsDecode¤  ¤   = NULL;
493f1b ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
94af5a
55097f ¤   OPENFILENAME¤   ¤   ofn;
663b59 ¤   SENDSHARESSTRUCT¤   sss;
766af0 ¤   CHAR¤   ¤   ¤   ¤   szFile[MAX_PATH];
98b697 ¤   CHAR¤   ¤   ¤   ¤   sz[256];
4347b0 ¤   CHAR¤   ¤   ¤   ¤   szTitle[64];
c425c8 ¤   CHAR*¤  ¤   ¤   ¤   p;
2cca8a ¤   PGPSize¤¤   ¤   ¤   size;
eeaf5a
65a8bb ¤   // initialize struct
9a3cec ¤   sss.context¤¤   ¤   ¤   = context;
476492 ¤   sss.tlsContext¤ ¤   ¤   = tlsContext;
2b7317 ¤   sss.hwnd¤   ¤   ¤   ¤   = NULL;
64af24 ¤   sss.hwndParent¤ ¤   ¤   = hwndParent;
a24c15 ¤   sss.keyset¤ ¤   ¤   ¤   = keyset;
94b212 ¤   sss.keysetDecryption¤   = kInvalidPGPKeySetRef;
449ea3 ¤   sss.keyidsDecryption¤   = NULL;
9da3c7 ¤   sss.keysetToAdd¤¤   ¤   = kInvalidPGPKeySetRef;
35078d ¤   sss.keyAuthenticating¤  = kInvalidPGPKeyRef;
36e303 ¤   sss.pszPhrase¤  ¤   ¤   = NULL;
4c06ff ¤   sss.pPasskey¤   ¤   ¤   = NULL;
76d421 ¤   sss.shares¤ ¤   ¤   ¤   = NULL;
40c608 ¤   sss.pszRemoteHost¤  ¤   = NULL;
f5881c ¤   sss.bConventional¤  ¤   = FALSE;
e50f9c ¤   sss.bThreadRunning¤ ¤   = FALSE;
6347e2 ¤   sss.bFinished¤  ¤   ¤   = FALSE;
63af5a
b8a673 ¤   // prompt user for name of share file to send
6e6632 ¤   szFile[0] = '\0';
c665df ¤   LoadString (g_hInst, IDS_SHAREFILEFILTER, sz, sizeof(sz));
e968d7 ¤   while (p = strrchr (sz, '@')) *p = '\0';
f648d3 ¤   LoadString (g_hInst, IDS_SHAREFILECAPTION, szTitle, sizeof(szTitle));
84af5a
9b4fd0 ¤   ofn.lStructSize ······= sizeof (OPENFILENAME);
ecbf14 ¤   ofn.hwndOwner ········= hwndParent;
--3f9d 000f7ecff6540110299 Page 7 of CLsend.c
bea756 ¤   ofn.hInstance ········= (HANDLE)g_hInst;
4ad0b3 ¤   ofn.lpstrFilter ······= sz;
ec3385 ¤   ofn.lpstrCustomFilter = (LPTSTR)NULL;
38e9dc ¤   ofn.nMaxCustFilter ···= 0L;
7c80b6 ¤   ofn.nFilterIndex ·····= 1L;
5a4e92 ¤   ofn.lpstrFile ········= szFile;
f0e317 ¤   ofn.nMaxFile ·········= sizeof (szFile);
32d176 ¤   ofn.lpstrFileTitle ···= NULL;
0f8734 ¤   ofn.nMaxFileTitle ····= 0;
003225 ¤   ofn.lpstrInitialDir ··= NULL;
f8006e ¤   ofn.lpstrTitle ·······= szTitle;
f1ef71 ¤   ofn.Flags¤  ¤   ¤   ··= OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
580d2e ¤   ofn.nFileOffset ······= 0;
0dc4f3 ¤   ofn.nFileExtension ···= 0;
e42fcb ¤   ofn.lpstrDefExt ······= "";
f9ebd4 ¤   ofn.lCustData ········= 0;
f5af5a
1363b6 ¤   if (GetOpenFileName (&ofn)) {
df7c9a ¤   ¤   err = PFLNewFileSpecFromFullPath (PGPGetContextMemoryMgr (context),·
5b0123 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFile, &fileref);
7683ae ¤   ¤   if (IsPGPError (err)) goto SendCleanup;
f5d83c ·
79a342 ¤   ¤   err = PGPOpenShareFile (fileref, &sharefileref);
4d83ae ¤   ¤   if (IsPGPError (err)) goto SendCleanup;
dcaf5a
1f3c62 ¤   ¤   err = PGPGetShareFileUserID (sharefileref,
688de7 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sss.szName), sss.szName, &size);
ff83ae ¤   ¤   if (IsPGPError (err)) goto SendCleanup;
6baf5a
1da41f ¤   ¤   sss.uNumShares = PGPGetNumSharesInFile (sharefileref);
bfaf5a
092851 ¤   ¤   // decrypt specified share file
0e1601 ¤   ¤   PGPBuildOptionList(context, &optionsDecode,
b9567d ¤   ¤   ¤   ¤   ¤   ¤   PGPOKeySetRef (context, keyset),
fa99b4 ¤   ¤   ¤   ¤   ¤   ¤   PGPOEventHandler (context, sHandlerDecode, &sss),
922323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
99c347 ¤   ¤   err = PGPCopySharesFromFile (context, sharefileref,·
782b0a ¤   ¤   ¤   ¤   ¤   ¤   optionsDecode, &sss.shares);
bdaf5a
2883ae ¤   ¤   if (IsPGPError (err)) goto SendCleanup;
58af5a
0471b9 ¤   ¤   // get authentication key and passphrase
d8c1ac ¤   ¤   if (sss.bConventional) {
d5af5a
65ccd0 ¤   ¤   ¤   // the phrase and passkey we got from user is no good here
114a45 ¤   ¤   ¤   if (sss.pszPhrase) {
690a60 ¤   ¤   ¤   ¤   KMFreePhrase (sss.pszPhrase);
3bfed8 ¤   ¤   ¤   ¤   sss.pszPhrase = NULL;
aca3a6 ¤   ¤   ¤   }
9ceffb ¤   ¤   ¤   if (sss.pPasskey) {
415fb8 ¤   ¤   ¤   ¤   KMFreePasskey (sss.pPasskey, sss.sizePasskey);
754bd5 ¤   ¤   ¤   ¤   sss.pPasskey = NULL;
5da3a6 ¤   ¤   ¤   }
84af5a
da9e41 ¤   ¤   ¤   // get new phrase
7c9898 ¤   ¤   ¤   LoadString (g_hInst, IDS_SENDAUTHPROMPT, sz, sizeof(sz));
02c9e2 ¤   ¤   ¤   err = KMGetSigningKeyPhrase (context, tlsContext, hwndParent,·
bf5dcf ¤   ¤   ¤   ¤   ¤   ¤   sz, keyset, TRUE, &sss.keyAuthenticating,
6a9349 ¤   ¤   ¤   ¤   ¤   ¤   &sss.pszPhrase, &sss.pPasskey, &sss.sizePasskey);·
ab15ef ¤   ¤   ¤   if (IsPGPError (err)) goto SendCleanup;
730fe4 ¤   ¤   }
b6af5a
c8f147 ¤   ¤   // launch send key shares dialog
b68ebc ¤   ¤   DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_SENDSHARES), hwndParent,·
7a6064 ¤   ¤   ¤   ¤   ¤   ¤   sSendKeySharesDlgProc, (LPARAM)&sss);
db9371 ¤   }
ebaf5a
9ae850 SendCleanup :
d6b2fb ¤   if (sss.pszPhrase)
200f4b ¤   ¤   KMFreePhrase (sss.pszPhrase);
62af5a
f72972 ¤   if (sss.pPasskey)
--fcfc 0015746083340110299 Page 8 of CLsend.c
305861 ¤   ¤   KMFreePasskey (sss.pPasskey, sss.sizePasskey);
19af5a
7bc679 ¤   if (sss.pszRemoteHost)
a3004c ¤   ¤   clFree (sss.pszRemoteHost);
abaf5a
206bed ¤   if (sss.shares)·
58ad97 ¤   ¤   PGPFreeShares (sss.shares);
04af5a
cb2cd7 ¤   if (PGPKeySetRefIsValid (sss.keysetDecryption))
bbecd3 ¤   ¤   PGPFreeKeySet (sss.keysetDecryption);
e0af5a
301a13 ¤   if (sss.keyidsDecryption)
8afdab ¤   ¤   clFree (sss.keyidsDecryption);
b9af5a
4a0a07 ¤   if (sharefileref)
a9d958 ¤   ¤   PGPFreeShareFile (sharefileref);
52af5a
7e27ed ¤   if (fileref)
84f26e ¤   ¤   PFLFreeFileSpec (fileref);
b7af5a
768fe5 ¤   if (optionsDecode)
acbc6b ¤   ¤   PGPFreeOptionList(optionsDecode);
77af5a
10dc76 ¤   if (PGPKeySetRefIsValid (sss.keysetToAdd)) {
ea8536 ¤   ¤   if (IsntPGPError (err)) {
89286f ¤   ¤   ¤   PGPclQueryAddKeys (context, tlsContext, hwndParent,
ba2b72 ¤   ¤   ¤   ¤   ¤   sss.keysetToAdd, keyset);
720fe4 ¤   ¤   }
f7b450 ¤   ¤   PGPFreeKeySet (sss.keysetToAdd);
f19371 ¤   }
91af5a
c47ed5 ¤   PGPclErrorBox (hwndParent, err);
65af5a
ad5ea8 ¤   return err;
2eefe6 }
57af5a
--764e 0008e0a7b044011029a Page 1 of CLserver.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
286ac1 ¤   CLserver.c -¤   handle those types of communication with keyserver
30a329 ¤   ¤   ¤   ¤   ¤   which are not handled by SDKuiLib
d567c5 ¤
feaf5a
c77f59 ¤   $Id: CLserver.c,v 1.42 1998/08/12 17:32:16 pbj Exp $
f7f7f7 ____________________________________________________________________________*/
12e610 #include "pgpPFLConfig.h"
b1af5a
44c917 // project header files
be5fcd #include "pgpclx.h"
32850a #include "pgpkmx.h"
40af5a
885584 // constant definitions
e2b7bd #define LEDTIMER¤   ¤   111L
334cc2 #define LEDTIMERPERIOD¤ 100L
10af5a
07e2dd #define NUMLEDS¤¤   ¤   10
a07fd1 #define LEDSPACING¤ ¤   2
12af5a
fe4db7 #define SENDGROUPS¤ ¤   1
01143c #define GETGROUPS¤  ¤   2
317318 #define SENDKEY¤¤   ¤   3
3d1090 #define¤DISABLEKEY¤ ¤   4
544254 #define DELETEKEY¤  ¤   5
0eaf5a
56d0d3 #if PGP_BUSINESS_SECURITY && PGP_ADMIN_BUILD
df0035 #define¤SERVER_ACCESS_TYPE¤ kPGPKeyServerAccessType_Administrator
77db21 #else
d31d32 #define¤SERVER_ACCESS_TYPE¤ kPGPKeyServerAccessType_Normal
1a7454 #endif
c3af5a
e093ed // external globals
539cad extern HINSTANCE g_hInst;
87af5a
e65bee // typedefs
58f0f7 typedef struct {
ae429f ¤   PGPContextRef¤  ¤   ¤   context;
b189ec ¤   PGPtlsContextRef¤   ¤   tlsContext;
0f124a ¤   HWND¤   ¤   ¤   ¤   ¤   hwnd;
623593 ¤   LPTHREAD_START_ROUTINE¤ lpThread;
4d3fb1 ¤   BOOL¤   ¤   ¤   ¤   ¤   bSearchInProgress;
e61165 ¤   BOOL¤   ¤   ¤   ¤   ¤   bCancel;
fab855 ¤   BOOL¤   ¤   ¤   ¤   ¤   bThreadFree;
47ca89 ¤   INT¤¤   ¤   ¤   ¤   ¤   iStatusValue;
b3796b ¤   INT¤¤   ¤   ¤   ¤   ¤   iStatusDirection;
11bb39 ¤   UINT¤   ¤   ¤   ¤   ¤   uOperation;
86ba49 ¤   PGPError¤   ¤   ¤   ¤   err;
167121 ¤   PGPKeySetRef¤   ¤   ¤   keysetIn;
b94447 ¤   PGPKeySetRef¤   ¤   ¤   keysetOut;
d655a9 ¤   PGPKeySetRef¤   ¤   ¤   keysetMain;
280de8 ¤   PGPKeyServerKeySpace¤   space;
82adca ¤   PGPKeyServerEntry¤  ¤   ksentry;
6d4624 ¤   PGPKeyServerRef¤¤   ¤   server;
68c305 ¤   PGPGroupSetRef¤ ¤   ¤   groupset;
7c70aa } SERVERTHREADSTRUCT, *PSERVERTHREADSTRUCT;
9daf5a
51af5a
554265 //¤ ___________________________________________________
28465d //
2aabe1 //¤ update keyserver entry info in prefs
1eaf5a
819d43 PGPError PGPclExport·
9529c0 PGPclSyncKeyserverPrefs (
649cd4 ¤   ¤   PGPContextRef¤  ¤   context,
38a6c8 ¤   ¤   PGPKeyServerEntry*¤ keyserver)
15bb36 {
49a48f ¤   PGPKeyServerEntry*¤ keyserverList¤  ¤   = NULL;
8e09ed ¤   PGPPrefRef¤ ¤   ¤   prefRef;
--b23e 000745d4e014011029a Page 2 of CLserver.c
b90110 ¤   PGPUInt32¤  ¤   ¤   keyserverCount;
f48f52 ¤   PGPError¤   ¤   ¤   err;
61af5a
943677 ¤   // load keyserverprefs
4eca35 ¤   err = PGPclOpenClientPrefs (
1eae6c ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (context),
74d0b7 ¤   ¤   ¤   ¤   &prefRef);
f1af5a
ccb23e ¤   if (IsntPGPError (err)) {
c66356 ¤   ¤   err = PGPGetKeyServerPrefs (prefRef,
a9f603 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverList,
2b907d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverCount);
b0af5a
e18536 ¤   ¤   if (IsntPGPError (err)) {
473130 ¤   ¤   ¤   PGPUInt32¤  index;
4aaf5a
6597e4 ¤   ¤   ¤   for (index = 0; index < keyserverCount; index++) {
f343a6 ¤   ¤   ¤   ¤   if (KeyServersAreEqual (keyserverList[index], *keyserver))
2872c3 ¤   ¤   ¤   ¤   {
3bbfd7 ¤   ¤   ¤   ¤   ¤   keyserverList[index].authAlg = keyserver->authAlg;
bbddbe ¤   ¤   ¤   ¤   ¤   lstrcpy (keyserverList[index].authKeyIDString,·
2602dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserver->authKeyIDString);
5814c3 ¤   ¤   ¤   ¤   ¤   break;
3a2613 ¤   ¤   ¤   ¤   }
5ca3a6 ¤   ¤   ¤   }
d6af5a
2f90ac ¤   ¤   ¤   err = PGPSetKeyServerPrefs (prefRef,
02da5a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList,
ad7ffc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverCount);
66af5a
ee0fe4 ¤   ¤   }
bdaf5a
271a09 ¤   ¤   PGPclCloseClientPrefs (prefRef, TRUE);
959371 ¤   }
42af5a
5b2248 ¤   if (keyserverList)·
78ba9b ¤   ¤   PGPDisposePrefData (prefRef, keyserverList);
7daf5a
8e5ea8 ¤   return err;
29efe6 }
73af5a
0e4265 //¤ ___________________________________________________
11465d //
0f7774 //¤ event handler for keyserver functions
8baf5a
a769c9 static PGPError·
859aee sServerEventHandler(
10e958 ¤   ¤   PGPContextRef¤  context,
b6d476 ¤   ¤   PGPEvent*¤  ¤   pevent,·
dec05f ¤   ¤   PGPUserValue¤   userValue)
3fbb36 {
23e23a ¤   PSERVERTHREADSTRUCT¤¤   psts¤   ¤   = (PSERVERTHREADSTRUCT)userValue;
6b5ebf ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
01b1e9 ¤   BOOL¤   ¤   ¤   ¤   ¤   bUserCancel = FALSE;
0cc1c1 ¤   BOOL¤   ¤   ¤   ¤   ¤   bSecure¤¤   = FALSE;
1baf5a
de2d23 ¤   if (psts->bCancel) {
9774be ¤   ¤   return kPGPError_UserAbort;
f69371 ¤   }
72af5a
399570 ¤   switch (pevent->type) {
02af5a
58bfc7 ¤   case kPGPEvent_KeyServerEvent:
c15b34 ¤   ¤   {
f96466 ¤   ¤   ¤   INT¤¤   ¤   ¤   ¤   ¤   ids¤¤   = 0;
6fedd1 ¤   ¤   ¤   PGPEventKeyServerData¤  data¤   = pevent->data.keyServerData;
98af5a
b9b934 ¤   ¤   ¤   PGPclSERVEREVENT¤   ¤   serverevent;
19af5a
c6b853 ¤   ¤   ¤   memset(&serverevent, 0x00, sizeof(PGPclSERVEREVENT));
f067c5 ¤
74dc6e ¤   ¤   ¤   serverevent.nmhdr.hwndFrom = (HWND)psts->hwnd;
--2896 000eccd1bf04011029a Page 3 of CLserver.c
98b48a ¤   ¤   ¤   serverevent.nmhdr.idFrom = 0;
70ec2d ¤   ¤   ¤   serverevent.nmhdr.code = PGPCL_SERVERPROGRESS;
e4c2ca ¤   ¤   ¤   serverevent.cancel = FALSE;
0dfa17 ¤   ¤   ¤   serverevent.step = PGPCL_SERVERINFINITE;
1b491b ¤   ¤   ¤   serverevent.total = PGPCL_SERVERINFINITE;
f867c5 ¤
5b1a7c ¤   ¤   ¤   switch (data.state) {
d33c6a ¤   ¤   ¤   case kPGPKeyServerState_Opening : ids = IDS_CONNECTING;¤break;
f78901 ¤   ¤   ¤   case kPGPKeyServerState_Querying :¤ ·ids = IDS_QUERYING;break;
e0996f ¤   ¤   ¤   case kPGPKeyServerState_ProcessingResults :
b0cc29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ids = IDS_PROCESSING;¤  break;
94b499 ¤   ¤   ¤   case kPGPKeyServerState_Uploading :¤
b9b04f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ids = IDS_EXCHANGING;¤  break;
752270 ¤   ¤   ¤   case kPGPKeyServerState_Deleting : ids = IDS_DELETING;¤ break;
24f140 ¤   ¤   ¤   case kPGPKeyServerState_Disabling : ids = IDS_DISABLING;break;
964eac ¤   ¤   ¤   case kPGPKeyServerState_Closing : ids = IDS_CLOSING;¤   break;
23a3a6 ¤   ¤   ¤   }
74af5a
74b38e ¤   ¤   ¤   if (ids) {
d2e792 ¤   ¤   ¤   ¤   LoadString (g_hInst, ids, serverevent.szmessage,
5a08ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(serverevent.szmessage));
a65f35 ¤   ¤   ¤   ¤   lstrcat (serverevent.szmessage, psts->ksentry.serverDNS);
c0a3a6 ¤   ¤   ¤   }
e9af5a
494526 ¤   ¤   ¤   SendMessage (psts->hwnd, WM_NOTIFY,·
bd74ae ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)(psts->hwnd), (LPARAM)&serverevent);
736a07 ¤   ¤   ¤   bUserCancel = serverevent.cancel;
8daf5a
ffcdcb ¤   ¤   ¤   break;
820fe4 ¤   ¤   }
d3af5a
124d59 ¤   case kPGPEvent_KeyServerSignEvent:
965b34 ¤   ¤   {
9fc621 ¤   ¤   ¤   PGPKeyRef¤  ¤   keySigning¤ = kInvalidPGPKeyRef;
954249 ¤   ¤   ¤   PGPByte*¤   ¤   pPasskey¤   = NULL;
238160 ¤   ¤   ¤   PGPSize¤¤   ¤   sizePasskey;
cb3ffc ¤   ¤   ¤   CHAR¤   ¤   ¤   sz[64];
1faf5a
f29e14 ¤   ¤   ¤   if (!psts->bCancel) {
5fa76b ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_PHRASEPROMPT, sz, sizeof(sz));
a0af5a
6aadec ¤   ¤   ¤   ¤   err = KMGetSigningKeyPhrase (
194658 ¤   ¤   ¤   ¤   ¤   psts->context,¤ ¤   // in context
d483a3 ¤   ¤   ¤   ¤   ¤   NULL,¤  ¤   ¤   ¤   // in tlscontext
579e08 ¤   ¤   ¤   ¤   ¤   psts->hwnd,¤¤   ¤   // in hwnd of parent
b45cb1 ¤   ¤   ¤   ¤   ¤   sz,¤¤   ¤   ¤   ¤   // in prompt
5585c5 ¤   ¤   ¤   ¤   ¤   psts->keysetMain,¤  // in keyset
583d3e ¤   ¤   ¤   ¤   ¤   FALSE,¤ ¤   ¤   ¤   // in reject split keys
d50e05 ¤   ¤   ¤   ¤   ¤   &keySigning,¤   ¤   // in/out signing key
9dc424 ¤   ¤   ¤   ¤   ¤   NULL,¤  ¤   ¤   ¤   // out phrase
6c324a ¤   ¤   ¤   ¤   ¤   &pPasskey,¤ ¤   ¤   // out passkey buffer
6e0c5d ¤   ¤   ¤   ¤   ¤   &sizePasskey);¤ ¤   // out passkey length
56af5a
9f27e8 ¤   ¤   ¤   ¤   if (IsntPGPError(err)) {
e43aaf ¤   ¤   ¤   ¤   ¤   err = PGPAddJobOptions (pevent->job,
6579ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOSignWithKey (
a39b57 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->context,·
1b21bf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keySigning,·
a9b869 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pPasskey) ?
efd368 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (psts->context,·
ca8ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey) :
09ccdc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPONullOption (psts->context),
d7fa0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (psts->context)),
d7cc96 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOClearSign (psts->context, TRUE),
49f8bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (psts->context));
722613 ¤   ¤   ¤   ¤   }
d2af5a
d8ece9 ¤   ¤   ¤   ¤   // burn and free passkey
7b7ac8 ¤   ¤   ¤   ¤   if (pPasskey)
7d46b5 ¤   ¤   ¤   ¤   ¤   PGPFreeData (pPasskey);
8ea3a6 ¤   ¤   ¤   }
eccdcb ¤   ¤   ¤   break;
--d990 0002da48cc94011029a Page 4 of CLserver.c
b50fe4 ¤   ¤   }
e6af5a
633318 ¤   case kPGPEvent_KeyServerTLSEvent:
2cdfe6 ¤   ¤   err = CLHandleTLSEvent (context, pevent, psts->hwnd,·
6b0094 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keysetMain, &psts->ksentry, &bSecure);
512f68 ¤   ¤   break;
c19371 ¤   }
dcaf5a
21fc17 ¤   if (psts->bCancel || bUserCancel) {
d50fd8 ¤   ¤   err = kPGPError_UserAbort;
d39371 ¤   }
bdaf5a
be5ea8 ¤   return err;
99efe6 }
93af5a
c54265 //¤ ___________________________________________________
8f465d //
ea3abe //¤ thread routine to handle all keyserver operations
f4af5a
29e8c0 static DWORD WINAPI·
20ed39 sKeyserverThreadRoutine (LPVOID lpvoid)
a2bb36 {
9b6e21 ¤   PSERVERTHREADSTRUCT¤¤   ¤   psts¤   ¤   ¤   = (PSERVERTHREADSTRUCT)lpvoid;
77c00b ¤   PGPPrefRef¤ ¤   ¤   ¤   ¤   prefref¤¤   ¤   = kPGPInvalidRef;
f651c1 ¤   HWND¤   ¤   ¤   ¤   ¤   ¤   hwndParent¤ ¤   = psts->hwnd;
2149ce ¤   PGPError¤   ¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
28bd19 ¤   PGPKeyRef¤  ¤   ¤   ¤   ¤   key¤¤   ¤   ¤   = kInvalidPGPKeyRef;
fc1384 ¤   PGPKeySetRef¤   ¤   ¤   ¤   keysetFailed¤   = kInvalidPGPKeySetRef;
5751c1 ¤   PGPKeyServerAccessType¤ ¤   ksaccess¤   ¤   = SERVER_ACCESS_TYPE;
d2af5a
439341 ¤   PGPclSERVEREVENT¤   ¤   ¤   ¤   event;
f32eed ¤   BOOL¤   ¤   ¤   ¤   ¤   ¤   ¤   bThreadFree;
8f9a5c ¤   PGPKeyServerThreadStorageRef¤   previousStorage;
4167c5 ¤
abae70 ¤   memset (&event, 0x00, sizeof(event));
b62316 ¤   event.nmhdr.hwndFrom = hwndParent;
08ad88 ¤   event.nmhdr.idFrom = 0;
72b36f ¤   event.nmhdr.code = PGPCL_SERVERPROGRESS;
2c8599 ¤   event.pData = NULL;
f12fd7 ¤   event.cancel = FALSE;
ddc669 ¤   event.step = PGPCL_SERVERINFINITE;
bbd3de ¤   event.total = PGPCL_SERVERINFINITE;
7faf5a
abe626 ¤   err = PGPKeyServerInit ();
53b23e ¤   if (IsntPGPError (err)) {
d3d974 ¤   ¤   PGPKeyServerCreateThreadStorage(&previousStorage);
84af5a
e1906b ¤   ¤   // check for cases where we use root server exclusively
f0c7b9 ¤   ¤   if ((psts->uOperation == GETGROUPS) ||
27469d ¤   ¤   ¤   (psts->uOperation == SENDGROUPS) ||
2d4204 ¤   ¤   ¤   (psts->uOperation == SENDKEY))
315b34 ¤   ¤   {
7ff2b0 ¤   ¤   ¤   err = PGPclOpenClientPrefs (
e84b2a ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (psts->context),·
7a98fd ¤   ¤   ¤   ¤   ¤   &prefref); CKERR;
6f9951 ¤   ¤   ¤   err = PGPGetRootKeyServer (prefref, &psts->ksentry);·
a0254c ¤   ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
92311c ¤   ¤   ¤   if (err == kPGPError_ItemNotFound)
c9f776 ¤   ¤   ¤   {
244c76 ¤   ¤   ¤   ¤   PGPclMessageBox (hwndParent, IDS_CAPTION,·
41ce86 ¤   ¤   ¤   ¤   ¤   ¤   IDS_NOROOTSERVER, MB_OK|MB_ICONEXCLAMATION);
5e4067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
2eff25 ¤   ¤   ¤   ¤   goto done;
eea3a6 ¤   ¤   ¤   }
0f0fe4 ¤   ¤   }
80af5a
7392bc ¤   ¤   // send message to update status text
dda8db ¤   ¤   LoadString (g_hInst, IDS_LOOKINGFORSERVER, event.szmessage,
1b381c ¤   ¤   ¤   ¤   ¤   sizeof(event.szmessage));
d2986d ¤   ¤   lstrcat (event.szmessage, psts->ksentry.serverDNS);
f0315d ¤   ¤   SendMessage (hwndParent, WM_NOTIFY, (WPARAM)hwndParent,·
2d0eb9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&event);
--c071 000875a1d5e4011029a Page 5 of CLserver.c
e0af5a
fe534b ¤   ¤   // we need to set keyserver access type to admin to allow·
74b555 ¤   ¤   // users to delete their own keys.
30a296 ¤   ¤   if (psts->uOperation == DELETEKEY)
a8df8a ¤   ¤   ¤   ksaccess = kPGPKeyServerAccessType_Administrator;
a8af5a
e42dfe ¤   ¤   err = PGPNewKeyServerFromHostName (psts->context,·
e817e5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··psts->ksentry.serverDNS,
e9870d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··psts->ksentry.serverPort,
75b09b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··psts->ksentry.protocol,
17e814 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··ksaccess,
a07cf7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··psts->space,
bd6f16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··&psts->server);
8c8536 ¤   ¤   if (IsntPGPError (err)) {
9e42d2 ¤   ¤   ¤   PGPtlsSessionRef tls = kInvalidPGPtlsSessionRef;
2daf5a
b4fa33 ¤   ¤   ¤   PGPSetKeyServerEventHandler (psts->server,·
ce2861 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sServerEventHandler, psts);
13af5a
5a7c0f ¤   ¤   ¤   if ((psts->ksentry.protocol ==·
3b26ca ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyServerType_LDAPS) ||
f7ea4f ¤   ¤   ¤   ¤   (psts->ksentry.protocol ==
80de72 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyServerType_HTTPS))
f9f776 ¤   ¤   ¤   {
3d9e01 ¤   ¤   ¤   ¤   err = PGPNewTLSSession (psts->tlsContext, &tls);
3daf5a
6eea86 ¤   ¤   ¤   ¤   if (IsPGPError (err)) {
65a9b1 ¤   ¤   ¤   ¤   ¤   // warn beyond the icon?
fae781 ¤   ¤   ¤   ¤   ¤   tls = kInvalidPGPtlsSessionRef;
b22613 ¤   ¤   ¤   ¤   }
51a3a6 ¤   ¤   ¤   }
07af5a
1d57e6 ¤   ¤   ¤   // if disabling or deleting using TLS, then get local key
f767c4 ¤   ¤   ¤   if (((psts->uOperation == DISABLEKEY) ||
149824 ¤   ¤   ¤   ¤   ·(psts->uOperation == DELETEKEY) ||
27a5e3 ¤   ¤   ¤   ¤   ·(psts->uOperation == SENDGROUPS)) &&
45eecb ¤   ¤   ¤   ¤   ·PGPtlsSessionRefIsValid (tls))·
a9f776 ¤   ¤   ¤   {
f3c278 ¤   ¤   ¤   ¤   PGPKeyRef¤  keyAuth¤¤   ¤   = kInvalidPGPKeyRef;
467415 ¤   ¤   ¤   ¤   PGPByte*¤   pPasskey¤   ¤   = NULL;
b354d0 ¤   ¤   ¤   ¤   LPSTR¤  ¤   pszPhrase¤  ¤   = NULL;
cda4b6 ¤   ¤   ¤   ¤   PGPSize¤¤   sizePasskey;
7d3279 ¤   ¤   ¤   ¤   CHAR¤   ¤   sz[64];
1baf5a
79a76b ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_PHRASEPROMPT, sz, sizeof(sz));
2987c7 ¤   ¤   ¤
65adec ¤   ¤   ¤   ¤   err = KMGetSigningKeyPhrase (
2f4658 ¤   ¤   ¤   ¤   ¤   psts->context,¤ ¤   // in context
da83a3 ¤   ¤   ¤   ¤   ¤   NULL,¤  ¤   ¤   ¤   // in tlscontext
e59e08 ¤   ¤   ¤   ¤   ¤   psts->hwnd,¤¤   ¤   // in hwnd of parent
d85cb1 ¤   ¤   ¤   ¤   ¤   sz,¤¤   ¤   ¤   ¤   // in prompt
f885c5 ¤   ¤   ¤   ¤   ¤   psts->keysetMain,¤  // in keyset
b83d3e ¤   ¤   ¤   ¤   ¤   FALSE,¤ ¤   ¤   ¤   // in reject split keys
2c867c ¤   ¤   ¤   ¤   ¤   &keyAuth,¤  ¤   ¤   // in/out signing key
cfa4ad ¤   ¤   ¤   ¤   ¤   &pszPhrase,¤¤   ¤   // out phrase
f2324a ¤   ¤   ¤   ¤   ¤   &pPasskey,¤ ¤   ¤   // out passkey buffer
2d0c5d ¤   ¤   ¤   ¤   ¤   &sizePasskey);¤ ¤   // out passkey length
61af5a
5b56ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
3d2406 ¤   ¤   ¤   ¤   ¤   if (pszPhrase)
cee741 ¤   ¤   ¤   ¤   ¤   ¤   err = PGPtlsSetLocalPrivateKey (tls, keyAuth,
7dc98b ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (psts->context, pszPhrase),
cff8bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (psts->context));
8e4bd6 ¤   ¤   ¤   ¤   ¤   else
9be741 ¤   ¤   ¤   ¤   ¤   ¤   err = PGPtlsSetLocalPrivateKey (tls, keyAuth,
4ebed1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pPasskey) ?
d2c0e4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (psts->context,·
0950cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey) :
91f1b2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPONullOption (psts->context),
e3f8bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (psts->context));
522613 ¤   ¤   ¤   ¤   }
87af5a
--02c6 0003de860ef4011029a Page 6 of CLserver.c
6669fa ¤   ¤   ¤   ¤   // burn and free phrase
d00e20 ¤   ¤   ¤   ¤   if (IsntNull (pszPhrase))
d01fee ¤   ¤   ¤   ¤   ¤   PGPclFreePhrase (pszPhrase);
4b7ac8 ¤   ¤   ¤   ¤   if (pPasskey)
3846b5 ¤   ¤   ¤   ¤   ¤   PGPFreeData (pPasskey);
6ca3a6 ¤   ¤   ¤   }
3faf5a
33b940 ¤   ¤   ¤   // perform the keyserver operation
d66a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
2a5fa6 ¤   ¤   ¤   ¤   err = PGPKeyServerOpen (psts->server, tls);
7756ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
77af5a
70ece0 ¤   ¤   ¤   ¤   ¤   switch (psts->uOperation) {
cb935a ¤   ¤   ¤   ¤   ¤   case GETGROUPS :
e5cecc ¤   ¤   ¤   ¤   ¤   ¤   err = PGPRetrieveGroupsFromServer (psts->server,·
07bdf7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &psts->groupset);·
1b00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
3daf5a
c00aef ¤   ¤   ¤   ¤   ¤   case SENDGROUPS :
c493bb ¤   ¤   ¤   ¤   ¤   ¤   err = PGPSendGroupsToServer (psts->server,·
102cd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->groupset);·
f100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
9faf5a
87348f ¤   ¤   ¤   ¤   ¤   case SENDKEY :
658e45 ¤   ¤   ¤   ¤   ¤   ¤   err = PGPUploadToKeyServer (psts->server,·
322e3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keysetIn,·
765490 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keysetFailed);
9c790b ¤   ¤   ¤   ¤   ¤   ¤   if (PGPKeySetRefIsValid (keysetFailed))·
fe41cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetFailed);
d200eb ¤   ¤   ¤   ¤   ¤   ¤   break;
3baf5a
92d8e4 ¤   ¤   ¤   ¤   ¤   case DISABLEKEY :
895d6d ¤   ¤   ¤   ¤   ¤   ¤   err = PGPDisableFromKeyServer (psts->server,·
e42e3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keysetIn,·
815490 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keysetFailed);
b7790b ¤   ¤   ¤   ¤   ¤   ¤   if (PGPKeySetRefIsValid (keysetFailed))·
2e41cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetFailed);
a100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
50af5a
f3f57b ¤   ¤   ¤   ¤   ¤   case DELETEKEY :
3f99fe ¤   ¤   ¤   ¤   ¤   ¤   err = PGPDeleteFromKeyServer (psts->server,·
692e3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keysetIn,·
3d5490 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keysetFailed);
f1790b ¤   ¤   ¤   ¤   ¤   ¤   if (PGPKeySetRefIsValid (keysetFailed))·
8d41cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetFailed);
e800eb ¤   ¤   ¤   ¤   ¤   ¤   break;
05af5a
3e1c89 ¤   ¤   ¤   ¤   ¤   }
d06435 ¤   ¤   ¤   ¤   ¤   PGPKeyServerClose (psts->server);
8a2613 ¤   ¤   ¤   ¤   }
17a3a6 ¤   ¤   ¤   }
f4af5a
442839 ¤   ¤   ¤   PGPFreeKeyServer (psts->server);
c68b67 ¤   ¤   ¤   psts->server = kInvalidPGPKeyServerRef;
4aaf5a
b82b9c ¤   ¤   ¤   if (PGPtlsSessionRefIsValid (tls))·
16397b ¤   ¤   ¤   ¤   PGPFreeTLSSession (tls);
1e0fe4 ¤   ¤   }
a2af5a
1f0e60 ¤   ¤   PGPKeyServerDisposeThreadStorage(previousStorage);
4faf5a
10d159 ¤   ¤   PGPKeyServerCleanup ();
979371 ¤   }
65af5a
2aa1c0 done :
ac7ab0 ¤   // let window know that we're done
920bcd ¤   psts->err = err;
3caa94 ¤   event.szmessage[0] = '\0';
d09cea ¤   if (err == kPGPError_UserAbort) {
465af6 ¤   ¤   event.nmhdr.code = PGPCL_SERVERABORT;
a4fb47 ¤   ¤   LoadString (g_hInst, IDS_SERVERABORT, event.szmessage,
3d381c ¤   ¤   ¤   ¤   ¤   sizeof(event.szmessage));
--fe82 000236a6a184011029a Page 7 of CLserver.c
e2986d ¤   ¤   lstrcat (event.szmessage, psts->ksentry.serverDNS);
8a9371 ¤   }
ff4ce9 ¤   else if (IsPGPError (err)) {
d121f3 ¤   ¤   event.nmhdr.code = PGPCL_SERVERERROR;
a61d1a ¤   ¤   LoadString (g_hInst, IDS_SERVERERROR, event.szmessage,
66381c ¤   ¤   ¤   ¤   ¤   sizeof(event.szmessage));
6b986d ¤   ¤   lstrcat (event.szmessage, psts->ksentry.serverDNS);
fd9371 ¤   }
1d665a ¤   else {
de889d ¤   ¤   event.nmhdr.code = PGPCL_SERVERDONE;
06d2da ¤   ¤   LoadString (g_hInst, IDS_SERVEROK, event.szmessage,
ae381c ¤   ¤   ¤   ¤   ¤   sizeof(event.szmessage));
d5986d ¤   ¤   lstrcat (event.szmessage, psts->ksentry.serverDNS);
ce9371 ¤   }
ccaf5a
423063 ¤   bThreadFree = psts->bThreadFree;
79eb74 ¤   SendMessage (hwndParent, WM_NOTIFY, (WPARAM)hwndParent,·
a85c24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&event);
39af5a
97b279 ¤   // if thread should free data structure, do it
7ad2ae ¤   if (bThreadFree) {
af9d13 ¤   ¤   if (psts->keysetIn) PGPFreeKeySet (psts->keysetIn);
e280d3 ¤   ¤   free (psts);
479371 ¤   }
67af5a
043e6b ¤   return 0;
ceefe6 }
60af5a
b1af5a
5ac509 //¤ ____________________________________
d0465d //
05a4ef // ·Draw the "LED" progress indicator
56af5a
1de6b2 static VOID
908e0f sDrawStatus (
6f317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
4c93e2 ¤   ¤   PSERVERTHREADSTRUCT psts)·
bebb36 {
0450e1 ¤   HBRUSH¤ ¤   ¤   hBrushLit, hBrushUnlit, hBrushOld;
64df75 ¤   HPEN¤   ¤   ¤   hPen, hPenOld;
bfdfcd ¤   INT¤¤   ¤   ¤   i;
32648c ¤   INT¤¤   ¤   ¤   itop, ibot, ileft, iright, iwidth;
68ad04 ¤   PAINTSTRUCT¤¤   ps;
728bc2 ¤   HDC¤¤   ¤   ¤   hdc;
ff1372 ¤   RECT¤   ¤   ¤   rc;
25af5a
4f15f8 ¤   if (psts->iStatusValue < -1) return;
41af5a
cf079e ¤   hdc = BeginPaint (hwnd, &ps);
9faf5a
b5ff4c ¤   // draw 3D shadow
9647d1 ¤   GetClientRect (hwnd, &rc);
5b9ae0 ¤   itop = rc.top+1;
6ac454 ¤   ibot = rc.bottom-2;
49af5a
8bd3ea ¤   iwidth = (rc.right-rc.left) / NUMLEDS;
d7962e ¤   iwidth -= LEDSPACING;
1aaf5a
601566 ¤   ileft = rc.left + 4;
f58d6c ¤   for (i=0; i<NUMLEDS; i++) {
a59e04 ¤   ¤   iright = ileft + iwidth;
38af5a
11855c ¤   ¤   MoveToEx (hdc, ileft, ibot, NULL);
e899e0 ¤   ¤   LineTo (hdc, iright, ibot);
08b146 ¤   ¤   LineTo (hdc, iright, itop);
e6af5a
1defbc ¤   ¤   ileft += iwidth + LEDSPACING;
6c9371 ¤   }
b0af5a
e06cf6 ¤   hPen = CreatePen (PS_SOLID, 0, RGB (128, 128, 128));
83d2d7 ¤   hPenOld = SelectObject (hdc, hPen);
236d82 ¤   hBrushLit = CreateSolidBrush (RGB (0, 255, 0));
--43f3 000240b113f4011029a Page 8 of CLserver.c
e7ee91 ¤   hBrushUnlit = CreateSolidBrush (RGB (0, 128, 0));
f7af5a
a71566 ¤   ileft = rc.left + 4;
8aaf5a
df18f3 ¤   // draw "Knight Rider" LEDs
588e91 ¤   if (psts->iStatusDirection) {
7d1ae7 ¤   ¤   hBrushOld = SelectObject (hdc, hBrushUnlit);
820690 ¤   ¤   for (i=0; i<NUMLEDS; i++) {
8ca36c ¤   ¤   ¤   iright = ileft + iwidth;
7967c5 ¤
39418d ¤   ¤   ¤   if (i == psts->iStatusValue) {
f1bb93 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushLit);
30844c ¤   ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
5c1f85 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushUnlit);
c7a3a6 ¤   ¤   ¤   }
1c9905 ¤   ¤   ¤   else ·{
32844c ¤   ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
2ea3a6 ¤   ¤   ¤   }
6c67c5 ¤
0dd352 ¤   ¤   ¤   ileft += iwidth + LEDSPACING;
040fe4 ¤   ¤   }
6c9371 ¤   }
baaf5a
efa806 ¤   // draw "progress bar" LEDs
19d8f5 ¤   else {·
0fc4aa ¤   ¤   if (psts->iStatusValue >= 0)·
d5bb7c ¤   ¤   ¤   hBrushOld = SelectObject (hdc, hBrushLit);
340e1d ¤   ¤   else
e675d4 ¤   ¤   ¤   hBrushOld = SelectObject (hdc, hBrushUnlit);
feaf5a
ca0690 ¤   ¤   for (i=0; i<NUMLEDS; i++) {
0ba36c ¤   ¤   ¤   iright = ileft + iwidth;
5567c5 ¤
aca244 ¤   ¤   ¤   if (i > psts->iStatusValue) {
651f85 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushUnlit);
b8a3a6 ¤   ¤   ¤   }
140b1b ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
cc67c5 ¤
d0d352 ¤   ¤   ¤   ileft += iwidth + LEDSPACING;
a40fe4 ¤   ¤   }
bd9371 ¤   }
bcaf5a
148c3c ¤   SelectObject (hdc, hBrushOld);
d83570 ¤   SelectObject (hdc, hPenOld);
f715f5 ¤   DeleteObject (hPen);
1dec46 ¤   DeleteObject (hBrushLit);
ef183c ¤   DeleteObject (hBrushUnlit);
1eaf5a
2e00b1 ¤   EndPaint (hwnd, &ps);
8aefe6 }
5daf5a
e5c426 //¤ ______________________________________________________
bc465d //
b20a78 // ·Server progress dialog procedure (used for disable and delete)
aaaf5a
2479b3 static UINT CALLBACK·
90bcb8 sServerProgressDlgProc (
194cfa ¤   ¤   ·HWND¤  hDlg,·
778347 ¤   ¤   ·UINT¤  uMsg,·
e19c37 ¤   ¤   ·WPARAM wParam,
fb6465 ¤   ¤   ·LPARAM lParam)·
85bb36 {
5daf5a
77347f ¤   switch (uMsg) {
7baf5a
ab2940 ¤   case WM_INITDIALOG:
115b34 ¤   ¤   {
df9639 ¤   ¤   ¤   PSERVERTHREADSTRUCT psts = (PSERVERTHREADSTRUCT)lParam;
29c703 ¤   ¤   ¤   DWORD¤  ¤   ¤   ¤   dwThreadID;
b6af5a
bf20eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
24af5a
--83eb 000d92797e54011029a Page 9 of CLserver.c
27db23 ¤   ¤   ¤   psts->hwnd = hDlg;
2f81a8 ¤   ¤   ¤   CreateThread (NULL, 0, psts->lpThread,·
5c7821 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (void*)psts, 0, &dwThreadID);
0a32bd ¤   ¤   ¤   return TRUE;
240fe4 ¤   ¤   }
e4af5a
d385ca ¤   case WM_PAINT :
a25b34 ¤   ¤   {
b5a263 ¤   ¤   ¤   PSERVERTHREADSTRUCT psts =·
ca1b0c ¤   ¤   ¤   ¤   (PSERVERTHREADSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
b1f72a ¤   ¤   ¤   sDrawStatus (GetDlgItem (hDlg, IDC_PROGRESS), psts);
26cdcb ¤   ¤   ¤   break;
7c0fe4 ¤   ¤   }
f2af5a
3a5122 ¤   case WM_TIMER :
c85b34 ¤   ¤   {
a5a263 ¤   ¤   ¤   PSERVERTHREADSTRUCT psts =·
fd1b0c ¤   ¤   ¤   ¤   (PSERVERTHREADSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
d2cab3 ¤   ¤   ¤   psts->iStatusValue += psts->iStatusDirection;
8b4c8d ¤   ¤   ¤   if (psts->iStatusValue <= 0) {
cdff7f ¤   ¤   ¤   ¤   psts->iStatusValue = 0;
c16986 ¤   ¤   ¤   ¤   psts->iStatusDirection = 1;
d8a3a6 ¤   ¤   ¤   }
291b9e ¤   ¤   ¤   else if (psts->iStatusValue >= NUMLEDS-1) {
43e5d6 ¤   ¤   ¤   ¤   psts->iStatusValue = NUMLEDS-1;
c8c698 ¤   ¤   ¤   ¤   psts->iStatusDirection = -1;
36a3a6 ¤   ¤   ¤   }
ecf217 ¤   ¤   ¤   InvalidateRect (hDlg, NULL, FALSE);
f4cdcb ¤   ¤   ¤   break;
060fe4 ¤   ¤   }
82af5a
201431 ¤   case WM_NOTIFY :
285b34 ¤   ¤   {
e55808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
c1a263 ¤   ¤   ¤   PSERVERTHREADSTRUCT psts =·
a71b0c ¤   ¤   ¤   ¤   (PSERVERTHREADSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
69af5a
66a0d8 ¤   ¤   ¤   if (pnmh->hwndFrom != hDlg) break;
1baf5a
5ce55c ¤   ¤   ¤   switch (pnmh->code) {
90af5a
314dcf ¤   ¤   ¤   ¤   case PGPCL_SERVERPROGRESS :
1172c3 ¤   ¤   ¤   ¤   {
2d748a ¤   ¤   ¤   ¤   ¤   PPGPclSERVEREVENT pEvent = (PPGPclSERVEREVENT)lParam;
fd55e7 ¤   ¤   ¤   ¤   ¤   if (!(psts->bSearchInProgress)) {
86e737 ¤   ¤   ¤   ¤   ¤   ¤   psts->bSearchInProgress = TRUE;
c56f49 ¤   ¤   ¤   ¤   ¤   ¤   psts->iStatusValue = 0;
8b3099 ¤   ¤   ¤   ¤   ¤   ¤   if (pEvent->step == PGPCL_SERVERINFINITE) {
90b23b ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->iStatusDirection = 1;
1061f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTimer (hDlg, LEDTIMER, LEDTIMERPERIOD, NULL);
a2db3c ¤   ¤   ¤   ¤   ¤   ¤   }
db2863 ¤   ¤   ¤   ¤   ¤   ¤   else {
81e8e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->iStatusDirection = 0;
caf908 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->iStatusValue = 0;
c1db3c ¤   ¤   ¤   ¤   ¤   ¤   }
8a1c89 ¤   ¤   ¤   ¤   ¤   }
4b3c4b ¤   ¤   ¤   ¤   ¤   else {
02ff1f ¤   ¤   ¤   ¤   ¤   ¤   if (pEvent->step != PGPCL_SERVERINFINITE) {
78e8e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->iStatusDirection = 0;
47cbc3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->iStatusValue = (pEvent->step * 9) /
1613d8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pEvent->total;
ba7ab1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (hDlg, NULL, FALSE);
f7db3c ¤   ¤   ¤   ¤   ¤   ¤   }
8a1c89 ¤   ¤   ¤   ¤   ¤   }
79a6b2 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PROGRESSTEXT,·
e43ddf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pEvent->szmessage);
0ce143 ¤   ¤   ¤   ¤   ¤   return FALSE;
6a2613 ¤   ¤   ¤   ¤   }
eaaf5a
8ab0dc ¤   ¤   ¤   ¤   case PGPCL_SERVERDONE :·
796bb7 ¤   ¤   ¤   ¤   case PGPCL_SERVERABORT :
d93c61 ¤   ¤   ¤   ¤   case PGPCL_SERVERERROR :
--86e3 0003965d04f4011029a Page 10 of CLserver.c
d072c3 ¤   ¤   ¤   ¤   {
c5aacd ¤   ¤   ¤   ¤   ¤   PPGPclSERVEREVENT¤  pEvent = (PPGPclSERVEREVENT)lParam;
490a39 ¤   ¤   ¤   ¤   ¤   PGPError¤   ¤   ¤   err;
d9af5a
cfeb20 ¤   ¤   ¤   ¤   ¤   KillTimer (hDlg, LEDTIMER);
163646 ¤   ¤   ¤   ¤   ¤   psts->keysetOut = (PGPKeySetRef)(pEvent->pData);
61bac4 ¤   ¤   ¤   ¤   ¤   err = psts->err;
40af5a
a837b0 ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, err);
f6e143 ¤   ¤   ¤   ¤   ¤   return FALSE;
292613 ¤   ¤   ¤   ¤   }
52a3a6 ¤   ¤   ¤   }
9ccdcb ¤   ¤   ¤   break;
fc0fe4 ¤   ¤   }
73af5a
14af5a
edd1d3 ¤   case WM_COMMAND :
9a379d ¤   ¤   switch(LOWORD (wParam)) {
33b6bb ¤   ¤   case IDCANCEL :
93f776 ¤   ¤   ¤   {
5b2a05 ¤   ¤   ¤   ¤   PSERVERTHREADSTRUCT psts =·
9b86d6 ¤   ¤   ¤   ¤   ¤   (PSERVERTHREADSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
0ff370 ¤   ¤   ¤   ¤   KillTimer (hDlg, LEDTIMER);
f30f89 ¤   ¤   ¤   ¤   psts->bThreadFree = TRUE;
928ff3 ¤   ¤   ¤   ¤   psts->bCancel = TRUE;
afab36 ¤   ¤   ¤   ¤   if (psts->server) {
cf4333 ¤   ¤   ¤   ¤   ¤   PGPError err;
6faf5a
863c08 ¤   ¤   ¤   ¤   ¤   err = PGPCancelKeyServerCall (psts->server);
a4b002 ¤   ¤   ¤   ¤   ¤   PGPclErrorBox (hDlg, err);
3d2613 ¤   ¤   ¤   ¤   }
ae139d ¤   ¤   ¤   ¤   EndDialog (hDlg, kPGPError_UserAbort);
6ef622 ¤   ¤   ¤   ¤   break;
59a3a6 ¤   ¤   ¤   }
4baf5a
950fe4 ¤   ¤   }
89836c ¤   ¤   return TRUE;
4f9371 ¤   }
b4af5a
cba230 ¤   return FALSE;
baefe6 }
60af5a
24af5a
ed4265 //¤ ___________________________________________________
40465d //
de541a //¤ update all groups from keyserver
09af5a
a89d43 PGPError PGPclExport·
883fa9 PGPclGetGroupsFromRootServer (
1b9feb ¤   ¤   PGPContextRef¤  ¤   ¤   context,
6ad913 ¤   ¤   PGPtlsContextRef¤   ¤   tlsContext,
258d32 ¤   ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,·
f90556 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
996495 ¤   ¤   PGPGroupSetRef*¤¤   ¤   pgroupsetDownloaded)
40bb36 {
6237df ¤   PGPError¤   ¤   ¤   err¤¤   = kPGPError_NoErr;
10af5a
b6acaa ¤   PSERVERTHREADSTRUCT psts;
35af5a
e5accb ¤   psts = (PSERVERTHREADSTRUCT)malloc (sizeof(SERVERTHREADSTRUCT));
f84772 ¤   memset(psts,0x00,sizeof(SERVERTHREADSTRUCT));
c1af5a
c73593 ¤   if (psts) {
fd89bc ¤   ¤   psts->uOperation¤   ¤   = GETGROUPS;
6bfe01 ¤   ¤   psts->context¤  ¤   ¤   = context;
ca3b90 ¤   ¤   psts->tlsContext¤   ¤   = tlsContext;
aa2d75 ¤   ¤   psts->keysetMain¤   ¤   = keysetMain;
5d09ab ¤   ¤   psts->hwnd¤ ¤   ¤   ¤   = hwndParent;
822d07 ¤   ¤   psts->lpThread¤ ¤   ¤   = sKeyserverThreadRoutine;
ce0eff ¤   ¤   psts->bSearchInProgress¤= FALSE;
24c907 ¤   ¤   psts->bCancel¤  ¤   ¤   = FALSE;
390dee ¤   ¤   psts->bThreadFree¤  ¤   = FALSE;
--d57b 000eefb37fc4011029a Page 11 of CLserver.c
14493a ¤   ¤   psts->iStatusValue¤ ¤   = -1;
8f1872 ¤   ¤   psts->iStatusDirection¤ = 1;
1df4bd ¤   ¤   psts->space¤¤   ¤   ¤   = kPGPKeyServerKeySpace_Default;
fe6b9d ¤   ¤   psts->groupset¤ ¤   ¤   = kInvalidPGPGroupSetRef;
d3af5a
e6c91b ¤   ¤   ZeroMemory (&psts->ksentry, sizeof(PGPKeyServerEntry));
adaf5a
f568b5 ¤   ¤   err = DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_SERVERPROGRESS),
7bb297 ¤   ¤   ¤   ¤   ¤   ¤   hwndParent, sServerProgressDlgProc, (LPARAM)psts);
43af5a
9f8536 ¤   ¤   if (IsntPGPError (err)) {
a56d42 ¤   ¤   ¤   if (pgroupsetDownloaded)
6a3cb1 ¤   ¤   ¤   ¤   *pgroupsetDownloaded = psts->groupset;
460fe4 ¤   ¤   }
aeaf5a
a1300d ¤   ¤   if (!psts->bThreadFree) {
8c3102 ¤   ¤   ¤   free (psts);
040fe4 ¤   ¤   }
c39371 ¤   }
3eaf5a
115ea8 ¤   return err;
1aefe6 }
4caf5a
96af5a
6b4265 //¤ ___________________________________________________
42465d //
426518 //¤ send all groups to keyserver
daaf5a
869d43 PGPError PGPclExport·
4de875 PGPclSendGroupsToRootServer (
db9feb ¤   ¤   PGPContextRef¤  ¤   ¤   context,
dfd913 ¤   ¤   PGPtlsContextRef¤   ¤   tlsContext,
568d32 ¤   ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,·
8e0556 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
96adf9 ¤   ¤   PGPGroupSetRef¤ ¤   ¤   groupsetToSend)
cfbb36 {
5f37df ¤   PGPError¤   ¤   ¤   err¤¤   = kPGPError_NoErr;
5eaf5a
b6acaa ¤   PSERVERTHREADSTRUCT psts;
a9af5a
dbaccb ¤   psts = (PSERVERTHREADSTRUCT)malloc (sizeof(SERVERTHREADSTRUCT));
be4772 ¤   memset(psts,0x00,sizeof(SERVERTHREADSTRUCT));
1caf5a
703593 ¤   if (psts) {
9da6e5 ¤   ¤   psts->uOperation¤   ¤   = SENDGROUPS;
f5fe01 ¤   ¤   psts->context¤  ¤   ¤   = context;
3d3b90 ¤   ¤   psts->tlsContext¤   ¤   = tlsContext;
432d75 ¤   ¤   psts->keysetMain¤   ¤   = keysetMain;
9709ab ¤   ¤   psts->hwnd¤ ¤   ¤   ¤   = hwndParent;
cb2d07 ¤   ¤   psts->lpThread¤ ¤   ¤   = sKeyserverThreadRoutine;
a30eff ¤   ¤   psts->bSearchInProgress¤= FALSE;
16c907 ¤   ¤   psts->bCancel¤  ¤   ¤   = FALSE;
740dee ¤   ¤   psts->bThreadFree¤  ¤   = FALSE;
36493a ¤   ¤   psts->iStatusValue¤ ¤   = -1;
791872 ¤   ¤   psts->iStatusDirection¤ = 1;
89f4bd ¤   ¤   psts->space¤¤   ¤   ¤   = kPGPKeyServerKeySpace_Default;
c4a71f ¤   ¤   psts->groupset¤ ¤   ¤   = groupsetToSend;
29af5a
3cc91b ¤   ¤   ZeroMemory (&psts->ksentry, sizeof(PGPKeyServerEntry));
d4af5a
7468b5 ¤   ¤   err = DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_SERVERPROGRESS),
6fb297 ¤   ¤   ¤   ¤   ¤   ¤   hwndParent, sServerProgressDlgProc, (LPARAM)psts);
68af5a
31300d ¤   ¤   if (!psts->bThreadFree) {
083102 ¤   ¤   ¤   free (psts);
0e0fe4 ¤   ¤   }
479371 ¤   }
86af5a
055ea8 ¤   return err;
59efe6 }
f5af5a
eeaf5a
--e5f7 000e5c4efec4011029a Page 12 of CLserver.c
384265 //¤ ___________________________________________________
d3465d //
e1588b //¤ send keyset to keyserver
b8af5a
d39d43 PGPError PGPclExport·
aeccc1 PGPclSendKeysToRootServerNotify (
219cd4 ¤   ¤   PGPContextRef¤  ¤   context,
55a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
ebc86a ¤   ¤   HWND¤   ¤   ¤   ¤   hwndToNotify,·
b1809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
60becb ¤   ¤   PGPKeySetRef¤   ¤   keysetToSend)
b9bb36 {
50acaa ¤   PSERVERTHREADSTRUCT psts;
258a30 ¤   DWORD¤  ¤   ¤   ¤   dwThreadID;
5faf5a
71accb ¤   psts = (PSERVERTHREADSTRUCT)malloc (sizeof(SERVERTHREADSTRUCT));
364772 ¤   memset(psts,0x00,sizeof(SERVERTHREADSTRUCT));
c1af5a
563593 ¤   if (psts) {
bbe0c4 ¤   ¤   PGPNewKeySet (context, &(psts->keysetIn));
f8c54e ¤   ¤   PGPAddKeys (keysetToSend, psts->keysetIn);
584cd1 ¤   ¤   PGPCommitKeyRingChanges (psts->keysetIn);
08af5a
e1c843 ¤   ¤   psts->uOperation¤   ¤   = SENDKEY;
87fe01 ¤   ¤   psts->context¤  ¤   ¤   = context;
853b90 ¤   ¤   psts->tlsContext¤   ¤   = tlsContext;
7e2d75 ¤   ¤   psts->keysetMain¤   ¤   = keysetMain;
f4ed9d ¤   ¤   psts->hwnd¤ ¤   ¤   ¤   = hwndToNotify;
5dba04 ¤   ¤   psts->lpThread¤ ¤   ¤   = NULL;
a70eff ¤   ¤   psts->bSearchInProgress¤= FALSE;
a3c907 ¤   ¤   psts->bCancel¤  ¤   ¤   = FALSE;
8046ed ¤   ¤   psts->bThreadFree¤  ¤   = TRUE;
b0493a ¤   ¤   psts->iStatusValue¤ ¤   = -1;
211872 ¤   ¤   psts->iStatusDirection¤ = 1;
002c24 ¤   ¤   psts->space¤¤   ¤   ¤   = kPGPKeyServerKeySpace_Default,
3d6b9d ¤   ¤   psts->groupset¤ ¤   ¤   = kInvalidPGPGroupSetRef;
a1af5a
82c91b ¤   ¤   ZeroMemory (&psts->ksentry, sizeof(PGPKeyServerEntry));
01af5a
e51c17 ¤   ¤   CreateThread (NULL, 0, sKeyserverThreadRoutine,·
f1331b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (void*)psts, 0, &dwThreadID);
c69371 ¤   }
aaaf5a
d0151e ¤   return kPGPError_NoErr;
51efe6 }
acaf5a
80af5a
414265 //¤ ___________________________________________________
62465d //
8b3bdb //¤ disable keyset on keyserver
36af5a
d79d43 PGPError PGPclExport·
c09b82 PGPclDisableKeysOnServer (
289feb ¤   ¤   PGPContextRef¤  ¤   ¤   context,
efd913 ¤   ¤   PGPtlsContextRef¤   ¤   tlsContext,
788d32 ¤   ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,·
8bae08 ¤   ¤   PGPKeyServerEntry*¤ ¤   pkeyserver,
8b9482 ¤   ¤   PGPKeyServerKeySpace¤   space,
a00556 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
dd6904 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetToSend)
457142 {·
8a45c1 ¤   PSERVERTHREADSTRUCT¤psts;
978f52 ¤   PGPError¤   ¤   ¤   err;
05af5a
17af5a
82accb ¤   psts = (PSERVERTHREADSTRUCT)malloc (sizeof(SERVERTHREADSTRUCT));
9aaf5a
d63593 ¤   if (psts) {
ebe0c4 ¤   ¤   PGPNewKeySet (context, &(psts->keysetIn));
bec54e ¤   ¤   PGPAddKeys (keysetToSend, psts->keysetIn);
504cd1 ¤   ¤   PGPCommitKeyRingChanges (psts->keysetIn);
e567c5 ¤
--c8df 000da7b174b4011029a Page 13 of CLserver.c
db0071 ¤   ¤   psts->uOperation¤   ¤   = DISABLEKEY;
19fe01 ¤   ¤   psts->context¤  ¤   ¤   = context;
d63b90 ¤   ¤   psts->tlsContext¤   ¤   = tlsContext;
7e2d75 ¤   ¤   psts->keysetMain¤   ¤   = keysetMain;
d42d07 ¤   ¤   psts->lpThread¤ ¤   ¤   = sKeyserverThreadRoutine;
900eff ¤   ¤   psts->bSearchInProgress¤= FALSE;
c8c907 ¤   ¤   psts->bCancel¤  ¤   ¤   = FALSE;
7d0dee ¤   ¤   psts->bThreadFree¤  ¤   = FALSE;
c5493a ¤   ¤   psts->iStatusValue¤ ¤   = -1;
fc1872 ¤   ¤   psts->iStatusDirection¤ = 1;
4e0832 ¤   ¤   psts->space¤¤   ¤   ¤   = space;
3b6b9d ¤   ¤   psts->groupset¤ ¤   ¤   = kInvalidPGPGroupSetRef;
31af5a
9ed7bb ¤   ¤   CopyMemory (&psts->ksentry, pkeyserver, sizeof(PGPKeyServerEntry));
36af5a
e568b5 ¤   ¤   err = DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_SERVERPROGRESS),
c7b297 ¤   ¤   ¤   ¤   ¤   ¤   hwndParent, sServerProgressDlgProc, (LPARAM)psts);
f3af5a
1f300d ¤   ¤   if (!psts->bThreadFree) {
d3590f ¤   ¤   ¤   if (psts->keysetIn) PGPFreeKeySet (psts->keysetIn);
4a3102 ¤   ¤   ¤   free (psts);
c60fe4 ¤   ¤   }
f99371 ¤   }
c7af5a
9b5ea8 ¤   return err;
fcefe6 }
4eaf5a
5daf5a
384265 //¤ ___________________________________________________
ff465d //
34f4f8 //¤ delete keyset from keyserver
e7af5a
4f9d43 PGPError PGPclExport·
2ce2ee PGPclDeleteKeysFromServer (
139feb ¤   ¤   PGPContextRef¤  ¤   ¤   context,
c6d913 ¤   ¤   PGPtlsContextRef¤   ¤   tlsContext,
238d32 ¤   ¤   HWND¤   ¤   ¤   ¤   ¤   hwndParent,·
01ae08 ¤   ¤   PGPKeyServerEntry*¤ ¤   pkeyserver,
7f9482 ¤   ¤   PGPKeyServerKeySpace¤   space,
de0556 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetMain,
ed6904 ¤   ¤   PGPKeySetRef¤   ¤   ¤   keysetToSend)
4fbb36 {
e145c1 ¤   PSERVERTHREADSTRUCT¤psts;
278f52 ¤   PGPError¤   ¤   ¤   err;
e5af5a
26af5a
6aaccb ¤   psts = (PSERVERTHREADSTRUCT)malloc (sizeof(SERVERTHREADSTRUCT));
96af5a
a73593 ¤   if (psts) {
b4e0c4 ¤   ¤   PGPNewKeySet (context, &(psts->keysetIn));
b3c54e ¤   ¤   PGPAddKeys (keysetToSend, psts->keysetIn);
e34cd1 ¤   ¤   PGPCommitKeyRingChanges (psts->keysetIn);
a367c5 ¤
498689 ¤   ¤   psts->uOperation¤   ¤   = DELETEKEY;
ebfe01 ¤   ¤   psts->context¤  ¤   ¤   = context;
a73b90 ¤   ¤   psts->tlsContext¤   ¤   = tlsContext;
d12d75 ¤   ¤   psts->keysetMain¤   ¤   = keysetMain;
e62d07 ¤   ¤   psts->lpThread¤ ¤   ¤   = sKeyserverThreadRoutine;
de0eff ¤   ¤   psts->bSearchInProgress¤= FALSE;
ecc907 ¤   ¤   psts->bCancel¤  ¤   ¤   = FALSE;
e20dee ¤   ¤   psts->bThreadFree¤  ¤   = FALSE;
a4493a ¤   ¤   psts->iStatusValue¤ ¤   = -1;
ee1872 ¤   ¤   psts->iStatusDirection¤ = 1;
e90832 ¤   ¤   psts->space¤¤   ¤   ¤   = space;
086b9d ¤   ¤   psts->groupset¤ ¤   ¤   = kInvalidPGPGroupSetRef;
d8af5a
6ed7bb ¤   ¤   CopyMemory (&psts->ksentry, pkeyserver, sizeof(PGPKeyServerEntry));
98af5a
f968b5 ¤   ¤   err = DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_SERVERPROGRESS),
b4b297 ¤   ¤   ¤   ¤   ¤   ¤   hwndParent, sServerProgressDlgProc, (LPARAM)psts);
e7af5a
da300d ¤   ¤   if (!psts->bThreadFree) {
--5658 00196c05b6f4011029a Page 14 of CLserver.c
7f590f ¤   ¤   ¤   if (psts->keysetIn) PGPFreeKeySet (psts->keysetIn);
af3102 ¤   ¤   ¤   free (psts);
270fe4 ¤   ¤   }
9a9371 ¤   }
daaf5a
cd5ea8 ¤   return err;
ffefe6 }
c9af5a
96af5a
--5830 0005b5949ef4011029b Page 1 of CLsplash.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
985585 ¤   CLsplash.c - display splash screen
d567c5 ¤
5daf5a
787a0e ¤   $Id: CLsplash.c,v 1.6 1998/08/11 14:43:19 pbj Exp $
58f7f7 ____________________________________________________________________________*/
02e610 #include "pgpPFLConfig.h"
caaf5a
79c917 // project header files
495fcd #include "pgpclx.h"
c9af5a
7ffc2c // system header files
0811a9 #include <process.h>
44af5a
cb5584 // constant definitions
bbfe15 #define TIMER_ID¤   ¤   4321
85f092 #define TIMER_PERIOD¤   200
f9ee41 #define MAINWINDOWDELAY¤500
d9af5a
369009 #define ADDHEIGHT¤  ¤   0
b31ee9 #define XINCREMENT¤ ¤   6
e98115 #define YINCREMENT¤ ¤   10
50af5a
4b93ed // external globals
4da009 extern HINSTANCE¤   g_hInst;
0cb645 extern HWND¤¤   ¤   g_hWndSplash;
a6af5a
915bee // typedefs
0a9f3d typedef struct _SPLASHSTRUCT {
498a97 ¤   PGPContextRef¤  context;
862dbd ¤   HBITMAP¤¤   ¤   hBitmapSplash;
f50e51 ¤   HPALETTE¤   ¤   hPaletteSplash;
82b1e8 ¤   UINT¤   ¤   ¤   uTimeOut;
f91e77 ¤   UINT¤   ¤   ¤   uTimerTime;
c242c8 ¤   UINT¤   ¤   ¤   uXsize;
0fdd1d ¤   UINT¤   ¤   ¤   uYsize;
bf6fef ¤   UINT¤   ¤   ¤   uXpos;
4e6bc4 ¤   UINT¤   ¤   ¤   uYpos;
2fec65 } SPLASHSTRUCT, *PSPLASHSTRUCT;
46af5a
b2492e // local globals
977b8d static HWND¤¤   ¤   ¤   hWndSplashParent;
158d7e static PGPMemoryMgrRef¤ MemMgr;
00af5a
9035e1 //¤ ______________________________
da465d //
f2f4c9 //¤ Splash screen dialog procedure
a9af5a
aa3f64 static BOOL CALLBACK·
0bf1f6 sSplashDlgProc (
9d3a3a ¤   ¤   HWND¤   hDlg,·
1deb77 ¤   ¤   UINT¤   uMsg,·
a417d4 ¤   ¤   WPARAM¤ wParam,·
18c0b8 ¤   ¤   LPARAM¤ lParam)·
e4bb36 {
9850c0 ¤   PSPLASHSTRUCT¤  pss;
44af5a
df347f ¤   switch (uMsg) {
c8af5a
b02940 ¤   case WM_INITDIALOG:
f25b34 ¤   ¤   {
b03eed ¤   ¤   ¤   HWND hWndControl;
d4af5a
7e20eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
45036a ¤   ¤   ¤   pss = (PSPLASHSTRUCT)lParam;
a6af5a
0ab87c ¤   ¤   ¤   g_hWndSplash = hDlg;
c2fc4b ¤   ¤   ¤   SetWindowPos (hDlg, HWND_TOP, pss->uXpos, pss->uYpos,·
5b8aaf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pss->uXsize, pss->uYsize, 0);
--8caf 000c7236a264011029b Page 2 of CLsplash.c
e0af5a
478be5 ¤   ¤   ¤   hWndControl = GetDlgItem (hDlg, IDOK);
f103f7 ¤   ¤   ¤   EnableWindow (hWndControl, FALSE);
49cd16 ¤   ¤   ¤   ShowWindow (hWndControl, SW_HIDE);
302ac9 ¤   ¤   ¤   hWndControl = GetDlgItem (hDlg, IDC_BUYNOW);
4403f7 ¤   ¤   ¤   EnableWindow (hWndControl, FALSE);
d4cd16 ¤   ¤   ¤   ShowWindow (hWndControl, SW_HIDE);
fd17f2 ¤   ¤   ¤   pss->uTimerTime = 0;
563612 ¤   ¤   ¤   SetTimer (hDlg, TIMER_ID, TIMER_PERIOD, NULL);
e50fe4 ¤   ¤   }
71836c ¤   ¤   return TRUE;
e6af5a
6993f9 ¤   case WM_PAINT:
9a5b34 ¤   ¤   {
239107 ¤   ¤   ¤   HDC¤¤   ¤   hDC, hMemDC;
a2f431 ¤   ¤   ¤   PAINTSTRUCT ps;
aa5a4e ¤   ¤   ¤   HBITMAP¤¤   hBitmapOld;
76af5a
b969b1 ¤   ¤   ¤   pss = (PSPLASHSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
9daf5a
43e2b0 ¤   ¤   ¤   hDC = BeginPaint (hDlg, &ps);
1e995d ¤   ¤   ¤   hMemDC = CreateCompatibleDC (hDC);
2f2713 ¤   ¤   ¤   if (pss->hPaletteSplash) {
542cfa ¤   ¤   ¤   ¤   SelectPalette (hDC, pss->hPaletteSplash, FALSE);
ae708d ¤   ¤   ¤   ¤   RealizePalette (hDC);
e5a3a6 ¤   ¤   ¤   }
5d7438 ¤   ¤   ¤   hBitmapOld = SelectObject (hMemDC, pss->hBitmapSplash);
9e9585 ¤   ¤   ¤   CLPaintUserInfo (MemMgr, hDlg, hMemDC, NULL);
96e408 ¤   ¤   ¤   BitBlt (hDC, 0, 0, pss->uXsize, pss->uYsize,·
2fa3b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hMemDC, 0, 0, SRCCOPY);
57e0e6 ¤   ¤   ¤   SelectObject (hMemDC, hBitmapOld);
0e9a29 ¤   ¤   ¤   DeleteDC (hMemDC);
c95dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
d10fe4 ¤   ¤   }
d898aa ¤   ¤   return FALSE;
d7af5a
de2e7d ¤   case WM_LBUTTONDOWN:
3a9c91 ¤   ¤   if (hWndSplashParent) EndDialog (hDlg, 0);
f5836c ¤   ¤   return TRUE;
59af5a
de6b08 ¤   case WM_DESTROY:
f0344f ¤   ¤   KillTimer (hDlg, TIMER_ID);
5598aa ¤   ¤   return FALSE;
ebaf5a
63e60b ¤   case WM_TIMER:
55e3f4 ¤   ¤   pss = (PSPLASHSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
c72f8c ¤   ¤   if (pss->uTimerTime < pss->uTimeOut)·
c73fd9 ¤   ¤   ¤   pss->uTimerTime += TIMER_PERIOD;
5eee26 ¤   ¤   else·
868db6 ¤   ¤   ¤   if (hWndSplashParent) EndDialog (hDlg, 0);
d4836c ¤   ¤   return TRUE;
aaaf5a
0375f9 ¤   case WM_CLOSE :
2b5438 ¤   ¤   EndDialog (hDlg, 0);
0d2f68 ¤   ¤   break;
82af5a
65d1d3 ¤   case WM_COMMAND :
ad379d ¤   ¤   switch(LOWORD (wParam)) {
8baf5a
eb4672 ¤   ¤   case IDOK:·
918db6 ¤   ¤   ¤   if (hWndSplashParent) EndDialog (hDlg, 0);
27cdcb ¤   ¤   ¤   break;
1e0fe4 ¤   ¤   }
cf836c ¤   ¤   return TRUE;
66af5a
072f72 ¤   default:
0498aa ¤   ¤   return FALSE;
81af5a
d09371 ¤   }
29efe6 }
84af5a
c735e1 //¤ ______________________________
--03e7 00034ac401e4011029b Page 3 of CLsplash.c
c1465d //
af2e43 //¤ Splash screen thread procedure
a6af5a
a9e8c0 static DWORD WINAPI·
3b211f sSplashThread (PVOID pvoid)·
41bb36 {
f733a9 ¤   SPLASHSTRUCT¤   ss;
e6707d ¤   BITMAP¤ ¤   ¤   bm;
8907aa ¤   HDC¤¤   ¤   ¤   hDC;
e8c58e ¤   INT¤¤   ¤   ¤   iNumBits, iSplashBitmap;
c0af5a
ce7f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
f689fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
0fe693 ¤   ReleaseDC (NULL, hDC);
9daf5a
9291d0 ¤   if (iNumBits <= 1) iSplashBitmap = IDB_SPLASH1;
2a4af1 ¤   else if (iNumBits <= 4) iSplashBitmap = IDB_SPLASH4;
1db04c ¤   else iSplashBitmap = IDB_SPLASH8;
02af5a
718693 ¤   ss.uTimeOut = (UINT)pvoid;
50a2aa ¤   ss.hBitmapSplash = CLLoadResourceBitmap (g_hInst,·
b2c727 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (iSplashBitmap),
89b0af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ss.hPaletteSplash);
59578e ¤   GetObject (ss.hBitmapSplash, sizeof(BITMAP), (LPSTR)&bm);
caaf5a
97d978 ¤   ss.uXsize = bm.bmWidth;
e343e8 ¤   ss.uYsize = bm.bmHeight;
3baf5a
a4e040 ¤   ss.uXpos = (GetSystemMetrics (SM_CXFULLSCREEN) - ss.uXsize) / 2;
43d79d ¤   ss.uYpos = (GetSystemMetrics (SM_CYFULLSCREEN) - ss.uYsize) / 2;
d9af5a
2e89fc ¤   DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_SPLASH),·
7020cb ¤   ¤   ¤   ¤   ¤   hWndSplashParent, sSplashDlgProc, (LPARAM)&ss);
b4af5a
2fb027 ¤   g_hWndSplash = NULL;
deb1f7 ¤   if (hWndSplashParent) {
d13fa4 ¤   ¤   EnableWindow (hWndSplashParent, TRUE);
5706ef ¤   ¤   SetForegroundWindow (hWndSplashParent);
7b9371 ¤   }
1faf5a
12e267 ¤   DeleteObject (ss.hBitmapSplash);
ec56f7 ¤   DeleteObject (ss.hPaletteSplash);
e9af5a
c0b027 ¤   g_hWndSplash = NULL;
06af5a
23151e ¤   return kPGPError_NoErr;
a1efe6 }
f0af5a
07e2b1 //¤ __________________
f2465d //
718ec2 //¤ Post Splash screen
c4af5a
789d43 PGPError PGPclExport·
04bdc8 PGPclSplash (
991e61 ¤   ¤   PGPContextRef¤  Context,
e7ac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
7e6517 ¤   ¤   UINT¤   ¤   ¤   uMS)·
1bbb36 {
da6f20 ¤   PGPTime¤¤   ¤   LastSplash¤ ¤   ¤   = 0;
e66470 ¤   PGPTime¤¤   ¤   Today;
41f0d5 ¤   DWORD¤  ¤   ¤   dwID;
f959a7 ¤   PGPPrefRef¤ ¤   PrefRef;
54ee74 ¤   struct tm *¤¤   stm;
60fb19 ¤   PGPError¤   ¤   err;
5e604a ¤   INT¤¤   ¤   ¤   iYear, iDay;
534932 ¤   time_t¤ ¤   ¤   tt;
460f53 ¤   BOOL¤   ¤   ¤   bShowSplash;
18af5a
89b701 ¤   MemMgr = PGPGetContextMemoryMgr (Context);
3227e3 ¤   PGPclOpenClientPrefs (MemMgr, &PrefRef);
0eaf5a
34b4ed ¤   Today = PGPGetTime ();
--3e0d 0015bbd85114011029b Page 4 of CLsplash.c
9f4fc0 ¤   tt = PGPGetStdTimeFromPGPTime (Today);
0d0913 ¤   stm = localtime (&tt);
e542bf ¤   iYear = stm->tm_year;
edf3b8 ¤   iDay = stm->tm_yday;
b5af5a
729520 ¤   if (PGPRefIsValid (PrefRef)) {
d4e106 ¤   ¤   err = PGPGetPrefNumber (PrefRef, kPGPPrefDateOfLastSplashScreen,·
84db6c ¤   ¤   ¤   ¤   ¤   ¤   &LastSplash);
473304 ¤   ¤   if (IsPGPError (err)) LastSplash = 0;
749371 ¤   }
e0825c ¤   tt = PGPGetStdTimeFromPGPTime (LastSplash);
5f0913 ¤   stm = localtime (&tt);
43af5a
ab7e23 ¤   bShowSplash = FALSE;
e064b0 ¤   if (uMS == 0) {
fefaf8 ¤   ¤   bShowSplash = TRUE;
649371 ¤   }
2a6143 ¤   if ((stm != NULL) &&
c20e4c ¤   ¤   ((stm->tm_year != iYear) ||·
6f6be6 ¤   ¤   ·(stm->tm_yday != iDay))) bShowSplash = TRUE;
27af5a
d087d8 ¤   if (bShowSplash)
75c7a1 ¤   {
928bcd ¤   ¤   if (g_hWndSplash) return kPGPError_Win32_AlreadyOpen;
447340 ¤   ¤   g_hWndSplash = (HWND)1;
f7af5a
144ea9 ¤   ¤   hWndSplashParent = hWndParent;
ffaf5a
baaa04 ¤   ¤   _beginthreadex (NULL, 0, sSplashThread, (PVOID)uMS, 0, &dwID);·
50af5a
3d5a66 ¤   ¤   PGPSetPrefNumber (PrefRef, kPGPPrefDateOfLastSplashScreen, Today);
4b0625 ¤   ¤   Sleep (MAINWINDOWDELAY);
bc9371 ¤   }
37af5a
b5c090 ¤   PGPclCloseClientPrefs (PrefRef, TRUE);
5daf5a
0a151e ¤   return kPGPError_NoErr;
97efe6 }
2baf5a
ffe2b1 //¤ __________________
f0465d //
ebb94a //¤ Identify splash screen parent window
a9af5a
b69d43 PGPError PGPclExport·
f2f751 PGPclSetSplashParent (HWND hWndParent)·
1cbb36 {
0577d5 ¤   if (hWndParent) {
f64ea9 ¤   ¤   hWndSplashParent = hWndParent;
22222d ¤   ¤   if (g_hWndSplash) {
978cb7 ¤   ¤   ¤   SendMessage (g_hWndSplash, WM_APP, 0, 0);
54dc00 ¤   ¤   ¤   EnableWindow (hWndParent, FALSE);
cf0fe4 ¤   ¤   }
ba9371 ¤   }
a3665a ¤   else {
ff4564 ¤   ¤   hWndSplashParent = NULL;
bd2475 ¤   ¤   if (g_hWndSplash)
6bd9af ¤   ¤   ¤   SendMessage (g_hWndSplash, WM_CLOSE, 0, 0);
f59371 ¤   }
c9af5a
2d151e ¤   return kPGPError_NoErr;
5befe6 }
--d9c5 0018f3e96434011029c Page 1 of CLsplash.rc
876c0e /////////////////////////////////////////////////////////////////////////////
93465d //
a3ae70 // Bitmap
ef465d //
59af5a
2a2ff5 #if PGP_FREEWARE
11583b IDB_SPLASH1 ············BITMAP ·DISCARDABLE ····"res\\freesplash1bit.bmp"
9f0e3b IDB_SPLASH4 ············BITMAP ·DISCARDABLE ····"res\\freesplash4bit.bmp"
533e34 IDB_SPLASH8 ············BITMAP ·DISCARDABLE ····"res\\freesplash8bit.bmp"
92db21 #else
f95bc9 #if PGP_PERSONAL_PRIVACY
82a321 IDB_SPLASH1 ············BITMAP ·DISCARDABLE ····"res\\splash1bit.bmp"
3c487e IDB_SPLASH4 ············BITMAP ·DISCARDABLE ····"res\\splash4bit.bmp"
2624bb IDB_SPLASH8 ············BITMAP ·DISCARDABLE ····"res\\splash8bit.bmp"
37db21 #else
c4b902 IDB_SPLASH1 ············BITMAP ·DISCARDABLE ····"res\\bizsplash1bit.bmp"
61f2b5 IDB_SPLASH4 ············BITMAP ·DISCARDABLE ····"res\\bizsplash4bit.bmp"
8eef0e IDB_SPLASH8 ············BITMAP ·DISCARDABLE ····"res\\bizsplash8bit.bmp"
ff7454 #endif
3e7454 #endif
44af5a
3831a1 #if CREDIT_RSA_BSAFE
1f4868 IDB_CREDITS8 ···········BITMAP ·DISCARDABLE ····"res\\rsacredits8bit.bmp"
0555d3 IDB_CREDITS4 ···········BITMAP ·DISCARDABLE ····"res\\rsacredits4bit.bmp"
ad1e64 IDB_CREDITS1 ···········BITMAP ·DISCARDABLE ····"res\\rsacredits1bit.bmp"
a7db21 #else
f212f4 IDB_CREDITS8 ···········BITMAP ·DISCARDABLE ····"res\\credits8bit.bmp"
297e31 IDB_CREDITS4 ···········BITMAP ·DISCARDABLE ····"res\\credits4bit.bmp"
65956e IDB_CREDITS1 ···········BITMAP ·DISCARDABLE ····"res\\credits1bit.bmp"
8f7454 #endif
--2111 0006fe5ba854011029d Page 1 of CLsrvprf.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
83ed18 ¤   CLsrvprf.c - does the drudge work of setting up keyservers
3367c5 ¤
4daf5a
658c0f ¤   $Id: CLsrvprf.c,v 1.8 1998/08/11 14:43:19 pbj Exp $
5ef7f7 ____________________________________________________________________________*/
ebe610 #include "pgpPFLConfig.h"
36af5a
fdc917 // project header files
3f5fcd #include "pgpclx.h"
6eaf5a
cb93ed // external globals
6d9cad extern HINSTANCE g_hInst;
04af5a
f94265 //¤ ___________________________________________________
40465d //
2fd730 //¤ handler for keyserver events that we care about (TLS events)
72af5a
ca8de9 PGPError·
a86c80 CLHandleTLSEvent (
d79cd4 ¤   ¤   PGPContextRef¤  ¤   context,
6352d4 ¤   ¤   PGPEvent*¤  ¤   ¤   pevent,
5e317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
80e561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
b4108c ¤   ¤   PGPKeyServerEntry*¤ pentry,
08f076 ¤   ¤   BOOL*¤  ¤   ¤   ¤   pbSecure)
0fbb36 {
395ebf ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
12af5a
76116d ¤   PGPtlsSessionRef¤   ¤   tls;
a7efb5 ¤   PGPKeyRef¤  ¤   ¤   ¤   keyAuth;
96a078 ¤   PGPPublicKeyAlgorithm¤  algAuth;
669fd8 ¤   PGPKeyID¤   ¤   ¤   ¤   keyidAuth;
62227c ¤   PGPKeyID¤   ¤   ¤   ¤   keyidExpected;
0330cf ¤   CHAR¤   ¤   ¤   ¤   ¤   szUserID[kPGPMaxUserIDSize +1];
1e4e1c ¤   PGPSize¤¤   ¤   ¤   ¤   size;
d0af5a
d73887 ¤   *pbSecure = FALSE;
d0af5a
44e900 ¤   if (pevent->type == kPGPEvent_KeyServerTLSEvent)
a7c7a1 ¤   {
617abe ¤   ¤   PGPEventKeyServerTLSData data = pevent->data.keyServerTLSData;
deaf5a
a82137 ¤   ¤   if (data.state == kPGPKeyServerState_TLSConnectionSecured)
49ed49 ¤   ¤   {¤
1eecd1 ¤   ¤   ¤   CHAR¤   szServer[256];
4aaf5a
f99fe6 ¤   ¤   ¤   PGPGetKeyServerURL (pentry, szServer);
40af5a
9f9bcc ¤   ¤   ¤   tls = pevent->data.keyServerTLSData.tlsSession;
ec27da ¤   ¤   ¤   err = PGPtlsGetRemoteAuthenticatedKey (tls, &keyAuth); CKERR;
fcaf5a
de2a9c ¤   ¤   ¤   err = PGPGetPrimaryUserIDNameBuffer (keyAuth,·
2f75cb ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szUserID), szUserID, &size); CKERR;
1187c7 ¤   ¤   ¤
facd47 ¤   ¤   ¤   err = PGPGetKeyIDFromKey (keyAuth, &keyidAuth); CKERR;
a8af5a
edbf7b ¤   ¤   ¤   err = PGPGetKeyNumber (keyAuth,·
872206 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyPropAlgID, &algAuth); CKERR;
07af5a
ff0a3f ¤   ¤   ¤   if (pentry->authAlg == kPGPPublicKeyAlgorithm_Invalid)
47f776 ¤   ¤   ¤   {
da2b85 ¤   ¤   ¤   ¤
5a2a50 ¤   ¤   ¤   ¤   err = PGPGetKeyIDString (&keyidAuth,·
c0cb31 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyIDString_Full,
63d569 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pentry->authKeyIDString); CKERR;
84af5a
a41482 ¤   ¤   ¤   ¤   pentry->authAlg = algAuth;
6f348d ¤   ¤   ¤   ¤   PGPclSyncKeyserverPrefs (context, pentry);
--1c94 0000e307cf54011029d Page 2 of CLsrvprf.c
e0af5a
f1a21f ¤   ¤   ¤   ¤   err = PGPclConfirmRemoteAuthentication (
3e59af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
b5a4f2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd,
61d4b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szServer,
e3a272 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyAuth,
402417 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyset,
24a0a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHNEWKEY);
c23845 ¤   ¤   ¤   ¤   if (IsntPGPError (err))·
9372c3 ¤   ¤   ¤   ¤   {
1859ae ¤   ¤   ¤   ¤   ¤   *pbSecure = TRUE; // ???
a52613 ¤   ¤   ¤   ¤   }
daa3a6 ¤   ¤   ¤   }
92d9e6 ¤   ¤   ¤   else¤   ¤   ¤   ¤
86f776 ¤   ¤   ¤   {
97ce20 ¤   ¤   ¤   ¤   err = PGPGetKeyIDFromString (
fdb3e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pentry->authKeyIDString,
31638c ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyidExpected); CKERR;
69af5a
7b5157 ¤   ¤   ¤   ¤   if (PGPCompareKeyIDs (&keyidExpected, &keyidAuth))
5672c3 ¤   ¤   ¤   ¤   {
5d84aa ¤   ¤   ¤   ¤   ¤   err = PGPclConfirmRemoteAuthentication (
7659af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
ffa4f2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd,
66d4b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szServer,
70a272 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyAuth,
682417 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyset,
744f32 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHUNEXPECTEDKEY);
a8d241 ¤   ¤   ¤   ¤   ¤   // if user approves
4868ab ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err))
a74859 ¤   ¤   ¤   ¤   ¤   {
25cb27 ¤   ¤   ¤   ¤   ¤   ¤   err = PGPGetKeyIDString (&keyidAuth,·
a1c846 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyIDString_Full,
195f2c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pentry->authKeyIDString); CKERR;
d9af5a
b45da8 ¤   ¤   ¤   ¤   ¤   ¤   pentry->authAlg = algAuth;
64b993 ¤   ¤   ¤   ¤   ¤   ¤   PGPclSyncKeyserverPrefs (context, pentry);
b1af5a
0b0b33 ¤   ¤   ¤   ¤   ¤   ¤   *pbSecure = TRUE; // ???
301c89 ¤   ¤   ¤   ¤   ¤   }
6c2613 ¤   ¤   ¤   ¤   }
77fa07 ¤   ¤   ¤   ¤   else
5f72c3 ¤   ¤   ¤   ¤   {
8284aa ¤   ¤   ¤   ¤   ¤   err = PGPclConfirmRemoteAuthentication (
6959af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   context,
64a4f2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd,
bcd4b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szServer,
62a272 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyAuth,
702417 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyset,
0c2117 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHEXPECTEDKEY);
f1d241 ¤   ¤   ¤   ¤   ¤   // if user approves
c468ab ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err))
554859 ¤   ¤   ¤   ¤   ¤   {
3026ed ¤   ¤   ¤   ¤   ¤   ¤   *pbSecure = TRUE;
381c89 ¤   ¤   ¤   ¤   ¤   }
552613 ¤   ¤   ¤   ¤   }
0fa3a6 ¤   ¤   ¤   }
ceec70 ¤   ¤   }¤  ¤
5d9371 ¤   }
f0af5a
80a1c0 done :
3daf5a
725ea8 ¤   return err;
06efe6 }
94af5a
4baf5a
134265 //¤ ___________________________________________________
9c465d //
42d730 //¤ handler for keyserver events that we care about (TLS events)
01af5a
0569c9 static PGPError·
0e77f1 sServerEventHandler (
--9168 00030f5747d4011029d Page 3 of CLsrvprf.c
1fe958 ¤   ¤   PGPContextRef¤  context,
e1d476 ¤   ¤   PGPEvent*¤  ¤   pevent,·
daa3dc ¤   ¤   PGPUserValue¤   uservalue)
2ebb36 {
46a5f2 ¤   PCLIENTSERVERSTRUCT¤pcss¤   = (PCLIENTSERVERSTRUCT)uservalue;
2337df ¤   PGPError¤   ¤   ¤   err¤¤   = kPGPError_NoErr;
ca5b5b ¤   BOOL¤   ¤   ¤   ¤   bSecure;
80af5a
4c9570 ¤   switch (pevent->type) {
ce3318 ¤   case kPGPEvent_KeyServerTLSEvent:
f86ad8 ¤   ¤   err = CLHandleTLSEvent (context, pevent, pcss->hwnd,·
0c2f1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   pcss->keysetMain, pcss->pentry, &bSecure);
9a2f68 ¤   ¤   break;
c79371 ¤   }
d5af5a
955ea8 ¤   return err;
aaefe6 }
40af5a
244265 //¤ ___________________________________________________
20465d //
d1b750 //¤ Init keyservers
3caf5a
91ff26 PGPError CLInitKeyServerPrefs(
e37022 ¤   ¤   PGPUInt32¤  ¤   ¤   uServer,
f51f76 ¤   ¤   PGPKeyServerEntry*¤ pkeyserver,
07f531 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,
5c9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
60809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
2fa1f9 ¤   ¤   PGPPrefRef¤ ¤   ¤   clientPrefsRef,
f7a86d ¤   ¤   CHAR*¤  ¤   ¤   ¤   pszUserID,
0bdcc4 ¤   ¤   PCLIENTSERVERSTRUCT¤*ppcss,
f74d4e ¤   ¤   PGPKeyServerEntry¤  **ksEntries,
6a018f ¤   ¤   PGPKeyServerSpec¤   **serverList,
9220f3 ¤   ¤   PGPUInt32*¤ ¤   ¤   numKSEntries)
f3bb36 {
663384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
331195 ¤   CHAR¤   ¤   ¤   ¤   ¤   szDomain[kMaxServerNameLength+1];
de1bc5 ¤   PGPKeyServerEntry¤  ¤   entryRoot;
1caf5a
ffd041 ¤   PGPValidatePtr (keysetMain);
967cc6 ¤   PGPValidatePtr (context);
d863a2 ¤   PGPValidatePtr (pszUserID);
c1af5a
b474d7 ¤   switch (uServer)·
48c7a1 ¤   {
f3d01c ¤   ¤   case PGPCL_SPECIFIEDSERVER :
965b34 ¤   ¤   {
4822b5 ¤   ¤   ¤   (*ksEntries) =·
c78445 ¤   ¤   ¤   ¤   (PGPKeyServerEntry *)pgpAlloc(sizeof(PGPKeyServerEntry));
445a5f ¤   ¤   ¤   memcpy (*ksEntries, pkeyserver, sizeof(PGPKeyServerEntry));
be921e ¤   ¤   ¤   (*numKSEntries) = 1;
36cdcb ¤   ¤   ¤   break;
d20fe4 ¤   ¤   }
44af5a
c3d89c ¤   ¤   case PGPCL_USERIDBASEDSERVER :
5b5b34 ¤   ¤   {
cafbb2 ¤   ¤   ¤   szDomain[0] = '\0';
1bdf7d ¤   ¤   ¤   if (pszUserID)·
f2a639 ¤   ¤   ¤   ¤   PGPFindEmailDomain (pszUserID, szDomain);
0a4542 ¤   ¤   ¤   err = PGPCreateKeyServerPath (clientPrefsRef, szDomain,
20b496 ¤   ¤   ¤   ¤   ksEntries, &(*numKSEntries));
1f0fe4 ¤   ¤   }
862f68 ¤   ¤   break;
4daf5a
f6016d ¤   ¤   case PGPCL_DEFAULTSERVER :
1f5b34 ¤   ¤   {
704523 ¤   ¤   ¤   err = PGPCreateKeyServerPath (clientPrefsRef, "",
f9b496 ¤   ¤   ¤   ¤   ksEntries, &(*numKSEntries));
35cdcb ¤   ¤   ¤   break;
900fe4 ¤   ¤   }
eeaf5a
30d3c2 ¤   ¤   case PGPCL_ROOTSERVER :·
--9c22 0009003f4304011029d Page 4 of CLsrvprf.c
e35b34 ¤   ¤   {
76414d ¤   ¤   ¤   err = PGPGetRootKeyServer (clientPrefsRef, &entryRoot);·
32af5a
1a6d33 ¤   ¤   ¤   if( err == kPGPError_ItemNotFound )
fff776 ¤   ¤   ¤   {
2e14ff ¤   ¤   ¤   ¤   PGPclMessageBox (hwndParent, IDS_CAPTION, IDS_NOROOTSERVER,
dcdd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
5b398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
a2a3a6 ¤   ¤   ¤   }
9722b5 ¤   ¤   ¤   (*ksEntries) =·
708445 ¤   ¤   ¤   ¤   (PGPKeyServerEntry *)pgpAlloc(sizeof(PGPKeyServerEntry));
4635ae ¤   ¤   ¤   memcpy (*ksEntries, &entryRoot, sizeof(PGPKeyServerEntry));
a6921e ¤   ¤   ¤   (*numKSEntries) = 1;
97cdcb ¤   ¤   ¤   break;
4a0fe4 ¤   ¤   }
3e9371 ¤   }
ffaf5a
b65a6d ¤   if ((IsntPGPError (err)) &&·
81e6c8 ¤   ¤   (IsntNull (*ksEntries)) &&·
1a2e8a ¤   ¤   ((*numKSEntries) > 0))
a9c7a1 ¤   {
62499e ¤   ¤   *ppcss = clAlloc ((*numKSEntries) * sizeof(CLIENTSERVERSTRUCT));
24af5a
610690 ¤   ¤   if (*ppcss!=0)
a55b34 ¤   ¤   {
2d0bbe ¤   ¤   ¤   *serverList = (PGPKeyServerSpec*)PGPNewData(
beae6c ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (context),
fb1c4c ¤   ¤   ¤   ¤   (*numKSEntries) * sizeof(PGPKeyServerSpec),
8abff7 ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
e0af5a
a2ab60 ¤   ¤   ¤   if (IsntNull (*serverList))
03f776 ¤   ¤   ¤   {
115e8c ¤   ¤   ¤   ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   ¤   iIndex;
3809f3 ¤   ¤   ¤   ¤   PGPKeyServerThreadStorageRef¤   previousStorage;
76af5a
a686c2 ¤   ¤   ¤   ¤   PGPKeyServerInit();
28af5a
04546a ¤   ¤   ¤   ¤   PGPKeyServerCreateThreadStorage(&previousStorage);
b3af5a
27cecd ¤   ¤   ¤   ¤   for (iIndex = 0; iIndex < (*numKSEntries); iIndex++)
bb72c3 ¤   ¤   ¤   ¤   {
04b359 ¤   ¤   ¤   ¤   ¤   err = PGPNewKeyServerFromHostName (context,
fd1688 ¤   ¤   ¤   ¤   ¤   ¤   (*ksEntries)[iIndex].serverDNS,
dd3fef ¤   ¤   ¤   ¤   ¤   ¤   (*ksEntries)[iIndex].serverPort,
39d58a ¤   ¤   ¤   ¤   ¤   ¤   (*ksEntries)[iIndex].protocol,
09ddcd ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyServerAccessType_Normal,
6f09e9 ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyServerKeySpace_Normal,
31c58d ¤   ¤   ¤   ¤   ¤   ¤   &(*serverList)[iIndex].server);
a5af5a
1eb35a ¤   ¤   ¤   ¤   ¤   if (IsPGPError (err))
3e00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
b4af5a
a2efac ¤   ¤   ¤   ¤   ¤   (*serverList)[iIndex].serverName =·
82ce11 ¤   ¤   ¤   ¤   ¤   ¤   (*ksEntries)[iIndex].serverDNS;
66af5a
54bcaf ¤   ¤   ¤   ¤   ¤   (*ppcss)[iIndex].hwnd¤  ¤   = hwndParent;
fe66f1 ¤   ¤   ¤   ¤   ¤   (*ppcss)[iIndex].keysetMain¤= keysetMain;
ae0579 ¤   ¤   ¤   ¤   ¤   (*ppcss)[iIndex].pentry¤¤   = &(*ksEntries)[iIndex];
02af5a
838b50 ¤   ¤   ¤   ¤   ¤   err = PGPSetKeyServerEventHandler (
b5ffc9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (*serverList)[iIndex].server,·
fb3a49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sServerEventHandler,·
2eb735 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUserValue)&(*ppcss)[iIndex]);
9a2613 ¤   ¤   ¤   ¤   }
a5af5a
ee837e ¤   ¤   ¤   ¤   PGPKeyServerDisposeThreadStorage(previousStorage);
8aa3a6 ¤   ¤   ¤   }
5d0fe4 ¤   ¤   }
fa9371 ¤   }
1eaf5a
8f5ea8 ¤   return err;
90efe6 }
--6c2d 00169db42c44011029d Page 5 of CLsrvprf.c
e0af5a
cc4265 //¤ ___________________________________________________
7d465d //
47e2d2 //¤ Uninit keyservers
b0af5a
2cc1d1 PGPError CLUninitKeyServerPrefs(
267022 ¤   ¤   PGPUInt32¤  ¤   ¤   uServer,
226767 ¤   ¤   PCLIENTSERVERSTRUCT¤pcss,
05cbcf ¤   ¤   PGPKeyServerEntry¤  *ksEntries,
7e36ad ¤   ¤   PGPKeyServerSpec¤   *serverList,
59927e ¤   ¤   PGPUInt32¤  ¤   ¤   numKSEntries)
cebb36 {
138531 ¤   PGPUInt32¤  ¤   ¤   ¤   ¤   ¤   iIndex;
f4dc13 ¤   PGPError¤   ¤   ¤   ¤   ¤   ¤   err;
179a5c ¤   PGPKeyServerThreadStorageRef¤   previousStorage;
fbaf5a
714ead ¤   err=kPGPError_NoErr;
e6af5a
03de4f ¤   PGPKeyServerCreateThreadStorage(&previousStorage);
09af5a
730a0a ¤   for (iIndex = 0; iIndex < numKSEntries; iIndex++)
34c7a1 ¤   {
0a0578 ¤   ¤   if (PGPKeyServerRefIsValid (serverList[iIndex].server))
7ccc07 ¤   ¤   ¤   PGPFreeKeyServer (serverList[iIndex].server);
899371 ¤   }
6067c5 ¤
d45a03 ¤   if (IsntNull (serverList))
ed6a3c ¤   ¤   PGPFreeData (serverList);
faaf5a
2e348d ¤   if (IsntNull (ksEntries))
9f1729 ¤   ¤   PGPDisposeKeyServerPath (ksEntries);
bdaf5a
87803c ¤   if (IsntNull (pcss))
ee8490 ¤   ¤   clFree(pcss);
5aaf5a
9e095b ¤   PGPKeyServerDisposeThreadStorage(previousStorage);
25af5a
9b7c07 ¤   PGPKeyServerCleanup ();
c7af5a
4e5ea8 ¤   return err;
ddefe6 }
69af5a
--a158 0009418e2014011029e Page 1 of CLwarn.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
e51b52 ¤   ¤
c6af5a
9f1616 ¤   $Id: CLwarn.c,v 1.2 1998/08/11 14:43:20 pbj Exp $
0cf7f7 ____________________________________________________________________________*/
b1af5a
d7e610 #include "pgpPFLConfig.h"
e93d0b #include <windowsx.h>
71af5a
f4c917 // project header files
7a5fcd #include "pgpclx.h"
d5af5a
d993ed // external globals
489cad extern HINSTANCE g_hInst;
b3af5a
b21741 typedef struct
c5bb36 {
caee49 int WarnHelpID; ·
19e700 PGPBoolean *pWarnCheck;
0ca82a char *szWarnMessage;
2d47c0 char *szWarnCaption;
e53211 } WARNGBL, *PWARNGBL;
34af5a
fead6c #define IDH_RSADSARECWARNING ··············3009
aeaf5a
6538e5 /*
c09d4c ·* WarnProc.c ·Main message loop for the warning dialog
af775e ·*
4df461 ·* This message loop handles all the operations of the warning
e13cd4 ·* dialog. Its a bit trickey, since it includes some routines to tack
5d5c89 ·* on our "global" variables to the USERDATA portion of the window
c97d72 ·* (for reentrancy)
c3775e ·*
d5495d ·*/
66af5a
def227 PWARNGBL AllocWarnGbl(void)
44bb36 {
f3e4be ····PWARNGBL pWarnGbl;
c0af5a
aa3fcc ····pWarnGbl=(PWARNGBL)malloc(sizeof(WARNGBL));
f03094 ····memset (pWarnGbl,0x00,sizeof(WARNGBL));
9baf5a
04435f ····return pWarnGbl;
76efe6 }
c5af5a
ff8db2 BOOL WINAPI WarningDlgProc(HWND hdlg, UINT uMsg,·
c200a7 ···························WPARAM wParam, LPARAM lParam)
93bb36 {
04af5a
cf827b ····switch(uMsg)
5c3b37 ····{
ba2aad ········case WM_INITDIALOG:
e82b60 ········{
bc275b ¤   ¤   ¤   PWARNGBL pwg;
c6af5a
8e1d4a ¤   ¤   ¤   SetWindowLong(hdlg,GWL_USERDATA,lParam);
8e24a4 ¤   ¤   ¤   pwg=(PWARNGBL)lParam;
04af5a
a899f9 ············SetWindowText(GetDlgItem(hdlg,IDC_WARNINGTEXT),
3733a0 ················pwg->szWarnMessage);
74af5a
354430 ············SetWindowText(hdlg,pwg->szWarnCaption);
83af5a
af291b ············Button_SetCheck(GetDlgItem(hdlg,IDC_WARNCHECK),
a7b1ee ················*(pwg->pWarnCheck));
0cd83c ·
c351a3 ············return TRUE;
057fb0 ········}
7caf5a
94af5a
--9d63 000d1d9840d4011029e Page 2 of CLwarn.c
6bfb31 ········case WM_DESTROY:
a62b60 ········{
e1275b ¤   ¤   ¤   PWARNGBL pwg;
11af5a
22311c ¤   ¤   ¤   pwg=(PWARNGBL)GetWindowLong(hdlg,GWL_USERDATA);
51af5a
226291 ············free(pwg);
4987c7 ¤   ¤   ¤
cb661f ············EndDialog(hdlg, FALSE);
548632 ············break;
387fb0 ········}
b8af5a
8faff6 ········case WM_COMMAND:
2e2b60 ········{
5214e1 ············switch(wParam)
de2cc2 ············{
13f804 ················case IDC_WARNCHECK:
163b8c ················{
289907 ¤   ¤   ¤   ¤   ¤   PWARNGBL pwg;
36af5a
84c86e ¤   ¤   ¤   ¤   ¤   pwg=(PWARNGBL)GetWindowLong(hdlg,GWL_USERDATA);
fbaf5a
dc9aca ····················*(pwg->pWarnCheck)=!*(pwg->pWarnCheck);
3709a2 ····················Button_SetCheck(GetDlgItem(hdlg,IDC_WARNCHECK),
988b27 ························*(pwg->pWarnCheck));
fd48e8 ····················break;
716f5c ················}
44af5a
a158d1 ················case IDOK:
c03b8c ················{
41ac68 ····················EndDialog(hdlg, TRUE);
9948e8 ····················break;
916f5c ················}
acaf5a
950981 ················case IDCANCEL:
fe3b8c ················{
187494 ····················EndDialog(hdlg, FALSE);
da48e8 ····················break;
476f5c ················}
0faf5a
1ee089 ················case IDHELP:
2f3b8c ················{
1a3148 ····················char szHelpFile[MAX_PATH],sz[MAX_PATH];
f79907 ¤   ¤   ¤   ¤   ¤   PWARNGBL pwg;
25af5a
fec86e ¤   ¤   ¤   ¤   ¤   pwg=(PWARNGBL)GetWindowLong(hdlg,GWL_USERDATA);
feaf5a
544cdc ¤   ¤   ¤   ¤   ¤   PGPclGetPGPPath (szHelpFile, sizeof(szHelpFile));
0b4bca ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_HELPFILENAME, sz, sizeof(sz));
afb041 ¤   ¤   ¤   ¤   ¤   lstrcat (szHelpFile, sz);
3daf5a
3caf5a
164cb7 ····················WinHelp (hdlg,szHelpFile, HELP_CONTEXT,pwg->WarnHelpID);·
c948e8 ····················break;
b26f5c ················}
2faf5a
607812 ············}
a951a3 ············return TRUE;
a47fb0 ········}
f7af5a
b76fe7 ····}
a030cb ····return FALSE;
04efe6 }
47af5a
67afaa //¤ __________________________________________________________
9c465d //
111d54 // ·Post warning about encrypting to RSA and signing w/DSA key
39af5a
0b9d43 PGPError PGPclExport·
f39d84 PGPclRSADSAMixWarning (HWND hWnd, PGPBoolean *pbNeverShowAgain)·
4fbb36 {
d145d9 ····int ReturnValue;
--4a3a 001f2e92a4c4011029e Page 3 of CLwarn.c
02e4be ····PWARNGBL pWarnGbl;
03d7d6 ·¤  CHAR szCaption [128];
ae7951 ¤   CHAR szMessage [256];
3faf5a
cee27a ¤   LoadString (g_hInst, IDS_CAPTION, szCaption, sizeof(szCaption));
63c8c0 ¤   LoadString (g_hInst, IDS_RSADSAMIXWARNING, szMessage, sizeof(szMessage));
04af5a
bc4051 ¤   pWarnGbl=AllocWarnGbl();
1caf5a
483133 ····pWarnGbl->WarnHelpID=IDH_RSADSARECWARNING;
36c701 ····pWarnGbl->pWarnCheck=pbNeverShowAgain;
b0b7e0 ····pWarnGbl->szWarnMessage=szMessage;
7716fa ¤   pWarnGbl->szWarnCaption=szCaption;
44af5a
9087b5 ····ReturnValue=DialogBoxParam(g_hInst,·
56ec49 ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE( IDD_WARNINGDLG ),
f5feff ¤   ¤   ¤   ¤   ¤   ¤   hWnd,·
f1188c ¤   ¤   ¤   ¤   ¤   ¤   (DLGPROC) WarningDlgProc,·
1140bd ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) pWarnGbl);
d2af5a
5877de ¤   if(ReturnValue)
26b840 ¤   ¤   return kPGPError_NoErr;
7baf5a
9bff42 ¤   return kPGPError_UserAbort;
a1efe6 }
e4af5a
e9af5a
707e4d /*__Editor_settings____
a9af5a
da4126 ¤   Local Variables:
907b17 ¤   tab-width: 4
720e6c ¤   End:
165f8c ¤   vi: ts=4 sw=4
f49e9b ¤   vim: si
8bd062 _____________________*/
f2af5a
--7033 000ef1f45674011029f Page 1 of KMAddUsr.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
3d14c5 ¤   KMAddUsr.c - add userID to key
6967c5 ¤
a6af5a
322c29 ¤   $Id: KMAddUsr.c,v 1.26 1998/08/12 18:31:21 pbj Exp $
fcf7f7 ____________________________________________________________________________*/
7ce610 #include "pgpPFLConfig.h"
24af5a
01c917 // project header files
d8850a #include "pgpkmx.h"
70af5a
d4ad8c // pgp header files
b876b7 #include "PGPClientPrefs.h"
56af5a
3efc2c // system header files
f06bd4 #include <commdlg.h>
77af5a
195584 // constant definitions
9c1bbe #define MAX_FULL_NAME_LEN¤  ¤   126
b8969d #define MAX_EMAIL_LEN¤  ¤   ¤   126
ceaf5a
9e5bee // typedefs
e2f0f7 typedef struct {
a4e71b ¤   PKEYMAN¤¤   pKM;
3cfa3f ¤   LPSTR¤  ¤   pszUserID;
fc2f8b ¤   PGPBoolean¤ bSyncWithServer;
5def66 } ADDNAMESTRUCT, *PADDNAMESTRUCT;
faaf5a
4ef0f7 typedef struct {
b5e71b ¤   PKEYMAN¤¤   pKM;
e740c6 ¤   WNDPROC¤¤   wpOrigPhotoIDProc;
b98dd0 ¤   HBITMAP¤¤   hbitmapPhotoID;
e0a1f9 ¤   HPALETTE¤   hpalettePhotoID;
067662 ¤   INT¤¤   ¤   iwidthPhotoID;
deb289 ¤   INT¤¤   ¤   iheightPhotoID;
aecea6 ¤   LPBYTE¤ ¤   pPhotoBuffer;
f60a1a ¤   PGPSize¤¤   iPhotoBufferLength;
a62f8b ¤   PGPBoolean¤ bSyncWithServer;
486456 } ADDPHOTOSTRUCT, *PADDPHOTOSTRUCT;
95af5a
6893ed // external globals
7e9cad extern HINSTANCE g_hInst;
42af5a
c0492e // local globals
b123ce static DWORD aNewUserIds[] = {¤ ¤   ¤   // Help IDs
7e0d28 ····IDC_NEWUSERNAME,¤   IDH_PGPKM_NEWUSERID,·
34be0a ¤   IDC_NEWEMAILADDR,¤  IDH_PGPKM_NEWEMAILADDR,
ae4434 ····0,0·
8ea6fe };·
42af5a
2c948d static DWORD aNewPhotoIds[] = {¤¤   ¤   // Help IDs
428690 ¤   IDC_PHOTOID,¤   ¤   IDH_PGPKM_NEWPHOTOID,
3ebfc0 ····IDC_SELECTFILE,¤¤   IDH_PGPKM_BROWSENEWPHOTOID,·
d44434 ····0,0·
d6a6fe };·
0baf5a
44af5a
6f4265 //¤ ___________________________________________________
a5465d //
402d24 // ·Dialog Message procedure
7415d1 //¤ When user asks to add a userID to a key, a dialog·
1b4674 //¤ appears asking for the new userID to be typed in.
a50629 //¤ This is the message processing procedure for that
bad5b2 //¤ dialog.
5caf5a
703f64 static BOOL CALLBACK·
db0d58 sAddUserDlgProc (
c23a3a ¤   ¤   HWND¤   hDlg,·
efeb77 ¤   ¤   UINT¤   uMsg,·
--df1a 0006f49c8bd4011029f Page 2 of KMAddUsr.c
e80303 ¤   ¤   WPARAM¤ wParam,
08c0b8 ¤   ¤   LPARAM¤ lParam)·
febb36 {
deaf5a
173f0b ¤   PADDNAMESTRUCT pans;
f8af5a
6a31cf ¤   switch(uMsg) {
20af5a
ac2940 ¤   case WM_INITDIALOG:
87f0d9 ¤   ¤   pans = (PADDNAMESTRUCT)lParam;
847547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
7e2897 ¤   ¤   SendDlgItemMessage (hDlg, IDC_NEWUSERNAME, EM_SETLIMITTEXT,·
4643b1 ¤   ¤   ¤   ¤   MAX_FULL_NAME_LEN, 0);
e54ec6 ¤   ¤   SendDlgItemMessage (hDlg, IDC_NEWEMAILADDR, EM_SETLIMITTEXT,·
ac03fc ¤   ¤   ¤   ¤   MAX_EMAIL_LEN, 0);
b1836c ¤   ¤   return TRUE;
dcaf5a
60c3eb ····case WM_HELP:·
a22798 ¤   ¤   pans = (PADDNAMESTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
7379a3 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pans->pKM->szHelpFile,·
bfa74c ············HELP_WM_HELP, (DWORD) (LPSTR) aNewUserIds);·
098f13 ········break;·
58d83c ·
f04fd8 ····case WM_CONTEXTMENU:·
1e3c4d ·¤  ¤   pans = (PADDNAMESTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
7443bd ¤   ¤   WinHelp ((HWND) wParam, pans->pKM->szHelpFile, HELP_CONTEXTMENU,·
6d71c1 ············(DWORD) (LPVOID) aNewUserIds);·
3e8f13 ········break;·
e1af5a
f03fcf ¤   case WM_COMMAND:
bd379d ¤   ¤   switch(LOWORD (wParam)) {
654672 ¤   ¤   case IDOK:·
663414 ¤   ¤   ¤   pans = (PADDNAMESTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
fd3c60 ¤   ¤   ¤   if (KMConstructUserID (hDlg, IDC_NEWUSERNAME, IDC_NEWEMAILADDR,·
17b807 ¤   ¤   ¤   ¤   ¤   &(pans->pszUserID))) {
d3cebd ¤   ¤   ¤   ¤   EndDialog (hDlg, 1);
26a3a6 ¤   ¤   ¤   }
2b32bd ¤   ¤   ¤   return TRUE;
15af5a
5871eb ¤   ¤   case IDCANCEL:
66ef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
c132bd ¤   ¤   ¤   return TRUE;
710fe4 ¤   ¤   }
c0836c ¤   ¤   return TRUE;
2d9371 ¤   }
01a230 ¤   return FALSE;
38efe6 }
2caf5a
374265 //¤ ___________________________________________________
20465d //
cb53a8 // ·Add User to key
091133 //¤ This routine is called when the user chooses to add
f267b3 //¤ a userID to an existing secret key.
d3af5a
267efe BOOL·
c838e5 KMAddUserToKey (PKEYMAN pKM)·
65bb36 {
ab0b8e ¤   PGPByte*¤   ¤   pPasskey¤   ¤   = NULL;
82a32a ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   = TRUE;
3afb19 ¤   PGPError¤   ¤   err;
2b1502 ¤   PGPKeyRef¤  ¤   key;
25b9e5 ¤   PGPSize¤¤   ¤   sizePasskey;
8c4b66 ¤   ADDNAMESTRUCT¤  ans;
002a4f ¤   CHAR¤   ¤   ¤   sz[256];
52ce0f ¤   PGPPrefRef¤ ¤   prefref;
acaf5a
7fcd70 ¤   // get selected key
dc0a36 ¤   key = (PGPKeyRef)KMFocusedObject (pKM);
b4af5a
00a8bb ¤   // initialize struct
452aa6 ¤   ans.pKM = pKM;
6f410a ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), &prefref);
--a052 000923b923a4011029f Page 3 of KMAddUsr.c
0659c0 ¤   PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnAdd,·
359fba ¤   ¤   ¤   ¤   ¤   ¤   &(ans.bSyncWithServer));
97ab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
39af5a
86f282 ¤   // get new userid from user
17fae8 ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_NEWUSERID),·
75f405 ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sAddUserDlgProc, (LPARAM)&ans)) {
a3af5a
435dba ¤   ¤   // get valid passphrase, if required
0e97ce ¤   ¤   LoadString (g_hInst, IDS_SELKEYPASSPHRASE, sz, sizeof(sz));·
1bf4b5 ¤   ¤   err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
2ae6e8 ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sz,
46da1c ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, key,
3bf782 ¤   ¤   ¤   ¤   ¤   ¤   NULL, &pPasskey, &sizePasskey);
5b94cd ¤   ¤   PGPclErrorBox (NULL, err);
6faf5a
d41a2d ¤   ¤   // now we have a valid passphrase, if required
e68536 ¤   ¤   if (IsntPGPError (err)) {
8aaf5a
bdda8a ¤   ¤   ¤   // update from server
66875a ¤   ¤   ¤   if (ans.bSyncWithServer) {
244a1c ¤   ¤   ¤   ¤   if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
abed00 ¤   ¤   ¤   ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
d8abcc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_QUERYCONTINUEADDING, ¤
8feba6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
0911b2 ¤   ¤   ¤   ¤   ¤   ¤   bRetVal = FALSE;
1d1c89 ¤   ¤   ¤   ¤   ¤   }
332613 ¤   ¤   ¤   ¤   }
e7a3a6 ¤   ¤   ¤   }
9a1b52 ¤   ¤
f09bd0 ¤   ¤   ¤   if (bRetVal) {
f9f44d ¤   ¤   ¤   ¤   // make sure we have enough entropy
62b2d2 ¤   ¤   ¤   ¤   PGPclRandom (pKM->Context, pKM->hWndParent, 0);
b4af5a
9f13c0 ¤   ¤   ¤   ¤   if (pPasskey) {
fc93df ¤   ¤   ¤   ¤   ¤   err = PGPAddUserID (key, ans.pszUserID,·
e87745 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (pKM->Context,·
cf3929 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey),
987e2c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
342613 ¤   ¤   ¤   ¤   }
22deaa ¤   ¤   ¤   ¤   else {
f393df ¤   ¤   ¤   ¤   ¤   err = PGPAddUserID (key, ans.pszUserID,·
687e2c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
d02613 ¤   ¤   ¤   ¤   }
79ba49 ¤   ¤   ¤   ¤   ¤   ·¤  ¤   ¤   ¤   ¤   ¤
7a3a35 ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
61aab9 ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
7b41e4 ¤   ¤   ¤   ¤   ¤   KMUpdateKeyInTree (pKM, key, FALSE);
de3ef8 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
56af5a
df9a84 ¤   ¤   ¤   ¤   ¤   // send to server
34188e ¤   ¤   ¤   ¤   ¤   if (ans.bSyncWithServer) {
a8e148 ¤   ¤   ¤   ¤   ¤   ¤   KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
5e1c89 ¤   ¤   ¤   ¤   ¤   }
022613 ¤   ¤   ¤   ¤   }
15d9bf ¤   ¤   ¤   ¤   else bRetVal = FALSE;
18a3a6 ¤   ¤   ¤   }
470fe4 ¤   ¤   }
1f01c4 ¤   ¤   else bRetVal = FALSE;
55af5a
089655 ¤   ¤   KMFree (ans.pszUserID);
069371 ¤   }
b78890 ¤   else bRetVal = FALSE;
39af5a
f3320f ¤   if (pPasskey) {
4a0297 ¤   ¤   KMFreePasskey (pPasskey, sizePasskey);
7a997e ¤   ¤   pPasskey = NULL;
c39371 ¤   }
beaf5a
6e1c35 ¤   return bRetVal;
e9efe6 }
92af5a
--86a9 000e4b25ec94011029f Page 4 of KMAddUsr.c
e0af5a
00bf56 //----------------------------------------------------|
a906a7 // ·display photo userID with appropriate overwriting
66af5a
02b333 static VOID·
2b361b sPaintPhotoID (
47757a ¤   ¤   HWND¤   ¤   hWnd,
aa8dd7 ¤   ¤   HBITMAP¤¤   hbitmapID,
eaf017 ¤   ¤   HPALETTE¤   hpaletteID,
2607a4 ¤   ¤   INT¤¤   ¤   iwidthBM,
a4dfd2 ¤   ¤   INT¤¤   ¤   iheightBM)
f4bb36 {
7f927f ¤   HPALETTE¤   ¤   hpaletteOld¤¤   = NULL;
ed8bc2 ¤   HDC¤¤   ¤   ¤   hdc;
d8d552 ¤   HDC¤¤   ¤   ¤   hdcMem;
12ad04 ¤   PAINTSTRUCT¤¤   ps;
651372 ¤   RECT¤   ¤   ¤   rc;
c0f6a7 ¤   INT¤¤   ¤   ¤   icent;
176434 ¤   INT¤¤   ¤   ¤   ileft, itop, iwidth, iheight;
feaf5a
ace514 ¤   hdc = BeginPaint (hWnd, &ps);
b1af5a
64837e ¤   if (hbitmapID) {
6c7d91 ¤   ¤   GetWindowRect (GetDlgItem (hWnd, IDC_PHOTOID), &rc);
01022b ¤   ¤   MapWindowPoints (NULL, hWnd, (LPPOINT)&rc, 2);
27af5a
fa4be1 ¤   ¤   // check if bitmap needs shrinking
3f611c ¤   ¤   if ((iheightBM > (rc.bottom-rc.top-2)) ||
b39166 ¤   ¤   ¤   (iwidthBM ·> (rc.right-rc.left-2)))·
a75b34 ¤   ¤   {
4faaa1 ¤   ¤   ¤   if (iheightBM > (iwidthBM * 1.25)) {
a9b5c4 ¤   ¤   ¤   ¤   itop = rc.top +1;
926e6b ¤   ¤   ¤   ¤   iheight = rc.bottom-rc.top -2;
adc66a ¤   ¤   ¤   ¤   icent = (rc.right+rc.left) / 2;
8dc794 ¤   ¤   ¤   ¤   iwidth = ((rc.bottom-rc.top) * iwidthBM) / iheightBM;
691815 ¤   ¤   ¤   ¤   ileft = icent -(iwidth/2);
41a3a6 ¤   ¤   ¤   }
c5e543 ¤   ¤   ¤   else {
fa6303 ¤   ¤   ¤   ¤   ileft = rc.left +1;
62f719 ¤   ¤   ¤   ¤   iwidth = rc.right-rc.left -2;
9c652a ¤   ¤   ¤   ¤   icent = (rc.bottom+rc.top) / 2;
abde60 ¤   ¤   ¤   ¤   iheight = ((rc.right-rc.left) * iheightBM) / iwidthBM;
01ade3 ¤   ¤   ¤   ¤   itop = icent - (iheight/2);
96a3a6 ¤   ¤   ¤   }
830fe4 ¤   ¤   }
43e0e5 ¤   ¤   // otherwise draw it at its real size
6907e0 ¤   ¤   else {
6520b9 ¤   ¤   ¤   iwidth = iwidthBM;
9bf1df ¤   ¤   ¤   iheight = iheightBM;
abde3a ¤   ¤   ¤   icent = (rc.right+rc.left) / 2;
bbec4a ¤   ¤   ¤   ileft = icent - (iwidth/2);
e97d7a ¤   ¤   ¤   icent = (rc.bottom+rc.top) / 2;
7a2585 ¤   ¤   ¤   itop = icent - (iheight/2);
6f0fe4 ¤   ¤   }
67af5a
f80744 ¤   ¤   hdcMem = CreateCompatibleDC (hdc);
94af5a
a8165c ¤   ¤   if (hpaletteID) {
3ec85f ¤   ¤   ¤   hpaletteOld = SelectPalette (hdc, hpaletteID, FALSE);
9d703c ¤   ¤   ¤   RealizePalette (hdc);
c30fe4 ¤   ¤   }
62af5a
6c451c ¤   ¤   SetStretchBltMode (hdc, COLORONCOLOR);
338651 ¤   ¤   SelectObject (hdcMem, hbitmapID);
f922b9 ¤   ¤   StretchBlt (hdc, ileft, itop, iwidth, iheight,
8334ec ¤   ¤   ¤   ¤   ¤   hdcMem, 0, 0, iwidthBM, iheightBM, SRCCOPY);
c7af5a
d8cc3c ¤   ¤   if (hpaletteOld) {
a569bb ¤   ¤   ¤   SelectPalette (hdc, hpaletteOld, TRUE);
91703c ¤   ¤   ¤   RealizePalette (hdc);
bc0fe4 ¤   ¤   }
e4af5a
--f53a 0008123ea984011029f Page 5 of KMAddUsr.c
21039b ¤   ¤   DeleteDC (hdcMem);
739371 ¤   }
a4af5a
66e23b ¤   EndPaint (hWnd, &ps);
10a79b }·
69af5a
55af5a
8bbf56 //----------------------------------------------------|
13e072 // ·update system palette
e7af5a
8f67fb static BOOL
d65965 sUpdatePalette (
3ee0af ¤   ¤   HWND¤   ¤   ¤   hwnd,
08610f ¤   ¤   PADDPHOTOSTRUCT¤paps)
1dbb36 {
1c51db ¤   BOOL¤   ¤   bretval¤¤   = FALSE;
3594c0 ¤   HDC¤¤   ¤   hdc;
3b4e1f ¤   HPALETTE¤   hpaletteOld;
29af5a
f59b85 ¤   if (paps->hpalettePhotoID == NULL) return FALSE;
d9af5a
be7424 ¤   hdc = GetDC (hwnd);
e0af5a
da4a78 ¤   hpaletteOld = SelectPalette (hdc, paps->hpalettePhotoID, FALSE);
eab081 ¤   if (RealizePalette (hdc)) {
cba462 ¤   ¤   InvalidateRect (hwnd, NULL, TRUE);·
9888ca ¤   ¤   bretval = TRUE;
4b9371 ¤   }
62af5a
64e7aa ¤   SelectPalette (hdc, hpaletteOld, TRUE);
d2ce60 ¤   RealizePalette (hdc);
9d108c ¤   ReleaseDC (hwnd, hdc);
8eaf5a
d9ca54 ¤   return bretval;
a8efe6 }
73af5a
bfaf5a
2ebf56 //----------------------------------------------------|
69c789 // ·PhotoID subclass procedure
c4af5a
2ad0ac static LRESULT APIENTRY·
94cb3f sPhotoIDSubclassProc (
c247b2 ¤   ¤   HWND¤   hWnd,·
7deb77 ¤   ¤   UINT¤   uMsg,·
6f17d4 ¤   ¤   WPARAM¤ wParam,·
42c0b8 ¤   ¤   LPARAM¤ lParam)·
c0bb36 {
07a711 ¤   PADDPHOTOSTRUCT paps;
b504c3 ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (GetParent (hWnd), GWL_USERDATA);
ddaf5a
5d1b44 ····switch (uMsg) {
12af5a
44651b ¤   case WM_CONTEXTMENU :
655b34 ¤   ¤   {
e85435 ¤   ¤   ¤   HMENU¤  hMC;
a54cea ¤   ¤   ¤   HMENU¤  hMenuTrackPopup;
e5af5a
7dba1f ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUNEWPHOTOID));
9ee6fb ¤   ¤   ¤   if (paps->hbitmapPhotoID)
406a62 ¤   ¤   ¤   ¤   EnableMenuItem (hMC, IDM_COPYBITMAP,·
526152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_ENABLED);
0bbb8c ¤   ¤   ¤   else
b26a62 ¤   ¤   ¤   ¤   EnableMenuItem (hMC, IDM_COPYBITMAP,·
a8e1fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_GRAYED);
77af5a
9620c2 ¤   ¤   ¤   if (IsClipboardFormatAvailable (CF_BITMAP) ||
779320 ¤   ¤   ¤   ¤   ·IsClipboardFormatAvailable (CF_HDROP))
40abee ¤   ¤   ¤   ¤   EnableMenuItem (hMC, IDM_PASTEBITMAP,·
b16152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_ENABLED);
3bbb8c ¤   ¤   ¤   else
e3abee ¤   ¤   ¤   ¤   EnableMenuItem (hMC, IDM_PASTEBITMAP,·
81e1fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_GRAYED);
--7bd4 000076aae964011029f Page 6 of KMAddUsr.c
e0af5a
3637b8 ¤   ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
38af5a
f3c72f ¤   ¤   ¤   TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
a12add ¤   ¤   ¤   ¤   LOWORD(lParam), HIWORD(lParam), 0, GetParent (hWnd), NULL);
0baf5a
7d7327 ¤   ¤   ¤   DestroyMenu (hMC);
320fe4 ¤   ¤   }
fd2f68 ¤   ¤   break;
8aaf5a
b8550b ¤   case WM_DROPFILES :
5c5b34 ¤   ¤   {
b81c0b ¤   ¤   ¤   CHAR¤   ¤   ¤   ¤   szFile[MAX_PATH];
c567e6 ¤   ¤   ¤   INT¤¤   ¤   ¤   ¤   iLen;
5351bc ¤   ¤   ¤   LPBITMAPINFO¤   ¤   lpbmi;
af8ce5 ¤   ¤   ¤   LPBYTE¤ ¤   ¤   ¤   pPhoto;
222da3 ¤   ¤   ¤   INT¤¤   ¤   ¤   ¤   isize;
8d096c ¤   ¤   ¤   PGPError¤   ¤   ¤   err;
bda5ce ¤   ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent;
99af5a
b559fd ¤   ¤   ¤   iLen = DragQueryFile ((HDROP)wParam, 0, szFile, sizeof(szFile));
d733df ¤   ¤   ¤   hwndParent = GetParent (hWnd);
b8af5a
71b4e1 ¤   ¤   ¤   err = KMReadPhotoFromFile (szFile, &pPhoto, &isize);
ec696f ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (hWnd, err))) {
0a7c76 ¤   ¤   ¤   ¤   SetActiveWindow (GetParent (hwndParent));
c8a7c4 ¤   ¤   ¤   ¤   if (paps->pPhotoBuffer)·
479758 ¤   ¤   ¤   ¤   ¤   KMFree (paps->pPhotoBuffer);
6f62ba ¤   ¤   ¤   ¤   if (paps->hbitmapPhotoID)·
437a3f ¤   ¤   ¤   ¤   ¤   DeleteObject (paps->hbitmapPhotoID);
452411 ¤   ¤   ¤   ¤   if (paps->hpalettePhotoID)·
477b8f ¤   ¤   ¤   ¤   ¤   DeleteObject (paps->hpalettePhotoID);
78af5a
8d512a ¤   ¤   ¤   ¤   paps->pPhotoBuffer = pPhoto;
f307af ¤   ¤   ¤   ¤   paps->iPhotoBufferLength = isize;
be70b2 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hwndParent, IDOK), TRUE);·
4baf5a
9df186 ¤   ¤   ¤   ¤   err = KMDIBfromPhoto (pPhoto, isize, TRUE, &lpbmi);·
71af5a
9456ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
9c7c26 ¤   ¤   ¤   ¤   ¤   KMGetDIBSize (lpbmi, &(paps->iwidthPhotoID),
04de74 ¤   ¤   ¤   ¤   ¤   ¤   ·&(paps->iheightPhotoID));
33af5a
e7aaac ¤   ¤   ¤   ¤   ¤   paps->hbitmapPhotoID = KMDDBfromDIB (lpbmi,·
547564 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(paps->hpalettePhotoID));·
f8af5a
a6548e ¤   ¤   ¤   ¤   ¤   KMFree (lpbmi);
62af5a
a65e94 ¤   ¤   ¤   ¤   ¤   InvalidateRect (hwndParent, NULL, TRUE);
f22613 ¤   ¤   ¤   ¤   }
ece5d3 ¤   ¤   ¤   }·
d1af5a
bc7f47 ¤   ¤   ¤   DragFinish ((HDROP)wParam);
780fe4 ¤   ¤   }
6f2f68 ¤   ¤   break;
a2af5a
ffbfad ¤   default :
ca0a01 ¤   ¤   return CallWindowProc (paps->wpOrigPhotoIDProc, hWnd, uMsg,·
36f126 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam, lParam);·
6e9371 ¤   }
0fc2e7 ¤   return TRUE;
2fa79b }·
1daf5a
2aaf5a
0d4265 //¤ ___________________________________________________
23465d //
695bbc // ·select BMP file·
60af5a
bfb333 static VOID·
b1e259 sSelectBitmapFile (
38e0af ¤   ¤   HWND¤   ¤   ¤   hwnd,
07610f ¤   ¤   PADDPHOTOSTRUCT¤paps)
--75df 000dd68b2f24011029f Page 7 of KMAddUsr.c
2cbb36 {
e086dc ¤   LPBYTE¤ ¤   ¤   pPhoto;
33ad23 ¤   INT¤¤   ¤   ¤   isize;
0063e2 ¤   CHAR¤   ¤   ¤   szFile[MAX_PATH];
ee6a6e ¤   CHAR¤   ¤   ¤   szTitle[128];
3b9eff ¤   CHAR¤   ¤   ¤   szFilter[128];
67cf2b ¤   CHAR*¤  ¤   ¤   p;
cefb19 ¤   PGPError¤   ¤   err;
457b0b ¤   OPENFILENAME¤   ofn;
2305ac ¤   LPBITMAPINFO¤   lpbmi;
70af5a
4b6632 ¤   szFile[0] = '\0';
76af5a
4ded91 ¤   LoadString (g_hInst, IDS_BITMAPFILTER, szFilter, sizeof(szFilter));
52a8e6 ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
fdaf5a
718d11 ¤   LoadString (g_hInst, IDS_OPENBITMAPTITLE, szTitle, sizeof(szTitle));
3baf5a
ff4fd0 ¤   ofn.lStructSize ······= sizeof (OPENFILENAME);
c49214 ¤   ofn.hwndOwner ········= hwnd;
b0a756 ¤   ofn.hInstance ········= (HANDLE)g_hInst;
8dbe52 ¤   ofn.lpstrFilter ······= szFilter;
c83385 ¤   ofn.lpstrCustomFilter = (LPTSTR)NULL;
26e9dc ¤   ofn.nMaxCustFilter ···= 0L;
1080b6 ¤   ofn.nFilterIndex ·····= 1L;
6a4e92 ¤   ofn.lpstrFile ········= szFile;
94e317 ¤   ofn.nMaxFile ·········= sizeof (szFile);
f7501d ¤   ofn.lpstrFileTitle ···= szTitle;
288734 ¤   ofn.nMaxFileTitle ····= 0;
a13225 ¤   ofn.lpstrInitialDir ··= NULL;
ce006e ¤   ofn.lpstrTitle ·······= szTitle;
e7ef71 ¤   ofn.Flags¤  ¤   ¤   ··= OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
db0d2e ¤   ofn.nFileOffset ······= 0;
d4c4f3 ¤   ofn.nFileExtension ···= 0;
d84406 ¤   ofn.lpstrDefExt ······= NULL;
66ebd4 ¤   ofn.lCustData ········= 0;
07af5a
b127ed ¤   if (!GetOpenFileName (&ofn)) return;
8faf5a
95487d ¤   err = KMReadPhotoFromFile (szFile, &pPhoto, &isize);
c2af5a
91162b ¤   if (IsntPGPError (PGPclErrorBox (hwnd, err))) {
fa9f41 ¤   ¤   if (paps->pPhotoBuffer)·
52c37d ¤   ¤   ¤   KMFree (paps->pPhotoBuffer);
1e2d05 ¤   ¤   if (paps->hbitmapPhotoID)·
4b4617 ¤   ¤   ¤   DeleteObject (paps->hbitmapPhotoID);
3c6922 ¤   ¤   if (paps->hpalettePhotoID)·
bdd6f9 ¤   ¤   ¤   DeleteObject (paps->hpalettePhotoID);
e3af5a
59527f ¤   ¤   paps->pPhotoBuffer = pPhoto;
9c7154 ¤   ¤   paps->iPhotoBufferLength = isize;
7b8aff ¤   ¤   EnableWindow (GetDlgItem (hwnd, IDOK), TRUE);
94af5a
4ea1ea ¤   ¤   err = KMDIBfromPhoto (pPhoto, isize, TRUE, &lpbmi);·
c9af5a
978536 ¤   ¤   if (IsntPGPError (err)) {
8f80ba ¤   ¤   ¤   KMGetDIBSize (lpbmi, &(paps->iwidthPhotoID),
f9975e ¤   ¤   ¤   ¤   ·&(paps->iheightPhotoID));
d8af5a
9d5630 ¤   ¤   ¤   paps->hbitmapPhotoID = KMDDBfromDIB (lpbmi,·
1db689 ¤   ¤   ¤   ¤   ¤   &(paps->hpalettePhotoID));·
acaf5a
c3722c ¤   ¤   ¤   KMFree (lpbmi);
4caf5a
549f4d ¤   ¤   ¤   InvalidateRect (hwnd, NULL, TRUE);
fb0fe4 ¤   ¤   }
3147d1 ¤   }·
87efe6 }
08af5a
3aaf5a
534265 //¤ ___________________________________________________
dd465d //
--247d 0008f8a1dbe4011029f Page 8 of KMAddUsr.c
35f26d // ·Add PhotoID Dialog Message procedure
56af5a
243f64 static BOOL CALLBACK·
af8664 sAddPhotoDlgProc (
5f3a3a ¤   ¤   HWND¤   hDlg,·
4eeb77 ¤   ¤   UINT¤   uMsg,·
a90303 ¤   ¤   WPARAM¤ wParam,
1fc0b8 ¤   ¤   LPARAM¤ lParam)·
abbb36 {
e2a711 ¤   PADDPHOTOSTRUCT paps;
5405ac ¤   LPBITMAPINFO¤   lpbmi;
0faf5a
6f31cf ¤   switch(uMsg) {
40af5a
d62940 ¤   case WM_INITDIALOG:
faddda ¤   ¤   paps = (PADDPHOTOSTRUCT)lParam;
357547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
b5af5a
783d47 ¤   ¤   // subclass photoID control to handle dropping, dragging
f4f8f1 ¤   ¤   paps->wpOrigPhotoIDProc =·
2e3c65 ¤   ¤   ¤   (WNDPROC) SetWindowLong(GetDlgItem (hDlg, IDC_PHOTOID),·
1959d7 ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG) sPhotoIDSubclassProc);·
77af5a
70836c ¤   ¤   return TRUE;
44af5a
75c3eb ····case WM_HELP:·
7df51a ¤   ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
1d3199 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, paps->pKM->szHelpFile,·
7b593a ············HELP_WM_HELP, (DWORD) (LPSTR) aNewPhotoIds);·
a18f13 ········break;·
55d83c ·
504fd8 ····case WM_CONTEXTMENU:·
b17421 ·¤  ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
64f551 ¤   ¤   WinHelp ((HWND) wParam, paps->pKM->szHelpFile, HELP_CONTEXTMENU,·
390601 ············(DWORD) (LPVOID) aNewPhotoIds);·
b68f13 ········break;·
1faf5a
2e6334 ¤   case WM_DESTROY :
c57421 ·¤  ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
4a7486 ¤   ¤   SetWindowLong(GetDlgItem(hDlg, IDC_PHOTOID),·
c86a8a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG)paps->wpOrigPhotoIDProc);·
942f68 ¤   ¤   break;
c4af5a
fc85ca ¤   case WM_PAINT :
00f51a ¤   ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
a0299c ¤   ¤   sPaintPhotoID (hDlg,·
c0da14 ¤   ¤   ¤   ¤   ¤   ¤   paps->hbitmapPhotoID, paps->hpalettePhotoID,
cb6487 ¤   ¤   ¤   ¤   ¤   ¤   paps->iwidthPhotoID, paps->iheightPhotoID);
5f2f68 ¤   ¤   break;
feaf5a
aaea1a ¤   case WM_PALETTECHANGED :
f03de4 ¤   ¤   if ((HWND)wParam != hDlg) {
1abb6d ¤   ¤   ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
b9ca93 ¤   ¤   ¤   sUpdatePalette (hDlg, paps);
eb0fe4 ¤   ¤   }
162f68 ¤   ¤   break;
9daf5a
f0dfee ¤   case WM_QUERYNEWPALETTE :
48f51a ¤   ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
46532b ¤   ¤   return (sUpdatePalette (hDlg, paps));
d8af5a
2a3fcf ¤   case WM_COMMAND:
edf51a ¤   ¤   paps = (PADDPHOTOSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
b8379d ¤   ¤   switch(LOWORD (wParam)) {
cd4672 ¤   ¤   case IDOK:·
64f3d5 ¤   ¤   ¤   EndDialog (hDlg, 1);
c132bd ¤   ¤   ¤   return TRUE;
68af5a
b371eb ¤   ¤   case IDCANCEL:
8aef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
ef32bd ¤   ¤   ¤   return TRUE;
8faf5a
--4e68 000bf7a88734011029f Page 9 of KMAddUsr.c
082ee5 ¤   ¤   case IDC_SELECTFILE :
32fdb0 ¤   ¤   ¤   sSelectBitmapFile (hDlg, paps);
7bcdcb ¤   ¤   ¤   break;
66af5a
12e2a4 ¤   ¤   case IDM_COPYBITMAP :
4a8302 ¤   ¤   ¤   KMCopyPhotoToClipboard (hDlg, paps->pPhotoBuffer,·
8476be ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   paps->iPhotoBufferLength);
a7cdcb ¤   ¤   ¤   break;
54af5a
e3f5ec ¤   ¤   case IDM_PASTEBITMAP :
6df776 ¤   ¤   ¤   {
4d3267 ¤   ¤   ¤   ¤   LPBYTE¤ ¤   pPhoto¤ ¤   ¤   ¤   = NULL;
308e1f ¤   ¤   ¤   ¤   INT¤¤   ¤   isize¤  ¤   ¤   ¤   = 0;
5945e4 ¤   ¤   ¤   ¤   PGPError¤   err¤¤   ¤   ¤   ¤   = kPGPError_UserAbort;
e03b45 ¤   ¤   ¤   ¤   INT¤¤   ¤   iLen;
135556 ¤   ¤   ¤   ¤   CHAR¤   ¤   szFile[MAX_PATH];
093eac ¤   ¤   ¤   ¤   HANDLE¤ ¤   hMem;
62cce4 ¤   ¤   ¤   ¤   HDROP¤  ¤   hDrop;
79af5a
9020f1 ¤   ¤   ¤   ¤   if (IsClipboardFormatAvailable (CF_DIB)) {
098236 ¤   ¤   ¤   ¤   ¤   err = KMPastePhotoFromClipboard (hDlg, &pPhoto, &isize);
962613 ¤   ¤   ¤   ¤   }
f3af5a
30ea86 ¤   ¤   ¤   ¤   if (IsPGPError (err)) {
877bad ¤   ¤   ¤   ¤   ¤   if (IsClipboardFormatAvailable (CF_HDROP)) {
5e649f ¤   ¤   ¤   ¤   ¤   ¤   if (OpenClipboard (hDlg)) {·
5783d4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hMem = GetClipboardData (CF_HDROP);·
04784a ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (hMem) {
5d4e09 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDrop = GlobalLock (hMem);
bf49c6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iLen = DragQueryFile (hDrop, 0,·
8721ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFile, sizeof(szFile));
cf67c5 ¤
a6aa70 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   err = KMReadPhotoFromFile (
ac4930 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFile, &pPhoto, &isize);
7c67c5 ¤
b76fa7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GlobalUnlock (hMem);
175268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
f24230 ¤   ¤   ¤   ¤   ¤   ¤   ¤   CloseClipboard ();
f3db3c ¤   ¤   ¤   ¤   ¤   ¤   }
681c89 ¤   ¤   ¤   ¤   ¤   }
132613 ¤   ¤   ¤   ¤   }
05af5a
24381b ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (hDlg, err)) &&
b4e43b ¤   ¤   ¤   ¤   ¤   IsntPGPError (err))·
0472c3 ¤   ¤   ¤   ¤   {
2da17c ¤   ¤   ¤   ¤   ¤   if (paps->pPhotoBuffer)·
c4c443 ¤   ¤   ¤   ¤   ¤   ¤   KMFree (paps->pPhotoBuffer);
cdf322 ¤   ¤   ¤   ¤   ¤   if (paps->hbitmapPhotoID)·
795c8a ¤   ¤   ¤   ¤   ¤   ¤   DeleteObject (paps->hbitmapPhotoID);
613c41 ¤   ¤   ¤   ¤   ¤   if (paps->hpalettePhotoID)·
8c998f ¤   ¤   ¤   ¤   ¤   ¤   DeleteObject (paps->hpalettePhotoID);
c3af5a
9b03b7 ¤   ¤   ¤   ¤   ¤   paps->pPhotoBuffer = pPhoto;
e9a9ae ¤   ¤   ¤   ¤   ¤   paps->iPhotoBufferLength = isize;
28278e ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
74af5a
d2f6f0 ¤   ¤   ¤   ¤   ¤   err = KMDIBfromPhoto (pPhoto, isize, TRUE, &lpbmi);·
41af5a
3a6f6e ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
a3f663 ¤   ¤   ¤   ¤   ¤   ¤   KMGetDIBSize (lpbmi, &(paps->iwidthPhotoID),
0ecf53 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·&(paps->iheightPhotoID));
95af5a
7120e9 ¤   ¤   ¤   ¤   ¤   ¤   paps->hbitmapPhotoID = KMDDBfromDIB (lpbmi,·
b5fa33 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(paps->hpalettePhotoID));·
c7af5a
0191db ¤   ¤   ¤   ¤   ¤   ¤   KMFree (lpbmi);
20af5a
19f964 ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (hDlg, NULL, TRUE);
c31c89 ¤   ¤   ¤   ¤   ¤   }
1f0770 ¤   ¤   ¤   ¤   }·
dfa3a6 ¤   ¤   ¤   }
bfcdcb ¤   ¤   ¤   break;
--9285 000d219a1044011029f Page 10 of KMAddUsr.c
b50fe4 ¤   ¤   }
ab836c ¤   ¤   return TRUE;
059371 ¤   }
a0a230 ¤   return FALSE;
d7efe6 }
85af5a
b9af5a
424265 //¤ ___________________________________________________
b4465d //
3f7ebb // ·Add Photo UserID to key
f11133 //¤ This routine is called when the user chooses to add
d45ea0 //¤ a PhotoID to an existing secret key.
80af5a
917efe BOOL·
155bc2 KMAddPhotoToKey (PKEYMAN pKM)·
92bb36 {
1e0b8e ¤   PGPByte*¤   ¤   pPasskey¤   ¤   = NULL;
2ca32a ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   = TRUE;
b4fb19 ¤   PGPError¤   ¤   err;
ea1502 ¤   PGPKeyRef¤  ¤   key;
9cb9e5 ¤   PGPSize¤¤   ¤   sizePasskey;
2db0de ¤   ADDPHOTOSTRUCT¤ aps;
0e2a4f ¤   CHAR¤   ¤   ¤   sz[256];
20ce0f ¤   PGPPrefRef¤ ¤   prefref;
f518da ¤   HCURSOR¤¤   ¤   hcursorOld;
deaf5a
bccd70 ¤   // get selected key
ff0a36 ¤   key = (PGPKeyRef)KMFocusedObject (pKM);
f5af5a
ea92fc ¤   // check if there is a pre-existing photoid
46f1f2 ¤   if (KMExistingPhotoID (pKM, key)) {
1a51b8 ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION,
02e91b ¤   ¤   ¤   IDS_PHOTOIDALREADYEXISTS, MB_OK|MB_ICONSTOP);
2098aa ¤   ¤   return FALSE;
2c9371 ¤   }
b4af5a
46a8bb ¤   // initialize struct
a81d7f ¤   aps.pKM = pKM;
60fb80 ¤   aps.pPhotoBuffer = NULL;
b62594 ¤   aps.hbitmapPhotoID = NULL;
528806 ¤   aps.hpalettePhotoID = NULL;
6c410a ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), &prefref);
3559c0 ¤   PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnAdd,·
85d780 ¤   ¤   ¤   ¤   ¤   ¤   &(aps.bSyncWithServer));
47ab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
28af5a
11b76d ¤   // get new photoid from user
690dfa ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_NEWPHOTOID),·
cd30d3 ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sAddPhotoDlgProc, (LPARAM)&aps)) {
9eaf5a
b07480 ¤   ¤   // get valid passphrase
d397ce ¤   ¤   LoadString (g_hInst, IDS_SELKEYPASSPHRASE, sz, sizeof(sz));·
b9f4b5 ¤   ¤   err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
27e6e8 ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sz,
09da1c ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, key,
f8f782 ¤   ¤   ¤   ¤   ¤   ¤   NULL, &pPasskey, &sizePasskey);
be94cd ¤   ¤   PGPclErrorBox (NULL, err);
3eaf5a
301a2d ¤   ¤   // now we have a valid passphrase, if required
028536 ¤   ¤   if (IsntPGPError (err)) {
a6af5a
b0da8a ¤   ¤   ¤   // update from server
a3cf60 ¤   ¤   ¤   if (aps.bSyncWithServer) {
424a1c ¤   ¤   ¤   ¤   if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
deed00 ¤   ¤   ¤   ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
b9abcc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_QUERYCONTINUEADDING, ¤
67eba6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
0b11b2 ¤   ¤   ¤   ¤   ¤   ¤   bRetVal = FALSE;
9e1c89 ¤   ¤   ¤   ¤   ¤   }
772613 ¤   ¤   ¤   ¤   }
1ca3a6 ¤   ¤   ¤   }
d21b52 ¤   ¤
--9a0f 00125a08a214011029f Page 11 of KMAddUsr.c
cf9bd0 ¤   ¤   ¤   if (bRetVal) {
14f44d ¤   ¤   ¤   ¤   // make sure we have enough entropy
9bb2d2 ¤   ¤   ¤   ¤   PGPclRandom (pKM->Context, pKM->hWndParent, 0);
6daf5a
f612fe ¤   ¤   ¤   ¤   hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
8913c0 ¤   ¤   ¤   ¤   if (pPasskey) {
f77c20 ¤   ¤   ¤   ¤   ¤   err = PGPAddAttributeUserID (
1e803f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   key,
e202fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAttribute_Image,
f2d5cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   aps.pPhotoBuffer,
25e447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   aps.iPhotoBufferLength,
35c8c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (pKM->Context,·
ae3929 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey),
78c929 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
d02613 ¤   ¤   ¤   ¤   }
92deaa ¤   ¤   ¤   ¤   else {
c87c20 ¤   ¤   ¤   ¤   ¤   err = PGPAddAttributeUserID (
d0803f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   key,
4702fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAttribute_Image,
5ad5cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   aps.pPhotoBuffer,
9fe447 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   aps.iPhotoBufferLength,
a7c929 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
b62613 ¤   ¤   ¤   ¤   }
2b1420 ¤   ¤   ¤   ¤   SetCursor (hcursorOld);
1094aa ¤   ¤   ¤   ¤   ¤   ¤
703a35 ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
1baab9 ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
6041e4 ¤   ¤   ¤   ¤   ¤   KMUpdateKeyInTree (pKM, key, FALSE);
103ef8 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
6daf5a
079a84 ¤   ¤   ¤   ¤   ¤   // send to server
f550b4 ¤   ¤   ¤   ¤   ¤   if (aps.bSyncWithServer) {
24e148 ¤   ¤   ¤   ¤   ¤   ¤   KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
c81c89 ¤   ¤   ¤   ¤   ¤   }
b02613 ¤   ¤   ¤   ¤   }
ffd9bf ¤   ¤   ¤   ¤   else bRetVal = FALSE;
c2a3a6 ¤   ¤   ¤   }
bc0fe4 ¤   ¤   }
5801c4 ¤   ¤   else bRetVal = FALSE;
bd9371 ¤   }
678890 ¤   else bRetVal = FALSE;
15af5a
06fa60 ¤   // free passkey
97320f ¤   if (pPasskey) {
840297 ¤   ¤   KMFreePasskey (pPasskey, sizePasskey);
22997e ¤   ¤   pPasskey = NULL;
479371 ¤   }
7baf5a
3509dd ¤   // free photoID objects
24e8c3 ¤   if (aps.hbitmapPhotoID)
ca832b ¤   ¤   DeleteObject (aps.hbitmapPhotoID);
933d6b ¤   if (aps.hpalettePhotoID)·
252dd3 ¤   ¤   DeleteObject (aps.hpalettePhotoID);
a7eac7 ¤   if (aps.pPhotoBuffer)·
f650c3 ¤   ¤   KMFree (aps.pPhotoBuffer);
36af5a
79af5a
e21c35 ¤   return bRetVal;
25efe6 }
--7da5 000a093b923401102a0 Page 1 of KMChange.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
25898b ¤   KMChange.c - handle dialog for changing key passphrase
3667c5 ¤
68129f ¤   $Id: KMChange.c,v 1.19 1998/08/11 14:43:22 pbj Exp $
55af5a
dbf7f7 ____________________________________________________________________________*/
5ce610 #include "pgpPFLConfig.h"
d6af5a
a1c917 // project header files
b9850a #include "pgpkmx.h"
99af5a
61ad8c // pgp header files
c83991 #include "pgpAdminPrefs.h"
a9af5a
6093ed // external globals
25a009 extern HINSTANCE¤   g_hInst;
20af5a
1c492e // local globals
93e5da static BOOL¤¤   ¤   sbChangingPhrase;
5daf5a
274265 //¤ ___________________________________________________
24465d //
9171be // ·Change Passphrase of split key and all subkeys
7daf5a
bf69c9 static PGPError·
33f5ae sChangePhraseSplit (
c4e958 ¤   ¤   PGPContextRef¤  context,
818b6a ¤   ¤   PGPKeySetRef¤   keyset,
69868f ¤   ¤   PGPKeyRef¤  ¤   key,·
9180c6 ¤   ¤   PGPByte*¤   ¤   passkey,
1f5c14 ¤   ¤   PGPSize¤¤   ¤   sizePasskey,
fdd053 ¤   ¤   LPSTR¤  ¤   ¤   szNew)·
b7bb36 {
f66e76 ¤   UINT¤   ¤   ¤   u;
f1d125 ¤   PGPKeyListRef¤  keylist;
46c323 ¤   PGPKeyIterRef¤  keyiter;
8187ac ¤   PGPSubKeyRef¤   subkey;
95fb19 ¤   PGPError¤   ¤   err;
19af5a
053abf ¤   err = PGPChangePassphrase (key,·
7c90ac ¤   ¤   ¤   PGPOPasskeyBuffer (context, passkey, sizePasskey),
a4fb3e ¤   ¤   ¤   PGPOPassphrase (context, szNew),·
f06445 ¤   ¤   ¤   PGPOLastOption (context));
778616 ¤   if (IsPGPError (err)) return err;
a1af5a
028b21 ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u);
fc86a2 ¤   switch (u) {
252692 ¤   case kPGPPublicKeyAlgorithm_RSA :
992f68 ¤   ¤   break;
0baf5a
f77cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
34278b ¤   ¤   PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
9dfa80 ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
bcae6d ¤   ¤   PGPKeyIterSeek (keyiter, key);
ce9c21 ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
716680 ¤   ¤   while (subkey) {
308a53 ¤   ¤   ¤   err = PGPChangeSubKeyPassphrase (subkey,·
c2de77 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, passkey, sizePasskey),
fad1ed ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (context, szNew),
1e2323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
97cf3a ¤   ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
4d0fe4 ¤   ¤   }
ece9ea ¤   ¤   PGPFreeKeyIter (keyiter);
815a47 ¤   ¤   PGPFreeKeyList (keylist);
8d2f68 ¤   ¤   break;
c6af5a
02bfad ¤   default :
ee2f68 ¤   ¤   break;
a09371 ¤   }
--595c 0000289452d401102a0 Page 2 of KMChange.c
e0af5a
de5ea8 ¤   return err;
57efe6 }
b7af5a
734265 //¤ ___________________________________________________
dc465d //
009b66 // ·Change Passphrase of normal key and all subkeys
c9af5a
6769c9 static PGPError·
fa1dc5 sChangePhraseNormal (
9be958 ¤   ¤   PGPContextRef¤  context,
4a8b6a ¤   ¤   PGPKeySetRef¤   keyset,
34868f ¤   ¤   PGPKeyRef¤  ¤   key,·
6e66bc ¤   ¤   LPSTR¤  ¤   ¤   szOld,
ead053 ¤   ¤   LPSTR¤  ¤   ¤   szNew)·
2bbb36 {
126e76 ¤   UINT¤   ¤   ¤   u;
6fd125 ¤   PGPKeyListRef¤  keylist;
e5c323 ¤   PGPKeyIterRef¤  keyiter;
7987ac ¤   PGPSubKeyRef¤   subkey;
41fb19 ¤   PGPError¤   ¤   err;
64af5a
103abf ¤   err = PGPChangePassphrase (key,·
370c7b ¤   ¤   ¤   PGPOPassphrase (context, szOld),
91fb3e ¤   ¤   ¤   PGPOPassphrase (context, szNew),·
c16445 ¤   ¤   ¤   PGPOLastOption (context));
ca8616 ¤   if (IsPGPError (err)) return err;
bcaf5a
b58b21 ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u);
2086a2 ¤   switch (u) {
142692 ¤   case kPGPPublicKeyAlgorithm_RSA :
102f68 ¤   ¤   break;
a1af5a
7a7cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
5e278b ¤   ¤   PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
79fa80 ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
d0ae6d ¤   ¤   PGPKeyIterSeek (keyiter, key);
329c21 ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
1a6680 ¤   ¤   while (subkey) {
7c8a53 ¤   ¤   ¤   err = PGPChangeSubKeyPassphrase (subkey,·
0262ce ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (context, szOld),
57d1ed ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (context, szNew),
d42323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
4bcf3a ¤   ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
4d0fe4 ¤   ¤   }
bee9ea ¤   ¤   PGPFreeKeyIter (keyiter);
595a47 ¤   ¤   PGPFreeKeyList (keylist);
a52f68 ¤   ¤   break;
e2af5a
89bfad ¤   default :
e22f68 ¤   ¤   break;
2c9371 ¤   }
9baf5a
c75ea8 ¤   return err;
b6efe6 }
7faf5a
d14265 //¤ ___________________________________________________
b7465d //
e86bbf // ·Change passphrase on key·
1caf5a
637efe BOOL·
7b09ae KMChangePhrase (
3205b3 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,·
fb4acd ¤   ¤   PKEYMAN¤¤   ¤   ¤   pKM,
de9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
24a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
aee561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
f5f7df ¤   ¤   PGPKeyRef¤  ¤   ¤   key)·
46bb36 {
e28590 ¤   LPSTR¤  ¤   pszOldPhrase¤   ¤   = NULL;
4f5eff ¤   LPSTR¤  ¤   pszNewPhrase¤   ¤   = NULL;
024c77 ¤   PGPByte*¤   pPasskey¤   ¤   ¤   = NULL;
--a758 000ab452e4d401102a0 Page 3 of KMChange.c
50f1ec ¤   PGPPrefRef¤ prefs¤  ¤   ¤   ¤   = kInvalidPGPPrefRef;
094023 ¤   INT¤¤   ¤   iMinPhraseLength¤   = 0;
087dda ¤   INT¤¤   ¤   iMinPhraseQuality¤  = 0;
dcaf5a
852607 ¤   CHAR¤   ¤   szPrompt[64];
7a2765 ¤   PGPSize¤¤   sizePasskey;
0261e0 ¤   PGPError¤   err;
5f60ee ¤   BOOL¤   ¤   bSplit;
e2be29 #if PGP_BUSINESS_SECURITY
4872e2 ¤   PGPBoolean¤ b;
dc2717 ¤   PGPUInt32¤  u;
757454 #endif
a5af5a
6c627b ¤   if (!sbChangingPhrase) {
3ac228 ¤   ¤   sbChangingPhrase = TRUE;
baaf5a
d1d143 ¤   // minimum passphrase length
c5be29 #if PGP_BUSINESS_SECURITY
0531d9 #if PGP_ADMIN_BUILD¤
69eeb6 ¤   ¤   err = PGPclOpenAdminPrefs (
e49a6f ¤   ¤   ¤   PGPGetContextMemoryMgr (context), &prefs, TRUE);
85db21 #else
e2eeb6 ¤   ¤   err = PGPclOpenAdminPrefs (
09001d ¤   ¤   ¤   PGPGetContextMemoryMgr (context), &prefs, FALSE);
088e60 #endif¤
712283 ¤   ¤   CKERR;
1baf5a
f005ed ¤   ¤   b = FALSE;
318515 ¤   ¤   err = PGPGetPrefBoolean (prefs, kPGPPrefEnforceMinChars, &b); CKERR;
61e6c8 ¤   ¤   if (b) {
74132d ¤   ¤   ¤   err = PGPGetPrefNumber (prefs, kPGPPrefMinChars, &u); CKERR;
d4fee6 ¤   ¤   ¤   iMinPhraseLength = (INT)u;
7d0fe4 ¤   ¤   }
c43199 #endif·
c1af5a
cf43a9 ¤   // minimum passphrase quality
d6be29 #if PGP_BUSINESS_SECURITY
f005ed ¤   ¤   b = FALSE;
377082 ¤   ¤   PGPGetPrefBoolean (prefs, kPGPPrefEnforceMinQuality, &b); CKERR;
78e6c8 ¤   ¤   if (b) {
164fdb ¤   ¤   ¤   err = PGPGetPrefNumber (prefs, kPGPPrefMinQuality, &u); CKERR;
2dae1f ¤   ¤   ¤   iMinPhraseQuality = (INT)u;
110fe4 ¤   ¤   }
e43199 #endif·
f3af5a
49c90f ¤   ¤   err = KMGetKeyPhrase (
4c58ce ¤   ¤   ¤   context,
535618 ¤   ¤   ¤   tlsContext,
f1164c ¤   ¤   ¤   hwndParent,·
79dab8 ¤   ¤   ¤   NULL,
d04d06 ¤   ¤   ¤   keyset,
48c153 ¤   ¤   ¤   key,
1f836d ¤   ¤   ¤   &pszOldPhrase,
389365 ¤   ¤   ¤   &pPasskey,
c54ea3 ¤   ¤   ¤   &sizePasskey);
32af5a
008536 ¤   ¤   if (IsntPGPError (err)) {
e9af5a
c10521 ¤   ¤   ¤   LoadString (g_hInst, IDS_NEWPHRASEPROMPT,·
d2b31e ¤   ¤   ¤   ¤   ¤   ¤   ¤   szPrompt, sizeof(szPrompt));
b3479a ¤   ¤   ¤   err = KMGetConfirmationPhrase (
64cdd3 ¤   ¤   ¤   ¤   context,·
146577 ¤   ¤   ¤   ¤   hwndParent,
526667 ¤   ¤   ¤   ¤   szPrompt,
0437f2 ¤   ¤   ¤   ¤   keyset,
a6002a ¤   ¤   ¤   ¤   iMinPhraseLength,
a4edf1 ¤   ¤   ¤   ¤   iMinPhraseQuality,
a0e6f6 ¤   ¤   ¤   ¤   &pszNewPhrase);
cdaf5a
c46a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
7539f3 ¤   ¤   ¤   ¤   if (pszOldPhrase) bSplit = FALSE;
ab2429 ¤   ¤   ¤   ¤   else bSplit = TRUE;
--251a 0016980540c401102a0 Page 4 of KMChange.c
e0af5a
e99b12 ¤   ¤   ¤   ¤   if (bSplit) {
d2d16c ¤   ¤   ¤   ¤   ¤   err = sChangePhraseSplit (
1b6614 ¤   ¤   ¤   ¤   ¤   ¤   context,
6b6cc9 ¤   ¤   ¤   ¤   ¤   ¤   keyset,
1f0554 ¤   ¤   ¤   ¤   ¤   ¤   key,
4b56ec ¤   ¤   ¤   ¤   ¤   ¤   pPasskey,
91b558 ¤   ¤   ¤   ¤   ¤   ¤   sizePasskey,·
3ec517 ¤   ¤   ¤   ¤   ¤   ¤   pszNewPhrase);
d52613 ¤   ¤   ¤   ¤   }
6ddeaa ¤   ¤   ¤   ¤   else {
dcf8ff ¤   ¤   ¤   ¤   ¤   err = sChangePhraseNormal (
396614 ¤   ¤   ¤   ¤   ¤   ¤   context,
6a6cc9 ¤   ¤   ¤   ¤   ¤   ¤   keyset,
310554 ¤   ¤   ¤   ¤   ¤   ¤   key,
171393 ¤   ¤   ¤   ¤   ¤   ¤   pszOldPhrase,·
6bc517 ¤   ¤   ¤   ¤   ¤   ¤   pszNewPhrase);
e32613 ¤   ¤   ¤   ¤   }
eda3a6 ¤   ¤   ¤   }
520fe4 ¤   ¤   }
57af5a
eeeb03 ¤   ¤   if (pszOldPhrase)
b17458 ¤   ¤   ¤   KMFreePhrase (pszOldPhrase);
71d20f ¤   ¤   if (pszNewPhrase)
59be0d ¤   ¤   ¤   KMFreePhrase (pszNewPhrase);
8c3429 ¤   ¤   if (pPasskey)
e7da25 ¤   ¤   ¤   KMFreePasskey (pPasskey, sizePasskey);
22af5a
b157cf ¤   ¤   if (IsPGPError (err))
7f7d80 ¤   ¤   ¤   PGPclErrorBox (hwndParent, err);
0b07e0 ¤   ¤   else {
705c6c ¤   ¤   ¤   PGPclNotifyPurgePassphraseCache (
45c5fd ¤   ¤   ¤   ¤   ¤   PGPCL_DECRYPTIONCACHE|PGPCL_SIGNINGCACHE, 0);
9933e2 ¤   ¤   ¤   if (bSplit)
f2ed67 ¤   ¤   ¤   ¤   KMMessageBox (hwndParent, IDS_PGP, IDS_KEYRECONSTITUTED,·
0f909c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
cfbb8c ¤   ¤   ¤   else
c03008 ¤   ¤   ¤   ¤   KMMessageBox (hwndParent, IDS_PGP, IDS_PHRASECHANGED,·
8b909c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
660fe4 ¤   ¤   }
dfaf5a
b39371 ¤   }
9eaf5a
64be29 #if PGP_BUSINESS_SECURITY
61a1c0 done :
1727fe ¤   if (PGPPrefRefIsValid (prefs))
cd7994 ¤   ¤   PGPclCloseAdminPrefs (prefs, FALSE);
747454 #endif
40af5a
68abc3 ¤   sbChangingPhrase = FALSE;
9aaf5a
797ed5 ¤   PGPclErrorBox (hwndParent, err);
49af5a
45ac2a ¤   return (IsntPGPError (err));
69efe6 }
--52fc 000ea11e9eb401102a1 Page 1 of KMColumn.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
25965a ¤   KMColumn.c - manage column selection
1f67c5 ¤
24af5a
c0d932 ¤   $Id: KMColumn.c,v 1.6 1998/08/11 14:43:22 pbj Exp $
0df7f7 ____________________________________________________________________________*/
23e610 #include "pgpPFLConfig.h"
64af5a
80c917 // project header files
08850a #include "pgpkmx.h"
46af5a
bcad8c // pgp header files
d2c97b #include "pgpClientPrefs.h"
d2af5a
0f5bee // typedefs
11f0f7 typedef struct {
907a35 ¤   WORD wColumnField[NUMBERFIELDS];
2589e3 ¤   WORD wFieldWidth[NUMBERFIELDS];
ae87d1 ¤   LONG lSortField;
0405b5 } COLUMNPREFSSTRUCT, *PCOLUMNPREFSSTRUCT;
acaf5a
f75584 // constant definitions
d112b4 #define DEFAULTCOLWIDTHNAME¤¤   240
433b5b #define DEFAULTCOLWIDTHVALID¤   50
916196 #define DEFAULTCOLWIDTHTRUST¤   50
f4d026 #define DEFAULTCOLWIDTHSIZE¤¤   70
4482db #define DEFAULTCOLWIDTHDESC¤¤   200
ba8911 #define MINWIDTH¤   ¤   ¤   ¤   10
acd04e #define MAXWIDTH¤   ¤   ¤   ¤   1000
21af5a
56eebb #define KMI_NAME¤   ¤   ¤   ¤   0
cd58f8 #define KMI_VALIDITY¤   ¤   ¤   1
e8448b #define KMI_SIZE¤   ¤   ¤   ¤   2
bb576a #define KMI_DESCRIPTION¤¤   ¤   3
93fb87 #define KMI_KEYID¤  ¤   ¤   ¤   4
a6587b #define KMI_TRUST¤  ¤   ¤   ¤   5
d29b8b #define KMI_CREATION¤   ¤   ¤   6
9775bb #define KMI_EXPIRATION¤ ¤   ¤   7
745679 #define KMI_ADK¤¤   ¤   ¤   ¤   8
82ce73 #define NUMBERFIELDS¤   ¤   ¤   9
84af5a
983fb5 // external global variables
879cad extern HINSTANCE g_hInst;
48af5a
cba3c6 //¤ ___________________________________________
96465d //
eef77f //¤ Get widths of control columns from client prefs file
99a1ba VOID·
1914ba KMGetColumnPreferences (PKEYMAN pKM)
f1bb36 {
488f52 ¤   PGPError¤   ¤   ¤   err;
99697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
5bca8a ¤   PGPSize¤¤   ¤   ¤   size;
d6b63b ¤   PCOLUMNPREFSSTRUCT¤ pcps;
05b236 ¤   INT¤¤   ¤   ¤   ¤   i;
f9716d ¤   WORD¤   ¤   ¤   ¤   wField, wWidth;
b2af5a
f5be29 #if PGP_BUSINESS_SECURITY
4b2350 ¤   pKM->wColumnField[0]¤   ¤   ¤   ¤   = KMI_NAME;
7c82fb ¤   pKM->wColumnField[1]¤   ¤   ¤   ¤   = KMI_VALIDITY;
55db79 ¤   pKM->wColumnField[2]¤   ¤   ¤   ¤   = KMI_SIZE;
e8ff57 ¤   pKM->wColumnField[3]¤   ¤   ¤   ¤   = KMI_DESCRIPTION;
f2f70d ¤   pKM->wColumnField[4]¤   ¤   ¤   ¤   = 0;
d17ec4 ¤   pKM->wColumnField[5]¤   ¤   ¤   ¤   = 0;
adec8e ¤   pKM->wColumnField[6]¤   ¤   ¤   ¤   = 0;
446547 ¤   pKM->wColumnField[7]¤   ¤   ¤   ¤   = 0;
52ae07 ¤   pKM->wColumnField[8]¤   ¤   ¤   ¤   = 0;
07af5a
eafa52 ¤   pKM->wFieldWidth[KMI_NAME]¤ ¤   ¤   = DEFAULTCOLWIDTHNAME;
--31ce 000d0fa9064401102a1 Page 2 of KMColumn.c
79b167 ¤   pKM->wFieldWidth[KMI_VALIDITY]¤ ¤   = DEFAULTCOLWIDTHVALID;
cbe341 ¤   pKM->wFieldWidth[KMI_SIZE]¤ ¤   ¤   = DEFAULTCOLWIDTHSIZE;
2e3ef0 ¤   pKM->wFieldWidth[KMI_DESCRIPTION]¤  = DEFAULTCOLWIDTHDESC;
26c7ad ¤   pKM->wFieldWidth[KMI_KEYID]¤¤   ¤   = 0;
fe0d6c ¤   pKM->wFieldWidth[KMI_TRUST]¤¤   ¤   = 0;
1fddc7 ¤   pKM->wFieldWidth[KMI_CREATION]¤ ¤   = 0;
2447b8 ¤   pKM->wFieldWidth[KMI_EXPIRATION]¤   = 0;
15a61d ¤   pKM->wFieldWidth[KMI_ADK]¤  ¤   ¤   = 0;
33db21 #else
2d2350 ¤   pKM->wColumnField[0]¤   ¤   ¤   ¤   = KMI_NAME;
3382fb ¤   pKM->wColumnField[1]¤   ¤   ¤   ¤   = KMI_VALIDITY;
56eb7d ¤   pKM->wColumnField[2]¤   ¤   ¤   ¤   = KMI_TRUST;
84fb8a ¤   pKM->wColumnField[3]¤   ¤   ¤   ¤   = KMI_SIZE;
64c0f9 ¤   pKM->wColumnField[4]¤   ¤   ¤   ¤   = KMI_DESCRIPTION;
f07ec4 ¤   pKM->wColumnField[5]¤   ¤   ¤   ¤   = 0;
31ec8e ¤   pKM->wColumnField[6]¤   ¤   ¤   ¤   = 0;
516547 ¤   pKM->wColumnField[7]¤   ¤   ¤   ¤   = 0;
fbae07 ¤   pKM->wColumnField[8]¤   ¤   ¤   ¤   = 0;
44af5a
28fa52 ¤   pKM->wFieldWidth[KMI_NAME]¤ ¤   ¤   = DEFAULTCOLWIDTHNAME;
5bb167 ¤   pKM->wFieldWidth[KMI_VALIDITY]¤ ¤   = DEFAULTCOLWIDTHVALID;
e4e341 ¤   pKM->wFieldWidth[KMI_SIZE]¤ ¤   ¤   = DEFAULTCOLWIDTHSIZE;
d23ef0 ¤   pKM->wFieldWidth[KMI_DESCRIPTION]¤  = DEFAULTCOLWIDTHDESC;
acc7ad ¤   pKM->wFieldWidth[KMI_KEYID]¤¤   ¤   = 0;
8dcac3 ¤   pKM->wFieldWidth[KMI_TRUST]¤¤   ¤   = DEFAULTCOLWIDTHTRUST;
90ddc7 ¤   pKM->wFieldWidth[KMI_CREATION]¤ ¤   = 0;
5b47b8 ¤   pKM->wFieldWidth[KMI_EXPIRATION]¤   = 0;
56a61d ¤   pKM->wFieldWidth[KMI_ADK]¤  ¤   ¤   = 0;
367454 #endif
40af5a
92672e ¤   pKM->lKeyListSortField¤ ¤   ¤   ¤   = kPGPUserIDOrdering;
f5af5a
0b2e4d ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context),·
8ccb15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
63b23e ¤   if (IsntPGPError (err)) {
bccd85 ¤   ¤   err = PGPGetPrefData (prefref, kPGPPrefPGPkeysWinColumnData,
2c556e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··&size, &pcps);
6aaf5a
e58536 ¤   ¤   if (IsntPGPError (err)) {
70cac9 ¤   ¤   ¤   if (size == sizeof(COLUMNPREFSSTRUCT)) {
d7dbf0 ¤   ¤   ¤   ¤   for (i=0; i<NUMBERFIELDS; i++) {
0bef8f ¤   ¤   ¤   ¤   ¤   wField = pcps->wColumnField[i];
7c21c5 ¤   ¤   ¤   ¤   ¤   if ((wField >= 0) && (wField < NUMBERFIELDS))
ecb975 ¤   ¤   ¤   ¤   ¤   ¤   pKM->wColumnField[i] = wField;
8519a2 ¤   ¤   ¤   ¤   ¤   wWidth = pcps->wFieldWidth[i];
a5ed73 ¤   ¤   ¤   ¤   ¤   if ((wWidth >= MINWIDTH) && (wWidth <= MAXWIDTH))
c6e496 ¤   ¤   ¤   ¤   ¤   ¤   pKM->wFieldWidth[i] = wWidth;
c92613 ¤   ¤   ¤   ¤   }
da437b ¤   ¤   ¤   ¤   pKM->lKeyListSortField = pcps->lSortField;
3fa3a6 ¤   ¤   ¤   }
8681f3 ¤   ¤   ¤   PGPDisposePrefData (prefref, pcps);
050fe4 ¤   ¤   }
6fb30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
0d9371 ¤   }
09efe6 }
b9af5a
5fa3c6 //¤ ___________________________________________
0bac6a //·
997ca2 //¤ Put column information into client prefs file
dfaf5a
caa1ba VOID·
090acd KMSetColumnPreferences (PKEYMAN pKM)·
dabb36 {
978f52 ¤   PGPError¤   ¤   ¤   err;
02697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
83398d ¤   COLUMNPREFSSTRUCT¤  cps;
53c23b ¤   INT¤¤   ¤   ¤   ¤   i, iField;
f5af5a
e1af5a
132e4d ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context),·
cfcb15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
d0b23e ¤   if (IsntPGPError (err)) {
--c85d 000cc3692d6401102a1 Page 3 of KMColumn.c
4a8fd5 ¤   ¤   for (i=0; i<NUMBERFIELDS; i++) {
3796cf ¤   ¤   ¤   cps.wColumnField[i] = pKM->wColumnField[i];
9eaf5a
d8b3f1 ¤   ¤   ¤   iField = pKM->wColumnField[i];
5f11e0 ¤   ¤   ¤   if ((i == 0) || (iField != 0)) pKM->wFieldWidth[iField] =·
b39643 ¤   ¤   ¤   ¤   ¤   LOWORD (TreeList_GetColumnWidth (pKM->hWndTree, i));
64d147 ¤   ¤   ¤   cps.wFieldWidth[i] = pKM->wFieldWidth[i];
7e0fe4 ¤   ¤   }
3caf5a
0941fb ¤   ¤   cps.lSortField = pKM->lKeyListSortField;
adaf5a
dfa70c ¤   ¤   PGPSetPrefData (prefref, kPGPPrefPGPkeysWinColumnData,
d9f927 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··sizeof(cps), &cps);
26af5a
1b31b9 ¤   ¤   PGPclCloseClientPrefs (prefref, TRUE);
109371 ¤   }
59efe6 }
6caf5a
c0af5a
49b4cc //¤ _________________________
1b465d //
4028a4 //¤ Retrieve flags indicating which columns are displayed
25af5a
8da1ba VOID·
7f1eae KMGetSelectedColumns (PKEYMAN pKM, ULONG* pulColumnFlags)·
2abb36 {
0805c2 ¤   INT¤¤   iCol, iField;
46af5a
381bd7 ¤   if (!pulColumnFlags) return;
a0af5a
7e2060 ¤   *pulColumnFlags = 0;
37af5a
5ff252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
9c8ff9 ¤   ¤   iField = pKM->wColumnField[iCol];
eaf657 ¤   ¤   switch (iField) {
c52f60 ¤   ¤   case KMI_VALIDITY :
b2b5b9 ¤   ¤   ¤   *pulColumnFlags |= KM_VALIDITY;
bdcdcb ¤   ¤   ¤   break;
884285 ¤   ¤   case KMI_SIZE :
38c273 ¤   ¤   ¤   *pulColumnFlags |= KM_SIZE;
10cdcb ¤   ¤   ¤   break;
f002b9 ¤   ¤   case KMI_DESCRIPTION :
d3cb9c ¤   ¤   ¤   *pulColumnFlags |= KM_DESCRIPTION;
cccdcb ¤   ¤   ¤   break;
056beb ¤   ¤   case KMI_KEYID :
085bc8 ¤   ¤   ¤   *pulColumnFlags |= KM_KEYID;
51cdcb ¤   ¤   ¤   break;
00f94d ¤   ¤   case KMI_TRUST :
4a443e ¤   ¤   ¤   *pulColumnFlags |= KM_TRUST;
c6cdcb ¤   ¤   ¤   break;
653eb4 ¤   ¤   case KMI_CREATION :
a7e8b8 ¤   ¤   ¤   *pulColumnFlags |= KM_CREATION;
78cdcb ¤   ¤   ¤   break;
83a2f4 ¤   ¤   case KMI_EXPIRATION :
e69274 ¤   ¤   ¤   *pulColumnFlags |= KM_EXPIRATION;
9ccdcb ¤   ¤   ¤   break;
2a0d50 ¤   ¤   case KMI_ADK :
4fe35e ¤   ¤   ¤   *pulColumnFlags |= KM_ADK;
a8cdcb ¤   ¤   ¤   break;
5f0fe4 ¤   ¤   }
329371 ¤   }
a9830f ¤   return;
faefe6 }
8baf5a
20af5a
46b4cc //¤ _________________________
80465d //
19ad5a //¤ Remove columns to display
89af5a
82b333 static VOID·
5052e9 sRemoveColumn (PKEYMAN pKM, INT iField)·
ccbb36 {
--9fdf 00168503571401102a1 Page 4 of KMColumn.c
027f02 ¤   INT i, j;
18af5a
224768 ¤   for (i=1; i<NUMBERFIELDS; i++) {
735cd9 ¤   ¤   if (pKM->wColumnField[i] == iField) {
9575c0 ¤   ¤   ¤   for (j=i+1; j<NUMBERFIELDS; j++) {
f02081 ¤   ¤   ¤   ¤   pKM->wColumnField[j-1] = pKM->wColumnField[j];
24a3a6 ¤   ¤   ¤   }
d31e4f ¤   ¤   ¤   pKM->wColumnField[NUMBERFIELDS-1] = 0;
910ecc ¤   ¤   ¤   return;
d20fe4 ¤   ¤   }
999371 ¤   }
8cefe6 }
98af5a
6687c7 ¤   ¤   ¤
dbb4cc //¤ _________________________
60465d //
27c3b8 //¤ Add columns to display
fbaf5a
44b333 static VOID·
a7876d sAddColumn (PKEYMAN pKM, INT iField)·
d9bb36 {
8daedd ¤   INT i, iNumCol;
8267c5 ¤
a488ca ¤   iNumCol = 1;
258a38 ¤   for (i=0; i<NUMBERFIELDS; i++) {
b80a7a ¤   ¤   if (pKM->wColumnField[i]) iNumCol++;
e49371 ¤   }
bfaf5a
5407a5 ¤   for (i=0; i<iNumCol; i++) {
0b1eaf ¤   ¤   if (pKM->wColumnField[i] == iField) return;
7c9371 ¤   }
13af5a
6ef722 ¤   pKM->wColumnField[iNumCol] = iField;
7b308d ¤   if ((pKM->wFieldWidth[iField] > 1000) ||
7064bc ¤   ¤   (pKM->wFieldWidth[iField] <= 0))·
d66865 ¤   ¤   pKM->wFieldWidth[iField] = 60;
9967c5 ¤
43efe6 }
aaaf5a
feaf5a
dfb4cc //¤ _________________________
e2465d //
f0ce2f //¤ Select columns to display
77af5a
08a1ba VOID·
1f808a KMSelectColumns (PKEYMAN pKM, ULONG ulColumnFlags)·
3bbb36 {
c853df ¤   if (ulColumnFlags & KM_VALIDITY) sAddColumn (pKM, KMI_VALIDITY);
00ef65 ¤   else sRemoveColumn (pKM, KMI_VALIDITY);
fcaf5a
baf943 ¤   if (ulColumnFlags & KM_SIZE) sAddColumn (pKM, KMI_SIZE);
349878 ¤   else sRemoveColumn (pKM, KMI_SIZE);
0eaf5a
8c2832 ¤   if (ulColumnFlags & KM_DESCRIPTION) sAddColumn (pKM, KMI_DESCRIPTION);
325a5f ¤   else sRemoveColumn (pKM, KMI_DESCRIPTION);
10af5a
f2f2e7 ¤   if (ulColumnFlags & KM_KEYID) sAddColumn (pKM, KMI_KEYID);
6f6122 ¤   else sRemoveColumn (pKM, KMI_KEYID);
66af5a
7739a7 ¤   if (ulColumnFlags & KM_TRUST) sAddColumn (pKM, KMI_TRUST);
3af384 ¤   else sRemoveColumn (pKM, KMI_TRUST);
76af5a
5b18c4 ¤   if (ulColumnFlags & KM_CREATION) sAddColumn (pKM, KMI_CREATION);
01feb1 ¤   else sRemoveColumn (pKM, KMI_CREATION);
ecaf5a
0e7e2f ¤   if (ulColumnFlags & KM_EXPIRATION) sAddColumn (pKM, KMI_EXPIRATION);
53d259 ¤   else sRemoveColumn (pKM, KMI_EXPIRATION);
38af5a
a2bfe1 ¤   if (ulColumnFlags & KM_ADK) sAddColumn (pKM, KMI_ADK);
3a5e1b ¤   else sRemoveColumn (pKM, KMI_ADK);
8eaf5a
68efe6 }
--7445 0006d889b79401102a2 Page 1 of KMConvrt.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
980452 ¤   KMConvrt.c - miscellaneous conversion routines
2467c5 ¤
87af5a
e2c8ab ¤   $Id: KMConvrt.c,v 1.5 1998/08/11 14:43:23 pbj Exp $
56f7f7 ____________________________________________________________________________*/
7f8ad2 #include "pgpPFLConfig.h"¤
31af5a
4dc917 // project header files
39850a #include "pgpkmx.h"
efaf5a
fb93ed // external globals
2b9cad extern HINSTANCE g_hInst;
01af5a
0f4a83 //¤ ________________________
0b465d //
04bc6d //¤ Convert tm to SystemTime
77af5a
0ba1ba VOID·
b69963 sTimeToSystemTime (
4cba73 ¤   struct tm*¤ ptm,·
bd9924 ¤   SYSTEMTIME* pst)·
71bb36 {
7cf735 ¤   pst->wYear = ptm->tm_year + 1900;
ad57bc ¤   pst->wMonth = ptm->tm_mon + 1;
dab44a ¤   pst->wDay = ptm->tm_mday;
ecb245 ¤   pst->wDayOfWeek = ptm->tm_wday;
63a81f ¤   pst->wHour = ptm->tm_hour;
f6a250 ¤   pst->wMinute = ptm->tm_min;
e24165 ¤   pst->wSecond = ptm->tm_sec;
6e8d04 ¤   pst->wMilliseconds = 0;
d4efe6 }
40af5a
01c426 //¤ ______________________________________________________
23465d //
ae8937 //¤ Convert time to string format based on system settings
19af5a
e4fe80 VOID
492bb9 KMConvertTimeToString (
60770f ¤   ¤   PGPTime¤¤   Time,·
7ff3b3 ¤   ¤   LPSTR¤  ¤   sz,·
6398a4 ¤   ¤   INT¤¤   ¤   iLen)·
79bb36 {
a6b6f3 ¤   SYSTEMTIME¤ systemtime;
190180 ¤   time_t¤ ¤   ttTime;
2e36b2 ¤   struct tm*¤ ptm;
77af5a
6b780e ¤   ttTime = PGPGetStdTimeFromPGPTime (Time);
d2ff37 ¤   ptm = localtime (&ttTime);
ccaf5a
d4097c ¤   if (ptm) {
47ccd4 ¤   ¤   sTimeToSystemTime (ptm, &systemtime);
d0116a ¤   ¤   GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime,·
d635e8 ¤   ¤   ¤   NULL, sz, iLen);
e59371 ¤   }
324264 ¤   else·
6b3848 ¤   ¤   LoadString (g_hInst, IDS_INVALIDDATE, sz, iLen);
05efe6 }
65af5a
efaf5a
27c426 //¤ ______________________________________________________
e3465d //
771a02 //¤ Convert time to Win32 systemtime
ffaf5a
0dfe80 VOID
fdcf9a KMConvertTimeToDays (
dd148c ¤   ¤   PGPTime¤¤   time,·
7a84b7 ¤   ¤   INT*¤   ¤   piDays)·
6dbb36 {
--7fc8 0002c7acb3e401102a2 Page 2 of KMConvrt.c
8710bb ¤   SYSTEMTIME¤ st;
ff0180 ¤   time_t¤ ¤   ttTime;
f636b2 ¤   struct tm*¤ ptm;
d7af5a
3e15c7 ¤   if (piDays == NULL) return;
0870cf ¤   *piDays = 0;
c0af5a
f41b8d ¤   ttTime = PGPGetStdTimeFromPGPTime (time);
3bff37 ¤   ptm = localtime (&ttTime);
38af5a
d1097c ¤   if (ptm) {
25a30a ¤   ¤   sTimeToSystemTime (ptm, &st);
a3b48d ¤   ¤   PGPclSystemTimeToDays (&st, piDays);
3b9371 ¤   }
2fefe6 }
caaf5a
8aaf5a
c008ea //¤ ___________________________________________________________
07465d //
9aba9d //¤ Convert Fingerprint from string format to presentation format
d685c3 //¤ NB: sz must be at least 42 bytes long for RSA and 52 bytes
29ebd1 // ····for DSA keys
75af5a
35a1ba VOID·
0ef3ea KMConvertStringFingerprint (
b49045 ¤   ¤   UINT¤   uAlgorithm,·
075986 ¤   ¤   LPSTR¤  sz)·
4fbb36 {
b35c93 ¤   INT¤¤   i;
3073d5 ¤   UINT¤   u;
f770b4 ¤   CHAR¤   szBuf[20];
427cd6 ¤   CHAR*¤  p;
82af5a
39eef4 ¤   switch (uAlgorithm) {
8b2692 ¤   case kPGPPublicKeyAlgorithm_RSA :
a8689a ¤   ¤   memcpy (szBuf, sz, 16);
fd2bae ¤   ¤   p = sz;
08338c ¤   ¤   for (i=0; i<16; i+=2) {
82b588 ¤   ¤   ¤   switch (i) {
a175ac ¤   ¤   ¤   case 0:
69f622 ¤   ¤   ¤   ¤   break;
edb36e ¤   ¤   ¤   case 8:
61f59b ¤   ¤   ¤   ¤   *p++ = ' ';
d40082 ¤   ¤   ¤   default :
5cf59b ¤   ¤   ¤   ¤   *p++ = ' ';
04f622 ¤   ¤   ¤   ¤   break;
f9a3a6 ¤   ¤   ¤   }
eae9ae ¤   ¤   ¤   u = ((unsigned long)szBuf[i] & 0xFF);
61d53b ¤   ¤   ¤   u <<= 8;
ddb016 ¤   ¤   ¤   u |= ((unsigned long)szBuf[i+1] & 0xFF);
d482b6 ¤   ¤   ¤   wsprintf (p, "%04lX", u);
ccc815 ¤   ¤   ¤   p += 4;
320fe4 ¤   ¤   }
d02f68 ¤   ¤   break;
81af5a
3b7cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
8b3ecc ¤   ¤   memcpy (szBuf, sz, 20);
af2bae ¤   ¤   p = sz;
554115 ¤   ¤   for (i=0; i<20; i+=2) {
95b588 ¤   ¤   ¤   switch (i) {
1e75ac ¤   ¤   ¤   case 0:
08f622 ¤   ¤   ¤   ¤   break;
5f192a ¤   ¤   ¤   case 10:
a0f59b ¤   ¤   ¤   ¤   *p++ = ' ';
030082 ¤   ¤   ¤   default :
92f59b ¤   ¤   ¤   ¤   *p++ = ' ';
b2f622 ¤   ¤   ¤   ¤   break;
cda3a6 ¤   ¤   ¤   }
b6e9ae ¤   ¤   ¤   u = ((unsigned long)szBuf[i] & 0xFF);
78d53b ¤   ¤   ¤   u <<= 8;
06b016 ¤   ¤   ¤   u |= ((unsigned long)szBuf[i+1] & 0xFF);
2c82b6 ¤   ¤   ¤   wsprintf (p, "%04lX", u);
--86eb 000163f9fbc401102a2 Page 3 of KMConvrt.c
3bc815 ¤   ¤   ¤   p += 4;
540fe4 ¤   ¤   }
af2f68 ¤   ¤   break;
66af5a
bbbfad ¤   default :
5c2f70 ¤   ¤   lstrcpy (sz, "");
482f68 ¤   ¤   break;
b39371 ¤   }
2fefe6 }
62af5a
40edc9 //¤ ________________________________________________
3f465d //
4d823b //¤ Convert trust from weird PGP values to 0-3 scale
dfaf5a
b844eb UINT·
f968a3 KMConvertFromPGPTrust (UINT uPGPTrust)·
7dbb36 {
86e002 ¤   switch (uPGPTrust & kPGPKeyTrust_Mask) {
65219d ¤   case kPGPKeyTrust_Undefined¤:
f6f6f2 ¤   case kPGPKeyTrust_Unknown :
3d9b3e ¤   case kPGPKeyTrust_Never :
f9bbde ¤   ¤   return 0;
9fee9e ¤   case kPGPKeyTrust_Marginal :
7ce102 ¤   ¤   return 1;
893e83 ¤   case kPGPKeyTrust_Complete :
977b79 ¤   case kPGPKeyTrust_Ultimate :
950e66 ¤   ¤   return 2;
0dbfad ¤   default :
9ebbde ¤   ¤   return 0;
329371 ¤   }
7befe6 }
b2af5a
aa4265 //¤ ___________________________________________________
2a465d //
56ee00 //¤ Convert validity from weird PGP values to 0-2 scale
68af5a
fe44eb UINT·
624b2a KMConvertFromPGPValidity (UINT uPGPValidity)·
0ebb36 {
8ab366 ¤   switch (uPGPValidity) {
580372 ¤   case kPGPValidity_Unknown :
44f5ef ¤   case kPGPValidity_Invalid :
bed2bc ¤   ¤   return KM_VALIDITY_INVALID;
596a63 ¤   case kPGPValidity_Marginal :
a05163 ¤   ¤   return KM_VALIDITY_MARGINAL;
f9ba7e ¤   case kPGPValidity_Complete :
0cf1d5 ¤   ¤   return KM_VALIDITY_COMPLETE;
c0bfad ¤   default :
c2bbde ¤   ¤   return 0;
5a9371 ¤   }
84efe6 }
36af5a
5ef9e4 //¤ __________________________________________
42465d //
502027 //¤ Convert trust from 0-3 scale to PGP values
7eaf5a
cb44eb UINT·
139627 KMConvertToPGPTrust (UINT uTrust)·
ffbb36 {
c55900 ¤   switch (uTrust & 0x03) {
31741e ¤   case 0 :
df5e91 ¤   ¤   return kPGPKeyTrust_Never;
ac68a5 ¤   case 1 :
d7c847 ¤   ¤   return kPGPKeyTrust_Marginal;
254d68 ¤   case 2 :
fc68f1 ¤   ¤   return kPGPKeyTrust_Complete;
ab51d3 ¤   case 3 :
e4aec6 ¤   ¤   return kPGPKeyTrust_Ultimate;
07bfad ¤   default :
4cbbde ¤   ¤   return 0;
e39371 ¤   }
16efe6 }
--3815 0011a3a0194401102a2 Page 4 of KMConvrt.c
e0af5a
1aaf5a
--95f0 0004352f645401102a3 Page 1 of KMFocus.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
e55b01 ¤   KMFocus.c - routines for tracking the focused/selected items
2f67c5 ¤
65af5a
e8896b ¤   $Id: KMFocus.c,v 1.10 1998/08/11 14:43:24 pbj Exp $
64f7f7 ____________________________________________________________________________*/
458ad2 #include "pgpPFLConfig.h"¤
d6af5a
7cc917 // project header files
54850a #include "pgpkmx.h"
bfaf5a
7b5584 // constant definitions
b911d4 #define KEYIDCHARS¤ 512
c2af5a
b293ed // external globals
a85b3f extern HINSTANCE g_hInst;·
7eaf5a
325bee // typedefs
b6f0f7 typedef struct {
bdf3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
027e47 ¤   PKEYMAN¤¤   ¤   pKM;
e4a68f ¤   PGPKeySetRef¤   keysetSelected;
c7587f ¤   INT¤¤   ¤   ¤   icount;
01024c } SELOBJECTINFO;
abaf5a
4ef0f7 typedef struct {
97f3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
f547ea ¤   INT¤¤   ¤   ¤   iObjectCount;
c79f8b } SELOBJECTCOUNT;
a2af5a
bdc8dc //¤ ________________________________________
2f465d //
c452a1 // ·Count a single object
84465d //
365110 //¤ lptli¤  = pointer to TreeList item to delete
e9af5a
9a3f64 static BOOL CALLBACK·
33d95a sCountSingleObject (
539d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
99dd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
c7bb36 {
e111a8 ¤   SELOBJECTCOUNT*¤psoc = (SELOBJECTCOUNT*)lParam;
321896 ¤   ++(psoc->iObjectCount);
6dc2e7 ¤   return TRUE;
4cefe6 }
d9af5a
21a18c //¤ ____________________________________________
39465d //
26863d // ·Update status bar text on basis of selection
21af5a
63b333 static VOID·
b29d7c sUpdateStatusBarText (PKEYMAN pKM)·
8bbb36 {
cdd923 ¤   CHAR sz1[128];
f053f3 ¤   CHAR sz2[128];
7a907b ¤   INT ids;
06aa43 ¤   SELOBJECTCOUNT soc;
f0af5a
46908b ¤   if (!pKM->hWndStatusBar) return;
f7ffc5 ¤   if (pKM->ulOptionFlags & KMF_DISABLESTATUSBAR) return;
6baf5a
c47d34 ¤   switch (pKM->uSelectedFlags) {
419f47 ¤   ¤   case 0 :¤   ¤   ¤   ¤   ids = 0;¤   ¤   ¤   ¤   ¤   break;
87751e ¤   ¤   case PGPKM_KEYFLAG :¤   ids = IDS_KEYSELECTED;¤ ¤   break;
e2e0eb ¤   ¤   case PGPKM_UIDFLAG :¤   ids = IDS_UIDSELECTED;¤ ¤   break;
2c92cf ¤   ¤   case PGPKM_CERTFLAG :¤  ids = IDS_CERTSELECTED;¤¤   break;
88d132 ¤   ¤   default :¤  ¤   ¤   ¤   ids = IDS_MULTISELECTED;¤   break;
3b9371 ¤   }
43af5a
--5e54 000ceb16c68401102a3 Page 2 of KMFocus.c
27569d ¤   if (pKM->bMultipleSelected) {
c7a107 ¤   ¤   soc.lpfnCallback = sCountSingleObject;
87ea01 ¤   ¤   soc.iObjectCount = 0;
198117 ¤   ¤   TreeList_IterateSelected (pKM->hWndTree, &soc);
ef9371 ¤   }
9a4264 ¤   else·
35b0dd ¤   ¤   soc.iObjectCount = 1;
c4af5a
6d6ac4 ¤   if (ids) {
ae4545 ¤   ¤   LoadString (g_hInst, ids, sz1, sizeof(sz1));
8a3854 ¤   ¤   wsprintf (sz2, sz1, soc.iObjectCount);
369371 ¤   }
e50e24 ¤   else
c85109 ¤   ¤   lstrcpy (sz2, "");
25af5a
47ccc6 ¤   SendMessage (pKM->hWndStatusBar, SB_SETTEXT, 1, (LPARAM)sz2);
36efe6 }
bbaf5a
fdc8dc //¤ ________________________________________
d9465d //
baf371 // ·Set handle of selected item.
1a9a76 // ·Type and pointer to object are retrieved from·
792d01 // ·TreeList as imagelist index.
00af5a
74a1ba VOID·
d92c8c KMSetFocus (
8845dc ¤   ¤   PKEYMAN¤¤   pKM,·
a320a2 ¤   ¤   HTLITEM¤¤   hFocused,·
e969ae ¤   ¤   BOOL¤   ¤   bMultiple)·
7dbb36 {
21e723 ¤   TL_TREEITEM tli;
48af5a
b62aab ¤   pKM->hFocusedItem = hFocused;
485d84 ¤   pKM->bMultipleSelected = bMultiple;
29af5a
f5fd0d ¤   if (!bMultiple) pKM->uSelectedFlags = 0;
a5af5a
36861f ¤   if (hFocused) {·
4d23da ¤   ¤   tli.hItem = hFocused;
074049 ¤   ¤   tli.mask = TLIF_IMAGE | TLIF_PARAM;
03e425 ¤   ¤   if (!TreeList_GetItem (pKM->hWndTree, &tli)) return;
bc1c53 ¤   ¤   pKM->iFocusedItemType = tli.iImage;
0c78bb ¤   ¤   pKM->pFocusedObject = (void*)tli.lParam;
1713fd ¤   ¤   switch (pKM->iFocusedItemType) {
5f3c77 ¤   ¤   ¤   case IDX_NONE :·
56d406 ¤   ¤   ¤   ¤   pKM->iFocusedObjectType = OBJECT_NONE;·
66f622 ¤   ¤   ¤   ¤   break;
c2af5a
e8c636 ¤   ¤   ¤   case IDX_RSAPUBKEY :
2348e3 ¤   ¤   ¤   case IDX_RSAPUBDISKEY :
86d8a9 ¤   ¤   ¤   case IDX_RSAPUBREVKEY :
b177b7 ¤   ¤   ¤   case IDX_RSAPUBEXPKEY :
53d49c ¤   ¤   ¤   case IDX_RSASECKEY :
01926f ¤   ¤   ¤   case IDX_RSASECDISKEY :
630225 ¤   ¤   ¤   case IDX_RSASECREVKEY :
3cad3b ¤   ¤   ¤   case IDX_RSASECEXPKEY :
da9a73 ¤   ¤   ¤   case IDX_RSASECSHRKEY :
5fd423 ¤   ¤   ¤   case IDX_DSAPUBKEY :
8852ea ¤   ¤   ¤   case IDX_DSAPUBDISKEY :
57c2a0 ¤   ¤   ¤   case IDX_DSAPUBREVKEY :
c96dbe ¤   ¤   ¤   case IDX_DSAPUBEXPKEY :
7ac689 ¤   ¤   ¤   case IDX_DSASECKEY :
848866 ¤   ¤   ¤   case IDX_DSASECDISKEY :
f0182c ¤   ¤   ¤   case IDX_DSASECREVKEY :
fbb732 ¤   ¤   ¤   case IDX_DSASECEXPKEY :
a2807a ¤   ¤   ¤   case IDX_DSASECSHRKEY :
bc8c96 ¤   ¤   ¤   ¤   pKM->iFocusedObjectType = OBJECT_KEY;·
fe665a ¤   ¤   ¤   ¤   pKM->uSelectedFlags |= PGPKM_KEYFLAG;
50f622 ¤   ¤   ¤   ¤   break;
e2af5a
62365a ¤   ¤   ¤   case IDX_RSAUSERID :
ce9f9b ¤   ¤   ¤   case IDX_DSAUSERID :·
--3097 00002290eb9401102a3 Page 3 of KMFocus.c
c8a81c ¤   ¤   ¤   case IDX_PHOTOUSERID :
f5db44 ¤   ¤   ¤   case IDX_INVALIDUSERID :
978f0a ¤   ¤   ¤   ¤   pKM->iFocusedObjectType = OBJECT_USERID;·
e9e2ff ¤   ¤   ¤   ¤   pKM->uSelectedFlags |= PGPKM_UIDFLAG;
58f622 ¤   ¤   ¤   ¤   break;
8daf5a
4fe9a2 ¤   ¤   ¤   case IDX_CERT :
be961d ¤   ¤   ¤   case IDX_REVCERT :·
de5776 ¤   ¤   ¤   case IDX_BADCERT :
a01386 ¤   ¤   ¤   case IDX_EXPCERT :
7b312d ¤   ¤   ¤   case IDX_EXPORTCERT :
fc5b7f ¤   ¤   ¤   case IDX_TRUSTEDCERT :
aeb447 ¤   ¤   ¤   case IDX_METACERT :
08cf2d ¤   ¤   ¤   ¤   pKM->iFocusedObjectType = OBJECT_CERT;·
fd8a35 ¤   ¤   ¤   ¤   pKM->uSelectedFlags |= PGPKM_CERTFLAG;
6df622 ¤   ¤   ¤   ¤   break;
790fe4 ¤   ¤   }
9f9371 ¤   }
de665a ¤   else {
220d9f ¤   ¤   pKM->iFocusedItemType = IDX_NONE;
b13c03 ¤   ¤   pKM->iFocusedObjectType = OBJECT_NONE;
5deed3 ¤   ¤   pKM->pFocusedObject = NULL;
ee9371 ¤   }
a9af5a
fc3d18 ¤   sUpdateStatusBarText (pKM);
46efe6 }
4eaf5a
71c8dc //¤ ________________________________________
2d465d //
3b242b //¤ Get type of focused item
f3af5a
45100d INT·
c42d96 KMFocusedItemType (PKEYMAN pKM)·
32bb36 {
d7c4b1 ¤   return pKM->iFocusedItemType;
88efe6 }
f1af5a
8ac8dc //¤ ________________________________________
28465d //
078cb3 //¤ Get type of focused object
a4af5a
1f100d INT·
2f6a12 KMFocusedObjectType (PKEYMAN pKM)·
7abb36 {
a59f7a ¤   return pKM->iFocusedObjectType;
07efe6 }
91af5a
d7c8dc //¤ ________________________________________
5e465d //
d38e39 //¤ Get handle of focused item
00af5a
a4e167 HTLITEM·
1b40ff KMFocusedItem (PKEYMAN pKM)·
c4bb36 {
78693b ¤   return pKM->hFocusedItem;
0defe6 }
33af5a
f6c8dc //¤ ________________________________________
a6465d //
30f16e //¤ Get pointer to focused object
3baf5a
28b2b6 VOID* KMFocusedObject (PKEYMAN pKM)·
0ebb36 {
4f97c0 ¤   return pKM->pFocusedObject;
96efe6 }
0eaf5a
d9c8dc //¤ ________________________________________
dc465d //
8e8cb3 //¤ Get type of focused object
cdaf5a
547efe BOOL·
020204 KMMultipleSelected (PKEYMAN pKM)·
--5eb2 00047204a5d401102a3 Page 4 of KMFocus.c
2cbb36 {
6cf7a7 ¤   return pKM->bMultipleSelected;
f3efe6 }
30af5a
cec8dc //¤ ________________________________________
50465d //
ee8cb3 //¤ Get type of focused object
adaf5a
b444eb UINT·
ee3cb4 KMSelectedFlags (PKEYMAN pKM)·
ffbb36 {
26d526 ¤   return pKM->uSelectedFlags;
9eefe6 }
c6af5a
be4265 //¤ ___________________________________________________
4d465d //
a79932 //¤ Return TRUE if more than one type of object selected
65af5a
867efe BOOL·
74f545 KMPromiscuousSelected (PKEYMAN pKM)·
dbbb36 {
dfd118 ¤   if (!pKM->bMultipleSelected) return FALSE;
73af5a
fc7d34 ¤   switch (pKM->uSelectedFlags) {
a6741e ¤   case 0 :
398696 ¤   case PGPKM_KEYFLAG :
d874b5 ¤   case PGPKM_UIDFLAG :
bb728b ¤   case PGPKM_CERTFLAG :
2b98aa ¤   ¤   return FALSE;
36af5a
9fbfad ¤   default :
68836c ¤   ¤   return TRUE;
529371 ¤   }
c0efe6 }
b0af5a
50c8dc //¤ ________________________________________
65465d //
80b77b //¤ Return TRUE if signing operations allowed
90af5a
ef7efe BOOL·
fc56e4 KMSigningAllowed (PKEYMAN pKM)·
72bb36 {
1366b6 ¤   if ((!pKM->uSelectedFlags) ||·
9cb8e9 ¤   ¤   (pKM->uSelectedFlags & PGPKM_CERTFLAG)) return FALSE;
916e4b ¤   else return TRUE;
d7efe6 }
1caf5a
a19268 //¤ _______________________________________________
ff465d //
660e71 //¤ routines called as callback functions from the·
d512de // ·TreeList control
d4465d //
e9af5a
d03f64 static BOOL CALLBACK·
35af98 sAddKeyToKeySet (
ae9d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
5edd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
cabb36 {
8e568d ¤   SELOBJECTINFO*¤ psoi = (SELOBJECTINFO*)lParam;
021502 ¤   PGPKeyRef¤  ¤   key;
692b4c ¤   PGPKeySetRef¤   newkeyset;
411240 ¤   PGPKeySetRef¤   oldkeyset;
1dfb19 ¤   PGPError¤   ¤   err;
57af5a
ea6919 ¤   switch (lptli->iImage) {
41493d ¤   case IDX_RSAPUBKEY :
706e41 ¤   case IDX_RSAPUBDISKEY :
245b97 ¤   case IDX_RSASECKEY :
d3b4cd ¤   case IDX_RSASECDISKEY :
615b28 ¤   case IDX_DSAPUBKEY :
4f7448 ¤   case IDX_DSAPUBDISKEY :
474982 ¤   case IDX_DSASECKEY :
--cfdd 0003b6a28fe401102a3 Page 5 of KMFocus.c
60aec4 ¤   case IDX_DSASECDISKEY :
b9a6d8 ¤   case IDX_DSASECSHRKEY :
32fe0b ¤   case IDX_RSAPUBREVKEY :
0f5115 ¤   case IDX_RSAPUBEXPKEY :
1a2487 ¤   case IDX_RSASECREVKEY :
9f8b99 ¤   case IDX_RSASECEXPKEY :
dcbcd1 ¤   case IDX_RSASECSHRKEY :
38e402 ¤   case IDX_DSAPUBREVKEY :
0a4b1c ¤   case IDX_DSAPUBEXPKEY :
973e8e ¤   case IDX_DSASECREVKEY :
589190 ¤   case IDX_DSASECEXPKEY :
4814a7 ¤   ¤   key = (PGPKeyRef)(lptli->lParam);
932f68 ¤   ¤   break;
3eaf5a
18b951 ¤   case IDX_RSAUSERID :
0eab44 ¤   case IDX_DSAUSERID :
5e304b ¤   case IDX_PHOTOUSERID :
e25d7a ¤   case IDX_INVALIDUSERID :
e18267 ¤   ¤   key = KMGetKeyFromUserID (psoi->pKM, (PGPUserIDRef)(lptli->lParam));
652f68 ¤   ¤   break;
76af5a
006533 ¤   case IDX_CERT :
411c1f ¤   case IDX_REVCERT :
73a1bf ¤   case IDX_BADCERT :
b68f71 ¤   case IDX_EXPORTCERT :
40c328 ¤   case IDX_TRUSTEDCERT :
6def7c ¤   case IDX_METACERT :
064b29 ¤   ¤   key = KMGetKeyFromCert (psoi->pKM, (PGPSigRef)(lptli->lParam));
c72f68 ¤   ¤   break;
1aaf5a
89bfad ¤   default :
2398aa ¤   ¤   return FALSE;
739371 ¤   }
51af5a
3e3d9c ¤   if (PGPKeyRefIsValid (key)) {
baa1d5 ¤   ¤   if (PGPKeySetRefIsValid (psoi->keysetSelected)) {
36b2c8 ¤   ¤   ¤   err = PGPNewSingletonKeySet (key, &newkeyset);
f26a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
ab76c6 ¤   ¤   ¤   ¤   oldkeyset = psoi->keysetSelected;
91e5af ¤   ¤   ¤   ¤   err = PGPUnionKeySets (oldkeyset,·
bdf95f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   newkeyset, &psoi->keysetSelected);
14e0cd ¤   ¤   ¤   ¤   if (IsntPGPError (err))
342677 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (oldkeyset);
be7dba ¤   ¤   ¤   ¤   PGPFreeKeySet (newkeyset);
7fa3a6 ¤   ¤   ¤   }
d30fe4 ¤   ¤   }
dbaf5a
47bd58 ¤   ¤   ++(psoi->icount);
309371 ¤   }
09af5a
93c2e7 ¤   return TRUE;
d6efe6 }
3eaf5a
abd59e //¤ ___________________________
d0465d //
42bff4 //¤ Get keyset of selected keys
67af5a
9a8de9 PGPError·
616c72 KMGetSelectedKeys (
c5934d ¤   ¤   PKEYMAN¤¤   ¤   pKM,·
8f1716 ¤   ¤   PGPKeySetRef*¤  pkeyset,
01add6 ¤   ¤   INT*¤   ¤   ¤   piCount)·
55bb36 {
5b37df ¤   PGPError¤   ¤   ¤   err¤¤   = kPGPError_NoErr;
1d8232 ¤   SELOBJECTINFO¤  ¤   soi;
fbaf5a
30a1e8 ¤   soi.lpfnCallback¤   = sAddKeyToKeySet;
29cc7c ¤   soi.pKM¤¤   ¤   ¤   = pKM;
88e367 ¤   soi.icount¤ ¤   ¤   = 0;
ffaf5a
e57e1d ¤   if (pkeyset)
3b9575 ¤   ¤   *pkeyset = kInvalidPGPKeySetRef;
--9b93 00120ebfe0c401102a3 Page 6 of KMFocus.c
8feffb ¤   if (piCount)
1fcc43 ¤   ¤   *piCount = 0;
bcaf5a
c27e1d ¤   if (pkeyset)
80f3c2 ¤   ¤   err = PGPNewEmptyKeySet (pKM->KeySetDisp, &(soi.keysetSelected));
fd0e24 ¤   else
342875 ¤   ¤   soi.keysetSelected = NULL;
1caf5a
86b23e ¤   if (IsntPGPError (err)) {
315db9 ¤   ¤   TreeList_IterateSelected (pKM->hWndTree, &soi);
ed3f96 ¤   ¤   if (pkeyset)
0e62fd ¤   ¤   ¤   *pkeyset = soi.keysetSelected;
67ae70 ¤   ¤   if (piCount)
336d83 ¤   ¤   ¤   *piCount = soi.icount;
d59371 ¤   }
2faf5a
ee5ea8 ¤   return err;
44efe6 }
c5af5a
84af5a
20af5a
--594a 0002e265e7e401102a4 Page 1 of KMIDataObject.cpp
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
44f7c1 ¤   KMIDataObject.cpp - implements OLE IDataObject for drag and drop
3fefc0 ¤   to the shell.
02af5a
192506 ¤   $Id: KMIDataObject.cpp,v 1.7 1998/08/13 02:46:08 pbj Exp $
e2f7f7 ____________________________________________________________________________*/
d3e610 #include "pgpPFLConfig.h"
88af5a
25fc2c // system header files
a52032 #include <windows.h>·
67f3cf #include <shlobj.h>
81af5a
04c917 // project header files
409091 #include "KMIDataObject.h"
bc1b7a #include "KMIEnumFormatEtc.h"
8f8031 #include "resource.h"
22af5a
956dad extern "C" {
49ce36 typedef struct _KM *PKEYMAN;
964772 LPSTR KMDropKeysGetData (PKEYMAN pKM, BOOL bForceComplete);
443b60 VOID KMDropKeysFreeData (LPSTR psz);
d6efe6 }
17af5a
4ec8dc //¤ ________________________________________
b2465d //
e9cabc //¤ IUnknown Methods
8daf5a
3a083d STDMETHODIMP CDataObject::QueryInterface (
a7ba44 ¤   ¤   REFIID¤ ¤   ¤   iid,·
f53437 ¤   ¤   void FAR* FAR*¤ ppv)·
68bb36 {
7e6aab ····if ((iid == IID_IUnknown) || (iid == IID_IDataObject)) {
907277 ······*ppv = this;
a9bc36 ······++m_refs;
354323 ······return NOERROR;
6e6fe7 ····}
fde0d5 ····*ppv = NULL;
67af5a
aa2438 ····return E_NOINTERFACE;
21efe6 }
b0af5a
13af5a
86474f STDMETHODIMP_(ULONG) CDataObject::AddRef (void)·
e9bb36 {
9bbd9a ····return ++m_refs;
a7efe6 }
6faf5a
04af5a
0da376 STDMETHODIMP_(ULONG) CDataObject::Release (void)·
b8bb36 {
3dffa3 ¤   if(--m_refs == 0) {
68b4fd ······delete this;
c6c9db ······return 0;
cb6fe7 ····}
7b21aa ····return m_refs;
190acd } ·
78af5a
dcaf5a
5fc8dc //¤ ________________________________________
3b465d //
d16c53 //¤ CDataObject Constructor
dad83c ·
d16658 CDataObject::CDataObject (
93588b ¤   ¤   VOID*¤  pKeyMan,·
d96668 ¤   ¤   LPSTR¤  szName)·
52bb36 {
5b9442 ¤   m_szName = szName;
22d170 ¤   m_szData = NULL;
2e04b4 ¤   m_pKeyMan = pKeyMan;
--e547 00042610bf1401102a4 Page 2 of KMIDataObject.cpp
c0bec9 ····m_refs = 1; ·
29306c ¤   m_cfe = 4;
6baf5a
06224b ¤   m_fe[0].cfFormat = RegisterClipboardFormat (CFSTR_FILEDESCRIPTOR);
67f6ce ¤   m_fe[0].ptd = NULL;
fb1007 ¤   m_fe[0].dwAspect = DVASPECT_CONTENT;
eef633 ¤   m_fe[0].lindex = -1;
abeed6 ¤   m_fe[0].tymed = TYMED_HGLOBAL;
79af5a
455dac ¤   m_fe[1].cfFormat = RegisterClipboardFormat (CFSTR_FILECONTENTS);
49bee4 ¤   m_fe[1].ptd = NULL;
0b6765 ¤   m_fe[1].dwAspect = DVASPECT_CONTENT;
a27823 ¤   m_fe[1].lindex = -1;
5d2386 ¤   m_fe[1].tymed = TYMED_HGLOBAL;
f8af5a
13570e ¤   m_fe[2].cfFormat = RegisterClipboardFormat (CFSTR_PGPCOMPLETEFORMAT);
30669a ¤   m_fe[2].ptd = NULL;
edfec3 ¤   m_fe[2].dwAspect = DVASPECT_CONTENT;
07e202 ¤   m_fe[2].lindex = -1;
0b7c67 ¤   m_fe[2].tymed = TYMED_HGLOBAL;
09af5a
46141e ¤   m_fe[3].cfFormat = CF_TEXT;
e82eb0 ¤   m_fe[3].ptd = NULL;
3889a1 ¤   m_fe[3].dwAspect = DVASPECT_CONTENT;
446c12 ¤   m_fe[3].lindex = -1;
66b137 ¤   m_fe[3].tymed = TYMED_HGLOBAL;
5aefe6 }
42af5a
58c8dc //¤ ________________________________________
c0465d //
eafb0d //¤ CDataObject Destructor
3ad83c ·
1f284d CDataObject::~CDataObject ()·
39bb36 {
15af0c ¤   KMDropKeysFreeData (m_szData);
63efe6 }
35af5a
48c8dc //¤ ________________________________________
a3465d //
a4d1b9 //¤ IDataObject Methods
0faf5a
48c8dc //¤ ________________________________________
a4465d //
8e1e64 //¤ CDataObject::GetData
bbac6a //·
412898 //¤ Purpose:
185382 //¤ ¤   Retrieves data described by a specific FormatEtc into a StgMedium
32d2e4 //¤ ¤   allocated by this function. ·Used like GetClipboardData.
b0465d //
d3b4f6 //¤ Parameters:
d80ec4 //¤ ¤   pFE ············LPFORMATETC describing the desired data.
998256 //¤ ¤   pSTM ···········LPSTGMEDIUM in which to return the data.
a7465d //
9f07c7 //¤ Return Value:
296679 //¤ ¤   HRESULT ········NOERROR or a general error value.
dd465d //
ceaf5a
ca8c9e STDMETHODIMP CDataObject::GetData (
26d34e ¤   ¤   LPFORMATETC¤¤   pFE,·
f80ea7 ¤   ¤   LPSTGMEDIUM ¤   pSTM)·
4dbb36 {
d33d36 ····HGLOBAL hMem;
47abde ¤   LPFILEGROUPDESCRIPTOR pfgd;
a28211 ····UINT uFormat;
aab616 ¤   CHAR* p;
9faf5a
ac60ee ¤   m_uFmtUsed = 0;
4cf487 ¤   uFormat = pFE->cfFormat;
d0af5a
2ab2d6 ¤   // FILEDESCRIPTOR format
fd42fc ¤   if (uFormat == m_fe[0].cfFormat) {¤
42412f ¤   ¤   if (!(pFE->dwAspect & DVASPECT_CONTENT))
--df5f 000539d05b5401102a4 Page 3 of KMIDataObject.cpp
88fbc2 ¤   ¤   ¤   return DV_E_DVASPECT;
9db103 ········if (!(pFE->tymed & TYMED_HGLOBAL))
918a58 ¤   ¤   ¤   return DV_E_FORMATETC;
bbaf5a
66b55f ¤   ····hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE,·
b69802 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(FILEGROUPDESCRIPTOR));
ceaf5a
56bd2b ¤   ¤   if (hMem == NULL) return STG_E_MEDIUMFULL;
efaf5a
b9a503 ¤   ¤   pfgd = (LPFILEGROUPDESCRIPTOR)GlobalLock (hMem);
478727 ¤   ¤   pfgd->cItems = 1;
a89dc7 ¤   ¤   pfgd->fgd[0].dwFlags = FD_ATTRIBUTES;
508558 ¤   ¤   pfgd->fgd[0].dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
4594b3 ¤   ¤   lstrcpy (pfgd->fgd[0].cFileName, m_szName);
c4af5a
e8eb4a ¤   ¤   GlobalUnlock (hMem);
10af5a
a885d5 ¤   ¤   pSTM->hGlobal = hMem;
1f1dc1 ¤   ¤   pSTM->tymed = TYMED_HGLOBAL;
3fd8c6 ¤   ¤   pSTM->pUnkForRelease = NULL;
eeea89 ¤   ¤   m_uFmtUsed = uFormat;
409731 ¤   ¤   return S_OK;¤
069371 ¤   }
3daf5a
1994ea ¤   // FILECONTENTS clipboard format
adbbd9 ¤   else if (uFormat == m_fe[1].cfFormat) {¤
57412f ¤   ¤   if (!(pFE->dwAspect & DVASPECT_CONTENT))
d8fbc2 ¤   ¤   ¤   return DV_E_DVASPECT;
64b103 ········if (!(pFE->tymed & TYMED_HGLOBAL))
438a58 ¤   ¤   ¤   return DV_E_FORMATETC;
24af5a
86e27c ¤   ¤   if (!m_szData)·
1bfdfe ¤   ¤   ¤   m_szData = KMDropKeysGetData ((PKEYMAN)m_pKeyMan, FALSE);
83af5a
0f3236 ¤   ····hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, lstrlen(m_szData)+1);
6faf5a
bebd2b ¤   ¤   if (hMem == NULL) return STG_E_MEDIUMFULL;
8caf5a
14ac09 ¤   ¤   p = (LPSTR) GlobalLock (hMem);
92bd41 ¤   ¤   lstrcpy (p, m_szData);
21eb4a ¤   ¤   GlobalUnlock (hMem);
6caf5a
bb85d5 ¤   ¤   pSTM->hGlobal = hMem;
2b1dc1 ¤   ¤   pSTM->tymed = TYMED_HGLOBAL;
8ed8c6 ¤   ¤   pSTM->pUnkForRelease = NULL;
04ea89 ¤   ¤   m_uFmtUsed = uFormat;
799731 ¤   ¤   return S_OK;¤
8c9371 ¤   }
9aaf5a
321330 ¤   // CFSTR_PGPCOMPLETEFORMAT clipboard format
b7b65e ¤   else if (uFormat == m_fe[2].cfFormat) {
7e6b5e ¤   ¤   if (pFE->lindex != -1) return DV_E_LINDEX;
4f412f ¤   ¤   if (!(pFE->dwAspect & DVASPECT_CONTENT))
85fbc2 ¤   ¤   ¤   return DV_E_DVASPECT;
bcb103 ········if (!(pFE->tymed & TYMED_HGLOBAL))
b48a58 ¤   ¤   ¤   return DV_E_FORMATETC;
73af5a
8fe27c ¤   ¤   if (!m_szData)·
d2a635 ¤   ¤   ¤   m_szData = KMDropKeysGetData ((PKEYMAN)m_pKeyMan, TRUE);
47af5a
823236 ¤   ····hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, lstrlen(m_szData)+1);
baaf5a
b7bd2b ¤   ¤   if (hMem == NULL) return STG_E_MEDIUMFULL;
aaaf5a
8cac09 ¤   ¤   p = (LPSTR) GlobalLock (hMem);
a2bd41 ¤   ¤   lstrcpy (p, m_szData);
86eb4a ¤   ¤   GlobalUnlock (hMem);
5faf5a
f085d5 ¤   ¤   pSTM->hGlobal = hMem;
c61dc1 ¤   ¤   pSTM->tymed = TYMED_HGLOBAL;
75d8c6 ¤   ¤   pSTM->pUnkForRelease = NULL;
53ea89 ¤   ¤   m_uFmtUsed = uFormat;
--a480 000a6ec4caa401102a4 Page 4 of KMIDataObject.cpp
2d9731 ¤   ¤   return S_OK;¤
c89371 ¤   }
47af5a
6dba6a ¤   // TEXT clipboard format
3b679f ¤   else if (uFormat == CF_TEXT) {
4c6b5e ¤   ¤   if (pFE->lindex != -1) return DV_E_LINDEX;
93412f ¤   ¤   if (!(pFE->dwAspect & DVASPECT_CONTENT))
fafbc2 ¤   ¤   ¤   return DV_E_DVASPECT;
0ab103 ········if (!(pFE->tymed & TYMED_HGLOBAL))
a08a58 ¤   ¤   ¤   return DV_E_FORMATETC;
44af5a
bbe27c ¤   ¤   if (!m_szData)·
78fdfe ¤   ¤   ¤   m_szData = KMDropKeysGetData ((PKEYMAN)m_pKeyMan, FALSE);
3daf5a
ed3236 ¤   ····hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, lstrlen(m_szData)+1);
ccaf5a
45bd2b ¤   ¤   if (hMem == NULL) return STG_E_MEDIUMFULL;
95af5a
9fac09 ¤   ¤   p = (LPSTR) GlobalLock (hMem);
9cbd41 ¤   ¤   lstrcpy (p, m_szData);
90eb4a ¤   ¤   GlobalUnlock (hMem);
45af5a
2985d5 ¤   ¤   pSTM->hGlobal = hMem;
f71dc1 ¤   ¤   pSTM->tymed = TYMED_HGLOBAL;
29d8c6 ¤   ¤   pSTM->pUnkForRelease = NULL;
afea89 ¤   ¤   m_uFmtUsed = uFormat;
259731 ¤   ¤   return S_OK;¤
849371 ¤   }
27af5a
590a2e ····return DV_E_FORMATETC;
efefe6 }
7daf5a
dcaf5a
81c8dc //¤ ________________________________________
86465d //
bbdf48 //¤ CDataObject::GetDataHere
7c465d //
132898 //¤ Purpose:
f7f6ff //¤ ¤   Renders the specific FormatEtc into caller-allocated medium
af0dde //¤ ¤   provided in pSTM.
40465d //
02b4f6 //¤ Parameters:
cd0ec4 //¤ ¤   pFE ············LPFORMATETC describing the desired data.
77997c //¤ ¤   pSTM ···········LPSTGMEDIUM providing the medium into which
a92852 //¤ ¤   ¤   ¤   ¤   ¤   we render the data.
55465d //
6107c7 //¤ Return Value:
3c6679 //¤ ¤   HRESULT ········NOERROR or a general error value.
a1465d //
c6af5a
4d5d57 STDMETHODIMP CDataObject::GetDataHere (
a21f00 ¤   ¤   LPFORMATETC ¤   pFE,·
a70ea7 ¤   ¤   LPSTGMEDIUM ¤   pSTM)·
25bb36 {
bbfe4a ····//Check the aspects we support.
4186c3 ····if (!(pFE->dwAspect & DVASPECT_CONTENT))
0a2ee4 ········return DV_E_DVASPECT;
24af5a
0cb3ec ¤   if (pFE->lindex != -1) return DV_E_LINDEX;
4daf5a
1a0a2e ····return DV_E_FORMATETC;
d1efe6 }
e4af5a
b0af5a
dbc8dc //¤ ________________________________________
cb465d //
322c97 //¤ CDataObject::QueryGetData
96465d //
da2898 //¤ Purpose:
ccd258 //¤ ¤   Tests if a call to GetData with this FormatEtc will provide
bd0312 //¤ ¤   any rendering; used like IsClipboardFormatAvailable.
a6465d //
--1f2b 0006e3b06fa401102a4 Page 5 of KMIDataObject.cpp
b4b4f6 //¤ Parameters:
110ec4 //¤ ¤   pFE ············LPFORMATETC describing the desired data.
96465d //
d107c7 //¤ Return Value:
606679 //¤ ¤   HRESULT ········NOERROR or a general error value.
8c465d //
67af5a
93450e STDMETHODIMP CDataObject::QueryGetData (LPFORMATETC pFE)·
6fbb36 {
17ea13 ····UINT uFormat = pFE->cfFormat;
85823d ····BOOL bRet = FALSE;
76af5a
5ffe4a ····//Check the aspects we support.
8e86c3 ····if (!(pFE->dwAspect & DVASPECT_CONTENT))
532ee4 ········return DV_E_DVASPECT;
1caf5a
ef00de ¤   if (uFormat == m_fe[0].cfFormat) {¤ ¤   ¤   // filegroupdescriptor
7ab357 ¤   ¤   bRet = (BOOL)(pFE->tymed & TYMED_HGLOBAL);
759371 ¤   }
8adf2d ¤   else if (uFormat == m_fe[1].cfFormat) {¤¤   // filecontents
acb357 ¤   ¤   bRet = (BOOL)(pFE->tymed & TYMED_HGLOBAL);
859371 ¤   }
0d7810 ¤   else if (uFormat == m_fe[2].cfFormat) {¤¤   // private PGP format
7c6b5e ¤   ¤   if (pFE->lindex != -1) return DV_E_LINDEX;
d6b357 ¤   ¤   bRet = (BOOL)(pFE->tymed & TYMED_HGLOBAL);
599371 ¤   }
53679f ¤   else if (uFormat == CF_TEXT) {
2b6b5e ¤   ¤   if (pFE->lindex != -1) return DV_E_LINDEX;
c4b357 ¤   ¤   bRet = (BOOL)(pFE->tymed & TYMED_HGLOBAL);
ce9371 ¤   }
35af5a
1f3d95 ¤   else bRet = FALSE;
4aaf5a
3d74b7 ····return (bRet ? S_OK : DV_E_FORMATETC);
07efe6 }
c0af5a
eaaf5a
35c8dc //¤ ________________________________________
5e465d //
525e21 //¤ CDataObject::EnumFormatEtc
6e465d //
7a2898 //¤ Purpose:
724bbc //¤ ¤   Returns an IEnumFORMATETC object through which the caller can
36d858 //¤ ¤   iterate to learn about all the data formats this object can
f1b185 //¤ ¤   provide through either GetData[Here] or SetData.
a2465d //
35b4f6 //¤ Parameters:
d254d1 //¤ ¤   dwDir ··········DWORD describing a data direction, either
9d1ba0 //¤ ¤   ¤   ¤   ¤   ¤   DATADIR_SET or DATADIR_GET.
0b8c22 //¤ ¤   ppEnum ·········LPENUMFORMATETC * in which to return the
451349 //¤ ¤   ¤   ¤   ¤   ¤   pointer to the enumerator.
ba465d //
5307c7 //¤ Return Value:
186679 //¤ ¤   HRESULT ········NOERROR or a general error value.
4b465d //
95af5a
4ea708 STDMETHODIMP CDataObject::EnumFormatEtc (
967962 ¤   ¤   DWORD¤  ¤   ¤   ¤   dwDir,·
810625 ¤   ¤   LPENUMFORMATETC*¤   ppEnum)·
46bb36 {
b37217 ····switch (dwDir) {
63dd9c ····case DATADIR_GET:
e4418f ········*ppEnum = new CEnumFormatEtc (m_cfe, &m_fe[0]);
772d5f ········break;
ceaf5a
d144cc ····case DATADIR_SET:
60649c ········*ppEnum = NULL;
7a2d5f ········break;
73af5a
a2b53c ····default:
55649c ········*ppEnum = NULL;
6e2d5f ········break;
--3e1c 0009f4ca9a0401102a4 Page 6 of KMIDataObject.cpp
9f6fe7 ····}
86af5a
a7c4d2 ····if (*ppEnum == NULL) return E_NOTIMPL;
3eaf5a
3fefa0 ····return S_OK;
2cefe6 }
58af5a
99af5a
f0c8dc //¤ ________________________________________
54465d //
c3289e //¤ Unimplemented methods·
4aaf5a
8fe9ca STDMETHODIMP CDataObject::DAdvise (
efd34e ¤   ¤   LPFORMATETC¤¤   pFE,·
118e96 ¤   ¤   DWORD ¤ ¤   ¤   dwFlags,·
89694e ¤   ¤   LPADVISESINK ¤  pIAdviseSink,·
947312 ¤   ¤   LPDWORD ¤   ¤   pdwConn)·
7bbb36 {
489abd ····return OLE_E_ADVISENOTSUPPORTED;
a4efe6 }
f0af5a
270b8d STDMETHODIMP CDataObject::DUnadvise (DWORD dwConn) {
069abd ····return OLE_E_ADVISENOTSUPPORTED;
efefe6 }
f5af5a
e2dd6c STDMETHODIMP CDataObject::EnumDAdvise (LPENUMSTATDATA *ppEnum) {
619abd ····return OLE_E_ADVISENOTSUPPORTED;
b1efe6 }
16af5a
d19cd1 STDMETHODIMP CDataObject::SetData (LPFORMATETC pFE, LPSTGMEDIUM pSTM,·
befbbb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···BOOL fRelease) {
5db6be ····return E_NOTIMPL;
2aefe6 }
a1af5a
ee109e STDMETHODIMP CDataObject::GetCanonicalFormatEtc (LPFORMATETC pFEIn,·
707f2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPFORMATETC pFEOut) {
5fe50d ¤   pFEOut->ptd = NULL;
77b6be ····return E_NOTIMPL;
c7efe6 }
19af5a
0caf5a
64c8dc //¤ ________________________________________
ab465d //
78611e //¤ get format used to render data ·
4faf5a
5773db BOOL CDataObject::OKToDelete (void)·
57bb36 {
49f8a5 ¤   if ((m_uFmtUsed == CF_TEXT) ||
fb395e ¤   ¤   (m_uFmtUsed == m_fe[2].cfFormat))
6498aa ¤   ¤   return FALSE;
244264 ¤   else·
99836c ¤   ¤   return TRUE;
bbefe6 }
99af5a
09af5a
2dc8dc //¤ ________________________________________
b5465d //
e3e21b //¤ Interface to C code·
acaf5a
d46dad extern "C" {
ac1a84 LPDATAOBJECT KMCreateDataObject (
23232b ¤   ¤   VOID* ¤ pKeyMan,·
4b0190 ¤   ¤   LPSTR ¤ szName)·
a5bb36 {
40c5ea ···return ((LPDATAOBJECT) new CDataObject (pKeyMan, szName));
acefe6 }
68af5a
2e1a2c BOOL KMOKToDeleteDataObject (CDataObject* pDataObject)·
05bb36 {
a09daf ¤   return (pDataObject->OKToDelete ());
f3efe6 }
9faf5a
--c34d 0010e631b23401102a4 Page 7 of KMIDataObject.cpp
0ebe43 }¶
--b682 001ab625a74401102a5 Page 1 of KMIDataObject.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
be422c ¤   KMIDataObject.h - implements OLE IDataObject for drag and drop
20efc0 ¤   to the shell.
5caf5a
da8b58 ¤   $Id: KMIDataObject.h,v 1.5 1998/08/13 02:46:08 pbj Exp $
85f7f7 ____________________________________________________________________________*/
1aaf5a
bbed0b #define CFSTR_PGPCOMPLETEFORMAT¤¤   ("PGP_COMPLETE60KEYFORMAT")
0aaf5a
f9ae09 class FAR CDataObject : public IDataObject
7dbb36 {
50dd93 public: ···
4b3830 ····CDataObject(LPVOID, LPSTR);
acab9e ¤   ~CDataObject ();
ecc0b3 ¤   BOOL OKToDelete (void);
3aaf5a
35c86e ····/* IUnknown methods */
2aa5a5 ····STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
665d7f ····STDMETHOD_(ULONG, AddRef)(void);
2269f5 ····STDMETHOD_(ULONG, Release)(void);
f4af5a
932e8b ····/* IDataObject methods */
561a1c ¤   /* NB: these are the subset of IDataObject methods required for D'n'D */
4eef87 ¤   STDMETHODIMP GetData (LPFORMATETC, LPSTGMEDIUM);
5e8423 ····STDMETHODIMP GetDataHere (LPFORMATETC, LPSTGMEDIUM);
47c2d3 ····STDMETHODIMP QueryGetData (LPFORMATETC);
c3e97e ····STDMETHODIMP EnumFormatEtc (DWORD, LPENUMFORMATETC *);
37af5a
30171f ¤   /* ·IDataObject methods not required for Drag and Drop */
2abb5d ····STDMETHODIMP GetCanonicalFormatEtc (LPFORMATETC,LPFORMATETC);
ec9981 ····STDMETHODIMP SetData (LPFORMATETC, LPSTGMEDIUM, BOOL);
4514f6 ····STDMETHODIMP DAdvise (LPFORMATETC, DWORD, ·LPADVISESINK, DWORD *);
a395f8 ····STDMETHODIMP DUnadvise (DWORD);
7c8659 ····STDMETHODIMP EnumDAdvise (LPENUMSTATDATA *);
c3d83c ·
f20fb9 private:
6ee4c5 ¤   LPSTR m_szName;
789468 ¤   LPSTR m_szData;
3ce3c0 ····ULONG m_refs; ·
cd9477 ¤   ULONG m_cfe;¤   ¤   ¤   // number of FORMATETC structs
582808 ¤   FORMATETC m_fe[4];¤ ¤   // pointer to FORMATETC structs
5b45e1 ¤   UINT ·m_uFmtUsed;¤  ¤   // format used to actually render object
c50a4b ¤   VOID* m_pKeyMan;
b33e67 }; ·
abaf5a
--b772 0009b89d479401102a6 Page 1 of KMIDropSource.cpp
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
577f2c ¤   KMIDropSource.cpp - implements OLE IDropSource for drag and drop
14af5a
2aa6a0 ¤   $Id: KMIDropSource.cpp,v 1.11 1998/08/11 14:43:26 pbj Exp $
63f7f7 ____________________________________________________________________________*/
b0e610 #include "pgpPFLConfig.h"
b7af5a
1afc2c // system header files
995655 #include <windows.h>
a790fb #include <commctrl.h>
54af5a
10c917 // project header files
845992 #include "KMIDropSource.h"
f28031 #include "resource.h"
fb8af7 #include "..\include\pgpImage.h"
babeb4 #include "..\include\treelist.h"
96af5a
5f6dad extern "C" {
f7ce36 typedef struct _KM *PKEYMAN;
a09cad extern HINSTANCE g_hInst;
a532c4 VOID KMFindWindowFromPoint (PKEYMAN pKM, POINT* ppt, HWND* phwnd);
28efe6 }
3faf5a
82c8dc //¤ ________________________________________
93465d //
cfcabc //¤ IUnknown Methods
57af5a
05847b STDMETHODIMP CDropSource::QueryInterface (
8ea1ff ¤   ¤   REFIID ¤¤   ¤   iid,·
ac0060 ¤   ¤   void FAR* FAR* ¤ppv)·
febb36 {
1b5760 ¤   if ((iid == IID_IUnknown) || (iid == IID_IDropSource)) {
5888be ¤   ¤   *ppv = this;
c2ce33 ¤   ¤   ++m_refs;
3854df ¤   ¤   return NOERROR;
cc9371 ¤   }
5ba223 ¤   *ppv = NULL;
aaaf5a
cdc4a0 ¤   return E_NOINTERFACE;
c5efe6 }
4faf5a
f3af5a
223fa1 STDMETHODIMP_(ULONG) CDropSource::AddRef (void)·
e2bb36 {
4c32e5 ¤   return ++m_refs;
3aefe6 }
08af5a
0daf5a
3fad7e STDMETHODIMP_(ULONG) CDropSource::Release (void)·
b1bb36 {
e49346 ¤   if (--m_refs == 0) {
964e34 ¤   ¤   delete this;
54bbde ¤   ¤   return 0;
629371 ¤   }
ef6864 ¤   return m_refs;
730acd } ·
f4af5a
81af5a
bfc8dc //¤ ________________________________________
0d465d //
0f5eb4 //¤ calculate cursor offsets
b0af5a
a7e6b2 static VOID
65b635 sCalcOffsets (
531cf6 ¤   ¤   HWND ¤  hwnd,·
917422 ¤   ¤   ULONG* ¤pulXOff,·
6f89f0 ¤   ¤   ULONG* ¤pulYOff)
1dbb36 {
9bd661 ¤   NONCLIENTMETRICS¤   ncm;
--65cb 0009b73392b401102a6 Page 2 of KMIDropSource.cpp
e0af5a
fbea15 ¤   // get offset number to convert client to window coordinates
f4bbff ¤   ncm.cbSize = sizeof(NONCLIENTMETRICS);
a13aec ¤   SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
842286 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ncm, 0);
644000 ¤   *pulXOff = ncm.iBorderWidth;
c6cd3b ¤   *pulYOff = ncm.iBorderWidth + ncm.iCaptionHeight;
af38e4 ¤   if (GetMenu (hwnd))
1e2f5b ¤   ¤   *pulYOff += ncm.iMenuHeight;
a4efe6 }
9fd83c ·
7ec8dc //¤ ________________________________________
86465d //
6bb844 //¤ CDropSource Constructor
c7d83c ·
5420ac CDropSource::CDropSource (
4a588b ¤   ¤   VOID*¤  pKeyMan,·
a2c2d2 ¤   ¤   HWND¤   hwnd,·
b7d99d ¤   ¤   HWND¤   hwndTree)·
09bb36 {
4447fb ¤   HIMAGELIST¤ ¤   ¤   hIml;
63a44e ¤   TL_DRAGBITMAP¤  ¤   tldb;
1faf5a
a3203a ····m_refs = 1;·
4dd88f ¤   m_hwnd = hwnd;
3a04b4 ¤   m_pKeyMan = pKeyMan;
67af5a
52a023 ¤   sCalcOffsets (hwnd, &m_ncxoffset, &m_ncyoffset);
d2af5a
310f6d ¤   GetCursorPos (&tldb.ptCursorPos);
ba93e6 ¤   ScreenToClient (hwndTree, &tldb.ptCursorPos);
ce69f9 ¤   tldb.ulFlags = TLRB_TOPLEVELONLY;
8fa05d ¤   TreeList_RenderDragBitmap (hwndTree, &tldb);
0c8e31 ¤   hIml = ImageList_Create (tldb.sizeDrag.cx, tldb.sizeDrag.cy,·
1a6268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILC_MASK|ILC_COLORDDB, 1, 1);
d2043a ¤   ImageList_AddMasked (hIml, tldb.hbmDrag, GetSysColor (COLOR_WINDOW));
cf1cb0 ¤   DeleteObject (tldb.hbmDrag);
d3d83c ·
dce197 ¤   ImageList_BeginDrag (hIml, 0, tldb.ptHotSpot.x, tldb.ptHotSpot.y);
95add3 ¤   ImageList_Destroy (hIml);
c8af5a
120f6d ¤   GetCursorPos (&tldb.ptCursorPos);
c8b3ba ¤   ScreenToClient (hwnd, &tldb.ptCursorPos);
a720e1 ¤   ImageList_DragEnter (hwnd, tldb.ptCursorPos.x + m_ncxoffset,·
007c9d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tldb.ptCursorPos.y + m_ncyoffset);
b6efe6 }
95af5a
f2929f CDropSource::~CDropSource()·
50bb36 {
a9a802 ¤   ImageList_DragLeave (m_hwnd);
97952e ¤   ImageList_EndDrag ();
26efe6 }
85af5a
48af5a
a5c8dc //¤ ________________________________________
13465d //
830ecf //¤ IDropSource Methods
7daf5a
1ae11a STDMETHODIMP CDropSource::QueryContinueDrag (
d76e41 ¤   ¤   BOOL¤   fEscapePressed,·
6815e6 ¤   ¤   DWORD¤  grfKeyState)·
184157 { ·
668adb ····if (fEscapePressed)
806c54 ········return DRAGDROP_S_CANCEL;
d28ebb ····else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
5d4151 ········return DRAGDROP_S_DROP;
dc842c ····else
c4d232 ········return NOERROR; ·················
30efe6 }
52af5a
4c157b STDMETHODIMP CDropSource::GiveFeedback (DWORD dwEffect)·
9bbb36 {
--b9ac 001e5ac9d93401102a6 Page 3 of KMIDropSource.cpp
24a360 ¤   POINT¤  pt;
bc72e3 ¤   HWND¤   hwnd;
eb0686 ¤   RECT¤   rc;
42af5a
e2ffbc ¤   GetCursorPos (&pt);
53af5a
5b2730 ¤   GetWindowRect (m_hwnd, &rc);
8ef581 ¤   if (!PtInRect (&rc, pt)) {
1dbbbf ¤   ¤   hwnd = NULL;
9bdfe2 ¤   ¤   KMFindWindowFromPoint ((PKEYMAN)m_pKeyMan, &pt, &hwnd);
ddaf5a
e46be2 ¤   ¤   if (hwnd != m_hwnd) {
2a7b9f ¤   ¤   ¤   ImageList_DragLeave (m_hwnd);
790187 ¤   ¤   ¤   m_hwnd = hwnd;
bfe2ab ¤   ¤   ¤   if (m_hwnd) {
b1338c ¤   ¤   ¤   ¤   sCalcOffsets (hwnd, &m_ncxoffset, &m_ncyoffset);
691223 ¤   ¤   ¤   ¤   ScreenToClient (m_hwnd, &pt);
4a91b0 ¤   ¤   ¤   ¤   ImageList_DragEnter (m_hwnd,·
d774e4 ¤   ¤   ¤   ¤   ¤   ¤   pt.x + m_ncxoffset, pt.y + m_ncyoffset);
90a3a6 ¤   ¤   ¤   }
ba0fe4 ¤   ¤   }
889371 ¤   }
fcaf5a
600995 ¤   if (!(dwEffect & DROPEFFECT_SCROLL)) {
221708 ¤   ¤   ScreenToClient (m_hwnd, &pt);
eafa81 ¤   ¤   ImageList_DragMove (pt.x + m_ncxoffset, pt.y + m_ncyoffset);
129371 ¤   }
d8af5a
aed316 ¤   return DRAGDROP_S_USEDEFAULTCURSORS;
67efe6 }
b3af5a
14af5a
c0c8dc //¤ ________________________________________
b8465d //
36e21b //¤ Interface to C code·
dfaf5a
406dad extern "C" {
cb9878 LPDROPSOURCE KMCreateDropSource (
c0232b ¤   ¤   VOID* ¤ pKeyMan,·
911cf6 ¤   ¤   HWND ¤  hwnd,·
e1bb36 ¤   ¤   HWND ¤  hwndTree)·
0cbb36 {
dad7e1 ···return ((LPDROPSOURCE) new CDropSource (pKeyMan, hwnd, hwndTree));
29efe6 }
79efe6 }
e5af5a
--30fa 0016f7ede11401102a7 Page 1 of KMIDropSource.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
577f2c ¤   KMIDropSource.cpp - implements OLE IDropSource for drag and drop
14af5a
c2a4d3 ¤   $Id: KMIDropSource.h,v 1.6 1998/08/11 14:43:27 pbj Exp $
5af7f7 ____________________________________________________________________________*/
08af5a
dd8696 class FAR CDropSource : public IDropSource
b0bb36 {
08dd93 public: ···
862d77 ····CDropSource(VOID* pKeyMan, HWND hwnd, HWND hwndTree);
f099cc ¤   ~CDropSource ();
d9af5a
08c86e ····/* IUnknown methods */
8ca5a5 ····STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
d15d7f ····STDMETHOD_(ULONG, AddRef)(void);
4669f5 ····STDMETHOD_(ULONG, Release)(void);
21af5a
f9a479 ····/* IDropSource methods */
c217d8 ····STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState);
538cb7 ····STDMETHOD(GiveFeedback)(DWORD dwEffect);
7ad83c ·
fc0fb9 private:
2cba01 ····ULONG¤  ¤   m_refs;
a8e0c7 ¤   HWND¤   ¤   m_hwnd;
a7693a ¤   ULONG¤  ¤   m_ncyoffset;
c224c7 ¤   ULONG¤  ¤   m_ncxoffset;
d15cc3 ¤   VOID*¤  ¤   m_pKeyMan;
ce3e67 }; ·
6faf5a
--01a2 00067d99077401102a8 Page 1 of KMIDropTarget.cpp
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
e9f69a ¤   KMIDropTarget.cpp - implements OLE IDropTarget for drag and drop
e8af5a
a93a42 ¤   $Id: KMIDropTarget.cpp,v 1.8 1998/08/13 02:46:09 pbj Exp $
24f7f7 ____________________________________________________________________________*/
78e610 #include "pgpPFLConfig.h"
7faf5a
30fc2c // system header files
785655 #include <windows.h>
cf90fb #include <commctrl.h>
96af5a
c3c917 // project header files
1b3828 #include "KMIDropTarget.h"
4b9091 #include "KMIDataObject.h"
52af5a
9c6dad extern "C" {
b0ce36 typedef struct _KM *PKEYMAN;
e09a00 typedef struct _PSKS *PSKS;
aac28f BOOL KMDropKeys (PKEYMAN pKM, HANDLE hMem);
2ac700 BOOL KMImportKey (PKEYMAN pKM, HANDLE hMem);
b943d8 BOOL KMSplitDropKeys (PSKS psks, HANDLE hMem);
33efe6 }
daaf5a
5ac8dc //¤ ________________________________________
cd465d //
89cabc //¤ IUnknown Methods
98af5a
bf0d2f STDMETHODIMP CDropTarget::QueryInterface (
f0ba44 ¤   ¤   REFIID¤ ¤   ¤   iid,·
ad3437 ¤   ¤   void FAR* FAR*¤ ppv)·
34bb36 {
094249 ····if ((iid == IID_IUnknown) || (iid == IID_IDropTarget)) {
d37277 ······*ppv = this;
21bc36 ······++m_refs;
134323 ······return NOERROR;
286fe7 ····}
6ce0d5 ····*ppv = NULL;
a2af5a
042438 ····return E_NOINTERFACE;
e7efe6 }
93af5a
2caf5a
70c9c4 STDMETHODIMP_(ULONG) CDropTarget::AddRef (void)·
c1bb36 {
b7bd9a ····return ++m_refs;
d1efe6 }
e8af5a
deaf5a
da9923 STDMETHODIMP_(ULONG) CDropTarget::Release (void)·
d4bb36 {
7c3dd1 ····if (--m_refs == 0) {
1bb4fd ······delete this;
9dc9db ······return 0;
f46fe7 ····}
6021aa ····return m_refs;
d80acd } ·
abaf5a
8caf5a
07c8dc //¤ ________________________________________
c6465d //
2bc2b0 //¤ CDropTarget Constructor
1bd83c ·
a16e0f CDropTarget::CDropTarget (
541cf6 ¤   ¤   HWND ¤  hwnd,·
5d232b ¤   ¤   VOID* ¤ pKeyMan,·
b816e6 ¤   ¤   VOID* ¤ pSplitStruct)·
d7bb36 {
b0bec9 ····m_refs = 1; ·
67d88f ¤   m_hwnd = hwnd;
--c3ce 000a521dcb5401102a8 Page 2 of KMIDropTarget.cpp
9d3653 ¤   m_bAcceptFmt = FALSE;
717aba ¤   m_bEnabled = FALSE;
8404b4 ¤   m_pKeyMan = pKeyMan;
939b66 ¤   m_pSplitStruct = pSplitStruct;
deefe6 }
01af5a
c5af5a
82c8dc //¤ ________________________________________
fc465d //
353b28 //¤ Enable/disable dropping. ·Used when dragging a key out
01982b //¤ of key manager.
61d83c ·
ff62d8 void CDropTarget::Enable (BOOL bEnable)·
2abb36 {
e79ce0 ····m_bEnabled = bEnable; ·
7fefe6 }
06af5a
efaf5a
d4c8dc //¤ ________________________________________
69465d //
b499bc //¤ IDropTarget Methods
87af5a
795729 STDMETHODIMP CDropTarget::DragEnter (
b36043 ¤   ¤   LPDATAOBJECT¤   pDataObj,·
0a6e32 ¤   ¤   DWORD ¤ ¤   ¤   grfKeyState,·
fa1141 ¤   ¤   POINTL ¤¤   ¤   pt,·
06bb15 ¤   ¤   LPDWORD ¤   ¤   pdwEffect)·
ac4157 { ·
1f7cf1 ¤   FORMATETC fmtetc;
2d869e ····
d70494 ¤   // default to not allowing drop
443653 ¤   m_bAcceptFmt = FALSE;
95f83f ·¤  *pdwEffect = DROPEFFECT_NONE;
8eaf5a
b534a4 ¤   if (!m_bEnabled) {
cd54df ¤   ¤   return NOERROR;
469371 ¤   }
72af5a
c06c7c ¤   // Does the drag source provide CF_TEXT? ····
802c8c ¤   fmtetc.cfFormat = CF_TEXT;
c9070a ¤   fmtetc.ptd ·····= NULL;
8c5821 ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
74b4a6 ¤   fmtetc.lindex ··= -1;
2729af ¤   fmtetc.tymed ···= TYMED_HGLOBAL;·
b2869e ····
0afdf8 ¤   if (pDataObj->QueryGetData (&fmtetc) == NOERROR) {
1c1c2a ¤   ¤   m_bAcceptFmt = TRUE;
199a88 ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
989371 ¤   }
4ee8c6 ···
20168f ¤   if (m_pKeyMan) {
f5304c ¤   ¤   // Does the drag source provide CF_HDROP? ····
2ca61b ¤   ¤   fmtetc.cfFormat = CF_HDROP;
2caa54 ¤   ¤   fmtetc.ptd ·····= NULL;
4461e4 ¤   ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
053df2 ¤   ¤   fmtetc.lindex ··= -1;
ce1541 ¤   ¤   fmtetc.tymed ···= TYMED_HGLOBAL;·
29da86 ¤   ····
d5fac3 ¤   ¤   if (pDataObj->QueryGetData (&fmtetc) == NOERROR) {
61a77c ¤   ¤   ¤   m_bAcceptFmt = TRUE;
faa666 ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
3a0fe4 ¤   ¤   }
299371 ¤   }
95e8c6 ···
bd2e2b ¤   return NOERROR;
63efe6 }
72af5a
4eaf5a
8adfbf STDMETHODIMP CDropTarget::DragOver (
262c5b ¤   ¤   DWORD¤  grfKeyState,·
a6d2c6 ¤   ¤   POINTL¤ pt,·
a5be08 ¤   ¤   LPDWORD¤pdwEffect)·
--a5f3 00083124667401102a8 Page 3 of KMIDropTarget.cpp
2cbb36 {
baa025 ¤   if (m_bAcceptFmt && m_bEnabled) *pdwEffect = DROPEFFECT_COPY;·
1d3829 ¤   else *pdwEffect = DROPEFFECT_NONE;·
f62e2b ¤   return NOERROR;
81efe6 }
90af5a
27af5a
c8856e STDMETHODIMP CDropTarget::DragLeave ()·
0c0337 { ··
640373 ¤   m_bAcceptFmt = FALSE; ··
bba802 ¤   ImageList_DragLeave (m_hwnd);
362e2b ¤   return NOERROR;
edefe6 }
86af5a
ccaf5a
95208b STDMETHODIMP CDropTarget::Drop (
376043 ¤   ¤   LPDATAOBJECT¤   pDataObj,·
446e32 ¤   ¤   DWORD ¤ ¤   ¤   grfKeyState,·
691141 ¤   ¤   POINTL ¤¤   ¤   pt,·
bcbb15 ¤   ¤   LPDWORD ¤   ¤   pdwEffect)·
030337 { ··
4b020a ¤   FORMATETC fmtetc; ··
ea9541 ¤   STGMEDIUM medium; ··
fe9627 ¤   HGLOBAL hGlobal;
85094a ¤   HRESULT hr;
e7583d ·····
6d0df1 ¤   *pdwEffect = DROPEFFECT_NONE;
d73211 ¤   hr = NOERROR;
95af5a
5ee5e6 ¤   if (m_bAcceptFmt && m_bEnabled) { ·····
dc7c5e ¤   ¤   // User has dropped on us. First, try getting data in the·
23c6f4 ¤   ¤   // private PGP format which is always a complete representation·
d67623 ¤   ¤   // of the key(s)
0efc37 ¤   ¤   fmtetc.cfFormat = RegisterClipboardFormat (CFSTR_PGPCOMPLETEFORMAT);
889cd0 ¤   ¤   fmtetc.ptd = NULL;
2d61e4 ¤   ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
100fa6 ¤   ¤   fmtetc.lindex = -1;
a9d16f ¤   ¤   fmtetc.tymed = TYMED_HGLOBAL; ······
cf508e ········
19376e ¤   ¤   hr = pDataObj->GetData (&fmtetc, &medium);
dac1cf ¤   ¤   if (!FAILED(hr)) {
c528cf ¤   ¤   // Import the data and release it.
5d450d ¤   ¤   ¤   hGlobal = medium.hGlobal;
a9d0e4 ¤   ¤   ¤   if (m_pKeyMan)
f26ee5 ¤   ¤   ¤   ¤   KMDropKeys ((PKEYMAN)m_pKeyMan, hGlobal);
f8bb8c ¤   ¤   ¤   else
557b68 ¤   ¤   ¤   ¤   KMSplitDropKeys ((PSKS)m_pSplitStruct, hGlobal);
0d33a1 ¤   ¤   ¤   ReleaseStgMedium (&medium);
faa666 ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
9da2ba ¤   ¤   ¤   return NOERROR;
1e0fe4 ¤   ¤   }
9caf5a
a4e0ac ¤   ¤   // Next try getting CF_TEXT data from drag source
88a0f3 ¤   ¤   fmtetc.cfFormat = CF_TEXT;
809cd0 ¤   ¤   fmtetc.ptd = NULL;
6b61e4 ¤   ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
360fa6 ¤   ¤   fmtetc.lindex = -1;
94d16f ¤   ¤   fmtetc.tymed = TYMED_HGLOBAL; ······
cc508e ········
51376e ¤   ¤   hr = pDataObj->GetData (&fmtetc, &medium);
4ec1cf ¤   ¤   if (!FAILED(hr)) {
4128cf ¤   ¤   // Import the data and release it.
bd450d ¤   ¤   ¤   hGlobal = medium.hGlobal;
55d0e4 ¤   ¤   ¤   if (m_pKeyMan)
316ee5 ¤   ¤   ¤   ¤   KMDropKeys ((PKEYMAN)m_pKeyMan, hGlobal);
4bbb8c ¤   ¤   ¤   else
e17b68 ¤   ¤   ¤   ¤   KMSplitDropKeys ((PSKS)m_pSplitStruct, hGlobal);
f433a1 ¤   ¤   ¤   ReleaseStgMedium (&medium);
54a666 ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
86a2ba ¤   ¤   ¤   return NOERROR;
c10fe4 ¤   ¤   }
83af5a
--17f0 00130588d82401102a8 Page 4 of KMIDropTarget.cpp
79a75e ¤   ¤   if (m_pKeyMan) {
5fefb9 ¤   ¤   ¤   // no CF_TEXT, try getting CF_HDROP data from drag source
85634e ¤   ¤   ¤   fmtetc.cfFormat = CF_HDROP;
f988f8 ¤   ¤   ¤   fmtetc.ptd = NULL;
632eda ¤   ¤   ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
4fa2f8 ¤   ¤   ¤   fmtetc.lindex = -1;
f583f2 ¤   ¤   ¤   fmtetc.tymed = TYMED_HGLOBAL; ······
48508e ········
892649 ¤   ¤   ¤   hr = pDataObj->GetData (&fmtetc, &medium);
66d5e7 ¤   ¤   ¤   if (!FAILED(hr)) {
41b957 ¤   ¤   ¤   // Import the data and release it.
a679e3 ¤   ¤   ¤   ¤   hGlobal = medium.hGlobal;
47cd72 ¤   ¤   ¤   ¤   KMImportKey ((PKEYMAN)m_pKeyMan, hGlobal);
5bbbc7 ¤   ¤   ¤   ¤   ReleaseStgMedium (&medium);
6c9fa3 ¤   ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
9d0fe4 ¤   ¤   ¤   ¤   return NOERROR;
e8a3a6 ¤   ¤   ¤   }
be0fe4 ¤   ¤   }
d6af5a
309371 ¤   }
c445a8 ¤   return hr; ·····
7c38af } ··
52af5a
0daf5a
21c8dc //¤ ________________________________________
7b465d //
7ae21b //¤ Interface to C code·
ebaf5a
d46dad extern "C" {
f48f6c LPDROPTARGET KMCreateDropTarget (
2bc2d2 ¤   ¤   HWND¤   hwnd,·
04232b ¤   ¤   VOID* ¤ pKeyMan,·
8b16e6 ¤   ¤   VOID* ¤ pSplitStruct)·
80bb36 {
537c3a ¤   return ((LPDROPTARGET) new CDropTarget (hwnd, pKeyMan, pSplitStruct));
25efe6 }
4eaf5a
5fd612 void KMReleaseDropTarget (LPDROPTARGET pDropTarget)·
84bb36 {
6c30f6 ¤   pDropTarget->Release ();
82efe6 }
b4af5a
77e4fa void KMEnableDropTarget (CDropTarget* pDropTarget, BOOL bEnable)·
b6bb36 {
c37e4b ¤   pDropTarget->Enable (bEnable);
6fefe6 }
52af5a
30be43 }¶
--9923 0015041dc7f401102a9 Page 1 of KMIDropTarget.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
e9f69a ¤   KMIDropTarget.cpp - implements OLE IDropTarget for drag and drop
e8af5a
f6fa3f ¤   $Id: KMIDropTarget.h,v 1.5 1998/08/11 14:43:28 pbj Exp $
51f7f7 ____________________________________________________________________________*/
4faf5a
5804c0 class FAR CDropTarget : public IDropTarget
89bb36 {
ecdd93 public: ···
ec42b6 ····CDropTarget(HWND hwnd, VOID* pKeyMan, VOID* pSplitStruct);
73ffbd ¤   void Enable(BOOL bEnable);
d0af5a
ead68d ····// IUnknown methods
12a5a5 ····STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
6c5d7f ····STDMETHOD_(ULONG, AddRef)(void);
5669f5 ····STDMETHOD_(ULONG, Release)(void);
39af5a
d12d85 ····// IDropTarget methods
f70e86 ····STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState,·
5c0f63 ¤   ¤   POINTL pt, LPDWORD pdwEffect);
184281 ····STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
7054ad ····STDMETHOD(DragLeave)();
0d717f ····STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState,·
6e74de ¤   ¤   POINTL pt, LPDWORD pdwEffect);·
14869e ····
c50fb9 private:
96e3c0 ····ULONG m_refs; ·
db8475 ¤   HWND m_hwnd;
530321 ····BOOL m_bAcceptFmt;
9e6c99 ¤   BOOL m_bEnabled;
ef0a4b ¤   VOID* m_pKeyMan;
8baf9e ¤   VOID* m_pSplitStruct;
c5a270 ¤   POINT m_ptPrevious;
3a1893 ¤   ULONG m_uDEPrevious;
443e67 }; ·
50af5a
--30fd 0001cdc930b401102aa Page 1 of KMIEnumFormatEtc.cpp
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
430c79 ¤   KMIEnumFormatEtc.cpp - implements OLE IEnumFORMATETC for drag and drop
afefc0 ¤   to the shell.
efaf5a
d13f1a ¤   $Id: KMIEnumFormatEtc.cpp,v 1.4 1998/08/11 14:43:29 pbj Exp $
46f7f7 ____________________________________________________________________________*/
d2e610 #include "pgpPFLConfig.h"
84af5a
6ffc2c // system header files
d75655 #include <windows.h>
87af5a
fdc917 // project header files
2f1b7a #include "KMIEnumFormatEtc.h"
3aaf5a
6caf5a
0bc8dc //¤ ________________________________________
f3465d //
2ecabc //¤ IUnknown Methods
3eaf5a
ea8f32 STDMETHODIMP CEnumFormatEtc::QueryInterface (
2bba44 ¤   ¤   REFIID¤ ¤   ¤   iid,·
9b3437 ¤   ¤   void FAR* FAR*¤ ppv)·
53bb36 {
a66aab ····if ((iid == IID_IUnknown) || (iid == IID_IDataObject)) {
347277 ······*ppv = this;
8ebc36 ······++m_refs;
2a4323 ······return NOERROR;
ef6fe7 ····}
8ae0d5 ····*ppv = NULL;
d4af5a
7e2438 ····return E_NOINTERFACE;
97efe6 }
f4af5a
45af5a
4b3ab6 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef (void)·
28bb36 {
ccbd9a ····return ++m_refs;
d5efe6 }
77af5a
6daf5a
53c945 STDMETHODIMP_(ULONG) CEnumFormatEtc::Release (void)·
58bb36 {
d7ffa3 ¤   if(--m_refs == 0) {
7446de ¤   ¤   if (m_prgfe != NULL) delete [] m_prgfe;¤
a5146b ¤   ¤   m_prgfe = NULL;¤¤   ¤   ¤   ¤   ¤   ¤
26bdcf ¤   ¤   delete this;¤   ¤   ¤   ¤   ¤   ¤
23bbde ¤   ¤   return 0;
c86fe7 ····}
0721aa ····return m_refs;
4f0acd } ·
2faf5a
cbaf5a
d8c8dc //¤ ________________________________________
82465d //
aec2c8 //¤ CEnumFormatEtc Constructor
09115f //¤ ¤   cFE ············ULONG number of FORMATETCs in pFE
ef6c7b //¤ ¤   prgFE ··········LPFORMATETC to the array to enumerate.
7dac6a //·
45af5a
8e7672 CEnumFormatEtc::CEnumFormatEtc (
025b4c ¤   ¤   ULONG¤  ¤   cFE,·
88a5d2 ¤   ¤   LPFORMATETC¤prgFE)·
35bb36 {
9529f8 ····UINT i;
8faf5a
4f5e55 ····m_refs = 1;
60af5a
02d6c0 ····m_iCur = 0;
1c9a15 ····m_cfe = cFE;
--b7a2 0002a34d983401102aa Page 2 of KMIEnumFormatEtc.cpp
52b55a ····m_prgfe = new FORMATETC[(UINT)cFE];
f8af5a
00e14a ····if (m_prgfe != NULL) {
a8ce3f ········for (i = 0; i < cFE; i++)
92ba72 ············m_prgfe[i] = prgFE[i];
0a6fe7 ····}
1faf5a
a03471 ····return;
21efe6 }
0caf5a
d3af5a
4fc8dc //¤ ________________________________________
d8465d //
233216 //¤ CEnumFormatEtc Destructor
5caf5a
38f9a4 CEnumFormatEtc::~CEnumFormatEtc(void)·
debb36 {
f6bd24 ····if (m_prgfe != NULL)
1e19ed ········delete [] m_prgfe;
433471 ····return;
59efe6 }
6daf5a
3baf5a
edc8dc //¤ ________________________________________
65465d //
69e08c //¤ IEnumFORMATETC Methods
e3af5a
f4af5a
f6c8dc //¤ ________________________________________
3e465d //
5c655d //¤ CEnumFormatEtc::Next
0b465d //
732898 //¤ Purpose:
3d4b68 //¤ ¤   Returns the next element in the enumeration.
b2465d //
fcb4f6 //¤ Parameters:
8b4ec0 //¤ ¤   cFE ············ULONG number of FORMATETCs to return.
7edd55 //¤ ¤   pFE ············LPFORMATETC in which to store the returned
a03eef //¤ ¤   ¤   ¤   ¤   ····structures.
cbc56a //¤ ¤   pulFE ··········ULONG * in which to return how many we
efd9b4 //¤ ¤   ¤   ¤   ¤   ¤   enumerated.
ecac6a //·
ba07c7 //¤ Return Value:
ebc435 //¤ ¤   HRESULT ········NOERROR if successful, S_FALSE otherwise,
e2ac6a //·
69af5a
912070 STDMETHODIMP CEnumFormatEtc::Next (
bf5b4c ¤   ¤   ULONG¤  ¤   cFE,·
83327b ¤   ¤   LPFORMATETC¤pFE,·
4a38a7 ¤   ¤   ULONG*¤ ¤   pulFE)·
74bb36 {
7fb32e ····ULONG ··············cReturn=0L;
06af5a
c2029f ····if (m_prgfe == NULL)
4e799f ········return S_FALSE;
a3af5a
370c2a ····if (pulFE == NULL) {
be3b2e ········if (cFE != 1L) return S_FALSE;
0d6fe7 ····}
84ac9c ····else *pulFE=0L;
33af5a
a7d3b8 ····if ((pFE == NULL) || (m_iCur >= m_cfe))
b2799f ········return S_FALSE;
b6af5a
38016a ····while ((m_iCur < m_cfe) && (cFE > 0)) {
2aa52d ········*pFE++=m_prgfe[m_iCur++];
78aef4 ········cReturn++;
a7544b ········cFE--;
d86fe7 ····}
baaf5a
5b73a1 ····if (pulFE != NULL) *pulFE=cReturn;
2aaf5a
--0c4d 0006aa4d5a6401102aa Page 3 of KMIEnumFormatEtc.cpp
14efa0 ····return S_OK;
2eefe6 }
1daf5a
41af5a
6ac8dc //¤ ________________________________________
76465d //
10bb02 //¤ CEnumFormatEtc::Skip
bb465d //
a92898 //¤ Purpose:
e22e83 //¤ ¤   Skips the next n elements in the enumeration.
e8465d //
75b4f6 //¤ Parameters:
b6ea7c //¤ ¤   cSkip ··········ULONG number of elements to skip.
1a465d //
3007c7 //¤ Return Value:
934fc1 //¤ ¤   HRESULT ········NOERROR if successful, S_FALSE if we could not
eaaa05 //¤ ¤   ¤   ¤   ¤   ¤   skip the requested number.
29465d //
e8af5a
d262df STDMETHODIMP CEnumFormatEtc::Skip (ULONG cSkip)·
a8bb36 {
e71516 ····if (((m_iCur+cSkip) >= m_cfe) || (m_prgfe == NULL))
03799f ········return S_FALSE;
8daf5a
e1f8db ····m_iCur+=cSkip;
dfefa0 ····return S_OK;
58efe6 }
20af5a
69af5a
4ac8dc //¤ ________________________________________
6a465d //
822093 //¤ CEnumFormatEtc::Reset
c3465d //
852898 //¤ Purpose:
deeba8 //¤ ¤   Resets the current element index in the enumeration to zero.
95465d //
42b4f6 //¤ Parameters:
06d740 //¤ ¤   None
4a465d //
f807c7 //¤ Return Value:
464d92 //¤ ¤   HRESULT ········NOERROR
75465d //
22af5a
3aa968 STDMETHODIMP CEnumFormatEtc::Reset (void)·
49bb36 {
d0fe35 ····m_iCur=0;
32efa0 ····return S_OK;
8fefe6 }
bbaf5a
14af5a
d9c8dc //¤ ________________________________________
35465d //
a6c616 //¤ CEnumFormatEtc::Clone
74465d //
312898 //¤ Purpose:
a45cbe //¤ ¤   Returns another IEnumFORMATETC with the same state as ourselves.
68465d //
d0b4f6 //¤ Parameters:
2d8c22 //¤ ¤   ppEnum ·········LPENUMFORMATETC * in which to return the
ac6a64 //¤ ¤   ¤   ¤   ¤   ¤   new object.
32465d //
0c07c7 //¤ Return Value:
5a6679 //¤ ¤   HRESULT ········NOERROR or a general error value.
4f465d //
d2af5a
e13a4e STDMETHODIMP CEnumFormatEtc::Clone (LPENUMFORMATETC *ppEnum)·
48bb36 {
f52cee ····CEnumFormatEtc* ····pNew;
4caf5a
1f45d7 ····*ppEnum=NULL;
1eaf5a
6aa6de ····//Create the clone
--b2a7 001534a7ba7401102aa Page 4 of KMIEnumFormatEtc.cpp
097dde ····pNew = new CEnumFormatEtc (m_cfe, m_prgfe);
64af5a
60281d ····if (pNew == NULL) return E_OUTOFMEMORY;
3daf5a
158e7e ····pNew->m_iCur = m_iCur;
78af5a
890f95 ····*ppEnum = pNew;
9eefa0 ····return S_OK;
51efe6 }
f9af5a
53af5a
--2284 0018bae3a66401102ab Page 1 of KMIEnumFormatEtc.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
430c79 ¤   KMIEnumFormatEtc.cpp - implements OLE IEnumFORMATETC for drag and drop
afefc0 ¤   to the shell.
efaf5a
d632c1 ¤   $Id: KMIEnumFormatEtc.h,v 1.3 1998/08/11 14:43:30 pbj Exp $
59f7f7 ____________________________________________________________________________*/
e6af5a
bb0bee class FAR CEnumFormatEtc : public IEnumFORMATETC {
9cdd93 public: ···
22f88f ····CEnumFormatEtc (ULONG cFE, LPFORMATETC prgFE);
0297ea ¤   ~CEnumFormatEtc (void);
42af5a
e2c86e ····/* IUnknown methods */
3aa5a5 ····STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
075d7f ····STDMETHOD_(ULONG, AddRef)(void);
5b69f5 ····STDMETHOD_(ULONG, Release)(void);
82af5a
d5549c ····/* IEnumFORMATETC methods */
1774e5 ¤   STDMETHODIMP Next (ULONG, LPFORMATETC, ULONG *);
07fac7 ¤   STDMETHODIMP Skip (ULONG);
80edd0 ¤   STDMETHODIMP Reset (void);
aeb5da ¤   STDMETHODIMP Clone (IEnumFORMATETC **);
05af5a
050fb9 private:
3227ce ····ULONG¤  ¤   ¤   m_refs; ····
82271d ····ULONG ··········m_iCur; ········//Current element.
008ae0 ····ULONG ··········m_cfe; ·········//Number of FORMATETCs in us
53afba ····LPFORMATETC ····m_prgfe; ·······//Source of FORMATETCs
103e67 }; ·
8baf5a
--f50e 000ae42211c401102ac Page 1 of KMKeyIO.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
2e7198 ¤   KMKeyIO.c - implements various operations related to importing·
c15312 ¤   ¤   ¤   ¤   and exporting keys ·
9d67c5 ¤
11af5a
355c34 ¤   $Id: KMKeyIO.c,v 1.16 1998/08/13 02:46:10 pbj Exp $
f7f7f7 ____________________________________________________________________________*/
6ae610 #include "pgpPFLConfig.h"
d5af5a
1bc917 // project header files
10850a #include "pgpkmx.h"
75af5a
23ad8c // pgp header files
47c97b #include "pgpClientPrefs.h"
653991 #include "pgpAdminPrefs.h"
5ca783 #include "pgpVersionHeader.c"
e3af5a
01fc2c // system header files
786bd4 #include <commdlg.h>
f5af5a
4d5bee // typedefs
91f0f7 typedef struct {
7b0fd0 ¤   PGPBoolean¤ bExportPrivKeys;
f52572 ¤   PGPBoolean¤ bCompatible;
229bcd ¤   LPSTR¤  ¤   pszHelpFile;
0b473b } EXPORTPRIVKEYSTRUCT, *PEXPORTPRIVKEYSTRUCT;
32af5a
8993ed // external globals
f49cad extern HINSTANCE g_hInst;
07af5a
94492e // local globals
bca0a5 static BOOL bDraggingOut = FALSE; ··//NB: valid across keymanagers!
3a9cf1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //prevents bonus selective import dialog
e1af5a
82005a static DWORD aExportKeyIds[] = {¤   ¤   ¤   // Help IDs
1fbf53 ····IDC_EXPORTPRIVATEKEYS,¤ ¤   IDH_PGPKM_EXPORTPRIVATEKEYS,·
88b2bc ····IDC_INCLUDEEXTENSIONS,¤ ¤   IDH_PGPKM_INCLUDEEXTENSIONS,·
bf4434 ····0,0·
85a6fe };·
91af5a
849ea5 // prototypes
f624bf BOOL IsDeleteEnabled (PKEYMAN pKM);
75af5a
3eaf5a
649268 //¤ _______________________________________________
33465d //
adc800 // ·Import key from text file
b8465d //
a91e53 //¤ hDrop¤  == NULL¤=> prompt user for file name
1f4c03 //¤ ¤   ¤   != NULL => hDrop is a handle passed in from·
db3b14 //¤ ¤   ¤   ¤   ¤   ¤   the WM_DROPFILE message
b5465d //
20af5a
257efe BOOL·
fb2d4f KMImportKey (
8b713a ¤   ¤   PKEYMAN pKM,·
75dc25 ¤   ¤   HDROP¤  hDrop)·
46bb36 {
f80b76 ¤   OPENFILENAME¤   OpenFileName;
a763e2 ¤   CHAR¤   ¤   ¤   szFile[MAX_PATH];
070c1c ¤   CHAR¤   ¤   ¤   szFilter[256];
5076ca ¤   CHAR¤   ¤   ¤   szTitle[64];
06cf2b ¤   CHAR*¤  ¤   ¤   p;
210c32 ¤   INT¤¤   ¤   ¤   iIndex;
8c3fcf ¤   BOOL¤   ¤   ¤   bImport;
acbf72 ¤   BOOL¤   ¤   ¤   bKeys;
c22afd ¤   PGPFileSpecRef¤ FileRef;
9328cc ¤   PGPKeySetRef¤   KeySet;
aeaf5a
--c151 00052f727f4401102ac Page 2 of KMKeyIO.c
d94d10 ¤   if (hDrop) {
075ab6 ¤   ¤   iIndex = 0;
63f7f6 ¤   ¤   bImport = FALSE;
10313e ¤   ¤   bKeys = FALSE;
cefddc ¤   ¤   while (DragQueryFile (hDrop, iIndex, szFile, sizeof(szFile))) {
3bea3a ¤   ¤   ¤   PGPNewFileSpecFromFullPath (pKM->Context, szFile, &FileRef);
749f2a ¤   ¤   ¤   if (FileRef) {
780f2b ¤   ¤   ¤   ¤   PGPImportKeySet (pKM->Context, &KeySet,·
d04b57 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputFile (pKM->Context, FileRef),
c0ba30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
d68c52 ¤   ¤   ¤   ¤   if (KeySet) {
704043 ¤   ¤   ¤   ¤   ¤   PGPUInt32¤  numKeys;
bebba7 ¤   ¤   ¤   ¤   ¤   PGPCountKeys (KeySet, &numKeys);
93b9fc ¤   ¤   ¤   ¤   ¤   if (numKeys > 0) {
faeb9a ¤   ¤   ¤   ¤   ¤   ¤   bKeys = TRUE;
5b7157 ¤   ¤   ¤   ¤   ¤   ¤   if (bDraggingOut) {
af403f ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL,·
291397 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPAddKeys (KeySet, pKM->KeySetDisp)))) {
dae5cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
e53c64 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bImport = TRUE;
dd5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
35db3c ¤   ¤   ¤   ¤   ¤   ¤   }
322863 ¤   ¤   ¤   ¤   ¤   ¤   else {
2c68ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (PGPclQueryAddKeys (pKM->Context,
4b35af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->tlsContext,
cafcab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent,·
683289 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KeySet,·
9cfcf1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetDisp) == kPGPError_NoErr) {
7be5cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
e73c64 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bImport = TRUE;
ee5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
08db3c ¤   ¤   ¤   ¤   ¤   ¤   }
971c89 ¤   ¤   ¤   ¤   ¤   }
3737d0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (KeySet);
602613 ¤   ¤   ¤   ¤   }
932cd0 ¤   ¤   ¤   ¤   PGPFreeFileSpec (FileRef);
1ba3a6 ¤   ¤   ¤   }
8e1368 ¤   ¤   ¤   iIndex++;
de0fe4 ¤   ¤   }
98cc00 ¤   ¤   if (!bKeys) {
ad6c82 ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_NOIMPORTKEYS,·
a014e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
9f0fe4 ¤   ¤   }
7d9371 ¤   }
44665a ¤   else {
9f8a55 ¤   ¤   lstrcpy (szFile, "");
0427cb ¤   ¤   LoadString (g_hInst, IDS_IMPORTFILTER, szFilter, sizeof(szFilter));
44b9c1 ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
a6426b ¤   ¤   LoadString (g_hInst, IDS_IMPORTCAPTION, szTitle, sizeof(szTitle));
930181 ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
6a5c91 ¤   ¤   OpenFileName.hwndOwner ········= pKM->hWndParent;
39e4b2 ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
c6a988 ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
b71ec3 ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
506424 ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
140d4e ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
492ff2 ¤   ¤   OpenFileName.lpstrFile ········= szFile;
0da0f3 ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (szFile);
e53c53 ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
3a3f2d ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
f7df00 ¤   ¤   OpenFileName.lpstrInitialDir ··= NULL;
e46309 ¤   ¤   OpenFileName.lpstrTitle ·······= szTitle;
79a93d ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
2fb537 ¤   ¤   OpenFileName.nFileOffset ······= 0;
3c7cea ¤   ¤   OpenFileName.nFileExtension ···= 0;
fca233 ¤   ¤   OpenFileName.lpstrDefExt ······= "";
b453cd ¤   ¤   OpenFileName.lCustData ········= 0;
92af5a
d0f7f6 ¤   ¤   bImport = FALSE;
e9313e ¤   ¤   bKeys = FALSE;
b6a55f ¤   ¤   if (GetOpenFileName (&OpenFileName)) {
52ea3a ¤   ¤   ¤   PGPNewFileSpecFromFullPath (pKM->Context, szFile, &FileRef);
--9724 000dbc5aafa401102ac Page 3 of KMKeyIO.c
509f2a ¤   ¤   ¤   if (FileRef) {
a30f2b ¤   ¤   ¤   ¤   PGPImportKeySet (pKM->Context, &KeySet,·
974b57 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputFile (pKM->Context, FileRef),
49ba30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
ee8c52 ¤   ¤   ¤   ¤   if (KeySet) {
bb4043 ¤   ¤   ¤   ¤   ¤   PGPUInt32¤  numKeys;
f6ae30 ¤   ¤   ¤   ¤   ¤
36bba7 ¤   ¤   ¤   ¤   ¤   PGPCountKeys (KeySet, &numKeys);
04dc08 ¤   ¤   ¤   ¤   ¤   if ( numKeys > 0) {
1deb9a ¤   ¤   ¤   ¤   ¤   ¤   bKeys = TRUE;
70d169 ¤   ¤   ¤   ¤   ¤   ¤   if (PGPclQueryAddKeys (pKM->Context,·
2fa600 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->tlsContext,
da8180 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent,
b05c3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KeySet,·
204659 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetDisp) ==·
196e87 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPError_NoErr) {
d607cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
342434 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bImport = TRUE;
28db3c ¤   ¤   ¤   ¤   ¤   ¤   }
4b1c89 ¤   ¤   ¤   ¤   ¤   }
9337d0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (KeySet);
2f2613 ¤   ¤   ¤   ¤   }
982cd0 ¤   ¤   ¤   ¤   PGPFreeFileSpec (FileRef);
bba3a6 ¤   ¤   ¤   }
660bb5 ¤   ¤   ¤   if (!bKeys) {
2381a5 ¤   ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_NOIMPORTKEYS,·
e113d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
44a3a6 ¤   ¤   ¤   }
020fe4 ¤   ¤   }
b79371 ¤   }
edaf5a
58d300 ¤   if (bImport) {
db36e0 ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, TRUE, FALSE);
bf201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
8c9371 ¤   }
9caf5a
ab0eef ¤   return bImport;
21efe6 }
3aaf5a
de9268 //¤ _______________________________________________
84465d //
6bed94 // ·Get appropriate comment string
faaf5a
52b333 static VOID·
dc6fc3 sGetCommentString (
c963c2 ¤   ¤   PGPMemoryMgrRef¤memMgr,
625d18 ¤   ¤   LPSTR¤  ¤   ¤   sz,·
fa7281 ¤   ¤   UINT¤   ¤   ¤   uLen)·
3ebb36 {
be910a ¤   PGPPrefRef¤ prefref;
26af5a
4b0762 ¤   sz[0] = 0;
03af5a
afbe29 #if PGP_BUSINESS_SECURITY
a29bec ¤   PGPclOpenAdminPrefs (memMgr, &prefref, FALSE);
de6fa3 ¤   PGPGetPrefStringBuffer (prefref, kPGPPrefComments, uLen, sz);
46496a ¤   PGPclCloseAdminPrefs (prefref, FALSE);
2b97b2 #endif¤ // PGP_BUSINESS_SECURITY
5caf5a
f5ebfd ¤   if (sz[0] == 0) {
a8a4b9 ¤   ¤   PGPclOpenClientPrefs (memMgr, &prefref);
8018f4 ¤   ¤   PGPGetPrefStringBuffer (prefref, kPGPPrefComment, uLen, sz);
65b30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
279371 ¤   }
c6efe6 }
f6af5a
269268 //¤ _______________________________________________
23465d //
18f858 // ·Get export format based on prefs
57af5a
583f72 static PGPExportFormat·
db8f6b sGetExportFormat (PGPMemoryMgrRef¤  memMgr)
--02c5 0003d8d50f8401102ac Page 4 of KMKeyIO.c
2cbb36 {
7123c3 ¤   PGPBoolean¤ bCompatible¤¤   = TRUE;
79910a ¤   PGPPrefRef¤ prefref;
35af5a
fef624 ¤   PGPclOpenClientPrefs (memMgr, &prefref);
ede556 ¤   PGPGetPrefBoolean (prefref, kPGPPrefExportKeysCompatible, &bCompatible);
6fab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
5aaf5a
0fe4f5 ¤   if (bCompatible)·
d7c04d ¤   ¤   return kPGPExportFormat_Basic;
5d0e24 ¤   else
1c4720 ¤   ¤   return kPGPExportFormat_Complete;
11efe6 }
84af5a
d29268 //¤ _______________________________________________
26465d //
c4d382 // ·Export key(s) to text file
10af5a
f46c77 static BOOL·
031de1 sExportKeys (
8e934d ¤   ¤   PKEYMAN¤¤   ¤   pKM,·
7c8b6a ¤   ¤   PGPKeySetRef¤   keyset,
6cdbaf ¤   ¤   LPSTR¤  ¤   ¤   szFile,
3af099 ¤   ¤   PGPBoolean¤ ¤   bExportPrivateKeys,
091636 ¤   ¤   PGPBoolean¤ ¤   bCompatible)·
b0bb36 {
d5d666 ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   ¤   = FALSE;
452afd ¤   PGPFileSpecRef¤ FileRef;
f1816a ¤   CHAR¤   ¤   ¤   szComment[256];
e5366c ¤   PGPExportFormat¤exportformat;
1aaf5a
d06709 ¤   PGPNewFileSpecFromFullPath (pKM->Context, szFile, &FileRef);
5a98e3 ¤   if (FileRef) {¤
59c9a5 ¤   ¤   sGetCommentString (PGPGetContextMemoryMgr (pKM->Context),·
9d926c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szComment, sizeof(szComment));
0aaf5a
743c66 ¤   ¤   if (bCompatible)
c66277 ¤   ¤   ¤   exportformat = kPGPExportFormat_Basic;
f80e1d ¤   ¤   else
e32ebb ¤   ¤   ¤   exportformat = kPGPExportFormat_Complete;
b1af5a
0306b6 ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL,
c9545e ¤   ¤   ¤   ¤   PGPExportKeySet (keyset,·
3d1a41 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOOutputFile (pKM->Context, FileRef),
a7d839 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOExportFormat (pKM->Context,·
cdb3bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   exportformat),
7ed536 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOVersionString (pKM->Context,·
a9da6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pgpVersionHeaderString),
0413b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOCommentString (pKM->Context, szComment),
e3c1fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOExportPrivateKeys (pKM->Context,
f28845 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bExportPrivateKeys),
a25593 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOLastOption (pKM->Context))))) {
4518c6 ¤   ¤   ¤   bRetVal = TRUE;
b50fe4 ¤   ¤   }
74636f ¤   ¤   PGPFreeFileSpec (FileRef);
f29371 ¤   }
7baf5a
e11c35 ¤   return bRetVal;
3cefe6 }
07af5a
b1d59e //¤ ___________________________
a0465d //
eeedf2 // ·Compute name of export file
47af5a
8ab333 static VOID·
c852d8 sGetExportFileName (
02713a ¤   ¤   PKEYMAN pKM,·
37603b ¤   ¤   LPSTR¤  sz,·
95a05a ¤   ¤   UINT¤   uLen)·
6ebb36 {
dc55e3 ¤   CHAR¤   ¤   szDefExt[8];
3dc595 ¤   PGPKeyRef¤  key;
--7737 0002c73c6be401102ac Page 5 of KMKeyIO.c
8e2aea ¤   INT¤¤   ¤   i;
30af5a
861826 ¤   if (!KMMultipleSelected (pKM)) {
369d05 ¤   ¤   key = KMFocusedObject (pKM);
eab68b ¤   ¤   PGPGetPrimaryUserIDNameBuffer (key, uLen, sz, &i);
e5af5a
a1f76e ¤   ¤   i = strcspn (sz, "\\/:*?""<>|");
16bf20 ¤   ¤   sz[i] = '\0';
610c5f ¤   ¤   if (i > 0) {
ea47f9 ¤   ¤   ¤   if (sz[i-1] == ' ') sz[i-1] = '\0';
300fe4 ¤   ¤   }
d04f0a ¤   ¤   if (lstrlen(sz) < 2) LoadString (g_hInst, IDS_DROPFILENAME,·
d34978 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·sz, uLen);
bc9371 ¤   }
804fbf ¤   else LoadString (g_hInst, IDS_DROPFILENAME, sz, uLen);
1baf5a
dc802d ¤   lstrcat (sz, ".");
0b4d81 ¤   LoadString (g_hInst, IDS_DEFEXPORTEXTENSION, szDefExt, sizeof(szDefExt));
1c66ee ¤   lstrcat (sz, szDefExt);
efefe6 }
92af5a
59bf56 //----------------------------------------------------|
2963c0 // Export Private Key dialog message procedure
6aaf5a
783f64 static BOOL CALLBACK·
8ffbe4 sExportPrivKeyDlgProc (
574669 ¤   ¤   HWND¤   hWndDlg,·
f5eb77 ¤   ¤   UINT¤   uMsg,·
7d17d4 ¤   ¤   WPARAM¤ wParam,·
81c0b8 ¤   ¤   LPARAM¤ lParam)·
55bb36 {
17d756 ¤   OPENFILENAME*¤  ¤   ¤   pofn;
db0bf6 ¤   PEXPORTPRIVKEYSTRUCT¤   pepks;
57af5a
bd347f ¤   switch (uMsg) {
5aaf5a
27ad3a ¤   case WM_INITDIALOG :
6b1766 ¤   ¤   pofn = (OPENFILENAME*)lParam;
5f29c9 ¤   ¤   SetWindowLong (hWndDlg, GWL_USERDATA, pofn->lCustData);
fc9ecf ¤   ¤   pepks = (PEXPORTPRIVKEYSTRUCT)pofn->lCustData;
2e5d93 ¤   ¤   if (!pepks->bExportPrivKeys)·
3fe9dd ¤   ¤   ¤   EnableWindow (GetDlgItem (hWndDlg, IDC_EXPORTPRIVATEKEYS), FALSE);
40d23f ¤   ¤   pepks->bExportPrivKeys = FALSE;
2bdd4a ¤   ¤   if (!pepks->bCompatible)
4ed7d9 ¤   ¤   ¤   CheckDlgButton (hWndDlg, IDC_INCLUDEEXTENSIONS, BST_CHECKED);
e62f68 ¤   ¤   break;
70af5a
03407e ¤   case WM_HELP :
1cdad2 ¤   ¤   pepks = (PEXPORTPRIVKEYSTRUCT)GetWindowLong (hWndDlg, GWL_USERDATA);
b22e5c ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pepks->pszHelpFile,·
e8c55f ············HELP_WM_HELP, (DWORD) (LPSTR) aExportKeyIds);·
15836c ¤   ¤   return TRUE;
d3af5a
d53fcf ¤   case WM_COMMAND:
b9af5a
ad537d ¤   ¤   switch (LOWORD(wParam)) {
13a0f0 ¤   ¤   case IDC_EXPORTPRIVATEKEYS :
b4c3d4 ¤   ¤   ¤   pepks =·
eca108 ¤   ¤   ¤   ¤   (PEXPORTPRIVKEYSTRUCT)GetWindowLong (hWndDlg, GWL_USERDATA);
ca9e13 ¤   ¤   ¤   if (IsDlgButtonChecked (hWndDlg, IDC_EXPORTPRIVATEKEYS) ==
2ff0b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED) {
4fcd70 ¤   ¤   ¤   ¤   pepks->bExportPrivKeys = TRUE;
2fa3a6 ¤   ¤   ¤   }
1be543 ¤   ¤   ¤   else {
364209 ¤   ¤   ¤   ¤   pepks->bExportPrivKeys = FALSE;
37a3a6 ¤   ¤   ¤   }
0c32bd ¤   ¤   ¤   return TRUE;
73af5a
9b82a0 ¤   ¤   case IDC_INCLUDEEXTENSIONS :
a6c3d4 ¤   ¤   ¤   pepks =·
91a108 ¤   ¤   ¤   ¤   (PEXPORTPRIVKEYSTRUCT)GetWindowLong (hWndDlg, GWL_USERDATA);
2c4ff4 ¤   ¤   ¤   if (IsDlgButtonChecked (hWndDlg, IDC_INCLUDEEXTENSIONS) ==
--1047 000126cc850401102ac Page 6 of KMKeyIO.c
aff0b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED) {
dea5ed ¤   ¤   ¤   ¤   pepks->bCompatible = FALSE;
3ea3a6 ¤   ¤   ¤   }
aae543 ¤   ¤   ¤   else {
1d2790 ¤   ¤   ¤   ¤   pepks->bCompatible = TRUE;
38a3a6 ¤   ¤   ¤   }
b232bd ¤   ¤   ¤   return TRUE;
6faf5a
bb0fe4 ¤   ¤   }
b598aa ¤   ¤   return FALSE;
179371 ¤   }
16a230 ¤   return FALSE;
4cefe6 }
16af5a
279268 //¤ _______________________________________________
2e465d //
7eeb7c // ·Export key to text file
fcaf5a
377efe BOOL·
c09d39 KMExportKeys (
9c713a ¤   ¤   PKEYMAN pKM,·
629298 ¤   ¤   LPSTR¤  szFile)·
54bb36 {
1a324c ¤   PGPKeySetRef¤   ¤   keysetExport¤   ¤   = kInvalidPGPKeySetRef;
613f1b ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
efaf5a
ba594b ¤   OPENFILENAME¤   ¤   OpenFileName;
94cab0 ¤   EXPORTPRIVKEYSTRUCT¤epks;
10bb70 ¤   CHAR¤   ¤   ¤   ¤   sz256[256];
45f841 ¤   CHAR¤   ¤   ¤   ¤   szDefExt[8];
5c21a2 ¤   CHAR¤   ¤   ¤   ¤   szFilter[256];
d747b0 ¤   CHAR¤   ¤   ¤   ¤   szTitle[64];
9825c8 ¤   CHAR*¤  ¤   ¤   ¤   p;
5d83aa ¤   BOOL¤   ¤   ¤   ¤   bRetVal;
62697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
0aaf5a
9868db ¤   KMGetSelectedKeys (pKM, &keysetExport, NULL);
ad4762 ¤   if (!PGPKeySetRefIsValid (keysetExport))
9e98aa ¤   ¤   return FALSE;
1aaf5a
017f0b ¤   if (szFile) {
29581e ¤   ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context),·
518c73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
a78e38 ¤   ¤   PGPGetPrefBoolean (prefref, kPGPPrefExportKeysCompatible,·
cc1eac ¤   ¤   ¤   ¤   ¤   ¤   ¤   &epks.bCompatible);
9eb30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
e5af5a
2238e9 ¤   ¤   bRetVal = sExportKeys (pKM, keysetExport, szFile,·
98a6e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE, epks.bCompatible);
9d9371 ¤   }
6a665a ¤   else {
920181 ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
b65c91 ¤   ¤   OpenFileName.hwndOwner ········= pKM->hWndParent;
53e4b2 ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
62b48d ¤   ¤   LoadString (g_hInst, IDS_EXPORTFILTER, szFilter, sizeof(szFilter));
1cb9c1 ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
90a988 ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
491ec3 ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
576424 ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
890d4e ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
8c40da ¤   ¤   sGetExportFileName (pKM, sz256, sizeof (sz256));
e86371 ¤   ¤   OpenFileName.lpstrFile ········= sz256;
f02a46 ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (sz256);
233c53 ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
783f2d ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
f6df00 ¤   ¤   OpenFileName.lpstrInitialDir ··= NULL;
02b58c ¤   ¤   LoadString (g_hInst, IDS_EXPORTCAPTION, szTitle, sizeof(szTitle));
966309 ¤   ¤   OpenFileName.lpstrTitle ·······= szTitle;
cc2cc1 ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_EXPLORER|
d5cbe4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_ENABLETEMPLATE|
283751 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_ENABLEHOOK|
12ac92 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_HIDEREADONLY|
--a244 0007e9174ee401102ac Page 7 of KMKeyIO.c
7c2b11 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_OVERWRITEPROMPT|
fe7205 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_NOREADONLYRETURN|
e9886a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_NOCHANGEDIR;
55b537 ¤   ¤   OpenFileName.nFileOffset ······= 0;
fe7cea ¤   ¤   OpenFileName.nFileExtension ···= 0;
ef1ee5 ¤   ¤   LoadString (g_hInst, IDS_DEFEXPORTEXTENSION, szDefExt,·
cd8cc4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szDefExt));
76a321 ¤   ¤   OpenFileName.lpstrDefExt ······= szDefExt;
f3af5a
f8e834 ¤   ¤   OpenFileName.lCustData ········= (DWORD)&epks;
76d8a8 ¤   ¤   OpenFileName.lpfnHook ·········= sExportPrivKeyDlgProc;·
3cbce1 ¤   ¤   OpenFileName.lpTemplateName ···=·
b910e8 ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDD_EXPORTDLGEXTENSIONS);
19af5a
79218e ¤   ¤   epks.pszHelpFile = pKM->szHelpFile;
8c873a ¤   ¤   epks.bExportPrivKeys = KMCheckForSecretKeys (keysetExport);
16581e ¤   ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context),·
648c73 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
2f8e38 ¤   ¤   PGPGetPrefBoolean (prefref, kPGPPrefExportKeysCompatible,·
ea1eac ¤   ¤   ¤   ¤   ¤   ¤   ¤   &epks.bCompatible);
5db30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
d9af5a
c3e7b0 ¤   ¤   if (GetSaveFileName (&OpenFileName)) {
bf4b7a ¤   ¤   ¤   bRetVal =·
35498c ¤   ¤   ¤   ¤   sExportKeys (pKM, keysetExport, sz256,·
ca96f6 ¤   ¤   ¤   ¤   ¤   ¤   epks.bExportPrivKeys, epks.bCompatible);
4f0fe4 ¤   ¤   }
f89371 ¤   }
f4af5a
d6e7dc ¤   if (PGPKeySetRefIsValid (keysetExport))·
d83862 ¤   ¤   PGPFreeKeySet (keysetExport);
f4af5a
f0c2e7 ¤   return TRUE;
06efe6 }
26af5a
4d9268 //¤ _______________________________________________
6b465d //
9075a6 //¤ called by OLE when DropTarget asks for data
18af5a
e717ce LPSTR·
513232 KMDropKeysGetData (
43d638 ¤   ¤   PKEYMAN¤pKM,
fc2252 ¤   ¤   BOOL¤   bForceComplete)
bdbb36 {
3fda0f ¤   PGPKeySetRef¤   keysetDrop¤ ¤   = kInvalidPGPKeySetRef;
301e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
79229b ¤   DWORD¤  ¤   ¤   dwEffect¤   ¤   = 0;
8de63b ¤   BOOL¤   ¤   ¤   bOKtoDelete¤¤   = FALSE;
361792 ¤   PGPSize¤¤   ¤   slen¤   ¤   ¤   = 0;
36583c ¤   LPSTR¤  ¤   ¤   pExport¤¤   ¤   = NULL;
d4af5a
59816a ¤   CHAR¤   ¤   ¤   szComment[256];
6518da ¤   HCURSOR¤¤   ¤   hcursorOld;
f721a0 ¤   PGPExportFormat exportformat;
d9af5a
d859c4 ¤   hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
afaf5a
b61c2d ¤   err = KMGetSelectedKeys (pKM, &keysetDrop, NULL);
a9b8c9 ¤   if (!PGPKeySetRefIsValid (keysetDrop))
0a7ed2 ¤   ¤   return NULL;
c6af5a
6e86b5 ¤   // get comment string
bd196e ¤   slen = 0;
9e4459 ¤   sGetCommentString (PGPGetContextMemoryMgr (pKM->Context),·
12926c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szComment, sizeof(szComment));
fbaf5a
34aa52 ¤   // determine export format
7852f3 ¤   if (bForceComplete)
4f80ba ¤   ¤   exportformat = kPGPExportFormat_Complete;
cf0e24 ¤   else
6b058f ¤   ¤   exportformat =·
7ee94f ¤   ¤   ¤   sGetExportFormat (PGPGetContextMemoryMgr (pKM->Context));
--5873 0000dd52305401102ac Page 8 of KMKeyIO.c
e0af5a
d076ab ¤   // export to buffer
50972e ¤   if (IsntPGPError (PGPclErrorBox (NULL,
115466 ¤   ¤   PGPExportKeySet (keysetDrop,·
f5fa65 ¤   ¤   ¤   ¤   ¤   ¤   PGPOAllocatedOutputBuffer (pKM->Context,
2e0a7d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pExport, 0x40000000, &slen),
755eb9 ¤   ¤   ¤   ¤   ¤   ¤   PGPOExportFormat (pKM->Context, exportformat),
bdb359 ¤   ¤   ¤   ¤   ¤   ¤   PGPOVersionString (pKM->Context,·
55abc5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pgpVersionHeaderString),
cc356c ¤   ¤   ¤   ¤   ¤   ¤   PGPOCommentString (pKM->Context, szComment),
15b53e ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context))))) {
51af64 ¤   ¤   if (pExport)·
b2df1f ¤   ¤   ¤   pExport[slen-2] = '\0';
829371 ¤   }
dcaf5a
4bcc50 ¤   if (PGPKeySetRefIsValid (keysetDrop))
c0ac1a ¤   ¤   PGPFreeKeySet (keysetDrop);
6eaf5a
abf7d7 ¤   SetCursor (hcursorOld);
aaaf5a
567578 ¤   return pExport;¤¤
5cefe6 }
f9af5a
a9af5a
209268 //¤ _______________________________________________
f6465d //
8375a6 //¤ called by OLE when DropTarget asks for data
feaf5a
9ea1ba VOID·
343a0b KMDropKeysFreeData (LPSTR psz)·
99bb36 {
54baed ¤   if (IsntNull (psz))
f967b8 ¤   ¤   PGPFreeData (psz);
10efe6 }
b7af5a
cbaf5a
7c9268 //¤ _______________________________________________
8c465d //
8dafa2 // ·Drag selected key or keys out of application onto·
3dbf03 // ·desktop or into Explorer. ·Uses OLE interface.
76af5a
e07efe BOOL·
d3f2a8 KMDragAndDrop (PKEYMAN pKM)·
41bb36 {
eb5e57 ¤   LPDATAOBJECT¤   lpdo;
0b680f ¤   LPDROPSOURCE¤   lpds;
9dbc23 ¤   DWORD¤  ¤   ¤   dwEffect = 0;
7063e2 ¤   CHAR¤   ¤   ¤   szFile[MAX_PATH];
482d24 ¤   BOOL¤   ¤   ¤   bOKtoDelete = FALSE;
58af5a
476338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
0daf5a
5fbf87 ¤   sGetExportFileName (pKM, szFile, sizeof(szFile));
bcaf5a
9dc11a ¤   lpdo = KMCreateDataObject (pKM, szFile);
fe96e9 ¤   lpds = KMCreateDropSource (pKM, pKM->hWndParent, pKM->hWndTree);
11af5a
23bf57 ¤   if (lpds) {
85eb54 ¤   ¤   if (lpdo) {
7407b2 ¤   ¤   ¤   bDraggingOut = TRUE;
7c2568 ¤   ¤   ¤   DoDragDrop (lpdo, lpds,·
9ba17f ¤   ¤   ¤   ¤   DROPEFFECT_COPY|DROPEFFECT_MOVE, &dwEffect);·
da4589 ¤   ¤   ¤   bOKtoDelete = KMOKToDeleteDataObject (lpdo);
5fcf6b ¤   ¤   ¤   lpdo->lpVtbl->Release(lpdo);
4aa7dd ¤   ¤   ¤   bDraggingOut = FALSE;
7b0fe4 ¤   ¤   }
195c4a ¤   ¤   lpds->lpVtbl->Release(lpds);
aa9371 ¤   }
81af5a
ff771f ¤   if (dwEffect == DROPEFFECT_MOVE) {
8af84d ¤   ¤   if (bOKtoDelete) {
0dada6 ¤   ¤   ¤   if (IsDeleteEnabled (pKM)) {
--0c31 00002b2f1b9401102ac Page 9 of KMKeyIO.c
283056 ¤   ¤   ¤   ¤   KMDeleteObject (pKM);
7fa3a6 ¤   ¤   ¤   }
320fe4 ¤   ¤   }
259371 ¤   }
74efe6 }
31af5a
629268 //¤ _______________________________________________
4a465d //
7681a2 // ·Copy key(s) to clipboard
6daf5a
a57efe BOOL·
e16c4e KMCopyKeys (
e5713a ¤   ¤   PKEYMAN pKM,·
7ccc06 ¤   ¤   HANDLE* phMem)·
07bb36 {
a18d8a ¤   PGPKeySetRef¤   keysetCopy¤ ¤   ¤   = kInvalidPGPKeySetRef;
8c7f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
18d666 ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   ¤   = FALSE;
ed9fd3 ¤   size_t¤ ¤   ¤   slen;
ad92c9 ¤   HANDLE¤ ¤   ¤   hMem;
84ee31 ¤   LPSTR¤  ¤   ¤   pMem;
e805bf ¤   LPSTR¤  ¤   ¤   pMemG;
39816a ¤   CHAR¤   ¤   ¤   szComment[256];
02366c ¤   PGPExportFormat¤exportformat;
83af5a
eab37e ¤   err = KMGetSelectedKeys (pKM, &keysetCopy, NULL);
ca2f61 ¤   if (!PGPKeySetRefIsValid (keysetCopy))
ab98aa ¤   ¤   return FALSE;
6baf5a
73196e ¤   slen = 0;
144459 ¤   sGetCommentString (PGPGetContextMemoryMgr (pKM->Context),·
7c926c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szComment, sizeof(szComment));
4b7f7b ¤   exportformat =·
0ee94f ¤   ¤   ¤   sGetExportFormat (PGPGetContextMemoryMgr (pKM->Context));
40af5a
2b972e ¤   if (IsntPGPError (PGPclErrorBox (NULL,
ecc3ce ¤   ¤   PGPExportKeySet (keysetCopy,·
4cfa65 ¤   ¤   ¤   ¤   ¤   ¤   PGPOAllocatedOutputBuffer (pKM->Context,
622a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pMem, 0x40000000, &slen),
575eb9 ¤   ¤   ¤   ¤   ¤   ¤   PGPOExportFormat (pKM->Context, exportformat),
13b359 ¤   ¤   ¤   ¤   ¤   ¤   PGPOVersionString (pKM->Context,·
2eabc5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pgpVersionHeaderString),
d2356c ¤   ¤   ¤   ¤   ¤   ¤   PGPOCommentString (pKM->Context, szComment),
d3b53e ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context))))) {
69b86b ¤   ¤   hMem = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, slen+1);
b3172c ¤   ¤   if (hMem) {
d7235e ¤   ¤   ¤   pMemG = GlobalLock (hMem);
0d1b1c ¤   ¤   ¤   if (pMem) {
fcd663 ¤   ¤   ¤   ¤   pMem[slen-2] = '\0';
174827 ¤   ¤   ¤   ¤   memcpy (pMemG, pMem, slen+1);
016d74 ¤   ¤   ¤   ¤   GlobalUnlock (hMem);
e5aa5f ¤   ¤   ¤   ¤   if (phMem) {
073da4 ¤   ¤   ¤   ¤   ¤   *phMem = hMem;
7d3e64 ¤   ¤   ¤   ¤   ¤   bRetVal = TRUE;
362613 ¤   ¤   ¤   ¤   }
5edeaa ¤   ¤   ¤   ¤   else {
001b15 ¤   ¤   ¤   ¤   ¤   if (OpenClipboard (NULL)) {
93c912 ¤   ¤   ¤   ¤   ¤   ¤   EmptyClipboard ();
8bffd4 ¤   ¤   ¤   ¤   ¤   ¤   SetClipboardData (CF_TEXT, hMem);
b2d3a8 ¤   ¤   ¤   ¤   ¤   ¤   CloseClipboard ();
b8fb31 ¤   ¤   ¤   ¤   ¤   ¤   bRetVal = TRUE;
071c89 ¤   ¤   ¤   ¤   ¤   }
532613 ¤   ¤   ¤   ¤   }
536b9e ¤   ¤   ¤   ¤   PGPFreeData (pMem);
e6a3a6 ¤   ¤   ¤   }
e1e323 ¤   ¤   ¤   else GlobalFree (hMem);
980fe4 ¤   ¤   }
de9371 ¤   }
47af5a
6d5bf8 ¤   if (PGPKeySetRefIsValid (keysetCopy))
df3bb2 ¤   ¤   PGPFreeKeySet (keysetCopy);
02af5a
--512e 000ad9e6a3b401102ac Page 10 of KMKeyIO.c
171c35 ¤   return bRetVal;
a6efe6 }
abaf5a
3e9268 //¤ _______________________________________________
de465d //
3ec277 // ·Paste key(s) from clipboard
1daf5a
8a7efe BOOL·
59fa94 KMPasteKeys (PKEYMAN pKM)·
19bb36 {
0928cc ¤   PGPKeySetRef¤   KeySet;
e43fcf ¤   BOOL¤   ¤   ¤   bImport;
d3bf72 ¤   BOOL¤   ¤   ¤   bKeys;
9b92c9 ¤   HANDLE¤ ¤   ¤   hMem;
d7ee31 ¤   LPSTR¤  ¤   ¤   pMem;
91ff42 ¤   size_t¤ ¤   ¤   sLen;
a79ced ¤   HDROP¤  ¤   ¤   hDrop;
19af5a
e74627 ¤   bImport = FALSE;
490ad7 ¤   bKeys = FALSE;
b0c58a ¤   if (OpenClipboard (NULL)) {
161a65 ¤   ¤   hMem = GetClipboardData (CF_HDROP);
3c172c ¤   ¤   if (hMem) {
041f73 ¤   ¤   ¤   hDrop = GlobalLock (hMem);
ed95c4 ¤   ¤   ¤   bImport = KMImportKey (pKM, hDrop);
09501c ¤   ¤   ¤   GlobalUnlock (hMem);
851068 ¤   ¤   ¤   CloseClipboard ();
e6827e ¤   ¤   ¤   return bImport;
290fe4 ¤   ¤   }
916139 ¤   ¤   hMem = GetClipboardData (CF_TEXT);
17172c ¤   ¤   if (hMem) {
3a426a ¤   ¤   ¤   pMem = GlobalLock (hMem);
1e1b1c ¤   ¤   ¤   if (pMem) {
cf6233 ¤   ¤   ¤   ¤   sLen = lstrlen (pMem);
f00f2b ¤   ¤   ¤   ¤   PGPImportKeySet (pKM->Context, &KeySet,·
af0eba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputBuffer (pKM->Context, pMem, sLen),
84ba30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
288c52 ¤   ¤   ¤   ¤   if (KeySet) {
5a4043 ¤   ¤   ¤   ¤   ¤   PGPUInt32¤  numKeys;
4708eb ¤   ¤   ¤   ¤   ¤   (void)PGPCountKeys (KeySet, &numKeys );
72ae30 ¤   ¤   ¤   ¤   ¤
3ab9fc ¤   ¤   ¤   ¤   ¤   if (numKeys > 0) {
d8eb9a ¤   ¤   ¤   ¤   ¤   ¤   bKeys = TRUE;
60d169 ¤   ¤   ¤   ¤   ¤   ¤   if (PGPclQueryAddKeys (pKM->Context,·
8335af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->tlsContext,
f76a99 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, KeySet,·
b7fcf1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetDisp) == kPGPError_NoErr) {
1607cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
a42434 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bImport = TRUE;
4ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
111c89 ¤   ¤   ¤   ¤   ¤   }
8437d0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (KeySet);
2d2613 ¤   ¤   ¤   ¤   }
df6d74 ¤   ¤   ¤   ¤   GlobalUnlock (hMem);
4aa3a6 ¤   ¤   ¤   }
400fe4 ¤   ¤   }
dacc00 ¤   ¤   if (!bKeys) {
f773ed ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
5a42f8 ¤   ¤   ¤   ¤   IDS_NOIMPORTKEYSPASTE, MB_OK|MB_ICONEXCLAMATION);
140fe4 ¤   ¤   }
840440 ¤   ¤   CloseClipboard ();
079371 ¤   }
aaaf5a
aed300 ¤   if (bImport) {
e936e0 ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, TRUE, FALSE);
9d201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
649371 ¤   }
b667c5 ¤
df0eef ¤   return bImport;
6aefe6 }
b0af5a
ad9268 //¤ _______________________________________________
--8ae8 0002710029d401102ac Page 11 of KMKeyIO.c
c1465d //
654964 // ·Drop text key(s)
81af5a
6a7efe BOOL·
bc2ed7 KMDropKeys (
2d713a ¤   ¤   PKEYMAN pKM,·
35e8fd ¤   ¤   HANDLE¤ hMem)·
e0bb36 {
8e28cc ¤   PGPKeySetRef¤   KeySet;
d93fcf ¤   BOOL¤   ¤   ¤   bImport;
1abf72 ¤   BOOL¤   ¤   ¤   bKeys;
91ee31 ¤   LPSTR¤  ¤   ¤   pMem;
c1ff42 ¤   size_t¤ ¤   ¤   sLen;
20af5a
b34627 ¤   bImport = FALSE;
d40ad7 ¤   bKeys = FALSE;
75805f ¤   if (hMem) {
41ad19 ¤   ¤   pMem = GlobalLock (hMem);
4a61e8 ¤   ¤   if (pMem) {
0823c0 ¤   ¤   ¤   sLen = lstrlen (pMem);
b06018 ¤   ¤   ¤   PGPImportKeySet (pKM->Context, &KeySet,·
c215b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputBuffer (pKM->Context, pMem, sLen),
e67e2c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
ec0506 ¤   ¤   ¤   if (KeySet) {
2945ae ¤   ¤   ¤   ¤   PGPUInt32¤  numKeys;
5f87bc ¤   ¤   ¤   ¤   (void)PGPCountKeys (KeySet, &numKeys );
bf2b85 ¤   ¤   ¤   ¤
f5195d ¤   ¤   ¤   ¤   if ( numKeys > 0) {
4d04e9 ¤   ¤   ¤   ¤   ¤   bKeys = TRUE;
c5f931 ¤   ¤   ¤   ¤   ¤   if (bDraggingOut) {
90c8fa ¤   ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL,
f60521 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPAddKeys (KeySet, pKM->KeySetDisp)))) {
7807cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
4e2434 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bImport = TRUE;
33db3c ¤   ¤   ¤   ¤   ¤   ¤   }
621c89 ¤   ¤   ¤   ¤   ¤   }
ed3c4b ¤   ¤   ¤   ¤   ¤   else {
c2d169 ¤   ¤   ¤   ¤   ¤   ¤   if (PGPclQueryAddKeys (pKM->Context,·
aa66b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->tlsContext,
2852aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent,·
463431 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KeySet,·
7b2c5a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetDisp) == kPGPError_NoErr) {
8607cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
0a2434 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bImport = TRUE;
28db3c ¤   ¤   ¤   ¤   ¤   ¤   }
561c89 ¤   ¤   ¤   ¤   ¤   }
b02613 ¤   ¤   ¤   ¤   }
92bfb6 ¤   ¤   ¤   ¤   PGPFreeKeySet (KeySet);
7fa3a6 ¤   ¤   ¤   }
35501c ¤   ¤   ¤   GlobalUnlock (hMem);
a00fe4 ¤   ¤   }
a1cc00 ¤   ¤   if (!bKeys) {
f5e324 ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_NODRAGTEXTKEYS,·
fb4ce5 ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
290fe4 ¤   ¤   }
a39371 ¤   }
1caf5a
20d300 ¤   if (bImport) {
1636e0 ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, TRUE, FALSE);
1d201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
ef9371 ¤   }
6667c5 ¤
4d0eef ¤   return bImport;
85efe6 }
b8af5a
fca3c6 //¤ ___________________________________________
06465d //
810c63 // ·Determine if there is text in the clipboard
8baf5a
597efe BOOL·
f485af KMDataToPaste (VOID)·
27bb36 {
--16a5 001f664fd18401102ac Page 12 of KMKeyIO.c
94ef38 ¤   if (IsClipboardFormatAvailable (CF_TEXT)) return TRUE;
b489b0 ¤   if (IsClipboardFormatAvailable (CF_HDROP)) return TRUE;
d6a230 ¤   return FALSE;
d6efe6 }
ddaf5a
f6af5a
--9b03 000bfa0353e401102ad Page 1 of KMKeyOps.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
156f10 ¤   KMKeyOps.c - implements various operations performed on keys.·
2b67c5 ¤
d3af5a
2f3202 ¤   $Id: KMKeyOps.c,v 1.48 1998/08/12 18:31:22 pbj Exp $
aff7f7 ____________________________________________________________________________*/
75e610 #include "pgpPFLConfig.h"
c4af5a
b9c917 // project header files
ae850a #include "pgpkmx.h"
055fcd #include "pgpclx.h"
abaf5a
135584 // constant definitions
4dabfd #define BITMAP_WIDTH¤   16
9c8af0 #define BITMAP_HEIGHT¤  16
69af5a
f4d11d #define INITIAL_SIGN_COLUMNWIDTH¤   210
90af5a
98a05f #define SIG_NONEXPORTABLE¤  0
f5fecc #define SIG_EXPORTABLE¤ ¤   1
55b65e #define SIG_TRUST¤  ¤   ¤   2
94fc02 #define SIG_META¤   ¤   ¤   3
e8af5a
3e578e // external globals ·
c89cad extern HINSTANCE g_hInst;
abaf5a
965bee // typedefs
e0f0f7 typedef struct {
77f3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
707e47 ¤   PKEYMAN¤¤   ¤   pKM;
cdcdfa ¤   BOOL¤   ¤   ¤   bItemModified;
08382a ¤   PGPKeyRef¤  ¤   keySigning;
1a6d4e ¤   PGPByte*¤   ¤   pPasskey;
10b9e5 ¤   PGPSize¤¤   ¤   sizePasskey;
041ab9 ¤   PGPBoolean¤ ¤   bExportable;
2b6c67 ¤   PGPUInt32¤  ¤   uTrustLevel;
aacd66 ¤   PGPUInt32¤  ¤   uExpireDays;
2f0b8e ¤   CHAR¤   ¤   ¤   szRegExpression[256];
84a5e6 } CERTIFYSTRUCT, *PCERTIFYSTRUCT;
9caf5a
56f0f7 typedef struct {
30f3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
ff8a97 ¤   PGPContextRef¤  context;
bb7e47 ¤   PKEYMAN¤¤   ¤   pKM;
2688ca ¤   LPSTR¤  ¤   ¤   pszPrompt;
bdcdfa ¤   BOOL¤   ¤   ¤   bItemModified;
ac6ea7 ¤   BOOL¤   ¤   ¤   bItemNotDeleted;
8dfad5 ¤   BOOL¤   ¤   ¤   bDeleteAll;
073f7c ¤   BOOL¤   ¤   ¤   bDeletedPrimaryUserID;
1f2795 ¤   PGPKeyRef¤  ¤   keyDefault;
8a322c ¤   HTLITEM¤¤   ¤   hPostDeleteFocusItem;
6d8280 } DELETESTRUCT, *PDELETESTRUCT;
f3af5a
92f0f7 typedef struct {
90f3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
7d7e47 ¤   PKEYMAN¤¤   ¤   pKM;
2c565d ¤   PGPBoolean¤ ¤   bSyncWithServer;
78cc7d ¤   INT¤¤   ¤   ¤   iSigType;
7474c2 ¤   HWND¤   ¤   ¤   hwndList;
aadeab ¤   HWND¤   ¤   ¤   hwndDTPicker;
857be3 ¤   HIMAGELIST¤ ¤   hIml;
243c53 ¤   INT¤¤   ¤   ¤   iItem;
8bb586 ¤   BOOL¤   ¤   ¤   bExpires;
8e6218 ¤   PGPInt32¤   ¤   iExpireDays;
343b20 ¤   BOOL¤   ¤   ¤   bExpandedChoices;
fe4cfd ¤   CHAR¤   ¤   ¤   szDomain[120];
4f3375 } CERTIFYCONFIRMSTRUCT, *PCERTIFYCONFIRMSTRUCT;
fdaf5a
bff0f7 typedef struct {
--ab8d 0002c65af33401102ad Page 2 of KMKeyOps.c
f91fb2 ¤   HWND¤   ¤   ¤   hwndParent;
8cc09c ¤   HWND¤   ¤   ¤   hwndProgress;
0ff498 ¤   INT¤¤   ¤   ¤   iNumSigsTotal;
b47373 ¤   BOOL¤   ¤   ¤   bCancel;
323ab5 } REVERIFYSTRUCT, *PREVERIFYSTRUCT;
ddaf5a
d0a8a5 static DWORD aDeleteAllIds[] = {¤   ¤   ¤   // Help IDs
e69f50 ····IDOK,¤  ¤   ¤   IDH_PGPKM_DELETEKEY,·
ad0e9c ····IDC_YESTOALL,¤  IDH_PGPKM_DELETEALLKEYS,·
b4dea0 ····IDNO,¤  ¤   ¤   IDH_PGPKM_DONTDELETEKEY,·
d5435e ····IDCANCEL,¤  ¤   IDH_PGPKM_CANCELDELETE,·
654434 ····0,0·
46a6fe };·
73af5a
74df70 static DWORD aSignKeyIds[] = {¤ ¤   ¤   // Help IDs
d7446a ¤   IDC_KEYLIST,¤   ¤   IDH_PGPKM_SIGNUSERIDLIST,
87644c ¤   IDC_MORECHOICES,¤   IDH_PGPKM_MORESIGCHOICES,
1acd81 ¤   IDC_EXPORTABLECHECK,IDH_PGPKM_ALLOWSIGEXPORT,
f202cf ¤   IDC_FEWERCHOICES,¤  IDH_PGPKM_FEWERSIGCHOICES,
03e10a ¤   IDC_NONEXPORTABLE,¤ IDH_PGPKM_SIGNONEXPORTABLE,
75aebd ¤   IDC_EXPORTABLE,¤¤   IDH_PGPKM_SIGEXPORTABLE,
b26120 ¤   IDC_TRUSTED,¤   ¤   IDH_PGPKM_SIGTRUSTED,
39bddf ¤   IDC_META,¤  ¤   ¤   IDH_PGPKM_SIGMETA,
3942e0 ¤   IDC_DOMAIN,¤¤   ¤   IDH_PGPKM_DOMAINRESTRICTION,
c26a07 ¤   IDC_NEVEREXPIRES,¤  IDH_PGPKM_SIGNEVEREXPIRES,
e0cfa3 ¤   IDC_EXPIRES,¤   ¤   IDH_PGPKM_SIGEXPIRES,
49369b ¤   IDC_EXPIRATIONDATE,¤IDH_PGPKM_SIGEXPIRATIONDATE,
1e4434 ····0,0·
2aa6fe };·
69af5a
bbaf5a
b19268 //¤ _______________________________________________
aa465d //
39f389 // ·Certify a single object
c1e952 //¤ routine called either from KMCertifyKeyOrUserID or as a
31995b //¤ callback function from the TreeList control to·
f3f11b //¤ certify a single item.
52465d //
299a74 //¤ lptli¤  = pointer to TreeList item to certify
a1af5a
e13f64 static BOOL CALLBACK·
be489e sCertifySingleObject (TL_TREEITEM* lptli,·
aad606 ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)·
6ebb36 {
24ff14 ¤   PCERTIFYSTRUCT¤ pcs¤¤   ¤   = (PCERTIFYSTRUCT)lParam;
403ecb ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
a0af5a
24b9b2 ¤   PGPKeyRef¤  ¤   key;¤
c48f18 ¤   PGPUserIDRef¤   userid;
608a97 ¤   PGPContextRef¤  context;
dfeca3 ¤   CHAR¤   ¤   ¤   sz512[512];
084240 ¤   CHAR¤   ¤   ¤   sz256[256];
5586e8 ¤   CHAR¤   ¤   ¤   sz64[64];
31af5a
386919 ¤   switch (lptli->iImage) {
16493d ¤   case IDX_RSAPUBKEY :
5a6e41 ¤   case IDX_RSAPUBDISKEY :
db5b97 ¤   case IDX_RSASECKEY :
7fb4cd ¤   case IDX_RSASECDISKEY :
82bcd1 ¤   case IDX_RSASECSHRKEY :
d65b28 ¤   case IDX_DSAPUBKEY :
ef7448 ¤   case IDX_DSAPUBDISKEY :
144982 ¤   case IDX_DSASECKEY :
dcaec4 ¤   case IDX_DSASECDISKEY :
aaa6d8 ¤   case IDX_DSASECSHRKEY :
8114a7 ¤   ¤   key = (PGPKeyRef)(lptli->lParam);
aad313 ¤   ¤   PGPGetPrimaryUserID (key, &userid);
782f68 ¤   ¤   break;
89af5a
85b951 ¤   case IDX_RSAUSERID :
47ab44 ¤   case IDX_DSAUSERID :
2c304b ¤   case IDX_PHOTOUSERID :
--49e9 000bb2b85f4401102ad Page 3 of KMKeyOps.c
87b234 ¤   ¤   userid = (PGPUserIDRef)(lptli->lParam);
4f6ed6 ¤   ¤   key = KMGetKeyFromUserID (pcs->pKM, userid);
012f68 ¤   ¤   break;
73af5a
6cfe0b ¤   case IDX_RSAPUBREVKEY :
5e5115 ¤   case IDX_RSAPUBEXPKEY :
b82487 ¤   case IDX_RSASECREVKEY :
eb8b99 ¤   case IDX_RSASECEXPKEY :
c7e402 ¤   case IDX_DSAPUBREVKEY :
b24b1c ¤   case IDX_DSAPUBEXPKEY :
d83e8e ¤   case IDX_DSASECREVKEY :
a19190 ¤   case IDX_DSASECEXPKEY :
7f836c ¤   ¤   return TRUE;
b7af5a
82bfad ¤   default :
4198aa ¤   ¤   return FALSE;
e99371 ¤   }
40af5a
c60838 ¤   context = pcs->pKM->Context;
62af5a
60f23a ¤   // make sure we have enough entropy
901463 ¤   PGPclRandom (context, pcs->pKM->hWndParent, 0);
bbaf5a
aab82a ¤   err = PGPSignUserID (userid, pcs->keySigning,·
41a6bb ¤   ¤   ¤   PGPOExpiration (context, pcs->uExpireDays),
ade7bf ¤   ¤   ¤   PGPOExportable (context, pcs->bExportable),
54ff32 ¤   ¤   ¤   PGPOSigTrust (context, pcs->uTrustLevel,·
d83e2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyTrust_Complete),
27736a ¤   ¤   ¤   (pcs->pPasskey) ?
d2b8cf ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pcs->pPasskey, pcs->sizePasskey) :
9a6d47 ¤   ¤   ¤   ¤   PGPONullOption (context),
69e21e ¤   ¤   ¤   (pcs->szRegExpression[0]) ?
e83899 ¤   ¤   ¤   ¤   PGPOSigRegularExpression (context, pcs->szRegExpression) :
aa6d47 ¤   ¤   ¤   ¤   PGPONullOption (context),
836445 ¤   ¤   ¤   PGPOLastOption (context));
83af5a
12b23e ¤   if (IsntPGPError (err)) {
93baaa ¤   ¤   pcs->bItemModified = TRUE;
6e836c ¤   ¤   return TRUE;
379371 ¤   }
02af5a
53b924 ¤   LoadString (g_hInst, IDS_CERTIFYERROR, sz64, 64);·
67ce47 ¤   PGPclErrorToString (err, sz256, 256);
af482e ¤   wsprintf (sz512, sz64, lptli->pszText, sz256);
afb439 ¤   LoadString (g_hInst, IDS_CAPTION, sz64, 64);
6e0fd8 ¤   if (KMMultipleSelected (pcs->pKM)) {
91d6bb ¤   ¤   if (MessageBox (pcs->pKM->hWndParent, sz512, sz64,·
f65b31 ¤   ¤   ¤   ¤   ¤   ¤   MB_OKCANCEL|MB_ICONEXCLAMATION) == IDOK)
ea32bd ¤   ¤   ¤   return TRUE;
029371 ¤   }
ef665a ¤   else {
9fd6bb ¤   ¤   if (MessageBox (pcs->pKM->hWndParent, sz512, sz64,·
c2eef6 ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION) == IDOK)
0132bd ¤   ¤   ¤   return TRUE;
5e9371 ¤   }
28af5a
3aa230 ¤   return FALSE;
74efe6 }
bcaf5a
b3af5a
a39268 //¤ _______________________________________________
fa465d //
a4e0b1 // ·Populate ListView with userids to sign
7faf5a
693f64 static BOOL CALLBACK·
9db843 sInsertOneID (TL_TREEITEM* lptli, LPARAM lParam)·
04bb36 {
916c94 ¤   PCERTIFYCONFIRMSTRUCT pccs = (PCERTIFYCONFIRMSTRUCT)lParam;
a2af5a
3db9b2 ¤   PGPKeyRef¤  ¤   key;¤
fb8f18 ¤   PGPUserIDRef¤   userid;
bb3512 ¤   UINT¤   ¤   ¤   u, uAlgorithm;
--7d9f 000e7c03243401102ad Page 4 of KMKeyOps.c
6882cc ¤   LV_ITEM¤¤   ¤   lvI;
e20524 ¤   PGPByte¤¤   ¤   fingerprintBytes[256];
c231b9 ¤   CHAR¤   ¤   ¤   sz[kPGPMaxUserIDSize];
bdaf5a
b46919 ¤   switch (lptli->iImage) {
bb493d ¤   case IDX_RSAPUBKEY :
796e41 ¤   case IDX_RSAPUBDISKEY :
a85b97 ¤   case IDX_RSASECKEY :
29b4cd ¤   case IDX_RSASECDISKEY :
b2bcd1 ¤   case IDX_RSASECSHRKEY :
875b28 ¤   case IDX_DSAPUBKEY :
da7448 ¤   case IDX_DSAPUBDISKEY :
cf4982 ¤   case IDX_DSASECKEY :
35aec4 ¤   case IDX_DSASECDISKEY :
02a6d8 ¤   case IDX_DSASECSHRKEY :
2414a7 ¤   ¤   key = (PGPKeyRef)(lptli->lParam);
42541b ¤   ¤   KMGetKeyName (key, sz, sizeof(sz));
a02f68 ¤   ¤   break;
09af5a
e5b951 ¤   case IDX_RSAUSERID :
16ab44 ¤   case IDX_DSAUSERID :
e4304b ¤   case IDX_PHOTOUSERID :
7cb234 ¤   ¤   userid = (PGPUserIDRef)(lptli->lParam);
48ef01 ¤   ¤   key = KMGetKeyFromUserID (pccs->pKM, userid);
ec8a99 ¤   ¤   KMGetUserIDName (userid, sz, sizeof(sz));
eb2f68 ¤   ¤   break;
e5af5a
a1fe0b ¤   case IDX_RSAPUBREVKEY :
655115 ¤   case IDX_RSAPUBEXPKEY :
282487 ¤   case IDX_RSASECREVKEY :
5d8b99 ¤   case IDX_RSASECEXPKEY :
cae402 ¤   case IDX_DSAPUBREVKEY :
434b1c ¤   case IDX_DSAPUBEXPKEY :
a13e8e ¤   case IDX_DSASECREVKEY :
b49190 ¤   case IDX_DSASECEXPKEY :
a8836c ¤   ¤   return TRUE;
fcaf5a
37bfad ¤   default :
b498aa ¤   ¤   return FALSE;
ba9371 ¤   }
87af5a
570b74 ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &uAlgorithm);
2eeef4 ¤   switch (uAlgorithm) {
4ba297 ¤   ¤   case kPGPPublicKeyAlgorithm_RSA :¤  lvI.iImage = IDX_RSAUSERID;¤break;
8af2c7 ¤   ¤   case kPGPPublicKeyAlgorithm_DSA :¤  lvI.iImage = IDX_DSAUSERID;¤break;
120a5c ¤   ¤   default :¤  ¤   ¤   ¤   ¤   ¤   ¤   lvI.iImage = IDX_RSAUSERID; break;
b89371 ¤   }
5baf5a
4e0590 ¤   lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
a47fa6 ¤   lvI.state = 0; ·····
49a982 ¤   lvI.stateMask = 0; ·
2caf5a
4a9ed1 ¤   lvI.iItem = pccs->iItem;
ea505a ¤   lvI.iSubItem = 0;
76eda9 ¤   lvI.pszText¤= sz;·
68fa85 ¤   lvI.cchTextMax = 0;
18af5a
48c20f ¤   if (ListView_InsertItem (pccs->hwndList, &lvI) == -1) return FALSE;
02af5a
a90e52 ¤   PGPGetKeyPropertyBuffer (key, kPGPKeyPropFingerprint,
e0d344 ¤   ¤   ¤   ¤   ¤   sizeof(fingerprintBytes), fingerprintBytes, &u);
96a274 ¤   KMConvertStringFingerprint (uAlgorithm, fingerprintBytes);
a521e4 ¤   ListView_SetItemText (pccs->hwndList, pccs->iItem, 1, fingerprintBytes);
48af5a
9d83ff ¤   (pccs->iItem)++;
1267c5 ¤
ffc2e7 ¤   return TRUE;
04efe6 }
66af5a
8aaf5a
3a9268 //¤ _______________________________________________
e7465d //
--5831 000987ce2e8401102ad Page 5 of KMKeyOps.c
55e0b1 // ·Populate ListView with userids to sign
dfaf5a
25b333 static VOID·
edf1c6 sFillKeyList (PCERTIFYCONFIRMSTRUCT pccs)·
cebb36 {
dfaf5a
afc89d ¤   LV_COLUMN¤  lvC;·
2ccdba ¤   CHAR¤   ¤   sz[256];
43f493 ¤   HBITMAP¤¤   hBmp;
c118a8 ¤   HDC¤¤   ¤   hDC;
ba0863 ¤   INT¤¤   ¤   iNumBits;
dcaf5a
ad4f7a ¤   // create image list
9e7f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
5389fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
bee693 ¤   ReleaseDC (NULL, hDC);
b0af5a
df2be4 ¤   if (iNumBits <= 8) {
7bc7ed ¤   ¤   pccs->hIml = ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
146d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
0c9694 ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
de85ad ¤   ¤   ImageList_AddMasked (pccs->hIml, hBmp, RGB(255, 0, 255));
695c8d ¤   ¤   DeleteObject (hBmp);
279371 ¤   }
75665a ¤   else {
e84c30 ¤   ¤   pccs->hIml = ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
1c6d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
d9bb8b ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
3285ad ¤   ¤   ImageList_AddMasked (pccs->hIml, hBmp, RGB(255, 0, 255));
f25c8d ¤   ¤   DeleteObject (hBmp);
9c9371 ¤   }
50af5a
36331e ¤   ListView_SetImageList (pccs->hwndList, pccs->hIml, LVSIL_SMALL);
47af5a
5a3e53 ¤   lvC.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
024e45 ¤   lvC.fmt = LVCFMT_LEFT;·
1334b0 ¤   lvC.pszText = sz;
fbaf5a
aa5e6b ¤   LoadString (g_hInst, IDS_USERID, sz, sizeof(sz));
05637c ¤   lvC.cx = INITIAL_SIGN_COLUMNWIDTH; ··
3214af ¤   lvC.iSubItem = 0;
eaab96 ¤   if (ListView_InsertColumn (pccs->hwndList, 0, &lvC) == -1) return;
27af5a
784ff8 ¤   LoadString (g_hInst, IDS_FINGERPRINT, sz, sizeof(sz));
453d12 ¤   lvC.cx = 360; ··
194e73 ¤   lvC.iSubItem = 1;
fbf0d2 ¤   if (ListView_InsertColumn (pccs->hwndList, 1, &lvC) == -1) return;
b4af5a
7e0130 ¤   // populate control by iterating through selected items
62310c ¤   pccs->lpfnCallback = sInsertOneID;
fc2d92 ¤   pccs->iItem = 0;
86d05f ¤   TreeList_IterateSelected (pccs->pKM->hWndTree, pccs);
dbefe6 }
2baf5a
ccaf5a
b09268 //¤ _______________________________________________
a3465d //
d22be8 //¤ Convert domain string to regular expression
2aaf5a
0be6b2 static VOID
df1669 sDomainToRegExpression (
bf2df6 ¤   LPSTR¤  ¤   szDomain,
b3d2cb ¤   LPSTR¤  ¤   szRegExp)
b8bb36 {
307849 ¤   LPSTR ¤ ¤   pszSrc¤ ¤   = szDomain;
96b366 ¤   LPSTR¤  ¤   pszDst¤ ¤   = szRegExp;
c367c5 ¤
5c839c ¤   lstrcpy (pszDst, "<[^>]+[@.]");
d809f5 ¤   pszDst += lstrlen (pszDst);
bcaf5a
d1813c ¤   for ( ; *pszSrc; pszSrc++)
98c7a1 ¤   {
--40c2 0004c32c9b2401102ad Page 6 of KMKeyOps.c
4dc51d ¤   ¤   switch (*pszSrc)
0e5b34 ¤   ¤   {
df7d84 ¤   ¤   ¤   case '*':
94613f ¤   ¤   ¤   case '+':
63d072 ¤   ¤   ¤   case '?':
510f68 ¤   ¤   ¤   case '.':
6c552d ¤   ¤   ¤   case '^':
86d3c6 ¤   ¤   ¤   case '$':
081578 ¤   ¤   ¤   case '\\':
433b7a ¤   ¤   ¤   case '[':
d870e0 ¤   ¤   ¤   case ']':
472aa5 ¤   ¤   ¤   case '-':
80ee10 ¤   ¤   ¤   ¤   *pszDst++ = '\\';
bb2ae2 ¤   ¤   ¤   ¤   *pszDst++ = *pszSrc;
f3f622 ¤   ¤   ¤   ¤   break;
4ddb68 ¤   ¤   ¤   default:
a82ae2 ¤   ¤   ¤   ¤   *pszDst++ = *pszSrc;
def622 ¤   ¤   ¤   ¤   break;
e70fe4 ¤   ¤   }
709371 ¤   }
467d7e ¤   *pszDst++ = '>';
936271 ¤   *pszDst++ = '$';
339929 ¤   *pszDst++ = '\0';
dfefe6 }
eaaf5a
4b9268 //¤ _______________________________________________
2c465d //
934d40 //¤ Sign key dialog message procedure
b4af5a
463f64 static BOOL CALLBACK·
07945b sSignKeyDlgProc (
603a3a ¤   ¤   HWND¤   hDlg,·
7eeb77 ¤   ¤   UINT¤   uMsg,·
7017d4 ¤   ¤   WPARAM¤ wParam,·
4dc0b8 ¤   ¤   LPARAM¤ lParam)·
e5bb36 {
08d6c5 ¤   PCERTIFYCONFIRMSTRUCT¤  pccs;
4f9f79 ¤   INT¤¤   ¤   ¤   ¤   ¤   iNewY, iNewWindowHeight, iOffset;
d13302 ¤   HWND¤   ¤   ¤   ¤   ¤   hwndControl;
40e7b3 ¤   RECT¤   ¤   ¤   ¤   ¤   rectControl;
a0035d ¤   RECT¤   ¤   ¤   ¤   ¤   rc;
67dab4 ¤   HDC¤¤   ¤   ¤   ¤   ¤   hdc;
a9af5a
30347f ¤   switch (uMsg) {
f3af5a
daad3a ¤   case WM_INITDIALOG :
117547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
dc1353 ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)lParam;
fe06fd ¤   ¤   pccs->hwndList = GetDlgItem (hDlg, IDC_KEYLIST);
d3af5a
b1f9a9 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_MORECHOICES), TRUE);
91463a ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_MORECHOICES), SW_SHOW);
b773d6 ¤   ¤   pccs->bExpandedChoices = FALSE;
35af5a
be190b ¤   ¤   sFillKeyList (pccs);
f7af5a
8744c6 ¤   ¤   // create and initialize date/time picker control
34cf7d ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_EXPIRATIONDATE), &rc);
304f66 ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
450849 ¤   ¤   pccs->hwndDTPicker = CreateWindowEx (0, DATETIMEPICK_CLASS,
bb3d5e ·····························"DateTime",
382052 ·····························WS_BORDER|WS_CHILD|WS_TABSTOP,
a3d631 ·····························rc.left, rc.top,·
1879ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·rc.right-rc.left, rc.bottom-rc.top,·
5cc779 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hDlg, (HMENU)IDC_EXPIRATIONDATE,·
5cd5a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·g_hInst, NULL);
237c2f ¤   ¤   SetWindowPos (pccs->hwndDTPicker,·
3bd4f7 ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_EXPIRATIONDATE),
7038dd ¤   ¤   ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
a44e2f ¤   ¤   SendMessage (pccs->hwndDTPicker, DTM_SETMCCOLOR,·
b46e0e ¤   ¤   ¤   ¤   ¤   ¤   MCSC_MONTHBK, (LPARAM)GetSysColor (COLOR_3DFACE));
4c32de ¤   ¤   EnableWindow (pccs->hwndDTPicker, FALSE);
--00f1 000fe395d75401102ad Page 7 of KMKeyOps.c
9a67ad ¤   ¤   CheckDlgButton (hDlg, IDC_NEVEREXPIRES, BST_CHECKED);
be1b52 ¤   ¤
3ec49e ¤   ¤   // user "more" button as desired Y location
28c66c ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_MORECHOICES);
03d220 ¤   ¤   GetWindowRect (hwndControl, &rectControl);
8500fd ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
5faf5a
677c10 ¤   ¤   GetWindowRect (hDlg, &rc);
623062 ¤   ¤   iOffset = rc.bottom-rc.top;
9d289b ¤   ¤   GetClientRect (hDlg, &rc);
04191f ¤   ¤   iOffset -= rc.bottom;
a55ba4 ¤   ¤   iOffset += (rectControl.bottom - rectControl.top) / 2;
e5af5a
0a41ad ¤   ¤   iNewY = rectControl.top;
5f8d0e ¤   ¤   iNewWindowHeight = rectControl.bottom + iOffset;
3baf5a
338d7b ¤   ¤   // move OK Button
46a312 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDOK);
08d220 ¤   ¤   GetWindowRect (hwndControl, &rectControl);
0c00fd ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
e09516 ¤   ¤   MoveWindow(¤hwndControl,·
3a7719 ¤   ¤   ¤   ¤   ¤   rectControl.left,
74f7d1 ¤   ¤   ¤   ¤   ¤   iNewY,
92628d ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
2b7ae9 ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
658584 ¤   ¤   ¤   ¤   ¤   TRUE);
26af5a
5210a4 ¤   ¤   // move Cancel Button
d8b374 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDCANCEL);
5ad220 ¤   ¤   GetWindowRect (hwndControl, &rectControl);
d300fd ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
e99516 ¤   ¤   MoveWindow(¤hwndControl,·
787719 ¤   ¤   ¤   ¤   ¤   rectControl.left,
26f7d1 ¤   ¤   ¤   ¤   ¤   iNewY,
6c628d ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
107ae9 ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
8e8584 ¤   ¤   ¤   ¤   ¤   TRUE);
77af5a
cadadf ¤   ¤   // move Help Button
9a0013 ¤   ¤   hwndControl = GetDlgItem (hDlg, IDHELP);
63d220 ¤   ¤   GetWindowRect (hwndControl, &rectControl);
8000fd ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
4f9516 ¤   ¤   MoveWindow(¤hwndControl,·
9e7719 ¤   ¤   ¤   ¤   ¤   rectControl.left,
f8f7d1 ¤   ¤   ¤   ¤   ¤   iNewY,
35628d ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
f27ae9 ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
178584 ¤   ¤   ¤   ¤   ¤   TRUE);
6daf5a
a42914 ¤   ¤   // size Window·
bdbb93 ¤   ¤   GetWindowRect (hDlg, &rectControl);
084228 ¤   ¤   MoveWindow(¤hDlg,·
c97719 ¤   ¤   ¤   ¤   ¤   rectControl.left,
9986bf ¤   ¤   ¤   ¤   ¤   rectControl.top,
56628d ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
0c69db ¤   ¤   ¤   ¤   ¤   iNewWindowHeight,
bf8584 ¤   ¤   ¤   ¤   ¤   TRUE);
caaf5a
ce2f68 ¤   ¤   break;
a1af5a
b4c3eb ····case WM_HELP:·
526089 ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
8a1c96 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pccs->pKM->szHelpFile,·
ca5cdb ············HELP_WM_HELP, (DWORD) (LPSTR) aSignKeyIds);·
c38f13 ········break;·
a8d83c ·
86daf9 ····case WM_CONTEXTMENU:
776089 ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
80b505 ········WinHelp ((HWND) wParam, pccs->pKM->szHelpFile, HELP_CONTEXTMENU,·
848a56 ············(DWORD) (LPVOID) aSignKeyIds);·
ed8f13 ········break;·
feaf5a
--c5cf 0004260213b401102ad Page 8 of KMKeyOps.c
dfc93c ¤   case WM_NOTIFY:
995b34 ¤   ¤   {
465808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
28af5a
666774 ¤   ¤   ¤   if (pnmh->code == DTN_DATETIMECHANGE) {
68c905 ¤   ¤   ¤   ¤   SYSTEMTIME st;
ebe7e8 ¤   ¤   ¤   ¤   pccs =·
81d959 ¤   ¤   ¤   ¤   ¤   (PCERTIFYCONFIRMSTRUCT)GetWindowLong(hDlg, GWL_USERDATA);
0044c9 ¤   ¤   ¤   ¤   SendMessage (pccs->hwndDTPicker, DTM_GETSYSTEMTIME,
24d2ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&st);
18d235 ¤   ¤   ¤   ¤   PGPclSystemTimeToDays (&st, &(pccs->iExpireDays));
fd3b06 ¤   ¤   ¤   ¤   if (pccs->iExpireDays > 0)·
ae278e ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
3f5109 ¤   ¤   ¤   ¤   else·
94f627 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
18a3a6 ¤   ¤   ¤   }
bd0fe4 ¤   ¤   }
cb2f68 ¤   ¤   break;
28af5a
6f85ca ¤   case WM_PAINT :
3a6089 ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
e8a89e ¤   ¤   if (pccs->bExpandedChoices) {
7e9141 ¤   ¤   ¤   // paint icons
d0d7f7 ¤   ¤   ¤   hdc = GetDC (hDlg);
0caf5a
8ab663 ¤   ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_NONEXPORTABLE), &rc);
4c485d ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
bd7c69 ¤   ¤   ¤   ImageList_Draw (pccs->hIml, IDX_CERT, hdc,·
83b878 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left-22, rc.top, ILD_TRANSPARENT);
2faf5a
4b8a23 ¤   ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_EXPORTABLE), &rc);
6b485d ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
b4e916 ¤   ¤   ¤   ImageList_Draw (pccs->hIml, IDX_EXPORTCERT, hdc,·
95b878 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left-22, rc.top, ILD_TRANSPARENT);
61af5a
0725e1 ¤   ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_TRUSTED), &rc);
08485d ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
84b0c5 ¤   ¤   ¤   ImageList_Draw (pccs->hIml, IDX_TRUSTEDCERT, hdc,·
2fb878 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left-22, rc.top, ILD_TRANSPARENT);
2faf5a
4ab883 ¤   ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_META), &rc);
72485d ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
b1e618 ¤   ¤   ¤   ImageList_Draw (pccs->hIml, IDX_METACERT, hdc,·
4ab878 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left-22, rc.top, ILD_TRANSPARENT);
5caf5a
7d6bee ¤   ¤   ¤   ReleaseDC (hDlg, hdc);
8b0fe4 ¤   ¤   }
102f68 ¤   ¤   break;
e0af5a
813fcf ¤   case WM_COMMAND:
e1af5a
55537d ¤   ¤   switch (LOWORD(wParam)) {
3371eb ¤   ¤   case IDCANCEL:
8b19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
0f3327 ¤   ¤   ¤   pccs->bSyncWithServer = FALSE;
125d4b ¤   ¤   ¤   ImageList_Destroy (pccs->hIml);
0df3d5 ¤   ¤   ¤   EndDialog (hDlg, 1);
b8cdcb ¤   ¤   ¤   break;
88af5a
c53860 ¤   ¤   case IDOK:
cf19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
31d149 ¤   ¤   ¤   if (!(pccs->bExpandedChoices)) {
99e30d ¤   ¤   ¤   ¤   pccs->bExpires = FALSE;
691cae ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_EXPORTABLECHECK)·
156274 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   == BST_CHECKED)·
6972c3 ¤   ¤   ¤   ¤   {
e7aa8f ¤   ¤   ¤   ¤   ¤   pccs->iSigType = SIG_EXPORTABLE;
ec2613 ¤   ¤   ¤   ¤   }
74deaa ¤   ¤   ¤   ¤   else {
fddee8 ¤   ¤   ¤   ¤   ¤   pccs->iSigType = SIG_NONEXPORTABLE;
1d2613 ¤   ¤   ¤   ¤   }
42a3a6 ¤   ¤   ¤   }
--7f41 0004af44205401102ad Page 9 of KMKeyOps.c
6ee543 ¤   ¤   ¤   else {
00ec10 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_NEVEREXPIRES)·
c21415 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   == BST_CHECKED)
516b6b ¤   ¤   ¤   ¤   ¤   pccs->bExpires = FALSE;
7fdeaa ¤   ¤   ¤   ¤   else {
95457a ¤   ¤   ¤   ¤   ¤   SYSTEMTIME st;
49edd8 ¤   ¤   ¤   ¤   ¤   pccs->bExpires = TRUE;
a8a2cb ¤   ¤   ¤   ¤   ¤   SendMessage (pccs->hwndDTPicker, DTM_GETSYSTEMTIME, 0,·
c7f9cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&st);
67c1b9 ¤   ¤   ¤   ¤   ¤   PGPclSystemTimeToDays (&st, &(pccs->iExpireDays));
072613 ¤   ¤   ¤   ¤   }
cea3a6 ¤   ¤   ¤   }
388daa ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_DOMAIN,·
375844 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pccs->szDomain, sizeof(pccs->szDomain));
2e5d4b ¤   ¤   ¤   ImageList_Destroy (pccs->hIml);
b9ef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
fecdcb ¤   ¤   ¤   break;
e9af5a
7eddc3 ¤   ¤   case IDC_EXPORTABLECHECK :
2e19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
9c21c0 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_EXPORTABLECHECK)·
ca604d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   == BST_CHECKED) {
33f994 ¤   ¤   ¤   ¤   pccs->iSigType = SIG_EXPORTABLE;
58a3a6 ¤   ¤   ¤   }
cee543 ¤   ¤   ¤   else {
a28b44 ¤   ¤   ¤   ¤   pccs->iSigType = SIG_NONEXPORTABLE;
0aa3a6 ¤   ¤   ¤   }
2dcdcb ¤   ¤   ¤   break;
05af5a
44cce8 ¤   ¤   case IDC_NONEXPORTABLE :
7a19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
981d05 ¤   ¤   ¤   pccs->iSigType = SIG_NONEXPORTABLE;
3146ec ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN), FALSE);
dacdcb ¤   ¤   ¤   break;
28af5a
ca0c45 ¤   ¤   case IDC_EXPORTABLE :
bb19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
8eab09 ¤   ¤   ¤   pccs->iSigType = SIG_EXPORTABLE;
dd46ec ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN), FALSE);
cdcdcb ¤   ¤   ¤   break;
61af5a
33a63f ¤   ¤   case IDC_TRUSTED :
4b19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
c2ce81 ¤   ¤   ¤   pccs->iSigType = SIG_TRUST;
734f6b ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN), TRUE);
01cdcb ¤   ¤   ¤   break;
96af5a
2859d1 ¤   ¤   case IDC_META :
7b19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
efc41c ¤   ¤   ¤   pccs->iSigType = SIG_META;
b246ec ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN), FALSE);
68cdcb ¤   ¤   ¤   break;
60af5a
81644a ¤   ¤   case IDC_NEVEREXPIRES :
a4fbff ¤   ¤   case IDC_EXPIRES :
dc19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
878031 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_EXPIRES) == BST_CHECKED) {
ffc905 ¤   ¤   ¤   ¤   SYSTEMTIME st;
1dfe44 ¤   ¤   ¤   ¤   EnableWindow (pccs->hwndDTPicker, TRUE);
d3af5a
1744c9 ¤   ¤   ¤   ¤   SendMessage (pccs->hwndDTPicker, DTM_GETSYSTEMTIME,
87d2ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&st);
ead235 ¤   ¤   ¤   ¤   PGPclSystemTimeToDays (&st, &(pccs->iExpireDays));
b53b06 ¤   ¤   ¤   ¤   if (pccs->iExpireDays > 0)·
2a278e ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
a95109 ¤   ¤   ¤   ¤   else·
4ff627 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
8ea3a6 ¤   ¤   ¤   }
81e543 ¤   ¤   ¤   else {
489fa8 ¤   ¤   ¤   ¤   EnableWindow (pccs->hwndDTPicker, FALSE);
d19b97 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
4aa3a6 ¤   ¤   ¤   }
--32f8 000c2a2d95b401102ad Page 10 of KMKeyOps.c
7ecdcb ¤   ¤   ¤   break;
f8af5a
2d0731 ¤   ¤   case IDC_MORECHOICES :
6919c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
e49f0c ¤   ¤   ¤   pccs->bExpandedChoices = TRUE;
a22942 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_MORECHOICES), SW_HIDE);
6ccb90 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPORTABLECHECK), SW_HIDE);
c461af ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_FEWERCHOICES), SW_SHOW);
6e73ad ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_SIGTYPE), SW_SHOW);
09f62c ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_NONEXPORTABLE), SW_SHOW);
e7a22a ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPORTABLE), SW_SHOW);
3031b4 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_TRUSTED), SW_SHOW);
3e4d10 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_META), SW_SHOW);
d0a22f ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPIRATION), SW_SHOW);
58b8ae ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_NEVEREXPIRES), SW_SHOW);
6cd61c ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPIRES), SW_SHOW);
5ac546 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_DOMAINTEXT), SW_SHOW);
439e71 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_DOMAIN), SW_SHOW);
e6e0d6 ¤   ¤   ¤   ShowWindow (pccs->hwndDTPicker, SW_SHOW);
ceaf5a
a73b4d ¤   ¤   ¤   // user "fewer" button as desired Y location
db24b8 ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_FEWERCHOICES);
0ac307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
213d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
4aaf5a
a73de3 ¤   ¤   ¤   GetWindowRect (hDlg, &rc);
f9f537 ¤   ¤   ¤   iOffset = rc.bottom-rc.top;
4f6968 ¤   ¤   ¤   GetClientRect (hDlg, &rc);
7d2e17 ¤   ¤   ¤   iOffset -= rc.bottom;
61d658 ¤   ¤   ¤   iOffset += (rectControl.bottom - rectControl.top) / 2;
b3af5a
2e7cc5 ¤   ¤   ¤   iNewY = rectControl.top;
41abbb ¤   ¤   ¤   iNewWindowHeight = rectControl.bottom + iOffset;
a0af5a
c6042f ¤   ¤   ¤   // move OK Button
c17ba0 ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDOK);
42c307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
a43d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
ad7a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
8e4bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
2de3f9 ¤   ¤   ¤   ¤   ¤   ¤   iNewY,
dd808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
c198e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
1e91ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
e1af5a
9427ac ¤   ¤   ¤   // move Cancel Button
37a253 ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDCANCEL);
95c307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
593d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
407a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
f64bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
b0e3f9 ¤   ¤   ¤   ¤   ¤   ¤   iNewY,
87808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
fc98e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
f091ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
0eaf5a
d27781 ¤   ¤   ¤   // move Help Button
4f5308 ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDHELP);
0ec307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
ca3d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
c57a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
634bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
1ce3f9 ¤   ¤   ¤   ¤   ¤   ¤   iNewY,
63808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
8298e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
8091ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
a5af5a
63eb50 ¤   ¤   ¤   // set radio buttons
5c9f95 ¤   ¤   ¤   CheckRadioButton (hDlg, IDC_NONEXPORTABLE, IDC_META,·
ada83c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_NONEXPORTABLE + pccs->iSigType);
123492 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_DOMAIN),·
c2f6f2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pccs->iSigType == SIG_META));
--0f65 0007e9497c1401102ad Page 11 of KMKeyOps.c
e0af5a
59df71 ¤   ¤   ¤   // size Window·
7ca3c3 ¤   ¤   ¤   GetWindowRect (hDlg, &rectControl);
375600 ¤   ¤   ¤   MoveWindow(¤hDlg,·
484bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
f78352 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
e6808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
db5535 ¤   ¤   ¤   ¤   ¤   ¤   iNewWindowHeight,
0b91ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
52af5a
93cdcb ¤   ¤   ¤   break;
caaf5a
bd8b82 ¤   ¤   case IDC_FEWERCHOICES :
9e19c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
3ffbb0 ¤   ¤   ¤   pccs->bExpandedChoices = FALSE;
f65319 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_MORECHOICES), SW_SHOW);
97b1cb ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPORTABLECHECK), SW_SHOW);
e21bf4 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_FEWERCHOICES), SW_HIDE);
8909f6 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_SIGTYPE), SW_HIDE);
e58c77 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_NONEXPORTABLE), SW_HIDE);
e8d871 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPORTABLE), SW_HIDE);
d24bef ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_TRUSTED), SW_HIDE);
ca374b ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_META), SW_HIDE);
94d874 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPIRATION), SW_HIDE);
97c2f5 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_NEVEREXPIRES), SW_HIDE);
b3ac47 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_EXPIRES), SW_HIDE);
1fbf1d ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_DOMAINTEXT), SW_HIDE);
cae42a ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_DOMAIN), SW_HIDE);
459a8d ¤   ¤   ¤   ShowWindow (pccs->hwndDTPicker, SW_HIDE);
b8af5a
fc9132 ¤   ¤   ¤   // user "more" button as desired Y location
b6246c ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDC_MORECHOICES);
fcc307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
953d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
e6af5a
903de3 ¤   ¤   ¤   GetWindowRect (hDlg, &rc);
7bf537 ¤   ¤   ¤   iOffset = rc.bottom-rc.top;
8c6968 ¤   ¤   ¤   GetClientRect (hDlg, &rc);
a32e17 ¤   ¤   ¤   iOffset -= rc.bottom;
59d658 ¤   ¤   ¤   iOffset += (rectControl.bottom - rectControl.top) / 2;
6daf5a
387cc5 ¤   ¤   ¤   iNewY = rectControl.top;
aaabbb ¤   ¤   ¤   iNewWindowHeight = rectControl.bottom + iOffset;
4daf5a
47042f ¤   ¤   ¤   // move OK Button
137ba0 ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDOK);
58c307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
7a3d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
ab7a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
c24bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
06e3f9 ¤   ¤   ¤   ¤   ¤   ¤   iNewY,
cd808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
c098e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
f791ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
84af5a
9427ac ¤   ¤   ¤   // move Cancel Button
04a253 ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDCANCEL);
6ec307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
bd3d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
a97a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
cd4bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
7ee3f9 ¤   ¤   ¤   ¤   ¤   ¤   iNewY,
39808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
1b98e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
da91ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
56af5a
8c7781 ¤   ¤   ¤   // move Help Button
645308 ¤   ¤   ¤   hwndControl = GetDlgItem (hDlg, IDHELP);
a6c307 ¤   ¤   ¤   GetWindowRect (hwndControl, &rectControl);
803d93 ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rectControl, 2);
a57a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
7e4bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
--2a62 0009570571b401102ad Page 12 of KMKeyOps.c
f5e3f9 ¤   ¤   ¤   ¤   ¤   ¤   iNewY,
cf808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
aa98e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
b291ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
57af5a
5beb50 ¤   ¤   ¤   // set radio buttons
e766d0 ¤   ¤   ¤   if (pccs->iSigType == SIG_EXPORTABLE)·
9a17a5 ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_EXPORTABLECHECK, BST_CHECKED);
1dbb8c ¤   ¤   ¤   else
4f697d ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_EXPORTABLECHECK, BST_UNCHECKED);
99af5a
17df71 ¤   ¤   ¤   // size Window·
12a3c3 ¤   ¤   ¤   GetWindowRect (hDlg, &rectControl);
f65600 ¤   ¤   ¤   MoveWindow(¤hDlg,·
df4bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
3f8352 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
c3808d ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
855535 ¤   ¤   ¤   ¤   ¤   ¤   iNewWindowHeight,
db91ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
7bcdcb ¤   ¤   ¤   break;
c9af5a
dc43f5 ¤   ¤   case IDHELP :
1519c3 ¤   ¤   ¤   pccs = (PCERTIFYCONFIRMSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
41af5c ¤   ¤   ¤   WinHelp (hDlg, pccs->pKM->szHelpFile, HELP_CONTEXT,·
0276a5 ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPKM_SIGNDIALOG);·
47cdcb ¤   ¤   ¤   break;
c7af5a
2a0fe4 ¤   ¤   }
99836c ¤   ¤   return TRUE;
1f9371 ¤   }
4ba230 ¤   return FALSE;
61efe6 }
4eaf5a
3eaf5a
ec9268 //¤ _______________________________________________
75465d //
191ce6 // ·Certify selected key or userid
eaaf5a
337efe BOOL·
bf31ac KMCertifyKeyOrUserID (PKEYMAN pKM)·
b7bb36 {
25e7a8 ¤   CHAR¤   ¤   ¤   ¤   ¤   sz256[256];
2eba49 ¤   PGPError¤   ¤   ¤   ¤   err;
c5ee76 ¤   CERTIFYSTRUCT¤  ¤   ¤   cs;
7179a0 ¤   CERTIFYCONFIRMSTRUCT¤   ccs;
719526 ¤   PGPPrefRef¤ ¤   ¤   ¤   prefref;
b8af5a
b13da6 ¤   // initialize structures
93ea47 ¤   cs.lpfnCallback = sCertifySingleObject;
21b1c1 ¤   cs.pKM = pKM;
3c95f4 ¤   cs.bItemModified = FALSE;
228b07 ¤   cs.keySigning = NULL;
78f652 ¤   cs.pPasskey = NULL;
fd67c5 ¤
89d8c2 ¤   ccs.pKM = pKM;
da4e35 ¤   ccs.iSigType = SIG_NONEXPORTABLE;
6d47db ¤   ccs.bExpires = FALSE;
82acdb ¤   ccs.iExpireDays = 0;
94af5a
59410a ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), &prefref);
f65907 ¤   PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnKeySign,·
3efa8f ¤   ¤   ¤   ¤   ¤   ¤   &(ccs.bSyncWithServer));
4fab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
d8af5a
cea28c ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_SIGNCONFIRM),
1a515f ¤   ¤   pKM->hWndParent, sSignKeyDlgProc, (LPARAM)&ccs)) {
3c98aa ¤   ¤   return FALSE;
f89371 ¤   }
31af5a
6a5ebf ¤   // convert user-entered signature type to flags to pass
b6cbb5 ¤   // and setup domain regular expression
95678a ¤   switch (ccs.iSigType) {
--2523 000aa8703df401102ad Page 13 of KMKeyOps.c
a81984 ¤   case SIG_NONEXPORTABLE :
9a52cc ¤   ¤   cs.bExportable = FALSE;
c02701 ¤   ¤   cs.uTrustLevel = 0;
5b2aba ¤   ¤   cs.szRegExpression[0] = '\0';
172f68 ¤   ¤   break;
a1af5a
d9f399 ¤   case SIG_EXPORTABLE :
8a8960 ¤   ¤   cs.bExportable = TRUE;
5a2701 ¤   ¤   cs.uTrustLevel = 0;
2e2aba ¤   ¤   cs.szRegExpression[0] = '\0';
202f68 ¤   ¤   break;
cbaf5a
9e8806 ¤   case SIG_TRUST :
c58960 ¤   ¤   cs.bExportable = TRUE;
c97ddd ¤   ¤   cs.uTrustLevel = 1;
80ca65 ¤   ¤   if (ccs.szDomain[0])
317978 ¤   ¤   ¤   sDomainToRegExpression (ccs.szDomain, cs.szRegExpression);
d30e1d ¤   ¤   else
5e1654 ¤   ¤   ¤   cs.szRegExpression[0] = '\0';
382f68 ¤   ¤   break;
74af5a
b18f9f ¤   case SIG_META :
ec52cc ¤   ¤   cs.bExportable = FALSE;
a492b9 ¤   ¤   cs.uTrustLevel = 2;
842aba ¤   ¤   cs.szRegExpression[0] = '\0';
872f68 ¤   ¤   break;
e39371 ¤   }
a8af5a
bda136 ¤   // convert expiration info to expire days
e2090c ¤   if ((ccs.bExpires) && (ccs.iExpireDays > 0))
dd5f69 ¤   ¤   cs.uExpireDays = (UINT)ccs.iExpireDays;
cd0e24 ¤   else
996eb1 ¤   ¤   cs.uExpireDays = 0;
28af5a
03d9de ¤   // get valid passphrase
b2501e ¤   LoadString (g_hInst, IDS_SIGNKEYPASSPHRASE, sz256, 256);
da6cc3 ¤   err = KMGetSigningKeyPhrase (pKM->Context, pKM->tlsContext,·
6432d9 ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sz256,·
9f9aad ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, FALSE, &cs.keySigning,
626654 ¤   ¤   ¤   ¤   ¤   ¤   NULL, &cs.pPasskey, &cs.sizePasskey);
d9af5a
a4b23e ¤   if (IsntPGPError (err)) {
c6af5a
2ded82 ¤   ¤   // update from server
6ea39c ¤   ¤   if (ccs.bSyncWithServer) {
e99ab7 ¤   ¤   ¤   if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
9a6745 ¤   ¤   ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
1e6fd4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_QUERYCONTINUESIGNING,·
03eba6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
9dcbe9 ¤   ¤   ¤   ¤   ¤   if (cs.pPasskey) {
938ac1 ¤   ¤   ¤   ¤   ¤   ¤   KMFreePasskey (cs.pPasskey, cs.sizePasskey);
ac6ba6 ¤   ¤   ¤   ¤   ¤   ¤   cs.pPasskey = NULL;
e71c89 ¤   ¤   ¤   ¤   ¤   }
b0e143 ¤   ¤   ¤   ¤   ¤   return FALSE;
4f2613 ¤   ¤   ¤   ¤   }
93a3a6 ¤   ¤   ¤   }
cf0fe4 ¤   ¤   }
ffaf5a
69021c ¤   ¤   // call callback for all selected items
be242d ¤   ¤   TreeList_IterateSelected (pKM->hWndTree, &cs);
c8af5a
c14e07 ¤   ¤   // changes have been made; save them and update all validities
cd987b ¤   ¤   if (cs.bItemModified) {
dadc42 ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
89d458 ¤   ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, FALSE, FALSE);
ee75b3 ¤   ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
0eaf5a
17569f ¤   ¤   ¤   // send key to server, if selected
9de26f ¤   ¤   ¤   if (ccs.bSyncWithServer) {
fc6c56 ¤   ¤   ¤   ¤   KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
e1a3a6 ¤   ¤   ¤   }
aa0fe4 ¤   ¤   }
--5134 0006332d4e2401102ad Page 14 of KMKeyOps.c
a19371 ¤   }
93af5a
40f0ac ¤   if (cs.pPasskey) {
40932b ¤   ¤   KMFreePasskey (cs.pPasskey, cs.sizePasskey);
8a0037 ¤   ¤   cs.pPasskey = NULL;
f99371 ¤   }
81da90 ¤   return (cs.bItemModified);
daefe6 }
cbaf5a
bcaf5a
869268 //¤ _______________________________________________
58465d //
c17825 // ·Enable selected key
3daf5a
a67efe BOOL·
1aa662 KMEnableKey (PKEYMAN pKM, PGPKeyRef key)·
0ebb36 {
667e31 ¤   if (IsntPGPError (PGPclErrorBox (NULL, PGPEnableKey (key)))) {
e7e0ac ¤   ¤   KMCommitKeyRingChanges (pKM);
912f51 ¤   ¤   KMUpdateKeyInTree (pKM, key, FALSE);
6b836c ¤   ¤   return TRUE;
b09371 ¤   }
b3a230 ¤   return FALSE;
69efe6 }
b6af5a
dcaf5a
119268 //¤ _______________________________________________
64465d //
2f389b // ·Disable selected key
b4af5a
097efe BOOL·
9de1be KMDisableKey (PKEYMAN pKM, PGPKeyRef key)·
31bb36 {
c782c5 ¤   if (IsntPGPError (PGPclErrorBox (NULL, PGPDisableKey (key)))) {
e2e0ac ¤   ¤   KMCommitKeyRingChanges (pKM);
3c2f51 ¤   ¤   KMUpdateKeyInTree (pKM, key, FALSE);
09836c ¤   ¤   return TRUE;
0d9371 ¤   }
30a230 ¤   return FALSE;
42efe6 }
8daf5a
a0af5a
b99268 //¤ _______________________________________________
8d465d //
28c5a7 //¤ Delete All dialog message procedure
49af5a
fe3f64 static BOOL CALLBACK·
663061 sDeleteAllDlgProc (
684669 ¤   ¤   HWND¤   hWndDlg,·
4beb77 ¤   ¤   UINT¤   uMsg,·
2817d4 ¤   ¤   WPARAM¤ wParam,·
afc0b8 ¤   ¤   LPARAM¤ lParam)·
e8bb36 {
a77a2a ¤   PDELETESTRUCT pds;
b2af5a
86347f ¤   switch (uMsg) {
13af5a
a5ad3a ¤   case WM_INITDIALOG :
6f2ec5 ¤   ¤   SetWindowLong (hWndDlg, GWL_USERDATA, lParam);
7c4d90 ¤   ¤   pds = (PDELETESTRUCT)lParam;
5b3aeb ¤   ¤   SetDlgItemText (hWndDlg, IDC_STRING, pds->pszPrompt);
02aaa9 ¤   ¤   SetFocus (GetDlgItem (hWndDlg, IDNO));
7398aa ¤   ¤   return FALSE;
81af5a
30c3eb ····case WM_HELP:·
db80de ¤   ¤   pds = (PDELETESTRUCT)GetWindowLong (hWndDlg, GWL_USERDATA);
405452 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pds->pKM->szHelpFile,·
2cd825 ············HELP_WM_HELP, (DWORD) (LPSTR) aDeleteAllIds);·
758f13 ········break;·
5fd83c ·
14daf9 ····case WM_CONTEXTMENU:
6380de ¤   ¤   pds = (PDELETESTRUCT)GetWindowLong (hWndDlg, GWL_USERDATA);
--63c4 00042f5d4bd401102ad Page 15 of KMKeyOps.c
4e190e ········WinHelp ((HWND) wParam, pds->pKM->szHelpFile, HELP_CONTEXTMENU,·
37572a ············(DWORD) (LPVOID) aDeleteAllIds);·
de8f13 ········break;·
36af5a
5a3fcf ¤   case WM_COMMAND:
c3af5a
2d537d ¤   ¤   switch (LOWORD(wParam)) {
2c71eb ¤   ¤   case IDCANCEL:
c0cea9 ¤   ¤   ¤   pds = (PDELETESTRUCT)GetWindowLong (hWndDlg, GWL_USERDATA);
ec2041 ¤   ¤   ¤   pds->bItemNotDeleted = TRUE;
e77baf ¤   ¤   ¤   EndDialog (hWndDlg, IDCANCEL);
e6cdcb ¤   ¤   ¤   break;
82af5a
933860 ¤   ¤   case IDOK:
a1c20f ¤   ¤   case IDYES:
749741 ¤   ¤   ¤   EndDialog (hWndDlg, IDYES);
a6cdcb ¤   ¤   ¤   break;
e0af5a
dd47ba ¤   ¤   case IDNO:
aefd12 ¤   ¤   ¤   EndDialog (hWndDlg, IDNO);
c5cdcb ¤   ¤   ¤   break;
80af5a
0a380a ¤   ¤   case IDC_YESTOALL :
7acea9 ¤   ¤   ¤   pds = (PDELETESTRUCT)GetWindowLong (hWndDlg, GWL_USERDATA);
84ab92 ¤   ¤   ¤   pds->bDeleteAll = TRUE;
499741 ¤   ¤   ¤   EndDialog (hWndDlg, IDYES);
94cdcb ¤   ¤   ¤   break;
3b0fe4 ¤   ¤   }
07836c ¤   ¤   return TRUE;
e39371 ¤   }
52a230 ¤   return FALSE;
6aefe6 }
85af5a
d1af5a
609268 //¤ _______________________________________________
42465d //
56e091 // ·Ask user for delete confirmation
2baf5a
c8083f static INT·
be3a9d sDeleteConfirm (
9c9d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
bb6b96 ¤   ¤   INT¤¤   ¤   ¤   iPromptID,·
d16eb6 ¤   ¤   PDELETESTRUCT¤  pds)·
babb36 {
662ee7 ¤   CHAR sz256[256];
8d8004 ¤   CHAR sz512[512];
12ebff ¤   INT iRetVal;
6eaf5a
f88d96 ¤   if (pds->bDeleteAll) return IDYES;
d4af5a
1d1fef ¤   LoadString (g_hInst, iPromptID, sz256, 256);·
de2261 ¤   wsprintf (sz512, sz256, lptli->pszText);
cfaf5a
308d40 ¤   if (KMMultipleSelected (pds->pKM)) {
bac98f ¤   ¤   pds->pszPrompt = sz512;
50de53 ¤   ¤   iRetVal = DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_DELETEALL),·
8fcf87 ¤   ¤   ¤   pds->pKM->hWndParent, sDeleteAllDlgProc, (LPARAM)pds);
74bf52 ¤   ¤   if (!pds->bItemNotDeleted && (iRetVal == IDNO)) {
292041 ¤   ¤   ¤   pds->bItemNotDeleted = TRUE;
aece31 ¤   ¤   ¤   pds->hPostDeleteFocusItem = lptli->hItem;
670fe4 ¤   ¤   }
129371 ¤   }
87665a ¤   else {
6b2216 ¤   ¤   LoadString (g_hInst, IDS_DELCONFCAPTION, sz256, 256);
479afc ¤   ¤   iRetVal = MessageBox (pds->pKM->hWndParent, sz512, sz256,
23d7b7 ¤   ¤   ¤   ¤   MB_YESNO|MB_TASKMODAL|MB_DEFBUTTON2|MB_ICONWARNING);
7b9371 ¤   }
4faf5a
fdb5f8 ¤   return iRetVal;
feefe6 }
47af5a
42af5a
--f8fd 000bfbf119a401102ad Page 16 of KMKeyOps.c
b09268 //¤ _______________________________________________
ca465d //
460ba2 // ·Get handle of nearby item
be465d //
3f13d1 //¤ lptli¤  = pointer to TreeList item
23af5a
21d7b4 static HTLITEM·
5963ba sGetAdjacentItem (
85bd0e ¤   ¤   HWND¤   ¤   ¤   hWndTree,·
26a4a1 ¤   ¤   TL_TREEITEM*¤   lptli)·
69bb36 {
47e723 ¤   TL_TREEITEM tli;
abaf5a
c1d247 ¤   tli.hItem = lptli->hItem;
d301eb ¤   tli.mask = TLIF_NEXTHANDLE;
324f6d ¤   TreeList_GetItem (hWndTree, &tli);
319f18 ¤   if (!tli.hItem) {
99e54f ¤   ¤   tli.hItem = lptli->hItem;
c1ff77 ¤   ¤   tli.mask = TLIF_PREVHANDLE;
8a4121 ¤   ¤   TreeList_GetItem (hWndTree, &tli);
0458ad ¤   ¤   if (!tli.hItem) {
910a3c ¤   ¤   ¤   tli.hItem = lptli->hItem;
9df510 ¤   ¤   ¤   tli.mask = TLIF_PARENTHANDLE;
79d0b9 ¤   ¤   ¤   TreeList_GetItem (hWndTree, &tli);
a60fe4 ¤   ¤   }
ae9371 ¤   }
a4af5a
6e24d3 ¤   return tli.hItem;
47efe6 }
cdaf5a
d667c5 ¤
499268 //¤ _______________________________________________
fe465d //
8c9d74 // ·Delete a single object
e2d925 //¤ routine called either from KMDeleteObject or as a
62995b //¤ callback function from the TreeList control to·
05b407 //¤ delete a single item.
61465d //
b75110 //¤ lptli¤  = pointer to TreeList item to delete
1caf5a
a13f64 static BOOL CALLBACK·
5a7b1e sDeleteSingleObject (
779d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
acdd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
cebb36 {
6e5c5c ¤   PDELETESTRUCT¤  pds¤¤   ¤   = (PDELETESTRUCT)lParam;
ecfead ¤   PGPKeySetRef¤   keyset;
1a1502 ¤   PGPKeyRef¤  ¤   key;
b48f18 ¤   PGPUserIDRef¤   userid;
a8b4f3 ¤   BOOL¤   ¤   ¤   bPrimary;
afeb13 ¤   INT¤¤   ¤   ¤   iConfirm;
036b3e ¤   LONG¤   ¤   ¤   lVal;
44fb19 ¤   PGPError¤   ¤   err;
e9af5a
f06919 ¤   switch (lptli->iImage) {
e55b97 ¤   case IDX_RSASECKEY :
50b4cd ¤   case IDX_RSASECDISKEY :
4dbcd1 ¤   case IDX_RSASECSHRKEY :
f74982 ¤   case IDX_DSASECKEY :
37aec4 ¤   case IDX_DSASECDISKEY :
a8a6d8 ¤   case IDX_DSASECSHRKEY :
1dc911 ¤   ¤   iConfirm = sDeleteConfirm (lptli, IDS_DELCONFPRIVKEY, pds);
c31bb4 ¤   ¤   if (iConfirm == IDYES) {
fa9a60 ¤   ¤   ¤   if ((PGPKeyRef)(lptli->lParam) == pds->keyDefault) {
1358f4 ¤   ¤   ¤   ¤   if (KMMessageBox (pds->pKM->hWndParent, IDS_CAPTION,·
840a3f ¤   ¤   ¤   ¤   ¤   IDS_DELCONFDEFKEY,
df5cb6 ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_TASKMODAL|MB_DEFBUTTON2|MB_ICONWARNING)
9cf40a ¤   ¤   ¤   ¤   ¤   ==IDNO)·
8d80de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
62a3a6 ¤   ¤   ¤   }
763cdc ¤   ¤   ¤   PGPNewSingletonKeySet ((PGPKeyRef)(lptli->lParam),
bf6c7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);
--ecd3 000cdf56926401102ad Page 17 of KMKeyOps.c
81dd2e ¤   ¤   ¤   KMGetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), &lVal);
5d2b6f ¤   ¤   ¤   KMSetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), 0);
5def68 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, PGPRemoveKeys (
f2a307 ¤   ¤   ¤   ¤   ¤   keyset, pds->pKM->KeySetDisp)))) {
2f88a6 ¤   ¤   ¤   ¤   KMDeletePropertiesKey (pds->pKM, (PGPKeyRef)(lptli->lParam));
b88787 ¤   ¤   ¤   ¤   pds->bItemModified = TRUE;
de9535 ¤   ¤   ¤   ¤   if (!pds->bItemNotDeleted)·
8fd8a7 ¤   ¤   ¤   ¤   ¤   pds->hPostDeleteFocusItem =·
bb85ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   sGetAdjacentItem (pds->pKM->hWndTree, lptli);·
172ee4 ¤   ¤   ¤   ¤   TreeList_DeleteItem (pds->pKM->hWndTree, lptli);
04a3a6 ¤   ¤   ¤   }
e56b93 ¤   ¤   ¤   else·
c54347 ¤   ¤   ¤   ¤   KMSetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), lVal);
22af5a
0b08ba ¤   ¤   ¤   PGPFreeKeySet (keyset);
fb0fe4 ¤   ¤   }
2e743c ¤   ¤   if (iConfirm == IDCANCEL) return FALSE;·
86a9fe ¤   ¤   else return TRUE;
58af5a
fb2487 ¤   case IDX_RSASECREVKEY :
2e8b99 ¤   case IDX_RSASECEXPKEY :
fa3e8e ¤   case IDX_DSASECREVKEY :
b59190 ¤   case IDX_DSASECEXPKEY :
aec911 ¤   ¤   iConfirm = sDeleteConfirm (lptli, IDS_DELCONFPRIVKEY, pds);
441bb4 ¤   ¤   if (iConfirm == IDYES) {
793cdc ¤   ¤   ¤   PGPNewSingletonKeySet ((PGPKeyRef)(lptli->lParam),
9a6c7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);
e4dd2e ¤   ¤   ¤   KMGetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), &lVal);
b72b6f ¤   ¤   ¤   KMSetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), 0);
b8ef68 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, PGPRemoveKeys (
b0a307 ¤   ¤   ¤   ¤   ¤   keyset, pds->pKM->KeySetDisp)))) {
8a88a6 ¤   ¤   ¤   ¤   KMDeletePropertiesKey (pds->pKM, (PGPKeyRef)(lptli->lParam));
bc8787 ¤   ¤   ¤   ¤   pds->bItemModified = TRUE;
509535 ¤   ¤   ¤   ¤   if (!pds->bItemNotDeleted)·
1ad8a7 ¤   ¤   ¤   ¤   ¤   pds->hPostDeleteFocusItem =·
b585ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   sGetAdjacentItem (pds->pKM->hWndTree, lptli);·
2c2ee4 ¤   ¤   ¤   ¤   TreeList_DeleteItem (pds->pKM->hWndTree, lptli);
41a3a6 ¤   ¤   ¤   }
dd6b93 ¤   ¤   ¤   else·
074347 ¤   ¤   ¤   ¤   KMSetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), lVal);
87af5a
0808ba ¤   ¤   ¤   PGPFreeKeySet (keyset);
ae0fe4 ¤   ¤   }
aa743c ¤   ¤   if (iConfirm == IDCANCEL) return FALSE;·
cca9fe ¤   ¤   else return TRUE;
0aaf5a
71493d ¤   case IDX_RSAPUBKEY :
866e41 ¤   case IDX_RSAPUBDISKEY :
e5fe0b ¤   case IDX_RSAPUBREVKEY :
bc5115 ¤   case IDX_RSAPUBEXPKEY :
c25b28 ¤   case IDX_DSAPUBKEY :
0d7448 ¤   case IDX_DSAPUBDISKEY :
5ce402 ¤   case IDX_DSAPUBREVKEY :
0e4b1c ¤   case IDX_DSAPUBEXPKEY :
b43660 ¤   ¤   iConfirm = sDeleteConfirm (lptli, IDS_DELCONFKEY, pds);
b31bb4 ¤   ¤   if (iConfirm == IDYES) {
b13991 ¤   ¤   ¤   PGPNewSingletonKeySet ((PGPKeyRef)(lptli->lParam),·
586c7e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyset);
ebdd2e ¤   ¤   ¤   KMGetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), &lVal);
e02b6f ¤   ¤   ¤   KMSetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), 0);
4aef68 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, PGPRemoveKeys (
dc2922 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyset, pds->pKM->KeySetDisp)))) {
d788a6 ¤   ¤   ¤   ¤   KMDeletePropertiesKey (pds->pKM, (PGPKeyRef)(lptli->lParam));
7e8787 ¤   ¤   ¤   ¤   pds->bItemModified = TRUE;
429535 ¤   ¤   ¤   ¤   if (!pds->bItemNotDeleted)·
3cd8a7 ¤   ¤   ¤   ¤   ¤   pds->hPostDeleteFocusItem =·
cc85ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   sGetAdjacentItem (pds->pKM->hWndTree, lptli);·
f02ee4 ¤   ¤   ¤   ¤   TreeList_DeleteItem (pds->pKM->hWndTree, lptli);
4ca3a6 ¤   ¤   ¤   }
06bb8c ¤   ¤   ¤   else
7c4347 ¤   ¤   ¤   ¤   KMSetKeyUserVal (pds->pKM, (PGPKeyRef)(lptli->lParam), lVal);
cd08ba ¤   ¤   ¤   PGPFreeKeySet (keyset);
--d79e 000b6902564401102ad Page 18 of KMKeyOps.c
b50fe4 ¤   ¤   }
51ed63 ¤   ¤   if (iConfirm == IDCANCEL) return FALSE;
04a9fe ¤   ¤   else return TRUE;
5caf5a
54b951 ¤   case IDX_RSAUSERID :
6cab44 ¤   case IDX_DSAUSERID :
8affd4 ¤   ¤   if (KMIsThisTheOnlyUserID (pds->pKM, (PGPUserIDRef)(lptli->lParam))) {
6d595d ¤   ¤   ¤   KMMessageBox (pds->pKM->hWndParent, IDS_CAPTION,·
82728b ¤   ¤   ¤   ¤   ¤   ¤   IDS_DELONLYUSERID, MB_OK|MB_ICONEXCLAMATION);
72cdcb ¤   ¤   ¤   break;
5c0fe4 ¤   ¤   }
9f7a39 ¤   ¤   // fall through
11af5a
c6304b ¤   case IDX_PHOTOUSERID :
825d7a ¤   case IDX_INVALIDUSERID :
1f3c36 ¤   ¤   iConfirm = sDeleteConfirm (lptli, IDS_DELCONFUSERID, pds);
7c1bb4 ¤   ¤   if (iConfirm == IDYES) {
afd204 ¤   ¤   ¤   key = KMGetKeyFromUserID (pds->pKM,·
1c5c7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUserIDRef)(lptli->lParam));
3caf5a
5ccb43 ¤   ¤   ¤   PGPGetPrimaryUserID (key, &userid);
db6787 ¤   ¤   ¤   if (userid == (PGPUserIDRef)(lptli->lParam))·
7fce6c ¤   ¤   ¤   ¤   bPrimary = TRUE;
626b93 ¤   ¤   ¤   else·
e698e7 ¤   ¤   ¤   ¤   bPrimary = FALSE;
d5af5a
d094f7 ¤   ¤   ¤   KMGetUserIDUserVal (pds->pKM,(PGPUserIDRef)(lptli->lParam),&lVal);
0c1712 ¤   ¤   ¤   KMSetUserIDUserVal (pds->pKM,(PGPUserIDRef)(lptli->lParam),0);
45295f ¤   ¤   ¤   err = PGPRemoveUserID ((PGPUserIDRef)(lptli->lParam));
1d9958 ¤   ¤   ¤   if (IsntPGPError (err)) {¤  ¤   ¤
968787 ¤   ¤   ¤   ¤   pds->bItemModified = TRUE;
86657f ¤   ¤   ¤   ¤   if (bPrimary) {
5a0431 ¤   ¤   ¤   ¤   ¤   pds->bDeletedPrimaryUserID = TRUE;
6e2613 ¤   ¤   ¤   ¤   }
7d2fc2 ¤   ¤   ¤   ¤   else {·
9b8d65 ¤   ¤   ¤   ¤   ¤   if (!pds->bItemNotDeleted)·
3c8bbc ¤   ¤   ¤   ¤   ¤   ¤   pds->hPostDeleteFocusItem =·
7f85ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   sGetAdjacentItem (pds->pKM->hWndTree, lptli);·
d4a4a1 ¤   ¤   ¤   ¤   ¤   TreeList_DeleteItem (pds->pKM->hWndTree, lptli);
ed2613 ¤   ¤   ¤   ¤   }
f4a3a6 ¤   ¤   ¤   }
86e543 ¤   ¤   ¤   else {
6edb72 ¤   ¤   ¤   ¤   PGPclErrorBox (NULL, err);
30d104 ¤   ¤   ¤   ¤   KMSetUserIDUserVal (pds->pKM,·
9aa96e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUserIDRef)(lptli->lParam), lVal);
e7a3a6 ¤   ¤   ¤   }
740fe4 ¤   ¤   }
e5ed63 ¤   ¤   if (iConfirm == IDCANCEL) return FALSE;
9ca9fe ¤   ¤   else return TRUE;
e3af5a
026533 ¤   case IDX_CERT :
681c1f ¤   case IDX_REVCERT :
f7a1bf ¤   case IDX_BADCERT :
b7e54f ¤   case IDX_EXPCERT :
748f71 ¤   case IDX_EXPORTCERT :
fac328 ¤   case IDX_TRUSTEDCERT :
13ef7c ¤   case IDX_METACERT :
1e4300 ¤   ¤   iConfirm = sDeleteConfirm (lptli, IDS_DELCONFCERT, pds);
df1bb4 ¤   ¤   if (iConfirm == IDYES) {
683ebf ¤   ¤   ¤   KMGetCertUserVal (pds->pKM, (PGPSigRef)(lptli->lParam), &lVal);
eed3f7 ¤   ¤   ¤   KMSetCertUserVal (pds->pKM, (PGPSigRef)(lptli->lParam), 0);
37ff0e ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, PGPRemoveSig (
bdc6a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPSigRef)(lptli->lParam))))) {
2d8787 ¤   ¤   ¤   ¤   pds->bItemModified = TRUE;
d89535 ¤   ¤   ¤   ¤   if (!pds->bItemNotDeleted)·
52d8a7 ¤   ¤   ¤   ¤   ¤   pds->hPostDeleteFocusItem =·
c885ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   sGetAdjacentItem (pds->pKM->hWndTree, lptli);·
0d2ee4 ¤   ¤   ¤   ¤   TreeList_DeleteItem (pds->pKM->hWndTree, lptli);
74a3a6 ¤   ¤   ¤   }
34bb8c ¤   ¤   ¤   else
442a59 ¤   ¤   ¤   ¤   KMSetCertUserVal (pds->pKM, (PGPSigRef)(lptli->lParam), lVal);
b60fe4 ¤   ¤   }
--6cd8 000e9165246401102ad Page 19 of KMKeyOps.c
96ed63 ¤   ¤   if (iConfirm == IDCANCEL) return FALSE;
04a9fe ¤   ¤   else return TRUE;
db9371 ¤   }
0caf5a
14a230 ¤   return FALSE;
2fefe6 }
a3af5a
fdaf5a
4b9268 //¤ _______________________________________________
8c465d //
a00fd7 // ·Delete selected key or keys
9daf5a
c57efe BOOL·
17feca KMDeleteObject (PKEYMAN pKM)·
5cbb36 {
6949d1 ¤   TL_TREEITEM¤¤   tli;
2147cc ¤   DELETESTRUCT¤   ds;
f4af5a
f44649 ¤   ds.lpfnCallback = sDeleteSingleObject;
1f3233 ¤   ds.context = pKM->Context;
f5c146 ¤   ds.pKM = pKM;
66e766 ¤   ds.bItemModified = FALSE;
7b6ffa ¤   ds.bDeleteAll = FALSE;
32f436 ¤   ds.bItemNotDeleted = FALSE;
f4b3b6 ¤   ds.bDeletedPrimaryUserID = FALSE;
f50e06 ¤   ds.hPostDeleteFocusItem = NULL;
54aa99 ¤   PGPGetDefaultPrivateKey (pKM->KeySetMain, &ds.keyDefault);
5faf5a
d53c72 ¤   // call callback function for all selected objects
ee05d6 ¤   TreeList_IterateSelected (pKM->hWndTree, &ds);
4aaf5a
0439a5 ¤   if (ds.bItemModified) {
49e0ac ¤   ¤   KMCommitKeyRingChanges (pKM);
1bbe03 ¤   ¤   if (ds.bDeletedPrimaryUserID) {
1e3020 ¤   ¤   ¤   TreeList_DeleteTree (pKM->hWndTree, TRUE);
7c805f ¤   ¤   ¤   KMAddColumns (pKM);
d8429d ¤   ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, FALSE, TRUE);
5b0fe4 ¤   ¤   }
f907e0 ¤   ¤   else {
8dd458 ¤   ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, FALSE, FALSE);
f4af5a
7b2dc4 ¤   ¤   ¤   if (ds.bItemNotDeleted) {
5b0b4f ¤   ¤   ¤   ¤   if (ds.hPostDeleteFocusItem) {
cf1222 ¤   ¤   ¤   ¤   ¤   tli.hItem = ds.hPostDeleteFocusItem;
833a51 ¤   ¤   ¤   ¤   ¤   TreeList_Select (pKM->hWndTree, &tli, FALSE);
cf2613 ¤   ¤   ¤   ¤   }
8f6d2a ¤   ¤   ¤   ¤   else KMSetFocus (pKM, NULL, FALSE);
05a3a6 ¤   ¤   ¤   }
18e543 ¤   ¤   ¤   else {
740b4f ¤   ¤   ¤   ¤   if (ds.hPostDeleteFocusItem) {
c01222 ¤   ¤   ¤   ¤   ¤   tli.hItem = ds.hPostDeleteFocusItem;
8c0de4 ¤   ¤   ¤   ¤   ¤   TreeList_Select (pKM->hWndTree, &tli, TRUE);
4dc5fc ¤   ¤   ¤   ¤   ¤   tli.stateMask = TLIS_SELECTED;
91ad52 ¤   ¤   ¤   ¤   ¤   tli.state = 0;
255562 ¤   ¤   ¤   ¤   ¤   tli.mask = TLIF_STATE;
1d5b0b ¤   ¤   ¤   ¤   ¤   TreeList_SetItem (pKM->hWndTree, &tli);
aa2613 ¤   ¤   ¤   ¤   }
044e14 ¤   ¤   ¤   ¤   KMSetFocus (pKM, NULL, FALSE);
ffa3a6 ¤   ¤   ¤   }
530fe4 ¤   ¤   }
56201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
379371 ¤   }
213a5c ¤   return (ds.bItemModified);
4aefe6 }
cdaf5a
d6af5a
3e9268 //¤ _______________________________________________
e2465d //
fafd5c //¤ Set focused key to be default signing key
90af5a
f17efe BOOL·
e9167c KMSetDefaultKey (PKEYMAN pKM)·
--89de 0007ba224fe401102ad Page 20 of KMKeyOps.c
2cbb36 {
4d704a ¤   PGPKeyRef¤  keyNewDef;
3bfe01 ¤   PGPKeyRef¤  keyOldDef;
1261e0 ¤   PGPError¤   err;
e6af5a
c901a7 ¤   PGPGetDefaultPrivateKey (pKM->KeySetMain, &keyOldDef);
282834 ¤   keyNewDef = (PGPKeyRef) KMFocusedObject (pKM);
60af5a
729d5f ¤   err = PGPSetDefaultPrivateKey (keyNewDef);
0b3f7e ¤   if (IsntPGPError (PGPclErrorBox (pKM->hWndParent, err))) {
e0af5a
1b85e9 ¤   ¤   PGPclErrorBox (NULL, PGPsdkSavePrefs (pKM->Context));
1c7f07 ¤   ¤   if (keyOldDef)
97c5e2 ¤   ¤   ¤   KMUpdateKeyInTree (pKM, keyOldDef, FALSE);
461664 ¤   ¤   KMUpdateKeyInTree (pKM, keyNewDef, FALSE);
73af5a
41836c ¤   ¤   return TRUE;
be9371 ¤   }
e5a230 ¤   return FALSE;
2fefe6 }
bcaf5a
b1af5a
ad9268 //¤ _______________________________________________
92465d //
221513 //¤ Set focused UID to be primary UID
d5af5a
7a7efe BOOL·
85a03f KMSetPrimaryUserID (PKEYMAN pKM)·
c8bb36 {
7db580 ¤   PGPUserIDRef¤   UserID;
ff7593 ¤   PGPKeyRef¤  ¤   Key;
f3af5a
1198b9 ¤   UserID = (PGPUserIDRef) KMFocusedObject (pKM);
32af5a
20d028 ¤   if (IsntPGPError (PGPclErrorBox (NULL, PGPSetPrimaryUserID (UserID)))) {
4ce0ac ¤   ¤   KMCommitKeyRingChanges (pKM);
1e4627 ¤   ¤   Key = KMGetKeyFromUserID (pKM, UserID);
7b8f11 ¤   ¤   KMUpdateKeyInTree (pKM, Key, TRUE);
00201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
e6836c ¤   ¤   return TRUE;
e09371 ¤   }
37a230 ¤   return FALSE;
35efe6 }
95af5a
72af5a
639268 //¤ _______________________________________________
48465d //
104341 //¤ add selected keys to main keyset
7eaf5a
277efe BOOL·
58146b KMAddSelectedToMain (PKEYMAN pKM)·
26bb36 {
046a93 ¤   PGPKeySetRef¤   ¤   keysetMain¤ = kInvalidPGPKeySetRef;
18bcc4 ¤   PGPKeySetRef¤   ¤   keysetToAdd¤= kInvalidPGPKeySetRef;
763333 ¤   PGPError¤   ¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
f8ffc1 ¤   BOOL¤   ¤   ¤   ¤   bSecret¤¤   = FALSE;
047438 ¤   BOOL¤   ¤   ¤   ¤   bRet¤   ¤   = FALSE;
b9af5a
09b94b ¤   err = KMGetSelectedKeys (pKM, &keysetToAdd, NULL);
75af5a
dfff2d ¤   if (PGPKeySetRefIsValid (keysetToAdd))·
86c7a1 ¤   {
0333d8 ¤   ¤   if (pKM->bMainKeySet)
658673 ¤   ¤   ¤   keysetMain = pKM->KeySetMain;
baaf5a
e0ab1b ¤   ¤   bSecret = KMCheckForSecretKeys (keysetToAdd);
0d16e5 ¤   ¤   bRet = CLAddKeysToMain (pKM->Context, pKM->hWndParent,·
5922e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetToAdd, keysetMain);
9baf5a
d6c0b0 ¤   ¤   if (bRet && bSecret)
325b34 ¤   ¤   {
7b73ed ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
--d2c6 000581947c3401102ad Page 21 of KMKeyOps.c
43cb9f ¤   ¤   ¤   ¤   ¤   IDS_IMPORTEDSECRETKEYS,·
6ddd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
0a0fe4 ¤   ¤   }
51af5a
eff72e ¤   ¤   PGPFreeKeySet (keysetToAdd);
5b9371 ¤   }
feaf5a
308d4d ¤   return bRet;
a7efe6 }
8067c5 ¤
729268 //¤ _______________________________________________
a9465d //
d3ea72 //¤ routine called as a callback function from the·
e6e9bc // ·PGPCheckKeyRingSigs function
f6af5a
9269c9 static PGPError·
9dc652 sKeyCheckEventHandler(
7be958 ¤   ¤   PGPContextRef¤  context,
128294 ¤   ¤   PGPEvent¤   ¤   *event,·
c9c05f ¤   ¤   PGPUserValue¤   userValue)
eebb36 {
527485 ¤   PREVERIFYSTRUCT prvs;
79195e ¤   CHAR¤   ¤   ¤   sz[64];
bfb3c7 ¤   INT¤¤   ¤   ¤   iTotal;
0baf5a
cdac14 ¤   prvs = (PREVERIFYSTRUCT)userValue;
dcaf5a
93b008 ¤   iTotal = LOWORD (event->data.nullData.bytesTotal);
5a12fc ¤   if (iTotal != prvs->iNumSigsTotal) {
ce67f7 ¤   ¤   prvs->iNumSigsTotal = iTotal;
3faf5a
275b24 ¤   ¤   EnableWindow (GetDlgItem (prvs->hwndProgress, IDCANCEL), TRUE);
97af5a
58311a ¤   ¤   LoadString (g_hInst, IDS_VERIFYING, sz, sizeof(sz));
4ceabd ¤   ¤   SetDlgItemText (prvs->hwndProgress, IDC_TEXT, sz);
feaf5a
8583da ¤   ¤   SendDlgItemMessage (prvs->hwndProgress, IDC_PROGRESSBAR,·
d410ed ¤   ¤   ¤   ¤   ¤   PBM_SETRANGE, 0, MAKELPARAM (0, prvs->iNumSigsTotal));
f89371 ¤   }
94af5a
993fc3 ¤   SendDlgItemMessage (prvs->hwndProgress, IDC_PROGRESSBAR,·
320a25 ¤   ¤   ¤   PBM_SETPOS, LOWORD (event->data.nullData.bytesWritten), 0);
2aaf5a
9201e0 ¤   if (prvs->bCancel)
d874be ¤   ¤   return kPGPError_UserAbort;
564264 ¤   else·
a1b840 ¤   ¤   return kPGPError_NoErr;
06efe6 }
5f67c5 ¤
429268 //¤ _______________________________________________
30465d //
fda349 //¤ reverify signature progress dialog message procedure
0eaf5a
a53f64 static BOOL CALLBACK·
b6eb5b sReverifyProgressDlgProc (
6d3a3a ¤   ¤   HWND¤   hDlg,·
795816 ¤   ¤   UINT¤   uMsg, ¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤
c817d4 ¤   ¤   WPARAM¤ wParam,·
c0c0b8 ¤   ¤   LPARAM¤ lParam)·
0fbb36 {
a57485 ¤   PREVERIFYSTRUCT prvs;
9d195e ¤   CHAR¤   ¤   ¤   sz[64];
3daf5a
45347f ¤   switch (uMsg) {
11ad3a ¤   case WM_INITDIALOG :
ef7547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
95f447 ¤   ¤   prvs = (PREVERIFYSTRUCT)lParam;
eac127 ¤   ¤   LoadString (g_hInst, IDS_PREPARINGTOVERIFY, sz, sizeof(sz));
bf0eaf ¤   ¤   SetDlgItemText (hDlg, IDC_TEXT, sz);
4fac4d ¤   ¤   prvs->hwndProgress = hDlg;
71836c ¤   ¤   return TRUE;
58af5a
--f546 000ce315868401102ad Page 22 of KMKeyOps.c
ec5020 ¤   case WM_APP :
e23a51 ¤   ¤   prvs = (PREVERIFYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
d799b1 ¤   ¤   SetForegroundWindow (prvs->hwndParent);
745438 ¤   ¤   EndDialog (hDlg, 0);
482f68 ¤   ¤   break;
e0af5a
d3d1d3 ¤   case WM_COMMAND :
081185 ¤   ¤   switch (LOWORD (wParam)) {
97b6bb ¤   ¤   case IDCANCEL :
1d7426 ¤   ¤   ¤   prvs = (PREVERIFYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
cee151 ¤   ¤   ¤   prvs->bCancel = TRUE;
4bcdcb ¤   ¤   ¤   break;
b70fe4 ¤   ¤   }
47836c ¤   ¤   return TRUE;
3a9371 ¤   }
57a230 ¤   return FALSE;
69efe6 }
60af5a
e79268 //¤ _______________________________________________
93465d //
9294bc //¤ reverify signatures thread routine
69af5a
28e8c0 static DWORD WINAPI·
19a156 sReverifyProgressThreadRoutine (LPVOID lpvoid)
efbb36 {
3b8c88 ¤   PREVERIFYSTRUCT¤¤   prvs¤   = (PREVERIFYSTRUCT)lpvoid;
6baf5a
fc05c6 ¤   DialogBoxParam (g_hInst,·
e5765a ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_REVERIFYING), NULL,·
86096c ¤   ¤   ¤   ¤   ¤   sReverifyProgressDlgProc, (LPARAM)prvs);
2cda4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
103e6b ¤   return 0;
d6efe6 }
5daf5a
6d9268 //¤ _______________________________________________
f2465d //
3c637c //¤ reverify signatures of selected keys
cbaf5a
497efe BOOL·
a22675 KMReverifySigs (PKEYMAN pKM)·
35cebb {¤
5b7a00 ¤   PGPKeySetRef¤   ¤   keysetReverify¤ = kInvalidPGPKeySetRef;
e673ec ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
a903e3 ¤   REVERIFYSTRUCT¤ ¤   rvs;
b406b1 ¤   DWORD¤  ¤   ¤   ¤   dw;
c2af5a
a10417 ¤   rvs.hwndParent = pKM->hWndParent;
843ecb ¤   rvs.hwndProgress = NULL;
da7c6f ¤   rvs.iNumSigsTotal = -1;
3871fb ¤   rvs.bCancel = FALSE;
406d01 ¤   CreateThread (NULL, 0, sReverifyProgressThreadRoutine, &rvs, 0, &dw);
32af5a
b75a23 ¤   // wait for dialog box
9c03b6 ¤   EnableWindow (pKM->hWndParent, FALSE);
9d68fa ¤   while (rvs.hwndProgress == NULL) Sleep (100);
59af5a
1178df ¤   err = KMGetSelectedKeys (pKM, &keysetReverify, NULL);
9aaf5a
279df1 ¤   if (PGPKeySetRefIsValid (keysetReverify))·
60c7a1 ¤   {
89b652 ¤   ¤   err = PGPCheckKeyRingSigs (keysetReverify,
795e4f ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, TRUE, sKeyCheckEventHandler, &rvs);
0a9371 ¤   }
e5af5a
2746e3 ¤   // send message to close down dialog
6aa7ef ¤   SendMessage (rvs.hwndProgress, WM_APP, 0, 0);
a0295c ¤   EnableWindow (pKM->hWndParent, TRUE);
62ae30 ¤   ¤   ¤   ¤   ¤
d924d2 ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
47e0ac ¤   ¤   KMCommitKeyRingChanges (pKM);
373658 ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, FALSE, FALSE);
ce201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
--d50e 001de6788f5401102ad Page 23 of KMKeyOps.c
a19371 ¤   }
93af5a
069df1 ¤   if (PGPKeySetRefIsValid (keysetReverify))·
b17dfe ¤   ¤   PGPFreeKeySet (keysetReverify);
1caf5a
87ac2a ¤   return (IsntPGPError (err));
dcefe6 }
deaf5a
--ed41 0005125a490401102ae Page 1 of KMMenu.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
f7806d ¤   KMMenu.c - handle menu enabling/disabling chores
0167c5 ¤
57af5a
fd2814 ¤   $Id: KMMenu.c,v 1.24 1998/08/11 14:43:33 pbj Exp $
aff7f7 ____________________________________________________________________________*/
17e610 #include "pgpPFLConfig.h"
03af5a
85c917 // project header files
d0850a #include "pgpkmx.h"
0baf5a
cf822f // External globals
039cad extern HINSTANCE g_hInst;
feaf5a
3b4265 //¤ ___________________________________________________
42465d //
1c0af9 //¤ determine if each action is enabled or not
e9af5a
71b60b //¤ copy·
0f6c77 static BOOL·
d0dd10 sIsCopyEnabled (PKEYMAN pKM) {
c784e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
616338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
c1c2e7 ¤   return TRUE;
41efe6 }
95af5a
4713d8 //¤ paste·
006c77 static BOOL·
08d2e8 sIsPasteEnabled (PKEYMAN pKM) {
9770ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
5262cc ¤   if (!KMDataToPaste ()) return FALSE;
aac2e7 ¤   return TRUE;
88efe6 }
beaf5a
9978da //¤ delete·
5e7efe BOOL·
963763 IsDeleteEnabled (PKEYMAN pKM) {
c770ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
f23bc1 ¤   if (KMMultipleSelected (pKM)) return TRUE;
b666e9 ¤   switch (KMFocusedItemType (pKM)) {
0e082a ¤   ¤   case IDX_NONE :·
315f1f ¤   ¤   ¤   return FALSE;
e68d0c ¤   ¤   case IDX_RSAUSERID :
659f19 ¤   ¤   case IDX_DSAUSERID :
940f06 ¤   ¤   ¤   if (KMIsThisTheOnlyUserID (pKM,·
388577 ¤   ¤   ¤   ¤   ¤   (PGPUserIDRef)KMFocusedObject (pKM)))·
b1d64b ¤   ¤   ¤   ¤   return FALSE;
d2bb8c ¤   ¤   ¤   else
9f06e0 ¤   ¤   ¤   ¤   return TRUE;
ad3a18 ¤   ¤   default :
5632bd ¤   ¤   ¤   return TRUE;
249371 ¤   }
53efe6 }
d0af5a
eeeff1 //¤ delete from server
746c77 static BOOL·
5cb0bd sIsDeleteFromServerEnabled (PKEYMAN pKM) {
b984e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
ac6338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
190687 ¤   if ((pKM->keyserver.protocol != kPGPKeyServerType_LDAP) &&
8488c1 ¤   ¤   (pKM->keyserver.protocol != kPGPKeyServerType_LDAPS))·
cd98aa ¤   ¤   return FALSE;
dcc2e7 ¤   return TRUE;
a2efe6 }
2daf5a
f3d378 //¤ select all·
fa6c77 static BOOL·
fdcb62 sIsSelectAllEnabled (PKEYMAN pKM) {
51c2e7 ¤   return TRUE;
--1f58 000645cd933401102ae Page 2 of KMMenu.c
7aefe6 }
46af5a
bd03dc //¤ collapse all·
2a6c77 static BOOL·
2f4e9c sIsCollapseAllEnabled (PKEYMAN pKM) {
a5b88b ¤   if (KMFocusedItemType (pKM) == IDX_NONE) return TRUE;
7aa230 ¤   return FALSE;
e4efe6 }
2caf5a
653c50 //¤ expand all·
3a6c77 static BOOL·
d3fbb2 sIsExpandAllEnabled (PKEYMAN pKM) {
d1b88b ¤   if (KMFocusedItemType (pKM) == IDX_NONE) return TRUE;
a1a230 ¤   return FALSE;
7defe6 }
c7af5a
44050a //¤ collapse selected·
f76c77 static BOOL·
51716f sIsCollapseSelEnabled (PKEYMAN pKM) {
470b20 ¤   if (KMFocusedItemType (pKM) == IDX_NONE) return FALSE;
b2c2e7 ¤   return TRUE;
cfefe6 }
03af5a
ca0664 //¤ expand selected·
e16c77 static BOOL·
a7c441 sIsExpandSelEnabled (PKEYMAN pKM) {
270b20 ¤   if (KMFocusedItemType (pKM) == IDX_NONE) return FALSE;
7ec2e7 ¤   return TRUE;
84efe6 }
78af5a
32370a //¤ certify·
526c77 static BOOL·
261601 sIsCertifyEnabled (PKEYMAN pKM) {
2570ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
d0a9f9 ¤   if (KMPromiscuousSelected (pKM)) return KMSigningAllowed (pKM);
2866e9 ¤   switch (KMFocusedItemType (pKM)) {
b1082a ¤   ¤   case IDX_NONE :·
115f1f ¤   ¤   ¤   return FALSE;
8b1fc7 ¤   ¤   case IDX_CERT :
f4fefe ¤   ¤   case IDX_REVCERT :
e907ae ¤   ¤   case IDX_EXPCERT :
ee435e ¤   ¤   case IDX_BADCERT :
370625 ¤   ¤   case IDX_EXPORTCERT :
20d700 ¤   ¤   case IDX_TRUSTEDCERT :
6d1919 ¤   ¤   case IDX_METACERT :
555f1f ¤   ¤   ¤   return FALSE;
2526c7 ¤   ¤   case IDX_RSASECEXPKEY :
423cce ¤   ¤   case IDX_DSASECEXPKEY :
c789d9 ¤   ¤   case IDX_RSASECREVKEY :
0a93d0 ¤   ¤   case IDX_DSASECREVKEY :
b8fc4b ¤   ¤   case IDX_RSAPUBEXPKEY :
87e642 ¤   ¤   case IDX_DSAPUBEXPKEY :
965355 ¤   ¤   case IDX_RSAPUBREVKEY :
fd495c ¤   ¤   case IDX_DSAPUBREVKEY :
608057 ¤   ¤   ¤   if (!KMMultipleSelected (pKM)) return FALSE;
9a20aa ¤   ¤   ¤   else return TRUE;
7a3a18 ¤   ¤   default :
6532bd ¤   ¤   ¤   return TRUE;
789371 ¤   }
fcefe6 }
f4af5a
2bb0ef // enable·
ee6c77 static BOOL·
8e20c4 sIsEnableEnabled (PKEYMAN pKM) {
3d70ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
4d84e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
23e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
c466e9 ¤   switch (KMFocusedItemType (pKM)) {
961993 ¤   ¤   case IDX_RSASECDISKEY :
31039a ¤   ¤   case IDX_DSASECDISKEY :
41c31f ¤   ¤   case IDX_RSAPUBDISKEY :
64d916 ¤   ¤   case IDX_DSAPUBDISKEY :
--1159 000b8411291401102ae Page 3 of KMMenu.c
9232bd ¤   ¤   ¤   return TRUE;
183a18 ¤   ¤   default :
425f1f ¤   ¤   ¤   return FALSE;
269371 ¤   }
93efe6 }
e2af5a
fd971c //¤ disable·
9a6c77 static BOOL·
f28ecb sIsDisableEnabled (PKEYMAN pKM) {
b2a5c2 ¤   PGPBoolean b;
1eaf5a
8370ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
bd84e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
35e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
2866e9 ¤   switch (KMFocusedItemType (pKM)) {
bb7d60 ¤   ¤   case IDX_RSAPUBKEY :
a76f75 ¤   ¤   case IDX_DSAPUBKEY :
d232bd ¤   ¤   ¤   return TRUE;
8f6fca ¤   ¤   case IDX_RSASECKEY :
27118f ¤   ¤   case IDX_RSASECSHRKEY :
997ddf ¤   ¤   case IDX_DSASECKEY :
960b86 ¤   ¤   case IDX_DSASECSHRKEY :
d07d4a ¤   ¤   ¤   PGPGetKeyBoolean ((PGPKeyRef)KMFocusedObject (pKM),
75404b ¤   ¤   ¤   ¤   kPGPKeyPropIsAxiomatic, &b);
d75d14 ¤   ¤   ¤   if (b) return FALSE;
7420aa ¤   ¤   ¤   else return TRUE;
f43a18 ¤   ¤   default :
615f1f ¤   ¤   ¤   return FALSE;
fd9371 ¤   }
0fefe6 }
61af5a
3d85f3 //¤ disable on server
cf6c77 static BOOL·
a8676b sIsDisableOnServerEnabled (PKEYMAN pKM) {
b184e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
f46338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
970687 ¤   if ((pKM->keyserver.protocol != kPGPKeyServerType_LDAP) &&
1b88c1 ¤   ¤   (pKM->keyserver.protocol != kPGPKeyServerType_LDAPS))·
4e98aa ¤   ¤   return FALSE;
7bc2e7 ¤   return TRUE;
abefe6 }
27af5a
dc7926 //¤ add user id·
416c77 static BOOL·
92c724 sIsAddUserEnabled (PKEYMAN pKM) {
5d70ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
0184e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
85e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
d966e9 ¤   switch (KMFocusedItemType (pKM)) {
7d6fca ¤   ¤   case IDX_RSASECKEY :
a77ddf ¤   ¤   case IDX_DSASECKEY :
c11993 ¤   ¤   case IDX_RSASECDISKEY :
ac039a ¤   ¤   case IDX_DSASECDISKEY :
1e118f ¤   ¤   case IDX_RSASECSHRKEY :
2e0b86 ¤   ¤   case IDX_DSASECSHRKEY :
1232bd ¤   ¤   ¤   return TRUE;
823a18 ¤   ¤   default :
fc5f1f ¤   ¤   ¤   return FALSE;
c49371 ¤   }
a8efe6 }
e0af5a
719107 //¤ add photo id·
e86c77 static BOOL·
bdd944 sIsAddPhotoEnabled (PKEYMAN pKM) {
2d70ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
f084e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
71e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
5b66e9 ¤   switch (KMFocusedItemType (pKM)) {
4a7ddf ¤   ¤   case IDX_DSASECKEY :
42039a ¤   ¤   case IDX_DSASECDISKEY :
d50b86 ¤   ¤   case IDX_DSASECSHRKEY :
b832bd ¤   ¤   ¤   return TRUE;
--04bf 000c5fa7f41401102ae Page 4 of KMMenu.c
d83a18 ¤   ¤   default :
475f1f ¤   ¤   ¤   return FALSE;
de9371 ¤   }
8aefe6 }
19af5a
d2fe73 //¤ add revoker·
9a6c77 static BOOL·
1e0400 sIsAddRevokerEnabled (PKEYMAN pKM) {
1e70ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
d984e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
d8e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
2166e9 ¤   switch (KMFocusedItemType (pKM)) {
c57ddf ¤   ¤   case IDX_DSASECKEY :
62039a ¤   ¤   case IDX_DSASECDISKEY :
ac0b86 ¤   ¤   case IDX_DSASECSHRKEY :
3832bd ¤   ¤   ¤   return TRUE;
413a18 ¤   ¤   default :
975f1f ¤   ¤   ¤   return FALSE;
419371 ¤   }
acefe6 }
35af5a
bf685d //¤ revoke·
f26c77 static BOOL·
16376f sIsRevokeEnabled (PKEYMAN pKM) {
25eb1d ¤   PGPBoolean b1, b2;
93af5a
ed70ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
2984e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
7fe6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
b5af5a
5966e9 ¤   switch (KMFocusedItemType (pKM)) {
9f6fca ¤   ¤   case IDX_RSASECKEY :
f57ddf ¤   ¤   case IDX_DSASECKEY :
2b1993 ¤   ¤   case IDX_RSASECDISKEY :
b0039a ¤   ¤   case IDX_DSASECDISKEY :
dc118f ¤   ¤   case IDX_RSASECSHRKEY :
db0b86 ¤   ¤   case IDX_DSASECSHRKEY :
207d4a ¤   ¤   ¤   PGPGetKeyBoolean ((PGPKeyRef)KMFocusedObject (pKM),
500859 ¤   ¤   ¤   ¤   kPGPKeyPropCanSign, &b2);
c78bbf ·¤  ¤   ¤   if (b2) return TRUE;
633b33 ¤   ¤   ¤   else return FALSE;
bcaf5a
577d60 ¤   ¤   case IDX_RSAPUBKEY :
966f75 ¤   ¤   case IDX_DSAPUBKEY :
c8c31f ¤   ¤   case IDX_RSAPUBDISKEY :
09d916 ¤   ¤   case IDX_DSAPUBDISKEY :
1c7d4a ¤   ¤   ¤   PGPGetKeyBoolean ((PGPKeyRef)KMFocusedObject (pKM),
ec0a6c ¤   ¤   ¤   ¤   kPGPKeyPropIsRevocable, &b1);
f1119e ·¤  ¤   ¤   if (b1) return TRUE;
2b3b33 ¤   ¤   ¤   else return FALSE;
5daf5a
c51fc7 ¤   ¤   case IDX_CERT :
89435e ¤   ¤   case IDX_BADCERT :
d00625 ¤   ¤   case IDX_EXPORTCERT :
4dd700 ¤   ¤   case IDX_TRUSTEDCERT :
801919 ¤   ¤   case IDX_METACERT :
5a2ce2 ¤   ¤   ¤   PGPGetSigBoolean ((PGPSigRef)KMFocusedObject (pKM),·
da2531 ¤   ¤   ¤   ¤   kPGPSigPropIsMySig, &b1);
11404c ¤   ¤   ¤   if (b1) return TRUE;
2d3b33 ¤   ¤   ¤   else return FALSE;
a6af5a
7c3a18 ¤   ¤   default :
ba5f1f ¤   ¤   ¤   return FALSE;
b99371 ¤   }
9fefe6 }
3faf5a
d0b730 //¤ set as default
136c77 static BOOL·
2e253f sIsSetAsDefaultEnabled (PKEYMAN pKM) {
caa5c2 ¤   PGPBoolean b;
82af5a
c584e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
--acbf 00032b775ee401102ae Page 5 of KMMenu.c
91e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
1e66e9 ¤   switch (KMFocusedItemType (pKM)) {
c56fca ¤   ¤   case IDX_RSASECKEY :
b21993 ¤   ¤   case IDX_RSASECDISKEY :
15118f ¤   ¤   case IDX_RSASECSHRKEY :
3f7d4a ¤   ¤   ¤   PGPGetKeyBoolean ((PGPKeyRef)KMFocusedObject (pKM),
20339a ¤   ¤   ¤   ¤   kPGPKeyPropCanSign, &b);
63299f ¤   ¤   ¤   if (b) return TRUE;
373b33 ¤   ¤   ¤   else return FALSE;
e57ddf ¤   ¤   case IDX_DSASECKEY :
8f039a ¤   ¤   case IDX_DSASECDISKEY :
540b86 ¤   ¤   case IDX_DSASECSHRKEY :
ef32bd ¤   ¤   ¤   return TRUE;
563a18 ¤   ¤   default :
115f1f ¤   ¤   ¤   return FALSE;
8f9371 ¤   }
e7efe6 }
11af5a
795645 //¤ set as primary
d16c77 static BOOL·
f4a24f sIsSetAsPrimaryEnabled (PKEYMAN pKM) {
8670ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
ff84e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
a4e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
be66e9 ¤   switch (KMFocusedItemType (pKM)) {
878d0c ¤   ¤   case IDX_RSAUSERID :
969f19 ¤   ¤   case IDX_DSAUSERID :
ad4c8c ¤   ¤   ¤   return (!KMIsThisThePrimaryUserID (pKM,·
3fa720 ¤   ¤   ¤   ¤   (PGPUserIDRef)KMFocusedObject (pKM)));
1d3a18 ¤   ¤   default :
345f1f ¤   ¤   ¤   return FALSE;
109371 ¤   }
d9efe6 }
78af5a
65b7d4 //¤ import·
886c77 static BOOL·
0962c9 sIsImportEnabled (PKEYMAN pKM) {
6c70ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
77c2e7 ¤   return TRUE;
74efe6 }
74af5a
89c65b //¤ export
656c77 static BOOL·
b800a5 sIsExportEnabled (PKEYMAN pKM) {
d284e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
a96338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
b1c2e7 ¤   return TRUE;
5cefe6 }
45af5a
043631 //¤ properties
896c77 static BOOL·
abd706 sIsPropertiesEnabled (PKEYMAN pKM) {
0fa5c2 ¤   PGPBoolean b;
a4af5a
4164d5 ¤   if (pKM->ulOptionFlags & KMF_MODALPROPERTIES) {
e070bc ¤   ¤   if (KMMultipleSelected (pKM)) return FALSE;
f29371 ¤   }
dc995d ¤   if (KMFocusedObjectType (pKM) == OBJECT_NONE) return FALSE;
599022 ¤   if (KMFocusedObjectType (pKM) == OBJECT_CERT) {
9c70bc ¤   ¤   if (KMMultipleSelected (pKM)) return FALSE;
89f6cb ¤   ¤   PGPGetSigBoolean ((PGPSigRef)KMFocusedObject (pKM),·
d0610e ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPSigPropIsVerified, &b);
d95620 ¤   ¤   if (!b) return FALSE;
059371 ¤   }
83c2e7 ¤   return TRUE;
20efe6 }
05af5a
22348d //¤ send to keyserver
946c77 static BOOL·
3182eb sIsSendToServerEnabled (PKEYMAN pKM) {
4a84e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
326338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
--aeb8 000f54c8a25401102ae Page 6 of KMMenu.c
d6c2e7 ¤   return TRUE;
43efe6 }
7baf5a
24eff4 //¤ get from keyserver
ce6c77 static BOOL·
f511d0 sIsGetFromServerEnabled (PKEYMAN pKM) {
e284e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
18995d ¤   if (KMFocusedObjectType (pKM) == OBJECT_NONE) return FALSE;
1a0c06 ¤   if (KMFocusedObjectType (pKM) == OBJECT_USERID) return FALSE;
18c2e7 ¤   return TRUE;
05efe6 }
c0af5a
a3a326 //¤ unselect all·
3e6c77 static BOOL·
7f0291 sIsUnselectAllEnabled (PKEYMAN pKM) {
bec2e7 ¤   return TRUE;
21efe6 }
7daf5a
e4a541 //¤ add to main·
aa6c77 static BOOL·
8afb2b sIsAddToMainEnabled (PKEYMAN pKM) {
fc84e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
936338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
bcc2e7 ¤   return TRUE;
faefe6 }
33af5a
eaba50 //¤ reverify signatures·
976c77 static BOOL·
dee3cc sIsReverifySigsEnabled (PKEYMAN pKM) {
9084e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
146338 ¤   if (KMFocusedObjectType (pKM) != OBJECT_KEY) return FALSE;
acc2e7 ¤   return TRUE;
16efe6 }
caaf5a
374deb //¤ split key for sharing·
2b6c77 static BOOL·
c5ea83 sIsSplitKeyEnabled (PKEYMAN pKM) {
87a5c2 ¤   PGPBoolean b;
e7af5a
3270ec ¤   if (pKM->ulOptionFlags & KMF_READONLY) return FALSE;
6a84e9 ¤   if (KMPromiscuousSelected (pKM)) return FALSE;
02e6fd ¤   if (KMMultipleSelected (pKM)) return FALSE;
3c66e9 ¤   switch (KMFocusedItemType (pKM)) {
c16fca ¤   ¤   case IDX_RSASECKEY :
5b1993 ¤   ¤   case IDX_RSASECDISKEY :
a97d4a ¤   ¤   ¤   PGPGetKeyBoolean ((PGPKeyRef)KMFocusedObject (pKM),
6b339a ¤   ¤   ¤   ¤   kPGPKeyPropCanSign, &b);
8a299f ¤   ¤   ¤   if (b) return TRUE;
5f3b33 ¤   ¤   ¤   else return FALSE;
e17ddf ¤   ¤   case IDX_DSASECKEY :
eb039a ¤   ¤   case IDX_DSASECDISKEY :
a932bd ¤   ¤   ¤   return TRUE;
dc3a18 ¤   ¤   default :
515f1f ¤   ¤   ¤   return FALSE;
0a9371 ¤   }
19efe6 }
15af5a
a64265 //¤ ___________________________________________________
57465d //
ffcb17 //¤ determine if action is enabled or not, based on
c66ad3 //¤ flags passed in and current selection
bcaf5a
7a1cb5 BOOL PGPkmExport·
f38b67 PGPkmIsActionEnabled (
d92b66 ¤   ¤   HKEYMAN hKM,·
37bd5f ¤   ¤   ULONG¤  ulAction)·
acbb36 {
e1af5a
75218e ¤   PKEYMAN pKM = (PKEYMAN)hKM;
40af5a
3149c3 ¤   if (!hKM) return FALSE;
f55c92 ¤   if (ulAction & pKM->ulDisableActions) return FALSE;
--24e6 000d1883f2e401102ae Page 7 of KMMenu.c
e0af5a
4ab1cd ¤   switch (ulAction) {
60af5a
5d20b6 ¤   case KM_COPY :¤ ¤   ¤   ¤   return sIsCopyEnabled (pKM);
48fc3f ¤   case KM_PASTE :¤¤   ¤   ¤   return sIsPasteEnabled (pKM);
639eef ¤   case KM_DELETEFROMSERVER :¤ return sIsDeleteFromServerEnabled (pKM);
642f17 ¤   case KM_DELETE :¤   ¤   ¤   return IsDeleteEnabled (pKM);
4a1cca ¤   case KM_SELECTALL :¤¤   ¤   return sIsSelectAllEnabled (pKM);
6e9529 ¤   case KM_COLLAPSEALL :¤  ¤   return sIsCollapseAllEnabled (pKM);
3e5459 ¤   case KM_COLLAPSESEL :¤  ¤   return sIsCollapseSelEnabled (pKM);
2b801d ¤   case KM_EXPANDALL :¤¤   ¤   return sIsExpandAllEnabled (pKM);
d5416d ¤   case KM_EXPANDSEL :¤¤   ¤   return sIsExpandSelEnabled (pKM);
790f2b ¤   case KM_CERTIFY :¤  ¤   ¤   return sIsCertifyEnabled (pKM);
699fa6 ¤   case KM_ENABLE :¤   ¤   ¤   return sIsEnableEnabled (pKM);
a4c66a ¤   case KM_DISABLEONSERVER :¤  return sIsDisableOnServerEnabled (pKM);
8f567d ¤   case KM_DISABLE :¤  ¤   ¤   return sIsDisableEnabled (pKM);
002bd8 ¤   case KM_ADDUSERID :¤¤   ¤   return sIsAddUserEnabled (pKM);
79c7f1 ¤   case KM_ADDPHOTOID :¤   ¤   return sIsAddPhotoEnabled (pKM);
c62cd7 ¤   case KM_ADDREVOKER :¤   ¤   return sIsAddRevokerEnabled (pKM);
f40f36 ¤   case KM_REVOKE :¤   ¤   ¤   return sIsRevokeEnabled (pKM);
3ea0c3 ¤   case KM_SETASDEFAULT :¤ ¤   return sIsSetAsDefaultEnabled (pKM);
a7c98d ¤   case KM_SETASPRIMARY :¤ ¤   return sIsSetAsPrimaryEnabled (pKM);
22c52e ¤   case KM_IMPORT :¤   ¤   ¤   return sIsImportEnabled (pKM);
3f6f95 ¤   case KM_EXPORT :¤   ¤   ¤   return sIsExportEnabled (pKM);
390518 ¤   case KM_PROPERTIES :¤   ¤   return sIsPropertiesEnabled (pKM);
275996 ¤   case KM_SENDTOSERVER :¤ ¤   return sIsSendToServerEnabled (pKM);
cc9892 ¤   case KM_GETFROMSERVER :¤¤   return sIsGetFromServerEnabled (pKM);
ceba4d ¤   case KM_UNSELECTALL:¤   ¤   return sIsUnselectAllEnabled (pKM);
557850 ¤   case KM_ADDTOMAIN :¤¤   ¤   return sIsAddToMainEnabled (pKM);
e478ba ¤   case KM_REVERIFYSIGS :¤ ¤   return sIsReverifySigsEnabled (pKM);
cfe6bc ¤   case KM_SPLITKEY¤   ·:¤ ¤   return sIsSplitKeyEnabled (pKM);
44ada4 ¤   default :¤  ¤   ¤   ¤   ¤   return FALSE;
959371 ¤   }
49efe6 }
56af5a
7d4265 //¤ ___________________________________________________
9d465d //
25b041 //¤ select all keys
27af5a
62e6b2 static VOID
c6ef67 sSelectAll (PKEYMAN pKM)·
d5bb36 {
393036 ¤   HTLITEM¤¤   ¤   hFirst;
254aea ¤   TL_TREEITEM¤¤   tlI;
5daf5a
fb6527 ¤   // get first item in list
8307e8 ¤   TreeList_SelectChildren (pKM->hWndTree, NULL);
79c87e ¤   hFirst = TreeList_GetFirstItem (pKM->hWndTree);
73af5a
c89dfc ¤   // try to get second item
c9c481 ¤   tlI.hItem = hFirst;
35bcd4 ¤   if (tlI.hItem) {
b7e99e ¤   ¤   tlI.mask = TLIF_NEXTHANDLE;
9fa78d ¤   ¤   TreeList_GetItem (pKM->hWndTree, &tlI);
3f9371 ¤   }
f9af5a
b8fcdb ¤   // if second item exists, then multiple select
9a1444 ¤   if (tlI.hItem)
0c220e ¤   ¤   KMSetFocus (pKM, hFirst, TRUE);
6a4264 ¤   else·
d8722a ¤   ¤   KMSetFocus (pKM, hFirst, FALSE);
a9af5a
f07096 ¤   SetFocus (pKM->hWndTree);
1befe6 }
5daf5a
464265 //¤ ___________________________________________________
7e465d //
83182c //¤ perform the specified action
8baf5a
41b997 PGPError PGPkmExport·
1a155c PGPkmPerformAction (
d12b66 ¤   ¤   HKEYMAN hKM,·
--7fe9 0008a6c94a9401102ae Page 8 of KMMenu.c
28bd5f ¤   ¤   ULONG¤  ulAction)·
c2bb36 {
01799d ¤   PKEYMAN¤¤   ¤   pKM = (PKEYMAN)hKM;
53af5a
e4ef62 ¤   if (!hKM) return kPGPError_BadParams;
4ec7de ¤   if (!PGPkmIsActionEnabled (hKM, ulAction))·
ba6904 ¤   ¤   return kPGPError_UnknownRequest;
caaf5a
8bb1cd ¤   switch (ulAction) {
5eaf5a
c52e06 ¤   case KM_COPY :
aaf0f1 ¤   ¤   KMCopyKeys (pKM, NULL);
b72f68 ¤   ¤   break;
87af5a
5b5a3c ¤   case KM_PASTE :
b7d14d ¤   ¤   KMPasteKeys (pKM);
182f68 ¤   ¤   break;
f8af5a
ca601c ¤   case KM_DELETE :
dee82d ¤   ¤   KMDeleteObject (pKM);
b32f68 ¤   ¤   break;
40af5a
fb2826 ¤   case KM_SELECTALL :
4c6741 ¤   ¤   sSelectAll (pKM);
0c2f68 ¤   ¤   break;
daaf5a
83d3b8 ¤   case KM_COLLAPSEALL :
8ff9b0 ¤   ¤   KMCollapseSelected (pKM);
7f2f68 ¤   ¤   break;
d7af5a
5ac83a ¤   case KM_COLLAPSESEL :
55f9b0 ¤   ¤   KMCollapseSelected (pKM);
a02f68 ¤   ¤   break;
2aaf5a
35c70e ¤   case KM_EXPANDALL :
28d296 ¤   ¤   KMExpandSelected (pKM);
442f68 ¤   ¤   break;
a3af5a
40dc8c ¤   case KM_EXPANDSEL :
27d296 ¤   ¤   KMExpandSelected (pKM);
a32f68 ¤   ¤   break;
b6af5a
f17983 ¤   case KM_CERTIFY :
a69b43 ¤   ¤   KMCertifyKeyOrUserID (pKM);
502f68 ¤   ¤   break;
49af5a
175673 ¤   case KM_ENABLE :
979398 ¤   ¤   KMEnableKey (pKM, (PGPKeyRef)KMFocusedObject (pKM));
f72f68 ¤   ¤   break;
d3af5a
7b0c94 ¤   case KM_DISABLE :
086243 ¤   ¤   KMDisableKey (pKM, (PGPKeyRef)KMFocusedObject (pKM));
212f68 ¤   ¤   break;
7eaf5a
03004c ¤   case KM_ADDUSERID :
5ba5dc ¤   ¤   KMAddUserToKey (pKM);·
212f68 ¤   ¤   break;
8faf5a
6e5c05 ¤   case KM_ADDPHOTOID :
e33ad3 ¤   ¤   KMAddPhotoToKey (pKM);
de2f68 ¤   ¤   break;
14af5a
62d20e ¤   case KM_ADDREVOKER :
d711df ¤   ¤   KMAddRevoker (pKM);
d92f68 ¤   ¤   break;
47af5a
f290bb ¤   case KM_REVOKE :
a3c1c8 ¤   ¤   if (KMFocusedObjectType (pKM) == OBJECT_CERT) KMRevokeCert (pKM);
fd32c2 ¤   ¤   else KMRevokeKey (pKM);
382f68 ¤   ¤   break;
1daf5a
8abdbb ¤   case KM_SETASDEFAULT :
--1ded 001e317c737401102ae Page 9 of KMMenu.c
fcc6cd ¤   ¤   KMSetDefaultKey (pKM);
382f68 ¤   ¤   break;
7aaf5a
71c540 ¤   case KM_SETASPRIMARY :
c14bcd ¤   ¤   KMSetPrimaryUserID (pKM);
872f68 ¤   ¤   break;
dbaf5a
4a89ad ¤   case KM_IMPORT :
4a0c0c ¤   ¤   KMImportKey (pKM, NULL);
212f68 ¤   ¤   break;
2b1b52 ¤   ¤
97059b ¤   case KM_EXPORT :
704af7 ¤   ¤   KMExportKeys (pKM, NULL);
7f2f68 ¤   ¤   break;
83af5a
d74449 ¤   case KM_PROPERTIES :
d73fe3 ¤   ¤   KMKeyProperties (pKM);
e52f68 ¤   ¤   break;
c6af5a
a926a3 ¤   case KM_SENDTOSERVER :
e7bb6a ¤   ¤   KMSendToServer (pKM, PGPCL_SPECIFIEDSERVER);
3c2f68 ¤   ¤   break;
8aaf5a
1330fd ¤   case KM_GETFROMSERVER :
705a34 ¤   ¤   KMGetFromServer (pKM);
372f68 ¤   ¤   break;
ddaf5a
d3099c ¤   case KM_DELETEFROMSERVER :
7732d8 ¤   ¤   KMDeleteFromServer (pKM);
a72f68 ¤   ¤   break;
7daf5a
0ab307 ¤   case KM_DISABLEONSERVER :
3a7ede ¤   ¤   KMDisableOnServer (pKM);
b82f68 ¤   ¤   break;
48af5a
d57342 ¤   case KM_UNSELECTALL :
4d19b3 ¤   ¤   TreeList_Select (pKM->hWndTree, NULL, TRUE);
d5d1c0 ¤   ¤   KMSetFocus (pKM, NULL, FALSE);
b82f68 ¤   ¤   break;
121b52 ¤   ¤
ff6124 ¤   case KM_ADDTOMAIN :
68df1c ¤   ¤   KMAddSelectedToMain (pKM);
f42f68 ¤   ¤   break;
09af5a
238688 ¤   case KM_REVERIFYSIGS :
2254e8 ¤   ¤   KMReverifySigs (pKM);
d82f68 ¤   ¤   break;
f4af5a
396dba ¤   case KM_SPLITKEY :
9b2c89 ¤   ¤   KMSplitKey (pKM, (PGPKeyRef)KMFocusedObject (pKM));
2d2f68 ¤   ¤   break;
b3af5a
e09371 ¤   }
55af5a
f0151e ¤   return kPGPError_NoErr;
74efe6 }
e3af5a
--e0b5 00083c50cce401102af Page 1 of KMMisc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
19d6de ¤   KMMisc.c - miscellaneous routines
d8af5a
5b4612 ¤   $Id: KMMisc.c,v 1.22 1998/08/11 14:43:33 pbj Exp $
cff7f7 ____________________________________________________________________________*/
7ee610 #include "pgpPFLConfig.h"
54af5a
f9c917 // project header files
c2850a #include "pgpkmx.h"
53af5a
7d3fb5 // external global variables
849cad extern HINSTANCE g_hInst;
4caf5a
d8af5a
f34265 //¤ ___________________________________________________
3c465d //
7f08e6 // Private memory allocation routine
47af5a
c726a1 VOID* KMAlloc (LONG size) {
302332 ¤   VOID* p;
34c01a ¤   p = malloc (size);
3ff191 ¤   if (p) {
f42a2d ¤   ¤   memset (p, 0, size);
769371 ¤   }
47381d ¤   return p;
9cefe6 }
b8af5a
01af5a
714265 //¤ ___________________________________________________
a0465d //
015ad0 // Private memory deallocation routine
3baf5a
977235 VOID KMFree (VOID* p) {
00f191 ¤   if (p) {
88de78 ¤   ¤   free (p);
799371 ¤   }
eeefe6 }
1daf5a
c0af5a
c04265 //¤ ___________________________________________________
88465d //
285ad0 // Private memory deallocation routine
3daf5a
7417a8 VOID KMFindWindowFromPoint (PKEYMAN pKM, POINT* ppt, HWND* phwnd)·
90bb36 {
ada360 ¤   POINT¤  pt;
37af5a
4e2411 ¤   pt.x = ppt->x;
3bfb98 ¤   pt.y = ppt->y;
7caf5a
43a319 ¤   (pKM->lpfnHwndListFunc)(NULL, FALSE, &pt, phwnd);
98efe6 }
4eaf5a
c1af5a
d34265 //¤ ___________________________________________________
46465d //
f07fda // ·Get and truncate the name of a userid.
27af5a
d1ad93 BOOL KMGetUserIDName (PGPUserIDRef UserID, LPSTR sz, UINT uLen) {
397f23 ¤   PGPError¤   err¤¤   ¤   = kPGPError_NoErr;
f61a5e ¤   UINT¤   ¤   u;
b44b0d ¤   PGPBoolean¤ bAttrib;
2b6c5b ¤   PGPInt32¤   iType;
82af5a
b116e0 ¤   PGPGetUserIDBoolean (UserID, kPGPUserIDPropIsAttribute, &bAttrib);
cd1a9f ¤   if (bAttrib) {
c43631 ¤   ¤   PGPGetUserIDNumber (UserID, kPGPUserIDPropAttributeType, &iType);
4e6611 ¤   ¤   switch (iType) {
83104e ¤   ¤   case kPGPAttribute_Image :
--4474 000e4bc269c401102af Page 2 of KMMisc.c
fb8974 ¤   ¤   ¤   LoadString (g_hInst, IDS_PHOTOUSERID, sz, uLen);
2ccdcb ¤   ¤   ¤   break;
f8af5a
883a18 ¤   ¤   default :
13f1ab ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWNUSERID, sz, uLen);
7ecdcb ¤   ¤   ¤   break;
eb0fe4 ¤   ¤   }
639371 ¤   }
f6665a ¤   else {
24dd5f ¤   ¤   err = PGPGetUserIDStringBuffer (UserID, kPGPUserIDPropName,·
d5b2e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uLen, sz, &u);
759371 ¤   }
cfaf5a
c0e101 ¤   switch (err) {
c04daa ¤   case kPGPError_BufferTooSmall :
0ebf4b ¤   case kPGPError_NoErr :
0b836c ¤   ¤   return TRUE;
4faf5a
fbbfad ¤   default :
2794cd ¤   ¤   PGPclErrorBox (NULL, err);
2f98aa ¤   ¤   return FALSE;
129371 ¤   }
40efe6 }
36af5a
94af5a
fa4265 //¤ ___________________________________________________
3c465d //
9dc5cf // ·Get and truncate the name of a primary userid on a key.
b6af5a
e95e86 BOOL KMGetKeyName (PGPKeyRef Key, LPSTR sz, UINT uLen) {
ae2d1f ¤   UINT u, uErr;
26af5a
dfb92c ¤   uErr = PGPGetPrimaryUserIDNameBuffer (Key, uLen, sz, &u);
02af5a
5a7cac ¤   switch (uErr) {
8a4daa ¤   case kPGPError_BufferTooSmall :
a5bf4b ¤   case kPGPError_NoErr :
ee836c ¤   ¤   return TRUE;
1aaf5a
44bfad ¤   default :
5c56bb ¤   ¤   PGPclErrorBox (NULL, uErr);
5298aa ¤   ¤   return FALSE;
a39371 ¤   }
7aefe6 }
5caf5a
e1af5a
074265 //¤ ___________________________________________________
fd465d //
739a68 // ·Get the keyid of a key.
b5af5a
6737da BOOL KMGetKeyIDFromKey (PGPKeyRef Key, LPSTR sz, UINT u) {
66af5a
282c35 ¤   PGPKeyID¤   KeyID;
12df3c ¤   CHAR¤   ¤   szID[kPGPMaxKeyIDStringSize];
a3af5a
5ebbd6 ¤   if (u < 11) return FALSE;
3baf5a
8aa01d ¤   PGPGetKeyIDFromKey (Key, &KeyID);
c8f29a ¤   PGPGetKeyIDString (&KeyID, kPGPKeyIDString_Abbreviated, szID);
957081 ¤   lstrcpyn (sz, szID, u);
96af5a
59c2e7 ¤   return TRUE;
85efe6 }
ceaf5a
87af5a
834265 //¤ ___________________________________________________
42465d //
dbec00 // ·Get the keyid of a signing key.
1faf5a
17898f BOOL KMGetKeyIDFromCert (PGPSigRef Cert, LPSTR sz, UINT u) {
95af5a
e42c35 ¤   PGPKeyID¤   KeyID;
--0c60 000b810c293401102af Page 3 of KMMisc.c
96df3c ¤   CHAR¤   ¤   szID[kPGPMaxKeyIDStringSize];
2caf5a
15bbd6 ¤   if (u < 11) return FALSE;
f5af5a
414ba8 ¤   PGPGetKeyIDOfCertifier (Cert, &KeyID);
00f29a ¤   PGPGetKeyIDString (&KeyID, kPGPKeyIDString_Abbreviated, szID);
937081 ¤   lstrcpyn (sz, szID, u);
5daf5a
64c2e7 ¤   return TRUE;
51efe6 }
efaf5a
a5af5a
8a4265 //¤ ___________________________________________________
d3465d //
1b5da6 // ·Get the parent key of a userid
02af5a
07c3d8 PGPKeyRef KMGetKeyFromUserID (PKEYMAN pKM, PGPUserIDRef UserID) {
7ee723 ¤   TL_TREEITEM tli;
cdaf5a
10144c ¤   KMGetUserIDUserVal (pKM, UserID, (long*)&(tli.hItem));
4f5e5e ¤   if (tli.hItem) {
12c9fe ¤   ¤   tli.mask = TLIF_PARENTHANDLE;
0d28de ¤   ¤   TreeList_GetItem (pKM->hWndTree, &tli);
3eef8f ¤   ¤   if (tli.hItem) {
e6263c ¤   ¤   ¤   tli.mask = TLIF_PARAM;
e7be9f ¤   ¤   ¤   TreeList_GetItem (pKM->hWndTree, &tli);
6ffb57 ¤   ¤   ¤   return ((PGPKeyRef)(tli.lParam));
9e0fe4 ¤   ¤   }
d09371 ¤   }
d23f59 ¤   return NULL;
1aefe6 }
79af5a
b9af5a
984265 //¤ ___________________________________________________
6e465d //
192483 // ·Get the signing key from a cert
64af5a
9b689a PGPKeyRef KMGetKeyFromCert (PKEYMAN pKM, PGPSigRef Cert) {
5fe723 ¤   TL_TREEITEM tli;
7daf5a
4203b6 ¤   KMGetCertUserVal (pKM, Cert, (long*)&(tli.hItem));
1b5e5e ¤   if (tli.hItem) {
bcc9fe ¤   ¤   tli.mask = TLIF_PARENTHANDLE;
e628de ¤   ¤   TreeList_GetItem (pKM->hWndTree, &tli);
42ef8f ¤   ¤   if (tli.hItem) {
74f510 ¤   ¤   ¤   tli.mask = TLIF_PARENTHANDLE;
55be9f ¤   ¤   ¤   TreeList_GetItem (pKM->hWndTree, &tli);
b5dbd2 ¤   ¤   ¤   if (tli.hItem) {
ad67cf ¤   ¤   ¤   ¤   tli.mask = TLIF_PARAM;
a0eb33 ¤   ¤   ¤   ¤   TreeList_GetItem (pKM->hWndTree, &tli);
4cb469 ¤   ¤   ¤   ¤   return ((PGPKeyRef)(tli.lParam));
58a3a6 ¤   ¤   ¤   }
4c0fe4 ¤   ¤   }
419371 ¤   }
c53f59 ¤   return NULL;
baefe6 }
ecaf5a
b2af5a
e04265 //¤ ___________________________________________________
d7465d //
c6aa05 // ·Look for secret keys
b7af5a
2bf543 BOOL KMCheckForSecretKeys (PGPKeySetRef KeySet) {
69d34e ¤   PGPKeyListRef KeyList;
be4276 ¤   PGPKeyIterRef KeyIter;
2a6a89 ¤   PGPKeyRef Key;
af827e ¤   BOOL bSecretKeys;
ef0df9 ¤   Boolean bSecret;
53af5a
c20ba7 ¤   PGPOrderKeySet (KeySet, kPGPAnyOrdering, &KeyList);
ad1953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
b8af5a
--f4e8 0008f81cc2c401102af Page 4 of KMMisc.c
ef5857 ¤   bSecretKeys = FALSE;
ef800a ¤   PGPKeyIterNext (KeyIter, &Key);
e7af5a
7acab8 ¤   while (Key && !bSecretKeys) {
d38a79 ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
166059 ¤   ¤   if (bSecret) {
e119f1 ¤   ¤   ¤   bSecretKeys = TRUE;
d60fe4 ¤   ¤   }
1f455f ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
9b9371 ¤   }
4daf5a
ba11d4 ¤   PGPFreeKeyIter (KeyIter);
70a279 ¤   PGPFreeKeyList (KeyList);
75af5a
0e1bc2 ¤   return bSecretKeys;
43efe6 }
b9af5a
12af5a
824265 //¤ ___________________________________________________
01465d //
e3f747 // ·Is this the only userID on the key ?
d2af5a
ad75c0 BOOL KMIsThisTheOnlyUserID (PKEYMAN pKM, PGPUserIDRef UID) {
cad34e ¤   PGPKeyListRef KeyList;
ae4276 ¤   PGPKeyIterRef KeyIter;
3b6a89 ¤   PGPKeyRef Key;
b6f63b ¤   PGPUserIDRef UserID;
520186 ¤   PGPBoolean bAttrib;
563287 ¤   INT iCount;
efaf5a
4a763d ¤   Key = KMGetKeyFromUserID (pKM, UID);
f8ad2a ¤   PGPOrderKeySet (pKM->KeySetDisp, kPGPAnyOrdering, &KeyList);
701953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
840c97 ¤   PGPKeyIterSeek (KeyIter, Key);
19af5a
dde957 ¤   PGPKeyIterNextUserID (KeyIter, &UserID);
17af5a
4052f5 ¤   iCount = 0;
2043e6 ¤   while (UserID) {
abc64b ¤   ¤   PGPGetUserIDBoolean (UserID, kPGPUserIDPropIsAttribute, &bAttrib);
d8499f ¤   ¤   if (!bAttrib) iCount++;
0abbca ¤   ¤   PGPKeyIterNextUserID (KeyIter, &UserID);
f29371 ¤   }
37af5a
9111d4 ¤   PGPFreeKeyIter (KeyIter);
0da279 ¤   PGPFreeKeyList (KeyList);
fdaf5a
f6194d ¤   return (iCount == 1);
faefe6 }
8faf5a
c8af5a
ae4265 //¤ ___________________________________________________
e5465d //
0fe9b1 // ·Is this the primary userID on the key ?
64af5a
884644 BOOL KMIsThisThePrimaryUserID (PKEYMAN pKM, PGPUserIDRef UID) {
4d6a89 ¤   PGPKeyRef Key;
e4a4d3 ¤   PGPUserIDRef PrimaryUserID;
92af5a
00763d ¤   Key = KMGetKeyFromUserID (pKM, UID);
ca342d ¤   PGPGetPrimaryUserID (Key, &PrimaryUserID);
81af5a
51c035 ¤   if (UID == PrimaryUserID) return TRUE;
f9cdfa ¤   else return FALSE;
24efe6 }
f4af5a
cbaf5a
8f4265 //¤ ___________________________________________________
b4465d //
367cc4 // ·Are there existing photoids on the key ?
73af5a
8f9019 BOOL KMExistingPhotoID (PKEYMAN pKM, PGPKeyRef key) {
--3596 000e6591fbc401102af Page 5 of KMMisc.c
e0af5a
4b57d0 ¤   BOOL¤   ¤   ¤   bExistingPhotoID¤   ¤   = FALSE;
dfaf5a
87d125 ¤   PGPKeyListRef¤  keylist;
1fc323 ¤   PGPKeyIterRef¤  keyiter;
7c8f18 ¤   PGPUserIDRef¤   userid;
e7e012 ¤   PGPBoolean¤ ¤   bAttrib;
134fac ¤   PGPInt32¤   ¤   iType;
0eaf5a
72621c ¤   PGPOrderKeySet (pKM->KeySetDisp, kPGPAnyOrdering, &keylist);
a1f4cc ¤   PGPNewKeyIter (keylist, &keyiter);
e3ef9e ¤   PGPKeyIterSeek (keyiter, key);
16af5a
7f42bf ¤   PGPKeyIterNextUserID (keyiter, &userid);
5caf5a
260aa2 ¤   while (userid) {
c0af5a
54149d ¤   ¤   PGPGetUserIDBoolean (userid, kPGPUserIDPropIsAttribute, &bAttrib);
b62176 ¤   ¤   if (bAttrib) {
ba9dad ¤   ¤   ¤   PGPGetUserIDNumber (userid, kPGPUserIDPropAttributeType, &iType);
0d0943 ¤   ¤   ¤   if (iType == kPGPAttribute_Image) {
fff83e ¤   ¤   ¤   ¤   bExistingPhotoID = TRUE;
6df622 ¤   ¤   ¤   ¤   break;
04a3a6 ¤   ¤   ¤   }
6e0fe4 ¤   ¤   }
c7af5a
171022 ¤   ¤   PGPKeyIterNextUserID (keyiter, &userid);
cb9371 ¤   }
2faf5a
4adee2 ¤   PGPFreeKeyIter (keyiter);
246d4f ¤   PGPFreeKeyList (keylist);
2caf5a
e0cbcc ¤   return bExistingPhotoID;
f9efe6 }
f1af5a
48af5a
8a4265 //¤ ___________________________________________________
9d465d //
38a2c1 // ·Put up preferences property sheet
8caf5a
157037 INT KMCommitKeyRingChanges (PKEYMAN pKM) {
c1d44b ¤   INT iError = 0;
612abc ¤   HCURSOR hCursorOld;
695684 ¤   UINT uReloadMessage;
8daf5a
62c497 ¤   if (pKM->ulOptionFlags & KMF_ENABLECOMMITS) {
78f63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
5227fd ¤   ¤   iError = PGPCommitKeyRingChanges (pKM->KeySetMain);
9e7139 ¤   ¤   SetCursor (hCursorOld);
26dd51 ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, iError))) {
cc4c40 ¤   ¤   ¤   KMUpdateKeyProperties (pKM);
e10fe4 ¤   ¤   }
cf9371 ¤   }
f00bea ¤   if (pKM->ulOptionFlags & KMF_ENABLERELOADS) {
362307 ¤   ¤   if (!iError) {
7889d8 ¤   ¤   ¤   uReloadMessage = RegisterWindowMessage (RELOADKEYRINGMSG);
730671 ¤   ¤   ¤   PostMessage (HWND_BROADCAST, uReloadMessage,·
381afe ¤   ¤   ¤   ¤   MAKEWPARAM (LOWORD (pKM->hWndParent), FALSE),·
b8794d ¤   ¤   ¤   ¤   GetCurrentProcessId ());
790fe4 ¤   ¤   }
909371 ¤   }
6d0507 ¤   return iError;
30efe6 }
86af5a
5aaf5a
374265 //¤ ___________________________________________________
99465d //
95a0ca // ·Determine the appropriate icon for a userid, based on
d30a42 //¤ key properties
c0af5a
58a3e8 INT KMDetermineUserIDIcon (
e69957 ¤   ¤   PGPKeyRef¤  ¤   Key,
--8f50 000ef291403401102af Page 6 of KMMisc.c
5fc047 ¤   ¤   PGPUserIDRef¤   UserID,
9debc7 ¤   ¤   BOOL*¤  ¤   ¤   pbItalics)·
67bb36 {
397a0a ¤   PGPInt32¤   iAlg;
c86c5b ¤   PGPInt32¤   iType;
d04b0d ¤   PGPBoolean¤ bAttrib;
30af5a
0a0455 ¤   if (pbItalics) *pbItalics = FALSE;
2caf5a
360c02 ¤   if (UserID) {
86c64b ¤   ¤   PGPGetUserIDBoolean (UserID, kPGPUserIDPropIsAttribute, &bAttrib);
572176 ¤   ¤   if (bAttrib) {
604f7b ¤   ¤   ¤   PGPGetUserIDNumber (UserID, kPGPUserIDPropAttributeType, &iType);
3e524c ¤   ¤   ¤   switch (iType) {
4b51bd ¤   ¤   ¤   case kPGPAttribute_Image :
85a6d2 ¤   ¤   ¤   ¤   return IDX_PHOTOUSERID;
94af5a
510082 ¤   ¤   ¤   default :
2bafec ¤   ¤   ¤   ¤   if (pbItalics)·
833ea3 ¤   ¤   ¤   ¤   ¤   *pbItalics = TRUE;
41ef25 ¤   ¤   ¤   ¤   return IDX_INVALIDUSERID;
cfa3a6 ¤   ¤   ¤   }
7c0fe4 ¤   ¤   }
bd9371 ¤   }
46af5a
1ec181 ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, &iAlg);
3e42c4 ¤   if (iAlg == kPGPPublicKeyAlgorithm_RSA) return (IDX_RSAUSERID);
13af69 ¤   else return (IDX_DSAUSERID);
dcefe6 }
ceaf5a
eaaf5a
484265 //¤ ___________________________________________________
d7465d //
14f7f5 // ·Determine the appropriate icon for a cert, based on
cb1419 //¤ its properties
2aaf5a
15100d INT·
731855 KMDetermineCertIcon (
d99b6b ¤   ¤   PGPSigRef¤  cert,·
166f68 ¤   ¤   BOOL*¤  ¤   pbItalics)·
c1bb36 {
752327 ¤   PGPBoolean¤ bRevoked, bVerified, bTried, bExpired;
0e7586 ¤   PGPBoolean¤ bNotCorrupt, bExportable;
566a3d ¤   PGPUInt32¤  uTrustLevel;
d9356e ¤   INT¤¤   ¤   idx;
83af5a
7c8f74 ¤   PGPGetSigBoolean (cert, kPGPSigPropIsRevoked, &bRevoked);
28a7e8 ¤   PGPGetSigBoolean (cert, kPGPSigPropIsExpired, &bExpired);
462757 ¤   PGPGetSigBoolean (cert, kPGPSigPropIsVerified, &bVerified);
b3fdc0 ¤   PGPGetSigBoolean (cert, kPGPSigPropIsTried, &bTried);
da957a ¤   PGPGetSigBoolean (cert, kPGPSigPropIsNotCorrupt, &bNotCorrupt);
9257ac ¤   PGPGetSigBoolean (cert, kPGPSigPropIsExportable, &bExportable);
c55f69 ¤   PGPGetSigNumber ·(cert, kPGPSigPropTrustLevel, &uTrustLevel);
2eaf5a
9c9364 ¤   if (bRevoked) idx = IDX_REVCERT;
7e4772 ¤   else if (bExpired) idx = IDX_EXPCERT;
aa881c ¤   else if (bVerified) {
e6347a ¤   ¤   if (bExportable) {
42ce65 ¤   ¤   ¤   if (uTrustLevel == 1) idx = IDX_TRUSTEDCERT;
54550c ¤   ¤   ¤   else idx = IDX_EXPORTCERT;
f00fe4 ¤   ¤   }
d907e0 ¤   ¤   else {
b9e82a ¤   ¤   ¤   if (uTrustLevel == 2) idx = IDX_METACERT;
8ad82a ¤   ¤   ¤   else idx = IDX_CERT;
430fe4 ¤   ¤   }
e59371 ¤   }
0b86c5 ¤   else if (bTried) idx = IDX_BADCERT;
5d3d72 ¤   else if (bNotCorrupt) {
340154 ¤   ¤   if (bExportable) idx = IDX_EXPORTCERT;
71637c ¤   ¤   else idx = IDX_CERT;
7b9371 ¤   }
ef7609 ¤   else idx = IDX_BADCERT;
--3c30 001b0cc919e401102af Page 7 of KMMisc.c
e0af5a
6de591 ¤   if ((idx == IDX_BADCERT) || (idx == IDX_REVCERT) || (idx == IDX_EXPCERT))·
56e707 ¤   ¤   *pbItalics = TRUE;
0eaf5a
5ad2d9 ¤   return idx;
55efe6 }
38af5a
b5af5a
e94265 //¤ ___________________________________________________
9e465d //
abf1e1 // ·Determine the appropriate icon for a key, based on
ad1419 //¤ its properties
bfaf5a
02f6ad INT KMDetermineKeyIcon (
9945dc ¤   ¤   PKEYMAN¤¤   pKM,·
87ade8 ¤   ¤   PGPKeyRef¤  Key,·
b35d82 ¤   ¤   BOOL*¤  ¤   lpbItalics)·
96bb36 {
bbaf5a
b0fea0 ¤   PGPBoolean bRevoked, bSecret, bDisabled, bExpired, bSplit;
aa7d8f ¤   PGPBoolean b, bRSADisabled;
4b31a4 ¤   PGPUInt32 iIdx, iAlg;
e1af5a
ffc209 ¤   bRSADisabled = FALSE;
b79734 ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsRevoked, &bRevoked);
3a8a9b ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
36561e ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsDisabled, &bDisabled);
23bfa8 ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsExpired, &bExpired);
938d1e ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecretShared, &bSplit);
5ac181 ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, &iAlg);
95af5a
ca7651 ¤   if (iAlg == kPGPPublicKeyAlgorithm_RSA) {
b56059 ¤   ¤   if (bSecret) {
9dc3d6 ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropCanSign, &b);
fc859f ¤   ¤   ¤   if (!b) bRSADisabled = TRUE;
35840f ¤   ¤   ¤   if (bRevoked) iIdx = IDX_RSASECREVKEY;
633985 ¤   ¤   ¤   else if (bExpired) iIdx = IDX_RSASECEXPKEY;
67a41d ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_RSASECDISKEY;
2c6431 ¤   ¤   ¤   else if (bSplit) iIdx = IDX_RSASECSHRKEY;
4ceb72 ¤   ¤   ¤   else iIdx = IDX_RSASECKEY;
560fe4 ¤   ¤   }
b607e0 ¤   ¤   else {
506e8b ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropCanEncrypt, &b);
b3859f ¤   ¤   ¤   if (!b) bRSADisabled = TRUE;
98e513 ¤   ¤   ¤   if (bRevoked) iIdx = IDX_RSAPUBREVKEY;
6b5899 ¤   ¤   ¤   else if (bExpired) iIdx = IDX_RSAPUBEXPKEY;
3ec501 ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_RSAPUBDISKEY;
05d040 ¤   ¤   ¤   else iIdx = IDX_RSAPUBKEY;
830fe4 ¤   ¤   }
389371 ¤   }
71f0b1 ¤   // DSA/ElGamal
4a665a ¤   else {
506059 ¤   ¤   if (bSecret) {
3b5cb5 ¤   ¤   ¤   if (bRevoked) iIdx = IDX_DSASECREVKEY;
95e13f ¤   ¤   ¤   else if (bExpired) iIdx = IDX_DSASECEXPKEY;
a37ca7 ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_DSASECDISKEY;
78bc8b ¤   ¤   ¤   else if (bSplit) iIdx = IDX_DSASECSHRKEY;
a86f40 ¤   ¤   ¤   else iIdx = IDX_DSASECKEY;
c10fe4 ¤   ¤   }
cc07e0 ¤   ¤   else {
6f3da9 ¤   ¤   ¤   if (bRevoked) iIdx = IDX_DSAPUBREVKEY;
688023 ¤   ¤   ¤   else if (bExpired) iIdx = IDX_DSAPUBEXPKEY;
f51dbb ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_DSAPUBDISKEY;
2a5472 ¤   ¤   ¤   else iIdx = IDX_DSAPUBKEY;
130fe4 ¤   ¤   }
429371 ¤   }
a3af5a
f9a1b4 ¤   if (lpbItalics)·
63d6e6 ¤   ¤   *lpbItalics = bRevoked || bExpired || bDisabled || bRSADisabled;
65eadc ¤   return iIdx;
b0efe6 }
--1c4a 0006e5b3dee401102b0 Page 1 of KMNotPrc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
5f1047 ¤   KMNotProc - notification processing and associated routines
b367c5 ¤
f8af5a
cc1e92 ¤   $Id: KMNotPrc.c,v 1.6 1998/08/11 14:43:34 pbj Exp $
46f7f7 ____________________________________________________________________________*/
aee610 #include "pgpPFLConfig.h"
6daf5a
55c917 // project header files
46850a #include "pgpkmx.h"
91af5a
cf822f // External globals
449cad extern HINSTANCE g_hInst;
ebaf5a
7f4265 //¤ ___________________________________________________
14465d //
897995 // ·reorder columns according to new header order
b7af5a
c5239b static VOID ·
8541fb sReorderColumns (PKEYMAN pKM)
3abb36 {
5393de ¤   INT¤¤   iOrderArray[NUMBERFIELDS];
ac9ca9 ¤   WORD¤   wColumnField[NUMBERFIELDS];
33762c ¤   INT¤¤   i, iNumCols;
1faf5a
330ae2 ¤   // save order
b1d760 ¤   KMSetColumnPreferences (pKM);
32a064 ¤   iNumCols = 1;
678a38 ¤   for (i=0; i<NUMBERFIELDS; i++) {
57f851 ¤   ¤   wColumnField[i] = pKM->wColumnField[i];
0c140f ¤   ¤   if (wColumnField[i]) iNumCols++;
3f9371 ¤   }
4faf5a
ebdbf0 ¤   TreeList_GetOrderArray (pKM->hWndTree, iNumCols, &iOrderArray);
70af5a
26a60c ¤   for (i=0; i<iNumCols; i++) {
eaadcd ¤   ¤   pKM->wColumnField[i] = wColumnField[iOrderArray[i]];
7d9371 ¤   }
1aaf5a
45ac18 ¤   KMDeleteAllUserValues (pKM);
119033 ¤   KMSetFocus (pKM, NULL, FALSE);
71f9b5 ¤   TreeList_DeleteTree (pKM->hWndTree, TRUE);
2a91cd ¤   TreeList_DeleteAllColumns (pKM->hWndTree);
c6af5a
75db64 ¤   KMAddColumns (pKM);
960b1b ¤   KMLoadKeyRingIntoTree (pKM, FALSE, FALSE, TRUE);
47b65e ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
18ed22 ¤   UpdateWindow (pKM->hWndTree);
76af5a
99d760 ¤   KMSetColumnPreferences (pKM);
28efe6 }
cdaf5a
4aaf5a
944265 //¤ ___________________________________________________
79465d //
ba344a // ·Key manager notification processing procedure
b0af5a
5db997 PGPError PGPkmExport·
1ac809 PGPkmDefaultNotificationProc (
562b66 ¤   ¤   HKEYMAN hKM,·
bdc0b8 ¤   ¤   LPARAM¤ lParam)·
75bb36 {
5af021 ¤   PKEYMAN¤¤   ¤   pKM¤¤   ¤   = (PKEYMAN)hKM;
3c48cb ¤   LPNM_TREELIST¤  lpntl¤  ¤   = (LPNM_TREELIST)lParam;
2caf5a
595f28 ¤   HTLITEM¤¤   ¤   hFocused;
9261ed ¤   BOOL¤   ¤   ¤   bMultiple;
30ac06 ¤   INT¤¤   ¤   ¤   i, iField;
6eaf5a
--6485 00089511772401102b0 Page 2 of KMNotPrc.c
f9ef62 ¤   if (!hKM) return kPGPError_BadParams;
b6af5a
ef5284 ¤   switch (lpntl->hdr.code) {
0eaf5a
5e39a9 ¤   case TLN_SELCHANGED :
34f4ca ¤   ¤   if (pKM->ulOptionFlags & KMF_ONLYSELECTKEYS) {
7262af ¤   ¤   ¤   TL_TREEITEM tli;
a1220f ¤   ¤   ¤   HTLITEM hItem, hInitialItem;
31af5a
e0218a ¤   ¤   ¤   hInitialItem = lpntl->itemNew.hItem;
ab3670 ¤   ¤   ¤   tli.hItem = hInitialItem;
5cf603 ¤   ¤   ¤   do {
299330 ¤   ¤   ¤   ¤   hItem = tli.hItem;
a4ccd5 ¤   ¤   ¤   ¤   tli.mask = TLIF_PARENTHANDLE;
cfeb33 ¤   ¤   ¤   ¤   TreeList_GetItem (pKM->hWndTree, &tli);
63f396 ¤   ¤   ¤   } while (tli.hItem);
42af5a
cef853 ¤   ¤   ¤   if (hItem != hInitialItem) {
66e78b ¤   ¤   ¤   ¤   tli.hItem = hItem;
93d7cd ¤   ¤   ¤   ¤   TreeList_Select (pKM->hWndTree, &tli, TRUE);
f6a3a6 ¤   ¤   ¤   }
a4e543 ¤   ¤   ¤   else {
0ec5ff ¤   ¤   ¤   ¤   bMultiple = lpntl->flags & TLC_MULTIPLE;
057361 ¤   ¤   ¤   ¤   hFocused = lpntl->itemNew.hItem;
715ed4 ¤   ¤   ¤   ¤   KMSetFocus (pKM, hFocused, bMultiple);
0fa3a6 ¤   ¤   ¤   }
b90fe4 ¤   ¤   }
9607e0 ¤   ¤   else {
32aacc ¤   ¤   ¤   bMultiple = lpntl->flags & TLC_MULTIPLE;
1c21fc ¤   ¤   ¤   hFocused = lpntl->itemNew.hItem;
3a4ff3 ¤   ¤   ¤   KMSetFocus (pKM, hFocused, bMultiple);
8b0fe4 ¤   ¤   }
30d4f5 ¤   ¤   lpntl->flags = KMSelectedFlags (pKM);
db2f68 ¤   ¤   break;
26af5a
266626 ¤   case TLN_KEYDOWN :
8d71ee ¤   ¤   switch (((TL_KEYDOWN*)lParam)->wVKey) {
4fbbad ¤   ¤   case VK_DELETE :
39df25 ¤   ¤   ¤   KMDeleteObject (pKM);
d3cdcb ¤   ¤   ¤   break;
3d0fe4 ¤   ¤   }
552f68 ¤   ¤   break;
c5af5a
f2206f ¤   case TLN_CONTEXTMENU :
2bd4f5 ¤   ¤   lpntl->flags = KMSelectedFlags (pKM);
912f68 ¤   ¤   break;
f4af5a
66a0b9 ¤   case TLN_BEGINDRAG :
34e776 ¤   ¤   if (pKM->ulOptionFlags & KMF_ENABLEDRAGOUT) {
86ec3f ¤   ¤   ¤   KMEnableDropTarget (pKM->pDropTarget, FALSE);
d60ba9 ¤   ¤   ¤   KMDragAndDrop (pKM);
d78df8 ¤   ¤   ¤   KMEnableDropTarget (pKM->pDropTarget,·
37e8f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   !(pKM->ulOptionFlags & KMF_READONLY) &&
ca07b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pKM->ulOptionFlags & KMF_ENABLEDROPIN));
680fe4 ¤   ¤   }
af2f68 ¤   ¤   break;
11af5a
d44a71 ¤   case TLN_LISTITEMCLICKED :·
068e6d ¤   ¤   if (PGPkmIsActionEnabled (hKM, KM_CERTIFY))
0d5e16 ¤   ¤   ¤   KMCertifyKeyOrUserID (pKM);
922f68 ¤   ¤   break;
43af5a
1825e3 ¤   case TLN_HEADERREORDERED :
ac34dc ¤   ¤   sReorderColumns (pKM);
1d2f68 ¤   ¤   break;
c4af5a
3cccac ¤   case TLN_HEADERCLICKED :
75e2c1 ¤   ¤   i = pKM->lKeyListSortField;
4642b6 ¤   ¤   iField = pKM->wColumnField[lpntl->index];
f5f657 ¤   ¤   switch (iField) {
eea3de ¤   ¤   ¤   case KMI_NAME :·
89a635 ¤   ¤   ¤   ¤   if (pKM->lKeyListSortField == kPGPUserIDOrdering)
--1d29 001be8c9d9c401102b0 Page 3 of KMNotPrc.c
5483f2 ¤   ¤   ¤   ¤   ¤   i = kPGPReverseUserIDOrdering;·
645109 ¤   ¤   ¤   ¤   else·
549c32 ¤   ¤   ¤   ¤   ¤   i = kPGPUserIDOrdering;·
0bf622 ¤   ¤   ¤   ¤   break;
e1af5a
91823e ¤   ¤   ¤   case KMI_VALIDITY :
99cb09 ¤   ¤   ¤   ¤   if (pKM->lKeyListSortField == kPGPValidityOrdering)
07c38a ¤   ¤   ¤   ¤   ¤   i = kPGPReverseValidityOrdering;
7afa07 ¤   ¤   ¤   ¤   else
590599 ¤   ¤   ¤   ¤   ¤   i = kPGPValidityOrdering;
05f622 ¤   ¤   ¤   ¤   break;
6daf5a
81cd10 ¤   ¤   ¤   case KMI_TRUST :
ba8243 ¤   ¤   ¤   ¤   if (pKM->lKeyListSortField == kPGPTrustOrdering)
5ac9fb ¤   ¤   ¤   ¤   ¤   i = kPGPReverseTrustOrdering;·
88fa07 ¤   ¤   ¤   ¤   else
7af014 ¤   ¤   ¤   ¤   ¤   i = kPGPTrustOrdering;·
42f622 ¤   ¤   ¤   ¤   break;
91af5a
826d8b ¤   ¤   ¤   case KMI_CREATION :·
271636 ¤   ¤   ¤   ¤   if (pKM->lKeyListSortField == kPGPCreationOrdering)
13c774 ¤   ¤   ¤   ¤   ¤   i = kPGPReverseCreationOrdering;·
bcfa07 ¤   ¤   ¤   ¤   else
6be5a8 ¤   ¤   ¤   ¤   ¤   i = kPGPCreationOrdering;·
08f622 ¤   ¤   ¤   ¤   break;
d4af5a
b7183a ¤   ¤   ¤   case KMI_EXPIRATION :·
477038 ¤   ¤   ¤   ¤   if (pKM->lKeyListSortField == kPGPExpirationOrdering)
6e275a ¤   ¤   ¤   ¤   ¤   i = kPGPReverseExpirationOrdering;·
4afa07 ¤   ¤   ¤   ¤   else
f0d3d1 ¤   ¤   ¤   ¤   ¤   i = kPGPExpirationOrdering;·
3bf622 ¤   ¤   ¤   ¤   break;
32af5a
f6c2f6 ¤   ¤   ¤   case KMI_SIZE :·
bd53f9 ¤   ¤   ¤   ¤   if (pKM->lKeyListSortField == kPGPEncryptKeySizeOrdering)
f6f630 ¤   ¤   ¤   ¤   ¤   i = kPGPReverseEncryptKeySizeOrdering;
fefa07 ¤   ¤   ¤   ¤   else
0d1617 ¤   ¤   ¤   ¤   ¤   i = kPGPEncryptKeySizeOrdering;·
fef622 ¤   ¤   ¤   ¤   break;
d0af5a
fff5ae ¤   ¤   ¤   case KMI_KEYID :·
12b96e ¤   ¤   ¤   ¤   if (pKM->lKeyListSortField == kPGPKeyIDOrdering)
08da76 ¤   ¤   ¤   ¤   ¤   i = kPGPReverseKeyIDOrdering;
cafa07 ¤   ¤   ¤   ¤   else
520ac8 ¤   ¤   ¤   ¤   ¤   i = kPGPKeyIDOrdering;·
83f622 ¤   ¤   ¤   ¤   break;
e0af5a
d5acef ¤   ¤   ¤   default : break;
3e0fe4 ¤   ¤   }
1dd1c4 ¤   ¤   if (i != pKM->lKeyListSortField) {
ea1a18 ¤   ¤   ¤   pKM->lKeyListSortField = i;
14ba44 ¤   ¤   ¤   TreeList_DeleteTree (pKM->hWndTree, FALSE);
2875b3 ¤   ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
3e3ebf ¤   ¤   ¤   UpdateWindow (pKM->hWndTree);
27c795 ¤   ¤   ¤   KMLoadKeyRingIntoTree (pKM, TRUE, FALSE, FALSE);
6b75b3 ¤   ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
230fe4 ¤   ¤   }
f62f68 ¤   ¤   break;
699371 ¤   }
4a3e6b ¤   return 0;
87efe6 }
beaf5a
--9100 00081c7d619401102b1 Page 1 of KMPhoto.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
9550e1 ¤   KMPhoto.c - photoID routines
f967c5 ¤
33af5a
e50fe4 ¤   $Id: KMPhoto.c,v 1.16 1998/08/11 14:43:35 pbj Exp $
3cf7f7 ____________________________________________________________________________*/
89e610 #include "pgpPFLConfig.h"
cfaf5a
7ec917 // project header files
b4850a #include "pgpkmx.h"
62af5a
4dad8c // pgp header files
6b08c5 #include "pgpJPEG.h"
f7d379 #include "pgpClientShared.h"
4a3d4b #include "pgpEndianConversion.h"
57af5a
403fb5 // external global variables
519cad extern HINSTANCE g_hInst;
e7af5a
265584 // constant definitions
aa3868 #define DISPLAY_WIDTH¤  ¤   120
1088cd #define MAX_FILE_WIDTH¤ ¤   1000
7563d3 #define MAX_FILE_HEIGHT¤¤   1200
bc485c #define MAX_PHOTO_WIDTH¤¤   120
01a42a #define MAX_PHOTO_HEIGHT¤   144
0faf5a
d526eb // error handler struct for JPEG library
6f1cb3 struct my_error_mgr {
9e0c31 ¤   struct jpeg_error_mgr pub;¤
ee74c7 ¤   jmp_buf setjmp_buffer;
7982f7 };
3caf5a
84fd15 typedef struct my_error_mgr * my_error_ptr;
caaf5a
3e4265 //¤ ___________________________________________________
2f465d //
f61903 //¤ extract size information from DIB
2aaf5a
7be274 INT
06dca4 KMGetDIBSize (LPBITMAPINFO lpbi, INT* piWidth, INT* piHeight)
b6bb36 {
5d1824 ¤   INT¤iRowSize;
5fce07 ¤   INT¤iDIBSize;
e4af5a
210969 ¤   // return image dimensions
10ad83 ¤   if (piWidth)
aedf38 ¤   ¤   *piWidth = lpbi->bmiHeader.biWidth;
83aba0 ¤   if (piHeight)
067422 ¤   ¤   *piHeight = lpbi->bmiHeader.biHeight;
e8af5a
5e43bd ¤   // rows length must be a multiple of sizeof(LONG)
a0ea0c ¤   iRowSize = (lpbi->bmiHeader.biWidth * lpbi->bmiHeader.biBitCount) >>3;
acd0dc ¤   iRowSize = ((iRowSize+3)>>2)<<2;
ecaf5a
0f29ac ¤   // calculate image size by multiplying row length by number of rows
e8d769 ¤   // and adding in header and color table sizes
64422f ¤   iDIBSize = lpbi->bmiHeader.biSize;
596eaf ¤   iDIBSize += lpbi->bmiHeader.biClrUsed * sizeof(RGBQUAD);
e49adf ¤   iDIBSize += iRowSize * lpbi->bmiHeader.biHeight;
2caf5a
6d76a8 ¤   return iDIBSize;
98efe6 }
93d83c ·
4b4265 //¤ ___________________________________________________
69465d //
37e5f7 //¤ create logical palette from bitmap color table
acaf5a
a3597e static HPALETTE·
8176ce sPaletteFromDIB (
--13ed 000efb1bbf1401102b1 Page 2 of KMPhoto.c
3a4159 ¤   ¤   ··LPBITMAPINFO¤ lpbmi,·
7fef12 ¤   ¤   ··INT*¤ ¤   ¤   piNumColors)·
76bb36 {
a11fa8 ¤   HPALETTE¤   ¤   ¤   hPal¤   = NULL;
3ab04a ¤   LPBITMAPINFOHEADER¤ lpbi;
daa52a ¤   LPLOGPALETTE¤   ¤   lpPal;
80795c ¤   HANDLE¤ ¤   ¤   ¤   hLogPal;
22b236 ¤   INT¤¤   ¤   ¤   ¤   i;
e4d83c ·
b47407 ¤   lpbi = (LPBITMAPINFOHEADER)lpbmi;
efaf5a
8aaa10 ¤   // palettes are only used on images with 8 bits/pixel or less
4ab16a ¤   switch (lpbi->biBitCount) {
9368a5 ¤   case 1 :
c31699 ¤   ¤   *piNumColors = 2;
322f68 ¤   ¤   break;
8aaf5a
c406f2 ¤   case 4 :
84d3cc ¤   ¤   *piNumColors = 16;
892f68 ¤   ¤   break;
69af5a
bd91c6 ¤   case 8 :
8c8e6e ¤   ¤   if (lpbi->biClrUsed)·
9a2353 ¤   ¤   ¤   *piNumColors = lpbi->biClrUsed;
3eee26 ¤   ¤   else·
4c66b3 ¤   ¤   ¤   *piNumColors = 256;
832f68 ¤   ¤   break;
0baf5a
6fbfad ¤   default :
a6a321 ¤   ¤   *piNumColors = 0;
952f68 ¤   ¤   break;
c49371 ¤   }
73d83c ·
6c143a ¤   // if a palette is indicated, extract it from bitmap color table
b7efc6 ¤   if (*piNumColors) {
750012 ¤   ¤   hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
a33c65 ·····························sizeof (PALETTEENTRY) * (*piNumColors));
8cd92a ¤   ¤   lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
815442 ¤   ¤   lpPal->palVersion = 0x300;
bfdc20 ¤   ¤   lpPal->palNumEntries = *piNumColors;
b0d83c ·
6435a6 ¤   ¤   for (i=0; i<*piNumColors; i++) {
e4d118 ¤   ¤   ¤   lpPal->palPalEntry[i].peRed ··= lpbmi->bmiColors[i].rgbRed;
11dc94 ¤   ¤   ¤   lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
571adf ¤   ¤   ¤   lpPal->palPalEntry[i].peBlue ·= lpbmi->bmiColors[i].rgbBlue;
0e089b ¤   ¤   ¤   lpPal->palPalEntry[i].peFlags = 0;
5b0fe4 ¤   ¤   }
db898e ¤   ¤   hPal = CreatePalette (lpPal);
f793f7 ¤   ¤   GlobalUnlock (hLogPal);
78b50d ¤   ¤   GlobalFree (hLogPal);
169371 ¤   }
78af5a
188370 ¤   return hPal;
ddefe6 }
77d83c ·
3d4265 //¤ ___________________________________________________
67465d //
b65f78 //¤ derive DDB and palette from DIB·
67af5a
c77a1f HBITMAP
5a160c KMDDBfromDIB (
9479cf ¤   ¤   LPBITMAPINFO¤   lpbi,·
7565d6 ¤   ¤   HPALETTE*¤  ¤   lphPalette)
cabb36 {
5e6606 ¤   HBITMAP¤¤   hBitmapFinal = NULL;
c194c0 ¤   HDC¤¤   ¤   hdc;
cd844e ····INT¤¤   ¤   iNumColors;
07a413 ¤   LPVOID¤ ¤   lpPixels;
30d83c ·
75dece ¤   hdc = GetDC (NULL);
89af5a
ef5e79 ¤   *lphPalette = NULL;
--d644 000a11288d1401102b1 Page 3 of KMPhoto.c
771045 ¤   iNumColors = 0;
6caf5a
9673c2 ¤   if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE)·
6bd286 ¤   ¤   *lphPalette = sPaletteFromDIB ((LPBITMAPINFO)lpbi, &iNumColors);
bbaf5a
dc2be5 ¤   if (*lphPalette) {
040380 ¤   ¤   SelectPalette (hdc, *lphPalette, FALSE);
f24734 ¤   ¤   RealizePalette (hdc);
2c9371 ¤   }
37d83c ·
b1fa95 ¤   lpPixels = (LPBYTE)lpbi +·
db77b4 ¤   ¤   ¤   ¤   lpbi->bmiHeader.biSize +
ee7c4c ¤   ¤   ¤   ¤   (iNumColors * sizeof(RGBQUAD));
35af5a
00adfb ¤   hBitmapFinal = CreateDIBitmap (hdc,
5b4331 ···················&(lpbi->bmiHeader),
3e7702 ···················CBM_INIT,
ed00a2 ···················lpPixels,
dc0baf ···················lpbi,
bb91db ···················DIB_RGB_COLORS);
d3d83c ·
6d0951 ¤   ReleaseDC (NULL, hdc);
a0af5a
d7aa7e ¤   return (hBitmapFinal);
84efe6 }
09af5a
164265 //¤ ___________________________________________________
97465d //
745c39 //¤ error handler routine for JPEG library
55465d //
45ad9b //¤ converts error code to string and displays it in MessageBox
b9af5a
9a0434 METHODDEF(void)
a66096 my_error_exit (j_common_ptr cinfo)
5cbb36 {
6fa728 //¤ CHAR szError [JMSG_LENGTH_MAX];
b7af5a
044108 ¤   my_error_ptr myerr = (my_error_ptr) cinfo->err;
c5af5a
6e1e92 //¤ (*cinfo->err->format_message) (cinfo, szError);
8ccbfb //¤ MessageBox (NULL, szError, "JPEG Library Error", MB_OK);
03465d //
05a8bd ¤   longjmp(myerr->setjmp_buffer, 1);
40efe6 }
afaf5a
a64265 //¤ ___________________________________________________
a0465d //
32a908 //¤ convert DIB to JPEG buffer
e2af5a
45f1ae static PGPError
e6b684 sJPEGFromDIB (
2eeee1 ¤   ¤   LPBITMAPINFO¤   lpbmi,·
2380d3 ¤   ¤   INT¤¤   ¤   ¤   iQuality,
c5fad2 ¤   ¤   INT¤¤   ¤   ¤   iMaxWidth,
fbaffe ¤   ¤   INT¤¤   ¤   ¤   iMaxHeight,
e57901 ¤   ¤   BOOL¤   ¤   ¤   bShrink,
a471a4 ¤   ¤   LPBYTE*¤¤   ¤   pbuf,·
091425 ¤   ¤   INT*¤   ¤   ¤   piLength)
aebb36 {
d71398 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
f6af5a
e6449a ¤   INT¤¤   ¤   iColorTableLength;
508969 ¤   INT¤¤   ¤   iRowOrigLen, iRowJPEGLen, iRowDIBLen, iDIBsize;
a649ae ¤   INT¤¤   ¤   i, j, index;
2ffea7 ¤   INT¤¤   ¤   iWidth, iHeight, iZoom;
eb8d3d ¤   INT¤¤   ¤   idxX, idxY;
504ee1 ¤   struct¤ ¤   my_error_mgr jerr;
5c3121 ¤   struct¤ ¤   jpeg_compress_struct cinfo;
00447b ¤   FILE*¤  ¤   outfile;
a91504 ¤   LPBYTE¤ ¤   pDIB;
22aec3 ¤   LPBYTE¤ ¤   pRGBorig;
a13bf8 ¤   LPBYTE¤ ¤   pRGBjpeg;
--34fc 0001c873b6a401102b1 Page 4 of KMPhoto.c
07392b ¤   JSAMPROW¤   pSampRow[1];¤
3d35d0 ¤   double¤ ¤   fZoom, fImageRatio, fMaxRatio, fTemp;
daaf5a
cb47e4 ¤   // do we really need to shrink image ?
5605d7 ¤   fZoom = 1.0;
3bc1ad ¤   iZoom = 1000;
9bf375 ¤   iWidth = lpbmi->bmiHeader.biWidth;
e70441 ¤   iHeight = lpbmi->bmiHeader.biHeight;
3aaf5a
b0bc77 ¤   if (bShrink) {
b36011 ¤   ¤   if ((lpbmi->bmiHeader.biWidth > iMaxWidth) ||
2bef94 ¤   ¤   ¤   (lpbmi->bmiHeader.biHeight > iMaxHeight)) {
b6af5a
5272a4 ¤   ¤   ¤   fImageRatio = (double)lpbmi->bmiHeader.biWidth /
5d23a1 ¤   ¤   ¤   ¤   ¤   ¤   ··(double)lpbmi->bmiHeader.biHeight;
500e1d ¤   ¤   ¤   fMaxRatio ··= (double)iMaxWidth / (double)iMaxHeight;
8caf5a
4f5eb0 ¤   ¤   ¤   if (fImageRatio >= fMaxRatio) {
4710c1 ¤   ¤   ¤   ¤   fZoom = (double)iMaxWidth /·
fcd8e9 ¤   ¤   ¤   ¤   ¤   ¤   (double)lpbmi->bmiHeader.biWidth;
8f7f44 ¤   ¤   ¤   ¤   fTemp = (1000.0 / fZoom);
c5af5a
3c462d ¤   ¤   ¤   ¤   iWidth = iMaxWidth;
60b91e ¤   ¤   ¤   ¤   iHeight = (INT)(lpbmi->bmiHeader.biHeight * fZoom);
a0af5a
467560 ¤   ¤   ¤   ¤   iZoom = (INT)fTemp;
72a3a6 ¤   ¤   ¤   }
59e543 ¤   ¤   ¤   else {
83cf32 ¤   ¤   ¤   ¤   fZoom = (double)iMaxHeight /·
0ff185 ¤   ¤   ¤   ¤   ¤   ¤   (double)lpbmi->bmiHeader.biHeight;
637f44 ¤   ¤   ¤   ¤   fTemp = (1000.0 / fZoom);
04af5a
134297 ¤   ¤   ¤   ¤   iHeight = iMaxHeight;
884d0b ¤   ¤   ¤   ¤   iWidth = (INT)(lpbmi->bmiHeader.biWidth * fZoom);
c2af5a
777560 ¤   ¤   ¤   ¤   iZoom = (INT)fTemp;
10a3a6 ¤   ¤   ¤   }
4f0fe4 ¤   ¤   }
6e9371 ¤   }
6caf5a
6e218e ¤   // calculate length of row of image in bytes (3 color channels)
ecca63 ¤   iRowOrigLen = lpbmi->bmiHeader.biWidth * 3;
c4cd08 ¤   iRowJPEGLen = (iWidth+1) * 3;¤
c3af5a
0d3b00 ¤   // calculate length of row of image in DIB structure
31b0a6 ¤   iRowDIBLen = (lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biBitCount) >>3;
868d95 ¤   iRowDIBLen = ((iRowDIBLen+3)>>2)<<2;
abaf5a
1bec24 ¤   // allocate buffer used for passing rows of RGB data into library
8d2dee ¤   pRGBorig = KMAlloc (iRowOrigLen);
dafc6d ¤   if (pRGBorig == NULL)·
b34030 ¤   ¤   return kPGPError_OutOfMemory;
2caf5a
e80a16 ¤   pRGBjpeg = KMAlloc (iRowJPEGLen);
c15af6 ¤   if (pRGBjpeg == NULL)·
294030 ¤   ¤   return kPGPError_OutOfMemory;
d3af5a
dfbd21 ¤   // calculate size of DIB structure
9e4233 ¤   iColorTableLength = lpbmi->bmiHeader.biClrUsed;
d34279 ¤   if (iColorTableLength == 0) {
9548d9 ¤   ¤   switch (lpbmi->bmiHeader.biBitCount) {
b3dd34 ¤   ¤   case 1 :
975b60 ¤   ¤   ¤   iColorTableLength = 2;
2dcdcb ¤   ¤   ¤   break;
70b363 ¤   ¤   case 4 :
e6b9cf ¤   ¤   ¤   iColorTableLength = 16;
97cdcb ¤   ¤   ¤   break;
032457 ¤   ¤   case 8 :
58f91c ¤   ¤   ¤   iColorTableLength = 256;
43cdcb ¤   ¤   ¤   break;
5e3a18 ¤   ¤   default :
1ceed8 ¤   ¤   ¤   iColorTableLength = 0;
--806f 000e578dace401102b1 Page 5 of KMPhoto.c
7ecdcb ¤   ¤   ¤   break;
690fe4 ¤   ¤   }
209371 ¤   }
f1de11 ¤   iDIBsize = sizeof(BITMAPINFOHEADER);
c27e0b ¤   iDIBsize += (iColorTableLength * sizeof (RGBQUAD));
2f8ee2 ¤   iDIBsize += (iRowDIBLen * lpbmi->bmiHeader.biHeight);
b6af5a
386a56 ¤   // initialize pointer to last row of DIB (DIB is stored bottom-up)
3df755 ¤   pDIB = (LPBYTE)lpbmi;
6988d9 ¤   pDIB += iDIBsize;
d1a73e ¤   pDIB -= iRowDIBLen;
7baf5a
358340 ¤   // JPEG library will write to temporary file
42e7b3 ¤   outfile = tmpfile ();
f8af5a
d652ba ¤   // setup error handler for JPEG library
afa0a8 ¤   cinfo.err = jpeg_std_error (&jerr.pub);
1c2a74 ¤   jerr.pub.error_exit = my_error_exit;
eafd01 ¤   if (setjmp(jerr.setjmp_buffer)) {
c73d41 ¤   ¤   // will be here only on error in library
4cf3a9 ¤   ¤   jpeg_destroy_compress (&cinfo);
5b449e ¤   ¤   fclose (outfile);
ddf14c ¤   ¤   _rmtmp ();
de2379 ¤   ¤   return kPGPError_Win32_InvalidImage;
789371 ¤   }
a4af5a
16b0b3 ¤   // initialize compression structure
30f399 ¤   jpeg_create_compress (&cinfo);
32af5a
5e8fb5 ¤   // specify destination of JPEG stream
1be830 ¤   jpeg_stdio_dest (&cinfo, outfile);
06af5a
153dd3 ¤   // specify image characteristics
084053 ¤   cinfo.image_width = iWidth;
319de1 ¤   cinfo.image_height = iHeight;
e264f1 ¤   cinfo.input_components = 3;¤
51833e ¤   cinfo.in_color_space = JCS_RGB;
3f9df7 ¤   jpeg_set_defaults (&cinfo);
fcaf5a
299370 ¤   // specify quality of compressed image
5d0c90 ¤   jpeg_set_quality (&cinfo, iQuality, TRUE);
b0af5a
50255f ¤   // startup compression
d2c89b ¤   jpeg_start_compress (&cinfo, TRUE);
17af5a
229d47 ¤   pSampRow[0] = pRGBjpeg;
2c7566 ¤   idxY = 0;
a947b6 ¤   while (cinfo.next_scanline < cinfo.image_height) {
0eaf5a
a1b4d1 ¤   ¤   // fill buffer of data on basis of number of bits/pixel
2248d9 ¤   ¤   switch (lpbmi->bmiHeader.biBitCount) {
a9dd34 ¤   ¤   case 1 :
2dea8b ¤   ¤   ¤   // B/W image
2b8d54 ¤   ¤   ¤   for (j=i=0; i<iRowOrigLen; i+=3) {
482527 ¤   ¤   ¤   ¤   index = pDIB [j>>3];
206990 ¤   ¤   ¤   ¤   index = (index >> (7 - (j&0x07))) & 0x01;
35ddab ¤   ¤   ¤   ¤   j++;
85af5a
6591f3 ¤   ¤   ¤   ¤   pRGBorig[i+0] = lpbmi->bmiColors[index].rgbRed;
a869e9 ¤   ¤   ¤   ¤   pRGBorig[i+1] = lpbmi->bmiColors[index].rgbGreen;
e4c712 ¤   ¤   ¤   ¤   pRGBorig[i+2] = lpbmi->bmiColors[index].rgbBlue;
d2a3a6 ¤   ¤   ¤   }
c9cdcb ¤   ¤   ¤   break;
acaf5a
45b363 ¤   ¤   case 4 :
586438 ¤   ¤   ¤   // 16 color image, derive RGB values from color table
288d54 ¤   ¤   ¤   for (j=i=0; i<iRowOrigLen; i+=3) {
185419 ¤   ¤   ¤   ¤   if (j & 0x1)·
3fd748 ¤   ¤   ¤   ¤   ¤   index = pDIB [j>>1] & 0x0F;
f55109 ¤   ¤   ¤   ¤   else·
1f25e4 ¤   ¤   ¤   ¤   ¤   index = pDIB [j>>1] >> 4;
e5ddab ¤   ¤   ¤   ¤   j++;
--aaed 00035831c49401102b1 Page 6 of KMPhoto.c
e0af5a
4a91f3 ¤   ¤   ¤   ¤   pRGBorig[i+0] = lpbmi->bmiColors[index].rgbRed;
5469e9 ¤   ¤   ¤   ¤   pRGBorig[i+1] = lpbmi->bmiColors[index].rgbGreen;
cec712 ¤   ¤   ¤   ¤   pRGBorig[i+2] = lpbmi->bmiColors[index].rgbBlue;
d8a3a6 ¤   ¤   ¤   }
d2cdcb ¤   ¤   ¤   break;
b4af5a
e72457 ¤   ¤   case 8 :
7ddccb ¤   ¤   ¤   // 256 color image, derive RGB values from color table
748d54 ¤   ¤   ¤   for (j=i=0; i<iRowOrigLen; i+=3) {
418718 ¤   ¤   ¤   ¤   index = pDIB[j++];
7891f3 ¤   ¤   ¤   ¤   pRGBorig[i+0] = lpbmi->bmiColors[index].rgbRed;
4e69e9 ¤   ¤   ¤   ¤   pRGBorig[i+1] = lpbmi->bmiColors[index].rgbGreen;
6fc712 ¤   ¤   ¤   ¤   pRGBorig[i+2] = lpbmi->bmiColors[index].rgbBlue;
47a3a6 ¤   ¤   ¤   }
73cdcb ¤   ¤   ¤   break;
bdaf5a
9034ec ¤   ¤   case 24 :
a6cf98 ¤   ¤   ¤   // RGB image, but DIB stores it as BGR, so invert
ab6ff9 ¤   ¤   ¤   for (i=0; i<iRowOrigLen; i+=3) {
59b3b0 ¤   ¤   ¤   ¤   pRGBorig[i+0] = pDIB[i+2];
8b186d ¤   ¤   ¤   ¤   pRGBorig[i+1] = pDIB[i+1];
6c9ef7 ¤   ¤   ¤   ¤   pRGBorig[i+2] = pDIB[i+0];
81a3a6 ¤   ¤   ¤   }
ddcdcb ¤   ¤   ¤   break;
f7af5a
b67432 ¤   ¤   case 32 :
326e79 ¤   ¤   ¤   // RGB image, but in DIB it's 0BGR, so invert and discard byte
60b672 ¤   ¤   ¤   for (i=j=0; i<iRowOrigLen; i+=3) {
41a376 ¤   ¤   ¤   ¤   pRGBorig[i+0] = pDIB[j+3];
a631dd ¤   ¤   ¤   ¤   pRGBorig[i+1] = pDIB[j+2];
808e31 ¤   ¤   ¤   ¤   pRGBorig[i+2] = pDIB[j+1];
85cf4a ¤   ¤   ¤   ¤   j += 4;
7fa3a6 ¤   ¤   ¤   }
62cdcb ¤   ¤   ¤   break;
440fe4 ¤   ¤   }
45af5a
5bebdb ¤   ¤   // subsample the row of data
586f06 ¤   ¤   idxX = 0;
513f70 ¤   ¤   for (i=j=0; j<iRowOrigLen; j+=3) {
e7ee26 ¤   ¤   ¤   idxX -= 1000;
95e901 ¤   ¤   ¤   while (idxX < 0) {
2d33ef ¤   ¤   ¤   ¤   pRGBjpeg[i+0] = pRGBorig[j+0];
b4f002 ¤   ¤   ¤   ¤   pRGBjpeg[i+1] = pRGBorig[j+1];
63bc24 ¤   ¤   ¤   ¤   pRGBjpeg[i+2] = pRGBorig[j+2];
29af5a
98c99f ¤   ¤   ¤   ¤   i += 3;
4a97d7 ¤   ¤   ¤   ¤   idxX += iZoom;
51a3a6 ¤   ¤   ¤   }
f70fe4 ¤   ¤   }
5eaf5a
e6f015 ¤   ¤   // pass the RGB data into the library
653a24 ¤   ¤   (void) jpeg_write_scanlines (&cinfo, pSampRow, 1);
24af5a
48a141 ¤   ¤   // step to previous DIB scan line
ace44b ¤   ¤   idxY += iZoom;
99876f ¤   ¤   while (idxY > 0) {
6dfc05 ¤   ¤   ¤   pDIB -= iRowDIBLen;
dfbbb7 ¤   ¤   ¤   idxY -= 1000;
7e0fe4 ¤   ¤   }
499371 ¤   }
69af5a
83ce4b ¤   // done with image
572d90 ¤   jpeg_finish_compress (&cinfo);
b336fc ¤   jpeg_destroy_compress (&cinfo);
43507a ¤   KMFree (pRGBorig);
87dfbf ¤   KMFree (pRGBjpeg);
b4af5a
d4d934 ¤   // now extract JPEG data from file -- first calculate buffer length
dbf620 ¤   fseek (outfile, 0, SEEK_END);
369b65 ¤   *piLength = ftell (outfile);
35af5a
--55d6 000b6fad8dc401102b1 Page 7 of KMPhoto.c
d11cec ¤   // allocate buffer
c84085 ¤   *pbuf = KMAlloc (*piLength);
4eaf5a
1e0a49 ¤   // read data from file into buffer
79bee8 ¤   if (*pbuf != NULL) {
3c4b56 ¤   ¤   rewind (outfile);
193f08 ¤   ¤   fread (*pbuf, 1, *piLength, outfile);·
059371 ¤   }
d6af5a
0047bf ¤   // memory allocation error
a64264 ¤   else·
4bbce1 ¤   ¤   err = kPGPError_OutOfMemory;
62af5a
92832b ¤   fclose (outfile);
e613ef ¤   _rmtmp ();
17af5a
9f5ea8 ¤   return err;
99efe6 }
f4af5a
c4af5a
094265 //¤ ___________________________________________________
92465d //
35dccc //¤ convert DIB to PhotoID buffer
7eaf5a
02f1ae static PGPError
2ca2a4 sPhotoFromDIB (
6ceee1 ¤   ¤   LPBITMAPINFO¤   lpbmi,·
e0fad2 ¤   ¤   INT¤¤   ¤   ¤   iMaxWidth,
22affe ¤   ¤   INT¤¤   ¤   ¤   iMaxHeight,
327901 ¤   ¤   BOOL¤   ¤   ¤   bShrink,
8471a4 ¤   ¤   LPBYTE*¤¤   ¤   pbuf,·
621425 ¤   ¤   INT*¤   ¤   ¤   piLength)
25bb36 {
e5ba49 ¤   PGPError¤   ¤   ¤   ¤   err;
b0a22e ¤   LPBYTE¤ ¤   ¤   ¤   ¤   pJPEGbuf;
9999cd ¤   INT¤¤   ¤   ¤   ¤   ¤   iJPEGlen;
dcf35c ¤   PGPPhotoUserIDHeader*¤  pheader;
e965e8 ¤   LPBYTE¤ ¤   ¤   ¤   ¤   pdata;
49c4e7 ¤   PGPUInt16¤  ¤   ¤   ¤   usHeaderLength;
b867c5 ¤
55197d ¤   // currently we only support JPEG photoids
0df3be ¤   err = sJPEGFromDIB (lpbmi, kPGPDefaultJPEQQuality,·
2a3f62 ¤   ¤   iMaxWidth, iMaxHeight, bShrink, &pJPEGbuf, &iJPEGlen);
7eaf5a
3db23e ¤   if (IsntPGPError (err)) {
9c7773 ¤   ¤   *piLength = iJPEGlen + sizeof(PGPPhotoUserIDHeader);
8c7ded ¤   ¤   *pbuf = KMAlloc (*piLength);
89af5a
ccdbfb ¤   ¤   if (*pbuf) {
fc0b4d ¤   ¤   ¤   pheader = (PGPPhotoUserIDHeader*)*pbuf;
fdaf8d ¤   ¤   ¤   usHeaderLength = sizeof(PGPPhotoUserIDHeader);
e24eca ¤   ¤   ¤   PGPUInt16ToStorage (usHeaderLength,·
da4d25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPByte*)&(pheader->headerLength));
8c0167 ¤   ¤   ¤   pheader->headerVersion ¤= kPGPPhotoIDHeaderVersion;
8d4e5c ¤   ¤   ¤   pheader->photoIDFormat¤ = kPGPPhotoIDFormat_JPEG;
7baf5a
7b042c ¤   ¤   ¤   pdata = *pbuf + usHeaderLength;
87af5a
2fa9e9 ¤   ¤   ¤   memcpy (pdata, pJPEGbuf, iJPEGlen);
390fe4 ¤   ¤   }
ca07e0 ¤   ¤   else {
37bcfd ¤   ¤   ¤   *piLength = 0;
05b90c ¤   ¤   ¤   err = kPGPError_OutOfMemory;
f00fe4 ¤   ¤   }
7baf5a
699371 ¤   }
afaf5a
fc5ea8 ¤   return err;
2eefe6 }
37af5a
5e4265 //¤ ___________________________________________________
b6465d //
--2add 00086d199f5401102b1 Page 8 of KMPhoto.c
ee345c //¤ convert JPEG buffer to DIB·
c5af5a
3596c1 static LPBITMAPINFO
44169f sDIBfromJPEGFile (
4f4bbb ¤   ¤   FILE*¤  infile,·
f22e59 ¤   ¤   BOOL¤   bForDisplay)
63bb36 {
d5f2cc ¤   LPBITMAPINFO¤   lpbmi¤  = NULL;
c3af5a
50d3e9 ¤   INT¤¤   ¤   ¤   i, iNumBits, iDIBsize;
8b12b5 ¤   INT¤¤   ¤   ¤   iRowDataLen, iRowDIBLen;
d7bfb5 ¤   struct¤ ¤   ¤   my_error_mgr jerr;
875429 ¤   struct¤ ¤   ¤   jpeg_decompress_struct cinfo;
c38bc2 ¤   HDC¤¤   ¤   ¤   hdc;
4cb35b ¤   JSAMPARRAY¤ ¤   buffer;
6a73db ¤   JSAMPROW¤   ¤   pSamp;
c6b320 ¤   LPBYTE¤ ¤   ¤   pDIB;
219639 ¤   BOOL¤   ¤   ¤   bQuantize;
8faf5a
8eaf5a
5cb042 ¤   // get pixel depth supported by the current display device
8edece ¤   hdc = GetDC (NULL);
c38529 ¤   iNumBits = GetDeviceCaps (hdc, BITSPIXEL) * GetDeviceCaps (hdc, PLANES);
280951 ¤   ReleaseDC (NULL, hdc);
79af5a
aa8295 ¤   // quantize colors only if a 256 color display
b55590 ¤   //¤ if more than 256, display is RGB and quantization is not needed
2110de ¤   //¤ if less than 256, quantization does no good as system palette will
bb9253 ¤   //¤ ¤   be used regardless
5dcd0c ¤   if (bForDisplay && (iNumBits == 8)) bQuantize = TRUE;
a0895c ¤   else bQuantize = FALSE;
eeaf5a
8759ee ¤   // prepare error handling structure for JPEG library
dba0a8 ¤   cinfo.err = jpeg_std_error (&jerr.pub);
be2a74 ¤   jerr.pub.error_exit = my_error_exit;
b1fd01 ¤   if (setjmp(jerr.setjmp_buffer)) {
f5d27b ¤   ¤   // here only when JPEG library encounters an error
f69b7e ¤   ¤   jpeg_destroy_decompress (&cinfo);
237ed2 ¤   ¤   return NULL;
8f9371 ¤   }
20af5a
9de43b ¤   // initialize decompression structure
092ddc ¤   jpeg_create_decompress (&cinfo);
5faf5a
2e2caa ¤   // identify source of JPEG data as input file
914b89 ¤   jpeg_stdio_src (&cinfo, infile);
aaaf5a
418dbd ¤   // load header data from file
8256b0 ¤   (void) jpeg_read_header (&cinfo, TRUE);
7aaf5a
471a71 ¤   // set scaling factor for decompression
bb39a7 ¤   if (bForDisplay) {
06443b ¤   ¤   cinfo.scale_num = 1;
79bc86 ¤   ¤   if (cinfo.image_width > 4*DISPLAY_WIDTH)·
95d5c6 ¤   ¤   ¤   cinfo.scale_denom = 8;
e91697 ¤   ¤   else if (cinfo.image_width > 2*DISPLAY_WIDTH)·
b87065 ¤   ¤   ¤   cinfo.scale_denom = 4;
6f17af ¤   ¤   else if (cinfo.image_width > 1*DISPLAY_WIDTH)·
d9a6bc ¤   ¤   ¤   cinfo.scale_denom = 2;
c6ee26 ¤   ¤   else·
af49d8 ¤   ¤   ¤   cinfo.scale_denom = 1;
cc9371 ¤   }
9f665a ¤   else {
8f443b ¤   ¤   cinfo.scale_num = 1;
44c5a7 ¤   ¤   cinfo.scale_denom = 1;
fa9371 ¤   }
91af5a
f0a098 ¤   // set decompression parameters
458f0f ¤   if (bQuantize) {
244f84 ¤   ¤   cinfo.quantize_colors = TRUE;
94c5ff ¤   ¤   cinfo.two_pass_quantize = TRUE;
86f089 ¤   ¤   cinfo.dither_mode = JDITHER_FS;
--6bfb 0008dad9700401102b1 Page 9 of KMPhoto.c
a000c0 ¤   ¤   cinfo.desired_number_of_colors = 128;
df9371 ¤   }
d6665a ¤   else {
c2f320 ¤   ¤   cinfo.quantize_colors = FALSE;
5e9371 ¤   }
8eaf5a
cd29bc ¤   // start decompression
604ae3 ¤   (void) jpeg_start_decompress (&cinfo);
33af5a
b32a45 ¤   // calculate bitmap size parameters and set DIB header info
038f0f ¤   if (bQuantize) {
81f0ba ¤   ¤   iRowDataLen = cinfo.output_width * 1;
319f32 ¤   ¤   iRowDIBLen = ((iRowDataLen+3)>>2)<<2;
92d8a9 ¤   ¤   iDIBsize = sizeof(BITMAPINFOHEADER);
c870a7 ¤   ¤   iDIBsize += (cinfo.actual_number_of_colors * sizeof (RGBQUAD));
f767ae ¤   ¤   iDIBsize += (iRowDIBLen * cinfo.output_height);
faaf5a
929a44 ¤   ¤   lpbmi = KMAlloc (iDIBsize);
36d926 ¤   ¤   lpbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
f157cd ¤   ¤   lpbmi->bmiHeader.biWidth = cinfo.output_width;
db13c8 ¤   ¤   lpbmi->bmiHeader.biHeight = cinfo.output_height;
5874f8 ¤   ¤   lpbmi->bmiHeader.biPlanes = 1;
c48317 ¤   ¤   lpbmi->bmiHeader.biBitCount = 8;
6a92af ¤   ¤   lpbmi->bmiHeader.biCompression = BI_RGB;
0b83ab ¤   ¤   lpbmi->bmiHeader.biSizeImage = iRowDIBLen * cinfo.output_height;
ec96ad ¤   ¤   lpbmi->bmiHeader.biClrUsed = cinfo.actual_number_of_colors;
5f1661 ¤   ¤   lpbmi->bmiHeader.biClrImportant = cinfo.actual_number_of_colors;
3c9371 ¤   }
51665a ¤   else {
df4502 ¤   ¤   iRowDataLen = cinfo.output_width * 3;
f99f32 ¤   ¤   iRowDIBLen = ((iRowDataLen+3)>>2)<<2;
d4d8a9 ¤   ¤   iDIBsize = sizeof(BITMAPINFOHEADER);
aa67ae ¤   ¤   iDIBsize += (iRowDIBLen * cinfo.output_height);
a7af5a
da9a44 ¤   ¤   lpbmi = KMAlloc (iDIBsize);
92d926 ¤   ¤   lpbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
6657cd ¤   ¤   lpbmi->bmiHeader.biWidth = cinfo.output_width;
2f13c8 ¤   ¤   lpbmi->bmiHeader.biHeight = cinfo.output_height;
8b74f8 ¤   ¤   lpbmi->bmiHeader.biPlanes = 1;
3bf2f4 ¤   ¤   lpbmi->bmiHeader.biBitCount = 24;
7892af ¤   ¤   lpbmi->bmiHeader.biCompression = BI_RGB;
d783ab ¤   ¤   lpbmi->bmiHeader.biSizeImage = iRowDIBLen * cinfo.output_height;
183f30 ¤   ¤   lpbmi->bmiHeader.biClrUsed = 0;
488a7e ¤   ¤   lpbmi->bmiHeader.biClrImportant = 0;
f39371 ¤   }
7eaf5a
4b1064 ¤   // have JPEG library allocate buffer for data output
eaebfa ¤   buffer = (*cinfo.mem->alloc_sarray)
2cd7f0 ¤   ¤   ¤   ((j_common_ptr) &cinfo, JPOOL_IMAGE, iRowDataLen, 1);
09af5a
78ddb3 ¤   // put color table into DIB
428f0f ¤   if (bQuantize) {
6fc470 ¤   ¤   pSamp = cinfo.colormap[0];
360ff0 ¤   ¤   for (i = 0; ·i < cinfo.actual_number_of_colors; ·i++)·
061ce3 ¤   ¤   ¤   lpbmi->bmiColors[i].rgbRed = pSamp[i];
aaaf5a
33d8cb ¤   ¤   pSamp = cinfo.colormap[1];
020ff0 ¤   ¤   for (i = 0; ·i < cinfo.actual_number_of_colors; ·i++)·
4eb1b6 ¤   ¤   ¤   lpbmi->bmiColors[i].rgbGreen = pSamp[i];
a4af5a
0bfd06 ¤   ¤   pSamp = cinfo.colormap[2];
390ff0 ¤   ¤   for (i = 0; ·i < cinfo.actual_number_of_colors; ·i++)·
150c61 ¤   ¤   ¤   lpbmi->bmiColors[i].rgbBlue = pSamp[i];
c39371 ¤   }
79af5a
86ced2 ¤   // initialize pointer to last scan row of DIB (DIB is bottom-up)
4ef755 ¤   pDIB = (LPBYTE)lpbmi;
8f88d9 ¤   pDIB += iDIBsize;
41a73e ¤   pDIB -= iRowDIBLen;
94af5a
430bd7 ¤   // decompress the image, one line at a time
8d3567 ¤   while (cinfo.output_scanline < cinfo.output_height) {
--4728 000574f8613401102b1 Page 10 of KMPhoto.c
1a3f8a ¤   ¤   (void) jpeg_read_scanlines (&cinfo, buffer, 1);
e4af5a
6cb266 ¤   ¤   // if quantized, just store the colormap index in the DIB
6f3ede ¤   ¤   if (bQuantize) {
2f8c75 ¤   ¤   ¤   pSamp = buffer[0];
38df48 ¤   ¤   ¤   for (i=0; i<iRowDataLen; i++) {
ec09b8 ¤   ¤   ¤   ¤   pDIB[i] = pSamp[i];
23a3a6 ¤   ¤   ¤   }
870fe4 ¤   ¤   }
e51aa3 ¤   ¤   // otherwise data is RGB, but DIB are in BGR order, so invert
ac07e0 ¤   ¤   else {
0f8c75 ¤   ¤   ¤   pSamp = buffer[0];
a77951 ¤   ¤   ¤   for (i=0; i<iRowDataLen; i+=3) {
27c4e2 ¤   ¤   ¤   ¤   pDIB[i+2] = pSamp[i+0];
e1e848 ¤   ¤   ¤   ¤   pDIB[i+1] = pSamp[i+1];
3ddd8a ¤   ¤   ¤   ¤   pDIB[i+0] = pSamp[i+2];
e0a3a6 ¤   ¤   ¤   }
b10fe4 ¤   ¤   }
a7af5a
fa9f95 ¤   ¤   // step to previous row
f8515b ¤   ¤   pDIB -= iRowDIBLen;
cd9371 ¤   }
9caf5a
110450 ¤   // finished decompressing
c3c537 ¤   jpeg_finish_decompress (&cinfo);
d0a790 ¤   jpeg_destroy_decompress (&cinfo);
8baf5a
10ae1e ¤   return lpbmi;
9cefe6 }
36af5a
074265 //¤ ___________________________________________________
0a465d //
62345c //¤ convert JPEG buffer to DIB·
d4af5a
3f96c1 static LPBITMAPINFO
0f89d1 sDIBfromJPEGBuffer (
0066a0 ¤   ¤   LPBYTE¤ buf,·
de5965 ¤   ¤   INT¤¤   isize,·
c82e59 ¤   ¤   BOOL¤   bForDisplay)
ecbb36 {
23f2cc ¤   LPBITMAPINFO¤   lpbmi¤  = NULL;
f5af5a
0a7165 ¤   FILE*¤  ¤   ¤   infile;
3caf5a
d90adb ¤   // write JPEG data to temp file for library to read from
73db10 ¤   infile = tmpfile ();
c25d35 ¤   fwrite (buf, 1, isize, infile);
83b63b ¤   rewind (infile);
00af5a
87e60d ¤   // convert the file
9bef4c ¤   lpbmi = sDIBfromJPEGFile (infile, bForDisplay);
4aaf5a
8d3e29 ¤   // close and delete temporary file
f206c4 ¤   fclose (infile);
0813ef ¤   _rmtmp ();
f8af5a
66ae1e ¤   return lpbmi;
54efe6 }
d5af5a
c54265 //¤ ___________________________________________________
d9465d //
41c4c5 //¤ convert PhotoID buffer to DIB·
15af5a
3ec77d PGPError
b39464 KMDIBfromPhoto (
6aa297 ¤   ¤   LPBYTE¤ ¤   ¤   buf,·
db92b6 ¤   ¤   INT¤¤   ¤   ¤   isize,·
6f6f4e ¤   ¤   BOOL¤   ¤   ¤   bForDisplay,
cd0b77 ¤   ¤   LPBITMAPINFO*¤  plpbmi)
aebb36 {
273384 ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
57f35c ¤   PGPPhotoUserIDHeader*¤  pheader;
--9c4f 0009d7e3359401102b1 Page 11 of KMPhoto.c
b965e8 ¤   LPBYTE¤ ¤   ¤   ¤   ¤   pdata;
ebc4e7 ¤   PGPUInt16¤  ¤   ¤   ¤   usHeaderLength;
aeaf5a
8afba0 ¤   if (!plpbmi) return kPGPError_BadParams;
e4af5a
87b0c5 ¤   *plpbmi = NULL;
128dad ¤   pheader = (PGPPhotoUserIDHeader*)buf;
8eaf5a
841be4 ¤   if (pheader->headerVersion != kPGPPhotoIDHeaderVersion)
c419d3 ¤   ¤   err = kPGPError_BadParams;
0d665a ¤   else {
0e88f6 ¤   ¤   switch (pheader->photoIDFormat) {
374cdc ¤   ¤   case kPGPPhotoIDFormat_JPEG :
a3e6cd ¤   ¤   ¤   usHeaderLength =·
b20b27 ¤   ¤   ¤   ¤   PGPStorageToUInt16 ((PGPByte*)&pheader->headerLength);
b16f6f ¤   ¤   ¤   pdata = buf + usHeaderLength;
8668b9 ¤   ¤   ¤   *plpbmi = sDIBfromJPEGBuffer (pdata,·
61d946 ¤   ¤   ¤   ¤   ¤   ¤   isize - usHeaderLength, bForDisplay);
6ecdcb ¤   ¤   ¤   break;
f1af5a
ab3a18 ¤   ¤   default :
095820 ¤   ¤   ¤   err = kPGPError_BadParams;
cd0fe4 ¤   ¤   }
099371 ¤   }
71af5a
6a5ea8 ¤   return err;
c1efe6 }
a1af5a
dc4265 //¤ ___________________________________________________
52465d //
b1f2a5 //¤ copy PhotoID buffer to clipboard in DIB format
88af5a
f4c77d PGPError
53727a KMCopyPhotoToClipboard (HWND hWnd, LPBYTE buf, INT isize)
d7bb36 {
4dfb19 ¤   PGPError¤   ¤   err;
3c05ac ¤   LPBITMAPINFO¤   lpbmi;
c792c9 ¤   HANDLE¤ ¤   ¤   hMem;
7ab3df ¤   LPBYTE¤ ¤   ¤   pMem;
be0e84 ¤   INT¤¤   ¤   ¤   iDIBsize;
f3af5a
8022bb ¤   err = KMDIBfromPhoto (buf, isize, FALSE, &lpbmi);
2caf5a
55b23e ¤   if (IsntPGPError (err)) {
d03a39 ¤   ¤   iDIBsize = KMGetDIBSize (lpbmi, NULL, NULL);
2dee04 ¤   ¤   hMem = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, iDIBsize);
58ad19 ¤   ¤   pMem = GlobalLock (hMem);
e19a63 ¤   ¤   CopyMemory (pMem, lpbmi, iDIBsize);
c1eb4a ¤   ¤   GlobalUnlock (hMem);
7caf5a
05bd97 ¤   ¤   OpenClipboard (hWnd);
117953 ¤   ¤   SetClipboardData (CF_DIB, hMem);
b60440 ¤   ¤   CloseClipboard ();
95af5a
a08449 ¤   ¤   KMFree (lpbmi);
c39371 ¤   }
1baf5a
205ea8 ¤   return err;
46efe6 }
f1af5a
fa4265 //¤ ___________________________________________________
22465d //
99d77e //¤ paste data in clipboard (DIB format) into JPEG buffer
aeaf5a
c0c77d PGPError
bfd35c KMPastePhotoFromClipboard (HWND hWnd, LPBYTE* pbuf, INT* pisize)
3cbb36 {
3e92c9 ¤   HANDLE¤ ¤   ¤   hMem;
3805ac ¤   LPBITMAPINFO¤   lpbmi;
3dfb19 ¤   PGPError¤   ¤   err;
c4af5a
9dd1b6 ¤   if (OpenClipboard (hWnd)) {·
--5a4e 0000694ae2f401102b1 Page 12 of KMPhoto.c
6fd967 ¤   ¤   hMem = GetClipboardData (CF_DIB);·
1bdd84 ¤   ¤   lpbmi = (LPBITMAPINFO)GlobalLock (hMem);
9eaf5a
0bf294 ¤   ¤   err = sPhotoFromDIB (lpbmi, MAX_PHOTO_WIDTH,
a54ec6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·MAX_PHOTO_HEIGHT, TRUE, pbuf, pisize);
9eaf5a
52eb4a ¤   ¤   GlobalUnlock (hMem);
9c579a ¤   ¤   CloseClipboard();·
3c9371 ¤   }
3e5ea8 ¤   return err;
16efe6 }
beaf5a
104265 //¤ ___________________________________________________
6d465d //
650db5 //¤ read BMP file into PhotoID buffer
fcaf5a
ddf1ae static PGPError
25ee25 sReadPhotoFromBMPFile (
1fa820 ¤   ¤   FILE*¤  ¤   pfile,·
93165a ¤   ¤   LPBYTE*¤¤   pbuf,·
052644 ¤   ¤   INT*¤   ¤   pisize)
56bb36 {
14ac94 ¤   PGPError¤   ¤   ¤   err¤¤   = kPGPError_Win32_InvalidImage;
d5501f ¤   LPBYTE¤ ¤   ¤   ¤   pfilebuf;
28f345 ¤   BITMAPFILEHEADER¤   bmfh;
5b9c30 ¤   LPBITMAPINFO¤   ¤   lpbmi;
1f4b8e ¤   ULONG¤  ¤   ¤   ¤   ulMaxFileSize;
0eaf5a
17d6e5 ¤   // read file header to get size of file
1d465e ¤   rewind (pfile);
ca8659 ¤   if (fread (&bmfh, 1, sizeof(bmfh), pfile) != sizeof(bmfh))
aac9db ¤   ¤   return err;
15af5a
017f86 ¤   // check for internal magic number and valid size
3960c6 ¤   if ((bmfh.bfType != 0x4d42) ||¤ ¤   // 'BM'
306b30 ¤   ¤   (bmfh.bfSize < (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)))) {
f9c9db ¤   ¤   return err;
e79371 ¤   }
92af5a
526402 ¤   // check for giant files
f94c64 ¤   ulMaxFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO);
442b0d ¤   ulMaxFileSize += 256*sizeof(RGBQUAD);
36047b ¤   ulMaxFileSize += MAX_FILE_WIDTH*MAX_FILE_HEIGHT*4;
baf954 ¤   if (bmfh.bfSize > ulMaxFileSize) {
c2ddb5 ¤   ¤   return kPGPError_Win32_ImageTooBig;
3a9371 ¤   }
8daf5a
01a6d9 ¤   // allocate buffer to hold entire file
655149 ¤   pfilebuf = KMAlloc (bmfh.bfSize);
b8bd69 ¤   if (!pfilebuf) {
524030 ¤   ¤   return kPGPError_OutOfMemory;
849371 ¤   }
5eaf5a
87802b ¤   // read the entire file into the buffer
d1465e ¤   rewind (pfile);
396df7 ¤   if (fread (pfilebuf, 1, bmfh.bfSize, pfile) != bmfh.bfSize)
18c9db ¤   ¤   return err;
7caf5a
d5a417 ¤   // set the pointer to byte following file header
ec9889 ¤   lpbmi = (LPBITMAPINFO)(pfilebuf + sizeof(bmfh));
19af5a
04e50e ¤   // check for compressed images (not supported)
a8acab ¤   if (lpbmi->bmiHeader.biCompression != BI_RGB) {
78a2dd ¤   ¤   KMFree (pfilebuf);
63c9db ¤   ¤   return err;
989371 ¤   }
06af5a
33e7d9 ¤   // convert
96a18f ¤   err = sPhotoFromDIB (lpbmi, MAX_PHOTO_WIDTH,
6173a8 ¤   ¤   ¤   ¤   ¤   ¤   ·MAX_PHOTO_HEIGHT, TRUE, pbuf, pisize);
39af5a
06403c ¤   KMFree (pfilebuf);
--f7cb 001fd856153401102b1 Page 13 of KMPhoto.c
e0af5a
de5ea8 ¤   return err;
57efe6 }
b7af5a
734265 //¤ ___________________________________________________
dc465d //
bbf64b //¤ read JPEG file into PhotoID buffer
12af5a
d6f1ae static PGPError
07df77 sReadPhotoFromJPEGFile (
87a820 ¤   ¤   FILE*¤  ¤   pfile,·
68165a ¤   ¤   LPBYTE*¤¤   pbuf,·
af2644 ¤   ¤   INT*¤   ¤   pisize)
a2bb36 {
a7ac94 ¤   PGPError¤   ¤   ¤   err¤¤   = kPGPError_Win32_InvalidImage;
269c30 ¤   LPBITMAPINFO¤   ¤   lpbmi;
a7af5a
395f7e ¤   // convert the JPEG file to a BMP buffer
b9465e ¤   rewind (pfile);
55bf3c ¤   lpbmi = sDIBfromJPEGFile (pfile, FALSE);
63af5a
f0a430 ¤   // convert to photoid format
40d118 ¤   if (lpbmi) {
fff294 ¤   ¤   err = sPhotoFromDIB (lpbmi, MAX_PHOTO_WIDTH,
4673a8 ¤   ¤   ¤   ¤   ¤   ¤   ·MAX_PHOTO_HEIGHT, TRUE, pbuf, pisize);
e89371 ¤   }
98af5a
f85ea8 ¤   return err;
55efe6 }
43af5a
7a4265 //¤ ___________________________________________________
6c465d //
3caef9 //¤ read image file into PhotoID buffer
8eaf5a
29c77d PGPError
5a03f0 KMReadPhotoFromFile (
97a814 ¤   ¤   LPSTR¤  ¤   pszFile,·
5c165a ¤   ¤   LPBYTE*¤¤   pbuf,·
d62644 ¤   ¤   INT*¤   ¤   pisize)
80bb36 {
e0ac94 ¤   PGPError¤   ¤   ¤   err¤¤   = kPGPError_Win32_InvalidImage;
661e88 ¤   FILE*¤  ¤   ¤   ¤   pfile;
54af5a
0e39c3 ¤   pfile = fopen (pszFile, "rb");
bdaf5a
602df3 ¤   if (pfile) {
c4b5a4 ¤   ¤   // attempt to read file as a JPEG file
6e72e6 ¤   ¤   err = sReadPhotoFromJPEGFile (pfile, pbuf, pisize);
e1af5a
2ca259 ¤   ¤   // if that didn't work, try it as a BMP file
daa42f ¤   ¤   if (IsPGPError (err)) {
bf6e6f ¤   ¤   ¤   err = sReadPhotoFromBMPFile (pfile, pbuf, pisize);
c70fe4 ¤   ¤   }
6caf5a
ab9fdf ¤   ¤   fclose (pfile);·
c89371 ¤   }
08af5a
6b5ea8 ¤   return err;
e7efe6 }
fdaf5a
--b1f7 00066de065b401102b2 Page 1 of KMProps.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
1d7fdb ¤   KMProps.c - handle Key properties dialogs
47af5a
d4d975 ¤   $Id: KMProps.c,v 1.84 1998/08/11 14:43:36 pbj Exp $
baf7f7 ____________________________________________________________________________*/
a1e610 #include "pgpPFLConfig.h"
87af5a
8dc917 // project header files
0d850a #include "pgpkmx.h"
405fcd #include "pgpclx.h"
06beb4 #include "..\include\treelist.h"
4faf5a
c4fc2c // system header files
6411a9 #include <process.h>
bfaf5a
965584 // constant definitions
0986ff #define ENFORCELISTWIDTH¤   52
73af5a
05638e #define MAXSHEETS¤  ¤   ¤   16¤ ¤   // max number of simultaneous dialogs
f3af5a
eee861 #define MINSUBKEYSIZE¤  ¤   768
96f42a #define MAXSUBKEYSIZE¤  ¤   4096
3aaded #define DEFAULTSUBKEYSIZE¤  2048
4daf5a
e2afcc #define SERIALIZE¤  ¤   ¤   1
065306 #define NOSERIALIZE¤¤   ¤   0
baaf5a
22cab4 #define AVI_TIMER¤  ¤   ¤   4321L
560515 #define AVI_RUNTIME¤¤   ¤   11000L
07af5a
685bee // typedefs
f7f0f7 typedef struct {
0f7e47 ¤   PKEYMAN¤¤   ¤   pKM;
868a8a ¤   WNDPROC¤¤   ¤   wpOrigFingerProc;
9df945 ¤   WNDPROC¤¤   ¤   wpOrigPhotoIDProc;
147be3 ¤   HIMAGELIST¤ ¤   hIml;
501502 ¤   PGPKeyRef¤  ¤   key;
20fead ¤   PGPKeySetRef¤   keyset;
ea8f18 ¤   PGPUserIDRef¤   userid;
03c339 ¤   UINT¤   ¤   ¤   algKey;
a20c32 ¤   INT¤¤   ¤   ¤   iIndex;
da1223 ¤   UINT¤   ¤   ¤   uTrust;
e5a48d ¤   UINT¤   ¤   ¤   uValidity;
088e57 ¤   INT¤¤   ¤   ¤   iExpireDays;
96e881 ¤   UINT¤   ¤   ¤   uNumberADKs;
e4cbbe ¤   UINT¤   ¤   ¤   uNumberRevokers;
f58e11 ¤   PGPBoolean¤ ¤   bReadOnly;
5c0000 ¤   PGPBoolean¤ ¤   bSecret;
580598 ¤   PGPBoolean¤ ¤   bSplit;
c271b4 ¤   PGPBoolean¤ ¤   bDisabled;
ab7067 ¤   PGPBoolean¤ ¤   bAxiomatic;
af6721 ¤   PGPBoolean¤ ¤   bInvalid;
ad085e ¤   PGPBoolean¤ ¤   bRevoked;
965a9e ¤   PGPBoolean¤ ¤   bExpired;
0cd466 ¤   PGPBoolean¤ ¤   bPhotoInvalid;
4a2c35 ¤   PGPBoolean¤ ¤   bKeyGenEnabled;
b5c215 ¤   BOOL¤   ¤   ¤   bReadyToPaint;
b2b3e5 ¤   BOOL¤   ¤   ¤   bNeedsCommit;
5d040d ¤   HWND¤   ¤   ¤   hwndValidity;
9ee03f ¤   HWND¤   ¤   ¤   hwndStartDate;
263f84 ¤   HWND¤   ¤   ¤   hwndExpireDate;
a108db ¤   HWND¤   ¤   ¤   hwndSubKeys;
b878d7 ¤   HWND¤   ¤   ¤   hwndADKs;
13dc4b ¤   HWND¤   ¤   ¤   hwndRevokers;
4adf77 ¤   HWND¤   ¤   ¤   hwndRevokerDlg;
58af2f ¤   INT¤¤   ¤   ¤   iNumPhotoIDs;
2fed7a ¤   INT¤¤   ¤   ¤   iPhotoIDIndex;
0ae7a7 ¤   HBITMAP¤¤   ¤   hbitmapPhotoID;
66cc3e ¤   HPALETTE¤   ¤   hpalettePhotoID;
--9a05 000390cffc7401102b2 Page 2 of KMProps.c
6e185f ¤   INT¤¤   ¤   ¤   iwidthPhotoID;
d25881 ¤   INT¤¤   ¤   ¤   iheightPhotoID;
9dd3db ¤   LPBYTE¤ ¤   ¤   pPhotoBuffer;
55f2b7 ¤   PGPSize¤¤   ¤   iPhotoBufferLength;
de62d3 ¤   PGPUInt32¤  ¤   uMinSubkeySize;
85d734 } KMPROPSHEETSTRUCT;
abaf5a
19f0f7 typedef struct {
3ef3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
167e47 ¤   PKEYMAN¤¤   ¤   pKM;
d8cb54 } PROPSTRUCT;
94af5a
d3f0f7 typedef struct {
467e47 ¤   PKEYMAN¤¤   ¤   pKM;
6a1502 ¤   PGPKeyRef¤  ¤   key;
0afead ¤   PGPKeySetRef¤   keyset;
428f18 ¤   PGPUserIDRef¤   userid;
ca518d } THREADSTRUCT;
0aaf5a
84f0f7 typedef struct {
b187ac ¤   PGPSubKeyRef¤   subkey;
673cd1 ¤   PGPTime¤¤   ¤   timeStart;
f28e57 ¤   INT¤¤   ¤   ¤   iExpireDays;
325ff1 ¤   BOOL¤   ¤   ¤   bNeverExpires;
855954 ¤   UINT¤   ¤   ¤   uSize;
a2f33d } SUBKEYSTRUCT, *PSUBKEYSTRUCT;
03af5a
25f0f7 typedef struct {
7b91a6 ¤   KMPROPSHEETSTRUCT*¤ pkmpss;
a14347 ¤   PSUBKEYSTRUCT¤  ¤   psks;
df183b ¤   LPSTR¤  ¤   ¤   ¤   pszPhrase;
cd0b24 ¤   PGPByte*¤   ¤   ¤   pPasskey;
000de9 ¤   PGPSize¤¤   ¤   ¤   sizePasskey;
f88602 ¤   HWND¤   ¤   ¤   ¤   hwndProgress;
d55c69 ¤   BOOL¤   ¤   ¤   ¤   bCancelPending;
e55a31 ¤   BOOL¤   ¤   ¤   ¤   bGenDone;
2cd309 ¤   BOOL¤   ¤   ¤   ¤   bGenOK;
06464c ¤   BOOL¤   ¤   ¤   ¤   bAVIStarted;
8cf362 ¤   BOOL¤   ¤   ¤   ¤   bAVIFinished;
42edd6 } SUBKEYGENSTRUCT, *PSUBKEYGENSTRUCT;
82af5a
0893ed // external globals
579cad extern HINSTANCE g_hInst;
97af5a
6e492e // local globals
0625ef static UINT uSubkeySizes[] = {768, 1024, 1536, 2048, 3072};
19af5a
ae62c7 static DWORD aKeyPropIds[] = {
5ebf61 ¤   IDC_CHANGEPHRASE,¤  IDH_PGPKM_CHANGEPHRASE,¤// this must be first item
2777e5 ¤   IDC_KEYID,¤ ¤   ¤   IDH_PGPKM_KEYID,
1160c1 ¤   IDC_KEYTYPE,¤   ¤   IDH_PGPKM_KEYTYPE,
e62522 ¤   IDC_KEYSIZE,¤   ¤   IDH_PGPKM_KEYSIZE,
186861 ¤   IDC_CREATEDATE,¤¤   IDH_PGPKM_CREATEDATE,
0e95bc ¤   IDC_EXPIREDATE,¤¤   IDH_PGPKM_KEYEXPIRES,
5cd910 ¤   IDC_CIPHER,¤¤   ¤   IDH_PGPKM_CIPHER,
4bcd28 ¤   IDC_FINGERPRINT,¤   IDH_PGPKM_FINGERPRINT,
d29cd9 ¤   IDC_ENABLED,¤   ¤   IDH_PGPKM_ENABLED,
df7886 ¤   IDC_PHOTOID,¤   ¤   IDH_PGPKM_PHOTOID,
e3824f ¤   IDC_VALIDITYBAR,¤   IDH_PGPKM_VALIDITYBAR,
918262 ¤   IDC_TRUSTSLIDER,¤   IDH_PGPKM_TRUSTSLIDER,
1b819b ¤   IDC_AXIOMATIC,¤ ¤   IDH_PGPKM_AXIOMATIC,
484434 ····0,0·
46a6fe };·
53af5a
8c5be6 static DWORD aNewSubkeyIds[] = {
9e9491 ¤   IDC_SUBKEYSIZE,¤¤   IDH_PGPKM_NEWSUBKEYSIZE,
082778 ¤   IDC_STARTDATE,¤ ¤   IDH_PGPKM_NEWSUBKEYSTARTDATE,
cb1041 ¤   IDC_NEVEREXPIRES,¤  IDH_PGPKM_NEWSUBKEYNEVEREXPIRES,
f38aaf ¤   IDC_EXPIRESON,¤ ¤   IDH_PGPKM_NEWSUBKEYEXPIRES,
392fd4 ¤   IDC_EXPIRATIONDATE,¤IDH_PGPKM_NEWSUBKEYEXPIREDATE,
724434 ····0,0·
39a6fe };·
--ba5f 000eedf24d7401102b2 Page 3 of KMProps.c
e0af5a
5f5237 static DWORD aSubkeyIds[] = {
9f2f97 ¤   IDC_SUBKEYLIST,¤¤   IDH_PGPKM_SUBKEYLIST,
c31d6a ¤   IDC_NEWSUBKEY,¤ ¤   IDH_PGPKM_SUBKEYCREATE,
e15dda ¤   IDC_REVOKESUBKEY,¤  IDH_PGPKM_SUBKEYREVOKE,
58dc31 ¤   IDC_REMOVESUBKEY,¤  IDH_PGPKM_SUBKEYREMOVE,
604434 ····0,0·
e0a6fe };·
25af5a
e16b38 static DWORD aADKIds[] = {
2bbceb ¤   IDC_FRAME,¤ ¤   ¤   IDH_PGPKM_ADKLIST,
8321ad ¤   IDC_ADKTREELIST,¤   IDH_PGPKM_ADKLIST,
e14434 ····0,0·
14a6fe };·
50af5a
e66608 static DWORD aRevokerIds[] = {
d1d37f ¤   IDC_FRAME,¤ ¤   ¤   IDH_PGPKM_REVOKERLIST,
f79f2c ¤   IDC_REVOKERTREELIST,IDH_PGPKM_REVOKERLIST,
c54434 ····0,0·
17a6fe };·
c4af5a
22af5a
294265 //¤ ___________________________________________________
3e465d //
5f7cc2 //¤ convert SYSTEMTIME structure to number of days from today
79af5a
2cf1ae static PGPError
efec46 sSystemTimeToPGPTime (
ab600d ¤   ¤   ·SYSTEMTIME*¤   pst,·
87d628 ¤   ¤   ·PGPTime*¤  ¤   ptime)·
ffbb36 {
d8af70 ¤   struct tm¤  tmstruct;
ce605c ¤   time_t¤ ¤   timeStd;
b1af5a
ddeeb3 ¤   pgpAssert (pst != NULL);
a95349 ¤   pgpAssert (ptime != NULL);
ddaf5a
7e3f62 ¤   *ptime = 0;
0caf5a
c4788f ¤   if (pst->wYear > 2037)·
fc62b5 ¤   ¤   return kPGPError_BadParams;
f6af5a
242939 ¤   tmstruct.tm_mday = pst->wDay;
e78a11 ¤   tmstruct.tm_mon = pst->wMonth -1;
3da9f3 ¤   tmstruct.tm_year = pst->wYear -1900;
b2ad07 ¤   tmstruct.tm_hour = 0;
6268da ¤   tmstruct.tm_min = 0;
a759b6 ¤   tmstruct.tm_sec = 0;
4c3c1d ¤   tmstruct.tm_isdst = -1;
d9af5a
dd0a45 ¤   timeStd = mktime (&tmstruct);
d9da51 ¤   if (timeStd == (time_t)-1) return kPGPError_BadParams;
14af5a
7a8a32 ¤   *ptime = PGPGetPGPTimeFromStdTime (timeStd);
1aaf5a
3c151e ¤   return kPGPError_NoErr;
62efe6 }
8caf5a
adaf5a
ffc509 //¤ ____________________________________
f2465d //
590dcc // ·display keygen AVI file in specified window
bbaf5a
a5e6b2 static VOID
5293d2 sStartKeyGenAVI (HWND hwnd, LPSTR szHelpFile)
83bb36 {
dbcde7 ¤   CHAR¤   szFile[32];
b78085 ¤   CHAR¤   szAnimationFile[MAX_PATH];
576d9e ¤   LPSTR¤  p;
acaf5a
d1ed16 ¤   lstrcpy (szAnimationFile, szHelpFile);
eeaf5a
--3511 00044f910b8401102b2 Page 4 of KMProps.c
93cc28 ¤   p = strrchr (szAnimationFile, '\\');
0f4dda ¤   if (!p)
48ee35 ¤   ¤   p = szAnimationFile;
4a0e24 ¤   else
7e4992 ¤   ¤   ++p;
8dddb4 ¤   *p = '\0';
71af5a
c21dae ¤   LoadString (g_hInst, IDS_ANIMATIONFILE, szFile, sizeof(szFile));
7a9a20 ¤   lstrcat (szAnimationFile, szFile);
6eaf5a
b8a1b1 ¤   Animate_Open (hwnd, szAnimationFile);
619c3d ¤   Animate_Play (hwnd, 0, -1, -1);
66efe6 }
82af5a
91af5a
78d4d4 //¤ ______________________________________________
62465d //
015b81 // ·callback routine called by library key generation routine
8fc69c // ·every so often with status of keygen. ·Returning a nonzero
a2e502 // ·value cancels the key generation.
0faf5a
bb69c9 static PGPError·
8f57bb sSubkeyGenEventHandler (
fcfb68 ¤   ¤   PGPContextRef¤  context,·
205b49 ¤   ¤   PGPEvent*¤  ¤   event,
4bc05f ¤   ¤   PGPUserValue¤   userValue)
67bb36 {
cef714 ¤   INT¤¤   ¤   ¤   ¤   iReturnCode = kPGPError_NoErr;
cd1597 ¤   PSUBKEYGENSTRUCT¤   pskgs;
4faf5a
ba6a31 ¤   pskgs = (PSUBKEYGENSTRUCT) userValue;
24af5a
a61db4 ¤   if (pskgs->bCancelPending)·
8e471f ¤   ¤   iReturnCode = kPGPError_UserAbort;
1c67c5 ¤
48b195 ¤   return (iReturnCode);
62efe6 }
22af5a
a0af5a
8b4265 //¤ ___________________________________________________
74465d //
2c7849 // ·subkey generation thread
d0af5a
49b333 static VOID·
be0580 sSubkeyGenerationThread (void *pArgs)
79bb36 {
38a9b9 ¤   PSUBKEYGENSTRUCT¤   pskgs¤  ¤   = (PSUBKEYGENSTRUCT)pArgs;
7aaf5a
75d666 ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   ¤   = FALSE;
feaf5a
81251c ¤   PGPBoolean¤ ¤   bFastGen;
adce0f ¤   PGPPrefRef¤ ¤   prefref;
62a946 ¤   PGPContextRef¤  ctx;
7d2b47 ¤   UINT¤   ¤   ¤   uEntropyNeeded;
06fb19 ¤   PGPError¤   ¤   err;
70af5a
83c1a1 ¤   // get client preferences
40d6bf ¤   KMRequestSDKAccess (pskgs->pkmpss->pKM);
1cda48 ¤   PGPclOpenClientPrefs (
a6565a ¤   ¤   PGPGetContextMemoryMgr (pskgs->pkmpss->pKM->Context), &prefref);
97a0aa ¤   PGPGetPrefBoolean (prefref, kPGPPrefFastKeyGen, &bFastGen);
1aab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
aeaf5a
e11aa7 ¤   // generate subkey
7c2a1e ¤   ctx = pskgs->pkmpss->pKM->Context;
953418 ¤   uEntropyNeeded = PGPGetKeyEntropyNeeded (ctx,
c2796f ¤   ¤   ¤   PGPOKeyGenParams (ctx,·
fb8156 ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_ElGamal,·
c5d04b ¤   ¤   ¤   ¤   ¤   ¤   pskgs->psks->uSize),
528fe0 ¤   ¤   ¤   PGPOKeyGenFast (ctx, bFastGen),
4fa400 ¤   ¤   ¤   PGPOLastOption (ctx));
44dcd4 ¤   PGPclRandom (ctx, pskgs->hwndProgress, uEntropyNeeded);
--51ca 00093644e5d401102b2 Page 5 of KMProps.c
e0af5a
984b3b ¤   if (pskgs->pszPhrase) {
a9bff5 ¤   ¤   err = PGPGenerateSubKey (
4a61ef ¤   ¤   ¤   ctx, &pskgs->psks->subkey,
90bc68 ¤   ¤   ¤   PGPOKeyGenMasterKey (ctx, pskgs->pkmpss->key),
be796f ¤   ¤   ¤   PGPOKeyGenParams (ctx,·
1c8156 ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_ElGamal,·
59d04b ¤   ¤   ¤   ¤   ¤   ¤   pskgs->psks->uSize),
c88fe0 ¤   ¤   ¤   PGPOKeyGenFast (ctx, bFastGen),
951fb4 ¤   ¤   ¤   PGPOPassphrase (ctx, pskgs->pszPhrase),
8e6c45 ¤   ¤   ¤   PGPOCreationDate (ctx, pskgs->psks->timeStart),
19b124 ¤   ¤   ¤   PGPOExpiration (ctx, pskgs->psks->iExpireDays),
9d29aa ¤   ¤   ¤   PGPOEventHandler (ctx, sSubkeyGenEventHandler, pskgs),
e3a400 ¤   ¤   ¤   PGPOLastOption (ctx));
b89371 ¤   }
c1665a ¤   else {
dbbff5 ¤   ¤   err = PGPGenerateSubKey (
f961ef ¤   ¤   ¤   ctx, &pskgs->psks->subkey,
90bc68 ¤   ¤   ¤   PGPOKeyGenMasterKey (ctx, pskgs->pkmpss->key),
af796f ¤   ¤   ¤   PGPOKeyGenParams (ctx,·
d88156 ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_ElGamal,·
70d04b ¤   ¤   ¤   ¤   ¤   ¤   pskgs->psks->uSize),
738fe0 ¤   ¤   ¤   PGPOKeyGenFast (ctx, bFastGen),
95ce5c ¤   ¤   ¤   PGPOPasskeyBuffer (ctx, pskgs->pPasskey, pskgs->sizePasskey),
776c45 ¤   ¤   ¤   PGPOCreationDate (ctx, pskgs->psks->timeStart),
70b124 ¤   ¤   ¤   PGPOExpiration (ctx, pskgs->psks->iExpireDays),
eb29aa ¤   ¤   ¤   PGPOEventHandler (ctx, sSubkeyGenEventHandler, pskgs),
d2a400 ¤   ¤   ¤   PGPOLastOption (ctx));
609371 ¤   }
aefe01 ¤   // note: PGPGenerateSubKey returns kPGPError_OutOfMemory·
d25168 ¤   // when user aborts!
5fc4ac ¤   if (err == kPGPError_OutOfMemory)·
d00fd8 ¤   ¤   err = kPGPError_UserAbort;
7054f1 ¤   KMReleaseSDKAccess (pskgs->pkmpss->pKM);
38af5a
44db30 ¤   PGPclErrorBox (pskgs->hwndProgress, err);
83af5a
731319 ¤   pskgs->bGenDone = TRUE;
d0033a ¤   if (IsntPGPError (err))
25093c ¤   ¤   pskgs->bGenOK = TRUE;
57af5a
71ad16 ¤   SendMessage (pskgs->hwndProgress, WM_CLOSE, 0, 0);
5baf5a
2d830f ¤   return;
b2efe6 }
29af5a
52af5a
c54265 //¤ ___________________________________________________
6a465d //
e95335 // ·check for valid date settings
1daf5a
dcb333 static VOID·
cac6d4 sValidateSubKeyDates (
f875f7 ¤   ¤   HWND¤   ¤   ¤   ¤   hDlg,·
26e8a4 ¤   ¤   KMPROPSHEETSTRUCT*¤ pkmpss)·
c1bb36 {
d6cef2 ¤   BOOL¤   ¤   bOK;
1c10bb ¤   SYSTEMTIME¤ st;
11b417 ¤   INT¤¤   ¤   iStartDays;
fbbe16 ¤   INT¤¤   ¤   iExpireDays;
01af5a
6f3210 ¤   // get starting date
9757c2 ¤   SendMessage (pkmpss->hwndStartDate, DTM_GETSYSTEMTIME, 0,·
725cad ¤   ¤   ¤   ¤   ¤   (LPARAM)&st);
5b55ef ¤   PGPclSystemTimeToDays (&st, &iStartDays);
acaf5a
d6e8d3 ¤   // get expiration date
55dad9 ¤   iExpireDays = iStartDays+1;
60f092 ¤   if (IsDlgButtonChecked (hDlg, IDC_NEVEREXPIRES) == BST_UNCHECKED) {
d8a31f ¤   ¤   SendMessage (pkmpss->hwndExpireDate, DTM_GETSYSTEMTIME, 0,·
ef5cad ¤   ¤   ¤   ¤   ¤   (LPARAM)&st);
9372f9 ¤   ¤   PGPclSystemTimeToDays (&st, &iExpireDays);
--9b02 000ffa3e008401102b2 Page 6 of KMProps.c
a19371 ¤   }
93af5a
6aec50 ¤   if ((iStartDays >= 0) &&·
54bfb6 ¤   ¤   (iExpireDays > iStartDays) &&
32526c ¤   ¤   ((pkmpss->iExpireDays == -1) ||
803a97 ¤   ¤   ·(iExpireDays <= pkmpss->iExpireDays)))
2ee7c8 ¤   ¤   bOK = TRUE;
514264 ¤   else·
317be0 ¤   ¤   bOK = FALSE;
afaf5a
404d8b ¤   if (bOK)
5a7ae0 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
c40e24 ¤   else
de7c02 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
5aefe6 }
caaf5a
3a4265 //¤ ___________________________________________________
f0465d //
bf4159 // ·subkey generation progress dialog procedure
8faf5a
0ef9ba static BOOL CALLBACK
61ea87 sSubkeyGenProgressDlgProc (
963a3a ¤   ¤   HWND¤   hDlg,·
bbeb77 ¤   ¤   UINT¤   uMsg,·
1c0303 ¤   ¤   WPARAM¤ wParam,
7ac0b8 ¤   ¤   LPARAM¤ lParam)·
bbbb36 {
3f1597 ¤   PSUBKEYGENSTRUCT¤   pskgs;
3c06b1 ¤   DWORD¤  ¤   ¤   ¤   dw;
f1af5a
1d347f ¤   switch (uMsg) {
a9af5a
222940 ¤   case WM_INITDIALOG:
5ac72a ¤   ¤   // store pointer to data structure
af7547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
dc710d ¤   ¤   pskgs = (PSUBKEYGENSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
4f45d4 ¤   ¤   pskgs->bAVIStarted = FALSE;
c30388 ¤   ¤   pskgs->bAVIFinished = FALSE;
821a26 ¤   ¤   pskgs->hwndProgress = hDlg;
4daf5a
34e268 ¤   ¤   // Kick off generation proc, here
f776b6 ¤   ¤   _beginthreadex (NULL, 0,·
e0c4bf ¤   ¤   ¤   ¤   (LPTHREAD_START_ROUTINE)sSubkeyGenerationThread,·
396258 ¤   ¤   ¤   ¤   (void *)pskgs, 0, &dw);
01dcb6 ¤   ¤   SetTimer (hDlg, AVI_TIMER, 100, NULL); ·// delay a few ms
0f99d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // before drawing
c0d551 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // AVI
8b836c ¤   ¤   return TRUE;
47af5a
185122 ¤   case WM_TIMER :
9ce873 ¤   ¤   if (wParam == AVI_TIMER) {
1d67bb ¤   ¤   ¤   pskgs = (PSUBKEYGENSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
18ade0 ¤   ¤   ¤   KillTimer (hDlg, AVI_TIMER);
91b410 ¤   ¤   ¤   if (pskgs->bAVIStarted) {
5f7b9f ¤   ¤   ¤   ¤   if (!pskgs->bAVIFinished) {
710560 ¤   ¤   ¤   ¤   ¤   pskgs->bAVIFinished = TRUE;
1950da ¤   ¤   ¤   ¤   ¤   if (pskgs->bGenDone)·
7c84f7 ¤   ¤   ¤   ¤   ¤   ¤   PostMessage (hDlg, WM_CLOSE, 0, 0);
5a2613 ¤   ¤   ¤   ¤   }
57a3a6 ¤   ¤   ¤   }
8be543 ¤   ¤   ¤   else {
19d667 ¤   ¤   ¤   ¤   sStartKeyGenAVI (GetDlgItem (hDlg, IDC_SUBKEYAVI),
93df56 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pskgs->pkmpss->pKM->szHelpFile);
d97bdf ¤   ¤   ¤   ¤   SetTimer (hDlg, AVI_TIMER, AVI_RUNTIME, NULL);
9667b8 ¤   ¤   ¤   ¤   pskgs->bAVIStarted = TRUE;
51a3a6 ¤   ¤   ¤   }
b60fe4 ¤   ¤   }
fa2f68 ¤   ¤   break;
6467c5 ¤
f46334 ¤   case WM_DESTROY :
2c710d ¤   ¤   pskgs = (PSUBKEYGENSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
ff5003 ¤   ¤   pskgs->bAVIFinished = TRUE;
--3cc8 000d860e6b7401102b2 Page 7 of KMProps.c
333f64 ¤   ¤   Animate_Close (GetDlgItem (hDlg, IDC_SUBKEYAVI));
6a2f68 ¤   ¤   break;
deaf5a
5d75f9 ¤   case WM_CLOSE :
c7710d ¤   ¤   pskgs = (PSUBKEYGENSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
bb07a6 ¤   ¤   EndDialog (hDlg, pskgs->bGenOK);
282f68 ¤   ¤   break;
91af5a
93d1d3 ¤   case WM_COMMAND :
50379d ¤   ¤   switch(LOWORD (wParam)) {
c3b6bb ¤   ¤   case IDCANCEL :
5a67bb ¤   ¤   ¤   pskgs = (PSUBKEYGENSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
eac239 ¤   ¤   ¤   pskgs->bCancelPending = TRUE;
ffcdcb ¤   ¤   ¤   break;
9a0fe4 ¤   ¤   }
b22f68 ¤   ¤   break;
289371 ¤   }
45af5a
85a230 ¤   return FALSE;
16efe6 }
cdaf5a
4c4265 //¤ ___________________________________________________
81465d //
68a32b // ·generate new subkey
cfaf5a
406c77 static BOOL·
b5f96c sAddNewSubkey (
ec75f7 ¤   ¤   HWND¤   ¤   ¤   ¤   hDlg,·
1de8a4 ¤   ¤   KMPROPSHEETSTRUCT*¤ pkmpss)·
c2bb36 {
b9baaa ¤   BOOL¤   ¤   ¤   ¤   bRetVal¤¤   ¤   ¤   = FALSE;
62af5a
764347 ¤   PSUBKEYSTRUCT¤  ¤   psks;
01d7cf ¤   SUBKEYGENSTRUCT¤¤   skgs;
16af5a
d8e8fe ¤   SYSTEMTIME¤ ¤   ¤   st;
0fec89 ¤   UINT¤   ¤   ¤   ¤   uSubKeySize;
42b26b ¤   CHAR¤   ¤   ¤   ¤   szSize[16];
31609f ¤   CHAR¤   ¤   ¤   ¤   szValid[32];
e58c7b ¤   CHAR¤   ¤   ¤   ¤   szExpires[32];
3e0d1a ¤   LV_ITEM¤¤   ¤   ¤   lvI;
daf204 ¤   INT¤¤   ¤   ¤   ¤   iItem, iStartDays;
d60846 ¤   CHAR¤   ¤   ¤   ¤   sz[64];
876385 ¤   CHAR¤   ¤   ¤   ¤   sz2[128];
a28f52 ¤   PGPError¤   ¤   ¤   err;
f5af5a
2f8376 ¤   // initialize structs
1062ad ¤   skgs.pkmpss = pkmpss;
720807 ¤   skgs.pszPhrase = NULL;
171334 ¤   skgs.pPasskey = NULL;
8aa4f9 ¤   skgs.bCancelPending = FALSE;
0bdde7 ¤   skgs.bGenDone = FALSE;
07a20b ¤   skgs.bGenOK = FALSE;
83af5a
dedfaf ¤   // get subkey size
7875a9 ¤   uSubKeySize = 0;
447541 ¤   GetDlgItemText (hDlg, IDC_SUBKEYSIZE, szSize, sizeof(szSize) -1);
2ac13a ¤   uSubKeySize = atoi (szSize);
a2dfab ¤   if ((uSubKeySize < pkmpss->uMinSubkeySize) ||·
40f85a ¤   ¤   (uSubKeySize > MAXSUBKEYSIZE)) {
9baf5a
a81c1f ¤   ¤   LoadString (g_hInst, IDS_BADSUBKEYSIZE, sz, sizeof(sz));
b01743 ¤   ¤   wsprintf (sz2, sz, pkmpss->uMinSubkeySize);
119255 ¤   ¤   LoadString (g_hInst, IDS_CAPTION, sz, sizeof(sz));
787529 ¤   ¤   MessageBox (hDlg, sz2, sz, MB_OK | MB_ICONEXCLAMATION);
7498aa ¤   ¤   return FALSE;
f9af5a
249371 ¤   }
95c5d3 ¤   wsprintf (szSize, "%i", uSubKeySize);
bcaf5a
f2d2ec ¤   // allocate new structure
d8da32 ¤   psks = KMAlloc (sizeof(SUBKEYSTRUCT));
--0c03 000f4d89738401102b2 Page 8 of KMProps.c
e196d4 ¤   if (!psks) return FALSE;
bf7e6a ¤   skgs.psks = psks;
e9af5a
e7abb0 ¤   // initialize structure
44879a ¤   psks->subkey = NULL;
da1a3f ¤   psks->timeStart = 0;
f4d7c5 ¤   psks->iExpireDays = 0;
fb9fdd ¤   psks->uSize = uSubKeySize;
f6af5a
883210 ¤   // get starting date
7957c2 ¤   SendMessage (pkmpss->hwndStartDate, DTM_GETSYSTEMTIME, 0,·
895cad ¤   ¤   ¤   ¤   ¤   (LPARAM)&st);
c60c87 ¤   sSystemTimeToPGPTime (&st, &psks->timeStart);
7cc20d ¤   GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,·
b834be ¤   ¤   ¤   ¤   ¤   ¤   NULL, szValid, sizeof(szValid));
df55ef ¤   PGPclSystemTimeToDays (&st, &iStartDays);
00af5a
1be8d3 ¤   // get expiration date
2a3248 ¤   if (IsDlgButtonChecked (hDlg, IDC_NEVEREXPIRES) == BST_CHECKED) {
500e50 ¤   ¤   psks->bNeverExpires = TRUE;
92c3ed ¤   ¤   psks->iExpireDays = 0;
c39371 ¤   }
fc665a ¤   else {
af63c8 ¤   ¤   psks->bNeverExpires = FALSE;
dea31f ¤   ¤   SendMessage (pkmpss->hwndExpireDate, DTM_GETSYSTEMTIME, 0,·
9e5cad ¤   ¤   ¤   ¤   ¤   (LPARAM)&st);
91aec6 ¤   ¤   PGPclSystemTimeToDays (&st, &psks->iExpireDays);
92b079 ¤   ¤   psks->iExpireDays -= iStartDays;
309371 ¤   }
8e36cf ¤   if (psks->bNeverExpires)
19c7a1 ¤   ¤   LoadString (g_hInst, IDS_NEVER, szExpires, sizeof(szExpires));
3f0e24 ¤   else
e27e14 ¤   ¤   GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,·
f5aa04 ¤   ¤   ¤   ¤   ¤   ¤   NULL, szExpires, sizeof(szExpires));
c9af5a
5efa63 ¤   // get phrase from user
861d8b ¤   LoadString (g_hInst, IDS_SELKEYPASSPHRASE, sz, sizeof(sz));·
e64e14 ¤   KMRequestSDKAccess (pkmpss->pKM);
5f9c03 ¤   err = KMGetKeyPhrase (pkmpss->pKM->Context, pkmpss->pKM->tlsContext,
c144d2 ¤   ¤   ¤   ¤   ¤   hDlg, sz, pkmpss->keyset, pkmpss->key,
2bd2ca ¤   ¤   ¤   ¤   ¤   &skgs.pszPhrase, &skgs.pPasskey, &skgs.sizePasskey);
534e88 ¤   KMReleaseSDKAccess (pkmpss->pKM);
9c18b2 ¤   PGPclErrorBox (NULL, err);
35af5a
b1b23e ¤   if (IsntPGPError (err)) {
850f6d ¤   ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_SUBKEYGENPROG),·
62b9c8 ¤   ¤   ¤   ¤   ¤   ¤   hDlg, sSubkeyGenProgressDlgProc, (LPARAM)&skgs))
ac5b34 ¤   ¤   {
d80291 ¤   ¤   ¤   pkmpss->bNeedsCommit = TRUE;
3eaf5a
1d1fc8 ¤   ¤   ¤   // figure item index to use
253e14 ¤   ¤   ¤   iItem = ListView_GetItemCount (pkmpss->hwndSubKeys);
1daf5a
569cc0 ¤   ¤   ¤   // insert listview item
cee035 ¤   ¤   ¤   lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
26f0ad ¤   ¤   ¤   lvI.state = 0; ·····
5b6839 ¤   ¤   ¤   lvI.stateMask = 0;
f3247a ¤   ¤   ¤   lvI.iImage = IDX_DSAPUBKEY;
af1b52 ¤   ¤
e39bd3 ¤   ¤   ¤   lvI.iItem = iItem;
401ebb ¤   ¤   ¤   lvI.iSubItem = 0;
429464 ¤   ¤   ¤   lvI.pszText¤= szValid;·
f7a1be ¤   ¤   ¤   lvI.cchTextMax = 0;
14a311 ¤   ¤   ¤   lvI.lParam = (LPARAM)psks;
68af5a
491156 ¤   ¤   ¤   iItem = ListView_InsertItem (pkmpss->hwndSubKeys, &lvI);
79fb05 ¤   ¤   ¤   if (iItem == -1)·
3103b7 ¤   ¤   ¤   ¤   KMFree (psks);
14e543 ¤   ¤   ¤   else {
82aac2 ¤   ¤   ¤   ¤   // add strings for other columns
6dae41 ¤   ¤   ¤   ¤   ListView_SetItemText (pkmpss->hwndSubKeys,·
f4a85e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iItem, 1, szExpires);
--3f9b 0008b1ed4c3401102b2 Page 9 of KMProps.c
5eae41 ¤   ¤   ¤   ¤   ListView_SetItemText (pkmpss->hwndSubKeys,·
71e538 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iItem, 2, szSize);
9ab598 ¤   ¤   ¤   ¤   bRetVal = TRUE;
a2a3a6 ¤   ¤   ¤   }
350fe4 ¤   ¤   }
f89371 ¤   }
51af5a
f8828b ¤   if (skgs.pszPhrase)
e4e99a ¤   ¤   KMFreePhrase (skgs.pszPhrase);
b4af5a
204580 ¤   if (skgs.pPasskey)·
c78e96 ¤   ¤   KMFreePasskey (skgs.pPasskey, skgs.sizePasskey);
fcaf5a
f91c35 ¤   return bRetVal;
5aefe6 }
baaf5a
45af5a
bb4265 //¤ ___________________________________________________
06465d //
170a95 // ·new subkey dialog procedure
0aaf5a
393f64 static BOOL CALLBACK·
cf94bb sNewSubkeyDlgProc (
233a3a ¤   ¤   HWND¤   hDlg,·
9deb77 ¤   ¤   UINT¤   uMsg,·
ec0303 ¤   ¤   WPARAM¤ wParam,
5bc0b8 ¤   ¤   LPARAM¤ lParam)·
a5bb36 {
6f91a6 ¤   KMPROPSHEETSTRUCT*¤ pkmpss;
76b996 ¤   RECT¤   ¤   ¤   ¤   rc;
dbb236 ¤   INT¤¤   ¤   ¤   ¤   i;
556d9c ¤   INT¤¤   ¤   ¤   ¤   iMinDefaultSize;¤   ¤   ¤
cf201c ¤   CHAR¤   ¤   ¤   ¤   sz[8];
a2af5a
e0b32f ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
cbaf5a
36347f ¤   switch (uMsg) {
a7af5a
032940 ¤   case WM_INITDIALOG:
6bc72a ¤   ¤   // store pointer to data structure
c17547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
61b459 ¤   ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
fcaf5a
d684b8 ¤   ¤   // create and initialize start date control
c3d004 ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_STARTDATE), &rc);
034f66 ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
e681a9 ¤   ¤   pkmpss->hwndStartDate = CreateWindowEx (0, DATETIMEPICK_CLASS,
6f3d5e ·····························"DateTime",
b2b6b3 ·····························WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
69d631 ·····························rc.left, rc.top,·
4679ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·rc.right-rc.left, rc.bottom-rc.top,·
232c04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hDlg, (HMENU)IDC_STARTDATE,·
95d5a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·g_hInst, NULL);
a51c1c ¤   ¤   SetWindowPos (pkmpss->hwndStartDate,·
ba0c1c ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_STARTDATETEXT),
57b78a ¤   ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
7834fc ¤   ¤   SendMessage (pkmpss->hwndStartDate, DTM_SETMCCOLOR,·
ac6e0e ¤   ¤   ¤   ¤   ¤   ¤   MCSC_MONTHBK, (LPARAM)GetSysColor (COLOR_3DFACE));
30af5a
5cc3f4 ¤   ¤   // create and initialize expire date control
3ecf7d ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_EXPIRATIONDATE), &rc);
c94f66 ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
51a730 ¤   ¤   pkmpss->hwndExpireDate = CreateWindowEx (0, DATETIMEPICK_CLASS,
c13d5e ·····························"DateTime",
3ab6b3 ·····························WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
1fd631 ·····························rc.left, rc.top,·
fb79ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·rc.right-rc.left, rc.bottom-rc.top,·
68c779 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hDlg, (HMENU)IDC_EXPIRATIONDATE,·
36d5a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·g_hInst, NULL);
085b91 ¤   ¤   SendMessage (pkmpss->hwndExpireDate, DTM_SETMCCOLOR,·
b46e0e ¤   ¤   ¤   ¤   ¤   ¤   MCSC_MONTHBK, (LPARAM)GetSysColor (COLOR_3DFACE));
8bfa97 ¤   ¤   SetWindowPos (pkmpss->hwndExpireDate,·
--356b 0009aa79d8a401102b2 Page 10 of KMProps.c
5a9087 ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_EXPIRESON),
e7b78a ¤   ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
a4904b ¤   ¤   EnableWindow (pkmpss->hwndExpireDate, FALSE);
0067ad ¤   ¤   CheckDlgButton (hDlg, IDC_NEVEREXPIRES, BST_CHECKED);
91af5a
bde0a4 ¤   ¤   // initialize subkey size combo box
a27f9b ¤   ¤   iMinDefaultSize = 0;
9a9d22 ¤   ¤   for (i=0; i<(sizeof(uSubkeySizes)/sizeof(UINT)); i++) {
8e5af3 ¤   ¤   ¤   if (uSubkeySizes[i] >= pkmpss->uMinSubkeySize) {
ba840f ¤   ¤   ¤   ¤   wsprintf (sz, "%i", uSubkeySizes[i]);
2c63af ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_SUBKEYSIZE, CB_ADDSTRING,·
1447d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)sz);
8af429 ¤   ¤   ¤   ¤   if (iMinDefaultSize == 0)·
f06769 ¤   ¤   ¤   ¤   ¤   iMinDefaultSize = uSubkeySizes[i];
b1a3a6 ¤   ¤   ¤   }
800fe4 ¤   ¤   }
d60b3f ¤   ¤   if (iMinDefaultSize < DEFAULTSUBKEYSIZE)
14f586 ¤   ¤   ¤   iMinDefaultSize = DEFAULTSUBKEYSIZE;
1c6613 ¤   ¤   wsprintf (sz, "%i", iMinDefaultSize);
090514 ¤   ¤   SetDlgItemText (hDlg, IDC_SUBKEYSIZE, sz);
0caf5a
83d271 ¤   ¤   sValidateSubKeyDates (hDlg, pkmpss);
a8af5a
c0836c ¤   ¤   return TRUE;
a4af5a
e93fcf ¤   case WM_COMMAND:
ac379d ¤   ¤   switch(LOWORD (wParam)) {
f4b6bb ¤   ¤   case IDCANCEL :
187c22 ¤   ¤   ¤   EndDialog (hDlg, FALSE);
6acdcb ¤   ¤   ¤   break;
8baf5a
ee644a ¤   ¤   case IDC_NEVEREXPIRES :
82c1b3 ¤   ¤   case IDC_EXPIRESON :
440a89 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_EXPIRESON) == BST_CHECKED) {
0c2c3d ¤   ¤   ¤   ¤   EnableWindow (pkmpss->hwndExpireDate, TRUE);
9fd3f7 ¤   ¤   ¤   ¤   sValidateSubKeyDates (hDlg, pkmpss);
13a3a6 ¤   ¤   ¤   }
83e543 ¤   ¤   ¤   else {
cb713c ¤   ¤   ¤   ¤   EnableWindow (pkmpss->hwndExpireDate, FALSE);
edd3f7 ¤   ¤   ¤   ¤   sValidateSubKeyDates (hDlg, pkmpss);
7fa3a6 ¤   ¤   ¤   }
5fcdcb ¤   ¤   ¤   break;
96af5a
428c29 ¤   ¤   case IDOK :
d991c9 ¤   ¤   ¤   if (sAddNewSubkey (hDlg, pkmpss))
619fb5 ¤   ¤   ¤   ¤   EndDialog (hDlg, TRUE);
b7cdcb ¤   ¤   ¤   break;
410fe4 ¤   ¤   }
9e836c ¤   ¤   return TRUE;
53af5a
6dc3eb ····case WM_HELP:·
16638a ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pkmpss->pKM->szHelpFile,·
d1928b ············HELP_WM_HELP, (DWORD) (LPSTR) aNewSubkeyIds);·
5b8f13 ········break;·
fdd83c ·
8b4fd8 ····case WM_CONTEXTMENU:·
705409 ········WinHelp ((HWND) wParam, pkmpss->pKM->szHelpFile, HELP_CONTEXTMENU,·
811d84 ············(DWORD) (LPVOID) aNewSubkeyIds);·
ca8f13 ········break;·
8eaf5a
0a6334 ¤   case WM_DESTROY :
eb2f68 ¤   ¤   break;
4caf5a
de1431 ¤   case WM_NOTIFY :
f7d271 ¤   ¤   sValidateSubKeyDates (hDlg, pkmpss);
cc2f68 ¤   ¤   break;
649371 ¤   }
19a230 ¤   return FALSE;
f4efe6 }
89af5a
724265 //¤ ___________________________________________________
9a465d //
--9519 000b64954aa401102b2 Page 11 of KMProps.c
d5a3e8 // ·remove subkey from listview control
d2af5a
026c77 static BOOL·
fff82c sRemoveSubKey (HWND hDlg, KMPROPSHEETSTRUCT* pkmpss)
b9bb36 {
000c32 ¤   INT¤¤   ¤   ¤   iIndex;
460f07 ¤   INT¤¤   ¤   ¤   iNumItems;
8ed2d1 ¤   INT¤¤   ¤   ¤   ids;
5082cc ¤   LV_ITEM¤¤   ¤   lvI;
45fb19 ¤   PGPError¤   ¤   err;
4e12ce ¤   PSUBKEYSTRUCT¤  psks;
8caf5a
21a5e8 ¤   iNumItems = ListView_GetItemCount (pkmpss->hwndSubKeys);
86f943 ¤   if (iNumItems > 1) ids = IDS_REMOVESUBKEYCONF;
c98c09 ¤   else ids = IDS_REMOVEONLYSUBKEYCONF;
5baf5a
8b90a3 ¤   if (KMMessageBox (hDlg, IDS_CAPTION, ids,·
9eb1c7 ¤   ¤   ¤   MB_YESNO | MB_ICONEXCLAMATION) == IDNO)·
eb98aa ¤   ¤   return FALSE;
58af5a
e1cae4 ¤   iIndex = ListView_GetNextItem (pkmpss->hwndSubKeys, -1, LVNI_SELECTED);
8caf5a
e5352e ¤   if (iIndex > -1) {
264124 ¤   ¤   lvI.mask = LVIF_PARAM;
9325c3 ¤   ¤   lvI.iItem = iIndex;
b697ef ¤   ¤   lvI.iSubItem = 0;
4231bf ¤   ¤   ListView_GetItem (pkmpss->hwndSubKeys, &lvI);
f3af5a
287165 ¤   ¤   psks = (PSUBKEYSTRUCT)(lvI.lParam);
36af5a
3672fa ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
31d200 ¤   ¤   err = PGPRemoveSubKey (psks->subkey);
7d7266 ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
ae67c5 ¤
d83f65 ¤   ¤   if (IsntPGPError (PGPclErrorBox (hDlg, err))) {
250291 ¤   ¤   ¤   pkmpss->bNeedsCommit = TRUE;
60b06c ¤   ¤   ¤   KMFree ((VOID*)lvI.lParam);
543553 ¤   ¤   ¤   ListView_DeleteItem (pkmpss->hwndSubKeys, iIndex);
dc0fe4 ¤   ¤   }
7c9371 ¤   }
69af5a
37c2e7 ¤   return TRUE;
68efe6 }
3faf5a
e3af5a
5f4265 //¤ ___________________________________________________
30465d //
41b54f // ·revoke subkey from listview control
2baf5a
6d6c77 static BOOL·
083f72 sRevokeSubKey (HWND hDlg, KMPROPSHEETSTRUCT* pkmpss)
5abb36 {
c3730f ¤   PGPByte*¤   ¤   pPasskey¤   ¤   ¤   = NULL;
75532a ¤   PGPSize¤¤   ¤   sizePasskey¤¤   ¤   = 0;
33af5a
e60c32 ¤   INT¤¤   ¤   ¤   iIndex;
8982cc ¤   LV_ITEM¤¤   ¤   lvI;
56fb19 ¤   PGPError¤   ¤   err;
cf12ce ¤   PSUBKEYSTRUCT¤  psks;
25195e ¤   CHAR¤   ¤   ¤   sz[64];
8aaf5a
f4b528 ¤   if (KMMessageBox (hDlg, IDS_CAPTION, IDS_REVOKESUBKEYCONF,·
59b1c7 ¤   ¤   ¤   MB_YESNO | MB_ICONEXCLAMATION) == IDNO)·
a298aa ¤   ¤   return FALSE;
e9af5a
d12c48 ¤   // get phrase from user if necessary
791d8b ¤   LoadString (g_hInst, IDS_SELKEYPASSPHRASE, sz, sizeof(sz));·
954e14 ¤   KMRequestSDKAccess (pkmpss->pKM);
bc9c03 ¤   err = KMGetKeyPhrase (pkmpss->pKM->Context, pkmpss->pKM->tlsContext,
3244d2 ¤   ¤   ¤   ¤   ¤   hDlg, sz, pkmpss->keyset, pkmpss->key,
7ca22e ¤   ¤   ¤   ¤   ¤   NULL, &pPasskey, &sizePasskey);
b64e88 ¤   KMReleaseSDKAccess (pkmpss->pKM);
--0ad3 0009dd7bcae401102b2 Page 12 of KMProps.c
2418b2 ¤   PGPclErrorBox (NULL, err);
69af5a
b3b23e ¤   if (IsntPGPError (err)) {
a879a4 ¤   ¤   iIndex = ListView_GetNextItem (pkmpss->hwndSubKeys,·
375e21 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   -1, LVNI_SELECTED);
13d7cf ¤   ¤   if (iIndex > -1) {
fbcd5b ¤   ¤   ¤   lvI.mask = LVIF_PARAM;
aa889d ¤   ¤   ¤   lvI.iItem = iIndex;
301ebb ¤   ¤   ¤   lvI.iSubItem = 0;
7832c8 ¤   ¤   ¤   ListView_GetItem (pkmpss->hwndSubKeys, &lvI);
a3af5a
a96935 ¤   ¤   ¤   psks = (PSUBKEYSTRUCT)(lvI.lParam);
bdaf5a
d94b3f ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
96887f ¤   ¤   ¤   err = PGPRevokeSubKey (psks->subkey,·
7eae24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey ?
8f837a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (pkmpss->pKM->Context,·
e950cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey) :
75a0fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPONullOption (pkmpss->pKM->Context),
d6fd43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pkmpss->pKM->Context));
a54ba3 ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
fbaf5a
7bb032 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (hDlg, err))) {
b80429 ¤   ¤   ¤   ¤   pkmpss->bNeedsCommit = TRUE;
476d78 ¤   ¤   ¤   ¤   lvI.mask = LVIF_IMAGE;
910361 ¤   ¤   ¤   ¤   lvI.iItem = iIndex;
c129b3 ¤   ¤   ¤   ¤   lvI.iSubItem = 0;
cabf8b ¤   ¤   ¤   ¤   lvI.iImage = IDX_DSAPUBREVKEY;
bbd4dd ¤   ¤   ¤   ¤   ListView_SetItem (pkmpss->hwndSubKeys, &lvI);
c8a3a6 ¤   ¤   ¤   }
0e0fe4 ¤   ¤   }
2e9371 ¤   }
dbaf5a
b9a252 ¤   if (pPasskey)·
e40297 ¤   ¤   KMFreePasskey (pPasskey, sizePasskey);
47af5a
b1c2e7 ¤   return TRUE;
95efe6 }
89af5a
48af5a
e44265 //¤ ___________________________________________________
40465d //
4c42aa // ·Populate ListView with subkeys
61af5a
1d6c77 static BOOL·
bf6db6 sInsertSubkeysIntoList (
7845c9 ¤   ¤   HWND¤   ¤   ¤   hwndList,·
fcf9c6 ¤   ¤   PGPKeyRef¤  ¤   key,
ddd026 ¤   ¤   PGPKeySetRef¤   keyset)·
48bb36 {
4c87ac ¤   PGPSubKeyRef¤   subkey;
a6d125 ¤   PGPKeyListRef¤  keylist;
efc323 ¤   PGPKeyIterRef¤  keyiter;
7882cc ¤   LV_ITEM¤¤   ¤   lvI;
274b5b ¤   CHAR¤   ¤   ¤   szSize[16];
3351e5 ¤   CHAR¤   ¤   ¤   szValid[32];
c2a1c5 ¤   CHAR¤   ¤   ¤   szExpires[32];
f6085e ¤   PGPBoolean¤ ¤   bRevoked;
375a9e ¤   PGPBoolean¤ ¤   bExpired;
2c3c53 ¤   INT¤¤   ¤   ¤   iItem;
f03f3b ¤   PGPTime¤¤   ¤   time;
e412ce ¤   PSUBKEYSTRUCT¤  psks;
1eaf5a
a17592 ¤   iItem = 0;
13af5a
b7a8dc ¤   PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
2cf4cc ¤   PGPNewKeyIter (keylist, &keyiter);
89ef9e ¤   PGPKeyIterSeek (keyiter, key);
a4cebc ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
42d751 ¤   while (subkey) {
66af5a
9d4b4c ¤   ¤   // allocate structure to hold info
--87c7 00058baf504401102b2 Page 13 of KMProps.c
974baa ¤   ¤   psks = KMAlloc (sizeof(SUBKEYSTRUCT));
13a92c ¤   ¤   if (!psks) break;
38af5a
cd06ee ¤   ¤   // initialize structure
bd3153 ¤   ¤   psks->subkey = subkey;
c3da56 ¤   ¤   psks->uSize = 0;
24af5a
d94fc1 ¤   ¤   // get subkey info
559137 ¤   ¤   PGPGetSubKeyNumber (subkey, kPGPKeyPropBits, &psks->uSize);
91668c ¤   ¤   wsprintf (szSize, "%i", psks->uSize);
78af5a
c4be93 ¤   ¤   PGPGetSubKeyBoolean (subkey, kPGPKeyPropIsExpired, &bExpired);
86960f ¤   ¤   PGPGetSubKeyBoolean (subkey, kPGPKeyPropIsRevoked, &bRevoked);
74af5a
ca3a1a ¤   ¤   PGPGetSubKeyTime (subkey, kPGPKeyPropCreation, &psks->timeStart);
9a65aa ¤   ¤   KMConvertTimeToString (psks->timeStart, szValid, sizeof (szValid));
4aaf5a
344697 ¤   ¤   PGPGetSubKeyTime (subkey, kPGPKeyPropExpiration, &time);
98e798 ¤   ¤   if (time != kPGPExpirationTime_Never) {
b36625 ¤   ¤   ¤   psks->bNeverExpires = FALSE;
f1a4b6 ¤   ¤   ¤   KMConvertTimeToDays (time, &psks->iExpireDays);
9233f9 ¤   ¤   ¤   KMConvertTimeToString (time, szExpires, sizeof (szExpires));
520fe4 ¤   ¤   }
1907e0 ¤   ¤   else {
15cb05 ¤   ¤   ¤   psks->bNeverExpires = TRUE;
9d4f92 ¤   ¤   ¤   psks->iExpireDays = 0;
d6c460 ¤   ¤   ¤   LoadString (g_hInst, IDS_NEVER, szExpires, sizeof (szExpires));
900fe4 ¤   ¤   }
30af5a
2e173c ¤   ¤   // insert listview item
fae743 ¤   ¤   lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
e64bfb ¤   ¤   lvI.state = 0; ·····
667c11 ¤   ¤   lvI.stateMask = 0;
d4ff6b ¤   ¤   if (bRevoked)·
8d2e13 ¤   ¤   ¤   lvI.iImage = IDX_DSAPUBREVKEY;
082f6d ¤   ¤   else if (bExpired)
7b6a19 ¤   ¤   ¤   lvI.iImage = IDX_DSAPUBEXPKEY;
fd0e1d ¤   ¤   else
8e247a ¤   ¤   ¤   lvI.iImage = IDX_DSAPUBKEY;
faaf5a
998ffb ¤   ¤   lvI.iItem = iItem;
4d97ef ¤   ¤   lvI.iSubItem = 0;
571f98 ¤   ¤   lvI.pszText¤= szValid;·
900ce0 ¤   ¤   lvI.cchTextMax = 0;
eee2e2 ¤   ¤   lvI.lParam = (LPARAM)psks;
e6af5a
c50617 ¤   ¤   if (ListView_InsertItem (hwndList, &lvI) == -1) return FALSE;
11af5a
2cfee7 ¤   ¤   // add strings for other columns
126d8e ¤   ¤   ListView_SetItemText (hwndList, iItem, 1, szExpires);
984950 ¤   ¤   ListView_SetItemText (hwndList, iItem, 2, szSize);
7caf5a
bd9c21 ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
52af5a
58f777 ¤   ¤   iItem++;
2f9371 ¤   }
15af5a
4adee2 ¤   PGPFreeKeyIter (keyiter);
536d4f ¤   PGPFreeKeyList (keylist);
e3af5a
68c2e7 ¤   return TRUE;
a5efe6 }
12af5a
c1af5a
4e4265 //¤ ___________________________________________________
6d465d //
e4ae02 // ·destroy all data structures associated with ListView
26af5a
b2e6b2 static VOID
83f335 sDestroySubKeyListAndStructures (KMPROPSHEETSTRUCT* pkmpss)
75bb36 {
58104b ¤   INT¤¤   iIndex;
--30e6 000f0ad780b401102b2 Page 14 of KMProps.c
b92ff0 ¤   INT¤¤   iNumItems;
6611d1 ¤   LV_ITEM¤lvI;
50af5a
f8a5e8 ¤   iNumItems = ListView_GetItemCount (pkmpss->hwndSubKeys);
9d0560 ¤   for (iIndex=0; iIndex<iNumItems; iIndex++) {
1c4124 ¤   ¤   lvI.mask = LVIF_PARAM;
c725c3 ¤   ¤   lvI.iItem = iIndex;
c397ef ¤   ¤   lvI.iSubItem = 0;
8431bf ¤   ¤   ListView_GetItem (pkmpss->hwndSubKeys, &lvI);
9f68dc ¤   ¤   KMFree ((VOID*)(lvI.lParam));
609371 ¤   }
70af5a
5ff7c1 ¤   ListView_DeleteAllItems (pkmpss->hwndSubKeys);
d9af5a
e3b9b8 ¤   ImageList_Destroy (pkmpss->hIml);
4defe6 }
efaf5a
50af5a
3b4265 //¤ ___________________________________________________
f1465d //
9bbec2 // ·setup subkey ListView·
97af5a
c8b333 static VOID·
dd991e sFillSubKeyList (HWND hDlg, KMPROPSHEETSTRUCT* pkmpss)·
66bb36 {
8caf5a
42c89d ¤   LV_COLUMN¤  lvC;·
3ecdba ¤   CHAR¤   ¤   sz[256];
cbf493 ¤   HBITMAP¤¤   hBmp;
4e18a8 ¤   HDC¤¤   ¤   hDC;
de0863 ¤   INT¤¤   ¤   iNumBits;
38af5a
4b4f7a ¤   // create image list
257f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
c389fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
f8e693 ¤   ReleaseDC (NULL, hDC);
79af5a
1903bc ¤   if (!pkmpss->hIml) {
c81fb9 ¤   ¤   if (iNumBits <= 8) {
19c638 ¤   ¤   ¤   pkmpss->hIml = ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
128f86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
de463f ¤   ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
ac526d ¤   ¤   ¤   ImageList_AddMasked (pkmpss->hIml, hBmp, RGB(255, 0, 255));
6ce7db ¤   ¤   ¤   DeleteObject (hBmp);
b50fe4 ¤   ¤   }
4807e0 ¤   ¤   else {
b17c3a ¤   ¤   ¤   pkmpss->hIml = ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
1e8f86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
6ba082 ¤   ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
dd526d ¤   ¤   ¤   ImageList_AddMasked (pkmpss->hIml, hBmp, RGB(255, 0, 255));
4ae7db ¤   ¤   ¤   DeleteObject (hBmp);
370fe4 ¤   ¤   }
1c9371 ¤   }
e3af5a
f53a00 ¤   ListView_SetImageList (pkmpss->hwndSubKeys, pkmpss->hIml, LVSIL_SMALL);
a9af5a
4b3e53 ¤   lvC.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
ee71b8 ¤   lvC.fmt = LVCFMT_CENTER;·
3434b0 ¤   lvC.pszText = sz;
9767c5 ¤
5fb890 ¤   LoadString (g_hInst, IDS_VALIDFROM, sz, sizeof(sz));
bdb88f ¤   lvC.cx = 120; ·
3d14af ¤   lvC.iSubItem = 0;
4ee473 ¤   if (ListView_InsertColumn (pkmpss->hwndSubKeys, 0, &lvC) == -1) return;
77af5a
7022aa ¤   LoadString (g_hInst, IDS_EXPIRES, sz, sizeof(sz));
0aa930 ¤   lvC.cx = 70; ··
bb4e73 ¤   lvC.iSubItem = 1;
7bbf37 ¤   if (ListView_InsertColumn (pkmpss->hwndSubKeys, 1, &lvC) == -1) return;
c7af5a
1474c2 ¤   LoadString (g_hInst, IDS_SIZE, sz, sizeof(sz));
f0a930 ¤   lvC.cx = 70; ··
--65b4 000dc7c3165401102b2 Page 15 of KMProps.c
f0a117 ¤   lvC.iSubItem = 2;
2752fb ¤   if (ListView_InsertColumn (pkmpss->hwndSubKeys, 2, &lvC) == -1) return;
62af5a
e1cedf ¤   // populate control by iterating through subkeys
21ee95 ¤   sInsertSubkeysIntoList (pkmpss->hwndSubKeys, pkmpss->key,·
edd5ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->keyset);
39efe6 }
7faf5a
65af5a
9c4265 //¤ ___________________________________________________
93465d //
01a0c6 // ·Key Properties Dialog Message procedure - subkey panel
2daf5a
803f64 static BOOL CALLBACK·
48f008 sKeyPropDlgProcSubkey (
893a3a ¤   ¤   HWND¤   hDlg,·
5beb77 ¤   ¤   UINT¤   uMsg,·
250303 ¤   ¤   WPARAM¤ wParam,
a5c0b8 ¤   ¤   LPARAM¤ lParam)·
78bb36 {
1091a6 ¤   KMPROPSHEETSTRUCT*¤ pkmpss;
8dc613 ¤   INT¤¤   ¤   ¤   ¤   iIndex;
3713fa ¤   NMHDR*¤ ¤   ¤   ¤   pnmh;
4daf5a
a5b32f ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
5eaf5a
76347f ¤   switch (uMsg) {
41af5a
f72940 ¤   case WM_INITDIALOG:
4dc72a ¤   ¤   // store pointer to data structure
57fe01 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, ((PROPSHEETPAGE*)lParam)->lParam);
b6b459 ¤   ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
a0bd4a ¤   ¤   pkmpss->hwndSubKeys = GetDlgItem (hDlg, IDC_SUBKEYLIST);
daaf5a
cd7f90 ¤   ¤   // hide explanatory text for non-keypairs
c3f866 ¤   ¤   if (!pkmpss->bSecret) {
20ca27 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATICTEXT1), SW_HIDE);
bf4919 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATICTEXT2), SW_HIDE);
860fe4 ¤   ¤   }
dbaf5a
c1a54c ¤   ¤   // initialize all controls
7a9370 ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
b7836c ¤   ¤   return TRUE;
60af5a
5a5020 ¤   case WM_APP :
6edb8f ¤   ¤   if (wParam == SERIALIZE)
194b3f ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
3f3fa0 ¤   ¤   sFillSubKeyList (hDlg, pkmpss);
4cdb8f ¤   ¤   if (wParam == SERIALIZE)
c74ba3 ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
6a85c8 ¤   ¤   if (pkmpss->bKeyGenEnabled) {
f057c8 ¤   ¤   ¤   if (pkmpss->bSecret && !pkmpss->bRevoked &&·
220069 ¤   ¤   ¤   ¤   ¤   !pkmpss->bExpired && !pkmpss->bReadOnly)
481f2b ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_NEWSUBKEY), TRUE);
400fe4 ¤   ¤   }
5d2f68 ¤   ¤   break;
fbaf5a
543fcf ¤   case WM_COMMAND:
b8379d ¤   ¤   switch(LOWORD (wParam)) {
37b51d ¤   ¤   case IDC_NEWSUBKEY :
5f897d ¤   ¤   ¤   DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_NEWSUBKEY),·
1f9460 ¤   ¤   ¤   ¤   ¤   ¤   hDlg, sNewSubkeyDlgProc, (LPARAM)pkmpss);
4ccdcb ¤   ¤   ¤   break;
40af5a
15dc0f ¤   ¤   case IDC_REVOKESUBKEY :
7d1067 ¤   ¤   ¤   if (sRevokeSubKey (hDlg, pkmpss)) {
c382ea ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_REVOKESUBKEY), FALSE);
230e96 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_REMOVESUBKEY), FALSE);
9ea3a6 ¤   ¤   ¤   }
dacdcb ¤   ¤   ¤   break;
47af5a
dc636b ¤   ¤   case IDC_REMOVESUBKEY :
--9735 000a2aa322f401102b2 Page 16 of KMProps.c
f194fb ¤   ¤   ¤   if (sRemoveSubKey (hDlg, pkmpss)) {
8682ea ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_REVOKESUBKEY), FALSE);
300e96 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_REMOVESUBKEY), FALSE);
3aa3a6 ¤   ¤   ¤   }
56cdcb ¤   ¤   ¤   break;
be0fe4 ¤   ¤   }
8a836c ¤   ¤   return TRUE;
3faf5a
e3c3eb ····case WM_HELP:·
a8638a ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pkmpss->pKM->szHelpFile,·
d87f81 ············HELP_WM_HELP, (DWORD) (LPSTR) aSubkeyIds);·
4e8f13 ········break;·
d3d83c ·
374fd8 ····case WM_CONTEXTMENU:·
6f5409 ········WinHelp ((HWND) wParam, pkmpss->pKM->szHelpFile, HELP_CONTEXTMENU,·
387f51 ············(DWORD) (LPVOID) aSubkeyIds);·
0b8f13 ········break;·
4caf5a
c86334 ¤   case WM_DESTROY :
e38eca ¤   ¤   sDestroySubKeyListAndStructures (pkmpss);
132f68 ¤   ¤   break;
63af5a
441431 ¤   case WM_NOTIFY :
c6dd21 ¤   ¤   pnmh = (NMHDR*)lParam;
dad254 ¤   ¤   switch (pnmh->code) {
42a305 //¤ ¤   case PSN_SETACTIVE :
76309a //¤ ¤   ¤   break;
b1af5a
288074 //¤ ¤   case PSN_APPLY :
4e9dd9 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
bc9525 //¤ ¤   ¤   return TRUE;
42af5a
e21b03 ¤   ¤   case PSN_HELP :
f3df94 ¤   ¤   ¤   WinHelp (hDlg, pkmpss->pKM->szHelpFile, HELP_CONTEXT,·
e52e96 ¤   ¤   ¤   ¤   IDH_PGPKM_PROPDIALOG);·
57cdcb ¤   ¤   ¤   break;
1eaf5a
f21e4a //¤ ¤   case PSN_KILLACTIVE :
69ccd4 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
d79525 //¤ ¤   ¤   return TRUE;
4eaf5a
8f958b ¤   ¤   case NM_CLICK :
62c191 ¤   ¤   case LVN_KEYDOWN :
a1a12b ¤   ¤   ¤   if ((pnmh->idFrom == IDC_SUBKEYLIST) &&·
431f12 ¤   ¤   ¤   ¤   ·pkmpss->bSecret &&
3a5602 ¤   ¤   ¤   ¤   !pkmpss->bReadOnly)·
6ef776 ¤   ¤   ¤   {
9d62e8 ¤   ¤   ¤   ¤   iIndex =·
86fabe ¤   ¤   ¤   ¤   ¤   ListView_GetNextItem (pkmpss->hwndSubKeys,
9bf22d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   -1, LVNI_SELECTED);
ed4f98 ¤   ¤   ¤   ¤   if (iIndex > -1) {
687b8e ¤   ¤   ¤   ¤   ¤   LV_ITEM lvI;
34af5a
ede60d ¤   ¤   ¤   ¤   ¤   lvI.mask = LVIF_IMAGE|LVIF_PARAM;
eac634 ¤   ¤   ¤   ¤   ¤   lvI.iItem = iIndex;
bec6c0 ¤   ¤   ¤   ¤   ¤   lvI.iSubItem = 0;
2dade2 ¤   ¤   ¤   ¤   ¤   ListView_GetItem(pkmpss->hwndSubKeys, &lvI);
67e688 ¤   ¤   ¤   ¤   ¤   if ((lvI.iImage == IDX_DSAPUBKEY) && (pkmpss->bSecret))
1ea2d5 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (
662cf0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_REVOKESUBKEY), TRUE);
a04bd6 ¤   ¤   ¤   ¤   ¤   else
29a2d5 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (
5efa3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg,IDC_REVOKESUBKEY), FALSE);
53af5a
385b4a ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg,IDC_REMOVESUBKEY), TRUE);
5f2613 ¤   ¤   ¤   ¤   }
8edeaa ¤   ¤   ¤   ¤   else {
e5fa0f ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg,IDC_REVOKESUBKEY), FALSE);
7c7673 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg,IDC_REMOVESUBKEY), FALSE);
322613 ¤   ¤   ¤   ¤   }
12a3a6 ¤   ¤   ¤   }
a2cdcb ¤   ¤   ¤   break;
--12de 00038ce5d82401102b2 Page 17 of KMProps.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
6aa230 ¤   return FALSE;
4eefe6 }
21af5a
034265 //¤ ___________________________________________________
66465d //
036474 // ·Populate ListView with ADKs
cdaf5a
94b333 static VOID·
25aeee sInsertADKsIntoTree (
a99283 ¤   ¤   PKEYMAN¤¤   ¤   pKM,
9711bb ¤   ¤   HWND¤   ¤   ¤   hwndTree,·
72f9c6 ¤   ¤   PGPKeyRef¤  ¤   key,
f28b6a ¤   ¤   PGPKeySetRef¤   keyset,
606f7b ¤   ¤   UINT¤   ¤   ¤   uNumberADKs)·
96bb36 {
ba4aea ¤   TL_TREEITEM¤¤   tlI;
33b50a ¤   TL_LISTITEM¤¤   tlL;
ece1c1 ¤   TL_INSERTSTRUCT tlIns;
bab5c5 ¤   HTLITEM¤¤   ¤   hTNew;
a86dbf ¤   PGPKeyRef¤  ¤   keyADK;
3bd994 ¤   PGPKeyID¤   ¤   keyidADK;
d1ce9d ¤   CHAR¤   ¤   ¤   szName[256];
84fb19 ¤   PGPError¤   ¤   err;
81ce12 ¤   CHAR¤   ¤   ¤   szID[kPGPMaxKeyIDStringSize];
0b6e76 ¤   UINT¤   ¤   ¤   u;
227c93 ¤   PGPByte¤¤   ¤   byteClass;
544866 ¤   BOOL¤   ¤   ¤   bItalics;
fdaf5a
a078ca ¤   tlI.hItem = NULL;
afaee0 ¤   tlI.mask = TLIF_TEXT | TLIF_IMAGE | TLIF_STATE;
7455eb ¤   tlI.stateMask = TLIS_ITALICS;
8b08b7 ¤   tlI.pszText = szName;
78af5a
51d8f9 ¤   for (u=0; u<uNumberADKs; u++) {
a97114 ¤   ¤   byteClass = 0;
72b8bc ¤   ¤   tlI.iImage = IDX_DSAPUBDISKEY;
196244 ¤   ¤   tlI.state = 0;
5caf5a
61622a ¤   ¤   err = PGPGetIndexedAdditionalRecipientRequestKey (key,·
88239d ¤   ¤   ¤   ¤   keyset, u, &keyADK, &keyidADK, &byteClass);
8faf5a
c2717c ¤   ¤   if (IsntPGPError (err)) {·
9faf5a
7486cf ¤   ¤   ¤   if (PGPKeyRefIsValid (keyADK)) {
2d5302 ¤   ¤   ¤   ¤   KMGetKeyName (keyADK, szName, sizeof(szName));
f07daa ¤   ¤   ¤   ¤   tlI.iImage = KMDetermineKeyIcon (pKM, keyADK, &bItalics);
fbd508 ¤   ¤   ¤   ¤   if (bItalics) tlI.state = TLIS_ITALICS;
f3a3a6 ¤   ¤   ¤   }
a3e543 ¤   ¤   ¤   else {
807dd0 ¤   ¤   ¤   ¤   tlI.state = TLIS_ITALICS;
acaf5a
a2b1c2 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWNADK,·
56ba17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szName, sizeof(szName));
cbdd83 ¤   ¤   ¤   ¤   err = PGPGetKeyIDString (&keyidADK,·
401512 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyIDString_Abbreviated, szID);
3956ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
320a90 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWNADKID,·
e2ba17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szName, sizeof(szName));
32f5a3 ¤   ¤   ¤   ¤   ¤   lstrcat (szName, szID);
712613 ¤   ¤   ¤   ¤   }
1fa3a6 ¤   ¤   ¤   }
b20fe4 ¤   ¤   }
cdaf5a
b007e0 ¤   ¤   else {
3f2454 ¤   ¤   ¤   LoadString (g_hInst, IDS_ERRONEOUSADK, szName, sizeof(szName));
810fe4 ¤   ¤   }
01af5a
9c55e8 ¤   ¤   tlI.cchTextMax = lstrlen (szName);
bbd42f ¤   ¤   tlIns.hInsertAfter = (HTLITEM)TLI_SORT;
3870a5 ¤   ¤   tlIns.item = tlI;
--3b0f 0009d5c54ed401102b2 Page 18 of KMProps.c
fbf003 ¤   ¤   tlIns.hParent = NULL;
08b302 ¤   ¤   hTNew = TreeList_InsertItem (hwndTree, &tlIns);
21af5a
81d960 ¤   ¤   tlL.pszText = NULL;
bf27d4 ¤   ¤   tlL.hItem = hTNew;
7dec78 ¤   ¤   tlL.stateMask = TLIS_VISIBLE;
e4ca06 ¤   ¤   tlL.iSubItem = 1;
1bd2a3 ¤   ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
2228bd ¤   ¤   tlL.state = TLIS_VISIBLE;
b4af5a
e5c68d ¤   ¤   if (byteClass & 0x80) tlL.lDataValue = IDX_ADK;
6ed9fe ¤   ¤   else tlL.lDataValue = IDX_NOADK;
7caf5a
85939d ¤   ¤   TreeList_SetListItem (hwndTree, &tlL, FALSE);
0e9371 ¤   }
e5efe6 }
13af5a
4eaf5a
013fc0 //¤ _____________________________________________________
2e465d //
d33e91 // ·add columns to treelist
bdaf5a
946c77 static BOOL·
8b429a sAddADKColumns (HWND hWndTree, INT iWidth) {
b07894 ¤   TL_COLUMN tlc;
97f61c ¤   CHAR sz[64];
56af5a
767a7a ¤   TreeList_DeleteAllColumns (hWndTree);
b4af5a
8b43d5 ¤   tlc.mask = TLCF_FMT | TLCF_WIDTH | TLCF_TEXT |·
315f34 ¤   ¤   ¤   ¤   TLCF_SUBITEM | TLCF_DATATYPE | TLCF_DATAMAX;
7ddef6 ¤   tlc.pszText = sz;
31af5a
e8fee9 ¤   tlc.iSubItem = 0;
a9b741 ¤   tlc.fmt = TLCFMT_LEFT;
01737a ¤   tlc.iDataType = TLC_DATASTRING;
bb6b43 ¤   tlc.cx = iWidth - ENFORCELISTWIDTH - 20;
088305 ¤   tlc.bMouseNotify = FALSE;
3d3468 ¤   LoadString (g_hInst, IDS_NAMEFIELD, sz, sizeof(sz));
5e6e63 ¤   TreeList_InsertColumn (hWndTree, 0, &tlc);
99af5a
2bc492 ¤   tlc.fmt = TLCFMT_IMAGE;
247ae7 ¤   tlc.iDataType = TLC_DATALONG;
fbfd8f ¤   tlc.cx = ENFORCELISTWIDTH;
178305 ¤   tlc.bMouseNotify = FALSE;
245ef9 ¤   LoadString (g_hInst, IDS_ENFORCEFIELD, sz, sizeof(sz));
aa4244 ¤   TreeList_InsertColumn (hWndTree, 1, &tlc);
25af5a
76c2e7 ¤   return TRUE;
ddefe6 }
4eaf5a
b1af5a
6d4265 //¤ ___________________________________________________
6e465d //
182035 // ·Key Properties Dialog Message procedure - ADK panel
81af5a
be3f64 static BOOL CALLBACK·
54eca5 sKeyPropDlgProcADK (
263a3a ¤   ¤   HWND¤   hDlg,·
88eb77 ¤   ¤   UINT¤   uMsg,·
b20303 ¤   ¤   WPARAM¤ wParam,
72c0b8 ¤   ¤   LPARAM¤ lParam)·
ecbb36 {
0491a6 ¤   KMPROPSHEETSTRUCT*¤ pkmpss;
c982e0 ¤   HBITMAP¤¤   ¤   ¤   hBmp;
e0f18e ¤   HDC¤¤   ¤   ¤   ¤   hDC;
0e2b61 ¤   INT¤¤   ¤   ¤   ¤   iNumBits;
e8b996 ¤   RECT¤   ¤   ¤   ¤   rc;
5caf5a
76b32f ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
72af5a
9d347f ¤   switch (uMsg) {
--5666 0004ee38992401102b2 Page 19 of KMProps.c
e0af5a
0b2940 ¤   case WM_INITDIALOG:
dcc72a ¤   ¤   // store pointer to data structure
9bfe01 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, ((PROPSHEETPAGE*)lParam)->lParam);
4db459 ¤   ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
b9af5a
569e46 ¤   ¤   // create tree view window
c4ab7d ¤   ¤   GetClientRect (GetDlgItem (hDlg, IDC_FRAME), &rc);
335a80 ¤   ¤   rc.left += 8;
8af0a4 ¤   ¤   rc.right -= 8;
19fe29 ¤   ¤   rc.top += 16;
0ede51 ¤   ¤   rc.bottom -= 8;
89af5a
5429e2 ¤   ¤   pkmpss->hwndADKs = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREELIST, "",
7463f8 ¤   ¤   ¤   WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_GROUP |
518f8e ¤   ¤   ¤   TLS_AUTOSCROLL | TLS_SINGLESELECT,
691056 ¤   ¤   ¤   rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
1d846d ¤   ¤   ¤   GetDlgItem (hDlg, IDC_FRAME),·
116807 ¤   ¤   ¤   (HMENU)IDC_ADKTREELIST, g_hInst, NULL);
eeaf5a
177b27 ¤   ¤   // create image list
4b3060 ¤   ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
0e1743 ¤   ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) *·
063726 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDeviceCaps (hDC, PLANES);
b6f2bb ¤   ¤   ReleaseDC (NULL, hDC);
72af5a
6337e1 ¤   ¤   if (!pkmpss->hIml) {
9ca4ef ¤   ¤   ¤   if (iNumBits <= 8) {
4ccbdd ¤   ¤   ¤   ¤   pkmpss->hIml = ImageList_Create (16, 16,·
27c138 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILC_COLOR|ILC_MASK, NUM_BITMAPS, 0);·
f1600b ¤   ¤   ¤   ¤   hBmp = LoadBitmap (g_hInst,·
563a4c ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_IMAGES4BIT));
7f4964 ¤   ¤   ¤   ¤   ImageList_AddMasked (pkmpss->hIml, hBmp, RGB(255, 0, 255));
50dab3 ¤   ¤   ¤   ¤   DeleteObject (hBmp);
6da3a6 ¤   ¤   ¤   }
0ee543 ¤   ¤   ¤   else {
2fcbdd ¤   ¤   ¤   ¤   pkmpss->hIml = ImageList_Create (16, 16,·
b10e01 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILC_COLOR24|ILC_MASK, NUM_BITMAPS, 0);·
3d600b ¤   ¤   ¤   ¤   hBmp = LoadBitmap (g_hInst,·
1be1e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_IMAGES24BIT));
7f4964 ¤   ¤   ¤   ¤   ImageList_AddMasked (pkmpss->hIml, hBmp, RGB(255, 0, 255));
4ddab3 ¤   ¤   ¤   ¤   DeleteObject (hBmp);
47a3a6 ¤   ¤   ¤   }
c93b90 ¤   ¤   }¤
176744 ¤   ¤   TreeList_SetImageList (pkmpss->hwndADKs, pkmpss->hIml);
d5084c ¤   ¤   sAddADKColumns (pkmpss->hwndADKs, rc.right-rc.left);
25af5a
3da54c ¤   ¤   // initialize all controls
5a9370 ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
5e836c ¤   ¤   return TRUE;
e8af5a
3b5020 ¤   case WM_APP :
1edb8f ¤   ¤   if (wParam == SERIALIZE)
8a4b3f ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
720266 ¤   ¤   TreeList_DeleteTree (pkmpss->hwndADKs, TRUE);
97af1e ¤   ¤   sInsertADKsIntoTree (pkmpss->pKM, pkmpss->hwndADKs, pkmpss->key,·
d6a9e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->keyset, pkmpss->uNumberADKs);
cadb8f ¤   ¤   if (wParam == SERIALIZE)
944ba3 ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
d72f68 ¤   ¤   break;
4baf5a
1bc3eb ····case WM_HELP:·
bf638a ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pkmpss->pKM->szHelpFile,·
e24cf0 ············HELP_WM_HELP, (DWORD) (LPSTR) aADKIds);·
0a8f13 ········break;·
4fd83c ·
6d4fd8 ····case WM_CONTEXTMENU:·
5c5409 ········WinHelp ((HWND) wParam, pkmpss->pKM->szHelpFile, HELP_CONTEXTMENU,·
9e31c8 ············(DWORD) (LPVOID) aADKIds);·
b48f13 ········break;·
64af5a
4e1431 ¤   case WM_NOTIFY :
--76b2 000075cc49f401102b2 Page 20 of KMProps.c
b40f7c ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
18a305 //¤ ¤   case PSN_SETACTIVE :
82309a //¤ ¤   ¤   break;
ebaf5a
428074 //¤ ¤   case PSN_APPLY :
149dd9 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
c59525 //¤ ¤   ¤   return TRUE;
4caf5a
a61b03 ¤   ¤   case PSN_HELP :
45df94 ¤   ¤   ¤   WinHelp (hDlg, pkmpss->pKM->szHelpFile, HELP_CONTEXT,·
672e96 ¤   ¤   ¤   ¤   IDH_PGPKM_PROPDIALOG);·
36cdcb ¤   ¤   ¤   break;
e1af5a
7d1e4a //¤ ¤   case PSN_KILLACTIVE :
34ccd4 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
059525 //¤ ¤   ¤   return TRUE;
2d0fe4 ¤   ¤   }
0a9371 ¤   }
35a230 ¤   return FALSE;
d3efe6 }
2aaf5a
40af5a
9d4265 //¤ ___________________________________________________
64465d //
c68fad // ·Populate ListView with Designated Revokers
51af5a
22b333 static VOID·
354c58 sInsertRevokersIntoTree (
6c9283 ¤   ¤   PKEYMAN¤¤   ¤   pKM,
2e11bb ¤   ¤   HWND¤   ¤   ¤   hwndTree,·
e1f9c6 ¤   ¤   PGPKeyRef¤  ¤   key,
358b6a ¤   ¤   PGPKeySetRef¤   keyset,
2975b1 ¤   ¤   UINT¤   ¤   ¤   uNumberRevokers)·
23bb36 {
2a4aea ¤   TL_TREEITEM¤¤   tlI;
4de1c1 ¤   TL_INSERTSTRUCT tlIns;
d5b5c5 ¤   HTLITEM¤¤   ¤   hTNew;
d80a37 ¤   PGPKeyRef¤  ¤   keyRevoker;
c2ac52 ¤   PGPKeyID¤   ¤   keyidRevoker;
6ace9d ¤   CHAR¤   ¤   ¤   szName[256];
bffb19 ¤   PGPError¤   ¤   err;
c3ce12 ¤   CHAR¤   ¤   ¤   szID[kPGPMaxKeyIDStringSize];
d96e76 ¤   UINT¤   ¤   ¤   u;
c84866 ¤   BOOL¤   ¤   ¤   bItalics;
8faf5a
6678ca ¤   tlI.hItem = NULL;
05aee0 ¤   tlI.mask = TLIF_TEXT | TLIF_IMAGE | TLIF_STATE;
5c55eb ¤   tlI.stateMask = TLIS_ITALICS;
0108b7 ¤   tlI.pszText = szName;
4faf5a
1dbee3 ¤   for (u=0; u<uNumberRevokers; u++) {
5aaf5a
45b8bc ¤   ¤   tlI.iImage = IDX_DSAPUBDISKEY;
3a6244 ¤   ¤   tlI.state = 0;
dfaf5a
22c3be ¤   ¤   err = PGPGetIndexedRevocationKey (key,·
ed6424 ¤   ¤   ¤   ¤   keyset, u, &keyRevoker, &keyidRevoker);
7eaf5a
24717c ¤   ¤   if (IsntPGPError (err)) {·
c1af5a
6674c0 ¤   ¤   ¤   if (!PGPKeyRefIsValid (keyRevoker)) {
990f3d ¤   ¤   ¤   ¤   // currently only DH/DSS designated revokers are allowed
e670b4 ¤   ¤   ¤   ¤   // so we assume that's what it is
ac5888 ¤   ¤   ¤   ¤   err = PGPGetKeyByKeyID (pKM->KeySetMain, &keyidRevoker,
2ea53d ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_DSA, &keyRevoker);
79a3a6 ¤   ¤   ¤   }
b9af5a
b87019 ¤   ¤   ¤   if (PGPKeyRefIsValid (keyRevoker)) {
e330e7 ¤   ¤   ¤   ¤   KMGetKeyName (keyRevoker, szName, sizeof(szName));
f274f4 ¤   ¤   ¤   ¤   tlI.iImage = KMDetermineKeyIcon (pKM, keyRevoker, &bItalics);
87d508 ¤   ¤   ¤   ¤   if (bItalics) tlI.state = TLIS_ITALICS;
07a3a6 ¤   ¤   ¤   }
--3dbc 000831fc011401102b2 Page 21 of KMProps.c
6ee543 ¤   ¤   ¤   else {
d27dd0 ¤   ¤   ¤   ¤   tlI.state = TLIS_ITALICS;
99af5a
f9b1c2 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWNADK,·
fbba17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szName, sizeof(szName));
0afefe ¤   ¤   ¤   ¤   err = PGPGetKeyIDString (&keyidRevoker,·
2e1512 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyIDString_Abbreviated, szID);
0b56ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
f30a90 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWNADKID,·
45ba17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szName, sizeof(szName));
8ef5a3 ¤   ¤   ¤   ¤   ¤   lstrcat (szName, szID);
002613 ¤   ¤   ¤   ¤   }
39a3a6 ¤   ¤   ¤   }
d20fe4 ¤   ¤   }
ccaf5a
8107e0 ¤   ¤   else {
d3aa55 ¤   ¤   ¤   LoadString (g_hInst, IDS_ERRONEOUSREVOKER,·
b3ba17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szName, sizeof(szName));
070fe4 ¤   ¤   }
1faf5a
c055e8 ¤   ¤   tlI.cchTextMax = lstrlen (szName);
9fd42f ¤   ¤   tlIns.hInsertAfter = (HTLITEM)TLI_SORT;
b170a5 ¤   ¤   tlIns.item = tlI;
d1f003 ¤   ¤   tlIns.hParent = NULL;
95af5a
e8b302 ¤   ¤   hTNew = TreeList_InsertItem (hwndTree, &tlIns);
49af5a
6b9371 ¤   }
68efe6 }
78af5a
e2af5a
a93fc0 //¤ _____________________________________________________
9d465d //
4e3e91 // ·add columns to treelist
53af5a
596c77 static BOOL·
2b5ed1 sAddRevokerColumns (HWND hWndTree, INT iWidth) {
0e7894 ¤   TL_COLUMN tlc;
9bf61c ¤   CHAR sz[64];
7baf5a
347a7a ¤   TreeList_DeleteAllColumns (hWndTree);
f7af5a
f543d5 ¤   tlc.mask = TLCF_FMT | TLCF_WIDTH | TLCF_TEXT |·
bf5f34 ¤   ¤   ¤   ¤   TLCF_SUBITEM | TLCF_DATATYPE | TLCF_DATAMAX;
91def6 ¤   tlc.pszText = sz;
0daf5a
fefee9 ¤   tlc.iSubItem = 0;
35b741 ¤   tlc.fmt = TLCFMT_LEFT;
f1737a ¤   tlc.iDataType = TLC_DATASTRING;
d5c2d9 ¤   tlc.cx = iWidth - 8;
558305 ¤   tlc.bMouseNotify = FALSE;
d23468 ¤   LoadString (g_hInst, IDS_NAMEFIELD, sz, sizeof(sz));
ec6e63 ¤   TreeList_InsertColumn (hWndTree, 0, &tlc);
66af5a
27c2e7 ¤   return TRUE;
a6efe6 }
6daf5a
80af5a
154265 //¤ ___________________________________________________
24465d //
e5f023 // ·Key Properties Dialog Message procedure - Revokers panel
34af5a
6f3f64 static BOOL CALLBACK·
6bd947 sKeyPropDlgProcRevokers (
fc3a3a ¤   ¤   HWND¤   hDlg,·
9deb77 ¤   ¤   UINT¤   uMsg,·
100303 ¤   ¤   WPARAM¤ wParam,
bbc0b8 ¤   ¤   LPARAM¤ lParam)·
37bb36 {
1691a6 ¤   KMPROPSHEETSTRUCT*¤ pkmpss;
5682e0 ¤   HBITMAP¤¤   ¤   ¤   hBmp;
83f18e ¤   HDC¤¤   ¤   ¤   ¤   hDC;
--8d29 000fb8e2f71401102b2 Page 22 of KMProps.c
292b61 ¤   INT¤¤   ¤   ¤   ¤   iNumBits;
b0b996 ¤   RECT¤   ¤   ¤   ¤   rc;
1caf5a
47b32f ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
e2af5a
ae347f ¤   switch (uMsg) {
62af5a
3a2940 ¤   case WM_INITDIALOG:
7bc72a ¤   ¤   // store pointer to data structure
49fe01 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, ((PROPSHEETPAGE*)lParam)->lParam);
4ab459 ¤   ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
29033f ¤   ¤   pkmpss->hwndRevokerDlg = hDlg;
06af5a
7f9e46 ¤   ¤   // create tree view window
dfab7d ¤   ¤   GetClientRect (GetDlgItem (hDlg, IDC_FRAME), &rc);
865a80 ¤   ¤   rc.left += 8;
44f0a4 ¤   ¤   rc.right -= 8;
78fe29 ¤   ¤   rc.top += 16;
5cde51 ¤   ¤   rc.bottom -= 8;
32af5a
cd8adf ¤   ¤   pkmpss->hwndRevokers = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREELIST,
697548 ¤   ¤   ¤   "", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_GROUP |
438f8e ¤   ¤   ¤   TLS_AUTOSCROLL | TLS_SINGLESELECT,
621056 ¤   ¤   ¤   rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
0b846d ¤   ¤   ¤   GetDlgItem (hDlg, IDC_FRAME),·
5446c9 ¤   ¤   ¤   (HMENU)IDC_REVOKERTREELIST, g_hInst, NULL);
90af5a
ac7b27 ¤   ¤   // create image list
0f3060 ¤   ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
3d1743 ¤   ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) *·
d03726 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDeviceCaps (hDC, PLANES);
09f2bb ¤   ¤   ReleaseDC (NULL, hDC);
5aaf5a
7937e1 ¤   ¤   if (!pkmpss->hIml) {
40a4ef ¤   ¤   ¤   if (iNumBits <= 8) {
5ccbdd ¤   ¤   ¤   ¤   pkmpss->hIml = ImageList_Create (16, 16,·
3ac138 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILC_COLOR|ILC_MASK, NUM_BITMAPS, 0);·
50600b ¤   ¤   ¤   ¤   hBmp = LoadBitmap (g_hInst,·
3e3a4c ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_IMAGES4BIT));
9f4964 ¤   ¤   ¤   ¤   ImageList_AddMasked (pkmpss->hIml, hBmp, RGB(255, 0, 255));
d6dab3 ¤   ¤   ¤   ¤   DeleteObject (hBmp);
64a3a6 ¤   ¤   ¤   }
ffe543 ¤   ¤   ¤   else {
50cbdd ¤   ¤   ¤   ¤   pkmpss->hIml = ImageList_Create (16, 16,·
ec0e01 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILC_COLOR24|ILC_MASK, NUM_BITMAPS, 0);·
63600b ¤   ¤   ¤   ¤   hBmp = LoadBitmap (g_hInst,·
04e1e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDB_IMAGES24BIT));
854964 ¤   ¤   ¤   ¤   ImageList_AddMasked (pkmpss->hIml, hBmp, RGB(255, 0, 255));
6edab3 ¤   ¤   ¤   ¤   DeleteObject (hBmp);
73a3a6 ¤   ¤   ¤   }
d13b90 ¤   ¤   }¤
dbb487 ¤   ¤   TreeList_SetImageList (pkmpss->hwndRevokers, pkmpss->hIml);
0f337b ¤   ¤   sAddRevokerColumns (pkmpss->hwndRevokers, rc.right-rc.left);
12af5a
eba54c ¤   ¤   // initialize all controls
fa9370 ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
2c836c ¤   ¤   return TRUE;
b5af5a
135020 ¤   case WM_APP :
5edb8f ¤   ¤   if (wParam == SERIALIZE)
a24b3f ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
60b59b ¤   ¤   TreeList_DeleteTree (pkmpss->hwndRevokers, TRUE);
3fa1a6 ¤   ¤   PGPCountRevocationKeys (pkmpss->key, &pkmpss->uNumberRevokers);
43358f ¤   ¤   sInsertRevokersIntoTree (pkmpss->pKM, pkmpss->hwndRevokers,·
ee5a48 ¤   ¤   ¤   ¤   ¤   pkmpss->key, pkmpss->keyset, pkmpss->uNumberRevokers);
ffdb8f ¤   ¤   if (wParam == SERIALIZE)
934ba3 ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
6a2f68 ¤   ¤   break;
75af5a
88c3eb ····case WM_HELP:·
b6638a ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pkmpss->pKM->szHelpFile,·
fbd728 ············HELP_WM_HELP, (DWORD) (LPSTR) aRevokerIds);·
--f6b1 000230263c4401102b2 Page 23 of KMProps.c
728f13 ········break;·
fbd83c ·
554fd8 ····case WM_CONTEXTMENU:·
645409 ········WinHelp ((HWND) wParam, pkmpss->pKM->szHelpFile, HELP_CONTEXTMENU,·
8501a5 ············(DWORD) (LPVOID) aRevokerIds);·
628f13 ········break;·
dcaf5a
f71431 ¤   case WM_NOTIFY :
780f7c ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
6ea305 //¤ ¤   case PSN_SETACTIVE :
3c309a //¤ ¤   ¤   break;
bbaf5a
628074 //¤ ¤   case PSN_APPLY :
439dd9 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
cd9525 //¤ ¤   ¤   return TRUE;
02af5a
041b03 ¤   ¤   case PSN_HELP :
9bdf94 ¤   ¤   ¤   WinHelp (hDlg, pkmpss->pKM->szHelpFile, HELP_CONTEXT,·
392e96 ¤   ¤   ¤   ¤   IDH_PGPKM_PROPDIALOG);·
8fcdcb ¤   ¤   ¤   break;
91af5a
b21e4a //¤ ¤   case PSN_KILLACTIVE :
e0ccd4 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
f09525 //¤ ¤   ¤   return TRUE;
e20fe4 ¤   ¤   }
ed9371 ¤   }
afa230 ¤   return FALSE;
54efe6 }
03af5a
78af5a
eb4265 //¤ ___________________________________________________
58465d //
f96330 // ·update controls dealing with validity
8faf5a
93e6b2 static VOID
09952e sSetValidityControls (HWND hwnd, KMPROPSHEETSTRUCT* pkmpss, UINT uVal)·
b1bb36 {
b7beb0 ¤   UINT u;
00af5a
c533f7 ¤   u = KMConvertFromPGPValidity (uVal);
6075c1 ¤   SendMessage (pkmpss->hwndValidity, PBM_SETPOS, u, 0);
67af5a
e89777 ¤   if (u < (UINT)pkmpss->pKM->iValidityThreshold)
d607f7 ¤   ¤   pkmpss->bInvalid = TRUE;
dc0e24 ¤   else
36b274 ¤   ¤   pkmpss->bInvalid = FALSE;
64af5a
cc923e ¤   InvalidateRect (hwnd, NULL, FALSE);
f3efe6 }
13af5a
85af5a
564265 //¤ ___________________________________________________
ee465d //
832157 // ·convert slider control values
1baf5a
89a970 static UINT
e6245d sConvertFromPGPTrust (UINT u)·
1ebb36 {
2cf56c #if 0 // vertical trust slider
3276dc ¤   return (KMConvertFromPGPTrust (kPGPKeyTrust_Complete) -
417f5c ¤   ¤   ¤   KMConvertFromPGPTrust (u));
b934b0 #else // horizontal trust slider
666207 ¤   return (KMConvertFromPGPTrust (u));
8c7454 #endif
9eefe6 }
d4af5a
baaf5a
a4a970 static UINT
a0f26e sConvertToPGPTrust (UINT u)·
e5bb36 {
ebf56c #if 0 // vertical trust slider
232164 ¤   return KMConvertToPGPTrust (
--3f34 0007126b67f401102b2 Page 24 of KMProps.c
c95079 ¤   ¤   KMConvertFromPGPTrust (kPGPKeyTrust_Complete) - u);
a134b0 #else // horizontal trust slider
d8d60e ¤   return KMConvertToPGPTrust (u);
937454 #endif
edefe6 }
6faf5a
08af5a
da4265 //¤ ___________________________________________________
a4465d //
1a2228 // ·update controls dealing with trust
8faf5a
8ae6b2 static VOID
994cb7 sSetTrustControls (HWND hDlg, KMPROPSHEETSTRUCT* pkmpss, UINT uTrust)·
e3bb36 {
f9cdd6 ¤   INT i;
c2af5a
ba9e9f ¤   i = sConvertFromPGPTrust (uTrust);
d0409f ¤   SendDlgItemMessage (hDlg, IDC_TRUSTSLIDER, TBM_SETPOS, (WPARAM)TRUE, i);
adefe6 }
a9af5a
3daf5a
a24265 //¤ ___________________________________________________
10465d //
79095d // ·Fingerprint edit box subclass procedure
a1af5a
5fd0ac static LRESULT APIENTRY·
2c32b0 sFingerSubclassProc (
3747b2 ¤   ¤   HWND¤   hWnd,·
e5eb77 ¤   ¤   UINT¤   uMsg,·
7b17d4 ¤   ¤   WPARAM¤ wParam,·
3ac0b8 ¤   ¤   LPARAM¤ lParam)·
e5bb36 {
ee5c90 ¤   KMPROPSHEETSTRUCT* pkmpss;
7cac24 ¤   pkmpss =·
b5af01 ¤   ¤   (KMPROPSHEETSTRUCT*)GetWindowLong (GetParent (hWnd), GWL_USERDATA);
55af5a
4d1b44 ····switch (uMsg) {
fb475b ¤   case WM_LBUTTONDOWN :
ad4919 ¤   case WM_LBUTTONDBLCLK :
7b31ca ¤   ¤   SendMessage (hWnd, EM_SETSEL, 0, -1);
4f94ae ¤   ¤   SetFocus (hWnd);
fcbbde ¤   ¤   return 0;
b89371 ¤   }
ba0110 ····return CallWindowProc (pkmpss->wpOrigFingerProc, hWnd, uMsg,·
bcf126 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam, lParam);·
e4a79b }·
1baf5a
7eaf5a
824265 //¤ ___________________________________________________
ca465d //
4706a7 // ·display photo userID with appropriate overwriting
7daf5a
2fb333 static VOID·
1d361b sPaintPhotoID (
d6757a ¤   ¤   HWND¤   ¤   hWnd,
f78dd7 ¤   ¤   HBITMAP¤¤   hbitmapID,
7ff017 ¤   ¤   HPALETTE¤   hpaletteID,
a307a4 ¤   ¤   INT¤¤   ¤   iwidthBM,
19a16a ¤   ¤   INT¤¤   ¤   iheightBM,
e1a653 ¤   ¤   BOOL¤   ¤   bInvalid,
4ec92c ¤   ¤   BOOL¤   ¤   bRevoked,
5ae554 ¤   ¤   BOOL¤   ¤   bExpired)
40bb36 {
a2927f ¤   HPALETTE¤   ¤   hpaletteOld¤¤   = NULL;
868bc2 ¤   HDC¤¤   ¤   ¤   hdc;
04d552 ¤   HDC¤¤   ¤   ¤   hdcMem;
3db272 ¤   HDC¤¤   ¤   ¤   hdcMask;
6776ff ¤   HBITMAP¤¤   ¤   hbitmap;
9ead04 ¤   PAINTSTRUCT¤¤   ps;
d61372 ¤   RECT¤   ¤   ¤   rc;
f6f6a7 ¤   INT¤¤   ¤   ¤   icent;
716434 ¤   INT¤¤   ¤   ¤   ileft, itop, iwidth, iheight;
--05bd 0001069a6a0401102b2 Page 25 of KMProps.c
8b707d ¤   BITMAP¤ ¤   ¤   bm;
b0af5a
f2e514 ¤   hdc = BeginPaint (hWnd, &ps);
44af5a
9b5b24 ¤   GetWindowRect (GetDlgItem (hWnd, IDC_PHOTOID), &rc);
b01360 ¤   rc.left += 2;
e9d0fe ¤   rc.top += 2;
3db837 ¤   rc.right -= 2;
83d7df ¤   rc.bottom -= 2;
26130c ¤   MapWindowPoints (NULL, hWnd, (LPPOINT)&rc, 2);
e4fe45 ¤   FillRect (hdc, &rc, (HBRUSH)(COLOR_3DFACE+1));
e4af5a
3b1155 ¤   // if photoid is available ... draw it
23837e ¤   if (hbitmapID) {
364be1 ¤   ¤   // check if bitmap needs shrinking
5a611c ¤   ¤   if ((iheightBM > (rc.bottom-rc.top-2)) ||
c79166 ¤   ¤   ¤   (iwidthBM ·> (rc.right-rc.left-2)))·
775b34 ¤   ¤   {
7daaa1 ¤   ¤   ¤   if (iheightBM > (iwidthBM * 1.25)) {
80b5c4 ¤   ¤   ¤   ¤   itop = rc.top +1;
8a6e6b ¤   ¤   ¤   ¤   iheight = rc.bottom-rc.top -2;
6dc66a ¤   ¤   ¤   ¤   icent = (rc.right+rc.left) / 2;
e3c794 ¤   ¤   ¤   ¤   iwidth = ((rc.bottom-rc.top) * iwidthBM) / iheightBM;
561815 ¤   ¤   ¤   ¤   ileft = icent -(iwidth/2);
3fa3a6 ¤   ¤   ¤   }
afe543 ¤   ¤   ¤   else {
dc6303 ¤   ¤   ¤   ¤   ileft = rc.left +1;
d5f719 ¤   ¤   ¤   ¤   iwidth = rc.right-rc.left -2;
9c652a ¤   ¤   ¤   ¤   icent = (rc.bottom+rc.top) / 2;
acde60 ¤   ¤   ¤   ¤   iheight = ((rc.right-rc.left) * iheightBM) / iwidthBM;
5cade3 ¤   ¤   ¤   ¤   itop = icent - (iheight/2);
bda3a6 ¤   ¤   ¤   }
3d0fe4 ¤   ¤   }
20e0e5 ¤   ¤   // otherwise draw it at its real size
ea07e0 ¤   ¤   else {
4e20b9 ¤   ¤   ¤   iwidth = iwidthBM;
ccf1df ¤   ¤   ¤   iheight = iheightBM;
6dde3a ¤   ¤   ¤   icent = (rc.right+rc.left) / 2;
68ec4a ¤   ¤   ¤   ileft = icent - (iwidth/2);
717d7a ¤   ¤   ¤   icent = (rc.bottom+rc.top) / 2;
022585 ¤   ¤   ¤   itop = icent - (iheight/2);
910fe4 ¤   ¤   }
41af5a
680744 ¤   ¤   hdcMem = CreateCompatibleDC (hdc);
71af5a
ef165c ¤   ¤   if (hpaletteID) {
b9c85f ¤   ¤   ¤   hpaletteOld = SelectPalette (hdc, hpaletteID, FALSE);
05703c ¤   ¤   ¤   RealizePalette (hdc);
790fe4 ¤   ¤   }
4aaf5a
39451c ¤   ¤   SetStretchBltMode (hdc, COLORONCOLOR);
808651 ¤   ¤   SelectObject (hdcMem, hbitmapID);
5e22b9 ¤   ¤   StretchBlt (hdc, ileft, itop, iwidth, iheight,
0834ec ¤   ¤   ¤   ¤   ¤   hdcMem, 0, 0, iwidthBM, iheightBM, SRCCOPY);
3faf5a
b6791f ¤   ¤   // overlay the question mark
d16749 ¤   ¤   if (bInvalid && !bRevoked && !bExpired) {
bb95d5 ¤   ¤   ¤   hdcMask = CreateCompatibleDC (hdc);
160182 ¤   ¤   ¤   hbitmap =·
6f9077 ¤   ¤   ¤   ¤   LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_QUESTIONMARK));
068585 ¤   ¤   ¤   GetObject (hbitmap, sizeof(BITMAP), (LPSTR)&bm);
3e67c5 ¤
e59fd0 ¤   ¤   ¤   SelectObject (hdcMask, hbitmap);
0d67c5 ¤
60ce79 ¤   ¤   ¤   SetTextColor(hdc, RGB (255,0,0));
02ebfb ¤   ¤   ¤   SetBkColor(hdc, RGB (0,0,0));
fd1507 ¤   ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
321241 ¤   ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
c87c8a ¤   ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCINVERT);
2567c5 ¤
c0bf09 ¤   ¤   ¤   SetTextColor(hdc, RGB (0,0,0));
10a0a6 ¤   ¤   ¤   SetBkColor(hdc, RGB (255,255,255));
--37a0 0003510dd83401102b2 Page 26 of KMProps.c
a21507 ¤   ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
891241 ¤   ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
6bc4fd ¤   ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCAND);
9d67c5 ¤
dece79 ¤   ¤   ¤   SetTextColor(hdc, RGB (255,0,0));
99ebfb ¤   ¤   ¤   SetBkColor(hdc, RGB (0,0,0));
1c1507 ¤   ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
541241 ¤   ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
0f7c8a ¤   ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCINVERT);
a767c5 ¤
565d9f ¤   ¤   ¤   DeleteDC (hdcMask);
9f0fe4 ¤   ¤   }
e1af5a
c2cc3c ¤   ¤   if (hpaletteOld) {
9369bb ¤   ¤   ¤   SelectPalette (hdc, hpaletteOld, TRUE);
d2703c ¤   ¤   ¤   RealizePalette (hdc);
320fe4 ¤   ¤   }
6faf5a
18039b ¤   ¤   DeleteDC (hdcMem);
4b9371 ¤   }
37af5a
9d717c ¤   // overlay the text
33e4e4 ¤   if (bRevoked) {
128d85 ¤   ¤   hdcMask = CreateCompatibleDC (hdc);
2a59f0 ¤   ¤   hbitmap = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_REVOKED));
10a330 ¤   ¤   GetObject (hbitmap, sizeof(BITMAP), (LPSTR)&bm);
56af5a
d19968 ¤   ¤   SelectObject (hdcMask, hbitmap);
a8af5a
daf7bc ¤   ¤   SetTextColor(hdc, RGB (255,0,0));
e5d715 ¤   ¤   SetBkColor(hdc, RGB (0,0,0));
50849f ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
d39d16 ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
9632fd ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCINVERT);
dfaf5a
4a376f ¤   ¤   SetTextColor(hdc, RGB (0,0,0));
0cb8f6 ¤   ¤   SetBkColor(hdc, RGB (255,255,255));
64849f ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
689d16 ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
a84eb8 ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCAND);
32af5a
6df7bc ¤   ¤   SetTextColor(hdc, RGB (255,0,0));
d9d715 ¤   ¤   SetBkColor(hdc, RGB (0,0,0));
2a849f ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
e49d16 ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
6d32fd ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCINVERT);
17af5a
41f0c1 ¤   ¤   DeleteDC (hdcMask);
b99371 ¤   }
8af3f2 ¤   else if (bExpired) {
6e8d85 ¤   ¤   hdcMask = CreateCompatibleDC (hdc);
8de2cd ¤   ¤   hbitmap = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_EXPIRED));
8ba330 ¤   ¤   GetObject (hbitmap, sizeof(BITMAP), (LPSTR)&bm);
bdaf5a
d79968 ¤   ¤   SelectObject (hdcMask, hbitmap);
69af5a
2cf7bc ¤   ¤   SetTextColor(hdc, RGB (255,0,0));
2cd715 ¤   ¤   SetBkColor(hdc, RGB (0,0,0));
e3849f ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
359d16 ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
2232fd ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCINVERT);
67af5a
26376f ¤   ¤   SetTextColor(hdc, RGB (0,0,0));
73b8f6 ¤   ¤   SetBkColor(hdc, RGB (255,255,255));
10849f ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
029d16 ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
694eb8 ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCAND);
71af5a
42f7bc ¤   ¤   SetTextColor(hdc, RGB (255,0,0));
dcd715 ¤   ¤   SetBkColor(hdc, RGB (0,0,0));
42849f ¤   ¤   StretchBlt (hdc, rc.left, rc.top,·
359d16 ¤   ¤   ¤   ¤   rc.right-rc.left-2, rc.bottom-rc.top-2,
--56a9 000d51aad6a401102b2 Page 27 of KMProps.c
b232fd ¤   ¤   ¤   ¤   hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, SRCINVERT);
1daf5a
3bf0c1 ¤   ¤   DeleteDC (hdcMask);
c09371 ¤   }
26af5a
c6e23b ¤   EndPaint (hWnd, &ps);
98a79b }·
1caf5a
0daf5a
c24265 //¤ ___________________________________________________
d3465d //
b5c789 // ·PhotoID subclass procedure
f3af5a
ccd0ac static LRESULT APIENTRY·
aecb3f sPhotoIDSubclassProc (
a747b2 ¤   ¤   HWND¤   hWnd,·
2feb77 ¤   ¤   UINT¤   uMsg,·
8417d4 ¤   ¤   WPARAM¤ wParam,·
48c0b8 ¤   ¤   LPARAM¤ lParam)·
c8bb36 {
725c90 ¤   KMPROPSHEETSTRUCT* pkmpss;
deac24 ¤   pkmpss =·
93af01 ¤   ¤   (KMPROPSHEETSTRUCT*)GetWindowLong (GetParent (hWnd), GWL_USERDATA);
60af5a
dd1b44 ····switch (uMsg) {
ccaf5a
bb651b ¤   case WM_CONTEXTMENU :
ce5b34 ¤   ¤   {
535435 ¤   ¤   ¤   HMENU¤  hMC;
734cea ¤   ¤   ¤   HMENU¤  hMenuTrackPopup;
23af5a
ac7e84 ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUPHOTOID));
e6fa5a ¤   ¤   ¤   if (pkmpss->hbitmapPhotoID)
566a62 ¤   ¤   ¤   ¤   EnableMenuItem (hMC, IDM_COPYBITMAP,·
fb6152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_ENABLED);
e7bb8c ¤   ¤   ¤   else
f16a62 ¤   ¤   ¤   ¤   EnableMenuItem (hMC, IDM_COPYBITMAP,·
38e1fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_GRAYED);
75af5a
5437b8 ¤   ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
a5af5a
5fc72f ¤   ¤   ¤   TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
1b2add ¤   ¤   ¤   ¤   LOWORD(lParam), HIWORD(lParam), 0, GetParent (hWnd), NULL);
0aaf5a
5a7327 ¤   ¤   ¤   DestroyMenu (hMC);
9d0fe4 ¤   ¤   }
9b2f68 ¤   ¤   break;
7caf5a
aebfad ¤   default :
67a5df ¤   ¤   return CallWindowProc (pkmpss->wpOrigPhotoIDProc, hWnd, uMsg,·
9ef126 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam, lParam);·
d39371 ¤   }
a4c2e7 ¤   return TRUE;
51a79b }·
9baf5a
58af5a
a34265 //¤ ___________________________________________________
29465d //
f6e072 // ·update system palette
baaf5a
fe67fb static BOOL
0b5965 sUpdatePalette (
27317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
fabc7b ¤   ¤   KMPROPSHEETSTRUCT*¤ pkmpss)
37bb36 {
1451db ¤   BOOL¤   ¤   bretval¤¤   = FALSE;
1394c0 ¤   HDC¤¤   ¤   hdc;
c34e1f ¤   HPALETTE¤   hpaletteOld;
32af5a
602e05 ¤   if (pkmpss->hpalettePhotoID == NULL) return FALSE;
96af5a
d57424 ¤   hdc = GetDC (hwnd);
--4654 00059503c84401102b2 Page 28 of KMProps.c
e0af5a
e35eee ¤   hpaletteOld = SelectPalette (hdc, pkmpss->hpalettePhotoID, FALSE);
c5b081 ¤   if (RealizePalette (hdc)) {
10a462 ¤   ¤   InvalidateRect (hwnd, NULL, TRUE);·
6e88ca ¤   ¤   bretval = TRUE;
fc9371 ¤   }
7aaf5a
dfe7aa ¤   SelectPalette (hdc, hpaletteOld, TRUE);
37ce60 ¤   RealizePalette (hdc);
5b108c ¤   ReleaseDC (hwnd, hdc);
dfaf5a
38ca54 ¤   return bretval;
2eefe6 }
9aaf5a
56af5a
c64265 //¤ ___________________________________________________
15465d //
8d6bca // ·Key Properties Dialog Message procedure - General panel
a3af5a
323f64 static BOOL CALLBACK·
eae438 sKeyPropDlgProcGeneral (
5a3a3a ¤   ¤   HWND¤   hDlg,·
94eb77 ¤   ¤   UINT¤   uMsg,·
880303 ¤   ¤   WPARAM¤ wParam,
46c0b8 ¤   ¤   LPARAM¤ lParam)·
08bb36 {
0391a6 ¤   KMPROPSHEETSTRUCT*¤ pkmpss;
d96a12 ¤   CHAR¤   ¤   ¤   ¤   sz[kPGPMaxUserIDSize];
bab236 ¤   INT¤¤   ¤   ¤   ¤   i;
460e31 ¤   UINT¤   ¤   ¤   ¤   u, uTrust;
2f6909 ¤   PGPBoolean¤ ¤   ¤   bB;
ac6df6 ¤   PGPUInt32¤  ¤   ¤   prefAlg[6];
b7e804 ¤   PGPTime¤¤   ¤   ¤   tm;
90db61 ¤   PGPUserIDRef¤   ¤   userid;
65e8fd ¤   HWND¤   ¤   ¤   ¤   hwndParent;
28b996 ¤   RECT¤   ¤   ¤   ¤   rc;
3d9c30 ¤   LPBITMAPINFO¤   ¤   lpbmi;
53af5a
6db32f ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
3baf5a
1c347f ¤   switch (uMsg) {
9eaf5a
c52940 ¤   case WM_INITDIALOG:
d0c72a ¤   ¤   // store pointer to data structure
c0fe01 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, ((PROPSHEETPAGE*)lParam)->lParam);
2eb459 ¤   ¤   pkmpss = (KMPROPSHEETSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
9aaf5a
e0b02f ¤   ¤   // save HWND to table
720262 ¤   ¤   pkmpss->pKM->hWndTable[pkmpss->iIndex] = hDlg;
7aaf5a
d140a9 ¤   ¤   // center dialog on screen
f4401b ¤   ¤   hwndParent = GetParent (hDlg);
08a46d ¤   ¤   if (pkmpss->pKM->iNumberSheets == 1) {
23f352 ¤   ¤   ¤   GetWindowRect (hwndParent, &rc);
3b45db ¤   ¤   ¤   SetWindowPos (hwndParent, NULL,
5f73f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
db8186 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 3,
cbf9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
880fe4 ¤   ¤   }
1b51c7 ¤   ¤   // subclass fingerprint edit control to prevent partial selection
7af676 ¤   ¤   pkmpss->wpOrigFingerProc =·
8bbd80 ¤   ¤   ¤   (WNDPROC) SetWindowLong(GetDlgItem (hDlg, IDC_FINGERPRINT),·
497a1b ················GWL_WNDPROC, (LONG) sFingerSubclassProc);·
c8af5a
e53d47 ¤   ¤   // subclass photoID control to handle dropping, dragging
af8896 ¤   ¤   pkmpss->wpOrigPhotoIDProc =·
e13c65 ¤   ¤   ¤   (WNDPROC) SetWindowLong(GetDlgItem (hDlg, IDC_PHOTOID),·
a459d7 ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG) sPhotoIDSubclassProc);·
25af5a
6f6944 ¤   ¤   // create smooth progress bar
5de3d6 ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_VALIDITYBAR), &rc);
594f66 ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
--0028 0005d3ee4ae401102b2 Page 29 of KMProps.c
15abe7 ¤   ¤   pkmpss->hwndValidity =·
8c35a2 ¤   ¤   ¤   CreateWindowEx (0, PROGRESS_CLASS, (LPSTR) NULL,·
073fae ¤   ¤   ¤   ¤   ¤   ¤   ¤   WS_CHILD|WS_VISIBLE|PBS_SMOOTH,·
41987c ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left, rc.top,·
2ac8ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right-rc.left, rc.bottom-rc.top,·
4620d6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, (HMENU) 0, g_hInst, NULL);·
95af5a
6ba200 ¤   ¤   // disable and hide cancel button; and move "OK" button over
46b676 ¤   ¤   SendMessage (hwndParent, PSM_CANCELTOCLOSE, 0, 0);
f51d67 ¤   ¤   GetWindowRect (GetDlgItem (hwndParent, IDCANCEL), &rc);
4494b0 ¤   ¤   MapWindowPoints (NULL, hwndParent, (LPPOINT)&rc, 2);
dadb81 ¤   ¤   SetWindowPos (GetDlgItem (hwndParent, IDOK), NULL, rc.left,
b33b2d ¤   ¤   ¤   ¤   ¤   ¤   rc.top, rc.right-rc.left, rc.bottom-rc.top,
497ac4 ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOZORDER);
617d64 ¤   ¤   ShowWindow (GetDlgItem (hwndParent, IDCANCEL), SW_HIDE);
94af5a
31a54c ¤   ¤   // initialize all controls
f89370 ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
ba836c ¤   ¤   return TRUE;
e1af5a
975020 ¤   case WM_APP :
e8db8f ¤   ¤   if (wParam == SERIALIZE)
8d4b3f ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
00af5a
b8c397 ¤   ¤   PGPGetKeyBoolean (pkmpss->key, kPGPKeyPropIsSecret,
32205c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pkmpss->bSecret);
af933a ¤   ¤   PGPGetKeyBoolean (pkmpss->key, kPGPKeyPropIsSecretShared,
7cf8d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pkmpss->bSplit);
6e39a2 ¤   ¤   PGPGetKeyBoolean (pkmpss->key, kPGPKeyPropIsRevoked,
3cc8e2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pkmpss->bRevoked);
356b62 ¤   ¤   PGPGetKeyBoolean (pkmpss->key, kPGPKeyPropIsExpired,
540ebc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pkmpss->bExpired);
a43964 ¤   ¤   PGPGetKeyBoolean (pkmpss->key, kPGPKeyPropIsAxiomatic,·
866b6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pkmpss->bAxiomatic);
43af5a
90eaa9 ¤   ¤   // initialize key id edit control
2b960a ¤   ¤   KMGetKeyIDFromKey (pkmpss->key, sz, sizeof(sz));
e88cb7 ¤   ¤   SetDlgItemText (hDlg, IDC_KEYID, sz);
00af5a
8ec2d9 ¤   ¤   // initialize key type edit control
a33089 ¤   ¤   switch (pkmpss->algKey) {
421a7c ¤   ¤   case kPGPPublicKeyAlgorithm_RSA :
28c00b ¤   ¤   ¤   LoadString (g_hInst, IDS_RSA, sz, sizeof (sz));
42cdcb ¤   ¤   ¤   break;
1baf5a
5a4036 ¤   ¤   case kPGPPublicKeyAlgorithm_DSA :
767f56 ¤   ¤   ¤   LoadString (g_hInst, IDS_DSA_ELGAMAL, sz, sizeof (sz));
45cdcb ¤   ¤   ¤   break;
fcaf5a
9b3a18 ¤   ¤   default :
6157bf ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWN, sz, sizeof (sz));
bfcdcb ¤   ¤   ¤   break;
860fe4 ¤   ¤   }
b612f5 ¤   ¤   SetDlgItemText (hDlg, IDC_KEYTYPE, sz);
aaaf5a
51745a ¤   ¤   // initialize key size edit control
7ae765 ¤   ¤   KMGetKeyBitsString (pkmpss->keyset,·
a12f79 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->key, sz, sizeof(sz));
dc8471 ¤   ¤   SetDlgItemText (hDlg, IDC_KEYSIZE, sz);
efaf5a
d1853c ¤   ¤   // initialize key creation date edit control
b2117c ¤   ¤   PGPGetKeyTime (pkmpss->key, kPGPKeyPropCreation, &tm);
f10b9e ¤   ¤   KMConvertTimeToString (tm, sz, sizeof (sz));
767ba6 ¤   ¤   SetDlgItemText (hDlg, IDC_CREATEDATE, sz);
70af5a
c7c312 ¤   ¤   // initialize key expiration date edit control
443d64 ¤   ¤   PGPGetKeyTime (pkmpss->key, kPGPKeyPropExpiration, &tm);
2b9353 ¤   ¤   if (tm == kPGPExpirationTime_Never) {
57902c ¤   ¤   ¤   LoadString (g_hInst, IDS_NEVER, sz, sizeof (sz));
0bf724 ¤   ¤   ¤   pkmpss->iExpireDays = -1;
130fe4 ¤   ¤   }
5d07e0 ¤   ¤   else {
--ccb2 0006a07643a401102b2 Page 30 of KMProps.c
88cb5e ¤   ¤   ¤   KMConvertTimeToDays (tm, &pkmpss->iExpireDays);
7264ad ¤   ¤   ¤   KMConvertTimeToString (tm, sz, sizeof (sz));
480fe4 ¤   ¤   }
c96f8b ¤   ¤   SetDlgItemText (hDlg, IDC_EXPIREDATE, sz);
14af5a
0e191a ¤   ¤   // initialize preferred cipher edit control
0429bb ¤   ¤   PGPGetKeyPropertyBuffer (pkmpss->key, kPGPKeyPropPreferredAlgorithms,
b8c428 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(prefAlg), (PGPByte*)&prefAlg[0], &u);
0138ce ¤   ¤   if (u < sizeof(PGPCipherAlgorithm))·
f3ef7d ¤   ¤   ¤   prefAlg[0] = kPGPCipherAlgorithm_IDEA;
2c27c1 ¤   ¤   switch (prefAlg[0]) {
78a8a5 ¤   ¤   ¤   case kPGPCipherAlgorithm_CAST5 :
561276 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_CAST, sz, sizeof(sz));
43f622 ¤   ¤   ¤   ¤   break;
b5af5a
6cff0f ¤   ¤   ¤   case kPGPCipherAlgorithm_3DES :
ccdb0c ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_3DES, sz, sizeof(sz));
7ef622 ¤   ¤   ¤   ¤   break;
34af5a
6f0082 ¤   ¤   ¤   default :
6d81e9 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_IDEA, sz, sizeof(sz));
2ef622 ¤   ¤   ¤   ¤   break;
380fe4 ¤   ¤   }
6dbfeb ¤   ¤   SetDlgItemText (hDlg, IDC_CIPHER, sz);
b2af5a
b97382 ¤   ¤   // initialize fingerprint edit control
513410 ¤   ¤   PGPGetKeyPropertyBuffer(pkmpss->key, kPGPKeyPropFingerprint,
183465 ¤   ¤   ¤   ¤   sizeof(sz), sz, &u);
ddf221 ¤   ¤   KMConvertStringFingerprint (pkmpss->algKey, sz);
da3b85 ¤   ¤   SetDlgItemText (hDlg, IDC_FINGERPRINT, sz);
c9af5a
0c91e1 ¤   ¤   // initialize validity edit and bar controls
66be9e ¤   ¤   i = KMConvertFromPGPValidity (kPGPValidity_Complete);
cc717a ¤   ¤   SendMessage (pkmpss->hwndValidity, PBM_SETRANGE,·
a72453 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, MAKELPARAM (0,i));
a5c412 ¤   ¤   PGPGetKeyNumber (pkmpss->key, kPGPKeyPropValidity,·
22dc8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pkmpss->uValidity);
72a001 ¤   ¤   sSetValidityControls (hDlg, pkmpss, pkmpss->uValidity);
48af5a
594903 ¤   ¤   // initialize "Axiomatic" checkbox control
18edcf ¤   ¤   if (pkmpss->bAxiomatic)·
a97597 ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_AXIOMATIC, BST_CHECKED);
b4ee26 ¤   ¤   else·
2aac7b ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_AXIOMATIC, BST_UNCHECKED);
00af5a
8278b0 ¤   ¤   if (pkmpss->bRevoked || pkmpss->bExpired || pkmpss->bReadOnly)
6d0194 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_AXIOMATIC), FALSE);
19ee26 ¤   ¤   else·
381b7e ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_AXIOMATIC), TRUE);
61af5a
a8db24 ¤   ¤   if (!pkmpss->bSecret && !pkmpss->bAxiomatic)·
f1fd65 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_AXIOMATIC), SW_HIDE);
f20e1d ¤   ¤   else
d7873e ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_AXIOMATIC), SW_SHOW);
0baf5a
25c554 ¤   ¤   // initialize trust edit and slider controls
bd8a9e ¤   ¤   i = KMConvertFromPGPTrust (kPGPKeyTrust_Complete);
ef914d ¤   ¤   SendDlgItemMessage (hDlg, IDC_TRUSTSLIDER, TBM_SETRANGE,·
8ab18c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, MAKELPARAM (0, i));
662cc8 ¤   ¤   PGPGetKeyNumber (pkmpss->key, kPGPKeyPropTrust, &pkmpss->uTrust);
adcb78 ¤   ¤   sSetTrustControls (hDlg, pkmpss, pkmpss->uTrust);
f4af5a
3a72a0 ¤   ¤   if (pkmpss->bAxiomatic || pkmpss->bRevoked || pkmpss->bReadOnly)
865b34 ¤   ¤   {
f357cc ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTSLIDER), FALSE);
dbd8f5 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTTEXT1), FALSE);
8a5f1b ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTTEXT2), FALSE);
2d0fe4 ¤   ¤   }
ba0e1d ¤   ¤   else
875b34 ¤   ¤   {
1ee66a ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTSLIDER), TRUE);
6a8f51 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTTEXT1), TRUE);
--7588 000e6d73289401102b2 Page 31 of KMProps.c
0a71e2 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTTEXT2), TRUE);
8b0fe4 ¤   ¤   }
51af5a
a0001c ¤   ¤   // initialize enable/disable checkbox
0cbe20 ¤   ¤   PGPGetKeyBoolean (pkmpss->key, kPGPKeyPropIsDisabled,·
6e54fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pkmpss->bDisabled);
f6cfd7 ¤   ¤   if (pkmpss->bDisabled)·
b66cce ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLED, BST_UNCHECKED);
7fee26 ¤   ¤   else·
54b3ca ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_ENABLED, BST_CHECKED);
a9af5a
f978b0 ¤   ¤   if (pkmpss->bRevoked || pkmpss->bExpired || pkmpss->bReadOnly)
bd268e ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLED), FALSE);
e50e1d ¤   ¤   else
b83338 ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLED), TRUE);
4aaf5a
921b08 ¤   ¤   if (pkmpss->bSecret) {
a6d0a7 ¤   ¤   ¤   if (pkmpss->bAxiomatic)·
1933ad ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLED), FALSE);
79bb8c ¤   ¤   ¤   else
42b97d ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLED), TRUE);
ae0fe4 ¤   ¤   }
d3af5a
551b5f ¤   ¤   // initialize change passphrase button
71430b ¤   ¤   if (pkmpss->bSplit) {
dca56a ¤   ¤   ¤   aKeyPropIds[1] = IDH_PGPKM_JOINKEY;
56bfa0 ¤   ¤   ¤   LoadString (g_hInst, IDS_RECONSTITUTEKEY, sz, sizeof(sz));
2b0fe4 ¤   ¤   }
d407e0 ¤   ¤   else {
22f7dc ¤   ¤   ¤   aKeyPropIds[1] = IDH_PGPKM_CHANGEPHRASE;
4ab1c5 ¤   ¤   ¤   LoadString (g_hInst, IDS_CHANGEPHRASE, sz, sizeof(sz));¤
690fe4 ¤   ¤   }
6f8468 ¤   ¤   SetDlgItemText (hDlg, IDC_CHANGEPHRASE, sz);
edaf5a
c0a75e ¤   ¤   if (!pkmpss->bSecret)·
429e93 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_CHANGEPHRASE), SW_HIDE);
f2af5a
140e44 ¤   ¤   PGPGetKeyBoolean (pkmpss->key, kPGPKeyPropCanSign, &bB);
a05cda ¤   ¤   if (!bB || pkmpss->bReadOnly)
4f218d ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_CHANGEPHRASE), FALSE);
df0e1d ¤   ¤   else
36084f ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_CHANGEPHRASE), TRUE);
80af5a
e0f441 ¤   ¤   // display photo ID
9281cb ¤   ¤   if (pkmpss->hbitmapPhotoID) {
963946 ¤   ¤   ¤   DeleteObject (pkmpss->hbitmapPhotoID);
8247b4 ¤   ¤   ¤   pkmpss->hbitmapPhotoID = NULL;
730fe4 ¤   ¤   }
cb26af ¤   ¤   if (pkmpss->pPhotoBuffer) {
03bbdb ¤   ¤   ¤   KMFree (pkmpss->pPhotoBuffer);
dcf05f ¤   ¤   ¤   pkmpss->pPhotoBuffer = NULL;
4d0fe4 ¤   ¤   }
8981cb ¤   ¤   if (pkmpss->hbitmapPhotoID) {
2c3946 ¤   ¤   ¤   DeleteObject (pkmpss->hbitmapPhotoID);
8f47b4 ¤   ¤   ¤   pkmpss->hbitmapPhotoID = NULL;
fa0fe4 ¤   ¤   }
6823d8 ¤   ¤   if (pkmpss->hpalettePhotoID) {
9c958a ¤   ¤   ¤   DeleteObject (pkmpss->hpalettePhotoID);
a7a966 ¤   ¤   ¤   pkmpss->hpalettePhotoID = NULL;
250fe4 ¤   ¤   }
e1af5a
49d901 ¤   ¤   PGPGetPrimaryAttributeUserID (pkmpss->key,·
fa58aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAttribute_Image, &userid);
66b919 ¤   ¤   if (userid == NULL) {
bb6dd6 ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHOTOSCROLLBAR), SW_HIDE);
86a124 ¤   ¤   ¤   pkmpss->iPhotoIDIndex = -1;
560fe4 ¤   ¤   }
ed07e0 ¤   ¤   else {
fe571b ¤   ¤   ¤   PGPKeyListRef¤  keylist;
34451d ¤   ¤   ¤   PGPKeyIterRef¤  keyiter;
25e529 ¤   ¤   ¤   INT¤¤   ¤   ¤   iNumPhotoID;
e68098 ¤   ¤   ¤   PGPUInt32¤  ¤   iType;
--6997 000602dea32401102b2 Page 32 of KMProps.c
7d662c ¤   ¤   ¤   PGPBoolean¤ ¤   bAttrib;
875be5 ¤   ¤   ¤   SCROLLINFO¤ ¤   si;
deaf5a
967ef3 ¤   ¤   ¤   if (pkmpss->iPhotoIDIndex < 0)
90a732 ¤   ¤   ¤   ¤   pkmpss->iPhotoIDIndex = 0;
faaf5a
d20ea6 ¤   ¤   ¤   // get number of Photo IDs
86450f ¤   ¤   ¤   PGPOrderKeySet (pkmpss->pKM->KeySetDisp,·
f91300 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAnyOrdering, &keylist);
cb6b18 ¤   ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
0449c5 ¤   ¤   ¤   PGPKeyIterSeek (keyiter, pkmpss->key);
044339 ¤   ¤   ¤   PGPKeyIterNextUserID (keyiter, &userid);
80d0b9 ¤   ¤   ¤   iNumPhotoID = 0;
588f2e ¤   ¤   ¤   while (userid) {
9df68a ¤   ¤   ¤   ¤   PGPGetUserIDBoolean (userid,·
540427 ¤   ¤   ¤   ¤   ¤   ¤   kPGPUserIDPropIsAttribute, &bAttrib);
ad5379 ¤   ¤   ¤   ¤   if (userid == pkmpss->userid)
b41269 ¤   ¤   ¤   ¤   ¤   pkmpss->iPhotoIDIndex = iNumPhotoID;
8cd7bf ¤   ¤   ¤   ¤   if (bAttrib) {
11e52f ¤   ¤   ¤   ¤   ¤   PGPGetUserIDNumber (userid,·
16291d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPUserIDPropAttributeType, &iType);
a0a4a7 ¤   ¤   ¤   ¤   ¤   if (iType == kPGPAttribute_Image)
e53962 ¤   ¤   ¤   ¤   ¤   ¤   iNumPhotoID++;
402613 ¤   ¤   ¤   ¤   }
712c0a ¤   ¤   ¤   ¤   PGPKeyIterNextUserID (keyiter, &userid);
11a3a6 ¤   ¤   ¤   }
86328f ¤   ¤   ¤   pkmpss->iNumPhotoIDs = iNumPhotoID;
afaf5a
fc1e2e ¤   ¤   ¤   // setup photoid scrollbar
b84375 ¤   ¤   ¤   if (iNumPhotoID <= 1)·
29f00c ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHOTOSCROLLBAR), SW_HIDE);
4ae543 ¤   ¤   ¤   else {
89a58b ¤   ¤   ¤   ¤   si.cbSize = sizeof(SCROLLINFO);
8782a9 ¤   ¤   ¤   ¤   si.fMask = SIF_ALL;
f9b834 ¤   ¤   ¤   ¤   si.nMin = 0;
78f318 ¤   ¤   ¤   ¤   si.nMax = iNumPhotoID-1;
fcbb13 ¤   ¤   ¤   ¤   si.nPage = 1;
feb590 ¤   ¤   ¤   ¤   si.nPos = pkmpss->iPhotoIDIndex;
4036b6 ¤   ¤   ¤   ¤   SetScrollInfo (GetDlgItem (hDlg, IDC_PHOTOSCROLLBAR), SB_CTL,
2b43cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &si, TRUE);
ca8a57 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PHOTOSCROLLBAR), SW_SHOW);
c2a3a6 ¤   ¤   ¤   }
b0af5a
7d65a0 ¤   ¤   ¤   // reset userid to selected one
0349c5 ¤   ¤   ¤   PGPKeyIterSeek (keyiter, pkmpss->key);
e14339 ¤   ¤   ¤   PGPKeyIterNextUserID (keyiter, &userid);
5813ee ¤   ¤   ¤   iNumPhotoID = -1;
778f2e ¤   ¤   ¤   while (userid) {
b9f68a ¤   ¤   ¤   ¤   PGPGetUserIDBoolean (userid,·
360427 ¤   ¤   ¤   ¤   ¤   ¤   kPGPUserIDPropIsAttribute, &bAttrib);
7fd7bf ¤   ¤   ¤   ¤   if (bAttrib) {
4ce52f ¤   ¤   ¤   ¤   ¤   PGPGetUserIDNumber (userid,·
06291d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPUserIDPropAttributeType, &iType);
f7a4a7 ¤   ¤   ¤   ¤   ¤   if (iType == kPGPAttribute_Image)
853962 ¤   ¤   ¤   ¤   ¤   ¤   iNumPhotoID++;
bc2613 ¤   ¤   ¤   ¤   }
fee522 ¤   ¤   ¤   ¤   if (pkmpss->iPhotoIDIndex == iNumPhotoID) {
5d5fa6 ¤   ¤   ¤   ¤   ¤   PGPGetUserIDNumber (userid,
0429ed ¤   ¤   ¤   ¤   ¤   ¤   kPGPUserIDPropValidity, &u);
1210c2 ¤   ¤   ¤   ¤   ¤   u = KMConvertFromPGPValidity (u);
fc0c75 ¤   ¤   ¤   ¤   ¤   if (u < (UINT)pkmpss->pKM->iValidityThreshold)
2dd587 ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->bPhotoInvalid = TRUE;
3d4bd6 ¤   ¤   ¤   ¤   ¤   else
e2c121 ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->bPhotoInvalid = FALSE;
b714c3 ¤   ¤   ¤   ¤   ¤   break;
402613 ¤   ¤   ¤   ¤   }
4c2c0a ¤   ¤   ¤   ¤   PGPKeyIterNextUserID (keyiter, &userid);
4ca3a6 ¤   ¤   ¤   }
6a0699 ¤   ¤   ¤   PGPFreeKeyIter (keyiter);
55b534 ¤   ¤   ¤   PGPFreeKeyList (keylist);
99af5a
60b74f ¤   ¤   ¤   // get length of photo id buffer
--f582 000e59018d2401102b2 Page 33 of KMProps.c
57b2bb ¤   ¤   ¤   PGPGetUserIDStringBuffer (userid, kPGPUserIDPropAttributeData,·
1e7692 ¤   ¤   ¤   ¤   ¤   1, NULL, &(pkmpss->iPhotoBufferLength));
1caf5a
4603ab ¤   ¤   ¤   if (pkmpss->iPhotoBufferLength > 0) {
9490d4 ¤   ¤   ¤   ¤   // now actually get the buffer data
7ecd41 ¤   ¤   ¤   ¤   pkmpss->pPhotoBuffer = KMAlloc (pkmpss->iPhotoBufferLength);
fe8b84 ¤   ¤   ¤   ¤   PGPGetUserIDStringBuffer (userid, kPGPUserIDPropAttributeData,
33d8db ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->iPhotoBufferLength, pkmpss->pPhotoBuffer,·
59baa6 ¤   ¤   ¤   ¤   ¤   ¤   &(pkmpss->iPhotoBufferLength));
d5af5a
090b07 ¤   ¤   ¤   ¤   // no more SDK calls, release to avoid palette-related lockup
c4e392 ¤   ¤   ¤   ¤   if (wParam == SERIALIZE) {
2ed6ec ¤   ¤   ¤   ¤   ¤   wParam = NOSERIALIZE;
b1aa9c ¤   ¤   ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
2c2613 ¤   ¤   ¤   ¤   }
48af5a
2c7339 ¤   ¤   ¤   ¤   if (IsntPGPError (KMDIBfromPhoto (pkmpss->pPhotoBuffer,·
d25903 ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->iPhotoBufferLength, TRUE, &lpbmi))) {
9eae49 ¤   ¤   ¤   ¤   ¤   if (lpbmi) {
a05d83 ¤   ¤   ¤   ¤   ¤   ¤   KMGetDIBSize (lpbmi, &(pkmpss->iwidthPhotoID),
dcd9ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·&(pkmpss->iheightPhotoID));
27479a ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->hbitmapPhotoID = KMDDBfromDIB (lpbmi,·
74332d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(pkmpss->hpalettePhotoID));·
3faf5a
f091db ¤   ¤   ¤   ¤   ¤   ¤   KMFree (lpbmi);
a51c89 ¤   ¤   ¤   ¤   ¤   }
1f2613 ¤   ¤   ¤   ¤   }
b2a3a6 ¤   ¤   ¤   }
ee0fe4 ¤   ¤   }
24af5a
2fdb8f ¤   ¤   if (wParam == SERIALIZE)
004ba3 ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
30af5a
7ecf9b ¤   ¤   if (pkmpss->hwndRevokerDlg) {
e42c9a ¤   ¤   ¤   SendMessage (pkmpss->hwndRevokerDlg, WM_APP, wParam, 0);
92146d ¤   ¤   ¤   InvalidateRect (pkmpss->hwndRevokers, NULL, TRUE);
15ba05 ¤   ¤   ¤   UpdateWindow (pkmpss->hwndRevokers);
690fe4 ¤   ¤   }
5c1b52 ¤   ¤
493e34 ¤   ¤   pkmpss->bReadyToPaint = TRUE;
baea47 ¤   ¤   InvalidateRect (hDlg, NULL, FALSE);
1c2f68 ¤   ¤   break;
d0af5a
516286 ¤   case WM_APP+1 :
6842ef ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTSLIDER), FALSE);
e952b0 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTTEXT1), FALSE);
f9d55e ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_TRUSTTEXT2), FALSE);
153cfa ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_AXIOMATIC), FALSE);
119a97 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_ENABLED), FALSE);
d43201 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_CHANGEPHRASE), FALSE);
8d8d80 ¤   ¤   EnableWindow (GetDlgItem (GetParent(hDlg), IDOK), FALSE);
242f68 ¤   ¤   break;
0daf5a
6f474b ¤   case WM_APP+2 :
f410e7 ¤   ¤   pkmpss->userid = (PGPUserIDRef)lParam;
58f29a ¤   ¤   PostMessage (hDlg, WM_APP, 0, 0);
792f68 ¤   ¤   break;
32af5a
9185ca ¤   case WM_PAINT :
9e7cf5 ¤   ¤   if (pkmpss->bReadyToPaint)
381e94 ¤   ¤   ¤   sPaintPhotoID (hDlg,·
7a36c7 ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->hbitmapPhotoID, pkmpss->hpalettePhotoID,
95c243 ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->iwidthPhotoID, pkmpss->iheightPhotoID,
a55287 ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->bPhotoInvalid, pkmpss->bRevoked,
27e40e ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->bExpired);
9f07e0 ¤   ¤   else {
6f5374 ¤   ¤   ¤   PAINTSTRUCT¤ps;
2daf5a
3b6494 ¤   ¤   ¤   BeginPaint (hDlg, &ps);
3c5dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
dd0fe4 ¤   ¤   }
e52f68 ¤   ¤   break;
--b092 000aea06772401102b2 Page 34 of KMProps.c
e0af5a
d7ea1a ¤   case WM_PALETTECHANGED :
bd31ad ¤   ¤   if ((HWND)wParam != hDlg)·
3430e1 ¤   ¤   ¤   sUpdatePalette (hDlg, pkmpss);
ab2f68 ¤   ¤   break;
8daf5a
0fdfee ¤   case WM_QUERYNEWPALETTE :
a7b103 ¤   ¤   return (sUpdatePalette (hDlg, pkmpss));
afaf5a
c025ea ¤   case WM_HSCROLL :
4f7643 ¤   case WM_VSCROLL :
ffeae9 ¤   ¤   // check if originating from trust slider
511d21 ¤   ¤   if ((HWND)lParam == GetDlgItem (hDlg, IDC_TRUSTSLIDER)) {
f68f03 ¤   ¤   ¤   if (LOWORD (wParam) == TB_ENDTRACK)·
76f776 ¤   ¤   ¤   {
751edd ¤   ¤   ¤   ¤   u = SendDlgItemMessage (hDlg, IDC_TRUSTSLIDER, TBM_GETPOS,·
cff311 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0);
309eff ¤   ¤   ¤   ¤   uTrust = sConvertToPGPTrust (u);
1e8ba9 ¤   ¤   ¤   ¤   if (uTrust == pkmpss->uTrust) break;
80af5a
a216da ¤   ¤   ¤   ¤   if ((pkmpss->uValidity <= kPGPValidity_Invalid) &&·
89e4d9 ¤   ¤   ¤   ¤   ¤   (uTrust >= kPGPKeyTrust_Marginal))·
7972c3 ¤   ¤   ¤   ¤   {
366aba ¤   ¤   ¤   ¤   ¤   sSetTrustControls (hDlg, pkmpss,·
187c37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyTrust_Never);
6c1d98 ¤   ¤   ¤   ¤   ¤   KMMessageBox (hDlg, IDS_CAPTION,·
2a1d63 ¤   ¤   ¤   ¤   ¤   ¤   IDS_TRUSTONINVALIDKEY,·
f305cf ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
8b2613 ¤   ¤   ¤   ¤   }
0e5109 ¤   ¤   ¤   ¤   else·
a872c3 ¤   ¤   ¤   ¤   {
fe0195 ¤   ¤   ¤   ¤   ¤   pkmpss->uTrust = uTrust;
7faa00 ¤   ¤   ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
89eb4f ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (hDlg,·
78c37b ¤   ¤   ¤   ¤   ¤   ¤   PGPSetKeyTrust (pkmpss->key, uTrust))))
fa4859 ¤   ¤   ¤   ¤   ¤   {
993f69 ¤   ¤   ¤   ¤   ¤   ¤   if (!pkmpss->bReadOnly)
f28683 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCommitKeyRingChanges (pkmpss->pKM->KeySetMain);
c1af5a
a4a9eb ¤   ¤   ¤   ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
6602b8 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage (pkmpss->pKM->hWndParent,·
9b818d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KM_M_KEYPROPACTION,·
76ffe2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KM_PROPACTION_UPDATEKEY,·
667e37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)(pkmpss->key));
3c601f ¤   ¤   ¤   ¤   ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
da1c89 ¤   ¤   ¤   ¤   ¤   }
554bd6 ¤   ¤   ¤   ¤   ¤   else
1ca9eb ¤   ¤   ¤   ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
7b2613 ¤   ¤   ¤   ¤   }
61a3a6 ¤   ¤   ¤   }
c90fe4 ¤   ¤   }
bc619e ¤   ¤   // otherwise, must be coming from photoid scrollbar
6e07e0 ¤   ¤   else {
0a3f20 ¤   ¤   ¤   INT¤iNewPos;
5aaf5a
6822c7 ¤   ¤   ¤   iNewPos = pkmpss->iPhotoIDIndex;
0eaf5a
d2bc0e ¤   ¤   ¤   switch (LOWORD(wParam)) {
eaabd3 ¤   ¤   ¤   case SB_TOP :
2101cf ¤   ¤   ¤   ¤   iNewPos = 0;
3ef622 ¤   ¤   ¤   ¤   break;
08af5a
bd5fee ¤   ¤   ¤   case SB_BOTTOM :
8906fa ¤   ¤   ¤   ¤   iNewPos = pkmpss->iNumPhotoIDs-1;
85f622 ¤   ¤   ¤   ¤   break;
3caf5a
e9c141 ¤   ¤   ¤   case SB_PAGELEFT :
2509e5 ¤   ¤   ¤   case SB_LINELEFT :
a18763 ¤   ¤   ¤   ¤   iNewPos = pkmpss->iPhotoIDIndex-1;
893a49 ¤   ¤   ¤   ¤   if (iNewPos < 0) iNewPos = 0;
71f622 ¤   ¤   ¤   ¤   break;
aeaf5a
--0306 000863ce09a401102b2 Page 35 of KMProps.c
678946 ¤   ¤   ¤   case SB_PAGERIGHT :
976aa0 ¤   ¤   ¤   case SB_LINERIGHT :
17ccf9 ¤   ¤   ¤   ¤   iNewPos = pkmpss->iPhotoIDIndex+1;
671749 ¤   ¤   ¤   ¤   if (iNewPos >= pkmpss->iNumPhotoIDs)·
f3a8fb ¤   ¤   ¤   ¤   ¤   iNewPos = pkmpss->iNumPhotoIDs-1;
6bf622 ¤   ¤   ¤   ¤   break;
a4af5a
35a68b ¤   ¤   ¤   case SB_THUMBPOSITION :
b541aa ¤   ¤   ¤   case SB_THUMBTRACK :
0e7f6f ¤   ¤   ¤   ¤   iNewPos = HIWORD(wParam);
72af5a
970082 ¤   ¤   ¤   default :
84f622 ¤   ¤   ¤   ¤   break;
0ba3a6 ¤   ¤   ¤   }
07af5a
b945bb ¤   ¤   ¤   if (iNewPos != pkmpss->iPhotoIDIndex) {
f91738 ¤   ¤   ¤   ¤   pkmpss->userid = kInvalidPGPUserIDRef;
ca8974 ¤   ¤   ¤   ¤   pkmpss->iPhotoIDIndex = iNewPos;
0b3e06 ¤   ¤   ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
8ba3a6 ¤   ¤   ¤   }
890fe4 ¤   ¤   }
f3bbde ¤   ¤   return 0;
9baf5a
f1a96f ¤   case WM_DESTROY:·
eb7486 ¤   ¤   SetWindowLong(GetDlgItem(hDlg, IDC_PHOTOID),·
991a30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG)pkmpss->wpOrigPhotoIDProc);·
0bec73 ¤   ¤   SetWindowLong(GetDlgItem(hDlg, IDC_FINGERPRINT),·
4c0ef4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG)pkmpss->wpOrigFingerProc);·
76ca2d ¤   ¤   break;·
9aaf5a
653fcf ¤   case WM_COMMAND:
e3379d ¤   ¤   switch(LOWORD (wParam)) {
198a1c ¤   ¤   ¤   case IDC_CHANGEPHRASE :
6ad684 ¤   ¤   ¤   ¤   if (pkmpss->bSecret) {
ecaa00 ¤   ¤   ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
e85e39 ¤   ¤   ¤   ¤   ¤   if (KMChangePhrase (GetParent (hDlg),·
423f34 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->pKM,·
4d11de ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->pKM->Context,·
4c2754 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->pKM->tlsContext,
61a7c9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->keyset,·
fad566 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->key))
b34859 ¤   ¤   ¤   ¤   ¤   {
6a05af ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->bNeedsCommit = TRUE;
851c89 ¤   ¤   ¤   ¤   ¤   }
32aa9c ¤   ¤   ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
a1dc06 ¤   ¤   ¤   ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
ad2613 ¤   ¤   ¤   ¤   }
dcf622 ¤   ¤   ¤   ¤   break;
21af5a
9665aa ¤   ¤   ¤   case IDC_AXIOMATIC :
fc0401 ¤   ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
a551a0 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (
ed227c ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_AXIOMATIC) == BST_CHECKED)·
6472c3 ¤   ¤   ¤   ¤   {
8f5718 ¤   ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (
4fff88 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_ENABLED) == BST_UNCHECKED)·
754859 ¤   ¤   ¤   ¤   ¤   {
e13fae ¤   ¤   ¤   ¤   ¤   ¤   PGPEnableKey (pkmpss->key);
2d1c89 ¤   ¤   ¤   ¤   ¤   }
4b7329 ¤   ¤   ¤   ¤   ¤   PGPSetKeyAxiomatic (pkmpss->key,
0eb334 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pkmpss->pKM->Context));
052613 ¤   ¤   ¤   ¤   }
eafa07 ¤   ¤   ¤   ¤   else
403325 ¤   ¤   ¤   ¤   ¤   PGPUnsetKeyAxiomatic (pkmpss->key);
afaf5f ¤   ¤   ¤   ¤   if (!pkmpss->bReadOnly)
8dbb0f ¤   ¤   ¤   ¤   ¤   PGPCommitKeyRingChanges (pkmpss->pKM->KeySetMain);
06049d ¤   ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
beeebe ¤   ¤   ¤   ¤   SendMessage (pkmpss->pKM->hWndParent, KM_M_KEYPROPACTION,·
40db41 ¤   ¤   ¤   ¤   ¤   ¤   KM_PROPACTION_UPDATEKEY, (LPARAM)(pkmpss->key));
d63e06 ¤   ¤   ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
c8f622 ¤   ¤   ¤   ¤   break;
862b85 ¤   ¤   ¤   ¤
--fab1 000c398c247401102b2 Page 36 of KMProps.c
f6f78b ¤   ¤   ¤   case IDC_ENABLED :
bb0401 ¤   ¤   ¤   ¤   KMRequestSDKAccess (pkmpss->pKM);
a451a0 ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (
7afeda ¤   ¤   ¤   ¤   ¤   ¤   ¤   hDlg, IDC_ENABLED) == BST_CHECKED)·
74a9ef ¤   ¤   ¤   ¤   ¤   PGPEnableKey (pkmpss->key);
d85109 ¤   ¤   ¤   ¤   else·
b65c69 ¤   ¤   ¤   ¤   ¤   PGPDisableKey (pkmpss->key);
9caf5f ¤   ¤   ¤   ¤   if (!pkmpss->bReadOnly)
6dbb0f ¤   ¤   ¤   ¤   ¤   PGPCommitKeyRingChanges (pkmpss->pKM->KeySetMain);
8c049d ¤   ¤   ¤   ¤   KMReleaseSDKAccess (pkmpss->pKM);
50eebe ¤   ¤   ¤   ¤   SendMessage (pkmpss->pKM->hWndParent, KM_M_KEYPROPACTION,·
65db41 ¤   ¤   ¤   ¤   ¤   ¤   KM_PROPACTION_UPDATEKEY, (LPARAM)(pkmpss->key));
903e06 ¤   ¤   ¤   ¤   PostMessage (hDlg, WM_APP, SERIALIZE, 0);
f4f622 ¤   ¤   ¤   ¤   break;
93af5a
42d5ac ¤   ¤   ¤   case IDM_COPYBITMAP :
4c8049 ¤   ¤   ¤   ¤   KMCopyPhotoToClipboard (hDlg, pkmpss->pPhotoBuffer,·
fb0d8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkmpss->iPhotoBufferLength);
60f622 ¤   ¤   ¤   ¤   break;
120fe4 ¤   ¤   }
d6836c ¤   ¤   return TRUE;
b3af5a
1dc3eb ····case WM_HELP:·
be638a ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pkmpss->pKM->szHelpFile,·
70ef82 ············HELP_WM_HELP, (DWORD) (LPSTR) aKeyPropIds);·
df8f13 ········break;·
12d83c ·
954fd8 ····case WM_CONTEXTMENU:·
625409 ········WinHelp ((HWND) wParam, pkmpss->pKM->szHelpFile, HELP_CONTEXTMENU,·
aa390f ············(DWORD) (LPVOID) aKeyPropIds);·
bf8f13 ········break;·
0daf5a
dd1431 ¤   case WM_NOTIFY :
670f7c ¤   ¤   switch (((NMHDR FAR *) lParam)->code) {
8ea305 //¤ ¤   case PSN_SETACTIVE :
7a309a //¤ ¤   ¤   break;
0caf5a
ca8074 //¤ ¤   case PSN_APPLY :
469dd9 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
b79525 //¤ ¤   ¤   return TRUE;
dbaf5a
3e1b03 ¤   ¤   case PSN_HELP :
3fdf94 ¤   ¤   ¤   WinHelp (hDlg, pkmpss->pKM->szHelpFile, HELP_CONTEXT,·
172e96 ¤   ¤   ¤   ¤   IDH_PGPKM_PROPDIALOG);·
34cdcb ¤   ¤   ¤   break;
4aaf5a
ca1e4a //¤ ¤   case PSN_KILLACTIVE :
89ccd4 //¤ ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
489525 //¤ ¤   ¤   return TRUE;
bd0fe4 ¤   ¤   }
a2836c ¤   ¤   return TRUE;
069371 ¤   }
dba230 ¤   return FALSE;
36efe6 }
34af5a
be4265 //¤ ___________________________________________________
95465d //
546e0e // ·Post Key Properties Dialog·
48af5a
c2e8c0 static DWORD WINAPI·
4bee13 sSingleKeyThread (THREADSTRUCT* pts)·
59bb36 {
692a7e ¤   CHAR¤   ¤   ¤   ¤   szTitle[32];
cd3a92 ¤   CHAR¤   ¤   ¤   ¤   szUserName[kPGPMaxUserIDSize];
c774d9 ····PROPSHEETPAGE¤  ¤   psp;
9e557c ····PROPSHEETHEADER¤¤   psh;
b2b9a7 ¤   HPROPSHEETPAGE¤ ¤   hpsp[4];
de4114 ¤   KMPROPSHEETSTRUCT¤  kmpss;
35ccdd ¤   INT¤¤   ¤   ¤   ¤   i, iRetVal;
1b8f52 ¤   PGPError¤   ¤   ¤   err;
57be29 #if PGP_BUSINESS_SECURITY
c3697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
--01cf 000bab6afb7401102b2 Page 37 of KMProps.c
a07454 #endif
e0af5a
3993cc ¤   iRetVal = 0;
36af5a
937e99 ¤   for (i=0; i<MAXSHEETS; i++) {
293582 ¤   ¤   if (!pts->pKM->KeyTable[i]) {
f37bb5 ¤   ¤   ¤   if (!pts->pKM->hWndTable[i]) {
3e2e4d ¤   ¤   ¤   ¤   pts->pKM->KeyTable[i] = pts->key;
5356e4 ¤   ¤   ¤   ¤   kmpss.iIndex = i;
19f622 ¤   ¤   ¤   ¤   break;
27a3a6 ¤   ¤   ¤   }
e90fe4 ¤   ¤   }
1a9371 ¤   }
21af5a
acb1de ¤   kmpss.pKM¤  ¤   ¤   ¤   ¤   = pts->pKM;
f40e6d ¤   kmpss.key¤  ¤   ¤   ¤   ¤   = pts->key;
4f4ed3 ¤   kmpss.keyset¤   ¤   ¤   ¤   = pts->keyset;
33ce4e ¤   kmpss.userid¤   ¤   ¤   ¤   = pts->userid;
4450e9 ¤   kmpss.bNeedsCommit¤ ¤   ¤   = FALSE;
b9f053 ¤   kmpss.bReadyToPaint¤¤   ¤   = FALSE;
442b38 ¤   kmpss.hIml¤ ¤   ¤   ¤   ¤   = NULL;
b78aeb ¤   kmpss.iPhotoIDIndex¤¤   ¤   = -1;
b81c47 ¤   kmpss.hbitmapPhotoID¤   ¤   = NULL;
0f414b ¤   kmpss.hpalettePhotoID¤  ¤   = NULL;
0b1e80 ¤   kmpss.pPhotoBuffer¤ ¤   ¤   = NULL;
1c0149 ¤   kmpss.iPhotoBufferLength¤   = 0;
76da27 ¤   kmpss.hwndRevokerDlg¤   ¤   = NULL;
4baf5a
5f4efc ¤   if ((pts->pKM->ulOptionFlags & KMF_READONLY) ||
8a15e5 ¤   ¤   !(pts->pKM->ulOptionFlags & KMF_ENABLECOMMITS))
288bc7 ¤   ¤   kmpss.bReadOnly = TRUE;
310e24 ¤   else
2d837b ¤   ¤   kmpss.bReadOnly = FALSE;
53af5a
b65f8e ¤   KMRequestSDKAccess (kmpss.pKM);
54af5a
c9be29 #if PGP_BUSINESS_SECURITY
71164e #if PGP_ADMIN_BUILD
93654a ¤   err = PGPclOpenAdminPrefs (
3042e3 ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (kmpss.pKM->Context),·
a57152 ¤   ¤   ¤   ¤   &prefref, TRUE);
80db21 #else
29654a ¤   err = PGPclOpenAdminPrefs (
4c42e3 ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (kmpss.pKM->Context),·
a8ea90 ¤   ¤   ¤   ¤   &prefref, FALSE);
0c3cce #endif¤ // PGP_ADMIN_BUILD
5c0d9b ¤   kmpss.bKeyGenEnabled = FALSE;
3730d4 ¤   kmpss.uMinSubkeySize = MINSUBKEYSIZE;
5ab23e ¤   if (IsntPGPError (err)) {
62ae23 ¤   ¤   PGPGetPrefBoolean (prefref, kPGPPrefAllowKeyGen,·
d59b76 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &kmpss.bKeyGenEnabled);
2d5f70 ¤   ¤   PGPGetPrefNumber (prefref, kPGPPrefMinimumKeySize,·
2ed669 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &kmpss.uMinSubkeySize);
86d8f2 ¤   ¤   PGPclCloseAdminPrefs (prefref, FALSE);
839371 ¤   }
44db21 #else
2933ed ¤   kmpss.bKeyGenEnabled = TRUE;
1630d4 ¤   kmpss.uMinSubkeySize = MINSUBKEYSIZE;
d197b2 #endif¤ // PGP_BUSINESS_SECURITY
d5af5a
c3e1b5 ¤   PGPCountAdditionalRecipientRequests (pts->key, &kmpss.uNumberADKs);
2420af ¤   PGPCountRevocationKeys (pts->key, &kmpss.uNumberRevokers);
800cf6 ¤   PGPGetKeyNumber (kmpss.key, kPGPKeyPropAlgID, &kmpss.algKey);
0caf5a
f89696 ¤   KMReleaseSDKAccess (kmpss.pKM);
1faf5a
99ab95 ¤   psh.nPages = 1;¤¤   //always show the general sheet
283823 ¤   LoadString (g_hInst, IDS_PROPTITLE0, szTitle, sizeof(szTitle));
d7c7fe ····psp.dwSize = sizeof(PROPSHEETPAGE);
f6cf9e ····psp.dwFlags = PSP_USETITLE | PSP_HASHELP;
464fdc ····psp.hInstance = g_hInst;
ba6217 ¤   psp.pszTemplate = MAKEINTRESOURCE (IDD_KEYPROPGENERAL);
--f8ce 000be00b495401102b2 Page 38 of KMProps.c
c6ef26 ····psp.pszIcon = NULL;
ef9c0a ····psp.pfnDlgProc = sKeyPropDlgProcGeneral;
f2a3bb ····psp.pszTitle = szTitle;
71de43 ····psp.lParam = (LPARAM)&kmpss;
b51eb4 ····psp.pfnCallback = NULL;
b4a04c ¤   hpsp[0] = CreatePropertySheetPage (&psp);
87af5a
acaaca ¤   if (kmpss.algKey == kPGPPublicKeyAlgorithm_DSA) {
b056a7 ¤   ¤   LoadString (g_hInst, IDS_PROPTITLE1, szTitle, sizeof(szTitle));
a5e0a1 ¤   ¤   psp.dwSize = sizeof(PROPSHEETPAGE);
c080a0 ¤   ····psp.dwFlags = PSP_USETITLE | PSP_HASHELP;
baf48a ¤   ····psp.hInstance = g_hInst;
08474b ¤   ¤   psp.pszTemplate = MAKEINTRESOURCE (IDD_KEYPROPSUBKEYS);
bbdc58 ¤   ¤   psp.pszIcon = NULL;
d1eac2 ¤   ¤   psp.pfnDlgProc = sKeyPropDlgProcSubkey;
583e76 ¤   ¤   psp.pszTitle = szTitle;
498c00 ¤   ¤   psp.lParam = (LPARAM)&kmpss;
de8379 ¤   ¤   psp.pfnCallback = NULL;
dcc6bd ¤   ¤   hpsp[psh.nPages] = CreatePropertySheetPage (&psp);
e287f6 ¤   ¤   psh.nPages++;
ba9371 ¤   }
9faf5a
23a7b6 ¤   if (kmpss.uNumberADKs > 0) {
3837b2 ¤   ¤   LoadString (g_hInst, IDS_PROPTITLE2, szTitle, sizeof(szTitle));
cf4f98 ¤   ····psp.dwSize = sizeof(PROPSHEETPAGE);
3880a0 ¤   ····psp.dwFlags = PSP_USETITLE | PSP_HASHELP;
0bf48a ¤   ····psp.hInstance = g_hInst;
62fa97 ¤   ¤   psp.pszTemplate = MAKEINTRESOURCE (IDD_KEYPROPADK);
a61943 ¤   ····psp.pszIcon = NULL;
fea042 ¤   ····psp.pfnDlgProc = sKeyPropDlgProcADK;
ed0ee5 ¤   ····psp.pszTitle = szTitle;
23e32b ¤   ····psp.lParam = (LPARAM)&kmpss;
d2b3ea ¤   ····psp.pfnCallback = NULL;
79c6bd ¤   ¤   hpsp[psh.nPages] = CreatePropertySheetPage (&psp);
9e87f6 ¤   ¤   psh.nPages++;
ef9371 ¤   }
a2af5a
678c09 ¤   if (kmpss.uNumberRevokers > 0) {
ab1741 ¤   ¤   LoadString (g_hInst, IDS_PROPTITLE3, szTitle, sizeof(szTitle));
5e4f98 ¤   ····psp.dwSize = sizeof(PROPSHEETPAGE);
d680a0 ¤   ····psp.dwFlags = PSP_USETITLE | PSP_HASHELP;
34f48a ¤   ····psp.hInstance = g_hInst;
4be53b ¤   ¤   psp.pszTemplate = MAKEINTRESOURCE (IDD_KEYPROPREVOKERS);
401943 ¤   ····psp.pszIcon = NULL;
88d626 ¤   ····psp.pfnDlgProc = sKeyPropDlgProcRevokers;
040ee5 ¤   ····psp.pszTitle = szTitle;
0ae32b ¤   ····psp.lParam = (LPARAM)&kmpss;
ddb3ea ¤   ····psp.pfnCallback = NULL;
6fc6bd ¤   ¤   hpsp[psh.nPages] = CreatePropertySheetPage (&psp);
1c87f6 ¤   ¤   psh.nPages++;
a29371 ¤   }
9faf5a
9a7b53 ¤   KMGetKeyName (pts->key, szUserName, sizeof(szUserName));
0fe7b1 ····psh.dwSize = sizeof(PROPSHEETHEADER);
e2042c ····psh.dwFlags = PSH_NOAPPLYNOW;
e3175f ¤   if (pts->pKM->ulOptionFlags & KMF_MODALPROPERTIES)
030f1f ¤   ¤   psh.hwndParent = pts->pKM->hWndParent;
ae0e24 ¤   else
4c5d64 ¤   ¤   psh.hwndParent = NULL;
2afdc8 ····psh.hInstance = g_hInst;
b1e6e6 ····psh.pszIcon = NULL;
c3e097 ····psh.pszCaption = (LPSTR) szUserName;
7aaf5a
99a961 ····psh.nStartPage = 0;
c3f253 ····psh.phpage = &hpsp[0];
08b973 ····psh.pfnCallback = NULL;
60af5a
bd66e0 ····PropertySheet(&psh);
42af5a
3853d3 ¤   kmpss.pKM->KeyTable[kmpss.iIndex] = NULL;
0b2889 ¤   kmpss.pKM->iNumberSheets--;
beaf5a
--c5d7 0009095920b401102b2 Page 39 of KMProps.c
5917a8 ¤   if (kmpss.pKM->ulOptionFlags & KMF_ENABLECOMMITS) {
24af5a
2453c0 ¤   ¤   // if anything changed, commit the changes
1f3b25 ¤   ¤   if (kmpss.bNeedsCommit) {
143b64 ¤   ¤   ¤   HCURSOR¤¤   hCursorOld;·
a6b8fe ¤   ¤   ¤   UINT¤   ¤   uReloadMessage;
7eaf5a
b64a25 ¤   ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
0c12bd ¤   ¤   ¤   KMRequestSDKAccess (kmpss.pKM);
a6ce5c ¤   ¤   ¤   err = PGPCommitKeyRingChanges (kmpss.pKM->KeySetMain);
cafac5 ¤   ¤   ¤   SetCursor (hCursorOld);
dedba5 ¤   ¤   ¤   KMReleaseSDKAccess (kmpss.pKM);
c71567 ¤   ¤   ¤   SendMessage (kmpss.pKM->hWndParent, KM_M_KEYPROPACTION,·
55aa81 ¤   ¤   ¤   ¤   ¤   ¤   KM_PROPACTION_UPDATEKEY, (LPARAM)(kmpss.key));
cfaf5a
e29de8 ¤   ¤   ¤   KMUpdateKeyPropertiesThread (kmpss.pKM);
02af5a
8f939e ¤   ¤   ¤   if (kmpss.pKM->ulOptionFlags & KMF_ENABLERELOADS) {
d356ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
6a5ab4 ¤   ¤   ¤   ¤   ¤   uReloadMessage =·
01497f ¤   ¤   ¤   ¤   ¤   ¤   RegisterWindowMessage (RELOADKEYRINGMSG);
6c5868 ¤   ¤   ¤   ¤   ¤   PostMessage (HWND_BROADCAST, uReloadMessage,·
6f1225 ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (LOWORD (kmpss.pKM->hWndParent),·
eb9e4d ¤   ¤   ¤   ¤   ¤   ¤   FALSE), GetCurrentProcessId ());
fb1b43 ¤   ¤   ¤   ¤   ¤   Sleep (200);
892613 ¤   ¤   ¤   ¤   }
86a3a6 ¤   ¤   ¤   }
ada940 ¤   ¤   ¤   InvalidateRect (kmpss.pKM->hWndTree, NULL, TRUE);
580fe4 ¤   ¤   }
7f9371 ¤   }
35af5a
39a687 ¤   kmpss.pKM->hWndTable[kmpss.iIndex] = NULL;
f2af5a
fba43f ¤   if (kmpss.pKM->iNumberSheets == 0) {
73f900 ¤   ¤   SetActiveWindow (kmpss.pKM->hWndParent);
e69371 ¤   }
7baf5a
837de7 ¤   // free allocated objects
b5e3f5 ¤   if (kmpss.hbitmapPhotoID) {
af5805 ¤   ¤   DeleteObject (kmpss.hbitmapPhotoID);
e29c1b ¤   ¤   kmpss.hbitmapPhotoID = NULL;
6d9371 ¤   }
739e6d ¤   if (kmpss.hpalettePhotoID)·
87e574 ¤   ¤   DeleteObject (kmpss.hpalettePhotoID);
83652b ¤   if (kmpss.pPhotoBuffer)·
b387ac ¤   ¤   KMFree (kmpss.pPhotoBuffer);
1daf5a
bdb5f8 ¤   return iRetVal;
27efe6 }
ceaf5a
34af5a
cf4265 //¤ ___________________________________________________
ae465d //
fe6e0e // ·Post Key Properties Dialog·
34af5a
903f64 static BOOL CALLBACK·
4d7668 sSingleKeyProperties (TL_TREEITEM* lptli, LPARAM lParam)·
33bb36 {
d7c1d5 ¤   PGPUserIDRef¤   userid¤ ¤   ¤   = kInvalidPGPUserIDRef;
7af0d5 ¤   DWORD¤  ¤   ¤   dwID;
2b1502 ¤   PGPKeyRef¤  ¤   key;
62fead ¤   PGPKeySetRef¤   keyset;
5cfb19 ¤   PGPError¤   ¤   err;
dda485 ¤   PGPSigRef¤  ¤   cert;
ec1fe7 ¤   BOOL¤   ¤   ¤   bContinue;
c0dfcd ¤   INT¤¤   ¤   ¤   i;
3abda6 ¤   THREADSTRUCT*¤  pts;
221e22 ¤   PROPSTRUCT*¤¤   pps = (PROPSTRUCT*)lParam;
89af5a
b36919 ¤   switch (lptli->iImage) {
c15b97 ¤   case IDX_RSASECKEY :
90b4cd ¤   case IDX_RSASECDISKEY :
--469c 0007be15a77401102b2 Page 40 of KMProps.c
dc2487 ¤   case IDX_RSASECREVKEY :
d18b99 ¤   case IDX_RSASECEXPKEY :
7ebcd1 ¤   case IDX_RSASECSHRKEY :
7c493d ¤   case IDX_RSAPUBKEY :
4c6e41 ¤   case IDX_RSAPUBDISKEY :
9cfe0b ¤   case IDX_RSAPUBREVKEY :
9d5115 ¤   case IDX_RSAPUBEXPKEY :
e24982 ¤   case IDX_DSASECKEY :
fbaec4 ¤   case IDX_DSASECDISKEY :
b33e8e ¤   case IDX_DSASECREVKEY :
289190 ¤   case IDX_DSASECEXPKEY :
e1a6d8 ¤   case IDX_DSASECSHRKEY :
4e5b28 ¤   case IDX_DSAPUBKEY :
127448 ¤   case IDX_DSAPUBDISKEY :
81e402 ¤   case IDX_DSAPUBREVKEY :
2e4b1c ¤   case IDX_DSAPUBEXPKEY :
9a14a7 ¤   ¤   key = (PGPKeyRef)(lptli->lParam);
e92b0a ¤   ¤   keyset = pps->pKM->KeySetDisp;
8cc107 ¤   ¤   bContinue = TRUE;
2a2f68 ¤   ¤   break;
96af5a
0cb951 ¤   case IDX_RSAUSERID :
0aab44 ¤   case IDX_DSAUSERID :
db5d7a ¤   case IDX_INVALIDUSERID :
a0b234 ¤   ¤   userid = (PGPUserIDRef)(lptli->lParam);
499961 ¤   ¤   key = KMGetKeyFromUserID (pps->pKM, userid);
a92b0a ¤   ¤   keyset = pps->pKM->KeySetDisp;
8ae477 ¤   ¤   userid = kInvalidPGPUserIDRef;
c2453d ¤   ¤   bContinue = FALSE;
122f68 ¤   ¤   break;
aeaf5a
ff304b ¤   case IDX_PHOTOUSERID :
c6b234 ¤   ¤   userid = (PGPUserIDRef)(lptli->lParam);
849961 ¤   ¤   key = KMGetKeyFromUserID (pps->pKM, userid);
a32b0a ¤   ¤   keyset = pps->pKM->KeySetDisp;
b2453d ¤   ¤   bContinue = FALSE;
d32f68 ¤   ¤   break;
cbaf5a
b06533 ¤   case IDX_CERT :
821c1f ¤   case IDX_REVCERT :
dea1bf ¤   case IDX_BADCERT :
f18f71 ¤   case IDX_EXPORTCERT :
61c328 ¤   case IDX_TRUSTEDCERT :
cfef7c ¤   case IDX_METACERT :
2ebd2a ¤   ¤   cert = (PGPSigRef)(lptli->lParam);
5f4664 ¤   ¤   key = NULL;
e0af5a
890945 ¤   ¤   err = PGPGetSigCertifierKey (cert, pps->pKM->KeySetDisp, &key);
418536 ¤   ¤   if (IsntPGPError (err)) {
c72546 ¤   ¤   ¤   keyset = pps->pKM->KeySetDisp;
ce0fe4 ¤   ¤   }
28af5a
99932c ¤   ¤   if (!key && (pps->pKM->KeySetDisp != pps->pKM->KeySetMain)) {
780501 ¤   ¤   ¤   err = PGPGetSigCertifierKey (cert, pps->pKM->KeySetMain, &key);
dc6a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
39410c ¤   ¤   ¤   ¤   keyset = pps->pKM->KeySetMain;
4ca3a6 ¤   ¤   ¤   }
f30fe4 ¤   ¤   }
03af5a
3d94cd ¤   ¤   PGPclErrorBox (NULL, err);
43c107 ¤   ¤   bContinue = TRUE;
202f68 ¤   ¤   break;
a7af5a
68bfad ¤   default :
3c98aa ¤   ¤   return FALSE;
459371 ¤   }
2baf5a
702a71 ¤   // see if property sheet is already open for this key
0a7e99 ¤   for (i=0; i<MAXSHEETS; i++) {
c405d9 ¤   ¤   if (key == pps->pKM->KeyTable[i]) {
1c947c ¤   ¤   ¤   // if user clicked on userid, communicate this to prop sheet
7b755a ¤   ¤   ¤   if (PGPUserIDRefIsValid (userid)) {
--bb7a 000b2e736b2401102b2 Page 41 of KMProps.c
82731e ¤   ¤   ¤   ¤   SendMessage (pps->pKM->hWndTable[i], WM_APP+2,·
beddc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)userid);
aea3a6 ¤   ¤   ¤   }
d583d0 ¤   ¤   ¤   SetForegroundWindow (pps->pKM->hWndTable[i]);
3332bd ¤   ¤   ¤   return TRUE;
560fe4 ¤   ¤   }
ea9371 ¤   }
a4af5a
ac1db3 ¤   // no existing property sheet for this key,·
95115f ¤   // see if we've reached the max number of sheets
f9acfc ¤   pps->pKM->iNumberSheets++;
080d6a ¤   if (pps->pKM->iNumberSheets > MAXSHEETS) {
10bdc0 ¤   ¤   pps->pKM->iNumberSheets--;
3498aa ¤   ¤   return FALSE;
739371 ¤   }
afaf5a
f608fe ¤   // create sheet for this key
6815fc ¤   if (key) {
4ca4ba ¤   ¤   pts = (THREADSTRUCT*)KMAlloc (sizeof (THREADSTRUCT));
123e27 ¤   ¤   if (pts) {
bea946 ¤   ¤   ¤   pts->pKM = pps->pKM;
afdb0b ¤   ¤   ¤   pts->key = key;
8c1c6c ¤   ¤   ¤   pts->keyset = keyset;
e50e1d ¤   ¤   ¤   pts->userid = userid;
1462f1 ¤   ¤   ¤   _beginthreadex (NULL, 0, sSingleKeyThread,·
b8bf33 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPVOID)pts, 0, &dwID);
ec0fe4 ¤   ¤   }
3e9371 ¤   }
e21cde ¤   return bContinue;
cfefe6 }
34af5a
3067c5 ¤
8e4265 //¤ ___________________________________________________
1b465d //
93c01b // ·Put up key properties dialog(s)
36af5a
387efe BOOL·
1946e9 KMKeyProperties (PKEYMAN pKM)·
73bb36 {
17cdd6 ¤   INT i;
f36a65 ¤   PROPSTRUCT ps;
82af5a
4eaac3 ¤   if (pKM->iNumberSheets == 0) {
8991ea ¤   ¤   for (i=0; i<MAXSHEETS; i++) {
7932de ¤   ¤   ¤   pKM->hWndTable[i] = NULL;
314b3f ¤   ¤   ¤   pKM->KeyTable[i] = NULL;
940fe4 ¤   ¤   }
819371 ¤   }
adaf5a
25e428 ¤   ps.pKM = pKM;
627a87 ¤   ps.lpfnCallback = sSingleKeyProperties;
e0af5a
779c86 ¤   TreeList_IterateSelected (pKM->hWndTree, &ps);
7faf5a
04c2e7 ¤   return TRUE;
64efe6 }
5caf5a
1aaf5a
064265 //¤ ___________________________________________________
bf465d //
6b28e3 // ·Update all existing propertysheets
22af5a
aea1ba VOID·
3a944d KMUpdateKeyProperties (PKEYMAN pKM)·
8fbb36 {
6bcdd6 ¤   INT i;
06af5a
4c2999 ¤   if (pKM->iNumberSheets > 0) {
2391ea ¤   ¤   for (i=0; i<MAXSHEETS; i++) {
02ef92 ¤   ¤   ¤   if (pKM->hWndTable[i] && pKM->KeyTable[i]) {
175e9e ¤   ¤   ¤   ¤   SendMessage (pKM->hWndTable[i], WM_APP, NOSERIALIZE, 0);
b2a3a6 ¤   ¤   ¤   }
--d7ea 00046d9252a401102b2 Page 42 of KMProps.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
6cefe6 }
99af5a
3caf5a
624265 //¤ ___________________________________________________
ea465d //
6a28e3 // ·Update all existing propertysheets
52af5a
54a1ba VOID·
00db6e KMUpdateKeyPropertiesThread (PKEYMAN pKM)·
80bb36 {
afcdd6 ¤   INT i;
b5af5a
c22999 ¤   if (pKM->iNumberSheets > 0) {
be91ea ¤   ¤   for (i=0; i<MAXSHEETS; i++) {
13ef92 ¤   ¤   ¤   if (pKM->hWndTable[i] && pKM->KeyTable[i]) {
877b4b ¤   ¤   ¤   ¤   PostMessage (pKM->hWndTable[i], WM_APP, SERIALIZE, 0);
11a3a6 ¤   ¤   ¤   }
a70fe4 ¤   ¤   }
be9371 ¤   }
17efe6 }
ecaf5a
b4af5a
ed4265 //¤ ___________________________________________________
2b465d //
f625a2 // ·Delete existing propertysheets
ecaf5a
55a1ba VOID·
60f598 KMDeletePropertiesKey (PKEYMAN pKM, PGPKeyRef key)·
77bb36 {
4bcdd6 ¤   INT i;
3baf5a
962999 ¤   if (pKM->iNumberSheets > 0) {
bc91ea ¤   ¤   for (i=0; i<MAXSHEETS; i++) {
6b9142 ¤   ¤   ¤   if (pKM->KeyTable[i] == key) {
06cbc1 ¤   ¤   ¤   ¤   SendMessage (pKM->hWndTable[i], WM_APP+1, 0, 0);
614ed2 ¤   ¤   ¤   ¤   pKM->KeyTable[i] = NULL;
e8a3a6 ¤   ¤   ¤   }
1f0fe4 ¤   ¤   }
c39371 ¤   }
deefe6 }
f0af5a
72af5a
4a4265 //¤ ___________________________________________________
8b465d //
6225a2 // ·Delete existing propertysheets
08af5a
e5a1ba VOID·
dce4eb KMDeleteAllKeyProperties (PKEYMAN pKM,·
9b1ddd ¤   ¤   ¤   ¤   ¤   ¤   ··BOOL bCloseWindows)·
92bb36 {
29cdd6 ¤   INT i;
fcaf5a
4e2999 ¤   if (pKM->iNumberSheets > 0) {
0091ea ¤   ¤   for (i=0; i<MAXSHEETS; i++) {
5019c4 ¤   ¤   ¤   if (pKM->hWndTable[i]) {
bb32f2 ¤   ¤   ¤   ¤   if (bCloseWindows) {
ac4276 ¤   ¤   ¤   ¤   ¤   PropSheet_PressButton (GetParent (pKM->hWndTable[i]),
9149bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···PSBTN_CANCEL);
132613 ¤   ¤   ¤   ¤   }
05fa07 ¤   ¤   ¤   ¤   else
a358d8 ¤   ¤   ¤   ¤   ¤   SendMessage (pKM->hWndTable[i], WM_APP+1, 0, 0);¤
aa4ed2 ¤   ¤   ¤   ¤   pKM->KeyTable[i] = NULL;
6ea3a6 ¤   ¤   ¤   }
a80fe4 ¤   ¤   }
989371 ¤   }
6eaf5a
e96412 ¤   Sleep (200);
4befe6 }
b0af5a
46af5a
--2d23 00123296652401102b2 Page 43 of KMProps.c
384265 //¤ ___________________________________________________
d3465d //
da5ddf // ·Enable/Disable existing propertysheets
89af5a
2bfe80 VOID
69bde2 KMEnableAllKeyProperties (PKEYMAN pKM,·
0b2e03 ¤   ¤   ¤   ¤   ¤   ¤   ··BOOL bEnable)·
8cbb36 {
885c93 ¤   INT¤¤   i;
a44880 ¤   HWND¤   hwndParent;
e8af5a
102999 ¤   if (pKM->iNumberSheets > 0) {
1291ea ¤   ¤   for (i=0; i<MAXSHEETS; i++) {
cc19c4 ¤   ¤   ¤   if (pKM->hWndTable[i]) {
d959a9 ¤   ¤   ¤   ¤   hwndParent = GetParent (pKM->hWndTable[i]);
4a3c78 ¤   ¤   ¤   ¤   EnableWindow (hwndParent, bEnable);
f3a3a6 ¤   ¤   ¤   }
3f0fe4 ¤   ¤   }
739371 ¤   }
a5efe6 }
0eaf5a
f0af5a
23af5a
--9339 000dfd3f6ac401102b3 Page 1 of KMRevoke.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
156f10 ¤   KMKeyOps.c - implements various operations performed on keys.·
2b67c5 ¤
d3af5a
c96944 ¤   $Id: KMRevoke.c,v 1.22 1998/08/12 18:31:23 pbj Exp $
f5f7f7 ____________________________________________________________________________*/
8fe610 #include "pgpPFLConfig.h"
56af5a
29c917 // project header files
58850a #include "pgpkmx.h"
f5af5a
a8ad8c // pgp header files
4f739b #include "pgpclientprefs.h"
57af5a
c15584 // constant definitions
5aabfd #define BITMAP_WIDTH¤   16
ad8af0 #define BITMAP_HEIGHT¤  16
c9af5a
e0d11d #define INITIAL_SIGN_COLUMNWIDTH¤   210
abaf5a
0fa05f #define SIG_NONEXPORTABLE¤  0
87fecc #define SIG_EXPORTABLE¤ ¤   1
55b65e #define SIG_TRUST¤  ¤   ¤   2
75fc02 #define SIG_META¤   ¤   ¤   3
7aaf5a
39578e // external globals ·
149cad extern HINSTANCE g_hInst;
a60afe extern CHAR g_szHelpFile[MAX_PATH];
c1af5a
835bee // typedefs
3ff0f7 typedef struct {
d97e47 ¤   PKEYMAN¤¤   ¤   pKM;
541502 ¤   PGPKeyRef¤  ¤   key;
dc565d ¤   PGPBoolean¤ ¤   bSyncWithServer;
098faa } REVOKECERTSTRUCT, *PREVOKECERTSTRUCT;
63af5a
88af5a
0c4265 //¤ ___________________________________________________
e7465d //
00ee4d // ·revoke split key and all subkeys
27af5a
3f69c9 static PGPError·
cda45a sRevokeKeySplit (
9de958 ¤   ¤   PGPContextRef¤  context,
9a8b6a ¤   ¤   PGPKeySetRef¤   keyset,
d6f9c6 ¤   ¤   PGPKeyRef¤  ¤   key,
6c80c6 ¤   ¤   PGPByte*¤   ¤   passkey,
3322ac ¤   ¤   PGPSize¤¤   ¤   sizePasskey)
ecbb36 {
446e76 ¤   UINT¤   ¤   ¤   u;
1bd125 ¤   PGPKeyListRef¤  keylist;
b4c323 ¤   PGPKeyIterRef¤  keyiter;
dd87ac ¤   PGPSubKeyRef¤   subkey;
87fb19 ¤   PGPError¤   ¤   err;
a8af5a
18e708 ¤   err = PGPRevokeKey (key,·
e41d50 ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, passkey, sizePasskey),
e26a09 ¤   ¤   ¤   ¤   PGPOLastOption (context));
098616 ¤   if (IsPGPError (err)) return err;
13af5a
c78b21 ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u);
6a86a2 ¤   switch (u) {
562692 ¤   case kPGPPublicKeyAlgorithm_RSA :
e42f68 ¤   ¤   break;
82af5a
287cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
03278b ¤   ¤   PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
17fa80 ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
dfae6d ¤   ¤   PGPKeyIterSeek (keyiter, key);
--ea85 00008d8b79e401102b3 Page 2 of KMRevoke.c
e49c21 ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
026680 ¤   ¤   while (subkey) {
977c92 ¤   ¤   ¤   err = PGPRevokeSubKey (subkey,·
370edc ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, passkey, sizePasskey),
05fb91 ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
9acf3a ¤   ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
950fe4 ¤   ¤   }
d6e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
d35a47 ¤   ¤   PGPFreeKeyList (keylist);
cf2f68 ¤   ¤   break;
aaaf5a
b8bfad ¤   default :
072f68 ¤   ¤   break;
9d9371 ¤   }
ceaf5a
785ea8 ¤   return err;
7befe6 }
bfaf5a
5e4265 //¤ ___________________________________________________
27465d //
9a5eed // ·revoke normal key and all subkeys
46af5a
b169c9 static PGPError·
83ac3f sRevokeKeyNormal (
90e958 ¤   ¤   PGPContextRef¤  context,
618b6a ¤   ¤   PGPKeySetRef¤   keyset,
30868f ¤   ¤   PGPKeyRef¤  ¤   key,·
5504d1 ¤   ¤   LPSTR¤  ¤   ¤   pszPhrase)
aabb36 {
a86e76 ¤   UINT¤   ¤   ¤   u;
f6d125 ¤   PGPKeyListRef¤  keylist;
7ec323 ¤   PGPKeyIterRef¤  keyiter;
ad87ac ¤   PGPSubKeyRef¤   subkey;
04fb19 ¤   PGPError¤   ¤   err;
62af5a
0fe708 ¤   err = PGPRevokeKey (key,·
c6a90a ¤   ¤   ¤   ¤   PGPOPassphrase (context, pszPhrase),
c36a09 ¤   ¤   ¤   ¤   PGPOLastOption (context));
2e8616 ¤   if (IsPGPError (err)) return err;
d8af5a
7d8b21 ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u);
a886a2 ¤   switch (u) {
e82692 ¤   case kPGPPublicKeyAlgorithm_RSA :
7b2f68 ¤   ¤   break;
b5af5a
357cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
4d278b ¤   ¤   PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
f3fa80 ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
19ae6d ¤   ¤   PGPKeyIterSeek (keyiter, key);
d39c21 ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
af6680 ¤   ¤   while (subkey) {
347c92 ¤   ¤   ¤   err = PGPRevokeSubKey (subkey,·
acc639 ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (context, pszPhrase),
6bfb91 ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
6bcf3a ¤   ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
220fe4 ¤   ¤   }
99e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
555a47 ¤   ¤   PGPFreeKeyList (keylist);
9a2f68 ¤   ¤   break;
e2af5a
cdbfad ¤   default :
8e2f68 ¤   ¤   break;
dc9371 ¤   }
59af5a
385ea8 ¤   return err;
1eefe6 }
4aaf5a
224265 //¤ ___________________________________________________
c4465d //
3280ce // ·Revoke selected key
b9af5a
087efe BOOL·
--0a53 00046192ba2401102b3 Page 3 of KMRevoke.c
87347d KMRevokeKey (PKEYMAN pKM)·
43bb36 {
f22be0 ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   ¤   = TRUE;
c07f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
bd1c01 ¤   LPSTR¤  ¤   ¤   pszPhrase¤  ¤   ¤   = NULL;
33730f ¤   PGPByte*¤   ¤   pPasskey¤   ¤   ¤   = NULL;
003746 ¤   PGPKeySetRef¤   keysetRevokers¤ ¤   = kInvalidPGPKeySetRef;
978999 ¤   PGPKeyRef¤  ¤   keyRevoker¤ ¤   ¤   = kInvalidPGPKeyRef;
dfaf5a
780000 ¤   PGPBoolean¤ ¤   bSecret;
0e0598 ¤   PGPBoolean¤ ¤   bSplit;
ba565d ¤   PGPBoolean¤ ¤   bSyncWithServer;
43b9e5 ¤   PGPSize¤¤   ¤   sizePasskey;
ff1502 ¤   PGPKeyRef¤  ¤   key;
bb9270 ¤   PGPKeyRef¤  ¤   keyToRevoke;
fa2447 ¤   PGPKeyRef¤  ¤   keyDef;
807d25 ¤   CHAR¤   ¤   ¤   sz128[128];
82ce0f ¤   PGPPrefRef¤ ¤   prefref;
6c989f ¤   PGPUInt32¤  ¤   u, uNumRevokers;
69af5a
150239 ¤   keyToRevoke = (PGPKeyRef) KMFocusedObject (pKM);
8572d2 ¤   PGPGetDefaultPrivateKey (pKM->KeySetMain, &keyDef);
4aaf5a
b2410a ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), &prefref);
85c213 ¤   PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnRevocation,·
1b0877 ¤   ¤   ¤   ¤   ¤   ¤   &bSyncWithServer);
63ab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
d2af5a
159763 ¤   if (keyToRevoke == keyDef) {
a6e4c1 ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_REVCONFDEFKEY,
8fd742 ¤   ¤   ¤   MB_YESNO|MB_TASKMODAL|MB_DEFBUTTON2|MB_ICONWARNING)==IDNO)·
125f1f ¤   ¤   ¤   return FALSE;
809371 ¤   }
3b665a ¤   else {
af2103 ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_REVOKECONFIRM,·
b1b0a6 ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO)·
745f1f ¤   ¤   ¤   return FALSE;
b09371 ¤   }
20af5a
10c80e ¤   err = PGPGetKeyBoolean (keyToRevoke,·
076ffb ¤   ¤   ¤   ¤   kPGPKeyPropIsSecret, &bSecret); CKERR;
97af5a
bd5bb0 ¤   if (bSecret) {
a73eb2 ¤   ¤   keyRevoker = keyToRevoke;
239371 ¤   }
a1665a ¤   else {
2a8af3 ¤   ¤   err = PGPCountRevocationKeys (keyToRevoke, &uNumRevokers); ·CKERR;
aa7310 ¤   ¤   for (u = 0; u < uNumRevokers; u++) {
fb3835 ¤   ¤   ¤   err = PGPGetIndexedRevocationKey (keyToRevoke, pKM->KeySetMain,
d291ad ¤   ¤   ¤   ¤   ¤   u, &key, NULL); CKERR;
f3ee01 ¤   ¤   ¤   if (PGPKeyRefIsValid (key)) {
3a6eb0 ¤   ¤   ¤   ¤   err = PGPGetKeyBoolean (key,·
276822 ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyPropIsSecret, &bSecret); CKERR;
9a6eb0 ¤   ¤   ¤   ¤   err = PGPGetKeyBoolean (key,·
9d9576 ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyPropIsSecretShared, &bSplit); CKERR;
0c9690 ¤   ¤   ¤   ¤   if (bSecret) {
6f508f ¤   ¤   ¤   ¤   ¤   keyRevoker = key;
058915 ¤   ¤   ¤   ¤   ¤   if (!bSplit)·
ae00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
ab2613 ¤   ¤   ¤   ¤   }
87a3a6 ¤   ¤   ¤   }
970fe4 ¤   ¤   }
f09371 ¤   }
dbaf5a
f6f4a9 ¤   if (!PGPKeyRefIsValid (keyRevoker))
7b262d ¤   ¤   goto done;
cfaf5a
21c80e ¤   err = PGPGetKeyBoolean (keyToRevoke,·
4e9576 ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyPropIsSecretShared, &bSplit); CKERR;
0aaf5a
c4d9de ¤   // get valid passphrase
46fb1d ¤   LoadString (g_hInst, IDS_SELKEYPASSPHRASE, sz128, 128);·
--59c4 000b35a135a401102b3 Page 4 of KMRevoke.c
87d200 ¤   err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
0b7691 ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sz128,
63cdca ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, keyRevoker,
f9895b ¤   ¤   ¤   ¤   ¤   ¤   &pszPhrase, &pPasskey, &sizePasskey);
2a18b2 ¤   PGPclErrorBox (NULL, err);
a2af5a
5f0b0a ¤   // now we have a valid passphrase, if required
bab23e ¤   if (IsntPGPError (err)) {
fcaf5a
f8ed82 ¤   ¤   // update from server
33671e ¤   ¤   if (bSyncWithServer) {
089ab7 ¤   ¤   ¤   if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
e56745 ¤   ¤   ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
f182c4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_QUERYCONTINUEREVOKINGKEY,·
99eba6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
5a145f ¤   ¤   ¤   ¤   ¤   bRetVal = FALSE;
c12613 ¤   ¤   ¤   ¤   }
72a3a6 ¤   ¤   ¤   }
610fe4 ¤   ¤   }
241b52 ¤   ¤
637931 ¤   ¤   if (bRetVal) {
3daf5a
7b620c ¤   ¤   ¤   // make sure we have enough entropy
0576ce ¤   ¤   ¤   PGPclRandom (pKM->Context, pKM->hWndParent, 0);
64af5a
941246 ¤   ¤   ¤   if (bSplit) {
092dd0 ¤   ¤   ¤   ¤   sRevokeKeySplit (pKM->Context, pKM->KeySetMain,
2322ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyToRevoke,·
7f18c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey);
f4a3a6 ¤   ¤   ¤   }
87e543 ¤   ¤   ¤   else {
08756e ¤   ¤   ¤   ¤   sRevokeKeyNormal (pKM->Context, pKM->KeySetMain,
8622ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyToRevoke,·
a77ac7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pszPhrase);
52a3a6 ¤   ¤   ¤   }
0994aa ¤   ¤   ¤   ¤   ¤   ¤
d8fe29 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
38e587 ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
d44567 ¤   ¤   ¤   ¤   KMUpdateKeyInTree (pKM, keyToRevoke, FALSE);
432c2f ¤   ¤   ¤   ¤   KMUpdateAllValidities (pKM);
4afae4 ¤   ¤   ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
9faf5a
6175f7 ¤   ¤   ¤   ¤   // send to server
f6aa92 ¤   ¤   ¤   ¤   if (bSyncWithServer) {
2f6cb4 ¤   ¤   ¤   ¤   ¤   KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
fa2613 ¤   ¤   ¤   ¤   }
e7a3a6 ¤   ¤   ¤   }
f936cc ¤   ¤   ¤   else bRetVal = FALSE;
120fe4 ¤   ¤   }
aa9371 ¤   }
3b8890 ¤   else bRetVal = FALSE;
ceaf5a
eea1c0 done :
79eab5 ¤   if (IsntNull (pszPhrase))
64c93b ¤   ¤   KMFreePhrase (pszPhrase);
2b4e8e ¤   if (IsntNull (pPasskey))·
2a0297 ¤   ¤   KMFreePasskey (pPasskey, sizePasskey);
2bf844 ¤   if (PGPKeySetRefIsValid (keysetRevokers))
0cdbd7 ¤   ¤   PGPFreeKeySet (keysetRevokers);
69af5a
5174c6 ¤   PGPclErrorBox (pKM->hWndParent, err);
8aaf5a
de1c35 ¤   return bRetVal;
41efe6 }
f0af5a
9daf5a
994265 //¤ ___________________________________________________
e3465d //
a6f7a0 //¤ Revoke signature dialog message procedure
61af5a
e53f64 static BOOL CALLBACK·
b36dba sRevokeCertDlgProc (HWND hDlg,·
--b199 0001e7af842401102b3 Page 5 of KMRevoke.c
41b8d3 ¤   ¤   ¤   ¤   ···UINT uMsg, ¤ ¤   ¤   ¤   ¤   ¤   ¤   ¤
d3285d ¤   ¤   ¤   ¤   ···WPARAM wParam,·
e62cd4 ¤   ¤   ¤   ¤   ···LPARAM lParam)·
b5bb36 {
b043cd ¤   PREVOKECERTSTRUCT prcs;
44af5a
6e347f ¤   switch (uMsg) {
6baf5a
f6ad3a ¤   case WM_INITDIALOG :
c15b34 ¤   ¤   {
f601e7 ¤   ¤   ¤   CHAR sz[kPGPMaxUserIDSize +1];
d320eb ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
b36ce7 ¤   ¤   ¤   prcs = (PREVOKECERTSTRUCT)lParam;
7eeb31 ¤   ¤   ¤   KMGetKeyIDFromKey (prcs->key, sz, sizeof (sz));
f2c389 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_KEYID, sz);
3eeaff ¤   ¤   ¤   KMGetKeyName (prcs->key, sz, sizeof (sz));
f5dd28 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_NAME, sz);
ad0fe4 ¤   ¤   }
c32f68 ¤   ¤   break;
1baf5a
ca3fcf ¤   case WM_COMMAND:
2baf5a
ab537d ¤   ¤   switch (LOWORD(wParam)) {
a971eb ¤   ¤   case IDCANCEL:
74f123 ¤   ¤   ¤   prcs = (PREVOKECERTSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
940cc6 ¤   ¤   ¤   prcs->bSyncWithServer = FALSE;
fff3d5 ¤   ¤   ¤   EndDialog (hDlg, 1);
42cdcb ¤   ¤   ¤   break;
78af5a
ad3860 ¤   ¤   case IDOK:
7ff123 ¤   ¤   ¤   prcs = (PREVOKECERTSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
e6ef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
04cdcb ¤   ¤   ¤   break;
54af5a
c843f5 ¤   ¤   case IDHELP :
edf123 ¤   ¤   ¤   prcs = (PREVOKECERTSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
c7e848 ¤   ¤   ¤   WinHelp (hDlg, prcs->pKM->szHelpFile, HELP_CONTEXT,·
5fb182 ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPKM_REVOKECERTDIALOG);·
79cdcb ¤   ¤   ¤   break;
f50fe4 ¤   ¤   }
4b836c ¤   ¤   return TRUE;
e19371 ¤   }
1ca230 ¤   return FALSE;
ddefe6 }
a7af5a
bbaf5a
2a4265 //¤ ___________________________________________________
e2465d //
f5e1ea // ·Revoke selected signature
e9af5a
5e7efe BOOL·
b165dc KMRevokeCert (PKEYMAN pKM)·
e5bb36 {
c457a3 ¤   BOOL¤   ¤   ¤   ¤   bRetVal¤¤   = TRUE;
a1ab93 ¤   PGPByte*¤   ¤   ¤   pPasskey¤   = NULL;
b4af5a
890de9 ¤   PGPSize¤¤   ¤   ¤   sizePasskey;
4c737f ¤   PGPSigRef¤  ¤   ¤   cert;
5d1f6d ¤   PGPKeyRef¤  ¤   ¤   keySigning, keyParent;
7a8f52 ¤   PGPError¤   ¤   ¤   err;
f98415 ¤   CHAR¤   ¤   ¤   ¤   sz128[128];
fc91e5 ¤   REVOKECERTSTRUCT¤   rcs;
ae697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
85af5a
787ba8 ¤   cert = (PGPSigRef) KMFocusedObject (pKM);
e8af5a
6a07d2 ¤   err = PGPGetSigCertifierKey (cert, pKM->KeySetMain, &keySigning);
a88369 ¤   if (err == kPGPError_ItemNotFound) {
499a65 ¤   ¤   keySigning = NULL;
4c70bb ¤   ¤   err = kPGPError_NoErr;
7b9371 ¤   }
1eaf5a
--b155 000eda36838401102b3 Page 6 of KMRevoke.c
bb24d2 ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
189640 ¤   ¤   if (!keySigning) {
7aa1dc ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_CERTKEYNOTONRING,·
9914e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
005f1f ¤   ¤   ¤   return FALSE;
d70fe4 ¤   ¤   }
61af5a
1409e5 ¤   ¤   rcs.pKM = pKM;
2c3816 ¤   ¤   rcs.key = KMGetKeyFromCert (pKM, cert);
eaaf5a
88581e ¤   ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context),·
dfcd80 ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
e68c64 ¤   ¤   PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnRevocation,·
c7af5e ¤   ¤   ¤   ¤   ¤   ¤   &(rcs.bSyncWithServer));
48b30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
4aaf5a
e5d5cd ¤   ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_REVOKECERT),·
333597 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sRevokeCertDlgProc,·
f6a3f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&rcs)) {
495f1f ¤   ¤   ¤   return FALSE;
680fe4 ¤   ¤   }
861b52 ¤   ¤
f77480 ¤   ¤   // get valid passphrase
28130e ¤   ¤   LoadString (g_hInst, IDS_SIGNKEYPASSPHRASE, sz128, 128);·
99f4b5 ¤   ¤   err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
ef7691 ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sz128,
f2ffd7 ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, keySigning,
d1f782 ¤   ¤   ¤   ¤   ¤   ¤   NULL, &pPasskey, &sizePasskey);
b594cd ¤   ¤   PGPclErrorBox (NULL, err);
28af5a
391a2d ¤   ¤   // now we have a valid passphrase, if required
558536 ¤   ¤   if (IsntPGPError (err)) {
9caf5a
6dda8a ¤   ¤   ¤   // update from server
fcb7be ¤   ¤   ¤   if (rcs.bSyncWithServer) {
3b4a1c ¤   ¤   ¤   ¤   if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
e3ed00 ¤   ¤   ¤   ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
c423a4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_QUERYCONTINUEREVOKINGCERT,·
38eba6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
a611b2 ¤   ¤   ¤   ¤   ¤   ¤   bRetVal = FALSE;
ae1c89 ¤   ¤   ¤   ¤   ¤   }
662613 ¤   ¤   ¤   ¤   }
0ba3a6 ¤   ¤   ¤   }
c71b52 ¤   ¤
859bd0 ¤   ¤   ¤   if (bRetVal) {
49af5a
23f44d ¤   ¤   ¤   ¤   // make sure we have enough entropy
60b2d2 ¤   ¤   ¤   ¤   PGPclRandom (pKM->Context, pKM->hWndParent, 0);
dcaf5a
6fc8bf ¤   ¤   ¤   ¤   err = PGPRevokeSig (
2efa9a ¤   ¤   ¤   ¤   ¤   ¤   (PGPSigRef) KMFocusedObject (pKM),·
103f4e ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain,
758791 ¤   ¤   ¤   ¤   ¤   ¤   pPasskey ?·
417745 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (pKM->Context,·
487678 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey) :
578e24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPONullOption (pKM->Context),
d5f17b ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context));
a894aa ¤   ¤   ¤   ¤   ¤   ¤
433a35 ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
feb7ec ¤   ¤   ¤   ¤   ¤   keyParent = KMGetKeyFromCert (pKM, cert);
698f07 ¤   ¤   ¤   ¤   ¤   KMUpdateKeyInTree (pKM, keyParent, FALSE);
70af5a
4faab9 ¤   ¤   ¤   ¤   ¤   KMCommitKeyRingChanges (pKM);
a57eb2 ¤   ¤   ¤   ¤   ¤   KMUpdateAllValidities (pKM);
ffaf5a
d89f0a ¤   ¤   ¤   ¤   ¤   // send key to server, if selected
9e286a ¤   ¤   ¤   ¤   ¤   if (rcs.bSyncWithServer) {
f2e148 ¤   ¤   ¤   ¤   ¤   ¤   KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
251c89 ¤   ¤   ¤   ¤   ¤   }
4e2613 ¤   ¤   ¤   ¤   }
dcd9bf ¤   ¤   ¤   ¤   else bRetVal = FALSE;
eda3a6 ¤   ¤   ¤   }
--52df 0003cd5788d401102b3 Page 7 of KMRevoke.c
b50fe4 ¤   ¤   }
2701c4 ¤   ¤   else bRetVal = FALSE;
169371 ¤   }
a78890 ¤   else bRetVal = FALSE;
52af5a
42320f ¤   if (pPasskey) {
990297 ¤   ¤   KMFreePasskey (pPasskey, sizePasskey);
e7997e ¤   ¤   pPasskey = NULL;
fd9371 ¤   }
46af5a
db1c35 ¤   return bRetVal;
2cefe6 }
bdaf5a
deaf5a
6b4265 //¤ ___________________________________________________
cd465d //
c2405a // ·Add designated revoker to key
a2af5a
6b7efe BOOL·
b99e8f KMAddRevoker (PKEYMAN pKM)·
64bb36 {
93db2b ¤   PGPKeySetRef¤   keysetToChoose¤ ¤   = kInvalidPGPKeySetRef;
64b26a ¤   PGPKeySetRef¤   keysetToRemove¤ ¤   = kInvalidPGPKeySetRef;
e26dcc ¤   PGPKeySetRef¤   keysetThisKey¤  ¤   = kInvalidPGPKeySetRef;
84e25b ¤   PGPKeySetRef¤   keysetSelected¤ ¤   = kInvalidPGPKeySetRef;
f15187 ¤   PGPFilterRef¤   filterRSA¤  ¤   ¤   = kInvalidPGPFilterRef;
6b7f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
904461 ¤   PGPByte*¤   ¤   pbyte¤  ¤   ¤   ¤   = NULL;
9989b8 ¤   BOOL¤   ¤   ¤   bRet¤   ¤   ¤   ¤   = FALSE;
5e9d99 ¤   PGPUInt32¤  ¤   uCount¤ ¤   ¤   ¤   = 0;
d1c64a ¤   PGPBoolean¤ ¤   bSyncWithServer¤¤   = FALSE;
beaf5a
35ce0f ¤   PGPPrefRef¤ ¤   prefref;
442f6a ¤   PGPSize¤¤   ¤   size;
8e1502 ¤   PGPKeyRef¤  ¤   key;
232a2a ¤   CHAR¤   ¤   ¤   szPrompt[256];
84af5a
a5af5a
d30a36 ¤   key = (PGPKeyRef)KMFocusedObject (pKM);
fdaf5a
b8410a ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), &prefref);
be59c0 ¤   PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnAdd,·
170877 ¤   ¤   ¤   ¤   ¤   ¤   &bSyncWithServer);
33ab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
8eaf5a
1a3259 ¤   err = PGPNewKeySet (pKM->Context, &keysetToChoose); CKERR;
8fbc1f ¤   err = PGPAddKeys (pKM->KeySetMain, keysetToChoose); CKERR;
b912af ¤   err = PGPCommitKeyRingChanges (keysetToChoose); CKERR;
89af5a
c9a0e7 ¤   err = PGPNewKeyEncryptAlgorithmFilter (pKM->Context,·
dae139 ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA, &filterRSA); CKERR;
302a5d ¤   err = PGPFilterKeySet (pKM->KeySetMain,·
83d186 ¤   ¤   ¤   ¤   ¤   ¤   filterRSA, &keysetToRemove); CKERR;
3caf5a
da7121 ¤   err = PGPCommitKeyRingChanges (keysetToRemove); CKERR;
c2a771 ¤   err = PGPRemoveKeys (keysetToRemove, keysetToChoose); CKERR;
1e12af ¤   err = PGPCommitKeyRingChanges (keysetToChoose); CKERR;
f0af5a
d9ad93 ¤   err = PGPCountKeys (keysetToChoose, &uCount); CKERR;
3e570c ¤   if (uCount <= 1) {
4e41ed ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_NOTENOUGHKEYSTOADDREVOKER,
5c8680 ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
c1262d ¤   ¤   goto done;
0e9371 ¤   }
1eaf5a
d15b87 ¤   err = PGPFreeKeySet (keysetToRemove); CKERR;
3b9dc2 ¤   err = PGPNewSingletonKeySet (key, &keysetToRemove); CKERR;
5ba771 ¤   err = PGPRemoveKeys (keysetToRemove, keysetToChoose); CKERR;
3caf5a
ec12af ¤   err = PGPCommitKeyRingChanges (keysetToChoose); CKERR;
92af5a
3c8b32 ¤   LoadString (g_hInst, IDS_ADDREVOKERPROMPT, szPrompt, sizeof(szPrompt));
--e7d9 0005dfc12b5401102b3 Page 8 of KMRevoke.c
2d9674 ¤   err = PGPclSelectKeys (pKM->Context, pKM->tlsContext,·
aaecf6 ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, szPrompt,
95361a ¤   ¤   ¤   ¤   ¤   keysetToChoose, pKM->KeySetMain, &keysetSelected);
cbaf5a
c7ad0d ¤   if (IsntPGPError (err) && PGPKeySetRefIsValid (keysetSelected))
5dc7a1 ¤   {
1c9bd9 ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
109382 ¤   ¤   ¤   ¤   IDS_ADDREVOKERCONFIRM, MB_YESNO|MB_ICONEXCLAMATION) == IDYES)·
705b34 ¤   ¤   {
632e9c ¤   ¤   ¤   err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
9cfc46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, NULL,·
2531d5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, key,·
04f651 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, &pbyte, &size); CKERR;
8daf5a
f0da8a ¤   ¤   ¤   // update from server
8c3ea9 ¤   ¤   ¤   if (IsntPGPError (err) && bSyncWithServer) {
a14a1c ¤   ¤   ¤   ¤   if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
0ded00 ¤   ¤   ¤   ¤   ¤   if (KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
32ab2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_QUERYCONTINUEADDING, ¤
ee2ed6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO)·
494859 ¤   ¤   ¤   ¤   ¤   {
66094d ¤   ¤   ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
ec1c89 ¤   ¤   ¤   ¤   ¤   }
1d2613 ¤   ¤   ¤   ¤   }
8fa3a6 ¤   ¤   ¤   }
331b52 ¤   ¤
f86a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
52b72b ¤   ¤   ¤   ¤   err = PGPAddKeyOptions (key,·
e82151 ¤   ¤   ¤   ¤   ¤   PGPORevocationKeySet (pKM->Context, keysetSelected),
83953c ¤   ¤   ¤   ¤   ¤   pbyte ?
aeabb2 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (pKM->Context, pbyte, size) :
8c891f ¤   ¤   ¤   ¤   ¤   ¤   PGPONullOption (pKM->Context),
e2b306 ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pKM->Context)); CKERR;
a8a3a6 ¤   ¤   ¤   }
960fe4 ¤   ¤   }
a10e1d ¤   ¤   else
104e2b ¤   ¤   ¤   err = kPGPError_UserAbort;
c29371 ¤   }
39af5a
280c1e ¤   // send to server
150281 ¤   if (IsntPGPError (err) && bSyncWithServer) {
297a4a ¤   ¤   KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
9b9371 ¤   }
a7af5a
e0b23e ¤   if (IsntPGPError (err)) {
2de0ac ¤   ¤   KMCommitKeyRingChanges (pKM);
995beb ¤   ¤   bRet = TRUE;
a1af5a
64671e ¤   ¤   if (bSyncWithServer) {
ec094b ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_ADDEDSENTREVOKERS,
a78680 ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
040fe4 ¤   ¤   }
c907e0 ¤   ¤   else {
2e74e1 ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_ADDEDREVOKERS,
3c8680 ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
310fe4 ¤   ¤   }
859371 ¤   }
9baf5a
efa1c0 done :
d05aea ¤   if (IsntNull (pbyte))
edc660 ¤   ¤   KMFreePasskey (pbyte, size);
ae1fe8 ¤   if (PGPKeySetRefIsValid (keysetToChoose))
7f3c7b ¤   ¤   PGPFreeKeySet (keysetToChoose);
1b06b3 ¤   if (PGPKeySetRefIsValid (keysetToRemove))
622520 ¤   ¤   PGPFreeKeySet (keysetToRemove);
541ee9 ¤   if (PGPKeySetRefIsValid (keysetThisKey))
9b0a59 ¤   ¤   PGPFreeKeySet (keysetThisKey);
2a18c9 ¤   if (PGPKeySetRefIsValid (keysetSelected))
ed3b5a ¤   ¤   PGPFreeKeySet (keysetSelected);
5afee2 ¤   if (PGPFilterRefIsValid (filterRSA))
94fdb9 ¤   ¤   PGPFreeFilter (filterRSA);
5daf5a
--5851 0017d13fedd401102b3 Page 9 of KMRevoke.c
8574c6 ¤   PGPclErrorBox (pKM->hWndParent, err);
a3af5a
5b8d4d ¤   return bRet;
7dbe43 }¶
--e912 000ad7278ab401102b4 Page 1 of KMShare.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
a95dd2 ¤   KMShare.c - code for splitting secret keys.·
0a67c5 ¤
65af5a
3c65cf ¤   $Id: KMShare.c,v 1.47.2.1 1998/10/21 20:48:41 pbj Exp $
c1f7f7 ____________________________________________________________________________*/
93e610 #include "pgpPFLConfig.h"
e2af5a
38c917 // project header files
8c850a #include "pgpkmx.h"
07af5a
6afc2c // system header files
4cf766 #include "shlobj.h"
a7af5a
b7ad8c // pgp header files
b73427 #include "pgpFileUtilities.h"
04add5 #include "pgpShareFile.h"
4faf5a
305584 // constant definitions
176b7d #define INITIAL_SHAREKEY_COLUMNWIDTH¤   250
d7e444 #define MAX_TOTAL_SHARES¤   ¤   ¤   ¤   255
93d720 #define MAX_SHARES¤ ¤   ¤   ¤   ¤   ¤   99
331349 #define MAX_SHARES_LEN¤ ¤   ¤   ¤   ¤   2
87af5a
ab5bee // typedefs
bff0f7 typedef struct {
a93b40 ¤   INT¤¤   iNumSteps;
4b6c6a } SPLITKEYPROGRESSSTRUCT;
99af5a
c8578e // external globals ·
ae9cad extern HINSTANCE g_hInst;
1d0afe extern CHAR g_szHelpFile[MAX_PATH];
2faf5a
e89cb7 // local global
640d8f static PSPLITKEYSTRUCT psksList = NULL;
5daf5a
f45b92 static DWORD aSplitIds[] = {¤   ¤   ¤   // Help IDs
b556b0 ¤   IDC_KEYTOSPLIT,¤¤   ¤   IDH_PGPCLSPLIT_KEYTOSPLIT,·
3093bf ¤   IDC_SHAREHOLDERS,¤  ¤   IDH_PGPCLSPLIT_SHAREHOLDERS,·
43d5fd ¤   IDC_CURRENTSHAREHOLDER,¤IDH_PGPCLSPLIT_SELECTEDSHAREHOLDER,·
76880e ¤   IDC_SHARES,¤¤   ¤   ¤   IDH_PGPCLSPLIT_SELECTEDSHARES,·
5b99ee ¤   IDC_REMOVESHAREHOLDER,¤ IDH_PGPCLSPLIT_REMOVESHARES,·
cb6ef9 ¤   IDC_ADDSHAREHOLDER,¤¤   IDH_PGPCLSPLIT_ADDSHARES,·
93788e ¤   IDC_TOTALSHARES,¤   ¤   IDH_PGPCLSPLIT_TOTALSHARES,·
733a44 ¤   IDC_THRESHOLD,¤ ¤   ¤   IDH_PGPCLSPLIT_THRESHOLD,·
2fb592 ¤   IDOK,¤  ¤   ¤   ¤   ¤   IDH_PGPCLSPLIT_SPLIT,·
cb4434 ····0,0·
79a6fe };·
d2af5a
30b945 static DWORD aNewShareIds[] = {¤¤   ¤   // Help IDs
223e2b ····IDC_NEWSHAREHOLDER,¤IDH_PGPCLSPLIT_NEWSHAREHOLDER,·
574434 ····0,0·
18a6fe };·
28af5a
739268 //¤ _______________________________________________
58465d //
e05df7 // ·add shareholder to listview control
adaf5a
3e6c77 static BOOL·
9cb4d6 sAddShareHolder (
c6a9be ¤   ¤   PSPLITKEYSTRUCT¤¤   psks,
f5036b ¤   ¤   PSHAREHOLDERSTRUCT¤ pshs,·
79d127 ¤   ¤   INT¤¤   ¤   ¤   ¤   iImage,·
f9f136 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndList)
c4bb36 {
992329 ¤   LV_ITEM¤¤   lvI;
a5b3a6 ¤   INT¤¤   ¤   iItem;¤
15eb14 ¤   CHAR¤   ¤   sz[16];
adaf5a
--ce80 000a532a298401102b4 Page 2 of KMShare.c
df61c2 ¤   // see if we're over the limit
6c379b ¤   if ((psks->uTotalShares + pshs->uShares) > MAX_TOTAL_SHARES) {
49a463 ¤   ¤   MessageBeep (MB_ICONASTERISK);
f298aa ¤   ¤   return FALSE;
379371 ¤   }
0aaf5a
d35161 ¤   // figure item index to use
4f6280 ¤   iItem = ListView_GetItemCount (hwndList);
78af5a
29ba62 ¤   // insert listview item
420bdd ¤   lvI.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE|LVIF_PARAM;
047fa6 ¤   lvI.state = 0; ·····
e69ef0 ¤   lvI.stateMask = 0;
39b4ac ¤   lvI.iImage = iImage;
7caf5a
656d1a ¤   lvI.iItem = iItem;
99505a ¤   lvI.iSubItem = 0;
e16ae0 ¤   lvI.pszText¤= pshs->szUserID;·
0cfa85 ¤   lvI.cchTextMax = 0;
9c4b50 ¤   lvI.lParam = (LPARAM)pshs;
c3af5a
eb0ad0 ¤   iItem = ListView_InsertItem (hwndList, &lvI);
afe2a5 ¤   if (iItem == -1) {
1698aa ¤   ¤   return FALSE;
b89371 ¤   }
8f665a ¤   else {
742c02 ¤   ¤   // add strings for Shares column
079681 ¤   ¤   wsprintf (sz, "%i", pshs->uShares);
e1a3c3 ¤   ¤   ListView_SetItemText (hwndList, iItem, 1, sz);
24836c ¤   ¤   return TRUE;
cf9371 ¤   }
a3efe6 }
46af5a
86af5a
ab9268 //¤ _______________________________________________
35465d //
3fcb3e // ·destroy shareholder data structures from listview control
3aaf5a
846c77 static BOOL·
178d1a sIsKeyIDAlreadyInList (
13dc2e ¤   ¤   PGPKeyID*¤  ¤   ¤   ¤   pkeyid,·
e9b2fc ¤   ¤   PGPPublicKeyAlgorithm¤  keyalg,
c642a6 ¤   ¤   PSPLITKEYSTRUCT¤¤   ¤   psks)
dabb36 {
4a613a ¤   INT¤¤   ¤   ¤   ¤   iNumItems;
ecc613 ¤   INT¤¤   ¤   ¤   ¤   iIndex;
0f0d1a ¤   LV_ITEM¤¤   ¤   ¤   lvI;
e1f2c6 ¤   PSHAREHOLDERSTRUCT¤ pshs;
80af5a
653189 ¤   iNumItems = ListView_GetItemCount (psks->hwndList);
250560 ¤   for (iIndex=0; iIndex<iNumItems; iIndex++) {
1a4124 ¤   ¤   lvI.mask = LVIF_PARAM;
5b25c3 ¤   ¤   lvI.iItem = iIndex;
3a97ef ¤   ¤   lvI.iSubItem = 0;
677d9a ¤   ¤   ListView_GetItem (psks->hwndList, &lvI);
9baf5a
972abf ¤   ¤   pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
11d22e ¤   ¤   if (pshs->keyalg == keyalg) {
dd7db0 ¤   ¤   ¤   if (PGPCompareKeyIDs (&pshs->keyid, pkeyid) == 0) {
2906e0 ¤   ¤   ¤   ¤   return TRUE;
3ca3a6 ¤   ¤   ¤   }
9e0fe4 ¤   ¤   }
e99371 ¤   }
a7af5a
72a230 ¤   return FALSE;
14efe6 }
07af5a
cfaf5a
f39268 //¤ _______________________________________________
da465d //
384964 // ·Drop text key(s)
a5af5a
--4c0a 000e2130a63401102b4 Page 3 of KMShare.c
697efe BOOL·
1ecd65 KMSplitDropKeys (
cbb4db ¤   ¤   PSPLITKEYSTRUCT psks,·
2be8fd ¤   ¤   HANDLE¤ hMem)·
e5bb36 {
276c3f ¤   PGPKeySetRef¤   ¤   ¤   keyset¤ ¤   = NULL;
c5c8cd ¤   PGPKeyListRef¤  ¤   ¤   keylist¤¤   = NULL;
b9c5d4 ¤   PGPKeyIterRef¤  ¤   ¤   keyiter¤¤   = NULL;
c9695d ¤   LPSTR¤  ¤   ¤   ¤   ¤   pMem¤   ¤   = NULL;
33af5a
cbba49 ¤   PGPError¤   ¤   ¤   ¤   err;
a0dba5 ¤   PGPKeyRef¤  ¤   ¤   ¤   key;
79b373 ¤   PGPKeyID¤   ¤   ¤   ¤   keyid;
a20fea ¤   BOOL¤   ¤   ¤   ¤   ¤   bKeys;
5f0168 ¤   PGPBoolean¤ ¤   ¤   ¤   bKeyIsUsable;
9946b5 ¤   size_t¤ ¤   ¤   ¤   ¤   sLen;
580023 ¤   PSHAREHOLDERSTRUCT¤ ¤   pshs;
12ae19 ¤   PGPPublicKeyAlgorithm¤  alg;
79af5a
8f0ad7 ¤   bKeys = FALSE;
50af5a
03805f ¤   if (hMem) {
adad19 ¤   ¤   pMem = GlobalLock (hMem);
2a61e8 ¤   ¤   if (pMem) {
75af5a
2823c0 ¤   ¤   ¤   sLen = lstrlen (pMem);
88c154 ¤   ¤   ¤   err = PGPImportKeySet (psks->pKM->Context, &keyset,·
b1a37a ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputBuffer (psks->pKM->Context, pMem, sLen),
32c614 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (psks->pKM->Context));
f89cbe ¤   ¤   ¤   if (IsPGPError (err)) goto SplitDropCleanup;
b1af5a
4df75c ¤   ¤   ¤   err = PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
1c9cbe ¤   ¤   ¤   if (IsPGPError (err)) goto SplitDropCleanup;
7baf5a
1a67c8 ¤   ¤   ¤   err = PGPNewKeyIter (keylist, &keyiter);
e29cbe ¤   ¤   ¤   if (IsPGPError (err)) goto SplitDropCleanup;
48af5a
18b6f8 ¤   ¤   ¤   PGPKeyIterNext (keyiter, &key);
36af5a
773b01 ¤   ¤   ¤   while (key) {
46422d ¤   ¤   ¤   ¤   bKeyIsUsable = FALSE;
5ff089 ¤   ¤   ¤   ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &alg);
0d1685 ¤   ¤   ¤   ¤   PGPGetKeyIDFromKey (key, &keyid);
8d2b85 ¤   ¤   ¤   ¤
dd7694 ¤   ¤   ¤   ¤   // key must either not be RSA or RSA ops must be enabled
9c4117 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropCanEncrypt, &bKeyIsUsable);
0caf5a
6f11dc ¤   ¤   ¤   ¤   // key must not be the same one that is being split
45e0fe ¤   ¤   ¤   ¤   if (alg == psks->keyalgToSplit) {
c0bade ¤   ¤   ¤   ¤   ¤   if (PGPCompareKeyIDs (&keyid, &(psks->keyidToSplit))==0)
654706 ¤   ¤   ¤   ¤   ¤   ¤   bKeyIsUsable = FALSE;
2f2613 ¤   ¤   ¤   ¤   }
44af5a
a4a801 ¤   ¤   ¤   ¤   // key must not already be in list
f9b1ee ¤   ¤   ¤   ¤   if (sIsKeyIDAlreadyInList (&keyid, alg, psks))
d67ec3 ¤   ¤   ¤   ¤   ¤   bKeyIsUsable = FALSE;
cfaf5a
259816 ¤   ¤   ¤   ¤   if (bKeyIsUsable) {
feaf5a
2c04e9 ¤   ¤   ¤   ¤   ¤   bKeys = TRUE;
cdda8b ¤   ¤   ¤   ¤   ¤   pshs = KMAlloc (sizeof(SHAREHOLDERSTRUCT));
b3f06b ¤   ¤   ¤   ¤   ¤   if (pshs) {
fbcc6d ¤   ¤   ¤   ¤   ¤   ¤   PGPSize¤¤   size;
07af5a
dc84bb ¤   ¤   ¤   ¤   ¤   ¤   pshs->bPublicKey = TRUE;
53ca4f ¤   ¤   ¤   ¤   ¤   ¤   pshs->pszPassphrase = NULL;
280bd3 ¤   ¤   ¤   ¤   ¤   ¤   pshs->uShares = 1;
f8af5a
eca0f0 ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (key,·
d2b070 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(pshs->szUserID), pshs->szUserID, &size);
da11e8 ¤   ¤   ¤   ¤   ¤   ¤   PGPGetKeyIDFromKey (key, &(pshs->keyid));
e22d1e ¤   ¤   ¤   ¤   ¤   ¤   PGPGetKeyNumber (key,·
--6e48 00010b34127401102b4 Page 4 of KMShare.c
05be4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyPropAlgID, &(pshs->keyalg));
15af5a
0921c1 ¤   ¤   ¤   ¤   ¤   ¤   if (sAddShareHolder (psks, pshs,·
eada55 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMDetermineUserIDIcon (key, NULL, NULL),·
9f1088 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->hwndList)) {
e11736 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uTotalShares += pshs->uShares;
244f79 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetDlgItemInt (psks->hwndDlg, IDC_TOTALSHARES,·
e16e85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uTotalShares, FALSE);
2af671 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage (psks->hwndDlg, WM_COMMAND,·
41a38d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM(IDC_THRESHOLD, EN_CHANGE), 0);
c3db3c ¤   ¤   ¤   ¤   ¤   ¤   }
a62863 ¤   ¤   ¤   ¤   ¤   ¤   else {
d5ddbb ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMFree (pshs);
b9db3c ¤   ¤   ¤   ¤   ¤   ¤   }
101c89 ¤   ¤   ¤   ¤   ¤   }
fa2613 ¤   ¤   ¤   ¤   }
c0af5a
e6aea8 ¤   ¤   ¤   ¤   PGPKeyIterNext (keyiter, &key);
eea3a6 ¤   ¤   ¤   }
2daf5a
39e34c SplitDropCleanup :
b348f5 ¤   ¤   ¤   if (keyiter)
1f3a77 ¤   ¤   ¤   ¤   PGPFreeKeyIter (keyiter);
c5af5a
69caa4 ¤   ¤   ¤   if (keylist)
be89da ¤   ¤   ¤   ¤   PGPFreeKeyList (keylist);
82af5a
d47d9d ¤   ¤   ¤   if (keyset)
11cdef ¤   ¤   ¤   ¤   PGPFreeKeySet (keyset);
07af5a
3f3bd0 ¤   ¤   ¤   if (pMem)
496d74 ¤   ¤   ¤   ¤   GlobalUnlock (hMem);
ee0fe4 ¤   ¤   }
d49371 ¤   }
3067c5 ¤
1ab5b4 ¤   return bKeys;
e2efe6 }
5daf5a
61af5a
7d9268 //¤ _______________________________________________
4a465d //
eef6d2 // ·Initialize ListView
71af5a
46b333 static VOID·
fd6409 sInitKeyList (PSPLITKEYSTRUCT psks)·
70bb36 {
bdaf5a
d1c89d ¤   LV_COLUMN¤  lvC;·
cdcdba ¤   CHAR¤   ¤   sz[256];
fef493 ¤   HBITMAP¤¤   hBmp;
ca18a8 ¤   HDC¤¤   ¤   hDC;
380863 ¤   INT¤¤   ¤   iNumBits;
18af5a
d24f7a ¤   // create image list
ed7f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
d189fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
92e693 ¤   ReleaseDC (NULL, hDC);
c1af5a
3f2be4 ¤   if (iNumBits <= 8) {
6cff94 ¤   ¤   psks->hIml = ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
206d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
3f9694 ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
06783f ¤   ¤   ImageList_AddMasked (psks->hIml, hBmp, RGB(255, 0, 255));
4d5c8d ¤   ¤   DeleteObject (hBmp);
249371 ¤   }
a8665a ¤   else {
1ad627 ¤   ¤   psks->hIml = ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
306d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
4fbb8b ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
16783f ¤   ¤   ImageList_AddMasked (psks->hIml, hBmp, RGB(255, 0, 255));
b35c8d ¤   ¤   DeleteObject (hBmp);
109371 ¤   }
--afbd 0006882f37f401102b4 Page 5 of KMShare.c
e0af5a
fb6a95 ¤   ListView_SetImageList (psks->hwndList, psks->hIml, LVSIL_SMALL);
feaf5a
4d3e53 ¤   lvC.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
1d4e45 ¤   lvC.fmt = LVCFMT_LEFT;·
da34b0 ¤   lvC.pszText = sz;
33af5a
665e6b ¤   LoadString (g_hInst, IDS_USERID, sz, sizeof(sz));
4adae1 ¤   lvC.cx = INITIAL_SHAREKEY_COLUMNWIDTH; ··
b014af ¤   lvC.iSubItem = 0;
9e5b27 ¤   if (ListView_InsertColumn (psks->hwndList, 0, &lvC) == -1) return;
02af5a
143450 ¤   LoadString (g_hInst, IDS_SHARES, sz, sizeof(sz));
539e8b ¤   lvC.cx = 50; ··
1e4e73 ¤   lvC.iSubItem = 1;
5c0063 ¤   if (ListView_InsertColumn (psks->hwndList, 1, &lvC) == -1) return;
b4efe6 }
e6af5a
6c9268 //¤ _______________________________________________
b3465d //
501bd8 // ·remove shareholder from listview control
bcaf5a
d2b333 static VOID·
a2ad73 sRemoveShareHolderFromList (HWND hDlg, PSPLITKEYSTRUCT psks)
16bb36 {
03c613 ¤   INT¤¤   ¤   ¤   ¤   iIndex;
4d0d1a ¤   LV_ITEM¤¤   ¤   ¤   lvI;
e0f2c6 ¤   PSHAREHOLDERSTRUCT¤ pshs;
a4af5a
c274a5 ¤   iIndex = ListView_GetNextItem (psks->hwndList, -1, LVNI_SELECTED);
55af5a
fa352e ¤   if (iIndex > -1) {
2d4124 ¤   ¤   lvI.mask = LVIF_PARAM;
a425c3 ¤   ¤   lvI.iItem = iIndex;
e797ef ¤   ¤   lvI.iSubItem = 0;
8b7d9a ¤   ¤   ListView_GetItem (psks->hwndList, &lvI);
0faf5a
b18626 ¤   ¤   // update total shares
152abf ¤   ¤   pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
f1876f ¤   ¤   psks->uTotalShares -= pshs->uShares;
717989 ¤   ¤   SetDlgItemInt (hDlg, IDC_TOTALSHARES, psks->uTotalShares, FALSE);
030181 ¤   ¤   SendMessage (hDlg, WM_COMMAND,·
9feb0e ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (IDC_THRESHOLD, EN_CHANGE), 0);
12af5a
497338 ¤   ¤   KMFreePhrase (pshs->pszPassphrase);
2ee8b2 ¤   ¤   KMFree (pshs);
6eaf5a
0c1573 ¤   ¤   ListView_DeleteItem (psks->hwndList, iIndex);
a99371 ¤   }
a2efe6 }
30af5a
2faf5a
a99268 //¤ _______________________________________________
ea465d //
7ec5b5 // add share holder dialog message procedure
a8af5a
ac3f64 static BOOL CALLBACK·
85b24f sAddShareHolderDlgProc (HWND hDlg,·
e6ffab ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
2e69ae ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
6b6d27 ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)·
fabb36 {
00462f ¤   PSPLITKEYSTRUCT¤¤   psks;
32f2c6 ¤   PSHAREHOLDERSTRUCT¤ pshs;
e1af5a
fa347f ¤   switch (uMsg) {
0baf5a
84ad3a ¤   case WM_INITDIALOG :
0ee3ba ¤   ¤   // save address of struct
577547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
5f836c ¤   ¤   return TRUE;
68af5a
--8120 000942ac6a4401102b4 Page 6 of KMShare.c
a68a25 ¤   case WM_HELP:·
9cfb42 ¤   ····WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
286f54 ¤   ········HELP_WM_HELP, (DWORD) (LPSTR) aNewShareIds);·
527d53 ¤   ····break;·
d8af5a
99af40 ¤   case WM_CONTEXTMENU:·
bd082b ¤   ¤   WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
61bb44 ¤   ¤   ····(DWORD) (LPVOID) aNewShareIds);·
43ca2d ¤   ¤   break;·
b0af5a
8dd1d3 ¤   case WM_COMMAND :
1a537d ¤   ¤   switch (LOWORD(wParam)) {
56b6bb ¤   ¤   case IDCANCEL :
e9ef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
8bcdcb ¤   ¤   ¤   break;
6eaf5a
398c29 ¤   ¤   case IDOK :
521be1 ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
9c91c0 ¤   ¤   ¤   pshs = KMAlloc (sizeof(SHAREHOLDERSTRUCT));
1bab50 ¤   ¤   ¤   if (pshs) {
b7c292 ¤   ¤   ¤   ¤   CHAR¤   ¤   szPrompt[64];
675f3a ¤   ¤   ¤   ¤   PGPError¤   err;
d6af5a
f14c64 ¤   ¤   ¤   ¤   pshs->bPublicKey = FALSE;
2f103f ¤   ¤   ¤   ¤   pshs->keyalg = 0;
cb445e ¤   ¤   ¤   ¤   pshs->pszPassphrase = NULL;
ef446c ¤   ¤   ¤   ¤   pshs->uShares = 1;
1caf99 ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_NEWSHAREHOLDER,·
90067c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pshs->szUserID, sizeof(pshs->szUserID));
23af5a
63af71 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_SHAREPHRASEPROMPT,·
178253 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szPrompt, sizeof (szPrompt));
30549b ¤   ¤   ¤   ¤   err = KMGetConfirmationPhrase (psks->pKM->Context, hDlg,·
da1341 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szPrompt, psks->pKM->KeySetMain,
1d5f90 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   1, 0, &(pshs->pszPassphrase));
32c72f ¤   ¤   ¤   ¤   // wjb changed min length to 1 for passphrase
c0af5a
7956ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
78f65a ¤   ¤   ¤   ¤   ¤   if (sAddShareHolder (
769b46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks, pshs, IDX_HEAD, psks->hwndList)) {
12cd1f ¤   ¤   ¤   ¤   ¤   ¤   psks->uTotalShares += pshs->uShares;
becde8 ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, 1);
b71c89 ¤   ¤   ¤   ¤   ¤   }
fe3c4b ¤   ¤   ¤   ¤   ¤   else {
d227d2 ¤   ¤   ¤   ¤   ¤   ¤   KMFreePhrase (pshs->pszPassphrase);
bfd3f7 ¤   ¤   ¤   ¤   ¤   ¤   KMFree (pshs);
1cd153 ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, 0);
e01c89 ¤   ¤   ¤   ¤   ¤   }
6e2613 ¤   ¤   ¤   ¤   }
b5a3a6 ¤   ¤   ¤   }
656b93 ¤   ¤   ¤   else·
76d206 ¤   ¤   ¤   ¤   EndDialog (hDlg, 0);
94cdcb ¤   ¤   ¤   break;
bf0fe4 ¤   ¤   }
cb836c ¤   ¤   return TRUE;
dd9371 ¤   }
0ea230 ¤   return FALSE;
daefe6 }
37af5a
5daf5a
8f9268 //¤ _______________________________________________
92465d //
ab7cd4 // ·pop dialog for adding conventional encryption shareholder
8caf5a
48b333 static VOID·
af5149 sAddShareHolderToList (HWND hDlg, PSPLITKEYSTRUCT psks)
5abb36 {
6bd6f9 ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_ADDSHAREHOLDER),·
fb1462 ¤   ¤   hDlg, sAddShareHolderDlgProc, (LPARAM)psks)) {
23af5a
f17989 ¤   ¤   SetDlgItemInt (hDlg, IDC_TOTALSHARES, psks->uTotalShares, FALSE);
940181 ¤   ¤   SendMessage (hDlg, WM_COMMAND,·
--b8e9 000847e8936401102b4 Page 7 of KMShare.c
51eb0e ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (IDC_THRESHOLD, EN_CHANGE), 0);
dc9371 ¤   }
52efe6 }
a2af5a
5aaf5a
af9268 //¤ _______________________________________________
11465d //
dacb3e // ·destroy shareholder data structures from listview control
e8af5a
cdb333 static VOID·
ed82fa sDestroyShareHolders (PSPLITKEYSTRUCT psks)
d3bb36 {
3c613a ¤   INT¤¤   ¤   ¤   ¤   iNumItems;
72c613 ¤   INT¤¤   ¤   ¤   ¤   iIndex;
bf0d1a ¤   LV_ITEM¤¤   ¤   ¤   lvI;
25f2c6 ¤   PSHAREHOLDERSTRUCT¤ pshs;
2faf5a
363189 ¤   iNumItems = ListView_GetItemCount (psks->hwndList);
ae0560 ¤   for (iIndex=0; iIndex<iNumItems; iIndex++) {
cf4124 ¤   ¤   lvI.mask = LVIF_PARAM;
ca25c3 ¤   ¤   lvI.iItem = iIndex;
a897ef ¤   ¤   lvI.iSubItem = 0;
b57d9a ¤   ¤   ListView_GetItem (psks->hwndList, &lvI);
0daf5a
ef2abf ¤   ¤   pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
7e7338 ¤   ¤   KMFreePhrase (pshs->pszPassphrase);
3aaf5a
28e8b2 ¤   ¤   KMFree (pshs);
f29371 ¤   }
e0efe6 }
98af5a
beaf5a
bd9268 //¤ _______________________________________________
38465d //
a3a984 // ·destroy dialog struct and remove from list
4caf5a
9ab333 static VOID·
4656b8 sDestroySplitKeyStruct (PSPLITKEYSTRUCT psksToDestroy)
10bb36 {
01f0bb ¤   PSPLITKEYSTRUCT* ppsks;
0baf5a
8705ab ¤   ppsks = psksToDestroy->pHeadOfList;
68af5a
b02d56 ¤   while (*ppsks) {
395e7c ¤   ¤   if (*ppsks == psksToDestroy) {
f78c0c ¤   ¤   ¤   *ppsks = psksToDestroy->next;
8f63d5 ¤   ¤   ¤   KMFree (psksToDestroy);
c80ecc ¤   ¤   ¤   return;
820fe4 ¤   ¤   }
7a2516 ¤   ¤   ppsks = &((*ppsks)->next);
f69371 ¤   }
85efe6 }
d1af5a
6caf5a
0c9268 //¤ _______________________________________________
14465d //
9db6e7 // ·Compute name of share file
72af5a
2cf1ae static PGPError
286f17 sCreateFilePathFromUserName (
b806ed ¤   ¤   LPSTR¤  pszFolder,
6831ad ¤   ¤   LPSTR¤  pszUserID,
5d6325 ¤   ¤   UINT¤   uNumShares,
1e51b2 ¤   ¤   LPSTR¤  pszModifier,
ac1ad0 ¤   ¤   LPSTR¤  pszPath,·
97b48b ¤   ¤   INT¤¤   iLen)·
d9bb36 {
4c0223 ¤   CHAR¤   ¤   sz[kPGPMaxUserIDSize];
a3955c ¤   CHAR¤   ¤   szDefName[16];
e855e3 ¤   CHAR¤   ¤   szDefExt[8];
542dc8 ¤   CHAR¤   ¤   szShares[16];
84148b ¤   INT¤¤   ¤   iMinRequiredLen;
--5c06 0004bf56d5f401102b4 Page 8 of KMShare.c
8e2aea ¤   INT¤¤   ¤   i;
30af5a
1e4496 ¤   // prepare number of shares substring
f1b6d5 ¤   if (uNumShares == 1) {
30a9c1 ¤   ¤   LoadString (g_hInst, IDS_ONESHARE, szShares, sizeof(szShares));
af9371 ¤   }
14665a ¤   else {
cae0ee ¤   ¤   LoadString (g_hInst, IDS_NUMSHARES, sz, sizeof(sz));
7ed042 ¤   ¤   wsprintf (szShares, sz, uNumShares);
879371 ¤   }
66af5a
d24268 ¤   // get default file name and extension
b44844 ¤   LoadString (g_hInst, IDS_DEFSHARENAME, szDefName, sizeof(szDefName));
c79b12 ¤   lstrcat (szDefName, pszModifier);
45dc71 ¤   LoadString (g_hInst, IDS_DEFSHAREEXTENSION, szDefExt, sizeof(szDefExt));
3baf5a
650b74 ¤   // check length of destination buffer
7b81e4 ¤   iMinRequiredLen =·
ea2eef ¤   ¤   lstrlen (pszFolder) + lstrlen (szDefExt) + lstrlen (szDefName) +1;
ad8504 ¤   if (iMinRequiredLen >= iLen)·
20841f ¤   ¤   return kPGPError_CantOpenFile;
c6af5a
12f31c ¤   // put folder into path
321f4f ¤   lstrcpy (pszPath, pszFolder);
ab1245 ¤   iLen -= lstrlen (pszPath);
112949 ¤   if (pszPath[lstrlen(pszPath)-1] != '\\') {
849a9f ¤   ¤   lstrcat (pszPath, "\\");
9398c5 ¤   ¤   iLen -= 1;
c19371 ¤   }
3daf5a
1d7da4 ¤   // look for invalid characters and truncate
a3ad8d ¤   lstrcpy (sz, pszUserID);
0df283 ¤   i = strcspn (sz, "\\/:*?""<>|");
2c85ba ¤   sz[i] = '\0';
e7af5a
84238f ¤   // remove trailing spaces
fb1715 ¤   while ((i > 0) && (sz[i-1] == ' ')) {
e7a93e ¤   ¤   i--;
2bbf20 ¤   ¤   sz[i] = '\0';
ae9371 ¤   }
69af5a
69d466 ¤   // check if we've truncated too much
3d67e2 ¤   if (lstrlen (sz) < 2)·
70c603 ¤   ¤   lstrcpy (sz, szDefName);
b6af5a
6390bb ¤   // check if name is too long
b692b5 ¤   iLen -= (lstrlen (szDefExt) +1);
a0b5d3 ¤   if ((lstrlen(sz) + lstrlen(szShares) + lstrlen(pszModifier)) >= iLen) {
8a9e04 ¤   ¤   if ((lstrlen (sz) + lstrlen (pszModifier)) >= iLen) {
e465a2 ¤   ¤   ¤   if (lstrlen (sz) >= iLen) {
2dd7f8 ¤   ¤   ¤   ¤   sz[iLen-1] = '\0';
75a3a6 ¤   ¤   ¤   }
8684eb ¤   ¤   ¤   lstrcat (pszPath, sz);
95b579 ¤   ¤   ¤   lstrcat (pszPath, ".");
ba1c39 ¤   ¤   ¤   lstrcat (pszPath, szDefExt);
33af5a
a80fe4 ¤   ¤   }
3807e0 ¤   ¤   else {
1f84eb ¤   ¤   ¤   lstrcat (pszPath, sz);
2a8c8f ¤   ¤   ¤   lstrcat (pszPath, pszModifier);
b9b579 ¤   ¤   ¤   lstrcat (pszPath, ".");
191c39 ¤   ¤   ¤   lstrcat (pszPath, szDefExt);
6a0fe4 ¤   ¤   }
4e9371 ¤   }
97665a ¤   else {
b39d16 ¤   ¤   // construct full path
560894 ¤   ¤   lstrcat (pszPath, sz);
9a3673 ¤   ¤   lstrcat (pszPath, szShares);
ea04e9 ¤   ¤   lstrcat (pszPath, pszModifier);
9c3e85 ¤   ¤   lstrcat (pszPath, ".");
9a19d4 ¤   ¤   lstrcat (pszPath, szDefExt);
4b9371 ¤   }
--7b8a 0003520e55f401102b4 Page 9 of KMShare.c
e0af5a
a5151e ¤   return kPGPError_NoErr;
6aefe6 }
f8af5a
7daf5a
8c9268 //¤ _______________________________________________
af465d //
442a46 // ·split the key·
5caf5a
4069c9 static PGPError·
f850ce sSaveSharesToFile (
de036b ¤   ¤   PSHAREHOLDERSTRUCT¤ pshs,·
9c9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
c69679 ¤   ¤   PGPShareRef¤¤   ¤   sharesTotal,
69e561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
54a2d5 ¤   ¤   LPSTR¤  ¤   ¤   ¤   pszFolder)
3ebb36 {
46007d ¤   PFLFileSpecRef¤ ¤   filespec¤   ¤   = NULL;
24c665 ¤   PGPShareFileRef¤¤   sharefile¤  ¤   = NULL;
b2f03a ¤   PGPShareRef¤¤   ¤   sharesHolder¤   = NULL;
3a32d3 ¤   PGPOptionListRef¤   encodeOptions¤  = NULL;
7973ec ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
e9c857 ¤   INT¤¤   ¤   ¤   ¤   iModifier¤  ¤   = 0;
b1af5a
e6a19c ¤   CHAR¤   ¤   ¤   ¤   szPath[MAX_PATH];
837e8d ¤   CHAR¤   ¤   ¤   ¤   szModifier[MAX_SHARES_LEN+1];
3210f3 ¤   CHAR¤   ¤   ¤   ¤   sz1[32];
61de50 ¤   CHAR¤   ¤   ¤   ¤   sz2[kPGPMaxUserIDSize + 32];
4423e3 ¤   PGPKeyRef¤  ¤   ¤   key;
d7af5a
323708 ¤   // create file name and filespec
b94fe9 ¤   err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID,·
8052e3 ¤   ¤   ¤   ¤   ¤   ¤   pshs->uShares, NULL, szPath, sizeof(szPath));
d1f299 ¤   if (IsPGPError (err)) goto SaveFileCleanup;
8eaf5a
b3768c ¤   // check for pre-existence of file
f8cb82 ¤   while (GetFileAttributes (szPath) != 0xFFFFFFFF) {
b5a9b7 ¤   ¤   iModifier++;
7f910d ¤   ¤   if (iModifier > MAX_SHARES) {
4d7f09 ¤   ¤   ¤   err = kPGPError_CantOpenFile;
3fb3c5 ¤   ¤   ¤   goto SaveFileCleanup;
7d0fe4 ¤   ¤   }
195a53 ¤   ¤   wsprintf (szModifier, " %i", iModifier);
eefeda ¤   ¤   err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID,
170822 ¤   ¤   ¤   ¤   ¤   ¤   pshs->uShares, szModifier, szPath, sizeof(szPath));
8964d8 ¤   ¤   if (IsPGPError (err)) goto SaveFileCleanup;
b2f828 ¤   }¤
e5af5a
5ce140 ¤   err = PFLNewFileSpecFromFullPath (PGPGetContextMemoryMgr (context),·
a372ef ¤   ¤   szPath, &filespec);
8df299 ¤   if (IsPGPError (err)) goto SaveFileCleanup;
5667c5 ¤
dfb531 ¤   err = PFLFileSpecCreate (filespec);
03f299 ¤   if (IsPGPError (err)) goto SaveFileCleanup;
20af5a
b15ddb ¤   err = PGPNewShareFile (filespec, &sharefile);
c8f299 ¤   if (IsPGPError (err)) goto SaveFileCleanup;
ebaf5a
587be3 ¤   err = PGPSetShareFileUserID (sharefile, pshs->szUserID);
d3f299 ¤   if (IsPGPError (err)) goto SaveFileCleanup;
3aaf5a
9cb4fb ¤   err = PGPSplitShares (sharesTotal, pshs->uShares, &sharesHolder);
21f299 ¤   if (IsPGPError (err)) goto SaveFileCleanup;
82af5a
d03b19 ¤   // if this shareholder has public key, use it
2af63f ¤   if (pshs->bPublicKey) {
09f4f7 ¤   ¤   err = PGPSetShareFileOwnerKeyID (sharefile, pshs->keyid);
1564d8 ¤   ¤   if (IsPGPError (err)) goto SaveFileCleanup;
f9af5a
235c3b ¤   ¤   err = PGPGetKeyByKeyID (keyset, &(pshs->keyid), pshs->keyalg, &key);
2ea42f ¤   ¤   if (IsPGPError (err)) {
3537ad ¤   ¤   ¤   LoadString (g_hInst, IDS_CAPTIONERROR, sz1, sizeof(sz1));
--9b1f 00087a883c9401102b4 Page 10 of KMShare.c
887711 ¤   ¤   ¤   LoadString (g_hInst, IDS_SHAREKEYGONE, sz2, sizeof(sz2));
a6adf5 ¤   ¤   ¤   lstrcat (sz2, pshs->szUserID);
c0c86c ¤   ¤   ¤   MessageBox (NULL, sz2, sz1, MB_OK|MB_ICONERROR);
404e2b ¤   ¤   ¤   err = kPGPError_UserAbort;
abb3c5 ¤   ¤   ¤   goto SaveFileCleanup;
a50fe4 ¤   ¤   }
0caf5a
42ed78 ¤   ¤   err = PGPBuildOptionList (context, &encodeOptions,
c5f634 ¤   ¤   ¤   PGPOEncryptToKey (context, key),
e96445 ¤   ¤   ¤   PGPOLastOption (context));
9f64d8 ¤   ¤   if (IsPGPError (err)) goto SaveFileCleanup;
ee9371 ¤   }
0baf5a
c05f40 ¤   // there is no public key for this shareholder
52665a ¤   else {
03ed78 ¤   ¤   err = PGPBuildOptionList (context, &encodeOptions,
124bff ¤   ¤   ¤   PGPOConventionalEncrypt (context,
b27f7b ¤   ¤   ¤   ¤   PGPOPassphrase (context, pshs->pszPassphrase),
78b290 ¤   ¤   ¤   ¤   PGPOLastOption (context)),
cd6445 ¤   ¤   ¤   PGPOLastOption (context));
bb64d8 ¤   ¤   if (IsPGPError (err)) goto SaveFileCleanup;
e39371 ¤   }
0baf5a
0f047d ¤   err = PGPCopySharesToFile (context, sharefile,·
7dff02 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   encodeOptions, sharesHolder);
1ff299 ¤   if (IsPGPError (err)) goto SaveFileCleanup;
99af5a
be1331 ¤   err = PGPSaveShareFile (sharefile);
afaf5a
f851a7 SaveFileCleanup:
6aaf5a
71bc90 ¤   if (encodeOptions != NULL)
1fd76e ¤   ¤   PGPFreeOptionList (encodeOptions);
80af5a
4ff70d ¤   if (sharesHolder != NULL)
dcb482 ¤   ¤   PGPFreeShares (sharesHolder);
c4af5a
890e23 ¤   if (sharefile != NULL)
473f4d ¤   ¤   PGPFreeShareFile (sharefile);
c0af5a
689a43 ¤   if (filespec != NULL)
f1a4b0 ¤   ¤   PFLFreeFileSpec (filespec);
4aaf5a
695ea8 ¤   return err;
a1efe6 }
90af5a
61af5a
939268 //¤ _______________________________________________
57465d //
571f53 //¤ Split key progress dialog message procedure
51af5a
af3f64 static BOOL CALLBACK·
eeaaf1 sSplitKeyProgressDlgProc (HWND hDlg,·
b2ffab ¤   ¤   ¤   ¤   ¤   ···UINT uMsg,·
8b69ae ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam,·
036d27 ¤   ¤   ¤   ¤   ¤   ···LPARAM lParam)·
23bb36 {
c64b7e ¤   SPLITKEYPROGRESSSTRUCT*¤pskps;
40af5a
1b347f ¤   switch (uMsg) {
24af5a
e5ad3a ¤   case WM_INITDIALOG :
62e3ba ¤   ¤   // save address of struct
2c7547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
ca21e7 ¤   ¤   pskps = (SPLITKEYPROGRESSSTRUCT*)lParam;
5593db ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESSBAR, PBM_SETRANGE,
cc67c4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, MAKELPARAM(0, pskps->iNumSteps));
ca5afb ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESSBAR, PBM_SETPOS,
c12d36 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0);
d4836c ¤   ¤   return TRUE;
65af5a
875020 ¤   case WM_APP :
--057e 000bb6e165d401102b4 Page 11 of KMShare.c
935afb ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESSBAR, PBM_SETPOS,
59335e ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam, 0);
c1df46 ¤   ¤   SetDlgItemText (hDlg, IDC_PROGRESSTEXT, (LPSTR)lParam);
7f2f68 ¤   ¤   break;
b5af5a
4c9371 ¤   }
07a230 ¤   return FALSE;
efefe6 }
61af5a
fdaf5a
4f4265 //¤ ___________________________________________________
b7465d //
eedd18 // ·Change passphrase of key and all subkeys
4daf5a
bf69c9 static PGPError·
b2e737 sChangeKeyPhrase (
fee958 ¤   ¤   PGPContextRef¤  context,
348b6a ¤   ¤   PGPKeySetRef¤   keyset,
d3868f ¤   ¤   PGPKeyRef¤  ¤   key,·
815acd ¤   ¤   LPSTR¤  ¤   ¤   szOld,·
d05750 ¤   ¤   PGPByte*¤   ¤   pPasskeyOld,
fab147 ¤   ¤   PGPSize¤¤   ¤   sizePasskeyOld,
4b82df ¤   ¤   PGPByte*¤   ¤   pPasskey,
dd4a08 ¤   ¤   PGPSize¤¤   ¤   sizePasskey)·
53bb36 {
7f6e76 ¤   UINT¤   ¤   ¤   u;
3bd125 ¤   PGPKeyListRef¤  keylist;
c2c323 ¤   PGPKeyIterRef¤  keyiter;
be87ac ¤   PGPSubKeyRef¤   subkey;
63fb19 ¤   PGPError¤   ¤   err;
2baf5a
8dabe4 ¤   if (szOld) {
3a3f52 ¤   ¤   err = PGPChangePassphrase (key,·
20a72a ¤   ¤   ¤   ¤   PGPOPassphrase (context, szOld),·
b3a047 ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
496a09 ¤   ¤   ¤   ¤   PGPOLastOption (context));
659371 ¤   }
4568bb ¤   else if (sizePasskeyOld > 0) {
ce3f52 ¤   ¤   err = PGPChangePassphrase (key,·
7e0cd2 ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pPasskeyOld, sizePasskeyOld),·
b7a047 ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
fc6a09 ¤   ¤   ¤   ¤   PGPOLastOption (context));
dc9371 ¤   }
17665a ¤   else {
c53f52 ¤   ¤   err = PGPChangePassphrase (key,·
dd57d5 ¤   ¤   ¤   ¤   PGPOPassphrase (context, ""),·
90a047 ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
c16a09 ¤   ¤   ¤   ¤   PGPOLastOption (context));
0d9371 ¤   }
a98616 ¤   if (IsPGPError (err)) return err;
bdaf5a
a18b21 ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u);
6b86a2 ¤   switch (u) {
212692 ¤   case kPGPPublicKeyAlgorithm_RSA :
372f68 ¤   ¤   break;
38af5a
8d7cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
9b278b ¤   ¤   PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
42fa80 ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
4dae6d ¤   ¤   PGPKeyIterSeek (keyiter, key);
ea9c21 ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
556680 ¤   ¤   while (subkey) {
435bbe ¤   ¤   ¤   if (szOld) {
d28924 ¤   ¤   ¤   ¤   err = PGPChangeSubKeyPassphrase (subkey,·
2b62ce ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (context, szOld),
e9f539 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
7e2323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
11a3a6 ¤   ¤   ¤   }
112704 ¤   ¤   ¤   else if (sizePasskeyOld > 0) {
cb8924 ¤   ¤   ¤   ¤   err = PGPChangeSubKeyPassphrase (subkey,·
3a739e ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context,·
bb0dca ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskeyOld, sizePasskeyOld),
--624e 000379328db401102b4 Page 12 of KMShare.c
5df539 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
8c2323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
efa3a6 ¤   ¤   ¤   }
37e543 ¤   ¤   ¤   else {
a98924 ¤   ¤   ¤   ¤   err = PGPChangeSubKeyPassphrase (subkey,·
b5f75e ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (context, ""),
c2f539 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
e82323 ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (context));
3ea3a6 ¤   ¤   ¤   }
38cf3a ¤   ¤   ¤   PGPKeyIterNextSubKey (keyiter, &subkey);
690fe4 ¤   ¤   }
dbe9ea ¤   ¤   PGPFreeKeyIter (keyiter);
ea5a47 ¤   ¤   PGPFreeKeyList (keylist);
192f68 ¤   ¤   break;
adaf5a
4fbfad ¤   default :
e32f68 ¤   ¤   break;
7c9371 ¤   }
b9af5a
855ea8 ¤   return err;
bfefe6 }
b8af5a
1f9268 //¤ _______________________________________________
a5465d //
422a46 // ·split the key·
8baf5a
3a6c77 static BOOL·
d84c94 sSplitKey (PSPLITKEYSTRUCT psks)
79bb36 {
190c85 ¤   PGPShareRef¤¤   ¤   shares¤ ¤   ¤   ¤   = NULL;
dc0331 ¤   PGPSize¤¤   ¤   ¤   sizePasskey¤¤   ¤   = 0;
a500fb ¤   PGPByte*¤   ¤   ¤   pPasskey¤   ¤   ¤   = NULL;
f9fbd1 ¤   LPSTR¤  ¤   ¤   ¤   pszPhraseKeyToSplit¤= NULL;
548a5e ¤   PGPByte*¤   ¤   ¤   pPasskeyToSplit¤¤   = NULL;
a207b6 ¤   PGPSize¤¤   ¤   ¤   sizePasskeyToSplit¤ = 0;
ae9a6f ¤   CHAR¤   ¤   ¤   ¤   szEmptyString[]¤¤   = {""};
1867f7 ¤   HWND¤   ¤   ¤   ¤   hwndProgress¤   ¤   = NULL;
e6997f ¤   BOOL¤   ¤   ¤   ¤   bRetVal¤¤   ¤   ¤   = TRUE;
0caf5a
22ba49 ¤   PGPError¤   ¤   ¤   ¤   err;
120984 ¤   PGPKeyRef¤  ¤   ¤   ¤   keyToSplit;
77395d ¤   BROWSEINFO¤ ¤   ¤   ¤   bi;
04464d ¤   LPITEMIDLIST¤   ¤   ¤   pidl;
aac099 ¤   LPMALLOC¤   ¤   ¤   ¤   pMalloc;
467da4 ¤   CHAR¤   ¤   ¤   ¤   ¤   szFolder[MAX_PATH];
88f212 ¤   CHAR¤   ¤   ¤   ¤   ¤   sz[kPGPMaxUserIDSize + 32];
121f62 ¤   INT¤¤   ¤   ¤   ¤   ¤   iItem;
4fb311 ¤   INT¤¤   ¤   ¤   ¤   ¤   iNumItems;
d4f8d3 ¤   LV_ITEM¤¤   ¤   ¤   ¤   lvI;
ce0023 ¤   PSHAREHOLDERSTRUCT¤ ¤   pshs;
967d92 ¤   HCURSOR¤¤   ¤   ¤   ¤   hcursorOld;
648636 ¤   SPLITKEYPROGRESSSTRUCT¤ skps;
6daf5a
7779fd ¤   // get keyref from keyring
271ba4 ¤   err = PGPGetKeyByKeyID (psks->pKM->KeySetMain, &(psks->keyidToSplit),
7f4e66 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->keyalgToSplit, &keyToSplit);
7d0971 ¤   if (IsPGPError (err)) {
3c9486 ¤   ¤   KMMessageBox (psks->hwndDlg, IDS_CAPTIONERROR, IDS_SPLITKEYGONE,·
ec5c33 ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONERROR);
1ba63c ¤   ¤   bRetVal = FALSE;
1ffbb0 ¤   ¤   goto SplitKeyCleanup;
0d9371 ¤   }
9eaf5a
7ce7b6 ¤   // get task allocator
68f0db ¤   if (SHGetMalloc(&pMalloc) != NOERROR) return FALSE;
d3af5a
64fee3 ¤   // get prompt string
854d1b ¤   LoadString (g_hInst, IDS_SAVESHARES, sz, sizeof(sz));
d1af5a
61abb0 ¤   // initialize structure
26c32f ¤   bi.hwndOwner = psks->hwndDlg;
378b1e ¤   bi.pidlRoot = NULL;
--8bdf 0000deb486e401102b4 Page 13 of KMShare.c
b065e2 ¤   bi.pszDisplayName = szFolder;
f48775 ¤   bi.lpszTitle = sz;
4729fa ¤   bi.ulFlags = BIF_RETURNONLYFSDIRS;
aa8387 ¤   bi.lpfn = NULL;
563c28 ¤   bi.lParam = 0;
dfaf5a
cd1c03 ¤   // allow user to browse
91bb27 ¤   pidl = SHBrowseForFolder (&bi);
5a05bb ¤   if (pidl == NULL) return FALSE;
258361 ¤   SHGetPathFromIDList (pidl, szFolder);
410ca7 ¤   pMalloc->lpVtbl->Free(pMalloc, pidl);
33af5a
eadb38 ¤   // get passphrase of key to split
fdedb4 ¤   LoadString (g_hInst, IDS_SPLITKEYPHRASEPROMPT, sz, sizeof(sz));
b2b504 ¤   err = KMGetKeyPhrase (psks->pKM->Context, psks->pKM->tlsContext,
6f8591 ¤   ¤   ¤   psks->hwndDlg, sz,·
3affe3 ¤   ¤   ¤   psks->pKM->KeySetMain, keyToSplit,
b34c70 ¤   ¤   ¤   &pszPhraseKeyToSplit, &pPasskeyToSplit,·
7a0517 ¤   ¤   ¤   &sizePasskeyToSplit);
e218b2 ¤   PGPclErrorBox (NULL, err);
60af5a
9f0971 ¤   if (IsPGPError (err)) {
aea63c ¤   ¤   bRetVal = FALSE;
4dfbb0 ¤   ¤   goto SplitKeyCleanup;
1d9371 ¤   }
91af5a
471bf6 ¤   // make sure that this is what user wants to do
b36eba ¤   if (KMMessageBox (psks->hwndDlg, IDS_CAPTION, IDS_SPLITKEYCONFIRMATION,
bd83b6 ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
bba63c ¤   ¤   bRetVal = FALSE;
a4fbb0 ¤   ¤   goto SplitKeyCleanup;
2d9371 ¤   }
73af5a
dea449 ¤   // post progress dialog
fd3189 ¤   iNumItems = ListView_GetItemCount (psks->hwndList);
8a33b9 ¤   skps.iNumSteps = iNumItems +2;
9e1c53 ¤   hwndProgress = CreateDialogParam (g_hInst,·
7cd8dd ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_SPLITKEYPROGRESS),
d71adb ¤   ¤   ¤   ¤   ¤   ¤   psks->hwndDlg, sSplitKeyProgressDlgProc,
2cfb64 ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&skps);
c622d2 ¤   LoadString (g_hInst, IDS_CREATINGSHARES, sz, sizeof(sz));
cf9c7d ¤   SendMessage (hwndProgress, WM_APP, 1, (LPARAM)sz);
c5af5a
667cf9 ¤   // create the shares
31bf07 ¤   err = PGPCreateShares (¤psks->pKM->Context,·
7a4d64 ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyToSplit,·
4e67ae ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uThreshold,·
1b81c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uTotalShares,·
a36bf9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &shares);
b8af5a
dc3b6f ¤   if (IsPGPError (PGPclErrorBox (NULL, err))) {
e6a63c ¤   ¤   bRetVal = FALSE;
dafbb0 ¤   ¤   goto SplitKeyCleanup;
a99371 ¤   }
91af5a
a01f45 ¤   // get the passkey from the shares
62509e ¤   err = PGPGetPasskeyFromShares (shares, &pPasskey, &sizePasskey);
f024d2 ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
fcaf5a
0cbbc4 ¤   ¤   hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
5caf5a
582eaf ¤   ¤   // save share file for each item in listview
b3de92 ¤   ¤   for (iItem=0; iItem<iNumItems; iItem++) {
87cd5b ¤   ¤   ¤   lvI.mask = LVIF_PARAM;
7a9bd3 ¤   ¤   ¤   lvI.iItem = iItem;
5d1ebb ¤   ¤   ¤   lvI.iSubItem = 0;
1cb365 ¤   ¤   ¤   ListView_GetItem(psks->hwndList, &lvI);
24af5a
a4f66a ¤   ¤   ¤   // update progress dialog
62f20d ¤   ¤   ¤   pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
f3f566 ¤   ¤   ¤   LoadString (g_hInst, IDS_SAVINGSHARES, sz, sizeof(sz));
0d97ae ¤   ¤   ¤   lstrcat (sz, pshs->szUserID);
--7795 000453e6a96401102b4 Page 14 of KMShare.c
e1423c ¤   ¤   ¤   SendMessage (hwndProgress, WM_APP, iItem+2, (LPARAM)sz);
41af5a
6994ba ¤   ¤   ¤   err = sSaveSharesToFile (pshs, psks->pKM->Context, shares,
f8fec2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->pKM->KeySetMain, szFolder);
a91cfb ¤   ¤   ¤   if (IsPGPError (err)) break;
200fe4 ¤   ¤   }
32af5a
ad1919 ¤   ¤   // update progress dialog
cd36e3 ¤   ¤   LoadString (g_hInst, IDS_SPLITTINGKEY, sz, sizeof(sz));
0625cf ¤   ¤   SendMessage (hwndProgress, WM_APP, iNumItems+2, (LPARAM)sz);
d0af5a
9e5a89 ¤   ¤   SetCursor (hcursorOld);
f394cd ¤   ¤   PGPclErrorBox (NULL, err);
4aaf5a
73a42f ¤   ¤   if (IsPGPError (err)) {
33401a ///¤¤   ¤   delete files;
d40fe4 ¤   ¤   }
5607e0 ¤   ¤   else {
0a847e ¤   ¤   ¤   err = sChangeKeyPhrase (psks->pKM->Context,·
0733cb ¤   ¤   ¤   ¤   ¤   psks->pKM->KeySetMain, keyToSplit,·
140bcf ¤   ¤   ¤   ¤   ¤   pszPhraseKeyToSplit, pPasskeyToSplit, sizePasskeyToSplit,
524c28 ¤   ¤   ¤   ¤   ¤   pPasskey, sizePasskey);
0dd53e ¤   ¤   ¤   PGPclErrorBox (NULL, err);
79378a ¤   ¤   ¤   KMCommitKeyRingChanges (psks->pKM);·
f8a299 ¤   ¤   ¤   KMUpdateKeyInTree (psks->pKM, keyToSplit, FALSE);
557779 ¤   ¤   ¤   KMSelectKey (psks->pKM, keyToSplit, TRUE);
5a0fe4 ¤   ¤   }
2f9371 ¤   }
7eaf5a
dacd7e ¤   // cleanup
1396ee SplitKeyCleanup :
9674c0 ¤   if (hwndProgress)
1b1a26 ¤   ¤   DestroyWindow (hwndProgress);
50af5a
479200 ¤   if (pszPhraseKeyToSplit)·
395cf3 ¤   ¤   KMFreePhrase (pszPhraseKeyToSplit);
8faf5a
8f778b ¤   if (pPasskeyToSplit)
e73e3d ¤   ¤   KMFreePasskey (pPasskeyToSplit, sizePasskeyToSplit);
00af5a
590eb3 ¤   if (pPasskey)
28807a ¤   ¤   PGPFreeData (pPasskey);
acaf5a
4d2c63 ¤   if (shares != NULL)
3d559e ¤   ¤   PGPFreeShares (shares);
ecaf5a
2eed60 ¤   return (bRetVal);
09efe6 }
64af5a
59af5a
069268 //¤ _______________________________________________
c4465d //
5ef36f //¤ Split key dialog message procedure
b9af5a
9d3f64 static BOOL CALLBACK·
3fef01 sSplitKeyDlgProc (HWND hDlg,·
68887f ¤   ¤   ¤   ¤   ·UINT uMsg,·
a1efe7 ¤   ¤   ¤   ¤   ·WPARAM wParam,·
15eb6e ¤   ¤   ¤   ¤   ·LPARAM lParam)·
21bb36 {
81462f ¤   PSPLITKEYSTRUCT¤¤   psks;
2e201c ¤   CHAR¤   ¤   ¤   ¤   sz[8];
ba13fa ¤   NMHDR*¤ ¤   ¤   ¤   pnmh;
a6e744 ¤   UINT¤   ¤   ¤   ¤   u;
94af5a
ae347f ¤   switch (uMsg) {
fdaf5a
c9ad3a ¤   case WM_INITDIALOG :
24c7a1 ¤   {
304c97 ¤   ¤   CHAR¤   szTitle[kPGPMaxUserIDSize + 32];
84af5a
45e3ba ¤   ¤   // save address of struct
--4981 00083abaeb4401102b4 Page 15 of KMShare.c
b27547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
0a74c3 ¤   ¤   psks = (PSPLITKEYSTRUCT)lParam;
cd1179 ¤   ¤   psks->hwndDlg = hDlg;
16af5a
2ac8e5 ¤   ¤   // if we have a function to call to add hwnd to list, then call it
0ea19b ¤   ¤   if (psks->pKM->lpfnHwndListFunc)·
75da80 ¤   ¤   ¤   (psks->pKM->lpfnHwndListFunc)(hDlg, TRUE, NULL, NULL);
68af5a
293027 ¤   ¤   // initialize shareholder list
ad6e00 ¤   ¤   psks->hwndList = GetDlgItem (hDlg, IDC_SHAREHOLDERS);
7cacd0 ¤   ¤   sInitKeyList (psks);
42af5a
baca82 ¤   ¤   // initialize name of key to split
305fc9 ¤   ¤   SetDlgItemText (hDlg, IDC_KEYTOSPLIT, psks->szUserIDToSplit);
9012a5 ¤   ¤   LoadString (g_hInst, IDS_SPLITKEYTITLE, szTitle, sizeof(szTitle));
859061 ¤   ¤   lstrcat (szTitle, psks->szUserIDToSplit);
86eea5 ¤   ¤   SetWindowText (hDlg, szTitle);
deaf5a
4a767d ¤   ¤   // limit number of shares
c14c73 ¤   ¤   SendDlgItemMessage (hDlg, IDC_SHARES, EM_SETLIMITTEXT,·
261902 ¤   ¤   ¤   ¤   (WPARAM)MAX_SHARES_LEN, 0);
0db1a4 ¤   ¤   SendDlgItemMessage (hDlg, IDC_THRESHOLD, EM_SETLIMITTEXT,·
441902 ¤   ¤   ¤   ¤   (WPARAM)MAX_SHARES_LEN, 0);
95af5a
59f11d ¤   ¤   // initialize spin controls·
359b34 ¤   ¤   SendDlgItemMessage (hDlg, IDC_SHARESSPIN, UDM_SETRANGE,
0515a8 ¤   ¤   ¤   ¤   0, (LPARAM)MAKELONG (MAX_SHARES, 1));
3a68d8 ¤   ¤   SetDlgItemText (hDlg, IDC_SHARES, "");
50dea3 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SHARES), FALSE);
d3af5a
dc66e3 ¤   ¤   SendDlgItemMessage (hDlg, IDC_THRESHOLDSPIN, UDM_SETRANGE,
fb15a8 ¤   ¤   ¤   ¤   0, (LPARAM)MAKELONG (MAX_SHARES, 1));
a39279 ¤   ¤   SendDlgItemMessage (hDlg, IDC_THRESHOLDSPIN, UDM_SETPOS,
e347a4 ¤   ¤   ¤   ¤   0, (LPARAM)MAKELONG (psks->uThreshold, 0));
adaf5a
82da41 ¤   ¤   // initialize total number of shares
5f7989 ¤   ¤   SetDlgItemInt (hDlg, IDC_TOTALSHARES, psks->uTotalShares, FALSE);
4eaf5a
f578eb ¤   ¤   // "split key" and "remove" buttons initially disabled
0e7fe3 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_REMOVESHAREHOLDER), FALSE);
0e7c02 ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
c5af5a
a2a60b ¤   ¤   // initialize drag/drop
31badf ¤   ¤   psks->pDropTarget = KMCreateDropTarget (psks->hwndList, NULL, psks);·
2db2b1 ¤   ¤   CoLockObjectExternal ((IUnknown*)psks->pDropTarget, TRUE, TRUE);
fa7229 ¤   ¤   RegisterDragDrop (psks->hwndList, psks->pDropTarget);
bced9a ¤   ¤   KMEnableDropTarget (psks->pDropTarget, TRUE);
74af5a
a2836c ¤   ¤   return TRUE;
5b9371 ¤   }
c1af5a
308a25 ¤   case WM_HELP:·
15c7a1 ¤   {
49fb42 ¤   ····WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,·
8677aa ¤   ········HELP_WM_HELP, (DWORD) (LPSTR) aSplitIds);·
0b7d53 ¤   ····break;·
c19371 ¤   }
18af5a
0faf40 ¤   case WM_CONTEXTMENU:·
67c7a1 ¤   {
0a082b ¤   ¤   WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
06dd6d ¤   ¤   ····(DWORD) (LPVOID) aSplitIds);·
5aca2d ¤   ¤   break;·
819371 ¤   }
6caf5a
711431 ¤   case WM_NOTIFY :
36dd21 ¤   ¤   pnmh = (NMHDR*)lParam;
f2d254 ¤   ¤   switch (pnmh->code) {
50af5a
07958b ¤   ¤   case NM_CLICK :
7ac191 ¤   ¤   case LVN_KEYDOWN :
83df78 ¤   ¤   ¤   if (pnmh->idFrom == IDC_SHAREHOLDERS) {
--02da 00013971c93401102b4 Page 16 of KMShare.c
963184 ¤   ¤   ¤   ¤   INT¤¤   iIndex;
1aaf5a
c100e8 ¤   ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
c562e8 ¤   ¤   ¤   ¤   iIndex =·
16b487 ¤   ¤   ¤   ¤   ¤   ListView_GetNextItem (psks->hwndList, -1, LVNI_SELECTED);
484f98 ¤   ¤   ¤   ¤   if (iIndex > -1) {
cd8871 ¤   ¤   ¤   ¤   ¤   LV_ITEM¤¤   ¤   ¤   lvI;
ac2f96 ¤   ¤   ¤   ¤   ¤   PSHAREHOLDERSTRUCT¤ pshs;
53af5a
4c82e4 ¤   ¤   ¤   ¤   ¤   lvI.mask = LVIF_PARAM;
59c634 ¤   ¤   ¤   ¤   ¤   lvI.iItem = iIndex;
24c6c0 ¤   ¤   ¤   ¤   ¤   lvI.iSubItem = 0;
b3699e ¤   ¤   ¤   ¤   ¤   ListView_GetItem(psks->hwndList, &lvI);
0faf5a
4ee411 ¤   ¤   ¤   ¤   ¤   pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
e35509 ¤   ¤   ¤   ¤   ¤   psks->pshsCurrent = pshs;
f2bb1e ¤   ¤   ¤   ¤   ¤   psks->iIndexCurrent = iIndex;
a7af5a
3caac7 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_CURRENTSHAREHOLDER,·
a0d61e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pshs->szUserID);
79377d ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_SHARESSPIN, UDM_SETPOS,
c58740 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)MAKELONG (pshs->uShares, 0));
80af5a
4e5e32 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SHARES), TRUE);
0ad41a ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SHARESSPIN), TRUE);
2be326 ¤   ¤   ¤   ¤   ¤   EnableWindow (
b0c434 ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_REMOVESHAREHOLDER), TRUE);
1f2613 ¤   ¤   ¤   ¤   }
38deaa ¤   ¤   ¤   ¤   else {
aa7e2b ¤   ¤   ¤   ¤   ¤   psks->iIndexCurrent = -1;
d9c1a4 ¤   ¤   ¤   ¤   ¤   psks->pshsCurrent = NULL;
5fa676 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_SHARES, "");
9ba577 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_CURRENTSHAREHOLDER, "");
9289b9 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SHARES), FALSE);
ebe326 ¤   ¤   ¤   ¤   ¤   EnableWindow (
03ec15 ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItem (hDlg, IDC_REMOVESHAREHOLDER), FALSE);
092613 ¤   ¤   ¤   ¤   }
83a3a6 ¤   ¤   ¤   }
d5cdcb ¤   ¤   ¤   break;
f40fe4 ¤   ¤   }
dc2f68 ¤   ¤   break;
eeaf5a
b46334 ¤   case WM_DESTROY :
4a5596 ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
9aaf5a
9d3135 ¤   ¤   // terminate drag/drop
14388b ¤   ¤   RevokeDragDrop (psks->hwndList);
cf0799 ¤   ¤   KMReleaseDropTarget (psks->pDropTarget); ·
276d0e ¤   ¤   CoLockObjectExternal ((IUnknown*)psks->pDropTarget, FALSE, TRUE);
30af5a
e995a3 ¤   ¤   // call function to remove hwnd from list
80a19b ¤   ¤   if (psks->pKM->lpfnHwndListFunc)·
f254c2 ¤   ¤   ¤   (psks->pKM->lpfnHwndListFunc)(hDlg, FALSE, NULL, NULL);
caaf5a
b967ed ¤   ¤   // destroy data objects
d57c5f ¤   ¤   ImageList_Destroy (psks->hIml);
7e3674 ¤   ¤   sDestroyShareHolders (psks);
bde5ac ¤   ¤   sDestroySplitKeyStruct (psks);
a72f68 ¤   ¤   break;
00af5a
b13fcf ¤   case WM_COMMAND:
1faf5a
14537d ¤   ¤   switch (LOWORD(wParam)) {
a0b6bb ¤   ¤   case IDCANCEL :
360abd ¤   ¤   ¤   DestroyWindow (hDlg);
78cdcb ¤   ¤   ¤   break;
14af5a
668c29 ¤   ¤   case IDOK :
db1be1 ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
4adb84 ¤   ¤   ¤   EnableWindow (psks->pKM->hWndParent, FALSE);
40eb19 ¤   ¤   ¤   if (sSplitKey (psks))·
13f776 ¤   ¤   ¤   {
--4ef7 000f912918a401102b4 Page 17 of KMShare.c
906935 ¤   ¤   ¤   ¤   EnableWindow (psks->pKM->hWndParent, TRUE);
63e5ce ¤   ¤   ¤   ¤   DestroyWindow (hDlg);
b5a3a6 ¤   ¤   ¤   }
1dbb8c ¤   ¤   ¤   else
ad6935 ¤   ¤   ¤   ¤   EnableWindow (psks->pKM->hWndParent, TRUE);
eccdcb ¤   ¤   ¤   break;
17af5a
6743f5 ¤   ¤   case IDHELP :
5d1be1 ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
fd183a ¤   ¤   ¤   WinHelp (hDlg, psks->pKM->szHelpFile, HELP_CONTEXT,·
02ba20 ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPCLSPLIT_SPLITDIALOG);·
a2cdcb ¤   ¤   ¤   break;
4faf5a
7cf69c ¤   ¤   case IDC_ADDSHAREHOLDER :
ce1be1 ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
40db84 ¤   ¤   ¤   EnableWindow (psks->pKM->hWndParent, FALSE);
24cb57 ¤   ¤   ¤   sAddShareHolderToList (hDlg, psks);
3be662 ¤   ¤   ¤   EnableWindow (psks->pKM->hWndParent, TRUE);
efd541 ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_ADDSHAREHOLDER));
48cdcb ¤   ¤   ¤   break;
ebaf5a
f76fca ¤   ¤   case IDC_REMOVESHAREHOLDER :
061be1 ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
55aa41 ¤   ¤   ¤   sRemoveShareHolderFromList (hDlg, psks);
387b00 ¤   ¤   ¤   psks->iIndexCurrent = -1;
f5c48f ¤   ¤   ¤   psks->pshsCurrent = NULL;
43b06a ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_SHARES, "");
ad3b07 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_CURRENTSHAREHOLDER, "");
16048a ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_SHARES), FALSE);
8264ea ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_REMOVESHAREHOLDER), FALSE);
2ccdcb ¤   ¤   ¤   break;
4eaf5a
b625cc ¤   ¤   case IDC_THRESHOLD :
2e2783 ¤   ¤   ¤   switch (HIWORD(wParam)) {
beefdb ¤   ¤   ¤   case EN_CHANGE :
6000e8 ¤   ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
4e5148 ¤   ¤   ¤   ¤   if (psks) {
e7677d ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_THRESHOLD, sz, sizeof(sz));
62285c ¤   ¤   ¤   ¤   ¤   if (lstrcmp (sz, "0")) {
59717e ¤   ¤   ¤   ¤   ¤   ¤   UINT u =·
170bae ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemInt (hDlg, IDC_THRESHOLD, NULL, FALSE);
5ff4bb ¤   ¤   ¤   ¤   ¤   ¤   if (u != 0) {
a9d750 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uThreshold = u;
08aa9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (psks->uTotalShares >= psks->uThreshold)
fe5d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
95c4dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
85d827 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
78db3c ¤   ¤   ¤   ¤   ¤   ¤   }
711c89 ¤   ¤   ¤   ¤   ¤   }
d12613 ¤   ¤   ¤   ¤   }
4ff622 ¤   ¤   ¤   ¤   break;
d9af5a
7e1e40 ¤   ¤   ¤   case EN_KILLFOCUS :
1eb0ec ¤   ¤   ¤   ¤   u = GetDlgItemInt (hDlg, IDC_THRESHOLD, NULL, FALSE);
911e87 ¤   ¤   ¤   ¤   if (u == 0) u = 1;
0763ba ¤   ¤   ¤   ¤   SetDlgItemInt (hDlg, IDC_THRESHOLD, u, FALSE);
80f622 ¤   ¤   ¤   ¤   break;
dca3a6 ¤   ¤   ¤   }
c9cdcb ¤   ¤   ¤   break;
9aaf5a
956f35 ¤   ¤   case IDC_SHARES :
581be1 ¤   ¤   ¤   psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
d22783 ¤   ¤   ¤   switch (HIWORD(wParam)) {
90efdb ¤   ¤   ¤   case EN_CHANGE :
6c5148 ¤   ¤   ¤   ¤   if (psks) {
6f2f96 ¤   ¤   ¤   ¤   ¤   PSHAREHOLDERSTRUCT¤ pshs;
672f5b ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_SHARES, sz, sizeof(sz));
b826a7 ¤   ¤   ¤   ¤   ¤   pshs = psks->pshsCurrent;
136ba9 ¤   ¤   ¤   ¤   ¤   if (pshs && (lstrcmp (sz, "0"))) {
26717e ¤   ¤   ¤   ¤   ¤   ¤   UINT u =·
596946 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemInt (hDlg, IDC_SHARES, NULL, FALSE);
f9f4bb ¤   ¤   ¤   ¤   ¤   ¤   if (u != 0) {
--2a48 00055eb51de401102b4 Page 18 of KMShare.c
2c1546 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uTotalShares -= pshs->uShares;
e0ff5c ¤   ¤   ¤   ¤   ¤   ¤   ¤   pshs->uShares = u;
9a1736 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uTotalShares += pshs->uShares;
77c66b ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetDlgItemInt (hDlg, IDC_TOTALSHARES,·
141d9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->uTotalShares, FALSE);
46af5a
f30677 ¤   ¤   ¤   ¤   ¤   ¤   ¤   wsprintf (sz, "%i", pshs->uShares);
4ad503 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ListView_SetItemText (psks->hwndList,·
5081f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->iIndexCurrent, 1, sz);
baaf5a
663bc9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if ((psks->uTotalShares >= psks->uThreshold) &&
bf4189 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (psks->uTotalShares <= MAX_TOTAL_SHARES))
645d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), TRUE);
2ec4dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
dbd827 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDOK), FALSE);
18db3c ¤   ¤   ¤   ¤   ¤   ¤   }
321c89 ¤   ¤   ¤   ¤   ¤   }
da2613 ¤   ¤   ¤   ¤   }
f7f622 ¤   ¤   ¤   ¤   break;
31af5a
0c1e40 ¤   ¤   ¤   case EN_KILLFOCUS :
889ef6 ¤   ¤   ¤   ¤   u = GetDlgItemInt (hDlg, IDC_SHARES, NULL, FALSE);
c84cda ¤   ¤   ¤   ¤   if (u == 0) {
fefbf2 ¤   ¤   ¤   ¤   ¤   u = 1;
6fe305 ¤   ¤   ¤   ¤   ¤   MessageBeep (MB_ICONASTERISK);
7a2613 ¤   ¤   ¤   ¤   }
47a745 ¤   ¤   ¤   ¤   else if (psks->uTotalShares-psks->pshsCurrent->uShares+u >·
18d0aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAX_TOTAL_SHARES) {
51fa61 ¤   ¤   ¤   ¤   ¤   u = MAX_TOTAL_SHARES - (psks->uTotalShares -·
6ec753 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psks->pshsCurrent->uShares);
b9e305 ¤   ¤   ¤   ¤   ¤   MessageBeep (MB_ICONASTERISK);
3a2613 ¤   ¤   ¤   ¤   }
dbaf5a
73e89a ¤   ¤   ¤   ¤   SetDlgItemInt (hDlg, IDC_SHARES, u, FALSE);
65f622 ¤   ¤   ¤   ¤   break;
dba3a6 ¤   ¤   ¤   }
00cdcb ¤   ¤   ¤   break;
110fe4 ¤   ¤   }
e4836c ¤   ¤   return TRUE;
059371 ¤   }
05a230 ¤   return FALSE;
caefe6 }
08af5a
62af5a
719268 //¤ _______________________________________________
eb465d //
c74a57 // ·Split selected key
83af5a
7a5898 BOOL KMSplitKey (PKEYMAN pKM, PGPKeyRef key)·
d1bb36 {
860bf4 ¤   PSPLITKEYSTRUCT¤¤   ¤   psks;
6eb691 ¤   BOOL¤   ¤   ¤   ¤   ¤   bOK;
6d0372 ¤   PGPKeyID¤   ¤   ¤   ¤   keyidToSplit;
371f5e ¤   PGPPublicKeyAlgorithm¤  keyalgToSplit;
b1124a ¤   HWND¤   ¤   ¤   ¤   ¤   hwnd;
5aaf5a
7b9a10 ¤   // find existing dialog struct for this key
9831d5 ¤   PGPGetKeyIDFromKey (key, &keyidToSplit);
b9fbeb ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID, &keyalgToSplit);
34dbe6 ¤   psks = pKM->pSplitKeyDialogList;
cebfe6 ¤   while (psks) {
e829e3 ¤   ¤   if (PGPCompareKeyIDs (&keyidToSplit, &(psks->keyidToSplit)) == 0) {
489490 ¤   ¤   ¤   if (keyalgToSplit == psks->keyalgToSplit)·
08f622 ¤   ¤   ¤   ¤   break;
800fe4 ¤   ¤   }
9a2dc5 ¤   ¤   psks = psks->next;
ff9371 ¤   }
96af5a
b99a1c ¤   // if dialog already exists, move to foreground
874aaa ¤   if (psks) {
950f8d ¤   ¤   SetForegroundWindow (psks->hwndDlg);
55e7c8 ¤   ¤   bOK = TRUE;
--e9f5 001a7ffb5b2401102b4 Page 19 of KMShare.c
a19371 ¤   }
93af5a
121231 ¤   // otherwise create new dialog
da665a ¤   else {
2fa79e ¤   ¤   psks = KMAlloc (sizeof (SPLITKEYSTRUCT));
21ddd9 ¤   ¤   if (psks) {
5827b0 ¤   ¤   ¤   // initialize struct
b7b911 ¤   ¤   ¤   psks->pKM = pKM;
083696 ¤   ¤   ¤   psks->pHeadOfList = &(pKM->pSplitKeyDialogList);
e08f52 ¤   ¤   ¤   PGPGetKeyIDFromKey (key, &(psks->keyidToSplit));
4f3fe9 ¤   ¤   ¤   psks->keyalgToSplit = keyalgToSplit;
bb630c ¤   ¤   ¤   KMGetKeyName (key, psks->szUserIDToSplit, kPGPMaxUserIDSize);
deba1b ¤   ¤   ¤   psks->uTotalShares = 0;
34f845 ¤   ¤   ¤   psks->uThreshold = 2;
e67b00 ¤   ¤   ¤   psks->iIndexCurrent = -1;
37c48f ¤   ¤   ¤   psks->pshsCurrent = NULL;
0af129 ¤   ¤   ¤   psks->pDropTarget = NULL;·
46af5a
acd0f5 ¤   ¤   ¤   // create modeless dialog
e584af ¤   ¤   ¤   hwnd = CreateDialogParam (g_hInst,·
f0ded9 ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDD_SPLITKEY),
3bee16 ¤   ¤   ¤   ¤   ¤   NULL, sSplitKeyDlgProc, (LPARAM)psks);
a9af5a
87affe ¤   ¤   ¤   // make it "floating"
815b5b ¤   ¤   ¤   SetWindowPos (hwnd, HWND_TOPMOST,·
2bb3d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
00af5a
477670 ¤   ¤   ¤   // add dialog struct to list
99a513 ¤   ¤   ¤   psks->next = pKM->pSplitKeyDialogList;
70e012 ¤   ¤   ¤   pKM->pSplitKeyDialogList = psks;
5f9d3c ¤   ¤   ¤   bOK = TRUE;
f90fe4 ¤   ¤   }
3bee26 ¤   ¤   else·
3cca31 ¤   ¤   ¤   bOK = FALSE;
8d9371 ¤   }
6faf5a
d8b3b9 ¤   return bOK;
63efe6 }
7aaf5a
1aaf5a
609268 //¤ _______________________________________________
21465d //
36f291 // ·Do any split key dialogs exist?
4daf5a
cbf803 BOOL KMExistSplitKeyDialog (PKEYMAN pKM)·
b5bb36 {
1244a1 ¤   if (pKM->pSplitKeyDialogList)
7b836c ¤   ¤   return TRUE;
330e24 ¤   else
4198aa ¤   ¤   return FALSE;
a7efe6 }
--3884 0004a184dce401102b5 Page 1 of KMTree.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
84f909 ¤   KMTree.c - handle creating and filling TreeList control
3d67c5 ¤
51af5a
7d0fb0 ¤   $Id: KMTree.c,v 1.31 1998/08/11 14:43:40 pbj Exp $
07f7f7 ____________________________________________________________________________*/
9fe610 #include "pgpPFLConfig.h"
97af5a
c1c917 // project header files
75850a #include "pgpkmx.h"
ffaf5a
ad13d7 // constant defitions
baffd5 #define BITMAP_WIDTH 16
6ac2a0 #define BITMAP_HEIGHT 16
72af5a
48f0f7 typedef struct {
aaf3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
8044cd ¤   HWND¤   ¤   ¤   hWndTree;
7f9b35 } EXPANDCOLLAPSESTRUCT;
1caf5a
d0f0f7 typedef struct {
67f3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
fb44cd ¤   HWND¤   ¤   ¤   hWndTree;
36a68f ¤   PGPKeySetRef¤   keysetSelected;
84ffa9 } SELECTEDSTRUCT;
99af5a
f7f4db typedef struct _USERVALSTRUCT {
91de5f ¤   struct _USERVALSTRUCT* next;
547e47 ¤   PKEYMAN¤¤   ¤   pKM;
32fb48 ¤   LONG¤   ¤   ¤   lValue;
73d08b } USERVALSTRUCT;
a0af5a
dd93ed // external globals
5a9cad extern HINSTANCE g_hInst;
a4af5a
ba9268 //¤ _______________________________________________
11465d //
4c1aba // ·get key user value list item
44af5a
578de9 PGPError·
458f7a KMGetKeyUserVal (PKEYMAN pKM, PGPKeyRef Key, LONG* lValue)·
26bb36 {
1615ab ¤   USERVALSTRUCT* puvs;
330040 ¤   PGPError err;
afaf5a
f3bc3f ¤   err = PGPGetKeyUserVal (Key, &puvs);
2a1454 ¤   if (err) return err;
66af5a
c03bb1 ¤   // there is an existing linked list
ef6508 ¤   if (puvs) {
a0b61d ¤   ¤   // search for the element inserted by this KM
794392 ¤   ¤   do {
d02bb1 ¤   ¤   ¤   if (puvs->pKM == pKM) {
c4034b ¤   ¤   ¤   ¤   *lValue = puvs->lValue;
0bf6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
75a3a6 ¤   ¤   ¤   }
863180 ¤   ¤   ¤   puvs = puvs->next;
4e513f ¤   ¤   } while (puvs);
8aaf5a
43d3a1 ¤   ¤   // no element in list inserted by this KM
9b4f3f ¤   ¤   *lValue = 0;
289371 ¤   }
06af5a
7e72d5 ¤   // no user value
324264 ¤   else·
b44f3f ¤   ¤   *lValue = 0;
7aaf5a
3f151e ¤   return kPGPError_NoErr;
4aefe6 }
--78a0 0009b7d766a401102b5 Page 2 of KMTree.c
e0af5a
1aaf5a
039268 //¤ _______________________________________________
e9465d //
92470e // ·get userid user value list item
27af5a
7b8de9 PGPError·
34df83 KMGetUserIDUserVal (PKEYMAN pKM, PGPUserIDRef UID, LONG* lValue)·
23bb36 {
b015ab ¤   USERVALSTRUCT* puvs;
0f0040 ¤   PGPError err;
f1af5a
eea996 ¤   err = PGPGetUserIDUserVal (UID, &puvs);
1f1454 ¤   if (err) return err;
46af5a
053bb1 ¤   // there is an existing linked list
f96508 ¤   if (puvs) {
1ab61d ¤   ¤   // search for the element inserted by this KM
364392 ¤   ¤   do {
d02bb1 ¤   ¤   ¤   if (puvs->pKM == pKM) {
c4034b ¤   ¤   ¤   ¤   *lValue = puvs->lValue;
e0f6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
d6a3a6 ¤   ¤   ¤   }
4c3180 ¤   ¤   ¤   puvs = puvs->next;
a6513f ¤   ¤   } while (puvs);
89af5a
abd3a1 ¤   ¤   // no element in list inserted by this KM
874f3f ¤   ¤   *lValue = 0;
8c9371 ¤   }
aeaf5a
4372d5 ¤   // no user value
af4264 ¤   else·
c24f3f ¤   ¤   *lValue = 0;
0aaf5a
44151e ¤   return kPGPError_NoErr;
a2efe6 }
dfaf5a
2daf5a
6c9268 //¤ _______________________________________________
59465d //
a96726 // ·get cert user value list item
98af5a
458de9 PGPError·
78d17b KMGetCertUserVal (PKEYMAN pKM, PGPSigRef Cert, LONG* lValue)·
89bb36 {
8515ab ¤   USERVALSTRUCT* puvs;
e60040 ¤   PGPError err;
5faf5a
794e6e ¤   err = PGPGetSigUserVal (Cert, &puvs);
421454 ¤   if (err) return err;
2daf5a
e73bb1 ¤   // there is an existing linked list
df6508 ¤   if (puvs) {
41b61d ¤   ¤   // search for the element inserted by this KM
664392 ¤   ¤   do {
d82bb1 ¤   ¤   ¤   if (puvs->pKM == pKM) {
19034b ¤   ¤   ¤   ¤   *lValue = puvs->lValue;
02f6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
f1a3a6 ¤   ¤   ¤   }
bb3180 ¤   ¤   ¤   puvs = puvs->next;
0b513f ¤   ¤   } while (puvs);
f7af5a
7cd3a1 ¤   ¤   // no element in list inserted by this KM
ea4f3f ¤   ¤   *lValue = 0;
f29371 ¤   }
69af5a
7b72d5 ¤   // no user value
8c4264 ¤   else·
034f3f ¤   ¤   *lValue = 0;
ebaf5a
d8151e ¤   return kPGPError_NoErr;
9befe6 }
--d61e 000b4092489401102b5 Page 3 of KMTree.c
e0af5a
1aaf5a
039268 //¤ _______________________________________________
e9465d //
d10da2 // ·set key user value list item
5daf5a
b68de9 PGPError·
344039 KMSetKeyUserVal (PKEYMAN pKM, PGPKeyRef Key, LONG lValue)·
3ebb36 {
b515ab ¤   USERVALSTRUCT* puvs;
7767a5 ¤   USERVALSTRUCT* puvsPrev;
1a0040 ¤   PGPError err;
3faf5a
e9bc3f ¤   err = PGPGetKeyUserVal (Key, &puvs);
921454 ¤   if (err) return err;
0caf5a
7e3bb1 ¤   // there is an existing linked list
c16508 ¤   if (puvs) {
3caac4 ¤   ¤   puvsPrev = NULL;
04b61d ¤   ¤   // search for the element inserted by this KM
144392 ¤   ¤   do {
092bb1 ¤   ¤   ¤   if (puvs->pKM == pKM) {
a859e3 ¤   ¤   ¤   ¤   // if value is zero, remove item from list
266d84 ¤   ¤   ¤   ¤   if (!lValue) {
7808af ¤   ¤   ¤   ¤   ¤   if (!puvsPrev)·
8ae223 ¤   ¤   ¤   ¤   ¤   ¤   PGPSetKeyUserVal (Key, puvs->next);
394bd6 ¤   ¤   ¤   ¤   ¤   else
f7cd42 ¤   ¤   ¤   ¤   ¤   ¤   puvsPrev->next = puvs->next;
8b5f06 ¤   ¤   ¤   ¤   ¤   KMFree (puvs);
602613 ¤   ¤   ¤   ¤   }
a54699 ¤   ¤   ¤   ¤   // otherwise set the list element to the desired value
5e5109 ¤   ¤   ¤   ¤   else·
4015de ¤   ¤   ¤   ¤   ¤   puvs->lValue = lValue;
97f6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
0da3a6 ¤   ¤   ¤   }
af5c4f ¤   ¤   ¤   puvsPrev = puvs;
fd3180 ¤   ¤   ¤   puvs = puvs->next;
ec513f ¤   ¤   } while (puvs);
fcaf5a
4225cc ¤   ¤   // no element in list inserted by this KM, create and append one
b8e592 ¤   ¤   if (!lValue) return kPGPError_NoErr;
aff462 ¤   ¤   puvs = KMAlloc (sizeof(USERVALSTRUCT));
7f07a6 ¤   ¤   puvsPrev->next = puvs;
849371 ¤   }
058a3e ¤   // no user value, create one
a1665a ¤   else {
39e592 ¤   ¤   if (!lValue) return kPGPError_NoErr;
9ef462 ¤   ¤   puvs = KMAlloc (sizeof(USERVALSTRUCT));
cf18ab ¤   ¤   PGPSetKeyUserVal (Key, puvs);
699371 ¤   }
36af5a
4598e6 ¤   // set contents of linked list element
6b93cb ¤   puvs->pKM = pKM;
c1d439 ¤   puvs->next = NULL;
8ac236 ¤   puvs->lValue = lValue;
63af5a
19151e ¤   return kPGPError_NoErr;
86efe6 }
e5af5a
63af5a
c59268 //¤ _______________________________________________
85465d //
07dcc0 // ·set userid user value list item
f0af5a
d78de9 PGPError·
d912ce KMSetUserIDUserVal (PKEYMAN pKM, PGPUserIDRef UID, LONG lValue)·
0fbb36 {
f815ab ¤   USERVALSTRUCT* puvs;
fd67a5 ¤   USERVALSTRUCT* puvsPrev;
6d0040 ¤   PGPError err;
eeaf5a
b4a996 ¤   err = PGPGetUserIDUserVal (UID, &puvs);
--5815 000c379b784401102b5 Page 4 of KMTree.c
a81454 ¤   if (err) return err;
e7af5a
973bb1 ¤   // there is an existing linked list
a86508 ¤   if (puvs) {
f2aac4 ¤   ¤   puvsPrev = NULL;
19b61d ¤   ¤   // search for the element inserted by this KM
fd4392 ¤   ¤   do {
662bb1 ¤   ¤   ¤   if (puvs->pKM == pKM) {
0659e3 ¤   ¤   ¤   ¤   // if value is zero, remove item from list
ac6d84 ¤   ¤   ¤   ¤   if (!lValue) {
b808af ¤   ¤   ¤   ¤   ¤   if (!puvsPrev)·
72e2d1 ¤   ¤   ¤   ¤   ¤   ¤   PGPSetUserIDUserVal (UID, puvs->next);
074bd6 ¤   ¤   ¤   ¤   ¤   else
82cd42 ¤   ¤   ¤   ¤   ¤   ¤   puvsPrev->next = puvs->next;
ee5f06 ¤   ¤   ¤   ¤   ¤   KMFree (puvs);
dc2613 ¤   ¤   ¤   ¤   }
e64699 ¤   ¤   ¤   ¤   // otherwise set the list element to the desired value
3a5109 ¤   ¤   ¤   ¤   else·
ec15de ¤   ¤   ¤   ¤   ¤   puvs->lValue = lValue;
e5f6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
42a3a6 ¤   ¤   ¤   }
995c4f ¤   ¤   ¤   puvsPrev = puvs;
253180 ¤   ¤   ¤   puvs = puvs->next;
aa513f ¤   ¤   } while (puvs);
2aaf5a
bf25cc ¤   ¤   // no element in list inserted by this KM, create and append one
f0e592 ¤   ¤   if (!lValue) return kPGPError_NoErr;
b1f462 ¤   ¤   puvs = KMAlloc (sizeof(USERVALSTRUCT));
2707a6 ¤   ¤   puvsPrev->next = puvs;
8e9371 ¤   }
bd8a3e ¤   // no user value, create one
96665a ¤   else {
bde592 ¤   ¤   if (!lValue) return kPGPError_NoErr;
3bf462 ¤   ¤   puvs = KMAlloc (sizeof(USERVALSTRUCT));
f97b63 ¤   ¤   PGPSetUserIDUserVal (UID, puvs);
899371 ¤   }
6faf5a
3798e6 ¤   // set contents of linked list element
b793cb ¤   puvs->pKM = pKM;
b0d439 ¤   puvs->next = NULL;
ebc236 ¤   puvs->lValue = lValue;
c0af5a
aa151e ¤   return kPGPError_NoErr;
f9efe6 }
deaf5a
3aaf5a
f29268 //¤ _______________________________________________
4e465d //
a3fbf8 // ·set cert user value list item
6faf5a
758de9 PGPError·
badae2 KMSetCertUserVal (PKEYMAN pKM, PGPSigRef Cert, LONG lValue)·
bbbb36 {
0715ab ¤   USERVALSTRUCT* puvs;
c167a5 ¤   USERVALSTRUCT* puvsPrev;
200040 ¤   PGPError err;
c2af5a
8a4e6e ¤   err = PGPGetSigUserVal (Cert, &puvs);
321454 ¤   if (err) return err;
6eaf5a
e03bb1 ¤   // there is an existing linked list
9e6508 ¤   if (puvs) {
ceaac4 ¤   ¤   puvsPrev = NULL;
98b61d ¤   ¤   // search for the element inserted by this KM
8b4392 ¤   ¤   do {
912bb1 ¤   ¤   ¤   if (puvs->pKM == pKM) {
1f59e3 ¤   ¤   ¤   ¤   // if value is zero, remove item from list
856d84 ¤   ¤   ¤   ¤   if (!lValue) {
af08af ¤   ¤   ¤   ¤   ¤   if (!puvsPrev)·
acba0a ¤   ¤   ¤   ¤   ¤   ¤   PGPSetSigUserVal (Cert, puvs->next);
114bd6 ¤   ¤   ¤   ¤   ¤   else
c3cd42 ¤   ¤   ¤   ¤   ¤   ¤   puvsPrev->next = puvs->next;
--113e 000a1526c56401102b5 Page 5 of KMTree.c
5a5f06 ¤   ¤   ¤   ¤   ¤   KMFree (puvs);
2d2613 ¤   ¤   ¤   ¤   }
514699 ¤   ¤   ¤   ¤   // otherwise set the list element to the desired value
745109 ¤   ¤   ¤   ¤   else·
bf15de ¤   ¤   ¤   ¤   ¤   puvs->lValue = lValue;
def6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
cba3a6 ¤   ¤   ¤   }
095c4f ¤   ¤   ¤   puvsPrev = puvs;
713180 ¤   ¤   ¤   puvs = puvs->next;
39513f ¤   ¤   } while (puvs);
91af5a
5f25cc ¤   ¤   // no element in list inserted by this KM, create and append one
f9e592 ¤   ¤   if (!lValue) return kPGPError_NoErr;
1af462 ¤   ¤   puvs = KMAlloc (sizeof(USERVALSTRUCT));
3107a6 ¤   ¤   puvsPrev->next = puvs;
bc9371 ¤   }
258a3e ¤   // no user value, create one
08665a ¤   else {
82e592 ¤   ¤   if (!lValue) return kPGPError_NoErr;
72f462 ¤   ¤   puvs = KMAlloc (sizeof(USERVALSTRUCT));
e456d3 ¤   ¤   PGPSetSigUserVal (Cert, puvs);
589371 ¤   }
87af5a
c998e6 ¤   // set contents of linked list element
2993cb ¤   puvs->pKM = pKM;
d8d439 ¤   puvs->next = NULL;
31c236 ¤   puvs->lValue = lValue;
62af5a
06151e ¤   return kPGPError_NoErr;
9eefe6 }
74af5a
2baf5a
789268 //¤ _______________________________________________
e8465d //
476ad9 // ·Create TreeList Window
66af5a
1b3bad HKEYMAN PGPkmExport·
4e26f1 PGPkmCreateKeyManager (
3f19cc ¤   ¤   PGPContextRef¤  ¤   Context,·
7fa960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
9b17bb ¤   ¤   HWND¤   ¤   ¤   ¤   hWndParent,
fdab8b ¤   ¤   INT¤¤   ¤   ¤   ¤   iID,·
10d425 ¤   ¤   HWNDLISTPROC¤   ¤   lpfnHwndListFunc,
2e0a9f ¤   ¤   INT¤¤   ¤   ¤   ¤   x,·
9afb12 ¤   ¤   INT¤¤   ¤   ¤   ¤   y,
a90a42 ¤   ¤   INT¤¤   ¤   ¤   ¤   nWidth,·
6edfa0 ¤   ¤   INT¤¤   ¤   ¤   ¤   nHeight)·
fdbb36 {
b1af5a
ebc482 ¤   HBITMAP¤¤   ¤   ¤   ¤   hBmp; ·····// handle to a bitmap
655e04 ¤   PKEYMAN¤¤   ¤   ¤   ¤   pKM;
4c56dc ¤   HDC¤¤   ¤   ¤   ¤   ¤   hDC;
49adf5 ¤   INT¤¤   ¤   ¤   ¤   ¤   iNumBits;
9faf5a
d5bed8 ¤   pKM = KMAlloc (sizeof (KEYMAN));
c1abb5 ¤   if (!pKM) return NULL;
202822 ¤   memset (pKM, 0x00, sizeof (KEYMAN));
85af5a
6c5053 ¤   pKM->hWndParent = hWndParent;
c5c844 ¤   pKM->hWndTree = NULL;
68fe8a ¤   pKM->lpfnHwndListFunc = lpfnHwndListFunc;
3baf5a
3c2717 ¤   pKM->iID = iID;
a831f3 ¤   pKM->hRequestMutex = CreateMutex (NULL, FALSE, NULL);
fdd860 ¤   pKM->hAccessMutex = CreateMutex (NULL, TRUE, NULL);
2c1d64 ¤   pKM->hIml = NULL;
8117c1 ¤   pKM->pDropTarget = NULL;¤   ¤   ¤   //pointer to DropTarget object
a4a4e9 ¤   lstrcpy (pKM->szHelpFile, "");¤ ¤   //string containing name of help file
b13d5f ¤   ZeroMemory (&pKM->keyserver, sizeof(PGPKeyServerEntry));¤
67af5a
18e767 ¤   pKM->Context = Context;¤¤   ¤   //PGP context
a1931a ¤   pKM->tlsContext = tlsContext;¤  //TLS context
--d3dd 0008eaab370401102b5 Page 6 of KMTree.c
e7855d ¤   pKM->KeySetDisp = NULL;¤¤   ¤   //displayed keyset
c5a9ce ¤   pKM->KeySetMain = NULL;¤¤   ¤   //main keyset
c66a5d ¤   pKM->bMainKeySet = FALSE;
7206ac ¤   pKM->ulOptionFlags = 0;
939868 ¤   pKM->ulDisableActions = 0;
5d32b8 ¤   pKM->ulHideColumns = 0;
eba62f ¤   pKM->ulShowColumns = 0;
15af5a
42cc86 ¤   pKM->bMultipleSelected = FALSE;
b8a2d5 ¤   pKM->uSelectedFlags = 0;
6dcbe1 ¤   pKM->iFocusedItemType = 0;
a351aa ¤   pKM->iFocusedObjectType = 0;
93dbe0 ¤   pKM->hFocusedItem = NULL;
47652f ¤   pKM->pFocusedObject = NULL;
e3af5a
38b95c ¤   pKM->iValidityThreshold = KM_VALIDITY_MARGINAL;
4faf5a
13b9c5 ¤   pKM->iNumberSheets = 0;
de5227 ¤   pKM->pSplitKeyDialogList = NULL;
01af5a
557607 ¤   KMGetColumnPreferences (pKM);
0eaf5a
5ac89f ¤   // Create the tree view window.
a5f33b ¤   pKM->hWndTree = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREELIST, "",
3263f8 ¤   ¤   ¤   WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_GROUP |
ab5a91 ¤   ¤   ¤   TLS_HASBUTTONS | TLS_HASLINES | TLS_AUTOSCROLL |·
aa65bc ¤   ¤   ¤   TLS_PROMISCUOUS | TLS_DRAGABLEHEADERS,
1d2d4c ¤   ¤   ¤   x, y, nWidth, nHeight,
df811b ¤   ¤   ¤   hWndParent, (HMENU)iID, g_hInst, NULL);
7eaf5a
75a794 ¤   if (pKM->hWndTree == NULL) return NULL;
09af5a
d9acf4 ¤   // Initialize the tree view window.
95642e ¤   // First create imagelist and load the appropriate bitmaps·
e00078 ¤   // based on current display capabilities.
a967c5 ¤
787f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
6e89fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
46e693 ¤   ReleaseDC (NULL, hDC);
ceaf5a
582be4 ¤   if (iNumBits <= 8) {
5b43bf ¤   ¤   pKM->hIml =¤ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
3f6d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
9e9694 ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
39fefa ¤   ¤   ImageList_AddMasked (pKM->hIml, hBmp, RGB(255, 0, 255));
0c5c8d ¤   ¤   DeleteObject (hBmp);
e69371 ¤   }
87665a ¤   else {
256e5b ¤   ¤   pKM->hIml =¤ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
b96d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
18bb8b ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
42fefa ¤   ¤   ImageList_AddMasked (pKM->hIml, hBmp, RGB(255, 0, 255));
525c8d ¤   ¤   DeleteObject (hBmp);
bf9371 ¤   }
e6af5a
8b4110 ¤   // Associate the image list with the tree view control.
ab68ab ¤   TreeList_SetImageList (pKM->hWndTree, pKM->hIml);
c2af5a
c29033 ¤   KMSetFocus (pKM, NULL, FALSE);
bee95b ¤   pKM->pDropTarget = KMCreateDropTarget (pKM->hWndTree, (VOID*)pKM, FALSE);·
bb5646 ¤   CoLockObjectExternal ((IUnknown*)pKM->pDropTarget, TRUE, TRUE);
5f74dc ¤   RegisterDragDrop (pKM->hWndTree, pKM->pDropTarget);
494149 ¤   KMEnableDropTarget (pKM->pDropTarget, FALSE);
5caf5a
ea3c28 ·¤  return (HKEYMAN)pKM;
49efe6 }
56af5a
e3af5a
fe9268 //¤ _______________________________________________
63465d //
143833 // ·Insert column information into control
8eaf5a
--9932 000179886e5401102b5 Page 7 of KMTree.c
697efe BOOL·
b33c39 KMAddColumns (PKEYMAN pKM)·
43bb36 {
287894 ¤   TL_COLUMN tlc;
81f61c ¤   CHAR sz[64];
8aa3bc ¤   INT iField, iCol, ids;
beaf5a
7f91cd ¤   TreeList_DeleteAllColumns (pKM->hWndTree);
83af5a
e643d5 ¤   tlc.mask = TLCF_FMT | TLCF_WIDTH | TLCF_TEXT |·
8ad085 ¤   ¤   ¤   ¤   TLCF_SUBITEM | TLCF_DATATYPE | TLCF_DATAMAX |
3ce832 ¤   ¤   ¤   ¤   TLCF_MOUSENOTIFY;
6bdef6 ¤   tlc.pszText = sz;
91af5a
9cfee9 ¤   tlc.iSubItem = 0;
10b741 ¤   tlc.fmt = TLCFMT_LEFT;
8a737a ¤   tlc.iDataType = TLC_DATASTRING;
fdcc6b ¤   tlc.cx = pKM->wFieldWidth[0];
9f8305 ¤   tlc.bMouseNotify = FALSE;
9a3468 ¤   LoadString (g_hInst, IDS_NAMEFIELD, sz, sizeof(sz));
c0636d ¤   TreeList_InsertColumn (pKM->hWndTree, 0, &tlc);
f1af5a
5ff252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
e48ff9 ¤   ¤   iField = pKM->wColumnField[iCol];
8553ba ¤   ¤   if (iField) {
c37f03 ¤   ¤   ¤   switch (iField) {
d0823e ¤   ¤   ¤   case KMI_VALIDITY :
c89e63 ¤   ¤   ¤   ¤   ids = IDS_VALIDITYFIELD;
9e074f ¤   ¤   ¤   ¤   if (pKM->ulOptionFlags & KMF_NOVICEMODE)·
15af03 ¤   ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_IMAGE;
4b5109 ¤   ¤   ¤   ¤   else·
e93a61 ¤   ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LINBAR;
e1349c ¤   ¤   ¤   ¤   tlc.cchTextMax =·
733ff6 ¤   ¤   ¤   ¤   ¤   ¤   KMConvertFromPGPValidity (kPGPValidity_Complete);
3d90bf ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATALONG;
237614 ¤   ¤   ¤   ¤   tlc.bMouseNotify = TRUE;
5ef622 ¤   ¤   ¤   ¤   break;
14af5a
c3b4e0 ¤   ¤   ¤   case KMI_SIZE :
6aaf4c ¤   ¤   ¤   ¤   ids = IDS_SIZEFIELD;
ed6ee5 ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LEFT;
b02619 ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATASTRING;
366790 ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
6af622 ¤   ¤   ¤   ¤   break;
30af5a
c98ec6 ¤   ¤   ¤   case KMI_DESCRIPTION :
fc0d85 ¤   ¤   ¤   ¤   ids = IDS_DESCRIPTIONFIELD;
5c6ee5 ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LEFT;
b32619 ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATASTRING;
366790 ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
a7f622 ¤   ¤   ¤   ¤   break;
bfaf5a
ef5fb6 ¤   ¤   ¤   case KMI_KEYID :
981ca6 ¤   ¤   ¤   ¤   ids = IDS_KEYIDFIELD;
166ee5 ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LEFT;
bf2619 ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATASTRING;
516790 ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
e7f622 ¤   ¤   ¤   ¤   break;
252b85 ¤   ¤   ¤   ¤
64cd10 ¤   ¤   ¤   case KMI_TRUST :
8cc9c0 ¤   ¤   ¤   ¤   ids = IDS_TRUSTFIELD;
563cd9 ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LINBAR;
59349c ¤   ¤   ¤   ¤   tlc.cchTextMax =·
f6404b ¤   ¤   ¤   ¤   ¤   ¤   KMConvertFromPGPTrust (kPGPKeyTrust_Complete);
3790bf ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATALONG;
0a6790 ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
58f622 ¤   ¤   ¤   ¤   break;
47af5a
6a93ea ¤   ¤   ¤   case KMI_CREATION :
13cbbe ¤   ¤   ¤   ¤   ids = IDS_CREATIONFIELD;
1d6ee5 ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LEFT;
172619 ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATASTRING;
--1340 0004f05644e401102b5 Page 8 of KMTree.c
086790 ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
e1f622 ¤   ¤   ¤   ¤   break;
142b85 ¤   ¤   ¤   ¤
c395fc ¤   ¤   ¤   case KMI_EXPIRATION :
16ce04 ¤   ¤   ¤   ¤   ids = IDS_EXPIRATIONFIELD;
b26ee5 ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LEFT;
c22619 ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATASTRING;
9d6790 ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
40f622 ¤   ¤   ¤   ¤   break;
e52b85 ¤   ¤   ¤   ¤
54efb1 ¤   ¤   ¤   case KMI_ADK :
2cc579 ¤   ¤   ¤   ¤   ids = IDS_ADKFIELD;
e42765 ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_IMAGE;
6c90bf ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATALONG;
d16790 ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
b8f622 ¤   ¤   ¤   ¤   break;
52a3a6 ¤   ¤   ¤   }
6b9d98 ¤   ¤   ¤   LoadString (g_hInst, ids, sz, sizeof(sz));
7541b9 ¤   ¤   ¤   tlc.cx = pKM->wFieldWidth[iField];
88db9a ¤   ¤   ¤   TreeList_InsertColumn (pKM->hWndTree, iCol, &tlc);
e80fe4 ¤   ¤   }
ad9371 ¤   }
83af5a
87c2e7 ¤   return TRUE;
a3efe6 }
d6af5a
18af5a
e79268 //¤ _______________________________________________
e8465d //
854735 // ·Set (or add) a tree item to the tree
74af5a
68d7b4 static HTLITEM·
3d8de7 sSetOneItem (
a645dc ¤   ¤   PKEYMAN¤¤   pKM,·
dae4b3 ¤   ¤   BOOL¤   ¤   bReInsertExisting,·
0d5390 ¤   ¤   HTLITEM¤¤   hItem,·
85ef10 ¤   ¤   HTLITEM¤¤   hParent,·
d0f042 ¤   ¤   LPSTR¤  ¤   szText,·
3844e3 ¤   ¤   HTLITEM¤¤   hInsAfter,·
e6c810 ¤   ¤   INT¤¤   ¤   iImage,·
3aeec8 ¤   ¤   UINT¤   ¤   uState,·
cfcf0a ¤   ¤   LPARAM¤ ¤   lParam)·
98bb36 {
d8e418 ¤   TL_TREEITEM tlI;
11e1c1 ¤   TL_INSERTSTRUCT tlIns;
41af5a
ac8cff ¤   tlI.hItem = hItem;
ee90ac ¤   tlI.mask = TLIF_TEXT | TLIF_IMAGE | TLIF_STATE | TLIF_PARAM;
0ca75b ¤   tlI.stateMask = TLIS_BOLD | TLIS_ITALICS;
e2ab60 ¤   tlI.stateMask |= uState;
568d61 ¤   tlI.state = uState;
ac3ca6 ¤   tlI.pszText = szText;
6e5a98 ¤   tlI.cchTextMax = lstrlen (szText);
a188f8 ¤   tlI.iImage = iImage;
67f485 ¤   tlI.iSelectedImage = iImage;
64ea06 ¤   tlI.lParam = lParam;
01af5a
0d5989 ¤   // Insert the data into the tree.
76b541 ¤   if (bReInsertExisting || !hItem) {
d470a5 ¤   ¤   tlIns.item = tlI;
718837 ¤   ¤   tlIns.hInsertAfter = hInsAfter;
dc05ae ¤   ¤   tlIns.hParent = hParent;
d29b31 ¤   ¤   return (TreeList_InsertItem (pKM->hWndTree, &tlIns));
669371 ¤   }
52665a ¤   else {
7f98e2 ¤   ¤   TreeList_SetItem (pKM->hWndTree, &tlI);
491030 ¤   ¤   return hItem;
679371 ¤   }
35efe6 }
a6af5a
59af5a
4f9268 //¤ _______________________________________________
--b9e3 00067a6d9d5401102b5 Page 9 of KMTree.c
c1465d //
01d853 // ·Construct string representation of number of key bits
27af5a
a6a1ba VOID·
b018a8 KMGetKeyBitsString (
139bc2 ¤   ¤   PGPKeySetRef¤   KeySet,·
1d03ef ¤   ¤   PGPKeyRef¤  ¤   Key,·
115d18 ¤   ¤   LPSTR¤  ¤   ¤   sz,·
0df5db ¤   ¤   UINT¤   ¤   ¤   u)·
c9bb36 {
6ad501 ¤   UINT uAlg;
d652d5 ¤   UINT uKeyBits, uSubKeyBits;
b50585 ¤   PGPSubKeyRef SubKey;
93d34e ¤   PGPKeyListRef KeyList;
074276 ¤   PGPKeyIterRef KeyIter;
820040 ¤   PGPError err;
1bf21d ¤   CHAR szbuf[32];
9aaf5a
c7c5d2 ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, &uAlg);
f9fadc ¤   switch (uAlg) {
8c2692 ¤   case kPGPPublicKeyAlgorithm_RSA :
d1bad3 ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropBits, &uKeyBits);
f3b7a0 ¤   ¤   wsprintf (szbuf, "%i", uKeyBits);
a222d8 ¤   ¤   lstrcpyn (sz, szbuf, u);
862f68 ¤   ¤   break;
b3af5a
2a7cd8 ¤   case kPGPPublicKeyAlgorithm_DSA :
bb771a ¤   ¤   // key key bits
f25a20 ¤   ¤   err = PGPGetKeyNumber (Key, kPGPKeyPropBits, &uKeyBits);
1ab7a0 ¤   ¤   wsprintf (szbuf, "%i", uKeyBits);
fbaf5a
14bd9a ¤   ¤   // now try to get subkey bits
ba84f0 ¤   ¤   PGPOrderKeySet (KeySet, kPGPAnyOrdering, &KeyList);
03171f ¤   ¤   PGPNewKeyIter (KeyList, &KeyIter);
134d64 ¤   ¤   PGPKeyIterSeek (KeyIter, Key);
cc5d6b ¤   ¤   PGPKeyIterNextSubKey (KeyIter, &SubKey);
606d19 ¤   ¤   if (SubKey) {
71bb93 ¤   ¤   ¤   PGPGetSubKeyNumber (SubKey, kPGPKeyPropBits, &uSubKeyBits);
bf786d ¤   ¤   ¤   wsprintf (szbuf, "%i/%i", uSubKeyBits, uKeyBits);
850fe4 ¤   ¤   }
e126dc ¤   ¤   PGPFreeKeyIter (KeyIter);
109571 ¤   ¤   PGPFreeKeyList (KeyList);
22af5a
9422d8 ¤   ¤   lstrcpyn (sz, szbuf, u);
d22f68 ¤   ¤   break;
83af5a
cebfad ¤   default :
06a3fb ¤   ¤   LoadString (g_hInst, IDS_UNKNOWN, sz, u);
eb2f68 ¤   ¤   break;
789371 ¤   }
6fefe6 }
ecaf5a
6eaf5a
a89268 //¤ _______________________________________________
36465d //
0d7bb0 // ·Set list data for a key
52af5a
f3b333 static VOID·
382076 sFillDescription (INT idx, INT iVal, LPSTR sz, INT iLen)·
d9bb36 {
43af5a
7bdfd8 ¤   INT¤¤   ids¤¤   ¤   ¤   = 0;
708e29 ¤   BOOL¤   bSig¤   ¤   ¤   = FALSE;
fa3d1b ¤   CHAR¤   szTemp[128];
2daf5a
694679 ¤   switch (idx) {
2e335d ¤   case IDX_RSAPUBKEY :¤   ids = IDS_RSAPUBKEY;¤   ¤   break;
5c01f3 ¤   case IDX_DSAPUBKEY :¤   ids = IDS_DSAPUBKEY;¤   ¤   break;
80fa1c ¤   case IDX_RSASECKEY :¤   ids = IDS_RSASECKEY;¤   ¤   break;
27c8b2 ¤   case IDX_DSASECKEY :¤   ids = IDS_DSASECKEY;¤   ¤   break;
0baf5a
6790b5 ¤   case IDX_RSAPUBDISKEY : ids = IDS_RSAPUBDISKEY;¤¤   break;
--2acc 00028779c4d401102b5 Page 10 of KMTree.c
197f9f ¤   case IDX_RSAPUBREVKEY : ids = IDS_RSAPUBREVKEY;¤¤   break;
e9f1c5 ¤   case IDX_RSAPUBEXPKEY : ids = IDS_RSAPUBEXPKEY;¤¤   break;
c0af5a
1259f4 ¤   case IDX_RSASECDISKEY : ids = IDS_RSASECDISKEY;¤¤   break;
5bb6de ¤   case IDX_RSASECREVKEY : ids = IDS_RSASECREVKEY;¤¤   break;
cb3884 ¤   case IDX_RSASECEXPKEY : ids = IDS_RSASECEXPKEY;¤¤   break;
3c3daf ¤   case IDX_RSASECSHRKEY : ids = IDS_RSASECSHRKEY;¤¤   break;
62af5a
16a21b ¤   case IDX_DSAPUBDISKEY : ids = IDS_DSAPUBDISKEY;¤¤   break;
194d31 ¤   case IDX_DSAPUBREVKEY : ids = IDS_DSAPUBREVKEY;¤¤   break;
99c36b ¤   case IDX_DSAPUBEXPKEY : ids = IDS_DSAPUBEXPKEY;¤¤   break;
daaf5a
0a6b5a ¤   case IDX_DSASECDISKEY : ids = IDS_DSASECDISKEY;¤¤   break;
108470 ¤   case IDX_DSASECREVKEY : ids = IDS_DSASECREVKEY;¤¤   break;
ed0a2a ¤   case IDX_DSASECEXPKEY : ids = IDS_DSASECEXPKEY;¤¤   break;
3b0f01 ¤   case IDX_DSASECSHRKEY : ids = IDS_DSASECSHRKEY;¤¤   break;
1aaf5a
faf48d ¤   case IDX_RSAUSERID :¤   ids = IDS_RSAUSERID;¤   ¤   break;
86c623 ¤   case IDX_DSAUSERID :¤   ids = IDS_DSAUSERID;¤   ¤   break;
c861eb ¤   case IDX_PHOTOUSERID :¤ ids = IDS_PHOTOUSERID;¤ ¤   break;
cd1340 ¤   case IDX_INVALIDUSERID:¤ids = IDS_UNKNOWNUSERID;¤   break;
4daf5a
d9d068 ¤   case IDX_CERT :¤¤
2aa404 ¤   ¤   ids = IDS_CERT;¤
b99a7a ¤   ¤   bSig = TRUE;
d52f68 ¤   ¤   break;
89af5a
d59be2 ¤   case IDX_REVCERT :¤ ¤
9127bb ¤   ¤   ids = IDS_REVCERT;¤ ¤   ¤
349a7a ¤   ¤   bSig = TRUE;
3d2f68 ¤   ¤   break;
5daf5a
3bb311 ¤   case IDX_EXPCERT :¤ ¤
23a918 ¤   ¤   ids = IDS_EXPCERT;¤ ¤   ¤
cf9a7a ¤   ¤   bSig = TRUE;
562f68 ¤   ¤   break;
65af5a
221e23 ¤   case IDX_BADCERT :¤ ¤
b08589 ¤   ¤   ids = IDS_BADCERT;¤ ¤   ¤
bf9a7a ¤   ¤   bSig = TRUE;
f92f68 ¤   ¤   break;
c1af5a
67f834 ¤   case IDX_EXPORTCERT :¤
9a2e81 ¤   ¤   ids = IDS_EXPORTCERT;¤  ¤
379a7a ¤   ¤   bSig = TRUE;
c32f68 ¤   ¤   break;
e6af5a
d14dba ¤   case IDX_TRUSTEDCERT :¤ ¤
5a8f35 ¤   ¤   ids = IDS_EXPORTMETACERT;¤
019a7a ¤   ¤   bSig = TRUE;
132f68 ¤   ¤   break;
1aaf5a
456b00 ¤   case IDX_METACERT:
9ee3b7 ¤   ¤   ids = IDS_METACERT;¤¤   ¤
6f9a7a ¤   ¤   bSig = TRUE;
5c2f68 ¤   ¤   break;
12af5a
731f5e ¤   default :¤  ¤   ¤   ¤
7076c4 ¤   ¤   ids = IDS_UNKNOWN;¤ ¤   ¤
b92f68 ¤   ¤   break;
d19371 ¤   }
7aaf5a
4ed0c1 ¤   sz[0] = '\0';
8eaf5a
81e838 ¤   if (bSig) {
85e0d0 ¤   ¤   switch (iVal) {
011a7c ¤   ¤   case kPGPPublicKeyAlgorithm_RSA :
0cf1e1 ¤   ¤   ¤   LoadString (g_hInst, IDS_RSA, sz, iLen);
efcdcb ¤   ¤   ¤   break;
f1af5a
e54036 ¤   ¤   case kPGPPublicKeyAlgorithm_DSA :
284739 ¤   ¤   ¤   LoadString (g_hInst, IDS_DSS, sz, iLen);
--8ecf 000006c0e50401102b5 Page 11 of KMTree.c
7ecdcb ¤   ¤   ¤   break;
f8af5a
803a18 ¤   ¤   default :
ba45f4 ¤   ¤   ¤   LoadString (g_hInst, IDS_UNKNOWN, sz, iLen);
6bcdcb ¤   ¤   ¤   break;
fd0fe4 ¤   ¤   }
3e0374 ¤   ¤   lstrcat (sz, " ");
5a9371 ¤   }
08af5a
ce8d18 ¤   LoadString (g_hInst, ids, szTemp, sizeof(szTemp));
12dc15 ¤   lstrcat (sz, szTemp);
a2efe6 }
04af5a
2eaf5a
369268 //¤ _______________________________________________
22465d //
f77bb0 // ·Set list data for a key
3faf5a
f8d7b4 static HTLITEM·
84a4e4 sSetKeyData (
fd45dc ¤   ¤   PKEYMAN¤¤   pKM,·
125390 ¤   ¤   HTLITEM¤¤   hItem,·
06ade8 ¤   ¤   PGPKeyRef¤  Key,·
945899 ¤   ¤   INT¤¤   ¤   idx)·
ab7142 {·
b5ab9f ¤   TL_LISTITEM tlL;
5b5c4c ¤   INT iField, iCol;
71d035 ¤   Boolean bAxiomatic;
54af5a
386877 ¤   CHAR szText [128];
f47796 ¤   INT iValue;
7ebea8 ¤   PGPTime time;
68beb0 ¤   UINT u;
93af5a
e0869b ¤   tlL.pszText = szText;
b1dccc ¤   tlL.hItem = hItem;
e8030b ¤   tlL.stateMask = TLIS_VISIBLE;
85af5a
87f252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
2e8ff9 ¤   ¤   iField = pKM->wColumnField[iCol];
2e53ba ¤   ¤   if (iField) {
4d7f03 ¤   ¤   ¤   switch (iField) {
f2823e ¤   ¤   ¤   case KMI_VALIDITY :
81922d ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDValidity (Key, &iValue);
a5cf00 ¤   ¤   ¤   ¤   iValue = KMConvertFromPGPValidity (iValue);
8aca35 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsAxiomatic, &bAxiomatic);
1e56bb ¤   ¤   ¤   ¤   if (bAxiomatic) iValue =·
687055 ¤   ¤   ¤   ¤   ¤   ¤   KMConvertFromPGPValidity (kPGPValidity_Complete)+1;
81fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
14114e ¤   ¤   ¤   ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
15f9ce ¤   ¤   ¤   ¤   if (pKM->ulOptionFlags & KMF_NOVICEMODE) {
4a8990 ¤   ¤   ¤   ¤   ¤   if (iValue > KM_VALIDITY_COMPLETE)
62590e ¤   ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_AXIOMATIC;
283dd6 ¤   ¤   ¤   ¤   ¤   else if (iValue >= pKM->iValidityThreshold)·
584faa ¤   ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_VALID;
6a4380 ¤   ¤   ¤   ¤   ¤   else tlL.lDataValue = IDX_INVALID;
432613 ¤   ¤   ¤   ¤   }
f137aa ¤   ¤   ¤   ¤   else tlL.lDataValue = iValue;
58f622 ¤   ¤   ¤   ¤   break;
54af5a
bcb4e0 ¤   ¤   ¤   case KMI_SIZE :
cafb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
b62903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
4e2ef7 ¤   ¤   ¤   ¤   KMGetKeyBitsString (pKM->KeySetDisp,·
5cc1b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   Key, szText, sizeof(szText));
58f622 ¤   ¤   ¤   ¤   break;
53af5a
fb8ec6 ¤   ¤   ¤   case KMI_DESCRIPTION :
0bfb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
ed2903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
1fba68 ¤   ¤   ¤   ¤   sFillDescription (idx, 0, szText, sizeof(szText));
00f622 ¤   ¤   ¤   ¤   break;
--7ca9 00028bd1aa9401102b5 Page 12 of KMTree.c
e0af5a
105fb6 ¤   ¤   ¤   case KMI_KEYID :
70fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
5a2903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
5fcf60 ¤   ¤   ¤   ¤   KMGetKeyIDFromKey (Key, szText, sizeof(szText));
67f622 ¤   ¤   ¤   ¤   break;
da2b85 ¤   ¤   ¤   ¤
aecd10 ¤   ¤   ¤   case KMI_TRUST :
f49a38 ¤   ¤   ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropTrust, &iValue);
f28a79 ¤   ¤   ¤   ¤   iValue = KMConvertFromPGPTrust (iValue);
beca35 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsAxiomatic, &bAxiomatic);
5765bf ¤   ¤   ¤   ¤   if (bAxiomatic)·
166cb1 ¤   ¤   ¤   ¤   ¤   iValue = KMConvertFromPGPTrust (kPGPKeyTrust_Ultimate)+1;
5bfb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
5d114e ¤   ¤   ¤   ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
9a46a5 ¤   ¤   ¤   ¤   tlL.lDataValue = iValue;
33f622 ¤   ¤   ¤   ¤   break;
feaf5a
8493ea ¤   ¤   ¤   case KMI_CREATION :
69fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
952903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
2f6fad ¤   ¤   ¤   ¤   PGPGetKeyTime (Key, kPGPKeyPropCreation, &time);
cf4440 ¤   ¤   ¤   ¤   KMConvertTimeToString (time, szText, sizeof(szText));
0bf622 ¤   ¤   ¤   ¤   break;
322b85 ¤   ¤   ¤   ¤
0695fc ¤   ¤   ¤   case KMI_EXPIRATION :
8afb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
8c2903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
48ad75 ¤   ¤   ¤   ¤   PGPGetKeyTime (Key, kPGPKeyPropExpiration, &time);
3f6924 ¤   ¤   ¤   ¤   if (time != kPGPExpirationTime_Never)·
e7f0e2 ¤   ¤   ¤   ¤   ¤   KMConvertTimeToString (time, szText, sizeof (szText));
aa5109 ¤   ¤   ¤   ¤   else·
f87183 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_NEVER, szText, sizeof (szText));
ddf622 ¤   ¤   ¤   ¤   break;
7d2b85 ¤   ¤   ¤   ¤
93efb1 ¤   ¤   ¤   case KMI_ADK :
fefb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
49114e ¤   ¤   ¤   ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
060875 ¤   ¤   ¤   ¤   PGPCountAdditionalRecipientRequests (Key, &u);
ece516 ¤   ¤   ¤   ¤   if (u > 0)·
7bda05 ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_ADK;
8bfa07 ¤   ¤   ¤   ¤   else
9d3650 ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_NOADK;
80f622 ¤   ¤   ¤   ¤   break;
8fa3a6 ¤   ¤   ¤   }
2adeb2 ¤   ¤   ¤   tlL.iSubItem = iCol;
15b28f ¤   ¤   ¤   hItem = (HTLITEM) TreeList_SetListItem (pKM->hWndTree,·
ad1e8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tlL, FALSE);
3c0fe4 ¤   ¤   }
c79371 ¤   }
d1af5a
4966c6 ¤   return (hItem);
6defe6 }
5faf5a
6daf5a
2f9268 //¤ _______________________________________________
94465d //
17d1e1 // ·Set treelist list data for a userID
ceaf5a
8ad7b4 static HTLITEM·
a68c74 sSetIDData (
ce934d ¤   ¤   PKEYMAN¤¤   ¤   pKM,·
157ac1 ¤   ¤   HTLITEM¤¤   ¤   hItem,·
9b1337 ¤   ¤   PGPUserIDRef¤   UserID,·
b99bf6 ¤   ¤   INT¤¤   ¤   ¤   idx)·
1fbb36 {
a9ab9f ¤   TL_LISTITEM tlL;
d06877 ¤   CHAR szText [128];
465c4c ¤   INT iField, iCol;
937796 ¤   INT iValue;
45af5a
28869b ¤   tlL.pszText = szText;
--657a 00077f72bc7401102b5 Page 13 of KMTree.c
cfdccc ¤   tlL.hItem = hItem;
81030b ¤   tlL.stateMask = TLIS_VISIBLE;
a6af5a
4cf252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
ce8ff9 ¤   ¤   iField = pKM->wColumnField[iCol];
5053ba ¤   ¤   if (iField) {
0f7f03 ¤   ¤   ¤   switch (iField) {
89823e ¤   ¤   ¤   case KMI_VALIDITY :
45b778 ¤   ¤   ¤   ¤   PGPGetUserIDNumber (UserID, kPGPUserIDPropValidity, &iValue);
a7cf00 ¤   ¤   ¤   ¤   iValue = KMConvertFromPGPValidity (iValue);
7efb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
d8114e ¤   ¤   ¤   ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
18f9ce ¤   ¤   ¤   ¤   if (pKM->ulOptionFlags & KMF_NOVICEMODE) {
7287f0 ¤   ¤   ¤   ¤   ¤   if (iValue >= pKM->iValidityThreshold)·
e64faa ¤   ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_VALID;
4d4380 ¤   ¤   ¤   ¤   ¤   else tlL.lDataValue = IDX_INVALID;
512613 ¤   ¤   ¤   ¤   }
7637aa ¤   ¤   ¤   ¤   else tlL.lDataValue = iValue;
eef622 ¤   ¤   ¤   ¤   break;
26af5a
36b4e0 ¤   ¤   ¤   case KMI_SIZE :
5e8794 ¤   ¤   ¤   ¤   tlL.state = 0;
966c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
e8f622 ¤   ¤   ¤   ¤   break;
d9af5a
c68ec6 ¤   ¤   ¤   case KMI_DESCRIPTION :
37fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
602903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
d7ba68 ¤   ¤   ¤   ¤   sFillDescription (idx, 0, szText, sizeof(szText));
84f622 ¤   ¤   ¤   ¤   break;
1faf5a
e15fb6 ¤   ¤   ¤   case KMI_KEYID :
ff8794 ¤   ¤   ¤   ¤   tlL.state = 0;
e66c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
aff622 ¤   ¤   ¤   ¤   break;
9c2b85 ¤   ¤   ¤   ¤
04cd10 ¤   ¤   ¤   case KMI_TRUST :
798794 ¤   ¤   ¤   ¤   tlL.state = 0;
8c6c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
97f622 ¤   ¤   ¤   ¤   break;
10af5a
7893ea ¤   ¤   ¤   case KMI_CREATION :
ae8794 ¤   ¤   ¤   ¤   tlL.state = 0;
936c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
31f622 ¤   ¤   ¤   ¤   break;
532b85 ¤   ¤   ¤   ¤
b895fc ¤   ¤   ¤   case KMI_EXPIRATION :
d08794 ¤   ¤   ¤   ¤   tlL.state = 0;
7d6c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
3df622 ¤   ¤   ¤   ¤   break;
292b85 ¤   ¤   ¤   ¤
64efb1 ¤   ¤   ¤   case KMI_ADK :
678794 ¤   ¤   ¤   ¤   tlL.state = 0;
6e6c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
c9f622 ¤   ¤   ¤   ¤   break;
d6a3a6 ¤   ¤   ¤   }
70deb2 ¤   ¤   ¤   tlL.iSubItem = iCol;
41b28f ¤   ¤   ¤   hItem = (HTLITEM) TreeList_SetListItem (pKM->hWndTree,·
3f1e8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tlL, FALSE);
d80fe4 ¤   ¤   }
c19371 ¤   }
1866c6 ¤   return (hItem);
59efe6 }
43af5a
89af5a
d69268 //¤ _______________________________________________
31465d //
7b5031 // ·Set treelist list data for a certification
c5af5a
13d7b4 static HTLITEM·
9f7d75 sSetCertData (
77aefa ¤   ¤   ¤   ·PKEYMAN¤   pKM,·
--9142 0009ffb6333401102b5 Page 14 of KMTree.c
0495c1 ¤   ¤   ¤   ·HTLITEM¤   hItem,·
c03b6b ¤   ¤   ¤   ·PGPSigRef¤ Cert,·
bdafd8 ¤   ¤   ¤   ·INT¤   ¤   idx)·
42bb36 {
ddab9f ¤   TL_LISTITEM tlL;
4e79b3 ¤   CHAR¤   ¤   szText [128];
abb6b1 ¤   INT¤¤   ¤   iField, iCol;
855c1c ¤   PGPTime¤¤   time;
9a5ba5 ¤   INT¤¤   ¤   iAlg;
dbaf5a
7d869b ¤   tlL.pszText = szText;
1ddccc ¤   tlL.hItem = hItem;
d7030b ¤   tlL.stateMask = TLIS_VISIBLE;
1daf5a
82f252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
cd8ff9 ¤   ¤   iField = pKM->wColumnField[iCol];
e053ba ¤   ¤   if (iField) {
327f03 ¤   ¤   ¤   switch (iField) {
c0823e ¤   ¤   ¤   case KMI_VALIDITY :
498794 ¤   ¤   ¤   ¤   tlL.state = 0;
2b6c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
1df622 ¤   ¤   ¤   ¤   break;
5daf5a
64b4e0 ¤   ¤   ¤   case KMI_SIZE :
2e8794 ¤   ¤   ¤   ¤   tlL.state = 0;
b36c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
ddf622 ¤   ¤   ¤   ¤   break;
ebaf5a
b18ec6 ¤   ¤   ¤   case KMI_DESCRIPTION :
29fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
222903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
5f1fd8 ¤   ¤   ¤   ¤   PGPGetSigNumber (Cert, kPGPSigPropAlgID, &iAlg);
3fe19e ¤   ¤   ¤   ¤   sFillDescription (idx, iAlg, szText, sizeof(szText));
caf622 ¤   ¤   ¤   ¤   break;
95af5a
6a5fb6 ¤   ¤   ¤   case KMI_KEYID :
44fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
f32903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
539c44 ¤   ¤   ¤   ¤   KMGetKeyIDFromCert (Cert, szText, sizeof(szText));
9bf622 ¤   ¤   ¤   ¤   break;
da2b85 ¤   ¤   ¤   ¤
7ccd10 ¤   ¤   ¤   case KMI_TRUST :
3e8794 ¤   ¤   ¤   ¤   tlL.state = 0;
256c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
a5f622 ¤   ¤   ¤   ¤   break;
edaf5a
5993ea ¤   ¤   ¤   case KMI_CREATION :
59fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
182903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
0b1cbe ¤   ¤   ¤   ¤   PGPGetSigTime (Cert, kPGPSigPropCreation, &time);
fd4440 ¤   ¤   ¤   ¤   KMConvertTimeToString (time, szText, sizeof(szText));
80f622 ¤   ¤   ¤   ¤   break;
292b85 ¤   ¤   ¤   ¤
3095fc ¤   ¤   ¤   case KMI_EXPIRATION :
68fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
bb2903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
d25390 ¤   ¤   ¤   ¤   PGPGetSigTime (Cert, kPGPSigPropExpiration, &time);
346924 ¤   ¤   ¤   ¤   if (time != kPGPExpirationTime_Never)·
9af0e2 ¤   ¤   ¤   ¤   ¤   KMConvertTimeToString (time, szText, sizeof (szText));
a15109 ¤   ¤   ¤   ¤   else·
427183 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_NEVER, szText, sizeof (szText));
5ff622 ¤   ¤   ¤   ¤   break;
072b85 ¤   ¤   ¤   ¤
d4efb1 ¤   ¤   ¤   case KMI_ADK :
b98794 ¤   ¤   ¤   ¤   tlL.state = 0;
356c14 ¤   ¤   ¤   ¤   tlL.mask = TLIF_STATE;
ecf622 ¤   ¤   ¤   ¤   break;
fda3a6 ¤   ¤   ¤   }
9fdeb2 ¤   ¤   ¤   tlL.iSubItem = iCol;
1db28f ¤   ¤   ¤   hItem = (HTLITEM) TreeList_SetListItem (pKM->hWndTree,·
001e8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tlL, FALSE);
9f0fe4 ¤   ¤   }
--2991 0004b3bb6df401102b5 Page 15 of KMTree.c
a19371 ¤   }
f966c6 ¤   return (hItem);
eeefe6 }
3eaf5a
7faf5a
ce9268 //¤ _______________________________________________
1b465d //
30d713 // ·Reload a single key
6caf5a
0ed7b4 static HTLITEM·
fd967d sReloadKey (
aa934d ¤   ¤   PKEYMAN¤¤   ¤   pKM,·
65c7b8 ¤   ¤   PGPKeyIterRef¤  KeyIter,·
6303ef ¤   ¤   PGPKeyRef¤  ¤   Key,·
e15943 ¤   ¤   BOOL¤   ¤   ¤   bReInsertExisting,·
1add36 ¤   ¤   BOOL¤   ¤   ¤   bForceNewAlloc,·
b36a35 ¤   ¤   BOOL¤   ¤   ¤   bExpandNew,·
2ac626 ¤   ¤   BOOL¤   ¤   ¤   bFirstCall,·
748b78 ¤   ¤   HTLITEM¤¤   ¤   hTPrev)·
7cbb36 {
90b40f ¤   HTLITEM hTKey, hTUID, hTCert;
92e723 ¤   TL_TREEITEM tli;
0eb9dd ¤   INT idx;
8e4e58 ¤   CHAR sz[kPGPMaxUserIDSize +1];
662872 ¤   CHAR sz2[64];
79a98e ¤   CHAR szID[32];
05546e ¤   UINT uState;
4e2174 ¤   BOOL bItalics, bNew;
cbf63b ¤   PGPUserIDRef UserID;
a1f4c5 ¤   PGPSigRef Cert;
734869 ¤   PGPKeyRef CertKey;
440040 ¤   PGPError err;
d75ea4 ¤   static BOOL bNewKeyExpanded;
37af5a
386126 ¤   uState = 0;
f9cde0 ¤   bNew = FALSE;
7ae617 ¤   if (bFirstCall) bNewKeyExpanded = FALSE;
35af5a
237952 ¤   KMGetKeyUserVal (pKM, Key, (long*)&hTKey);
81222e ¤   if (!hTKey) {
6635c0 ¤   ¤   bNew = TRUE;
079371 ¤   }
15af5a
9b7cc9 ¤   // determine icon and italics
3cc058 ¤   idx = KMDetermineKeyIcon (pKM, Key, &bItalics);
0b333a ¤   if (bItalics) uState |= TLIS_ITALICS;
28af5a
dedece ¤   // get primary userid name string
2e5e98 ¤   KMGetKeyName (Key, sz, sizeof(sz));
38af5a
e08203 ¤   // insert key item into tree and save pointer to tree item
8734e5 ¤   if (!hTKey && bExpandNew) uState |= TLIS_SELECTED;
2af410 ¤   if (bForceNewAlloc) hTKey = NULL;
a677da ¤   hTKey = sSetOneItem (pKM, bReInsertExisting, hTKey, NULL, sz, hTPrev,·
b8c997 ¤   ¤   ¤   ¤   ¤   ¤   idx, uState, (LPARAM)Key);
468f8f ¤   KMSetKeyUserVal (pKM, Key, (long)hTKey);
fbaf5a
77c4c3 ¤   // if a reinsertion, then we're done
fd5893 ¤   if (bReInsertExisting)·
623f86 ¤   ¤   return hTKey;
ccaf5a
8c9af4 ¤   sSetKeyData (pKM, hTKey, Key, idx);
02af5a
fad0d0 ¤   // iterate through userids
40e957 ¤   PGPKeyIterNextUserID (KeyIter, &UserID);
8d43e6 ¤   while (UserID) {
2df655 ¤   ¤   uState = 0;
c3af06 ¤   ¤   KMGetUserIDUserVal (pKM, UserID, (long*)&hTUID);
a644c0 ¤   ¤   if (!hTUID) bNew = TRUE;
56af5a
cac4b8 ¤   ¤   // get and set treelist tree data for this userid
4beb74 ¤   ¤   KMGetUserIDName (UserID, sz, sizeof(sz));
--eae1 000f007ad2e401102b5 Page 16 of KMTree.c
875b07 ¤   ¤   if (bForceNewAlloc) hTUID = NULL;
2641ae ¤   ¤   idx = KMDetermineUserIDIcon (Key, UserID, &bItalics);
4b0aff ¤   ¤   if (bItalics) uState |= TLIS_ITALICS;
c2af5a
ee2955 ¤   ¤   hTUID = sSetOneItem (pKM, FALSE, hTUID, hTKey, sz,·
9867aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   (HTLITEM)TLI_LAST, idx, uState, (LPARAM)UserID);
dcc2ad ¤   ¤   KMSetUserIDUserVal (pKM, UserID, (long)hTUID);
11af5a
38593a ¤   ¤   // get and set treelist list data for this userid
5c2847 ¤   ¤   sSetIDData (pKM, hTUID, UserID, idx);
b11b52 ¤   ¤
30636d ¤   ¤   // iterate through certifications
958f09 ¤   ¤   PGPKeyIterNextUIDSig (KeyIter, &Cert);
4c594c ¤   ¤   while (Cert) {
c48ca1 ¤   ¤   ¤   uState = 0;
c9e9b6 ¤   ¤   ¤   KMGetCertUserVal (pKM, Cert, (long*)&hTCert);
8b7b4e ¤   ¤   ¤   if (!hTCert) bNew = TRUE;
c3af5a
386ebc ¤   ¤   ¤   // get and set treelist tree data for this cert
b13988 ¤   ¤   ¤   err = PGPGetSigCertifierKey (Cert, pKM->KeySetDisp, &CertKey);
e1d74c ¤   ¤   ¤   if (err == kPGPError_ItemNotFound) {
70bd37 ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
e4bb36 ¤   ¤   ¤   ¤   CertKey = NULL;
e4a3a6 ¤   ¤   ¤   }
4baf5a
e505ea ¤   ¤   ¤   if (!CertKey && (pKM->KeySetDisp != pKM->KeySetMain)) {
614007 ¤   ¤   ¤   ¤   err = PGPGetSigCertifierKey (Cert, pKM->KeySetMain, &CertKey);
34a3a6 ¤   ¤   ¤   }
78d74c ¤   ¤   ¤   if (err == kPGPError_ItemNotFound) {
71bd37 ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
efbb36 ¤   ¤   ¤   ¤   CertKey = NULL;
dfa3a6 ¤   ¤   ¤   }
32af5a
1dd53e ¤   ¤   ¤   PGPclErrorBox (NULL, err);
a98edf ¤   ¤   ¤   bItalics = FALSE;
6b9991 ¤   ¤   ¤   if (CertKey) {
e61aa9 ¤   ¤   ¤   ¤   KMGetKeyName (CertKey, sz, sizeof(sz));
e7a3a6 ¤   ¤   ¤   }
79e543 ¤   ¤   ¤   else {
5ffc4c ¤   ¤   ¤   ¤   bItalics = TRUE;
d638b9 ¤   ¤   ¤   ¤   KMGetKeyIDFromCert (Cert, szID, sizeof(szID));
ea1da1 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNAVAILABLECERT,·
84f266 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz2, sizeof(sz2));
aa93d1 ¤   ¤   ¤   ¤   wsprintf (sz, sz2, szID);
51a3a6 ¤   ¤   ¤   }
f8a3b4 ¤   ¤   ¤   idx = KMDetermineCertIcon (Cert, &bItalics);
4b45c1 ¤   ¤   ¤   if (bItalics) uState |= TLIS_ITALICS;
98646e ¤   ¤   ¤   if (bForceNewAlloc) hTCert = NULL;
284b4a ¤   ¤   ¤   hTCert = sSetOneItem (pKM, FALSE, hTCert, hTUID, sz,·
04939d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (HTLITEM)TLI_LAST, idx,·
1ea2ad ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uState, (LPARAM)Cert);
e06e0b ¤   ¤   ¤   KMSetCertUserVal (pKM, Cert, (long)hTCert);
a2af5a
806bed ¤   ¤   ¤   // get and set treelist list data for this cert
5273c3 ¤   ¤   ¤   sSetCertData (pKM, hTCert, Cert, idx);
06af5a
e157bb ¤   ¤   ¤   PGPKeyIterNextUIDSig (KeyIter, &Cert);
458469 ¤   ¤   }·
dabbca ¤   ¤   PGPKeyIterNextUserID (KeyIter, &UserID);
b09371 ¤   }
ceaf5a
401329 ¤   // select and expand key, if appropriate·
fe3d80 ¤   if (bExpandNew && bNew) {
2d506a ¤   ¤   tli.hItem = hTKey;
77b137 ¤   ¤   if (!bNewKeyExpanded) {
24f178 ¤   ¤   ¤   TreeList_Select (pKM->hWndTree, &tli, TRUE);
9ed8ed ¤   ¤   ¤   TreeList_Expand (pKM->hWndTree, &tli, TLE_EXPANDALL);
ad1a12 ¤   ¤   ¤   bNewKeyExpanded = TRUE;
720fe4 ¤   ¤   }
b607e0 ¤   ¤   else {
ad0495 ¤   ¤   ¤   KMSetFocus (pKM, KMFocusedItem (pKM), TRUE);
f0d8ed ¤   ¤   ¤   TreeList_Expand (pKM->hWndTree, &tli, TLE_EXPANDALL);
--1528 0000c6f3d90401102b5 Page 17 of KMTree.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
27051c ¤   return hTKey;
32efe6 }
2daf5a
14af5a
549268 //¤ _______________________________________________
d8465d //
9bd416 // ·Scan entire keyring loading in any new data
8c465d //
328ceb //¤ bReInsertExisting¤  - is only used when reordering keys in window.
0de2bf //¤ ¤   ¤   ¤   ¤   ¤   ··This is set TRUE if the caller has already
ed06dc //¤ ¤   ¤   ¤   ¤   ¤   ··deleted the treelist but not deallocated the items.
dd535c //¤ bExpandNew¤ ¤   ¤   - causes new keys to be expanded
3d5b5d //¤ bForceRealloc¤  ¤   - forces reallocation of treelist items. ·Used after
203086 //¤ ¤   ¤   ¤   ¤   ¤   ··the caller has deleted the treelist and deallocated
01e865 //¤ ¤   ¤   ¤   ¤   ¤   ··all the items.·
bfaf5a
fe7efe BOOL·
159b11 KMLoadKeyRingIntoTree (
ec9851 ¤   ¤   PKEYMAN¤pKM,·
ec5f70 ¤   ¤   BOOL¤   bReInsertExisting,·
bd559a ¤   ¤   BOOL¤   bExpandNew,·
40ff96 ¤   ¤   BOOL¤   bForceRealloc)·
70bb36 {
59af5a
cefa50 ¤   HCURSOR¤¤   ¤   hCursorOld;
f1a37c ¤   PGPKeyListRef¤  KeyList;
8cb17a ¤   PGPKeyIterRef¤  KeyIter;
f57593 ¤   PGPKeyRef¤  ¤   Key;
322447 ¤   PGPKeyRef¤  ¤   keyDef;
e649d1 ¤   TL_TREEITEM¤¤   tli;
626c79 ¤   HTLITEM¤¤   ¤   hTPrevKey;
4e44ec ¤   BOOL¤   ¤   ¤   bFirst;
0e6f4c ¤   PGPBoolean¤ ¤   bSecret, bRevoked, bExpired, bCanSign;
80af5a
9fe45b ¤   hTPrevKey = (HTLITEM)TLI_FIRST;
deca72 ¤   bFirst = TRUE;
7eaf5a
16eba5 ¤   if (pKM->KeySetDisp) {
eef63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
c46e2a ¤   ¤   PGPOrderKeySet (pKM->KeySetDisp, pKM->lKeyListSortField, &KeyList);
4c171f ¤   ¤   PGPNewKeyIter (KeyList, &KeyIter);
47af5a
7d455f ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
1eaf5a
df9f37 ¤   ¤   while (Key) {
cd144f ¤   ¤   ¤   hTPrevKey = sReloadKey (pKM, KeyIter, Key, bReInsertExisting,·
8ba645 ¤   ¤   ¤   ¤   ¤   ¤   bForceRealloc, bExpandNew, bFirst, hTPrevKey);
31cd39 ¤   ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
7bed8d ¤   ¤   ¤   bFirst = FALSE;
750fe4 ¤   ¤   }
3e26dc ¤   ¤   PGPFreeKeyIter (KeyIter);
619571 ¤   ¤   PGPFreeKeyList (KeyList);
7eaf5a
5b5994 ¤   ¤   if (pKM->bMainKeySet) {
1e3999 ¤   ¤   ¤   PGPGetDefaultPrivateKey (pKM->KeySetMain, &keyDef);
d279aa ¤   ¤   ¤   if (keyDef) {
869a37 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (keyDef, kPGPKeyPropIsSecret, &bSecret);
c581ea ¤   ¤   ¤   ¤   PGPGetKeyBoolean (keyDef, kPGPKeyPropIsRevoked, &bRevoked);
46a976 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (keyDef, kPGPKeyPropIsExpired, &bExpired);
6372cd ¤   ¤   ¤   ¤   PGPGetKeyBoolean (keyDef, kPGPKeyPropCanSign, &bCanSign);
68af5a
f1bb3d ¤   ¤   ¤   ¤   if (bSecret && bCanSign && !bRevoked && !bExpired) {
f21824 ¤   ¤   ¤   ¤   ¤   KMGetKeyUserVal (pKM, keyDef, (long*)&(tli.hItem));
595dec ¤   ¤   ¤   ¤   ¤   if (tli.hItem) {
42a287 ¤   ¤   ¤   ¤   ¤   ¤   tli.state = TLIS_BOLD;
68cde0 ¤   ¤   ¤   ¤   ¤   ¤   tli.stateMask = TLIS_BOLD;
c6c4fa ¤   ¤   ¤   ¤   ¤   ¤   tli.mask = TLIF_STATE;
0f9f17 ¤   ¤   ¤   ¤   ¤   ¤   TreeList_SetItem (pKM->hWndTree, &tli);
0c1c89 ¤   ¤   ¤   ¤   ¤   }
--f6c2 000f681b548401102b5 Page 18 of KMTree.c
862613 ¤   ¤   ¤   ¤   }
2ba3a6 ¤   ¤   ¤   }
590fe4 ¤   ¤   }
e6af5a
ba7139 ¤   ¤   SetCursor (hCursorOld);
cb6991 ¤   ¤   if (bExpandNew) {
373347 ¤   ¤   ¤   tli.hItem = KMFocusedItem (pKM);
a63db9 ¤   ¤   ¤   if (tli.hItem) TreeList_EnsureVisible (pKM->hWndTree, &tli);
1b0fe4 ¤   ¤   }
e9836c ¤   ¤   return TRUE;
8c9371 ¤   }
dfaf5a
e0efe6 }
d0af5a
95af5a
899268 //¤ _______________________________________________
e3465d //
e630ba // ·iterate entire keyset, deleting user value linked-list elements
1aaf5a
f27efe BOOL·
f7f1c5 KMDeleteAllUserValues (PKEYMAN pKM)·
2cbb36 {
77af5a
9cd34e ¤   PGPKeyListRef KeyList;
1e4276 ¤   PGPKeyIterRef KeyIter;
546a89 ¤   PGPKeyRef Key;
cef63b ¤   PGPUserIDRef UserID;
b8f4c5 ¤   PGPSigRef Cert;
18af5a
b88fc6 ¤   if (!pKM) return FALSE;
1513cf ¤   if (!pKM->KeySetDisp) return FALSE;
c9af5a
edad2a ¤   PGPOrderKeySet (pKM->KeySetDisp, kPGPAnyOrdering, &KeyList);
941953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
16af5a
eb800a ¤   PGPKeyIterNext (KeyIter, &Key);
5faf5a
f0a5ad ¤   while (Key) {
acbbca ¤   ¤   PGPKeyIterNextUserID (KeyIter, &UserID);
d5f237 ¤   ¤   while (UserID) {
d857bb ¤   ¤   ¤   PGPKeyIterNextUIDSig (KeyIter, &Cert);
cebbad ¤   ¤   ¤   while (Cert) {
4ab379 ¤   ¤   ¤   ¤   KMSetCertUserVal (pKM, Cert, 0);
c9469c ¤   ¤   ¤   ¤   PGPKeyIterNextUIDSig (KeyIter, &Cert);
36a3a6 ¤   ¤   ¤   }
eb4727 ¤   ¤   ¤   KMSetUserIDUserVal (pKM, UserID, 0);
89e8d1 ¤   ¤   ¤   PGPKeyIterNextUserID (KeyIter, &UserID);
780fe4 ¤   ¤   }
203257 ¤   ¤   KMSetKeyUserVal (pKM, Key, 0);
fa455f ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
299371 ¤   }
8d11d4 ¤   PGPFreeKeyIter (KeyIter);
a6a279 ¤   PGPFreeKeyList (KeyList);
b2af5a
69c2e7 ¤   return TRUE;
07efe6 }
79af5a
ddaf5a
519268 //¤ _______________________________________________
fc465d //
c5b180 // ·Insert single key into treelist
18af5a
547efe BOOL·
4a6b4f KMUpdateKeyInTree (
8a45dc ¤   ¤   PKEYMAN¤¤   pKM,·
dbade8 ¤   ¤   PGPKeyRef¤  Key,·
59cfee ¤   ¤   BOOL¤   ¤   bForceNew)·
65bb36 {
54af5a
dfa37c ¤   PGPKeyListRef¤  KeyList;
d0b17a ¤   PGPKeyIterRef¤  KeyIter;
f60c56 ¤   PGPKeyRef¤  ¤   PrevKey;
--f702 000a9b1aa74401102b5 Page 19 of KMTree.c
a82993 ¤   PGPKeyRef¤  ¤   DefaultKey;
f549d1 ¤   TL_TREEITEM¤¤   tli;
a06c79 ¤   HTLITEM¤¤   ¤   hTPrevKey;
4e76fc ¤   HTLITEM¤¤   ¤   hTFocused;
5f6f4c ¤   PGPBoolean¤ ¤   bSecret, bRevoked, bExpired, bCanSign;
71af5a
9568f9 ¤   if (pKM->KeySetDisp) {¤
3e9872 ¤   ¤   hTFocused = KMFocusedItem (pKM);
a9bf5a ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, KMGetKeyUserVal (pKM, Key,·
bc5d76 ¤   ¤   ¤   ¤   ¤   (long*)&(tli.hItem))))) {
b14d6f ¤   ¤   ¤   if (bForceNew && tli.hItem) {
03f832 ¤   ¤   ¤   ¤   TreeList_DeleteItem (pKM->hWndTree, &tli);
6a7180 ¤   ¤   ¤   ¤   KMSetKeyUserVal (pKM, Key, 0L);
e6a3a6 ¤   ¤   ¤   }
0faf5a
41a1e0 ¤   ¤   ¤   PGPOrderKeySet (pKM->KeySetDisp,·
8d737d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->lKeyListSortField, &KeyList);
608687 ¤   ¤   ¤   PGPNewKeyIter (KeyList, &KeyIter);
bf4328 ¤   ¤   ¤   PGPKeyIterSeek (KeyIter, Key);
2f24c4 ¤   ¤   ¤   PGPKeyIterPrev (KeyIter, &PrevKey);
934328 ¤   ¤   ¤   PGPKeyIterSeek (KeyIter, Key);
e9af5a
70a968 ¤   ¤   ¤   hTPrevKey = (HTLITEM)TLI_FIRST;
501dd9 ¤   ¤   ¤   if (PrevKey) {
a09831 ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, KMGetKeyUserVal (pKM,·
e57aa1 ¤   ¤   ¤   ¤   ¤   ¤   PrevKey, (long*)&(tli.hItem))))) {
f38e4c ¤   ¤   ¤   ¤   ¤   hTPrevKey = tli.hItem;
002613 ¤   ¤   ¤   ¤   }
9f5a2a ¤   ¤   ¤   }¤
90af5a
31317e ¤   ¤   ¤   sReloadKey (pKM, KeyIter, Key, FALSE, bForceNew, FALSE,·
053433 ¤   ¤   ¤   ¤   ¤   ¤   TRUE, hTPrevKey);
f6af5a
1cc9af ¤   ¤   ¤   PGPFreeKeyIter (KeyIter);
567a02 ¤   ¤   ¤   PGPFreeKeyList (KeyList);
b3af5a
8988d7 ¤   ¤   ¤   // only set default key if this is the main keyset
13d268 ¤   ¤   ¤   if (pKM->bMainKeySet) {
1ad43d ¤   ¤   ¤   ¤   PGPGetDefaultPrivateKey (pKM->KeySetMain, &DefaultKey);
a21a8d ¤   ¤   ¤   ¤   if (DefaultKey == Key) {
1eaf5a
33c4a2 ¤   ¤   ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
2e5df4 ¤   ¤   ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsRevoked, &bRevoked);
597568 ¤   ¤   ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsExpired, &bExpired);
902c58 ¤   ¤   ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropCanSign, &bCanSign);
78af5a
17bc4b ¤   ¤   ¤   ¤   ¤   if (bSecret && bCanSign && !bRevoked && !bExpired) {
b6600a ¤   ¤   ¤   ¤   ¤   ¤   KMGetKeyUserVal (pKM,·
673047 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DefaultKey, (long*)&(tli.hItem));
535801 ¤   ¤   ¤   ¤   ¤   ¤   if (tli.hItem) {
a87a35 ¤   ¤   ¤   ¤   ¤   ¤   ¤   tli.state = TLIS_BOLD;
17dcc7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   tli.stateMask = TLIS_BOLD;
551c48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   tli.mask = TLIF_STATE;
3ba279 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TreeList_SetItem (pKM->hWndTree, &tli);
4adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
601c89 ¤   ¤   ¤   ¤   ¤   }
bc2613 ¤   ¤   ¤   ¤   }
50a3a6 ¤   ¤   ¤   }
6daf5a
d919b0 ¤   ¤   ¤   // set selection appropriately
d1d3e5 ¤   ¤   ¤   if (bForceNew)·
be809a ¤   ¤   ¤   ¤   KMGetKeyUserVal (pKM, Key, (long*)&(tli.hItem));
41bb8c ¤   ¤   ¤   else
5d6f91 ¤   ¤   ¤   ¤   tli.hItem = hTFocused;
7ef178 ¤   ¤   ¤   TreeList_Select (pKM->hWndTree, &tli, TRUE);
d7af5a
3f32bd ¤   ¤   ¤   return TRUE;
840fe4 ¤   ¤   }
249371 ¤   }
4ba230 ¤   return FALSE;
0defe6 }
a9af5a
--2b15 0000788c594401102b5 Page 20 of KMTree.c
e0af5a
0d9268 //¤ _______________________________________________
1d465d //
e29e8e // ·Set validity for a treelist item
61af5a
ddd7b4 static HTLITEM·
e6b5ac sSetItemValidity (
399851 ¤   ¤   PKEYMAN¤pKM,·
5d4165 ¤   ¤   HTLITEM¤hItem,·
6afd3f ¤   ¤   INT¤¤   iValidity)·
27bb36 {
d9ab9f ¤   TL_LISTITEM tlL;
c2af5a
32dccc ¤   tlL.hItem = hItem;
7daf5a
7e0db3 ¤   tlL.iSubItem = 1;
047e74 ¤   tlL.mask = TLIF_DATAVALUE;
723760 ¤   if (pKM->ulOptionFlags & KMF_NOVICEMODE) {
f7746c ¤   ¤   if (iValidity > KM_VALIDITY_COMPLETE)
5d82b3 ¤   ¤   ¤   tlL.lDataValue = IDX_AXIOMATIC;
fee1e5 ¤   ¤   else if (iValidity >= pKM->iValidityThreshold)·
2349dd ¤   ¤   ¤   tlL.lDataValue = IDX_VALID;
7b1b8d ¤   ¤   else tlL.lDataValue = IDX_INVALID;
409371 ¤   }
c0a0cc ¤   else tlL.lDataValue = iValidity;
e25f32 ¤   hItem = (HTLITEM) TreeList_SetListItem (pKM->hWndTree, &tlL, FALSE);
5faf5a
3266c6 ¤   return (hItem);
a1efe6 }
caaf5a
a2af5a
989268 //¤ _______________________________________________
8e465d //
038e9e // ·update validity values for all keys/userids
87af5a
377efe BOOL·
0c0160 KMUpdateAllValidities (PKEYMAN pKM)·
a9bb36 {
1daf5a
f4fa50 ¤   HCURSOR¤¤   ¤   hCursorOld;
00eec1 ¤   HTLITEM¤¤   ¤   hTKey, hTUID;
d1d125 ¤   PGPKeyListRef¤  keylist;
7cc323 ¤   PGPKeyIterRef¤  keyiter;
4e1502 ¤   PGPKeyRef¤  ¤   key;
978f18 ¤   PGPUserIDRef¤   userid;
a06dd4 ¤   Boolean¤¤   ¤   bAxiomatic;
076e76 ¤   UINT¤   ¤   ¤   u;
57af5a
8beba5 ¤   if (pKM->KeySetDisp) {
c8f63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
92a11c ¤   ¤   PGPOrderKeySet (pKM->KeySetDisp, pKM->lKeyListSortField, &keylist);
96fa80 ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
36af5a
653e9e ¤   ¤   PGPKeyIterNext (keyiter, &key);
a1af5a
af0986 ¤   ¤   // iterate through keys
06fcb4 ¤   ¤   while (key) {
396d21 ¤   ¤   ¤   KMGetKeyUserVal (pKM, key, (long*)&hTKey);
16092b ¤   ¤   ¤   if (hTKey) {
5edb63 ¤   ¤   ¤   ¤   // if axiomatic set trust and validity to out-of-range values
d90860 ¤   ¤   ¤   ¤   // ·in order to flag different graphical representation
d25a68 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropIsAxiomatic, &bAxiomatic);
ad65bf ¤   ¤   ¤   ¤   if (bAxiomatic)·
8b7959 ¤   ¤   ¤   ¤   ¤   u = KMConvertFromPGPValidity (kPGPValidity_Complete) + 1;
71deaa ¤   ¤   ¤   ¤   else {
8bb4f3 ¤   ¤   ¤   ¤   ¤   if (IsPGPError (PGPclErrorBox (NULL,
0c8328 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDValidity (key, &u)))) u = 0;
3896bc ¤   ¤   ¤   ¤   ¤   else·
9013b5 ¤   ¤   ¤   ¤   ¤   ¤   u = KMConvertFromPGPValidity (u);
f92613 ¤   ¤   ¤   ¤   }
3001fe ¤   ¤   ¤   ¤   sSetItemValidity (pKM, hTKey, u);
07a3a6 ¤   ¤   ¤   }
--50db 0001bae351e401102b5 Page 21 of KMTree.c
e0af5a
e31d5c ¤   ¤   ¤   // iterate through userids
034339 ¤   ¤   ¤   PGPKeyIterNextUserID (keyiter, &userid);
938f2e ¤   ¤   ¤   while (userid) {
bda8d8 ¤   ¤   ¤   ¤   KMGetUserIDUserVal (pKM, userid, (long*)&hTUID);
0512af ¤   ¤   ¤   ¤   if (hTUID) {
99cc5f ¤   ¤   ¤   ¤   ¤   PGPGetUserIDNumber (userid, kPGPUserIDPropValidity, &u);
b410c2 ¤   ¤   ¤   ¤   ¤   u = KMConvertFromPGPValidity (u);
37fe29 ¤   ¤   ¤   ¤   ¤   sSetItemValidity (pKM, hTUID, u);
122613 ¤   ¤   ¤   ¤   }
71af5a
442c0a ¤   ¤   ¤   ¤   PGPKeyIterNextUserID (keyiter, &userid);
9fa3a6 ¤   ¤   ¤   }
8eb6f8 ¤   ¤   ¤   PGPKeyIterNext (keyiter, &key);
890fe4 ¤   ¤   }
76e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
655a47 ¤   ¤   PGPFreeKeyList (keylist);
047139 ¤   ¤   SetCursor (hCursorOld);
d2af5a
33836c ¤   ¤   return TRUE;
fa9371 ¤   }
c7af5a
78da59 ¤   // error on open key rings
b5cdfa ¤   else return FALSE;
6befe6 }
32af5a
90af5a
b29268 //¤ _______________________________________________
b5465d //
a7dda6 // ·Expand a single item
3c6d3e //¤ routine called as a
1b995b //¤ callback function from the TreeList control to·
5fa512 //¤ expand a single item.
fb465d //
24e701 //¤ lptli¤  = pointer to TreeList item to expand
79af5a
f13f64 static BOOL CALLBACK·
6d94c8 sExpandSingleItem (TL_TREEITEM* lptli, LPARAM lParam)·
19bb36 {
4200bf ¤   EXPANDCOLLAPSESTRUCT* pecs = (EXPANDCOLLAPSESTRUCT*)lParam;
5e7909 ¤   TreeList_Expand (pecs->hWndTree, lptli, TLE_EXPANDALL);
02c2e7 ¤   return TRUE;
62efe6 }
feaf5a
b2af5a
f79268 //¤ _______________________________________________
45465d //
dd66d8 // ·Expand the selected items
3eaf5a
f2da9d BOOL KMExpandSelected (PKEYMAN pKM) {
b4a9af ¤   EXPANDCOLLAPSESTRUCT ecs;
cdaf5a
6f03cc ¤   ecs.lpfnCallback = sExpandSingleItem;
da130a ¤   ecs.hWndTree = pKM->hWndTree;
e93a60 ¤   TreeList_IterateSelected (pKM->hWndTree, &ecs);
22b65e ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
b9af5a
e4c2e7 ¤   return TRUE;
16efe6 }
32af5a
8aaf5a
729268 //¤ _______________________________________________
ea465d //
d1ff15 // ·Collapse a single item
c66d3e //¤ routine called as a
df995b //¤ callback function from the TreeList control to·
0240d4 //¤ collapse a single item.
dbac6a //·
9cab4c //¤ lptli¤  = pointer to TreeList item to collapse
deaf5a
c23f64 static BOOL CALLBACK·
1bd1a8 sCollapseSingleItem (TL_TREEITEM* lptli, LPARAM lParam)·
--4b66 000edb712b3401102b5 Page 22 of KMTree.c
2cbb36 {
a300bf ¤   EXPANDCOLLAPSESTRUCT* pecs = (EXPANDCOLLAPSESTRUCT*)lParam;
8f0a5c ¤   TreeList_Expand (pecs->hWndTree, lptli, TLE_COLLAPSEALL);
39c2e7 ¤   return TRUE;
b6efe6 }
9aaf5a
2eaf5a
599268 //¤ _______________________________________________
58465d //
5193b5 // ·Collapse the selected items
eeaf5a
784bc7 BOOL KMCollapseSelected (PKEYMAN pKM) {
bda9af ¤   EXPANDCOLLAPSESTRUCT ecs;
5caf5a
66a1a0 ¤   ecs.lpfnCallback = sCollapseSingleItem;
71130a ¤   ecs.hWndTree = pKM->hWndTree;
803a60 ¤   TreeList_IterateSelected (pKM->hWndTree, &ecs);
02b65e ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
ceaf5a
3bc2e7 ¤   return TRUE;
62efe6 }
b7af5a
57af5a
419268 //¤ _______________________________________________
86465d //
30931e // ·Cleanup treelist
9faf5a
a6b997 PGPError PGPkmExport·
5fe899 PGPkmDestroyKeyManager (
db4fe0 ¤   ¤   HKEYMAN¤hKM,
8e0d66 ¤   ¤   BOOL¤   bSaveColumnInfo)·
4cbb36 {
f9af5a
da218e ¤   PKEYMAN pKM = (PKEYMAN)hKM;
fcef62 ¤   if (!hKM) return kPGPError_BadParams;
1caf5a
cffa69 ¤   KMDeleteAllKeyProperties (pKM, TRUE);
26ac18 ¤   KMDeleteAllUserValues (pKM);
b5af5a
d5247f ¤   CloseHandle (pKM->hRequestMutex);
12a4e6 ¤   CloseHandle (pKM->hAccessMutex);
51af5a
e357a2 ¤   RevokeDragDrop (pKM->hWndTree);
9fe662 ¤   KMReleaseDropTarget (pKM->pDropTarget); ·
0deeda ¤   CoLockObjectExternal ((IUnknown*)pKM->pDropTarget, FALSE, TRUE);
63fde3 ¤   DragAcceptFiles (pKM->hWndTree, FALSE);
b2af5a
15e970 ¤   if (bSaveColumnInfo) KMSetColumnPreferences (pKM);
e9af5a
caf952 ¤   SendMessage (pKM->hWndTree, WM_CLOSE, 0, 0);
9bda6d ¤   ImageList_Destroy (pKM->hIml);
11af5a
f1151e ¤   return kPGPError_NoErr;
62efe6 }
33af5a
1faf5a
429268 //¤ _______________________________________________
48465d //
a83e3b // ·Load keyset into treelist
a7af5a
6cb997 PGPError PGPkmExport·
dee93a PGPkmLoadKeySet (
9ef0a4 ¤   ¤   HKEYMAN¤¤   ¤   hKeyMan,·
907c86 ¤   ¤   PGPKeySetRef¤   KeySetDisp,
8a08d9 ¤   ¤   PGPKeySetRef¤   KeySetMain)·
babb36 {
ceaf5a
75f184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
b9da2c ¤   if (!pKM) return kPGPError_BadParams;
abaf5a
43eba5 ¤   if (pKM->KeySetDisp) {
edc3ac ¤   ¤   KMDeleteAllKeyProperties (pKM, TRUE);
--a026 000b6450a9a401102b5 Page 23 of KMTree.c
2e9170 ¤   ¤   KMDeleteAllUserValues (pKM);
81d1c0 ¤   ¤   KMSetFocus (pKM, NULL, FALSE);
b697c5 ¤   ¤   pKM->KeySetDisp = NULL;
328088 ¤   ¤   pKM->KeySetMain = NULL;
c22107 ¤   ¤   TreeList_DeleteTree (pKM->hWndTree, TRUE);
f69371 ¤   }
84af5a
6f1301 ¤   pKM->KeySetDisp = KeySetDisp;
ce7607 ¤   KMGetColumnPreferences (pKM);
2bdb64 ¤   KMAddColumns (pKM);
7caf5a
77651b ¤   if (KeySetDisp) {
426e07 ¤   ¤   if (KeySetMain) {
3b86dc ¤   ¤   ¤   pKM->KeySetMain = KeySetMain;
1b55f7 ¤   ¤   ¤   pKM->bMainKeySet = TRUE;
920fe4 ¤   ¤   }
1907e0 ¤   ¤   else {
f6730e ¤   ¤   ¤   pKM->KeySetMain = KeySetDisp;
12b226 ¤   ¤   ¤   pKM->bMainKeySet = FALSE;
020fe4 ¤   ¤   }
896428 ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, FALSE, TRUE);
ed554a ¤   ¤   KMEnableDropTarget (pKM->pDropTarget,·
56e8f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   !(pKM->ulOptionFlags & KMF_READONLY) &&
ab07b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pKM->ulOptionFlags & KMF_ENABLEDROPIN));
169371 ¤   }
0f665a ¤   else {
95689f ¤   ¤   pKM->bMainKeySet = TRUE;
4c9371 ¤   }
2baf5a
35b65e ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
9aed22 ¤   UpdateWindow (pKM->hWndTree);
78af5a
a4151e ¤   return kPGPError_NoErr;
29efe6 }
98af5a
a3af5a
209268 //¤ _______________________________________________
7e465d //
b63e3b // ·Load keyset into treelist
56af5a
30b997 PGPError PGPkmExport·
60a25a PGPkmReLoadKeySet (HKEYMAN hKeyMan, BOOL bExpandNew)·
46bb36 {
75f184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
4dda2c ¤   if (!pKM) return kPGPError_BadParams;
6cec0b ¤   if (!pKM->KeySetDisp) return kPGPError_BadParams;
09af5a
aff3a3 ¤   KMLoadKeyRingIntoTree (pKM, FALSE, bExpandNew, FALSE);
88af5a
1ab65e ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
cced22 ¤   UpdateWindow (pKM->hWndTree);
41af5a
34151e ¤   return kPGPError_NoErr;
1defe6 }
f8af5a
a2af5a
829268 //¤ _______________________________________________
69465d //
82f4e0 // ·Select specified key
e2af5a
a3a1ba VOID·
7d3da3 KMSelectKey (PKEYMAN pKM, PGPKeyRef key, BOOL bDeselect)·
4cbb36 {
3349d1 ¤   TL_TREEITEM¤¤   tli;
41af5a
440a9f ¤   KMGetKeyUserVal (pKM, key, (long*)&(tli.hItem));
a55e5e ¤   if (tli.hItem) {
a20e5e ¤   ¤   TreeList_Select (pKM->hWndTree, &tli, bDeselect);
eb9371 ¤   }
68efe6 }
57af5a
b69268 //¤ _______________________________________________
--ea39 0014c65a202401102b5 Page 24 of KMTree.c
c1465d //
d1f4e0 // ·Select specified key
9faf5a
3eb997 PGPError PGPkmExport·
b1d882 PGPkmSelectKey (HKEYMAN hKeyMan, PGPKeyRef key, BOOL bDeselect)·
f1bb36 {
8552c9 ¤   PKEYMAN¤¤   ¤   pKM = (PKEYMAN)hKeyMan;
d9af5a
233529 ¤   KMSelectKey (pKM, key, bDeselect);
20af5a
24151e ¤   return kPGPError_NoErr;
3defe6 }
ddaf5a
859268 //¤ _______________________________________________
46465d //
4362af // ·Get a keyset of all selected keys
c8af5a
e5b997 PGPError PGPkmExport·
5734d3 PGPkmGetSelectedKeys (HKEYMAN hKeyMan, PGPKeySetRef* pkeysetSelected)·
bbbb36 {
1a52c9 ¤   PKEYMAN¤¤   ¤   pKM = (PKEYMAN)hKeyMan;
23af5a
d1b9ae ¤   return (KMGetSelectedKeys (pKM, pkeysetSelected, NULL));
9cefe6 }
04af5a
0caf5a
4caf5a
--b523 000c7ddcafd401102b6 Page 1 of KMUser.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
730499 ¤   KMUser.c - miscellaneous user interface routines
9167c5 ¤
5eaf5a
577ba7 ¤   $Id: KMUser.c,v 1.27 1998/08/11 14:43:41 pbj Exp $
0ff7f7 ____________________________________________________________________________*/
41e610 #include "pgpPFLConfig.h"
3daf5a
46c917 // project header files
34850a #include "pgpkmx.h"
5daf5a
7a3fb5 // external global variables
dd9cad extern HINSTANCE g_hInst;
c2af5a
de18be // local global variables
42d86a static DWORD aSignConfirmIds[] = {¤ ¤   ¤   // Help IDs
574434 ····0,0·
6ea6fe };·
f9af5a
329268 //¤ _______________________________________________
0e465d //
1e43f7 // Message box routine
1b465d //
db8a32 //¤ iCaption and iMessage are string table resource IDs.
a3af5a
dd0218 LRESULT·
4d11f7 KMMessageBox (
2047b2 ¤   ¤   HWND¤   hWnd,·
2d1310 ¤   ¤   INT¤¤   iCaption,·
bf08ad ¤   ¤   INT¤¤   iMessage,
b01582 ¤   ¤   ULONG¤  ulFlags)·
7fbb36 {
6001b5 ¤   CHAR szCaption [128];
793a7c ¤   CHAR szMessage [512];
b7af5a
93c237 ¤   LoadString (g_hInst, iCaption, szCaption, sizeof(szCaption));
597e8b ¤   LoadString (g_hInst, iMessage, szMessage, sizeof(szMessage));
14af5a
18897a ¤   ulFlags |= MB_SETFOREGROUND;
6a729f ¤   return (MessageBox (hWnd, szMessage, szCaption, ulFlags));
5eefe6 }
d9af5a
80af5a
aa9268 //¤ _______________________________________________
92465d //
7c7fcb // Signature confirmation dialog message procedure
e1af5a
c53f64 static BOOL CALLBACK·
e2c70e sSignConfirmDlgProc (
724669 ¤   ¤   HWND¤   hWndDlg,·
0ceb77 ¤   ¤   UINT¤   uMsg,·
1f17d4 ¤   ¤   WPARAM¤ wParam,·
d8c0b8 ¤   ¤   LPARAM¤ lParam)·
99bb36 {
985a24 ¤   PKEYMAN pKM;
44af5a
f3347f ¤   switch (uMsg) {
46ad3a ¤   case WM_INITDIALOG :
fd2ec5 ¤   ¤   SetWindowLong (hWndDlg, GWL_USERDATA, lParam);
f05d3a ¤   ¤   CheckDlgButton (hWndDlg, IDC_SENDSIG, BST_UNCHECKED);
bf2f68 ¤   ¤   break;
feaf5a
b38a25 ¤   case WM_HELP:·
3d0c3b ¤   ¤   pKM = (PKEYMAN)GetWindowLong (hWndDlg, GWL_USERDATA);
b99e07 ¤   ····WinHelp (((LPHELPINFO) lParam)->hItemHandle, pKM->szHelpFile,·
cd50f9 ¤   ········HELP_WM_HELP, (DWORD) (LPSTR) aSignConfirmIds);·
ed7d53 ¤   ····break;·
b2d83c ·
c7af40 ¤   case WM_CONTEXTMENU:·
--b0fa 0009b4fe3b8401102b6 Page 2 of KMUser.c
e30c3b ¤   ¤   pKM = (PKEYMAN)GetWindowLong (hWndDlg, GWL_USERDATA);
7affe7 ¤   ····WinHelp ((HWND) wParam, pKM->szHelpFile, HELP_CONTEXTMENU,·
601db6 ¤   ········(DWORD) (LPVOID) aSignConfirmIds);·
a27d53 ¤   ····break;·
44af5a
a3d1d3 ¤   case WM_COMMAND :
8b537d ¤   ¤   switch (LOWORD(wParam)) {
28b6bb ¤   ¤   case IDCANCEL :
dba2ac ¤   ¤   ¤   EndDialog (hWndDlg, 0);
3ccdcb ¤   ¤   ¤   break;
feaf5a
2b8c29 ¤   ¤   case IDOK :
4e9937 ¤   ¤   ¤   if (IsDlgButtonChecked (hWndDlg, IDC_SENDSIG) == BST_CHECKED)·
cd5e8f ¤   ¤   ¤   ¤   EndDialog (hWndDlg, 2);
076b93 ¤   ¤   ¤   else·
447b42 ¤   ¤   ¤   ¤   EndDialog (hWndDlg, 1);
d9cdcb ¤   ¤   ¤   break;
b80fe4 ¤   ¤   }
d2836c ¤   ¤   return TRUE;
b09371 ¤   }
a2a230 ¤   return FALSE;
b1efe6 }
e0af5a
94af5a
ec9268 //¤ _______________________________________________
eb465d //
98d1e6 //¤ Ask user for signature confirmation
c7af5a
db7efe BOOL·
9c59d9 KMSignConfirm (PKEYMAN pKM, BOOL* pbSendToServer)·
b9bb36 {
a2e79b ¤   INT iError;
bdaf5a
f0e848 ¤   iError = DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_SIGNCONFIRM),·
a646de ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, sSignConfirmDlgProc, (LPARAM)pKM);
c1af5a
dbea85 ¤   switch (iError) {
3b741e ¤   case 0 :
77cbf1 ¤   ¤   *pbSendToServer = FALSE;
cc98aa ¤   ¤   return FALSE;
25af5a
e068a5 ¤   case 1 :
8bcbf1 ¤   ¤   *pbSendToServer = FALSE;
78836c ¤   ¤   return TRUE;
03af5a
314d68 ¤   case 2 :
8c552d ¤   ¤   *pbSendToServer = TRUE;
02836c ¤   ¤   return TRUE;
7af828 ¤   }¤
eeefe6 }
6caf5a
efaf5a
619268 //¤ _______________________________________________
93465d //
617aca //¤ construct userid from name and address edit box contents
e9af5a
7e6bed BOOL KMConstructUserID (
c03a3a ¤   ¤   HWND¤   hDlg,·
2c89cd ¤   ¤   UINT¤   uNameIDC,·
7e88db ¤   ¤   UINT¤   uAddrIDC,·
03c1a2 ¤   ¤   LPSTR*¤ pszUserID)·
4cbb36 {
3bca0d ¤   UINT uNameLen, uAddrLen, uUserIDLen;
e4b616 ¤   CHAR* p;
adaf5a
6d987e ¤   uNameLen = SendDlgItemMessage (hDlg, uNameIDC, WM_GETTEXTLENGTH, 0, 0);
29b7e7 ¤   if (uNameLen == 0) {
315aa5 ¤   ¤   KMMessageBox (hDlg, IDS_CAPTION, IDS_NOUSERNAME,·
5442a9 ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
a6bbca ¤   ¤   SetFocus (GetDlgItem (hDlg, uNameIDC));
8898aa ¤   ¤   return FALSE;
9b9371 ¤   }
--db44 0009d1aebc5401102b6 Page 3 of KMUser.c
e0af5a
153f31 ¤   uAddrLen = SendDlgItemMessage (hDlg, uAddrIDC, WM_GETTEXTLENGTH, 0, 0);
c1e6e9 ¤   if (uAddrLen == 0) {
c3d8a1 ¤   ¤   if (KMMessageBox (hDlg, IDS_CAPTION, IDS_NOUSERADDR,·
2c68a9 ¤   ¤   ¤   MB_YESNO|MB_DEFBUTTON2|MB_ICONEXCLAMATION) == IDNO) {
84583d ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, uAddrIDC));
225f1f ¤   ¤   ¤   return FALSE;
780fe4 ¤   ¤   }
429371 ¤   }
71af5a
5ad9e9 ¤   uUserIDLen = uNameLen + uAddrLen + 4;
3727ab ¤   *pszUserID = KMAlloc (uUserIDLen * sizeof(char));
f0ebd2 ¤   if (!*pszUserID) return FALSE;
e3af5a
13d9eb ¤   p = *pszUserID;
8a0005 ¤   GetDlgItemText (hDlg, uNameIDC, p, uUserIDLen);
cdaf5a
027737 ¤   if (uAddrLen > 0) {
daa41c ¤   ¤   p += uNameLen;
599b46 ¤   ¤   lstrcpy (p, " <");
c6af5a
3b89bf ¤   ¤   p += 2;
ba314a ¤   ¤   GetDlgItemText (hDlg, uAddrIDC, p, uUserIDLen);
e1af5a
c2ba0d ¤   ¤   p += uAddrLen;
c5a0f3 ¤   ¤   lstrcpy (p, ">");
f29371 ¤   }
ecefe6 }
19af5a
31af5a
9fbf56 //----------------------------------------------------|
ccb49a // Wipe edit box clean
4faf5a
77a1ba VOID·
2dc026 KMWipeEditBox (HWND hDlg, UINT uID)·
a6bb36 {
80b616 ¤   CHAR* p;
80cdd6 ¤   INT i;
dbaf5a
65621d ¤   i = SendDlgItemMessage (hDlg, uID, WM_GETTEXTLENGTH, 0, 0);
d94dd4 ¤   if (i > 0) {
440234 ¤   ¤   p = KMAlloc (i+1);
7d4400 ¤   ¤   if (p) {
0db668 ¤   ¤   ¤   FillMemory (p, i, ' ');
627804 ¤   ¤   ¤   SendDlgItemMessage (hDlg, uID, WM_SETTEXT, 0, (LPARAM)p);
400c04 ¤   ¤   ¤   KMFree (p);
fe0fe4 ¤   ¤   }
b49371 ¤   }
2befe6 }
03af5a
0cbf56 //----------------------------------------------------|
e864ea // get passphrase for key from user
07af5a
345a72 PGPError ·
3001b8 KMGetKeyPhrase (
e09cd4 ¤   ¤   PGPContextRef¤  ¤   context,
55a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
358d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
ebb7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
fde561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
33402c ¤   ¤   PGPKeyRef¤  ¤   ¤   key,
75fb51 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   ppszPhrase,
e51229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
8c8624 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength)·
ddbb36 {
255964 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_BadParams;
48f725 ¤   PGPBoolean¤ bSplit¤ ¤   ¤   = FALSE;
88d69b ¤   LPSTR¤  ¤   psz;
ea5d43 ¤   UINT¤   ¤   uFlags;
50af5a
9ff85a ¤   if (!ppPasskeyBuffer) return err;
9d31ed ¤   if (!piPasskeyLength) return err;
--2897 00050461af2401102b6 Page 4 of KMUser.c
e0af5a
1bb996 ¤   psz = NULL;
ab9100 ¤   *ppPasskeyBuffer = NULL;
71dfee ¤   *piPasskeyLength = 0;
37af5a
d96314 ¤   if (key)·
d544a4 ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropIsSecretShared, &bSplit);
a0af5a
d943ab ¤   do {
00d5f3 ¤   ¤   if (bSplit) {
7e249c ¤   ¤   ¤   err=PGPclReconstituteKey(
57fffc ¤   ¤   ¤   ¤   context,¤   ¤   ¤   // in context
0458f8 ¤   ¤   ¤   ¤   tlsContext,¤¤   ¤   // in TLS context
f47320 ¤   ¤   ¤   ¤   hwnd,¤  ¤   ¤   ¤   // in hwnd of parent
77e1bf ¤   ¤   ¤   ¤   keyset,¤¤   ¤   ¤   // in keyset
0c8349 ¤   ¤   ¤   ¤   key,¤   ¤   ¤   ¤   // in key
9b4ce4 ¤   ¤   ¤   ¤   ppPasskeyBuffer,¤   // out passkey buffer
1c0a74 ¤   ¤   ¤   ¤   piPasskeyLength);¤  // out passkey length
820fe4 ¤   ¤   }
4707e0 ¤   ¤   else {
0d852b ¤   ¤   ¤   if (key) uFlags = PGPCL_KEYPASSPHRASE;
b3e030 ¤   ¤   ¤   else uFlags = PGPCL_DECRYPTION;
d168f3 ¤   ¤   ¤   err = PGPclGetPhrase (
4ffffc ¤   ¤   ¤   ¤   context,¤   ¤   ¤   // in context
0e3e41 ¤   ¤   ¤   ¤   keyset,¤¤   ¤   ¤   // in main keyset
0c7320 ¤   ¤   ¤   ¤   hwnd,¤  ¤   ¤   ¤   // in hwnd of parent
928a1c ¤   ¤   ¤   ¤   szPrompt,¤  ¤   ¤   // in prompt
e0ab0c ¤   ¤   ¤   ¤   &psz,¤  ¤   ¤   ¤   // out phrase
0b0cbb ¤   ¤   ¤   ¤   NULL,¤  ¤   ¤   ¤   // in keyset
170460 ¤   ¤   ¤   ¤   NULL,¤  ¤   ¤   ¤   // in keyids
f1a26d ¤   ¤   ¤   ¤   0,¤ ¤   ¤   ¤   ¤   // in keyid count
d46162 ¤   ¤   ¤   ¤   &key,¤  ¤   ¤   ¤   // in/out key
184045 ¤   ¤   ¤   ¤   NULL,¤  ¤   ¤   ¤   // out options
04060b ¤   ¤   ¤   ¤   uFlags,¤¤   ¤   ¤   // in flags
834ce4 ¤   ¤   ¤   ¤   ppPasskeyBuffer,¤   // out passkey buffer
123ece ¤   ¤   ¤   ¤   piPasskeyLength,¤   // out passkey length
4bfe06 ¤   ¤   ¤   ¤   0,0,¤   ¤   ¤   ¤   // in min length/quality
5e7a9d ¤   ¤   ¤   ¤   tlsContext,¤¤   ¤   // in tlsContext,
74962b ¤   ¤   ¤   ¤   NULL);¤ ¤   ¤   ¤   // out AddedKeys
95af5a
2f0fe4 ¤   ¤   }
b6af5a
73a42f ¤   ¤   if (IsPGPError (err)) {
36487b ¤   ¤   ¤   if (psz) {
6affef ¤   ¤   ¤   ¤   PGPFreeData (psz);
5ba274 ¤   ¤   ¤   ¤   psz = NULL;
05a3a6 ¤   ¤   ¤   }
93cb51 ¤   ¤   ¤   if (*ppPasskeyBuffer) {
0b9a76 ¤   ¤   ¤   ¤   PGPFreeData (*ppPasskeyBuffer);
4b12d3 ¤   ¤   ¤   ¤   *ppPasskeyBuffer = NULL;
3fa3a6 ¤   ¤   ¤   }
e6cce3 ¤   ¤   ¤   PGPclErrorBox (hwnd, err);
1e0fe4 ¤   ¤   }
2707e0 ¤   ¤   else {
95225d ¤   ¤   ¤   if (ppszPhrase) *ppszPhrase = psz;
6e222e ¤   ¤   ¤   else KMFreePhrase (psz);
bc0fe4 ¤   ¤   }
14af5a
6c4ba9 ¤   } while (err == kPGPError_BadPassphrase);
12af5a
285ea8 ¤   return err;
51efe6 }
68af5a
34bf56 //----------------------------------------------------|
88d5ab // get passphrase for decryption from user
64af5a
505a72 PGPError ·
78f1aa KMGetDecryptionPhrase (
e49cd4 ¤   ¤   PGPContextRef¤  ¤   context,
64a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
c88d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
50b7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
--2bed 000bdd5bccf401102b6 Page 5 of KMUser.c
ab809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
087854 ¤   ¤   PGPKeyRef*¤ ¤   ¤   pkey,
edc4de ¤   ¤   PGPKeySetRef¤   ¤   keysetDecryption,
6d35a5 ¤   ¤   PGPUInt32¤  ¤   ¤   iKeyIDCount,
5200c6 ¤   ¤   PGPKeyID*¤  ¤   ¤   keyidsDecryption,
679a82 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetToAdd,
95fb51 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   ppszPhrase,
7f1229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
068624 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength)·
92bb36 {
775964 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_BadParams;
03f725 ¤   PGPBoolean¤ bSplit¤ ¤   ¤   = FALSE;
78d69b ¤   LPSTR¤  ¤   psz;
f3af5a
b2f85a ¤   if (!ppPasskeyBuffer) return err;
4031ed ¤   if (!piPasskeyLength) return err;
11af5a
3fb996 ¤   psz = NULL;
3c9100 ¤   *ppPasskeyBuffer = NULL;
99dfee ¤   *piPasskeyLength = 0;
1eaf5a
7f0667 ¤   if (pkey)·
15254a ¤   ¤   if (*pkey)
865ebd ¤   ¤   ¤   PGPGetKeyBoolean (*pkey, kPGPKeyPropIsSecretShared, &bSplit);
5caf5a
cf43ab ¤   do {
f3d5f3 ¤   ¤   if (bSplit) {
74249c ¤   ¤   ¤   err=PGPclReconstituteKey(
85fffc ¤   ¤   ¤   ¤   context,¤   ¤   ¤   // in context
8c58f8 ¤   ¤   ¤   ¤   tlsContext,¤¤   ¤   // in TLS context
227320 ¤   ¤   ¤   ¤   hwnd,¤  ¤   ¤   ¤   // in hwnd of parent
74bb26 ¤   ¤   ¤   ¤   keysetMain,¤¤   ¤   // in keyset
411e53 ¤   ¤   ¤   ¤   *pkey,¤ ¤   ¤   ¤   // in key
b64ce4 ¤   ¤   ¤   ¤   ppPasskeyBuffer,¤   // out passkey buffer
b30a74 ¤   ¤   ¤   ¤   piPasskeyLength);¤  // out passkey length
e90fe4 ¤   ¤   }
f207e0 ¤   ¤   else {
a668f3 ¤   ¤   ¤   err = PGPclGetPhrase (
5afffc ¤   ¤   ¤   ¤   context,¤   ¤   ¤   // in context
4b5888 ¤   ¤   ¤   ¤   keysetMain,¤¤   ¤   // in main keyset
fa7320 ¤   ¤   ¤   ¤   hwnd,¤  ¤   ¤   ¤   // in hwnd of parent
328a1c ¤   ¤   ¤   ¤   szPrompt,¤  ¤   ¤   // in prompt
4aab0c ¤   ¤   ¤   ¤   &psz,¤  ¤   ¤   ¤   // out phrase
4ea593 ¤   ¤   ¤   ¤   keysetDecryption,¤  // in keyset
cd7f7c ¤   ¤   ¤   ¤   keyidsDecryption,¤  // in keyids
0bac32 ¤   ¤   ¤   ¤   iKeyIDCount,¤   ¤   // in keyid count
006e2c ¤   ¤   ¤   ¤   pkey,¤  ¤   ¤   ¤   // in/out key
8a4045 ¤   ¤   ¤   ¤   NULL,¤  ¤   ¤   ¤   // out options
0cc85b ¤   ¤   ¤   ¤   PGPCL_DECRYPTION,¤  // in flags
624ce4 ¤   ¤   ¤   ¤   ppPasskeyBuffer,¤   // out passkey buffer
b83ece ¤   ¤   ¤   ¤   piPasskeyLength,¤   // out passkey length
46fe06 ¤   ¤   ¤   ¤   0,0,¤   ¤   ¤   ¤   // in min length/quality
607a9d ¤   ¤   ¤   ¤   tlsContext,¤¤   ¤   // in tlsContext,
b63326 ¤   ¤   ¤   ¤   pkeysetToAdd);¤ ¤   // out AddedKeys
43af5a
f40fe4 ¤   ¤   }
e5af5a
daa42f ¤   ¤   if (IsPGPError (err)) {
83487b ¤   ¤   ¤   if (psz) {
8cffef ¤   ¤   ¤   ¤   PGPFreeData (psz);
cda274 ¤   ¤   ¤   ¤   psz = NULL;
8da3a6 ¤   ¤   ¤   }
1dcb51 ¤   ¤   ¤   if (*ppPasskeyBuffer) {
c89a76 ¤   ¤   ¤   ¤   PGPFreeData (*ppPasskeyBuffer);
8b12d3 ¤   ¤   ¤   ¤   *ppPasskeyBuffer = NULL;
8ea3a6 ¤   ¤   ¤   }
c9cce3 ¤   ¤   ¤   PGPclErrorBox (hwnd, err);
ee0fe4 ¤   ¤   }
4607e0 ¤   ¤   else {
70225d ¤   ¤   ¤   if (ppszPhrase) *ppszPhrase = psz;
a0222e ¤   ¤   ¤   else KMFreePhrase (psz);
bd0fe4 ¤   ¤   }
--3469 00070ce3b6d401102b6 Page 6 of KMUser.c
e0af5a
9a4ba9 ¤   } while (err == kPGPError_BadPassphrase);
37af5a
405ea8 ¤   return err;
e2efe6 }
9caf5a
d5bf56 //----------------------------------------------------|
8e8778 // get passphrase for signing key from user
9eaf5a
1e5a72 PGPError ·
0519a3 KMGetSigningKeyPhrase (
1f9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
05a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
bb8d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
afb7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
08e561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
389cb9 ¤   ¤   BOOL¤   ¤   ¤   ¤   bRejectSplitKeys,
fc7854 ¤   ¤   PGPKeyRef*¤ ¤   ¤   pkey,
89fb51 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   ppszPhrase,
c41229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
c08624 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength)·
d9bb36 {
1b5803 ¤   PGPError¤   err¤¤   ¤   = kPGPError_BadParams;
c2d69b ¤   LPSTR¤  ¤   psz;
835d43 ¤   UINT¤   ¤   uFlags;
31af5a
a1f85a ¤   if (!ppPasskeyBuffer) return err;
5c31ed ¤   if (!piPasskeyLength) return err;
20af5a
c1b996 ¤   psz = NULL;
319100 ¤   *ppPasskeyBuffer = NULL;
22dfee ¤   *piPasskeyLength = 0;
d2af5a
ae4bf4 ¤   if (bRejectSplitKeys)
cd491b ¤   ¤   uFlags = PGPCL_REJECTSPLITKEYS;
170e24 ¤   else
f20b03 ¤   ¤   uFlags = 0;
e1af5a
80f0a4 ¤   err = PGPclGetPhrase (
ce8907 ¤   ¤   context,¤   ¤   ¤   // in context
1bdf7e ¤   ¤   keyset,¤¤   ¤   ¤   // in main keyset
334f08 ¤   ¤   hwnd,¤  ¤   ¤   ¤   // in hwnd of parent
0ade39 ¤   ¤   szPrompt,¤  ¤   ¤   // in prompt
0bddf7 ¤   ¤   &psz,¤  ¤   ¤   ¤   // out phrase
42589e ¤   ¤   NULL,¤  ¤   ¤   ¤   // in keyset
f85045 ¤   ¤   NULL,¤  ¤   ¤   ¤   // in keyids
894352 ¤   ¤   0,¤ ¤   ¤   ¤   ¤   // in keyid count
b018d7 ¤   ¤   pkey,¤  ¤   ¤   ¤   // in/out key
55096f ¤   ¤   NULL,¤  ¤   ¤   ¤   // out options
91963d ¤   ¤   uFlags,¤¤   ¤   ¤   // in flags
4ae192 ¤   ¤   ppPasskeyBuffer,¤   // out passkey buffer
1d93b8 ¤   ¤   piPasskeyLength,¤   // out passkey length
77b780 ¤   ¤   0,0,¤   ¤   ¤   ¤   // in min length/quality
321751 ¤   ¤   tlsContext,¤¤   ¤   // in tlsContext
ff97ad ¤   ¤   NULL);¤ ¤   ¤   ¤   // out AddedKeys
42af5a
b40971 ¤   if (IsPGPError (err)) {
b87392 ¤   ¤   if (psz) {
c37390 ¤   ¤   ¤   PGPFreeData (psz);
ec5411 ¤   ¤   ¤   psz = NULL;
0c0fe4 ¤   ¤   }
9c40ad ¤   ¤   if (*ppPasskeyBuffer) {
428226 ¤   ¤   ¤   PGPFreeData (*ppPasskeyBuffer);
20173e ¤   ¤   ¤   *ppPasskeyBuffer = NULL;
d70fe4 ¤   ¤   }
2c9371 ¤   }
f5665a ¤   else {
4ab3c5 ¤   ¤   if (ppszPhrase) *ppszPhrase = psz;
201f46 ¤   ¤   else KMFreePhrase (psz);
0b9371 ¤   }
a0af5a
702cc8 ¤   if (bRejectSplitKeys) {
--38ac 000e984369c401102b6 Page 7 of KMUser.c
866a47 ¤   ¤   if (err == kPGPError_KeyUnusableForSignature) {
554872 ¤   ¤   ¤   KMMessageBox (hwnd, IDS_CAPTION, IDS_SPLITKEYSNOTALLOWED,
44dd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
104e2b ¤   ¤   ¤   err = kPGPError_UserAbort;
d90fe4 ¤   ¤   }
669371 ¤   }
78af5a
f45ea8 ¤   return err;
3fefe6 }
d5af5a
8dbf56 //----------------------------------------------------|
bc64ea // get passphrase for key from user
8baf5a
f45a72 PGPError ·
4e69cb KMGetConfirmationPhrase (
01e958 ¤   ¤   PGPContextRef¤  context,
fb7851 ¤   ¤   HWND¤   ¤   ¤   hwnd,·
dc609e ¤   ¤   LPSTR¤  ¤   ¤   szPrompt,
3a8b6a ¤   ¤   PGPKeySetRef¤   keyset,
984a3f ¤   ¤   INT¤¤   ¤   ¤   iMinLen,
4a6627 ¤   ¤   INT¤¤   ¤   ¤   iMinQual,
6bae3b ¤   ¤   LPSTR*¤ ¤   ¤   ppszPhrase)
1fbb36 {
4d5803 ¤   PGPError¤   err¤¤   ¤   = kPGPError_BadParams;
43af5a
d3a8df ¤   if (!ppszPhrase) return err;
b2af5a
a8f0a4 ¤   err = PGPclGetPhrase (
038907 ¤   ¤   context,¤   ¤   ¤   // in context
32df7e ¤   ¤   keyset,¤¤   ¤   ¤   // in main keyset
104f08 ¤   ¤   hwnd,¤  ¤   ¤   ¤   // in hwnd of parent
3ade39 ¤   ¤   szPrompt,¤  ¤   ¤   // in prompt
067319 ¤   ¤   ppszPhrase,¤¤   ¤   // out phrase
7b589e ¤   ¤   NULL,¤  ¤   ¤   ¤   // in keyset
7d5045 ¤   ¤   NULL,¤  ¤   ¤   ¤   // in keyids
474352 ¤   ¤   0,¤ ¤   ¤   ¤   ¤   // in keyid count
86111c ¤   ¤   NULL,¤  ¤   ¤   ¤   // in/out key
b6096f ¤   ¤   NULL,¤  ¤   ¤   ¤   // out options
56ba68 ¤   ¤   PGPCL_ENCRYPTION,¤  // in flags
985b97 ¤   ¤   NULL,¤  ¤   ¤   ¤   // out passkey buffer
d46e35 ¤   ¤   NULL,¤  ¤   ¤   ¤   // out passkey length
6de924 ¤   ¤   iMinLen,iMinQual,¤  // min length/quality
5f16ff ¤   ¤   NULL,NULL);¤¤   ¤   // tlsContext/Added Keys
a9af5a
7f0971 ¤   if (IsPGPError (err)) {
6c9d39 ¤   ¤   if (*ppszPhrase) {
0a456d ¤   ¤   ¤   PGPFreeData (*ppszPhrase);
fa0a1d ¤   ¤   ¤   *ppszPhrase = NULL;
280fe4 ¤   ¤   }
c19371 ¤   }
1faf5a
c05ea8 ¤   return err;
0cefe6 }
9baf5a
f0bf56 //----------------------------------------------------|
4e198a // free passphrase for key
e4af5a
acfe80 VOID
eb5f21 KMFreePhrase (LPSTR pszPhrase)
44bb36 {
3afb33 ¤   if (pszPhrase) {
69cb26 ¤   ¤   PGPFreeData (pszPhrase);
199371 ¤   }
d2efe6 }
54af5a
dfbf56 //----------------------------------------------------|
f67beb // free passkey for key
dbaf5a
0cfe80 VOID
87a6a9 KMFreePasskey (PGPByte* pbyte, PGPSize size)
73bb36 {
e9ed0c ¤   if (pbyte) {
--8bf4 00187aa6100401102b6 Page 8 of KMUser.c
34e560 ¤   ¤   FillMemory (pbyte, size, 0x00);
81a63b ¤   ¤   PGPFreeData (pbyte);
a59371 ¤   }
87efe6 }
--4894 0002b100cd6401102b7 Page 1 of KMserver.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
72e8dd ¤   KMserver.c - handle communication with keyserver
2067c5 ¤
a1af5a
e6d7e7 ¤   $Id: KMserver.c,v 1.18 1998/08/12 18:31:24 pbj Exp $
84f7f7 ____________________________________________________________________________*/
51e610 #include "pgpPFLConfig.h"
eaaf5a
cac917 // project header files
96850a #include "pgpkmx.h"
92af5a
e093ed // external globals
199cad extern HINSTANCE g_hInst;
c1af5a
365bee // typedefs
3ff0f7 typedef struct {
d0f3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
9e7e47 ¤   PKEYMAN¤¤   ¤   pKM;
e98a97 ¤   PGPContextRef¤  context;
b5fead ¤   PGPKeySetRef¤   keyset;
f9587f ¤   INT¤¤   ¤   ¤   icount;
868194 ¤   PGPKeyID*¤  ¤   pkeyidList;
a20b8b } SERVERSTRUCT, *PSERVERSTRUCT;
64af5a
e9af5a
f83f64 static BOOL CALLBACK·
65d0c6 sAddKeyIDToList (
ac9d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
b7dd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
5abb36 {
fca8fd ¤   SERVERSTRUCT*¤  pss = (SERVERSTRUCT*)lParam;
34a485 ¤   PGPSigRef¤  ¤   cert;
d6af5a
06b366 ¤   cert = (PGPSigRef)(lptli->lParam);
14fd57 ¤   PGPGetKeyIDOfCertifier (cert, &pss->pkeyidList[pss->icount]);
f3af5a
11173c ¤   ++(pss->icount);
39af5a
a6c2e7 ¤   return TRUE;
36efe6 }
88af5a
324265 //¤ ___________________________________________________
e4465d //
2a7273 //¤ Send selected keys to keyserver
11af5a
037efe BOOL·
e9f8ef KMSendToServer (PKEYMAN pKM, UINT uServerFlags)·
57bb36 {
9af5c9 ¤   PGPKeySetRef¤   keysetSend¤ ¤   = kInvalidPGPKeySetRef;
4834e8 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_BadParams;
1abac4 ¤   INT¤¤   ¤   ¤   iKeyCount;
a5af5a
effcfe ¤   if ((uServerFlags == PGPCL_SPECIFIEDSERVER) &&·
d1e45b ¤   ¤   (pKM->keyserver.structSize == 0))
e0c7a1 ¤   {
6ca175 ¤   ¤   uServerFlags = PGPCL_USERIDBASEDSERVER;
e29371 ¤   }
b2af5a
c84878 ¤   KMGetSelectedKeys (pKM, &keysetSend, &iKeyCount);
c6da28 ¤   if (PGPRefIsValid (keysetSend)) {
709216 ¤   ¤   err = PGPclSendKeysToServer (pKM->Context, pKM->tlsContext,·
612d1e ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, uServerFlags, &pKM->keyserver,·
bde45f ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain, keysetSend);
a73aa3 ¤   ¤   PGPFreeKeySet (keysetSend);
689371 ¤   }
42af5a
f98761 ¤   if (err == kPGPError_ServerKeyAlreadyExists) {
c2f172 ¤   ¤   if (iKeyCount > 1) {
2b73ed ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
--dc9e 0007b127a45401102b7 Page 2 of KMserver.c
d3cafa ¤   ¤   ¤   ¤   ¤   ¤   IDS_KEYSALREADYONSERVER, MB_OK|MB_ICONINFORMATION);
d40fe4 ¤   ¤   }
5e07e0 ¤   ¤   else {
8273ed ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION,·
4bf810 ¤   ¤   ¤   ¤   ¤   ¤   IDS_KEYALREADYONSERVER, MB_OK|MB_ICONINFORMATION);
7b0fe4 ¤   ¤   }
449371 ¤   }
9b4ce9 ¤   else if (IsPGPError (err)) {
9994cd ¤   ¤   PGPclErrorBox (NULL, err);
819371 ¤   }
92665a ¤   else {
25aac4 ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_UPLOADOK,
33909c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
8e9371 ¤   }
dbaf5a
12c2e7 ¤   return TRUE;
9aefe6 }
d2af5a
9e4265 //¤ ___________________________________________________
89465d //
ebe93c //¤ Disable selected keys on keyserver
c1af5a
607efe BOOL·
83bc66 KMDisableOnServer (PKEYMAN pKM)·
adbb36 {
554f9e ¤   PGPKeySetRef¤   ¤   ¤   keysetDisable¤  = kInvalidPGPKeySetRef;
820eca ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_BadParams;
230de8 ¤   PGPKeyServerKeySpace¤   space;
85af5a
4f0e3c ¤   if (pKM->ulOptionFlags & KMF_PENDINGBUCKET)
836184 ¤   ¤   space = kPGPKeyServerKeySpace_Normal;
520e24 ¤   else
ed3e24 ¤   ¤   space = kPGPKeyServerKeySpace_Default;
afaf5a
92b307 ¤   KMGetSelectedKeys (pKM, &keysetDisable, NULL);
26d5c2 ¤   if (PGPRefIsValid (keysetDisable)) {
c11d24 ¤   ¤   err = PGPclDisableKeysOnServer (pKM->Context, pKM->tlsContext,
6eacd7 ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, &pKM->keyserver,·
2047d2 ¤   ¤   ¤   ¤   ¤   space, pKM->KeySetMain, keysetDisable);
81cfcd ¤   ¤   PGPFreeKeySet (keysetDisable);
e29371 ¤   }
e2af5a
5add60 ¤   if (IsPGPError (err)) PGPclErrorBox (NULL, err);
b5665a ¤   else {
40ca73 ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_DISABLEONSERVEROK,
10909c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
299371 ¤   }
f4af5a
28c2e7 ¤   return TRUE;
2aefe6 }
dfaf5a
d44265 //¤ ___________________________________________________
03465d //
aeb680 //¤ Delete selected keys from keyserver
1caf5a
707efe BOOL·
f73c53 KMDeleteFromServer (PKEYMAN pKM)·
5cbb36 {
a5f956 ¤   PGPKeySetRef¤   ¤   ¤   keysetDelete¤   = kInvalidPGPKeySetRef;
950eca ¤   PGPError¤   ¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_BadParams;
c60de8 ¤   PGPKeyServerKeySpace¤   space;
68af5a
230e3c ¤   if (pKM->ulOptionFlags & KMF_PENDINGBUCKET)
19a4c9 ¤   ¤   space = kPGPKeyServerKeySpace_Pending;
660e24 ¤   else
f93e24 ¤   ¤   space = kPGPKeyServerKeySpace_Default;
5faf5a
02f64f ¤   KMGetSelectedKeys (pKM, &keysetDelete, NULL);
fdaa53 ¤   if (PGPKeySetRefIsValid (keysetDelete)) {
86a0fd ¤   ¤   err = PGPclDeleteKeysFromServer (pKM->Context, pKM->tlsContext,
54acd7 ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, &pKM->keyserver,·
7b2aa9 ¤   ¤   ¤   ¤   ¤   space, pKM->KeySetMain, keysetDelete);
--7aa6 000549c01ae401102b7 Page 3 of KMserver.c
e45de5 ¤   ¤   PGPFreeKeySet (keysetDelete);
a99371 ¤   }
02af5a
8fdd60 ¤   if (IsPGPError (err)) PGPclErrorBox (NULL, err);
95665a ¤   else {
4459a1 ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_DELETEFROMSERVEROK,
65909c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONINFORMATION);
e99371 ¤   }
59af5a
30c2e7 ¤   return TRUE;
62efe6 }
6eaf5a
4a9268 //¤ _______________________________________________
fe465d //
668f0d // ·Update selected keys from server
4faf5a
607efe BOOL·
20c889 KMGetFromServerInternal (
6945dc ¤   ¤   PKEYMAN¤¤   pKM,·
67dc86 ¤   ¤   BOOL¤   ¤   bQueryAdd,·
d261cb ¤   ¤   BOOL¤   ¤   bWarn,
ebe278 ¤   ¤   BOOL¤   ¤   bGetSigners)·
3ebb36 {
db0c8a ¤   SERVERSTRUCT¤   ss;
26ad84 ¤   PGPKeySetRef¤   keysetGet¤  ¤   = kInvalidPGPKeySetRef;
08bd45 ¤   PGPKeySetRef¤   keysetFound¤¤   = kInvalidPGPKeySetRef;
461e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
9baf5a
c1890f ¤   ss.context = pKM->Context;
686716 ¤   ss.pKM = pKM;
47d282 ¤   ss.icount = 0;
9faf5a
f0fbcc ¤   // get selected keys
110064 ¤   if ((KMFocusedObjectType (pKM) == OBJECT_KEY) ||
8ee6b6 ¤   ¤   (KMFocusedObjectType (pKM) == OBJECT_USERID) ||
ab3950 ¤   ¤   (!bGetSigners))·
85c7a1 ¤   {
e139ad ¤   ¤   KMGetSelectedKeys (pKM, &keysetGet, NULL);
8692fa ¤   ¤   if (PGPRefIsValid (keysetGet)) {
867781 ¤   ¤   ¤   err = PGPclUpdateKeySetFromServer (pKM->Context,·
645a9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->tlsContext,
72ffdc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent,·
0c57d6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetGet,
452fb1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_USERIDBASEDSERVER,
795743 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain,
82a548 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keysetFound);
4e0b43 ¤   ¤   ¤   PGPFreeKeySet (keysetGet);
470fe4 ¤   ¤   }
b29371 ¤   }
aaaf5a
a1d424 ¤   // get signing keys
67665a ¤   else {
c1144e ¤   ¤   KMGetSelectedKeys (pKM, NULL, &ss.icount);
55c755 ¤   ¤   if (ss.icount) {
15f047 ¤   ¤   ¤   ss.pkeyidList =·
974b95 ¤   ¤   ¤   ¤   (PGPKeyID*)malloc ((ss.icount) * sizeof(PGPKeyID));
fe0b8a ¤   ¤   ¤   ss.icount = 0;
443e36 ¤   ¤   ¤   ss.lpfnCallback = sAddKeyIDToList;
d19756 ¤   ¤   ¤   TreeList_IterateSelected (pKM->hWndTree, &ss);
136ade ¤   ¤   ¤   err = PGPclSearchServerForKeyIDs (pKM->Context,
ec66b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->tlsContext,
0852aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent,·
2690dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ss.pkeyidList,
ec895f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ss.icount,·
6ee179 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_DEFAULTSERVER,
686b6b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->KeySetMain,
7a6cdd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keysetFound);
646fa8 ¤   ¤   ¤   free (ss.pkeyidList);
cb0fe4 ¤   ¤   }
139371 ¤   }
66af5a
54860b ¤   if (err == kPGPError_UserAbort) return FALSE;
--7a29 00106847ac3401102b7 Page 4 of KMserver.c
e0af5a
6f0971 ¤   if (IsPGPError (err)) {
0d4164 ¤   ¤   if (bWarn) PGPclErrorBox (NULL, err);
7f9371 ¤   }
e1665a ¤   else {
093e28 ¤   ¤   if (PGPRefIsValid (keysetFound)) {
958190 ¤   ¤   ¤   PGPUInt32 u;
bd3df5 ¤   ¤   ¤   PGPCountKeys (keysetFound, &u);
720235 ¤   ¤   ¤   if (u > 0) {
89c916 ¤   ¤   ¤   ¤   if (bQueryAdd) {
e4df85 ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys (pKM->Context, pKM->tlsContext,
8058a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKM->hWndParent, keysetFound, pKM->KeySetDisp);
942613 ¤   ¤   ¤   ¤   }
d8deaa ¤   ¤   ¤   ¤   else {
4637f8 ¤   ¤   ¤   ¤   ¤   if (pKM->ulOptionFlags & KMF_ENABLECOMMITS) {
018522 ¤   ¤   ¤   ¤   ¤   ¤   PGPAddKeys (keysetFound, pKM->KeySetDisp);
e8ee37 ¤   ¤   ¤   ¤   ¤   ¤   PGPCommitKeyRingChanges (pKM->KeySetDisp);
071c89 ¤   ¤   ¤   ¤   ¤   }
402613 ¤   ¤   ¤   ¤   }
eda3a6 ¤   ¤   ¤   }
c9e543 ¤   ¤   ¤   else {
4c8b43 ¤   ¤   ¤   ¤   KMMessageBox (pKM->hWndParent, IDS_CAPTION,
16f2b8 ¤   ¤   ¤   ¤   ¤   ¤   IDS_SERVERSEARCHFAIL, MB_OK|MB_ICONEXCLAMATION);
bfa3a6 ¤   ¤   ¤   }
8e3900 ¤   ¤   ¤   PGPFreeKeySet (keysetFound);
b20fe4 ¤   ¤   }
cf9371 ¤   }
9aaf5a
34c2e7 ¤   return TRUE;
89efe6 }
73af5a
1a9268 //¤ _______________________________________________
c5465d //
f58f0d // ·Update selected keys from server
d0af5a
b37efe BOOL·
247baa KMGetFromServer (PKEYMAN pKM)·
d4bb36 {
07d1e9 ¤   return KMGetFromServerInternal (pKM, TRUE, TRUE, TRUE);
32efe6 }
06af5a
--b05d 000d4d744e2401102b8 Page 1 of PGPcl.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
4ff734 ¤   PGPcl.c - PGP ClientLib DLL·
db67c5 ¤
b4af5a
753580 ¤   $Id: PGPcl.c,v 1.11.2.1 1998/09/04 15:42:19 pbj Exp $
dff7f7 ____________________________________________________________________________*/
eb8ad2 #include "pgpPFLConfig.h"¤
4faf5a
05c917 // project header files
465fcd #include "pgpclx.h"
90416b #include "treelist.h"
14af5a
c43ef0 #include <zmouse.h>
fbaf5a
0ce457 #define IMPORTDLGCLASS¤ ("PGPDLGCLASS")
7caf5a
c2999d // the following structure is used to get version information
bddd28 // from COMCTL32.DLL. ·This typedef is in the new system header
376320 // file <SHWLAPI.H>. ·Since not everyone may have this file,·
cf43ff // I've taken the structure and put it here.
c1e542 typedef struct _DllVersionInfo
35bb36 {
01fb66 ¤   DWORD cbSize;
c24190 ¤   DWORD dwMajorVersion; ··················// Major version
d80880 ¤   DWORD dwMinorVersion; ··················// Minor version
60df23 ¤   DWORD dwBuildNumber; ···················// Build number
97f315 ¤   DWORD dwPlatformID; ····················// DLLVER_PLATFORM_*
f7062c } DLLVERSIONINFO;
76af5a
3219ea #pragma data_seg ("PGPcl_shared")
58744f HWND g_hWndSplash = NULL;
266c63 #pragma data_seg ()
2daf5a
7366d8 // DLL globals
7b839a HINSTANCE¤  g_hInst;
d6fc39 CHAR¤   ¤   g_szHelpFile[MAX_PATH];
830fc0 UINT¤   ¤   g_uMouseWheelMessage = 0;
ceaf5a
a34265 //¤ ___________________________________________________
ea465d //
50eccf //¤ Register window class for selective import dialog
277072 //¤ This allows setting the icon to the PGPkeys icon
40af5a
dae6b2 static VOID
8eaa22 sRegisterSelectiveImportClass (VOID)
f3bb36 {
53f168 ¤   WNDCLASSEX¤ wc;
7daf5a
f06da9 ¤   // class 0x8002 is the "hardwired" class of standard dialogs
854151 ¤   wc.cbSize = sizeof (WNDCLASSEX);
a8fc97 ¤   GetClassInfoEx (NULL, MAKEINTRESOURCE(0x8002), &wc);
b6af5a
1201ce ¤   wc.lpszClassName = IMPORTDLGCLASS;
30fb96 ¤   wc.hIcon = LoadIcon (g_hInst, MAKEINTRESOURCE(IDI_KEYICON));
6cde94 ¤   wc.hInstance = g_hInst;
2daf5a
4a80a2 ¤   RegisterClassEx (&wc);
7fefe6 }
61af5a
774a49 //¤ ____________________________________________________________
65465d //
9f0df5 //¤ check if proper version of COMCTL32.DLL is installed
acaf5a
eb8289 #define MIN_MAJORVERSION¤   4
80add4 #define MIN_MINORVERSION¤   70
7daf5a
737b94 static PGPError ·
721f2e sCheckComctl32Version (VOID)·
d4bb36 {
--80f1 00085b411f3401102b8 Page 2 of PGPcl.c
a83ecb ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
da51b5 ¤   HINSTANCE¤  ¤   hComCtl;
22af5a
90df20 ¤   hComCtl = LoadLibrary ("comctl32.dll");
faaf5a
f5ab33 ¤   if (hComCtl) {
3ea020 ·¤  ¤   FARPROC¤pDllGetVersion;
8fde7b ··
ca3c6e ¤   ¤   pDllGetVersion = GetProcAddress (hComCtl, "DllGetVersion");
45e8c6 ···
878a38 ¤   ¤   if (pDllGetVersion) {
574b9c ¤   ¤   ¤   DLLVERSIONINFO¤ dvi;
50e51d ¤   ¤   ¤   LONG¤   ¤   ¤   hr;¤¤   // this should be an HRESULT
8ccf72 ······
cc9766 ¤   ¤   ¤   ZeroMemory (&dvi, sizeof(dvi));
b0781f ¤   ¤   ¤   dvi.cbSize = sizeof(dvi);
61e8c6 ···
965e06 ¤   ¤   ¤   hr = (LONG)(*pDllGetVersion)(&dvi);
d9cf72 ······
1e1921 ¤   ¤   ¤   if (!(hr & 0x01)) {¤¤   // HRESULT returns error in bit 0
5071a6 ¤   ¤   ¤   ¤   if (dvi.dwMajorVersion < MIN_MAJORVERSION)
b83a86 ¤   ¤   ¤   ¤   ¤   err = kPGPError_Win32_InvalidComctl32;
c3dda1 ¤   ¤   ¤   ¤   else if (dvi.dwMajorVersion == MIN_MAJORVERSION) {
04f69a ¤   ¤   ¤   ¤   ¤   if (dvi.dwMinorVersion < MIN_MINORVERSION)
a73a64 ¤   ¤   ¤   ¤   ¤   ¤   err = kPGPError_Win32_InvalidComctl32;
b12613 ¤   ¤   ¤   ¤   }
a2a3a6 ¤   ¤   ¤   }
236b93 ¤   ¤   ¤   else·
b33dbd ¤   ¤   ¤   ¤   err = kPGPError_Win32_InvalidComctl32;
a40fe4 ¤   ¤   }
b507e0 ¤   ¤   else {
412c9a ¤   ¤   ¤   err = kPGPError_Win32_InvalidComctl32;
880fe4 ¤   ¤   }
34af5a
171bc8 ¤   ¤   FreeLibrary(hComCtl);
519371 ¤   }
184264 ¤   else·
8bf428 ¤   ¤   err = kPGPError_Win32_InvalidComctl32;
93af5a
a0af5a
3d5ea8 ¤   return err;
5eefe6 }
a6af5a
974a49 //¤ ____________________________________________________________
e9465d //
62efa6 //¤ Dialog procedure for driver warning dialog
d5af5a
e43f64 static BOOL CALLBACK·
03a098 sDriverWarnDlgProc (
6d3a3a ¤   ¤   HWND¤   hDlg,·
deeb77 ¤   ¤   UINT¤   uMsg,·
a50303 ¤   ¤   WPARAM¤ wParam,
6fc0b8 ¤   ¤   LPARAM¤ lParam)·
72bb36 {
b231cf ¤   switch(uMsg) {
ecaf5a
882940 ¤   case WM_INITDIALOG:
77836c ¤   ¤   return TRUE;
b7af5a
c0d1d3 ¤   case WM_COMMAND :
d2379d ¤   ¤   switch(LOWORD (wParam)) {
4daf5a
449903 ¤   ¤   case IDOK :·
6b906b ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_NOMOREWARNINGS) == BST_CHECKED)
48eb70 ¤   ¤   ¤   ¤   EndDialog (hDlg, 2);
7ebb8c ¤   ¤   ¤   else
40cebd ¤   ¤   ¤   ¤   EndDialog (hDlg, 1);
94cdcb ¤   ¤   ¤   break;
b9af5a
92b6bb ¤   ¤   case IDCANCEL :
78ef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
85cdcb ¤   ¤   ¤   break;
--77ba 0002c7e2506401102b8 Page 3 of PGPcl.c
b50fe4 ¤   ¤   }
ab836c ¤   ¤   return TRUE;
059371 ¤   }
a0a230 ¤   return FALSE;
d7efe6 }
85af5a
b9af5a
6df993 //________________________________________
27465d //
f7cd38 //¤ code to start PGPmemlock driver in NT
6d65e4 //¤ ¤   driver must already have been copied to·
b729c3 //¤ ¤   c:\winnt\system32\drivers directory and
d0a10f //¤ ¤   appropriate registry entries created
83af5a
847156 #define DRIVERNAME¤ ¤   ¤   ¤   "PGPmemlock"
932e7a #define DRIVER_NO_ERROR¤¤   ¤   0
4d6b91 #define DRIVER_NOT_WINNT¤   ¤   1
1dc10e #define DRIVER_ACCESS_ERROR¤¤   2
743e4c #define DRIVER_CREATE_FAIL¤ ¤   3
48b8b7 #define DRIVER_ALREADY_STARTED¤ 4
328178 #define DRIVER_MISC_ERROR¤  ¤   5
56af5a
bcec6d PGPError PGPclExport
fea455 PGPclStartMemLockDriver (VOID)
55bb36 {
279d10 ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_UnknownError;
405232 ¤   SC_HANDLE¤  ¤   schSCMan¤   = NULL;
1e4e79 ¤   SC_HANDLE¤  ¤   schServ¤¤   = NULL;
496bc0 ¤   DWORD¤  ¤   ¤   dwErr;
431be7 ¤   BOOL¤   ¤   ¤   bRet;
d23731 ¤   OSVERSIONINFO¤  osid;
298345 ¤   SERVICE_STATUS¤ ss;
dda88e ¤   CHAR¤   ¤   ¤   szPath[MAX_PATH];
7aaf5a
c2fcd3 ¤   // check if we're running under NT
5cce5f ¤   osid.dwOSVersionInfoSize = sizeof (osid);
6c6d53 ¤   GetVersionEx (&osid);
bbaf5a
b672bc ¤   // no => just stop here
405486 ¤   if (osid.dwPlatformId != VER_PLATFORM_WIN32_NT) {
f84aff ¤   ¤   err = DRIVER_NOT_WINNT;
a0262d ¤   ¤   goto done;
819371 ¤   }
26af5a
469b20 ¤   // yes, open service control manager
f206ed ¤   schSCMan = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE);
81c72c ¤   if (schSCMan == NULL) {
31872a ¤   ¤   dwErr = GetLastError();
5d2848 ¤   ¤   if (dwErr == ERROR_ACCESS_DENIED) {
213518 ¤   ¤   ¤   err = DRIVER_ACCESS_ERROR;
631dc4 ¤   ¤   ¤   goto done;
e70fe4 ¤   ¤   }
3d07e0 ¤   ¤   else {
2e8d58 ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
8f1dc4 ¤   ¤   ¤   goto done;
980fe4 ¤   ¤   }
099371 ¤   }
50cc3e ¤   // OK, success open of service control manager
82665a ¤   else {
a4e622 ¤   ¤   // try to open service
f9a511 ¤   ¤   schServ = OpenService (schSCMan, DRIVERNAME,·
25f6dc ¤   ¤   ¤   ¤   ¤   ¤   SERVICE_START|SERVICE_QUERY_STATUS);
acaf5a
2e708c ¤   ¤   if (schServ == NULL) {
b6d1be ¤   ¤   ¤   // couldn't open service
86c521 ¤   ¤   ¤   dwErr = GetLastError ();
8e6d25 ¤   ¤   ¤   if (dwErr != ERROR_SERVICE_DOES_NOT_EXIST) {
b088b5 ¤   ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
31ff25 ¤   ¤   ¤   ¤   goto done;
7fa3a6 ¤   ¤   ¤   }
caaf5a
2c594c ¤   ¤   ¤   // try to create new service ...
--806d 0004d324463401102b8 Page 4 of PGPcl.c
f0baf4 ¤   ¤   ¤   GetSystemDirectory (szPath, sizeof(szPath));
210904 ¤   ¤   ¤   if (szPath[lstrlen (szPath) -1] != '\\')
2b4a95 ¤   ¤   ¤   ¤   lstrcat (szPath, "\\");
034502 ¤   ¤   ¤   lstrcat (szPath, "drivers\\");
c3e35b ¤   ¤   ¤   lstrcat (szPath, DRIVERNAME);
983077 ¤   ¤   ¤   lstrcat (szPath, ".sys");
e4bbf3 ¤   ¤   ¤   schServ = CreateService (schSCMan, DRIVERNAME, DRIVERNAME,
a56a14 ¤   ¤   ¤   ¤   ¤   ¤   SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
fdcc3f ¤   ¤   ¤   ¤   ¤   ¤   SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
3754d5 ¤   ¤   ¤   ¤   ¤   ¤   szPath, NULL, NULL, NULL, NULL, NULL);
47af5a
8dfcf3 ¤   ¤   ¤   if (schServ == NULL) {
152de1 ¤   ¤   ¤   ¤   err = DRIVER_CREATE_FAIL;
e2ff25 ¤   ¤   ¤   ¤   goto done;
74a3a6 ¤   ¤   ¤   }
e50fe4 ¤   ¤   }
0baf5a
97c9ef ¤   ¤   bRet = QueryServiceStatus (schServ, &ss);
9d1413 ¤   ¤   if (!bRet) {
8e8d58 ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
e11dc4 ¤   ¤   ¤   goto done;
020fe4 ¤   ¤   }
7e9f65 ¤   ¤   if (ss.dwCurrentState == SERVICE_STOPPED) {
9724da ¤   ¤   ¤   bRet = StartService (schServ, 0, NULL);
1ca5c2 ¤   ¤   ¤   if (!bRet) {
27c0cc ¤   ¤   ¤   ¤   dwErr = GetLastError ();
0888b5 ¤   ¤   ¤   ¤   err = DRIVER_MISC_ERROR;
28ff25 ¤   ¤   ¤   ¤   goto done;
88a3a6 ¤   ¤   ¤   }
a30fe4 ¤   ¤   }
7307e0 ¤   ¤   else {
7272a7 ¤   ¤   ¤   err = DRIVER_ALREADY_STARTED;
051dc4 ¤   ¤   ¤   goto done;
cf0fe4 ¤   ¤   }
fc9371 ¤   }
f54929 ¤   err = DRIVER_NO_ERROR;
fbaf5a
b3a1c0 done :
a047a1 ¤   // cleanup service handle
58a967 ¤   if (schServ)
48c0d2 ¤   ¤   CloseServiceHandle (schServ);
90af5a
2a5c26 ¤   // clean up service control manager
7c8c55 ¤   if (schSCMan)
32c14f ¤   ¤   CloseServiceHandle (schSCMan);
38af5a
df5ea8 ¤   return err;
9aefe6 }
ecaf5a
e8af5a
a94a49 //¤ ____________________________________________________________
8e465d //
38af80 //¤ check if page-locking driver is working by attempting to lock memory
a8af5a
967b94 static PGPError ·
ed66b7 sCheckMemLockDriver (VOID)·
fdbb36 {
a73ecb ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
238034 ¤   PGPContextRef¤  context¤¤   = kInvalidPGPContextRef;
2b16da ¤   PGPPrefRef¤ ¤   prefs¤  ¤   = kInvalidPGPPrefRef;
8bdbb6 ¤   PGPBoolean¤ ¤   bWarn¤  ¤   = TRUE;
aa993e ¤   PGPFlags¤   ¤   flags¤  ¤   = 0;
474dae ¤   LPVOID¤ ¤   ¤   pmem¤   ¤   = NULL;
c39116 ¤   INT¤¤   ¤   ¤   iret¤   ¤   = 0;
32af5a
a31d48 ¤   PGPclStartMemLockDriver ();
beaf5a
943dc9 ¤   err = PGPNewContext (kPGPsdkAPIVersion, &context); CKERR;
64af5a
f36848 ¤   pmem = PGPNewSecureData (PGPGetContextMemoryMgr (context), 32, 0);
f42f15 ¤   if (!pmem) {
4dbce1 ¤   ¤   err = kPGPError_OutOfMemory;
--078d 00058b881a8401102b8 Page 5 of PGPcl.c
e8262d ¤   ¤   goto done;
a99371 ¤   }
e7af5a
ec3efa ¤   flags = PGPGetMemoryMgrDataInfo (pmem);
80b4f3 ¤   if (!(flags & kPGPMemoryMgrBlockInfo_NonPageable)) {
e49d5e ¤   ¤   // memory is pageable, thus the driver is not working
939396 ¤   ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (context), &prefs);
25b601 ¤   ¤   PGPGetPrefBoolean (prefs, kPGPPrefWarnOnMemLockFailure, &bWarn);
51af5a
928633 ¤   ¤   if (bWarn) {
7a7976 ¤   ¤   ¤   iret = DialogBox (g_hInst, MAKEINTRESOURCE(IDD_DRIVERWARNING),
8a4aae ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, sDriverWarnDlgProc);
5ae48c ¤   ¤   ¤   switch (iret) {
a08004 ¤   ¤   ¤   case 0 :
7d4067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
b1f622 ¤   ¤   ¤   ¤   break;
43af5a
d8b972 ¤   ¤   ¤   case 2 :
b8aead ¤   ¤   ¤   ¤   PGPSetPrefBoolean (prefs,kPGPPrefWarnOnMemLockFailure,FALSE);
a49cbf ¤   ¤   ¤   case 1 :
a9bd37 ¤   ¤   ¤   ¤   err = kPGPError_NoErr;
82f622 ¤   ¤   ¤   ¤   break;
86a3a6 ¤   ¤   ¤   }
7b0fe4 ¤   ¤   }
07af5a
f1a086 ¤   ¤   PGPclCloseClientPrefs (prefs, TRUE);
f99371 ¤   }
2eaf5a
7fa1c0 done :
3ae46e ¤   if (pmem)
c1c85c ¤   ¤   PGPFreeData (pmem);
112739 ¤   if (PGPContextRefIsValid (context))
a4669e ¤   ¤   PGPFreeContext (context);
e9d83c ·
a35ea8 ¤   return err;
71efe6 }
6faf5a
a24a49 //¤ ____________________________________________________________
2a465d //
b14d24 //¤ initialize common controls
7daf5a
61b333 static VOID·
1b32ab sInitControls (VOID)
ebbb36 {
0d57fa ¤   INITCOMMONCONTROLSEX¤   icex;
49c8f2 ¤   HINSTANCE¤  ¤   ¤   ¤   hComCtl;
7eaf5a
a0af5a
b5605e ¤   // Ensure that the common control DLL is loaded.
5a3500 ¤   InitCommonControls ();
00af5a
a42593 ¤   // Ensure that the custom control DLL is loaded.
f828bd ¤   InitTreeListControl ();
98af5a
bedf20 ¤   hComCtl = LoadLibrary ("comctl32.dll");
5aab33 ¤   if (hComCtl) {
29b8a4 ·¤  ¤   FARPROC¤pInitCommonControlsEx;
b0de7b ··
dd4bf8 ¤   ¤   pInitCommonControlsEx =·
763a23 ¤   ¤   ¤   GetProcAddress (hComCtl, "InitCommonControlsEx");
0ce8c6 ···
f448b8 ¤   ¤   if (pInitCommonControlsEx) {
f8af5a
81b6d2 ¤   ¤   ¤   // Ensure that the extended common controls are loaded
bad6d4 ¤   ¤   ¤   icex.dwSize = sizeof(icex);
af9941 ¤   ¤   ¤   icex.dwICC = ICC_BAR_CLASSES|ICC_DATE_CLASSES;
861e90 ¤   ¤   ¤   (*pInitCommonControlsEx)(&icex);
330fe4 ¤   ¤   }
1daf5a
671bc8 ¤   ¤   FreeLibrary(hComCtl);
ad9371 ¤   }
58efe6 }
--da7d 000934d8815401102b8 Page 6 of PGPcl.c
e0af5a
284a49 //¤ ____________________________________________________________
46465d //
75f0d1 //¤ initialize DLL
89af5a
449d43 PGPError PGPclExport·
70b24c PGPclInitLibrary (PGPContextRef context)·
b2bb36 {
9861e0 ¤   PGPError¤   err;
1faf5a
ee6ad9 ¤   err = sCheckComctl32Version ();
ea0fc8 ¤   if (IsPGPError (err))·
43c9db ¤   ¤   return err;
49af5a
8db121 ¤   err = sCheckMemLockDriver ();
7a0fc8 ¤   if (IsPGPError (err))·
d6c9db ¤   ¤   return err;
5baf5a
c6b16b ¤   // register the mouse wheel message
60f512 ¤   g_uMouseWheelMessage = RegisterWindowMessage (MSH_MOUSEWHEEL);
a3af5a
d8271c ¤   sInitControls ();
53af5a
2d4ce1 ¤   PGPInitPassphraseCaches (context);
63af5a
075ea8 ¤   return err;
79efe6 }
62af5a
e34a49 //¤ ____________________________________________________________
25465d //
73ade7 //¤ close down DLL
79af5a
7b9d43 PGPError PGPclExport·
bd7e90 PGPclCloseLibrary (VOID)·
63bb36 {
da4f04 ¤   PGPClosePassphraseCaches ();
f0af5a
03151e ¤   return kPGPError_NoErr;
93efe6 }
e9af5a
9e4a49 //¤ ____________________________________________________________
f1465d //
a8d6ef //¤ get PGPkeys path from registry and append Help file name·
f7af5a
24b333 static VOID·
006013 sGetHelpFilePath (VOID)·
c5bb36 {
ccd955 ¤   CHAR sz[128];
59af5a
a260f0 ¤   PGPclGetPGPPath (g_szHelpFile, sizeof(g_szHelpFile));
c9af5a
4de7c6 ¤   LoadString (g_hInst, IDS_HELPFILENAME, sz, sizeof(sz));
1d3669 ¤   lstrcat (g_szHelpFile, sz);
38efe6 }
87af5a
52af5a
17a291 //¤ ____________________
38465d //
c2f18d //¤ DLL entry/exit point
26af5a
6d5b4e BOOL WINAPI·
7cb4c1 DllMain (
b93c9f ¤   ¤   ·HINSTANCE hInstDll,·
925ec7 ¤   ¤   ·DWORD dwReason,·
14c091 ¤   ¤   ·LPVOID lpvReserved)·
16bb36 {
6aaf5a
ff80bf ¤   switch (dwReason) {
42c556 ¤   case DLL_PROCESS_ATTACH:
3e2dd6 ¤   ¤   g_hInst = hInstDll;
d2cfe2 ¤   ¤   sGetHelpFilePath ();
93995b ¤   ¤   sRegisterSelectiveImportClass ();
--0a22 001eb62ee3f401102b8 Page 7 of PGPcl.c
4f2f68 ¤   ¤   break;
3eab2e ····case DLL_THREAD_ATTACH:
6c2d5f ········break;
6b1653 ····case DLL_THREAD_DETACH:
ea2f68 ¤   ¤   break;
95de09 ····case DLL_PROCESS_DETACH:
262f68 ¤   ¤   break;
af6fe7 ····}
088011 ····return TRUE;
deefe6 }
6caf5a
ebaf5a
--db3b 00186e8322d401102b9 Page 1 of PGPcl.def
ec0717 ; PGPcl.def : Declares the module parameters for the DLL.
4faf5a
bc257e LIBRARY ·····"PGP60cl
a57a51 DESCRIPTION ·'PGP ClientLib DLL'
e1af5a
59ef2b EXPORTS
68e6d0 ¤   PGPOpenPrefFile
b085e7 ¤   PGPSavePrefFile
46b0c5 ¤   PGPClosePrefFile
f2cb61 ¤   PGPGetPrefFileSpec
82b7a0 ¤   PGPGetPrefData
aba70e ¤   PGPSetPrefData
204f42 ¤   PGPRemovePref
e1df44 ¤   PGPDisposePrefData
edaf5a
09d453 ¤   PGPGetPrefBoolean
f45e0e ¤   PGPSetPrefBoolean
b136cd ¤   PGPGetPrefNumber
6813a3 ¤   PGPSetPrefNumber
aa96e2 ¤   PGPGetPrefStringAlloc
88f96b ¤   PGPGetPrefStringBuffer
255028 ¤   PGPSetPrefString
acaf5a
ccfd0a ¤   PGPGetKeyServerPrefs
c2f02a ¤   PGPSetKeyServerPrefs
633854 ¤   PGPCreateKeyServerPath
3ae2e9 ¤   PGPDisposeKeyServerPath
68f5bd ¤   PGPGetKeyServerURL
3bd808 ¤   PGPFindEmailDomain
86af5a
--b77c 0000a63cc32401102ba Page 1 of PGPcl.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
77fca7 #include "..\..\shared\pgpBuildFlags.h"
1b6c0e /////////////////////////////////////////////////////////////////////////////
887b93 #undef APSTUDIO_READONLY_SYMBOLS
90af5a
5e6c0e /////////////////////////////////////////////////////////////////////////////
70f930 // English (U.S.) resources
c7af5a
9a1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
caec08 #ifdef _WIN32
72e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
989c1c #pragma code_page(1252)
321f8e #endif //_WIN32
37af5a
2ff860 #ifdef APSTUDIO_INVOKED
896c0e /////////////////////////////////////////////////////////////////////////////
bc465d //
215733 // TEXTINCLUDE
b8465d //
95af5a
8886ef 1 TEXTINCLUDE DISCARDABLE·
be4523 BEGIN
37541e ····"resource.h\0"
a7e0d1 END
b4af5a
197037 2 TEXTINCLUDE DISCARDABLE·
4e4523 BEGIN
c0eb23 ····"#include ""afxres.h""\r\n"
474449 ····"#include ""..\\..\\shared\\pgpBuildFlags.h""\0"
8de0d1 END
dbaf5a
24227f 3 TEXTINCLUDE DISCARDABLE·
4c4523 BEGIN
508c01 ····"#include ""CLSplash.rc""\r\n"
7ee153 ····"#include ""PGPclVer.rc""\r\n"
75e40d ····"#include ""CLNag.rc""\0"
56e0d1 END
7faf5a
cb69ab #endif ···// APSTUDIO_INVOKED
5daf5a
90af5a
c96c0e /////////////////////////////////////////////////////////////////////////////
60465d //
e6b090 // Dialog
91465d //
23af5a
90bdd1 IDD_PREF1 DIALOG DISCARDABLE ·0, 0, 240, 180
5a388a STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP | WS_CAPTION |·
6bf85b ····WS_SYSMENU
6f5af8 CAPTION "Dialog"
34309f FONT 8, "MS Sans Serif"
4b4523 BEGIN
b5faaf ····GROUPBOX ·······"P&ublic Keyring File",IDC_STATIC,7,12,226,47,WS_GROUP
0a5d86 ····EDITTEXT ·······IDC_PUBLICKEYRING,13,23,214,14,ES_AUTOHSCROLL
3df6a4 ····PUSHBUTTON ·····"&Browse ...",IDC_SETPUBLICKEYRING,177,41,50,14
b2bd13 ····GROUPBOX ·······"P&rivate Keyring File",IDC_STATIC,7,67,226,47,WS_GROUP
dcaee4 ····EDITTEXT ·······IDC_PRIVATEKEYRING,13,79,214,14,ES_AUTOHSCROLL
99ba08 ····PUSHBUTTON ·····"Bro&wse ...",IDC_SETPRIVATEKEYRING,177,96,50,14
ebe99c ····GROUPBOX ·······"Random &Seed File",IDC_STATIC,7,123,226,47,WS_GROUP
779787 ····EDITTEXT ·······IDC_RNGSEEDFILE,13,135,214,14,ES_AUTOHSCROLL
8cc9af ····PUSHBUTTON ·····"Brows&e ...",IDC_SETRNGSEEDFILE,177,152,50,14
63e0d1 END
0aaf5a
--cdab 00020434674401102ba Page 2 of PGPcl.rc
49078e IDD_PREF0 DIALOG DISCARDABLE ·0, 0, 240, 180
a7388a STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP | WS_CAPTION |·
01f85b ····WS_SYSMENU
0f5af8 CAPTION "Dialog"
3a309f FONT 8, "MS Sans Serif"
614523 BEGIN
4fb791 ····GROUPBOX ·······"Encryption and Signing Preferences",IDC_STATIC1,5,8,226,
133dea ····················116
67bef3 ····CONTROL ········"Always &encrypt to default key",IDC_ENCRYPTTOSELF,
2cc50a ····················"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,20,23,
21608e ····················115,10
210a54 ····CONTROL ········"&Faster key generation",IDC_USEFASTKEYGEN,"Button",
0a22ff ····················BS_AUTOCHECKBOX | WS_TABSTOP,20,41,84,10
3bdf52 ····CONTROL ········"Cache &decryption passphrases for",
e6a255 ····················IDC_DECRYPTCACHEENABLE,"Button",BS_AUTOCHECKBOX |·
b3e049 ····················WS_GROUP | WS_TABSTOP,20,59,123,10
9350ec ····LTEXT ··········"Time picker",IDC_DECRYPTCACHETIME,147,57,56,14,NOT·
c21580 ····················WS_VISIBLE | WS_BORDER | NOT WS_GROUP
10b84c ····CONTROL ········"Cache &signing passphrases for",IDC_SIGNCACHEENABLE,
12d827 ····················"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,20,79,
3a5b16 ····················113,10
84c8c1 ····LTEXT ··········"Time picker",IDC_SIGNCACHETIME,137,77,56,14,NOT·
581580 ····················WS_VISIBLE | WS_BORDER | NOT WS_GROUP
e2a229 ····LTEXT ··········"&Comment\nblock (optional)",IDC_STATIC,20,95,50,19
cfe85c ····EDITTEXT ·······IDC_COMMENTBLOCK,76,97,146,14,ES_AUTOHSCROLL
d40ed4 ····GROUPBOX ·······"File Wiping",IDC_STATIC2,7,132,226,40
88b1f9 ····CONTROL ········"&Warn before wiping",IDC_WIPECONFIRM,"Button",
cd1f0a ····················BS_AUTOCHECKBOX | WS_TABSTOP,20,150,77,10
e7629a ····LTEXT ··········"&Number of passes :",IDC_NUMPASSESTEXT,117,151,64,8
e167ff ····EDITTEXT ·······IDC_NUMPASSES,185,148,24,14,ES_AUTOHSCROLL | ES_NUMBER
48a651 ····CONTROL ········"Spin1",IDC_NUMPASSESSPIN,"msctls_updown32",
d24d6b ····················UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |·
c49b61 ····················UDS_ARROWKEYS,209,148,9,15
d1e0d1 END
d5af5a
fe983b IDD_PREF2 DIALOGEX 0, 0, 240, 180
ae4300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
5a5af8 CAPTION "Dialog"
0e3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
474523 BEGIN
c0ad9f ····GROUPBOX ·······"Email Preferences",IDC_STATIC1,7,10,226,152,0,
fd5f73 ····················WS_EX_NOPARENTNOTIFY
b49679 ····CONTROL ········"&Use PGP/MIME when sending email",IDC_USEPGPMIME,"Button",
8205ef ····················BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,25,28,165,10
65a475 ····CONTROL ········"&Encrypt new messages by default",IDC_ENCRYPTBYDEFAULT,
174cce ····················"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,25,45,
4b5d32 ····················151,10
ff6fbe ····CONTROL ········"&Sign new messages by default",IDC_SIGNBYDEFAULT,"Button",
4b4e80 ····················BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,25,62,134,10
2bc36f ····CONTROL ········"Automatically &decrypt/verify when opening messages",
672c0a ····················IDC_AUTODECRYPT,"Button",BS_AUTOCHECKBOX | WS_GROUP |·
19e476 ····················WS_TABSTOP,25,79,183,10
334a4f ····CONTROL ········"&Word wrap clear-signed messages",IDC_WRAPENABLE,"Button",
a73ccb ····················BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,25,98,121,11
0f9937 ····LTEXT ··········"at colu&mn",IDC_STATIC,147,99,33,8
3bf45b ····EDITTEXT ·······IDC_WRAPNUMBER,183,97,20,13,ES_AUTOHSCROLL | ES_NUMBER
e61f37 ····LTEXT ··········"Note :",IDC_STATIC2,25,129,20,8
753b7f ····LTEXT ··········"some of these options may not be available with all plugin¶
fdba64 s.",
969ee6 ····················IDC_STATIC3,49,129,150,18
d6e0d1 END
e9af5a
bfd7d8 IDD_HELPABOUT DIALOG DISCARDABLE ·0, 0, 332, 133
4c62ae STYLE DS_CENTER | WS_POPUP | WS_VISIBLE | WS_BORDER
1d309f FONT 8, "MS Sans Serif"
584523 BEGIN
62ff3e ····DEFPUSHBUTTON ··"&OK",IDOK,279,114,44,13
88b118 ····PUSHBUTTON ·····"&Credits",IDC_CREDITS,161,114,44,13
7a8e04 ····PUSHBUTTON ·····"&www.pgp.com",IDC_WWWLINK,214,114,57,13
b4e0d1 END
75af5a
20c78f IDD_SPLASH DIALOGEX 0, 0, 147, 72
--ee49 0002c3594eb401102ba Page 3 of PGPcl.rc
a8c5ee STYLE DS_SYSMODAL | DS_NOIDLEMSG | DS_CENTER | WS_POPUP
a9482f EXSTYLE WS_EX_TOOLWINDOW
303884 FONT 8, "MS Sans Serif", 0, 0, 0x1
934523 BEGIN
b46698 ····DEFPUSHBUTTON ··"&Later",IDOK,93,51,47,14
63118a ····DEFPUSHBUTTON ··"&Buy Now!",IDC_BUYNOW,37,51,50,14
b7e0d1 END
e0af5a
d1a10a IDD_NAG DIALOG DISCARDABLE ·0, 0, 175, 150
88467f STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE
69309f FONT 8, "MS Sans Serif"
994523 BEGIN
a69e1e ····DEFPUSHBUTTON ··"&Not yet...",IDOK,110,80,60,14
0a2d7d ····PUSHBUTTON ·····"&Order Now!",IDC_WWWLINK,110,65,60,14
47e0d1 END
3baf5a
32fed0 IDD_PREF4 DIALOG DISCARDABLE ·0, 0, 240, 180
624300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
355af8 CAPTION "Dialog"
d0309f FONT 8, "MS Sans Serif"
d34523 BEGIN
3f0d40 ····GROUPBOX ·······"Encryption",IDC_STATIC1,7,7,226,63
20ccfb ····LTEXT ··········"&Preferred algorithm :",IDC_STATIC,34,18,64,8,NOT·
b41efd ····················WS_GROUP
57b76c ····COMBOBOX ·······IDC_PREFERREDALG,116,16,68,46,CBS_DROPDOWNLIST |·
d5be8a ····················WS_VSCROLL | WS_TABSTOP
510210 ····GROUPBOX ·······"Allowed Algorithms",IDC_STATIC4,28,35,182,27
401eaf ····CHECKBOX ·······"&CAST",IDC_ENABLECAST,44,47,38,10,WS_DISABLED |·
ab1efd ····················WS_GROUP
cce73d ····CHECKBOX ·······"&IDEA",IDC_ENABLEIDEA,91,47,40,10,WS_DISABLED
2d43c2 ····CHECKBOX ·······"&TripleDES",IDC_ENABLE3DES,146,47,49,10,WS_DISABLED
7ee0e6 ····GROUPBOX ·······"Trust Model",IDC_STATIC2,7,77,226,58
b21f3f ····CONTROL ········"&Display marginal validity level",IDC_DISPMARGVALIDITY,
4b7185 ····················"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,31,90,
e06281 ····················147,10
f2afed ····CONTROL ········"Treat &marginally valid keys as invalid",
2547d8 ····················IDC_MARGVALIDISINVALID,"Button",BS_AUTOCHECKBOX |·
b7acc2 ····················WS_TABSTOP,31,105,145,10
d91e4b ····CONTROL ········"&Warn when encrypting to keys with an ADK",
45f8c4 ····················IDC_WARNONADK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,31,
9cf757 ····················120,155,10
3af708 ····GROUPBOX ·······"Export Format",IDC_STATIC3,7,142,226,27
49f41d ····CONTROL ········"C&ompatible",IDC_EXPORTCOMPATIBLE,"Button",
39e2f4 ····················BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,64,153,51,10
7746af ····CONTROL ········"Compl&ete",IDC_EXPORTCOMPLETE,"Button",
47a895 ····················BS_AUTORADIOBUTTON,134,153,45,10
27e0d1 END
69af5a
cb556b IDD_PREF3 DIALOGEX 0, 0, 240, 180
814300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
277541 EXSTYLE WS_EX_CONTEXTHELP
3a5af8 CAPTION "Dialog"
643884 FONT 8, "MS Sans Serif", 0, 0, 0x1
c34523 BEGIN
0c1503 ····PUSHBUTTON ·····"&New",IDC_NEWKEYSERVER,9,101,50,14,WS_GROUP
2b0ed7 ····PUSHBUTTON ·····"&Remove",IDC_REMOVEKEYSERVER,66,101,50,14,WS_DISABLED
b3d0ee ····PUSHBUTTON ·····"&Edit",IDC_EDITKEYSERVER,123,101,50,14,WS_DISABLED
291b93 ····PUSHBUTTON ·····"Set as R&oot",IDC_SETASROOT,180,101,50,14,WS_DISABLED
7246ca ····GROUPBOX ·······"Synchronize with server upon",IDC_SYNCONSTATICTEXT,7,
8417d8 ····················121,226,54
34f030 ····CONTROL ········"Encrypting to &unknown keys",IDC_SYNCONUNKNOWN,"Button",
36d924 ····················BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,30,133,105,10
06565d ····CONTROL ········"&Signing keys",IDC_SYNCONKEYSIGN,"Button",
efc846 ····················BS_AUTOCHECKBOX | WS_TABSTOP,30,147,56,10
7ac896 ····CONTROL ········"A&dding names/photos/revokers",IDC_SYNCONADDNAME,"Button",
e4a69e ····················BS_AUTOCHECKBOX | WS_TABSTOP,30,161,116,10
ff2d3c ····CONTROL ········"Revo&cation",IDC_SYNCONREVOKE,"Button",BS_AUTOCHECKBOX |·
a85d0c ····················WS_TABSTOP,150,133,53,10
929004 ····CONTROL ········"&Verification",IDC_SYNCONVERIFY,"Button",
606535 ····················BS_AUTOCHECKBOX | WS_TABSTOP,150,147,51,10
ece0d1 END
2caf5a
--ae44 0008016e1bc401102ba Page 4 of PGPcl.rc
ce47bf IDD_NEWSERVER DIALOGEX 0, 0, 258, 199
c9e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
a17541 EXSTYLE WS_EX_CONTEXTHELP
abc0e7 CAPTION "Add New Server"
bc3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
264523 BEGIN
fc2241 ····GROUPBOX ·······"Server Information",IDC_STATIC1,6,7,247,164,WS_GROUP
33c1ec ····LTEXT ··········"&Protocol :",IDC_STATIC,35,20,31,8
f25778 ····COMBOBOX ·······IDC_PROTOCOL,70,18,43,55,CBS_DROPDOWNLIST | WS_VSCROLL |·
86c64d ····················WS_TABSTOP
5e7d13 ····LTEXT ··········"Server &Name :",IDC_STATIC,20,37,46,8
4452ca ····EDITTEXT ·······IDC_SERVERNAME,70,35,175,14,ES_AUTOHSCROLL | WS_GROUP
64fee6 ····LTEXT ··········"Po&rt :",IDC_STATIC,48,55,18,8
a2f593 ····EDITTEXT ·······IDC_PORT,70,53,34,14,ES_AUTOHSCROLL | ES_NUMBER
afc4aa ····LTEXT ··········"Server &Key :",IDC_STATIC,25,74,40,8
72b77c ····EDITTEXT ·······IDC_SERVERKEY,70,72,175,14,ES_AUTOHSCROLL | ES_READONLY |·
1a3a64 ····················NOT WS_TABSTOP
5fcdef ····GROUPBOX ·······"Serves Keys for Domain",IDC_STATIC2,12,98,234,50
5cb2d7 ····CONTROL ········" ··Any &Domain",IDC_ANYDOMAIN,"Button",
7a49d6 ····················BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,28,110,60,10
aba33a ····CONTROL ········"",IDC_SPECIFIEDDOMAIN,"Button",BS_AUTORADIOBUTTON,28,
909805 ····················128,16,8
bdf216 ····EDITTEXT ·······IDC_DOMAIN,45,125,192,14,ES_AUTOHSCROLL
030dd5 ····CONTROL ········"&List in search window",IDC_LISTED,"Button",
f81d97 ····················BS_AUTOCHECKBOX | WS_TABSTOP,19,155,93,10
b9832a ····DEFPUSHBUTTON ··"&OK",IDOK,145,178,50,14,WS_GROUP
019a38 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,202,178,50,14
3ce0d1 END
2aaf5a
ea58a4 IDD_SERVERPROGRESS DIALOGEX 0, 0, 215, 63
3c5b1a STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
fee3f3 CAPTION "PGP Server Progress"
fe3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
594523 BEGIN
88a797 ····DEFPUSHBUTTON ··"&Cancel",IDCANCEL,82,42,50,14
0bae22 ····CTEXT ··········"Static",IDC_PROGRESSTEXT,6,9,204,8
9769f1 ····LTEXT ··········"",IDC_PROGRESS,44,26,126,8,0,WS_EX_CLIENTEDGE
02e0d1 END
4eaf5a
4f89ce IDD_KEYPROPGENERAL DIALOG DISCARDABLE ·0, 0, 237, 222
ed5b1a STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
d9de5a CAPTION "PGP Key Properties - General"
fd309f FONT 8, "MS Sans Serif"
444523 BEGIN
5b691e ····RTEXT ··········"&ID :",IDC_STATIC,30,13,14,8
606cfb ····EDITTEXT ·······IDC_KEYID,48,11,58,13,ES_AUTOHSCROLL | ES_READONLY
d02f37 ····RTEXT ··········"&Type :",IDC_STATIC,24,30,20,8
42a0c0 ····EDITTEXT ·······IDC_KEYTYPE,48,28,58,13,ES_AUTOHSCROLL | ES_READONLY
2d9728 ····RTEXT ··········"&Size :",IDC_STATIC,27,47,17,8
b91a8e ····EDITTEXT ·······IDC_KEYSIZE,48,45,58,13,ES_AUTOHSCROLL | ES_READONLY
898e04 ····RTEXT ··········"&Created :",IDC_STATIC,14,65,30,8
cce10f ····EDITTEXT ·······IDC_CREATEDATE,48,63,58,13,ES_AUTOHSCROLL | ES_READONLY
6b19f1 ····RTEXT ··········"E&xpires :",IDC_STATIC,16,82,28,8
363aad ····EDITTEXT ·······IDC_EXPIREDATE,48,80,58,13,ES_AUTOHSCROLL | ES_READONLY
121820 ····RTEXT ··········"Cip&her :",IDC_STATIC,18,100,25,8
23841e ····EDITTEXT ·······IDC_CIPHER,48,98,58,13,ES_AUTOHSCROLL | ES_READONLY
eeda4f ····CONTROL ········"&Enabled",IDC_ENABLED,"Button",BS_AUTOCHECKBOX |·
56b96d ····················WS_TABSTOP,48,117,42,10
0b086a ····CONTROL ········"",IDC_PHOTOID,"Static",SS_ETCHEDFRAME | SS_NOTIFY,132,
cce275 ····················11,84,92
93e8a7 ····SCROLLBAR ······IDC_PHOTOSCROLLBAR,132,103,84,8,WS_TABSTOP
a1fa1c ····PUSHBUTTON ·····"Change &Passphrase ...",IDC_CHANGEPHRASE,132,116,84,14,
dc1efd ····················WS_GROUP
96413e ····GROUPBOX ·······"&Fingerprint",IDC_STATIC,5,132,225,29,WS_GROUP
814e5e ····EDITTEXT ·······IDC_FINGERPRINT,13,142,210,13,ES_CENTER | ES_MULTILINE |·
39bee8 ····················ES_AUTOHSCROLL | ES_READONLY
3a809c ····GROUPBOX ·······"Trust Model",IDC_STATIC1,5,170,225,45
24b41f ····LTEXT ··········"Invalid",IDC_STATIC2,14,184,22,8
cc2a0a ····CONTROL ········"Progress1",IDC_VALIDITYBAR,"msctls_progress32",0x0,41,
0a6b8e ····················185,33,7
930f4e ····LTEXT ··········"Valid",IDC_STATIC3,79,184,16,8,NOT WS_GROUP
809032 ····LTEXT ··········"&Untrusted",IDC_TRUSTTEXT1,120,184,32,8
--6b37 0007d2ddc0a401102ba Page 5 of PGPcl.rc
71776f ····CONTROL ········"Slider1",IDC_TRUSTSLIDER,"msctls_trackbar32",TBS_BOTH |·
151dd3 ····················TBS_NOTICKS | WS_TABSTOP,152,183,41,15
8bede8 ····LTEXT ··········"Trusted",IDC_TRUSTTEXT2,193,184,25,8,NOT WS_GROUP
a2844a ····CONTROL ········"I&mplicit Trust",IDC_AXIOMATIC,"Button",BS_AUTOCHECKBOX |·
40b7f1 ····················WS_GROUP | WS_TABSTOP,14,198,56,10
25e0d1 END
9faf5a
3c96ae IDD_NEWUSERID DIALOGEX 0, 0, 201, 95
bee659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
e17541 EXSTYLE WS_EX_CONTEXTHELP
7e82ba CAPTION "PGP New User Name"
1c3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
fc4523 BEGIN
50adf0 ····LTEXT ··········"New &name to add to key :",IDC_STATIC,7,7,82,8
bfedac ····EDITTEXT ·······IDC_NEWUSERNAME,7,17,187,14,ES_AUTOHSCROLL
6573fa ····LTEXT ··········"New &email address to add to key :",IDC_STATIC,7,38,108,
55e6e7 ····················8
56df14 ····EDITTEXT ·······IDC_NEWEMAILADDR,7,48,187,14,ES_AUTOHSCROLL
017619 ····DEFPUSHBUTTON ··"&OK",IDOK,85,74,50,14
cb025f ····PUSHBUTTON ·····"&Cancel",IDCANCEL,144,74,50,14
a0e0d1 END
f1af5a
fe94d5 IDD_DELETEALL DIALOGEX 0, 0, 222, 63
ace659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
f67541 EXSTYLE WS_EX_CONTEXTHELP
9e6c1a CAPTION "Delete Confirmation"
663884 FONT 8, "MS Sans Serif", 0, 0, 0x1
ed4523 BEGIN
2d8c58 ····CTEXT ··········"Static",IDC_STRING,7,7,208,25
38213d ····PUSHBUTTON ·····"&Yes",IDOK,13,42,40,14,WS_GROUP
60b03a ····PUSHBUTTON ·····"Yes to &All",IDC_YESTOALL,65,42,40,14
51ed4b ····DEFPUSHBUTTON ··"&No",IDNO,117,42,40,14
117817 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,169,42,40,14
cbe0d1 END
06af5a
3a821f IDD_QUERYADD DIALOG DISCARDABLE ·0, 0, 279, 137
8d2da8 STYLE DS_CENTER | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION |·
e84ac4 ····WS_SYSMENU | WS_THICKFRAME
5c83f2 CAPTION "Select key(s)"
f6d244 CLASS "PGPDLGCLASS"
87309f FONT 8, "MS Sans Serif"
a04523 BEGIN
5202ee ····DEFPUSHBUTTON ··"&OK",IDOK,204,116,50,14
58e0bc ····PUSHBUTTON ·····"&Select All",IDC_SELECTALL,24,116,50,14
f99cb8 ····PUSHBUTTON ·····"&Unselect All",IDC_UNSELECTALL,84,116,50,14
279c6d ····PUSHBUTTON ·····"&Cancel",IDCANCEL,144,116,50,14
618564 ····LTEXT ··········"Select the desired keys :",IDC_PROMPT,6,7,267,11
e8e0d1 END
36af5a
da359c IDD_REVOKECERT DIALOG DISCARDABLE ·0, 0, 208, 71
0fe659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
80d79d CAPTION "Revoke Signature"
d7309f FONT 8, "MS Sans Serif"
6f4523 BEGIN
3114e1 ····LTEXT ··········"Are you sure you want to revoke your signature on this key¶
f46d41 ?",
24525e ····················IDC_STATIC,7,8,194,12
133b9c ····LTEXT ··········"Key ID :",IDC_STATIC,14,22,32,8
6593c4 ····LTEXT ··········"Static",IDC_KEYID,46,22,155,8
96ed55 ····LTEXT ··········"Name :",IDC_STATIC,14,32,24,8
39ce41 ····LTEXT ··········"Static",IDC_NAME,46,32,155,8
5bc3ea ····DEFPUSHBUTTON ··"&OK",IDOK,18,50,50,14
05e244 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,78,50,50,14
1c9a2c ····PUSHBUTTON ·····"&Help",9,138,50,50,14
a0e0d1 END
f3af5a
a80d8d IDD_SIGNCONFIRM DIALOG DISCARDABLE ·0, 0, 380, 231
2f49fc STYLE DS_MODALFRAME | DS_CENTER | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION |·
19f85b ····WS_SYSMENU
09fe58 CAPTION "PGP Sign Key"
03309f FONT 8, "MS Sans Serif"
7d4523 BEGIN
--1fa0 0008ba3bede401102ba Page 6 of PGPcl.rc
e72ada ····LTEXT ··········"By signing the selected user ID(s), you are certifying bas¶
998d96 ed on your own direct first-hand knowledge that the key(s) and attached user ID¶
79eb59 (s) actually belong to the identified user(s).",
3d3b64 ····················IDC_STATIC1,7,3,366,19,NOT WS_GROUP
a94411 ····LTEXT ··········"Before signing, make sure the key(s) were given to you in ¶
19af94 a secure manner by the owner or you have verified the fingerprint with the owne¶
d2b120 r.",
e3995b ····················IDC_STATIC2,7,22,366,17,NOT WS_GROUP
39530a ····CONTROL ········"List1",IDC_KEYLIST,"SysListView32",LVS_REPORT |·
3bccb1 ····················LVS_NOSORTHEADER | WS_BORDER,7,43,366,65
c81a2a ····CONTROL ········"&Allow signature to be exported. ·Others may rely upon you¶
e71883 r signature.",
db1659 ····················IDC_EXPORTABLECHECK,"Button",BS_AUTOCHECKBOX | WS_GROUP |·
b2620d ····················WS_TABSTOP,20,115,231,10
4f0a6b ····PUSHBUTTON ·····"&More Choices",IDC_MORECHOICES,7,132,53,14,WS_GROUP
e4a4f1 ····GROUPBOX ·······"Signature Type",IDC_SIGTYPE,7,115,233,87,NOT WS_VISIBLE
45849c ····CONTROL ········"&Non-Exportable",IDC_NONEXPORTABLE,"Button",
05dbf8 ····················BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_GROUP |·
b17313 ····················WS_TABSTOP,33,128,65,10
4c309f ····CONTROL ········"&Exportable",IDC_EXPORTABLE,"Button",BS_AUTORADIOBUTTON |·
d6504a ····················NOT WS_VISIBLE,33,142,49,10
398068 ····CONTROL ········"Meta-&Introducer Non-Exportable",IDC_META,"Button",
35a330 ····················BS_AUTORADIOBUTTON | NOT WS_VISIBLE,33,156,117,10
202a59 ····CONTROL ········"&Trusted Introducer Exportable",IDC_TRUSTED,"Button",
313af2 ····················BS_AUTORADIOBUTTON | NOT WS_VISIBLE,33,170,109,10
3db14d ····LTEXT ··········"Domain restriction :",IDC_DOMAINTEXT,51,184,61,8
afc189 ····EDITTEXT ·······IDC_DOMAIN,118,182,110,14,ES_AUTOHSCROLL | WS_DISABLED
3af8f2 ····GROUPBOX ·······"Expiration",IDC_EXPIRATION,250,115,126,46,NOT·
4521cb ····················WS_VISIBLE
faae16 ····CONTROL ········"Ne&ver",IDC_NEVEREXPIRES,"Button",BS_AUTORADIOBUTTON |·
ea4965 ····················NOT WS_VISIBLE | WS_GROUP,265,128,35,10
8b56b1 ····CONTROL ········"&Date:",IDC_EXPIRES,"Button",BS_AUTORADIOBUTTON | NOT·
9d2a19 ····················WS_VISIBLE,265,143,32,10
2d27ac ····LTEXT ··········"Date/Time Picker",IDC_EXPIRATIONDATE,304,141,58,14,NOT·
4a1580 ····················WS_VISIBLE | WS_BORDER | NOT WS_GROUP
489eef ····PUSHBUTTON ·····"&Fewer Choices",IDC_FEWERCHOICES,7,211,53,14,NOT·
ba9ed2 ····················WS_VISIBLE | WS_GROUP
76d256 ····DEFPUSHBUTTON ··"&OK",IDOK,208,211,50,14,WS_GROUP
a9793b ····PUSHBUTTON ·····"&Cancel",IDCANCEL,265,211,50,14
b7a20b ····PUSHBUTTON ·····"&Help",9,322,211,50,14
2ee0d1 END
adaf5a
a37dde IDD_EXPORTDLGEXTENSIONS DIALOGEX 0, 0, 186, 84
532534 STYLE DS_3DLOOK | DS_CONTROL | DS_CONTEXTHELP | WS_CHILD | WS_VISIBLE |·
1c7521 ····WS_CLIPSIBLINGS
c77541 EXSTYLE WS_EX_CONTEXTHELP
553884 FONT 8, "MS Sans Serif", 0, 0, 0x1
144523 BEGIN
6c67c0 ····LTEXT ··········"",1119,7,7,172,42
5161dc ····CONTROL ········"Include &Private Key(s)",IDC_EXPORTPRIVATEKEYS,"Button",
532158 ····················BS_AUTOCHECKBOX | WS_TABSTOP,11,54,85,10
91c6c0 ····CONTROL ········"Include &6.0 Extensions",IDC_INCLUDEEXTENSIONS,"Button",
506b07 ····················BS_AUTOCHECKBOX | WS_TABSTOP,11,67,87,10
44e0d1 END
0baf5a
82a805 IDD_KEYPROPSUBKEYS DIALOG DISCARDABLE ·0, 0, 237, 222
184300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
99a0dc CAPTION "PGP Key Properties - Subkeys"
e0309f FONT 8, "MS Sans Serif"
904523 BEGIN
bcae3e ····CONTROL ········"List1",IDC_SUBKEYLIST,"SysListView32",LVS_REPORT |·
b63ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
b95ebb ····················WS_TABSTOP,28,14,180,86
ff29da ····PUSHBUTTON ·····"&New ...",IDC_NEWSUBKEY,28,112,50,14,WS_DISABLED
165c02 ····PUSHBUTTON ·····"Re&voke",IDC_REVOKESUBKEY,92,112,50,14,WS_DISABLED
de8de2 ····PUSHBUTTON ·····"&Remove",IDC_REMOVESUBKEY,157,112,50,14,WS_DISABLED
c2c410 ····LTEXT ··········"The Master Key for this key is used for signing only. ·Sub¶
031df0 keys are used for encryption, and may be replaced and revoked separately from t¶
07f6d8 he Master Key without losing any of the Signatures applied to this key. ",
9b93fa ····················IDC_STATICTEXT1,18,137,200,35
911975 ····LTEXT ··········"Changes made here will require redistribution of this key ¶
8b6ea4 to the server in order to be noticed by others.",
--ca9a 0009490e5d1401102ba Page 7 of PGPcl.rc
5cce9f ····················IDC_STATICTEXT2,18,172,200,18
75e0d1 END
c9af5a
8a19f1 IDD_KEYPROPADK DIALOG DISCARDABLE ·0, 0, 237, 222
044300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
339596 CAPTION "PGP Key Properties - ADK"
5c309f FONT 8, "MS Sans Serif"
934523 BEGIN
6aea4f ····GROUPBOX ·······"Additional Decryption Keys",IDC_FRAME,9,30,218,130
17e0d1 END
66af5a
46ed38 IDD_NEWSUBKEY DIALOGEX 0, 0, 196, 106
a9d6db STYLE DS_SYSMODAL | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |·
86f85b ····WS_SYSMENU
647541 EXSTYLE WS_EX_CONTEXTHELP
07bc1c CAPTION "New Subkey"
a23884 FONT 8, "MS Sans Serif", 0, 0, 0x1
1e4523 BEGIN
235946 ····LTEXT ··········"&Key Size : ",IDC_STATIC,49,10,34,8
b509b0 ····COMBOBOX ·······IDC_SUBKEYSIZE,91,8,48,68,CBS_DROPDOWN | WS_VSCROLL |·
bba63c ····················WS_GROUP | WS_TABSTOP
7e0e21 ····LTEXT ··········"&Start Date : ",IDC_STARTDATETEXT,44,28,39,8
47ed81 ····LTEXT ··········"Date Picker",IDC_STARTDATE,90,26,58,14,NOT WS_VISIBLE |·
fe8373 ····················WS_BORDER | NOT WS_GROUP
745b9f ····GROUPBOX ·······"Expiration",IDC_STATIC1,16,46,164,30,WS_GROUP
567e92 ····CONTROL ········"Ne&ver",IDC_NEVEREXPIRES,"Button",BS_AUTORADIOBUTTON,29,
55a280 ····················58,35,10
ea631d ····CONTROL ········"&Date : ",IDC_EXPIRESON,"Button",BS_AUTORADIOBUTTON |·
556c27 ····················WS_TABSTOP,74,58,33,10
842ba7 ····LTEXT ··········"Date Picker",IDC_EXPIRATIONDATE,110,56,58,14,NOT·
681580 ····················WS_VISIBLE | WS_BORDER | NOT WS_GROUP
0c9b63 ····DEFPUSHBUTTON ··"&OK",IDOK,43,85,50,14
cfeb46 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,102,85,50,14,WS_GROUP
52e0d1 END
ebaf5a
de3819 IDD_SPLITKEY DIALOGEX 0, 0, 238, 229
e34925 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |·
6df85b ····WS_SYSMENU
517541 EXSTYLE WS_EX_CONTEXTHELP
bf1da3 CAPTION "Split Key"
783884 FONT 8, "MS Sans Serif", 0, 0, 0x1
034523 BEGIN
cd7477 ····LTEXT ··········"Split Key : ",IDC_STATIC,12,14,32,8
251220 ····EDITTEXT ·······IDC_KEYTOSPLIT,50,12,173,14,ES_AUTOHSCROLL | ES_READONLY |·
723a64 ····················NOT WS_TABSTOP
025a32 ····GROUPBOX ·······"Shareholders",IDC_STATIC1,7,35,224,142
d4b2af ····LTEXT ··········"To add shareholders, drag their keys to this window, or cl¶
6e673c ick Add to add a user without a key.",
c77d77 ····················IDC_STATIC2,15,46,200,17
c71448 ····CONTROL ········"List1",IDC_SHAREHOLDERS,"SysListView32",LVS_REPORT |·
903ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
93675c ····················WS_TABSTOP,14,70,206,61
131aa5 ····EDITTEXT ·······IDC_CURRENTSHAREHOLDER,14,138,174,14,ES_AUTOHSCROLL |·
6a669b ····················ES_READONLY | NOT WS_TABSTOP
08f0ef ····EDITTEXT ·······IDC_SHARES,194,138,27,14,ES_AUTOHSCROLL | ES_NUMBER
e2496e ····CONTROL ········"Spin1",IDC_SHARESSPIN,"msctls_updown32",UDS_SETBUDDYINT |·
b405e1 ····················UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,215,138,9,
ac9579 ····················15
30c634 ····PUSHBUTTON ·····"&Remove",IDC_REMOVESHAREHOLDER,14,158,50,14
417481 ····PUSHBUTTON ·····"&Add",IDC_ADDSHAREHOLDER,69,158,50,14
d2053c ····LTEXT ··········"Total Shares : ",IDC_STATIC,143,161,47,8
fcb1b0 ····EDITTEXT ·······IDC_TOTALSHARES,194,158,27,14,ES_AUTOHSCROLL |·
1d7220 ····················ES_READONLY | ES_NUMBER | NOT WS_TABSTOP
61c7cd ····LTEXT ··········"Total Shares Required to Decrypt or Sign : ",IDC_STATIC,
385dc3 ····················54,187,136,8
9dbf1d ····EDITTEXT ·······IDC_THRESHOLD,194,184,27,14,ES_AUTOHSCROLL | ES_NUMBER
a2151f ····CONTROL ········"Spin3",IDC_THRESHOLDSPIN,"msctls_updown32",
614d6b ····················UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |·
357633 ····················UDS_ARROWKEYS,215,184,9,15
cb68a5 ····DEFPUSHBUTTON ··"&Split Key",IDOK,71,207,50,14
acbe46 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,127,207,50,14
94ae4f ····PUSHBUTTON ·····"&Help",9,181,207,50,14
--fbb0 000ce3dd6a9401102ba Page 8 of PGPcl.rc
a2e0d1 END
86af5a
8f2eb5 IDD_ADDSHAREHOLDER DIALOGEX 0, 0, 225, 92
d4e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
d87541 EXSTYLE WS_EX_CONTEXTHELP
f99a93 CAPTION "Add Shareholder"
153884 FONT 8, "MS Sans Serif", 0, 0, 0x1
e64523 BEGIN
8008df ····GROUPBOX ·······"Name",IDC_STATIC,7,21,211,39
04da73 ····EDITTEXT ·······IDC_NEWSHAREHOLDER,16,35,194,14,ES_AUTOHSCROLL
2e6115 ····DEFPUSHBUTTON ··"&OK",IDOK,103,71,50,14
e4757a ····PUSHBUTTON ·····"&Cancel",IDCANCEL,168,71,50,14
102912 ····LTEXT ··········"Please enter a name for the new shareholder :",
fb2f29 ····················IDC_STATIC1,7,7,146,8
aae0d1 END
54af5a
1588b6 IDD_SENDSHARES DIALOGEX 0, 0, 252, 167
44e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
697541 EXSTYLE WS_EX_CONTEXTHELP
99d94d CAPTION "Send Key Shares"
1b3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
b24523 BEGIN
84cd8b ····GROUPBOX ·······"&Remote Address",IDC_STATIC,7,44,238,36,WS_GROUP
085603 ····EDITTEXT ·······IDC_REMOTECOMPUTER,16,57,222,14,ES_AUTOHSCROLL
acba06 ····GROUPBOX ·······"Network",IDC_STATIC1,7,85,238,51,WS_GROUP
aae593 ····LTEXT ··········"Status :",IDC_STATIC,41,97,25,8,NOT WS_GROUP
4a7580 ····EDITTEXT ·······IDC_NETSTATUS,71,96,165,14,ES_AUTOHSCROLL | ES_READONLY |·
d53a64 ····················NOT WS_TABSTOP
2053eb ····LTEXT ··········"Authenticated :",IDC_STATIC,17,116,49,8,NOT WS_GROUP
4b9d75 ····EDITTEXT ·······IDC_AUTHENTICATION,71,115,166,14,ES_AUTOHSCROLL |·
f1669b ····················ES_READONLY | NOT WS_TABSTOP
274814 ····DEFPUSHBUTTON ··"&Send Shares",IDC_SENDSHARES,119,144,66,14
585e3e ····PUSHBUTTON ·····"&Cancel",IDCANCEL,195,144,50,14
ed7db6 ····LTEXT ··········"Share File :",IDC_STATIC,19,10,36,8
2afa30 ····EDITTEXT ·······IDC_SHAREFILE,59,8,179,14,ES_AUTOHSCROLL | ES_READONLY |·
d83a64 ····················NOT WS_TABSTOP
9cd331 ····LTEXT ··········"Shares :",IDC_STATIC,28,28,27,8
7a7cb6 ····EDITTEXT ·······IDC_NUMSHARES,59,26,24,14,ES_AUTOHSCROLL | ES_READONLY |·
7f3a64 ····················NOT WS_TABSTOP
7ee0d1 END
cfaf5a
db3260 IDD_CONFIRMAUTHENTICATION DIALOGEX 0, 0, 279, 191
dae659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
397541 EXSTYLE WS_EX_CONTEXTHELP
888fac CAPTION "Remote Authentication"
983884 FONT 8, "MS Sans Serif", 0, 0, 0x1
354523 BEGIN
aeec55 ····DEFPUSHBUTTON ··"Con&firm",IDOK,165,171,50,14
70b834 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,223,171,50,14
fa7dae ····LTEXT ··········"The remote system has authenticated with the following key¶
d59692 ·at the address shown :",
494e08 ····················IDC_STATIC7,7,7,265,13
5bba20 ····GROUPBOX ·······"Remote Address",IDC_STATIC,7,19,265,33
c152fd ····EDITTEXT ·······IDC_SERVERNAME,17,31,247,14,ES_AUTOHSCROLL | ES_READONLY
3531d2 ····GROUPBOX ·······"Authenticating Key",IDC_STATIC1,7,58,265,75
2344fc ····LTEXT ··········"Name : ",IDC_STATIC,39,73,23,8
fd6961 ····EDITTEXT ·······IDC_KEYNAME,68,71,196,14,ES_AUTOHSCROLL | ES_READONLY
672d16 ····LTEXT ··········"Fingerprint :",IDC_STATIC,25,94,38,8
226c08 ····EDITTEXT ·······IDC_FINGERPRINT,68,92,196,14,ES_AUTOHSCROLL |·
db536e ····················ES_READONLY
1ff0d5 ····LTEXT ··········"Validity :",IDC_STATIC2,35,115,27,8
f69944 ····LTEXT ··········"Invalid",IDC_STATIC3,68,115,22,8
e8226a ····CONTROL ········"Progress1",IDC_VALIDITY,"msctls_progress32",WS_BORDER,
c949a1 ····················96,115,66,8
3a59d1 ····LTEXT ··········"Valid",IDC_STATIC4,168,115,16,8
93308a ····PUSHBUTTON ·····"&Import Key ...",IDC_IMPORTKEY,201,112,62,14
ec8d1c ····LTEXT ··········"",IDC_AUTHTEXT,7,140,265,23
6be0d1 END
82af5a
7a37a7 IDD_SPLITKEYPROGRESS DIALOG DISCARDABLE ·0, 0, 239, 45
07d973 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION
cecd90 CAPTION "Share Split Progress"
--fff1 00021af3c3c401102ba Page 9 of PGPcl.rc
ef309f FONT 8, "MS Sans Serif"
3a4523 BEGIN
f9b83b ····CTEXT ··········"Static",IDC_PROGRESSTEXT,7,7,225,8
73af43 ····CONTROL ········"Progress1",IDC_PROGRESSBAR,"msctls_progress32",
1f457c ····················WS_BORDER,42,22,154,7
4ee0d1 END
52af5a
0c125e IDD_RECONSTITUTEKEY DIALOGEX 0, 0, 238, 250
d5e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
7c7541 EXSTYLE WS_EX_CONTEXTHELP
1a2e69 CAPTION "Key Share Collection"
893884 FONT 8, "MS Sans Serif", 0, 0, 0x1
8b4523 BEGIN
c81448 ····CONTROL ········"List1",IDC_SHAREHOLDERS,"SysListView32",LVS_REPORT |·
4598ef ····················LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,34,224,56
aece5b ····LTEXT ··········"Total Shares Collected :",IDC_STATIC3,113,97,76,8
f8c44b ····EDITTEXT ·······IDC_SHARESCOLLECTED,196,94,24,14,ES_AUTOHSCROLL |·
43536e ····················ES_READONLY
b3bfb8 ····LTEXT ··········"Total Shares Needed :",IDC_STATIC4,117,114,72,8
e4c4f7 ····EDITTEXT ·······IDC_SHARESNEEDED,196,111,24,14,ES_AUTOHSCROLL |·
c5536e ····················ES_READONLY
6141e4 ····GROUPBOX ·······"Network Shares",IDC_STATIC1,7,128,224,49
a91bc4 ····LTEXT ··········"To receive shares securely over your network connection, c¶
103906 lick the Start Network button.",
7a8659 ····················IDC_NETWORKINSTRUCTIONS,18,142,115,27
32ef92 ····PUSHBUTTON ·····"Network",IDC_NETWORK,149,138,76,14
040c13 ····GROUPBOX ·······"Local Shares",IDC_STATIC2,7,181,224,40
7c7ce4 ····LTEXT ··········"To add a Share File stored on this computer, click the Sel¶
89bf64 ect Share File button.",
b62bfb ····················IDC_STATIC,18,191,91,27
5cdb98 ····PUSHBUTTON ·····"Select Share &File",IDC_SHAREFILE,149,190,76,14
e01bce ····DEFPUSHBUTTON ··"&OK",IDOK,123,229,50,14
b1344e ····PUSHBUTTON ·····"&Cancel",IDCANCEL,181,229,50,14
14e3b0 ····EDITTEXT ·······IDC_AUTHENTICATION,68,158,157,14,ES_AUTOHSCROLL |·
f2536e ····················ES_READONLY
5cb72c ····LTEXT ··········"Authenticated :",IDC_AUTHENTICATIONTEXT,14,161,49,8
99e9ae ····EDITTEXT ·······IDC_STATUS,68,139,68,14,ES_AUTOHSCROLL | ES_READONLY
a20bd1 ····LTEXT ··········"Status :",IDC_STATUSTEXT,38,142,25,8
f70b53 ····LTEXT ··········"Key : ",IDC_STATIC,8,11,19,8
4fa099 ····EDITTEXT ·······IDC_KEYTORECON,31,9,199,14,ES_AUTOHSCROLL | ES_READONLY |·
f03a64 ····················NOT WS_TABSTOP
1fe0d1 END
f5af5a
60889d IDD_REVERIFYING DIALOG DISCARDABLE ·0, 0, 201, 63
43d973 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION
a6ab02 CAPTION "Signature Reverification"
2c309f FONT 8, "MS Sans Serif"
7a4523 BEGIN
b0b3c7 ····DEFPUSHBUTTON ··"&Cancel",IDCANCEL,76,42,50,14,WS_DISABLED
89c5a9 ····CTEXT ··········"Static",IDC_TEXT,7,13,187,8
21af43 ····CONTROL ········"Progress1",IDC_PROGRESSBAR,"msctls_progress32",
4b3580 ····················WS_BORDER,33,28,136,8
53e0d1 END
a1af5a
1b340e IDD_NEWPHOTOID DIALOGEX 0, 0, 196, 166
d0e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
1b7541 EXSTYLE WS_EX_CONTEXTHELP
e2fd99 CAPTION "Add Photo"
943884 FONT 8, "MS Sans Serif", 0, 0, 0x1
0a4523 BEGIN
66a47d ····DEFPUSHBUTTON ··"&OK",IDOK,86,145,50,14,WS_DISABLED
edf629 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,139,145,50,14
8cc64b ····LTEXT ··········"Drag or paste a picture into the area below. ·To choose a ¶
fc1db9 picture from a file, click the ""Select File"" button. ·For best results, crop ¶
e7ab71 your picture to 120x144.",
306d26 ····················IDC_STATIC1,7,7,182,30
3716dc ····CONTROL ········"",IDC_PHOTOID,"Static",SS_ETCHEDFRAME | SS_NOTIFY,56,41,
86b711 ····················84,92,WS_EX_ACCEPTFILES
730057 ····PUSHBUTTON ·····"&Select File ...",IDC_SELECTFILE,7,145,55,14
92e0d1 END
7eaf5a
2132c0 IDD_DRIVERWARNING DIALOG DISCARDABLE ·0, 0, 252, 108
--ce59 000a2b5fb66401102ba Page 10 of PGPcl.rc
7ce659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
cb96bf CAPTION "PGP Warning"
92309f FONT 8, "MS Sans Serif"
c04523 BEGIN
9f0bc0 ····DEFPUSHBUTTON ··"C&ontinue",IDOK,139,87,50,14
e2cb5d ····PUSHBUTTON ·····"&Quit",IDCANCEL,195,87,50,14
646d55 ····CONTROL ········"&Don't warn me again",IDC_NOMOREWARNINGS,"Button",
66bcbb ····················BS_AUTOCHECKBOX | WS_TABSTOP,7,91,81,10
9733ee ····LTEXT ··········"The PGP memory page locking driver is not functioning corr¶
3d864b ectly. ·This could be the result of an incorrect installation, a system failure¶
842fda , or tampering with your system. ",
14ba22 ····················IDC_STATIC,7,7,238,26
db3070 ····LTEXT ··········"If you continue to use PGP under these conditions, sensiti¶
d2839b ve data such as passphrases may end up being written to the system paging file.¶
0e934a ",
739e1e ····················IDC_STATIC,7,57,238,19
b70908 ····LTEXT ··········"We recommend that you quit PGP now and consult the documen¶
f84d17 tation on how to fix this problem.",
ce22e9 ····················IDC_STATIC,7,36,238,18
1ce0d1 END
18af5a
762b18 IDD_KEYPROPREVOKERS DIALOG DISCARDABLE ·0, 0, 237, 223
5e7844 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
091e59 CAPTION "PGP Key Properties - Designated Revokers"
15309f FONT 8, "MS Sans Serif"
be4523 BEGIN
009842 ····GROUPBOX ·······"Designated Revoker Keys",IDC_FRAME,9,30,218,130
a2e0d1 END
98af5a
356b96 IDD_WARNINGDLG DIALOG DISCARDABLE ·0, 0, 226, 106
0ee659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
4f96bf CAPTION "PGP Warning"
c9309f FONT 8, "MS Sans Serif"
2d4523 BEGIN
b2fab6 ····DEFPUSHBUTTON ··"OK",IDOK,51,88,50,14
f7435e ····PUSHBUTTON ·····"Cancel",IDCANCEL,109,88,50,14
79f9ce ····PUSHBUTTON ·····"Help",9,169,88,50,14
54ecad ····GROUPBOX ·······"Static",IDC_STATIC1,7,7,212,75
90c1e8 ····CONTROL ········"Never Show Me This Warning Again",IDC_WARNCHECK,"Button",
17fcf7 ····················BS_AUTOCHECKBOX | WS_TABSTOP,13,7,131,10
77fd45 ····LTEXT ··········"Sample Warning Text",IDC_WARNINGTEXT,15,25,195,47
38e0d1 END
5caf5a
9fe65a IDD_SUBKEYGENPROG DIALOG DISCARDABLE ·0, 0, 157, 130
724300 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
1f2955 CAPTION "Subkey Generation"
f1309f FONT 8, "MS Sans Serif"
8c4523 BEGIN
0dec0a ····DEFPUSHBUTTON ··"Cancel",IDCANCEL,49,109,60,14
a8b339 ····CONTROL ········"Animate1",IDC_SUBKEYAVI,"SysAnimate32",ACS_CENTER,7,7,
010497 ····················143,89
58e0d1 END
58af5a
c7af5a
ef6c0e /////////////////////////////////////////////////////////////////////////////
5f465d //
bfae70 // Bitmap
1f465d //
c3af5a
cc32ce IDB_IMAGES4 ············BITMAP ·DISCARDABLE ····"res\\CLimag4.bmp"
fb3c3c IDB_IMAGES24 ···········BITMAP ·DISCARDABLE ····"res\\CLimag24.bmp"
ebfed3 IDB_IMAGES4BIT ·········BITMAP ·DISCARDABLE ····"..\\shared\\images4.bmp"
c024e2 IDB_IMAGES24BIT ········BITMAP ·DISCARDABLE ····"..\\shared\\images24.bmp"
09c644 IDB_QUESTIONMARK ·······BITMAP ·DISCARDABLE ····"res\\qmark.bmp"
5a738f IDB_REVOKED ············BITMAP ·DISCARDABLE ····"res\\revoked.bmp"
1ab7f4 IDB_EXPIRED ············BITMAP ·DISCARDABLE ····"Res\\expired.bmp"
67af5a
726c0e /////////////////////////////////////////////////////////////////////////////
95465d //
7ecbaf // Icon
d2465d //
a2af5a
--dbb0 00095e9251b401102ba Page 11 of PGPcl.rc
582951 // Icon with lowest ID value placed first to ensure application icon
9b0f06 // remains consistent on all systems.
758a33 IDI_KEYICON ············ICON ···DISCARDABLE ····"res\\Key.ico"
77af5a
306c0e /////////////////////////////////////////////////////////////////////////////
3f465d //
9586c0 // Menu
d0465d //
feaf5a
da86b6 IDR_MENUEDITSERVER MENU DISCARDABLE·
5b4523 BEGIN
209fe8 ····POPUP "Context"
be5574 ····BEGIN
ddcbf9 ········MENUITEM "&New", ·······················IDM_NEWSERVER
81592d ········MENUITEM SEPARATOR
8c659f ········MENUITEM "&Remove", ····················IDM_REMOVESERVER
8f0eab ········MENUITEM "&Edit", ······················IDM_EDITSERVER
66bee1 ········MENUITEM "Set as R&oot", ···············IDM_SETASROOT
217d01 ····END
50e0d1 END
23af5a
4c4d02 IDR_MENUIMPORT MENU DISCARDABLE·
744523 BEGIN
089fe8 ····POPUP "Context"
9e5574 ····BEGIN
585c9b ········MENUITEM "Key &Properties", ············IDM_KEYPROPERTIES
c87d01 ····END
96e0d1 END
eeaf5a
1d1a42 IDR_MENUPHOTOID MENU DISCARDABLE·
af4523 BEGIN
e69fe8 ····POPUP "Context"
025574 ····BEGIN
9024e6 ········MENUITEM "&Copy Image", ················IDM_COPYBITMAP
967d01 ····END
ede0d1 END
1daf5a
e4eaaa IDR_MENUNEWPHOTOID MENU DISCARDABLE·
c64523 BEGIN
199fe8 ····POPUP "Context"
445574 ····BEGIN
f824e6 ········MENUITEM "&Copy Image", ················IDM_COPYBITMAP
b8315d ········MENUITEM "&Paste Image", ···············IDM_PASTEBITMAP
f27d01 ····END
e4e0d1 END
19af5a
2aaf5a
ce6c0e /////////////////////////////////////////////////////////////////////////////
fe465d //
1dce54 // Dialog Info
27465d //
52af5a
ddbcd9 IDD_NEWSERVER DLGINIT
ca4523 BEGIN
43b882 ····IDC_PROTOCOL, 0x403, 5, 0
ca3299 0x444c, 0x5041, "\000"·
1da54e ····IDC_PROTOCOL, 0x403, 6, 0
e2b1e7 0x444c, 0x5041, 0x0053,·
5db882 ····IDC_PROTOCOL, 0x403, 5, 0
c096af 0x5448, 0x5054, "\000"·
4b99f9 ····0
21e0d1 END
5aaf5a
89af5a
086c0e /////////////////////////////////////////////////////////////////////////////
a6465d //
0a6077 // DESIGNINFO
62465d //
06af5a
8df860 #ifdef APSTUDIO_INVOKED
0470e4 GUIDELINES DESIGNINFO DISCARDABLE·
954523 BEGIN
--2c00 00036441243401102ba Page 12 of PGPcl.rc
2fe8c0 ····IDD_HELPABOUT, DIALOG
615574 ····BEGIN
462f23 ········BOTTOMMARGIN, 132
467d01 ····END
09af5a
b31a1d ····IDD_QUERYADD, DIALOG
2c5574 ····BEGIN
8bd0ad ········LEFTMARGIN, 6
a3fbe1 ········RIGHTMARGIN, 273
d21c93 ········BOTTOMMARGIN, 130
2c7d01 ····END
ffaf5a
412e0f ····IDD_SIGNCONFIRM, DIALOG
ed5574 ····BEGIN
e899e2 ········RIGHTMARGIN, 376
ad7d01 ····END
d6af5a
251e05 ····IDD_EXPORTDLGEXTENSIONS, DIALOG
405574 ····BEGIN
5e7011 ········BOTTOMMARGIN, 83
497d01 ····END
cbaf5a
bd47be ····IDD_KEYPROPSUBKEYS, DIALOG
ee5574 ····BEGIN
8e8158 ········RIGHTMARGIN, 232
f18ce6 ········BOTTOMMARGIN, 210
f07d01 ····END
a6af5a
2240a5 ····IDD_KEYPROPADK, DIALOG
e65574 ····BEGIN
158158 ········RIGHTMARGIN, 232
8e8ce6 ········BOTTOMMARGIN, 210
7e7d01 ····END
d9af5a
dafd6c ····IDD_NEWSUBKEY, DIALOG
2c5574 ····BEGIN
8c833f ········RIGHTMARGIN, 194
f17d01 ····END
5faf5a
827bd4 ····IDD_SPLITKEY, DIALOG
095574 ····BEGIN
e8ad42 ········BOTTOMMARGIN, 228
8d7d01 ····END
0daf5a
f90c55 ····IDD_NEWPHOTOID, DIALOG
235574 ····BEGIN
59c975 ········LEFTMARGIN, 7
15699b ········RIGHTMARGIN, 189
2487e9 ········TOPMARGIN, 7
b71d52 ········BOTTOMMARGIN, 159
b07d01 ····END
aeaf5a
656a9e ····IDD_DRIVERWARNING, DIALOG
815574 ····BEGIN
17c975 ········LEFTMARGIN, 7
2c4055 ········RIGHTMARGIN, 245
3b87e9 ········TOPMARGIN, 7
3cea2f ········BOTTOMMARGIN, 101
4d7d01 ····END
b1af5a
f8251c ····IDD_KEYPROPREVOKERS, DIALOG
735574 ····BEGIN
83c975 ········LEFTMARGIN, 7
13b2e8 ········RIGHTMARGIN, 230
4887e9 ········TOPMARGIN, 7
93d836 ········BOTTOMMARGIN, 216
637d01 ····END
5faf5a
d7927f ····IDD_SUBKEYGENPROG, DIALOG
765574 ····BEGIN
a1c975 ········LEFTMARGIN, 7
3641fc ········RIGHTMARGIN, 150
--6ee2 0002120e3eb401102ba Page 13 of PGPcl.rc
2387e9 ········TOPMARGIN, 7
396c27 ········BOTTOMMARGIN, 123
3c7d01 ····END
ede0d1 END
9869ab #endif ···// APSTUDIO_INVOKED
3eaf5a
64af5a
316c0e /////////////////////////////////////////////////////////////////////////////
cb465d //
be5e87 // String Table
4e465d //
6daf5a
576f6c STRINGTABLE DISCARDABLE·
984523 BEGIN
ca09fb ····IDS_GENERAL ············"General strings"
60ae0d ····IDS_PRIVKEYRINGFILTER ··"Private Keyring Files (*.skr; *.prvkr; *.pgp)@*.sk¶
f9a8ff r;*.prvkr;*.pgp@All Files (*.*)@*.*@@"
45d1c5 ····IDS_PRIVKEYCAPTION ·····"Select Private Keyring File"
325f12 ····IDS_PUBKEYCAPTION ······"Select Public Keyring File"
9a9156 ····IDS_PROPCAPTION ········"PGP Preferences"
7982c1 ····IDS_CAPTIONERROR ·······"PGP Error"
dce5cf ····IDS_HELPFILENAME ·······"PGP60.hlp"
e0c90b ····IDS_TITLE0 ·············"General"
e3d31c ····IDS_TITLE1 ·············"Files"
fadd86 ····IDS_TITLE2 ·············"Email"
ede2cb ····IDS_TITLE3 ·············"Servers"
55215d ····IDS_TITLE4 ·············"Advanced"
c5120f ····IDS_NOSIGNKEY ··········"No signing key has been selected. ·Please select a¶
bef8ce ·key\nfrom the dropdown list of signing keys."
240dab ····IDS_RANDOMPROMPT ·······"Enter random input:"
37fe1d ····IDS_RANDOMDONE ·········"Input complete!"
cae0d1 END
e7af5a
fb6f6c STRINGTABLE DISCARDABLE·
104523 BEGIN
869bf6 ····IDS_ERR_OUTOFMEMORY ····"The PGP library has run out of memory."
352398 ····IDS_ERR_WRONGKEYPASSPHRASE·
0ca7fd ····························"The passphrase you entered does not match the pass¶
6909a1 phrase on the key."
890406 ····IDS_ERR_INVALIDFILEOPERROR·
34419f ····························"The action could not be completed due to an invali¶
8cf867 d file operation."
1a2876 ····IDS_ERR_CATCHALL ·······"An internal error (#%i) occurred. ·Please call the¶
859b38 ·Pretty Good Privacy, Inc. technical support line."
dd52be ····IDS_ERR_KEYIOWRITING ···"There was an error during the writing of the keyri¶
afc5a1 ng or the exported file."
e9e775 ····IDS_ERR_NOFILE ·········"There was an error opening or writing the keyring ¶
d9a250 or the output file."
baee28 ····IDS_ERR_RNGNOTSEEDED ···"There is not enough random data currently availabl¶
2d5b4a e."
27849e ····IDS_ERR_INPUTFILENOTEXIST "The specified input file does not exist."
c5c741 ····IDS_ERR_CANNOTUSEUNTRUSTEDKEY·
a525e8 ····························"Cannot use the requested key for this operation be¶
75f9ee cause the key has insufficient validity."
7c04d0 ····IDS_ERR_OUTPUTBUFFERTOOSMALL·
aa15d8 ····························"Cannot perform the requested operation because the¶
e179a3 ·output buffer is too small."
485b7a ····IDS_ERR_KEYRINGCORRUPT ·"The keyring file is corrupt."
5ee0d1 END
3baf5a
8b6f6c STRINGTABLE DISCARDABLE·
844523 BEGIN
90fbc9 ····IDS_SERVEREXISTS ·······"The specifed email domain and server name combinat¶
f83f39 ion already exists in your list."
32f35d ····IDS_NOSERVERNAME ·······"Please enter the URL for the server."
018a0d ····IDS_INFOTEXT ···········"&Info"
4da472 ····IDS_CREDITTEXT ·········"&Credits"
9b26ed ····IDS_WEBLINK ············"http://www.pgp.com/"
c2ac0d ····IDS_NODOMAINNAME ·······"Please enter the email domain for which you want u¶
b63414 se this server."
103c06 ····IDS_SEEDFILEFILTER ·····"RNG seed files (*.rnd; *.bin)@*.rnd;*.bin@All File¶
21912c s (*.*)@*.*@@"
--f2e5 00044d5d61d401102ba Page 14 of PGPcl.rc
8238a5 ····IDS_SEEDFILECAPTION ····"Select Random Number Generator Seed File"
1f1b76 ····IDS_DEFSEEDFILEEXT ·····"bin"
1e6fa3 ····IDS_CAST ···············"CAST"
35fff6 ····IDS_3DES ···············"TripleDES"
b76ec1 ····IDS_IDEA ···············"IDEA"
42eb9a ····IDS_NOADMINFILE ········"This version of PGP requires an Administration Pre¶
a6a4d6 ferences file.\nThis file is either corrupt or not present on your computer.\n ¶
b3a98c Please contact your Security Administrator."
0c6cf4 ····IDS_CLIENTPREFSFILE ····"PGP_Client.prf"
11b698 ····IDS_ADMINPREFSFILE ·····"PGP_Admin.prf"
71e905 ····IDS_CONNECTING ·········"Connecting to "
30e0d1 END
c5af5a
ac6f6c STRINGTABLE DISCARDABLE·
b14523 BEGIN
b5a76b ····IDS_QUERYING ···········"Querying "
fddb00 ····IDS_PROCESSING ·········"Processing results from "
fbf803 ····IDS_EXCHANGING ·········"Exchanging data with server "
8cb93e ····IDS_REGISTRYKEY ········"Software\\Network Associates\\PGP60\\PGPkeys"
58a370 ····IDS_NOSERVERS ··········"No servers available"
63123e ····IDS_SERVEROK ···········"Operation successful on server "
5566f6 ····IDS_SERVERERROR ········"Error communicating with server "
4ba8a4 ····IDS_LOOKINGFORSERVER ···"Looking for server "
b4833f ····IDS_ERRORPREFIX ········"An error has occurred : "
9af12b ····IDS_ERRORMESSAGECAPTION "PGP Warning"
0579e8 ····IDS_ERRORMESSAGE ·······"\n\nThe attempted operation was not completed succ¶
100731 essfully."
b6b6d7 ····IDS_DELETING ···········"Deleting key(s) from "
cf0b07 ····IDS_DISABLING ··········"Disabling key(s) on "
f947c6 ····IDS_CLOSING ············"Closing connection to "
8fe0d1 END
e9af5a
a86f6c STRINGTABLE DISCARDABLE·
ea4523 BEGIN
640f41 ····IDS_RSA ················"RSA"
50d32c ····IDS_DH ·················"DH"
2c4e9f ····IDS_UNKNOWN ············"Unknown"
7b400e ····IDS_CAPTION ············"PGP Warning"
37f6e9 ····IDS_INVALIDWRAP ········"The word wrap column must be greater than zero."
076cfb ····IDS_INVALIDCACHEVALUE ··"You cannot cache passphrases for more than 100 hou¶
83b356 rs"
7714ba ····IDS_PUBKEYRINGFILTER ···"Public Keyring Files (*.pkr; *.pubkr; *.pgp)@*.pkr¶
df1e87 ;*.pubkr;*.pgp@All Files (*.*)@*.*@@"
effc43 ····IDS_DEFPRIVRINGEXT ·····"skr"
010155 ····IDS_DEFPUBRINGEXT ······"pkr"
580a99 ····IDS_ILLEGALFILENAME ····"You have specified an invalid file name."
4cf3a7 ····IDS_BROWSERERROR ·······"Windows is not able to launch your web browser."
ec421e ····IDS_RSADSAMIXWARNING ···"Signing with a Diffie-Hellman/DSS key when encrypt¶
e72f2a ing to\nRSA recipients will result in a message that users of PGP\nversions pri¶
7ecb15 or to 5.0 will not be able to decrypt.\n\nAre you sure you want to do this?\n"
231084 ····IDS_ERR_EXPIRED ········"The evaluation time for PGP encrypting and signing¶
f0af4b ·has passed.\nOperation aborted."
b1dbc4 ····IDS_DOMAIN ·············"Domain"
7a9623 ····IDS_LISTED ·············"Listed"
df9c52 ····IDS_DELKSPROMPT ········"Remove server\n\n%s\n\nfrom your server search lis¶
f55b19 t?"
03e0d1 END
26af5a
f66f6c STRINGTABLE DISCARDABLE·
ca4523 BEGIN
a19c45 ····IDS_ERR_EXTRACTKEYNOTEXIST·
fe79c3 ····························"The specified key could not be found on your keyri¶
aaa237 ng."
3feb54 ····IDS_ERR_SIGONLYKEY ·····"Could not encrypt to specified key because it is a¶
83ad16 ·sign-only key."
8c76e6 ····IDS_ERR_ENCRYPTONLYKEY ·"Could not sign with specified key because it is an¶
270cac ·encrypt-only key."
8f140e ····IDS_ERR_CORRUPTPACKET ··"The keyring contains a bad (corrupted) PGP packet."
06febc ····IDS_ERR_DETSIGFOUND ····"The message/data contains a detached signature."
19896f ····IDS_ERR_NOSECRETKEYS ···"No secret keys could be found on your keyring."
de0ebe ····IDS_ERR_DUPLICATEUSERID "The specified user ID was not added because it alr¶
443773 eady exists on the selected key."
--7a4c 0004a7c591a401102ba Page 15 of PGPcl.rc
6648ce ····IDS_ERR_DUPLICATECERT ··"This key is already signed by the specified signin¶
220e20 g key."
059dc8 ····IDS_ERR_FILEPERMISSIONS "Unable to perform operation because this file is r¶
906cfc eadonly or otherwise protected.\nIf you store your keyring files on removable m¶
ec908b edia the media may not be inserted."
69135b ····IDS_PHRASEMISMATCH ·····"Passphrase entries do not match. ·Please try again¶
e5acf9 ."
056a3f ····IDS_EMPTYPHRASE ········"You must enter a passphrase or click on ""Cancel""¶
76acf9 ."
476212 ····IDS_SERVERABORT ········"Canceled operation on server "
b4dde5 ····IDS_SEARCHABORT ········"Canceled key search on server "
4886f6 ····IDS_SEARCHOK ···········"Key(s) downloaded from server "
be33e8 ····IDS_SEARCHERROR ········"Key search error on server "
9b73b0 ····IDS_WRONGPHRASE ········"&Re-enter phrase or select a different key"
cce0d1 END
77af5a
266f6c STRINGTABLE DISCARDABLE·
0a4523 BEGIN
6a65ab ····IDS_PHRASEPROMPT ·······"&Passphrase for selected key :"
92d4dc ····IDS_DELETESERVEROK ·····"Key(s) deleted from server."
34f25e ····IDS_DELETESERVERABORT ··"Canceled deleting key(s) on server."
dd34e2 ····IDS_DELETESERVERERROR ··"Error deleting key(s) from server."
cc2b24 ····IDS_DISABLESERVEROK ····"Key(s) disabled on server."
e9bd76 ····IDS_DISABLESERVERABORT ·"Canceled disabling key(s) on server."
e3950c ····IDS_DISABLESERVERERROR ·"Error disabling key(s) on server."
3c8f06 ····IDS_UNKNOWNKEYS ········"%i unknown key(s)"
6eda56 ····IDS_NEEDALGORITHM ······"At least one encryption algorithm must be enabled ¶
da920b at all times."
669027 ····IDS_DSS ················"DSS"
8c92b9 ····IDS_ERR_KEYFAILEDPOLICY "The key you are trying to add to the server has fa¶
30c659 iled the server policy check.\nThe key will be stored in a Pending area for rev¶
7a7e6d iew by the Server Administrator."
de162c ····IDS_ERR_INCOMPATIBLESDKAPI·
c9b405 ····························"This application is not compatible with the versio¶
8bcffb n of the PGP SDK \nlibrary which is installed on your computer. "
a7da94 ····IDS_GROUPFILENAME ······"PGPgroup.pgr"
5893b2 ····IDS_EDITSERVERTITLE ····"Edit Server"
eed91f ····IDS_ERR_UNSUPPORTEDHTTPFILTER·
67a6c9 ····························"One or more of the search types you have selected ¶
dd290c are not compatible with HTTP-based servers. \nOnly LDAP-based servers support t¶
dd53b4 he selected search."
7202ef ····IDS_ERR_NOSIGNINGKEYFORSEARCH·
5d2a71 ····························"The user ID you have entered could not be found on¶
1ccc27 ·your keyring.\nA search for signatures cannot be performed without the signing¶
53b5e3 ·key."
50e0d1 END
56af5a
096f6c STRINGTABLE DISCARDABLE·
234523 BEGIN
e0abf8 ····IDS_FOUNDMATCHFORPHRASE "The key with user ID\n\n%s\n\nmatches the passphra¶
0ac54b se.\n\nSign with this key instead?"
937471 ····IDS_PGP ················"PGP"
19217b ····IDS_BADDECRYPTPHRASE ···"The phrase you entered does not match any of the u¶
73ed5a sable listed keys."
d18598 ····IDS_WRONGDECRYPTPHRASE ·"&Re-enter phrase of your private key"
493731 ····IDS_BETATIMEOUT ········"Thank you for testing Pretty Good Privacy. ·The %i¶
4d11ff \nday beta period has expired. ·Please order your\npermanent copy today, or uni¶
6d8938 nstall PGP through the\nWindows Control Panel-Add/Remove Programs applet.\nVisi¶
bff73d t http://www.pgp.com to order a registered copy.\n"
58d10b ····IDS_EVALTIMEOUT ········"Thank you for evaluating Pretty Good Privacy. ·The¶
eb258f ·%i\nday evaluation period has expired. ·Please order your\npermanent copy toda¶
f41dd8 y.\n\nVisit http://www.pgp.com to order a registered copy.\n"
947f4e ····IDS_VALIDITYFIELD ······"Validity"
e8f87a ····IDS_DESCRIPTIONFIELD ···"Description"
c9e0d1 END
dcaf5a
ab6f6c STRINGTABLE DISCARDABLE·
a04523 BEGIN
6ba416 ····IDS_PASSPHRASEMISMATCH ·"Passphrase entries do not match. ·Please try again¶
3facf9 ."
97c307 ····IDS_CAPTIONKEYGEN ······"PGPkeys Key Generation"
4a7207 ····IDS_IMPORTCAPTION ······"Select File Containing Key"
--1e0a 0001bfb1e16401102ba Page 16 of PGPcl.rc
0d8809 ····IDS_EXPORTCAPTION ······"Export Key to File"
d7e565 ····IDS_DELCONFCAPTION ·····"Delete Confirmation"
7b768e ····IDS_DELCONFPRIVKEY ·····"Are you sure you want to delete your public/privat¶
d3dea6 e key pair :\n\n%s ?"
0be0d1 END
95af5a
c36f6c STRINGTABLE DISCARDABLE·
ef4523 BEGIN
58e1d5 ····IDS_DELCONFKEY ·········"Are you sure you want to delete this key :\n\n%s ?"
5b3fc2 ····IDS_DELCONFUSERID ······"Are you sure you want to delete this name :\n\n%s ¶
a973b0 ?"
3ab459 ····IDS_DELCONFCERT ········"Are you sure you want to delete this signature :\n¶
e34274 \n%s ?"
fcc266 ····IDS_NAMEFIELD ··········"Keys"
af2fdc ····IDS_TRUSTFIELD ·········"Trust"
6d9ea3 ····IDS_CREATIONFIELD ······"Creation"
c43dc6 ····IDS_SIZEFIELD ··········"Size"
854f5e ····IDS_VALIDITY0 ··········"Unknown"
c2fce2 ····IDS_VALIDITY1 ··········"Invalid"
0720c5 ····IDS_VALIDITY2 ··········"Marginal"
cf09ba ····IDS_VALIDITY3 ··········"Complete"
50e0d1 END
80af5a
db6f6c STRINGTABLE DISCARDABLE·
044523 BEGIN
fa3a02 ····IDS_DELCONFDEFKEY ······"You are about to delete your default signing/encry¶
84bf77 ption key.\nAre you sure you want to do this ?"
96ef65 ····IDS_DROPFILENAME ·······"Exported PGP Key(s)"
d1ac32 ····IDS_CERTKEYNOTONRING ···"The private key used to create this signature\nis ¶
4c36da not on your keyring."
38ff0d ····IDS_NOIMPORTKEYS ·······"The selected file does not contain any valid PGP k¶
f704d0 eys."
5641c4 ····IDS_NOIMPORTKEYSPASTE ··"The clipboard does not contain any valid PGP keys."
629b29 ····IDS_DELONLYUSERID ······"This user ID cannot be deleted because it is the\n¶
cd7f78 only one on the key.\n\nTo delete this user ID, you must delete the entire key."
566aa9 ····IDS_IMPORTEDSECRETKEYS ·"Some of the imported keys are private keys.\n\nThe¶
148607 ·trust values on these keys must be\nset manually via the Key Properties dialog¶
9facf9 ."
a76fe4 ····IDS_TRUST2 ·············"Untrusted"
fe0f1a ····IDS_TRUST3 ·············"Marginal"
78dd3e ····IDS_TRUST4 ·············"Complete"
5fd659 ····IDS_TRUST5 ·············"Ultimate"
7780e8 ····IDS_SIGNKEYPASSPHRASE ··"&Passphrase of signing key :"
abe3b1 ····IDS_SELKEYPASSPHRASE ···"&Passphrase of selected key :"
20f568 ····IDS_IMPORTFILTER ·······"Text Files (*.txt; *.asc)@*.txt;*.asc@Keyring File¶
04458f s (*.pkr; *.skr; *.pgp; *.pubkr; ...)@*.pgp;*.pkr;*.skr;*.pubkr;*.prvkr;*.aexpk¶
e659ef @All Files (*.*)@*.*@@"
b0bb10 ····IDS_PROPTITLE0 ·········"General"
678863 ····IDS_DSA_ELGAMAL ········"DH/DSS"
4ee0d1 END
a9af5a
126f6c STRINGTABLE DISCARDABLE·
e74523 BEGIN
f66483 ····IDS_NEVER ··············"Never"
813059 ····IDS_NODRAGTEXTKEYS ·····"The selected text does not contain any valid PGP k¶
d304d0 eys."
f8df9f ····IDS_DEFEXPORTEXTENSION ·"asc"
08d435 ····IDS_ERRONEOUSADK ·······" -- this ADK is erroneous --"
709d02 ····IDS_NOUSERNAME ·········"Each key must have a name."
c337bb ····IDS_REVOKECONFIRM ······"Are you sure you want to revoke this key?\nOnce di¶
a1dcf2 stributed, others will be unable to encrypt data to this key."
6506c8 ····IDS_TRUSTONINVALIDKEY ··"This is an invalid key. ·Modifying the trust on th¶
5aa387 is key is not allowed\nsince trust settings on invalid keys have no effect."
e53728 ····IDS_CERTIFYERROR ·······"Cannot sign\n\n%s\n\n%s"
35088c ····IDS_REVCONFDEFKEY ······"You are about to revoke your default signing/encry¶
f6a163 ption key.\nYou will no longer be able to sign with this key, and once \ndistri¶
ac06c5 buted, others will be unable to encrypt data to this key.\n\nAre you sure you w¶
897b3e ant to do this ?"
0c7e16 ····IDS_UNAVAILABLECERT ····"Unknown Signer, Key ID is %s"
fc1693 ····IDS_NOUSERADDR ·········"In order to take full advantage of PGP's email int¶
85864f egration\nfeatures, each name must have an associated email address.\nAre you s¶
1b7bb1 ure you want to proceed without entering an email address?"
--7478 000280a05f8401102ba Page 17 of PGPcl.rc
ce0bb1 ····IDS_EXPORTFILTER ·······"ASCII Key File (*.asc)@*.asc@@"
e24745 ····IDS_INVALIDDATE ········"Unknown"
c62950 ····IDS_USERID ·············"Key/User Name"
96bb8b ····IDS_FINGERPRINT ········"Fingerprint"
b3e0d1 END
86af5a
b86f6c STRINGTABLE DISCARDABLE·
624523 BEGIN
df6c46 ····IDS_KEYIDFIELD ·········"Key ID"
5f2995 ····IDS_EXPIRATIONFIELD ····"Expiration"
f5bba6 ····IDS_ADKFIELD ···········"ADK"
ddaa71 ····IDS_RSAPUBKEY ··········"RSA public key"
74b0a0 ····IDS_RSASECKEY ··········"RSA key pair"
7db9f8 ····IDS_RSAPUBEXPKEY ·······"Expired RSA public key"
1f1168 ····IDS_RSAPUBREVKEY ·······"Revoked RSA public key"
e5ba4f ····IDS_RSAPUBDISKEY ·······"Disabled RSA public key"
ebf345 ····IDS_RSASECDISKEY ·······"Disabled RSA key pair"
ecae4b ····IDS_RSASECEXPKEY ·······"Expired RSA key pair"
8974ee ····IDS_RSASECREVKEY ·······"Revoked RSA key pair"
8514a7 ····IDS_DSAPUBKEY ··········"DH/DSS public key"
a37b81 ····IDS_DSASECKEY ··········"DH/DSS key pair"
3fac79 ····IDS_DSAPUBEXPKEY ·······"Expired DH/DSS public key"
64443f ····IDS_DSAPUBREVKEY ·······"Revoked DH/DSS public key"
0be0d1 END
06af5a
b36f6c STRINGTABLE DISCARDABLE·
f74523 BEGIN
bfaa20 ····IDS_DSAPUBDISKEY ·······"Disabled DH/DSS public key"
c14148 ····IDS_DSASECDISKEY ·······"Disabled DH/DSS key pair"
8fc321 ····IDS_DSASECEXPKEY ·······"Expired DH/DSS key pair"
7e5700 ····IDS_DSASECREVKEY ·······"Revoked DH/DSS key pair"
af944d ····IDS_RSAUSERID ··········"User ID"
dc4975 ····IDS_DSAUSERID ··········"User ID"
291a33 ····IDS_CERT ···············"signature"
80ed3e ····IDS_REVCERT ············"revoked signature"
643861 ····IDS_BADCERT ············"corrupt signature"
ad98a6 ····IDS_KEYSELECTED ········" %i key(s) selected"
8df74b ····IDS_UIDSELECTED ········" %i user ID(s) selected"
ecc118 ····IDS_CERTSELECTED ·······" %i signature(s) selected"
129d5f ····IDS_MULTISELECTED ······" %i objects selected"
be77c7 ····IDS_UPLOADOK ···········"Key(s) successfully uploaded to server."
26c6b9 ····IDS_REQMINPHRASELEN ····"The passphrase you entered does not meet the minim¶
55a8cc um required length of %i characters.\n\nPlease enter a longer passphrase."
f40437 ····IDS_SUGMINPHRASELEN ····"The passphrase you entered does not meet the minim¶
72768c um suggested length of %i characters.\n\nA short passphrase may compromise the ¶
01df5c security of your key.\n\nAre you sure you want to use the passphrase you entere¶
4d98b8 d?"
d0e0d1 END
46af5a
1f6f6c STRINGTABLE DISCARDABLE·
964523 BEGIN
4ee26b ····IDS_REQMINPHRASEQUAL ···"The passphrase you entered does not meet the minim¶
60dc4a um required quality of %i out of 100.\n\nPlease enter a higher quality passphra¶
dd5375 se."
3b20e5 ····IDS_SUGMINPHRASEQUAL ···"The passphrase you entered does not meet the minim¶
e5a613 um suggested quality of %i out of 100.\n\nA low-quality passphrase may compromi¶
a2993c se the security of your key.\n\nAre you sure you want to use the low-quality pa¶
fbfbe3 ssphrase you entered?"
defe93 ····IDS_QUERYCONTINUESIGNING·
ce46c9 ····························"You have canceled the automatic key update from th¶
a9cc5c e server.\n\nDo you wish to continue with signing the key(s) ?"
33a6c0 ····IDS_QUERYCONTINUEREVOKINGKEY·
4f46c9 ····························"You have canceled the automatic key update from th¶
df941f e server.\n\nDo you wish to continue with revoking this key ?"
ffe46e ····IDS_QUERYCONTINUEREVOKINGCERT·
5346c9 ····························"You have canceled the automatic key update from th¶
9ba3f7 e server.\n\nDo you wish to continue with revoking this signature ?"
efc0fc ····IDS_QUERYCONTINUEADDING "You have canceled the automatic key update from th¶
015163 e server.\n\nDo you wish to continue with adding to this key?"
a838c5 ····IDS_DELETEFROMSERVEROK ·"Key(s) successfully deleted from server."
691dd7 ····IDS_DISABLEONSERVEROK ··"Key(s) successfully disabled on server."
28d92f ····IDS_EXPORTCERT ·········"exportable signature"
--b9b8 000c5dbb633401102ba Page 18 of PGPcl.rc
a8763c ····IDS_METACERT ···········"meta-introducer signature"
1930b4 ····IDS_EXPORTMETACERT ·····"trusted introducer signature"
8bfc21 ····IDS_SERVERSEARCHFAIL ···"No matching keys were found on the server."
71b4c8 ····IDS_UNKNOWNADK ·········" Unknown Key"
4de2de ····IDS_UNKNOWNADKID ·······" Unknown Key, Key ID is "
37bd12 ····IDS_KEYALREADYONSERVER ·"The selected key was already on the server."
aa9597 ····IDS_KEYSALREADYONSERVER "One or more of the selected keys was already on th¶
6d4776 e server."
c2e0d1 END
14af5a
c56f6c STRINGTABLE DISCARDABLE·
c94523 BEGIN
3ff2fa ····IDS_PROPTITLE1 ·········"Subkeys"
4f34cb ····IDS_PROPTITLE2 ·········"ADK"
fc4d0c ····IDS_VALIDFROM ··········" ···Valid from"
2b9655 ····IDS_EXPIRES ············"Expires"
b50b21 ····IDS_SIZE ···············"Size"
605947 ····IDS_BADSUBKEYSIZE ······"Subkey size must be between %i and 4096 bits."
56f544 ····IDS_DELETESUBKEYCONF ···"Are you sure you want to delete this subkey ?"
06c155 ····IDS_UNKNOWNKEY ·········"<unknown>"
49b336 ····IDS_SHARES ·············"Shares"
b9996c ····IDS_SAVESHARES ·········"Select folder to receive split key share files."
8b07c3 ····IDS_SHAREPHRASEPROMPT ··"Enter &passphrase to protect these shares :"
47cc1e ····IDS_SPLITKEYTITLE ······"Split Key : "
93a90a ····IDS_SPLITKEYPHRASEPROMPT "&Enter passphrase for key to be split :"
7f1427 ····IDS_DEFSHAREEXTENSION ··"shf"
783bb6 ····IDS_DEFSHARENAME ·······"User"
6ee0d1 END
f3af5a
ff6f6c STRINGTABLE DISCARDABLE·
514523 BEGIN
55304f ····IDS_PHOTOIDPHRASE ······"Creating photo User ID ... Enter phrase of key :"
63294d ····IDS_PHOTOUSERID ········"Photograph"
f6a066 ····IDS_UNKNOWNUSERID ······"Unrecognized user ID format"
c6f0df ····IDS_ERR_IMAGETOOBIG ····"The specified image is too large."
1cb44e ····IDS_ERR_INVALIDIMAGE ···"The specified image is corrupt or of an unsupporte¶
1ac747 d type.\n\nPGPkeys currently supports importing photos in JPEG or BMP formats."
ec82ee ····IDS_REVOKESUBKEYCONF ···"You are about to revoke an encryption subkey for t¶
e896d4 his key.\nOnce distributed, others will no longer be able to encrypt data to th¶
981e45 is subkey.\n\nAre you sure you want to do this?"
23c43d ····IDS_REMOVESUBKEYCONF ···"Removing an encryption subkey cannot be undone.\nA¶
75abb8 nything encrypted to the selected subkey(s) will no longer be able to be decryp¶
59a93b ted.\n\nAre you sure you want to do this?"
d82039 ····IDS_REMOVEONLYSUBKEYCONF·
9316b7 ····························"This key has only one encryption subkey.\nAnything¶
abd6b6 ·encrypted to the selected subkey will no longer be able to be decrypted.\nIf y¶
68f2d2 ou remove this subkey, the master key will become a signing-only key.\n\nAre yo¶
0962a7 u sure you want to do this?"
ed594e ····IDS_NUMSHARES ··········" %i Shares"
011a28 ····IDS_ONESHARE ···········" 1 Share"
5fe0d1 END
d7af5a
596f6c STRINGTABLE DISCARDABLE·
b44523 BEGIN
db614b ····IDS_SHAREFILEFILTER ····"Share Files (*.shf)@*.shf@All Files (*.*)@*.*@@"
247690 ····IDS_SHAREFILECAPTION ···"Select Share File"
845e78 ····IDS_STATUSNOTCONNECTED ·"Not Connected"
d3e0d1 END
1daf5a
256f6c STRINGTABLE DISCARDABLE·
c84523 BEGIN
6a2476 ····IDS_STATUSCONNECTING ···"Connecting ... "
2c5870 ····IDS_STATUSCONNECTED ····"Connected"
31d30b ····IDS_STATUSSENDING ······"Sending ... "
ce9976 ····IDS_STATUSCLOSING ······"Closing Connection ... "
5f9387 ····IDS_SENDAUTHPROMPT ·····"&Passphrase for remote computer authentication :"
36c6bc ····IDS_DECRYPTSHARESPROMPT "Share decryption &passphrase :"
ff3467 ····IDS_STATUSAUTHENTICATED "Authenticated"
2b4f0a ····IDS_SPLITKEYCONFIRMATION·
5f0b64 ····························"The key you are splitting will no longer be able t¶
0e82ef o decrypt or\nsign without rejoining the required shares.\n\nAre you sure you w¶
c5be03 ant to do this?"
--5478 000462fd411401102ba Page 19 of PGPcl.rc
88ae99 ····IDS_SENDSUCCESS ········"Shares were successfully sent to remote computer."
a40359 ····IDS_CREATINGSHARES ·····"Creating Shares ..."
ccacd6 ····IDS_SAVINGSHARES ·······"Saving Shares for "
a86f7b ····IDS_SPLITTINGKEY ·······"Splitting Key ..."
ae0557 ····IDS_SPLITKEYGONE ·······"The key to be split is no longer on the keyring."
07cfaa ····IDS_SHAREKEYGONE ·······"The key cannot be split because the following publ¶
b28e7e ic key is no longer on the keyring :\n\n"
f93b9f ····IDS_RECONKEYTITLE ······"Key Share Collection : "
09240a ····IDS_SHAREKEYMISMATCH ···"The selected share file does not pertain to this k¶
998838 ey."
5de0d1 END
70af5a
d76f6c STRINGTABLE DISCARDABLE·
124523 BEGIN
7c6d7d ····IDS_SHARENUMMISMATCH ···"The selected share file is not from the same split¶
a22d78 \noperation as the previously collected shares."
6c1034 ····IDS_RSASECSHRKEY ·······"Split RSA key pair"
318143 ····IDS_DSASECSHRKEY ·······"Split key pair"
6a51e9 ····IDS_ERR_INVALIDCOMMONCONTROLS·
57c7f1 ····························"This version of PGP requires a newer version of th¶
669e90 e Windows system file COMCTL32.DLL than is currently installed on your computer¶
9a121c .\n\nThe PGP installation program should have updated your system for you. ·If ¶
a6156e you installed this copy of PGP ""by hand"" then you should remove it and use th¶
cdbd26 e installation program."
ab6cc9 ····IDS_STARTNETWORK ·······"Start &Network"
adda66 ····IDS_STOPNETWORK ········"Stop &Network"
676147 ····IDS_STATUSRECEIVING ····"Receiving ..."
4744b7 ····IDS_RECONAUTHPROMPT ····"Key and &passphrase for authentication :"
9e2101 ····IDS_PREPARINGTOVERIFY ··"Preparing list of signatures to verify ..."
0a2c3d ····IDS_VERIFYING ··········"Reverifying signatures ..."
89407c ····IDS_UNIDENTIFIEDHOST ···"unidentified remote computer"
a58681 ····IDS_SERVER ·············"Server"
9f1227 ····IDS_LDAP ···············"LDAP"
684564 ····IDS_LDAPS ··············"LDAPS"
76bde7 ····IDS_HTTP ···············"HTTP"
1b91b6 ····IDS_BADPASSKEY ·········"The passphrase formed by the collected shares is n¶
51b494 ot able to unlock the key."
9be0d1 END
08af5a
5b6f6c STRINGTABLE DISCARDABLE·
cd4523 BEGIN
c60c9f ····IDS_BITMAPFILTER ·······"JPEG Files (*.jpg, *.jpeg)@*.jpg;*.jpeg@Bitmap Fil¶
633f6a es (*.bmp)@*.bmp@@"
e8519d ····IDS_OPENBITMAPTITLE ····"Select an image file :"
380912 ····IDS_EXPCERT ············"Expired Signature"
1c7dde ····IDS_NEWPHRASEPROMPT ····"Enter new &passphrase for key :"
f6a3c6 ····IDS_PHRASECHANGED ······"The passphrase has been changed."
0a2e30 ····IDS_RECONSTITUTEKEY ····"&Join Key ..."
cd2534 ····IDS_KEYRECONSTITUTED ···"The split key has been rejoined.\n\nAll old share ¶
9b22d3 files for this key are no longer valid."
c11d5d ····IDS_CHANGEPHRASE ·······"Change &Passphrase ..."
803679 ····IDS_DUPLICATESHARES ····"The selected share file contains shares which you ¶
d3a993 have already collected."
43a796 ····IDS_LICENSEDTO ·········"Licensed to :"
24177c ····IDS_VERSION ············"Version :"
84e8f0 ····IDS_NOROOTSERVER ·······"This operation requires that a Trusted Root Server¶
bab030 ·is selected in the Server Preferences."
af834c ····IDS_UNEXPECTEDAUTHKEY ··"The key used by the server to authenticate itself ¶
f604b5 is different from the key normally associated with this server. ·Please Confirm¶
529c17 ·the use of this key or press Cancel to abort the connection."
14e055 ····IDS_INVALIDAUTHKEY ·····"The key used by the remote system to authenticate ¶
54e487 the connection is not valid on the local keyring. ·Please Confirm the use of th¶
fb8517 is key or press Cancel to abort the connection."
75d9df ····IDS_NEWAUTHKEY ·········"This server is authenticating itself to you for th¶
01a7ea e first time. ·Please Confirm the use of the above authentication key or press ¶
f13c9b Cancel to abort the connection."
99e0d1 END
76af5a
476f6c STRINGTABLE DISCARDABLE·
4d4523 BEGIN
296055 ····IDS_ENFORCEFIELD ·······"Enforce"
465dab ····IDS_IMPORT ·············"&Import"
--e0fd 00097a5318a401102ba Page 20 of PGPcl.rc
4a28cd ····IDS_ADDREVOKERPROMPT ···"Select the key(s) you would like to be able to rev¶
1adba9 oke your key :"
9b68c4 ····IDS_QUERYADDPROMPT ·····"Select the key(s) you would like to import to your¶
5e4ea2 ·keyring :"
aa8601 ····IDS_ADDEDREVOKERS ······"The selected key(s) have been granted the ability ¶
5f2bf6 to revoke your key.\nYou may want to distribute current copies of your key to t¶
621157 he revokers or upload your key to the server now."
6d665d ····IDS_ADDREVOKERCONFIRM ··"Are you sure you would like to grant the ability t¶
e629ad o revoke your key to the selected key(s)?"
1cd621 ····IDS_NOTENOUGHKEYSTOADDREVOKER·
3b6da1 ····························"You need at least one other non-RSA key on your ke¶
e4d877 yring in order to add a revoker to the selected key."
c3d1cb ····IDS_STATUSFINISHED ·····"Finished"
8b7d41 ····IDS_DONE ···············"&Done"
8d9adb ····IDS_DUPLICATESERVER ····"The specified server is already listed."
50cb09 ····IDS_IMPORTKEYERROR ·····"Error importing the key(s) to the keyring."
898e10 ····IDS_PROPTITLE3 ·········"Revokers"
d530cd ····IDS_ERRONEOUSREVOKER ···" -- this revoker is erroneous --"
8117fe ····IDS_VALIDAUTHKEY ·······"If this is the expected key, press the Confirm but¶
0785bd ton."
2b03d8 ····IDS_ERR_FILEOPFAILED ···"Operation could not be completed because a file op¶
e8b205 eration error has occurred."
b2c924 ····IDS_KEYNOTSIGNEDBYCORP ·"Warning! Key not signed by corporate key.\n\nDo yo¶
e0638f u want to continue?"
60e0d1 END
3daf5a
796f6c STRINGTABLE DISCARDABLE·
0e4523 BEGIN
ced0c8 ····IDS_NOVALIDDEFAULTKEY ··"Could not find valid Default Key! Please\ncheck yo¶
1c2d72 ur settings in PGPkeys."
8ee64a ····IDS_NOOUTADK ···········"The Outgoing Additional Decryption Key\nconfigured¶
931369 ·for this PGP could not be found.\nPlease contact your security administrator."
aecf0f ····IDS_NOCORPSIGNKEY ······"Could not find valid Corporate Signing Key!\nConta¶
9f2bc5 ct your security administrator."
bd7bb4 ····IDS_TEXTOUTPUT ·········"&Text Output"
c17ba2 ····IDS_CONVENCRYPTION ·····"Conventional &Encryption"
8a1bfc ····IDS_WIPEORIGINAL ·······"&Wipe Original"
2a7d03 ····IDS_ATLEASTONEORCONV ···"You must select at least one key or use\nconventio¶
61418f nal encryption."
d22211 ····IDS_DETACHEDSIG ········"&Detached Signature"
6d3f30 ····IDS_ANIMATIONFILE ······"KeyGen.avi"
dbf0d4 ····IDS_PHOTOIDALREADYEXISTS·
1f81da ····························"The key you have selected already has a Photo asso¶
108d93 ciated with it.\nYou may not add another without deleting the old Photo."
b16c17 ····IDS_ADDEDSENTREVOKERS ··"The selected key(s) have been granted the ability ¶
c22bf6 to revoke your key.\nYou may want to distribute current copies of your key to t¶
70d734 he revokers now."
19b6ca ····IDS_STATUSLISTENING ····"Listening ..."
6880dd ····IDS_MUSTHAVEDEFAULTSERVER·
391399 ····························"You are not allowed to perform this operation beca¶
616a14 use you must\nhave at least one server which can serve Any domain."
5e61a3 ····IDS_SPLITKEYSNOTALLOWED "Split keys are not allowed for this operation."
6f5a2d ····IDS_BADSHAREFILEPASSPHRASE "Bad &Passphrase. Please re-enter:"
a5125d ····IDS_KEYRINGFOLDER ······"PGP Keyrings"
91e0d1 END
21af5a
9b6f6c STRINGTABLE DISCARDABLE·
bd4523 BEGIN
2abe6c ····IDS_FYEO ···············"&Secure Viewer"
ad2f25 ····IDS_WIPEWODEFAULT ······"You have chosen not to encrypt to yourself and you¶
dfa690 ·are\nwiping the original item(s). You will not be able to decrypt\nthe resulti¶
d43093 ng item(s) nor will you have the original files.\n\nAre you sure you want to do¶
179e58 ·this?"
6be0d1 END
b8af5a
831b3a #endif ···// English (U.S.) resources
5c6c0e /////////////////////////////////////////////////////////////////////////////
bbaf5a
9eaf5a
b5af5a
5dce8c #ifndef APSTUDIO_INVOKED
976c0e /////////////////////////////////////////////////////////////////////////////
--30da 0018acc88ff401102ba Page 21 of PGPcl.rc
c1465d //
8e8464 // Generated from the TEXTINCLUDE 3 resource.
46465d //
476e4b #include "CLSplash.rc"
b718da #include "PGPclVer.rc"
44e9d2 #include "CLNag.rc"
a36c0e /////////////////////////////////////////////////////////////////////////////
a98072 #endif ···// not APSTUDIO_INVOKED
8aaf5a
--cbe4 001fd6e7bbd401102bb Page 1 of PGPclVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
8862d4 ············VALUE "FileDescription", "PGP Client Library\0"
65c1dd ············VALUE "FileVersion", PGPVERSIONSTRING
eb8189 ············VALUE "InternalName", "PGP60cl\0"
bd8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
a72bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
64d35e ············VALUE "OriginalFilename", "PGP60cl.dll\0"
669317 ············VALUE "ProductName", PGPPRODUCTNAME
e1d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
10f37f ········END
807d01 ····END
e026ab ····BLOCK "VarFileInfo"
4f5574 ····BEGIN
294b11 ········VALUE "Translation", 0x409, 1200
bb7d01 ····END
b2e0d1 END
34af5a
0caf5a
fdaf5a
--0b5e 0008de1339f401102bc Page 1 of PGPclx.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
92e601 ¤   PGPclx.h - internal header for PGPcl project
ee67c5 ¤
6baf5a
feb4f8 ¤   $Id: PGPclx.h,v 1.23 1998/08/11 14:43:43 pbj Exp $
edf7f7 ____________________________________________________________________________*/
dafa42 #ifndef Included_PGPclx_h¤  /* [ */
8e8fae #define Included_PGPclx_h
0caf5a
cb2a68 #define WIN32_LEAN_AND_MEAN
3eaf5a
fffc2c // system header files
385655 #include <windows.h>
5790fb #include <commctrl.h>
597cab #include <stddef.h>
caaf5a
897b85 // PGP build flags
0881a4 #include "pgpBuildFlags.h"
70af5a
a5d495 // PGP SDK header files
aae684 #include "pgpUserInterface.h"
dfc5d5 #include "pgpBase.h"
270d08 #include "pgpMem.h"
b9a076 #include "pgpKeys.h"
d62f8d #include "pgpErrors.h"
f14919 #include "pgpUtilities.h"
6ec2ae #include "pgpGroups.h"
e504f5 #include "pgpFeatures.h"
4b91b9 #include "pgpSDKPrefs.h"
52e8b2 #include "pflPrefs.h"
aa4720 #include "pflPrefTypes.h"
7d3991 #include "pgpAdminPrefs.h"
bec97b #include "pgpClientPrefs.h"
fd894b #include "pgpFileSpec.h"
b6fbe2 #include "pgpMemoryIO.h"
cc6aa0 #include "pgpWordWrap.h"
e3af5a
238687 // PGP client header files
b0cda8 #include "..\include\help\PGPclHlp.h"
f54f73 #include "..\include\PGPWerr.h"
37b5ac #include "..\include\PGPcl.h"
eeaf5a
557a15 // local header files
cd8031 #include "resource.h"
28af5a
5e7274 // macro definitions
7ca8fa #define CKERR¤  ¤   if (IsPGPError (err)) goto done
78af5a
31efc6 // common definitions
72ec82 #define IDC_KSTREELIST¤ ¤   5555
ab62c1 #define IDC_ADKTREELIST¤¤   5556
28a8e6 #define IDC_REVOKERTREELIST¤5557
76af5a
435bee // typedefs
def0f7 typedef struct {
26deec ¤   HWND¤   ¤   ¤   ¤   hwnd;
799d52 ¤   PGPKeySetRef¤   ¤   keysetMain;
a643e9 ¤   PGPKeyServerEntry*¤ pentry;
53c094 } CLIENTSERVERSTRUCT, *PCLIENTSERVERSTRUCT;
f8af5a
e49ea5 // prototypes
6f54b1 // CLcache.c
3554e0 VOID PGPInitPassphraseCaches (PGPContextRef context);
45707b VOID PGPClosePassphraseCaches (VOID);
6aaf5a
d0939a // CLMisc.c
04bfb2 VOID* clAlloc (UINT uBytes);
c8b2d1 VOID clFree (VOID* p);
8dcda6 VOID CLPaintUserInfo (
--9b3c 0004c30b536401102bc Page 2 of PGPclx.h
e8c031 ¤   ¤   PGPMemoryMgrRef¤memMgr,·
13e0af ¤   ¤   HWND¤   ¤   ¤   hwnd,
2dafdf ¤   ¤   HDC¤¤   ¤   ¤   hDC,·
d2103a ¤   ¤   LPSTR¤  ¤   ¤   pszVersion);
ff782c LRESULT PGPclMessageBox (
86fd31 ¤   ¤   HWND¤   ¤   ¤   hWnd,·
155d79 ¤   ¤   INT¤¤   ¤   ¤   iCaption,·
e115c2 ¤   ¤   INT¤¤   ¤   ¤   iMessage,·
10462a ¤   ¤   ULONG¤  ¤   ¤   ulFlags);
5f9646 HBITMAP CLLoadResourceBitmap (
87ab83 ¤   ¤   HINSTANCE¤  ¤   hInstance,·
317450 ¤   ¤   LPSTR¤  ¤   ¤   lpString,
e9b3fe ¤   ¤   HPALETTE*¤  ¤   lphPalette);
2ac431 BOOL CLAddKeysToMain (
7efb68 ¤   ¤   PGPContextRef¤  context,·
00e0af ¤   ¤   HWND¤   ¤   ¤   hwnd,
373e7d ¤   ¤   PGPKeySetRef¤   keysetToAdd,
f234a0 ¤   ¤   PGPKeySetRef¤   keysetMain);
f6af5a
518960 // CLksPref.c
feab3a HWND CLCreateKeyserverTreeList (
31ca38 ¤   ¤   PGPPrefRef¤ ¤   PrefRef,·
86fb68 ¤   ¤   PGPContextRef¤  context,·
a1ae5d ¤   ¤   HWND¤   ¤   ¤   hWndParent,
7a34a0 ¤   ¤   PGPKeySetRef¤   keysetMain);
88cc70 INT CLDestroyKeyserverTreeList (HWND hWndTree);
ae19e5 INT CLNewKeyserver (HWND hWndParent, HWND hWndTree);
fe3793 VOID CLRemoveKeyserver (HWND hWndParent, HWND hWndTree);
1e9f3a INT CLSetDefaultKeyserver (HWND hWndParent, HWND hWndTree);
d993e8 INT CLProcessKeyserverTreeList (
cfac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
c2bd0e ¤   ¤   HWND¤   ¤   ¤   hWndTree,·
73da26 ¤   ¤   WPARAM¤ ¤   ¤   wParam,·
77f84b ¤   ¤   LPARAM¤ ¤   ¤   lParam);
97bce9 INT CLSaveKeyserverPrefs (
f4ca38 ¤   ¤   PGPPrefRef¤ ¤   PrefRef,·
ccac82 ¤   ¤   HWND¤   ¤   ¤   hWndParent,·
bda1df ¤   ¤   HWND¤   ¤   ¤   hWndTree);
038450 VOID CLEditKeyserver (HWND hWndParent, HWND hWndTree);
d82654 VOID CLSetKeyserverAsRoot (HWND hWndParent, HWND hWndTree);
49af5a
932d96 // CLsdksrv.c
f99f7a PGPError CLHandleTLSEvent (
b59cd4 ¤   ¤   PGPContextRef¤  ¤   context,
a852d4 ¤   ¤   PGPEvent*¤  ¤   ¤   pevent,
cf317d ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,
1be561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
53108c ¤   ¤   PGPKeyServerEntry*¤ pentry,
721661 ¤   ¤   BOOL*¤  ¤   ¤   ¤   pbSecure);
d7af5a
ba3f05 // CLsrvprf.c
bfff26 PGPError CLInitKeyServerPrefs(
477022 ¤   ¤   PGPUInt32¤  ¤   ¤   uServer,
321f76 ¤   ¤   PGPKeyServerEntry*¤ pkeyserver,
57f531 ¤   ¤   HWND¤   ¤   ¤   ¤   hwndParent,
ef9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
31809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
08a1f9 ¤   ¤   PGPPrefRef¤ ¤   ¤   clientPrefsRef,
29c9e5 ¤   ¤   CHAR¤   ¤   ¤   ¤   *pszUserID,
e9dcc4 ¤   ¤   PCLIENTSERVERSTRUCT¤*ppcss,
ac4d4e ¤   ¤   PGPKeyServerEntry¤  **ksEntries,
6d018f ¤   ¤   PGPKeyServerSpec¤   **serverList,
25900b ¤   ¤   PGPUInt32¤  ¤   ¤   *numKSEntries);
37af5a
c9c1d1 PGPError CLUninitKeyServerPrefs(
fd7022 ¤   ¤   PGPUInt32¤  ¤   ¤   uServer,
8e6767 ¤   ¤   PCLIENTSERVERSTRUCT¤pcss,
d5cbcf ¤   ¤   PGPKeyServerEntry¤  *ksEntries,
0836ad ¤   ¤   PGPKeyServerSpec¤   *serverList,
f19a4b ¤   ¤   PGPUInt32¤  ¤   ¤   numKSEntries);
41af5a
4c7967 #endif /* ] Included_PGPclx_h */
--9c92 00154a9f3aa401102bc Page 3 of PGPclx.h
e0af5a
1aaf5a
dd7e4d /*__Editor_settings____
96af5a
e44126 ¤   Local Variables:
997b17 ¤   tab-width: 4
f90e6c ¤   End:
f75f8c ¤   vi: ts=4 sw=4
8b9e9b ¤   vim: si
54d062 _____________________*/
--1c41 00068394ecc401102bd Page 1 of PGPkm.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
26bef5 ¤   PGPkm.c - PGP key manager DLL
4767c5 ¤
14af5a
4cf1db ¤   $Id: PGPkm.c,v 1.10 1998/08/11 14:43:44 pbj Exp $
72f7f7 ____________________________________________________________________________*/
bae610 #include "pgpPFLConfig.h"
b7af5a
3fc917 // project header files
a6850a #include "pgpkmx.h"
57af5a
9b3fb5 // external global variables
289cad extern HINSTANCE g_hInst;
75af5a
f94265 //¤ ___________________________________________________
ff465d //
3dbfbb // ·Return handle of keymanager window
a9af5a
7f4dde HWND PGPkmExport·
36b150 PGPkmGetManagerWindow (HKEYMAN hKM)·
1bbb36 {
7ca275 ¤   if (!hKM) return NULL;
885b63 ¤   return (((PKEYMAN)hKM)->hWndTree);
7faf5a
9aefe6 }
8caf5a
d54265 //¤ ___________________________________________________
93465d //
143d90 // ·Set configuration
01af5a
deb997 PGPError PGPkmExport·
ac0601 PGPkmConfigure (
1113eb ¤   ¤   HKEYMAN¤¤   hKeyMan,·
e215ae ¤   ¤   LPKMCONFIG¤ pKMConfig)·
5dbb36 {
45f184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
98da2c ¤   if (!pKM) return kPGPError_BadParams;
40af5a
2e93b4 ¤   if (pKM) {
2e68a8 ¤   ¤   // set help file
9d4e0e ¤   ¤   if (pKMConfig->ulMask & PGPKM_HELPFILE) {
9e7fff ¤   ¤   ¤   if (pKMConfig->lpszHelpFile) {
ba8ce5 ¤   ¤   ¤   ¤   lstrcpyn (pKM->szHelpFile,·
5ad7da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKMConfig->lpszHelpFile,·
ab0585 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(pKM->szHelpFile));
e3a3a6 ¤   ¤   ¤   }
2ae543 ¤   ¤   ¤   else {
2598d4 ¤   ¤   ¤   ¤   CHAR¤   sz[MAX_PATH];
f7af5a
9b6cd7 ¤   ¤   ¤   ¤   PGPclGetPGPPath (pKM->szHelpFile, sizeof(pKM->szHelpFile));
6050c3 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_HELPFILENAME, sz, sizeof(sz));
466cf4 ¤   ¤   ¤   ¤   lstrcat (pKM->szHelpFile, sz);
d8a3a6 ¤   ¤   ¤   }
4d0fe4 ¤   ¤   }
22af5a
6cc26f ¤   ¤   // set keyserver
82d8dd ¤   ¤   if (pKMConfig->ulMask & PGPKM_KEYSERVER) {
53ae64 ¤   ¤   ¤   if (pKMConfig->keyserver.structSize)·
d7b256 ¤   ¤   ¤   ¤   CopyMemory (&pKM->keyserver, &pKMConfig->keyserver,
3cb765 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(PGPKeyServerEntry));
8dbb8c ¤   ¤   ¤   else
36a798 ¤   ¤   ¤   ¤   ZeroMemory (&pKM->keyserver, sizeof(PGPKeyServerEntry));
6b0fe4 ¤   ¤   }
5aaf5a
05e7a5 ¤   ¤   // set disabled actions
5d5198 ¤   ¤   if (pKMConfig->ulMask & PGPKM_DISABLEFLAGS) {
5066f8 ¤   ¤   ¤   pKM->ulDisableActions = pKMConfig->ulDisableActions;
e40fe4 ¤   ¤   }
68af5a
--5833 0008a55f449401102bd Page 2 of PGPkm.c
8ab366 ¤   ¤   // set option flags
23b767 ¤   ¤   if (pKMConfig->ulMask & PGPKM_OPTIONS) {
55e9c0 ¤   ¤   ¤   pKM->ulOptionFlags = pKMConfig->ulOptionFlags;
0d0fe4 ¤   ¤   }
0faf5a
1348e4 ¤   ¤   // set column flags
5ed001 ¤   ¤   if (pKMConfig->ulMask & PGPKM_COLUMNFLAGS) {
75795f ¤   ¤   ¤   pKM->ulShowColumns = pKMConfig->ulShowColumns;
ff8f28 ¤   ¤   ¤   pKM->ulHideColumns = pKMConfig->ulHideColumns;
810fe4 ¤   ¤   }
21af5a
670e06 ¤   ¤   // set statusbar hwnd
1082ca ¤   ¤   if (pKMConfig->ulMask & PGPKM_STATUSBAR) {
b6fbbe ¤   ¤   ¤   pKM->hWndStatusBar = pKMConfig->hWndStatusBar;
2e0fe4 ¤   ¤   }
ac1b52 ¤   ¤
d3b299 ¤   ¤   // set the procedure address for adding/removing
79af5a
057dea ¤   ¤   // enable or disable the key properties windows
09d929 ¤   ¤   if (pKM->ulOptionFlags & KMF_DISABLEKEYPROPS)·
f0f88a ¤   ¤   ¤   KMEnableAllKeyProperties (pKM, FALSE);
f80e1d ¤   ¤   else
c9fa60 ¤   ¤   ¤   KMEnableAllKeyProperties (pKM, TRUE);
ac67c5 ¤
226bfb ¤   ¤   // determine validity threshold for green dot
3c2ef3 ¤   ¤   if (pKM->ulOptionFlags & KMF_MARGASINVALID)·
d9c311 ¤   ¤   ¤   pKM->iValidityThreshold = KM_VALIDITY_COMPLETE;
7d0e1d ¤   ¤   else
4163a7 ¤   ¤   ¤   pKM->iValidityThreshold = KM_VALIDITY_MARGINAL;
3787c7 ¤   ¤   ¤
f0b840 ¤   ¤   return kPGPError_NoErr;
fb9371 ¤   }
e4af5a
addd95 ¤   else return kPGPError_BadParams;
c7af5a
26efe6 }
a9af5a
6daf5a
084265 //¤ ___________________________________________________
e0465d //
551ee1 // ·Select columns
fbaf5a
26b997 PGPError PGPkmExport·
2ca557 PGPkmSelectColumns (HKEYMAN hKeyMan, ULONG ulColumnFlags, BOOL bRedraw)·
6ebb36 {
a5f184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
95af5a
6f2709 ¤   KMSelectColumns (pKM, ulColumnFlags);
93af5a
72e6f9 ¤   if (bRedraw) {
d99170 ¤   ¤   KMDeleteAllUserValues (pKM);
35d1c0 ¤   ¤   KMSetFocus (pKM, NULL, FALSE);
9f2107 ¤   ¤   TreeList_DeleteTree (pKM->hWndTree, TRUE);
b9497f ¤   ¤   TreeList_DeleteAllColumns (pKM->hWndTree);
78af5a
f82d01 ¤   ¤   KMAddColumns (pKM);
a46428 ¤   ¤   KMLoadKeyRingIntoTree (pKM, FALSE, FALSE, TRUE);
11201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
940251 ¤   ¤   UpdateWindow (pKM->hWndTree);
be9371 ¤   }
e8af5a
bdd760 ¤   KMSetColumnPreferences (pKM);
e6af5a
69151e ¤   return kPGPError_NoErr;
d8efe6 }
31af5a
a8af5a
bb4265 //¤ ___________________________________________________
79465d //
8cf9ce // ·Get selected columns
78af5a
8ab997 PGPError PGPkmExport·
--1879 000c7a484b1401102bd Page 3 of PGPkm.c
9ee68f PGPkmGetSelectedColumns (HKEYMAN hKeyMan, ULONG* pulColumnFlags)·
71bb36 {
5bf184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
34af5a
5d36f6 ¤   KMGetSelectedColumns (pKM, pulColumnFlags);
e4af5a
cc151e ¤   return kPGPError_NoErr;
b4efe6 }
f0af5a
deaf5a
954265 //¤ ___________________________________________________
c6465d //
b2b95d // ·process message from prop sheet
77af5a
607cb4 VOID PGPkmExport·
b0678e PGPkmProcessKeyPropMessage (
6ca733 ¤   ¤   HKEYMAN hKeyMan,·
610303 ¤   ¤   WPARAM¤ wParam,
e7eac2 ¤   ¤   LPARAM¤ lParam)
59bb36 {
62f184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
bdaf5a
fd0216 ¤   switch (wParam) {
655bf5 ¤   case KM_PROPACTION_UPDATEKEY :
1f2b05 ¤   ¤   KMUpdateKeyInTree (pKM, (PGPKeyRef)lParam, FALSE);
c22f7a ¤   ¤   KMUpdateAllValidities (pKM);
b5201f ¤   ¤   InvalidateRect (pKM->hWndTree, NULL, TRUE);
eb2f68 ¤   ¤   break;
1caf5a
86af5a
9fd6e9 ¤   case KM_PROPACTION_SPLITKEY :
ba92d5 ¤   ¤   KMSplitKey (pKM, (PGPKeyRef)lParam);
2f2f68 ¤   ¤   break;
239371 ¤   }
ccefe6 }
faaf5a
cfaf5a
984265 //¤ ___________________________________________________
49465d //
bec530 // ·check if OK to close key manager
bbaf5a
881cb5 BOOL PGPkmExport·
dac6b9 PGPkmOKToClose (HKEYMAN hKeyMan, PUINT puReason)
91bb36 {
c5f184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
37af5a
3079c4 ¤   if (KMExistSplitKeyDialog (pKM)) {
aa1d17 ¤   ¤   *puReason = KMR_EXISTINGSPLITKEYDLGS;
cd98aa ¤   ¤   return FALSE;
2d9371 ¤   }
3baf5a
c8c2e7 ¤   return TRUE;
a0efe6 }
14af5a
0eaf5a
5a4265 //¤ ___________________________________________________
e6465d //
90c24a // ·Synchronize thread access to SDK by using mutexs
f8af5a
e67cb4 VOID PGPkmExport·
e26525 PGPkmSynchronizeThreadAccessToSDK (HKEYMAN¤ hKeyMan)
a8bb36 {
b9f184 ¤   PKEYMAN pKM = (PKEYMAN)hKeyMan;
c8af5a
bfcfd0 ¤   ReleaseMutex (pKM->hAccessMutex);
f8f721 ¤   WaitForSingleObject (pKM->hRequestMutex, INFINITE);
8d1711 ¤   WaitForSingleObject (pKM->hAccessMutex, INFINITE);
4770a1 ¤   ReleaseMutex (pKM->hRequestMutex);
c9efe6 }
d7af5a
7daf5a
c74265 //¤ ___________________________________________________
--fc8c 0014761fbdf401102bd Page 4 of PGPkm.c
c1465d //
192b6a // ·request thread access to SDK (called internally)
9caf5a
e4fe80 VOID
7b0609 KMRequestSDKAccess (PKEYMAN pKM)
3ebb36 {
67f721 ¤   WaitForSingleObject (pKM->hRequestMutex, INFINITE);
707841 ¤   PostMessage (pKM->hWndParent, KM_M_REQUESTSDKACCESS, 0, 0);
461711 ¤   WaitForSingleObject (pKM->hAccessMutex, INFINITE);
53efe6 }
deaf5a
41af5a
7b4265 //¤ ___________________________________________________
01465d //
26a4c7 // ·release thread access to SDK (called internally)
09af5a
d4fe80 VOID
b19a09 KMReleaseSDKAccess (PKEYMAN pKM)
72bb36 {
0ccfd0 ¤   ReleaseMutex (pKM->hAccessMutex);
3d70a1 ¤   ReleaseMutex (pKM->hRequestMutex);
ecefe6 }
e2af5a
d3af5a
47af5a
--4bce 00096d558f3401102be Page 1 of PGPkmx.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
df9b36 ¤   PGPkmx.h - internal header file for KeyManager DLL
a667c5 ¤
2daf5a
ee45b9 ¤   $Id: PGPkmx.h,v 1.50 1998/08/12 18:31:25 pbj Exp $
0ff7f7 ____________________________________________________________________________*/
f5e2ac #ifndef Included_PGPkmx_h¤  /* [ */
7ea5b2 #define Included_PGPkmx_h
98af5a
cfa56f #define _PGPKMDLL
84af5a
602a68 #define WIN32_LEAN_AND_MEAN
14ca87 #define _WIN32_WINNT 0x0400
f8af5a
afd881 // Win32 header files
ad5655 #include <windows.h>
2190fb #include <commctrl.h>
4162da #include <ole2.h>
57dbcb #include <shellapi.h>
ceaf5a
1a7b85 // PGP build flags
fa81a4 #include "pgpBuildFlags.h"
b6af5a
23d495 // PGP SDK header files
aa0d08 #include "pgpMem.h"
ac2f8d #include "pgpErrors.h"
824919 #include "pgpUtilities.h"
a3a076 #include "pgpKeys.h"
acaf5a
048687 // PGP client header files
cccba4 #include "..\include\help\pgpclhlp.h"
af97e6 #include "..\include\pgpcl.h"
fbbdfa #include "..\include\pgpkm.h"
3c8af7 #include "..\include\pgpImage.h"
45beb4 #include "..\include\treelist.h"
bdaf5a
277a15 // local header files
d68031 #include "resource.h"
b7af5a
b07274 // macro definitions
f0a8fa #define CKERR¤  ¤   if (IsPGPError (err)) goto done
c4af5a
695584 // constant definitions
e68349 #define OBJECT_NONE¤¤   0
4ac673 #define OBJECT_KEY¤ ¤   1
aacf78 #define OBJECT_USERID¤  2
554a54 #define OBJECT_CERT¤¤   3
ddaf5a
87c491 #define NUMBERFIELDS¤   9
ed91b2 #define MAXSHEETS¤  ¤   16¤ ¤   // maximum number of simultaneous dialogs
e5af5a
8042bb #define DEFAULTWINDOWWIDTH¤ 520
db14fc #define DEFAULTWINDOWHEIGHT 300
a7b3a0 #define DEFAULTWINDOWX ·····85
bcbd06 #define DEFAULTWINDOWY¤ ¤   90
61af5a
39a3fc #define KMI_NAME¤   ¤   ¤   0
1f018a #define KMI_VALIDITY¤   ¤   1
cd0977 #define KMI_SIZE¤   ¤   ¤   2
88b262 #define KMI_DESCRIPTION¤¤   3
ccc7d1 #define KMI_KEYID¤  ¤   ¤   4
7e9821 #define KMI_TRUST¤  ¤   ¤   5
7391bd #define KMI_CREATION¤   ¤   6
003209 #define KMI_EXPIRATION¤ ¤   7
e9a5b0 #define KMI_ADK¤¤   ¤   ¤   8
8987f3 #define NUMBERFIELDS¤   ¤   9
ddaf5a
a75edc #define KM_VALIDITY_INVALID¤¤   0
966fdb #define KM_VALIDITY_MARGINAL¤   1
--ff25 000bfe6f1b2401102be Page 2 of PGPkmx.h
6d6062 #define KM_VALIDITY_COMPLETE¤   2
18af5a
7393b3 #define KM_PROPACTION_UPDATEKEY¤¤   1
aa2033 #define KM_PROPACTION_SPLITKEY¤ ¤   2
45af5a
dcfcf1 struct _KEYMAN;
3baf5a
b5c222 // split key structures
67a024 typedef struct _SHAREHOLDERSTRUCT {
9b6d57 ¤   BOOL¤   ¤   ¤   ¤   ¤   ¤   bPublicKey;
a6e5fd ¤   PGPKeyID¤   ¤   ¤   ¤   ¤   keyid;
deeeeb ¤   PGPPublicKeyAlgorithm¤  ¤   keyalg;
f5d4f6 ¤   CHAR¤   ¤   ¤   ¤   ¤   ¤   szUserID[kPGPMaxUserIDSize];
b8f8dd ¤   LPSTR¤  ¤   ¤   ¤   ¤   ¤   pszPassphrase;
1331e8 ¤   UINT¤   ¤   ¤   ¤   ¤   ¤   uShares;
61344e } SHAREHOLDERSTRUCT, *PSHAREHOLDERSTRUCT;
eeaf5a
1fc31d typedef struct _SPLITKEYSTRUCT {
7ec632 ¤   struct _SPLITKEYSTRUCT*¤¤   next;
a9ef37 ¤   struct _SPLITKEYSTRUCT**¤   pHeadOfList;
f02537 ¤   struct _KEYMAN*¤¤   ¤   ¤   pKM;
598190 ¤   HWND¤   ¤   ¤   ¤   ¤   ¤   hwndDlg;
ef6ed8 ¤   HWND¤   ¤   ¤   ¤   ¤   ¤   hwndList;
83539b ¤   HIMAGELIST¤ ¤   ¤   ¤   ¤   hIml;
8625d7 ¤   LPDROPTARGET¤   ¤   ¤   ¤   pDropTarget;
3b5bd5 ¤   PGPKeyID¤   ¤   ¤   ¤   ¤   keyidToSplit;
2a9bf4 ¤   PGPPublicKeyAlgorithm¤  ¤   keyalgToSplit;
008c6e ¤   CHAR¤   ¤   ¤   ¤   ¤   ¤   szUserIDToSplit[kPGPMaxUserIDSize];
42f538 ¤   UINT¤   ¤   ¤   ¤   ¤   ¤   uTotalShares;
6abdfb ¤   UINT¤   ¤   ¤   ¤   ¤   ¤   uThreshold;
4748ed ¤   INT¤¤   ¤   ¤   ¤   ¤   ¤   iIndexCurrent;
d8455e ¤   PSHAREHOLDERSTRUCT¤ ¤   ¤   pshsCurrent;
0a1b40 } SPLITKEYSTRUCT, *PSPLITKEYSTRUCT;
2baf5a
031da1 // Manager global variables
16c385 typedef struct _KEYMAN {
def2f4 ¤   PGPContextRef¤  ¤   Context;¤   ¤   ¤
b8b4ac ¤   PGPtlsContextRef¤   tlsContext;
28af5a
7d0a77 ¤   HWND¤   ¤   ¤   ¤   hWndParent;
38886b ¤   HWND¤   ¤   ¤   ¤   hWndTree;
363579 ¤   HWNDLISTPROC¤   ¤   lpfnHwndListFunc;
48fce5 ¤   INT¤¤   ¤   ¤   ¤   iID;
41b86f ¤   HWND¤   ¤   ¤   ¤   hWndStatusBar;
3d7753 ¤   HANDLE¤ ¤   ¤   ¤   hRequestMutex;
5a6721 ¤   HANDLE¤ ¤   ¤   ¤   hAccessMutex;
7347fb ¤   HIMAGELIST¤ ¤   ¤   hIml;
74c038 ¤   LPDROPTARGET¤   ¤   pDropTarget;¤   ¤   //pointer to DropTarget object
e18bbe ¤   CHAR¤   ¤   ¤   ¤   szHelpFile[MAX_PATH];¤  //name of help file
6caf5a
8f1b93 ¤   PGPKeySetRef¤   ¤   KeySetMain;¤¤   ¤   //pointer to main keyset
b3be33 ¤   PGPKeySetRef¤   ¤   KeySetDisp;¤¤   ¤   //pointer to display keyset
ab43d7 ¤   LONG¤   ¤   ¤   ¤   lKeyListSortField;¤ //keylist sort order
185881 ¤   BOOL¤   ¤   ¤   ¤   bMainKeySet;¤
0aec49 ¤   ULONG¤  ¤   ¤   ¤   ulOptionFlags;
2da9dd ¤   ULONG¤  ¤   ¤   ¤   ulDisableActions;
2e5c09 ¤   ULONG¤  ¤   ¤   ¤   ulShowColumns;¤ ¤   //currently unused
87d9ec ¤   ULONG¤  ¤   ¤   ¤   ulHideColumns;¤ ¤   //currently unused
15af5a
bab387 ¤   BOOL¤   ¤   ¤   ¤   bMultipleSelected;¤
63fd6f ¤   UINT¤   ¤   ¤   ¤   uSelectedFlags;
2ff6da ¤   INT¤¤   ¤   ¤   ¤   iFocusedItemType;
a40c16 ¤   INT¤¤   ¤   ¤   ¤   iFocusedObjectType;
1953ff ¤   HTLITEM¤¤   ¤   ¤   hFocusedItem;
2e94df ¤   VOID*¤  ¤   ¤   ¤   pFocusedObject;
67af5a
5f02f1 ¤   INT¤¤   ¤   ¤   ¤   iValidityThreshold;¤//for setting icons to green
12af5a
e408df ¤   INT¤¤   ¤   ¤   ¤   iNumberSheets;¤ ¤   ¤   //number of open prop sheets
872402 ¤   HWND¤   ¤   ¤   ¤   hWndTable[MAXSHEETS];
36bc9e ¤   PGPKeyRef¤  ¤   ¤   KeyTable[MAXSHEETS];
bfaf5a
--5e01 0004b16709e401102be Page 3 of PGPkmx.h
6041ac ¤   WORD¤   ¤   ¤   ¤   wColumnField[NUMBERFIELDS];
16c379 ¤   WORD¤   ¤   ¤   ¤   wFieldWidth[NUMBERFIELDS];
61af5a
0af6dc ¤   PGPKeyServerEntry¤  keyserver;
e96ba0 ¤   PSPLITKEYSTRUCT¤¤   pSplitKeyDialogList;
72af5a
0faca1 } KEYMAN, *PKEYMAN;
9baf5a
63af5a
090921 // KMAddUser.c
ffc769 BOOL KMAddUserToKey (PKEYMAN pKM);
bd997a BOOL KMAddPhotoToKey (PKEYMAN pKM);
5caf5a
4f487c // KMChange.c¤
972bf3 BOOL KMChangePhrase (HWND hwndParent, PKEYMAN pKM,·
21fc8b ¤   ¤   ¤   ¤   ¤   ·PGPContextRef context, PGPtlsContextRef tlsContext,
a6e3e2 ¤   ¤   ¤   ¤   ¤   ·PGPKeySetRef keyset, PGPKeyRef key);·
18af5a
4c35fd // KMColumn.c
99c721 VOID KMGetColumnPreferences (PKEYMAN pKM);·
357ef1 VOID KMSetColumnPreferences (PKEYMAN pKM);
e2e28a VOID KMGetSelectedColumns (PKEYMAN pKM, ULONG* pulColumnFlags);·
a575d5 VOID KMSelectColumns (PKEYMAN pKM, ULONG ulColumnFlags);·
4caf5a
8880d0 // KMConvert.c
27b11c VOID KMConvertStringFingerprint (UINT uAlgorithm, LPSTR sz);
f26532 VOID KMConvertTimeToDays (PGPTime tm, INT* piDays);
54ca22 VOID KMConvertTimeToString (PGPTime tm, LPSTR sz, INT ilen);
9fe3ff UINT KMConvertFromPGPTrust (UINT uPGPTrust);
466e26 UINT KMConvertToPGPTrust (UINT uTrust);
8c22ea UINT KMConvertFromPGPValidity (UINT uPGPValidity);
72af5a
9797da // KMFocus.c
533add VOID KMSetFocus (PKEYMAN pKM, HTLITEM hFocused, BOOL bMultiple);
bb85ec INT KMFocusedItemType (PKEYMAN pKM);
20d1d2 INT KMFocusedObjectType (PKEYMAN pKM);
a211f9 HTLITEM KMFocusedItem (PKEYMAN pKM);
0597da VOID* KMFocusedObject (PKEYMAN pKM);
8f6f97 BOOL KMMultipleSelected (PKEYMAN pKM);
619e7c BOOL KMPromiscuousSelected (PKEYMAN pKM);
a47d8d UINT KMSelectedFlags (PKEYMAN pKM);
6be3c6 BOOL KMSigningAllowed (PKEYMAN pKM);
f5aafe PGPError KMGetSelectedKeys (PKEYMAN pKM, PGPKeySetRef* pKeySet, INT* piCount);
8faf5a
a9563f // KMIDataObject.cpp
e416c1 LPDATAOBJECT KMCreateDataObject (PKEYMAN pKM, LPSTR szName);
558417 BOOL KMOKToDeleteDataObject (LPDATAOBJECT pDataObject);
69af5a
51646d // KMIDropSource.cpp
ba860c LPDROPSOURCE KMCreateDropSource (PKEYMAN pKM, HWND hwnd, HWND hwndTree);
53af5a
a47edd // KMIDropTarget.cpp
7f8f6c LPDROPTARGET KMCreateDropTarget (
72a449 ¤   ¤   ¤   ¤   ¤   HWND hwnd, VOID* pKeyMan, VOID* pSplitStruct);
72962b VOID KMReleaseDropTarget (LPDROPTARGET pDropTarget);
f64657 VOID KMEnableDropTarget (LPDROPTARGET pDropTarget, BOOL bEnable);
21af5a
66d7c9 // KMKeyIO.c
31806c BOOL KMImportKey (PKEYMAN pKM, HDROP hDrop);
3c1f99 BOOL KMExportKeys (PKEYMAN pKM, LPSTR szFile);
67367b BOOL KMCopyKeys (PKEYMAN pKM, HANDLE* phMem);
2a8f5d BOOL KMDataToPaste (VOID);
9cbdff BOOL KMPasteKeys (PKEYMAN pKM);
cedad8 BOOL KMDragAndDrop (PKEYMAN pKM);
ebaf5a
09474a // KMKeyOps.c
dd0146 BOOL KMDeleteObject (PKEYMAN pKM);
a6254c BOOL KMCertifyKeyOrUserID (PKEYMAN pKM);
cdb5ce BOOL KMDisableKey (PKEYMAN pKM, PGPKeyRef Key);
e8edad BOOL KMEnableKey (PKEYMAN pKM, PGPKeyRef Key);
1dd4c4 BOOL KMSetDefaultKey (PKEYMAN pKM);
4bcdac BOOL KMSetPrimaryUserID (PKEYMAN pKM);
--6c13 0008069a9a4401102be Page 4 of PGPkmx.h
db3e37 BOOL KMAddSelectedToMain (PKEYMAN pKM);
bbd9f9 BOOL KMReverifySigs (PKEYMAN pKM);
a0af5a
e01c14 // KMMenu.c
705d20 VOID KMContextMenu (PKEYMAN pKM, INT x, INT y);
f6af5a
f96def // KMMisc.c
2c886a VOID* KMAlloc (LONG size);
4fa95c VOID KMFree (VOID* p);
e8efa8 PGPKeyRef KMGetKeyFromUserID (PKEYMAN pKM, PGPUserIDRef UserID);
61cfef BOOL KMCheckForSecretKeys (PGPKeySetRef KeySet);
3d642b BOOL KMIsThisTheOnlyUserID (PKEYMAN pKM, PGPUserIDRef UID);
f87339 BOOL KMIsThisThePrimaryUserID (PKEYMAN pKM, PGPUserIDRef UID);
97a3e9 BOOL KMExistingPhotoID (PKEYMAN pKM, PGPKeyRef key);
2770a1 BOOL KMGetKeyName (PGPKeyRef Key, LPSTR sz, UINT uLen);
adca15 BOOL KMGetUserIDName (PGPUserIDRef UserID, LPSTR sz, UINT uLen);
33da10 INT KMDetermineKeyIcon (PKEYMAN pKM, PGPKeyRef Key, BOOL* lpbItalics);
c5e858 INT KMDetermineUserIDIcon (PGPKeyRef Key, PGPUserIDRef UserID,·
2b80a1 ¤   ¤   ¤   ¤   ¤   ¤   BOOL* pbItalics);
a14898 INT KMDetermineCertIcon (PGPSigRef Cert, BOOL* pbItalics);
4fbb7e INT KMCommitKeyRingChanges (PKEYMAN pKM);
057a6b BOOL KMGetKeyIDFromKey (PGPKeyRef Key, LPSTR sz, UINT u);
f4fc60 BOOL KMGetKeyIDFromCert (PGPSigRef Cert, LPSTR sz, UINT u);
5ed7e6 PGPKeyRef KMGetKeyFromCert (PKEYMAN pKM, PGPSigRef Cert);
5ed704 VOID KMFindWindowFromPoint (PKEYMAN pKM, POINT* ppt, HWND phwnd);
b5af5a
62782e // KMPhoto.c
eeaddc INT KMGetDIBSize (LPBITMAPINFO lpbi, INT* piWidth, INT* piHeight);
21e6d7 HBITMAP KMDDBfromDIB (LPBITMAPINFO lpbi, HPALETTE* lphPalette);
500494 PGPError KMDIBfromPhoto (LPBYTE buf, INT isize, BOOL bForDisplay,
e94a97 ¤   ¤   ¤   ¤   ¤   ¤   ·LPBITMAPINFO* plpbmi);
89e9ff PGPError KMCopyPhotoToClipboard (HWND hWnd, PBYTE buf, INT isize);
bbe2eb PGPError KMPastePhotoFromClipboard (HWND hWnd, LPBYTE* pbuf, INT* pisize);
409ae9 PGPError KMReadPhotoFromFile (LPSTR pszFile, LPBYTE* pbuf, INT* pisize);
47af5a
ae5d35 // KMProps.c
928451 BOOL KMKeyProperties (PKEYMAN pKM);
b07c42 VOID KMUpdateKeyProperties (PKEYMAN pKM);
d642cd VOID KMUpdateKeyPropertiesThread (PKEYMAN pKM);
36fc00 VOID KMDeletePropertiesKey (PKEYMAN pKM, PGPKeyRef Key);
ae662a VOID KMDeleteAllKeyProperties (PKEYMAN pKM, BOOL bCloseWindows);
eb2415 VOID KMEnableAllKeyProperties (PKEYMAN pKM, BOOL bEnable);
e6af5a
416dea // KMRevoke.c
557316 BOOL KMRevokeKey (PKEYMAN pKM);
fd346d BOOL KMRevokeCert (PKEYMAN pKM);
6ccf3e BOOL KMAddRevoker (PKEYMAN pKM);
8eaf5a
22dd9a // KMServer.c
349bc0 BOOL KMSendToServer (PKEYMAN pKM, UINT uServerFlags);
f1b912 BOOL KMGetFromServer (PKEYMAN pKM);
2cc7bc BOOL KMGetFromServerInternal (PKEYMAN pKM,·
1abb3f ¤   ¤   ¤   ¤   ¤   ¤   BOOL bQueryAdd, BOOL bWarn, BOOL bGetSigners);·
8551c0 BOOL KMDeleteFromServer (PKEYMAN pKM);
4532e0 BOOL KMDisableOnServer (PKEYMAN pKM);
d2af5a
e22c6a // KMShare.c
ba7df4 BOOL KMSplitKey (PKEYMAN pKM, PGPKeyRef key);
87dd6f BOOL KMExistSplitKeyDialog (PKEYMAN pKM);
36a33d BOOL KMSplitDropKeys (PSPLITKEYSTRUCT psks, HANDLE hMem);
acaf5a
9c32c8 // KMTree.c
e16d88 BOOL KMAddColumns (PKEYMAN pKM);
d08051 BOOL KMLoadKeyRingIntoTree (PKEYMAN pKM, BOOL bReInsert,·
5804c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bExpandNew, BOOL bForceRealloc);
bd9fe6 BOOL KMUpdateKeyInTree (PKEYMAN pKM, PGPKeyRef Key, BOOL bForceNew);
c16a59 BOOL KMUpdateAllValidities (PKEYMAN pKM);
426321 BOOL KMExpandSelected (PKEYMAN pKM);
ec98e4 BOOL KMCollapseSelected (PKEYMAN pKM);
48a29f PGPError KMGetKeyUserVal (PKEYMAN pKM, PGPKeyRef Key, LONG* lValue);
7d801e PGPError KMGetUserIDUserVal (PKEYMAN pKM, PGPUserIDRef UID, LONG* lValue);
80238b PGPError KMGetCertUserVal (PKEYMAN pKM, PGPSigRef Cert, LONG* lValue);
--48f7 0005b183280401102be Page 5 of PGPkmx.h
eaacdd PGPError KMSetKeyUserVal (PKEYMAN pKM, PGPKeyRef Key, LONG lValue);
09094b PGPError KMSetUserIDUserVal (PKEYMAN pKM, PGPUserIDRef UID, LONG lValue);
32e64f PGPError KMSetCertUserVal (PKEYMAN pKM, PGPSigRef Cert, LONG lValue);
499afc BOOL KMDeleteAllUserValues (PKEYMAN pKM);
28f4d1 VOID KMSelectKey (PKEYMAN pKM, PGPKeyRef key, BOOL bDeselect);
43b1d5 VOID KMGetKeyBitsString (PGPKeySetRef KeySet,·
4eb09d ¤   ¤   ¤   ¤   ¤   ¤   ·PGPKeyRef Key, LPSTR sz, UINT u);
6faf5a
dd3db6 // KMUser.c
7e2e63 LRESULT KMMessageBox (HWND hwnd, INT iCaption, INT iMessage, ULONG flags);
c73c8a BOOL KMUseBadPassPhrase (HWND hwnd);
a85461 BOOL KMConstructUserID (HWND hDlg, UINT uNameIDC, UINT uAddrIDC,·
513bbc ¤   ¤   ¤   ¤   ¤   ¤   LPSTR* pszUserID);
e63789 BOOL KMSignConfirm (PKEYMAN pKM, BOOL* pbSendToServer);
752829 VOID KMWipeEditBox (HWND hDlg, UINT uID);
7b089f PGPError KMGetKeyPhrase (
919cd4 ¤   ¤   PGPContextRef¤  ¤   context,
63a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
978d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
f7b7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
e9e561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
fe402c ¤   ¤   PGPKeyRef¤  ¤   ¤   key,
c9fb51 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   ppszPhrase,
a21229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
e6a348 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength);
c3984b PGPError KMGetSigningKeyPhrase (
4b9cd4 ¤   ¤   PGPContextRef¤  ¤   context,
36a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
9f8d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
7cb7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
6ee561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
879cb9 ¤   ¤   BOOL¤   ¤   ¤   ¤   bRejectSplitKeys,
e97854 ¤   ¤   PGPKeyRef*¤ ¤   ¤   pkey,
62fb51 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   ppszPhrase,
b01229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
a5a348 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength);
a8db13 PGPError KMGetConfirmationPhrase (
329cd4 ¤   ¤   PGPContextRef¤  ¤   context,
2c8d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
7eb7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
10e561 ¤   ¤   PGPKeySetRef¤   ¤   keyset,
56e839 ¤   ¤   INT¤¤   ¤   ¤   ¤   iMinPhraseLength,
33cf03 ¤   ¤   INT¤¤   ¤   ¤   ¤   iMinPhraseQuality,
967a6a ¤   ¤   LPSTR*¤ ¤   ¤   ¤   ppszPhrase);
857042 PGPError KMGetDecryptionPhrase (
949cd4 ¤   ¤   PGPContextRef¤  ¤   context,
a3a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
828d1f ¤   ¤   HWND¤   ¤   ¤   ¤   hwnd,·
dcb7a2 ¤   ¤   LPSTR¤  ¤   ¤   ¤   szPrompt,
fd809e ¤   ¤   PGPKeySetRef¤   ¤   keysetMain,
597854 ¤   ¤   PGPKeyRef*¤ ¤   ¤   pkey,
5bc4de ¤   ¤   PGPKeySetRef¤   ¤   keysetDecryption,
fc35a5 ¤   ¤   PGPUInt32¤  ¤   ¤   iKeyIDCount,
0d00c6 ¤   ¤   PGPKeyID*¤  ¤   ¤   keyidsDecryption,
d49a82 ¤   ¤   PGPKeySetRef*¤  ¤   pkeysetToAdd,
49fb51 ¤   ¤   LPSTR*¤ ¤   ¤   ¤   ppszPhrase,
651229 ¤   ¤   PGPByte**¤  ¤   ¤   ppPasskeyBuffer,
f7eba3 ¤   ¤   PGPUInt32*¤ ¤   ¤   piPasskeyLength);·
5b14f3 VOID KMFreePhrase (LPSTR pszPhrase);
e1ebde VOID KMFreePasskey (PGPByte* pbyte, PGPSize size);
5eaf5a
677113 // PGPkm.c
beb7c9 VOID KMRequestSDKAccess (PKEYMAN pKM);
ccb755 VOID KMReleaseSDKAccess (PKEYMAN pKM);
02af5a
57af5a
128712 #endif /* ] Included_PGPkmx_h */
6baf5a
77af5a
267e4d /*__Editor_settings____
20af5a
5b4126 ¤   Local Variables:
--6dc3 001d090f0b5401102be Page 6 of PGPkmx.h
2f7b17 ¤   tab-width: 4
030e6c ¤   End:
9e5f8c ¤   vi: ts=4 sw=4
269e9b ¤   vim: si
d0d062 _____________________*/
--6bf8 0001e323ca3401102bf Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
80679c // Used by PGPcl.rc
91465d //
8dad33 #define IDS_GENERAL ····················1
56f960 #define IDS_PRIVKEYRINGFILTER ··········2
43d3ed #define IDS_PRIVKEYCAPTION ·············3
08bfe6 #define IDS_PUBKEYCAPTION ··············4
e6fea4 #define IDS_PROPCAPTION ················5
39f4cc #define IDS_CAPTIONERROR ···············6
ea57f7 #define IDS_HELPFILENAME ···············7
99c701 #define IDS_TITLE0 ·····················8
46daa2 #define IDS_TITLE1 ·····················9
cafb69 #define IDS_TITLE2 ·····················10
3d2fe1 #define IDS_TITLE3 ·····················11
8e771b #define IDS_TITLE4 ·····················12
8bb643 #define IDS_NOSIGNKEY ··················13
b3112f #define IDS_RANDOMPROMPT ···············14
634801 #define IDS_RANDOMDONE ·················15
4b1507 #define IDS_RSA ························16
a98346 #define IDS_DH ·························17
5b76c1 #define IDS_UNKNOWN ····················18
287911 #define IDS_CAPTION ····················19
c24c6e #define IDS_INVALIDWRAP ················20
49657d #define IDS_INVALIDCACHEVALUE ··········21
222d31 #define IDS_PUBKEYRINGFILTER ···········22
665018 #define IDS_DEFPRIVRINGEXT ·············23
891a05 #define IDS_DEFPUBRINGEXT ··············24
172918 #define IDS_ILLEGALFILENAME ············25
304cfc #define IDS_BROWSERERROR ···············26
e949da #define IDS_RSADSAMIXWARNING ···········27
aef096 #define IDS_ERR_EXPIRED ················28
9fdac0 #define IDS_DOMAIN ·····················29
88f401 #define IDS_LISTED ·····················30
e13069 #define IDS_DELKSPROMPT ················31
186531 #define IDS_SERVEREXISTS ···············32
7d87e8 #define IDS_NOSERVERNAME ···············33
957744 #define IDS_INFOTEXT ···················34
ade7e0 #define IDS_CREDITTEXT ·················35
0ffb23 #define IDS_WEBLINK ····················36
dadf4b #define IDS_NODOMAINNAME ···············37
a12e3d #define IDS_SEEDFILEFILTER ·············38
14e3e5 #define IDS_SEEDFILECAPTION ············39
f6b812 #define IDS_DEFSEEDFILEEXT ·············40
f2ba4a #define IDS_CAST ·······················41
0d3eaa #define IDS_3DES ·······················42
3f3368 #define IDS_IDEA ·······················43
e50875 #define IDS_NOADMINFILE ················44
595c57 #define IDS_CLIENTPREFSFILE ············45
0ec3b6 #define IDS_ADMINPREFSFILE ·············46
c1a0e8 #define IDS_CONNECTING ·················47
af6fc9 #define IDS_WAITING ····················48
aaec75 #define IDS_QUERYING ···················48
53a83a #define IDS_RECEIVING ··················49
2602c2 #define IDS_PROCESSING ·················49
e40a63 #define IDS_SENDING ····················50
bd34fb #define IDS_EXCHANGING ·················50
3ef380 #define IDS_REGISTRYKEY ················51
c10734 #define IDS_NOSERVERS ··················52
c317ac #define IDS_SENDSERVEROK ···············53
f62f4e #define IDS_SERVEROK ···················53
feedf1 #define IDS_SENDSERVERERROR ············54
f7df40 #define IDS_SERVERERROR ················54
6c4c41 #define IDS_LOOKINGFORSERVER ···········55
be1d47 #define IDS_ERRORPREFIX ················56
6ee859 #define IDS_ERRORMESSAGECAPTION ········57
9c4fc1 #define IDS_ERRORMESSAGE ···············58
7228b9 #define IDS_DELETING ···················59
52394c #define IDS_DISABLING ··················60
86e24c #define IDS_CLOSING ····················61
bb0797 #define IDS_ERR_OUTOFMEMORY ············101
1e679a #define IDD_KEYPROPGENERAL ·············101
--32db 00068896749401102bf Page 2 of resource.h
d9a27e #define IDS_ERR_WRONGKEYPASSPHRASE ·····102
9ad37a #define IDD_CHANGEPHRASE ···············102
bdbfaa #define IDS_ERR_INVALIDFILEOPERROR ·····103
7a1623 #define IDS_ERR_CATCHALL ···············104
86b5ef #define IDS_ERR_KEYIOWRITING ···········105
653325 #define IDS_ERR_NOFILE ·················106
401dd0 #define IDS_ERR_RNGNOTSEEDED ···········107
c44149 #define IDS_ERR_INPUTFILENOTEXIST ······108
9d6317 #define IDD_KEYRAND ····················108
8d1393 #define IDS_ERR_CANNOTUSEUNTRUSTEDKEY ··109
10770f #define IDD_NEWUSERID ··················109
67ff54 #define IDS_ERR_OUTPUTBUFFERTOOSMALL ···110
fe628d #define IDD_DELETEALL ··················110
bffe80 #define IDS_ERR_KEYRINGCORRUPT ·········111
156c50 #define IDD_KEYPROPADK ·················111
cffeb7 #define IDS_ERR_EXTRACTKEYNOTEXIST ·····112
81c9b9 #define IDD_SIGNCONFIRM ················112
84dadd #define IDS_ERR_SIGONLYKEY ·············113
fbd650 #define IDD_QUERYADD ···················113
346d21 #define IDS_ERR_ENCRYPTONLYKEY ·········114
ab0a58 #define IDD_REVOKECERT ·················114
990d93 #define IDS_ERR_CORRUPTPACKET ··········115
e6a984 #define IDS_ERR_DETSIGFOUND ············116
3da1cb #define IDD_EXPORTPRIVKEY ··············116
280749 #define IDD_EXPORTDLGEXTENSIONS ········116
48b32b #define IDS_ERR_NOSECRETKEYS ···········117
a89198 #define IDD_PREF0 ······················117
6d5a63 #define IDS_ERR_DUPLICATEUSERID ········118
b7dc4e #define IDD_PREF1 ······················118
0582b2 #define IDS_ERR_DUPLICATECERT ··········119
cc9fa5 #define IDD_PREF2 ······················119
f625f7 #define IDS_ERR_FILEPERMISSIONS ········120
d813bf #define IDD_PREF4 ······················120
646f50 #define IDS_PHRASEMISMATCH ·············121
57701f #define IDD_PREF3 ······················121
3c6e3a #define IDS_EMPTYPHRASE ················122
1d2d7a #define IDD_HELPABOUT ··················122
abb0f7 #define IDS_SENDSERVERABORT ············123
327f93 #define IDD_SPLASH ·····················123
f2c9b9 #define IDS_SERVERABORT ················123
a59800 #define IDS_SEARCHABORT ················124
1b5796 #define IDD_NAG ························124
fe05e4 #define IDS_SEARCHOK ···················125
50b33e #define IDD_NEWSERVER ··················125
534a07 #define IDS_SEARCHERROR ················126
e9d150 #define IDD_SERVERPROGRESS ·············126
3fb608 #define IDS_WRONGPHRASE ················127
9de241 #define IDS_PHRASEPROMPT ···············128
a7b3fe #define IDS_DELETESERVEROK ·············129
2c07bb #define IDS_DELETESERVERABORT ··········130
b7e970 #define IDS_DELETESERVERERROR ··········131
6c0e98 #define IDS_DISABLESERVEROK ············132
3d55f8 #define IDS_DISABLESERVERABORT ·········133
278400 #define IDS_DISABLESERVERERROR ·········134
7c8662 #define IDS_UNKNOWNKEYS ················135
5a04ea #define IDS_NEEDALGORITHM ··············136
00cf69 #define IDS_DSS ························137
8f9071 #define IDS_ERR_KEYFAILEDPOLICY ········138
f2bfef #define IDS_ERR_INCOMPATIBLESDKAPI ·····139
ade46b #define IDS_GROUPFILENAME ··············140
6e5a4a #define IDS_EDITSERVERTITLE ············141
42ed63 #define IDS_ERR_UNSUPPORTEDHTTPFILTER ··142
9f5370 #define IDS_ERR_NOSIGNINGKEYFORSEARCH ··143
27999c #define IDS_FOUNDMATCHFORPHRASE ········144
97b568 #define IDS_PGP ························145
59318f #define IDS_BADDECRYPTPHRASE ···········146
1d01fe #define IDS_WRONGDECRYPTPHRASE ·········147
8fec68 #define IDS_BETATIMEOUT ················148
85855a #define IDS_EVALTIMEOUT ················149
baa89f #define IDS_VALIDITYFIELD ··············150
318f33 #define IDS_DESCRIPTIONFIELD ···········151
689a3e #define IDS_PASSPHRASEMISMATCH ·········201
--e55d 00022b14d36401102bf Page 3 of resource.h
895ef5 #define IDB_IMAGES4BIT ·················201
530dc4 #define IDS_CAPTIONKEYGEN ··············202
a35d1f #define IDB_IMAGES24BIT ················202
ed05fb #define IDS_IMPORTCAPTION ··············203
34ebcf #define IDB_IMAGES4 ····················203
4ac412 #define IDS_EXPORTCAPTION ··············204
c59b6d #define IDB_IMAGES24 ···················204
b6546b #define IDS_DELCONFCAPTION ·············205
2490c7 #define IDB_CREDITS4 ···················205
ceabe7 #define IDS_DELCONFPRIVKEY ·············206
6baf38 #define IDB_CREDITS1 ···················206
789143 #define IDB_CREDITS8 ···················207
c8371a #define IDS_DELCONFKEY ·················208
38e87e #define IDB_SPLASH1 ····················208
ebee52 #define IDS_DELCONFUSERID ··············209
af1185 #define IDB_SPLASH4 ····················209
6e06d6 #define IDS_DELCONFCERT ················210
d9ebd4 #define IDB_SPLASH8 ····················210
bcc1a7 #define IDS_KEYRINGFILTER ··············211
c2cff6 #define IDB_NAG1 ·······················211
bce058 #define IDB_NAG4 ·······················212
72b57b #define IDS_NAMEFIELD ··················213
7df488 #define IDB_NAG8 ·······················213
7fa68c #define IDS_TRUSTFIELD ·················215
74973d #define IDS_CREATIONFIELD ··············216
c57999 #define IDS_SIZEFIELD ··················217
a023fc #define IDD_SENDSHARES ·················219
07a737 #define IDS_VALIDITY0 ··················220
87e5ab #define IDS_VALIDITY1 ··················221
9b220f #define IDS_VALIDITY2 ··················222
f46093 #define IDS_VALIDITY3 ··················223
72f882 #define IDS_DELCONFDEFKEY ··············224
f231cc #define IDS_DROPFILENAME ···············225
2cdd05 #define IDS_CERTKEYNOTONRING ···········226
0316c6 #define IDS_NOIMPORTKEYS ···············227
119ed8 #define IDS_NOIMPORTKEYSPASTE ··········228
3fa1d4 #define IDS_DELONLYUSERID ··············229
9a2f9b #define IDS_IMPORTEDSECRETKEYS ·········230
8c2ea6 #define IDS_TRUST2 ·····················231
255686 #define IDS_TRUST3 ·····················232
99f8b7 #define IDS_TRUST4 ·····················233
cee7f7 #define IDS_TRUST5 ·····················234
1ad678 #define IDS_SIGNKEYPASSPHRASE ··········235
22382c #define IDS_SELKEYPASSPHRASE ···········236
f5b5a4 #define IDS_IMPORTFILTER ···············237
229be1 #define IDS_PROPTITLE0 ·················238
07052b #define IDS_DSA_ELGAMAL ················239
770807 #define IDS_NEVER ······················241
fd5862 #define IDS_NODRAGTEXTKEYS ·············242
410463 #define IDS_DEFEXPORTEXTENSION ·········243
e7e791 #define IDS_ERRONEOUSADK ···············244
21cc39 #define IDS_NOUSERNAME ·················245
f1c057 #define IDS_REVOKECONFIRM ··············246
7437ee #define IDS_TRUSTONINVALIDKEY ··········247
a9bbb1 #define IDS_CERTIFYERROR ···············248
1aba54 #define IDS_REVCONFDEFKEY ··············249
599e2b #define IDS_UNAVAILABLECERT ············250
482474 #define IDS_NOUSERADDR ·················251
3e9124 #define IDS_EXPORTFILTER ···············252
2dfc2b #define IDS_INVALIDDATE ················253
563ed7 #define IDS_USERID ·····················254
222516 #define IDS_FINGERPRINT ················255
dbc23e #define IDS_KEYIDFIELD ·················257
fb6ef5 #define IDS_EXPIRATIONFIELD ············258
5c1da4 #define IDS_ADKFIELD ···················259
1bfd12 #define IDS_RSAPUBKEY ··················260
0a34ec #define IDS_RSASECKEY ··················261
feb94a #define IDS_RSAPUBEXPKEY ···············262
bbc5ba #define IDS_RSAPUBREVKEY ···············263
958ecd #define IDS_RSAPUBDISKEY ···············264
534733 #define IDS_RSASECDISKEY ···············265
220e0c #define IDS_RSASECEXPKEY ···············266
--183f 000812d023e401102bf Page 4 of resource.h
6d72fc #define IDS_RSASECREVKEY ···············267
fa46d8 #define IDS_DSAPUBKEY ··················268
178f26 #define IDS_DSASECKEY ··················269
cda52c #define IDS_DSAPUBEXPKEY ···············270
e5d9dc #define IDS_DSAPUBREVKEY ···············271
c1f5cb #define IDS_DSAPUBDISKEY ···············272
933c35 #define IDS_DSASECDISKEY ···············273
f0126a #define IDS_DSASECEXPKEY ···············274
386e9a #define IDS_DSASECREVKEY ···············275
968d4b #define IDS_RSAUSERID ··················276
68e199 #define IDS_DSAUSERID ··················277
5276ff #define IDS_CERT ·······················278
236419 #define IDS_REVCERT ····················279
76e586 #define IDS_BADCERT ····················280
146f7b #define IDS_KEYSELECTED ················281
5f35bb #define IDS_UIDSELECTED ················282
1e0243 #define IDS_CERTSELECTED ···············283
f39f00 #define IDS_MULTISELECTED ··············284
3a764b #define IDS_UPLOADOK ···················285
c39f96 #define IDS_REQMINPHRASELEN ············286
461f98 #define IDS_SUGMINPHRASELEN ············287
7c54dd #define IDS_REQMINPHRASEQUAL ···········288
40d4d3 #define IDS_SUGMINPHRASEQUAL ···········289
f26c68 #define IDS_QUERYCONTINUESIGNING ·······290
e8bb7f #define IDS_QUERYCONTINUEREVOKINGKEY ···291
d7ee1b #define IDS_QUERYCONTINUEREVOKINGCERT ··292
92060d #define IDS_QUERYCONTINUEADDINGNAME ····293
43fca3 #define IDS_QUERYCONTINUEADDING ········293
167663 #define IDS_DELETEFROMSERVEROK ·········294
3f9d61 #define IDS_DISABLEONSERVEROK ··········295
aa2086 #define IDS_EXPORTCERT ·················296
c05f8d #define IDS_METACERT ···················297
b27432 #define IDS_EXPORTMETACERT ·············298
2c3228 #define IDS_SERVERSEARCHFAIL ···········299
31a5d7 #define IDS_UNKNOWNADK ·················300
9c9297 #define IDS_UNKNOWNADKID ···············301
481a6b #define IDI_KEYICON ····················301
46faf6 #define IDS_KEYALREADYONSERVER ·········302
ee6287 #define IDR_MENUIMPORT ·················302
b04036 #define IDS_KEYSALREADYONSERVER ········303
f1aca4 #define IDR_MENUEDITSERVER ·············303
de4857 #define IDS_PROPTITLE1 ·················304
f2c3c5 #define IDS_PROPTITLE2 ·················305
1cb618 #define IDS_VALIDFROM ··················306
f3741e #define IDS_EXPIRES ····················307
0ca064 #define IDS_SIZE ·······················308
4d7ab7 #define IDS_BADSUBKEYSIZE ··············309
0cfdb5 #define IDS_DELETESUBKEYCONF ···········310
bb5122 #define IDS_UNKNOWNKEY ·················311
2a80cc #define IDS_SUBKEYOVERLAP ··············312
ce0272 #define IDS_SHARES ·····················313
f0e2f1 #define IDS_SAVESHARES ·················314
15ddc6 #define IDS_SHAREPHRASEPROMPT ··········315
7336d7 #define IDS_SPLITKEYTITLE ··············316
51345a #define IDS_SPLITKEYPHRASEPROMPT ·······317
204d11 #define IDS_DEFSHAREEXTENSION ··········318
2e19d3 #define IDS_DEFSHARENAME ···············319
c40619 #define IDS_PHOTOIDPHRASE ··············320
301727 #define IDS_PHOTOUSERID ················321
5d54be #define IDS_UNKNOWNUSERID ··············322
4685ed #define IDS_UNKNOWNIMAGEFORMAT ·········325
1e0afc #define IDS_ERR_IMAGETOOBIG ············326
d4adf7 #define IDS_ERR_INVALIDIMAGE ···········327
5b4828 #define IDS_REVOKESUBKEYCONF ···········328
4f0f91 #define IDS_REMOVESUBKEYCONF ···········329
8d3a78 #define IDS_REMOVEONLYSUBKEYCONF ·······330
b97f7b #define IDS_NUMSHARES ··················331
31c899 #define IDS_ONESHARE ···················332
1e8c9b #define IDD_KEYPROPSUBKEYS ·············401
a9993f #define IDD_NEWSUBKEY ··················403
3902f6 #define IDB_QUESTIONMARK ···············406
81aac6 #define IDB_REVOKED ····················407
--92f4 000189ff2de401102bf Page 5 of resource.h
b523d6 #define IDD_SPLITKEY ···················408
b0ec35 #define IDD_ADDSHAREHOLDER ·············409
8b6ef7 #define IDR_MENUPHOTOID ················410
20b98a #define IDD_CONFIRMAUTHENTICATION ······411
1978e3 #define IDD_SPLITKEYPROGRESS ···········412
0eaabb #define IDD_RECONSTITUTEKEY ············413
d1685d #define IDD_REVERIFYING ················414
c6ab61 #define IDD_WARNINGDLG ·················415
d55d76 #define IDD_NEWPHOTOID ·················416
00a4a6 #define IDR_MENUNEWPHOTOID ·············417
49592d #define IDB_EXPIRED ····················418
4c28f6 #define IDB_NOTAVAILABLE ···············419
b551fa #define IDD_DRIVERWARNING ··············420
a6b126 #define IDD_KEYPROPREVOKERS ············421
1d4486 #define IDD_SUBKEYGENPROG ··············422
603eee #define IDC_TREELIST ···················1000
4f68cd #define IDC_YESTOALL ···················1001
b156d1 #define IDC_NAME ·······················1002
de422f #define IDC_SETPRIVATEKEYRING ··········1003
c9cf20 #define IDC_SETPUBLICKEYRING ···········1004
0d683a #define IDC_PRIVATEKEYRING ·············1005
7e04fd #define IDC_PUBLICKEYRING ··············1006
d5ee7c #define IDC_NEVEREXPIRES ···············1007
08c66c #define IDC_FINGERPRINT ················1008
f56284 #define IDC_TRUSTSLIDER ················1009
18ff6c #define IDC_VALIDITYBAR ················1010
9cb55f #define IDC_BITSPROGBAR ················1011
9d77f4 #define IDC_ENABLED ····················1012
9bde25 #define IDC_CHANGEPHRASE ···············1013
953157 #define IDC_KEYID ······················1014
4e13f1 #define IDC_NEWUSERNAME ················1015
2677b8 #define IDC_PHRASE2 ····················1016
798dc2 #define IDC_KEYTYPE ····················1017
778e4f #define IDC_CREATEDATE ·················1018
e50c4a #define IDC_OLDPHRASE ··················1019
447b63 #define IDC_HIDETYPING ·················1021
3f8331 #define IDC_ENCRYPTTOSELF ··············1023
d28c9b #define IDC_KEYSIZE ····················1025
cfeea6 #define IDC_NEWPHRASE1 ·················1026
331ab2 #define IDC_NEWPHRASE2 ·················1027
b9ebe2 #define IDC_PHRASE ·····················1028
c02c82 #define IDC_PROMPTSTRING ···············1029
7c03c4 #define IDC_STRING ·····················1030
b9db05 #define IDC_EXPIREDATE ·················1031
65db52 #define IDC_AXIOMATIC ··················1032
317f19 #define IDC_CIPHER ·····················1033
16fbbe #define IDC_NEWEMAILADDR ···············1034
b3f90c #define IDC_SENDSIG ····················1035
588b83 #define IDC_SELECTALL ··················1036
013344 #define IDC_UNSELECTALL ················1037
384468 #define IDC_KEYLIST ····················1038
db24df #define IDC_PHRASEQUALITY ··············1045
338091 #define IDC_MINPHRASEQUALITY ···········1046
073bb3 #define IDC_NONEXPORTABLE ··············1047
8d25f0 #define IDC_EXPORTABLE ·················1048
0aee85 #define IDC_TRUSTED ····················1049
982552 #define IDC_META ·······················1050
76d46e #define IDC_MORECHOICES ················1051
3c9d2d #define IDC_FEWERCHOICES ···············1052
022667 #define IDC_EXPORTABLECHECK ············1053
d023ef #define IDC_SIGTYPE ····················1054
0eb77f #define IDC_ADVANCEDTEXT1 ··············1055
6ac4a3 #define IDC_ADVANCEDTEXT2 ··············1056
08ea17 #define IDC_ADVANCEDTEXT3 ··············1057
3feddb #define IDC_ADVANCEDTEXT4 ··············1058
d2f2a0 #define IDC_MINQUALITYTEXT ·············1059
42352b #define IDC_TRUSTTEXT2 ·················1060
22c13f #define IDC_TRUSTTEXT1 ·················1061
cf8102 #define IDC_EXPORTPRIVATEKEYS ··········1062
ebe85b #define IDC_EXPIRATION ·················1063
cd7ba3 #define IDC_EXPIRATIONDATE ·············1064
1861f8 #define IDC_PROGRESS ···················1066
--fc76 000f2887fca401102bf Page 6 of resource.h
001c07 #define IDC_SHAREFILE ··················1093
0d68d4 #define IDC_NUMSHARES ··················1094
9c4293 #define IDC_REMOTECOMPUTER ·············1095
474cc7 #define IDC_NETSTATUS ··················1096
eaf8b8 #define IDC_AUTHENTICATION ·············1097
b33550 #define IDC_SENDSHARES ·················1098
bc64da #define IDC_WWWLINK ····················1100
3ba178 #define IDC_USEFASTKEYGEN ··············1102
6fd0d3 #define IDC_RNGSEEDFILE ················1103
044de9 #define IDC_SETRNGSEEDFILE ·············1104
8c8e79 #define IDC_ENCRYPTPGPMIME ·············1105
76f2f7 #define IDC_USEPGPMIME ·················1105
a41d30 #define IDC_DECRYPTCACHEENABLE ·········1107
4cf448 #define IDC_WRAPENABLE ·················1108
91748c #define IDC_WRAPNUMBER ·················1109
951b25 #define IDC_SIGNCACHEENABLE ············1110
1ecf90 #define IDC_CREDITS ····················1111
7bf105 #define IDC_ENCRYPTBYDEFAULT ···········1112
343ed4 #define IDC_SIGNBYDEFAULT ··············1113
1a3b04 #define IDC_SIGNKEYCOMBO ···············1114
8d897a #define IDC_ASCIIARMOR ·················1115
646ace #define IDC_DETACHEDSIG ················1116
bdfb81 #define IDC_BEGIN ······················1117
33636a #define IDC_STATIC1 ····················1118
bd8c6a #define IDC_STATIC2 ····················1119
47e65e #define IDC_STATIC3 ····················1120
04ca2d #define IDC_TEXTPROMPT ·················1121
347675 #define IDC_REMOVEKEYSERVER ············1122
968128 #define IDC_SYNCONUNKNOWN ··············1123
9c220a #define IDC_SYNCONADDNAME ··············1124
7f7502 #define IDC_SYNCONKEYSIGN ··············1125
5efda1 #define IDC_SYNCONREVOKE ···············1126
49635f #define IDC_MARGVALIDISINVALID ·········1127
862372 #define IDC_PREFERREDALG ···············1128
2a2423 #define IDC_SETDEFAULTKEYSERVER ········1129
bcad7f #define IDC_EDITKEYSERVER ··············1129
7a356f #define IDC_DOMAINNAME ·················1130
c097a7 #define IDC_PROTOCOL ···················1130
aefeca #define IDC_SERVERNAME ·················1131
ab71b5 #define IDC_ENABLECAST ·················1132
587802 #define IDC_ENABLE3DES ·················1133
261f4e #define IDC_ENABLEIDEA ·················1134
790bd1 #define IDC_DISPMARGVALIDITY ···········1135
236d80 #define IDC_COMMENTBLOCK ···············1136
6546d6 #define IDC_KEYLISTBOX ·················1137
fe8a89 #define IDC_PROGRESSTEXT ···············1138
ceff63 #define IDC_NEWKEYSERVER ···············1139
56265e #define IDC_WIPECONFIRM ················1140
b78856 #define IDC_LDAP ·······················1141
ddf0a3 #define IDC_LDAPS ······················1142
870677 #define IDC_HTTP ·······················1143
41f008 #define IDC_CANNOTDECRYPTTEXT ··········1143
317c3f #define IDC_AUTODECRYPT ················1144
473805 #define IDC_WARNONADK ··················1145
6a1c25 #define IDC_PHRASECONV ·················1146
2d5406 #define IDC_SYNCONSTATICTEXT ···········1147
398880 #define IDC_BUYNOW ·····················1148
7a7f38 #define IDC_DECRYPTCACHETIME ···········1149
639977 #define IDC_SIGNCACHETIME ··············1150
e7a4ec #define IDC_SUBKEYLIST ·················1201
e1cd3c #define IDC_NEWSUBKEY ··················1202
72af7e #define IDC_REVOKESUBKEY ···············1203
eb90a7 #define IDC_REMOVESUBKEY ···············1204
577769 #define IDC_ADKLIST ····················1205
0d0d59 #define IDC_STARTDATE ··················1207
cfaa58 #define IDC_SUBKEYSIZE ·················1208
e9a2b7 #define IDC_EXPIRESON ··················1211
7010cd #define IDC_ONEPASSWIPE ················1212
7526f2 #define IDC_MULTIPASSWIPE ··············1213
57fcd6 #define IDC_OVERWRITEPATTERN ···········1214
d05874 #define IDC_NUMPASSESTEXT ··············1216
f2ef2d #define IDC_OVERWRITETEXT ··············1217
--906a 000d491aa3f401102bf Page 7 of resource.h
de1052 #define IDC_NUMPASSES ··················1218
d7eedb #define IDC_NUMPASSESSPIN ··············1219
0537af #define IDC_SERVERKEY ··················1220
17cc89 #define IDC_SECUREADD ··················1221
5e6183 #define IDC_SECUREDELETE ···············1222
117b13 #define IDC_LIST ·······················1223
6227e1 #define IDC_LISTED ·····················1223
2891c2 #define IDC_PHOTOID ····················1225
923dd4 #define IDC_KEYTOSPLIT ·················1227
a081c4 #define IDC_SHAREHOLDERS ···············1228
5d0bbd #define IDC_CURRENTSHAREHOLDER ·········1229
f00aef #define IDC_REMOVESHAREHOLDER ··········1230
43d465 #define IDC_ADDSHAREHOLDER ·············1231
b7f7a0 #define IDC_THRESHOLD ··················1232
944b0d #define IDC_TOTALSHARES ················1233
0f33aa #define IDC_SHARES ·····················1234
b257dc #define IDC_SHARESSPIN ·················1235
b36e49 #define IDC_THRESHOLDSPIN ··············1237
59dadc #define IDC_NEWSHAREHOLDER ·············1238
83a483 #define IDC_KEYNAME ····················1240
14ac1a #define IDC_VALIDITY ···················1242
c2f383 #define IDC_PROGRESSBAR ················1243
6e2098 #define IDC_STARTNETWORK ···············1245
2758c6 #define IDC_NETWORK ····················1245
8c0abf #define IDC_SHARESCOLLECTED ············1247
a0acdb #define IDC_SHARESNEEDED ···············1248
ae81e4 #define IDC_NETWORKINSTRUCTIONS ········1249
abb361 #define IDC_WARNCHECK ··················1250
398ae3 #define IDC_STATUS ·····················1251
2548f7 #define IDC_WARNINGTEXT ················1251
139c77 #define IDC_STATUSTEXT ·················1252
3e0d00 #define IDC_AUTHENTICATIONTEXT ·········1253
f4a761 #define IDC_TEXT ·······················1254
974b14 #define IDC_PORT ·······················1256
10d112 #define IDC_ANYDOMAIN ··················1257
a62f01 #define IDC_SPECIFIEDDOMAIN ············1258
6dbfbd #define IDC_DOMAIN ·····················1259
c965c0 #define IDC_SELECTFILE ·················1263
d58e08 #define IDC_PHOTOSCROLLBAR ·············1264
cbd063 #define IDC_SYNCONVERIFY ···············1265
23bb1d #define IDC_SETASROOT ··················1268
e08750 #define IDC_IMPORTKEY ··················1269
ebfc51 #define IDC_AUTHTEXT ···················1270
46a85b #define IDC_FRAME ······················1271
e73641 #define IDC_PROMPT ·····················1272
8fd539 #define IDC_NOMOREWARNINGS ·············1273
2f2e42 #define IDC_KEYTORECON ·················1274
0660da #define IDC_STARTDATETEXT ··············1275
710577 #define IDC_SUBKEYAVI ··················1276
d2fd01 #define IDC_STATICTEXT1 ················1277
12ec83 #define IDC_STATICTEXT2 ················1278
88ab26 #define IDC_DOMAINTEXT ·················1280
da2865 #define IDC_EXPORTCOMPATIBLE ···········1281
26f981 #define IDC_EXPORTCOMPLETE ·············1282
c2a13d #define IDC_INCLUDEEXTENSIONS ··········1283
9accca #define IDC_EXPIRES ····················1284
ad79b8 #define IDC_STATIC4 ····················1285
7b3f18 #define IDC_STATIC7 ····················1288
dd2787 #define IDS_SHAREFILEFILTER ············2109
7daa97 #define IDS_SHAREFILECAPTION ···········2110
bdaa00 #define IDS_STATUSNOTCONNECTED ·········2111
32d01c #define IDS_STATUSCONNECTING ···········2112
1610a5 #define IDS_STATUSCONNECTED ············2113
86a356 #define IDS_STATUSSENDING ··············2114
79314e #define IDS_STATUSCLOSING ··············2115
5e8444 #define IDS_SENDAUTHPROMPT ·············2116
910b6f #define IDS_DECRYPTSHARESPROMPT ········2117
6bc6cb #define IDS_STATUSAUTHENTICATED ········2118
3b99e5 #define IDS_SPLITKEYCONFIRMATION ·······2119
89fd7e #define IDS_SENDSUCCESS ················2120
433558 #define IDS_CREATINGSHARES ·············2121
d41875 #define IDS_SAVINGSHARES ···············2122
--6606 000b033fe78401102bf Page 8 of resource.h
10126d #define IDS_SPLITTINGKEY ···············2123
fd6b7c #define IDS_SPLITKEYGONE ···············2124
882c91 #define IDS_SHAREKEYGONE ···············2125
33a697 #define IDS_RECONKEYTITLE ··············2126
059f82 #define IDS_SHAREKEYMISMATCH ···········2127
986675 #define IDS_SHARENUMMISMATCH ···········2128
f499fc #define IDS_RSASECSHRKEY ···············2129
6abb17 #define IDS_DSASECSHRKEY ···············2130
038d4b #define IDS_ERR_INVALIDCOMMONCONTROLS ··2131
a70a04 #define IDS_STARTNETWORK ···············2132
5e9212 #define IDS_STOPNETWORK ················2133
16c68c #define IDS_STATUSRECEIVING ············2134
03addc #define IDS_RECONAUTHPROMPT ············2135
49cd4f #define IDS_PREPARINGTOVERIFY ··········2136
36b554 #define IDS_VERIFYING ··················2137
9615b9 #define IDS_UNIDENTIFIEDHOST ···········2138
0a5088 #define IDS_SERVER ·····················2139
005fd2 #define IDS_LDAP ·······················2140
831497 #define IDS_LDAPS ······················2141
a5d1f3 #define IDS_HTTP ·······················2142
2d342f #define IDS_BADPASSKEY ·················2143
c7e9d8 #define IDS_BITMAPDEFEXT ···············2144
132c5c #define IDS_BITMAPFILTER ···············2145
a2db1d #define IDS_OPENBITMAPTITLE ············2146
17be18 #define IDS_EXPCERT ····················2147
80b4fd #define IDS_NEWPHRASEPROMPT ············2148
3357ac #define IDS_PHRASECHANGED ··············2149
0cf204 #define IDS_RECONSTITUTEKEY ············2150
778eba #define IDS_KEYRECONSTITUTED ···········2151
e2767b #define IDS_CHANGEPHRASE ···············2152
c39c9b #define IDS_DUPLICATESHARES ············2153
262e27 #define IDS_LICENSEDTO ·················2154
e5eb81 #define IDS_VERSION ····················2155
6bc69d #define IDS_NOROOTSERVER ···············2156
ed7c59 #define IDS_UNEXPECTEDAUTHKEY ··········2157
658d8d #define IDS_INVALIDAUTHKEY ·············2158
390292 #define IDS_NEWAUTHKEY ·················2159
7e60d2 #define IDS_ENFORCEFIELD ···············2160
01a373 #define IDS_IMPORT ·····················2161
bce542 #define IDS_ADDREVOKERPROMPT ···········2162
91fbec #define IDS_QUERYADDPROMPT ·············2163
8a5075 #define IDS_ADDEDREVOKERS ··············2164
ba4b6a #define IDS_ADDREVOKERCONFIRM ··········2165
bf655c #define IDS_NOTENOUGHKEYSTOADDREVOKER ··2166
4be59f #define IDS_STATUSFINISHED ·············2167
52e350 #define IDS_DONE ·······················2168
602639 #define IDS_DUPLICATESERVER ············2169
962b15 #define IDS_IMPORTKEYERROR ·············2170
e69531 #define IDS_PROPTITLE3 ·················2171
4e5e3a #define IDS_ERRONEOUSREVOKER ···········2172
f15329 #define IDS_VALIDAUTHKEY ···············2173
665e45 #define IDS_ERR_FILEOPFAILED ···········2174
1e831e #define IDS_KEYNOTSIGNEDBYCORP ·········2175
31cb0c #define IDS_NOVALIDDEFAULTKEY ··········2176
2b2fac #define IDS_NOOUTADK ···················2177
244aa2 #define IDS_NOCORPSIGNKEY ··············2178
ef0e20 #define IDS_TEXTOUTPUT ·················2179
7e6447 #define IDS_CONVENCRYPTION ·············2180
2cbbb2 #define IDS_WIPEORIGINAL ···············2181
fba04b #define IDS_ATLEASTONEORCONV ···········2182
5a4634 #define IDS_DETACHEDSIG ················2183
fbbe0f #define IDS_ANIMATIONFILE ··············2184
f6ba10 #define IDS_PHOTOIDALREADYEXISTS ·······2185
cf7485 #define IDS_ADDEDSENTREVOKERS ··········2186
230975 #define IDS_ERR_FAILEDSERVERPOLICY ·····2187
74a7ed #define IDS_STATUSLISTENING ············2187
d757c8 #define IDS_MUSTHAVEDEFAULTSERVER ······2188
0f14f9 #define IDS_SPLITKEYSNOTALLOWED ········2189
6a984c #define IDS_BADSHAREFILEPASSPHRASE ·····2190
b92fe4 #define IDS_KEYRINGFOLDER ··············2191
2cb1cf #define IDS_FYEO ·······················2192
b0f20a #define IDS_WIPEWODEFAULT ··············2193
--a781 001e5b5daeb401102bf Page 9 of resource.h
65b39c #define IDM_EDITSERVER ·················40001
3ad8eb #define IDM_KEYPROPERTIES ··············40002
dc88ba #define IDM_PASTEBITMAP ················40003
ac6306 #define IDM_COPYBITMAP ·················40004
28a567 #define IDM_REMOVESERVER ···············40005
d69964 #define IDM_NEWSERVER ··················40006
2856b4 #define IDM_SETASROOT ··················40007
c1af5a
9611aa // Next default values for new objects
9eac6a //·
edf860 #ifdef APSTUDIO_INVOKED
1b3f23 #ifndef APSTUDIO_READONLY_SYMBOLS
3858f4 #define _APS_NEXT_RESOURCE_VALUE ·······423
22b604 #define _APS_NEXT_COMMAND_VALUE ········40008
bbde40 #define _APS_NEXT_CONTROL_VALUE ········1289
8b1285 #define _APS_NEXT_SYMED_VALUE ··········101
1d7454 #endif
e57454 #endif
--3a42 0002c11a4da401102c0 Page 1 of hook.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d35004 ¤   $Id: hook.c,v 1.1.2.2.2.1 1998/11/12 03:13:17 heller Exp $
0bf7f7 ____________________________________________________________________________*/
1caf5a
fb729d #include "windows.h"
88a855 #include "..\include\PGPhk.h"
68af5a
f622ee HINSTANCE g_hinst;
11af5a
f6c640 #pragma data_seg(".SHARDAT")
e72a5b static HHOOK ·g_hCBTHook ··= NULL ;
4e7cc8 static DWORD ·TrayProcessID = 0 ··;
bd3498 static HWND ··CurrentFocus = NULL ; // SetFocus window
6fd116 #pragma data_seg()
c7af5a
e8cf2c LRESULT WINAPI CBTProc (int nCode, WPARAM wParam, LPARAM lParam)
05bb36 {
01d807 ¤   if (nCode >= 0)
08c7a1 ¤   {
31e511 ¤   ¤   switch (nCode)
122b60 ········{
5ff633 ¤   ¤   ¤   case HCBT_SETFOCUS:
faf776 ¤   ¤   ¤   {
2c9827 ¤   ¤   ¤   ¤   HWND hwndCurrent;
f86d3e ¤   ¤   ¤   ¤   DWORD ThreadID;
2362d9 ¤   ¤   ¤   ¤   DWORD ProcessID;
58af5a
a63679 ¤   ¤   ¤   ¤   hwndCurrent=(HWND)LOWORD(wParam);
d0af5a
8f959c ¤   ¤   ¤   ¤   ThreadID=GetWindowThreadProcessId(hwndCurrent,&ProcessID);
b442fd ¤   ¤   ¤   ¤   if((ProcessID!=TrayProcessID)&&(CurrentFocus!=hwndCurrent)&&
3b9fa7 ¤   ¤   ¤   ¤   ¤   (hwndCurrent!=NULL))
a172c3 ¤   ¤   ¤   ¤   {
67af36 ¤   ¤   ¤   ¤   ¤   CurrentFocus=hwndCurrent;
742613 ¤   ¤   ¤   ¤   }
56f622 ¤   ¤   ¤   ¤   break;
e35a2a ¤   ¤   ¤   }¤
7231d3 ¤   ¤   }¤  ¤   ¤
789371 ¤   }
bdaf5a
3c7a29 ¤   return CallNextHookEx (g_hCBTHook, nCode, wParam, lParam);
3cefe6 }
fcaf5a
48af5a
efd01f HWND ReadCurrentFocus(void)
8ebb36 {
99ee47 ¤   return CurrentFocus;
58efe6 }
7faf5a
adac49 void SetHook(void)
b3bb36 {
43ff3a ¤   TrayProcessID=GetCurrentProcessId();
c8af5a
53186c ¤   g_hCBTHook=SetWindowsHookEx(WH_CBT,·
455562 ¤   ¤   (HOOKPROC)CBTProc,
186373 ¤   ¤   g_hinst,
a6fa39 ¤   ¤   0);
96efe6 }
beaf5a
8d9acb void DeleteHook(void)
6dbb36 {
815506 ¤   UnhookWindowsHookEx(g_hCBTHook);
16efe6 }
7a1b52 ¤   ¤
522163 BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason,LPVOID lpvReserved)
80bb36 {
2c5a5c ···switch (fdwReason) {
--f186 001c7af21b1401102c0 Page 2 of hook.c
bfd340 ······case DLL_PROCESS_ATTACH:
a0923f ·········g_hinst = hinstDll;
b2a646 ¤   ¤   ·//vErrorOut(fg_white,"DLL_PROCESS_ATTACH\n");
955180 ·········break;
113ccb ······case DLL_THREAD_ATTACH:
61462a ¤   ¤   ··//vErrorOut(fg_white,"DLL_THREAD_ATTACH\n");
d05180 ·········break;
c181b6 ······case DLL_THREAD_DETACH:
2ac867 ¤   ¤   ··//vErrorOut(fg_red,"DLL_THREAD_DETACH\n");
742f68 ¤   ¤   break;
5d6e3d ······case DLL_PROCESS_DETACH:
a86f2f ¤   ¤   ··//vErrorOut(fg_red,"DLL_PROCESS_DETACH\n");
9b5180 ·········break;
9fb144 ···}
297921 ···return(TRUE);
20efe6 }
b4af5a
717e4d /*__Editor_settings____
3caf5a
4c4126 ¤   Local Variables:
f17b17 ¤   tab-width: 4
420e6c ¤   End:
bc5f8c ¤   vi: ts=4 sw=4
9e9e9b ¤   vim: si
c7d062 _____________________*/
--19c2 00185f8c405401102c1 Page 1 of pgphk.def
d80c85 ; PGP60hk.def : Declares the module parameters for the DLL.
2baf5a
0c9465 LIBRARY ·····"PGP60hk"
4cc0d1 DESCRIPTION ·'PGP CBT Hook Library'
60af5a
6a7665 SECTIONS
56bfc7 ··········.SHARDAT READ WRITE SHARED
2eaf5a
e1ef2b EXPORTS
369063 ········CBTProc
105265 ¤   ¤   ReadCurrentFocus
f4c750 ¤   ¤   SetHook
855817 ¤   ¤   DeleteHook
--e87b 001442fc829401102c2 Page 1 of PGPhk.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
c2729d #include "windows.h"
08af5a
396c0e /////////////////////////////////////////////////////////////////////////////
8c7b93 #undef APSTUDIO_READONLY_SYMBOLS
e2af5a
2a6c0e /////////////////////////////////////////////////////////////////////////////
00f930 // English (U.S.) resources
43af5a
3d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
96ec08 #ifdef _WIN32
5de912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
779c1c #pragma code_page(1252)
e81f8e #endif //_WIN32
24af5a
96f860 #ifdef APSTUDIO_INVOKED
866c0e /////////////////////////////////////////////////////////////////////////////
c1465d //
fb5733 // TEXTINCLUDE
86465d //
32af5a
eb86ef 1 TEXTINCLUDE DISCARDABLE·
724523 BEGIN
ad541e ····"resource.h\0"
78e0d1 END
85af5a
9e7037 2 TEXTINCLUDE DISCARDABLE·
614523 BEGIN
ba766b ····"#include ""windows.h""\r\n"
a2db5c ····"\0"
21e0d1 END
6caf5a
fd227f 3 TEXTINCLUDE DISCARDABLE·
144523 BEGIN
acdb71 ····"#include ""PGPhkVer.rc""\r\n"
12db5c ····"\0"
31e0d1 END
37af5a
5069ab #endif ···// APSTUDIO_INVOKED
feaf5a
541b3a #endif ···// English (U.S.) resources
f86c0e /////////////////////////////////////////////////////////////////////////////
dcaf5a
45af5a
52af5a
a4ce8c #ifndef APSTUDIO_INVOKED
5c6c0e /////////////////////////////////////////////////////////////////////////////
2a465d //
978464 // Generated from the TEXTINCLUDE 3 resource.
65465d //
e9ec78 #include "PGPhkVer.rc"
c0af5a
076c0e /////////////////////////////////////////////////////////////////////////////
2b8072 #endif ···// not APSTUDIO_INVOKED
44af5a
--5c15 0011f89562c401102c3 Page 1 of PGPhkVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
1d029d ············VALUE "FileDescription", "PGP Hook Library\0"
f7c1dd ············VALUE "FileVersion", PGPVERSIONSTRING
5b9c70 ············VALUE "InternalName", "PGP60hk\0"
bd8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
ef2bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
3327fc ············VALUE "OriginalFilename", "PGP60hk.dll\0"
759317 ············VALUE "ProductName", PGPPRODUCTNAME
fcd1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
93f37f ········END
b87d01 ····END
cb26ab ····BLOCK "VarFileInfo"
e35574 ····BEGIN
194b11 ········VALUE "Translation", 0x409, 1200
447d01 ····END
d7e0d1 END
66af5a
53af5a
1faf5a
--4cf1 001a6be565f401102c4 Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
923739 // Used by PGPhkVer.rc
9e465d //
95af5a
8611aa // Next default values for new objects
37ac6a //·
3df860 #ifdef APSTUDIO_INVOKED
e53f23 #ifndef APSTUDIO_READONLY_SYMBOLS
90b0ab #define _APS_NEXT_RESOURCE_VALUE ·······101
e4611c #define _APS_NEXT_COMMAND_VALUE ········40001
a4f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
841285 #define _APS_NEXT_SYMED_VALUE ··········101
487454 #endif
a67454 #endif
--72c8 000be579275401102c5 Page 1 of ListMng.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
3138d9 ¤   $Id: ListMng.c,v 1.4.18.1 1998/11/12 03:13:18 heller Exp $
89f7f7 ____________________________________________________________________________*/
205ed8 #include "precomp.h"
45af5a
aabbf8 #define EDGEMARGIN 0
59af5a
099510 #if LISTBOX
4aaf5a
80fccc void MoveList(LISTSTRUCT *ls,int Width,int Height)
9bbb36 {
2ba6f6 ¤   int listwidth;
326b72 ¤   int xpos;
4cf7fd ¤   float textfloat,ratio;
592715 ¤   int index;
03af5a
ece613 ¤   listwidth=Width-EDGEMARGIN*2;
02af5a
01e612 ¤   MoveWindow(ls->hwndlist,
2dfc9b ¤   ¤   EDGEMARGIN,EDGEMARGIN+15,
58a21a ¤   ¤   listwidth,Height-EDGEMARGIN*2-15,
e9be2f ¤   ¤   TRUE);
2faf5a
deed00 ¤   xpos=EDGEMARGIN;
49af5a
0d7572 ····for(index=0;index<NUMCOLUMNS;index++)
c43b37 ····{
e22136 ¤   ¤   ratio=ls->colratio[index];
50af5a
cb885a ¤   ¤   textfloat=(float)listwidth;
0ae29a ¤   ¤   ls->colwidth[index]=(int)(ratio*textfloat);
ea1b52 ¤   ¤
3f6d9e ¤   ¤   MoveWindow(ls->hwndtext[index],
c2094d ¤   ¤   ¤   xpos,0,
5658b7 ¤   ¤   ¤   ls->colwidth[index],20,
5c5c8c ¤   ¤   ¤   TRUE);
a267c5 ¤
68f757 ¤   ¤   xpos=xpos+ls->colwidth[index];
cc9371 ¤   }
cbefe6 }
e1af5a
1779bf BOOL InitList(HWND hwnd,LISTSTRUCT *ls,char **ColText,float *ColRatio)
febb36 {
475bda ¤   RECT rc;
202715 ¤   int index;
81af5a
18e6a7 ¤   ls->hwnd=hwnd;
84f9a6 ¤   ls->colratio=ColRatio;
f4af5a
8c57bc ····ls->hwndlist = CreateWindow ("listbox", NULL,
0651a5 ······················WS_CHILD | WS_VISIBLE | WS_VSCROLL |·
3a5d55 ¤   ¤   ¤   ¤   ¤   ··WS_BORDER| LBS_OWNERDRAWFIXED,
0f16d9 ······················0,0,0,0,
5a9e0a ······················hwnd, (HMENU)IDC_LOGLIST,
7a65a2 ······················(HINSTANCE) g_hinst,
08eac6 ······················NULL) ;
e9af5a
becfca ¤   ShowWindow(ls->hwndlist,SW_SHOW);
8faf5a
ba7572 ····for(index=0;index<NUMCOLUMNS;index++)
a43b37 ····{
425a8d ¤   ¤   ls->hwndtext[index]=CreateWindow ("STATIC",ColText[index],
e4e1cd ····················WS_CHILD | WS_VISIBLE | SS_CENTER,
cfa6ed ····················0,0,0,0,
c061d6 ····················hwnd, (HMENU)(2000+index),
065f68 ····················(HINSTANCE) g_hinst,
be7d23 ····················NULL) ;
--6ade 000ade6efaf401102c5 Page 2 of ListMng.c
e0af5a
16dfa5 ¤   ¤   SendMessage(ls->hwndtext[index],WM_SETFONT,
02e6a7 ¤   ¤   ¤   ¤   ···(WPARAM)hFont,(LPARAM)MAKELPARAM(TRUE,0));
8b9371 ¤   }
05af5a
ca1c73 ¤   GetClientRect(hwnd,&rc);
2c26e8 ¤   MoveList(ls,rc.right-rc.left,rc.bottom-rc.top);
8eaf5a
abc2e7 ¤   return TRUE;
19efe6 }
18af5a
838c6c int AddAnItem(HWND hwndList,DRAWDATA *dd)
41bb36 {
a5009c ¤   return SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)dd);
2aefe6 }
63af5a
a3c432 int SetListCursor(HWND hwndList,int index)
5ebb36 {
572b89 ¤   return SendMessage(hwndList,LB_SETCURSEL,(WPARAM)index,
c981fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)0);
0cefe6 }
57af5a
e47ef4 #else // Listview·
edaf5a
ea9d43 int AddListViewItem(HWND hWndLV,int iImage,LPSTR szText,LPARAM lParam)
1fbb36 {
e129aa ····LV_ITEM ·lvItem;
55af5a
8618eb ····lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT ;
32af5a
59e8f4 ····lvItem.lParam ·······= lParam;
8612ab ····lvItem.iImage ·······= iImage;
d4ac06 ¤   lvItem.pszText ······= szText;
7d6eca ····lvItem.iSubItem ·····= 0;
b40c9b ····lvItem.iItem ········= ListView_GetItemCount( hWndLV);
7767c5 ¤
22ca0f ····return ListView_InsertItem ( hWndLV, &lvItem );
c4efe6 }
afaf5a
acaf5a
8e83b0 BOOL AddListViewColumn(HWND hwnd,char **ColText,int *ColWidth,int num)
c9bb36 {
5df7c3 ····LV_COLUMN lvc;
48cf7d ····RECT rect;
6718ca ····BOOL ReturnValue = TRUE;
007312 ····int scrollwidth = GetSystemMetrics(SM_CXVSCROLL);
9bc0b0 ····int index;
18af5a
4f3260 ····GetClientRect(hwnd, &rect);
7eaf5a
9276c9 ····for(index=0;index<num;index++)
d83b37 ····{
42df15 ····lvc.mask ·······= LVCF_WIDTH | LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT;·
67da84 ····lvc.pszText ····= ColText[index];
152524 ····lvc.cx ·········= ColWidth[index];
01b151 ····lvc.iSubItem ···= index;·
439986 ····if(index==0)
447fc2 ········lvc.fmt ····= LVCFMT_LEFT;
55842c ····else
faaef6 ········lvc.fmt ····= LVCFMT_CENTER;
f9af5a
28f175 ····ListView_InsertColumn(hwnd, index, &lvc);
506fe7 ····}
f6af5a
54dc7e ····return ReturnValue;
adefe6 }
a4af5a
96fccc void MoveList(LISTSTRUCT *ls,int Width,int Height)
a2bb36 {
4be612 ¤   MoveWindow(ls->hwndlist,
cbe319 ¤   ¤   EDGEMARGIN,EDGEMARGIN,
ad6b88 ¤   ¤   Width-EDGEMARGIN*2,Height-EDGEMARGIN*2,
--7cff 000140eb9e6401102c5 Page 3 of ListMng.c
7ebe2f ¤   ¤   TRUE);
3defe6 }
0baf5a
1679bf BOOL InitList(HWND hwnd,LISTSTRUCT *ls,char **ColText,float *ColRatio)
17bb36 {
565bda ¤   RECT rc;
ef2715 ¤   int index;
99a6f6 ¤   int listwidth;
156b72 ¤   int xpos;
1dc7e6 ¤   float ratio;
e89c36 ¤   float textfloat;
26af5a
94e6a7 ¤   ls->hwnd=hwnd;
0aaf5a
55ba51 ····GetClientRect(hwnd,&rc);
daaf5a
5a5685 ¤   listwidth=rc.right-rc.left-EDGEMARGIN*2;
9baf5a
0cbd82 ¤   ls->hwndlist = CreateWindowEx (
5ab7f1 ¤   ¤   ¤   ¤   ¤   WS_EX_CLIENTEDGE,
40f4e8 ¤   ¤   ¤   ¤   ¤   WC_LISTVIEW,
b506e6 ¤   ¤   ¤   ¤   ¤   "",
802e09 ¤   ¤   ¤   ¤   ¤   WS_VISIBLE|WS_CHILD|LVS_REPORT|
38fc1d ¤   ¤   ¤   ¤   ¤   WS_BORDER|LVS_OWNERDRAWFIXED,
49a6ed ····················0,0,0,0,
260989 ····················hwnd, (HMENU)IDC_LOGLIST,
075f68 ····················(HINSTANCE) g_hinst,
887d23 ····················NULL) ;
c7af5a
d1cfca ¤   ShowWindow(ls->hwndlist,SW_SHOW);
aaaf5a
d476cc ¤   listwidth=listwidth; // For icon
2b35c2 ¤   xpos=rc.left+10;
abaf5a
567572 ····for(index=0;index<NUMCOLUMNS;index++)
b13b37 ····{
33e608 ¤   ¤   ratio=ColRatio[index];
d0af5a
f5c845 ¤   ¤   if(ratio>1.0)
1168c0 ¤   ¤   ¤   ls->colwidth[index]=(int)ratio;
910e1d ¤   ¤   else
c85b34 ¤   ¤   {
ab4d0f ¤   ¤   ¤   textfloat=(float)listwidth;
0db736 ¤   ¤   ¤   ls->colwidth[index]=(int)(ratio*textfloat);
4e0fe4 ¤   ¤   }
959371 ¤   }
49af5a
e2b836 ¤   AddListViewColumn(ls->hwndlist,ColText,
f7a6f9 ¤   ¤   ¤   ls->colwidth,NUMCOLUMNS);
9aaf5a
b1c2e7 ¤   return TRUE;
aeefe6 }
faaf5a
d88c6c int AddAnItem(HWND hwndList,DRAWDATA *dd)
4abb36 {
3f2715 ¤   int index;
8faf5a
1547db ¤   index=AddListViewItem(hwndList,0,"",(LPARAM)dd);
aaaf5a
a724a6 ¤   return index;
46efe6 }
64af5a
22c432 int SetListCursor(HWND hwndList,int index)
77bb36 {
b96a4a ¤   ListView_EnsureVisible( hwndList,index,FALSE);
7eaf5a
05c2e7 ¤   return TRUE;
7aefe6 }
dbaf5a
e54bbb #endif // LISTBOX
0faf5a
14af5a
--78fa 001dffab6e2401102c5 Page 4 of ListMng.c
217e4d /*__Editor_settings____
c9af5a
864126 ¤   Local Variables:
f87b17 ¤   tab-width: 4
5c0e6c ¤   End:
b85f8c ¤   vi: ts=4 sw=4
a09e9b ¤   vim: si
dfd062 _____________________*/
--1947 001244d57dc401102c6 Page 1 of ListMng.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
1596a0 ¤   $Id: ListMng.h,v 1.2.18.1 1998/11/12 03:13:19 heller Exp $
c9f7f7 ____________________________________________________________________________*/
e8e890 #ifndef Included_LISTMNG_h¤ /* [ */
70bc24 #define Included_LISTMNG_h
25af5a
8d547d #include "OwnDraw.h"
20af5a
252713 #define NUMCOLUMNS 4
b672c3 #define LISTBOX 0
03af5a
b70027 typedef struct _liststruct
babb36 {
dd55cf ¤   HWND hwnd;
16b2d0 ¤   HWND hwndlist;
68010f ¤   HWND hwndtext[NUMCOLUMNS];
8bbfd3 ¤   int colwidth[NUMCOLUMNS];
d9b4ec ¤   float *colratio;
a7d648 } LISTSTRUCT;
8caf5a
234d25 BOOL InitList(HWND hwnd,LISTSTRUCT *ls,char **ColText,float *ColRatio);
e11275 int SetListCursor(HWND hwndList,int index);
9ca9c6 int AddAnItem(HWND hwndList,DRAWDATA *dd);
bd0cbc void MoveList(LISTSTRUCT *ls,int Width,int Height);
6baf5a
fd4955 #endif /* ] Included_LISTMNG_h */
e8af5a
73af5a
9d7e4d /*__Editor_settings____
8daf5a
f34126 ¤   Local Variables:
d37b17 ¤   tab-width: 4
ca0e6c ¤   End:
765f8c ¤   vi: ts=4 sw=4
f79e9b ¤   vim: si
24d062 _____________________*/
--f5af 000ce6850aa401102c7 Page 1 of OwnDraw.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
b4d2b7 ¤   $Id: OwnDraw.c,v 1.9.2.2.2.1 1998/11/12 03:13:19 heller Exp $
88f7f7 ____________________________________________________________________________*/
5f38e5 /*
6e468e ·* OwnDraw.c ·ListView draw routines to accommidate italics/strikeout
9f775e ·*
b98a63 ·* These routines use the ownerdraw characteristic of the standard·
81ea7f ·* listview to provide custom drawing routines.
16775e ·*
a2bd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
a2599a ·* All rights reserved.
6f495d ·*/
a35ed8 #include "precomp.h"
32af5a
62af5a
f5af5a
81cbaf void CreateDrawElements(DRAWSTRUCT *ds)
06bb36 {
dbc1dd ¤   LOGFONT lf;
f9cade ¤   int iNumBits;
4d8b3d ¤   HDC hDC;
eb37a3 ¤   HBITMAP hBmp;
6daf5a
338733 ¤   ds->DisplayMarginal=FALSE;
a6af5a
ce3ff5 ¤   GetValidityDrawPrefs(PGPsc,&(ds->DisplayMarginal));
7af130 ¤   GetMarginalInvalidPref(PGPsc,&(ds->MarginalInvalid));
53af5a
22d6be ····ds->stdbarbrush =·
21da3f ········CreateSolidBrush (GetSysColor (COLOR_3DSHADOW));
aa3d44 ····ds->spcbarbrush =·
7f1274 ········CreateHatchBrush(HS_BDIAGONAL, GetSysColor (COLOR_WINDOW));
1d5e12 ····ds->g_seltextpen =·
79f007 ········CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOWTEXT));
48a07f ····ds->g_unseltextpen =
4a717a ········CreatePen (PS_SOLID, 0, GetSysColor (COLOR_WINDOW));
b6af5a
1baba6 ¤   ds->barcolor = GetSysColor (COLOR_3DSHADOW);
97af5a
1ba516 ····ds->buttonpen = CreatePen(PS_SOLID, 0, GetSysColor (COLOR_3DSHADOW));
d68941 ¤   ds->hilightpen = CreatePen (PS_SOLID, 0,·
e88cfd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DHILIGHT));
f4cea1 ¤   ds->shadowpen = CreatePen (PS_SOLID, 0,·
3d3dd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DDKSHADOW));
efaf5a
9ec2fd ····ds->barbgbrush = CreateSolidBrush (GetSysColor (COLOR_3DFACE));
5faf5a
774f7f ····ds->HighBrush=CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
b883e0 ····ds->BackBrush=CreateSolidBrush(GetSysColor(COLOR_WINDOW));
c8af5a
ed44ab ····SystemParametersInfo (SPI_GETICONTITLELOGFONT,·
9b345f ¤   ¤   sizeof(LOGFONT), &lf, 0);
c5af5a
8bf7b3 ····ds->hFont=CreateFontIndirect (&lf);
de81c9 ····lf.lfItalic = !lf.lfItalic;
cf38b0 ····ds->hItalic=CreateFontIndirect (&lf);
3b81c9 ····lf.lfItalic = !lf.lfItalic;
148205 ····lf.lfStrikeOut=TRUE;
7c567a ····ds->hStrikeOut = CreateFontIndirect (&lf);
10af5a
d52b93 ¤   // ImageList Init
c6af5a
097f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
a689fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
efe693 ¤   ReleaseDC (NULL, hDC);
8caf5a
ce2be4 ¤   if (iNumBits <= 8) {
--830e 00003723637401102c7 Page 2 of OwnDraw.c
94dcbc ¤   ¤   ds->hIml =¤ ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
4a8fce ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
8fd557 ¤   ¤   hBmp = LoadBitmap (g_hinst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
a86628 ¤   ¤   ImageList_AddMasked (ds->hIml, hBmp, RGB(255, 0, 255));
3a5c8d ¤   ¤   DeleteObject (hBmp);
8a9371 ¤   }
6f665a ¤   else {
1f284d ¤   ¤   ds->hIml =¤ ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
7b8fce ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
234f5f ¤   ¤   hBmp = LoadBitmap (g_hinst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
5f6628 ¤   ¤   ImageList_AddMasked (ds->hIml, hBmp, RGB(255, 0, 255));
fb5c8d ¤   ¤   DeleteObject (hBmp);
a09371 ¤   }
00efe6 }
73af5a
b0e647 void DeleteDrawElements(DRAWSTRUCT *ds)
32bb36 {
a04971 ····DeleteObject(ds->stdbarbrush);
c5dd5d ····DeleteObject(ds->spcbarbrush);
79ef39 ····DeleteObject(ds->g_seltextpen);
15b78c ····DeleteObject(ds->g_unseltextpen);
e8eff4 ¤   DeleteObject(ds->hilightpen);
93401d ¤   DeleteObject(ds->shadowpen);
315336 ¤   DeleteObject(ds->buttonpen);
18af5a
f2c5ad ····DeleteObject(ds->barbgbrush);·
c6e855 ····DeleteObject(ds->HighBrush);·
31eeb7 ····DeleteObject(ds->BackBrush);·
a9bfdc ¤   DeleteObject(ds->hFont);
f44b24 ¤   DeleteObject(ds->hItalic);
d2f139 ¤   DeleteObject(ds->hStrikeOut);
741938 ¤   ImageList_Destroy(ds->hIml);
ddefe6 }
85af5a
bc79f9 void DrawBar(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
f8a4a9 ·············int DataValue,int MaxValue,BOOL Selected)
06bb36 {
68c194 ····RECT rc;
fd7939 ····HBRUSH oldbrush,barbrush;
0bf069 ····HPEN oldpen;
73af32 ····COLORREF oldbkcolor;
4ed6f9 ¤   int cx;
74af5a
b6c573 ¤   CopyRect(&rc,ptrBarRect);
f7af5a
217de8 ····if(Selected)
093b37 ····{
215f33 ········FillRect (hdc, &rc, ds->HighBrush);
aaeee2 ········oldpen = SelectObject (hdc, ds->g_unseltextpen);
216fe7 ····}
fd842c ····else
4a3b37 ····{
358d55 ········FillRect (hdc, &rc, ds->BackBrush);
00bfef ········oldpen = SelectObject (hdc, ds->g_seltextpen);
ea6fe7 ····}
6daf5a
829228 ····rc.top+=5;
aee182 ····rc.left+=5;
0629fd ····rc.bottom-=5;
a40dda ····rc.right-=5;
a1af5a
96eca7 ¤   if(rc.right<=rc.left)
c399bf ¤   ¤   return;
b1af5a
e73f87 ¤   cx=rc.right-rc.left;
8caf5a
435b7c ¤   oldbrush = SelectObject (hdc, ds->barbgbrush);
f244ef ¤   SelectObject (hdc, ds->buttonpen);
3eaf5a
e0766f ¤   Rectangle (hdc, rc.left - 1, rc.top - 1,·
c4d7a3 ¤   ¤   rc.right + 2, rc.bottom + 2);
03af5a
--f112 000e2e39275401102c7 Page 3 of OwnDraw.c
4357c4 ¤   SelectObject (hdc, ds->shadowpen);
20eb65 ¤   MoveToEx (hdc, rc.left, rc.bottom, NULL);
ba2014 ¤   LineTo (hdc, rc.left, rc.top);
16d7f7 ¤   LineTo (hdc, rc.right, rc.top);
b2af5a
dfa4af ¤   SelectObject (hdc, ds->hilightpen);
77a783 ¤   LineTo (hdc, rc.right, rc.bottom);
537046 ¤   LineTo (hdc, rc.left, rc.bottom);
b3e624 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
410f63 ¤   if (MaxValue != 0)·
f1c7a1 ¤   {
0fd224 ¤   ¤   if (DataValue > MaxValue)·
c85b34 ¤   ¤   {
a59763 ¤   ¤   ¤   barbrush = ds->spcbarbrush;
5d40f1 ¤   ¤   ¤   rc.right = rc.left + cx;
460fe4 ¤   ¤   }
68ee26 ¤   ¤   else·
615b34 ¤   ¤   {
be32f3 ¤   ¤   ¤   barbrush = ds->stdbarbrush;
6ffccf ¤   ¤   ¤   rc.right = rc.left +·
98135e ¤   ¤   ¤   ¤   (int)(((float)DataValue /·
001cbf ¤   ¤   ¤   ¤   (float)MaxValue)
c346cb ¤   ¤   ¤   ¤   * (float)cx);
dc0fe4 ¤   ¤   }
8e9371 ¤   }
f14264 ¤   else·
076cc3 ¤   ¤   rc.right = rc.left;
85af5a
5cd34a ¤   rc.top++;
c9b27f ¤   rc.left++;
bfaf5a
3eba0a ¤   if (rc.right > rc.left)·
a3c7a1 ¤   {
d15974 ¤   ¤   oldbkcolor=SetBkColor (hdc, ds->barcolor);
415341 ¤   ¤   FillRect (hdc, &rc, barbrush);·
cfaf5a
f1cbbc ¤   ¤   rc.top--;
8bcd9f ¤   ¤   rc.left--;
5daf5a
6ccdf5 ¤   ¤   // hilight pen already selected·
d1b757 ¤   ¤   MoveToEx (hdc, rc.right, rc.top, NULL);
d061e7 ¤   ¤   LineTo (hdc, rc.left, rc.top);
95eaa6 ¤   ¤   LineTo (hdc, rc.left,rc.bottom);
f2af5a
325988 ¤   ¤   SelectObject (hdc, ds->shadowpen);
43a9cf ¤   ¤   LineTo (hdc, rc.right, rc.bottom);
f712a2 ¤   ¤   LineTo (hdc, rc.right, rc.top);
569b70 ¤   ¤   SetBkColor(hdc,oldbkcolor);
919371 ¤   }
a2af5a
7e23c2 ¤   SelectObject (hdc, oldbrush);
5962dc ¤   SelectObject (hdc, oldpen);
89efe6 }
e0af5a
1be23d void DrawNoviceButton(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
a2a4a9 ·············int DataValue,int MaxValue,BOOL Selected)
b8bb36 {
005813 ¤   DWORD NoviceIcon;
a847a3 //¤ HICON hIcon;
a8af5a
d47de8 ····if(Selected)
153b37 ····{
b4437c ········FillRect (hdc, ptrBarRect, ds->HighBrush);
3b6fe7 ····}
3c842c ····else
bc3b37 ····{
7a911a ········FillRect (hdc, ptrBarRect, ds->BackBrush);
c76fe7 ····}
6faf5a
aafeb1 ¤   if((ptrBarRect->right-ptrBarRect->left)>=CX_SMICON)
b6c7a1 ¤   {
e201c1 ¤   ¤   NoviceIcon=IDX_INVALID;
--d9d5 0008b293f47401102c7 Page 4 of OwnDraw.c
e0af5a
1db1e3 ¤   ¤   if(DataValue>2)
95fcd5 ¤   ¤   ¤   NoviceIcon=IDX_AXIOMATIC;
34af5a
fb7023 ¤   ¤   if(DataValue==2)
fb7a44 ¤   ¤   ¤   NoviceIcon=IDX_VALID;
9caf5a
921575 ¤   ¤   if((!ds->MarginalInvalid)&&(DataValue==1))
3f7a44 ¤   ¤   ¤   NoviceIcon=IDX_VALID;
b7af5a
07ec08 #ifdef _WIN32
4150bd ¤   ¤   ImageList_Draw(ds->hIml,NoviceIcon,
3636cb ¤   ¤   ¤   hdc,
2c8a15 ¤   ¤   ¤   ptrBarRect->left+((ptrBarRect->right-ptrBarRect->left-16)/2),
fa4e5f ¤   ¤   ¤   ptrBarRect->top+((ptrBarRect->bottom-ptrBarRect->top-16)/2),
794a66 ¤   ¤   ¤   ILD_TRANSPARENT);
6cdb21 #else
413230 ¤   ¤   hIcon=LoadIcon(g_hinst,MAKEINTRESOURCE(NoviceIcon));
2e67c5 ¤
a76757 ¤   ¤   DrawIcon(hdc,
f2ee0c ¤   ¤   ¤   ptrBarRect->left+((ptrBarRect->right-ptrBarRect->left-32)/2),
362a46 ¤   ¤   ¤   ptrBarRect->top+((ptrBarRect->bottom-ptrBarRect->top-32)/2),
b9d911 ¤   ¤   ¤   hIcon);
8e67c5 ¤
2a40c0 ¤   ¤   DeleteObject(hIcon);
7f7454 #endif
8b9371 ¤   }
62efe6 }
10af5a
7dfe19 LISTSTRUCT *GetListStruct(HWND hwndList)
b5bb36 {
98638e ¤   return &logList;
e8efe6 }
d5af5a
50bbd0 DRAWSTRUCT *GetDrawStruct(HWND hDlg)
e8bb36 {
13a4c9 ¤   return &logDraw;
1fefe6 }
d6af5a
2ac0bc void DrawStuff(LPDRAWITEMSTRUCT lpDrawItem)
8fbb36 {
2b2afb ¤   DRAWDATA *dd;
e229b8 ¤   DRAWSTRUCT *ds;
d092b8 ¤   LISTSTRUCT *ls;
7d2715 ¤   int index;
c65bda ¤   RECT rc;
0b47a3 //¤ HICON hIcon;
3298f5 ¤   HWND hDlg,hwndList;
bfd8d0 ¤   int max;
85af5a
bc02d2 ¤   hwndList=lpDrawItem->hwndItem;
e6a701 ¤   hDlg=GetParent(hwndList);
df67c5 ¤
4f8529 ¤   ls=GetListStruct(hwndList);
5a025a ¤   ds=GetDrawStruct(hDlg);
aaaf5a
e208e4 ¤   dd=(DRAWDATA *)(lpDrawItem->itemData);
6971e5 ¤   CopyRect(&rc,&(lpDrawItem->rcItem));
5438e5 /*
2f86da ¤   hIcon=LoadIcon(g_hinst,MAKEINTRESOURCE(dd->icon));
3667c5 ¤
7837cc ¤   DrawIcon(lpDrawItem->hDC,
62cbcc ¤   ¤   rc.left+((CX_SMICON-32)/2),
8bc643 ¤   ¤   rc.top+((CY_SMICON-32)/2),
f24e62 ¤   ¤   hIcon);
e067c5 ¤
77749d ¤   DeleteObject(hIcon);
807fe0 */
c6765a ¤   ImageList_Draw(ds->hIml,dd->icon,
7969ca ¤   ¤   lpDrawItem->hDC,
abafd5 ¤   ¤   rc.left+((CX_SMICON-16)/2),
8ba25a ¤   ¤   rc.top+((CY_SMICON-16)/2),
--0936 00084765833401102c7 Page 5 of OwnDraw.c
3fc332 ¤   ¤   ILD_TRANSPARENT);
2faf5a
81a39f ¤   rc.right=rc.left;
ca25fc ¤   rc.left=rc.left+16;
f7af5a
a939b8 ¤   max=0;
6caf5a
0e4935 ¤   for(index=0;index<NUMCOLUMNS;index++)
40c7a1 ¤   {
d59510 #if LISTBOX
461ea5 ¤   ¤   max=max+ls->colwidth[index];
1bdb21 #else
b8b072 ¤   ¤   max=max+
373886 ¤   ¤   ¤   ListView_GetColumnWidth(lpDrawItem->hwndItem,index);
1f7454 #endif
a99371 ¤   }
2eaf5a
ac4935 ¤   for(index=0;index<NUMCOLUMNS;index++)
ddc7a1 ¤   {
d59510 #if LISTBOX
82520d ¤   ¤   rc.right=rc.right+ls->colwidth[index];
9adb21 #else
280af1 ¤   ¤   rc.right=rc.right+
9c3886 ¤   ¤   ¤   ListView_GetColumnWidth(lpDrawItem->hwndItem,index);
367454 #endif
1291da ¤   ¤   switch(dd->type[index])
5d5b34 ¤   ¤   {
933b67 ¤   ¤   ¤   case PGP_DDERROR:
25f776 ¤   ¤   ¤   {
14e640 ¤   ¤   ¤   ¤   rc.right=max;
8d6934 ¤   ¤   ¤   ¤   DrawItemColumn(lpDrawItem->hDC,
97ec06 ¤   ¤   ¤   ¤   ¤   (char *)dd->data1[index],
e508f0 ¤   ¤   ¤   ¤   ¤   &rc);
a4f622 ¤   ¤   ¤   ¤   break;
d6a3a6 ¤   ¤   ¤   }
76af5a
3a9c1c ¤   ¤   ¤   case PGP_DDTEXT:
bdf776 ¤   ¤   ¤   {
946934 ¤   ¤   ¤   ¤   DrawItemColumn(lpDrawItem->hDC,
edec06 ¤   ¤   ¤   ¤   ¤   (char *)dd->data1[index],
e008f0 ¤   ¤   ¤   ¤   ¤   &rc);
79f622 ¤   ¤   ¤   ¤   break;
c4a3a6 ¤   ¤   ¤   }
80af5a
0f959a ¤   ¤   ¤   case PGP_DDBAR:
a3f776 ¤   ¤   ¤   {
f5eded ¤   ¤   ¤   ¤   // Don't display validity for bad signature
82a2ed ¤   ¤   ¤   ¤   if(dd->icon==IDX_REVCERT)
9a72c3 ¤   ¤   ¤   ¤   {
750258 ¤   ¤   ¤   ¤   ¤   if(lpDrawItem->itemState & ODS_SELECTED)
564859 ¤   ¤   ¤   ¤   ¤   {
bd8b5b ¤   ¤   ¤   ¤   ¤   ¤   FillRect (lpDrawItem->hDC, &rc, ds->HighBrush);
ae1c89 ¤   ¤   ¤   ¤   ¤   }
724bd6 ¤   ¤   ¤   ¤   ¤   else
834859 ¤   ¤   ¤   ¤   ¤   {
00593d ¤   ¤   ¤   ¤   ¤   ¤   FillRect (lpDrawItem->hDC, &rc, ds->BackBrush);
3e1c89 ¤   ¤   ¤   ¤   ¤   }
b414c3 ¤   ¤   ¤   ¤   ¤   break;
612613 ¤   ¤   ¤   ¤   }
e9af5a
afebb4 ¤   ¤   ¤   ¤   if(ds->DisplayMarginal)
08cbbd ¤   ¤   ¤   ¤   ¤   DrawBar(ds,lpDrawItem->hDC,&rc,
85eaab ¤   ¤   ¤   ¤   ¤   ¤   (int)dd->data1[index],(int)dd->data2[index],
2597f8 ¤   ¤   ¤   ¤   ¤   ¤   (lpDrawItem->itemState & ODS_SELECTED));
fefa07 ¤   ¤   ¤   ¤   else
d7677d ¤   ¤   ¤   ¤   ¤   DrawNoviceButton(ds,lpDrawItem->hDC,&rc,
0b60ee ¤   ¤   ¤   ¤   ¤   (int)dd->data1[index],(int)dd->data2[index],
874dd1 ¤   ¤   ¤   ¤   ¤   (lpDrawItem->itemState & ODS_SELECTED));
88f622 ¤   ¤   ¤   ¤   break;
67a3a6 ¤   ¤   ¤   }
0eaf5a
840fe4 ¤   ¤   }
--7670 000c83ccaf3401102c7 Page 6 of OwnDraw.c
40f6a0 ¤   ¤   rc.left=rc.right;
529371 ¤   }
77b115 ¤   lpDrawItem->rcItem.right=max;
b7efe6 }
d1af5a
e9465d //
f1728e // ·DrawListViewItem
c0465d //
e10917 // ·This routine, given a standard Windows LPDRAWITEMSTRUCT, draws the
4037a0 // ·elements of our custom listview (adapted from a routine in the Microsoft
b2eab2 // ·Knowledge base)
f8465d //
e0af5a
9920f4 void DrawListViewItem(LPDRAWITEMSTRUCT lpDrawItem)
95bb36 {
8f6c54 ····UINT uiFlags;
3baf5a
2a6c24 ¤   uiFlags=ILD_TRANSPARENT;
f8af5a
77c1c4 ····// Check to see if this item is selected
2f398f ····if (lpDrawItem->itemState & ODS_SELECTED)
853b37 ····{
322c2d ········// Set the text background and foreground colors
ed3903 ········SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
ef6bcd ········SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
33869e ····
7fe79e ········// Also add the ILD_BLEND50 so the images come out selected
f8e937 ········uiFlags |= ILD_BLEND50;
a36fe7 ····}
b9842c ····else
933b37 ····{
f2cb98 ········// Set the text background and foreground colors to the·
cae1de ········// standard window colors
4f5e9d ········SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
a6db7e ········SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
5a6fe7 ····}
94af5a
7b00d8 ¤   DrawStuff(lpDrawItem);
67af5a
cf0f7c ¤   lpDrawItem->rcItem.left=lpDrawItem->rcItem.left+CX_SMICON;
2eaf5a
e50fbc ····// If we changed the colors for the selected item, undo it
e0398f ····if (lpDrawItem->itemState & ODS_SELECTED)
943b37 ····{
6d2c2d ········// Set the text background and foreground colors
875e9d ········SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
4fdb7e ········SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
e66fe7 ····}
4baf5a
89d144 ····// If the item is focused, now draw a focus rect around the entire row
843167 ····if (lpDrawItem->itemState & ODS_FOCUS)
c13b37 ····{
e3427b ········// Draw the focus rect
7c17a4 ········DrawFocusRect(lpDrawItem->hDC, &(lpDrawItem->rcItem));
196fe7 ····}
faaf5a
4d3471 ····return;
ecefe6 }
a9af5a
e3af5a
942019 // DrawItemColumn
3c465d //
5e49b8 // Given a clipping rectange and some text, see how well we can fit
244ee5 // it in there, and tack on ... if we can't
caaf5a
6e6622 void DrawItemColumn(HDC hdc, LPTSTR lpsz, LPRECT prcClip)
13bb36 {
b58a45 ····TCHAR szString[256];
0eaf5a
2bc063 ····// Check to see if the string fits in the clip rect. ·If not, truncate
b12180 ····// the string and add "...".
c88d35 ····lstrcpy(szString, lpsz);
--3b6c 000b325acea401102c7 Page 7 of OwnDraw.c
c9ceb8 ····CalcStringEllipsis(hdc, szString, 256, prcClip->right - prcClip->left);
1daf5a
ff2ef3 ····// print the text
7caf5a
f957fd ····ExtTextOut(hdc, prcClip->left + 2, prcClip->top + 1,·
1c0adf ···············ETO_CLIPPED | ETO_OPAQUE,
bd7025 ···············prcClip, szString, lstrlen(szString), NULL);
15efe6 }
6daf5a
57af5a
cd14ce // CalcStringEllipsis
80465d //
fe219d // Trial and error routine used to see where to put the ... in our string
3f53b3 // to make it fit within a clipping rectangle.
38af5a
23b7ec BOOL CalcStringEllipsis(HDC hdc, LPTSTR lpszString,·
abf8e7 ························int cchMax, UINT uColWidth)
2cbb36 {
8a1156 ····const TCHAR szEllipsis[] = TEXT("...");
ec6bf7 ····SIZE ··sizeString;
32d2ca ····SIZE ··sizeEllipsis;
f61111 ····int ···cbString;
fe18a5 ····LPTSTR lpszTemp;
02ff5a ····BOOL ··fSuccess = FALSE;
74a3ba ····BOOL fOnce = TRUE;
d41a5b ····FARPROC pGetTextExtentPoint;
f7af5a
60e171 ····if (fOnce)
1a3b37 ····{
d71621 ········fOnce = FALSE;
25af5a
3364a2 ········pGetTextExtentPoint = &GetTextExtentPoint;
a46fe7 ····}
64af5a
52a919 ····// Adjust the column width to take into account the edges
dc3d61 ····uColWidth -= 4;
e8af5a
313b37 ····{
597672 ········// Allocate a string for us to work with. ·This way we can mangle the
342e34 ········// string and still preserve the return value
85ed76 ········lpszTemp = (LPTSTR) malloc(cchMax);
c09fee ········lstrcpy(lpszTemp, lpszString);
61af5a
d05e6d ········// Get the width of the string in pixels
003906 ········cbString = lstrlen(lpszTemp);
0e592b ········(pGetTextExtentPoint)(hdc, lpszTemp, cbString, &sizeString);
19af5a
b08633 ········// If the width of the string is greater than the column width shave
5395d2 ········// the string and add the ellipsis
662348 ········if ((ULONG)sizeString.cx > uColWidth)
9a2b60 ········{
48060c ············(pGetTextExtentPoint)(hdc, szEllipsis, lstrlen(szEllipsis),
14f5ab ·······································&sizeEllipsis);
21af5a
67b699 ············while (cbString > 0)
632cc2 ············{
048868 ················lpszTemp[--cbString] = 0;
61267c ················!(pGetTextExtentPoint)(hdc, lpszTemp, cbString, &sizeString);
2daf5a
847c83 ················if ((ULONG)(sizeString.cx + sizeEllipsis.cx) <= uColWidth)
523b8c ················{
b482ae ················// The string with the ellipsis finally fits, now make sure
27563f ················// there is enough room in the string for the ellipsis
73ac8f ····················if (cchMax >= (cbString + lstrlen(szEllipsis)))
238ae9 ····················{
8601a9 ····················// Concatenate the two strings and break out of the loop
af9168 ························lstrcat(lpszTemp, szEllipsis);
2b2e9c ························lstrcpy(lpszString, lpszTemp);
45db42 ························fSuccess = TRUE;
508c7f ························break;
bdde39 ····················}
b36f5c ················}
--fec8 000de8e1b19401102c7 Page 8 of OwnDraw.c
077812 ············}
657fb0 ········}
ed1e5b ········else
342b60 ········{
0e9fd4 ············// No need to do anything, everything fits great.
0e9b9b ············fSuccess = TRUE;
727fb0 ········}
1d6fe7 ····}
8caf5a
c5bf86 ····// Free the memory
092d03 ····free(lpszTemp);
75f7c4 ····return (fSuccess);
a7efe6 }
0eaf5a
bbaf5a
e11dd4 // Main_OnDrawItem
bf465d //
5fb626 // Entry function for the message handler. Basically, we want to draw
76b689 // the whole thing no matter what.
46af5a
8aa2cb BOOL Main_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
7ebb36 {
11af5a
858972 ····// Make sure the control is the listview control
26be00 ····if ((lpDrawItem->CtlType != ODT_LISTVIEW)&&
302dfb ¤   ¤   (lpDrawItem->CtlType != ODT_LISTBOX))
4d81ae ········return FALSE;
a7af5a
2bfb0f ····switch (lpDrawItem->itemAction)
283b37 ····{
22beb0 ········case ODA_DRAWENTIRE:
4bd89d ········case ODA_FOCUS:
7b2c3c ········case ODA_SELECT:
cd569f ············DrawListViewItem((LPDRAWITEMSTRUCT)lpDrawItem);
708632 ············break;
656fe7 ····}
ffaf5a
988011 ····return TRUE;
acefe6 }
a7af5a
19d95e // Main_OnMeasureItem
22465d //
694e61 // Entry function for the message handler. We need to get the width and
ded969 // height of the font we're using.
b1af5a
656f5e void Main_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT * lpMeasureItem)
1fbb36 {
df440f ····TEXTMETRIC tm;
c59d1b ····HDC hdc;
21d8c8 ····HWND hwndLV;
7dfa9a ····HFONT hFont;
c1af5a
428972 ····// Make sure the control is the listview control
7b3f00 ····if ((lpMeasureItem->CtlType != ODT_LISTVIEW)&&
729de2 ¤   ¤   (lpMeasureItem->CtlType != ODT_LISTBOX))
4cdc81 ········return;
11af5a
f0b9e9 ····// Get the handle of the ListView control we're using
5faa71 ····hwndLV = GetDlgItem(hwnd, lpMeasureItem->CtlID);
dfaf5a
91f885 ····// Get the font the control is currently using
9766f3 ····hFont = (HFONT)(DWORD) SendMessage(hwndLV, WM_GETFONT, 0, 0L);
daaf5a
5440b3 ····// Set the font of the DC to the same font the control is using
0293bb ····hdc = GetDC(hwndLV);
810e12 ····SelectObject(hdc, hFont);
51af5a
c3363e ····// Get the height of the font used by the control
5b521b ····if (!GetTextMetrics(hdc, &tm))
12dc81 ········return;
ceaf5a
de7b5f ····// Add a little extra space between items
--6b55 00199a3a539401102c7 Page 9 of OwnDraw.c
2734c9 ····lpMeasureItem->itemHeight = tm.tmHeight + 1;
80af5a
d4b2a8 ····// Make sure there is enough room for the images which are CY_SMICON high
8f0de5 ····if (lpMeasureItem->itemHeight < (CY_SMICON + 1))
78fffd ········lpMeasureItem->itemHeight = CY_SMICON + 1;
80af5a
36bf5f ····// Clean up
37983e ····ReleaseDC(hwndLV, hdc);
6eefe6 }
9aaf5a
47af5a
cd7e4d /*__Editor_settings____
dbaf5a
384126 ¤   Local Variables:
507b17 ¤   tab-width: 4
c80e6c ¤   End:
dc5f8c ¤   vi: ts=4 sw=4
479e9b ¤   vim: si
aad062 _____________________*/
99af5a
--d267 000af2c401b401102c8 Page 1 of OwnDraw.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
601ddc ¤   $Id: OwnDraw.h,v 1.6.16.1 1998/11/12 03:13:20 heller Exp $
89f7f7 ____________________________________________________________________________*/
d3e1ad #ifndef Included_OWNDRAW_h¤ /* [ */
a96e04 #define Included_OWNDRAW_h
14af5a
f638e5 /*
43468e ·* OwnDraw.c ·ListView draw routines to accommidate italics/strikeout
ea775e ·*
a38a63 ·* These routines use the ownerdraw characteristic of the standard·
45ea7f ·* listview to provide custom drawing routines.
2c775e ·*
9ebd54 ·* Copyright (C) 1996 Network Associates, Inc. and its affiliates.
99599a ·* All rights reserved.
15495d ·*/
f2af5a
e27b18 #define CX_SMICON ··16 ·············// Size of the small images
89c966 #define CY_SMICON ··16
51af5a
27af5a
909d21 typedef struct _drawstruct
95bb36 {
f1b3f0 ¤   BOOL DisplayMarginal;
d09d16 ¤   BOOL MarginalInvalid;
c74702 ¤   DWORD barcolor;
03bd45 ¤   HBRUSH stdbarbrush;
8e18d5 ¤   HBRUSH spcbarbrush;
f77880 ¤   HPEN g_seltextpen;
d295c8 ¤   HPEN g_unseltextpen;
0f640e ¤   HPEN hilightpen;
811db9 ¤   HPEN shadowpen;
dbaf9a ¤   HPEN buttonpen;
9daf5a
82ba96 ¤   HBRUSH barbgbrush;
718d41 ¤   HBRUSH HighBrush;
8f46d5 ¤   HBRUSH BackBrush;
fcf61b ¤   HFONT¤  hFont;
f8caf3 ¤   HFONT¤  hItalic;
436d42 ¤   HFONT¤  hStrikeOut;
d657f7 ¤   HIMAGELIST hIml;
03b3e3 } DRAWSTRUCT;
1baf5a
faaf5a
6a15af #define PGP_DDERROR 1
cd213f #define PGP_DDTEXT 2
ff7755 #define PGP_DDBAR 3
c1af5a
377d6c #define MAXCOLS 10
c0af5a
24c666 typedef struct _drawdata
05bb36 {
82159c ¤   int numcols;
a2fe8f ¤   int icon;
fd016a ¤   int type[MAXCOLS];
5ec724 ¤   void *data1[MAXCOLS];
a040ca ¤   void *data2[MAXCOLS];
830d8d ¤   int chunksize;
110ec5 ¤   char *chunk;
38447e ¤   struct _drawdata *next;
78ed25 } DRAWDATA;
4daf5a
9b5d16 void CreateDrawElements(DRAWSTRUCT *ds);
73367d void DeleteDrawElements(DRAWSTRUCT *ds);
2b79f9 void DrawBar(DRAWSTRUCT *ds,HDC hdc,RECT *ptrBarRect,
b1384f ·············int DataValue,int MaxValue,BOOL Selected);
ccb1ab void DrawListViewItem(LPDRAWITEMSTRUCT lpDrawItem);
af0256 void DrawItemColumn(HDC hdc, LPTSTR lpsz, LPRECT prcClip);
--9a48 001cd91cdd7401102c8 Page 2 of OwnDraw.h
d0b7ec BOOL CalcStringEllipsis(HDC hdc, LPTSTR lpszString,·
519369 ························int cchMax, UINT uColWidth);
26785d BOOL Main_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem);
20bbb4 void Main_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT * lpMeasureItem);
87af5a
2326e5 #endif /* ] Included_OWNDRAW_h */
35af5a
adaf5a
347e4d /*__Editor_settings____
32af5a
f64126 ¤   Local Variables:
d57b17 ¤   tab-width: 4
1f0e6c ¤   End:
cf5f8c ¤   vi: ts=4 sw=4
939e9b ¤   vim: si
cdd062 _____________________*/
--685a 001fbc3d44e401102c9 Page 1 of PGPlgVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
d52042 ·FILETYPE VFT_APP
817247 ·FILESUBTYPE VFT2_UNKNOWN
f44523 BEGIN
752c72 ····BLOCK "StringFileInfo"
095574 ····BEGIN
fe70ac ········BLOCK "040904b0"
2752d6 ········BEGIN
e980b6 ············VALUE "CompanyName", PGPCOMPANYNAME
e8919d ············VALUE "FileDescription", "PGP Message Logger\0"
91c1dd ············VALUE "FileVersion", PGPVERSIONSTRING
ac85c8 ············VALUE "InternalName", "PGPlog\0"
3f8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
d12bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
795b1a ············VALUE "OriginalFilename", "PGPlog.exe\0"
c79317 ············VALUE "ProductName", PGPPRODUCTNAME
86d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
03f37f ········END
5c7d01 ····END
cd26ab ····BLOCK "VarFileInfo"
405574 ····BEGIN
6a4b11 ········VALUE "Translation", 0x409, 1200
ff7d01 ····END
fae0d1 END
2faf5a
17af5a
fbaf5a
--6cef 00085f0133f401102ca Page 1 of PGPlog.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
6d6c0e /////////////////////////////////////////////////////////////////////////////
81465d //
fbcbaf // Icon
7c465d //
56af5a
e52951 // Icon with lowest ID value placed first to ensure application icon
d50f06 // remains consistent on all systems.
82ade2 IDI_LOGICON ············ICON ···DISCARDABLE ····"res\\logicon.ico"
9493d5 IDI_GOODSIG ············ICON ···DISCARDABLE ····"res\\goodsig.ico"
960ed5 IDI_BADSIG ·············ICON ···DISCARDABLE ····"res\\badsig.ico"
4f074f IDI_PGPERROR ···········ICON ···DISCARDABLE ····"res\\pgperror.ico"
21af5a
66f860 #ifdef APSTUDIO_INVOKED
046c0e /////////////////////////////////////////////////////////////////////////////
3e465d //
8c5733 // TEXTINCLUDE
b8465d //
87af5a
9786ef 1 TEXTINCLUDE DISCARDABLE·
e34523 BEGIN
b0541e ····"resource.h\0"
d3e0d1 END
50af5a
d97037 2 TEXTINCLUDE DISCARDABLE·
214523 BEGIN
f7eb23 ····"#include ""afxres.h""\r\n"
53db5c ····"\0"
19e0d1 END
bdaf5a
26227f 3 TEXTINCLUDE DISCARDABLE·
b94523 BEGIN
ef8ad8 ····"#include ""PGPlgVer.rc""\r\n"
d3db5c ····"\0"
47e0d1 END
33af5a
5469ab #endif ···// APSTUDIO_INVOKED
ecaf5a
83af5a
556c0e /////////////////////////////////////////////////////////////////////////////
63465d //
3eae70 // Bitmap
25465d //
dfaf5a
81fed3 IDB_IMAGES4BIT ·········BITMAP ·DISCARDABLE ····"..\\shared\\images4.bmp"
fe24e2 IDB_IMAGES24BIT ········BITMAP ·DISCARDABLE ····"..\\shared\\images24.bmp"
a5af5a
621b3a #endif ···// English (U.S.) resources
956c0e /////////////////////////////////////////////////////////////////////////////
85af5a
--1234 001ab1926c4401102ca Page 2 of PGPlog.rc
e0af5a
1aaf5a
7bce8c #ifndef APSTUDIO_INVOKED
ca6c0e /////////////////////////////////////////////////////////////////////////////
37465d //
b28464 // Generated from the TEXTINCLUDE 3 resource.
d7465d //
e71ccb #include "PGPlgVer.rc"
69af5a
086c0e /////////////////////////////////////////////////////////////////////////////
c88072 #endif ···// not APSTUDIO_INVOKED
abaf5a
--38b9 0006195a774401102cb Page 1 of Precomp.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
05f618 ¤   $Id: Precomp.h,v 1.8.2.1.2.1 1998/11/12 03:13:21 heller Exp $
f5f7f7 ____________________________________________________________________________*/
1b519a #ifndef Included_PRECOMP_h¤ /* [ */
a35498 #define Included_PRECOMP_h
a5af5a
ba1bcc /*++
67af5a
6dfd5d ··File: precomp.h
0b3b41 ··Author: Bill Blanke (wjb@pgp.com)
a1b408 ··Date: September 25, 1997
430c58 ··Revisions:
22af5a
d567d9 --*/
68af5a
a52a68 #define WIN32_LEAN_AND_MEAN
71f451 #define PGPExport __declspec( dllimport )
d8af5a
e57158 #ifndef WIN32
38af5a
97f9cb #define BST_CHECKED¤¤   ¤   1
1e3c84 #define ULONG unsigned long
db23b0 #define USHORT unsigned short ···
dee290 #define LPTSTR ·char*·
27af5a
5edad3 #define MAX_PATH 256
b2af5a
45f74f #define UCHAR unsigned char
ce67f0 #define CHAR char
abff9d #define INT int ·
562996 #define APIENTRY WINAPI ··
7f7a28 #define BST_CHECKED 1
8e640a #define BST_UNCHECKED 0 ················
8faf5a
0dc950 #define LPCTSTR char *
9caf5a
267454 #endif
93af5a
a6e69a #define STATUS_SUCCESS¤ ¤   ¤   0x0000000
e7b96e #define STATUS_FAILURE¤ ¤   ¤   0x0000001
89d5c8 #define STATUS_CANCEL¤  ¤   ¤   0x0000002
a9af5a
226105 #define NOERROR¤0
5baf5a
b5d500 // system include files
e45655 #include <windows.h>
0e3d0b #include <windowsx.h>
0ebb5f #include <assert.h>
df6bd4 #include <commdlg.h>
adfeb2 #include <stdio.h>
79bea3 #include <stdlib.h>
68e6b2 #include <DDEML.h>
5e90fb #include <commctrl.h>
c0af5a
6c5a65 // project include files
bc9de0 #include "..\include\PGPsc.h"
90ef78 #include "..\include\PGPImage.h"
ffaf5a
6ea0de #include "ListMng.h"
18547d #include "OwnDraw.h"
2e8031 #include "resource.h"
caaf5a
8a5918 #define DISMISSY 25
069301 #define IDC_LOGLIST 101 ··
cfaf5a
bf0dfd HFONT hFont;
61d4ac LISTSTRUCT logList;
--8f09 0019afdd75d401102cb Page 2 of Precomp.h
7d9db3 DRAWSTRUCT logDraw;
2baf5a
2722ee HINSTANCE g_hinst;
f9af5a
e5f8cb void *PGPsc;
433a96 void *PGPtls;
7baf5a
7841ed #endif /* ] Included_PRECOMP_h */
02af5a
d4af5a
497e4d /*__Editor_settings____
3eaf5a
034126 ¤   Local Variables:
547b17 ¤   tab-width: 4
470e6c ¤   End:
f45f8c ¤   vi: ts=4 sw=4
9c9e9b ¤   vim: si
9ad062 _____________________*/
--0aca 00051a04e62401102cc Page 1 of main.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d93832 ¤   $Id: main.c,v 1.20.2.2.2.1 1998/11/12 03:13:21 heller Exp $
92f7f7 ____________________________________________________________________________*/
545ed8 #include "precomp.h"
fdaf5a
9a7a86 #define LOGREGPATH "Software\\Network Associates\\PGP60\\PGPlog"
0faf5a
0ac73a LRESULT ·CALLBACK WndProc ····(HWND, UINT, WPARAM, LPARAM) ;
5b8c31 HDDEDATA CALLBACK DdeCallback (UINT, UINT, HCONV, HSZ, HSZ,
2d17c1 ¤   HDDEDATA, DWORD, DWORD) ;
51af5a
41de42 static float ColRatio[NUMCOLUMNS]={0.20f,0.30f,0.1f,0.39f};
a6a16c static char *ColText[NUMCOLUMNS]={"Name","Signer","Validity","Signed"};
90af5a
407fcb DWORD idInst ;
14d906 HSZ hszService, hszTopic;
39d513 HWND hwndList;
b07c4b DRAWDATA *ddlist;
26af5a
642665 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
4a37bc ¤   ¤   ····LPSTR szCmdLine, int iCmdShow)
dcbb36 {
c396b6 ····MSG msg;
35d613 ····WNDCLASS wndclass;
541be2 ¤   HWND hwnd;·
bec5c7 ¤   int error;
7c247d ¤   DRAWDATA *FreeAtLast;
a5af5a
96d78a ¤   if(WindowExists(DDElogServer,DDElogServer))
1ec7a1 ¤   {
e3836c ¤   ¤   return TRUE;
9c9371 ¤   }
ee869e ····
8b5836 ¤   if(!InitPGPsc(NULL,&PGPsc,&PGPtls))
6932bd ¤   ¤   ¤   return TRUE;
4caf5a
cf8f6c ¤   ddlist=0;
08af5a
a7f9eb ····g_hinst=hInstance;
c2d83c ·
ca642d ····wndclass.style ········= CS_HREDRAW | CS_VREDRAW ;
642a9c ····wndclass.lpfnWndProc ··= (WNDPROC)WndProc ;
4a6e09 ····wndclass.cbClsExtra ···= 0 ;
2750fc ····wndclass.cbWndExtra ···= 0 ;
e10f53 ····wndclass.hInstance ····= hInstance ;
179cbf ····wndclass.hIcon ········= LoadIcon(hInstance,
11c13f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDI_LOGICON));
01f5e1 ····wndclass.hCursor ······= LoadCursor (NULL, IDC_ARROW) ;
f4258f ····wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
319e2a ····wndclass.lpszMenuName ·= NULL;
368297 ····wndclass.lpszClassName = DDElogServer;
2aaf5a
ca4f1a ····error=RegisterClass (&wndclass) ;
07af5a
651af5 ····hwnd = CreateWindow (DDElogServer, DDElogServer,
6b7781 ··················WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX |·
aa4d5a ¤   ¤   ¤   ¤   ··WS_BORDER | WS_SYSMENU | WS_THICKFRAME |
1241db ¤   ¤   ¤   ¤   ··WS_MAXIMIZEBOX,
db681d ··················CW_USEDEFAULT, CW_USEDEFAULT,
700ae8 ··················590,120,
0242d3 ··················NULL, NULL, hInstance, NULL) ;
81af5a
627b52 ····ShowWindow (hwnd, SW_SHOW);
aa290f ····UpdateWindow (hwnd) ;
1eaf5a
7e57ea ····// Initialize for using DDEML
51af5a
--5c72 00010e01d04401102cc Page 2 of main.c
31e07e ····if (DdeInitialize (&idInst, (PFNCALLBACK) &DdeCallback,
f139cb ··················CBF_FAIL_POKES |
743263 ··················CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS |
b6597e ¤   ¤   ¤   ·¤  ··CBF_SKIP_CONNECT_CONFIRMS, 0))
309108 ¤   {·
3e8bf5 ¤   ¤   MessageBox (hwnd,"Could not initialize PGPlog's DDEML server!",
feb282 ······················DDElogServer, MB_ICONEXCLAMATION | MB_OK) ;
65af5a
6425b6 ¤   ¤   DestroyWindow (hwnd) ;
72a6db ¤   ¤   return FALSE ;
bd6fe7 ····}
e0af5a
37e8c6 ···
b6fc55 ····hszService = DdeCreateStringHandle (idInst, DDElogServer, 0) ;
fc7a38 ····hszTopic ··= DdeCreateStringHandle (idInst, DDElogTopic, ··0) ;
d3af5a
38a149 ····DdeNameService (idInst, hszService, NULL, DNS_REGISTER) ;
3eaf5a
cc629f ····while (GetMessage (&msg, NULL, 0, 0))
bd3b37 ····{
509cde ¤   ¤   if( IsDialogMessage( hwnd, &msg ) ) ····
788f5e ¤   ¤   ¤   // ·Process Tab messages and such
9c17f5 ¤   ¤   ¤   continue;
0eaf5a
63db9b ¤   ¤   TranslateMessage (&msg) ;
404f6b ¤   ¤   DispatchMessage (&msg) ;
d06fe7 ····}
50af5a
5cbf5f ····// Clean up
ccaf5a
f65e5a ····DdeUninitialize (idInst) ;
d8af5a
75f272 ¤   // Erase the juicy info
56584c ¤   while(ddlist!=0)
b8c7a1 ¤   {
f7c11b ¤   ¤   FreeAtLast=ddlist;
706f1d ¤   ¤   ddlist=ddlist->next;
f1af5a
9540cc ¤   ¤   memset(FreeAtLast->chunk,0x00,FreeAtLast->chunksize);
e4eaa5 ¤   ¤   free(FreeAtLast->chunk);
34af5a
c9b5fc ¤   ¤   memset(FreeAtLast,0x00,sizeof(DRAWDATA));
4f975d ¤   ¤   free(FreeAtLast);
299371 ¤   }
a7af5a
64baa3 ¤   UninitPGPsc(NULL,PGPsc,PGPtls);
3eaf5a
5c5570 ¤   return msg.wParam ;
9defe6 }
0daf5a
971ba1 HDDEDATA CALLBACK·
45fbf0 #ifndef WIN32·
5d52e7 _export·
147454 #endif
343fe8 DdeCallback (UINT iType, UINT iFmt, HCONV hConv,
64fb8d ·······························HSZ hsz1, HSZ hsz2, HDDEDATA hData,
2b9a83 ·······························DWORD dwData1, DWORD dwData2)
bc4157 { ·
a7af5a
537914 ¤   switch (iType)
5b3b37 ····{
21f1d3 ¤   ¤   case XTYP_CONNECT : ··········
125b34 ¤   ¤   {
69b6d6 ¤   ¤   ¤   char szBuffer[256];
7faf5a
e5a663 ¤   ¤   ¤   DdeQueryString (idInst, hsz2, szBuffer, sizeof (szBuffer), 0) ;
79af5a
971f46 ············if (0 != strcmp (szBuffer, DDElogServer))
c45012 ¤   ¤   ¤   ¤   return FALSE ;
8aaf5a
3a9363 ············DdeQueryString (idInst, hsz1, szBuffer, sizeof (szBuffer), 0) ;
10af5a
--7eb5 000c678f2dc401102cc Page 3 of main.c
49ee10 ············if (0 != strcmp (szBuffer, DDElogTopic))
dc5012 ¤   ¤   ¤   ¤   return FALSE ;
35af5a
7bcd7a ············return (HDDEDATA) TRUE ;
5c7fb0 ········}
071b52 ¤   ¤
97a5fe // From client since server will recieve instead
3b4d5d ¤   ¤   case XTYP_EXECUTE : ··
755b34 ¤   ¤   {
141d7c ¤   ¤   ¤   char szItem[1000];
f8fe5f ¤   ¤   ¤   int index;
a2d7d4 ¤   ¤   ¤   DRAWDATA *dd;
247ad2 ¤   ¤   ¤   char *myString;
4ee0d1 ¤   ¤   ¤   char *start,*end;
7baf5a
fcc094 ¤   ¤   ¤   DdeGetData(hData,szItem,500,0);
60af5a
442740 ¤   ¤   ¤   dd=(DRAWDATA *)malloc(sizeof(DRAWDATA));
3e75eb ¤   ¤   ¤   memset(dd,0x00,sizeof(DRAWDATA));
7baf5a
d09027 ¤   ¤   ¤   dd->next=ddlist; ·// Add to our linked list for cleanup
ee1e51 ¤   ¤   ¤   ddlist=dd;
1faf5a
331f36 ¤   ¤   ¤   dd->chunksize=strlen(szItem)+1;
28af5a
2e0c4a ¤   ¤   ¤   myString=(char *)malloc(dd->chunksize);
db3ffc ¤   ¤   ¤   strcpy(myString,szItem);
a1af5a
525b4e //¤ ¤   ¤   MessageBox(NULL,myString,"Information from client",MB_OK);
48af5a
2882da ¤   ¤   ¤   dd->chunk=myString;
7a472c ¤   ¤   ¤   dd->numcols=0;
e6af5a
0b9618 ¤   ¤   ¤   start=myString;
cdaf5a
4b103c ¤   ¤   ¤   end=strstr(myString,"\n");
4e6305 ¤   ¤   ¤   if(end!=0)
f68401 ¤   ¤   ¤   ¤   *end=0;
baaf5a
00aa58 ¤   ¤   ¤   if(strstr(start,"Signature"))
86f776 ¤   ¤   ¤   {
9b4112 ¤   ¤   ¤   ¤   if(!strcmp(start,"Good Signature"))
3d7777 ¤   ¤   ¤   ¤   ¤   dd->icon=IDX_CERT;
28fa07 ¤   ¤   ¤   ¤   else
aac984 ¤   ¤   ¤   ¤   ¤   dd->icon=IDX_REVCERT; // Using Rev instead of bad now
2eaf5a
cf1c7e ¤   ¤   ¤   ¤   start=end+1;
8faf5a
518f00 ¤   ¤   ¤   ¤   do
5b72c3 ¤   ¤   ¤   ¤   {
9b6f37 ¤   ¤   ¤   ¤   ¤   end=strstr(start,"\n");
7d95cc ¤   ¤   ¤   ¤   ¤   if(end!=0)
26df3a ¤   ¤   ¤   ¤   ¤   ¤   *end=0;
1aaf5a
4c2989 ¤   ¤   ¤   ¤   ¤   dd->type[dd->numcols]=PGP_DDTEXT;
b5cabd ¤   ¤   ¤   ¤   ¤   dd->data1[dd->numcols]=start;
dbaf5a
addc5f ¤   ¤   ¤   ¤   ¤   if(dd->numcols==2)
c44859 ¤   ¤   ¤   ¤   ¤   {
e0ec48 ¤   ¤   ¤   ¤   ¤   ¤   dd->type[dd->numcols]=PGP_DDBAR;
954c08 ¤   ¤   ¤   ¤   ¤   ¤   dd->data2[dd->numcols]=(void *)2;
38d78a ¤   ¤   ¤   ¤   ¤   ¤   if(!strcmp(start,"Invalid Key"))
004451 ¤   ¤   ¤   ¤   ¤   ¤   ¤   dd->data1[dd->numcols]=(void *)0;
bfd567 ¤   ¤   ¤   ¤   ¤   ¤   else if(!strcmp(start,"Marginal Key"))
571e8d ¤   ¤   ¤   ¤   ¤   ¤   ¤   dd->data1[dd->numcols]=(void *)1;
e046e9 ¤   ¤   ¤   ¤   ¤   ¤   else if(!strcmp(start,"Valid Key"))
f8f1e9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   dd->data1[dd->numcols]=(void *)2;
5f7f8b ¤   ¤   ¤   ¤   ¤   ¤   else
a7ab35 ¤   ¤   ¤   ¤   ¤   ¤   ¤   dd->data1[dd->numcols]=(void *)3;
0e1c89 ¤   ¤   ¤   ¤   ¤   }
d0af5a
c6fb73 ¤   ¤   ¤   ¤   ¤   dd->numcols++;
--c5ab 00010d56e70401102cc Page 4 of main.c
76a728 ¤   ¤   ¤   ¤   ¤   start=end+1;
5f2613 ¤   ¤   ¤   ¤   }
a18205 ¤   ¤   ¤   ¤   while(end!=0);
36af5a
0b0b23 ¤   ¤   ¤   ¤   index=AddAnItem(logList.hwndlist,dd);
f24c3f ¤   ¤   ¤   ¤   SetListCursor(logList.hwndlist,index);
39a3a6 ¤   ¤   ¤   }
4eaf5a
4a123c ············return (HDDEDATA) DDE_FACK ;
450fe4 ¤   ¤   }
049371 ¤   }
7bf193 ····return NULL ;
a4efe6 }
31cf72 ······
d4bea0 void SetReg(HKEY hKey,char *item,DWORD value)
66bb36 {
46f8f2 ¤   RegSetValueEx (¤hKey,·
9a793b ¤   ¤   item,·
c5e6e8 ¤   ¤   0,·
9b91e5 ¤   ¤   REG_DWORD,·
a78012 ¤   ¤   (LPBYTE)&value,·
8add35 ¤   ¤   sizeof(DWORD));
2aefe6 }
5eaf5a
d45893 void SavePosition(HWND hwnd)
6dbb36 {
1541d8 ¤   HKEY¤   hKey;
884d65 ¤   LONG¤   lResult;
dae36f ¤   DWORD¤  dw = 0;
ff28d8 ¤   RECT rect;
3caf5a
664543 ¤   GetWindowRect(hwnd, &rect);
6467c5 ¤
5b8e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
e60f50 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LOGREGPATH,·
054ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
9d2cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
4aa698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
d4af5a
39d84a ¤   if (lResult == ERROR_SUCCESS)·
a2c7a1 ¤   {
197fbe ¤   ¤   SetReg(hKey,"xPos",rect.left);
171475 ¤   ¤   SetReg(hKey,"yPos",rect.top);
ea5d00 ¤   ¤   SetReg(hKey,"xSize",rect.right-rect.left);
81ba3c ¤   ¤   SetReg(hKey,"ySize",rect.bottom-rect.top);
97af5a
258e60 ¤   ¤   RegCloseKey (hKey);
9c9371 ¤   }
ccaf5a
43efe6 }
65af5a
cc4eb6 DWORD GetReg(HKEY hKey,char *item)
e2bb36 {
822c0d ¤   DWORD value,type,size;
a4af5a
85e7ab ¤   value=0;
8009b7 ¤   type=0;
92e428 ¤   size=sizeof(DWORD);
81af5a
b9cf6d ¤   RegQueryValueEx(hKey,·
8b793b ¤   ¤   item,·
28e6e8 ¤   ¤   0,·
718a5d ¤   ¤   &type,·
da8012 ¤   ¤   (LPBYTE)&value,·
a15f8c ¤   ¤   &size);
7daf5a
815679 ¤   return value;
76efe6 }
9baf5a
b9b130 void RememberPosition(HWND hwnd,RECT *rc)
f5bb36 {
1041d8 ¤   HKEY¤   hKey;
--160f 0006d03d1af401102cc Page 5 of main.c
894d65 ¤   LONG¤   lResult;
bba9fa ¤   DWORD¤  x,y,dx,dy;
f3af5a
ee808d ¤   x=y=dx=dy=0;
b5af5a
b58e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
6c0f50 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LOGREGPATH,·
9d4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
702cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
7fa698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
f7af5a
9fd84a ¤   if (lResult == ERROR_SUCCESS)·
a7c7a1 ¤   {
5c2ad7 ¤   ¤   x=GetReg(hKey,"xPos");
5122a1 ¤   ¤   y=GetReg(hKey,"yPos");
caaf5a
e408fd ¤   ¤   dx=GetReg(hKey,"xSize");
901e44 ¤   ¤   dy=GetReg(hKey,"ySize");
57af5a
dd8e60 ¤   ¤   RegCloseKey (hKey);
a09371 ¤   }
0f0e24 ¤   else
40c7a1 ¤   {
e6c15b ¤   ¤   DWORD dw;
91af5a
5d9b9d ¤   ¤   lResult = RegCreateKeyEx (¤ HKEY_CURRENT_USER,·
685b75 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LOGREGPATH,·
65044d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
de4a56 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,
8d002b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   REG_OPTION_NON_VOLATILE,·
aa2d7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
f912b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
43f77a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey,·
705ba4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dw);
5caf5a
129371 ¤   }
6aaf5a
eec155 ¤   if((dx==0)||(dy==0)||
a5ef81 ¤   ¤   (x<0)||(y<0)||
947606 ¤   ¤   (x>(DWORD)GetSystemMetrics(SM_CXSCREEN))||
50d997 ¤   ¤   (y>(DWORD)GetSystemMetrics(SM_CYSCREEN)))
fac7a1 ¤   {
161afc ¤   ¤   dx=rc->right-rc->left;
a77208 ¤   ¤   dy=rc->bottom-rc->top;
6e1713 ¤   ¤   x=(GetSystemMetrics(SM_CXSCREEN)-(rc->right-rc->left))/2;
eca435 ¤   ¤   y=0;
3b9371 ¤   }
7caf5a
b61148 ¤   SetWindowPos (hwnd,NULL,x,y,dx,dy,SWP_NOZORDER);
e8efe6 }
23af5a
bb06d4 void QuitLog(void)
f9bb36 {
99db3a ¤   DdeNameService (idInst, hszService, NULL, DNS_UNREGISTER) ;
b8178c ····DdeFreeStringHandle (idInst, hszService) ;
f2d8ff ····DdeFreeStringHandle (idInst, hszTopic) ;
4168b0 ¤   DeleteDrawElements(&logDraw);
a6af5a
aa933b ····PostQuitMessage (0) ;
b7efe6 }
bacaf9 ············
bbebaa LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg,·
4bd454 ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam, LPARAM lParam)
1bbb36 {
cbaf5a
e39d6e ····switch (iMsg)
bd3b37 ····{
c754c9 ¤   ¤   case WM_CREATE:
c55b34 ¤   ¤   {
74afc0 ¤   ¤   ¤   RECT rc;
de2c5a ¤   ¤   ¤   LOGFONT lf;
6daf5a
--4221 000871fd361401102cc Page 6 of main.c
51240d ¤   ¤   ¤   InitCommonControls();
f026c8 ¤   ¤   ¤   ···
1898eb ············SystemParametersInfo (SPI_GETICONTITLELOGFONT,·
d7e7c2 ¤   ¤   ¤   ¤   sizeof(LOGFONT), &lf, 0);
bda67a ¤   ¤   ¤   hFont = CreateFontIndirect (&lf);
a0af5a
7e8217 ¤   ¤   ¤   CreateDrawElements(&logDraw);
8d3e31 ¤   ··
7f3c6f ¤   ¤   ····GetClientRect(hwnd,&rc);
24af5a
84d04b ¤   ¤   ¤   InitList(hwnd,&logList,ColText,ColRatio);
e9af5a
e8ded6 ¤   ¤   ¤   GetWindowRect (hwnd, &rc);
d9af5a
d52aa5 ¤   ¤   ¤   MoveList(&logList,rc.right,rc.bottom);
80af5a
d5c032 ¤   ¤   ¤   RememberPosition(hwnd,&rc);
f61b52 ¤   ¤
479e6a ¤   ¤   ¤   SetForegroundWindow(hwnd);
5932bd ¤   ¤   ¤   return TRUE;
ab0fe4 ¤   ¤   }
f9af5a
8d2267 ········case WM_DRAWITEM:·
b82b60 ········{
782848 ············Main_OnDrawItem(hwnd,(LPDRAWITEMSTRUCT) lParam);
b751a3 ············return TRUE;
517fb0 ········}
f4af5a
0f775f ········case WM_MEASUREITEM:
33daaa ············Main_OnMeasureItem(hwnd,(LPMEASUREITEMSTRUCT) lParam);
2751a3 ············return TRUE;
b9de7b ··
9d4e34 ¤   ¤   case WM_GETMINMAXINFO:
d45b34 ¤   ¤   {
bb8590 ¤   ¤   ¤   MINMAXINFO* lpmmi;
a1af5a
dab98a ¤   ¤   ····lpmmi = (MINMAXINFO*) lParam;
c14244 ····¤   ¤   lpmmi->ptMinTrackSize.x = 350;
564e10 ····¤   ¤   lpmmi->ptMinTrackSize.y = 120;
9d8632 ············break;
da0fe4 ¤   ¤   }
38af5a
fc9dfe ¤   ¤   case WM_CTLCOLOR:
a6c329 ¤   ¤   { ·········
aa1fa7 ·¤  ¤   ¤   if((wParam!=0)&&(HIWORD(lParam)!=CTLCOLOR_EDIT))
cb330a ¤   ¤   ¤   {·
2d2276 ¤   ¤   ¤   ¤   DWORD color;
25a03d ¤   ¤   ¤   ¤   color=GetSysColor(COLOR_BTNFACE);
772b85 ¤   ¤   ¤   ¤
b27c37 ¤   ¤   ¤   ··¤ SetBkColor ((HDC)wParam, color);
a42eb0 ¤   ¤   ¤   ··¤ SetTextColor ((HDC)wParam,·
a8449a ¤   ¤   ¤   ¤   ¤   GetSysColor(COLOR_WINDOWTEXT)); ·····
5137bc ¤   ¤   ¤   ··¤ return (BOOL)CreateSolidBrush (color);
f92efb ¤   ¤   ¤   } ¤ ·
1fcdcb ¤   ¤   ¤   break;
3f0fe4 ¤   ¤   }
25af5a
2e2526 ¤   ¤   case WM_SIZE:
975b34 ¤   ¤   {
5807da ¤   ¤   ¤   unsigned short Width, Height;
2ad850 ¤   ¤   ¤   Width = LOWORD(lParam); ·// width of client area·
b7d81f ¤   ¤   ¤   Height = HIWORD(lParam); // height of client area·
88af5a
509cd8 ¤   ¤   ¤   MoveList(&logList,Width,Height);
9fcdcb ¤   ¤   ¤   break;
3f0fe4 ¤   ¤   }
21af5a
882c97 ¤   ¤   case WM_CLOSE:
9ecfe6 ········case WM_DESTROY :
845b34 ¤   ¤   {
2ddd26 ¤   ¤   ¤   SavePosition(hwnd);
870af9 ¤   ¤   ¤   QuitLog();
--3c89 001f468ab44401102cc Page 7 of main.c
62092a ············return 0 ;
647fb0 ········}
379371 ¤   }
26af5a
7fe467 ¤   return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
c3efe6 }
74af5a
617e4d /*__Editor_settings____
51af5a
1a4126 ¤   Local Variables:
ae7b17 ¤   tab-width: 4
820e6c ¤   End:
b85f8c ¤   vi: ts=4 sw=4
189e9b ¤   vim: si
f4d062 _____________________*/
--e8a5 0015585c0c2401102cd Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
d45b31 // Used by PGPlog.rc
ae465d //
ea262c #define IDI_LOGICON ····················101
4e3e4a #define IDI_GOODSIG ····················102
f9fbdd #define IDI_BADSIG ·····················103
68610a #define IDB_IMAGES24BIT ················103
ef9413 #define IDI_PGPERROR ···················104
f8347d #define IDB_BITMAP1 ····················104
540580 #define IDB_IMAGES4BIT ·················104
4aaf5a
6c11aa // Next default values for new objects
5bac6a //·
29f860 #ifdef APSTUDIO_INVOKED
4a3f23 #ifndef APSTUDIO_READONLY_SYMBOLS
87d7cb #define _APS_NEXT_RESOURCE_VALUE ·······105
5c611c #define _APS_NEXT_COMMAND_VALUE ········40001
a0f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
a61285 #define _APS_NEXT_SYMED_VALUE ··········101
d67454 #endif
557454 #endif
--d371 000a82fcbab401102ce Page 1 of EnclyptorProc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
35be1f ¤   $Id: EnclyptorProc.c,v 1.35.2.2.2.1 1998/11/12 03:13:49 heller Exp $
40f7f7 ____________________________________________________________________________*/
9f5ed8 #include "precomp.h"
9faf5a
bb8b26 BOOL PopupTaskbarMenu(HWND hwndTarget, BOOL InPGPOperation);
770bc4 BOOL bUseCurrent=FALSE;
65c0e3 UINT nLaunchKeysTimer=0;
b12c4c BOOL PGPDiskExists=FALSE;
91af5a
afebfd #define REGPATH "Software\\Network Associates\\PGP60\\PGPtray"
97af5a
be5284 void RememberUseCurrent(BOOL bUseCurrent)
02bb36 {
0241d8 ¤   HKEY¤   hKey;
6a4d65 ¤   LONG¤   lResult;
46e36f ¤   DWORD¤  dw = 0;
8067c5 ¤
d32895 ¤   dw = bUseCurrent;
e4af5a
068e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
c19298 ¤   ¤   ¤   ¤   ¤   ¤   ¤   REGPATH,·
fa4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
6f2cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
dea698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
55af5a
e3d84a ¤   if (lResult == ERROR_SUCCESS)·
4cc7a1 ¤   {
f9ecda ¤   ¤   RegSetValueEx (¤hKey,·
e635a8 ¤   ¤   ¤   ¤   ¤   ¤   "UseCurrent",·
f0e7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
263bd6 ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
9e4d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
aafcfa ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
e7af5a
6a8e60 ¤   ¤   RegCloseKey (hKey);
f29371 ¤   }
72efe6 }
34af5a
5f4056 BOOL GetUseCurrent()
8fbb36 {
4f41d8 ¤   HKEY¤   hKey;
7d4d65 ¤   LONG¤   lResult;
e02c19 ¤   DWORD¤  dw;
c6af5a
e08e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
a19298 ¤   ¤   ¤   ¤   ¤   ¤   ¤   REGPATH,·
fe4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
3e2cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
aba698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
3eaf5a
dad84a ¤   if (lResult == ERROR_SUCCESS)·
44c7a1 ¤   {
c5fa9a ¤   ¤   DWORD ·size = sizeof(dw);
33fde9 ¤   ¤   DWORD ·type = 0;
1baf5a
b6db45 ¤   ¤   RegQueryValueEx(hKey,·
6a35a8 ¤   ¤   ¤   ¤   ¤   ¤   "UseCurrent",·
4ee7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
f03ce1 ¤   ¤   ¤   ¤   ¤   ¤   &type,·
e74d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
91e930 ¤   ¤   ¤   ¤   ¤   ¤   &size);
fb9371 ¤   }
438b92 ¤   else // Init Values
26c7a1 ¤   {
719b9d ¤   ¤   lResult = RegCreateKeyEx (¤ HKEY_CURRENT_USER,·
a897b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   REGPATH,·
--5be7 000bbc76be3401102ce Page 2 of EnclyptorProc.c
60044d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
7a4a56 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,
74002b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   REG_OPTION_NON_VOLATILE,·
402d7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
8712b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
b8f77a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey,·
9d5ba4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dw);
26af5a
9b99b9 ¤   ¤   if (lResult == ERROR_SUCCESS)·
315b34 ¤   ¤   {
da7e20 ¤   ¤   ¤   dw = 0;
87af5a
eb60a5 ¤   ¤   ¤   RegSetValueEx (¤hKey,·
c73be4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "UseCurrent",·
0a4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
78fe83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
df7173 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
dbf917 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
5caf5a
fb233e ¤   ¤   ¤   RegCloseKey (hKey);
530fe4 ¤   ¤   }
6e9371 ¤   }
8baf5a
fa7fc0 ¤   return (BOOL)dw;
97efe6 }
aaaf5a
7b14cd LRESULT CALLBACK EnclyptorProc(HWND hwnd, UINT msg,·
c2270e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam, LPARAM lParam)
4ebb36 {
2fd42f ¤   static char HelpFile[MAX_PATH + 1] = "\0";
381256 ¤   static BOOL InPGPOperation = FALSE;
e0da7a ¤   static HWND hwndFocus;
b567c5 ¤
b7a2d9 ¤   // See if user deselects caching via prefs
c7c9fd ¤   CheckForPurge(msg,wParam);
e9af5a
d39467 ¤   switch(msg)
ffc7a1 ¤   {
3654c9 ¤   ¤   case WM_CREATE:
955b34 ¤   ¤   {
861870 ¤   ¤   ¤   char szPGPDisk[MAX_PATH+1];
ad0954 ¤   ¤   ¤   FILE *fPGPDisk;
c0af5a
a6a149 ¤   ¤   ¤   bUseCurrent=GetUseCurrent();
e4af5a
249bf8 ¤   ¤   ¤   // See if we have to grey PGPDisk Menu Item
f3fe58 ¤   ¤   ¤   PGPDiskExists=FALSE;
067ea8 ¤   ¤   ¤   PGPpath(szPGPDisk);
c34513 ¤   ¤   ¤   strcat(szPGPDisk,"PGPdisk.exe");
51af5a
4763d9 ¤   ¤   ¤   fPGPDisk=fopen(szPGPDisk,"rb");
972b0f ¤   ¤   ¤   if(fPGPDisk!=NULL)
38f776 ¤   ¤   ¤   {
9fd4a5 ¤   ¤   ¤   ¤   PGPDiskExists=TRUE;
0fb072 ¤   ¤   ¤   ¤   fclose(fPGPDisk);
58a3a6 ¤   ¤   ¤   }
5aaf5a
bf23c8 ¤   ¤   ¤   StartUpdateTimer(hwnd, &nLaunchKeysTimer);
c68144 ¤   ¤   ¤   return 0;
9a0fe4 ¤   ¤   }
92af5a
6f51d8 ¤   ¤   case WM_QUERYOPEN:
a65b34 ¤   ¤   {
258144 ¤   ¤   ¤   return 0;
0d0fe4 ¤   ¤   }
4daf5a
147e29 ¤   ¤   case WM_TASKAREA_MESSAGE:
945b34 ¤   ¤   {
495c84 ¤   ¤   ¤   UINT uID = (UINT) wParam;
49b738 ¤   ¤   ¤   UINT uMouseMsg = (UINT) lParam;
7eaf5a
bb12ad ¤   ¤   ¤   if(uMouseMsg == WM_RBUTTONDOWN)
--2478 000425d80e0401102ce Page 3 of EnclyptorProc.c
99f776 ¤   ¤   ¤   {
f51de6 ¤   ¤   ¤   ¤   switch(uID)
a472c3 ¤   ¤   ¤   ¤   {
b9a3e1 ¤   ¤   ¤   ¤   ¤   case 1:
244859 ¤   ¤   ¤   ¤   ¤   {
0ac9c9 ¤   ¤   ¤   ¤   ¤   ¤   PopupTaskbarMenu(hwnd, InPGPOperation);
4ff8ad ¤   ¤   ¤   ¤   ¤   ¤   return 0;
6a1c89 ¤   ¤   ¤   ¤   ¤   }
162613 ¤   ¤   ¤   ¤   }
8fa3a6 ¤   ¤   ¤   }
53eb6e ¤   ¤   ¤   else if(uMouseMsg == WM_LBUTTONDOWN)
f4f776 ¤   ¤   ¤   {
211de6 ¤   ¤   ¤   ¤   switch(uID)
2f72c3 ¤   ¤   ¤   ¤   {
8da3e1 ¤   ¤   ¤   ¤   ¤   case 1:
764859 ¤   ¤   ¤   ¤   ¤   {
e4c9c9 ¤   ¤   ¤   ¤   ¤   ¤   PopupTaskbarMenu(hwnd, InPGPOperation);
baf8ad ¤   ¤   ¤   ¤   ¤   ¤   return 0;
371c89 ¤   ¤   ¤   ¤   ¤   }
532613 ¤   ¤   ¤   ¤   }
80a3a6 ¤   ¤   ¤   }
01cdcb ¤   ¤   ¤   break;
d90fe4 ¤   ¤   }
d7af5a
5d8e1e ¤   ¤   case WM_COMMAND:
2d5b34 ¤   ¤   {
c54afd ¤   ¤   ¤   switch(wParam)
adf776 ¤   ¤   ¤   {
e92a79 ¤   ¤   ¤   ¤   case ID_ENCRYPT:
f472c3 ¤   ¤   ¤   ¤   {
abde5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
0e7235 ¤   ¤   ¤   ¤   ¤   if(DoCopy(hwnd,PGPsc,bUseCurrent,&hwndFocus))
d04859 ¤   ¤   ¤   ¤   ¤   {
9e1266 ¤   ¤   ¤   ¤   ¤   ¤   EncryptClipboard(hwnd, PGPsc, PGPtls, TRUE, FALSE);
6857c8 ¤   ¤   ¤   ¤   ¤   ¤   DoPaste(bUseCurrent,hwndFocus);
301c89 ¤   ¤   ¤   ¤   ¤   }
f8b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
dd14c3 ¤   ¤   ¤   ¤   ¤   break;
6c2613 ¤   ¤   ¤   ¤   }
eeaf5a
35820d ¤   ¤   ¤   ¤   case ID_SIGN:
d172c3 ¤   ¤   ¤   ¤   {
76de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
1b7235 ¤   ¤   ¤   ¤   ¤   if(DoCopy(hwnd,PGPsc,bUseCurrent,&hwndFocus))
2c4859 ¤   ¤   ¤   ¤   ¤   {
10f58f ¤   ¤   ¤   ¤   ¤   ¤   EncryptClipboard(hwnd, PGPsc,PGPtls, FALSE, TRUE);
6357c8 ¤   ¤   ¤   ¤   ¤   ¤   DoPaste(bUseCurrent,hwndFocus);
561c89 ¤   ¤   ¤   ¤   ¤   }
9eb8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
7714c3 ¤   ¤   ¤   ¤   ¤   break;
be2613 ¤   ¤   ¤   ¤   }
f6af5a
b11e38 ¤   ¤   ¤   ¤   case ID_ENCRYPTSIGN:
1872c3 ¤   ¤   ¤   ¤   {
bbde5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
f37235 ¤   ¤   ¤   ¤   ¤   if(DoCopy(hwnd,PGPsc,bUseCurrent,&hwndFocus))
de4859 ¤   ¤   ¤   ¤   ¤   {
83daed ¤   ¤   ¤   ¤   ¤   ¤   EncryptClipboard(hwnd, PGPsc,PGPtls, TRUE, TRUE);
bf57c8 ¤   ¤   ¤   ¤   ¤   ¤   DoPaste(bUseCurrent,hwndFocus);
ee1c89 ¤   ¤   ¤   ¤   ¤   }
97b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
1414c3 ¤   ¤   ¤   ¤   ¤   break;
522613 ¤   ¤   ¤   ¤   }
b9af5a
7fa084 ¤   ¤   ¤   ¤   case ID_DECRYPTVERIFY:
0772c3 ¤   ¤   ¤   ¤   {
19de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
637235 ¤   ¤   ¤   ¤   ¤   if(DoCopy(hwnd,PGPsc,bUseCurrent,&hwndFocus))
3a4859 ¤   ¤   ¤   ¤   ¤   {
901426 ¤   ¤   ¤   ¤   ¤   ¤   DecryptClipboard(hwnd, PGPsc,PGPtls);
2fa4e1 ¤   ¤   ¤   ¤   ¤   ¤   DoFocus(bUseCurrent,hwndFocus);
421c89 ¤   ¤   ¤   ¤   ¤   }
--93bd 00089017a4c401102ce Page 4 of EnclyptorProc.c
17b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
cb14c3 ¤   ¤   ¤   ¤   ¤   break;
382613 ¤   ¤   ¤   ¤   }
51af5a
e62b85 ¤   ¤   ¤   ¤
a123a0 ¤   ¤   ¤   ¤   case ID_ADDKEY:
d272c3 ¤   ¤   ¤   ¤   {
62de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
a57235 ¤   ¤   ¤   ¤   ¤   if(DoCopy(hwnd,PGPsc,bUseCurrent,&hwndFocus))
fa4859 ¤   ¤   ¤   ¤   ¤   {
8131ef ¤   ¤   ¤   ¤   ¤   ¤   AddKeyClipboard(hwnd, PGPsc,PGPtls);
fca4e1 ¤   ¤   ¤   ¤   ¤   ¤   DoFocus(bUseCurrent,hwndFocus);
331c89 ¤   ¤   ¤   ¤   ¤   }
e4b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
c914c3 ¤   ¤   ¤   ¤   ¤   break;
ae2613 ¤   ¤   ¤   ¤   }
80af5a
fba1c4 ¤   ¤   ¤   ¤   case ID_WIPECLIP:
6472c3 ¤   ¤   ¤   ¤   {
91de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
a7f8a2 ¤   ¤   ¤   ¤   ¤   ClipboardWipe(hwnd,PGPsc);
28b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
9614c3 ¤   ¤   ¤   ¤   ¤   break;
7e2613 ¤   ¤   ¤   ¤   }
222b85 ¤   ¤   ¤   ¤
35b00e ¤   ¤   ¤   ¤   case ID_VIEWCLIPBOARD:
a972c3 ¤   ¤   ¤   ¤   {
87de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
c1e9d9 ¤   ¤   ¤   ¤   ¤   LaunchInternalViewer(hwnd);
05b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
f314c3 ¤   ¤   ¤   ¤   ¤   break;
7f2613 ¤   ¤   ¤   ¤   }
11af5a
b140b0 ¤   ¤   ¤   ¤   case ID_USECURRENT:
3172c3 ¤   ¤   ¤   ¤   {
e07d88 ¤   ¤   ¤   ¤   ¤   bUseCurrent = !bUseCurrent;
324050 ¤   ¤   ¤   ¤   ¤   RememberUseCurrent(bUseCurrent);
b014c3 ¤   ¤   ¤   ¤   ¤   break;
2f2613 ¤   ¤   ¤   ¤   }
07ae30 ¤   ¤   ¤   ¤   ¤
64301c ¤   ¤   ¤   ¤   case ID_LAUNCHPGPKEYS:
a172c3 ¤   ¤   ¤   ¤   {
31de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
6b7411 ¤   ¤   ¤   ¤   ¤   DoLaunchKeys(hwnd);
d8b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
8314c3 ¤   ¤   ¤   ¤   ¤   break;
522613 ¤   ¤   ¤   ¤   }
bdaf5a
7321c5 ¤   ¤   ¤   ¤   case ID_LAUNCHPGPTOOLS:
3972c3 ¤   ¤   ¤   ¤   {
4fde5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
4562c4 ¤   ¤   ¤   ¤   ¤   DoLaunchTools(hwnd);
93b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
6f14c3 ¤   ¤   ¤   ¤   ¤   break;
8a2613 ¤   ¤   ¤   ¤   }
51af5a
b6e55c ¤   ¤   ¤   ¤   case ID_LAUNCHPGPDISK:
b472c3 ¤   ¤   ¤   ¤   {
d5de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
80afa3 ¤   ¤   ¤   ¤   ¤   DoLaunchDisk(hwnd);
85b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
ae14c3 ¤   ¤   ¤   ¤   ¤   break;
a62613 ¤   ¤   ¤   ¤   }
cfaf5a
96f554 ¤   ¤   ¤   ¤   case ID_PROPERTIES:
1772c3 ¤   ¤   ¤   ¤   {
14de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
17246b ¤   ¤   ¤   ¤   ¤   PGPscPreferences(hwnd, PGPsc,PGPtls);
45b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
7a14c3 ¤   ¤   ¤   ¤   ¤   break;
d22613 ¤   ¤   ¤   ¤   }
89af5a
--3c70 00031aec3c8401102ce Page 5 of EnclyptorProc.c
be36f8 ¤   ¤   ¤   ¤   case ID_QUIT_ENCLYPTOR:
9c72c3 ¤   ¤   ¤   ¤   {
774050 ¤   ¤   ¤   ¤   ¤   RememberUseCurrent(bUseCurrent);
9401be ¤   ¤   ¤   ¤   ¤   SetForegroundWindow(hwnd);
30330b ¤   ¤   ¤   ¤   ¤   PostMessage(hwnd, WM_CLOSE, 0, 0);
2d14c3 ¤   ¤   ¤   ¤   ¤   break;
ec2613 ¤   ¤   ¤   ¤   }
5baf5a
439cb8 ¤   ¤   ¤   ¤   case ID_HELP_TOPICS:
1472c3 ¤   ¤   ¤   ¤   {
26de5d ¤   ¤   ¤   ¤   ¤   InPGPOperation = TRUE;
3edb46 ¤   ¤   ¤   ¤   ¤   PGPpath(HelpFile);
cc0cef ¤   ¤   ¤   ¤   ¤   strcat(HelpFile,"PGP60.hlp");
4fca2d ¤   ¤   ¤   ¤   ¤   WinHelp(hwnd, HelpFile, HELP_FINDER, 0);
17b8fd ¤   ¤   ¤   ¤   ¤   InPGPOperation = FALSE;
8014c3 ¤   ¤   ¤   ¤   ¤   break;
132613 ¤   ¤   ¤   ¤   }
eeda4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
47a3a6 ¤   ¤   ¤   }
12cdcb ¤   ¤   ¤   break;
670fe4 ¤   ¤   }
0c1b52 ¤   ¤
9f8ee0 ¤   ¤   case WM_ENDSESSION :
055b34 ¤   ¤   {
51cdcb ¤   ¤   ¤   break;
0b0fe4 ¤   ¤   }
d5af5a
052c97 ¤   ¤   case WM_CLOSE:
48ed49 ¤   ¤   {¤
7c0675 ¤   ¤   ¤   KillTimer(hwnd, nLaunchKeysTimer);
b0a500 ¤   ¤   ¤   PostQuitMessage(0);¤
308144 ¤   ¤   ¤   return 0;
580fe4 ¤   ¤   }
3a9371 ¤   }
2d4c1c ¤   return DefWindowProc(hwnd, msg, wParam, lParam);
c0efe6 }
caaf5a
a1af5a
ea767f BOOL PopupTaskbarMenu(HWND hwndTarget, BOOL InPGPOperation)
fabb36 {
ac8d83 ¤   HMENU hMenu = NULL;
770eff ¤   HMENU hSubMenu = NULL;
74a305 ¤   POINT pt;
1f00a4 ¤   UINT flags;
21af5a
c8e400 ¤   GetCursorPos( &pt );
c2af5a
52f7bc ¤   // If the cursor is at the top, we need to reverse the menu
2bd86f ¤   if(pt.y<400)
1941f1 ¤   ¤   hMenu = LoadMenu(g_hinst, MAKEINTRESOURCE(IDM_TASKBARMENUREV));
f40e24 ¤   else
acbf65 ¤   ¤   hMenu = LoadMenu(g_hinst, MAKEINTRESOURCE(IDM_TASKBARMENU));
76af5a
b1dbbe ¤   flags = (bUseCurrent ?¤ MF_BYCOMMAND|MF_CHECKED :·
88ab3c ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_UNCHECKED);
31af5a
32758f ¤   CheckMenuItem(hMenu, ID_USECURRENT, flags);
36af5a
5ccaca ¤   // PGPdisk only in biz and pp versions
54aff8 #if !(PGP_BUSINESS_SECURITY || PGP_PERSONAL_PRIVACY)
0ddc76 ¤   ¤   EnableMenuItem(hMenu,·
139e27 ¤   ¤   ¤   ¤   ¤   ···ID_LAUNCHPGPDISK,·
b9b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
527454 #endif
89af5a
3d7522 ¤   // Its not installed anyway so forget it...
423799 ¤   if (!PGPDiskExists)
59dc76 ¤   ¤   EnableMenuItem(hMenu,·
359e27 ¤   ¤   ¤   ¤   ¤   ···ID_LAUNCHPGPDISK,·
70b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
3eaf5a
3118e0 ¤   if(InPGPOperation)
--fe97 001d8500a1a401102ce Page 6 of EnclyptorProc.c
f7c7a1 ¤   {
f9dc76 ¤   ¤   EnableMenuItem(hMenu,·
32cea2 ¤   ¤   ¤   ¤   ¤   ···ID_ENCRYPT,·
38b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
ccdc76 ¤   ¤   EnableMenuItem(hMenu,·
30c037 ¤   ¤   ¤   ¤   ¤   ···ID_SIGN,·
92b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
4ddc76 ¤   ¤   EnableMenuItem(hMenu,·
c90b74 ¤   ¤   ¤   ¤   ¤   ···ID_ENCRYPTSIGN,·
b9b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
50dc76 ¤   ¤   EnableMenuItem(hMenu,·
49c4a7 ¤   ¤   ¤   ¤   ¤   ···ID_DECRYPTVERIFY,·
2fb36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
ecdc76 ¤   ¤   EnableMenuItem(hMenu,·
a0b83d ¤   ¤   ¤   ¤   ¤   ···ID_ADDKEY,·
4bb36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
63dc76 ¤   ¤   EnableMenuItem(hMenu,·
d3fff2 ¤   ¤   ¤   ¤   ¤   ···ID_PROPERTIES,·
d6b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
83dc76 ¤   ¤   EnableMenuItem(hMenu,·
80efe5 ¤   ¤   ¤   ¤   ¤   ···ID_VIEWCLIPBOARD,·
e7b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
4edc76 ¤   ¤   EnableMenuItem(hMenu,·
2b5e6d ¤   ¤   ¤   ¤   ¤   ···ID_USECURRENT,·
4fb36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
bedc76 ¤   ¤   EnableMenuItem(hMenu,·
1a8ffe ¤   ¤   ¤   ¤   ¤   ···ID_HELP_TOPICS,·
dab36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
bedc76 ¤   ¤   EnableMenuItem(hMenu,·
36dcf6 ¤   ¤   ¤   ¤   ¤   ···ID_LAUNCHPGPKEYS,·
81b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
f0dc76 ¤   ¤   EnableMenuItem(hMenu,·
759e27 ¤   ¤   ¤   ¤   ¤   ···ID_LAUNCHPGPDISK,·
22b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
40dc76 ¤   ¤   EnableMenuItem(hMenu,·
cad9ad ¤   ¤   ¤   ¤   ¤   ···ID_WIPECLIP,·
54b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
eedc76 ¤   ¤   EnableMenuItem(hMenu,·
e27821 ¤   ¤   ¤   ¤   ¤   ···ID_LAUNCHPGPTOOLS,·
13b36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
53dc76 ¤   ¤   EnableMenuItem(hMenu,·
519250 ¤   ¤   ¤   ¤   ¤   ···ID_QUIT_ENCLYPTOR,·
3fb36f ¤   ¤   ¤   ¤   ¤   ···MF_BYCOMMAND | MF_GRAYED);
009371 ¤   }
6aaf5a
d55a95 ¤   hSubMenu = GetSubMenu(hMenu,0);
b7af5a
4a6321 ·····// ·Calls to SetForegroundWindow and PostMessage to fix a bug
51c032 ·····// ·documented in PSS ID Number: Q135788
ac7d09 ¤   SetForegroundWindow(hwndTarget);·
5224f7 ¤   TrackPopupMenu( hSubMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,·
964039 ¤   ¤   ¤   ¤   ¤   pt.x, pt.y, 0, hwndTarget, NULL);
b4c89c ¤   PostMessage( hwndTarget, WM_NULL, 0, 0 ) ;
28516b // Above fixes "three clicks" problem ·-wjb
86af5a
404d1c ¤   DestroyMenu(hMenu);
73af5a
bbc2e7 ¤   return TRUE;
07efe6 }
e6af5a
1f7e4d /*__Editor_settings____
15af5a
1d4126 ¤   Local Variables:
997b17 ¤   tab-width: 4
240e6c ¤   End:
f15f8c ¤   vi: ts=4 sw=4
2d9e9b ¤   vim: si
d8d062 _____________________*/
--191e 001d867533a401102cf Page 1 of EnclyptorProc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
c6d7d9 ¤   $Id: EnclyptorProc.h,v 1.4.16.1 1998/11/12 03:13:49 heller Exp $
6bf7f7 ____________________________________________________________________________*/
56ee59 #ifndef Included_ENCLYPTORPROC_h¤   /* [ */
8e0f26 #define Included_ENCLYPTORPROC_h
90af5a
8614cd LRESULT CALLBACK EnclyptorProc(HWND hwnd, UINT msg,·
0be979 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam, LPARAM lParam);
b5af5a
970b8d #endif /* ] Included_ENCLYPTORPROC_h */
19af5a
12af5a
0c7e4d /*__Editor_settings____
06af5a
7e4126 ¤   Local Variables:
837b17 ¤   tab-width: 4
f10e6c ¤   End:
da5f8c ¤   vi: ts=4 sw=4
6b9e9b ¤   vim: si
d8d062 _____________________*/
--8b35 000d1ee42d8401102d0 Page 1 of Main.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
a5b9d5 ¤   $Id: Main.c,v 1.17.2.1.2.1 1998/11/12 03:13:50 heller Exp $
8ef7f7 ____________________________________________________________________________*/
4b5ed8 #include "precomp.h"
dda855 #include "..\include\PGPhk.h"
ceaf5a
73badc static char szAppName[]="PGPtray_Hidden_Window";
a6af5a
0ea925 HWND TrayWindow(void)
f3bb36 {
9455cf ¤   HWND hwnd;
c4d663 ¤   WNDCLASS wc;
44af5a
5dc22e ¤   // Register the Server Window Class
feaf5a
b57783 ¤   wc.style¤   ¤   ¤   = 0;
6d2f68 ¤   wc.lpfnWndProc¤ ¤   = EnclyptorProc;
112ff0 ¤   wc.cbClsExtra¤  ¤   = 0;
e4f5bd ¤   wc.cbWndExtra¤  ¤   = 0;
9a5f64 ¤   wc.hInstance¤   ¤   = g_hinst;
8c6b61 ¤   wc.hIcon¤   ¤   ¤   = 0;
ea1af3 ¤   wc.hCursor¤ ¤   ¤   = 0;
4ffdb7 ¤   wc.hbrBackground¤   = 0;
464d10 ¤   wc.lpszMenuName¤¤   = 0;
31b42e ¤   wc.lpszClassName¤   = szAppName;
9aaf5a
2bfd79 ¤   RegisterClass(&wc);
0faf5a
fad059 ¤   hwnd = CreateWindow(
db9ff8 ¤   ¤   szAppName, szAppName, WS_OVERLAPPEDWINDOW,·
956ebc ¤   ¤   CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
7fe4a5 ¤   ¤   CW_USEDEFAULT, NULL, NULL, g_hinst, NULL );
65af5a
6363cc ¤   ShowWindow(hwnd, SW_HIDE);
2066e6 ¤   UpdateWindow(hwnd);
96af5a
87a706 ¤   return hwnd;
8cefe6 }
ecaf5a
4c0711 int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hinstPrev,·
1d0bf2 ¤   ¤   ¤   ¤   ¤   LPSTR lpszCmdLine, int nCmdShow)
dfbb36 {
d955cf ¤   HWND hwnd;
fd0cf8 ¤   MSG msg;
e9af5a
3fc48a ¤   g_hinst = hInstance;
93af5a
969270 ¤   if(*lpszCmdLine)
fdc7a1 ¤   {
acbb8b ¤   ¤   FILELIST *ListHead;
65af5a
82d050 ¤   ¤   if(!InitPGPsc(NULL,&PGPsc,&PGPtls))
3232bd ¤   ¤   ¤   return TRUE;
beaf5a
abc533 ¤   ¤   hwnd=TrayWindow();
c9af5a
696b92 ¤   ¤   ListHead=CmdLineToFileList(lpszCmdLine);
29af5a
839610 ¤   ¤   DecryptFileList(hwnd, PGPsc,PGPtls, ListHead);
fdaf5a
86c4b0 ¤   ¤   UninitPGPsc(hwnd,PGPsc,PGPtls);
a0af5a
0dbbde ¤   ¤   return 0;
449371 ¤   }
f1af5a
31c85c ¤   if(FindWindow(szAppName,szAppName))·
d1c7a1 ¤   {
--f14c 00148981fd6401102d0 Page 2 of Main.c
605565 ¤   ¤   return(0);
e99371 ¤   }
2aaf5a
565836 ¤   if(!InitPGPsc(NULL,&PGPsc,&PGPtls))
3632bd ¤   ¤   ¤   return TRUE;
d1af5a
23dd86 ¤   hwndTray=TrayWindow();
9baf5a
91bc9f ¤   hIconKey = LoadIcon(g_hinst,·
287ce6 ¤   ¤   ¤   MAKEINTRESOURCE(IDI_TASKBAR));
a0d9eb ¤   TaskbarAddIcon(hwndTray,1, hIconKey, "PGPtray",·
418e9a ¤   ¤   ¤   WM_TASKAREA_MESSAGE);
5baf5a
6d4222 ¤   SetHook(); // Our CBT hook for current focus
5faf5a
dc0afa ¤   while( GetMessage( &msg, NULL, 0, 0 ) ) ···········
ccc7a1 ¤   {
baeeb0 ¤   ¤   if( IsDialogMessage( hwndTray, &msg ) ) ····
b26e61 ¤   ¤   ¤   ¤   ¤   // ·Process Tab messages and such
6017f5 ¤   ¤   ¤   continue;
6eaf5a
37317a ¤   ¤   TranslateMessage( &msg ); ·····················
fb3cf5 ¤   ¤   DispatchMessage( &msg );
739371 ¤   }
3caf5a
2c9719 ¤   DeleteHook(); // Our CBT hook for current focus
53af5a
8a743e ¤   TaskbarDeleteIcon(hwndTray, 1);
d9af5a
59baa3 ¤   UninitPGPsc(NULL,PGPsc,PGPtls);
80af5a
fac7a1 ¤   {
00ab5b ¤   ¤   HWND test;
22af5a
632912 ¤   ¤   test=ReadCurrentFocus();
369371 ¤   }
98af5a
583e6b ¤   return 0;
8fefe6 }
cdaf5a
e77e4d /*__Editor_settings____
59af5a
734126 ¤   Local Variables:
bb7b17 ¤   tab-width: 4
7d0e6c ¤   End:
f15f8c ¤   vi: ts=4 sw=4
779e9b ¤   vim: si
48d062 _____________________*/
--ecf9 0010302a4a6401102d1 Page 1 of PGPTrayVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
d52042 ·FILETYPE VFT_APP
817247 ·FILESUBTYPE VFT2_UNKNOWN
f44523 BEGIN
752c72 ····BLOCK "StringFileInfo"
095574 ····BEGIN
fe70ac ········BLOCK "040904b0"
2752d6 ········BEGIN
e980b6 ············VALUE "CompanyName", PGPCOMPANYNAME
a8cbf7 ············VALUE "FileDescription", "PGP System Tray Application\0"
aac1dd ············VALUE "FileVersion", PGPVERSIONSTRING
1385e8 ············VALUE "InternalName", "PGPtray\0"
848ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
dc2bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
46a9cd ············VALUE "OriginalFilename", "PGPtray.exe\0"
d29317 ············VALUE "ProductName", PGPPRODUCTNAME
f8d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
a8f37f ········END
197d01 ····END
e526ab ····BLOCK "VarFileInfo"
695574 ····BEGIN
1b4b11 ········VALUE "Translation", 0x409, 1200
a47d01 ····END
4de0d1 END
b4af5a
03af5a
--442b 0007ead5d94401102d2 Page 1 of PGPtray.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
19f860 #ifdef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
66465d //
df5733 // TEXTINCLUDE
a2465d //
99af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
2d4523 BEGIN
70541e ····"resource.h\0"
48e0d1 END
85af5a
467037 2 TEXTINCLUDE DISCARDABLE·
044523 BEGIN
c3eb23 ····"#include ""afxres.h""\r\n"
98db5c ····"\0"
97e0d1 END
5aaf5a
ea227f 3 TEXTINCLUDE DISCARDABLE·
024523 BEGIN
c8bb53 ····"#include ""pgptrayver.rc""\r\n"
3cdb5c ····"\0"
03e0d1 END
8baf5a
d069ab #endif ···// APSTUDIO_INVOKED
faaf5a
4faf5a
716c0e /////////////////////////////////////////////////////////////////////////////
69465d //
6386c0 // Menu
4d465d //
beaf5a
07c939 IDM_TASKBARMENUREV MENU DISCARDABLE·
c84523 BEGIN
8c3c7d ····POPUP "PGPtray"
a65574 ····BEGIN
1da7db ········MENUITEM "&Encrypt Clipboard", ·········ID_ENCRYPT
f5ea75 ········MENUITEM "&Sign Clipboard", ············ID_SIGN
37923b ········MENUITEM "E&ncrypt && Sign Clipboard", ·ID_ENCRYPTSIGN
3f5d64 ········MENUITEM "&Decrypt && Verify Clipboard", ID_DECRYPTVERIFY
4c22a0 ········MENUITEM "Add &Key from Clipboard", ····ID_ADDKEY
84592d ········MENUITEM SEPARATOR
6a65b9 ········MENUITEM "Edit Clipboard &Text", ·······ID_VIEWCLIPBOARD
6ad461 ········MENUITEM "E&mpty Clipboard", ···········ID_WIPECLIP
a50425 ········MENUITEM "&Use Current Window", ········ID_USECURRENT
19592d ········MENUITEM SEPARATOR
f391ab ········MENUITEM "Launch PGPt&ools", ···········ID_LAUNCHPGPTOOLS
ff654c ········MENUITEM "&Launch PGPkeys", ············ID_LAUNCHPGPKEYS
35c994 ········MENUITEM "Launch PGPd&isk", ············ID_LAUNCHPGPDISK
7ea1e7 ········MENUITEM "PGP P&references", ···········ID_PROPERTIES
--9e50 001dd455a43401102d2 Page 2 of PGPtray.rc
21d62c ········MENUITEM "&Help...", ···················ID_HELP_TOPICS
00592d ········MENUITEM SEPARATOR
9d0498 ········MENUITEM "E&xit PGPtray", ··············ID_QUIT_ENCLYPTOR
c97d01 ····END
3ee0d1 END
3faf5a
929ec7 IDM_TASKBARMENU MENU DISCARDABLE·
b14523 BEGIN
033c7d ····POPUP "PGPtray"
e45574 ····BEGIN
110498 ········MENUITEM "E&xit PGPtray", ··············ID_QUIT_ENCLYPTOR
c5592d ········MENUITEM SEPARATOR
72d62c ········MENUITEM "&Help...", ···················ID_HELP_TOPICS
07a1e7 ········MENUITEM "PGP P&references", ···········ID_PROPERTIES
61c994 ········MENUITEM "Launch PGPd&isk", ············ID_LAUNCHPGPDISK
a2654c ········MENUITEM "&Launch PGPkeys", ············ID_LAUNCHPGPKEYS
e991ab ········MENUITEM "Launch PGPt&ools", ···········ID_LAUNCHPGPTOOLS
f3592d ········MENUITEM SEPARATOR
d60425 ········MENUITEM "&Use Current Window", ········ID_USECURRENT
ffd461 ········MENUITEM "E&mpty Clipboard", ···········ID_WIPECLIP
5565b9 ········MENUITEM "Edit Clipboard &Text", ·······ID_VIEWCLIPBOARD
d3592d ········MENUITEM SEPARATOR
5f22a0 ········MENUITEM "Add &Key from Clipboard", ····ID_ADDKEY
315d64 ········MENUITEM "&Decrypt && Verify Clipboard", ID_DECRYPTVERIFY
db923b ········MENUITEM "E&ncrypt && Sign Clipboard", ·ID_ENCRYPTSIGN
65ea75 ········MENUITEM "&Sign Clipboard", ············ID_SIGN
e0a7db ········MENUITEM "&Encrypt Clipboard", ·········ID_ENCRYPT
c07d01 ····END
8fe0d1 END
e5af5a
b6af5a
d76c0e /////////////////////////////////////////////////////////////////////////////
6f465d //
22cbaf // Icon
dc465d //
29af5a
422951 // Icon with lowest ID value placed first to ensure application icon
2a0f06 // remains consistent on all systems.
90a315 IDI_TASKBAR ············ICON ···DISCARDABLE ····"res\\taskbar.ico"
431b3a #endif ···// English (U.S.) resources
6f6c0e /////////////////////////////////////////////////////////////////////////////
8aaf5a
94af5a
c0af5a
f8ce8c #ifndef APSTUDIO_INVOKED
9e6c0e /////////////////////////////////////////////////////////////////////////////
99465d //
bb8464 // Generated from the TEXTINCLUDE 3 resource.
c1465d //
f220a5 #include "pgptrayver.rc"
62af5a
eb6c0e /////////////////////////////////////////////////////////////////////////////
488072 #endif ···// not APSTUDIO_INVOKED
ddaf5a
--304a 000b8e296c8401102d3 Page 1 of Precomp.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
09a3d8 ¤   $Id: Precomp.h,v 1.9.8.1 1998/11/12 03:13:51 heller Exp $
d4f7f7 ____________________________________________________________________________*/
63519a #ifndef Included_PRECOMP_h¤ /* [ */
315498 #define Included_PRECOMP_h
b7af5a
a41bcc /*++
83af5a
7a4678 Module Name:
5daf5a
953fd4 ····precomp.h
2faf5a
0e57d7 Abstract:
60af5a
45cab2 ····This file includes all the headers required to build the dll
3b3a9d ····to ease the process of building a precompiled header.
83af5a
b1d16a Author:
62af5a
66af5a
5e8999 Revision History:
b5af5a
9caf5a
8667d9 --*/
5faf5a
6b2a68 #define WIN32_LEAN_AND_MEAN
35f451 #define PGPExport __declspec( dllimport )
a6af5a
452de6 // System headers
565655 #include <windows.h>
5c3d0b #include <windowsx.h>
2ebea3 #include <stdlib.h>
85feb2 #include <stdio.h>
84bea3 #include <stdlib.h>
1b8f85 #include <assert.h>·
c5324c #include <string.h>
287609 #include <ShellAPI.h>
2eaf5a
a8fee6 #define UNFINISHED_CODE_ALLOWED 1
41af5a
888cbe // PGPlib headers
f09de0 #include "..\include\PGPsc.h"
10fca7 #include "..\..\shared\pgpBuildFlags.h"
beaf5a
1e9e94 // PGPtray headers
f9af5a
af9776 #include "enclyptorproc.h"
938031 #include "resource.h"
26d9b2 #include "taskbar.h"
a3af5a
d422ee HINSTANCE g_hinst;
ace027 HICON hIconKey;
5440ff HWND hwndTray;
33af5a
a7f8cb void *PGPsc;
e03a96 void *PGPtls;
6eaf5a
b93f49 #define WM_TASKAREA_MESSAGE¤¤   WM_USER + 1
36af5a
6441ed #endif /* ] Included_PRECOMP_h */
a6af5a
9eaf5a
f97e4d /*__Editor_settings____
dcaf5a
144126 ¤   Local Variables:
217b17 ¤   tab-width: 4
b80e6c ¤   End:
--2cb3 0015de63703401102d3 Page 2 of Precomp.h
e65f8c ¤   vi: ts=4 sw=4
949e9b ¤   vim: si
8ed062 _____________________*/
5daf5a
--2e1f 0009c1d92b0401102d4 Page 1 of RESOURCE.H
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
ba102b // Used by PGPtray.rc
f7465d //
8f73fc #define IDM_TASKBARMENU ················101
7a6f97 #define IDM_TASKBARMENUREV ·············102
1c7680 #define IDD_CLIPBOARDVIEWER ············104
62364d #define IDI_TASKBAR ····················105
187779 #define IDB_BITMAP1 ····················115
466576 #define IDI_TED ························116
924ecb #define IDM_TEDBARMENU ·················117
c998e0 #define IDB_BITMAP2 ····················118
f91e1a #define WAV_TED1 ·······················120
092ee8 #define WAV_TED2 ·······················122
08ce01 #define WAV_TED3 ·······················123
161779 #define IDD_RESULTS ····················124
c24324 #define IDD_LAUNCH_VIEWER ··············125
81a30c #define IDB_BITMAP3 ····················129
5d7ec0 #define IDD_RESULTS_SMALL ··············131
f2fc40 #define IDR_MENU1 ······················132
0954c7 #define IDD_PASSPHRASE ·················1001
9bfe71 #define IDC_EDIT1 ······················1001
1ea32a #define IDC_PHRASE ·····················1002
0e4351 #define IDC_EXTERNAL_VIEWER ············1002
2bfd6b #define IDC_HIDETYPING ·················1003
b4b55d #define ID_VIEW_EXTERNAL ···············1003
1de9a7 #define IDVIEW_EXTERNAL ················1003
052942 #define IDC_PROMPTSTRING ···············1004
bbc017 #define ID_VIEW_INTERNAL ···············1004
24c581 #define IDVIEW_INTERNAL ················1004
c3ea43 #define IDC_DECRYPTION_RESULTS ·········1005
2b64aa #define ID_BROWSE ······················1006
bc2d43 #define IDBROWSE ·······················1006
1254d1 #define IDUNDO ·························1007
1413af #define IDS_SIGNATURE_ERROR ············5000
fc8c61 #define IDS_OUT_OF_MEMORY ··············5001
0eab84 #define IDS_FUNCTION_NOT_ENABLED ·······5002
de7e2e #define IDS_CANNOT_SIGN_WITH_UNCERTIFIED_KEY 5003
cab40a #define IDS_CANNOT_DECRYPT_WITH_UNCERTIFIED_KEY 5004
4d2f90 #define IDS_CANNOT_ENCRYPT_WITH_UNCERTIFIED_KEY 5005
4a4878 #define IDS_CATCHALL_ERROR_MESSAGE ·····5006
81da91 #define IDS_UNABLE_TO_MATCH_ID ·········5007
859234 #define IDS_RSA_ENCR_ERROR ·············5008
8d7539 #define IDS_INVALID_FILE_OP_ERROR ······5009
9e7faf #define IDS_NO_PGP_DATA ················5010
e0037b #define IDS_NO_DATA_TO_ENCRYPT ·········5011
d4ee20 #define IDS_HELPFILENAME ···············5012
eebdda #define IDS_ENTER_PHRASE ···············5013
62833f #define IDS_WRONG_PHRASE ···············5014
917310 #define ID_ADDKEY ······················40006
a3e15b #define ID_ENCRYPTSIGN ·················40007
f8377a #define ID_DECRYPTVERIFY ···············40008
aae36c #define ID_VIEWCLIPBOARD ···············40009
b7bbd0 #define ID_LAUNCHVIEWER ················40010
14a40b #define ID_LAUNCHPGPKEYS ···············40011
122148 #define ID_PROPERTIES ··················40012
8fe417 #define ID_WHATIS_TED1 ·················40013
f7a592 #define ID_WHATIS_TED2 ·················40014
60180d #define ID_PGPTRAY_ENCRYPT ·············40014
68ed97 #define ID_QUIT_ENCLYPTOR ··············40015
3ab89a #define ID_HELP_TOPICS ·················40016
e2ce55 #define ID_ENCRYPT ·····················40017
b4fce7 #define ID_SIGN ························40018
a4b877 #define ID_LAUNCHPGPTOOLS ··············40019
e19ab1 #define ID_WIPECLIP ····················40020
089bb4 #define ID_USECURRENT ··················40021
498a0f #define ID_LAUNCHPGPDISK¤   ¤   40022
59af5a
8e11aa // Next default values for new objects
77ac6a //·
a5f860 #ifdef APSTUDIO_INVOKED
9c3f23 #ifndef APSTUDIO_READONLY_SYMBOLS
--7aa5 001ef1847e7401102d4 Page 2 of RESOURCE.H
e62177 #define _APS_NEXT_RESOURCE_VALUE ·······134
e4e714 #define _APS_NEXT_COMMAND_VALUE ········40023
2f382c #define _APS_NEXT_CONTROL_VALUE ········1008
551285 #define _APS_NEXT_SYMED_VALUE ··········101
0a7454 #endif
ef7454 #endif
--cc36 00124e89485401102d5 Page 1 of Taskbar.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7b9a75 ¤   $Id: Taskbar.c,v 1.5.16.1 1998/11/12 03:13:51 heller Exp $
edf7f7 ____________________________________________________________________________*/
7b5ed8 #include "precomp.h"
b3af5a
fec782 BOOL TaskbarAddIcon(HWND hwnd, UINT uID, HICON hicon,·
e9d6e3 ¤   ¤   ¤   ¤   ¤   LPSTR lpszTip, UINT cbMsg)
42bb36 {
8791e2 ¤   BOOL result;
2efbfe ¤   NOTIFYICONDATA tnid;
e0af5a
296f6d ¤   memset(&tnid,0x00,sizeof(NOTIFYICONDATA));
daaf5a
2c38ac ¤   tnid.cbSize¤¤   ¤   ¤   = sizeof(NOTIFYICONDATA);
9e1dd9 ¤   tnid.hWnd¤  ¤   ¤   ¤   = hwnd;
0f32e8 ¤   tnid.uID¤   ¤   ¤   ¤   = uID;
79844d ¤   tnid.uFlags¤¤   ¤   ¤   = NIF_MESSAGE | NIF_ICON | NIF_TIP;
9a02f9 ¤   tnid.uCallbackMessage¤  = cbMsg;
1bf36a ¤   tnid.hIcon¤ ¤   ¤   ¤   = hicon;
d4af5a
e899c0 ¤   if(lpszTip)
d0c7a1 ¤   {
7ebf52 ¤   ¤   strcpy(tnid.szTip, lpszTip);
df9371 ¤   }
62af5a
03b34b ¤   result = Shell_NotifyIcon(NIM_ADD, &tnid);
c2af5a
303b65 ¤   if(hicon)
5ac7a1 ¤   {
222c7c ¤   ¤   DestroyIcon(hicon);
609371 ¤   }
faaf5a
e25d73 ¤   return result;
cbefe6 }
a4af5a
fcaf5a
35b219 BOOL TaskbarDeleteIcon(HWND hwnd, UINT uID)
4dbb36 {
f891e2 ¤   BOOL result;
f8fbfe ¤   NOTIFYICONDATA tnid;
0faf5a
756f6d ¤   memset(&tnid,0x00,sizeof(NOTIFYICONDATA));
6baf5a
ea38ac ¤   tnid.cbSize¤¤   ¤   ¤   = sizeof(NOTIFYICONDATA);
551dd9 ¤   tnid.hWnd¤  ¤   ¤   ¤   = hwnd;
c532e8 ¤   tnid.uID¤   ¤   ¤   ¤   = uID;
7faf5a
a0e39e ¤   result = Shell_NotifyIcon(NIM_DELETE, &tnid);
e9af5a
5d5d73 ¤   return result;
7aefe6 }
d7af5a
93af5a
d27e4d /*__Editor_settings____
74af5a
434126 ¤   Local Variables:
197b17 ¤   tab-width: 4
f00e6c ¤   End:
165f8c ¤   vi: ts=4 sw=4
f09e9b ¤   vim: si
24d062 _____________________*/
--e252 0010d7cc744401102d6 Page 1 of Taskbar.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
58aa62 ¤   $Id: Taskbar.h,v 1.2.16.1 1998/11/12 03:13:52 heller Exp $
0ff7f7 ____________________________________________________________________________*/
15e54d #ifndef Included_TASKBAR_h¤ /* [ */
ca2e2b #define Included_TASKBAR_h
2eaf5a
33c782 BOOL TaskbarAddIcon(HWND hwnd, UINT uID, HICON hicon,·
b9d563 ¤   ¤   ¤   ¤   ¤   LPSTR lpszTip, UINT cbMsg);
d6af5a
fc8dd2 BOOL TaskbarDeleteIcon(HWND hwnd, UINT uID);
3eaf5a
b8297f #endif /* ] Included_TASKBAR_h */
45af5a
60af5a
447e4d /*__Editor_settings____
55af5a
164126 ¤   Local Variables:
f87b17 ¤   tab-width: 4
a30e6c ¤   End:
bc5f8c ¤   vi: ts=4 sw=4
fd9e9b ¤   vim: si
0dd062 _____________________*/
--37ac 000807262fc401102d7 Page 1 of Choice.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
69d762 ¤   All rights reserved. ·
39e8c6 ···
39dda0 ¤   $Id: Choice.c,v 1.14 1998/08/11 15:19:57 pbj Exp $
9df7f7 ____________________________________________________________________________*/
c83281 #include <windows.h> ·
833d0b #include <windowsx.h>
69bb5f #include <assert.h>
8ad83c ·
d2bd58 #include "pgpMem.h" ·
6cd83c ·
a0354b #include "Choice.h"
cd17c5 #include "ChoiceProc.h"
5505c6 #include "resource.h"·
14e8c6 ···
c3d83c ·
8e48b7 PCHOICE NewChoice(HWND hwndParent)
6fbb36 {
5ff1aa ¤   PCHOICE choice = NULL;
0366e8 ¤   PCHOICE ChoiceList = NULL;
66d187 ¤   HWND hwndChoice = NULL; ·
810261 ¤   HWND hwndSpec = NULL;·
ae9bbf ¤   RECT rectParent;
42d83c ·
9f543c ¤   ChoiceList = (PCHOICE)GetProp(hwndParent, "ChoiceList");
f1af5a
b9d9e1 ¤   choice = (PCHOICE) malloc( sizeof(CHOICE) );
9dda86 ¤   ····
72afbc ¤   if(choice) ·
38fce6 ¤   { ···
0a6697 ¤   ¤   HWND hwndPrevChoice = NULL; ····
75d83c ·
645f9d ¤   ¤   if(ChoiceList)
0c52b0 ¤   ¤   {·
8f4698 ¤   ¤   ¤   hwndPrevChoice = ChoiceList->hwnd;·
b78469 ¤   ¤   }·
f2e8c6 ···
ba1145 ¤   ¤   memset(choice, 0x00, sizeof(choice)); ·
96d83c ·
819ca4 ¤   ¤   GetClientRect(hwndParent, &rectParent);
f0af5a
f20010 ¤   ¤   hwndChoice = CreateDialogParam(¤GetModuleHandle( NULL ),·
8f2d3b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE( IDD_CHOICE ),·
51473e ¤   ¤   ¤   ¤   ¤   ¤   ·¤  ¤   ¤   ¤   hwndParent,·
2f7966 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DLGPROC) ChoiceProc,·
6bc377 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) hwndPrevChoice);
89af5a
28217d ¤   ¤   choice->hwnd = hwndChoice;·
4e43de ¤   ¤   choice->next = ChoiceList;
840277 ¤   ¤   ChoiceList = choice;
0c9dc2 ¤   ¤   SetProp( hwndParent, "ChoiceList",(HANDLE) ChoiceList);
cd9371 ¤   }
bdd83c ·
85747f ¤   return choice;
1ea79b }·
beaf5a
93a972 PCHOICE RemoveLastChoice(HWND hwndParent, HWND* hwndChoice)
2d7142 {·
9b1cf4 ¤   PCHOICE choice = NULL; ·
b366e8 ¤   PCHOICE ChoiceList = NULL;
28af5a
eb543c ¤   ChoiceList = (PCHOICE)GetProp(hwndParent, "ChoiceList");
51af5a
4c6474 ¤   if(ChoiceList)
b1c7a1 ¤   {
620f25 ¤   ¤   choice = ChoiceList->next;
a7af5a
bbf3f1 ¤   ¤   *hwndChoice =ChoiceList->hwnd;
d6af5a
17c0aa ¤   ¤   free(ChoiceList);
80af5a
--cc39 0000b375da4401102d7 Page 2 of Choice.c
b60277 ¤   ¤   ChoiceList = choice;
4f9dc2 ¤   ¤   SetProp( hwndParent, "ChoiceList",(HANDLE) ChoiceList);
7d9371 ¤   }
07af5a
f0747f ¤   return choice;
baefe6 }
1aaf5a
9cda27 int¤ChoiceCount(HWND hwndParent)
cfbb36 {
5bf1aa ¤   PCHOICE choice = NULL;
69c2cd ¤   int count = 0;
92af5a
9a9cb4 ¤   choice = (PCHOICE)GetProp(hwndParent, "ChoiceList");
60af5a
117f65 ¤   while( choice )
7dc7a1 ¤   {
5fefd2 ¤   ¤   count++;
4ba577 ¤   ¤   choice = choice->next;·
ff9371 ¤   }
b8af5a
fd1368 ¤   return count;
00efe6 }
33af5a
9fbcb0 PCHOICE¤FirstChoice(HWND hwndParent)
e4bb36 {
0fb90b ¤   return (PCHOICE)GetProp(hwndParent, "ChoiceList");;
ffefe6 }
02af5a
002ab1 PCHOICE NextChoice(HWND hwndParent, PCHOICE choice)
38bb36 {
bcbf1a ¤   assert(choice);
a3af5a
22881e ¤   if(choice)
7cc7a1 ¤   {
f59343 ¤   ¤   return choice->next;
dc9371 ¤   }
430e24 ¤   else
1ec7a1 ¤   {
477ed2 ¤   ¤   return NULL;
dd9371 ¤   }
ebefe6 }
bdaf5a
b60218 LRESULT·
77a2f4 CALLBACK·
65c157 SearchSubclassWndProc(HWND hwnd,·
27919a ¤   ¤   ¤   ¤   ¤   UINT msg,·
8283f0 ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
7907d7 ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
96bb36 {
28dd49 ¤   WNDPROC oldproc = (WNDPROC)GetProp(hwnd, "oldproc");
80215f ¤   HWND hwndNotify = GetProp(hwnd, "hwnd");
21af5a
af9467 ¤   switch(msg)
74c7a1 ¤   {
8d6eda ¤   ¤   case WM_DESTROY:·
545b34 ¤   ¤   {
8659d4 ¤   ¤   ¤   // put back old window proc
48d053 ¤   ¤   ¤   SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)oldproc );
d8af5a
863db7 ¤   ¤   ¤   // remove props
a89697 ¤   ¤   ¤   RemoveProp( hwnd, "oldproc" );·
aacdcb ¤   ¤   ¤   break;
320fe4 ¤   ¤   }
d7af5a
453a01 ¤   ¤   case WM_GETDLGCODE :
e35b34 ¤   ¤   {
f4f362 ¤   ¤   ¤   LPMSG¤  lpmsg = (LPMSG)lParam;
16af5a
df3042 ¤   ¤   ¤   if (lpmsg)·
3bf776 ¤   ¤   ¤   {
13967b ¤   ¤   ¤   ¤   if (lpmsg->message == WM_KEYDOWN)·
0b72c3 ¤   ¤   ¤   ¤   {
--dd40 0013986e55a401102d7 Page 3 of Choice.c
965c3a ¤   ¤   ¤   ¤   ¤   if (lpmsg->wParam == VK_RETURN)·
144859 ¤   ¤   ¤   ¤   ¤   {
03d114 ¤   ¤   ¤   ¤   ¤   ¤   return DLGC_WANTMESSAGE;
6d1c89 ¤   ¤   ¤   ¤   ¤   }
9d2613 ¤   ¤   ¤   ¤   }
4ea3a6 ¤   ¤   ¤   }
c2cdcb ¤   ¤   ¤   break;
670fe4 ¤   ¤   }
b1af5a
6500cb ¤   ¤   case WM_KEYDOWN:
475b34 ¤   ¤   {
56dc72 ¤   ¤   ¤   int nVirtKey = (int) wParam; ···// virtual-key code·
7c4268 ¤   ¤   ¤   long lKeyData = lParam; ·········// key data·
8daf5a
0360f1 ¤   ¤   ¤   if(nVirtKey == VK_RETURN)
15f776 ¤   ¤   ¤   {
1e5581 ¤   ¤   ¤   ¤   HWND hwndButton;
3aaf5a
a22be5 ¤   ¤   ¤   ¤   hwndButton = GetDlgItem (hwndNotify, IDC_SEARCH);
98af5a
56e09a ¤   ¤   ¤   ¤   if (IsWindowEnabled (hwndButton) &&·
b9f11d ¤   ¤   ¤   ¤   ¤   IsWindowVisible (hwndButton))
b572c3 ¤   ¤   ¤   ¤   {
d77892 ¤   ¤   ¤   ¤   ¤   SendMessage(hwndNotify,·
e0e08a ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND, IDC_SEARCH, (LPARAM)hwndButton);
682613 ¤   ¤   ¤   ¤   }
2d5109 ¤   ¤   ¤   ¤   else·
9072c3 ¤   ¤   ¤   ¤   {
048790 ¤   ¤   ¤   ¤   ¤   hwndButton = GetDlgItem (hwndNotify, IDC_STOP);
c08fa9 ¤   ¤   ¤   ¤   ¤   if (IsWindowEnabled (hwndButton) &&·
965f1c ¤   ¤   ¤   ¤   ¤   ¤   IsWindowVisible (hwndButton))
484859 ¤   ¤   ¤   ¤   ¤   {
312a0f ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwndNotify,·
106c7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND, IDC_STOP, (LPARAM)hwndButton);
be1c89 ¤   ¤   ¤   ¤   ¤   }
ed2613 ¤   ¤   ¤   ¤   }
7146f1 ¤   ¤   ¤   ¤   return 0;
cba3a6 ¤   ¤   ¤   }
54af5a
09cdcb ¤   ¤   ¤   break;
010fe4 ¤   ¤   }
e7af5a
9266f6 ¤   ¤   case WM_CHAR:
095b34 ¤   ¤   {
87a453 ¤   ¤   ¤   TCHAR chCharCode = (TCHAR) wParam; ···// character code·
18c714 ¤   ¤   ¤   long lKeyData = lParam; ·············// key data·
37af5a
d1005b ¤   ¤   ¤   if(chCharCode == 0x0A || chCharCode == 0x0D)
aaf776 ¤   ¤   ¤   {
ae46f1 ¤   ¤   ¤   ¤   return 0;
c0a3a6 ¤   ¤   ¤   }
f3af5a
0fcdcb ¤   ¤   ¤   break;
de0fe4 ¤   ¤   }
f31b52 ¤   ¤
659371 ¤   }
01af5a
ab59d4 ¤   return CallWindowProc(oldproc, hwnd, msg, wParam, lParam);
85efe6 }
39af5a
--6de6 001f02ed68e401102d8 Page 1 of Choice.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
69d762 ¤   All rights reserved. ·
39e8c6 ···
ec90a1 ¤   $Id: Choice.h,v 1.6 1998/08/11 15:19:58 pbj Exp $
35f7f7 ____________________________________________________________________________*/
47d83c ·
f534ee #ifndef _CHOICE_H
19e9b7 #define _CHOICE_H
73af5a
9faf5a
cc7cd0 typedef struct _CHOICE
e3bb36 {
e955cf ¤   HWND hwnd;
4d4fe9 ¤   struct _CHOICE* next;
48af5a
0ec461 }CHOICE, *PCHOICE;
ebaf5a
3caf5a
17c15c PCHOICE NewChoice(HWND hwndParent);
8f501c PCHOICE RemoveLastChoice(HWND hwndParent, HWND* hwndChoice);
2559e7 int¤¤   ChoiceCount(HWND hwndParent);
09b517 PCHOICE¤FirstChoice(HWND hwndParent);
96a408 PCHOICE NextChoice(HWND hwndParent, PCHOICE choice);
0baf5a
370218 LRESULT·
0ea2f4 CALLBACK·
c7c157 SearchSubclassWndProc(HWND hwnd,·
91919a ¤   ¤   ¤   ¤   ¤   UINT msg,·
2283f0 ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
38a215 ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
34af5a
d3af5a
f02841 #endif¶
--9e3c 0007205978a401102d9 Page 1 of ChoiceProc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
d932a3 ¤   $Id: ChoiceProc.c,v 1.12 1998/08/11 15:19:59 pbj Exp $
cbf7f7 ____________________________________________________________________________*/
6d5655 #include <windows.h>
5b3d0b #include <windowsx.h>
bf90fb #include <commctrl.h>
78af5a
8fa076 #include "pgpKeys.h"
f0af5a
f35ab2 #include "PGPcl.h"
a7354b #include "Choice.h"
1d1323 #include "SearchCommon.h"
788031 #include "resource.h"
2caf5a
adeec0 extern HINSTANCE¤   ¤   g_hInst;
79af5a
1caf5a
4e7efe BOOL·
bba2f4 CALLBACK·
c6b0ff ChoiceProc(¤HWND hwnd,·
686753 ¤   ¤   ¤   UINT msg,·
96a552 ¤   ¤   ¤   WPARAM wParam,·
c6be88 ¤   ¤   ¤   LPARAM lParam )
a87142 {·
303665 ¤   static HWND hwndPrevChild¤  = NULL;
0faf5a
ce9467 ¤   switch(msg)
0ec7a1 ¤   {
62df25 ¤   ¤   case WM_INITDIALOG:
875b34 ¤   ¤   {
26b004 ¤   ¤   ¤   RECT rect, rectPrevChild, rectDefaultBox;
7f3f29 ¤   ¤   ¤   HWND hwndDefaultBox, hwndBox;
ca1a3f ¤   ¤   ¤   int height = 0;
9527b9 ¤   ¤   ¤   int defaultSelection;
437740 ¤   ¤   ¤   HWND hwndTime = NULL;
96577d ¤   ¤   ¤   HWND hwndParent = NULL;
9caf5a
69a104 ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO);
02af5a
bae995 ¤   ¤   ¤   GetClientRect(hwndBox, &rect);
ab5cc9 ¤   ¤   ¤   MapWindowPoints(hwndBox, hwnd, (LPPOINT)&rect, 2);
eeaf5a
5c21b6 ¤   ¤   ¤   hwndTime = CreateWindowEx (0, DATETIMEPICK_CLASS,
da1a19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "DateTime",
b00858 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
a11d91 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.left, rect.top-1,·
932d4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.right-rect.left, rect.bottom-rect.top+2,·
8fb287 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd, NULL, g_hInst, NULL);
196c7a ¤   ¤   ¤   SetWindowPos (hwndTime, GetDlgItem (hwnd, IDC_VERB),
68fcc1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
855b1a ¤   ¤   ¤   SendMessage (hwndTime, DTM_SETMCCOLOR,·
296e0e ¤   ¤   ¤   ¤   ¤   ¤   MCSC_MONTHBK, (LPARAM)GetSysColor (COLOR_3DFACE));
c7af5a
085754 ¤   ¤   ¤   ShowWindow(hwndTime, SW_HIDE);
b32584 ¤   ¤   ¤   SetProp( hwnd, "hwndTime", hwndTime);·
85af5a
30a1cf ¤   ¤   ¤   hwndPrevChild = (HWND) lParam;
64af5a
cf0373 ¤   ¤   ¤   defaultSelection = ChoiceCount(GetParent(hwnd)) + 1;
19af5a
878cf9 ¤   ¤   ¤   defaultSelection = defaultSelection %·
828719 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (IDS_ATTRIBUTE_LAST - IDS_ATTRIBUTE_1);
fbaf5a
fc119f ¤   ¤   ¤   InitializeControlValues(hwnd, defaultSelection);
04af5a
e23165 ¤   ¤   ¤   GetClientRect(hwnd, &rect);
73af5a
10d0ec ¤   ¤   ¤   hwndDefaultBox = GetDlgItem(GetParent(hwnd),·
7276ba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_SPECIFIER_COMBO);
--c664 000f9a440a4401102d9 Page 2 of ChoiceProc.c
e0af5a
8a3165 ¤   ¤   ¤   GetClientRect(hwnd, &rect);
8bf559 ¤   ¤   ¤   GetWindowRect(hwndDefaultBox, &rectDefaultBox);
cd2b2c ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectDefaultBox, 2);
afaf5a
4c1979 ¤   ¤   ¤   if( hwndPrevChild )
acf776 ¤   ¤   ¤   {
7c2885 ¤   ¤   ¤   ¤   GetClientRect(hwndPrevChild, &rectPrevChild);
5ba3a6 ¤   ¤   ¤   }
6bbb8c ¤   ¤   ¤   else
82f776 ¤   ¤   ¤   {
d17782 ¤   ¤   ¤   ¤   HWND hwndDefaultBoxes = GetDlgItem(¤GetParent(hwnd),·
6392bf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_DEFAULT_GROUP);
17af5a
d61de6 ¤   ¤   ¤   ¤   GetWindowRect(hwndDefaultBoxes, &rectPrevChild);
90a3a6 ¤   ¤   ¤   }
6aaf5a
29af5a
17af5a
b1b6bf ¤   ¤   ¤   hwndParent = GetParent (hwnd);
58af5a
e1e745 ¤   ¤   ¤   // subclass edit box
cf6cbc ¤   ¤   ¤   SetProp(hwndTime,"hwnd", hwndParent ); ·
b92a51 ¤   ¤   ¤   SetProp(hwndTime, ·
81fb1e ¤   ¤   ¤   ¤   ¤   "oldproc",
dc837c ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndTime, GWL_WNDPROC ) );·
73817f ¤   ¤   ¤   SetWindowLong(¤ hwndTime, ·
a52a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
2f9197 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc ); ···
3aaf5a
62e745 ¤   ¤   ¤   // subclass edit box
d6a104 ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO);
f9ccef ¤   ¤   ¤   SetProp(hwndBox,"hwnd", hwndParent ); ·
c01c37 ¤   ¤   ¤   SetProp(hwndBox, ·
5ffb1e ¤   ¤   ¤   ¤   ¤   "oldproc",
125684 ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndBox, GWL_WNDPROC ) );·
504879 ¤   ¤   ¤   SetWindowLong(¤ hwndBox, ·
e22a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
9d9197 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc ); ···
b7af5a
6fe745 ¤   ¤   ¤   // subclass edit box
647387 ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO_LIST);
58ccef ¤   ¤   ¤   SetProp(hwndBox,"hwnd", hwndParent ); ·
261c37 ¤   ¤   ¤   SetProp(hwndBox, ·
0efb1e ¤   ¤   ¤   ¤   ¤   "oldproc",
fc5684 ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndBox, GWL_WNDPROC ) );·
ec4879 ¤   ¤   ¤   SetWindowLong(¤ hwndBox, ·
272a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
b29197 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc ); ···
c5af5a
ebe745 ¤   ¤   ¤   // subclass edit box
b8ab92 ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_EDIT);
51ccef ¤   ¤   ¤   SetProp(hwndBox,"hwnd", hwndParent ); ·
761c37 ¤   ¤   ¤   SetProp(hwndBox, ·
a7fb1e ¤   ¤   ¤   ¤   ¤   "oldproc",
685684 ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndBox, GWL_WNDPROC ) );·
344879 ¤   ¤   ¤   SetWindowLong(¤ hwndBox, ·
912a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
519197 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc ); ···
e4af5a
ed87c7 ¤   ¤   ¤
71004f ¤   ¤   ¤   MapWindowPoints(hwnd,·
831ea7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetParent(hwnd),·
b49aae ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPPOINT)&rect,·
0e6f43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
4faf5a
bb2c65 ¤   ¤   ¤   MapWindowPoints(hwndPrevChild,·
a81ea7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetParent(hwnd),·
3b025c ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPPOINT)&rectPrevChild,·
036f43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
1daf1d ¤   ¤   ¤   height = rect.bottom - rect.top;
f9af5a
--84b6 0005164ce59401102d9 Page 3 of ChoiceProc.c
a51600 ¤   ¤   ¤   rect.top¤   = rectPrevChild.bottom + 1;
a032c6 ¤   ¤   ¤   rect.right¤ = rectDefaultBox.right;
78ef57 ¤   ¤   ¤   rect.bottom = rect.top + height;
81af5a
27aee8 ¤   ¤   ¤   MoveWindow(¤hwnd,·
1dfc76 ¤   ¤   ¤   ¤   ¤   ¤   rect.left,·
ced080 ¤   ¤   ¤   ¤   ¤   ¤   rect.top,·
1cfb3a ¤   ¤   ¤   ¤   ¤   ¤   rect.right - rect.left,
d715cb ¤   ¤   ¤   ¤   ¤   ¤   rect.bottom - rect.top,·
b591ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
68af5a
bd87c7 ¤   ¤   ¤
ba32bd ¤   ¤   ¤   return TRUE;
780fe4 ¤   ¤   }
27af5a
9c2526 ¤   ¤   case WM_SIZE:
b15b34 ¤   ¤   {
c975d9 ¤   ¤   ¤   RECT rectControl, rectDefaultBox;
5dd752 ¤   ¤   ¤   HWND hwndControl, hwndDefaultBox;
c4af5a
f3ce12 ¤   ¤   ¤   // move the Boxes
c0af5a
7ad0ec ¤   ¤   ¤   hwndDefaultBox = GetDlgItem(GetParent(hwnd),·
ff76ba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_SPECIFIER_COMBO);
69f559 ¤   ¤   ¤   GetWindowRect(hwndDefaultBox, &rectDefaultBox);
a92b2c ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectDefaultBox, 2);
73af5a
186bf1 ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO);
d7ea73 ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
32305e ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
767a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
bf4bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
a98352 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
2198ff ¤   ¤   ¤   ¤   ¤   ¤   rectDefaultBox.right - rectDefaultBox.left,
5f98e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
b391ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
24af5a
b7329e ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_SPECIFIER_EDIT);
20ea73 ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
cf305e ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
e57a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
d24bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
1d8352 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
6198ff ¤   ¤   ¤   ¤   ¤   ¤   rectDefaultBox.right - rectDefaultBox.left,
b098e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
3591ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
18af5a
002d02 ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO_LIST);
ecea73 ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
c9305e ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
e97a65 ¤   ¤   ¤   MoveWindow(¤hwndControl,·
754bf7 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
708352 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
7d98ff ¤   ¤   ¤   ¤   ¤   ¤   rectDefaultBox.right - rectDefaultBox.left,
fc98e9 ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
d491ac ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
8e87c7 ¤   ¤   ¤
ae32bd ¤   ¤   ¤   return TRUE;
b20fe4 ¤   ¤   }
15af5a
5e8e1e ¤   ¤   case WM_COMMAND:
4052b0 ¤   ¤   {·
70a168 ¤   ¤   ¤   switch( LOWORD(wParam) )
b7f776 ¤   ¤   ¤   {
c5727c ¤   ¤   ¤   ¤   case IDC_ATTRIBUTE:
ee72c3 ¤   ¤   ¤   ¤   {
4a3a11 ¤   ¤   ¤   ¤   ¤   HANDLE_IDC_ATTRIBUTE(hwnd, msg, wParam, lParam);
9f14c3 ¤   ¤   ¤   ¤   ¤   break;
f62613 ¤   ¤   ¤   ¤   }
61a3a6 ¤   ¤   ¤   }
8aaf5a
5132bd ¤   ¤   ¤   return TRUE;
--f79e 00149417aaa401102d9 Page 4 of ChoiceProc.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
b4af5a
a1a230 ¤   return FALSE;
3fefe6 }
28af5a
49af5a
--7efc 001219ee1e5401102da Page 1 of ChoiceProc.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
7a3d20 ¤   $Id: ChoiceProc.h,v 1.3 1998/08/11 15:19:59 pbj Exp $
e2f7f7 ____________________________________________________________________________*/
feb799 #ifndef _CHOICEPROC_H
5eeb9c #define _CHOICEPROC_H
7eaf5a
e5af5a
3b7efe BOOL·
9ca2f4 CALLBACK·
45b0ff ChoiceProc(¤HWND hwnd,·
006753 ¤   ¤   ¤   UINT msg,·
cfa552 ¤   ¤   ¤   WPARAM wParam,·
fe08de ¤   ¤   ¤   LPARAM lParam );
f0af5a
212841 #endif¶
--e2a8 000cb2724d1401102db Page 1 of GMIDropTarget.cpp
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
96af5a
0beca2 ¤   GMIDropTarget.cpp - implements OLE IDropTarget for drag and drop
be67c5 ¤
ad79a2 ¤   $Id: GMIDropTarget.cpp,v 1.6 1998/08/11 15:20:00 pbj Exp $
3df7f7 ____________________________________________________________________________*/
c2af5a
fbfc2c // system header files
aa5655 #include <windows.h>
6790fb #include <commctrl.h>
a6af5a
39c917 // project header files
6af86c #include "GMIDropTarget.h"
2bbeb4 #include "..\include\treelist.h"
7daf5a
e66dad extern "C" {
bd131f typedef struct _GM *PGROUPMAN;
f91b45 BOOL GMDropKeys (PGROUPMAN pGM, HANDLE hMem);
ea7f26 BOOL GMImportGroups (PGROUPMAN pGM, HDROP hDrop);
121b97 BOOL GMSelectGroup (PGROUPMAN pGM, POINTL pt);
2fefe6 }
1aaf5a
844265 //¤ ___________________________________________________
4f465d //
03cabc //¤ IUnknown Methods
dfaf5a
9e0d2f STDMETHODIMP CDropTarget::QueryInterface (
63a1ff ¤   ¤   REFIID ¤¤   ¤   iid,·
fe0060 ¤   ¤   void FAR* FAR* ¤ppv)·
f7bb36 {
8e4249 ····if ((iid == IID_IUnknown) || (iid == IID_IDropTarget)) {
077277 ······*ppv = this;
a4bc36 ······++m_refs;
354323 ······return NOERROR;
1f6fe7 ····}
6ee0d5 ····*ppv = NULL;
24af5a
bb2438 ····return E_NOINTERFACE;
1defe6 }
26af5a
25af5a
50c9c4 STDMETHODIMP_(ULONG) CDropTarget::AddRef (void)·
c1bb36 {
79bd9a ····return ++m_refs;
94efe6 }
f8af5a
76af5a
319923 STDMETHODIMP_(ULONG) CDropTarget::Release (void)·
cabb36 {
3f3dd1 ····if (--m_refs == 0) {
dfb4fd ······delete this;
25c9db ······return 0;
976fe7 ····}
5421aa ····return m_refs;
bf0acd } ·
12af5a
04af5a
b44265 //¤ ___________________________________________________
30465d //
6bc2b0 //¤ CDropTarget Constructor
92d83c ·
cc6e0f CDropTarget::CDropTarget (
c61cf6 ¤   ¤   HWND ¤  hwnd,·
ec90ca ¤   ¤   VOID* ¤ pGroupMan)·
99bb36 {
35bec9 ····m_refs = 1; ·
aa3653 ¤   m_bAcceptFmt = FALSE;
9f7aba ¤   m_bEnabled = FALSE;
fa1c0f ¤   m_pGroupMan = pGroupMan;
cbd88f ¤   m_hwnd = hwnd;
--b693 000ef039821401102db Page 2 of GMIDropTarget.cpp
020cae ¤   m_fmtDrop = 0;
53efe6 }
a7af5a
17af5a
014265 //¤ ___________________________________________________
10465d //
173b28 //¤ Enable/disable dropping. ·Used when dragging a key out
53982b //¤ of key manager.
f2d83c ·
c362d8 void CDropTarget::Enable (BOOL bEnable)·
96bb36 {
8c9ce0 ····m_bEnabled = bEnable; ·
cdefe6 }
90af5a
27af5a
2c4265 //¤ ___________________________________________________
ec465d //
b399bc //¤ IDropTarget Methods
39af5a
065729 STDMETHODIMP CDropTarget::DragEnter (
a66043 ¤   ¤   LPDATAOBJECT¤   pDataObj,·
f86e32 ¤   ¤   DWORD ¤ ¤   ¤   grfKeyState,·
561141 ¤   ¤   POINTL ¤¤   ¤   pt,·
40bb15 ¤   ¤   LPDWORD ¤   ¤   pdwEffect)·
cf4157 { ·
c67cf1 ¤   FORMATETC fmtetc;
50869e ····
7d0494 ¤   // default to not allowing drop
8e3653 ¤   m_bAcceptFmt = FALSE;
aff83f ·¤  *pdwEffect = DROPEFFECT_NONE;
b3af5a
b034a4 ¤   if (!m_bEnabled) {
7354df ¤   ¤   return NOERROR;
399371 ¤   }
f5af5a
c36c7c ¤   // Does the drag source provide CF_TEXT? ····
722c8c ¤   fmtetc.cfFormat = CF_TEXT;
25070a ¤   fmtetc.ptd ·····= NULL;
9c5821 ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
40b4a6 ¤   fmtetc.lindex ··= -1;
d029af ¤   fmtetc.tymed ···= TYMED_HGLOBAL;·
b1869e ····
bcfdf8 ¤   if (pDataObj->QueryGetData (&fmtetc) == NOERROR) {
9d1c2a ¤   ¤   m_bAcceptFmt = TRUE;
abe8ab ¤   ¤   m_fmtDrop = CF_TEXT;
019a88 ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
c69371 ¤   }
d0e8c6 ···
67216b ¤   // Does the drag source provide CF_HDROP? ····
572de7 ¤   fmtetc.cfFormat = CF_HDROP;
95070a ¤   fmtetc.ptd ·····= NULL;
905821 ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
1bb4a6 ¤   fmtetc.lindex ··= -1;
7c29af ¤   fmtetc.tymed ···= TYMED_HGLOBAL;·
60869e ····
16fdf8 ¤   if (pDataObj->QueryGetData (&fmtetc) == NOERROR) {
401c2a ¤   ¤   m_bAcceptFmt = TRUE;
b1789e ¤   ¤   m_fmtDrop = CF_HDROP;
bd9a88 ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
339371 ¤   }
9de8c6 ···
f62e2b ¤   return NOERROR;
75efe6 }
56af5a
dfaf5a
49dfbf STDMETHODIMP CDropTarget::DragOver (
1a2718 ¤   ¤   DWORD ¤ grfKeyState,·
7b2ea3 ¤   ¤   POINTL ¤pt,·
816e1e ¤   ¤   LPDWORD pdwEffect)·
c4bb36 {
91c347 ¤   *pdwEffect = DROPEFFECT_NONE;·
ef2941 ¤   if (m_bAcceptFmt && m_bEnabled) {
--341a 0000f52c48f401102db Page 3 of GMIDropTarget.cpp
1487d6 ¤   ¤   if (m_fmtDrop == CF_HDROP)
c823da ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;·
6d07e0 ¤   ¤   else {
3bcaa9 ¤   ¤   ¤   if (GMSelectGroup ((PGROUPMAN)m_pGroupMan, pt))·
b3b242 ¤   ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;·
2b0fe4 ¤   ¤   }
9c9371 ¤   }
042e2b ¤   return NOERROR;
67efe6 }
cbaf5a
3faf5a
ef856e STDMETHODIMP CDropTarget::DragLeave ()·
920337 { ··
de0373 ¤   m_bAcceptFmt = FALSE; ··
7d2e2b ¤   return NOERROR;
45efe6 }
d6af5a
36af5a
1f208b STDMETHODIMP CDropTarget::Drop (
ee6043 ¤   ¤   LPDATAOBJECT¤   pDataObj,·
576b94 ¤   ¤   DWORD ¤ ¤   ¤   grfKeyState, ¤  ¤   ¤   ¤   ¤   ···
c81141 ¤   ¤   POINTL ¤¤   ¤   pt,·
0bbb15 ¤   ¤   LPDWORD ¤   ¤   pdwEffect)·
bc0337 { ··
7a020a ¤   FORMATETC fmtetc; ··
969541 ¤   STGMEDIUM medium; ··
629627 ¤   HGLOBAL hGlobal;
0e094a ¤   HRESULT hr;
95583d ·····
4c0df1 ¤   *pdwEffect = DROPEFFECT_NONE;
323211 ¤   hr = NOERROR;
04af5a
65e5e6 ¤   if (m_bAcceptFmt && m_bEnabled) { ·····
5478e9 ¤   ¤   // User has dropped on us. Try getting CF_TEXT data from drag source
bea0f3 ¤   ¤   fmtetc.cfFormat = CF_TEXT;
3c9cd0 ¤   ¤   fmtetc.ptd = NULL;
a061e4 ¤   ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
1c0fa6 ¤   ¤   fmtetc.lindex = -1;
6bd16f ¤   ¤   fmtetc.tymed = TYMED_HGLOBAL; ······
f0508e ········
6f376e ¤   ¤   hr = pDataObj->GetData (&fmtetc, &medium);
a9c1cf ¤   ¤   if (!FAILED(hr)) {
8128cf ¤   ¤   // Import the data and release it.
03450d ¤   ¤   ¤   hGlobal = medium.hGlobal;
d3ad3d ¤   ¤   ¤   GMDropKeys ((PGROUPMAN)m_pGroupMan, hGlobal);
ca33a1 ¤   ¤   ¤   ReleaseStgMedium (&medium);
e8a666 ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
70a2ba ¤   ¤   ¤   return NOERROR;
400fe4 ¤   ¤   }
03af5a
77fa9a ¤   ¤   // no CF_TEXT, try getting CF_HDROP data from drag source
72a61b ¤   ¤   fmtetc.cfFormat = CF_HDROP;
689cd0 ¤   ¤   fmtetc.ptd = NULL;
1661e4 ¤   ¤   fmtetc.dwAspect = DVASPECT_CONTENT; ·
f10fa6 ¤   ¤   fmtetc.lindex = -1;
87d16f ¤   ¤   fmtetc.tymed = TYMED_HGLOBAL; ······
d4508e ········
ce376e ¤   ¤   hr = pDataObj->GetData (&fmtetc, &medium);
c3c1cf ¤   ¤   if (!FAILED(hr)) {
3d28cf ¤   ¤   // Import the data and release it.
6b450d ¤   ¤   ¤   hGlobal = medium.hGlobal;
728eab ¤   ¤   ¤   GMImportGroups ((PGROUPMAN)m_pGroupMan, hGlobal);
0b33a1 ¤   ¤   ¤   ReleaseStgMedium (&medium);
3ba666 ¤   ¤   ¤   *pdwEffect = DROPEFFECT_COPY;
f8a2ba ¤   ¤   ¤   return NOERROR;
f50fe4 ¤   ¤   }
789371 ¤   }
6b45a8 ¤   return hr; ·····
5b38af } ··
abaf5a
75af5a
0f4265 //¤ ___________________________________________________
--a2e6 00141664f60401102db Page 4 of GMIDropTarget.cpp
c1465d //
8de21b //¤ Interface to C code·
09af5a
c26dad extern "C" {
1ae1ad LPDROPTARGET GMCreateDropTarget (
c0c2d2 ¤   ¤   HWND¤   hwnd,·
0390ca ¤   ¤   VOID* ¤ pGroupMan)·
57bb36 {
7e6f7f ¤   return ((LPDROPTARGET) new CDropTarget (hwnd, pGroupMan));
6fefe6 }
01af5a
169019 void GMReleaseDropTarget (LPDROPTARGET pDropTarget)·
8bbb36 {
fd30f6 ¤   pDropTarget->Release ();
c5efe6 }
e9af5a
076210 void GMEnableDropTarget (
c9fc2e ¤   ¤   CDropTarget*¤   pDropTarget,·
96df88 ¤   ¤   BOOL ¤  ¤   ¤   bEnable)·
1abb36 {
b57e4b ¤   pDropTarget->Enable (bEnable);
a0efe6 }
a5af5a
41be43 }¶
--0116 00170e5513b401102dc Page 1 of GMIDropTarget.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
5272ac ¤   $Id: GMIDropTarget.h,v 1.5 1998/08/11 15:20:01 pbj Exp $
2cf7f7 ____________________________________________________________________________*/
31af5a
3704c0 class FAR CDropTarget : public IDropTarget
52bb36 {
ccdd93 public: ···
bbba03 ····CDropTarget(HWND hwnd, VOID* pGroupMan);
1bffbd ¤   void Enable(BOOL bEnable);
47af5a
a9d68d ····// IUnknown methods
27a5a5 ····STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
885d7f ····STDMETHOD_(ULONG, AddRef)(void);
d869f5 ····STDMETHOD_(ULONG, Release)(void);
cfaf5a
f52d85 ····// IDropTarget methods
4a0e86 ····STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState,·
c50f63 ¤   ¤   POINTL pt, LPDWORD pdwEffect);
c04281 ····STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
8a54ad ····STDMETHOD(DragLeave)();
1c717f ····STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState,·
7874de ¤   ¤   POINTL pt, LPDWORD pdwEffect);·
c0869e ····
1f0fb9 private:
45e3c0 ····ULONG m_refs; ·
0dd338 ····ULONG m_fmtDrop; ·
720321 ····BOOL m_bAcceptFmt;
6d6c99 ¤   BOOL m_bEnabled;
368475 ¤   HWND m_hwnd;
ee253a ¤   VOID* m_pGroupMan;
8f3e67 }; ·
70af5a
--3049 0004071aa2f401102dd Page 1 of GMMenu.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
063ef8 ¤   GMMenu.c - handle menu enabling/disabling chores
7867c5 ¤
d3af5a
674528 ¤   $Id: GMMenu.c,v 1.13 1998/08/11 15:20:02 pbj Exp $
4af7f7 ____________________________________________________________________________*/
4fe610 #include "pgpPFLConfig.h"
3daf5a
62c917 // project header files
5b3490 #include "pgpgmx.h"
e4af5a
4f5bee // typedefs
3af0f7 typedef struct {
5f9093 ¤   FARPROC lpfnCallback;
ce07bf ¤   HWND hWndTree;
749b35 } EXPANDCOLLAPSESTRUCT;
8aaf5a
a7822f // External globals
999cad extern HINSTANCE g_hInst;
44af5a
d14265 //¤ ___________________________________________________
2b465d //
85dda6 // ·Expand a single item
b06d3e //¤ routine called as a
7e995b //¤ callback function from the TreeList control to·
79a512 //¤ expand a single item.
53465d //
6ee701 //¤ lptli¤  = pointer to TreeList item to expand
51af5a
353f64 static BOOL CALLBACK·
8694c8 sExpandSingleItem (TL_TREEITEM* lptli, LPARAM lParam)·
e6bb36 {
ab00bf ¤   EXPANDCOLLAPSESTRUCT* pecs = (EXPANDCOLLAPSESTRUCT*)lParam;
f67909 ¤   TreeList_Expand (pecs->hWndTree, lptli, TLE_EXPANDALL);
6ac2e7 ¤   return TRUE;
8defe6 }
a4af5a
bbaf5a
be4265 //¤ ___________________________________________________
5a465d //
d466d8 // ·Expand the selected items
ecaf5a
ff7efe BOOL·
ef6197 GMExpandSelected (PGROUPMAN pGM)·
bdbb36 {
00e723 ¤   TL_TREEITEM tli;
ada9af ¤   EXPANDCOLLAPSESTRUCT ecs;
deaf5a
3e5165 ¤   if (GMMultipleSelected (pGM)) {
3f3a09 ¤   ¤   ecs.lpfnCallback = sExpandSingleItem;
bfe0a3 ¤   ¤   ecs.hWndTree = pGM->hWndTree;
e4010d ¤   ¤   TreeList_IterateSelected (pGM->hWndTree, &ecs);
72e34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
b5836c ¤   ¤   return TRUE;
f49371 ¤   }
29665a ¤   else {
c82c0e ¤   ¤   tli.hItem = GMFocusedItem (pGM);
538fc7 ¤   ¤   TreeList_Expand (pGM->hWndTree, &tli, TLE_EXPANDALL);
f4e34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
85836c ¤   ¤   return TRUE;
b69371 ¤   }
4ba230 ¤   return FALSE;
8eefe6 }
34af5a
deaf5a
214265 //¤ ___________________________________________________
66465d //
95ff15 // ·Collapse a single item
406d3e //¤ routine called as a
--41e2 000a5461524401102dd Page 2 of GMMenu.c
fa995b //¤ callback function from the TreeList control to·
5640d4 //¤ collapse a single item.
83ac6a //·
f0ab4c //¤ lptli¤  = pointer to TreeList item to collapse
90af5a
523f64 static BOOL CALLBACK·
08d1a8 sCollapseSingleItem (TL_TREEITEM* lptli, LPARAM lParam)·
42bb36 {
f700bf ¤   EXPANDCOLLAPSESTRUCT* pecs = (EXPANDCOLLAPSESTRUCT*)lParam;
140a5c ¤   TreeList_Expand (pecs->hWndTree, lptli, TLE_COLLAPSEALL);
88c2e7 ¤   return TRUE;
edefe6 }
2eaf5a
c1af5a
594265 //¤ ___________________________________________________
e0465d //
0093b5 // ·Collapse the selected items
5aaf5a
395905 BOOL GMCollapseSelected (PGROUPMAN pGM) {
3ae723 ¤   TL_TREEITEM tli;
eca9af ¤   EXPANDCOLLAPSESTRUCT ecs;
e8af5a
785165 ¤   if (GMMultipleSelected (pGM)) {
a7b9f0 ¤   ¤   ecs.lpfnCallback = sCollapseSingleItem;
0ae0a3 ¤   ¤   ecs.hWndTree = pGM->hWndTree;
a2010d ¤   ¤   TreeList_IterateSelected (pGM->hWndTree, &ecs);
d1e34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
55836c ¤   ¤   return TRUE;
709371 ¤   }
52665a ¤   else {
902c0e ¤   ¤   tli.hItem = GMFocusedItem (pGM);
81c85f ¤   ¤   TreeList_Expand (pGM->hWndTree, &tli, TLE_COLLAPSEALL);
28e34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
eb836c ¤   ¤   return TRUE;
039371 ¤   }
a2a230 ¤   return FALSE;
67efe6 }
fbaf5a
a0af5a
f6a3c6 //¤ ___________________________________________
d5465d //
500c63 // ·Determine if there is text in the clipboard
a0af5a
327efe BOOL·
c35244 GMDataToPaste (VOID)·
e1bb36 {
79ef38 ¤   if (IsClipboardFormatAvailable (CF_TEXT)) return TRUE;
7ea230 ¤   return FALSE;
21efe6 }
69af5a
554265 //¤ ___________________________________________________
3c465d //
660af9 //¤ determine if each action is enabled or not
41af5a
5513d8 //¤ paste·
8673c1 static BOOL sIsPasteEnabled (PGROUPMAN pGM) {
2548cf ¤   if (GMMultipleSelected (pGM)) return FALSE;
c31476 ¤   if (!GMDataToPaste ()) return FALSE;
00c2e7 ¤   return TRUE;
f2efe6 }
8faf5a
6878da //¤ delete·
fcd4b7 static BOOL sIsDeleteEnabled (PGROUPMAN pGM) {
a72515 ¤   if (GMFocusedItemType (pGM) == IDX_NONE) return FALSE;
7dc2e7 ¤   return TRUE;
5aefe6 }
60af5a
e0d378 //¤ select all·
ac5cd7 static BOOL sIsSelectAllEnabled (PGROUPMAN pGM) {
53c2e7 ¤   return TRUE;
4cefe6 }
a5af5a
--45d7 00055cb3047401102dd Page 3 of GMMenu.c
1703dc //¤ collapse all·
55a55f static BOOL sIsCollapseAllEnabled (PGROUPMAN pGM) {
7df754 ¤   if (GMFocusedItemType (pGM) == IDX_NONE) return TRUE;
78a230 ¤   return FALSE;
1defe6 }
27af5a
5a3c50 //¤ expand all·
4c326f static BOOL sIsExpandAllEnabled (PGROUPMAN pGM) {
eff754 ¤   if (GMFocusedItemType (pGM) == IDX_NONE) return TRUE;
14a230 ¤   return FALSE;
f9efe6 }
b7af5a
dc050a //¤ collapse selected·
293a4b static BOOL sIsCollapseSelEnabled (PGROUPMAN pGM) {
702515 ¤   if (GMFocusedItemType (pGM) == IDX_NONE) return FALSE;
cfc2e7 ¤   return TRUE;
88efe6 }
77af5a
a80664 //¤ expand selected·
23ad7b static BOOL sIsExpandSelEnabled (PGROUPMAN pGM) {
fb2515 ¤   if (GMFocusedItemType (pGM) == IDX_NONE) return FALSE;
97c2e7 ¤   return TRUE;
77efe6 }
7eaf5a
458226 //¤ locate keys
5a7796 static BOOL sIsLocateKeysEnabled (PGROUPMAN pGM) {
0d1536 ¤   if (GMFocusedObjectType (pGM) != OBJECT_KEY) return FALSE;
9ec2e7 ¤   return TRUE;
13efe6 }
a5af5a
b55930 //¤ get keys from server
992491 static BOOL sIsGetFromServerEnabled (PGROUPMAN pGM) {
a27055 ¤   if (GMFocusedObjectType (pGM) == OBJECT_NONE) return FALSE;
68c2e7 ¤   return TRUE;
cbefe6 }
59af5a
363631 //¤ properties
615d4a static BOOL sIsPropertiesEnabled (PGROUPMAN pGM) {
2848cf ¤   if (GMMultipleSelected (pGM)) return FALSE;
bd7055 ¤   if (GMFocusedObjectType (pGM) == OBJECT_NONE) return FALSE;
c8c2e7 ¤   return TRUE;
ceefe6 }
4baf5a
8cb8d1 //¤ import groups from file
b60f12 static BOOL sIsImportGroupsEnabled (PGROUPMAN pGM) {
94c2e7 ¤   return TRUE;
eeefe6 }
f9af5a
06a326 //¤ unselect all·
239d4f static BOOL sIsUnselectAllEnabled (PGROUPMAN pGM) {
34f62f ¤   if (pGM->bLocatingKeys) return FALSE;
8fc2e7 ¤   return TRUE;
cbefe6 }
1baf5a
c5541a //¤ update all groups from keyserver
4dc6ac static BOOL sIsUpdateAllGroupsEnabled (PGROUPMAN pGM) {
0dc2e7 ¤   return TRUE;
95efe6 }
9eaf5a
246518 //¤ send all groups to keyserver
74352a static BOOL sIsSendAllGroupsEnabled (PGROUPMAN pGM) {
d4c2e7 ¤   return TRUE;
e1efe6 }
e2af5a
aa4265 //¤ ___________________________________________________
c7465d //
81cb17 //¤ determine if action is enabled or not, based on
7d6ad3 //¤ flags passed in and current selection
4daf5a
efc500 BOOL PGPgmExport·
0324da PGPgmIsActionEnabled (
558d7a ¤   ¤   HGROUPMAN hGM,·
--062d 000e05a9aaf401102dd Page 4 of GMMenu.c
28bd5f ¤   ¤   ULONG¤  ulAction)·
c2bb36 {
74af5a
37fdb3 ¤   PGROUPMAN pGM = (PGROUPMAN)hGM;
daaf5a
464d23 ¤   if (!hGM) return FALSE;
f7b7a1 ¤   if (ulAction & pGM->ulDisableActions) return FALSE;
68af5a
5db1cd ¤   switch (ulAction) {
fcaf5a
bd91ce ¤   case GM_PASTE :¤¤   ¤   ¤   return sIsPasteEnabled (pGM);
8348d1 ¤   case GM_DELETE :¤   ¤   ¤   return sIsDeleteEnabled (pGM);
27ba77 ¤   case GM_SELECTALL :¤¤   ¤   return sIsSelectAllEnabled (pGM);
0a19a9 ¤   case GM_COLLAPSEALL :¤  ¤   return sIsCollapseAllEnabled (pGM);
a7d8d9 ¤   case GM_COLLAPSESEL :¤  ¤   return sIsCollapseSelEnabled (pGM);
7126a0 ¤   case GM_EXPANDALL :¤¤   ¤   return sIsExpandAllEnabled (pGM);
2ee7d0 ¤   case GM_EXPANDSEL :¤¤   ¤   return sIsExpandSelEnabled (pGM);
632d14 ¤   case GM_PROPERTIES :¤   ¤   return sIsPropertiesEnabled (pGM);
6a36cd ¤   case GM_UNSELECTALL:¤   ¤   return sIsUnselectAllEnabled (pGM);
bcecaa ¤   case GM_LOCATEKEYS :¤   ¤   return sIsLocateKeysEnabled (pGM);
8a9c90 ¤   case GM_GETFROMSERVER :¤¤   return sIsGetFromServerEnabled (pGM);
1fd0a3 ¤   case GM_IMPORTGROUPS :¤ ¤   return sIsImportGroupsEnabled (pGM);
21057e ¤   case GM_UPDATEALLGROUPS :¤  return sIsUpdateAllGroupsEnabled (pGM);
eb65ac ¤   case GM_SENDALLGROUPS :¤¤   return sIsSendAllGroupsEnabled (pGM);
72ada4 ¤   default :¤  ¤   ¤   ¤   ¤   return FALSE;
3a9371 ¤   }
11efe6 }
59af5a
b84265 //¤ ___________________________________________________
e4465d //
a5182c //¤ perform the specified action
46af5a
746022 PGPError PGPgmExport·
a911bc PGPgmPerformAction (
9d8d7a ¤   ¤   HGROUPMAN hGM,·
5cbd5f ¤   ¤   ULONG¤  ulAction)·
acbb36 {
accf22 ¤   PGROUPMAN¤  ¤   ¤   pGM = (PGROUPMAN)hGM;
d8af5a
a53036 ¤   HTLITEM¤¤   ¤   hFirst;
c14aea ¤   TL_TREEITEM¤¤   tlI;
34af5a
bb99d8 ¤   if (!hGM) return kPGPError_BadParams;
fc544b ¤   if (!PGPgmIsActionEnabled (hGM, ulAction))·
c16904 ¤   ¤   return kPGPError_UnknownRequest;
82af5a
2eb1cd ¤   switch (ulAction) {
d7af5a
39b8c3 ¤   case GM_PASTE :
244177 ¤   ¤   GMPasteKeys (pGM);
792f68 ¤   ¤   break;
acaf5a
fa6f86 ¤   case GM_DELETE :
dd48f6 ¤   ¤   GMDeleteObject (pGM);
c32f68 ¤   ¤   break;
56af5a
c851ed ¤   case GM_SELECTALL :
81522f ¤   ¤   // get first item in list
6d780e ¤   ¤   TreeList_SelectChildren (pGM->hWndTree, NULL);
13e419 ¤   ¤   hFirst = TreeList_GetFirstItem (pGM->hWndTree);
58aaf4 ¤   ¤   // try to get second item
1e32e4 ¤   ¤   tlI.hItem = hFirst;
500d05 ¤   ¤   if (tlI.hItem) {
502ccb ¤   ¤   ¤   tlI.mask = TLIF_NEXTHANDLE;
8f5f0d ¤   ¤   ¤   TreeList_GetItem (pGM->hWndTree, &tlI);
3c0fe4 ¤   ¤   }
0eedfc ¤   ¤   // if second item exists, then multiple select
832fad ¤   ¤   if (tlI.hItem)
3c3bd8 ¤   ¤   ¤   GMSetFocus (pGM, hFirst, TRUE);
74ee26 ¤   ¤   else·
31c188 ¤   ¤   ¤   GMSetFocus (pGM, hFirst, FALSE);
e03e55 ¤   ¤   SetFocus (pGM->hWndTree);
--ebb0 001843379e1401102dd Page 5 of GMMenu.c
4f2f68 ¤   ¤   break;
92af5a
0c13fc ¤   case GM_COLLAPSEALL :
fef915 ¤   ¤   GMCollapseSelected (pGM);
1b2f68 ¤   ¤   break;
43af5a
d5087e ¤   case GM_COLLAPSESEL :
05f915 ¤   ¤   GMCollapseSelected (pGM);
412f68 ¤   ¤   break;
aaaf5a
99bec5 ¤   case GM_EXPANDALL :
a90aa5 ¤   ¤   GMExpandSelected (pGM);
842f68 ¤   ¤   break;
73af5a
49a547 ¤   case GM_EXPANDSEL :
800aa5 ¤   ¤   GMExpandSelected (pGM);
022f68 ¤   ¤   break;
a8af5a
923cef ¤   case GM_PROPERTIES :
3320b6 ¤   ¤   GMGroupProperties (pGM);
e22f68 ¤   ¤   break;
77af5a
04f5d8 ¤   case GM_LOCATEKEYS :
f3dd27 ¤   ¤   GMLocateKeys (pGM);
d72f68 ¤   ¤   break;
70af5a
c5d7f7 ¤   case GM_GETFROMSERVER :
e0740e ¤   ¤   GMGetFromServer (pGM);
bb2f68 ¤   ¤   break;
d8af5a
b36d80 ¤   case GM_IMPORTGROUPS :
6b7bdb ¤   ¤   GMImportGroups (pGM, NULL);
bf2f68 ¤   ¤   break;
3daf5a
18b306 ¤   case GM_UNSELECTALL :
60dae0 ¤   ¤   TreeList_Select (pGM->hWndTree, NULL, TRUE);
b7c005 ¤   ¤   GMSetFocus (pGM, NULL, FALSE);
d02f68 ¤   ¤   break;
c7af5a
431554 ¤   case GM_UPDATEALLGROUPS :
6a01f8 ¤   ¤   GMGetGroupsFromServer (pGM);
e92f68 ¤   ¤   break;
8f1b52 ¤   ¤
1fcfd6 ¤   case GM_SENDALLGROUPS :
2b9d4e ¤   ¤   GMSendGroupsToServer (pGM);
222f68 ¤   ¤   break;
261b52 ¤   ¤
329371 ¤   }
38af5a
87151e ¤   return kPGPError_NoErr;
8defe6 }
84af5a
--618b 0009856504e401102de Page 1 of GMMisc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
8f5898 ¤   GMTree.h - create and fill group manager control
9b67c5 ¤
6caf5a
776ede ¤   $Id: GMMisc.c,v 1.25 1998/08/11 15:20:03 pbj Exp $
edf7f7 ____________________________________________________________________________*/
30e610 #include "pgpPFLConfig.h"
1baf5a
28c917 // project header files
3f3490 #include "pgpgmx.h"
f8af5a
f9ad8c // pgp header files
5cc97b #include "pgpClientPrefs.h"
bfaf5a
985584 // constant definitions
da0d75 #define DEFAULTCOLWIDTHNAME ·240
9d061a #define DEFAULTCOLWIDTHVALID ·50
3148e9 #define DEFAULTCOLWIDTHDESC¤ 200
421588 #define MINWIDTH¤   ¤   ¤   ··10
41be49 #define MAXWIDTH¤   ¤   ¤   1000
30af5a
a35bee // typedefs
31f0f7 typedef struct {
f3f3fa ¤   FARPROC¤¤   ¤   lpfnCallback;
b82101 ¤   PGROUPMAN¤  ¤   pGM;
668a97 ¤   PGPContextRef¤  context;
78fead ¤   PGPKeySetRef¤   keyset;
8a587f ¤   INT¤¤   ¤   ¤   icount;
ed8194 ¤   PGPKeyID*¤  ¤   pkeyidList;
6a0b8b } SERVERSTRUCT, *PSERVERSTRUCT;
e9af5a
88f0f7 typedef struct {
137a35 ¤   WORD wColumnField[NUMBERFIELDS];
d889e3 ¤   WORD wFieldWidth[NUMBERFIELDS];
5b87d1 ¤   LONG lSortField;
3405b5 } COLUMNPREFSSTRUCT, *PCOLUMNPREFSSTRUCT;
b2af5a
57f0f7 typedef struct {
4d9e3c ¤   PGPKeySetRef¤   keySet;
4be849 ¤   PGPGroupSetRef¤ set;
fac844 ¤   INT¤¤   ¤   ¤   iInvert;
444217 } GMSortInfo;
2caf5a
70af5a
da93ed // external globals
729cad extern HINSTANCE g_hInst;
3faf5a
9caf5a
4ec509 //¤ ____________________________________
59465d //
d9fe84 //¤ Private memory allocation routine
ddaf5a
f5493a VOID*·
896b42 gmAlloc (LONG size)·
68bb36 {
d11d41 ¤   return malloc (size);
cfefe6 }
0baf5a
5ac509 //¤ ____________________________________
c0465d //
329e8c //¤ Private memory deallocation routine
d8af5a
01a1ba VOID·
9c017a gmFree (VOID* p)·
bebb36 {
1118c7 ¤   if (p)·
d2de78 ¤   ¤   free (p);
84efe6 }
98af5a
--f64e 00013324713401102de Page 2 of GMMisc.c
62c509 //¤ ____________________________________
0c465d //
a3bbfe //¤ Message box routine
57465d //
9d8a32 //¤ iCaption and iMessage are string table resource IDs.
15af5a
330218 LRESULT·
92d0f9 PGPgmMessageBox (
1547b2 ¤   ¤   HWND¤   hWnd,·
441310 ¤   ¤   INT¤¤   iCaption,·
3008ad ¤   ¤   INT¤¤   iMessage,
151582 ¤   ¤   ULONG¤  ulFlags)·
f1bb36 {
e501b5 ¤   CHAR szCaption [128];
753a7c ¤   CHAR szMessage [512];
50af5a
57c237 ¤   LoadString (g_hInst, iCaption, szCaption, sizeof(szCaption));
be7e8b ¤   LoadString (g_hInst, iMessage, szMessage, sizeof(szMessage));
e7af5a
82897a ¤   ulFlags |= MB_SETFOREGROUND;
c2729f ¤   return (MessageBox (hWnd, szMessage, szCaption, ulFlags));
66efe6 }
3eaf5a
244265 //¤ ___________________________________________________
43465d //
aeee00 //¤ Convert validity from weird PGP values to 0-2 scale
c4af5a
8544eb UINT·
033de4 GMConvertFromPGPValidity (UINT uPGPValidity)·
d8bb36 {
89b366 ¤   switch (uPGPValidity) {
7f0372 ¤   case kPGPValidity_Unknown :
21f5ef ¤   case kPGPValidity_Invalid :
58bc7d ¤   ¤   return GM_VALIDITY_INVALID;
156a63 ¤   case kPGPValidity_Marginal :
2e8688 ¤   ¤   return GM_VALIDITY_MARGINAL;
beba7e ¤   case kPGPValidity_Complete :
66263e ¤   ¤   return GM_VALIDITY_COMPLETE;
b39371 ¤   }
b7efe6 }
0aaf5a
75a3c6 //¤ ___________________________________________
52465d //
cbaff6 //¤ Get widths of control columns from prefs file
3aaf5a
13a1ba VOID·
febac1 GMGetColumnPreferences (PGROUPMAN pGM)
cbbb36 {
8f8f52 ¤   PGPError¤   ¤   ¤   err;
71697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
d6ca8a ¤   PGPSize¤¤   ¤   ¤   size;
45b63b ¤   PCOLUMNPREFSSTRUCT¤ pcps;
50b236 ¤   INT¤¤   ¤   ¤   ¤   i;
e8716d ¤   WORD¤   ¤   ¤   ¤   wField, wWidth;
a0af5a
8e030c ¤   pGM->wColumnField[GMI_NAME]¤¤   ¤   = 0;
d81902 ¤   pGM->wColumnField[GMI_VALIDITY]¤¤   = 1;
cfe26a ¤   pGM->wColumnField[GMI_DESCRIPTION]¤ = 2;
39af5a
5002c9 ¤   pGM->wFieldWidth[GMI_NAME]¤ ¤   ¤   = DEFAULTCOLWIDTHNAME;
479bc5 ¤   pGM->wFieldWidth[GMI_VALIDITY]¤ ¤   = DEFAULTCOLWIDTHVALID;
1bc66b ¤   pGM->wFieldWidth[GMI_DESCRIPTION]¤  = DEFAULTCOLWIDTHDESC;
baaf5a
17b6a3 ¤   pGM->lKeyListSortField¤ ¤   ¤   ¤   = kPGPUserIDOrdering;
2caf5a
84e9d4 ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pGM->context),
5b13a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
45b23e ¤   if (IsntPGPError (err)) {
460092 ¤   ¤   err = PGPGetPrefData (prefref, kPGPPrefPGPkeysWinGroupsData,
08556e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··&size, &pcps);
3daf5a
138536 ¤   ¤   if (IsntPGPError (err)) {
--6403 0000379ec06401102de Page 3 of GMMisc.c
45cac9 ¤   ¤   ¤   if (size == sizeof(COLUMNPREFSSTRUCT)) {
21dbf0 ¤   ¤   ¤   ¤   for (i=0; i<NUMBERFIELDS; i++) {
dcef8f ¤   ¤   ¤   ¤   ¤   wField = pcps->wColumnField[i];
2321c5 ¤   ¤   ¤   ¤   ¤   if ((wField >= 0) && (wField < NUMBERFIELDS))
493530 ¤   ¤   ¤   ¤   ¤   ¤   pGM->wColumnField[i] = wField;
8c19a2 ¤   ¤   ¤   ¤   ¤   wWidth = pcps->wFieldWidth[i];
08ed73 ¤   ¤   ¤   ¤   ¤   if ((wWidth >= MINWIDTH) && (wWidth <= MAXWIDTH))
5ee99e ¤   ¤   ¤   ¤   ¤   ¤   pGM->wFieldWidth[i] = wWidth;
122613 ¤   ¤   ¤   ¤   }
12e4dc ¤   ¤   ¤   ¤   pGM->lKeyListSortField = pcps->lSortField;
c6a3a6 ¤   ¤   ¤   }
4681f3 ¤   ¤   ¤   PGPDisposePrefData (prefref, pcps);
b60fe4 ¤   ¤   }
d4b30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
6f9371 ¤   }
76efe6 }
00af5a
65a3c6 //¤ ___________________________________________
11ac6a //·
b150ba //¤ Put window position information in registry
c7af5a
10a1ba VOID·
fcb55b GMSetColumnPreferences (PGROUPMAN pGM)·
55bb36 {
c48f52 ¤   PGPError¤   ¤   ¤   err;
23697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
48398d ¤   COLUMNPREFSSTRUCT¤  cps;
7cc23b ¤   INT¤¤   ¤   ¤   ¤   i, iField;
05af5a
3ce9d4 ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pGM->context),
2e13a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
8bb23e ¤   if (IsntPGPError (err)) {
e68fd5 ¤   ¤   for (i=0; i<NUMBERFIELDS; i++) {
2bf80e ¤   ¤   ¤   cps.wColumnField[i] = pGM->wColumnField[i];
c4af5a
11dd30 ¤   ¤   ¤   iField = pGM->wColumnField[i];
05d2b3 ¤   ¤   ¤   if ((i == 0) || (iField != 0)) pGM->wFieldWidth[iField] =·
e87149 ¤   ¤   ¤   ¤   ¤   LOWORD (TreeList_GetColumnWidth (pGM->hWndTree, i));
0d7efa ¤   ¤   ¤   cps.wFieldWidth[i] = pGM->wFieldWidth[i];
700fe4 ¤   ¤   }
49af5a
c318f1 ¤   ¤   cps.lSortField = pGM->lKeyListSortField;
faaf5a
4f6a1b ¤   ¤   PGPSetPrefData (prefref, kPGPPrefPGPkeysWinGroupsData,
3ff927 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··sizeof(cps), &cps);
5eaf5a
1631b9 ¤   ¤   PGPclCloseClientPrefs (prefref, TRUE);
9f9371 ¤   }
32efe6 }
0caf5a
3ba3c6 //¤ ___________________________________________
c0465d //
a0d6fa //¤ Get key from groupitem struct
bbaf5a
3df1ae static PGPError
0f7c1b sGroupItemToKey(
66619f ¤   PGPGroupItem const *¤   item,
b595e6 ¤   PGPKeySetRef¤   ¤   ¤   keySet,
e6abb1 ¤   PGPKeyRef *¤¤   ¤   ¤   outKey )
dbbb36 {
979372 ¤   PGPError¤   ¤   err¤= kPGPError_NoErr;
858a97 ¤   PGPContextRef¤  context;
1b67c5 ¤
e733b9 ¤   context¤= PGPGetKeySetContext( keySet );
4c67c5 ¤
839d51 ¤   err¤= PGPGetKeyByKeyID( keySet, &item->u.key.keyID,
a45b7c ¤   ¤   ¤   ¤   item->u.key.algorithm, outKey );
6667c5 ¤
37deb7 ¤   return( err );
81efe6 }
ea67c5 ¤
03a3c6 //¤ ___________________________________________
--b34a 00040d77e40401102de Page 4 of GMMisc.c
c1465d //
e70249 //¤ Sort on name callback routine
b1af5a
3711ec static INT
13201f sSortOnName (
f727e5 ¤   PGPGroupItem *¤ item1,
fec881 ¤   PGPGroupItem *¤ item2,
88c41f ¤   void *¤ ¤   ¤   userValue )
ccbb36 {
1e505d ¤   PGPKeyRef¤  ¤   key1;
ccbf39 ¤   PGPKeyRef¤  ¤   key2;
befee1 ¤   PGPError¤   ¤   err1;
ba1185 ¤   PGPError¤   ¤   err2;
8b4314 ¤   GMSortInfo const *¤ info¤   = (GMSortInfo const *)userValue;
786b59 ¤   PGPKeySetRef¤   keySet¤ = info->keySet;
fcb46b ¤   int¤¤   ¤   ¤   result;
b9c73e ¤   int¤¤   ¤   ¤   iInvert;
3887c7 ¤   ¤   ¤
a6ec24 ¤   keySet¤ = info->keySet;
d14a7a ¤   iInvert = info->iInvert;
4e67c5 ¤
22b09c ¤   if ( item1->type == kPGPGroupItem_Group ||
e751d6 ¤   ¤   ¤   item2->type == kPGPGroupItem_Group )
5ec7a1 ¤   {
c9d1a4 ¤   ¤   PGPGroupInfo¤   groupInfo1;
c33ec0 ¤   ¤   PGPGroupInfo¤   groupInfo2;
f01b52 ¤   ¤
a9aaf1 ¤   ¤   /* for now, always make groups come before keys */
cd9f47 ¤   ¤   if (item1->type == kPGPGroupItem_Group &&
61d1c2 ¤   ¤   ¤   item2->type == kPGPGroupItem_KeyID)
6f5b34 ¤   ¤   {
7ec245 ¤   ¤   ¤   return (-1 * iInvert);
380fe4 ¤   ¤   }
8f529e ¤   ¤   else if (item1->type == kPGPGroupItem_KeyID &&
f48fe8 ¤   ¤   ¤   item2->type == kPGPGroupItem_Group)
995b34 ¤   ¤   {
4ff3a4 ¤   ¤   ¤   return ( 1 * iInvert);
eb0fe4 ¤   ¤   }
8a9e22 ¤   ¤   /* both are groups */
3ea064 ¤   ¤   PGPGetGroupInfo (info->set, item1->u.group.id, &groupInfo1);
f686eb ¤   ¤   PGPGetGroupInfo (info->set, item2->u.group.id, &groupInfo2);
113572 ¤   ¤   return (lstrcmpi (groupInfo1.name, groupInfo2.name) * iInvert);
5e9371 ¤   }
7f67c5 ¤
b2d66a ¤   err1¤   = sGroupItemToKey (item1, keySet, &key1);
8545ac ¤   err2¤   = sGroupItemToKey (item2, keySet, &key2);
c467c5 ¤
9dd8af ¤   /*
a99cf4 ¤   ¤   Rules:
c899de ¤   ¤   errors on both: consider the same
9b544a ¤   ¤   error on one: it's always less than
569faa ¤   */
d27adf ¤   if (IsPGPError (err1) && IsPGPError (err2))
03c7a1 ¤   {
24d561 ¤   ¤   /* if we got errors on both, consider them the same */
49f109 ¤   ¤   return (0);
d39371 ¤   }
c50ecb ¤   else if (IsPGPError (err1))
9ec7a1 ¤   {
854e3a ¤   ¤   return (-1 * iInvert);
5b9371 ¤   }
be2b06 ¤   else if (IsPGPError (err2))
87c7a1 ¤   {
c97fdb ¤   ¤   return ( 1 * iInvert);
089371 ¤   }
7667c5 ¤
531a25 ¤   result¤ = PGPCompareKeys (key1, key2, kPGPUserIDOrdering);
4067c5 ¤
8a74e6 ¤   return (result * iInvert);
88efe6 }
1faf5a
40a3c6 //¤ ___________________________________________
--541e 0000866f70a401102de Page 5 of GMMisc.c
c1465d //
678262 //¤ Sort groupset based on selected criteria
04af5a
59c77d PGPError
86368b GMSortGroupSet (PGROUPMAN pGM)
b3bb36 {
1026d5 ¤   PGPError¤   err¤= kPGPError_NoErr;
ad5a39 ¤   GMSortInfo¤ info;
1867c5 ¤
520256 ¤   info.set¤   = pGM->groupsetMain;
a0d0cd ¤   info.keySet¤= pGM->keysetMain;
8467c5 ¤
a8290d ¤   switch (pGM->lKeyListSortField) {
f5279d ¤   case kPGPUserIDOrdering :
9e478f ¤   ¤   info.iInvert = 1;
2de191 ¤   ¤   err¤= PGPSortGroupSet (pGM->groupsetMain, sSortOnName, &info);
972f68 ¤   ¤   break;
87af5a
95065f ¤   case kPGPReverseUserIDOrdering :
72478f ¤   ¤   info.iInvert = 1;
c3e191 ¤   ¤   err¤= PGPSortGroupSet (pGM->groupsetMain, sSortOnName, &info);
752f68 ¤   ¤   break;
3daf5a
0fcea4 ¤   case kPGPValidityOrdering :
13478f ¤   ¤   info.iInvert = 1;
15e191 ¤   ¤   err¤= PGPSortGroupSet (pGM->groupsetMain, sSortOnName, &info);
5a2f68 ¤   ¤   break;
9aaf5a
3d0735 ¤   case kPGPReverseValidityOrdering :
64478f ¤   ¤   info.iInvert = 1;
d4e191 ¤   ¤   err¤= PGPSortGroupSet (pGM->groupsetMain, sSortOnName, &info);
d82f68 ¤   ¤   break;
909371 ¤   }
a567c5 ¤
cc9337 ¤   return (err);
7eefe6 }
1baf5a
e5af5a
c09268 //¤ _______________________________________________
17465d //
a2fa0d //¤ recursively add keys to list
a5465d //
1bb333 static VOID·
91c975 sAddKeysInGroup (PSERVERSTRUCT pss, PGPGroupID groupid)·
54bb36 {
e47d78 ¤   INT¤¤   ¤   ¤   i, iNumKeys, iNumTotal;
8d796a ¤   PGPGroupItem¤   groupitem;
5aaf5a
e7d7fe ¤   PGPCountGroupItems (pss->pGM->groupsetMain, groupid, FALSE,
5576ab ¤   ¤   ¤   ¤   &iNumKeys, &iNumTotal);
1eaf5a
2e82eb ¤   for (i=0; i<iNumTotal; i++) {
76677d ¤   ¤   PGPGetIndGroupItem (pss->pGM->groupsetMain, groupid, i, &groupitem);
6baf5a
d7c16d ¤   ¤   if (groupitem.type == kPGPGroupItem_KeyID) {
a4f220 ¤   ¤   ¤   pss->pkeyidList[pss->icount] =·
f61ecb ¤   ¤   ¤   ¤   groupitem.u.key.keyID;
9b92b0 ¤   ¤   ¤   ++(pss->icount);
360fe4 ¤   ¤   }
56af5a
0d9cea ¤   ¤   // otherwise it's a group
1407e0 ¤   ¤   else {
2aab40 ¤   ¤   ¤   sAddKeysInGroup (pss, groupitem.u.group.id);
f30fe4 ¤   ¤   }
569371 ¤   }
64efe6 }
1eaf5a
7a9268 //¤ _______________________________________________
fb465d //
ea0e71 //¤ routines called as callback functions from the·
0b12de // ·TreeList control
08af5a
--ff02 0009cc0efa6401102de Page 6 of GMMisc.c
9f3f64 static BOOL CALLBACK·
099b2b sCountSelectedObjects (
919d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
03dd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
71bb36 {
178925 ¤   SERVERSTRUCT*¤  pss¤¤   ¤   = (SERVERSTRUCT*)lParam;
03e7f3 ¤   PGPGroupID¤ ¤   groupid;
ce796a ¤   PGPGroupItem¤   groupitem;
4c96e8 ¤   INT¤¤   ¤   ¤   iNumKeys, iNumTotal;
560c32 ¤   INT¤¤   ¤   ¤   iIndex;
a1af5a
668cfe ¤   // is the current item a group ?
afcd24 ¤   if (lptli->iImage == IDX_GROUP) {
e627bb ¤   ¤   groupid = HIWORD(lptli->lParam);
f5fbf9 ¤   ¤   if (groupid) {
714997 ¤   ¤   ¤   iIndex = LOWORD(lptli->lParam);
2c831c ¤   ¤   ¤   PGPGetIndGroupItem (pss->pGM->groupsetMain, groupid, iIndex,
9886db ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &groupitem);
8b5fba ¤   ¤   ¤   groupid = groupitem.u.group.id;·
530fe4 ¤   ¤   }
577571 ¤   ¤   else groupid = LOWORD(lptli->lParam);
3caf5a
c98aaa ¤   ¤   PGPCountGroupItems (pss->pGM->groupsetMain, groupid, TRUE,
0476ab ¤   ¤   ¤   ¤   &iNumKeys, &iNumTotal);
551d0f ¤   ¤   pss->icount += iNumKeys;
cf9371 ¤   }
1aaf5a
ae92bf ¤   // otherwise, it's a key; count it
8bd8f5 ¤   else {·
6ca6ed ¤   ¤   ++(pss->icount);
509371 ¤   }
1faf5a
91c2e7 ¤   return TRUE;
92efe6 }
9daf5a
4c3f64 static BOOL CALLBACK·
61d0c6 sAddKeyIDToList (
c09d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
62dd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
a2bb36 {
b4a8fd ¤   SERVERSTRUCT*¤  pss = (SERVERSTRUCT*)lParam;
85c474 ¤   PGPGroupID¤ ¤   id;
4ee939 ¤   PGPUInt32¤  ¤   index;
70796a ¤   PGPGroupItem¤   groupitem;
1caf5a
4e25be ¤   id = HIWORD(lptli->lParam);
b71d9d ¤   index = LOWORD(lptli->lParam);
95af5a
f03415 ¤   // is it a root group?
847e29 ¤   if (id == 0) id = index;
d6af5a
45aeb8 ¤   // not a root group
84665a ¤   else {
7e0470 ¤   ¤   PGPGetIndGroupItem (pss->pGM->groupsetMain, id, index, &groupitem);
b1af5a
bda343 ¤   ¤   // is it a key ?
aac16d ¤   ¤   if (groupitem.type == kPGPGroupItem_KeyID) {
23d95a ¤   ¤   ¤   id = 0;
cbe9c1 ¤   ¤   ¤   pss->pkeyidList[pss->icount] =
531ecb ¤   ¤   ¤   ¤   groupitem.u.key.keyID;
75af5a
c492b0 ¤   ¤   ¤   ++(pss->icount);
440fe4 ¤   ¤   }
68af5a
2466f4 ¤   ¤   // not a key, it's a non-root group
33169d ¤   ¤   else id = groupitem.u.group.id;
c19371 ¤   }
b8af5a
666f0c ¤   // it's a group
774a04 ¤   if (id) {
59e5a1 ¤   ¤   sAddKeysInGroup (pss, id);
9c9371 ¤   }
--8ddb 000039e05ea401102de Page 7 of GMMisc.c
e0af5a
c4c2e7 ¤   return TRUE;
14efe6 }
baaf5a
f69268 //¤ _______________________________________________
fe465d //
3c5883 // ·Update selected group from server
f4af5a
db7efe BOOL·
b2ac97 GMGetFromServer (PGROUPMAN pGM)·
69bb36 {
480c8a ¤   SERVERSTRUCT¤   ss;
955c48 ¤   PGPKeySetRef¤   keysetFound¤= kPGPInvalidRef;
8bfb19 ¤   PGPError¤   ¤   err;
99af5a
5445ea ¤   ss.context = pGM->context;
9c2997 ¤   ss.pGM = pGM;
07af5a
aefbcc ¤   // get selected keys
63d282 ¤   ss.icount = 0;
bdcb3c ¤   ss.lpfnCallback = sCountSelectedObjects;
8f2ef7 ¤   TreeList_IterateSelected (pGM->hWndTree, &ss);
5b7684 ¤   if (ss.icount) {
85c41a ¤   ¤   ss.pkeyidList =·
219606 ¤   ¤   ¤   (PGPKeyID*)gmAlloc(ss.icount * sizeof(PGPKeyID));
77e96b ¤   ¤   ss.icount = 0;
4bafae ¤   ¤   ss.lpfnCallback = sAddKeyIDToList;
d33fd0 ¤   ¤   TreeList_IterateSelected (pGM->hWndTree, &ss);
6e89ab ¤   ¤   err = PGPclSearchServerForKeyIDs (pGM->context, pGM->tlsContext,
64c9cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   pGM->hWndParent, ss.pkeyidList,
b28dc2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ss.icount, PGPCL_DEFAULTSERVER,
8f33b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pGM->keysetMain, &keysetFound);
4a1fae ¤   ¤   gmFree (ss.pkeyidList);
2a9371 ¤   }
ea665a ¤   else {
b01fe7 ¤   ¤   PGPgmMessageBox (pGM->hWndParent, IDS_CAPTION,
b17d8f ¤   ¤   ¤   ¤   ¤   IDS_EMPTYGROUP, MB_OK|MB_ICONEXCLAMATION);
0c98aa ¤   ¤   return FALSE;
399371 ¤   }
6c67c5 ¤
39860b ¤   if (err == kPGPError_UserAbort) return FALSE;
aeaf5a
ac0971 ¤   if (IsPGPError (err)) {
8c94cd ¤   ¤   PGPclErrorBox (NULL, err);
819371 ¤   }
0b665a ¤   else {
1d3e28 ¤   ¤   if (PGPRefIsValid (keysetFound)) {
868190 ¤   ¤   ¤   PGPUInt32 u;
983df5 ¤   ¤   ¤   PGPCountKeys (keysetFound, &u);
940235 ¤   ¤   ¤   if (u > 0) {
c55dcc ¤   ¤   ¤   ¤   PGPclQueryAddKeys (pGM->context, pGM->tlsContext,
ab4094 ¤   ¤   ¤   ¤   ¤   ¤   pGM->hWndParent, keysetFound, pGM->keysetMain);
bea3a6 ¤   ¤   ¤   }
8ee543 ¤   ¤   ¤   else {
92183e ¤   ¤   ¤   ¤   PGPgmMessageBox (pGM->hWndParent, IDS_CAPTION,
b1f2b8 ¤   ¤   ¤   ¤   ¤   ¤   IDS_SERVERSEARCHFAIL, MB_OK|MB_ICONEXCLAMATION);
56a3a6 ¤   ¤   ¤   }
1b3900 ¤   ¤   ¤   PGPFreeKeySet (keysetFound);
e80fe4 ¤   ¤   }
1d9371 ¤   }
d3af5a
1ec2e7 ¤   return TRUE;
9befe6 }
acaf5a
929268 //¤ _______________________________________________
69465d //
065883 // ·Update selected group from server
a1af5a
40a1ba VOID·
0df2a8 GMGetGroupsFromServer (PGROUPMAN pGM)·
b1bb36 {
033ecb ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
--7658 000a5a1b27a401102de Page 8 of GMMisc.c
472b31 ¤   PGPGroupSetRef¤ groupset¤   = kInvalidPGPGroupSetRef;
76af5a
2134bb ¤   err = PGPclGetGroupsFromRootServer (
a16161 ¤   ¤   ¤   ¤   pGM->context,
9472b2 ¤   ¤   ¤   ¤   pGM->tlsContext,
795532 ¤   ¤   ¤   ¤   pGM->hWndParent,
2ca3e4 ¤   ¤   ¤   ¤   pGM->keysetMain,
0058f5 ¤   ¤   ¤   ¤   &groupset);
76af5a
c1f141 ¤   if (IsntPGPError (err) && PGPGroupSetRefIsValid (groupset))
09c7a1 ¤   {
14c530 ¤   ¤   err = PGPMergeGroupSets (groupset, pGM->groupsetMain);
5a00c0 ¤   ¤   if (IsntPGPError (err))·
d15b34 ¤   ¤   {
2e3f50 ¤   ¤   ¤   GMSortGroupSet (pGM);
193c09 ¤   ¤   ¤   GMCommitGroupChanges (pGM, TRUE);
1e09b1 ¤   ¤   ¤   GMLoadGroupsIntoTree (pGM, FALSE, TRUE, FALSE);
fdb6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
6b4774 ¤   ¤   ¤   UpdateWindow (pGM->hWndTree);
860fe4 ¤   ¤   }
ad07c4 ¤   ¤   PGPFreeGroupSet (groupset);
d99371 ¤   }
08af5a
09a32d ¤   PGPclErrorBox (pGM->hWndParent, err);
80efe6 }
faaf5a
629268 //¤ _______________________________________________
56465d //
36cb44 // ·Send groups to root server
ceaf5a
e1a1ba VOID·
5d27f8 GMSendGroupsToServer (PGROUPMAN pGM)·
96bb36 {
3f3ecb ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
122b31 ¤   PGPGroupSetRef¤ groupset¤   = kInvalidPGPGroupSetRef;
39af5a
67a2ce ¤   err = PGPclSendGroupsToRootServer (
7f6161 ¤   ¤   ¤   ¤   pGM->context,
d172b2 ¤   ¤   ¤   ¤   pGM->tlsContext,
255532 ¤   ¤   ¤   ¤   pGM->hWndParent,
61a3e4 ¤   ¤   ¤   ¤   pGM->keysetMain,
c6d5d6 ¤   ¤   ¤   ¤   pGM->groupsetMain);
e6af5a
a6a32d ¤   PGPclErrorBox (pGM->hWndParent, err);
dfefe6 }
b9af5a
544265 //¤ ___________________________________________________
94465d //
c89c3d // ·commit groups changes and broadcast reload message
c8af5a
b98de9 PGPError·
205674 GMCommitGroupChanges (PGROUPMAN pGM, BOOL bBroadcast)·
1bbb36 {
97af5a
333ecb ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
f9fa50 ¤   HCURSOR¤¤   ¤   hCursorOld;
6102e1 ¤   UINT¤   ¤   ¤   uReloadMessage;
a6af5a
d51dee ¤   if (PGPGroupSetNeedsCommit (pGM->groupsetMain)) {
56af5a
bbf63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
5b30b0 ¤   ¤   err = PGPclSaveGroupFile (pGM->pGroupFile);
9f7139 ¤   ¤   SetCursor (hCursorOld);
5caf5a
e5fbc6 ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err)) && bBroadcast) {
9589d8 ¤   ¤   ¤   uReloadMessage = RegisterWindowMessage (RELOADKEYRINGMSG);
180671 ¤   ¤   ¤   PostMessage (HWND_BROADCAST, uReloadMessage,·
4b6d6b ¤   ¤   ¤   ¤   MAKEWPARAM (LOWORD (pGM->hWndParent), FALSE),·
26794d ¤   ¤   ¤   ¤   GetCurrentProcessId ());
520fe4 ¤   ¤   }
b69371 ¤   }
a55ea8 ¤   return err;
--9f92 0011e84ee0a401102de Page 9 of GMMisc.c
7aefe6 }
46af5a
8eaf5a
79af5a
85af5a
1eaf5a
--c67e 00095e70785401102df Page 1 of GMNewGrp.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
9c18ec ¤   GMNewGrp.c - create new recipient group
7b67c5 ¤
e6af5a
a8bff8 ¤   $Id: GMNewGrp.c,v 1.14 1998/08/11 15:20:03 pbj Exp $
7bf7f7 ____________________________________________________________________________*/
fce610 #include "pgpPFLConfig.h"
b8af5a
77c917 // project header files
a23490 #include "pgpgmx.h"
9faf5a
c02b67 // typedefs·
b7f0f7 typedef struct {
cc2101 ¤   PGROUPMAN¤  ¤   pGM;
1705f5 ¤   PGPGroupSetRef¤ groupset;
aae7f3 ¤   PGPGroupID¤ ¤   groupid;
b65fe3 ¤   BOOL¤   ¤   ¤   bNewGroup;
ecfdcf ¤   CHAR¤   ¤   ¤   szGroupName[kPGPMaxGroupNameLength];
7a087d ¤   CHAR¤   ¤   ¤   szGroupDesc[kPGPMaxGroupDescriptionLength];
bea8b5 } NEWGROUPSTRUCT;
f5af5a
7393ed // external globals
209cad extern HINSTANCE g_hInst;
f0af5a
76492e // local globals
030a84 static DWORD aIds[] = {¤¤   ¤   // Help IDs
8eaaa1 ¤   IDC_NEWGROUPNAME,¤  IDH_PGPPKGRP_GROUPNAME,·
ac972e ¤   IDC_NEWGROUPDESC,¤  IDH_PGPPKGRP_GROUPDESC,
244434 ····0,0·
73a6fe };·
0caf5a
9aaf5a
704265 //¤ ___________________________________________________
ad465d //
f72d24 // ·Dialog Message procedure
2b15d1 //¤ When user asks to add a userID to a key, a dialog·
2f4674 //¤ appears asking for the new userID to be typed in.
bb0629 //¤ This is the message processing procedure for that
01d5b2 //¤ dialog.
daaf5a
5c3f64 static BOOL CALLBACK·
86d605 sNewGroupDlgProc (
f73a3a ¤   ¤   HWND¤   hDlg,·
8deb77 ¤   ¤   UINT¤   uMsg,·
ff0303 ¤   ¤   WPARAM¤ wParam,
cec0b8 ¤   ¤   LPARAM¤ lParam)·
77bb36 {
03af5a
0520aa ¤   NEWGROUPSTRUCT* pngs;
1bfb19 ¤   PGPError¤   ¤   err;
5eaf5a
bf31cf ¤   switch(uMsg) {
9aaf5a
6a2940 ¤   case WM_INITDIALOG:
3e1b9d ¤   ¤   pngs = (NEWGROUPSTRUCT*)lParam;
e27547 ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, lParam);
ca0046 ¤   ¤   SendDlgItemMessage (hDlg, IDC_NEWGROUPNAME, EM_SETLIMITTEXT,
a43559 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMaxGroupNameLength, 0);
d97da3 ¤   ¤   SendDlgItemMessage (hDlg, IDC_NEWGROUPDESC, EM_SETLIMITTEXT,
0ebcaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMaxGroupDescriptionLength, 0);
e4f160 ¤   ¤   if (!pngs->bNewGroup) {
5ae9f2 ¤   ¤   ¤   CHAR szTitle[64];
2c159a ¤   ¤   ¤   LoadString (g_hInst, IDS_GROUPPROPS, szTitle, sizeof(szTitle));
efe0e9 ¤   ¤   ¤   SetWindowText (hDlg, szTitle);
a18330 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_NEWGROUPNAME, pngs->szGroupName);
899409 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_NEWGROUPDESC, pngs->szGroupDesc);
6c0fe4 ¤   ¤   }
58836c ¤   ¤   return TRUE;
95af5a
--75cb 00096a7f0bf401102df Page 2 of GMNewGrp.c
bdc3eb ····case WM_HELP:·
4e2bad ¤   ¤   pngs = (NEWGROUPSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
4db947 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pngs->pGM->szHelpFile,·
de4eec ············HELP_WM_HELP, (DWORD) (LPSTR) aIds);·
048f13 ········break;·
ced83c ·
594fd8 ····case WM_CONTEXTMENU:·
a0aa96 ·¤  ¤   pngs = (NEWGROUPSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
887791 ¤   ¤   WinHelp ((HWND) wParam, pngs->pGM->szHelpFile, HELP_CONTEXTMENU,·
47faf0 ············(DWORD) (LPVOID) aIds);·
af8f13 ········break;·
f5af5a
db3fcf ¤   case WM_COMMAND:
87379d ¤   ¤   switch(LOWORD (wParam)) {
124672 ¤   ¤   case IDOK:·
5965da ¤   ¤   ¤   pngs = (NEWGROUPSTRUCT*)GetWindowLong (hDlg, GWL_USERDATA);
d9457e ¤   ¤   ¤   if (!GetDlgItemText (hDlg, IDC_NEWGROUPNAME, pngs->szGroupName,
d5ea02 ¤   ¤   ¤   ¤   sizeof (pngs->szGroupName))) {
3ca2c0 ¤   ¤   ¤   ¤   PGPgmMessageBox (hDlg, IDS_CAPTION, IDS_NEEDGROUPNAME,
5bdd7d ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
bb06e0 ¤   ¤   ¤   ¤   return TRUE;
86a3a6 ¤   ¤   ¤   }
18af5a
3bdae9 ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_NEWGROUPDESC, pngs->szGroupDesc,
81468f ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof (pngs->szGroupDesc));
41af5a
ae9e71 ¤   ¤   ¤   if (pngs->bNewGroup) {
bab932 ¤   ¤   ¤   ¤   err = PGPNewGroup (pngs->pGM->groupsetMain,·
b104c4 ¤   ¤   ¤   ¤   ¤   pngs->szGroupName, pngs->szGroupDesc, &(pngs->groupid));
f6a3a6 ¤   ¤   ¤   }
afe543 ¤   ¤   ¤   else {
2f5c22 ¤   ¤   ¤   ¤   err = PGPSetGroupName (pngs->pGM->groupsetMain,·
0716fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pngs->groupid, pngs->szGroupName);
f656ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
47838b ¤   ¤   ¤   ¤   ¤   err = PGPSetGroupDescription (pngs->pGM->groupsetMain,·
0fb240 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pngs->groupid, pngs->szGroupDesc);
662613 ¤   ¤   ¤   ¤   }
ada3a6 ¤   ¤   ¤   }
fdaf5a
db2fd3 ¤   ¤   ¤   if (IsPGPError (err)) {
46db72 ¤   ¤   ¤   ¤   PGPclErrorBox (NULL, err);
a7d206 ¤   ¤   ¤   ¤   EndDialog (hDlg, 0);
d606e0 ¤   ¤   ¤   ¤   return TRUE;
9ea3a6 ¤   ¤   ¤   }
04af5a
bbf3d5 ¤   ¤   ¤   EndDialog (hDlg, 1);
c532bd ¤   ¤   ¤   return TRUE;
65af5a
3871eb ¤   ¤   case IDCANCEL:
0fef6e ¤   ¤   ¤   EndDialog (hDlg, 0);
e132bd ¤   ¤   ¤   return TRUE;
f10fe4 ¤   ¤   }
34836c ¤   ¤   return TRUE;
2d9371 ¤   }
f6a230 ¤   return FALSE;
59efe6 }
01af5a
aa4265 //¤ ___________________________________________________
f2465d //
1388b6 // ·Update recipient group
e814e8 //¤ This routine is called when the user chooses to edit
5d9f4d //¤ recipient group properties
02af5a
057efe BOOL·
eabd8e GMGroupProperties (PGROUPMAN pGM)
04bb36 {
81bfb8 ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   = FALSE;
41796a ¤   PGPGroupItem¤   groupitem;
a9c5c8 ¤   PGPGroupInfo¤   groupinfo;
9f8b66 ¤   PGPUInt32¤  ¤   iIndex;
8c49d1 ¤   TL_TREEITEM¤¤   tli;
96c2c4 ¤   NEWGROUPSTRUCT¤ ngs;
--1f45 000b5f377a3401102df Page 3 of GMNewGrp.c
e0af5a
86a8bb ¤   // initialize struct
f9541b ¤   ngs.pGM = pGM;
458f7e ¤   ngs.bNewGroup = FALSE;
50af5a
0929e3 ¤   tli.hItem = GMFocusedItem (pGM);
02b6f1 ¤   tli.mask = TLIF_IMAGE|TLIF_PARAM;
4f5e4f ¤   TreeList_GetItem (pGM->hWndTree, &tli);
caaf5a
33a4fd ¤   // if selected item is a key, get its parent
dadc16 ¤   if (tli.iImage != IDX_GROUP) {
f72c0e ¤   ¤   tli.hItem = GMFocusedItem (pGM);
25c9fe ¤   ¤   tli.mask = TLIF_PARENTHANDLE;
83461f ¤   ¤   TreeList_GetItem (pGM->hWndTree, &tli);
80af5a
408a1f ¤   ¤   tli.mask = TLIF_IMAGE|TLIF_PARAM;
6c461f ¤   ¤   TreeList_GetItem (pGM->hWndTree, &tli);
209371 ¤   }
c7af5a
5ce95b ¤   // if selected item is a group then get the groupid
950538 ¤   if (tli.iImage == IDX_GROUP) {
1477c4 ¤   ¤   ngs.groupid = HIWORD(tli.lParam);
ed4338 ¤   ¤   if (ngs.groupid) {
948e03 ¤   ¤   ¤   iIndex = LOWORD(tli.lParam);
631617 ¤   ¤   ¤   PGPGetIndGroupItem (pGM->groupsetMain, ngs.groupid, iIndex,
3286db ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &groupitem);
78483c ¤   ¤   ¤   ngs.groupid = groupitem.u.group.id;·
ae0fe4 ¤   ¤   }
e341aa ¤   ¤   else ngs.groupid = LOWORD(tli.lParam);
dbaf5a
990184 ¤   ¤   PGPGetGroupInfo (pGM->groupsetMain, ngs.groupid, &groupinfo);
baeca8 ¤   ¤   lstrcpy (ngs.szGroupName, groupinfo.name);
f9b357 ¤   ¤   lstrcpy (ngs.szGroupDesc, groupinfo.description);
78af5a
039c2a ¤   ¤   // get new info from user
2c573a ¤   ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_NEWGROUP),·
c4a2e5 ¤   ¤   ¤   ¤   ¤   pGM->hWndParent, sNewGroupDlgProc, (LPARAM)&ngs)) {
a93f50 ¤   ¤   ¤   GMSortGroupSet (pGM);
753c09 ¤   ¤   ¤   GMCommitGroupChanges (pGM, TRUE);
2bfda0 ¤   ¤   ¤   PGPgmLoadGroups ((HGROUPMAN)pGM);
457cce ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, FALSE);
e54774 ¤   ¤   ¤   UpdateWindow (pGM->hWndTree);
608904 ¤   ¤   ¤   bRetVal = TRUE;¤¤   ¤
640fe4 ¤   ¤   }
269371 ¤   }
8aaf5a
861c35 ¤   return bRetVal;
92efe6 }
77af5a
604265 //¤ ___________________________________________________
f1465d //
1b0c00 // ·Create new recipient group
6a8dc9 //¤ This routine is called when the user chooses to create
3e755e //¤ a new recipient group
fdaf5a
cb5237 PGPError PGPgmExport
64eaef PGPgmNewGroup (HGROUPMAN hGroupMan)·
1abb36 {
dc0cf5 ¤   PGROUPMAN¤  ¤   pGM¤¤   ¤   ¤   = (PGROUPMAN)hGroupMan;
79bfb8 ¤   BOOL¤   ¤   ¤   bRetVal¤¤   ¤   = FALSE;
08c2c4 ¤   NEWGROUPSTRUCT¤ ngs;
85af5a
78a8bb ¤   // initialize struct
61541b ¤   ngs.pGM = pGM;
f2ee0b ¤   ngs.bNewGroup = TRUE;
4daf5a
5f1752 ¤   // get new group info from user
ff4219 ¤   if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_NEWGROUP),·
97ec92 ¤   ¤   ¤   ¤   pGM->hWndParent, sNewGroupDlgProc, (LPARAM)&ngs)) {
e205cc ¤   ¤   GMCommitGroupChanges (pGM, TRUE);
8b465d //
b56daf ¤   ¤   ¤   TreeList_DeleteTree (pGM->hWndTree, FALSE);
--1c5c 001eda8f88c401102df Page 4 of GMNewGrp.c
4cb6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
994774 ¤   ¤   ¤   UpdateWindow (pGM->hWndTree);
503f50 ¤   ¤   ¤   GMSortGroupSet (pGM);
e2de71 ¤   ¤   ¤   GMLoadGroupsIntoTree (pGM, TRUE, FALSE, FALSE);
3bb6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
26465d //
f2a618 //¤ ¤   GMLoadGroupsIntoTree (pGM, FALSE, FALSE, FALSE);·
673388 //¤ ¤   InvalidateRect (pGM->hWndTree, NULL, FALSE);
a37b9a ¤   ¤   UpdateWindow (pGM->hWndTree);
3cbe0c ¤   ¤   bRetVal = TRUE;¤¤   ¤
a39371 ¤   }
8caf5a
0e1c35 ¤   return bRetVal;
1aefe6 }
a6af5a
5f38e5 /*
366daf ¤   ¤   ¤   TreeList_DeleteTree (pGM->hWndTree, FALSE);
55b6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
104774 ¤   ¤   ¤   UpdateWindow (pGM->hWndTree);
593f50 ¤   ¤   ¤   GMSortGroupSet (pGM);
2ede71 ¤   ¤   ¤   GMLoadGroupsIntoTree (pGM, TRUE, FALSE, FALSE);
2eb6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
eddbe5 */¶
--b742 000589eadfc401102e0 Page 1 of GMNotPrc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
22a537 ¤   GMNotProc - notification processing and associated routines
b667c5 ¤
89af5a
073c4b ¤   $Id: GMNotPrc.c,v 1.17 1998/08/11 15:20:04 pbj Exp $
cdf7f7 ____________________________________________________________________________*/
89e610 #include "pgpPFLConfig.h"
f7af5a
ddc917 // project header files
703490 #include "pgpgmx.h"
dcaf5a
8c5584 // constant definitions
f7032c #define STATUS_MSG_PANE 1
f5af5a
5f822f // External globals
7f9cad extern HINSTANCE g_hInst;
06af5a
905bee // typedefs
29f0f7 typedef struct {
c09093 ¤   FARPROC lpfnCallback;
8cfeaa ¤   INT iObjectCount;
949f8b } SELOBJECTCOUNT;
e8af5a
90c8dc //¤ ________________________________________
0a465d //
9652a1 // ·Count a single object
11465d //
ae5110 //¤ lptli¤  = pointer to TreeList item to delete
b0af5a
113f64 static BOOL CALLBACK·
86d95a sCountSingleObject (
dd9d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
2fdd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
80bb36 {
8c11a8 ¤   SELOBJECTCOUNT*¤psoc = (SELOBJECTCOUNT*)lParam;
e41896 ¤   ++(psoc->iObjectCount);
25c2e7 ¤   return TRUE;
96efe6 }
48af5a
45a18c //¤ ____________________________________________
c2465d //
75863d // ·Update status bar text on basis of selection
60af5a
7ab333 static VOID·
c03fe3 sUpdateStatusBarText (PGROUPMAN pGM)·
9abb36 {
e8d923 ¤   CHAR sz1[128];
cf53f3 ¤   CHAR sz2[128];
14907b ¤   INT ids;
fcaa43 ¤   SELOBJECTCOUNT soc;
23af5a
f253d8 ¤   if (!pGM->hWndStatusBar) return;
f5af5a
41aadf ¤   switch (pGM->uSelectedFlags) {
a79f47 ¤   ¤   case 0 :¤   ¤   ¤   ¤   ids = 0;¤   ¤   ¤   ¤   ¤   break;
f36537 ¤   ¤   case PGPGM_GROUPFLAG :¤ ids = IDS_GROUPSELECTED;¤   break;
fd4e0e ¤   ¤   case PGPGM_KEYFLAG :¤   ids = IDS_KEYSELECTED;¤ ¤   break;
cad132 ¤   ¤   default :¤  ¤   ¤   ¤   ids = IDS_MULTISELECTED;¤   break;
879371 ¤   }
a2af5a
2d64a9 ¤   if (pGM->bMultipleSelected) {
33a107 ¤   ¤   soc.lpfnCallback = sCountSingleObject;
98ea01 ¤   ¤   soc.iObjectCount = 0;
f2efd6 ¤   ¤   TreeList_IterateSelected (pGM->hWndTree, &soc);
3f9371 ¤   }
e04264 ¤   else·
f3b0dd ¤   ¤   soc.iObjectCount = 1;
c3af5a
586ac4 ¤   if (ids) {
--46fc 00091b85217401102e0 Page 2 of GMNotPrc.c
914545 ¤   ¤   LoadString (g_hInst, ids, sz1, sizeof(sz1));
e93854 ¤   ¤   wsprintf (sz2, sz1, soc.iObjectCount);
439371 ¤   }
720e24 ¤   else
ae5109 ¤   ¤   lstrcpy (sz2, "");
f5af5a
9365e8 ¤   SendMessage (pGM->hWndStatusBar, SB_SETTEXT,·
5427c4 ¤   ¤   ¤   ¤   ¤   ¤   STATUS_MSG_PANE, (LPARAM)sz2);
53efe6 }
bdaf5a
2cc8dc //¤ ________________________________________
93465d //
e2f371 // ·Set handle of selected item.
709a76 // ·Type and pointer to object are retrieved from·
cb2d01 // ·TreeList as imagelist index.
41af5a
3ca1ba VOID·
801750 GMSetFocus (
b83970 ¤   ¤   PGROUPMAN¤  pGM,·
1220a2 ¤   ¤   HTLITEM¤¤   hFocused,·
da69ae ¤   ¤   BOOL¤   ¤   bMultiple)·
70bb36 {
dae723 ¤   TL_TREEITEM tli;
9faf5a
5c27a3 ¤   pGM->hFocusedItem = hFocused;
4b00a8 ¤   pGM->bMultipleSelected = bMultiple;
b4af5a
2e520e ¤   if (!bMultiple) pGM->uSelectedFlags = 0;
d5af5a
23861f ¤   if (hFocused) {·
4123da ¤   ¤   tli.hItem = hFocused;
5a4049 ¤   ¤   tli.mask = TLIF_IMAGE | TLIF_PARAM;
7de92d ¤   ¤   if (!TreeList_GetItem (pGM->hWndTree, &tli)) return;
b3417f ¤   ¤   pGM->iFocusedItemType = tli.iImage;
7d3183 ¤   ¤   pGM->pFocusedObject = (void*)tli.lParam;
d4bcfe ¤   ¤   switch (pGM->iFocusedItemType) {
983c77 ¤   ¤   ¤   case IDX_NONE :·
cdb0fd ¤   ¤   ¤   ¤   pGM->iFocusedObjectType = OBJECT_NONE;·
e8f622 ¤   ¤   ¤   ¤   break;
7baf5a
7ac636 ¤   ¤   ¤   case IDX_RSAPUBKEY :
4548e3 ¤   ¤   ¤   case IDX_RSAPUBDISKEY :
f8d8a9 ¤   ¤   ¤   case IDX_RSAPUBREVKEY :
c777b7 ¤   ¤   ¤   case IDX_RSAPUBEXPKEY :
b8d49c ¤   ¤   ¤   case IDX_RSASECKEY :
c4926f ¤   ¤   ¤   case IDX_RSASECDISKEY :
290225 ¤   ¤   ¤   case IDX_RSASECREVKEY :
e3ad3b ¤   ¤   ¤   case IDX_RSASECEXPKEY :
2a9a73 ¤   ¤   ¤   case IDX_RSASECSHRKEY :
7ad423 ¤   ¤   ¤   case IDX_DSAPUBKEY :
da52ea ¤   ¤   ¤   case IDX_DSAPUBDISKEY :
8ec2a0 ¤   ¤   ¤   case IDX_DSAPUBREVKEY :
6b6dbe ¤   ¤   ¤   case IDX_DSAPUBEXPKEY :
77c689 ¤   ¤   ¤   case IDX_DSASECKEY :
e98866 ¤   ¤   ¤   case IDX_DSASECDISKEY :
5a182c ¤   ¤   ¤   case IDX_DSASECREVKEY :
0a376a ¤   ¤   ¤   case IDX_DSASECEXPKEY :·
a0807a ¤   ¤   ¤   case IDX_DSASECSHRKEY :
294981 ¤   ¤   ¤   ¤   pGM->iFocusedObjectType = OBJECT_KEY;·
f06a33 ¤   ¤   ¤   ¤   pGM->uSelectedFlags |= PGPGM_KEYFLAG;
39f622 ¤   ¤   ¤   ¤   break;
70af5a
8a2b87 ¤   ¤   ¤   case IDX_GROUP :
707ec6 ¤   ¤   ¤   ¤   pGM->iFocusedObjectType = OBJECT_GROUP;·
3df331 ¤   ¤   ¤   ¤   pGM->uSelectedFlags |= PGPGM_GROUPFLAG;
e7f622 ¤   ¤   ¤   ¤   break;
0daf5a
1e0fe4 ¤   ¤   }
979371 ¤   }
08665a ¤   else {
171738 ¤   ¤   pGM->iFocusedItemType = IDX_NONE;
91f914 ¤   ¤   pGM->iFocusedObjectType = OBJECT_NONE;
--0c9f 0009f61dd1e401102e0 Page 3 of GMNotPrc.c
9b2d80 ¤   ¤   pGM->pFocusedObject = NULL;
149371 ¤   }
4daf5a
2e4a28 ¤   sUpdateStatusBarText (pGM);
71efe6 }
7baf5a
43c8dc //¤ ________________________________________
e3465d //
7c242b //¤ Get type of focused item
94af5a
b3100d INT·
5bc3ad GMFocusedItemType (PGROUPMAN pGM)·
73bb36 {
7d135a ¤   return pGM->iFocusedItemType;
81efe6 }
3daf5a
0ac8dc //¤ ________________________________________
22465d //
008cb3 //¤ Get type of focused object
5aaf5a
2f100d INT·
8a4065 GMFocusedObjectType (PGROUPMAN pGM)·
52bb36 {
c93079 ¤   return pGM->iFocusedObjectType;
caefe6 }
fbaf5a
30c8dc //¤ ________________________________________
6b465d //
498e39 //¤ Get handle of focused item
9eaf5a
42e167 HTLITEM·
8e810a GMFocusedItem (PGROUPMAN pGM)·
91bb36 {
6b6ddb ¤   return pGM->hFocusedItem;
28efe6 }
a0af5a
a9c8dc //¤ ________________________________________
8e465d //
3ff16e //¤ Get pointer to focused object
f2af5a
6bcb6b VOID* GMFocusedObject (PGROUPMAN pGM)·
ffbb36 {
f1387d ¤   return pGM->pFocusedObject;
aaefe6 }
1daf5a
dec8dc //¤ ________________________________________
7c465d //
2f8cb3 //¤ Get type of focused object
19af5a
4e7efe BOOL·
0286aa GMMultipleSelected (PGROUPMAN pGM)·
87bb36 {
55aead ¤   return pGM->bMultipleSelected;
e6efe6 }
81af5a
5bc8dc //¤ ________________________________________
8a465d //
2c8cb3 //¤ Get type of focused object
8aaf5a
1c44eb UINT·
cd95ad GMSelectedFlags (PGROUPMAN pGM)·
1fbb36 {
2b7a9b ¤   return pGM->uSelectedFlags;
99efe6 }
dcaf5a
6d4265 //¤ ___________________________________________________
2b465d //
0b9932 //¤ Return TRUE if more than one type of object selected
a0af5a
897efe BOOL·
82d5ec GMPromiscuousSelected (PGROUPMAN pGM)·
9fbb36 {
--fba6 0002930c5e1401102e0 Page 4 of GMNotPrc.c
58d2eb ¤   if (!pGM->bMultipleSelected) return FALSE;
84af5a
88aadf ¤   switch (pGM->uSelectedFlags) {
af741e ¤   case 0 :
2bbd4a ¤   case PGPGM_KEYFLAG :
be7d81 ¤   case PGPGM_GROUPFLAG :
0598aa ¤   ¤   return FALSE;
f5af5a
a5bfad ¤   default :
84836c ¤   ¤   return TRUE;
7c9371 ¤   }
8fefe6 }
2faf5a
a04265 //¤ ___________________________________________________
c6465d //
55a67d // ·create drag image
5faf5a
72b333 static VOID·
f2ca54 sBeginDrag (PGROUPMAN pGM)·
17bb36 {
e147fb ¤   HIMAGELIST¤ ¤   ¤   hIml;
d4a44e ¤   TL_DRAGBITMAP¤  ¤   tldb;
05d661 ¤   NONCLIENTMETRICS¤   ncm;
d7af5a
31ea15 ¤   // get offset number to convert client to window coordinates
edbbff ¤   ncm.cbSize = sizeof(NONCLIENTMETRICS);
1e3aec ¤   SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
fe2286 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ncm, 0);
f72109 ¤   pGM->iXCursorOffset = ncm.iBorderWidth;
e183be ¤   pGM->iYCursorOffset = ncm.iBorderWidth + ncm.iCaptionHeight;
4e4683 ¤   if (GetMenu (pGM->hWndParent))
963ecc ¤   ¤   pGM->iYCursorOffset += ncm.iMenuHeight;
22af5a
d50f6d ¤   GetCursorPos (&tldb.ptCursorPos);
97dc57 ¤   ScreenToClient (pGM->hWndTree, &tldb.ptCursorPos);
c696ce ¤   tldb.ulFlags = 0;
7c9ab2 ¤   TreeList_RenderDragBitmap (pGM->hWndTree, &tldb);
768e31 ¤   hIml = ImageList_Create (tldb.sizeDrag.cx, tldb.sizeDrag.cy,·
f76268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILC_MASK|ILC_COLORDDB, 1, 1);
3d043a ¤   ImageList_AddMasked (hIml, tldb.hbmDrag, GetSysColor (COLOR_WINDOW));
ff1cb0 ¤   DeleteObject (tldb.hbmDrag);
f0d83c ·
7be197 ¤   ImageList_BeginDrag (hIml, 0, tldb.ptHotSpot.x, tldb.ptHotSpot.y);
cbadd3 ¤   ImageList_Destroy (hIml);
75af5a
8c4b5b ¤   ImageList_DragEnter (pGM->hWndParent, tldb.ptCursorPos.x,·
c44fb9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tldb.ptCursorPos.y);
95efe6 }
afaf5a
9be6b2 static VOID
522ea4 sEndDrag (PGROUPMAN pGM) {
6f29e5 ¤   ImageList_DragLeave (pGM->hWndParent);
d2952e ¤   ImageList_EndDrag ();
1eefe6 }
3daf5a
a74265 //¤ ___________________________________________________
ff465d //
f77995 // ·reorder columns according to new header order
a7af5a
a2239b static VOID ·
5084ac sReorderColumns (PGROUPMAN pGM)
09bb36 {
7d93de ¤   INT¤¤   iOrderArray[NUMBERFIELDS];
299ca9 ¤   WORD¤   wColumnField[NUMBERFIELDS];
7d762c ¤   INT¤¤   i, iNumCols;
1faf5a
4e0ae2 ¤   // save order
682c15 ¤   GMSetColumnPreferences (pGM);
d3a064 ¤   iNumCols = 1;
1c8a38 ¤   for (i=0; i<NUMBERFIELDS; i++) {
799690 ¤   ¤   wColumnField[i] = pGM->wColumnField[i];
29140f ¤   ¤   if (wColumnField[i]) iNumCols++;
--6bdf 0007ae1a215401102e0 Page 5 of GMNotPrc.c
a19371 ¤   }
93af5a
29bf0b ¤   TreeList_GetOrderArray (pGM->hWndTree, iNumCols, &iOrderArray);
f5af5a
b3a60c ¤   for (i=0; i<iNumCols; i++) {
92bd77 ¤   ¤   pGM->wColumnField[i] = wColumnField[iOrderArray[i]];
c79371 ¤   }
a1af5a
e59774 ¤   TreeList_DeleteTree (pGM->hWndTree, TRUE);
6ee806 ¤   TreeList_DeleteAllColumns (pGM->hWndTree);
c5750d ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
cf94e9 ¤   UpdateWindow (pGM->hWndTree);
dd03e9 ¤   GMAddColumns (pGM);
fe8182 ¤   GMLoadGroupsIntoTree (pGM, FALSE, FALSE, TRUE);
16750d ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
2eaf5a
482c15 ¤   GMSetColumnPreferences (pGM);
7fefe6 }
6daf5a
724265 //¤ ___________________________________________________
de465d //
9f2120 // ·Group manager notification processing procedure
aeaf5a
3e6022 PGPError PGPgmExport·
a7a8d4 PGPgmDefaultNotificationProc (
0a5358 ¤   ¤   HGROUPMAN¤  hGM,·
c2cf0a ¤   ¤   LPARAM¤ ¤   lParam)·
82bb36 {
90f2bf ¤   PGROUPMAN¤  pGM = (PGROUPMAN)hGM;
a0af5a
7b9798 ¤   HTLITEM¤¤   hFocused;
cd24a7 ¤   BOOL¤   ¤   bMultiple;
5ee10a ¤   INT¤¤   ¤   i, iField;
ee805b ¤   POINT¤  ¤   pt;
80af5a
7a99d8 ¤   if (!hGM) return kPGPError_BadParams;
86af5a
f90600 ¤   switch (((LPNM_TREELIST)lParam)->hdr.code) {
b7af5a
cb39a9 ¤   case TLN_SELCHANGED :
967790 ¤   ¤   bMultiple = (((LPNM_TREELIST)lParam)->flags & TLC_MULTIPLE);
847d83 ¤   ¤   hFocused = ((LPNM_TREELIST)lParam)->itemNew.hItem;
81842f ¤   ¤   GMSetFocus (pGM, hFocused, bMultiple);
11a8b7 ¤   ¤   ((LPNM_TREELIST)lParam)->flags = GMSelectedFlags (pGM);
4b2f68 ¤   ¤   break;
eeaf5a
23ab00 ¤   case TLN_DRAGGEDOVER :
917d83 ¤   ¤   hFocused = ((LPNM_TREELIST)lParam)->itemNew.hItem;
0e8fc8 ¤   ¤   if (GMFocusedItem (pGM) != hFocused) {
ffb33c ¤   ¤   ¤   GMSetFocus (pGM, hFocused, FALSE);
5795d9 ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->flags = GMSelectedFlags (pGM);
98af5a
3260cf ¤   ¤   ¤   ImageList_DragLeave (pGM->hWndParent);
d9b6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
3b4774 ¤   ¤   ¤   UpdateWindow (pGM->hWndTree);
a7ecbe ¤   ¤   ¤   ImageList_DragEnter (pGM->hWndParent, 0, 0);
ed0fe4 ¤   ¤   }
5a5b3b ¤   ¤   pt = ((LPNM_TREELIST)lParam)->ptDrag;
109e07 ¤   ¤   MapWindowPoints (pGM->hWndTree, pGM->hWndParent, &pt, 1);
f1d029 ¤   ¤   ImageList_DragMove (pt.x + pGM->iXCursorOffset,·
f8d030 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pt.y + pGM->iYCursorOffset);
992f68 ¤   ¤   break;
00af5a
b136bd ¤   case TLN_AUTOSCROLLED :
0db87d ¤   ¤   ImageList_DragLeave (pGM->hWndParent);
63e34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
2a7b9a ¤   ¤   UpdateWindow (pGM->hWndTree);
17838d ¤   ¤   ImageList_DragEnter (pGM->hWndParent, 0, 0);
562f68 ¤   ¤   break;
1faf5a
796626 ¤   case TLN_KEYDOWN :
7a71ee ¤   ¤   switch (((TL_KEYDOWN*)lParam)->wVKey) {
--332e 001b836b4b6401102e0 Page 6 of GMNotPrc.c
93bbad ¤   ¤   case VK_DELETE :
e57ffe ¤   ¤   ¤   GMDeleteObject (pGM);
92cdcb ¤   ¤   ¤   break;
320fe4 ¤   ¤   }
602f68 ¤   ¤   break;
d3af5a
3d206f ¤   case TLN_CONTEXTMENU :
aea8b7 ¤   ¤   ((LPNM_TREELIST)lParam)->flags = GMSelectedFlags (pGM);
5b2f68 ¤   ¤   break;
f0af5a
b325e3 ¤   case TLN_HEADERREORDERED :
5943ec ¤   ¤   sReorderColumns (pGM);
5d2f68 ¤   ¤   break;
f7af5a
8ea0b9 ¤   case TLN_BEGINDRAG :
5bcbf3 ¤   ¤   pGM->hFocusedItemDragging = GMFocusedItem (pGM);
6eabb2 ¤   ¤   GMEnableDropTarget (pGM->pDropTarget, FALSE);
25ac73 ¤   ¤   sBeginDrag (pGM);
ef2f68 ¤   ¤   break;
6faf5a
c8b21b ¤   case TLN_DROP :
8bdf00 ¤   ¤   if (((LPNM_TREELIST)lParam)->index) {
b5b896 ¤   ¤   ¤   GMAddSelectedToFocused (pGM);
eb0fe4 ¤   ¤   }
ab7915 ¤   ¤   sEndDrag (pGM);
fe4f21 ¤   ¤   GMEnableDropTarget (pGM->pDropTarget, TRUE);
79408f ¤   ¤   GMSetFocus (pGM, pGM->hFocusedItemDragging, FALSE);
7d2f68 ¤   ¤   break;
f7af5a
08ccac ¤   case TLN_HEADERCLICKED :
f1bbcb ¤   ¤   i = pGM->lKeyListSortField;
8f77a0 ¤   ¤   iField = pGM->wColumnField[((LPNM_TREELIST)lParam)->index];
f0f657 ¤   ¤   switch (iField) {
a2ac44 ¤   ¤   ¤   case GMI_NAME :·
36c710 ¤   ¤   ¤   ¤   if (pGM->lKeyListSortField == kPGPUserIDOrdering)
4183f2 ¤   ¤   ¤   ¤   ¤   i = kPGPReverseUserIDOrdering;·
e45109 ¤   ¤   ¤   ¤   else·
ca9c32 ¤   ¤   ¤   ¤   ¤   i = kPGPUserIDOrdering;·
5df622 ¤   ¤   ¤   ¤   break;
21af5a
a6fbf5 ¤   ¤   ¤   case GMI_VALIDITY :
bbe40d ¤   ¤   ¤   ¤   if (pGM->lKeyListSortField == kPGPValidityOrdering)
66c38a ¤   ¤   ¤   ¤   ¤   i = kPGPReverseValidityOrdering;
c1fa07 ¤   ¤   ¤   ¤   else
d30599 ¤   ¤   ¤   ¤   ¤   i = kPGPValidityOrdering;
b0f622 ¤   ¤   ¤   ¤   break;
39af5a
19acef ¤   ¤   ¤   default : break;
630fe4 ¤   ¤   }
93e3f0 ¤   ¤   if (i != pGM->lKeyListSortField) {
60d94b ¤   ¤   ¤   pGM->lKeyListSortField = i;
976daf ¤   ¤   ¤   TreeList_DeleteTree (pGM->hWndTree, FALSE);
eab6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
934774 ¤   ¤   ¤   UpdateWindow (pGM->hWndTree);
e43f50 ¤   ¤   ¤   GMSortGroupSet (pGM);
f3de71 ¤   ¤   ¤   GMLoadGroupsIntoTree (pGM, TRUE, FALSE, FALSE);
e5b6e0 ¤   ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
af0fe4 ¤   ¤   }
292f68 ¤   ¤   break;
2e9371 ¤   }
0b3e6b ¤   return 0;
8befe6 }
b8af5a
--a3b3 000a5880465401102e1 Page 1 of GMOps.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
8f5898 ¤   GMTree.h - create and fill group manager control
9b67c5 ¤
6caf5a
2b7edf ¤   $Id: GMOps.c,v 1.26 1998/08/11 15:20:05 pbj Exp $
8af7f7 ____________________________________________________________________________*/
28e610 #include "pgpPFLConfig.h"
83af5a
fac917 // project header files
cc3490 #include "pgpgmx.h"
c7af5a
bdfc2c // system header files
b16bd4 #include <commdlg.h>
89af5a
8f5584 // constant definitions
12ffd5 #define BITMAP_WIDTH 16
c2c2a0 #define BITMAP_HEIGHT 16
56af5a
30873b #define VALIDITYTHRESHOLD 2
a53ce2 #define AXIOMATICTHRESHOLD 3
f2af5a
832b67 // typedefs·
a7f0f7 typedef struct {
409093 ¤   FARPROC lpfnCallback;
56939b ¤   PGPContextRef Context;
85aafb ¤   PGROUPMAN pGM;
4e3f6f ¤   LPSTR pszPrompt;
780d89 ¤   BOOL bItemModified;
bb7325 ¤   BOOL bRootGroupDeleted;
497207 ¤   BOOL bItemNotDeleted;
ed0bd9 ¤   BOOL bDeleteAll;
1f1f0d ¤   HTLITEM hPostDeleteFocusItem;
c5a2c6 } DELETESTRUCT;
cbaf5a
03f0f7 typedef struct {
3a9093 ¤   FARPROC lpfnCallback;
1aaafb ¤   PGROUPMAN pGM;
4b2b4d ¤   BOOL bFirst;
2abdb6 } LOCATESTRUCT;
4baf5a
23f0f7 typedef struct {
459093 ¤   FARPROC lpfnCallback;
69aafb ¤   PGROUPMAN pGM;
272118 ¤   PGPGroupID groupidDest;
cf5bfc ¤   BOOL bAdded;
95a55c } ADDSTRUCT;
0faf5a
54492e // local globals
57a8a5 static DWORD aDeleteAllIds[] = {¤   ¤   ¤   // Help IDs
a56059 ¤   IDOK,¤  ¤   ¤   ¤   IDH_PGPPKGRP_DELETEONE,·
6e7bfe ¤   IDC_YESTOALL,¤  ¤   IDH_PGPPKGRP_DELETEALL,
c06383 ¤   IDNO,¤  ¤   ¤   ¤   IDH_PGPPKGRP_DELETENO,
d6ceca ¤   IDCANCEL,¤  ¤   ¤   IDH_PGPPKGRP_DELETECANCEL,
c24434 ····0,0·
37a6fe };·
32af5a
5093ed // external globals
8c9cad extern HINSTANCE g_hInst;
9caf5a
08af5a
f9bf56 //----------------------------------------------------|
7101fb // Delete All dialog message procedure
39af5a
0b3f64 static BOOL CALLBACK·
753061 sDeleteAllDlgProc (
654669 ¤   ¤   HWND¤   hWndDlg,·
7deb77 ¤   ¤   UINT¤   uMsg,·
8f17d4 ¤   ¤   WPARAM¤ wParam,·
a5c0b8 ¤   ¤   LPARAM¤ lParam)·
--8309 0001d568c83401102e1 Page 2 of GMOps.c
2cbb36 {
835026 ¤   DELETESTRUCT* pds;
45af5a
4f347f ¤   switch (uMsg) {
43af5a
12ad3a ¤   case WM_INITDIALOG :
192ec5 ¤   ¤   SetWindowLong (hWndDlg, GWL_USERDATA, lParam);
813670 ¤   ¤   pds = (DELETESTRUCT*)lParam;
ab3aeb ¤   ¤   SetDlgItemText (hWndDlg, IDC_STRING, pds->pszPrompt);
de2f68 ¤   ¤   break;
32af5a
dec3eb ····case WM_HELP:·
a58e65 ¤   ¤   pds = (DELETESTRUCT*)GetWindowLong (hWndDlg, GWL_USERDATA);
119416 ········WinHelp (((LPHELPINFO) lParam)->hItemHandle, pds->pGM->szHelpFile,·
acd825 ············HELP_WM_HELP, (DWORD) (LPSTR) aDeleteAllIds);·
0d8f13 ········break;·
f4d83c ·
31daf9 ····case WM_CONTEXTMENU:
1b8e65 ¤   ¤   pds = (DELETESTRUCT*)GetWindowLong (hWndDlg, GWL_USERDATA);
454422 ········WinHelp ((HWND) wParam, pds->pGM->szHelpFile, HELP_CONTEXTMENU,·
09572a ············(DWORD) (LPVOID) aDeleteAllIds);·
038f13 ········break;·
b7af5a
8e3fcf ¤   case WM_COMMAND:
50af5a
88537d ¤   ¤   switch (LOWORD(wParam)) {
1b71eb ¤   ¤   case IDCANCEL:
05c012 ¤   ¤   ¤   pds = (DELETESTRUCT*)GetWindowLong (hWndDlg, GWL_USERDATA);
572041 ¤   ¤   ¤   pds->bItemNotDeleted = TRUE;
567baf ¤   ¤   ¤   EndDialog (hWndDlg, IDCANCEL);
bdcdcb ¤   ¤   ¤   break;
27af5a
af3860 ¤   ¤   case IDOK:
c4c20f ¤   ¤   case IDYES:
db9741 ¤   ¤   ¤   EndDialog (hWndDlg, IDYES);
cfcdcb ¤   ¤   ¤   break;
f5af5a
7347ba ¤   ¤   case IDNO:
16fd12 ¤   ¤   ¤   EndDialog (hWndDlg, IDNO);
a6cdcb ¤   ¤   ¤   break;
d3af5a
2c380a ¤   ¤   case IDC_YESTOALL :
92c012 ¤   ¤   ¤   pds = (DELETESTRUCT*)GetWindowLong (hWndDlg, GWL_USERDATA);
82ab92 ¤   ¤   ¤   pds->bDeleteAll = TRUE;
329741 ¤   ¤   ¤   EndDialog (hWndDlg, IDYES);
66cdcb ¤   ¤   ¤   break;
e60fe4 ¤   ¤   }
8c836c ¤   ¤   return TRUE;
3d9371 ¤   }
c6a230 ¤   return FALSE;
84efe6 }
a5af5a
8baf5a
b9bf56 //----------------------------------------------------|
9ee091 // ·Ask user for delete confirmation
dcaf5a
80083f static INT·
cd3a9d sDeleteConfirm (
9c9d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
dc6b96 ¤   ¤   INT¤¤   ¤   ¤   iPromptID,·
3d1556 ¤   ¤   DELETESTRUCT*¤  pds)·
d4bb36 {
7a2ee7 ¤   CHAR sz256[256];
068004 ¤   CHAR sz512[512];
11ebff ¤   INT iRetVal;
31af5a
8d8d96 ¤   if (pds->bDeleteAll) return IDYES;
79af5a
6d1fef ¤   LoadString (g_hInst, iPromptID, sz256, 256);·
132261 ¤   wsprintf (sz512, sz256, lptli->pszText);
17af5a
1d267d ¤   if (GMMultipleSelected (pds->pGM)) {
--2347 000321e707a401102e1 Page 3 of GMOps.c
00c98f ¤   ¤   pds->pszPrompt = sz512;
ffde53 ¤   ¤   iRetVal = DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_DELETEALL),·
0a7112 ¤   ¤   ¤   pds->pGM->hWndParent, sDeleteAllDlgProc, (LPARAM)pds);
49bf52 ¤   ¤   if (!pds->bItemNotDeleted && (iRetVal == IDNO)) {
e72041 ¤   ¤   ¤   pds->bItemNotDeleted = TRUE;
48ce31 ¤   ¤   ¤   pds->hPostDeleteFocusItem = lptli->hItem;
b20fe4 ¤   ¤   }
109371 ¤   }
cd665a ¤   else {
d52216 ¤   ¤   LoadString (g_hInst, IDS_DELCONFCAPTION, sz256, 256);
7016b9 ¤   ¤   iRetVal = MessageBox (pds->pGM->hWndParent, sz512, sz256,
22d7b7 ¤   ¤   ¤   ¤   MB_YESNO|MB_TASKMODAL|MB_DEFBUTTON2|MB_ICONWARNING);
259371 ¤   }
f9af5a
53b5f8 ¤   return iRetVal;
51efe6 }
99af5a
3eaf5a
1fbf56 //----------------------------------------------------|
7b0ba2 // ·Get handle of nearby item
cf465d //
3e13d1 //¤ lptli¤  = pointer to TreeList item
5aaf5a
fdd7b4 static HTLITEM·
0e63ba sGetAdjacentItem (
45bd0e ¤   ¤   HWND¤   ¤   ¤   hWndTree,·
97a4a1 ¤   ¤   TL_TREEITEM*¤   lptli)·
15bb36 {
84e723 ¤   TL_TREEITEM tli;
c8af5a
43d247 ¤   tli.hItem = lptli->hItem;
2901eb ¤   tli.mask = TLIF_NEXTHANDLE;
e94f6d ¤   TreeList_GetItem (hWndTree, &tli);
799f18 ¤   if (!tli.hItem) {
80e54f ¤   ¤   tli.hItem = lptli->hItem;
1cff77 ¤   ¤   tli.mask = TLIF_PREVHANDLE;
824121 ¤   ¤   TreeList_GetItem (hWndTree, &tli);
4f58ad ¤   ¤   if (!tli.hItem) {
870a3c ¤   ¤   ¤   tli.hItem = lptli->hItem;
d5f510 ¤   ¤   ¤   tli.mask = TLIF_PARENTHANDLE;
b2d0b9 ¤   ¤   ¤   TreeList_GetItem (hWndTree, &tli);
d50fe4 ¤   ¤   }
f99371 ¤   }
c9af5a
4324d3 ¤   return tli.hItem;
6defe6 }
9faf5a
81af5a
95bf56 //----------------------------------------------------|
579d74 // ·Delete a single object
d0cb1f //¤ routine called as a callback function from the TreeList control to·
b0b407 //¤ delete a single item.
6f465d //
e95110 //¤ lptli¤  = pointer to TreeList item to delete
98af5a
c53f64 static BOOL CALLBACK·
e87b1e sDeleteSingleObject (
819d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
3cdd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
88bb36 {
492907 ¤   DELETESTRUCT*¤  pds¤¤   ¤   = (DELETESTRUCT*)lParam;
25eb13 ¤   INT¤¤   ¤   ¤   iConfirm;
37e939 ¤   PGPUInt32¤  ¤   index;
13c474 ¤   PGPGroupID¤ ¤   id;
f0af5a
a46919 ¤   switch (lptli->iImage) {
b0af5a
b1178e ¤   // is it a group ?
78ae0b ¤   case IDX_GROUP :
cf63c2 ¤   ¤   iConfirm = sDeleteConfirm (lptli, IDS_DELCONFGROUP, pds);
7f1bb4 ¤   ¤   if (iConfirm == IDYES) {
326b17 ¤   ¤   ¤   id = HIWORD(lptli->lParam);
--32b5 00096871ca7401102e1 Page 4 of GMOps.c
5f5222 ¤   ¤   ¤   index = LOWORD(lptli->lParam);
03d833 ¤   ¤   ¤   // if hiword is non-zero, then it's a copy of a group
6cf52b ¤   ¤   ¤   if (id) {
f678c7 ¤   ¤   ¤   ¤   PGPDeleteIndItemFromGroup (pds->pGM->groupsetMain,·
97b7ce ¤   ¤   ¤   ¤   ¤   ¤   id, index);
a1a3a6 ¤   ¤   ¤   }
8aaf5a
fb19f9 ¤   ¤   ¤   // if hiword is zero, then it's a root group
c1e543 ¤   ¤   ¤   else {
e43b8a ¤   ¤   ¤   ¤   id = LOWORD(lptli->lParam);
d7fdef ¤   ¤   ¤   ¤   PGPDeleteGroup (pds->pGM->groupsetMain, id);
818e74 ¤   ¤   ¤   ¤   pds->bRootGroupDeleted = TRUE;
eda3a6 ¤   ¤   ¤   }
35af5a
8189cb ¤   ¤   ¤   pds->bItemModified = TRUE;
681d53 ¤   ¤   ¤   if (!pds->bItemNotDeleted)·
2e8a3a ¤   ¤   ¤   ¤   pds->hPostDeleteFocusItem =·
680c4f ¤   ¤   ¤   ¤   ¤   ¤   sGetAdjacentItem (pds->pGM->hWndTree, lptli);·
8b2326 ¤   ¤   ¤   TreeList_DeleteItem (pds->pGM->hWndTree, lptli);
2f0fe4 ¤   ¤   }
7a743c ¤   ¤   if (iConfirm == IDCANCEL) return FALSE;·
30a9fe ¤   ¤   else return TRUE;
a4af5a
2f0d7f ¤   // otherwise it's a key·
712f72 ¤   default:
e93660 ¤   ¤   iConfirm = sDeleteConfirm (lptli, IDS_DELCONFKEY, pds);
571bb4 ¤   ¤   if (iConfirm == IDYES) {
216b17 ¤   ¤   ¤   id = HIWORD(lptli->lParam);
445222 ¤   ¤   ¤   index = LOWORD(lptli->lParam);
0af52b ¤   ¤   ¤   if (id) {
dea515 ¤   ¤   ¤   ¤   PGPDeleteIndItemFromGroup (pds->pGM->groupsetMain, id, index);
e98787 ¤   ¤   ¤   ¤   pds->bItemModified = TRUE;
0d9535 ¤   ¤   ¤   ¤   if (!pds->bItemNotDeleted)·
40d8a7 ¤   ¤   ¤   ¤   ¤   pds->hPostDeleteFocusItem =·
2bdce4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sGetAdjacentItem (pds->pGM->hWndTree, lptli);·
64f90f ¤   ¤   ¤   ¤   TreeList_DeleteItem (pds->pGM->hWndTree, lptli);
5ea3a6 ¤   ¤   ¤   }
770fe4 ¤   ¤   }
93743c ¤   ¤   if (iConfirm == IDCANCEL) return FALSE;·
bba9fe ¤   ¤   else return TRUE;
2b9371 ¤   }
0befe6 }
8eaf5a
d54265 //¤ ___________________________________________________
6b465d //
7b14cf //¤ delete group or keys
7daf5a
527efe BOOL·
edbb41 GMDeleteObject (PGROUPMAN pGM)
e5bb36 {
7849d1 ¤   TL_TREEITEM¤¤   tli;
bb47cc ¤   DELETESTRUCT¤   ds;
12af5a
f04649 ¤   ds.lpfnCallback = sDeleteSingleObject;
65ceed ¤   ds.Context = pGM->context;
6e8fc7 ¤   ds.pGM = pGM;
9ee766 ¤   ds.bItemModified = FALSE;
2a7c7a ¤   ds.bRootGroupDeleted = FALSE;
ba6ffa ¤   ds.bDeleteAll = FALSE;
21f436 ¤   ds.bItemNotDeleted = FALSE;
660e06 ¤   ds.hPostDeleteFocusItem = NULL;
a1af5a
35aa6b ¤   TreeList_IterateSelected (pGM->hWndTree, &ds);
53af5a
2339a5 ¤   if (ds.bItemModified) {
3405cc ¤   ¤   GMCommitGroupChanges (pGM, TRUE);
48af5a
4f52fb ¤   ¤   if (ds.bRootGroupDeleted) {
475ee1 ¤   ¤   ¤   TreeList_DeleteTree (pGM->hWndTree, TRUE);
f558d2 ¤   ¤   ¤   GMAddColumns (pGM);
da3f50 ¤   ¤   ¤   GMSortGroupSet (pGM);
965b79 ¤   ¤   ¤   GMLoadGroupsIntoTree (pGM, FALSE, FALSE, TRUE);
--c373 000abaa50e2401102e1 Page 5 of GMOps.c
b50fe4 ¤   ¤   }
0aee26 ¤   ¤   else·
b5756b ¤   ¤   ¤   GMLoadGroupsIntoTree (pGM, FALSE, FALSE, FALSE);
d6af5a
19c2b7 ¤   ¤   if (ds.bItemNotDeleted) {
259ad7 ¤   ¤   ¤   if (ds.hPostDeleteFocusItem) {
e07d11 ¤   ¤   ¤   ¤   tli.hItem = ds.hPostDeleteFocusItem;
30e695 ¤   ¤   ¤   ¤   TreeList_Select (pGM->hWndTree, &tli, FALSE);
11a3a6 ¤   ¤   ¤   }
06eaae ¤   ¤   ¤   else GMSetFocus (pGM, NULL, FALSE);
890fe4 ¤   ¤   }
c407e0 ¤   ¤   else {
ff9ad7 ¤   ¤   ¤   if (ds.hPostDeleteFocusItem) {
727d11 ¤   ¤   ¤   ¤   tli.hItem = ds.hPostDeleteFocusItem;
e0149e ¤   ¤   ¤   ¤   TreeList_Select (pGM->hWndTree, &tli, TRUE);
621d4e ¤   ¤   ¤   ¤   tli.stateMask = TLIS_SELECTED;
1e212d ¤   ¤   ¤   ¤   tli.state = 0;
595b2e ¤   ¤   ¤   ¤   tli.mask = TLIF_STATE;
0dba9d ¤   ¤   ¤   ¤   TreeList_SetItem (pGM->hWndTree, &tli);
2fa3a6 ¤   ¤   ¤   }
afeaae ¤   ¤   ¤   else GMSetFocus (pGM, NULL, FALSE);
9d0fe4 ¤   ¤   }
7ee34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
d09371 ¤   }
d93a5c ¤   return (ds.bItemModified);
f5efe6 }
f5af5a
02bf56 //----------------------------------------------------|
e65c79 // ·Add a single object
78cb1f //¤ routine called as a callback function from the TreeList control to·
0515d2 //¤ add a single item.
d5465d //
8f5110 //¤ lptli¤  = pointer to TreeList item to delete
bfaf5a
b93f64 static BOOL CALLBACK·
47fdd9 sAddSingleObject (
ba9d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
c8dd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
61bb36 {
58454d ¤   ADDSTRUCT*¤ ¤   pas¤¤   ¤   = (ADDSTRUCT*)lParam;
89e939 ¤   PGPUInt32¤  ¤   index;
7cc474 ¤   PGPGroupID¤ ¤   id;
11796a ¤   PGPGroupItem¤   groupitem;
ebfb19 ¤   PGPError¤   ¤   err;
71af5a
f06919 ¤   switch (lptli->iImage) {
d5af5a
ca178e ¤   // is it a group ?
5bae0b ¤   case IDX_GROUP :
65ae42 ¤   ¤   id = HIWORD(lptli->lParam);
dfd8d8 ¤   ¤   if (!id) id = LOWORD(lptli->lParam);
51cfb1 ¤   ¤   if (id) {
b3dd74 ¤   ¤   ¤   if (id != pas->groupidDest) {
354408 ¤   ¤   ¤   ¤   groupitem.type = kPGPGroupItem_Group;
bcde7e ¤   ¤   ¤   ¤   groupitem.userValue = 0;
a5b148 ¤   ¤   ¤   ¤   groupitem.u.group.id = id;
7dd3a4 ¤   ¤   ¤   ¤   err = PGPAddItemToGroup (pas->pGM->groupsetMain,·
92be9a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &groupitem, pas->groupidDest);
45cd9e ¤   ¤   ¤   ¤   if (IsntPGPError (err)) pas->bAdded = TRUE;
52a3a6 ¤   ¤   ¤   }
130fe4 ¤   ¤   }
46836c ¤   ¤   return TRUE;
caaf5a
480d7f ¤   // otherwise it's a key·
a52f72 ¤   default:
bdae42 ¤   ¤   id = HIWORD(lptli->lParam);
455c6e ¤   ¤   index = LOWORD(lptli->lParam);
f0cfb1 ¤   ¤   if (id) {
754635 ¤   ¤   ¤   PGPGetIndGroupItem (pas->pGM->groupsetMain,·
a03ceb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   id, index, &groupitem);
4edb93 ¤   ¤   ¤   groupitem.userValue = 0;
ab1372 ¤   ¤   ¤   err = PGPAddItemToGroup (pas->pGM->groupsetMain, &groupitem,·
--8bc0 0006422e77a401102e1 Page 6 of GMOps.c
d7dd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pas->groupidDest);
0542c9 ¤   ¤   ¤   if (IsntPGPError (err)) pas->bAdded = TRUE;
a70fe4 ¤   ¤   }
c0836c ¤   ¤   return TRUE;
1e9371 ¤   }
10efe6 }
1eaf5a
5e9268 //¤ _______________________________________________
f0465d //
5ed33c // ·add selected items to focused group
02af5a
8d7efe BOOL·
21e973 GMAddSelectedToFocused (PGROUPMAN pGM)·
3bbb36 {
9e85e4 ¤   PGPGroupID¤ ¤   groupidDest;
da49d1 ¤   TL_TREEITEM¤¤   tli;
014fbf ¤   ADDSTRUCT¤  ¤   as;
b4af5a
ac29e3 ¤   tli.hItem = GMFocusedItem (pGM);
3fb6f1 ¤   tli.mask = TLIF_IMAGE|TLIF_PARAM;
b35e4f ¤   TreeList_GetItem (pGM->hWndTree, &tli);
f7af5a
6fe95b ¤   // if selected item is a group then get the groupid
a30538 ¤   if (tli.iImage == IDX_GROUP) {
c650ec ¤   ¤   groupidDest = HIWORD(tli.lParam);
617bb7 ¤   ¤   if (!groupidDest) groupidDest = LOWORD(tli.lParam);
339371 ¤   }
0faf5a
837f29 ¤   // otherwise it's a key, get the parent groupid
f5665a ¤   else {
c350ec ¤   ¤   groupidDest = HIWORD(tli.lParam);
129371 ¤   }
fcaf5a
4d0c6c ¤   if (groupidDest) {
e03e5b ¤   ¤   as.lpfnCallback = sAddSingleObject;
8a380e ¤   ¤   as.pGM = pGM;
79a0d1 ¤   ¤   as.groupidDest = groupidDest;
4e2bbf ¤   ¤   as.bAdded = FALSE;
efaf5a
139d18 ¤   ¤   TreeList_IterateSelected (pGM->hWndTree, &as);
479371 ¤   }
8267c5 ¤
0b4298 ¤   if (as.bAdded) {
8e0858 ¤   ¤   GMSortGroupSet (pGM);
3c05cc ¤   ¤   GMCommitGroupChanges (pGM, TRUE);
6e86e6 ¤   ¤   GMLoadGroupsIntoTree (pGM, FALSE, TRUE, FALSE);
1de34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
c87b9a ¤   ¤   UpdateWindow (pGM->hWndTree);
f59371 ¤   }
d7af5a
fec2e7 ¤   return TRUE;
b2efe6 }
bcaf5a
789268 //¤ _______________________________________________
01465d //
c669a6 // ·add keys to selected group
4caf5a
f67efe BOOL·
624b5c GMAddKeysToGroup (
74b420 ¤   ¤   PGROUPMAN¤  ¤   pGM,·
2ed026 ¤   ¤   PGPKeySetRef¤   keyset)·
e7bb36 {
79d125 ¤   PGPKeyListRef¤  keylist;
9bc323 ¤   PGPKeyIterRef¤  keyiter;
e81502 ¤   PGPKeyRef¤  ¤   key;
6ce7f3 ¤   PGPGroupID¤ ¤   groupid;
29796a ¤   PGPGroupItem¤   groupitem;
a949d1 ¤   TL_TREEITEM¤¤   tli;
f7af5a
8729e3 ¤   tli.hItem = GMFocusedItem (pGM);
19b6f1 ¤   tli.mask = TLIF_IMAGE|TLIF_PARAM;
645e4f ¤   TreeList_GetItem (pGM->hWndTree, &tli);
--cc1f 000958e7438401102e1 Page 7 of GMOps.c
e0af5a
39e95b ¤   // if selected item is a group then get the groupid
a80538 ¤   if (tli.iImage == IDX_GROUP) {
f3257f ¤   ¤   groupid = HIWORD(tli.lParam);
eed6cd ¤   ¤   if (!groupid) groupid = LOWORD(tli.lParam);
f79371 ¤   }
b0af5a
f47f29 ¤   // otherwise it's a key, get the parent groupid
53665a ¤   else {
b4257f ¤   ¤   groupid = HIWORD(tli.lParam);
299371 ¤   }
89af5a
1ac010 ¤   if (groupid) {
04278b ¤   ¤   PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
5ffa80 ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
21af5a
e33e9e ¤   ¤   PGPKeyIterNext (keyiter, &key);
82af5a
e5fcb4 ¤   ¤   while (key) {
e3b423 ¤   ¤   ¤   groupitem.type = kPGPGroupItem_KeyID;
5fdb93 ¤   ¤   ¤   groupitem.userValue = 0;
0bf217 ¤   ¤   ¤   PGPGetKeyNumber (key, kPGPKeyPropAlgID,·
8be760 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &groupitem.u.key.algorithm);
41af85 ¤   ¤   ¤   PGPGetKeyIDFromKey (key, &groupitem.u.key.keyID);
27af5a
2c0679 ¤   ¤   ¤   PGPAddItemToGroup (pGM->groupsetMain, &groupitem, groupid);
2eaf5a
c7b6f8 ¤   ¤   ¤   PGPKeyIterNext (keyiter, &key);
8c0fe4 ¤   ¤   }
df67c5 ¤
65e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
935a47 ¤   ¤   PGPFreeKeyList (keylist);
309371 ¤   }
1467c5 ¤
98c2e7 ¤   return TRUE;
98efe6 }
2caf5a
6b9268 //¤ _______________________________________________
20465d //
524964 // ·Drop text key(s)
60af5a
297efe BOOL·
46150b GMDropKeys (
a43970 ¤   ¤   PGROUPMAN¤  pGM,·
0de26e ¤   ¤   HANDLE¤ ¤   hMem)·
33bb36 {
dcfead ¤   PGPKeySetRef¤   keyset;
d9fb19 ¤   PGPError¤   ¤   err;
e2345d ¤   BOOL¤   ¤   ¤   bAdded;
7aee31 ¤   LPSTR¤  ¤   ¤   pMem;
88ff42 ¤   size_t¤ ¤   ¤   sLen;
78af5a
dcd785 ¤   bAdded = FALSE;
35805f ¤   if (hMem) {
8bad19 ¤   ¤   pMem = GlobalLock (hMem);
5461e8 ¤   ¤   if (pMem) {
1d23c0 ¤   ¤   ¤   sLen = lstrlen (pMem);
2b99d0 ¤   ¤   ¤   err =PGPImportKeySet (pGM->context, &keyset,·
8ae0c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputBuffer (pGM->context, pMem, sLen),
bee56d ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pGM->context));
eaa867 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err) &&·
f4bfc3 ¤   ¤   ¤   ¤   ¤   PGPRefIsValid (keyset))) {
5945ae ¤   ¤   ¤   ¤   PGPUInt32¤  numKeys;
535baf ¤   ¤   ¤   ¤   PGPCountKeys (keyset, &numKeys);
0e2b85 ¤   ¤   ¤   ¤
3af80f ¤   ¤   ¤   ¤   if (numKeys > 0) {
0f10e9 ¤   ¤   ¤   ¤   ¤   GMAddKeysToGroup (pGM, keyset);
64af5a
81494f ¤   ¤   ¤   ¤   ¤   TreeList_Select (pGM->hWndTree, NULL, TRUE);
d88763 ¤   ¤   ¤   ¤   ¤   GMSetFocus (pGM, NULL, FALSE);
b8af5a
9581ae ¤   ¤   ¤   ¤   ¤   bAdded = TRUE;
--2e33 000d67a2236401102e1 Page 8 of GMOps.c
862613 ¤   ¤   ¤   ¤   }
fdaf5a
65cdef ¤   ¤   ¤   ¤   PGPFreeKeySet (keyset);
f1a3a6 ¤   ¤   ¤   }
06501c ¤   ¤   ¤   GlobalUnlock (hMem);
160fe4 ¤   ¤   }
a49371 ¤   }
42af5a
ee9df9 ¤   if (bAdded) {
050858 ¤   ¤   GMSortGroupSet (pGM);
5405cc ¤   ¤   GMCommitGroupChanges (pGM, TRUE);
7e86e6 ¤   ¤   GMLoadGroupsIntoTree (pGM, FALSE, TRUE, FALSE);
8ae34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
f87b9a ¤   ¤   UpdateWindow (pGM->hWndTree);
929371 ¤   }
1567c5 ¤
05976d ¤   return bAdded;
a1efe6 }
0faf5a
249268 //¤ _______________________________________________
8b465d //
dfc277 // ·Paste key(s) from clipboard
8aaf5a
107efe BOOL·
24020b GMPasteKeys (PGROUPMAN pGM)·
8abb36 {
51345d ¤   BOOL¤   ¤   ¤   bAdded;
9492c9 ¤   HANDLE¤ ¤   ¤   hMem;
9aaf5a
1cd785 ¤   bAdded = FALSE;
45af5a
00c58a ¤   if (OpenClipboard (NULL)) {
7f6139 ¤   ¤   hMem = GetClipboardData (CF_TEXT);
f6172c ¤   ¤   if (hMem) {
27ff06 ¤   ¤   ¤   bAdded = GMDropKeys (pGM, hMem);
200fe4 ¤   ¤   }
ef0440 ¤   ¤   CloseClipboard ();
499371 ¤   }
59af5a
ef3750 ¤   if (!bAdded) {
66b6e2 ¤   ¤   PGPgmMessageBox (pGM->hWndParent, IDS_CAPTION,·
9f0e50 ¤   ¤   ¤   ¤   ¤   IDS_NOPASTEKEYS, MB_OK|MB_ICONEXCLAMATION);
c1af5a
e19371 ¤   }
5aaf5a
c5976d ¤   return bAdded;
5defe6 }
3baf5a
e6bf56 //----------------------------------------------------|
09de61 // ·Locate (ie. select) a single object
0bcb1f //¤ routine called as a callback function from the TreeList control to·
a7b407 //¤ delete a single item.
73465d //
d25110 //¤ lptli¤  = pointer to TreeList item to delete
03af5a
9c3f64 static BOOL CALLBACK·
a1156b sLocateSingleObject (
289d1c ¤   ¤   TL_TREEITEM*¤   lptli,·
b1dd27 ¤   ¤   LPARAM¤ ¤   ¤   lParam)·
c4bb36 {
223855 ¤   LOCATESTRUCT*¤  pls¤¤   ¤   = (LOCATESTRUCT*)lParam;
181502 ¤   PGPKeyRef¤  ¤   key;
1ee939 ¤   PGPUInt32¤  ¤   index;
0ac474 ¤   PGPGroupID¤ ¤   id;
fb796a ¤   PGPGroupItem¤   groupitem;
69fb19 ¤   PGPError¤   ¤   err;
63af5a
446919 ¤   switch (lptli->iImage) {
24af5a
1a178e ¤   // is it a group ?
59ae0b ¤   case IDX_GROUP :
d6836c ¤   ¤   return TRUE;
--4bf0 000d779f790401102e1 Page 9 of GMOps.c
e0af5a
590d7f ¤   // otherwise it's a key·
de2f72 ¤   default:
48ae42 ¤   ¤   id = HIWORD(lptli->lParam);
b95c6e ¤   ¤   index = LOWORD(lptli->lParam);
fecfb1 ¤   ¤   if (id) {
21b272 ¤   ¤   ¤   PGPGetIndGroupItem (pls->pGM->groupsetMain,·
1a3ceb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   id, index, &groupitem);
4daf5a
50f93d ¤   ¤   ¤   err = PGPGetKeyByKeyID (pls->pGM->keysetMain,
01345e ¤   ¤   ¤   ¤   ¤   ¤   &groupitem.u.key.keyID,·
d72b12 ¤   ¤   ¤   ¤   ¤   ¤   groupitem.u.key.algorithm, &key);
56af5a
226a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
e0ebfc ¤   ¤   ¤   ¤   PGPkmSelectKey (pls->pGM->hKM, key, pls->bFirst);
4f2e80 ¤   ¤   ¤   ¤   pls->bFirst = FALSE;
80a3a6 ¤   ¤   ¤   }
f8af5a
1e32bd ¤   ¤   ¤   return TRUE;
7a0fe4 ¤   ¤   }
d99371 ¤   }
a6efe6 }
b8af5a
354265 //¤ ___________________________________________________
fc465d //
1e2be4 //¤ select keys in main keys window
04af5a
a53ebf BOOL ·
2267d5 GMLocateKeys (PGROUPMAN pGM)
79bb36 {
85b9a9 ¤   LOCATESTRUCT¤   ls;
0daf5a
201aa6 ¤   ls.lpfnCallback = sLocateSingleObject;
9560a4 ¤   ls.pGM = pGM;
c41c8b ¤   ls.bFirst = TRUE;
50af5a
8ebd7d ¤   pGM->bLocatingKeys = TRUE;
e0f04b ¤   TreeList_IterateSelected (pGM->hWndTree, &ls);
08999c ¤   pGM->bLocatingKeys = FALSE;
c3af5a
70c2e7 ¤   return TRUE;
c5efe6 }
cfaf5a
7eaf5a
d89268 //¤ _______________________________________________
b8465d //
fca44a // ·Import groups from group file
a1465d //
f91e53 //¤ hDrop¤  == NULL¤=> prompt user for file name
324c03 //¤ ¤   ¤   != NULL => hDrop is a handle passed in from·
b23b14 //¤ ¤   ¤   ¤   ¤   ¤   the WM_DROPFILE message
9c465d //
abaf5a
ba7efe BOOL·
e0ecf3 GMImportGroups (
813970 ¤   ¤   PGROUPMAN¤  pGM,·
f89225 ¤   ¤   HDROP¤  ¤   hDrop)·
bebb36 {
d3a0c9 ¤   PGPGroupSetRef¤ groupset¤   ¤   ¤   = NULL;
5c0b76 ¤   OPENFILENAME¤   OpenFileName;
9863e2 ¤   CHAR¤   ¤   ¤   szFile[MAX_PATH];
7a0c1c ¤   CHAR¤   ¤   ¤   szFilter[256];
3a76ca ¤   CHAR¤   ¤   ¤   szTitle[64];
aecf2b ¤   CHAR*¤  ¤   ¤   p;
8a0c32 ¤   INT¤¤   ¤   ¤   iIndex;
0e3fcf ¤   BOOL¤   ¤   ¤   bImport;
29f366 ¤   PGPFileSpecRef¤ filespec;
77fb19 ¤   PGPError¤   ¤   err;
20af5a
3b525f ¤   // file was dropped
544d10 ¤   if (hDrop) {
d75ab6 ¤   ¤   iIndex = 0;
--62b5 0000b9bd07a401102e1 Page 10 of GMOps.c
8ff7f6 ¤   ¤   bImport = FALSE;
bafddc ¤   ¤   while (DragQueryFile (hDrop, iIndex, szFile, sizeof(szFile))) {
72f468 ¤   ¤   ¤   PGPNewFileSpecFromFullPath (pGM->context, szFile, &filespec);
3143c5 ¤   ¤   ¤   if (filespec) {
ca322a ¤   ¤   ¤   ¤   groupset = NULL;
ba5418 ¤   ¤   ¤   ¤   err = PGPNewGroupSetFromFile (pGM->context,·
184e58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filespec, &groupset);
c056ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
a48beb ¤   ¤   ¤   ¤   ¤   err = PGPMergeGroupSets (groupset, pGM->groupsetMain);
f6c70b ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err)) bImport = TRUE;
542613 ¤   ¤   ¤   ¤   }
9c750e ¤   ¤   ¤   ¤   if (groupset)
b452a7 ¤   ¤   ¤   ¤   ¤   PGPFreeGroupSet (groupset);
a97992 ¤   ¤   ¤   ¤   PGPFreeFileSpec (filespec);
05a3a6 ¤   ¤   ¤   }
051368 ¤   ¤   ¤   iIndex++;
910fe4 ¤   ¤   }
b69195 ¤   ¤   if (!bImport) {
8539b5 ¤   ¤   ¤   PGPgmMessageBox (pGM->hWndParent, IDS_CAPTION,·
4b313d ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_NOIMPORTGROUPS, MB_OK|MB_ICONEXCLAMATION);
360fe4 ¤   ¤   }
4c9371 ¤   }
62af5a
15aef4 ¤   // file wasn't dropped, prompt user for file name
2e665a ¤   else {
de8a55 ¤   ¤   lstrcpy (szFile, "");
f45683 ¤   ¤   LoadString (g_hInst, IDS_GROUPIMPORTFILTER,·
96e59f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFilter, sizeof(szFilter));
89b9c1 ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
ece96f ¤   ¤   LoadString (g_hInst, IDS_GROUPIMPORTCAPTION,·
0658eb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTitle, sizeof(szTitle));
e70181 ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
a22437 ¤   ¤   OpenFileName.hwndOwner ········= pGM->hWndParent;
77e4b2 ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
7da988 ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
721ec3 ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
c66424 ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
500d4e ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
3a2ff2 ¤   ¤   OpenFileName.lpstrFile ········= szFile;
60a0f3 ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (szFile);
393c53 ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
533f2d ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
d6df00 ¤   ¤   OpenFileName.lpstrInitialDir ··= NULL;
c86309 ¤   ¤   OpenFileName.lpstrTitle ·······= szTitle;
56a93d ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
31b537 ¤   ¤   OpenFileName.nFileOffset ······= 0;
ca7cea ¤   ¤   OpenFileName.nFileExtension ···= 0;
51a233 ¤   ¤   OpenFileName.lpstrDefExt ······= "";
1c53cd ¤   ¤   OpenFileName.lCustData ········= 0;
f9af5a
d0f7f6 ¤   ¤   bImport = FALSE;
57a55f ¤   ¤   if (GetOpenFileName (&OpenFileName)) {
94f468 ¤   ¤   ¤   PGPNewFileSpecFromFullPath (pGM->context, szFile, &filespec);
dd43c5 ¤   ¤   ¤   if (filespec) {
13322a ¤   ¤   ¤   ¤   groupset = NULL;
545418 ¤   ¤   ¤   ¤   err = PGPNewGroupSetFromFile (pGM->context,·
734e58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filespec, &groupset);
d756ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
508beb ¤   ¤   ¤   ¤   ¤   err = PGPMergeGroupSets (groupset, pGM->groupsetMain);
65c70b ¤   ¤   ¤   ¤   ¤   if (IsntPGPError (err)) bImport = TRUE;
2f2613 ¤   ¤   ¤   ¤   }
5d750e ¤   ¤   ¤   ¤   if (groupset)
4352a7 ¤   ¤   ¤   ¤   ¤   PGPFreeGroupSet (groupset);
377992 ¤   ¤   ¤   ¤   PGPFreeFileSpec (filespec);
f4a3a6 ¤   ¤   ¤   }
0567f0 ¤   ¤   ¤   if (!bImport) {
c2fda9 ¤   ¤   ¤   ¤   PGPgmMessageBox (pGM->hWndParent, IDS_CAPTION,·
72313d ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_NOIMPORTGROUPS, MB_OK|MB_ICONEXCLAMATION);
50a3a6 ¤   ¤   ¤   }
170fe4 ¤   ¤   }
409371 ¤   }
0baf5a
--7b0d 001e7e6f881401102e1 Page 11 of GMOps.c
49d300 ¤   if (bImport) {
f50858 ¤   ¤   GMSortGroupSet (pGM);
1505cc ¤   ¤   GMCommitGroupChanges (pGM, TRUE);
b986e6 ¤   ¤   GMLoadGroupsIntoTree (pGM, FALSE, TRUE, FALSE);
5fe34c ¤   ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
457b9a ¤   ¤   UpdateWindow (pGM->hWndTree);
799371 ¤   }
74af5a
040eef ¤   return bImport;
0befe6 }
5eaf5a
e7af5a
--075d 0009d59b253401102e2 Page 1 of GMTree.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
8f5898 ¤   GMTree.h - create and fill group manager control
9b67c5 ¤
6caf5a
0fd636 ¤   $Id: GMTree.c,v 1.34 1998/08/11 15:20:06 pbj Exp $
aff7f7 ____________________________________________________________________________*/
95e610 #include "pgpPFLConfig.h"
9baf5a
f4c917 // project header files
df3490 #include "pgpgmx.h"
90af5a
ec5584 // constant definitions
dfffd5 #define BITMAP_WIDTH 16
d8c2a0 #define BITMAP_HEIGHT 16
12af5a
3d93ed // external globals
9b9cad extern HINSTANCE g_hInst;
72af5a
714265 //¤ ___________________________________________________
32465d //
94a91f // ·Return handle of group manager window
10af5a
375a9c HWND ·
e1a001 PGPgmGetManagerWindow (HGROUPMAN hGM)·
c8bb36 {
216231 ¤   if (!hGM) return NULL;
101172 ¤   return (((PGROUPMAN)hGM)->hWndTree);
15efe6 }
49af5a
57af5a
014265 //¤ ___________________________________________________
4e465d //
d33833 // ·Insert column information into control
e8af5a
cf7efe BOOL·
273ffb GMAddColumns (PGROUPMAN pGM)·
dabb36 {
757894 ¤   TL_COLUMN tlc;
11f61c ¤   CHAR sz[64];
ff8dfc ¤   INT iField;·
2b9450 ¤   INT iCol, ids;
4caf5a
9ce806 ¤   TreeList_DeleteAllColumns (pGM->hWndTree);
9caf5a
a843d5 ¤   tlc.mask = TLCF_FMT | TLCF_WIDTH | TLCF_TEXT |·
95d085 ¤   ¤   ¤   ¤   TLCF_SUBITEM | TLCF_DATATYPE | TLCF_DATAMAX |
5ee832 ¤   ¤   ¤   ¤   TLCF_MOUSENOTIFY;
badef6 ¤   tlc.pszText = sz;
c3af5a
b4fee9 ¤   tlc.iSubItem = 0;
63b741 ¤   tlc.fmt = TLCFMT_LEFT;
49737a ¤   tlc.iDataType = TLC_DATASTRING;
a663d6 ¤   tlc.cx = pGM->wFieldWidth[0];
a98305 ¤   tlc.bMouseNotify = FALSE;
3ae8aa ¤   LoadString (g_hInst, IDS_GROUPNAMEFIELD, sz, sizeof(sz));
5fcc6e ¤   TreeList_InsertColumn (pGM->hWndTree, 0, &tlc);
8aaf5a
90f252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
2e20fa ¤   ¤   iField = pGM->wColumnField[iCol];
2a53ba ¤   ¤   if (iField) {
157f03 ¤   ¤   ¤   switch (iField) {
0a7009 ¤   ¤   ¤   ¤   case GMI_VALIDITY :
9f98db ¤   ¤   ¤   ¤   ¤   ids = IDS_VALIDITYFIELD;
0026f8 ¤   ¤   ¤   ¤   ¤   if (pGM->ulOptionFlags & GMF_NOVICEMODE)·
13b753 ¤   ¤   ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_IMAGE;
6b96bc ¤   ¤   ¤   ¤   ¤   else·
cf68fc ¤   ¤   ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LINBAR;
91dbef ¤   ¤   ¤   ¤   ¤   tlc.cchTextMax =·
9d8526 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GMConvertFromPGPValidity (kPGPValidity_Complete);
--9f7b 0000c5bc1b0401102e2 Page 2 of GMTree.c
1bdf81 ¤   ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATALONG;
f45e55 ¤   ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
ad14c3 ¤   ¤   ¤   ¤   ¤   break;
44af5a
32cbd5 ¤   ¤   ¤   ¤   case GMI_DESCRIPTION :
6015d5 ¤   ¤   ¤   ¤   ¤   ids = IDS_DESCRIPTIONFIELD;
de60a9 ¤   ¤   ¤   ¤   ¤   tlc.fmt = TLCFMT_LEFT;
adb058 ¤   ¤   ¤   ¤   ¤   tlc.iDataType = TLC_DATASTRING;
165e55 ¤   ¤   ¤   ¤   ¤   tlc.bMouseNotify = FALSE;
3e14c3 ¤   ¤   ¤   ¤   ¤   break;
01a3a6 ¤   ¤   ¤   }
989d98 ¤   ¤   ¤   LoadString (g_hInst, ids, sz, sizeof(sz));
55738d ¤   ¤   ¤   tlc.cx = pGM->wFieldWidth[iField];
6018c9 ¤   ¤   ¤   TreeList_InsertColumn (pGM->hWndTree, iCol, &tlc);
dd0fe4 ¤   ¤   }
cd9371 ¤   }
3aaf5a
1bc2e7 ¤   return TRUE;
16efe6 }
baaf5a
f94265 //¤ ___________________________________________________
32465d //
5d6ad9 // ·Create TreeList Window
96af5a
050969 HGROUPMAN·
1b61a3 PGPgmCreateGroupManager (
9019cc ¤   ¤   PGPContextRef¤  ¤   Context,·
42a960 ¤   ¤   PGPtlsContextRef¤   tlsContext,
6c2e03 ¤   ¤   HWND¤   ¤   ¤   ¤   hWndParent,·
19ab8b ¤   ¤   INT¤¤   ¤   ¤   ¤   iID,·
8f0a9f ¤   ¤   INT¤¤   ¤   ¤   ¤   x,·
0dfb12 ¤   ¤   INT¤¤   ¤   ¤   ¤   y,
720a42 ¤   ¤   INT¤¤   ¤   ¤   ¤   nWidth,·
a2dfa0 ¤   ¤   INT¤¤   ¤   ¤   ¤   nHeight)·
26bb36 {
70af5a
8d5543 ¤   HBITMAP¤¤   hBmp; ·····// handle to a bitmap
07b494 ¤   PGROUPMAN¤  pGM;
7018a8 ¤   HDC¤¤   ¤   hDC;
2f0863 ¤   INT¤¤   ¤   iNumBits;
6aaf5a
ab605e ¤   // Ensure that the common control DLL is loaded.
bc3500 ¤   InitCommonControls ();
14af5a
752593 ¤   // Ensure that the custom control DLL is loaded.
4b28bd ¤   InitTreeListControl ();
6baf5a
0cb0eb ¤   pGM = gmAlloc (sizeof (_GROUPMAN));
946bf1 ¤   if (!pGM) return NULL;
46278f ¤   memset (pGM, 0x00, sizeof (_GROUPMAN));
fcaf5a
275d5b ¤   pGM->hWndParent = hWndParent;
31a685 ¤   pGM->hWndTree = NULL;
9772de ¤   pGM->groupsetMain = NULL;
e45edc ¤   pGM->iID = iID;
38dd20 ¤   pGM->hIml = NULL;
40aa10 ¤   pGM->pDropTarget = NULL;¤   ¤   ¤   //pointer to DropTarget object
d24d53 ¤   lstrcpy (pGM->szHelpFile, "");¤ ¤   //string containing name of help file
aeaf5a
ffc581 ¤   pGM->context = Context;¤¤   ¤   //PGP context
db1551 ¤   pGM->tlsContext = tlsContext;
a95fa6 ¤   pGM->ulOptionFlags = 0;
fbeffd ¤   pGM->ulDisableActions = 0;
32af5a
32d9a3 ¤   pGM->bMultipleSelected = FALSE;
b5999c ¤   pGM->bLocatingKeys = FALSE;
260dd6 ¤   pGM->uSelectedFlags = 0;
8cbc74 ¤   pGM->iFocusedItemType = 0;
e43177 ¤   pGM->iFocusedObjectType = 0;
68e9d4 ¤   pGM->hFocusedItem = NULL;
eda67c ¤   pGM->pFocusedObject = NULL;
0caf5a
--0e03 0000a895be5401102e2 Page 3 of GMTree.c
cf41b3 ¤   pGM->iValidityThreshold = GM_VALIDITY_MARGINAL;
10af5a
378d72 ¤   GMGetColumnPreferences (pGM);
ceaf5a
2dc89f ¤   // Create the tree view window.
7e4eea ¤   pGM->hWndTree = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREELIST, "",
3a63f8 ¤   ¤   ¤   WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_GROUP |
265a91 ¤   ¤   ¤   TLS_HASBUTTONS | TLS_HASLINES | TLS_AUTOSCROLL |·
4f557d ¤   ¤   ¤   TLS_PROMISCUOUS | TLS_INTERNALDRAG | TLS_DRAGABLEHEADERS,
902d4c ¤   ¤   ¤   x, y, nWidth, nHeight,
81811b ¤   ¤   ¤   hWndParent, (HMENU)iID, g_hInst, NULL);
5baf5a
d2fab8 ¤   if (pGM->hWndTree == NULL) return NULL;
62af5a
f2acf4 ¤   // Initialize the tree view window.
1b642e ¤   // First create imagelist and load the appropriate bitmaps·
cc0078 ¤   // based on current display capabilities.
7567c5 ¤
977f5e ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
b089fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
3de693 ¤   ReleaseDC (NULL, hDC);
a2af5a
5c2be4 ¤   if (iNumBits <= 8) {
341c83 ¤   ¤   pGM->hIml =¤ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
e16d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
449694 ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
55a3d6 ¤   ¤   ImageList_AddMasked (pGM->hIml, hBmp, RGB(255, 0, 255));
1a5c8d ¤   ¤   DeleteObject (hBmp);
fe9371 ¤   }
d0665a ¤   else {
d1db2b ¤   ¤   pGM->hIml =¤ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
4e6d86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
f9bb8b ¤   ¤   hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
cda3d6 ¤   ¤   ImageList_AddMasked (pGM->hIml, hBmp, RGB(255, 0, 255));
605c8d ¤   ¤   DeleteObject (hBmp);
889371 ¤   }
52af5a
284110 ¤   // Associate the image list with the tree view control.
adfdc1 ¤   TreeList_SetImageList (pGM->hWndTree, pGM->hIml);
2caf5a
5d81f6 ¤   GMSetFocus (pGM, NULL, FALSE);
527128 ¤   pGM->pDropTarget = GMCreateDropTarget (pGM->hWndParent, (VOID*)pGM);·
72da03 ¤   CoLockObjectExternal ((IUnknown*)pGM->pDropTarget, TRUE, TRUE);
836a9b ¤   RegisterDragDrop (pGM->hWndTree, pGM->pDropTarget);
1205b3 ¤   GMEnableDropTarget (pGM->pDropTarget, FALSE);
b3af5a
5e8c1b ·¤  return (HGROUPMAN)pGM;
30efe6 }
faaf5a
14af5a
e54265 //¤ ___________________________________________________
02465d //
a64735 // ·Set (or add) a tree item to the tree
34af5a
31d7b4 static HTLITEM·
cbd9d0 sSetOneGroupItem (
613970 ¤   ¤   PGROUPMAN¤  pGM,·
3d1789 ¤   ¤   BOOL¤   ¤   bReInsert,·
d35390 ¤   ¤   HTLITEM¤¤   hItem,·
a2ef10 ¤   ¤   HTLITEM¤¤   hParent,·
80f042 ¤   ¤   LPSTR¤  ¤   szText,·
1444e3 ¤   ¤   HTLITEM¤¤   hInsAfter,·
bfc810 ¤   ¤   INT¤¤   ¤   iImage,·
58eec8 ¤   ¤   UINT¤   ¤   uState,·
b0cf0a ¤   ¤   LPARAM¤ ¤   lParam)·
ccbb36 {
e4e418 ¤   TL_TREEITEM tlI;
9ae1c1 ¤   TL_INSERTSTRUCT tlIns;
17af5a
f78cff ¤   tlI.hItem = hItem;
1690ac ¤   tlI.mask = TLIF_TEXT | TLIF_IMAGE | TLIF_STATE | TLIF_PARAM;
0aa75b ¤   tlI.stateMask = TLIS_BOLD | TLIS_ITALICS;
--fbc3 0007d9bf957401102e2 Page 4 of GMTree.c
b0ab60 ¤   tlI.stateMask |= uState;
a68d61 ¤   tlI.state = uState;
1b3ca6 ¤   tlI.pszText = szText;
125a98 ¤   tlI.cchTextMax = lstrlen (szText);
5088f8 ¤   tlI.iImage = iImage;
4ff485 ¤   tlI.iSelectedImage = iImage;
bfea06 ¤   tlI.lParam = lParam;
90af5a
355989 ¤   // Insert the data into the tree.
e1260a ¤   if (bReInsert || !hItem) {
6870a5 ¤   ¤   tlIns.item = tlI;
4d8837 ¤   ¤   tlIns.hInsertAfter = hInsAfter;
a405ae ¤   ¤   tlIns.hParent = hParent;
eb3432 ¤   ¤   return (TreeList_InsertItem (pGM->hWndTree, &tlIns));
109371 ¤   }
30665a ¤   else {
3bf623 ¤   ¤   TreeList_SetItem (pGM->hWndTree, &tlI);
cc1030 ¤   ¤   return hItem;
279371 ¤   }
2aefe6 }
d4af5a
21af5a
164265 //¤ ___________________________________________________
0c465d //
017bb0 // ·Set list data for a key
32af5a
53d7b4 static HTLITEM·
e345fd sSetGroupData (
cd3970 ¤   ¤   PGROUPMAN¤  pGM,·
bc5390 ¤   ¤   HTLITEM¤¤   hItem,·
d8bc98 ¤   ¤   PGPGroupID¤ groupid,·
f902c0 ¤   ¤   LPSTR¤  ¤   pszDesc)·
4d7142 {·
b7ab9f ¤   TL_LISTITEM tlL;
015c4c ¤   INT iField, iCol;
0daf5a
c473ad ¤   INT iValue, iNumNotFound;
0eaf5a
88dccc ¤   tlL.hItem = hItem;
5e030b ¤   tlL.stateMask = TLIS_VISIBLE;
ebaf5a
40f252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
0a20fa ¤   ¤   iField = pGM->wColumnField[iCol];
5453ba ¤   ¤   if (iField) {
747f03 ¤   ¤   ¤   switch (iField) {
c3fbf5 ¤   ¤   ¤   case GMI_VALIDITY :
aeffc2 ¤   ¤   ¤   ¤   tlL.pszText = NULL;
2eaf5a
e1c466 ¤   ¤   ¤   ¤   PGPGetGroupLowestValidity (pGM->groupsetMain, groupid,·
7bd659 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pGM->keysetMain, &iValue, &iNumNotFound);
58af5a
96278b ¤   ¤   ¤   ¤   if (iNumNotFound > 0) iValue = 0;
afe184 ¤   ¤   ¤   ¤   else iValue = GMConvertFromPGPValidity (iValue);
80af5a
0dfb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
51114e ¤   ¤   ¤   ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
723839 ¤   ¤   ¤   ¤   if (pGM->ulOptionFlags & GMF_NOVICEMODE) {
985e7b ¤   ¤   ¤   ¤   ¤   if (iValue > GM_VALIDITY_COMPLETE)
3b590e ¤   ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_AXIOMATIC;
710fe2 ¤   ¤   ¤   ¤   ¤   else if (iValue >= pGM->iValidityThreshold)·
ae4faa ¤   ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_VALID;
5c4380 ¤   ¤   ¤   ¤   ¤   else tlL.lDataValue = IDX_INVALID;
8c2613 ¤   ¤   ¤   ¤   }
8737aa ¤   ¤   ¤   ¤   else tlL.lDataValue = iValue;
03f622 ¤   ¤   ¤   ¤   break;
c3af5a
638a26 ¤   ¤   ¤   case GMI_DESCRIPTION :
3bfb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
a12903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
6c3781 ¤   ¤   ¤   ¤   tlL.pszText = pszDesc;
9cf622 ¤   ¤   ¤   ¤   break;
7daf5a
--ec37 000074d9855401102e2 Page 5 of GMTree.c
cfa3a6 ¤   ¤   ¤   }
d7deb2 ¤   ¤   ¤   tlL.iSubItem = iCol;
8dcb44 ¤   ¤   ¤   hItem = (HTLITEM) TreeList_SetListItem (pGM->hWndTree,·
351e8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tlL, FALSE);
270fe4 ¤   ¤   }
479371 ¤   }
01af5a
ea66c6 ¤   return (hItem);
f6efe6 }
bfaf5a
bcaf5a
dc4265 //¤ ___________________________________________________
77465d //
4f7bb0 // ·Set list data for a key
eeaf5a
37d7b4 static HTLITEM·
4ea4e4 sSetKeyData (
bb3970 ¤   ¤   PGROUPMAN¤  pGM,·
045390 ¤   ¤   HTLITEM¤¤   hItem,·
0c2888 ¤   ¤   PGPKeyRef¤  key,·
c102c0 ¤   ¤   LPSTR¤  ¤   pszDesc)·
4e7142 {·
d6be91 ¤   TL_LISTITEM¤tlL;
43b6b1 ¤   INT¤¤   ¤   iField, iCol;
24f462 ¤   PGPBoolean¤ bAxiomatic;
dcaf5a
367796 ¤   INT iValue;
e8af5a
addccc ¤   tlL.hItem = hItem;
d4030b ¤   tlL.stateMask = TLIS_VISIBLE;
c6af5a
9df252 ¤   for (iCol=1; iCol<NUMBERFIELDS; iCol++) {
0120fa ¤   ¤   iField = pGM->wColumnField[iCol];
9753ba ¤   ¤   if (iField) {
917f03 ¤   ¤   ¤   switch (iField) {
4ffbf5 ¤   ¤   ¤   case GMI_VALIDITY :
19dff4 ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDValidity (key, &iValue);
9e922c ¤   ¤   ¤   ¤   iValue = GMConvertFromPGPValidity (iValue);
8e5a68 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropIsAxiomatic, &bAxiomatic);
2c56bb ¤   ¤   ¤   ¤   if (bAxiomatic) iValue =·
b460ef ¤   ¤   ¤   ¤   ¤   ¤   GMConvertFromPGPValidity (kPGPValidity_Complete)+1;
05fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
cd114e ¤   ¤   ¤   ¤   tlL.mask = TLIF_DATAVALUE | TLIF_STATE;
233839 ¤   ¤   ¤   ¤   if (pGM->ulOptionFlags & GMF_NOVICEMODE) {
285e7b ¤   ¤   ¤   ¤   ¤   if (iValue > GM_VALIDITY_COMPLETE)
e9590e ¤   ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_AXIOMATIC;
a60fe2 ¤   ¤   ¤   ¤   ¤   else if (iValue >= pGM->iValidityThreshold)·
454faa ¤   ¤   ¤   ¤   ¤   ¤   tlL.lDataValue = IDX_VALID;
fb4380 ¤   ¤   ¤   ¤   ¤   else tlL.lDataValue = IDX_INVALID;
7b2613 ¤   ¤   ¤   ¤   }
a337aa ¤   ¤   ¤   ¤   else tlL.lDataValue = iValue;
dbf622 ¤   ¤   ¤   ¤   break;
4eaf5a
ae8a26 ¤   ¤   ¤   case GMI_DESCRIPTION :
c2fb20 ¤   ¤   ¤   ¤   tlL.state = TLIS_VISIBLE;
762903 ¤   ¤   ¤   ¤   tlL.mask = TLIF_TEXT | TLIF_STATE;
4f3781 ¤   ¤   ¤   ¤   tlL.pszText = pszDesc;
b9f622 ¤   ¤   ¤   ¤   break;
62af5a
91a3a6 ¤   ¤   ¤   }
eedeb2 ¤   ¤   ¤   tlL.iSubItem = iCol;
74cb44 ¤   ¤   ¤   hItem = (HTLITEM) TreeList_SetListItem (pGM->hWndTree,·
d11e8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tlL, FALSE);
ca0fe4 ¤   ¤   }
259371 ¤   }
f1af5a
e666c6 ¤   return (hItem);
84efe6 }
19af5a
5baf5a
ca4265 //¤ ___________________________________________________
07465d //
--6621 000916625d8401102e2 Page 6 of GMTree.c
33f1e1 // ·Determine the appropriate icon for a key, based on
801419 //¤ its properties
eeaf5a
80083f static INT·
98be60 sDetermineKeyIcon (PGPKeyRef Key, BOOL* lpbItalics)·
9dbb36 {
d7af5a
73fea0 ¤   PGPBoolean bRevoked, bSecret, bDisabled, bExpired, bSplit;
8031a4 ¤   PGPUInt32 iIdx, iAlg;
c0af5a
8f9734 ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsRevoked, &bRevoked);
a88a9b ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
63561e ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsDisabled, &bDisabled);
7dbfa8 ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsExpired, &bExpired);
6d8d1e ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecretShared, &bSplit);
5dc181 ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, &iAlg);
75af5a
da7651 ¤   if (iAlg == kPGPPublicKeyAlgorithm_RSA) {
c46059 ¤   ¤   if (bSecret) {
b3840f ¤   ¤   ¤   if (bRevoked) iIdx = IDX_RSASECREVKEY;
153985 ¤   ¤   ¤   else if (bExpired) iIdx = IDX_RSASECEXPKEY;
4da41d ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_RSASECDISKEY;
9d6431 ¤   ¤   ¤   else if (bSplit) iIdx = IDX_RSASECSHRKEY;
60eb72 ¤   ¤   ¤   else iIdx = IDX_RSASECKEY;
750fe4 ¤   ¤   }
0e07e0 ¤   ¤   else {
08e513 ¤   ¤   ¤   if (bRevoked) iIdx = IDX_RSAPUBREVKEY;
e65899 ¤   ¤   ¤   else if (bExpired) iIdx = IDX_RSAPUBEXPKEY;
47c501 ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_RSAPUBDISKEY;
6ed040 ¤   ¤   ¤   else iIdx = IDX_RSAPUBKEY;
eb0fe4 ¤   ¤   }
039371 ¤   }
84f0b1 ¤   // DSA/ElGamal
8e665a ¤   else {
676059 ¤   ¤   if (bSecret) {
905cb5 ¤   ¤   ¤   if (bRevoked) iIdx = IDX_DSASECREVKEY;
5ce13f ¤   ¤   ¤   else if (bExpired) iIdx = IDX_DSASECEXPKEY;
347ca7 ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_DSASECDISKEY;
95bc8b ¤   ¤   ¤   else if (bSplit) iIdx = IDX_DSASECSHRKEY;
af6f40 ¤   ¤   ¤   else iIdx = IDX_DSASECKEY;
710fe4 ¤   ¤   }
5a07e0 ¤   ¤   else {
693da9 ¤   ¤   ¤   if (bRevoked) iIdx = IDX_DSAPUBREVKEY;
c88023 ¤   ¤   ¤   else if (bExpired) iIdx = IDX_DSAPUBEXPKEY;
9e1dbb ¤   ¤   ¤   else if (bDisabled) iIdx = IDX_DSAPUBDISKEY;
915472 ¤   ¤   ¤   else iIdx = IDX_DSAPUBKEY;
050fe4 ¤   ¤   }
fb9371 ¤   }
9eaf5a
d1687a ¤   if (lpbItalics) *lpbItalics = bRevoked || bExpired || bDisabled;
11eadc ¤   return iIdx;
3befe6 }
bcaf5a
dcaf5a
d54265 //¤ ___________________________________________________
4e465d //
fdb519 // ·Reload a single group
deaf5a
73d7b4 static HTLITEM·
c7f3ea sReloadGroup (
3c3970 ¤   ¤   PGROUPMAN¤  pGM,·
afbc98 ¤   ¤   PGPGroupID¤ groupid,·
1a6bff ¤   ¤   INT¤¤   ¤   iIndex,
1b1789 ¤   ¤   BOOL¤   ¤   bReInsert,·
2d291a ¤   ¤   BOOL¤   ¤   bForceNewAlloc,·
a4de24 ¤   ¤   BOOL¤   ¤   bExpandNew,
6aeea7 ¤   ¤   BOOL¤   ¤   bFirstCall,·
bf264b ¤   ¤   HTLITEM¤¤   hTParent,·
7bc85d ¤   ¤   HTLITEM¤¤   hTPrev)·
a3bb36 {
5eaf5a
91eed1 ¤   HTLITEM¤¤   ¤   ¤   hTGroup, hTItem, hTItemPrev;
--b9c4 000adb362d9401102e2 Page 7 of GMTree.c
b50a2a ¤   TL_TREEITEM¤¤   ¤   tli;
20dda8 ¤   INT¤¤   ¤   ¤   ¤   i, iNumKeys, iNumTotal, idx;
24ee7e ¤   UINT¤   ¤   ¤   ¤   u, uState, uVal;
5036b9 ¤   BOOL¤   ¤   ¤   ¤   bNew, bItalics;
b0e7fb ¤   PGPGroupInfo¤   ¤   groupinfo;
599d03 ¤   PGPGroupItem¤   ¤   groupitem;
92453c ¤   PGPGroupID¤ ¤   ¤   groupidThis, groupidParent;
c923e3 ¤   PGPKeyRef¤  ¤   ¤   key;
718f52 ¤   PGPError¤   ¤   ¤   err;
3f6a12 ¤   CHAR¤   ¤   ¤   ¤   sz[kPGPMaxUserIDSize];
12304a ¤   CHAR¤   ¤   ¤   ¤   szID[kPGPMaxKeyIDStringSize];
d855b2 ¤   static BOOL¤¤   ¤   bNewKeyExpanded;
fcaf5a
556126 ¤   uState = 0;
bdcde0 ¤   bNew = FALSE;
477cea ¤   hTItem = NULL;
c7aeda ¤   hTItemPrev = TLI_FIRST;
a6af5a
d6e617 ¤   if (bFirstCall) bNewKeyExpanded = FALSE;
1aaf5a
93130f ¤   if (hTParent) {
322697 ¤   ¤   groupidParent = groupid;
93b110 ¤   ¤   PGPGetIndGroupItem (pGM->groupsetMain, groupidParent,·
286bd6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iIndex, &groupitem);
bcbb09 ¤   ¤   groupidThis = groupitem.u.group.id;
4c6a8f ¤   ¤   PGPGetGroupInfo (pGM->groupsetMain, groupidThis, &groupinfo);
f75840 ¤   ¤   hTGroup = groupitem.userValue;
7e9371 ¤   }
f2665a ¤   else {
18a91c ¤   ¤   groupidThis = groupid;
e56a8f ¤   ¤   PGPGetGroupInfo (pGM->groupsetMain, groupidThis, &groupinfo);
f4b3e6 ¤   ¤   hTGroup = groupinfo.userValue;
609371 ¤   }
ac68d1 ¤   if (!hTGroup) bNew = TRUE;
0daf5a
f17cc9 ¤   // determine icon and italics
5e66f2 ¤   idx = IDX_GROUP;
0eaf5a
6da96d ¤   // insert group item into tree and save pointer to tree item
30c9a6 ¤   if (bNew && bExpandNew) uState |= TLIS_SELECTED;
a855a4 ¤   if (bForceNewAlloc) hTGroup = NULL;
ee130f ¤   if (hTParent) {
392b4b ¤   ¤   uVal = MAKELONG (iIndex, groupidParent);
dfa0a6 ¤   ¤   hTGroup = sSetOneGroupItem (pGM, bReInsert, hTGroup, hTParent,·
7a933e ¤   ¤   ¤   ¤   ¤   groupinfo.name, hTPrev, idx, uState, uVal);
c67ee1 ¤   ¤   PGPSetIndGroupItemUserValue (pGM->groupsetMain, groupidParent,·
884aa3 ¤   ¤   ¤   ¤   ¤   iIndex, (PGPUserValue)hTGroup);
879371 ¤   }
a3665a ¤   else {
418212 ¤   ¤   uVal = MAKELONG (groupidThis, 0);
d4a0a6 ¤   ¤   hTGroup = sSetOneGroupItem (pGM, bReInsert, hTGroup, hTParent,·
a0933e ¤   ¤   ¤   ¤   ¤   groupinfo.name, hTPrev, idx, uState, uVal);
1bdac4 ¤   ¤   PGPSetGroupUserValue (pGM->groupsetMain, groupidThis,·
df8db2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUserValue)hTGroup);
ab9371 ¤   }
c0af5a
2dc4c3 ¤   // if a reinsertion, then we're done
47de71 ¤   if (bReInsert) return hTGroup;
25af5a
248379 ¤   sSetGroupData (pGM, hTGroup, groupidThis, groupinfo.description);
24af5a
e689dc ¤   // if not at root, then we don't draw items in group
e89640 ¤   if (hTParent) return hTGroup;
b8af5a
bfe83a ¤   // iterate through items in group
c4daca ¤   PGPCountGroupItems (pGM->groupsetMain, groupidThis, FALSE, &iNumKeys,
2904cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   &iNumTotal);
a2af5a
e482eb ¤   for (i=0; i<iNumTotal; i++) {
1facbd ¤   ¤   PGPGetIndGroupItem (pGM->groupsetMain, groupidThis, i, &groupitem);
aeaf5a
adc16d ¤   ¤   if (groupitem.type == kPGPGroupItem_KeyID) {
--ba50 000c58dddaa401102e2 Page 8 of GMTree.c
e0af5a
1a051e ¤   ¤   ¤   err = PGPGetKeyByKeyID (pGM->keysetMain,
88345e ¤   ¤   ¤   ¤   ¤   ¤   &groupitem.u.key.keyID,·
d72b12 ¤   ¤   ¤   ¤   ¤   ¤   groupitem.u.key.algorithm, &key);
64af5a
1199e2 ¤   ¤   ¤   if (IsntPGPError (err) && PGPRefIsValid (key)) {
527ac4 ¤   ¤   ¤   ¤   uState = 0;
9648ff ¤   ¤   ¤   ¤   hTItem = (HTLITEM)groupitem.userValue;
85dad7 ¤   ¤   ¤   ¤   if (!hTItem) bNew = TRUE;
4567c5 ¤
a049dc ¤   ¤   ¤   ¤   // get and set treelist tree data for this key
07b8dd ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (key, sizeof(sz), sz, &u);
f34c9c ¤   ¤   ¤   ¤   if (bForceNewAlloc) hTItem = NULL;
436fe7 ¤   ¤   ¤   ¤   idx = sDetermineKeyIcon (key, &bItalics);
0debc0 ¤   ¤   ¤   ¤   if (bItalics) uState |= TLIS_ITALICS;
31af5a
c7883a ¤   ¤   ¤   ¤   uVal = MAKELONG (i, groupidThis);
69be9a ¤   ¤   ¤   ¤   hTItem = sSetOneGroupItem (pGM, bReInsert, hTItem, hTGroup,·
a463b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz, hTItemPrev, idx, uState, uVal);
3daf5a
2419a7 ¤   ¤   ¤   ¤   PGPSetIndGroupItemUserValue (pGM->groupsetMain,
e38143 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   groupidThis, i, (PGPUserValue)hTItem);
88af5a
dd89f8 ¤   ¤   ¤   ¤   sSetKeyData (pGM, hTItem, key, "");
cfa3a6 ¤   ¤   ¤   }
6fe543 ¤   ¤   ¤   else {
3b48ff ¤   ¤   ¤   ¤   hTItem = (HTLITEM)groupitem.userValue;
81dad7 ¤   ¤   ¤   ¤   if (!hTItem) bNew = TRUE;
9f67c5 ¤
1249dc ¤   ¤   ¤   ¤   // get and set treelist tree data for this key
1b4c9c ¤   ¤   ¤   ¤   if (bForceNewAlloc) hTItem = NULL;
b52b26 ¤   ¤   ¤   ¤   if (groupitem.u.key.algorithm == kPGPPublicKeyAlgorithm_RSA)
a6cfe2 ¤   ¤   ¤   ¤   ¤   idx = IDX_RSAPUBDISKEY;
fafa07 ¤   ¤   ¤   ¤   else
9b1758 ¤   ¤   ¤   ¤   ¤   idx = IDX_DSAPUBDISKEY;
70af5a
a0872d ¤   ¤   ¤   ¤   uState = TLIS_ITALICS;
b9af5a
28b101 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_UNAVAILABLE, sz, sizeof(sz));
3cb0a5 ¤   ¤   ¤   ¤   PGPGetKeyIDString (&groupitem.u.key.keyID,·
3b660b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyIDString_Abbreviated, szID);
26534e ¤   ¤   ¤   ¤   lstrcat (sz, szID);
38af5a
71883a ¤   ¤   ¤   ¤   uVal = MAKELONG (i, groupidThis);
22be9a ¤   ¤   ¤   ¤   hTItem = sSetOneGroupItem (pGM, bReInsert, hTItem, hTGroup,·
2d2dcf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz, hTItemPrev, idx, uState, uVal);
eaaf5a
8c19a7 ¤   ¤   ¤   ¤   PGPSetIndGroupItemUserValue (pGM->groupsetMain,
bc8143 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   groupidThis, i, (PGPUserValue)hTItem);
60af5a
6fa3a6 ¤   ¤   ¤   }
7f0fe4 ¤   ¤   }
9eaf5a
85af59 ¤   ¤   // this is a group within a group
3b07e0 ¤   ¤   else {
d89767 ¤   ¤   ¤   hTItem = sReloadGroup (pGM, groupidThis, i, bReInsert,·
4c0443 ¤   ¤   ¤   ¤   ¤   bForceNewAlloc, bExpandNew, FALSE, hTGroup, hTItemPrev);
730fe4 ¤   ¤   }
11af5a
43b9ac ¤   ¤   hTItemPrev = hTItem;
1f9371 ¤   }
beaf5a
3c1329 ¤   // select and expand key, if appropriate·
073d80 ¤   if (bExpandNew && bNew) {
001c84 ¤   ¤   tli.hItem = hTGroup;
ceb137 ¤   ¤   if (!bNewKeyExpanded) {
6d322b ¤   ¤   ¤   TreeList_Select (pGM->hWndTree, &tli, TRUE);
4033de ¤   ¤   ¤   TreeList_Expand (pGM->hWndTree, &tli, TLE_EXPANDALL);
fd1a12 ¤   ¤   ¤   bNewKeyExpanded = TRUE;
7c0fe4 ¤   ¤   }
8207e0 ¤   ¤   else {
c57c4d ¤   ¤   ¤   GMSetFocus (pGM, GMFocusedItem (pGM), TRUE);
--bf7b 000eb70a6bd401102e2 Page 9 of GMTree.c
7033de ¤   ¤   ¤   TreeList_Expand (pGM->hWndTree, &tli, TLE_EXPANDALL);
670fe4 ¤   ¤   }
939371 ¤   }
5aaf5a
59bdb8 ¤   return hTGroup;
f3efe6 }
4aaf5a
2baf5a
d84265 //¤ ___________________________________________________
9b465d //
4bf81e // ·Scan entire groupset loading in any new data
ebaf5a
bb7efe BOOL·
2526a1 GMLoadGroupsIntoTree (
083970 ¤   ¤   PGROUPMAN¤  pGM,·
c31789 ¤   ¤   BOOL¤   ¤   bReInsert,·
2942b4 ¤   ¤   BOOL¤   ¤   bExpandNew,·
ff342f ¤   ¤   BOOL¤   ¤   bForceRealloc)·
e0bb36 {
8caf5a
6dfa50 ¤   HCURSOR¤¤   ¤   hCursorOld;
7b49d1 ¤   TL_TREEITEM¤¤   tli;
df6c79 ¤   HTLITEM¤¤   ¤   hTPrevKey;
3c44ec ¤   BOOL¤   ¤   ¤   bFirst;
44e7f3 ¤   PGPGroupID¤ ¤   groupid;
38329a ¤   INT¤¤   ¤   ¤   i, iNumGroups;
7faf5a
33e45b ¤   hTPrevKey = (HTLITEM)TLI_FIRST;
bbca72 ¤   bFirst = TRUE;
22af5a
5c035b ¤   if (pGM->groupsetMain) {
2af63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
c63607 ¤   ¤   PGPCountGroupsInSet (pGM->groupsetMain, &iNumGroups);
8caf5a
8a7826 ¤   ¤   for (i=0; i<iNumGroups; i++) {
7a471d ¤   ¤   ¤   PGPGetIndGroupID (pGM->groupsetMain, i, &groupid);
e8d39f ¤   ¤   ¤   hTPrevKey = sReloadGroup (pGM, groupid, 0, bReInsert,·
c2edec ¤   ¤   ¤   ¤   ¤   ¤   bForceRealloc, bExpandNew, bFirst, NULL, hTPrevKey);
6ced8d ¤   ¤   ¤   bFirst = FALSE;
b80fe4 ¤   ¤   }
1eaf5a
3d7139 ¤   ¤   SetCursor (hCursorOld);
306991 ¤   ¤   if (bExpandNew) {
472ab6 ¤   ¤   ¤   tli.hItem = GMFocusedItem (pGM);
395378 ¤   ¤   ¤   if (tli.hItem) TreeList_EnsureVisible (pGM->hWndTree, &tli);
310fe4 ¤   ¤   }
bb836c ¤   ¤   return TRUE;
bc9371 ¤   }
9befe6 }
13af5a
80af5a
ea4265 //¤ ___________________________________________________
c0465d //
f4605c // ·Cleanup group manager
1caf5a
fa8de9 PGPError·
36e20f PGPgmDestroyGroupManager (HGROUPMAN hGM)·
fdbb36 {
b5af5a
b38676 ¤   PGROUPMAN¤  ¤   pGM¤¤   ¤   ¤   ¤   = (PGROUPMAN)hGM;
66af5a
ab99d8 ¤   if (!hGM) return kPGPError_BadParams;
35af5a
292e69 ¤   RevokeDragDrop (pGM->hWndTree);
f6ee78 ¤   GMReleaseDropTarget (pGM->pDropTarget); ·
b7fbff ¤   CoLockObjectExternal ((IUnknown*)pGM->pDropTarget, FALSE, TRUE);
12af5a
017ad5 ¤   PGPclCloseGroupFile (pGM->pGroupFile);
b9af5a
972c15 ¤   GMSetColumnPreferences (pGM);
9eaf5a
ebec77 ¤   SendMessage (pGM->hWndTree, WM_CLOSE, 0, 0);
--65d8 00057983884401102e2 Page 10 of GMTree.c
043892 ¤   ImageList_Destroy (pGM->hIml);
d0af5a
c6151e ¤   return kPGPError_NoErr;
9eefe6 }
17af5a
744265 //¤ ___________________________________________________
c4465d //
141f28 // ·Map dragover screen coordinates to window coords
02af5a
997fc9 BOOL
f569be GMSelectGroup (PGROUPMAN pGM, POINTL ptl)
e8bb36 {
cda360 ¤   POINT¤  pt;
3baf5a
e07cd5 ¤   pt.x = ptl.x;
687398 ¤   pt.y = ptl.y;
727bbb ¤   MapWindowPoints (NULL, pGM->hWndTree, &pt, 1);
d1af5a
418ca0 ¤   return (TreeList_DragOver (pGM->hWndTree, MAKELONG (pt.x, pt.y)));
94efe6 }
e9af5a
564265 //¤ ___________________________________________________
36465d //
1d3e3b // ·Load keyset into treelist
6caf5a
068de9 PGPError·
237dbb PGPgmLoadGroups (HGROUPMAN hGroupMan)
45bb36 {
4c11e1 ¤   PGROUPMAN¤  ¤   pGM¤¤   ¤   = (PGROUPMAN)hGroupMan;
a1af5a
b8ac96 ¤   if (!pGM) return kPGPError_BadParams;
a2af5a
b7035b ¤   if (pGM->groupsetMain) {
fcc005 ¤   ¤   GMSetFocus (pGM, NULL, FALSE);
294fc6 ¤   ¤   TreeList_DeleteTree (pGM->hWndTree, TRUE);
62eb4d ¤   ¤   PGPclCloseGroupFile (pGM->pGroupFile);
0b45d6 ¤   ¤   pGM->groupsetMain = NULL;
dc9371 ¤   }
35af5a
1eab3a ¤   if (PGPRefIsValid (pGM->keysetMain)) {
a54196 ¤   ¤   PGPclOpenGroupFile (pGM->context, &(pGM->pGroupFile));
aa7a11 ¤   ¤   pGM->groupsetMain = pGM->pGroupFile->groupset;
fcaf5a
43f58c ¤   ¤   GMAddColumns (pGM);
7caf5a
a70858 ¤   ¤   GMSortGroupSet (pGM);
88d42e ¤   ¤   GMLoadGroupsIntoTree (pGM, FALSE, FALSE, TRUE);
c04f21 ¤   ¤   GMEnableDropTarget (pGM->pDropTarget, TRUE);
5c9371 ¤   }
12af5a
4a750d ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
3d94e9 ¤   UpdateWindow (pGM->hWndTree);
1aaf5a
47151e ¤   return kPGPError_NoErr;
5cefe6 }
bbaf5a
17af5a
064265 //¤ ___________________________________________________
b7465d //
4c3e3b // ·Load keyset into treelist
07af5a
826022 PGPError PGPgmExport·
892650 PGPgmReLoadGroups (HGROUPMAN hGroupMan)·
6bbb36 {
bf86b9 ¤   PGROUPMAN pGM = (PGROUPMAN)hGroupMan;
6aac96 ¤   if (!pGM) return kPGPError_BadParams;
00442a ¤   if (!pGM->groupsetMain) return kPGPError_BadParams;
81af5a
bd810c ¤   GMSortGroupSet (pGM);
9bd34a ¤   GMLoadGroupsIntoTree (pGM, FALSE, TRUE, FALSE);
2caf5a
57750d ¤   InvalidateRect (pGM->hWndTree, NULL, TRUE);
--33dd 0011c91044d401102e2 Page 11 of GMTree.c
9594e9 ¤   UpdateWindow (pGM->hWndTree);
8faf5a
c5151e ¤   return kPGPError_NoErr;
72efe6 }
26af5a
0a4265 //¤ ___________________________________________________
18465d //
d028b7 //¤ get PGPkeys path from registry and substitute Help file name·
1baf5a
8aa1ba VOID·
e6cab1 GMGetHelpFilePath (PGROUPMAN pGM)·
54bb36 {
30c9fb ¤   CHAR¤   sz[MAX_PATH];
2faf5a
6ea780 ¤   PGPclGetPGPPath (pGM->szHelpFile, sizeof(pGM->szHelpFile));
17e7c6 ¤   LoadString (g_hInst, IDS_HELPFILENAME, sz, sizeof(sz));
d8dc12 ¤   lstrcat (pGM->szHelpFile, sz);
88efe6 }
37af5a
c74265 //¤ ___________________________________________________
18465d //
7b3d90 // ·Set configuration
cfaf5a
656022 PGPError PGPgmExport·
c11adb PGPgmConfigure (
166354 ¤   ¤   HGROUPMAN¤  hGroupMan,·
4420ba ¤   ¤   LPGMCONFIG¤ pGMConfig)·
c6bb36 {
1886b9 ¤   PGROUPMAN pGM = (PGROUPMAN)hGroupMan;
11ac96 ¤   if (!pGM) return kPGPError_BadParams;
99af5a
88a240 ¤   if (pGM) {
425355 ¤   ¤   if (pGMConfig->lpszHelpFile)
89bb03 ¤   ¤   ¤   lstrcpy (pGM->szHelpFile, pGMConfig->lpszHelpFile);
03ee26 ¤   ¤   else·
e18604 ¤   ¤   ¤   GMGetHelpFilePath (pGM);
65af5a
684f06 ¤   ¤   pGM->hKM = pGMConfig->hKM;
1d4458 ¤   ¤   pGM->keysetMain = pGMConfig->keysetMain;
e7aa01 ¤   ¤   pGM->ulOptionFlags = pGMConfig->ulOptionFlags;
77b87f ¤   ¤   pGM->hWndStatusBar = pGMConfig->hWndStatusBar;
b8af5a
b9c876 ¤   ¤   if (pGM->ulOptionFlags & GMF_MARGASINVALID)·
243bfe ¤   ¤   ¤   pGM->iValidityThreshold = GM_VALIDITY_COMPLETE;
680e1d ¤   ¤   else
399b48 ¤   ¤   ¤   pGM->iValidityThreshold = GM_VALIDITY_MARGINAL;
4daf5a
82b840 ¤   ¤   return kPGPError_NoErr;
739371 ¤   }
69af5a
eedd95 ¤   else return kPGPError_BadParams;
bbaf5a
fdefe6 }
1caf5a
--8a4a 0004bd346ab401102e3 Page 1 of PGPgmx.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
327c1c ¤   PGPgmx.h - internal header file for Group Manager code
ca67c5 ¤
dbaf5a
902b08 ¤   $Id: PGPgmx.h,v 1.23 1998/08/11 15:20:06 pbj Exp $
e1f7f7 ____________________________________________________________________________*/
a29a0a #ifndef Included_PGPgmx_h¤  /* [ */
c69446 #define Included_PGPgmx_h
15af5a
6f2a68 #define WIN32_LEAN_AND_MEAN
3daf5a
7ed881 // Win32 header files
3a5655 #include <windows.h>
f290fb #include <commctrl.h>
0662da #include <ole2.h>
87dbcb #include <shellapi.h>
95af5a
557b85 // PGP build flags
aa81a4 #include "pgpBuildFlags.h"
f7af5a
2ad495 // PGP SDK header files
ab0d08 #include "pgpMem.h"
912f8d #include "pgpErrors.h"
744919 #include "pgpUtilities.h"
3aa076 #include "pgpKeys.h"
07c2ae #include "pgpGroups.h"
a2af5a
088687 // PGP client header files
208031 #include "resource.h"
af97e6 #include "..\include\pgpcl.h"
aabeb4 #include "..\include\treelist.h"
378af7 #include "..\include\pgpImage.h"
3a7835 #include "..\include\help\PGPpkHlp.h"
5faf5a
c3949b #define _PGPGMDLL
55bdfa #include "..\include\pgpkm.h"
7b8c0e #include "..\include\pgpgm.h"
3faf5a
f35584 // constant definitions
01af5a
0f8349 #define OBJECT_NONE¤¤   0
eebac8 #define OBJECT_GROUP¤   1
caec1b #define OBJECT_KEY¤ ¤   2
67af5a
6b7417 #define GMI_NAME¤   ¤   ¤   0
19d661 #define GMI_VALIDITY¤   ¤   1
e27c51 #define GMI_DESCRIPTION¤¤   2
397a83 #define NUMBERFIELDS¤   ¤   3
54af5a
ad2949 #define GM_VALIDITY_INVALID¤¤   0
f7184e #define GM_VALIDITY_MARGINAL¤   1
7517f7 #define GM_VALIDITY_COMPLETE¤   2
22af5a
331da1 // Manager global variables
4df0f7 typedef struct {
b37925 ¤   PGPContextRef¤  ¤   context;
60b4ac ¤   PGPtlsContextRef¤   tlsContext;
90af5a
e70a77 ¤   HWND¤   ¤   ¤   ¤   hWndParent;
69886b ¤   HWND¤   ¤   ¤   ¤   hWndTree;
7dfce5 ¤   INT¤¤   ¤   ¤   ¤   iID;
ebb86f ¤   HWND¤   ¤   ¤   ¤   hWndStatusBar;
baa30a ¤   HKEYMAN¤¤   ¤   ¤   hKM;
d747fb ¤   HIMAGELIST¤ ¤   ¤   hIml;
d7af5a
8f9d52 ¤   PGPKeySetRef¤   ¤   keysetMain;
ac274c ¤   PGPclGROUPFILE*¤¤   pGroupFile;
ea0c81 ¤   PGPGroupSetRef¤ ¤   groupsetMain;
4bed2c ¤   LPDROPTARGET¤   ¤   pDropTarget;¤   //pointer to DropTarget object
--7683 000857e4122401102e3 Page 2 of PGPgmx.h
9d2615 ¤   CHAR¤   ¤   ¤   ¤   szHelpFile[MAX_PATH];¤
1aaf5a
ac43d7 ¤   LONG¤   ¤   ¤   ¤   lKeyListSortField;¤ //keylist sort order
3aec49 ¤   ULONG¤  ¤   ¤   ¤   ulOptionFlags;
84a9dd ¤   ULONG¤  ¤   ¤   ¤   ulDisableActions;
3d9f4a ¤   ULONG¤  ¤   ¤   ¤   ulShowColumns;¤ ¤   // not used
a0a515 ¤   ULONG¤  ¤   ¤   ¤   ulHideColumns;¤ ¤   // not used
a1af5a
d670a8 ¤   BOOL¤   ¤   ¤   ¤   bMultipleSelected;
ae0ddd ¤   BOOL¤   ¤   ¤   ¤   bLocatingKeys;
8efd6f ¤   UINT¤   ¤   ¤   ¤   uSelectedFlags;
58f6da ¤   INT¤¤   ¤   ¤   ¤   iFocusedItemType;
b90c16 ¤   INT¤¤   ¤   ¤   ¤   iFocusedObjectType;
e553ff ¤   HTLITEM¤¤   ¤   ¤   hFocusedItem;
a594df ¤   VOID*¤  ¤   ¤   ¤   pFocusedObject;
d7af5a
fb22e6 ¤   HTLITEM¤¤   ¤   ¤   hFocusedItemDragging;
35af5a
b60c4b ¤   INT¤¤   ¤   ¤   ¤   iValidityThreshold;
edaf5a
779b8f ¤   INT¤¤   ¤   ¤   ¤   iXCursorOffset;
c2d3a5 ¤   INT¤¤   ¤   ¤   ¤   iYCursorOffset;
74af5a
1141ac ¤   WORD¤   ¤   ¤   ¤   wColumnField[NUMBERFIELDS];
09c379 ¤   WORD¤   ¤   ¤   ¤   wFieldWidth[NUMBERFIELDS];
47af5a
746446 } _GROUPMAN;
1ca5e6 typedef _GROUPMAN* PGROUPMAN;
e1af5a
97aa86 typedef struct _GM FAR* HGROUPMAN;
17af5a
044e6f // GMFocus.c
d3bdae VOID GMSetFocus (PGROUPMAN pGM, HTLITEM hFocused, BOOL bMultiple);
b7786d INT GMFocusedItemType (PGROUPMAN pGM);
e21ea1 INT GMFocusedObjectType (PGROUPMAN pGM);
df09e0 HTLITEM GMFocusedItem (PGROUPMAN pGM);
54ee07 VOID* GMFocusedObject (PGROUPMAN pGM);
62924a BOOL GMMultipleSelected (PGROUPMAN pGM);
ecf6b5 BOOL GMPromiscuousSelected (PGROUPMAN pGM);
5538ac UINT GMSelectedFlags (PGROUPMAN pGM);
152c9d BOOL GMSigningAllowed (PGROUPMAN pGM);
8346ad VOID GMGetSelectedObjects (PGROUPMAN ppGM, PGPKeySetRef* pKeySet,·
ac60ad ¤   ¤   ¤   ¤   ¤   ¤   ···LPSTR* pszKeyIDs);
8c795b VOID GMFreeSelectedObjects (PGPKeySetRef KeySet, LPSTR szKeyIDs);
67af5a
df7a3d // GMIDropTarget.cpp
2dc025 LPDROPTARGET GMCreateDropTarget (HWND hwnd, VOID* pGroupMan);
a1d020 VOID GMReleaseDropTarget (LPDROPTARGET pDropTarget);
fb3565 VOID GMEnableDropTarget (LPDROPTARGET pDropTarget, BOOL bEnable);
61af5a
7bbe44 // GMOps.c
172a7b BOOL GMPasteKeys (PGROUPMAN pGM);
8f5b87 BOOL GMLocateKeys (PGROUPMAN pGM);
28c358 BOOL GMDeleteObject (PGROUPMAN pGM);
c1aa37 BOOL GMAddSelectedToFocused (PGROUPMAN pGM);
697f26 BOOL GMImportGroups (PGROUPMAN pGM, HDROP hDrop);
b8af5a
4f2dc0 // GMMisc.c
710826 VOID* gmAlloc (LONG size);
af5971 VOID gmFree (VOID* p);
f89c5e LRESULT PGPgmMessageBox (HWND hWnd, INT iCaption, INT iMess, ULONG ulFlags);
8d5424 UINT GMConvertFromPGPValidity (UINT uPGPValidity);
c947e4 VOID GMGetColumnPreferences (PGROUPMAN pGM);
34165a PGPError GMSortGroupSet (PGROUPMAN pGM);
302211 BOOL GMGetFromServer (PGROUPMAN pGM);
618fe4 PGPError GMCommitGroupChanges (PGROUPMAN pGM, BOOL bBroadcast);
c547e4 VOID GMGetColumnPreferences (PGROUPMAN pGM);
bc00cc VOID GMSetColumnPreferences (PGROUPMAN pGM);
c28510 VOID GMGetGroupsFromServer (PGROUPMAN pGM);
6153c4 VOID GMSendGroupsToServer (PGROUPMAN pGM);
b0af5a
854391 // GMNewGrp.c
--1310 001ee36e404401102e3 Page 3 of PGPgmx.h
7b62db BOOL GMGroupProperties (PGROUPMAN pGM);
c9af5a
ba72e7 // GMTree.c
cdf3bd BOOL GMLoadGroupsIntoTree (PGROUPMAN pGM, BOOL bReInsert,·
5504c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bExpandNew, BOOL bForceRealloc);
d322b4 BOOL GMAddColumns (PGROUPMAN pGM);·
e6af5a
85af5a
b9af5a
8fc73d #endif /* ] Included_PGPgmx_h */
61af5a
e4af5a
1d7e4d /*__Editor_settings____
76af5a
0f4126 ¤   Local Variables:
377b17 ¤   tab-width: 4
b20e6c ¤   End:
d45f8c ¤   vi: ts=4 sw=4
2a9e9b ¤   vim: si
eed062 _____________________*/
--8a17 00098d768f3401102e4 Page 1 of PGPkeys.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
23b1b6 ¤   PGPkeys.c - PGPkeys WinMain, associated routines, and global variables
7367c5 ¤
1caf5a
bdbac2 ¤   $Id: PGPkeys.c,v 1.58 1998/08/11 15:20:07 pbj Exp $
f5f7f7 ____________________________________________________________________________*/
42e610 #include "pgpPFLConfig.h"
55af5a
56c917 // project header files
00c55a #include "pgpkeysx.h"
c7cbbd #include "..\include\PGPpk.h"
b7af5a
baad8c // pgp header files
75c9be #include "pgpRandomPool.h"
d9af5a
4dfc2c // system header files
5562da #include <ole2.h>
2a3ef0 #include <zmouse.h>
cbaf5a
4d5584 // constant definitions
0a67ae #define SPLASH_TIME¤¤   2500
a9af5a
795bee // typedefs
a5b320 typedef struct _DLGLISTSTRUCT {
a6fcd8 ¤   HWND¤   hwndDlg;
a3afc9 ¤   struct¤ _DLGLISTSTRUCT* nextItem;
1042f7 } DLGLISTSTRUCT, *PDLGLISTSTRUCT;
e6af5a
5de360 // Application global variables
56389d HINSTANCE¤  ¤   ¤   g_hInst;¤   ···········//handle of current instance
03d88c HWND¤   ¤   ¤   ¤   g_hWndMain;
9a70a4 UINT¤   ¤   ¤   ¤   g_uReloadKeyringMessage = 0;¤   //broadcast messages
d68b3b UINT¤   ¤   ¤   ¤   g_uReloadPrefsMessage = 0;¤
42cf55 UINT¤   ¤   ¤   ¤   g_uReloadKeyserverPrefsMessage = 0;¤
2ab629 UINT¤   ¤   ¤   ¤   g_uPurgePassphraseCacheMessage = 0;
39fac3 UINT¤   ¤   ¤   ¤   g_uMouseWheelMessage = 0;
0fbf64 PGPContextRef¤  ¤   g_Context;
5d6148 PGPtlsContextRef¤   g_TLSContext = kInvalidPGPtlsContextRef;
ec015e CHAR¤   ¤   ¤   ¤   g_szHelpFile[MAX_PATH];
1172ee PGPBoolean¤ ¤   ¤   g_bKeyGenEnabled = TRUE;
57b8a0 PGPBoolean¤ ¤   ¤   g_bExpertMode = FALSE;
94ddd6 PGPBoolean¤ ¤   ¤   g_bMarginalAsInvalid = FALSE;
b9c7ea BOOL¤   ¤   ¤   ¤   g_bReadOnly = FALSE;
57af5a
50fc53 BOOL¤   ¤   ¤   ¤   g_bShowGroups;
855c57 INT¤¤   ¤   ¤   ¤   g_iGroupsPercent;
5ace29 INT¤¤   ¤   ¤   ¤   g_iToolHeight;
19af5a
66ec91 // Local globals
ee20c5 static HHOOK¤   hhookKeyboard;¤ ¤   ¤   ¤   //handle of keyboard hook·
38df75 static HHOOK¤   hhookMouse;¤¤   ¤   ¤   ¤   //handle of mouse hook·
1b48f3 static PDLGLISTSTRUCT¤  pDlgList = NULL;
86af5a
02c509 //¤ ____________________________________
7e465d //
e3eee5 //¤ Check for correct version of Windows
56af5a
bf7efe BOOL·
7e472a IsCorrectVersion (VOID)·
4abb36 {
59f275 ¤   OSVERSIONINFO osid;
caaf5a
63ce5f ¤   osid.dwOSVersionInfoSize = sizeof (osid);
b26d53 ¤   GetVersionEx (&osid);
a4af5a
60b516 ¤   switch (osid.dwPlatformId) {
3faf5a
fd7840 ¤   case VER_PLATFORM_WIN32s :
9898aa ¤   ¤   return FALSE;
--75f6 000597c1d79401102e4 Page 2 of PGPkeys.c
e0af5a
8321de ¤   // Windows 95
5a465b ¤   case VER_PLATFORM_WIN32_WINDOWS :
fb1cec ·¤  ¤   return TRUE;
36af5a
69518e ¤   // Windows NT
096e59 ¤   case VER_PLATFORM_WIN32_NT :
e28593 ¤   ¤   if (osid.dwMajorVersion >= 4) return TRUE;
d58de5 //¤ ¤   return FALSE;
6d4569 //>>>
359a10 ¤   ¤   MessageBox (NULL, "PGPkeys is not supported on Windows NT 3.51\n\n"
dce281 ¤   ¤   ¤   "Use at your own risk.",
3cb42c ¤   ¤   "PGPkeys Warning", MB_OK|MB_ICONEXCLAMATION);
20836c ¤   ¤   return TRUE;
a5fa17 //<<<
439371 ¤   }
7fefe6 }
afaf5a
8ec509 //¤ ____________________________________
4d465d //
cd4795 //¤ Check for previously running instances
1aaf5a
677efe BOOL·
81e9e0 DoIExist (
5e4b79 ¤   ¤   LPSTR lpszSemName,·
9a76c2 ¤   ¤   LPSTR lpszClassName,·
8cd63d ¤   ¤   LPSTR lpszWindowTitle)·
23bb36 {
5ba7a9 ····HANDLE¤ ¤   ¤   hSem;
3f02f2 ····HWND¤   ¤   ¤   hWndMe;
11b184 ¤   COPYDATASTRUCT¤ cds;
86af5a
a618c5 ····// Create or open a named semaphore.·
560aa8 ····hSem = CreateSemaphore (NULL, 0, 1, lpszSemName);
ccaf5a
68ec6d ····// Close handle and return NULL if existing semaphore was opened.
0c57a9 ····if ((hSem != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
f35806 ········CloseHandle(hSem);
d37f13 ········hWndMe = FindWindow (lpszClassName, lpszWindowTitle);
ea5d24 ········if (hWndMe) {
5a8906 ¤   ¤   ¤   if (!IsZoomed (hWndMe)) ShowWindow (hWndMe, SW_RESTORE);
5789c6 ¤   ¤   ¤   SetForegroundWindow (hWndMe);
f3f23c ¤   ¤   ¤   cds.dwData = PGPPK_IMPORTKEYCOMMANDLINE | PGPPK_SELECTIVEIMPORT;
f74c4d ¤   ¤   ¤   cds.lpData = GetCommandLine ();
4b7dbb ¤   ¤   ¤   cds.cbData = lstrlen (cds.lpData) +1;
21fa25 ¤   ¤   ¤   SendMessage (hWndMe, WM_COPYDATA, 0, (LPARAM)&cds);
0d0fe4 ¤   ¤   }
024ee5 ········return TRUE;
956fe7 ····}
64af5a
eb77c9 ····// If new semaphore was created, return FALSE.
7c30cb ····return FALSE;
65efe6 }
cbaf5a
53af5a
284a49 //¤ ____________________________________________________________
16465d //
3cd6ef //¤ get PGPkeys path from registry and append Help file name·
d0af5a
2aa1ba VOID·
c6b29f GetHelpFilePath (VOID)·
e8bb36 {
bad955 ¤   CHAR sz[128];
e8af5a
0960f0 ¤   PGPclGetPGPPath (g_szHelpFile, sizeof(g_szHelpFile));
deaf5a
21e7c6 ¤   LoadString (g_hInst, IDS_HELPFILENAME, sz, sizeof(sz));
db3669 ¤   lstrcat (g_szHelpFile, sz);
b1efe6 }
e8af5a
52af5a
59a18c //¤ ____________________________________________
--baf1 00026d451db401102e4 Page 3 of PGPkeys.c
c1465d //
e01fe9 //¤ Initializations for all instances of program
5caf5a
1a7efe BOOL·
a192bf InitApplication (HINSTANCE hInstance, BOOL bIgnoreComctlError)·
3ebb36 {
1caa43 ¤   WNDCLASS¤   ¤   ¤   ¤   wndclass;
04ba49 ¤   PGPError¤   ¤   ¤   ¤   err;
fdaf5a
ee5023 ¤   // check correct version of windows
356cb9 ¤   if (!IsCorrectVersion ())·
1e98aa ¤   ¤   return FALSE;
0eaf5a
ef6b3a ¤   // check for previous instances
e062b9 ¤   if (DoIExist (SEMAPHORENAME, WINCLASSNAME, WINDOWTITLE))·
8898aa ¤   ¤   return FALSE;
dbaf5a
ee8447 ¤   // save instance handle
202185 ¤   g_hInst = hInstance;
ceaf5a
f0c023 ¤   // register the reload messages
29bdfc ¤   g_uReloadKeyringMessage =·
de1411 ¤   ¤   ¤   RegisterWindowMessage (RELOADKEYRINGMSG);
051a2f ¤   g_uReloadPrefsMessage =·
53867a ¤   ¤   ¤   RegisterWindowMessage (RELOADPREFSMSG);
a7969e ¤   g_uReloadKeyserverPrefsMessage =·
d0e593 ¤   ¤   ¤   RegisterWindowMessage (RELOADKEYSERVERPREFSMSG);
62a4cd ¤   g_uPurgePassphraseCacheMessage =·
cbdca2 ¤   ¤   ¤   RegisterWindowMessage (PURGEPASSPHRASECACEHMSG);
50af5a
f9b16b ¤   // register the mouse wheel message
84897f ¤   g_uMouseWheelMessage =·
00fb5f ¤   ¤   ¤   RegisterWindowMessage (MSH_MOUSEWHEEL);
53af5a
7932a0 ¤   // Initialize the sdk library
1779af ¤   err = PGPNewContext (kPGPsdkAPIVersion, &g_Context);
e10971 ¤   if (IsPGPError (err)) {
f0cbd5 ¤   ¤   if (err == kPGPError_FeatureNotAvailable) {
8391c9 ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_SDKEXPIRED,
e6bd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
6b0fe4 ¤   ¤   }
110e1d ¤   ¤   else
88d53e ¤   ¤   ¤   PGPclErrorBox (NULL, err);
1698aa ¤   ¤   return FALSE;
7e9371 ¤   }
0aaf5a
dad62e ¤   PGPclErrorBox (NULL, PGPNewTLSContext (g_Context, &g_TLSContext));
62af5a
e4502e ¤   // initialize client library
97a919 ¤   // note: this fails if common control DLL is not correct version
c935f1 ¤   err = PGPclInitLibrary (g_Context);
f30971 ¤   if (IsPGPError (err)) {
2a7a2f ¤   ¤   if (err == kPGPError_Win32_InvalidComctl32 && bIgnoreComctlError)
effcc4 ¤   ¤   ¤   err = kPGPError_NoErr;
d807e0 ¤   ¤   else {
0ad53e ¤   ¤   ¤   PGPclErrorBox (NULL, err);
635f1f ¤   ¤   ¤   return FALSE;
1b0fe4 ¤   ¤   }
f19371 ¤   }
0daf5a
9ca45d ¤   wndclass.style = 0; ····················
3a22ce ¤   wndclass.lpfnWndProc = (WNDPROC)KeyManagerWndProc;·
437371 ¤   wndclass.cbClsExtra = 0; ·············
7bb1d8 ¤   wndclass.cbWndExtra = 0; ·············
f934da ¤   wndclass.hInstance = hInstance; ······
46c40a ¤   wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_EXEICON));
099b84 ¤   wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
e03c6c ¤   wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);·
946f3c ····wndclass.lpszMenuName = NULL;
5bdb38 ¤   wndclass.lpszClassName = WINCLASSNAME;
1eaf5a
263426 ¤   return (RegisterClass (&wndclass));
--8d53 000d60e65e5401102e4 Page 4 of PGPkeys.c
7aefe6 }
46af5a
21c509 //¤ ____________________________________
36465d //
217ad3 // ·Hook procedure for WH_MOUSE hook.
ccde7b ··
165b1a LRESULT CALLBACK·
a68fd5 MouseHookProc (
ef422d ¤   ¤   INT¤¤   iCode,·
9517d4 ¤   ¤   WPARAM¤ wParam,·
b6c0b8 ¤   ¤   LPARAM¤ lParam)·
ed7142 {·
67a097 ¤   MOUSEHOOKSTRUCT* pmhs;
71af5a
8d27c2 ····if (iCode >= 0) {
dbf883 ¤   ¤   pmhs = (MOUSEHOOKSTRUCT*) lParam;·
81a418 ¤   ¤   PGPGlobalRandomPoolAddMouse (pmhs->pt.x, pmhs->pt.y);
599371 ¤   }
e7af5a
134c69 ¤   return CallNextHookEx (hhookMouse, iCode, wParam, lParam);
8ba79b }·
50af5a
bbc509 //¤ ____________________________________
6a465d //
47827c // ·Hook procedure for WH_KEYBOARD hook.
c5de7b ··
1b5b1a LRESULT CALLBACK·
bcf2ae KeyboardHookProc (
50422d ¤   ¤   INT¤¤   iCode,·
8a17d4 ¤   ¤   WPARAM¤ wParam,·
b8c0b8 ¤   ¤   LPARAM¤ lParam)·
3e7142 {·
e727c2 ····if (iCode >= 0) {
1acdda ¤   ¤   PGPGlobalRandomPoolAddKeystroke (wParam);
3f9371 ¤   }
9daf5a
27d8c8 ¤   return CallNextHookEx (hhookKeyboard, iCode, wParam, lParam);
b7a79b }·
44af5a
c3c509 //¤ ____________________________________
cc465d //
e46629 //¤ Reload all search windows in list
84af5a
72fe80 VOID
104d8d PKPostMessageDlgList (UINT uMsg, WPARAM wParam, LPARAM lParam)
2dbb36 {
74b2bc ¤   PDLGLISTSTRUCT pdls;
71af5a
96ae2e ¤   pdls = pDlgList;
ffaf5a
71d1e6 ¤   while (pdls) {
d447b9 ¤   ¤   PostMessage (pdls->hwndDlg, uMsg, wParam, lParam);
c4c57d ¤   ¤   pdls = pdls->nextItem;
cb9371 ¤   }
deefe6 }
d7af5a
a9c509 //¤ ____________________________________
a2465d //
5be3c1 //¤ Enable/Disable all search windows in list
b4af5a
9ffe80 VOID
6bde57 PKEnableDlgList (BOOL bEnabled)
d5bb36 {
ccb2bc ¤   PDLGLISTSTRUCT pdls;
23af5a
93ae2e ¤   pdls = pDlgList;
13af5a
c6d1e6 ¤   while (pdls) {
97a3eb ¤   ¤   EnableWindow (pdls->hwndDlg, bEnabled);
35c57d ¤   ¤   pdls = pdls->nextItem;
cb9371 ¤   }
d6efe6 }
--9b28 000b562fb66401102e4 Page 5 of PGPkeys.c
e0af5a
f2c509 //¤ ____________________________________
8c465d //
7e2174 //¤ Add dlg hwnd to linked list
40af5a
b4e6b2 static VOID
6713d2 sAddDlgToList (HWND hwndDlg)
dbbb36 {
72b2bc ¤   PDLGLISTSTRUCT pdls;
3aaf5a
9465fe ¤   pdls = pkAlloc (sizeof (DLGLISTSTRUCT));
ad24aa ¤   if (pdls) {
63a4ec ¤   ¤   pdls->hwndDlg = hwndDlg;
2893e0 ¤   ¤   pdls->nextItem = pDlgList;
e4cf86 ¤   ¤   pDlgList = pdls;
009371 ¤   }
9aefe6 }
1faf5a
2ac509 //¤ ____________________________________
d2465d //
afe722 //¤ Remove dlg hwnd from linked list
76af5a
0be6b2 static VOID
9df65e sRemoveDlgFromList (HWND hwndDlg)
cabb36 {
acb2bc ¤   PDLGLISTSTRUCT pdls;
ff70f7 ¤   PDLGLISTSTRUCT pdlsPrev;
5aaf5a
0128de ¤   if (!pDlgList) return;
7daf5a
3aae2e ¤   pdls = pDlgList;
f1af5a
2b96f4 ¤   if (pdls->hwndDlg == hwndDlg) {
9f11a0 ¤   ¤   pDlgList = pDlgList->nextItem;
1a9371 ¤   }
0c665a ¤   else {
76bd9d ¤   ¤   pdls = pDlgList->nextItem;
e275bf ¤   ¤   pdlsPrev = pDlgList;
44ea0f ¤   ¤   while (pdls) {
d9dbc7 ¤   ¤   ¤   if (pdls->hwndDlg == hwndDlg) {
1fc7e8 ¤   ¤   ¤   ¤   pdlsPrev->nextItem = pdls->nextItem;
d5f622 ¤   ¤   ¤   ¤   break;
97a3a6 ¤   ¤   ¤   }
19b01e ¤   ¤   ¤   pdlsPrev = pdls;
8b4902 ¤   ¤   ¤   pdls = pdls->nextItem;
5d0fe4 ¤   ¤   }
ec9371 ¤   }
63af5a
e51ba8 ¤   if (pdls) pkFree (pdls);
32efe6 }
dcaf5a
79c509 //¤ ____________________________________
a6465d //
d72a88 //¤ Add or remove dlg hwnd from linked list
65af5a
dbfe80 VOID
898c32 PKDialogListFunc (HWND hwndDlg, BOOL bAdd, POINT* ppt, HWND* phwnd)
77bb36 {
7e6956 ¤   PDLGLISTSTRUCT¤ pdls;
5d1372 ¤   RECT¤   ¤   ¤   rc;
6daf5a
5913e1 ¤   // if a hwnd is specified, then add/remove if from list
bb67aa ¤   if (hwndDlg) {
48bc39 ¤   ¤   if (bAdd)
e059aa ¤   ¤   ¤   sAddDlgToList (hwndDlg);
8d0e1d ¤   ¤   else
b3746c ¤   ¤   ¤   sRemoveDlgFromList (hwndDlg);
479371 ¤   }
1daf5a
8fb733 ¤   // otherwise this is a query to find out if a point is in a window
c7665a ¤   else {
b54352 ¤   ¤   if (!phwnd) return;
--1985 00002d6800a401102e4 Page 6 of PGPkeys.c
042a17 ¤   ¤   *phwnd = NULL;
4eaf5a
234227 ¤   ¤   if (!ppt) return;
103cf6 ¤   ¤   if (!pDlgList) return;
f9af5a
aa1fff ¤   ¤   pdls = pDlgList;
0caf5a
4fea0f ¤   ¤   while (pdls) {
997728 ¤   ¤   ¤   GetWindowRect (pdls->hwndDlg, &rc);
874765 ¤   ¤   ¤   if (PtInRect (&rc, *ppt)) {
1dd38d ¤   ¤   ¤   ¤   *phwnd = pdls->hwndDlg;
f17438 ¤   ¤   ¤   ¤   return;
98a3a6 ¤   ¤   ¤   }
044902 ¤   ¤   ¤   pdls = pdls->nextItem;
b40fe4 ¤   ¤   }
f29371 ¤   }
7cefe6 }
3faf5a
ebc509 //¤ ____________________________________
b2465d //
aba90c //¤ Main Windows routine
1faf5a
20f629 INT APIENTRY·
1e6b8d WinMain (
e75674 ¤   ¤   HINSTANCE hInstance,·
71afe0 ¤   ¤   HINSTANCE hPrevInstance,
0b3daa ¤   ¤   LPSTR lpCmdLine,·
c09a29 ¤   ¤   INT nCmdShow)·
a9bb36 {
bd2e34 ¤   MSG¤¤   ¤   msg;
a2dd92 ¤   HACCEL¤ ¤   haccelMain, haccelDialog;
bb7fbf ¤   INT¤¤   ¤   lWindowPosX, lWindowPosY, lWindowWidth, lWindowHeight;
9362eb ¤   DWORD¤  ¤   dwShow;
743769 ¤   CHAR¤   ¤   szSwitch[32];
ae11b4 ¤   HMENU¤  ¤   hMenuMain;
01f19b ¤   PGPPrefRef¤ prefRef;
4861e0 ¤   PGPError¤   err;
468411 ¤   BOOL¤   ¤   bDlgMessage;
7a49ac ¤   BOOL¤   ¤   bIgnoreComctlError;
04af5a
996956 ¤   PDLGLISTSTRUCT¤ pdls;
b1af5a
77d710 ¤   // ·store path name of application
4eaa76 ¤   PKSetPathRegistryData ();
7baf5a
a8b850 ¤   //¤ initialize application stuff
80a911 ¤   LoadString (hInstance, IDS_COMCTLERRORSWITCH, szSwitch, sizeof(szSwitch));
b200f2 ¤   if (strstr (lpCmdLine, szSwitch))
889485 ¤   ¤   bIgnoreComctlError = TRUE;
a50e24 ¤   else
7de272 ¤   ¤   bIgnoreComctlError = FALSE;
c531b5 ¤   if (!InitApplication (hInstance, bIgnoreComctlError)) return 0;
6caf5a
5147dc ¤   //¤ attempt to set event hooks
4811a3 ¤   hhookMouse = SetWindowsHookEx (WH_MOUSE, MouseHookProc,·
650154 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, GetCurrentThreadId());
d0f135 ¤   hhookKeyboard = SetWindowsHookEx (WH_KEYBOARD, KeyboardHookProc,·
270154 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, GetCurrentThreadId());
78df17 ¤   if (!hhookMouse || !hhookKeyboard) return 0;
5aaf5a
c03f1e ¤   //¤ check for timed-out software
db697f ¤   if (IsPGPError (PGPclIsExpired (NULL))) return 0;
dcaf5a
7c397d ¤   //¤ check that admin file can be found
a4be29 #if PGP_BUSINESS_SECURITY
32164e #if PGP_ADMIN_BUILD
97654a ¤   err = PGPclOpenAdminPrefs (
b773b1 ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),·
7de1b4 ¤   ¤   ¤   &prefRef, TRUE);
4fdb21 #else
fb654a ¤   err = PGPclOpenAdminPrefs (
0273b1 ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),·
--ab27 000a0b5ffd8401102e4 Page 7 of PGPkeys.c
676838 ¤   ¤   ¤   &prefRef, FALSE);
4f3cce #endif¤ // PGP_ADMIN_BUILD
720c3a ¤   if (IsPGPError (err)) return 0;
70b4fe ¤   PGPGetPrefBoolean (prefRef, kPGPPrefAllowKeyGen,·
2d0834 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &g_bKeyGenEnabled);
bbfcca ¤   PGPclCloseAdminPrefs (prefRef, FALSE);
9edb21 #else
2d1ff2 ¤   err = 0;
f83fde ¤   g_bKeyGenEnabled = TRUE;
4697b2 #endif¤ // PGP_BUSINESS_SECURITY
43af5a
75318e ¤   //¤ post splash screen
6b96b7 ¤   LoadString (hInstance, IDS_NOSPLASHSWITCH, szSwitch, sizeof(szSwitch));
1a7f53 ¤   if (!strstr (lpCmdLine, szSwitch))
6078eb ¤   ¤   PGPclSplash (g_Context, NULL, SPLASH_TIME);
d2af5a
4aead0 ¤   // ·initialize OLE for drag and drop functionality
5e518b ····if (OleInitialize (NULL) != NOERROR) return 0;·
c8af5a
719a75 ¤   // ·get window position and size information from registry
db8685 ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (g_Context), &prefRef);
f79249 ¤   PGPGetPrefBoolean (prefRef, kPGPPrefDisplayMarginalValidity,·
8351bf ¤   ¤   ¤   ¤   ¤   ¤   ¤   &g_bExpertMode);
a932d9 ¤   PGPGetPrefBoolean (prefRef, kPGPPrefMarginalIsInvalid,·
d00aab ¤   ¤   ¤   ¤   ¤   ¤   ¤   &g_bMarginalAsInvalid);
800157 ¤   PKGetPrivatePrefData (&dwShow, &lWindowPosX, &lWindowPosY,·
3155bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   &lWindowWidth, &lWindowHeight, &g_bShowGroups,
ead8c8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &g_iGroupsPercent, &g_iToolHeight);
4d1efd ¤   PGPclCloseClientPrefs (prefRef, FALSE);
662b85 ¤   ¤   ¤   ¤
0c94ff ¤   //¤ load name of help file
c369e6 ¤   GetHelpFilePath ();
69af5a
caeda8 ¤   hMenuMain = LoadMenu (hInstance, MAKEINTRESOURCE (IDR_MENUKEYMAN));
75af5a
a17c00 ¤   g_hWndMain = CreateWindow (WINCLASSNAME, WINDOWTITLE,·
5be1f9 ¤   ¤   WS_OVERLAPPEDWINDOW, lWindowPosX,·
893753 ¤   ¤   lWindowPosY, lWindowWidth,
7330e5 ¤   ¤   lWindowHeight, NULL, hMenuMain, hInstance, NULL);¤
30af5a
ac727e ¤   if (!g_hWndMain) return 0;
aeaf5a
857e7d ¤   ShowWindow (g_hWndMain, nCmdShow);¤ // Show the window
db78ed ¤   UpdateWindow (g_hWndMain);¤ ¤   ¤   // Sends WM_PAINT message
50af5a
f3ed53 ¤   haccelMain =·
f4d8eb ¤   ¤   LoadAccelerators (g_hInst, MAKEINTRESOURCE (IDR_KEYMANACCEL)); ·
4e885c ¤   haccelDialog =·
12625b ¤   ¤   LoadAccelerators (g_hInst, MAKEINTRESOURCE (IDR_DIALOGACCEL)); ·
03af5a
fb2757 ¤   while (GetMessage (&msg, NULL, 0,0)) {
161fb7 ¤   ¤   if (pDlgList) {
a59b4e ¤   ¤   ¤   bDlgMessage = FALSE;
3d2ba2 ¤   ¤   ¤   pdls = pDlgList;
3408ee ¤   ¤   ¤   while (pdls) {
588c72 ¤   ¤   ¤   ¤   if (pdls->hwndDlg != g_hWndMain) {
b4d7ba ¤   ¤   ¤   ¤   ¤   if (IsDialogMessage (pdls->hwndDlg, &msg)) {
63f94f ¤   ¤   ¤   ¤   ¤   ¤   TranslateAccelerator (
42d2be ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pdls->hwndDlg, haccelDialog, &msg);
a9b990 ¤   ¤   ¤   ¤   ¤   ¤   bDlgMessage = TRUE;
cb00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
4d1c89 ¤   ¤   ¤   ¤   ¤   }
4f2613 ¤   ¤   ¤   ¤   }
fa08f1 ¤   ¤   ¤   ¤   pdls = pdls->nextItem;
a3a3a6 ¤   ¤   ¤   }
49a40c ¤   ¤   ¤   if (bDlgMessage) continue;
450fe4 ¤   ¤   }
1708d5 ¤   ¤   if (!TranslateAccelerator (g_hWndMain, haccelMain, &msg)) {·
aba3e9 ¤   ¤   ¤   TranslateMessage(&msg);·
606ced ¤   ¤   ¤   DispatchMessage(&msg);·
398469 ¤   ¤   }·
a09371 ¤   }
--7e9e 001203ecdac401102e4 Page 8 of PGPkeys.c
e0af5a
636de8 ¤   // clean out caches
d5583a ¤   PGPclCloseLibrary ();
75af5a
bd73c0 ¤   if (PGPtlsContextRefIsValid (g_TLSContext))
36b5b7 ¤   ¤   PGPFreeTLSContext (g_TLSContext);
94af5a
7bdd84 ¤   // close down SDK
330c4c ¤   PGPFreeContext (g_Context);
a2af5a
9c1bc0 ¤   // required by OLE
6a7607 ····OleUninitialize ();
fdaf5a
56212a ¤   // remove hook procedures
d4096e ¤   UnhookWindowsHookEx (hhookKeyboard);
c17b4f ¤   UnhookWindowsHookEx (hhookMouse);
38af5a
81b2e2 ¤   return (msg.wParam); ·
96efe6 }
51af5a
20af5a
--e905 000a617970d401102e5 Page 1 of PGPkeys.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
19f860 #ifdef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
66465d //
df5733 // TEXTINCLUDE
a2465d //
99af5a
5186ef 1 TEXTINCLUDE DISCARDABLE·
2d4523 BEGIN
70541e ····"resource.h\0"
48e0d1 END
85af5a
467037 2 TEXTINCLUDE DISCARDABLE·
044523 BEGIN
c3eb23 ····"#include ""afxres.h""\r\n"
98db5c ····"\0"
97e0d1 END
5aaf5a
ea227f 3 TEXTINCLUDE DISCARDABLE·
024523 BEGIN
bc9a9f ····"#include ""PKVer.rc""\r\n"
5edb5c ····"\0"
5ee0d1 END
53af5a
5a69ab #endif ···// APSTUDIO_INVOKED
4caf5a
5caf5a
3f6c0e /////////////////////////////////////////////////////////////////////////////
ea465d //
0b86c0 // Menu
7e465d //
a7af5a
22cdf2 IDR_MENUKEY MENU DISCARDABLE·
914523 BEGIN
1a9fe8 ····POPUP "Context"
3c5574 ····BEGIN
e9ac70 ········MENUITEM "&Copy", ······················IDM_COPYKEY
130382 ········MENUITEM "&Paste", ·····················IDM_PASTEKEY
ecd276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
f1592d ········MENUITEM SEPARATOR
ca3d9c ········MENUITEM "&Sign ...", ··················IDM_CERTIFYKEY
b7308f ········MENUITEM "Se&t as Default", ············IDM_SETASDEFAULT
07e2ea ········POPUP "&Add"
1052d6 ········BEGIN
5667c9 ············MENUITEM "&Name ...", ··················IDM_ADDUSERID
aa4f87 ············MENUITEM "&Photo ...", ·················IDM_ADDPHOTOID
9a32ad ············MENUITEM "&Revoker ...", ···············IDM_ADDREVOKER
a2f37f ········END
d134a0 ········MENUITEM "&Enable", ····················IDM_ENABLEKEY
a6089b ········MENUITEM "D&isable", ···················IDM_DISABLEKEY
--d128 000311cad5e401102e5 Page 2 of PGPkeys.rc
4cb0a7 ········MENUITEM "Re&voke ...", ················IDM_REVOKEKEY
d0dd6f ········MENUITEM "Reveri&fy Signatures", ·······IDM_REVERIFY
65592d ········MENUITEM SEPARATOR
19d656 ········MENUITEM "&Update", ····················IDM_GETFROMSERVER
b6592d ········MENUITEM SEPARATOR
a8c1ea ········MENUITEM "Share S&plit ...", ···········IDM_SPLITKEY
e99560 ········MENUITEM "E&xport ...", ················IDM_EXPORTKEYS
4e592d ········MENUITEM SEPARATOR
ca8f9a ········MENUITEM "Key P&roperties", ············IDM_KEYPROPERTIES
737d01 ····END
03e0d1 END
efaf5a
de065f IDR_MENUUID MENU DISCARDABLE·
424523 BEGIN
e49fe8 ····POPUP "Context"
dc5574 ····BEGIN
09d276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
17592d ········MENUITEM SEPARATOR
f73d9c ········MENUITEM "&Sign ...", ··················IDM_CERTIFYKEY
cb4000 ········MENUITEM "Se&t as Primary Name", ·······IDM_SETASDEFAULT
6e592d ········MENUITEM SEPARATOR
148f9a ········MENUITEM "Key P&roperties", ············IDM_KEYPROPERTIES
c97d01 ····END
90e0d1 END
5caf5a
d8b1c2 IDR_MENUCERT MENU DISCARDABLE·
b94523 BEGIN
4c9fe8 ····POPUP "Context"
895574 ····BEGIN
80d276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
3f592d ········MENUITEM SEPARATOR
23b0a7 ········MENUITEM "Re&voke ...", ················IDM_REVOKEKEY
cb8396 ········MENUITEM "&Get Signing Key from Server", IDM_GETFROMSERVER
be592d ········MENUITEM SEPARATOR
62c37e ········MENUITEM "Signing Key P&roperties", ····IDM_KEYPROPERTIES
b27d01 ····END
11e0d1 END
f0af5a
2ae409 IDR_MENUKEYMAN MENU DISCARDABLE·
cf4523 BEGIN
8bb474 ····POPUP "&File"
395574 ····BEGIN
72df06 ········MENUITEM "&Send Key Shares ...", ·······IDM_SENDSHARES
17592d ········MENUITEM SEPARATOR
b0d362 ········MENUITEM "E&xit", ······················IDM_FILEEXIT
f37d01 ····END
6f7563 ····POPUP "&Edit"
ad5574 ····BEGIN
e37efe ········MENUITEM "&Copy\tCtrl+C", ··············IDM_COPYKEY
5c6d21 ········MENUITEM "&Paste\tCtrl+V", ·············IDM_PASTEKEY
c6d276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
1b592d ········MENUITEM SEPARATOR
3d8cf7 ········MENUITEM "Select &All\tCtrl+A", ········IDM_SELECTALL
e09226 ········MENUITEM "Co&llapse Selection", ········IDM_COLLAPSESEL
7ae790 ········MENUITEM "E&xpand Selection", ··········IDM_EXPANDSEL
a1592d ········MENUITEM SEPARATOR
69cb36 ········MENUITEM "Pre&ferences ...\tCtrl+T", ···IDM_PROPERTIES
4c7d01 ····END
b23f8a ····POPUP "&View"
ef5574 ····BEGIN
c63b59 ········MENUITEM "&Validity", ··················IDM_VIEWVALIDITY
cac04a ········MENUITEM "&Size", ······················IDM_VIEWSIZE
ef4d8a ········MENUITEM "&Key ID", ····················IDM_VIEWKEYID
489e2f ········MENUITEM "Tr&ust", ·····················IDM_VIEWTRUST
574c12 ········MENUITEM "&Creation Date", ·············IDM_VIEWCREATION
8fd0c6 ········MENUITEM "&Expiration Date", ···········IDM_VIEWEXPIRATION
dde0ce ········MENUITEM "&ADK", ·······················IDM_VIEWADK
aa1d7f ········MENUITEM "&Description", ···············IDM_VIEWDESC
8a592d ········MENUITEM SEPARATOR
2a8787 ········MENUITEM "&Toolbar", ···················IDM_VIEWTOOLBAR
a47d01 ····END
310821 ····POPUP "&Keys"
--cc28 0008fadb22b401102e5 Page 3 of PGPkeys.rc
5c5574 ····BEGIN
b8f5e7 ········MENUITEM "&Sign ...\tCtrl+S", ··········IDM_CERTIFYKEY
86e44a ········MENUITEM "Se&t As Default\tCtrl+D", ····IDM_SETASDEFAULT
0ee2ea ········POPUP "&Add"
d652d6 ········BEGIN
b967c9 ············MENUITEM "&Name ...", ··················IDM_ADDUSERID
004f87 ············MENUITEM "&Photo ...", ·················IDM_ADDPHOTOID
4c32ad ············MENUITEM "&Revoker ...", ···············IDM_ADDREVOKER
bbf37f ········END
8234a0 ········MENUITEM "&Enable", ····················IDM_ENABLEKEY
48ef68 ········MENUITEM "&Disable", ···················IDM_DISABLEKEY
1bb0a7 ········MENUITEM "Re&voke ...", ················IDM_REVOKEKEY
efdd6f ········MENUITEM "Reveri&fy Signatures", ·······IDM_REVERIFY
dc592d ········MENUITEM SEPARATOR
d0cb44 ········MENUITEM "&New Key ...\tCtrl+N", ·······IDM_CREATEKEY
6ac1ea ········MENUITEM "Share S&plit ...", ···········IDM_SPLITKEY
81592d ········MENUITEM SEPARATOR
ea31d1 ········MENUITEM "I&mport ...\tCtrl+M", ········IDM_IMPORTKEYS
806a63 ········MENUITEM "E&xport ...\tCtrl+E", ········IDM_EXPORTKEYS
42592d ········MENUITEM SEPARATOR
6ffb8a ········MENUITEM "Key P&roperties ...\tCtrl+I", IDM_KEYPROPERTIES
487d01 ····END
0a7343 ····POPUP "&Server"
d95574 ····BEGIN
417fe5 ········MENUITEM "Send &to", ···················IDM_SENDTOSERVERPOPUP
610500 ········MENUITEM "Searc&h ... \tCtrl+F", ·······IDM_SEARCH
a620a8 ········MENUITEM "&Update\tCtrl+G", ············IDM_GETFROMSERVER
08592d ········MENUITEM SEPARATOR
20748f ········MENUITEM "Update &Introducers", ········IDM_UPDATEINTRODUCERS
be8067 ········MENUITEM "U&pdate Group Lists", ········IDM_UPDATEGROUPLISTS
0a7ab6 ········MENUITEM "S&end Group Lists", ··········IDM_SENDGROUPLISTS
f47d01 ····END
53d1bd ····POPUP "&Groups"
cb5574 ····BEGIN
b20dfc ········MENUITEM "&New Group ...\tCtrl+R", ·····IDM_NEWGROUP
71e8b1 ········MENUITEM "&Show Groups\tCtrl+U", ·······IDM_VIEWGROUPS
52b33c ········MENUITEM "I&mport Groups ...", ·········IDM_IMPORTGROUPS
18592d ········MENUITEM SEPARATOR
9118b8 ········MENUITEM "Group P&roperties ...", ······IDM_GROUPPROPERTIES
f97d01 ····END
eb46ce ····POPUP "&Help"
905574 ····BEGIN
986ae1 ········MENUITEM "&Help Topics", ···············IDM_HELPTOPICS
4a592d ········MENUITEM SEPARATOR
aa19f5 ········MENUITEM "&About PGP ...", ·············IDM_HELPABOUT
b37d01 ····END
41e0d1 END
8daf5a
d61bce IDR_MENUNONE MENU DISCARDABLE·
4c4523 BEGIN
819fe8 ····POPUP "Context"
855574 ····BEGIN
130382 ········MENUITEM "&Paste", ·····················IDM_PASTEKEY
747d01 ····END
dce0d1 END
0aaf5a
fbce07 IDR_MENUPROMISCUOUS MENU DISCARDABLE·
e34523 BEGIN
0e9fe8 ····POPUP "Context"
815574 ····BEGIN
11d276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
c6592d ········MENUITEM SEPARATOR
fd3d9c ········MENUITEM "&Sign ...", ··················IDM_CERTIFYKEY
d6592d ········MENUITEM SEPARATOR
4c8f9a ········MENUITEM "Key P&roperties", ············IDM_KEYPROPERTIES
367d01 ····END
8de0d1 END
10af5a
295fc2 IDR_MENUKEYSEARCHSERVER MENU DISCARDABLE·
954523 BEGIN
7d9fe8 ····POPUP "Context"
8f5574 ····BEGIN
--3438 000846ce829401102e5 Page 4 of PGPkeys.rc
e3ac70 ········MENUITEM "&Copy", ······················IDM_COPYKEY
1f0382 ········MENUITEM "&Paste", ·····················IDM_PASTEKEY
3ad276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
764f64 ········MENUITEM "D&elete from Server", ········IDM_DELETESERVER
b9592d ········MENUITEM SEPARATOR
263d9c ········MENUITEM "&Sign ...", ··················IDM_CERTIFYKEY
a6308f ········MENUITEM "Se&t as Default", ············IDM_SETASDEFAULT
e7e2ea ········POPUP "&Add"
f652d6 ········BEGIN
6c67c9 ············MENUITEM "&Name ...", ··················IDM_ADDUSERID
8a4f87 ············MENUITEM "&Photo ...", ·················IDM_ADDPHOTOID
7632ad ············MENUITEM "&Revoker ...", ···············IDM_ADDREVOKER
7cf37f ········END
8afdb6 ········MENUITEM "D&isable on Server", ·········IDM_DISABLEKEY
3db0a7 ········MENUITEM "Re&voke ...", ················IDM_REVOKEKEY
41592d ········MENUITEM SEPARATOR
f47cc1 ········MENUITEM "I&mport to Local Keyring ", ··IDM_ADDTOMAIN
af9560 ········MENUITEM "E&xport ...", ················IDM_EXPORTKEYS
ba592d ········MENUITEM SEPARATOR
458f9a ········MENUITEM "Key P&roperties", ············IDM_KEYPROPERTIES
047d01 ····END
dae0d1 END
2faf5a
f2018b IDR_MENUKEYSEARCHLOCAL MENU DISCARDABLE·
384523 BEGIN
309fe8 ····POPUP "Context"
995574 ····BEGIN
c4ac70 ········MENUITEM "&Copy", ······················IDM_COPYKEY
2e0382 ········MENUITEM "&Paste", ·····················IDM_PASTEKEY
4fd276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
83592d ········MENUITEM SEPARATOR
a83d9c ········MENUITEM "&Sign ...", ··················IDM_CERTIFYKEY
8a308f ········MENUITEM "Se&t as Default", ············IDM_SETASDEFAULT
70e2ea ········POPUP "&Add"
9952d6 ········BEGIN
4f67c9 ············MENUITEM "&Name ...", ··················IDM_ADDUSERID
8b4f87 ············MENUITEM "&Photo ...", ·················IDM_ADDPHOTOID
f732ad ············MENUITEM "&Revoker ...", ···············IDM_ADDREVOKER
d3f37f ········END
7f34a0 ········MENUITEM "&Enable", ····················IDM_ENABLEKEY
ec089b ········MENUITEM "D&isable", ···················IDM_DISABLEKEY
aeb0a7 ········MENUITEM "Re&voke ...", ················IDM_REVOKEKEY
f7592d ········MENUITEM SEPARATOR
947cc1 ········MENUITEM "I&mport to Local Keyring ", ··IDM_ADDTOMAIN
f69560 ········MENUITEM "E&xport ...", ················IDM_EXPORTKEYS
fc592d ········MENUITEM SEPARATOR
128f9a ········MENUITEM "Key P&roperties", ············IDM_KEYPROPERTIES
1e7d01 ····END
5ee0d1 END
6faf5a
cbf16a IDR_MENUGROUP MENU DISCARDABLE·
024523 BEGIN
149fe8 ····POPUP "Context"
ee5574 ····BEGIN
1abf09 ········MENUITEM "&Paste into Group", ··········IDM_PASTEKEY
b7d276 ········MENUITEM "&Delete", ····················IDM_DELETEKEY
c6592d ········MENUITEM SEPARATOR
9c713e ········MENUITEM "&Get Keys from Server", ······IDM_GETFROMSERVER
3e592d ········MENUITEM SEPARATOR
2fcf01 ········MENUITEM "Group P&roperties", ··········IDM_GROUPPROPERTIES
537d01 ····END
dbe0d1 END
aeaf5a
fe17c0 IDR_MENUGROUPKEY MENU DISCARDABLE·
d44523 BEGIN
9f9fe8 ····POPUP "Context"
385574 ····BEGIN
dfbf09 ········MENUITEM "&Paste into Group", ··········IDM_PASTEKEY
9b82db ········MENUITEM "Re&move", ····················IDM_DELETEKEY
f5bbaf ········MENUITEM "&Locate in Keyring", ·········IDM_FINDKEY
63592d ········MENUITEM SEPARATOR
84d0f4 ········MENUITEM "&Get Key from Server", ·······IDM_GETFROMSERVER
--55a7 000892d9f0d401102e5 Page 5 of PGPkeys.rc
77592d ········MENUITEM SEPARATOR
c98f9a ········MENUITEM "Key P&roperties", ············IDM_KEYPROPERTIES
557d01 ····END
70e0d1 END
cbaf5a
feaf5a
cc6c0e /////////////////////////////////////////////////////////////////////////////
46465d //
98b090 // Dialog
55465d //
34af5a
874311 IDD_BACKUPWARN DIALOG DISCARDABLE ·0, 0, 212, 97
a45b1a STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
c450d9 CAPTION "PGPkeys "
b5309f FONT 8, "MS Sans Serif"
5c4523 BEGIN
e51a10 ····LTEXT ··········"The new key that has been generated during this session is¶
d15589 ·very important. ·Losing your keyring file in a disk crash or accidental file d¶
dabe70 eletion without having a backup will render the key and all data encrypted with¶
00b8d3 ·that key useless.",
2c6c73 ····················IDC_STATIC,7,7,198,33,NOT WS_GROUP
48fafa ····LTEXT ··········"It is strongly recommended that you backup your keyring fi¶
eaa9a3 les to a medium other than your main drive.",
bef153 ····················IDC_STATIC,7,47,198,19,NOT WS_GROUP
2b1314 ····DEFPUSHBUTTON ··"&Save Backup Now",IDC_BACKUPNOW,14,76,76,14,WS_GROUP
b8d59e ····PUSHBUTTON ·····"&Don't Save",IDC_DONTBACKUP,98,76,46,14
745b6d ····PUSHBUTTON ·····"&Cancel",IDCANCEL,152,76,45,14
00e0d1 END
02af5a
1b6415 IDD_READONLY DIALOG DISCARDABLE ·0, 0, 215, 82
645b1a STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
447435 CAPTION "PGPkeys Warning"
f2309f FONT 8, "MS Sans Serif"
594523 BEGIN
fc6557 ····DEFPUSHBUTTON ··"OK",IDOK,158,61,50,14
e4818d ····CONTROL ········"Do not warn me about these files again",IDC_WARNNOMORE,
24937d ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,65,141,10
abb729 ····LTEXT ··········"You do not have file access rights to modify the contents ¶
350b6b of one or both of the selected keyring files.",
6e8b97 ····················IDC_STATIC,7,7,201,19
8ba9cb ····LTEXT ··········"These keyring files are being opened in ""read-only"" mode¶
4c5602 . ·You can view and use the contents of the keyring files, but all operations o¶
e4e2b4 n these files will be disabled.",
90fd76 ····················IDC_STATIC,7,28,201,26
0ee0d1 END
44af5a
5ed9ad IDD_KEYWIZ_INTRO DIALOG DISCARDABLE ·0, 0, 313, 170
cce74b STYLE DS_CENTER | WS_CHILD | WS_CAPTION
15e497 CAPTION "Key Generation Wizard"
c1309f FONT 8, "MS Sans Serif"
9e4523 BEGIN
daad53 ····LTEXT ··········"In order for other people to send you secure messages, you¶
ebf303 ·must generate a key pair.",
34fc2e ····················IDC_STATIC,100,7,206,19
527ca8 ····LTEXT ··········"If you would like more information on what a key pair is a¶
355f68 nd how PGP works, click the Help button, below.",
e80170 ····················IDC_STATIC,100,113,206,17
722d69 ····LTEXT ··········"Otherwise, choose Next to continue.",IDC_STATIC,100,145,
cbe2b4 ····················206,9
95c4a9 ····LTEXT ··········"Your key pair will also be used to sign digital documents.¶
c9934a ",
91ae4f ····················IDC_STATIC,100,41,206,9
949f9d ····LTEXT ··········"A key pair consists of a ""Public Key,"" and a ""Private K¶
4db6ed ey."" ·The public key should be given to everyone you know (PGP has facilities ¶
5f25cb to assist in this). ·The private key should be kept absolutely secret.",
38606c ····················IDC_STATIC,100,65,206,33
22c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
fcb30f ····················SS_SUNKEN,5,4,83,162
d0e0d1 END
97af5a
e02ceb IDD_KEYWIZ_NAME DIALOG DISCARDABLE ·0, 0, 313, 170
891d84 STYLE WS_CHILD | WS_CAPTION
--0531 000167e58ca401102e5 Page 6 of PGPkeys.rc
67e497 CAPTION "Key Generation Wizard"
28309f FONT 8, "MS Sans Serif"
e74523 BEGIN
6c093d ····LTEXT ··········"What name and email address should be associated with this¶
410672 ·key pair?",
1ffc2e ····················IDC_STATIC,100,7,206,19
4d13f5 ····LTEXT ··········"&Full name:",IDC_STATIC,100,67,206,9
426a5a ····EDITTEXT ·······IDC_FULL_NAME,100,79,156,14,ES_AUTOHSCROLL
988af6 ····LTEXT ··········"&Email address:",IDC_STATIC,100,110,206,9
a335af ····EDITTEXT ·······IDC_EMAIL,99,122,156,14,ES_AUTOHSCROLL
3943a9 ····LTEXT ··········"By listing your name and email address here, you let your ¶
50e095 correspondents know that the key they are using belongs to you.",
cff9e2 ····················IDC_STATIC,100,34,206,19
eac75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
17b30f ····················SS_SUNKEN,5,4,83,162
0be0d1 END
e9af5a
7ff8ec IDD_KEYWIZ_TYPE DIALOG DISCARDABLE ·0, 0, 313, 170
f21d84 STYLE WS_CHILD | WS_CAPTION
efe497 CAPTION "Key Generation Wizard"
d2309f FONT 8, "MS Sans Serif"
db4523 BEGIN
b1f978 ····LTEXT ··········"What type of key would you like to generate? ·If you don't¶
4b8c3c ·know, it's recommended that you generate a Diffie-Hellman/DSS key pair.",
91134a ····················IDC_STATIC,100,7,206,29
b9ed0d ····LTEXT ··········"RSA is the ""old-style"" PGP key. ·Most new users of PGP w¶
f748e3 ill be expecting a Diffie-Hellman/DSS key.",
61b9cd ····················IDC_STATIC,100,38,206,19
1587dc ····LTEXT ··········"If you'd like more information on the differences between ¶
8ffb5e the two key types, press the Help button, below.",
96688b ····················IDC_STATIC,100,69,206,19
6667e3 ····LTEXT ··········"This version of PGP does not support RSA key generation",
028c10 ····················IDC_NORSAGENTEXT,100,99,206,12,NOT WS_VISIBLE
ea8af1 ····GROUPBOX ·······"Key Pair Type",IDC_STATIC,100,118,206,42
89824c ····CONTROL ········"&Diffie-Hellman/DSS",IDC_RADIO_ELGAMAL,"Button",
6917a7 ····················BS_AUTORADIOBUTTON | WS_GROUP,109,132,187,10
e2182b ····CONTROL ········"&RSA",IDC_RADIO_RSA,"Button",BS_AUTORADIOBUTTON,109,145,
915375 ····················187,10
8ec75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
0fb30f ····················SS_SUNKEN,5,4,83,162
d0e0d1 END
9eaf5a
6c7f7a IDD_KEYWIZ_SIZE DIALOG DISCARDABLE ·0, 0, 313, 170
761d84 STYLE WS_CHILD | WS_CAPTION
76e497 CAPTION "Key Generation Wizard"
7a309f FONT 8, "MS Sans Serif"
5b4523 BEGIN
352da8 ····LTEXT ··········"How large a key pair do you wish to generate? ·As a rule, ¶
2b2265 larger keys are more secure, but slower.",
f3fc2e ····················IDC_STATIC,100,7,206,19
2baa07 ····LTEXT ··········"For most applications, 1024 - 2048 bit keys are quite suff¶
726012 icient.",
30fadf ····················IDC_STATIC_SMALL_GUIDE,100,32,206,9
a5dbf6 ····GROUPBOX ·······"Key Pair Size",IDC_STATIC,100,51,206,110
a3ccc9 ····CONTROL ········"768 bits",IDC_RADIO_768,"Button",BS_AUTORADIOBUTTON,108,
06e344 ····················65,194,10
4741ea ····CONTROL ········"1024 bits",IDC_RADIO_1024,"Button",BS_AUTORADIOBUTTON,
3ac8bd ····················108,78,188,10
51da84 ····CONTROL ········"1536 bits",IDC_RADIO_1536,"Button",BS_AUTORADIOBUTTON,
0b7b71 ····················108,91,188,10
065d09 ····CONTROL ········"2048 bits",IDC_RADIO_2048,"Button",BS_AUTORADIOBUTTON,
76bd10 ····················108,104,188,10
a13e01 ····CONTROL ········"3072 bits",IDC_RADIO_3072,"Button",BS_AUTORADIOBUTTON |·
5e494b ····················NOT WS_VISIBLE,108,117,188,10
6ac59e ····CONTROL ········"&Custom (512 - 2048 bits)",IDC_RADIO_CUSTOM,"Button",
e7efed ····················BS_AUTORADIOBUTTON,108,130,188,10
9913e5 ····EDITTEXT ·······IDC_CUSTOM_BITS,120,143,34,14,ES_NUMBER
b9c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
8ab30f ····················SS_SUNKEN,5,4,83,162
d2e0d1 END
90af5a
169902 IDD_KEYWIZ_EXPIRATION DIALOG DISCARDABLE ·0, 0, 313, 170
--0de8 00014a64f3b401102e5 Page 7 of PGPkeys.rc
841d84 STYLE WS_CHILD | WS_CAPTION
cce497 CAPTION "Key Generation Wizard"
76309f FONT 8, "MS Sans Serif"
614523 BEGIN
3cc75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
08b30f ····················SS_SUNKEN,5,4,83,162
67a221 ····LTEXT ··········"You can set your key pair to automatically expire within a¶
a80f92 ·certain amount of time.",
2bfc2e ····················IDC_STATIC,100,7,206,19
174a6a ····LTEXT ··········"When your key pair expires, you will no longer be able to ¶
668fc1 use it for encrypting or signing. ·However, it will still decrypt and verify.",
291000 ····················IDC_STATIC,100,33,206,19
0c3cba ····LTEXT ··········"Once you generate your key pair, you will not be able to c¶
02ec72 hange its expiration setting.",
e877c5 ····················IDC_STATIC,100,64,207,18
9097e9 ····GROUPBOX ·······"Key Expiration",IDC_STATIC,100,94,206,52,WS_GROUP
8bb9bb ····CONTROL ········"Key pair ne&ver expires",IDC_RADIO_NEVER,"Button",
349b9e ····················BS_AUTORADIOBUTTON | WS_TABSTOP,109,108,130,10
255891 ····CONTROL ········"Key pair &expires on",IDC_RADIO_CUSTOM_DAYS,"Button",
d35392 ····················BS_AUTORADIOBUTTON,109,125,80,8
8b9226 ····LTEXT ··········"Date picker",IDC_EXPIRATIONDATE,189,123,58,14,NOT·
fd1580 ····················WS_VISIBLE | WS_BORDER | NOT WS_GROUP
88e0d1 END
38af5a
0ee7ee IDD_KEYWIZ_PASSPHRASE DIALOG DISCARDABLE ·0, 0, 313, 170
d01d84 STYLE WS_CHILD | WS_CAPTION
b8e497 CAPTION "Key Generation Wizard"
89309f FONT 8, "MS Sans Serif"
e44523 BEGIN
31c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
d1b30f ····················SS_SUNKEN,5,4,83,162
b2bfff ····LTEXT ··········"Your private key will be protected by a passphrase. ·It is¶
698215 ·important that you do not write this passphrase down.",
63ec81 ····················IDC_DUMMYSTOP,100,7,206,18
c1040f ····LTEXT ··········"Your passphrase should be at least 8 characters long and s¶
89baf6 hould contain non-alphabetic characters.",
6f4fb7 ····················IDC_PHRASELENGTHTEXT,100,31,206,20
2f4927 ····LTEXT ··········"&Passphrase:",IDC_STATIC,100,57,111,8
2b3956 ····EDITTEXT ·······IDC_EDIT_PASSPHRASE,100,67,203,28,ES_MULTILINE |·
b890de ····················WS_VSCROLL
885f03 ····LTEXT ··········"Passphrase Quality :",IDC_STATIC,100,99,65,8
261e9a ····CONTROL ········"Progress1",IDC_PHRASEQUALITY,"msctls_progress32",
1ceeeb ····················WS_BORDER,171,100,132,7
fc2405 ····LTEXT ··········"Minimum Quality :",IDC_MINQUALITYTEXT,100,109,62,8
ac26c5 ····CONTROL ········"Progress1",IDC_MINPHRASEQUALITY,"msctls_progress32",
e6a316 ····················WS_BORDER,171,110,132,7
85ca15 ····LTEXT ··········"&Confirmation:",IDC_STATIC,100,127,150,8
7ecc4d ····EDITTEXT ·······IDC_EDIT_PASSPHRASE2,100,137,203,28,ES_MULTILINE |·
2790de ····················WS_VSCROLL
21e40d ····CONTROL ········"&Hide Typing",IDC_CHECK_HIDE_TYPING,"Button",
90b025 ····················BS_AUTOCHECKBOX | WS_TABSTOP,245,56,57,10
77e0d1 END
00af5a
34c1e3 IDD_KEYWIZ_RANDOBITS DIALOG DISCARDABLE ·0, 0, 313, 170
8f1d84 STYLE WS_CHILD | WS_CAPTION
bbe497 CAPTION "Key Generation Wizard"
d5309f FONT 8, "MS Sans Serif"
914523 BEGIN
42514a ····LTEXT ··········"In order to generate a key pair, PGP needs a certain amoun¶
8872dc t of random data.",
e2fc2e ····················IDC_STATIC,100,7,206,19
031b56 ····LTEXT ··········"Please type or move your mouse around until the progress b¶
a59baa ar below fills up.",
c943bc ····················IDC_STATIC,100,36,206,21
6bb831 ····LTEXT ··········"Press ""Next"" when you're ready to continue.",
980dee ····················IDC_STATIC,100,133,206,11
7bf934 ····CTEXT ··········"Random Data Collected :",IDC_STATIC,100,70,206,8
6cc96c ····CONTROL ········"Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
b36a75 ····················100,86,206,8
27f9be ····CTEXT ··········"x of y Bits Needed",IDC_STATIC_PROGRESS_TEXT,132,101,
57c3f8 ····················132,8,NOT WS_VISIBLE
147d23 ····LTEXT ··········"0 %",IDC_STATIC,100,99,12,8
--126c 000ba9ac923401102e5 Page 8 of PGPkeys.rc
b046ba ····RTEXT ··········"100 %",IDC_STATIC,285,99,20,8
7bc75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
60b30f ····················SS_SUNKEN,5,4,83,162
a9e0d1 END
ccaf5a
270d75 IDD_KEYWIZ_GENERATION DIALOG DISCARDABLE ·0, 0, 313, 170
0b1d84 STYLE WS_CHILD | WS_CAPTION
eee497 CAPTION "Key Generation Wizard"
9c309f FONT 8, "MS Sans Serif"
614523 BEGIN
2f1a0d ····LTEXT ··········"PGP is now generating your new key pair. ·On a slow machin¶
6c9b3c e, this could take several minutes. ·Please be patient.",
13edbb ····················IDC_STATIC,100,17,206,17
b98374 ····CONTROL ········"Animate1",IDC_WORKINGAVI,"SysAnimate32",ACS_CENTER |·
a88148 ····················WS_TABSTOP,100,48,206,99
2c0aae ····CTEXT ··········"Generation Progess",IDC_PHASE,100,154,206,9
6cc75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
0fb30f ····················SS_SUNKEN,5,4,83,162
11e0d1 END
b0af5a
07002c IDD_KEYWIZ_PRESEND DIALOG DISCARDABLE ·0, 0, 313, 170
6a1d84 STYLE WS_CHILD | WS_CAPTION
6de497 CAPTION "Key Generation Wizard"
f7309f FONT 8, "MS Sans Serif"
554523 BEGIN
a70bd6 ····LTEXT ··········"If you have an Internet connection, we suggest that you se¶
7e6e30 nd your new public key to the server.",
68527a ····················IDC_STATIC,100,8,206,20
d3b693 ····LTEXT ··········"This will make it easy for your correspondents to get your¶
ffb727 ·key and communicate with you securely.",
34b2f4 ····················IDC_STATIC,100,39,206,25
53b7f6 ····LTEXT ··········"If you don't have an Internet connection, or are not conne¶
f4c957 cted right now, leave ""Send my key to the root server now"" unchecked. ·You ca¶
0ec6bf n send your key later from within PGPkeys.",
7d1bdd ····················IDC_STATIC,100,72,206,28
10c940 ····CONTROL ········"&Send my key to the root server now",IDC_CHECK_SEND,
bd4856 ····················"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,115,163,10
28c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
30b30f ····················SS_SUNKEN,5,4,83,162
5de0d1 END
a7af5a
c5e6f6 IDD_KEYWIZ_SEND DIALOG DISCARDABLE ·0, 0, 313, 170
1b1d84 STYLE WS_CHILD | WS_CAPTION
aae497 CAPTION "Key Generation Wizard"
dc309f FONT 8, "MS Sans Serif"
a44523 BEGIN
79e47c ····LTEXT ··········"By sending your key to the server, you make it simple for ¶
4b9a9e your friends and associates to automatically retrieve your public key.",
68c452 ····················IDC_STATIC,100,7,206,20
ffdcc0 ····LTEXT ··········"It is also suggested that, whenever you sign someone else'¶
ac5bd5 s key, you send their newly-signed key to the server as well. ·In this way, you¶
900e88 'll assist in the propagation of the Web Of Trust!",
e809cb ····················IDC_STATIC,100,41,206,25
ad4cf5 ····LTEXT ··········"If you are already connected to the Internet, this should ¶
2ddd99 take only a moment...",
669123 ····················IDC_STATIC,100,85,206,20
dfc75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
fab30f ····················SS_SUNKEN,5,4,83,162
15ecac ····CTEXT ··········"Static",IDC_PROGRESSTEXT,100,124,198,8
f9c7eb ····LTEXT ··········"",IDC_PROGRESS,119,144,160,9,SS_SUNKEN | WS_BORDER
aee0d1 END
3eaf5a
c34721 IDD_KEYWIZ_DONE DIALOG DISCARDABLE ·0, 0, 313, 170
f81d84 STYLE WS_CHILD | WS_CAPTION
a1e497 CAPTION "Key Generation Wizard"
9b309f FONT 8, "MS Sans Serif"
554523 BEGIN
c2a587 ····LTEXT ··········"Congratulations! ·You have just generated a PGP key pair!",
7ba4c6 ····················IDC_STATIC,100,8,206,11
ba51c6 ····LTEXT ··········"You will now be able to receive secure messages and sign d¶
d3833a ocuments.",
baf9e2 ····················IDC_STATIC,100,34,206,19
--ce94 0006ac37aa4401102e5 Page 9 of PGPkeys.rc
91bf25 ····LTEXT ··········"Click Finish below to add your new key to your keyring!",
d28804 ····················IDC_STATIC,100,128,206,11
5006f0 ····LTEXT ··········"Because you sent your key to the server, your corresponden¶
05fd9d ts will now be able to get your key automatically when they wish to communicate¶
083064 ·with you.",
c33b84 ····················IDC_STATIC_KS_TEXT,100,71,206,29
82c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
45b30f ····················SS_SUNKEN,5,4,83,162
dde0d1 END
52af5a
a01cdd IDD_KEYWIZ_SIGN_OLD DIALOG DISCARDABLE ·0, 0, 313, 170
961d84 STYLE WS_CHILD | WS_CAPTION
f7e497 CAPTION "Key Generation Wizard"
b1309f FONT 8, "MS Sans Serif"
f84523 BEGIN
394bc1 ····LTEXT ··········"You have an old private key on your keyring with the same ¶
d7925b name and email address as the key pair you've just generated.",
effc2e ····················IDC_STATIC,100,7,206,19
546a92 ····LTEXT ··········"We recommend that you now sign your new key pair with your¶
adddb2 ·old one. ·To do so, simply enter the passphrase to your old private key in the¶
fef85e ·field below.",
89aaab ····················IDC_STATIC,100,30,206,26
e9f135 ····LTEXT ··········"If you do not wish to sign your new key with your old one ¶
c1b195 now, uncheck ""Sign my new key now,"" and press ""Next."" ·You can always sign ¶
f2a102 your new key at a later date from within PGPkeys.",
23887a ····················IDC_STATIC_KMI,100,62,205,26
854545 ····CONTROL ········"&Sign my new key now",IDC_CHECK_SIGN_KEY,"Button",
ba00b5 ····················BS_AUTOCHECKBOX | WS_TABSTOP,100,95,181,10
ffa956 ····LTEXT ··········"Old Private Key &Passphrase",IDC_STATIC,100,116,92,8
24b946 ····EDITTEXT ·······IDC_EDIT_PASSPHRASE,100,128,203,28,ES_MULTILINE |·
4590de ····················WS_VSCROLL
f2e40d ····CONTROL ········"&Hide Typing",IDC_CHECK_HIDE_TYPING,"Button",
2eab61 ····················BS_AUTOCHECKBOX | WS_TABSTOP,251,116,57,10
a5c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
6db30f ····················SS_SUNKEN,5,4,83,162
17e0d1 END
7baf5a
74a3dc IDD_SEARCH DIALOGEX 0, 0, 281, 58
e69fa0 STYLE DS_NOIDLEMSG | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |·
2cc538 ····WS_CLIPCHILDREN
fd0175 EXSTYLE WS_EX_CONTEXTHELP | WS_EX_CONTROLPARENT
a6309f FONT 8, "MS Sans Serif"
6f4523 BEGIN
50cc44 ····DEFPUSHBUTTON ··"&Search",IDC_SEARCH,228,3,50,14
4a57f8 ····DEFPUSHBUTTON ··"S&top Search",IDC_STOP,228,3,50,14,NOT WS_VISIBLE |·
2c4ee4 ····················WS_DISABLED
ce1ae7 ····PUSHBUTTON ·····"&Clear Search",IDC_CLEAR,228,20,50,14
97299f ····PUSHBUTTON ·····"&Help",9,228,37,50,14
d58489 ····LTEXT ··········"Search for keys on",IDC_STATIC,3,6,60,8
5aa5bf ····COMBOBOX ·······IDC_LOCATION,68,3,124,116,CBS_DROPDOWNLIST |·
c50f85 ····················CBS_OWNERDRAWVARIABLE | CBS_HASSTRINGS | WS_VSCROLL |·
9ac64d ····················WS_TABSTOP
b74960 ····LTEXT ··········"where",IDC_STATIC1,196,6,20,8,NOT WS_GROUP
bb58eb ····PUSHBUTTON ·····"&More Choices",IDC_MORE,3,42,52,13
51e764 ····PUSHBUTTON ·····"&Fewer Choices",IDC_FEWER,59,42,52,13,WS_DISABLED
ffdbed ····CONTROL ········"Search &Pending Area",IDC_PENDING,"Button",
2df2cd ····················BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,135,45,83,
c8ebc1 ····················10
82cb24 ····CONTROL ········"",IDC_DEFAULT_GROUP,"Static",SS_BLACKFRAME | NOT·
c01fc5 ····················WS_VISIBLE,3,20,223,16
287a2d ····COMBOBOX ·······IDC_ATTRIBUTE,3,21,62,81,CBS_DROPDOWNLIST | WS_VSCROLL |·
db6d57 ····················WS_TABSTOP,WS_EX_NOPARENTNOTIFY
7a5265 ····COMBOBOX ·······IDC_VERB,67,21,66,72,CBS_DROPDOWNLIST | WS_VSCROLL |·
7f6d57 ····················WS_TABSTOP,WS_EX_NOPARENTNOTIFY
0cebd7 ····COMBOBOX ·······IDC_SPECIFIER_COMBO,135,21,86,69,CBS_DROPDOWN |·
25e52a ····················CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
05d3ed ····EDITTEXT ·······IDC_SPECIFIER_EDIT,135,21,86,13,ES_MULTILINE |·
654569 ····················ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_VISIBLE
256003 ····COMBOBOX ·······IDC_SPECIFIER_COMBO_LIST,135,21,86,69,CBS_DROPDOWNLIST |·
cfe52a ····················CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
73e0d1 END
6aaf5a
--0cfb 0008d5d4869401102e5 Page 10 of PGPkeys.rc
68e323 IDD_CHOICE DIALOGEX 0, 0, 227, 17
631c99 STYLE DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
5c3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
3f4523 BEGIN
e1614f ····COMBOBOX ·······IDC_ATTRIBUTE,3,2,62,81,CBS_DROPDOWNLIST | WS_VSCROLL |·
bfc64d ····················WS_TABSTOP
9a9912 ····COMBOBOX ·······IDC_VERB,67,2,66,72,CBS_DROPDOWNLIST | WS_VSCROLL |·
866d57 ····················WS_TABSTOP,WS_EX_NOPARENTNOTIFY
eacb2b ····COMBOBOX ·······IDC_SPECIFIER_COMBO,135,2,86,69,CBS_DROPDOWN |·
265604 ····················CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,
165f73 ····················WS_EX_NOPARENTNOTIFY
3aeb0f ····EDITTEXT ·······IDC_SPECIFIER_EDIT,135,2,86,13,ES_MULTILINE |·
9f4569 ····················ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_VISIBLE
c76562 ····COMBOBOX ·······IDC_SPECIFIER_COMBO_LIST,135,2,86,69,CBS_DROPDOWNLIST |·
c15604 ····················CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,
685f73 ····················WS_EX_NOPARENTNOTIFY
90e0d1 END
78af5a
7db316 IDD_KEYWIZ_BADPHRASE DIALOG DISCARDABLE ·0, 0, 313, 170
e51d84 STYLE WS_CHILD | WS_CAPTION
b3e497 CAPTION "Key Generation Wizard"
05309f FONT 8, "MS Sans Serif"
314523 BEGIN
2ec75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
e5b30f ····················SS_SUNKEN,5,4,83,162
0cac2c ····LTEXT ··········"Your passphrase is a potential security hazard because :",
497c58 ····················IDC_REJECTTEXT,100,7,190,8
667e1e ····LTEXT ··········"Passphrase quality is based on a mix of the length of your¶
0e06e9 ·passphrase and the number of character set variations. ·Capitalizing some lett¶
3e6fb3 ers and not others along with using punctuation marks and numbers will result i¶
22fc2b n a higher quality rating.",
ce93ba ····················IDC_BADQUALITY2,114,81,175,40
9cff78 ····LTEXT ··········"- It did not meet the length requirement of XXX characters¶
29b25b .",
b9cae1 ····················IDC_BADLENGTH,110,35,183,8
66c66e ····GROUPBOX ·······"",IDC_BOX1,100,24,200,27
96ad7f ····LTEXT ··········"- It did not meet the quality requirement of XXX out of 10¶
e5668a 0.",
8a7472 ····················IDC_BADQUALITY1,110,73,187,8
99c016 ····GROUPBOX ·······"",IDC_BOX2,100,61,200,73
e0f287 ····LTEXT ··········"- The confirmation passphrase did not match the original",
5a2896 ····················IDC_BADCONFIRM,110,35,176,8
efe0d1 END
9caf5a
d37c0c IDD_KEYWIZ_ADK DIALOG DISCARDABLE ·0, 0, 314, 170
261d84 STYLE WS_CHILD | WS_CAPTION
26309f FONT 8, "MS Sans Serif"
eb4523 BEGIN
41c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
c6b30f ····················SS_SUNKEN,5,4,83,162
f7a76c ····LTEXT ··········"This copy of PGP Desktop Security has been configured to u¶
43e37f se an Additional Decryption Key.",
7dd6ce ····················IDC_STATIC,100,7,207,21
3f1355 ····LTEXT ··········"This means that everything encrypted to the key pair which¶
fd0a53 ·you are creating will also be encrypted to the Additional Decryption Key.",
4e4458 ····················IDC_STATIC,100,33,207,24
b09ab1 ····LTEXT ··········"Additional Decryption Key :",IDC_STATIC,100,68,159,8
ddfaeb ····EDITTEXT ·······IDC_ADK,100,80,196,14,ES_AUTOHSCROLL | ES_READONLY
324435 ····LTEXT ··········"The Additional Decryption Key cannot be changed.",
8d0509 ····················IDC_STATIC,100,120,207,8
c5e0d1 END
eeaf5a
87becd IDD_KEYWIZ_CORPCERT DIALOG DISCARDABLE ·0, 0, 313, 170
d01d84 STYLE WS_CHILD | WS_CAPTION
85e497 CAPTION "Key Generation Wizard"
b7309f FONT 8, "MS Sans Serif"
1f4523 BEGIN
72c75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
04b30f ····················SS_SUNKEN,5,4,83,162
4e3f72 ····LTEXT ··········"A Corporate Signing Key has been configured for use by you¶
fd9954 r Administrator.",
8ddd8a ····················IDC_STATIC,100,7,206,21
--90af 000c9b8d8fd401102e5 Page 11 of PGPkeys.rc
fdf05a ····LTEXT ··········"The key you are generating will be used to automatically s¶
e5a4cc ign and trust the Corporate Signing Key.",
b3f808 ····················IDC_STATIC,100,36,206,17
fca4f6 ····LTEXT ··········"Corporate Signing Key :",IDC_STATIC,101,67,163,8
4348d8 ····EDITTEXT ·······IDC_CORPCERTKEY,100,80,196,14,ES_AUTOHSCROLL |·
e5536e ····················ES_READONLY
b2e0d1 END
19af5a
dbf320 IDD_NEWGROUP DIALOGEX 0, 0, 261, 109
59e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
cc7541 EXSTYLE WS_EX_CONTEXTHELP
7b7fe1 CAPTION "PGP New Recipient Group"
ed309f FONT 8, "MS Sans Serif"
254523 BEGIN
1dcb3c ····GROUPBOX ·······"Group Info",IDC_STATIC1,6,7,248,73
ab0492 ····LTEXT ··········"A&ddress :",IDC_STATIC,24,22,30,8
f2e35a ····EDITTEXT ·······IDC_NEWGROUPNAME,64,20,178,14,ES_AUTOHSCROLL
b33689 ····LTEXT ··········"for example: all-staff@company.com",IDC_STATIC2,65,37,
e2c523 ····················114,8
6d524a ····LTEXT ··········"D&escription :",IDC_STATIC,16,57,40,8
d6e0e1 ····EDITTEXT ·······IDC_NEWGROUPDESC,64,55,178,14,ES_AUTOHSCROLL
ad558c ····DEFPUSHBUTTON ··"&OK",IDOK,146,88,50,14
64a494 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,204,88,50,14
74e0d1 END
70af5a
9394d5 IDD_DELETEALL DIALOGEX 0, 0, 222, 63
d5e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
d67541 EXSTYLE WS_EX_CONTEXTHELP
506c1a CAPTION "Delete Confirmation"
8b3884 FONT 8, "MS Sans Serif", 0, 0, 0x1
d34523 BEGIN
caed4b ····DEFPUSHBUTTON ··"&No",IDNO,117,42,40,14
107817 ····PUSHBUTTON ·····"&Cancel",IDCANCEL,169,42,40,14
59d485 ····PUSHBUTTON ·····"&Yes",IDOK,13,42,40,14
9ab03a ····PUSHBUTTON ·····"Yes to &All",IDC_YESTOALL,65,42,40,14
8b8c58 ····CTEXT ··········"Static",IDC_STRING,7,7,208,25
38e0d1 END
a4af5a
647461 IDD_KEYWIZ_REVOKER DIALOG DISCARDABLE ·0, 0, 313, 170
901d84 STYLE WS_CHILD | WS_CAPTION
ace497 CAPTION "Key Generation Wizard"
c5309f FONT 8, "MS Sans Serif"
f34523 BEGIN
795853 ····LTEXT ··········"A Designated Revocation Key has been configured for use by¶
052a50 ·your Administrator.",
65dd8a ····················IDC_STATIC,100,7,206,21
1d3a21 ····LTEXT ··········"The key you are generating will be able to be revoked by t¶
eb5be8 he Designated Revocation Key.",
aef808 ····················IDC_STATIC,100,36,206,17
550b42 ····LTEXT ··········"Designated Revocation Key :",IDC_STATIC,101,67,163,8
a6dd95 ····EDITTEXT ·······IDC_REVOCATIONKEY,100,80,196,14,ES_AUTOHSCROLL |·
b3536e ····················ES_READONLY
6ec75f ····CONTROL ········189,IDC_WIZBITMAP,"Static",SS_BITMAP | SS_REALSIZEIMAGE |·
99b30f ····················SS_SUNKEN,5,4,83,162
25e0d1 END
e4af5a
9faf5a
2e6c0e /////////////////////////////////////////////////////////////////////////////
cb465d //
116077 // DESIGNINFO
43465d //
5faf5a
01f860 #ifdef APSTUDIO_INVOKED
9b70e4 GUIDELINES DESIGNINFO DISCARDABLE·
894523 BEGIN
1be89b ····IDD_BACKUPWARN, DIALOG
445574 ····BEGIN
1ac975 ········LEFTMARGIN, 7
3c2334 ········RIGHTMARGIN, 205
1087e9 ········TOPMARGIN, 7
0600a5 ········BOTTOMMARGIN, 90
c97d01 ····END
--9a96 00038f5193b401102e5 Page 12 of PGPkeys.rc
e0af5a
1e2fa7 ····IDD_READONLY, DIALOG
015574 ····BEGIN
15c975 ········LEFTMARGIN, 7
b5934c ········RIGHTMARGIN, 208
7d87e9 ········TOPMARGIN, 7
0a6e06 ········BOTTOMMARGIN, 75
ae7d01 ····END
67af5a
4d403c ····IDD_KEYWIZ_RANDOBITS, DIALOG
425574 ····BEGIN
1df236 ········BOTTOMMARGIN, 169
a27d01 ····END
d1af5a
884524 ····IDD_SEARCH, DIALOG
645574 ····BEGIN
44ae15 ········LEFTMARGIN, 3
c01f49 ········RIGHTMARGIN, 278
afe089 ········TOPMARGIN, 3
f6dbbe ········BOTTOMMARGIN, 55
967d01 ····END
ccaf5a
acd83e ····IDD_CHOICE, DIALOG
c65574 ····BEGIN
1cf1ec ········RIGHTMARGIN, 221
747d01 ····END
dcaf5a
11c2c6 ····IDD_KEYWIZ_BADPHRASE, DIALOG
505574 ····BEGIN
5cc975 ········LEFTMARGIN, 7
ec15e7 ········RIGHTMARGIN, 306
4a87e9 ········TOPMARGIN, 7
260f46 ········BOTTOMMARGIN, 163
7c7d01 ····END
7baf5a
c9b7a1 ····IDD_KEYWIZ_ADK, DIALOG
6d5574 ····BEGIN
2dc975 ········LEFTMARGIN, 7
1e0c3f ········RIGHTMARGIN, 307
d587e9 ········TOPMARGIN, 7
030f46 ········BOTTOMMARGIN, 163
557d01 ····END
37af5a
b4fc0a ····IDD_KEYWIZ_CORPCERT, DIALOG
eb5574 ····BEGIN
4fc975 ········LEFTMARGIN, 7
3c15e7 ········RIGHTMARGIN, 306
3287e9 ········TOPMARGIN, 7
a60f46 ········BOTTOMMARGIN, 163
0d7d01 ····END
bbaf5a
3a42b1 ····IDD_NEWGROUP, DIALOG
095574 ····BEGIN
1dd0ad ········LEFTMARGIN, 6
f00351 ········RIGHTMARGIN, 254
f487e9 ········TOPMARGIN, 7
60c047 ········BOTTOMMARGIN, 102
5c7d01 ····END
d4af5a
e243b4 ····IDD_DELETEALL, DIALOG
bb5574 ····BEGIN
bac975 ········LEFTMARGIN, 7
d879e8 ········RIGHTMARGIN, 215
d287e9 ········TOPMARGIN, 7
f8f1d6 ········BOTTOMMARGIN, 56
037d01 ····END
4faf5a
be98f1 ····IDD_KEYWIZ_REVOKER, DIALOG
fa5574 ····BEGIN
66c975 ········LEFTMARGIN, 7
5f15e7 ········RIGHTMARGIN, 306
3887e9 ········TOPMARGIN, 7
--c9ca 000326e1f48401102e5 Page 13 of PGPkeys.rc
3e0f46 ········BOTTOMMARGIN, 163
677d01 ····END
60e0d1 END
ad69ab #endif ···// APSTUDIO_INVOKED
3faf5a
8baf5a
ad6c0e /////////////////////////////////////////////////////////////////////////////
78465d //
b1ae70 // Bitmap
2b465d //
04af5a
007d79 IDB_KEYWIZ8 ············BITMAP ·DISCARDABLE ····"Res\\kgwiz8bit.bmp"
755f7c IDB_KEYWIZ4 ············BITMAP ·DISCARDABLE ····"Res\\kgwiz4bit.bmp"
9a80f3 IDB_KEYWIZ1 ············BITMAP ·DISCARDABLE ····"Res\\kgwiz1bit.bmp"
29fed3 IDB_IMAGES4BIT ·········BITMAP ·DISCARDABLE ····"..\\shared\\images4.bmp"
5824e2 IDB_IMAGES24BIT ········BITMAP ·DISCARDABLE ····"..\\shared\\images24.bmp"
af7819 IDB_TOOLBAR4BIT ········BITMAP ·DISCARDABLE ····"Res\\Toolbar4bit.bmp"
5cb7c8 IDB_TOOLBAR24BIT ·······BITMAP ·DISCARDABLE ····"Res\\Toolbar24bit.bmp"
4baf5a
8b6c0e /////////////////////////////////////////////////////////////////////////////
a1465d //
f95a93 // Accelerator
81465d //
b6af5a
ff49f6 IDR_KEYMANACCEL ACCELERATORS DISCARDABLE·
f94523 BEGIN
93b179 ····"A", ···········IDM_SELECTALL, ·········VIRTKEY, CONTROL, NOINVERT
31c035 ····"C", ···········IDM_COPYKEY, ···········VIRTKEY, CONTROL, NOINVERT
0255ac ····"D", ···········IDM_SETASDEFAULT, ······VIRTKEY, CONTROL, NOINVERT
3767af ····"E", ···········IDM_EXPORTKEYS, ········VIRTKEY, CONTROL, NOINVERT
d92f9e ····"F", ···········IDM_SEARCH, ············VIRTKEY, CONTROL, NOINVERT
8e2acc ····"G", ···········IDM_GETFROMSERVER, ·····VIRTKEY, CONTROL, NOINVERT
d41bb3 ····"I", ···········IDM_KEYPROPERTIES, ·····VIRTKEY, CONTROL, NOINVERT
1de01e ····"K", ···········IDM_DOMAINKEYSERVER, ···VIRTKEY, CONTROL, NOINVERT
47720e ····"M", ···········IDM_IMPORTKEYS, ········VIRTKEY, CONTROL, NOINVERT
17feea ····"N", ···········IDM_CREATEKEY, ·········VIRTKEY, CONTROL, NOINVERT
09d699 ····"R", ···········IDM_NEWGROUP, ··········VIRTKEY, CONTROL, NOINVERT
bd1b0e ····"S", ···········IDM_CERTIFYKEY, ········VIRTKEY, CONTROL, NOINVERT
dc971a ····"T", ···········IDM_PROPERTIES, ········VIRTKEY, CONTROL, NOINVERT
19d6b8 ····"U", ···········IDM_VIEWGROUPS, ········VIRTKEY, CONTROL, NOINVERT
fdbedf ····"V", ···········IDM_PASTEKEY, ··········VIRTKEY, CONTROL, NOINVERT
a5e0d1 END
92af5a
858a59 IDR_DIALOGACCEL ACCELERATORS DISCARDABLE·
5d4523 BEGIN
acb179 ····"A", ···········IDM_SELECTALL, ·········VIRTKEY, CONTROL, NOINVERT
9ac035 ····"C", ···········IDM_COPYKEY, ···········VIRTKEY, CONTROL, NOINVERT
e667af ····"E", ···········IDM_EXPORTKEYS, ········VIRTKEY, CONTROL, NOINVERT
e6e0d1 END
bfaf5a
24af5a
d36c0e /////////////////////////////////////////////////////////////////////////////
37465d //
8ecbaf // Icon
a5465d //
3baf5a
7d2951 // Icon with lowest ID value placed first to ensure application icon
120f06 // remains consistent on all systems.
97c09d IDI_EXEICON ············ICON ···DISCARDABLE ····"res\\Key.ico"
0eaf5a
df6c0e /////////////////////////////////////////////////////////////////////////////
28465d //
59ce54 // Dialog Info
e8465d //
0caf5a
5419f6 IDD_SEARCH DLGINIT
6d4523 BEGIN
4f8d17 ····IDC_LOCATION, 0x403, 23, 0
98111f 0x6544, 0x6166, 0x6c75, 0x2074, 0x654b, 0x5379, 0x7265, 0x6576, 0x2072,·
2a4632 0x6150, 0x6874, "\000"·
92b1b6 ····IDC_LOCATION, 0x403, 14, 0
329445 0x6f4c, 0x6163, 0x206c, 0x654b, 0x7279, 0x6e69, 0x0067,·
--ac8b 00004aa8df6401102e5 Page 14 of PGPkeys.rc
ef8d17 ····IDC_LOCATION, 0x403, 23, 0
1639f8 0x7543, 0x7272, 0x6e65, 0x2074, 0x6553, 0x7261, 0x6863, 0x5220, 0x7365,·
a7d043 0x6c75, 0x7374, "\000"·
606c49 ····IDC_ATTRIBUTE, 0x403, 9, 0
b05100 0x656b, 0x2079, 0x7974, 0x6570, "\000"·
1ce6b8 ····IDC_ATTRIBUTE, 0x403, 14, 0
def7b7 0x7263, 0x6165, 0x6974, 0x6e6f, 0x6420, 0x7461, 0x0065,·
c5f030 ····IDC_ATTRIBUTE, 0x403, 16, 0
329d3d 0x7865, 0x6970, 0x6172, 0x6974, 0x6e6f, 0x6420, 0x7461, 0x0065,·
f60df1 ····IDC_ATTRIBUTE, 0x403, 7, 0
79fb67 0x656b, 0x2079, 0x6469, "\000"·
a5670d ····IDC_ATTRIBUTE, 0x403, 8, 0
1f7353 0x7375, 0x7265, 0x6920, 0x0064,·
226c49 ····IDC_ATTRIBUTE, 0x403, 9, 0
0cf140 0x656b, 0x2079, 0x6973, 0x657a, "\000"·
f0928b ····IDC_VERB, 0x403, 9, 0
1b8beb 0x6f63, 0x746e, 0x6961, 0x736e, "\000"·
9d1e94 ····IDC_VERB, 0x403, 17, 0
364a03 0x6f64, 0x7365, 0x6e20, 0x746f, 0x6320, 0x6e6f, 0x6174, 0x6e69, "\000"·
53456e ····IDC_SPECIFIER_COMBO, 0x403, 15, 0
9173b0 0x6944, 0x6666, 0x6569, 0x482d, 0x6c65, 0x6d6c, 0x6e61, "\000"·
f9e040 ····IDC_SPECIFIER_COMBO, 0x403, 4, 0
a14d30 0x5352, 0x0041,·
caeb04 ····IDC_SPECIFIER_COMBO, 0x403, 5, 0
e46b44 0x3031, 0x3432, "\000"·
7ae040 ····IDC_SPECIFIER_COMBO, 0x403, 4, 0
672cfc 0x3637, 0x0038,·
d9eb04 ····IDC_SPECIFIER_COMBO, 0x403, 5, 0
5c1825 0x3032, 0x3834, "\000"·
5f99f9 ····0
b1e0d1 END
72af5a
f784ec IDD_CHOICE DLGINIT
754523 BEGIN
9b6c49 ····IDC_ATTRIBUTE, 0x403, 9, 0
075100 0x656b, 0x2079, 0x7974, 0x6570, "\000"·
8de6b8 ····IDC_ATTRIBUTE, 0x403, 14, 0
6ff7b7 0x7263, 0x6165, 0x6974, 0x6e6f, 0x6420, 0x7461, 0x0065,·
17f030 ····IDC_ATTRIBUTE, 0x403, 16, 0
3f9d3d 0x7865, 0x6970, 0x6172, 0x6974, 0x6e6f, 0x6420, 0x7461, 0x0065,·
c80df1 ····IDC_ATTRIBUTE, 0x403, 7, 0
02fb67 0x656b, 0x2079, 0x6469, "\000"·
66670d ····IDC_ATTRIBUTE, 0x403, 8, 0
677353 0x7375, 0x7265, 0x6920, 0x0064,·
c29188 ····IDC_ATTRIBUTE, 0x403, 18, 0
4f5071 0x6572, 0x6f76, 0x6163, 0x6974, 0x6e6f, 0x7320, 0x6174, 0x7574, 0x0073,·
45af5a
c66c49 ····IDC_ATTRIBUTE, 0x403, 9, 0
9ff140 0x656b, 0x2079, 0x6973, 0x657a, "\000"·
a8e6b8 ····IDC_ATTRIBUTE, 0x403, 14, 0
0bd544 0x656b, 0x2079, 0x7369, 0x7320, 0x6769, 0x656e, 0x0064,·
73928b ····IDC_VERB, 0x403, 9, 0
608beb 0x6f63, 0x746e, 0x6961, 0x736e, "\000"·
79456e ····IDC_SPECIFIER_COMBO, 0x403, 15, 0
c073b0 0x6944, 0x6666, 0x6569, 0x482d, 0x6c65, 0x6d6c, 0x6e61, "\000"·
c6e040 ····IDC_SPECIFIER_COMBO, 0x403, 4, 0
9c4d30 0x5352, 0x0041,·
2feb04 ····IDC_SPECIFIER_COMBO, 0x403, 5, 0
2c6b44 0x3031, 0x3432, "\000"·
8be040 ····IDC_SPECIFIER_COMBO, 0x403, 4, 0
132cfc 0x3637, 0x0038,·
96eb04 ····IDC_SPECIFIER_COMBO, 0x403, 5, 0
611825 0x3032, 0x3834, "\000"·
2099f9 ····0
dce0d1 END
c8af5a
73af5a
616c0e /////////////////////////////////////////////////////////////////////////////
d3465d //
b73731 // Cursor
71465d //
04af5a
--f67d 0003134fbd6401102e5 Page 15 of PGPkeys.rc
d9b16b TREELISTDRAGGINGCURSOR ·CURSOR ·DISCARDABLE ····"res\\arrowcop.cur"
67af5a
b16c0e /////////////////////////////////////////////////////////////////////////////
3b465d //
d65e87 // String Table
0b465d //
48af5a
266f6c STRINGTABLE DISCARDABLE·
7a4523 BEGIN
fa09fb ····IDS_GENERAL ············"General strings"
f1a416 ····IDS_PASSPHRASEMISMATCH ·"Passphrase entries do not match. ·Please try again¶
4dacf9 ."
67b34d ····IDS_CAPTION ············"PGPkeys"
e3c307 ····IDS_CAPTIONKEYGEN ······"PGPkeys Key Generation"
14bca9 ····IDS_BADPASSPHRASE ······"You have selected a bad passphrase which could\nco¶
86f98d mpromise the security of your key.\n\nPassphrases should be at least 8 characte¶
7b9a9d rs,\nand they should not contain words that are found in a dictionary of any la¶
a60243 nguage.\n\nDo you want to use the bad passphrase?"
f91172 ····IDS_INVALIDNUMBITS ·····"The key size must be at least 512 bits but\nno mor¶
46a310 e than 4096 bits."
dca23c ····IDS_SUCCESSKEYGEN ······"A new public/private key pair has been created.\n\¶
9c2b9d nDo you want to use this key as the default\nsigning/encrypt to self key ?"
5cb027 ····IDS_GROUPIMPORTCAPTION ·"Select File Containing Groups"
786414 ····IDS_DELCONFKEY ·········"Remove this key from the group :\n\n%s ?"
05e0d1 END
06af5a
226f6c STRINGTABLE DISCARDABLE·
db4523 BEGIN
18be7c ····IDS_MEMALLOCFAIL ·······"Memory allocation failure."
323b61 ····IDS_VALCOLTITLE ········"Validity"
c67448 ····IDS_BACKUPCAPTION ······"Select Private Keyring Backup Destination"
029254 ····IDS_BACKUPDEFAULTFILE ··"secring.skr"
b97f74 ····IDS_BACKUPDEFAULTDIR ···"C:\\WINDOWS\\DESKTOP"
2ab93e ····IDS_REGISTRYKEY ········"Software\\Network Associates\\PGP60\\PGPkeys"
7ee0d1 END
81af5a
4d6f6c STRINGTABLE DISCARDABLE·
3d4523 BEGIN
059d64 ····IDS_CAPTIONERROR ·······"PGPkeys Error"
a8739a ····IDS_KEYGENPHASE1 ·······"Generating first prime number ..."
03c4a9 ····IDS_KEYGENPHASE2 ·······"Generating second prime number ..."
dcee51 ····IDS_NODEFAULTKEY ·······"No default private key has been assigned.\n\nYou m¶
d2403f ust assign a default private key\nin order to create signatures."
16ac32 ····IDS_CERTKEYNOTONRING ···"The private key used to create this signature\nis ¶
5036da not on your keyring."
3dff0d ····IDS_NOIMPORTKEYS ·······"The selected file does not contain any valid PGP k¶
5304d0 eys."
d4e0d1 END
36af5a
2a6f6c STRINGTABLE DISCARDABLE·
cf4523 BEGIN
a441c4 ····IDS_NOIMPORTKEYSPASTE ··"The clipboard does not contain any valid PGP keys."
62be84 ····IDS_CANNOTOPENRINGS ····"Please locate your keyring file(s)."
389b29 ····IDS_DELONLYUSERID ······"This user ID cannot be deleted because it is the\n¶
757f78 only one on the key.\n\nTo delete this user ID, you must delete the entire key."
7be538 ····IDS_BACKUPERROR ········"Backup file could not be written.\n\nCheck file na¶
6850cc me and try again."
526aa9 ····IDS_IMPORTEDSECRETKEYS ·"Some of the imported keys are private keys.\n\nThe¶
b28607 ·trust values on these keys must be\nset manually via the Key Properties dialog¶
3bacf9 ."
d0baea ····IDS_SIGNKEYPASSPHRASE ··"Passphrase of signing key :"
f44a04 ····IDS_SELKEYPASSPHRASE ···"Passphrase of selected key :"
fde786 ····IDS_GROUPIMPORTFILTER ··"Group Files (*.pgr)@*.pgr@All Files (*.*)@*.*@@"
1ce0d1 END
24af5a
106f6c STRINGTABLE DISCARDABLE·
f94523 BEGIN
3fd6f3 ····IDS_COLLAPSEALL ········"Co&llapse All"
fb89c5 ····IDS_EXPANDALL ··········"E&xpand All"
98ead5 ····IDS_COLLAPSESEL ········"Co&llapse Selection"
2c2a61 ····IDS_EXPANDSEL ··········"E&xpand Selection"
31e5cf ····IDS_HELPFILENAME ·······"PGP60.hlp"
--b008 000bda8ba36401102e5 Page 16 of PGPkeys.rc
2dbb10 ····IDS_PROPTITLE0 ·········"General"
ed0f41 ····IDS_RSA ················"RSA"
734ad8 ····IDS_DSA_ELGAMAL ········"Diffie-Hellman/DSS"
364e9f ····IDS_UNKNOWN ············"Unknown"
cd6483 ····IDS_NEVER ··············"Never"
ada045 ····IDS_KEYGENERATION ······"PGPkeys - Key Generation"
7cdd94 ····IDS_SUBKEYGENERATION ···"PGPkeys - Key Generation Phase 2"
d53059 ····IDS_NODRAGTEXTKEYS ·····"The selected text does not contain any valid PGP k¶
ea04d0 eys."
1da0d8 ····IDS_SETKEYAXIOMATIC ····"Passphrase is required for Implicit Trust"
69e0d1 END
4faf5a
406f6c STRINGTABLE DISCARDABLE·
774523 BEGIN
5c51c5 ····IDS_DEFKEYRINGEXTENSION "skr"
66df9f ····IDS_DEFEXPORTEXTENSION ·"asc"
756e98 ····IDS_CORRUPTKEYRING ·····"At least one of the selected keyring files is corr¶
b6556d upt or is not a valid keyring file."
88b1e2 ····IDS_NOSPLASHSWITCH ·····"/s"
4d1693 ····IDS_NOUSERADDR ·········"In order to take full advantage of PGP's email int¶
34864f egration\nfeatures, each name must have an associated email address.\nAre you s¶
ea7bb1 ure you want to proceed without entering an email address?"
c0e0d1 END
74af5a
2d6f6c STRINGTABLE DISCARDABLE·
504523 BEGIN
97c31b ····IDS_LOCKEDKEYRING ······"The selected keyring cannot be used because\nit is¶
eced25 ·locked by the operating system."
e1defe ····IDS_EMPTY ··············"empty"
9be0d1 END
efaf5a
416f6c STRINGTABLE DISCARDABLE·
764523 BEGIN
7f6a79 ····IDS_KW_INVALID_KEY_SIZE "This version of PGP only supports key sizes betwee¶
4f8da7 n %lu and %lu bits.\n\nPlease ensure that your selection is within this range."
ddbb00 ····IDS_KW_TITLE ···········"PGP Key Generation"
ea15ca ····IDS_KW_INVALID_KEY_TYPE "This version of PGP only supports RSA and Diffie-H¶
ed581b ellman/DSS key types."
afe0d1 END
b6af5a
606f6c STRINGTABLE DISCARDABLE·
674523 BEGIN
660e51 ····IDS_KW_INVALID_EXPIRATION·
7433af ····························"This version of PGP only supports key expirations ¶
7f4ca7 between %lu and %lu days.\n\nPlease ensure that your selection is within this r¶
7b4f66 ange."
c0840f ····IDS_KW_MISMATCHED_PHRASES·
7f47da ····························"The passphrases you entered do not match. ·Please ¶
57dd0c try again."
b42d69 ····IDS_KW_NO_EMAIL ········"In order to take advantage of PGP's email integrat¶
69a0bd ion features\n(and so others can find your key), it is strongly advised that yo¶
223175 u\nenter an email address.\n\nContinue without entering an email address?"
4425dd ····IDS_KW_NO_FULL_NAME ····"Each key must have an associated name.\nYou must e¶
8122e3 nter a name before continuing with key generation."
56c656 ····IDS_KW_NEED_MORE_BITS ··"You must complete entering random data before cont¶
cb6bbc inuing!"
6e11d9 ····IDS_KW_CONFIRM_CANCEL ··"Cancel key generation?"
326bab ····IDS_KW_COMPLETE ········"Complete"
01a81a ····IDS_SETASDEFAULT ·······"Se&t as Default Key\tCtrl+D"
6059e6 ····IDS_SETASPRIMARY ·······"Se&t as Primary Name\tCtrl+D"
119c6b ····IDS_EXPORTFILTER ·······"Text File (*.*)@*.*@@"
c7e0d1 END
16af5a
406f6c STRINGTABLE DISCARDABLE·
b24523 BEGIN
6fd990 ····IDS_KW_BAD_PASSPHRASE ··"The passphrase you entered does not match the pass¶
8f034d phrase of the key."
62885c ····IDS_KW_CANCELING ·······"Canceling ..."
2d721e ····IDS_KW_DSACUSTOM ·······"&Custom (%i - 4096 bits)"
e59462 ····IDS_KW_DSA1536 ·········"1536 bits (1536 Diffie-Hellman/1024 DSS)"
15e0d1 END
bdaf5a
--8df4 000c61b0b9d401102e5 Page 17 of PGPkeys.rc
6e6f6c STRINGTABLE DISCARDABLE·
bf4523 BEGIN
fe94e5 ····IDS_KW_DSA2048 ·········"2048 bits (2048 Diffie-Hellman/1024 DSS)"
9b50e0 ····IDS_KW_DSA3072 ·········"3072 bits (3072 Diffie-Hellman/1024 DSS)"
ca06cd ····IDS_KW_RSACUSTOM ·······"&Custom (%i - 2048 bits)"
ff6adf ····IDS_KW_RSA1536 ·········"1536 bits"
98510a ····IDS_KW_RSA2048 ·········"2048 bits"
2e3f30 ····IDS_ANIMATIONFILE ······"KeyGen.avi"
bf880f ····IDS_KW_CANCELED ········"Canceled"
ca0eb4 ····IDS_KW_SENDLATER ·······"If you wish to send your key to the server at a la¶
9a0fe0 ter date, simply right click on it in PGPkeys, and use the ""Send to"" menu ite¶
62be92 m."
621a5e ····IDS_PUBBACKUPDEFAULTFILE "pubring.pkr"
3bc334 ····IDS_DEFPUBKEYRINGEXTENSION "pkr"
5dd331 ····IDS_PUBBACKUPCAPTION ···"Select Public Keyring Backup Destination"
7faf9b ····IDS_PUBBACKUPFILTER ····"Public keyring file (*.pkr)@*.pkr@PGP file (*.pgp)¶
def448 @*.pgp@@"
2ebcc9 ····IDS_BACKUPFILTER ·······"Secret keyring file (*.skr)@*.skr@PGP file (*.pgp)¶
9af448 @*.pgp@@"
7d4745 ····IDS_INVALIDDATE ········"Unknown"
7080c5 ····IDS_GROUPCOLTITLE ······"Recipient Groups"
ae36b5 ····IDS_DESCCOLTITLE ·······"Description"
ebe0d1 END
6baf5a
096f6c STRINGTABLE DISCARDABLE·
704523 BEGIN
3666a5 ····IDS_SEARCHTITLE ········"PGPkeys Search Window"
5ae0d1 END
71af5a
496f6c STRINGTABLE DISCARDABLE·
0b4523 BEGIN
8bb2ae ····IDS_SEARCH_STRINGTABLE_BASE " "
4bcda7 ····IDS_ATTRIBUTE_1 ········"User ID"
fbdb53 ····IDS_ATTRIBUTE_2 ········"Key ID"
f26554 ····IDS_ATTRIBUTE_3 ········"Key Type"
906aff ····IDS_ATTRIBUTE_4 ········"Creation Date"
01284e ····IDS_ATTRIBUTE_5 ········"Expiration Date"
ec5405 ····IDS_ATTRIBUTE_6 ········"Key Status"
19ccdb ····IDS_ATTRIBUTE_7 ········"Key Size"
026dc6 ····IDS_ATTRIBUTE_LAST ·····" "
1db9ba ····IDS_VERBS_ATTRIBUTE_1 ··"is,is not,contains,does not contain,is signed by,i¶
67ad68 s not signed by,"
c6aa62 ····IDS_VERBS_ATTRIBUTE_2 ··"is,is not,"
5f3fed ····IDS_VERBS_ATTRIBUTE_3 ··"is,"
ca10a5 ····IDS_VERBS_ATTRIBUTE_4 ··"is on,is on or before,is on or after,"
9f90e2 ····IDS_VERBS_ATTRIBUTE_5 ··"is on,is on or before,is on or after,"
8de0d1 END
03af5a
d36f6c STRINGTABLE DISCARDABLE·
974523 BEGIN
260f6d ····IDS_VERBS_ATTRIBUTE_6 ··"is,is not"
5e0159 ····IDS_VERBS_ATTRIBUTE_7 ··"is,is at least,is at most,"
467408 ····IDS_VERBS_LAST ·········" "
8cd0a9 ····IDS_SPECIFIERS_ATTRIBUTE_1 " "
17dcd4 ····IDS_SPECIFIERS_ATTRIBUTE_2 " "
f27cc9 ····IDS_SPECIFIERS_ATTRIBUTE_3 "*,Diffie-Hellman,RSA,"
b38237 ····IDS_SPECIFIERS_ATTRIBUTE_4 "Date"
09cfca ····IDS_SPECIFIERS_ATTRIBUTE_5 "Date"
30eaf9 ····IDS_SPECIFIERS_ATTRIBUTE_6 "*,revoked,disabled,"
6759ff ····IDS_SPECIFIERS_ATTRIBUTE_7 "512,768,1024,2048,4096,"
9609de ····IDS_SPECIFIERS_LAST ····" "
df105f ····IDS_LOCAL_KEYRING ······"Local Keyring"
2f314d ····IDS_CURRENT_SEARCH ·····"Current Search Results"
29e0d1 END
08af5a
cb6f6c STRINGTABLE DISCARDABLE·
884523 BEGIN
755079 ····IDS_DEFAULT_PATH ·······"Default Server Search Path"
a1b17b ····IDS_MONTH1 ·············"Jan"
e248b0 ····IDS_MONTH2 ·············"Feb"
19cf49 ····IDS_MONTH3 ·············"Mar"
c6e367 ····IDS_MONTH4 ·············"Apr"
--c2ea 000632a47bf401102e5 Page 18 of PGPkeys.rc
825587 ····IDS_MONTH5 ·············"May"
f08432 ····IDS_MONTH6 ·············"Jun"
8206e6 ····IDS_MONTH7 ·············"Jul"
7a5fd9 ····IDS_MONTH8 ·············"Aug"
22e0d1 END
d7af5a
a36f6c STRINGTABLE DISCARDABLE·
4d4523 BEGIN
91004c ····IDS_MONTH9 ·············"Sep"
37a1b5 ····IDS_MONTH10 ············"Oct"
8b572b ····IDS_MONTH11 ············"Nov"
c012ee ····IDS_MONTH12 ············"Dec"
81b622 ····IDS_SEARCH_MESSAGE_BASE " "
004103 ····IDS_SEARCH_MESSAGE_CONNECTING "Connecting to server."
10102e ····IDS_SEARCH_MESSAGE_QUERYING "Querying server."
8d7569 ····IDS_SEARCH_MESSAGE_PROCESSING "Processing results from server."
63e0d1 END
deaf5a
aa6f6c STRINGTABLE DISCARDABLE·
914523 BEGIN
aeb039 ····IDS_SEARCH_MESSAGE_SENDING "Sending keys to server."
bb63a5 ····IDS_SEARCH_MESSAGE_CLOSING "Closing server connection."
ed40b6 ····IDS_REQPHRASELENGTH ····"- It did not meet the required length of %i charac¶
063d06 ters."
e286b6 ····IDS_REQPHRASEQUALITY ···"- It did not meet the required quality of %i out o¶
f25a12 f 100."
c6561d ····IDS_ADMINPREFSCORRUPT ··"The Administration Preferences file is corrupt or ¶
e11b1f out of date.\nContact your Security Administrator."
b60709 ····IDS_SUGPHRASELENGTH ····"- It did not meet the suggested length of %i chara¶
c164d7 cters."
78b0db ····IDS_SUGPHRASEQUALITY ···"- It did not meet the suggested quality of %i out ¶
dcdd60 of 100."
edca96 ····IDS_PHRASEREJECTED ·····"The passphrase you entered has been rejected becau¶
6a8bc5 se :"
a2edb1 ····IDS_PHRASEWARNED ·······"Your passphrase is a potential security hazard bec¶
a23894 ause :"
9b1168 ····IDS_MISSINGCORPKEY ·····"The required Corporate Signing Key is not on your ¶
d1f73d keyring.\nContact your Security Administrator."
a45b65 ····IDS_MISSINGADK ·········"The required Additional Decryption Key is not on y¶
9a3003 our keyring.\nContact your Security Administrator."
fe311f ····IDS_KW_UNABLETOCOMPLETE "Unable to complete key generation"
27761e ····IDS_MISSINGREVOKERKEY ··"The required Designated Revocation Key is not on y¶
fc3003 our keyring.\nContact your Security Administrator."
d17e74 ····IDS_SENDTOSERVERMENU ···"Send &to"
9ca468 ····IDS_SEARCH_MESSAGE_SERVER_NAME "Searching for keys on %s"
7fe0d1 END
bbaf5a
8f6f6c STRINGTABLE DISCARDABLE·
9b4523 BEGIN
f6552f ····IDS_SEARCH_MESSAGE_CANCEL "Search canceled."
87f610 ····IDS_SEARCHABORTED ······"Search canceled."
50d85b ····IDS_KSKEYCOUNT ·········"Found %i key(s) matching search criteria."
d7f101 ····IDS_PHRASELENGTHTEXT ···"Your passphrase should be at least %i characters l¶
1d6b10 ong and should contain non-alphabetic characters."
01aeac ····IDS_SYNCINGKEYSETS ·····"Synchronizing results with keyring."
ef039f ····IDS_GROUPNAMEFIELD ·····"Groups"
d37f4e ····IDS_VALIDITYFIELD ······"Validity"
d3f87a ····IDS_DESCRIPTIONFIELD ···"Description"
003570 ····IDS_NEEDGROUPNAME ······"A group must have a name."
5e048f ····IDS_UNAVAILABLE ········"Unknown Key, Key ID is "
a1bbe3 ····IDS_DELCONFGROUP ·······"Are you sure you want to delete this group :\n\n%s¶
25450d ·?"
c6406b ····IDS_NOIMPORTGROUPS ·····"File does not contain any group information."
613ee9 ····IDS_GROUPPROPS ·········"PGPKeys Group Properties"
dd5654 ····IDS_STRING2094 ·········"import"
ea4706 ····IDS_NOPASTEKEYS ········"The clipboard does not contain any keys."
2fe0d1 END
96af5a
746f6c STRINGTABLE DISCARDABLE·
114523 BEGIN
8198a6 ····IDS_KEYSELECTED ········" %i key(s) selected"
63d4e3 ····IDS_GROUPSELECTED ······" %i group(s) selected."
--66cd 0005f0775eb401102e5 Page 19 of PGPkeys.rc
8e9d5f ····IDS_MULTISELECTED ······" %i objects selected"
c5e0d1 END
50af5a
d96f6c STRINGTABLE DISCARDABLE·
e94523 BEGIN
d3fc21 ····IDS_SERVERSEARCHFAIL ···"No matching keys were found on the server."
35e0d1 END
29af5a
736f6c STRINGTABLE DISCARDABLE·
d64523 BEGIN
c3010c ····IDS_EMPTYGROUP ·········"The selected group is empty."
d64edc ····IDS_KSTOOMANYKEYCOUNT ··"Search exceeded server limits. ·First %i keys are ¶
647c88 shown."
c90a46 ····IDS_EXPIREDADK ·········"The required Additional Decryption Key is expired.¶
21f0ac \nContact your Security Administrator."
ff10eb ····IDS_REVOKEDADK ·········"The required Additional Decryption Key has been re¶
d1e584 voked.\nContact your Security Administrator."
e8e328 ····IDS_EXPIREDCORPKEY ·····"The required Corporate Signing Key is expired.\nCo¶
5dc702 ntact your Security Administrator."
aa66c8 ····IDS_REVOKEDCORPKEY ·····"The required Corporate Signing Key has been revoke¶
8db4ad d.\nContact your Security Administrator."
f5775f ····IDS_GROUPSINFREEWARE ···"PGPfreeware does not support the Groups feature. ·¶
846970 You may edit and create Groups, but they will not be available when encrypting.¶
6d5e13 \n\nPGP for Personal Privacy and PGP Desktop Security support handling of Group¶
b3d371 s."
96b330 ····IDS_SEARCHINFREEWARE ···"PGPfreeware only supports User ID and Key ID searc¶
cd4aa6 hes.\n\nPGP for Personal Privacy and PGP Desktop Security support all search ca¶
9ab76f tegories along with many other new features. "
69e63e ····IDS_UPGRADE ············"&Upgrade ..."
d30f23 ····IDS_UPGRADEURL ·········"http://www.pgp.com/products/products.cgi"
68dbee ····IDS_SPLITKEYWARNING ····"You have started a split key operation which has n¶
d702f7 ot been completed.\n\nAre you sure you want to quit PGPkeys?"
6d063a ····IDS_TOOLTIPNEWKEY ······"Generate new keypair"
58e0d1 END
bdaf5a
366f6c STRINGTABLE DISCARDABLE·
5a4523 BEGIN
1ee2f3 ····IDS_TOOLTIPREVOKE ······"Revoke the selected item"
6bb19a ····IDS_TOOLTIPSIGN ········"Sign the selected item"
2881a3 ····IDS_TOOLTIPDELETE ······"Delete the selected item"
7953d1 ····IDS_TOOLTIPSEARCH ······"Open key search window"
575dfd ····IDS_TOOLTIPNEWGROUP ····"Create a new group"
881ae1 ····IDS_TOOLTIPUPDATE ······"Update key from server"
1eacdb ····IDS_TOOLTIPSENDTOSERVER "Send key to server"
14ab50 ····IDS_TOOLTIPPROPERTIES ··"Show key properties"
938c2a ····IDS_TOOLTIPIMPORT ······"Import keys from a file"
99de53 ····IDS_TOOLTIPEXPORT ······"Export selected keys to a file"
1e273d ····IDS_EXPIREDREVOKERKEY ··"The required Designated Revocation Key is expired.¶
3ef0ac \nContact your Security Administrator."
e13d90 ····IDS_REVOKEDREVOKERKEY ··"The required Designated Revocation Key has been re¶
d9e584 voked.\nContact your Security Administrator."
11060e ····IDS_COMCTLERRORSWITCH ··"/c"
18c629 ····IDS_DOMAINSERVER ·······"&Domain Server\tCtrl+K"
dc4e75 ····IDS_CONNECTIONNOTAUTHENTICATED·
02935a ····························"No authentication information is available because¶
022d0a ·:\n\nThe previous server connection was not authenticated"
988f83 ····IDS_NOCONNECTIONYET ····"No authentication information is available because¶
444ee3 ·:\n\nYou have not yet connected to a server."
13e0d1 END
76af5a
a96f6c STRINGTABLE DISCARDABLE·
2a4523 BEGIN
393325 ····IDS_SEARCH_MESSAGE_DELETING "Deleting keys from server."
8fdd1b ····IDS_SEARCH_MESSAGE_DISABLING "Disabling keys on server."
979805 ····IDS_SDKEXPIRED ·········"This version of PGP has expired."
59cfee ····IDS_NONEWTRUSTEDINTROS ·"No trusted introducers were found on server."
311478 ····IDS_NOUPDATEDKEYS ······"No keys were updated because none of the keys\non ¶
022dd3 your keyring could be found on the server(s)."
0a899b ····IDS_AUTOUPDATECAPTION ··"PGP Auto Update Warning"
dbe0d1 END
29af5a
5f1b3a #endif ···// English (U.S.) resources
--70a1 00145427ed3401102e5 Page 20 of PGPkeys.rc
876c0e /////////////////////////////////////////////////////////////////////////////
bcaf5a
05af5a
45af5a
f1ce8c #ifndef APSTUDIO_INVOKED
3a6c0e /////////////////////////////////////////////////////////////////////////////
99465d //
b98464 // Generated from the TEXTINCLUDE 3 resource.
2a465d //
75e98e #include "PKVer.rc"
06af5a
516c0e /////////////////////////////////////////////////////////////////////////////
9d8072 #endif ···// not APSTUDIO_INVOKED
45af5a
--bf8d 000e95ed31e401102e6 Page 1 of PGPkeysx.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
5701d7 ¤   PGPKeysx.h - internal include file for PGPkeys project¤
0faf5a
0b4e5a ¤   $Id: PGPkeysx.h,v 1.66.2.1 1998/10/08 15:35:08 pbj Exp $
4ff7f7 ____________________________________________________________________________*/
081b38 #ifndef Included_PGPkeysx_h¤/* [ */
fd4b2f #define Included_PGPkeysx_h
96af5a
122a68 #define WIN32_LEAN_AND_MEAN
f4ca87 #define _WIN32_WINNT 0x0400
2eaf5a
f3d881 // Win32 header files
765655 #include <windows.h>
b490fb #include <commctrl.h>
c4af5a
897b85 // PGP build flags
f981a4 #include "pgpBuildFlags.h"
bdaf5a
d0d495 // PGP SDK header files
b50d08 #include "pgpMem.h"
ed2f8d #include "pgpErrors.h"
944919 #include "pgpUtilities.h"
80a076 #include "pgpKeys.h"
463991 #include "pgpAdminPrefs.h"
10c97b #include "pgpClientPrefs.h"
10ed82 #include "pgpKeyServerPrefs.h"
88af5a
1e8687 // PGP client header files
3e7835 #include "..\include\help\PGPpkHlp.h"
4cf675 #include "..\include\pgpWerr.h"
16bdfa #include "..\include\pgpkm.h"
4a8c0e #include "..\include\pgpgm.h"
af97e6 #include "..\include\pgpcl.h"
9bbeb4 #include "..\include\treelist.h"
9f8031 #include "resource.h"
efaf5a
bbe627 #define MAXSHEETS¤  16¤ ¤   // maximum number of simultaneous dialogs
37af5a
fa418b #define IDC_STATUSBAR¤  ¤   ¤   0x3333
bd4d5e #define IDC_TOOLBAR¤¤   ¤   ¤   0x3334
b7cbaf #define IDM_DOMAINKEYSERVERX¤   41000
3964e0 #define IDM_TOOLBARSENDTOSERVER¤42000
10af5a
b37274 // macro definitions
81e205 #define CKERR¤  ¤   ¤   if (IsPGPError (err)) goto done¤
75af5a
5f5584 // constant definitions
18cafd #define KCD_NEWKEY¤ ¤   ¤   0x0001
f42482 #define KCD_NEWDEFKEY¤  ¤   0x0002
2baf5a
1d42bb #define DEFAULTWINDOWWIDTH¤ 520
c114fc #define DEFAULTWINDOWHEIGHT 300
8bb3a0 #define DEFAULTWINDOWX ·····85
5ebd06 #define DEFAULTWINDOWY¤ ¤   90
c67e8a #define¤DEFAULTGROUPSHOW¤   FALSE
83e0ce #define DEFAULTGROUPPERCENT¤30
9a7b06 #define¤DEFAULTTOOLHEIGHT¤  28
75eefc #define TOOLBARXOFFSET¤ ¤   4
8ba6d6 #define TOOLBARYOFFSET¤ ¤   4
75af5a
bddc3f #define KM_M_CREATEDONE¤¤   ¤   ¤   WM_APP+99
d7b90b #define KM_M_RELOADKEYRINGS¤¤   ¤   WM_APP+98
380840 #define KM_M_GENERATION_COMPLETE¤   WM_APP+97
e29a17 #define KM_M_CHANGEPHASE¤   ¤   ¤   WM_APP+96
631520 #define KM_M_RESIZE¤¤   ¤   ¤   ¤   WM_APP+95
2eaf5a
cb5bee // typedefs
e7f0f7 typedef struct {
e93410 ¤   HWND¤   ¤   ¤   hWndMain;
--ff4b 0006635ec9d401102e6 Page 2 of PGPkeysx.h
228c0b ¤   BOOL¤   ¤   ¤   bMainWindow;
489c4d ¤   BOOL¤   ¤   ¤   bMemoryKeySet;
860432 ¤   BOOL¤   ¤   ¤   bLocalKeySet;
4bc3c9 ¤   UINT¤   ¤   ¤   uKeySelectionFlags;
0a4da5 ¤   HKEYMAN¤¤   ¤   hKM;
9b19f1 ¤   KMCONFIG¤   ¤   kmConfig;
94e69b ¤   HWND¤   ¤   ¤   hWndTreeList;¤
172c34 ¤   HWND¤   ¤   ¤   hWndToolBar;
15fe46 ¤   HWND¤   ¤   ¤   hWndSearchControl;
f02fe3 ¤   PGPKeySetRef¤   KeySetDisp;
a6da31 ¤   PGPKeySetRef¤   KeySetMain;
b0af5a
9f16ca ¤   HMENU¤  ¤   ¤   hMenuKeyMan;
fa276d ¤   HMENU¤  ¤   ¤   hMenuKeyserver;
c0d18c ¤   INT¤¤   ¤   ¤   iToolHeight;
e60894 ¤   INT¤¤   ¤   ¤   iKeysHeight;
07af5a
a9d102 ¤   PGPclGROUPFILE*¤pGroupFile;
26394b ¤   BOOL¤   ¤   ¤   bGroupsVisible;
280158 ¤   BOOL¤   ¤   ¤   bGroupsFocused;
c512e3 ¤   HGROUPMAN¤  ¤   hGM;
d7b7d1 ¤   GMCONFIG¤   ¤   gmConfig;
97d732 ¤   UINT¤   ¤   ¤   uGroupSelectionFlags;
d7f1d5 ¤   HWND¤   ¤   ¤   hWndTreeListGroups;
603700 ¤   INT¤¤   ¤   ¤   iGroupsHeight;
417c64 ¤   INT¤¤   ¤   ¤   iGroupsPercent;
2eb835 ¤   BOOL¤   ¤   ¤   bGrabEnabled;
01b246 ¤   BOOL¤   ¤   ¤   bGrabbed;
b8fa50 ¤   HCURSOR¤¤   ¤   hCursorOld;
feaf5a
8e8f91 ¤   BOOL¤   ¤   ¤   bSearchInProgress;
cd0a0b ¤   INT¤¤   ¤   ¤   iStatusValue;
612016 ¤   INT¤¤   ¤   ¤   iStatusPrevValue;
fa67e9 ¤   INT¤¤   ¤   ¤   iStatusDirection;
d0af5a
704f31 ¤   INT¤¤   ¤   ¤   iTLSstatus;
a8be27 ¤   CHAR¤   ¤   ¤   szTLSserver[256];
5b30eb ¤   PGPKeySetRef¤   keysetAuth;
630028 ¤   PGPKeyRef¤  ¤   keyAuth;
efad00 } PGPKEYSSTRUCT, *PPGPKEYSSTRUCT;
0baf5a
75af5a
5efa8d // PGPkeys.c
88e23e VOID PKDialogListFunc (HWND hwndDlg, BOOL bAdd, POINT* ppt, HWND phwnd);
f4525f VOID PKEnableDlgList (BOOL bEnabled);
d87d4b VOID PKReloadDlgList (VOID);
987844 VOID PKPostMessageDlgList (UINT uMsg, WPARAM wParam, LPARAM lParam);
57af5a
05a3cc // PKgenwiz.c
4957e5 VOID PKCreateKey (HWND hParent, PGPKeySetRef keyset);
49af5a
3c57fc // PKMenu.c
7fda95 VOID PKInitMenuKeyMan (HMENU hmenu);
bd1e84 VOID PKSetMainMenu (PGPKEYSSTRUCT*¤ ppks);
b380ee VOID PKContextMenu (PGPKEYSSTRUCT*¤ ppks, HWND hWnd, INT x, INT y);
df1fb1 VOID PKGetServerFromID (UINT uID, PGPKeyServerEntry* pkeyserver);
2f4ab2 VOID PKToolbarKeyserverMenu (HWND hWnd, LPRECT lprect);·
bbaf5a
7f2607 // PKMisc.c
573107 VOID* pkAlloc (LONG size);
c5354b VOID pkFree (VOID* p);
1beb1e BOOL PKGetPrivatePrefData (DWORD* show, INT* X, INT* Y,·
beefc2 ¤   ¤   ¤   INT* Width, INT* Height, BOOL* bShowGroups, INT* iGroupsPercent,
b2a33e ¤   ¤   ¤   INT* iToolHeight);
fa6165 BOOL PKGetColWidthsFromRegistry (WORD * widths, INT nWidths);
c6819d BOOL PKGetSortOrderFromRegistry (LONG * field);
e88e3c VOID PKReloadPGPPreferences (PGPKEYSSTRUCT* ppks);
9ada7f BOOL PKPGPPreferences (PGPKEYSSTRUCT* ppks, HWND hwnd, INT iPage);
5f055e VOID PKSetPrivatePrefData (HWND hWnd, BOOL bGroupShow,·
4f7899 ¤   ¤   ¤   ¤   ¤   ¤   ···INT iGroupPercent, INT iToolHeight);
554a43 VOID PKSetPathRegistryData (VOID);
66419c INT ·PKCommitKeyRingChanges (PGPKeySetRef KeySet, BOOL bBroadcast);
--f3c4 00130087d31401102e6 Page 3 of PGPkeysx.h
fb698b BOOL PKAutoUpdateAllKeys (HWND hwnd, PGPKeySetRef keyset, BOOL bForce);
01555b BOOL PKAutoUpdateIntroducers (HWND hwnd, PGPKeySetRef keyset, BOOL bForce);
56af5a
63e7ea // PKMsgPrc.c
f06928 LONG APIENTRY KeyManagerWndProc(HWND hWndDlg, UINT msg, WPARAM wParam,·
e2f776 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
14af5a
17bb0e // PKSend.c
ae81a8 INT PKSendShares (PGPContextRef context, HWND hwnd, PGPKeySetRef keyset);·
dbaf5a
9d7810 // PKTools.c
15887f HWND PKCreateToolbar (HWND hwndParent);
801a4b VOID PKDestroyToolbar (HWND hwndToolbar);
3618ef VOID PKGetToolbarTooltipText (LPTOOLTIPTEXT lpttt);
cef12e VOID PKSetToolbarButtonStates (PPGPKEYSSTRUCT ppks);
7a67f4 VOID PKGetSendToServerButtonRect (HWND hwndToolbar, LPRECT lprect);
2eaf5a
d5765e // PKUser.c
f9e288 LRESULT PKMessageBox (HWND hwnd, INT iCaption,·
737452 ¤   ¤   ¤   ¤   ¤   ¤   ···INT iMessage, ULONG flags);
cd8753 BOOL PKBackupWarn (HWND hwnd, BOOL* pbBackup);
27c5bb VOID PKBackup (HWND hWnd);
f38571 VOID PKHelpAbout (HWND hWnd);
c6c6f2 VOID PKReadOnlyWarning (HWND hWnd);
4718ae VOID PKWipeEditBox (HWND hDlg, UINT uID);
d89ebf BOOL PKSplitKeyWarn (HWND hWnd);
fcaf5a
24a3cc // PKgenwiz.c
24e3ac VOID PGPkeysCreateKey (HWND hwnd, PGPKeySetRef KeySet);
daaf5a
73db58 #endif /* ] Included_PGPkeysx_h */
1aaf5a
d9af5a
8f7e4d /*__Editor_settings____
69af5a
514126 ¤   Local Variables:
027b17 ¤   tab-width: 4
850e6c ¤   End:
3a5f8c ¤   vi: ts=4 sw=4
939e9b ¤   vim: si
30d062 _____________________*/
--2a7d 000c0db7a46401102e7 Page 1 of PKMenu.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
e296b6 ¤   PGPkeysMenu.c - handle menu enabling/disabling chores
0b67c5 ¤
2faf5a
9dbeae ¤   $Id: PKMenu.c,v 1.54 1998/08/11 15:20:08 pbj Exp $
68f7f7 ____________________________________________________________________________*/
c5e610 #include "pgpPFLConfig.h"
7aaf5a
11c917 // project header files
f6c55a #include "pgpkeysx.h"
b5af5a
4aad8c // pgp header files
81b26d #include "pgpkeyserverprefs.h"
63af5a
5b5584 // constant definitions
1635e5 #define¤SENDTOSERVERPOS¤0
88af5a
e50f5c #define MENU_FILE¤  ¤   0
1c670d #define MENU_EDIT¤  ¤   1
0d051b #define MENU_VIEW¤  ¤   2
7254de #define MENU_KEYS¤  ¤   3
6a42c1 #define MENU_SERVER¤¤   4
cb3e4c #define MENU_GROUPS¤¤   5
7e2a79 #define MENU_HELP¤  ¤   6
e3af5a
548194 #define SUBMENU_ADD¤¤   2
6eaf5a
d0822f // External globals
1aeec0 extern HINSTANCE¤   ¤   g_hInst;
132e92 extern PGPBoolean¤  ¤   g_bKeyGenEnabled;
b31924 extern BOOL¤¤   ¤   ¤   g_bReadOnly;
4bcf38 extern PGPContextRef¤   g_Context;
85af5a
d24265 //¤ ___________________________________________________
cd465d //
b7bf15 //¤ create popup menu which is list of keyservers
d6af5a
d0e0ce static HMENU
338da6 sCreateKeyserverMenu (VOID)
1cbb36 {
d77355 ¤   PGPUInt32¤  ¤   ¤   uNumServers¤= 0;
37ded2 ¤   HMENU¤  ¤   ¤   ¤   hmenu¤  ¤   = NULL;
1faf5a
cb476b ¤   PGPKeyServerEntry*¤ keyserverList;
d9697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
956a21 ¤   PGPUInt32¤  ¤   ¤   u, uID;
8e8f52 ¤   PGPError¤   ¤   ¤   err;
31b697 ¤   CHAR¤   ¤   ¤   ¤   sz[256];
84af5a
6f94fa ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (g_Context),·
5713a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
bb6374 ¤   if (IsPGPError (err)) return NULL;
90af5a
d7e12a ¤   hmenu = CreatePopupMenu ();
077d34 ¤   err = PGPGetKeyServerPrefs (prefref, &keyserverList, &uNumServers);
7aaf5a
65b23e ¤   if (IsntPGPError (err)) {
b7d407 ¤   ¤   LoadString (g_hInst, IDS_DOMAINSERVER, sz, sizeof(sz));
ec82c0 ¤   ¤   AppendMenu (hmenu, MF_STRING, IDM_DOMAINKEYSERVERX, sz);
f1d982 ¤   ¤   AppendMenu (hmenu, MF_SEPARATOR, 0, NULL);
54af5a
eccb48 ¤   ¤   uID = 1;
5c5a17 ¤   ¤   for (u=0; u<uNumServers; u++) {
cb2a43 ¤   ¤   ¤   if (IsKeyServerListed (keyserverList[u].flags)) {
4bc131 ¤   ¤   ¤   ¤   PGPGetKeyServerURL (&(keyserverList[u]), sz);
7210aa ¤   ¤   ¤   ¤   AppendMenu (hmenu, MF_STRING, IDM_DOMAINKEYSERVERX +uID, sz);
a68238 ¤   ¤   ¤   ¤   ++uID;
2fa3a6 ¤   ¤   ¤   }
c00fe4 ¤   ¤   }
--71b1 00001d006a7401102e7 Page 2 of PKMenu.c
e0af5a
ff1697 ¤   ¤   if (keyserverList) PGPDisposePrefData (prefref, keyserverList);
739371 ¤   }
1aaf5a
37ab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
8aaf5a
fd8320 ¤   return hmenu;
3fefe6 }
15af5a
3aaf5a
d44265 //¤ ___________________________________________________
f1465d //
f40499 //¤ initialize the main window menu based on build flags
9faf5a
4afe80 VOID
b17569 PKInitMenuKeyMan (HMENU hmenu)
56bb36 {
320211 #if !PGP_ADMIN_BUILD
65a77c ¤   HMENU¤  ¤   ¤   hmenuServer;
39af5a
935ad5 ¤   // get "Servers" menu
0527dd ¤   hmenuServer = GetSubMenu (hmenu, MENU_SERVER);
d5af5a
a9908e ¤   // delete "Send Group Lists" item
7d4750 ¤   DeleteMenu (hmenuServer, IDM_SENDGROUPLISTS, MF_BYCOMMAND);
84af5a
cb5a91 #if !PGP_BUSINESS_SECURITY
b14415 ¤   // delete "Update" items
7e3fd6 ¤   DeleteMenu (hmenuServer, IDM_UPDATEGROUPLISTS, MF_BYCOMMAND);
e7f39e ¤   DeleteMenu (hmenuServer, IDM_UPDATEINTRODUCERS, MF_BYCOMMAND);
a9af5a
c966e3 ¤   // delete separator
11413f ¤   DeleteMenu (hmenuServer, (GetMenuItemCount (hmenuServer) -1),·
0bdc5d ¤   ¤   ¤   ¤   ¤   MF_BYPOSITION);
71af5a
03b779 #endif //!PGP_BUSINESS_SECURITY
a2aecc #endif //!PGP_ADMIN_BUILD
fcefe6 }
e8af5a
4faf5a
e64265 //¤ ___________________________________________________
92465d //
d150fd //¤ derive the keyserver string name from the menu ID
08af5a
54fe80 VOID
0341ea PKGetServerFromID (
f133a4 ¤   ¤   UINT¤   ¤   ¤   ¤   uID,·
7261ce ¤   ¤   PGPKeyServerEntry*¤ pkeyserver)
e1bb36 {
991775 ¤   PGPUInt32¤  ¤   ¤   uNumServers¤¤   = 0;
d8879f ¤   HMENU¤  ¤   ¤   ¤   hmenu¤  ¤   ¤   = NULL;
de5704 ¤   PGPKeyServerEntry*¤ keyserverList¤  = NULL;
dda4a6 ¤   PGPPrefRef¤ ¤   ¤   prefref¤¤   ¤   = kInvalidPGPPrefRef;
96af5a
b91ea2 ¤   PGPUInt32¤  ¤   ¤   u1, u2;
618f52 ¤   PGPError¤   ¤   ¤   err;
c5e02a //¤ CHAR¤   ¤   ¤   ¤   sz[kPGPMaxUserIDSize];
57c72f //¤ PGPKeySetRef¤   ¤   keyset;
b2af5a
4294fa ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (g_Context),·
7d13a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
07ec03 ¤   if (IsPGPError (err)) return;
a6af5a
ae5be3 ¤   if (uID == IDM_DOMAINKEYSERVERX) {
1239f5 ¤   ¤   err = PGPCreateKeyServerPath (prefref, "",·
ed5b78 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverList, &uNumServers);
fb8536 ¤   ¤   if (IsntPGPError (err)) {
7e7e9c ¤   ¤   ¤   CopyMemory (pkeyserver, &(keyserverList[0]),
f8fc2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(PGPKeyServerEntry));
a64147 ¤   ¤   ¤   PGPDisposeKeyServerPath (keyserverList);
370fe4 ¤   ¤   }
019371 ¤   }
--fd7d 000ec181352401102e7 Page 3 of PKMenu.c
75665a ¤   else {
190b67 ¤   ¤   PGPGetKeyServerPrefs (prefref, &keyserverList, &uNumServers);
e2af5a
3a1154 ¤   ¤   if ((uID - IDM_DOMAINKEYSERVERX) <= uNumServers) {
109921 ¤   ¤   ¤   u1 = IDM_DOMAINKEYSERVERX+1;
c22ca5 ¤   ¤   ¤   for (u2=0; u2<uNumServers; u2++) {
88066e ¤   ¤   ¤   ¤   if (IsKeyServerListed (keyserverList[u2].flags)) {
968fde ¤   ¤   ¤   ¤   ¤   if (uID == u1) {
030115 ¤   ¤   ¤   ¤   ¤   ¤   CopyMemory (pkeyserver, &(keyserverList[u2]),
6dfc2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(PGPKeyServerEntry));
dd00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
fd1c89 ¤   ¤   ¤   ¤   ¤   }
a6ded5 ¤   ¤   ¤   ¤   ¤   u1++;
d82613 ¤   ¤   ¤   ¤   }
3ca3a6 ¤   ¤   ¤   }
750fe4 ¤   ¤   }
d41697 ¤   ¤   if (keyserverList) PGPDisposePrefData (prefref, keyserverList);
bd9371 ¤   }
d8af5a
42ab5d ¤   PGPclCloseClientPrefs (prefref, FALSE);
4faf5a
6d830f ¤   return;
8defe6 }
d4af5a
2faf5a
df3fc0 //¤ _____________________________________________________
db465d //
887896 // ·Set the Expand/Collapse items to "All" or "Selection"
b6af5a
ccb333 static VOID·
2493ff sSetMenuAllOrSelected (
9ba555 ¤   ¤   HMENU¤  hMenu,·
c7c991 ¤   ¤   BOOL¤   bAll)·
48bb36 {
4da700 ¤   MENUITEMINFO¤   mii;
e4195e ¤   CHAR¤   ¤   ¤   sz[64];
06af5a
15c57b ¤   mii.cbSize = sizeof (MENUITEMINFO);
138af8 ¤   mii.fMask = MIIM_TYPE;
413288 ¤   mii.fType = MFT_STRING;
763921 ¤   if (bAll) {
5ae025 ¤   ¤   LoadString (g_hInst, IDS_COLLAPSEALL, sz, sizeof(sz));
1cfe3f ¤   ¤   mii.dwTypeData = sz;
a72e12 ¤   ¤   mii.cch = lstrlen (sz);
4c8f44 ¤   ¤   SetMenuItemInfo (hMenu, IDM_COLLAPSESEL, FALSE, &mii);
36af23 ¤   ¤   LoadString (g_hInst, IDS_EXPANDALL, sz, sizeof(sz));
1bfe3f ¤   ¤   mii.dwTypeData = sz;
8d2e12 ¤   ¤   mii.cch = lstrlen (sz);
948329 ¤   ¤   SetMenuItemInfo (hMenu, IDM_EXPANDSEL, FALSE, &mii);
109371 ¤   }
16665a ¤   else {
36fbe9 ¤   ¤   LoadString (g_hInst, IDS_COLLAPSESEL, sz, sizeof(sz));
23fe3f ¤   ¤   mii.dwTypeData = sz;
9a2e12 ¤   ¤   mii.cch = lstrlen (sz);
538f44 ¤   ¤   SetMenuItemInfo (hMenu, IDM_COLLAPSESEL, FALSE, &mii);
86b4ef ¤   ¤   LoadString (g_hInst, IDS_EXPANDSEL, sz, sizeof(sz));
55fe3f ¤   ¤   mii.dwTypeData = sz;
3d2e12 ¤   ¤   mii.cch = lstrlen (sz);
078329 ¤   ¤   SetMenuItemInfo (hMenu, IDM_EXPANDSEL, FALSE, &mii);
0b9371 ¤   }
ccefe6 }
21af5a
43d4d4 //¤ ______________________________________________
b2465d //
5861b6 // ·Set the "Set As ..." to "Default" or "Primary"
3daf5a
4cb333 static VOID·
b050fa sSetMenuDefaultOrPrimary (
9aa555 ¤   ¤   HMENU¤  hMenu,·
ff0ffb ¤   ¤   BOOL¤   bDefault)·
aebb36 {
eca700 ¤   MENUITEMINFO¤   mii;
--8610 0009c92e9f8401102e7 Page 4 of PKMenu.c
42195e ¤   CHAR¤   ¤   ¤   sz[64];
f9af5a
6cc57b ¤   mii.cbSize = sizeof (MENUITEMINFO);
728af8 ¤   mii.fMask = MIIM_TYPE;
643288 ¤   mii.fType = MFT_STRING;
940d94 ¤   if (bDefault) {
abba12 ¤   ¤   LoadString (g_hInst, IDS_SETASDEFAULT, sz, sizeof(sz));
d4fe3f ¤   ¤   mii.dwTypeData = sz;
812e12 ¤   ¤   mii.cch = lstrlen (sz);
b206f6 ¤   ¤   SetMenuItemInfo (hMenu, IDM_SETASDEFAULT, FALSE, &mii);
fb9371 ¤   }
b2665a ¤   else {
640d94 ¤   ¤   LoadString (g_hInst, IDS_SETASPRIMARY, sz, sizeof(sz));
61fe3f ¤   ¤   mii.dwTypeData = sz;
c52e12 ¤   ¤   mii.cch = lstrlen (sz);
bb06f6 ¤   ¤   SetMenuItemInfo (hMenu, IDM_SETASDEFAULT, FALSE, &mii);
5a9371 ¤   }
5fefe6 }
12af5a
a9c509 //¤ ____________________________________
fc465d //
8f8ab6 // ·Enable/Disable menu items
69af5a
b1b333 static VOID·
d22d50 sSetItem (
cca555 ¤   ¤   HMENU¤  hMenu,·
016ca9 ¤   ¤   INT¤¤   iId,·
cd2ff9 ¤   ¤   BOOL¤   bEnable)·
debb36 {
3410ca ¤   if (bEnable)
d7d17b ¤   ¤   EnableMenuItem (hMenu, iId, MF_BYCOMMAND|MF_ENABLED);
414264 ¤   else·
2c6b1e ¤   ¤   EnableMenuItem (hMenu, iId, MF_BYCOMMAND|MF_GRAYED);
83efe6 }
11af5a
c99268 //¤ _______________________________________________
49465d //
395a5f // ·Enable/Disable menu items on basis of currently
ff7907 // ·focused key type
76af5a
e6a1ba VOID·
0a916f PKSetMainMenu (PGPKEYSSTRUCT* ppks)·
02bb36 {
fa3e75 ¤   HMENU¤  ¤   ¤   hMP;
2c4da5 ¤   HKEYMAN¤¤   ¤   hKM;
9612e3 ¤   HGROUPMAN¤  ¤   hGM;
06cafa ¤   ULONG¤  ¤   ¤   ulColumns;
bb195e ¤   CHAR¤   ¤   ¤   sz[64];
dcaf5a
96af5a
fe0bb1 ¤   hKM = ppks->hKM;
d0e423 ¤   hGM = ppks->hGM;
8baf5a
a0513a ¤   // "Edit" menu
366fbd ¤   hMP = GetSubMenu (ppks->hMenuKeyMan, MENU_EDIT);
31af5a
6eacde ¤   sSetItem (hMP, IDM_COPYKEY, PGPkmIsActionEnabled (hKM, KM_COPY));
142964 ¤   if (ppks->bGroupsFocused) {
8ae17b ¤   ¤   sSetItem (hMP, IDM_PASTEKEY, PGPgmIsActionEnabled (hGM, GM_PASTE));
ebdcf1 ¤   ¤   sSetItem (hMP, IDM_DELETEKEY, PGPgmIsActionEnabled (hGM, GM_DELETE));
382165 ¤   ¤   sSetMenuAllOrSelected (hMP,·
904e79 ¤   ¤   ¤   ¤   ¤   ¤   ¤   !PGPgmIsActionEnabled (hGM, GM_EXPANDSEL));
629371 ¤   }
a6665a ¤   else {
957d74 ¤   ¤   sSetItem (hMP, IDM_PASTEKEY, PGPkmIsActionEnabled (hKM, KM_PASTE));
6a249a ¤   ¤   sSetItem (hMP, IDM_DELETEKEY, PGPkmIsActionEnabled (hKM, KM_DELETE));
fd2165 ¤   ¤   sSetMenuAllOrSelected (hMP,·
37d05a ¤   ¤   ¤   ¤   ¤   ¤   ¤   !PGPkmIsActionEnabled (hKM, KM_EXPANDSEL));
a49371 ¤   }
b4af5a
5ee1a1 ¤   // "View" menu
9c1538 ¤   hMP = GetSubMenu (ppks->hMenuKeyMan, MENU_VIEW);
--a19a 000d43cea2f401102e7 Page 5 of PKMenu.c
14167b ¤   PGPkmGetSelectedColumns (hKM, &ulColumns);
ffaf5a
d4bd0b ¤   if (ulColumns & KM_VALIDITY)
3c6390 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWVALIDITY, MF_BYCOMMAND|MF_CHECKED);
930e24 ¤   else
7d94c4 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWVALIDITY, MF_BYCOMMAND|MF_UNCHECKED);
e0af5a
55bea1 ¤   if (ulColumns & KM_SIZE)
356bb3 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWSIZE, MF_BYCOMMAND|MF_CHECKED);
080e24 ¤   else
e411d7 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWSIZE, MF_BYCOMMAND|MF_UNCHECKED);
25af5a
053e4f ¤   if (ulColumns & KM_DESCRIPTION)
ad5500 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWDESC, MF_BYCOMMAND|MF_CHECKED);
aa0e24 ¤   else
ead92c ¤   ¤   CheckMenuItem (hMP, IDM_VIEWDESC, MF_BYCOMMAND|MF_UNCHECKED);
b4af5a
1a3827 ¤   if (ulColumns & KM_KEYID)
f9af8e ¤   ¤   CheckMenuItem (hMP, IDM_VIEWKEYID, MF_BYCOMMAND|MF_CHECKED);
8c0e24 ¤   else
a39725 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWKEYID, MF_BYCOMMAND|MF_UNCHECKED);
0baf5a
3627d1 ¤   if (ulColumns & KM_TRUST)
60fe27 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWTRUST, MF_BYCOMMAND|MF_CHECKED);
470e24 ¤   else
97acce ¤   ¤   CheckMenuItem (hMP, IDM_VIEWTRUST, MF_BYCOMMAND|MF_UNCHECKED);
aeaf5a
a3e00a ¤   if (ulColumns & KM_CREATION)
3ec9ee ¤   ¤   CheckMenuItem (hMP, IDM_VIEWCREATION, MF_BYCOMMAND|MF_CHECKED);
900e24 ¤   else
d3f440 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWCREATION, MF_BYCOMMAND|MF_UNCHECKED);
87af5a
f44b14 ¤   if (ulColumns & KM_EXPIRATION)
7620e7 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWEXPIRATION, MF_BYCOMMAND|MF_CHECKED);
8d0e24 ¤   else
b75997 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWEXPIRATION, MF_BYCOMMAND|MF_UNCHECKED);
d6af5a
d95b63 ¤   if (ulColumns & KM_ADK)
f41f9e ¤   ¤   CheckMenuItem (hMP, IDM_VIEWADK, MF_BYCOMMAND|MF_CHECKED);
430e24 ¤   else
fcb73f ¤   ¤   CheckMenuItem (hMP, IDM_VIEWADK, MF_BYCOMMAND|MF_UNCHECKED);
62af5a
540e12 ¤   if (ppks->iToolHeight > 0)·
311fd4 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWTOOLBAR, MF_BYCOMMAND|MF_CHECKED);
e60e24 ¤   else
ce0c29 ¤   ¤   CheckMenuItem (hMP, IDM_VIEWTOOLBAR, MF_BYCOMMAND|MF_UNCHECKED);
91af5a
32af5a
7f575a ¤   // "Keys" menu
a60ed6 ¤   hMP = GetSubMenu (ppks->hMenuKeyMan, MENU_KEYS);
72af5a
de1a3e ¤   sSetItem (hMP, IDM_CERTIFYKEY, PGPkmIsActionEnabled (hKM, KM_CERTIFY));
9723d3 ¤   sSetItem (hMP, IDM_ENABLEKEY, PGPkmIsActionEnabled (hKM, KM_ENABLE));
e7e227 ¤   sSetItem (hMP, IDM_DISABLEKEY, PGPkmIsActionEnabled (hKM, KM_DISABLE));
66a0e4 ¤   sSetItem (hMP, IDM_REVOKEKEY, PGPkmIsActionEnabled (hKM, KM_REVOKE));
7591fa ¤   sSetItem (hMP, IDM_REVERIFY,·
f446e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_REVERIFYSIGS));
0eaf5a
3cb8d5 ¤   if (PGPkmIsActionEnabled (hKM, KM_SETASPRIMARY)) {
6cb3fb ¤   ¤   sSetMenuDefaultOrPrimary (hMP, FALSE);
05b6a0 ¤   ¤   EnableMenuItem (hMP, IDM_SETASDEFAULT, MF_BYCOMMAND|MF_ENABLED);
0e9371 ¤   }
47665a ¤   else {
81c7b9 ¤   ¤   sSetMenuDefaultOrPrimary (hMP, TRUE);
2abd6d ¤   ¤   sSetItem (hMP, IDM_SETASDEFAULT,·
6245c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_SETASDEFAULT));
ba9371 ¤   }
0faf5a
6f41b7 ¤   sSetItem (hMP, IDM_CREATEKEY, (!g_bReadOnly) && g_bKeyGenEnabled);
efaf5a
873d1d ¤   sSetItem (hMP, IDM_SPLITKEY, PGPkmIsActionEnabled (hKM, KM_SPLITKEY));
d4af5a
--9f80 00019ad4f2a401102e7 Page 6 of PKMenu.c
a72b7d ¤   sSetItem (hMP, IDM_IMPORTKEYS, PGPkmIsActionEnabled (hKM, KM_IMPORT));
3b2772 ¤   sSetItem (hMP, IDM_EXPORTKEYS, PGPkmIsActionEnabled (hKM, KM_EXPORT));
08af5a
1cad60 ¤   sSetItem (hMP, IDM_KEYPROPERTIES,·
ec2373 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_PROPERTIES));
86af5a
91f5d3 ¤   // "Add" popup submenu
73c93d ¤   hMP = GetSubMenu (hMP, SUBMENU_ADD);
9c9a51 ¤   sSetItem (hMP, IDM_ADDUSERID, PGPkmIsActionEnabled (hKM, KM_ADDUSERID));
8dd791 ¤   sSetItem (hMP, IDM_ADDPHOTOID, PGPkmIsActionEnabled (hKM, KM_ADDPHOTOID));
c69e1e ¤   sSetItem (hMP, IDM_ADDREVOKER, PGPkmIsActionEnabled (hKM, KM_ADDREVOKER));
50af5a
f36782 ¤   // "Servers" menu
8da7c5 ¤   hMP = GetSubMenu (ppks->hMenuKeyMan, MENU_SERVER);
97af5a
3b7fa8 ¤   DeleteMenu (hMP, SENDTOSERVERPOS, MF_BYPOSITION);
7363c4 ¤   LoadString (g_hInst, IDS_SENDTOSERVERMENU, sz, sizeof(sz));
aaaeb1 ¤   if (PGPkmIsActionEnabled (hKM, KM_SENDTOSERVER)) {
76c613 ¤   ¤   ppks->hMenuKeyserver = sCreateKeyserverMenu ();
84aefe ¤   ¤   InsertMenu (hMP, SENDTOSERVERPOS, MF_BYPOSITION|MF_POPUP|MF_STRING,·
1dd86a ¤   ¤   ¤   (UINT)ppks->hMenuKeyserver, sz);
229371 ¤   }
9da99d ¤   else {¤ ¤
ed1a90 ¤   ¤   InsertMenu (hMP, SENDTOSERVERPOS, MF_BYPOSITION|MF_STRING,·
f3ea39 ¤   ¤   ¤   IDM_SENDTOSERVERPOPUP, sz);
e328f4 ¤   ¤   sSetItem (hMP, IDM_SENDTOSERVERPOPUP, FALSE);
499371 ¤   }
61af5a
7470ba ¤   sSetItem (hMP, IDM_GETFROMSERVER,·
d15f03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_GETFROMSERVER));
1baf5a
84af56 ¤   // "Groups" menu
63b996 ¤   hMP = GetSubMenu (ppks->hMenuKeyMan, MENU_GROUPS);
31af5a
402b56 ¤   if (ppks->bGroupsVisible) {
817784 ¤   ¤   sSetItem (hMP, IDM_GROUPPROPERTIES,·
3d3074 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_PROPERTIES));
169371 ¤   }
1a665a ¤   else {
b0a544 ¤   ¤   sSetItem (hMP, IDM_GROUPPROPERTIES, FALSE);
a69371 ¤   }
7daf5a
74efe6 }
15af5a
69c426 //¤ ______________________________________________________
fe465d //
f85be9 // ·Put up appropriate context menu on basis of key idx
37b87d // ·of currently focused item. ·Called in response to right
f58b56 // ·mouse click.
c0465d //
3d5d68 //¤ hWnd¤   ¤   = handle of parent window
6bd58a //¤ uSelFlags¤  = bits indicate what types of objects are selected
e5ee2d //¤ x, y¤   ¤   = mouse position when right button clicked (screen coords)
9aaf5a
c9a1ba VOID·
ccd6f3 PKContextMenu (
dfcda5 ¤   ¤   PGPKEYSSTRUCT*¤ ppks,
81fd31 ¤   ¤   HWND¤   ¤   ¤   hWnd,·
071895 ¤   ¤   INT¤¤   ¤   ¤   x,·
8e3d93 ¤   ¤   INT¤¤   ¤   ¤   y)·
aebb36 {
645484 ¤   HMENU¤  ¤   ¤   hMC;
9801d7 ¤   HMENU¤  ¤   ¤   hMCS;
6f5917 ¤   HMENU¤  ¤   ¤   hMenuTrackPopup;
924da5 ¤   HKEYMAN¤¤   ¤   hKM;
ba12e3 ¤   HGROUPMAN¤  ¤   hGM;
0f0214 ¤   UINT¤   ¤   ¤   uAddUserIDIndex;
02195e ¤   CHAR¤   ¤   ¤   sz[64];
c1af5a
742964 ¤   if (ppks->bGroupsFocused) {
4355f2 ¤   ¤   hGM = ppks->hGM;
19abb0 ¤   ¤   switch (ppks->uGroupSelectionFlags) {
--374f 0004108be7d401102e7 Page 7 of PKMenu.c
87c18f ¤   ¤   case 0 :
5faade ¤   ¤   ¤   hMC = NULL;
7ccdcb ¤   ¤   ¤   break;
05af5a
2a69a9 ¤   ¤   case PGPGM_GROUPFLAG :
bf86f7 ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUGROUP));
4861fa ¤   ¤   ¤   sSetItem (hMC, IDM_PASTEKEY,·
c17b61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_PASTE));
c7cc1d ¤   ¤   ¤   sSetItem (hMC, IDM_DELETEKEY,·
604f1c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_DELETE));
7ba13c ¤   ¤   ¤   sSetItem (hMC, IDM_GETFROMSERVER,·
306cff ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_GETFROMSERVER));
3a6e24 ¤   ¤   ¤   sSetItem (hMC, IDM_GROUPPROPERTIES,·
cb3074 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_PROPERTIES));
cab86b ··¤ ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
3ccdcb ¤   ¤   ¤   break;
0caf5a
708917 ¤   ¤   case PGPGM_KEYFLAG :
978286 ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUGROUPKEY));
a761fa ¤   ¤   ¤   sSetItem (hMC, IDM_PASTEKEY,·
d47b61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_PASTE));
f5cc1d ¤   ¤   ¤   sSetItem (hMC, IDM_DELETEKEY,·
5a4f1c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_DELETE));
ebdb1f ¤   ¤   ¤   sSetItem (hMC, IDM_FINDKEY,·
eb7581 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_LOCATEKEYS));
d0a13c ¤   ¤   ¤   sSetItem (hMC, IDM_GETFROMSERVER,·
236cff ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_GETFROMSERVER));
097ce6 ¤   ¤   ¤   sSetItem (hMC, IDM_KEYPROPERTIES,·
8e7581 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_LOCATEKEYS));
8b37b8 ¤   ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
85cdcb ¤   ¤   ¤   break;
f5af5a
cf3a18 ¤   ¤   default :
6386f7 ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUGROUP));
916863 ¤   ¤   ¤   sSetItem (hMC, IDM_PASTEKEY, FALSE);
adcc1d ¤   ¤   ¤   sSetItem (hMC, IDM_DELETEKEY,·
a54f1c ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_DELETE));
12a13c ¤   ¤   ¤   sSetItem (hMC, IDM_GETFROMSERVER,·
ed6cff ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmIsActionEnabled (hGM, GM_GETFROMSERVER));
122719 ¤   ¤   ¤   sSetItem (hMC, IDM_GROUPPROPERTIES, FALSE);
c3b86b ··¤ ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
0ccdcb ¤   ¤   ¤   break;
aa0fe4 ¤   ¤   }
aa9371 ¤   }
9e665a ¤   else {
1cba60 ¤   ¤   hKM = ppks->hKM;
8caf5a
730fb9 ¤   ¤   switch (ppks->uKeySelectionFlags) {
7bc18f ¤   ¤   case 0 :
114d4b ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUNONE));
9361fa ¤   ¤   ¤   sSetItem (hMC, IDM_PASTEKEY,·
1ae76e ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_PASTE));
dcb86b ··¤ ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
bfcdcb ¤   ¤   ¤   break;
c6af5a
ddb2cb ¤   ¤   case PGPKM_KEYFLAG :
ccbba6 ¤   ¤   ¤   if (ppks->bMainWindow) {
abe509 ¤   ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUKEY));
8bdc38 ¤   ¤   ¤   ¤   uAddUserIDIndex = 6;
9ba3a6 ¤   ¤   ¤   }
28e543 ¤   ¤   ¤   else {
aea70e ¤   ¤   ¤   ¤   if (ppks->bLocalKeySet) {
9c78df ¤   ¤   ¤   ¤   ¤   hMC = LoadMenu (g_hInst,·
c2b4f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDR_MENUKEYSEARCHLOCAL));
93d9d5 ¤   ¤   ¤   ¤   ¤   uAddUserIDIndex = 6;
eb2613 ¤   ¤   ¤   ¤   }
21deaa ¤   ¤   ¤   ¤   else {
5178df ¤   ¤   ¤   ¤   ¤   hMC = LoadMenu (g_hInst,·
1ce6c4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE (IDR_MENUKEYSEARCHSERVER));
308309 ¤   ¤   ¤   ¤   ¤   uAddUserIDIndex = 7;
b12613 ¤   ¤   ¤   ¤   }
41bb31 ¤   ¤   ¤   ¤   sSetItem (hMC, IDM_ADDTOMAIN,·
--cbe2 000ef556255401102e7 Page 8 of PKMenu.c
21d259 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_ADDTOMAIN));
44a3a6 ¤   ¤   ¤   }
1bb86b ··¤ ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
d4af5a
df1348 ¤   ¤   ¤   sSetItem (hMC, IDM_COPYKEY,·
a3cf91 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_COPY));
8961fa ¤   ¤   ¤   sSetItem (hMC, IDM_PASTEKEY,·
d3e76e ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_PASTE));
89cc1d ¤   ¤   ¤   sSetItem (hMC, IDM_DELETEKEY,·
12b777 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_DELETE));
eac477 ¤   ¤   ¤   sSetItem (hMC, IDM_DELETESERVER,·
3804c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_DELETEFROMSERVER));
fca4b1 ¤   ¤   ¤   sSetItem (hMC, IDM_CERTIFYKEY,·
97ebea ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_CERTIFY));
0f61e5 ¤   ¤   ¤   sSetItem (hMC, IDM_ENABLEKEY,·
b32cb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_ENABLE));
9d6222 ¤   ¤   ¤   if (ppks->bLocalKeySet)
8d3b0d ¤   ¤   ¤   ¤   sSetItem (hMC, IDM_DISABLEKEY,·
568fa1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_DISABLE));
bfbb8c ¤   ¤   ¤   else
5b3b0d ¤   ¤   ¤   ¤   sSetItem (hMC, IDM_DISABLEKEY,·
890d81 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_DISABLEONSERVER));
00af5a
a8c339 ¤   ¤   ¤   sSetItem (hMC, IDM_SPLITKEY,·
611f59 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_SPLITKEY));
1daf5a
0d33c7 ¤   ¤   ¤   sSetItem (hMC, IDM_REVOKEKEY,·
6f6632 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_REVOKE));
4fb5d0 ¤   ¤   ¤   sSetItem (hMC, IDM_REVERIFY,·
5d46e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_REVERIFYSIGS));
c1b224 ¤   ¤   ¤   sSetItem (hMC, IDM_SETASDEFAULT,·
0e45c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_SETASDEFAULT));
fbe038 ¤   ¤   ¤   sSetItem (hMC, IDM_EXPORTKEYS,·
1e47a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_EXPORT));
86af5a
c810dd ¤   ¤   ¤   LoadString (g_hInst, IDS_SENDTOSERVERMENU, sz, sizeof(sz));
caa968 ¤   ¤   ¤   if (PGPkmIsActionEnabled (hKM, KM_SENDTOSERVER)) {
4e8d58 ¤   ¤   ¤   ¤   ppks->hMenuKeyserver = sCreateKeyserverMenu ();
ab46ff ¤   ¤   ¤   ¤   InsertMenu (hMenuTrackPopup, 13,·
2a4627 ¤   ¤   ¤   ¤   ¤   MF_BYPOSITION|MF_POPUP|MF_STRING,·
65d9ec ¤   ¤   ¤   ¤   ¤   (UINT)ppks->hMenuKeyserver, sz);
fca3a6 ¤   ¤   ¤   }
9f16b2 ¤   ¤   ¤   else {¤ ¤
8426c3 ¤   ¤   ¤   ¤   InsertMenu (hMC, 13, MF_BYPOSITION|MF_STRING,·
787a0f ¤   ¤   ¤   ¤   ¤   IDM_SENDTOSERVERPOPUP, sz);
747acc ¤   ¤   ¤   ¤   sSetItem (hMenuTrackPopup, IDM_SENDTOSERVERPOPUP, FALSE);
02a3a6 ¤   ¤   ¤   }
c9af5a
5da13c ¤   ¤   ¤   sSetItem (hMC, IDM_GETFROMSERVER,·
485f03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_GETFROMSERVER));
cf7ce6 ¤   ¤   ¤   sSetItem (hMC, IDM_KEYPROPERTIES,·
3d2373 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_PROPERTIES));
5faf5a
f1bff9 ¤   ¤   ¤   // take care of "Add" popup submenu
e96580 ¤   ¤   ¤   hMCS = GetSubMenu (hMenuTrackPopup, uAddUserIDIndex);
71fd55 ¤   ¤   ¤   sSetItem (hMCS, IDM_ADDUSERID,·
733d76 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_ADDUSERID));
f32c08 ¤   ¤   ¤   sSetItem (hMCS, IDM_ADDPHOTOID,·
88ab03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_ADDPHOTOID));
6ea203 ¤   ¤   ¤   sSetItem (hMCS, IDM_ADDREVOKER,·
10155e ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_ADDREVOKER));
b9cdcb ¤   ¤   ¤   break;
51af5a
3440e8 ¤   ¤   case PGPKM_UIDFLAG :
892857 ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUUID));
eacc1d ¤   ¤   ¤   sSetItem (hMC, IDM_DELETEKEY,·
55b777 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_DELETE));
32a4b1 ¤   ¤   ¤   sSetItem (hMC, IDM_CERTIFYKEY,·
3eebea ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_CERTIFY));
0bb224 ¤   ¤   ¤   sSetItem (hMC, IDM_SETASDEFAULT,·
f10ce4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_SETASPRIMARY));
ef7ce6 ¤   ¤   ¤   sSetItem (hMC, IDM_KEYPROPERTIES,·
--1884 001c054abea401102e7 Page 9 of PKMenu.c
172373 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_PROPERTIES));
b6d6b2 ¤   ··¤ ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
72cdcb ¤   ¤   ¤   break;
99af5a
81fbdf ¤   ¤   case PGPKM_CERTFLAG :
29d281 ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUCERT));
65cc1d ¤   ¤   ¤   sSetItem (hMC, IDM_DELETEKEY,·
e1b777 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_DELETE));
db33c7 ¤   ¤   ¤   sSetItem (hMC, IDM_REVOKEKEY,·
776632 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_REVOKE));
36a13c ¤   ¤   ¤   sSetItem (hMC, IDM_GETFROMSERVER,·
435f03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_GETFROMSERVER));
957ce6 ¤   ¤   ¤   sSetItem (hMC, IDM_KEYPROPERTIES,·
fb2373 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_PROPERTIES));
b1b86b ··¤ ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
fecdcb ¤   ¤   ¤   break;
97af5a
1b3a18 ¤   ¤   default :
83afe3 ¤   ¤   ¤   hMC = LoadMenu (g_hInst, MAKEINTRESOURCE (IDR_MENUPROMISCUOUS));
aacc1d ¤   ¤   ¤   sSetItem (hMC, IDM_DELETEKEY,·
54b777 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_DELETE));
3da4b1 ¤   ¤   ¤   sSetItem (hMC, IDM_CERTIFYKEY,·
35ebea ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_CERTIFY));
227ce6 ¤   ¤   ¤   sSetItem (hMC, IDM_KEYPROPERTIES,·
bc2373 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmIsActionEnabled (hKM, KM_PROPERTIES));
95b86b ··¤ ¤   ¤   hMenuTrackPopup = GetSubMenu (hMC, 0);
91cdcb ¤   ¤   ¤   break;
a80fe4 ¤   ¤   }
839371 ¤   }
28af5a
4b75a4 ¤   if (!hMC) return;
56af5a
a5966f ¤   TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
388dd9 ¤   ¤   ¤   ¤   ¤   x, y, 0, hWnd, NULL);
39af5a
7a85ee ¤   DestroyMenu (hMC);
e2af5a
2cefe6 }
11af5a
5daf5a
5bc426 //¤ ______________________________________________________
eb465d //
feda34 // ·Put up keyserver menu for send to server button in toolbar
bf465d //
c15d68 //¤ hWnd¤   ¤   = handle of parent window
b1af5a
7da1ba VOID·
535eb1 PKToolbarKeyserverMenu (
a9803e ¤   ¤   HWND¤   ¤   ¤   hWnd,
082f36 ¤   ¤   LPRECT¤ ¤   ¤   lprect)·
b7bb36 {
b2f60b ¤   HMENU¤  ¤   hMenuKeyserver;
8f805b ¤   POINT¤  ¤   pt;
0caf5a
35c429 ¤   hMenuKeyserver = sCreateKeyserverMenu ();
dcffbc ¤   GetCursorPos (&pt);
216ff9 ¤   TrackPopupMenu (hMenuKeyserver,·
6c60a1 ¤   ¤   ¤   ¤   ¤   TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON,
8ec4a8 ¤   ¤   ¤   ¤   ¤   lprect->left +2, lprect->bottom +4, 0, hWnd, NULL);
7baf5a
2ac2e7 ¤   DestroyMenu (hMenuKeyserver);
c0be43 }¶
--3e71 000c22a182e401102e8 Page 1 of PKMisc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
1806ad ¤   PKMisc.c - miscellaneous routines
8167c5 ¤
a7af5a
2249ce ¤   $Id: PKMisc.c,v 1.35.2.1 1998/10/08 15:35:09 pbj Exp $
9df7f7 ____________________________________________________________________________*/
912194 #include "pgpPFLConfig.h"¤  /* or pgpConfig.h in the CDK */
75af5a
f6c917 // project header files
03c55a #include "pgpkeysx.h"
4eaf5a
7c5bee // typedefs
99f0f7 typedef struct {
822178 ¤   PGPUInt32¤  uWindowShow;
4308bb ¤   PGPInt32¤   iWindowPosX;
1b5267 ¤   PGPInt32¤   iWindowPosY;
f024ee ¤   PGPInt32¤   iWindowWidth;
ae85c6 ¤   PGPInt32¤   iWindowHeight;
b8d3d8 ¤   PGPBoolean¤ bGroupShow;
f5e06a ¤   PGPInt32¤   iGroupPercent;
269cec ¤   PGPInt32¤   iToolHeight;
81af5a
dda352 } KEYSWINDOWSTRUCT, *PKEYSWINDOWSTRUCT;
e5af5a
5aaf5a
793fb5 // external global variables
f6eec0 extern HINSTANCE¤   ¤   g_hInst;
442dd4 extern HWND¤¤   ¤   ¤   g_hWndMain;
817d05 extern UINT¤¤   ¤   ¤   g_uReloadKeyringMessage;
fdcf38 extern PGPContextRef¤   g_Context;
0502e7 extern PGPtlsContextRef¤g_TLSContext;
81aacd extern PGPBoolean¤  ¤   g_bExpertMode;
d4dbc0 extern PGPBoolean¤  ¤   g_bMarginalAsInvalid;
e2af5a
33c509 //¤ ____________________________________
e4465d //
b7fe84 //¤ Private memory allocation routine
32af5a
5b493a VOID*·
855263 pkAlloc (LONG size)·
d7bb36 {
c18418 ¤   void* p;
66c01a ¤   p = malloc (size);
38f191 ¤   if (p) {
3b2a2d ¤   ¤   memset (p, 0, size);
569371 ¤   }
f8381d ¤   return p;
0eefe6 }
a8af5a
d2c509 //¤ ____________________________________
49465d //
5c9e8c //¤ Private memory deallocation routine
2eaf5a
f2a1ba VOID·
736d40 pkFree (VOID* p)·
6bbb36 {
eef191 ¤   if (p) {
a5de78 ¤   ¤   free (p);
409371 ¤   }
25efe6 }
89af5a
a9c509 //¤ ____________________________________
44465d //
4525b9 //¤ Get PGPkeys private info from prefs file
f8af5a
d07efe BOOL·
697fde PKGetPrivatePrefData (
6c5a61 ¤   ¤   ¤   DWORD*¤ dwShow,·
c2c97c ¤   ¤   ¤   INT*¤   iX,·
--2d65 00049264eba401102e8 Page 2 of PKMisc.c
52d5c7 ¤   ¤   ¤   INT*¤   iY,·
84e28f ¤   ¤   ¤   INT*¤   iWidth,·
509d58 ¤   ¤   ¤   INT*¤   iHeight,
0e6a42 ¤   ¤   ¤   BOOL*¤  bGroupShow,
9eab8d ¤   ¤   ¤   INT*¤   iGroupPercent,
a9f778 ¤   ¤   ¤   INT*¤   iToolHeight)·
58bb36 {
83b04f ¤   PKEYSWINDOWSTRUCT¤  ¤   pkws;
db9526 ¤   PGPPrefRef¤ ¤   ¤   ¤   prefref;
30ba49 ¤   PGPError¤   ¤   ¤   ¤   err;
2c4e1c ¤   PGPSize¤¤   ¤   ¤   ¤   size;
b8af5a
cb45e7 ¤   *dwShow¤¤   ¤   = SW_SHOWNORMAL;
b0ddab ¤   *iX¤¤   ¤   ¤   = DEFAULTWINDOWX;
53f015 ¤   *iY¤¤   ¤   ¤   = DEFAULTWINDOWY;
1384e9 ¤   *iWidth¤¤   ¤   = DEFAULTWINDOWWIDTH;·
8b253c ¤   *iHeight¤   ¤   = DEFAULTWINDOWHEIGHT;·
97725e ¤   *bGroupShow¤¤   = DEFAULTGROUPSHOW;
067f1c ¤   *iGroupPercent¤ = DEFAULTGROUPPERCENT;
3c5e85 ¤   *iToolHeight¤   = DEFAULTTOOLHEIGHT;
93af5a
6894fa ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (g_Context),·
6113a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
6eb23e ¤   if (IsntPGPError (err)) {
32728b ¤   ¤   size = 0;
420fba ¤   ¤   err = PGPGetPrefData (prefref, kPGPPrefPGPkeysWinMainWinPos,
cdb550 ¤   ¤   ¤   ¤   ¤   ¤   &size, &pkws);
74b30d ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
b0af5a
1e8536 ¤   ¤   if (IsntPGPError (err)) {
020ad9 ¤   ¤   ¤   if (size == sizeof(KEYSWINDOWSTRUCT)) {
cd1705 ¤   ¤   ¤   ¤   *dwShow¤¤   ¤   = pkws->uWindowShow;
e0cf92 ¤   ¤   ¤   ¤   *iX¤¤   ¤   ¤   = pkws->iWindowPosX;
ac9877 ¤   ¤   ¤   ¤   *iY¤¤   ¤   ¤   = pkws->iWindowPosY;
cdeb71 ¤   ¤   ¤   ¤   *iWidth¤¤   ¤   = pkws->iWindowWidth;
61b07b ¤   ¤   ¤   ¤   *iHeight¤   ¤   = pkws->iWindowHeight;
1875d2 ¤   ¤   ¤   ¤   *bGroupShow¤¤   = pkws->bGroupShow;
7afeae ¤   ¤   ¤   ¤   *iGroupPercent¤ = pkws->iGroupPercent;
8ee531 ¤   ¤   ¤   ¤   *iToolHeight¤   = pkws->iToolHeight;
87a3a6 ¤   ¤   ¤   }
b49077 ¤   ¤   ¤   PGPDisposePrefData (prefref, pkws);
330fe4 ¤   ¤   }
399371 ¤   }
03af5a
a4a230 ¤   return FALSE;
84efe6 }
34af5a
34c509 //¤ ____________________________________
50465d //
3c3e09 //¤ ·Put window position information in registry
4eaf5a
20a1ba VOID·
04cc9d PKSetPrivatePrefData (
4a47b2 ¤   ¤   HWND¤   hWnd,·
4d9852 ¤   ¤   BOOL¤   bGroupShow,
daf35e ¤   ¤   INT¤¤   iGroupPercent,
0cf182 ¤   ¤   INT¤¤   iToolHeight)·
a8bb36 {
35c92e ¤   WINDOWPLACEMENT¤¤   wp;
5c1dee ¤   KEYSWINDOWSTRUCT¤   kws;
54697c ¤   PGPPrefRef¤ ¤   ¤   prefref;
7a8f52 ¤   PGPError¤   ¤   ¤   err;
ccaf5a
52a530 ¤   wp.length = sizeof(WINDOWPLACEMENT);
b824d9 ¤   GetWindowPlacement (hWnd, &wp);
55af5a
7b94fa ¤   err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (g_Context),·
8b13a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
deb23e ¤   if (IsntPGPError (err)) {
d71965 ¤   ¤   kws.uWindowShow = wp.showCmd;
1d99cf ¤   ¤   kws.iWindowPosX = wp.rcNormalPosition.left;
495350 ¤   ¤   kws.iWindowPosY = wp.rcNormalPosition.top;
--1c6b 000b47aef6e401102e8 Page 3 of PKMisc.c
4e79dc ¤   ¤   kws.iWindowWidth =·
25b081 ¤   ¤   ¤   wp.rcNormalPosition.right - wp.rcNormalPosition.left;
c1cec5 ¤   ¤   kws.iWindowHeight =·
ae06e8 ¤   ¤   ¤   wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
f5c410 ¤   ¤   kws.bGroupShow = bGroupShow;
8321b7 ¤   ¤   kws.iGroupPercent = iGroupPercent;
3275fb ¤   ¤   kws.iToolHeight = iToolHeight;
b72631 ¤   ¤   PGPSetPrefData (prefref, kPGPPrefPGPkeysWinMainWinPos,·
9d3eef ¤   ¤   ¤   ¤   ¤   ¤   sizeof(kws), &kws);
f6af5a
cd31b9 ¤   ¤   PGPclCloseClientPrefs (prefref, TRUE);
bf9371 ¤   }
cfefe6 }
bfaf5a
ccc509 //¤ ____________________________________
b1465d //
39a469 //¤ Put PGPkeys application path into registry
e2af5a
89a1ba VOID·
af71e2 PKSetPathRegistryData (void)·
e9bb36 {
c941d8 ¤   HKEY¤   hKey;
f54d65 ¤   LONG¤   lResult;
872e3b ¤   CHAR¤   szPath[MAX_PATH];
dd2c19 ¤   DWORD¤  dw;
39069c ¤   CHAR¤   sz[256];
c8af5a
3fae3a ¤   LoadString (g_hInst, IDS_REGISTRYKEY, sz, sizeof(sz));
830ae8 ¤   lResult = RegCreateKeyEx (HKEY_CURRENT_USER, sz, 0, NULL,
379606 ¤   ¤   ¤   ¤   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw);
ccaf5a
ebaebc ¤   if (lResult == ERROR_SUCCESS) {
25b8d5 ¤   ¤   GetModuleFileName (NULL, szPath, sizeof(szPath));
e6eb53 ¤   ¤   RegSetValueEx (hKey, "ExePath", 0, REG_SZ, (LPBYTE)szPath,·
118f4f ¤   ¤   ¤   lstrlen(szPath)+1);
7a8e60 ¤   ¤   RegCloseKey (hKey);
a99371 ¤   }
8aefe6 }
cdaf5a
d8c509 //¤ ____________________________________
08465d //
c6a2c1 // ·Put up preferences property sheet
e2af5a
baa1ba VOID·
a978c3 PKReloadPGPPreferences (PGPKEYSSTRUCT* ppks)·
dbbb36 {
bc0f24 ¤   PGPPrefRef¤ prefs;
3167f7 ¤   PGPBoolean¤ b, bUpdate;
46af5a
993afd ¤   bUpdate = FALSE;
fe2919 ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (g_Context), &prefs);
bcaf5a
a85e2e ¤   // has the validity dot vs. bar pref changed?
1b1c8d ¤   PGPGetPrefBoolean (prefs, kPGPPrefDisplayMarginalValidity, &b);
97ccd1 ¤   if (b != g_bExpertMode) {
6dccfc ¤   ¤   g_bExpertMode = b;
c79c4f ¤   ¤   bUpdate = TRUE;
e052fd ¤   ¤   if (!g_bExpertMode) {
90dd71 ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_NOVICEMODE;
530270 ¤   ¤   ¤   ppks->gmConfig.ulOptionFlags |= GMF_NOVICEMODE;
7f0fe4 ¤   ¤   }
bd07e0 ¤   ¤   else {
a88795 ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags &= ~KMF_NOVICEMODE;
612e21 ¤   ¤   ¤   ppks->gmConfig.ulOptionFlags &= ~GMF_NOVICEMODE;
1d0fe4 ¤   ¤   }
259371 ¤   }
06af5a
c6cd21 ¤   // has the display marginal validity as invalid pref changed?
a88cac ¤   PGPGetPrefBoolean (prefs, kPGPPrefMarginalIsInvalid, &b);
4b9c16 ¤   if (b != g_bMarginalAsInvalid) {
ce1600 ¤   ¤   g_bMarginalAsInvalid = b;
b49c4f ¤   ¤   bUpdate = TRUE;
--adbd 0002e497cfd401102e8 Page 4 of PKMisc.c
3861f3 ¤   ¤   if (g_bMarginalAsInvalid) {
9f2496 ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_MARGASINVALID;
eca2b9 ¤   ¤   ¤   ppks->gmConfig.ulOptionFlags |= GMF_MARGASINVALID;
260fe4 ¤   ¤   }
b507e0 ¤   ¤   else {
e160d1 ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags &= ~KMF_MARGASINVALID;
65f115 ¤   ¤   ¤   ppks->gmConfig.ulOptionFlags &= ~GMF_MARGASINVALID;
7e0fe4 ¤   ¤   }
479371 ¤   }
a6af5a
0c432d ¤   PGPclCloseClientPrefs (prefs, FALSE);
d3af5a
a8f92b ¤   // if prefs have changed => redraw the windows
1846d8 ¤   if (bUpdate) {
e5c090 ¤   ¤   ppks->kmConfig.ulMask = PGPKM_OPTIONS;
6383dd ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
028e68 ¤   ¤   PGPkmLoadKeySet (ppks->hKM, ppks->KeySetMain, ppks->KeySetMain);
441006 ¤   ¤   PGPgmConfigure (ppks->hGM, &(ppks->gmConfig));
023d4e ¤   ¤   PGPgmLoadGroups (ppks->hGM);
9e9371 ¤   }
e2efe6 }
cfaf5a
dbc509 //¤ ____________________________________
37465d //
caa2c1 // ·Put up preferences property sheet
26af5a
b27efe BOOL·
5ffa4a PKPGPPreferences (
0fd726 ¤   ¤   PGPKEYSSTRUCT*¤ ppks,·
01fd31 ¤   ¤   HWND¤   ¤   ¤   hWnd,·
8d898a ¤   ¤   INT¤¤   ¤   ¤   iPage)·
b9bb36 {
f161e0 ¤   PGPError¤   err;
8daf5a
b4fa76 ¤   EnableWindow (hWnd, FALSE);
df48f8 ¤   err = PGPclPreferences (g_Context, hWnd, iPage, ppks->KeySetMain);
cd80cb ¤   if (err != kPGPError_Win32_AlreadyOpen) SetForegroundWindow (hWnd);
19af5a
581642 ¤   EnableWindow (hWnd, TRUE);
22d7a3 ¤   SetFocus (ppks->hWndTreeList);
49af5a
71d0fe ¤   PKReloadPGPPreferences (ppks);
48af5a
e9199f ¤   if (err == kPGPError_NoErr) return TRUE;
18cdfa ¤   else return FALSE;
cdefe6 }
3faf5a
ecaf5a
cf4265 //¤ ___________________________________________________
73465d //
340121 // ·commit keyring changes and broadcast reload message
04af5a
33100d INT·
789f90 PKCommitKeyRingChanges (PGPKeySetRef KeySet, BOOL bBroadcast)·
d9bb36 {
8561e0 ¤   PGPError¤   err;
5d1dd6 ¤   HCURSOR¤¤   hcursorOld;
c5af5a
8859c4 ¤   hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
0ee952 ¤   err = PGPCommitKeyRingChanges (KeySet);
08eee5 ¤   if (IsntPGPError (PGPclErrorBox (NULL, err)) && bBroadcast) {
c1c55f ¤   ¤   PostMessage (HWND_BROADCAST, g_uReloadKeyringMessage,
fbd8e0 ¤   ¤   ¤   MAKEWPARAM (LOWORD (g_hWndMain), FALSE),
096333 ¤   ¤   ¤   (LPARAM)GetCurrentProcessId ());
d19371 ¤   }
82f7d7 ¤   SetCursor (hcursorOld);
5f5ea8 ¤   return err;
07efe6 }
caaf5a
14af5a
e9c509 //¤ ____________________________________
2e465d //
--cec2 000899513bd401102e8 Page 5 of PKMisc.c
50e9c3 //¤ Auto update all keys in keyring
90af5a
367efe BOOL·
418569 PKAutoUpdateAllKeys (
2b7851 ¤   ¤   HWND¤   ¤   ¤   hwnd,·
2655dd ¤   ¤   PGPKeySetRef¤   keysetMain,
6bb086 ¤   ¤   BOOL¤   ¤   ¤   bForce)·
d1bb36 {
a67f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
c07cb4 ¤   PGPKeySetRef¤   keysetUpdated¤  ¤   = kInvalidPGPKeySetRef;
e705c1 ¤   BOOL¤   ¤   ¤   bImported¤  ¤   ¤   = FALSE;
abaf5a
01a110 ¤   INT¤¤   ¤   ¤   iNumKeys;
7818da ¤   HCURSOR¤¤   ¤   hcursorOld;
92af5a
b41fca ¤   // update entire keyset from key-based server
0a05a8 ¤   err = PGPclUpdateKeySetFromServer (g_Context, g_TLSContext, hwnd,·
3ac30d ¤   ¤   ¤   ¤   ¤   keysetMain, PGPCL_USERIDBASEDSERVER, keysetMain,·
3c0012 ¤   ¤   ¤   ¤   ¤   &keysetUpdated); CKERR;
81af5a
3c197f ¤   // if we got updated keys, query user and commit the changes
d8eb38 ¤   if (PGPKeySetRefIsValid (keysetUpdated))·
ddc7a1 ¤   {
c1d836 ¤   ¤   if (bForce)·
fd5b34 ¤   ¤   {
af07dd ¤   ¤   ¤   hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
e2e787 ¤   ¤   ¤   err = PGPAddKeys (keysetUpdated, keysetMain);
3a6a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
73035f ¤   ¤   ¤   ¤   bImported = TRUE;
b49323 ¤   ¤   ¤   ¤   err = PKCommitKeyRingChanges (keysetMain, TRUE);
c5a3a6 ¤   ¤   ¤   }
e4d175 ¤   ¤   ¤   SetCursor (hcursorOld);
8e0fe4 ¤   ¤   }
f5ee26 ¤   ¤   else·
505b34 ¤   ¤   {
8db250 ¤   ¤   ¤   PGPCountKeys (keysetUpdated, &iNumKeys);
0dd4fd ¤   ¤   ¤   if (iNumKeys > 0)
dff776 ¤   ¤   ¤   {
017511 ¤   ¤   ¤   ¤   err = PGPclQueryAddKeys (g_Context,·
dfca9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·g_TLSContext,
f4bf13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hwnd,
1cb7c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·keysetUpdated,·
299f3b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·keysetMain);
b656ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
daec2c ¤   ¤   ¤   ¤   ¤   bImported = TRUE;
ab1966 ¤   ¤   ¤   ¤   ¤   err = PKCommitKeyRingChanges (keysetMain, TRUE);
072613 ¤   ¤   ¤   ¤   }
fba3a6 ¤   ¤   ¤   }
06bb8c ¤   ¤   ¤   else
bb6b6e ¤   ¤   ¤   ¤   PKMessageBox (hwnd, IDS_AUTOUPDATECAPTION,·
63988e ¤   ¤   ¤   ¤   ¤   ¤   IDS_NOUPDATEDKEYS, MB_OK|MB_ICONEXCLAMATION);
eb0fe4 ¤   ¤   }
9a9371 ¤   }
dbaf5a
a9a1c0 done :
8d3848 ¤   if (PGPKeySetRefIsValid (keysetUpdated))
752cf8 ¤   ¤   PGPFreeKeySet (keysetUpdated);
c5af5a
d2016f ¤   PGPclErrorBox (hwnd, err);
d7af5a
f7107d ¤   return bImported;
23efe6 }
b8af5a
10af5a
c5c509 //¤ ____________________________________
d1465d //
7edb2e //¤ derive meta introducers from keyset
1daf5a
6969c9 static PGPError·
8ab818 sGetMetaIntroducers (
1d55dd ¤   ¤   PGPKeySetRef¤   keysetMain,
89e537 ¤   ¤   PGPKeySetRef*¤  pkeysetMeta)
--6241 000940c2e23401102e8 Page 6 of PKMisc.c
2cbb36 {
a37f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
9c3ca3 ¤   PGPKeyListRef¤  keylist¤¤   ¤   ¤   = kInvalidPGPKeyListRef;
d06293 ¤   PGPKeyIterRef¤  keyiter¤¤   ¤   ¤   = kInvalidPGPKeyIterRef;
49bec4 ¤   PGPKeyRef¤  ¤   key¤¤   ¤   ¤   ¤   = kInvalidPGPKeyRef;
ad8858 ¤   PGPKeySetRef¤   keysetMeta¤ ¤   ¤   = kInvalidPGPKeySetRef;
e073b0 ¤   PGPKeySetRef¤   keysetSingle¤   ¤   = kInvalidPGPKeySetRef;
5ae14c ¤   PGPBoolean¤ ¤   bMargIsInvalid;
5aeb1b ¤   PGPValidity¤¤   validityThreshold;
0af43b ¤   PGPPrefRef¤ ¤   prefs;
64af5a
fa64a3 ¤   // use prefs to determine validity threshold
8e2919 ¤   PGPclOpenClientPrefs (PGPGetContextMemoryMgr (g_Context), &prefs);
ce326e ¤   PGPGetPrefBoolean (prefs, kPGPPrefMarginalIsInvalid, &bMargIsInvalid);
34432d ¤   PGPclCloseClientPrefs (prefs, FALSE);
26af5a
8d3243 ¤   if (bMargIsInvalid)·
ae6b91 ¤   ¤   validityThreshold = kPGPValidity_Complete;
590e24 ¤   else
65cb27 ¤   ¤   validityThreshold = kPGPValidity_Marginal;
edaf5a
0fe865 ¤   // create the new keyset to collect the meta-introducer keys
2053e3 ¤   err = PGPNewKeySet (g_Context, &keysetMeta); CKERR;
3faf5a
93a54a ¤   // now we'll iterate the entire keyset
d2d3d4 ¤   err = PGPOrderKeySet (keysetMain, kPGPAnyOrdering, &keylist); CKERR;
d3cece ¤   err = PGPNewKeyIter (keylist, &keyiter); CKERR;
eeaf5a
be3600 ¤   while (IsntPGPError (PGPKeyIterNext (keyiter, &key)) &&·
72aa6e ¤   ¤   ¤   PGPKeyRefIsValid (key))·
70c7a1 ¤   {
82fdcb ¤   ¤   PGPBoolean¤ ¤   bDisabled;
a16d96 ¤   ¤   PGPBoolean¤ ¤   bExpired;
ef3f56 ¤   ¤   PGPBoolean¤ ¤   bRevoked;
77eefb ¤   ¤   PGPBoolean¤ ¤   bMetaIntroducer;
c5aee2 ¤   ¤   PGPValidity¤¤   validity;
f72246 ¤   ¤   PGPUserIDRef¤   userid;
c5c91e ¤   ¤   PGPSigRef¤  ¤   sig;
7faf5a
286fa2 ¤   ¤   bMetaIntroducer = FALSE;
39af5a
5e76ef ¤   ¤   // we'll exclude expired, revoked, disabled and invalid keys
6970d8 ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropIsExpired, &bExpired);
965844 ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropIsRevoked, &bRevoked);
fb9821 ¤   ¤   PGPGetKeyBoolean (key, kPGPKeyPropIsDisabled, &bDisabled);
07b5fd ¤   ¤   PGPGetPrimaryUserIDValidity (key, &validity);
caaf5a
ab805d ¤   ¤   if (!bDisabled && !bExpired && !bRevoked &&
a34055 ¤   ¤   ¤   (validity >= validityThreshold))·
db5b34 ¤   ¤   {
700dde ¤   ¤   ¤   while (IsntPGPError (PGPKeyIterNextUserID (keyiter, &userid)) &&·
144053 ¤   ¤   ¤   ¤   ¤   PGPUserIDRefIsValid (userid) &&
1a3ff1 ¤   ¤   ¤   ¤   ¤   !bMetaIntroducer)·
0ef776 ¤   ¤   ¤   {
bdbc8a ¤   ¤   ¤   ¤   while (IsntPGPError (PGPKeyIterNextUIDSig (keyiter, &sig)) &&·
ba7891 ¤   ¤   ¤   ¤   ¤   ¤   PGPSigRefIsValid (sig) &&
1331bd ¤   ¤   ¤   ¤   ¤   ¤   !bMetaIntroducer)·
e972c3 ¤   ¤   ¤   ¤   {
157619 ¤   ¤   ¤   ¤   ¤   PGPBoolean¤ ¤   bExportable;
4e00c7 ¤   ¤   ¤   ¤   ¤   PGPUInt32¤  ¤   uTrustLevel;
3caf5a
b53aab ¤   ¤   ¤   ¤   ¤   PGPGetSigBoolean (sig,·
9605b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPSigPropIsRevoked, &bRevoked);
093aab ¤   ¤   ¤   ¤   ¤   PGPGetSigBoolean (sig,·
a89e74 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPSigPropIsExportable, &bExportable);
011662 ¤   ¤   ¤   ¤   ¤   PGPGetSigNumber ·(sig,·
9d3645 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPSigPropTrustLevel, &uTrustLevel);
d6af5a
8e97b9 ¤   ¤   ¤   ¤   ¤   if (!bRevoked && !bExportable && (uTrustLevel == 2))
74441f ¤   ¤   ¤   ¤   ¤   ¤   ·bMetaIntroducer = TRUE;
e6af5a
942613 ¤   ¤   ¤   ¤   }
--0b7e 000240a3d18401102e8 Page 7 of PKMisc.c
cfa3a6 ¤   ¤   ¤   }
7987c7 ¤   ¤   ¤
f3ae6a ¤   ¤   ¤   // this is a meta introducer, add it to our growing collection
6ac517 ¤   ¤   ¤   if (bMetaIntroducer)·
90f776 ¤   ¤   ¤   {
27f123 ¤   ¤   ¤   ¤   err = PGPNewSingletonKeySet (key, &keysetSingle); CKERR;
00cf67 ¤   ¤   ¤   ¤   err = PGPAddKeys (keysetSingle, keysetMeta); CKERR;
1fa457 ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetSingle);
c49e50 ¤   ¤   ¤   ¤   keysetSingle = kInvalidPGPKeySetRef;
35a3a6 ¤   ¤   ¤   }
e70fe4 ¤   ¤   }
039371 ¤   }
f3af5a
260085 ¤   // return keyset
8a7ed4 ¤   *pkeysetMeta = keysetMeta;
7d7091 ¤   keysetMeta = kInvalidPGPKeySetRef;
09af5a
40a1c0 done :
c0ffbe ¤   if (PGPKeySetRefIsValid (keysetMeta))
a49ff4 ¤   ¤   PGPFreeKeySet (keysetMeta);
2d259a ¤   if (PGPKeySetRefIsValid (keysetSingle))
50a17c ¤   ¤   PGPFreeKeySet (keysetSingle);
2bc601 ¤   if (PGPKeyIterRefIsValid (keyiter))
48e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
a6774a ¤   if (PGPKeyListRefIsValid (keylist))
5e5a47 ¤   ¤   PGPFreeKeyList (keylist);
8e67c5 ¤
195ea8 ¤   return err;
b4efe6 }
a9af5a
74c509 //¤ ____________________________________
2d465d //
8c6bfb //¤ find keys signed by specified key and update them from keyserver
f4af5a
0169c9 static PGPError·
c79423 sFindAndUpdateKeysIntroducedBy (
b3e0af ¤   ¤   HWND¤   ¤   ¤   hwnd,
59f9c6 ¤   ¤   PGPKeyRef¤  ¤   key,
1455dd ¤   ¤   PGPKeySetRef¤   keysetMain,
aac7a3 ¤   ¤   PGPKeySetRef¤   keysetSigned)
59bb36 {
001e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
ccd219 ¤   PGPFilterRef¤   filter¤ ¤   ¤   = kInvalidPGPFilterRef;
752a76 ¤   PGPKeyListRef¤  keylist¤¤   ¤   = kInvalidPGPKeyListRef;
00c69d ¤   PGPKeyIterRef¤  keyiter¤¤   ¤   = kInvalidPGPKeyIterRef;
3ebd45 ¤   PGPKeySetRef¤   keysetFound¤¤   = kInvalidPGPKeySetRef;
7e913b ¤   PGPKeySetRef¤   keysetSingle¤   = kInvalidPGPKeySetRef;
29af5a
0086e7 ¤   PGPKeyID¤   ¤   keyidMeta;
9aaf5a
bf2a76 ¤   // get the keyid of this meta introducer key
d39f30 ¤   err = PGPGetKeyIDFromKey (key, &keyidMeta); CKERR;
3baf5a
ec4129 ¤   // create a filter to find keys signed by this key
889fd3 ¤   err = PGPNewSigKeyIDFilter (g_Context, &keyidMeta, &filter); CKERR;
d5af5a
0a035c ¤   // go out and search the root keyserver with this filter
b4a2b8 ¤   err = PGPclSearchServerWithFilter (g_Context, g_TLSContext,
cb49fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd, filter, PGPCL_ROOTSERVER,·
e2091c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keysetMain, &keysetFound); CKERR;
3cf097 ¤   if (!PGPKeySetRefIsValid (keysetFound))·
73262d ¤   ¤   goto done;
f0af5a
d5a1f6 ¤   // we found some keys signed by the meta introducer, now iterate them
566d2b ¤   err = PGPOrderKeySet (keysetFound, kPGPAnyOrdering, &keylist); CKERR;
43cece ¤   err = PGPNewKeyIter (keylist, &keyiter); CKERR;
89d83c ·
d36fda ¤   while (¤IsntPGPError (PGPKeyIterNext (keyiter, &key)) &&
b7723b ¤   ¤   ¤   PGPKeyRefIsValid (key))
d8c7a1 ¤   {
02b810 ¤   ¤   PGPBoolean¤ ¤   bSignedByMeta¤  = FALSE;
242246 ¤   ¤   PGPUserIDRef¤   userid;
--68b7 0001effb9a1401102e8 Page 8 of PKMisc.c
b5c91e ¤   ¤   PGPSigRef¤  ¤   sig;
d927d1 ¤   ¤   PGPBoolean¤ ¤   bExportable;
95510f ¤   ¤   PGPUInt32¤  ¤   uTrustLevel;
c24607 ¤   ¤   PGPKeyID¤   ¤   keyidSigner;
57af5a
7e4c34 ¤   ¤   while (¤IsntPGPError (PGPKeyIterNextUserID (keyiter, &userid)) &&
bad612 ¤   ¤   ¤   ¤   PGPUserIDRefIsValid (userid) &&
e8a8bb ¤   ¤   ¤   ¤   !bSignedByMeta)
685b34 ¤   ¤   {
6a6949 ¤   ¤   ¤   while (¤IsntPGPError (PGPKeyIterNextUIDSig (keyiter, &sig)) &&
0d37af ¤   ¤   ¤   ¤   ¤   PGPSigRefIsValid (sig) &&
f32347 ¤   ¤   ¤   ¤   ¤   !bSignedByMeta)
aaf776 ¤   ¤   ¤   {
f000d1 ¤   ¤   ¤   ¤   err = PGPGetKeyIDOfCertifier (sig, &keyidSigner); CKERR;
4c1310 ¤   ¤   ¤   ¤   err = PGPGetSigBoolean (sig,·
e2c083 ¤   ¤   ¤   ¤   ¤   ¤   kPGPSigPropIsExportable, &bExportable); CKERR;
78770c ¤   ¤   ¤   ¤   err =PGPGetSigNumber ·(sig,·
18ff5b ¤   ¤   ¤   ¤   ¤   ¤   kPGPSigPropTrustLevel, &uTrustLevel); CKERR;
d3af5a
eaef4f ¤   ¤   ¤   ¤   // check if this cert was created by meta introducer
8d3abb ¤   ¤   ¤   ¤   // and if it has the appropriate properties
1da119 ¤   ¤   ¤   ¤   if (bExportable && (uTrustLevel == 1)) {
046d26 ¤   ¤   ¤   ¤   ¤   if (PGPCompareKeyIDs (&keyidMeta, &keyidSigner) == 0)
b57c9c ¤   ¤   ¤   ¤   ¤   ¤   bSignedByMeta = TRUE;
fc2613 ¤   ¤   ¤   ¤   }
f9a3a6 ¤   ¤   ¤   }
ce0fe4 ¤   ¤   }
ea1b52 ¤   ¤
7ec280 ¤   ¤   // this key is one that we're looking for, add it to keyset
6869fb ¤   ¤   if (bSignedByMeta) {
90f655 ¤   ¤   ¤   err = PGPNewSingletonKeySet (key, &keysetSingle); CKERR;
77ec66 ¤   ¤   ¤   err = PGPAddKeys (keysetSingle, keysetSigned); CKERR;
2f9d92 ¤   ¤   ¤   PGPFreeKeySet (keysetSingle);
23cd4b ¤   ¤   ¤   keysetSingle = kInvalidPGPKeySetRef;
3d0fe4 ¤   ¤   }
629371 ¤   }
c2af5a
6fb38c done:
ca259a ¤   if (PGPKeySetRefIsValid (keysetSingle))
9ca17c ¤   ¤   PGPFreeKeySet (keysetSingle);
b647df ¤   if (PGPKeySetRefIsValid (keysetFound))
a93ced ¤   ¤   PGPFreeKeySet (keysetFound);
1e774a ¤   if (PGPKeyListRefIsValid (keylist))
d95a47 ¤   ¤   PGPFreeKeyList (keylist);
fcc601 ¤   if (PGPKeyIterRefIsValid (keyiter))
45e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
f10947 ¤   if (PGPFilterRefIsValid (filter))
b41fb8 ¤   ¤   PGPFreeFilter (filter);
bbaf5a
915ea8 ¤   return err;
56efe6 }
07af5a
76c509 //¤ ____________________________________
26465d //
f43b3d //¤ Auto update trusted introducers in keyring
07af5a
bf7efe BOOL·
3a2310 PKAutoUpdateIntroducers (
dc7851 ¤   ¤   HWND¤   ¤   ¤   hwnd,·
0c55dd ¤   ¤   PGPKeySetRef¤   keysetMain,
9eb086 ¤   ¤   BOOL¤   ¤   ¤   bForce)·
0dbb36 {
ff7f73 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   ¤   = kPGPError_NoErr;
8b8858 ¤   PGPKeySetRef¤   keysetMeta¤ ¤   ¤   = kInvalidPGPKeySetRef;
f21685 ¤   PGPKeySetRef¤   keysetUpdatedMeta¤  = kInvalidPGPKeySetRef;
737e57 ¤   PGPKeySetRef¤   keysetSigned¤   ¤   = kInvalidPGPKeySetRef;
1c3ca3 ¤   PGPKeyListRef¤  keylist¤¤   ¤   ¤   = kInvalidPGPKeyListRef;
196293 ¤   PGPKeyIterRef¤  keyiter¤¤   ¤   ¤   = kInvalidPGPKeyIterRef;
8b05c1 ¤   BOOL¤   ¤   ¤   bImported¤  ¤   ¤   = FALSE;
e2af5a
3b23e3 ¤   PGPKeyRef¤  ¤   ¤   key;
1e48b2 ¤   PGPInt32¤   ¤   ¤   iNumKeys;
--245e 0002efdae1a401102e8 Page 9 of PKMisc.c
74b653 ¤   HCURSOR¤¤   ¤   ¤   hcursorOld;
faaf5a
874ad9 ¤   // get meta introducers from main keyset
f52690 ¤   err = sGetMetaIntroducers (keysetMain, &keysetMeta); CKERR;
e9af5a
676276 ¤   // if we have some, update them from root keyserver
eeb152 ¤   PGPCountKeys (keysetMeta, &iNumKeys);
b6ff3b ¤   if (iNumKeys > 0)·
c3c7a1 ¤   {
ecd503 ¤   ¤   err = PGPclUpdateKeySetFromServer (g_Context, g_TLSContext, hwnd,·
d02488 ¤   ¤   ¤   ¤   ¤   keysetMeta, PGPCL_ROOTSERVER, keysetMain,·
6498fa ¤   ¤   ¤   ¤   ¤   &keysetUpdatedMeta); CKERR;
1b9371 ¤   }
13af5a
61b079 ¤   // if we found keys on keyserver, add them to our main keyset
f2e42b ¤   if (PGPRefIsValid (keysetUpdatedMeta)) {
46bbc4 ¤   ¤   hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
83af75 ¤   ¤   err = PGPAddKeys (keysetUpdatedMeta, keysetMain);·
f600c0 ¤   ¤   if (IsntPGPError (err))·
8d5b34 ¤   ¤   {
113457 ¤   ¤   ¤   bImported = TRUE;
db490a ¤   ¤   ¤   err = PKCommitKeyRingChanges (keysetMain, TRUE);
c70fe4 ¤   ¤   }
5a5a89 ¤   ¤   SetCursor (hcursorOld);
ac2283 ¤   ¤   CKERR;
439371 ¤   }
f1af5a
c74e21 ¤   // create new keyset to collect keys signed by the meta introducers
474c0c ¤   err = PGPNewKeySet (g_Context, &keysetSigned); CKERR;
b4af5a
b10578 ¤   // now prepare to iterate through the meta introducers
2b79d3 ¤   err = PGPOrderKeySet (keysetMeta, kPGPAnyOrdering, &keylist); CKERR;
fdcece ¤   err = PGPNewKeyIter (keylist, &keyiter); CKERR;
c2af5a
c35cf4 ¤   while (¤IsntPGPError (PGPKeyIterNext (keyiter, &key)) &&·
0f723b ¤   ¤   ¤   PGPKeyRefIsValid (key))
a8c7a1 ¤   {
ab658c ¤   ¤   // go look for keys signed by this meta introducer
191d49 ¤   ¤   err = sFindAndUpdateKeysIntroducedBy (
2868a2 ¤   ¤   ¤   ¤   ¤   hwnd, key, keysetMain, keysetSigned); CKERR;
ac9371 ¤   }
c44339 ¤   CKERR;
62af5a
d6d80a ¤   // now add the updated signed keys to our main keyset
b499bd ¤   if (bForce)·
39c7a1 ¤   {
17bbc4 ¤   ¤   hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
ce69ba ¤   ¤   err = PGPAddKeys (keysetSigned, keysetMain);
478536 ¤   ¤   if (IsntPGPError (err)) {
8d3457 ¤   ¤   ¤   bImported = TRUE;
6e490a ¤   ¤   ¤   err = PKCommitKeyRingChanges (keysetMain, TRUE);
2c0fe4 ¤   ¤   }
4f5a89 ¤   ¤   SetCursor (hcursorOld);
169371 ¤   }
894264 ¤   else·
6ac7a1 ¤   {
227599 ¤   ¤   PGPCountKeys (keysetSigned, &iNumKeys);
f55da9 ¤   ¤   if (iNumKeys > 0)
a25b34 ¤   ¤   {
dd7497 ¤   ¤   err = PGPclQueryAddKeys (g_Context,·
d90309 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·g_TLSContext,
3620c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hwnd,
6cae66 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·keysetSigned,·
877e04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·keysetMain);
008536 ¤   ¤   if (IsntPGPError (err)) {
fb035f ¤   ¤   ¤   ¤   bImported = TRUE;
569323 ¤   ¤   ¤   ¤   err = PKCommitKeyRingChanges (keysetMain, TRUE);
43a3a6 ¤   ¤   ¤   }
110fe4 ¤   ¤   }
3a0e1d ¤   ¤   else
a95b34 ¤   ¤   {
2ee439 ¤   ¤   ¤   PKMessageBox (hwnd, IDS_AUTOUPDATECAPTION,·
--7ef7 0017193eb21401102e8 Page 10 of PKMisc.c
18cb5e ¤   ¤   ¤   ¤   ¤   IDS_NONEWTRUSTEDINTROS, MB_OK|MB_ICONEXCLAMATION);
0d0fe4 ¤   ¤   }
139371 ¤   }
8aaf5a
cbb38c done:
30774a ¤   if (PGPKeyListRefIsValid (keylist))
225a47 ¤   ¤   PGPFreeKeyList (keylist);
3cc601 ¤   if (PGPKeyIterRefIsValid (keyiter))
c2e9ea ¤   ¤   PGPFreeKeyIter (keyiter);
117e95 ¤   if (PGPKeySetRefIsValid (keysetUpdatedMeta))
d1153a ¤   ¤   PGPFreeKeySet (keysetUpdatedMeta);
ccffbe ¤   if (PGPKeySetRefIsValid (keysetMeta))
439ff4 ¤   ¤   PGPFreeKeySet (keysetMeta);
ce0c0f ¤   if (PGPKeySetRefIsValid (keysetSigned))
7688e9 ¤   ¤   PGPFreeKeySet (keysetSigned);
8eaf5a
10016f ¤   PGPclErrorBox (hwnd, err);
dbaf5a
df107d ¤   return bImported;
6cefe6 }
22af5a
71af5a
--f66f 0008c0ab02d401102e9 Page 1 of PKMsgPrc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
6d4d2f ¤   PKMsgPrc - main message processing and associated routines
bc67c5 ¤
0caf5a
0b87e6 ¤   $Id: PKMsgPrc.c,v 1.165.2.3 1998/10/28 23:11:34 pbj Exp $
31f7f7 ____________________________________________________________________________*/
982194 #include "pgpPFLConfig.h"¤  /* or pgpConfig.h in the CDK */
58af5a
60c917 // project header files
7cc55a #include "pgpkeysx.h"
10c94c #include "search.h"
e324a3 #include "PGPpk.h"
cb7528 #include "pgpImage.h"
65af5a
6bad8c // pgp header files
74c9ba #include "pgpKeyserverPrefs.h"·
7e91b9 #include "pgpSDKPrefs.h"
b9af5a
59fc2c // system header files
203ef0 #include <zmouse.h>
16af5a
9e13d7 // constant defitions
a1750d #define RELOADDELAY¤¤   ·200L¤  ¤   //delay to allow clearing of window
3ff7d6 #define RELOADTIMERID¤  1112L¤  ¤   //
06af5a
5b53a4 #define WRITELOCKTRIES¤ 3¤  ¤   ¤   //num times to try keyring when locked
504d06 #define WRITELOCKDELAY¤ 1500L¤  ¤   //ms delay when keyring is writelocked
efaf5a
11b7bd #define LEDTIMER¤   ¤   111L
2c4cc2 #define LEDTIMERPERIOD¤ 100L
9caf5a
711520 #define NUMLEDS 10
b7d490 #define LEDWIDTH 6
6dc9ac #define LEDSPACING 2
8927b6 #define TOTALLEDWIDTH (NUMLEDS*(LEDWIDTH+LEDSPACING+1))
aaaf5a
b1ff3e #define LOCK_PANE¤  ¤   ¤   0
e0ed8c #define STATUS_MSG_PANE¤¤   1
15ac32 #define PROGRESS_PANE¤  ¤   2
0baf5a
68d0b7 #define TLS_NOSEARCHYET¤¤   ¤   0
37e89c #define TLS_NOTAUTHENTICATED¤   1
8efab3 #define TLS_AUTHENTICATED¤  ¤   2
f5af5a
c66712 #define LOCKWIDTH¤  ¤   ¤   18
96af5a
5c7be8 #define STATUSBARHEIGHT¤¤   20
87e9fd #define SEARCHCONTROLHEIGHT¤100
8daf5a
7d5156 #define GRABBARHEIGHT¤  ¤   2
34af5a
611384 #define MINSEARCHWINDOWHEIGHT¤  260
dc83da #define MINSEARCHWINDOWWIDTH¤   460
28af5a
dc822f // External globals
42eec0 extern HINSTANCE¤   ¤   g_hInst;
2c2dd4 extern HWND¤¤   ¤   ¤   g_hWndMain;
9c5e8b extern CHAR¤¤   ¤   ¤   g_szHelpFile[MAX_PATH];
4cacd2 extern UINT¤¤   ¤   ¤   g_uReloadPrefsMessage;
cf7d05 extern UINT¤¤   ¤   ¤   g_uReloadKeyringMessage;
c52fa3 extern UINT¤¤   ¤   ¤   g_uReloadKeyserverPrefsMessage;
d2508d extern UINT¤¤   ¤   ¤   g_uPurgePassphraseCacheMessage;
45dd35 extern UINT¤¤   ¤   ¤   g_uMouseWheelMessage;
f9cf38 extern PGPContextRef¤   g_Context;
4002e7 extern PGPtlsContextRef¤g_TLSContext;
1daacd extern PGPBoolean¤  ¤   g_bExpertMode;
6b2e92 extern PGPBoolean¤  ¤   g_bKeyGenEnabled;
58dbc0 extern PGPBoolean¤  ¤   g_bMarginalAsInvalid;
8c1924 extern BOOL¤¤   ¤   ¤   g_bReadOnly;
--3627 000c08e2796401102e9 Page 2 of PKMsgPrc.c
0236d6 extern BOOL¤¤   ¤   ¤   g_bShowGroups;
5b5d79 extern INT¤ ¤   ¤   ¤   g_iGroupsPercent;
78cba3 extern INT¤ ¤   ¤   ¤   g_iToolHeight;
f1af5a
07ec91 // Local globals
584822 static BOOL¤¤   ¤   bKeyHasBeenGenerated = FALSE;
8060f5 static BOOL¤¤   ¤   bMakeBackups = FALSE;
9d6a8b static BOOL¤¤   ¤   bIgnoreReloads = FALSE;
afc5b3 static HWND¤¤   ¤   hwndOpenSearch = NULL;
3f5a0d static BOOL¤¤   ¤   bFirstKeyringLoad = TRUE;
823f98 static ULONG¤   ¤   ulColumns = 0;
3f4fbc static HIMAGELIST¤  himlLocks = NULL;
deaf5a
b1af5a
29c509 //¤ ____________________________________
e5465d //
afaa05 // ·Look for secret keys
77af5a
576c77 static BOOL·
8ae59c sPKCheckForSecretKeys (PGPKeySetRef KeySet)·
e9bb36 {
37a37c ¤   PGPKeyListRef¤  KeyList;
92b17a ¤   PGPKeyIterRef¤  KeyIter;
0e7593 ¤   PGPKeyRef¤  ¤   Key;
fe0000 ¤   PGPBoolean¤ ¤   bSecret;
3348e3 ¤   BOOL¤   ¤   ¤   bSecretKeys;
caaf5a
750ba7 ¤   PGPOrderKeySet (KeySet, kPGPAnyOrdering, &KeyList);
f21953 ¤   PGPNewKeyIter (KeyList, &KeyIter);
4baf5a
1a5857 ¤   bSecretKeys = FALSE;
fd800a ¤   PGPKeyIterNext (KeyIter, &Key);
b1af5a
8dcab8 ¤   while (Key && !bSecretKeys) {
b38a79 ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
fc6059 ¤   ¤   if (bSecret) {
8019f1 ¤   ¤   ¤   bSecretKeys = TRUE;
ad0fe4 ¤   ¤   }
4f455f ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
059371 ¤   }
6baf5a
5111d4 ¤   PGPFreeKeyIter (KeyIter);
eca279 ¤   PGPFreeKeyList (KeyList);
d7af5a
d81bc2 ¤   return bSecretKeys;
dbefe6 }
0eaf5a
38c509 //¤ ____________________________________
ac465d //
70907f // ·Process files in command line
eaaf5a
26b333 static VOID·
1db731 sProcessFileList (LPSTR¤¤   ¤   pszList,·
ee656c ¤   ¤   ¤   ¤   ·BOOL¤  ¤   ¤   bCommandLine,·
b88094 ¤   ¤   ¤   ¤   ·BOOL¤  ¤   ¤   bAllowSelect,
296d90 ¤   ¤   ¤   ¤   ·PGPKeySetRef¤  keysetMain)·
94bb36 {
dcbd55 ¤   PGPFileSpecRef¤ fileref;
14db8c ¤   PGPKeySetRef¤   keysetToAdd;
b09018 ¤   LPSTR¤  ¤   ¤   p, p2;
19a110 ¤   INT¤¤   ¤   ¤   iNumKeys;
a441c8 ¤   CHAR¤   ¤   ¤   cTerm;
5567c5 ¤
ac2cfb ¤   p = pszList;
45af5a
5f288e ¤   // skip over path of program·
feb4f9 ¤   if (bCommandLine) {
c4b44e ¤   ¤   while (*p && (*p == ' ')) p++;
c7584d ¤   ¤   if (*p) {
621754 ¤   ¤   ¤   if (*p == '"') {
742543 ¤   ¤   ¤   ¤   p++;
c0fedc ¤   ¤   ¤   ¤   cTerm = '"';
--71c5 000ba9c417a401102e9 Page 3 of PKMsgPrc.c
cfa3a6 ¤   ¤   ¤   }
0be1e0 ¤   ¤   ¤   else cTerm = ' ';
240fe4 ¤   ¤   }
4e29ec ¤   ¤   while (*p && (*p != cTerm)) p++;
4d510e ¤   ¤   if (*p && (cTerm == '"')) p++;
489371 ¤   }
f5af5a
03433d ¤   // parse file names
30066f ¤   // Unfortunately, the OS hands me names in the command line in all·
3a0258 ¤   // sorts of forms: space delimited; quoted and space delimited; space
30feb0 ¤   // delimiter after the program path but then NULL terminated.
8e4db2 ¤   // And this is just NT ...
d3ee8f ¤   while (p && *p) {
e8b44e ¤   ¤   while (*p && (*p == ' ')) p++;
f6584d ¤   ¤   if (*p) {
ef1754 ¤   ¤   ¤   if (*p == '"') {
9c2543 ¤   ¤   ¤   ¤   p++;
5ffedc ¤   ¤   ¤   ¤   cTerm = '"';
5ea3a6 ¤   ¤   ¤   }
b2e1e0 ¤   ¤   ¤   else cTerm = ' ';
50af5a
1c20b2 ¤   ¤   ¤   p2 = strchr (p, cTerm);
65dc12 ¤   ¤   ¤   if (p2) {
4bf519 ¤   ¤   ¤   ¤   if (*(p2+2) == ':') *p2 = '\0';
96a3a6 ¤   ¤   ¤   }
efaf5a
7b1c20 ¤   ¤   ¤   PGPNewFileSpecFromFullPath (g_Context, p, &fileref);
331e23 ¤   ¤   ¤   if (fileref) {
ef7361 ¤   ¤   ¤   ¤   PGPImportKeySet (g_Context, &keysetToAdd,·
ef84b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputFile (g_Context, fileref),
02ff59 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (g_Context));
3b4b16 ¤   ¤   ¤   ¤   if (keysetToAdd) {
4d6f61 ¤   ¤   ¤   ¤   ¤   PGPCountKeys (keysetToAdd, &iNumKeys);
bed907 ¤   ¤   ¤   ¤   ¤   if (iNumKeys > 0) {
57f27a ¤   ¤   ¤   ¤   ¤   ¤   if (bAllowSelect) {
e0f5e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys (g_Context, g_TLSContext,
5df9fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_hWndMain, keysetToAdd, keysetMain);
94db3c ¤   ¤   ¤   ¤   ¤   ¤   }
592863 ¤   ¤   ¤   ¤   ¤   ¤   else {
39407a ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPAddKeys (keysetToAdd, keysetMain);
da9452 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PKCommitKeyRingChanges (keysetMain, TRUE);
6bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
a81c89 ¤   ¤   ¤   ¤   ¤   }
21a6e6 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetToAdd);
992613 ¤   ¤   ¤   ¤   }
080505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
f3a3a6 ¤   ¤   ¤   }
d6a8ff ¤   ¤   ¤   if (p2) *p2 = ' ';
130fe4 ¤   ¤   }
7929ec ¤   ¤   while (*p && (*p != cTerm)) p++;
ef510e ¤   ¤   if (*p && (cTerm == '"')) p++;
339371 ¤   }
83efe6 }
72af5a
86c509 //¤ ____________________________________
7c465d //
40345d // ·Import keys from WM_COPYDATA struct
c1af5a
806c77 static BOOL·
096119 sImportData (PGPKEYSSTRUCT* ppks, PCOPYDATASTRUCT pcds)·
6bbb36 {
d4c1dc ¤   PGPKeySetRef¤   keyset¤ ¤   = kInvalidPGPKeySetRef;
93344e ¤   BOOL¤   ¤   ¤   bPrompt;
b7fb19 ¤   PGPError¤   ¤   err;
98af5a
5baf5a
bf9c0a ¤   bPrompt = pcds->dwData & PGPPK_SELECTIVEIMPORT;
91af5a
1600fc ¤   switch (pcds->dwData & PGPPK_IMPORTKEYMASK) {
543f52 ¤   case PGPPK_IMPORTKEYBUFFER :
41baba ¤   ¤   err = PGPImportKeySet (g_Context, &keyset,·
ba9371 ¤   ¤   ¤   ¤   PGPOInputBuffer (g_Context, pcds->lpData, pcds->cbData),
--22cd 00019ee7f99401102e9 Page 4 of PKMsgPrc.c
55b759 ¤   ¤   ¤   ¤   PGPOLastOption (g_Context));
b11274 ¤   ¤   if (IsntPGPError (err) && PGPKeySetRefIsValid (keyset)) {
5721cf ¤   ¤   ¤   if (bPrompt) {
1fa736 ¤   ¤   ¤   ¤   PGPclQueryAddKeys (g_Context, g_TLSContext,·
e80208 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_hWndMain, keyset, ppks->KeySetMain);
f7a3a6 ¤   ¤   ¤   }
99e543 ¤   ¤   ¤   else {
4466d5 ¤   ¤   ¤   ¤   err = PGPAddKeys (keyset, ppks->KeySetMain);
1e54db ¤   ¤   ¤   ¤   PKCommitKeyRingChanges (ppks->KeySetMain, TRUE);
200bc3 ¤   ¤   ¤   ¤   PGPkmReLoadKeySet (ppks->hKM, TRUE);
41a3a6 ¤   ¤   ¤   }
9b0fe4 ¤   ¤   }
0d1e6d ¤   ¤   if (PGPKeySetRefIsValid (keyset))·
0808ba ¤   ¤   ¤   PGPFreeKeySet (keyset);
eb9142 ¤   ¤   return (IsntPGPError (err));
efaf5a
80979d ¤   case PGPPK_IMPORTKEYFILELIST :
1a7fda ¤   ¤   sProcessFileList (pcds->lpData, FALSE, bPrompt, ppks->KeySetMain);
ca836c ¤   ¤   return TRUE;
06af5a
e9e2ee ¤   case PGPPK_IMPORTKEYCOMMANDLINE :
69dee4 ¤   ¤   sProcessFileList (pcds->lpData, TRUE, bPrompt, ppks->KeySetMain);
0d836c ¤   ¤   return TRUE;
869371 ¤   }
d4efe6 }
3daf5a
4fc509 //¤ ____________________________________
26465d //
460883 // ·import keys from admin prefs file
c5af5a
0269c9 static PGPError·
e9d707 sImportPrefsKeys (PGPKeySetRef keysetMain)
fcbb36 {
5e9d10 ¤   PGPError¤   ¤   err¤¤   ¤   = kPGPError_UnknownError;
ceaf5a
8cbe29 #if PGP_BUSINESS_SECURITY
8156d3 ¤   BOOL¤   ¤   ¤   bSave¤  ¤   = FALSE;
09ff87 ¤   PGPKeySetRef¤   keysetNew;
50ce0f ¤   PGPPrefRef¤ ¤   prefref;
31fdbc ¤   LPSTR¤  ¤   ¤   psz;
30af5a
ad164e #if PGP_ADMIN_BUILD
d1654a ¤   err = PGPclOpenAdminPrefs (
74ce55 ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
7d4906 ¤   ¤   ¤   ¤   &prefref,·
8d6765 ¤   ¤   ¤   ¤   TRUE);
cadb21 #else
c8654a ¤   err = PGPclOpenAdminPrefs (
7ece55 ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
db4906 ¤   ¤   ¤   ¤   &prefref,·
83afba ¤   ¤   ¤   ¤   FALSE);
367454 #endif
51af5a
46b23e ¤   if (IsntPGPError (err)) {
c40b08 ¤   ¤   err = PGPGetPrefStringAlloc (prefref, kPGPPrefDefaultKeys, &psz);
d6551b ¤   ¤   if (IsntPGPError (err) && psz) {
0b0c05 ¤   ¤   ¤   if (psz[0]) {
06f0c9 ¤   ¤   ¤   ¤   err = PGPImportKeySet (g_Context, &keysetNew,·
9984f5 ¤   ¤   ¤   ¤   ¤   ¤   PGPOInputBuffer (g_Context, psz, lstrlen(psz)+1),
78b6df ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (g_Context));
8caf5a
7456ab ¤   ¤   ¤   ¤   if (IsntPGPError (err)) {
9e72fb ¤   ¤   ¤   ¤   ¤   PGPAddKeys (keysetNew, keysetMain);
2a1966 ¤   ¤   ¤   ¤   ¤   err = PKCommitKeyRingChanges (keysetMain, TRUE);
919429 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetNew);
272613 ¤   ¤   ¤   ¤   }
11a3a6 ¤   ¤   ¤   }
a9cd83 ¤   ¤   ¤   PGPDisposePrefData (prefref, psz);
630fe4 ¤   ¤   }
218387 ¤   ¤   PGPclCloseAdminPrefs (prefref, bSave);
829371 ¤   }
19af5a
--d25a 00074869683401102e9 Page 5 of PKMsgPrc.c
180863 #endif //PGP_BUSINESS_SECURITY
95af5a
e85ea8 ¤   return err;
a1efe6 }
67af5a
bec509 //¤ ____________________________________
72465d //
316e85 // ·Reload keyrings
5eaf5a
bdb333 static VOID·
53a7a1 sReloadKeyrings (PGPKEYSSTRUCT* ppks,PGPBoolean *UserCancel)·
aebb36 {
e3485e ¤   BOOL¤   ¤   ¤   ¤   bMutable¤   ¤   ¤   = TRUE;
6e931b ¤   PGPKeyRingOpenFlags¤flags¤  ¤   ¤   ¤   = kPGPKeyRingOpenFlags_Mutable;
415743 ¤   INT¤¤   ¤   ¤   ¤   iLockTries¤ ¤   ¤   = 0;
5daf5a
50a715 ¤   PGPError¤   ¤   ¤   pgpError;
3f54d9 ¤   HCURSOR¤¤   ¤   ¤   hCursorOld;
55af5a
7a3c56 ¤   *UserCancel=FALSE;
7aaf5a
16143c ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
9a1137 ¤   PGPsdkLoadDefaultPrefs (g_Context);
7a9af8 ¤   pgpError = PGPOpenDefaultKeyRings (g_Context, flags,·
3320ba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(ppks->KeySetMain));
43dc67 ¤   SetCursor (hCursorOld);
e1af5a
39b099 ¤   while (!ppks->KeySetMain ||·
28d3bf ¤   ¤   ···PGPkmLoadKeySet (ppks->hKM, ppks->KeySetMain, ppks->KeySetMain)) {
9baf5a
9599fe ¤   ¤   switch (pgpError) {
26af5a
4034cd ¤   ¤   case kPGPError_FilePermissions :
19cf6d ¤   ¤   ¤   bMutable = FALSE;
7ccdcb ¤   ¤   ¤   break;
37af5a
46d5ef ¤   ¤   case kPGPError_FileLocked :
6ed162 ¤   ¤   ¤   iLockTries++;
73a4f3 ¤   ¤   ¤   if (iLockTries < WRITELOCKTRIES) {
c24453 ¤   ¤   ¤   ¤   Sleep (WRITELOCKDELAY);
bba3a6 ¤   ¤   ¤   }
8ae543 ¤   ¤   ¤   else {
aa8052 ¤   ¤   ¤   ¤   PKMessageBox (g_hWndMain, IDS_CAPTION, IDS_LOCKEDKEYRING,
652d15 ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
88daf6 ¤   ¤   ¤   ¤   if (!PKPGPPreferences (ppks, g_hWndMain, 1)) {
25eb47 ¤   ¤   ¤   ¤   ¤   *UserCancel=TRUE;
e7a81b ¤   ¤   ¤   ¤   ¤   SendMessage (g_hWndMain, WM_CLOSE, 0, 0);
24825d ¤   ¤   ¤   ¤   ¤   return;
882613 ¤   ¤   ¤   ¤   }
d7a3a6 ¤   ¤   ¤   }
08cdcb ¤   ¤   ¤   break;
10af5a
f9f613 ¤   ¤   case kPGPError_CantOpenFile :
80bac3 ¤   ¤   case kPGPError_FileNotFound :
f9da14 ¤   ¤   ¤   if (!PKPGPPreferences (ppks, g_hWndMain, 1)) {
a70434 ¤   ¤   ¤   ¤   *UserCancel=TRUE;
244a1b ¤   ¤   ¤   ¤   SendMessage (g_hWndMain, WM_CLOSE, 0, 0);
f57438 ¤   ¤   ¤   ¤   return;
36a3a6 ¤   ¤   ¤   }
58cdcb ¤   ¤   ¤   break;
faaf5a
ae3a18 ¤   ¤   default :
1c4609 ¤   ¤   ¤   PKMessageBox (g_hWndMain, IDS_CAPTION, IDS_CORRUPTKEYRING,·
14e840 ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
1fda14 ¤   ¤   ¤   if (!PKPGPPreferences (ppks, g_hWndMain, 1)) {
6f0434 ¤   ¤   ¤   ¤   *UserCancel=TRUE;
5c4a1b ¤   ¤   ¤   ¤   SendMessage (g_hWndMain, WM_CLOSE, 0, 0);
577438 ¤   ¤   ¤   ¤   return;
9ba3a6 ¤   ¤   ¤   }
d0cdcb ¤   ¤   ¤   break;
b40fe4 ¤   ¤   }
74f63c ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
--6e01 000d262df28401102e9 Page 6 of PKMsgPrc.c
220e78 ¤   ¤   flags = 0;
4cc6f6 ¤   ¤   if (bMutable) flags |= kPGPKeyRingOpenFlags_Mutable;
2978f8 ¤   ¤   pgpError = PGPOpenDefaultKeyRings (g_Context, flags,·
059ca3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(ppks->KeySetMain));
d67139 ¤   ¤   SetCursor (hCursorOld);
eb9371 ¤   }
f0af5a
84ed99 ¤   g_bReadOnly = !bMutable;
2baf5a
b69db1 ¤   if (g_bReadOnly) {
0c9603 ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_READONLY;
277ffa ¤   ¤   PKReadOnlyWarning (ppks->hWndMain);
879371 ¤   }
41665a ¤   else {
70486f ¤   ¤   ppks->kmConfig.ulOptionFlags &= ~KMF_READONLY;
c89371 ¤   }
17af5a
008c29 ¤   // pass readonly flag to keymanager
255108 ¤   ppks->kmConfig.ulMask = PGPKM_OPTIONS;
6f92fa ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
32af5a
3992fc ¤   // reload the groups file
df121f ¤   ppks->gmConfig.keysetMain = ppks->KeySetMain;
b20121 ¤   PGPgmConfigure (ppks->hGM, &(ppks->gmConfig));
160026 ¤   PGPgmLoadGroups (ppks->hGM);
93efe6 }
34af5a
b4c509 //¤ ____________________________________
f2465d //
793ea9 // ·Draw the owner-drawn part of the status bar
59af5a
b3e6b2 static VOID
f08e0f sDrawStatus (
b7fb4e ¤   ¤   LPDRAWITEMSTRUCT lpdis,·
e7baef ¤   ¤   PGPKEYSSTRUCT* ppks)·
52bb36 {
0a9276 ¤   HBRUSH¤ hBrushLit, hBrushUnlit, hBrushOld;
0c664d ¤   HPEN¤   hPen, hPenOld;
945c93 ¤   INT¤¤   i;
4c7a23 ¤   INT¤¤   itop, ibot, ileft, iright;
caaf5a
6423ab ¤   if(lpdis->itemID == PROGRESS_PANE)
0ac7a1 ¤   {
50eb02 ¤   ¤   if (ppks->iStatusValue < -1) return;
08af5a
1b38f9 ¤   ¤   // draw 3D shadow
5cb54f ¤   ¤   itop = lpdis->rcItem.top+3;
ea172f ¤   ¤   ibot = lpdis->rcItem.bottom-5;
77af5a
3bef05 ¤   ¤   ileft = lpdis->rcItem.left + 4;
c50690 ¤   ¤   for (i=0; i<NUMLEDS; i++) {
b60a19 ¤   ¤   ¤   iright = ileft + LEDWIDTH;
c9af5a
4a426b ¤   ¤   ¤   MoveToEx (lpdis->hDC, ileft, ibot, NULL);
61c3ef ¤   ¤   ¤   LineTo (lpdis->hDC, iright, ibot);
7feb49 ¤   ¤   ¤   LineTo (lpdis->hDC, iright, itop);
1faf5a
0bc85a ¤   ¤   ¤   ileft += LEDWIDTH + LEDSPACING;
590fe4 ¤   ¤   }
62af5a
474a43 ¤   ¤   hPen = CreatePen (PS_SOLID, 0, RGB (128, 128, 128));
c7a2f8 ¤   ¤   hPenOld = SelectObject (lpdis->hDC, hPen);
68382e ¤   ¤   hBrushLit = CreateSolidBrush (RGB (0, 255, 0));
ceede6 ¤   ¤   hBrushUnlit = CreateSolidBrush (RGB (0, 128, 0));
3aaf5a
d0ef05 ¤   ¤   ileft = lpdis->rcItem.left + 4;
6baf5a
15930f ¤   ¤   // draw "Knight Rider" LEDs
7db3b5 ¤   ¤   if (ppks->iStatusDirection) {
234066 ¤   ¤   ¤   hBrushOld = SelectObject (lpdis->hDC, hBrushUnlit);
92c3c5 ¤   ¤   ¤   for (i=0; i<NUMLEDS; i++) {
d20455 ¤   ¤   ¤   ¤   iright = ileft + LEDWIDTH;
--bfff 00012b1fe3e401102e9 Page 7 of PKMsgPrc.c
f11b52 ¤   ¤
9cd24a ¤   ¤   ¤   ¤   if (i == ppks->iStatusValue) {
247e66 ¤   ¤   ¤   ¤   ¤   SelectObject (lpdis->hDC, hBrushLit);
f01ad4 ¤   ¤   ¤   ¤   ¤   Rectangle (lpdis->hDC, ileft, itop, iright, ibot);
188c94 ¤   ¤   ¤   ¤   ¤   SelectObject (lpdis->hDC, hBrushUnlit);
132613 ¤   ¤   ¤   ¤   }
d0e3f1 ¤   ¤   ¤   ¤   else ·{
211ad4 ¤   ¤   ¤   ¤   ¤   Rectangle (lpdis->hDC, ileft, itop, iright, ibot);
672613 ¤   ¤   ¤   ¤   }
eb1b52 ¤   ¤
f0d00a ¤   ¤   ¤   ¤   ileft += LEDWIDTH + LEDSPACING;
d4a3a6 ¤   ¤   ¤   }
f10fe4 ¤   ¤   }
88af5a
d323fa ¤   ¤   // draw "progress bar" LEDs
f2c245 ¤   ¤   else {·
cb2a13 ¤   ¤   ¤   if (ppks->iStatusValue >= 0)·
90fa64 ¤   ¤   ¤   ¤   hBrushOld = SelectObject (lpdis->hDC, hBrushLit);
9dbb8c ¤   ¤   ¤   else
ad7d08 ¤   ¤   ¤   ¤   hBrushOld = SelectObject (lpdis->hDC, hBrushUnlit);
88af5a
b7c3c5 ¤   ¤   ¤   for (i=0; i<NUMLEDS; i++) {
e90455 ¤   ¤   ¤   ¤   iright = ileft + LEDWIDTH;
ee1b52 ¤   ¤
2199de ¤   ¤   ¤   ¤   if (i > ppks->iStatusValue) {
2c8c94 ¤   ¤   ¤   ¤   ¤   SelectObject (lpdis->hDC, hBrushUnlit);
e32613 ¤   ¤   ¤   ¤   }
220958 ¤   ¤   ¤   ¤   Rectangle (lpdis->hDC, ileft, itop, iright, ibot);
431b52 ¤   ¤
8dd00a ¤   ¤   ¤   ¤   ileft += LEDWIDTH + LEDSPACING;
75a3a6 ¤   ¤   ¤   }
1b0fe4 ¤   ¤   }
11af5a
1b75a6 ¤   ¤   SelectObject (lpdis->hDC, hBrushOld);
831d76 ¤   ¤   SelectObject (lpdis->hDC, hPenOld);
c621a8 ¤   ¤   DeleteObject (hPen);
22db4e ¤   ¤   DeleteObject (hBrushLit);
b693c0 ¤   ¤   DeleteObject (hBrushUnlit);
ea9371 ¤   }
22ad95 ¤   else if(lpdis->itemID == LOCK_PANE)
7ac7a1 ¤   {
5e6804 ¤   ¤   BOOL bSecure = (BOOL) lpdis->itemData;
28af5a
c24624 ¤   ¤   if (bSecure) {
0774d9 ¤   ¤   ¤   bSecure = TRUE;
ec0fe4 ¤   ¤   }
3daf5a
a0bf0f ¤   ¤   ImageList_Draw (himlLocks, (bSecure ? IDX_CLOSEDLOCK:IDX_OPENLOCK),
437fb3 ¤   ¤   ¤   lpdis->hDC, 1, 3, ILD_TRANSPARENT);
b7af5a
6b9371 ¤   }
37efe6 }
26af5a
08af5a
34c509 //¤ ____________________________________
91465d //
260234 // ·display downloaded key count in status bar
15af5a
e111ec static INT
b4d6c1 sDisplayKSKeyResult (
34e99b ¤   ¤   PGPKeySetRef¤   keyset,·
867851 ¤   ¤   HWND¤   ¤   ¤   hwnd,·
78118e ¤   ¤   PGPError¤   ¤   err)·
8fbb36 {
0a4bc0 ¤   CHAR sz1[256];
c1c110 ¤   CHAR sz2[256];
95bf0d ¤   INT¤ iCount;
10af5a
0b901a ¤   if (keyset)
173ca3 ¤   ¤   (void)PGPCountKeys (keyset, &iCount);
504264 ¤   else·
12c586 ¤   ¤   iCount = 0;
--dd55 0003665c2c3401102e9 Page 8 of PKMsgPrc.c
e0af5a
978ec4 ¤   if (err == kPGPError_ServerPartialSearchResults)
827307 ¤   ¤   LoadString (g_hInst, IDS_KSTOOMANYKEYCOUNT, sz1, sizeof(sz1));
174264 ¤   else·
4ede37 ¤   ¤   LoadString (g_hInst, IDS_KSKEYCOUNT, sz1, sizeof(sz1));
905266 ¤   wsprintf (sz2, sz1, iCount);
6812fd ¤   SendMessage (hwnd, SB_SETTEXT, STATUS_MSG_PANE, (LPARAM)sz2);
bd67c5 ¤
e2d01b ¤   return iCount;
2aefe6 }
97af5a
27c509 //¤ ____________________________________
2a465d //
d6107a // ·get number of wheel scroll lines and pass to treelist controls
b0af5a
a0e6b2 static VOID
b3cf09 sUpdateWheelScrollLines (PGPKEYSSTRUCT* ppks)
a3bb36 {
046996 ¤   UINT uLines;
f0af5a
28ad81 ¤   if (!SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &uLines, 0))·
9ac7a1 ¤   {
2d38a3 ¤   ¤   HWND hwnd = NULL;
dfb309 ¤   ¤   UINT umsg = 0;
9aaf5a
c4c5ed ¤   ¤   umsg = RegisterWindowMessage (MSH_SCROLL_LINES);
c6f294 ¤   ¤   hwnd = FindWindow (MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE);
36af5a
56160c ¤   ¤   if (hwnd && umsg)·
71ff8e ¤   ¤   ¤   uLines = (UINT)SendMessage (hwnd, umsg, 0, 0);
539371 ¤   }
56af5a
c8893e ¤   if (ppks->hWndTreeList)
9a8191 ¤   ¤   TreeList_SetWheelScrollLines (ppks->hWndTreeList, uLines);
3ceef8 ¤   if (ppks->hWndTreeListGroups)
60b9ae ¤   ¤   TreeList_SetWheelScrollLines (ppks->hWndTreeListGroups, uLines);
47efe6 }
9baf5a
b9c509 //¤ ____________________________________
52465d //
5c30de // ·Main PGPkeys Window Message procedure
a2af5a
21880b LONG APIENTRY·
58dcff KeyManagerWndProc (
8547b2 ¤   ¤   HWND¤   hWnd,·
4deb77 ¤   ¤   UINT¤   uMsg,·
1617d4 ¤   ¤   WPARAM¤ wParam,·
f7c0b8 ¤   ¤   LPARAM¤ lParam)·
4fbb36 {
391372 ¤   RECT¤   ¤   ¤   rc;
519c68 ¤   PGPKEYSSTRUCT*¤ ppks;
4af618 ¤   INT¤¤   ¤   ¤   iWidths[3];
8baf5a
12347f ¤   switch (uMsg) {
97af5a
31055f ¤   case WM_CREATE :
72d122 ¤   ¤   ppks = (PGPKEYSSTRUCT*)pkAlloc (sizeof (PGPKEYSSTRUCT));
e92073 ¤   ¤   if (!ppks) return -1;
807914 ¤   ¤   SetWindowLong (hWnd, GWL_USERDATA, (LPARAM)ppks);
87af5a
632924 ¤   ¤   GetClientRect (hWnd, &rc);
59af5a
307059 ¤   ¤   // if lpCreateParams is NULL, this is the main window
fd23df ¤   ¤   if (((LPCREATESTRUCT)lParam)->lpCreateParams == NULL) {
42fc4f ¤   ¤   ¤   ppks->hWndMain = hWnd;
42e310 ¤   ¤   ¤   ppks->bMainWindow = TRUE;
4483b9 ¤   ¤   ¤   ppks->iToolHeight = g_iToolHeight;·
32f2c9 ¤   ¤   ¤   ppks->iKeysHeight =·
07b30e ¤   ¤   ¤   ¤   rc.bottom-rc.top-ppks->iToolHeight-STATUSBARHEIGHT;
686283 ¤   ¤   ¤   ppks->bGroupsVisible = FALSE;
f7dd69 ¤   ¤   ¤   ppks->iGroupsPercent = g_iGroupsPercent;
36fc7b ¤   ¤   ¤   ppks->iGroupsHeight = 0;
--ff21 0009ae02d34401102e9 Page 9 of PKMsgPrc.c
e7cbf8 ¤   ¤   ¤   ppks->bLocalKeySet = TRUE;
19cd2f ¤   ¤   ¤   ppks->KeySetMain = NULL;
69da62 ¤   ¤   ¤   ppks->KeySetDisp = NULL;
3ffd40 ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags =·
059e72 ¤   ¤   ¤   ¤   KMF_ENABLECOMMITS|KMF_ENABLEDRAGOUT|
f30c89 ¤   ¤   ¤   ¤   KMF_ENABLEDROPIN|KMF_ENABLERELOADS;
88f557 ¤   ¤   ¤   if (!g_bExpertMode)·
32196d ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_NOVICEMODE;
a592e0 ¤   ¤   ¤   if (g_bMarginalAsInvalid)·
30a96a ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_MARGASINVALID;
36d5e9 ¤   ¤   ¤   ppks->kmConfig.ulDisableActions =·
e1e6c1 ¤   ¤   ¤   ¤   KM_ADDTOMAIN;
2daf5a
21c970 ¤   ¤   ¤   ppks->hMenuKeyserver = NULL;
ea86fc ¤   ¤   ¤   ppks->hMenuKeyMan = GetMenu (hWnd);
8599f7 ¤   ¤   ¤   PKInitMenuKeyMan (ppks->hMenuKeyMan);
9faf5a
6ed4fc ¤   ¤   ¤   // setup group manager
95e9e7 ¤   ¤   ¤   ppks->hGM = PGPgmCreateGroupManager (g_Context, g_TLSContext,
398d5a ¤   ¤   ¤   ¤   ¤   hWnd, IDC_TREELISTGROUP,
a311df ¤   ¤   ¤   ¤   ¤   0,·
969476 ¤   ¤   ¤   ¤   ¤   (rc.bottom-rc.top)-ppks->iGroupsHeight-
f68b68 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STATUSBARHEIGHT,
35583e ¤   ¤   ¤   ¤   ¤   (rc.right-rc.left),
828f08 ¤   ¤   ¤   ¤   ¤   ppks->iGroupsHeight);
6d8083 ¤   ¤   ¤   ppks->hWndTreeListGroups = PGPgmGetManagerWindow (ppks->hGM);
d7bbbb ¤   ¤   ¤   ppks->gmConfig.ulOptionFlags = 0;
0ef557 ¤   ¤   ¤   if (!g_bExpertMode)·
16c66c ¤   ¤   ¤   ¤   ppks->gmConfig.ulOptionFlags |= GMF_NOVICEMODE;
bc1bee ¤   ¤   ¤   ppks->gmConfig.ulDisableActions = 0;
5323d2 ¤   ¤   ¤   ppks->gmConfig.keysetMain = NULL;
018871 ¤   ¤   ¤   ppks->hWndToolBar = PKCreateToolbar (hWnd);
3e0fe4 ¤   ¤   }
40af5a
1e4c4b ¤   ¤   // otherwise this is a search window and lpCreateParams is·
62c735 ¤   ¤   // the main KeySetRef
1607e0 ¤   ¤   else {
8ec5be ¤   ¤   ¤   hwndOpenSearch = hWnd;
ae2121 ¤   ¤   ¤   ppks->bMainWindow = FALSE;
7f6a69 ¤   ¤   ¤   ppks->iToolHeight = SEARCHCONTROLHEIGHT;
89f2c9 ¤   ¤   ¤   ppks->iKeysHeight =·
1fb30e ¤   ¤   ¤   ¤   rc.bottom-rc.top-ppks->iToolHeight-STATUSBARHEIGHT;
ed6283 ¤   ¤   ¤   ppks->bGroupsVisible = FALSE;
e6fc7b ¤   ¤   ¤   ppks->iGroupsHeight = 0;
f9016c ¤   ¤   ¤   ppks->iGroupsPercent = 0;
7dcbf8 ¤   ¤   ¤   ppks->bLocalKeySet = TRUE;
82abf8 ¤   ¤   ¤   ppks->KeySetMain =·
2cfa30 ¤   ¤   ¤   ¤   (PGPKeySetRef)(((LPCREATESTRUCT)lParam)->lpCreateParams);
92da62 ¤   ¤   ¤   ppks->KeySetDisp = NULL;
c2fd40 ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags =·
fd39ac ¤   ¤   ¤   ¤   KMF_ENABLEDRAGOUT;
95f557 ¤   ¤   ¤   if (!g_bExpertMode)·
9a196d ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_NOVICEMODE;
6292e0 ¤   ¤   ¤   if (g_bMarginalAsInvalid)·
2ca96a ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_MARGASINVALID;
c05d57 ¤   ¤   ¤   ppks->kmConfig.ulDisableActions = KM_ALLACTIONS;
851ece ¤   ¤   ¤   ppks->pGroupFile = NULL;
d2af5a
d9c970 ¤   ¤   ¤   ppks->hMenuKeyserver = NULL;
647dc4 ¤   ¤   ¤   ppks->hMenuKeyMan = NULL;
96af5a
c179f5 ¤   ¤   ¤   if (InitSearch ()) {
1b7fb3 ¤   ¤   ¤   ¤   ppks->hWndSearchControl = CreateSearch (g_hInst, hWnd);
70af5a
ee6c13 ¤   ¤   ¤   ¤   SendMessage (ppks->hWndSearchControl, SEARCH_SET_LOCAL_KEYSET,
872e12 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)(ppks->KeySetMain));
638dcd ¤   ¤   ¤   ¤   GetWindowRect (ppks->hWndSearchControl, &rc);
2c5515 ¤   ¤   ¤   ¤   ppks->iToolHeight = rc.bottom-rc.top;
58a3a6 ¤   ¤   ¤   }
a7b3cf ¤   ¤   ¤   ppks->hWndToolBar = NULL;
5f0fe4 ¤   ¤   }
9aaf5a
--b80a 0006d4075f5401102e9 Page 10 of PKMsgPrc.c
18747a ¤   ¤   PKDialogListFunc (hWnd, TRUE, NULL, NULL);
daaf5a
5e8763 ¤   ¤   ppks->bGroupsFocused = FALSE;
410461 ¤   ¤   ppks->uKeySelectionFlags = 0;
5204c3 ¤   ¤   ppks->uGroupSelectionFlags = 0;
18315f ¤   ¤   ppks->hCursorOld = NULL;
dff2d9 ¤   ¤   ppks->bGrabEnabled = FALSE;
e0e840 ¤   ¤   ppks->bGrabbed = FALSE;
e5af5a
7065c9 ¤   ¤   ppks->hKM = PGPkmCreateKeyManager (g_Context, g_TLSContext,
fa9835 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hWnd, IDC_TREELIST, PKDialogListFunc,·
83f1f3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, ppks->iToolHeight,·
be95d5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right-rc.left,·
ee1690 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iKeysHeight);
24af5a
22713d ¤   ¤   ppks->kmConfig.lpszHelpFile = NULL;
00e90c ¤   ¤   ppks->kmConfig.keyserver.structSize = 0;
f04220 ¤   ¤   ppks->kmConfig.ulShowColumns = 0;
77d6b7 ¤   ¤   ppks->kmConfig.ulHideColumns = 0;
5aaf5a
68b031 ¤   ¤   // create status bar
1de4d7 ¤   ¤   ppks->bSearchInProgress = FALSE;
e19d8e ¤   ¤   ppks->iStatusValue = -2;
a84fd5 ¤   ¤   ppks->iStatusDirection = 1;
bcf7f8 ¤   ¤   ppks->kmConfig.hWndStatusBar = CreateStatusWindow (
63c91d ¤   ¤   ¤   WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP,
69eb61 ¤   ¤   ¤   "",
742276 ¤   ¤   ¤   hWnd,
5c6d74 ¤   ¤   ¤   IDC_STATUSBAR);
921b52 ¤   ¤
3f2f13 ¤   ¤   // setup status bar
bdabf3 ¤   ¤   if (ppks->bMainWindow)
281a4c ¤   ¤   ¤   iWidths[0] = 0;
3d0e1d ¤   ¤   else
fad3a8 ¤   ¤   ¤   iWidths[0] = LOCKWIDTH;
467a81 ¤   ¤   iWidths[1] = rc.right-TOTALLEDWIDTH-16;
3e4cb9 ¤   ¤   iWidths[2] = rc.right-16;
4c67c5 ¤
59d6fe ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETPARTS, 3,·
d7a6fb ¤   ¤   ¤   ¤   ¤   (LPARAM)iWidths);
fdaf5a
d9d278 ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTEXT,·
1b7377 ¤   ¤   ¤   ¤   ¤   LOCK_PANE|SBT_OWNERDRAW|SBT_POPOUT, 0);
9faf5a
78d278 ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTEXT,·
ee5ff1 ¤   ¤   ¤   ¤   ¤   PROGRESS_PANE|SBT_OWNERDRAW, 0);
95af5a
6f13c1 ¤   ¤   // load the lock icons
92ce53 ¤   ¤   if (himlLocks == NULL)
915b34 ¤   ¤   {
12031f ¤   ¤   ¤   HDC¤¤   hDC;
f9cb0c ¤   ¤   ¤   INT¤¤   iNumBits;
6223e7 ¤   ¤   ¤   HBITMAP¤hBmp;
f1af5a
639e61 ¤   ¤   ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
4e5727 ¤   ¤   ¤   iNumBits =·
19c868 ¤   ¤   ¤   ¤   GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
ba7ec4 ¤   ¤   ¤   ReleaseDC (NULL, hDC);
6b67c5 ¤
b2a4ef ¤   ¤   ¤   if (iNumBits <= 8) {
d63e04 ¤   ¤   ¤   ¤   himlLocks =¤
b7330a ¤   ¤   ¤   ¤   ¤   ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,·
6d8f86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
7c4914 ¤   ¤   ¤   ¤   hBmp =·
f00afb ¤   ¤   ¤   ¤   ¤   LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
e12197 ¤   ¤   ¤   ¤   ImageList_AddMasked (himlLocks, hBmp, RGB(255, 0, 255));
61dab3 ¤   ¤   ¤   ¤   DeleteObject (hBmp);
82a3a6 ¤   ¤   ¤   }
41e543 ¤   ¤   ¤   else {
f03e04 ¤   ¤   ¤   ¤   himlLocks =¤
79590a ¤   ¤   ¤   ¤   ¤   ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,·
6d8f86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_BITMAPS, 0);·
--c327 000d86422f2401102e9 Page 11 of PKMsgPrc.c
ae4914 ¤   ¤   ¤   ¤   hBmp =·
1120e6 ¤   ¤   ¤   ¤   ¤   LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
cb2197 ¤   ¤   ¤   ¤   ImageList_AddMasked (himlLocks, hBmp, RGB(255, 0, 255));
51dab3 ¤   ¤   ¤   ¤   DeleteObject (hBmp);
b9a3a6 ¤   ¤   ¤   }
df0fe4 ¤   ¤   }
8eaf5a
7b61fb ¤   ¤   // set the tooltip text for the lock icon (requires comctl 4.71)
06c906 ///¤¤   if (!ppks->bMainWindow) {
294d10 ///¤¤   ¤   CHAR szTip[32];
7be671 ///¤¤   ¤   LoadString (g_hInst, IDS_LOCKICONTIP, szTip, sizeof(szTip));
9dd9fe ///¤¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTIPTEXT,·
3fb957 ///¤¤   ¤   ¤   ¤   (WPARAM)LOCK_PANE, (LPARAM)szTip);
907ea3 ///¤¤   }
9eaf5a
772f7d ¤   ¤   // initialize TLS info
fa30c2 ¤   ¤   ppks->iTLSstatus = TLS_NOSEARCHYET;
ed24d3 ¤   ¤   ppks->szTLSserver[0] = '\0';
fb9c5e ¤   ¤   ppks->keyAuth = kInvalidPGPKeyRef;
9baf5a
719b98 ¤   ¤   // set initial configuration of keymanager
365af8 ¤   ¤   ppks->kmConfig.ulMask = PGPKM_ALLITEMS;
5c83dd ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
5c1b52 ¤   ¤
92745b ¤   ¤   ppks->hWndTreeList = PGPkmGetManagerWindow (ppks->hKM);
a3af5a
6186ce ¤   ¤   if (ppks->bMainWindow) {
29b86a ¤   ¤   ¤   PGPkmGetSelectedColumns (ppks->hKM, &ulColumns);
92e528 ¤   ¤   ¤   ppks->gmConfig.lpszHelpFile = NULL;
350f7a ¤   ¤   ¤   ppks->gmConfig.hKM = ppks->hKM;
898ea9 ¤   ¤   ¤   ppks->gmConfig.hWndStatusBar = ppks->kmConfig.hWndStatusBar;
6f173d ¤   ¤   ¤   PGPgmConfigure (ppks->hGM, &(ppks->gmConfig));
91856a ¤   ¤   ¤   PGPclSetSplashParent (hWnd);
2aeab7 ¤   ¤   ¤   PostMessage (hWnd, KM_M_RELOADKEYRINGS, 0, 0);
6c0fe4 ¤   ¤   }
2707e0 ¤   ¤   else {
9e1fbe ¤   ¤   ¤   PGPkmLoadKeySet (ppks->hKM, ppks->KeySetDisp, ppks->KeySetMain);
bd4f82 ¤   ¤   ¤   ppks->iStatusValue = -1;
789d55 ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar, NULL, FALSE);
210fe4 ¤   ¤   }
f7af5a
7a98bf ¤   ¤   // initialize enabled/disabled states of toolbar buttons
2ef44f ¤   ¤   PKSetToolbarButtonStates (ppks);
73af5a
fd8cbe ¤   ¤   // initialize the number of mouse wheel scroll lines
773a3c ¤   ¤   sUpdateWheelScrollLines (ppks);
d8af5a
9dbbde ¤   ¤   return 0;
d9af5a
0475f9 ¤   case WM_CLOSE :
89a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
4f86ce ¤   ¤   if (ppks->bMainWindow) {
8f8aac ¤   ¤   ¤   UINT uReason;
5daf5a
3da38a ¤   ¤   ¤   if (!PGPkmOKToClose (ppks->hKM, &uReason)) {
60a24d ¤   ¤   ¤   ¤   if (uReason == KMR_EXISTINGSPLITKEYDLGS) {
d574e1 ¤   ¤   ¤   ¤   ¤   if (!PKSplitKeyWarn (hWnd)) break;
8c2613 ¤   ¤   ¤   ¤   }
47a3a6 ¤   ¤   ¤   }
6faf5a
f13830 ¤   ¤   ¤   if (bKeyHasBeenGenerated) {
1036fd ¤   ¤   ¤   ¤   if (!PKBackupWarn (hWnd, &bMakeBackups)) break;
32a3a6 ¤   ¤   ¤   }
fdaf5a
985770 ¤   ¤   ¤   PKSetPrivatePrefData (hWnd,·
4e02c9 ¤   ¤   ¤   ¤   ¤   ppks->bGroupsVisible, ppks->iGroupsPercent,
cd1ab6 ¤   ¤   ¤   ¤   ¤   ppks->iToolHeight);
58139e ¤   ¤   ¤   WinHelp (hWnd, g_szHelpFile, HELP_QUIT, 0);
75d8b0 ¤   ¤   ¤   if (hwndOpenSearch) {
48a4e0 ¤   ¤   ¤   ¤   SendMessage (hwndOpenSearch, WM_CLOSE, 0, 0);
91a3a6 ¤   ¤   ¤   }
d80fe4 ¤   ¤   }
--81b3 000285e4d37401102e9 Page 12 of PKMsgPrc.c
5f07e0 ¤   ¤   else {
5b53d5 ¤   ¤   ¤   KillTimer (hWnd, LEDTIMER);
6f3d70 ¤   ¤   ¤   hwndOpenSearch = NULL;
6f0fe4 ¤   ¤   }
3a403d ¤   ¤   DestroyWindow (hWnd);
2ebbde ¤   ¤   return 0;
2daf5a
a3ae91 ¤   case WM_ACTIVATE :
dbe6ba ¤   ¤   if (LOWORD (wParam) != WA_INACTIVE) {
cfb66e ¤   ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
87bba6 ¤   ¤   ¤   if (ppks->bMainWindow) {
e44bfd ¤   ¤   ¤   ¤   if (ppks->bGroupsFocused) SetFocus (ppks->hWndTreeListGroups);
e12aba ¤   ¤   ¤   ¤   else SetFocus (ppks->hWndTreeList);
90a3a6 ¤   ¤   ¤   }
c5e543 ¤   ¤   ¤   else {
860984 ¤   ¤   ¤   ¤   SetFocus (ppks->hWndTreeList);
73a3a6 ¤   ¤   ¤   }
960fe4 ¤   ¤   }
3e2f68 ¤   ¤   break;
7baf5a
154c31 ¤   case WM_ENABLE :
9fa5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
880d17 ¤   ¤   if (ppks->bMainWindow) PKEnableDlgList ((BOOL)wParam);
1e4251 ¤   ¤   if (wParam)
44862f ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags &= ~KMF_DISABLEKEYPROPS;
890e1d ¤   ¤   else
728961 ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_DISABLEKEYPROPS;
7cc090 ¤   ¤   ppks->kmConfig.ulMask = PGPKM_OPTIONS;
1183dd ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
f52f68 ¤   ¤   break;
bbaf5a
716334 ¤   case WM_DESTROY :
09a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
55af5a
8d5718 ¤   ¤   if (ppks->hGM) {
0c858b ¤   ¤   ¤   PGPgmDestroyGroupManager (ppks->hGM);
80f7a7 ¤   ¤   ¤   ppks->hGM = NULL;
810fe4 ¤   ¤   }
7067c5 ¤
c4039e ¤   ¤   PGPkmDestroyKeyManager (ppks->hKM, ppks->bMainWindow);
1ecab5 ¤   ¤   PGPgmDestroyGroupManager (ppks->hGM);
e7af5a
da86ce ¤   ¤   if (ppks->bMainWindow) {
8fde18 ¤   ¤   ¤   if (PGPKeySetRefIsValid (ppks->KeySetMain))
b41754 ¤   ¤   ¤   ¤   PGPFreeKeySet (ppks->KeySetMain);
0e103d ¤   ¤   ¤   if (bMakeBackups) PKBackup (hWnd);
7f1cc5 ¤   ¤   ¤   PKDestroyToolbar (ppks->hWndToolBar);
9f66c5 ¤   ¤   ¤   ImageList_Destroy (himlLocks);
0846de ¤   ¤   ¤   PostQuitMessage(0);
430fe4 ¤   ¤   }
1307e0 ¤   ¤   else {
032b72 ¤   ¤   ¤   if (PGPKeySetRefIsValid (ppks->KeySetDisp))
aae23e ¤   ¤   ¤   ¤   PGPFreeKeySet (ppks->KeySetDisp);
f70fe4 ¤   ¤   }
55af5a
90f289 ¤   ¤   if (PGPKeySetRefIsValid (ppks->keysetAuth))
b22157 ¤   ¤   ¤   PGPFreeKeySet (ppks->keysetAuth);
42af5a
370cb9 ¤   ¤   PKDialogListFunc (hWnd, FALSE, NULL, NULL);
d334e0 ¤   ¤   pkFree (ppks);
d20737 ¤   ¤   ppks=NULL;
4b2f68 ¤   ¤   break;
b6af5a
fc1ce4 ¤   case WM_INITMENU :
36a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
159e91 ¤   ¤   if ((HMENU)wParam == ppks->hMenuKeyMan)·
e6c195 ¤   ¤   ¤   PKSetMainMenu (ppks);
452f68 ¤   ¤   break;
1caf5a
db90ef ¤   case WM_SIZE :
78a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
28a0aa ¤   ¤   if (ppks->bGroupsVisible) {
--375c 00006984104401102e9 Page 13 of PKMsgPrc.c
25c930 ¤   ¤   ¤   ppks->iGroupsHeight = HIWORD(lParam) * ppks->iGroupsPercent;
4c52fd ¤   ¤   ¤   ppks->iGroupsHeight /= 100;
9ff2c9 ¤   ¤   ¤   ppks->iKeysHeight =·
864bc0 ¤   ¤   ¤   ¤   HIWORD(lParam)-ppks->iToolHeight-STATUSBARHEIGHT-
f2a85e ¤   ¤   ¤   ¤   ppks->iGroupsHeight-GRABBARHEIGHT;
16c88f ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeList, NULL,·
484b51 ¤   ¤   ¤   ¤   0, 0,·
cddcef ¤   ¤   ¤   ¤   LOWORD(lParam),·
aaa1e9 ¤   ¤   ¤   ¤   ppks->iKeysHeight,
bee6cc ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);
7b3cdc ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeListGroups, NULL, 0,
af5a67 ¤   ¤   ¤   ¤   HIWORD(lParam)-ppks->iGroupsHeight-STATUSBARHEIGHT,
ab5c1e ¤   ¤   ¤   ¤   LOWORD(lParam),
03036e ¤   ¤   ¤   ¤   ppks->iGroupsHeight,
40b748 ¤   ¤   ¤   ¤   SWP_NOZORDER);
aa0fe4 ¤   ¤   }
0b07e0 ¤   ¤   else {
4af2c9 ¤   ¤   ¤   ppks->iKeysHeight =·
cd8a81 ¤   ¤   ¤   ¤   HIWORD(lParam)-ppks->iToolHeight-STATUSBARHEIGHT;
dbaf5a
93c88f ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeList, NULL,·
814b51 ¤   ¤   ¤   ¤   0, 0,·
2adcef ¤   ¤   ¤   ¤   LOWORD(lParam),·
3ba1e9 ¤   ¤   ¤   ¤   ppks->iKeysHeight,
1ce6cc ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);
540fe4 ¤   ¤   }
1caf5a
36403e ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, WM_SIZE, wParam, lParam);
56af5a
2ee0f3 ¤   ¤   if (ppks->bMainWindow)·
f11a4c ¤   ¤   ¤   iWidths[0] = 0;
00ee26 ¤   ¤   else·
7ad3a8 ¤   ¤   ¤   iWidths[0] = LOCKWIDTH;
6c52d9 ¤   ¤   iWidths[1] = LOWORD(lParam)-TOTALLEDWIDTH-16;
aefe00 ¤   ¤   iWidths[2] = LOWORD(lParam)-16;
78d6fe ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETPARTS, 3,·
a2a6fb ¤   ¤   ¤   ¤   ¤   (LPARAM)iWidths);
e1af5a
b2b6c1 ¤   ¤   if (ppks->hWndSearchControl) {
bdc1a6 ¤   ¤   ¤   SendMessage (ppks->hWndSearchControl, WM_SIZE, wParam,·
d6314c ¤   ¤   ¤   ¤   MAKELPARAM (LOWORD(lParam), ppks->iToolHeight));
665b10 ¤   ¤   ¤   InvalidateRect (ppks->hWndSearchControl, NULL, FALSE);
7c0fe4 ¤   ¤   }
68af5a
a5242d ¤   ¤   if (ppks->hWndToolBar) {
24a463 ¤   ¤   ¤   SetWindowPos (ppks->hWndToolBar, NULL,·
0a4b51 ¤   ¤   ¤   ¤   0, 0,·
88dcef ¤   ¤   ¤   ¤   LOWORD(lParam),·
01b018 ¤   ¤   ¤   ¤   ppks->iToolHeight - TOOLBARYOFFSET,
3429ca ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);·
f10fe4 ¤   ¤   }
8aaf5a
d1bbde ¤   ¤   return 0;
50af5a
18e1c7 ¤   case WM_MOUSEMOVE :
16a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
f8a0aa ¤   ¤   if (ppks->bGroupsVisible) {
1b92e2 ¤   ¤   ¤   INT¤¤   iY, iVSize, iYGrab;
d29ef4 ¤   ¤   ¤   iY = HIWORD(lParam);
cd7b52 ¤   ¤   ¤   if (ppks->bGrabbed) {
dc669b ¤   ¤   ¤   ¤   GetClientRect (hWnd, &rc);
043d92 ¤   ¤   ¤   ¤   iVSize = rc.bottom-rc.top;
41c5da ¤   ¤   ¤   ¤   if (iVSize <= 0) break;
aaaf5a
33ac27 ¤   ¤   ¤   ¤   iY = (iVSize-STATUSBARHEIGHT-GRABBARHEIGHT) -iY;
ea8243 ¤   ¤   ¤   ¤   if ((iY > 50) && (iY < (iVSize -50))) {
8ef1f8 ¤   ¤   ¤   ¤   ¤   ppks->iGroupsPercent = (100 * iY) / iVSize;
2f5423 ¤   ¤   ¤   ¤   ¤   ppks->iGroupsHeight = iY;
182613 ¤   ¤   ¤   ¤   }
85af5a
58cfa1 ¤   ¤   ¤   ¤   ppks->iKeysHeight =·
068a6f ¤   ¤   ¤   ¤   ¤   iVSize-ppks->iToolHeight-STATUSBARHEIGHT-
--3186 0002f11573e401102e9 Page 14 of PKMsgPrc.c
0eb979 ¤   ¤   ¤   ¤   ¤   ppks->iGroupsHeight-GRABBARHEIGHT;
95a7bc ¤   ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeList, NULL,·
89a9b0 ¤   ¤   ¤   ¤   ¤   0, 0,·
1a0a01 ¤   ¤   ¤   ¤   ¤   rc.right-rc.left,·
6de01a ¤   ¤   ¤   ¤   ¤   ppks->iKeysHeight,
97df09 ¤   ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);
39e6f5 ¤   ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeListGroups, NULL, 0,
a9a1d5 ¤   ¤   ¤   ¤   ¤   iVSize-ppks->iGroupsHeight-STATUSBARHEIGHT,
b73fce ¤   ¤   ¤   ¤   ¤   rc.right-rc.left,
c80683 ¤   ¤   ¤   ¤   ¤   ppks->iGroupsHeight,
273b37 ¤   ¤   ¤   ¤   ¤   SWP_NOZORDER);
d3a3a6 ¤   ¤   ¤   }
1ee543 ¤   ¤   ¤   else {
c230b6 ¤   ¤   ¤   ¤   iYGrab = ppks->iToolHeight+ppks->iKeysHeight;
79ed6f ¤   ¤   ¤   ¤   if ((iY >= iYGrab-2) &&·
9c7250 ¤   ¤   ¤   ¤   ¤   (iY <= iYGrab+GRABBARHEIGHT+2)) {
c060b2 ¤   ¤   ¤   ¤   ¤   ppks->bGrabEnabled = TRUE;
dc5e71 ¤   ¤   ¤   ¤   ¤   ppks->hCursorOld =·
9b61b6 ¤   ¤   ¤   ¤   ¤   ¤   SetCursor (LoadCursor (NULL, IDC_SIZENS));
422115 ¤   ¤   ¤   ¤   ¤   SetCapture (hWnd);
b12613 ¤   ¤   ¤   ¤   }
13deaa ¤   ¤   ¤   ¤   else {
58ac24 ¤   ¤   ¤   ¤   ¤   if (ppks->bGrabEnabled) {
5631fb ¤   ¤   ¤   ¤   ¤   ¤   ppks->bGrabEnabled = FALSE;
dd3a9d ¤   ¤   ¤   ¤   ¤   ¤   SetCursor (ppks->hCursorOld);
c57765 ¤   ¤   ¤   ¤   ¤   ¤   ReleaseCapture ();
2e1c89 ¤   ¤   ¤   ¤   ¤   }
882613 ¤   ¤   ¤   ¤   }
6aa3a6 ¤   ¤   ¤   }
e60fe4 ¤   ¤   }
982f68 ¤   ¤   break;
90af5a
dd475b ¤   case WM_LBUTTONDOWN :
a0a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
9c467c ¤   ¤   if (ppks->bGrabEnabled) {
367a50 ¤   ¤   ¤   ppks->bGrabbed = TRUE;
100fe4 ¤   ¤   }
712f68 ¤   ¤   break;
15af5a
9d6373 ¤   case WM_LBUTTONUP :
bda5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
cb4c5a ¤   ¤   if (ppks->bGrabbed) {
1763bc ¤   ¤   ¤   ppks->bGrabbed = FALSE;
9f0fe4 ¤   ¤   }
cc2f68 ¤   ¤   break;
a7af5a
029a87 ¤   case WM_SYSCOLORCHANGE :
34a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
91b19a ¤   ¤   PostMessage (ppks->hWndTreeList, WM_SYSCOLORCHANGE, 0, 0);
702f68 ¤   ¤   break;
e2af5a
d336bc ¤   case WM_SETTINGCHANGE :
11a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
04d6e5 ¤   ¤   if (wParam == SPI_SETWHEELSCROLLLINES)
19b25a ¤   ¤   ¤   sUpdateWheelScrollLines (ppks);
69ee26 ¤   ¤   else·
9ba216 ¤   ¤   ¤   PostMessage (ppks->hWndTreeList, WM_SYSCOLORCHANGE, 0, 0);
e32f68 ¤   ¤   break;
85af5a
421d0f ¤   case WM_DRAWITEM :
ef0405 ¤   ¤   if (wParam == IDC_STATUSBAR) {
87b66e ¤   ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
685a8e ¤   ¤   ¤   sDrawStatus ((LPDRAWITEMSTRUCT)lParam, ppks);
af32bd ¤   ¤   ¤   return TRUE;
310fe4 ¤   ¤   }
492f68 ¤   ¤   break;
02af5a
3b4805 ¤   case WM_COPYDATA :
0fa5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
59d570 ¤   ¤   return (sImportData (ppks, (PCOPYDATASTRUCT)lParam));
8faf5a
2f1431 ¤   case WM_NOTIFY :
--0b7d 0002ec8c864401102e9 Page 15 of PKMsgPrc.c
84a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
d35b34 ¤   ¤   {
e75eb0 ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
33af5a
6ff526 ¤   ¤   // did it come from the keys treelist ?
997c21 ¤   ¤   if (wParam == IDC_TREELIST) {
eabdec ¤   ¤   ¤   if (pnmh->code == TLN_SELCHANGED) {
34dc13 ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_UNSELECTALL);
6aa3a6 ¤   ¤   ¤   }
89af5a
e80ced ¤   ¤   ¤   PGPkmDefaultNotificationProc (ppks->hKM, lParam);
40af5a
35e55c ¤   ¤   ¤   switch (pnmh->code) {
5db838 ¤   ¤   ¤   case TLN_CONTEXTMENU :
ec8248 ¤   ¤   ¤   ¤   ppks->bGroupsFocused = FALSE;
e495f1 ¤   ¤   ¤   ¤   ppks->uKeySelectionFlags = ((LPNM_TREELIST)lParam)->flags;
29777b ¤   ¤   ¤   ¤   PKContextMenu (ppks, hWnd,·
40caa3 ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.x,
55b27d ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.y);
cef622 ¤   ¤   ¤   ¤   break;
05af5a
be87f5 ¤   ¤   ¤   case TLN_SELCHANGED :
c88248 ¤   ¤   ¤   ¤   ppks->bGroupsFocused = FALSE;
d995f1 ¤   ¤   ¤   ¤   ppks->uKeySelectionFlags = ((LPNM_TREELIST)lParam)->flags;
ada06a ¤   ¤   ¤   ¤   PKSetToolbarButtonStates (ppks);
19f622 ¤   ¤   ¤   ¤   break;
5daf5a
4d90ef ¤   ¤   ¤   case TLN_KEYDOWN :
f0ed99 ¤   ¤   ¤   ¤   if (ppks->bGroupsVisible) {
993d54 ¤   ¤   ¤   ¤   ¤   switch (((TL_KEYDOWN*)lParam)->wVKey) {
7550fb ¤   ¤   ¤   ¤   ¤   case VK_TAB :
49ed17 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar,·
c1f609 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SB_SETTEXT, STATUS_MSG_PANE, (LPARAM)"");
464983 ¤   ¤   ¤   ¤   ¤   ¤   ppks->bGroupsFocused = !ppks->bGroupsFocused;
0a9a13 ¤   ¤   ¤   ¤   ¤   ¤   if (ppks->bGroupsFocused)·
6d5916 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetFocus (ppks->hWndTreeListGroups);
321fe8 ¤   ¤   ¤   ¤   ¤   ¤   else·
c0c72a ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetFocus (ppks->hWndTreeList);
5d9c42 ¤   ¤   ¤   ¤   ¤   ¤   PKSetToolbarButtonStates (ppks);
0700eb ¤   ¤   ¤   ¤   ¤   ¤   break;
a31c89 ¤   ¤   ¤   ¤   ¤   }
4f2613 ¤   ¤   ¤   ¤   }
4af622 ¤   ¤   ¤   ¤   break;
bfaf5a
d10082 ¤   ¤   ¤   default :
36f622 ¤   ¤   ¤   ¤   break;
01a3a6 ¤   ¤   ¤   }
d20fe4 ¤   ¤   }
51af5a
b8169f ¤   ¤   // did it come from the group treelist ?
5f149e ¤   ¤   else if (wParam == IDC_TREELISTGROUP) {
4dbdec ¤   ¤   ¤   if (pnmh->code == TLN_SELCHANGED) {
9513b3 ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_UNSELECTALL);
a1a3a6 ¤   ¤   ¤   }
55af5a
e01835 ¤   ¤   ¤   PGPgmDefaultNotificationProc (ppks->hGM, lParam);
6aaf5a
94e55c ¤   ¤   ¤   switch (pnmh->code) {
66b838 ¤   ¤   ¤   case TLN_CONTEXTMENU :
28b0d6 ¤   ¤   ¤   ¤   ppks->bGroupsFocused = TRUE;
1e8ec9 ¤   ¤   ¤   ¤   ppks->uGroupSelectionFlags = ((LPNM_TREELIST)lParam)->flags;
5a777b ¤   ¤   ¤   ¤   PKContextMenu (ppks, hWnd,·
0acaa3 ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.x,
40b27d ¤   ¤   ¤   ¤   ¤   ((LPNM_TREELIST)lParam)->ptDrag.y);
30f622 ¤   ¤   ¤   ¤   break;
61af5a
7f87f5 ¤   ¤   ¤   case TLN_SELCHANGED :
e2b0d6 ¤   ¤   ¤   ¤   ppks->bGroupsFocused = TRUE;
7f8ec9 ¤   ¤   ¤   ¤   ppks->uGroupSelectionFlags = ((LPNM_TREELIST)lParam)->flags;
0da06a ¤   ¤   ¤   ¤   PKSetToolbarButtonStates (ppks);
7cf622 ¤   ¤   ¤   ¤   break;
2eaf5a
--dda2 000a3bdc427401102e9 Page 16 of PKMsgPrc.c
4090ef ¤   ¤   ¤   case TLN_KEYDOWN :
2fb203 ¤   ¤   ¤   ¤   switch (((TL_KEYDOWN*)lParam)->wVKey) {
7367f3 ¤   ¤   ¤   ¤   case VK_TAB :
d6ba68 ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTEXT,·
72cfd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STATUS_MSG_PANE, (LPARAM)"");
d45ca0 ¤   ¤   ¤   ¤   ¤   ppks->bGroupsFocused = !ppks->bGroupsFocused;
9142a1 ¤   ¤   ¤   ¤   ¤   if (ppks->bGroupsFocused)·
e7833f ¤   ¤   ¤   ¤   ¤   ¤   SetFocus (ppks->hWndTreeListGroups);
b896bc ¤   ¤   ¤   ¤   ¤   else·
bbc011 ¤   ¤   ¤   ¤   ¤   ¤   SetFocus (ppks->hWndTreeList);
00f371 ¤   ¤   ¤   ¤   ¤   PKSetToolbarButtonStates (ppks);
1b14c3 ¤   ¤   ¤   ¤   ¤   break;
372613 ¤   ¤   ¤   ¤   }
70f622 ¤   ¤   ¤   ¤   break;
1faf5a
e90082 ¤   ¤   ¤   default :
9cf622 ¤   ¤   ¤   ¤   break;
36a3a6 ¤   ¤   ¤   }
f30fe4 ¤   ¤   }
4aaf5a
cfe84f ¤   ¤   // did it come from the search window keyserver code ?
d95425 ¤   ¤   else if ((ppks->hWndSearchControl) &&
8269ca ¤   ¤   ¤   ¤   ·(pnmh->hwndFrom == ppks->hWndSearchControl)) {
454263 ¤   ¤   ¤   switch (pnmh->code)
66f776 ¤   ¤   ¤   {
f9d426 ¤   ¤   ¤   ¤   case SEARCH_REQUEST_SIZING:·
7672c3 ¤   ¤   ¤   ¤   {
1265b0 ¤   ¤   ¤   ¤   ¤   PSIZEREQUEST pRequest = (PSIZEREQUEST)lParam;
232a4c ¤   ¤   ¤   ¤   ¤   RECT rc;
ed641e ¤   ¤   ¤   ¤   ¤   GetClientRect (ppks->hWndTreeList, &rc);
f09209 ¤   ¤   ¤   ¤   ¤   if ((rc.bottom - rc.top) > (pRequest->delta + 50))
9880de ¤   ¤   ¤   ¤   ¤   ¤   return TRUE;
2b4bd6 ¤   ¤   ¤   ¤   ¤   else
f00e30 ¤   ¤   ¤   ¤   ¤   ¤   return FALSE;
a02613 ¤   ¤   ¤   ¤   }
ccaf5a
b8ea64 ¤   ¤   ¤   ¤   case SEARCH_SIZING:·
6f72c3 ¤   ¤   ¤   ¤   {
b665b0 ¤   ¤   ¤   ¤   ¤   PSIZEREQUEST pRequest = (PSIZEREQUEST)lParam;
e4304c ¤   ¤   ¤   ¤   ¤   RECT rcTool, rcMain;
77490c ¤   ¤   ¤   ¤   ¤   GetWindowRect (pnmh->hwndFrom, &rcTool);
64ec55 ¤   ¤   ¤   ¤   ¤   ppks->iToolHeight = rcTool.bottom-rcTool.top;
72af5a
136ecc ¤   ¤   ¤   ¤   ¤   GetClientRect (hWnd, &rcMain);
7eaf5a
0a8109 ¤   ¤   ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeList, NULL,·
ff2941 ¤   ¤   ¤   ¤   ¤   ¤   0, ppks->iToolHeight,·
d830dc ¤   ¤   ¤   ¤   ¤   ¤   rcMain.right-rcMain.left,·
3c028d ¤   ¤   ¤   ¤   ¤   ¤   rcMain.bottom-rcMain.top
523aaf ¤   ¤   ¤   ¤   ¤   ¤   ¤   -ppks->iToolHeight
bcccda ¤   ¤   ¤   ¤   ¤   ¤   ¤   -STATUSBARHEIGHT,·
de7ac4 ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOZORDER);
d539f7 ¤   ¤   ¤   ¤   ¤   InvalidateRect (hWnd, NULL, FALSE);
f814c3 ¤   ¤   ¤   ¤   ¤   break;
902613 ¤   ¤   ¤   ¤   }
f4af5a
2288e0 ¤   ¤   ¤   ¤   case SEARCH_DISPLAY_KEYSET:·
8372c3 ¤   ¤   ¤   ¤   {
f0a7a6 ¤   ¤   ¤   ¤   ¤   PSEARCHRESULT¤  pResult = (PSEARCHRESULT)lParam;
3a5824 ¤   ¤   ¤   ¤   ¤   PGPKeySetRef¤   KeySetPrevious;
0524cf ¤   ¤   ¤   ¤   ¤   HCURSOR¤¤   ¤   hCursorOld;
2e72cf ¤   ¤   ¤   ¤   ¤   CHAR¤   ¤   ¤   sz[64];
21af5a
edd1ea ¤   ¤   ¤   ¤   ¤   // stop LEDs, if going
0a4a1c ¤   ¤   ¤   ¤   ¤   if (ppks->bSearchInProgress) {
6855a2 ¤   ¤   ¤   ¤   ¤   ¤   KillTimer (hWnd, LEDTIMER);
178cda ¤   ¤   ¤   ¤   ¤   ¤   ppks->bSearchInProgress = FALSE;
7a1e4a ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue = -1;
3accb0 ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar,·
bcd29b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
f76d63 ¤   ¤   ¤   ¤   ¤   ¤   UpdateWindow (ppks->kmConfig.hWndStatusBar);
a31c89 ¤   ¤   ¤   ¤   ¤   }
--9253 000a76ff562401102e9 Page 17 of PKMsgPrc.c
e0af5a
9509d5 ¤   ¤   ¤   ¤   ¤   // if error, post message and drop out
b3c953 ¤   ¤   ¤   ¤   ¤   if (IsPGPError (pResult->error) &&·
3d9118 ¤   ¤   ¤   ¤   ¤   ¤   (pResult->error !=·
132b86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPError_ServerPartialSearchResults))·
504859 ¤   ¤   ¤   ¤   ¤   {
3455a2 ¤   ¤   ¤   ¤   ¤   ¤   KillTimer (hWnd, LEDTIMER);
8d8cda ¤   ¤   ¤   ¤   ¤   ¤   ppks->bSearchInProgress = FALSE;
701e4a ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue = -1;
e3ed17 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar,·
e7f609 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SB_SETTEXT, STATUS_MSG_PANE, (LPARAM)"");
c2ccb0 ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar,·
33d1ec ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
5e293c ¤   ¤   ¤   ¤   ¤   ¤   PGPclErrorBox (NULL, pResult->error);
c100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
351c89 ¤   ¤   ¤   ¤   ¤   }
a1af5a
b72b93 ¤   ¤   ¤   ¤   ¤   // load new keyset into window
c6a1bc ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_SYNCINGKEYSETS, sz, sizeof(sz));
09ba68 ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTEXT,·
10813a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STATUS_MSG_PANE, (LPARAM)sz);
9ae726 ¤   ¤   ¤   ¤   ¤   UpdateWindow (ppks->kmConfig.hWndStatusBar);
6daf5a
0e49b0 ¤   ¤   ¤   ¤   ¤   hCursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));
3faf5a
97391b ¤   ¤   ¤   ¤   ¤   KeySetPrevious = ppks->KeySetDisp;
2473ea ¤   ¤   ¤   ¤   ¤   ppks->KeySetDisp = (PGPKeySetRef)(pResult->pData);
92af5a
4406b2 ¤   ¤   ¤   ¤   ¤   if (pResult->flags & FLAG_SEARCH_LOCAL_KEYSET) {
578c9e ¤   ¤   ¤   ¤   ¤   ¤   ppks->bLocalKeySet = TRUE;
f629b8 ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.keyserver.structSize = 0;
db26fd ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags =·
3b0401 ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMF_ENABLERELOADS |
c83d58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMF_ENABLECOMMITS |
60e78b ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMF_ENABLEDRAGOUT;
866079 ¤   ¤   ¤   ¤   ¤   ¤   if (!g_bExpertMode)
21717d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_NOVICEMODE;
05d586 ¤   ¤   ¤   ¤   ¤   ¤   if (g_bMarginalAsInvalid)·
fc876a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_MARGASINVALID;
2b143f ¤   ¤   ¤   ¤   ¤   ¤   if (g_bReadOnly)
48c8f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_READONLY;
581b47 ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulDisableActions =·
aab60d ¤   ¤   ¤   ¤   ¤   ¤   ¤   KM_ADDTOMAIN|KM_IMPORT|KM_PASTE|
5fe4cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   KM_SETASPRIMARY|KM_SETASDEFAULT;
7c1c89 ¤   ¤   ¤   ¤   ¤   }
353c4b ¤   ¤   ¤   ¤   ¤   else {
234c38 ¤   ¤   ¤   ¤   ¤   ¤   ppks->bLocalKeySet = FALSE;
605d93 ¤   ¤   ¤   ¤   ¤   ¤   memcpy (&ppks->kmConfig.keyserver,·
b265f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &pResult->keyserver,·
b63832 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(PGPKeyServerEntry));
7526fd ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags =·
9ee78b ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMF_ENABLEDRAGOUT;
8e6079 ¤   ¤   ¤   ¤   ¤   ¤   if (!g_bExpertMode)
cc717d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_NOVICEMODE;
a7d586 ¤   ¤   ¤   ¤   ¤   ¤   if (g_bMarginalAsInvalid)·
28876a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_MARGASINVALID;
53ce1d ¤   ¤   ¤   ¤   ¤   ¤   if (pResult->flags & FLAG_AREA_PENDING)·
9cf8ac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |= KMF_PENDINGBUCKET;
651b47 ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulDisableActions =·
6e220a ¤   ¤   ¤   ¤   ¤   ¤   ¤   KM_IMPORT|KM_PASTE|
a5e4cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   KM_SETASPRIMARY|KM_SETASDEFAULT;
e81c89 ¤   ¤   ¤   ¤   ¤   }
777f8e ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulMask = PGPKM_OPTIONS |
74c293 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPKM_KEYSERVER |
f386fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPKM_DISABLEFLAGS;
2d09f8 ¤   ¤   ¤   ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
e9af5a
4b8ca4 ¤   ¤   ¤   ¤   ¤   // display keyset
615702 ¤   ¤   ¤   ¤   ¤   PGPkmLoadKeySet (ppks->hKM, ppks->KeySetDisp,·
17350c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetMain);
d6af5a
a7c1ba ¤   ¤   ¤   ¤   ¤   // sync downloaded keyset with main and redisplay
--283d 00085f95014401102e9 Page 18 of PKMsgPrc.c
254264 ¤   ¤   ¤   ¤   ¤   PGPclSyncKeySets (g_Context, ppks->KeySetMain,·
6b4d9a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetDisp);
715702 ¤   ¤   ¤   ¤   ¤   PGPkmLoadKeySet (ppks->hKM, ppks->KeySetDisp,·
a5350c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetMain);
7caf5a
aff2d4 ¤   ¤   ¤   ¤   ¤   sDisplayKSKeyResult (ppks->KeySetDisp,·
e87ff0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.hWndStatusBar,
a0307f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pResult->error);
76af5a
a7d1ea ¤   ¤   ¤   ¤   ¤   // stop LEDs, if going
414a1c ¤   ¤   ¤   ¤   ¤   if (ppks->bSearchInProgress) {
7c55a2 ¤   ¤   ¤   ¤   ¤   ¤   KillTimer (hWnd, LEDTIMER);
ba8cda ¤   ¤   ¤   ¤   ¤   ¤   ppks->bSearchInProgress = FALSE;
d51e4a ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue = -1;
e4ccb0 ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar,·
41d29b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
e01c89 ¤   ¤   ¤   ¤   ¤   }
65af5a
59059a ¤   ¤   ¤   ¤   ¤   if (KeySetPrevious) PGPFreeKeySet (KeySetPrevious);
a5b7f6 ¤   ¤   ¤   ¤   ¤   SetCursor (hCursorOld);
f2af5a
3548ad ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->hWndSearchControl,·
f92698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SEARCH_SET_FOCUS, 0, 0);
8c14c3 ¤   ¤   ¤   ¤   ¤   break;
b52613 ¤   ¤   ¤   ¤   }
4daf5a
f9683c ¤   ¤   ¤   ¤   case SEARCH_PROGRESS :
7a72c3 ¤   ¤   ¤   ¤   {
761e34 ¤   ¤   ¤   ¤   ¤   PSEARCHPROGRESS pProgress = (PSEARCHPROGRESS)lParam;
f8af5a
8c9253 ¤   ¤   ¤   ¤   ¤   if (pProgress->total) {
a7aa8a ¤   ¤   ¤   ¤   ¤   ¤   // we're starting a query
d7375b ¤   ¤   ¤   ¤   ¤   ¤   if (!ppks->bSearchInProgress) {
34dd6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->bSearchInProgress = TRUE;
195a2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags |=·
68de2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KMF_DISABLESTATUSBAR;
298320 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->kmConfig.ulMask = PGPKM_OPTIONS;
f3cadf ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
e1af5a
f48a25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue = 0;
58b549 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pProgress->step == SEARCH_PROGRESS_INFINITE)·
bb06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
7e560c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusDirection = 1;
daea49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTimer (hWnd, LEDTIMER,·
372793 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LEDTIMERPERIOD, NULL);
975268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
5d28e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else·
cf06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
330cd0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusDirection = 0;
addf89 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue = 0;
9a5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
b680cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   // reset icon to "unlocked"
72a360 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar,·
65d25e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SB_SETTEXT,·
875371 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LOCK_PANE|SBT_OWNERDRAW|SBT_POPOUT,·
c1189c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
613f50 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // signal that we're not authenticated yet
05de00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iTLSstatus = TLS_NOTAUTHENTICATED;
aedb3c ¤   ¤   ¤   ¤   ¤   ¤   }
622863 ¤   ¤   ¤   ¤   ¤   ¤   else {
a1261e ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pProgress->step != SEARCH_PROGRESS_INFINITE)·
2a06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
c60cd0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusDirection = 0;
61fd19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue =·
3efed7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pProgress->step * 9) / pProgress->total;
50f13c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar,·
b88c82 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
8b5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
77db3c ¤   ¤   ¤   ¤   ¤   ¤   }
761c89 ¤   ¤   ¤   ¤   ¤   }
313c4b ¤   ¤   ¤   ¤   ¤   else {
855b3b ¤   ¤   ¤   ¤   ¤   ¤   if (ppks->bSearchInProgress) {
--428f 00057a999f3401102e9 Page 19 of PKMsgPrc.c
ff000e ¤   ¤   ¤   ¤   ¤   ¤   ¤   KillTimer (hWnd, LEDTIMER);
72aa6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->bSearchInProgress = FALSE;
da4d51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue = -1;
8a1c1b ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar,·
bbd29b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
72db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ca1c89 ¤   ¤   ¤   ¤   ¤   }
a9af5a
e8ba68 ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTEXT,·
b0da96 ¤   ¤   ¤   ¤   ¤   ¤   ¤   STATUS_MSG_PANE, (LPARAM)(pProgress->message));
1514c3 ¤   ¤   ¤   ¤   ¤   break;
a52613 ¤   ¤   ¤   ¤   }
23af5a
de47ce ¤   ¤   ¤   ¤   case SEARCH_SECURE_STATUS :
5c72c3 ¤   ¤   ¤   ¤   {
385224 ¤   ¤   ¤   ¤   ¤   PSEARCHSECURE¤  pSecure = (PSEARCHSECURE)lParam;
bb953c ¤   ¤   ¤   ¤   ¤   PGPKeySetRef¤   keyset;
f6544e ¤   ¤   ¤   ¤   ¤   PGPKeyListRef¤  keylist;
514648 ¤   ¤   ¤   ¤   ¤   PGPKeyIterRef¤  keyiter;
91ae30 ¤   ¤   ¤   ¤   ¤
53f52b ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTEXT,
b95371 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LOCK_PANE|SBT_OWNERDRAW|SBT_POPOUT,·
6d8c66 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)(pSecure->secure));
0aaf5a
6841a9 ¤   ¤   ¤   ¤   ¤   if (pSecure->secure) {
a6aefb ¤   ¤   ¤   ¤   ¤   ¤   ppks->iTLSstatus = TLS_AUTHENTICATED;
14af5a
9e6b11 ¤   ¤   ¤   ¤   ¤   ¤   lstrcpy (ppks->szTLSserver, pSecure->szServerName);
aeaf5a
e0d100 ¤   ¤   ¤   ¤   ¤   ¤   if (PGPKeySetRefIsValid (ppks->keysetAuth))
9c211f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (ppks->keysetAuth);
a37f57 ¤   ¤   ¤   ¤   ¤   ¤   PGPNewSingletonKeySet (pSecure->keyAuth, &keyset);
a4c1d5 ¤   ¤   ¤   ¤   ¤   ¤   PGPNewKeySet (g_Context, &ppks->keysetAuth);
8d7278 ¤   ¤   ¤   ¤   ¤   ¤   PGPAddKeys (keyset, ppks->keysetAuth);
364d35 ¤   ¤   ¤   ¤   ¤   ¤   PGPCommitKeyRingChanges (ppks->keysetAuth);
2c5dd9 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keyset);
9a67c5 ¤
22fa2f ¤   ¤   ¤   ¤   ¤   ¤   PGPOrderKeySet (ppks->keysetAuth,·
91ea72 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAnyOrdering, &keylist);
51a5b6 ¤   ¤   ¤   ¤   ¤   ¤   PGPNewKeyIter (keylist, &keyiter);
f39b24 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyIterNext (keyiter, &ppks->keyAuth);
1f4c8c ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeyIter (keyiter);
10ff21 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeyList (keylist);
661c89 ¤   ¤   ¤   ¤   ¤   }
9c96bc ¤   ¤   ¤   ¤   ¤   else·
665445 ¤   ¤   ¤   ¤   ¤   ¤   ppks->iTLSstatus = TLS_NOTAUTHENTICATED;
7767c5 ¤
2514c3 ¤   ¤   ¤   ¤   ¤   break;
5c2613 ¤   ¤   ¤   ¤   }
b6af5a
637910 ¤   ¤   ¤   ¤   case SEARCH_ABORT :
7e72c3 ¤   ¤   ¤   ¤   {
7055cd ¤   ¤   ¤   ¤   ¤   PSEARCHABORT pAbort = (PSEARCHABORT)lParam;
6708c5 ¤   ¤   ¤   ¤   ¤   CHAR sz[256];
be4a1c ¤   ¤   ¤   ¤   ¤   if (ppks->bSearchInProgress) {
9255a2 ¤   ¤   ¤   ¤   ¤   ¤   KillTimer (hWnd, LEDTIMER);
da8cda ¤   ¤   ¤   ¤   ¤   ¤   ppks->bSearchInProgress = FALSE;
571e4a ¤   ¤   ¤   ¤   ¤   ¤   ppks->iStatusValue = -1;
d1ccb0 ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar,·
e9d29b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
3e1c89 ¤   ¤   ¤   ¤   ¤   }
9b9d37 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_SEARCHABORTED,·
accac8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz, sizeof(sz));
8af52b ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->kmConfig.hWndStatusBar, SB_SETTEXT,
34813a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   STATUS_MSG_PANE, (LPARAM)sz);
7448ad ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->hWndSearchControl,·
a02698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SEARCH_SET_FOCUS, 0, 0);
5414c3 ¤   ¤   ¤   ¤   ¤   break;
812613 ¤   ¤   ¤   ¤   }
77af5a
87c737 ¤   ¤   ¤   ¤   default :
5714c3 ¤   ¤   ¤   ¤   ¤   break;
--faaa 000c50babdd401102e9 Page 20 of PKMsgPrc.c
cfa3a6 ¤   ¤   ¤   }
ccaf5a
9bece6 ¤   ¤   ¤   if (!ppks->bSearchInProgress) {
061ad5 ¤   ¤   ¤   ¤   ppks->kmConfig.ulOptionFlags &= ~KMF_DISABLESTATUSBAR;
aa0905 ¤   ¤   ¤   ¤   ppks->kmConfig.ulMask = PGPKM_OPTIONS;
f98404 ¤   ¤   ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
9ba3a6 ¤   ¤   ¤   }
870fe4 ¤   ¤   }
bdaf5a
1f7ea3 ¤   ¤   // did it come from the status bar?
d5c865 ¤   ¤   else if ((ppks->kmConfig.hWndStatusBar) &&
447131 ¤   ¤   ¤   ¤   ·(pnmh->hwndFrom == ppks->kmConfig.hWndStatusBar)) {
efd0cf ¤   ¤   ¤   if (pnmh->code == NM_CLICK) {
357f83 ¤   ¤   ¤   ¤   if (!ppks->bMainWindow) {
fb52cb ¤   ¤   ¤   ¤   ¤   POINT pt;
cfea2e ¤   ¤   ¤   ¤   ¤   GetCursorPos (&pt);
2a8294 ¤   ¤   ¤   ¤   ¤   ScreenToClient (ppks->kmConfig.hWndStatusBar, &pt);
83fa9e ¤   ¤   ¤   ¤   ¤   if (pt.x <= LOCKWIDTH) {
b6858a ¤   ¤   ¤   ¤   ¤   ¤   switch (ppks->iTLSstatus) {
70a3b8 ¤   ¤   ¤   ¤   ¤   ¤   case TLS_NOSEARCHYET :
ef2491 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PKMessageBox (hWnd, IDS_CAPTION,·
cd709d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_NOCONNECTIONYET,·
2a13d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
518c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
9daf5a
3f08a9 ¤   ¤   ¤   ¤   ¤   ¤   case TLS_NOTAUTHENTICATED :
8e2491 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PKMessageBox (hWnd, IDS_CAPTION,·
423047 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_CONNECTIONNOTAUTHENTICATED,·
8513d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONEXCLAMATION);
a38c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
d3af5a
8d94ee ¤   ¤   ¤   ¤   ¤   ¤   case TLS_AUTHENTICATED :
a60fb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclConfirmRemoteAuthentication (
949d5c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context, hWnd, ppks->szTLSserver,
64d3a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->keyAuth, ppks->KeySetMain,·
9c1bed ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_SHOWAUTHENTICATION);
f68c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
d7af5a
c7db3c ¤   ¤   ¤   ¤   ¤   ¤   }
a91c89 ¤   ¤   ¤   ¤   ¤   }
f72613 ¤   ¤   ¤   ¤   }
88a3a6 ¤   ¤   ¤   }
8b0fe4 ¤   ¤   }
e6af5a
604ce6 ¤   ¤   // else assume it's from the tooltip control of the toolbar
8d235c ¤   ¤   else if (pnmh->code == TTN_NEEDTEXT) {
521ded ¤   ¤   ¤   PKGetToolbarTooltipText ((LPTOOLTIPTEXT)lParam);
bc0fe4 ¤   ¤   }
5e0fe4 ¤   ¤   }
77af5a
5b2f68 ¤   ¤   break;
2faf5a
e385ca ¤   case WM_PAINT :
8e5b34 ¤   ¤   {
dc114c ¤   ¤   ¤   HDC¤¤   ¤   hdc;
b9f431 ¤   ¤   ¤   PAINTSTRUCT ps;
de8ce8 ¤   ¤   ¤   RECT¤   ¤   rc;
5e4b51 ¤   ¤   ¤   HPEN¤   ¤   hpenOld;
9d6b8e ¤   ¤   ¤   INT¤¤   ¤   iWidth;
dcaf5a
b5b66e ¤   ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
5caf5a
613689 ¤   ¤   ¤   hdc = BeginPaint (hWnd, &ps);
3faf5a
bb9012 ¤   ¤   ¤   if (ppks->hWndToolBar && (ppks->iToolHeight > 0)) {
5b3210 ¤   ¤   ¤   ¤   GetWindowRect (hWnd, &rc);
53c85f ¤   ¤   ¤   ¤   iWidth = rc.right-rc.left;
6caf5a
6a2a5c ¤   ¤   ¤   ¤   hpenOld = SelectObject (hdc, CreatePen (PS_SOLID, 0,·
f7ecdb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DSHADOW)));
4adf04 ¤   ¤   ¤   ¤   MoveToEx (hdc, 0, 0, NULL);
c508fa ¤   ¤   ¤   ¤   LineTo (hdc, iWidth, 0);
--5443 0002caf49e2401102e9 Page 21 of PKMsgPrc.c
e0af5a
d808f5 ¤   ¤   ¤   ¤   SelectObject (hdc, CreatePen (PS_SOLID, 0,·
331ceb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DHILIGHT)));
1df323 ¤   ¤   ¤   ¤   MoveToEx (hdc, 0, 1, NULL);
c21441 ¤   ¤   ¤   ¤   LineTo (hdc, iWidth, 1);
53af5a
c7fc74 ¤   ¤   ¤   ¤   SelectObject (hdc, hpenOld);
5aa3a6 ¤   ¤   ¤   }
1caf5a
ed5c67 ¤   ¤   ¤   EndPaint (hWnd, &ps);
a40fe4 ¤   ¤   }
bfbbde ¤   ¤   return 0;
95af5a
f85122 ¤   case WM_TIMER :
25a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
d7af5a
d5ea63 ¤   ¤   // it's time to load the keyring from disk
de8132 ¤   ¤   if (wParam == RELOADTIMERID) {
985f03 ¤   ¤   ¤   PGPBoolean UserCancel;
94af5a
9349da ¤   ¤   ¤   KillTimer (hWnd, wParam);
7daf5a
f0c881 ¤   ¤   ¤   // do the actual loading
011f17 ¤   ¤   ¤   bIgnoreReloads = TRUE;
a6f764 ¤   ¤   ¤   sReloadKeyrings (ppks, &UserCancel);
f15562 ¤   ¤   ¤   bIgnoreReloads = FALSE;
6baf5a
3bae0f ¤   ¤   ¤   // wjb if we cancel, we need to break out of here since
9dc2fd ¤   ¤   ¤   // ppks will be freed by PGPkeys WM_DESTROY routine
14287f ¤   ¤   ¤   if(UserCancel)
21f622 ¤   ¤   ¤   ¤   break;
42af5a
f81b15 ¤   ¤   ¤   // repaint window
61fa1a ¤   ¤   ¤   InvalidateRect (hWnd, NULL, FALSE);
bfaf5a
4783fb ¤   ¤   ¤   // do some first-time post-processing
39e3f7 ¤   ¤   ¤   if (bFirstKeyringLoad) {
56e26f ¤   ¤   ¤   ¤   PGPBoolean bUpdateAllKeys;
734b08 ¤   ¤   ¤   ¤   PGPBoolean bUpdateTrustedIntroducers;
edaf5a
254465 ¤   ¤   ¤   ¤   bFirstKeyringLoad = FALSE;
89af5a
0fb775 ¤   ¤   ¤   ¤   // import key files if passed from the command line
c8234c ¤   ¤   ¤   ¤   sProcessFileList (GetCommandLine (), TRUE, TRUE,
6abf29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetMain);
a5af5a
c36b85 ¤   ¤   ¤   ¤   // import keys from prefs file if available
7a413b ¤   ¤   ¤   ¤   if (IsntPGPError (sImportPrefsKeys (ppks->KeySetMain)))
ee6c9d ¤   ¤   ¤   ¤   ¤   PGPkmReLoadKeySet (ppks->hKM, FALSE);
2daf5a
bbc5a8 ¤   ¤   ¤   ¤   // display groups if groups were displayed last session
e3555c ¤   ¤   ¤   ¤   if (g_bShowGroups)·
f7c374 ¤   ¤   ¤   ¤   ¤   PostMessage (hWnd, WM_COMMAND,
faf1ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (IDM_VIEWGROUPS, 0), 0);
4aaf5a
40a9fa ¤   ¤   ¤   ¤   // check if we are to run the keygen wizard
d96d32 ¤   ¤   ¤   ¤   if (g_bKeyGenEnabled) {
4f314f ¤   ¤   ¤   ¤   ¤   PGPBoolean¤ bKeyGenerated;
782684 ¤   ¤   ¤   ¤   ¤   PGPPrefRef¤ prefref;
94af5a
970da0 ¤   ¤   ¤   ¤   ¤   PGPclOpenClientPrefs (
403940 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),·
16823f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &prefref);
a9c63d ¤   ¤   ¤   ¤   ¤   PGPGetPrefBoolean (prefref,·
084183 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefFirstKeyGenerated, &bKeyGenerated);
08ffb7 ¤   ¤   ¤   ¤   ¤   PGPclCloseClientPrefs (prefref, FALSE);
af0e73 ¤   ¤   ¤   ¤   ¤   if (!bKeyGenerated) {
663449 ¤   ¤   ¤   ¤   ¤   ¤   if (!sPKCheckForSecretKeys (ppks->KeySetMain)) {
81f680 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ShowWindow (g_hWndMain, SW_HIDE);
8ba320 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PKCreateKey (g_hWndMain, ppks->KeySetMain);
7adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
2c1c89 ¤   ¤   ¤   ¤   ¤   }
--4879 0001592d3bd401102e9 Page 22 of PKMsgPrc.c
862613 ¤   ¤   ¤   ¤   }
fdaf5a
e76be1 ¤   ¤   ¤   ¤   // see if it's time to auto-update any keys
c621c4 ¤   ¤   ¤   ¤   PGPclCheckAutoUpdate (PGPGetContextMemoryMgr (g_Context),
076028 ¤   ¤   ¤   ¤   ¤   TRUE, &bUpdateAllKeys, &bUpdateTrustedIntroducers);
8eaf5a
fefabf ¤   ¤   ¤   ¤   if (bUpdateAllKeys) {
b19230 ¤   ¤   ¤   ¤   ¤   if (PKAutoUpdateAllKeys (hWnd,·
784ac5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetMain, FALSE))
c48e9d ¤   ¤   ¤   ¤   ¤   ¤   PGPkmReLoadKeySet (ppks->hKM, FALSE);
b52613 ¤   ¤   ¤   ¤   }
beaf5a
74b302 ¤   ¤   ¤   ¤   if (bUpdateTrustedIntroducers) {
a157cb ¤   ¤   ¤   ¤   ¤   if (PKAutoUpdateIntroducers (hWnd,·
534ac5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetMain, FALSE))
014245 ¤   ¤   ¤   ¤   ¤   ¤   PGPkmReLoadKeySet (ppks->hKM, TRUE);
a02613 ¤   ¤   ¤   ¤   }
a4a3a6 ¤   ¤   ¤   }
3a0fe4 ¤   ¤   }
0107e0 ¤   ¤   else {
bb1cb1 ¤   ¤   ¤   ppks->iStatusValue += ppks->iStatusDirection;
356a65 ¤   ¤   ¤   if (ppks->iStatusValue <= 0) {
d08c52 ¤   ¤   ¤   ¤   ppks->iStatusValue = 0;
1002e6 ¤   ¤   ¤   ¤   ppks->iStatusDirection = 1;
f1a3a6 ¤   ¤   ¤   }
32158f ¤   ¤   ¤   else if (ppks->iStatusValue >= NUMLEDS-1) {
c250d9 ¤   ¤   ¤   ¤   ppks->iStatusValue = NUMLEDS-1;
e3a5f5 ¤   ¤   ¤   ¤   ppks->iStatusDirection = -1;
00a3a6 ¤   ¤   ¤   }
129d55 ¤   ¤   ¤   InvalidateRect (ppks->kmConfig.hWndStatusBar, NULL, FALSE);
5b0fe4 ¤   ¤   }
322f68 ¤   ¤   break;
fdaf5a
6a802b ¤   case KM_M_RELOADKEYRINGS :·
e9a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
8386ce ¤   ¤   if (ppks->bMainWindow) {
577143 ¤   ¤   ¤   PGPkmLoadKeySet (ppks->hKM, NULL, NULL);
3263fd ¤   ¤   ¤   if (ppks->KeySetMain) {
071754 ¤   ¤   ¤   ¤   PGPFreeKeySet (ppks->KeySetMain);
c7c8c2 ¤   ¤   ¤   ¤   ppks->KeySetMain = NULL;
d5a3a6 ¤   ¤   ¤   }
6e2638 ¤   ¤   ¤   SetTimer (hWnd, RELOADTIMERID, RELOADDELAY, NULL);
e20fe4 ¤   ¤   }
4e07e0 ¤   ¤   else {
fda7fb ¤   ¤   ¤   if (wParam) {
906335 ¤   ¤   ¤   ¤   PGPkmLoadKeySet (ppks->hKM,·
25e9c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetDisp, ppks->KeySetMain);
41a3a6 ¤   ¤   ¤   }
640fe4 ¤   ¤   }
0e2f68 ¤   ¤   break;
9faf5a
9d90ba ¤   case KM_M_CREATEDONE :
e3a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
fff0db ¤   ¤   ShowWindow (hWnd, SW_SHOW);
a69a3d ¤   ¤   EnableWindow (hWnd, TRUE);
babcaf ¤   ¤   SetForegroundWindow (hWnd);
247671 ¤   ¤   if (ppks->bGroupsFocused) SetFocus (ppks->hWndTreeListGroups);
66a4ab ¤   ¤   else SetFocus (ppks->hWndTreeList);
4f3ad5 ¤   ¤   if (wParam & KCD_NEWKEY) {
0db833 ¤   ¤   ¤   PGPPrefRef PrefRef;
d5421f ¤   ¤   ¤   PGPclOpenClientPrefs (
254f99 ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),·
aa682a ¤   ¤   ¤   ¤   ¤   &PrefRef);
7dcd1f ¤   ¤   ¤   PGPSetPrefBoolean (PrefRef, kPGPPrefFirstKeyGenerated,·
41e4ed ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (Boolean)TRUE);
9089ba ¤   ¤   ¤   PGPclCloseClientPrefs (PrefRef, TRUE);
ae3253 ¤   ¤   ¤   bKeyHasBeenGenerated = TRUE;
a58ef2 ¤   ¤   ¤   PKCommitKeyRingChanges (ppks->KeySetMain, TRUE);
4658d8 ¤   ¤   ¤   PGPkmReLoadKeySet (ppks->hKM, TRUE);
eb0ae4 ¤   ¤   ¤   if (wParam & KCD_NEWDEFKEY)·
eb7da4 ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_SETASDEFAULT);
15984b ¤   ¤   ¤   PGPkmSelectKey (ppks->hKM, (PGPKeyRef)lParam, TRUE);
--564e 000b98c347d401102e9 Page 23 of PKMsgPrc.c
b50fe4 ¤   ¤   }
43e24a ¤   ¤   InvalidateRect (hWnd, NULL, FALSE);
0a836c ¤   ¤   return TRUE;
89af5a
5484e1 ¤   case KM_M_REQUESTSDKACCESS :
26a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
77126d ¤   ¤   PGPkmSynchronizeThreadAccessToSDK (ppks->hKM);
b72f68 ¤   ¤   break;
a0af5a
f95ce0 ¤   case KM_M_KEYPROPACTION :
b9a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
08d420 ¤   ¤   PGPkmProcessKeyPropMessage (ppks->hKM, wParam, lParam);
722f68 ¤   ¤   break;
08af5a
80a2ba ¤   case KM_M_RESIZE :
e0a5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
512924 ¤   ¤   GetClientRect (hWnd, &rc);
c1242d ¤   ¤   if (ppks->hWndToolBar) {
5ea463 ¤   ¤   ¤   SetWindowPos (ppks->hWndToolBar, NULL,·
47a9b0 ¤   ¤   ¤   ¤   ¤   0, 0,·
84fde9 ¤   ¤   ¤   ¤   ¤   (rc.right-rc.left),·
4d0667 ¤   ¤   ¤   ¤   ¤   ppks->iToolHeight,·
8bdf09 ¤   ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOZORDER);
db0fe4 ¤   ¤   }
ccc904 ¤   ¤   if (ppks->hWndTreeList) {
ccc88f ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeList, NULL,·
c4b8d9 ¤   ¤   ¤   ¤   ¤   0, ppks->iToolHeight,·
1efde9 ¤   ¤   ¤   ¤   ¤   (rc.right-rc.left),·
229a77 ¤   ¤   ¤   ¤   ¤   ppks->iKeysHeight,·
793b37 ¤   ¤   ¤   ¤   ¤   SWP_NOZORDER);
ba0fe4 ¤   ¤   }
3eb29a ¤   ¤   if (ppks->hWndTreeListGroups) {
169ef6 ¤   ¤   ¤   SetWindowPos (ppks->hWndTreeListGroups, NULL,·
0411df ¤   ¤   ¤   ¤   ¤   0,·
fc0dbb ¤   ¤   ¤   ¤   ¤   (rc.bottom-rc.top)-ppks->iGroupsHeight-STATUSBARHEIGHT,
8a583e ¤   ¤   ¤   ¤   ¤   (rc.right-rc.left),
c00683 ¤   ¤   ¤   ¤   ¤   ppks->iGroupsHeight,
a83b37 ¤   ¤   ¤   ¤   ¤   SWP_NOZORDER);
140fe4 ¤   ¤   }
da033b ¤   ¤   UpdateWindow (hWnd);
572f68 ¤   ¤   break;
abaf5a
403fcf ¤   case WM_COMMAND:
7da5e2 ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
f0af5a
f9537d ¤   ¤   switch (LOWORD(wParam)) {
698bbd ¤   ¤   case IDM_FILEEXIT:
3fe50b ¤   ¤   ¤   SendMessage (hWnd, WM_CLOSE, 0, 0);
43cdcb ¤   ¤   ¤   break;
d0af5a
c2ae23 ¤   ¤   case IDM_SENDSHARES :
2babe3 ¤   ¤   ¤   PGPclSendShares (g_Context, g_TLSContext, hWnd, ppks->KeySetMain);
19cdcb ¤   ¤   ¤   break;
d4af5a
3c280e ¤   ¤   case IDM_HELPABOUT :
997616 ¤   ¤   ¤   PKHelpAbout (hWnd);
d7cdcb ¤   ¤   ¤   break;
79af5a
14157d ¤   ¤   case IDM_HELPTOPICS :
143403 ¤   ¤   ¤   WinHelp (hWnd, g_szHelpFile, HELP_FINDER, 0);
31cdcb ¤   ¤   ¤   break;
61af5a
fe0c14 ¤   ¤   case IDM_PROPERTIES :
702027 ¤   ¤   ¤   PKPGPPreferences (ppks, hWnd, 0);
b6cdcb ¤   ¤   ¤   break;
aeaf5a
994efa ¤   ¤   case IDM_CERTIFYKEY :
fd9668 ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_CERTIFY);·
2ccdcb ¤   ¤   ¤   break;
91af5a
60c916 ¤   ¤   case IDM_DISABLEKEY :
b95069 ¤   ¤   ¤   if (!ppks->bMainWindow && !ppks->bLocalKeySet &&
--3cd3 000f48a5ecf401102e9 Page 24 of PKMsgPrc.c
2db8d9 ¤   ¤   ¤   ¤   (ppks->uKeySelectionFlags == PGPKM_KEYFLAG))
31cc2f ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_DISABLEONSERVER);·
736b93 ¤   ¤   ¤   else·
a9d496 ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_DISABLE);·
93cdcb ¤   ¤   ¤   break;
8faf5a
1b2382 ¤   ¤   case IDM_ENABLEKEY :
a2a42a ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_ENABLE);·
0dcdcb ¤   ¤   ¤   break;
10af5a
e78e7a ¤   ¤   case IDM_DELETEKEY :
1cdd75 ¤   ¤   ¤   if (ppks->bGroupsFocused)·
acf6a0 ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_DELETE);·
03bb8c ¤   ¤   ¤   else
ebb0ba ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_DELETE);·
99cdcb ¤   ¤   ¤   break;
86af5a
50662b ¤   ¤   case IDM_DELETESERVER :
d91b8f ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_DELETEFROMSERVER);·
92cdcb ¤   ¤   ¤   break;
8eaf5a
b4a7aa ¤   ¤   case IDM_CREATEKEY :
c5a867 ¤   ¤   ¤   if (g_bKeyGenEnabled) {
7085d6 ¤   ¤   ¤   ¤   PKCreateKey (hWnd, ppks->KeySetMain);
1aa3a6 ¤   ¤   ¤   }
2ccdcb ¤   ¤   ¤   break;
76af5a
ed1078 ¤   ¤   case IDM_SETASDEFAULT :
a6c20c ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_SETASPRIMARY))
228f3b ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_SETASPRIMARY);·
02bb8c ¤   ¤   ¤   else
35c61f ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_SETASDEFAULT);·
d2cdcb ¤   ¤   ¤   break;
e7af5a
44191d ¤   ¤   case IDM_KEYPROPERTIES :
eb67cd ¤   ¤   ¤   if (ppks->bGroupsFocused) {
c0c523 ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_LOCATEKEYS);
58bc45 ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_PROPERTIES);·
a6a3a6 ¤   ¤   ¤   }
b06b93 ¤   ¤   ¤   else·
85bc45 ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_PROPERTIES);·
39cdcb ¤   ¤   ¤   break;
851b52 ¤   ¤
5a8ae9 ¤   ¤   case IDM_GROUPPROPERTIES :
c40cf6 ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_PROPERTIES);
fecdcb ¤   ¤   ¤   break;
e21b52 ¤   ¤
1ca454 ¤   ¤   case IDM_IMPORTKEYS :
759b06 ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_IMPORT);·
eecdcb ¤   ¤   ¤   break;
18af5a
38c4a3 ¤   ¤   case IDM_IMPORTGROUPS :
b98388 ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_IMPORTGROUPS);·
7ccdcb ¤   ¤   ¤   break;
b01b52 ¤   ¤
3d0a73 ¤   ¤   case IDM_EXPORTKEYS :
1fcf3f ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_EXPORT);·
2ccdcb ¤   ¤   ¤   break;
40af5a
ddc4c7 ¤   ¤   case IDM_GETFROMSERVER :
00ce0f ¤   ¤   ¤   if (ppks->bGroupsFocused)
ce6f36 ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_GETFROMSERVER);
12bb8c ¤   ¤   ¤   else
01fe32 ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_GETFROMSERVER);
a8cdcb ¤   ¤   ¤   break;
11af5a
1868ce ¤   ¤   case IDM_ADDTOMAIN :
e2864a ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_ADDTOMAIN);
90cdcb ¤   ¤   ¤   break;
0daf5a
e2d566 ¤   ¤   case IDM_EXPANDSEL :
f467cd ¤   ¤   ¤   if (ppks->bGroupsFocused) {
--8ea5 00075ec5fb1401102e9 Page 25 of PKMsgPrc.c
2555c6 ¤   ¤   ¤   ¤   if (PGPgmIsActionEnabled (ppks->hGM, GM_EXPANDSEL))
2f882c ¤   ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_EXPANDSEL);·
b0fa07 ¤   ¤   ¤   ¤   else
fc2f2d ¤   ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_EXPANDALL);·
08a3a6 ¤   ¤   ¤   }
47e543 ¤   ¤   ¤   else {
f5aa22 ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_EXPANDSEL))
2a6c75 ¤   ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_EXPANDSEL);·
d5fa07 ¤   ¤   ¤   ¤   else
23cb74 ¤   ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_EXPANDALL);·
52a3a6 ¤   ¤   ¤   }
1ecdcb ¤   ¤   ¤   break;
66af5a
2f4112 ¤   ¤   case IDM_COLLAPSESEL :
c567cd ¤   ¤   ¤   if (ppks->bGroupsFocused) {
60fe0a ¤   ¤   ¤   ¤   if (PGPgmIsActionEnabled (ppks->hGM, GM_COLLAPSESEL))
0872bb ¤   ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_COLLAPSESEL);·
d2fa07 ¤   ¤   ¤   ¤   else
54d5ba ¤   ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_COLLAPSEALL);·
8da3a6 ¤   ¤   ¤   }
1ae543 ¤   ¤   ¤   else {
5d7f8b ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_COLLAPSESEL))
b5d77e ¤   ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_COLLAPSESEL);·
53fa07 ¤   ¤   ¤   ¤   else
0e707f ¤   ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_COLLAPSEALL);·
dca3a6 ¤   ¤   ¤   }
4acdcb ¤   ¤   ¤   break;
7aaf5a
5021cc ¤   ¤   case IDM_SELECTALL :
8cdd75 ¤   ¤   ¤   if (ppks->bGroupsFocused)·
640f74 ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_SELECTALL);·
61bb8c ¤   ¤   ¤   else
11eb2d ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_SELECTALL);·
4df2f7 ¤   ¤   ¤   PKSetToolbarButtonStates (ppks);
4ccdcb ¤   ¤   ¤   break;
13af5a
0d71a0 ¤   ¤   case IDM_REVOKEKEY :
40eea8 ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_REVOKE);·
7ccdcb ¤   ¤   ¤   break;
71af5a
e006de ¤   ¤   case IDM_COPYKEY :
88026a ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_COPY);·
e5cdcb ¤   ¤   ¤   break;
cfaf5a
1b6de0 ¤   ¤   case IDM_PASTEKEY :
e7dd75 ¤   ¤   ¤   if (ppks->bGroupsFocused)·
37d119 ¤   ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_PASTE);·
be6b93 ¤   ¤   ¤   else·
e5ef1d ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_PASTE);·
aacdcb ¤   ¤   ¤   break;
51af5a
8309a6 ¤   ¤   case IDM_ADDUSERID :
3727bb ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_ADDUSERID);·
8ecdcb ¤   ¤   ¤   break;
e8af5a
3b1458 ¤   ¤   case IDM_ADDPHOTOID :
1bf029 ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_ADDPHOTOID);·
26cdcb ¤   ¤   ¤   break;
b7af5a
fd9a53 ¤   ¤   case IDM_ADDREVOKER :
da4e74 ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_ADDREVOKER);·
2dcdcb ¤   ¤   ¤   break;
b1af5a
5bcf23 ¤   ¤   case IDM_SPLITKEY :
41fee7 ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_SPLITKEY);·
cccdcb ¤   ¤   ¤   break;
f0af5a
9bb9ca ¤   ¤   case IDM_REVERIFY :
809cbe ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_REVERIFYSIGS);
99cdcb ¤   ¤   ¤   break;
ceaf5a
75d3ab ¤   ¤   case IDM_VIEWVALIDITY :
--8f6d 0007331cb7a401102e9 Page 26 of PKMsgPrc.c
77c8ac ¤   ¤   ¤   ulColumns ^= KM_VALIDITY;
5144ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
facdcb ¤   ¤   ¤   break;
93af5a
c14f9e ¤   ¤   case IDM_VIEWSIZE :
f20a67 ¤   ¤   ¤   ulColumns ^= KM_SIZE;
6344ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
fbcdcb ¤   ¤   ¤   break;
32af5a
b91645 ¤   ¤   case IDM_VIEWDESC :
693708 ¤   ¤   ¤   ulColumns ^= KM_DESCRIPTION;
de44ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
f2cdcb ¤   ¤   ¤   break;
59af5a
77c5b4 ¤   ¤   case IDM_VIEWKEYID :
d10da5 ¤   ¤   ¤   ulColumns ^= KM_KEYID;
0f44ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
59cdcb ¤   ¤   ¤   break;
91af5a
535712 ¤   ¤   case IDM_VIEWTRUST :
931253 ¤   ¤   ¤   ulColumns ^= KM_TRUST;
4144ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
85cdcb ¤   ¤   ¤   break;
04af5a
47c27f ¤   ¤   case IDM_VIEWCREATION :
b595ad ¤   ¤   ¤   ulColumns ^= KM_CREATION;
3744ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
f3cdcb ¤   ¤   ¤   break;
daaf5a
2cb115 ¤   ¤   case IDM_VIEWEXPIRATION :
6bd13f ¤   ¤   ¤   ulColumns ^= KM_EXPIRATION;
c844ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
1ccdcb ¤   ¤   ¤   break;
7eaf5a
517e8d ¤   ¤   case IDM_VIEWADK :
b28b70 ¤   ¤   ¤   ulColumns ^= KM_ADK;
0d44ef ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, TRUE);
b6cdcb ¤   ¤   ¤   break;
d1af5a
92bb83 ¤   ¤   case IDM_VIEWTOOLBAR :
3ce6b5 ¤   ¤   ¤   if (ppks->iToolHeight == 0)·
0c52a9 ¤   ¤   ¤   ¤   ppks->iToolHeight = DEFAULTTOOLHEIGHT;
a56b93 ¤   ¤   ¤   else·
590cde ¤   ¤   ¤   ¤   ppks->iToolHeight = 0;
b068d7 ¤   ¤   ¤   GetClientRect (hWnd, &rc);
0df2c9 ¤   ¤   ¤   ppks->iKeysHeight =·
be18d3 ¤   ¤   ¤   ¤   ¤   (rc.bottom-rc.top)-ppks->iToolHeight-STATUSBARHEIGHT;
82a1a8 ¤   ¤   ¤   if (ppks->iGroupsHeight)
5c439c ¤   ¤   ¤   ¤   ppks->iKeysHeight -= (ppks->iGroupsHeight + GRABBARHEIGHT);
db647a ¤   ¤   ¤   PostMessage (hWnd, KM_M_RESIZE, 0, 0);
dacdcb ¤   ¤   ¤   break;
e6af5a
aece89 ¤   ¤   case IDM_FINDKEY :
f9c5c1 ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_LOCATEKEYS);
0abb8d ¤   ¤   ¤   ppks->bGroupsFocused = FALSE;
fe981c ¤   ¤   ¤   SetFocus (ppks->hWndTreeList);
9ccdcb ¤   ¤   ¤   break;
e1af5a
9c6ae1 ¤   ¤   case IDM_UPDATEINTRODUCERS :
1718d1 ¤   ¤   ¤   if (PKAutoUpdateIntroducers (hWnd, ppks->KeySetMain, FALSE))
dd0bc3 ¤   ¤   ¤   ¤   PGPkmReLoadKeySet (ppks->hKM, TRUE);
3bcdcb ¤   ¤   ¤   break;
0baf5a
77e51c ¤   ¤   case IDM_UPDATEGROUPLISTS :
c692dd ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_UPDATEALLGROUPS);·
82cdcb ¤   ¤   ¤   break;
c7af5a
0d4a1b ¤   ¤   case IDM_SENDGROUPLISTS :
82ccf9 ¤   ¤   ¤   PGPgmPerformAction (ppks->hGM, GM_SENDALLGROUPS);·
7fcdcb ¤   ¤   ¤   break;
beaf5a
7324f7 ¤   ¤   case IDM_NEWGROUP :
--4a6b 000b5a8a5e3401102e9 Page 27 of PKMsgPrc.c
f0682b ¤   ¤   ¤   PGPgmNewGroup (ppks->hGM);
1fcdcb ¤   ¤   ¤   break;
06af5a
17e3bc ¤   ¤   case IDM_VIEWGROUPS :
0365ff ¤   ¤   ¤   if (ppks->bGroupsVisible) {
3a5b46 ¤   ¤   ¤   ¤   ppks->bGroupsVisible = FALSE;
7227ee ¤   ¤   ¤   ¤   CheckMenuItem (ppks->hMenuKeyMan, IDM_VIEWGROUPS,·
37bf1b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_UNCHECKED);
15f996 ¤   ¤   ¤   ¤   ppks->iGroupsHeight = 0;
58669b ¤   ¤   ¤   ¤   GetClientRect (hWnd, &rc);
d5cfa1 ¤   ¤   ¤   ¤   ppks->iKeysHeight =·
0318d3 ¤   ¤   ¤   ¤   ¤   (rc.bottom-rc.top)-ppks->iToolHeight-STATUSBARHEIGHT;
6d755d ¤   ¤   ¤   ¤   PostMessage (hWnd, KM_M_RESIZE, 0, 0);
e9a3a6 ¤   ¤   ¤   }
2ee543 ¤   ¤   ¤   else {
254bf9 ¤   ¤   ¤   ¤   ppks->bGroupsVisible = TRUE;
111196 ¤   ¤   ¤   ¤   PGPgmReLoadGroups (ppks->hGM);
c6d98f ¤   ¤   ¤   ¤   CheckMenuItem (ppks->hMenuKeyMan, IDM_VIEWGROUPS, MF_CHECKED);
68669b ¤   ¤   ¤   ¤   GetClientRect (hWnd, &rc);
14887d ¤   ¤   ¤   ¤   ppks->iGroupsHeight =·
8aaa29 ¤   ¤   ¤   ¤   ¤   (rc.bottom-rc.top) * ppks->iGroupsPercent;
fcda9b ¤   ¤   ¤   ¤   ppks->iGroupsHeight /= 100;
d8cfa1 ¤   ¤   ¤   ¤   ppks->iKeysHeight =·
b5d992 ¤   ¤   ¤   ¤   ¤   (rc.bottom-rc.top)-ppks->iToolHeight-STATUSBARHEIGHT-
9eb979 ¤   ¤   ¤   ¤   ¤   ppks->iGroupsHeight-GRABBARHEIGHT;
7e755d ¤   ¤   ¤   ¤   PostMessage (hWnd, KM_M_RESIZE, 0, 0);
75a3a6 ¤   ¤   ¤   }
a3cdcb ¤   ¤   ¤   break;
78af5a
aca419 ¤   ¤   case IDM_SEARCH :
2bf776 ¤   ¤   ¤   {
f91d64 ¤   ¤   ¤   ¤   RECT¤   rc;
dd7c7e ¤   ¤   ¤   ¤   INT¤¤   iHeight, iWidth;
b6816c ¤   ¤   ¤   ¤   CHAR¤   sz[64];
385e8c ¤   ¤   ¤   ¤   ULONG¤  ulColumns;
d9af5a
055903 ¤   ¤   ¤   ¤   // if main window has not finished initializing, then ignore
28b13f ¤   ¤   ¤   ¤   if (!ppks->KeySetMain)
4f14c3 ¤   ¤   ¤   ¤   ¤   break;
08af5a
0e0334 ¤   ¤   ¤   ¤   // if search window already exists, move to front
db37c3 ¤   ¤   ¤   ¤   if (hwndOpenSearch) {
bdd08a ¤   ¤   ¤   ¤   ¤   ShowWindow (hwndOpenSearch, SW_RESTORE);
a207a9 ¤   ¤   ¤   ¤   ¤   SetForegroundWindow (hwndOpenSearch);
5414c3 ¤   ¤   ¤   ¤   ¤   break;
212613 ¤   ¤   ¤   ¤   }
38af5a
bc9201 ¤   ¤   ¤   ¤   // save column info of main window
c36243 ¤   ¤   ¤   ¤   PGPkmGetSelectedColumns (ppks->hKM, &ulColumns);
d038d2 ¤   ¤   ¤   ¤   PGPkmSelectColumns (ppks->hKM, ulColumns, FALSE);
56af5a
1d63ef ¤   ¤   ¤   ¤   // create new search window
8e44f1 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_SEARCHTITLE, sz, sizeof(sz));
483210 ¤   ¤   ¤   ¤   GetWindowRect (hWnd, &rc);
eae944 ¤   ¤   ¤   ¤   iWidth = rc.right - rc.left;
c18664 ¤   ¤   ¤   ¤   if (iWidth < MINSEARCHWINDOWWIDTH)
374869 ¤   ¤   ¤   ¤   ¤   iWidth = MINSEARCHWINDOWWIDTH;
1db48f ¤   ¤   ¤   ¤   iHeight = ((rc.bottom-rc.top)*3)>>2;
c4d356 ¤   ¤   ¤   ¤   if (iHeight < MINSEARCHWINDOWHEIGHT)·
ad9736 ¤   ¤   ¤   ¤   ¤   iHeight = MINSEARCHWINDOWHEIGHT;
b8a950 ¤   ¤   ¤   ¤   if (rc.left+60+iWidth > GetSystemMetrics (SM_CXSCREEN))
1ee5d2 ¤   ¤   ¤   ¤   ¤   rc.left = GetSystemMetrics (SM_CXSCREEN) - iWidth - 60;
d9a73e ¤   ¤   ¤   ¤   CreateWindow (WINCLASSNAME, sz,·
bdaf68 ¤   ¤   ¤   ¤   ¤   WS_OVERLAPPEDWINDOW|WS_VISIBLE, rc.left+60,·
1202a6 ¤   ¤   ¤   ¤   ¤   rc.top+60, iWidth,
e52f25 ¤   ¤   ¤   ¤   ¤   iHeight, NULL, NULL, g_hInst,·
006e47 ¤   ¤   ¤   ¤   ¤   (LPVOID)(ppks->KeySetMain));
d0a3a6 ¤   ¤   ¤   }
55cdcb ¤   ¤   ¤   break;
85af5a
2b8f4a ¤   ¤   case IDM_DOMAINKEYSERVER :
b54489 ¤   ¤   ¤   SendMessage (hWnd, WM_COMMAND, IDM_DOMAINKEYSERVERX, 0);
--d8fb 000154678fb401102e9 Page 28 of PKMsgPrc.c
7ecdcb ¤   ¤   ¤   break;
f8af5a
5cbd5b ¤   ¤   case IDM_DOMAINKEYSERVERX :
b59213 ¤   ¤   ¤   ZeroMemory (&ppks->kmConfig.keyserver, sizeof(PGPKeyServerEntry));
d61cbe ¤   ¤   ¤   ppks->kmConfig.ulMask = PGPKM_KEYSERVER;
3484e6 ¤   ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
2f3c95 ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_SENDTOSERVER);
81cdcb ¤   ¤   ¤   break;
98af5a
2e0551 ¤   ¤   case IDM_TOOLBARSENDTOSERVER :
04ff47 ¤   ¤   ¤   PKGetSendToServerButtonRect (ppks->hWndToolBar, &rc);
e845fb ¤   ¤   ¤   MapWindowPoints (ppks->hWndMain, NULL, (LPPOINT)&rc, 2);
169d1f ¤   ¤   ¤   PKToolbarKeyserverMenu (hWnd, &rc);
e2cdcb ¤   ¤   ¤   break;
5faf5a
ce3a18 ¤   ¤   default :
32f4a9 ¤   ¤   ¤   if (LOWORD (wParam) > IDM_DOMAINKEYSERVERX) {
080569 ¤   ¤   ¤   ¤   PKGetServerFromID (LOWORD (wParam),
96d8f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ppks->kmConfig.keyserver);
9d738d ¤   ¤   ¤   ¤   ppks->kmConfig.ulMask = PGPKM_KEYSERVER;
998404 ¤   ¤   ¤   ¤   PGPkmConfigure (ppks->hKM, &(ppks->kmConfig));
0de6bc ¤   ¤   ¤   ¤   PGPkmPerformAction (ppks->hKM, KM_SENDTOSERVER);
66a3a6 ¤   ¤   ¤   }
3dcdcb ¤   ¤   ¤   break;
940fe4 ¤   ¤   }
c12f68 ¤   ¤   break;
54af5a
0ebfad ¤   default :
fcdd0d ¤   ¤   // check for mousewheel message
4a2f16 ¤   ¤   if (uMsg == g_uMouseWheelMessage) {
96a20e ¤   ¤   ¤   WORD iDelta;
c7af5a
37b66e ¤   ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
07de65 ¤   ¤   ¤   iDelta = (WORD)wParam;
5f87c7 ¤   ¤   ¤
ccce0f ¤   ¤   ¤   if (ppks->bGroupsFocused)
214c77 ¤   ¤   ¤   ¤   SendMessage (ppks->hWndTreeListGroups,·
85e614 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_MOUSEWHEEL, MAKEWPARAM (0, iDelta), 0);
64bb8c ¤   ¤   ¤   else
ae5e52 ¤   ¤   ¤   ¤   SendMessage (ppks->hWndTreeList,·
98e614 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_MOUSEWHEEL, MAKEWPARAM (0, iDelta), 0);
915f1f ¤   ¤   ¤   return FALSE;
d50fe4 ¤   ¤   }
dbaf5a
4e97ff ¤   ¤   // check for prefs broadcast message
d79d61 ¤   ¤   else if (uMsg == g_uReloadPrefsMessage) {
9bb66e ¤   ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
669f41 ¤   ¤   ¤   PKReloadPGPPreferences (ppks);
e80fe4 ¤   ¤   }
73af5a
50878a ¤   ¤   // check for keyring broadcast message
5a3014 ¤   ¤   else if (uMsg == g_uReloadKeyringMessage) {
18b66e ¤   ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
c90ed0 ¤   ¤   ¤   if (ppks->kmConfig.ulOptionFlags & KMF_ENABLERELOADS) {
4dbe4b ¤   ¤   ¤   ¤   if (ppks->bMainWindow) {
92b2a3 ¤   ¤   ¤   ¤   ¤   if ((DWORD)lParam != GetCurrentProcessId ()) {
cac88c ¤   ¤   ¤   ¤   ¤   ¤   if (!bIgnoreReloads)
bca48e ¤   ¤   ¤   ¤   ¤   ¤   ¤   PostMessage (hWnd, KM_M_RELOADKEYRINGS, 0, 0);
001c89 ¤   ¤   ¤   ¤   ¤   }
fc3c4b ¤   ¤   ¤   ¤   ¤   else {
30efbd ¤   ¤   ¤   ¤   ¤   ¤   if (LOWORD (wParam) != LOWORD (hWnd)) {
5ad6e4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (HIWORD (wParam))
631229 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmReLoadKeySet (ppks->hKM, TRUE);
4b28e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else·
698c68 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPkmLoadKeySet (ppks->hKM, ppks->KeySetMain,·
e22680 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetMain);
54db3c ¤   ¤   ¤   ¤   ¤   ¤   }
44bc09 ¤   ¤   ¤   ¤   ¤   ¤   if (ppks->bGroupsVisible)
79df38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPgmReLoadGroups (ppks->hGM);
981c89 ¤   ¤   ¤   ¤   ¤   }
d12613 ¤   ¤   ¤   ¤   }
15deaa ¤   ¤   ¤   ¤   else {
--2eb3 00140fb2e55401102e9 Page 29 of PKMsgPrc.c
074178 ¤   ¤   ¤   ¤   ¤   if (((DWORD)lParam != GetCurrentProcessId ()) ||
910e5a ¤   ¤   ¤   ¤   ¤   ¤   (LOWORD (wParam) != LOWORD (hWnd))) {
068baa ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetDisp = NULL;
0d448e ¤   ¤   ¤   ¤   ¤   ¤   PGPkmLoadKeySet (ppks->hKM, ppks->KeySetDisp,·
7a2680 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ppks->KeySetMain);
a2484f ¤   ¤   ¤   ¤   ¤   ¤   SendMessage (ppks->hWndSearchControl,·
12beba ¤   ¤   ¤   ¤   ¤   ¤   ¤   SEARCH_SET_CURRENT_SEARCH, 0, 0);
141c89 ¤   ¤   ¤   ¤   ¤   }
442613 ¤   ¤   ¤   ¤   }
62a3a6 ¤   ¤   ¤   }
6032bd ¤   ¤   ¤   return TRUE;
440fe4 ¤   ¤   }
21af5a
96f8e0 ¤   ¤   // check for keyserver prefs broadcast message
e81674 ¤   ¤   else if (uMsg == g_uReloadKeyserverPrefsMessage) {
6eb66e ¤   ¤   ¤   ppks = (PGPKEYSSTRUCT*)GetWindowLong (hWnd, GWL_USERDATA);
03436d ¤   ¤   ¤   if (!ppks->bMainWindow) {
aa133a ¤   ¤   ¤   ¤   NMHDR nmhdr;
b2af5a
d303ad ¤   ¤   ¤   ¤   nmhdr.hwndFrom = hWnd;
2d3f9e ¤   ¤   ¤   ¤   nmhdr.idFrom = 0;
66fb58 ¤   ¤   ¤   ¤   nmhdr.code = REFRESH_KEYSERVER_LIST;
b4af5a
9c4f96 ¤   ¤   ¤   ¤   SendMessage (ppks->hWndSearchControl,·
894337 ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
1f11df ¤   ¤   ¤   ¤   ¤   0,·
415b26 ¤   ¤   ¤   ¤   ¤   (LPARAM)&nmhdr);
61a3a6 ¤   ¤   ¤   }
0c32bd ¤   ¤   ¤   return TRUE;
280fe4 ¤   ¤   }
62af5a
87b0a4 ¤   ¤   // check for purge passphrase cache broadcast message
702427 ¤   ¤   else if (uMsg == g_uPurgePassphraseCacheMessage) {
0b3109 ¤   ¤   ¤   PGPclPurgeCachedPassphrase (wParam);
e132bd ¤   ¤   ¤   return TRUE;
980fe4 ¤   ¤   }
0eaf5a
07f6fe ¤   ¤   else return (DefWindowProc (hWnd, uMsg, wParam, lParam));
f49371 ¤   }
f4a230 ¤   return FALSE;
24efe6 }
40af5a
--7115 000c2fa3740401102ea Page 1 of PKTool.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
8a6e44 ¤   PKTool.c - toolbar routines
7767c5 ¤
b6af5a
d9f888 ¤   $Id: PKTool.c,v 1.10 1998/08/11 15:20:11 pbj Exp $
96f7f7 ____________________________________________________________________________*/
5b2194 #include "pgpPFLConfig.h"¤  /* or pgpConfig.h in the CDK */
46af5a
0ac917 // project header files
d8c55a #include "pgpkeysx.h"
6daf5a
f75584 // constant definitions
4d9e5b #define BITMAP_CX¤  ¤   ¤   16
acd671 #define BITMAP_CY¤  ¤   ¤   16
3aaf5a
3fee05 #define IDX_TBNEWKEY¤   ¤   0
172df2 #define IDX_SEPARATOR1¤ ¤   1
f0c959 #define IDX_TBREVOKKEY¤ ¤   2
8f3207 #define IDX_TBSIGNKEY¤  ¤   3
e844ab #define IDX_TBDELETE¤   ¤   4
529c95 #define IDX_SEPARATOR2¤ ¤   5
4d645d #define IDX_TBSEARCH¤   ¤   6
199b17 #define IDX_TBSENDKEY¤  ¤   7
75a584 #define IDX_TBUPDATEKEY¤¤   8
c3f786 #define IDX_TBPROPERTIES¤   9
d06876 #define IDX_SEPARATOR3¤ ¤   10
401b04 #define IDX_TBIMPORT¤   ¤   11
68f6d2 #define IDX_TBEXPORT¤   ¤   12
92b195 #define NUM_TBBUTTONS¤  ¤   13
eaaf5a
19492e // local globals
7c9223 static BOOL bIsSeparator[NUM_TBBUTTONS] = {0,1,0,0,0,1,0,0,0,0,1,0,0};
bcaf5a
3a3fb5 // external global variables
85a009 extern HINSTANCE¤   g_hInst;
c52cdf extern HWND¤¤   ¤   g_hWndMain;
c32682 extern BOOL¤¤   ¤   g_bReadOnly;
064809 extern BOOL¤¤   ¤   g_bKeyGenEnabled;
85af5a
cec509 //¤ ____________________________________
a9465d //
7cd2d0 //¤ Create new toolbar for main window
10af5a
558104 HWND
a4df70 PKCreateToolbar (HWND hwndParent)
efbb36 {
3d9d7f ¤   HWND¤   ¤   hwndToolbar;
a4f897 ¤   HIMAGELIST¤ himl;
fb1490 ¤   TBBUTTON¤   tbArray[NUM_TBBUTTONS];
1e94c0 ¤   HDC¤¤   ¤   hdc;
3e8136 ¤   INT¤¤   ¤   i, iNumBits, iBitmap;
a29402 ¤   HBITMAP¤¤   hbmp;
43af5a
def74e ¤   // create the toolbar control.
a5af7c ¤   hwndToolbar = CreateWindowEx(
0090ca ¤   ¤   ¤   ¤   ¤   WS_EX_TOOLWINDOW,
07b677 ¤   ¤   ¤   ¤   ¤   TOOLBARCLASSNAME,
4a2797 ¤   ¤   ¤   ¤   ¤   NULL,
2375e3 ¤   ¤   ¤   ¤   ¤   WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN |·
509529 ¤   ¤   ¤   ¤   ¤   WS_CLIPSIBLINGS | CCS_NODIVIDER |
cca2ba ¤   ¤   ¤   ¤   ¤   CCS_NOPARENTALIGN | CCS_NORESIZE |·
ca46e4 ¤   ¤   ¤   ¤   ¤   TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,·
2ab11c ¤   ¤   ¤   ¤   ¤   TOOLBARXOFFSET,TOOLBARYOFFSET,0,0,·
cc28c8 ¤   ¤   ¤   ¤   ¤   hwndParent, (HMENU)IDC_TOOLBAR,
6c5934 ¤   ¤   ¤   ¤   ¤   g_hInst, NULL);·
dbaf5a
d5af5a
bd27d1 ¤   // sets the size of the TBBUTTON structure.
c2900f ¤   SendMessage (hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
--bf04 0008f5f4812401102ea Page 2 of PKTool.c
e0af5a
bbef40 ¤   // set the bitmap size.
20b88f ¤   SendMessage¤(hwndToolbar, TB_SETBITMAPSIZE,
8fc00e ¤   ¤   ¤   ···0, (LPARAM)MAKELONG (BITMAP_CX, BITMAP_CY));
b6af5a
57d2fe ¤   // set the button size.
0be573 ¤   SendMessage¤(hwndToolbar, TB_SETBUTTONSIZE,
25a557 ¤   ¤   ¤   ···0, (LPARAM)MAKELONG (BITMAP_CX+8, BITMAP_CY+2));
f6af5a
cfe96a ¤   // get imagelist on basis of display capabilities
95f3cc ¤   hdc = GetDC (NULL);¤¤   // DC for desktop
c78529 ¤   iNumBits = GetDeviceCaps (hdc, BITSPIXEL) * GetDeviceCaps (hdc, PLANES);
e10951 ¤   ReleaseDC (NULL, hdc);
33af5a
ae2be4 ¤   if (iNumBits <= 8) {
19f990 ¤   ¤   himl = ImageList_Create (BITMAP_CX, BITMAP_CY, ILC_COLOR|ILC_MASK,·
3eb165 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_TBBUTTONS, 0);·
4f5c8c ¤   ¤   hbmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_TOOLBAR4BIT));
6d154b ¤   ¤   ImageList_AddMasked (himl, hbmp, RGB(255, 0, 255));
81d9ed ¤   ¤   DeleteObject (hbmp);
729371 ¤   }
07665a ¤   else {
18d471 ¤   ¤   himl = ImageList_Create (BITMAP_CX, BITMAP_CY, ILC_COLOR24|ILC_MASK,·
91b165 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NUM_TBBUTTONS, 0);·
172788 ¤   ¤   hbmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_TOOLBAR24BIT));
f7154b ¤   ¤   ImageList_AddMasked (himl, hbmp, RGB(255, 0, 255));
dcd9ed ¤   ¤   DeleteObject (hbmp);
1e9371 ¤   }
8b0791 ¤   SendMessage (hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl);
4ee8c6 ···
d2f6c6 ¤   // Loop to fill the array of TBBUTTON structures.
a8c1d8 ¤   iBitmap = 0;
232c7a ¤   for (i=0; i<NUM_TBBUTTONS; i++) {
83fd4b ¤   ¤   tbArray[i].iBitmap ··= iBitmap;
e1a2e3 ¤   ¤   tbArray[i].idCommand = 0;
323021 ¤   ¤   tbArray[i].fsStyle ··= TBSTYLE_BUTTON;
4f67cb ¤   ¤   tbArray[i].dwData ···= 0;
124502 ¤   ¤   tbArray[i].iString ··= iBitmap;
6f7f36 ¤   ¤   if (bIsSeparator[i]) {
c62894 ¤   ¤   ¤   tbArray[i].fsState = 0;
8896d7 ¤   ¤   ¤   tbArray[i].fsStyle = TBSTYLE_SEP;
420fe4 ¤   ¤   }
6607e0 ¤   ¤   else {
c7a132 ¤   ¤   ¤   tbArray[i].fsState = TBSTATE_ENABLED;
ac69b7 ¤   ¤   ¤   tbArray[i].fsStyle = TBSTYLE_BUTTON;
a34e93 ¤   ¤   ¤   iBitmap++;
d60fe4 ¤   ¤   }
2b9371 ¤   }
21af5a
246f31 ¤   tbArray[IDX_TBNEWKEY].idCommand¤¤   = IDM_CREATEKEY;
e921c8 ¤   tbArray[IDX_TBREVOKKEY].idCommand¤  = IDM_REVOKEKEY;
5360e1 ¤   tbArray[IDX_TBSIGNKEY].idCommand¤   = IDM_CERTIFYKEY;
696f3e ¤   tbArray[IDX_TBDELETE].idCommand¤¤   = IDM_DELETEKEY;
716517 ¤   tbArray[IDX_TBSEARCH].idCommand¤¤   = IDM_SEARCH;
e54ce7 ¤   tbArray[IDX_TBUPDATEKEY].idCommand¤ = IDM_GETFROMSERVER;
00c795 ¤   tbArray[IDX_TBSENDKEY].idCommand¤   = IDM_TOOLBARSENDTOSERVER;
253ad9 ¤   tbArray[IDX_TBPROPERTIES].idCommand¤= IDM_KEYPROPERTIES;
dd6575 ¤   tbArray[IDX_TBIMPORT].idCommand¤¤   = IDM_IMPORTKEYS;
8cbeb5 ¤   tbArray[IDX_TBEXPORT].idCommand¤¤   = IDM_EXPORTKEYS;
d1af5a
7f9343 ¤   // add the buttons
48aed3 ¤   SendMessage (hwndToolbar,
38aa07 ¤   ¤   ¤   ···TB_ADDBUTTONS, (UINT)NUM_TBBUTTONS, (LPARAM)tbArray);
88af5a
a0f6ac ¤   return hwndToolbar;
acefe6 }
ebaf5a
4fc509 //¤ ____________________________________
c7465d //
94a72c //¤ destroy toolbar
1baf5a
8ffe80 VOID
--7225 000f1ea4849401102ea Page 3 of PKTool.c
2c47e8 PKDestroyToolbar (HWND hwndToolbar) {
2eaf5a
81f897 ¤   HIMAGELIST¤ himl;
9daf5a
103936 ¤   himl = (HIMAGELIST)SendMessage (hwndToolbar, TB_GETIMAGELIST, 0, 0);
f71592 ¤   if (himl)
a21fbb ¤   ¤   ImageList_Destroy (himl);
99af5a
49efe6 }
7baf5a
aec509 //¤ ____________________________________
f7465d //
bea9ef //¤ get rect of send to server button
eeaf5a
16fe80 VOID
207c7d PKGetSendToServerButtonRect (HWND hwndToolbar, LPRECT lprect) {
3caf5a
5ec1f4 ¤   SendMessage (hwndToolbar,·
493a23 ¤   ¤   ¤   TB_GETITEMRECT, IDX_TBSENDKEY, (LPARAM)lprect);
bfefe6 }
88af5a
d7c509 //¤ ____________________________________
ae465d //
ec224a //¤ get toolbar tooltip text
f7af5a
acfe80 VOID
a422b7 PKGetToolbarTooltipText (LPTOOLTIPTEXT lpttt) {
0daf5a
5b2c6b ¤   lpttt->hinst = g_hInst;·
a1af5a
13be62 ¤   // Specify the resource identifier of the descriptive·
3aaaa0 ¤   // text for the given button.·
6c2f31 ¤   switch (lpttt->hdr.idFrom) {·
e16df1 ¤   ¤   case IDM_CREATEKEY:·
af6749 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPNEWKEY);·
625d5e ¤   ¤   ¤   break;·
85bbfb ¤   ¤   case IDM_REVOKEKEY:·
1c78b5 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPREVOKE);·
495d5e ¤   ¤   ¤   break;·
d784a1 ¤   ¤   case IDM_CERTIFYKEY:·
b561a2 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPSIGN);·
255d5e ¤   ¤   ¤   break;·
ea4421 ¤   ¤   case IDM_DELETEKEY:·
8da9f0 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPDELETE);·
4c5d5e ¤   ¤   ¤   break;·
346e42 ¤   ¤   case IDM_SEARCH:·
20554e ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPSEARCH);·
ad5d5e ¤   ¤   ¤   break;·
27cf0a ¤   ¤   case IDM_TOOLBARSENDTOSERVER:·
ca94b6 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPSENDTOSERVER);·
a65d5e ¤   ¤   ¤   break;·
7c0e9c ¤   ¤   case IDM_GETFROMSERVER:·
2b98c3 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPUPDATE);·
fb5d5e ¤   ¤   ¤   break;·
34d346 ¤   ¤   case IDM_KEYPROPERTIES:·
5a6fd7 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPPROPERTIES);·
065d5e ¤   ¤   ¤   break;·
4d6e0f ¤   ¤   case IDM_IMPORTKEYS:·
9c0d1b ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPIMPORT);·
745d5e ¤   ¤   ¤   break;·
23c028 ¤   ¤   case IDM_EXPORTKEYS:·
5a5922 ¤   ¤   ¤   lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIPEXPORT);·
8c5d5e ¤   ¤   ¤   break;·
b747d1 ¤   }·
69af5a
49efe6 }
55af5a
1cc509 //¤ ____________________________________
00465d //
2b0bfb //¤ set toolbar buttons states (enabled/grayed)
69af5a
f1fe80 VOID
--a089 000758c6761401102ea Page 4 of PKTool.c
6a31b6 PKSetToolbarButtonStates (PPGPKEYSSTRUCT ppks) {
6caf5a
7a5b12 ¤   TBBUTTON¤   tbb;
3bcee1 ¤   UINT¤   ¤   uState;
412aea ¤   INT¤¤   ¤   i;
8eaf5a
48af5a
4a92f5 ¤   // groups window has focus
f42964 ¤   if (ppks->bGroupsFocused) {
981094 ¤   ¤   for (i=0; i<NUM_TBBUTTONS; i++) {
44af5a
add0e5 ¤   ¤   ¤   if (bIsSeparator[i])·
87d040 ¤   ¤   ¤   ¤   continue;
5faf5a
4a05a6 ¤   ¤   ¤   SendMessage (ppks->hWndToolBar, TB_GETBUTTON, i, (LPARAM)&tbb);
bdaf5a
0c7778 ¤   ¤   ¤   uState = TBSTATE_INDETERMINATE;
35af5a
9849f1 ¤   ¤   ¤   switch (tbb.idCommand) {
28d6a7 ¤   ¤   ¤   case IDM_CREATEKEY:·
37b434 ¤   ¤   ¤   ¤   if (!g_bReadOnly && g_bKeyGenEnabled)·
9d3f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
cc27aa ¤   ¤   ¤   ¤   break;·
3aaf5a
e000ad ¤   ¤   ¤   case IDM_REVOKEKEY:·
c127aa ¤   ¤   ¤   ¤   break;·
07af5a
7eb3a9 ¤   ¤   ¤   case IDM_CERTIFYKEY:·
9827aa ¤   ¤   ¤   ¤   break;·
56af5a
06ff77 ¤   ¤   ¤   case IDM_DELETEKEY:·
b3f385 ¤   ¤   ¤   ¤   if (PGPgmIsActionEnabled (ppks->hGM, GM_DELETE))
1c3f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
7927aa ¤   ¤   ¤   ¤   break;·
51af5a
35e716 ¤   ¤   ¤   case IDM_SEARCH:·
fa0651 ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
a6f622 ¤   ¤   ¤   ¤   break;
cf2b85 ¤   ¤   ¤   ¤
b41cd3 ¤   ¤   ¤   case IDM_TOOLBARSENDTOSERVER:
8227aa ¤   ¤   ¤   ¤   break;·
dcaf5a
9733f4 ¤   ¤   ¤   case IDM_GETFROMSERVER:·
0c27aa ¤   ¤   ¤   ¤   break;·
b6af5a
5bee2e ¤   ¤   ¤   case IDM_KEYPROPERTIES:·
07d0dc ¤   ¤   ¤   ¤   if (PGPgmIsActionEnabled (ppks->hGM, GM_LOCATEKEYS))
ea3f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
fb27aa ¤   ¤   ¤   ¤   break;·
aaaf5a
115907 ¤   ¤   ¤   case IDM_IMPORTKEYS:·
56caaf ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_IMPORT))
373f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
0127aa ¤   ¤   ¤   ¤   break;·
7eaf5a
7df720 ¤   ¤   ¤   case IDM_EXPORTKEYS:·
6527aa ¤   ¤   ¤   ¤   break;·
19a3a6 ¤   ¤   ¤   }
45af5a
f036a4 ¤   ¤   ¤   if (tbb.idCommand)
beb329 ¤   ¤   ¤   ¤   SendMessage (ppks->hWndToolBar, TB_SETSTATE, tbb.idCommand,·
d37309 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM (uState, 0));
980fe4 ¤   ¤   }
58af5a
9b9371 ¤   }
a1af5a
c5c691 ¤   // main key window has focus
b3665a ¤   else {
b9af5a
761094 ¤   ¤   for (i=0; i<NUM_TBBUTTONS; i++) {
ebaf5a
75d0e5 ¤   ¤   ¤   if (bIsSeparator[i])·
--c7f3 0018ba1f565401102ea Page 5 of PKTool.c
1bd040 ¤   ¤   ¤   ¤   continue;
e3af5a
8f05a6 ¤   ¤   ¤   SendMessage (ppks->hWndToolBar, TB_GETBUTTON, i, (LPARAM)&tbb);
e2af5a
bd7778 ¤   ¤   ¤   uState = TBSTATE_INDETERMINATE;
f6af5a
0f49f1 ¤   ¤   ¤   switch (tbb.idCommand) {
86d6a7 ¤   ¤   ¤   case IDM_CREATEKEY:·
07b434 ¤   ¤   ¤   ¤   if (!g_bReadOnly && g_bKeyGenEnabled)·
113f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
c727aa ¤   ¤   ¤   ¤   break;·
6baf5a
4900ad ¤   ¤   ¤   case IDM_REVOKEKEY:·
c5d3b9 ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_REVOKE))
ec3f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
c227aa ¤   ¤   ¤   ¤   break;·
aeaf5a
d7b3a9 ¤   ¤   ¤   case IDM_CERTIFYKEY:·
26eaa7 ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_CERTIFY))
3e3f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
ba27aa ¤   ¤   ¤   ¤   break;·
9faf5a
65ff77 ¤   ¤   ¤   case IDM_DELETEKEY:·
e1231e ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_DELETE))
ca3f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
5327aa ¤   ¤   ¤   ¤   break;·
e3af5a
1ce716 ¤   ¤   ¤   case IDM_SEARCH:·
350651 ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
91f622 ¤   ¤   ¤   ¤   break;
2b2b85 ¤   ¤   ¤   ¤
cc1cd3 ¤   ¤   ¤   case IDM_TOOLBARSENDTOSERVER:
913263 ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_SENDTOSERVER))
ba3f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
1d27aa ¤   ¤   ¤   ¤   break;·
c6af5a
1233f4 ¤   ¤   ¤   case IDM_GETFROMSERVER:·
444690 ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_GETFROMSERVER))
a63f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
5527aa ¤   ¤   ¤   ¤   break;·
84af5a
3aee2e ¤   ¤   ¤   case IDM_KEYPROPERTIES:·
44b83e ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_PROPERTIES))
b73f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
b127aa ¤   ¤   ¤   ¤   break;·
69af5a
e95907 ¤   ¤   ¤   case IDM_IMPORTKEYS:·
62caaf ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_IMPORT))
743f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
f427aa ¤   ¤   ¤   ¤   break;·
73af5a
c8f720 ¤   ¤   ¤   case IDM_EXPORTKEYS:·
934699 ¤   ¤   ¤   ¤   if (PGPkmIsActionEnabled (ppks->hKM, KM_EXPORT))
c63f94 ¤   ¤   ¤   ¤   ¤   uState = TBSTATE_ENABLED;
6827aa ¤   ¤   ¤   ¤   break;·
49a3a6 ¤   ¤   ¤   }
7daf5a
e236a4 ¤   ¤   ¤   if (tbb.idCommand)
2bb329 ¤   ¤   ¤   ¤   SendMessage (ppks->hWndToolBar, TB_SETSTATE, tbb.idCommand,·
2e7309 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKELPARAM (uState, 0));
c80fe4 ¤   ¤   }
5c9371 ¤   }
97efe6 }
1faf5a
8baf5a
--623e 00053e4069f401102eb Page 1 of PKUser.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
8dbb0e ¤   PKUser.c - miscellaneous user interface routines
4867c5 ¤
e7af5a
7140e7 ¤   $Id: PKUser.c,v 1.27.2.1 1998/10/05 21:30:32 pbj Exp $
f3f7f7 ____________________________________________________________________________*/
2d2194 #include "pgpPFLConfig.h"¤  /* or pgpConfig.h in the CDK */
c0af5a
81c917 // project header files
08c55a #include "pgpkeysx.h"
b9af5a
3dad8c // pgp header files
7791b9 #include "pgpSDKPrefs.h"
96af5a
3bfc2c // system header files
1e6bd4 #include <commdlg.h>
fdaf5a
e13fb5 // external global variables
23eec0 extern HINSTANCE¤   ¤   g_hInst;
6ccf38 extern PGPContextRef¤   g_Context;
5baf5a
02c509 //¤ ____________________________________
27465d //
15bbfe //¤ Message box routine
31465d //
168a32 //¤ iCaption and iMessage are string table resource IDs.
afaf5a
3a0218 LRESULT·
fa3472 PKMessageBox (
a147b2 ¤   ¤   HWND¤   hWnd,·
771310 ¤   ¤   INT¤¤   iCaption,·
f608ad ¤   ¤   INT¤¤   iMessage,
eb1582 ¤   ¤   ULONG¤  ulFlags)·
abbb36 {
5c01b5 ¤   CHAR szCaption [128];
053a7c ¤   CHAR szMessage [512];
0baf5a
aac237 ¤   LoadString (g_hInst, iCaption, szCaption, sizeof(szCaption));
5b7e8b ¤   LoadString (g_hInst, iMessage, szMessage, sizeof(szMessage));
2eaf5a
23897a ¤   ulFlags |= MB_SETFOREGROUND;
6a729f ¤   return (MessageBox (hWnd, szMessage, szCaption, ulFlags));
08efe6 }
5eaf5a
5bc509 //¤ ____________________________________
6c465d //
7d31de //¤ Backup warning dialog message procedure
cfaf5a
cd3f64 static BOOL CALLBACK·
345a75 sBackupWarnDlgProc(
254669 ¤   ¤   HWND¤   hWndDlg,·
e9eb77 ¤   ¤   UINT¤   uMsg,·
5217d4 ¤   ¤   WPARAM¤ wParam,·
a4c0b8 ¤   ¤   LPARAM¤ lParam)·
33bb36 {
07347f ¤   switch (uMsg) {
aeaf5a
562940 ¤   case WM_INITDIALOG:
3f836c ¤   ¤   return TRUE;
b8af5a
9f3fcf ¤   case WM_COMMAND:
deaf5a
26537d ¤   ¤   switch (LOWORD(wParam)) {
f78b09 ¤   ¤   case IDC_BACKUPNOW:
cfed4b ¤   ¤   ¤   EndDialog (hWndDlg, IDC_BACKUPNOW);
d4cdcb ¤   ¤   ¤   break;
0baf5a
af00b5 ¤   ¤   case IDC_DONTBACKUP :
5353e4 ¤   ¤   ¤   EndDialog (hWndDlg, IDC_DONTBACKUP);
--b442 00095495d97401102eb Page 2 of PKUser.c
7ecdcb ¤   ¤   ¤   break;
f8af5a
a871eb ¤   ¤   case IDCANCEL:
d57baf ¤   ¤   ¤   EndDialog (hWndDlg, IDCANCEL);
5dcdcb ¤   ¤   ¤   break;
2aaf5a
580fe4 ¤   ¤   }
b2836c ¤   ¤   return TRUE;
1c9371 ¤   }
4ea230 ¤   return FALSE;
92efe6 }
e6af5a
14c509 //¤ ____________________________________
cc465d //
d70241 //¤ Warn user of need for backup
5baf5a
c57efe BOOL·
f1cb19 PKBackupWarn (HWND hWnd, BOOL* pbBackup)·
41bb36 {
23e671 ¤   INT¤¤   iReturn;
edaf5a
86bb82 ¤   iReturn = DialogBox (g_hInst, MAKEINTRESOURCE (IDD_BACKUPWARN), hWnd,·
8712bf ¤   ¤   ¤   sBackupWarnDlgProc);·
02af5a
20ec2d ¤   if (iReturn == IDCANCEL) {
1d4f08 ¤   ¤   *pbBackup = FALSE;
1a98aa ¤   ¤   return FALSE;
b09371 ¤   }
efaf5a
931740 ¤   else if (iReturn == IDC_BACKUPNOW) {
17a4ad ¤   ¤   *pbBackup = TRUE;
72836c ¤   ¤   return TRUE;
969371 ¤   }
5baf5a
aa665a ¤   else {
0d4f08 ¤   ¤   *pbBackup = FALSE;
60836c ¤   ¤   return TRUE;
6f9371 ¤   }
61efe6 }
32af5a
64af5a
6cc509 //¤ ____________________________________
1c465d //
84ebbb //¤ Warn user of existing split key dialogs
f6af5a
867efe BOOL·
6bcf0e PKSplitKeyWarn (HWND hWnd)·
58bb36 {
98f74d ¤   if (PKMessageBox (hWnd,·
a0e30e ¤   ¤   ¤   ¤   ¤   IDS_CAPTION,·
91b8b3 ¤   ¤   ¤   ¤   ¤   IDS_SPLITKEYWARNING,·
0b9899 ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONEXCLAMATION) == IDYES)
62836c ¤   ¤   return TRUE;
450e24 ¤   else
5998aa ¤   ¤   return FALSE;
7fefe6 }
00af5a
56af5a
2ac509 //¤ ____________________________________
15465d //
670319 //¤ Actually do the backing-up
8daf5a
0aa1ba VOID·
3751b5 PKBackup (HWND hWnd)·
91bb36 {
9ae6e2 ¤   BOOL¤   ¤   ¤   bFileError;
850339 ¤   HKEY¤   ¤   ¤   hKey;
007dd4 ¤   LONG¤   ¤   ¤   lResult;
5386cf ¤   DWORD¤  ¤   ¤   dwValueType, dwSize;
b00b76 ¤   OPENFILENAME¤   OpenFileName;
ca63e2 ¤   CHAR¤   ¤   ¤   szFile[MAX_PATH];
951542 ¤   CHAR¤   ¤   ¤   szDir[MAX_PATH];
--b213 0005b17da53401102eb Page 3 of PKUser.c
624240 ¤   CHAR¤   ¤   ¤   sz256[256];
86c93b ¤   CHAR¤   ¤   ¤   szDefExt[8];
5a0c1c ¤   CHAR¤   ¤   ¤   szFilter[256];
87fb19 ¤   PGPError¤   ¤   err;
86bd55 ¤   PGPFileSpecRef¤ fileref;
a8b47b ¤   LPSTR¤  ¤   ¤   lpsz;
e4cf2b ¤   CHAR*¤  ¤   ¤   p;
e3af5a
a243ab ¤   do {
9eff66 ¤   ¤   bFileError = FALSE;
00af5a
0b5d14 ¤   ¤   lResult = RegOpenKeyEx (HKEY_CURRENT_USER,·
a565c2 ¤   ¤   ¤   "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\"
99d172 ¤   ¤   ¤   "Shell Folders",·
10b469 ¤   ¤   ¤   0, KEY_READ, &hKey);
c66be9 ¤   ¤   if (lResult == ERROR_SUCCESS) {
8eaf5a
c807c8 ¤   ¤   // backup public keyring file
43b283 ¤   ¤   ¤   dwSize = sizeof(szDir);
65b30b ¤   ¤   ¤   lResult = RegQueryValueEx (hKey, "Desktop", 0, &dwValueType,·
376bf4 ¤   ¤   ¤   ¤   (LPBYTE)&szDir, &dwSize);
690cf6 ¤   ¤   ¤   if (lResult != ERROR_SUCCESS)·
de93a9 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_BACKUPDEFAULTDIR,·
a4216d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDir, sizeof(szDir));
333cef ¤   ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
57c712 ¤   ¤   ¤   OpenFileName.hwndOwner ········= hWnd;
1806b2 ¤   ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
dcffbb ¤   ¤   ¤   LoadString (g_hInst, IDS_PUBBACKUPFILTER,·
0877b6 ¤   ¤   ¤   ¤   szFilter, sizeof(szFilter));
acbefa ¤   ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
7eb8af ¤   ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
c919f8 ¤   ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
0236b9 ¤   ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
8c5fd3 ¤   ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
1967c5 ¤
8ac3a1 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (g_Context,·
22029b ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PublicKeyring, &fileref);
81fe29 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
234b07 ¤   ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileref, &lpsz);
0bfec7 ¤   ¤   ¤   ¤   p = strrchr (lpsz, '\\');
e0b45a ¤   ¤   ¤   ¤   if (p) {
529492 ¤   ¤   ¤   ¤   ¤   p++;
f4ed5a ¤   ¤   ¤   ¤   ¤   lstrcpy (szFile, p);
c62613 ¤   ¤   ¤   ¤   }
ee7b3f ¤   ¤   ¤   ¤   else lstrcpy (szFile, lpsz);
200944 ¤   ¤   ¤   ¤   p = strrchr (szFile, '.');
e15cc9 ¤   ¤   ¤   ¤   if (p) *p = '\0';
ef869a ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
2c0505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
48a3a6 ¤   ¤   ¤   }
a8e543 ¤   ¤   ¤   else {
e849d0 ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_PUBBACKUPDEFAULTFILE,·
2676b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFile, sizeof(szFile));
95a3a6 ¤   ¤   ¤   }
1cae30 ¤   ¤   ¤   ¤   ¤
5a7ce9 ¤   ¤   ¤   OpenFileName.lpstrFile ········= szFile;
5c42f3 ¤   ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (szFile);
1ae4e1 ¤   ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
c8277d ¤   ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
02f71e ¤   ¤   ¤   OpenFileName.lpstrInitialDir ··= szDir;
4e348d ¤   ¤   ¤   LoadString (g_hInst, IDS_PUBBACKUPCAPTION, sz256,·
599a4d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz256));
9dea4c ¤   ¤   ¤   OpenFileName.lpstrTitle ·······= sz256;
1dc073 ¤   ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_HIDEREADONLY|
7c9708 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_OVERWRITEPROMPT|
55fff9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_NOREADONLYRETURN|
cc6a6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_NOCHANGEDIR;
30ad67 ¤   ¤   ¤   OpenFileName.nFileOffset ······= 0;
c064ba ¤   ¤   ¤   OpenFileName.nFileExtension ···= 0;
1f90e8 ¤   ¤   ¤   LoadString (g_hInst, IDS_DEFPUBKEYRINGEXTENSION,·
343222 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDefExt, sizeof(szDefExt));
5bb206 ¤   ¤   ¤   OpenFileName.lpstrDefExt ······= szDefExt;
--92d6 00040339984401102eb Page 4 of PKUser.c
f64b9d ¤   ¤   ¤   OpenFileName.lCustData ········= 0;
d567c5 ¤
420661 ¤   ¤   ¤   if (GetSaveFileName (&OpenFileName)) {·
54ac92 ¤   ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (g_Context,·
b3029b ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PublicKeyring, &fileref);
6e3a35 ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
9267c5 ¤
ad912e ¤   ¤   ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileref, &lpsz);
f62abd ¤   ¤   ¤   ¤   ¤   if (!CopyFile (lpsz, szFile, FALSE))·
15bea0 ¤   ¤   ¤   ¤   ¤   ¤   bFileError = TRUE;
3743cf ¤   ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
68949d ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
3d67c5 ¤
4c2613 ¤   ¤   ¤   ¤   }
f5449c ¤   ¤   ¤   ¤   else bFileError = TRUE;
4c67c5 ¤
9e1a26 ¤   ¤   ¤   ¤   if (bFileError) {
4cb709 ¤   ¤   ¤   ¤   ¤   PKMessageBox (hWnd, IDS_CAPTION, IDS_BACKUPERROR,·
32f199 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
e42613 ¤   ¤   ¤   ¤   }
94a3a6 ¤   ¤   ¤   }
1daf5a
de1945 ¤   ¤   ¤   if (bFileError) continue;
e167c5 ¤
15d19f ¤   ¤   ¤   // backup private keyring file
5bf71d ¤   ¤   ¤   lstrcpy (szDir, szFile);
6a956b ¤   ¤   ¤   p = strrchr (szDir, '\\');
c16bc1 ¤   ¤   ¤   if (p) *p = '\0';
893cef ¤   ¤   ¤   OpenFileName.lStructSize ······= sizeof (OPENFILENAME);
9fc712 ¤   ¤   ¤   OpenFileName.hwndOwner ········= hWnd;
0506b2 ¤   ¤   ¤   OpenFileName.hInstance ········= (HANDLE)g_hInst;
a81e77 ¤   ¤   ¤   LoadString (g_hInst, IDS_BACKUPFILTER,·
3477b6 ¤   ¤   ¤   ¤   szFilter, sizeof(szFilter));
70befa ¤   ¤   ¤   while (p = strrchr (szFilter, '@')) *p = '\0';
c8b8af ¤   ¤   ¤   OpenFileName.lpstrFilter ······= szFilter;
5719f8 ¤   ¤   ¤   OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
2d36b9 ¤   ¤   ¤   OpenFileName.nMaxCustFilter ···= 0L;
f95fd3 ¤   ¤   ¤   OpenFileName.nFilterIndex ·····= 1L;
d067c5 ¤
63c3a1 ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (g_Context,·
84f37b ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PrivateKeyring, &fileref);
abfe29 ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
d34b07 ¤   ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileref, &lpsz);
71fec7 ¤   ¤   ¤   ¤   p = strrchr (lpsz, '\\');
4ab45a ¤   ¤   ¤   ¤   if (p) {
8c9492 ¤   ¤   ¤   ¤   ¤   p++;
c7ed5a ¤   ¤   ¤   ¤   ¤   lstrcpy (szFile, p);
fa2613 ¤   ¤   ¤   ¤   }
157b3f ¤   ¤   ¤   ¤   else lstrcpy (szFile, lpsz);
480944 ¤   ¤   ¤   ¤   p = strrchr (szFile, '.');
635cc9 ¤   ¤   ¤   ¤   if (p) *p = '\0';
81869a ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
030505 ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
1ea3a6 ¤   ¤   ¤   }
63e543 ¤   ¤   ¤   else {
6e3f0f ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_BACKUPDEFAULTFILE,·
cf76b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFile, sizeof(szFile));
c8a3a6 ¤   ¤   ¤   }
0267c5 ¤
b47ce9 ¤   ¤   ¤   OpenFileName.lpstrFile ········= szFile;
3d42f3 ¤   ¤   ¤   OpenFileName.nMaxFile ·········= sizeof (szFile);
b5e4e1 ¤   ¤   ¤   OpenFileName.lpstrFileTitle ···= NULL;
f5277d ¤   ¤   ¤   OpenFileName.nMaxFileTitle ····= 0;
e8f71e ¤   ¤   ¤   OpenFileName.lpstrInitialDir ··= szDir;
0c5396 ¤   ¤   ¤   LoadString (g_hInst, IDS_BACKUPCAPTION, sz256, sizeof(sz256));
beea4c ¤   ¤   ¤   OpenFileName.lpstrTitle ·······= sz256;
b3c073 ¤   ¤   ¤   OpenFileName.Flags¤ ¤   ¤   ···= OFN_HIDEREADONLY|
f19708 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_OVERWRITEPROMPT|
a6fff9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_NOREADONLYRETURN|
786a6a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·OFN_NOCHANGEDIR;
49ad67 ¤   ¤   ¤   OpenFileName.nFileOffset ······= 0;
4064ba ¤   ¤   ¤   OpenFileName.nFileExtension ···= 0;
--90c1 000f92bbf95401102eb Page 5 of PKUser.c
2c60aa ¤   ¤   ¤   LoadString (g_hInst, IDS_DEFKEYRINGEXTENSION,·
803222 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDefExt, sizeof(szDefExt));
92b206 ¤   ¤   ¤   OpenFileName.lpstrDefExt ······= szDefExt;
924b9d ¤   ¤   ¤   OpenFileName.lCustData ········= 0;
6967c5 ¤
660661 ¤   ¤   ¤   if (GetSaveFileName (&OpenFileName)) {·
38ac92 ¤   ¤   ¤   ¤   err = PGPsdkPrefGetFileSpec (g_Context,·
def37b ¤   ¤   ¤   ¤   ¤   ¤   kPGPsdkPref_PrivateKeyring, &fileref);
e53a35 ¤   ¤   ¤   ¤   if (IsntPGPError (PGPclErrorBox (NULL, err))) {
f0af5a
eb912e ¤   ¤   ¤   ¤   ¤   PGPGetFullPathFromFileSpec (fileref, &lpsz);
fa2abd ¤   ¤   ¤   ¤   ¤   if (!CopyFile (lpsz, szFile, FALSE))·
e5bea0 ¤   ¤   ¤   ¤   ¤   ¤   bFileError = TRUE;
6c43cf ¤   ¤   ¤   ¤   ¤   PGPFreeData (lpsz);
d3949d ¤   ¤   ¤   ¤   ¤   PGPFreeFileSpec (fileref);
cc67c5 ¤
012613 ¤   ¤   ¤   ¤   }
f0449c ¤   ¤   ¤   ¤   else bFileError = TRUE;
8467c5 ¤
d61a26 ¤   ¤   ¤   ¤   if (bFileError) {
cbb709 ¤   ¤   ¤   ¤   ¤   PKMessageBox (hWnd, IDS_CAPTION, IDS_BACKUPERROR,·
aef199 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
5e2613 ¤   ¤   ¤   ¤   }
65a3a6 ¤   ¤   ¤   }
390fe4 ¤   ¤   }
b12166 ¤   } while (bFileError);
5167c5 ¤
83830f ¤   return;
63efe6 }
7267c5 ¤
68c509 //¤ ____________________________________
92465d //
a6766e //¤ Read-only warning dialog message procedure
f3af5a
223f64 static BOOL CALLBACK·
a94bb9 sReadOnlyDlgProc (
6a4669 ¤   ¤   HWND¤   hWndDlg,·
71eb77 ¤   ¤   UINT¤   uMsg,·
4617d4 ¤   ¤   WPARAM¤ wParam,·
4ac0b8 ¤   ¤   LPARAM¤ lParam)·
42bb36 {
fc347f ¤   switch (uMsg) {
693fcf ¤   case WM_COMMAND:
82af5a
bc537d ¤   ¤   switch (LOWORD(wParam)) {
cb3860 ¤   ¤   case IDOK:
8e2f09 ¤   ¤   ¤   if (IsDlgButtonChecked (hWndDlg, IDC_WARNNOMORE) == BST_CHECKED)
967b42 ¤   ¤   ¤   ¤   EndDialog (hWndDlg, 1);
026b93 ¤   ¤   ¤   else·
7667f9 ¤   ¤   ¤   ¤   EndDialog (hWndDlg, 0);
8dcdcb ¤   ¤   ¤   break;
d10fe4 ¤   ¤   }
60836c ¤   ¤   return TRUE;
ab9371 ¤   }
c9a230 ¤   return FALSE;
94efe6 }
21af5a
0fc509 //¤ ____________________________________
42465d //
0e0484 // Warn user that keyrings are read-only
16af5a
7ca1ba VOID·
34ceeb PKReadOnlyWarning (HWND hWnd)·
b0bb36 {
72dbb6 ¤   PGPBoolean¤ ¤   bWarn¤  ¤   = TRUE;
05ce0f ¤   PGPPrefRef¤ ¤   prefref;
38fb19 ¤   PGPError¤   ¤   err;
03af5a
ceca35 ¤   err = PGPclOpenClientPrefs (
4f5814 ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
f3b736 ¤   ¤   ¤   &prefref);
f9b23e ¤   if (IsntPGPError (err)) {
--6de1 00199b73305401102eb Page 6 of PKUser.c
6e1d36 ¤   ¤   PGPGetPrefBoolean (prefref, kPGPPrefWarnOnReadOnlyKeyRings, &bWarn);
85af5a
6a8633 ¤   ¤   if (bWarn) {
636464 ¤   ¤   ¤   if (DialogBox (g_hInst, MAKEINTRESOURCE (IDD_READONLY),·
855cea ¤   ¤   ¤   ¤   ¤   ¤   hWnd, sReadOnlyDlgProc)) {
9d5067 ¤   ¤   ¤   ¤   bWarn = FALSE;
87d0ba ¤   ¤   ¤   ¤   PGPSetPrefBoolean (prefref, kPGPPrefWarnOnReadOnlyKeyRings,·
ceeb48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bWarn);
68a3a6 ¤   ¤   ¤   }
7e0fe4 ¤   ¤   }
b5af5a
d48695 ¤   ¤   PGPclCloseClientPrefs (prefref, !bWarn);
639371 ¤   }
c7efe6 }
edaf5a
c6c509 //¤ ____________________________________
b6465d //
e72637 //¤ Post Help About dialog
56af5a
7fa1ba VOID·
34335e PKHelpAbout (HWND hWnd)·
d4bb36 {
5f8ae8 ¤   PGPclHelpAbout (g_Context, hWnd, NULL, NULL, NULL);·
86efe6 }
82af5a
53c509 //¤ ____________________________________
d0465d //
dd4c93 //¤ Wipe edit box clean
c2af5a
6aa1ba VOID·
ccaefc PKWipeEditBox (
0e7de9 ¤   ¤   HWND hDlg,·
093408 ¤   ¤   UINT uID)·
7bbb36 {
08b616 ¤   CHAR* p;
96cdd6 ¤   INT i;
88af5a
66621d ¤   i = SendDlgItemMessage (hDlg, uID, WM_GETTEXTLENGTH, 0, 0);
d64dd4 ¤   if (i > 0) {
3ccfd7 ¤   ¤   p = pkAlloc (i+1);
e34400 ¤   ¤   if (p) {
95b668 ¤   ¤   ¤   FillMemory (p, i, ' ');
8a7804 ¤   ¤   ¤   SendDlgItemMessage (hDlg, uID, WM_SETTEXT, 0, (LPARAM)p);
c2a893 ¤   ¤   ¤   pkFree (p);
350fe4 ¤   ¤   }
abc622 ¤   ¤   SendDlgItemMessage (hDlg, uID, WM_SETTEXT, 0, (LPARAM)"");
679371 ¤   }
69efe6 }
beaf5a
99af5a
--21e2 001dcf1531a401102ec Page 1 of PKVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
d52042 ·FILETYPE VFT_APP
817247 ·FILESUBTYPE VFT2_UNKNOWN
f44523 BEGIN
752c72 ····BLOCK "StringFileInfo"
095574 ····BEGIN
fe70ac ········BLOCK "040904b0"
2752d6 ········BEGIN
e980b6 ············VALUE "CompanyName", PGPCOMPANYNAME
ef623c ············VALUE "FileDescription", "PGP Key Manager Application\0"
dcc1dd ············VALUE "FileVersion", PGPVERSIONSTRING
c032b3 ············VALUE "InternalName", "PGPkeys\0"
4d8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
002bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
2dba89 ············VALUE "OriginalFilename", "PGPkeys.exe\0"
809317 ············VALUE "ProductName", PGPPRODUCTNAME
39d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
2cf37f ········END
177d01 ····END
7626ab ····BLOCK "VarFileInfo"
cb5574 ····BEGIN
4c4b11 ········VALUE "Translation", 0x409, 1200
0e7d01 ····END
27e0d1 END
5caf5a
27af5a
dcaf5a
--f348 0007b7cfd04401102ed Page 1 of PKgenwiz.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
9b24f5 ¤   All rights reserved
9967c5 ¤
6e55a0 ¤   PKgenwiz.c - handle wizard for creating new keys
d8af5a
630e44 ¤   $Id: PKgenwiz.c,v 1.100.2.2 1998/10/05 21:30:56 pbj Exp $
f3f7f7 ____________________________________________________________________________*/
59e610 #include "pgpPFLConfig.h"
cfaf5a
c1c917 // project header files
22c55a #include "pgpkeysx.h"
f3af5a
3fad8c // pgp header files
28c9be #include "pgpRandomPool.h"
3ae684 #include "pgpUserInterface.h"
f1af5a
4afc2c // system header files
c411a9 #include <process.h>
f6af5a
695584 // constant definitions
c61bbe #define MAX_FULL_NAME_LEN¤  ¤   126
4f969d #define MAX_EMAIL_LEN¤  ¤   ¤   126
85af5a
8bebc0 #define BADPHRASE_LENGTH¤   ¤   0x01
ae8391 #define BADPHRASE_QUALITY¤  ¤   0x02
3b1f36 #define BADPHRASE_CONFIRMATION¤ 0x04
23af5a
b1ab76 #define MIN_KEY_SIZE¤   ¤   ¤   768
c42fd3 #define MAX_RSA_KEY_SIZE¤   ¤   2048
602f8e #define MAX_DSA_KEY_SIZE¤   ¤   4096
d0af5a
40b7de #define DEFAULT_MINPHRASELEN¤   8
114b4b #define DEFAULT_MINPHRASEQUAL¤  60
0017bf #define DEFAULT_KEYSIZE¤¤   ¤   2048
3c4fd0 #define DEFAULT_SUBKEYSIZE¤ ¤   1024
9d0945 #define DEFAULT_KEYTYPE¤¤   ¤   kPGPPublicKeyAlgorithm_DSA
48af5a
ddbe67 #define TIMERPERIOD¤¤   ¤   ¤   1000L
33f12b #define AVI_TIMER¤  ¤   ¤   ¤   2345L
af2d10 #define AVI_RUNTIME¤¤   ¤   ¤   11000L ·// duration of AVI in ms
98af5a
c4b7bd #define LEDTIMER¤   ¤   111L
2f4cc2 #define LEDTIMERPERIOD¤ 100L
41af5a
2ce2dd #define NUMLEDS¤¤   ¤   10
cf7fd1 #define LEDSPACING¤ ¤   2
bbaf5a
50af5a
a0268e #define KGWIZ_INTRO¤¤   0
71764c #define KGWIZ_NAME¤ ¤   1
59ab84 #define KGWIZ_TYPE¤ ¤   2
8370e6 #define KGWIZ_SIZE¤ ¤   3
4c706b #define KGWIZ_EXPIRE¤   4
243f02 #define KGWIZ_ADK¤  ¤   5
d665a7 #define KGWIZ_CORPCERT¤ 6
3dcfc2 #define KGWIZ_REVOKER¤  7
229b4e #define KGWIZ_PHRASE¤   8
1c7c77 #define KGWIZ_BADPHRASE¤9
a2b3a4 #define KGWIZ_ENTROPY ··10
5b6f03 #define KGWIZ_KEYGEN¤   11
323ba3 #define KGWIZ_SIGN¤ ¤   12
fad677 #define KGWIZ_PRESEND ··13
03b8b5 #define KGWIZ_SEND¤ ¤   14
7dc78e #define KGWIZ_DONE¤ ¤   15
9b05d9 #define NUM_WIZ_PAGES¤  16
71af5a
63af5a
4293ed // external globals
91eec0 extern HINSTANCE¤   ¤   g_hInst;
92cf38 extern PGPContextRef¤   g_Context;
7b02e7 extern PGPtlsContextRef¤g_TLSContext;
--ca13 000495890ba401102ed Page 2 of PKgenwiz.c
66cf4b extern CHAR¤¤   ¤   ¤   g_szHelpFile[MAX_PATH];¤ // name of help file
32af5a
32492e // local globals
5601aa static HHOOK¤   hhookKeyboard;
d1af5a
f02a8b static HHOOK¤   hhookJournalRecord;
08fe09 static HHOOK¤   hhookCBT;
03ae39 static HHOOK¤   hhookGetMessage;
5591b0 static HHOOK¤   hhookMsgFilter;
6de7ff static HHOOK¤   hhookSysMsgFilter;
e5af5a
869861 static HWND¤¤   hWndCollectEntropy = NULL;
dc4441 static WNDPROC¤ wpOrigPhrase1Proc; ·
299246 static WNDPROC¤ wpOrigPhrase2Proc; ·
1b2578 static BOOL¤¤   bHideTyping = TRUE;
651b18 static LPSTR¤   szPhrase1 = NULL;
4f6f71 static LPSTR¤   szPhrase2 = NULL;
3616b6 static LONG¤¤   lPhrase1Len = 0;
e462df static LONG¤¤   lPhrase2Len = 0;
66af5a
821d0c static PGPKeySetRef¤KeySetMain;
05af5a
305bee // typedefs
9d4621 typedef struct _KeyGenInfo
c4bb36 {
108e1c ¤   PGPContextRef¤  ¤   Context;
51b4ac ¤   PGPtlsContextRef¤   tlsContext;
261800 ¤   PGPPrefRef¤ ¤   ¤   PrefRefAdmin;
acfe96 ¤   PGPPrefRef¤ ¤   ¤   PrefRefClient;
cdbb81 ¤   HWND¤   ¤   ¤   ¤   hWndWiz;
c2a384 ¤   HBITMAP¤¤   ¤   ¤   hBitmap;
058160 ¤   HPALETTE¤   ¤   ¤   hPalette;
1cb076 ¤   LPSTR¤  ¤   ¤   ¤   pszFullName;
534194 ¤   LPSTR¤  ¤   ¤   ¤   pszEmail;
187247 ¤   LPSTR¤  ¤   ¤   ¤   pszUserID;
ff0378 ¤   LPSTR¤  ¤   ¤   ¤   pszPassPhrase;
d3af24 ¤   PGPKeyRef¤  ¤   ¤   ADK;
2c794e ¤   BOOL¤   ¤   ¤   ¤   bEnforceADK;
92560d ¤   PGPKeyRef¤  ¤   ¤   CorpKey;
9967ee ¤   BOOL¤   ¤   ¤   ¤   bMetaCorpKey;
1f62d0 ¤   PGPKeyRef¤  ¤   ¤   RevokerKey;
03db2c ¤   BOOL¤   ¤   ¤   ¤   bMinPhraseQuality;
188602 ¤   INT¤¤   ¤   ¤   ¤   iMinPhraseQuality;
e2daca ¤   BOOL¤   ¤   ¤   ¤   bMinPhraseLength;
310965 ¤   INT¤¤   ¤   ¤   ¤   iMinPhraseLength;
3ebe8f ¤   BOOL¤   ¤   ¤   ¤   bAllowRSAGen;
d5be7f ¤   UINT¤   ¤   ¤   ¤   uMinKeySize;
9f0460 ¤   UINT¤   ¤   ¤   ¤   uPhraseFlags;
e86505 ¤   UINT¤   ¤   ¤   ¤   uKeyType;
8c113a ¤   UINT¤   ¤   ¤   ¤   uKeySize;
b7ec89 ¤   UINT¤   ¤   ¤   ¤   uSubKeySize;
2c1ec8 ¤   UINT¤   ¤   ¤   ¤   uExpireDays;
0335d1 ¤   HWND¤   ¤   ¤   ¤   hwndExpirationDate;
31c5a7 ¤   LONG¤   ¤   ¤   ¤   lRandomBitsNeeded;
a651ee ¤   LONG¤   ¤   ¤   ¤   lOriginalEntropy;
7a4372 ¤   PGPKeyRef¤  ¤   ¤   Key;
4da69e ¤   PGPKeyRef¤  ¤   ¤   OldKey;
64a2ae ¤   BOOL¤   ¤   ¤   ¤   bFinishSelected;
985c69 ¤   BOOL¤   ¤   ¤   ¤   bCancelPending;
c211c5 ¤   BOOL¤   ¤   ¤   ¤   bInGeneration;
f28b1a ¤   UINT¤   ¤   ¤   ¤   uWorkingPhase;
7008a3 ¤   BOOL¤   ¤   ¤   ¤   bDoSend;
0186e6 ¤   BOOL¤   ¤   ¤   ¤   bSendInProgress;
ee8c9f ¤   INT¤¤   ¤   ¤   ¤   iStatusValue;
0121ff ¤   INT¤¤   ¤   ¤   ¤   iStatusDirection;
ff44a9 ¤   BOOL¤   ¤   ¤   ¤   bSendComplete;
63c665 ¤   INT¤¤   ¤   ¤   ¤   iFinalResult;
a54716 } KEYGENINFO, *PKEYGENINFO;
a8af5a
b3af5a
1fc509 //¤ ____________________________________
49465d //
--b2b8 0008e40aa72401102ed Page 3 of PKgenwiz.c
31c415 // Secure memory allocation routines
c9465d //
edaf5a
7050e1 static VOID*·
605a20 secAlloc (UINT uBytes)·
22bb36 {
5a0235 ¤   return (PGPNewSecureData (
64ce55 ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
6a6582 ¤   ¤   ¤   ¤   uBytes, 0));
00efe6 }
baaf5a
70af5a
9eb333 static VOID·
5bd91b secFree (VOID* p)·
f4bb36 {
c4f191 ¤   if (p) {
e26d67 ¤   ¤   FillMemory (p, lstrlen (p), '\0');
ca4bbf ¤   ¤   PGPFreeData (p);
729371 ¤   }
efefe6 }
d6af5a
9fc509 //¤ ____________________________________
5d465d //
e723ca // ·Hook procedure for WH_KEYBOARD hook
5dd83c ·
70a004 static LRESULT CALLBACK·
1cb4c2 sWizKeyboardHookProc (
2d422d ¤   ¤   INT¤¤   iCode,·
a017d4 ¤   ¤   WPARAM¤ wParam,·
aac0b8 ¤   ¤   LPARAM¤ lParam)·
5a7142 {·
34d83c ·
f6bf38 ¤   if (hWndCollectEntropy) {
b1cdda ¤   ¤   PGPGlobalRandomPoolAddKeystroke (wParam);
2874d7 ¤   ¤   PostMessage (hWndCollectEntropy, WM_MOUSEMOVE, 0, 0);
c9e102 ¤   ¤   return 1;
fa9371 ¤   }
97af5a
ab3e6b ¤   return 0;
7aa79b }·
bbd83c ·
24c509 //¤ ____________________________________
54465d //
d7a161 // ·Hook procedure for various hooks -- used to prevent
0190de // ·passing the hook info on to next hook procedure
59d83c ·
54a004 static LRESULT CALLBACK·
a78692 sWizGenericHookProc (
73422d ¤   ¤   INT¤¤   iCode,·
9917d4 ¤   ¤   WPARAM¤ wParam,·
e1c0b8 ¤   ¤   LPARAM¤ lParam)·
9c7142 {·
543e6b ¤   return 0;
8ba79b }·
1cd83c ·
d5af5a
efc509 //¤ ____________________________________
98465d //
7e83d0 // ·set all the message hooks
4caf5a
27e6b2 static VOID
37130c sInstallWindowsHooks (VOID)
88bb36 {
82504a ¤   DWORD¤  dwThreadID;
44af5a
ef1ea7 ¤   dwThreadID = GetCurrentThreadId ();
a6af5a
b33958 ¤   // keyboard hook is to trap entropy
05a291 ¤   hhookKeyboard = SetWindowsHookEx (WH_KEYBOARD,·
edc12a ¤   ¤   ¤   ¤   ¤   ¤   sWizKeyboardHookProc, NULL, dwThreadID);
12af5a
8ee5ce ¤   // others are just to prevent messages from going to sniffer hooks
--a6d6 00007f244bb401102ed Page 4 of PKgenwiz.c
728013 ¤   hhookJournalRecord = SetWindowsHookEx (WH_JOURNALRECORD,·
ae4bf6 ¤   ¤   (int (__stdcall *)(void))sWizGenericHookProc,·
6115e3 ¤   ¤   NULL, dwThreadID);
b3c9b9 ¤   hhookCBT = SetWindowsHookEx (WH_CBT,·
934bf6 ¤   ¤   (int (__stdcall *)(void))sWizGenericHookProc,·
4615e3 ¤   ¤   NULL, dwThreadID);
5b981e ¤   hhookGetMessage = SetWindowsHookEx (WH_GETMESSAGE,·
ac4bf6 ¤   ¤   (int (__stdcall *)(void))sWizGenericHookProc,·
d115e3 ¤   ¤   NULL, dwThreadID);
845a36 ¤   hhookMsgFilter = SetWindowsHookEx (WH_MSGFILTER,·
4b4bf6 ¤   ¤   (int (__stdcall *)(void))sWizGenericHookProc,·
0415e3 ¤   ¤   NULL, dwThreadID);
8cd22e ¤   hhookMsgFilter = SetWindowsHookEx (WH_SYSMSGFILTER,·
e84bf6 ¤   ¤   (int (__stdcall *)(void))sWizGenericHookProc,·
5115e3 ¤   ¤   NULL, dwThreadID);
8fefe6 }
c5af5a
9caf5a
fac509 //¤ ____________________________________
17465d //
968aeb // ·remove all the message hooks
69af5a
21e6b2 static VOID
f54084 sUninstallWindowsHooks (VOID)
c8bb36 {
e323dc ¤   UnhookWindowsHookEx (hhookSysMsgFilter);
6c97b5 ¤   UnhookWindowsHookEx (hhookMsgFilter);
2f1aeb ¤   UnhookWindowsHookEx (hhookGetMessage);
03863f ¤   UnhookWindowsHookEx (hhookCBT);
a8a19a ¤   UnhookWindowsHookEx (hhookJournalRecord);
07af5a
78096e ¤   UnhookWindowsHookEx (hhookKeyboard);
7eefe6 }
76af5a
0faf5a
07c509 //¤ ____________________________________
50465d //
009254 // ·test admin prefs for validity
c9af5a
a76c77 static BOOL·
1ffa0b sValidateConfiguration (PKEYGENINFO pkgi)·
24bb36 {
2c05c7 ¤   BOOL¤   ¤   bPrefsOK = TRUE;
20d2f8 ¤   BOOL¤   ¤   bPrefsCorrupt = FALSE;
47af5a
3961e0 ¤   PGPError¤   err;
ccaf5a
fdbe29 #if PGP_BUSINESS_SECURITY
225156 ¤   CHAR¤   ¤   szID[20];
be72e2 ¤   PGPBoolean¤ b;
1e2717 ¤   PGPUInt32¤  u;
567454 #endif
f0af5a
669534 ¤   pkgi->pszFullName¤  ¤   = NULL;
dd00f4 ¤   pkgi->pszEmail¤ ¤   ¤   = NULL;
c9ed80 ¤   pkgi->pszUserID¤¤   ¤   = NULL;
ea1879 ¤   pkgi->uKeyType¤ ¤   ¤   = DEFAULT_KEYTYPE;
dc7096 ¤   pkgi->uKeySize¤ ¤   ¤   = DEFAULT_KEYSIZE;
6e3e07 ¤   pkgi->uSubKeySize¤  ¤   = DEFAULT_SUBKEYSIZE;
52e0ec ¤   pkgi->uExpireDays¤  ¤   = 0;
499dd8 ¤   pkgi->pszPassPhrase¤¤   = NULL;
ca5196 ¤   pkgi->uPhraseFlags¤ ¤   = 0;
0c7b06 ¤   pkgi->lRandomBitsNeeded¤= 0;
398eb3 ¤   pkgi->lOriginalEntropy¤ = 0;
4da51f ¤   pkgi->Key¤  ¤   ¤   ¤   = NULL;
834cea ¤   pkgi->OldKey¤   ¤   ¤   = NULL;
eb15ee ¤   pkgi->bFinishSelected¤  = FALSE;
310030 ¤   pkgi->bCancelPending¤   = FALSE;
42ec28 ¤   pkgi->bInGeneration¤¤   = FALSE;
b180ae ¤   pkgi->uWorkingPhase¤¤   = 0;
3e1aa4 ¤   pkgi->bDoSend¤  ¤   ¤   = FALSE;
0728e6 ¤   pkgi->bSendComplete¤¤   = FALSE;
--5a8f 000deb1a2b4401102ed Page 5 of PKgenwiz.c
6d372e ¤   pkgi->iFinalResult¤ ¤   = 0;
a8af5a
88d143 ¤   // minimum passphrase length
87be29 #if PGP_BUSINESS_SECURITY
6fe74e ¤   b = FALSE;
0c0045 ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefEnforceMinChars, &b);
0cad19 ¤   pkgi->bMinPhraseLength = b;
025359 ¤   if (b) {
697f10 ¤   ¤   u = DEFAULT_MINPHRASELEN;
dd4caa ¤   ¤   err = PGPGetPrefNumber (pkgi->PrefRefAdmin, kPGPPrefMinChars, &u);
dca9fa ¤   ¤   if (IsPGPError (err)) bPrefsCorrupt = TRUE;
7da01e ¤   ¤   pkgi->iMinPhraseLength = (INT)u;
229371 ¤   }
856983 ¤   else pkgi->iMinPhraseLength = DEFAULT_MINPHRASELEN;
e0db21 #else
76e26a ¤   pkgi->bMinPhraseLength = FALSE;
0a1ae1 ¤   pkgi->iMinPhraseLength = DEFAULT_MINPHRASELEN;
613eb0 #endif // PGP_BUSINESS_SECURITY
f2af5a
5643a9 ¤   // minimum passphrase quality
66be29 #if PGP_BUSINESS_SECURITY
ece74e ¤   b = FALSE;
52ec30 ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefEnforceMinQuality, &b);
d7d375 ¤   pkgi->bMinPhraseQuality = b;
a45359 ¤   if (b) {
5c6dd5 ¤   ¤   u = DEFAULT_MINPHRASEQUAL;
8dc4e8 ¤   ¤   err = PGPGetPrefNumber (pkgi->PrefRefAdmin, kPGPPrefMinQuality, &u);
12a9fa ¤   ¤   if (IsPGPError (err)) bPrefsCorrupt = TRUE;
d0d586 ¤   ¤   pkgi->iMinPhraseQuality = (INT)u;
2e9371 ¤   }
0c05bd ¤   else pkgi->iMinPhraseQuality = 0;
67db21 #else
8e7c79 ¤   pkgi->bMinPhraseQuality = FALSE;
d71968 ¤   pkgi->iMinPhraseQuality = 0;
4a3eb0 #endif // PGP_BUSINESS_SECURITY
b1af5a
a966e7 ¤   // RSA key generation
aed0e0 ¤   pkgi->bAllowRSAGen = TRUE;
a2be29 #if PGP_BUSINESS_SECURITY
38e74e ¤   b = FALSE;
1980f6 ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefAllowRSAKeyGen, &b);
47c07e ¤   pkgi->bAllowRSAGen = b;
fb3199 #endif·
9ef17f ¤   err = PGPclCheckSDKSupportForPKAlg (
5ef83b ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA, FALSE, FALSE);
8fde9b ¤   if (IsPGPError (err))
4d5d61 ¤   ¤   pkgi->bAllowRSAGen = FALSE;
469e7a #if NO_RSA_KEYGEN
89d69d ¤   pkgi->bAllowRSAGen = FALSE;
277454 #endif
8e67c5 ¤
7fc108 ¤   // minimum key size·
d3be29 #if PGP_BUSINESS_SECURITY
2e0e77 ¤   u = MIN_KEY_SIZE;
69eb80 ¤   PGPGetPrefNumber (pkgi->PrefRefAdmin, kPGPPrefMinimumKeySize, &u);
ea3111 ¤   pkgi->uMinKeySize = u;
cddb21 #else
f6a9f6 ¤   pkgi->uMinKeySize = MIN_KEY_SIZE;
707454 #endif
f7af5a
42f956 ¤   // ADK stuff
02be29 #if PGP_BUSINESS_SECURITY
f3e74e ¤   b = FALSE;
fe1e92 ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefEnforceIncomingADK, &b);
407b55 ¤   pkgi->bEnforceADK = b;
e7af5a
69e74e ¤   b = FALSE;
56b446 ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefUseDHADK, &b);
6a5359 ¤   if (b) {
ae5bb6 ¤   ¤   err = PGPGetPrefStringBuffer (pkgi->PrefRefAdmin, kPGPPrefDHADKID,·
5dad21 ¤   ¤   ¤   sizeof(szID), szID);
de8536 ¤   ¤   if (IsntPGPError (err)) {
--7cad 000e41bbacd401102ed Page 6 of PKgenwiz.c
8bcaf8 ¤   ¤   ¤   err = PGPclGetKeyFromKeyID (pkgi->Context, KeySetMain,·
26449c ¤   ¤   ¤   ¤   ¤   szID, kPGPPublicKeyAlgorithm_DSA, &(pkgi->ADK));
5a0fe4 ¤   ¤   }
f5a42f ¤   ¤   if (IsPGPError (err)) {
2167b9 ¤   ¤   ¤   bPrefsOK = FALSE;
fdc1ab ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_MISSINGADK,·
8cbd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
bf0fe4 ¤   ¤   }
5607e0 ¤   ¤   else {
c3f35f ¤   ¤   ¤   PGPGetKeyBoolean (pkgi->ADK, kPGPKeyPropIsExpired, &b);
f9a743 ¤   ¤   ¤   if (b) {
ec50b1 ¤   ¤   ¤   ¤   bPrefsOK = FALSE;
ec848a ¤   ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_EXPIREDADK,·
94bd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
a6a3a6 ¤   ¤   ¤   }
7de543 ¤   ¤   ¤   else {
ba1a3f ¤   ¤   ¤   ¤   PGPGetKeyBoolean (pkgi->ADK, kPGPKeyPropIsRevoked, &b);
601692 ¤   ¤   ¤   ¤   if (b) {
70bfc2 ¤   ¤   ¤   ¤   ¤   bPrefsOK = FALSE;
449c2b ¤   ¤   ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_REVOKEDADK,·
bd2b62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
932613 ¤   ¤   ¤   ¤   }
40a3a6 ¤   ¤   ¤   }
a60fe4 ¤   ¤   }
ba9371 ¤   }
b9003f ¤   else pkgi->ADK = NULL;
3bdb21 #else
ada8c2 ¤   pkgi->ADK = NULL;
953a3f ¤   pkgi->bEnforceADK = FALSE;
223eb0 #endif // PGP_BUSINESS_SECURITY
c2af5a
e3827c ¤   // Corporate Key stuff
b7be29 #if PGP_BUSINESS_SECURITY
64bfa8 ¤   // corp key signing type
5ae74e ¤   b = FALSE;
260d0a ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefMetaIntroducerCorp, &b);
0d5630 ¤   pkgi->bMetaCorpKey = b;
8aaf5a
442009 ¤   // corp key
a0e74e ¤   b = FALSE;
60910b ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefAutoSignTrustCorp, &b);
d05359 ¤   if (b) {
80517f ¤   ¤   err = PGPGetPrefStringBuffer (pkgi->PrefRefAdmin,·
3ceaef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefCorpKeyID, sizeof(szID), szID);
5d8536 ¤   ¤   if (IsntPGPError (err)) {
3e77f5 ¤   ¤   ¤   err = PGPGetPrefNumber (pkgi->PrefRefAdmin,
c35a88 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefCorpKeyPublicKeyAlgorithm, &u);
2c6a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
7f848f ¤   ¤   ¤   ¤   err = PGPclGetKeyFromKeyID (pkgi->Context, KeySetMain,·
d7376c ¤   ¤   ¤   ¤   ¤   ¤   szID, u, &(pkgi->CorpKey));
0a6258 ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤
fc0fe4 ¤   ¤   }
eca42f ¤   ¤   if (IsPGPError (err)) {
1767b9 ¤   ¤   ¤   bPrefsOK = FALSE;
7d9c18 ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_MISSINGCORPKEY,·
71bd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
dc0fe4 ¤   ¤   }
8e07e0 ¤   ¤   else {
b76db1 ¤   ¤   ¤   PGPGetKeyBoolean (pkgi->CorpKey, kPGPKeyPropIsExpired, &b);
c3a743 ¤   ¤   ¤   if (b) {
0b50b1 ¤   ¤   ¤   ¤   bPrefsOK = FALSE;
8f303b ¤   ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_EXPIREDCORPKEY,·
d4bd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
fba3a6 ¤   ¤   ¤   }
7de543 ¤   ¤   ¤   else {
09d1af ¤   ¤   ¤   ¤   PGPGetKeyBoolean (pkgi->CorpKey, kPGPKeyPropIsRevoked, &b);
ec1692 ¤   ¤   ¤   ¤   if (b) {
17bfc2 ¤   ¤   ¤   ¤   ¤   bPrefsOK = FALSE;
78cdea ¤   ¤   ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_REVOKEDCORPKEY,·
0d2b62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
832613 ¤   ¤   ¤   ¤   }
e4a3a6 ¤   ¤   ¤   }
--3d18 000807f4481401102ed Page 7 of PKgenwiz.c
b50fe4 ¤   ¤   }
6b9371 ¤   }
387688 ¤   else pkgi->CorpKey = NULL;
19db21 #else
6d31c8 ¤   pkgi->bMetaCorpKey = FALSE;
564339 ¤   pkgi->CorpKey = NULL;
683eb0 #endif // PGP_BUSINESS_SECURITY
aeaf5a
3d3a98 ¤   // Designated Revoker Key stuff
18be29 #if PGP_BUSINESS_SECURITY
40eefa ¤   // revoker key
c3e74e ¤   b = FALSE;
5cad3e ¤   PGPGetPrefBoolean (pkgi->PrefRefAdmin, kPGPPrefAutoAddRevoker, &b);
c55359 ¤   if (b) {
c1517f ¤   ¤   err = PGPGetPrefStringBuffer (pkgi->PrefRefAdmin,·
1e11e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefRevokerKeyID, sizeof(szID), szID);
6c8536 ¤   ¤   if (IsntPGPError (err)) {
7077f5 ¤   ¤   ¤   err = PGPGetPrefNumber (pkgi->PrefRefAdmin,
059125 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefRevokerPublicKeyAlgorithm, &u);
d56a45 ¤   ¤   ¤   if (IsntPGPError (err)) {
3d848f ¤   ¤   ¤   ¤   err = PGPclGetKeyFromKeyID (pkgi->Context, KeySetMain,·
9f09b7 ¤   ¤   ¤   ¤   ¤   ¤   szID, u, &(pkgi->RevokerKey));
f96258 ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤
ce0fe4 ¤   ¤   }
d1a42f ¤   ¤   if (IsPGPError (err)) {
c167b9 ¤   ¤   ¤   bPrefsOK = FALSE;
366fe8 ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_MISSINGREVOKERKEY,·
e3bd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
b20fe4 ¤   ¤   }
7607e0 ¤   ¤   else {
997ff7 ¤   ¤   ¤   PGPGetKeyBoolean (pkgi->RevokerKey, kPGPKeyPropIsExpired, &b);
baa743 ¤   ¤   ¤   if (b) {
8550b1 ¤   ¤   ¤   ¤   bPrefsOK = FALSE;
3685e8 ¤   ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_EXPIREDREVOKERKEY,·
fabd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
83a3a6 ¤   ¤   ¤   }
b2e543 ¤   ¤   ¤   else {
fe9246 ¤   ¤   ¤   ¤   PGPGetKeyBoolean (pkgi->RevokerKey, kPGPKeyPropIsRevoked,&b);
b31692 ¤   ¤   ¤   ¤   if (b) {
81bfc2 ¤   ¤   ¤   ¤   ¤   bPrefsOK = FALSE;
519c4b ¤   ¤   ¤   ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_REVOKEDREVOKERKEY,·
db2b62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
dc2613 ¤   ¤   ¤   ¤   }
bea3a6 ¤   ¤   ¤   }
1a0fe4 ¤   ¤   }
be9371 ¤   }
f03758 ¤   else pkgi->RevokerKey = NULL;
abdb21 #else
862fdc ¤   pkgi->RevokerKey = NULL;
673eb0 #endif // PGP_BUSINESS_SECURITY
2faf5a
0eaf5a
cd83e7 ¤   // everything OK ?
ddf70b ¤   if (bPrefsCorrupt) {
f0eeed ¤   ¤   bPrefsOK = FALSE;
a9b2ce ¤   ¤   PKMessageBox (NULL, IDS_CAPTION, IDS_ADMINPREFSCORRUPT,·
05bd23 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK|MB_ICONSTOP);
6f9371 ¤   }
8044f7 ¤   return (bPrefsOK); ·
c0efe6 }
a6af5a
d7af5a
a6c509 //¤ ____________________________________
93465d //
86194d // ·return DSA key size on basis of requested ElGamal key size
cfaf5a
dae9f6 static ULONG·
0abb70 sGetDSAKeySize (ULONG ulRequested)
3abb36 {
5c639f ¤   ULONG ulActualBits = ulRequested;
43af5a
80b283 ¤   if (ulRequested > 1024) ulActualBits = 1024;
--2894 00087305984401102ed Page 8 of PKgenwiz.c
e0af5a
544024 ¤   return (ulActualBits);
cdefe6 }
40af5a
c1af5a
04c509 //¤ ____________________________________
66465d //
c00dcc // ·display keygen AVI file in specified window
40af5a
f2e6b2 static VOID
248272 sStartKeyGenAVI (HWND hwnd)
43bb36 {
fccde7 ¤   CHAR¤   szFile[32];
b78085 ¤   CHAR¤   szAnimationFile[MAX_PATH];
636d9e ¤   LPSTR¤  p;
66af5a
ab2e11 ¤   lstrcpy (szAnimationFile, g_szHelpFile);
d3af5a
05cc28 ¤   p = strrchr (szAnimationFile, '\\');
c24dda ¤   if (!p)
3fee35 ¤   ¤   p = szAnimationFile;
ff0e24 ¤   else
204992 ¤   ¤   ++p;
d9ddb4 ¤   *p = '\0';
26af5a
661dae ¤   LoadString (g_hInst, IDS_ANIMATIONFILE, szFile, sizeof(szFile));
bd9a20 ¤   lstrcat (szAnimationFile, szFile);
74af5a
e5a1b1 ¤   Animate_Open (hwnd, szAnimationFile);
c99c3d ¤   Animate_Play (hwnd, 0, -1, -1);
0aefe6 }
82af5a
d1af5a
d6c509 //¤ ____________________________________
79465d //
7fa4ef // ·Draw the "LED" progress indicator
beaf5a
04e6b2 static VOID
3e57e6 sDrawSendStatus (
5915eb ¤   ¤   HWND¤   ¤   hwnd,
a9fe3d ¤   ¤   PKEYGENINFO¤pkgi)·
eebb36 {
8c50e1 ¤   HBRUSH¤ ¤   ¤   hBrushLit, hBrushUnlit, hBrushOld;
98df75 ¤   HPEN¤   ¤   ¤   hPen, hPenOld;
c4dfcd ¤   INT¤¤   ¤   ¤   i;
aa648c ¤   INT¤¤   ¤   ¤   itop, ibot, ileft, iright, iwidth;
7c1372 ¤   RECT¤   ¤   ¤   rc;
c98bc2 ¤   HDC¤¤   ¤   ¤   hdc;
e7ad04 ¤   PAINTSTRUCT¤¤   ps;
fdaf5a
2edd30 ¤   if (pkgi->iStatusValue < -1) return;
96af5a
f6079e ¤   hdc = BeginPaint (hwnd, &ps);
bfaf5a
e9ff4c ¤   // draw 3D shadow
fb47d1 ¤   GetClientRect (hwnd, &rc);
0c9ae0 ¤   itop = rc.top+1;
acc454 ¤   ibot = rc.bottom-2;
6aaf5a
ccd3ea ¤   iwidth = (rc.right-rc.left) / NUMLEDS;
c8962e ¤   iwidth -= LEDSPACING;
94af5a
a01566 ¤   ileft = rc.left + 4;
728d6c ¤   for (i=0; i<NUMLEDS; i++) {
289e04 ¤   ¤   iright = ileft + iwidth;
8eaf5a
aa855c ¤   ¤   MoveToEx (hdc, ileft, ibot, NULL);
4199e0 ¤   ¤   LineTo (hdc, iright, ibot);
60b146 ¤   ¤   LineTo (hdc, iright, itop);
5caf5a
12efbc ¤   ¤   ileft += iwidth + LEDSPACING;
879371 ¤   }
--215b 00016464761401102ed Page 9 of PKgenwiz.c
e0af5a
fc6cf6 ¤   hPen = CreatePen (PS_SOLID, 0, RGB (128, 128, 128));
ccd2d7 ¤   hPenOld = SelectObject (hdc, hPen);
d46d82 ¤   hBrushLit = CreateSolidBrush (RGB (0, 255, 0));
a9ee91 ¤   hBrushUnlit = CreateSolidBrush (RGB (0, 128, 0));
d1af5a
161566 ¤   ileft = rc.left + 4;
16af5a
8118f3 ¤   // draw "Knight Rider" LEDs
0d32b7 ¤   if (pkgi->iStatusDirection) {
611ae7 ¤   ¤   hBrushOld = SelectObject (hdc, hBrushUnlit);
bc0690 ¤   ¤   for (i=0; i<NUMLEDS; i++) {
f6a36c ¤   ¤   ¤   iright = ileft + iwidth;
2967c5 ¤
c180df ¤   ¤   ¤   if (i == pkgi->iStatusValue) {
abbb93 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushLit);
4c844c ¤   ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
bb1f85 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushUnlit);
18a3a6 ¤   ¤   ¤   }
959905 ¤   ¤   ¤   else ·{
d7844c ¤   ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
30a3a6 ¤   ¤   ¤   }
8167c5 ¤
00d352 ¤   ¤   ¤   ileft += iwidth + LEDSPACING;
830fe4 ¤   ¤   }
989371 ¤   }
b0af5a
c5a806 ¤   // draw "progress bar" LEDs
6cd8f5 ¤   else {·
2f788c ¤   ¤   if (pkgi->iStatusValue >= 0)·
2abb7c ¤   ¤   ¤   hBrushOld = SelectObject (hdc, hBrushLit);
4c0e1d ¤   ¤   else
6e75d4 ¤   ¤   ¤   hBrushOld = SelectObject (hdc, hBrushUnlit);
f9af5a
0b0690 ¤   ¤   for (i=0; i<NUMLEDS; i++) {
03a36c ¤   ¤   ¤   iright = ileft + iwidth;
bc67c5 ¤
176316 ¤   ¤   ¤   if (i > pkgi->iStatusValue) {
d81f85 ¤   ¤   ¤   ¤   SelectObject (hdc, hBrushUnlit);
eaa3a6 ¤   ¤   ¤   }
500b1b ¤   ¤   ¤   Rectangle (hdc, ileft, itop, iright, ibot);
6e67c5 ¤
26d352 ¤   ¤   ¤   ileft += iwidth + LEDSPACING;
d80fe4 ¤   ¤   }
9d9371 ¤   }
e2af5a
ac8c3c ¤   SelectObject (hdc, hBrushOld);
ee3570 ¤   SelectObject (hdc, hPenOld);
6515f5 ¤   DeleteObject (hPen);
78ec46 ¤   DeleteObject (hBrushLit);
07183c ¤   DeleteObject (hBrushUnlit);
28af5a
3000b1 ¤   EndPaint (hwnd, &ps);
a6efe6 }
15af5a
abc509 //¤ ____________________________________
1a465d //
489e17 // ·find key with specified user id, if it exists
a2af5a
a8b333 static VOID·
9cdf81 sGetOldKey (PGPContextRef¤  context,·
bbc149 ¤   ¤   ···LPSTR¤   ¤   ¤   szUserID,·
1dac2a ¤   ¤   ···PGPKeyRef*¤  ¤   pOldKey)·
dcbb36 {
33a37c ¤   PGPKeyListRef¤  KeyList;
8eb17a ¤   PGPKeyIterRef¤  KeyIter;
4228cc ¤   PGPKeySetRef¤   KeySet;
517593 ¤   PGPKeyRef¤  ¤   Key;
9f0000 ¤   PGPBoolean¤ ¤   bSecret;
80fb19 ¤   PGPError¤   ¤   err;
e6d5e0 ¤   PGPFilterRef¤   filter¤ = kPGPInvalidRef;
162249 ¤   PGPUInt32¤  ¤   uAlg;
--c99d 000e3b65ad2401102ed Page 10 of PKgenwiz.c
e0af5a
fc6cfb ¤   *pOldKey = NULL;
f4af5a
37bb7e ¤   err¤= PGPNewUserIDStringFilter (context, szUserID, kPGPMatchSubString,·
6848ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &filter);
67b23e ¤   if (IsntPGPError (err)) {
df50e8 ¤   ¤   err¤= PGPFilterKeySet (KeySetMain, filter, &KeySet);¤
101fb8 ¤   ¤   PGPFreeFilter (filter);
cd9371 ¤   }
60af5a
1ef829 ¤   if (KeySet) {
09af5a
209f83 ¤   ¤   PGPOrderKeySet (KeySet, kPGPCreationOrdering, &KeyList);
f2dc25 ¤   ¤   if (KeyList) {
f4af5a
878687 ¤   ¤   ¤   PGPNewKeyIter (KeyList, &KeyIter);
4453f1 ¤   ¤   ¤   if (KeyIter) {
38af5a
7fd569 ¤   ¤   ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
1d954e ¤   ¤   ¤   ¤   while (Key && !*pOldKey) {
aac4a2 ¤   ¤   ¤   ¤   ¤   PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret);
051aef ¤   ¤   ¤   ¤   ¤   if (bSecret) {
d7a82c ¤   ¤   ¤   ¤   ¤   ¤   PGPGetKeyNumber (Key, kPGPKeyPropAlgID, &uAlg);
02f33d ¤   ¤   ¤   ¤   ¤   ¤   if (uAlg == kPGPPublicKeyAlgorithm_RSA) {
b42ae6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   *pOldKey = Key;
b9db3c ¤   ¤   ¤   ¤   ¤   ¤   }
4d1c89 ¤   ¤   ¤   ¤   ¤   }
254328 ¤   ¤   ¤   ¤   ¤   PGPKeyIterNext (KeyIter, &Key);
3e2613 ¤   ¤   ¤   ¤   }
acf541 ¤   ¤   ¤   ¤   PGPFreeKeyIter (KeyIter);
30a3a6 ¤   ¤   ¤   }
707a02 ¤   ¤   ¤   PGPFreeKeyList (KeyList);
760fe4 ¤   ¤   }
14eacc ¤   ¤   PGPFreeKeySet(KeySet);
d59371 ¤   }
a167c5 ¤
27efe6 }
b8af5a
bfaf5a
c8d4d4 //¤ ______________________________________________
13465d //
c1d1da // ·create standard PGP userid from name and email address
e1af5a
a0e9f6 static ULONG·
8f12c6 sCreatePGPUserID (
76f81f ¤   ¤   LPSTR*¤ pszUserID,·
cab6ee ¤   ¤   LPSTR¤  szFullName,·
ca7d9c ¤   ¤   LPSTR¤  szEmail)
c1bb36 {
44d34b ¤   INT iReturnCode = kPGPError_NoErr;
745843 ¤   UINT uUserIDLen = 0;
5ce063 ¤   BOOL bEmail = FALSE;
beaf5a
e83500 ¤   /*+4 is: ·1 for the \0, one for the space, two for the broquets.*/
92c501 ¤   uUserIDLen = lstrlen (szFullName) +1;
b5f208 ¤   if (lstrlen (szEmail)) {
6c2b91 ¤   ¤   bEmail = TRUE;
772abe ¤   ¤   uUserIDLen += lstrlen (szEmail) +3;
f39371 ¤   }
36af5a
8692d2 ¤   *pszUserID = pkAlloc (sizeof(char) * uUserIDLen);
a6c310 ¤   if (*pszUserID) {
88ec5e ¤   ¤   if (bEmail)
6cd0b7 ¤   ¤   ¤   wsprintf (*pszUserID, "%s <%s>", szFullName, szEmail);
8aee26 ¤   ¤   else·
7e3191 ¤   ¤   ¤   lstrcpy (*pszUserID, szFullName);
639371 ¤   }
050e24 ¤   else
eef50f ¤   ¤   iReturnCode = kPGPError_OutOfMemory;
a9af5a
31b195 ¤   return (iReturnCode);
e3efe6 }
--6461 00056782031401102ed Page 11 of PKgenwiz.c
e0af5a
1aaf5a
59d4d4 //¤ ______________________________________________
57465d //
685b81 // ·callback routine called by library key generation routine
b8c69c // ·every so often with status of keygen. ·Returning a nonzero
31e502 // ·value cancels the key generation.
2caf5a
1969c9 static PGPError·
893dfc sKeyGenCallback (
2afb68 ¤   ¤   PGPContextRef¤  context,·
465b49 ¤   ¤   PGPEvent*¤  ¤   event,
18c05f ¤   ¤   PGPUserValue¤   userValue)
73bb36 {
d3f714 ¤   INT¤¤   ¤   ¤   ¤   iReturnCode = kPGPError_NoErr;
8768ff ¤   UINT¤   ¤   ¤   ¤   uOriginalPhase;
f69826 ¤   PKEYGENINFO¤¤   ¤   pkgi;
7de235 ¤   PGPEventKeyGenData* pkgd;
c4af5a
e1a48f ¤   switch (event->type) {
9660a0 ¤   case kPGPEvent_KeyGenEvent:
51e5f8 ¤   ¤   pkgd = &event->data.keyGenData;
31fc71 ¤   ¤   pkgi = (PKEYGENINFO) userValue;
43df83 ¤   ¤   uOriginalPhase = pkgi->uWorkingPhase;
9caf5a
cc866c ¤   ¤   if (!pkgi->bCancelPending) {
e00753 ¤   ¤   ¤   if (pkgd->state == ' ') {
2e45c5 ¤   ¤   ¤   ¤   if (pkgi->uWorkingPhase == IDS_KEYGENPHASE1)
4d4909 ¤   ¤   ¤   ¤   ¤   pkgi->uWorkingPhase = IDS_KEYGENPHASE2;
cafa07 ¤   ¤   ¤   ¤   else
eba66d ¤   ¤   ¤   ¤   ¤   pkgi->uWorkingPhase = IDS_KEYGENPHASE1;
3aa3a6 ¤   ¤   ¤   }
9d1666 ¤   ¤   ¤   if (uOriginalPhase != pkgi->uWorkingPhase)
4ce29d ¤   ¤   ¤   ¤   PostMessage (pkgi->hWndWiz,·
f9ebe7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   KM_M_CHANGEPHASE,·
c0ceac ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
476e83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) pkgi->uWorkingPhase);
ae0fe4 ¤   ¤   }
c4e647 ¤   ¤   else //Let the kernel know we're canceling
37f628 ¤   ¤   ¤   iReturnCode = kPGPError_UnknownError;
60f828 ¤   }¤
3167c5 ¤
8ab195 ¤   return (iReturnCode);
35efe6 }
c6af5a
71af5a
1fd4d4 //¤ ______________________________________________
a5465d //
8fb701 // ·thread for actually creating key
5caf5a
aab333 static VOID·
278dde sKeyGenerationThread (void *pArgs)
00bb36 {
4d86dc ¤   PKEYGENINFO¤¤   ¤   pkgi¤   ¤   ¤   = NULL;
5c5f4a ¤   BOOL¤   ¤   ¤   ¤   bNewDefaultKey¤ = TRUE;
a68b00 ¤   PGPUInt32¤  ¤   ¤   AlgFlags¤   ¤   = 0;
c79cb0 ¤   PGPSize¤¤   ¤   ¤   prefDataSize¤   = 0;
6e8db6 ¤   PGPKeySetRef¤   ¤   keysetADK¤  ¤   = kInvalidPGPKeySetRef;
181ecc ¤   PGPKeySetRef¤   ¤   keysetRevoker¤  = kInvalidPGPKeySetRef;
902d1d ¤   PGPOptionListRef¤   optionlist¤ ¤   = kInvalidPGPOptionListRef;
eb7e26 ¤   PGPCipherAlgorithm*¤pAlgs¤  ¤   ¤   = NULL;
91af5a
3a45f2 ¤   PGPKeyRef¤  ¤   ¤   keyDefault;
65048c ¤   PGPSubKeyRef¤   ¤   subkey;
7c5ef3 ¤   PGPUserIDRef¤   ¤   useridCorp;
6c9988 ¤   PGPBoolean¤ ¤   ¤   bFastGen;
9f8d67 ¤   PGPContextRef¤  ¤   ctx;
9bb552 ¤   PGPByte¤¤   ¤   ¤   enforce;
868f52 ¤   PGPError¤   ¤   ¤   err;
d1a3f4 ¤   INT¤¤   ¤   ¤   ¤   iTrustLevel;
cbe6c8 ¤   PGPUInt32¤  ¤   ¤   numAlgs;
56af5a
--5a68 000bdb1709e401102ed Page 12 of PKgenwiz.c
f68993 ¤   pkgi = (PKEYGENINFO) pArgs;
4a601d ¤   ctx = pkgi->Context;
8baf5a
03c7a4 ¤   PGPGetDefaultPrivateKey (KeySetMain, &keyDefault);
f84eab ¤   if (PGPRefIsValid (keyDefault)) bNewDefaultKey = FALSE;
91af5a
6876ca ¤   // construct userid and check for existing key with same userid
edaf94 ¤   err = sCreatePGPUserID (&pkgi->pszUserID, pkgi->pszFullName,·
05fac3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->pszEmail); CKERR;
f77836 ¤   if (pkgi->uKeyType == kPGPPublicKeyAlgorithm_DSA)
ef1256 ¤   ¤   sGetOldKey (ctx, pkgi->pszUserID, &pkgi->OldKey);
82af5a
a4c1a1 ¤   // get client preferences
442212 ¤   PGPGetPrefBoolean (pkgi->PrefRefClient, kPGPPrefFastKeyGen, &bFastGen);
4723be ¤   PGPGetPrefData (pkgi->PrefRefClient, kPGPPrefAllowedAlgorithmsList,
ee1c27 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··&prefDataSize, &pAlgs);
4daf5a
4dbf60 ¤   // build list of common options
e0bbce ¤   numAlgs¤= prefDataSize / sizeof(PGPCipherAlgorithm);
9de3d9 ¤   err = PGPBuildOptionList (ctx, &optionlist,
cabc0f ¤   ¤   ¤   PGPOKeySetRef (ctx, KeySetMain),
68c3bd ¤   ¤   ¤   PGPOKeyGenParams (ctx, pkgi->uKeyType, pkgi->uKeySize),
738fe0 ¤   ¤   ¤   PGPOKeyGenFast (ctx, bFastGen),
ad60ff ¤   ¤   ¤   PGPOKeyGenName (ctx, pkgi->pszUserID, lstrlen (pkgi->pszUserID)),
e25746 ¤   ¤   ¤   PGPOPassphrase (ctx, pkgi->pszPassPhrase),
2b5672 ¤   ¤   ¤   PGPOExpiration (ctx, pkgi->uExpireDays),
6334ca ¤   ¤   ¤   PGPOPreferredAlgorithms (ctx, pAlgs, numAlgs),
63ee80 ¤   ¤   ¤   PGPOEventHandler (ctx, sKeyGenCallback, pkgi),
b580cc ¤   ¤   ¤   PGPOLastOption (ctx)); CKERR;
baaf5a
25afaa ¤   // add ADK option
1974cc ¤   if (PGPKeyRefIsValid (pkgi->ADK))·
8bc7a1 ¤   {
7fb271 ¤   ¤   if (pkgi->bEnforceADK) enforce = 0x80;
04e7fd ¤   ¤   else enforce = 0x00;
970d46 ¤   ¤   err = PGPNewSingletonKeySet (pkgi->ADK, &keysetADK); CKERR;
04256f ¤   ¤   err = PGPAppendOptionList (optionlist,
cb9538 ¤   ¤   ¤   PGPOAdditionalRecipientRequestKeySet (ctx, keysetADK, enforce),
9c80cc ¤   ¤   ¤   PGPOLastOption (ctx)); CKERR;
b29371 ¤   }
47af5a
997ad8 ¤   // add revoker key option
8d616a ¤   if ((PGPKeyRefIsValid (pkgi->RevokerKey)) &&
b95a17 ¤   ¤   (pkgi->uKeyType != kPGPPublicKeyAlgorithm_RSA))·
b1c7a1 ¤   {
eb2e76 ¤   ¤   err = PGPNewSingletonKeySet (pkgi->RevokerKey, &keysetRevoker); CKERR;
d0256f ¤   ¤   err = PGPAppendOptionList (optionlist,
cbb17c ¤   ¤   ¤   ¤   PGPORevocationKeySet (ctx, keysetRevoker),
62b909 ¤   ¤   ¤   ¤   PGPOLastOption (ctx)); CKERR;
649371 ¤   }
7faf5a
c69aa3 ¤   // generate key using specified options
8c66e9 ¤   err = PGPGenerateKey (ctx, &(pkgi->Key),·
b34bdb ¤   ¤   ¤   ¤   ¤   ¤   ¤   optionlist,
3ae6ca ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (ctx));·
03af5a
ec10c1 ¤   // note: PGPGenerateKey returns kPGPError_OutOfMemory when user aborts!
23c4ac ¤   if (err == kPGPError_OutOfMemory)·
590fd8 ¤   ¤   err = kPGPError_UserAbort;
df4339 ¤   CKERR;
5aaf5a
7bd6ca ¤   if (pkgi->uKeyType == kPGPPublicKeyAlgorithm_DSA) {
54bff5 ¤   ¤   err = PGPGenerateSubKey (
bc5fa1 ¤   ¤   ¤   ctx, &subkey,
323644 ¤   ¤   ¤   PGPOKeyGenMasterKey (ctx, pkgi->Key),
9a6a35 ¤   ¤   ¤   PGPOKeyGenParams (ctx, kPGPPublicKeyAlgorithm_ElGamal,·
703878 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->uSubKeySize),
3d8fe0 ¤   ¤   ¤   PGPOKeyGenFast (ctx, bFastGen),
1e5746 ¤   ¤   ¤   PGPOPassphrase (ctx, pkgi->pszPassPhrase),
6a5672 ¤   ¤   ¤   PGPOExpiration (ctx, pkgi->uExpireDays),
0aee80 ¤   ¤   ¤   PGPOEventHandler (ctx, sKeyGenCallback, pkgi),
bda400 ¤   ¤   ¤   PGPOLastOption (ctx));
--3732 000941f6433401102ed Page 13 of PKgenwiz.c
e0af5a
04573b ¤   ¤   ¤   // note: PGPGenerateSubKey returns kPGPError_OutOfMemory·
f9de63 ¤   ¤   ¤   // when user aborts!
535b78 ¤   ¤   ¤   if (err == kPGPError_OutOfMemory)·
c54067 ¤   ¤   ¤   ¤   err = kPGPError_UserAbort;
1f9371 ¤   }
3baf5a
b8e1a9 ¤   if (IsntPGPError (err) && !pkgi->bCancelPending)·
bdc7a1 ¤   {
ef990d ¤   ¤   // sign and trust corporate key
0b8bb6 ¤   ¤   if (PGPKeyRefIsValid (pkgi->CorpKey))·
db5b34 ¤   ¤   {
538865 ¤   ¤   ¤   err = PGPGetPrimaryUserID (pkgi->CorpKey, &useridCorp);
b63da8 ¤   ¤   ¤   if (IsntPGPError (err))·
99f776 ¤   ¤   ¤   {
fe1148 ¤   ¤   ¤   ¤   if (pkgi->bMetaCorpKey) iTrustLevel = 2;
20096e ¤   ¤   ¤   ¤   else iTrustLevel = 0;
59af5a
c4f44d ¤   ¤   ¤   ¤   // make sure we have enough entropy
dd0c99 ¤   ¤   ¤   ¤   PGPclRandom (ctx, pkgi->hWndWiz, 0);
16af5a
d7caba ¤   ¤   ¤   ¤   err = PGPSignUserID (useridCorp, pkgi->Key,·
09509f ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (ctx, pkgi->pszPassPhrase),
0df189 ¤   ¤   ¤   ¤   ¤   PGPOExpiration (ctx, 0),
47f247 ¤   ¤   ¤   ¤   ¤   PGPOExportable (ctx, FALSE),
d563ce ¤   ¤   ¤   ¤   ¤   PGPOSigTrust (ctx, iTrustLevel, kPGPKeyTrust_Complete),
e3ebbf ¤   ¤   ¤   ¤   ¤   PGPOLastOption (ctx));
9d3845 ¤   ¤   ¤   ¤   if (IsntPGPError (err))·
4172c3 ¤   ¤   ¤   ¤   {
e152d9 ¤   ¤   ¤   ¤   ¤   err = PGPSetKeyTrust (pkgi->CorpKey,·
6c9093 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyTrust_Complete);
3a2491 ¤   ¤   ¤   ¤   ¤   // ignore errors here. ·If key is axiomatic,·
0b6eba ¤   ¤   ¤   ¤   ¤   // setting trust will cause an error.
07e8ab ¤   ¤   ¤   ¤   ¤   err = kPGPError_NoErr;·
792613 ¤   ¤   ¤   ¤   }
f3a3a6 ¤   ¤   ¤   }
090fe4 ¤   ¤   }
90165e ¤   ¤   // commit everything now so if there is a problem
ffdcbd ¤   ¤   // during keyserver stuff, at least the key is saved
178880 ¤   ¤   if (IsntPGPError (PGPclErrorBox (pkgi->hWndWiz, err)))·
9b5b34 ¤   ¤   {
5ff102 ¤   ¤   ¤   err = PGPCommitKeyRingChanges (KeySetMain);
55e5b6 ¤   ¤   ¤   PGPclErrorBox (pkgi->hWndWiz, err);
c55843 ¤   ¤   ¤   pkgi->iFinalResult = KCD_NEWKEY;
a1f49d ¤   ¤   ¤   if (bNewDefaultKey)
464a74 ¤   ¤   ¤   ¤   pkgi->iFinalResult |= KCD_NEWDEFKEY;
700fe4 ¤   ¤   }
b39371 ¤   }
b8af5a
bea1c0 done :
fce687 ¤   if (IsntNull (pAlgs))
663f5a ¤   ¤   PGPDisposePrefData (pkgi->PrefRefClient, pAlgs);
ab0675 ¤   if (PGPKeySetRefIsValid (keysetADK))
fbc794 ¤   ¤   PGPFreeKeySet (keysetADK);
135005 ¤   if (PGPKeySetRefIsValid (keysetRevoker))
1e44b5 ¤   ¤   PGPFreeKeySet (keysetRevoker);
07932a ¤   if (PGPOptionListRefIsValid (optionlist))
8453e8 ¤   ¤   PGPFreeOptionList (optionlist);
66af5a
38b275 ¤   pkgi->bInGeneration = FALSE;
7baf5a
d17580 ¤   PGPclErrorBox (pkgi->hWndWiz, err);
90af5a
965cdc ¤   if (pkgi->bCancelPending) {
5b54d3 ¤   ¤   PropSheet_PressButton (GetParent (pkgi->hWndWiz), PSBTN_CANCEL);
4c9371 ¤   }
2e665a ¤   else {
c31b5a ¤   ¤   PostMessage (pkgi->hWndWiz, KM_M_GENERATION_COMPLETE, 0, 0);
9e9371 ¤   }
eeefe6 }
7baf5a
94af5a
--7be0 000b9f35867401102ed Page 14 of PKgenwiz.c
cfd4d4 //¤ ______________________________________________
0f465d //
c7a9a0 // ·Check if message is dangerous to pass to passphrase edit box
f6af5a
ca6c77 static BOOL·
80ce5d sWizCommonNewKeyPhraseMsgProc (
ec47b2 ¤   ¤   HWND¤   hWnd,·
4beb77 ¤   ¤   UINT¤   uMsg,·
6417d4 ¤   ¤   WPARAM¤ wParam,·
4fc0b8 ¤   ¤   LPARAM¤ lParam)·
6abb36 {
5a347f ¤   switch (uMsg) {
1e7082 ¤   case WM_RBUTTONDOWN :
404919 ¤   case WM_LBUTTONDBLCLK :
92e1c7 ¤   case WM_MOUSEMOVE :
a425e1 ¤   case WM_COPY :
c00cce ¤   case WM_CUT :
18c986 ¤   case WM_PASTE :
a26abf ¤   case WM_CLEAR :
ec651b ¤   case WM_CONTEXTMENU :
cc836c ¤   ¤   return TRUE;
eeaf5a
49475b ¤   case WM_LBUTTONDOWN :
4be851 ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000) return TRUE;
132f68 ¤   ¤   break;
2aaf5a
1285ca ¤   case WM_PAINT :
a7604e ¤   ¤   if (wParam) {
14c559 ¤   ¤   ¤   SetBkColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
e71fd7 ¤   ¤   ¤   if (bHideTyping)·
deb25f ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
c56b93 ¤   ¤   ¤   else·
0bf4fd ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOWTEXT));
ef0fe4 ¤   ¤   }
0bca2d ¤   ¤   break;·
b5af5a
49507d ¤   case WM_KEYDOWN :
d91c37 ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000) {
8b4cf7 ¤   ¤   ¤   switch (wParam) {
eb8ada ¤   ¤   ¤   ¤   case VK_HOME :
8a000e ¤   ¤   ¤   ¤   case VK_END :
b1e8e7 ¤   ¤   ¤   ¤   case VK_UP :
2a03bd ¤   ¤   ¤   ¤   case VK_DOWN :
005454 ¤   ¤   ¤   ¤   case VK_LEFT :
d6ceff ¤   ¤   ¤   ¤   case VK_RIGHT :
59b617 ¤   ¤   ¤   ¤   case VK_NEXT :
8b443f ¤   ¤   ¤   ¤   case VK_PRIOR :
e1bdb6 ¤   ¤   ¤   ¤   ¤   return TRUE;
8aa3a6 ¤   ¤   ¤   }
670fe4 ¤   ¤   }
892f68 ¤   ¤   break;
10af5a
5e524f ¤   case WM_SETFOCUS :
e1908d ¤   ¤   SendMessage (hWnd, EM_SETSEL, 0xFFFF, 0xFFFF);
2c2f68 ¤   ¤   break;
2daf5a
36f4f5 ¤   case WM_KILLFOCUS :
5c2f68 ¤   ¤   break;
5f9371 ¤   }
f5146d ¤   return FALSE;·
66a79b }·
33af5a
bdaf5a
1ed4d4 //¤ ______________________________________________
79465d //
bcab27 // ·New passphrase 1 edit box subclass procedure
a7af5a
47d0ac static LRESULT APIENTRY·
b44947 sWizPhrase1SubclassProc (
d847b2 ¤   ¤   HWND¤   hWnd,·
42eb77 ¤   ¤   UINT¤   uMsg,·
b917d4 ¤   ¤   WPARAM¤ wParam,·
--87ee 000c95301c5401102ed Page 15 of PKgenwiz.c
a4c0b8 ¤   ¤   LPARAM¤ lParam)·
debb36 {
ec4eee ¤   UINT¤   ¤   ¤   ¤   uQuality;
f34c06 ¤   CHAR¤   ¤   ¤   ¤   szBuf[256];
7f07ef ¤   LRESULT¤¤   ¤   ¤   lResult;
d9af5a
d5dd32 ¤   if (sWizCommonNewKeyPhraseMsgProc (hWnd, uMsg, wParam, lParam)) return 0;
27347f ¤   switch (uMsg) {
21da21 ¤   case WM_GETTEXT :
e761f3 ¤   ¤   wParam = lPhrase1Len;
6278b4 ¤   ¤   lParam = (LPARAM)szPhrase1;
582f68 ¤   ¤   break;
a0af5a
0e4621 ¤   case WM_CHAR :
7dc5a3 ¤   ¤   switch (wParam) {
032912 ¤   ¤   case VK_TAB :
c9afb3 ¤   ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000)·
c11b83 ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd), IDC_DUMMYSTOP));
a36b93 ¤   ¤   ¤   else·
79b7f7 ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd),·
d0861d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_EDIT_PASSPHRASE2));
7acdcb ¤   ¤   ¤   break;
d4af5a
df323e ¤   ¤   case VK_RETURN :
a8f776 ¤   ¤   ¤   {
39f650 ¤   ¤   ¤   ¤   HWND hGrandParent = GetParent (GetParent (hWnd));
b0330b ¤   ¤   ¤   ¤   PropSheet_PressButton (hGrandParent, PSBTN_NEXT);
c4a3a6 ¤   ¤   ¤   }
fecdcb ¤   ¤   ¤   break;
37af5a
baaf5a
e23a18 ¤   ¤   default :
21eb50 ¤   ¤   ¤   lResult = CallWindowProc (wpOrigPhrase1Proc,·
3aa230 ¤   ¤   ¤   ¤   ¤   ¤   hWnd, uMsg, wParam, lParam);·
2b9ac0 ¤   ¤   ¤   CallWindowProc (wpOrigPhrase1Proc,·
6de69f ¤   ¤   ¤   ¤   ¤   ¤   hWnd, WM_GETTEXT, sizeof(szBuf), (LPARAM)szBuf);·
c96ff7 ¤   ¤   ¤   uQuality = PGPEstimatePassphraseQuality (szBuf);
c86ae6 ¤   ¤   ¤   memset (szBuf, 0, sizeof(szBuf));
80b154 ¤   ¤   ¤   SendDlgItemMessage (GetParent (hWnd), IDC_PHRASEQUALITY,·
6f6745 ¤   ¤   ¤   ¤   ¤   ¤   PBM_SETPOS, uQuality, 0);
71e225 ¤   ¤   ¤   return lResult;
65af5a
970fe4 ¤   ¤   }
312f68 ¤   ¤   break;
0caf5a
509371 ¤   }
dde538 ¤   return CallWindowProc(wpOrigPhrase1Proc, hWnd, uMsg, wParam, lParam);·
f8a79b }·
bdaf5a
b6af5a
6cd4d4 //¤ ______________________________________________
b1465d //
abca32 // ·New passphrase 2 edit box subclass procedure
e7af5a
b5d0ac static LRESULT APIENTRY·
dad366 sWizPhrase2SubclassProc (
3747b2 ¤   ¤   HWND¤   hWnd,·
8feb77 ¤   ¤   UINT¤   uMsg,·
b417d4 ¤   ¤   WPARAM¤ wParam,·
c6c0b8 ¤   ¤   LPARAM¤ lParam)·
36bb36 {
4faf5a
26dd32 ¤   if (sWizCommonNewKeyPhraseMsgProc (hWnd, uMsg, wParam, lParam)) return 0;
4d347f ¤   switch (uMsg) {
50da21 ¤   case WM_GETTEXT :
7d6d8e ¤   ¤   wParam = lPhrase2Len;
9997d0 ¤   ¤   lParam = (LPARAM)szPhrase2;
912f68 ¤   ¤   break;
dbaf5a
e54621 ¤   case WM_CHAR :
d5c5a3 ¤   ¤   switch (wParam) {
c92912 ¤   ¤   case VK_TAB :
--e760 000b84390b1401102ed Page 16 of PKgenwiz.c
80afb3 ¤   ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000)·
598945 ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd), IDC_EDIT_PASSPHRASE));
1f6b93 ¤   ¤   ¤   else·
deb7f7 ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd),·
ab90fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_CHECK_HIDE_TYPING));
c9cdcb ¤   ¤   ¤   break;
56af5a
0a323e ¤   ¤   case VK_RETURN :
0af776 ¤   ¤   ¤   {
e8f650 ¤   ¤   ¤   ¤   HWND hGrandParent = GetParent (GetParent (hWnd));
4e330b ¤   ¤   ¤   ¤   PropSheet_PressButton (hGrandParent, PSBTN_NEXT);
f9a3a6 ¤   ¤   ¤   }
b3cdcb ¤   ¤   ¤   break;
260fe4 ¤   ¤   }
ac2f68 ¤   ¤   break;
de9371 ¤   }
9623c8 ¤   return CallWindowProc(wpOrigPhrase2Proc, hWnd, uMsg, wParam, lParam);·
d9a79b }·
c3af5a
f6af5a
c2d4d4 //¤ ______________________________________________
d1465d //
9c6967 // ·Signing passphrase edit box subclass procedure
33af5a
7fd0ac static LRESULT APIENTRY·
a55d76 sWizPhrase3SubclassProc (
4147b2 ¤   ¤   HWND¤   hWnd,·
1eeb77 ¤   ¤   UINT¤   uMsg,·
4517d4 ¤   ¤   WPARAM¤ wParam,·
acc0b8 ¤   ¤   LPARAM¤ lParam)·
d2bb36 {
f0af5a
bfdd32 ¤   if (sWizCommonNewKeyPhraseMsgProc (hWnd, uMsg, wParam, lParam)) return 0;
fc347f ¤   switch (uMsg) {
77da21 ¤   case WM_GETTEXT :
1e61f3 ¤   ¤   wParam = lPhrase1Len;
9378b4 ¤   ¤   lParam = (LPARAM)szPhrase1;
1c2f68 ¤   ¤   break;
96af5a
104621 ¤   case WM_CHAR :
f7c5a3 ¤   ¤   switch (wParam) {
362912 ¤   ¤   case VK_TAB :
86afb3 ¤   ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000)·
7c0dfb ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd), IDC_CHECK_SIGN_KEY));
916b93 ¤   ¤   ¤   else·
1cb7f7 ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (GetParent (hWnd),·
261ab9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_CHECK_HIDE_TYPING));
e4cdcb ¤   ¤   ¤   break;
69af5a
9f323e ¤   ¤   case VK_RETURN :
faf776 ¤   ¤   ¤   {
acf650 ¤   ¤   ¤   ¤   HWND hGrandParent = GetParent (GetParent (hWnd));
42330b ¤   ¤   ¤   ¤   PropSheet_PressButton (hGrandParent, PSBTN_NEXT);
dca3a6 ¤   ¤   ¤   }
60cdcb ¤   ¤   ¤   break;
8d0fe4 ¤   ¤   }
b12f68 ¤   ¤   break;
5f9371 ¤   }
b1e538 ¤   return CallWindowProc(wpOrigPhrase1Proc, hWnd, uMsg, wParam, lParam);·
19a79b }·
7daf5a
53af5a
6dbf56 //----------------------------------------------------|
226cdf // ·Dialog procedure for "Finish" dialog
baaf5a
875678 static LRESULT WINAPI·
026f91 sKeyWizardDoneDlgProc (
8c3a3a ¤   ¤   HWND¤   hDlg,·
5eeb77 ¤   ¤   UINT¤   uMsg,·
a517d4 ¤   ¤   WPARAM¤ wParam,·
e1c0b8 ¤   ¤   LPARAM¤ lParam)·
b8bb36 {
--7a64 0009a6e4a79401102ed Page 17 of PKgenwiz.c
f42ccd ¤   PKEYGENINFO¤¤   pkgi;
4a0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
7aaf5a
d0347f ¤   switch (uMsg) {
342940 ¤   case WM_INITDIALOG:
ce5b34 ¤   ¤   {
62509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
73e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
b1423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
31cdcb ¤   ¤   ¤   break;
240fe4 ¤   ¤   }
a0af5a
9485ca ¤   case WM_PAINT :
ea2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
3fd515 ¤   ¤   if (pkgi->hPalette)
745b34 ¤   ¤   {
7af431 ¤   ¤   ¤   PAINTSTRUCT ps;
ae638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
01cada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
b29ffe ¤   ¤   ¤   RealizePalette (hDC);
065dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
5e0fe4 ¤   ¤   }
f72f68 ¤   ¤   break;
b9af5a
a1c93c ¤   case WM_NOTIFY:
0eed49 ¤   ¤   {¤
0b5808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
c0af5a
57e55c ¤   ¤   ¤   switch (pnmh->code) {
4f66bc ¤   ¤   ¤   case PSN_SETACTIVE:
06577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
84ab95 ¤   ¤   ¤   ¤   if (pkgi->bDoSend)
869a83 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent (hDlg),·
b6cdf1 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
b25109 ¤   ¤   ¤   ¤   else·
d99a83 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent (hDlg),·
4a144b ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_FINISH);
00af5a
dfc3aa ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
7454b0 ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
2b84a6 ¤   ¤   ¤   ¤   if ((!pkgi->bDoSend) || (!pkgi->bSendComplete)) {
ab08c4 ¤   ¤   ¤   ¤   ¤   CHAR szText[256];
dc7b6e ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_SENDLATER,·
e68161 ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
b450ec ¤   ¤   ¤   ¤   ¤   SetDlgItemText(hDlg, IDC_STATIC_KS_TEXT, szText);
452613 ¤   ¤   ¤   ¤   }
d6deaa ¤   ¤   ¤   ¤   else {
de4e43 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (GetParent (hDlg), IDCANCEL),
85324e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
ac2613 ¤   ¤   ¤   ¤   }
a6f095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
17841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
94f622 ¤   ¤   ¤   ¤   break;
c4af5a
2fb546 ¤   ¤   ¤   case PSN_WIZFINISH:
52577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
368ed6 ¤   ¤   ¤   ¤   pkgi->bFinishSelected = TRUE;
6a0086 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
f1841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
27f622 ¤   ¤   ¤   ¤   break;
77af5a
6f6122 ¤   ¤   ¤   case PSN_HELP:
075535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
5fe51b ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_DONE);·
c7f622 ¤   ¤   ¤   ¤   break;
88af5a
858f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
11f622 ¤   ¤   ¤   ¤   break;
28a3a6 ¤   ¤   ¤   }
5bcdcb ¤   ¤   ¤   break;
d00fe4 ¤   ¤   }
9a9371 ¤   }
--4259 000a9cd4859401102ed Page 18 of PKgenwiz.c
e0af5a
188ca8 ¤   return bReturnCode;
18efe6 }
65af5a
80af5a
a9d4d4 //¤ ______________________________________________
4f465d //
53b993 // ·Dialog procedure for displaying keyserver communication status
e1af5a
ac5678 static LRESULT WINAPI·
a3df52 sKeyWizardSendToServerDlgProc (
a43a3a ¤   ¤   HWND¤   hDlg,·
52eb77 ¤   ¤   UINT¤   uMsg,·
f017d4 ¤   ¤   WPARAM¤ wParam,·
39c0b8 ¤   ¤   LPARAM¤ lParam)·
62bb36 {
be9826 ¤   PKEYGENINFO¤¤   ¤   pkgi;
472e99 ¤   BOOL¤   ¤   ¤   ¤   bReturnCode = FALSE;
c0737c ¤   static PGPKeySetRef¤keysetSend;¤¤   ¤
85af5a
3c347f ¤   switch (uMsg) {
742940 ¤   case WM_INITDIALOG:
ba5b34 ¤   ¤   {
14509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
94e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
a9423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
12cdcb ¤   ¤   ¤   break;
150fe4 ¤   ¤   }
97af5a
7085ca ¤   case WM_PAINT :
c82463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
54a17e ¤   ¤   if (pkgi->hPalette) {
06f431 ¤   ¤   ¤   PAINTSTRUCT ps;
e0638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
8ecada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
ff9ffe ¤   ¤   ¤   RealizePalette (hDC);
165dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
680fe4 ¤   ¤   }
e3330a ¤   ¤   sDrawSendStatus (GetDlgItem (hDlg, IDC_PROGRESS), pkgi);
122f68 ¤   ¤   break;
1c67c5 ¤
295122 ¤   case WM_TIMER :
522463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
de85d1 ¤   ¤   pkgi->iStatusValue += pkgi->iStatusDirection;
cd0649 ¤   ¤   if (pkgi->iStatusValue <= 0) {
8b0de8 ¤   ¤   ¤   pkgi->iStatusValue = 0;
5ae9e4 ¤   ¤   ¤   pkgi->iStatusDirection = 1;
4b0fe4 ¤   ¤   }
1f001c ¤   ¤   else if (pkgi->iStatusValue >= NUMLEDS-1) {
4249a8 ¤   ¤   ¤   pkgi->iStatusValue = NUMLEDS-1;
b4860c ¤   ¤   ¤   pkgi->iStatusDirection = -1;
c80fe4 ¤   ¤   }
efea47 ¤   ¤   InvalidateRect (hDlg, NULL, FALSE);
492f68 ¤   ¤   break;
2aaf5a
51c93c ¤   case WM_NOTIFY:
832463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
365b34 ¤   ¤   {
225808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
3eaf5a
48e55c ¤   ¤   ¤   switch (pnmh->code) {
e666bc ¤   ¤   ¤   case PSN_SETACTIVE:
fb577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
7a596c ¤   ¤   ¤   ¤   if (!pkgi->bDoSend) {
f60001 ¤   ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, -1L); // skip
954149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
a72613 ¤   ¤   ¤   ¤   }
a2deaa ¤   ¤   ¤   ¤   else {
241e7c ¤   ¤   ¤   ¤   ¤   pkgi->bSendInProgress = FALSE;
c4536a ¤   ¤   ¤   ¤   ¤   pkgi->iStatusValue = -1;
1679d2 ¤   ¤   ¤   ¤   ¤   pkgi->iStatusDirection = 1;
a94351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
--9099 000c2fca188401102ed Page 19 of PKgenwiz.c
d01a50 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, 0);
a7d8a3 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
3b5452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
8ea7e5 ¤   ¤   ¤   ¤   ¤   PGPNewSingletonKeySet (pkgi->Key, &keysetSend);
72bede ¤   ¤   ¤   ¤   ¤   PGPclSendKeysToRootServerNotify (pkgi->Context,·
231c37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->tlsContext, hDlg,·
15b07f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KeySetMain, keysetSend);
d7e2c7 ¤   ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);·
334149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
f32613 ¤   ¤   ¤   ¤   }
c6f622 ¤   ¤   ¤   ¤   break;
68af5a
cbb86b ¤   ¤   ¤   case PSN_KILLACTIVE :
b1f370 ¤   ¤   ¤   ¤   KillTimer (hDlg, LEDTIMER);
1ef622 ¤   ¤   ¤   ¤   break;
d6af5a
3ac5a9 ¤   ¤   ¤   case PGPCL_SERVERPROGRESS :
ef72c3 ¤   ¤   ¤   ¤   {
a5748a ¤   ¤   ¤   ¤   ¤   PPGPclSERVEREVENT pEvent = (PPGPclSERVEREVENT)lParam;
24ec61 ¤   ¤   ¤   ¤   ¤   if (!(pkgi->bSendInProgress)) {
efe3cf ¤   ¤   ¤   ¤   ¤   ¤   pkgi->bSendInProgress = TRUE;
b7588b ¤   ¤   ¤   ¤   ¤   ¤   pkgi->iStatusValue = 0;
bc3099 ¤   ¤   ¤   ¤   ¤   ¤   if (pEvent->step == PGPCL_SERVERINFINITE) {
a4ba3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->iStatusDirection = 1;
9861f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTimer (hDlg, LEDTIMER, LEDTIMERPERIOD, NULL);
78db3c ¤   ¤   ¤   ¤   ¤   ¤   }
872863 ¤   ¤   ¤   ¤   ¤   ¤   else {
1ce0e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->iStatusDirection = 0;
27ceca ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->iStatusValue = 0;
aedb3c ¤   ¤   ¤   ¤   ¤   ¤   }
f21c89 ¤   ¤   ¤   ¤   ¤   }
043c4b ¤   ¤   ¤   ¤   ¤   else {
98ff1f ¤   ¤   ¤   ¤   ¤   ¤   if (pEvent->step != PGPCL_SERVERINFINITE) {
70e0e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->iStatusDirection = 0;
3b1512 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->iStatusValue = (pEvent->step * 9) /
0413d8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pEvent->total;
2008c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (GetDlgItem (hDlg, IDC_PROGRESS),
98d29b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
addb3c ¤   ¤   ¤   ¤   ¤   ¤   }
5b1c89 ¤   ¤   ¤   ¤   ¤   }
7ca6b2 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PROGRESSTEXT,·
a43ddf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pEvent->szmessage);
c1e757 ¤   ¤   ¤   ¤   ¤   pEvent->cancel = pkgi->bCancelPending;
6ee143 ¤   ¤   ¤   ¤   ¤   return FALSE;
df2613 ¤   ¤   ¤   ¤   }
92af5a
02b531 ¤   ¤   ¤   case PGPCL_SERVERDONE :·
cd9991 ¤   ¤   ¤   ¤   ¤   pkgi->bSendComplete = TRUE;
35d8fd ¤   ¤   ¤   case PGPCL_SERVERABORT :·
d46b11 ¤   ¤   ¤   case PGPCL_SERVERERROR :·
d3577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
6f72c3 ¤   ¤   ¤   ¤   {
26aacd ¤   ¤   ¤   ¤   ¤   PPGPclSERVEREVENT¤  pEvent = (PPGPclSERVEREVENT)lParam;
00af5a
1ceb20 ¤   ¤   ¤   ¤   ¤   KillTimer (hDlg, LEDTIMER);
d3536a ¤   ¤   ¤   ¤   ¤   pkgi->iStatusValue = -1;
9c79d2 ¤   ¤   ¤   ¤   ¤   pkgi->iStatusDirection = 1;
f3926d ¤   ¤   ¤   ¤   ¤   InvalidateRect (GetDlgItem (hDlg, IDC_PROGRESS),
3ad29b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
87af5a
10a6b2 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PROGRESSTEXT,·
5f3ddf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pEvent->szmessage);
894351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
9b69e2 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
0d4e43 ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (GetParent (hDlg), IDCANCEL),
14324e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
a5df7b ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_PROGRESS), SW_HIDE);
00af5a
1b6fc0 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet (keysetSend);
8eaf5a
dfe757 ¤   ¤   ¤   ¤   ¤   pEvent->cancel = pkgi->bCancelPending;
c2e143 ¤   ¤   ¤   ¤   ¤   return FALSE;
--d815 00004fae0da401102ed Page 20 of PKgenwiz.c
862613 ¤   ¤   ¤   ¤   }
fdaf5a
3b6122 ¤   ¤   ¤   case PSN_HELP:
7c5535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
65c07e ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_SEND);·
e4f622 ¤   ¤   ¤   ¤   break;
0faf5a
5f8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
53577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
afa95d ¤   ¤   ¤   ¤   if (!pkgi->bSendComplete) {
c848d4 ¤   ¤   ¤   ¤   ¤   CHAR¤   ¤   ¤   ¤   sz[128];
d7af5a
61d2fd ¤   ¤   ¤   ¤   ¤   pkgi->bCancelPending = TRUE;
0a0c34 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_CANCELING, sz, sizeof(sz));
907a2e ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PROGRESSTEXT, sz);
6c82ae ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L);·
b84149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ed2613 ¤   ¤   ¤   ¤   }
89f622 ¤   ¤   ¤   ¤   break;
91a3a6 ¤   ¤   ¤   }
cfcdcb ¤   ¤   ¤   break;
ce0fe4 ¤   ¤   }
e89371 ¤   }
5eaf5a
3e8ca8 ¤   return bReturnCode;
74efe6 }
1eaf5a
28af5a
81d4d4 //¤ ______________________________________________
6f465d //
2dc9b6 // ·Dialog procedure for querying about sending to keyserver
0faf5a
8e5678 static LRESULT WINAPI·
a11f1c sKeyWizardPreSendDlgProc (
7c3a3a ¤   ¤   HWND¤   hDlg,·
2ceb77 ¤   ¤   UINT¤   uMsg,·
1a17d4 ¤   ¤   WPARAM¤ wParam,·
48c0b8 ¤   ¤   LPARAM¤ lParam)·
a4bb36 {
482ccd ¤   PKEYGENINFO¤¤   pkgi;
750f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
caaf5a
01347f ¤   switch (uMsg) {
872940 ¤   case WM_INITDIALOG:
db5b34 ¤   ¤   {
f1509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
32e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
44423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
8baf5a
b7714c ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CHECK_SEND,·
fcc5af ¤   ¤   ¤   ¤   BM_SETCHECK, BST_UNCHECKED, 0);
abcdcb ¤   ¤   ¤   break;
d20fe4 ¤   ¤   }
0caf5a
3e85ca ¤   case WM_PAINT :
962463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
a2d515 ¤   ¤   if (pkgi->hPalette)
b65b34 ¤   ¤   {
99f431 ¤   ¤   ¤   PAINTSTRUCT ps;
dd638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
bacada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
859ffe ¤   ¤   ¤   RealizePalette (hDC);
205dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
960fe4 ¤   ¤   }
552f68 ¤   ¤   break;
fdaf5a
cd3fcf ¤   case WM_COMMAND:
351185 ¤   ¤   switch (LOWORD (wParam)) {
319c83 ¤   ¤   case IDC_CHECK_SEND:
21190d ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
016ba3 ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_CHECK_SEND) ==·
042279 ¤   ¤   ¤   ¤   BST_CHECKED) {
--6c38 00027058fc5401102ed Page 21 of PKgenwiz.c
e9a294 ¤   ¤   ¤   ¤   pkgi->bDoSend = TRUE;
3fa3a6 ¤   ¤   ¤   }
e2e543 ¤   ¤   ¤   else {
b3e34c ¤   ¤   ¤   ¤   pkgi->bDoSend = FALSE;
ffa3a6 ¤   ¤   ¤   }
a8cdcb ¤   ¤   ¤   break;
da0fe4 ¤   ¤   }
9b2f68 ¤   ¤   break;
82af5a
c1c93c ¤   case WM_NOTIFY:
0f5b34 ¤   ¤   {
f55808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
5faf5a
41e55c ¤   ¤   ¤   switch (pnmh->code) {
8266bc ¤   ¤   ¤   case PSN_SETACTIVE:
d8577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
7e9be3 ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
44e6b5 ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
c6c3aa ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
e854b0 ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
baf095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
de841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c7f622 ¤   ¤   ¤   ¤   break;
46af5a
7eb86b ¤   ¤   ¤   case PSN_KILLACTIVE :
88577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
adb3fd ¤   ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_CHECK_SEND)·
9f756e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   == BST_CHECKED) {
779e7a ¤   ¤   ¤   ¤   ¤   pkgi->bDoSend = TRUE;
0c2613 ¤   ¤   ¤   ¤   }
0e5810 ¤   ¤   ¤   ¤   else pkgi->bDoSend = FALSE;
8ef095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
f2841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
29f622 ¤   ¤   ¤   ¤   break;
dfaf5a
d26122 ¤   ¤   ¤   case PSN_HELP:
c95535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
35479f ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_PRESEND);·
4ef622 ¤   ¤   ¤   ¤   break;
ceaf5a
568f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
d7f622 ¤   ¤   ¤   ¤   break;
8fa3a6 ¤   ¤   ¤   }
73cdcb ¤   ¤   ¤   break;
650fe4 ¤   ¤   }
149371 ¤   }
76af5a
6f8ca8 ¤   return bReturnCode;
76efe6 }
bdaf5a
b1af5a
04d4d4 //¤ ______________________________________________
00465d //
1b0c0c // ·Dialog procedure for querying user about signing new
cfda7f // ·key with old key
9eaf5a
7d5678 static LRESULT WINAPI·
dc5445 sKeyWizardSignOldDlgProc (
143a3a ¤   ¤   HWND¤   hDlg,·
f9eb77 ¤   ¤   UINT¤   uMsg,·
9517d4 ¤   ¤   WPARAM¤ wParam,·
95c0b8 ¤   ¤   LPARAM¤ lParam)·
c4bb36 {
782ccd ¤   PKEYGENINFO¤¤   pkgi;
6c0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
e77ad4 ¤   PGPBoolean¤ ¤   bNeedsPhrase;
b81d3c ¤   static HBRUSH¤  hBrushEdit;
b2af5a
29347f ¤   switch (uMsg) {
762940 ¤   case WM_INITDIALOG:
595b34 ¤   ¤   {
27509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
--b064 000c1921968401102ed Page 22 of PKgenwiz.c
e7e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
9c423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
00af5a
648d84 ¤   ¤   ¤   wpOrigPhrase1Proc = (WNDPROC) SetWindowLong (GetDlgItem (hDlg,·
27111a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_EDIT_PASSPHRASE),·
62f2c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
2147fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LONG) sWizPhrase3SubclassProc);·
62af5a
bf8bc0 ¤   ¤   ¤   hBrushEdit = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
cecdcb ¤   ¤   ¤   break;
a80fe4 ¤   ¤   }
dcaf5a
3685ca ¤   case WM_PAINT :
9b2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
f8d515 ¤   ¤   if (pkgi->hPalette)
d25b34 ¤   ¤   {
24f431 ¤   ¤   ¤   PAINTSTRUCT ps;
78638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
3ccada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
cb9ffe ¤   ¤   ¤   RealizePalette (hDC);
985dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
000fe4 ¤   ¤   }
892f68 ¤   ¤   break;
35af5a
5a95f7 ¤   case WM_CTLCOLOREDIT:
feaa00 ¤   ¤   if (((HWND)lParam == GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE)) ||
9e3345 ¤   ¤   ¤   ((HWND)lParam == GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE2))) {
e1c559 ¤   ¤   ¤   SetBkColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
321fd7 ¤   ¤   ¤   if (bHideTyping)·
bd2e70 ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor(COLOR_WINDOW));
756b93 ¤   ¤   ¤   else·
7fe58d ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
a947cc ¤   ¤   ¤   return (BOOL)hBrushEdit;
230fe4 ¤   ¤   }
a12f68 ¤   ¤   break;
f0af5a
a5a96f ¤   case WM_DESTROY:·
ee2dd8 ¤   ¤   SetWindowLong (GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE),·
f75312 ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG)wpOrigPhrase1Proc);·
0a79e7 ¤   ¤   DeleteObject (hBrushEdit);
e5fc33 ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE);
abca2d ¤   ¤   break;·
8caf5a
4d3fcf ¤   case WM_COMMAND:
19537d ¤   ¤   switch (LOWORD(wParam)) {
384df6 ¤   ¤   case IDC_CHECK_HIDE_TYPING:
18fbcd ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_CHECK_HIDE_TYPING) ==
8c624a ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
053bfb ¤   ¤   ¤   ¤   bHideTyping = TRUE;
646b93 ¤   ¤   ¤   else·
b87824 ¤   ¤   ¤   ¤   bHideTyping = FALSE;
17ddfb ¤   ¤   ¤   InvalidateRect (GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE),·
bddf4e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, TRUE);
28cdcb ¤   ¤   ¤   break;
4c0fe4 ¤   ¤   }
c72f68 ¤   ¤   break;
adaf5a
eac93c ¤   case WM_NOTIFY:
795b34 ¤   ¤   {
f75808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
78af5a
66e55c ¤   ¤   ¤   switch (pnmh->code) {
5c66bc ¤   ¤   ¤   case PSN_SETACTIVE:
ce577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
6e7c97 ¤   ¤   ¤   ¤   if (!pkgi->OldKey) {
54c6a6 ¤   ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, -1L); // skip this page
504149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
eb2613 ¤   ¤   ¤   ¤   }
79deaa ¤   ¤   ¤   ¤   else {
ef4351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
5669e2 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
c1d8a3 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
--9d42 0004979848b401102ed Page 23 of PKgenwiz.c
705452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
c5feae ¤   ¤   ¤   ¤   ¤   bHideTyping = TRUE;
b564eb ¤   ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_CHECK_HIDE_TYPING,·
6fa855 ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED);
17aab2 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CHECK_SIGN_KEY,·
6f85d5 ¤   ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
6d3b26 ¤   ¤   ¤   ¤   ¤   PGPGetKeyBoolean (pkgi->OldKey,·
053be1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyPropNeedsPassphrase, &bNeedsPhrase);
23907f ¤   ¤   ¤   ¤   ¤   if (!bNeedsPhrase) {
91ac96 ¤   ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_EDIT_PASSPHRASE, "");
7d839d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg,IDC_EDIT_PASSPHRASE),
272a1e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
3c235d ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg,IDC_CHECK_HIDE_TYPING),
8e2a1e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE);
e21c89 ¤   ¤   ¤   ¤   ¤   }
8dd620 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
f94149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c62613 ¤   ¤   ¤   ¤   }
35f622 ¤   ¤   ¤   ¤   break;
56af5a
c9d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
411036 ¤   ¤   ¤   ¤   if (SendDlgItemMessage (hDlg, IDC_CHECK_SIGN_KEY,·
3a425e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED) {
3ab354 ¤   ¤   ¤   ¤   ¤   BOOL bAllOk = FALSE;
4841b5 ¤   ¤   ¤   ¤   ¤   PGPUserIDRef UserID;
6fcd93 ¤   ¤   ¤   ¤   ¤   CHAR szDummy[4];
eaaf5a
9a4c73 ¤   ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
3267c5 ¤
20d145 ¤   ¤   ¤   ¤   ¤   if (szPhrase1) {
7faf32 ¤   ¤   ¤   ¤   ¤   ¤   secFree (szPhrase1);
9f9845 ¤   ¤   ¤   ¤   ¤   ¤   szPhrase1 = NULL;
a71c89 ¤   ¤   ¤   ¤   ¤   }
455653 ¤   ¤   ¤   ¤   ¤   lPhrase1Len = SendDlgItemMessage (hDlg,·
16db2d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_EDIT_PASSPHRASE,·
f03b76 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) +1;
f2fc79 ¤   ¤   ¤   ¤   ¤   szPhrase1 = secAlloc (lPhrase1Len);
5dc6f6 ¤   ¤   ¤   ¤   ¤   if (szPhrase1)·
856f94 ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_EDIT_PASSPHRASE,·
089f26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDummy, sizeof(szDummy));
95d83c ·
d6d145 ¤   ¤   ¤   ¤   ¤   if (szPhrase1) {
4a4acb ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserID (pkgi->Key, &UserID);
2aaf5a
f1a002 ¤   ¤   ¤   ¤   ¤   ¤   if (UserID) {
54c4c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPError err = kPGPError_BadPassphrase;
3faf5a
9feaaa ¤   ¤   ¤   ¤   ¤   ¤   ¤   // make sure we have enough entropy
c15353 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclRandom (pkgi->Context, pkgi->hWndWiz, 0);
d8af5a
5ae88e ¤   ¤   ¤   ¤   ¤   ¤   ¤   err = PGPSignUserID (UserID, pkgi->OldKey,·
d106e6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase (pkgi->Context, szPhrase1),
078fa9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (pkgi->Context));
52a820 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (err == kPGPError_BadPassphrase) {
0cbde9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PKMessageBox (hDlg, IDS_KW_TITLE,
9e5f40 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_KW_BAD_PASSPHRASE,·
5f0120 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_OK | MB_ICONERROR);
a75268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
afa41c ¤   ¤   ¤   ¤   ¤   ¤   ¤   else {
acf4e9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (err != kPGPError_NoErr)
591e09 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclErrorBox (pkgi->hWndWiz, err);
02f9b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else
c5f861 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bAllOk = TRUE;
145268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
cc0482 ¤   ¤   ¤   ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤   ···
baaf32 ¤   ¤   ¤   ¤   ¤   ¤   secFree (szPhrase1);
709845 ¤   ¤   ¤   ¤   ¤   ¤   szPhrase1 = NULL;
a86731 ¤   ¤   ¤   ¤   ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE);
921c89 ¤   ¤   ¤   ¤   ¤   }
ad43cd ¤   ¤   ¤   ¤   ¤   if (!bAllOk) {
fe449b ¤   ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L);
49c92f ¤   ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
--edcf 000439a642f401102ed Page 24 of PKgenwiz.c
b61c89 ¤   ¤   ¤   ¤   ¤   }
7c2613 ¤   ¤   ¤   ¤   }
0ef622 ¤   ¤   ¤   ¤   break;
6faf5a
9e6122 ¤   ¤   ¤   case PSN_HELP:
5f5535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
f7ed60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_SIGNOLD);·
c1f622 ¤   ¤   ¤   ¤   break;
11af5a
f08f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
88f622 ¤   ¤   ¤   ¤   break;
86a3a6 ¤   ¤   ¤   }
d1cdcb ¤   ¤   ¤   break;
a70fe4 ¤   ¤   }
7c9371 ¤   }
a2af5a
fc8ca8 ¤   return bReturnCode;
34efe6 }
ceaf5a
77af5a
e0d4d4 //¤ ______________________________________________
7d465d //
a92769 // ·Dialog procedure for actually generating the key(s)
4daf5a
e65678 static LRESULT WINAPI·
60b087 sKeyWizardGenerationDlgProc (
a53a3a ¤   ¤   HWND¤   hDlg,·
9eeb77 ¤   ¤   UINT¤   uMsg,·
8517d4 ¤   ¤   WPARAM¤ wParam,·
12c0b8 ¤   ¤   LPARAM¤ lParam)·
41bb36 {
3a2ccd ¤   PKEYGENINFO¤¤   pkgi;
e30f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
e3521d ¤   DWORD¤  ¤   ¤   dwThreadID;
0d934a ¤   char¤   ¤   ¤   szPhaseString[128];
174426 ¤   static BOOL¤¤   bAVIFinished;
9899de ¤   static BOOL¤¤   bAVIStarted;
d0af5a
ab347f ¤   switch (uMsg) {
832940 ¤   case WM_INITDIALOG:
125b34 ¤   ¤   {
58509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
efe006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
bb423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
13af5a
cf7c96 ¤   ¤   ¤   pkgi->uWorkingPhase = IDS_KEYGENPHASE1;
defd19 ¤   ¤   ¤   LoadString (g_hInst, pkgi->uWorkingPhase,·
e719fa ¤   ¤   ¤   ¤   ¤   ···szPhaseString, sizeof(szPhaseString));
6812ce ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PHASE, szPhaseString);
a7af5a
614f23 ¤   ¤   ¤   pkgi->hWndWiz = hDlg;
e5485e ¤   ¤   ¤   pkgi->bInGeneration = TRUE;
bdaf5a
eddbad ¤   ¤   ¤   // Kick off generation proc, here
5b99c5 ¤   ¤   ¤   _beginthreadex (NULL, 0,·
ec2f1d ¤   ¤   ¤   ¤   (LPTHREAD_START_ROUTINE)sKeyGenerationThread,·
e7fe51 ¤   ¤   ¤   ¤   (void *) pkgi, 0, &dwThreadID);
89cdcb ¤   ¤   ¤   break;
f30fe4 ¤   ¤   }
d6af5a
7f85ca ¤   case WM_PAINT :
482463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
9fd515 ¤   ¤   if (pkgi->hPalette)
1c5b34 ¤   ¤   {
0df431 ¤   ¤   ¤   PAINTSTRUCT ps;
fb638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
0acada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
a49ffe ¤   ¤   ¤   RealizePalette (hDC);
1b5dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
f90fe4 ¤   ¤   }
f32f68 ¤   ¤   break;
43af5a
--40c5 000163304ef401102ed Page 25 of PKgenwiz.c
6b4f76 ¤   case KM_M_CHANGEPHASE:
2ca2be ¤   ¤   bReturnCode = TRUE;
7a6ae0 ¤   ¤   LoadString (g_hInst, lParam, szPhaseString, sizeof(szPhaseString));
1c347b ¤   ¤   SetDlgItemText (hDlg, IDC_PHASE, szPhaseString);
0b2f68 ¤   ¤   break;
ebaf5a
b75122 ¤   case WM_TIMER :
bbe873 ¤   ¤   if (wParam == AVI_TIMER) {
d5ade0 ¤   ¤   ¤   KillTimer (hDlg, AVI_TIMER);
6f0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
4ce1e9 ¤   ¤   ¤   if (bAVIStarted) {
5e26a2 ¤   ¤   ¤   ¤   if (!bAVIFinished) {
bc911f ¤   ¤   ¤   ¤   ¤   bAVIFinished = TRUE;
b34c73 ¤   ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
3c399a ¤   ¤   ¤   ¤   ¤   if (!pkgi->bInGeneration)·
d2842d ¤   ¤   ¤   ¤   ¤   ¤   PostMessage (hDlg, KM_M_GENERATION_COMPLETE, 0, 0);
5f2613 ¤   ¤   ¤   ¤   }
f0a3a6 ¤   ¤   ¤   }
bde543 ¤   ¤   ¤   else {
0e0014 ¤   ¤   ¤   ¤   sStartKeyGenAVI (GetDlgItem (hDlg, IDC_WORKINGAVI));
367bdf ¤   ¤   ¤   ¤   SetTimer (hDlg, AVI_TIMER, AVI_RUNTIME, NULL);
57c5e5 ¤   ¤   ¤   ¤   bAVIStarted = TRUE;
d7a3a6 ¤   ¤   ¤   }
090fe4 ¤   ¤   }
de2f68 ¤   ¤   break;
f767c5 ¤
d85689 ¤   case KM_M_GENERATION_COMPLETE:
7f2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
d35913 ¤   ¤   if (bAVIFinished)·
16431d ¤   ¤   ¤   Animate_Stop (GetDlgItem (hDlg, IDC_WORKINGAVI));
7367c5 ¤
82d720 ¤   ¤   if (pkgi->bCancelPending) {
d71cc3 ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_CANCELING,·
14449d ¤   ¤   ¤   ¤   szPhaseString, sizeof(szPhaseString));
ce0fe4 ¤   ¤   }
cc07e0 ¤   ¤   else {
05cc80 ¤   ¤   ¤   if (pkgi->iFinalResult) {
4266be ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_COMPLETE,·
7243a6 ¤   ¤   ¤   ¤   ¤   szPhaseString, sizeof(szPhaseString));
320c3b ¤   ¤   ¤   ¤   SendMessage (GetParent(hDlg),·
d1e6b5 ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
e8a3a6 ¤   ¤   ¤   }
b0e543 ¤   ¤   ¤   else {
d5b89a ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_UNABLETOCOMPLETE,·
9c43a6 ¤   ¤   ¤   ¤   ¤   szPhaseString, sizeof(szPhaseString));
baa3a6 ¤   ¤   ¤   }
a50fe4 ¤   ¤   }
15347b ¤   ¤   SetDlgItemText (hDlg, IDC_PHASE, szPhaseString);
3994aa ¤   ¤   ¤   ¤   ¤   ¤
a4a2be ¤   ¤   bReturnCode = TRUE;
162f68 ¤   ¤   break;
d21b52 ¤   ¤
593fcf ¤   case WM_COMMAND:
f7c8f0 ¤   ¤   switch (HIWORD(wParam)) {
b2b5ef ¤   ¤   case BN_CLICKED:
293b51 ¤   ¤   ¤   if (LOWORD(wParam) == IDC_RADIO_CUSTOM_DAYS) {
b4e32b ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_EDIT_CUSTOM_DAYS,·
2fbc4b ¤   ¤   ¤   ¤   ¤   ¤   WM_ENABLE, TRUE, 0);
56a3a6 ¤   ¤   ¤   }
e7e543 ¤   ¤   ¤   else {
b7e32b ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_EDIT_CUSTOM_DAYS,·
00619a ¤   ¤   ¤   ¤   ¤   ¤   WM_ENABLE, FALSE, 0);
0ca3a6 ¤   ¤   ¤   }
55cdcb ¤   ¤   ¤   break;
e10fe4 ¤   ¤   }
912f68 ¤   ¤   break;
52af5a
f7c93c ¤   case WM_NOTIFY:
285b34 ¤   ¤   {
c65808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
f1af5a
16e55c ¤   ¤   ¤   switch (pnmh->code) {
--af90 000bb5c57a1401102ed Page 26 of PKgenwiz.c
d566bc ¤   ¤   ¤   case PSN_SETACTIVE:
a5577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
8a9be3 ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
a11a50 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, 0);
a3c3aa ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
0d5452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
73e54a ¤   ¤   ¤   ¤   bAVIFinished = FALSE;
928125 ¤   ¤   ¤   ¤   bAVIStarted = FALSE;
7bdf23 ¤   ¤   ¤   ¤   SetTimer (hDlg, AVI_TIMER, 100, NULL); ·// delay a few ms
839a46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // before drawing
5bd288 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // AVI
74f095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
c2841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
4df622 ¤   ¤   ¤   ¤   break;
a1af5a
8fd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
b2496f ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_CANCELING,·
0f4344 ¤   ¤   ¤   ¤   ¤   ¤   szPhaseString, sizeof(szPhaseString));
33c8e7 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PHASE, szPhaseString);
6394f2 ¤   ¤   ¤   ¤   bAVIFinished = TRUE;
2a7ca4 ¤   ¤   ¤   ¤   Animate_Close (GetDlgItem (hDlg, IDC_WORKINGAVI));
b3f622 ¤   ¤   ¤   ¤   break;
cbaf5a
a26122 ¤   ¤   ¤   case PSN_HELP:
6a5535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
349c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_GENERATION);·
2df622 ¤   ¤   ¤   ¤   break;
00af5a
a98f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
340755 ¤   ¤   ¤   ¤   //If we're generating a key, don't let the user press
f25778 ¤   ¤   ¤   ¤   //cancel without asking. ·If he says, "yes, I want to cancel,"
8d9f24 ¤   ¤   ¤   ¤   //then we'll still reject the message, but set CancelPending
ae680b ¤   ¤   ¤   ¤   //to TRUE, so that the next time the library comes around, we
e62653 ¤   ¤   ¤   ¤   //can nuke the thread. ·The thread will then clear the
95125f ¤   ¤   ¤   ¤   //InGeneration flag and re-send us the cancel message.
97577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
162b85 ¤   ¤   ¤   ¤
f1b36f ¤   ¤   ¤   ¤   if (pkgi->bInGeneration) {
169b91 ¤   ¤   ¤   ¤   ¤   if (!pkgi->bCancelPending &&
5cb1f8 ¤   ¤   ¤   ¤   ¤   ¤   (PKMessageBox (hDlg, IDS_KW_TITLE,·
46a988 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_KW_CONFIRM_CANCEL,
a797e4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO | MB_ICONQUESTION) == IDYES)) {
aafa45 ¤   ¤   ¤   ¤   ¤   ¤   if (pkgi->bInGeneration) {
6aeed5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->bCancelPending = TRUE;
13c313 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PostMessage (hDlg, KM_M_GENERATION_COMPLETE,·
f6de15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0L);
d5db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e51c89 ¤   ¤   ¤   ¤   ¤   }
e72613 ¤   ¤   ¤   ¤   }
a3b36f ¤   ¤   ¤   ¤   if (pkgi->bInGeneration) {
bf00b3 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 1L);·
994149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
722613 ¤   ¤   ¤   ¤   }
07deaa ¤   ¤   ¤   ¤   else {
440498 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);·
054149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
922613 ¤   ¤   ¤   ¤   }
80f622 ¤   ¤   ¤   ¤   break;
1aa3a6 ¤   ¤   ¤   }
a7cdcb ¤   ¤   ¤   break;
b70fe4 ¤   ¤   }
499371 ¤   }
12af5a
608ca8 ¤   return bReturnCode;
75efe6 }
5eaf5a
f4af5a
6bd4d4 //¤ ______________________________________________
b8465d //
fad13a // ·Dialog procedure for getting entropy
572192 // ·from user
bbaf5a
--7883 000100ae03a401102ed Page 27 of PKgenwiz.c
995678 static LRESULT WINAPI·
bccfca sKeyWizardRandobitsDlgProc (
513a3a ¤   ¤   HWND¤   hDlg,·
6eeb77 ¤   ¤   UINT¤   uMsg,·
ce17d4 ¤   ¤   WPARAM¤ wParam,·
b9c0b8 ¤   ¤   LPARAM¤ lParam)·
d4bb36 {
1a2ccd ¤   PKEYGENINFO¤¤   pkgi;
9d0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
38af5a
8e347f ¤   switch (uMsg) {
432940 ¤   case WM_INITDIALOG:
0b5b34 ¤   ¤   {
dc509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
52e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
76423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
b5cdcb ¤   ¤   ¤   break;
520fe4 ¤   ¤   }
ceaf5a
ed85ca ¤   case WM_PAINT :
1a2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
edd515 ¤   ¤   if (pkgi->hPalette)
c85b34 ¤   ¤   {
7ff431 ¤   ¤   ¤   PAINTSTRUCT ps;
a3638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
ebcada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
559ffe ¤   ¤   ¤   RealizePalette (hDC);
e65dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
fb0fe4 ¤   ¤   }
cf2f68 ¤   ¤   break;
e6af5a
aba0ee ¤   case WM_MOUSEMOVE:
765b34 ¤   ¤   {
60e99c ¤   ¤   ¤   INT¤¤   iPercentComplete = 0;
80749a ¤   ¤   ¤   FLOAT¤  fTotal, fSoFar;
27af5a
84190d ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
a768e9 ¤   ¤   ¤   if (lParam) {
852e4f ¤   ¤   ¤   ¤   PGPGlobalRandomPoolAddMouse (LOWORD (lParam),·
719721 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·HIWORD (lParam));
97a3a6 ¤   ¤   ¤   }
48af5a
400465 ¤   ¤   ¤   if (pkgi->lRandomBitsNeeded) {
295532 ¤   ¤   ¤   ¤   fSoFar = (float) PGPGlobalRandomPoolGetEntropy();
8764b7 ¤   ¤   ¤   ¤   fTotal = (float) pkgi->lRandomBitsNeeded;
987202 ¤   ¤   ¤   ¤   fSoFar -= (float) pkgi->lOriginalEntropy;
2d3e22 ¤   ¤   ¤   ¤   fTotal -= (float) pkgi->lOriginalEntropy;
ebfa2a ¤   ¤   ¤   ¤   iPercentComplete = (INT) ((fSoFar / fTotal) * 100.0);
29af5a
e33df0 ¤   ¤   ¤   ¤   if (fSoFar >= fTotal) {
8c02a8 ¤   ¤   ¤   ¤   ¤   pkgi->lRandomBitsNeeded = 0;
70bc78 ¤   ¤   ¤   ¤   ¤   iPercentComplete = 100;
b5be85 ¤   ¤   ¤   ¤   ¤   hWndCollectEntropy = NULL;
3b685d ¤   ¤   ¤   ¤   ¤   SendMessage (GetParent(hDlg), PSM_SETWIZBUTTONS,·
7ccf94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, PSWIZB_NEXT|PSWIZB_BACK);
dd2613 ¤   ¤   ¤   ¤   }
6e3783 ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS,·
c6e2af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   iPercentComplete, 0);
63a3a6 ¤   ¤   ¤   }
3fcdcb ¤   ¤   ¤   break;
080fe4 ¤   ¤   }
89af5a
b4c93c ¤   case WM_NOTIFY:
205b34 ¤   ¤   {
e05808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
8faf5a
e7302d ¤   ¤   ¤   switch(pnmh->code) {
b566bc ¤   ¤   ¤   case PSN_SETACTIVE:
1f577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
d2816b ¤   ¤   ¤   ¤   PostMessage(GetParent(hDlg),·
5b1a50 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, 0);
101647 ¤   ¤   ¤   ¤   SendDlgItemMessage(hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
--db51 0000c68a373401102ed Page 28 of PKgenwiz.c
705452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
5d72c3 ¤   ¤   ¤   ¤   {
670d5a ¤   ¤   ¤   ¤   ¤   LONG¤   ¤   ¤   lTotalBitsNeeded, lRandPoolSize;
c5f84c ¤   ¤   ¤   ¤   ¤   PGPBoolean¤ ¤   bFastGen;
b46933 ¤   ¤   ¤   ¤   ¤   PGPContextRef¤  ctx = pkgi->Context;
ccaf5a
8239d5 ¤   ¤   ¤   ¤   ¤   hWndCollectEntropy = hDlg;
a6af5a
7f610b ¤   ¤   ¤   ¤   ¤   // Check to see if there are random bits needed
ebfe5a ¤   ¤   ¤   ¤   ¤   PGPGetPrefBoolean (pkgi->PrefRefClient,·
594110 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefFastKeyGen,
3a19ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &bFastGen);
e9695e ¤   ¤   ¤   ¤   ¤   lTotalBitsNeeded =·
6105ab ¤   ¤   ¤   ¤   ¤   ¤   PGPGetKeyEntropyNeeded (ctx,
81aaa5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOKeyGenParams (ctx, pkgi->uKeyType,·
43af46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->uKeySize),
21db0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOKeyGenFast (ctx, bFastGen),
17a295 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (ctx));
e5ee98 ¤   ¤   ¤   ¤   ¤   if (pkgi->uKeyType == kPGPPublicKeyAlgorithm_DSA) {
df6fcb ¤   ¤   ¤   ¤   ¤   ¤   lTotalBitsNeeded +=·
b68152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetKeyEntropyNeeded (pkgi->Context,
87efe1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOKeyGenParams (ctx,·
61f0f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_ElGamal,·
853878 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->uSubKeySize),
c41f16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOKeyGenFast (ctx, bFastGen),
32b3b2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption (ctx));
3c1c89 ¤   ¤   ¤   ¤   ¤   }
998eae ¤   ¤   ¤   ¤   ¤   lRandPoolSize = PGPGlobalRandomPoolGetSize ();
4daf5a
8a01da ¤   ¤   ¤   ¤   ¤   pkgi->lRandomBitsNeeded =·
8a482a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   min (lTotalBitsNeeded, lRandPoolSize);
172613 ¤   ¤   ¤   ¤   }
87d4fc ¤   ¤   ¤   ¤   if ((pkgi->lRandomBitsNeeded -
3be4b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LONG)PGPGlobalRandomPoolGetEntropy()) > 0) {
774573 ¤   ¤   ¤   ¤   ¤   pkgi->lOriginalEntropy = PGPGlobalRandomPoolGetEntropy();
6bdfc5 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS,·
233910 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PBM_SETRANGE, 0, MAKELPARAM(0, 100));
57dfc5 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS,·
a54fe8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PBM_SETPOS, 0, 0);
8b8fd1 ¤   ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
944149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
752613 ¤   ¤   ¤   ¤   }
64deaa ¤   ¤   ¤   ¤   else {
bdd30e ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L); // skip page
f74149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
adbe85 ¤   ¤   ¤   ¤   ¤   hWndCollectEntropy = NULL;
692613 ¤   ¤   ¤   ¤   }
45f622 ¤   ¤   ¤   ¤   break;
bfaf5a
bfd105 ¤   ¤   ¤   case PSN_KILLACTIVE:
cd9856 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0);
e0841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
512f1d ¤   ¤   ¤   ¤   hWndCollectEntropy = NULL;
46f622 ¤   ¤   ¤   ¤   break;
63af5a
0f6122 ¤   ¤   ¤   case PSN_HELP:
145535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
c0df6f ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_RANDOBITS);·
3df622 ¤   ¤   ¤   ¤   break;
3aaf5a
858f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
9b2f1d ¤   ¤   ¤   ¤   hWndCollectEntropy = NULL;
43f622 ¤   ¤   ¤   ¤   break;
d2a3a6 ¤   ¤   ¤   }
79cdcb ¤   ¤   ¤   break;
520fe4 ¤   ¤   }
f59371 ¤   }
28af5a
e08ca8 ¤   return bReturnCode;
03efe6 }
deaf5a
0caf5a
--eb10 0004151cc2e401102ed Page 29 of PKgenwiz.c
cfd4d4 //¤ ______________________________________________
0f465d //
05a400 // ·Dialog procedure for "Bad Passphrase" dialog
80af5a
335678 static LRESULT WINAPI·
209e88 sKeyWizardBadPassphraseDlgProc (
9d3a3a ¤   ¤   HWND¤   hDlg,·
5beb77 ¤   ¤   UINT¤   uMsg,·
2117d4 ¤   ¤   WPARAM¤ wParam,·
bec0b8 ¤   ¤   LPARAM¤ lParam)·
6cbb36 {
3f2ccd ¤   PKEYGENINFO¤¤   pkgi;
dd0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
8caf5a
92347f ¤   switch (uMsg) {
8e2940 ¤   case WM_INITDIALOG:
4b5b34 ¤   ¤   {
e7509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
52e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
c1423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
26af5a
5dcdcb ¤   ¤   ¤   break;
2a0fe4 ¤   ¤   }
86af5a
5585ca ¤   case WM_PAINT :
ae2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
5bd515 ¤   ¤   if (pkgi->hPalette)
325b34 ¤   ¤   {
6ef431 ¤   ¤   ¤   PAINTSTRUCT ps;
12638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
cbcada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
1f9ffe ¤   ¤   ¤   RealizePalette (hDC);
2b5dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
d60fe4 ¤   ¤   }
762f68 ¤   ¤   break;
90af5a
35c93c ¤   case WM_NOTIFY:
eced49 ¤   ¤   {¤
c02cbb ¤   ¤   ¤   LPNMHDR pnmh¤   ¤   = (LPNMHDR) lParam;
7f6230 ¤   ¤   ¤   BOOL¤   bPhraseOK¤  = TRUE;
5cff08 ¤   ¤   ¤   INT¤¤   iShow;
86d02e ¤   ¤   ¤   CHAR¤   sz1[128], sz2[128];
10af5a
dbe55c ¤   ¤   ¤   switch (pnmh->code) {
2a66bc ¤   ¤   ¤   case PSN_SETACTIVE:
c3f776 ¤   ¤   ¤   {
894e6d ¤   ¤   ¤   ¤   BOOL¤   bRejected;
6c31f7 ¤   ¤   ¤   ¤   BOOL¤   bLengthRejected, bQualityRejected, bConfirmRejected;
18e9a2 ¤   ¤   ¤   ¤   INT¤¤   ids;
d8af5a
db577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
74e149 ¤   ¤   ¤   ¤   if (pkgi->uPhraseFlags == 0) {
12d30e ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L); // skip page
0b4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
0314c3 ¤   ¤   ¤   ¤   ¤   break;
5a2613 ¤   ¤   ¤   ¤   }
a6af5a
37c3aa ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
3854b0 ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
38af5a
d8f03d ¤   ¤   ¤   ¤   if (pkgi->bMinPhraseLength) ids = IDS_REQPHRASELENGTH;
f11d18 ¤   ¤   ¤   ¤   else ids = IDS_SUGPHRASELENGTH;
4b0cc3 ¤   ¤   ¤   ¤   LoadString (g_hInst, ids, sz1, sizeof(sz1));
672ef0 ¤   ¤   ¤   ¤   wsprintf (sz2, sz1, pkgi->iMinPhraseLength);
509117 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_BADLENGTH, sz2);
3eaf5a
07b608 ¤   ¤   ¤   ¤   if (pkgi->bMinPhraseQuality) ids = IDS_REQPHRASEQUALITY;
722d4f ¤   ¤   ¤   ¤   else ids = IDS_SUGPHRASEQUALITY;
f00cc3 ¤   ¤   ¤   ¤   LoadString (g_hInst, ids, sz1, sizeof(sz1));
dab9c1 ¤   ¤   ¤   ¤   wsprintf (sz2, sz1, pkgi->iMinPhraseQuality);
558b40 ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_BADQUALITY1, sz2);
41af5a
--fef5 000db779045401102ed Page 30 of PKgenwiz.c
ba9fd4 ¤   ¤   ¤   ¤   bRejected = FALSE;
17802f ¤   ¤   ¤   ¤   bLengthRejected = FALSE;
d3178b ¤   ¤   ¤   ¤   bQualityRejected = FALSE;
77b9dd ¤   ¤   ¤   ¤   bConfirmRejected = FALSE;
c2e21b ¤   ¤   ¤   ¤   if ((pkgi->bMinPhraseLength) &&·
b26a13 ¤   ¤   ¤   ¤   ¤   (pkgi->uPhraseFlags & BADPHRASE_LENGTH)) {
0f4f92 ¤   ¤   ¤   ¤   ¤   bLengthRejected = TRUE;
282a68 ¤   ¤   ¤   ¤   ¤   bRejected = TRUE;
592613 ¤   ¤   ¤   ¤   }
12d654 ¤   ¤   ¤   ¤   if ((pkgi->bMinPhraseQuality) &&·
bbfda4 ¤   ¤   ¤   ¤   ¤   (pkgi->uPhraseFlags & BADPHRASE_QUALITY)) {
7ff4ef ¤   ¤   ¤   ¤   ¤   bQualityRejected = TRUE;
ef2a68 ¤   ¤   ¤   ¤   ¤   bRejected = TRUE;
d62613 ¤   ¤   ¤   ¤   }
1dc7a2 ¤   ¤   ¤   ¤   if (pkgi->uPhraseFlags & BADPHRASE_CONFIRMATION) {
a9f0f4 ¤   ¤   ¤   ¤   ¤   bConfirmRejected = TRUE;
a12a68 ¤   ¤   ¤   ¤   ¤   bRejected = TRUE;
d52613 ¤   ¤   ¤   ¤   }
87af5a
04db7e ¤   ¤   ¤   ¤   if (bRejected) {
9444a6 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_PHRASEREJECTED,·
734612 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz1, sizeof(sz1));
e6ad32 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_REJECTTEXT, sz1);
ac9a83 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent (hDlg),·
4d4a20 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
a02613 ¤   ¤   ¤   ¤   }
f7deaa ¤   ¤   ¤   ¤   else {
00c4b9 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_PHRASEWARNED,·
c14612 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz1, sizeof(sz1));
13ad32 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_REJECTTEXT, sz1);
a69a83 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent (hDlg),·
152a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
c12613 ¤   ¤   ¤   ¤   }
77af5a
90aa63 ¤   ¤   ¤   ¤   iShow = SW_HIDE;
fc0d02 ¤   ¤   ¤   ¤   if (pkgi->uPhraseFlags & BADPHRASE_LENGTH)·
e4afc9 ¤   ¤   ¤   ¤   ¤   if (!bRejected || bLengthRejected)
e0060f ¤   ¤   ¤   ¤   ¤   ¤   iShow = SW_SHOW;
254573 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BADLENGTH), iShow);
71de65 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BOX1), iShow);
0daf5a
eab8c7 ¤   ¤   ¤   ¤   if (iShow == SW_HIDE) {
8acdf5 ¤   ¤   ¤   ¤   ¤   if (pkgi->uPhraseFlags & BADPHRASE_CONFIRMATION)
c98f41 ¤   ¤   ¤   ¤   ¤   ¤   if (!bRejected || bConfirmRejected)
8200b7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iShow = SW_SHOW;
bc199b ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BADCONFIRM), iShow);
495420 ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BOX1), iShow);
212613 ¤   ¤   ¤   ¤   }
b9fa07 ¤   ¤   ¤   ¤   else
021370 ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BADCONFIRM), SW_HIDE);
cfaf5a
7eaa63 ¤   ¤   ¤   ¤   iShow = SW_HIDE;
fb0fd9 ¤   ¤   ¤   ¤   if (pkgi->uPhraseFlags & BADPHRASE_QUALITY)
74564b ¤   ¤   ¤   ¤   ¤   if (!bRejected || bQualityRejected)
fa060f ¤   ¤   ¤   ¤   ¤   ¤   iShow = SW_SHOW;
d6ae1c ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BADQUALITY1), iShow);
c529f2 ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BADQUALITY2), iShow);
3d598b ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_BOX2), iShow);
f0af5a
adf095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
25841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
56f622 ¤   ¤   ¤   ¤   break;
e7a3a6 ¤   ¤   ¤   }
86af5a
6a6122 ¤   ¤   ¤   case PSN_HELP:
925535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
080f86 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_BADPHRASE);·
baf622 ¤   ¤   ¤   ¤   break;
b5af5a
888f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
69f622 ¤   ¤   ¤   ¤   break;
dba3a6 ¤   ¤   ¤   }
--018c 0009b35f1eb401102ed Page 31 of PKgenwiz.c
7ecdcb ¤   ¤   ¤   break;
690fe4 ¤   ¤   }
209371 ¤   }
39af5a
f78ca8 ¤   return bReturnCode;
3cefe6 }
4aaf5a
73af5a
a5d4d4 //¤ ______________________________________________
03465d //
8a06f4 // ·Dialog procedure for getting passphrase
372192 // ·from user
d6af5a
f05678 static LRESULT WINAPI·
5b68c0 sKeyWizardPassphraseDlgProc (
093a3a ¤   ¤   HWND¤   hDlg,·
b1eb77 ¤   ¤   UINT¤   uMsg,·
9517d4 ¤   ¤   WPARAM¤ wParam,·
c8c0b8 ¤   ¤   LPARAM¤ lParam)·
a8bb36 {
852ccd ¤   PKEYGENINFO¤¤   pkgi;
9e0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
6ba286 ¤   CHAR¤   ¤   ¤   szDummy[4];
106f42 ¤   INT¤¤   ¤   ¤   iQuality;
081d3c ¤   static HBRUSH¤  hBrushEdit;
7eaf5a
e6347f ¤   switch (uMsg) {
2e2940 ¤   case WM_INITDIALOG:
d35b34 ¤   ¤   {
385059 ¤   ¤   ¤   CHAR sz1[256], sz2[256];
b6509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
a1e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
09423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
56af5a
5f8d84 ¤   ¤   ¤   wpOrigPhrase1Proc = (WNDPROC) SetWindowLong (GetDlgItem (hDlg,·
e307e4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_EDIT_PASSPHRASE),·
f42a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
a7d86f ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LONG) sWizPhrase1SubclassProc);·
270da2 ¤   ¤   ¤   wpOrigPhrase2Proc = (WNDPROC) SetWindowLong (GetDlgItem (hDlg,·
f9b945 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_EDIT_PASSPHRASE2),·
312a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
6ae87e ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LONG) sWizPhrase2SubclassProc);·
7daf5a
e68bc0 ¤   ¤   ¤   hBrushEdit = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
f3af5a
810af6 ¤   ¤   ¤   LoadString (g_hInst, IDS_PHRASELENGTHTEXT, sz1, sizeof(sz1));
cd0845 ¤   ¤   ¤   wsprintf (sz2, sz1, pkgi->iMinPhraseLength);
77e3b2 ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_PHRASELENGTHTEXT, sz2);
8ecdcb ¤   ¤   ¤   break;
310fe4 ¤   ¤   }
20af5a
1585ca ¤   case WM_PAINT :
3b2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
bed515 ¤   ¤   if (pkgi->hPalette)
985b34 ¤   ¤   {
e6f431 ¤   ¤   ¤   PAINTSTRUCT ps;
b1638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
22cada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
ae9ffe ¤   ¤   ¤   RealizePalette (hDC);
395dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
ff0fe4 ¤   ¤   }
f02f68 ¤   ¤   break;
b0af5a
7e95f7 ¤   case WM_CTLCOLOREDIT:
14aa00 ¤   ¤   if (((HWND)lParam == GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE)) ||
ec3345 ¤   ¤   ¤   ((HWND)lParam == GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE2))) {
d3c559 ¤   ¤   ¤   SetBkColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
8b1fd7 ¤   ¤   ¤   if (bHideTyping)·
87b25f ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOW));
fc6b93 ¤   ¤   ¤   else·
c7f4fd ¤   ¤   ¤   ¤   SetTextColor ((HDC)wParam, GetSysColor (COLOR_WINDOWTEXT));
9b47cc ¤   ¤   ¤   return (BOOL)hBrushEdit;
--3a37 000276e01a3401102ed Page 32 of PKgenwiz.c
b50fe4 ¤   ¤   }
892f68 ¤   ¤   break;
11af5a
1ba96f ¤   case WM_DESTROY:·
745693 ¤   ¤   SetWindowLong(GetDlgItem(hDlg, IDC_EDIT_PASSPHRASE),
9b5312 ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG)wpOrigPhrase1Proc);·
ac94a3 ¤   ¤   SetWindowLong(GetDlgItem(hDlg, IDC_EDIT_PASSPHRASE2),·
f37bf5 ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC, (LONG)wpOrigPhrase2Proc);
8679e7 ¤   ¤   DeleteObject (hBrushEdit);
0afc33 ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE);
79305d ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE2);
e9ca2d ¤   ¤   break;·
5baf5a
b83fcf ¤   case WM_COMMAND:
13712a ¤   ¤   switch(LOWORD(wParam)) {
cd4df6 ¤   ¤   case IDC_CHECK_HIDE_TYPING:
9efbcd ¤   ¤   ¤   if (IsDlgButtonChecked (hDlg, IDC_CHECK_HIDE_TYPING) ==
56b1d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED)·
603bfb ¤   ¤   ¤   ¤   bHideTyping = TRUE;
d46b93 ¤   ¤   ¤   else·
147824 ¤   ¤   ¤   ¤   bHideTyping = FALSE;
77af5a
23ddfb ¤   ¤   ¤   InvalidateRect (GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE),·
66b1fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, TRUE);
e351e9 ¤   ¤   ¤   InvalidateRect (GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE2),·
c7b1fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, TRUE);
3ecdcb ¤   ¤   ¤   break;
dc0fe4 ¤   ¤   }
172f68 ¤   ¤   break;
3baf5a
c8c93c ¤   case WM_NOTIFY:
ed5b34 ¤   ¤   {
215808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
f7af5a
27e55c ¤   ¤   ¤   switch (pnmh->code) {
2166bc ¤   ¤   ¤   case PSN_SETACTIVE:
b1577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
959be3 ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
0a2a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
e9c3aa ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
c15452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
abf095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
453bfb ¤   ¤   ¤   ¤   bHideTyping = TRUE;
61594c ¤   ¤   ¤   ¤   CheckDlgButton (hDlg, IDC_CHECK_HIDE_TYPING, BST_CHECKED);
074fe9 ¤   ¤   ¤   ¤   if (pkgi->bMinPhraseQuality) {
cd0268 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_MINPHRASEQUALITY,·
da1fc4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PBM_SETRANGE, 0, MAKELPARAM (0, 100));
460268 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_MINPHRASEQUALITY,·
f233c8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PBM_SETPOS, pkgi->iMinPhraseQuality, 0);
0b2613 ¤   ¤   ¤   ¤   }
77deaa ¤   ¤   ¤   ¤   else {
dc8760 ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_MINPHRASEQUALITY),·
f38f63 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SW_HIDE);
6f3894 ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_MINQUALITYTEXT),·
6b8f63 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SW_HIDE);
342613 ¤   ¤   ¤   ¤   }
1e482c ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PHRASEQUALITY, PBM_SETRANGE,·
3fb8ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, MAKELPARAM (0, 100));
1c39db ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PHRASEQUALITY, PBM_SETPOS,·
d93a84 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0);
82841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
8cf622 ¤   ¤   ¤   ¤   break;
8baf5a
ef99a3 ¤   ¤   ¤   case PSN_WIZNEXT:
f7577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
f5af5a
8cba56 ¤   ¤   ¤   ¤   // get entered phrase into buffer
3cec2d ¤   ¤   ¤   ¤   if (szPhrase1) {
62a98a ¤   ¤   ¤   ¤   ¤   secFree (szPhrase1);
d2a4ab ¤   ¤   ¤   ¤   ¤   szPhrase1 = NULL;
7c2613 ¤   ¤   ¤   ¤   }
2770e6 ¤   ¤   ¤   ¤   lPhrase1Len = SendDlgItemMessage (hDlg,·
--3e2c 000de56fa63401102ed Page 33 of PKgenwiz.c
c31f8b ¤   ¤   ¤   ¤   ¤   ¤   IDC_EDIT_PASSPHRASE, WM_GETTEXTLENGTH, 0, 0) +1;
96a9d5 ¤   ¤   ¤   ¤   szPhrase1 = secAlloc (lPhrase1Len);
924d0a ¤   ¤   ¤   ¤   if (szPhrase1)·
d752fa ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_EDIT_PASSPHRASE,·
aa9f26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDummy, sizeof(szDummy));
90af5a
3591ea ¤   ¤   ¤   ¤   // get confirmation phrase
0bf1e1 ¤   ¤   ¤   ¤   if (szPhrase2) {
0d8c47 ¤   ¤   ¤   ¤   ¤   secFree (szPhrase2);
19d0c2 ¤   ¤   ¤   ¤   ¤   szPhrase2 = NULL;
cd2613 ¤   ¤   ¤   ¤   }
b88281 ¤   ¤   ¤   ¤   lPhrase2Len = SendDlgItemMessage (hDlg,·
bb0c47 ¤   ¤   ¤   ¤   ¤   ¤   IDC_EDIT_PASSPHRASE2, WM_GETTEXTLENGTH, 0, 0) +1;
075b88 ¤   ¤   ¤   ¤   szPhrase2 = secAlloc (lPhrase2Len);
d868c7 ¤   ¤   ¤   ¤   if (szPhrase2)·
6a3ab2 ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_EDIT_PASSPHRASE2,·
e49f26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szDummy, sizeof(szDummy));
53d83c ·
918f14 ¤   ¤   ¤   ¤   if (szPhrase1 && szPhrase2) {
bd4178 ¤   ¤   ¤   ¤   ¤   pkgi->uPhraseFlags = 0;
873db5 ¤   ¤   ¤   ¤   ¤   if (strcmp (szPhrase1, szPhrase2) != 0)·
3dd9b1 ¤   ¤   ¤   ¤   ¤   ¤   pkgi->uPhraseFlags |= BADPHRASE_CONFIRMATION;
a5af5a
ff425a ¤   ¤   ¤   ¤   ¤   if (lstrlen (szPhrase1) < pkgi->iMinPhraseLength)·
f59972 ¤   ¤   ¤   ¤   ¤   ¤   pkgi->uPhraseFlags |= BADPHRASE_LENGTH;
b4af5a
bc2862 ¤   ¤   ¤   ¤   ¤   iQuality = PGPEstimatePassphraseQuality (szPhrase1);
acdd09 ¤   ¤   ¤   ¤   ¤   if (iQuality < pkgi->iMinPhraseQuality)·
03e197 ¤   ¤   ¤   ¤   ¤   ¤   pkgi->uPhraseFlags |= BADPHRASE_QUALITY;
35af5a
c9b4d1 ¤   ¤   ¤   ¤   ¤   if (pkgi->pszPassPhrase) {
c680ba ¤   ¤   ¤   ¤   ¤   ¤   secFree (pkgi->pszPassPhrase);
6f4dcb ¤   ¤   ¤   ¤   ¤   ¤   pkgi->pszPassPhrase = NULL;
591c89 ¤   ¤   ¤   ¤   ¤   }
1eb3ff ¤   ¤   ¤   ¤   ¤   pkgi->pszPassPhrase =·
77761f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secAlloc (lPhrase1Len * sizeof(char));
a35597 ¤   ¤   ¤   ¤   ¤   lstrcpy (pkgi->pszPassPhrase, szPhrase1);
77af5a
49eacd ¤   ¤   ¤   ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE);
3d2eba ¤   ¤   ¤   ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE2);
34f627 ¤   ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_EDIT_PASSPHRASE));
89af5a
1bd620 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
184149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
d02613 ¤   ¤   ¤   ¤   }
3aec2d ¤   ¤   ¤   ¤   if (szPhrase1) {
efa98a ¤   ¤   ¤   ¤   ¤   secFree (szPhrase1);
bba4ab ¤   ¤   ¤   ¤   ¤   szPhrase1 = NULL;
022613 ¤   ¤   ¤   ¤   }
bcf1e1 ¤   ¤   ¤   ¤   if (szPhrase2) {
f38c47 ¤   ¤   ¤   ¤   ¤   secFree (szPhrase2);
17d0c2 ¤   ¤   ¤   ¤   ¤   szPhrase2 = NULL;
572613 ¤   ¤   ¤   ¤   }
f4f622 ¤   ¤   ¤   ¤   break;
d5af5a
5f5bdd ¤   ¤   ¤   case PSN_WIZBACK :
32ea2f ¤   ¤   ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE);
96eaa6 ¤   ¤   ¤   ¤   PKWipeEditBox (hDlg, IDC_EDIT_PASSPHRASE2);
02f622 ¤   ¤   ¤   ¤   break;
1eaf5a
ff6122 ¤   ¤   ¤   case PSN_HELP:
805535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
b9aad9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_PASSPHRASE);·
16f622 ¤   ¤   ¤   ¤   break;
22af5a
518f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
50f622 ¤   ¤   ¤   ¤   break;
88a3a6 ¤   ¤   ¤   }
0fcdcb ¤   ¤   ¤   break;
b50fe4 ¤   ¤   }
ed9371 ¤   }
deaf5a
--7af4 000920badfa401102ed Page 34 of PKgenwiz.c
a48ca8 ¤   return bReturnCode;
07efe6 }
6baf5a
e8af5a
70d4d4 //¤ ______________________________________________
70465d //
1ee19f // ·Dialog procedure for designated revocation key dialog
d7af5a
fe5678 static LRESULT WINAPI·
7c0057 sKeyWizardRevokerDlgProc (
5a3a3a ¤   ¤   HWND¤   hDlg,·
48eb77 ¤   ¤   UINT¤   uMsg,·
0e17d4 ¤   ¤   WPARAM¤ wParam,·
5cc0b8 ¤   ¤   LPARAM¤ lParam)·
e5bb36 {
532ccd ¤   PKEYGENINFO¤¤   pkgi;
cc0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
d4af5a
c7347f ¤   switch (uMsg) {
332940 ¤   case WM_INITDIALOG:
e75b34 ¤   ¤   {
69509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
90e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
da423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
cdcdcb ¤   ¤   ¤   break;
d10fe4 ¤   ¤   }
0baf5a
6485ca ¤   case WM_PAINT :
3b2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
53d515 ¤   ¤   if (pkgi->hPalette)
6b5b34 ¤   ¤   {
8bf431 ¤   ¤   ¤   PAINTSTRUCT ps;
26638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
48cada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
c99ffe ¤   ¤   ¤   RealizePalette (hDC);
845dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
8e0fe4 ¤   ¤   }
9c2f68 ¤   ¤   break;
8caf5a
c6c93c ¤   case WM_NOTIFY:
38ed49 ¤   ¤   {¤
285808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
4faf5a
19e55c ¤   ¤   ¤   switch (pnmh->code) {
f066bc ¤   ¤   ¤   case PSN_SETACTIVE:
c1577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
637bf7 ¤   ¤   ¤   ¤   if ((PGPKeyRefIsValid (pkgi->RevokerKey)) &&
f8ca99 ¤   ¤   ¤   ¤   ¤   (pkgi->uKeyType != kPGPPublicKeyAlgorithm_RSA))
7372c3 ¤   ¤   ¤   ¤   {
1c1b2a ¤   ¤   ¤   ¤   ¤   CHAR sz[kPGPMaxUserIDSize];
02bfe2 ¤   ¤   ¤   ¤   ¤   UINT u;
7f9a83 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent (hDlg),·
452a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
55d8a3 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
4f5452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
f5d620 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
c88d11 ¤   ¤   ¤   ¤   ¤   u = sizeof(sz);
e6c10e ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (pkgi->RevokerKey,·
b9282a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz, &u);
be25d8 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_REVOCATIONKEY, sz);
782613 ¤   ¤   ¤   ¤   }
5e5109 ¤   ¤   ¤   ¤   else·
1ed30e ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L); // skip page
d2af5a
b0841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
96f622 ¤   ¤   ¤   ¤   break;
92af5a
906122 ¤   ¤   ¤   case PSN_HELP:
685535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
68e08d ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_REVOKERKEY);·
d9f622 ¤   ¤   ¤   ¤   break;
92af5a
--76a1 00014eab20d401102ed Page 35 of PKgenwiz.c
658f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
fcf622 ¤   ¤   ¤   ¤   break;
50a3a6 ¤   ¤   ¤   }
1fcdcb ¤   ¤   ¤   break;
bb0fe4 ¤   ¤   }
5d9371 ¤   }
08af5a
978ca8 ¤   return bReturnCode;
d6efe6 }
cfaf5a
0baf5a
3ad4d4 //¤ ______________________________________________
1d465d //
4d22b8 // ·Dialog procedure for Corporate cert key dialog
a9af5a
bc5678 static LRESULT WINAPI·
e679c5 sKeyWizardCorpCertDlgProc (
783a3a ¤   ¤   HWND¤   hDlg,·
5ceb77 ¤   ¤   UINT¤   uMsg,·
c317d4 ¤   ¤   WPARAM¤ wParam,·
ffc0b8 ¤   ¤   LPARAM¤ lParam)·
83bb36 {
582ccd ¤   PKEYGENINFO¤¤   pkgi;
980f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
6caf5a
ac347f ¤   switch (uMsg) {
8a2940 ¤   case WM_INITDIALOG:
665b34 ¤   ¤   {
43509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
a3e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
fa423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
9ccdcb ¤   ¤   ¤   break;
0d0fe4 ¤   ¤   }
81af5a
7a85ca ¤   case WM_PAINT :
d22463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
cbd515 ¤   ¤   if (pkgi->hPalette)
c25b34 ¤   ¤   {
31f431 ¤   ¤   ¤   PAINTSTRUCT ps;
39638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
28cada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
ab9ffe ¤   ¤   ¤   RealizePalette (hDC);
6b5dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
4b0fe4 ¤   ¤   }
b82f68 ¤   ¤   break;
46af5a
6cc93c ¤   case WM_NOTIFY:
aeed49 ¤   ¤   {¤
e45808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
40af5a
aae55c ¤   ¤   ¤   switch (pnmh->code) {
c066bc ¤   ¤   ¤   case PSN_SETACTIVE:
40577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
df7f70 ¤   ¤   ¤   ¤   if (pkgi->CorpKey) {
4c1b2a ¤   ¤   ¤   ¤   ¤   CHAR sz[kPGPMaxUserIDSize];
a0bfe2 ¤   ¤   ¤   ¤   ¤   UINT u;
5c9a83 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent (hDlg),·
bc2a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
fed8a3 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
325452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
33d620 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
2f8d11 ¤   ¤   ¤   ¤   ¤   u = sizeof(sz);
ba5315 ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (pkgi->CorpKey,·
b4282a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz, &u);
fb3d69 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_CORPCERTKEY, sz);
972613 ¤   ¤   ¤   ¤   }
ab5109 ¤   ¤   ¤   ¤   else·
92d30e ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L); // skip page
20af5a
f2841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
ebf622 ¤   ¤   ¤   ¤   break;
14af5a
--9b90 000eaddeb86401102ed Page 36 of PKgenwiz.c
dc6122 ¤   ¤   ¤   case PSN_HELP:
805535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
cf103f ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_CORPKEY);·
8df622 ¤   ¤   ¤   ¤   break;
62af5a
988f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
4cf622 ¤   ¤   ¤   ¤   break;
08a3a6 ¤   ¤   ¤   }
67cdcb ¤   ¤   ¤   break;
610fe4 ¤   ¤   }
039371 ¤   }
9baf5a
708ca8 ¤   return bReturnCode;
33efe6 }
3eaf5a
e7af5a
a4d4d4 //¤ ______________________________________________
f8465d //
987119 // ·Dialog procedure for "ADK" dialog
0baf5a
5d5678 static LRESULT WINAPI·
00e2e8 sKeyWizardADKDlgProc (
b53a3a ¤   ¤   HWND¤   hDlg,·
12eb77 ¤   ¤   UINT¤   uMsg,·
5f17d4 ¤   ¤   WPARAM¤ wParam,·
55c0b8 ¤   ¤   LPARAM¤ lParam)·
afbb36 {
d82ccd ¤   PKEYGENINFO¤¤   pkgi;
1e0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
88af5a
23347f ¤   switch (uMsg) {
242940 ¤   case WM_INITDIALOG:
725b34 ¤   ¤   {
84509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
f1e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
0f423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
1ecdcb ¤   ¤   ¤   break;
dc0fe4 ¤   ¤   }
48af5a
a285ca ¤   case WM_PAINT :
e22463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
a9d515 ¤   ¤   if (pkgi->hPalette)
175b34 ¤   ¤   {
a2f431 ¤   ¤   ¤   PAINTSTRUCT ps;
e3638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
ddcada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
619ffe ¤   ¤   ¤   RealizePalette (hDC);
605dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
b10fe4 ¤   ¤   }
382f68 ¤   ¤   break;
00af5a
b0c93c ¤   case WM_NOTIFY:
03ed49 ¤   ¤   {¤
285808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
acaf5a
aae55c ¤   ¤   ¤   switch (pnmh->code) {
8b66bc ¤   ¤   ¤   case PSN_SETACTIVE:
bf577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
40fc1c ¤   ¤   ¤   ¤   if ((pkgi->ADK) &&
972cce ¤   ¤   ¤   ¤   ¤   (pkgi->uKeyType != kPGPPublicKeyAlgorithm_RSA))·
2772c3 ¤   ¤   ¤   ¤   {
9a1b2a ¤   ¤   ¤   ¤   ¤   CHAR sz[kPGPMaxUserIDSize];
88bfe2 ¤   ¤   ¤   ¤   ¤   UINT u;
4e9a83 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent (hDlg),·
ec2a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
31d8a3 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
835452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
72d620 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
5f8d11 ¤   ¤   ¤   ¤   ¤   u = sizeof(sz);
98fcf5 ¤   ¤   ¤   ¤   ¤   PGPGetPrimaryUserIDNameBuffer (pkgi->ADK,·
d6282a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(sz), sz, &u);
ea53d0 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_ADK, sz);
--2113 000e92fb16a401102ed Page 37 of PKgenwiz.c
862613 ¤   ¤   ¤   ¤   }
265109 ¤   ¤   ¤   ¤   else·
2cd30e ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L); // skip page
3faf5a
b3841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
61f622 ¤   ¤   ¤   ¤   break;
daaf5a
c86122 ¤   ¤   ¤   case PSN_HELP:
e55535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
ab8be5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_ADK);·
b0f622 ¤   ¤   ¤   ¤   break;
b1af5a
e48f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
abf622 ¤   ¤   ¤   ¤   break;
42a3a6 ¤   ¤   ¤   }
3bcdcb ¤   ¤   ¤   break;
740fe4 ¤   ¤   }
6e9371 ¤   }
29af5a
b38ca8 ¤   return bReturnCode;
3aefe6 }
7aaf5a
8eaf5a
efd4d4 //¤ ______________________________________________
e2465d //
12c042 // ·Dialog procedure for getting expiration info of key
0b2192 // ·from user
faaf5a
575678 static LRESULT WINAPI·
d3c584 sKeyWizardExpirationDlgProc (
c13a3a ¤   ¤   HWND¤   hDlg,·
2aeb77 ¤   ¤   UINT¤   uMsg,·
8f17d4 ¤   ¤   WPARAM¤ wParam,·
50c0b8 ¤   ¤   LPARAM¤ lParam)·
89bb36 {
ba2ccd ¤   PKEYGENINFO¤¤   pkgi;
b20f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
ee8e57 ¤   INT¤¤   ¤   ¤   iExpireDays;
013f62 ¤   SYSTEMTIME¤ ¤   stExpire;
1caf5a
07347f ¤   switch (uMsg) {
e02940 ¤   case WM_INITDIALOG:
255b34 ¤   ¤   {
294849 ¤   ¤   ¤   RECT¤   ¤   ¤   rc;
bb7784 ¤   ¤   ¤   PROPSHEETPAGE¤  *ppspMsgRec = (PROPSHEETPAGE *) lParam;
2daf5a
30e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
80423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
e087c7 ¤   ¤   ¤
b3a6c6 ¤   ¤   ¤   // create and initialize date/time picker control
c1810a ¤   ¤   ¤   GetWindowRect (GetDlgItem (hDlg, IDC_EXPIRATIONDATE), &rc);
2c485d ¤   ¤   ¤   MapWindowPoints (NULL, hDlg, (LPPOINT)&rc, 2);
9e1e0f ¤   ¤   ¤   pkgi->hwndExpirationDate = CreateWindowEx (0, DATETIMEPICK_CLASS,
11970b ¤   ¤   ·························"DateTime",
7cc59a ¤   ¤   ·························WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
4a24bb ¤   ¤   ·························rc.left, rc.top,·
d36cc9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·rc.right-rc.left, rc.bottom-rc.top,·
081ec1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·hDlg, NULL, g_hInst, NULL);
8edecd ¤   ¤   ¤   SendMessage (pkgi->hwndExpirationDate, DTM_SETMCCOLOR,·
946e0e ¤   ¤   ¤   ¤   ¤   ¤   MCSC_MONTHBK, (LPARAM)GetSysColor (COLOR_3DFACE));
58af5a
a8f8d1 ¤   ¤   ¤   if (!pkgi->uExpireDays) {
2f5d6a ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_NEVER,·
6f2bd4 ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
cee762 ¤   ¤   ¤   ¤   EnableWindow (pkgi->hwndExpirationDate, FALSE);
f7a3a6 ¤   ¤   ¤   }
f8e543 ¤   ¤   ¤   else {
3e9822 ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_CUSTOM_DAYS,·
462bd4 ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
1eeb8f ¤   ¤   ¤   ¤   EnableWindow (pkgi->hwndExpirationDate, TRUE);
35a3a6 ¤   ¤   ¤   }
e9cdcb ¤   ¤   ¤   break;
--2b97 000d201418c401102ed Page 38 of PKgenwiz.c
b50fe4 ¤   ¤   }
e6af5a
2085ca ¤   case WM_PAINT :
cb2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
50d515 ¤   ¤   if (pkgi->hPalette)
ba5b34 ¤   ¤   {
dff431 ¤   ¤   ¤   PAINTSTRUCT ps;
c0638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
eacada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
879ffe ¤   ¤   ¤   RealizePalette (hDC);
855dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
b90fe4 ¤   ¤   }
a62f68 ¤   ¤   break;
69af5a
383fcf ¤   case WM_COMMAND:
292463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
aa1185 ¤   ¤   switch (LOWORD (wParam)) {
21f821 ¤   ¤   case IDC_EXPIRATIONDATE :
0912fc ¤   ¤   ¤   SetFocus (pkgi->hwndExpirationDate);
d0cdcb ¤   ¤   ¤   break;
a5af5a
d73b04 ¤   ¤   case IDC_RADIO_NEVER :
eb141d ¤   ¤   case IDC_RADIO_CUSTOM_DAYS :
afae79 ¤   ¤   ¤   if (IsDlgButtonChecked·
58b5b3 ¤   ¤   ¤   ¤   ¤   (hDlg, IDC_RADIO_CUSTOM_DAYS) == BST_CHECKED) {
57eb8f ¤   ¤   ¤   ¤   EnableWindow (pkgi->hwndExpirationDate, TRUE);
c1e5ad ¤   ¤   ¤   ¤   SendMessage (pkgi->hwndExpirationDate, DTM_GETSYSTEMTIME,
4d23cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&stExpire);
7f91ec ¤   ¤   ¤   ¤   PGPclSystemTimeToDays (&stExpire, &iExpireDays);
88130e ¤   ¤   ¤   ¤   if (iExpireDays > 0)·
2f4351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
e62a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
115109 ¤   ¤   ¤   ¤   else·
b24351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
ae4a20 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
d6a3a6 ¤   ¤   ¤   }
e4e543 ¤   ¤   ¤   else {
38e762 ¤   ¤   ¤   ¤   EnableWindow (pkgi->hwndExpirationDate, FALSE);
259be3 ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
632a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
69a3a6 ¤   ¤   ¤   }
c3cdcb ¤   ¤   ¤   break;
6f0fe4 ¤   ¤   }
1b2f68 ¤   ¤   break;
97af5a
99c93c ¤   case WM_NOTIFY:
fc5b34 ¤   ¤   {
9f7ee0 ¤   ¤   ¤   BOOL¤   bInRange = TRUE;
665808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
67af5a
82e55c ¤   ¤   ¤   switch (pnmh->code) {
5193c0 ¤   ¤   ¤   case DTN_DATETIMECHANGE :
fa577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
72e5ad ¤   ¤   ¤   ¤   SendMessage (pkgi->hwndExpirationDate, DTM_GETSYSTEMTIME,
c423cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&stExpire);
1891ec ¤   ¤   ¤   ¤   PGPclSystemTimeToDays (&stExpire, &iExpireDays);
64130e ¤   ¤   ¤   ¤   if (iExpireDays > 0)·
234351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
242a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
345109 ¤   ¤   ¤   ¤   else·
c94351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
054a20 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
c5f622 ¤   ¤   ¤   ¤   break;
61af5a
5466bc ¤   ¤   ¤   case PSN_SETACTIVE:
ad577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
599be3 ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
bc2a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
d7c3aa ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
cc5452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
17e5ad ¤   ¤   ¤   ¤   SendMessage (pkgi->hwndExpirationDate, DTM_GETSYSTEMTIME,
d223cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&stExpire);
--7aa9 0007c0f432f401102ed Page 39 of PKgenwiz.c
1191ec ¤   ¤   ¤   ¤   PGPclSystemTimeToDays (&stExpire, &iExpireDays);
25479b ¤   ¤   ¤   ¤   if ((iExpireDays > 0) ||·
00575b ¤   ¤   ¤   ¤   ¤   (IsDlgButtonChecked (hDlg, IDC_RADIO_NEVER) ==·
acb49b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED))
fd4351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
ff2a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
bc5109 ¤   ¤   ¤   ¤   else·
554351 ¤   ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
cf4a20 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
25f095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
45841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
fef622 ¤   ¤   ¤   ¤   break;
afaf5a
3799a3 ¤   ¤   ¤   case PSN_WIZNEXT:
db577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
fcaf5a
e9db69 ¤   ¤   ¤   ¤   if (SendDlgItemMessage (hDlg, IDC_RADIO_NEVER,·
148ce5 ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
e88d3e ¤   ¤   ¤   ¤   ¤   iExpireDays = 0;
5fdeaa ¤   ¤   ¤   ¤   else {
799ce7 ¤   ¤   ¤   ¤   ¤   SendMessage (pkgi->hwndExpirationDate, DTM_GETSYSTEMTIME,
0923cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, (LPARAM)&stExpire);
bb1ba9 ¤   ¤   ¤   ¤   ¤   PGPclSystemTimeToDays (&stExpire, &iExpireDays);
7d2613 ¤   ¤   ¤   ¤   }
7baf5a
d7c01e ¤   ¤   ¤   ¤   pkgi->uExpireDays = (UINT)iExpireDays;
f9f622 ¤   ¤   ¤   ¤   break;
5caf5a
736122 ¤   ¤   ¤   case PSN_HELP:
9e5535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
d5ffe7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_EXPIRATION);·
c1f622 ¤   ¤   ¤   ¤   break;
afaf5a
9b8f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
abf622 ¤   ¤   ¤   ¤   break;
dca3a6 ¤   ¤   ¤   }
55cdcb ¤   ¤   ¤   break;
c50fe4 ¤   ¤   }
3d9371 ¤   }
d4af5a
658ca8 ¤   return bReturnCode;
78efe6 }
06af5a
3aaf5a
27d4d4 //¤ ______________________________________________
0e465d //
4ab162 // ·Dialog procedure for getting size of key (number of bits)
852192 // ·from user
90af5a
525678 static LRESULT WINAPI·
08c481 sKeyWizardSizeDlgProc (
673a3a ¤   ¤   HWND¤   hDlg,·
c6eb77 ¤   ¤   UINT¤   uMsg,·
3f17d4 ¤   ¤   WPARAM¤ wParam,·
80c0b8 ¤   ¤   LPARAM¤ lParam)·
d6bb36 {
ab2ccd ¤   PKEYGENINFO¤¤   pkgi;
800f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
fbaf5a
e6347f ¤   switch (uMsg) {
a72940 ¤   case WM_INITDIALOG:
565b34 ¤   ¤   {
63509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
9de006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
41423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
64af5a
53b66c ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CUSTOM_BITS, EM_SETLIMITTEXT, 4, 0);
5abffb ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CUSTOM_BITS, WM_ENABLE,·
0d48d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE, 0);
5eaf5a
27e98b ¤   ¤   ¤   if (pkgi->uKeySize < pkgi->uMinKeySize)·
7c988b ¤   ¤   ¤   ¤   pkgi->uKeySize = pkgi->uMinKeySize;
--2934 0000bafcb1b401102ed Page 40 of PKgenwiz.c
d74355 ¤   ¤   ¤   SetDlgItemInt (hDlg, IDC_CUSTOM_BITS, pkgi->uKeySize, FALSE);
14af5a
d2411f ¤   ¤   ¤   if (pkgi->uMinKeySize > 768)·
8f1578 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_RADIO_768), FALSE);
c510a8 ¤   ¤   ¤   if (pkgi->uMinKeySize > 1024)·
49eb36 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_RADIO_1024), FALSE);
6d361d ¤   ¤   ¤   if (pkgi->uMinKeySize > 1536)·
506173 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_RADIO_1536), FALSE);
03146a ¤   ¤   ¤   if (pkgi->uMinKeySize > 2048)·
88213c ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_RADIO_2048), FALSE);
434add ¤   ¤   ¤   if (pkgi->uMinKeySize > 3072)·
1c6fb6 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_RADIO_3072), FALSE);
1baf5a
643a48 ¤   ¤   ¤   switch (pkgi->uKeySize) {
ce5203 ¤   ¤   ¤   case 768:
4da1b9 ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_768,·
1fcd98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
4ff622 ¤   ¤   ¤   ¤   break;
70af5a
c4c4e6 ¤   ¤   ¤   case 1024:
c9879e ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_1024,·
2fcd98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
62f622 ¤   ¤   ¤   ¤   break;
00af5a
754bb1 ¤   ¤   ¤   case 1536:
89a12b ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_1536,·
5ecd98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
53f622 ¤   ¤   ¤   ¤   break;
77af5a
0f26a2 ¤   ¤   ¤   case 2048:
06835c ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_2048,·
f0cd98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
58f622 ¤   ¤   ¤   ¤   break;
e7af5a
0c743e ¤   ¤   ¤   case 3072:
01ddeb ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_3072,·
c7cd98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
01f622 ¤   ¤   ¤   ¤   break;
6faf5a
45db68 ¤   ¤   ¤   default:
d3e46b ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_CUSTOM,·
5ccd98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_SETCHECK, BST_CHECKED, 0);
034d6f ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CUSTOM_BITS,·
4ff44b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_ENABLE, TRUE, 0);
e4f622 ¤   ¤   ¤   ¤   break;
a9a3a6 ¤   ¤   ¤   }
2acdcb ¤   ¤   ¤   break;
8a0fe4 ¤   ¤   }
e6af5a
2885ca ¤   case WM_PAINT :
302463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
41d515 ¤   ¤   if (pkgi->hPalette)
ac5b34 ¤   ¤   {
68f431 ¤   ¤   ¤   PAINTSTRUCT ps;
b3638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
14cada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
159ffe ¤   ¤   ¤   RealizePalette (hDC);
6d5dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
480fe4 ¤   ¤   }
f32f68 ¤   ¤   break;
7aaf5a
903fcf ¤   case WM_COMMAND:
625b34 ¤   ¤   {
572783 ¤   ¤   ¤   switch (HIWORD(wParam)) {
3d81b2 ¤   ¤   ¤   case BN_CLICKED:
21d642 ¤   ¤   ¤   ¤   if (LOWORD (wParam) == IDC_RADIO_CUSTOM) {
2b8973 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CUSTOM_BITS,·
52f44b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_ENABLE, TRUE, 0);
c9d670 ¤   ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_CUSTOM_BITS));
d42b89 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CUSTOM_BITS, EM_SETSEL,
3a48f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)0, (LPARAM)-1);
0b2613 ¤   ¤   ¤   ¤   }
--bd3f 0004509e2d8401102ed Page 41 of PKgenwiz.c
62deaa ¤   ¤   ¤   ¤   else {
ba8973 ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_CUSTOM_BITS,·
0861d2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_ENABLE, FALSE, 0);
ec2613 ¤   ¤   ¤   ¤   }
17f622 ¤   ¤   ¤   ¤   break;
91a3a6 ¤   ¤   ¤   }
d9cdcb ¤   ¤   ¤   break;
760fe4 ¤   ¤   }
96af5a
8dc93c ¤   case WM_NOTIFY:
eb5b34 ¤   ¤   {
67ef7b ¤   ¤   ¤   UINT¤   uMaxKeySize;
8cf88b ¤   ¤   ¤   UINT¤   uKeySize = 0;
d3569b ¤   ¤   ¤   CHAR¤   szText[64];
22d865 ¤   ¤   ¤   CHAR¤   szText2[64];
555808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
c5af5a
f8302d ¤   ¤   ¤   switch(pnmh->code) {
6e66bc ¤   ¤   ¤   case PSN_SETACTIVE:
4a577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
d89be3 ¤   ¤   ¤   ¤   PostMessage (GetParent(hDlg),·
992a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
191647 ¤   ¤   ¤   ¤   SendDlgItemMessage(hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
675452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
f5f095 ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, 0L);
63841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
b9af5a
efa0ef ¤   ¤   ¤   ¤   if (pkgi->uKeyType == kPGPPublicKeyAlgorithm_DSA) {
4b16e0 ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_RADIO_3072), SW_SHOW);
e2820e ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATIC_SMALL_GUIDE),·
655b39 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SW_SHOW);
7d64db ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_DSACUSTOM,·
c0d27a ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
7a0080 ¤   ¤   ¤   ¤   ¤   wsprintf (szText2, szText, pkgi->uMinKeySize);
46d5f0 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RADIO_CUSTOM, szText2);
158c77 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_DSA1536,·
a3d27a ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
99ae57 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RADIO_1536, szText);
9aae00 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_DSA2048,·
2cd27a ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
1eee18 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RADIO_2048, szText);
a5f0b7 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_DSA3072,·
02d27a ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
dca092 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RADIO_3072, szText);
ab2613 ¤   ¤   ¤   ¤   }
8bdeaa ¤   ¤   ¤   ¤   else {
9a6cbb ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_RADIO_3072), SW_HIDE);
37820e ¤   ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_STATIC_SMALL_GUIDE),·
8f2162 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SW_HIDE);
4e76ce ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_RSACUSTOM,·
5cd27a ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
ae0080 ¤   ¤   ¤   ¤   ¤   wsprintf (szText2, szText, pkgi->uMinKeySize);
53d5f0 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RADIO_CUSTOM, szText2);
7cb6f7 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_RSA1536,·
24d27a ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
7fae57 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RADIO_1536, szText);
8f9480 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_RSA2048,·
9ed27a ¤   ¤   ¤   ¤   ¤   ¤   ¤   szText, sizeof(szText));
55ee18 ¤   ¤   ¤   ¤   ¤   SetDlgItemText (hDlg, IDC_RADIO_2048, szText);
db2613 ¤   ¤   ¤   ¤   }
b8f622 ¤   ¤   ¤   ¤   break;
58af5a
09d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
b1577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
c2af5a
2eda12 ¤   ¤   ¤   ¤   if (SendDlgItemMessage (hDlg, IDC_RADIO_768,·
348ce5 ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
00d1f7 ¤   ¤   ¤   ¤   ¤   uKeySize = 768;
258f85 ¤   ¤   ¤   ¤   else if (SendDlgItemMessage (hDlg, IDC_RADIO_1024,·
ff8ce5 ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
f836ca ¤   ¤   ¤   ¤   ¤   uKeySize = 1024;
45a930 ¤   ¤   ¤   ¤   else if (SendDlgItemMessage (hDlg, IDC_RADIO_1536,·
--73ee 000e5b0ac08401102ed Page 42 of PKgenwiz.c
8d8ce5 ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
e8b99d ¤   ¤   ¤   ¤   ¤   uKeySize = 1536;
4a8b47 ¤   ¤   ¤   ¤   else if (SendDlgItemMessage (hDlg, IDC_RADIO_2048,·
518ce5 ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
74d48e ¤   ¤   ¤   ¤   ¤   uKeySize = 2048;
9fd5f0 ¤   ¤   ¤   ¤   else if (SendDlgItemMessage (hDlg, IDC_RADIO_3072,·
2f8ce5 ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
6e8612 ¤   ¤   ¤   ¤   ¤   uKeySize = 3072;
49191a ¤   ¤   ¤   ¤   else if (SendDlgItemMessage (hDlg, IDC_RADIO_CUSTOM,·
c21232 ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED) {
3ee2fe ¤   ¤   ¤   ¤   ¤   uKeySize = GetDlgItemInt(hDlg, IDC_CUSTOM_BITS,·
6535f8 ¤   ¤   ¤   ¤   ¤   ¤   NULL, FALSE);
682613 ¤   ¤   ¤   ¤   }
07af5a
4faa80 ¤   ¤   ¤   ¤   if (pkgi->uKeyType == kPGPPublicKeyAlgorithm_RSA)
a0da55 ¤   ¤   ¤   ¤   ¤   uMaxKeySize = MAX_RSA_KEY_SIZE;
e25109 ¤   ¤   ¤   ¤   else·
bb02ef ¤   ¤   ¤   ¤   ¤   uMaxKeySize = MAX_DSA_KEY_SIZE;
b8af5a
eb2d24 ¤   ¤   ¤   ¤   if ((uKeySize < pkgi->uMinKeySize) ||·
d9b145 ¤   ¤   ¤   ¤   ¤   (uKeySize > uMaxKeySize)) {
34c27c ¤   ¤   ¤   ¤   ¤   CHAR szError[1024], szTitle[1024], szTemp[1024];
881f25 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_INVALID_KEY_SIZE,·
c451f3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTemp, sizeof(szTemp));
838d08 ¤   ¤   ¤   ¤   ¤   LoadString (g_hInst, IDS_KW_TITLE,·
fac69b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTitle, sizeof(szTitle));
5c1fb4 ¤   ¤   ¤   ¤   ¤   wsprintf (szError, szTemp,·
8e96c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->uMinKeySize, uMaxKeySize);
0476a6 ¤   ¤   ¤   ¤   ¤   MessageBox (hDlg, szError, szTitle, MB_OK|MB_ICONERROR);
cef882 ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L);
294149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
c42613 ¤   ¤   ¤   ¤   }
0ddeaa ¤   ¤   ¤   ¤   else {
d3d234 ·¤  ¤   ¤   ¤   ¤   if (pkgi->uKeyType == kPGPPublicKeyAlgorithm_DSA)·
c24859 ¤   ¤   ¤   ¤   ¤   {
b4f43d ·¤  ¤   ¤   ¤   ¤   ¤   pkgi->uKeySize = sGetDSAKeySize (uKeySize);
60dfa9 ·¤  ¤   ¤   ¤   ¤   ¤   pkgi->uSubKeySize = uKeySize;
08981e ·¤  ¤   ¤   ¤   ¤   }
5a6d00 ·¤  ¤   ¤   ¤   ¤   else {
ac8d01 ·¤  ¤   ¤   ¤   ¤   ¤   pkgi->uKeySize = uKeySize;
58981e ·¤  ¤   ¤   ¤   ¤   }
0e2613 ¤   ¤   ¤   ¤   }
72af5a
78f622 ¤   ¤   ¤   ¤   break;
52af5a
916122 ¤   ¤   ¤   case PSN_HELP:
185535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
3428bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_SIZE);·
c1f622 ¤   ¤   ¤   ¤   break;
f6af5a
428f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
a9f622 ¤   ¤   ¤   ¤   break;
90a3a6 ¤   ¤   ¤   }
62cdcb ¤   ¤   ¤   break;
070fe4 ¤   ¤   }
aa9371 ¤   }
9caf5a
5d8ca8 ¤   return bReturnCode;
b2efe6 }
70af5a
c5af5a
b6d4d4 //¤ ______________________________________________
89465d //
f85722 // ·Dialog procedure for getting type of key (RSA/DSA)
282192 // ·from user
fcaf5a
905678 static LRESULT WINAPI·
83e681 sKeyWizardTypeDlgProc (
ce3a3a ¤   ¤   HWND¤   hDlg,·
71eb77 ¤   ¤   UINT¤   uMsg,·
9b17d4 ¤   ¤   WPARAM¤ wParam,·
e5c0b8 ¤   ¤   LPARAM¤ lParam)·
--157d 000019948a6401102ed Page 43 of PKgenwiz.c
2cbb36 {
a42ccd ¤   PKEYGENINFO¤¤   pkgi;
160f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
0caf5a
fa347f ¤   switch (uMsg) {
e32940 ¤   case WM_INITDIALOG:
885b34 ¤   ¤   {
cd509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
90e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
35423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
80af5a
b640ce ¤   ¤   ¤   if (!pkgi->bAllowRSAGen) {
f2896e ¤   ¤   ¤   ¤   pkgi->uKeyType = kPGPPublicKeyAlgorithm_DSA;
4e5da2 ¤   ¤   ¤   ¤   EnableWindow (GetDlgItem (hDlg, IDC_RADIO_RSA), FALSE);
a6a3ed ¤   ¤   ¤   ¤   ShowWindow (GetDlgItem (hDlg, IDC_NORSAGENTEXT), SW_SHOW);
8ba3a6 ¤   ¤   ¤   }
0eaf5a
293a81 ¤   ¤   ¤   switch (pkgi->uKeyType) {
2cf26a ¤   ¤   ¤   case kPGPPublicKeyAlgorithm_RSA:
ab2a20 ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_RSA, BM_SETCHECK,·
4ea66e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED, 0);
71f622 ¤   ¤   ¤   ¤   break;
6caf5a
3d7db2 ¤   ¤   ¤   case kPGPPublicKeyAlgorithm_DSA:
d4f517 ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_RADIO_ELGAMAL, BM_SETCHECK,·
22a66e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BST_CHECKED, 0);
0af622 ¤   ¤   ¤   ¤   break;
faa3a6 ¤   ¤   ¤   }
2acdcb ¤   ¤   ¤   break;
610fe4 ¤   ¤   }
75af5a
d285ca ¤   case WM_PAINT :
d72463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
89d515 ¤   ¤   if (pkgi->hPalette)
b55b34 ¤   ¤   {
4ff431 ¤   ¤   ¤   PAINTSTRUCT ps;
37638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
ebcada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
7e9ffe ¤   ¤   ¤   RealizePalette (hDC);
d45dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
270fe4 ¤   ¤   }
a52f68 ¤   ¤   break;
0caf5a
05c93c ¤   case WM_NOTIFY:
935b34 ¤   ¤   {
46d05b ¤   ¤   ¤   UINT¤   uKeyType;
ce5808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
a4af5a
a3af5a
fb302d ¤   ¤   ¤   switch(pnmh->code) {
c366bc ¤   ¤   ¤   case PSN_SETACTIVE:
34577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
c74e82 ¤   ¤   ¤   ¤   if (!pkgi->bAllowRSAGen) {
45d30e ¤   ¤   ¤   ¤   ¤   SetWindowLong (hDlg, DWL_MSGRESULT, -1L); // skip page
392613 ¤   ¤   ¤   ¤   }
51deaa ¤   ¤   ¤   ¤   else {
b9ce55 ¤   ¤   ¤   ¤   ¤   PostMessage(GetParent(hDlg),·
4d2a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
bec6ec ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage(hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
5e5452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
d08fd1 ¤   ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
c42613 ¤   ¤   ¤   ¤   }
69841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
59f622 ¤   ¤   ¤   ¤   break;
b9af5a
61d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
c75cb4 ¤   ¤   ¤   ¤   uKeyType = kPGPPublicKeyAlgorithm_DSA +·
8e49ca ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_RSA;
df577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
90af5a
a56de5 ¤   ¤   ¤   ¤   if (SendDlgItemMessage (hDlg, IDC_RADIO_RSA,·
0101fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
--9027 0008f54ec5c401102ed Page 44 of PKgenwiz.c
4b6195 ¤   ¤   ¤   ¤   ¤   uKeyType = kPGPPublicKeyAlgorithm_RSA;
63bd18 ¤   ¤   ¤   ¤   else if(SendDlgItemMessage(hDlg, IDC_RADIO_ELGAMAL,·
ca01fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BM_GETCHECK, 0, 0) == BST_CHECKED)
f2ee4d ¤   ¤   ¤   ¤   ¤   uKeyType = kPGPPublicKeyAlgorithm_DSA;
bcaf5a
89905d ¤   ¤   ¤   ¤   if ((uKeyType != kPGPPublicKeyAlgorithm_RSA) &&·
84d253 ¤   ¤   ¤   ¤   ¤   (uKeyType != kPGPPublicKeyAlgorithm_DSA)) {
4ed51b ¤   ¤   ¤   ¤   ¤   PKMessageBox (hDlg, IDS_KW_TITLE,·
4ab96c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···IDS_KW_INVALID_KEY_TYPE,·
c2729f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···MB_OK|MB_ICONERROR);
ff1edd ¤   ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, -1L);
6c4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
1c2613 ¤   ¤   ¤   ¤   }
95deaa ¤   ¤   ¤   ¤   else {
c94b35 ¤   ¤   ¤   ¤   ¤   pkgi->uKeyType = uKeyType;
9a2613 ¤   ¤   ¤   ¤   }
010086 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
33841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
3df622 ¤   ¤   ¤   ¤   break;
32af5a
e96122 ¤   ¤   ¤   case PSN_HELP:
ef5535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
372875 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_TYPE);·
e9f622 ¤   ¤   ¤   ¤   break;
a4af5a
448f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
0bf622 ¤   ¤   ¤   ¤   break;
eea3a6 ¤   ¤   ¤   }
23cdcb ¤   ¤   ¤   break;
770fe4 ¤   ¤   }
719371 ¤   }
92af5a
7e8ca8 ¤   return bReturnCode;
11efe6 }
47af5a
2baf5a
38d4d4 //¤ ______________________________________________
be465d //
8347a1 // ·Dialog procedure for getting name and email address
9c2192 // ·from user
95af5a
c25678 static LRESULT WINAPI·
b4ca4e sKeyWizardNameDlgProc (
873a3a ¤   ¤   HWND¤   hDlg,·
41eb77 ¤   ¤   UINT¤   uMsg,·
d317d4 ¤   ¤   WPARAM¤ wParam,·
d4c0b8 ¤   ¤   LPARAM¤ lParam)·
32bb36 {
fc2ccd ¤   PKEYGENINFO¤¤   pkgi;
2a0f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
a0af5a
12347f ¤   switch (uMsg) {
c52940 ¤   case WM_INITDIALOG:
965b34 ¤   ¤   {
62509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
e0e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
12423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
26af5a
de5dfe ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_FULL_NAME, EM_SETLIMITTEXT,·
e243b1 ¤   ¤   ¤   ¤   MAX_FULL_NAME_LEN, 0);
e18a74 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_EMAIL, EM_SETLIMITTEXT,·
e703fc ¤   ¤   ¤   ¤   MAX_EMAIL_LEN, 0);
cdcdcb ¤   ¤   ¤   break;
aa0fe4 ¤   ¤   }
c8af5a
ae85ca ¤   case WM_PAINT :
5c2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
aad515 ¤   ¤   if (pkgi->hPalette)
e55b34 ¤   ¤   {
5bf431 ¤   ¤   ¤   PAINTSTRUCT ps;
19638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
8fcada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
--2ae5 0004f84f3ef401102ed Page 45 of PKgenwiz.c
e69ffe ¤   ¤   ¤   RealizePalette (hDC);
f95dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
1c0fe4 ¤   ¤   }
a72f68 ¤   ¤   break;
97af5a
51c93c ¤   case WM_NOTIFY:
575b34 ¤   ¤   {
b8f2a5 ¤   ¤   ¤   INT¤¤   iTextLen;
5a39b6 ¤   ¤   ¤   BOOL¤   bContinue = TRUE;
135808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
75af5a
9b302d ¤   ¤   ¤   switch(pnmh->code) {
f466bc ¤   ¤   ¤   case PSN_SETACTIVE:
42577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
cd816b ¤   ¤   ¤   ¤   PostMessage(GetParent(hDlg),·
ac2a7f ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_BACK|PSWIZB_NEXT);
2d1647 ¤   ¤   ¤   ¤   SendDlgItemMessage(hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
795452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
2d0086 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
f5841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
eaf622 ¤   ¤   ¤   ¤   break;
5baf5a
f3d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
070086 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
58841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
91f622 ¤   ¤   ¤   ¤   break;
37af5a
c06122 ¤   ¤   ¤   case PSN_HELP:
d85535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
6f4994 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_NAME);·
cef622 ¤   ¤   ¤   ¤   break;
c2af5a
488f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
5bf622 ¤   ¤   ¤   ¤   break;
8eaf5a
c999a3 ¤   ¤   ¤   case PSN_WIZNEXT:
cd577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
7faf5a
9823ad ¤   ¤   ¤   ¤   if (pkgi->pszFullName) {
5998b1 ¤   ¤   ¤   ¤   ¤   pkFree (pkgi->pszFullName);
266ebb ¤   ¤   ¤   ¤   ¤   pkgi->pszFullName = NULL;
2d2613 ¤   ¤   ¤   ¤   }
abaf5a
7b3ec9 ¤   ¤   ¤   ¤   if (pkgi->pszEmail) {
d569e7 ¤   ¤   ¤   ¤   ¤   pkFree (pkgi->pszEmail);
aec704 ¤   ¤   ¤   ¤   ¤   pkgi->pszEmail = NULL;
432613 ¤   ¤   ¤   ¤   }
73af5a
3cd506 ¤   ¤   ¤   ¤   // allocate string and get name from edit box
53146e ¤   ¤   ¤   ¤   iTextLen = SendDlgItemMessage (hDlg, IDC_FULL_NAME,·
842965 ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) + 1;
cd1fe3 ¤   ¤   ¤   ¤   pkgi->pszFullName = pkAlloc (iTextLen * sizeof(char));
488953 ¤   ¤   ¤   ¤   if (pkgi->pszFullName)·
1ab7af ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_FULL_NAME,·
598d42 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->pszFullName, iTextLen);
20af5a
1fd6ce ¤   ¤   ¤   ¤   // no name entered, warn user
a48ee7 ¤   ¤   ¤   ¤   if (iTextLen <= 1) {
bfd51b ¤   ¤   ¤   ¤   ¤   PKMessageBox (hDlg, IDS_KW_TITLE,·
f03da8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·IDS_KW_NO_FULL_NAME,·
f7937d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·MB_OK|MB_ICONWARNING);
c89c99 ¤   ¤   ¤   ¤   ¤   bContinue = FALSE;
de5bcf ¤   ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_FULL_NAME));
920770 ¤   ¤   ¤   ¤   }·
7fae30 ¤   ¤   ¤   ¤   ¤
836d37 ¤   ¤   ¤   ¤   if (bContinue) {
05555a ¤   ¤   ¤   ¤   ¤   iTextLen = SendDlgItemMessage (hDlg, IDC_EMAIL,·
1f37f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_GETTEXTLENGTH, 0, 0) + 1;
0e3fc8 ¤   ¤   ¤   ¤   ¤   pkgi->pszEmail = pkAlloc (iTextLen * sizeof(char));
cb1575 ¤   ¤   ¤   ¤   ¤   if (pkgi->pszEmail)
ad98b2 ¤   ¤   ¤   ¤   ¤   ¤   GetDlgItemText (hDlg, IDC_EMAIL,·
4f6812 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pkgi->pszEmail, iTextLen);
--1648 000a3d63a38401102ed Page 46 of PKgenwiz.c
028b0a ¤   ¤   ¤   ¤   ¤   if (iTextLen <= 1) {
8be748 ¤   ¤   ¤   ¤   ¤   ¤   if ((PKMessageBox (hDlg, IDS_KW_TITLE,·
ca349c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_KW_NO_EMAIL,·
b457df ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_YESNO|MB_ICONWARNING|
694483 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MB_DEFBUTTON2) != IDYES)) {
65034d ¤   ¤   ¤   ¤   ¤   ¤   ¤   bContinue = FALSE;
3b1f46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetFocus (GetDlgItem (hDlg, IDC_EMAIL));
abdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
781c89 ¤   ¤   ¤   ¤   ¤   }
ee2613 ¤   ¤   ¤   ¤   }
4feb42 ¤   ¤   ¤   ¤   if (!bContinue) {
4f1edd ¤   ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, -1L);
0f4149 ¤   ¤   ¤   ¤   ¤   bReturnCode = TRUE;
922613 ¤   ¤   ¤   ¤   }
31a3a6 ¤   ¤   ¤   }
150fe4 ¤   ¤   }
e89371 ¤   }
90af5a
538ca8 ¤   return bReturnCode;
8cefe6 }
5daf5a
01af5a
8ad4d4 //¤ ______________________________________________
af465d //
a0b713 // ·Dialog procedure for handling beginning introductory
f11579 // ·dialog.
06af5a
0b5678 static LRESULT WINAPI·
bb8284 sKeyWizardIntroDlgProc (
693a3a ¤   ¤   HWND¤   hDlg,·
5ceb77 ¤   ¤   UINT¤   uMsg,·
4b0303 ¤   ¤   WPARAM¤ wParam,
62c0b8 ¤   ¤   LPARAM¤ lParam)·
90bb36 {
110f09 ¤   BOOL¤   ¤   ¤   bReturnCode = FALSE;
986892 ¤   PKEYGENINFO¤¤   pkgi¤   ¤   = NULL;
76af5a
d2347f ¤   switch (uMsg) {
1f2940 ¤   case WM_INITDIALOG:
2d5b34 ¤   ¤   {
29afc0 ¤   ¤   ¤   RECT rc;
56af5a
a2509f ¤   ¤   ¤   PROPSHEETPAGE *ppspMsgRec = (PROPSHEETPAGE *) lParam;
76e006 ¤   ¤   ¤   pkgi = (PKEYGENINFO) ppspMsgRec->lParam;
9e423c ¤   ¤   ¤   SetWindowLong (hDlg, GWL_USERDATA, (LPARAM)pkgi);
31af5a
13015a ¤   ¤   ¤   // center dialog on screen
5eaca3 ¤   ¤   ¤   GetWindowRect(GetParent(hDlg), &rc);
dfc04f ¤   ¤   ¤   SetWindowPos (GetParent(hDlg), NULL,
bb0971 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left))/2,
8a004e ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top))/2,
60f9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
f0cdcb ¤   ¤   ¤   break;
030fe4 ¤   ¤   }
d0af5a
a8ae91 ¤   case WM_ACTIVATE :
d9a652 ¤   ¤   InvalidateRect (hDlg, NULL, TRUE);
f52f68 ¤   ¤   break;
7aaf5a
7885ca ¤   case WM_PAINT :
2b2463 ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
e0d515 ¤   ¤   if (pkgi->hPalette)
f55b34 ¤   ¤   {
eff431 ¤   ¤   ¤   PAINTSTRUCT ps;
8e638f ¤   ¤   ¤   HDC¤hDC = BeginPaint (hDlg, &ps);
1ecada ¤   ¤   ¤   SelectPalette (hDC, pkgi->hPalette, FALSE);
6a9ffe ¤   ¤   ¤   RealizePalette (hDC);
995dd8 ¤   ¤   ¤   EndPaint (hDlg, &ps);
720fe4 ¤   ¤   }
512f68 ¤   ¤   break;
68af5a
a3c93c ¤   case WM_NOTIFY:
--5051 000bb479c1c401102ed Page 47 of PKgenwiz.c
e35b34 ¤   ¤   {
ea5808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
62af5a
2c302d ¤   ¤   ¤   switch(pnmh->code) {
9566bc ¤   ¤   ¤   case PSN_SETACTIVE:
a2577a ¤   ¤   ¤   ¤   pkgi = (PKEYGENINFO)GetWindowLong (hDlg, GWL_USERDATA);
24816b ¤   ¤   ¤   ¤   PostMessage(GetParent(hDlg),·
2269e2 ¤   ¤   ¤   ¤   ¤   ¤   PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
101647 ¤   ¤   ¤   ¤   SendDlgItemMessage(hDlg, IDC_WIZBITMAP, STM_SETIMAGE,·
375452 ¤   ¤   ¤   ¤   ¤   ¤   IMAGE_BITMAP, (LPARAM) pkgi->hBitmap);
9f0086 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
f9841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
05f622 ¤   ¤   ¤   ¤   break;
76af5a
68d105 ¤   ¤   ¤   case PSN_KILLACTIVE:
550086 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, DWL_MSGRESULT, 0L);
17841c ¤   ¤   ¤   ¤   bReturnCode = TRUE;
81f622 ¤   ¤   ¤   ¤   break;
44af5a
766122 ¤   ¤   ¤   case PSN_HELP:
ba5535 ¤   ¤   ¤   ¤   WinHelp (hDlg, g_szHelpFile, HELP_CONTEXT,·
72a444 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDH_PGPPK_WIZ_ABOUT);·
f6f622 ¤   ¤   ¤   ¤   break;
3aaf5a
a68f46 ¤   ¤   ¤   case PSN_QUERYCANCEL:
8cf622 ¤   ¤   ¤   ¤   break;
fba3a6 ¤   ¤   ¤   }
ca87c7 ¤   ¤   ¤
aacdcb ¤   ¤   ¤   break;
a70fe4 ¤   ¤   }
189371 ¤   }
a3af5a
908ca8 ¤   return bReturnCode;
e1efe6 }
51af5a
eaaf5a
e2d4d4 //¤ ______________________________________________
3e465d //
178349 // Load DIB bitmap and associated palette
75af5a
d7597e static HPALETTE·
0b3928 sCreateDIBPalette (
01eee1 ¤   ¤   LPBITMAPINFO¤   lpbmi,·
cf5a14 ¤   ¤   LPINT¤  ¤   ¤   lpiNumColors)·
a5bb36 {
fce3ed ¤   LPBITMAPINFOHEADER lpbi;
ee0377 ¤   LPLOGPALETTE lpPal;
cfdcb6 ¤   HANDLE hLogPal;
c4abc2 ¤   HPALETTE hPal = NULL;
accdd6 ¤   INT i;
ead83c ·
147407 ¤   lpbi = (LPBITMAPINFOHEADER)lpbmi;
eaff30 ¤   if (lpbi->biBitCount <= 8) {
fe5406 ¤   ¤   *lpiNumColors = (1 << lpbi->biBitCount);
749371 ¤   }
f70e24 ¤   else
d121cc ¤   ¤   *lpiNumColors = 0; ·// No palette needed for 24 BPP DIB
a0d83c ·
14f623 ¤   if (*lpiNumColors) {
870012 ¤   ¤   hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
45440c ·····························sizeof (PALETTEENTRY) * (*lpiNumColors));
e1d92a ¤   ¤   lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
825442 ¤   ¤   lpPal->palVersion = 0x300;
b24b35 ¤   ¤   lpPal->palNumEntries = *lpiNumColors;
0dd83c ·
20a249 ¤   ¤   for (i = 0; ·i < *lpiNumColors; ·i++) {
38d118 ¤   ¤   ¤   lpPal->palPalEntry[i].peRed ··= lpbmi->bmiColors[i].rgbRed;
00dc94 ¤   ¤   ¤   lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
301adf ¤   ¤   ¤   lpPal->palPalEntry[i].peBlue ·= lpbmi->bmiColors[i].rgbBlue;
69089b ¤   ¤   ¤   lpPal->palPalEntry[i].peFlags = 0;
6a0fe4 ¤   ¤   }
bb898e ¤   ¤   hPal = CreatePalette (lpPal);
--4fc7 0002bba6afb401102ed Page 48 of PKgenwiz.c
4893f7 ¤   ¤   GlobalUnlock (hLogPal);
12b50d ¤   ¤   GlobalFree (hLogPal);
75b144 ···}
fdef80 ···return hPal;
f3efe6 }
47af5a
42af5a
f7fb93 static HBITMAP·
922666 sLoadResourceBitmap (
20e109 ¤   ¤   HINSTANCE¤  hInstance,·
58d507 ¤   ¤   LPSTR¤  ¤   lpString,
9d042b ¤   ¤   HPALETTE*¤  phPalette)·
38bb36 {
73ef32 ¤   HRSRC ·hRsrc;
049627 ¤   HGLOBAL hGlobal;
b7cfb4 ¤   HBITMAP hBitmapFinal = NULL;
cce3ed ¤   LPBITMAPINFOHEADER lpbi;
530755 ¤   HDC hdc;
7f5789 ····INT iNumColors;
8ed83c ·
3de2a3 ¤   if (hRsrc = FindResource (hInstance, lpString, RT_BITMAP)) {
11aa39 ¤   ¤   hGlobal = LoadResource (hInstance, hRsrc);
3626b6 ¤   ¤   lpbi = (LPBITMAPINFOHEADER)LockResource (hGlobal);
07d83c ·
77002d ¤   ¤   hdc = GetDC(NULL);
293923 ¤   ¤   *phPalette = ·sCreateDIBPalette ((LPBITMAPINFO)lpbi, &iNumColors);
3e0fad ¤   ¤   if (*phPalette) {
3c3634 ¤   ¤   ¤   SelectPalette (hdc,*phPalette,FALSE);
ea703c ¤   ¤   ¤   RealizePalette (hdc);
670fe4 ¤   ¤   }
80d83c ·
60259d ¤   ¤   hBitmapFinal = CreateDIBitmap (hdc,
4a14f2 ···················(LPBITMAPINFOHEADER)lpbi,
f5e478 ···················(LONG)CBM_INIT,
d1d8e7 ···················(LPSTR)lpbi + lpbi->biSize + iNumColors * sizeof(RGBQUAD),
f4e564 ···················(LPBITMAPINFO)lpbi,
7aa1a1 ···················DIB_RGB_COLORS );
ffd83c ·
3d6078 ¤   ¤   ReleaseDC (NULL,hdc);
4466f7 ¤   ¤   UnlockResource (hGlobal);
b41d90 ¤   ¤   FreeResource (hGlobal);
149371 ¤   }
40aa7e ¤   return (hBitmapFinal);
1cefe6 }
c0af5a
c1af5a
cfd4d4 //¤ ______________________________________________
a5465d //
ee1f7c // ·Create wizard data structures and call PropertySheet·
ac56fa // ·to actually create wizard
e5af5a
ebe6b2 static VOID
510da5 sCreateKeyGenWizard (VOID *pArg)
e2bb36 {
843157 ¤   KEYGENINFO¤ ¤   KGInfo;
22fcfa ¤   PROPSHEETPAGE ··pspWiz[NUM_WIZ_PAGES];
054a77 ¤   PROPSHEETHEADER pshWiz;
610c32 ¤   INT¤¤   ¤   ¤   iIndex;
4a2c49 ¤   INT¤¤   ¤   ¤   iNumBits, iBitmap;
2c07aa ¤   HDC¤¤   ¤   ¤   hDC;
4b9f29 ¤   HWND¤   ¤   ¤   hWndMain = (HWND)pArg;
3efb19 ¤   PGPError¤   ¤   err;
21af5a
5daebc ¤   // Set defaults
5dc42a ¤   KGInfo.Context¤ ¤   ¤   = g_Context;
c69f48 ¤   KGInfo.tlsContext¤  ¤   = g_TLSContext;
7b8c34 ¤   KGInfo.PrefRefAdmin¤¤   = NULL;
625b19 ¤   KGInfo.PrefRefClient¤   = NULL;
45466c ¤   KGInfo.hWndWiz¤ ¤   ¤   = NULL;
952f9d ¤   KGInfo.hPalette¤¤   ¤   = NULL;
80af5a
2bc81b ¤   // Determine which bitmap will be displayed in the wizard
--7802 000687f649d401102ed Page 49 of PKgenwiz.c
e0af5a
5e5389 ¤   hDC = GetDC (NULL);¤ // DC for desktop
3589fe ¤   iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
78e693 ¤   ReleaseDC (NULL, hDC);
77af5a
fc01be ¤   if (iNumBits <= 1)
f343f1 ¤   ¤   iBitmap = IDB_KEYWIZ1;
9bf2dd ¤   else if (iNumBits <= 4)·
817a4c ¤   ¤   iBitmap = IDB_KEYWIZ4;
014264 ¤   else·
2edfef ¤   ¤   iBitmap = IDB_KEYWIZ8;
67af5a
3176d9 ¤   KGInfo.hBitmap = sLoadResourceBitmap (g_hInst,·
beff2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··MAKEINTRESOURCE (iBitmap),
c56fe6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··&KGInfo.hPalette);
69af5a
b0667e ¤   // Set the values common to all pages
75505d ¤   for (iIndex=0; iIndex<NUM_WIZ_PAGES; iIndex++)
c3c7a1 ¤   {
0d9379 ¤   ¤   pspWiz[iIndex].dwSize¤  ¤   = sizeof(PROPSHEETPAGE);
b0e05a ¤   ¤   pspWiz[iIndex].dwFlags¤ ¤   = PSP_DEFAULT | PSP_HASHELP;
c5fb75 ¤   ¤   pspWiz[iIndex].hInstance¤   = g_hInst;
7d014e ¤   ¤   pspWiz[iIndex].pszTemplate ·= NULL;
379267 ¤   ¤   pspWiz[iIndex].hIcon¤   ¤   = NULL;
82ba02 ¤   ¤   pspWiz[iIndex].pszTitle¤¤   = NULL;
658a9a ¤   ¤   pspWiz[iIndex].pfnDlgProc ··= NULL;
3c8032 ¤   ¤   pspWiz[iIndex].lParam¤  ¤   = (LPARAM) &KGInfo;
432149 ¤   ¤   pspWiz[iIndex].pfnCallback ·= NULL;
13eb5c ¤   ¤   pspWiz[iIndex].pcRefParent ·= NULL;
6f9371 ¤   }
11af5a
37af5a
64c8da ¤   // Set up the intro page
d367c7 ¤   pspWiz[KGWIZ_INTRO].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_INTRO);
494b92 ¤   pspWiz[KGWIZ_INTRO].pfnDlgProc = sKeyWizardIntroDlgProc;
7867c5 ¤
d79aeb ¤   // Set up the name page
2eb3e6 ¤   pspWiz[KGWIZ_NAME].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_NAME);
6ebc20 ¤   pspWiz[KGWIZ_NAME].pfnDlgProc = sKeyWizardNameDlgProc;
c9af5a
db1825 ¤   // Set up the type page
36ddb4 ¤   pspWiz[KGWIZ_TYPE].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_TYPE);
49c47c ¤   pspWiz[KGWIZ_TYPE].pfnDlgProc = sKeyWizardTypeDlgProc;
2a67c5 ¤
e80597 ¤   // Set up the size page
e09431 ¤   pspWiz[KGWIZ_SIZE].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_SIZE);
2a6355 ¤   pspWiz[KGWIZ_SIZE].pfnDlgProc = sKeyWizardSizeDlgProc;
db67c5 ¤
301711 ¤   // Set up the expiration page
8c4bc0 ¤   pspWiz[KGWIZ_EXPIRE].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_EXPIRATION);
842be2 ¤   pspWiz[KGWIZ_EXPIRE].pfnDlgProc = sKeyWizardExpirationDlgProc;
e467c5 ¤
a2ab0c ¤   // Set up the ADK page
bba264 ¤   pspWiz[KGWIZ_ADK].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_ADK);
c83a98 ¤   pspWiz[KGWIZ_ADK].pfnDlgProc = sKeyWizardADKDlgProc;
4767c5 ¤
f4f5e2 ¤   // Set up the corporate cert page
957ae0 ¤   pspWiz[KGWIZ_CORPCERT].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_CORPCERT);
b5cc1f ¤   pspWiz[KGWIZ_CORPCERT].pfnDlgProc = sKeyWizardCorpCertDlgProc;
6967c5 ¤
abd41d ¤   // Set up the designated revoker page
ca3f05 ¤   pspWiz[KGWIZ_REVOKER].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_REVOKER);
b09d1d ¤   pspWiz[KGWIZ_REVOKER].pfnDlgProc = sKeyWizardRevokerDlgProc;
da67c5 ¤
373e8b ¤   // Set up the passphrase page
e555eb ¤   pspWiz[KGWIZ_PHRASE].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_PASSPHRASE);
9b7c97 ¤   pspWiz[KGWIZ_PHRASE].pfnDlgProc = sKeyWizardPassphraseDlgProc;
bd67c5 ¤
f6b815 ¤   // Set up the bad passphrase page
208902 ¤   pspWiz[KGWIZ_BADPHRASE].pszTemplate =·
92695d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_KEYWIZ_BADPHRASE);
68fb4a ¤   pspWiz[KGWIZ_BADPHRASE].pfnDlgProc = sKeyWizardBadPassphraseDlgProc;
--c827 0003b2c0224401102ed Page 50 of PKgenwiz.c
2a67c5 ¤
40126c ¤   // Set up the entropy page
89c434 ¤   pspWiz[KGWIZ_ENTROPY].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_RANDOBITS);
007261 ¤   pspWiz[KGWIZ_ENTROPY].pfnDlgProc = sKeyWizardRandobitsDlgProc;
f967c5 ¤
be58b0 ¤   // Set up the key generation page
f66022 ¤   pspWiz[KGWIZ_KEYGEN].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_GENERATION);
324a92 ¤   pspWiz[KGWIZ_KEYGEN].pfnDlgProc = sKeyWizardGenerationDlgProc;
1867c5 ¤
4fd99f ¤   // Set up the sign key page
94bf13 ¤   pspWiz[KGWIZ_SIGN].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_SIGN_OLD);
39f599 ¤   pspWiz[KGWIZ_SIGN].pfnDlgProc = sKeyWizardSignOldDlgProc;
b6af5a
6915db ¤   // Set up the presend to server page
2bf595 ¤   pspWiz[KGWIZ_PRESEND].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_PRESEND);
85ba0d ¤   pspWiz[KGWIZ_PRESEND].pfnDlgProc = sKeyWizardPreSendDlgProc;
04af5a
29d8b8 ¤   // Set up the send to server page
920e9d ¤   pspWiz[KGWIZ_SEND].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_SEND);
82b84b ¤   pspWiz[KGWIZ_SEND].pfnDlgProc = sKeyWizardSendToServerDlgProc;
efaf5a
f9fa89 ¤   // Set up the done page
085cb7 ¤   pspWiz[KGWIZ_DONE].pszTemplate = MAKEINTRESOURCE(IDD_KEYWIZ_DONE);
2d838f ¤   pspWiz[KGWIZ_DONE].pfnDlgProc = sKeyWizardDoneDlgProc;
faaf5a
d4fe81 ¤   // Create the header
4279d3 ¤   pshWiz.dwSize¤  ¤   = sizeof(PROPSHEETHEADER);
0cabcc ¤   pshWiz.dwFlags¤ ¤   = PSH_WIZARD | PSH_PROPSHEETPAGE;
76422d ¤   pshWiz.hwndParent ··= hWndMain;
8f7bf4 ¤   pshWiz.hInstance¤   = g_hInst;
b6ac7c ¤   pshWiz.hIcon¤   ¤   = NULL;
64de3c ¤   pshWiz.pszCaption ··= NULL;
167f64 ¤   pshWiz.nPages¤  ¤   = NUM_WIZ_PAGES;
07fc15 ¤   pshWiz.nStartPage ··= KGWIZ_INTRO;
77db1b ¤   pshWiz.ppsp¤¤   ¤   = pspWiz;
4d1f52 ¤   pshWiz.pfnCallback ·= NULL;
f4af5a
74d340 ¤   sInstallWindowsHooks ();
5caf5a
a3be29 #if PGP_BUSINESS_SECURITY
4f654a ¤   err = PGPclOpenAdminPrefs (
63ce55 ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
5ae4d1 ¤   ¤   ¤   ¤   &KGInfo.PrefRefAdmin, FALSE);
83db21 #else
3c6493 ¤   err = kPGPError_NoErr;
237454 #endif
5db23e ¤   if (IsntPGPError (err)) {
76e290 ¤   ¤   if (sValidateConfiguration (&KGInfo)) {
9a421f ¤   ¤   ¤   PGPclOpenClientPrefs (
299bf9 ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
d85c74 ¤   ¤   ¤   ¤   ¤   &KGInfo.PrefRefClient);
8daf5a
0f3943 ¤   ¤   ¤   // Execute the Wizard - doesn't return until Cancel or Save
04896c ¤   ¤   ¤   PropertySheet(&pshWiz);
57af5a
61ef8a ¤   ¤   ¤   PGPclCloseClientPrefs (KGInfo.PrefRefClient, FALSE);
8e0fe4 ¤   ¤   }
926df7 ¤   ¤   if (KGInfo.PrefRefAdmin)
0ca2b5 ¤   ¤   ¤   PGPclCloseAdminPrefs (KGInfo.PrefRefAdmin, FALSE);
ae9371 ¤   }
45af5a
d9f0ff ¤   sUninstallWindowsHooks ();
51ecdd ¤   hWndCollectEntropy = NULL;
20af5a
3d2c6a ¤   // Free allocated memory and objects
65af5a
d76fe7 ¤   if (KGInfo.pszPassPhrase) {
41d7e7 ¤   ¤   secFree (KGInfo.pszPassPhrase);
ea8489 ¤   ¤   KGInfo.pszPassPhrase = NULL;
6d9371 ¤   }
feaf5a
3b8d90 ¤   if (KGInfo.pszFullName) {
--4f85 001bdf216a1401102ed Page 51 of PKgenwiz.c
6d7c7d ¤   ¤   pkFree (KGInfo.pszFullName);
6ba5c2 ¤   ¤   KGInfo.pszFullName = NULL;
6c9371 ¤   }
f2af5a
b56557 ¤   if (KGInfo.pszEmail) {
b08e28 ¤   ¤   pkFree (KGInfo.pszEmail);
949dc7 ¤   ¤   KGInfo.pszEmail = NULL;
c49371 ¤   }
1caf5a
8a5c99 ¤   if (KGInfo.pszUserID) {
865d65 ¤   ¤   pkFree (KGInfo.pszUserID);
8cba6a ¤   ¤   KGInfo.pszUserID = NULL;
c29371 ¤   }
57af5a
25ffd3 ¤   DeleteObject (KGInfo.hBitmap);
4caf5a
883c13 ¤   if (!KGInfo.bFinishSelected) {
c22bf4 ¤   ¤   PGPKeySetRef KeySet;
908e69 ¤   ¤   if (KGInfo.Key) {
36c865 ¤   ¤   ¤   PGPclErrorBox (NULL, PGPNewSingletonKeySet (KGInfo.Key,·
4d3592 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &KeySet));
81aff1 ¤   ¤   ¤   PGPclErrorBox (NULL, PGPRemoveKeys (KeySet, KeySetMain));
ae7ae3 ¤   ¤   ¤   PGPFreeKeySet (KeySet);
b8d7ad ¤   ¤   ¤   PGPCommitKeyRingChanges (KeySetMain);
050fe4 ¤   ¤   }
566a9f ¤   ¤   KGInfo.iFinalResult = 0;
039371 ¤   }
c0af5a
1c8a7b ¤   SendMessage (hWndMain, KM_M_CREATEDONE, KGInfo.iFinalResult,·
983e1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) KGInfo.Key);·
45af5a
dc830f ¤   return;
f0efe6 }
3faf5a
b4af5a
c1d4d4 //¤ ______________________________________________
c0465d //
9e1bea // ·Create thread to handle dialog box·
22af5a
65fe80 VOID
794de4 PKCreateKey (
0b910c ¤   HWND¤   ¤   ¤   hParent,·
8b6b70 ¤   PGPKeySetRef¤   keyset)·
c7bb36 {
a8e031 ¤   DWORD dwNewKeyThreadID;
8897c5 ¤   ULONG ul;
bdaf5a
5b9265 ¤   PGPclSetSplashParent (NULL);
4a61d5 ¤   EnableWindow (hParent, FALSE);
afecdd ¤   hWndCollectEntropy = NULL;
dd5330 ¤   KeySetMain = keyset;
80af5a
e6d078 ¤   ul = _beginthreadex (¤  NULL, 0,·
7a4617 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPTHREAD_START_ROUTINE)sCreateKeyGenWizard,·
3b49b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hParent, 0, &dwNewKeyThreadID);
bdefe6 }
--7e31 0019242786f401102ee Page 1 of Search.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
a66209 ¤   All rights reserved.¤
deaf5a
20c047 ¤   $Id: Search.c,v 1.9 1998/08/11 15:20:15 pbj Exp $
b2f7f7 ____________________________________________________________________________*/
42af5a
ba5060 // System Headers·
a85655 #include <windows.h>
913d0b #include <windowsx.h>
2d90fb #include <commctrl.h>
48af5a
00af5a
e25582 // PGPsdk Headers
51a076 #include "pgpKeys.h"
e32f8d #include "pgpErrors.h"
e7eb5b #include "pgpKeyServer.h"
deed82 #include "pgpKeyServerPrefs.h"
16ec82 #include "pgpTLS.h"
3e81a4 #include "pgpBuildFlags.h"
964919 #include "pgpUtilities.h"
2eaf5a
18e8e0 // Project Headers
f965f9 #include "Search.h"
9fcccc #include "SearchProc.h"
da8031 #include "resource.h"
2eaf5a
0d7efe BOOL·
2d408d InitSearch()
15bb36 {
f6bee8 ¤   BOOL ReturnValue = TRUE;
cbaf5a
6e9a51 ¤   InitCommonControls();
c2af5a
d91965 ¤   return ReturnValue;
3cefe6 }
e0af5a
71c823 void·
413b88 CloseSearch()
43bb36 {
fe830f ¤   return;
e9efe6 }
e0af5a
1563e9 HWND·
c2c67d CreateSearch(HINSTANCE hInstance,·
1d5a90 ¤   ¤   ¤   ·HWND hwndParent)
97bb36 {
fe25f6 ¤   HWND hwndSearch = NULL;
f19bbf ¤   RECT rectParent;
91af5a
7284f4 ¤   GetClientRect(hwndParent, &rectParent);
92af5a
579ee7 ¤   hwndSearch = CreateDialog(¤ hInstance,·
fba0d5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_SEARCH),·
97a77a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndParent,·
9c448f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DLGPROC)SearchProc);
b067c5 ¤
498339 ¤   return hwndSearch;
92efe6 }
--a5d8 00067af731c401102ef Page 1 of Search.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
a19ee1 ¤   $Id: Search.h,v 1.19.2.1 1998/10/28 23:11:43 pbj Exp $
61f7f7 ____________________________________________________________________________*/
62af5a
fa139c #ifndef _SEARCH_H
4ccec5 #define _SEARCH_H
2aaf5a
0fc5d5 #include "pgpBase.h"
8982bb #include "pgpKeyServerPrefs.h"·
3baf5a
a6a36e #define SEARCH_DISPLAY_KEYSET¤  ¤   WM_APP + 100
c5cb87 #define SEARCH_SIZING¤  ¤   ¤   ¤   WM_APP + 101
cfdb5c #define SEARCH_REQUEST_SIZING¤  ¤   WM_APP + 102
245a71 #define SEARCH_PROGRESS¤¤   ¤   ¤   WM_APP + 103
af252b #define SEARCH_ABORT¤   ¤   ¤   ¤   WM_APP + 104
4528b0 #define SEARCH_SECURE_STATUS¤   ¤   WM_APP + 105
1aaf5a
40ff69 #define SEARCH_SET_LOCAL_KEYSET¤¤   WM_APP + 110
fde60b #define SEARCH_SET_CURRENT_SEARCH¤  WM_APP + 111
224ce9 #define SEARCH_SET_FOCUS¤   ¤   ¤   WM_APP + 112
9daf5a
001fd5 #define REFRESH_KEYSERVER_LIST¤ ¤   WM_APP + 120
dfaf5a
f6da32 #define FLAG_SEARCH_LOCAL_KEYSET¤   1L
116d70 #define FLAG_SEARCH_MEMORY¤ ¤   ¤   2L
db8e1a #define FLAG_AREA_PENDING¤  ¤   ¤   4L
8aaf5a
82e1e0 #define SEARCH_PROGRESS_INFINITE¤   -1L
dbaf5a
eb1a8f typedef struct _SEARCHRESULT
15bb36 {
cb6896 ¤   NMHDR¤  ¤   ¤   ¤   nmhdr;
d9b43a ¤   void*¤  ¤   ¤   ¤   pData;
61f6dc ¤   PGPKeyServerEntry¤  keyserver;
108008 ¤   PGPError¤   ¤   ¤   error;
5acd02 ¤   long¤   ¤   ¤   ¤   flags;
4aaf5a
cfcec2 }SEARCHRESULT, *PSEARCHRESULT;
9faf5a
7de13c typedef struct _SEARCHPROGRESS
c0bb36 {
2f0deb ¤   NMHDR¤  nmhdr;
05e688 ¤   char¤   message[256];
ca85cc ¤   long¤   step;
15cbb0 ¤   long¤   total;
ca5fe4 }SEARCHPROGRESS, *PSEARCHPROGRESS;
06af5a
5d189b typedef struct _SEARCHABORT
8fbb36 {
aa45d2 ¤   NMHDR¤  ¤   nmhdr;
0e87a6 ¤   PGPError¤   error;
5dac82 }SEARCHABORT, *PSEARCHABORT;
2daf5a
4628dd typedef struct _SEARCHSECURE
17bb36 {
f430f7 ¤   NMHDR¤  ¤   ¤   nmhdr;
e78fe6 ¤   BOOL¤   ¤   ¤   secure;
6d6902 ¤   char¤   ¤   ¤   szServerName[256];
750028 ¤   PGPKeyRef¤  ¤   keyAuth;
944aa4 }SEARCHSECURE, *PSEARCHSECURE;
c1af5a
2eaf5a
3c97d6 typedef struct _SIZEREQUEST
00bb36 {
a20deb ¤   NMHDR¤  nmhdr;
27f74b ¤   int¤¤   delta;
3ecb98 }SIZEREQUEST, *PSIZEREQUEST;
72af5a
67af5a
--2014 0013d882cc9401102ef Page 2 of Search.h
1abb10 // call this function before calling any·
d46998 // Search Functions
0b7efe BOOL·
4eaeab InitSearch(¤void );
90af5a
d0c823 void·
2b4d1e CloseSearch( void );
12af5a
1b6c61 // This function creates a Search Control·
15c48e // It places itself in the upper left corner
0c3b00 // of the parent control.·
66465d //
8463e9 HWND·
59c67d CreateSearch(HINSTANCE hInstance,·
430cee ¤   ¤   ¤   ·HWND hwndParent );
1daf5a
3da6de #endif#d¶
--73e5 0000200a51f401102f0 Page 1 of SearchCommon.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
a66209 ¤   All rights reserved.¤
deaf5a
ad2b32 ¤   $Id: SearchCommon.c,v 1.28 1998/08/11 15:20:17 pbj Exp $
a7f7f7 ____________________________________________________________________________*/
283281 #include <windows.h> ·
c13d0b #include <windowsx.h>
d090fb #include <commctrl.h>
2caf5a
2da076 #include "pgpKeys.h"
492f8d #include "pgpErrors.h"
c84919 #include "pgpUtilities.h"
bbed82 #include "pgpKeyServerPrefs.h"
48c97b #include "pgpClientPrefs.h"
74af5a
6b5ab2 #include "PGPcl.h"
bcaf5a
7b65f9 #include "Search.h"
f9354b #include "Choice.h"
cbb4b6 #include "SearchFilter.h"
af1323 #include "SearchCommon.h"
92af5a
748031 #include "resource.h"
98af5a
a517c6 extern PGPContextRef g_Context;
f7af5a
29c8f9 void HANDLE_IDC_ATTRIBUTE(¤ HWND hwnd,·
075c16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
a5cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
a14868 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam)
78bb36 {
f2031f ¤   WORD wNotifyCode¤   ¤   ¤   = HIWORD(wParam); // notification code·
52b1e2 ¤   HWND hwndCtl¤   ¤   ¤   ¤   = (HWND) lParam; ·// handle of control·
b853b4 ¤   static BOOL bCancel¤¤   ¤   = FALSE;
7b5639 ¤   static BOOL bChange¤¤   ¤   = FALSE;
89af5a
bd168f ¤   if( wNotifyCode == CBN_SELCHANGE /*&& bChange*/)
02c7a1 ¤   {
4c5edc ¤   ¤   ChangeAttributeSelection(hwndCtl);
22cf2f ¤   ¤   bChange = FALSE;
009371 ¤   }
97efe6 }
1167c5 ¤
eed614 void ReloadKeyserverList(HWND hwnd)
60bb36 {
7a402c ¤   HINSTANCE hinst¤¤   ¤   = GetModuleHandle(NULL);
b85e20 ¤   HWND hwndBox¤   ¤   ¤   = NULL;
e11865 ¤   char szString[512]¤ ¤   = {0x00};
ee12bc ¤   LPARAM lastSearch¤  ¤   = 0;
aeed01 ¤   int¤lastSearchIndex¤¤   = 0;
dbb360 ¤   LPARAM localKeyset¤ ¤   = 0;
74940c ¤   int¤localKeysetIndex¤   = 0;
913e9d ¤   LPARAM searchPathInfo¤  = 0;
ec29fe ¤   int searchPathIndex¤¤   = 0;
246449 ¤   char szCurSel[512]¤ ¤   = {0x00};
debefe ¤   PSEARCHPATH path¤   ¤   = NULL;
02af5a
b17020 ¤   hwndBox = GetDlgItem(hwnd, IDC_LOCATION);
22af5a
d37fe9 ¤   // get text of current selection
877822 ¤   ComboBox_GetText(hwndBox, szCurSel, sizeof(szCurSel));
baaf5a
a7cc55 ¤   if( hwndBox )·
6dc7a1 ¤   {
c06614 ¤   ¤   int index = 0;
59af5a
9d997d ¤   ¤   LoadString(hinst, IDS_CURRENT_SEARCH, szString, sizeof(szString));
cc16ea ¤   ¤   lastSearchIndex = ComboBox_FindString(hwndBox, -1, szString);
84af5a
8ec0ce ¤   ¤   LoadString(hinst, IDS_LOCAL_KEYRING, szString, sizeof(szString));
023be1 ¤   ¤   localKeysetIndex = ComboBox_FindString(hwndBox, -1, szString);
--a60b 0008269d77b401102f0 Page 2 of SearchCommon.c
e0af5a
08f9e1 ¤   ¤   lastSearch = ComboBox_GetItemData(hwndBox, lastSearchIndex);
c8cf60 ¤   ¤   localKeyset = ComboBox_GetItemData(hwndBox, localKeysetIndex);
07af5a
2fc503 ¤   ¤   // delete old combo entries
0e4291 ¤   ¤   ComboBox_ResetContent(hwndBox);
faaf5a
c514c2 ¤   ¤   // free the prefs struct I am using
a1fbb9 ¤   ¤   path = (PSEARCHPATH) GetProp(hwnd, "SearchPath");
c8af5a
933abb ¤   ¤   if(path)
d05b34 ¤   ¤   {
04f70b ¤   ¤   ¤   if (path->keyserverList)·
17eb82 ¤   ¤   ¤   ¤   PGPDisposePrefData (path->prefRef, path->keyserverList);
29af5a
a5dbd8 ¤   ¤   ¤   if (path->prefRef)
fdb854 ¤   ¤   ¤   ¤   PGPclCloseClientPrefs (path->prefRef, FALSE);
82af5a
1054c5 ¤   ¤   ¤   free(path);
660fe4 ¤   ¤   }
e79371 ¤   }
5caf5a
8acc55 ¤   if( hwndBox )·
ebc7a1 ¤   {
c5960e ¤   ¤   PSEARCHPATH¤¤   ¤   searchPath;
a43485 ¤   ¤   PGPPrefRef¤ ¤   ¤   prefRef;
e44927 ¤   ¤   PGPKeyServerEntry*¤ keyserverList;
cf8976 ¤   ¤   PGPUInt32¤  ¤   ¤   keyserverCount;
f10c77 ¤   ¤   PGPError¤   ¤   ¤   error;
e8493c ¤   ¤   int¤¤   ¤   ¤   ¤   i;
3faf5a
b3225f ¤   ¤   // load keyserverprefs
02fb3d ¤   ¤   error = PGPclOpenClientPrefs (
559bf9 ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
6ec49f ¤   ¤   ¤   ¤   ¤   &prefRef);
b3af5a
62a9cb ¤   ¤   if (error == kPGPError_NoErr)
1d5b34 ¤   ¤   {
879d62 ¤   ¤   ¤   error = PGPGetKeyServerPrefs(¤  prefRef,
e32cf8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverList,
f2710a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverCount);
caaf5a
a52e03 ¤   ¤   ¤   if( IsntPGPError(error) )
d9f776 ¤   ¤   ¤   {
387a2e ¤   ¤   ¤   ¤   searchPath = (PSEARCHPATH) malloc(sizeof(SEARCHPATH));
af05fb ¤   ¤   ¤   ¤   memset(searchPath, 0x00, sizeof(SEARCHPATH));
3aaf5a
a6d1e4 ¤   ¤   ¤   ¤   searchPath->prefRef¤¤   ¤   = prefRef;
1f4f5e ¤   ¤   ¤   ¤   searchPath->keyserverList¤  = keyserverList;
1ef427 ¤   ¤   ¤   ¤   searchPath->keyserverCount¤ = keyserverCount;
3daf5a
f7941f ¤   ¤   ¤   ¤   SetProp(hwnd, "SearchPath", (HANDLE)searchPath);
19a3a6 ¤   ¤   ¤   }
710fe4 ¤   ¤   }
20af5a
7cc0ce ¤   ¤   LoadString(hinst, IDS_LOCAL_KEYRING, szString, sizeof(szString));
fa626a ¤   ¤   i = ComboBox_AddString(hwndBox, szString);
af63a8 ¤   ¤   ComboBox_SetItemData(hwndBox, i, localKeyset);
6faf5a
39997d ¤   ¤   LoadString(hinst, IDS_CURRENT_SEARCH, szString, sizeof(szString));
ee626a ¤   ¤   i = ComboBox_AddString(hwndBox, szString);
ab03b4 ¤   ¤   ComboBox_SetItemData(hwndBox, i, lastSearch);
1baf5a
471b52 ¤   ¤
edaf5a
cad26a ¤   ¤   // place listed strings in box if prefs were loaded
99c170 ¤   ¤   if( IsntPGPError(error) )
a55b34 ¤   ¤   {
913130 ¤   ¤   ¤   PGPUInt32¤  index;
f9af5a
50ded9 ¤   ¤   ¤   for(index = 0; index < keyserverCount; index++)
82f776 ¤   ¤   ¤   {
--f178 000c47408bc401102f0 Page 3 of SearchCommon.c
71bc56 ¤   ¤   ¤   ¤   if( IsKeyServerListed( keyserverList[index].flags) )
f572c3 ¤   ¤   ¤   ¤   {
9b8913 ¤   ¤   ¤   ¤   ¤   PGPGetKeyServerURL(&(keyserverList[index]), szString);
cbaf5a
4ebed3 ¤   ¤   ¤   ¤   ¤   i = ComboBox_AddString(¤hwndBox,·
20d2af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szString);
2faf5a
f9a545 ¤   ¤   ¤   ¤   ¤   ComboBox_SetItemData(hwndBox, i,·
992c2c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(keyserverList[index]));¤
622613 ¤   ¤   ¤   ¤   }
7ea3a6 ¤   ¤   ¤   }
860fe4 ¤   ¤   }
4baf5a
34f8ae ¤   ¤   // restore previous selection, if still available
2e4dce ¤   ¤   ComboBox_SetCurSel(hwndBox, 2);
494392 ¤   ¤   ComboBox_SelectString(hwndBox, 0, szCurSel);
699371 ¤   }
fbefe6 }
9aaf5a
38b1e7 void InitializeControlValues(HWND hwnd, int defaultSelection)
5abb36 {
a80a2b ¤   HINSTANCE hinst¤¤   = GetModuleHandle(NULL);
736ef8 ¤   HWND hwndBox¤   ¤   = NULL;
4a6cfe ¤   HWND hwndEdit¤  ¤   = NULL;
308b2f ¤   HWND hwndSpin¤  ¤   = NULL;
aef0c3 ¤   HWND hwndMonth¤ ¤   = NULL;
14f04d ¤   HWND hwndDay¤   ¤   = NULL;
65ddde ¤   char szString[512]¤ = {0x00};
e049d0 ¤   char* cp¤   ¤   ¤   = NULL;
a0c6c0 ¤   char* end¤  ¤   ¤   = NULL;
82ab2f ¤   int i¤  ¤   ¤   ¤   = 0;
07af5a
947020 ¤   hwndBox = GetDlgItem(hwnd, IDC_LOCATION);
09af5a
a14fa3 ¤   if( hwndBox ) // only done for parent search window
16c7a1 ¤   {
dd960e ¤   ¤   PSEARCHPATH¤¤   ¤   searchPath;
6b3485 ¤   ¤   PGPPrefRef¤ ¤   ¤   prefRef;
394927 ¤   ¤   PGPKeyServerEntry*¤ keyserverList;
348976 ¤   ¤   PGPUInt32¤  ¤   ¤   keyserverCount;
0c0c77 ¤   ¤   PGPError¤   ¤   ¤   error;
7c7807 ¤   ¤   PGPUInt32¤  ¤   ¤   selection = 2;
b4af5a
d0225f ¤   ¤   // load keyserverprefs
d3fb3d ¤   ¤   error = PGPclOpenClientPrefs (
9f9bf9 ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
f3c49f ¤   ¤   ¤   ¤   ¤   &prefRef);
d6af5a
56a9cb ¤   ¤   if (error == kPGPError_NoErr)
535b34 ¤   ¤   {
93af5a
239d62 ¤   ¤   ¤   error = PGPGetKeyServerPrefs(¤  prefRef,
dc2cf8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverList,
66710a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverCount);
5aaf5a
c42e03 ¤   ¤   ¤   if( IsntPGPError(error) )
58f776 ¤   ¤   ¤   {
9b7a2e ¤   ¤   ¤   ¤   searchPath = (PSEARCHPATH) malloc(sizeof(SEARCHPATH));
8b05fb ¤   ¤   ¤   ¤   memset(searchPath, 0x00, sizeof(SEARCHPATH));
aeaf5a
01d1e4 ¤   ¤   ¤   ¤   searchPath->prefRef¤¤   ¤   = prefRef;
304f5e ¤   ¤   ¤   ¤   searchPath->keyserverList¤  = keyserverList;
f9f427 ¤   ¤   ¤   ¤   searchPath->keyserverCount¤ = keyserverCount;
f92b85 ¤   ¤   ¤   ¤
6d941f ¤   ¤   ¤   ¤   SetProp(hwnd, "SearchPath", (HANDLE)searchPath);
9eaf5a
c4dfe4 ¤   ¤   ¤   ¤   PGPGetPrefNumber (¤ prefRef,
7be80e ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefLastSearchWindowSelection,·
3513d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUInt32*)&selection);
b2a3a6 ¤   ¤   ¤   }
150fe4 ¤   ¤   }
c4af5a
--8205 000f9692b68401102f0 Page 4 of SearchCommon.c
7bc0ce ¤   ¤   LoadString(hinst, IDS_LOCAL_KEYRING, szString, sizeof(szString));
84626a ¤   ¤   i = ComboBox_AddString(hwndBox, szString);
86339a ¤   ¤   ComboBox_SetItemData(hwndBox, i, NULL);
d7af5a
f4997d ¤   ¤   LoadString(hinst, IDS_CURRENT_SEARCH, szString, sizeof(szString));
08626a ¤   ¤   i = ComboBox_AddString(hwndBox, szString);
6d339a ¤   ¤   ComboBox_SetItemData(hwndBox, i, NULL);
27af5a
87d26a ¤   ¤   // place listed strings in box if prefs were loaded
fbc170 ¤   ¤   if( IsntPGPError(error) )
855b34 ¤   ¤   {
a43130 ¤   ¤   ¤   PGPUInt32¤  index;
1caf5a
4aded9 ¤   ¤   ¤   for(index = 0; index < keyserverCount; index++)
a7f776 ¤   ¤   ¤   {
22bc56 ¤   ¤   ¤   ¤   if( IsKeyServerListed( keyserverList[index].flags) )
bf72c3 ¤   ¤   ¤   ¤   {
238913 ¤   ¤   ¤   ¤   ¤   PGPGetKeyServerURL(&(keyserverList[index]), szString);
f3af5a
7ebed3 ¤   ¤   ¤   ¤   ¤   i = ComboBox_AddString(¤hwndBox,·
e0d2af ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szString);
57af5a
f0a545 ¤   ¤   ¤   ¤   ¤   ComboBox_SetItemData(hwndBox, i,·
a8fc87 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(keyserverList[index]));¤
152613 ¤   ¤   ¤   ¤   }
dba3a6 ¤   ¤   ¤   }
cc0fe4 ¤   ¤   }
6567c5 ¤
cbc725 ¤   ¤   SetProp( hwndBox, "LastSearchType",(HANDLE) 0);
3faf5a
155183 ¤   ¤   ComboBox_SetCurSel(hwndBox, selection);
109371 ¤   }
d6af5a
649d79 ¤   hwndBox = GetDlgItem(hwnd, IDC_ATTRIBUTE);
88af5a
2f4b6e ¤   for(i = IDS_ATTRIBUTE_1; i < IDS_ATTRIBUTE_LAST; i++)
83c7a1 ¤   {
520cb6 ¤   ¤   LoadString(hinst, i, szString, sizeof(szString));
751b52 ¤   ¤
0afb4f ¤   ¤   ComboBox_AddString(hwndBox, szString);
bb9371 ¤   }
9daf5a
a469ac ¤   ComboBox_SetCurSel(hwndBox, defaultSelection);
49af5a
1d165a ¤   ChangeAttributeSelection(hwndBox);
d4efe6 }
f6af5a
ebb2a5 void ChangeAttributeSelection(HWND hwndCtl)
54bb36 {
217531 ¤   int index¤  ¤   ¤   ¤   ¤   = ComboBox_GetCurSel(hwndCtl);
df6201 ¤   HINSTANCE hinst¤¤   ¤   ¤   = GetModuleHandle(NULL);
c7bdf3 ¤   HWND hwndParent¤¤   ¤   ¤   = GetParent(hwndCtl);
46c52e ¤   HWND hwndBox¤   ¤   ¤   ¤   = NULL;
deef24 ¤   HWND hwndEdit¤  ¤   ¤   ¤   = NULL;
162bd2 ¤   HWND hwndBoxList¤   ¤   ¤   = NULL;
f1f106 ¤   HWND hwnd¤  ¤   ¤   ¤   ¤   = NULL;
dc66f1 ¤   HWND hwndTime¤  ¤   ¤   ¤   = GetProp(hwndParent, "hwndTime");
58faf9 ¤   char* cp¤   ¤   ¤   ¤   ¤   = NULL;
853e68 ¤   char* end¤  ¤   ¤   ¤   ¤   = NULL;
f58056 ¤   char szString[256]¤ ¤   ¤   = {0x00};
38af5a
0cdd33 ¤   hwndBox ·= GetDlgItem(hwndParent, IDC_VERB);
4887c4 ¤   ComboBox_ResetContent(hwndBox);
01af5a
df4ab0 ¤   LoadString(¤hinst,·
e438ed ¤   ¤   ¤   ¤   index + IDS_VERBS_ATTRIBUTE_1,·
99419b ¤   ¤   ¤   ¤   szString,·
ff9a54 ¤   ¤   ¤   ¤   sizeof(szString));
dbaf5a
bb7b05 ¤   end = cp = szString;
1eaf5a
f9b1ef ¤   while( cp && *cp )
--d1e6 000f45f87ec401102f0 Page 5 of SearchCommon.c
f7c7a1 ¤   {
34c5c0 ¤   ¤   while(end && *end && *end != ',')
f15b34 ¤   ¤   {
25bebc ¤   ¤   ¤   end++;
8b0fe4 ¤   ¤   }
79af5a
1a89de ¤   ¤   if(end)
9e5b34 ¤   ¤   {
cc7d4a ¤   ¤   ¤   *end = 0x00;
e8f3ce ¤   ¤   ¤   ComboBox_AddString(hwndBox, cp);
21bebc ¤   ¤   ¤   end++;
6594ac ¤   ¤   ¤   cp = end;
cb0fe4 ¤   ¤   }
4c9371 ¤   }
f4af5a
afef72 ¤   if(index == 0) // User Id
f3c7a1 ¤   {
804dce ¤   ¤   ComboBox_SetCurSel(hwndBox, 2);
739371 ¤   }
a30e24 ¤   else
acc7a1 ¤   {
f174b8 ¤   ¤   ComboBox_SetCurSel(hwndBox, 0);
909371 ¤   }
2eaf5a
794ab0 ¤   LoadString(¤hinst,·
561790 ¤   ¤   ¤   ¤   index + IDS_SPECIFIERS_ATTRIBUTE_1,·
0f419b ¤   ¤   ¤   ¤   szString,·
929a54 ¤   ¤   ¤   ¤   sizeof(szString));
0daf5a
a588bb ¤   hwndBox = GetDlgItem(¤  hwndParent,·
8a39cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_SPECIFIER_COMBO);
307428 ¤   hwndBoxList = GetDlgItem(¤  hwndParent,·
6169c7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_SPECIFIER_COMBO_LIST);
83bab8 ¤   hwndEdit = GetDlgItem(¤ hwndParent,·
278ace ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDC_SPECIFIER_EDIT);
1baf5a
2587c4 ¤   ComboBox_ResetContent(hwndBox);
0bdb86 ¤   ComboBox_ResetContent(hwndBoxList);
7eaf5a
55bf73 ¤   if(*szString != 0x20)
94c7a1 ¤   {
b61946 ¤   ¤   if(!strcmp(szString, "Date"))
895b34 ¤   ¤   {
8e54a8 ¤   ¤   ¤   ShowWindow(hwndBox,¤¤   SW_HIDE);
84938d ¤   ¤   ¤   ShowWindow(hwndBoxList,¤SW_HIDE);
1e5bb4 ¤   ¤   ¤   ShowWindow(hwndEdit,¤   SW_HIDE);
a25d0c ¤   ¤   ¤   ShowWindow(hwndTime,¤   SW_SHOW);
9b0fe4 ¤   ¤   }
5e0e1d ¤   ¤   else
765b34 ¤   ¤   {
51e5e9 ¤   ¤   ¤   ShowWindow(hwndEdit, SW_HIDE);
bc5754 ¤   ¤   ¤   ShowWindow(hwndTime, SW_HIDE);
9daf5a
31f40e ¤   ¤   ¤   end = cp = szString;
1caf5a
769429 ¤   ¤   ¤   if (*end == '*')·
93f776 ¤   ¤   ¤   {
e61b96 ¤   ¤   ¤   ¤   ShowWindow(hwndBox,¤¤   SW_HIDE);
50a6e8 ¤   ¤   ¤   ¤   ShowWindow(hwndBoxList,¤SW_SHOW);
cc788d ¤   ¤   ¤   ¤   hwnd = hwndBoxList;
ea988b ¤   ¤   ¤   ¤   end += 2;
115319 ¤   ¤   ¤   ¤   cp = end;
6ea3a6 ¤   ¤   ¤   }
346b93 ¤   ¤   ¤   else·
49f776 ¤   ¤   ¤   {
ba61cd ¤   ¤   ¤   ¤   ShowWindow(hwndBox,¤¤   SW_SHOW);
98dcb3 ¤   ¤   ¤   ¤   ShowWindow(hwndBoxList,¤SW_HIDE);
ea53af ¤   ¤   ¤   ¤   hwnd = hwndBox;
4fa3a6 ¤   ¤   ¤   }
a9af5a
b94726 ¤   ¤   ¤   while( cp && *cp )
f4f776 ¤   ¤   ¤   {
--2ddc 0016bbd74ed401102f0 Page 6 of SearchCommon.c
eab33b ¤   ¤   ¤   ¤   while(end && *end && *end != ',')
2a72c3 ¤   ¤   ¤   ¤   {
ae67b4 ¤   ¤   ¤   ¤   ¤   end++;
5d2613 ¤   ¤   ¤   ¤   }
5daf5a
e16459 ¤   ¤   ¤   ¤   if(end)
1072c3 ¤   ¤   ¤   ¤   {
7ef241 ¤   ¤   ¤   ¤   ¤   *end = 0x00;
6d9c29 ¤   ¤   ¤   ¤   ¤   ComboBox_AddString(hwnd, cp);
6467b4 ¤   ¤   ¤   ¤   ¤   end++;
c7da4d ¤   ¤   ¤   ¤   ¤   cp = end;
ed2613 ¤   ¤   ¤   ¤   }
24a3a6 ¤   ¤   ¤   }
eeaf5a
ecda4f ¤   ¤   ¤   ComboBox_SetCurSel(hwnd, 0);
be0fe4 ¤   ¤   }
709371 ¤   }
9a0e24 ¤   else
5fc7a1 ¤   {
496d6d ¤   ¤   ShowWindow(hwndBox,¤¤   SW_HIDE);
23aa48 ¤   ¤   ShowWindow(hwndBoxList,¤SW_HIDE);
13182a ¤   ¤   ShowWindow(hwndEdit,¤   SW_SHOW);
551e92 ¤   ¤   ShowWindow(hwndTime,¤   SW_HIDE);
6a9371 ¤   }
75af5a
03af5a
d6efe6 }
6baf5a
--b45d 001553c392c401102f1 Page 1 of SearchCommon.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
f12f99 ¤   $Id: SearchCommon.h,v 1.7 1998/08/11 15:20:17 pbj Exp $
7cf7f7 ____________________________________________________________________________*/
26363c #ifndef _SEARCHCOMMON_H
a1d06d #define _SEARCHCOMMON_H
42af5a
2aed82 #include "pgpKeyServerPrefs.h"
73af5a
e33791 #define MAX_YEAR¤   2099
eb5ef0 #define MIN_YEAR¤   1970
b2af5a
62bf72 typedef struct _SEARCHPATH
fdbb36 {
cd09ed ¤   PGPPrefRef¤ ¤   ¤   prefRef;
fe476b ¤   PGPKeyServerEntry*¤ keyserverList;
b20110 ¤   PGPUInt32¤  ¤   ¤   keyserverCount;
88af5a
732e70 }SEARCHPATH,*PSEARCHPATH;
f5af5a
dec8f9 void HANDLE_IDC_ATTRIBUTE(¤ HWND hwnd,·
985c16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
e9cec3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
c3ef26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
3daf5a
fb2fe8 void HANDLE_IDC_MONTH(¤ HWND hwnd,·
fb1de5 ¤   ¤   ¤   ¤   ¤   ¤   UINT msg,·
7f46a5 ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam,·
506740 ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
cfaf5a
cf5653 void ReloadKeyserverList(HWND hwnd);
59af5a
fb9320 void InitializeControlValues(HWND hwnd, int defaultSelection);
e7af5a
51c9f6 void ChangeAttributeSelection(HWND hwnd);
69af5a
89af5a
a2af5a
552841 #endif¶
--9706 0007a96dc6a401102f2 Page 1 of SearchFilter.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
96af5a
4798a1 ¤   $Id: SearchFilter.c,v 1.28 1998/08/11 15:20:18 pbj Exp $
55f7f7 ____________________________________________________________________________*/
1b5655 #include <windows.h>
0c3d0b #include <windowsx.h>
cd0a8b #include <time.h>
9ebb5f #include <assert.h>
1f90fb #include <commctrl.h>
bfaf5a
b1a076 #include "pgpKeys.h"
b22f8d #include "pgpErrors.h"
7f4919 #include "pgpUtilities.h"
da81a4 #include "pgpBuildFlags.h"
63af5a
4d65f9 #include "Search.h"
4fb4b6 #include "SearchFilter.h"
e75ab2 #include "PGPcl.h"
7f5f0b #include "PGPWerr.h"
9d8031 #include "resource.h"
f1af5a
a9ac92 #define¤IS¤ ¤   ¤   ¤   ¤   0
b41e41 #define IS_NOT¤ ¤   ¤   ¤   1
b9a9cd #define IS_ON_OR_BEFORE¤¤   1
a32c81 #define IS_AT_LEAST¤¤   ¤   1
ea8383 #define IS_NOT_FROM¤¤   ¤   1
9a92e7 #define CONTAINS¤   ¤   ¤   2
64918b #define IS_ON_OR_AFTER¤ ¤   2
4c7119 #define IS_AT_MOST¤ ¤   ¤   2
e7973b #define DOES_NOT_CONTAIN¤   3
5249b6 #define IS_SIGNED_BY¤   ¤   4
307158 #define IS_NOT_SIGNED_BY¤   5
bcaf5a
9143b5 #define DH_KEY_TYPE¤¤   ¤   0
e0e6a0 #define RSA_KEY_TYPE¤   ¤   1
cbaf5a
120561 #define REVOKED¤¤   ¤   ¤   0
b2db9a #define DISABLED¤   ¤   ¤   1
b1af5a
719848 extern PGPContextRef¤   g_Context;·
6eeec0 extern HINSTANCE¤   ¤   g_hInst;
5faf5a
a634b5 PGPError KeyIdFilterFromKeySet(¤PGPKeySetRef keySet,
6e16d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef* filter);
edaf5a
7553af PGPError CreateFilter(HWND hwnd, PGPFilterRef* filter, int* action)
4abb36 {
eb36a8 ¤   PGPError error = kPGPError_NoErr;
169d68 ¤   HWND hwndAttribute, hwndVerb;
b69504 ¤   HWND hwndEditSpecifier, hwndComboSpecifier, hwndComboListSpecifier;
8be6f2 ¤   HWND hwndTime;
b488c7 ¤   int AttributeSelection = 0;
a75e1a ¤   int VerbSelection = 0;
ce04a8 ¤   int SpecifierSelection = 0;
e9720c ¤   char* SpecifierBuffer = NULL;
f6d8c8 ¤   DWORD SpecifierLength = 0;
e11ce7 ¤   int Month = 1;
0fce87 ¤   int Day = 1;
e6ae50 ¤   int Year = 1970;
dd1f8f ¤   BOOL bNegate = FALSE;
ef0425 ¤   SYSTEMTIME st;
70af5a
a8828e ¤   assert(hwnd);
f73ca4 ¤   assert(filter);
96f7e2 ¤   assert(action);
94af5a
f62a8b ¤   // set default action
5b0566 ¤   *action = ACTION_INTERSECT;
09af5a
7a0cbb ¤   // find all our window handles
--3ddf 00040c1bc33401102f2 Page 2 of SearchFilter.c
1b8c92 ¤   hwndAttribute¤  ¤   ¤   = GetDlgItem(hwnd, IDC_ATTRIBUTE);
a465ff ¤   hwndVerb¤   ¤   ¤   ¤   = GetDlgItem(hwnd, IDC_VERB);
4c826e ¤   hwndEditSpecifier¤  ¤   = GetDlgItem(hwnd, IDC_SPECIFIER_EDIT);
d78cbd ¤   hwndComboSpecifier¤ ¤   = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO);
a19c14 ¤   hwndComboListSpecifier¤ = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO_LIST);
5f92e5 ¤   hwndTime¤   ¤   ¤   ¤   = GetProp(hwnd, "hwndTime");
4f1b52 ¤   ¤
f20b91 ¤   // find what the user has chosen to search on
530a86 ¤   AttributeSelection¤ = ComboBox_GetCurSel(hwndAttribute);
a1783f ¤   VerbSelection¤  ¤   = ComboBox_GetCurSel(hwndVerb);
a67346 ¤   SpecifierSelection¤ = ComboBox_GetCurSel(hwndComboSpecifier);
aa5ccc ¤   if (SpecifierSelection < 0)·
3e29c2 ¤   ¤   SpecifierSelection¤ = ComboBox_GetCurSel(hwndComboListSpecifier);
14af5a
79f1ee ¤   // get date currently in time/date picker control
bae922 ¤   SendMessage (hwndTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&st);
329e4d ¤   // struct tm represents months 0-11 ·so we have to subtract 1
fc740c ¤   Month = st.wMonth - 1;·
b1cb48 ¤   // struct tm represents days 1-31 ·we have don't subtract 1
d3b497 ¤   Day =¤  st.wDay;
64c430 ¤   // struct tm represents years as offset from 1900
09654f ¤   Year =¤ st.wYear - 1900;
eeaf5a
eb1d7a ¤   // combo is zero based and the string list is not... adjust Selection
2a0e0d ¤   switch( AttributeSelection + IDS_SEARCH_STRINGTABLE_BASE + 1 )·
60c7a1 ¤   {
9bf316 ¤   ¤   case IDS_ATTRIBUTE_1: // user id
305b34 ¤   ¤   {
539ab7 ¤   ¤   ¤   SpecifierLength = Edit_GetTextLength(hwndEditSpecifier) + 1;
63b191 ¤   ¤   ¤   SpecifierBuffer = (char*) malloc(SpecifierLength);
5eaf5a
0d3a1a ¤   ¤   ¤   if( SpecifierBuffer )
79f776 ¤   ¤   ¤   {
90b5af ¤   ¤   ¤   ¤   Edit_GetText(¤  hwndEditSpecifier,·
d91b2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierBuffer,·
6afd9a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierLength);
6faf5a
04d6b6 ¤   ¤   ¤   ¤   // MessageBox(NULL, SpecifierBuffer, "user id", MB_OK);
d1af5a
02ab8e ¤   ¤   ¤   ¤   switch( VerbSelection )
a872c3 ¤   ¤   ¤   ¤   {
7bb313 ¤   ¤   ¤   ¤   ¤   case IS_NOT:
dbf746 ¤   ¤   ¤   ¤   ¤   ¤   bNegate = TRUE;
15c912 ¤   ¤   ¤   ¤   ¤   case IS:
b04859 ¤   ¤   ¤   ¤   ¤   {
7a1a5e ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewUserIDStringFilter(
030f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
f1b65c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierBuffer,·
9b4b16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchEqual,
e512a1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
ffaf5a
4c22ad ¤   ¤   ¤   ¤   ¤   ¤   if( bNegate && IsntPGPError(error) )
b98fec ¤   ¤   ¤   ¤   ¤   ¤   {
7f89f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef NegatedFilter = kPGPInvalidRef;
a5af5a
a5bb42 ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNegateFilter(*filter,·
b05f8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &NegatedFilter);
68af5a
a4ca17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
7606b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
49d54d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *filter = NegatedFilter;
de5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
25db3c ¤   ¤   ¤   ¤   ¤   ¤   }
07af5a
1800eb ¤   ¤   ¤   ¤   ¤   ¤   break;
281c89 ¤   ¤   ¤   ¤   ¤   }
40af5a
9c4470 ¤   ¤   ¤   ¤   ¤   case DOES_NOT_CONTAIN:
abf746 ¤   ¤   ¤   ¤   ¤   ¤   bNegate = TRUE;
061226 ¤   ¤   ¤   ¤   ¤   case CONTAINS:
504859 ¤   ¤   ¤   ¤   ¤   {
4094aa ¤   ¤   ¤   ¤   ¤   ¤
--5130 00014f61401401102f2 Page 3 of SearchFilter.c
641a5e ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewUserIDStringFilter(
fa0f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
cbb65c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierBuffer,·
12566a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchSubString,
b612a1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
82af5a
1922ad ¤   ¤   ¤   ¤   ¤   ¤   if( bNegate && IsntPGPError(error) )
ef8fec ¤   ¤   ¤   ¤   ¤   ¤   {
f589f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef NegatedFilter = kPGPInvalidRef;
d3af5a
75bb42 ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNegateFilter(*filter,·
575f8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &NegatedFilter);
19af5a
a5ca17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
1206b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
42d54d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *filter = NegatedFilter;
1a5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
28db3c ¤   ¤   ¤   ¤   ¤   ¤   }
bdaf5a
2100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
051c89 ¤   ¤   ¤   ¤   ¤   }
e3af5a
c1b534 ¤   ¤   ¤   ¤   ¤   case IS_NOT_SIGNED_BY:
99f746 ¤   ¤   ¤   ¤   ¤   ¤   bNegate = TRUE;
b093ed ¤   ¤   ¤   ¤   ¤   case IS_SIGNED_BY:
894859 ¤   ¤   ¤   ¤   ¤   {
622ac3 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeySetRef¤   ringSet¤¤   = kPGPInvalidRef;
d2e1e1 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeySetRef¤   filteredSet¤= kPGPInvalidRef;
32af5a
20af5a
0c5b01 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPOpenDefaultKeyRings(¤g_Context,·
efd8c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
d31d25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ringSet);
b5af5a
1a352d ¤   ¤   ¤   ¤   ¤   ¤   if(ringSet && IsntPGPError(error))
8b8fec ¤   ¤   ¤   ¤   ¤   ¤   {
c2f8b2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef userIdFilter = kPGPInvalidRef;
3caf5a
34f85e ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewUserIDStringFilter(
0cd5d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
f4e845 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierBuffer,·
d3af18 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchSubString,
4ae0a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &userIdFilter );
81af5a
09ca17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
4506b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
5a6c41 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPFilterKeySet(ringSet,·
352a49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   userIdFilter,·
51a77a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &filteredSet);
13af5a
b08b91 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeFilter(userIdFilter);
fd5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
e0af5a
1eca17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
2606b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
6ce3a8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = KeyIdFilterFromKeySet(¤ filteredSet,
35678a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter);
415fe0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(filteredSet);
cd5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
daaf5a
985d9d ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!PGPRefIsValid (*filter))
4806b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
0b11aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = kPGPError_Win32_NoSigningKey;
3d5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
9eaf5a
d44f62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(ringSet);
1ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
d4af5a
eb22ad ¤   ¤   ¤   ¤   ¤   ¤   if( bNegate && IsntPGPError(error) )
218fec ¤   ¤   ¤   ¤   ¤   ¤   {
f789f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef NegatedFilter = kPGPInvalidRef;
14af5a
--cdfd 000b3fdae5f401102f2 Page 4 of SearchFilter.c
02bb42 ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNegateFilter(*filter,·
625f8c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &NegatedFilter);
01af5a
77ca17 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
9106b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
53d54d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *filter = NegatedFilter;
aa5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
23db3c ¤   ¤   ¤   ¤   ¤   ¤   }
3eaf5a
1300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
db1c89 ¤   ¤   ¤   ¤   ¤   }
432613 ¤   ¤   ¤   ¤   }
54af5a
1917ca ¤   ¤   ¤   ¤   free(SpecifierBuffer);
e8a3a6 ¤   ¤   ¤   }
59bb8c ¤   ¤   ¤   else
5df776 ¤   ¤   ¤   {
9c2f55 ¤   ¤   ¤   ¤   error = kPGPError_OutOfMemory;
dba3a6 ¤   ¤   ¤   }
65af5a
51cdcb ¤   ¤   ¤   break;
cb0fe4 ¤   ¤   }
d7af5a
2b5193 ¤   ¤   case IDS_ATTRIBUTE_2: // key id
855b34 ¤   ¤   {
139ab7 ¤   ¤   ¤   SpecifierLength = Edit_GetTextLength(hwndEditSpecifier) + 1;
88b191 ¤   ¤   ¤   SpecifierBuffer = (char*) malloc(SpecifierLength);
20af5a
da3a1a ¤   ¤   ¤   if( SpecifierBuffer )
ddf776 ¤   ¤   ¤   {
5cb5af ¤   ¤   ¤   ¤   Edit_GetText(¤  hwndEditSpecifier,·
1c1b2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierBuffer,·
1dfd9a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierLength);
47af5a
d8a30e ¤   ¤   ¤   ¤   //MessageBox(NULL, SpecifierBuffer, "key id", MB_OK);
50af5a
17ab8e ¤   ¤   ¤   ¤   switch( VerbSelection )
d572c3 ¤   ¤   ¤   ¤   {
1eb313 ¤   ¤   ¤   ¤   ¤   case IS_NOT:
f9f746 ¤   ¤   ¤   ¤   ¤   ¤   bNegate = TRUE;
c9c912 ¤   ¤   ¤   ¤   ¤   case IS:
374859 ¤   ¤   ¤   ¤   ¤   {
d83093 ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyID keyId;
dfaf5a
35331b ¤   ¤   ¤   ¤   ¤   ¤   error = PGPGetKeyIDFromString(¤ SpecifierBuffer,·
63924f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyId );
623e29 ¤   ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(error))
5c8fec ¤   ¤   ¤   ¤   ¤   ¤   {
b81c9e ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyIDFilter(¤ g_Context,·
c605ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyId,
f95dd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
5dae30 ¤   ¤   ¤   ¤   ¤
94f884 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( bNegate && IsntPGPError(error) )
c506b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
fe142d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef NegatedFilter = kPGPInvalidRef;
64af5a
9e075b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNegateFilter(*filter,·
8758fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &NegatedFilter);
44af5a
fbc960 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
5631b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
99f3f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *filter = NegatedFilter;
4a6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
525268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
0ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
b5af5a
6b00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
6d1c89 ¤   ¤   ¤   ¤   ¤   }
482613 ¤   ¤   ¤   ¤   }
84af5a
0617ca ¤   ¤   ¤   ¤   free(SpecifierBuffer);
b3a3a6 ¤   ¤   ¤   }
--eea9 0007f3a0238401102f2 Page 5 of SearchFilter.c
b1bb8c ¤   ¤   ¤   else
89f776 ¤   ¤   ¤   {
a82f55 ¤   ¤   ¤   ¤   error = kPGPError_OutOfMemory;
a4a3a6 ¤   ¤   ¤   }
9baf5a
19cdcb ¤   ¤   ¤   break;
500fe4 ¤   ¤   }
a8af5a
e6ff1c ¤   ¤   case IDS_ATTRIBUTE_3: // key type
2f5b34 ¤   ¤   {
6153b7 ¤   ¤   ¤   PGPByte encryptAlgorithm = 0;
b1af5a
13fa96 ¤   ¤   ¤   if( SpecifierSelection == DH_KEY_TYPE )
eff776 ¤   ¤   ¤   {
ce418f ¤   ¤   ¤   ¤   encryptAlgorithm = kPGPPublicKeyAlgorithm_ElGamal;
d3a3a6 ¤   ¤   ¤   }
4c6de2 ¤   ¤   ¤   else if( SpecifierSelection == RSA_KEY_TYPE )
53f776 ¤   ¤   ¤   {
44f5e4 ¤   ¤   ¤   ¤   encryptAlgorithm = kPGPPublicKeyAlgorithm_RSA;
e2a3a6 ¤   ¤   ¤   }
9587c7 ¤   ¤   ¤
e1eb14 ¤   ¤   ¤   error = PGPNewKeyEncryptAlgorithmFilter(g_Context,·
e8f3ec ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   encryptAlgorithm,·
f54642 ¤   ¤   ¤   ·¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter);
aacdcb ¤   ¤   ¤   break;
840fe4 ¤   ¤   }
a2af5a
fab444 ¤   ¤   case IDS_ATTRIBUTE_4: // creation date
4e5b34 ¤   ¤   {
f98944 ¤   ¤   ¤   struct tm time;
e6af5a
cc3409 ¤   ¤   ¤   memset(&time, 0x00, sizeof(time));
80af5a
b2f136 ¤   ¤   ¤   time.tm_mday¤   = Day; ···/* day of the month - [1,31] */
37e8f3 ¤   ¤   ¤   time.tm_mon¤¤   = Month; ·/* months since January - [0,11] */
6dfb7e ¤   ¤   ¤   time.tm_year¤   = Year; ··/* years since 1900 */
2aaf5a
316edb ¤   ¤   ¤   switch( VerbSelection )
1ff776 ¤   ¤   ¤   {
00af5a
3bacde ¤   ¤   ¤   ¤   // In order to simulate an "is date" without the
0ea4b6 ¤   ¤   ¤   ¤   // user having to enter the exact hour, min, sec
84fdf5 ¤   ¤   ¤   ¤   // the key was created, we fake it by doing an
02be80 ¤   ¤   ¤   ¤   // intersection between the entire day.
defd4f ¤   ¤   ¤   ¤   case IS:
c072c3 ¤   ¤   ¤   ¤   {
5e4787 ¤   ¤   ¤   ¤   ¤   PGPFilterRef filterAM;
0f989d ¤   ¤   ¤   ¤   ¤   PGPFilterRef filterPM;
5aaf5a
40b031 ¤   ¤   ¤   ¤   ¤   /* midnight AM */
a41365 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 0;·
a031f5 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 0; ····
1fae60 ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 0;
ffaf5a
5ad5d6 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyCreationTimeFilter(·
058139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
0467dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)),·
c18072 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchGreaterOrEqual,·
852057 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &filterAM );
74af5a
22d00f ¤   ¤   ¤   ¤   ¤   if(IsPGPError(error))
964859 ¤   ¤   ¤   ¤   ¤   {
8f00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
941c89 ¤   ¤   ¤   ¤   ¤   }
57af5a
dc659e ¤   ¤   ¤   ¤   ¤   /* just before midnight PM */
eea799 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 59;·
8564a0 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 59; ····
489c3c ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 23;
16af5a
efd5d6 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyCreationTimeFilter(·
7f8139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
--7b13 000ab2bc9a5401102f2 Page 6 of SearchFilter.c
e467dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)),·
438e4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchLessOrEqual,·
3a66cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &filterPM );
02af5a
0a2679 ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(error))
8f4859 ¤   ¤   ¤   ¤   ¤   {
1ff496 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPIntersectFilters(filterAM,
afb927 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filterPM,
733090 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter);
dc1c89 ¤   ¤   ¤   ¤   ¤   }
c2ae30 ¤   ¤   ¤   ¤   ¤
8014c3 ¤   ¤   ¤   ¤   ¤   break;
8e2613 ¤   ¤   ¤   ¤   }
6daf5a
0aa0be ¤   ¤   ¤   ¤   case IS_ON_OR_BEFORE:
2472c3 ¤   ¤   ¤   ¤   {
03ae30 ¤   ¤   ¤   ¤   ¤
62d361 ¤   ¤   ¤   ¤   ¤   /* just before midnight PM*/
7ea799 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 59;·
6d64a0 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 59; ····
f29c3c ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 23;
d5af5a
4ed5d6 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyCreationTimeFilter(·
928139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
722d3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)), ·
ba8e4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchLessOrEqual,·
fe645a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
5b14c3 ¤   ¤   ¤   ¤   ¤   break;
b52613 ¤   ¤   ¤   ¤   }
4faf5a
fb0405 ¤   ¤   ¤   ¤   case IS_ON_OR_AFTER:
eb72c3 ¤   ¤   ¤   ¤   {
cde982 ¤   ¤   ¤   ¤   ¤   /* midnight AM*/
a91365 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 0;·
f931f5 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 0; ····
c4ae60 ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 0;
5daf5a
ead5d6 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyCreationTimeFilter(·
688139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
1e67dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)),·
658072 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchGreaterOrEqual,·
06645a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
87af5a
5314c3 ¤   ¤   ¤   ¤   ¤   break;
232613 ¤   ¤   ¤   ¤   }
23a3a6 ¤   ¤   ¤   }
0dcdcb ¤   ¤   ¤   break;
f30fe4 ¤   ¤   }
e5af5a
bcb4cc ¤   ¤   case IDS_ATTRIBUTE_5: // expiration date
135b34 ¤   ¤   {
ee8944 ¤   ¤   ¤   struct tm time;
7887c7 ¤   ¤   ¤
2c3409 ¤   ¤   ¤   memset(&time, 0x00, sizeof(time));
70af5a
eef136 ¤   ¤   ¤   time.tm_mday¤   = Day; ···/* day of the month - [1,31] */
4de8f3 ¤   ¤   ¤   time.tm_mon¤¤   = Month; ·/* months since January - [0,11] */
0afb7e ¤   ¤   ¤   time.tm_year¤   = Year; ··/* years since 1900 */
ceaf5a
da6edb ¤   ¤   ¤   switch( VerbSelection )
06f776 ¤   ¤   ¤   {
83af5a
0dacde ¤   ¤   ¤   ¤   // In order to simulate an "is date" without the
d8a4b6 ¤   ¤   ¤   ¤   // user having to enter the exact hour, min, sec
affdf5 ¤   ¤   ¤   ¤   // the key was created, we fake it by doing an
29be80 ¤   ¤   ¤   ¤   // intersection between the entire day.
6cfd4f ¤   ¤   ¤   ¤   case IS:
9072c3 ¤   ¤   ¤   ¤   {
244787 ¤   ¤   ¤   ¤   ¤   PGPFilterRef filterAM;
4f989d ¤   ¤   ¤   ¤   ¤   PGPFilterRef filterPM;
4caf5a
abb031 ¤   ¤   ¤   ¤   ¤   /* midnight AM */
--4b57 000952d04f7401102f2 Page 7 of SearchFilter.c
701365 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 0;·
2231f5 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 0; ····
e7ae60 ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 0;
a5af5a
b1dc17 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyExpirationTimeFilter(·
3b8139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
0067dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)),·
9e8072 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchGreaterOrEqual,·
482057 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &filterAM );
96af5a
71d00f ¤   ¤   ¤   ¤   ¤   if(IsPGPError(error))
c44859 ¤   ¤   ¤   ¤   ¤   {
4700eb ¤   ¤   ¤   ¤   ¤   ¤   break;
f91c89 ¤   ¤   ¤   ¤   ¤   }
6daf5a
da659e ¤   ¤   ¤   ¤   ¤   /* just before midnight PM */
37a799 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 59;·
6464a0 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 59; ····
009c3c ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 23;
23af5a
bedc17 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyExpirationTimeFilter(·
718139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
9667dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)),·
808e4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchLessOrEqual,·
7966cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &filterPM );
1faf5a
af2679 ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(error))
fe4859 ¤   ¤   ¤   ¤   ¤   {
ebf496 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPIntersectFilters(filterAM,
a0b927 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filterPM,
1e3090 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter);
beaf5a
861c89 ¤   ¤   ¤   ¤   ¤   }
59ae30 ¤   ¤   ¤   ¤   ¤
5f14c3 ¤   ¤   ¤   ¤   ¤   break;
de2613 ¤   ¤   ¤   ¤   }
d8af5a
14a0be ¤   ¤   ¤   ¤   case IS_ON_OR_BEFORE:
2672c3 ¤   ¤   ¤   ¤   {
c6ae30 ¤   ¤   ¤   ¤   ¤
03d361 ¤   ¤   ¤   ¤   ¤   /* just before midnight PM*/
72a799 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 59;·
7f64a0 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 59; ····
e69c3c ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 23;
61af5a
f3dc17 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyExpirationTimeFilter(·
438139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
a02d3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)), ·
818e4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchLessOrEqual,·
a5645a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
2114c3 ¤   ¤   ¤   ¤   ¤   break;
ef2613 ¤   ¤   ¤   ¤   }
75af5a
6f0405 ¤   ¤   ¤   ¤   case IS_ON_OR_AFTER:
1172c3 ¤   ¤   ¤   ¤   {
48e982 ¤   ¤   ¤   ¤   ¤   /* midnight AM*/
671365 ¤   ¤   ¤   ¤   ¤   time.tm_sec¤¤   = 0;·
9b31f5 ¤   ¤   ¤   ¤   ¤   time.tm_min¤¤   = 0; ····
37ae60 ¤   ¤   ¤   ¤   ¤   time.tm_hour¤   = 0;
5caf5a
9edc17 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyExpirationTimeFilter(·
a48139 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
f567dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPGetPGPTimeFromStdTime(mktime(&time)),·
d38072 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchGreaterOrEqual,·
2f645a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
0daf5a
dd14c3 ¤   ¤   ¤   ¤   ¤   break;
de2613 ¤   ¤   ¤   ¤   }
14a3a6 ¤   ¤   ¤   }
5bcdcb ¤   ¤   ¤   break;
920fe4 ¤   ¤   }
95af5a
--9ecf 00006b58449401102f2 Page 8 of SearchFilter.c
5f7d24 ¤   ¤   case IDS_ATTRIBUTE_6: // key
395b34 ¤   ¤   {
4edb98 ¤   ¤   ¤   if( SpecifierSelection == REVOKED )
b2f776 ¤   ¤   ¤   {
710995 ¤   ¤   ¤   ¤   error = PGPNewKeyRevokedFilter(¤
dc095f ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
e9c9a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPBoolean)!VerbSelection,·
bf58b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
0ca3a6 ¤   ¤   ¤   }
e46ad2 ¤   ¤   ¤   else if( SpecifierSelection == DISABLED )
48f776 ¤   ¤   ¤   {
9031d3 ¤   ¤   ¤   ¤   error = PGPNewKeyDisabledFilter(¤
9e095f ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
2bc9a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPBoolean)!VerbSelection,·
d658b4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
b3a3a6 ¤   ¤   ¤   }
5dcdcb ¤   ¤   ¤   break;
040fe4 ¤   ¤   }
63af5a
5457a2 ¤   ¤   case IDS_ATTRIBUTE_7: // key size
895b34 ¤   ¤   {
6cdd3f ¤   ¤   ¤   SpecifierLength = ComboBox_GetTextLength(hwndComboSpecifier) + 1;
6db191 ¤   ¤   ¤   SpecifierBuffer = (char*) malloc(SpecifierLength);
e3af5a
2c3a1a ¤   ¤   ¤   if( SpecifierBuffer )
04f776 ¤   ¤   ¤   {
94a079 ¤   ¤   ¤   ¤   ComboBox_GetText(¤  hwndComboSpecifier,·
0eb52b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierBuffer,·
56539b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SpecifierLength);
02af5a
e678c6 ¤   ¤   ¤   ¤   //MessageBox(NULL, SpecifierBuffer, "Key Size", MB_OK);
96af5a
d1ab8e ¤   ¤   ¤   ¤   switch( VerbSelection )
4672c3 ¤   ¤   ¤   ¤   {
d4c912 ¤   ¤   ¤   ¤   ¤   case IS:
ef4859 ¤   ¤   ¤   ¤   ¤   {
6ec343 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyEncryptKeySizeFilter(·
165a84 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
347820 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   atol(SpecifierBuffer),·
fd00d7 ¤   ¤   ¤   ·¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchEqual,·
1abca0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
9a00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
2e1c89 ¤   ¤   ¤   ¤   ¤   }
f9af5a
d6f95a ¤   ¤   ¤   ¤   ¤   case IS_AT_LEAST:
584859 ¤   ¤   ¤   ¤   ¤   {
edc343 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyEncryptKeySizeFilter(·
365a84 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
9e7820 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   atol(SpecifierBuffer),·
ed185a ¤   ¤   ¤   ·¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchGreaterOrEqual,·
63bca0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
a300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
ca1c89 ¤   ¤   ¤   ¤   ¤   }
0baf5a
1e5583 ¤   ¤   ¤   ¤   ¤   case IS_AT_MOST:
e44859 ¤   ¤   ¤   ¤   ¤   {
5ac343 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyEncryptKeySizeFilter(·
085a84 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,·
e47820 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   atol(SpecifierBuffer),·
c56794 ¤   ¤   ¤   ·¤  ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMatchLessOrEqual,·
0dbca0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter );
9f00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
2d1c89 ¤   ¤   ¤   ¤   ¤   }
332613 ¤   ¤   ¤   ¤   }
d5af5a
6617ca ¤   ¤   ¤   ¤   free(SpecifierBuffer);
01a3a6 ¤   ¤   ¤   }
e7bb8c ¤   ¤   ¤   else
aff776 ¤   ¤   ¤   {
7b2f55 ¤   ¤   ¤   ¤   error = kPGPError_OutOfMemory;
35a3a6 ¤   ¤   ¤   }
06cdcb ¤   ¤   ¤   break;
--38a0 0003afe21c9401102f2 Page 9 of SearchFilter.c
b50fe4 ¤   ¤   }
e6af5a
6b9ae3 ¤   ¤   default:
3e5b34 ¤   ¤   {
76df01 ¤   ¤   ¤   MessageBox(NULL, "DefaultFilter: Unknown Attribute", 0, MB_OK);
4c0fe4 ¤   ¤   }
1d9371 ¤   }
f0af5a
c6c674 ¤   return error;
91efe6 }
e9af5a
2934b5 PGPError KeyIdFilterFromKeySet(¤PGPKeySetRef keySet,
f34276 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef* filter)
5dbb36 {
0a17eb ¤   PGPError¤   ¤   error¤  = kPGPError_NoErr;
6f82f9 ¤   PGPKeyListRef¤  list¤   = kPGPInvalidRef;
91aee9 ¤   PGPKeyIterRef¤  iter¤   = kPGPInvalidRef;
1e538b ¤   PGPKeyRef¤  ¤   key¤¤   = kPGPInvalidRef;
34f93b ¤   PGPFilterRef¤   aFilter = kPGPInvalidRef;
bc2daa ¤   PGPFilterRef¤   idFilter= kPGPInvalidRef;
e4c3c4 ¤   PGPKeyID¤   ¤   keyId;
2baf5a
3aa76b ¤   error = PGPOrderKeySet(¤keySet,
e01435 ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPAnyOrdering,
ce408f ¤   ¤   ¤   ¤   ¤   ¤   ¤   &list);
0aaf5a
2df678 ¤   if( IsntPGPError(error) )
70c7a1 ¤   {
7cabcc ¤   ¤   error = PGPNewKeyIter(¤ list,
39c654 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &iter);
2eaf5a
e5ea42 ¤   ¤   if(IsntPGPError(error) )
6b5b34 ¤   ¤   {
345229 ¤   ¤   ¤   PGPError iterError = kPGPError_NoErr;
1baf5a
c36da3 ¤   ¤   ¤   do
7ff776 ¤   ¤   ¤   {
6411f1 ¤   ¤   ¤   ¤   iterError = PGPKeyIterNext(iter, &key);
7faf5a
fa8306 ¤   ¤   ¤   ¤   if( IsntPGPError(iterError) )
9072c3 ¤   ¤   ¤   ¤   {
9dc099 ¤   ¤   ¤   ¤   ¤   error = PGPGetKeyIDFromKey(¤key,
731055 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyId);
4aaf5a
822b28 ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
db4859 ¤   ¤   ¤   ¤   ¤   {
1b4ce0 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewSigKeyIDFilter(¤  g_Context,·
d1f018 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyId,·
cae0ce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &aFilter );
94af5a
6cf68b ¤   ¤   ¤   ¤   ¤   ¤   if(idFilter == kPGPInvalidRef)
cd8fec ¤   ¤   ¤   ¤   ¤   ¤   {
8d46b3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   idFilter = aFilter;
eadb3c ¤   ¤   ¤   ¤   ¤   ¤   }
027f8b ¤   ¤   ¤   ¤   ¤   ¤   else
948fec ¤   ¤   ¤   ¤   ¤   ¤   {
613fcf ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef combinedFilter = NULL;
d4af5a
eeab1f ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPUnionFilters(idFilter,
d336c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   aFilter,·
2bbbca ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &combinedFilter);
8baf5a
7d2fe1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   idFilter = combinedFilter;
c2db3c ¤   ¤   ¤   ¤   ¤   ¤   }
661c89 ¤   ¤   ¤   ¤   ¤   }
bb2613 ¤   ¤   ¤   ¤   }
baaf5a
fdae52 ¤   ¤   ¤   }while(IsntPGPError(iterError) && IsntPGPError(error));
eeaf5a
88fb3c ¤   ¤   ¤   PGPFreeKeyIter(iter);
4b0fe4 ¤   ¤   }
3aaf5a
--4a65 001a7a5cc3f401102f2 Page 10 of SearchFilter.c
42572d ¤   ¤   PGPFreeKeyList(list);
4a9371 ¤   }
53af5a
d4af5a
87f678 ¤   if( IsntPGPError(error) )
f6c7a1 ¤   {
cf1470 ¤   ¤   *filter = idFilter;
6a9371 ¤   }
95af5a
3dc674 ¤   return error;
a7efe6 }
--6ac3 001e6d59925401102f3 Page 1 of SearchFilter.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
51c3bb ¤   $Id: SearchFilter.h,v 1.3 1998/08/11 15:20:19 pbj Exp $
28f7f7 ____________________________________________________________________________*/
89b9be #ifndef _SEARCHFILTER_H
3a5fef #define _SEARCHFILTER_H
c7af5a
c66165 #define ACTION_UNION¤   ¤   1
336258 #define ACTION_INTERSECT¤   2
3dc627 #define ACTION_NEGATE¤  ¤   3
5baf5a
405d8e PGPError CreateFilter(HWND hwnd, PGPFilterRef* filter, int* action);
f1af5a
e62841 #endif¶
--b0c9 0000a303831401102f4 Page 1 of SearchProc.c
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
96af5a
a77012 ¤   $Id: SearchProc.c,v 1.99.2.2 1998/10/28 23:11:51 pbj Exp $
16f7f7 ____________________________________________________________________________*/
5aaf5a
185060 // System Headers·
3b5655 #include <windows.h>
b43d0b #include <windowsx.h>
862d5f #include <winsock.h>
f790fb #include <commctrl.h>
adaf5a
2b5582 // PGPsdk Headers
66a076 #include "pgpKeys.h"
b62f8d #include "pgpErrors.h"
f9eb5b #include "pgpKeyServer.h"
f0ed82 #include "pgpKeyServerPrefs.h"
0b81a4 #include "pgpBuildFlags.h"
d64919 #include "pgpUtilities.h"
62c97b #include "pgpClientPrefs.h"
a7af5a
e16578 // Shared Headers·
585ab2 #include "PGPcl.h"
035159 #include "PGPpkHlp.h"·
7baf5a
eee8e0 // Project Headers
4965f9 #include "Search.h"
17354b #include "Choice.h"
5eb4b6 #include "SearchFilter.h"
901323 #include "SearchCommon.h"
3c8031 #include "resource.h"
ffaf5a
b7cfc4 typedef struct _SEARCHTHREADSTRUCT
20bb36 {
37deec ¤   HWND¤   ¤   ¤   ¤   hwnd;
0133f8 ¤   HANDLE¤ ¤   ¤   ¤   threadHandle;
834a06 ¤   DWORD¤  ¤   ¤   ¤   threadID;
eee179 ¤   PGPFilterRef¤   ¤   filter;
300e80 ¤   PGPKeyServerEntry¤  keyserverEntry;
9cac57 ¤   PGPKeySetRef¤   ¤   keySet;¤¤
24218f ¤   PGPKeyServerRef¤¤   server;
aeddcc ¤   BOOL¤   ¤   ¤   ¤   bCancel;
dacaf4 ¤   BOOL¤   ¤   ¤   ¤   bAlreadyAsked;
13af5a
44c013 }SEARCHTHREADSTRUCT,*PSEARCHTHREADSTRUCT;
16af5a
05af5a
f29848 extern PGPContextRef¤   g_Context;·
1f152b extern PGPtlsContextRef g_TLSContext;
c4eec0 extern HINSTANCE¤   ¤   g_hInst;
215e8b extern CHAR¤¤   ¤   ¤   g_szHelpFile[MAX_PATH];
5eaf5a
811de1 static DWORD aSearchIds[] = {¤  ¤   ¤   // Help IDs
4c88e3 ····IDC_SEARCH,¤¤   IDH_PGPPKSEARCH_SEARCH,·
220580 ····IDC_STOP,¤  ¤   IDH_PGPPKSEARCH_STOP,·
06ab8a ····IDC_CLEAR,¤ ¤   IDH_PGPPKSEARCH_CLEAR,·
bd5658 ····IDC_LOCATION,¤  IDH_PGPPKSEARCH_LOCATION,·
a9fcd4 ····IDC_ATTRIBUTE,¤ IDH_PGPPKSEARCH_ATTRIBUTE,·
1800fd ····IDC_VERB,¤  ¤   IDH_PGPPKSEARCH_VERB,·
1161c5 ····IDC_MORE,¤  ¤   IDH_PGPPKSEARCH_MORE,·
ebec26 ····IDC_FEWER,¤ ¤   IDH_PGPPKSEARCH_FEWER,·
1436a0 ····IDC_PENDING,¤   IDH_PGPPKSEARCH_PENDING,
934434 ····0,0·
35a6fe };·
a1af5a
b01c0e PGPError PerformSearch(HWND hwndLocation,·
2633b6 ¤   ¤   ¤   ¤   ¤   ···PSEARCHTHREADSTRUCT psts,
3a4ab6 ¤   ¤   ¤   ¤   ¤   ···BOOL¤bPending,
9a6372 ¤   ¤   ¤   ¤   ¤   ···long* flags,
302068 ¤   ¤   ¤   ¤   ¤   ···PGPKeySetRef* pKeySetOut);
0aaf5a
--e714 000d03d441a401102f4 Page 2 of SearchProc.c
27663a PGPError SearchEventHandler(PGPContextRef context,
373f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPEvent *event,·
8fa3a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUserValue userValue);
d0af5a
e1ef87 DWORD WINAPI SearchThreadRoutine( LPVOID lpvoid);
88af5a
ec7395 void GrabUserIdStrings(HWND hwnd,·
646155 ¤   ¤   ¤   ¤   ¤   ···char** string,
e21ef3 ¤   ¤   ¤   ¤   ¤   ···int* length);
ddaf5a
a47efe BOOL·
e6a2f4 CALLBACK·
5f811c SearchProc(¤HWND hwnd,·
c46753 ¤   ¤   ¤   UINT msg,·
24a552 ¤   ¤   ¤   WPARAM wParam,·
64be88 ¤   ¤   ¤   LPARAM lParam )
667142 {·
1257d3 ¤   static int offsetButtons¤   = 0;
03d222 ¤   static int offsetBoxes¤ ¤   = 0;
87a3cf ¤   static int originalWidth¤   = 0;
133c1d ¤   int oldWidth¤   ¤   ¤   ¤   = (int)GetProp(hwnd, "oldWidth");
14167d ¤   int oldHeight¤  ¤   ¤   ¤   = (int)GetProp(hwnd, "oldHeight");
5daf5a
049467 ¤   switch(msg)
b0c7a1 ¤   {
69df25 ¤   ¤   case WM_INITDIALOG:
c15b34 ¤   ¤   {
8a384b ¤   ¤   ¤   RECT rectWindow, rectButton, rectBox;
41ff6c ¤   ¤   ¤   HWND hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO);
faec09 ¤   ¤   ¤   HWND hwndButton = GetDlgItem(hwnd, IDC_SEARCH);
875339 ¤   ¤   ¤   HWND hwndPending = GetDlgItem(hwnd, IDC_PENDING);
547740 ¤   ¤   ¤   HWND hwndTime = NULL;
f1f192 ¤   ¤   ¤   RECT rect;
d8dd6b ¤   ¤   ¤   PSEARCHTHREADSTRUCT psts;
09f616 ¤   ¤   ¤   CRITICAL_SECTION* keyserverLock;
25af5a
85e995 ¤   ¤   ¤   GetClientRect(hwndBox, &rect);
385cc9 ¤   ¤   ¤   MapWindowPoints(hwndBox, hwnd, (LPPOINT)&rect, 2);
f4af5a
e821b6 ¤   ¤   ¤   hwndTime = CreateWindowEx (0, DATETIMEPICK_CLASS,
f51a19 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "DateTime",
9e0858 ¤   ¤   ¤   ¤   ¤   ¤   ¤   WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
401d91 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.left, rect.top-1,·
bc2d4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.right-rect.left, rect.bottom-rect.top+2,·
69b287 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwnd, NULL, g_hInst, NULL);
74af5a
d76c7a ¤   ¤   ¤   SetWindowPos (hwndTime, GetDlgItem (hwnd, IDC_VERB),
c1fcc1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
8b5b1a ¤   ¤   ¤   SendMessage (hwndTime, DTM_SETMCCOLOR,·
cf6e0e ¤   ¤   ¤   ¤   ¤   ¤   MCSC_MONTHBK, (LPARAM)GetSysColor (COLOR_3DFACE));
3f5754 ¤   ¤   ¤   ShowWindow(hwndTime, SW_HIDE);
d92584 ¤   ¤   ¤   SetProp( hwnd, "hwndTime", hwndTime);·
e8af5a
3d67c5 ¤
cf14bc ¤   ¤   ¤   GetWindowRect(hwnd, &rectWindow);
19cba7 ¤   ¤   ¤   GetWindowRect(hwndButton, &rectButton);
d6ddb7 ¤   ¤   ¤   GetWindowRect(hwndBox, &rectBox);
9faf5a
0e2635 ¤   ¤   ¤   offsetButtons = rectWindow.right - rectButton.right;
c72332 ¤   ¤   ¤   offsetBoxes = rectButton.left - rectBox.right;
24b519 ¤   ¤   ¤   oldWidth = rectWindow.right - rectWindow.left;
5514c9 ¤   ¤   ¤   SetProp( hwnd, "oldWidth",(HANDLE) oldWidth);·
5bd6bc ¤   ¤   ¤   oldHeight = rectWindow.bottom - rectWindow.top;
733762 ¤   ¤   ¤   SetProp( hwnd, "oldHeight",(HANDLE) oldHeight);
049204 ¤   ¤   ¤   originalWidth ·= oldWidth;·
abaf5a
d28345 ¤   ¤   ¤   SetProp( hwnd, "ChoiceList",(HANDLE) 0);
3baf5a
2d52df ¤   ¤   ¤   keyserverLock =·
c89586 ¤   ¤   ¤   ¤   (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION));
0c87c7 ¤   ¤   ¤
d02b92 ¤   ¤   ¤   if(keyserverLock)
--462d 000de1dbdf7401102f4 Page 3 of SearchProc.c
99f776 ¤   ¤   ¤   {
1c461b ¤   ¤   ¤   ¤   InitializeCriticalSection(keyserverLock);
45af5a
191c82 ¤   ¤   ¤   ¤   SetProp(hwnd,"KeyserverLock", (HANDLE) keyserverLock );·
3ea3a6 ¤   ¤   ¤   }
a6af5a
c2a739 ¤   ¤   ¤   EnterCriticalSection(keyserverLock);
44af5a
9a0678 ¤   ¤   ¤   InitializeControlValues(hwnd, 0);
1eaf5a
1993c5 ¤   ¤   ¤   LeaveCriticalSection(keyserverLock);
2daf5a
5b6efe ¤   ¤   ¤   psts = (PSEARCHTHREADSTRUCT) malloc( sizeof(SEARCHTHREADSTRUCT));
43af5a
d075cb ¤   ¤   ¤   if(psts)
63f776 ¤   ¤   ¤   {
3fb1b9 ¤   ¤   ¤   ¤   memset(psts, 0x00, sizeof(SEARCHTHREADSTRUCT));
90face ¤   ¤   ¤   ¤   SetProp(hwnd,"SearchInfo", (HANDLE) psts );·
d7a3a6 ¤   ¤   ¤   }
0eaf5a
788acf ¤   ¤   ¤   // subclass datetime control
a70033 ¤   ¤   ¤   SetProp(hwndTime,"hwnd", hwnd );·
a0b8c6 ¤   ¤   ¤   SetProp (hwndTime, "oldproc",·
6a53d7 ¤   ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndTime, GWL_WNDPROC ) );·
0865e4 ¤   ¤   ¤   SetWindowLong(¤ hwndTime,·
092a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
c25272 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc );
caaf5a
0ea948 ¤   ¤   ¤   // subclass combo box
46a104 ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO);
a41a10 ¤   ¤   ¤   SetProp(hwndBox,"hwnd", hwnd );·
f1da07 ¤   ¤   ¤   SetProp (hwndBox, "oldproc",·
b54032 ¤   ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndBox, GWL_WNDPROC ) );·
4417db ¤   ¤   ¤   SetWindowLong(¤ hwndBox,·
ca2a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
6e5272 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc );
86af5a
2aa948 ¤   ¤   ¤   // subclass combo box
d77387 ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO_LIST);
b61a10 ¤   ¤   ¤   SetProp(hwndBox,"hwnd", hwnd );·
f6da07 ¤   ¤   ¤   SetProp (hwndBox, "oldproc",·
9c4032 ¤   ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndBox, GWL_WNDPROC ) );·
b417db ¤   ¤   ¤   SetWindowLong(¤ hwndBox,·
f02a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
f85272 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc );
37af5a
e4e745 ¤   ¤   ¤   // subclass edit box
70ab92 ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_SPECIFIER_EDIT);
351a10 ¤   ¤   ¤   SetProp(hwndBox,"hwnd", hwnd );·
e2da07 ¤   ¤   ¤   SetProp (hwndBox, "oldproc",·
d94032 ¤   ¤   ¤   ¤   ¤   ¤   (HANDLE)GetWindowLong( hwndBox, GWL_WNDPROC ) );·
6317db ¤   ¤   ¤   SetWindowLong(¤ hwndBox,·
ef2a3a ¤   ¤   ¤   ¤   ¤   ¤   ¤   GWL_WNDPROC,·
0a5272 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DWORD)SearchSubclassWndProc );
bbaf5a
139a8e ¤   ¤   ¤   SetFocus(hwndBox);
baaf5a
49af5a
3fef06 ¤   ¤   ¤   #if PGP_BUSINESS_SECURITY
693781 ¤   ¤   ¤   #if PGP_ADMIN_BUILD
6fad7a ¤   ¤   ¤   ¤   ShowWindow(hwndPending, SW_SHOW);
fbe56a ¤   ¤   ¤   #endif¤ // PGP_ADMIN_BUILD
cda98f ¤   ¤   ¤   #endif¤ // PGP_BUSINESS_SECURITY
4daf5a
345f1f ¤   ¤   ¤   return FALSE;
550fe4 ¤   ¤   }
9caf5a
a8dad9 ¤   ¤   case WM_DESTROY:
515b34 ¤   ¤   {
d6c108 ¤   ¤   ¤   HINSTANCE¤  ¤   ¤   hinst¤  ¤   ¤   = GetModuleHandle(NULL);
1b2686 ¤   ¤   ¤   PCHOICE¤¤   ¤   ¤   choice¤ ¤   ¤   = NULL;
de6299 ¤   ¤   ¤   HWND¤   ¤   ¤   ¤   hwndChoice¤ ¤   = NULL;
--36bd 000a6f0a1fa401102f4 Page 4 of SearchProc.c
2950a0 ¤   ¤   ¤   HWND¤   ¤   ¤   ¤   hwndLocation¤   = NULL;
61f47c ¤   ¤   ¤   LPARAM¤ ¤   ¤   ¤   itemData¤   ¤   = 0;
cf7a4f ¤   ¤   ¤   int¤¤   ¤   ¤   ¤   searchPathIndex¤= 0;
8d7f95 ¤   ¤   ¤   int¤¤   ¤   ¤   ¤   locationSelection = 0;
a0ae03 ¤   ¤   ¤   char¤   ¤   ¤   ¤   szString[256]¤  = {0x00};
dcf72d ¤   ¤   ¤   PSEARCHTHREADSTRUCT¤psts¤   ¤   ¤   = NULL;
29b96e ¤   ¤   ¤   CRITICAL_SECTION*¤  keyserverLock¤  = NULL;
3eb350 ¤   ¤   ¤   PSEARCHPATH¤¤   ¤   path¤   ¤   ¤   = NULL;
2b87c7 ¤   ¤   ¤
fc21b4 ¤   ¤   ¤   psts = (PSEARCHTHREADSTRUCT) GetProp(hwnd, "SearchInfo");
4baf5a
9a75cb ¤   ¤   ¤   if(psts)
dbf776 ¤   ¤   ¤   {
0138b4 ¤   ¤   ¤   ¤   if(psts->threadHandle)
09a633 ¤   ¤   ¤   ¤   ¤   TerminateThread(psts->threadHandle, 0);·
fbebf2 ¤   ¤   ¤   ¤   free(psts);
6ba3a6 ¤   ¤   ¤   }
79af5a
2dc896 ¤   ¤   ¤   keyserverLock = (CRITICAL_SECTION*) GetProp(hwnd,·
b877cb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "KeyserverLock");
61af5a
3d2b92 ¤   ¤   ¤   if(keyserverLock)
9af776 ¤   ¤   ¤   {
b5f422 ¤   ¤   ¤   ¤   EnterCriticalSection(keyserverLock);
0c80f3 ¤   ¤   ¤   ¤   DeleteCriticalSection( keyserverLock );·
ef3cde ¤   ¤   ¤   ¤   free(keyserverLock);
0ba3a6 ¤   ¤   ¤   }
f7af5a
4b5b42 ¤   ¤   ¤   // remove all the choice windows
d66da3 ¤   ¤   ¤   do
18f776 ¤   ¤   ¤   {
ebd582 ¤   ¤   ¤   ¤   choice = RemoveLastChoice(hwnd, &hwndChoice);
7d0e1f ¤   ¤   ¤   ¤   DestroyWindow( hwndChoice );
65af5a
d92c8c ¤   ¤   ¤   }while( choice );
4caf5a
2e0c92 ¤   ¤   ¤   // free the prefs struct I am using
8587c7 ¤   ¤   ¤
e17a06 ¤   ¤   ¤   hwndLocation = GetDlgItem(hwnd, IDC_LOCATION);
8d03a4 ¤   ¤   ¤   locationSelection = ComboBox_GetCurSel(hwndLocation);
cbaf5a
6719b9 ¤   ¤   ¤   path = (PSEARCHPATH) GetProp(hwnd, "SearchPath");
34af5a
737b30 ¤   ¤   ¤   if(path)
fef776 ¤   ¤   ¤   {
68ef09 ¤   ¤   ¤   ¤   PGPDisposePrefData(path->prefRef, path->keyserverList);
f5af5a
4e52d1 ¤   ¤   ¤   ¤   PGPSetPrefNumber (¤ path->prefRef,
7fe80e ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPPrefLastSearchWindowSelection,·
748da2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPUInt32)locationSelection);
b2af5a
fba66c ¤   ¤   ¤   ¤   PGPclCloseClientPrefs (¤path->prefRef, TRUE);
65a2a0 ¤   ¤   ¤   ¤   free(path);
1ea3a6 ¤   ¤   ¤   }
afaf5a
81812a ¤   ¤   ¤   CloseSearch ();
b432bd ¤   ¤   ¤   return TRUE;
b00fe4 ¤   ¤   }
06af5a
3f1436 #define DividerItem 1
26af5a
dfa502 ¤   ¤   case WM_MEASUREITEM: ····
b85b34 ¤   ¤   {
9ed720 ¤   ¤   ····LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT) lParam;·
942213 ¤   ¤   ·····¤  ¤   ····
d512db ············if (lpmis->itemID != -1)·
362cc2 ············{
7673df ················lpmis->itemHeight += 2;
752659 ·¤  ¤   ¤   }
bfdace ·¤  ¤   ¤
9f73a3 ··¤ ¤   ¤   return TRUE;·
a60fe4 ¤   ¤   }
--f0e9 0000c7f1665401102f4 Page 5 of SearchProc.c
f11b52 ¤   ¤
268c5a ¤   ¤   // ·Draw the listbox
beb295 ¤   ··¤ case WM_DRAWITEM: ···································
f844b2 ¤   ··¤ {
2f00d6 ¤   ¤   ¤   LPDRAWITEMSTRUCT lpDs¤  = (LPDRAWITEMSTRUCT)lParam;
d02511 ¤   ¤   ¤   int iTextVOff¤  ¤   ¤   =¤  2;
04340e ¤   ¤   ¤   RECT Rect, EtchRect;
7b83af ¤   ¤   ¤   HBRUSH hBrush;
d6dcb0 ¤   ¤   ¤   char szText[ 256 ];
dc87c7 ¤   ¤   ¤
f50195 ¤   ¤   ¤   // ·If nothing to draw, exit now
eb89fc ¤   ¤   ¤   if( lpDs->itemID == CB_ERR ) ····
802491 ¤   ¤   ¤   { ····
306d06 ¤   ¤   ¤   ¤   return( FALSE );
c6a3a6 ¤   ¤   ¤   }
c887c7 ¤   ¤   ¤
37cbab ¤   ¤   ¤   Rect.left = lpDs->rcItem.left;
79fb68 ¤   ¤   ¤   Rect.top = lpDs->rcItem.top;
2939cc ¤   ¤   ¤   Rect.right = lpDs->rcItem.right;
e65914 ¤   ¤   ¤   Rect.bottom = lpDs->rcItem.bottom;
f187c7 ¤   ¤   ¤
ae5830 ¤   ¤   ¤   // ·Create a brush using the item's background color
be1083 ¤   ¤   ¤   hBrush = CreateSolidBrush( GetSysColor(COLOR_WINDOW ));
2a87c7 ¤   ¤   ¤
aa178f ¤   ¤   ¤   // ·Fill entire item area
f20bb3 ¤   ¤   ¤   FillRect( lpDs->hDC, &Rect, hBrush ); ··
6d87c7 ¤   ¤   ¤
b168c8 ¤   ¤   ¤   // ·Delete the brush when done
8cd50f ¤   ¤   ¤   DeleteObject( hBrush ); ······
0687c7 ¤   ¤   ¤
8e81ce ¤   ¤   ¤   // ·Highlight if selected
1411fd ¤   ¤   ¤   if( lpDs->itemState & ODS_FOCUS )
55f776 ¤   ¤   ¤   {
ee24f2 ¤   ¤   ¤   ¤   if (!(lpDs->itemState & ODS_COMBOBOXEDIT)) {
39a92e ¤   ¤   ¤   ¤   ¤   if (lpDs->itemID == DividerItem) {
224752 ¤   ¤   ¤   ¤   ¤   ¤   iTextVOff = 1;
b73d71 ¤   ···············¤¤   Rect.bottom -= 2;
561c89 ¤   ¤   ¤   ¤   ¤   }
f83fc9 ¤   ¤   ¤   ¤   ¤   else if (lpDs->itemID == DividerItem+1)
c162b8 ¤   ¤   ¤   ¤   ¤   ¤   Rect.top += 1;
a72613 ¤   ¤   ¤   ¤   }
75af5a
36d275 ¤   ¤   ¤   ¤   // ·Create a brush using the item's background color
7c6d29 ¤   ¤   ¤   ¤   hBrush = CreateSolidBrush( GetSysColor(COLOR_HIGHLIGHT ));
1b87c7 ¤   ¤   ¤
092b61 ¤   ¤   ¤   ¤   // ·Fill entire item area
046480 ¤   ¤   ¤   ¤   FillRect( lpDs->hDC, &Rect, hBrush ); ··
fa87c7 ¤   ¤   ¤
7ff950 ¤   ¤   ¤   ¤   // ·Delete the brush when done
b6a083 ¤   ¤   ¤   ¤   DeleteObject( hBrush ); ·
556ebd ¤   ¤   ¤   } ······
e887c7 ¤   ¤   ¤
e134db ¤   ¤   ¤   // ·Get the item string
7fa469 ¤   ¤   ¤   SendMessage(lpDs->hwndItem,·
bc99d1 ¤   ¤   ¤   ¤   ¤   ¤   CB_GETLBTEXT ,·
37c76d ¤   ¤   ¤   ¤   ¤   ¤   lpDs->itemID,
024914 ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)szText );
d994aa ¤   ¤   ¤   ¤   ¤   ¤
2587c7 ¤   ¤   ¤
a3a39a ¤   ¤   ¤   SetBkMode( lpDs->hDC, TRANSPARENT );
5587c7 ¤   ¤   ¤
2aa86f ¤   ¤   ¤   SetTextColor( ¤ lpDs->hDC,·
808b53 ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor(( (lpDs->itemState & ODS_FOCUS) ?
31070e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   COLOR_HIGHLIGHTTEXT : COLOR_BTNTEXT) ));
0eaf5a
6cdbf1 ¤   ¤   ¤   // ·and display the text
1ab1fe ¤   ¤   ¤   TextOut(lpDs->hDC,·
276333 ¤   ¤   ¤   ¤   ¤   4,·
c32c0f ¤   ¤   ¤   ¤   ¤   lpDs->rcItem.top + iTextVOff,·
736c27 ¤   ¤   ¤   ¤   ¤   szText,
71576d ¤   ¤   ¤   ······¤ strlen( szText ) ); ·
0c947c ¤   ¤   ¤   ·
--2c88 0008266de54401102f4 Page 6 of SearchProc.c
12dace ·¤  ¤   ¤
47421f ·¤  ¤   ¤   EtchRect = lpDs->rcItem;
f3dace ·¤  ¤   ¤
d4f9f7 ·¤  ¤   ¤   if (!(lpDs->itemState & ODS_COMBOBOXEDIT) &&
6735a7 ¤   ¤   ¤   ¤   ·(lpDs->itemID == DividerItem))·
bcf776 ¤   ¤   ¤   {
e23532 ·······¤¤   ¤   EtchRect.top = EtchRect.bottom-1;
760ca7 ········¤   ¤
15fb44 ············¤   DrawEdge( ¤ lpDs->hDC,
5c15ea ·¤  ¤   ¤   ¤   ¤   ¤   ¤   &EtchRect,·
cd67e6 ·¤  ¤   ¤   ¤   ¤   ¤   ¤   EDGE_ETCHED,·
513706 ·¤  ¤   ¤   ¤   ¤   ¤   ¤   BF_TOP );·
57a3a6 ¤   ¤   ¤   }
51d653 ¤   ¤   ¤   ······¤ ······················¤
4932bd ¤   ¤   ¤   return TRUE;
fdaf5a
77ea88 ¤   ¤   } // ·End of WM_DRAWITEM
29af5a
3f83e3 ¤   ¤   case WM_GETDLGCODE:
a05b34 ¤   ¤   {
2486d4 ¤   ¤   ¤   return DLGC_WANTMESSAGE;¤
900fe4 ¤   ¤   }
23af5a
e82614 ¤   ¤   case WM_CONTEXTMENU:·
435b34 ¤   ¤   {
0f826e ¤   ¤   ¤   WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,·
88e5c1 ¤   ¤   ¤   ¤   (DWORD) (LPVOID) aSearchIds);·
645d5e ¤   ¤   ¤   break;·
7b0fe4 ¤   ¤   }
1eaf5a
571ecd ¤   ¤   case SEARCH_SET_LOCAL_KEYSET:
6f5b34 ¤   ¤   {
003603 ¤   ¤   ¤   HINSTANCE hinst¤¤   = GetModuleHandle(NULL);
172051 ¤   ¤   ¤   HWND hwndBox¤   ¤   = NULL;
396700 ¤   ¤   ¤   char szString[256]¤ = {0x00};
582d11 ¤   ¤   ¤   int i¤  ¤   ¤   ¤   = 0;
8eaf5a
b0911f ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_LOCATION);
63af5a
80b984 ¤   ¤   ¤   LoadString(hinst, IDS_LOCAL_KEYRING, szString, sizeof(szString));
e85620 ¤   ¤   ¤   i = ComboBox_FindString(hwndBox, -1, szString);
de15a9 ¤   ¤   ¤   ComboBox_SetItemData(hwndBox, i, lParam);
9aaf5a
13cdcb ¤   ¤   ¤   break;
ad0fe4 ¤   ¤   }
53af5a
1925b6 ¤   ¤   case SEARCH_SET_CURRENT_SEARCH:
025b34 ¤   ¤   {
fd3603 ¤   ¤   ¤   HINSTANCE hinst¤¤   = GetModuleHandle(NULL);
b62051 ¤   ¤   ¤   HWND hwndBox¤   ¤   = NULL;
5f6700 ¤   ¤   ¤   char szString[256]¤ = {0x00};
632d11 ¤   ¤   ¤   int i¤  ¤   ¤   ¤   = 0;
baaf5a
eb911f ¤   ¤   ¤   hwndBox = GetDlgItem(hwnd, IDC_LOCATION);
26af5a
96745a ¤   ¤   ¤   LoadString(hinst, IDS_CURRENT_SEARCH, szString, sizeof(szString));
345620 ¤   ¤   ¤   i = ComboBox_FindString(hwndBox, -1, szString);
c115a9 ¤   ¤   ¤   ComboBox_SetItemData(hwndBox, i, lParam);
04af5a
2acdcb ¤   ¤   ¤   break;
cd0fe4 ¤   ¤   }
f3af5a
900eee ¤   ¤   case SEARCH_SET_FOCUS:
d65b34 ¤   ¤   {
d5be0d ¤   ¤   ¤   SetFocus (GetDlgItem (hwnd, IDC_SEARCH));
65cdcb ¤   ¤   ¤   break;
b60fe4 ¤   ¤   }
6baf5a
6ab3c8 ¤   ¤   case WM_NOTIFY:
345b34 ¤   ¤   {
5c5808 ¤   ¤   ¤   LPNMHDR pnmh = (LPNMHDR) lParam;
8287c7 ¤   ¤   ¤
--d271 000f1ecc2d4401102f4 Page 7 of SearchProc.c
f6b7b0 ¤   ¤   ¤   switch(pnmh->code)
6af776 ¤   ¤   ¤   {
c84902 ¤   ¤   ¤   ¤   case REFRESH_KEYSERVER_LIST:
ce72c3 ¤   ¤   ¤   ¤   {
5f4b4e ¤   ¤   ¤   ¤   ¤   CRITICAL_SECTION* keyserverLock =·
8e2975 ¤   ¤   ¤   ¤   ¤   ¤   (CRITICAL_SECTION*) GetProp(hwnd, "KeyserverLock");
41af5a
d09b11 ¤   ¤   ¤   ¤   ¤   EnterCriticalSection(keyserverLock);
14ae30 ¤   ¤   ¤   ¤   ¤
0d370f ¤   ¤   ¤   ¤   ¤   ReloadKeyserverList(hwnd);
5baf5a
b9afed ¤   ¤   ¤   ¤   ¤   LeaveCriticalSection(keyserverLock);
f7af5a
8914c3 ¤   ¤   ¤   ¤   ¤   break;
f82613 ¤   ¤   ¤   ¤   }
69a3a6 ¤   ¤   ¤   }
50af5a
bccdcb ¤   ¤   ¤   break;
c10fe4 ¤   ¤   }
acaf5a
de2526 ¤   ¤   case WM_SIZE:
f15b34 ¤   ¤   {
04d236 ¤   ¤   ¤   BOOL fwSizeType = wParam; ·····// resizing flag·
2f90e9 ¤   ¤   ¤   WORD newWidth = LOWORD(lParam); ·// width of client area·
32f01d ¤   ¤   ¤   WORD newHeight = HIWORD(lParam); // height of client area·
34f504 ¤   ¤   ¤   int¤ delta = ·newWidth - oldWidth;
699752 ¤   ¤   ¤   RECT rectControl;
d6155d ¤   ¤   ¤   HWND hwndControl;
1eaf5a
aaaf5a
d8aeb2 ¤   ¤   ¤   if( newWidth < originalWidth )
9ef776 ¤   ¤   ¤   {
47d561 ¤   ¤   ¤   ¤   delta = originalWidth - oldWidth;
444b4d ¤   ¤   ¤   ¤   newWidth = originalWidth;
6a2b85 ¤   ¤   ¤   ¤
faa3a6 ¤   ¤   ¤   }
d4af5a
58bdef ¤   ¤   ¤   if( newWidth >= originalWidth )
39f776 ¤   ¤   ¤   {
ac280e ¤   ¤   ¤   ¤   PCHOICE choice = NULL;
91af5a
415452 ¤   ¤   ¤   ¤   oldWidth = newWidth;
d7e430 ¤   ¤   ¤   ¤   SetProp( hwnd, "oldWidth",(HANDLE) oldWidth);
74af5a
7f732b ¤   ¤   ¤   ¤   // move Search Button
386bd7 ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_SEARCH);
b8e904 ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
e423d2 ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
6a468b ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
29c926 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left + delta,
0a85ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
423c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
8824f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
9e1dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
32af5a
a9341a ¤   ¤   ¤   ¤   // move Stop Button
d7e2a9 ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_STOP);
07e904 ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
d423d2 ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
cc468b ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
ebc926 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left + delta,
3a85ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
6f3c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
e224f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
501dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
61af5a
5fa8eb ¤   ¤   ¤   ¤   // move Clear Button
273423 ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_CLEAR);
9be904 ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
4523d2 ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
c8468b ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
f1c926 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left + delta,
--ab15 000dd8d8f80401102f4 Page 8 of SearchProc.c
df85ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
2a3c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
7a24f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
551dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
95af5a
7faf5a
4afc7d ¤   ¤   ¤   ¤   // move Help Button
ff1f9c ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDHELP);
69e904 ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
2f23d2 ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
71468b ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
62c926 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left + delta,
4185ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
bd3c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
6f24f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
311dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
bdaf5a
adf91a ¤   ¤   ¤   ¤   // move the Boxes
5de1b4 ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO);
b2e904 ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
2623d2 ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
ea468b ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
8f7232 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
4c85ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
aae8a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left + delta,
1524f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
9b1dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
8aaf5a
b80ff0 ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_SPECIFIER_EDIT);
f2e904 ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
5023d2 ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
3f468b ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
ff7232 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
f485ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
602d83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left ·+ delta,
8d24f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
591dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
35af5a
683bb4 ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_SPECIFIER_COMBO_LIST);
a1e904 ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
7223d2 ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
24468b ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
b27232 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
3585ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top,
4ae8a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left + delta,
bc24f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
c61dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
0caf5a
3efdb2 ¤   ¤   ¤   ¤   // move all the choice windows
21ac91 ¤   ¤   ¤   ¤   choice = FirstChoice(hwnd);
0faf5a
4b5eaa ¤   ¤   ¤   ¤   while( choice )
f772c3 ¤   ¤   ¤   ¤   {
bd6ac3 ¤   ¤   ¤   ¤   ¤   hwndControl = ·choice->hwnd;
960b04 ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
86f379 ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
0c7f4e ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
683d0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
8e7af5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top ,
7491e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left + delta,
0231d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
a45c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
0caf5a
a7e620 ¤   ¤   ¤   ¤   ¤   choice = NextChoice(hwnd, choice);
012613 ¤   ¤   ¤   ¤   }
68af5a
83ffb9 ¤   ¤   ¤   ¤   // move the more and less buttons and the pending checkbox
4c4945 ¤   ¤   ¤   ¤   if(oldHeight != newHeight)
8c72c3 ¤   ¤   ¤   ¤   {
07ec8f ¤   ¤   ¤   ¤   ¤   delta = newHeight - oldHeight;
8caf5a
dd0e29 ¤   ¤   ¤   ¤   ¤   oldHeight = newHeight;
--d81c 0004793a433401102f4 Page 9 of SearchProc.c
5dce10 ¤   ¤   ¤   ¤   ¤   SetProp( hwnd, "oldHeight",(HANDLE) oldHeight);
8aaf5a
513916 ¤   ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_MORE);
ee0b04 ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
9df379 ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
117f4e ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
c23d0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
432e8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top + delta,
4129b7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
f531d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
055c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
a5af5a
44856f ¤   ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_FEWER);
060b04 ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
69f379 ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
6b7f4e ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
073d0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
0b2e8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top + delta,
6d29b7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
1131d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
f85c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
46af5a
124592 ¤   ¤   ¤   ¤   ¤   hwndControl = GetDlgItem(hwnd, IDC_PENDING);
350b04 ¤   ¤   ¤   ¤   ¤   GetWindowRect(hwndControl, &rectControl);
ddf379 ¤   ¤   ¤   ¤   ¤   MapWindowPoints(NULL, hwnd, (LPPOINT)&rectControl, 2);
507f4e ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwndControl,·
6c3d0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.left,
192e8b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.top + delta,
a329b7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.right - rectControl.left,
db31d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rectControl.bottom - rectControl.top,
565c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
2daf5a
c12613 ¤   ¤   ¤   ¤   }
12a3a6 ¤   ¤   ¤   }
b587c7 ¤   ¤   ¤
9332bd ¤   ¤   ¤   return TRUE;
3a0fe4 ¤   ¤   }
c5af5a
e3a810 ¤   ¤   case WM_PAINT:
e75b34 ¤   ¤   {
886473 ¤   ¤   ¤   RECT rect, rectParent;
7eaf5a
653165 ¤   ¤   ¤   GetClientRect(hwnd, &rect);
afe3e9 ¤   ¤   ¤   GetClientRect(GetParent(hwnd), &rectParent);
d2af5a
d5f2d5 ¤   ¤   ¤   if(rect.right != rectParent.right)
88f776 ¤   ¤   ¤   {
392b2f ¤   ¤   ¤   ¤   MapWindowPoints(hwnd, GetParent(hwnd), (LPPOINT)&rect, 2);
b6af5a
038d1b ¤   ¤   ¤   ¤   rect.left¤  = rectParent.left;
bb5646 ¤   ¤   ¤   ¤   rect.top¤   = rectParent.top;
be5e60 ¤   ¤   ¤   ¤   rect.right¤ = rectParent.right;
2caf5a
042297 ¤   ¤   ¤   ¤   MoveWindow(¤hwnd,·
0f3923 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.left,·
1b9173 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.top,·
096d7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.right - rect.left,
41f6fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.bottom - rect.top, ·
e51dd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
8fa3a6 ¤   ¤   ¤   }
6acdcb ¤   ¤   ¤   break;
880fe4 ¤   ¤   }
adaf5a
f88e1e ¤   ¤   case WM_COMMAND:
975b34 ¤   ¤   {
892a0d ¤   ¤   ¤   WORD wNotifyCode = HIWORD(wParam); // notification code·
029f3f ¤   ¤   ¤   WORD wID = LOWORD(wParam); ········// item, control id
f2af64 ¤   ¤   ¤   HWND hwndCtl = (HWND) lParam; ·····// handle of control·
d8d83c ·
c6c648 ¤   ¤   ¤   switch( wID )
62f776 ¤   ¤   ¤   {
47c719 ¤   ¤   ¤   ¤   case IDC_MORE:
--72d0 000668c5ef0401102f4 Page 10 of SearchProc.c
d072c3 ¤   ¤   ¤   ¤   {
017638 ¤   ¤   ¤   ¤   ¤   PCHOICE choice;
d85c05 ¤   ¤   ¤   ¤   ¤   RECT rectChoice;
92075b ¤   ¤   ¤   ¤   ¤   RECT rect;
79aaed ¤   ¤   ¤   ¤   ¤   int height;
48af5a
7a8cef ¤   ¤   ¤   ¤   ¤   if(wNotifyCode)
704859 ¤   ¤   ¤   ¤   ¤   {
ef00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
f81c89 ¤   ¤   ¤   ¤   ¤   }
6eaf5a
b34868 ¤   ¤   ¤   ¤   ¤   choice = NewChoice(hwnd);
76af5a
99a79d ¤   ¤   ¤   ¤   ¤   if(choice)
024859 ¤   ¤   ¤   ¤   ¤   {
5a0730 ¤   ¤   ¤   ¤   ¤   ¤   SIZEREQUEST request;
71689b ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndCtrl = NULL;
fdaf5a
29af5a
203712 ¤   ¤   ¤   ¤   ¤   ¤   GetClientRect(hwnd, &rect);
421713 ¤   ¤   ¤   ¤   ¤   ¤   GetClientRect(choice->hwnd, &rectChoice);
1aaf5a
322e04 ¤   ¤   ¤   ¤   ¤   ¤   height = rectChoice.bottom - rectChoice.top + 1;
e1af5a
3b7eb0 ¤   ¤   ¤   ¤   ¤   ¤   memset(&request, 0x00, sizeof(request));
d6af5a
b8a06a ¤   ¤   ¤   ¤   ¤   ¤   request.nmhdr.hwndFrom = hwnd;
8dd4c4 ¤   ¤   ¤   ¤   ¤   ¤   request.nmhdr.idFrom = IDD_SEARCH;
c46e21 ¤   ¤   ¤   ¤   ¤   ¤   request.nmhdr.code = SEARCH_REQUEST_SIZING;
a3dabe ¤   ¤   ¤   ¤   ¤   ¤   request.delta = height;
42af5a
76f98d ¤   ¤   ¤   ¤   ¤   ¤   if(SendMessage(¤GetParent(hwnd),·
b90be9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
12cb0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)hwnd,·
1f174e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&request))
878fec ¤   ¤   ¤   ¤   ¤   ¤   {
3790e9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   NMHDR nmhdr;
40af5a
3b293e ¤   ¤   ¤   ¤   ¤   ¤   ¤   height += rect.bottom - rect.top;
fbaf5a
cc8402 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MapWindowPoints(hwnd,
a7709a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetParent(hwnd),
706df0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPPOINT)&rect,
82b1dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   2);
9aaf5a
1e09b7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.bottom¤= rect.top + height;
b1af5a
6afcb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwnd,·
423f54 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.left,·
3dd615 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.top,·
6f739c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.right - rect.left,
55d57f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.bottom - rect.top,·
c4c3f4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
1faf5a
fec1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ShowWindow(choice->hwnd, SW_SHOW);
9faf5a
243458 ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwnd, IDC_FEWER), TRUE);
30531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
ef0501 ¤   ¤   ¤   ¤   ¤   ¤   ¤   memset(&nmhdr, 0x00, sizeof(nmhdr));
d8af5a
bc245a ¤   ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.hwndFrom = hwnd;
bef7bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.idFrom = IDD_SEARCH;
ea2aad ¤   ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.code = SEARCH_SIZING;
78af5a
fa413e ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwnd),·
2d0be9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
fbcb0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)hwnd,·
aa36c6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&nmhdr);
45af5a
aee5b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndCtrl = GetDlgItem(hwnd, IDC_MORE);
a57038 ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect(hwndCtrl, NULL, FALSE);
66d84e ¤   ¤   ¤   ¤   ¤   ¤   ¤   hwndCtrl = GetDlgItem(hwnd, IDC_FEWER);
--5147 00023d6b0e2401102f4 Page 11 of SearchProc.c
377038 ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect(hwndCtrl, NULL, FALSE);
e0af5a
5adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
9f7f8b ¤   ¤   ¤   ¤   ¤   ¤   else
768fec ¤   ¤   ¤   ¤   ¤   ¤   {
9e68b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   HWND hwndChoice;
98af5a
3602be ¤   ¤   ¤   ¤   ¤   ¤   ¤   RemoveLastChoice(hwnd, &hwndChoice);
34b6f4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DestroyWindow(hwndChoice);
dbdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
6b1c89 ¤   ¤   ¤   ¤   ¤   }
baaf5a
0114c3 ¤   ¤   ¤   ¤   ¤   break;
772613 ¤   ¤   ¤   ¤   }
5daf5a
712e28 ¤   ¤   ¤   ¤   case IDC_FEWER:
8172c3 ¤   ¤   ¤   ¤   {
bc7638 ¤   ¤   ¤   ¤   ¤   PCHOICE choice;
3e6be3 ¤   ¤   ¤   ¤   ¤   HWND hwndChoice;
ef5c05 ¤   ¤   ¤   ¤   ¤   RECT rectChoice;
91075b ¤   ¤   ¤   ¤   ¤   RECT rect;
1faaed ¤   ¤   ¤   ¤   ¤   int height;
03a86c ¤   ¤   ¤   ¤   ¤   NMHDR nmhdr;
17af5a
9e8cef ¤   ¤   ¤   ¤   ¤   if(wNotifyCode)
914859 ¤   ¤   ¤   ¤   ¤   {
1a00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
581c89 ¤   ¤   ¤   ¤   ¤   }
55af5a
97699b ¤   ¤   ¤   ¤   ¤   choice = RemoveLastChoice(hwnd, &hwndChoice);
32af5a
99a153 ¤   ¤   ¤   ¤   ¤   GetClientRect(hwnd, &rect);
1b00b6 ¤   ¤   ¤   ¤   ¤   GetClientRect(hwndChoice, &rectChoice);
33af5a
e6ae9b ¤   ¤   ¤   ¤   ¤   height = rect.bottom - rect.top;
2828d3 ¤   ¤   ¤   ¤   ¤   height -= rectChoice.bottom - rectChoice.top + 1;
2faf5a
d5c608 ¤   ¤   ¤   ¤   ¤   MapWindowPoints(hwnd, GetParent(hwnd), (LPPOINT)&rect, 2);
b8af5a
ff4031 ¤   ¤   ¤   ¤   ¤   rect.bottom¤= rect.top + height;
a0af5a
e76364 ¤   ¤   ¤   ¤   ¤   MoveWindow(¤hwnd,·
12b145 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.left,·
ae9f3f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.top,·
6038d7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.right - rect.left,
5629e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rect.bottom - rect.top,·
6b5c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
51af5a
21483a ¤   ¤   ¤   ¤   ¤   if(!choice)
6d4859 ¤   ¤   ¤   ¤   ¤   {
933cc5 ¤   ¤   ¤   ¤   ¤   ¤   EnableWindow(GetDlgItem(hwnd, IDC_FEWER), FALSE);
c81c89 ¤   ¤   ¤   ¤   ¤   }
89af5a
867f61 ¤   ¤   ¤   ¤   ¤   DestroyWindow(hwndChoice);
b9af5a
a8f99d ¤   ¤   ¤   ¤   ¤   memset(&nmhdr, 0x00, sizeof(nmhdr));
d0af5a
9f6d70 ¤   ¤   ¤   ¤   ¤   nmhdr.hwndFrom = hwnd;
ac3e2e ¤   ¤   ¤   ¤   ¤   nmhdr.idFrom = IDD_SEARCH;
a0e940 ¤   ¤   ¤   ¤   ¤   nmhdr.code = SEARCH_SIZING;
b9af5a
8eec48 ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwnd),·
1785f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
100299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)hwnd,·
960aee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&nmhdr);
9aaf5a
9114c3 ¤   ¤   ¤   ¤   ¤   break;
872613 ¤   ¤   ¤   ¤   }
c3af5a
892bdc ¤   ¤   ¤   ¤   case IDC_CLEAR:
9672c3 ¤   ¤   ¤   ¤   {
2376e8 ¤   ¤   ¤   ¤   ¤   HWND¤   hwndItem¤   = NULL;
--1052 000b84bd4c2401102f4 Page 12 of SearchProc.c
863f64 ¤   ¤   ¤   ¤   ¤   int¤¤   count¤  ¤   = ChoiceCount(hwnd);
5eae30 ¤   ¤   ¤   ¤   ¤
968cef ¤   ¤   ¤   ¤   ¤   if(wNotifyCode)
774859 ¤   ¤   ¤   ¤   ¤   {
c100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
8d1c89 ¤   ¤   ¤   ¤   ¤   }
eeaf5a
5a2c2d ¤   ¤   ¤   ¤   ¤   // delete extra choices
0ca12f ¤   ¤   ¤   ¤   ¤   for(count; count > 0; count--)
fa4859 ¤   ¤   ¤   ¤   ¤   {
92d4f6 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(hwnd,·
d625a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_COMMAND,·
945fbe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM(IDC_FEWER, 0),·
cf189c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0);
f51c89 ¤   ¤   ¤   ¤   ¤   }
1eae30 ¤   ¤   ¤   ¤   ¤
c9ad13 ¤   ¤   ¤   ¤   ¤   // reset default choice
abbfa7 ¤   ¤   ¤   ¤   ¤   hwndItem = GetDlgItem(hwnd, IDC_ATTRIBUTE);
4e439d ¤   ¤   ¤   ¤   ¤   ComboBox_SetCurSel(hwndItem, 0);
96af5a
172b67 ¤   ¤   ¤   ¤   ¤   ChangeAttributeSelection(hwndItem);
f6af5a
9d59c3 ¤   ¤   ¤   ¤   ¤   hwndItem = GetDlgItem(hwnd, IDC_SPECIFIER_EDIT);
59cbc7 ¤   ¤   ¤   ¤   ¤   Edit_SetText(hwndItem, "");
7eaf5a
0714c3 ¤   ¤   ¤   ¤   ¤   break;
a72613 ¤   ¤   ¤   ¤   }
22af5a
154c29 ¤   ¤   ¤   ¤   case IDC_SEARCH:
5172c3 ¤   ¤   ¤   ¤   {
174f19 ¤   ¤   ¤   ¤   ¤   PGPFilterRef¤   filter = NULL;
bfb2b0 ¤   ¤   ¤   ¤   ¤   PGPFilterRef¤   SearchFilter = NULL;
f2e5a0 ¤   ¤   ¤   ¤   ¤   PCHOICE¤¤   ¤   choice = NULL;
e5c08d ¤   ¤   ¤   ¤   ¤   PGPError¤   ¤   error;
14db39 ¤   ¤   ¤   ¤   ¤   int¤¤   ¤   ¤   action = 0;
d0810b ¤   ¤   ¤   ¤   ¤   HWND¤   ¤   ¤   hwndStop = NULL;
d2ae30 ¤   ¤   ¤   ¤   ¤
798cef ¤   ¤   ¤   ¤   ¤   if(wNotifyCode)
6a4859 ¤   ¤   ¤   ¤   ¤   {
1800eb ¤   ¤   ¤   ¤   ¤   ¤   break;
d71c89 ¤   ¤   ¤   ¤   ¤   }
42af5a
52c6d5 ¤   ¤   ¤   ¤   ¤   hwndStop = GetDlgItem(hwnd, IDC_STOP);
fdaf5a
22f17e ¤   ¤   ¤   ¤   ¤   ShowWindow(hwndStop, SW_SHOW);
254573 ¤   ¤   ¤   ¤   ¤   EnableWindow(hwndCtl, FALSE);
422fe7 ¤   ¤   ¤   ¤   ¤   ShowWindow(hwndCtl, SW_HIDE);
3daf5a
5efc65 ¤   ¤   ¤   ¤   ¤   // Take Care of the Default Search Item in ourself
766b30 ¤   ¤   ¤   ¤   ¤   error = CreateFilter(hwnd, &filter, &action);
d6af5a
7a44ae ¤   ¤   ¤   ¤   ¤   SearchFilter = filter;
18af5a
0d2855 ¤   ¤   ¤   ¤   ¤   if( IsntPGPError (error ) )
6b4859 ¤   ¤   ¤   ¤   ¤   {
15259f ¤   ¤   ¤   ¤   ¤   ¤   // now iterate the children if there are any
a02280 ¤   ¤   ¤   ¤   ¤   ¤   choice = FirstChoice(hwnd);
11af5a
388cf8 ¤   ¤   ¤   ¤   ¤   ¤   while( choice && IsntPGPError (error ) )
cba8f4 ¤   ¤   ¤   ¤   ¤   ¤   {¤  ¤   ¤   ¤   ¤   ¤   ¤
24912b ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = CreateFilter(¤  choice->hwnd,·
c05476 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &filter,·
5883e1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &action);
faaf5a
61ebb8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError (error ) )
2f06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
03b280 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFilterRef CombinedFilter = NULL;
acaf5a
f7f4dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // | the filters
55547c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( action == ACTION_UNION ) ·
ee31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
b8b35a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPUnionFilters(
--22a9 000cbbc7c83401102f4 Page 13 of SearchProc.c
664599 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter,
192e48 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SearchFilter,·
b8aa08 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &CombinedFilter);
006560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
7b73d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // & the filters
16f38b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else if( action == ACTION_INTERSECT )·
6d31b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
baa8b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPIntersectFilters(
168185 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   filter,
653dc4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SearchFilter,·
55bcbe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &CombinedFilter);
35ed43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
7c6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
29af5a
2faedb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SearchFilter = CombinedFilter;·
7c5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
64af5a
a4e1f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   choice = NextChoice(hwnd, choice);
7cdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
e61c89 ¤   ¤   ¤   ¤   ¤   }
4296bc ¤   ¤   ¤   ¤   ¤   else·
6b4859 ¤   ¤   ¤   ¤   ¤   {
61aecd ¤   ¤   ¤   ¤   ¤   ¤   PGPclErrorBox (NULL, error);
441c89 ¤   ¤   ¤   ¤   ¤   }
26ae30 ¤   ¤   ¤   ¤   ¤
09eaa3 ¤   ¤   ¤   ¤   ¤   EnableWindow (hwndStop, TRUE);
c3af5a
472b28 ¤   ¤   ¤   ¤   ¤   if( IsntPGPError(error) )
8d4859 ¤   ¤   ¤   ¤   ¤   {
8d3fb1 ¤   ¤   ¤   ¤   ¤   ¤   PSEARCHTHREADSTRUCT psts = NULL;
08af5a
26d2b6 ¤   ¤   ¤   ¤   ¤   ¤   psts = (PSEARCHTHREADSTRUCT)
47bea2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetProp( hwnd, "SearchInfo");
16af5a
80e8fc ¤   ¤   ¤   ¤   ¤   ¤   if( psts )
ae8fec ¤   ¤   ¤   ¤   ¤   ¤   {
320587 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!psts->threadHandle)
2206b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
cad2da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   memset(psts, 0x00,·
9d8dc7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(SEARCHTHREADSTRUCT));
c2af5a
374ec6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->hwnd = hwnd;
8e016f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->filter = SearchFilter;
5da299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->bCancel = FALSE;
9d6c03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->bAlreadyAsked = FALSE;
47af5a
95f7a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetProp( hwnd, "SearchInfo",(HANDLE) psts);
6eaf5a
d3e741 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->threadHandle = CreateThread(¤ NULL,·
d35796 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
0d11f9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SearchThreadRoutine,·
5edc9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (void*)psts,·
275796 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
54f3b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &psts->threadID);
d65268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
1fdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
fb1c89 ¤   ¤   ¤   ¤   ¤   }
4eaf5a
d65364 ¤   ¤   ¤   ¤   ¤   if( IsPGPError(error) )
be4859 ¤   ¤   ¤   ¤   ¤   {
5ca268 ¤   ¤   ¤   ¤   ¤   ¤   SEARCHABORT abort;
a8af5a
7a62a4 ¤   ¤   ¤   ¤   ¤   ¤   if (filter) PGPFreeFilter (filter);
58af5a
c1bddd ¤   ¤   ¤   ¤   ¤   ¤   abort.nmhdr.hwndFrom = hwnd;
189893 ¤   ¤   ¤   ¤   ¤   ¤   abort.nmhdr.idFrom = IDD_SEARCH;
4d29cf ¤   ¤   ¤   ¤   ¤   ¤   abort.nmhdr.code = SEARCH_ABORT;
68d83a ¤   ¤   ¤   ¤   ¤   ¤   abort.error = kPGPError_UserAbort;
afaf5a
894249 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(hwnd),·
5785f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
cb0299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)hwnd,·
--f2c3 0002c33766f401102f4 Page 14 of SearchProc.c
507a3b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&abort);
7caf5a
f0fbbd ¤   ¤   ¤   ¤   ¤   ¤   ShowWindow(hwndCtl, SW_SHOW);
cc9a02 ¤   ¤   ¤   ¤   ¤   ¤   ShowWindow(hwndStop, SW_HIDE);
8e1c89 ¤   ¤   ¤   ¤   ¤   }
5daf5a
0114c3 ¤   ¤   ¤   ¤   ¤   break;
2b2613 ¤   ¤   ¤   ¤   }
78af5a
bcbba1 ¤   ¤   ¤   ¤   case IDC_STOP:
3872c3 ¤   ¤   ¤   ¤   {
7c3710 ¤   ¤   ¤   ¤   ¤   HWND hwndSearch, hwndStop;
50d840 ¤   ¤   ¤   ¤   ¤   PSEARCHTHREADSTRUCT psts;
b9af5a
228cef ¤   ¤   ¤   ¤   ¤   if(wNotifyCode)
454859 ¤   ¤   ¤   ¤   ¤   {
0f00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
b61c89 ¤   ¤   ¤   ¤   ¤   }
e4af5a
1144f2 ¤   ¤   ¤   ¤   ¤   hwndSearch = GetDlgItem(hwnd, IDC_SEARCH);
f2c6d5 ¤   ¤   ¤   ¤   ¤   hwndStop = GetDlgItem(hwnd, IDC_STOP);
9aaf5a
eb1b0b ¤   ¤   ¤   ¤   ¤   if(!IsWindowEnabled (hwndStop))
b24859 ¤   ¤   ¤   ¤   ¤   {
0100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
931c89 ¤   ¤   ¤   ¤   ¤   }
e0af5a
454e48 ¤   ¤   ¤   ¤   ¤   psts = (PSEARCHTHREADSTRUCT) GetProp(hwnd, "SearchInfo");
8baf5a
ab5e52 ¤   ¤   ¤   ¤   ¤   EnableWindow(hwndStop, FALSE);
76af5a
bbf047 ¤   ¤   ¤   ¤   ¤   if(psts)
804859 ¤   ¤   ¤   ¤   ¤   {
7e370f ¤   ¤   ¤   ¤   ¤   ¤   PGPEvent event;
02d45e ¤   ¤   ¤   ¤   ¤   ¤   PGPEventErrorData data;
8cac40 ¤   ¤   ¤   ¤   ¤   ¤   PGPError err;
f4af5a
1950dc ¤   ¤   ¤   ¤   ¤   ¤   if (PGPKeyServerRefIsValid (psts->server))
408fec ¤   ¤   ¤   ¤   ¤   ¤   {
e9b13b ¤   ¤   ¤   ¤   ¤   ¤   ¤   err = PGPCancelKeyServerCall (psts->server);
dd9aa2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclErrorBox (hwnd, err);
b1db3c ¤   ¤   ¤   ¤   ¤   ¤   }
18af5a
448360 ¤   ¤   ¤   ¤   ¤   ¤   data.error = kPGPError_UserAbort;
feaf5a
5c2be2 ¤   ¤   ¤   ¤   ¤   ¤   memset(&event, 0x00, sizeof(PGPEvent));
d4af5a
af3bdc ¤   ¤   ¤   ¤   ¤   ¤   event.type = kPGPEvent_ErrorEvent;
b036bd ¤   ¤   ¤   ¤   ¤   ¤   event.data.errorData = data;
a5af5a
1614d8 ¤   ¤   ¤   ¤   ¤   ¤   SearchEventHandler(¤NULL,
1daeb5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &event,·
f9fa45 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts);
d31c89 ¤   ¤   ¤   ¤   ¤   }
3faf5a
84f047 ¤   ¤   ¤   ¤   ¤   if(psts)
8c4859 ¤   ¤   ¤   ¤   ¤   {
b0a268 ¤   ¤   ¤   ¤   ¤   ¤   SEARCHABORT abort;
e8af5a
fece21 ¤   ¤   ¤   ¤   ¤   ¤   memset(&abort, 0x00, sizeof(abort));
5aaf5a
b73627 ¤   ¤   ¤   ¤   ¤   ¤   abort.nmhdr.hwndFrom = psts->hwnd;
239893 ¤   ¤   ¤   ¤   ¤   ¤   abort.nmhdr.idFrom = IDD_SEARCH;
4b29cf ¤   ¤   ¤   ¤   ¤   ¤   abort.nmhdr.code = SEARCH_ABORT;
eed83a ¤   ¤   ¤   ¤   ¤   ¤   abort.error = kPGPError_UserAbort;
31af5a
ab8628 ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(psts->hwnd),·
5c85f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
504318 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)psts->hwnd,·
0b7a3b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&abort);
ea1c89 ¤   ¤   ¤   ¤   ¤   }
2caf5a
--19ec 000e4f46322401102f4 Page 15 of SearchProc.c
f014c3 ¤   ¤   ¤   ¤   ¤   break;
092613 ¤   ¤   ¤   ¤   }
5baf5a
4725b5 ¤   ¤   ¤   ¤   case IDHELP:
d272c3 ¤   ¤   ¤   ¤   {
158cef ¤   ¤   ¤   ¤   ¤   if(wNotifyCode)
704859 ¤   ¤   ¤   ¤   ¤   {
2000eb ¤   ¤   ¤   ¤   ¤   ¤   break;
c41c89 ¤   ¤   ¤   ¤   ¤   }
7baf5a
fe6720 ¤   ¤   ¤   ¤   ¤   WinHelp (hwnd, g_szHelpFile, HELP_CONTEXT, ··············
c98a9f ························IDH_PGPPK_SEARCH_DIALOG);
8eaf5a
4914c3 ¤   ¤   ¤   ¤   ¤   break;
192613 ¤   ¤   ¤   ¤   }
dfaf5a
f92b85 ¤   ¤   ¤   ¤
fd727c ¤   ¤   ¤   ¤   case IDC_ATTRIBUTE:
7b72c3 ¤   ¤   ¤   ¤   {
953a11 ¤   ¤   ¤   ¤   ¤   HANDLE_IDC_ATTRIBUTE(hwnd, msg, wParam, lParam);
7e14c3 ¤   ¤   ¤   ¤   ¤   break;
1e2613 ¤   ¤   ¤   ¤   }
47af5a
f0119d ¤   ¤   ¤   ¤   case IDC_LOCATION:
6a72c3 ¤   ¤   ¤   ¤   {
0b97c7 ¤   ¤   ¤   ¤   ¤   INT i;
3fdd24 ¤   ¤   ¤   ¤   ¤   if (wNotifyCode == CBN_DROPDOWN)
314859 ¤   ¤   ¤   ¤   ¤   {
3e911a ¤   ¤   ¤   ¤   ¤   ¤   RECT rc;
0488f3 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowRect (hwndCtl, &rc);
5e1716 ¤   ¤   ¤   ¤   ¤   ¤   i = rc.top;
c61c89 ¤   ¤   ¤   ¤   ¤   }
c835c0 ¤   ¤   ¤   ¤   ¤   if (wNotifyCode == CBN_SELCHANGE)
db4859 ¤   ¤   ¤   ¤   ¤   {
6e911a ¤   ¤   ¤   ¤   ¤   ¤   RECT rc;
a188f3 ¤   ¤   ¤   ¤   ¤   ¤   GetWindowRect (hwndCtl, &rc);
d01716 ¤   ¤   ¤   ¤   ¤   ¤   i = rc.top;
b21c89 ¤   ¤   ¤   ¤   ¤   }
2114c3 ¤   ¤   ¤   ¤   ¤   break;
f12613 ¤   ¤   ¤   ¤   }
89a3a6 ¤   ¤   ¤   }
40af5a
4f32bd ¤   ¤   ¤   return TRUE;
780fe4 ¤   ¤   }
ccaf5a
b29371 ¤   }
f4af5a
5fa230 ¤   return FALSE;
deefe6 }
9aaf5a
6daf5a
611c0e PGPError PerformSearch(HWND hwndLocation,·
4533b6 ¤   ¤   ¤   ¤   ¤   ···PSEARCHTHREADSTRUCT psts,
ee4ab6 ¤   ¤   ¤   ¤   ¤   ···BOOL¤bPending,
736372 ¤   ¤   ¤   ¤   ¤   ···long* flags,
7b4231 ¤   ¤   ¤   ¤   ¤   ···PGPKeySetRef* pKeySetOut)
05bb36 {
17d1d4 ¤   HINSTANCE¤  ¤   hinst¤  ¤   ¤   ¤   = GetModuleHandle(NULL);
48e68f ¤   PGPError¤   ¤   error¤  ¤   ¤   ¤   = kPGPError_NoErr;
de0203 ¤   PGPKeySetRef¤   localKeySet¤¤   ¤   = kPGPInvalidRef;·
01610c ¤   int¤¤   ¤   ¤   locationSelection¤  = 0;
c747ba ¤   int¤¤   ¤   ¤   lastSearchIndex¤¤   = 0;
d8976f ¤   int¤¤   ¤   ¤   localSearchIndex¤   = 0;
152803 ¤   int¤¤   ¤   ¤   searchPathIndex¤¤   = 0;
c8dbca ¤   char*¤  ¤   ¤   locationBuffer¤ ¤   = NULL;
86a386 ¤   int¤¤   ¤   ¤   locationLength¤ ¤   = 0;
f185ec ¤   LPARAM¤ ¤   ¤   lParam¤ ¤   ¤   ¤   = 0;
91e045 ¤   int¤¤   ¤   ¤   lastSearchType¤ ¤   = 0;
a5f06b ¤   char¤   ¤   ¤   szString[256]¤  ¤   = {0x00};
2bb94a ¤   PGPKeyServerAccessType¤ accessType¤ = kPGPKeyServerAccessType_Normal;
4b1c79 ¤   CRITICAL_SECTION*¤  keyserverLock¤  =·
e49fc6 ¤   ¤   ¤   ¤   ¤   ¤   (CRITICAL_SECTION*) GetProp(GetParent(hwndLocation),·
--ea29 000f0a04c5f401102f4 Page 16 of SearchProc.c
c8617d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "KeyserverLock");
d29a5c ¤   PGPKeyServerThreadStorageRef¤   previousStorage;
fbaf5a
b3af5a
22377d ¤   #if PGP_BUSINESS_SECURITY
626cba ¤   #if PGP_ADMIN_BUILD
ccb274 ¤   ¤   accessType¤ = kPGPKeyServerAccessType_Administrator;
5a28e6 ¤   #endif¤ // PGP_ADMIN_BUILD
39aada ¤   #endif¤ // PGP_BUSINESS_SECURITY
1467c5 ¤
5c5605 ¤   PGPKeyServerInit();
6fde4f ¤   PGPKeyServerCreateThreadStorage(&previousStorage);
78af5a
4af31c ¤   EnterCriticalSection(keyserverLock);
8faf5a
d2dabd ¤   lastSearchType = (int)GetProp(hwndLocation, "LastSearchType");
2caf5a
b24928 ¤   LoadString(hinst, IDS_DEFAULT_PATH, szString, sizeof(szString));
3d1645 ¤   searchPathIndex = ComboBox_FindString(hwndLocation, -1, szString);
c6af5a
bcd678 ¤   LoadString(hinst, IDS_LOCAL_KEYRING, szString, sizeof(szString));
d9e5da ¤   localSearchIndex = ComboBox_FindString(hwndLocation, -1, szString);
44af5a
eb49d6 ¤   LoadString(hinst, IDS_CURRENT_SEARCH, szString, sizeof(szString));
4f1eae ¤   lastSearchIndex = ComboBox_FindString(hwndLocation, -1, szString);
ceaf5a
4f5dbd ¤   locationSelection = ComboBox_GetCurSel(hwndLocation);
6daf5a
8d6e10 ¤   lParam = ComboBox_GetItemData(hwndLocation, locationSelection);
6daf5a
718570 ¤   psts->keySet =·
edc444 ¤   ¤   (PGPKeySetRef) ComboBox_GetItemData(hwndLocation, localSearchIndex);
99af5a
cfc7e0 ¤   LeaveCriticalSection(keyserverLock);
aaaf5a
eb6814 ¤   if (lParam == 0L ) // NULL: Invalid Selection
49c7a1 ¤   {
08d34c ¤   ¤   *pKeySetOut = kPGPInvalidRef;
659371 ¤   }
25af5a
d8f684 ¤   // Default Path·
3a6cd7 ¤   else if( locationSelection == searchPathIndex )
4bc7a1 ¤   {
0d8930 ¤   ¤   PGPPrefRef prefs;
a06467 ¤   ¤   PGPtlsSessionRef tls = kInvalidPGPtlsSessionRef;
2c7ca3 ¤   ¤   PGPKeyServerEntry* keyserverList = NULL;
407ebc ¤   ¤   PGPUInt32 keyserverCount = 0;
7de54e ¤   ¤   char* searchString = NULL;
1f25f3 ¤   ¤   int searchStringLength = 0;
e04e2d ¤   ¤   char emailDomain[512] = {0x00};
14af5a
57683b ¤   ¤   *flags = FLAG_SEARCH_MEMORY;
5bf187 ¤   ¤   SetProp( hwndLocation, "LastSearchType",(HANDLE) *flags);
29af5a
f941aa ¤   ¤   // retrieve search string from control
9d7b5a ¤   ¤   GrabUserIdStrings(¤ GetParent(hwndLocation),
51e838 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &searchString,
9e476a ¤   ¤   ¤   ¤   ¤   ¤   ¤   &searchStringLength);
b4af5a
b12067 ¤   ¤   if(searchString)
da5b34 ¤   ¤   {
2d380f ¤   ¤   ¤   PGPFindEmailDomain(searchString, emailDomain);
4b0fe4 ¤   ¤   }
4caf5a
781ee6 ¤   ¤   error = PGPclOpenClientPrefs(
c99bf9 ¤   ¤   ¤   ¤   ¤   PGPGetContextMemoryMgr (g_Context),
2a98e7 ¤   ¤   ¤   ¤   ¤   &prefs);
51af5a
b2cb70 ¤   ¤   if( IsntPGPError( error ) )
035b34 ¤   ¤   {
afe8de ¤   ¤   ¤   DWORD index = 0;
f0af5a
--8c54 000232eb264401102f4 Page 17 of SearchProc.c
dbdff5 ¤   ¤   ¤   error = PGPCreateKeyServerPath(¤prefs,
2fbccb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   emailDomain,
e22cf8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverList,
16710a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keyserverCount);
070e25 ¤   ¤   ¤   if( IsntPGPError( error ) )
abf776 ¤   ¤   ¤   {
c11ac5 ¤   ¤   ¤   ¤   for(index = 0; index < keyserverCount; index++)
c072c3 ¤   ¤   ¤   ¤   {
3cb225 ¤   ¤   ¤   ¤   ¤   SEARCHPROGRESS progress;
53aeef ¤   ¤   ¤   ¤   ¤   char templateString[256];
38af5a
c35576 ¤   ¤   ¤   ¤   ¤   memset(&progress, 0x00, sizeof(progress));
3aaf5a
33f40d ¤   ¤   ¤   ¤   ¤   progress.nmhdr.hwndFrom = GetParent(hwndLocation);
1a86a3 ¤   ¤   ¤   ¤   ¤   progress.nmhdr.idFrom = IDD_SEARCH;
48a8c1 ¤   ¤   ¤   ¤   ¤   progress.nmhdr.code = SEARCH_PROGRESS;
b03bd2 ¤   ¤   ¤   ¤   ¤   progress.step = SEARCH_PROGRESS_INFINITE;
3a1436 ¤   ¤   ¤   ¤   ¤   progress.total = SEARCH_PROGRESS_INFINITE;
d7af5a
7c700d ¤   ¤   ¤   ¤   ¤   LoadString(¤g_hInst,
c006e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IDS_SEARCH_MESSAGE_SERVER_NAME,
c21b21 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   templateString,
37be1b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(templateString));
dfaf5a
b9d50d ¤   ¤   ¤   ¤   ¤   wsprintf(¤  progress.message,
8215dc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   templateString,·
093c24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[index].serverDNS);
03af5a
42b9db ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(GetParent(hwndLocation)),·
1d85f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
ac367a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)GetParent(hwndLocation),·
51a99a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&progress);
9eaf5a
6811c5 ¤   ¤   ¤   ¤   ¤   error = PGPNewKeyServerFromHostName(·
ce77b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,
4f9155 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[index].serverDNS,
7d3200 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[index].serverPort,
e61839 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[index].protocol,
a43799 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   accessType,·
797b74 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (bPending ? kPGPKeyServerKeySpace_Pending :·
3ec845 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyServerKeySpace_Default),·
aa0725 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &psts->server );
3faf5a
192b85 ¤   ¤   ¤   ¤
1e9e13 ¤   ¤   ¤   ¤   ¤   if( IsntPGPError( error ) )
3d4859 ¤   ¤   ¤   ¤   ¤   {
a2edd2 ¤   ¤   ¤   ¤   ¤   ¤   memcpy(&(psts->keyserverEntry),·
e4eb8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(keyserverList[index]),·
fcb765 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(PGPKeyServerEntry));
cbaf5a
774347 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPSetKeyServerEventHandler( psts->server,·
e6972c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SearchEventHandler, psts );
13af5a
7e2ff9 ¤   ¤   ¤   ¤   ¤   ¤   if ( IsntPGPError( error ) )·
208fec ¤   ¤   ¤   ¤   ¤   ¤   {
f0531f ¤   ¤   ¤   ¤   ¤   ¤   ¤
9b0127 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(¤(kPGPKeyServerType_LDAPS ==·
b0e498 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[index].protocol) ||
731219 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (kPGPKeyServerType_HTTPS ==·
d740ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   keyserverList[index].protocol))
2f06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
8252b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPNewTLSSession(¤  g_TLSContext,
67787c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tls );
6a88d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsPGPError(error) )
6731b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
80e1b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // warn beyond the icon?
b9c408 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tls = kInvalidPGPtlsSessionRef;
5b6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
6f5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
02af5a
f7a1f0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPKeyServerOpen( psts->server, tls );
23af5a
--bc23 00042d88726401102f4 Page 18 of SearchProc.c
53a379 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if ( IsntPGPError(error) )·
ca06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
ea1497 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPQueryKeyServer(¤ psts->server,·
5db7d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->filter,·
a0cdc7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKeySetOut);
bdda4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
b21298 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPKeyServerClose ( psts->server );
765268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
0adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
b5af5a
29f87b ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeKeyServer( psts->server );
5b9580 ¤   ¤   ¤   ¤   ¤   ¤   psts->server = kInvalidPGPKeyServerRef;
59af5a
1f1842 ¤   ¤   ¤   ¤   ¤   ¤   if( PGPtlsSessionRefIsValid(tls) )
af8fec ¤   ¤   ¤   ¤   ¤   ¤   {
278e8f ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeTLSSession( tls );
6e3d7a ¤   ¤   ¤   ¤   ¤   ¤   ¤   tls = kInvalidPGPtlsSessionRef;
3adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
99af5a
fe0852 ¤   ¤   ¤   ¤   ¤   ¤   if( IsntPGPError( error ) )
698fec ¤   ¤   ¤   ¤   ¤   ¤   {
21678d ¤   ¤   ¤   ¤   ¤   ¤   ¤   EnterCriticalSection(keyserverLock);
ccaf5a
6fdde0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ComboBox_SetItemData(¤  hwndLocation,·
56b9cd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lastSearchIndex,·
e78cd4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *pKeySetOut);
fd5371 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LeaveCriticalSection(keyserverLock);
abaf5a
f78c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
a8db3c ¤   ¤   ¤   ¤   ¤   ¤   }
b21c89 ¤   ¤   ¤   ¤   ¤   }
742613 ¤   ¤   ¤   ¤   }
56af5a
128e13 ¤   ¤   ¤   ¤   PGPDisposeKeyServerPath(keyserverList);
5da3a6 ¤   ¤   ¤   }
6caf5a
f235d6 ¤   ¤   ¤   PGPclCloseClientPrefs (prefs, FALSE);
800fe4 ¤   ¤   }
00af5a
702067 ¤   ¤   if(searchString)
3e95e9 ¤   ¤   { ·
b62b6e ¤   ¤   ¤   free(searchString);
d20fe4 ¤   ¤   }
c29371 ¤   }
0baf5a
e0c14b ¤   // peform search on a local KeySet (keyring or mem)
371ab0 ¤   else if(locationSelection == localSearchIndex ||
d1acb3 ¤   ¤   ¤   locationSelection == lastSearchIndex)
1fc7a1 ¤   {
333945 ¤   ¤   localKeySet = (PGPKeySetRef) lParam;
e8af5a
091198 ¤   ¤   if(locationSelection == lastSearchIndex)
515b34 ¤   ¤   {
8a84fe ¤   ¤   ¤   *flags = lastSearchType;
b20fe4 ¤   ¤   }
810e1d ¤   ¤   else
c85b34 ¤   ¤   {
a75569 ¤   ¤   ¤   *flags = FLAG_SEARCH_LOCAL_KEYSET;
efe4a4 ¤   ¤   ¤   SetProp( hwndLocation, "LastSearchType",(HANDLE) *flags);
9e0fe4 ¤   ¤   }
d1af5a
4fd9f0 ¤   ¤   if(localKeySet != kPGPInvalidRef)
b25b34 ¤   ¤   {
777b3f ¤   ¤   ¤   error = PGPFilterKeySet( localKeySet, psts->filter, pKeySetOut);
3caf5a
9d1e57 ¤   ¤   ¤   if( IsPGPError(error) )
b7f776 ¤   ¤   ¤   {
27d667 ¤   ¤   ¤   ¤   *pKeySetOut = kPGPInvalidRef;
70a3a6 ¤   ¤   ¤   }
050fe4 ¤   ¤   }
98ee26 ¤   ¤   else·
425b34 ¤   ¤   {
--cc05 000072bc35a401102f4 Page 19 of SearchProc.c
3eefa2 ¤   ¤   ¤   *pKeySetOut = kPGPInvalidRef;
ce0fe4 ¤   ¤   }
0b1b52 ¤   ¤
52f5a4 ¤   ¤   EnterCriticalSection(keyserverLock);
7aaf5a
d283ca ¤   ¤   ComboBox_SetItemData(hwndLocation, lastSearchIndex, *pKeySetOut);
04af5a
f0c158 ¤   ¤   LeaveCriticalSection(keyserverLock);
079371 ¤   }
fbaf5a
83f0cc ¤   // perform search on specified keyserver
ac0e24 ¤   else
ddc7a1 ¤   {
706467 ¤   ¤   PGPtlsSessionRef tls = kInvalidPGPtlsSessionRef;
fca532 ¤   ¤   PGPKeyServerEntry* entry = NULL;
de1b52 ¤   ¤
4b683b ¤   ¤   *flags = FLAG_SEARCH_MEMORY;
9df187 ¤   ¤   SetProp( hwndLocation, "LastSearchType",(HANDLE) *flags);
1eaf5a
7924a9 ¤   ¤   // retrieve keyserver entry from control
c6825a ¤   ¤   entry = (PGPKeyServerEntry*)lParam;
9faf5a
94dd89 ¤   ¤   if( entry )
575b34 ¤   ¤   {
78bcb3 ¤   ¤   ¤   error = PGPNewKeyServerFromHostName(·
1d77b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,
7a1c6d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   entry->serverDNS,
878f46 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   entry->serverPort,
546020 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   entry->protocol,
463799 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   accessType,·
077b74 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (bPending ? kPGPKeyServerKeySpace_Pending :·
3dc845 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyServerKeySpace_Default),·
480725 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &psts->server );
40af5a
f98367 ¤   ¤   ¤   memcpy(&(psts->keyserverEntry),·
33c40d ¤   ¤   ¤   ¤   ¤   ¤   entry, sizeof(PGPKeyServerEntry));
170fe4 ¤   ¤   }
f70e1d ¤   ¤   else
3d5b34 ¤   ¤   {
9ebecd ¤   ¤   ¤   error = kPGPError_OutOfMemory;
040fe4 ¤   ¤   }
e3af5a
f5cb70 ¤   ¤   if( IsntPGPError( error ) )
535b34 ¤   ¤   {
a92b57 ¤   ¤   ¤   error = PGPSetKeyServerEventHandler( psts->server,·
3ce109 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SearchEventHandler, psts );
a3e294 ¤   ¤   ¤   if ( IsntPGPError( error ) )
4cf776 ¤   ¤   ¤   {
320fb0 ¤   ¤   ¤   ¤   if(¤kPGPKeyServerType_LDAPS == entry->protocol ||
c68e16 ¤   ¤   ¤   ¤   ¤   kPGPKeyServerType_HTTPS¤== entry->protocol)
7b72c3 ¤   ¤   ¤   ¤   {
12ed34 ¤   ¤   ¤   ¤   ¤   error = PGPNewTLSSession(¤  g_TLSContext,
400e59 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &tls );
4e5364 ¤   ¤   ¤   ¤   ¤   if( IsPGPError(error) )
384859 ¤   ¤   ¤   ¤   ¤   {
d7fb2c ¤   ¤   ¤   ¤   ¤   ¤   // warn beyond the icon?
87b22d ¤   ¤   ¤   ¤   ¤   ¤   tls = kInvalidPGPtlsSessionRef;
231c89 ¤   ¤   ¤   ¤   ¤   }
852613 ¤   ¤   ¤   ¤   }
2baf5a
efef2b ¤   ¤   ¤   ¤   error = PGPKeyServerOpen( psts->server, tls );
2baf5a
0e78c4 ¤   ¤   ¤   ¤   if ( IsntPGPError(error) )·
1f72c3 ¤   ¤   ¤   ¤   {
4e5a4c ¤   ¤   ¤   ¤   ¤   error = PGPQueryKeyServer(¤ psts->server,·
f83a2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->filter,·
4217ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pKeySetOut);
10af5a
2664bd ¤   ¤   ¤   ¤   ¤   PGPKeyServerClose ( psts->server );
992613 ¤   ¤   ¤   ¤   }
46a3a6 ¤   ¤   ¤   }
07af5a
--fe79 000aeb0b3b5401102f4 Page 20 of SearchProc.c
421a33 ¤   ¤   ¤   PGPFreeKeyServer( psts->server );
918b67 ¤   ¤   ¤   psts->server = kInvalidPGPKeyServerRef;
0eaf5a
71d6ec ¤   ¤   ¤   if( PGPtlsSessionRefIsValid(tls) )
b5f776 ¤   ¤   ¤   {
265675 ¤   ¤   ¤   ¤   PGPFreeTLSSession( tls );
f971c0 ¤   ¤   ¤   ¤   tls = kInvalidPGPtlsSessionRef;
a3a3a6 ¤   ¤   ¤   }
bcaf5a
33165e ¤   ¤   ¤   if( (IsntPGPError( error )) ||·
e58508 ¤   ¤   ¤   ¤   (error == kPGPError_ServerPartialSearchResults ))
a1f776 ¤   ¤   ¤   {
d1f422 ¤   ¤   ¤   ¤   EnterCriticalSection(keyserverLock);
c6af5a
e557c5 ¤   ¤   ¤   ¤   ComboBox_SetItemData(¤  hwndLocation,·
84f2f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lastSearchIndex,·
e6d1ba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *pKeySetOut);
f6af5a
eac0de ¤   ¤   ¤   ¤   LeaveCriticalSection(keyserverLock);
a4a3a6 ¤   ¤   ¤   }
28af5a
fd0fe4 ¤   ¤   }
579371 ¤   }
1f095b ¤   PGPKeyServerDisposeThreadStorage(previousStorage);
42af5a
72c1aa ¤   PGPKeyServerCleanup();
3caf5a
f2c674 ¤   return error;
4eefe6 }
3baf5a
ec39d4 DWORD WINAPI SearchThreadRoutine (LPVOID lpvoid)
d3bb36 {
075fb5 ¤   PSEARCHTHREADSTRUCT psts = (PSEARCHTHREADSTRUCT) lpvoid;
38dea7 ¤   SEARCHRESULT result;
45a82c ¤   PGPKeySetRef keySet = kPGPInvalidRef;
ffd206 ¤   HWND hwnd = psts->hwnd;
b4e8eb ¤   HWND hwndLocation = NULL;
4825f6 ¤   HWND hwndSearch = NULL;
efab83 ¤   HWND hwndStop = NULL;
2c0fc2 ¤   HWND hwndPending = NULL;
4b2ab5 ¤   long flags = 0;
2aab85 ¤   BOOL bPending = FALSE;
6a36a8 ¤   PGPError error = kPGPError_NoErr;
fa67c5 ¤
b86c1a ¤   hwndLocation = GetDlgItem(hwnd, IDC_LOCATION);
8a8abe ¤   hwndSearch = GetDlgItem(hwnd, IDC_SEARCH);
9199e3 ¤   hwndStop = GetDlgItem(hwnd, IDC_STOP);
0509f3 ¤   hwndPending = GetDlgItem(hwnd, IDC_PENDING);
6faf5a
6c017f ¤   bPending = Button_GetCheck(hwndPending);
26af5a
b1f874 ¤   error = PerformSearch(¤ hwndLocation,
7d59f3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts,
d8a3a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   bPending,
73d1fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   &flags,
6fec35 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &keySet);
94af5a
bcc90d ¤   memset(&result, 0x00, sizeof(result));
ccaf5a
2c4e29 ¤   if( IsntPGPError(error) ||
a47b80 ¤   ¤   (error == kPGPError_ServerPartialSearchResults))
cec7a1 ¤   {
388660 ¤   ¤   result.pData = keySet;
d30d86 ¤   ¤   result.flags = flags;
7c2c8f ¤   ¤   result.error = error;
7baf5a
f197aa ¤   ¤   memcpy(&(result.keyserver),·
6e3fc9 ¤   ¤   ¤   &(psts->keyserverEntry),·
0ee4be ¤   ¤   ¤   sizeof(PGPKeyServerEntry));
05af5a
1777f5 ¤   ¤   if(bPending)
ae5b34 ¤   ¤   {
--c66c 000ae1cb3a1401102f4 Page 21 of SearchProc.c
f645e9 ¤   ¤   ¤   result.flags |= FLAG_AREA_PENDING;
1d0fe4 ¤   ¤   }
db9371 ¤   }
584264 ¤   else·
4ec7a1 ¤   {
cd0c2f ¤   ¤   result.pData = NULL;
7e8ed3 ¤   ¤   result.flags = 0;
5b2c8f ¤   ¤   result.error = error;
5c9371 ¤   }
50af5a
a9dbaa ¤   result.nmhdr.hwndFrom = hwnd;
214663 ¤   result.nmhdr.idFrom = IDD_SEARCH;
111c66 ¤   result.nmhdr.code = SEARCH_DISPLAY_KEYSET;
6aaf5a
20492e ¤   SendMessage(GetParent(hwnd),·
13ee69 ¤   ¤   ¤   ¤   WM_NOTIFY,·
eb50c1 ¤   ¤   ¤   ¤   (WPARAM)hwnd,·
b007a7 ¤   ¤   ¤   ¤   (LPARAM)&result);
45af5a
47d989 ¤   if ( psts->filter )
b59ec5 ¤   ¤   PGPFreeFilter ( psts->filter );
c1af5a
71af5e ¤   memset(psts, 0x00, sizeof(SEARCHTHREADSTRUCT));
30af5a
aa58c7 ¤   EnableWindow(hwndStop, FALSE);
1d8db0 ¤   ShowWindow(hwndStop, SW_HIDE);
e53876 ¤   ShowWindow(hwndSearch, SW_SHOW);
5c83b7 ¤   EnableWindow(hwndSearch, TRUE);
38af5a
e83e6b ¤   return 0;
b3efe6 }
a7af5a
7ec509 //¤ ____________________________________
c1465d //
e14c36 // ·translate keyserver state to string index
96af5a
5611ec static INT
bbfa99 sTranslateKSMessage (INT iKSmessage)·
ffbb36 {
bd80ad ¤   switch (iKSmessage) {
543c13 ¤   case kPGPKeyServerState_Opening :
10e3d0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IDS_SEARCH_MESSAGE_CONNECTING;
e63c00 ¤   case kPGPKeyServerState_Querying:¤  ¤   ¤
257cb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IDS_SEARCH_MESSAGE_QUERYING;
ae5a82 ¤   case kPGPKeyServerState_ProcessingResults :
0c3f20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IDS_SEARCH_MESSAGE_PROCESSING;
47af62 ¤   case kPGPKeyServerState_Uploading :¤¤   ¤
40a5de ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IDS_SEARCH_MESSAGE_SENDING;
38f17e ¤   case kPGPKeyServerState_Deleting :¤ ¤   ¤
0c26c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IDS_SEARCH_MESSAGE_DELETING;
353d5a ¤   case kPGPKeyServerState_Disabling :¤¤   ¤
68759a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IDS_SEARCH_MESSAGE_DISABLING;
e04799 ¤   case kPGPKeyServerState_Closing¤:¤  ¤   ¤
a437fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   return IDS_SEARCH_MESSAGE_CLOSING;
31af5a
94bfad ¤   default :
dde898 //¤ case kPGPKeyServerState_TLSUnableToSecureConnection :
9664ce //¤ case kPGPKeyServerState_TLSConnectionSecured :
47dcac ¤   ¤   return IDS_SEARCH_MESSAGE_BASE;
fa9371 ¤   }
cbefe6 }
97af5a
13af5a
31663a PGPError SearchEventHandler(PGPContextRef context,
6d3f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPEvent *event,·
82bcc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUserValue userValue)
e3bb36 {
0e36a8 ¤   PGPError error = kPGPError_NoErr;
eb0510 ¤   PSEARCHTHREADSTRUCT psts;
deaf5a
cd5a25 ¤   psts = (PSEARCHTHREADSTRUCT) userValue;
aeaf5a
--904d 000163f6a70401102f4 Page 22 of SearchProc.c
1a45e9 ¤   switch(event->type)
34c7a1 ¤   {
f5104e ¤   ¤   case kPGPEvent_ErrorEvent:
d25b34 ¤   ¤   {
969318 ¤   ¤   ¤   PGPEventErrorData data = event->data.errorData;
caaf5a
ac324a ¤   ¤   ¤   if(data.error == kPGPError_UserAbort)
15f776 ¤   ¤   ¤   {
e18ff3 ¤   ¤   ¤   ¤   psts->bCancel = TRUE;
63f6e9 ¤   ¤   ¤   ¤   return kPGPError_NoErr;
91a3a6 ¤   ¤   ¤   }
f487c7 ¤   ¤   ¤
e4cdcb ¤   ¤   ¤   break;
df0fe4 ¤   ¤   }
47af5a
a3fe34 ¤   ¤   case kPGPEvent_KeyServerEvent:
c55b34 ¤   ¤   {
3a80cd ¤   ¤   ¤   PGPEventKeyServerData data = event->data.keyServerData;
dab170 ¤   ¤   ¤   SEARCHPROGRESS progress;
05fe5f ¤   ¤   ¤   int index;
b7af5a
f752af ¤   ¤   ¤   memset(&progress, 0x00, sizeof(progress));
40af5a
4bd40c ¤   ¤   ¤   progress.nmhdr.hwndFrom = psts->hwnd;
c4454e ¤   ¤   ¤   progress.nmhdr.idFrom = IDD_SEARCH;
01bedd ¤   ¤   ¤   progress.nmhdr.code = SEARCH_PROGRESS;
56c535 ¤   ¤   ¤   progress.step = SEARCH_PROGRESS_INFINITE; // data.soFar;//
136bbf ¤   ¤   ¤   progress.total = SEARCH_PROGRESS_INFINITE;// data.total;//
caaf5a
b6dc35 ¤   ¤   ¤   if(!psts->bCancel)
acf776 ¤   ¤   ¤   {
b73187 ¤   ¤   ¤   ¤   index = data.state;
aea3a6 ¤   ¤   ¤   }
2dbb8c ¤   ¤   ¤   else
68f776 ¤   ¤   ¤   {
cc7646 ¤   ¤   ¤   ¤   index = IDS_SEARCH_MESSAGE_CANCEL;
9ef6d7 ¤   ¤   ¤   ¤   progress.step = 0;
0f867e ¤   ¤   ¤   ¤   progress.total = 0;
f5a3a6 ¤   ¤   ¤   }
deaf5a
205574 ¤   ¤   ¤   index = sTranslateKSMessage (index);
1d4888 ¤   ¤   ¤   LoadString(¤g_hInst,
9bceed ¤   ¤   ¤   ¤   ¤   ¤   index,
dd7ca7 ¤   ¤   ¤   ¤   ¤   ¤   progress.message,
ce3819 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(progress.message));
ffaf5a
10af5a
1eca92 ¤   ¤   ¤   SendMessage(GetParent(psts->hwnd),·
4dc8cb ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
db429e ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)psts->hwnd,·
ae278b ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&progress);
ee87c7 ¤   ¤   ¤
a8cdcb ¤   ¤   ¤   break;
c20fe4 ¤   ¤   }
7b1b52 ¤   ¤
ff0ff6 ¤   ¤   case kPGPEvent_KeyServerTLSEvent:
5a5b34 ¤   ¤   {
716330 ¤   ¤   ¤   PGPEventKeyServerTLSData data = event->data.keyServerTLSData;
57af5a
f3f41e ¤   ¤   ¤   SEARCHSECURE secure;
3f87c7 ¤   ¤   ¤
280e3f ¤   ¤   ¤   memset(&secure, 0x00, sizeof(secure));
b6af5a
c25cb1 ¤   ¤   ¤   secure.nmhdr.hwndFrom = psts->hwnd;
a09cad ¤   ¤   ¤   secure.nmhdr.idFrom = IDD_SEARCH;
71999a ¤   ¤   ¤   secure.nmhdr.code = SEARCH_SECURE_STATUS;
195a49 ¤   ¤   ¤   secure.secure = FALSE;
47af5a
45c9a9 ¤   ¤   ¤   if(data.state == kPGPKeyServerState_TLSConnectionSecured)
c5f776 ¤   ¤   ¤   {
162b85 ¤   ¤   ¤   ¤
16becc ¤   ¤   ¤   ¤   PGPtlsSessionRef¤   tls =·
--9ddb 000b66191c6401102f4 Page 23 of SearchProc.c
50111d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   event->data.keyServerTLSData.tlsSession;
acaf5a
1264b1 ¤   ¤   ¤   ¤   PGPInt32¤   ¤   ¤   remoteKeyAlg;
4e7259 ¤   ¤   ¤   ¤   PGPKeyID¤   ¤   ¤   keyID,
516f33 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   expectedID;
1843c8 ¤   ¤   ¤   ¤   PGPError¤   ¤   ¤   error;
4667c5 ¤
eb14ac ¤   ¤   ¤   ¤   error =·
bd6f57 ¤   ¤   ¤   ¤   ¤   PGPtlsGetRemoteAuthenticatedKey( tls, &secure.keyAuth );
18b7df ¤   ¤   ¤   ¤   if( IsPGPError( error ) )
7c14c3 ¤   ¤   ¤   ¤   ¤   break;
27af5a
d9c5c0 ¤   ¤   ¤   ¤   PGPGetKeyServerURL(&(psts->keyserverEntry),·
41f998 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.szServerName);
392b85 ¤   ¤   ¤   ¤
4370fd ¤   ¤   ¤   ¤   error = PGPGetKeyIDFromKey( secure.keyAuth, &keyID );
4bb7df ¤   ¤   ¤   ¤   if( IsPGPError( error ) )
0e14c3 ¤   ¤   ¤   ¤   ¤   break;
77af5a
a18b59 ¤   ¤   ¤   ¤   error = PGPGetKeyNumber( secure.keyAuth, kPGPKeyPropAlgID,
e236a8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &remoteKeyAlg );
30b7df ¤   ¤   ¤   ¤   if( IsPGPError( error ) )
e214c3 ¤   ¤   ¤   ¤   ¤   break;
04af5a
0a306c ¤   ¤   ¤   ¤   // check if we already have an auth key from this server
a54df9 ¤   ¤   ¤   ¤   if( psts->keyserverEntry.authAlg !=
b05d20 ¤   ¤   ¤   ¤   ¤   kPGPPublicKeyAlgorithm_Invalid )
dd72c3 ¤   ¤   ¤   ¤   {
a2e8c1 ¤   ¤   ¤   ¤   ¤   error = PGPGetKeyIDFromString(
9c0cad ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keyserverEntry.authKeyIDString,
6efecf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &expectedID );
58af5a
558e1a ¤   ¤   ¤   ¤   ¤   if( IsPGPError( error ) )
b500eb ¤   ¤   ¤   ¤   ¤   ¤   break;
53af5a
38753f ¤   ¤   ¤   ¤   ¤   if( PGPCompareKeyIDs( &expectedID, &keyID ) )
124859 ¤   ¤   ¤   ¤   ¤   {
269b1a ¤   ¤   ¤   ¤   ¤   ¤   error = PGPclConfirmRemoteAuthentication (
3b2887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,
90fb52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->hwnd,
a739a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.szServerName,
4b7f87 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.keyAuth,
9a410b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keySet,
015984 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHUNEXPECTEDKEY);
620c94 ¤   ¤   ¤   ¤   ¤   ¤   // if user approve
353e29 ¤   ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(error))
748fec ¤   ¤   ¤   ¤   ¤   ¤   {
3f90e9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   NMHDR nmhdr;
ffaf5a
88aada ¤   ¤   ¤   ¤   ¤   ¤   ¤   error = PGPGetKeyIDString( &keyID,·
82c846 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyIDString_Full,
0d48d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keyserverEntry.authKeyIDString );
64af5a
906f25 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if( IsPGPError( error ) )
dfcd67 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
03af5a
5c69d5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keyserverEntry.authAlg =
169b16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPPublicKeyAlgorithm) remoteKeyAlg;
02af5a
6cb7cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPclSyncKeyserverPrefs(g_Context,
1399f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(psts->keyserverEntry));
76af5a
0de98e ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.secure = TRUE;
c6af5a
ac4025 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.hwndFrom = psts->hwnd;
e5f7bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.idFrom = IDD_SEARCH;
d268f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.code = REFRESH_KEYSERVER_LIST;
21af5a
3c6e94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(psts->hwnd,·
e685f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
d84318 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)psts->hwnd,·
b60aee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&nmhdr);
--6a09 000c89426e9401102f4 Page 24 of SearchProc.c
0ddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
fc1c89 ¤   ¤   ¤   ¤   ¤   }
dd4bd6 ¤   ¤   ¤   ¤   ¤   else
d64859 ¤   ¤   ¤   ¤   ¤   {
869b1a ¤   ¤   ¤   ¤   ¤   ¤   error = PGPclConfirmRemoteAuthentication (
852887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,
d8fb52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->hwnd,
e239a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.szServerName,
e87f87 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.keyAuth,
e2410b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keySet,
5a6f60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHEXPECTEDKEY);
ae0c94 ¤   ¤   ¤   ¤   ¤   ¤   // if user approve
fa3e29 ¤   ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(error))
ae8fec ¤   ¤   ¤   ¤   ¤   ¤   {
f2e98e ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.secure = TRUE;
70db3c ¤   ¤   ¤   ¤   ¤   ¤   }
b61c89 ¤   ¤   ¤   ¤   ¤   }
2f2613 ¤   ¤   ¤   ¤   }
ddfc71 ¤   ¤   ¤   ¤   // this is the first time we're talking to this server
95fa07 ¤   ¤   ¤   ¤   else
bb72c3 ¤   ¤   ¤   ¤   {
02ae30 ¤   ¤   ¤   ¤   ¤
2016e6 ¤   ¤   ¤   ¤   ¤   error = PGPclConfirmRemoteAuthentication (
ed2fbc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   g_Context,
3e7405 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->hwnd,
74b3e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.szServerName,
69bb9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   secure.keyAuth,
43a30b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keySet,
33a0a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_AUTHNEWKEY);
f402d8 ¤   ¤   ¤   ¤   ¤   // if user approve
ad2679 ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(error))
fa4859 ¤   ¤   ¤   ¤   ¤   {
e29504 ¤   ¤   ¤   ¤   ¤   ¤   NMHDR nmhdr;
13af5a
646ec6 ¤   ¤   ¤   ¤   ¤   ¤   error = PGPGetKeyIDString( &keyID,·
09c846 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyIDString_Full,
6a48d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   psts->keyserverEntry.authKeyIDString );
5faf5a
c9c124 ¤   ¤   ¤   ¤   ¤   ¤   if( IsPGPError( error ) )
208c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
0daf5a
e36eee ¤   ¤   ¤   ¤   ¤   ¤   psts->keyserverEntry.authAlg =
078e35 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (PGPPublicKeyAlgorithm) remoteKeyAlg;
8daf5a
fdaf5a
dfb72d ¤   ¤   ¤   ¤   ¤   ¤   PGPclSyncKeyserverPrefs(g_Context,
d899f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &(psts->keyserverEntry));
f4af5a
95a6b0 ¤   ¤   ¤   ¤   ¤   ¤   secure.secure = TRUE;
5eaf5a
742f16 ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.hwndFrom = psts->hwnd;
22e69c ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.idFrom = IDD_SEARCH;
a6b2de ¤   ¤   ¤   ¤   ¤   ¤   nmhdr.code = REFRESH_KEYSERVER_LIST;
86af5a
923d8f ¤   ¤   ¤   ¤   ¤   ¤   SendMessage(psts->hwnd,·
980d9e ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
4e1003 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)psts->hwnd,·
fd5873 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&nmhdr);
571c89 ¤   ¤   ¤   ¤   ¤   }
332613 ¤   ¤   ¤   ¤   }
91af5a
50d364 ¤   ¤   ¤   ¤   if (secure.secure != TRUE)·
a472c3 ¤   ¤   ¤   ¤   {
feac24 ¤   ¤   ¤   ¤   ¤   SEARCHABORT abort;
8daf5a
a6b31d ¤   ¤   ¤   ¤   ¤   psts->bCancel = TRUE;
7daf5a
29e894 ¤   ¤   ¤   ¤   ¤   memset(&abort, 0x00, sizeof(abort));
8daf5a
cf311c ¤   ¤   ¤   ¤   ¤   abort.nmhdr.hwndFrom = psts->hwnd;
06f7a0 ¤   ¤   ¤   ¤   ¤   abort.nmhdr.idFrom = IDD_SEARCH;
c846fc ¤   ¤   ¤   ¤   ¤   abort.nmhdr.code = SEARCH_ABORT;
--e4b5 0005784b038401102f4 Page 25 of SearchProc.c
addf01 ¤   ¤   ¤   ¤   ¤   abort.error = kPGPError_UserAbort;
5eaf5a
54097f ¤   ¤   ¤   ¤   ¤   SendMessage(GetParent(psts->hwnd),·
a40d9e ¤   ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
f91003 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)psts->hwnd,·
6028a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&abort);
3e2613 ¤   ¤   ¤   ¤   }
77af5a
b3a3a6 ¤   ¤   ¤   }
7bfefb ¤   ¤   ¤   else if(data.state ==·
3af40e ¤   ¤   ¤   ¤   ¤   ¤   kPGPKeyServerState_TLSUnableToSecureConnection)
0cf776 ¤   ¤   ¤   {
061bba ¤   ¤   ¤   ¤   secure.secure = FALSE;
98a3a6 ¤   ¤   ¤   }
33af5a
61ca92 ¤   ¤   ¤   SendMessage(GetParent(psts->hwnd),·
21c8cb ¤   ¤   ¤   ¤   ¤   ¤   WM_NOTIFY,·
9a429e ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM)psts->hwnd,·
9326ec ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&secure);
a22b85 ¤   ¤   ¤   ¤
f0cdcb ¤   ¤   ¤   break;
980fe4 ¤   ¤   }
3faf5a
4f1fbb ¤   ¤   case kPGPEvent_FinalEvent:
8e5b34 ¤   ¤   {
6d22bb ¤   ¤   ¤   psts->bAlreadyAsked = FALSE;
9ccdcb ¤   ¤   ¤   break;
f80fe4 ¤   ¤   }
d09371 ¤   }
4faf5a
6eaf5a
6517d9 ¤   if( psts->bCancel )
78c7a1 ¤   {
89c3d8 ¤   ¤   error = kPGPError_UserAbort;
8d9371 ¤   }
3eaf5a
10c674 ¤   return error;
4eefe6 }
97af5a
497395 void GrabUserIdStrings(HWND hwnd,·
a66155 ¤   ¤   ¤   ¤   ¤   ···char** string,
f022fe ¤   ¤   ¤   ¤   ¤   ···int* length)
b3bb36 {
216e40 ¤   PCHOICE¤choice¤ ¤   ¤   ¤   = NULL;
7ce8b6 ¤   HWND¤   hwndEdit¤   ¤   ¤   = NULL;
cc2376 ¤   HWND¤   hwndAttribute¤  ¤   = NULL;
3c52ba ¤   int¤¤   AttributeSelection¤ = 0;
d179db ¤   int¤¤   userIdSelection¤¤   = 0;
34af5a
c6a81f ¤   *string = NULL;
29c829 ¤   *length = 0;
f0af5a
c8af71 ¤   hwndAttribute¤  = GetDlgItem(hwnd, IDC_ATTRIBUTE);
7f423d ¤   hwndEdit¤   ¤   = GetDlgItem(hwnd, IDC_SPECIFIER_EDIT);
5caf5a
fa0a86 ¤   AttributeSelection¤ = ComboBox_GetCurSel(hwndAttribute);
f8af5a
dc6b13 ¤   if(AttributeSelection == 0) // User Id
7bc7a1 ¤   {
2071f9 ¤   ¤   *length = Edit_GetTextLength(hwndEdit) + 1;
36af5a
dcb5b1 ¤   ¤   *string = (char*)malloc(*length);
f2af5a
1d29b2 ¤   ¤   if( *string )
655b34 ¤   ¤   {
484a8f ¤   ¤   ¤   Edit_GetText(¤  hwndEdit,·
444a14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   *string,·
f0925e ¤   ¤   ¤   ¤   ¤   ¤   ¤   *length);
1a0fe4 ¤   ¤   }
689371 ¤   }
b8af5a
576f6e ¤   // now iterate the children if there are any
--0563 0010244862c401102f4 Page 26 of SearchProc.c
666a5e ¤   choice = FirstChoice(hwnd);
abaf5a
307f65 ¤   while( choice )
933a9a ¤   {¤  ¤   ¤   ¤   ¤   ¤   ¤
c78af8 ¤   ¤   hwndAttribute¤  = GetDlgItem(choice->hwnd, IDC_ATTRIBUTE);
5c2330 ¤   ¤   hwndEdit¤   ¤   = GetDlgItem(choice->hwnd, IDC_SPECIFIER_EDIT);
60af5a
b6d0af ¤   ¤   AttributeSelection¤ = ComboBox_GetCurSel(hwndAttribute);
fcaf5a
e3fa8b ¤   ¤   if(AttributeSelection == 0) // User Id
7c5b34 ¤   ¤   {
b7bcf4 ¤   ¤   ¤   int tempLength = 0;
39af5a
752b48 ¤   ¤   ¤   tempLength = *length + Edit_GetTextLength(hwndEdit) + 1;
59af5a
47013b ¤   ¤   ¤   if(!(*string))
07f776 ¤   ¤   ¤   {
7e72c7 ¤   ¤   ¤   ¤   *string = (char*)malloc(tempLength);
66a3a6 ¤   ¤   ¤   }
2ebb8c ¤   ¤   ¤   else
09f776 ¤   ¤   ¤   {
351fd5 ¤   ¤   ¤   ¤   *string = (char*)realloc(*string, tempLength);
58a3a6 ¤   ¤   ¤   }
61af5a
96ee07 ¤   ¤   ¤   if( *string )
3ef776 ¤   ¤   ¤   {
97dd38 ¤   ¤   ¤   ¤   if(*length)
ba72c3 ¤   ¤   ¤   ¤   {
0ad327 ¤   ¤   ¤   ¤   ¤   *(*string + *length - 1) = 0x20; // add space
112613 ¤   ¤   ¤   ¤   }
caaf5a
ba44c3 ¤   ¤   ¤   ¤   Edit_GetText(¤  hwndEdit,·
6d87f8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *string + *length,·
0d58a4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tempLength);
c8af5a
c9544f ¤   ¤   ¤   ¤   *length = tempLength;
01a3a6 ¤   ¤   ¤   }
1f0fe4 ¤   ¤   }
bfaf5a
94be2d ¤   ¤   choice = NextChoice(hwnd, choice);
e39371 ¤   }
29efe6 }
02af5a
--c908 0018f6adf07401102f5 Page 1 of SearchProc.h
a70335 /*____________________________________________________________________________
a99e23 ¤   Copyright (C) 1998 Network Associates, Inc.
e74b0f ¤   All rights reserved.
3d67c5 ¤
ca9460 ¤   $Id: SearchProc.h,v 1.2 1998/08/11 15:20:21 pbj Exp $
dbf7f7 ____________________________________________________________________________*/
805b94 #ifndef _SEARCHPROC_H
f20791 #define _SEARCHPROC_H
69af5a
70af5a
0d112b // the message handler for the search control
db7efe BOOL·
61a2f4 CALLBACK·
39811c SearchProc(¤HWND hwnd,·
e26753 ¤   ¤   ¤   UINT msg,·
74a552 ¤   ¤   ¤   WPARAM wParam,·
ff08de ¤   ¤   ¤   LPARAM lParam );
8f2841 #endif¶
--b659 000754e1dd6401102f6 Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
18a770 // Used by PGPkeys.rc
89465d //
6cad33 #define IDS_GENERAL ····················1
05ee39 #define IDS_PASSPHRASEMISMATCH ·········2
23f678 #define IDS_CAPTION ····················3
8d650a #define IDC_YESTOALL ···················3
bb5f02 #define IDS_CAPTIONKEYGEN ··············4
22574f #define IDS_BADPASSPHRASE ··············5
ea5a58 #define IDS_INVALIDNUMBITS ·············6
1c7700 #define IDS_SUCCESSKEYGEN ··············7
b70402 #define IDS_DEFAULTUID ·················8
053232 #define IDS_GROUPIMPORTCAPTION ·········9
c03971 #define IDS_EXPORTCAPTION ··············10
84e1f4 #define IDS_DELCONFCAPTION ·············11
50ba7f #define IDS_DELCONFPRIVKEY ·············12
56cb1e #define IDS_DELCONFPUBKEY ··············13
c67ec1 #define IDS_DELCONFKEY ·················13
569f6f #define IDS_DELCONFUSERID ··············14
5af0b1 #define IDS_DELCONFCERT ················15
8e25db #define IDS_MEMALLOCFAIL ···············16
68a759 #define IDS_KEYRINGFILTER ··············17
a5a3c8 #define IDS_PRIVKEYCAPTION ·············18
7c88aa #define IDS_PUBKEYCAPTION ··············19
f08b5d #define IDS_PROPCAPTION ················20
cc21fd #define IDS_KEYCOLTITLE ················21
4e85ed #define IDS_VALCOLTITLE ················22
4491a8 #define IDS_TRUSTCOLTITLE ··············23
25fa09 #define IDS_DATECOLTITLE ···············24
815788 #define IDS_BITSCOLTITLE ···············25
97ec21 #define IDS_VERSION ····················26
ea6312 #define IDS_PGPKEYSVERSION ·············26
4eb2a7 #define IDS_BACKUPCAPTION ··············27
8c3062 #define IDS_BACKUPDEFAULTFILE ··········28
418b0c #define IDS_BACKUPDEFAULTDIR ···········29
4c3c81 #define IDS_REGISTRYKEY ················30
ed564a #define IDS_CERTMESSAGE ················31
b285ba #define IDS_OUTOFMEMORY ················32
ded6a2 #define IDS_GENERICERROR ···············33
90b6c1 #define IDS_CAPTIONERROR ···············34
9430f1 #define IDS_CONFIRMSETDEFAULT ··········35
5a8eed #define IDS_VALIDITY0 ··················36
151efc #define IDS_VALIDITY1 ··················37
270f7e #define IDS_VALIDITY2 ··················38
159f6f #define IDS_VALIDITY3 ··················39
a1d967 #define IDS_WRONGPASSPHRASE ············40
d35149 #define IDS_DELCONFDEFKEY ··············41
09a609 #define IDS_KEYGENPHASE1 ···············42
10d63a #define IDS_KEYGENPHASE2 ···············43
7e0447 #define IDS_DROPFILENAME ···············44
2c1303 #define IDS_NODEFAULTKEY ···············45
269a37 #define IDS_CERTKEYNOTONRING ···········46
eb357b #define IDS_NOIMPORTKEYS ···············47
943808 #define IDS_NOIMPORTKEYSPASTE ··········48
10c467 #define IDS_CANNOTOPENRINGS ············49
b84243 #define IDS_DELONLYUSERID ··············50
8977d9 #define IDS_BACKUPERROR ················51
7de2c0 #define IDS_IMPORTEDSECRETKEYS ·········52
900039 #define IDS_TRUST0 ·····················54
bbd4b1 #define IDS_TRUST1 ·····················55
aaa138 #define IDS_TRUST2 ·····················56
f575b0 #define IDS_TRUST3 ·····················57
8184ea #define IDS_TRUST4 ·····················58
a25062 #define IDS_TRUST5 ·····················59
f326eb #define IDS_DEFKEYPASSPHRASE ···········60
2b75a7 #define IDS_SIGNKEYPASSPHRASE ··········60
994c9d #define IDS_SELKEYPASSPHRASE ···········61
27a6bd #define IDS_IMPORTFILTER ···············63
570c96 #define IDS_GROUPIMPORTFILTER ··········63
9a4e78 #define IDS_COLLAPSEALL ················64
754ec0 #define IDS_EXPANDALL ··················65
--1168 000c36052d4401102f6 Page 2 of resource.h
3771b3 #define IDS_COLLAPSESEL ················66
dea370 #define IDS_EXPANDSEL ··················67
26f3f3 #define IDS_HELPFILENAME ···············68
759ce5 #define IDS_PROPTITLE0 ·················69
d7970e #define IDS_RSA ························70
3c0a4a #define IDS_DSA_ELGAMAL ················71
4b5d68 #define IDS_UNKNOWN ····················72
17bc67 #define IDS_NEVER ······················73
be1fdd #define IDS_KEYGENERATION ··············74
b77516 #define IDS_SUBKEYGENERATION ···········75
f4608d #define IDS_MULTCERTMESSAGE2 ···········76
7be374 #define IDS_MULTCERTMESSAGE1 ···········77
309a26 #define IDS_NODRAGTEXTKEYS ·············78
8987dd #define IDS_SETKEYAXIOMATIC ············79
779175 #define IDS_DEFKEYRINGEXTENSION ········80
59e2ce #define IDS_DEFEXPORTEXTENSION ·········81
0c71d1 #define IDS_CORRUPTKEYRING ·············84
62e4ee #define IDS_PGPMAILKEY ·················85
0b07dd #define IDS_ERRONEOUSADK ···············86
f7d75c #define IDS_NOSPLASHSWITCH ·············87
6976ce #define IDS_NOUSERNAME ·················88
e75341 #define IDS_REVOKECONFIRM ··············89
f3f9fc #define IDS_TRUSTONINVALIDKEY ··········90
ad0fdb #define IDS_CERTIFYERROR ···············91
65fd1d #define IDS_NONSTANDARDNAME ············92
f6c0f3 #define IDS_REVCONFDEFKEY ··············93
435c97 #define IDS_UNAVAILABLECERT ············94
46f889 #define IDS_NOUSERADDR ·················95
20ed66 #define IDS_LOCKEDKEYRING ··············97
823d02 #define IDS_EMPTY ······················99
57a01d #define IDD_PUBMAIL ····················102
298559 #define IDD_KEYMAN ·····················102
e13d93 #define IDR_MENUCONTEXT ················103
7b6ac0 #define IDR_MENUPRIVKEY ················103
47c8ce #define IDR_MENUKEY ····················103
c97cb8 #define IDR_MENUPUBKEY ·················104
1b7ee2 #define IDB_RSAPRIVKEY ·················104
a1a709 #define IDB_RSASEC ·····················104
2b0b17 #define IDB_CERT ·······················105
bf2598 #define IDR_MENUUID ····················105
dfe83e #define IDR_MENUCERT ···················106
cbae55 #define IDB_RSAPRIVKEYMSK ··············106
d5255d #define IDB_RSASECMSK ··················106
6b125c #define IDB_CERTMSK ····················107
92a49e #define IDB_RSAPUBKEY ··················108
92de8f #define IDB_RSAPUB ·····················108
d4c91a #define IDB_RSAPUBKEYMSK ···············109
2e76b3 #define IDB_RSAPUBMSK ··················109
bd3f4c #define IDB_UID ························110
e06fe2 #define IDB_UIDMSK ·····················111
74506c #define IDR_MENUKEYMAN ·················112
a57d11 #define IDR_MENUDISKEY ·················113
4bd6ea #define IDD_PROP1 ······················114
af2623 #define IDR_MENUREVKEY ·················114
ab012c #define IDD_PROP0 ······················115
719129 #define IDR_MENUNONE ···················115
064840 #define IDD_KEYPROP ····················116
f9cccb #define IDR_MENUEXPKEY ·················116
60d5fe #define IDB_RSADISKEY ··················117
ee1b40 #define IDB_RSAPUBDIS ··················117
d7226a #define IDB_RSADISKEYMSK ···············118
71ecd4 #define IDB_RSAPUBDISMSK ···············118
14d121 #define IDB_RSAREVKEY ··················119
e9872f #define IDB_RSAPUBREV ··················119
8a9d01 #define IDB_RSAREVKEYMSK ···············120
07cb0f #define IDB_RSAPUBREVMSK ···············120
2f2e91 #define IDB_RSAEXPKEY ··················121
6cc3a3 #define IDB_RSAPUBEXP ··················121
0c70a5 #define IDB_RSAEXPKEYMSK ···············122
7d9d97 #define IDB_RSAPUBEXPMSK ···············122
c1e141 #define IDB_REVCERT ····················123
c3e3bd #define IDB_REVCERTMSK ·················124
--60b2 0003249d70a401102f6 Page 3 of resource.h
112bca #define IDD_CHANGEPHRASE ···············125
e09e56 #define IDD_BACKUPWARN ·················126
aaa47d #define IDD_BADPHRASE ··················127
ac7c50 #define IDR_KEYMANACCEL ················128
b39fcc #define IDD_PASSPHRASE ·················129
a442b3 #define IDD_KEYRAND ····················130
5f177d #define IDI_EXEICON ····················133
ee931a #define IDI_ICON1 ······················134
8cae6a #define IDC_ICON1 ······················134
2d144b #define IDD_WORKING ····················134
10d0f1 #define IDI_ICON2 ······················135
90ed81 #define IDC_ICON2 ······················135
7b3487 #define IDI_ICON3 ······················136
d709f7 #define IDC_ICON3 ······················136
c05727 #define IDI_ICON4 ······················137
916a57 #define IDC_ICON4 ······················137
24bc8a #define IDD_KEYGEN ·····················138
b71af1 #define IDI_ICON5 ······················138
612781 #define IDC_ICON5 ······················138
e2591a #define IDI_ICON6 ······················139
d0646a #define IDC_ICON6 ······················139
b7a0ac #define IDD_LOADING ····················139
6fcc19 #define IDI_ICON7 ······················140
61f169 #define IDC_ICON7 ······················140
13ef2f #define IDI_ICON8 ······················141
84d25f #define IDC_ICON8 ······················141
68715e #define IDB_BITMAP6 ····················142
9a642c #define IDB_BADCERTMSK ·················143
17a416 #define IDD_NEWUSERID ··················144
e866d0 #define IDB_BADCERT ····················144
b42588 #define IDD_DELETEALL ··················145
6f28e5 #define IDB_DSAPUBKEY ··················146
4e52f4 #define IDB_DSAPUB ·····················146
674561 #define IDB_DSAPUBKEYMSK ···············147
95fac8 #define IDB_DSAPUBMSK ··················147
cc222e #define IDB_DSAPRIVKEYMSK ··············148
53a926 #define IDB_DSASECMSK ··················148
67d8f1 #define IDB_DSAPRIVKEY ·················149
45011a #define IDB_DSASEC ·····················149
4afaae #define IDB_LOGO ·······················154
e9c98d #define IDB_LOGOMSK ····················155
4b8db8 #define IDR_CLOCKAVI ···················162
230699 #define IDB_DSADISKEY ··················164
b5c827 #define IDB_DSAPUBDIS ··················164
176b1d #define IDB_DSADISKEYMSK ···············165
fca5a3 #define IDB_DSAPUBDISMSK ···············165
b5abe6 #define IDB_DSAREVKEY ··················166
7efde8 #define IDB_DSAPUBREV ··················166
9ac662 #define IDB_DSAREVKEYMSK ···············167
3d906c #define IDB_DSAPUBREVMSK ···············167
3eb1a1 #define IDB_DSASECDIS ··················168
4cdc25 #define IDB_DSASECDISMSK ···············169
4450b7 #define IDB_RSASECDIS ··················170
603d33 #define IDB_RSASECDISMSK ···············171
ad6578 #define IDB_RSASECREV ··················172
9e08fc #define IDB_RSASECREVMSK ···············173
125480 #define IDB_RSASECEXP ··················174
ef3904 #define IDB_RSASECEXPMSK ···············175
2e123a #define IDB_DSASECEXP ··················176
f87fbe #define IDB_DSASECEXPMSK ···············177
61ed02 #define IDB_DSASECREV ··················178
6d8086 #define IDB_DSASECREVMSK ···············179
fbdc0b #define IDB_DSAPUBEXP ··················180
2eb18f #define IDB_DSAPUBEXPMSK ···············181
a7da26 #define IDD_KEYPROPADK ·················182
a6a51b #define IDD_READONLY ···················183
efb07b #define IDB_RSAUID ·····················184
860177 #define IDD_SIGNCONFIRM ················184
7adca9 #define IDB_DSAUID ·····················185
0493a3 #define IDD_KEYWIZ_SIGN_OLD ············186
eb5037 #define IDC_CHECK_SIGN_KEY ·············187
32a4b4 #define IDB_KEYWIZ8 ····················187
--306c 0008e3134b3401102f6 Page 4 of resource.h
8850e9 #define IDB_KEYWIZ4 ····················188
46a912 #define IDB_KEYWIZ1 ····················189
642c3d #define IDR_MENUPROMISCUOUS ············190
664e3e #define IDB_UNCHECK ····················192
3f1812 #define IDB_UNCHECKMSK ·················193
ce6ebb #define IDB_CHECK ······················194
efd6f8 #define IDB_CHECKMSK ···················195
c4b5f3 #define IDB_PUSHMSK ····················196
ab86d0 #define IDB_PUSH ·······················197
5102a6 #define IDB_PUSHED ·····················198
a0aa9a #define IDB_PUSHEDMSK ··················199
995d94 #define IDD_KEYWIZ_BADPHRASE ···········200
c040a5 #define IDD_KEYWIZ_ADK ·················201
a6964e #define IDD_KEYWIZ_CORPCERT ············202
e5e0ee #define IDR_MENUKEYSEARCH ··············203
0265ec #define IDR_MENUKEYSEARCHSERVER ········203
d75322 #define IDR_MENUKEYSEARCHLOCAL ·········204
2d0a25 #define IDB_IMAGES4BIT ·················207
cba06f #define IDB_IMAGES24BIT ················208
6b258d #define IDD_NEWGROUP ···················209
171c38 #define IDR_MENUGROUP ··················213
2d2345 #define IDR_MENUGROUPKEY ···············214
500b6b #define IDI_OPENLOCK ···················220
367898 #define IDI_CLOSEDLOCK ·················221
ce7531 #define IDB_TOOLBAR4BIT ················223
4ef891 #define IDB_TOOLBAR24BIT ···············224
88214b #define IDD_KEYWIZ_REVOKER ·············225
a2f4c4 #define IDR_DIALOGACCEL ················226
6e366d #define IDI_CLOSELOCK ··················228
5dfc93 #define IDC_TREELIST ···················401
6e1448 #define IDC_TREELISTGROUP ··············402
b7c0ca #define IDC_TEXT ·······················1000
876561 #define IDC_NAME ·······················1000
f0db06 #define IDC_RANDOMTEXT ·················1000
456c16 #define IDC_NUMBER ·····················1001
9f719f #define IDC_SETPRIVATEKEYRING ··········1001
b49bf0 #define IDC_SETPUBLICKEYRING ···········1002
e02af4 #define IDC_PGPBITSIZE ·················1003
dc683a #define IDC_PRIVATEKEYRING ·············1005
cf04fd #define IDC_PUBLICKEYRING ··············1006
5c49e9 #define IDC_KEYTYPECOMBO ···············1006
bf8dbc #define IDC_KEYSIZECOMBO ···············1007
2c6db4 #define IDC_NEVEREXPIRES ···············1008
c38306 #define IDC_EXPIRES ····················1009
1b4307 #define IDC_EXPIRESDAYS ················1010
7b7818 #define IDC_FINGERPRINT ················1013
368820 #define IDC_TRUSTSLIDER ················1014
0c81d4 #define IDC_VALIDITYBAR ················1015
b3d23f #define IDC_BITSPROGBAR ················1015
f41094 #define IDC_ENABLED ····················1016
78b945 #define IDC_CHANGEPHRASE ···············1017
7d923a #define IDC_USERID ·····················1017
8998f7 #define IDC_KEYID ······················1018
9c1b70 #define IDC_PHRASE1 ····················1018
7ea389 #define IDC_NEWUSERNAME ················1018
d7de29 #define IDC_NEWGROUPNAME ···············1018
2f106a #define IDC_CERTDEPTH ··················1019
eef470 #define IDC_PHRASE2 ····················1019
3617d2 #define IDC_KEYTYPE ····················1019
49afeb #define IDC_CREATEDATE ·················1020
0b1f98 #define IDC_USERADDR ···················1020
742dee #define IDC_OLDPHRASE ··················1021
d669dd #define IDC_VALIDITY ···················1021
c1510b #define IDC_HIDETYPING ·················1022
27db4a #define IDC_TRUST ······················1022
738331 #define IDC_ENCRYPTTOSELF ··············1023
d8a080 #define IDC_ADKAGENT ···················1023
b9e7c5 #define IDC_COMPRESS ···················1024
804b26 #define IDC_NUMCOMPLETE ················1025
e0d18b #define IDC_NUMMARGINAL ················1026
9099dd #define IDC_NEWPHRASE ··················1027
8ef77e #define IDC_NEWPHRASE1 ·················1027
--5c64 00035ea2e50401102f6 Page 5 of resource.h
dc997a #define IDC_NEWPHRASE2 ·················1028
8cf23a #define IDC_PHRASE ·····················1029
07f08d #define IDC_BITSREMAIN ·················1031
8fa60a #define IDC_PHASE ······················1032
4f35a4 #define IDC_KEYSTRING ··················1034
ffdffe #define IDC_PROMPTSTRING ···············1035
f4ccdc #define IDC_PASSPHRASE ·················1037
e24ecc #define IDC_STRING ·····················1037
2510e3 #define IDC_PASSPHRASE2 ················1038
f8f279 #define IDC_BACKUPNOW ··················1038
d9052c #define IDC_USEBADPHRASE ···············1039
614ed8 #define IDC_EXPIREDATE ·················1040
9d7d3f #define IDC_AXIOMATIC ··················1041
89512f #define IDC_WORKINGAVI ·················1043
256e63 #define IDC_NEWEMAILADDR ···············1045
0b68af #define IDC_NEWGROUPDESC ···············1045
9f5844 #define IDC_WARNNOMORE ·················1046
a65a91 #define IDC_STATIC_KMI ·················1050
e9252e #define IDC_PROGRESS_TEXT ··············1051
b636d6 #define IDC_STATIC_KMI2 ················1052
8dce14 #define IDC_CHECK_NO_SEND ··············1053
ce360d #define IDC_SENDSIG ····················1054
0f0ea7 #define IDC_CHECK_SEND ·················1055
a5b346 #define IDC_DUMMYSTOP ··················1055
56a73b #define IDC_STATIC_KS_TEXT ·············1056
bcd246 #define IDC_FREEWARETEXT ···············1056
b1ccdf #define IDC_NORSAGENTEXT ···············1056
bede1a #define IDC_STATIC_SMALL_GUIDE ·········1057
dcbf9c #define IDC_STOP ·······················1057
86e03c #define IDC_WIZBITMAP ··················1058
7d32a9 #define IDC_EXPIREDAY ··················1059
ca4bb3 #define IDC_EXPIREMONTH ················1060
a514fa #define IDC_EXPIREYEAR ·················1061
b61818 #define IDC_BADLENGTH ··················1062
da99be #define IDC_BADQUALITY ·················1063
b19633 #define IDC_BADCONFIRM ·················1064
da830d #define IDC_ADK ························1066
1f23c5 #define IDC_CORPCERTKEY ················1067
0d383a #define IDC_REJECTTEXT ·················1068
1ddc9d #define IDC_SERVERLIST ·················1070
3c224b #define IDC_PROGRESSTEXT ···············1071
4186b3 #define IDC_PHRASEQUALITY ··············1072
30114d #define IDC_MINPHRASEQUALITY ···········1073
cd2832 #define IDC_DONTBACKUP ·················1078
6b6973 #define IDC_PENDING ····················1079
066209 #define IDC_PHRASELENGTHTEXT ···········1082
d710c8 #define IDC_BADQUALITY1 ················1085
5aa8ea #define IDC_BADQUALITY2 ················1086
60489b #define IDC_BOX1 ·······················1087
faaa46 #define IDC_BOX2 ·······················1088
d6801b #define IDC_MINQUALITYTEXT ·············1090
3c8c96 #define IDC_REGISTRATION ···············1091
0b65b4 #define IDC_EXPIRATIONDATE ·············1092
d0d334 #define IDC_REVOCATIONKEY ··············1099
6cc964 #define IDS_KW_INVALID_KEY_SIZE ········1100
4af776 #define IDC_STATIC1 ····················1100
61c568 #define IDS_KW_INVALID_KEY_SIZE_TITLE ··1101
1e4aa9 #define IDS_KW_TITLE ···················1101
dd1876 #define IDC_STATIC2 ····················1101
124c57 #define IDS_KW_INVALID_KEY_TYPE ········1102
ed405b #define IDS_KW_INVALID_KEY_TYPE_TITLE ··1103
e34127 #define IDS_KW_INVALID_EXPIRATION ······1104
f2ea61 #define IDS_KW_INVALID_EXPIRATION_TITLE 1105
5050a2 #define IDS_KW_MISMATCHED_PHRASES ······1106
81fbe4 #define IDS_KW_MISMATCHED_PHRASES_TITLE 1107
810005 #define IDS_KW_ERROR_TITLE ·············1108
cd7bea #define IDS_KW_NO_EMAIL ················1109
5224f7 #define IDS_KW_NO_FULL_NAME ············1110
b5c0f6 #define IDS_KW_NEED_MORE_BITS ··········1111
29c2b7 #define IDB_KEYWIZ24 ···················1112
74e445 #define IDS_KW_CONFIRM_TITLE ···········1112
3519ec #define IDD_KEYWIZ_ABOUT ···············1113
--e3a4 000a035decd401102f6 Page 6 of resource.h
34b3fc #define IDS_KW_CONFIRM_CANCEL ··········1113
da3b98 #define IDD_KEYWIZ_INTRO ···············1113
a260c3 #define IDD_KEYWIZ_NAME ················1114
cf647e #define IDS_KW_COMPLETE ················1114
ba08ba #define IDD_KEYWIZ_TYPE ················1115
019fa1 #define IDS_SETASDEFAULT ···············1115
666b7a #define IDD_KEYWIZ_SIZE ················1116
adace1 #define IDS_SETASPRIMARY ···············1116
ef16ec #define IDD_KEYWIZ_EXPIRATION ··········1117
ad4e73 #define IDS_EXPORTFILTER ···············1117
a411e9 #define IDD_KEYWIZ_PASSPHRASE ··········1118
cb6e25 #define IDD_KEYWIZ_RANDOBITS ···········1119
0e8b5a #define IDD_KEYWIZ_GENERATION ··········1120
c5ee46 #define IDD_KEYWIZ_DONE ················1121
21a197 #define IDD_KEYWIZ_SEND ················1122
e4609a #define IDC_PROGRESS ···················1123
a92584 #define IDC_WIZIMAGE ···················1124
89b0a8 #define IDC_FULL_NAME ··················1125
6c7926 #define IDC_RADIO_ELGAMAL ··············1126
b00a17 #define IDC_EMAIL ······················1127
a111da #define IDC_RADIO_RSA ··················1128
9f8c9f #define IDC_RADIO_768 ··················1129
9620f0 #define IDC_RADIO_1024 ·················1130
776bf8 #define IDC_RADIO_1536 ·················1131
bd9c4d #define IDC_EDIT_PASSPHRASE2 ···········1132
2a4a59 #define IDC_RADIO_2048 ·················1133
96c244 #define IDC_CHECK_HIDE_TYPING ··········1134
4c3cc6 #define IDC_RADIO_3072 ·················1135
200054 #define IDC_STATIC_PROGRESS_TEXT ·······1136
c199f6 #define IDC_RADIO_CUSTOM ···············1137
bff740 #define IDC_BUTTON_BACKUP ··············1138
4ab538 #define IDC_CUSTOM_BITS ················1139
32a3d0 #define IDC_STATIC_CUSTOM_SIZE ·········1140
f6b995 #define IDC_RADIO_CUSTOM_DAYS ··········1141
0e0049 #define IDC_EDIT_CUSTOM_DAYS ···········1142
77fc8d #define IDC_RADIO_NEVER ················1143
84f38f #define IDC_STATIC_DAYS ················1144
916dd4 #define IDC_EDIT_PASSPHRASE ············1145
64547c #define IDS_KW_BAD_PASSPHRASE ··········1146
5f32d3 #define IDS_KW_BAD_PASSPHRASE_TITLE ····1147
06a126 #define IDD_KEYWIZ_PRESEND ·············1148
d5d23d #define IDS_KW_CANCELING ···············1149
ff831a #define IDS_KW_DSACUSTOM ···············1150
dc3c1c #define IDS_KW_DSA1536 ·················1151
0a0465 #define IDS_KW_DSA2048 ·················1152
f53ff2 #define IDS_KW_DSA3072 ·················1153
fb3942 #define IDS_KW_RSACUSTOM ···············1154
4d8644 #define IDS_KW_RSA1536 ·················1155
46be3d #define IDS_KW_RSA2048 ·················1156
d276d4 #define IDS_ANIMATIONFILE ··············1157
5d0777 #define IDS_KW_CANCELED ················1158
853071 #define IDS_KW_SENDLATER ···············1159
5d2f55 #define IDS_PUBBACKUPDEFAULTFILE ·······1160
f54076 #define IDS_DEFPUBKEYRINGEXTENSION ·····1161
8a19f4 #define IDS_PUBBACKUPCAPTION ···········1162
f400f8 #define IDS_PUBBACKUPFILTER ············1163
3a93c3 #define IDS_BACKUPFILTER ···············1164
845380 #define IDS_INVALIDDATE ················1165
9cde9f #define IDS_GROUPCOLTITLE ··············1166
46d7b6 #define IDS_DESCCOLTITLE ···············1167
6218a4 #define IDS_SEARCHTITLE ················1168
4b7566 #define IDS_KEYSELECTED ················1195
edf04b #define IDS_GROUPSELECTED ··············1196
d43107 #define IDS_MULTISELECTED ··············1198
269c2b #define IDS_SERVERSEARCHFAIL ···········1218
58b0a6 #define IDS_SEARCH_STRINGTABLE_BASE ····2000
2bfec6 #define IDS_ATTRIBUTE_1 ················2001
0e46e4 #define IDS_ATTRIBUTE_2 ················2002
5cd6f5 #define IDS_ATTRIBUTE_3 ················2003
0a3eb1 #define IDS_ATTRIBUTE_4 ················2004
44aea0 #define IDS_ATTRIBUTE_5 ················2005
a01682 #define IDS_ATTRIBUTE_6 ················2006
--7fca 0003130250b401102f6 Page 7 of resource.h
b28693 #define IDS_ATTRIBUTE_7 ················2007
5d9270 #define IDS_ATTRIBUTE_LAST ·············2008
bc192c #define IDS_VERBS_ATTRIBUTE_1 ··········2011
3c0355 #define IDS_VERBS_ATTRIBUTE_2 ··········2012
240a82 #define IDS_VERBS_ATTRIBUTE_3 ··········2013
da37a7 #define IDS_VERBS_ATTRIBUTE_4 ··········2014
033e70 #define IDS_VERBS_ATTRIBUTE_5 ··········2015
bc2409 #define IDS_VERBS_ATTRIBUTE_6 ··········2016
4c2dde #define IDS_VERBS_ATTRIBUTE_7 ··········2017
d2c6b6 #define IDS_VERBS_LAST ·················2018
e97d3d #define IDS_SPECIFIERS_ATTRIBUTE_1 ·····2021
3fd0bb #define IDS_SPECIFIERS_ATTRIBUTE_2 ·····2022
384c36 #define IDS_SPECIFIERS_ATTRIBUTE_3 ·····2023
b483a6 #define IDS_SPECIFIERS_ATTRIBUTE_4 ·····2024
431f2b #define IDS_SPECIFIERS_ATTRIBUTE_5 ·····2025
bfb2ad #define IDS_SPECIFIERS_ATTRIBUTE_6 ·····2026
0b2e20 #define IDS_SPECIFIERS_ATTRIBUTE_7 ·····2027
ea6249 #define IDS_SPECIFIERS_LAST ············2028
1ac3c3 #define IDS_LOCAL_KEYRING ··············2030
9aed21 #define IDS_CURRENT_SEARCH ·············2031
d01870 #define IDS_DEFAULT_PATH ···············2032
1f3142 #define IDS_MONTH1 ·····················2040
8b72a9 #define IDS_MONTH2 ·····················2041
1c96df #define IDS_MONTH3 ·····················2042
0ff57f #define IDS_MONTH4 ·····················2043
537669 #define IDS_MONTH5 ·····················2044
873582 #define IDS_MONTH6 ·····················2045
aad1f4 #define IDS_MONTH7 ·····················2046
17f2c2 #define IDS_MONTH8 ·····················2047
18bf14 #define IDS_MONTH9 ·····················2048
11abe4 #define IDS_MONTH10 ····················2049
117468 #define IDS_MONTH11 ····················2050
8f9b68 #define IDS_MONTH12 ····················2051
983206 #define IDS_SEARCH_MESSAGE_BASE ········2060
fecca3 #define IDS_SEARCH_MESSAGE_CONNECT ·····2061
23e4fe #define IDS_SEARCH_MESSAGE_CONNECTING ··2061
49fbc2 #define IDS_SEARCH_MESSAGE_WAIT ········2062
729a5e #define IDS_SEARCH_MESSAGE_QUERYING ····2062
5775cf #define IDS_SEARCH_MESSAGE_RECV ········2063
eb9fea #define IDS_SEARCH_MESSAGE_PROCESSING ··2063
900426 #define IDS_SEARCH_MESSAGE_SEND ········2064
0e9549 #define IDS_SEARCH_MESSAGE_SENDING ·····2064
35f917 #define IDS_SEARCH_MESSAGE_COMPLETED ···2065
00365a #define IDS_SEARCH_MESSAGE_CLOSING ·····2065
065adc #define IDS_MONTHS ·····················2066
4ce517 #define IDS_BADPHRASELENGTH ············2067
34eca1 #define IDS_REQPHRASELENGTH ············2067
eb83fb #define IDS_BADPHRASEQUALITY ···········2068
0e8a4d #define IDS_REQPHRASEQUALITY ···········2068
61385b #define IDS_ADMINPREFSCORRUPT ··········2069
484857 #define IDS_SUGPHRASELENGTH ············2070
bdb4ab #define IDS_SUGPHRASEQUALITY ···········2071
e9943d #define IDS_PHRASEREJECTED ·············2072
c595a8 #define IDS_PHRASEWARNED ···············2073
53497b #define IDS_MISSINGCORPKEY ·············2074
758673 #define IDS_MISSINGADK ·················2075
9ebea2 #define IDS_KW_UNABLETOCOMPLETE ········2076
627ef8 #define IDS_CLIENTPREFSFILE ············2077
e0e847 #define IDS_KSSENDDONE ·················2077
d6e0b1 #define IDS_MISSINGREVOKERKEY ··········2077
514ab4 #define IDS_SENDTOSERVERMENU ···········2078
1b876a #define IDS_SEARCH_MESSAGE_SERVER_NAME ·2079
2cf146 #define IDS_SMALLKEYWARNING ············2080
ff17ee #define IDS_SEARCH_MESSAGE_CANCEL ······2081
24afca #define IDS_SEARCHABORTED ··············2082
c94ff8 #define IDS_KSKEYCOUNT ·················2083
14f885 #define IDS_PHRASELENGTHTEXT ···········2084
e022c1 #define IDS_MISSINGKEYRINGS ············2085
467851 #define IDS_SYNCINGKEYSETS ·············2085
14dde9 #define IDS_GROUPNAMEFIELD ·············2086
d0700f #define IDS_VALIDITYFIELD ··············2087
31c65a #define IDS_DESCRIPTIONFIELD ···········2088
--23ab 0006fe7962c401102f6 Page 8 of resource.h
8e92ed #define IDS_NEEDGROUPNAME ··············2089
c31350 #define IDS_UNAVAILABLE ················2090
469769 #define IDS_DELCONFGROUP ···············2091
aefdf9 #define IDS_NOIMPORTGROUPS ·············2092
aaad2b #define IDS_GROUPPROPS ·················2093
4416d2 #define IDS_STRING2094 ·················2094
9c8db0 #define IDS_NOPASTEKEYS ················2095
4cb8c8 #define IDS_EMPTYGROUP ·················2096
44ebfd #define IDS_KSTOOMANYKEYCOUNT ··········2097
2c6e0b #define IDS_REGISTERURL ················2098
da1c6a #define IDS_REGISTERURLCGI ·············2099
cda165 #define IDS_EXPIREDADK ·················2100
2851a9 #define IDB_BACKGRND ···················2101
9d250d #define IDD_SEARCH ·····················2101
c3b7ef #define IDS_REVOKEDADK ·················2101
b76622 #define IDB_LARGE_BUTTON1 ··············2102
ba4405 #define IDS_EXPIREDCORPKEY ·············2102
96264e #define IDB_LARGE_BUTTON2 ··············2103
427900 #define IDD_CHOICE ·····················2103
11528f #define IDS_REVOKEDCORPKEY ·············2103
d35c2a #define IDB_LARGE_BUTTON3 ··············2104
399de2 #define IDS_GROUPSINFREEWARE ···········2104
be398d #define IDB_MIDDLE_BUTTON3 ·············2105
8aaf1a #define IDS_SEARCHINFREEWARE ···········2105
bfccb3 #define IDB_MIDDLE_BUTTON2 ·············2106
159115 #define IDS_UPGRADE ····················2106
9bbc80 #define IDB_MIDDLE_BUTTON1 ·············2107
f05ab5 #define IDS_UPGRADEURL ·················2107
006dd5 #define IDB_SMALL_BUTTON3 ··············2108
48c34e #define IDS_SPLITKEYWARNING ············2108
1c4361 #define IDB_SMALL_BUTTON2 ··············2109
f9c926 #define IDS_AUTOUPDATEKEYS ·············2109
159711 #define IDB_SMALL_BUTTON1 ··············2110
7c62b6 #define IDS_AUTOUPDATEINTRODUCERS ······2110
4f0214 #define IDS_TOOLTIPNEWKEY ··············2111
510b15 #define IDS_TOOLTIPREVOKE ··············2112
4de06e #define IDS_TOOLTIPSIGN ················2113
bd21bc #define IDS_TOOLTIPDELETE ··············2114
38a85e #define IDS_TOOLTIPSEARCH ··············2115
0fa2ed #define IDS_TOOLTIPNEWGROUP ············2116
4ddc6b #define IDS_TOOLTIPUPDATE ··············2117
b68e3d #define IDS_TOOLTIPSENDTOSERVER ········2118
5d1c25 #define IDS_TOOLTIPPROPERTIES ··········2119
e0c05e #define IDS_TOOLTIPIMPORT ··············2120
b5fc34 #define IDS_TOOLTIPEXPORT ··············2121
37721f #define IDS_EXPIREDREVOKERKEY ··········2122
036495 #define IDS_REVOKEDREVOKERKEY ··········2123
d22428 #define IDS_COMCTLERRORSWITCH ··········2124
620c58 #define IDS_DOMAINSERVER ···············2125
bf67c5 #define IDS_CONNECTIONNOTAUTHENTICATED ·2126
640d73 #define IDS_NOCONNECTIONYET ············2127
760b15 #define IDS_SEARCH_MESSAGE_DELETING ····2128
adf2a5 #define IDS_SEARCH_MESSAGE_DISABLING ···2129
5161f6 #define IDS_SDKEXPIRED ·················2130
f40644 #define IDS_NONEWTRUSTEDINTROS ·········2131
fb46bb #define IDS_NOUPDATEDKEYS ··············2132
f0d95e #define IDS_AUTOUPDATECAPTION ··········2133
df0885 #define IDC_SEARCH ·····················3000
4b008b #define IDC_CLEAR ······················3001
e9c44c #define IDC_LOCATION ···················3002
1960be #define IDC_MORE ·······················3003
1dd1b5 #define IDC_FEWER ······················3004
07abaa #define IDC_ATTRIBUTE ··················3005
8c44d3 #define IDC_VERB ·······················3006
ed02ef #define IDC_SPECIFIER_COMBO ············3007
613e73 #define IDC_DEFAULT_GROUP ··············3008
d0d26e #define IDC_SPECIFIER_EDIT ·············3012
feb46d #define IDC_SPECIFIER_COMBO_LIST ·······3013
62165d #define IDC_MONTH ······················3016
415aa8 #define IDC_DAY ························3017
512c16 #define IDC_YEAR ·······················3019
6f8132 #define IDC_DEFAULT_SPIN ···············3020
--81bb 000a39e4a4d401102f6 Page 9 of resource.h
bbe1ab #define IDC_SPIN ·······················3020
3dbeb5 #define IDC_CHOICE_SPIN ················3024
486c83 #define IDM_DELETEKEY ··················40006
eea653 #define IDM_KEYPROPERTIES ··············40007
9046eb #define IDM_CERTIFYKEY ·················40008
07d198 #define IDM_REVOKEKEY ··················40010
c09e65 #define IDM_HELPCONTENTS ···············40013
6bb083 #define IDM_HELPSEARCH ·················40014
48066e #define IDM_HELPTOPICS ·················40014
be95d2 #define IDM_HELPTUTORIAL ···············40015
35c868 #define IDM_HELPABOUT ··················40016
14c600 #define IDM_NEWKEYPAIR ·················40018
e0ab92 #define IDM_DISABLEKEY ·················40019
045544 #define IDM_ENABLEKEY ··················40020
daf5a9 #define IDM_PROPERTIES ·················40021
9c0016 #define IDM_COLLAPSEALL ················40023
0f00c8 #define IDM_COLLAPSESEL ················40023
400ada #define IDM_EXPANDALL ··················40024
09cff1 #define IDM_EXPANDSEL ··················40024
421c00 #define IDM_ADDUSERID ··················40025
be26b5 #define IDM_IMPORTKEYS ·················40027
e91b58 #define IDM_EXPORTKEYS ·················40028
bae1db #define IDM_SELECTALL ··················40030
31a623 #define IDM_CUTKEY ·····················40031
8fba00 #define IDM_COPYKEY ····················40032
9bdbaf #define IDM_PASTEKEY ···················40033
617d89 #define IDM_UNDO ·······················40034
46bbff #define IDM_FILEEXIT ···················40038
9fed70 #define IDM_REVOKECERT ·················40039
adc806 #define IDM_CREATEKEY ··················40041
6a1566 #define IDM_SETASDEFAULT ···············40042
06d43a #define IDM_ADVERTISE1 ·················40043
4f1b6b #define IDM_VIEWGROUPS ·················40045
b6a7f9 #define IDM_SEARCH ·····················40046
318fa5 #define IDM_NEWGROUP ···················40047
a2edc8 #define IDM_SELECTCOLUMNS ··············40048
efd7ad #define IDM_ADDTOMAIN ··················40049
fb3ef8 #define IDM_SENDTOSERVER ···············40050
edc907 #define IDM_GETFROMSERVER ··············40051
4bb70c #define IDM_SENDTOSERVERPOPUP ··········40052
a2bc6b #define IDM_DELETESERVER ···············40053
390428 #define IDM_DISABLESERVER ··············40054
db6021 #define IDM_DISABLE ····················40055
c33782 #define IDM_GROUPPROPS ·················40056
dacdab #define IDM_GROUPPROPERTIES ············40056
af2a26 #define IDM_FINDKEY ····················40059
ccb217 #define IDM_IMPORTGROUPS ···············40061
2237b3 #define IDM_VIEWVALIDITY ···············40063
0b31b7 #define IDM_VIEWSIZE ···················40064
d0b385 #define IDM_VIEWDESC ···················40065
c2786f #define IDM_VIEWKEYID ··················40066
d77899 #define IDM_VIEWTRUST ··················40067
87fc32 #define IDM_VIEWCREATION ···············40068
4b5f16 #define IDM_VIEWEXPIRATION ·············40069
319118 #define IDM_VIEWADK ····················40070
c19558 #define IDM_VIEWTOOLBAR ················40071
5f02f9 #define IDM_REVERIFY ···················40072
005189 #define IDM_SPLITKEY ···················40073
d1cdc7 #define IDM_SENDSHARES ·················40074
02f4ff #define IDM_UPDATEINTRODUCERS ··········40075
f50b6b #define IDM_ADDPHOTOID ·················40076
856cbb #define IDM_UPDATEGROUP ················40079
1839e6 #define IDM_UPDATEGROUPLISTS ···········40079
75ea34 #define IDM_SENDGROUPLISTS ·············40080
1f32cd #define IDM_ADDREVOKER ·················40081
06c012 #define IDM_DOMAINKEYSERVER ············40082
6eaf5a
9211aa // Next default values for new objects
74ac6a //·
7df860 #ifdef APSTUDIO_INVOKED
4b3f23 #ifndef APSTUDIO_READONLY_SYMBOLS
a3ee1e #define _APS_NEXT_RESOURCE_VALUE ·······229
--880a 00161488367401102f6 Page 10 of resource.h
d2d966 #define _APS_NEXT_COMMAND_VALUE ········40084
f8d9e7 #define _APS_NEXT_CONTROL_VALUE ········1102
401285 #define _APS_NEXT_SYMED_VALUE ··········101
a17454 #endif
617454 #endif

--c607 001518ee559401102f7 Page 1 of PGPtlVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
d52042 ·FILETYPE VFT_APP
817247 ·FILESUBTYPE VFT2_UNKNOWN
f44523 BEGIN
752c72 ····BLOCK "StringFileInfo"
095574 ····BEGIN
fe70ac ········BLOCK "040904b0"
2752d6 ········BEGIN
e980b6 ············VALUE "CompanyName", PGPCOMPANYNAME
e95be4 ············VALUE "FileDescription", "PGP Encryption/Decryption Tool\0"
a0c1dd ············VALUE "FileVersion", PGPVERSIONSTRING
1f2c49 ············VALUE "InternalName", "PGPtools\0"
ec8ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
592bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
1a46d3 ············VALUE "OriginalFilename", "PGPtools.exe\0"
9c9317 ············VALUE "ProductName", PGPPRODUCTNAME
60d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
e4f37f ········END
187d01 ····END
be26ab ····BLOCK "VarFileInfo"
525574 ····BEGIN
444b11 ········VALUE "Translation", 0x409, 1200
9b7d01 ····END
c7e0d1 END
e0af5a
50af5a
51af5a
--92b8 0001580eed8401102f8 Page 1 of PGPtools.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
c15655 #include <windows.h>
180786 #include <dlgs.h>
396c0e /////////////////////////////////////////////////////////////////////////////
c37b93 #undef APSTUDIO_READONLY_SYMBOLS
6faf5a
b76c0e /////////////////////////////////////////////////////////////////////////////
3bf930 // English (U.S.) resources
b9af5a
aa1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
f5ec08 #ifdef _WIN32
0ee912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
e09c1c #pragma code_page(1252)
961f8e #endif //_WIN32
50af5a
bc6c0e /////////////////////////////////////////////////////////////////////////////
8a465d //
ddb090 // Dialog
d3465d //
82af5a
22a9d3 IDD_CUST32DLG DIALOG DISCARDABLE ·0, 0, 279, 23
34c8d7 STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
63309f FONT 8, "MS Sans Serif"
924523 BEGIN
99b041 ····PUSHBUTTON ·····"Clipboard",IDC_CLIPBOARD,222,0,50,15
6ee0d1 END
baaf5a
80af5a
546c0e /////////////////////////////////////////////////////////////////////////////
44465d //
8fcbaf // Icon
8d465d //
baaf5a
832951 // Icon with lowest ID value placed first to ensure application icon
180f06 // remains consistent on all systems.
2626af IDI_TOOLSICO ···········ICON ···DISCARDABLE ····"res\\TOOLSICO.ICO"
e95418 IDI_L4KEYS ·············ICON ···DISCARDABLE ····"res\\l4keys.ico"
10c5d5 IDI_L8KEYS ·············ICON ···DISCARDABLE ····"res\\l8keys.ico"
019a91 IDI_S4KEYS ·············ICON ···DISCARDABLE ····"res\\s4keys.ico"
201518 IDI_L4WIPE ·············ICON ···DISCARDABLE ····"res\\l4wipe.ico"
184a5c IDI_S8WIPE ·············ICON ···DISCARDABLE ····"res\\s8wipe.ico"
3b84d5 IDI_L8WIPE ·············ICON ···DISCARDABLE ····"res\\l8wipe.ico"
20db91 IDI_S4WIPE ·············ICON ···DISCARDABLE ····"res\\s4wipe.ico"
1ef96f IDI_L8ENC ··············ICON ···DISCARDABLE ····"res\\l8enc.ico"
c395aa IDI_L4ENC ··············ICON ···DISCARDABLE ····"res\\l4enc.ico"
1e13b5 IDI_L8SIG ··············ICON ···DISCARDABLE ····"res\\l8sig.ico"
3e7f70 IDI_L4SIG ··············ICON ···DISCARDABLE ····"res\\l4sig.ico"
bd9a62 IDI_L8DECVER ···········ICON ···DISCARDABLE ····"res\\l8decver.ico"
be65b0 IDI_L4DECVER ···········ICON ···DISCARDABLE ····"res\\l4decver.ico"
d4a0e5 IDI_L8ENCSIG ···········ICON ···DISCARDABLE ····"res\\l8encsig.ico"
a65f37 IDI_L4ENCSIG ···········ICON ···DISCARDABLE ····"res\\l4encsig.ico"
f6d443 IDI_S8ENCSIG ···········ICON ···DISCARDABLE ····"res\\s8encsig.ico"
d42b91 IDI_S4ENCSIG ···········ICON ···DISCARDABLE ····"res\\s4encsig.ico"
3b3c27 IDI_S8ENC ··············ICON ···DISCARDABLE ····"res\\s8enc.ico"
fa50e2 IDI_S4ENC ··············ICON ···DISCARDABLE ····"res\\s4enc.ico"
b8d6fd IDI_S8SIG ··············ICON ···DISCARDABLE ····"res\\s8sig.ico"
3aba38 IDI_S4SIG ··············ICON ···DISCARDABLE ····"res\\s4sig.ico"
0beec4 IDI_S8DECVER ···········ICON ···DISCARDABLE ····"res\\s8decver.ico"
1e1116 IDI_S4DECVER ···········ICON ···DISCARDABLE ····"res\\s4decver.ico"
4a0b5c IDI_S8KEYS ·············ICON ···DISCARDABLE ····"res\\s8keys.ico"
1e49b0 IDI_L4WIPEV ············ICON ···DISCARDABLE ····"res\\l4wipev.ico"
0d50b7 IDI_S4WIPEV ············ICON ···DISCARDABLE ····"res\\s4wipev.ico"
9654c8 IDI_L8WIPEV ············ICON ···DISCARDABLE ····"res\\l8wipev.ico"
154dcf IDI_S8WIPEV ············ICON ···DISCARDABLE ····"res\\s8wipev.ico"
--0055 0002c8092dd401102f8 Page 2 of PGPtools.rc
e0af5a
fff860 #ifdef APSTUDIO_INVOKED
0d6c0e /////////////////////////////////////////////////////////////////////////////
ef465d //
a15733 // TEXTINCLUDE
b2465d //
91af5a
5786ef 1 TEXTINCLUDE DISCARDABLE·
954523 BEGIN
f2541e ····"resource.h\0"
4de0d1 END
c5af5a
037037 2 TEXTINCLUDE DISCARDABLE·
994523 BEGIN
96075a ····"#include <windows.h>\r\n"
86cfa5 ····"#include <dlgs.h>\0"
33e0d1 END
fcaf5a
3d227f 3 TEXTINCLUDE DISCARDABLE·
bf4523 BEGIN
f1f298 ····"#include ""PGPtlVer.rc""\r\n"
7de851 ····"\r\n"
bddb5c ····"\0"
08e0d1 END
d9af5a
b669ab #endif ···// APSTUDIO_INVOKED
c8af5a
d2af5a
556c0e /////////////////////////////////////////////////////////////////////////////
d6465d //
6486c0 // Menu
03465d //
4daf5a
a7f1bd IDR_PGPTOOLSMENU MENU DISCARDABLE·
e34523 BEGIN
67b474 ····POPUP "&File"
e95574 ····BEGIN
2e0b08 ········MENUITEM "Edit Clipboard &Text\tCtrl+T", IDC_EDITCLIP
8ad43a ········MENUITEM "Launch Associated V&iewer\tCtrl+I", IDC_ASSOCVIEWER
d0592d ········MENUITEM SEPARATOR
ec1337 ········MENUITEM "&Launch PGPkeys\tCtrl+L", ····IDC_KEYS
bdd443 ········MENUITEM "&Resize PGPtools\tCtrl+R", ···IDC_RESIZE
c572b6 ········MENUITEM "PGP &Preferences\tCtrl+P", ···IDC_PGPPREFS
8c592d ········MENUITEM SEPARATOR
bd9268 ········MENUITEM "E&xit\tCtrl+X", ··············IDC_QUIT
0d7d01 ····END
21dc4b ····POPUP "&PGP"
a55574 ····BEGIN
2ba5fa ········MENUITEM "&Encrypt\tCtrl+E", ···········IDC_ENCRYPT
809550 ········MENUITEM "&Sign\tCtrl+S", ··············IDC_SIGN
7ea36c ········MENUITEM "E&ncrypt && Sign\tCtrl+N", ···IDC_ENCSIGN
eb592d ········MENUITEM SEPARATOR
135b25 ········MENUITEM "&Decrypt + Verify\tCtrl+D", ··IDC_DECRYPT
867a1c ········MENUITEM "Add &Key\tCtrl+K", ···········IDC_ADDKEY
e0592d ········MENUITEM SEPARATOR
01184c ········MENUITEM "&Wipe\tCtrl+W", ··············IDC_WIPE
867d01 ····END
bc46ce ····POPUP "&Help"
d15574 ····BEGIN
a12cda ········MENUITEM "&Help Topics\tCtrl+H", ·······IDC_HELPTOPICS
05592d ········MENUITEM SEPARATOR
173a7e ········MENUITEM "&About PGP\tCtrl+A", ·········IDC_ABOUTPGP
2c7d01 ····END
76e0d1 END
fcaf5a
0daf5a
f36c0e /////////////////////////////////////////////////////////////////////////////
d9465d //
d25a93 // Accelerator
08465d //
e6af5a
2c8523 IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE·
--46a5 001245b44fd401102f8 Page 3 of PGPtools.rc
254523 BEGIN
b43d71 ····"A", ···········IDC_ABOUTPGP, ··········VIRTKEY, CONTROL, NOINVERT
e594f0 ····"D", ···········IDC_DECRYPT, ···········VIRTKEY, CONTROL, NOINVERT
b67450 ····"E", ···········IDC_ENCRYPT, ···········VIRTKEY, CONTROL, NOINVERT
9e7f69 ····"H", ···········IDC_HELPTOPICS, ········VIRTKEY, CONTROL, NOINVERT
744d5b ····"I", ···········IDC_ASSOCVIEWER, ·······VIRTKEY, CONTROL, NOINVERT
cce888 ····"K", ···········IDC_ADDKEY, ············VIRTKEY, CONTROL, NOINVERT
4499ef ····"L", ···········IDC_KEYS, ··············VIRTKEY, CONTROL, NOINVERT
243267 ····"N", ···········IDC_ENCSIGN, ···········VIRTKEY, CONTROL, NOINVERT
24fcc6 ····"P", ···········IDC_PGPPREFS, ··········VIRTKEY, CONTROL, NOINVERT
f5d1b4 ····"R", ···········IDC_RESIZE, ············VIRTKEY, CONTROL, NOINVERT
a4bd87 ····"S", ···········IDC_SIGN, ··············VIRTKEY, CONTROL, NOINVERT
435c1e ····"T", ···········IDC_EDITCLIP, ··········VIRTKEY, CONTROL, NOINVERT
0e67bd ····"W", ···········IDC_WIPE, ··············VIRTKEY, CONTROL, NOINVERT
c15076 ····"X", ···········IDC_QUIT, ··············VIRTKEY, CONTROL, NOINVERT
07e0d1 END
20af5a
38af5a
c36c0e /////////////////////////////////////////////////////////////////////////////
f9465d //
ed5e87 // String Table
05465d //
8aaf5a
f46f6c STRINGTABLE DISCARDABLE·
fa4523 BEGIN
44b8c9 ····IDS_SELFILEENC ·········"Select File(s) to Encrypt"
b09ffd ····IDS_SELFILESIGN ········"Select File(s) to Sign"
07d8e8 ····IDS_SELFILEENCSIGN ·····"Select File(s) to Encrypt & Sign"
13a51d ····IDS_ALLFILES ···········"All Files (*.*)@*.*@@"
964534 ····IDS_SELFILEDECVER ······"Select File(s) to Decrypt/Verify"
014cba ····IDS_PGPFILES ···········"PGP Files (*.pgp, *.asc, *.sig)@*.pgp;*.asc;*.sig@¶
d63999 All Files (*.*)@*.*@@"
cf3e72 ····IDS_SELFILEWIPE ········"Select File(s) to Wipe"
95c85f ····IDS_SELFILEADD ·········"Select File(s) to Add Keys"
7512a7 ····IDS_KEYFILES ···········"PGP Key Files (*.pgp, *.asc)@*.pgp;*.asc@All Files¶
c01d53 ·(*.*)@*.*@@"
ced887 ····IDS_NOVOLWIPENT ········"Volume wiping is not currently supported under\nWi¶
ff2fde ndows NT."
9e10eb ····IDS_PGPERROR ···········"PGP Error"
36e0d1 END
50af5a
421b3a #endif ···// English (U.S.) resources
466c0e /////////////////////////////////////////////////////////////////////////////
afaf5a
71af5a
e5af5a
35ce8c #ifndef APSTUDIO_INVOKED
a56c0e /////////////////////////////////////////////////////////////////////////////
42465d //
938464 // Generated from the TEXTINCLUDE 3 resource.
c1465d //
e00e7d #include "PGPtlVer.rc"
41af5a
13af5a
ea6c0e /////////////////////////////////////////////////////////////////////////////
ef8072 #endif ···// not APSTUDIO_INVOKED
24af5a
--1367 000bc20ba6c401102f9 Page 1 of Precomp.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
fe5a1f ¤   $Id: Precomp.h,v 1.8.2.1.2.1 1998/11/12 03:13:43 heller Exp $
b3f7f7 ____________________________________________________________________________*/
fd519a #ifndef Included_PRECOMP_h¤ /* [ */
5f5498 #define Included_PRECOMP_h
1daf5a
c61bcc /*++
32af5a
f6fd5d ··File: precomp.h
fa3b41 ··Author: Bill Blanke (wjb@pgp.com)
07e3b0 ··Date: September 14, 1997
830c58 ··Revisions:
baaf5a
0d67d9 --*/
88af5a
a52a68 #define WIN32_LEAN_AND_MEAN
9cc0db #define PGPLIB·
c9af5a
ea7158 #ifndef WIN32
30af5a
aef9cb #define BST_CHECKED¤¤   ¤   1
583c84 #define ULONG unsigned long
e223b0 #define USHORT unsigned short ···
87e290 #define LPTSTR ·char*·
8faf5a
dedad3 #define MAX_PATH 256
25af5a
cdf74f #define UCHAR unsigned char
e267f0 #define CHAR char
f9ff9d #define INT int ·
f62996 #define APIENTRY WINAPI ··
657a28 #define BST_CHECKED 1
f1640a #define BST_UNCHECKED 0 ················
eeaf5a
2ec950 #define LPCTSTR char *
fdaf5a
d17454 #endif
71af5a
58f451 #define PGPExport __declspec( dllimport )
6aaf5a
96af5a
ddd500 // system include files
6d5655 #include <windows.h>
743d0b #include <windowsx.h>
1abb5f #include <assert.h>
2b6bd4 #include <commdlg.h>
80feb2 #include <stdio.h>
81bea3 #include <stdlib.h>
9d7609 #include <ShellAPI.h>
46af5a
72fee6 #define UNFINISHED_CODE_ALLOWED 1
feaf5a
3f8cbe // PGPlib headers
bdaf5a
839de0 #include "..\include\PGPsc.h"
9faf5a
723db0 #include "openfile.h"
17f4a0 #include "proc.h"
1f8031 #include "resource.h"
58af5a
eb22ee HINSTANCE g_hinst;
f833b4 FARPROC origButtonProc;
a4af5a
07f8cb void *PGPsc;
4c3a96 void *PGPtls;
47af5a
bcdf71 #define IDM_STAYONTOP 1
--1f3a 00120e662d1401102f9 Page 2 of Precomp.h
e0af5a
c241ed #endif /* ] Included_PRECOMP_h */
4baf5a
31af5a
687e4d /*__Editor_settings____
9aaf5a
f64126 ¤   Local Variables:
c87b17 ¤   tab-width: 4
f70e6c ¤   End:
a15f8c ¤   vi: ts=4 sw=4
649e9b ¤   vim: si
20d062 _____________________*/
--835f 0008c304317401102fa Page 1 of main.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
41550b ¤   $Id: main.c,v 1.18.2.1.2.1 1998/11/12 03:13:44 heller Exp $
16f7f7 ____________________________________________________________________________*/
675ed8 #include "precomp.h"
1aaf5a
12a9e8 #ifdef _WIN32·
5ec113 static char szAppName[] = "PGPtools" ;
99db21 #else
f2dd58 static char szAppName[] = "PGPtls16" ;
0b7454 #endif
2daf5a
862665 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
d237bc ¤   ¤   ····LPSTR szCmdLine, int iCmdShow)
41bb36 {
77eb74 ¤   MSG ········msg ;
b571cb ¤   HWND ·······hwnd ;
1544da ¤   WNDCLASS ···wndclass ;·
98b891 ¤   int WinHeight;
0e2a28 ¤   HACCEL hAccel;
17af5a
a58785 ¤   g_hinst = hInstance ;
5baf5a
fec11e ¤   if(*szCmdLine)
e6c7a1 ¤   {
57bb8b ¤   ¤   FILELIST *ListHead;
85af5a
e2d050 ¤   ¤   if(!InitPGPsc(NULL,&PGPsc,&PGPtls))
ca32bd ¤   ¤   ¤   return TRUE;
6faf5a
c5f24f ¤   ¤   wndclass.style¤ ¤   ¤   = 0;
93fde3 ¤   ¤   wndclass.lpfnWndProc¤   = (WNDPROC)HiddenWndProc;
0f0684 ¤   ¤   wndclass.cbClsExtra¤¤   = 0;
113871 ¤   ¤   wndclass.cbWndExtra¤¤   = 0;
b6ae0b ¤   ¤   wndclass.hInstance¤ ¤   = hInstance;
5a367c ¤   ¤   wndclass.hIcon¤ ¤   ¤   = 0;
589c3f ¤   ¤   wndclass.hCursor¤   ¤   = 0;
e4e6e0 ¤   ¤   wndclass.hbrBackground¤ = 0;
d5cacf ¤   ¤   wndclass.lpszMenuName¤  = 0;
81c258 ¤   ¤   wndclass.lpszClassName¤ = "PGPtools_Hidden_Window";
84af5a
1b53ae ¤   ¤   RegisterClass(&wndclass);
afaf5a
b419a9 ¤   ¤   hwnd = CreateWindow("PGPtools_Hidden_Window",·
8830eb ¤   ¤   ¤   ¤   ¤   "PGPtools_Hidden_Window", WS_OVERLAPPEDWINDOW,·
93fd13 ¤   ¤   ¤   ¤   ¤   CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
2bce45 ¤   ¤   ¤   ¤   ¤   CW_USEDEFAULT, NULL, NULL, hInstance, NULL );
a5af5a
d4efb3 ¤   ¤   ShowWindow(hwnd, SW_HIDE);
5b9083 ¤   ¤   UpdateWindow(hwnd);
11af5a
bd4f2b ¤   ¤   ListHead=CmdLineToFileList(szCmdLine);
a6af5a
f31ef4 ¤   ¤   DecryptFileList(hwnd,PGPsc,PGPtls,ListHead);
2baf5a
f2c4b0 ¤   ¤   UninitPGPsc(hwnd,PGPsc,PGPtls);
80836c ¤   ¤   return TRUE;
689371 ¤   }
d9d83c ·
d59ba3 ¤   if(WindowExists(szAppName,szAppName))·
f2836c ¤   ¤   return TRUE;
2d869e ····
fb5836 ¤   if(!InitPGPsc(NULL,&PGPsc,&PGPtls))
a2836c ¤   ¤   return TRUE;
4baf5a
652ecd ¤   wndclass.style ········= CS_HREDRAW | CS_VREDRAW ;
ac591c ¤   wndclass.lpfnWndProc ··= (WNDPROC) PGPtoolsWndProc ;
8c0122 ¤   wndclass.cbClsExtra ···= 0 ;
--7f98 001e508c248401102fa Page 2 of main.c
343fd7 ¤   wndclass.cbWndExtra ···= 0 ;
30a3be ¤   wndclass.hInstance ····= hInstance ;
c82cd5 ¤   wndclass.hIcon ········= LoadIcon (g_hinst,
0b91a1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDI_TOOLSICO)) ;
18141e ¤   wndclass.hCursor ······= LoadCursor (NULL, IDC_ARROW) ;
476f6f ¤   wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
cd901e ¤   wndclass.lpszMenuName ·= NULL;//MAKEINTRESOURCE(IDR_PGPTOOLSMENU);
17595d ¤   wndclass.lpszClassName = szAppName ;
a7af5a
0f6c4b ¤   RegisterClass(&wndclass) ;
df67c5 ¤
5d63e1 ¤   hAccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR1));
e0af5a
4220c4 ¤   WinHeight=120;
bbaf5a
450afe ¤   hwnd = CreateWindow( ·szAppName, szAppName,
51f732 ··························WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX |·
130341 ¤   ¤   ¤   ¤   ¤   ¤   ··WS_SIZEBOX| WS_SYSMENU,
3876fc ¤   ······················CW_USEDEFAULT, CW_USEDEFAULT,
ebeae7 ¤   ······················450, ······
282f6a ¤   ¤   ¤   ¤   ¤   ¤   ··WinHeight,
6d6d8c ··························NULL,NULL, hInstance, NULL) ;
82af5a
efb17f ¤   ShowWindow (hwnd, iCmdShow) ;
0a40c8 ¤   UpdateWindow (hwnd);·
31af5a
0c5ed8 ¤   while (GetMessage (&msg, NULL, 0, 0))
1bc7a1 ¤   {
fd48ff ¤   ¤   if(!TranslateAccelerator(hwnd,hAccel,&msg))
545b34 ¤   ¤   {
b434e8 ¤   ¤   ¤   TranslateMessage (&msg) ;
a07203 ¤   ¤   ¤   DispatchMessage (&msg) ;
250fe4 ¤   ¤   }
009371 ¤   }
ba583d ·····
9f01e5 ¤   UninitPGPsc(hwnd,PGPsc,PGPtls);
dcaf5a
6c5570 ¤   return msg.wParam ;
703cfd } ····
e6af5a
457e4d /*__Editor_settings____
fcaf5a
d14126 ¤   Local Variables:
837b17 ¤   tab-width: 4
d80e6c ¤   End:
d55f8c ¤   vi: ts=4 sw=4
c09e9b ¤   vim: si
ddd062 _____________________*/
e5af5a
--be92 0007bd869d9401102fb Page 1 of openfile.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
217974 ¤   $Id: openfile.c,v 1.9.2.1.2.1 1998/11/12 03:13:45 heller Exp $
09af5a
41af5a
55af5a
f1f7f7 ____________________________________________________________________________*/
755ed8 #include "precomp.h"
67af5a
1d84aa #define OFNBUFFSIZE 25000
bdaf5a
2a7efe BOOL·
347158 #ifndef WIN32
6c94b6 FAR __export
d01736 #endif // WIN32
c2b947 PASCAL FileDlgHookProc(HWND hDlg, unsigned message,
f9e290 ···························WORD wParam, LONG lParam)
d87142 {·
8f17c4 ····static BOOL *ClipBoard;
e9869e ····
31a42e ····switch (message)
b03b37 ····{
6e2aad ········case WM_INITDIALOG:
1e8fd1 ·················ClipBoard=(BOOL *)(((OPENFILENAME *)lParam)->lCustData);
381985 ·················*ClipBoard=FALSE;
af7341 ·············return TRUE;
b5583d ·····
9caff6 ········case WM_COMMAND:
ccccd8 ·············switch(wParam)
890c4d ·············{
3ec62e ·················case IDC_CLIPBOARD:
b76faa ·····················*ClipBoard=TRUE;
c22664 #ifdef WIN32
d457b6 ¤   ¤   ¤   ¤   ¤   ·EndDialog(GetParent(hDlg),TRUE);
70db21 #else
4099eb ············¤   ¤   ·EndDialog(hDlg, TRUE);
f37454 #endif
26589d ·············}
64e9c8 ·············break;
7dd2c9 ···························
106fe7 ····}
abcf72 ······
f630cb ····return FALSE;
85efe6 }
b4af5a
5218fb #ifdef WIN32 // Translate Multi for Win95 and WinNT
06af5a
bb9ce9 FILELIST *TranslateMulti(char *FileString)
b2bb36 {
e8f275 ¤   char *FileName;
984cda ¤   char *FilePath;
44c616 ¤   FILELIST *ListHead,*Current;
dd37f2 ¤   int FirstFile;
c3a27b ¤   char name[MAX_PATH];
baaf5a
c657ac ¤   FirstFile=0;
2faf5a
bb6337 ¤   while(FileString[FirstFile]!=0)
aec7a1 ¤   {
77322f ¤   ¤   FirstFile++;
f09371 ¤   }
3baf5a
ee73a4 ¤   FirstFile++;
5eaf5a
a5b4d1 ¤   ListHead=Current=0;
3eabb3 ¤   FilePath=FileString;
7bf779 ¤   FileName=&FileString[FirstFile];
--bc8c 000f29c1377401102fb Page 2 of openfile.c
e0af5a
e99e63 ¤   while(TRUE)
03c7a1 ¤   {
c2fea1 ¤   ¤   strcpy(name,FilePath);
68af5a
f35714 ¤   ¤   if((*FileName)!=0)
045b34 ¤   ¤   {
c2a084 ¤   ¤   ¤   strcat(name,"\\");
043cda ¤   ¤   ¤   strcat(name,FileName);
040fe4 ¤   ¤   }
76af5a
39dee7 ¤   ¤   AddToFileList(&ListHead,name,NULL);
2eaf5a
7f9e19 ¤   ¤   while((*FileName)!=0)
465b34 ¤   ¤   {
b5e5b9 ¤   ¤   ¤   FileName++;
c70fe4 ¤   ¤   }
adaf5a
a29f4d ¤   ¤   FileName++;
f3af5a
589464 ¤   ¤   if((*FileName)==0)
7ccdcb ¤   ¤   ¤   break;
269371 ¤   }
d8af5a
76b85c ¤   return ListHead;
9aefe6 }
16af5a
3c8dc7 #else // Translate Multi For Win3.1
2caf5a
439ce9 FILELIST *TranslateMulti(char *FileString)
04bb36 {
15f275 ¤   char *FileName;
f3825e ¤   char *FilePath; ·
a34648 ¤   char *FileStart;
e74dee ¤   FILELIST *ListHead;
c937f2 ¤   int FirstFile;
793a67 ····BOOL OneMore;
0ba27b ¤   char name[MAX_PATH];
e5869e ····
7757ac ¤   FirstFile=0;
abaf5a
2c54db ¤   while((FileString[FirstFile]!=' ')&&(FileString[FirstFile]!=0))
4d9108 ¤   {·
0e322f ¤   ¤   FirstFile++;
e29371 ¤   }
3d869e ····
7ff13e ····FileString[FirstFile]=0;
92869e ····
3d73a4 ¤   FirstFile++;
11af5a
27a1f1 ¤   ListHead=0;
d4abb3 ¤   FilePath=FileString;
8af779 ¤   FileName=&FileString[FirstFile];
79869e ····
947894 ····OneMore=TRUE;
4a869e ····
623c63 ¤   while(OneMore)
bcc7a1 ¤   {
0265ce ¤   FileStart=FileName;
7967c5 ¤
194ec8 ¤   while(((*FileName)!=' ')&&((*FileName)!=0))
2bc7a1 ¤   {
559f4d ¤   ¤   FileName++;
9b9371 ¤   }
fbd83c ·
2e9637 ·¤  if((*FileName)==0)
1791b1 ¤   ¤   OneMore=FALSE;
1267c5 ¤
241085 ¤   *FileName=0;
0b9746 ¤   ································
57e1aa // ···MessageBox(NULL,FilePath,FileStart,MB_OK);
f2869e ····
--a4a0 0000b10c7bf401102fb Page 3 of openfile.c
97ea89 ¤   strcpy(name,FilePath);
ed25a1 ¤   if((*FileStart)!=0)
9cc7a1 ¤   {
55b4ac ¤   ¤   strcat(name,"\\");
6a8d24 ¤   ¤   strcat(name,FileStart);
266fe7 ····}
3e869e ····
d24ac5 ····AddToFileList(&ListHead,name);
9ee8c6 ···
cc083e ¤   FileName++;
cd9371 ¤   }
99af5a
a5b85c ¤   return ListHead;
20efe6 }
e1af5a
101736 #endif // WIN32
2baf5a
d4cb11 BOOL GetFileName(HWND hwnd,
2f886a ¤   ¤   ¤   ¤   ·char *lpszMessage,
313279 ¤   ¤   ¤   ¤   ·FILELIST **FileList,
da592b ¤   ¤   ¤   ¤   ·BOOL Clipboard,
c4190b ¤   ¤   ¤   ¤   ·char *FilterString)
3cbb36 {
52c9bb ¤   char *OriginalFile;
4d80d9 ¤   BOOL ReturnValue;
9ab9af ····OPENFILENAME OriginalFileName; ···
420b2e ····BOOL ClipBoard;
a222f1 ¤   DWORD OFN_Error,Flags;
80af5a
657dea ¤   // Get 40K for file selector
43b3ff ¤   OriginalFile=(char *)malloc(OFNBUFFSIZE);·
e7869e ····
4f0674 ¤   memset(OriginalFile,0x00,OFNBUFFSIZE);
7caf5a
8d5529 ¤   OriginalFileName.lStructSize=sizeof(OPENFILENAME);
6e6736 ····OriginalFileName.hwndOwner=hwnd;
5f6334 ····OriginalFileName.hInstance=g_hinst;
e16742 ····OriginalFileName.lpstrFilter=FilterString;
119aa5 ····OriginalFileName.lpstrCustomFilter=NULL;
876c2f ····OriginalFileName.nMaxCustFilter=0;
45322b ····OriginalFileName.nFilterIndex=1;
a81b6d ····OriginalFileName.lpstrFile=OriginalFile;
6d0df7 ····OriginalFileName.nMaxFile=OFNBUFFSIZE;
258e01 ····OriginalFileName.lpstrFileTitle=NULL;
d03882 ····OriginalFileName.nMaxFileTitle=0;
d6e323 ····OriginalFileName.lpstrInitialDir=NULL;
db11fe ····OriginalFileName.lpstrTitle=lpszMessage;
42ae2b ¤   Flags=OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
55f286 ¤   ¤   OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST |·
1c00ab ¤   ¤   OFN_ALLOWMULTISELECT;
1b79e9 ¤   if(Clipboard)
411f44 ¤   ¤   Flags|=OFN_ENABLEHOOK | OFN_ENABLETEMPLATE;
9751e8 ····OriginalFileName.Flags=Flags;
0f2664 #ifdef WIN32
e2a56f ····OriginalFileName.Flags=OriginalFileName.Flags | OFN_EXPLORER;
f57454 #endif
bbb470 ····OriginalFileName.nFileOffset=0;
d710e2 ····OriginalFileName.nFileExtension=strlen(OriginalFile);
bcd9fb ····OriginalFileName.lpstrDefExt=0;
3051ac ····OriginalFileName.lCustData=(LPARAM)(&ClipBoard);
0679e9 ¤   if(Clipboard)
91c7a1 ¤   {
a52664 #ifdef WIN32
d2f22b ¤   ¤   OriginalFileName.lpfnHook=
3e0e6a ¤   ¤   ¤   (LPOFNHOOKPROC)FileDlgHookProc;
53b897 ¤   ¤   OriginalFileName.lpTemplateName=
2c5b7a ¤   ¤   ¤   MAKEINTRESOURCE(IDD_CUST32DLG);
4cdb21 #else
7af22b ¤   ¤   OriginalFileName.lpfnHook=
935833 ¤   ¤   ¤   MakeProcInstance(FileDlgHookProc,g_hinst);
69b897 ¤   ¤   OriginalFileName.lpTemplateName=
0b3f63 ¤   ¤   ¤   MAKEINTRESOURCE(IDD_CUST16DLG);
--c78b 001e1dd7e35401102fb Page 4 of openfile.c
a07454 #endif
879371 ¤   }
da0e24 ¤   else
94c7a1 ¤   {
0ef76d ¤   ¤   OriginalFileName.lpfnHook=NULL;
b114c0 ¤   ¤   OriginalFileName.lpTemplateName=NULL;
cc9371 ¤   }
83af5a
7bb623 ¤   if(GetOpenFileName(&OriginalFileName))
acc7a1 ¤   {
669e7f ¤   ¤   ReturnValue = TRUE;
ccaf5a
ae101a ¤   ¤   if(ClipBoard==TRUE)
28f14a ¤   ¤   ¤   *FileList=0;
5c0e1d ¤   ¤   else
c65b34 ¤   ¤   {
c0e786 ¤   ¤   ¤   *FileList=TranslateMulti(OriginalFileName.lpstrFile);
aa0fe4 ¤   ¤   }
009371 ¤   }
5e0e24 ¤   else
82c7a1 ¤   {
808063 ¤   ¤   OFN_Error=CommDlgExtendedError();
60baad ¤   ¤   ReturnValue = FALSE;
209371 ¤   }
09869e ····
8617b0 #ifndef _WIN32
c0d986 ····FreeProcInstance(OriginalFileName.lpfnHook);
313d91 #endif // !_WIN32
c5af5a
530674 ¤   memset(OriginalFile,0x00,OFNBUFFSIZE);
2d746b ¤   free(OriginalFile);
d4869e ····
e555cd ¤   return(ReturnValue);
afefe6 }
49af5a
25af5a
227e4d /*__Editor_settings____
c7af5a
3f4126 ¤   Local Variables:
af7b17 ¤   tab-width: 4
890e6c ¤   End:
7a5f8c ¤   vi: ts=4 sw=4
ce9e9b ¤   vim: si
d3d062 _____________________*/
e1af5a
--8ac5 001d758a14e401102fc Page 1 of openfile.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
796d38 ¤   $Id: openfile.h,v 1.6.8.1 1998/11/12 03:13:45 heller Exp $
c7af5a
c6af5a
06af5a
aef7f7 ____________________________________________________________________________*/
ee0c7b #ifndef Included_OPENFILE_h¤/* [ */
79e9f1 #define Included_OPENFILE_h
56af5a
0dcb11 BOOL GetFileName(HWND hwnd,
dd886a ¤   ¤   ¤   ¤   ·char *lpszMessage,
043279 ¤   ¤   ¤   ¤   ·FILELIST **FileList,
32592b ¤   ¤   ¤   ¤   ·BOOL Clipboard,
99beea ¤   ¤   ¤   ¤   ·char *FilterString);
c9af5a
94d803 #endif /* ] Included_OPENFILE_h */
a5af5a
ebaf5a
977e4d /*__Editor_settings____
bbaf5a
164126 ¤   Local Variables:
8c7b17 ¤   tab-width: 4
080e6c ¤   End:
895f8c ¤   vi: ts=4 sw=4
769e9b ¤   vim: si
d7d062 _____________________*/
--f60a 00009710417401102fd Page 1 of proc.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
50c788 ¤   $Id: proc.c,v 1.51.2.1.2.1 1998/11/12 03:13:46 heller Exp $
b7af5a
edaf5a
7eaf5a
61f7f7 ____________________________________________________________________________*/
375ed8 #include "precomp.h"
ba90fb #include <commctrl.h>
49af5a
93c95d #define ICONSIZE 32
59af5a
e10dfd HFONT hFont;
4aaf5a
ba4646 BOOL IsOnTop(void);
370cb2 void RememberOnTop(BOOL bOnTop);
393584 void RememberPosition(HWND hwnd);
4c8216 void GetSavedPosition(POINT* pt, BOOL* bLarge);
e0af5a
829550 typedef struct _buttonstruct·
5dbb36 {
80ddab ¤   HWND hwndbutton;
493d13 ¤   unsigned int idbutton;
4be067 ¤   int showbutton;
74661d ¤   HWND hwndtext;
99a937 ¤   unsigned int idtext;
19e8d3 ¤   int showtext;
90f1ba ¤   char text[30];
ac87af ¤   unsigned int idicon;
3394ed ¤   int x;
3dce31 ¤   int y;
ce81d8 ¤   int dx;
ffdb04 ¤   int dy;
ac2a46 ¤   unsigned int L8idicon;
4e6a69 ¤   unsigned int L4idicon;
93eb53 ¤   int Lx;
78b18f ¤   int Ly;
68dd52 ¤   int Ldx;
d5878e ¤   int Ldy;
c155c8 ¤   unsigned int S8idicon;
9315e7 ¤   unsigned int S4idicon;
399a0b ¤   int Sx;
d3c0d7 ¤   int Sy;
d503ee ¤   int Sdx;
cb5932 ¤   int Sdy;
90ab44 } BUTTONSTRUCT;
d8af5a
b2765e HWND hwndToolTip=NULL;
a3af5a
935165 BOOL LargeMode;
5a3816 BOOL HighColor;
ecaf5a
e5af0c static BUTTONSTRUCT bd[]={
ab24d0 ¤   {0,IDC_KEYS ··,0,0,2000,0,"PGPkeys",
3039a1 ¤   ¤   ¤   ¤   ···0,0,0,0,0,
3262bc ¤   ···IDI_L8KEYS,IDI_L4KEYS ···, 0 ,1,46,46,
372f29 ¤   ···IDI_S8KEYS,IDI_S4KEYS ···, 0 ,1,25,25},
4d6b8b ¤   {0,IDC_ENCRYPT,0,0,2001,0,"Encrypt",
3a39a1 ¤   ¤   ¤   ¤   ···0,0,0,0,0,
8d5ed6 ¤   ···IDI_L8ENC,IDI_L4ENC ·····,46 ,1,46,46,
730762 ¤   ···IDI_S8ENC,IDI_S4ENC ·····,25 ,1,25,25},
92514b ¤   {0,IDC_SIGN ··,0,0,2002,0,"Sign",
c3c03d ¤   ···············0,0,0,0,0,
81e1af ¤   ···IDI_L8SIG,IDI_L4SIG ·····,92 ,1,46,46,
81fe81 ¤   ···IDI_S8SIG,IDI_S4SIG ·····,50 ,1,25,25},
93bcef ¤   {0,IDC_ENCSIGN,0,0,2003,0,"Encrypt & Sign",
09c03d ¤   ···············0,0,0,0,0,
--2133 000b0fc3c14401102fd Page 2 of proc.c
411b9e ¤   ···IDI_L8ENCSIG,IDI_L4ENCSIG,138,1,46,46,
affa36 ¤   ···IDI_S8ENCSIG,IDI_S4ENCSIG,75,1,25,25},
d723f5 ¤   {0,IDC_DECRYPT,0,0,2004,0,"Decrypt/Verify",
82c03d ¤   ···············0,0,0,0,0,
00fdb9 ¤   ···IDI_L8DECVER,IDI_L4DECVER,184,1,46,46,
db3e54 ¤   ···IDI_S8DECVER,IDI_S4DECVER,100,1,25,25},
34c402 ¤   {0,IDC_WIPE ··,0,0,2005,0,"Wipe",
46c03d ¤   ···············0,0,0,0,0,
51e862 ¤   ···IDI_L8WIPE,IDI_L4WIPE ···,230,1,46,46,
5b16e0 ¤   ···IDI_S8WIPE,IDI_S4WIPE ···,125,1,25,25},
67d017 ¤   {0,IDC_FREESPACE_WIPE ··,0,0,2006,0,"Freespace Wipe",
c8c03d ¤   ···············0,0,0,0,0,
ea508b ¤   ···IDI_L8WIPEV,IDI_L4WIPEV ·,276,1,46,46,
fd503d ¤   ···IDI_S8WIPEV,IDI_S4WIPEV ·,150,1,25,25}};
79af5a
08e1f5 #define numbuttons (sizeof(bd)/sizeof(bd[0]))
97af5a
cce372 LRESULT CALLBACK HiddenWndProc (HWND hwnd, UINT iMsg,·
906329 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   WPARAM wParam, LPARAM lParam)
eebb36 {
00ef45 ¤   ·RECT rc;
aba4ab ¤   ·
9701c2 ·····switch (iMsg)
03ac78 ·····{
d0b784 ·········case WM_CREATE :
e4af5a
b4cd77 ··¤ ¤   ¤   GetWindowRect (hwnd, &rc);
b2fd8b ¤   ¤   ¤   SetWindowPos (hwnd, NULL,
7c73f1 ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
25db5a ¤   ¤   ¤   ¤   (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2,
1df9f4 ¤   ¤   ¤   ¤   0, 0, SWP_NOSIZE | SWP_NOZORDER);
d3f999 ¤   ¤   ¤   ················
86092a ············return 0 ;
e809eb ¤   ·}
14d83c ·
5e0323 ····return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
0defe6 }
9caf5a
b4303a LRESULT WINAPI MyDropFilesProc(HWND hwnd, UINT msg,·
76270e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···WPARAM wParam, LPARAM lParam)
65bb36 {
0fd83c ·
719467 ¤   switch(msg)
5bc7a1 ¤   {
5b0dae ¤   ¤   case WM_DROPFILES:
e4f48a ¤   ¤   {¤  ¤
c2c954 ¤   ¤   ¤   HWND hwndDlg;
7320dc ¤   ¤   ¤   HDROP hDrop;
fa2492 ¤   ¤   ¤   int NumFiles,ReturnCode;
1f7d1d ¤   ¤   ¤   BOOL bEncrypt,bSign;
b016d5 ¤   ¤   ¤   FILELIST *ListHead;
98af5a
a5c08b ¤   ¤   ¤   hDrop=(HDROP)wParam;
4aaf5a
b69ac2 ¤   ¤   ¤   if(hDrop==0)
6746f1 ¤   ¤   ¤   ¤   return 0;
d8af5a
16ed8b ¤   ¤   ¤   NumFiles=DragQueryFile(hDrop,0xFFFFFFFF,NULL,0);
0d87c7 ¤   ¤   ¤
674388 ¤   ¤   ¤   if(NumFiles==0)
9046f1 ¤   ¤   ¤   ¤   return 0;
adaf5a
66d662 ¤   ¤   ¤   hwndDlg=GetParent(hwnd);
ffaf5a
2cd083 ¤   ¤   ¤   bEncrypt=bSign=FALSE;
93af5a
41fcad ¤   ¤   ¤   if(hwnd==GetDlgItem(hwndDlg,IDC_ENCRYPT))
4f2e71 ¤   ¤   ¤   ¤   bEncrypt = TRUE;
5baf5a
350cac ¤   ¤   ¤   if(hwnd==GetDlgItem(hwndDlg,IDC_SIGN))
2c549b ¤   ¤   ¤   ¤   bSign = TRUE;
b0af5a
--b728 0008a45733f401102fd Page 3 of proc.c
d7ba5b ¤   ¤   ¤   if(hwnd==GetDlgItem(hwndDlg,IDC_ENCSIGN))
159e26 ¤   ¤   ¤   ¤   bEncrypt = bSign = TRUE;
5daf5a
e1fb85 ¤   ¤   ¤   if ((hwnd==GetDlgItem(hwndDlg,IDC_ENCRYPT))||
c4cd7b ¤   ¤   ¤   ¤   (hwnd==GetDlgItem(hwndDlg,IDC_SIGN)) ··||
5c097a ¤   ¤   ¤   ¤   (hwnd==GetDlgItem(hwndDlg,IDC_ENCSIGN)))
7af776 ¤   ¤   ¤   {
0e53aa ¤   ¤   ¤   ¤   ListHead=HDropToFileList(hDrop);
8caf5a
de078f ¤   ¤   ¤   ¤   ReturnCode = EncryptFileList(hwndDlg,PGPsc,PGPtls,
dbe868 ¤   ¤   ¤   ¤   ¤   ListHead,
401171 ¤   ¤   ¤   ¤   ¤   bEncrypt,·
305ce3 ¤   ¤   ¤   ¤   ¤   bSign);
d0a3a6 ¤   ¤   ¤   }
d1af5a
75cbab ¤   ¤   ¤   if(hwnd==GetDlgItem(hwndDlg,IDC_KEYS))
faf776 ¤   ¤   ¤   {
cc53aa ¤   ¤   ¤   ¤   ListHead=HDropToFileList(hDrop);
caaf5a
674fee ¤   ¤   ¤   ¤   ReturnCode = AddKeyFileList(hwndDlg,PGPsc,PGPtls,
48d63b ¤   ¤   ¤   ¤   ¤   ListHead);
46a3a6 ¤   ¤   ¤   }
0daf5a
557947 ¤   ¤   ¤   if(hwnd==GetDlgItem(hwndDlg,IDC_DECRYPT))
50f776 ¤   ¤   ¤   {
8c53aa ¤   ¤   ¤   ¤   ListHead=HDropToFileList(hDrop);
b8af5a
10911a ¤   ¤   ¤   ¤   ReturnCode = DecryptFileList(hwndDlg,PGPsc,PGPtls,
41d63b ¤   ¤   ¤   ¤   ¤   ListHead);
25a3a6 ¤   ¤   ¤   }
d2af5a
ee2753 ¤   ¤   ¤   if(hwnd==GetDlgItem(hwndDlg,IDC_WIPE))
7cf776 ¤   ¤   ¤   {
4453aa ¤   ¤   ¤   ¤   ListHead=HDropToFileList(hDrop);
c82b85 ¤   ¤   ¤   ¤
25b06b ¤   ¤   ¤   ¤   ReturnCode = WipeFileList(hwndDlg,PGPsc,
87d63b ¤   ¤   ¤   ¤   ¤   ListHead);
83a3a6 ¤   ¤   ¤   }
0caf5a
9998da ¤   ¤   ¤   DragFinish(hDrop);
56af5a
5b8144 ¤   ¤   ¤   return 0;
650fe4 ¤   ¤   }
116fe7 ····}
9a583d ·····
cfc543 ¤   // ·Pass all non-custom messages to old window proc
881a72 ¤   return CallWindowProc((FARPROC)origButtonProc, hwnd,·
41c5fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   msg, wParam, lParam ) ;
36efe6 }
83af5a
a4ed9c BOOL CreateTooltips(HWND hWnd)
f0bb36 {
441137 ¤   TOOLINFO ti;
9a4ba4 ¤   int i;
a267c5 ¤
6283b3 ¤   if(hwndToolTip!=NULL)
1c983c ¤   ¤   DestroyWindow(hwndToolTip);
bdaf5a
34b007 ······/* create the tooltip window - we will use the default delays, but·
c0f0c1 ······if you want to change that, you can use the TTM_SETDELAYTIME·
91c056 ······message */
2b6ad9 ¤   hwndToolTip = CreateWindowEx( 0,·
08c091 ¤   ¤   TOOLTIPS_CLASS,·
86fcc1 ········NULL,·
6b9f4e ········WS_POPUP | TTS_ALWAYSTIP,·
488fe3 ········CW_USEDEFAULT,·
e58fe3 ········CW_USEDEFAULT,·
bea1a4 ········10,·
eea1a4 ········10,·
34d34b ········hWnd,·
fbfcc1 ········NULL,·
8a5d28 ········g_hinst,·
--9aa3 00058f640b3401102fd Page 4 of proc.c
8be010 ········NULL);
4ce8c6 ···
b398f9 ¤   for(i=0;i<numbuttons;i++)
d1c7a1 ¤   {
21d1a6 ¤   ¤   //add the button to the tooltip
e0a006 ¤   ¤   ZeroMemory(&ti, sizeof(ti));
295209 ¤   ¤   ti.cbSize = sizeof(ti);
69360a ¤   ¤   ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; ·
c0a906 ¤   ¤   //TTF_SUBCLASS causes the tooltip to automatically·
8e4a07 ¤   ¤   //subclass the window and look for the messages it·
82e61b ¤   ¤   //is interested in.
6f8587 ¤   ¤   ti.hwnd = hWnd;
9d2564 ¤   ¤   ti.uId = (UINT)bd[i].hwndbutton;
dae9e9 ¤   ¤   ti.lpszText = bd[i].text;
6476f1 ¤   ¤   SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
f89371 ¤   }
d6af5a
5ac2e7 ¤   return TRUE;
bcefe6 }
18af5a
b89be1 void MoveButtons(HWND hwnd)
4bbb36 {
ef4ba4 ¤   int i;
9cc8d1 ¤   int windowSizeX,windowSizeY;
155bda ¤   RECT rc;
bc8b53 ¤   int menuheight,captionheight;
29a112 ¤   int edgex,edgey;
b8af5a
2b98f9 ¤   for(i=0;i<numbuttons;i++)
aec7a1 ¤   {
d1c2f3 ¤   ¤   if(LargeMode)
725b34 ¤   ¤   {
056c35 ¤   ¤   ¤   if(HighColor)
b540b0 ¤   ¤   ¤   ¤   bd[i].idicon=bd[i].L8idicon;
b0bb8c ¤   ¤   ¤   else
97009f ¤   ¤   ¤   ¤   bd[i].idicon=bd[i].L4idicon;
5baf5a
eb6651 ¤   ¤   ¤   bd[i].x=bd[i].Lx;
a1b9d8 ¤   ¤   ¤   bd[i].y=bd[i].Ly;
299200 ¤   ¤   ¤   bd[i].dx=bd[i].Ldx;
18cd71 ¤   ¤   ¤   bd[i].dy=bd[i].Ldy;
820914 ¤   ¤   ¤   bd[i].showbutton=SW_SHOW;
dbf4ff ¤   ¤   ¤   bd[i].showtext=SW_HIDE;
e60fe4 ¤   ¤   }
090e1d ¤   ¤   else
eb5b34 ¤   ¤   {
e16c35 ¤   ¤   ¤   if(HighColor)
ff3f3e ¤   ¤   ¤   ¤   bd[i].idicon=bd[i].S8idicon;
efbb8c ¤   ¤   ¤   else
3c7f11 ¤   ¤   ¤   ¤   bd[i].idicon=bd[i].S4idicon;
9eaf5a
df1709 ¤   ¤   ¤   bd[i].x=bd[i].Sx;
79c880 ¤   ¤   ¤   bd[i].y=bd[i].Sy;
5c4cbc ¤   ¤   ¤   bd[i].dx=bd[i].Sdx;
a913cd ¤   ¤   ¤   bd[i].dy=bd[i].Sdy;
bc0914 ¤   ¤   ¤   bd[i].showbutton=SW_SHOW;
15f4ff ¤   ¤   ¤   bd[i].showtext=SW_HIDE;
700fe4 ¤   ¤   }
30af5a
cc8330 ¤   ¤   SendMessage(bd[i].hwndbutton,BM_SETIMAGE,(WPARAM)IMAGE_ICON,
126438 ¤   ¤   ¤   ¤   (LPARAM)LoadIcon(g_hinst,MAKEINTRESOURCE(bd[i].idicon)));
cc9371 ¤   }
b0af5a
d02091 ¤   edgex=GetSystemMetrics(SM_CXFIXEDFRAME);
37e424 ¤   edgey=GetSystemMetrics(SM_CYFIXEDFRAME);
c8af5a
def869 ¤   if(LargeMode)
83c7a1 ¤   {
d55e55 ¤   ¤   windowSizeX ·= numbuttons*bd[0].Ldx + edgex*2 + 2;
2c257c ¤   ¤   windowSizeY = bd[0].Ldy+ edgey*2 + 3;
279371 ¤   }
580e24 ¤   else
--079a 000c7a60d1b401102fd Page 5 of proc.c
f7c7a1 ¤   {
a9789c ¤   ¤   windowSizeX ·= numbuttons*bd[0].Sdx + edgex*2 + 2;
1fd62b ¤   ¤   windowSizeY = bd[0].Sdy+ edgey*2 + 3;
139371 ¤   }
c3af5a
609677 ¤   rc.left=0;
5ff742 ¤   rc.top=0;
b28b8d ¤   rc.right=windowSizeX;
cb971d ¤   rc.bottom=windowSizeY;
38af5a
9592d1 ¤   menuheight = GetSystemMetrics(SM_CYMENU);
2ad7bc ¤   captionheight= GetSystemMetrics(SM_CYCAPTION);
b7af5a
0da257 ¤   rc.bottom=rc.bottom+captionheight;·
6eaf5a
fb4c6a ¤   SetWindowPos (hwnd, NULL, 0, 0,rc.right,rc.bottom, SWP_NOMOVE|SWP_NOZORDER);
c9af5a
5998f9 ¤   for(i=0;i<numbuttons;i++)
c43b37 ····{
9d6d47 ¤   ¤   MoveWindow(bd[i].hwndbutton,
69aac4 ¤   ¤   ¤   bd[i].x,bd[i].y,
d24531 ¤   ¤   ¤   bd[i].dx,bd[i].dy,TRUE);
bdaf5a
a7370e ¤   ¤   MoveWindow(bd[i].hwndtext,
ffa4ac ¤   ¤   ¤   bd[i].x-5,bd[i].y+bd[i].dy+5,
d325d9 ¤   ¤   ¤   bd[i].dx+10,20,TRUE);
e4af5a
d7a1a2 ¤   ¤   ShowWindow(bd[i].hwndbutton,bd[i].showbutton);
b73815 ¤   ¤   ShowWindow(bd[i].hwndtext,bd[i].showtext);
8b9371 ¤   }
01af5a
d85300 ¤   CreateTooltips(hwnd);
2aefe6 }
a7af5a
cfdfa2 void LargePGPtools(void)
3ebb36 {
ebea5a ¤   LargeMode=TRUE;
f7efe6 }
f4af5a
aafa49 void SmallPGPtools(void)
29bb36 {
5dcc76 ¤   LargeMode=FALSE;
b6efe6 }
a9af5a
42af5a
ed2fa3 LRESULT CALLBACK PGPtoolsWndProc (HWND hwnd, UINT iMsg,·
279f1f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam, LPARAM lParam)
13bb36 {
14578a ¤   LONG Ret = NOERROR;
04a3e4 ¤   UINT cbFiles = 0;
c480a3 ¤   UINT i = 0;
35c594 ¤   UINT ReturnCode = TRUE;
97dbc4 ¤   static BOOL bOnTop = FALSE;
54813a ¤   char *p;
00af5a
b7a2d9 ¤   // See if user deselects caching via prefs
eb03d7 ¤   CheckForPurge(iMsg,wParam);
41af5a
be0f95 ¤   switch (iMsg)
773b37 ····{
9ab48e ¤   ¤   case WM_CREATE :
835b34 ¤   ¤   {
812c5a ¤   ¤   ¤   LOGFONT lf;
58c8bd ¤   ¤   ¤   int i;
7937f1 ¤   ¤   ¤   int iNumBits;
bd7f27 ¤   ¤   ¤   HDC hDC;
ff6318 ¤   ¤   ¤   HMENU hmenu = NULL;
491c2a ¤   ¤   ¤   POINT pt;
2f3b95 ¤   ¤   ¤   BOOL bIsLarge = FALSE;
7587c7 ¤   ¤   ¤
83c2fc ¤   ¤   ¤   //don't forget this
c7240d ¤   ¤   ¤   InitCommonControls();
--f7e9 0009989ef86401102fd Page 6 of proc.c
e0af5a
fb9e61 ¤   ¤   ¤   hDC = GetDC (NULL);¤¤   // DC for desktop
ed5727 ¤   ¤   ¤   iNumBits =·
36c868 ¤   ¤   ¤   ¤   GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
fc7ec4 ¤   ¤   ¤   ReleaseDC (NULL, hDC);
30af5a
6b6b69 ¤   ¤   ¤   if (iNumBits <= 8)
14cb07 ¤   ¤   ¤   ¤   HighColor=FALSE;
c3bb8c ¤   ¤   ¤   else
30a32d ¤   ¤   ¤   ¤   HighColor=TRUE;
a3af5a
8d1bbb ············SystemParametersInfo(SPI_GETICONTITLELOGFONT,
7ae7c2 ¤   ¤   ¤   ¤   sizeof(LOGFONT), &lf, 0);
82a67a ¤   ¤   ¤   hFont = CreateFontIndirect (&lf);
fbaf5a
1936a3 ·········¤  for(i=0;i<numbuttons;i++)
3039dc ·········¤  {
8bdb68 ¤   ¤   ¤   ¤   bd[i].hwndbutton=CreateWindow ("BUTTON", "",
65ce12 ····················WS_CHILD | WS_VISIBLE | BS_ICON, //BS_OWNERDRAW,
b7a6ed ····················0,0,0,0,
fcbaa5 ····················hwnd, (HMENU) bd[i].idbutton, g_hinst, NULL) ;·
63d83c ·
c4102c ¤   ¤   ¤   ¤   if(i!=6)
6e72c3 ¤   ¤   ¤   ¤   {
f9d962 ¤   ¤   ¤   ¤   ¤   DragAcceptFiles(bd[i].hwndbutton, TRUE);
c4ad44 ¤   ¤   ¤   ¤   ¤   origButtonProc=SubclassWindow(bd[i].hwndbutton,
35d29a ¤   ¤   ¤   ¤   ¤   ¤   MyDropFilesProc);
f42613 ¤   ¤   ¤   ¤   }
87af5a
594ea6 ¤   ¤   ¤   ¤   bd[i].hwndtext=CreateWindow ("STATIC",bd[i].text,
3ee1cd ····················WS_CHILD | WS_VISIBLE | SS_CENTER,
60a6ed ····················0,0,0,0,
ff870c ····················hwnd, (HMENU) bd[i].idtext,·
2ab590 ¤   ¤   ¤   ¤   ¤   g_hinst, NULL) ;·
11af5a
cc4d29 ¤   ¤   ¤   ¤   SendMessage(bd[i].hwndtext,WM_SETFONT,
99e6a7 ¤   ¤   ¤   ¤   ···(WPARAM)hFont,(LPARAM)MAKELPARAM(TRUE,0));
f0a3a6 ¤   ¤   ¤   }
33af5a
942e17 ¤   ¤   ¤   hmenu = GetSystemMenu(hwnd, FALSE);
5f1b52 ¤   ¤
1f44a5 ¤   ¤   ¤   AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
486a00 ¤   ¤   ¤   AppendMenu(hmenu, MF_STRING, IDM_STAYONTOP, "Stay On &Top");
6faf5a
6915a1 ¤   ¤   ¤   if(IsOnTop())
31f776 ¤   ¤   ¤   {
b551a5 ¤   ¤   ¤   ¤   SetWindowPos(¤  hwnd,·
e7e97f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   HWND_TOPMOST,·
4642d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
1942d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
b442d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
2a42d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
dada8e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOSIZE);
4eaf5a
7b81c3 ¤   ¤   ¤   ¤   bOnTop = TRUE;
6eaf5a
99d843 ¤   ¤   ¤   ¤   if(hmenu)
5b72c3 ¤   ¤   ¤   ¤   {
9ae6e5 ¤   ¤   ¤   ¤   ¤   CheckMenuItem(hmenu,·
8ef7a1 ¤   ¤   ¤   ¤   ¤   ¤   IDM_STAYONTOP, MF_BYCOMMAND|MF_CHECKED);
b42613 ¤   ¤   ¤   ¤   }
35a3a6 ¤   ¤   ¤   }
f5af5a
f106ac ¤   ¤   ¤   GetSavedPosition(&pt, &bIsLarge);
b8af5a
91b286 ¤   ¤   ¤   if(bIsLarge)
b9f776 ¤   ¤   ¤   {
426cf9 ¤   ¤   ¤   ¤   LargePGPtools();
c2a3a6 ¤   ¤   ¤   }
11bb8c ¤   ¤   ¤   else
d8f776 ¤   ¤   ¤   {
99d2e9 ¤   ¤   ¤   ¤   SmallPGPtools();
--d14b 000ffb130f1401102fd Page 7 of proc.c
cfa3a6 ¤   ¤   ¤   }
ccaf5a
c3049f ¤   ¤   ¤   MoveButtons(hwnd);
1daf5a
66eccc ¤   ¤   ¤   // wjb we want to make sure it will be on the screen! Otherwise
67b5dd ¤   ¤   ¤   // let the system decide....
78c255 ¤   ¤   ¤   if((pt.x>=0)&&(pt.y>=0)&&
e10320 ¤   ¤   ¤   ¤   (pt.x<GetSystemMetrics(SM_CXSCREEN))&&
7f54d3 ¤   ¤   ¤   ¤   (pt.y<GetSystemMetrics(SM_CYSCREEN)))
fcf776 ¤   ¤   ¤   {
9351a5 ¤   ¤   ¤   ¤   SetWindowPos(¤  hwnd,·
7a5d0a ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
aa4931 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pt.x,
1213ed ¤   ¤   ¤   ¤   ¤   ¤   ¤   pt.y,
16ceac ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
deceac ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
bacdee ¤   ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOSIZE|SWP_NOZORDER);
ef7812 ············}
fe87c7 ¤   ¤   ¤
7c092a ············return 0 ;
ed0fe4 ¤   ¤   }
abaf5a
2a900f ¤   ¤   case WM_SYSCOMMAND:
f65b34 ¤   ¤   {
104afd ¤   ¤   ¤   switch(wParam)
04f776 ¤   ¤   ¤   {
7d6f9c ¤   ¤   ¤   ¤   case IDM_STAYONTOP:
7d72c3 ¤   ¤   ¤   ¤   {
682db1 ¤   ¤   ¤   ¤   ¤   HMENU hmenu = NULL;
1405d7 ¤   ¤   ¤   ¤   ¤   UINT flags = 0;
46af5a
5f5fe9 ¤   ¤   ¤   ¤   ¤   SetWindowPos(¤  hwnd,·
e276b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (bOnTop ? HWND_NOTOPMOST: HWND_TOPMOST),·
f20320 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
650320 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
c10320 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
de0320 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,
0e55d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOMOVE|SWP_NOSIZE);
b2af5a
d45b68 ¤   ¤   ¤   ¤   ¤   bOnTop = !bOnTop;
52af5a
1ad37d ¤   ¤   ¤   ¤   ¤   RememberOnTop(bOnTop);
d2af5a
14edfa ¤   ¤   ¤   ¤   ¤   hmenu = GetSystemMenu(hwnd, FALSE);
35af5a
4d5117 ¤   ¤   ¤   ¤   ¤   if(hmenu)
324859 ¤   ¤   ¤   ¤   ¤   {
845cab ¤   ¤   ¤   ¤   ¤   ¤   flags = (bOnTop ?¤  MF_BYCOMMAND|MF_CHECKED :·
53936e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MF_BYCOMMAND|MF_UNCHECKED);
adaf5a
28e86d ¤   ¤   ¤   ¤   ¤   ¤   CheckMenuItem(hmenu, IDM_STAYONTOP, flags);
c11c89 ¤   ¤   ¤   ¤   ¤   }
7e14c3 ¤   ¤   ¤   ¤   ¤   break;
4d2613 ¤   ¤   ¤   ¤   }
2fa3a6 ¤   ¤   ¤   }
48cdcb ¤   ¤   ¤   break;
710fe4 ¤   ¤   }
33af5a
f52526 ¤   ¤   case WM_SIZE:
415b34 ¤   ¤   {
5a049f ¤   ¤   ¤   MoveButtons(hwnd);
afcdcb ¤   ¤   ¤   break;
0e0fe4 ¤   ¤   }
3faf5a
c54354 ¤   ¤   case WM_SIZING:
cd5b34 ¤   ¤   {
2336bf ¤   ¤   ¤   LPRECT DragRect = (LPRECT) lParam;
71ba2b ¤   ¤   ¤   int edgeX=GetSystemMetrics(SM_CXFIXEDFRAME);
e67e9e ¤   ¤   ¤   int edgeY=GetSystemMetrics(SM_CYFIXEDFRAME);
a63f8c ¤   ¤   ¤   int captionY = GetSystemMetrics(SM_CYCAPTION);
be247c ¤   ¤   ¤   int smallSizeX, smallSizeY, largeSizeX, largeSizeY;
ffaf5a
--fe91 000e285c946401102fd Page 8 of proc.c
c65968 ¤   ¤   ¤   largeSizeX ·= 324 + edgeX * 2; //278
c1c6a2 ¤   ¤   ¤   largeSizeY = 49 + edgeY * 2 + captionY;
0a1b52 ¤   ¤
1f53e7 ¤   ¤   ¤   smallSizeX= 177 + edgeX * 2; ·// 152
0df562 ¤   ¤   ¤   smallSizeY = 28 + edgeY*2 + captionY;
f1af5a
fbf003 ¤   ¤   ¤   if(DragRect)
aef776 ¤   ¤   ¤   {
c47b94 ¤   ¤   ¤   ¤   switch(wParam)¤ ¤   //side being resized;
c572c3 ¤   ¤   ¤   ¤   {
91df8f ¤   ¤   ¤   ¤   ¤   case WMSZ_BOTTOM:
7e94aa ¤   ¤   ¤   ¤   ¤   ¤
82254c ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) < largeSizeY - 5)
aa8fec ¤   ¤   ¤   ¤   ¤   ¤   {
1a46aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
e7ac3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + smallSizeX;
94af5a
9a6887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
d306b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
2cbe49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
96d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
3a5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
aedb3c ¤   ¤   ¤   ¤   ¤   ¤   }
afaf5a
1f2400 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) > smallSizeY + 5)
838fec ¤   ¤   ¤   ¤   ¤   ¤   {
ab9a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
2f709b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + largeSizeX;
57af5a
f61d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
f306b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
4a0059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
b5d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
9e5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
54db3c ¤   ¤   ¤   ¤   ¤   ¤   }
a7af5a
b400eb ¤   ¤   ¤   ¤   ¤   ¤   break;
40af5a
50755d ¤   ¤   ¤   ¤   ¤   case WMSZ_BOTTOMLEFT:
16af5a
00254c ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) < largeSizeY - 5)
ce8fec ¤   ¤   ¤   ¤   ¤   ¤   {
9346aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
a8965b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - smallSizeX;
ddaf5a
df6887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
9c06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
bbbe49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
89d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
7b5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
16db3c ¤   ¤   ¤   ¤   ¤   ¤   }
b6af5a
a22400 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) > smallSizeY + 5)
498fec ¤   ¤   ¤   ¤   ¤   ¤   {
8a9a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
a64afd ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - largeSizeX;
6daf5a
601d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
c406b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
0a0059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
a0d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
2a5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
bfdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
b0af5a
291a01 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) < largeSizeX - 5)
158fec ¤   ¤   ¤   ¤   ¤   ¤   {
90965b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - smallSizeX;
ab46aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
61af5a
8d6887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
cb06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
e2be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
--4970 000ec8079f0401102fd Page 9 of proc.c
43d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
905268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
bfdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
f3af5a
691b4d ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) > smallSizeX + 5)
9e8fec ¤   ¤   ¤   ¤   ¤   ¤   {
274afd ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - largeSizeX;
549a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
64af5a
c81d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
7406b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
bd0059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
f0d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
e05268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
52db3c ¤   ¤   ¤   ¤   ¤   ¤   }
3daf5a
4200eb ¤   ¤   ¤   ¤   ¤   ¤   break;
45af5a
5cd876 ¤   ¤   ¤   ¤   ¤   case WMSZ_BOTTOMRIGHT:
a0254c ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) < largeSizeY - 5)
748fec ¤   ¤   ¤   ¤   ¤   ¤   {
5846aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
60ac3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + smallSizeX;
81af5a
696887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
8e06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
d0be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
3ad770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
2a5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
1bdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
31af5a
3f2400 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) > smallSizeY + 5)
708fec ¤   ¤   ¤   ¤   ¤   ¤   {
979a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
12709b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + largeSizeX;
b6af5a
c51d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
1606b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
ca0059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
b8d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
355268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
2cdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
57af5a
a51a01 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) < largeSizeX - 5)
b08fec ¤   ¤   ¤   ¤   ¤   ¤   {
e9ac3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + smallSizeX;
c846aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
c4af5a
706887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
e006b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
0fbe49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
53d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
c65268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
91db3c ¤   ¤   ¤   ¤   ¤   ¤   }
13af5a
541b4d ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) > smallSizeX + 5)
108fec ¤   ¤   ¤   ¤   ¤   ¤   {
4b709b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + largeSizeX;
369a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
7aaf5a
ce1d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
9106b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
5e0059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
2ad770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
ac5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
f3db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ff00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
45af5a
9b30e8 ¤   ¤   ¤   ¤   ¤   case WMSZ_LEFT:
ef1a01 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) < largeSizeX - 5)
a98fec ¤   ¤   ¤   ¤   ¤   ¤   {
ec965b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - smallSizeX;
--cdda 00021f8d923401102fd Page 10 of proc.c
9446aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
c2af5a
3d6887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
d706b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
a4be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
b8d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
a05268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
ccdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
29af5a
591b4d ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) > smallSizeX + 5)
198fec ¤   ¤   ¤   ¤   ¤   ¤   {
d94afd ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - largeSizeX;
059a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
88af5a
d21d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
0806b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
670059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
bad770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
1b5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
16db3c ¤   ¤   ¤   ¤   ¤   ¤   }
a200eb ¤   ¤   ¤   ¤   ¤   ¤   break;
72af5a
613a15 ¤   ¤   ¤   ¤   ¤   case WMSZ_RIGHT:
431a01 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) < largeSizeX - 5)
788fec ¤   ¤   ¤   ¤   ¤   ¤   {
7eac3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + smallSizeX;
0446aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
2baf5a
086887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
6206b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
7ebe49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
69d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
e85268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
b2db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e8af5a
751b4d ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) > smallSizeX + 5)
608fec ¤   ¤   ¤   ¤   ¤   ¤   {
23709b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + largeSizeX;
6d9a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
51af5a
671d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
4806b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
d00059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
17d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
d05268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
34db3c ¤   ¤   ¤   ¤   ¤   ¤   }
3100eb ¤   ¤   ¤   ¤   ¤   ¤   break;
6aaf5a
aacc6f ¤   ¤   ¤   ¤   ¤   case WMSZ_TOP:
b6254c ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) < largeSizeY - 5)
e68fec ¤   ¤   ¤   ¤   ¤   ¤   {
d4cd36 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->top = DragRect->bottom - smallSizeY;
f7ac3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + smallSizeX;
93af5a
e06887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
fd06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
96be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
1bd770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
375268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
97db3c ¤   ¤   ¤   ¤   ¤   ¤   }
7daf5a
c42400 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) > smallSizeY + 5)
278fec ¤   ¤   ¤   ¤   ¤   ¤   {
e31190 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->top = DragRect->bottom - largeSizeY;
19709b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + largeSizeX;
67af5a
a11d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
1206b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
dd0059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
7ad770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
805268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
21db3c ¤   ¤   ¤   ¤   ¤   ¤   }
--6c98 00034ae5bdd401102fd Page 11 of proc.c
d300eb ¤   ¤   ¤   ¤   ¤   ¤   break;
c7af5a
52ab26 ¤   ¤   ¤   ¤   ¤   case WMSZ_TOPLEFT:
b8254c ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) < largeSizeY - 5)
518fec ¤   ¤   ¤   ¤   ¤   ¤   {
4ecd36 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->top = DragRect->bottom - smallSizeY;
50965b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - smallSizeX;
03af5a
f96887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
2d06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
28be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
54d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
f85268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
bddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
bbaf5a
7b2400 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) > smallSizeY + 5)
828fec ¤   ¤   ¤   ¤   ¤   ¤   {
371190 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->top = DragRect->bottom - largeSizeY;
5f4afd ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - largeSizeX;
c9af5a
951d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
8706b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
a90059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
9fd770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
6b5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
5cdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
49af5a
b01a01 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) < largeSizeX - 5)
038fec ¤   ¤   ¤   ¤   ¤   ¤   {
22965b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - smallSizeX;
fb46aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
b8af5a
876887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
8306b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
01be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
eed770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
ad5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
bddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
e2af5a
631b4d ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) > smallSizeX + 5)
628fec ¤   ¤   ¤   ¤   ¤   ¤   {
864afd ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->left = DragRect->right - largeSizeX;
979a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
dfaf5a
5d1d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
0d06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
f90059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
4ad770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
5c5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
43db3c ¤   ¤   ¤   ¤   ¤   ¤   }
fd00eb ¤   ¤   ¤   ¤   ¤   ¤   break;
18af5a
c415fc ¤   ¤   ¤   ¤   ¤   case WMSZ_TOPRIGHT:
58254c ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) < largeSizeY - 5)
a28fec ¤   ¤   ¤   ¤   ¤   ¤   {
6dcd36 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->top = DragRect->bottom - smallSizeY;
59ac3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + smallSizeX;
ecaf5a
3a6887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
e306b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
67be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
ecd770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
d75268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
92db3c ¤   ¤   ¤   ¤   ¤   ¤   }
afaf5a
172400 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->bottom - DragRect->top) > smallSizeY + 5)
e58fec ¤   ¤   ¤   ¤   ¤   ¤   {
431190 ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->top = DragRect->bottom - largeSizeY;
c9709b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + largeSizeX;
faaf5a
531d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
3406b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
--852e 0000c2fba30401102fd Page 12 of proc.c
4c0059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
74d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
b25268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
33db3c ¤   ¤   ¤   ¤   ¤   ¤   }
25af5a
ad1a01 ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) < largeSizeX - 5)
ab8fec ¤   ¤   ¤   ¤   ¤   ¤   {
e5ac3d ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + smallSizeX;
4146aa ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + smallSizeY;
8eaf5a
b66887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(LargeMode)
d306b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
f9be49 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
2bd770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
8f5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
f0db3c ¤   ¤   ¤   ¤   ¤   ¤   }
0daf5a
b31b4d ¤   ¤   ¤   ¤   ¤   ¤   if((DragRect->right - DragRect->left) > smallSizeX + 5)
128fec ¤   ¤   ¤   ¤   ¤   ¤   {
33709b ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->right = DragRect->left + largeSizeX;
889a0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   DragRect->bottom = DragRect->top + largeSizeY;
44af5a
3f1d26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(!LargeMode)
ba06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
210059 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
f0d770 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //MoveButtons(hwnd);
0d5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
41db3c ¤   ¤   ¤   ¤   ¤   ¤   }
6900eb ¤   ¤   ¤   ¤   ¤   ¤   break;
7e2613 ¤   ¤   ¤   ¤   }
90a3a6 ¤   ¤   ¤   }
548144 ¤   ¤   ¤   return 0;
850fe4 ¤   ¤   }
0aaf5a
978e1e ¤   ¤   case WM_COMMAND:
9f5b34 ¤   ¤   {
ee9164 ¤   ¤   ¤   switch(LOWORD(wParam))
f8f776 ¤   ¤   ¤   {
78b161 ¤   ¤   ¤   ¤   case IDC_RESIZE:
c272c3 ¤   ¤   ¤   ¤   {
00bb1a ¤   ¤   ¤   ¤   ¤   if(LargeMode)
f9ea6c ¤   ¤   ¤   ¤   ¤   ¤   SmallPGPtools();
a34bd6 ¤   ¤   ¤   ¤   ¤   else
02547c ¤   ¤   ¤   ¤   ¤   ¤   LargePGPtools();
2faf5a
fdc913 ¤   ¤   ¤   ¤   ¤   MoveButtons(hwnd);
5714c3 ¤   ¤   ¤   ¤   ¤   break;
f52613 ¤   ¤   ¤   ¤   }
6caf5a
4238c6 ¤   ¤   ¤   ¤   case IDC_EDITCLIP:
a572c3 ¤   ¤   ¤   ¤   {
a1e9d9 ¤   ¤   ¤   ¤   ¤   LaunchInternalViewer(hwnd);
5a14c3 ¤   ¤   ¤   ¤   ¤   break;
bf2613 ¤   ¤   ¤   ¤   }
7787c7 ¤   ¤   ¤
98ea1d ¤   ¤   ¤   ¤   case IDC_HELPTOPICS:
b572c3 ¤   ¤   ¤   ¤   {
747c37 ¤   ¤   ¤   ¤   ¤   char HelpFile[MAX_PATH];
46af5a
c4db46 ¤   ¤   ¤   ¤   ¤   PGPpath(HelpFile);
1e0cef ¤   ¤   ¤   ¤   ¤   strcat(HelpFile,"PGP60.hlp");
0baf5a
53ca2d ¤   ¤   ¤   ¤   ¤   WinHelp(hwnd, HelpFile, HELP_FINDER, 0);
7914c3 ¤   ¤   ¤   ¤   ¤   break;
e32613 ¤   ¤   ¤   ¤   }
22af5a
747247 ¤   ¤   ¤   ¤   case IDC_PGPPREFS:
6772c3 ¤   ¤   ¤   ¤   {
43978f ¤   ¤   ¤   ¤   ¤   PGPscPreferences(hwnd,PGPsc,PGPtls);
9914c3 ¤   ¤   ¤   ¤   ¤   break;
992613 ¤   ¤   ¤   ¤   }
0caf5a
--18b1 0007813ba8a401102fd Page 13 of proc.c
b39d72 ¤   ¤   ¤   ¤   case IDC_ABOUTPGP:
fe72c3 ¤   ¤   ¤   ¤   {
639e2a ¤   ¤   ¤   ¤   ¤   PGPscAbout(hwnd,PGPsc);
a014c3 ¤   ¤   ¤   ¤   ¤   break;
742613 ¤   ¤   ¤   ¤   }
abaf5a
b20012 ¤   ¤   ¤   ¤   case IDC_KEYS:
c272c3 ¤   ¤   ¤   ¤   {
8f7411 ¤   ¤   ¤   ¤   ¤   DoLaunchKeys(hwnd);
6d14c3 ¤   ¤   ¤   ¤   ¤   break;
2f2613 ¤   ¤   ¤   ¤   }
2eaf5a
ada5ec ¤   ¤   ¤   ¤   case IDC_ENCRYPT:
1d03c3 ¤   ¤   ¤   ¤   case IDC_SIGN:
7077e8 ¤   ¤   ¤   ¤   case IDC_ENCSIGN:
3f72c3 ¤   ¤   ¤   ¤   {
7e4598 ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt,bSign;
85587c ¤   ¤   ¤   ¤   ¤   FILELIST *ListHead;
bfedec ¤   ¤   ¤   ¤   ¤   char Prompt[100];
1dcbda ¤   ¤   ¤   ¤   ¤   char Filter[100];
f8af5a
16174d ¤   ¤   ¤   ¤   ¤   ListHead=0;
e8031e ¤   ¤   ¤   ¤   ¤   bEncrypt=bSign=FALSE;
31af5a
a99096 ¤   ¤   ¤   ¤   ¤   if(LOWORD(wParam)==IDC_ENCRYPT)
6b4859 ¤   ¤   ¤   ¤   ¤   {
bd16f4 ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt = TRUE;
ef85a4 ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SELFILEENC, Prompt, sizeof(Pro¶
9b636d mpt));
d81c89 ¤   ¤   ¤   ¤   ¤   }
59af5a
11a0ef ¤   ¤   ¤   ¤   ¤   if(LOWORD(wParam)==IDC_SIGN)
824859 ¤   ¤   ¤   ¤   ¤   {
108ce0 ¤   ¤   ¤   ¤   ¤   ¤   bSign = TRUE;
0e668f ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SELFILESIGN, Prompt, sizeof(Pr¶
ce01de ompt));
c01c89 ¤   ¤   ¤   ¤   ¤   }
31af5a
9e4292 ¤   ¤   ¤   ¤   ¤   if(LOWORD(wParam)==IDC_ENCSIGN)
644859 ¤   ¤   ¤   ¤   ¤   {
29ca03 ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt = bSign = TRUE;
b004bb ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SELFILEENCSIGN, Prompt, sizeof¶
bba9e3 (Prompt));
da1c89 ¤   ¤   ¤   ¤   ¤   }
80af5a
b03f35 ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_ALLFILES, Filter, sizeof(Filter));
26ef51 ¤   ¤   ¤   ¤   ¤   while (p = strrchr (Filter, '@')) *p = '\0';
e1af5a
b424e3 ¤   ¤   ¤   ¤   ¤   if(GetFileName(hwnd,
f476b8 ¤   ¤   ¤   ¤   ¤   ¤   Prompt,
b33d10 ¤   ¤   ¤   ¤   ¤   ¤   &ListHead,TRUE,
9217b5 ¤   ¤   ¤   ¤   ¤   ¤   Filter))
ba4859 ¤   ¤   ¤   ¤   ¤   {
e08886 ¤   ¤   ¤   ¤   ¤   ¤   if(ListHead==0)
ab8fec ¤   ¤   ¤   ¤   ¤   ¤   {
17f91c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReturnCode = EncryptClipboard(hwnd,PGPsc,PGPtls, bE¶
c159a9 ncrypt, bSign);
42db3c ¤   ¤   ¤   ¤   ¤   ¤   }
367f8b ¤   ¤   ¤   ¤   ¤   ¤   else
478fec ¤   ¤   ¤   ¤   ¤   ¤   {
c17445 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReturnCode = EncryptFileList(hwnd,PGPsc,PGPtls,
0a0cfd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ListHead,
ded2b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bEncrypt,·
7abf14 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bSign);
71db3c ¤   ¤   ¤   ¤   ¤   ¤   }
b8ba23 ¤   ¤   ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤
bd14c3 ¤   ¤   ¤   ¤   ¤   break;
f253b0 ¤   ¤   ¤   ¤   } ·
b6af5a
504f7d ¤   ¤   ¤   ¤   case IDC_DECRYPT:
f472c3 ¤   ¤   ¤   ¤   {
78587c ¤   ¤   ¤   ¤   ¤   FILELIST *ListHead;
--5b63 0009038dab4401102fd Page 14 of proc.c
1dedec ¤   ¤   ¤   ¤   ¤   char Prompt[100];
3dc7a7 ¤   ¤   ¤   ¤   ¤   char Filter[200];
e8af5a
e6174d ¤   ¤   ¤   ¤   ¤   ListHead=0;
eeaf5a
706ddb ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SELFILEDECVER, Prompt, sizeof(Prom¶
ade9a7 pt));
f1b1e2 ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_PGPFILES, Filter, sizeof(Filter));
e2ef51 ¤   ¤   ¤   ¤   ¤   while (p = strrchr (Filter, '@')) *p = '\0';
e7af5a
6824e3 ¤   ¤   ¤   ¤   ¤   if(GetFileName(hwnd,
0f76b8 ¤   ¤   ¤   ¤   ¤   ¤   Prompt,
d53d10 ¤   ¤   ¤   ¤   ¤   ¤   &ListHead,TRUE,
d217b5 ¤   ¤   ¤   ¤   ¤   ¤   Filter))
504859 ¤   ¤   ¤   ¤   ¤   {
5b8886 ¤   ¤   ¤   ¤   ¤   ¤   if(ListHead==0)
cc8fec ¤   ¤   ¤   ¤   ¤   ¤   {
0162b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReturnCode = DecryptClipboard(hwnd,PGPsc,PGPtls);
54db3c ¤   ¤   ¤   ¤   ¤   ¤   }
957f8b ¤   ¤   ¤   ¤   ¤   ¤   else
5a8fec ¤   ¤   ¤   ¤   ¤   ¤   {
d515d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReturnCode = DecryptFileList(hwnd,PGPsc,PGPtls,
bed3fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ListHead);¤
cddb3c ¤   ¤   ¤   ¤   ¤   ¤   }
bdba23 ¤   ¤   ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤
dc14c3 ¤   ¤   ¤   ¤   ¤   break;
c39094 ¤   ¤   ¤   ¤   } ··
6baf5a
f2ae49 ¤   ¤   ¤   ¤   case IDC_WIPE:
0d72c3 ¤   ¤   ¤   ¤   {
744859 ¤   ¤   ¤   ¤   ¤   {
ffd01a ¤   ¤   ¤   ¤   ¤   ¤   FILELIST *ListHead;
dfd102 ¤   ¤   ¤   ¤   ¤   ¤   char Prompt[100];
6bfb49 ¤   ¤   ¤   ¤   ¤   ¤   char Filter[200];
dfaf5a
779cb1 ¤   ¤   ¤   ¤   ¤   ¤   ListHead=0;
50af5a
999f7c ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SELFILEWIPE, Prompt, sizeof(Pr¶
ed01de ompt));
3fea94 ¤   ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_ALLFILES, Filter, sizeof(Filte¶
00173e r));
076514 ¤   ¤   ¤   ¤   ¤   ¤   while (p = strrchr (Filter, '@')) *p = '\0';
dbaf5a
5a225b ¤   ¤   ¤   ¤   ¤   ¤   if(GetFileName(hwnd,
dbfd44 ¤   ¤   ¤   ¤   ¤   ¤   ¤   Prompt,
9cf64e ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ListHead,FALSE,
732add ¤   ¤   ¤   ¤   ¤   ¤   ¤   Filter))
3f8fec ¤   ¤   ¤   ¤   ¤   ¤   {
b5c390 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if(ListHead!=0)
8a06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
bcf8e1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReturnCode = WipeFileList(hwnd,PGPsc,
4dcbac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ListHead);¤
335268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
fcdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
421c89 ¤   ¤   ¤   ¤   ¤   }
1e14c3 ¤   ¤   ¤   ¤   ¤   break;
f02613 ¤   ¤   ¤   ¤   }
73af5a
e0ed2b ¤   ¤   ¤   ¤   case IDC_FREESPACE_WIPE:
8872c3 ¤   ¤   ¤   ¤   {
9e945a ¤   ¤   ¤   ¤   ¤   FreeSpaceWipeWizard(hwnd, PGPsc);
a414c3 ¤   ¤   ¤   ¤   ¤   break;
f32613 ¤   ¤   ¤   ¤   }
beaf5a
eae69b ¤   ¤   ¤   ¤   case IDC_ADDKEY:
b072c3 ¤   ¤   ¤   ¤   {
ef587c ¤   ¤   ¤   ¤   ¤   FILELIST *ListHead;
d2edec ¤   ¤   ¤   ¤   ¤   char Prompt[100];
02c7a7 ¤   ¤   ¤   ¤   ¤   char Filter[200];
18af5a
87174d ¤   ¤   ¤   ¤   ¤   ListHead=0;
90af5a
--1e69 00046566a02401102fd Page 15 of proc.c
bef3d3 ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_SELFILEADD, Prompt, sizeof(Prompt)¶
bf6275 );
f6ec12 ¤   ¤   ¤   ¤   ¤   LoadString (g_hinst, IDS_KEYFILES, Filter, sizeof(Filter));
28ef51 ¤   ¤   ¤   ¤   ¤   while (p = strrchr (Filter, '@')) *p = '\0';
86af5a
7124e3 ¤   ¤   ¤   ¤   ¤   if(GetFileName(hwnd,
d676b8 ¤   ¤   ¤   ¤   ¤   ¤   Prompt,
a73d10 ¤   ¤   ¤   ¤   ¤   ¤   &ListHead,TRUE,
3d17b5 ¤   ¤   ¤   ¤   ¤   ¤   Filter))
a24859 ¤   ¤   ¤   ¤   ¤   {
2c8886 ¤   ¤   ¤   ¤   ¤   ¤   if(ListHead==0)
048fec ¤   ¤   ¤   ¤   ¤   ¤   {
1f31d8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReturnCode = AddKeyClipboard(hwnd,PGPsc,PGPtls);
79db3c ¤   ¤   ¤   ¤   ¤   ¤   }
337f8b ¤   ¤   ¤   ¤   ¤   ¤   else
758fec ¤   ¤   ¤   ¤   ¤   ¤   {
e57a75 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ReturnCode = AddKeyFileList(hwnd,PGPsc,PGPtls,
c2d3fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ListHead);¤
16db3c ¤   ¤   ¤   ¤   ¤   ¤   }
bcba23 ¤   ¤   ¤   ¤   ¤   }¤  ¤   ¤   ¤   ¤
9014c3 ¤   ¤   ¤   ¤   ¤   break;
962613 ¤   ¤   ¤   ¤   }
90af5a
bb9048 ¤   ¤   ¤   ¤   case IDC_QUIT:
c172c3 ¤   ¤   ¤   ¤   {
1b1e62 ¤   ¤   ¤   ¤   ¤   PostQuitMessage (0) ;
de14c3 ¤   ¤   ¤   ¤   ¤   break;
d12613 ¤   ¤   ¤   ¤   }
ced11f ¤   ¤   ¤   } ··
b2cdcb ¤   ¤   ¤   break;
9d0fe4 ¤   ¤   }
418c17 ···············¤¤   ¤   ··
c72c97 ¤   ¤   case WM_CLOSE:
81a481 ¤   ¤   case WM_DESTROY :
f85b34 ¤   ¤   {
aaf070 ¤   ¤   ¤   RememberPosition(hwnd);
28c7dd ¤   ¤   ¤   DeleteObject(hFont);
51cdff ¤   ¤   ¤   PostQuitMessage (0) ;
432519 ¤   ¤   ¤   return 0 ; ····
f40fe4 ¤   ¤   }
4e9371 ¤   }
12d83c ·
010323 ····return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
5fefe6 }
f7af5a
5ff2cc void RememberOnTop(BOOL bOnTop)
56bb36 {
0341d8 ¤   HKEY¤   hKey;
be4d65 ¤   LONG¤   lResult;
5ee36f ¤   DWORD¤  dw = 0;
46a474 ¤   char¤   path[] = "Software\\Network Associates\\PGP60\\PGPtools";
cb67c5 ¤
deb6ea ¤   dw = bOnTop;
a3af5a
2c8e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
b9a953 ¤   ¤   ¤   ¤   ¤   ¤   ¤   path,·
934ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
a12cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
5ea698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
d1af5a
35d84a ¤   if (lResult == ERROR_SUCCESS)·
41c7a1 ¤   {
5becda ¤   ¤   RegSetValueEx (¤hKey,·
69d3ee ¤   ¤   ¤   ¤   ¤   ¤   "StayOnTop",·
86e7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
b83bd6 ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
d44d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
5afcfa ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
fa9371 ¤   }
5befe6 }
f6af5a
46be73 BOOL IsOnTop()
--5497 0003b4d0f72401102fd Page 16 of proc.c
2cbb36 {
1e41d8 ¤   HKEY¤   hKey;
f94d65 ¤   LONG¤   lResult;
082c19 ¤   DWORD¤  dw;
9ca474 ¤   char¤   path[] = "Software\\Network Associates\\PGP60\\PGPtools";
e8af5a
058e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
cca953 ¤   ¤   ¤   ¤   ¤   ¤   ¤   path,·
d14ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
e82cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
2aa698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
8aaf5a
5dd84a ¤   if (lResult == ERROR_SUCCESS)·
04c7a1 ¤   {
18fa9a ¤   ¤   DWORD ·size = sizeof(dw);
a0fde9 ¤   ¤   DWORD ·type = 0;
5faf5a
f4db45 ¤   ¤   RegQueryValueEx(hKey,·
c9d3ee ¤   ¤   ¤   ¤   ¤   ¤   "StayOnTop",·
8ae7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
503ce1 ¤   ¤   ¤   ¤   ¤   ¤   &type,·
fb4d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
f1e930 ¤   ¤   ¤   ¤   ¤   ¤   &size);
dd9371 ¤   }
448b92 ¤   else // Init Values
73c7a1 ¤   {
d39b9d ¤   ¤   lResult = RegCreateKeyEx (¤ HKEY_CURRENT_USER,·
9ce6ec ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   path,·
cb044d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
074a56 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,
0b002b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   REG_OPTION_NON_VOLATILE,·
b92d7c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
7d12b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL,·
a6f77a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey,·
935ba4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dw);
83af5a
b499b9 ¤   ¤   if (lResult == ERROR_SUCCESS)·
385b34 ¤   ¤   {
ba7e20 ¤   ¤   ¤   dw = 0;
2daf5a
ed60a5 ¤   ¤   ¤   RegSetValueEx (¤hKey,·
e2ef00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   "StayOnTop",·
fc4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
a4fe83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
cf7173 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
e1f917 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
0a66a4 ¤   ¤   ¤   dw = 110;
d3af5a
8c60a5 ¤   ¤   ¤   RegSetValueEx (¤hKey,·
940bb6 ¤   ¤   ¤   ¤   ¤   ¤   "xPos",·
8de7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
1d3bd6 ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
914d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
9ffcfa ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
2faf5a
ef24fc ¤   ¤   ¤   dw = 1;
93af5a
2f60a5 ¤   ¤   ¤   RegSetValueEx (¤hKey,·
148a09 ¤   ¤   ¤   ¤   ¤   ¤   "yPos",·
4de7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
3b3bd6 ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
b34d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
53fcfa ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
49af5a
3924fc ¤   ¤   ¤   dw = 1;
daaf5a
b960a5 ¤   ¤   ¤   RegSetValueEx (¤hKey,·
6bdf2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   "size",·
c84ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
f1fe83 ¤   ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
db7173 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
3bf917 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
--7262 000c20e7418401102fd Page 17 of proc.c
e0af5a
c2233e ¤   ¤   ¤   RegCloseKey (hKey);
25af5a
c60fe4 ¤   ¤   }
469371 ¤   }
88af5a
ed7fc0 ¤   return (BOOL)dw;
4fefe6 }
5caf5a
020774 void RememberPosition(HWND hwnd)
22bb36 {
8f41d8 ¤   HKEY¤   hKey;
f24d65 ¤   LONG¤   lResult;
7fe36f ¤   DWORD¤  dw = 0;
0aa474 ¤   char¤   path[] = "Software\\Network Associates\\PGP60\\PGPtools";
c628d8 ¤   RECT rect;
56af5a
b34543 ¤   GetWindowRect(hwnd, &rect);
3b67c5 ¤
6faf5a
e48e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
4fa953 ¤   ¤   ¤   ¤   ¤   ¤   ¤   path,·
1c4ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
872cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
27a698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
d3af5a
d6d84a ¤   if (lResult == ERROR_SUCCESS)·
c8c7a1 ¤   {
3d1650 ¤   ¤   dw = rect.left;
eeaf5a
acecda ¤   ¤   RegSetValueEx (¤hKey,·
9e0bb6 ¤   ¤   ¤   ¤   ¤   ¤   "xPos",·
ade7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
fd3bd6 ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
ec4d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
cdfcfa ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
b9af5a
d0655a ¤   ¤   dw = rect.top;
4caf5a
ebecda ¤   ¤   RegSetValueEx (¤hKey,·
3d8a09 ¤   ¤   ¤   ¤   ¤   ¤   "yPos",·
a3e7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
c53bd6 ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
d34d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
9cfcfa ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
d1af5a
b98547 ¤   ¤   dw = LargeMode;
7baf5a
96ecda ¤   ¤   RegSetValueEx (¤hKey,·
aae246 ¤   ¤   ¤   ¤   ¤   ¤   "size",·
7ae7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
103bd6 ¤   ¤   ¤   ¤   ¤   ¤   REG_DWORD,·
ac4d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
cdfcfa ¤   ¤   ¤   ¤   ¤   ¤   sizeof(dw));
589371 ¤   }
06af5a
f1efe6 }
a2af5a
eb0ee6 void GetSavedPosition(POINT* pt, BOOL* bLarge)
9cbb36 {
3941d8 ¤   HKEY¤   hKey;
244d65 ¤   LONG¤   lResult;
752c19 ¤   DWORD¤  dw;
1ca474 ¤   char¤   path[] = "Software\\Network Associates\\PGP60\\PGPtools";
e0af5a
6f8e19 ¤   lResult = RegOpenKeyEx(¤HKEY_CURRENT_USER,
dda953 ¤   ¤   ¤   ¤   ¤   ¤   ¤   path,·
834ae4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0,·
722cfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   KEY_ALL_ACCESS,·
5fa698 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hKey);
63af5a
c2d84a ¤   if (lResult == ERROR_SUCCESS)·
--90d0 001392db7d2401102fd Page 18 of proc.c
f7c7a1 ¤   {
f1fa9a ¤   ¤   DWORD ·size = sizeof(dw);
93fde9 ¤   ¤   DWORD ·type = 0;
e1af5a
3edb45 ¤   ¤   RegQueryValueEx(hKey,·
bc0bb6 ¤   ¤   ¤   ¤   ¤   ¤   "xPos",·
2fe7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
363ce1 ¤   ¤   ¤   ¤   ¤   ¤   &type,·
2c4d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
9ce930 ¤   ¤   ¤   ¤   ¤   ¤   &size);
122056 ¤   ¤   pt->x = dw;
abbc4f ¤   ¤   size = sizeof(dw);
a5af5a
36db45 ¤   ¤   RegQueryValueEx(hKey,·
b98a09 ¤   ¤   ¤   ¤   ¤   ¤   "yPos",·
36e7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
f73ce1 ¤   ¤   ¤   ¤   ¤   ¤   &type,·
bd4d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
bae930 ¤   ¤   ¤   ¤   ¤   ¤   &size);
24a1e9 ¤   ¤   pt->y = dw;
75bc4f ¤   ¤   size = sizeof(dw);
13af5a
19db45 ¤   ¤   RegQueryValueEx(hKey,·
75e246 ¤   ¤   ¤   ¤   ¤   ¤   "size",·
1be7ba ¤   ¤   ¤   ¤   ¤   ¤   0,·
9f3ce1 ¤   ¤   ¤   ¤   ¤   ¤   &type,·
484d9d ¤   ¤   ¤   ¤   ¤   ¤   (LPBYTE)&dw,·
d4e930 ¤   ¤   ¤   ¤   ¤   ¤   &size);
c7af5a
6dd7fa ¤   ¤   *bLarge = dw;
19af5a
f48e60 ¤   ¤   RegCloseKey (hKey);
be9371 ¤   }
25efe6 }
0caf5a
93af5a
b77e4d /*__Editor_settings____
e5af5a
8d4126 ¤   Local Variables:
fa7b17 ¤   tab-width: 4
4f0e6c ¤   End:
4f5f8c ¤   vi: ts=4 sw=4
d39e9b ¤   vim: si
39d062 _____________________*/
--a057 00110267157401102fe Page 1 of proc.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8a2437 ¤   $Id: proc.h,v 1.2.16.1 1998/11/12 03:13:47 heller Exp $
32f7f7 ____________________________________________________________________________*/
2b62be #ifndef Included_PROC_h¤/* [ */
d508aa #define Included_PROC_h
3faf5a
4de372 LRESULT CALLBACK HiddenWndProc (HWND hwnd, UINT iMsg,·
98aa7e ¤   ¤   ¤   ¤   ¤   WPARAM wParam, LPARAM lParam);
40af5a
ba303a LRESULT WINAPI MyDropFilesProc(HWND hwnd, UINT msg,·
59aa7e ¤   ¤   ¤   ¤   ¤   WPARAM wParam, LPARAM lParam);
0caf5a
3c2fa3 LRESULT CALLBACK PGPtoolsWndProc (HWND hwnd, UINT iMsg,·
27aa7e ¤   ¤   ¤   ¤   ¤   WPARAM wParam, LPARAM lParam);
2daf5a
14f15a #endif /* ] Included_PROC_h */
0aaf5a
c9af5a
977e4d /*__Editor_settings____
30af5a
384126 ¤   Local Variables:
617b17 ¤   tab-width: 4
ae0e6c ¤   End:
175f8c ¤   vi: ts=4 sw=4
229e9b ¤   vim: si
10d062 _____________________*/
--abef 000bc7c867f401102ff Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
7b2718 // Used by PGPtools.rc
d3465d //
1f5637 #define IDS_SELFILEENC ·················1
d93fd1 #define IDS_SELFILESIGN ················2
280e36 #define IDS_SELFILEENCSIGN ·············3
476214 #define IDS_ALLFILES ···················4
010f56 #define IDS_SELFILEDECVER ··············5
727d09 #define IDS_PGPFILES ···················6
173fa5 #define IDS_SELFILEWIPE ················7
070a3b #define IDS_SELFILEADD ·················8
2afbb4 #define IDS_KEYFILES ···················9
745234 #define IDS_NOVOLWIPENT ················10
46ee37 #define IDS_PGPERROR ···················11
b46c63 #define IDI_TOOLSICO ···················101
5918b8 #define IDI_KEYS ·······················102
2f8f25 #define IDI_ENCRYPT ····················103
e6795e #define IDI_SIGN ·······················104
64654f #define IDI_ENCSIGN ····················105
8ed874 #define IDI_DECRYPT ····················106
e089d9 #define IDI_WIPE ·······················107
6742ea #define IDD_CUST32DLG ··················109
f21a32 #define IDD_CUST16DLG ··················110
97cefc #define IDD_EXPCLIPCHILD ···············111
879dbc #define IDR_PGPTOOLSMENU ···············116
9167c2 #define IDR_ACCELERATOR1 ···············117
392a6d #define IDC_KEYS ·······················201
338e40 #define IDC_ENCRYPT ····················202
b72ceb #define IDC_SIGN ·······················203
f6642a #define IDC_ENCSIGN ····················204
d5eaa1 #define IDC_DECRYPT ····················205
5d88bc #define IDC_WIPE ·······················206
5514a9 #define IDC_FREESPACE_WIPE ·············207
e22dee #define IDC_QUIT ·······················208
4f5fba #define IDC_ADDKEY ·····················209
033892 #define IDI_SMENC ······················209
53bbc6 #define IDI_SMSIGN ·····················210
5829ac #define IDI_SMENCSIG ···················211
817df7 #define IDI_SMKEYS ·····················212
284d70 #define IDI_SMDEC ······················213
17d084 #define IDI_SMWIPE ·····················214
f2f602 #define IDI_L4KEY ······················218
00679a #define IDI_L4KEYS ·····················218
c3531b #define IDI_L8KEYS ·····················220
5ffead #define IDI_S4KEYS ·····················221
ca8c2d #define IDI_L4WIPE ·····················222
ea219b #define IDI_S8WIPE ·····················223
00cdd8 #define IDI_L8WIPE ·····················224
04606e #define IDI_S4WIPE ·····················225
2afcda #define IDI_L8ENC ······················226
dcf027 #define IDI_L4ENC ······················227
ac640c #define IDI_L8SIG ······················228
6d68f1 #define IDI_L4SIG ······················229
ca9371 #define IDI_L8DECVER ···················230
5d9f8c #define IDI_L4DECVER ···················231
ef4444 #define IDI_L8ENCSIG ···················232
b905b1 #define IDI_L4ENCSIG ···················234
b5a807 #define IDI_S8ENCSIG ···················235
f2974a #define IDI_S4ENCSIG ···················236
291e95 #define IDI_S8ENC ······················237
178878 #define IDI_S4ENC ······················238
4e8643 #define IDI_S8SIG ······················239
8fc87b #define IDI_S4SIG ······················240
2fa7e7 #define IDI_S8DECVER ···················241
de98aa #define IDI_S4DECVER ···················242
530ee1 #define IDI_S8KEYS ·····················243
ebd7c2 #define IDI_L4WIPEV ····················244
9c6f51 #define IDI_S4WIPEV ····················245
22f157 #define IDI_L8WIPEV ····················246
3749c4 #define IDI_S8WIPEV ····················247
bc668c #define IDC_PGPPREFS ···················400
--9b6e 0016d958e52401102ff Page 2 of resource.h
f0a3cb #define IDC_EDITCLIP ···················401
979232 #define IDC_ASSOCVIEWER ················402
3c5e85 #define IDC_HELPTOPICS ·················403
506c9d #define IDC_ABOUTPGP ···················404
04b458 #define IDC_ASSOCVIEW ··················405
cdef09 #define IDC_RESIZE ·····················407
cfa670 #define IDC_CLIPBOARD ··················1000
2eaf5a
9f11aa // Next default values for new objects
acac6a //·
d0f860 #ifdef APSTUDIO_INVOKED
223f23 #ifndef APSTUDIO_READONLY_SYMBOLS
6088bf #define _APS_NEXT_RESOURCE_VALUE ·······244
ad4882 #define _APS_NEXT_COMMAND_VALUE ········408
81918c #define _APS_NEXT_CONTROL_VALUE ········1004
c1fceb #define _APS_NEXT_SYMED_VALUE ··········308
787454 #endif
6d7454 #endif
--ce94 000150883e640110300 Page 1 of TLMisc.c
e17df8 //: TreeList memory allocation and miscellaneous routines
bb465d //
af1912 //¤ $Id: TLMisc.c,v 1.15 1998/08/13 23:18:59 pbj Exp $
5f465d //
02af5a
96fb2c #include "TLintern.h"
f95e84 #include <malloc.h>
12c737 #include <memory.h>
c7af5a
0daf5a
98bf56 //----------------------------------------------------|
3708e6 // Private memory allocation routine
b4af5a
26df8f void* TLAlloc (long size) {
e78418 ¤   void* p;
86c01a ¤   p = malloc (size);
57f0dd ¤   if (!p) {
dbc641 ¤   ¤   MessageBox (NULL, "Memory allocation failure", "Error", MB_OK);
ee9371 ¤   }
c6665a ¤   else {
9b2a2d ¤   ¤   memset (p, 0, size);
e19371 ¤   }
d5381d ¤   return p;
e1efe6 }
bfaf5a
a9af5a
12bf56 //----------------------------------------------------|
41874b // Private memory reallocation routine
efaf5a
9949a1 void* TLReAlloc (void* p, long size) {
b5f191 ¤   if (p) {
bfde78 ¤   ¤   free (p);
e44a0c ¤   ¤   return (TLAlloc (size));
9f9371 ¤   }
df93f5 ¤   else return NULL;
60efe6 }
8aaf5a
61af5a
3cbf56 //----------------------------------------------------|
9f5ad0 // Private memory deallocation routine
17af5a
3f7cf4 void TLFree (void* p) {
de38c2 ¤   if (p) free (p);
a5efe6 }
82af5a
b7af5a
32bf56 //----------------------------------------------------|
22e899 // Return next item
8daf5a
fc5b79 TLTreeItem* NextItem (TLTreeItem* p) {
67d41f ¤   if (p->nextItem) return p->nextItem;
5f7326 ¤   if (p->parentItem) return (NextItem (p->parentItem));
4f3f59 ¤   return NULL;
9cefe6 }
d8af5a
acaf5a
1fbf56 //----------------------------------------------------|
e8862a // Return item below the specified one
33af5a
4b01e7 TLTreeItem* DownItem (TLTreeItem* p, BOOL bShift) {
14658e ¤   TLTreeItem *p2;
b8af5a
e85487 ¤   if (bShift) {
487863 ¤   ¤   if (p->nextItem) p = p->nextItem;
2b9371 ¤   }
27665a ¤   else {
a03bd7 ¤   ¤   if (p->childItem && (p->state & TLIS_EXPANDED)) return p->childItem;
30d2a7 ¤   ¤   if (p->nextItem) return p->nextItem;
d5bc98 ¤   ¤   if (p->parentItem) {
5936ec ¤   ¤   ¤   p2 = NextItem (p->parentItem);
fe1e55 ¤   ¤   ¤   if (p2) return (p2);
150fe4 ¤   ¤   }
--66de 00055a4be5640110300 Page 2 of TLMisc.c
a19371 ¤   }
9b381d ¤   return p;
66efe6 }
f0af5a
e3af5a
46bf56 //----------------------------------------------------|
f7fc29 // Return last child item of the specified item
2caf5a
11fdcf TLTreeItem* LastItem (TLTreeItem* p) {
699dc0 ¤   if (p->childItem && (p->state & TLIS_EXPANDED)) {
724ead ¤   ¤   p = p->childItem;
931dba ¤   ¤   while (p->nextItem) p = p->nextItem;
4fb483 ¤   ¤   return (LastItem (p));
819371 ¤   }
d4381d ¤   return p;
51efe6 }
69af5a
b4af5a
cdbf56 //----------------------------------------------------|
72fcb2 // Return item above the specified one
c1af5a
4c31c5 TLTreeItem* UpItem (TLTreeItem* p, BOOL bShift) {
335487 ¤   if (bShift) {
35809d ¤   ¤   if (p->prevItem) p = p->prevItem;
b09371 ¤   }
f4665a ¤   else {
056088 ¤   ¤   if (p->prevItem) return LastItem (p->prevItem);
e82492 ¤   ¤   if (p->parentItem) return p->parentItem;
5f9371 ¤   }
bc381d ¤   return p;
19efe6 }
4daf5a
ddaf5a
79bf56 //----------------------------------------------------|
de7c5a // Process keyboard character
62af5a
a7e4de BOOL TLKeyboardChar (TLWndData* pWD, WPARAM ch, LPARAM lP) {
21145e ¤   TLTreeItem*¤¤   p;
28352e ¤   INT¤¤   ¤   ¤   iCurrentRow, iFinalRow;
fcee61 ¤   BOOL¤   ¤   ¤   bShift, bControl;
89af5a
84b746 ¤   if (pWD->style & TLS_SINGLESELECT) {
934bc1 ¤   ¤   bShift = FALSE;
604f5d ¤   ¤   bControl = FALSE;
529371 ¤   }
bf665a ¤   else {
1b4f5d ¤   ¤   bControl = FALSE;
d34d7b ¤   ¤   bShift = FALSE;¤
2a96e6 ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000) bShift = TRUE;
3f1fd1 ¤   ¤   else if (GetKeyState (VK_CONTROL) & 0x8000) bControl = TRUE;
ec9371 ¤   }
e8af5a
e8c30d ¤   pWD->nmTreeList.flags = 0;
17af5a
24081b ¤   if (ch == VK_ESCAPE) {
c7325c ¤   ¤   if (pWD->bDragging && (pWD->style & TLS_INTERNALDRAG)) {
bf051a ¤   ¤   ¤   TLEndDrag (pWD, MAKELPARAM (-1, -1));
8d6a28 ¤   ¤   ¤   pWD->bDragging = FALSE;
a07805 ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
080fe4 ¤   ¤   }
cc9371 ¤   }
59af5a
8aa7d9 ¤   if (pWD->focusItem) {
66af5a
263948 ¤   ¤   switch (ch) {
f4f574 ¤   ¤   case VK_DOWN :
4876c3 ¤   ¤   ¤   p = DownItem (pWD->focusItem, bShift);
bc8fce ¤   ¤   ¤   if (p != pWD->focusItem) {
63831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
4b4cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
5c2af8 ¤   ¤   ¤   ¤   pWD->focusItem = p;
5546ae ¤   ¤   ¤   ¤   if (!bControl) {
--ff56 000c94dde2340110300 Page 3 of TLMisc.c
8eff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
8bea4c ¤   ¤   ¤   ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = p;
10bf71 ¤   ¤   ¤   ¤   ¤   if (!bShift) {
e44887 ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
1e8732 ¤   ¤   ¤   ¤   ¤   ¤   pWD->firstSelectItem = p;
011c89 ¤   ¤   ¤   ¤   ¤   }
5e3c4b ¤   ¤   ¤   ¤   ¤   else {
1c125b ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
1cc744 ¤   ¤   ¤   ¤   ¤   ¤   TLSelectRange (pWD, pWD->rootItem, p);
801c89 ¤   ¤   ¤   ¤   ¤   }
a6d043 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_SELECTED;
0403cf ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
f92613 ¤   ¤   ¤   ¤   }
866b1c ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
4c4cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
ae6168 ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pWD->focusItem))·
dc2869 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
07a3a6 ¤   ¤   ¤   }
8dcdcb ¤   ¤   ¤   break;
14af5a
826d6b ¤   ¤   case VK_UP :
24d42c ¤   ¤   ¤   p = UpItem (pWD->focusItem, bShift);
1c8fce ¤   ¤   ¤   if (p != pWD->focusItem) {
18831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
514cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
2f2af8 ¤   ¤   ¤   ¤   pWD->focusItem = p;
4946ae ¤   ¤   ¤   ¤   if (!bControl) {
12ff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
3eea4c ¤   ¤   ¤   ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = p;
a0bf71 ¤   ¤   ¤   ¤   ¤   if (!bShift) {
064887 ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
668732 ¤   ¤   ¤   ¤   ¤   ¤   pWD->firstSelectItem = p;
a01c89 ¤   ¤   ¤   ¤   ¤   }
893c4b ¤   ¤   ¤   ¤   ¤   else {
2d125b ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
1bc744 ¤   ¤   ¤   ¤   ¤   ¤   TLSelectRange (pWD, pWD->rootItem, p);
1d1c89 ¤   ¤   ¤   ¤   ¤   }
a4d043 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_SELECTED;
5903cf ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
e42613 ¤   ¤   ¤   ¤   }
7a6b1c ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
6a4cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
e46168 ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pWD->focusItem))·
ae2869 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
0da3a6 ¤   ¤   ¤   }
0fcdcb ¤   ¤   ¤   break;
03af5a
0ea29d ¤   ¤   case VK_LEFT :
6a414d ¤   ¤   case VK_SUBTRACT :
cb2726 ¤   ¤   ¤   if (!bShift) {
d4fdd9 ¤   ¤   ¤   ¤   if (pWD->focusItem->state & TLIS_EXPANDED) {
221878 ¤   ¤   ¤   ¤   ¤   p = pWD->focusItem;
a27bc6 ¤   ¤   ¤   ¤   ¤   if (!bControl) {
69a236 ¤   ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, p);
d94887 ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
56e620 ¤   ¤   ¤   ¤   ¤   ¤   p->state |= TLIS_SELECTED;
46d9e6 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
781c89 ¤   ¤   ¤   ¤   ¤   }
68ca0d ¤   ¤   ¤   ¤   ¤   p->state &= ~TLIS_EXPANDED;
be2869 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
ab2613 ¤   ¤   ¤   ¤   }
7adeaa ¤   ¤   ¤   ¤   else {
b919ee ¤   ¤   ¤   ¤   ¤   if (ch != VK_SUBTRACT) {
b67b1d ¤   ¤   ¤   ¤   ¤   ¤   if (pWD->focusItem->parentItem) {
fdf53a ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
9c3af6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
3c20ae ¤   ¤   ¤   ¤   ¤   ¤   ¤   p = pWD->focusItem->parentItem;
717f9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->focusItem = p;
c67893 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!bControl) {
45b1f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
932a44 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->firstSelectItem = p;
c9e5f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
--6c4e 000376050d240110300 Page 4 of TLMisc.c
d3f03c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->state |= TLIS_SELECTED;
3f54d5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
e85268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
af1a61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->state |= TLIS_FOCUSED;
a2a9b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, p);
df77f3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, p))·
61ea40 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval,
9e5c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
01db3c ¤   ¤   ¤   ¤   ¤   ¤   }
171c89 ¤   ¤   ¤   ¤   ¤   }
6e2613 ¤   ¤   ¤   ¤   }
88a3a6 ¤   ¤   ¤   }
2ecdcb ¤   ¤   ¤   break;
7faf5a
3e95c4 ¤   ¤   case VK_RIGHT :
c0323e ¤   ¤   case VK_RETURN :
2a12eb ¤   ¤   case VK_ADD :
262726 ¤   ¤   ¤   if (!bShift) {
cbb1d9 ¤   ¤   ¤   ¤   if (pWD->focusItem->childItem) {
d027f0 ¤   ¤   ¤   ¤   ¤   if (pWD->focusItem->state & TLIS_EXPANDED) {
b3e041 ¤   ¤   ¤   ¤   ¤   ¤   if (ch != VK_ADD) {
a2f53a ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
a63af6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
949991 ¤   ¤   ¤   ¤   ¤   ¤   ¤   p = pWD->focusItem->childItem;
b17f9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->focusItem = p;
aa7893 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (!bControl) {
9fb1f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
ca2a44 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->firstSelectItem = p;
14e5f1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
37f03c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->state |= TLIS_SELECTED;
ac54d5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
3e5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
c21a61 ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->state |= TLIS_FOCUSED;
f2a9b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, p);
8f77f3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, p))·
eeea40 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval,
9c5c20 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TRUE);
6edb3c ¤   ¤   ¤   ¤   ¤   ¤   }
011c89 ¤   ¤   ¤   ¤   ¤   }
103c4b ¤   ¤   ¤   ¤   ¤   else {
01901e ¤   ¤   ¤   ¤   ¤   ¤   p = pWD->focusItem;
8f7e2b ¤   ¤   ¤   ¤   ¤   ¤   if (!bControl) {
409f58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, p);
8be686 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
2cf707 ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->state |= TLIS_SELECTED;
b553a3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
5adb3c ¤   ¤   ¤   ¤   ¤   ¤   }
61a015 ¤   ¤   ¤   ¤   ¤   ¤   p->state |= TLIS_EXPANDED;
732f1f ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
85a0b7 ¤   ¤   ¤   ¤   ¤   ¤   TLExpandAutoScroll (pWD, pWD->focusItem);
9f1c89 ¤   ¤   ¤   ¤   ¤   }
2d2613 ¤   ¤   ¤   ¤   }
69a3a6 ¤   ¤   ¤   }
9ccdcb ¤   ¤   ¤   break;
ccaf5a
4340de ¤   ¤   case VK_NEXT :
69de82 ¤   ¤   ¤   iCurrentRow = 0;
6a8243 ¤   ¤   ¤   TLGetRow (pWD->rootItem, pWD->focusItem, &iCurrentRow);
912fc6 ¤   ¤   ¤   if (iCurrentRow >= (pWD->iFirstRow + pWD->iMaxRows -1))·
d8bcb0 ¤   ¤   ¤   ¤   iFinalRow = iCurrentRow + pWD->iMaxRows -1;
2f6b93 ¤   ¤   ¤   else·
2b7bb1 ¤   ¤   ¤   ¤   iFinalRow = pWD->iFirstRow + pWD->iMaxRows -1;
3c9af6 ¤   ¤   ¤   if (iFinalRow > pWD->iExpandedRows)·
eadbb0 ¤   ¤   ¤   ¤   iFinalRow = pWD->iExpandedRows;
4767c5 ¤
f756d1 ¤   ¤   ¤   p = pWD->focusItem;
363afc ¤   ¤   ¤   while (iCurrentRow < iFinalRow) {
c81a8e ¤   ¤   ¤   ¤   p = DownItem (p, bShift);
e55637 ¤   ¤   ¤   ¤   iCurrentRow++;
91a3a6 ¤   ¤   ¤   }
6a8fce ¤   ¤   ¤   if (p != pWD->focusItem) {
37831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
--6ba4 000856b2abb40110300 Page 5 of TLMisc.c
8d4cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
3a2af8 ¤   ¤   ¤   ¤   pWD->focusItem = p;
0920fc ¤   ¤   ¤   ¤   if (bShift) {
a8ff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
f9ea4c ¤   ¤   ¤   ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = p;
645d65 ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
6cc7a6 ¤   ¤   ¤   ¤   ¤   TLSelectRange (pWD, pWD->rootItem, p);
212613 ¤   ¤   ¤   ¤   }
6eb626 ¤   ¤   ¤   ¤   else if (!bControl) {
2dff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
17c80c ¤   ¤   ¤   ¤   ¤   pWD->firstSelectItem = p;
6007b9 ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
c9d043 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_SELECTED;
b603cf ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
bf2613 ¤   ¤   ¤   ¤   }
9b6b1c ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
e84cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
3d6168 ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pWD->focusItem))·
8d2869 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
b3a3a6 ¤   ¤   ¤   }
17cdcb ¤   ¤   ¤   break;
60af5a
c81f04 ¤   ¤   case VK_PRIOR :
dede82 ¤   ¤   ¤   iCurrentRow = 0;
9a8243 ¤   ¤   ¤   TLGetRow (pWD->rootItem, pWD->focusItem, &iCurrentRow);
fd1e7b ¤   ¤   ¤   if (iCurrentRow == pWD->iFirstRow)·
9724fc ¤   ¤   ¤   ¤   iFinalRow = iCurrentRow - pWD->iMaxRows +1;
136b93 ¤   ¤   ¤   else·
76894c ¤   ¤   ¤   ¤   iFinalRow = pWD->iFirstRow;
ccf1fa ¤   ¤   ¤   if (iFinalRow < 0) iFinalRow = 0;
8067c5 ¤
4656d1 ¤   ¤   ¤   p = pWD->focusItem;
ddaaa8 ¤   ¤   ¤   while (iCurrentRow > iFinalRow) {
455d81 ¤   ¤   ¤   ¤   p = UpItem (p, bShift);
36cb74 ¤   ¤   ¤   ¤   iCurrentRow--;
c9a3a6 ¤   ¤   ¤   }
3e8fce ¤   ¤   ¤   if (p != pWD->focusItem) {
c3831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
f44cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
572af8 ¤   ¤   ¤   ¤   pWD->focusItem = p;
ef20fc ¤   ¤   ¤   ¤   if (bShift) {
6bff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
e7ea4c ¤   ¤   ¤   ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = p;
f05d65 ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
cbc7a6 ¤   ¤   ¤   ¤   ¤   TLSelectRange (pWD, pWD->rootItem, p);
ff2613 ¤   ¤   ¤   ¤   }
8eb626 ¤   ¤   ¤   ¤   else if (!bControl) {
87ff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
35ea4c ¤   ¤   ¤   ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = p;
2043b5 ¤   ¤   ¤   ¤   ¤   if (!bShift) pWD->firstSelectItem = p;
3907b9 ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
add043 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_SELECTED;
4a03cf ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
602613 ¤   ¤   ¤   ¤   }
8e6b1c ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
e44cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
bf6168 ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pWD->focusItem))·
c42869 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
1ba3a6 ¤   ¤   ¤   }
21cdcb ¤   ¤   ¤   break;
f4af5a
0c7c13 ¤   ¤   case VK_HOME :
d74ae9 ¤   ¤   ¤   p = pWD->rootItem;
248fce ¤   ¤   ¤   if (p != pWD->focusItem) {
92831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
474cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
c92af8 ¤   ¤   ¤   ¤   pWD->focusItem = p;
1746ae ¤   ¤   ¤   ¤   if (!bControl) {
a2ff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
8bea4c ¤   ¤   ¤   ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = p;
56bf71 ¤   ¤   ¤   ¤   ¤   if (!bShift) {
854887 ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
--f1bc 0003a20a43e40110300 Page 6 of TLMisc.c
0d8732 ¤   ¤   ¤   ¤   ¤   ¤   pWD->firstSelectItem = p;
161c89 ¤   ¤   ¤   ¤   ¤   }
f43c4b ¤   ¤   ¤   ¤   ¤   else {
1b125b ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
0bc744 ¤   ¤   ¤   ¤   ¤   ¤   TLSelectRange (pWD, pWD->rootItem, p);
7a1c89 ¤   ¤   ¤   ¤   ¤   }
4bd043 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_SELECTED;
7203cf ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
d42613 ¤   ¤   ¤   ¤   }
156b1c ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
154cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
b76168 ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pWD->focusItem))·
012869 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
5ca3a6 ¤   ¤   ¤   }
e4cdcb ¤   ¤   ¤   break;
b8af5a
5a4eef ¤   ¤   case VK_END :
2f4ae9 ¤   ¤   ¤   p = pWD->rootItem;
c64f27 ¤   ¤   ¤   while (p->nextItem) p = p->nextItem;
d98fce ¤   ¤   ¤   if (p != pWD->focusItem) {
5a831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
ad4cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
c52af8 ¤   ¤   ¤   ¤   pWD->focusItem = p;
3946ae ¤   ¤   ¤   ¤   if (!bControl) {
41ff2d ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
79ea4c ¤   ¤   ¤   ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = p;
52bf71 ¤   ¤   ¤   ¤   ¤   if (!bShift) {
e94887 ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
ea8732 ¤   ¤   ¤   ¤   ¤   ¤   pWD->firstSelectItem = p;
241c89 ¤   ¤   ¤   ¤   ¤   }
543c4b ¤   ¤   ¤   ¤   ¤   else {
19125b ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
f8c744 ¤   ¤   ¤   ¤   ¤   ¤   TLSelectRange (pWD, pWD->rootItem, p);
481c89 ¤   ¤   ¤   ¤   ¤   }
fad043 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_SELECTED;
3903cf ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
642613 ¤   ¤   ¤   ¤   }
3b6b1c ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
224cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
ea6168 ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pWD->focusItem))·
ba2869 ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
57a3a6 ¤   ¤   ¤   }
7fcdcb ¤   ¤   ¤   break;
76af5a
b46087 ¤   ¤   case VK_SPACE :
6f8652 ¤   ¤   ¤   if (bControl) {
8ddd2d ¤   ¤   ¤   ¤   p = pWD->focusItem;
d212f1 ¤   ¤   ¤   ¤   if (pWD->focusItem->state & TLIS_SELECTED) {
404bd2 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_SELECTED;
5bad9d ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected--;
9c2613 ¤   ¤   ¤   ¤   }
a6deaa ¤   ¤   ¤   ¤   else {
41d043 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_SELECTED;
9a30de ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected++;
932613 ¤   ¤   ¤   ¤   }
c1257a ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYKEYBOARD;
074cd3 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
e5a3a6 ¤   ¤   ¤   }
70cdcb ¤   ¤   ¤   break;
320fe4 ¤   ¤   }
e5f828 ¤   }¤
4faf5a
b69261 ¤   if (pWD->nmTreeList.flags) {
fb2989 ¤   ¤   if (pWD->iNumberSelected > 1) pWD->nmTreeList.flags |= TLC_MULTIPLE;
a73467 ¤   ¤   pWD->nmTreeList.itemOld.hItem = NULL;
92782f ¤   ¤   if (pWD->iNumberSelected > 0) {
226c0d ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)p;
1f8d64 ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = p->state;
900fe4 ¤   ¤   }
f007e0 ¤   ¤   else {
8f2860 ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
3aa778 ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
--a950 0002844c7d740110300 Page 7 of TLMisc.c
b50fe4 ¤   ¤   }
29b89d ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
633d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
82847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
01836c ¤   ¤   return TRUE;
dc9371 ¤   }
b8665a ¤   else {
37bef1 ¤   ¤   pWD->nmKeyDown.hdr.code = TLN_KEYDOWN;
dd3b4e ¤   ¤   pWD->nmKeyDown.wVKey = ch;
fafdea ¤   ¤   pWD->nmKeyDown.flags = lP;
b83d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
7c27a9 ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmKeyDown));
1498aa ¤   ¤   return FALSE;
829371 ¤   }
26efe6 }
76af5a
19af5a
c7bf56 //----------------------------------------------------|
979b03 // Process selected objects by calling callback function
caaf5a
0db3a6 BOOL IterateSelected (TLTreeItem* pStart, LPARAM lParam) {
7ce723 ¤   TL_TREEITEM tli;
91df18 ¤   TLTreeItem* p;
2a9093 ¤   FARPROC lpfnCallback;
04af5a
dea5a6 ¤   lpfnCallback = *(FARPROC*)lParam;
a9af5a
4be48d ¤   if (!pStart) return FALSE;
37bd26 ¤   p = pStart;
aeaf5a
af1b02 ¤   while (p->nextItem) p = p->nextItem;
fbaf5a
f8d3a5 ¤   while (p) {
cc3c62 ¤   ¤   if (p->state & TLIS_EXPANDED)·
21d1ad ¤   ¤   ¤   IterateSelected (p->childItem, lParam);
f4ec3a ¤   ¤   if (p->state & TLIS_SELECTED) {
5a14e4 ¤   ¤   ¤   tli.hItem = (HTLITEM)p;
7009c9 ¤   ¤   ¤   tli.pszText = p->pszText;
c2b526 ¤   ¤   ¤   tli.iImage = p->iImage;
d97dd7 ¤   ¤   ¤   tli.lParam = p->lParam;
40af5a
058157 ¤   ¤   ¤   p = p->prevItem;
e5e55c ¤   ¤   ¤   if (!(lpfnCallback)(&tli, lParam)) return FALSE;
0a0fe4 ¤   ¤   }
a812f2 ¤   ¤   else p = p->prevItem;
c39371 ¤   }
1ac2e7 ¤   return TRUE;
d4efe6 }
ddaf5a
15af5a
f129c5 BOOL TLIterateSelected (TLWndData* pWD, LPARAM lParam) {
ce9965 ¤   return (IterateSelected (pWD->rootItem, lParam));
0fefe6 }
cbaf5a
a3af5a
85bf56 //----------------------------------------------------|
38f76c // Scroll to keyboard-selected key
a7465d //
57c037 //¤ c =¤¤   ¤   ¤   character just typed by user
36d427 //¤ bStillTyping =¤ TRUE => this character is part of a previous
252182 //¤ ¤   ¤   ¤   ¤   string of characters => append to end.
a9af5a
aff941 BOOL TLSelectByKeyboard (TLWndData* pWD, LONG c, BOOL bStillTyping) {
bcaf5a
fdcdd6 ¤   INT i;
82df18 ¤   TLTreeItem* p;
c411b7 ¤   TLTreeItem* pfirst;
0eaf5a
d0dd7c ¤   // return if non-printable character
45d8dc ¤   if (!isprint (c)) return FALSE;
afaf5a
282cfd ¤   // escape key deselects selection and clears buffer
--7da6 000df23290940110300 Page 8 of TLMisc.c
f1fd02 ¤   if (c == VK_ESCAPE) {
780b63 ¤   ¤   pWD->pTypeBufPtr = &(pWD->szTypeBuf[0]);
da4455 ¤   ¤   pWD->iNumCharInTypeBuf = 0;
bb2e8d ¤   ¤   if (pWD->focusItem) {
c4d6b3 ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
04197f ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
74f8f4 ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
940fe4 ¤   ¤   }
9f64e8 ¤   ¤   pWD->focusItem = NULL;
5ecdd0 ¤   ¤   pWD->firstSelectItem = NULL;
37b73d ¤   ¤   pWD->iNumberSelected = 0;
5dccc4 ¤   ¤   pWD->nmTreeList.flags = TLC_BYKEYBOARD;
063467 ¤   ¤   pWD->nmTreeList.itemOld.hItem = NULL;
e7675e ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
ae36e0 ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
dbb89d ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
d43d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
f1847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
c498aa ¤   ¤   return FALSE;
829371 ¤   }
27af5a
d29246 ¤   // convert to lower case
ca18f9 ¤   (CHAR)c = tolower ((CHAR)c);
38af5a
8ed905 ¤   // get starting point for traversing linked list
2da7d9 ¤   if (pWD->focusItem) {
f1fb8f ¤   ¤   p = pWD->focusItem;
a93ba6 ¤   ¤   while (p->parentItem) p = p->parentItem;
a39371 ¤   }
4e90e2 ¤   else p = pWD->rootItem;
3ef78b ¤   if (!p) return FALSE;
9ec739 ¤   pfirst = p;
0faf5a
bd6d41 ¤   // if only one char in buffer and incoming is same character
a61dd2 ¤   // then step to next item which begins with this character
071602 ¤   if ((pWD->iNumCharInTypeBuf == 1) &&·
b01c8f ¤   ¤   (pWD->szTypeBuf[0] == (CHAR)c))·
b5c7a1 ¤   {
c87863 ¤   ¤   if (p->nextItem) p = p->nextItem;
893dbc ¤   ¤   else p = pWD->rootItem;
2dbc7c ¤   ¤   while (tolower (p->pszText[0]) != pWD->szTypeBuf[0]) {
2141a6 ¤   ¤   ¤   if (p->nextItem) p = p->nextItem;
88b640 ¤   ¤   ¤   else p = pWD->rootItem;
5b9ced ¤   ¤   ¤   if (p == pfirst) break;
100fe4 ¤   ¤   }
649371 ¤   }
8faf5a
b0a743 ¤   // otherwise do standard matching
4b665a ¤   else {
d6c23c ¤   ¤   if (!bStillTyping) {
088100 ¤   ¤   ¤   pWD->iNumCharInTypeBuf = 0;
6f5878 ¤   ¤   ¤   pWD->pTypeBufPtr = &(pWD->szTypeBuf[0]);
370fe4 ¤   ¤   }
58312f ¤   ¤   if (pWD->iNumCharInTypeBuf < TYPEBUFFERSIZE-1) {
e5aebb ¤   ¤   ¤   *(pWD->pTypeBufPtr) = (CHAR)c;
41d337 ¤   ¤   ¤   (pWD->pTypeBufPtr)++;
307d27 ¤   ¤   ¤   *(pWD->pTypeBufPtr) = '\0';
d7a9b3 ¤   ¤   ¤   pWD->iNumCharInTypeBuf++;
e7af5a
b941a6 ¤   ¤   ¤   if (p->nextItem) p = p->nextItem;
4aaf5a
5fa62f ¤   ¤   ¤   i = lstrlen (pWD->szTypeBuf);
100e1f ¤   ¤   ¤   while (strnicmp (p->pszText, pWD->szTypeBuf, i) != 0) {
fb0e98 ¤   ¤   ¤   ¤   if (p->nextItem) p = p->nextItem;
a97315 ¤   ¤   ¤   ¤   else p = pWD->rootItem;
0a59b8 ¤   ¤   ¤   ¤   if (p == pfirst) break;
94a3a6 ¤   ¤   ¤   }
2f0fe4 ¤   ¤   }
f49371 ¤   }
d1af5a
1e0cf5 ¤   // if we have selected new item then handle selection/deselection and
df8319 ¤   // notify parent of selection change
--e1c2 001bca2a99040110300 Page 9 of TLMisc.c
96f662 ¤   if (p != pfirst) {
8e2e8d ¤   ¤   if (pWD->focusItem) {
f8d6b3 ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
73197f ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
66f8f4 ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
760fe4 ¤   ¤   }
060c5a ¤   ¤   pWD->focusItem = p;
32ede1 ¤   ¤   pWD->iNumberSelected = 1;
6d2254 ¤   ¤   pWD->firstSelectItem = p;
b3dda5 ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED | TLIS_SELECTED;
b38f3e ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
1666b1 ¤   ¤   if (TLSelectAutoScroll (pWD, pWD->focusItem))·
b37805 ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
f3ccc4 ¤   ¤   pWD->nmTreeList.flags = TLC_BYKEYBOARD;
353467 ¤   ¤   pWD->nmTreeList.itemOld.hItem = NULL;
ac39a1 ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)p;
9b2365 ¤   ¤   pWD->nmTreeList.itemNew.state = p->state;
ceb89d ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
933d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
c8847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
619371 ¤   }
ceaf5a
98c2e7 ¤   return TRUE;
c4efe6 }
4baf5a
c4af5a
bcaf5a
--cd9d 00050b7b14040110301 Page 1 of TLMouse.c
63add8 //:TLMouse.c - handle tree list mouse events
e5465d //
c0c54f //¤ $Id: TLMouse.c,v 1.32 1998/07/20 19:02:06 pbj Exp $
85465d //
b2af5a
7e5799 #include "TLIntern.h"
2720db #include "math.h"
bbaf5a
b67b2d #define DRAGDEADZONE 2
f7af5a
9cf74a #define WHEELTHRESHOLD¤ WHEEL_DELTA
9daf5a
46f600 #define TLMF_DBLCLICK¤  0x0001
f7a157 #define TLMF_CONTROL¤   0x0002
62bd3d #define TLMF_SHIFT¤ ¤   0x0004
a3e5bf #define TLMF_RBUTTON¤   0x0008
beaf5a
328e41 #define TLK_NONE¤   ¤   0x0000
6eb049 #define TLK_BUTTON¤ ¤   0x0001
4e9944 #define TLK_SELECT¤ ¤   0x0002
464a13 #define TLK_ACTIVE¤ ¤   0x0003
a0af5a
5baf5a
4cbf56 //----------------------------------------------------|
8f13f7 // ·Search for object containg given point
b7af5a
1b277d INT PointInActiveArea (TLTreeItem* p, TLColumnItem* pci, int ix, POINT mpt) {
837eca ¤   TLListItem* pli;
ae5bda ¤   RECT rc;
06b546 ¤   INT iSubItem;
1daf5a
a9952d ¤   pli = p->listItem;
90205c ¤   iSubItem = 1;
48af5a
a4549b ¤   while (pci && pli) {
d4af5a
2261e1 ¤   ¤   if (pci->bMouseNotify) {
173fe6 ¤   ¤   ¤   if (pli->state & TLIS_VISIBLE) {
29c892 ¤   ¤   ¤   ¤   rc.left = ix + pci->cxImageOffset;
8e9118 ¤   ¤   ¤   ¤   rc.right = rc.left + BITMAPWIDTH;
cafdc7 ¤   ¤   ¤   ¤   rc.top = p->selectRect.top;
206dfb ¤   ¤   ¤   ¤   rc.bottom = p->selectRect.bottom;
106e59 ¤   ¤   ¤   ¤   if (PtInRect (&rc, mpt)) {
a9c215 ¤   ¤   ¤   ¤   ¤   return iSubItem;
762613 ¤   ¤   ¤   ¤   }
eba3a6 ¤   ¤   ¤   }
450fe4 ¤   ¤   }
92af5a
33646c ¤   ¤   iSubItem++;
8d020d ¤   ¤   ix += pci->cx;
f1af5a
3e4836 ¤   ¤   pci = pci->nextItem;
1d1184 ¤   ¤   pli = pli->nextItem;
fe9371 ¤   }
fb3e6b ¤   return 0;
4eefe6 }
c9af5a
96af5a
fcbf56 //----------------------------------------------------|
4513f7 // ·Search for object containg given point
b0af5a
c04810 TLTreeItem* PointSearchEx (TLTreeItem* pStart, TLColumnItem* pci,
7458de ¤   ¤   ¤   ¤   ¤   ¤   ···int ix, POINT mpt, int* iType, int* iSubItem) {
e0df18 ¤   TLTreeItem* p;
bfb3e6 ¤   TLTreeItem* pp;
8967c5 ¤
eabd26 ¤   p = pStart;
ced3a5 ¤   while (p) {
12af5a
a7ac66 ¤   ¤   *iSubItem = PointInActiveArea (p, pci, ix, mpt);
1f98b5 ¤   ¤   if (*iSubItem) {
506528 ¤   ¤   ¤   *iType = TLK_ACTIVE;
--c20d 000b064ea2440110301 Page 2 of TLMouse.c
398732 ¤   ¤   ¤   return p;
8f0fe4 ¤   ¤   }
59fb18 ¤   ¤   if (PtInRect (&p->buttonRect, mpt)) {
e2d9ac ¤   ¤   ¤   *iType = TLK_BUTTON;
c18732 ¤   ¤   ¤   return p;
990fe4 ¤   ¤   }
5bcfb0 ¤   ¤   if (PtInRect (&p->selectRect, mpt)) {
1d0b95 ¤   ¤   ¤   *iType = TLK_SELECT;
0d8732 ¤   ¤   ¤   return p;
3c0fe4 ¤   ¤   }
eb0312 ¤   ¤   if (p->state & TLIS_EXPANDED) {
1f1576 ¤   ¤   ¤   pp = PointSearchEx (p->childItem, pci, ix, mpt, iType, iSubItem);
32bc7e ¤   ¤   ¤   if (pp) return pp;
1d0fe4 ¤   ¤   }
284870 ¤   ¤   if (p->buttonRect.right < p->buttonRect.left) {
3d620e ¤   ¤   ¤   *iType = TLK_NONE;
83cf03 ¤   ¤   ¤   return NULL;
f40fe4 ¤   ¤   }
8c26cb ¤   ¤   p = p->nextItem;
819371 ¤   }
3194c7 ¤   *iType = TLK_NONE;
c83f59 ¤   return NULL;
d4efe6 }
cbaf5a
4faf5a
32bf56 //----------------------------------------------------|
0613f7 // ·Search for object containg given point
8daf5a
d09bcd TLTreeItem* PointSearch (TLTreeItem* pStart, POINT mpt, int* iType) {
efdf18 ¤   TLTreeItem* p;
53b3e6 ¤   TLTreeItem* pp;
b367c5 ¤
d3bd26 ¤   p = pStart;
69d3a5 ¤   while (p) {
09fb18 ¤   ¤   if (PtInRect (&p->buttonRect, mpt)) {
38d9ac ¤   ¤   ¤   *iType = TLK_BUTTON;
8b8732 ¤   ¤   ¤   return p;
e30fe4 ¤   ¤   }
43cfb0 ¤   ¤   if (PtInRect (&p->selectRect, mpt)) {
340b95 ¤   ¤   ¤   *iType = TLK_SELECT;
5d8732 ¤   ¤   ¤   return p;
dc0fe4 ¤   ¤   }
950312 ¤   ¤   if (p->state & TLIS_EXPANDED) {
494c80 ¤   ¤   ¤   pp = PointSearch (p->childItem, mpt, iType);
27bc7e ¤   ¤   ¤   if (pp) return pp;
6f0fe4 ¤   ¤   }
5b4870 ¤   ¤   if (p->buttonRect.right < p->buttonRect.left) {
85620e ¤   ¤   ¤   *iType = TLK_NONE;
16cf03 ¤   ¤   ¤   return NULL;
400fe4 ¤   ¤   }
4926cb ¤   ¤   p = p->nextItem;
0f9371 ¤   }
d894c7 ¤   *iType = TLK_NONE;
553f59 ¤   return NULL;
99efe6 }
acaf5a
76af5a
7cbf56 //----------------------------------------------------|
edb1e5 // ·Select range of lines
5baf5a
ea6d7f BOOL TLSelectRange (TLWndData* pWD, TLTreeItem* pFirst, TLTreeItem* pSel) {
12af5a
b2df18 ¤   TLTreeItem* p;
38bd5f ¤   TLTreeItem* pLast;
6cfb25 ¤   BOOL bSel;
70af5a
5f3a14 ¤   p = pFirst;
5c9a1d ¤   bSel = FALSE;
d8af5a
495fc0 ¤   if (pSel == pWD->firstSelectItem) {
b59dcd ¤   ¤   pSel->state |= TLIS_SELECTED;
b0ede1 ¤   ¤   pWD->iNumberSelected = 1;
--4cfe 000486e531240110301 Page 3 of TLMouse.c
8e9bda ¤   ¤   TLInvalidateItem (pWD, pSel);
a2836c ¤   ¤   return TRUE;
109371 ¤   }
8aaf5a
99b43a ¤   while (p && !bSel) {
728cae ¤   ¤   if ((p->childItem) && (p->state & TLIS_EXPANDED)) {
48ef8b ¤   ¤   ¤   if (TLSelectRange (pWD, p->childItem, pSel)) return TRUE;
bb0fe4 ¤   ¤   }
b49212 ¤   ¤   if (p == pSel) {
93d414 ¤   ¤   ¤   bSel = TRUE;
40d8f0 ¤   ¤   ¤   pLast = pWD->firstSelectItem;
65a146 ¤   ¤   ¤   p->state |= TLIS_SELECTED;
b57588 ¤   ¤   ¤   (pWD->iNumberSelected)++;
c4fff9 ¤   ¤   ¤   TLInvalidateItem (pWD, p);
260fe4 ¤   ¤   }
d0543b ¤   ¤   else if (p == pWD->firstSelectItem) {
38d414 ¤   ¤   ¤   bSel = TRUE;
3812a1 ¤   ¤   ¤   pLast = pSel;
22a146 ¤   ¤   ¤   p->state |= TLIS_SELECTED;
e67588 ¤   ¤   ¤   (pWD->iNumberSelected)++;
40fff9 ¤   ¤   ¤   TLInvalidateItem (pWD, p);
1e0fe4 ¤   ¤   }
4a26cb ¤   ¤   p = p->nextItem;
d09371 ¤   }
4caf5a
229e20 ¤   if (bSel) {
75d691 ¤   ¤   while (p && bSel) {
d75ca6 ¤   ¤   ¤   if (p == pLast) {
ccee66 ¤   ¤   ¤   ¤   bSel = FALSE;
b6a3a6 ¤   ¤   ¤   }
f3a146 ¤   ¤   ¤   p->state |= TLIS_SELECTED;
077588 ¤   ¤   ¤   (pWD->iNumberSelected)++;
7afff9 ¤   ¤   ¤   TLInvalidateItem (pWD, p);
891296 ¤   ¤   ¤   p = p->nextItem;
ca0fe4 ¤   ¤   }
b6836c ¤   ¤   return TRUE;
159371 ¤   }
01a230 ¤   return FALSE;
1d1862 }¤
52af5a
f8af5a
29bf56 //----------------------------------------------------|
384c99 // ·De-dragover Tree
77af5a
cab2e6 BOOL TLDeDragOverTree (TLWndData* pWD, TLTreeItem* p, TLTreeItem* pExcept) {
229d69 ¤   BOOL bDedragged = FALSE;
d8af5a
5ad3a5 ¤   while (p) {
3f769d ¤   ¤   if (p->childItem)·
92c4cd ¤   ¤   ¤   bDedragged = TLDeDragOverTree (pWD, p->childItem, pExcept);
43e72b ¤   ¤   if (p != pExcept) {
921e95 ¤   ¤   ¤   if (p->state & TLIS_DRAGGEDOVER) {
b96211 ¤   ¤   ¤   ¤   p->state &= ~TLIS_DRAGGEDOVER;
cbf1b5 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, p);
c96d5f ¤   ¤   ¤   ¤   bDedragged = TRUE;
12a3a6 ¤   ¤   ¤   }
2a0fe4 ¤   ¤   }
f526cb ¤   ¤   p = p->nextItem;
9d9371 ¤   }
21c7bc ¤   return bDedragged;
55efe6 }
85af5a
4daf5a
74bf56 //----------------------------------------------------|
1d07b1 // ·cursor is moving during internal drag operation
5aaf5a
375294 BOOL DragOverInternal (TLWndData* pWD, LPARAM lParam) {
ac01c3 ¤   INT¤¤   ¤   irow, iHitType;
1b355b ¤   TLTreeItem* pHit;
7b1a9f ¤   POINT¤  ¤   mpt;
dc71e7 ¤   BOOL¤   ¤   bRet;
48af5a
--9b46 0003d5ddeb140110301 Page 4 of TLMouse.c
3fab7c ¤   BOOL¤   ¤   bShift = FALSE;
e3af5a
b47821 ¤   mpt.x = LOWORD (lParam);
e93322 ¤   mpt.y = HIWORD (lParam);
e1af5a
a633ce ¤   pWD->nmTreeList.hdr.code = 0;
675e9b ¤   pWD->nmTreeList.itemNew.hItem = NULL;
0238ac ¤   pWD->nmTreeList.itemNew.state = 0;
1e0da2 ¤   pWD->nmTreeList.itemOld.hItem = NULL;
e5af5a
e2bb1a ¤   pHit = PointSearch (pWD->rootItem, mpt, &iHitType);
6baf5a
8bff56 ¤   switch (iHitType) {
55f889 ¤   case TLK_NONE :
bb7a8e ¤   ¤   TLDeDragOverTree (pWD, pWD->rootItem, NULL);
8c424c ¤   ¤   SetCursor (pWD->hCursorNoDrag);
e6cdd0 ¤   ¤   pWD->firstSelectItem = NULL;
722e8d ¤   ¤   if (pWD->focusItem) {
e3e9e9 ¤   ¤   ¤   pHit = pWD->focusItem;
8ce897 ¤   ¤   ¤   pWD->focusItem = NULL;
fa0fe4 ¤   ¤   }
62675e ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
ac36e0 ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
caf948 ¤   ¤   pWD->nmTreeList.hdr.code = TLN_DRAGGEDOVER;
0068c5 ¤   ¤   bRet = FALSE;
c72f68 ¤   ¤   break;
81af5a
3fbfad ¤   default :
d86fc3 ¤   ¤   if (pWD->uDragScrollState == 0) {
ddb316 ¤   ¤   ¤   irow = 0;
4113e8 ¤   ¤   ¤   TLGetRow (pWD->rootItem, pHit, &irow);
4619fc ¤   ¤   ¤   if (irow == pWD->iFirstRow) {
00ffb0 ¤   ¤   ¤   ¤   pWD->iFirstRow--;
aae02c ¤   ¤   ¤   ¤   if (pWD->iFirstRow < 0)·
bf7aec ¤   ¤   ¤   ¤   ¤   pWD->iFirstRow = 0;
99deaa ¤   ¤   ¤   ¤   else {
acc462 ¤   ¤   ¤   ¤   ¤   SetTimer (pWD->hWnd, DRAGSCROLLTIMERID,·
aafdee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DRAGSCROLLTIME, NULL);
e2ba63 ¤   ¤   ¤   ¤   ¤   pWD->uDragScrollState = DRAGSCROLL_DOWN;
9c8516 ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
066eed ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
7c0526 ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_AUTOSCROLLED;
a84087 ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
1ba393 ¤   ¤   ¤   ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
f6847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
6f2613 ¤   ¤   ¤   ¤   }
8fa3a6 ¤   ¤   ¤   }
512010 ¤   ¤   ¤   if (irow == (pWD->iFirstRow + pWD->iMaxRows)) {
a662f3 ¤   ¤   ¤   ¤   pWD->iFirstRow++;
69e2d7 ¤   ¤   ¤   ¤   SetTimer (pWD->hWnd, DRAGSCROLLTIMERID,·
7b7012 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DRAGSCROLLTIME, NULL);
293349 ¤   ¤   ¤   ¤   pWD->uDragScrollState = DRAGSCROLL_UP;
e38661 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
ba7fca ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
5bdf0f ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_AUTOSCROLLED;
c543f0 ¤   ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
f0b01f ¤   ¤   ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
1a847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
3ea3a6 ¤   ¤   ¤   }
bf0fe4 ¤   ¤   }
3eaf5a
13b265 ¤   ¤   TLDeDragOverTree (pWD, pWD->rootItem, pHit);
2f341c ¤   ¤   SetCursor (pWD->hCursorDragging);
9bb73d ¤   ¤   pWD->iNumberSelected = 0;
82f20f ¤   ¤   pHit->state |= TLIS_DRAGGEDOVER;
f99afb ¤   ¤   (pWD->iNumberSelected)++;
759e4e ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
fb381e ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
3ef948 ¤   ¤   pWD->nmTreeList.hdr.code = TLN_DRAGGEDOVER;
19219a ¤   ¤   if (pWD->focusItem != pHit) {
331985 ¤   ¤   ¤   if (pWD->focusItem) {
3d831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
--74cd 0009fcc313540110301 Page 5 of TLMouse.c
1763ef ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.hItem = (HTLITEM)pWD->focusItem;
1d5cd6 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.state = pWD->focusItem->state;
5aa3a6 ¤   ¤   ¤   }
b10fe4 ¤   ¤   }
ca5beb ¤   ¤   bRet = TRUE;
8f2f68 ¤   ¤   break;
ef9371 ¤   }
8a67c5 ¤
efa73d ¤   if (pWD->nmTreeList.hdr.code) {
c3a2cf ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
4ee528 ¤   ¤   pWD->nmTreeList.ptDrag = mpt;
fd3d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
ca847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
219371 ¤   }
b3af5a
7f8d4d ¤   return bRet;
3aefe6 }
15af5a
ccaf5a
5abf56 //----------------------------------------------------|
3e4a32 // ·Handle mouse move event
c8af5a
17aac6 void TLMouseMove (TLWndData* pWD, WPARAM wParam, LPARAM lParam) {
5da147 ¤   POINT mpt;
71af5a
364ed5 ¤   // if left button is not pressed, make sure dragging is finished
39827e ¤   if (!(wParam & MK_LBUTTON)) {
486416 ¤   ¤   if (pWD->bDragging) {
406dc5 ¤   ¤   ¤   TLEndDrag (pWD, lParam);
eb6a28 ¤   ¤   ¤   pWD->bDragging = FALSE;
8d0fe4 ¤   ¤   }
9499bf ¤   ¤   return;
999371 ¤   }
48af5a
b406c1 ¤   // user is dragging something around within window
c9e875 ¤   if (pWD->bDragging && (pWD->style & TLS_INTERNALDRAG)) {
894910 ¤   ¤   DragOverInternal (pWD, lParam);
579371 ¤   }
6aaf5a
f1c4b9 ¤   // if user has previously pressed an active region
b9575a ¤   else if (pWD->clickedTreeItem) {
22c377 ¤   ¤   mpt.x = LOWORD (lParam);
1e8874 ¤   ¤   mpt.y = HIWORD (lParam);
e12ebb ¤   ¤   if (PointInActiveArea (pWD->clickedTreeItem, pWD->columnItem,
b7390e ¤   ¤   ¤   pWD->iFirstColumnWidth - pWD->iHorizontalPos, mpt))·
78e783 ¤   ¤   ¤   pWD->clickedListItem->state |= TLIS_CLICKED;
39ee26 ¤   ¤   else·
c1a8db ¤   ¤   ¤   pWD->clickedListItem->state &= ~TLIS_CLICKED;
7c7766 ¤   ¤   TLInvalidateItem (pWD, pWD->clickedTreeItem);¤
f29371 ¤   }
e5af5a
d7dee4 ¤   // user is starting a drag operation
de94ad ¤   else if (!pWD->bDragging) {
6493e5 ¤   ¤   if ((pWD->iNumberSelected > 0) && (pWD->ptButtonDown.x > 0)) {
699fc6 ¤   ¤   ¤   if ((abs(pWD->ptButtonDown.x-LOWORD(lParam))>DRAGDEADZONE) ||
1f132c ¤   ¤   ¤   ¤   (abs(pWD->ptButtonDown.y-HIWORD(lParam))>DRAGDEADZONE)) {
7d133a ¤   ¤   ¤   ¤   NMHDR nmhdr;
0ae73a ¤   ¤   ¤   ¤   pWD->bDragging = TRUE;
558f13 ¤   ¤   ¤   ¤   nmhdr.code = TLN_BEGINDRAG;
2fb01f ¤   ¤   ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
e10aee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&nmhdr);
2268fc ¤   ¤   ¤   ¤   if (pWD->style & TLS_INTERNALDRAG) SetCapture (pWD->hWnd);
50a3a6 ¤   ¤   ¤   }
0e0fe4 ¤   ¤   }
b29371 ¤   }
13efe6 }
86af5a
9967c5 ¤
c8bf56 //----------------------------------------------------|
664a32 // ·Handle mouse move event
11af5a
9f58b5 void TLEndDrag (TLWndData* pWD, LPARAM lParam) {
--750a 00010c93a2e40110301 Page 6 of TLMouse.c
9f95ec ¤   POINT¤  mpt;
79af5a
9dc680 ¤   if (!pWD->bDragging) return;
44426c ¤   ReleaseCapture ();
beb6b2 ¤   SetCursor (pWD->hCursorNormal);
76af5a
fda42b ¤   if (!(pWD->style & TLS_INTERNALDRAG)) return;
ec2995 ¤   TLDeDragOverTree (pWD, pWD->rootItem, NULL);
0aaf5a
747821 ¤   mpt.x = LOWORD (lParam);
dd3322 ¤   mpt.y = HIWORD (lParam);
14e1fb ¤   if (PtInRect (&(pWD->tlInval), mpt)) {
765e59 ¤   ¤   pWD->nmTreeList.index = 1;
139371 ¤   }
c5665a ¤   else {
180485 ¤   ¤   pWD->nmTreeList.index = 0;
0a9371 ¤   }
4c5e9b ¤   pWD->nmTreeList.itemNew.hItem = NULL;
f70da2 ¤   pWD->nmTreeList.itemOld.hItem = NULL;
05f597 ¤   pWD->nmTreeList.hdr.code = TLN_DROP;
263a3a ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
66847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
93efe6 }
44af5a
6b67c5 ¤
abbf56 //----------------------------------------------------|
f6ce81 // ·Handle left mouse button down event
61af5a
6ce0e1 void TLLeftButtonDown (TLWndData* pWD, WPARAM wParam, LPARAM lParam) {
fe43c1 ¤   int i, iHitType, iHitSubItem;
8a355b ¤   TLTreeItem* pHit;
0cf065 ¤   TLColumnItem* pci;
6e7eca ¤   TLListItem* pli;
aca147 ¤   POINT mpt;
d4a752 ¤   BOOL bControl, bShift;
e4af5a
997821 ¤   mpt.x = LOWORD (lParam);
ad3322 ¤   mpt.y = HIWORD (lParam);
0faf5a
38b746 ¤   if (pWD->style & TLS_SINGLESELECT) {
c64f5d ¤   ¤   bControl = FALSE;
7b4bc1 ¤   ¤   bShift = FALSE;
e89371 ¤   }
18665a ¤   else {
ae71cb ¤   ¤   if (wParam & MK_CONTROL) bControl = TRUE;
dc343d ¤   ¤   else bControl = FALSE;
8396e6 ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000) bShift = TRUE;
eaea83 ¤   ¤   else bShift = FALSE;¤
989371 ¤   }
51af5a
1f33ce ¤   pWD->nmTreeList.hdr.code = 0;
8a5e9b ¤   pWD->nmTreeList.itemNew.hItem = NULL;
d538ac ¤   pWD->nmTreeList.itemNew.state = 0;
0f0da2 ¤   pWD->nmTreeList.itemOld.hItem = NULL;
97af5a
54ca7f ¤   pHit = PointSearchEx (pWD->rootItem, pWD->columnItem,·
58e790 ¤   ¤   ¤   ¤   ¤   ¤   ··pWD->iFirstColumnWidth - pWD->iHorizontalPos,
7023a6 ¤   ¤   ¤   ¤   ¤   ¤   ··mpt, &iHitType, &iHitSubItem);
a9af5a
4cff56 ¤   switch (iHitType) {
92f889 ¤   case TLK_NONE :
c01152 ¤   ¤   if (bControl || bShift) return;
94e9d3 ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
00cdd0 ¤   ¤   pWD->firstSelectItem = NULL;
03b89d ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
c02e8d ¤   ¤   if (pWD->focusItem) {
cae9e9 ¤   ¤   ¤   pHit = pWD->focusItem;
5ee897 ¤   ¤   ¤   pWD->focusItem = NULL;
5499e8 ¤   ¤   ¤   TLInvalidateItem (pWD, pHit);
a60fe4 ¤   ¤   }
132f68 ¤   ¤   break;
10af5a
--ccdb 00021125a0540110301 Page 7 of TLMouse.c
3370bd ¤   case TLK_BUTTON :
9c5ab7 ¤   ¤   if (pHit->state & TLIS_EXPANDED) {
21d3ac ¤   ¤   ¤   pHit->state &= ~TLIS_EXPANDED;
67d556 ¤   ¤   ¤   if (TLDeselectTree (pWD, pHit->childItem, NULL)) {
81ffcf ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
b53e7c ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
448cea ¤   ¤   ¤   ¤   pHit->state |= TLIS_SELECTED | TLIS_FOCUSED;
b79997 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
447198 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
efae81 ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
5f3e4a ¤   ¤   ¤   ¤   pWD->focusItem = pHit;
cfa3a6 ¤   ¤   ¤   }
230fe4 ¤   ¤   }
3107e0 ¤   ¤   else {
03102e ¤   ¤   ¤   pHit->state |= TLIS_EXPANDED;
03c676 ¤   ¤   ¤   if (bControl) TLExpandTree (pHit->childItem);
82fc2b ¤   ¤   ¤   TLExpandAutoScroll (pWD, pHit);
5a0fe4 ¤   ¤   }
875eb0 ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
032f68 ¤   ¤   break;
84af5a
22b22d ¤   case TLK_ACTIVE :
b982d5 ¤   ¤   pci = pWD->columnItem;
f4d6f5 ¤   ¤   for (i=1; i<iHitSubItem; i++) pci = pci->nextItem;
5f5933 ¤   ¤   if (pci->iDataFmt == TLCFMT_IMAGE) {
062b89 ¤   ¤   ¤   pWD->clickedTreeItem = pHit;
41c1c2 ¤   ¤   ¤   pli = pHit->listItem;
908fa5 ¤   ¤   ¤   for (i=1; i<iHitSubItem; i++) pli = pli->nextItem;
8fbd38 ¤   ¤   ¤   pli->state |= TLIS_CLICKED;
149ef8 ¤   ¤   ¤   pWD->clickedListItem = pli;
e599e8 ¤   ¤   ¤   TLInvalidateItem (pWD, pHit);
770fe4 ¤   ¤   }
47fa65 ¤   ¤   // fall through to select item
7faf5a
abdc2d ¤   case TLK_SELECT :
e775d3 ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = pHit;
e33a78 ¤   ¤   if (!bShift) pWD->firstSelectItem = pHit;
d47db1 ¤   ¤   if ((pHit->parentItem == pWD->firstSelectItem->parentItem) ||
d3ba48 ¤   ¤   ¤   ((pWD->style & TLS_PROMISCUOUS) && !bShift)) {
e5a9a8 ¤   ¤   ¤   if (bShift) {
99ffcf ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
b964a0 ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
29caae ¤   ¤   ¤   ¤   TLSelectRange (pWD, pWD->rootItem, pHit);
889997 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
667198 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
0eae81 ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
57a3a6 ¤   ¤   ¤   }
afe543 ¤   ¤   ¤   else {
19613e ¤   ¤   ¤   ¤   if (!(pHit->state & TLIS_SELECTED)) {
827bc6 ¤   ¤   ¤   ¤   ¤   if (!bControl) {
2c9229 ¤   ¤   ¤   ¤   ¤   ¤   if (!bControl && !bShift) {
92a9b6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, pHit);
9fbc5a ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 0;
e8db3c ¤   ¤   ¤   ¤   ¤   ¤   }
9e8ee1 ¤   ¤   ¤   ¤   ¤   ¤   pHit->state |= TLIS_SELECTED;
743f9d ¤   ¤   ¤   ¤   ¤   ¤   (pWD->iNumberSelected)++;
948608 ¤   ¤   ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pHit))·
4cb2c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
c307e7 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
db21f4 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
9d239f ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
cc1c89 ¤   ¤   ¤   ¤   ¤   }
432613 ¤   ¤   ¤   ¤   }
66a3a6 ¤   ¤   ¤   }
e11d74 ¤   ¤   ¤   if (pWD->focusItem != pHit) {
7cf6f6 ¤   ¤   ¤   ¤   if (pWD->focusItem) {
120c48 ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
d3fe35 ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.hItem = (HTLITEM)pWD->focusItem;
728c7d ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.state = pWD->focusItem->state;
e7c384 ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
7b2613 ¤   ¤   ¤   ¤   }
212a3d ¤   ¤   ¤   ¤   pHit->state |= TLIS_FOCUSED;
--3976 0000385c7b840110301 Page 8 of TLMouse.c
f53e4a ¤   ¤   ¤   ¤   pWD->focusItem = pHit;
26a3a6 ¤   ¤   ¤   }
1a99e8 ¤   ¤   ¤   TLInvalidateItem (pWD, pHit);
a60fe4 ¤   ¤   }
f52f68 ¤   ¤   break;
ef9371 ¤   }
3567c5 ¤
b0a73d ¤   if (pWD->nmTreeList.hdr.code) {
f1a2cf ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
f62989 ¤   ¤   if (pWD->iNumberSelected > 1) pWD->nmTreeList.flags |= TLC_MULTIPLE;
10e528 ¤   ¤   pWD->nmTreeList.ptDrag = mpt;
6d3d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
39847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
8e9371 ¤   }
abefe6 }
84af5a
18af5a
6abf56 //----------------------------------------------------|
8bfdf3 // ·Handle drag scrolling timer event
d2af5a
3f7207 VOID TLDragScroll (TLWndData* pWD) {
f0805b ¤   POINT¤  ¤   pt;
1daf5a
651abb ¤   pWD->uDragScrollState = 0;
4baf5a
99e875 ¤   if (pWD->bDragging && (pWD->style & TLS_INTERNALDRAG)) {
0109d9 ¤   ¤   GetCursorPos (&pt);
c0979e ¤   ¤   ScreenToClient (pWD->hWnd, &pt);
2e934f ¤   ¤   TLMouseMove (pWD, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
f29371 ¤   }
17efe6 }
b0af5a
d4af5a
fbbf56 //----------------------------------------------------|
8cce81 // ·Handle left mouse button down event
91af5a
b669d1 BOOL TLDragOver (TLWndData* pWD, LPARAM lParam) {
9fab94 ¤   int¤¤   ¤   iHitType, iHitSubItem, irow;
60355b ¤   TLTreeItem* pHit;
441a9f ¤   POINT¤  ¤   mpt;
bd71e7 ¤   BOOL¤   ¤   bRet;
52af5a
a94667 ¤   BOOL¤   bShift = FALSE;
ccaf5a
507821 ¤   mpt.x = LOWORD (lParam);
753322 ¤   mpt.y = HIWORD (lParam);
0eaf5a
0133ce ¤   pWD->nmTreeList.hdr.code = 0;
fe5e9b ¤   pWD->nmTreeList.itemNew.hItem = NULL;
2b38ac ¤   pWD->nmTreeList.itemNew.state = 0;
8d0da2 ¤   pWD->nmTreeList.itemOld.hItem = NULL;
c9af5a
7fca7f ¤   pHit = PointSearchEx (pWD->rootItem, pWD->columnItem,·
dce790 ¤   ¤   ¤   ¤   ¤   ¤   ··pWD->iFirstColumnWidth - pWD->iHorizontalPos,
9723a6 ¤   ¤   ¤   ¤   ¤   ¤   ··mpt, &iHitType, &iHitSubItem);
e9af5a
b4ff56 ¤   switch (iHitType) {
9bf889 ¤   case TLK_NONE :
7796c4 ¤   ¤   pWD->uDragScrollState = 0;
a0e9d3 ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
74cdd0 ¤   ¤   pWD->firstSelectItem = NULL;
1a2e8d ¤   ¤   if (pWD->focusItem) {
12e9e9 ¤   ¤   ¤   pHit = pWD->focusItem;
eee897 ¤   ¤   ¤   pWD->focusItem = NULL;
270fe4 ¤   ¤   }
ea675e ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
3e36e0 ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
14f948 ¤   ¤   pWD->nmTreeList.hdr.code = TLN_DRAGGEDOVER;
4f68c5 ¤   ¤   bRet = FALSE;
b02f68 ¤   ¤   break;
91af5a
03bfad ¤   default :
--35de 00032c7c73240110301 Page 9 of TLMouse.c
5a6fc3 ¤   ¤   if (pWD->uDragScrollState == 0) {
35b316 ¤   ¤   ¤   irow = 0;
3e13e8 ¤   ¤   ¤   TLGetRow (pWD->rootItem, pHit, &irow);
0e19fc ¤   ¤   ¤   if (irow == pWD->iFirstRow) {
ceffb0 ¤   ¤   ¤   ¤   pWD->iFirstRow--;
78e02c ¤   ¤   ¤   ¤   if (pWD->iFirstRow < 0)·
437aec ¤   ¤   ¤   ¤   ¤   pWD->iFirstRow = 0;
e9deaa ¤   ¤   ¤   ¤   else {
48c462 ¤   ¤   ¤   ¤   ¤   SetTimer (pWD->hWnd, DRAGSCROLLTIMERID,·
cafdee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DRAGSCROLLTIME, NULL);
e6ba63 ¤   ¤   ¤   ¤   ¤   pWD->uDragScrollState = DRAGSCROLL_DOWN;
e28516 ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
296eed ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
650526 ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_AUTOSCROLLED;
cf112c ¤   ¤   ¤   ¤   ¤   bRet = FALSE;
3314c3 ¤   ¤   ¤   ¤   ¤   break;
512613 ¤   ¤   ¤   ¤   }
3ea3a6 ¤   ¤   ¤   }
532010 ¤   ¤   ¤   if (irow == (pWD->iFirstRow + pWD->iMaxRows)) {
8762f3 ¤   ¤   ¤   ¤   pWD->iFirstRow++;
cee2d7 ¤   ¤   ¤   ¤   SetTimer (pWD->hWnd, DRAGSCROLLTIMERID,·
337012 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   DRAGSCROLLTIME, NULL);
cd3349 ¤   ¤   ¤   ¤   pWD->uDragScrollState = DRAGSCROLL_UP;
df8661 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
907fca ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
6bdf0f ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_AUTOSCROLLED;
4a2624 ¤   ¤   ¤   ¤   bRet = FALSE;
1af622 ¤   ¤   ¤   ¤   break;
04a3a6 ¤   ¤   ¤   }
440fe4 ¤   ¤   }
a95afe ¤   ¤   pWD->firstSelectItem = pHit;
ec8001 ¤   ¤   if (!(pHit->state & TLIS_SELECTED)) {
91301f ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, pHit);
7d584e ¤   ¤   ¤   pWD->iNumberSelected = 0;
8b561b ¤   ¤   ¤   pHit->state |= TLIS_SELECTED;
eb7588 ¤   ¤   ¤   (pWD->iNumberSelected)++;
d69975 ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
c7572d ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
e8ace4 ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_DRAGGEDOVER;
8c0fe4 ¤   ¤   }
f7219a ¤   ¤   if (pWD->focusItem != pHit) {
591985 ¤   ¤   ¤   if (pWD->focusItem) {
80831f ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
ec63ef ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.hItem = (HTLITEM)pWD->focusItem;
a45cd6 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.state = pWD->focusItem->state;
70a3a6 ¤   ¤   ¤   }
420fe4 ¤   ¤   }
4c5beb ¤   ¤   bRet = TRUE;
442f68 ¤   ¤   break;
2c9371 ¤   }
bf67c5 ¤
54a73d ¤   if (pWD->nmTreeList.hdr.code) {
1aa2cf ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
cae528 ¤   ¤   pWD->nmTreeList.ptDrag = mpt;
813d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
75847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
039371 ¤   }
edaf5a
ee8d4d ¤   return bRet;
39efe6 }
24af5a
c3af5a
03bf56 //----------------------------------------------------|
f37298 // ·Handle left mouse button up event
41af5a
42a00d void TLLeftButtonUp (TLWndData* pWD, WPARAM wParam, LPARAM lParam) {
0ace25 ¤   int iHitType, iHitSubItem;
90355b ¤   TLTreeItem* pHit;
92a147 ¤   POINT mpt;
78a752 ¤   BOOL bControl, bShift;
31af5a
327821 ¤   mpt.x = LOWORD (lParam);
--89d6 000b7e8d16040110301 Page 10 of TLMouse.c
ed3322 ¤   mpt.y = HIWORD (lParam);
52af5a
0db746 ¤   if (pWD->style & TLS_SINGLESELECT) {
b44f5d ¤   ¤   bControl = FALSE;
7d4bc1 ¤   ¤   bShift = FALSE;
b09371 ¤   }
15665a ¤   else {
fb71cb ¤   ¤   if (wParam & MK_CONTROL) bControl = TRUE;
d8343d ¤   ¤   else bControl = FALSE;
fb96e6 ¤   ¤   if (GetKeyState (VK_SHIFT) & 0x8000) bShift = TRUE;
08ea83 ¤   ¤   else bShift = FALSE;¤
eb9371 ¤   }
14af5a
e433ce ¤   pWD->nmTreeList.hdr.code = 0;
735e9b ¤   pWD->nmTreeList.itemNew.hItem = NULL;
cf38ac ¤   pWD->nmTreeList.itemNew.state = 0;
4b0da2 ¤   pWD->nmTreeList.itemOld.hItem = NULL;
ccaf5a
6dca7f ¤   pHit = PointSearchEx (pWD->rootItem, pWD->columnItem,·
e7e790 ¤   ¤   ¤   ¤   ¤   ¤   ··pWD->iFirstColumnWidth - pWD->iHorizontalPos,
8f23a6 ¤   ¤   ¤   ¤   ¤   ¤   ··mpt, &iHitType, &iHitSubItem);
06af5a
81ff56 ¤   switch (iHitType) {
fbf889 ¤   case TLK_NONE :
622f68 ¤   ¤   break;
a5af5a
5f70bd ¤   case TLK_BUTTON :
962f68 ¤   ¤   break;
39af5a
89b22d ¤   case TLK_ACTIVE :
303c96 ¤   ¤   if (pHit == pWD->clickedTreeItem) {
729975 ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
7b572d ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
d861d6 ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_LISTITEMCLICKED;
8c4eed ¤   ¤   ¤   pWD->nmTreeList.index = iHitSubItem;
de0fe4 ¤   ¤   }
222f68 ¤   ¤   break;
dfaf5a
07dc2d ¤   case TLK_SELECT :
0b75d3 ¤   ¤   if (!pWD->firstSelectItem) pWD->firstSelectItem = pHit;
17f643 //¤ ¤   if (!bControl && !bShift) pWD->firstSelectItem = pHit;
da3a78 ¤   ¤   if (!bShift) pWD->firstSelectItem = pHit;
3e7db1 ¤   ¤   if ((pHit->parentItem == pWD->firstSelectItem->parentItem) ||
86ba48 ¤   ¤   ¤   ((pWD->style & TLS_PROMISCUOUS) && !bShift)) {
5f2726 ¤   ¤   ¤   if (!bShift) {
7afcb5 ¤   ¤   ¤   ¤   if (pHit->state & TLIS_SELECTED) {
4fa0f0 ¤   ¤   ¤   ¤   ¤   if (bControl) {
52cd94 ¤   ¤   ¤   ¤   ¤   ¤   pHit->state &= ~TLIS_SELECTED;
b5a2de ¤   ¤   ¤   ¤   ¤   ¤   (pWD->iNumberSelected)--;
504112 ¤   ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pHit);
0e07e7 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
dc21f4 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
56239f ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
9f1c89 ¤   ¤   ¤   ¤   ¤   }
e03c4b ¤   ¤   ¤   ¤   ¤   else {
a5ba3a ¤   ¤   ¤   ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, pHit);
028ee1 ¤   ¤   ¤   ¤   ¤   ¤   pHit->state |= TLIS_SELECTED;
804887 ¤   ¤   ¤   ¤   ¤   ¤   pWD->iNumberSelected = 1;
7e8608 ¤   ¤   ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pHit))·
cdb2c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
e107e7 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
0921f4 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
bf239f ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
431c89 ¤   ¤   ¤   ¤   ¤   }
772613 ¤   ¤   ¤   ¤   }
c4deaa ¤   ¤   ¤   ¤   else {
05a0f0 ¤   ¤   ¤   ¤   ¤   if (bControl) {
888ee1 ¤   ¤   ¤   ¤   ¤   ¤   pHit->state |= TLIS_SELECTED;
d43f9d ¤   ¤   ¤   ¤   ¤   ¤   (pWD->iNumberSelected)++;
934112 ¤   ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pHit);
db8608 ¤   ¤   ¤   ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pHit))·
b7b2c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
--1562 00024e319c740110301 Page 11 of TLMouse.c
2507e7 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
ef21f4 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
49239f ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
ad1c89 ¤   ¤   ¤   ¤   ¤   }
a92613 ¤   ¤   ¤   ¤   }
ffa3a6 ¤   ¤   ¤   }
a9a6fc ¤   ¤   ¤   if (bShift || bControl) {
6224b1 ¤   ¤   ¤   ¤   if (pWD->focusItem != pHit) {
83ca18 ¤   ¤   ¤   ¤   ¤   if (pWD->focusItem) {
e1c854 ¤   ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
9f7f4c ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.hItem =·
0b764f ¤   ¤   ¤   ¤   ¤   ¤   ¤   (HTLITEM)pWD->focusItem;
c92791 ¤   ¤   ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.state =·
2392b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->focusItem->state;
480798 ¤   ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
631c89 ¤   ¤   ¤   ¤   ¤   }
d378a0 ¤   ¤   ¤   ¤   ¤   pHit->state |= TLIS_FOCUSED;
de3006 ¤   ¤   ¤   ¤   ¤   pWD->focusItem = pHit;
13ef13 ¤   ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, pHit);
b62613 ¤   ¤   ¤   ¤   }
b9a3a6 ¤   ¤   ¤   }
b80fe4 ¤   ¤   }
cd2f68 ¤   ¤   break;
c99371 ¤   }
abaf5a
766386 ¤   if (pWD->clickedTreeItem) {
a6abac ¤   ¤   pWD->clickedListItem->state &= ~TLIS_CLICKED;
748d4a ¤   ¤   TLInvalidateItem (pWD, pWD->clickedTreeItem);
03b94a ¤   ¤   pWD->clickedTreeItem = NULL;
9d9371 ¤   }
3a67c5 ¤
7ba73d ¤   if (pWD->nmTreeList.hdr.code) {
d2a2cf ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
762989 ¤   ¤   if (pWD->iNumberSelected > 1) pWD->nmTreeList.flags |= TLC_MULTIPLE;
95e528 ¤   ¤   pWD->nmTreeList.ptDrag = mpt;
d33d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
26847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
019371 ¤   }
cbefe6 }
07af5a
05af5a
b7bf56 //----------------------------------------------------|
e5cb23 // ·Handle left mouse button double click event
baaf5a
5f20f5 void TLLeftButtonDblClk (TLWndData* pWD, WPARAM wParam, LPARAM lParam) {
273581 ¤   int iHitType;
6a355b ¤   TLTreeItem* pHit;
00a147 ¤   POINT mpt;
70ac42 ¤   BOOL bControl;
7eaf5a
c77821 ¤   mpt.x = LOWORD (lParam);
d33322 ¤   mpt.y = HIWORD (lParam);
7daf5a
453ef5 ¤   if (wParam & MK_CONTROL) bControl = TRUE;
292015 ¤   else bControl = FALSE;
e6af5a
50bb1a ¤   pHit = PointSearch (pWD->rootItem, mpt, &iHitType);
fcaf5a
64ff56 ¤   switch (iHitType) {
c6f889 ¤   case TLK_NONE :
6b2f68 ¤   ¤   break;
5faf5a
a270bd ¤   case TLK_BUTTON :
a25ab7 ¤   ¤   if (pHit->state & TLIS_EXPANDED) {
09d3ac ¤   ¤   ¤   pHit->state &= ~TLIS_EXPANDED;
c30fe4 ¤   ¤   }
d307e0 ¤   ¤   else {
1f102e ¤   ¤   ¤   pHit->state |= TLIS_EXPANDED;
84c676 ¤   ¤   ¤   if (bControl) TLExpandTree (pHit->childItem);
05fc2b ¤   ¤   ¤   TLExpandAutoScroll (pWD, pHit);
340fe4 ¤   ¤   }
245eb0 ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
--7fa6 0002e819af740110301 Page 12 of TLMouse.c
4f2f68 ¤   ¤   break;
92af5a
5adc2d ¤   case TLK_SELECT :
a15ab7 ¤   ¤   if (pHit->state & TLIS_EXPANDED) {
9ed3ac ¤   ¤   ¤   pHit->state &= ~TLIS_EXPANDED;
120fe4 ¤   ¤   }
4207e0 ¤   ¤   else {
a2102e ¤   ¤   ¤   pHit->state |= TLIS_EXPANDED;
65c676 ¤   ¤   ¤   if (bControl) TLExpandTree (pHit->childItem);
6cfc2b ¤   ¤   ¤   TLExpandAutoScroll (pWD, pHit);
100fe4 ¤   ¤   }
d95eb0 ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
242f68 ¤   ¤   break;
ad9371 ¤   }
86efe6 }
a2af5a
f1af5a
dcbf56 //----------------------------------------------------|
221900 // ·Handle right mouse button down event
93af5a
4cf5f7 void TLRightButtonDown (TLWndData* pWD, WPARAM wParam, LPARAM lParam) {
aa3581 ¤   int iHitType;
8b355b ¤   TLTreeItem* pHit;
5ea147 ¤   POINT mpt;
8eaf5a
409dfb ¤   if (wParam & MK_CONTROL) return;
b03727 ¤   if (GetKeyState (VK_SHIFT) & 0x8000) return;
66af5a
a77821 ¤   mpt.x = LOWORD (lParam);
603322 ¤   mpt.y = HIWORD (lParam);
23af5a
6bc30d ¤   pWD->nmTreeList.flags = 0;
345e9b ¤   pWD->nmTreeList.itemNew.hItem = NULL;
b30da2 ¤   pWD->nmTreeList.itemOld.hItem = NULL;
91af5a
5dbb1a ¤   pHit = PointSearch (pWD->rootItem, mpt, &iHitType);
7baf5a
52ff56 ¤   switch (iHitType) {
23f889 ¤   case TLK_NONE :
65e9d3 ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
d6cdd0 ¤   ¤   pWD->firstSelectItem = NULL;
0fa2cf ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
202e8d ¤   ¤   if (pWD->focusItem) {
f0e9e9 ¤   ¤   ¤   pHit = pWD->focusItem;
80e897 ¤   ¤   ¤   pWD->focusItem = NULL;
1d99e8 ¤   ¤   ¤   TLInvalidateItem (pWD, pHit);
960fe4 ¤   ¤   }
a42f68 ¤   ¤   break;
e4af5a
b570bd ¤   case TLK_BUTTON :
1b2f68 ¤   ¤   break;
e6af5a
c7dc2d ¤   case TLK_SELECT :
408001 ¤   ¤   if (!(pHit->state & TLIS_SELECTED)) {
c6301f ¤   ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, pHit);
77561b ¤   ¤   ¤   pHit->state |= TLIS_SELECTED;
450292 ¤   ¤   ¤   pWD->iNumberSelected = 1;
429c95 ¤   ¤   ¤   if (TLSelectAutoScroll (pWD, pHit))·
b6a22c ¤   ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
1c9975 ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)pHit;
1d572d ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = pHit->state;
0dedf1 ¤   ¤   ¤   pWD->nmTreeList.flags |= TLC_BYMOUSE;
1f0fe4 ¤   ¤   }
002e8d ¤   ¤   if (pWD->focusItem) {
18d6b3 ¤   ¤   ¤   pWD->focusItem->state &= ~TLIS_FOCUSED;
676499 ¤   ¤   ¤   pWD->nmTreeList.itemOld.hItem = (HTLITEM)pWD->focusItem;
d84f5a ¤   ¤   ¤   pWD->nmTreeList.itemOld.state = pWD->focusItem->state;
62197f ¤   ¤   ¤   TLInvalidateItem (pWD, pWD->focusItem);
670fe4 ¤   ¤   }
202968 ¤   ¤   pHit->state |= TLIS_FOCUSED;
c2f3c6 ¤   ¤   pWD->focusItem = pHit;
2ea506 ¤   ¤   TLInvalidateItem (pWD, pHit);
--c554 0002febb67640110301 Page 13 of TLMouse.c
4f2f68 ¤   ¤   break;
d99371 ¤   }
9367c5 ¤
429261 ¤   if (pWD->nmTreeList.flags) {
e92989 ¤   ¤   if (pWD->iNumberSelected > 1) pWD->nmTreeList.flags |= TLC_MULTIPLE;
2bb89d ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
b9e528 ¤   ¤   pWD->nmTreeList.ptDrag = mpt;
373d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
e3847c ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
999371 ¤   }
24efe6 }
26af5a
d5af5a
b1bf56 //----------------------------------------------------|
cf48d3 // ·Handle column resizing
f6af5a
d93575 void ColumnResize (TLWndData* pWD, HD_NOTIFY* hdn) {
6af065 ¤   TLColumnItem* pci;
04a875 ¤   int i, scx, left;
36d1f4 ¤   HD_ITEM hdi;
1be1fc ¤   RECT rcInval;
78af5a
18562c ¤   if (hdn->iButton == 0) {
213673 ¤   ¤   rcInval = pWD->tlInval;
753467 ¤   ¤   left = pWD->iFirstColumnWidth;
17392a ¤   ¤   if (hdn->iItem == 0) {
43c070 ¤   ¤   ¤   scx = hdn->pitem->cxy - pWD->iFirstColumnWidth;
3aad5d ¤   ¤   ¤   pWD->iFirstColumnWidth = hdn->pitem->cxy;
bb9c6e ¤   ¤   ¤   rcInval.right = pWD->iFirstColumnWidth + scx +1;
6acdc7 ¤   ¤   ¤   if (scx < 0) rcInval.left = rcInval.right - 24;
161714 ¤   ¤   ¤   else rcInval.left = pWD->iFirstColumnWidth - 24;
4f0fe4 ¤   ¤   }
3d07e0 ¤   ¤   else {
630eaa ¤   ¤   ¤   pci = pWD->columnItem;
152b5c ¤   ¤   ¤   left += pci->cx;
5021ff ¤   ¤   ¤   rcInval.left = pWD->iFirstColumnWidth;
3ba01c ¤   ¤   ¤   for (i=1; i<hdn->iItem; i++) {
8c781d ¤   ¤   ¤   ¤   rcInval.left += pci->cx;
0bce08 ¤   ¤   ¤   ¤   pci = pci->nextItem;
f0900a ¤   ¤   ¤   ¤   left += pci->cx;
5da3a6 ¤   ¤   ¤   }
598edf ¤   ¤   ¤   scx = hdn->pitem->cxy - pci->cx;
29b25c ¤   ¤   ¤   pci->cx = hdn->pitem->cxy;
67bb49 ¤   ¤   ¤   if (pci->cx >= BITMAPWIDTH)·
74b334 ¤   ¤   ¤   ¤   pci->cxImageOffset = (pci->cx - BITMAPWIDTH) / 2;
d16b93 ¤   ¤   ¤   else·
25e92f ¤   ¤   ¤   ¤   pci->cxImageOffset = 0;
a8cebd ¤   ¤   ¤   rcInval.right = left + scx +1;
d90fe4 ¤   ¤   }
9baf5a
fa82d5 ¤   ¤   pci = pWD->columnItem;
1860d7 ¤   ¤   pWD->iTotalWidth = pWD->iFirstColumnWidth;
9f0dea ¤   ¤   for (i=1; i<pWD->iNumberColumns; i++) {
f1e888 ¤   ¤   ¤   pWD->iTotalWidth += pci->cx;
aaf360 ¤   ¤   ¤   pci = pci->nextItem;
c30fe4 ¤   ¤   }
43af5a
6351bc ¤   ¤   hdi.mask = HDI_WIDTH;
ace593 ¤   ¤   hdi.cxy = hdn->pitem->cxy;
0c1cbd ¤   ¤   Header_SetItem (pWD->hWndHeader, hdn->iItem, &hdi);
b67b83 ¤   ¤   rcInval.left -= pWD->iHorizontalPos;
ff25a0 ¤   ¤   rcInval.right -= pWD->iHorizontalPos;
2c2ea3 ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, FALSE);
b4900f ¤   ¤   if ((scx < 0) && (pWD->iHorizontalPos > 0)) {
24282b ¤   ¤   ¤   i = pWD->iHorizontalPos + scx;
db7151 ¤   ¤   ¤   if (i < 0) i = 0;
8a6a07 ¤   ¤   ¤   SendMessage (pWD->hWnd, WM_HSCROLL,·
edf7e4 ¤   ¤   ¤   ¤   MAKEWPARAM (SB_THUMBPOSITION, i), 0);
597805 ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
400fe4 ¤   ¤   }
749371 ¤   }
2fefe6 }
--5785 0005a3b496840110301 Page 14 of TLMouse.c
e0af5a
1aaf5a
aebf56 //----------------------------------------------------|
9d64de // ·Handle header notifications
3caf5a
4e3645 BOOL TLHeaderNotification (TLWndData* pWD, NMHEADER* pnmh) {
0daf5a
06f7eb ¤   switch (pnmh->hdr.code) {
1886e3 ¤   case HDN_ENDTRACK :
3d75b8 ¤   case HDN_TRACK :
c5733b ¤   ¤   if (pnmh->iButton == 0) {
b10f22 ¤   ¤   ¤   ColumnResize (pWD, pnmh);
0a0fe4 ¤   ¤   }
002f68 ¤   ¤   break;
1baf5a
a86c80 ¤   case HDN_ITEMCLICK :
19733b ¤   ¤   if (pnmh->iButton == 0) {
8d2984 ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_HEADERCLICKED;
15c433 ¤   ¤   ¤   pWD->nmTreeList.index = pnmh->iItem;
ac3de3 ¤   ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
9ceb4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
a20fe4 ¤   ¤   }
0f2f68 ¤   ¤   break;
d8af5a
8e28e5 ¤   case HDN_BEGINDRAG :
c098aa ¤   ¤   return FALSE;
f5af5a
ad4904 ¤   case HDN_ENDDRAG :
df157d ¤   ¤   if (pnmh->iItem == 0) return TRUE;
7d3d76 ¤   ¤   if (pnmh->pitem->iOrder == 0) return TRUE;
aeb43a ¤   ¤   SetTimer (pWD->hWnd, REORDERTIMERID, REORDERTIMEOUT, NULL);
b598aa ¤   ¤   return FALSE;
4eaf5a
849371 ¤   }
03af5a
c4a230 ¤   return FALSE;
6cefe6 }
baaf5a
deaf5a
b1bf56 //----------------------------------------------------|
6f3dd2 // ·Handle horizontal scrolling
4baf5a
f712e9 void TLHScroll (TLWndData* pWD, int code, int pos, HWND hWndBar) {
ca8c9d ¤   int pagesize;
63254a ¤   int newpos;
87effb ¤   int scrollamount;
81af5a
5c8aaa ¤   pagesize = pWD->tlInval.right - pWD->tlInval.left;
053c0c ¤   newpos = pWD->iHorizontalPos;
6aaf5a
496e67 ¤   switch (code) {
6d56fc ¤   case SB_TOP :
6ddf27 ¤   ¤   newpos = 0;
e12f68 ¤   ¤   break;
f1af5a
90da62 ¤   case SB_BOTTOM :
11d24f ¤   ¤   newpos = (pWD->iTotalWidth-pagesize);
e82f68 ¤   ¤   break;
6faf5a
403788 ¤   case SB_PAGELEFT :
76e23f ¤   ¤   newpos -= pagesize;
178ce1 ¤   ¤   if (newpos < 0) newpos = 0;
a92f68 ¤   ¤   break;
4aaf5a
54d27d ¤   case SB_PAGERIGHT :
e4ffd1 ¤   ¤   newpos += pagesize;
1d6ecd ¤   ¤   if (newpos > (pWD->iTotalWidth-pagesize))·
f99d71 ¤   ¤   ¤   newpos = (pWD->iTotalWidth-pagesize);
af2f68 ¤   ¤   break;
81af5a
34ff2c ¤   case SB_LINELEFT :
5a3064 ¤   ¤   newpos-=3;
--c4c4 00012ae182240110301 Page 15 of TLMouse.c
a98ce1 ¤   ¤   if (newpos < 0) newpos = 0;
752f68 ¤   ¤   break;
7aaf5a
eb319b ¤   case SB_LINERIGHT :
de0bfc ¤   ¤   newpos+=3;
f96ecd ¤   ¤   if (newpos > (pWD->iTotalWidth-pagesize))·
129d71 ¤   ¤   ¤   newpos = (pWD->iTotalWidth-pagesize);
922f68 ¤   ¤   break;
1faf5a
e88029 ¤   case SB_THUMBPOSITION :
95cea1 ¤   case SB_THUMBTRACK :
26c70f ¤   ¤   newpos = pos;
a22f68 ¤   ¤   break;
72af5a
60bfad ¤   default :
ad99bf ¤   ¤   return;
ae9371 ¤   }
166eff ¤   scrollamount = pWD->iHorizontalPos - newpos;
63cd16 ¤   pWD->iHorizontalPos = newpos;
5e43a2 ¤   if (scrollamount) {
c70a30 ¤   ¤   ScrollWindowEx (pWD->hWnd, scrollamount, 0, NULL, &(pWD->tlRect),
2dae68 ¤   ¤   ¤   ¤   ¤   ¤   NULL, NULL, SW_INVALIDATE|SW_SCROLLCHILDREN);·
27c15d ¤   ¤   UpdateWindow (pWD->hWnd);
f19371 ¤   }
36efe6 }
a0af5a
27af5a
6bbf56 //----------------------------------------------------|
0041b8 // ·Handle window resizing
6eaf5a
1e0b63 void TLResize (TLWndData* pWD, WINDOWPOS* pWP) {
d83356 ¤   int dx, dy;
bb67c5 ¤
159797 ¤   dx = pWD->tlRect.right - pWP->cx;
75738a ¤   if ((dx < 0) && (pWD->iHorizontalPos > 0)) {
cd640d ¤   ¤   dx += pWD->iHorizontalPos;
641fde ¤   ¤   if (dx < 0) dx = 0;
4e389a ¤   ¤   SendMessage (pWD->hWnd, WM_HSCROLL,·
476b38 ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (SB_THUMBPOSITION, dx), 0);
3b9371 ¤   }
7d86f5 ¤   pWD->tlRect.right = pWP->cx;
d01b52 ¤   ¤
62d422 ¤   dy = pWD->tlRect.bottom - pWP->cy;
f0b7dd ¤   if ((dy < 0) && (pWD->iFirstRow > 0)) {
5d0dbf ¤   ¤   dy += (pWD->iFirstRow * pWD->iRowHeight);
9b4faf ¤   ¤   dy /= pWD->iRowHeight;
c0c821 ¤   ¤   if (dy < 0) dy = 0;
926b33 ¤   ¤   SendMessage (pWD->hWnd, WM_VSCROLL,·
38ea87 ¤   ¤   ¤   ¤   ¤   ¤   MAKEWPARAM (SB_THUMBPOSITION, dy), 0);
889371 ¤   }
82a167 ¤   pWD->tlRect.bottom = pWP->cy;
a3af5a
a52226 ¤   TLDeleteMemDC (pWD);
b7af5a
57ed64 ¤   pWD->tlInval = pWD->tlRect;
e4cd9a ¤   pWD->tlInval.top += pWD->iRowHeight+1;
9baf5a
b63183 ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
5eefe6 }
44af5a
15af5a
eebf56 //----------------------------------------------------|
ca387e // ·Handle vertical scrolling
89af5a
902aa0 void TLVScroll (TLWndData* pWD, int code, int pos, HWND hWndBar) {
beeffb ¤   int scrollamount;
6a50a3 ¤   int newrow;
88af5a
ae64b1 ¤   newrow = pWD->iFirstRow;
e1af5a
166e67 ¤   switch (code) {
1256fc ¤   case SB_TOP :
--1a82 00080b6fc4740110301 Page 16 of TLMouse.c
0f2bab ¤   ¤   newrow = 0;
7c2f68 ¤   ¤   break;
65af5a
39da62 ¤   case SB_BOTTOM :
7f907a ¤   ¤   newrow = (pWD->iExpandedRows-pWD->iMaxRows);
3b2f68 ¤   ¤   break;
aaaf5a
3165fb ¤   case SB_PAGEUP :
ef40a3 ¤   ¤   newrow -= pWD->iMaxRows;
a94bb3 ¤   ¤   if (newrow < 0) newrow = 0;
202f68 ¤   ¤   break;
09af5a
b26061 ¤   case SB_PAGEDOWN :
0b42d3 ¤   ¤   newrow += pWD->iMaxRows;
f36226 ¤   ¤   if (newrow > (pWD->iExpandedRows-pWD->iMaxRows))·
4724ce ¤   ¤   ¤   newrow = (pWD->iExpandedRows-pWD->iMaxRows) +1;
eb2f68 ¤   ¤   break;
ccaf5a
2fb6c5 ¤   case SB_LINEUP :
6c9edf ¤   ¤   newrow--;
804bb3 ¤   ¤   if (newrow < 0) newrow = 0;
ed2f68 ¤   ¤   break;
55af5a
aea8c5 ¤   case SB_LINEDOWN :
7a039c ¤   ¤   newrow++;
076226 ¤   ¤   if (newrow > (pWD->iExpandedRows-pWD->iMaxRows))·
1724ce ¤   ¤   ¤   newrow = (pWD->iExpandedRows-pWD->iMaxRows) +1;
4c2f68 ¤   ¤   break;
d5af5a
b38029 ¤   case SB_THUMBPOSITION :
82cea1 ¤   case SB_THUMBTRACK :
e653c8 ¤   ¤   newrow = pos;
0d2f68 ¤   ¤   break;
ecaf5a
cebfad ¤   default :
fa99bf ¤   ¤   return;
169371 ¤   }
bfaf5a
188869 ¤   scrollamount = pWD->iFirstRow - newrow;
298c09 ¤   pWD->iFirstRow = newrow;
bcaf5a
3d43a2 ¤   if (scrollamount) {
e15eb0 ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
8e9371 ¤   }
20efe6 }
62af5a
b5af5a
50bf56 //----------------------------------------------------|
2927e8 // ·Handle "Intellimouse" wheel scrolling
2aaf5a
47b665 void TLMouseWheel (TLWndData* pWD, int iKeys, short int iDelta) {
efeffb ¤   int scrollamount;
df50a3 ¤   int newrow;
b2af5a
6c64b1 ¤   newrow = pWD->iFirstRow;
eaaf5a
0748d6 ¤   // if buttons or keyboard keys are pressed, don't do anything
36a368 ¤   if (iKeys != 0) return;
05af5a
5ca41a ¤   // sum incoming movements of wheel
da7a95 ¤   pWD->iWheelDelta += iDelta;
7caf5a
0d6bbb ¤   // positive value => wheel rotated away from user => scroll up
a9d07f ¤   if (pWD->iWheelDelta >= WHEELTHRESHOLD) {
3308fd ¤   ¤   if ((pWD->iWheelScroll == WHEEL_PAGESCROLL) ||
6b56c6 ¤   ¤   ¤   (pWD->iWheelScroll > pWD->iMaxRows))
7b7dcb ¤   ¤   ¤   newrow -= pWD->iMaxRows;
0aee26 ¤   ¤   else·
073bc2 ¤   ¤   ¤   newrow -= pWD->iWheelScroll;
699ed3 ¤   ¤   pWD->iWheelDelta = 0;
ae4bb3 ¤   ¤   if (newrow < 0) newrow = 0;
809371 ¤   }
--a55d 0014c1cb64540110301 Page 17 of TLMouse.c
e0af5a
90cea3 ¤   // negative value => wheel rotated toward user => scroll down
ba6c77 ¤   else if (pWD->iWheelDelta <= (-1 * WHEELTHRESHOLD)) {
cd08fd ¤   ¤   if ((pWD->iWheelScroll == WHEEL_PAGESCROLL) ||
d056c6 ¤   ¤   ¤   (pWD->iWheelScroll > pWD->iMaxRows))
b67fbb ¤   ¤   ¤   newrow += pWD->iMaxRows;
9bee26 ¤   ¤   else·
8bd43f ¤   ¤   ¤   newrow += pWD->iWheelScroll;
4b9ed3 ¤   ¤   pWD->iWheelDelta = 0;
4d6226 ¤   ¤   if (newrow > (pWD->iExpandedRows-pWD->iMaxRows))·
3724ce ¤   ¤   ¤   newrow = (pWD->iExpandedRows-pWD->iMaxRows) +1;
f99371 ¤   }
97af5a
699828 ¤   // not reached threshold => no movement
458f09 ¤   else return;
59af5a
038869 ¤   scrollamount = pWD->iFirstRow - newrow;
a78c09 ¤   pWD->iFirstRow = newrow;
72af5a
bd43a2 ¤   if (scrollamount) {
dc5eb0 ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
cb9371 ¤   }
ccefe6 }
75af5a
4caf5a
--0368 0008de07f2040110302 Page 1 of TLMsgPrc.c
dff900 //:TLMsgProc.c - TreeList message processing routine
d1465d //
9a538b //¤ $Id: TLMsgPrc.c,v 1.19.2.1 1998/10/08 15:35:12 pbj Exp $
6e465d //
d5af5a
0dfb2c #include "TLintern.h"
6538ab #include <math.h>
2daf5a
63af5a
f9bf56 //----------------------------------------------------|
1dddb8 // ·Message processing function for TreeList class
c0af5a
47fbee LRESULT WINAPI TreeListMsgProc (HWND hWnd, UINT msg, WPARAM wParam,·
73af28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam) {
b8af5a
fb78a0 ¤   PAINTSTRUCT ps;
820755 ¤   HDC hdc;
992328 ¤   DWORD dwStyle;
0daf5a
fb95ba ¤   TLWndData* pWD = TreeList_GetPtr(hWnd);
78af5a
f7399d ····if (pWD == NULL) {
7ee3b8 ········if (msg == WM_NCCREATE) {
aa5e9c ········¤   pWD = (TLWndData*)TLAlloc (sizeof(TLWndData));
1f8a3e ········¤   if (pWD == NULL) return 0L;
201f7f ········¤   TreeList_SetPtr (hWnd, pWD);
297fb0 ········}
0505d7 ········else {
eb4691 ········¤   return DefWindowProc (hWnd, msg, wParam, lParam);
f67fb0 ········}
586fe7 ····}
6467c5 ¤
7db9b6 ····if (msg == WM_NCDESTROY) {
c4abdf ¤   ¤   TLFree (pWD);
5cb05d ········pWD = NULL;
67d1db ········TreeList_SetPtr (hWnd, NULL);
fd6fe7 ····}
2aaf5a
05a9d2 ¤   switch (msg) {
d7af5a
de055f ¤   case WM_CREATE :
e5bb0d ¤   ¤   pWD->hWnd = hWnd;
b31f3d ¤   ¤   pWD->hWndParent = ((LPCREATESTRUCT)lParam)->hwndParent;
889134 ¤   ¤   pWD->hdcMem = NULL;
777a49 ¤   ¤   pWD->id = (LONG)((LPCREATESTRUCT)lParam)->hMenu;·
4e9d3d ¤   ¤   pWD->style = (LONG)((LPCREATESTRUCT)lParam)->style;
ecd092 ¤   ¤   pWD->bTreeFocused = FALSE;
b996c4 ¤   ¤   pWD->uDragScrollState = 0;
3bd2d0 ¤   ¤   pWD->rootItem = NULL;
c725bf ¤   ¤   pWD->columnItem = NULL;
0a6ef8 ¤   ¤   pWD->hImageList = NULL;
22237c ¤   ¤   pWD->hCursorNormal = GetCursor ();
df0126 ¤   ¤   pWD->hCursorDragging =·
2f6c76 ¤   ¤   ¤   LoadCursor (GetModuleHandle (NULL), "TreeListDraggingCursor");
bda4db ¤   ¤   if (!(pWD->hCursorDragging)) pWD->hCursorDragging = GetCursor ();
18f492 ¤   ¤   pWD->hCursorNoDrag = LoadCursor (NULL, IDC_NO);
f60d39 ¤   ¤   if (!(pWD->hCursorNoDrag)) pWD->hCursorNoDrag = GetCursor ();
1bcdd0 ¤   ¤   pWD->firstSelectItem = NULL;
0d64e8 ¤   ¤   pWD->focusItem = NULL;
7cbe67 ¤   ¤   pWD->iNumberColumns = 0;
160fe3 ¤   ¤   pWD->iHorizontalPos = 0;
bf991b ¤   ¤   pWD->iFirstRow = 0;
2d9ed3 ¤   ¤   pWD->iWheelDelta = 0;
56f516 ¤   ¤   pWD->iWheelScroll = 3;
dbb73d ¤   ¤   pWD->iNumberSelected = 0;
33b94a ¤   ¤   pWD->clickedTreeItem = NULL;
e7e1d4 ¤   ¤   pWD->bDragging = FALSE;
cf4cee ¤   ¤   pWD->nmTreeList.hdr.hwndFrom = hWnd;
6d17e8 ¤   ¤   pWD->bStillTyping = FALSE;
9fde6e ¤   ¤   pWD->szTypeBuf[0] = '\0';
250b63 ¤   ¤   pWD->pTypeBufPtr = &(pWD->szTypeBuf[0]);
8d4455 ¤   ¤   pWD->iNumCharInTypeBuf = 0;
--cf18 000567126da40110302 Page 2 of TLMsgPrc.c
e0af5a
fbee97 ¤   ¤   TLInitPaint (pWD);
43af5a
4d5635 ¤   ¤   // create a vertical scroll bar
c9f11f ¤   ¤   GetClientRect (pWD->hWnd, &pWD->tlRect);
6aaf5a
bd5ee3 ¤   ¤   // create header control
1cada6 ¤   ¤   dwStyle = WS_VISIBLE | WS_CHILD | HDS_HORZ | HDS_BUTTONS;
6b163e ¤   ¤   if (pWD->style & TLS_DRAGABLEHEADERS)·
f7c96c ¤   ¤   ¤   dwStyle |= HDS_DRAGDROP;
fde022 ¤   ¤   pWD->hWndHeader = CreateWindowEx (0L, WC_HEADER, (LPCTSTR) NULL,
9fd7b4 ¤   ¤   ¤   dwStyle, 0, 0, 30000, pWD->iRowHeight+1,
98f857 ¤   ¤   ¤   hWnd, (HMENU)IDC_TREELISTHEADER, 0, NULL);
80ed3f ¤   ¤   SendMessage (pWD->hWndHeader, WM_SETFONT, (WPARAM)pWD->hFont, FALSE);
612f68 ¤   ¤   break;
dbaf5a
a3f491 ¤   case WM_ERASEBKGND :
0be102 ¤   ¤   return 1;
65af5a
eef4f5 ¤   case WM_KILLFOCUS :
2d24b2 ¤   ¤   if (!pWD->bDragging) {
599161 ¤   ¤   ¤   pWD->bTreeFocused = FALSE;
d3fa1a ¤   ¤   ¤   InvalidateRect (hWnd, NULL, FALSE);
2e0fe4 ¤   ¤   }
5dbbde ¤   ¤   return 0;
b2af5a
86524f ¤   case WM_SETFOCUS :
8eef86 ¤   ¤   pWD->bTreeFocused = TRUE;
3d6e29 ¤   ¤   if (!pWD->focusItem) {
0a4a94 ¤   ¤   ¤   if (pWD->rootItem) {
bfe92f ¤   ¤   ¤   ¤   pWD->focusItem = pWD->rootItem;
816b1c ¤   ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
f1a3a6 ¤   ¤   ¤   }
910fe4 ¤   ¤   }
09ee26 ¤   ¤   else·
d67a3b ¤   ¤   ¤   pWD->focusItem->state |= TLIS_FOCUSED;
e1e24a ¤   ¤   InvalidateRect (hWnd, NULL, FALSE);
42bbde ¤   ¤   return 0;
d9af5a
b20e5c ¤   case WM_GETDLGCODE :
f09f4a ¤   ¤   return DLGC_WANTARROWS | DLGC_WANTCHARS;
70af5a
3585ca ¤   case WM_PAINT :
164fb2 ¤   ¤   TLPrePaint (pWD);
f83173 ¤   ¤   hdc = BeginPaint (pWD->hWnd, &ps);
0f791f ¤   ¤   TLMemPaint (pWD, hdc);
85ee0c ¤   ¤   EndPaint (pWD->hWnd, &ps);
24bbde ¤   ¤   return 0;
99af5a
fd3fac ¤   case TLM_DRAGOVERPAINT :
b64fb2 ¤   ¤   TLPrePaint (pWD);
e8a837 ¤   ¤   hdc = GetDCEx (pWD->hWnd, NULL, DCX_LOCKWINDOWUPDATE);
38791f ¤   ¤   TLMemPaint (pWD, hdc);
85fa8b ¤   ¤   ReleaseDC (pWD->hWnd, hdc);
2cbbde ¤   ¤   return 0;
47af5a
733673 ¤   case TLM_RENDERDRAGBITMAP :
f04fb2 ¤   ¤   TLPrePaint (pWD);
87f4a9 ¤   ¤   return ((BOOL)TLMemPaintDragBitmap (pWD, (LPTL_DRAGBITMAP)lParam));
74af5a
ba8523 ¤   case TLM_DRAGOVER :
2fef86 ¤   ¤   pWD->bTreeFocused = TRUE;
b24f89 ¤   ¤   return ((LRESULT)TLDragOver (pWD, lParam));
d8af5a
75475b ¤   case WM_LBUTTONDOWN :
4d94ae ¤   ¤   SetFocus (hWnd);
c250ad ¤   ¤   TLEndDrag (pWD, lParam);
4fe1d4 ¤   ¤   pWD->bDragging = FALSE;
8a3863 ¤   ¤   TLLeftButtonDown (pWD, wParam, lParam);
9a87e5 ¤   ¤   pWD->ptButtonDown.x = LOWORD (lParam);
c6cce6 ¤   ¤   pWD->ptButtonDown.y = HIWORD (lParam);
56bbde ¤   ¤   return 0;
--b3ab 0009d14541740110302 Page 3 of TLMsgPrc.c
e0af5a
626373 ¤   case WM_LBUTTONUP :
f3988d ¤   ¤   if (pWD->bDragging) TLEndDrag (pWD, lParam);
4443e2 ¤   ¤   else TLLeftButtonUp (pWD, wParam, lParam);
70e1d4 ¤   ¤   pWD->bDragging = FALSE;
c32f68 ¤   ¤   break;
4aaf5a
5b7082 ¤   case WM_RBUTTONDOWN :
2a94ae ¤   ¤   SetFocus (hWnd);
5b50ad ¤   ¤   TLEndDrag (pWD, lParam);
7ee1d4 ¤   ¤   pWD->bDragging = FALSE;
397e0e ¤   ¤   TLRightButtonDown (pWD, wParam, lParam);
22bbde ¤   ¤   return 0;
caaf5a
524919 ¤   case WM_LBUTTONDBLCLK :
b194ae ¤   ¤   SetFocus (hWnd);
a350ad ¤   ¤   TLEndDrag (pWD, lParam);
15e1d4 ¤   ¤   pWD->bDragging = FALSE;
e83121 ¤   ¤   TLLeftButtonDblClk (pWD, wParam, lParam);
84bbde ¤   ¤   return 0;
c5af5a
f18406 ¤   case WM_RBUTTONDBLCLK :
f494ae ¤   ¤   SetFocus (hWnd);
272f68 ¤   ¤   break;
b2af5a
7ce1c7 ¤   case WM_MOUSEMOVE :
6e1d30 ¤   ¤   TLMouseMove (pWD, wParam, lParam);
cebbde ¤   ¤   return 0;
59af5a
1032e7 ¤   case TLM_INSERTITEM :
4cd0f4 ¤   ¤   return ((LRESULT)TLInsertTreeItem (pWD, (LPTL_INSERTSTRUCT)lParam));
4baf5a
ad9245 ¤   case TLM_DELETEITEM :
77ed6f ¤   ¤   return ((LRESULT)TLDeleteTreeItem (pWD, (TL_TREEITEM*)lParam));
5baf5a
aa447f ¤   case TLM_GETITEM :
15883f ¤   ¤   return ((LRESULT)TLGetTreeItem (pWD, (TL_TREEITEM*)lParam));
b5af5a
2126b1 ¤   case TLM_SETITEM :
8568c7 ¤   ¤   return ((LRESULT)TLSetTreeItem (pWD, (TL_TREEITEM*)lParam));
adaf5a
ada456 ¤   case TLM_GETFIRSTITEM :
b9738f ¤   ¤   return ((LRESULT)pWD->rootItem);
0eaf5a
80ed52 ¤   case TLM_INSERTCOLUMN :
e6ff8c ¤   ¤   return ((LRESULT)TLInsertColumn (pWD, wParam, (TL_COLUMN*)lParam));
c5af5a
5f3cd0 ¤   case TLM_SETCOLUMN :
3d7c51 ¤   ¤   return ((LRESULT)TLSetColumn (pWD, wParam, (TL_COLUMN*)lParam));
47af5a
579d2a ¤   case TLM_DELETEALLCOLUMNS :
265485 ¤   ¤   return (TLDeleteAllColumns (pWD));
41af5a
20b6a4 ¤   case TLM_GETCOLUMNWIDTH :
b0443d ¤   ¤   return ((LRESULT)TLGetColumnWidth (pWD, wParam));
9e1b52 ¤   ¤
857671 ¤   case TLM_SETIMAGELIST :
25d2d6 ¤   ¤   pWD->hImageList = (HIMAGELIST)lParam;
fdbbde ¤   ¤   return 0;
0faf5a
51a2cb ¤   case TLM_SETLISTITEM :
142705 ¤   ¤   return ((LRESULT)TLSetListItem (pWD, (TL_LISTITEM*)lParam,
a0ae98 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (BOOL)wParam));
54af5a
4d87a5 ¤   case TLM_GETLISTITEM :
c4b4a5 ¤   ¤   return ((LRESULT)TLGetListItem (pWD, (TL_LISTITEM*)lParam));
b1af5a
b0385e ¤   case TLM_EXPAND :
082b54 ¤   ¤   return ((LRESULT)TLExpandTreeItem (pWD, (TL_TREEITEM*)lParam,·
b1ae5b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam));
91af5a
9d1c67 ¤   case TLM_SELECTITEM :
--d2e4 00003227d2e40110302 Page 4 of TLMsgPrc.c
297be8 ¤   ¤   return ((LRESULT)TLSelectTreeItem (pWD, (TL_TREEITEM*)lParam,·
93ae5b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   wParam));
09af5a
64aa8e ¤   case TLM_SELECTCHILDREN :
495e65 ¤   ¤   return ((LRESULT)TLSelectChildren (pWD, (TL_TREEITEM*)lParam));
94af5a
b54012 ¤   case TLM_ENSUREVISIBLE :
2622ce ¤   ¤   return ((LRESULT)TLEnsureVisible (pWD, (TL_TREEITEM*)lParam));
feaf5a
83b7e1 ¤   case TLM_ITERATESELECTED :
05c692 ¤   ¤   return ((LRESULT)TLIterateSelected (pWD, lParam));
3baf5a
b1f4e1 ¤   case TLM_DELETETREE :
3e1972 ¤   ¤   if (wParam) TLDeleteTreeList (pWD->rootItem);
09d2d0 ¤   ¤   pWD->rootItem = NULL;
4664e8 ¤   ¤   pWD->focusItem = NULL;
2ccdd0 ¤   ¤   pWD->firstSelectItem = NULL;
6fb73d ¤   ¤   pWD->iNumberSelected = 0;
78991b ¤   ¤   pWD->iFirstRow = 0;
a9836c ¤   ¤   return TRUE;
46af5a
d48db4 ¤   case TLM_GETORDERARRAY :
6a7e11 ¤   ¤   return (SendMessage (pWD->hWndHeader,·
43b7fb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   HDM_GETORDERARRAY, wParam, lParam));
8daf5a
9e2a4f ¤   case TLM_SETWHEELSCROLLLINES :
82e04a ¤   ¤   pWD->iWheelScroll = lParam;
f02f68 ¤   ¤   break;
5faf5a
425122 ¤   case WM_TIMER :
5aa6a9 ¤   ¤   KillTimer (hWnd, wParam);
3cc5a3 ¤   ¤   switch (wParam) {
d844de ¤   ¤   case KEYBOARDTIMERID :
cf561b ¤   ¤   ¤   pWD->bStillTyping = FALSE;
aecdcb ¤   ¤   ¤   break;
f869a7 ¤   ¤   case REORDERTIMERID :
30c17b ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_HEADERREORDERED;
cf3de3 ¤   ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
20eb4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
21cdcb ¤   ¤   ¤   break;
d8fa0e ¤   ¤   case DRAGSCROLLTIMERID :
0a98a6 ¤   ¤   ¤   TLDragScroll (pWD);
0fcdcb ¤   ¤   ¤   break;
b90fe4 ¤   ¤   }
db2f68 ¤   ¤   break;
1daf5a
521431 ¤   case WM_NOTIFY :
8ac5a3 ¤   ¤   switch (wParam) {
951c25 ¤   ¤   case IDC_TREELISTHEADER :
21f066 ¤   ¤   ¤   return TLHeaderNotification (pWD, (NMHEADER*)lParam);
720fe4 ¤   ¤   }
5a2f68 ¤   ¤   break;
ac1b52 ¤   ¤
a325ea ¤   case WM_HSCROLL :
dd10de ¤   ¤   TLHScroll (pWD, LOWORD (wParam), HIWORD (wParam), (HWND)lParam);
cabbde ¤   ¤   return 0;
e7af5a
e87643 ¤   case WM_VSCROLL :
6df2d4 ¤   ¤   TLVScroll (pWD, LOWORD (wParam), HIWORD (wParam), (HWND)lParam);
ffbbde ¤   ¤   return 0;
c1af5a
d8a7eb ¤   case WM_MOUSEWHEEL :
7c2b1d ¤   ¤   TLMouseWheel (pWD, LOWORD (wParam), HIWORD (wParam));
4fbbde ¤   ¤   return 0;
00af5a
da30d7 ¤   case WM_WINDOWPOSCHANGED :
3bcd10 ¤   ¤   TLResize (pWD, (WINDOWPOS*)lParam);
40bbde ¤   ¤   return 0;
2eaf5a
c990ef ¤   case WM_SIZE :
4dcccd ¤   case WM_MOVE :
03bbde ¤   ¤   return 0;
--bcbb 0010a90df8240110302 Page 5 of TLMsgPrc.c
e0af5a
a5507d ¤   case WM_KEYDOWN :
4d7e22 ¤   ¤   TLKeyboardChar (pWD, wParam, lParam);
b72f68 ¤   ¤   break;
ccaf5a
0f9a87 ¤   case WM_SYSCOLORCHANGE :
abe2cd ¤   ¤   TLClosePaint (pWD);
74ee97 ¤   ¤   TLInitPaint (pWD);
281083 ¤   ¤   SetWindowPos (pWD->hWndHeader, 0, 0, 0, 30000, pWD->iRowHeight+1,·
f3cd8b ¤   ¤   ¤   ¤   ¤   ¤   SWP_NOZORDER|SWP_NOMOVE);
52ed3f ¤   ¤   SendMessage (pWD->hWndHeader, WM_SETFONT, (WPARAM)pWD->hFont, FALSE);
e22f68 ¤   ¤   break;
26af5a
f2651b ¤   case WM_CONTEXTMENU :
4ce637 ¤   ¤   pWD->nmTreeList.hdr.code = TLN_CONTEXTMENU;
9a302c ¤   ¤   pWD->nmTreeList.ptDrag.x = LOWORD (lParam);
c87b2f ¤   ¤   pWD->nmTreeList.ptDrag.y = HIWORD (lParam);
023d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
2deb4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
c8bbde ¤   ¤   return 0;
89af5a
2e4621 ¤   case WM_CHAR :
0f0ef0 ¤   ¤   if ((pWD->style & TLS_AUTOSCROLL) && ~(lParam & 0x80000000)) {
9baccc ¤   ¤   ¤   TLSelectByKeyboard (pWD, wParam, pWD->bStillTyping);
a87e24 ¤   ¤   ¤   pWD->bStillTyping = TRUE;
381681 ¤   ¤   ¤   SetTimer (hWnd, KEYBOARDTIMERID, KEYTIMEOUT, NULL);
e30fe4 ¤   ¤   }
e4c738 ¤   ¤   pWD->nmKeyDown.hdr.code = TLN_CHAR;
d3f67c ¤   ¤   pWD->nmKeyDown.wVKey = wParam;
41bfee ¤   ¤   pWD->nmKeyDown.flags = lParam;
5e3d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
af7205 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmKeyDown));
b02f68 ¤   ¤   break;
26af5a
be75f9 ¤   case WM_CLOSE :
22167b ¤   ¤   TLDeleteMemDC (pWD);
3fe2cd ¤   ¤   TLClosePaint (pWD);
cdbd3e ¤   ¤   TLDeleteTreeList (pWD->rootItem);
62d2d0 ¤   ¤   pWD->rootItem = NULL;
f71b4d ¤   ¤   TLDeleteAllColumns (pWD);
c925bf ¤   ¤   pWD->columnItem = NULL;
ee2f68 ¤   ¤   break;
dcaf5a
ef47d1 ¤   }·
d9074d ¤   return (DefWindowProc (hWnd, msg, wParam, lParam));
ceaf5a
0aefe6 }
--830e 0005d16a08c40110303 Page 1 of TLPaint.c
daa599 //:TLPaint.c - paint tree list
43465d //
75650a //¤ $Id: TLPaint.c,v 1.18 1998/07/20 18:01:38 pbj Exp $
3f465d //
415799 #include "TLIntern.h"
0b38ab #include <math.h>
2eaf5a
6e3be9 typedef struct _DOTTEDSTRUCT {
398b3d ¤   HDC hDC;
b289ab ¤   DWORD dwDottedColor;
7a0c9c } DOTTEDSTRUCT;
b1af5a
84af5a
01bf56 //----------------------------------------------------|
76f255 // Initialize painting routines -- create pens, brushes, etc.
4caf5a
e7c8c0 void TLInitPaint (TLWndData* pWD) {
595d90 ¤   DWORD rgb;
54d2e2 ¤   BYTE r, g, b;
b1c1dd ¤   LOGFONT lf;
46e21f ¤   HDC hdcMem, hdcScreen;
6feba6 ¤   HBITMAP hOldBitmap;
a50dc1 ¤   TEXTMETRIC tm;
825bda ¤   RECT rc;
90b176 ¤   HPEN pen;
454ba4 ¤   int i;
48af5a
8dcfb1 ¤   hdcMem = CreateCompatibleDC (NULL);¤
4faf5a
804d44 ¤   pWD->selbgbrush = CreateSolidBrush (GetSysColor (COLOR_HIGHLIGHT));
3dc5bd ¤   pWD->unselbgbrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
24692c ¤   pWD->selfgbrush = CreateSolidBrush (GetSysColor (COLOR_HIGHLIGHTTEXT));
d3a33d ¤   pWD->unselfgbrush = CreateSolidBrush (GetSysColor (COLOR_WINDOWTEXT));
13af5a
794cef ¤   pWD->unselfocuscolor = GetSysColor (COLOR_HIGHLIGHT);
ee6230 ¤   r = GetRValue (pWD->unselfocuscolor);
698ad8 ¤   if (r > 127) r = 0;
d9791d ¤   else r = 255;
ff758b ¤   g = GetGValue (pWD->unselfocuscolor);
82c848 ¤   if (g > 127) g = 0;
30f491 ¤   else g = 255;
83ad96 ¤   b = GetBValue (pWD->unselfocuscolor);
699e99 ¤   if (b > 127) b = 0;
378689 ¤   else b = 255;
1063af ¤   pWD->selfocuscolor = PALETTERGB (r, g, b);
a3af5a
f36265 ¤   pWD->seltextpen = CreatePen (PS_SOLID, 0,·
b35a24 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_HIGHLIGHTTEXT));
2adb2c ¤   pWD->unseltextpen = CreatePen (PS_SOLID, 0,·
5070ec ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_WINDOWTEXT));
7baf5a
8590fd ····pWD->buttonpen = CreatePen(PS_SOLID, 0, GetSysColor (COLOR_3DSHADOW));
419edc ¤   pWD->linecolor = GetSysColor (COLOR_3DSHADOW);
f4af5a
602c88 ¤   pWD->barcolor = GetSysColor (COLOR_3DSHADOW);
734ba2 ¤   pWD->stdbarbrush = CreateSolidBrush (GetSysColor (COLOR_3DSHADOW));
8e8ea6 ¤   pWD->spcbarbrush = CreateHatchBrush (HS_BDIAGONAL,·
671453 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_HIGHLIGHTTEXT));
13af5a
3012ab ¤   pWD->hilightpen = CreatePen (PS_SOLID, 0,·
4b8cfd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DHILIGHT));
d5d5ce ¤   pWD->shadowpen = CreatePen (PS_SOLID, 0,·
2d3dd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   GetSysColor (COLOR_3DDKSHADOW));
e8af5a
ad95e6 ¤   // GetDeviceCaps returns positive value for displays with 2-256 colors
bfba82 ¤   if (GetDeviceCaps (hdcMem, NUMCOLORS) > 0) {
fffabb ¤   ¤   hdcScreen = GetDC (NULL);
0487a6 ¤   ¤   pWD->barbgbitmap = CreateCompatibleBitmap (hdcScreen, 8, 8);
d7fac3 ¤   ¤   hOldBitmap = SelectObject (hdcMem, pWD->barbgbitmap);
040dd3 ¤   ¤   rc.left = 0;
b961be ¤   ¤   rc.top = 0;
5d2909 ¤   ¤   rc.bottom = 8;
--a214 0003619e99e40110303 Page 2 of TLPaint.c
90a6d6 ¤   ¤   rc.right = 8;
7fd97b ¤   ¤   FillRect (hdcMem, &rc, pWD->unselbgbrush);
17355e ¤   ¤   pen = CreatePen (PS_SOLID, 0, GetSysColor (COLOR_3DLIGHT));
020885 ¤   ¤   SelectObject (hdcMem, pen);
886183 ¤   ¤   for (i=-8; i<8; i+=2) {
be11e6 ¤   ¤   ¤   MoveToEx (hdcMem, i, 0, NULL);
32fd4b ¤   ¤   ¤   LineTo (hdcMem, i+8, 8);
8b0fe4 ¤   ¤   }
7bf70a ¤   ¤   DeleteObject (pen);
d5ecf9 ¤   ¤   pWD->barbgbrush = CreatePatternBrush (pWD->barbgbitmap);
edd7c9 ¤   ¤   SelectObject (hdcMem, hOldBitmap);
d8bf2f ¤   ¤   ReleaseDC (NULL, hdcScreen);
959371 ¤   }
5c6225 ¤   // GetDeviceCaps returns -1 for displays with more than 8 bit depth
3a665a ¤   else {
953813 ¤   ¤   rgb = GetSysColor (COLOR_BTNFACE);
19849d ¤   ¤   r = GetRValue (rgb);
d154e6 ¤   ¤   r = 255 - ((255 - r)/2);
d85b36 ¤   ¤   g = GetGValue (rgb);
4643ab ¤   ¤   g = 255 - ((255 - g)/2);
733cb9 ¤   ¤   b = GetBValue (rgb);
17a69f ¤   ¤   b = 255 - ((255 - b)/2);
7a6c4a ¤   ¤   pWD->barbgbitmap = NULL;
1ccb80 ¤   ¤   pWD->barbgbrush = CreateSolidBrush (RGB (r,g,b));
219371 ¤   }
ecaf5a
95eddc ¤   SystemParametersInfo (SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0);
29af5a
e1e3bc ¤   pWD->hFont = CreateFontIndirect (&lf);
72cc65 ¤   lf.lfItalic = !lf.lfItalic;
4a640b ¤   pWD->hFontItalic = CreateFontIndirect (&lf);
1bcc65 ¤   lf.lfItalic = !lf.lfItalic;
6bddc1 ¤   lf.lfWeight = FW_BOLD;
1aff46 ¤   pWD->hFontBold = CreateFontIndirect (&lf);
00af5a
ee25b5 ¤   SelectObject (hdcMem, pWD->hFont);
bdc125 ¤   GetTextMetrics (hdcMem, &tm);
4d25ee ¤   pWD->iRowHeight = tm.tmHeight + (2 * (TEXTVERTOFF+1)) -1;
daaf5a
24e17a ¤   DeleteDC (hdcMem);
c7efe6 }
49af5a
c9af5a
7fbf56 //----------------------------------------------------|
604443 // Close painting routines -- delete pens, brushes, etc.
2faf5a
cd54e8 void TLClosePaint (TLWndData* pWD) {
bac320 ¤   DeleteObject (pWD->selbgbrush);
f6d630 ¤   DeleteObject (pWD->unselbgbrush);
d073bc ¤   DeleteObject (pWD->selfgbrush);
9866ac ¤   DeleteObject (pWD->unselfgbrush);
0e2e21 ¤   DeleteObject (pWD->stdbarbrush);
beba0d ¤   DeleteObject (pWD->spcbarbrush);
66a1b3 ¤   DeleteObject (pWD->barbgbrush);
d097f9 ¤   DeleteObject (pWD->seltextpen);
ee82e9 ¤   DeleteObject (pWD->unseltextpen);
d4b738 ¤   DeleteObject (pWD->buttonpen);
44066e ¤   DeleteObject (pWD->hilightpen);
a4a413 ¤   DeleteObject (pWD->shadowpen);
76c545 ¤   DeleteObject (pWD->hFont);
2cf4a5 ¤   DeleteObject (pWD->hFontItalic);
eada5b ¤   DeleteObject (pWD->hFontBold);
f61062 ¤   if (pWD->barbgbitmap) DeleteObject (pWD->barbgbitmap);
d5efe6 }
95af5a
8baf5a
eebf56 //----------------------------------------------------|
eb58d0 // ·Truncate text string
4eaf5a
b872e4 void TruncateText (HDC hdc, char * szorig, int xmax, char * sztrunc) {
1698c0 ¤   SIZE s;
36fc13 ¤   int l, w;
--a3f8 00009473c5c40110303 Page 3 of TLPaint.c
a6bf69 ¤   lstrcpy (sztrunc, szorig);
482f20 ¤   GetTextExtentPoint32 (hdc, szorig, lstrlen (szorig), &s);
6ff201 ¤   w = s.cx + 4;
7caf5a
f42eea ¤   l = lstrlen (szorig);
1915bb ¤   if (l < 3) {
9ffbd3 ¤   ¤   if (w > xmax) lstrcpy (sztrunc, "");
3a9371 ¤   }
2f665a ¤   else {
72681d ¤   ¤   l = lstrlen (szorig) - 3;
27b838 ¤   ¤   while ((w > xmax) && (l >= 0)) {
c8f931 ¤   ¤   ¤   lstrcpy (&sztrunc[l], "...");
5f0a66 ¤   ¤   ¤   GetTextExtentPoint32 (hdc, sztrunc, lstrlen (sztrunc), &s);
260f2e ¤   ¤   ¤   w = s.cx + 4;
af3afb ¤   ¤   ¤   l--;
073b90 ¤   ¤   }¤
c0ed2c ¤   ¤   if (l < 0) lstrcpy (sztrunc, "");
db9371 ¤   }
ebefe6 }
f6af5a
d4af5a
a1bf56 //----------------------------------------------------|
37705c // ·Calculate how many lines are needed
dfaf5a
052abf int CountRows (TLTreeItem* p) {
9e8034 ¤   int i = 0;
9867c5 ¤
61d3a5 ¤   while (p) {
bf347d ¤   ¤   i++;
5b586b ¤   ¤   if (p->childItem && (p->state & TLIS_EXPANDED))·
83dbec ¤   ¤   ¤   i += CountRows (p->childItem);
bb26cb ¤   ¤   p = p->nextItem;
cb9371 ¤   }
8b2196 ¤   return i;
5cefe6 }
4eaf5a
8faf5a
f6bf56 //----------------------------------------------------|
4ff8fd // ·Get row number of item
79af5a
895f95 BOOL TLGetRow (TLTreeItem* root, TLTreeItem* p, int* row) {
a767c5 ¤
6790aa ¤   while (root) {
ef4adb ¤   ¤   if (p == root) return TRUE;
74b1ab ¤   ¤   (*row)++;
ff2d4c ¤   ¤   if (root->childItem && (root->state & TLIS_EXPANDED)) {
8d3023 ¤   ¤   ¤   if (TLGetRow (root->childItem, p, row)) return TRUE;
540fe4 ¤   ¤   }
c41cc1 ¤   ¤   root = root->nextItem;
759371 ¤   }
cea230 ¤   return FALSE;
c3efe6 }
e9af5a
e2af5a
e7bf56 //----------------------------------------------------|
ef61ba // ·Item has just been expanded -- scroll window appropriately
03af5a
ee6e6c void TLExpandAutoScroll (TLWndData* pWD, TLTreeItem* p) {
f1fa78 ¤   int itemRow = 0;
21af5a
50aa0b ¤   if (TLGetRow (pWD->rootItem, p, &itemRow)) {
482fdb ¤   ¤   if (((itemRow-pWD->iFirstRow) + p->cChildren) >= pWD->iMaxRows) {
cfb00f ¤   ¤   ¤   if (p->cChildren >= pWD->iMaxRows) pWD->iFirstRow = itemRow;
8d9f48 ¤   ¤   ¤   else pWD->iFirstRow = itemRow + p->cChildren - pWD->iMaxRows +1;
ecd7fd ¤   ¤   ¤   if (pWD->iFirstRow < 0) pWD->iFirstRow = 0;
360fe4 ¤   ¤   }
139371 ¤   }
97830f ¤   return;
5befe6 }
3c67c5 ¤
a3af5a
09bf56 //----------------------------------------------------|
--fc8f 000fe588cf240110303 Page 4 of TLPaint.c
6c52b8 // ·Item has just been selected -- scroll window appropriately
f2af5a
6d5a94 BOOL TLSelectAutoScroll (TLWndData* pWD, TLTreeItem* p) {
fdfa78 ¤   int itemRow = 0;
45af5a
73aa0b ¤   if (TLGetRow (pWD->rootItem, p, &itemRow)) {
51b3c8 ¤   ¤   if ((itemRow-pWD->iFirstRow) >= pWD->iMaxRows) {
59f372 ¤   ¤   ¤   pWD->iFirstRow = itemRow - pWD->iMaxRows +1;
54d7fd ¤   ¤   ¤   if (pWD->iFirstRow < 0) pWD->iFirstRow = 0;
1532bd ¤   ¤   ¤   return TRUE;
8d0fe4 ¤   ¤   }
591a36 ¤   ¤   if (itemRow < pWD->iFirstRow) {
67a671 ¤   ¤   ¤   pWD->iFirstRow = itemRow;
ac32bd ¤   ¤   ¤   return TRUE;
c40fe4 ¤   ¤   }
739371 ¤   }
c7a230 ¤   return FALSE;
6cefe6 }
0167c5 ¤
42af5a
4fbf56 //----------------------------------------------------|
6f016a // ·Invalidate the specified item
f4af5a
9fa821 void TLInvalidateItem (TLWndData* pWD, TLTreeItem* p) {
485bda ¤   RECT rc;
5ba23b ¤   rc = p->hiliteRect;
35dd2c ¤   rc.left = pWD->tlInval.left;
d2e932 ¤   InvalidateRect (pWD->hWnd, &rc, TRUE);¤
e8efe6 }
8067c5 ¤
24af5a
2bbf56 //----------------------------------------------------|
b30939 // ·draw a dotted line by setting alternate pixels
092e28 // ·(callback to LineDDA)
94af5a
09d51b void CALLBACK DottedLineProc (INT iX, INT iY, LPARAM lpData) {
dc5635 ¤   DOTTEDSTRUCT *pDottedStruct;
77af5a
de3fbd ¤   pDottedStruct = (DOTTEDSTRUCT*)lpData;
49baa5 ¤   if (!((iX+iY) & 0x0001))·
328d34 ¤   ¤   SetPixel (pDottedStruct->hDC, iX, iY, pDottedStruct->dwDottedColor);
feefe6 }
bc67c5 ¤
04af5a
cabf56 //----------------------------------------------------|
facfde // ·Paint one level of list
ceaf5a
9d6e08 void PaintItems (HDC hdc, TLWndData* pWD, int *item, int* y, int indent,·
19446c ¤   ¤   ¤   ¤   ¤   ¤   ¤   TLTreeItem* p) {
8738b4 ¤   HBRUSH oldbrush, bgbrush, fgbrush, barbrush;
576c0e ¤   INT iBCent, iBMPos;
bb491f ¤   HPEN oldpen, textpen;
6398c0 ¤   SIZE s;
fe98ad ¤   INT ix, iy, cx, xoffset;
1ff065 ¤   TLColumnItem* pci;
947eca ¤   TLListItem* pli;
ba5bda ¤   RECT rc;
f51ee8 ¤   DOTTEDSTRUCT DottedStruct;
677a71 ¤   double f;
de9c42 ¤   char sz256[256];
ebaf5a
9d7548 ¤   iBCent = pWD->iBCent;
02f54f ¤   iBMPos = pWD->iBMPos;
971455 ¤   DottedStruct.hDC = hdc;
a9af5a
3c86dd ¤   xoffset = indent - pWD->iHorizontalPos;
dbaf5a
2ad3a5 ¤   while (p) {
4daf5a
5ef5fb ¤   ¤   // ·increment item count
44b217 ¤   ¤   (*item)++;
fe700d ¤   ¤   // ·check if items are visible in window
--7992 0007796a12040110303 Page 5 of TLPaint.c
427f5c ¤   ¤   if ((*item) > (pWD->iFirstRow + pWD->iMaxRows + 2)) break;
844342 ¤   ¤   if ((*item) > pWD->iFirstRow) {
1daf5a
c06ab9 ¤   ¤   ¤   // ·first paint the tree items ·...
265451 ¤   ¤   ¤   // ·select colors based on state of tree item
b52789 ¤   ¤   ¤   if (pWD->bTreeFocused &&·
0535bf ¤   ¤   ¤   ¤   (p->state & (TLIS_SELECTED|TLIS_DRAGGEDOVER))) {
ed8f85 ¤   ¤   ¤   ¤   bgbrush = pWD->selbgbrush;
e0f151 ¤   ¤   ¤   ¤   fgbrush = pWD->selfgbrush;
810041 ¤   ¤   ¤   ¤   textpen = pWD->seltextpen;
7f2ad4 ¤   ¤   ¤   ¤   DottedStruct.dwDottedColor = pWD->selfocuscolor;
02cb9c ¤   ¤   ¤   ¤   pWD->textbgcolor = GetSysColor (COLOR_HIGHLIGHT);
9af6c1 ¤   ¤   ¤   ¤   SetTextColor (hdc, GetSysColor (COLOR_HIGHLIGHTTEXT));
07a3a6 ¤   ¤   ¤   }
99e543 ¤   ¤   ¤   else {
4b4f6e ¤   ¤   ¤   ¤   bgbrush = pWD->unselbgbrush;
ba8c7c ¤   ¤   ¤   ¤   fgbrush = pWD->unselfgbrush;
24b975 ¤   ¤   ¤   ¤   textpen = pWD->unseltextpen;
204dcd ¤   ¤   ¤   ¤   DottedStruct.dwDottedColor = pWD->unselfocuscolor;
c91fe1 ¤   ¤   ¤   ¤   pWD->textbgcolor = GetSysColor (COLOR_WINDOW);
f4e0ee ¤   ¤   ¤   ¤   SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
2ba3a6 ¤   ¤   ¤   }
939cc6 ¤   ¤   ¤   SetBkColor (hdc, pWD->textbgcolor);
3c1b52 ¤   ¤
3702af ¤   ¤   ¤   // ·set rectangle coordinates·
dac9a9 ¤   ¤   ¤   // ·rectangle sensitive to "selection" mouse clicks
c284b5 ¤   ¤   ¤   p->selectRect.left = xoffset + BUTTONWIDTH;
764c90 ¤   ¤   ¤   p->selectRect.right = pWD->tlInval.right;
073c84 ¤   ¤   ¤   p->selectRect.top = *y+1;
09cebd ¤   ¤   ¤   p->selectRect.bottom = p->selectRect.top + pWD->iRowHeight;
0faf5a
14a9cd ¤   ¤   ¤   // ·rectangle sensitive to "button" mouse clicks
f92220 ¤   ¤   ¤   if (p->cChildren && (pWD->style & TLS_HASBUTTONS)) {
0e558c ¤   ¤   ¤   ¤   p->buttonRect.left = xoffset;
1033c5 ¤   ¤   ¤   ¤   p->buttonRect.right = p->buttonRect.left + BUTTONWIDTH;
0c7775 ¤   ¤   ¤   ¤   p->buttonRect.top = *y;
802f96 ¤   ¤   ¤   ¤   p->buttonRect.bottom = p->buttonRect.top + pWD->iRowHeight;
2ca3a6 ¤   ¤   ¤   }
d6e543 ¤   ¤   ¤   else {
94c163 ¤   ¤   ¤   ¤   p->buttonRect.left = xoffset + BUTTONWIDTH;
bbcb66 ¤   ¤   ¤   ¤   p->buttonRect.right = xoffset + BUTTONWIDTH;
737775 ¤   ¤   ¤   ¤   p->buttonRect.top = *y;
271f7c ¤   ¤   ¤   ¤   p->buttonRect.bottom = 0;
10a3a6 ¤   ¤   ¤   }
8baf5a
4f1ec5 ¤   ¤   ¤   // ·rectangle which is highlighted when item is selected
9cc578 ¤   ¤   ¤   p->hiliteRect.left =·
3ca9e9 ¤   ¤   ¤   ¤   min (xoffset + BUTTONWIDTH+BITMAPWIDTH+HTEXTSHIFT,
61b6d3 ¤   ¤   ¤   ¤   ¤   ·pWD->iFirstColumnWidth);
d7f621 ¤   ¤   ¤   p->hiliteRect.top = *y+1;
292eab ¤   ¤   ¤   p->hiliteRect.bottom = p->selectRect.top + pWD->iRowHeight;
adecde ¤   ¤   ¤   if (p->state & TLIS_BOLD) SelectObject (hdc, pWD->hFontBold);
b4a649 ¤   ¤   ¤   else if (p->state & TLIS_ITALICS)·
b5ac64 ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->hFontItalic);
17cff7 ¤   ¤   ¤   else SelectObject (hdc, pWD->hFont);
ed47c4 ¤   ¤   ¤   TruncateText (hdc, p->pszText,·
505b54 ¤   ¤   ¤   ¤   pWD->iFirstColumnWidth-
661ed3 ¤   ¤   ¤   ¤   (indent + BUTTONWIDTH+BITMAPWIDTH+HTEXTSHIFT),·
d46c9b ¤   ¤   ¤   ¤   sz256);
e5f1fb ¤   ¤   ¤   GetTextExtentPoint32 (hdc, sz256, lstrlen (sz256), &s);
88b1fc ¤   ¤   ¤   p->hiliteRect.right = p->hiliteRect.left + s.cx + HTEXTSHIFT;
8863e4 ¤   ¤   ¤   pli = p->listItem;
6e0eaa ¤   ¤   ¤   pci = pWD->columnItem;
c849f1 ¤   ¤   ¤   ix = pWD->iFirstColumnWidth;
eadb90 ¤   ¤   ¤   while (pci && pli) {
72f4c4 ¤   ¤   ¤   ¤   ix += pci->cx;
3900df ¤   ¤   ¤   ¤   if (pli->state & TLIS_VISIBLE) p->hiliteRect.right = ix;
c5ce08 ¤   ¤   ¤   ¤   pci = pci->nextItem;
8b97ba ¤   ¤   ¤   ¤   pli = pli->nextItem;
23a3a6 ¤   ¤   ¤   }
30af5a
7709ad ¤   ¤   ¤   // ·if focused, draw box
--e794 00082d6aef040110303 Page 6 of TLPaint.c
bdf1d0 ¤   ¤   ¤   FillRect (hdc, &p->hiliteRect, bgbrush);
a5bd2c ¤   ¤   ¤   if (pWD->bTreeFocused && (p->state & TLIS_FOCUSED)) {
cba7e2 ¤   ¤   ¤   ¤   LineDDA (p->hiliteRect.left, p->hiliteRect.top,
cd29a9 ¤   ¤   ¤   ¤   ¤   ¤   ·p->hiliteRect.right-1, p->hiliteRect.top,
6b471b ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc, (LPARAM)&DottedStruct);
1b7bc0 ¤   ¤   ¤   ¤   LineDDA (p->hiliteRect.right-1, p->hiliteRect.top,
7bfe7b ¤   ¤   ¤   ¤   ¤   ¤   ·p->hiliteRect.right-1, p->hiliteRect.bottom-1,
ca471b ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc, (LPARAM)&DottedStruct);
f2e2cc ¤   ¤   ¤   ¤   LineDDA (p->hiliteRect.right-1, p->hiliteRect.bottom-1,
5d3843 ¤   ¤   ¤   ¤   ¤   ¤   ·p->hiliteRect.left, p->hiliteRect.bottom-1,
82471b ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc, (LPARAM)&DottedStruct);
effb99 ¤   ¤   ¤   ¤   LineDDA (p->hiliteRect.left, p->hiliteRect.bottom-1,
e2cc84 ¤   ¤   ¤   ¤   ¤   ¤   ·p->hiliteRect.left, p->hiliteRect.top,
38471b ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc, (LPARAM)&DottedStruct);
e4a3a6 ¤   ¤   ¤   }
95af5a
dc6c76 ¤   ¤   ¤   // ·draw tree item text·
260930 ¤   ¤   ¤   iy = p->hiliteRect.top + TEXTVERTOFF;
14bd73 ¤   ¤   ¤   SetTextAlign (hdc, TA_LEFT);
d5a3dc ¤   ¤   ¤   TextOut (hdc, p->hiliteRect.left+2, iy, sz256, lstrlen(sz256));
98af5a
addab4 ¤   ¤   ¤   // ·draw tree item bitmap, if there is space
027c0c ¤   ¤   ¤   if (pWD->iFirstColumnWidth >= (p->buttonRect.right+BITMAPWIDTH)) {
816790 ¤   ¤   ¤   ¤   ImageList_Draw (pWD->hImageList, p->iImage, hdc,
f758eb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.right, p->hiliteRect.top+iBMPos,
41d808 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILD_TRANSPARENT);
82a3a6 ¤   ¤   ¤   }
97af5a
d14655 ¤   ¤   ¤   // ·paint list items based on their data type
0d5c62 ¤   ¤   ¤   SelectObject (hdc, pWD->hFont);
5063e4 ¤   ¤   ¤   pli = p->listItem;
030eaa ¤   ¤   ¤   pci = pWD->columnItem;
ec9992 ¤   ¤   ¤   ix = pWD->iFirstColumnWidth - pWD->iHorizontalPos;
a7af5a
6fdb90 ¤   ¤   ¤   while (pci && pli) {
caaf5a
db6d7b ¤   ¤   ¤   ¤   if (pli->state & TLIS_VISIBLE) {
67af5a
532471 ¤   ¤   ¤   ¤   ¤   switch (pci->iDataType) {
9bbd4b ¤   ¤   ¤   ¤   ¤   case TLC_DATANONE :
5700eb ¤   ¤   ¤   ¤   ¤   ¤   break;
2eaf5a
ff725d ¤   ¤   ¤   ¤   ¤   case TLC_DATASTRING :
b301c5 ¤   ¤   ¤   ¤   ¤   ¤   TruncateText (hdc, pli->pszText, pci->cx, sz256);
8cd07c ¤   ¤   ¤   ¤   ¤   ¤   SetBkColor (hdc, pWD->textbgcolor);
ffbc50 ¤   ¤   ¤   ¤   ¤   ¤   switch (pci->iDataFmt) {
84517d ¤   ¤   ¤   ¤   ¤   ¤   case TLCFMT_LEFT :
d7d57e ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTextAlign (hdc, TA_LEFT);
3e9707 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TextOut (hdc, ix+6, iy, sz256, lstrlen(sz256));
408c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
02af5a
ef2466 ¤   ¤   ¤   ¤   ¤   ¤   case TLCFMT_CENTER :
c0043b ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTextAlign (hdc, TA_CENTER);
1ace91 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TextOut (hdc, ix + (pci->cx>>1), iy,·
e7cb63 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz256, lstrlen(sz256));
128c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
21af5a
2f7239 ¤   ¤   ¤   ¤   ¤   ¤   case TLCFMT_RIGHT :
6c665f ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTextAlign (hdc, TA_RIGHT);
64b6ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   TextOut (hdc, ix + pci->cx - 6, iy,·
33cb63 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz256, lstrlen(sz256));
be8c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
0edb3c ¤   ¤   ¤   ¤   ¤   ¤   }
1900eb ¤   ¤   ¤   ¤   ¤   ¤   break;
1aaf5a
0ab386 ¤   ¤   ¤   ¤   ¤   case TLC_DATALONG :
e7bc50 ¤   ¤   ¤   ¤   ¤   ¤   switch (pci->iDataFmt) {
11fe76 ¤   ¤   ¤   ¤   ¤   ¤   case TLCFMT_LINBAR :
8d8fb2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   cx = pci->cx - BARCOLUMNDIFF;
fb7de8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (cx <= 0) break;
d51f1a ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left = ix + HBARSHIFT;
821195 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.top = iy + VBARSHIFT +1;
--6d45 000a2319c4340110303 Page 7 of TLPaint.c
33d7ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = ix + pci->cx - HBARSHIFT -1;
ed8401 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.bottom = iy+pWD->iRowHeight-(VBARSHIFT+2) -1;
4e2da6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   oldbrush = SelectObject (hdc, pWD->barbgbrush);
ec62b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   oldpen = SelectObject (hdc, pWD->buttonpen);
c9df1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   Rectangle (hdc, rc.left - 1, rc.top - 1,·
116d4c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right + 2, rc.bottom + 2);
cfaf5a
a4e1a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->shadowpen);
934217 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, rc.left, rc.bottom, NULL);
1c309d ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left, rc.top);
03ce2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.top);
ebaf5a
35813b ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->hilightpen);
05f61b ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.bottom);
067525 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left, rc.bottom);
9ce624 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
1e8921 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pci->lMaxValue != 0) {
9b12bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pli->lDataValue > pci->lMaxValue) {
85f316 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   barbrush = pWD->spcbarbrush;
120ba4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = rc.left + cx;
1f6560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
ede5ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else {
b45686 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   barbrush = pWD->stdbarbrush;
21f4df ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = rc.left +·
e93a82 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (int)(((float)pli->lDataValue /·
59f309 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (float)pci->lMaxValue)
d479d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   * (float)cx);
476560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
9a5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
4828e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else·
d48943 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = rc.left;
c9af5a
85faff ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.top++;
b35070 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left++;
4faf5a
a3d0b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (rc.right > rc.left) {
fa47f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetBkColor (hdc, pWD->barcolor);
584bd1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FillRect (hdc, &rc, barbrush);·
06af5a
c65b52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.top--;
e9c37f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left--;
7daf5a
1b5964 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // hilight pen already selected·
3d4ce8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, rc.right, rc.top, NULL);
45307f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left, rc.top);
be7e37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left,rc.bottom);
79af5a
3cdcce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->shadowpen);
837be7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.bottom);
780a32 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.top);
3f5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
bbaf5a
482bd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, oldbrush);
157fae ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, oldpen);
198c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
2faf5a
82a2fe ¤   ¤   ¤   ¤   ¤   ¤   case TLCFMT_LOGBAR :
1c1f1a ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left = ix + HBARSHIFT;
741195 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.top = iy + VBARSHIFT +1;
20d7ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = ix + pci->cx - HBARSHIFT -1;
a38401 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.bottom = iy+pWD->iRowHeight-(VBARSHIFT+2) -1;
cc2da6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   oldbrush = SelectObject (hdc, pWD->barbgbrush);
7e62b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   oldpen = SelectObject (hdc, pWD->buttonpen);
5ddf1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   Rectangle (hdc, rc.left - 1, rc.top - 1,·
ba6d4c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right + 2, rc.bottom + 2);
caaf5a
c7e1a0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->shadowpen);
654217 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, rc.left, rc.bottom, NULL);
c3309d ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left, rc.top);
aece2e ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.top);
25af5a
a2813b ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->hilightpen);
--5228 000fab105ce40110303 Page 8 of TLPaint.c
b8f61b ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.bottom);
717525 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left, rc.bottom);
29e624 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
8d8921 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pci->lMaxValue != 0) {
4112bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pli->lDataValue > pci->lMaxValue) {
e5f316 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   barbrush = pWD->spcbarbrush;
240ba4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = rc.left + cx;
246560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
cae5ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   else {
195686 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   barbrush = pWD->stdbarbrush;
4bd981 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   f = (float)pli->lDataValue /·
ced8d4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (float)pci->lMaxValue;
ed8b7a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   f += 1.0;
b645ce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   f = log (f) / log (2.0);
e97ba9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = rc.left + (int)(f * (float)cx);
926560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
cb5268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
e728e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else·
2c8943 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.right = rc.left;
57af5a
07faff ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.top++;
e75070 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left++;
18af5a
e2d0b5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (rc.right > rc.left) {
5d47f6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetBkColor (hdc, pWD->barcolor);
944bd1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FillRect (hdc, &rc, barbrush);·
88af5a
875b52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.top--;
65c37f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.left--;
36af5a
9d5964 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // hilight pen already selected·
184ce8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, rc.right, rc.top, NULL);
f2307f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left, rc.top);
cb7e37 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.left,rc.bottom);
7aaf5a
0ddcce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->shadowpen);
497be7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.bottom);
ea0a32 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, rc.right, rc.top);
e65268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
95af5a
a72bd2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, oldbrush);
987fae ¤   ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, oldpen);
b38c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
c1af5a
af4c47 ¤   ¤   ¤   ¤   ¤   ¤   case TLCFMT_IMAGE :
b5a56e ¤   ¤   ¤   ¤   ¤   ¤   ¤   // use text if available
f0c5a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pli->pszText) {
e89337 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TruncateText (hdc, pli->pszText,·
ccca04 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pci->cx, sz256);
47290e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetBkColor (hdc, pWD->textbgcolor);
9004d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTextAlign (hdc, TA_CENTER);
bcdbb2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   TextOut (hdc, ix + (pci->cx>>1), iy,·
4a9e1d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz256, lstrlen(sz256));
355268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
cbace3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   // otherwise paint image
e0a41c ¤   ¤   ¤   ¤   ¤   ¤   ¤   else {
1a9c85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pci->cx >= (BITMAPWIDTH)) {
18fdef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   int i = 0;
eff9d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (pli->state & TLIS_CLICKED) i = 1;
1bea1b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ImageList_Draw (pWD->hImageList,·
02e06e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (pli->lDataValue + i), hdc,·
fe3890 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ix + pci->cxImageOffset,·
80f866 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->hiliteRect.top+iBMPos,
c1757e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILD_TRANSPARENT);
d56560 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
a45268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
e48c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
fcaf5a
85796b ¤   ¤   ¤   ¤   ¤   ¤   default :
da7379 ¤   ¤   ¤   ¤   ¤   ¤   ¤   wsprintf (sz256, "%i", pli->lDataValue);
4b1460 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetBkColor (hdc, pWD->textbgcolor);
fad57e ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetTextAlign (hdc, TA_LEFT);
--ec66 000ce6ec70740110303 Page 9 of TLPaint.c
359707 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TextOut (hdc, ix+6, iy, sz256, lstrlen(sz256));
d48c94 ¤   ¤   ¤   ¤   ¤   ¤   ¤   break;
02db3c ¤   ¤   ¤   ¤   ¤   ¤   }
e17c91 ¤   ¤   ¤   ¤   ¤   ¤   break;·
401c89 ¤   ¤   ¤   ¤   ¤   }
6b2613 ¤   ¤   ¤   ¤   }
9bf4c4 ¤   ¤   ¤   ¤   ix += pci->cx;
bbaf5a
79ce08 ¤   ¤   ¤   ¤   pci = pci->nextItem;
ab97ba ¤   ¤   ¤   ¤   pli = pli->nextItem;
56a3a6 ¤   ¤   ¤   }
8eaf5a
08cfb5 ¤   ¤   ¤   // ·increment y coordinate to next row¤
3a8c61 ¤   ¤   ¤   *y += pWD->iRowHeight;
6267c5 ¤
b05d96 ¤   ¤   ¤   // ·if there is space, paint button and lines
17c6bc ¤   ¤   ¤   if (pWD->iFirstColumnWidth >= p->buttonRect.right) {
2073fc ¤   ¤   ¤   ¤   if (p->cChildren) {
4def8b ¤   ¤   ¤   ¤   ¤   oldpen = SelectObject (hdc, pWD->buttonpen);
035f2b ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, p->buttonRect.left+HBCENT-BBOX,·
095f2a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent-BBOX, NULL);
d7cfc9 ¤   ¤   ¤   ¤   ¤   LineTo (hdc, p->buttonRect.left+HBCENT+BBOX,·
a73664 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent-BBOX);
aecfc9 ¤   ¤   ¤   ¤   ¤   LineTo (hdc, p->buttonRect.left+HBCENT+BBOX,·
0d2bd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent+BBOX);
e2d278 ¤   ¤   ¤   ¤   ¤   LineTo (hdc, p->buttonRect.left+HBCENT-BBOX,·
9e2bd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent+BBOX);
28d278 ¤   ¤   ¤   ¤   ¤   LineTo (hdc, p->buttonRect.left+HBCENT-BBOX,·
c83664 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent-BBOX);
3cbc43 ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, oldpen);
c30565 ¤   ¤   ¤   ¤   ¤   if (p->state & TLIS_EXPANDED) {
74b48f ¤   ¤   ¤   ¤   ¤   ¤   oldpen = SelectObject (hdc, pWD->unseltextpen);
b0ac4a ¤   ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, p->buttonRect.left+HBCENT-BBAR,·
1bbe08 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent, NULL);
bb99e7 ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, p->buttonRect.left+HBCENT+BBAR+1,·
a6ebfd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent);
8d2a02 ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, oldpen);
2afc93 ¤   ¤   ¤   ¤   ¤   ¤   // paint children
633c07 ¤   ¤   ¤   ¤   ¤   ¤   PaintItems (hdc, pWD, item, y,·
275924 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   indent+INCREMENTINDENT, p->childItem);
e61c89 ¤   ¤   ¤   ¤   ¤   }
de3c4b ¤   ¤   ¤   ¤   ¤   else {
18b48f ¤   ¤   ¤   ¤   ¤   ¤   oldpen = SelectObject (hdc, pWD->unseltextpen);
b3ac4a ¤   ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, p->buttonRect.left+HBCENT-BBAR,·
00be08 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent, NULL);
0099e7 ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, p->buttonRect.left+HBCENT+BBAR+1,·
84ebfd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent);
8c727b ¤   ¤   ¤   ¤   ¤   ¤   MoveToEx (hdc, p->buttonRect.left+HBCENT,·
763126 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent-BBAR, NULL);
1557b6 ¤   ¤   ¤   ¤   ¤   ¤   LineTo (hdc, p->buttonRect.left+HBCENT,·
50df77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   p->buttonRect.top+iBCent+BBAR+1);
742a02 ¤   ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, oldpen);
c41c89 ¤   ¤   ¤   ¤   ¤   }
ddd6d4 ¤   ¤   ¤   ¤   ¤   if ((pWD->style & TLS_HASLINES) && (p->parentItem ||
68fcc3 ¤   ¤   ¤   ¤   ¤   ¤   (!p->parentItem && (pWD->style & TLS_LINESATROOT)))) {
add2a2 ¤   ¤   ¤   ¤   ¤   ¤   DottedStruct.dwDottedColor = pWD->linecolor;
46a672 ¤   ¤   ¤   ¤   ¤   ¤   if (p->prevItem || p->parentItem) {
875a47 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (p->prevItem)·
7b2172 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineDDA (xoffset+HBCENT,·
9c53c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·p->prevItem->selectRect.bottom,
011599 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·xoffset+HBCENT,·
27c497 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·p->buttonRect.top+iBCent-BBOX,
faa493 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc,·
d1b771 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&DottedStruct);
e728e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   else·
80fecc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineDDA (xoffset+HBCENT, p->buttonRect.top,
311599 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·xoffset+HBCENT,·
47c497 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·p->buttonRect.top+iBCent-BBOX,
c6a493 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc,·
deb771 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&DottedStruct);
82db3c ¤   ¤   ¤   ¤   ¤   ¤   }
ce9123 ¤   ¤   ¤   ¤   ¤   ¤   if (p->nextItem) {
--ebcb 0000cf98da940110303 Page 10 of TLPaint.c
fd2205 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineDDA (xoffset+HBCENT,·
e0d22d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·p->buttonRect.top+iBCent+BBOX,
2f6d60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·xoffset+HBCENT, *y +1,
dfb71f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc,·
386d58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&DottedStruct);
35db3c ¤   ¤   ¤   ¤   ¤   ¤   }
c9aa8b ¤   ¤   ¤   ¤   ¤   ¤   LineDDA (xoffset+HBCENT+BBOX,·
d7d538 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·p->buttonRect.top+iBCent,
8fc1c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·xoffset+BUTTONWIDTH,·
d2d538 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·p->buttonRect.top+iBCent,
903ae3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc,·
8e4bed ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&DottedStruct);
301c89 ¤   ¤   ¤   ¤   ¤   }
bc2613 ¤   ¤   ¤   ¤   }
0667c5 ¤
bc2827 ¤   ¤   ¤   ¤   // ·if item has no children, only paint lines
dedeaa ¤   ¤   ¤   ¤   else {
18d6d4 ¤   ¤   ¤   ¤   ¤   if ((pWD->style & TLS_HASLINES) && (p->parentItem ||
de3d45 ¤   ¤   ¤   ¤   ¤   ····(!p->parentItem && (pWD->style & TLS_LINESATROOT)))) {
29d2a2 ¤   ¤   ¤   ¤   ¤   ¤   DottedStruct.dwDottedColor = pWD->linecolor;
24e443 ¤   ¤   ¤   ¤   ¤   ¤   if (p->prevItem) {
bb3bba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ix = xoffset+HBCENT;
e4d28b ¤   ¤   ¤   ¤   ¤   ¤   ¤   iy = p->prevItem->selectRect.bottom;
54db3c ¤   ¤   ¤   ¤   ¤   ¤   }
8e2863 ¤   ¤   ¤   ¤   ¤   ¤   else {
873bba ¤   ¤   ¤   ¤   ¤   ¤   ¤   ix = xoffset+HBCENT;
49ada1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   iy = p->buttonRect.top;
a5db3c ¤   ¤   ¤   ¤   ¤   ¤   }
339123 ¤   ¤   ¤   ¤   ¤   ¤   if (p->nextItem) {
ee73c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LineDDA (ix, iy, xoffset+HBCENT, *y +1,·
d5b71f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc,·
226d58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&DottedStruct);
f2db3c ¤   ¤   ¤   ¤   ¤   ¤   }
448289 ¤   ¤   ¤   ¤   ¤   ¤   else LineDDA (ix, iy, xoffset+HBCENT,·
397eb8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··p->buttonRect.top+iBCent,
7431fc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··(LINEDDAPROC)DottedLineProc,·
96e2c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··(LPARAM)&DottedStruct);
b1f218 ¤   ¤   ¤   ¤   ¤   ¤   LineDDA (xoffset+HBCENT, p->buttonRect.top+iBCent,
3cc1c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·xoffset+BUTTONWIDTH,·
ded538 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·p->buttonRect.top+iBCent,
d83ae3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LINEDDAPROC)DottedLineProc,·
694bed ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·(LPARAM)&DottedStruct);
0b1c89 ¤   ¤   ¤   ¤   ¤   }
b72613 ¤   ¤   ¤   ¤   }
45a3a6 ¤   ¤   ¤   }
b5af5a
7f84df ¤   ¤   ¤   // ·if no space, we still need to paint children
c2e543 ¤   ¤   ¤   else {
2073fc ¤   ¤   ¤   ¤   if (p->cChildren) {
c80565 ¤   ¤   ¤   ¤   ¤   if (p->state & TLIS_EXPANDED) {
7b3c07 ¤   ¤   ¤   ¤   ¤   ¤   PaintItems (hdc, pWD, item, y,·
269a03 ¤   ¤   ¤   ¤   ¤   ¤   ¤   indent+INCREMENTINDENT, p->childItem);
2e1c89 ¤   ¤   ¤   ¤   ¤   }
1c2613 ¤   ¤   ¤   ¤   }
03a3a6 ¤   ¤   ¤   }
88af5a
eb0fe4 ¤   ¤   }
36765f ¤   ¤   else {¤ ¤   // ((*item) <= pWD->iFirstRow) {
7a66f0 ¤   ¤   ¤   p->selectRect.left = 0;
3873e6 ¤   ¤   ¤   p->selectRect.right = 0;
4c0456 ¤   ¤   ¤   p->selectRect.top = 0;
533b45 ¤   ¤   ¤   p->selectRect.bottom = 0;
f1af5a
c04f86 ¤   ¤   ¤   p->buttonRect.left = 0;
63657e ¤   ¤   ¤   p->buttonRect.right = 0;
4b30fe ¤   ¤   ¤   p->buttonRect.top = 0;
c72392 ¤   ¤   ¤   p->buttonRect.bottom = 0;
54af5a
f0f800 ¤   ¤   ¤   if (p->cChildren) {
839324 ¤   ¤   ¤   ¤   if (p->state & TLIS_EXPANDED) {
3469ab ¤   ¤   ¤   ¤   ¤   PaintItems (hdc, pWD, item, y,·
0c17ff ¤   ¤   ¤   ¤   ¤   ¤   indent+INCREMENTINDENT, p->childItem);
--874a 0007a1cad4340110303 Page 11 of TLPaint.c
862613 ¤   ¤   ¤   ¤   }
2ba3a6 ¤   ¤   ¤   }
590fe4 ¤   ¤   }
317030 ¤   ¤   // ·step to next tree item
e526cb ¤   ¤   p = p->nextItem;
c89371 ¤   }
abaf5a
4ed43e ¤   //¤ set next item to unusual value to flag end of list
26f191 ¤   if (p) {
beed0c ¤   ¤   p->selectRect.left = 0;
94564c ¤   ¤   p->selectRect.right = -1;
f68829 ¤   ¤   p->selectRect.top = 0;
186f15 ¤   ¤   p->selectRect.bottom = -1;
f0af5a
f3c47a ¤   ¤   p->buttonRect.left = 0;
934e9b ¤   ¤   p->buttonRect.right = -1;
dbbc81 ¤   ¤   p->buttonRect.top = 0;
1ecd3f ¤   ¤   p->buttonRect.bottom = -1;
7e9371 ¤   }
39efe6 }
2aaf5a
26af5a
3fbf56 //----------------------------------------------------|
1079c1 // ·Paint one level of list (selected items only)
74af5a
5a1856 void PaintItemsDragBitmap (
37d29a ¤   ¤   HDC hdc, TLWndData* pWD, ULONG ulFlags, int *item, int* y,·
692163 ¤   ¤   int iLevel, TLTreeItem* p, BOOL* pbStarted)·
f6bb36 {
49ac6f ¤   SIZE¤   ¤   ¤   s;
f6aed8 ¤   INT¤¤   ¤   ¤   iy;
634240 ¤   CHAR¤   ¤   ¤   sz256[256];
f9b929 ¤   RECT¤   ¤   ¤   rcBound;
cfaf5a
7496cb ¤   SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
95124a ¤   SetBkColor (hdc, GetSysColor (COLOR_WINDOW));
2baf5a
6ad3a5 ¤   while (p) {
94af5a
8bf5fb ¤   ¤   // ·increment item count
1db217 ¤   ¤   (*item)++;
7b700d ¤   ¤   // ·check if items are visible in window
fd7f5c ¤   ¤   if ((*item) > (pWD->iFirstRow + pWD->iMaxRows + 2)) break;
e74342 ¤   ¤   if ((*item) > pWD->iFirstRow) {
49af5a
1a6ab9 ¤   ¤   ¤   // ·first paint the tree items ·...
8a5451 ¤   ¤   ¤   // ·select colors based on state of tree item
f12789 ¤   ¤   ¤   if (pWD->bTreeFocused &&·
f05572 ¤   ¤   ¤   ¤   (p->state & TLIS_SELECTED) &&
357c8e ¤   ¤   ¤   ¤   ((iLevel == 0) || !(ulFlags & TLRB_TOPLEVELONLY)))·
def776 ¤   ¤   ¤   {
ab8cbc ¤   ¤   ¤   ¤   *pbStarted = TRUE;
8eaf5a
bf785b ¤   ¤   ¤   ¤   // ·bounding rectangle for this item
9cc8b2 ¤   ¤   ¤   ¤   rcBound.left = iLevel * INCREMENTINDENT;
39d0b1 ¤   ¤   ¤   ¤   rcBound.top = *y+1;
0d7aa4 ¤   ¤   ¤   ¤   rcBound.bottom = p->selectRect.top + pWD->iRowHeight;
c89594 ¤   ¤   ¤   ¤   if (p->state & TLIS_BOLD) SelectObject (hdc, pWD->hFontBold);
7f7efb ¤   ¤   ¤   ¤   else if (p->state & TLIS_ITALICS)·
99af13 ¤   ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->hFontItalic);
d59cec ¤   ¤   ¤   ¤   else SelectObject (hdc, pWD->hFont);
f75f94 ¤   ¤   ¤   ¤   TruncateText (hdc, p->pszText,·
b4088f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pWD->iFirstColumnWidth-
435434 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (BUTTONWIDTH+BITMAPWIDTH+HTEXTSHIFT),·
247909 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz256);
6fbf8c ¤   ¤   ¤   ¤   GetTextExtentPoint32 (hdc, sz256, lstrlen (sz256), &s);
5924a3 ¤   ¤   ¤   ¤   rcBound.right = rcBound.left + s.cx + HTEXTSHIFT;
21af5a
74699b ¤   ¤   ¤   ¤   // ·draw tree item text·
5e1898 ¤   ¤   ¤   ¤   iy = rcBound.top + TEXTVERTOFF;
61bbcb ¤   ¤   ¤   ¤   SetTextAlign (hdc, TA_LEFT);
7ad853 ¤   ¤   ¤   ¤   TextOut (hdc, rcBound.left+HTEXTSHIFT+BUTTONWIDTH, iy,·
--d6a7 00043ca028a40110303 Page 12 of TLPaint.c
c2e8ea ¤   ¤   ¤   ¤   ¤   ¤   ¤   sz256, lstrlen(sz256));
f0af5a
86fc01 ¤   ¤   ¤   ¤   // ·draw tree item bitmap, if there is space
5db140 ¤   ¤   ¤   ¤   if (pWD->iFirstColumnWidth >= (BUTTONWIDTH+BITMAPWIDTH)) {
c6edd5 ¤   ¤   ¤   ¤   ¤   ImageList_Draw (pWD->hImageList, p->iImage, hdc,
959011 ¤   ¤   ¤   ¤   ¤   ¤   ¤   rcBound.left, rcBound.top+pWD->iBMPos,
979736 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ILD_TRANSPARENT);
d12613 ¤   ¤   ¤   ¤   }
9eaf5a
13a455 ¤   ¤   ¤   ¤   // ·paint list items based on their data type
8f4432 ¤   ¤   ¤   ¤   SelectObject (hdc, pWD->hFont);
05af5a
0ba3a6 ¤   ¤   ¤   }
06af5a
a8cfb5 ¤   ¤   ¤   // ·increment y coordinate to next row¤
58522d ¤   ¤   ¤   if (*pbStarted)·
cecd92 ¤   ¤   ¤   ¤   *y += pWD->iRowHeight;
50af5a
96f7e1 ¤   ¤   ¤   // if there are expanded children, we need to add rows
64f800 ¤   ¤   ¤   if (p->cChildren) {
0d9324 ¤   ¤   ¤   ¤   if (p->state & TLIS_EXPANDED) {
05e37d ¤   ¤   ¤   ¤   ¤   PaintItemsDragBitmap (hdc, pWD, ulFlags, item, y,·
9cadeb ¤   ¤   ¤   ¤   ¤   ¤   iLevel+1, p->childItem, pbStarted);
312613 ¤   ¤   ¤   ¤   }
0fa3a6 ¤   ¤   ¤   }
cf0fe4 ¤   ¤   }
84765f ¤   ¤   else {¤ ¤   // ((*item) <= pWD->iFirstRow) {
1bf800 ¤   ¤   ¤   if (p->cChildren) {
959324 ¤   ¤   ¤   ¤   if (p->state & TLIS_EXPANDED) {
20e37d ¤   ¤   ¤   ¤   ¤   PaintItemsDragBitmap (hdc, pWD, ulFlags, item, y,·
3cadeb ¤   ¤   ¤   ¤   ¤   ¤   iLevel+1, p->childItem, pbStarted);
1c2613 ¤   ¤   ¤   ¤   }
dba3a6 ¤   ¤   ¤   }
1c0fe4 ¤   ¤   }
0a7030 ¤   ¤   // ·step to next tree item
ab26cb ¤   ¤   p = p->nextItem;
e29371 ¤   }
19efe6 }
85af5a
90af5a
cebf56 //----------------------------------------------------|
5c79c1 // ·Paint one level of list (selected items only)
b5af5a
aa26ef void CalcItemsDragBitmap (
f9d442 ¤   ¤   TLWndData* pWD, ULONG ulFlags, int *item, int* y,·
831bb3 ¤   ¤   int iLevel, TLTreeItem* p, BOOL* pbStarted, RECT* prc)·
84bb36 {
16d3a5 ¤   while (p) {
03af5a
b5f5fb ¤   ¤   // ·increment item count
1cb217 ¤   ¤   (*item)++;
b3700d ¤   ¤   // ·check if items are visible in window
407f5c ¤   ¤   if ((*item) > (pWD->iFirstRow + pWD->iMaxRows + 2)) break;
4f4342 ¤   ¤   if ((*item) > pWD->iFirstRow) {
37af5a
286ab9 ¤   ¤   ¤   // ·first paint the tree items ·...
df5451 ¤   ¤   ¤   // ·select colors based on state of tree item
f62789 ¤   ¤   ¤   if (pWD->bTreeFocused &&·
ad5572 ¤   ¤   ¤   ¤   (p->state & TLIS_SELECTED) &&
c67c8e ¤   ¤   ¤   ¤   ((iLevel == 0) || !(ulFlags & TLRB_TOPLEVELONLY)))·
67f776 ¤   ¤   ¤   {
e38e87 ¤   ¤   ¤   ¤   if (*pbStarted) {
db9f6f ¤   ¤   ¤   ¤   ¤   prc->bottom = *y + pWD->iRowHeight;
2c2613 ¤   ¤   ¤   ¤   }
40deaa ¤   ¤   ¤   ¤   else {
246ab6 ¤   ¤   ¤   ¤   ¤   prc->top = *y;
359f6f ¤   ¤   ¤   ¤   ¤   prc->bottom = *y + pWD->iRowHeight;
80cd4f ¤   ¤   ¤   ¤   ¤   *pbStarted = TRUE;
082613 ¤   ¤   ¤   ¤   }
fba3a6 ¤   ¤   ¤   }
36af5a
43cfb5 ¤   ¤   ¤   // ·increment y coordinate to next row¤
--742a 000e45814d340110303 Page 13 of TLPaint.c
168c61 ¤   ¤   ¤   *y += pWD->iRowHeight;
0baf5a
c8b84c ¤   ¤   ¤   // if there are expanded children, we need to add empty rows
eff800 ¤   ¤   ¤   if (p->cChildren) {
c89324 ¤   ¤   ¤   ¤   if (p->state & TLIS_EXPANDED) {
436610 ¤   ¤   ¤   ¤   ¤   CalcItemsDragBitmap (pWD, ulFlags, item, y,·
8a20ba ¤   ¤   ¤   ¤   ¤   ¤   iLevel+1, p->childItem, pbStarted, prc);
592613 ¤   ¤   ¤   ¤   }
84a3a6 ¤   ¤   ¤   }
f10fe4 ¤   ¤   }
da765f ¤   ¤   else {¤ ¤   // ((*item) <= pWD->iFirstRow) {
b6f800 ¤   ¤   ¤   if (p->cChildren) {
bd9324 ¤   ¤   ¤   ¤   if (p->state & TLIS_EXPANDED) {
9d6610 ¤   ¤   ¤   ¤   ¤   CalcItemsDragBitmap (pWD, ulFlags, item, y,·
8020ba ¤   ¤   ¤   ¤   ¤   ¤   iLevel+1, p->childItem, pbStarted, prc);
992613 ¤   ¤   ¤   ¤   }
5ba3a6 ¤   ¤   ¤   }
bb0fe4 ¤   ¤   }
937030 ¤   ¤   // ·step to next tree item
1226cb ¤   ¤   p = p->nextItem;
199371 ¤   }
f3efe6 }
f9af5a
e7af5a
44bf56 //----------------------------------------------------|
2820e7 // ·Calculations before painting -- called in response to WM_PAINT
42af5a
92d536 void TLPrePaint (TLWndData* pWD) {
95af5a
03d300 ¤   SCROLLINFO si;
f403a3 ¤   INT iY;
18af5a
f1a566 ¤   pWD->iBCent = (pWD->iRowHeight / 2) +2;
6309ce ¤   pWD->iBMPos = pWD->iBCent - (BITMAPHEIGHT/2) -1;·
2baf5a
c4ed64 ¤   pWD->tlInval = pWD->tlRect;
e8cd9a ¤   pWD->tlInval.top += pWD->iRowHeight+1;
34af5a
1bd5cc ¤   pWD->iExpandedRows = CountRows (pWD->rootItem);
c36415 ¤   pWD->iMaxRows = (pWD->tlInval.bottom-pWD->tlInval.top-
d7b4ee ¤   ¤   ¤   ¤   ¤   (pWD->iRowHeight/2)) / pWD->iRowHeight;
03c033 ¤   if (pWD->iMaxRows <= pWD->iExpandedRows) pWD->tlInval.right =·
297a92 ¤   ¤   pWD->tlRect.right - GetSystemMetrics (SM_CXVSCROLL);
0d665a ¤   else {
43991b ¤   ¤   pWD->iFirstRow = 0;
ac4b29 ¤   ¤   pWD->tlInval.right = pWD->tlRect.right;
549371 ¤   }
3eaf5a
e9c4a1 ¤   iY = pWD->tlInval.right - pWD->tlInval.left;
25e1ea ¤   if (pWD->iTotalWidth > iY) pWD->tlInval.bottom =·
7e154b ¤   ¤   pWD->tlRect.bottom - GetSystemMetrics (SM_CYHSCROLL);
dd0610 ¤   else pWD->tlInval.bottom = pWD->tlRect.bottom;
88af5a
956415 ¤   pWD->iMaxRows = (pWD->tlInval.bottom-pWD->tlInval.top-
ecb4ee ¤   ¤   ¤   ¤   ¤   (pWD->iRowHeight/2)) / pWD->iRowHeight;
cbdcb7 ¤   si.cbSize = sizeof (SCROLLINFO);
0a95ee ¤   si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
837c33 ¤   si.nMin = 0;
2dcabe ¤   si.nMax = pWD->iExpandedRows;
8be6d9 ¤   si.nPage = pWD->iMaxRows;
764b2f ¤   si.nPos = pWD->iFirstRow;
02fd4c ¤   SetScrollInfo (pWD->hWnd, SB_VERT, &si, TRUE);
57af5a
2b57ee ¤   si.nMax = pWD->iTotalWidth;
609e16 ¤   si.nPage = pWD->tlInval.right - pWD->tlInval.left;
12eb77 ¤   si.nPos = pWD->iHorizontalPos;
49bf05 ¤   SetScrollInfo (pWD->hWnd, SB_HORZ, &si, TRUE);
61efe6 }
82af5a
b7af5a
71bf56 //----------------------------------------------------|
e4880f // ·Paint a tree list -- called in response to WM_PAINT
--069c 0000e27474940110303 Page 14 of TLPaint.c
e0af5a
747bf7 void TLPaint (TLWndData* pWD, HDC hdc) {
63af5a
21809a ¤   TLTreeItem*¤p;
7e750e ¤   HFONT¤  ¤   hOldFont;
43cda7 ¤   HBRUSH¤ ¤   hOldBrush;
c2497d ¤   int¤¤   ¤   y, item;
0faf5a
b4dbea ¤   hOldFont = SelectObject (hdc, pWD->hFont);
00af5a
1ead60 ¤   UnrealizeObject (pWD->spcbarbrush);
0ded55 ¤   SetBrushOrgEx (hdc, -1 * pWD->iHorizontalPos, 0, NULL);
a603c1 ¤   hOldBrush = SelectObject (hdc, pWD->spcbarbrush);
97af5a
31bc20 ¤   p = pWD->rootItem;
650931 ¤   y = pWD->tlInval.top;
09d26b ¤   item = 0;
42af5a
717bb0 ¤   PaintItems (hdc, pWD, &item, &y, 0, p);
1aaf5a
f04d6d ¤   SelectObject (hdc, hOldBrush);
7877a0 ¤   SelectObject (hdc, hOldFont);
eeefe6 }
8caf5a
b1af5a
acbf56 //----------------------------------------------------|
5583e5 // ·delete the memory DC
fdaf5a
2fecf6 void TLDeleteMemDC (TLWndData* pWD) {
8228c8 ¤   if (pWD->hdcMem) {
8fab42 ¤   ¤   SelectObject (pWD->hdcMem, pWD->hbmOld);
d26b4a ¤   ¤   DeleteObject (pWD->hbmMem);
fa7427 ¤   ¤   DeleteDC (pWD->hdcMem);
7f9134 ¤   ¤   pWD->hdcMem = NULL;
629371 ¤   }
9cefe6 }
51af5a
94af5a
bcbf56 //----------------------------------------------------|
2c2f39 // ·create mem dc and pass it to routine to render treelist
95af5a
7a9d54 void TLMemPaint (TLWndData* pWD, HDC hdc) {
d05bda ¤   RECT rc;
f6af5a
b7f0a5 ¤   GetClientRect (pWD->hWnd, &rc);
91af5a
c6edfb ¤   if (!pWD->hdcMem) {
442df3 ¤   ¤   pWD->hdcMem = CreateCompatibleDC (hdc);
b2f33a ¤   ¤   pWD->hbmMem = CreateCompatibleBitmap (hdc, rc.right-rc.left,·
3064f5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rc.bottom-rc.top);
2a80bd ¤   ¤   pWD->hbmOld = SelectObject (pWD->hdcMem, pWD->hbmMem);
e5804c ¤   ¤   SetBkMode (pWD->hdcMem, TRANSPARENT);
e59371 ¤   }
77af5a
ea631d ¤   FillRect (pWD->hdcMem, &rc, pWD->unselbgbrush);
24af5a
4ca686 ¤   TLPaint (pWD, pWD->hdcMem);
59869e ····
9f4d48 ¤   BitBlt (hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
1c9d01 ¤   ¤   ¤   pWD->hdcMem, 0, 0, SRCCOPY);
89efe6 }
9dde7b ··
e9af5a
adbf56 //----------------------------------------------------|
0d880f // ·Paint a tree list -- called in response to WM_PAINT
edaf5a
ef0914 void TLPaintDragBitmap (TLWndData* pWD, ULONG ulFlags, HDC hdc) {
feaf5a
6cdf18 ¤   TLTreeItem* p;
a867e5 ¤   HFONT hOldFont;
e8ce66 ¤   int y, item;
0e8f38 ¤   BOOL bStarted;
--3870 000dfd8c18440110303 Page 15 of TLPaint.c
e0af5a
efdbea ¤   hOldFont = SelectObject (hdc, pWD->hFont);
adaf5a
27bc20 ¤   p = pWD->rootItem;
3f4aa5 ¤   y = 0;
9cd26b ¤   item = 0;
48edaf ¤   bStarted = FALSE;
d0a676 ¤   PaintItemsDragBitmap (hdc, pWD, ulFlags, &item, &y, 0, p, &bStarted);
fdaf5a
6f77a0 ¤   SelectObject (hdc, hOldFont);
c8efe6 }
6aaf5a
41af5a
33bf56 //----------------------------------------------------|
f3880f // ·Paint a tree list -- called in response to WM_PAINT
e2af5a
88e9ff void TLCalcDragBitmap (TLWndData* pWD, ULONG ulFlags, RECT* prc) {
2baf5a
c1df18 ¤   TLTreeItem* p;
75ce66 ¤   int y, item;
778f38 ¤   BOOL bStarted;
b2af5a
7f74d4 ¤   prc->left = BUTTONWIDTH;
c23b1c ¤   prc->right = prc->left + pWD->iFirstColumnWidth;
79af5a
4118b3 ¤   prc->top = 0;
0c3768 ¤   prc->bottom = 0;
26bc20 ¤   p = pWD->rootItem;
974aa5 ¤   y = 0;
cad26b ¤   item = 0;
5dedaf ¤   bStarted = FALSE;
a45371 ¤   CalcItemsDragBitmap (pWD, ulFlags, &item, &y, 0, p, &bStarted, prc);
f7efe6 }
25af5a
f5af5a
07bf56 //----------------------------------------------------|
db0934 // ·create bitmap and paint selected items to it
d2af5a
186246 BOOL TLMemPaintDragBitmap (TLWndData* pWD, LPTL_DRAGBITMAP lpdb) {
ef8c06 ¤   HBITMAP¤hbmOld;
2b8d5c ¤   HDC¤¤   hdcMem;
ad81b4 ¤   HDC¤¤   hdcScreen;
6c0686 ¤   RECT¤   rc;
56af5a
7a0428 ¤   if (!lpdb) return FALSE;
0eaf5a
d5f4a1 ¤   // calculate bitmap size and position
69140f ¤   TLCalcDragBitmap (pWD, lpdb->ulFlags, &rc);
959cb7 ¤   lpdb->sizeDrag.cx = rc.right - rc.left;
9f3bc8 ¤   lpdb->sizeDrag.cy = rc.bottom - rc.top;
b5af5a
1e4f99 ¤   lpdb->ptHotSpot.x = lpdb->ptCursorPos.x - rc.left;
2e3030 ¤   lpdb->ptHotSpot.y = lpdb->ptCursorPos.y - rc.top - pWD->tlInval.top;
c0af5a
44bdf2 ¤   // contstruct bitmap
24b927 ¤   hdcMem = CreateCompatibleDC (NULL);
9c7fe4 ¤   hdcScreen = GetDC (pWD->hWnd);
9027e5 ¤   lpdb->hbmDrag = CreateCompatibleBitmap (hdcScreen, lpdb->sizeDrag.cx,·
d7e83d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lpdb->sizeDrag.cy);
94500e ¤   ReleaseDC (pWD->hWnd, hdcScreen);
ccaf5a
29de01 ¤   hbmOld = SelectObject (hdcMem, lpdb->hbmDrag);
865a73 ¤   SetBkMode (hdcMem, TRANSPARENT);
d54c58 ¤   rc.left = 0;
82f6cd ¤   rc.top = 0;
d8bfae ¤   rc.right = lpdb->sizeDrag.cx;
c1242a ¤   rc.bottom = lpdb->sizeDrag.cy;
5c01c9 ¤   FillRect (hdcMem, &rc, pWD->unselbgbrush);
aaaf5a
fb58c4 ¤   TLPaintDragBitmap (pWD, lpdb->ulFlags, hdcMem);
b2af5a
df817a ¤   SelectObject (hdcMem, hbmOld);
--1a07 001a4d2f8cc40110303 Page 16 of TLPaint.c
e0af5a
a8e17a ¤   DeleteDC (hdcMem);
41af5a
9ac2e7 ¤   return TRUE;
70efe6 }
03de7b ··
a4af5a
--5cf0 00085147f5340110304 Page 1 of TLTree.c
b1bf5d //: TreeList Tree linked list management routines
6e465d //
c44d21 //¤ $Id: TLTree.c,v 1.13 1998/07/10 19:19:42 pbj Exp $
e6465d //
7aaf5a
96fb2c #include "TLintern.h"
5faf5a
c4af5a
1bbf56 //----------------------------------------------------|
07eb74 // ·Insert Tree item into list
e3af5a
b5a794 HTLITEM TLInsertTreeItem (TLWndData* pWD, LPTL_INSERTSTRUCT lpIns) {
b517d3 ¤   TLTreeItem* lpParent;
3b4389 ¤   TLTreeItem* lpPrev;
a1221a ¤   TLTreeItem* lpNew;
237eca ¤   TLListItem* pli;
8e4ba4 ¤   int i;
f1af5a
cd619d ¤   // allocate new linked list structure if needed
73706e ¤   if (!lpIns->item.hItem) {
a152ae ¤   ¤   lpNew = TLAlloc (sizeof (TLTreeItem));
68667b ¤   ¤   if (!lpNew) return NULL;
fa202a ¤   ¤   lpNew->state = 0;
e189ae ¤   ¤   lpNew->childItem = NULL;
97e3c6 ¤   ¤   lpNew->listItem = NULL;
3c47c3 ¤   ¤   lpNew->cChildren = 0;
819371 ¤   }
12bf8f ¤   else lpNew = (TLTreeItem*)(lpIns->item.hItem);
13af5a
0846a1 ¤   // get parent item
cf4f46 ¤   lpParent = (TLTreeItem*)lpIns->hParent;
9d162f ¤   lpNew->parentItem = lpParent;
25af5a
3bc81e ¤   // Insert item into list at appropriate spot
03aaa6 ¤   if (lpParent) {
dfaf5a
856731 ¤   //not a root item
fff814 ¤   ¤   if (lpIns->hInsertAfter == TLI_FIRST) {
0c68a5 ¤   ¤   ¤   lpNew->nextItem = lpParent->childItem;
f2490c ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
f818a8 ¤   ¤   ¤   lpParent->childItem = lpNew;
c92c2f ¤   ¤   ¤   lpNew->prevItem = NULL;
e70fe4 ¤   ¤   }
99324e ¤   ¤   else if (lpIns->hInsertAfter == TLI_LAST) {
a52f1c ¤   ¤   ¤   lpPrev = lpParent->childItem;
1810e7 ¤   ¤   ¤   if (lpPrev) {
8dc776 ¤   ¤   ¤   ¤   while (lpPrev->nextItem) lpPrev = lpPrev->nextItem;
6a2011 ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
6a3c96 ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
837cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
66a3a6 ¤   ¤   ¤   }
c7e543 ¤   ¤   ¤   else {
751e10 ¤   ¤   ¤   ¤   lpParent->childItem = lpNew;
597cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
dbe97a ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
6fa3a6 ¤   ¤   ¤   }
900fe4 ¤   ¤   }
a45a8e ¤   ¤   else if (lpIns->hInsertAfter == TLI_SORT) {
452f1c ¤   ¤   ¤   lpPrev = lpParent->childItem;
719e69 ¤   ¤   ¤   if (!lpPrev) {
b71e10 ¤   ¤   ¤   ¤   lpParent->childItem = lpNew;
077cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
bee97a ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
06a3a6 ¤   ¤   ¤   }
aee543 ¤   ¤   ¤   else {
3980bd ¤   ¤   ¤   ¤   if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) >= 0) {
727eb9 ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = lpParent->childItem;
231c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
1f4c8d ¤   ¤   ¤   ¤   ¤   lpParent->childItem = lpNew;
a8611c ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
4a2613 ¤   ¤   ¤   ¤   }
85deaa ¤   ¤   ¤   ¤   else {
--fa4b 0002e4a3d5640110304 Page 2 of TLTree.c
0052b7 ¤   ¤   ¤   ¤   ¤   while (lpPrev->nextItem &&·
64793e ¤   ¤   ¤   ¤   ¤   ¤   (lstrcmp (lpPrev->nextItem->pszText,·
60e1ce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··lpIns->item.pszText) < 0))·
39156b ¤   ¤   ¤   ¤   ¤   ¤   lpPrev = lpPrev->nextItem;
ce9970 ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = lpPrev->nextItem;
2b1c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
9d19d4 ¤   ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
fe0553 ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
b02613 ¤   ¤   ¤   ¤   }
24a3a6 ¤   ¤   ¤   }
c50fe4 ¤   ¤   }
6c1a7e ¤   ¤   else if (lpIns->hInsertAfter == TLI_SORTREVERSE) {
752f1c ¤   ¤   ¤   lpPrev = lpParent->childItem;
049e69 ¤   ¤   ¤   if (!lpPrev) {
c31e10 ¤   ¤   ¤   ¤   lpParent->childItem = lpNew;
357cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
c9e97a ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
d9a3a6 ¤   ¤   ¤   }
bee543 ¤   ¤   ¤   else {
fb8bd2 ¤   ¤   ¤   ¤   if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) <= 0) {
227eb9 ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = lpParent->childItem;
d21c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
7b4c8d ¤   ¤   ¤   ¤   ¤   lpParent->childItem = lpNew;
a7611c ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
472613 ¤   ¤   ¤   ¤   }
cedeaa ¤   ¤   ¤   ¤   else {
ec52b7 ¤   ¤   ¤   ¤   ¤   while (lpPrev->nextItem &&·
08793e ¤   ¤   ¤   ¤   ¤   ¤   (lstrcmp (lpPrev->nextItem->pszText,·
c4d675 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··lpIns->item.pszText) > 0))·
4e156b ¤   ¤   ¤   ¤   ¤   ¤   lpPrev = lpPrev->nextItem;
ac9970 ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = lpPrev->nextItem;
0f1c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
2619d4 ¤   ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
540553 ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
b02613 ¤   ¤   ¤   ¤   }
f8a3a6 ¤   ¤   ¤   }
dd0fe4 ¤   ¤   }
0207e0 ¤   ¤   else {
3084e2 ¤   ¤   ¤   lpPrev = (TLTreeItem*)lpIns->hInsertAfter;
3b10e7 ¤   ¤   ¤   if (lpPrev) {
3e3c96 ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
9fccdc ¤   ¤   ¤   ¤   lpNew->nextItem = lpPrev->nextItem;
712011 ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
a3077b ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
faa3a6 ¤   ¤   ¤   }
e90fe4 ¤   ¤   }
e2af5a
2f2ef8 ¤   ¤   lpParent->cChildren++;
d39371 ¤   }
7faf5a
1bb1d4 ¤   // this is a root item
18665a ¤   else {
a8f814 ¤   ¤   if (lpIns->hInsertAfter == TLI_FIRST) {
2683ea ¤   ¤   ¤   lpNew->nextItem = pWD->rootItem;
a9490c ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
c72c2f ¤   ¤   ¤   lpNew->prevItem = NULL;
825cb2 ¤   ¤   ¤   pWD->rootItem = lpNew;
830fe4 ¤   ¤   }
33324e ¤   ¤   else if (lpIns->hInsertAfter == TLI_LAST) {
52969e ¤   ¤   ¤   lpPrev = pWD->rootItem;
2e10e7 ¤   ¤   ¤   if (lpPrev) {
84c776 ¤   ¤   ¤   ¤   while (lpPrev->nextItem) lpPrev = lpPrev->nextItem;
8a2011 ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
313c96 ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
607cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
d6a3a6 ¤   ¤   ¤   }
e5e543 ¤   ¤   ¤   else {
f51d41 ¤   ¤   ¤   ¤   pWD->rootItem = lpNew;
507cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
9ae97a ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
2fa3a6 ¤   ¤   ¤   }
2e0fe4 ¤   ¤   }
--12ad 000177029c540110304 Page 3 of TLTree.c
e75a8e ¤   ¤   else if (lpIns->hInsertAfter == TLI_SORT) {
a2969e ¤   ¤   ¤   lpPrev = pWD->rootItem;
789e69 ¤   ¤   ¤   if (!lpPrev) {
7a1d41 ¤   ¤   ¤   ¤   pWD->rootItem = lpNew;
db7cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
b0e97a ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
f4a3a6 ¤   ¤   ¤   }
62e543 ¤   ¤   ¤   else {
5180bd ¤   ¤   ¤   ¤   if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) >= 0) {
b0826c ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = pWD->rootItem;
641c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
f2130d ¤   ¤   ¤   ¤   ¤   pWD->rootItem = lpNew;
80611c ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
e02613 ¤   ¤   ¤   ¤   }
07deaa ¤   ¤   ¤   ¤   else {
ba52b7 ¤   ¤   ¤   ¤   ¤   while (lpPrev->nextItem &&·
ee793e ¤   ¤   ¤   ¤   ¤   ¤   (lstrcmp (lpPrev->nextItem->pszText,·
dfe1ce ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··lpIns->item.pszText) < 0))·
19156b ¤   ¤   ¤   ¤   ¤   ¤   lpPrev = lpPrev->nextItem;
159970 ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = lpPrev->nextItem;
df1c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
3119d4 ¤   ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
600553 ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
8f2613 ¤   ¤   ¤   ¤   }
c969c5 ¤   ¤   ¤   }¤  ¤
6c0fe4 ¤   ¤   }
c11a7e ¤   ¤   else if (lpIns->hInsertAfter == TLI_SORTREVERSE) {
3b969e ¤   ¤   ¤   lpPrev = pWD->rootItem;
e59e69 ¤   ¤   ¤   if (!lpPrev) {
411d41 ¤   ¤   ¤   ¤   pWD->rootItem = lpNew;
8e7cdb ¤   ¤   ¤   ¤   lpNew->nextItem = NULL;
81e97a ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
99a3a6 ¤   ¤   ¤   }
ade543 ¤   ¤   ¤   else {
a68bd2 ¤   ¤   ¤   ¤   if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) <= 0) {
53826c ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = pWD->rootItem;
4c1c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
33130d ¤   ¤   ¤   ¤   ¤   pWD->rootItem = lpNew;
fb611c ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = NULL;
e52613 ¤   ¤   ¤   ¤   }
88deaa ¤   ¤   ¤   ¤   else {
7652b7 ¤   ¤   ¤   ¤   ¤   while (lpPrev->nextItem &&·
08793e ¤   ¤   ¤   ¤   ¤   ¤   (lstrcmp (lpPrev->nextItem->pszText,·
a7d675 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··lpIns->item.pszText) > 0))·
96156b ¤   ¤   ¤   ¤   ¤   ¤   lpPrev = lpPrev->nextItem;
049970 ¤   ¤   ¤   ¤   ¤   lpNew->nextItem = lpPrev->nextItem;
e51c72 ¤   ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
f319d4 ¤   ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
920553 ¤   ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
b52613 ¤   ¤   ¤   ¤   }
d469c5 ¤   ¤   ¤   }¤  ¤
ca0fe4 ¤   ¤   }
8f07e0 ¤   ¤   else {
8b84e2 ¤   ¤   ¤   lpPrev = (TLTreeItem*)lpIns->hInsertAfter;
c410e7 ¤   ¤   ¤   if (lpPrev) {
143c96 ¤   ¤   ¤   ¤   lpNew->prevItem = lpPrev;
d9ccdc ¤   ¤   ¤   ¤   lpNew->nextItem = lpPrev->nextItem;
b62011 ¤   ¤   ¤   ¤   lpPrev->nextItem = lpNew;
df077b ¤   ¤   ¤   ¤   if (lpNew->nextItem) lpNew->nextItem->prevItem = lpNew;
50a3a6 ¤   ¤   ¤   }
600fe4 ¤   ¤   }
5eaf5a
379371 ¤   }
bdaf5a
8ce806 ¤   // only do the following if this is a new item
5ed7af ¤   if (!lpIns->item.hItem) {¤  ¤
cff5fa ¤   ¤   if (lpIns->item.mask & TLIF_TEXT) {
90d14e ¤   ¤   ¤   lpNew->pszText = TLAlloc (lstrlen (lpIns->item.pszText) +1);
40f068 ¤   ¤   ¤   if (lpNew->pszText) lstrcpy (lpNew->pszText, lpIns->item.pszText);
d80fe4 ¤   ¤   }
400e01 ¤   ¤   else lpNew->pszText = NULL;
1767c5 ¤
--572c 000a6d5ad4240110304 Page 4 of TLTree.c
f63258 ¤   ¤   if (lpIns->item.mask & TLIF_IMAGE) lpNew->iImage = lpIns->item.iImage;
4ae9a4 ¤   ¤   else lpNew->iImage = 0;
9467c5 ¤
0fbbf4 ¤   ¤   if (lpIns->item.mask & TLIF_PARAM) lpNew->lParam = lpIns->item.lParam;
49c282 ¤   ¤   else lpNew->lParam = 0;
5a67c5 ¤
295c16 ¤   ¤   if (lpIns->item.mask & TLIF_STATE) {
e21b0c ¤   ¤   ¤   lpNew->state &= ~lpIns->item.stateMask;
b6594e ¤   ¤   ¤   lpNew->state |= (lpIns->item.stateMask & lpIns->item.state);
2a0fe4 ¤   ¤   }
a967c5 ¤
8dd375 ¤   ¤   if (pWD->iNumberColumns > 1) {
786181 ¤   ¤   ¤   lpNew->listItem = TLAlloc (sizeof (TLListItem));
a9062e ¤   ¤   ¤   pli = lpNew->listItem;
e35b0e ¤   ¤   ¤   for (i=2; i<pWD->iNumberColumns; i++) {
5caf5b ¤   ¤   ¤   ¤   pli->nextItem = TLAlloc (sizeof (TLListItem));
6597ba ¤   ¤   ¤   ¤   pli = pli->nextItem;
81a3a6 ¤   ¤   ¤   }
f80fe4 ¤   ¤   }
af9371 ¤   }
3faf5a
10c755 ¤   return (HTLITEM)lpNew;
15af5a
e3efe6 }
e9af5a
89af5a
bdbf56 //----------------------------------------------------|
da97fc // ·Delete Tree item
d9af5a
df4cc5 BOOL TLDeleteTreeItem (TLWndData* pWD, TL_TREEITEM* lpti) {
1ddf18 ¤   TLTreeItem* p;
efc2be ¤   TLTreeItem* op;
827eca ¤   TLListItem* pli;
128d4d ¤   TLListItem* opli;
b8af5a
dc776a ¤   p = (TLTreeItem*) lpti->hItem;
4af78b ¤   if (!p) return FALSE;
54af5a
0547fa ¤   if (p->prevItem) p->prevItem->nextItem = p->nextItem;
9004eb ¤   else if (p->parentItem) p->parentItem->childItem = p->nextItem;
68f565 ¤   else pWD->rootItem = p->nextItem;
5caf5a
eaf7ae ¤   if (p->nextItem) p->nextItem->prevItem = p->prevItem;
83296f ¤   if (p->parentItem) p->parentItem->cChildren--;
15af5a
9ddaa3 ¤   if (p->childItem) TLDeleteTreeList (p->childItem);
82af5a
5b6870 ¤   if (pWD->focusItem == p) pWD->focusItem = NULL;
3d6aa5 ¤   if (pWD->firstSelectItem == p) pWD->firstSelectItem = NULL;
0daf5a
2e952d ¤   pli = p->listItem;
2a9456 ¤   while (pli) {
020838 ¤   ¤   TLFree (pli->pszText);
6a940e ¤   ¤   opli = pli;
391184 ¤   ¤   pli = pli->nextItem;
ab0756 ¤   ¤   TLFree (opli);
429371 ¤   }
12af5a
3400f6 ¤   TLFree (p->pszText);
2e95e1 ¤   op = p;
6e971a ¤   p = p->nextItem;
1e9e18 ¤   TLFree (op);
efefe6 }
b8af5a
99af5a
ecbf56 //----------------------------------------------------|
b280da // ·Get Tree item information
8eaf5a
dc646a BOOL TLGetTreeItem (TLWndData* pWD, TL_TREEITEM* lpti) {
e9df18 ¤   TLTreeItem* p;
e5af5a
a6776a ¤   p = (TLTreeItem*) lpti->hItem;
--614d 0007e98e15440110304 Page 5 of TLTree.c
41f78b ¤   if (!p) return FALSE;
41af5a
6c03cc ¤   if (lpti->mask & TLIF_TEXT) {
7a2439 ¤   ¤   if (lpti->cchTextMax > lstrlen (p->pszText))·
9a01f4 ¤   ¤   ¤   lstrcpy (lpti->pszText, p->pszText);
ec07e0 ¤   ¤   else {
c36d4c ¤   ¤   ¤   lpti->pszText = NULL;
495f1f ¤   ¤   ¤   return FALSE;
e90fe4 ¤   ¤   }
7b9371 ¤   }
ffaf5a
92c292 ¤   if (lpti->mask & TLIF_IMAGE) lpti->iImage = p->iImage;
5baf5a
4f4ee0 ¤   if (lpti->mask & TLIF_PARAM) lpti->lParam = p->lParam;
e4af5a
8f1344 ¤   if (lpti->mask & TLIF_STATE) lpti->state = p->state;
20af5a
a60ab0 ¤   if (lpti->mask & TLIF_NEXTHANDLE) lpti->hItem = (HTLITEM)p->nextItem;
e991d2 ¤   else if (lpti->mask & TLIF_PREVHANDLE) lpti->hItem = (HTLITEM)p->prevItem;
7398cb ¤   else if (lpti->mask & TLIF_PARENTHANDLE) lpti->hItem =·
403671 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (HTLITEM)p->parentItem;
cc54ba ¤   else if (lpti->mask & TLIF_CHILDHANDLE) lpti->hItem =·
91f7e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (HTLITEM)p->childItem;
1aaf5a
f8c2e7 ¤   return TRUE;
d7efe6 }
d9af5a
78af5a
ddbf56 //----------------------------------------------------|
2d1865 // ·Set Tree item information
8eaf5a
e528d5 BOOL TLSetTreeItem (TLWndData* pWD, TL_TREEITEM* lpti) {
5cdf18 ¤   TLTreeItem* p;
f3af5a
e8776a ¤   p = (TLTreeItem*) lpti->hItem;
d3f78b ¤   if (!p) return FALSE;
ffaf5a
e503cc ¤   if (lpti->mask & TLIF_TEXT) {
bdb0de ¤   ¤   p->pszText = TLReAlloc (p->pszText, lstrlen (lpti->pszText) +1);
d7a611 ¤   ¤   lstrcpy (p->pszText, lpti->pszText);
799371 ¤   }
85af5a
27a719 ¤   if (lpti->mask & TLIF_IMAGE) p->iImage = lpti->iImage;
d7af5a
10daaf ¤   if (lpti->mask & TLIF_PARAM) ·p->lParam = lpti->lParam;
f6af5a
1c0855 ¤   if (lpti->mask & TLIF_STATE) {
92b37d ¤   ¤   p->state &= ~(lpti->stateMask);
311e9f ¤   ¤   p->state |= (lpti->state & lpti->stateMask);
cb9371 ¤   }
d5af5a
693275 ¤   TLInvalidateItem (pWD, p);
74c2e7 ¤   return TRUE;
e4efe6 }
5faf5a
a4af5a
35bf56 //----------------------------------------------------|
d083e9 // ·Deselect Tree
63af5a
7d1697 BOOL TLDeselectTree (TLWndData* pWD, TLTreeItem* p, TLTreeItem* pExcept) {
8b7938 ¤   BOOL bDeselected = FALSE;
04af5a
07d3a5 ¤   while (p) {
cd769d ¤   ¤   if (p->childItem)·
65f965 ¤   ¤   ¤   bDeselected = TLDeselectTree (pWD, p->childItem, pExcept);
e5e72b ¤   ¤   if (p != pExcept) {
34645c ¤   ¤   ¤   if (p->state & TLIS_SELECTED) {
c99468 ¤   ¤   ¤   ¤   p->state &= ~TLIS_SELECTED;
4425fb ¤   ¤   ¤   ¤   pWD->iNumberSelected--;
daf1b5 ¤   ¤   ¤   ¤   TLInvalidateItem (pWD, p);
7629df ¤   ¤   ¤   ¤   bDeselected = TRUE;
7ea3a6 ¤   ¤   ¤   }
--dd94 000c0e8dd4f40110304 Page 6 of TLTree.c
d1c799 ¤   ¤   ¤   if (p->state & TLIS_FOCUSED) {
f97301 ¤   ¤   ¤   ¤   p->state &= ~TLIS_FOCUSED;
0e00cd ¤   ¤   ¤   ¤   pWD->nmTreeList.flags = 0;
b8d558 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemOld.hItem = NULL;
e38661 ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.hItem = NULL;
027fca ¤   ¤   ¤   ¤   pWD->nmTreeList.itemNew.state = 0;
17ae81 ¤   ¤   ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
5fb01f ¤   ¤   ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
64cdfa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
31a3a6 ¤   ¤   ¤   }
b60fe4 ¤   ¤   }
6726cb ¤   ¤   p = p->nextItem;
ab9371 ¤   }
228880 ¤   return bDeselected;
c6efe6 }
61af5a
8eaf5a
c9bf56 //----------------------------------------------------|
278945 // ·Expand Tree
dfaf5a
6a2f31 void TLExpandTree (TLTreeItem* p) {
7ed3a5 ¤   while (p) {
8b0c20 ¤   ¤   if (p->childItem) {
e1e773 ¤   ¤   ¤   p->state |= TLIS_EXPANDED;
805be4 ¤   ¤   ¤   TLExpandTree (p->childItem);
8b0fe4 ¤   ¤   }
2a26cb ¤   ¤   p = p->nextItem;
249371 ¤   }
44efe6 }
16af5a
efaf5a
00bf56 //----------------------------------------------------|
b6462c // ·Expand entire Tree
c8af5a
7c2253 void ExpandTree (TLTreeItem* p) {
bad3a5 ¤   while (p) {
f9b64a ¤   ¤   if (p->childItem) ExpandTree (p->childItem);
77a680 ¤   ¤   p->state |= TLIS_EXPANDED;
0026cb ¤   ¤   p = p->nextItem;
549371 ¤   }
24efe6 }
caaf5a
b9af5a
bdbf56 //----------------------------------------------------|
e67559 // ·Expand/Collapse Tree item·
61af5a
6a7aff BOOL TLExpandTreeItem (TLWndData* pWD, TL_TREEITEM* lpti, int flags) {
d1df18 ¤   TLTreeItem* p;
34af5a
e4af5a
283b40 ¤   switch (flags) {
660050 ¤   case TLE_COLLAPSE :
2b3699 ¤   ¤   p = (TLTreeItem*) lpti->hItem;
ae7edf ¤   ¤   if (!p) return FALSE;
b80312 ¤   ¤   if (p->state & TLIS_EXPANDED) {
fb5a3b ¤   ¤   ¤   p->state &= ~TLIS_EXPANDED;
e95e9f ¤   ¤   ¤   TLDeselectTree (pWD, p->childItem, NULL);
f32ff5 ¤   ¤   ¤   TLSelectAutoScroll (pWD, p);
f032bd ¤   ¤   ¤   return TRUE;
1e0fe4 ¤   ¤   }
772f1b ¤   ¤   else return FALSE;
38af5a
f384f4 ¤   case TLE_EXPAND :
e53699 ¤   ¤   p = (TLTreeItem*) lpti->hItem;
097edf ¤   ¤   if (!p) return FALSE;
edb43d ¤   ¤   if (p->state & TLIS_EXPANDED) return FALSE;
7f07e0 ¤   ¤   else {
a9e773 ¤   ¤   ¤   p->state |= TLIS_EXPANDED;
15ccb4 ¤   ¤   ¤   TLExpandAutoScroll (pWD, p);
1832bd ¤   ¤   ¤   return TRUE;
640fe4 ¤   ¤   }
c02f68 ¤   ¤   break;
--2fda 000bb2703fc40110304 Page 7 of TLTree.c
e0af5a
fd91f3 ¤   case TLE_TOGGLE :
123699 ¤   ¤   p = (TLTreeItem*) lpti->hItem;
637edf ¤   ¤   if (!p) return FALSE;
630312 ¤   ¤   if (p->state & TLIS_EXPANDED) {
a75a3b ¤   ¤   ¤   p->state &= ~TLIS_EXPANDED;
b85e9f ¤   ¤   ¤   TLDeselectTree (pWD, p->childItem, NULL);
fd2ff5 ¤   ¤   ¤   TLSelectAutoScroll (pWD, p);
7232bd ¤   ¤   ¤   return TRUE;
940fe4 ¤   ¤   }
7098cf ¤   ¤   else p->state |= TLIS_EXPANDED;
bb836c ¤   ¤   return TRUE;
5faf5a
c9948c ¤   case TLE_COLLAPSEALL :
9372c7 ¤   ¤   p = NULL;
79c3d7 ¤   ¤   if (lpti) p = (TLTreeItem*) lpti->hItem;
324400 ¤   ¤   if (p) {
885a3b ¤   ¤   ¤   p->state &= ~TLIS_EXPANDED;
035e9f ¤   ¤   ¤   TLDeselectTree (pWD, p->childItem, NULL);
642ff5 ¤   ¤   ¤   TLSelectAutoScroll (pWD, p);
f70fe4 ¤   ¤   }
d907e0 ¤   ¤   else {
4a4ae9 ¤   ¤   ¤   p = pWD->rootItem;
573e22 ¤   ¤   ¤   while (p) {
5cd25d ¤   ¤   ¤   ¤   p->state &= ~TLIS_EXPANDED;
7b5de8 ¤   ¤   ¤   ¤   TLDeselectTree (pWD, p->childItem, NULL);
a2a9c0 ¤   ¤   ¤   ¤   p = p->nextItem;
dea3a6 ¤   ¤   ¤   }
0a0d30 ¤   ¤   ¤   TLSelectAutoScroll (pWD, pWD->rootItem);
2c0fe4 ¤   ¤   }
36836c ¤   ¤   return TRUE;
c0af5a
0c1396 ¤   case TLE_EXPANDALL :
d672c7 ¤   ¤   p = NULL;
42c3d7 ¤   ¤   if (lpti) p = (TLTreeItem*) lpti->hItem;
b04400 ¤   ¤   if (p) {
a2e773 ¤   ¤   ¤   p->state |= TLIS_EXPANDED;
315be4 ¤   ¤   ¤   TLExpandTree (p->childItem);
1fccb4 ¤   ¤   ¤   TLExpandAutoScroll (pWD, p);
860fe4 ¤   ¤   }
d907e0 ¤   ¤   else {
b4298f ¤   ¤   ¤   TLExpandTree (pWD->rootItem);
719c22 ¤   ¤   ¤   TLExpandAutoScroll (pWD, pWD->rootItem);
450fe4 ¤   ¤   }
66836c ¤   ¤   return TRUE;
8e9371 ¤   }
22af5a
84a230 ¤   return FALSE;
73efe6 }
5baf5a
3eaf5a
48bf56 //----------------------------------------------------|
3ced0d // ·Select Tree item·
f6af5a
0c2ff3 BOOL TLSelectTreeItem (TLWndData* pWD, TL_TREEITEM* lpti, BOOL bDeselect) {
2adf18 ¤   TLTreeItem* p;
54af5a
bcdddb ¤   if (pWD->focusItem) pWD->focusItem->state &= ~TLIS_FOCUSED;
e657f9 ¤   if (bDeselect) {
35e9d3 ¤   ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
a6b73d ¤   ¤   pWD->iNumberSelected = 0;
d59371 ¤   }
7b050f ¤   if (lpti) {
c13699 ¤   ¤   p = (TLTreeItem*) lpti->hItem;
ee7edf ¤   ¤   if (!p) return FALSE;
9ccab7 ¤   ¤   p->state |= TLIS_SELECTED | TLIS_FOCUSED;
e40c5a ¤   ¤   pWD->focusItem = p;
582254 ¤   ¤   pWD->firstSelectItem = p;
ed9afb ¤   ¤   (pWD->iNumberSelected)++;
1f4e7e ¤   ¤   if (TLSelectAutoScroll (pWD, p))·
4c7805 ¤   ¤   ¤   InvalidateRect (pWD->hWnd, &pWD->tlInval, TRUE);
bb8045 ¤   ¤   else TLInvalidateItem (pWD, p);
--da9e 0004556db1e40110304 Page 8 of TLTree.c
87697f ¤   ¤   if (pWD->iNumberSelected > 1) pWD->nmTreeList.flags = TLC_MULTIPLE;
c1713d ¤   ¤   else pWD->nmTreeList.flags = 0;
b23467 ¤   ¤   pWD->nmTreeList.itemOld.hItem = NULL;
3539a1 ¤   ¤   pWD->nmTreeList.itemNew.hItem = (HTLITEM)p;
192365 ¤   ¤   pWD->nmTreeList.itemNew.state = p->state;
f3b89d ¤   ¤   pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
af3d01 ¤   ¤   SendMessage (pWD->hWndParent, WM_NOTIFY, pWD->id,·
4aeb4f ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&(pWD->nmTreeList));
4d9371 ¤   }
04c2e7 ¤   return TRUE;
a8efe6 }
49af5a
abaf5a
e7bf56 //----------------------------------------------------|
48cb07 // ·Select all the children of a Tree item·
72af5a
58922f BOOL TLSelectChildren (TLWndData* pWD, TL_TREEITEM* lpti) {
92df18 ¤   TLTreeItem* p;
5faf5a
b33161 ¤   TLDeselectTree (pWD, pWD->rootItem, NULL);
048035 ¤   pWD->iNumberSelected = 0;
32af5a
563eb9 ¤   if (lpti == NULL) {
585ec1 ¤   ¤   p = pWD->rootItem;
e20c5a ¤   ¤   pWD->focusItem = p;
309371 ¤   }
cf665a ¤   else {
e63699 ¤   ¤   p = (TLTreeItem*) lpti->hItem;
878f17 ¤   ¤   if (p) p = p->childItem;
e99371 ¤   }
4caf5a
d9f78b ¤   if (!p) return FALSE;
02af5a
03d3a5 ¤   while (p) {
3be0b5 ¤   ¤   p->state |= TLIS_SELECTED;
b7f611 ¤   ¤   pWD->iNumberSelected++;
99be0a ¤   ¤   TLInvalidateItem (pWD, p);
5e26cb ¤   ¤   p = p->nextItem;
4e9371 ¤   }
00c2e7 ¤   return TRUE;
6eefe6 }
ffaf5a
50af5a
a7bf56 //----------------------------------------------------|
e6c909 // ·Delete Tree List linked list
18af5a
6b9247 void TLDeleteTreeList (TLTreeItem* p) {
6bc2be ¤   TLTreeItem* op;
cf7eca ¤   TLListItem* pli;
978d4d ¤   TLListItem* opli;
b5af5a
74d3a5 ¤   while (p) {
17dd98 ¤   ¤   if (p->childItem) TLDeleteTreeList (p->childItem);
b0af5a
2777cc ¤   ¤   pli = p->listItem;
2baecc ¤   ¤   while (pli) {
568447 ¤   ¤   ¤   TLFree (pli->pszText);
4eeefa ¤   ¤   ¤   opli = pli;
26aad2 ¤   ¤   ¤   pli = pli->nextItem;
9de5b7 ¤   ¤   ¤   TLFree (opli);
ef0fe4 ¤   ¤   }
d3af5a
eb34ab ¤   ¤   TLFree (p->pszText);
b88f51 ¤   ¤   op = p;
1926cb ¤   ¤   p = p->nextItem;
45df93 ¤   ¤   TLFree (op);
2f9371 ¤   }
7defe6 }
8daf5a
69af5a
7abf56 //----------------------------------------------------|
45fb6d // ·Delete Column linked list
--0946 00030c1aeec40110304 Page 9 of TLTree.c
e0af5a
33a338 BOOL TLDeleteAllColumns (TLWndData* pWD) {
9b6c05 ¤   TLColumnItem* p;
cf083b ¤   TLColumnItem* opci;
41cdd6 ¤   INT i;
c7af5a
d76cc2 ¤   for (i=pWD->iNumberColumns-1; i>=0; i--)·
2d00e1 ¤   ¤   Header_DeleteItem (pWD->hWndHeader, i);
9baf5a
1a5781 ¤   p = pWD->columnItem;
2ad3a5 ¤   while (p) {
12f458 ¤   ¤   opci = p;
8426cb ¤   ¤   p = p->nextItem;
076daa ¤   ¤   TLFree (opci);
fb9371 ¤   }
f51b52 ¤   ¤
8d8008 ¤   pWD->columnItem = NULL;¤¤
310531 ¤   pWD->iNumberColumns = 0;
dfaf5a
40c2e7 ¤   return TRUE;
bdefe6 }
a5af5a
b5af5a
c8bf56 //----------------------------------------------------|
4e04b9 // ·Insert column into TreeList
e6af5a
f2de7e LONG TLInsertColumn (TLWndData* pWD, LONG index, TL_COLUMN* tlc) {
95af5a
682e17 ¤   HD_ITEM hditem;
5bf065 ¤   TLColumnItem* pci;
8eaf5a
64cfc4 ¤   hditem.mask = 0;
d1af5a
79526f ¤   if (index == 0) {
9300c8 ¤   ¤   if (tlc->mask & TLCF_WIDTH) pWD->iFirstColumnWidth = tlc->cx;
0e7607 ¤   ¤   hditem.mask = HDI_FORMAT | HDI_WIDTH |HDI_TEXT;
734d3f ¤   ¤   hditem.fmt = tlc->fmt;
527108 ¤   ¤   hditem.cxy = tlc->cx;
fc87ee ¤   ¤   hditem.pszText = tlc->pszText;
21fe23 ¤   ¤   pWD->iNumberColumns++;
afd731 ¤   ¤   pWD->iFirstColumnWidth = tlc->cx;
a7dbe5 ¤   ¤   pWD->iTotalWidth = tlc->cx;
afc18d ¤   ¤   return (Header_InsertItem (pWD->hWndHeader, index, &hditem));·
5b9371 ¤   }
27af5a
73b70d ¤   pWD->iTotalWidth += tlc->cx;
62af5a
2a96fd ¤   pci = pWD->columnItem;
3c7a0d ¤   if (pci) {
79e880 ¤   ¤   while (pci->nextItem) pci = pci->nextItem;
b807ac ¤   ¤   pci->nextItem = TLAlloc (sizeof (TLColumnItem));
2f4836 ¤   ¤   pci = pci->nextItem;
2d9371 ¤   }
fd665a ¤   else {
34ef8a ¤   ¤   pWD->columnItem = TLAlloc (sizeof (TLColumnItem));
b882d5 ¤   ¤   pci = pWD->columnItem;
6f9371 ¤   }
7171c3 ¤   pci->iSubItem = index;
77af5a
46bf91 ¤   if (tlc->mask & TLCF_DATATYPE) {
ec08f3 ¤   ¤   pci->iDataType = tlc->iDataType;
8c9371 ¤   }
3c40b7 ¤   if (tlc->mask & TLCF_DATAMAX) {
0c3aae ¤   ¤   pci->lMaxValue = tlc->cchTextMax;
4a9371 ¤   }
080184 ¤   if (tlc->mask & TLCF_FMT) {
27f3c4 ¤   ¤   hditem.mask |= HDI_FORMAT;
574d3f ¤   ¤   hditem.fmt = tlc->fmt;
eceddc ¤   ¤   if ((hditem.fmt == TLCFMT_LOGBAR) ||·
7c9e46 ¤   ¤   ¤   (hditem.fmt == TLCFMT_LINBAR) ||
527d46 ¤   ¤   ¤   (hditem.fmt == TLCFMT_IMAGE))·
30e255 ¤   ¤   ¤   ¤   hditem.fmt = HDF_CENTER;
--2452 000cf702e5840110304 Page 10 of TLTree.c
5cfcc6 ¤   ¤   pci->iDataFmt = tlc->fmt;
df9371 ¤   }
f1c701 ¤   if (tlc->mask & TLCF_WIDTH) {
0fb6cb ¤   ¤   hditem.mask |= HDI_WIDTH;
897108 ¤   ¤   hditem.cxy = tlc->cx;
6eca2f ¤   ¤   pci->cx = tlc->cx;
3dbea4 ¤   ¤   if (pci->cx >= BITMAPWIDTH)·
010f2d ¤   ¤   ¤   pci->cxImageOffset = (pci->cx - BITMAPWIDTH) / 2;
8eee26 ¤   ¤   else·
f82c7a ¤   ¤   ¤   pci->cxImageOffset = 0;
9a9371 ¤   }
5a01c5 ¤   if (tlc->mask & TLCF_TEXT) {
898df7 ¤   ¤   hditem.mask |= HDI_TEXT;
a187ee ¤   ¤   hditem.pszText = tlc->pszText;
1f9371 ¤   }
0ff3a5 ¤   if (tlc->mask & TLCF_SUBITEM) {
90f0d0 ¤   ¤   hditem.mask |= HDI_LPARAM;
297ac5 ¤   ¤   hditem.lParam = tlc->iSubItem;
bf9371 ¤   }
f25ed7 ¤   if (tlc->mask & TLCF_MOUSENOTIFY) {
4b8341 ¤   ¤   pci->bMouseNotify = tlc->bMouseNotify;
ae9371 ¤   }
58ea0b ¤   pWD->iNumberColumns++;
2b67c5 ¤
87d201 ¤   return (Header_InsertItem (pWD->hWndHeader, index, &hditem));·
07efe6 }
bdaf5a
12af5a
dbbf56 //----------------------------------------------------|
0a67d4 // ·Change column attributes
31af5a
b58be0 LONG TLSetColumn (TLWndData* pWD, LONG index, TL_COLUMN* tlc) {
32af5a
75f065 ¤   TLColumnItem* pci;
86d1f4 ¤   HD_ITEM hdi;
114ba4 ¤   int i;
4caf5a
14dc00 ¤   if (index < 1) return -1;
93e702 ¤   if (index >= pWD->iNumberColumns) return -1;
c5af5a
ff4940 ¤   hdi.mask = 0;
8eaf5a
1f96fd ¤   pci = pWD->columnItem;
556cae ¤   for (i=1; i<index; i++) {
8a17f3 ¤   ¤   if (pci) pci = pci->nextItem;
6e9371 ¤   }
e871c3 ¤   pci->iSubItem = index;
86af5a
d2bf91 ¤   if (tlc->mask & TLCF_DATATYPE) {
9708f3 ¤   ¤   pci->iDataType = tlc->iDataType;
6c9371 ¤   }
a40184 ¤   if (tlc->mask & TLCF_FMT) {
a4fcc6 ¤   ¤   pci->iDataFmt = tlc->fmt;
d99371 ¤   }
0f40b7 ¤   if (tlc->mask & TLCF_DATAMAX) {
9b3aae ¤   ¤   pci->lMaxValue = tlc->cchTextMax;
de9371 ¤   }
fcc701 ¤   if (tlc->mask & TLCF_WIDTH) {
e2ca2f ¤   ¤   pci->cx = tlc->cx;
1cbea4 ¤   ¤   if (pci->cx >= BITMAPWIDTH)·
b40f2d ¤   ¤   ¤   pci->cxImageOffset = (pci->cx - BITMAPWIDTH) / 2;
7dee26 ¤   ¤   else·
092c7a ¤   ¤   ¤   pci->cxImageOffset = 0;
2451bc ¤   ¤   hdi.mask = HDI_WIDTH;
aedb0c ¤   ¤   hdi.cxy = tlc->cx;
d98a65 ¤   ¤   pWD->iTotalWidth += tlc->cx;
259371 ¤   }
78af5a
9620c8 ¤   if (hdi.mask) Header_SetItem (pWD->hWndHeader, index, &hdi);
76af5a
3e3237 ¤   InvalidateRect (pWD->hWnd, NULL, TRUE);
cf24a6 ¤   return index;
--ee82 0007186325840110304 Page 11 of TLTree.c
7aefe6 }
46af5a
8eaf5a
76bf56 //----------------------------------------------------|
dab87e // ·Get column width
02af5a
9f544b LONG TLGetColumnWidth (TLWndData* pWD, LONG index) {
7daf5a
c2f065 ¤   TLColumnItem* pci;
244ba4 ¤   int i;
c0af5a
2fa2ea ¤   if (index < 0) return -1;
44e702 ¤   if (index >= pWD->iNumberColumns) return -1;
72af5a
42d35b ¤   if (index == 0) return (pWD->iFirstColumnWidth);
83af5a
2296fd ¤   pci = pWD->columnItem;
506cae ¤   for (i=1; i<index; i++) {
6b17f3 ¤   ¤   if (pci) pci = pci->nextItem;
d59371 ¤   }
ebe4f5 ¤   return pci->cx;
7fefe6 }
89af5a
7eaf5a
90bf56 //----------------------------------------------------|
9da5a7 // ·Set data in list item
fcaf5a
890a3d LONG TLSetListItem (TLWndData* pWD, TL_LISTITEM* lpli, BOOL bInvalidate) {
a87eca ¤   TLListItem* pli;
5e4ba4 ¤   int i;
02af5a
575525 ¤   if (!lpli) return -1;
8fec53 ¤   if (lpli->iSubItem < 1) return -1;
3fcd74 ¤   if (lpli->iSubItem >= pWD->iNumberColumns) return -1;
8aaf5a
a0f7fc ¤   pli = ((TLTreeItem*)(lpli->hItem))->listItem;
eb9f4f ¤   for (i=1; i<lpli->iSubItem; i++) {
8e1184 ¤   ¤   pli = pli->nextItem;
359371 ¤   }
23af5a
b76c3d ¤   if (lpli->mask & TLIF_STATE) {
a90217 ¤   ¤   pli->state &= ~(lpli->stateMask);
1715d3 ¤   ¤   pli->state |= (lpli->stateMask & lpli->state);
189371 ¤   }
9155db ¤   if (lpli->mask & TLIF_TEXT) {
e20838 ¤   ¤   TLFree (pli->pszText);
29844c ¤   ¤   if (lpli->pszText) {
ab06dd ¤   ¤   ¤   pli->pszText = TLAlloc (lstrlen (lpli->pszText) +1);
9fbe8b ¤   ¤   ¤   lstrcpy (pli->pszText, lpli->pszText);
280fe4 ¤   ¤   }
be0e1d ¤   ¤   else
4b25c1 ¤   ¤   ¤   pli->pszText = NULL;
849371 ¤   }
779f83 ¤   if (lpli->mask & TLIF_DATAVALUE) {
21091e ¤   ¤   pli->lDataValue = lpli->lDataValue;
599371 ¤   }
10af5a
25cb8d ¤   if (bInvalidate) TLInvalidateItem (pWD, (TLTreeItem*)lpli->hItem);
c416b1 ¤   return (lpli->iSubItem);
4ca79b }·
31af5a
30af5a
abbf56 //----------------------------------------------------|
08d58b // ·Get data in list item
e7af5a
db347a LONG TLGetListItem (TLWndData* pWD, TL_LISTITEM* lpli) {
e47eca ¤   TLListItem* pli;
b74ba4 ¤   int i;
1aaf5a
525525 ¤   if (!lpli) return -1;
6bec53 ¤   if (lpli->iSubItem < 1) return -1;
71cd74 ¤   if (lpli->iSubItem >= pWD->iNumberColumns) return -1;
--0b05 001387f25d240110304 Page 12 of TLTree.c
e0af5a
a3f7fc ¤   pli = ((TLTreeItem*)(lpli->hItem))->listItem;
a79f4f ¤   for (i=1; i<lpli->iSubItem; i++) {
b01184 ¤   ¤   pli = pli->nextItem;
069371 ¤   }
a9af5a
6055db ¤   if (lpli->mask & TLIF_TEXT) {
08844c ¤   ¤   if (lpli->pszText) {
3df5f7 ¤   ¤   ¤   if (lstrlen (pli->pszText) < lpli->cchTextMax)
b6eeb4 ¤   ¤   ¤   ¤   lstrcpy (lpli->pszText, pli->pszText);
d30fe4 ¤   ¤   }
ab9371 ¤   }
1daf5a
af9f83 ¤   if (lpli->mask & TLIF_DATAVALUE) {
f2440f ¤   ¤   lpli->lDataValue = pli->lDataValue;
229371 ¤   }
2aaf5a
bc16b1 ¤   return (lpli->iSubItem);
2ca79b }·
79af5a
4caf5a
2abf56 //----------------------------------------------------|
879381 // ·Ensure that specified item is visible·
00af5a
a68697 BOOL TLEnsureVisible (TLWndData* pWD, TL_TREEITEM* lpti) {
52af5a
13eb76 ¤   if (!lpti->hItem) return FALSE;
9f7ce7 ¤   if (!pWD->rootItem) return FALSE;
2daf5a
abce2a ¤   return (TLSelectAutoScroll (pWD, (TLTreeItem*)lpti->hItem));
80efe6 }
a7af5a
38af5a
--6a2b 000e52c0ccf40110305 Page 1 of TLintern.h
9e46cc //: TreeList internal include file
bf465d //
fe5df1 //¤ $Id: TLintern.h,v 1.24 1998/08/13 22:28:23 pbj Exp $
d1465d //
442a68 #define WIN32_LEAN_AND_MEAN
7fca87 #define _WIN32_WINNT 0x0400
08a7a0 #include <limits.h>
e95655 #include <windows.h>
8190fb #include <commctrl.h>
4223f4 #include "..\include\TreeList.h"
f2af5a
97dfe2 #define KEYTIMEOUT¤ ¤   1000L¤  //millisec to wait for subsequent keypresses
3bb7b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //¤ while autoscrolling·
896ea1 #define KEYBOARDTIMERID¤1111L¤  //arbitrary numbers used as timer identifiers
86af5a
dd83fb #define REORDERTIMEOUT¤ 10L¤¤   //millisec to delay for reordering
47ff5c #define REORDERTIMERID¤ 1112L¤  //arbitrary numbers used as timer identifiers
efaf5a
3c84e2 #define DRAGSCROLLTIME¤ ¤   250
30dd44 #define DRAGSCROLLTIMERID¤  1113L
58af5a
f57325 #define DRAGSCROLL_UP¤  ¤   1
98f46e #define DRAGSCROLL_DOWN¤¤   2
baaf5a
883d3d #define TEXTVERTOFF¤¤   ¤   1
045362 #define NUMIMAGELISTS¤  ¤   2
69af5a
b3e7d0 #define IDC_TREELISTHEADER¤ 100
5c90a8 #define IDC_SCROLLBAR¤  ¤   101
69af5a
2f3f70 #define INCREMENTINDENT 16
6364d8 #define BUTTONWIDTH 18
1409c5 #define BUTTONHEIGHT 16
e0b4d0 #define BITMAPWIDTH 16
509546 #define BITMAPHEIGHT 16
f7f6a8 #define HTEXTSHIFT 4
67ce35 #define HBARSHIFT 6
44a874 #define VBARSHIFT 3
df3e6b #define BARCOLUMNDIFF HBARSHIFT*2
33c97e #define HBCENT 9
6a4d81 #define BBOX 4
a4a447 #define BBAR 2
1aaf5a
a5ab21 #define TYPEBUFFERSIZE¤ ¤   32
c3af5a
bc6acc // TreeList linked list list item
17c13d typedef struct _TLListItem {
71a64c ¤   struct _TLListItem* nextItem;
799306 ¤   UINT state;
ed3c2f ¤   LPSTR pszText;
4c1a64 ¤   LONG lDataValue;
03b703 } TLListItem;
89af5a
686acc // TreeList linked list list item
b50600 typedef struct _TLColumnItem {
8ee14f ¤   struct _TLColumnItem* nextItem;
72b546 ¤   INT iSubItem;
707339 ¤   UINT iDataType;
e0a773 ¤   UINT iDataFmt;
2fab41 ¤   LONG lMaxValue;
3586ea ¤   INT cx;
3d7b02 ¤   BOOL bMouseNotify;
69ef49 ¤   INT cxImageOffset;
050660 } TLColumnItem;
faaf5a
cdeb3b // TreeList linked list tree item
0d428c typedef struct _TLTreeItem {
6d66f9 ¤   struct _TLTreeItem* nextItem;
a7f538 ¤   struct _TLTreeItem* prevItem;
585c7c ¤   struct _TLTreeItem* childItem;
811c80 ¤   struct _TLTreeItem* parentItem;
e5efe0 ¤   TLListItem* listItem;
--5baf 000a152a7c740110305 Page 2 of TLintern.h
152d82 ¤   RECT selectRect;
bbfae2 ¤   RECT hiliteRect;
75a2a4 ¤   RECT buttonRect;
009306 ¤   UINT state;
d13c2f ¤   LPSTR pszText;
e56cfc ¤   INT iImage;
f2edbb ¤   INT iSelImage;
cfbddd ¤   INT cChildren;
aee0a9 ¤   LPARAM lParam;
7336f4 } TLTreeItem;
0aaf5a
a2904e // TreeList window extra data. ·Must include window handle field.
8e44fd typedef struct _TLWndData {
67355e ¤   HWND hWnd;
3c4ed3 ¤   HWND hWndParent;
800424 ¤   HWND hWndHeader;
34e020 ¤   HDC ·hdcMem;
4004c1 ¤   HBITMAP hbmMem;
957734 ¤   HBITMAP hbmOld;
26b86c ¤   HFONT hFont;
ab847d ¤   HFONT hFontItalic;
12b069 ¤   HFONT hFontBold;
c1b67b ¤   LONG id;
845b1f ¤   UINT style;
79d9ca ¤   BOOL bTreeFocused;
382ebd ¤   INT iNumberSelected;
26e51a ¤   NM_TREELIST nmTreeList;
48cf1f ¤   TL_KEYDOWN nmKeyDown;
078e17 ¤   HIMAGELIST hImageList;
f5c88c ¤   HCURSOR hCursorNormal;
92167b ¤   HCURSOR hCursorDragging;
66e0bc ¤   HCURSOR hCursorNoDrag;
37b8f9 ¤   TLTreeItem* rootItem;
b046a2 ¤   TLTreeItem* focusItem;
1edaca ¤   TLTreeItem* firstSelectItem;
70e46e ¤   TLTreeItem* clickedTreeItem;
d7c21e ¤   TLListItem* clickedListItem;
36c77a ¤   TLColumnItem* columnItem;
e501ec ¤   INT iNumberColumns;
0607d1 ¤   INT iFirstColumnWidth;
f49080 ¤   INT iTotalWidth;
252e3c ¤   INT iHorizontalPos;
f2735f ¤   INT iMaxRows;
1ecc3e ¤   INT iFirstRow;
b88748 ¤   INT iExpandedRows;
d3800f ¤   INT iRowHeight;
e29c75 ¤   INT iWheelDelta;
adb7fa ¤   INT iWheelScroll;
98419b ¤   RECT tlRect;
13f451 ¤   RECT tlInval;
8f89a5 ¤   BOOL bDragging;
2ba7d8 ¤   BOOL bStillTyping;
8fb60d ¤   UINT uDragScrollState;
3cef09 ¤   POINT ptButtonDown;
d027e7 ¤   HBRUSH selbgbrush;
e730c9 ¤   HBRUSH unselbgbrush;
d81802 ¤   HBRUSH selfgbrush;
200f2c ¤   HBRUSH unselfgbrush;
fbbd45 ¤   HBRUSH stdbarbrush;
adba96 ¤   HBRUSH barbgbrush;
0918d5 ¤   HBRUSH spcbarbrush;
72ebc7 ¤   DWORD textbgcolor;
b04702 ¤   DWORD barcolor;
51d3e6 ¤   DWORD linecolor;
0d9960 ¤   DWORD selfocuscolor;
cd97d3 ¤   DWORD unselfocuscolor;
6649ec ¤   HBITMAP barbgbitmap;
6d52cb ¤   HPEN seltextpen;
9fb95e ¤   HPEN unseltextpen;
2aaf9a ¤   HPEN buttonpen;
c4640e ¤   HPEN hilightpen;
a11db9 ¤   HPEN shadowpen;
--8724 000dded7f7b40110305 Page 3 of TLintern.h
e2ad86 ¤   INT iBCent;
b1f61f ¤   INT iBMPos;
57530c ¤   CHAR szTypeBuf[TYPEBUFFERSIZE];
a7cf27 ¤   CHAR* pTypeBufPtr;
216e9f ¤   INT iNumCharInTypeBuf;
121933 } TLWndData;
deaf5a
d91ab9 #define TreeList_GetPtr(hwnd) ·(TLWndData*)GetWindowLong((hwnd), 0)
490b90 #define TreeList_SetPtr(hwnd, pTL) ·\
3f0937 ¤   ¤   ¤   (TLWndData*)SetWindowLong((hwnd), 0, (LONG)(pTL))
6caf5a
45ccf1 // function prototypes
ecaf5a
c485ec // TLMisc.c
715974 void* TLAlloc (long size);
93eec6 void* TLReAlloc (void* p, long size);
3b18b2 void TLFree (void* p);
41dbee BOOL TLKeyboardChar (TLWndData* pWD, WPARAM ch, LPARAM lP);
0e9495 BOOL TLIterateSelected (TLWndData* pWD, LPARAM lParam);
baad23 BOOL TLSelectByKeyboard (TLWndData* pWD, LONG c, BOOL bStillTyping);
a4af5a
a0eb2c // TLMouse.c
a8c4aa void TLLeftButtonDown (TLWndData* pWD, WPARAM wParam, LPARAM lParam);
fa3cc8 void TLLeftButtonUp (TLWndData* pWD, WPARAM wParam, LPARAM lParam);
7f7bef void TLRightButtonDown (TLWndData* pWD, WPARAM wParam, LPARAM lParam);
fdec0c void TLLeftButtonDblClk (TLWndData* pWD, WPARAM wParam, LPARAM lParam);
e4ed7a BOOL TLHeaderNotification (TLWndData* pWD, NMHEADER* pnmh);
076b0f void TLHScroll (TLWndData* pWD, int code, int pos, HWND hWndBar);
a3e9a6 void TLVScroll (TLWndData* pWD, int code, int pos, HWND hWndBar);
6a2886 void TLResize (TLWndData* pWD, WINDOWPOS* pWP);
1e1ab3 BOOL TLSelectRange (TLWndData* pWD, TLTreeItem* pFirst, TLTreeItem* pSel);
bba762 void TLMouseMove (TLWndData* pWD, WPARAM wParam, LPARAM lParam);
85332a void TLDragScroll (TLWndData* pWD);
0294f7 BOOL TLDragOver (TLWndData* pWD, LPARAM lParam);
9346fa BOOL TLDeDragOverTree (TLWndData* pWD, TLTreeItem* p, TLTreeItem* pExcept);
da73c7 void TLEndDrag (TLWndData* pWD, LPARAM lParam);
3be5be void TLMouseWheel (TLWndData* pWD, int iKeys, short int iDelta);
89af5a
ade335 // TLMsgProc.c
4dfbee LRESULT WINAPI TreeListMsgProc (HWND hWnd, UINT msg, WPARAM wParam,·
d8f776 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
92af5a
06e8c2 // TLPaint.c
2b6bb0 BOOL TLGetRow (TLTreeItem* root, TLTreeItem* p, int* row);
a9af13 void TLInitPaint (TLWndData* pWD);
a24e0b void TLClosePaint (TLWndData* pWD);
8db0de void TLPrePaint (TLWndData* pWD);
2823c5 void TLPaint (TLWndData* pWD, HDC hdc);
b58634 void TLMemPaint (TLWndData* pWD, HDC hdc);
621180 void TLExpandAutoScroll (TLWndData* pWD, TLTreeItem* p);
6f42e5 BOOL TLSelectAutoScroll (TLWndData* pWD, TLTreeItem* p);
e25040 void TLInvalidateItem (TLWndData* pWD, TLTreeItem* p);
f7b366 void TLDeleteMemDC (TLWndData* pWD);
bd5b4c BOOL TLMemPaintDragBitmap (TLWndData* pWD, LPTL_DRAGBITMAP lpdb);
58af5a
4cdacb // TLTree.c
535cb1 HTLITEM TLInsertTreeItem (TLWndData* pWD, LPTL_INSERTSTRUCT lpInsert);
cd5159 LONG TLSetListItem (TLWndData* pWD, TL_LISTITEM* pli, BOOL bInvalidate);
a72ab0 LONG TLGetListItem (TLWndData* pWD, TL_LISTITEM* pli);
74edcb void TLDeleteTreeList (TLTreeItem* p);
b911fb BOOL TLDeleteAllColumns (TLWndData* pWD);
b5a065 LONG TLInsertColumn (TLWndData* pWD, LONG index, TL_COLUMN* tlc);
258342 LONG TLSetColumn (TLWndData* pWD, LONG index, TL_COLUMN* tlc);
dced0b LONG TLGetColumnWidth (TLWndData* pWD, LONG index);
1e472a BOOL TLGetTreeItem (TLWndData* pWD, TL_TREEITEM* lpti);
a3354b BOOL TLDeselectTree (TLWndData* pWD, TLTreeItem* p, TLTreeItem* pExcept);
5f23d4 BOOL TLExpandTreeItem (TLWndData* pWD, TL_TREEITEM* lpti, int flags);
fb8c3e BOOL TLSelectTreeItem (TLWndData* pWD, TL_TREEITEM* lpti, int flags);
f185cb BOOL TLSelectChildren (TLWndData* pWD, TL_TREEITEM* lpti);
c18c84 BOOL TLSetTreeItem (TLWndData* pWD, TL_TREEITEM* lpti);
fea293 BOOL TLDeleteTreeItem (TLWndData* pWD, TL_TREEITEM* lpti);
dd50f3 void TLExpandTree (TLTreeItem* p);
--ab0b 001ac9a0ed840110305 Page 4 of TLintern.h
ac9c9f BOOL TLEnsureVisible (TLWndData* pWD, TL_TREEITEM* lpti);
--181a 0014a9b6f9f40110306 Page 1 of TreeList.c
53e0fb //:TreeList.c - handle "TreeList" window class
87465d //
dd6e78 //¤ $Id: TreeList.c,v 1.8 1997/09/12 15:51:49 pbj Exp $
99465d //
6aaf5a
36fb2c #include "TLintern.h"
55af5a
78af5a
3dbf56 //----------------------------------------------------|
4b034e // ·Load and initialize control
8daf5a
ec620a void WINAPI InitTreeListControl (void) {
61af5a
f9ee70 ¤   WNDCLASS ·wc;
3b67c5 ¤
e83500 ¤   InitCommonControls ();
2baf5a
4a88b5 ¤   // register new window classes for menus
000fc9 ¤   wc.style = CS_DBLCLKS | CS_GLOBALCLASS | CS_PARENTDC; // Class style(s).
b19408 ¤   wc.lpfnWndProc = (WNDPROC) TreeListMsgProc;·
c0192b ¤   wc.cbClsExtra = 0;¤ ························// No per-class extra data.
50b2fc ¤   wc.cbWndExtra = sizeof (TLWndData*);¤   ¤   // pointer to extra data·
255c1a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   //¤ ¤   structure
9066c4 ¤   wc.hInstance = 0;¤
3b6a26 ¤   wc.hIcon = NULL;
792d56 ¤   wc.hCursor = LoadCursor (NULL, IDC_ARROW);
6247f4 ¤   wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); // Background color
78fa8a ¤   wc.lpszMenuName = NULL;¤¤   ¤   ¤   ¤   ¤   // No menu
05bbdf ¤   wc.lpszClassName = "TreeListCtrl32";¤   ¤   // Name used in CreateWindow
c36228 ¤   RegisterClass (&wc);
2baf5a
ceefe6 }
44af5a
4aaf5a

--290b 00054adef9a40110307 Page 1 of Attachments.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
460aed ¤   $Id: Attachments.cpp,v 1.15.2.4.2.1 1998/11/12 03:13:53 heller Exp $
4caf5a
35af5a
c6f7f7 ____________________________________________________________________________*/
3d5d3c #include "stdinc.h"
2f9803 #include "Exchange.h"
07b04c #include "EncryptSign.h"
e453a7 #include "DecryptVerify.h"
e78031 #include "resource.h"
b8adf9 #include "UIutils.h"
d4af5a
52e2ff #include "pgpConfig.h"
099f63 #include "pgpEncode.h"
074919 #include "pgpUtilities.h"
5d0d08 #include "pgpMem.h"
e1af5a
93af5a
75d554 STDMETHODIMP CExtImpl::OnReadPattFromSzFile(IAttach* lpAtt,·
71d351 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPTSTR lpszFile,·
0775ac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ULONG ulFlags)
62bb36 {
5c2a53 ¤   _bHaveAttachments = TRUE;
48e94b ¤   return S_FALSE;
d9efe6 }
6daf5a
3baf5a
4ca34a STDMETHODIMP CExtImpl::OnWritePattToSzFile(IAttach* lpAtt,·
d59939 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···LPTSTR lpszFile,·
41ba7b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···ULONG ulFlags)
7abb36 {
e1e94b ¤   return S_FALSE;
9defe6 }
0eaf5a
2eaf5a
56b21c STDMETHODIMP CExtImpl::QueryDisallowOpenPatt(IAttach* lpAtt)
7fbb36 {
21e94b ¤   return S_FALSE;
83efe6 }
03af5a
beaf5a
fd2199 STDMETHODIMP CExtImpl::OnOpenPatt(IAttach* lpAtt)
7ebb36 {
1be94b ¤   return S_FALSE;
b0efe6 }
51af5a
e7af5a
7b811b STDMETHODIMP CExtImpl::OnOpenSzFile(LPTSTR lpszFile, ULONG ulFlags)
3cbb36 {
3fc0cb ¤   char *szExtension;
315631 ¤   char *szOutFile = NULL;
514cea ¤   HINSTANCE hInst;
3b1e1a ¤   int nError;
9ced51 ¤   char szName[256];
31752f ¤   char szFile[256];
762392 ¤   BOOL bDummy;
57af5a
e44416 ¤   if (_context != EECONTEXT_READNOTEMESSAGE)
9393bf ¤   ¤   return S_FALSE;
feaf5a
fd6a8c ¤   szExtension = strrchr(lpszFile, '.');
b94c2a ¤   if (!szExtension)
1c93bf ¤   ¤   return S_FALSE;
77cdde ¤   if (stricmp(szExtension, ".asc") && stricmp(szExtension, ".pgp"))
7393bf ¤   ¤   return S_FALSE;
54af5a
--66b5 0003ac450e440110307 Page 2 of Attachments.cpp
ae3a44 ¤   UIGetString(szName, sizeof(szName), IDS_LOGNAME);
001792 ¤   UIGetString(szFile, sizeof(szFile), IDS_DLL);
58af5a
f33c28 ¤   nError = DecryptVerifyFile(UIGetInstance(), NULL, _pgpContext,·
a972ea ¤   ¤   ¤   ¤   _tlsContext, szName, szFile, lpszFile, FALSE, TRUE,·
39897c ¤   ¤   ¤   ¤   &szOutFile, NULL, NULL, &bDummy);
4eaf5a
be21a4 ¤   if (nError == kPGPError_NoErr)
99c7a1 ¤   {
8af46f ¤   ¤   hInst = ShellExecute(NULL, "open", szOutFile, NULL, NULL, 0);
36af5a
5e19f1 ¤   ¤   if (szOutFile != NULL)
57f663 ¤   ¤   ¤   PGPFreeData(szOutFile);
5daf5a
abecdd ¤   ¤   return S_OK;
859371 ¤   }
1eaf5a
2ae94b ¤   return S_FALSE;
cdefe6 }
f7af5a
05af5a
263d03 int CExtImpl::EncryptSignAttachment(HWND hwnd,
c174c3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IMessage *psmg,
3d969c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   UINT nOutSize,
a385fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   SRowSet *prAttach,
74aa74 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds,
e41f15 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOptionListRef *pSignOptions)
bbbb36 {
19919b ¤   ULONG ulRow;
c2bb0b ¤   ULONG ulNum;
885b5f ¤   SizedSPropTagArray(6, tagaAttach) = {
06fe8c ¤   ¤   6, {PR_ATTACH_METHOD, PR_ATTACH_TAG, PR_RENDERING_POSITION,·
7e1dd5 ¤   ¤   ¤   PR_ATTACH_FILENAME, PR_ATTACH_LONG_FILENAME,·
d04b02 ¤   ¤   ¤   PR_DISPLAY_NAME}};
e92624 ¤   enum {ivalAttachMethod=0, ivalAttachTag, ivalRenderingPos, ivalFilename,·
1f136d ¤   ¤   ¤   ivalLongFilename, ivalDisplayName};
f8c474 ¤   SPropValue *pval;
65abfc ¤   ULONG ulNumVals;
ff5815 ¤   LPATTACH pAttach = 0;
70c36d ¤   IStream *pstrmAttach;
1dc0b5 ¤   STATSTG AttStreamStats;
2781f4 ¤   DWORD dwAttSize;
8cb150 ¤   UINT nAttOutSize;
352375 ¤   char *pAttachText = NULL;
da5c3d ¤   char *pOutput = NULL;
0cec13 ¤   char *szFileName;
d29fe0 ¤   char *szLongFileName;
04c0cb ¤   char *szExtension;
05f5b4 ¤   int nError = 0;
efed51 ¤   char szName[256];
ae752f ¤   char szFile[256];
9567c5 ¤
be3a44 ¤   UIGetString(szName, sizeof(szName), IDS_LOGNAME);
d01792 ¤   UIGetString(szFile, sizeof(szFile), IDS_DLL);
7aaf5a
7a41dc ¤   for (ulRow=0; ulRow<prAttach->cRows; ulRow++)
7bc7a1 ¤   {
52a801 ¤   ¤   ulNum = prAttach->aRow[ulRow].lpProps[0].Value.l;
8e2606 ¤   ¤   psmg->OpenAttach(ulNum, NULL, MAPI_MODIFY, &pAttach);
f8ffb7 ¤   ¤   pAttach->GetProps((SPropTagArray *)&tagaAttach, 0,·
b21679 ¤   ¤   ¤   &ulNumVals, &pval);
16e9a6 ¤   ¤   switch (pval[ivalAttachMethod].Value.l)
9d5b34 ¤   ¤   {
5f26fb ¤   ¤   case ATTACH_BY_VALUE:
eca296 ¤   ¤   ¤   // Don't sign attachments unless we're also encrypting them
039d84 ¤   ¤   ¤   if (_bEncrypt)
38f776 ¤   ¤   ¤   {
055c55 ¤   ¤   ¤   ¤   pAttach->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, 0,·
41ea3a ¤   ¤   ¤   ¤   ¤   MAPI_MODIFY, (LPUNKNOWN *) &pstrmAttach);
4c2b85 ¤   ¤   ¤   ¤
b5003f ¤   ¤   ¤   ¤   pstrmAttach->Stat(&AttStreamStats, STATFLAG_NONAME);
3a719a ¤   ¤   ¤   ¤   dwAttSize = AttStreamStats.cbSize.LowPart;
--d61a 0006fa15e8f40110307 Page 3 of Attachments.cpp
9f2b85 ¤   ¤   ¤   ¤
852bcc ¤   ¤   ¤   ¤   pAttachText = (char *) calloc(dwAttSize+1, sizeof(char));
ae882d ¤   ¤   ¤   ¤   pstrmAttach->Read(pAttachText, dwAttSize, &dwAttSize);
7cd913 ¤   ¤   ¤   ¤   pAttachText[dwAttSize] = 0;
1d0908 ¤   ¤   ¤   ¤   nError = EncryptSignBuffer(UIGetInstance(), hwnd,·
a17409 ¤   ¤   ¤   ¤   ¤   _pgpContext, _tlsContext, szName, szFile,
1ce5a6 ¤   ¤   ¤   ¤   ¤   pAttachText, dwAttSize, prds, NULL, pSignOptions,·
86e1ae ¤   ¤   ¤   ¤   ¤   (VOID ** )&pOutput, &nAttOutSize, _bEncrypt, _bSign,·
af8584 ¤   ¤   ¤   ¤   ¤   TRUE);
212b85 ¤   ¤   ¤   ¤
aa36e4 ¤   ¤   ¤   ¤   if (!nError)
5372c3 ¤   ¤   ¤   ¤   {
7e1059 ¤   ¤   ¤   ¤   ¤   ULONG ulAttOutSize = nAttOutSize;
92a5f6 ¤   ¤   ¤   ¤   ¤   LARGE_INTEGER li = {0,0};
1c4cb9 ¤   ¤   ¤   ¤   ¤   ULARGE_INTEGER uli = {ulAttOutSize, 0};
9f0a3e ¤   ¤   ¤   ¤   ¤   ULONG ulWritten;
d8e946 ¤   ¤   ¤   ¤   ¤   ULARGE_INTEGER uliSeek;
c1ae30 ¤   ¤   ¤   ¤   ¤
839e44 ¤   ¤   ¤   ¤   ¤   pstrmAttach->Seek(li, STREAM_SEEK_SET, &uliSeek);
207e3f ¤   ¤   ¤   ¤   ¤   pstrmAttach->Write(pOutput, ulAttOutSize, &ulWritten);
0b48ac ¤   ¤   ¤   ¤   ¤   pstrmAttach->SetSize(uli);
38cf58 ¤   ¤   ¤   ¤   ¤   pstrmAttach->Commit(STGC_DEFAULT);
b8ba05 ¤   ¤   ¤   ¤   ¤   pstrmAttach->Release();
c4800d ¤   ¤   ¤   ¤   ¤   PGPFreeData(pOutput);
642613 ¤   ¤   ¤   ¤   }
51fa07 ¤   ¤   ¤   ¤   else
91ba05 ¤   ¤   ¤   ¤   ¤   pstrmAttach->Release();
c32b85 ¤   ¤   ¤   ¤
c0f52f ¤   ¤   ¤   ¤   if (pval[ivalRenderingPos].Value.l > -1)
1d60a1 ¤   ¤   ¤   ¤   ¤   pval[ivalRenderingPos].Value.l = nOutSize + ulRow;
6c2b85 ¤   ¤   ¤   ¤
6648b2 ¤   ¤   ¤   ¤   szFileName = (char *) calloc(MAX_PATH, sizeof(char));
cc7956 ¤   ¤   ¤   ¤   szLongFileName = (char *) calloc(MAX_PATH, sizeof(char));
7ce112 ¤   ¤   ¤   ¤   strcpy(szFileName, pval[ivalFilename].Value.lpszA);
48dbca ¤   ¤   ¤   ¤   strcpy(szLongFileName, pval[ivalLongFilename].Value.lpszA);
fd117b ¤   ¤   ¤   ¤   szExtension = strrchr(szFileName, '.');
7eb3b6 ¤   ¤   ¤   ¤   if (szExtension)
1389d4 ¤   ¤   ¤   ¤   ¤   *szExtension = '\0';
422b85 ¤   ¤   ¤   ¤
44ea4d ¤   ¤   ¤   ¤   strcat(szFileName, ".asc");
6fbc64 ¤   ¤   ¤   ¤   strcpy(pval[ivalFilename].Value.lpszA, szFileName);
850429 ¤   ¤   ¤   ¤   strcat(szLongFileName, ".asc");
d48aba ¤   ¤   ¤   ¤   MAPIFreeBuffer(pval[ivalLongFilename].Value.lpszA);
df627c ¤   ¤   ¤   ¤   MAPIAllocateBuffer(MAX_PATH,·
822af4 ¤   ¤   ¤   ¤   ¤   (void **) &(pval[ivalLongFilename].Value.lpszA));
96b8e0 ¤   ¤   ¤   ¤   MAPIFreeBuffer(pval[ivalDisplayName].Value.lpszA);
62627c ¤   ¤   ¤   ¤   MAPIAllocateBuffer(MAX_PATH,·
b875bb ¤   ¤   ¤   ¤   ¤   (void **) &(pval[ivalDisplayName].Value.lpszA));
f71bb2 ¤   ¤   ¤   ¤   strcpy(pval[ivalLongFilename].Value.lpszA, szLongFileName);
7b52de ¤   ¤   ¤   ¤   strcpy(pval[ivalDisplayName].Value.lpszA, szLongFileName);
0836e4 ¤   ¤   ¤   ¤   if (!nError)
24a4e1 ¤   ¤   ¤   ¤   ¤   pAttach->SetProps(6, pval, NULL);
92077d ¤   ¤   ¤   ¤   free(szFileName);
6b0d40 ¤   ¤   ¤   ¤   free(szLongFileName);
0ea3a6 ¤   ¤   ¤   }
1abb8c ¤   ¤   ¤   else
2cf776 ¤   ¤   ¤   {
7bf52f ¤   ¤   ¤   ¤   if (pval[ivalRenderingPos].Value.l > -1)
2960a1 ¤   ¤   ¤   ¤   ¤   pval[ivalRenderingPos].Value.l = nOutSize + ulRow;
9d0ae0 ¤   ¤   ¤   ¤   pAttach->SetProps(6, pval, NULL);
1ea3a6 ¤   ¤   ¤   }
f5f2b3 ¤   ¤   ¤   pAttach->SaveChanges(0);
13cdcb ¤   ¤   ¤   break;
b887c7 ¤   ¤   ¤
95bd0f ¤   ¤   case ATTACH_BY_REFERENCE:
ebcdcb ¤   ¤   ¤   break;
af87c7 ¤   ¤   ¤
89536c ¤   ¤   case ATTACH_BY_REF_RESOLVE:
e2cdcb ¤   ¤   ¤   break;
8187c7 ¤   ¤   ¤
1f2539 ¤   ¤   case ATTACH_BY_REF_ONLY:
6fcdcb ¤   ¤   ¤   break;
--668f 0017864f36140110307 Page 4 of Attachments.cpp
e587c7 ¤   ¤   ¤
1995ea ¤   ¤   case ATTACH_EMBEDDED_MSG:
75f776 ¤   ¤   ¤   {
0a0543 ¤   ¤   ¤   ¤   IMessage *pmsg = 0;
54af5a
d9d9b7 ¤   ¤   ¤   ¤   pAttach->OpenProperty(PR_ATTACH_DATA_OBJ, &IID_IMessage, 0,·
4fc6d1 ¤   ¤   ¤   ¤   ¤   MAPI_MODIFY, (LPUNKNOWN *) &pmsg);
fe6cd8 ¤   ¤   ¤   ¤   nError = EncryptSignMessage(hwnd, pmsg, prds, pSignOptions);
741cff ¤   ¤   ¤   ¤   pmsg->SaveChanges(0);
ebf24a ¤   ¤   ¤   ¤   pmsg->Release();
33a3a6 ¤   ¤   ¤   }
35f2b3 ¤   ¤   ¤   pAttach->SaveChanges(0);
a6cdcb ¤   ¤   ¤   break;
ec87c7 ¤   ¤   ¤
a101fa ¤   ¤   case ATTACH_OLE:
7bf776 ¤   ¤   ¤   {
f9f52f ¤   ¤   ¤   ¤   if (pval[ivalRenderingPos].Value.l > -1)
b260a1 ¤   ¤   ¤   ¤   ¤   pval[ivalRenderingPos].Value.l = nOutSize + ulRow;
01af5a
c60ae0 ¤   ¤   ¤   ¤   pAttach->SetProps(6, pval, NULL);
b5a3a6 ¤   ¤   ¤   }
37f2b3 ¤   ¤   ¤   pAttach->SaveChanges(0);
e2cdcb ¤   ¤   ¤   break;
3f87c7 ¤   ¤   ¤
419ae3 ¤   ¤   default:
42cdcb ¤   ¤   ¤   break;
ce0fe4 ¤   ¤   }
f881e7 ¤   ¤   MAPIFreeBuffer(pval);
67dad5 ¤   ¤   if (pAttachText)
be5b34 ¤   ¤   {
bbcaee ¤   ¤   ¤   free(pAttachText);
3c5cb7 ¤   ¤   ¤   pAttachText = NULL;
a40fe4 ¤   ¤   }
748d4c ¤   ¤   pAttach->Release();
a61b52 ¤   ¤
cfdf9d ¤   ¤   if (nError)
44cdcb ¤   ¤   ¤   break;
1c9371 ¤   }
2eaf5a
409909 ¤   return nError;
b1efe6 }
afaf5a
deaf5a
2b7e4d /*__Editor_settings____
ebaf5a
a84126 ¤   Local Variables:
d77b17 ¤   tab-width: 4
900e6c ¤   End:
8b5f8c ¤   vi: ts=4 sw=4
a39e9b ¤   vim: si
78d062 _____________________*/
--6605 000df6d74cc40110308 Page 1 of Commands.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
058113 ¤   $Id: Commands.cpp,v 1.34.2.2.2.1 1998/11/12 03:13:54 heller Exp $
97af5a
87af5a
16af5a
32f7f7 ____________________________________________________________________________*/
e55d3c #include "stdinc.h"
9a9803 #include "Exchange.h"
0c8031 #include "resource.h"
1a05f4 #include "AddKey.h"
86b04c #include "EncryptSign.h"
5d53a7 #include "DecryptVerify.h"
36cc89 #include "Prefs.h"
01cd68 #include "Recipients.h"
a91db1 #include "RichEdit_IO.h"
e3d2cf #include "BlockUtils.h"
6fadf9 #include "UIutils.h"
a5af5a
53e2ff #include "pgpConfig.h"
13fb31 #include "pgpOptionList.h"
484919 #include "pgpUtilities.h"
4891b9 #include "pgpSDKPrefs.h"
2d0d08 #include "pgpMem.h"
805ab2 #include "PGPcl.h"
4e72fe #include "PGPsc.h"
4caf5a
42f0f7 typedef struct {
49d376 ¤   ¤   HWND hwndFound;
eac5ad ¤   ¤   int yMax;
aea2c3 ¤   ¤   BOOL bInternetExplorer;
3b1a22 ¤   ¤   BOOL bMicrosoftWord;
61b557 } FindStruct;
feaf5a
7d8c02 static HWND FindMessageWindow(IExchExtCallback* pmecb, FindStruct *fs);
d3da1c BOOL CALLBACK ReportChildren(HWND hwnd, LPARAM lParam);
1baf5a
d6af5a
48b5f3 STDMETHODIMP CExtImpl::InstallCommands(IExchExtCallback* pmecb,·
5300cf ····························HWND hWnd, HMENU hMenu,
6f8d0c ····························UINT * pcmdidBase, LPTBENTRY lptbeArray,
6657e4 ····························UINT ctbe, ULONG ulFlags)
71bb36 {
de9480 ¤   if ((EECONTEXT_READNOTEMESSAGE != _context) &&·
3be686 ¤   ¤   (EECONTEXT_SENDNOTEMESSAGE != _context) &&
d8b852 ¤   ¤   (EECONTEXT_VIEWER != _context))
ef93bf ¤   ¤   return S_FALSE;
96af5a
896223 ¤   // First, the menu
bfaf5a
85b1ce ¤   HMENU hmenuTools;
98f745 ¤   HMENU hmenuHelp;
e994aa ¤   HMENU hmenuHelpTopics;
c8fb87 ¤   ULONG ulBeforeTools;
d260cf ¤   ULONG ulAfterExchange;
f27079 ¤   HRESULT hr = pmecb->GetMenuPos(EECMDID_Tools, &hmenuTools,·
ac90fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &ulBeforeTools, NULL, 0);
6fdb13 ¤   if (S_OK != hr)
614f2d ¤   ¤   return S_FALSE; // No such menu item? ·Very bad.
454071 ¤   hr = pmecb->GetMenuPos(EECMDID_HelpAboutMicrosoftExchange, &hmenuHelp,
cb7b59 ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL, NULL, 0);
3adb13 ¤   if (S_OK != hr)
404f2d ¤   ¤   return S_FALSE; // No such menu item? ·Very bad.
4fe82f ¤   hr = pmecb->GetMenuPos(EECMDID_HelpMicrosoftExchangeHelpTopics,·
75fc74 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &hmenuHelpTopics, NULL, &ulAfterExchange, 0);
c7db13 ¤   if (S_OK != hr)
df4f2d ¤   ¤   return S_FALSE; // No such menu item? ·Very bad.
--e147 000b4e8717640110308 Page 2 of Commands.cpp
e0af5a
b2affb ¤   char szCommand[80];
6867c5 ¤
6d436d ¤   _hmenuPGP = CreatePopupMenu();
96d4a2 ¤   InsertMenu(hmenuTools, ulBeforeTools,·
8a8e92 ¤   ¤   ¤   ¤   MF_BYPOSITION | MF_STRING | MF_POPUP,·
0910bd ¤   ¤   ¤   ¤   (UINT) _hmenuPGP, "&PGP");
77af5a
4666fb ¤   if (_context == EECONTEXT_SENDNOTEMESSAGE)
81c7a1 ¤   {
ad37fd ¤   ¤   UIGetString(szCommand, sizeof(szCommand), IDS_ENCRYPT_MENU);
4b05cb ¤   ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
63dd8e ¤   ¤   _cmdidEncrypt = *pcmdidBase;
643fa6 ·¤  ¤   ++(*pcmdidBase);
16af5a
b21c65 ¤   ¤   UIGetString(szCommand, sizeof(szCommand), IDS_SIGN_MENU);
d005cb ¤   ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
4dee06 ¤   ¤   _cmdidSign = *pcmdidBase;
013fa6 ·¤  ¤   ++(*pcmdidBase);
68af5a
a11064 ¤   ¤   AppendMenu(_hmenuPGP, MF_SEPARATOR, 0, NULL);
e71b52 ¤   ¤
44a18f ¤   ¤   UIGetString(szCommand, sizeof(szCommand), IDS_ENCRYPTNOW_MENU);
4b05cb ¤   ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
6d7576 ¤   ¤   _cmdidEncryptNow = *pcmdidBase;
3fd176 ¤   ¤   ++(*pcmdidBase);
b41b52 ¤   ¤
d629af ¤   ¤   UIGetString(szCommand, sizeof(szCommand), IDS_SIGNNOW_MENU);
7c05cb ¤   ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
c22392 ¤   ¤   _cmdidSignNow = *pcmdidBase;
c2d176 ¤   ¤   ++(*pcmdidBase);
5b1b52 ¤   ¤
6cdb0b ¤   ¤   UIGetString(szCommand, sizeof(szCommand), IDS_ENCRYPTSIGN_MENU);
af05cb ¤   ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
1a56eb ¤   ¤   _cmdidEncryptSign = *pcmdidBase;
0dd176 ¤   ¤   ++(*pcmdidBase);
221b52 ¤   ¤
e11064 ¤   ¤   AppendMenu(_hmenuPGP, MF_SEPARATOR, 0, NULL);
609371 ¤   }
adaf5a
33d741 ¤   if (_context == EECONTEXT_READNOTEMESSAGE)
08c7a1 ¤   {
d1138a ¤   ¤   UIGetString(szCommand, sizeof(szCommand), IDS_DECRYPT_MENU);
9205cb ¤   ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
92c50c ¤   ¤   _cmdidDecrypt = *pcmdidBase;
823fa6 ·¤  ¤   ++(*pcmdidBase);
3caf5a
bf1064 ¤   ¤   AppendMenu(_hmenuPGP, MF_SEPARATOR, 0, NULL);
9b9371 ¤   }
5caf5a
971f56 ¤   UIGetString(szCommand, sizeof(szCommand), IDS_PGPKEYS_MENU);
e8b9d2 ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
f92946 ¤   _cmdidPgpKeys = *pcmdidBase;
cf60a7 ¤   ++(*pcmdidBase);
c8af5a
9ae9d1 ¤   UIGetString(szCommand, sizeof(szCommand), IDS_PGPPREFS_MENU);
fab9d2 ¤   AppendMenu(_hmenuPGP, MF_STRING, *pcmdidBase, szCommand);
5faf86 ¤   _cmdidPrefs = *pcmdidBase;
6460a7 ¤   ++(*pcmdidBase);
0167c5 ¤
210056 ¤   UIGetString(szCommand, sizeof(szCommand), IDS_PGPHELP_MENU);
a9d2e2 ¤   InsertMenu(hmenuHelpTopics, ulAfterExchange,·
62b14b ¤   ¤   ¤   ¤   MF_BYPOSITION | MF_STRING, *pcmdidBase, szCommand);
5d1648 ¤   _cmdidHelp = *pcmdidBase;
a660a7 ¤   ++(*pcmdidBase);
2567c5 ¤
df12b8 ¤   UIGetString(szCommand, sizeof(szCommand), IDS_ABOUT_MENU);
aa9e97 ¤   AppendMenu(hmenuHelp, MF_STRING, *pcmdidBase, szCommand);
a278b1 ¤   _cmdidAbout = *pcmdidBase;
d660a7 ¤   ++(*pcmdidBase);
ec67c5 ¤
b4c2c3 ¤   // Next, the toolbar
--e8cf 000c663a36940110308 Page 3 of Commands.cpp
e0af5a
9ed8a0 ¤   int tbindx;
746aa3 ¤   HWND hwndToolbar = NULL;
ee80c5 ¤   for (tbindx = ctbe-1; (int) tbindx > -1; --tbindx)
e7c7a1 ¤   {
157fe7 ¤   ¤   if (EETBID_STANDARD == lptbeArray[tbindx].tbid)
7e5b34 ¤   ¤   {
b3fe31 ¤   ¤   ¤   hwndToolbar = lptbeArray[tbindx].hwnd;
98af6e ¤   ¤   ¤   if (_context == EECONTEXT_SENDNOTEMESSAGE)
fcf776 ¤   ¤   ¤   {
0525d5 ¤   ¤   ¤   ¤   _hwndSendToolbar = hwndToolbar;
dabdda ¤   ¤   ¤   ¤   _itbbEncrypt = lptbeArray[tbindx].itbbBase++;
a8acab ¤   ¤   ¤   ¤   _itbbSign = lptbeArray[tbindx].itbbBase++;
71a3a6 ¤   ¤   ¤   }
cbaf5a
ec1ed4 ¤   ¤   ¤   if (_context == EECONTEXT_READNOTEMESSAGE)
99f776 ¤   ¤   ¤   {
d84924 ¤   ¤   ¤   ¤   _hwndReadToolbar = hwndToolbar;
6f4093 ¤   ¤   ¤   ¤   _itbbDecrypt = lptbeArray[tbindx].itbbBase++;
5ca3a6 ¤   ¤   ¤   }
ce87c7 ¤   ¤   ¤
5fc221 ¤   ¤   ¤   _itbbPgpKeys = lptbeArray[tbindx].itbbBase++;
83cdcb ¤   ¤   ¤   break;
220fe4 ¤   ¤   }
949371 ¤   }
63af5a
042d06 ¤   if (hwndToolbar)
b1c7a1 ¤   {
be8083 ¤   ¤   TBADDBITMAP tbab;
17af5a
6936d1 ¤   ¤   tbab.hInst = UIGetInstance();
1dbe49 ¤   ¤   if (_context == EECONTEXT_SENDNOTEMESSAGE)
365b34 ¤   ¤   {
e7e368 ¤   ¤   ¤   if (_fOutlook98)
b18edf ¤   ¤   ¤   ¤   tbab.nID = IDB_T_ENCRYPT;
38bb8c ¤   ¤   ¤   else
fa7748 ¤   ¤   ¤   ¤   tbab.nID = IDB_ENCRYPT;
47795b ¤   ¤   ¤   _itbmEncrypt = SendMessage(hwndToolbar, TB_ADDBITMAP, 1,·
a8f177 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&tbab);
8faf5a
84e368 ¤   ¤   ¤   if (_fOutlook98)
269003 ¤   ¤   ¤   ¤   tbab.nID = IDB_T_SIGN;
73bb8c ¤   ¤   ¤   else
6f5f61 ¤   ¤   ¤   ¤   tbab.nID = IDB_SIGN;
09a548 ¤   ¤   ¤   _itbmSign = SendMessage(hwndToolbar, TB_ADDBITMAP, 1,·
cbf177 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&tbab);
610fe4 ¤   ¤   }
28af5a
2e0ff3 ¤   ¤   if (_context == EECONTEXT_READNOTEMESSAGE)
a65b34 ¤   ¤   {
f0e368 ¤   ¤   ¤   if (_fOutlook98)
4a644e ¤   ¤   ¤   ¤   tbab.nID = IDB_T_DECRYPT;
98bb8c ¤   ¤   ¤   else
2e9dd9 ¤   ¤   ¤   ¤   tbab.nID = IDB_DECRYPT;
35da3d ¤   ¤   ¤   _itbmDecrypt = SendMessage(hwndToolbar, TB_ADDBITMAP, 1,·
4df177 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&tbab);
240fe4 ¤   ¤   }
e5af5a
b2d735 ¤   ¤   if (_fOutlook98)
615fcc ¤   ¤   ¤   tbab.nID = IDB_T_PGPKEYS;
040e1d ¤   ¤   else
f55fe0 ¤   ¤   ¤   tbab.nID = IDB_PGPKEYS;
687282 ¤   ¤   _itbmPgpKeys = SendMessage(hwndToolbar, TB_ADDBITMAP, 1,·
a07911 ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM)&tbab);
f5af5a
5c9371 ¤   }
09af5a
65ad56 ¤   return S_OK;
93efe6 }
abaf5a
8daf5a
c6c20b STDMETHODIMP CExtImpl::QueryButtonInfo (ULONG tbid, UINT itbb,·
--64dc 0002e2f3e9340110308 Page 4 of Commands.cpp
8ccba2 ····························LPTBBUTTON ptbb, LPTSTR lpsz, UINT cch,·
d4adde ····························ULONG ulFlags)
97bb36 {
ba67f4 ¤   if ((EECONTEXT_READNOTEMESSAGE != _context) &&
b8e686 ¤   ¤   (EECONTEXT_SENDNOTEMESSAGE != _context) &&
2cb852 ¤   ¤   (EECONTEXT_VIEWER != _context))
3d93bf ¤   ¤   return S_FALSE;
b2af5a
2608c5 ¤   HRESULT hr = S_FALSE;
caaf5a
f63ec5 ¤   if ((itbb == _itbbEncrypt) && (_context == EECONTEXT_SENDNOTEMESSAGE))
07c7a1 ¤   {
147b62 ¤   ¤   ptbb->iBitmap = _itbmEncrypt;
917d17 ¤   ¤   ptbb->idCommand = _cmdidEncrypt;
629a51 ¤   ¤   ptbb->fsState = TBSTATE_ENABLED;
f3d60c ¤   ¤   ptbb->fsStyle = TBSTYLE_CHECK;
ca871a ¤   ¤   ptbb->dwData = 0;
0d2231 ¤   ¤   ptbb->iString = -1;
bfaf5a
4ba2e0 ¤   ¤   UIGetString(lpsz, cch, IDS_ENCRYPT_TOOLTIP);
cb814d ¤   ¤   hr = S_OK;
989371 ¤   }
36af5a
6f9156 ¤   if ((itbb == _itbbSign) && (_context == EECONTEXT_SENDNOTEMESSAGE))
efc7a1 ¤   {
e2fd3c ¤   ¤   ptbb->iBitmap = _itbmSign;
a00fe4 ¤   ¤   ptbb->idCommand = _cmdidSign;
f29a51 ¤   ¤   ptbb->fsState = TBSTATE_ENABLED;
dad60c ¤   ¤   ptbb->fsStyle = TBSTYLE_CHECK;
e6871a ¤   ¤   ptbb->dwData = 0;
ec2231 ¤   ¤   ptbb->iString = -1;
e0af5a
163469 ¤   ¤   UIGetString(lpsz, cch, IDS_SIGN_TOOLTIP);
5e814d ¤   ¤   hr = S_OK;
d29371 ¤   }
50af5a
dc3c30 ¤   if (itbb == _itbbPgpKeys)
e5c7a1 ¤   {
c613ff ¤   ¤   ptbb->iBitmap = _itbmPgpKeys;
18158a ¤   ¤   ptbb->idCommand = _cmdidPgpKeys;
3b9a51 ¤   ¤   ptbb->fsState = TBSTATE_ENABLED;
13d92d ¤   ¤   ptbb->fsStyle = TBSTYLE_BUTTON;
33871a ¤   ¤   ptbb->dwData = 0;
862231 ¤   ¤   ptbb->iString = -1;
f4af5a
ce2715 ¤   ¤   UIGetString(lpsz, cch, IDS_PGPKEYS_TOOLTIP);
b3814d ¤   ¤   hr = S_OK;
f79371 ¤   }
67af5a
6287c3 ¤   if ((itbb == _itbbDecrypt) && (_context == EECONTEXT_READNOTEMESSAGE))
b2c7a1 ¤   {
c091f3 ¤   ¤   ptbb->iBitmap = _itbmDecrypt;
249786 ¤   ¤   ptbb->idCommand = _cmdidDecrypt;
da9a51 ¤   ¤   ptbb->fsState = TBSTATE_ENABLED;
7ed92d ¤   ¤   ptbb->fsStyle = TBSTYLE_BUTTON;
c2871a ¤   ¤   ptbb->dwData = 0;
622231 ¤   ¤   ptbb->iString = -1;
daaf5a
03ea6e ¤   ¤   UIGetString(lpsz, cch, IDS_DECRYPT_TOOLTIP);
a2814d ¤   ¤   hr = S_OK;
4a9371 ¤   }
a4af5a
44af5a
dd776d ¤   return hr;
a5efe6 }
46af5a
48af5a
babf73 STDMETHODIMP CExtImpl::ResetToolbar(ULONG tbid, ULONG ulFlags)
12bb36 {
ec7d5d ¤   // To implement this method,
20ec13 ¤   // the extension must cache the results of a prior call
2e4f1a ¤   // to IExchExtCallback::GetToolbar.
--0fe4 0002fa4209840110308 Page 5 of Commands.cpp
e0af5a
99e94b ¤   return S_FALSE;
67efe6 }
d6af5a
a9af5a
71db5d STDMETHODIMP CExtImpl::QueryHelpText(UINT cmdid, ULONG ulFlags,·
42a6e0 ······································LPTSTR psz, UINT cch)
2dbb36 {
1067f4 ¤   if ((EECONTEXT_READNOTEMESSAGE != _context) &&
a3e686 ¤   ¤   (EECONTEXT_SENDNOTEMESSAGE != _context) &&
15b852 ¤   ¤   (EECONTEXT_VIEWER != _context))
4c93bf ¤   ¤   return S_FALSE;
3eaf5a
1f1c2a ¤   if (ulFlags == EECQHT_STATUS)
0bc7a1 ¤   {
064c35 ¤   ¤   if ((cmdid == _cmdidEncrypt) &&·
d1e4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
7a5b34 ¤   ¤   {
206120 ¤   ¤   ¤   UIGetString(psz, cch, IDS_ENCRYPT_STATUS);
795d0c ¤   ¤   ¤   return S_OK;
8a0fe4 ¤   ¤   }
a5af5a
aaca3b ¤   ¤   if ((cmdid == _cmdidSign) &&·
aee4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
e35b34 ¤   ¤   {
412a71 ¤   ¤   ¤   UIGetString(psz, cch, IDS_SIGN_STATUS);
fd5d0c ¤   ¤   ¤   return S_OK;
090fe4 ¤   ¤   }
c0af5a
90b7cd ¤   ¤   if ((cmdid == _cmdidEncryptNow) &&·
28e4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
7c5b34 ¤   ¤   {
2f0369 ¤   ¤   ¤   UIGetString(psz, cch, IDS_ENCRYPTNOW_STATUS);
5e5d0c ¤   ¤   ¤   return S_OK;
d50fe4 ¤   ¤   }
41af5a
b17fca ¤   ¤   if ((cmdid == _cmdidSignNow) &&·
70e4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
225b34 ¤   ¤   {
1a7898 ¤   ¤   ¤   UIGetString(psz, cch, IDS_SIGNNOW_STATUS);
165d0c ¤   ¤   ¤   return S_OK;
cc0fe4 ¤   ¤   }
69af5a
4a2de5 ¤   ¤   if ((cmdid == _cmdidEncryptSign) &&·
64e4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
e65b34 ¤   ¤   {
9356b0 ¤   ¤   ¤   UIGetString(psz, cch, IDS_ENCRYPTSIGN_STATUS);
065d0c ¤   ¤   ¤   return S_OK;
870fe4 ¤   ¤   }
cdaf5a
afc49a ¤   ¤   if ((cmdid == _cmdidDecrypt) &&·
2ffea4 ¤   ¤   ¤   (_context == EECONTEXT_READNOTEMESSAGE))
385b34 ¤   ¤   {
93bbca ¤   ¤   ¤   UIGetString(psz, cch, IDS_DECRYPT_STATUS);
335d0c ¤   ¤   ¤   return S_OK;
6b0fe4 ¤   ¤   }
c3af5a
41e94a ¤   ¤   if (cmdid == _cmdidPgpKeys)
725b34 ¤   ¤   {
b294b1 ¤   ¤   ¤   UIGetString(psz, cch, IDS_PGPKEYS_STATUS);
9d5d0c ¤   ¤   ¤   return S_OK;
ba0fe4 ¤   ¤   }
32af5a
83014e ¤   ¤   if (cmdid == _cmdidPrefs)
e05b34 ¤   ¤   {
900f57 ¤   ¤   ¤   UIGetString(psz, cch, IDS_PGPPREFS_STATUS);
975d0c ¤   ¤   ¤   return S_OK;
6a0fe4 ¤   ¤   }
33af5a
81365e ¤   ¤   if (cmdid == _cmdidHelp)
f45b34 ¤   ¤   {
2f7cc7 ¤   ¤   ¤   UIGetString(psz, cch, IDS_PGPHELP_STATUS);
--7b0a 00074df80b640110308 Page 6 of Commands.cpp
425d0c ¤   ¤   ¤   return S_OK;
190fe4 ¤   ¤   }
76af5a
d84f23 ¤   ¤   if (cmdid == _cmdidAbout)
dd5b34 ¤   ¤   {
c8fb13 ¤   ¤   ¤   UIGetString(psz, cch, IDS_ABOUT_STATUS);
9f5d0c ¤   ¤   ¤   return S_OK;
8e0fe4 ¤   ¤   }
49af5a
129371 ¤   }
cc2b99 ¤   else if (ulFlags == EECQHT_TOOLTIP)
aac7a1 ¤   {
8c4c35 ¤   ¤   if ((cmdid == _cmdidEncrypt) &&·
f6e4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
3e5b34 ¤   ¤   {
26870f ¤   ¤   ¤   UIGetString(psz, cch, IDS_ENCRYPT_TOOLTIP);
855d0c ¤   ¤   ¤   return S_OK;
020fe4 ¤   ¤   }
f1af5a
83ca3b ¤   ¤   if ((cmdid == _cmdidSign) &&·
2de4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
ae5b34 ¤   ¤   {
98c448 ¤   ¤   ¤   UIGetString(psz, cch, IDS_SIGN_TOOLTIP);
8e5d0c ¤   ¤   ¤   return S_OK;
ea0fe4 ¤   ¤   }
0baf5a
45b7cd ¤   ¤   if ((cmdid == _cmdidEncryptNow) &&·
37e4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
745b34 ¤   ¤   {
df58a8 ¤   ¤   ¤   UIGetString(psz, cch, IDS_ENCRYPTNOW_TOOLTIP);
205d0c ¤   ¤   ¤   return S_OK;
370fe4 ¤   ¤   }
feaf5a
9d7fca ¤   ¤   if ((cmdid == _cmdidSignNow) &&·
7be4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
1d5b34 ¤   ¤   {
18bed5 ¤   ¤   ¤   UIGetString(psz, cch, IDS_SIGNNOW_TOOLTIP);
d75d0c ¤   ¤   ¤   return S_OK;
f30fe4 ¤   ¤   }
f8af5a
192de5 ¤   ¤   if ((cmdid == _cmdidEncryptSign) &&·
c2e4c4 ¤   ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
6a5b34 ¤   ¤   {
4113b1 ¤   ¤   ¤   UIGetString(psz, cch, IDS_ENCRYPTSIGN_TOOLTIP);
755d0c ¤   ¤   ¤   return S_OK;
a60fe4 ¤   ¤   }
a9af5a
31c49a ¤   ¤   if ((cmdid == _cmdidDecrypt) &&·
76fea4 ¤   ¤   ¤   (_context == EECONTEXT_READNOTEMESSAGE))
ea5b34 ¤   ¤   {
e1cf81 ¤   ¤   ¤   UIGetString(psz, cch, IDS_DECRYPT_TOOLTIP);
ef5d0c ¤   ¤   ¤   return S_OK;
7d0fe4 ¤   ¤   }
7faf5a
27e94a ¤   ¤   if (cmdid == _cmdidPgpKeys)
3c5b34 ¤   ¤   {
9d02fa ¤   ¤   ¤   UIGetString(psz, cch, IDS_PGPKEYS_TOOLTIP);
a85d0c ¤   ¤   ¤   return S_OK;
3d0fe4 ¤   ¤   }
e09371 ¤   }
7faf5a
efe94b ¤   return S_FALSE;
acefe6 }
0baf5a
6caf5a
b16d96 STDMETHODIMP CExtImpl::Help(IExchExtCallback* pmecb, UINT cmdid)
83bb36 {
48e94b ¤   return S_FALSE;
14efe6 }
f7af5a
78af5a
743a67 STDMETHODIMP_(VOID) CExtImpl::InitMenu(IExchExtCallback* pmecb)
--dfe1 000f79b03ca40110308 Page 7 of Commands.cpp
2cbb36 {
5e67ee ¤   FindStruct fs;
ff805b ¤   HWND hwndMain;
373e7b ¤   HWND hwndToolbar;
7b094a ¤   HRESULT hr;
9aaf5a
e067f4 ¤   if ((EECONTEXT_READNOTEMESSAGE != _context) &&
3eef94 ¤   ¤   (EECONTEXT_SENDNOTEMESSAGE != _context))
8599bf ¤   ¤   return;
f9af5a
7d0b65 ¤   pmecb->GetWindow(&hwndMain);
6d8000 ¤   _hwndMessage = FindMessageWindow(pmecb, &fs);
39af5a
409528 ¤   hr = pmecb->GetToolbar(EETBID_STANDARD, &hwndToolbar);
ade54b ¤   if (hr != S_OK)
a299bf ¤   ¤   return;
73af5a
51d8c5 ¤   if (fs.bInternetExplorer || fs.bMicrosoftWord)
90c7a1 ¤   {
65be49 ¤   ¤   if (_context == EECONTEXT_SENDNOTEMESSAGE)
6d5b34 ¤   ¤   {
157afe ¤   ¤   ¤   DeleteMenu(_hmenuPGP, _cmdidEncryptNow, MF_BYCOMMAND);
90d989 ¤   ¤   ¤   DeleteMenu(_hmenuPGP, _cmdidSignNow, MF_BYCOMMAND);
49a25d ¤   ¤   ¤   DeleteMenu(_hmenuPGP, _cmdidEncryptSign, MF_BYCOMMAND);
a78530 ¤   ¤   ¤   DrawMenuBar(hwndMain);
450fe4 ¤   ¤   }
cbaf5a
060ff3 ¤   ¤   if (_context == EECONTEXT_READNOTEMESSAGE)
b45b34 ¤   ¤   {
8fa498 ¤   ¤   ¤   DeleteMenu(_hmenuPGP, _cmdidDecrypt, MF_BYCOMMAND);
708530 ¤   ¤   ¤   DrawMenuBar(hwndMain);
e7af5a
c2f5f6 ¤   ¤   ¤   SendMessage(hwndToolbar, TB_ENABLEBUTTON,·
f9d538 ¤   ¤   ¤   ¤   _cmdidDecrypt, MAKELONG(FALSE, 0));
d70fe4 ¤   ¤   }
dd9371 ¤   }
cc0e24 ¤   else
d60ff3 ¤   ¤   if (_context == EECONTEXT_READNOTEMESSAGE)
d15b34 ¤   ¤   {
e043e7 ¤   ¤   ¤   char szCommand[256];
2b60e0 ¤   ¤   ¤   char szMenu[256];
d2bbd1 ¤   ¤   ¤   MENUITEMINFO miiMenu;
76af5a
5f193a ¤   ¤   ¤   miiMenu.cbSize = sizeof(MENUITEMINFO);
243bc8 ¤   ¤   ¤   miiMenu.fMask = MIIM_TYPE;
5baef5 ¤   ¤   ¤   miiMenu.dwTypeData = szMenu;
6e0cc7 ¤   ¤   ¤   miiMenu.cch = 255;
2caf5a
9514fc ¤   ¤   ¤   UIGetString(szCommand, sizeof(szCommand), IDS_DECRYPT_MENU);
d7ff08 ¤   ¤   ¤   GetMenuItemInfo(_hmenuPGP, 0, TRUE, &miiMenu);
53fba4 ¤   ¤   ¤   if (strcmp(szCommand, szMenu))
e2f776 ¤   ¤   ¤   {
7f2b54 ¤   ¤   ¤   ¤   strcpy(szMenu, szCommand);
788ee6 ¤   ¤   ¤   ¤   SetMenuItemInfo(_hmenuPGP, 0, TRUE, &miiMenu);
b2c4c3 ¤   ¤   ¤   ¤   DrawMenuBar(hwndMain);
66a3a6 ¤   ¤   ¤   }
7caf5a
a9f5f6 ¤   ¤   ¤   SendMessage(hwndToolbar, TB_ENABLEBUTTON,·
9d863e ¤   ¤   ¤   ¤   _cmdidDecrypt, MAKELONG(TRUE, 0));
0f0fe4 ¤   ¤   }
d4af5a
87af5a
5ea35c ¤   if (!_fInitMenuOnce)
8bc7a1 ¤   {
5b7ff8 ¤   ¤   // Only set encrypt and sign flags once.
7e1b52 ¤   ¤
7a85f0 ¤   ¤   _fInitMenuOnce = TRUE;
a71b52 ¤   ¤
5499ad ¤   ¤   _bEncrypt = ByDefaultEncrypt(_memoryMgr);
78e366 ¤   ¤   _bSign = ByDefaultSign(_memoryMgr);
f99371 ¤   }
f7af5a
--7241 000240001bf40110308 Page 8 of Commands.cpp
6280a0 ¤   // Now to the real menu business
edaf5a
5f66fb ¤   if (_context == EECONTEXT_SENDNOTEMESSAGE)
6bc7a1 ¤   {
ea90a1 ¤   ¤   HMENU hmenu;
5c93ed ¤   ¤   MENUITEMINFO miiEncrypt;
3cd5ab ¤   ¤   MENUITEMINFO miiSign;
371b52 ¤   ¤
eb5c9d ¤   ¤   hr = pmecb->GetMenu(&hmenu);
bd658d ¤   ¤   if (FAILED(hr))
cd0ecc ¤   ¤   ¤   return;
a5af5a
2c20a6 ¤   ¤   miiEncrypt.cbSize = sizeof(MENUITEMINFO);
8e9740 ¤   ¤   miiEncrypt.fMask = MIIM_STATE | MIIM_CHECKMARKS;
6cd51c ¤   ¤   GetMenuItemInfo(hmenu, _cmdidEncrypt, FALSE, &miiEncrypt);
557f65 ¤   ¤   if (_bEncrypt)
615b34 ¤   ¤   {
80dc1e ¤   ¤   ¤   miiEncrypt.fState = MFS_CHECKED;
f3d238 ¤   ¤   ¤   miiEncrypt.hbmpChecked = NULL;
0a9371 ¤   ¤   ¤   SendMessage(hwndToolbar, TB_CHECKBUTTON,·
8d65aa ¤   ¤   ¤   ¤   _cmdidEncrypt, MAKELONG(TRUE, 0));
940fe4 ¤   ¤   }
390e1d ¤   ¤   else
b45b34 ¤   ¤   {
fc97ee ¤   ¤   ¤   miiEncrypt.fState = MFS_UNCHECKED;
7bf6a2 ¤   ¤   ¤   miiEncrypt.hbmpUnchecked = NULL;
f49371 ¤   ¤   ¤   SendMessage(hwndToolbar, TB_CHECKBUTTON,·
480776 ¤   ¤   ¤   ¤   _cmdidEncrypt, MAKELONG(FALSE, 0));
6f0fe4 ¤   ¤   }
0dd1dd ¤   ¤   SetMenuItemInfo(hmenu, _cmdidEncrypt, FALSE, &miiEncrypt);
feaf5a
1489be ¤   ¤   miiSign.cbSize = sizeof(MENUITEMINFO);
8c59d4 ¤   ¤   miiSign.fMask = MIIM_STATE | MIIM_CHECKMARKS;
02e8b7 ¤   ¤   GetMenuItemInfo(hmenu, _cmdidSign, FALSE, &miiSign);
4ca038 ¤   ¤   if (_bSign)
bf5b34 ¤   ¤   {
59dbf1 ¤   ¤   ¤   miiSign.fState = MFS_CHECKED;
5920f9 ¤   ¤   ¤   miiSign.hbmpChecked = NULL;
799371 ¤   ¤   ¤   SendMessage(hwndToolbar, TB_CHECKBUTTON,·
975151 ¤   ¤   ¤   ¤   _cmdidSign, MAKELONG(TRUE, 0));
f00fe4 ¤   ¤   }
860e1d ¤   ¤   else
e55b34 ¤   ¤   {
f48900 ¤   ¤   ¤   miiSign.fState = MFS_UNCHECKED;
60f14d ¤   ¤   ¤   miiSign.hbmpUnchecked = NULL;
c69371 ¤   ¤   ¤   SendMessage(hwndToolbar, TB_CHECKBUTTON,·
714e1e ¤   ¤   ¤   ¤   _cmdidSign, MAKELONG(FALSE, 0));
4d0fe4 ¤   ¤   }
b3c7f4 ¤   ¤   SetMenuItemInfo(hmenu, _cmdidSign, FALSE, &miiSign);
579371 ¤   }
04efe6 }
c0af5a
f8af5a
4039ca STDMETHODIMP CExtImpl::DoCommand(IExchExtCallback* pmecb, UINT cmdid)
8bbb36 {
02805b ¤   HWND hwndMain;
c267ee ¤   FindStruct fs;
c6414d ¤   BOOL FYEO;
75af5a
2267f4 ¤   if ((EECONTEXT_READNOTEMESSAGE != _context) &&
a2e686 ¤   ¤   (EECONTEXT_SENDNOTEMESSAGE != _context) &&
34b852 ¤   ¤   (EECONTEXT_VIEWER != _context))
2293bf ¤   ¤   return S_FALSE;
77af5a
55c27d ¤   if ((cmdid == _cmdidEncrypt) && (_context == EECONTEXT_SENDNOTEMESSAGE))
cac7a1 ¤   {
447bbe ¤   ¤   _bEncrypt = !_bEncrypt;
d9edf8 ¤   ¤   InitMenu(pmecb);
00ecdd ¤   ¤   return S_OK;
f59371 ¤   }
8faf5a
245fba ¤   if ((cmdid == _cmdidSign) && (_context == EECONTEXT_SENDNOTEMESSAGE))
--c925 0005a3e164d40110308 Page 9 of Commands.cpp
f7c7a1 ¤   {
d053fa ¤   ¤   _bSign = !_bSign;
d2edf8 ¤   ¤   InitMenu(pmecb);
8decdd ¤   ¤   return S_OK;
db9371 ¤   }
34af5a
2f0b65 ¤   pmecb->GetWindow(&hwndMain);
70af5a
184d4d ¤   if ((_context == EECONTEXT_SENDNOTEMESSAGE) ||·
6dadbf ¤   ¤   (_context == EECONTEXT_READNOTEMESSAGE))
b62e01 ¤   ¤   _hwndMessage = FindMessageWindow(pmecb, &fs);
a3af5a
ad02dc ¤   if (((cmdid == _cmdidEncryptNow) || (cmdid == _cmdidSignNow) ||·
f23e0c ¤   ¤   (cmdid == _cmdidEncryptSign)) &&·
3fb7df ¤   ¤   (_context == EECONTEXT_SENDNOTEMESSAGE))
b3c7a1 ¤   {
5bf15d ¤   ¤   BOOL bEncrypt;
b2ec7c ¤   ¤   BOOL bSign;
681b52 ¤   ¤
6c3602 ¤   ¤   bEncrypt =¤ (cmdid == _cmdidEncryptNow) ||·
a09479 ¤   ¤   ¤   ¤   ¤   (cmdid == _cmdidEncryptSign);
fbaf5a
b0454f ¤   ¤   bSign = (cmdid == _cmdidSignNow) ||·
0e132c ¤   ¤   ¤   ¤   (cmdid == _cmdidEncryptSign);·
92af5a
66fd4c ¤   ¤   if (_bHaveAttachments)
d75627 ¤   ¤   ¤   if (!UIWarnUser(hwndMain, IDS_Q_ATTACHMENT, "Attachment"))
f16951 ¤   ¤   ¤   ¤   return S_OK;
dcaf5a
243520 ¤   ¤   if (_hwndMessage)
d75b34 ¤   ¤   {
90e67c ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds;
88842a ¤   ¤   ¤   PGPKeySetRef newKeySet = NULL;
a6fd6f ¤   ¤   ¤   PGPError err;
daaf5a
3cd2c8 ¤   ¤   ¤   prds = (RECIPIENTDIALOGSTRUCT *)·
5ce941 ¤   ¤   ¤   ¤   ¤   calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);
4aaf5a
3d8f47 ¤   ¤   ¤   err = PGPsdkLoadDefaultPrefs(_pgpContext);
340dfb ¤   ¤   ¤   if (IsPGPError(err))
8df776 ¤   ¤   ¤   {
98cc20 ¤   ¤   ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, NULL, err);
aec884 ¤   ¤   ¤   ¤   return S_FALSE;
5ca3a6 ¤   ¤   ¤   }
6aaf5a
b05bc0 ¤   ¤   ¤   err = PGPOpenDefaultKeyRings(_pgpContext, (PGPKeyRingOpenFlags)0,·
a6c210 ¤   ¤   ¤   ¤   ¤   &(prds->OriginalKeySetRef));
11af5a
a00dfb ¤   ¤   ¤   if (IsPGPError(err))
1ff776 ¤   ¤   ¤   {
c3cc20 ¤   ¤   ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, NULL, err);
98c884 ¤   ¤   ¤   ¤   return S_FALSE;
a2a3a6 ¤   ¤   ¤   }
efaf5a
1d15dd ¤   ¤   ¤   PGPNewKeySet(_pgpContext, &newKeySet);
68beb4 ¤   ¤   ¤   PGPAddKeys(prds->OriginalKeySetRef, newKeySet);
b6bb2e ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
53af5a
8de35b ¤   ¤   ¤   prds->OriginalKeySetRef = newKeySet;
93af5a
57d9f5 ¤   ¤   ¤   if (EncryptSignMessageWindow(hwndMain, pmecb, bEncrypt, bSign,·
84902c ¤   ¤   ¤   ¤   prds))
c4f776 ¤   ¤   ¤   {
2fe862 ¤   ¤   ¤   ¤   _bEncrypt = _bEncrypt && !bEncrypt;
8b7374 ¤   ¤   ¤   ¤   _bSign = _bSign && !bSign;
9562f3 ¤   ¤   ¤   ¤   InitMenu(pmecb);
54a3a6 ¤   ¤   ¤   }
49af5a
dbd65e ¤   ¤   ¤   FreeRecipients(prds);
4967c5 ¤
134f60 ¤   ¤   ¤   if (IsntNull(prds->OriginalKeySetRef))
5af776 ¤   ¤   ¤   {
--0a41 000190aeebd40110308 Page 10 of Commands.cpp
e3ee82 ¤   ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
5e9987 ¤   ¤   ¤   ¤   prds->OriginalKeySetRef = NULL;
eaa3a6 ¤   ¤   ¤   }
3baf5a
f1adfc ¤   ¤   ¤   free(prds);
f80fe4 ¤   ¤   }
63af5a
cfecdd ¤   ¤   return S_OK;
bc9371 ¤   }
bdaf5a
ff7b7b ¤   if ((cmdid == _cmdidDecrypt) && (_context == EECONTEXT_READNOTEMESSAGE))
48c7a1 ¤   {
fe3520 ¤   ¤   if (_hwndMessage)
375b34 ¤   ¤   {
376afd ¤   ¤   ¤   char *szInput;
9919ce ¤   ¤   ¤   char *szOutput = NULL;
f651ad ¤   ¤   ¤   long lLength;
d8a700 ¤   ¤   ¤   UINT nOutLength;
b1cdcd ¤   ¤   ¤   BOOL bSelectedText = FALSE;
383c68 ¤   ¤   ¤   CHARRANGE chRange = {0,0};
ac103c ¤   ¤   ¤   PGPError nError = kPGPError_NoErr;
57a3b0 ¤   ¤   ¤   char szName[256];
a03bce ¤   ¤   ¤   char szFile[256];
d7af5a
7fdb33 ¤   ¤   ¤   UIGetString(szName, sizeof(szName), IDS_LOGNAME);
ccbae4 ¤   ¤   ¤   UIGetString(szFile, sizeof(szFile), IDS_DLL);
baaf5a
936baf ¤   ¤   ¤   // Determine if the user selected a particular piece of text
f39bd2 ¤   ¤   ¤   SendMessage(_hwndMessage, EM_EXGETSEL,·
d31d6e ¤   ¤   ¤   ¤   (WPARAM)0, (LPARAM) &chRange);
fdd779 ¤   ¤   ¤   bSelectedText = chRange.cpMax - chRange.cpMin;
db87c7 ¤   ¤   ¤
820ab7 ¤   ¤   ¤   szInput = GetRichEditContents(_hwndMessage, &lLength,·
adac50 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE, bSelectedText);
1306b8 ¤   ¤   ¤   if (!szInput)
9b6951 ¤   ¤   ¤   ¤   return S_OK;
5daf5a
ef2bef ¤   ¤   ¤   chRange.cpMin = 0;
a3f96e ¤   ¤   ¤   chRange.cpMax = lLength;
beaf5a
741354 ¤   ¤   ¤   while (!isgraph(szInput[chRange.cpMax-3]))
64bf2f ¤   ¤   ¤   ¤   chRange.cpMax--;
33af5a
940d2d ¤   ¤   ¤   if (_fOutlook)
8ff776 ¤   ¤   ¤   {
c499e6 ¤   ¤   ¤   ¤   char *szCR;
e5eb80 ¤   ¤   ¤   ¤   int nNumCR=0;
6fae30 ¤   ¤   ¤   ¤   ¤
418030 ¤   ¤   ¤   ¤   szCR = strchr(szInput, '\r');
c4e7a7 ¤   ¤   ¤   ¤   while (szCR && (szCR < (szInput+lLength)))
3f72c3 ¤   ¤   ¤   ¤   {
577c10 ¤   ¤   ¤   ¤   ¤   nNumCR++;
fb1c16 ¤   ¤   ¤   ¤   ¤   szCR = strchr(szCR+1, '\r');
202613 ¤   ¤   ¤   ¤   }
93af5a
9e69ee ¤   ¤   ¤   ¤   chRange.cpMax -= nNumCR;
dba3a6 ¤   ¤   ¤   }
01af5a
28d0f8 ¤   ¤   ¤   SendMessage(_hwndMessage, EM_EXSETSEL, (WPARAM)0,·
4868d5 ¤   ¤   ¤   ¤   (LPARAM) &chRange);
03af5a
0b73ec ¤   ¤   ¤   nError = DecryptVerifyBuffer(UIGetInstance(), hwndMain,·
9e7fdb ¤   ¤   ¤   ¤   ¤   ¤   _pgpContext, _tlsContext,
8b40b0 ¤   ¤   ¤   ¤   ¤   ¤   szName, szFile, szInput, lLength,
f4363b ¤   ¤   ¤   ¤   ¤   ¤   FALSE, (void **) &szOutput, &nOutLength, &FYEO);
90af5a
396400 ¤   ¤   ¤   if (IsntPGPError(nError))
27f776 ¤   ¤   ¤   {
92c2f6 ¤   ¤   ¤   ¤   if ((nOutLength > 0) && (szOutput != NULL))
0872c3 ¤   ¤   ¤   ¤   {
167010 ¤   ¤   ¤   ¤   ¤   if(FYEO)
194859 ¤   ¤   ¤   ¤   ¤   {
--e1f9 0007722361640110308 Page 11 of Commands.cpp
e126e4 ¤   ¤   ¤   ¤   ¤   ¤   TempestViewer((void *)_pgpContext,hwndMain,
7b0bbf ¤   ¤   ¤   ¤   ¤   ¤   ¤   szOutput,nOutLength);
701c89 ¤   ¤   ¤   ¤   ¤   }
5d4bd6 ¤   ¤   ¤   ¤   ¤   else
034859 ¤   ¤   ¤   ¤   ¤   {
17e52b ¤   ¤   ¤   ¤   ¤   ¤   if ((nOutLength != (UINT) lLength) &&
09fec8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (nOutLength != (UINT) (lLength+1)))
428fec ¤   ¤   ¤   ¤   ¤   ¤   {
2804d6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetRichEditContents(_hwndMessage, szOutput,·
81cd62 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE, TRUE);
4cdb3c ¤   ¤   ¤   ¤   ¤   ¤   }
3f1c89 ¤   ¤   ¤   ¤   ¤   }
c7af5a
fcb489 ¤   ¤   ¤   ¤   ¤   PGPFreeData(szOutput);
fb2613 ¤   ¤   ¤   ¤   }
e5fa07 ¤   ¤   ¤   ¤   else
03d649 ¤   ¤   ¤   ¤   ¤   UIDisplayStringID(_hwndMessage, IDS_E_NOPGP);
8aa3a6 ¤   ¤   ¤   }
1887c7 ¤   ¤   ¤
bd2bef ¤   ¤   ¤   chRange.cpMin = 0;
f8eb57 ¤   ¤   ¤   chRange.cpMax = 0;
ed5ba3 ¤   ¤   ¤   SendMessage(_hwndMessage, EM_EXSETSEL,·
7e1d6e ¤   ¤   ¤   ¤   (WPARAM)0, (LPARAM) &chRange);
1150dc ¤   ¤   ¤   HeapFree(GetProcessHeap (), 0, szInput);
c70fe4 ¤   ¤   }
6eaf5a
0aecdd ¤   ¤   return S_OK;
389371 ¤   }
64af5a
0a62b6 ¤   if (cmdid == _cmdidPgpKeys)
7cc7a1 ¤   {
8c2a7f ¤   ¤   char szPath[MAX_PATH];
02eeb5 ¤   ¤   char szPGPkeys[MAX_PATH];
c7af5a
7448a8 ¤   ¤   PGPclGetPGPPath(szPath, MAX_PATH-1);
f971df ¤   ¤   UIGetString(szPGPkeys, sizeof(szPGPkeys), IDS_PGPKEYSEXE);
7952a0 ¤   ¤   strcat(szPath, szPGPkeys);
a6af5a
75e03d ¤   ¤   // run it...
6f6aee ¤   ¤   WinExec(szPath, SW_SHOW);
51ecdd ¤   ¤   return S_OK;
5e9371 ¤   }
efaf5a
af3646 ¤   if (cmdid == _cmdidPrefs)
cec7a1 ¤   {
f59d89 ¤   ¤   PGPclPreferences(_pgpContext, hwndMain, 0, NULL);
b2ecdd ¤   ¤   return S_OK;
869371 ¤   }
c2af5a
568d08 ¤   if (cmdid == _cmdidHelp)
8cc7a1 ¤   {
f4706a ¤   ¤   CHAR szHelpFile[MAX_PATH] = {0x00};
4e77b7 ¤   ¤   char szHelpName[256];
79af5a
e7a51c ¤   ¤   PGPclGetPGPPath(szHelpFile, MAX_PATH-1);
322aa6 ¤   ¤   UIGetString(szHelpName, sizeof(szHelpName), IDS_PGPHELP);
f0773d ¤   ¤   strcat(szHelpFile, szHelpName);
731b52 ¤   ¤
81b739 ¤   ¤   WinHelp(hwndMain, szHelpFile, HELP_FINDER, 0);
9decdd ¤   ¤   return S_OK;
9b9371 ¤   }
40af5a
64782b ¤   if (cmdid == _cmdidAbout)
a3c7a1 ¤   {
67fb6a ¤   ¤   PGPclHelpAbout(_pgpContext, hwndMain, NULL, NULL, NULL);
9fecdd ¤   ¤   return S_OK;
3e9371 ¤   }
2daf5a
b7e94b ¤   return S_FALSE;
69efe6 }
25af5a
77af5a
--9ddd 000cde868c240110308 Page 12 of Commands.cpp
825a44 BOOL CExtImpl::EncryptSignMessageWindow(HWND hwndMain,
1bdd29 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   IExchExtCallback *pmecb,
4944c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt,
005df4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bSign,
135e89 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds)
d4bb36 {
82b3f5 ¤   char *szInput;
488199 ¤   char *szOutput = NULL;
e0ac82 ¤   long lLength;
36228c ¤   UINT nOutLength;
bc8364 ¤   BOOL bSelectedText = FALSE;
729af8 ¤   BOOL bReturn = FALSE;
69f1e4 ¤   CHARRANGE chRange = {0,0};
7a6030 ¤   PGPOptionListRef signOptions = NULL;
c3ed51 ¤   char szName[256];
83752f ¤   char szFile[256];
288fe8 ¤   PGPError nError = kPGPError_NoErr;
f3af5a
bd6111 //¤ prds = (RECIPIENTDIALOGSTRUCT *)·
de2c3c //¤ ¤   ¤   calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);
8baf5a
41fa3e ¤   if ((prds == NULL) && bEncrypt)
f898aa ¤   ¤   return FALSE;
f3af5a
2a3a44 ¤   UIGetString(szName, sizeof(szName), IDS_LOGNAME);
511792 ¤   UIGetString(szFile, sizeof(szFile), IDS_DLL);
b5af5a
ebf932 ¤   if (bEncrypt)
2e4c5c ¤   ¤   nError = GetRecipients(pmecb, _pgpContext, _tlsContext, prds);
6587c7 ¤   ¤   ¤
440734 ¤   if (IsPGPError(nError))
92c7a1 ¤   {
bd7622 ¤   ¤   if (nError != kPGPError_UserAbort)
164587 ¤   ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, NULL, nError);
8f98aa ¤   ¤   return FALSE;
d59371 ¤   }
86af5a
8be69c ¤   // Determine if the user selected a particular piece of text
ca15c3 ¤   SendMessage(_hwndMessage, EM_EXGETSEL,·
9b82ba ¤   ¤   (WPARAM)0, (LPARAM) &chRange);
f8af5a
84c165 ¤   bSelectedText = chRange.cpMax - chRange.cpMin;
8d87c7 ¤   ¤   ¤
5287a9 ¤   szInput = GetRichEditContents(_hwndMessage, &lLength,·
4f32c2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE, bSelectedText);
67fb97 ¤   if (!szInput)
d698aa ¤   ¤   return FALSE;
93af5a
ff5d28 ¤   lLength = strlen(szInput);
4ce38f ¤   nError = EncryptSignBuffer(UIGetInstance(), hwndMain, _pgpContext,·
a8d556 ¤   ¤   ¤   ¤   _tlsContext, szName, szFile, szInput,·
8396ac ¤   ¤   ¤   ¤   lLength, prds, NULL, &signOptions, (void **) &szOutput,·
2219e8 ¤   ¤   ¤   ¤   &nOutLength, bEncrypt, bSign, FALSE);
75af5a
8ebc7b ¤   if (IsntPGPError(nError))
f0c7a1 ¤   {
4bccc1 ¤   ¤   SetRichEditContents(_hwndMessage, szOutput, FALSE,·
e92a84 ¤   ¤   ¤   bSelectedText);
847749 ¤   ¤   PGPFreeData(szOutput);
ab9545 ¤   ¤   bReturn = TRUE;
f39371 ¤   }
76af5a
adffc5 ¤   if (signOptions != NULL)
d0c7a1 ¤   {
973020 ¤   ¤   PGPFreeOptionList(signOptions);
fe8bbc ¤   ¤   signOptions = NULL;
149371 ¤   }
8aaf5a
16093d ¤   memset(szInput, 0, lLength);
1a515a ¤   HeapFree(GetProcessHeap (), 0, szInput);
e8af5a
cd32bc ¤   return bReturn;
--7d2a 001b56b6be140110308 Page 13 of Commands.cpp
7aefe6 }
46af5a
8eaf5a
59f1c4 HWND FindMessageWindow(IExchExtCallback* pmecb, FindStruct *fs)
43bb36 {
3e805b ¤   HWND hwndMain;
ec25f6 ¤   HWND hwndSearch = NULL;
e6e708 ¤   HWND hwndFound = NULL;
8a72a5 ¤   HWND hwndLast = NULL;
a3af5a
9135c4 ¤   fs->hwndFound = NULL;
3a51e6 ¤   fs->yMax = 0;
f09c43 ¤   fs->bInternetExplorer = FALSE;
444407 ¤   fs->bMicrosoftWord = FALSE;
09af5a
0c0b65 ¤   pmecb->GetWindow(&hwndMain);
0760a3 ¤   EnumChildWindows(hwndMain, (WNDENUMPROC) ReportChildren,·
298162 ¤   ¤   ¤   ¤   ¤   (LPARAM) fs);
2baf5a
4b92e0 ¤   hwndFound = fs->hwndFound;
52fdcc ¤   return hwndFound;
f4efe6 }
19af5a
23af5a
8ed11c BOOL CALLBACK ReportChildren(HWND hwnd, LPARAM lParam)
72bb36 {
7558a0 ¤   char szClassName[200];
0e2ac9 ¤   char szOldEditClass[256];
5586d8 ¤   char szNewEditClass[256];
9c0bf9 ¤   char szIEClass[256];
5766c8 ¤   char szWordClass[256];
133796 ¤   FindStruct *pfsRichEdit;
425bda ¤   RECT rc;
ecaf5a
5ba584 ¤   UIGetString(szOldEditClass, sizeof(szOldEditClass), IDS_OLDEDITCTRLCLASS);
ffaaaf ¤   UIGetString(szNewEditClass, sizeof(szNewEditClass), IDS_NEWEDITCTRLCLASS);
dba434 ¤   UIGetString(szIEClass, sizeof(szIEClass), IDS_IE40CLASS);
c8d90b ¤   UIGetString(szWordClass, sizeof(szWordClass), IDS_WORDCLASS);
6daf5a
e04a93 ¤   pfsRichEdit = (FindStruct *) lParam;
c9faf3 ¤   GetClassName(hwnd, szClassName, 199);
61af5a
973ea8 ¤   if (!strcmp(szClassName, szOldEditClass) ||·
7d5f7f ¤   ¤   !strcmp(szClassName, szNewEditClass))
bfc7a1 ¤   {
04052e ¤   ¤   GetWindowRect(hwnd, &rc);
19ea70 ¤   ¤   if (rc.bottom > pfsRichEdit->yMax)
995b34 ¤   ¤   {
c73ded ¤   ¤   ¤   pfsRichEdit->yMax = rc.bottom;
1a98eb ¤   ¤   ¤   pfsRichEdit->hwndFound = hwnd;
410fe4 ¤   ¤   }
309371 ¤   }
e3af5a
cd30c6 ¤   if (!strcmp(szClassName, szIEClass))
b43c0a ¤   ¤   pfsRichEdit->bInternetExplorer = TRUE;
41af5a
8fb310 ¤   if (!strcmp(szClassName, szWordClass))
72dc10 ¤   ¤   pfsRichEdit->bMicrosoftWord = TRUE;
38af5a
78c2e7 ¤   return TRUE;
afefe6 }
d7af5a
5faf5a
fcaf5a
737e4d /*__Editor_settings____
b3af5a
654126 ¤   Local Variables:
757b17 ¤   tab-width: 4
4a0e6c ¤   End:
835f8c ¤   vi: ts=4 sw=4
0f9e9b ¤   vim: si
b5d062 _____________________*/
--d905 0005740a2dc40110309 Page 1 of Exchange.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
0d4058 ¤   $Id: Exchange.h,v 1.18.8.1 1998/11/12 03:13:55 heller Exp $
baaf5a
93af5a
53af5a
74f7f7 ____________________________________________________________________________*/
1b51af #ifndef Included_Exchange_h¤/* [ */
4a5686 #define Included_Exchange_h
73af5a
185d3c #include "stdinc.h"
f34919 #include "pgpUtilities.h"
629f63 #include "pgpEncode.h"
7eec82 #include "pgpTLS.h"
9c78f8 #include "pgpcl.h"
c2af5a
8be49e // Global variables
43af5a
1f469c extern PGPContextRef _pgpContext;¤  ¤   // PGP context of current instance
ead4e5 extern PGPtlsContextRef _tlsContext;¤   // TLS context of current instance
b920b2 extern PGPMemoryMgrRef _memoryMgr;¤ ¤   // Memory manager of PGP context
296722 extern PGPError _errContext;¤   ¤   ¤   // Error code if context failed
72af5a
c8af5a
60336e // In STDNOTE.CPP·
7c9d54 // Heuristic class to guess the origin of current note
5aaf5a
f6c758 class CMsgType
75bb36 {
970fb9 private:
55a4c9 ¤   UINT _cRecips;
ea597c ¤   BOOL _fSubjSet;
0320ed ¤   BOOL _fNew;
52cfeb ¤   BOOL _fIsReply;
3253a1 ¤   BOOL _fIsFwd;
b2c4c5 ¤   BOOL _fIsSubmitted;
65af5a
1a5ed4 public:
506fc9 ¤   CMsgType() : _cRecips(0), _fSubjSet(FALSE),
a033b8 ¤   ¤   _fNew(FALSE), _fIsReply(FALSE), _fIsFwd(FALSE),
6fa0d2 ¤   ¤   _fIsSubmitted(FALSE) { }
59f092 ¤   HRESULT Read(IExchExtCallback* peecb);
e2ac7d ¤   HRESULT Write(IExchExtCallback* peecb, BOOL fInSubmit);
5aaf5a
d1a67c ¤   BOOL IsNew() const;
4cf569 ¤   BOOL IsForward() const;
7a3044 ¤   BOOL IsReply() const;
95d4cf ¤   BOOL WasSubmittedOnce() const;
2782f7 };
46af5a
97af5a
d36b79 class CExtImpl : public IExchExt,·
07a7f3 ¤   IExchExtPropertySheets, IExchExtMessageEvents,·
ecdd02 ¤   IExchExtCommands, IExchExtAttachedFileEvents
4fbb36 {
2c5ed4 public:
553165 ····CExtImpl();
e8d0a3 ¤   ~CExtImpl();
29af5a
2a7208 ¤   // The methods of IUnknown·
d8af5a
da5f3b ····STDMETHODIMP QueryInterface(REFIID riid, void** ppvObj);
cd9289 ····inline STDMETHODIMP_(ULONG) AddRef()
5e4b0a ····¤   { ++_cRef; return _cRef; }
922d2e ····inline STDMETHODIMP_(ULONG) Release()
41b2ec ········{ ULONG ulCount = --_cRef;
57433e ··········if (!ulCount) { delete this; }
--a2ff 00048309db840110309 Page 2 of Exchange.h
0d45cb ··········return ulCount;
5790b8 ········}·
4baf5a
54656c ¤   // The methods of IExchExt·
44af5a
0a8af5 ····STDMETHODIMP Install(IExchExtCallback* pmecb,·
ad5694 ··························ULONG mecontext, ULONG ulFlags);
84af5a
04ab75 ¤   // The methods of IExchExtPropertySheets·
caaf5a
88a6fa ····STDMETHODIMP_(ULONG) GetMaxPageCount(ULONG ulFlags); ·········
cdbb07 ····STDMETHODIMP GetPages(IExchExtCallback* peecb,
e78701 ··························ULONG ulFlags, LPPROPSHEETPAGE ppsp,·
d9d139 ¤   ¤   ¤   ¤   ¤   ¤   ··ULONG * pcpsp); ·········
fb42ee ····STDMETHODIMP_(VOID) FreePages(LPPROPSHEETPAGE ppsp, ULONG ulFlags,·
a7478a ·········································ULONG cpsp); ·········
63af5a
b5d964 ¤   // The methods of IExchExtMessageEvents·
b7af5a
5fbfd6 ····STDMETHODIMP OnRead(IExchExtCallback* lpeecb);
211eef ····STDMETHODIMP OnReadComplete(IExchExtCallback* lpeecb, ULONG ulFlags);
a09d92 ····STDMETHODIMP OnWrite(IExchExtCallback* lpeecb);
3299f4 ····STDMETHODIMP OnWriteComplete(IExchExtCallback* lpeecb, ULONG ulFlags);
8cffd0 ····STDMETHODIMP OnCheckNames(IExchExtCallback* lpeecb);
611131 ····STDMETHODIMP OnCheckNamesComplete(IExchExtCallback* lpeecb,·
bce064 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ULONG ulFlags);
1419ef ····STDMETHODIMP OnSubmit(IExchExtCallback* lpeecb);
47a7ff ····STDMETHODIMP_(VOID) OnSubmitComplete(IExchExtCallback* lpeecb,·
9d6f33 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ULONG ulFlags);
c8af5a
ca1efe ¤   // The methods of IExchExtCommands·
baaf5a
a2b839 ····STDMETHODIMP InstallCommands(IExchExtCallback* pmecb,·
65d248 ································HWND hwnd, HMENU hmenu,
d80529 ································UINT * cmdidBase, LPTBENTRY lptbeArray,
fa67e0 ································UINT ctbe, ULONG ulFlags);
26fb8b ····STDMETHODIMP DoCommand(IExchExtCallback* pmecb, UINT mni);
dc111f ····STDMETHODIMP_(VOID) InitMenu(IExchExtCallback* pmecb);
81a868 ····STDMETHODIMP Help(IExchExtCallback* pmecb, UINT mni);
f3d8dc ····STDMETHODIMP QueryHelpText(UINT mni, ULONG ulFlags, LPTSTR sz, UINT cch);
c927ec ····STDMETHODIMP QueryButtonInfo(ULONG tbid, UINT itbb, LPTBBUTTON ptbb,
616c35 ································LPTSTR lpsz, UINT cch, ULONG ulFlags);
83e35e ····STDMETHODIMP ResetToolbar(ULONG tbid, ULONG ulFlags);
38af5a
789984 ¤   // The methods of IExchExtAttachedFileEvents
63af5a
7f681f ¤   STDMETHODIMP OnReadPattFromSzFile(IAttach* lpAtt, LPTSTR lpszFile,·
67008e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ULONG ulFlags);·
8e8bd0 ¤   STDMETHODIMP OnWritePattToSzFile(IAttach* lpAtt, LPTSTR lpszFile,·
2ee064 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ULONG ulFlags);
8445f6 ¤   STDMETHODIMP QueryDisallowOpenPatt(IAttach* lpAtt);·
f7b62a ····STDMETHODIMP OnOpenPatt(IAttach* lpAtt);·
f48049 ¤   STDMETHODIMP OnOpenSzFile(LPTSTR lpszFile, ULONG ulFlags);
6daf5a
f50fb9 private:
0369b9 ····ULONG¤  _cRef;
8caf5a
db758a ¤   // Set in Install.
54af5a
930263 ····UINT¤   _context;¤  ¤   ¤   // The context of the current instance
2baf5a
befaa2 ····BOOL¤   _fOldEEME;¤ ¤   ¤   // Set if old style IExchExtMessageEvents
9fa13c ¤   BOOL¤   _fOutlook;¤ ¤   ¤   // Set if Outlook is being used
48da11 ¤   BOOL¤   _fOutlook98;¤   ¤   // Set if Outlook98 is being used
bc43d1 ¤   BOOL¤   _fLoaded;¤  ¤   ¤   // Set if the plug-in DLL was already loaded
4d24ce ¤   HWND¤   _hwndRE;¤   ¤   ¤   // The richedit control on a note form
0fcc8d ¤   HWND¤   _hwndMessage;¤  ¤   // Window containing message
06af5a
e29e4f ¤   // Set in OnSubmit and OnSubmitComplete.·
72af5a
82ad36 ····BOOL ···_fInSubmitState;¤   // Set if in a submission.
48af5a
--92b4 0004b2e81cd40110309 Page 3 of Exchange.h
7d851c ¤   // Set on the first pass through InitMenu.·
02af5a
94d354 ¤   BOOL¤   _fInitMenuOnce;¤¤   // Flag as to whether the above is·
86f031 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // initialized yet.
9aaf5a
980e4b ¤   // Set in InstallCommands.·
c6af5a
666317 ¤   // PGP menu on menu bar
58af5a
670fcd ¤   HMENU _hmenuPGP;
aaaf5a
8c0976 ¤   // Menu and/or button command ID's
c0af5a
aab7e1 ¤   UINT¤   _cmdidSign;
141182 ¤   UINT¤   _cmdidSignNow;
e8b004 ¤   UINT¤   _cmdidEncrypt;
b46c96 ¤   UINT¤   _cmdidEncryptNow;
55c4fb ¤   UINT¤   _cmdidEncryptSign;
485a95 ¤   UINT¤   _cmdidDecrypt;
90d899 ¤   UINT¤   _cmdidPgpKeys;
2b020f ¤   UINT¤   _cmdidPrefs;
fafadf ¤   UINT¤   _cmdidHelp;
cc4c62 ¤   UINT¤   _cmdidAbout;
b7af5a
95a406 ¤   // Button bitmap ID's
6aaf5a
4d08fa ¤   UINT¤   _itbmSign;
030417 ¤   UINT¤   _itbmSignNow;
2ea591 ¤   UINT¤   _itbmEncrypt;
62377b ¤   UINT¤   _itbmEncryptNow;
41f84b ¤   UINT¤   _itbmEncryptSign;
d44f00 ¤   UINT¤   _itbmDecrypt;
22cd0c ¤   UINT¤   _itbmPgpKeys;
0faf5a
e10468 ¤   // Button ID's
68af5a
1a110e ¤   UINT¤   _itbbSign;
77a9cb ¤   UINT¤   _itbbSignNow;
b8084d ¤   UINT¤   _itbbEncrypt;
660250 ¤   UINT¤   _itbbEncryptNow;
8767af ¤   UINT¤   _itbbEncryptSign;
e9e2dc ¤   UINT¤   _itbbDecrypt;
fe60d0 ¤   UINT¤   _itbbPgpKeys;
06af5a
c4a014 ¤   // Toolbar handles
8baf5a
5876e5 ¤   HWND¤   _hwndSendToolbar;
ed6f04 ¤   HWND¤   _hwndReadToolbar;
32af5a
43d0f0 ¤   // Message flags
40af5a
44144c ¤   BOOL¤   _bSign;
6bc53b ¤   BOOL¤   _bEncrypt;
ba66f5 ¤   BOOL¤   _bHaveAttachments;
b1af5a
3a9914 ¤   // Set in either or both of InitMenu and OnReadComplete.·
d9af5a
2d7c32 ¤   CMsgType _msgtype;¤ ¤   ¤   // Type of message, analyzed at note-read·
a5ea34 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   // time.
80af5a
719bf2 int EncryptSignMessage(HWND hwnd,
1ce5a4 ¤   ¤   ¤   ¤   ¤   ···IMessage *pmsg,
4bb980 ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds,
f42825 ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef *pSignOptions);
02af5a
5c5bda int EncryptSignAttachment(HWND hwnd,
e6c8fb ¤   ¤   ¤   ¤   ¤   ¤   ··IMessage *pmsg,·
0626f8 ¤   ¤   ¤   ¤   ¤   ¤   ··UINT nOutSize,
d9e4b0 ¤   ¤   ¤   ¤   ¤   ¤   ··SRowSet *prAttach,
8696cf ¤   ¤   ¤   ¤   ¤   ¤   ··RECIPIENTDIALOGSTRUCT *prds,
2ac597 ¤   ¤   ¤   ¤   ¤   ¤   ··PGPOptionListRef *pSignOptions);
4baf5a
--8ac3 001bc44fc3d40110309 Page 4 of Exchange.h
c15eb8 BOOL EncryptSignMessageWindow(HWND hwndMain,
93970f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··IExchExtCallback *pmecb,
74e33b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··BOOL bEncrypt,
e818dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··BOOL bSign,
0188a7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··RECIPIENTDIALOGSTRUCT *prds);
ad82f7 };
cbaf5a
41af5a
1e932d // In MsgProps.cpp
92d034 // Persistence structure for decryption
aaaf5a
8141b3 class CDecrypt
3abb36 {
6a0fb9 private:
885789 ¤   IMAPISession* _psess;
cb4684 ¤   BOOL _fInit;
46af5a
285ed4 public:
e1cc9e ¤   CDecrypt(IMAPISession*);
33cabf ¤   ~CDecrypt();
07af5a
9f19e3 ¤   void Init()
b28247 ¤   ¤   { if (!_fInit) Load(); }
144800 ¤   void Load();
9171ce ¤   void Save();
e0af5a
5ffac1 ¤   // Can take or drop session on the fly (needed because it can
d4c8b0 ¤   // outlive any particular callback).
60af5a
1ec1f6 ¤   void TakeSession(IMAPISession*);
7e588b ¤   void DropSession();
c982f7 };
f7af5a
72af5a
2baf5a
2faa1e // Lock-object, which puts up a wait cursor until the object dies.
afaf5a
ee6cf3 class CWaitCursor
a9bb36 {
ce0fb9 private:
f43a0f ¤   HCURSOR _hcurSave;
61af5a
295ed4 public:
94fd5c ¤   CWaitCursor() : _hcurSave(SetCursor(LoadCursor(NULL, IDC_WAIT))) {}
072825 ¤   ~CWaitCursor() ·{ SetCursor(_hcurSave); }
2382f7 };
daaf5a
536d78 #endif /* ] Included_Exchange_h */
69af5a
b0af5a
667e4d /*__Editor_settings____
75af5a
0a4126 ¤   Local Variables:
f97b17 ¤   tab-width: 4
320e6c ¤   End:
1d5f8c ¤   vi: ts=4 sw=4
a49e9b ¤   vim: si
bcd062 _____________________*/
--a1c4 00168f740624011030a Page 1 of GUIDS.CPP
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
5ab95f ¤   $Id: GUIDS.CPP,v 1.4.2.2.2.1 1998/11/12 03:13:56 heller Exp $
dff7f7 ____________________________________________________________________________*/
0aaf5a
cf841d #define INITGUID
8e55cb #define USES_IID_IExchExt
a5009e #define USES_IID_IExchExtPropertySheets
7c5d09 #define USES_IID_IExchExtMessageEvents
fad565 #define USES_IID_IExchExtAttachedFileEvents
7fec49 #define USES_IID_IMessage
c3eec8 #define USES_IID_IDistList
21a8c2 #define USES_IID_IABContainer
b7af5a
10bdfb #include <objbase.h>
f10cbc #include <initguid.h>
83709c #include <mapiguid.h>
85af5a
ed66a2 #define DEFINE_EXCHEXTGUID(name, b) \
d3caf3 ····DEFINE_GUID(name, 0x00020D00 | (b), 0, 0, 0xC0,0,0,0,0,0,0,0x46)
44af5a
3501ce #ifndef NOEXCHEXTGUIDS
4dad27 DEFINE_EXCHEXTGUID(IID_IExchExtCallback, ···········0x10);
5b31fa DEFINE_EXCHEXTGUID(IID_IExchExt, ···················0x11);
d98717 DEFINE_EXCHEXTGUID(IID_IExchExtCommands, ···········0x12);
b788da DEFINE_EXCHEXTGUID(IID_IExchExtUserEvents, ·········0x13);
17c9cf DEFINE_EXCHEXTGUID(IID_IExchExtSessionEvents, ······0x14);
1695ed DEFINE_EXCHEXTGUID(IID_IExchExtMessageEvents, ······0x15);
687b2b DEFINE_EXCHEXTGUID(IID_IExchExtAttachedFileEvents, ·0x16);
87e97e DEFINE_EXCHEXTGUID(IID_IExchExtPropertySheets, ·····0x17);
6466f3 DEFINE_EXCHEXTGUID(IID_IExchExtAdvancedCriteria, ···0x18);
4d8c47 DEFINE_EXCHEXTGUID(IID_IExchExtModeless, ···········0x19);
268443 DEFINE_EXCHEXTGUID(IID_IExchExtModelessCallback, ···0x1a);
7905f1 #endif // NOEXCHEXTGUIDS
08af5a
48505a // Application-specific GUIDs
5caf5a
a00804 #include "guids.h"
e1af5a
e5af5a
67af5a
f77e4d /*__Editor_settings____
b1af5a
884126 ¤   Local Variables:
c47b17 ¤   tab-width: 4
9e0e6c ¤   End:
8a5f8c ¤   vi: ts=4 sw=4
c49e9b ¤   vim: si
68d062 _____________________*/
--dac8 0018b2b8ee54011030b Page 1 of GUIDS.H
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
11d189 ¤   $Id: GUIDS.H,v 1.2.18.1 1998/11/12 03:13:56 heller Exp $
58f7f7 ____________________________________________________________________________*/
655ef4 #ifndef Included_GUIDS_h¤   /* [ */
774630 #define Included_GUIDS_h
adaf5a
2d95e8 // {1C8F62A0-B699-11d0-95B0-0060977B23E7}
cee812 DEFINE_GUID(GUID_PGPPlugin,·
1f9dfe 0x1c8f62a0, 0xb699, 0x11d0, 0x95, 0xb0, 0x0, 0x60, 0x97, 0x7b, 0x23, 0xe7);
b0af5a
f83632 #endif /* ] Included_GUIDS_h */
4daf5a
16af5a
b67e4d /*__Editor_settings____
e3af5a
044126 ¤   Local Variables:
7c7b17 ¤   tab-width: 4
8b0e6c ¤   End:
7b5f8c ¤   vi: ts=4 sw=4
159e9b ¤   vim: si
8bd062 _____________________*/
--3e00 0004aed03c34011030c Page 1 of Main.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
e8b4e0 ¤   $Id: Main.cpp,v 1.27.8.1 1998/11/12 03:13:57 heller Exp $
34af5a
57af5a
eeaf5a
2af7f7 ____________________________________________________________________________*/
bf5d3c #include "stdinc.h"
6b9803 #include "Exchange.h"
1fed8f #include "Outlook.h"
21cd68 #include "Recipients.h"
0b8031 #include "resource.h"
eeadf9 #include "UIutils.h"
854919 #include "pgpUtilities.h"
05a076 #include "pgpKeys.h"
275ab2 #include "PGPcl.h"
1aaf5a
43cfa8 // The version that went out with Win95 is 410; with Exchange Server, 837.
9df068 // (RC1 used 611; RC2 used 736.3.)
be23a8 // The Windows 95 Messaging Update is 839.
35ac6a //·
b257af // Exchange 5.0 comes back as 4.0 build 1458
065441 // Outlook 98 comes back as 4.0 build 1573
e0af5a
835d5d #define LAST_BUILD_SUPPORTED¤   1573
d9ecd4 #define OUTLOOK98_BUILD¤¤   ¤   1573
4faf5a
7dbbf8 // Other values returned by IExchExtCallback::GetVersion
52fc1a // Microsoft Exchange 4.0 is 0x01??0400
cdaf5a
7d6a21 #define CURRENT_PRODUCT_CODE ·0x01000000
90131d #define LAST_MAJVER_SUPPORTED 0x00000400
e7cee0 #define LAST_MINVER_SUPPORTED 0x00000000
cdaf5a
35c5fb extern "C" IExchExt* CALLBACK ExchEntryPoint();
3caf5a
aabed9 static BOOL IsExchExtWithinOutlook(IExchExtCallback* peecb);
65af5a
54b68c static void TurnOffWarning(ULONG ulMajVer, ULONG ulMinVer,·
ad1808 ¤   ¤   ¤   ¤   ¤   ¤   ···ULONG ulBuildMinVer);
f4af5a
0c49d2 static void SetNewerOK(ULONG ulMajVer,·
2fa197 ¤   ¤   ¤   ¤   ¤   ···ULONG ulMinVer,·
465644 ¤   ¤   ¤   ¤   ¤   ···ULONG ulBuildMinVer,·
162763 ¤   ¤   ¤   ¤   ¤   ···BOOL bOK);
aeaf5a
032720 static BOOL IsWarningOff(ULONG ulMajVer,·
d5ad49 ¤   ¤   ¤   ¤   ¤   ¤   ·ULONG ulMinVer,·
7c432e ¤   ¤   ¤   ¤   ¤   ¤   ·ULONG ulBuildMinVer);
4aaf5a
8dd054 static BOOL IsNewerOK(ULONG ulMajVer,·
90a1a7 ¤   ¤   ¤   ¤   ¤   ··ULONG ulMinVer,·
0b9e44 ¤   ¤   ¤   ¤   ¤   ··ULONG ulBuildMinVer);
0eaf5a
b79fbe static BOOL DoIExist(BOOL bOutlook);
dc342d static void SetNoLoad(void);
9d9c3a static BOOL ShouldILoad(void);
25235f static HWND CreateHiddenWindow(void);
98af5a
375aa8 LRESULT CALLBACK HiddenWindowProc(HWND hwnd,·
a508ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
a113bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
7d325e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
72af5a
e0e49e // Global variables
43af5a
4a2c67 PGPContextRef _pgpContext = NULL;¤  ¤   // PGP context of current instance
--ee5a 0000191e8e84011030c Page 2 of Main.cpp
d22733 PGPtlsContextRef _tlsContext = NULL;¤   // TLS context of current instance
c0826a PGPMemoryMgrRef _memoryMgr = NULL;¤ ¤   // Memory manager of PGP context
6190fc PGPError _errContext = kPGPError_NoErr;¤// Error code if context failed
8f68b2 HWND _hwndHidden = NULL;¤   ¤   ¤   ¤   // Window for catching messages
39662a UINT _nPurgeCacheMsg = 0;¤  ¤   ¤   ¤   // Purge Passphrase Cache message
11af5a
60af5a
e491c6 // DLL entry point
05af5a
8ea989 BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID)
c0bb36 {
6d8fe1 ·¤  if (DLL_PROCESS_ATTACH == fdwReason)
d32e29 ·¤  {
7c9a4a ¤   ¤   UISetInstance(hinstDll);
df7af9 ·¤  }
71af5a
3827d6 ·¤  if (DLL_PROCESS_DETACH == fdwReason)
fc2e29 ·¤  {
a47af9 ·¤  }
83af5a
b9c2e7 ¤   return TRUE;
b7efe6 }
3faf5a
51af5a
1b145f // Exchange client extension entry point
f3af5a
453fac IExchExt* CALLBACK ExchEntryPoint()
a6bb36 {
48797e ¤   return new CExtImpl;
aeefe6 }
84af5a
5aaf5a
8e2437 CExtImpl::CExtImpl()·
992710 ¤   : _cRef(1), _context(0),
347105 ¤   ··_fOldEEME(FALSE), _fInSubmitState(FALSE),·
a9e38d ¤   ··_fInitMenuOnce(FALSE),
9f7cc8 ¤   ··_hwndRE(NULL), _msgtype()
a5bb36 {
516489 ¤   _hmenuPGP = NULL;
635177 ¤   _bHaveAttachments = FALSE;
2aefe6 }
ddaf5a
cfaf5a
93fcc8 CExtImpl::~CExtImpl()
febb36 {
372296 ¤   if (_hmenuPGP)
3b0a78 ¤   ¤   DestroyMenu(_hmenuPGP);
d2af5a
cf5b4f ¤   if (!_fLoaded)
57c7a1 ¤   {
306dd5 ¤   ¤   if (_hwndHidden)
f15b34 ¤   ¤   {
bbc2f6 ¤   ¤   ¤   DestroyWindow(_hwndHidden);
4f8214 ¤   ¤   ¤   _hwndHidden = NULL;
4e0fe4 ¤   ¤   }
1baf5a
726703 ¤   ¤   if (_tlsContext)
fb5b34 ¤   ¤   {
20c7b0 ¤   ¤   ¤   PGPFreeTLSContext(_tlsContext);
7c0705 ¤   ¤   ¤   _tlsContext = NULL;
4d0fe4 ¤   ¤   }
f8af5a
ccc6eb ¤   ¤   if (_pgpContext && IsntPGPError(_errContext))
335b34 ¤   ¤   {
0d59d4 ¤   ¤   ¤   PGPclCloseLibrary();
d0bbf9 ¤   ¤   ¤   PGPFreeContext(_pgpContext);
5b9465 ¤   ¤   ¤   _pgpContext = NULL;
09ce4a ¤   ¤   ¤   _memoryMgr = NULL;
790fe4 ¤   ¤   }
229371 ¤   }
4aefe6 }
01af5a
--d163 0009706de764011030c Page 3 of Main.cpp
e0af5a
81d90e STDMETHODIMP CExtImpl::QueryInterface(REFIID riid, void** ppvObj) ·········
4bbb36 {
ce8147 ····*ppvObj = NULL;
bcaf5a
5d65c1 ····HRESULT hr = S_OK;
d58f2d ¤   IUnknown* punk = NULL;
7baf5a
d5e4e1 ····if (( IID_IUnknown == riid) || ( IID_IExchExt == riid) )
bb3b37 ····{
7f9cc5 ········punk = (IExchExt*)this;
1a6fe7 ····}
138fa6 ····else if (IID_IExchExtPropertySheets == riid)
cf3b37 ····{
066249 ········punk = (IExchExtPropertySheets*)this;
7b6fe7 ····}
c65184 ····else if (IID_IExchExtMessageEvents == riid)
0b3b37 ····{
c40eb3 ········punk = (IExchExtMessageEvents*)this;
ed6fe7 ····}
28558b ····else if (IID_IExchExtCommands == riid)
733b37 ····{
de9ff4 ········punk = (IExchExtCommands*)this;
c86fe7 ····}
51f2c0 ····else if (IID_IExchExtAttachedFileEvents == riid)
863b37 ····{
090933 ········punk = (IExchExtAttachedFileEvents*)this;
ad6fe7 ····}
5f842c ····else
35eae3 ········hr = E_NOINTERFACE;
47af5a
a37438 ¤   if (NULL != punk)
77c7a1 ¤   {
9a7370 ¤   ¤   *ppvObj = punk;
5efb5c ¤   ¤   AddRef();
cf9371 ¤   }
beaf5a
8190c8 ····return hr;
0fefe6 }
cdaf5a
3eaf5a
770c52 STDMETHODIMP CExtImpl::Install(IExchExtCallback* peecb, ULONG eecontext,·
775833 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···ULONG ulFlags)
4abb36 {
1ed84c ····ULONG ulBuildVer;
1767af ¤   ULONG ulProductVer;
668534 ¤   ULONG ulMajVer;
ef4b74 ¤   ULONG ulMinVer;
8b9c99 ¤   ULONG ulBuildMinVer;
a92b5f ¤   BOOL fMinorBuildOk;
b7fb0a ····HRESULT hr;
3b55cf ¤   HWND hwnd;
ec0040 ¤   PGPError err;
cbaf5a
1f97a2 ¤   hr = peecb->GetVersion(&ulProductVer, EECBGV_GETVIRTUALVERSION);
3809bc ¤   if (SUCCEEDED(hr))
0527a3 ¤   ¤   hr = peecb->GetVersion(&ulBuildVer, EECBGV_GETBUILDVERSION);
7a1f79 ¤   if (FAILED(hr))
5fc7a1 ¤   {
cf5e80 ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOVERSION);
828cd7 ¤   ¤   SetNoLoad();
3c93bf ¤   ¤   return S_FALSE;
f29371 ¤   }
bc1b52 ¤   ¤
49d6f8 ¤   ulMajVer = ulProductVer & EECBGV_VERSION_MAJOR_MASK;
b73251 ¤   ulMinVer = ulProductVer & EECBGV_VERSION_MINOR_MASK;
a531ce ¤   ulBuildMinVer = ulBuildVer & EECBGV_BUILDVERSION_MINOR_MASK;
321b52 ¤   ¤
f2f99f ¤   // Check to see if we're running Outlook97
ac6e0c ¤   _fOutlook = IsExchExtWithinOutlook(peecb);
c5af5a
977a57 ¤   // Check to see if we're running Outlook98
--fc6f 000a4fd50674011030c Page 4 of Main.cpp
1f5039 ¤   if (ulBuildMinVer == OUTLOOK98_BUILD)
4a1b10 ¤   ¤   _fOutlook98 = TRUE;
2b0e24 ¤   else
5d21d9 ¤   ¤   _fOutlook98 = FALSE;
59af5a
cbc1b4 ¤   _fLoaded = DoIExist(_fOutlook);
6123d4 ¤   if ((!_fLoaded) || (_pgpContext == NULL))
dbc12a ¤   ¤   _errContext = PGPNewContext(kPGPsdkAPIVersion, &_pgpContext);
c7af5a
540cd7 ¤   if (!ShouldILoad())
3e93bf ¤   ¤   return S_FALSE;
25af5a
58f033 ····_context = eecontext;
bdaf5a
78ae1a ¤   peecb->GetWindow(&hwnd);
88ab0c ¤   if (!hwnd)
cba8e4 ¤   ¤   hwnd = GetTopWindow(NULL);
a9af5a
c23a8c ¤   // Check for SDK expiration or other SDK initialization failure
b1af5a
c82ded ¤   if (IsPGPError(_errContext))
c2c7a1 ¤   {
1e71c4 ¤   ¤   if (_errContext == kPGPError_FeatureNotAvailable)
91db47 ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_EXPIRED);
130e1d ¤   ¤   else
78c9d7 ¤   ¤   ¤   PGPclErrorBox(hwnd, _errContext);
dbaf5a
278cd7 ¤   ¤   SetNoLoad();
d593bf ¤   ¤   return S_FALSE;
449371 ¤   }
27af5a
931a65 ¤   // Initialize common library
23af5a
af5b4f ¤   if (!_fLoaded)
82c7a1 ¤   {
76eb93 ¤   ¤   err = PGPclInitLibrary(_pgpContext);
c0b6ad ¤   ¤   if (IsPGPError(err))
2b5b34 ¤   ¤   {
bc9c7e ¤   ¤   ¤   PGPclErrorBox(hwnd, err);
083d06 ¤   ¤   ¤   SetNoLoad();
2c65da ¤   ¤   ¤   return S_FALSE;
fc0fe4 ¤   ¤   }
849371 ¤   }
84af5a
ae9c6d ¤   // Check for beta/demo expiration
d7af5a
e4cfb0 ¤   if (PGPclIsExpired(hwnd) != kPGPError_NoErr)
95c7a1 ¤   {
b18cd7 ¤   ¤   SetNoLoad();
3493bf ¤   ¤   return S_FALSE;
c29371 ¤   }
3eaf5a
4e5b4f ¤   if (!_fLoaded)
05c7a1 ¤   {
bdd811 ¤   ¤   // Register the passphrase cache purge message
d4af5a
da6a06 ¤   ¤   _nPurgeCacheMsg = RegisterWindowMessage(PURGEPASSPHRASECACEHMSG);
2baf5a
b0f650 ¤   ¤   // Create a hidden window to catch messages
c1af5a
a12b6e ¤   ¤   _hwndHidden = CreateHiddenWindow();
e4af5a
3b494b ¤   ¤   _memoryMgr = PGPGetContextMemoryMgr(_pgpContext);
412d9e ¤   ¤   PGPNewTLSContext(_pgpContext, &_tlsContext);
4aaf5a
fc6b9f ¤   ¤   // Ensure that this is the right version on first load
e11b52 ¤   ¤
1de426 ¤   ¤   if ((CURRENT_PRODUCT_CODE !=·
55a099 ¤   ¤   ¤   (ulProductVer & EECBGV_VERSION_PRODUCT_MASK)) ··
fb910d ¤   ¤   ¤   ||
25c7f1 ¤   ¤   ¤   (EECBGV_BUILDVERSION_MAJOR !=·
a4734e ¤   ¤   ¤   (ulBuildVer & EECBGV_BUILDVERSION_MAJOR_MASK)))
--5847 0002210cfe74011030c Page 5 of Main.cpp
e35b34 ¤   ¤   {
8e2cd3 ¤   ¤   ¤   // The first time, explain why we aren't loading.
f9cd2b ¤   ¤   ¤   // Subsequently, remain silent.
0987c7 ¤   ¤   ¤
1f3e2b ¤   ¤   ¤   if (!IsWarningOff(ulMajVer, ulMinVer, ulBuildMinVer))
a3f776 ¤   ¤   ¤   {
a9751d ¤   ¤   ¤   ¤   TurnOffWarning(ulMajVer, ulMinVer, ulBuildMinVer);
a42f1f ¤   ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_INCOMPATIBLE_VERSION);
7da3a6 ¤   ¤   ¤   }
483d06 ¤   ¤   ¤   SetNoLoad();
d265da ¤   ¤   ¤   return S_FALSE;
310fe4 ¤   ¤   }
69af5a
4f7ab2 ¤   ¤   if ((LAST_MAJVER_SUPPORTED < (ulMajVer)) ||
9fb9ef ¤   ¤   ¤   (LAST_MINVER_SUPPORTED < (ulMinVer)) ||
918f71 ¤   ¤   ¤   (LAST_BUILD_SUPPORTED ·< (ulBuildMinVer)))
cc5b34 ¤   ¤   {
f5584b ¤   ¤   ¤   // Warn the user of a newer version of Exchange.
e7e72f ¤   ¤   ¤   // If the user loads the plug-in anyway, don't warn anymore,
6d4eee ¤   ¤   ¤   // otherwise, warn every time.
553e2b ¤   ¤   ¤   if (!IsWarningOff(ulMajVer, ulMinVer, ulBuildMinVer))
aff776 ¤   ¤   ¤   {
7f90b8 ¤   ¤   ¤   ¤   fMinorBuildOk =¤
96c2d1 ¤   ¤   ¤   ¤   ¤   (UIAskYesNoStringID(hwnd, IDS_Q_LATER_BUILD) == IDYES);
71ad48 ¤   ¤   ¤   ¤   if (fMinorBuildOk)
1c6691 ¤   ¤   ¤   ¤   ¤   TurnOffWarning(ulMajVer, ulMinVer, ulBuildMinVer);
d3a3a6 ¤   ¤   ¤   }
44bb8c ¤   ¤   ¤   else
8ff02a ¤   ¤   ¤   ¤   fMinorBuildOk = IsNewerOK(ulMajVer, ulMinVer, ulBuildMinVer);
b487c7 ¤   ¤   ¤
a649f6 ¤   ¤   ¤   if (!fMinorBuildOk)
daf776 ¤   ¤   ¤   {
14095b ¤   ¤   ¤   ¤   SetNoLoad();
a5c884 ¤   ¤   ¤   ¤   return S_FALSE;
aba3a6 ¤   ¤   ¤   }
02bb8c ¤   ¤   ¤   else
e26677 ¤   ¤   ¤   ¤   SetNewerOK(ulMajVer, ulMinVer, ulBuildMinVer, TRUE);
dd0fe4 ¤   ¤   }
f69371 ¤   }
77af5a
bcb6e2 ¤   BOOL fFindRE = FALSE; // Set if it needs to find the RE.
e0af5a
c12c0f ····switch (eecontext)
633b37 ····{
88c108 ¤   case EECONTEXT_SENDPOSTMESSAGE:
04f5cd ¤   case EECONTEXT_SENDNOTEMESSAGE:
944477 ¤   case EECONTEXT_READNOTEMESSAGE:
6270b2 ¤   case EECONTEXT_READPOSTMESSAGE:
011632 //¤ ¤   fFindRE = TRUE;
2d814d ¤   ¤   hr = S_OK;
072f68 ¤   ¤   break;
1eaf5a
6b9989 ····case EECONTEXT_PROPERTYSHEETS:
8de287 ¤   ¤   // To get the property page
402f26 ········hr = S_OK;
152d5f ········break;
8faf5a
dafecb ¤   case EECONTEXT_VIEWER:
be814d ¤   ¤   hr = S_OK;
c62f68 ¤   ¤   break;
93af5a
131bee ¤   case EECONTEXT_READREPORTMESSAGE:
f73fba ¤   case EECONTEXT_SENDRESENDMESSAGE:
01b53c ····default:
8fd6ef ········hr = S_FALSE;
be2d5f ········break;
726fe7 ····}
20869e ····
337695 ····// Make a note of pre-RC1 builds,
4722e4 ····// in which the IExchExtMessageEvent sequence differed on reply notes.
0e869e ····
22639e ····_fOldEEME = ((EECBGV_BUILDVERSION_MINOR_MASK & ulBuildVer) < 611);
--533a 0003322e7364011030c Page 6 of Main.cpp
e0af5a
5f90c8 ····return hr;
62efe6 }
85af5a
24af5a
40feca BOOL IsExchExtWithinOutlook(IExchExtCallback* peecb)
2dbb36 {
8c37ef ¤   IOutlookGetObjectForExchExtCallback* po = NULL;
0eaf5a
01fc0f ¤   HRESULT hr = peecb->
93e471 ¤   ¤   ¤   ¤   ¤   QueryInterface(IID_IOutlookGetObjectForExchExtCallback,·
40ed75 ¤   ¤   ¤   ¤   ¤   ¤   (void**)&po);
174b25 ¤   if (po)
b0725e ¤   ¤   po->Release();
16af5a
d67eb8 ¤   return (SUCCEEDED(hr));
a1efe6 }
63af5a
10af5a
71f635 void TurnOffWarning(ULONG ulMajVer, ULONG ulMinVer, ULONG ulBuildMinVer)
11bb36 {
cf6fcf ¤   HKEY hkey;
1f2cf2 ¤   char szRegKey[255];
ca33a4 ¤   char szVersion[255];
c9f00f ¤   DWORD dwDummy;
562d6a ¤   DWORD dwValue;
bbaf5a
de4b46 ¤   UIGetString(szRegKey, 254, IDS_WARNING_REGKEY);
66408b ¤   wsprintf(szVersion, "Maj %ld Min %ld Build %ld", ulMajVer, ulMinVer,·
a0a23b ¤   ¤   ulBuildMinVer);
e40d7b ¤   strcat(szRegKey, szVersion);
feaf5a
8e0e9d ¤   RegCreateKeyEx(HKEY_CURRENT_USER, szRegKey, 0, NULL,·
3eb5c9 ¤   ¤   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDummy);
04af5a
c79f65 ¤   dwValue = 1;
2bb706 ¤   RegSetValueEx(hkey, "WarningOff", 0, REG_DWORD, (BYTE *) &dwValue,·
d7dd35 ¤   ¤   sizeof(DWORD));
d16c72 ¤   RegCloseKey(hkey);
64830f ¤   return;
97efe6 }
d6af5a
49af5a
75d82d void SetNewerOK(ULONG ulMajVer,·
6c27ee ¤   ¤   ¤   ¤   ULONG ulMinVer,·
0b7427 ¤   ¤   ¤   ¤   ULONG ulBuildMinVer,·
79edcd ¤   ¤   ¤   ¤   BOOL bOK)
1dbb36 {
1f6fcf ¤   HKEY hkey;
032cf2 ¤   char szRegKey[255];
ae33a4 ¤   char szVersion[255];
98f00f ¤   DWORD dwDummy;
532d6a ¤   DWORD dwValue;
1aaf5a
164b46 ¤   UIGetString(szRegKey, 254, IDS_WARNING_REGKEY);
23408b ¤   wsprintf(szVersion, "Maj %ld Min %ld Build %ld", ulMajVer, ulMinVer,·
1ca23b ¤   ¤   ulBuildMinVer);
780d7b ¤   strcat(szRegKey, szVersion);
76af5a
b40e9d ¤   RegCreateKeyEx(HKEY_CURRENT_USER, szRegKey, 0, NULL,·
4ab5c9 ¤   ¤   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDummy);
98af5a
73966e ¤   dwValue = bOK;
25749b ¤   RegSetValueEx(hkey, "NewerOK", 0, REG_DWORD, (BYTE *) &dwValue,·
e9dd35 ¤   ¤   sizeof(DWORD));
506c72 ¤   RegCloseKey(hkey);
9b830f ¤   return;
64efe6 }
7daf5a
d0af5a
4e8c79 BOOL IsWarningOff(ULONG ulMajVer, ULONG ulMinVer, ULONG ulBuildMinVer)
33bb36 {
--2f37 00083459da64011030c Page 7 of Main.cpp
b06fcf ¤   HKEY hkey;
9a2cf2 ¤   char szRegKey[255];
3733a4 ¤   char szVersion[255];
0cf00f ¤   DWORD dwDummy;
1f2d6a ¤   DWORD dwValue;
73563d ¤   DWORD dwType;
7f11df ¤   DWORD dwSize=4;
3caf5a
1f4b46 ¤   UIGetString(szRegKey, 254, IDS_WARNING_REGKEY);
f9408b ¤   wsprintf(szVersion, "Maj %ld Min %ld Build %ld", ulMajVer, ulMinVer,·
7ba23b ¤   ¤   ulBuildMinVer);
fa0d7b ¤   strcat(szRegKey, szVersion);
a3af5a
040e9d ¤   RegCreateKeyEx(HKEY_CURRENT_USER, szRegKey, 0, NULL,·
2db5c9 ¤   ¤   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDummy);
5caf5a
da74e1 ¤   if (RegQueryValueEx(hkey, "WarningOff", 0, &dwType, (BYTE *) &dwValue,·
02d793 ¤   ¤   &dwSize) != ERROR_SUCCESS)
34c7a1 ¤   {
7a8432 ¤   ¤   dwValue = 0;
93ac0f ¤   ¤   RegSetValueEx(hkey, "WarningOff", 0, REG_DWORD, (BYTE *) &dwValue,·
812b50 ¤   ¤   ¤   sizeof(DWORD));
fd9371 ¤   }
ecaf5a
146c72 ¤   RegCloseKey(hkey);
a90482 ¤   return dwValue;
83efe6 }
dfaf5a
40af5a
eaebcd BOOL IsNewerOK(ULONG ulMajVer, ULONG ulMinVer, ULONG ulBuildMinVer)
5dbb36 {
646fcf ¤   HKEY hkey;
cf2cf2 ¤   char szRegKey[255];
0633a4 ¤   char szVersion[255];
1ff00f ¤   DWORD dwDummy;
4f2d6a ¤   DWORD dwValue;
3c563d ¤   DWORD dwType;
8811df ¤   DWORD dwSize=4;
fcaf5a
bb4b46 ¤   UIGetString(szRegKey, 254, IDS_WARNING_REGKEY);
89408b ¤   wsprintf(szVersion, "Maj %ld Min %ld Build %ld", ulMajVer, ulMinVer,·
e0a23b ¤   ¤   ulBuildMinVer);
a50d7b ¤   strcat(szRegKey, szVersion);
56af5a
b80e9d ¤   RegCreateKeyEx(HKEY_CURRENT_USER, szRegKey, 0, NULL,·
9db5c9 ¤   ¤   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDummy);
eeaf5a
32043f ¤   if (RegQueryValueEx(hkey, "NewerOK", 0, &dwType, (BYTE *) &dwValue,·
8ed793 ¤   ¤   &dwSize) != ERROR_SUCCESS)
4cc7a1 ¤   {
868432 ¤   ¤   dwValue = 0;
f673ed ¤   ¤   RegSetValueEx(hkey, "NewerOK", 0, REG_DWORD, (BYTE *) &dwValue,·
882b50 ¤   ¤   ¤   sizeof(DWORD));
9b9371 ¤   }
e2af5a
776c72 ¤   RegCloseKey(hkey);
cc0482 ¤   return dwValue;
80efe6 }
51af5a
dcaf5a
12e799 BOOL DoIExist(BOOL bOutlook)
e7bb36 {
13079d ····HANDLE hSem;
feaf5a
53d5d5 ····// Create or open a named semaphore
6eaf5a
6ed907 ¤   if (bOutlook)
68644b ¤   ····hSem = CreateSemaphore (NULL, 0, 1, "pgpOutlookInstSem");
880e24 ¤   else
2e280d ¤   ¤   hSem = CreateSemaphore (NULL, 0, 1, "pgpExchangeInstSem");
8baf5a
83a7d7 ····// Close handle and return TRUE if existing semaphore was opened.
--8feb 0009a9d60194011030c Page 8 of Main.cpp
663254 ····if ((hSem != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))·
a3c7a1 ¤   {
605806 ········CloseHandle(hSem);
5e4ee5 ········return TRUE;
699371 ¤   }
e2af5a
c5a230 ¤   return FALSE;
2eefe6 }
56af5a
c1af5a
b5ab4b void SetNoLoad(void)
67bb36 {
61079d ····HANDLE hSem;
e6af5a
3018c5 ····// Create or open a named semaphore.·
5cc76e ····hSem = CreateSemaphore (NULL, 0, 1, "pgpExchLoadSem");
56af5a
833254 ····if ((hSem != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))·
b55806 ········CloseHandle(hSem);
91af5a
18830f ¤   return;
55efe6 }
c3af5a
98af5a
39b1de BOOL ShouldILoad(void)
d3bb36 {
04079d ····HANDLE hSem;
5f1eeb ¤   BOOL bShouldLoad = TRUE;
eeaf5a
1c18c5 ····// Create or open a named semaphore.·
eec76e ····hSem = CreateSemaphore (NULL, 0, 1, "pgpExchLoadSem");
06af5a
a3fd11 ····if (hSem != NULL)
b6c7a1 ¤   {
c9b363 ¤   ¤   if (GetLastError() == ERROR_ALREADY_EXISTS)·
2733c0 ¤   ¤   ¤   bShouldLoad = FALSE;
9d0e1d ¤   ¤   else
d69322 ¤   ¤   ¤   bShouldLoad = TRUE;
14af5a
924fd4 ¤   ¤   CloseHandle(hSem);
9d9371 ¤   }
20af5a
42faa1 ¤   return bShouldLoad;
43efe6 }
71af5a
76af5a
bafb33 HWND CreateHiddenWindow(void)
39bb36 {
a455cf ¤   HWND hwnd;
93d663 ¤   WNDCLASS wc;
00af5a
355e44 ¤   // Register the Window Class
deaf5a
b67783 ¤   wc.style¤   ¤   ¤   = 0;
cff813 ¤   wc.lpfnWndProc¤ ¤   = HiddenWindowProc;
d52ff0 ¤   wc.cbClsExtra¤  ¤   = 0;
23f5bd ¤   wc.cbWndExtra¤  ¤   = 0;
98af22 ¤   wc.hInstance¤   ¤   = UIGetInstance();
0e6b61 ¤   wc.hIcon¤   ¤   ¤   = 0;
231af3 ¤   wc.hCursor¤ ¤   ¤   = 0;
a0fdb7 ¤   wc.hbrBackground¤   = 0;
9c4d10 ¤   wc.lpszMenuName¤¤   = 0;
180887 ¤   wc.lpszClassName¤   = "pgpExch Hidden Window";
57af5a
f7fd79 ¤   RegisterClass(&wc);
4daf5a
33bd18 ¤   hwnd = CreateWindow("pgpExch Hidden Window", "pgpExch Hidden Window",
8d7b39 ¤   ¤   WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
47cd04 ¤   ¤   CW_USEDEFAULT, NULL, NULL, UIGetInstance(), NULL);
d1af5a
d1a706 ¤   return hwnd;
9aefe6 }
--02de 00124cf06434011030c Page 9 of Main.cpp
e0af5a
1aaf5a
715aa8 LRESULT CALLBACK HiddenWindowProc(HWND hwnd,·
f608ff ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT msg,·
6913bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
6de503 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
0fbb36 {
18b539 ¤   if (msg == WM_CREATE)
4ec7a1 ¤   {
a7efb3 ¤   ¤   ShowWindow(hwnd, SW_HIDE);
00bbde ¤   ¤   return 0;
f99371 ¤   }
2eaf5a
05ba59 ¤   if (msg == _nPurgeCacheMsg)
f6c7a1 ¤   {
5984b4 ¤   ¤   PGPclPurgeCachedPassphrase(wParam);
de836c ¤   ¤   return TRUE;
9c9371 ¤   }
81af5a
014c1c ¤   return DefWindowProc(hwnd, msg, wParam, lParam);
caefe6 }
14af5a
f5af5a
967e4d /*__Editor_settings____
eaaf5a
dc4126 ¤   Local Variables:
577b17 ¤   tab-width: 4
dd0e6c ¤   End:
3f5f8c ¤   vi: ts=4 sw=4
229e9b ¤   vim: si
24d062 _____________________*/
--b984 0000b32c07d4011030d Page 1 of MessageEvents.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
e4f464 ¤   $Id: MessageEvents.cpp,v 1.26.2.2.2.1 1998/11/12 03:13:58 heller Exp $
27af5a
afaf5a
83af5a
52f7f7 ____________________________________________________________________________*/
e55d3c #include "stdinc.h"
c69803 #include "Exchange.h"
f0b04c #include "EncryptSign.h"
0753a7 #include "DecryptVerify.h"
a28031 #include "resource.h"
07d2cf #include "BlockUtils.h"
e2cd68 #include "Recipients.h"
ddcc89 #include "Prefs.h"
89adf9 #include "UIutils.h"
62af5a
b8e2ff #include "pgpConfig.h"
19fb31 #include "pgpOptionList.h"
834919 #include "pgpUtilities.h"
cb91b9 #include "pgpSDKPrefs.h"
ef0d08 #include "pgpMem.h"
cdaf5a
0372fe #include "PGPsc.h"
0baf5a
acdc5e #if !defined(PR_BODY_HTML)
ca1979 #define PR_BODY_HTML¤   0x1013001E
3c7454 #endif
e5af5a
5c19f8 STDMETHODIMP CExtImpl::OnRead(IExchExtCallback* peecb)
49bb36 {
7155cf ¤   HWND hwnd;
fcaf5a
1eae1a ¤   peecb->GetWindow(&hwnd);
8dab0c ¤   if (!hwnd)
74a8e4 ¤   ¤   hwnd = GetTopWindow(NULL);
63af5a
5ce801 ¤   switch (_context)
0ec7a1 ¤   {
04f5cd ¤   case EECONTEXT_SENDNOTEMESSAGE:
495b34 ¤   ¤   {
65e6ef ¤   ¤   ¤   BOOL fAddButtons = TRUE;
b6685c ¤   ¤   ¤   int nNumButtons;
37114f ¤   ¤   ¤   int nIndex;
d2e546 ¤   ¤   ¤   TBBUTTON tbbNew[5];
e5cacd ¤   ¤   ¤   TBBUTTON tbbCheck;
1387c7 ¤   ¤   ¤
cf309f ¤   ¤   ¤   // Check to make sure the buttons aren't already on the toolbar
a8af5a
f49ce4 ¤   ¤   ¤   nNumButtons = SendMessage(_hwndSendToolbar, TB_BUTTONCOUNT, 0, 0);
a54473 ¤   ¤   ¤   for (nIndex=0; nIndex<nNumButtons; nIndex++)
daf776 ¤   ¤   ¤   {
31ad59 ¤   ¤   ¤   ¤   SendMessage(_hwndSendToolbar, TB_GETBUTTON, (WPARAM) nIndex,·
cef1b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) &tbbCheck);
74af5a
ca42c5 ¤   ¤   ¤   ¤   // If a button exists with the same bitmap ID and command ID
cf4232 ¤   ¤   ¤   ¤   // as the Encrypt button, odds are good that the button is
c9f1c7 ¤   ¤   ¤   ¤   // already on the toolbar
69d6dd ¤   ¤   ¤   ¤   if ((tbbCheck.iBitmap == (int)_itbmEncrypt) &&·
c00008 ¤   ¤   ¤   ¤   ¤   (tbbCheck.idCommand == (int)_cmdidEncrypt))
5e72c3 ¤   ¤   ¤   ¤   {
8995e2 ¤   ¤   ¤   ¤   ¤   fAddButtons = FALSE;
3166d4 ¤   ¤   ¤   ¤   ¤   nIndex = nNumButtons;
6a2613 ¤   ¤   ¤   ¤   }
39a3a6 ¤   ¤   ¤   }
6baf5a
0ba4f3 ¤   ¤   ¤   if (fAddButtons)
--36e5 0003ca299054011030d Page 2 of MessageEvents.cpp
99f776 ¤   ¤   ¤   {
ce0e33 ¤   ¤   ¤   ¤   tbbNew[0].iBitmap = 0;
6bafbc ¤   ¤   ¤   ¤   tbbNew[0].idCommand = 0;
3ccd3e ¤   ¤   ¤   ¤   tbbNew[0].fsState = 0;
320e66 ¤   ¤   ¤   ¤   tbbNew[0].fsStyle = TBSTYLE_SEP;
a4f3bc ¤   ¤   ¤   ¤   tbbNew[0].dwData = 0;
fdecbd ¤   ¤   ¤   ¤   tbbNew[0].iString = -1;
8b87c7 ¤   ¤   ¤
e0ab08 ¤   ¤   ¤   ¤   tbbNew[1].iBitmap = _itbmEncrypt;
83541b ¤   ¤   ¤   ¤   tbbNew[1].idCommand = _cmdidEncrypt;
e5b35d ¤   ¤   ¤   ¤   tbbNew[1].fsState = TBSTATE_ENABLED;
441a80 ¤   ¤   ¤   ¤   tbbNew[1].fsStyle = TBSTYLE_CHECK;
22bb96 ¤   ¤   ¤   ¤   tbbNew[1].dwData = 0;
0cfcb2 ¤   ¤   ¤   ¤   tbbNew[1].iString = -1;
dd87c7 ¤   ¤   ¤
eb42e2 ¤   ¤   ¤   ¤   tbbNew[2].iBitmap = _itbmSign;
b02956 ¤   ¤   ¤   ¤   tbbNew[2].idCommand = _cmdidSign;
ead248 ¤   ¤   ¤   ¤   tbbNew[2].fsState = TBSTATE_ENABLED;
4a40b3 ¤   ¤   ¤   ¤   tbbNew[2].fsStyle = TBSTYLE_CHECK;
1963e8 ¤   ¤   ¤   ¤   tbbNew[2].dwData = 0;
ebcca3 ¤   ¤   ¤   ¤   tbbNew[2].iString = -1;
3daf5a
1f9412 ¤   ¤   ¤   ¤   tbbNew[3].iBitmap = 0;
96ae84 ¤   ¤   ¤   ¤   tbbNew[3].idCommand = 0;
4f571f ¤   ¤   ¤   ¤   tbbNew[3].fsState = 0;
995187 ¤   ¤   ¤   ¤   tbbNew[3].fsStyle = TBSTYLE_SEP;
932bc2 ¤   ¤   ¤   ¤   tbbNew[3].dwData = 0;
81dcac ¤   ¤   ¤   ¤   tbbNew[3].iString = -1;
f587c7 ¤   ¤   ¤
14d0ec ¤   ¤   ¤   ¤   tbbNew[4].iBitmap = _itbmPgpKeys;
c09fb9 ¤   ¤   ¤   ¤   tbbNew[4].idCommand = _cmdidPgpKeys;
8e1062 ¤   ¤   ¤   ¤   tbbNew[4].fsState = TBSTATE_ENABLED;
129243 ¤   ¤   ¤   ¤   tbbNew[4].fsStyle = TBSTYLE_BUTTON;
26db05 ¤   ¤   ¤   ¤   tbbNew[4].dwData = 0;
87ac81 ¤   ¤   ¤   ¤   tbbNew[4].iString = -1;
e987c7 ¤   ¤   ¤
e4e087 ¤   ¤   ¤   ¤   SendMessage(_hwndSendToolbar, TB_ADDBUTTONS, 5,·
598c57 ¤   ¤   ¤   ¤   ¤   (LPARAM) tbbNew);
30a3a6 ¤   ¤   ¤   }
b10fe4 ¤   ¤   }
e62f68 ¤   ¤   break;
73af5a
ea0d08 ····case EECONTEXT_SENDPOSTMESSAGE:
142f68 ¤   ¤   break;
6e869e ····
6e4477 ¤   case EECONTEXT_READNOTEMESSAGE:
a35b34 ¤   ¤   {
79e6ef ¤   ¤   ¤   BOOL fAddButtons = TRUE;
7a685c ¤   ¤   ¤   int nNumButtons;
aa114f ¤   ¤   ¤   int nIndex;
4be546 ¤   ¤   ¤   TBBUTTON tbbNew[5];
71cacd ¤   ¤   ¤   TBBUTTON tbbCheck;
de9807 ¤   ¤   ¤   BOOL FYEO;
c6af5a
b2309f ¤   ¤   ¤   // Check to make sure the buttons aren't already on the toolbar
53af5a
ce1363 ¤   ¤   ¤   nNumButtons = SendMessage(_hwndReadToolbar, TB_BUTTONCOUNT, 0, 0);
944473 ¤   ¤   ¤   for (nIndex=0; nIndex<nNumButtons; nIndex++)
7af776 ¤   ¤   ¤   {
3543ec ¤   ¤   ¤   ¤   SendMessage(_hwndReadToolbar, TB_GETBUTTON,·
6239cc ¤   ¤   ¤   ¤   ¤   ¤   ¤   (WPARAM) nIndex, (LPARAM) &tbbCheck);
48af5a
e442c5 ¤   ¤   ¤   ¤   // If a button exists with the same bitmap ID and command ID
bc32de ¤   ¤   ¤   ¤   // as the Decrypt button, odds are good that the button is
80f1c7 ¤   ¤   ¤   ¤   // already on the toolbar
b65e72 ¤   ¤   ¤   ¤   if ((tbbCheck.iBitmap == (int)_itbmDecrypt) &&·
8985e2 ¤   ¤   ¤   ¤   ¤   (tbbCheck.idCommand == (int)_cmdidDecrypt))
9372c3 ¤   ¤   ¤   ¤   {
4a95e2 ¤   ¤   ¤   ¤   ¤   fAddButtons = FALSE;
5b66d4 ¤   ¤   ¤   ¤   ¤   nIndex = nNumButtons;
c92613 ¤   ¤   ¤   ¤   }
3ca3a6 ¤   ¤   ¤   }
--aa71 00071b84ab24011030d Page 3 of MessageEvents.cpp
e0af5a
f0a4f3 ¤   ¤   ¤   if (fAddButtons)
dcf776 ¤   ¤   ¤   {
a10e33 ¤   ¤   ¤   ¤   tbbNew[0].iBitmap = 0;
63afbc ¤   ¤   ¤   ¤   tbbNew[0].idCommand = 0;
40cd3e ¤   ¤   ¤   ¤   tbbNew[0].fsState = 0;
830e66 ¤   ¤   ¤   ¤   tbbNew[0].fsStyle = TBSTYLE_SEP;
f6f3bc ¤   ¤   ¤   ¤   tbbNew[0].dwData = 0;
c9ecbd ¤   ¤   ¤   ¤   tbbNew[0].iString = -1;
cb87c7 ¤   ¤   ¤
3c4199 ¤   ¤   ¤   ¤   tbbNew[1].iBitmap = _itbmDecrypt;
3abe8a ¤   ¤   ¤   ¤   tbbNew[1].idCommand = _cmdidDecrypt;
35b35d ¤   ¤   ¤   ¤   tbbNew[1].fsState = TBSTATE_ENABLED;
d09785 ¤   ¤   ¤   ¤   tbbNew[1].fsStyle = TBSTYLE_BUTTON;
5fbb96 ¤   ¤   ¤   ¤   tbbNew[1].dwData = 0;
83fcb2 ¤   ¤   ¤   ¤   tbbNew[1].iString = -1;
a687c7 ¤   ¤   ¤
d91a02 ¤   ¤   ¤   ¤   tbbNew[2].iBitmap = 0;
c55663 ¤   ¤   ¤   ¤   tbbNew[2].idCommand = 0;
4bd90f ¤   ¤   ¤   ¤   tbbNew[2].fsState = 0;
9d9cd7 ¤   ¤   ¤   ¤   tbbNew[2].fsStyle = TBSTYLE_SEP;
5363e8 ¤   ¤   ¤   ¤   tbbNew[2].dwData = 0;
69cca3 ¤   ¤   ¤   ¤   tbbNew[2].iString = -1;
1787c7 ¤   ¤   ¤
3f6705 ¤   ¤   ¤   ¤   tbbNew[3].iBitmap = _itbmPgpKeys;
7d7d60 ¤   ¤   ¤   ¤   tbbNew[3].idCommand = _cmdidPgpKeys;
7af2bb ¤   ¤   ¤   ¤   tbbNew[3].fsState = TBSTATE_ENABLED;
576df6 ¤   ¤   ¤   ¤   tbbNew[3].fsStyle = TBSTYLE_BUTTON;
392bc2 ¤   ¤   ¤   ¤   tbbNew[3].dwData = 0;
e0dcac ¤   ¤   ¤   ¤   tbbNew[3].iString = -1;
5a87c7 ¤   ¤   ¤
77660e ¤   ¤   ¤   ¤   SendMessage(_hwndReadToolbar, TB_ADDBUTTONS, 4,·
e38c57 ¤   ¤   ¤   ¤   ¤   (LPARAM) tbbNew);
2ba3a6 ¤   ¤   ¤   }
c6af5a
a37241 ¤   ¤   ¤   IMAPISession* psess;
45af5a
28e649 ¤   ¤   ¤   HRESULT hr = peecb->GetSession(&psess, NULL);
7093e8 ¤   ¤   ¤   if (FAILED(hr))
e4f776 ¤   ¤   ¤   {
b3eef2 ¤   ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOSESSION);
06c884 ¤   ¤   ¤   ¤   return S_FALSE;
56a3a6 ¤   ¤   ¤   }
e887c7 ¤   ¤   ¤
c44689 ¤   ¤   ¤   if (AutoDecrypt(_memoryMgr))
07f776 ¤   ¤   ¤   {
660543 ¤   ¤   ¤   ¤   IMessage *pmsg = 0;
5e927d ¤   ¤   ¤   ¤   STATSTG StreamStats;
07c529 ¤   ¤   ¤   ¤   DWORD dwInSize;
cac4ef ¤   ¤   ¤   ¤   UINT nOutSize;
715335 ¤   ¤   ¤   ¤   char *pInput;
970d12 ¤   ¤   ¤   ¤   char *pOutput = NULL;
c04973 ¤   ¤   ¤   ¤   BOOL bGotHTML = FALSE;
94c88e ¤   ¤   ¤   ¤   PGPError nError = kPGPError_NoErr;
360cc6 ¤   ¤   ¤   ¤   char szFile[256];
7094b8 ¤   ¤   ¤   ¤   char szName[256];
4daf5a
57672a ¤   ¤   ¤   ¤   UIGetString(szName, sizeof(szName), IDS_LOGNAME);
b858e4 ¤   ¤   ¤   ¤   UIGetString(szFile, sizeof(szFile), IDS_DLL);
af2b85 ¤   ¤   ¤   ¤
c78ae9 ¤   ¤   ¤   ¤   CWaitCursor wait; // Mark busy
762b85 ¤   ¤   ¤   ¤
65f696 ¤   ¤   ¤   ¤   hr = peecb->GetObject(NULL, (IMAPIProp**)&pmsg);
0e3eb6 ¤   ¤   ¤   ¤   if (FAILED(hr))
f672c3 ¤   ¤   ¤   ¤   {
5ce436 ¤   ¤   ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOMESSAGE);
094378 ¤   ¤   ¤   ¤   ¤   return S_FALSE;
382613 ¤   ¤   ¤   ¤   }
0e2b85 ¤   ¤   ¤   ¤
98868a ¤   ¤   ¤   ¤   IStream *pstrmBody = 0;
b8af5a
7171da ¤   ¤   ¤   ¤   hr = pmsg->OpenProperty(PR_BODY_HTML, &IID_IStream,·
--6461 0009c29b2004011030d Page 4 of MessageEvents.cpp
e14baa ¤   ¤   ¤   ¤   ¤   STGM_READWRITE, MAPI_MODIFY, (IUnknown**)&pstrmBody);
2a2b85 ¤   ¤   ¤   ¤
683eb6 ¤   ¤   ¤   ¤   if (FAILED(hr))
f472c3 ¤   ¤   ¤   ¤   {
2b3697 ¤   ¤   ¤   ¤   ¤   hr = pmsg->OpenProperty(PR_BODY, &IID_IStream,·
e432e0 ¤   ¤   ¤   ¤   ¤   ¤   STGM_READWRITE, MAPI_MODIFY, (IUnknown**)&pstrmBody);
952613 ¤   ¤   ¤   ¤   }
57fa07 ¤   ¤   ¤   ¤   else
fcb200 ¤   ¤   ¤   ¤   ¤   bGotHTML = TRUE;
7daf5a
ed3eb6 ¤   ¤   ¤   ¤   if (FAILED(hr))
ce72c3 ¤   ¤   ¤   ¤   {
ebe77c ¤   ¤   ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOBODY);
32cf22 ¤   ¤   ¤   ¤   ¤   pmsg->Release();
50b52f ¤   ¤   ¤   ¤   ¤   psess->Release();
a04378 ¤   ¤   ¤   ¤   ¤   return S_FALSE;
842613 ¤   ¤   ¤   ¤   }
542b85 ¤   ¤   ¤   ¤
b94d44 ¤   ¤   ¤   ¤   pstrmBody->Stat(&StreamStats, STATFLAG_NONAME);
b2e362 ¤   ¤   ¤   ¤   dwInSize = StreamStats.cbSize.LowPart;
452b85 ¤   ¤   ¤   ¤
178527 ¤   ¤   ¤   ¤   pInput = (char *) calloc(dwInSize+1, sizeof(char));
cc4011 ¤   ¤   ¤   ¤   if (!pInput)
2b72c3 ¤   ¤   ¤   ¤   {
1e82df ¤   ¤   ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOMEMORY);
b35860 ¤   ¤   ¤   ¤   ¤   pstrmBody->Release();
3dcf22 ¤   ¤   ¤   ¤   ¤   pmsg->Release();
06b52f ¤   ¤   ¤   ¤   ¤   psess->Release();
bf4378 ¤   ¤   ¤   ¤   ¤   return S_FALSE;
e62613 ¤   ¤   ¤   ¤   }
0338e8 ¤   ¤   ¤   ¤   pstrmBody->Read(pInput, dwInSize, &dwInSize);
583bcc ¤   ¤   ¤   ¤   pInput[dwInSize] = 0;
962b85 ¤   ¤   ¤   ¤
4d4031 ¤   ¤   ¤   ¤   if (AutoDecrypt(_memoryMgr))
5d72c3 ¤   ¤   ¤   ¤   {
e7ca1b ¤   ¤   ¤   ¤   ¤   nError = DecryptVerifyBuffer(UIGetInstance(), hwnd,·
725de4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   _pgpContext, _tlsContext, szName,·
54bd58 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFile, pInput, dwInSize,·
100086 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   FALSE, (VOID ** )&pOutput, &nOutSize, &FYEO);
4faf5a
15249d ¤   ¤   ¤   ¤   ¤   if (IsntPGPError(nError) && (nOutSize > 0) &&·
5f3cbd ¤   ¤   ¤   ¤   ¤   ¤   (pOutput != NULL))
554859 ¤   ¤   ¤   ¤   ¤   {
9eeac8 ¤   ¤   ¤   ¤   ¤   ¤   LARGE_INTEGER li = {0,0};
59d7dd ¤   ¤   ¤   ¤   ¤   ¤   ULARGE_INTEGER uli = {nOutSize, 0};
8ce87f ¤   ¤   ¤   ¤   ¤   ¤   BOOL fPartied;
2a2c00 ¤   ¤   ¤   ¤   ¤   ¤   char *szBuffer = NULL;
6994aa ¤   ¤   ¤   ¤   ¤   ¤
d62e1c ¤   ¤   ¤   ¤   ¤   ¤   // Alter only the block of encrypted/signed text
ad6526 ¤   ¤   ¤   ¤   ¤   ¤   // if this is not HTML
60af5a
443d93 ¤   ¤   ¤   ¤   ¤   ¤   if (FYEO)
fe8fec ¤   ¤   ¤   ¤   ¤   ¤   {
d9f334 ¤   ¤   ¤   ¤   ¤   ¤   ¤   TempestViewer((void *)_pgpContext,hwnd,
b49950 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pOutput,nOutSize);
f9db3c ¤   ¤   ¤   ¤   ¤   ¤   }
d77f8b ¤   ¤   ¤   ¤   ¤   ¤   else
e68fec ¤   ¤   ¤   ¤   ¤   ¤   {
e1bc35 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szBuffer = (char *) calloc(dwInSize+nOutSize+1,·
e9aa13 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(char));
54af5a
badc12 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szBuffer, pOutput);
f6af5a
be988e ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (strlen(szBuffer) > 0)
6a06b8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   {
035f43 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   uli.LowPart = strlen(szBuffer);
523437 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pstrmBody->Seek(li, STREAM_SEEK_SET, NULL);
2d9be4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pstrmBody->Write(szBuffer, strlen(szBuffer),·
7f474e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   NULL);
b9c0c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pstrmBody->SetSize(uli);
e87fca ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pstrmBody->Commit(STGC_DEFAULT);
9c809a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pstrmBody->Release();
--d1d7 0002dd0fe3a4011030d Page 5 of MessageEvents.cpp
e25ca2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   RTFSync(pmsg, RTF_SYNC_BODY_CHANGED,·
a40aec ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   &fPartied);
705268 ¤   ¤   ¤   ¤   ¤   ¤   ¤   }
3267c5 ¤
64c36e ¤   ¤   ¤   ¤   ¤   ¤   ¤   free(szBuffer);
74db3c ¤   ¤   ¤   ¤   ¤   ¤   }
74af5a
01b9c8 ¤   ¤   ¤   ¤   ¤   ¤   PGPFreeData(pOutput);
431c89 ¤   ¤   ¤   ¤   ¤   }
194bd6 ¤   ¤   ¤   ¤   ¤   else
8061a5 ¤   ¤   ¤   ¤   ¤   ¤   pstrmBody->Release();
212613 ¤   ¤   ¤   ¤   }
50fa07 ¤   ¤   ¤   ¤   else
df5860 ¤   ¤   ¤   ¤   ¤   pstrmBody->Release();
ccaf5a
c73ace ¤   ¤   ¤   ¤   free(pInput);
f5f24a ¤   ¤   ¤   ¤   pmsg->Release();
baa3a6 ¤   ¤   ¤   }
1687c7 ¤   ¤   ¤
f16d54 ¤   ¤   ¤   psess->Release();
2b0fe4 ¤   ¤   }
a22f68 ¤   ¤   break;
f5af5a
8c70b2 ¤   case EECONTEXT_READPOSTMESSAGE:
ba2f68 ¤   ¤   break;
a8af5a
f02f72 ¤   default:
a48fa4 ¤   ¤   // This way, the function defends itself against unknown future
2d1a2a ¤   ¤   // variants, as FindREOnNote is less robust than it might be.
f593bf ¤   ¤   return S_FALSE;
dc9371 ¤   }
67af5a
f6e94b ¤   return S_FALSE;
0befe6 }
17af5a
77af5a
d0f4a5 STDMETHODIMP CExtImpl::OnReadComplete(IExchExtCallback* peecb, ULONG ulFlags)
c5bb36 {
a0e94b ¤   return S_FALSE;
8befe6 }
a4af5a
faaf5a
ccc3ff STDMETHODIMP CExtImpl::OnWrite(IExchExtCallback* pecb)
2fbb36 {
2a3f6c ¤   // The prewrite handler stamps this message as having been processed.
615f13 ¤   // This prevents the extension from munging the message body twice.
b2af5a
a0f5ac ¤   if (_context != EECONTEXT_SENDNOTEMESSAGE)
f493bf ¤   ¤   return S_FALSE;
0daf5a
a754ce ¤   CWaitCursor wait; // Mark busy
62311b ¤   HRESULT hr = _msgtype.Write(pecb, _fInSubmitState);
671f79 ¤   if (FAILED(hr))
8b95ce ¤   ¤   return hr;
52af5a
91e94b ¤   return S_FALSE;
6defe6 }
67af5a
b2af5a
a4c6a2 STDMETHODIMP CExtImpl::OnWriteComplete(IExchExtCallback* pecb, ULONG ulFlags)
94bb36 {
d3f5ac ¤   if (_context != EECONTEXT_SENDNOTEMESSAGE)
de93bf ¤   ¤   return S_FALSE;
48af5a
bc7dfd ¤   if (ulFlags == EEME_COMPLETE_FAILED) // Nothing to unwind
f793bf ¤   ¤   return S_FALSE;
dbaf5a
2f883e ¤   if (!_fInSubmitState)¤  // This is not a submission.
ab93bf ¤   ¤   return S_FALSE;
f4af5a
92a7fd ¤   if (_bEncrypt || _bSign)
2dc7a1 ¤   {
--2110 000c82327d04011030d Page 6 of MessageEvents.cpp
9723e1 ¤   ¤   IMessage *pmsg = 0;
9be391 ¤   ¤   RECIPIENTDIALOGSTRUCT *prds;
dc6688 ¤   ¤   PGPOptionListRef signOptions = NULL;
29b76c ¤   ¤   HWND hwnd;
c681a4 ¤   ¤   PGPError nError = kPGPError_NoErr;
52af5a
27bd2d ¤   ¤   pecb->GetWindow(&hwnd);
3d49af ¤   ¤   if (!hwnd)
cbe917 ¤   ¤   ¤   hwnd = GetTopWindow(NULL);
ef1b52 ¤   ¤
15153d ¤   ¤   CWaitCursor wait; // Mark busy
e01b52 ¤   ¤
adb404 ¤   ¤   HRESULT hr = pecb->GetObject(NULL, (IMAPIProp**)&pmsg);
82658d ¤   ¤   if (FAILED(hr))
965b34 ¤   ¤   {
e30541 ¤   ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOMESSAGE);
6d2b0a ¤   ¤   ¤   return E_ABORT;
960fe4 ¤   ¤   }
efaf5a
d2eb0d ¤   ¤   prds = (RECIPIENTDIALOGSTRUCT *)·
b4c933 ¤   ¤   ¤   ¤   calloc(sizeof(RECIPIENTDIALOGSTRUCT), 1);¤
14af5a
209a83 ¤   ¤   nError = PGPsdkLoadDefaultPrefs(_pgpContext);
23aa6a ¤   ¤   if (IsPGPError(nError))
015b34 ¤   ¤   {
db4587 ¤   ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, NULL, nError);
a22b0a ¤   ¤   ¤   return E_ABORT;
290fe4 ¤   ¤   }
d5af5a
f6fc8c ¤   ¤   nError = PGPOpenDefaultKeyRings(_pgpContext, (PGPKeyRingOpenFlags)0,·
83c210 ¤   ¤   ¤   ¤   ¤   &(prds->OriginalKeySetRef));
0eaf5a
c2aa6a ¤   ¤   if (IsPGPError(nError))
c45b34 ¤   ¤   {
be4587 ¤   ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, NULL, nError);
862b0a ¤   ¤   ¤   return E_ABORT;
d70fe4 ¤   ¤   }
81af5a
897f65 ¤   ¤   if (_bEncrypt)
a4ab1f ¤   ¤   ¤   nError = GetRecipients(pecb, _pgpContext, _tlsContext, prds);
b7af5a
1faa6a ¤   ¤   if (IsPGPError(nError))
975b34 ¤   ¤   {
94e7ba ¤   ¤   ¤   if (nError != kPGPError_UserAbort)
c710b3 ¤   ¤   ¤   ¤   UIDisplayErrorCode(__FILE__, __LINE__, NULL,·
f56819 ¤   ¤   ¤   ¤   ¤   nError);
dc2b0a ¤   ¤   ¤   return E_ABORT;
230fe4 ¤   ¤   }
b7af5a
36d270 ¤   ¤   nError = EncryptSignMessage(hwnd, pmsg, prds, &signOptions);
31af5a
cc4493 ¤   ¤   if (signOptions != NULL)
bd5b34 ¤   ¤   {
a8b846 ¤   ¤   ¤   PGPFreeOptionList(signOptions);
9326e2 ¤   ¤   ¤   signOptions = NULL;
2a0fe4 ¤   ¤   }
03af5a
0ae156 ¤   ¤   FreeRecipients(prds);
f8af5a
c597d2 ¤   ¤   if (IsntNull(prds->OriginalKeySetRef))
575b34 ¤   ¤   {
e0bb2e ¤   ¤   ¤   PGPFreeKeySet(prds->OriginalKeySetRef);
0281d7 ¤   ¤   ¤   prds->OriginalKeySetRef = NULL;
4d0fe4 ¤   ¤   }
ceaf5a
8cd708 ¤   ¤   free(prds);
157d41 ¤   ¤   pmsg->Release();
41af5a
01aa6a ¤   ¤   if (IsPGPError(nError))
922b0a ¤   ¤   ¤   return E_ABORT;
f49371 ¤   }
c8af5a
--5190 00095d66a874011030d Page 7 of MessageEvents.cpp
58e94b ¤   return S_FALSE;
8aefe6 }
ddaf5a
15af5a
534e90 STDMETHODIMP CExtImpl::OnCheckNames(IExchExtCallback*)
6cbb36 {
7fe94b ¤   return S_FALSE;
10efe6 }
21af5a
bcaf5a
961b61 STDMETHODIMP CExtImpl::OnCheckNamesComplete(IExchExtCallback*, ULONG)
a5bb36 {
c6e94b ¤   return S_FALSE;
45efe6 }
89af5a
beaf5a
bb274a STDMETHODIMP CExtImpl::OnSubmit(IExchExtCallback*)
5abb36 {
9dca9b ¤   _fInSubmitState = TRUE;
9fe94b ¤   return S_FALSE;
36efe6 }
89af5a
56af5a
158f77 STDMETHODIMP_(VOID) CExtImpl::OnSubmitComplete(IExchExtCallback*, ULONG)
e0bb36 {
2a1bd3 ¤   _fInSubmitState = FALSE;
b3830f ¤   return;
26efe6 }
b9af5a
85af5a
6f98bd int CExtImpl::EncryptSignMessage(HWND hwnd,
d20f4d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·IMessage *pmsg,
2b5b51 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·RECIPIENTDIALOGSTRUCT *prds,
9b4043 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef *pSignOptions)
08bb36 {
2c657d ¤   IStream *pstrmBody = 0;
4a201e ¤   STATSTG StreamStats;
efe4e6 ¤   DWORD dwInSize;
4f09cf ¤   UINT nOutSize;
35725f ¤   BOOL bExchangeUser = FALSE;
35274e ¤   char *pInput;
055c3d ¤   char *pOutput = NULL;
6abfee ¤   LPMAPITABLE ptableAttach = 0;
80d5ac ¤   SizedSPropTagArray(1, tagaTable) = {
266462 ¤   ¤   ¤   1, {PR_ATTACH_NUM}};
93375e ¤   SRowSet *prAttach = 0;
2a8fe8 ¤   PGPError nError = kPGPError_NoErr;
d0094a ¤   HRESULT hr;
c4ed51 ¤   char szName[256];
15752f ¤   char szFile[256];
95af5a
c13a44 ¤   UIGetString(szName, sizeof(szName), IDS_LOGNAME);
051792 ¤   UIGetString(szFile, sizeof(szFile), IDS_DLL);
abaf5a
5b72eb ¤   pmsg->GetAttachmentTable(0, &ptableAttach);
66e09f ¤   HrQueryAllRows(ptableAttach, (SPropTagArray *)&tagaTable,·
693db3 ¤   ¤   ¤   ¤   ¤   NULL, NULL, 0, &prAttach);
fdaf5a
cdd17a ¤   hr = pmsg->OpenProperty(PR_BODY, &IID_IStream, STGM_READWRITE,·
110140 ¤   ¤   MAPI_MODIFY, (IUnknown**)&pstrmBody);
b41f79 ¤   if (FAILED(hr))
a9c7a1 ¤   {
3a29d2 ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOBODY);
455ada ¤   ¤   ptableAttach->Release();
f9e8e7 ¤   ¤   return kPGPError_ItemNotFound;
929371 ¤   }
441b52 ¤   ¤
0b53a3 ¤   pstrmBody->Stat(&StreamStats, STATFLAG_NONAME);
c6bb6f ¤   dwInSize = StreamStats.cbSize.LowPart;
2f1b52 ¤   ¤
60f302 ¤   pInput = (char *) calloc(dwInSize+1, sizeof(char));
958416 ¤   if (!pInput)
--a489 0005dd84d694011030d Page 8 of MessageEvents.cpp
f7c7a1 ¤   {
029842 ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOMEMORY);
8fbcf5 ¤   ¤   pstrmBody->Release();
cd5ada ¤   ¤   ptableAttach->Release();
954030 ¤   ¤   return kPGPError_OutOfMemory;
c59371 ¤   }
cb779e ¤   pstrmBody->Read(pInput, dwInSize, &dwInSize);
8c6ae3 ¤   pInput[dwInSize] = 0;
7aaf5a
e34e5f ¤   nError = EncryptSignBuffer(UIGetInstance(), hwnd, _pgpContext,·
f1416a ¤   ¤   ¤   ¤   _tlsContext, szName, szFile, pInput,·
e9774b ¤   ¤   ¤   ¤   dwInSize, prds, NULL, pSignOptions, (VOID ** )&pOutput,·
429fb2 ¤   ¤   ¤   ¤   &nOutSize, _bEncrypt, _bSign, FALSE);
4daf5a
edb34d ¤   if ((dwInSize > 0) && IsntPGPError(nError))
2ec7a1 ¤   {
0f4fae ¤   ¤   LARGE_INTEGER li = {0,0};
db5b62 ¤   ¤   ULARGE_INTEGER uli = {1,0};
b7d33a ¤   ¤   BOOL fPartied;
9aaf5a
d942c0 ¤   ¤   pstrmBody->Seek(li, STREAM_SEEK_SET, NULL);
c9915b ¤   ¤   pstrmBody->Write("\0", 1, NULL);
879048 ¤   ¤   pstrmBody->SetSize(uli);
e2eb5b ¤   ¤   pstrmBody->Commit(STGC_DEFAULT);
68bcf5 ¤   ¤   pstrmBody->Release();
54cb93 ¤   ¤   RTFSync(pmsg, RTF_SYNC_BODY_CHANGED, &fPartied);
a4af5a
a3a788 ¤   ¤   pmsg->OpenProperty(PR_BODY, &IID_IStream, STGM_READWRITE,·
bd4e7e ¤   ¤   ¤   MAPI_MODIFY, (IUnknown**)&pstrmBody);
be9371 ¤   }
12af5a
fcbc7b ¤   if (IsntPGPError(nError))
ffc7a1 ¤   {
384fae ¤   ¤   LARGE_INTEGER li = {0,0};
f65bd3 ¤   ¤   ULARGE_INTEGER uli = {nOutSize + prAttach->cRows, 0};
43d33a ¤   ¤   BOOL fPartied;
34af5a
8842c0 ¤   ¤   pstrmBody->Seek(li, STREAM_SEEK_SET, NULL);
937b96 ¤   ¤   pstrmBody->Write(pOutput, nOutSize, NULL);
4f9048 ¤   ¤   pstrmBody->SetSize(uli);
41eb5b ¤   ¤   pstrmBody->Commit(STGC_DEFAULT);
78bcf5 ¤   ¤   pstrmBody->Release();
73cb93 ¤   ¤   RTFSync(pmsg, RTF_SYNC_BODY_CHANGED, &fPartied);
0f6498 ¤   ¤   PGPFreeData(pOutput);
609371 ¤   }
930e24 ¤   else
0dbcf5 ¤   ¤   pstrmBody->Release();
f41b52 ¤   ¤
584eb5 ¤   free(pInput);
d9af5a
f3b4f4 ¤   hr = pmsg->OpenProperty(PR_BODY_HTML, &IID_IStream, STGM_READWRITE,·
610140 ¤   ¤   MAPI_MODIFY, (IUnknown**)&pstrmBody);
15af5a
c91f79 ¤   if (FAILED(hr))
98d73e ¤   ¤   goto NoBodyHTML;
600e24 ¤   else
54c7a1 ¤   {
394fae ¤   ¤   LARGE_INTEGER li = {0,0};
5f5b62 ¤   ¤   ULARGE_INTEGER uli = {1,0};
9bd33a ¤   ¤   BOOL fPartied;
c7af5a
0742c0 ¤   ¤   pstrmBody->Seek(li, STREAM_SEEK_SET, NULL);
9a915b ¤   ¤   pstrmBody->Write("\0", 1, NULL);
d99048 ¤   ¤   pstrmBody->SetSize(uli);
89eb5b ¤   ¤   pstrmBody->Commit(STGC_DEFAULT);
7abcf5 ¤   ¤   pstrmBody->Release();
9acb93 ¤   ¤   RTFSync(pmsg, RTF_SYNC_BODY_CHANGED, &fPartied);
519371 ¤   }
60af5a
00d3f1 NoBodyHTML:
2ef073 ¤   if (prAttach->cRows && IsntPGPError(nError))
5d5bc6 ¤   ¤   nError = EncryptSignAttachment(hwnd, pmsg, nOutSize,
--2b28 0016083de524011030d Page 9 of MessageEvents.cpp
67f447 ¤   ¤   ¤   ¤   ¤   prAttach, prds, pSignOptions);
01af5a
3de18c ¤   ptableAttach->Release();
3d9909 ¤   return nError;
d0efe6 }
f6af5a
95af5a
94af5a
907e4d /*__Editor_settings____
48af5a
624126 ¤   Local Variables:
f07b17 ¤   tab-width: 4
360e6c ¤   End:
cb5f8c ¤   vi: ts=4 sw=4
979e9b ¤   vim: si
60d062 _____________________*/
--8143 0003ad231ac4011030e Page 1 of MsgProps.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
280972 ¤   $Id: MsgProps.cpp,v 1.5.16.1 1998/11/12 03:13:59 heller Exp $
cbf7f7 ____________________________________________________________________________*/
8b5d3c #include "stdinc.h"
d50804 #include "guids.h"
7c9803 #include "Exchange.h"
4a8031 #include "resource.h"
16adf9 #include "UIutils.h"
feaf5a
25af5a
9ff0b8 CDecrypt::CDecrypt(IMAPISession* psess)·
e62dde ¤   : _psess(psess), _fInit(FALSE)
5cbb36 {
3dcaf5 ¤   if (psess)
010286 ¤   ¤   psess->AddRef();
7aefe6 }
eeaf5a
f3af5a
4a2131 CDecrypt::~CDecrypt()
9d7142 {·
458cce ¤   if (_psess)
331edb ¤   ¤   _psess->Release();
87efe6 }
7baf5a
c8af5a
2c3eb3 void CDecrypt::TakeSession(IMAPISession* psess)
b2bb36 {
b28cce ¤   if (_psess)
691edb ¤   ¤   _psess->Release();
36a336 ¤   _psess = psess;
fccaf5 ¤   if (psess)
7d0286 ¤   ¤   psess->AddRef();
9befe6 }
7faf5a
25af5a
3f595b void CDecrypt::DropSession()
1bbb36 {
538cce ¤   if (_psess)
491edb ¤   ¤   _psess->Release();
11bb42 ¤   _psess = NULL;
91efe6 }
eeaf5a
94af5a
12ee12 void CDecrypt::Load()
ffbb36 {
91e751 ¤   // If we hit any exceptions, initialize as empty anyway.
71af5a
65783e ¤   _fInit = TRUE;
f1af5a
7ed12e ¤   IProfSect* pprof;
ae3aa3 ¤   HRESULT hr = _psess->OpenProfileSection(
3b30d7 ¤   ¤   (LPMAPIUID)&GUID_PGPPlugin, NULL, 0, &pprof);
8535e3 ¤   if (FAILED(hr)) // Assume uninitialized
0099bf ¤   ¤   return;
1caf5a
0b80c4 ¤   pprof->Release();
8fefe6 }
1faf5a
19af5a
e0e3aa void CDecrypt::Save()
5dbb36 {
4ad12e ¤   IProfSect* pprof;
f83aa3 ¤   HRESULT hr = _psess->OpenProfileSection(
f7edf3 ¤   ¤   (LPMAPIUID)&GUID_PGPPlugin, NULL, MAPI_MODIFY, &pprof);
b0aaa9 ¤   if (pprof)
674771 ¤   ¤   pprof->Release();
3aaf5a
--22ac 001685f5c554011030e Page 2 of MsgProps.cpp
991f79 ¤   if (FAILED(hr))
c0c7a1 ¤   {
78d968 ¤   ¤   UIDisplayStringID(NULL, IDS_E_SAVEPROFILE );
b09371 ¤   }
feaf5a
0eefe6 }
81af5a
0eaf5a
79af5a
19af5a
547e4d /*__Editor_settings____
68af5a
514126 ¤   Local Variables:
c57b17 ¤   tab-width: 4
ab0e6c ¤   End:
f25f8c ¤   vi: ts=4 sw=4
a49e9b ¤   vim: si
68d062 _____________________*/
--3f97 0012f9a1bdd4011030f Page 1 of PropertySheets.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ce15c9 ¤   $Id: PropertySheets.cpp,v 1.4.16.1 1998/11/12 03:13:59 heller Exp $
21f7f7 ____________________________________________________________________________*/
455d3c #include "stdinc.h"
e89803 #include "Exchange.h"
a1af5a
f84b8e STDMETHODIMP_(ULONG) CExtImpl::GetMaxPageCount(ULONG ulFlags) ·········
d3bb36 {
663e6b ¤   return 0;
69efe6 }
e2af5a
b2af5a
789ce8 STDMETHODIMP CExtImpl::GetPages(IExchExtCallback* peecb,
0bb92a ¤   ULONG ulFlags, LPPROPSHEETPAGE ppsp, ULONG * pcpsp)
acbb36 {
28e94b ¤   return S_FALSE;
b1efe6 }
28af5a
e4af5a
5a6ec3 STDMETHODIMP_(VOID) CExtImpl::FreePages(LPPROPSHEETPAGE ppsp,·
675ebb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ULONG ulFlags, ULONG cpsp)
09bb36 {
1c830f ¤   return;
8eefe6 }
baaf5a
e8af5a
457e4d /*__Editor_settings____
ddaf5a
d94126 ¤   Local Variables:
8f7b17 ¤   tab-width: 4
a80e6c ¤   End:
175f8c ¤   vi: ts=4 sw=4
cc9e9b ¤   vim: si
2fd062 _____________________*/
--4aec 00011f26f8840110310 Page 1 of Recipients.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
3d776a ¤   $Id: Recipients.cpp,v 1.21.2.5.2.1 1998/11/12 03:14:00 heller Exp $
fff7f7 ____________________________________________________________________________*/
c85d3c #include "stdinc.h"
c7cd68 #include "Recipients.h"
46adf9 #include "UIutils.h"
fba076 #include "pgpKeys.h"
9b5ab2 #include "PGPcl.h"
7ca146 #include "pgpDebug.h"
150d08 #include "pgpMem.h"
6791b9 #include "pgpSDKPrefs.h"
74c97b #include "pgpClientPrefs.h"
f14919 #include "pgpUtilities.h"
258031 #include "resource.h"
14af5a
20e493 #ifndef PR_EMS_AB_PROXY_ADDRESSES
90531a #define PR_EMS_AB_PROXY_ADDRESSES¤  PROP_TAG( PT_MV_TSTRING, ···0x800F)
467454 #endif
4baf5a
20af5a
add4aa static void ResolveEntries(LPADRBOOK pAddrBook, LPABCONT pContainer,·
aebc78 ¤   ¤   ¤   ¤   ¤   ¤   ···ULONG ulNumRows, LPADRENTRY aEntries,·
a1628d ¤   ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds, DWORD *pdwNumRecip,·
da61f1 ¤   ¤   ¤   ¤   ¤   ¤   ···DWORD *pdwRecipIndex);
ecaf5a
7e1bc0 BOOL GetSMTPAddress(ULONG ulNum, LPSTR *lppszProxy,
3e6ac0 ¤   ¤   ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds,
65c0f5 ¤   ¤   ¤   ¤   ¤   DWORD *pdwRecipIndex, DWORD *pdwNumRecip,
86e09d ¤   ¤   ¤   ¤   ¤   char *szAddress, BOOL *pbRecipAdded);
ccaf5a
f5af5a
d7c20a PGPError GetRecipients(IExchExtCallback *pmecb,·
043420 ¤   ¤   ¤   ¤   ¤   ···PGPContextRef context,
85deb9 ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,
10c738 ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds)
adbb36 {
7a4467 ¤   LPADRLIST¤  ¤   pAddrList¤  ¤   = NULL;
6e322d ¤   LPADRBOOK¤  ¤   pAddrBook¤  ¤   = NULL;
05b733 ¤   LPABCONT¤   ¤   pContainer¤ ¤   = NULL;
257187 ¤   LPENTRYID¤  ¤   pEntryID¤   ¤   = NULL;
e83180 ¤   DWORD¤  ¤   ¤   dwNumRecip¤ ¤   = 0;
da9ee1 ¤   ULONG¤  ¤   ¤   ulRow¤  ¤   ¤   = 0;
94047d ¤   ULONG¤  ¤   ¤   ulIndex¤¤   ¤   = 0;
7b73ef ¤   ULONG¤  ¤   ¤   ulEntrySize¤¤   = 0;
ab0a85 ¤   char¤   ¤   ¤   szTitle[256];
85aa59 ¤   ULONG¤  ¤   ¤   ulNumRows¤  ¤   = 0;
1c0127 ¤   DWORD¤  ¤   ¤   dwRecipIndex¤   = 0;
383ec9 ¤   HWND¤   ¤   ¤   hwnd¤   ¤   ¤   = NULL;
89f387 ¤   BOOL¤   ¤   ¤   bGotRecipients¤ = FALSE;
cb1e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
95af5a
dbc677 ¤   pgpAssert(pmecb);
2265ed ¤   pgpAssert(prds);
a44ca6 ¤   pgpAssert(prds->OriginalKeySetRef);
18f34e ¤   pgpAssert(PGPRefIsValid(context));
8faf5a
3c6418 ¤   pmecb->GetWindow(&hwnd);
a5ab0c ¤   if (!hwnd)
3ca8e4 ¤   ¤   hwnd = GetTopWindow(NULL);
b8af5a
d2551c ¤   UIGetString(szTitle, sizeof(szTitle), IDS_RECIPIENTTITLE);
17af5a
12d97c ¤   prds->Version = CurrentPGPrecipVersion;
748cdc ¤   prds->hwndParent = hwnd;
cc9559 ¤   prds->szTitle = szTitle;
f430dc ¤   prds->Context = context;
11d67c ¤   prds->tlsContext = tlsContext;
--2457 0002cb54d0540110310 Page 2 of Recipients.cpp
692581 ¤   prds->SelectedKeySetRef = NULL;
b8afcd ¤   prds->szRecipientArray = NULL;
a54840 ¤   prds->dwOptions = PGPCL_ASCIIARMOR;
a05127 ¤   prds->dwFlags = 0;
9f0892 ¤   prds->dwDisableFlags = PGPCL_DISABLE_ASCIIARMOR |
2e2c3e ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_DISABLE_WIPEORIG;
e87225 ¤   prds->AddedKeys = NULL;
17af5a
6e61b6 ¤   pmecb->GetRecipients(&pAddrList);
55bb62 ¤   if (pAddrList)
c7c7a1 ¤   {
19d680 ¤   ¤   LPSRowSet pSearch = NULL;
dcd44c ¤   ¤   ULONG ulMatch = ULONG_MAX;
4bea03 ¤   ¤   ULONG ulObjType = 0;
4b768c ¤   ¤   SizedSPropTagArray(6, propTags) = {
84c746 ¤   ¤   ¤   6, {PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_OBJECT_TYPE, PR_ENTRYID,
532003 ¤   ¤   ¤   ¤   PR_ADDRTYPE, PR_EMS_AB_PROXY_ADDRESSES}};
78af5a
7ceb30 ¤   ¤   pmecb->GetSession(NULL, &pAddrBook);
73d40b ¤   ¤   pAddrBook->GetSearchPath(0, &pSearch);
12499f ¤   ¤   pAddrBook->PrepareRecips(0, (LPSPropTagArray) &propTags, pAddrList);
0daf5a
6c5474 ¤   ¤   for (ulRow=0; ulRow<pSearch->cRows; ulRow++)
835b34 ¤   ¤   {
d4cd03 ¤   ¤   ¤   for(ulIndex=0; ulIndex<pSearch->aRow[ulRow].cValues; ulIndex++)
73f776 ¤   ¤   ¤   {
cb9154 ¤   ¤   ¤   ¤   switch (pSearch->aRow[ulRow].lpProps[ulIndex].ulPropTag)
8372c3 ¤   ¤   ¤   ¤   {
578b9f ¤   ¤   ¤   ¤   case PR_DISPLAY_TYPE:
2edb97 ¤   ¤   ¤   ¤   ¤   if (pSearch->aRow[ulRow].lpProps[ulIndex].Value.l ==·
9e7845 ¤   ¤   ¤   ¤   ¤   ¤   DT_GLOBAL)
9eb9e8 ¤   ¤   ¤   ¤   ¤   ¤   ulMatch = ulRow;
0c14c3 ¤   ¤   ¤   ¤   ¤   break;
99af5a
4af9ac ¤   ¤   ¤   ¤   case PR_ENTRYID:
3813a2 ¤   ¤   ¤   ¤   ¤   ulEntrySize = pSearch->aRow[ulRow].
b5cfd3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lpProps[ulIndex].Value.bin.cb;
7f2b85 ¤   ¤   ¤   ¤
14238d ¤   ¤   ¤   ¤   ¤   pEntryID = (LPENTRYID) pSearch->aRow[ulRow].
6f6b2f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   lpProps[ulIndex].Value.bin.lpb;
0614c3 ¤   ¤   ¤   ¤   ¤   break;
1d2613 ¤   ¤   ¤   ¤   }
d8a3a6 ¤   ¤   ¤   }
c5af5a
fad8d5 ¤   ¤   ¤   if (ulMatch != ULONG_MAX)
4e5305 ¤   ¤   ¤   ¤   ulRow = pSearch->cRows;
960fe4 ¤   ¤   }
c9af5a
ac37a6 ¤   ¤   if (ulMatch != ULONG_MAX)
d0b8b8 ¤   ¤   ¤   pAddrBook->OpenEntry(ulEntrySize, pEntryID, &IID_IABContainer,
8890d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, &ulObjType, (IUnknown **) &pContainer);
0eaf5a
b453fd ¤   ¤   FreeProws(pSearch);
faefa7 ¤   ¤   dwNumRecip = pAddrList->cEntries;
4d9371 ¤   }
c30e24 ¤   else
5dc7a1 ¤   {
efbc21 ¤   ¤   prds->dwNumRecipients = 0;
f7c9db ¤   ¤   return err;
459371 ¤   }
c02b85 ¤   ¤   ¤   ¤
51d28d ¤   ulNumRows = dwNumRecip;
9f8bfc ¤   prds->szRecipientArray = (char **) calloc(sizeof(char *), dwNumRecip);
b067c5 ¤
90840b ¤   ResolveEntries(pAddrBook, pContainer, ulNumRows,·
c58bb1 ¤   ¤   pAddrList->aEntries, prds, &dwNumRecip, &dwRecipIndex);
3daf5a
492441 ¤   prds->dwNumRecipients = dwNumRecip;
b9af5a
453388 ¤   if (pContainer != NULL)
6c2993 ¤   ¤   pContainer->Release();
2caf5a
--be89 0007bf107fa40110310 Page 3 of Recipients.cpp
324b5e ¤   if (pAddrBook != NULL)
faa251 ¤   ¤   pAddrBook->Release();
c2af5a
936c5f ¤   // If shift is pressed, force the dialog to pop.
9b196e ¤   if (GetAsyncKeyState( VK_SHIFT) & 0x8000)
06acd2 ¤   ¤   prds->dwDisableFlags|=PGPCL_DISABLE_AUTOMODE;
f6af5a
ec9fbb ¤   bGotRecipients = PGPclRecipientDialog(prds);
6daf5a
404ff7 ¤   if (prds->AddedKeys != NULL)
f5c7a1 ¤   {
b92bca ¤   ¤   PGPUInt32 numKeys;
16af5a
03d400 ¤   ¤   PGPCountKeys(prds->AddedKeys, &numKeys);
9cf327 ¤   ¤   if (numKeys > 0)
3f96e9 ¤   ¤   ¤   PGPclQueryAddKeys(context, tlsContext, hwnd,·
eda4bd ¤   ¤   ¤   ¤   prds->AddedKeys, NULL);
80af5a
674d58 ¤   ¤   PGPFreeKeySet(prds->AddedKeys);
cddf7b ¤   ¤   prds->AddedKeys = NULL;
f29371 ¤   }
46af5a
705b65 ¤   if (bGotRecipients != TRUE)
02c7a1 ¤   {
6f0fd8 ¤   ¤   err = kPGPError_UserAbort;
b235b8 ¤   ¤   goto GetRecipientsError;
ff9371 ¤   }
7faf5a
d45ea8 ¤   return err;
24af5a
8c7090 GetRecipientsError:
cfaf5a
226802 ¤   FreeRecipients(prds);
f15ea8 ¤   return err;
27efe6 }
2baf5a
87af5a
81878b void FreeRecipients(RECIPIENTDIALOGSTRUCT *prds)
55bb36 {
5e5fb5 ¤   DWORD dwIndex;
dfaf5a
23fd21 ¤   if (prds == NULL)
be99bf ¤   ¤   return;
5baf5a
5c6bb9 ¤   if (prds->szRecipientArray != NULL)
9dc7a1 ¤   {
c66a81 ¤   ¤   for (dwIndex=0; dwIndex<prds->dwNumRecipients; dwIndex++)
c95b34 ¤   ¤   {
5f02e4 ¤   ¤   ¤   if ((prds->szRecipientArray)[dwIndex] != NULL)
4af776 ¤   ¤   ¤   {
b6df6e ¤   ¤   ¤   ¤   free((prds->szRecipientArray)[dwIndex]);
f54f37 ¤   ¤   ¤   ¤   (prds->szRecipientArray)[dwIndex] = NULL;
61a3a6 ¤   ¤   ¤   }
550fe4 ¤   ¤   }
941b52 ¤   ¤
6e9de7 ¤   ¤   free(prds->szRecipientArray);
ffee3e ¤   ¤   prds->szRecipientArray = NULL;
e49371 ¤   }
d7af5a
b6723f ¤   if (IsntNull(prds->SelectedKeySetRef))
24c7a1 ¤   {
fb591a ¤   ¤   PGPFreeKeySet(prds->SelectedKeySetRef);
87e0d4 ¤   ¤   prds->SelectedKeySetRef = NULL;
2e9371 ¤   }
b867c5 ¤
4b830f ¤   return;
5eefe6 }
c8af5a
e4af5a
98d4aa static void ResolveEntries(LPADRBOOK pAddrBook, LPABCONT pContainer,·
11bc78 ¤   ¤   ¤   ¤   ¤   ¤   ···ULONG ulNumRows, LPADRENTRY aEntries,·
7b628d ¤   ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds, DWORD *pdwNumRecip,·
--7496 000bdd5734e40110310 Page 4 of Recipients.cpp
06c742 ¤   ¤   ¤   ¤   ¤   ¤   ···DWORD *pdwRecipIndex)
73bb36 {
007187 ¤   LPENTRYID¤  ¤   pEntryID¤   ¤   = NULL;
199ee1 ¤   ULONG¤  ¤   ¤   ulRow¤  ¤   ¤   = 0;
32047d ¤   ULONG¤  ¤   ¤   ulIndex¤¤   ¤   = 0;
7c5f37 ¤   ULONG¤  ¤   ¤   ulEmailAddr¤¤   = 0;
8d098b ¤   ULONG¤  ¤   ¤   ulDisplayName¤  = 0;
72427d ¤   ULONG¤  ¤   ¤   ulType¤ ¤   ¤   = 0;
a009ac ¤   ULONG¤  ¤   ¤   ulEntryID¤  ¤   = 0;
6c1cf4 ¤   ULONG¤  ¤   ¤   ulAddrType¤ ¤   = 0;
d175a8 ¤   ULONG¤  ¤   ¤   ulNumProxies¤   = 0;
c30c23 ¤   ULONG¤  ¤   ¤   ulProxy¤¤   ¤   = 0;
4f73ef ¤   ULONG¤  ¤   ¤   ulEntrySize¤¤   = 0;
56913d ¤   int¤¤   ¤   ¤   nChar¤  ¤   ¤   = 0;
7130dd ¤   int¤¤   ¤   ¤   nRecipLength¤   = 0;
77c846 ¤   char *¤ ¤   ¤   szRecip¤¤   ¤   = NULL;
27a9d4 ¤   char *¤ ¤   ¤   szAddrType¤ ¤   = NULL;
a8415e ¤   char¤   ¤   ¤   szSMTP[1024];
42edd9 ¤   char **¤¤   ¤   pszProxy¤   ¤   = NULL;
bc8d92 ¤   BOOL¤   ¤   ¤   bGotSMTP¤   ¤   = TRUE;
42aa28 ¤   BOOL¤   ¤   ¤   bRecipAdded¤¤   = FALSE;
f3af5a
27cc17 ¤   for (ulRow=0; ulRow<ulNumRows; ulRow++)
a8c7a1 ¤   {
f05d42 ¤   ¤   ulEmailAddr¤¤   = ULONG_MAX;
546a48 ¤   ¤   ulDisplayName¤  = ULONG_MAX;
e785e6 ¤   ¤   ulType¤ ¤   ¤   = ULONG_MAX;
0e40b6 ¤   ¤   ulEntryID¤  ¤   = ULONG_MAX;
4316e9 ¤   ¤   ulAddrType¤ ¤   = ULONG_MAX;
7dca45 ¤   ¤   ulProxy¤¤   ¤   = ULONG_MAX;
d91b52 ¤   ¤
486611 ¤   ¤   for (¤  ulIndex=0;
1049c2 ¤   ¤   ¤   ¤   ulIndex<aEntries[ulRow].cValues;·
6d3580 ¤   ¤   ¤   ¤   ulIndex++)
9a5b34 ¤   ¤   {
11676a ¤   ¤   ¤   switch (aEntries[ulRow].rgPropVals[ulIndex].ulPropTag)
92f776 ¤   ¤   ¤   {
b2a91c ¤   ¤   ¤   case PR_DISPLAY_NAME:
de9100 ¤   ¤   ¤   ¤   ulDisplayName = ulIndex;
65f622 ¤   ¤   ¤   ¤   break;
2787c7 ¤   ¤   ¤
ac70f5 ¤   ¤   ¤   case PR_EMAIL_ADDRESS:
c2bf13 ¤   ¤   ¤   ¤   ulEmailAddr = ulIndex;
43f622 ¤   ¤   ¤   ¤   break;
f387c7 ¤   ¤   ¤
eefe7e ¤   ¤   ¤   case PR_OBJECT_TYPE:
9dcb01 ¤   ¤   ¤   ¤   ulType = ulIndex;
23f622 ¤   ¤   ¤   ¤   break;
88af5a
3642fa ¤   ¤   ¤   case PR_ENTRYID:
ad0871 ¤   ¤   ¤   ¤   ulEntryID = ulIndex;
4cf622 ¤   ¤   ¤   ¤   break;
edaf5a
b5b476 ¤   ¤   ¤   case PR_ADDRTYPE:
f74a2f ¤   ¤   ¤   ¤   ulAddrType = ulIndex;
fff622 ¤   ¤   ¤   ¤   break;
9faf5a
7df9a4 ¤   ¤   ¤   case PR_EMS_AB_PROXY_ADDRESSES:
c9b038 ¤   ¤   ¤   ¤   ulProxy = ulIndex;
a7a3a6 ¤   ¤   ¤   }
850fe4 ¤   ¤   }
75af5a
cea05d ¤   ¤   if ((ulDisplayName == ULONG_MAX) && (ulEmailAddr == ULONG_MAX))
e75b34 ¤   ¤   {
77ca2f ¤   ¤   ¤   (*pdwNumRecip)--;
4f17f5 ¤   ¤   ¤   continue;
a20fe4 ¤   ¤   }
2c1b52 ¤   ¤
ee7f31 ¤   ¤   if (ulEmailAddr != ULONG_MAX)
c95b34 ¤   ¤   {
688fbb ¤   ¤   ¤   szRecip = aEntries[ulRow].rgPropVals[ulEmailAddr].Value.lpszA;
bdaf5a
--1974 00074fe818c40110310 Page 5 of Recipients.cpp
15a084 ¤   ¤   ¤   if (szRecip)
1cf776 ¤   ¤   ¤   {
c9f2db ¤   ¤   ¤   ¤   if (strlen(szRecip))
4672c3 ¤   ¤   ¤   ¤   {
96e2e4 ¤   ¤   ¤   ¤   ¤   ulIndex = ulEmailAddr;
ea2613 ¤   ¤   ¤   ¤   }
8efa07 ¤   ¤   ¤   ¤   else
5003c7 ¤   ¤   ¤   ¤   ¤   ulIndex = ulDisplayName;
7da3a6 ¤   ¤   ¤   }
4fbb8c ¤   ¤   ¤   else
f5057f ¤   ¤   ¤   ¤   ulIndex = ulDisplayName;
3b0fe4 ¤   ¤   }
dc0e1d ¤   ¤   else
ad0092 ¤   ¤   ¤   ulIndex = ulDisplayName;
901b52 ¤   ¤
bbb8a4 ¤   ¤   // Older versions of Exchange return an invalid number
bc7b25 ¤   ¤   // of recipients, so we have to check each recipient
ed439d ¤   ¤   // for validity
b21b52 ¤   ¤
31e1cb ¤   ¤   // First, make sure there's a pointer to the recipient
6d760a ¤   ¤   // entry
992e60 ¤   ¤   if (!&(aEntries[ulRow]))
9a5b34 ¤   ¤   {
0bca2f ¤   ¤   ¤   (*pdwNumRecip)--;
fe17f5 ¤   ¤   ¤   continue;
a90fe4 ¤   ¤   }
371b52 ¤   ¤
d71cac ¤   ¤   // Now see if the recipient has any properties
0b080e ¤   ¤   if (!(aEntries[ulRow].cValues) ||
af4390 ¤   ¤   ¤   ((aEntries[ulRow].cValues-1) < ulIndex))
da5b34 ¤   ¤   {
0aca2f ¤   ¤   ¤   (*pdwNumRecip)--;
6b17f5 ¤   ¤   ¤   continue;
5b0fe4 ¤   ¤   }
a01b52 ¤   ¤
dae90e ¤   ¤   // Check to see if this is a distribution list. If so,
ff626f ¤   ¤   // process it
2eaf5a
7e1e47 ¤   ¤   if (ulType != ULONG_MAX)
365b34 ¤   ¤   {
06a0ca ¤   ¤   ¤   if (aEntries[ulRow].rgPropVals[ulType].Value.l ==
b38d19 ¤   ¤   ¤   ¤   MAPI_DISTLIST)
3df776 ¤   ¤   ¤   {
f26769 ¤   ¤   ¤   ¤   LPDISTLIST pDistList = NULL;
70ca0c ¤   ¤   ¤   ¤   LPMAPITABLE pTable = NULL;
df2dd9 ¤   ¤   ¤   ¤   SizedSPropTagArray(6, tagaDistList) = {6,·
c6835d ¤   ¤   ¤   ¤   ¤   {PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_ENTRYID,·
1176d8 ¤   ¤   ¤   ¤   ¤   PR_ADDRTYPE, PR_OBJECT_TYPE,
28d18f ¤   ¤   ¤   ¤   ¤   PR_EMS_AB_PROXY_ADDRESSES}};
379556 ¤   ¤   ¤   ¤   SRowSet *pRows = NULL;
f96c3d ¤   ¤   ¤   ¤   ULONG ulObjType = 0;
e1af5a
ddcfb4 ¤   ¤   ¤   ¤   ulEntrySize = aEntries[ulRow].
abbbd0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[ulEntryID].Value.bin.cb;
8b2b85 ¤   ¤   ¤   ¤
c395f8 ¤   ¤   ¤   ¤   pEntryID = (LPENTRYID) aEntries[ulRow].
f659c0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[ulEntryID].Value.bin.lpb;
b32b85 ¤   ¤   ¤   ¤
8a4bb0 ¤   ¤   ¤   ¤   pAddrBook->OpenEntry(ulEntrySize, pEntryID, &IID_IDistList,
89b7a5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   0, &ulObjType, (IUnknown**)&pDistList);
042b85 ¤   ¤   ¤   ¤
d272ae ¤   ¤   ¤   ¤   pDistList->GetContentsTable(0, &pTable);
507da0 ¤   ¤   ¤   ¤   HrQueryAllRows(pTable, (SPropTagArray *)&tagaDistList, NULL,·
e56617 ¤   ¤   ¤   ¤   ¤   NULL, 0, &pRows);
0d2b85 ¤   ¤   ¤   ¤
81bdf8 ¤   ¤   ¤   ¤   (*pdwNumRecip) += pRows->cRows - 1;
e5bb00 ¤   ¤   ¤   ¤   prds->szRecipientArray = (char **)·
9b96df ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   realloc(prds->szRecipientArray,·
93bc7a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(char *) * (*pdwNumRecip));
d2af5a
8a33eb ¤   ¤   ¤   ¤   ResolveEntries(pAddrBook, pContainer, pRows->cRows,·
741dae ¤   ¤   ¤   ¤   ¤   (LPADRENTRY) pRows->aRow, prds, pdwNumRecip,·
--989c 0008938ccd340110310 Page 6 of Recipients.cpp
9090c7 ¤   ¤   ¤   ¤   ¤   pdwRecipIndex);
0faf5a
6f7ba9 ¤   ¤   ¤   ¤   pTable->Release();
7d30bd ¤   ¤   ¤   ¤   pDistList->Release();
6fd040 ¤   ¤   ¤   ¤   continue;
96a3a6 ¤   ¤   ¤   }
f50fe4 ¤   ¤   }
5daf5a
164216 ¤   ¤   szRecip = aEntries[ulRow].rgPropVals[ulIndex].Value.lpszA;
27af5a
97b231 ¤   ¤   // Make sure e-mail address is an SMTP address. If not, try
90747c ¤   ¤   // to fetch the SMTP address
dbaf5a
9ea19a ¤   ¤   bGotSMTP = FALSE;
a97797 ¤   ¤   bRecipAdded = FALSE;
941b52 ¤   ¤
43a223 ¤   ¤   if (ulAddrType != ULONG_MAX)
3497c8 ¤   ¤   ¤   szAddrType = aEntries[ulRow].
429a9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[ulAddrType].Value.lpszA;
8b0e1d ¤   ¤   else
7e5b34 ¤   ¤   {
c9ca2f ¤   ¤   ¤   (*pdwNumRecip)--;
c017f5 ¤   ¤   ¤   continue;
d60fe4 ¤   ¤   }
72af5a
8e8350 ¤   ¤   if (szAddrType)
175b34 ¤   ¤   {
1667ed ¤   ¤   ¤   if (strstr(szAddrType, "SMTP"))
81ffdf ¤   ¤   ¤   ¤   bGotSMTP = TRUE;
ffbb8c ¤   ¤   ¤   else
dff776 ¤   ¤   ¤   {
5f9ec1 ¤   ¤   ¤   ¤   SizedADRLIST(1, newAddress);
3c8c36 ¤   ¤   ¤   ¤   newAddress.cEntries = 1;
6929dc ¤   ¤   ¤   ¤   ulNumProxies = 0;
e60ccc ¤   ¤   ¤   ¤   pszProxy = NULL;
3aaf5a
ecfa94 ¤   ¤   ¤   ¤   if ((ulProxy == ULONG_MAX) && (pContainer != NULL))
be72c3 ¤   ¤   ¤   ¤   {
12708a ¤   ¤   ¤   ¤   ¤   FlagList flags;
7ea298 ¤   ¤   ¤   ¤   ¤   char *szName = NULL;
3cbe3e ¤   ¤   ¤   ¤   ¤   char *szNameCopy = NULL;
5988c6 ¤   ¤   ¤   ¤   ¤   char *szFirstName = NULL;
0f83fa ¤   ¤   ¤   ¤   ¤   char *szLastName = NULL;
610c8b ¤   ¤   ¤   ¤   ¤   char *szPutNull = NULL;
bfbff1 ¤   ¤   ¤   ¤   ¤   HRESULT result;
c4ed0d ¤   ¤   ¤   ¤   ¤   SizedSPropTagArray(2, propTags) = {
9896f3 ¤   ¤   ¤   ¤   ¤   ¤   2, {PR_DISPLAY_NAME, PR_EMS_AB_PROXY_ADDRESSES}};
5faf5a
0ef6db ¤   ¤   ¤   ¤   ¤   flags.cFlags = 1;
2b1186 ¤   ¤   ¤   ¤   ¤   flags.ulFlag[0] = MAPI_UNRESOLVED;
56af5a
6a43ca ¤   ¤   ¤   ¤   ¤   newAddress.aEntries[0].ulReserved1 = 0;
df3a6e ¤   ¤   ¤   ¤   ¤   newAddress.aEntries[0].cValues = 2;
c5c217 ¤   ¤   ¤   ¤   ¤   MAPIAllocateBuffer(sizeof(SPropValue)*2, (void **)
9252a5 ¤   ¤   ¤   ¤   ¤   ¤   &(newAddress.aEntries[0].rgPropVals));
b6af5a
ddf25d ¤   ¤   ¤   ¤   ¤   newAddress.aEntries[0].rgPropVals[0].ulPropTag =·
4b21ea ¤   ¤   ¤   ¤   ¤   ¤   PR_DISPLAY_NAME;
de7c4d ¤   ¤   ¤   ¤   ¤   newAddress.aEntries[0].rgPropVals[1].ulPropTag =·
99bb8c ¤   ¤   ¤   ¤   ¤   ¤   PR_EMS_AB_PROXY_ADDRESSES;
e3ae30 ¤   ¤   ¤   ¤   ¤
7ba95f ¤   ¤   ¤   ¤   ¤   newAddress.aEntries[0].rgPropVals[1].
0bbdef ¤   ¤   ¤   ¤   ¤   ¤   Value.MVszA.cValues = 0;
04a95f ¤   ¤   ¤   ¤   ¤   newAddress.aEntries[0].rgPropVals[1].
dd6050 ¤   ¤   ¤   ¤   ¤   ¤   Value.MVszA.lppszA = NULL;
45af5a
be2f93 ¤   ¤   ¤   ¤   ¤   szName = aEntries[ulRow].
7e4468 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[ulDisplayName].Value.lpszA;
23af5a
5a09d7 ¤   ¤   ¤   ¤   ¤   szPutNull = strstr(szName, " (E-mail)");
e02b42 ¤   ¤   ¤   ¤   ¤   if (szPutNull)
89c1d7 ¤   ¤   ¤   ¤   ¤   ¤   *szPutNull = 0;
--f149 0002d9e733040110310 Page 7 of Recipients.cpp
e0af5a
157804 ¤   ¤   ¤   ¤   ¤   MAPIAllocateBuffer(strlen(szName)+2, (void **)
82ae5e ¤   ¤   ¤   ¤   ¤   ¤   &(newAddress.aEntries[0].rgPropVals[0].Value.lpszA));
34af5a
2c5ff9 ¤   ¤   ¤   ¤   ¤   strcpy(newAddress.aEntries[0].rgPropVals[0].Value.lpszA,
a4d626 ¤   ¤   ¤   ¤   ¤   ¤   szName);
34af5a
6bc199 ¤   ¤   ¤   ¤   ¤   result = pContainer->ResolveNames(
3c887c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPSPropTagArray) &propTags, 0,·
854626 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPADRLIST) &newAddress,·
f11f00 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (FlagList *) &flags);
feaf5a
b9b9de ¤   ¤   ¤   ¤   ¤   if (flags.ulFlag[0] == MAPI_UNRESOLVED)
604859 ¤   ¤   ¤   ¤   ¤   {
d39ae4 ¤   ¤   ¤   ¤   ¤   ¤   szNameCopy = (char *) calloc(strlen(szName)+1, 1);
62e46c ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szNameCopy, szName);
e8af5a
06d226 ¤   ¤   ¤   ¤   ¤   ¤   szFirstName = strtok(szNameCopy, " ");
44f882 ¤   ¤   ¤   ¤   ¤   ¤   if (szFirstName != NULL)
6e8fec ¤   ¤   ¤   ¤   ¤   ¤   {
f74e9b ¤   ¤   ¤   ¤   ¤   ¤   ¤   szLastName = szFirstName + strlen(szFirstName)·
cb734d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   + 1;
78af5a
9f817f ¤   ¤   ¤   ¤   ¤   ¤   ¤   szName = (char *) calloc(strlen(szFirstName)
825056 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   + strlen(szLastName) + 3, 1);
caaf5a
f9f152 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szName, szLastName);
c94da0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szName, ", ");
80dca4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcat(szName, szFirstName);
59af5a
115e45 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy(newAddress.aEntries[0].
1145dd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[0].Value.lpszA, szName);
92af5a
1ec640 ¤   ¤   ¤   ¤   ¤   ¤   ¤   result = pContainer->ResolveNames(
7c054f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPSPropTagArray) &propTags, 0,·
e1183f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPADRLIST) &newAddress,·
52fe77 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (FlagList *) &flags);
95af5a
e67b66 ¤   ¤   ¤   ¤   ¤   ¤   ¤   free(szName);
b2db3c ¤   ¤   ¤   ¤   ¤   ¤   }
15af5a
4dc7d2 ¤   ¤   ¤   ¤   ¤   ¤   free(szNameCopy);
5f1c89 ¤   ¤   ¤   ¤   ¤   }
3faf5a
b0097d ¤   ¤   ¤   ¤   ¤   ulNumProxies = newAddress.aEntries[0].
33a9fd ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[1].Value.MVszA.cValues;
67af5a
50861c ¤   ¤   ¤   ¤   ¤   pszProxy = newAddress.aEntries[0].
fcea91 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[1].Value.MVszA.lppszA;
982613 ¤   ¤   ¤   ¤   }
d3afc0 ¤   ¤   ¤   ¤   else if (ulProxy != ULONG_MAX)
4672c3 ¤   ¤   ¤   ¤   {
4147ea ¤   ¤   ¤   ¤   ¤   ulNumProxies = aEntries[ulRow].
2ec79e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[ulProxy].Value.MVszA.cValues;
6daf5a
fbec4d ¤   ¤   ¤   ¤   ¤   pszProxy = aEntries[ulRow].
f3e906 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[ulProxy].Value.MVszA.lppszA;
572613 ¤   ¤   ¤   ¤   }
caaf5a
ea313e ¤   ¤   ¤   ¤   if (GetSMTPAddress(ulNumProxies, pszProxy, prds,·
b5bff9 ¤   ¤   ¤   ¤   ¤   ¤   pdwRecipIndex, pdwNumRecip, szSMTP, &bRecipAdded))
9d72c3 ¤   ¤   ¤   ¤   {
13cd90 ¤   ¤   ¤   ¤   ¤   szRecip = szSMTP;
49c2b7 ¤   ¤   ¤   ¤   ¤   bGotSMTP = TRUE;
e32613 ¤   ¤   ¤   ¤   }
01fa07 ¤   ¤   ¤   ¤   else
5cf0b5 ¤   ¤   ¤   ¤   ¤   bGotSMTP = FALSE;
b2af5a
0c9d4b ¤   ¤   ¤   ¤   if (ulProxy == ULONG_MAX)
a872c3 ¤   ¤   ¤   ¤   {
53f0ee ¤   ¤   ¤   ¤   ¤   MAPIFreeBuffer(newAddress.aEntries[0].
2d10e8 ¤   ¤   ¤   ¤   ¤   ¤   rgPropVals[0].Value.lpszA);
--4f82 00073a7f5ea40110310 Page 8 of Recipients.cpp
e0af5a
57ea9e ¤   ¤   ¤   ¤   ¤   MAPIFreeBuffer(newAddress.aEntries[0].rgPropVals);
382613 ¤   ¤   ¤   ¤   }
1fa3a6 ¤   ¤   ¤   }
210fe4 ¤   ¤   }
ebaf5a
1122ec ¤   ¤   if (!bGotSMTP && !bRecipAdded && (ulIndex == ulEmailAddr))
de5b34 ¤   ¤   {
4e0092 ¤   ¤   ¤   ulIndex = ulDisplayName;
af557b ¤   ¤   ¤   szRecip =·
ffc960 ¤   ¤   ¤   ¤   aEntries[ulRow].rgPropVals[ulIndex].Value.lpszA;
634489 ¤   ¤   ¤   bGotSMTP = TRUE;
6b0fe4 ¤   ¤   }
f5af5a
794e53 ¤   ¤   if (bGotSMTP)
0b5b34 ¤   ¤   {
2f7812 ¤   ¤   ¤   // Make sure the recipient e-mail address is not
ff9676 ¤   ¤   ¤   // a null string
6f65d4 ¤   ¤   ¤   nRecipLength = strlen(szRecip);
28159c ¤   ¤   ¤   if (!nRecipLength)
2cf776 ¤   ¤   ¤   {
4afd27 ¤   ¤   ¤   ¤   (*pdwNumRecip)--;
57d040 ¤   ¤   ¤   ¤   continue;
eea3a6 ¤   ¤   ¤   }
0587c7 ¤   ¤   ¤
7cab6e ¤   ¤   ¤   // Finally, make sure the address has at least one
e827be ¤   ¤   ¤   // printable non-space character in it
fc595f ¤   ¤   ¤   for (nChar=0; nChar<nRecipLength; nChar++)
6df776 ¤   ¤   ¤   {
c2f298 ¤   ¤   ¤   ¤   if (isgraph(szRecip[nChar]))
8614c3 ¤   ¤   ¤   ¤   ¤   break;
e8a3a6 ¤   ¤   ¤   }
3a87c7 ¤   ¤   ¤
4fba60 ¤   ¤   ¤   if (nChar >= nRecipLength)
40f776 ¤   ¤   ¤   {
aafd27 ¤   ¤   ¤   ¤   (*pdwNumRecip)--;
a4d040 ¤   ¤   ¤   ¤   continue;
28a3a6 ¤   ¤   ¤   }
6d87c7 ¤   ¤   ¤
384fb5 ¤   ¤   ¤   (prds->szRecipientArray)[*pdwRecipIndex] =·
f3ee8b ¤   ¤   ¤   ¤   (char *) calloc(1, nRecipLength+1);
fb87c7 ¤   ¤   ¤
6f3709 ¤   ¤   ¤   strcpy((prds->szRecipientArray)[*pdwRecipIndex], szRecip);
6b6cd2 ¤   ¤   ¤   (*pdwRecipIndex)++;
b10fe4 ¤   ¤   }
fb9371 ¤   }
7faf5a
61830f ¤   return;
9fefe6 }
67af5a
91af5a
f81bc0 BOOL GetSMTPAddress(ULONG ulNum, LPSTR *lppszProxy,
486ac0 ¤   ¤   ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds,
28c0f5 ¤   ¤   ¤   ¤   ¤   DWORD *pdwRecipIndex, DWORD *pdwNumRecip,
e18b97 ¤   ¤   ¤   ¤   ¤   char *szAddress, BOOL *pbRecipAdded)
babb36 {
33f3dc ¤   BOOL¤   ¤   ¤   bMatch = FALSE;
618658 ¤   BOOL¤   ¤   ¤   bReturn = FALSE;
4e6766 ¤   BOOL¤   ¤   ¤   *pbSMTP = NULL;
0c422b ¤   BOOL¤   ¤   ¤   bFoundSMTP = FALSE;
c687e0 ¤   const char *¤   szNewAddress = NULL;
8a1455 ¤   ULONG¤  ¤   ¤   ulIndex;
6c2245 ¤   PGPFilterRef¤   filter;
020476 ¤   PGPKeySetRef¤   userKeySet;
65dff3 ¤   PGPKeySetRef¤   matchKeySet;
fc21c5 ¤   PGPUInt32¤  ¤   nNumKeys;
0848bc ¤   DWORD¤  ¤   ¤   dwNumNew = 0;
75fb19 ¤   PGPError¤   ¤   err;
8faf5a
e53a43 ¤   userKeySet = prds->OriginalKeySetRef;
7b9f10 ¤   *pbRecipAdded = FALSE;
73af5a
--84d7 000a76e3a7e40110310 Page 9 of Recipients.cpp
ce8ee3 ¤   pbSMTP = (BOOL *) calloc(sizeof(BOOL), ulNum);
53af5a
d38f61 ¤   for (ulIndex=0; ulIndex<ulNum; ulIndex++)
19c7a1 ¤   {
359da2 ¤   ¤   if (!_strnicmp("smtp", lppszProxy[ulIndex], 4))
805b34 ¤   ¤   {
49b5f8 ¤   ¤   ¤   pbSMTP[ulIndex] = TRUE;
05137b ¤   ¤   ¤   bFoundSMTP = TRUE;
f50fe4 ¤   ¤   }
5f9371 ¤   }
77af5a
7b99e2 ¤   if (!bFoundSMTP)
b1c7a1 ¤   {
1d72e2 ¤   ¤   if (pbSMTP != NULL)
853e66 ¤   ¤   ¤   free(pbSMTP);
bbaf5a
7998aa ¤   ¤   return FALSE;
589371 ¤   }
b1af5a
8f7dff ¤   ulIndex = 0;
dc9a4e ¤   while ((ulIndex < ulNum) && !bMatch)
27c7a1 ¤   {
602a2b ¤   ¤   if (pbSMTP[ulIndex])
b65b34 ¤   ¤   {
463a82 ¤   ¤   ¤   dwNumNew++;
f37276 ¤   ¤   ¤   szNewAddress = lppszProxy[ulIndex] + 5;
33af5a
bee1ee ¤   ¤   ¤   PGPNewUserIDEmailFilter(PGPGetKeySetContext(userKeySet),·
a46b00 ¤   ¤   ¤   ¤   szNewAddress, kPGPMatchEqual, &filter);
4ce46e ¤   ¤   ¤   err = PGPFilterKeySet(userKeySet, filter, &matchKeySet);
4b87c7 ¤   ¤   ¤
5012ce ¤   ¤   ¤   if (IsntNull(matchKeySet))
04f776 ¤   ¤   ¤   {
6a7905 ¤   ¤   ¤   ¤   PGPCountKeys(matchKeySet, &nNumKeys);
559372 ¤   ¤   ¤   ¤   if (nNumKeys > 0)
47b777 ¤   ¤   ¤   ¤   ¤   bMatch = TRUE;
4ea3a6 ¤   ¤   ¤   }
8887c7 ¤   ¤   ¤
285840 ¤   ¤   ¤   PGPFreeKeySet(matchKeySet);
ccbc16 ¤   ¤   ¤   PGPFreeFilter(filter);
280fe4 ¤   ¤   }
b4af5a
564aa9 ¤   ¤   ulIndex++;
9c9371 ¤   }
bf67c5 ¤
fcb9ee ¤   if (bMatch)
30c7a1 ¤   {
cbb978 ¤   ¤   strcpy(szAddress, szNewAddress);
5a9545 ¤   ¤   bReturn = TRUE;
109371 ¤   }
1caf5a
eb03e3 ¤   if (!bMatch)
88c7a1 ¤   {
d50584 ¤   ¤   PGPPrefRef prefs = NULL;
96b767 ¤   ¤   PGPBoolean sync = FALSE;
c6aebe ¤   ¤   PGPUInt32 numServers = 0;
e2a739 ¤   ¤   PGPKeySetRef tempSet = NULL;
9da7f8 ¤   ¤   char szTempAddress[1024];
f9af5a
c63e25 ¤   ¤   err = PGPclOpenClientPrefs(PGPGetContextMemoryMgr(prds->Context),
3d98e7 ¤   ¤   ¤   ¤   ¤   &prefs);
2faf5a
0db6ad ¤   ¤   if (IsPGPError(err))
55efb2 ¤   ¤   ¤   goto AddAllToRecipientDialog;
e4af5a
3c3607 ¤   ¤   PGPGetPrefBoolean(prefs, kPGPPrefKeyServerSyncUnknownKeys, &sync);
4a7fc4 ¤   ¤   PGPclCloseClientPrefs(prefs, FALSE);
6daf5a
dbcb87 ¤   ¤   if (!sync)
aaefb2 ¤   ¤   ¤   goto AddAllToRecipientDialog;
44af5a
a73c74 ¤   ¤   ulIndex = 0;
--82dc 000e66742c440110310 Page 10 of Recipients.cpp
4f9cf6 ¤   ¤   while ((ulIndex < ulNum) && !bMatch)
b85b34 ¤   ¤   {
a0917d ¤   ¤   ¤   if (pbSMTP[ulIndex])
04f776 ¤   ¤   ¤   {
d927da ¤   ¤   ¤   ¤   szNewAddress = lppszProxy[ulIndex] + 5;
aa2b85 ¤   ¤   ¤   ¤
91a03f ¤   ¤   ¤   ¤   strcpy(szTempAddress, "<");
3c2553 ¤   ¤   ¤   ¤   strcat(szTempAddress, szNewAddress);
03a125 ¤   ¤   ¤   ¤   strcat(szTempAddress, ">");
802b85 ¤   ¤   ¤   ¤
1576a8 ¤   ¤   ¤   ¤   err = PGPclSearchServerForUserID(prds->Context,·
3ac636 ¤   ¤   ¤   ¤   ¤   ¤   prds->tlsContext, prds->hwndParent, szTempAddress,·
dbc40f ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_DEFAULTSERVER, prds->OriginalKeySetRef,·
d5d04e ¤   ¤   ¤   ¤   ¤   ¤   &tempSet);
9e2b85 ¤   ¤   ¤   ¤
477595 ¤   ¤   ¤   ¤   if(IsntPGPError(err) && PGPKeySetRefIsValid(tempSet))
6572c3 ¤   ¤   ¤   ¤   {
4b7070 ¤   ¤   ¤   ¤   ¤   PGPUInt32¤  ¤   numKeys;
f1afbb ¤   ¤   ¤   ¤   ¤   PGPKeySetRef¤   newKeySet = NULL;
9eae30 ¤   ¤   ¤   ¤   ¤
297adc ¤   ¤   ¤   ¤   ¤   err = PGPCountKeys(tempSet, &numKeys);
2b146e ¤   ¤   ¤   ¤   ¤   if(IsntPGPError(err) && (numKeys > 0))
f34859 ¤   ¤   ¤   ¤   ¤   {
cc2d34 ¤   ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys(prds->Context, prds->tlsContext,·
499250 ¤   ¤   ¤   ¤   ¤   ¤   ¤   prds->hwndParent, tempSet, NULL);
5394aa ¤   ¤   ¤   ¤   ¤   ¤
313f9a ¤   ¤   ¤   ¤   ¤   ¤   PGPAddKeys(tempSet, prds->OriginalKeySetRef);
d1e24a ¤   ¤   ¤   ¤   ¤   ¤   PGPCommitKeyRingChanges(prds->OriginalKeySetRef);
1794aa ¤   ¤   ¤   ¤   ¤   ¤
38b3f9 ¤   ¤   ¤   ¤   ¤   ¤   (*pdwNumRecip)++;
3e7286 ¤   ¤   ¤   ¤   ¤   ¤   prds->szRecipientArray =·
3698bf ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char **) realloc(prds->szRecipientArray,·
fd7abc ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(char *) * (*pdwNumRecip));
c094aa ¤   ¤   ¤   ¤   ¤   ¤
683990 ¤   ¤   ¤   ¤   ¤   ¤   (prds->szRecipientArray)[*pdwRecipIndex] =·
3d588c ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) calloc(1, strlen(szNewAddress)+1);
7194aa ¤   ¤   ¤   ¤   ¤   ¤
062904 ¤   ¤   ¤   ¤   ¤   ¤   strcpy((prds->szRecipientArray)[*pdwRecipIndex],·
a60535 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szNewAddress);
f594aa ¤   ¤   ¤   ¤   ¤   ¤
a8aa1d ¤   ¤   ¤   ¤   ¤   ¤   (*pdwRecipIndex)++;
f1f684 ¤   ¤   ¤   ¤   ¤   ¤   bMatch = TRUE;
6b551f ¤   ¤   ¤   ¤   ¤   ¤   *pbRecipAdded = TRUE;
cc1c89 ¤   ¤   ¤   ¤   ¤   }
1bae30 ¤   ¤   ¤   ¤   ¤
6d918f ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(tempSet);
4d2613 ¤   ¤   ¤   ¤   }
022b85 ¤   ¤   ¤   ¤
65a20c ¤   ¤   ¤   ¤   if (bMatch)
601254 ¤   ¤   ¤   ¤   ¤   (*pdwNumRecip)--;
92a3a6 ¤   ¤   ¤   }
5baf5a
447140 ¤   ¤   ¤   ulIndex++;
9e0fe4 ¤   ¤   }
889371 ¤   }
06af5a
3faf5a
ba1700 AddAllToRecipientDialog:
19af5a
ca03e3 ¤   if (!bMatch)
c8c7a1 ¤   {
b574d8 ¤   ¤   (*pdwNumRecip) += dwNumNew-1;
a03511 ¤   ¤   prds->szRecipientArray = (char **)·
c596bd ¤   ¤   ¤   realloc(prds->szRecipientArray, sizeof(char *) * (*pdwNumRecip));
daaf5a
14c05f ¤   ¤   for (ulIndex=0; ulIndex<ulNum; ulIndex++)
a25b34 ¤   ¤   {
fc917d ¤   ¤   ¤   if (pbSMTP[ulIndex])
0ff776 ¤   ¤   ¤   {
0227da ¤   ¤   ¤   ¤   szNewAddress = lppszProxy[ulIndex] + 5;
d667c5 ¤
e6c0e2 ¤   ¤   ¤   ¤   (prds->szRecipientArray)[*pdwRecipIndex] =·
--0976 00145802d2740110310 Page 11 of Recipients.cpp
d12b95 ¤   ¤   ¤   ¤   ¤   (char *) calloc(1, strlen(szNewAddress)+1);
5c87c7 ¤   ¤   ¤
7d2a91 ¤   ¤   ¤   ¤   strcpy((prds->szRecipientArray)[*pdwRecipIndex],·
ed4a8a ¤   ¤   ¤   ¤   ¤   szNewAddress);
84e72e ¤   ¤   ¤   ¤   (*pdwRecipIndex)++;
d4af5a
565034 ¤   ¤   ¤   ¤   *pbRecipAdded = TRUE;
24a3a6 ¤   ¤   ¤   }
6b0fe4 ¤   ¤   }
9a9371 ¤   }
22af5a
3a8487 ¤   if (pbSMTP != NULL)
bef9d3 ¤   ¤   free(pbSMTP);
5faf5a
6932bc ¤   return bReturn;
eeefe6 }
1eaf5a
2baf5a
5d7e4d /*__Editor_settings____
08af5a
a44126 ¤   Local Variables:
507b17 ¤   tab-width: 4
c10e6c ¤   End:
f25f8c ¤   vi: ts=4 sw=4
aa9e9b ¤   vim: si
45d062 _____________________*/
--121b 001c5efb80c40110311 Page 1 of Recipients.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
dd2994 ¤   $Id: Recipients.h,v 1.4.8.1 1998/11/12 03:14:01 heller Exp $
a4f7f7 ____________________________________________________________________________*/
5477c9 #ifndef Included_Recipients_h¤  /* [ */
f2b0ad #define Included_Recipients_h
83af5a
f4af5a
0f5d3c #include "stdinc.h"
07e82c #include "pgpPubTypes.h"
c178f8 #include "pgpcl.h"
37af5a
9fc20a PGPError GetRecipients(IExchExtCallback *pmecb,·
5a3420 ¤   ¤   ¤   ¤   ¤   ···PGPContextRef context,
eadeb9 ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,
c0bd2c ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds);
9faf5a
e93a7c void FreeRecipients(RECIPIENTDIALOGSTRUCT *prds);
72af5a
24af5a
f66d78 #endif /* ] Included_Exchange_h */
25af5a
30af5a
7a7e4d /*__Editor_settings____
45af5a
b84126 ¤   Local Variables:
0b7b17 ¤   tab-width: 4
3b0e6c ¤   End:
7e5f8c ¤   vi: ts=4 sw=4
8c9e9b ¤   vim: si
c5d062 _____________________*/
--c93c 00176694ce640110312 Page 1 of STDINC.H
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
f987bd ¤   $Id: STDINC.H,v 1.3.18.1 1998/11/12 03:14:02 heller Exp $
88f7f7 ____________________________________________________________________________*/
dd35ae #ifndef Included_STDINC_h¤  /* [ */
40042e #define Included_STDINC_h
97af5a
129512 // STDINC.H - project invariants
93af5a
1c5655 #include <windows.h>
333d0b #include <windowsx.h>
b190fb #include <commctrl.h>
5e2f6f #include <richedit.h>
9988d0 #include <tchar.h>
7eaf5a
f248c9 #include <mapix.h>
9fe57e #include <mapiutil.h>
53934c #include <mapiform.h>
0da0f5 #include <exchext.h>
7aaf5a
8b1def #endif /* ] Included_STDINC_h */
ceaf5a
61af5a
067e4d /*__Editor_settings____
47af5a
ec4126 ¤   Local Variables:
6d7b17 ¤   tab-width: 4
8b0e6c ¤   End:
c15f8c ¤   vi: ts=4 sw=4
5b9e9b ¤   vim: si
76d062 _____________________*/
--2ec7 000aa80283040110313 Page 1 of STDNOTE.CPP
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
6c31bb ¤   $Id: STDNOTE.CPP,v 1.3.16.1 1998/11/12 03:14:02 heller Exp $
3ff7f7 ____________________________________________________________________________*/
eeaf5a
cc5d3c #include "stdinc.h"
f89803 #include "Exchange.h"
7badf9 #include "UIutils.h"
818031 #include "resource.h"
94af5a
eeaf5a
3e851b // Property recording the decision of CMsgType
8daf5a
c5fe51 #define PR_INETXIDM_EXISTING_MESSAGE¤   PROP_TAG(PT_LONG, 0x7C00)
c2af5a
b6af5a
3eaf5a
7b7050 //¤ Heuristic class to guess the origin of the current note.
16af5a
942284 // Codes for CMsgType Read/Write
63af5a
67c24d enum {MSGTYPE_COMPOSE_NEW=1, MSGTYPE_COMPOSE_REPLY, MSGTYPE_COMPOSE_FORWARD};
f6af5a
2b883e #define MASK_MSGTYPE_COMPOSE 0x00000003
01eca1 #define MASK_MSGTYPE_SUBMITTED 0x00000004
deaf5a
9aaf5a
f1c536 HRESULT CMsgType::Read(IExchExtCallback* peecb)
3ebb36 {
4bc7a1 ¤   {
62a3df ¤   ¤   ADRLIST* padrlist;
822381 ¤   ¤   HRESULT hr = peecb->GetRecipients(&padrlist);
90658d ¤   ¤   if (FAILED(hr))
abae27 ¤   ¤   ¤   return hr;
a8225c ¤   ¤   if (padrlist == NULL)
f48c71 ¤   ¤   ¤   _cRecips = 0;
ff0e1d ¤   ¤   else
c9d8ad ¤   ¤   ¤   _cRecips = (UINT) padrlist->cEntries;
92fb3e ¤   ¤   FreePadrlist(padrlist);
a19371 ¤   }
e0af5a
7dc7a1 ¤   {
02c820 ¤   ¤   IMessage* pmsg;
f6f763 ¤   ¤   HRESULT hr = peecb->GetObject(NULL, (IMAPIProp**)&pmsg);
8b658d ¤   ¤   if (FAILED(hr))
c3ae27 ¤   ¤   ¤   return hr;
50af5a
251436 ¤   ¤   enum {ivalSubject = 0, ivalPrefix, ivalIsNotNew, cvalTotal};
f3d811 ¤   ¤   SizedSPropTagArray(cvalTotal, taga) =·
0c2a4c ¤   ¤   ¤   { 3,·
f67adb ¤   ¤   ¤   { PR_SUBJECT, PR_SUBJECT_PREFIX, PR_INETXIDM_EXISTING_MESSAGE }};
75cc45 ¤   ¤   SPropValue* pval;
2c9a37 ¤   ¤   ULONG cval = cvalTotal;
f5ccb4 ¤   ¤   hr = pmsg->GetProps((SPropTagArray*)&taga, 0, &cval, &pval);
31658d ¤   ¤   if (FAILED(hr))
c95b34 ¤   ¤   {
64491c ¤   ¤   ¤   pmsg->Release();
b9ae27 ¤   ¤   ¤   return hr;
b10fe4 ¤   ¤   }
75af5a
9452c1 ¤   ¤   _fSubjSet =·
d94ba1 ¤   ¤   ¤   (pval[ivalSubject].ulPropTag == PR_SUBJECT
5e4582 ¤   ¤   ¤   ¤   && pval[ivalPrefix].ulPropTag == PR_SUBJECT_PREFIX);
e78c5b ¤   ¤   _fNew = (PROP_TYPE(pval[ivalIsNotNew].ulPropTag) == PT_ERROR);
d043ae ¤   ¤   if (!_fNew)
205b34 ¤   ¤   {
8a2ff5 ¤   ¤   ¤   const ULONG ul = pval[ivalIsNotNew].Value.ul;
aaaf5a
--63de 0006288961040110313 Page 2 of STDNOTE.CPP
615535 ¤   ¤   ¤   _fIsReply = ((MASK_MSGTYPE_COMPOSE & ul) ==·
e1d1a2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MSGTYPE_COMPOSE_REPLY);
afab78 ¤   ¤   ¤   _fIsFwd = ((MASK_MSGTYPE_COMPOSE & ul) ==·
78ddd5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   MSGTYPE_COMPOSE_FORWARD);
c27220 ¤   ¤   ¤   _fIsSubmitted = !!(MASK_MSGTYPE_SUBMITTED & ul);
6e0fe4 ¤   ¤   }
89af5a
30af5a
2081e7 ¤   ¤   MAPIFreeBuffer(pval);
917d41 ¤   ¤   pmsg->Release();
649371 ¤   }
5aaf5a
452e2b ¤   return NOERROR;
e8efe6 }
41af5a
69af5a
d93c88 HRESULT CMsgType::Write(IExchExtCallback* peecb, BOOL fInSubmitState)
4abb36 {
2eff16 ¤   HWND hwnd = NULL;
eeae1a ¤   peecb->GetWindow(&hwnd);
d0af5a
36d584 ¤   IMessage *pmsg = 0;
8baf5a
98b44d ¤   HRESULT hr = peecb->GetObject(NULL, (LPMAPIPROP *)&pmsg);
341f79 ¤   if (FAILED(hr))
9fc7a1 ¤   {
8fab40 ¤   ¤   UIDisplayStringID(hwnd, IDS_E_NOMESSAGE);
7b95ce ¤   ¤   return hr;
dd9371 ¤   }
b4af5a
91ca04 ¤   // Stamp the message's souvenir booklet.
08af5a
70b5f0 ¤   SPropValue val;
9901f7 ¤   val.ulPropTag = PR_INETXIDM_EXISTING_MESSAGE;
4bd4dc ¤   val.Value.ul =
2b6e1e ¤   ¤   (IsReply() ? MSGTYPE_COMPOSE_REPLY·
cd75ec ¤   ¤   ¤   : (IsForward() ? MSGTYPE_COMPOSE_FORWARD·
2fca0a ¤   ¤   ¤   ¤   : MSGTYPE_COMPOSE_NEW));
97faa3 ¤   if (_fIsSubmitted || fInSubmitState)
330415 ¤   ¤   val.Value.ul |= MASK_MSGTYPE_SUBMITTED;
c816c3 ¤   hr = pmsg->SetProps(1, &val, NULL);
801f79 ¤   if (FAILED(hr))
e8c7a1 ¤   {
fa65d2 ¤   ¤   UIDisplayStringID(hwnd, IDS_E_STAMPMESSAGE);
237d41 ¤   ¤   pmsg->Release();
d195ce ¤   ¤   return hr;
5b9371 ¤   }
d1af5a
f8f163 ¤   // All client extensions operate as parasites within the client.
e86c5d ¤   // Only the client gets the privilege of calling SaveChanges.
85af5a
bbcc90 ¤   pmsg->Release();
c72e2b ¤   return NOERROR;
64efe6 }
1eaf5a
44af5a
3dd05e BOOL CMsgType::IsNew() const
d7bb36 {
faed87 ¤   return _fNew;
f4efe6 }
9faf5a
8baf5a
a5e804 BOOL CMsgType::IsReply() const
58bb36 {
0ed4dd ¤   if (!_fNew)
6ab8f1 ¤   ¤   return _fIsReply;
ba0e24 ¤   else
0ab550 ¤   ¤   return (_cRecips > 0 && _fSubjSet);
41efe6 }
57af5a
93af5a
62ffe6 BOOL CMsgType::IsForward() const
--2b86 0018af8eece40110313 Page 3 of STDNOTE.CPP
2cbb36 {
34d4dd ¤   if (!_fNew)
61ac99 ¤   ¤   return _fIsFwd;
780e24 ¤   else
ca8975 ¤   ¤   return (_cRecips == 0 && _fSubjSet);
4cefe6 }
03af5a
ccaf5a
2a6bdd BOOL CMsgType::WasSubmittedOnce() const
0fbb36 {
e62a92 ¤   if (_fNew)
6898aa ¤   ¤   return FALSE;
360e24 ¤   else
f9d717 ¤   ¤   return _fIsSubmitted;
bcefe6 }
c1af5a
77af5a
c3af5a
6f7e4d /*__Editor_settings____
9daf5a
914126 ¤   Local Variables:
de7b17 ¤   tab-width: 4
5e0e6c ¤   End:
355f8c ¤   vi: ts=4 sw=4
4a9e9b ¤   vim: si
8ad062 _____________________*/
--e5e4 000017d433c40110314 Page 1 of UIutils.cpp
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
c85e90 ¤   $Id: UIutils.cpp,v 1.13.8.1 1998/11/12 03:14:03 heller Exp $
96af5a
6daf5a
6caf5a
9cf7f7 ____________________________________________________________________________*/
c75d3c #include "stdinc.h"
b6d92d #include <stdarg.h>
5a460b #include <crtdbg.h>
f3af5a
25a146 #include "pgpDebug.h"
6eadf9 #include "UIutils.h"
d28031 #include "resource.h"
b1a076 #include "pgpKeys.h"
5c5ab2 #include "PGPcl.h"
c9af5a
379f92 #define WARN_BIT¤   ¤   0x0001
c795a9 #define CONTINUE_BIT¤   0x0002
abaf5a
06fa7d static HINSTANCE g_hInstance;
a1af5a
7000fd typedef struct _HexDumpParam
3dbb36 {
8f24ff ¤   char *szText;
bb6f4e ¤   int nLength;
180971 } HexDumpParam;
e2af5a
e4af5a
74561a BOOL CALLBACK WarnUserDlgProc(HWND hwndDlg,·
746983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
985c85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
257d60 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam);
74af5a
8456a3 BOOL CALLBACK HexDumpDlgProc(HWND hwndDlg,·
540bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
16d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
fbf03f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam);
ccaf5a
e8f43b void DumpText(HWND hList, char *szText, int nLength);
fbaf5a
83af5a
b861c7 HINSTANCE UIGetInstance(void)
26bb36 {
e9734e ¤   return g_hInstance;
1eefe6 }
afaf5a
8baf5a
b888b0 void UISetInstance(HINSTANCE hInstance)
02bb36 {
9e3cfe ¤   g_hInstance = hInstance;
aaefe6 }
e9af5a
0aaf5a
ca0b12 void UIGetString(char *szBuffer, size_t nLength, UINT nID)
b6bb36 {
6ad8b4 ¤   LoadString(g_hInstance, nID, szBuffer, nLength);
f1830f ¤   return;
83efe6 }
6caf5a
89af5a
91ee88 void UIFormatString(char *szBuffer, size_t nLength, UINT nID, char *szData)
5abb36 {
2baf7d ¤   char szTemp[1024];
f8af5a
35f373 ····LoadString(g_hInstance, nID, szTemp, 1023);
0160d5 ¤   wsprintf(szBuffer, szTemp, szData);
--6bd8 0001871bd6540110314 Page 2 of UIutils.cpp
f9830f ¤   return;
38efe6 }
44af5a
5aaf5a
d0a111 void UIDisplayString(HWND hwnd, char *szBuffer)
51bb36 {
97d103 ¤   char szTitle[255];
e9af5a
f35db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
bc3fbb ¤   MessageBox(hwnd, szBuffer, szTitle, MB_OK);
23830f ¤   return;
6fefe6 }
06af5a
d5af5a
b58ec3 void UIDisplayStringID(HWND hwnd, UINT nID)
bcbb36 {
84d103 ¤   char szTitle[255];
c51ecc ¤   char szBuffer[1024];
3aaf5a
235db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
1089cc ¤   LoadString(g_hInstance, nID, szBuffer, 1023);
3e3fbb ¤   MessageBox(hwnd, szBuffer, szTitle, MB_OK);
18830f ¤   return;
e2efe6 }
51af5a
3eaf5a
1c6687 BOOL UIAskYesNoStringID(HWND hwnd, UINT nID)
47bb36 {
97d103 ¤   char szTitle[255];
a21ecc ¤   char szBuffer[1024];
7eaf5a
705db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
8289cc ¤   LoadString(g_hInstance, nID, szBuffer, 1023);
1067c5 ¤
4c59e4 ¤   return MessageBox(hwnd, szBuffer, szTitle, MB_YESNO);
a5efe6 }
d4af5a
c7af5a
d1e34d void UIDisplayErrorCode(char *szFile,·
7ba4bc ¤   ¤   ¤   ¤   ¤   ¤   int nLine,·
8d7ff0 ¤   ¤   ¤   ¤   ¤   ¤   char *szModule,·
8e74d2 ¤   ¤   ¤   ¤   ¤   ¤   int nCode)
32bb36 {
bc907b ¤   char szErrorMsg[255];
91d103 ¤   char szTitle[255];
33bb90 ¤   char szFileName[255];
4eaf5a
b9962d ¤   PGPclEncDecErrorToString(nCode, szErrorMsg, 254);
d8af5a
df237f ¤   if (szModule == NULL)
70c7a1 ¤   {
bb1eea ¤   ¤   UIGetString(szFileName, sizeof(szFileName), IDS_DLL);
1647fe ¤   ¤   szModule = szFileName;
139371 ¤   }
43af5a
3e1f29 #ifdef _DEBUG
141c4d ¤   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
470851 ¤   _CrtDbgReport(_CRT_ERROR, szFile, nLine, szModule, szErrorMsg);
7c7454 #endif
34af5a
585db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
63517a ¤   MessageBox(NULL, szErrorMsg, szTitle, MB_ICONEXCLAMATION);
55830f ¤   return;
5eefe6 }
bfaf5a
ccaf5a
e68a67 BOOL UIWarnUser(HWND hwnd, UINT nID, char *szRegValue)
7bbb36 {
056fcf ¤   HKEY hkey;
2e2cf2 ¤   char szRegKey[255];
7cbdf4 ¤   char szMessage[255];
18ac71 ¤   BOOL bContinue;
--e80b 0001045ca6640110314 Page 3 of UIutils.cpp
8e7f12 ¤   DWORD dwResult;
5ef00f ¤   DWORD dwDummy;
c42d6a ¤   DWORD dwValue;
c1563d ¤   DWORD dwType;
a611df ¤   DWORD dwSize=4;
dbaf5a
9e19de ¤   UIGetString(szMessage, 254, nID);
f54b46 ¤   UIGetString(szRegKey, 254, IDS_WARNING_REGKEY);
bbaf5a
0b0e9d ¤   RegCreateKeyEx(HKEY_CURRENT_USER, szRegKey, 0, NULL,·
a6b5c9 ¤   ¤   REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDummy);
81af5a
9849b6 ¤   if (RegQueryValueEx(hkey, szRegValue, 0, &dwType, (BYTE *) &dwValue,·
75d793 ¤   ¤   &dwSize) != ERROR_SUCCESS)
abc7a1 ¤   {
051a04 ¤   ¤   dwValue = TRUE;
2e8866 ¤   ¤   RegSetValueEx(hkey, szRegValue, 0, REG_DWORD, (BYTE *) &dwValue,·
ba2b50 ¤   ¤   ¤   sizeof(DWORD));
d79371 ¤   }
ea67c5 ¤
25d403 ¤   if (dwValue == FALSE)
8a836c ¤   ¤   return TRUE;
c0af5a
543de4 ¤   dwResult = DialogBoxParam(UIGetInstance(), MAKEINTRESOURCE(IDD_WARN),·
370773 ¤   ¤   ¤   ¤   ¤   hwnd, (DLGPROC) WarnUserDlgProc, (LPARAM) szMessage);
65af5a
db3589 ¤   dwValue = (dwResult & WARN_BIT) == WARN_BIT;
94ab06 ¤   bContinue = (dwResult & CONTINUE_BIT) == CONTINUE_BIT;
2faf5a
ed9ed0 ¤   RegSetValueEx(hkey, szRegValue, 0, REG_DWORD, (BYTE *) &dwValue,·
c4dd35 ¤   ¤   sizeof(DWORD));
746c72 ¤   RegCloseKey(hkey);
6baf5a
8e1cde ¤   return bContinue;
10efe6 }
47af5a
65af5a
cf2908 void PGPDebugMessage(const char *szMessage)
f5bb36 {
4ed103 ¤   char szTitle[255];
c1af5a
f01f29 #ifdef _DEBUG
861c4d ¤   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
eec097 ¤   _CrtDbgReport(_CRT_ERROR, NULL, NULL, NULL, szMessage);
b77454 #endif
a0af5a
5a5db8 ¤   LoadString(g_hInstance, IDS_TITLE, szTitle, 254);
f9a166 ¤   MessageBox(NULL, szMessage, szTitle, MB_ICONEXCLAMATION);
c4830f ¤   return;
ceefe6 }
6baf5a
79af5a
edb991 void UIHexDump(HWND hwnd, char *szMessage, int nLength)
2cbb36 {
f3a48d ¤   HexDumpParam lParam;
35af5a
381a75 ¤   lParam.szText = szMessage;
dfbcfa ¤   lParam.nLength = nLength;
05af5a
4ced6b ¤   DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_HEXDUMP), hwnd,·
a22994 ¤   ¤   (DLGPROC) HexDumpDlgProc, (LPARAM) &lParam);
74af5a
28830f ¤   return;
dfefe6 }
01af5a
05af5a
e5561a BOOL CALLBACK WarnUserDlgProc(HWND hwndDlg,·
b86983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
355c85 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,·
92b79e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
88bb36 {
108d02 ¤   BOOL bReturnCode = FALSE;
--dbc3 00097251dea40110314 Page 4 of UIutils.cpp
8e7f12 ¤   DWORD dwResult;
ccaf5a
1bc08d ¤   switch(uMsg)
abc7a1 ¤   {
b82940 ¤   case WM_INITDIALOG:
155b34 ¤   ¤   {
7c9289 ¤   ¤   ¤   SetWindowText(GetDlgItem(hwndDlg, IDC_WARNING), (char *) lParam);
13cdcb ¤   ¤   ¤   break;
8e0fe4 ¤   ¤   }
3aaf5a
733fcf ¤   case WM_COMMAND:
9c72a4 ¤   ¤   switch (LOWORD(wParam))
f25b34 ¤   ¤   {
6adb23 ¤   ¤   case IDC_YESCONTINUE:
60c486 ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_NOWARN) == BST_CHECKED)
592066 ¤   ¤   ¤   ¤   dwResult = CONTINUE_BIT;
d5bb8c ¤   ¤   ¤   else
af438a ¤   ¤   ¤   ¤   dwResult = CONTINUE_BIT | WARN_BIT;
7caf5a
152c0c ¤   ¤   ¤   EndDialog(hwndDlg, dwResult);
4b0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
77cdcb ¤   ¤   ¤   break;
45af5a
d28a8e ¤   ¤   case IDC_NOCONTINUE:
05c486 ¤   ¤   ¤   if (IsDlgButtonChecked(hwndDlg, IDC_NOWARN) == BST_CHECKED)
a69c9f ¤   ¤   ¤   ¤   dwResult = 0;
85bb8c ¤   ¤   ¤   else
b86555 ¤   ¤   ¤   ¤   dwResult = WARN_BIT;
19af5a
ba2c0c ¤   ¤   ¤   EndDialog(hwndDlg, dwResult);
ab0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
11cdcb ¤   ¤   ¤   break;
a20fe4 ¤   ¤   }
362f68 ¤   ¤   break;
499371 ¤   }
69af5a
b048b1 ¤   return(bReturnCode);
b5efe6 }
49af5a
f2af5a
7b56a3 BOOL CALLBACK HexDumpDlgProc(HWND hwndDlg,·
040bac ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·UINT uMsg,·
83d1da ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·WPARAM wParam,·
ffa887 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·LPARAM lParam)
75bb36 {
5f8d02 ¤   BOOL bReturnCode = FALSE;
5f3c96 ¤   HWND hList;
86af5a
65a07f ¤   hList = GetDlgItem(hwndDlg, IDC_DUMP);
38af5a
34c08d ¤   switch(uMsg)
4bc7a1 ¤   {
ad2940 ¤   case WM_INITDIALOG:
255b34 ¤   ¤   {
64371c ¤   ¤   ¤   LV_COLUMN lvcText;
5c7969 ¤   ¤   ¤   HexDumpParam *pParam;
d6af5a
cf8613 ¤   ¤   ¤   // Setup the list control columns
72ec7b ¤   ¤   ¤   lvcText.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
c8625f ¤   ¤   ¤   lvcText.fmt = LVCFMT_LEFT;
ec408f ¤   ¤   ¤   lvcText.cx = 500;
ff3a49 ¤   ¤   ¤   lvcText.pszText = "ASCII";
0a17f8 ¤   ¤   ¤   lvcText.iSubItem = -1;
0baa19 ¤   ¤   ¤   ListView_InsertColumn(hList, 0, &lvcText);
8e87c7 ¤   ¤   ¤
15ec7b ¤   ¤   ¤   lvcText.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
2a625f ¤   ¤   ¤   lvcText.fmt = LVCFMT_LEFT;
416885 ¤   ¤   ¤   lvcText.cx = 1400;
d93cc5 ¤   ¤   ¤   lvcText.pszText = "Hex";
41bc21 ¤   ¤   ¤   lvcText.iSubItem = 1;
f7d4f3 ¤   ¤   ¤   ListView_InsertColumn(hList, 1, &lvcText);
97af5a
--75bb 000eaf10e2c40110314 Page 5 of UIutils.cpp
f7491d ¤   ¤   ¤   pParam = (HexDumpParam *) lParam;
69af5a
548f66 ¤   ¤   ¤   // Fill list control with text
7c4f44 ¤   ¤   ¤   DumpText(hList, pParam->szText, pParam->nLength);
42cdcb ¤   ¤   ¤   break;
2a0fe4 ¤   ¤   }
beaf5a
023fcf ¤   case WM_COMMAND:
2272a4 ¤   ¤   switch (LOWORD(wParam))
945b34 ¤   ¤   {
7e3860 ¤   ¤   case IDOK:
c7796b ¤   ¤   ¤   EndDialog(hwndDlg, FALSE);
4b0fe0 ¤   ¤   ¤   bReturnCode = TRUE;
dfcdcb ¤   ¤   ¤   break;
2c0fe4 ¤   ¤   }
902f68 ¤   ¤   break;
479371 ¤   }
19af5a
e448b1 ¤   return(bReturnCode);
b1efe6 }
d4af5a
65af5a
7a8cc3 void DumpText(HWND hList, char *szText, int nLength)
66bb36 {
1ca993 ¤   int nX, nY;
acac24 ¤   int nHexIndex, nAsciiIndex;
de7349 ¤   int nLimit;
3f75b4 ¤   int nLines;
f092d7 ¤   char szHex[241];
05f3d0 ¤   char szAscii[81];
b7880a ¤   LV_ITEM¤lviText;
19af5a
e312de ¤   nLines = 0;
28af5a
7a96f6 ¤   for (nX=0; nX<nLength; nX+=80)
8dc7a1 ¤   {
06c8a2 ¤   ¤   nHexIndex = 0;
feda0a ¤   ¤   nAsciiIndex = 0;
9faf5a
ca6d7a ¤   ¤   if ((nX+80) > nLength)
0f1e81 ¤   ¤   ¤   nLimit = nLength;
980e1d ¤   ¤   else
438d2e ¤   ¤   ¤   nLimit = nX+80;
a2af5a
54e635 ¤   ¤   for (nY=nX; nY<nLimit; nY++)
055b34 ¤   ¤   {
6d049a ¤   ¤   ¤   wsprintf(&(szHex[nHexIndex]), "%02X ", szText[nY]);
56e788 ¤   ¤   ¤   nHexIndex += 3;
efaf5a
f41ef4 ¤   ¤   ¤   if ((szText[nY] > 31) && (szText[nY] < 127))
2886c8 ¤   ¤   ¤   ¤   wsprintf(&(szAscii[nAsciiIndex]), "%c", szText[nY]);
2efa34 ¤   ¤   ¤   else if (szText[nY] == '\n')
bdf776 ¤   ¤   ¤   {
ffc813 ¤   ¤   ¤   ¤   nX = nY-79;
5750dd ¤   ¤   ¤   ¤   nY = nLimit;
aba3a6 ¤   ¤   ¤   }
a3bb8c ¤   ¤   ¤   else
f1ea2c ¤   ¤   ¤   ¤   wsprintf(&(szAscii[nAsciiIndex]), " ");
0b8683 ¤   ¤   ¤   nAsciiIndex++;
290fe4 ¤   ¤   }
c41b52 ¤   ¤
05fcbe ¤   ¤   szHex[nHexIndex] = 0;
2ec52e ¤   ¤   szAscii[nAsciiIndex] = 0;
15af5a
215277 ¤   ¤   lviText.mask = LVIF_TEXT;
ac8762 ¤   ¤   lviText.pszText = szAscii;
a04774 ¤   ¤   lviText.iItem = nLines;
7aad9e ¤   ¤   lviText.iSubItem = 0;
dbeb13 ¤   ¤   ListView_InsertItem(hList, &lviText);
82af5a
be5277 ¤   ¤   lviText.mask = LVIF_TEXT;
eaf2ec ¤   ¤   lviText.pszText = szHex;
--324f 001a697415b40110314 Page 6 of UIutils.cpp
b74774 ¤   ¤   lviText.iItem = nLines;
d3f742 ¤   ¤   lviText.iSubItem = 1;
604b7b ¤   ¤   ListView_SetItem(hList, &lviText);
09af5a
b3adaa ¤   ¤   nLines++;
9a9371 ¤   }
c0af5a
4a830f ¤   return;
fbefe6 }
4caf5a
e3af5a
92af5a
c17e4d /*__Editor_settings____
3baf5a
684126 ¤   Local Variables:
6a7b17 ¤   tab-width: 4
c00e6c ¤   End:
f75f8c ¤   vi: ts=4 sw=4
019e9b ¤   vim: si
a6d062 _____________________*/
--7b87 0010206cb5c40110315 Page 1 of UIutils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
6367e2 ¤   $Id: UIutils.h,v 1.4.8.1 1998/11/12 03:14:04 heller Exp $
21af5a
62af5a
ddaf5a
a3f7f7 ____________________________________________________________________________*/
6d43f2 #ifndef Included_UIutils_h¤ /* [ */
c63e71 #define Included_UIutils_h
b8af5a
8c5655 #include <windows.h>
bbaf5a
ce99c6 PGP_BEGIN_C_DECLARATIONS
b2af5a
a9b2f2 HINSTANCE UIGetInstance(void);
12b523 void UISetInstance(HINSTANCE hInstance);
3733b8 void UIGetString(char *szBuffer, size_t nLength, UINT nID);
93088e void UIFormatString(char *szBuffer, size_t nLength, UINT nID, char *szData);
cc0189 void UIDisplayString(HWND hwnd, char *szBuffer);
a3f439 void UIDisplayStringID(HWND hwnd, UINT nID);
b0f0f1 BOOL UIAskYesNoStringID(HWND hwnd, UINT nID);
458599 void UIHexDump(HWND hwnd, char *szMessage, int nLength);
28e34d void UIDisplayErrorCode(char *szFile,·
0ca4bc ¤   ¤   ¤   ¤   ¤   ¤   int nLine,·
a27ff0 ¤   ¤   ¤   ¤   ¤   ¤   char *szModule,·
aaf5cb ¤   ¤   ¤   ¤   ¤   ¤   int nCode);
711713 BOOL UIWarnUser(HWND hwnd, UINT nID, char *szRegValue);
1c8c41 void PGPDebugMessage(const char *szMessage);
bdaf5a
261254 PGP_END_C_DECLARATIONS
2aaf5a
eb81bb #endif /* ] Included_utils_h */
b8af5a
2baf5a
f37e4d /*__Editor_settings____
87af5a
a64126 ¤   Local Variables:
807b17 ¤   tab-width: 4
730e6c ¤   End:
1c5f8c ¤   vi: ts=4 sw=4
e09e9b ¤   vim: si
02d062 _____________________*/
--4582 001491dbb5a40110316 Page 1 of outlook.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
84c7b7 ¤   $Id: outlook.h,v 1.2.18.1 1998/11/12 03:14:04 heller Exp $
baf7f7 ____________________________________________________________________________*/
46e92e #ifndef Included_outlook_h¤ /* [ */
eef0a6 #define Included_outlook_h
1aaf5a
294fa0 const IID IID_IOutlookGetObjectForExchExtCallback =·
d5e73b ¤   {0x0006720D,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
baaf5a
ee9271 DECLARE_INTERFACE_(IOutlookGetObjectForExchExtCallback, IUnknown)
debb36 {
c4bb98 ········// *** IUnknown methods ***
5f29ed ········STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvObj) PURE;
a5e8c8 ········STDMETHOD_(ULONG,AddRef) (THIS) ·PURE;
f0b5e1 ········STDMETHOD_(ULONG,Release) (THIS) PURE;
c7a4ff ········// *** IOutlookGetObjectForExchExtCallback methods ***
d2c295 ········STDMETHOD(GetObject) (THIS_ IUnknown **ppunk) PURE;
b193e0 ········STDMETHOD(DontCallThis)(THIS_ void **ppv) PURE;
af82f7 };
30af5a
8a1fc7 #endif /* ] Included_outlook_h */
94af5a
13af5a
647e4d /*__Editor_settings____
0baf5a
514126 ¤   Local Variables:
3a7b17 ¤   tab-width: 4
c90e6c ¤   End:
b65f8c ¤   vi: ts=4 sw=4
6e9e9b ¤   vim: si
49d062 _____________________*/
--902e 001340b054b40110317 Page 1 of pgpExch.DEF
bc6bd6 LIBRARY ········pgpExch
b50127 DESCRIPTION ····'PGP Plugin for Exchange'
6baf5a
7fef2b EXPORTS
3429b1 ····ExchEntryPoint ··················@1
--323b 00064a0965740110318 Page 1 of pgpExch.RC
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
ed8031 #include "resource.h"
aeaf5a
35e1bf #define APSTUDIO_READONLY_SYMBOLS
356c0e /////////////////////////////////////////////////////////////////////////////
26465d //
770131 // Generated from the TEXTINCLUDE 2 resource.
03465d //
19897a #include "afxres.h"
71af5a
3c6c0e /////////////////////////////////////////////////////////////////////////////
137b93 #undef APSTUDIO_READONLY_SYMBOLS
77af5a
4c6c0e /////////////////////////////////////////////////////////////////////////////
6af930 // English (U.S.) resources
16af5a
6d1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
e8ec08 #ifdef _WIN32
70e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
c29c1c #pragma code_page(1252)
161f8e #endif //_WIN32
81af5a
6d6c0e /////////////////////////////////////////////////////////////////////////////
81465d //
90b090 // Dialog
94465d //
05af5a
8b7ce5 IDD_HEXDUMP DIALOG DISCARDABLE ·0, 0, 346, 218
83e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
d0b5d2 CAPTION "Hex Dump"
251145 FONT 9, "Courier New"
594523 BEGIN
413dd1 ····DEFPUSHBUTTON ··"OK",IDOK,147,197,50,14
df8227 ····CONTROL ········"List2",IDC_DUMP,"SysListView32",LVS_REPORT |·
5e3ecc ····················LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |·
9d3b50 ····················WS_TABSTOP,7,7,332,179
38e0d1 END
58af5a
b561e0 IDD_WARN DIALOG DISCARDABLE ·0, 0, 186, 95
d8e659 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
ace487 CAPTION "PGP Plug-in for Exchange/Outlook"
88309f FONT 8, "MS Sans Serif"
7c4523 BEGIN
bb0a61 ····PUSHBUTTON ·····"&Yes",IDC_YESCONTINUE,26,54,50,14
47029e ····PUSHBUTTON ·····"&No",IDC_NOCONTINUE,112,54,50,14
aefab9 ····CTEXT ··········"Place warning here",IDC_WARNING,7,7,172,42
b148d9 ····CONTROL ········"Do not &warn me any more",IDC_NOWARN,"Button",
844d99 ····················BS_AUTOCHECKBOX | WS_TABSTOP,7,77,172,11
77e0d1 END
d9af5a
e9af5a
01f860 #ifdef APSTUDIO_INVOKED
066c0e /////////////////////////////////////////////////////////////////////////////
0a465d //
a35733 // TEXTINCLUDE
bb465d //
7caf5a
a686ef 1 TEXTINCLUDE DISCARDABLE·
df4523 BEGIN
23541e ····"resource.h\0"
36e0d1 END
b7af5a
9f7037 2 TEXTINCLUDE DISCARDABLE·
cb4523 BEGIN
eeeb23 ····"#include ""afxres.h""\r\n"
cfdb5c ····"\0"
b7e0d1 END
82af5a
da227f 3 TEXTINCLUDE DISCARDABLE·
214523 BEGIN
64ab12 ····"#include ""pgpExchVer.rc""\r\n"
--3916 0003929dc1b40110318 Page 2 of pgpExch.RC
324537 ····"#include ""..\\shared\\Working.rc""\r\n"
4e23a3 ····"#include ""..\\shared\\SharedStrings.rc""\0"
e2e0d1 END
c4af5a
d469ab #endif ···// APSTUDIO_INVOKED
f8af5a
beaf5a
e26c0e /////////////////////////////////////////////////////////////////////////////
fa465d //
31ae70 // Bitmap
37465d //
afaf5a
5a23f0 IDB_ENCRYPT ············BITMAP ·DISCARDABLE ····"Res\\encrypt.bmp"
d6e874 IDB_SIGN ···············BITMAP ·DISCARDABLE ····"Res\\sign.bmp"
b45baa IDB_DECRYPT ············BITMAP ·DISCARDABLE ····"Res\\decrypt.bmp"
90cf75 IDB_PGPKEYS ············BITMAP ·DISCARDABLE ····"Res\\pgpkeys.bmp"
437ffa IDB_ENCRYPTSIGN ········BITMAP ·DISCARDABLE ····"Res\\both.bmp"
988b52 IDB_T_ENCRYPTSIGN ······BITMAP ·DISCARDABLE ····"Res\\Tboth.bmp"
242a8d IDB_T_DECRYPT ··········BITMAP ·DISCARDABLE ····"Res\\Tdecrypt.bmp"
62e0a5 IDB_T_ENCRYPT ··········BITMAP ·DISCARDABLE ····"Res\\Tencrypt.bmp"
77132e IDB_T_PGPKEYS ··········BITMAP ·DISCARDABLE ····"Res\\Tpgpkeys.bmp"
78ed7b IDB_T_SIGN ·············BITMAP ·DISCARDABLE ····"Res\\Tsign.bmp"
baaf5a
586c0e /////////////////////////////////////////////////////////////////////////////
c0465d //
426077 // DESIGNINFO
a3465d //
ecaf5a
94f860 #ifdef APSTUDIO_INVOKED
cb70e4 GUIDELINES DESIGNINFO DISCARDABLE·
934523 BEGIN
78af4e ····IDD_HEXDUMP, DIALOG
545574 ····BEGIN
12c975 ········LEFTMARGIN, 7
ef794b ········RIGHTMARGIN, 339
1587e9 ········TOPMARGIN, 7
92953e ········BOTTOMMARGIN, 211
b17d01 ····END
15af5a
756371 ····IDD_WARN, DIALOG
c85574 ····BEGIN
43c975 ········LEFTMARGIN, 7
7c235c ········RIGHTMARGIN, 179
9087e9 ········TOPMARGIN, 7
da94b9 ········BOTTOMMARGIN, 88
577d01 ····END
61e0d1 END
1069ab #endif ···// APSTUDIO_INVOKED
b5af5a
14af5a
ff6c0e /////////////////////////////////////////////////////////////////////////////
16465d //
925e87 // String Table
56465d //
13af5a
6c6f6c STRINGTABLE DISCARDABLE·
c04523 BEGIN
6d1d4d ····IDS_TITLE ··············"PGP Plug-in for Exchange/Outlook"
4359c0 ····IDS_NO_ERR ·············"(Unknown error.)"
ef8a40 ····IDS_NO_INFO ············"(No further information on the error is available.¶
0220fc )"
f1e0d1 END
dbaf5a
db6f6c STRINGTABLE DISCARDABLE·
aa4523 BEGIN
1f1fb7 ····IDS_E_NOMEMORY ·········"Out of memory error"
cc7b4b ····IDS_DECRYPT_MENU ·······"&Decrypt/Verify"
b64f0e ····IDS_DECRYPT_STATUS ·····"Decrypts the current message and verifies any sign¶
a7d9af atures"
e67090 ····IDS_DECRYPT_TOOLTIP ····"Decrypt message and verify signature"
b5e05e ····IDS_ENCRYPT_MENU ·······"&Encrypt on send"
391859 ····IDS_ENCRYPT_STATUS ·····"Encrypt the current message before sending it"
--2e53 0003a5103cc40110318 Page 3 of pgpExch.RC
226cd4 ····IDS_ENCRYPT_TOOLTIP ····"Encrypt message before sending"
42a260 ····IDS_SIGN_MENU ··········"&Sign on send"
98e0d1 END
7eaf5a
396f6c STRINGTABLE DISCARDABLE·
194523 BEGIN
96b8fb ····IDS_SIGN_STATUS ········"Sign the current message before sending it"
1387a7 ····IDS_SIGN_TOOLTIP ·······"Sign message before sending"
dc0934 ····IDS_ASKDECRYPT ·········"This message contains encrypted text. Do you wish ¶
8e6c49 to decrypt it now?"
fd9564 ····IDS_VERSION ············"0.8"
111a9d ····IDS_ABOUT_MENU ·········"About PGP..."
a4f4f7 ····IDS_WRONG_PHRASE ·······"Wrong Pass Phrase"
d9e16d ····IDS_ENTER_PHRASE ·······"Enter PGP Pass Phrase"
45863a ····IDS_ENCRYPTSIGN_MENU ···"Encrypt and sign &now"
2fdf08 ····IDS_ENCRYPTSIGN_STATUS ·"Encrypt and sign the current message while viewing"
5e736a ····IDS_ENCRYPTSIGN_TOOLTIP "Encrypt and sign message now"
a505fc ····IDS_ADDKEY_MENU ········"Add &key"
d7d710 ····IDS_ADDKEY_STATUS ······"Add a public key to your keyring"
d98513 ····IDS_ADDKEY_TOOLTIP ·····"Add key to keyring"
66d07c ····IDS_PGPKEYS_MENU ·······"&Launch PGPkeys"
7ba6ad ····IDS_PGPKEYS_STATUS ·····"Launch the PGP Key Management program"
19b0f7 ····IDS_PGPKEYS_TOOLTIP ····"Launch PGPkeys"
88e0d1 END
3caf5a
d36f6c STRINGTABLE DISCARDABLE·
bb4523 BEGIN
0f825b ····IDS_ENCRYPTNOW_MENU ····"Encrypt now"
a9b600 ····IDS_ENCRYPTNOW_STATUS ··"Encrypt the current message while viewing"
769eea ····IDS_ENCRYPTNOW_TOOLTIP ·"Encrypt message now"
2a5189 ····IDS_SIGNNOW_MENU ·······"Sign now"
cd5401 ····IDS_SIGNNOW_STATUS ·····"Sign the current message while viewing"
853c52 ····IDS_SIGNNOW_TOOLTIP ····"Sign message now"
4e4860 ····IDS_E_INITPROFILE ······"Error initializing MAPI profile settings"
953343 ····IDS_E_SAVEPROFILE ······"Error writing MAPI profile settings"
7b8e2a ····IDS_E_BADPGPBLOCK ······"This message contains corrupted PGP data"
469f18 ····IDS_DETACHEDSIG ········"This attachment is a signature which can verify th¶
3e7b84 at an attachment that was sent to you came from the original sender. Press OK, ¶
656ff9 then double-click on the attachment that this signature should apply to."
643a50 ····IDS_PGPHELP_MENU ·······"&PGP Help Topics"
57c18d ····IDS_PGPPREFS_MENU ······"&Preferences..."
4ccbac ····IDS_PGPPREFS_STATUS ····"Configure your preferences for using PGP"
bbebc8 ····IDS_PGPHELP_STATUS ·····"Displays Help for PGP"
c8362c ····IDS_ABOUT_STATUS ·······"Displays information about PGP"
5f68aa ····IDS_ADDKEY_SUCCESS ·····"Public key(s) added to keyring successfully"
99e0d1 END
11af5a
f66f6c STRINGTABLE DISCARDABLE·
ea4523 BEGIN
98ff98 ····IDS_E_NOVERSION ········"PGP was unable to retrieve the version information¶
6693df ·for Exchange. Since this represents a potential problem in the way PGP works w¶
5a4e74 ith Exchange, the plug-in will not be loaded."
91199f ····IDS_E_INCOMPATIBLE_VERSION·
ae535e ····························"The PGP plug-in was not designed for this version ¶
6b22ec of Exchange. The plug-in will not be loaded."
797fb0 ····IDS_Q_LATER_BUILD ······"This version of Exchange is newer than the version¶
ea6040 ·that the PGP plug-in was built for. The functionality of the plug-in may be af¶
0cc441 fected by changes in the way Exchange works. Load the plug-in anyway?"
5f32a6 ····IDS_E_NOSESSION ········"Unable to retrieve the MAPI session object. Operat¶
c072a6 ion terminated."
4345f9 ····IDS_E_NOMESSAGE ········"Unable to retrieve the MAPI message object. Operat¶
f872a6 ion terminated."
d92d0f ····IDS_E_NOBODY ···········"Unable to retrieve the MAPI message body. Operatio¶
c4ef13 n terminated."
127639 ····IDS_Q_DISCARDCHANGES ···"You have made changes to the options for the PGP p¶
17c7e5 lug-in. Discard those changes?"
772e1d ····IDS_E_STAMPMESSAGE ·····"Unable to stamp message status. Operation terminat¶
cdc016 ed."
1ed643 ····IDS_ADDKEY_NEWKEYS ·····"The following keys were added to your keyring:\n\n"
c03544 ····IDS_SIG_UNTRUSTED ······"\nWarning: ·Because this key is not certified with¶
27788d ·enough\ntrusted signatures, it cannot be known with high confidence\nthat this¶
3a8ee4 ·message was actually signed by %s."
--9e19 001557e8a4640110318 Page 4 of pgpExch.RC
008939 ····IDS_SIG_VERIFIED ·······"Good signature from %s."
b8e11c ····IDS_SIG_NOKEY ··········"Could not find a public key to verify the signatur¶
c892a0 e on this message."
8f1a67 ····IDS_SIG_BAD ············"Bad signature from %s!"
cfb28b ····IDS_SIG_NONE ···········"Unable to verify signature!"
3b3d02 ····IDS_SIG_DATE ···········"\nSignature made on %s.\n"
a9d881 ····IDS_E_GETTEXT ··········"Error getting text from message window"
85e0d1 END
dfaf5a
ef6f6c STRINGTABLE DISCARDABLE·
044523 BEGIN
4cca49 ····IDS_REGKEY ·············"Software\\Network Associates\\PGP60\\PGPkeys"
370dc0 ····IDS_E_NOPGPKEYS ········"PGPkeys could not be found. You may need to re-ins¶
67d8ae tall the product."
989d25 ····IDS_WARNING_REGKEY ·····"Software\\Network Associates\\PGP60\\pgpExch\\"
1cade6 ····IDS_LOGNAME ············"Exchange/Outlook"
a5dc9c ····IDS_SIGKEYREVOKED ······"The key used to sign this message has been revoked¶
10cfc1 . The signature cannot be completely trusted."
3d4194 ····IDS_SIGKEYDISABLED ·····"The key used to sign this message has been disable¶
2947f1 d."
cfd725 ····IDS_SIGKEYEXPIRED ······"The key used to sign this message has expired. The¶
eff402 ·integrity of the signature is secure if the message was signed before the key'¶
74dc34 s expiration date.\n\nYou may need to update your keyring with the signer's lat¶
318634 est key."
1aede3 ····IDS_E_EXPIRED ··········"This version of PGP has expired. The Exchange/Outl¶
cfddd9 ook plug-in will not be available."
4b7c1b ····IDS_E_NOPGP ············"No valid PGP message blocks found"
cca079 ····IDS_E_NOKEYS ···········"No valid PGP key blocks found"
b68e6f ····IDS_Q_ATTACHMENT ·······"If you choose to encrypt or sign now, instead of o¶
931999 n send, your attachments will be removed from the message. You may still reatta¶
141775 ch them, but they will not be encrypted or signed. Do you wish to continue?"
e9d4c5 ····IDS_DLL ················"pgpExch.dll"
e99978 ····IDS_PGPKEYSEXE ·········"PGPkeys /s"
e8c34f ····IDS_PGPHELP ············"PGP55.HLP"
a1158d ····IDS_OLDEDITCTRLCLASS ···"RICHEDIT"
f93f3c ····IDS_NEWEDITCTRLCLASS ···"RichEdit20A"
57e0d1 END
afaf5a
a76f6c STRINGTABLE DISCARDABLE·
7a4523 BEGIN
e7650f ····IDS_IE40CLASS ··········"Internet Explorer_Server"
913ff7 ····IDS_WORDCLASS ··········"_WwW"
b05a40 ····IDS_RECIPIENTTITLE ·····"Recipient Selection"
f1e0d1 END
beaf5a
ca1b3a #endif ···// English (U.S.) resources
ec6c0e /////////////////////////////////////////////////////////////////////////////
2faf5a
dcaf5a
5daf5a
8bce8c #ifndef APSTUDIO_INVOKED
0b6c0e /////////////////////////////////////////////////////////////////////////////
55465d //
838464 // Generated from the TEXTINCLUDE 3 resource.
b2465d //
7cd0c7 #include "pgpExchVer.rc"
92f88e #include "..\shared\Working.rc"
fb96d0 #include "..\shared\SharedStrings.rc"
0b6c0e /////////////////////////////////////////////////////////////////////////////
7b8072 #endif ···// not APSTUDIO_INVOKED
55af5a
--913d 001227ddcd940110319 Page 1 of pgpExch.reg
98fb29 REGEDIT4
a0af5a
3504f3 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions]
91a0b3 @=" "
226278 "PGP Plugin"="4.0;pgpExch.dll;1;01000111111100;1001110"
--3c65 00101e094ba4011031a Page 1 of pgpExchVer.rc
b3eddb // VERSIONINFO structure which automatically include version
d7555d // string from PGPversion.h
05465d //
3c0380 #include <winver.h>
b08c2d #include "..\include\pgpversion.h"
50af5a
ba6c0e /////////////////////////////////////////////////////////////////////////////
9c465d //
56c5f2 // Version
dd465d //
5daf5a
108df2 VS_VERSION_INFO VERSIONINFO
a0eb97 ·FILEVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
c6d8e3 ·PRODUCTVERSION PGPVERSIONMAJOR,PGPVERSIONMINOR,PGPVERSIONSUBMINOR,0
9da381 ·FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
5e1f29 #ifdef _DEBUG
ac7c0e ·FILEFLAGS VS_FF_DEBUG
f6db21 #else
cf12ca ·FILEFLAGS 0x0L
af7454 #endif
ff03bb ·FILEOS VOS__WINDOWS32
115212 ·FILETYPE VFT_DLL
237247 ·FILESUBTYPE VFT2_UNKNOWN
1c4523 BEGIN
c62c72 ····BLOCK "StringFileInfo"
a55574 ····BEGIN
dd70ac ········BLOCK "040904b0"
f252d6 ········BEGIN
2380b6 ············VALUE "CompanyName", PGPCOMPANYNAME
fed9f7 ············VALUE "FileDescription", "PGP Plug-in for Exchange/Outlook E-mail c¶
d587f4 lient\0"
eec1dd ············VALUE "FileVersion", PGPVERSIONSTRING
490edc ············VALUE "InternalName", "pgpExch\0"
e38ed7 ············VALUE "LegalCopyright", PGPCOPYRIGHT
802bfd ············VALUE "LegalTrademarks", PGPTRADEMARKS
012e34 ············VALUE "OriginalFilename", "pgpExch.dll\0"
629317 ············VALUE "ProductName", PGPPRODUCTNAME
42d1a3 ············VALUE "ProductVersion", PGPVERSIONSTRING
41f37f ········END
467d01 ····END
3c26ab ····BLOCK "VarFileInfo"
a65574 ····BEGIN
494b11 ········VALUE "Translation", 0x409, 1200
8a7d01 ····END
22e0d1 END
8baf5a
3baf5a
01af5a
--8a86 00123a6ec694011031b Page 1 of readme.txt
1a6cb9 PGP Plugin for Exchange
3a3862 -----------------------
ceaf5a
3e6dc3 INSTALLATION
8caf5a
0b843d 1) Copy the file "pgpExch.dll" to your Windows\System or WINNT35\SYSTEM32 direc¶
41ae18 tory
b40a7b 2) Double-click on the file "pgpExch.reg" to set the proper Registry settings
c0af5a
717dbf Send comments to dgal@pgp.com
57af5a
7f913d - Damon Gallaty
23af5a
--146f 00090a87ea64011031c Page 1 of resource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
a1bb17 // Used by pgpExch.RC
37465d //
d24403 #define IDS_TITLE ······················20
41045e #define IDS_NO_ERR ·····················21
bb6aee #define IDS_NO_INFO ····················22
7a1040 #define IDD_HEXDUMP ····················22
643069 #define IDS_E_NOMEMORY ·················37
2139ca #define IDS_DECRYPT_MENU ···············38
17e782 #define IDS_DECRYPT_STATUS ·············39
8074bf #define IDS_DECRYPT_TOOLTIP ············40
42c97f #define IDS_ENCRYPT_MENU ···············41
dd2487 #define IDS_ENCRYPT_STATUS ·············42
04eca7 #define IDD_WARN ·······················42
24f57f #define IDS_ENCRYPT_TOOLTIP ············43
55c40d #define IDB_T_ENCRYPTSIGN ··············44
31c022 #define IDB_T_DECRYPT ··················45
7609de #define IDB_T_ENCRYPT ··················46
863119 #define IDS_SIGN_MENU ··················47
b3e95e #define IDB_T_PGPKEYS ··················47
87bc0a #define IDS_SIGN_STATUS ················48
836489 #define IDB_T_SIGN ·····················48
f4a283 #define IDS_SIGN_TOOLTIP ···············49
c75a7d #define IDS_ASKDECRYPT ·················50
752d2c #define IDS_VERSION ····················51
3b04fe #define IDS_ABOUT_MENU ·················52
7b20f3 #define IDS_WRONG_PHRASE ···············53
465302 #define IDS_ENTER_PHRASE ···············54
cff794 #define IDS_ENCRYPTSIGN_MENU ···········55
741bcb #define IDS_ENCRYPTSIGN_STATUS ·········56
14c2da #define IDS_ENCRYPTSIGN_TOOLTIP ········57
5cc62c #define IDS_ADDKEY_MENU ················58
c94bba #define IDS_ADDKEY_STATUS ··············59
a4520c #define IDS_ADDKEY_TOOLTIP ·············60
f40bbe #define IDS_PGPKEYS_MENU ···············61
dfe646 #define IDS_PGPKEYS_STATUS ·············62
4a37be #define IDS_PGPKEYS_TOOLTIP ············63
d1b946 #define IDS_ENCRYPTNOW_MENU ············64
0be564 #define IDS_ENCRYPTNOW_STATUS ··········65
139401 #define IDS_ENCRYPTNOW_TOOLTIP ·········66
8e40d7 #define IDS_SIGNNOW_MENU ···············67
b1048f #define IDS_SIGNNOW_STATUS ·············68
b9d577 #define IDS_SIGNNOW_TOOLTIP ············69
788461 #define IDS_E_INITPROFILE ··············70
5606f6 #define IDS_E_SAVEPROFILE ··············71
c27bd1 #define IDS_E_BADPGPBLOCK ··············72
0097bf #define IDS_DETACHEDSIG ················73
582c8b #define IDS_PGPHELP_MENU ···············74
556adf #define IDS_PGPPREFS_MENU ··············75
8fd466 #define IDS_PGPPREFS_STATUS ············76
e6c173 #define IDS_PGPHELP_STATUS ·············77
d0e7d8 #define IDS_ABOUT_STATUS ···············78
79b559 #define IDS_ADDKEY_SUCCESS ·············79
b85edd #define IDS_E_NOVERSION ················80
2e5d16 #define IDS_E_INCOMPATIBLE_VERSION ·····81
db91b4 #define IDS_Q_LATER_BUILD ··············82
d363b7 #define IDS_E_NOSESSION ················83
dfa3dd #define IDS_E_NOMESSAGE ················84
0a3ce1 #define IDS_E_NOBODY ···················85
1119e2 #define IDS_Q_DISCARDCHANGES ···········86
4912d8 #define IDS_E_STAMPMESSAGE ·············87
5805de #define IDS_ADDKEY_NEWKEYS ·············88
767a62 #define IDS_SIG_UNCERTIFIED ············89
64a359 #define IDS_SIG_UNTRUSTED ··············89
3e9742 #define IDS_SIG_VERIFIED ···············90
45acff #define IDS_SIG_UNVERIFIED ·············91
9e5dae #define IDS_SIG_NOKEY ··················91
80d331 #define IDS_SIG_BAD ····················92
67004a #define IDS_SIG_NONE ···················93
2de20a #define IDS_SIG_DATE ···················94
9017c8 #define IDS_E_GETTEXT ··················95
--e9b8 001fe9569534011031c Page 2 of resource.h
bd58ed #define IDS_REGKEY ·····················96
a0242b #define IDS_E_NOPGPKEYS ················97
e3e9f6 #define IDS_WARNING_REGKEY ·············98
755e53 #define IDS_LOGNAME ····················99
8c0fb0 #define IDS_SIGKEYREVOKED ··············100
fef5c2 #define IDD_MAINPROP ···················101
781f03 #define IDS_SIGKEYDISABLED ·············101
157b37 #define IDS_SIGKEYEXPIRED ··············102
2a91d7 #define IDS_E_EXPIRED ··················103
2f97c7 #define IDS_E_NOPGP ····················104
892008 #define IDS_E_NOKEYS ···················105
d57fc3 #define IDS_Q_ATTACHMENT ···············106
d284e8 #define IDB_ENCRYPT ····················107
9bb3ab #define IDS_DLL ························107
e9bc53 #define IDB_SIGN ·······················108
078422 #define IDS_PGPKEYSEXE ·················108
afd79e #define IDS_PGPHELP ····················109
251204 #define IDS_OLDEDITCTRLCLASS ···········110
71de4b #define IDS_NEWEDITCTRLCLASS ···········111
578965 #define IDB_DECRYPT ····················112
228051 #define IDS_IE40CLASS ··················112
858c06 #define IDB_ADDKEY ·····················113
ae2b01 #define IDS_WORDCLASS ··················113
841a6d #define IDB_PGPKEYS ····················114
4db318 #define IDS_RECIPIENTTITLE ·············114
5a8cce #define IDB_PGPNOW ·····················115
93e1b5 #define IDB_ENCRYPTSIGN ················115
146632 #define IDC_ABOUT ······················1013
03f954 #define IDC_DECRYPT ····················1019
381a77 #define IDC_ASKDECRYPT ·················1020
eeca6c #define IDC_ADDKEY ·····················1020
2d0ad6 #define IDC_PGPPREFS ···················1022
0603a6 #define IDC_DUMP ·······················1024
f9fc61 #define IDC_YESCONTINUE ················1031
8e82b0 #define IDC_NOCONTINUE ·················1032
2f8fff #define IDC_NOWARN ·····················1033
f2ce0d #define IDC_WARNING ····················1034
4faf5a
db11aa // Next default values for new objects
bfac6a //·
f2f860 #ifdef APSTUDIO_INVOKED
f23f23 #ifndef APSTUDIO_READONLY_SYMBOLS
b0691a #define _APS_NEXT_RESOURCE_VALUE ·······49
cf611c #define _APS_NEXT_COMMAND_VALUE ········40001
796730 #define _APS_NEXT_CONTROL_VALUE ········1035
581285 #define _APS_NEXT_SYMED_VALUE ··········101
a87454 #endif
fe7454 #endif

--02e1 0005f73e6ed4011031d Page 1 of AddKey.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
9c1273 ¤   $Id: AddKey.c,v 1.1.8.1 1998/11/12 03:14:06 heller Exp $
1ef7f7 ____________________________________________________________________________*/
42af5a
875060 // System Headers·
eb5655 #include <windows.h>
823d0b #include <windowsx.h>
08bb5f #include <assert.h>
80af5a
fc5582 // PGPsdk Headers
afe2ff #include "pgpConfig.h"
82a076 #include "pgpKeys.h"
362f8d #include "pgpErrors.h"
2ea845 #include "pgpUtilities.h"·
1891b9 #include "pgpSDKPrefs.h"
aaaf5a
3e2062 // Shared Headers
5e5ab2 #include "PGPcl.h"
b6af5a
fbe8e0 // Project Headers
1705f4 #include "AddKey.h"
71af5a
216bfb PGPError AddKey(HWND hwnd, PGPContextRef context,·
14150d ¤   ¤   ¤   ¤   PGPtlsContextRef tlsContext, PGPOptionListRef options);
dfaf5a
50af5a
efbcc5 PGPError AddKeyBuffer(HWND hwnd, PGPContextRef context,·
90efb3 ¤   ¤   ¤   ¤   ¤   ··PGPtlsContextRef tlsContext, void* pInput,·
b732aa ¤   ¤   ¤   ¤   ¤   ··DWORD dwInSize)
f4bb36 {
688f52 ¤   PGPError¤   ¤   ¤   err;
5b5ec1 ¤   PGPOptionListRef¤   options;
bdaf5a
bb8601 ¤   err = PGPBuildOptionList(context, &options,
109ab5 ¤   ¤   ¤   PGPOInputBuffer( context, (PGPByte *) pInput, dwInSize ),
669425 ¤   ¤   ¤   PGPOLastOption( context ) );
1baf5a
8d82f0 ¤   if (IsPGPError(err))
e1c9db ¤   ¤   return err;
95af5a
3f7002 ¤   err = AddKey(hwnd, context, tlsContext, options);
a5af5a
fef71e ¤   PGPFreeOptionList(options);
335ea8 ¤   return err;
a4efe6 }
5eaf5a
76af5a
4aa7a9 PGPError AddKeyFile(HWND hwnd, PGPContextRef context,·
c93e37 ¤   ¤   ¤   ¤   ¤   PGPtlsContextRef tlsContext, char *szInFile)
18bb36 {
0d8f52 ¤   PGPError¤   ¤   ¤   err;
e98d27 ¤   PGPFileSpecRef¤ ¤   inputFile;
175ec1 ¤   PGPOptionListRef¤   options;
5baf5a
f7df37 ¤   err = PGPNewFileSpecFromFullPath(context, szInFile, &inputFile);
5282f0 ¤   if (IsPGPError(err))
82c9db ¤   ¤   return err;
c8af5a
1d8601 ¤   err = PGPBuildOptionList(context, &options,
0fbfac ¤   ¤   ¤   PGPOInputFile( context, inputFile ),
af9425 ¤   ¤   ¤   PGPOLastOption( context ) );
f7af5a
3882f0 ¤   if (IsPGPError(err))
b3c7a1 ¤   {
37acba ¤   ¤   PGPFreeFileSpec(inputFile);
10c9db ¤   ¤   return err;
5f9371 ¤   }
--0d12 0015b6fb3a34011031d Page 2 of AddKey.c
e0af5a
e77002 ¤   err = AddKey(hwnd, context, tlsContext, options);
e2af5a
372746 ¤   PGPFreeFileSpec(inputFile);
c2f71e ¤   PGPFreeOptionList(options);
225ea8 ¤   return err;
57efe6 }
62af5a
e6af5a
656bfb PGPError AddKey(HWND hwnd, PGPContextRef context,·
7c8445 ¤   ¤   ¤   ¤   PGPtlsContextRef tlsContext, PGPOptionListRef options)
30bb36 {
948f52 ¤   PGPError¤   ¤   ¤   err;
6efb26 ¤   PGPKeySetRef¤   ¤   importKeySet;
faaf5a
6166e6 ¤   UpdateWindow(hwnd);
71af5a
c3e947 ¤   err = PGPsdkLoadDefaultPrefs(context);
3582f0 ¤   if (IsPGPError(err))
74c9db ¤   ¤   return err;
a5af5a
ecc380 ¤   err = PGPImportKeySet(context, &importKeySet,
d7914c ¤   ¤   ¤   options,
be9425 ¤   ¤   ¤   PGPOLastOption( context ) );
4aaf5a
4482f0 ¤   if (IsPGPError(err))
32c9db ¤   ¤   return err;
6caf5a
769bb2 ¤   if (importKeySet)·
69c7a1 ¤   {
7ac390 ¤   ¤   PGPUInt32¤  numKeys;
131b52 ¤   ¤
568c0e ¤   ¤   (void)PGPCountKeys(importKeySet, &numKeys );
e13a8f ¤   ¤   if ( numKeys > 0)·
9e5b34 ¤   ¤   {
71cad0 ¤   ¤   ¤   err = PGPclQueryAddKeys(context, tlsContext, hwnd, importKeySet,·
47d98c ¤   ¤   ¤   ¤   ¤   NULL);
670fe4 ¤   ¤   }
6faf5a
861792 ¤   ¤   PGPFreeKeySet(importKeySet);
d49371 ¤   }
0a67c5 ¤
8b5ea8 ¤   return err;
95efe6 }
f8af5a
36af5a
4daf5a
30af5a
6f7e4d /*__Editor_settings____
aeaf5a
a94126 ¤   Local Variables:
457b17 ¤   tab-width: 4
b00e6c ¤   End:
b45f8c ¤   vi: ts=4 sw=4
dc9e9b ¤   vim: si
5bd062 _____________________*/
--1ef7 0019212d0ae4011031e Page 1 of AddKey.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
06b9dd ¤   $Id: AddKey.h,v 1.1.8.1 1998/11/12 03:14:07 heller Exp $
f0f7f7 ____________________________________________________________________________*/
9ad45d #ifndef Included_AddKey_h¤  /* [ */
bf513c #define Included_AddKey_h
89af5a
a02f8d #include "pgpErrors.h"
bfaf5a
583379 #ifdef __cplusplus
226dad extern "C" {
b47454 #endif
e7af5a
47bcc5 PGPError AddKeyBuffer(HWND hwnd, PGPContextRef context,·
5defb3 ¤   ¤   ¤   ¤   ¤   ··PGPtlsContextRef tlsContext, void* pInput,·
a50a42 ¤   ¤   ¤   ¤   ¤   ··DWORD dwInSize);
68af5a
30a7a9 PGPError AddKeyFile(HWND hwnd, PGPContextRef context,·
044522 ¤   ¤   ¤   ¤   ¤   PGPtlsContextRef tlsContext, char *szInFile);
caaf5a
253379 #ifdef __cplusplus
eeefe6 }
c57454 #endif
9daf5a
f9808d #endif /* ] Included_AddKey_h */
9daf5a
c2af5a
247e4d /*__Editor_settings____
88af5a
e94126 ¤   Local Variables:
897b17 ¤   tab-width: 4
2b0e6c ¤   End:
795f8c ¤   vi: ts=4 sw=4
899e9b ¤   vim: si
92d062 _____________________*/
--b4b9 000ac5adc804011031f Page 1 of BlockUtils.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
d81ee2 ¤   $Id: BlockUtils.c,v 1.6.8.1 1998/11/12 03:14:07 heller Exp $
aef7f7 ____________________________________________________________________________*/
9eaf5a
d79b16 // System Headers
1c5655 #include <windows.h>
02bb5f #include <assert.h>
97af5a
13af5a
663f3c // CDK Headers
610d08 #include "pgpMem.h"
78af5a
c6e8e0 // Project Headers
a8d2cf #include "BlockUtils.h"
31af5a
46d2ab ¤   const char *
b38348 FindMatchingBytes(
0ca1b5 ¤   const char *¤   buffer,
efcef8 ¤   ulong¤  ¤   ¤   length,
f34a56 ¤   const char *¤   findIt,
e99fbc ¤   ulong¤  ¤   ¤   findItLength
8927e6 ¤   )
0ebb36 {
2be602 ¤   const char *¤   result¤ = NULL;
8767c5 ¤
48e195 ¤   assert( length >= 1 ); // allow 'length' to be 0
1e67c5 ¤
f10a1e ¤   if ( ¤  length != 0 &&
92bfd8 ¤   ¤   ¤   findItLength != 0 &&
c0a657 ¤   ¤   ¤   findItLength <= length )
cbc7a1 ¤   {
60d53f ¤   ¤   const char *¤   cur;
323d52 ¤   ¤   const char *¤   last;
867f7e ¤   ¤   const char¤ ¤   searchChar¤ = findIt[ 0 ];
c1af5a
7d5040 ¤   ¤   cur¤¤   = buffer;
cfc9e5 ¤   ¤   last¤   = cur + ( length - findItLength );
e2d2a2 ¤   ¤   while ( cur <= last )
af5b34 ¤   ¤   {
2d4cea ¤   ¤   ¤   if ( *cur == searchChar )
b9f776 ¤   ¤   ¤   {
d631c8 ¤   ¤   ¤   ¤   if ( pgpMemoryEqual( cur, findIt, findItLength ) )
0172c3 ¤   ¤   ¤   ¤   {
1892ea ¤   ¤   ¤   ¤   ¤   result¤ = cur;
9e14c3 ¤   ¤   ¤   ¤   ¤   break;
872613 ¤   ¤   ¤   ¤   }
54a3a6 ¤   ¤   ¤   }
07af5a
f8bdb8 ¤   ¤   ¤   ++cur;
0b0fe4 ¤   ¤   }
e69371 ¤   }
83af5a
fe67c5 ¤
aa4c6e ¤   return( result );
43efe6 }
6faf5a
38af5a
20af5a
e3af5a
3b5e1f /*______________________________________________________________
69f6e3 ¤   Find a block of the form:
b567c5 ¤
e66520 ¤   linestart
89c9f6 ¤   ...
aecdf2 ¤   lineEnd
1d67c5 ¤
acdbd7 ¤   Return the offset at which it begins and its length.
--a504 000f68b5a204011031f Page 2 of BlockUtils.c
3aa623 ¤   Length includes the begin/end lines and the trailing·
d46cbd ¤   carriage return/line feed.
44cc84 ______________________________________________________________*/
897e69 ¤   Boolean
dfd03e FindBlock(
a66914 ¤   const void *¤   ¤   inBuffer,
b13593 ¤   ulong¤  ¤   ¤   ¤   inBufferSize,
45b608 ¤   const char*¤¤   ¤   startLine,
406527 ¤   const char*¤¤   ¤   endLine,
fbe3e4 ¤   ulong *¤¤   ¤   ¤   encryptedBlockStart,
786d9d ¤   ulong *¤¤   ¤   ¤   encryptedBlockSize )
26bb36 {
d38060 ¤   Boolean¤¤   ¤   foundBlock¤ = FALSE;
25e162 ¤   const char *¤   cur;
855616 ¤   const char *¤   beginning¤  = NULL;
0a133a ¤   const char *¤   end¤= NULL;
82514b ¤   const char¤ ¤   kCarriageReturnChar¤= 13;
2c7df3 ¤   const char¤ ¤   kLineFeedChar¤  ¤   = 10;
25c9ae ¤   const char *¤   inBufferLast;
061c29 ¤   int¤¤   ¤   ¤   nReplyNum = 0;
3067c5 ¤
f2d2f4 ¤   cur¤= (const char *)inBuffer;
155394 ¤   inBufferLast¤   = ( cur + inBufferSize ) -1;
75af5a
ac32c7 #define IsEOL( c )¤ ( (c) == '\r' || (c) == '\n' )
a867c5 ¤
8087f3 ¤   while ( cur <= inBufferLast )
00c7a1 ¤   {
5ba2c8 ¤   ¤   beginning = FindMatchingBytes(¤ cur,·
b27a1c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   inBufferSize,·
419a7a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (const char *)startLine,·
3fcb16 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen( startLine ) );
95af5a
bef4dc ¤   ¤   nReplyNum = 0;
38af5a
0171ab ¤   ¤   if (!beginning )
e7cdcb ¤   ¤   ¤   break;
dfaf5a
d629f0 ¤   ¤   while ((beginning != inBuffer) && !IsEOL( *(beginning - 1) ) )
6b5b34 ¤   ¤   {
f1b5b1 ¤   ¤   ¤   beginning--;
b2488a ¤   ¤   ¤   nReplyNum++;
d40fe4 ¤   ¤   }
dbaf5a
ce38e5 /*
5b8feb ¤   ¤   if (cur == inBuffer) || IsEOL( *(cur - 1) ) )
5b7fe0 */
22cdcb ¤   ¤   ¤   break;
34af5a
2d38e5 /*
61f323 ¤   ¤   // string doesn't start at beginning of line--skip it
1a83a7 ¤   ¤   cur¤= beginning + strlen( startLine );
d87fe0 */
559371 ¤   }
eaaf5a
8987bb ¤   if ( beginning )·
9ac7a1 ¤   {
1e44a0 ¤   ¤   ulong¤  ¤   ¤   bytesRemaining;
60a7bd ¤   ¤   int¤¤   ¤   ¤   nEndReplyNum = 0;
73af5a
9cb4a4 ¤   ¤   *encryptedBlockStart = beginning - (const char *)inBuffer;
88af5a
63dd46 ¤   ¤   cur¤= beginning + strlen(startLine ) + nReplyNum;
f0af5a
bc135b ¤   ¤   bytesRemaining¤ = inBufferSize - *encryptedBlockStart;
56af5a
1a6880 ¤   ¤   while ( cur <= inBufferLast )
ce5b34 ¤   ¤   {
cf038d ¤   ¤   ¤   end¤= FindMatchingBytes(¤   cur,·
fbefe5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   bytesRemaining,
c6696e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (const char *)endLine,
f627b1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen( endLine ) );
--c0f7 00078a645b34011031f Page 3 of BlockUtils.c
89895e ¤   ¤   ¤   if ( !end )·
b9f622 ¤   ¤   ¤   ¤   break;
79af5a
8c80d7 ¤   ¤   ¤   nEndReplyNum = 0;
d20a5e ¤   ¤   ¤   while (!IsEOL( *(end - 1) ) )
49f776 ¤   ¤   ¤   {
b01816 ¤   ¤   ¤   ¤   end--;
6ad0a4 ¤   ¤   ¤   ¤   nEndReplyNum++;
f2a3a6 ¤   ¤   ¤   }
dfaf5a
a987c7 ¤   ¤   ¤
3d38e5 /*
dbd23c ¤   ¤   ¤   if ( IsEOL( *(end - 1 ) ) )
78f776 ¤   ¤   ¤   {
697fe0 */
1701e7 ¤   ¤   ¤   if (nReplyNum == nEndReplyNum)
31f776 ¤   ¤   ¤   {
e45d86 ¤   ¤   ¤   ¤   // advance past line end,·
d40fe5 ¤   ¤   ¤   ¤   // which could be <CR><LF> or <LF> or <CR>
b1b872 ¤   ¤   ¤   ¤   cur¤= end + strlen( endLine ) + nReplyNum;
6aaf5a
234834 ¤   ¤   ¤   ¤   if ( *cur == kCarriageReturnChar )
0172c3 ¤   ¤   ¤   ¤   {
1064b0 ¤   ¤   ¤   ¤   ¤   ++cur;
988e17 ¤   ¤   ¤   ¤   ¤   if ( *cur == kLineFeedChar )
247098 ¤   ¤   ¤   ¤   ¤   ¤   ++cur;
3b2613 ¤   ¤   ¤   ¤   }
fbb477 ¤   ¤   ¤   ¤   else if ( *cur == kLineFeedChar )
cf72c3 ¤   ¤   ¤   ¤   {
ec64b0 ¤   ¤   ¤   ¤   ¤   ++cur;
072613 ¤   ¤   ¤   ¤   }
d5af5a
d17250 ¤   ¤   ¤   ¤   *encryptedBlockSize¤= ( cur - (const char *)inBuffer) -·
22f6ee ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   *encryptedBlockStart;
79af5a
653056 ¤   ¤   ¤   ¤   foundBlock¤ = TRUE;
f0f622 ¤   ¤   ¤   ¤   break;
30a3a6 ¤   ¤   ¤   }
5eaf5a
55ad70 ¤   ¤   ¤   cur¤= end + strlen( endLine );
7e0fe4 ¤   ¤   }
6c9371 ¤   }
2167c5 ¤
718195 ¤   return( foundBlock );
9eefe6 }
34af5a
ff5e1f /*______________________________________________________________
83f6e3 ¤   Find a block of the form:
1267c5 ¤
380fa4 -----BEGIN PGP SIGNED MESSAGE-----
982448 ...
2ae38f -----BEGIN PGP SIGNATURE-----
0c2448 ...
65e726 -----END PGP SIGNATURE-----
dc67c5 ¤
e6dbd7 ¤   Return the offset at which it begins and its length.
fca623 ¤   Length includes the begin/end lines and the trailing·
186cbd ¤   carriage return/line feed.
7dcc84 ______________________________________________________________*/
107e69 ¤   Boolean
36a4ee FindSignedBlock(
5a4f2f ¤   const void *¤   inBuffer,
beef37 ¤   ulong¤  ¤   ¤   inBufferSize,
d5e94d ¤   ulong *¤¤   ¤   encryptedBlockStart,
d16734 ¤   ulong *¤¤   ¤   encryptedBlockSize )
eabb36 {
84fb20 ¤   const char¤ ¤   kBeginString[]¤ = "-----BEGIN PGP SIGNED MESSAGE-----";
419a76 ¤   const char¤ ¤   kEndString[]¤   = "-----END PGP SIGNATURE-----";
1d67c5 ¤
3b70d9 ¤   return( FindBlock(¤ inBuffer,·
f22c5d ¤   ¤   ¤   ¤   ¤   ¤   inBufferSize,·
7827fa ¤   ¤   ¤   ¤   ¤   ¤   kBeginString,·
--6148 001e7ee225f4011031f Page 4 of BlockUtils.c
195b8d ¤   ¤   ¤   ¤   ¤   ¤   kEndString,·
e21e98 ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockStart,·
e98c99 ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockSize ) );
20efe6 }
49af5a
80af5a
635e1f /*______________________________________________________________
5ef6e3 ¤   Find a block of the form:
e067c5 ¤
c3764c ¤   -----BEGIN PGP MESSAGE-----
2d0536 ¤   .....
18761b ¤   -----END PGP MESSAGE-----
e767c5 ¤
7fdbd7 ¤   Return the offset at which it begins and its length.
71a623 ¤   Length includes the begin/end lines and the trailing·
a36cbd ¤   carriage return/line feed.
c5cc84 ______________________________________________________________*/
797e69 ¤   Boolean
b2070c FindEncryptedBlock(
b64f2f ¤   const void *¤   inBuffer,
16ef37 ¤   ulong¤  ¤   ¤   inBufferSize,
48e94d ¤   ulong *¤¤   ¤   encryptedBlockStart,
176734 ¤   ulong *¤¤   ¤   encryptedBlockSize )
eabb36 {
c00525 ¤   const char¤ ¤   kBeginString[]¤ = "-----BEGIN PGP MESSAGE-----";
1e9c13 ¤   const char¤ ¤   kEndString[]¤   = "-----END PGP MESSAGE-----";
d767c5 ¤
5c70d9 ¤   return( FindBlock(¤ inBuffer,·
772c5d ¤   ¤   ¤   ¤   ¤   ¤   inBufferSize,·
7f27fa ¤   ¤   ¤   ¤   ¤   ¤   kBeginString,·
675b8d ¤   ¤   ¤   ¤   ¤   ¤   kEndString,·
1b1e98 ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockStart,·
fa8c99 ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockSize ) );
e4efe6 }
aaaf5a
0eaf5a
e65e1f /*______________________________________________________________
9ff6e3 ¤   Find a block of the form:
3967c5 ¤
41a8e8 ¤   -----BEGIN PGP KEY-----
020536 ¤   .....
2eec75 ¤   -----END PGP KEY-----
6567c5 ¤
d7dbd7 ¤   Return the offset at which it begins and its length.
9ba623 ¤   Length includes the begin/end lines and the trailing·
bd6cbd ¤   carriage return/line feed.
2bcc84 ______________________________________________________________*/
bb7e69 ¤   Boolean
5d6e0a FindPGPKeyBlock(
2a4f2f ¤   const void *¤   inBuffer,
eeef37 ¤   ulong¤  ¤   ¤   inBufferSize,
24e94d ¤   ulong *¤¤   ¤   encryptedBlockStart,
816734 ¤   ulong *¤¤   ¤   encryptedBlockSize )
52bb36 {
83aa4d ¤   const char¤ ¤   kBeginString[]¤ = "-----BEGIN PGP PUBLIC KEY BLOCK-----";
6f3a66 ¤   const char¤ ¤   kEndString[]¤   = "-----END PGP PUBLIC KEY BLOCK-----";
ee67c5 ¤
2070d9 ¤   return( FindBlock(¤ inBuffer,·
722c5d ¤   ¤   ¤   ¤   ¤   ¤   inBufferSize,·
d727fa ¤   ¤   ¤   ¤   ¤   ¤   kBeginString,·
115b8d ¤   ¤   ¤   ¤   ¤   ¤   kEndString,·
861e98 ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockStart,·
e98c99 ¤   ¤   ¤   ¤   ¤   ¤   encryptedBlockSize ) );
abefe6 }
faaf5a
bcaf5a
56af5a
e7af5a
--32c4 001e31ff9ef40110320 Page 1 of BlockUtils.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
b77cf5 ¤   $Id: BlockUtils.h,v 1.2.18.1 1998/11/12 03:14:08 heller Exp $
24f7f7 ____________________________________________________________________________*/
01470f #ifndef Included_BlockUtils_h¤  /* [ */
f8ee42 #define Included_BlockUtils_h
2eaf5a
e502d5 #include "PGPTypes.h"
09af5a
9aaf5a
8d3379 #ifdef __cplusplus
f26dad extern "C" {
e77454 #endif
6daf5a
cdaf5a
71040b const char *¤
cbe5e9 FindMatchingBytes(¤ const char * buffer,·
0f979d ¤   ¤   ¤   ¤   ¤   ulong length,
b82d81 ¤   ¤   ¤   ¤   ¤   const char * findIt,·
24f36a ¤   ¤   ¤   ¤   ¤   ulong findItLength );
74ae30 ¤   ¤   ¤   ¤   ¤
51c847 PGPBoolean¤
b62a51 FindBlock(¤ const void * inBuffer, ·
4516ae ¤   ¤   ¤   ulong inBufferSize,
491828 ¤   ¤   ¤   const char* startLine,·
11f213 ¤   ¤   ¤   const char* endLine,
c53e44 ¤   ¤   ¤   ulong * encryptedBlockStart,·
bff5e0 ¤   ¤   ¤   ulong * encryptedBlockSize );
ac67c5 ¤
d5c847 PGPBoolean¤
53eb3e FindSignedBlock(const void * inBuffer, ·
c79d52 ¤   ¤   ¤   ¤   ulong inBufferSize,
9c0781 ¤   ¤   ¤   ¤   ulong * encryptedBlockStart,·
71cc25 ¤   ¤   ¤   ¤   ulong * encryptedBlockSize );
6caf5a
10c847 PGPBoolean¤
26a4da FindEncryptedBlock(¤const void * inBuffer, ·
d85807 ¤   ¤   ¤   ¤   ¤   ulong inBufferSize,
5b48bf ¤   ¤   ¤   ¤   ¤   ulong * encryptedBlockStart,·
44831b ¤   ¤   ¤   ¤   ¤   ulong * encryptedBlockSize );
f1af5a
31c847 PGPBoolean¤
f8d3e4 FindPGPKeyBlock(const void * inBuffer, ·
2a9d52 ¤   ¤   ¤   ¤   ulong inBufferSize,
ec0781 ¤   ¤   ¤   ¤   ulong * encryptedBlockStart,·
d9cc25 ¤   ¤   ¤   ¤   ulong * encryptedBlockSize );
f3af5a
6aaf5a
803379 #ifdef __cplusplus
4eefe6 }
f37454 #endif
e8af5a
d5af5a
c9af5a
d18b7b #endif /* ] Included_BlockUtils_h */
bcaf5a
1aaf5a
037e4d /*__Editor_settings____
15af5a
0d4126 ¤   Local Variables:
be7b17 ¤   tab-width: 4
3a0e6c ¤   End:
5b5f8c ¤   vi: ts=4 sw=4
a99e9b ¤   vim: si
e3d062 _____________________*/
--7cdf 0000bce693540110321 Page 1 of DecryptVerify.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
321cd2 ¤   $Id: DecryptVerify.c,v 1.9.2.5.2.1 1998/11/12 03:14:09 heller Exp $
a1f7f7 ____________________________________________________________________________*/
9caf5a
c89b16 // System Headers
f75655 #include <windows.h>
313d0b #include <windowsx.h>
52bb5f #include <assert.h>
4caf5a
215582 // PGPsdk Headers
d3e2ff #include "pgpConfig.h"
63a076 #include "pgpKeys.h"
e12f8d #include "pgpErrors.h"
44e60d #include "pgpWerr.h"
6e4919 #include "pgpUtilities.h"
840d08 #include "pgpMem.h"
d291b9 #include "pgpSDKPrefs.h"
0ab545 #include "pgpSC.h"
14af5a
d36578 // Shared Headers·
d55ab2 #include "PGPcl.h"
b6cf36 #include "SigEvent.h"
d2d092 #include "Working.h"
afcc89 #include "Prefs.h"
fe53a7 #include "DecryptVerify.h"
c70a79 #include "VerificationBlock.h"
ab1a14 #include "WorkingResource.h"
65ef45 #include "SharedStrings.h"
41af5a
cb3507 typedef struct _VerificationBlock VerificationBlock;
b6af5a
c2a641 struct _VerificationBlock
cfbb36 {
aac2a8 ¤   VerificationBlock *¤¤   next;
0d0228 ¤   VerificationBlock *¤¤   previous;
8ddaef ¤   char *¤ ¤   ¤   ¤   ¤   szBlockBegin;
f7dcd1 ¤   char *¤ ¤   ¤   ¤   ¤   szBlockEnd;
939948 ¤   void *¤ ¤   ¤   ¤   ¤   pOutput;
ec82e5 ¤   PGPSize¤¤   ¤   ¤   ¤   outSize;
fee9e2 ¤   PGPBoolean¤ ¤   ¤   ¤   bEncrypted;
2cc5b7 ¤   PGPBoolean¤ ¤   ¤   ¤   FYEO;
c282f7 };
88af5a
f7a6d5 typedef struct _DecodeEventData
77bb36 {
6df381 ¤   HINSTANCE¤  ¤   ¤   hInst;
23deec ¤   HWND¤   ¤   ¤   ¤   hwnd;
ffc57c ¤   HWND¤   ¤   ¤   ¤   hwndWorking;
05b4ac ¤   PGPtlsContextRef¤   tlsContext;
18f65e ¤   char *¤ ¤   ¤   ¤   szName;
398104 ¤   PGPKeySetRef¤   ¤   pubKeySet;
5c543d ¤   PGPKeySetRef¤   ¤   recipients;
1ef99a ¤   PGPUInt32¤  ¤   ¤   keyCount;
f9592f ¤   PGPKeyID¤   ¤   ¤   *keyIDArray;
d25be8 ¤   VerificationBlock *¤pVerBlock;
4e7325 } DecodeEventData;
2daf5a
0389d2 static PGPError DecryptVerify(HINSTANCE hInst, HWND hwnd,·
92330f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPContextRef context,·
743853 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPtlsContextRef tlsContext,·
acd92e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··char *szName, char *szModule,
565b89 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··PGPOptionListRef options, BOOL bMIME,
7e0299 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··VerificationBlock *pVerBlock);
1eaf5a
b072c1 PGPError DecodeEventHandler(PGPContextRef context,·
623f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPEvent *event,·
0ba3a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUserValue userValue);
--825b 000db321f9e40110321 Page 2 of DecryptVerify.c
e0af5a
80ed94 static void DisplayErrorCode(char *szFile,·
3e4098 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·int nLine,·
3bf417 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char *szModule,·
b111ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·int nCode);
56af5a
185485 static char * GetNextLine(char *szStart,
ea8ca3 ¤   ¤   ¤   ¤   ¤   ¤   ··char *szOutput,
539160 ¤   ¤   ¤   ¤   ¤   ¤   ··size_t nOutputSize);
19af5a
08af5a
1acb69 PGPError DecryptVerifyBuffer(HINSTANCE hInst, HWND hwnd,·
9a1466 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPContextRef context,·
1dcadc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPtlsContextRef tlsContext,·
d92ba1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char *szName, char *szModule,
96947c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·void *pInput, DWORD dwInSize,·
3703c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL bMIME, void **ppOutput, PGPSize *pOutSize,
8a7084 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL *FYEO)
6cbb36 {
c13333 ¤   PGPError¤   ¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
f113c6 ¤   PGPOptionListRef¤   options¤¤   = NULL;
3125ce ¤   VerificationBlock *¤pVerBlock¤  = NULL;
d9f82a ¤   VerificationBlock * pTempBlock¤ = NULL;
e7dc05 ¤   PGPMemoryMgrRef¤¤   memoryMgr¤  = NULL;
c52ee1 ¤   VerificationBlock * pVerIndex¤  = NULL;
f1f286 ¤   OUTBUFFLIST¤ ·····* obl¤¤   ¤   = NULL;
8b09d0 ¤   OUTBUFFLIST ······* nobl¤   ¤   = NULL;
1aaf5a
5ff0ef ¤   pgpAssert(pInput != NULL);
747bf0 ¤   pgpAssert(ppOutput != NULL);
f6051b ¤   pgpAssert(pOutSize != NULL);
6eb287 ¤   pgpAssert(szName != NULL);
1fc8e6 ¤   pgpAssert(szModule != NULL);
0df34e ¤   pgpAssert(PGPRefIsValid(context));
c17f9b ¤   pgpAssert(PGPRefIsValid(tlsContext));
d4af5a
2bcc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
8baf5a
ac3443 ¤   err = PGPBuildOptionList(context, &options,·
b0df5e ¤   ¤   ¤   PGPOInputBuffer(context, pInput, dwInSize),
9be5ff ¤   ¤   ¤   PGPOLastOption(context));
69af5a
7d82f0 ¤   if (IsPGPError(err))
65c7a1 ¤   {
f1142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
0f9b7a ¤   ¤   goto DecryptVerifyBufferError;
ae9371 ¤   }
80af5a
7744fa ¤   pVerBlock =·
a5b1a3 ¤   ¤   (VerificationBlock *) PGPNewData(memoryMgr,
a1b74a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(VerificationBlock),
79e023 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
a3af5a
39a2ef ¤   pVerBlock->next = NULL;
fca7bf ¤   pVerBlock->szBlockBegin = NULL;
dd16a6 ¤   pVerBlock->szBlockEnd = NULL;
621683 ¤   pVerBlock->pOutput = NULL;
664c00 ¤   pVerBlock->outSize = 0;
8baf5a
84a36f ¤   err = DecryptVerify(hInst, hwnd, context, tlsContext, szName, szModule,·
66946b ¤   ¤   ¤   options, bMIME, pVerBlock);
d3af5a
b35545 ¤   *ppOutput = NULL;
45165c ¤   *pOutSize = 0;
a4af5a
78c804 ¤   pVerIndex=pVerBlock;
27af5a
fe05ed ¤   // Convert pVerBlock to OUTBUFFLIST
18cfa1 ¤   do
c1c7a1 ¤   {
965c01 ¤   ¤   if (pVerIndex->szBlockBegin != NULL)
db5b34 ¤   ¤   {
--6ecc 000a4c0801140110321 Page 3 of DecryptVerify.c
cbfdd9 ¤   ¤   ¤   nobl=MakeOutBuffItem(&obl);
c1209a ¤   ¤   ¤   nobl->pBuff=pVerIndex->szBlockBegin;
984d3b ¤   ¤   ¤   nobl->dwBuffSize=strlen(pVerIndex->szBlockBegin);
0a0fe4 ¤   ¤   }
d3af5a
47ad99 ¤   ¤   if (pVerIndex->pOutput != NULL)
7e5b34 ¤   ¤   {
0dfdd9 ¤   ¤   ¤   nobl=MakeOutBuffItem(&obl);
986537 ¤   ¤   ¤   nobl->pBuff=pVerIndex->pOutput;
5d7571 ¤   ¤   ¤   nobl->dwBuffSize=strlen(pVerIndex->pOutput);
4211b7 ¤   ¤   ¤   nobl->FYEO=pVerIndex->FYEO;
a50fe4 ¤   ¤   }
ebaf5a
49b4af ¤   ¤   if (pVerIndex->szBlockEnd != NULL)
ea5b34 ¤   ¤   {
48fdd9 ¤   ¤   ¤   nobl=MakeOutBuffItem(&obl);
b24827 ¤   ¤   ¤   nobl->pBuff=pVerIndex->szBlockEnd;
745f7e ¤   ¤   ¤   nobl->dwBuffSize=strlen(pVerIndex->szBlockEnd);
3b0fe4 ¤   ¤   }
41af5a
352590 ¤   ¤   pTempBlock = pVerIndex;
a9488d ¤   ¤   pVerIndex=pVerIndex->next;
02fbad ¤   ¤   PGPFreeData(pTempBlock);
399371 ¤   }
2ee4b9 ¤   while (pVerIndex != NULL);
abaf5a
a10ab6 ¤   // Concatinate them to ppOutput
523105 ¤   ConcatOutBuffList((void *)context,
6bb2db ¤   ¤   obl,
fb6061 ¤   ¤   (char **)ppOutput,
b4341b ¤   ¤   pOutSize,
a77996 ¤   ¤   FYEO);
2d38e5 /*
94cfa1 ¤   do
0fc7a1 ¤   {
d1bad4 ¤   ¤   if (pVerBlock->szBlockBegin != NULL)
125b34 ¤   ¤   {
540321 ¤   ¤   ¤   PGPReallocData(memoryMgr, ppOutput, *pOutSize +·
36997b ¤   ¤   ¤   ¤   strlen(pVerBlock->szBlockBegin) +·
c0cb62 ¤   ¤   ¤   ¤   strlen((char *) pVerBlock->pOutput) +·
d49f74 ¤   ¤   ¤   ¤   strlen(pVerBlock->szBlockEnd) + 1,
79174c ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_None);
f9af5a
827402 ¤   ¤   ¤   ((char *) *ppOutput)[*pOutSize] = 0;
095c4a ¤   ¤   ¤   strcat((char *) *ppOutput, pVerBlock->szBlockBegin);
17d699 ¤   ¤   ¤   strcat((char *) *ppOutput, (char *) pVerBlock->pOutput);
44a971 ¤   ¤   ¤   strcat((char *) *ppOutput, pVerBlock->szBlockEnd);
439431 ¤   ¤   ¤   *pOutSize = strlen((char *) *ppOutput) + 1;
e7af5a
065188 ¤   ¤   ¤   PGPFreeData(pVerBlock->szBlockBegin);
4f163f ¤   ¤   ¤   PGPFreeData(pVerBlock->pOutput);
a4062e ¤   ¤   ¤   PGPFreeData(pVerBlock->szBlockEnd);
760fe4 ¤   ¤   }
f60ecf ¤   ¤   else if (pVerBlock->pOutput != NULL)
965b34 ¤   ¤   {
cb0321 ¤   ¤   ¤   PGPReallocData(memoryMgr, ppOutput, *pOutSize +·
991d15 ¤   ¤   ¤   ¤   strlen((char *) pVerBlock->pOutput) + 1,
ab174c ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_None);
30af5a
8b7402 ¤   ¤   ¤   ((char *) *ppOutput)[*pOutSize] = 0;
d7d699 ¤   ¤   ¤   strcat((char *) *ppOutput, (char *) pVerBlock->pOutput);
359431 ¤   ¤   ¤   *pOutSize = strlen((char *) *ppOutput) + 1;
61af5a
f8163f ¤   ¤   ¤   PGPFreeData(pVerBlock->pOutput);
af0fe4 ¤   ¤   }
9d1b52 ¤   ¤
473dc3 ¤   ¤   pTempBlock = pVerBlock;
f825aa ¤   ¤   pVerBlock = pTempBlock->next;
36fbad ¤   ¤   PGPFreeData(pTempBlock);
8e9371 ¤   }
a85d8d ¤   while (pVerBlock != NULL);
a47fe0 */
--d94e 0001db0d63f40110321 Page 4 of DecryptVerify.c
534053 DecryptVerifyBufferError:
adaf5a
bcabae ¤   if (options != NULL)
757ce2 ¤   ¤   PGPFreeOptionList(options);
b5af5a
f65ea8 ¤   return err;
76efe6 }
bfaf5a
d8af5a
8fd504 PGPError DecryptVerifyFile(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
0262eb ¤   ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,·
338396 ¤   ¤   ¤   ¤   ¤   ¤   ···char *szName, char *szModule,
c1eec8 ¤   ¤   ¤   ¤   ¤   ¤   ···char *szInFile, BOOL bMIME, BOOL bBinary,
aa7fd7 ¤   ¤   ¤   ¤   ¤   ¤   ···char **pszOutFile, void **ppOutput,·
02ba29 ¤   ¤   ¤   ¤   ¤   ¤   ···PGPSize *pOutSize, BOOL *FYEO)
29bb36 {
543333 ¤   PGPError¤   ¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
d413c6 ¤   PGPOptionListRef¤   options¤¤   = NULL;
ef7988 ¤   PGPFileSpecRef¤ ¤   inputFile¤  = NULL;
7c356a ¤   PGPFileSpecRef¤ ¤   outputFile¤ = NULL;
6aed33 ¤   PGPFileSpecRef¤ ¤   finalFile¤  = NULL;
3fe728 ¤   PGPFileSpecRef¤ ¤   dataFile¤   = NULL;
cca9b3 ¤   PGPUInt32¤  ¤   ¤   macCreator¤ = 0;
2191f9 ¤   PGPUInt32¤  ¤   ¤   macType¤¤   = 0;
8025ce ¤   VerificationBlock *¤pVerBlock¤  = NULL;
43f82a ¤   VerificationBlock * pTempBlock¤ = NULL;
a01bbe ¤   char *¤ ¤   ¤   ¤   szExtension = NULL;
ca85a3 ¤   char *¤ ¤   ¤   ¤   szOutFile¤  = NULL;
dff286 ¤   OUTBUFFLIST¤ ·····* obl¤¤   ¤   = NULL;
2509d0 ¤   OUTBUFFLIST ······* nobl¤   ¤   = NULL;
55af5a
58114a ¤   pgpAssert(szInFile != NULL);
1d3088 ¤   pgpAssert(pszOutFile != NULL);
8eb287 ¤   pgpAssert(szName != NULL);
02c8e6 ¤   pgpAssert(szModule != NULL);
3ff34e ¤   pgpAssert(PGPRefIsValid(context));
3b7f9b ¤   pgpAssert(PGPRefIsValid(tlsContext));
acaf5a
c13112 ¤   if (ppOutput != NULL)
a592f0 ¤   ¤   *ppOutput = NULL;
c4af5a
e535bf ¤   if (pOutSize != NULL)
842db5 ¤   ¤   *pOutSize = 0;
5eaf5a
61df37 ¤   err = PGPNewFileSpecFromFullPath(context, szInFile, &inputFile);
0d82f0 ¤   if (IsPGPError(err))
14c7a1 ¤   {
ea142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
efaaee ¤   ¤   goto DecryptVerifyFileError;
b49371 ¤   }
c1af5a
8d7ee4 ¤   szOutFile = (char *) calloc(sizeof(char), strlen(szInFile)+5);
1fb262 ¤   if (szOutFile == NULL)
64c7a1 ¤   {
52bce1 ¤   ¤   err = kPGPError_OutOfMemory;
89142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
40aaee ¤   ¤   goto DecryptVerifyFileError;
d39371 ¤   }
ceaf5a
b42aee ¤   strcpy(szOutFile, szInFile);
1d1d94 ·¤  szExtension = strrchr(szOutFile, '.');
1a7e7f ¤   if (szExtension != NULL)
c7c7a1 ¤   {
d12275 ¤   ¤   if (!strcmp(szExtension, ".asc") || !strcmp(szExtension, ".pgp"))
e3b151 ¤   ¤   ¤   *szExtension = '\0';
610e1d ¤   ¤   else
46200a ¤   ¤   ¤   strcat(szOutFile, ".tmp");
2b9371 ¤   }
2b0e24 ¤   else
1661f9 ¤   ¤   strcat(szOutFile, ".tmp");
a6af5a
1d264c ¤   if (bBinary)
--2b66 000973403c640110321 Page 5 of DecryptVerify.c
f7c7a1 ¤   {
085a6a ¤   ¤   err = PGPNewFileSpecFromFullPath(context, szOutFile, &outputFile);
99b6ad ¤   ¤   if (IsPGPError(err))
fd5b34 ¤   ¤   {
2ece02 ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
b2af03 ¤   ¤   ¤   goto DecryptVerifyFileError;
150fe4 ¤   ¤   }
591b52 ¤   ¤
be6758 ¤   ¤   err = PGPBuildOptionList(context, &options,·
7879c6 ¤   ¤   ¤   ¤   PGPOInputFile(context, inputFile),
8ae2b3 ¤   ¤   ¤   ¤   PGPOOutputFile(context, outputFile),
ebd911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
749371 ¤   }
5c0e24 ¤   else
c2c7a1 ¤   {
410571 ¤   ¤   pVerBlock =·
a4eedc ¤   ¤   ¤   (VerificationBlock *) PGPNewData(PGPGetContextMemoryMgr(context),
b2b74a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(VerificationBlock),
86e023 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
42af5a
6a0fb1 ¤   ¤   pVerBlock->next = NULL;
2262ea ¤   ¤   pVerBlock->szBlockBegin = NULL;
c4f9d5 ¤   ¤   pVerBlock->szBlockEnd = NULL;
7d9afc ¤   ¤   pVerBlock->pOutput = NULL;
c1e15e ¤   ¤   pVerBlock->outSize = 0;
7baf5a
e86758 ¤   ¤   err = PGPBuildOptionList(context, &options,·
4c79c6 ¤   ¤   ¤   ¤   PGPOInputFile(context, inputFile),
8ad911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
0d9371 ¤   }
a1af5a
db1b52 ¤   ¤
1982f0 ¤   if (IsPGPError(err))
d6c7a1 ¤   {
6b142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
69aaee ¤   ¤   goto DecryptVerifyFileError;
579371 ¤   }
38af5a
b6a36f ¤   err = DecryptVerify(hInst, hwnd, context, tlsContext, szName, szModule,·
17946b ¤   ¤   ¤   options, bMIME, pVerBlock);
beaf5a
1efd13 ¤   if (!bBinary)
fbc7a1 ¤   {
b9496e ¤   ¤   HANDLE hFile;
61e4e2 ¤   ¤   DWORD dwWritten;
643edc ¤   ¤   BOOL bFixed = FALSE;
b1af5a
94d2f7 ¤   ¤   hFile = CreateFile(szOutFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
13d30c ¤   ¤   ¤   ¤   ¤   FILE_ATTRIBUTE_NORMAL, NULL);
1daf5a
c8553f ¤   ¤   if (pVerBlock->FYEO)
c25b34 ¤   ¤   {
1a95db ¤   ¤   ¤   // Convert pVerBlock to OUTBUFFLIST
4d6da3 ¤   ¤   ¤   do
5bf776 ¤   ¤   ¤   {
13bb52 ¤   ¤   ¤   ¤   if (pVerBlock->szBlockBegin != NULL)
d672c3 ¤   ¤   ¤   ¤   {
316def ¤   ¤   ¤   ¤   ¤   nobl=MakeOutBuffItem(&obl);
3e7d8c ¤   ¤   ¤   ¤   ¤   nobl->pBuff=pVerBlock->szBlockBegin;
063c9d ¤   ¤   ¤   ¤   ¤   nobl->dwBuffSize=strlen(pVerBlock->szBlockBegin);
062613 ¤   ¤   ¤   ¤   }
e32b85 ¤   ¤   ¤   ¤
3ed797 ¤   ¤   ¤   ¤   if (pVerBlock->pOutput != NULL)
1872c3 ¤   ¤   ¤   ¤   {
086def ¤   ¤   ¤   ¤   ¤   nobl=MakeOutBuffItem(&obl);
875212 ¤   ¤   ¤   ¤   ¤   nobl->pBuff=pVerBlock->pOutput;
2bfef3 ¤   ¤   ¤   ¤   ¤   nobl->dwBuffSize=strlen(pVerBlock->pOutput);
0f23fd ¤   ¤   ¤   ¤   ¤   nobl->FYEO=pVerBlock->FYEO;
d92613 ¤   ¤   ¤   ¤   }
8e2b85 ¤   ¤   ¤   ¤
b0a900 ¤   ¤   ¤   ¤   if (pVerBlock->szBlockEnd != NULL)
9772c3 ¤   ¤   ¤   ¤   {
--4eca 000bf91d4ce40110321 Page 6 of DecryptVerify.c
c86def ¤   ¤   ¤   ¤   ¤   nobl=MakeOutBuffItem(&obl);
8a890b ¤   ¤   ¤   ¤   ¤   nobl->pBuff=pVerBlock->szBlockEnd;
bb8e4e ¤   ¤   ¤   ¤   ¤   nobl->dwBuffSize=strlen(pVerBlock->szBlockEnd);
1b2613 ¤   ¤   ¤   ¤   }
142b85 ¤   ¤   ¤   ¤
4c736a ¤   ¤   ¤   ¤   pTempBlock = pVerBlock;
e3fb73 ¤   ¤   ¤   ¤   pVerBlock=pVerBlock->next;
3cc328 ¤   ¤   ¤   ¤   PGPFreeData(pTempBlock);
77a3a6 ¤   ¤   ¤   }
029001 ¤   ¤   ¤   while (pVerBlock != NULL);
ce87c7 ¤   ¤   ¤
974785 ¤   ¤   ¤   // Concatinate them to ppOutput
eaaed1 ¤   ¤   ¤   ConcatOutBuffList((void *)context,
bc46c1 ¤   ¤   ¤   ¤   obl,
b2f836 ¤   ¤   ¤   ¤   (char **)ppOutput,
b2c934 ¤   ¤   ¤   ¤   pOutSize,
f2a0dc ¤   ¤   ¤   ¤   FYEO);
570fe4 ¤   ¤   }
679cec ¤   ¤   else do
3d5b34 ¤   ¤   {
9894bb ¤   ¤   ¤   // Fix for Eudora 4.0.1 bug where "boundary=..." is on
5b969b ¤   ¤   ¤   // a separate line
b0af5a
5d8df0 ¤   ¤   ¤   if ((pVerBlock->pOutput != NULL) && !bFixed && bMIME)
94f776 ¤   ¤   ¤   {
7780b4 ¤   ¤   ¤   ¤   char szLine[256];
0c0a4d ¤   ¤   ¤   ¤   char szLastLine[256];
ff76b1 ¤   ¤   ¤   ¤   char *szLinePtr;
2ce349 ¤   ¤   ¤   ¤   char *szLastLinePtr;
ae2b85 ¤   ¤   ¤   ¤
b1d55b ¤   ¤   ¤   ¤   szLine[0] = 0;
4afca1 ¤   ¤   ¤   ¤   szLastLine[0] = 0;
5f2b85 ¤   ¤   ¤   ¤
88178d ¤   ¤   ¤   ¤   szLinePtr = (char *) pVerBlock->pOutput;
fe7239 ¤   ¤   ¤   ¤   while (szLinePtr != NULL)
0872c3 ¤   ¤   ¤   ¤   {
304f6e ¤   ¤   ¤   ¤   ¤   strcpy(szLastLine, szLine);
0ffe66 ¤   ¤   ¤   ¤   ¤   szLastLinePtr = szLinePtr;
7f84d4 ¤   ¤   ¤   ¤   ¤   szLinePtr = GetNextLine(szLinePtr, szLine,·
3896d3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szLine));
c4ef13 ¤   ¤   ¤   ¤   ¤   if ((strstr(szLine, "boundary=") != NULL) &&
a13ce9 ¤   ¤   ¤   ¤   ¤   ¤   (strstr(szLastLine, "Content-Type: multipart/mixed;")
8bbf9d ¤   ¤   ¤   ¤   ¤   ¤   != NULL))
e44859 ¤   ¤   ¤   ¤   ¤   {
beefd3 ¤   ¤   ¤   ¤   ¤   ¤   szLastLinePtr -= 2;
272323 ¤   ¤   ¤   ¤   ¤   ¤   szLastLinePtr[0] = ' ';
860f04 ¤   ¤   ¤   ¤   ¤   ¤   szLastLinePtr[1] = ' ';
541c89 ¤   ¤   ¤   ¤   ¤   }
e02613 ¤   ¤   ¤   ¤   }
ba2b85 ¤   ¤   ¤   ¤
5c5965 ¤   ¤   ¤   ¤   bFixed = TRUE;
d3a3a6 ¤   ¤   ¤   }
bdaf5a
1ce849 ¤   ¤   ¤   if (pVerBlock->szBlockBegin != NULL)
19f776 ¤   ¤   ¤   {
08f63e ¤   ¤   ¤   ¤   if (!bMIME)
f272c3 ¤   ¤   ¤   ¤   {
bf01c5 ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, pVerBlock->szBlockBegin,·
5eab4f ¤   ¤   ¤   ¤   ¤   ¤   strlen(pVerBlock->szBlockBegin), &dwWritten,·
c6cda4 ¤   ¤   ¤   ¤   ¤   ¤   NULL);
8694aa ¤   ¤   ¤   ¤   ¤   ¤
797e76 ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, pVerBlock->pOutput,·
5942f9 ¤   ¤   ¤   ¤   ¤   ¤   strlen((char *) pVerBlock->pOutput), &dwWritten,·
d7cda4 ¤   ¤   ¤   ¤   ¤   ¤   NULL);
18ae30 ¤   ¤   ¤   ¤   ¤
8ec2e0 ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, pVerBlock->szBlockEnd,·
ed3f1b ¤   ¤   ¤   ¤   ¤   ¤   strlen(pVerBlock->szBlockEnd), &dwWritten, NULL);
eaae30 ¤   ¤   ¤   ¤   ¤
0efcfe ¤   ¤   ¤   ¤   ¤   PGPFreeData(pVerBlock->szBlockBegin);
1917b9 ¤   ¤   ¤   ¤   ¤   PGPFreeData(pVerBlock->pOutput);
5ec5c3 ¤   ¤   ¤   ¤   ¤   PGPFreeData(pVerBlock->szBlockEnd);
bf2613 ¤   ¤   ¤   ¤   }
--5c80 0006b1a56e440110321 Page 7 of DecryptVerify.c
67fa07 ¤   ¤   ¤   ¤   else
d172c3 ¤   ¤   ¤   ¤   {
bf6fc7 ¤   ¤   ¤   ¤   ¤   char szLine[256];
5436a3 ¤   ¤   ¤   ¤   ¤   char szLastLine[256];
97d6fb ¤   ¤   ¤   ¤   ¤   char szBoundary[256];
82fb72 ¤   ¤   ¤   ¤   ¤   char szContentType[256];
014bd9 ¤   ¤   ¤   ¤   ¤   char *szLinePtr;
aae499 ¤   ¤   ¤   ¤   ¤   char *szFinalBoundary = NULL;
1975a6 ¤   ¤   ¤   ¤   ¤   char *szFirstText = NULL;
809cf9 ¤   ¤   ¤   ¤   ¤   DWORD dwBegin;
0843d2 ¤   ¤   ¤   ¤   ¤   DWORD dwEnd;
5eae30 ¤   ¤   ¤   ¤   ¤
dc5924 ¤   ¤   ¤   ¤   ¤   szLine[0] = 0;
aebd52 ¤   ¤   ¤   ¤   ¤   szLastLine[0] = 0;
6b476b ¤   ¤   ¤   ¤   ¤   szBoundary[0] = 0;
aeae30 ¤   ¤   ¤   ¤   ¤
363138 ¤   ¤   ¤   ¤   ¤   szLinePtr = (char *) pVerBlock->pOutput;
1f46c9 ¤   ¤   ¤   ¤   ¤   while ((szLinePtr != NULL) && (szBoundary[0] == 0))
ea4859 ¤   ¤   ¤   ¤   ¤   {
7ed92f ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szLastLine, szLine);
f0b9ba ¤   ¤   ¤   ¤   ¤   ¤   szLinePtr = GetNextLine(szLinePtr, szLine,·
6ef9e0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szLine));
6e1cdb ¤   ¤   ¤   ¤   ¤   ¤   if (strstr(szLine, "Content-Type: text")·
2d6d0c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   != NULL)
208fec ¤   ¤   ¤   ¤   ¤   ¤   {
d2d49d ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szBoundary, szLastLine);
eaed52 ¤   ¤   ¤   ¤   ¤   ¤   ¤   strcpy(szContentType, szLine);
f477d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   if (szFirstText == NULL)
cf536c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFirstText = GetNextLine(szLinePtr, NULL, 0);
5edb3c ¤   ¤   ¤   ¤   ¤   ¤   }
b91c89 ¤   ¤   ¤   ¤   ¤   }
9bae30 ¤   ¤   ¤   ¤   ¤
554bfc ¤   ¤   ¤   ¤   ¤   while (szLinePtr != NULL)
614859 ¤   ¤   ¤   ¤   ¤   {
87c3ce ¤   ¤   ¤   ¤   ¤   ¤   GetNextLine(szLinePtr, szLine, sizeof(szLine));
9d9a6c ¤   ¤   ¤   ¤   ¤   ¤   if (strstr(szLine, szBoundary))
2dbe28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szFinalBoundary = szLinePtr;
3b430a ¤   ¤   ¤   ¤   ¤   ¤   szLinePtr = GetNextLine(szLinePtr, NULL, 0);
3e1c89 ¤   ¤   ¤   ¤   ¤   }
48ae30 ¤   ¤   ¤   ¤   ¤
870589 ¤   ¤   ¤   ¤   ¤   dwBegin = szFirstText - ((char *) pVerBlock->pOutput);
de69ce ¤   ¤   ¤   ¤   ¤   if (szFinalBoundary != NULL)
e7b7b7 ¤   ¤   ¤   ¤   ¤   ¤   dwEnd = szFinalBoundary -·
c17d66 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ((char *) pVerBlock->pOutput);
424bd6 ¤   ¤   ¤   ¤   ¤   else
47d01e ¤   ¤   ¤   ¤   ¤   ¤   dwEnd = strlen((char *) pVerBlock->pOutput);
15ae30 ¤   ¤   ¤   ¤   ¤
320b20 ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, pVerBlock->pOutput, dwBegin, &dwWritten,·
7bcda4 ¤   ¤   ¤   ¤   ¤   ¤   NULL);
e4af5a
c71878 ¤   ¤   ¤   ¤   ¤   if (strstr(szContentType, "text/html"))
f34859 ¤   ¤   ¤   ¤   ¤   {
320d49 ¤   ¤   ¤   ¤   ¤   ¤   char szTemp[] = "<html><pre>\r\n";
d3af5a
b66509 ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, szTemp, strlen(szTemp),·
fc7bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwWritten, NULL);
881c89 ¤   ¤   ¤   ¤   ¤   }
e4af5a
d101c5 ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, pVerBlock->szBlockBegin,·
be3796 ¤   ¤   ¤   ¤   ¤   ¤   strlen(pVerBlock->szBlockBegin), &dwWritten, NULL);
83af5a
f11878 ¤   ¤   ¤   ¤   ¤   if (strstr(szContentType, "text/html"))
594859 ¤   ¤   ¤   ¤   ¤   {
b8719b ¤   ¤   ¤   ¤   ¤   ¤   char szTemp[] = "</html>\r\n";
6daf5a
3c6509 ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, szTemp, strlen(szTemp),·
aa7bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwWritten, NULL);
141c89 ¤   ¤   ¤   ¤   ¤   }
2faf5a
c395d0 ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, ((char *) pVerBlock->pOutput) + dwBegin,
34f2e2 ¤   ¤   ¤   ¤   ¤   ¤   dwEnd - dwBegin, &dwWritten, NULL);
6bae30 ¤   ¤   ¤   ¤   ¤
--de28 0002df987bc40110321 Page 8 of DecryptVerify.c
a569ce ¤   ¤   ¤   ¤   ¤   if (szFinalBoundary != NULL)
ea4859 ¤   ¤   ¤   ¤   ¤   {
2116fd ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, szBoundary, strlen(szBoundary),
9d7bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwWritten, NULL);
573402 ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, "\r\n", 2, &dwWritten, NULL);
b1d23c ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, szContentType, strlen(szContentType),
d17bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwWritten, NULL);
f83402 ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, "\r\n", 2, &dwWritten, NULL);
8a1c89 ¤   ¤   ¤   ¤   ¤   }
afaf5a
ea1878 ¤   ¤   ¤   ¤   ¤   if (strstr(szContentType, "text/html"))
1e4859 ¤   ¤   ¤   ¤   ¤   {
260d49 ¤   ¤   ¤   ¤   ¤   ¤   char szTemp[] = "<html><pre>\r\n";
94af5a
b86509 ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, szTemp, strlen(szTemp),·
3c7bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwWritten, NULL);
c41c89 ¤   ¤   ¤   ¤   ¤   }
10af5a
fac2e0 ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, pVerBlock->szBlockEnd,·
8a3f1b ¤   ¤   ¤   ¤   ¤   ¤   strlen(pVerBlock->szBlockEnd), &dwWritten, NULL);
91af5a
1b1878 ¤   ¤   ¤   ¤   ¤   if (strstr(szContentType, "text/html"))
344859 ¤   ¤   ¤   ¤   ¤   {
12719b ¤   ¤   ¤   ¤   ¤   ¤   char szTemp[] = "</html>\r\n";
88af5a
206509 ¤   ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, szTemp, strlen(szTemp),·
427bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   &dwWritten, NULL);
a31c89 ¤   ¤   ¤   ¤   ¤   }
18af5a
3c141e ¤   ¤   ¤   ¤   ¤   WriteFile(hFile, ((char *) pVerBlock->pOutput) + dwEnd,
df5c88 ¤   ¤   ¤   ¤   ¤   ¤   strlen((char *) pVerBlock->pOutput) - dwEnd,·
2bea4f ¤   ¤   ¤   ¤   ¤   ¤   &dwWritten, NULL);
b6ae30 ¤   ¤   ¤   ¤   ¤
61fcfe ¤   ¤   ¤   ¤   ¤   PGPFreeData(pVerBlock->szBlockBegin);
bc17b9 ¤   ¤   ¤   ¤   ¤   PGPFreeData(pVerBlock->pOutput);
49c5c3 ¤   ¤   ¤   ¤   ¤   PGPFreeData(pVerBlock->szBlockEnd);
9d2613 ¤   ¤   ¤   ¤   }
08a3a6 ¤   ¤   ¤   }
bb5c52 ¤   ¤   ¤   else if (pVerBlock->pOutput != NULL)
e3f776 ¤   ¤   ¤   {
567d01 ¤   ¤   ¤   ¤   WriteFile(hFile, pVerBlock->pOutput,·
ca544f ¤   ¤   ¤   ¤   ¤   strlen((char *) pVerBlock->pOutput), &dwWritten,·
49d98c ¤   ¤   ¤   ¤   ¤   NULL);
612b85 ¤   ¤   ¤   ¤
f744a2 ¤   ¤   ¤   ¤   PGPFreeData(pVerBlock->pOutput);
faa3a6 ¤   ¤   ¤   }
a72b85 ¤   ¤   ¤   ¤
eeb63f ¤   ¤   ¤   pTempBlock = pVerBlock;
eb1944 ¤   ¤   ¤   pVerBlock = pTempBlock->next;
9fc6c5 ¤   ¤   ¤   PGPFreeData(pTempBlock);
380fe4 ¤   ¤   }
f0d1f2 ¤   ¤   while (pVerBlock != NULL);
1987c7 ¤   ¤   ¤
3e5eb2 ¤   ¤   CloseHandle(hFile);
3caf5a
a97e7b ¤   ¤   *pszOutFile = (char *) PGPNewData(PGPGetContextMemoryMgr(context),
d2142d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen(szOutFile)+1,
f7e023 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
fe84ce ¤   ¤   strcpy(*pszOutFile, szOutFile);
809371 ¤   }
220e24 ¤   else
63c7a1 ¤   {
e6c609 ¤   ¤   PGPMacBinaryToLocal(outputFile, &finalFile, &macCreator, &macType);
ea27b1 ¤   ¤   if (finalFile != NULL)
d939e5 ¤   ¤   ¤   PGPGetFullPathFromFileSpec(finalFile, pszOutFile);
a50e1d ¤   ¤   else
825b34 ¤   ¤   {
e7935c ¤   ¤   ¤   *pszOutFile = (char *) PGPNewData(PGPGetContextMemoryMgr(context),
1d3298 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   strlen(szOutFile)+1,
a66ddf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
710ca8 ¤   ¤   ¤   strcpy(*pszOutFile, szOutFile);
2d0fe4 ¤   ¤   }
--5e92 000d1c62f4940110321 Page 9 of DecryptVerify.c
a19371 ¤   }
93af5a
9de25d DecryptVerifyFileError:
28af5a
353399 ¤   if (finalFile != NULL)
ea6134 ¤   ¤   PGPFreeFileSpec(finalFile);
f9af5a
d60109 ¤   if (inputFile != NULL)
27acba ¤   ¤   PGPFreeFileSpec(inputFile);
06af5a
864fdb ¤   if (outputFile != NULL)
b378a7 ¤   ¤   PGPFreeFileSpec(outputFile);
11af5a
57abae ¤   if (options != NULL)
497ce2 ¤   ¤   PGPFreeOptionList(options);
d8af5a
125ea8 ¤   return err;
eeefe6 }
74af5a
39af5a
d22801 PGPError DecryptVerify(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
c60dd8 ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,·
08eca5 ¤   ¤   ¤   ¤   ¤   ···char *szName, char *szModule,
7411ee ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef options, BOOL bMIME,
939ca9 ¤   ¤   ¤   ¤   ¤   ···VerificationBlock *pVerBlock)
70bb36 {
803333 ¤   PGPError¤   ¤   ¤   err¤¤   ¤   = kPGPError_NoErr;
f363d4 ¤   PGPKeySetRef¤   ¤   pubKeySet¤  = NULL;
626ea7 ¤   PGPKeySetRef¤   ¤   newKeySet¤  = NULL;
1ce1c6 ¤   PGPOptionListRef¤   tempOptions¤= NULL;
40f7c7 ¤   PGPUInt32¤  ¤   ¤   nNumKeys¤   = 0;
15bb0f ¤   HWND¤   ¤   ¤   ¤   hwndWorking¤= NULL;
b39adf ¤   char¤   ¤   ¤   ¤   szWorkingTitle[256];
084054 ¤   DecodeEventData¤¤   decodeData;
4faf5a
4f66e6 ¤   UpdateWindow(hwnd);
f1af5a
9761eb ¤   decodeData.hInst¤   ¤   = hInst;
2673b6 ¤   decodeData.hwnd¤¤   ¤   = hwnd;
2d535a ¤   decodeData.tlsContext¤  = tlsContext;
9fd370 ¤   decodeData.szName¤  ¤   = szName;
bf47dc ¤   decodeData.recipients¤  = NULL;
5705f1 ¤   decodeData.keyCount¤¤   = 0;
343bd1 ¤   decodeData.keyIDArray¤  = NULL;
9aaf19 ¤   decodeData.pVerBlock¤   = pVerBlock;
5caf5a
30e947 ¤   err = PGPsdkLoadDefaultPrefs(context);
fd82f0 ¤   if (IsPGPError(err))
c0c7a1 ¤   {
5a142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
4ba6e5 ¤   ¤   goto DecryptVerifyError;
6b9371 ¤   }
11af5a
e7efcf ¤   err = PGPOpenDefaultKeyRings(context, (PGPKeyRingOpenFlags)0, &pubKeySet);
5c82f0 ¤   if (IsPGPError(err))
c0c7a1 ¤   {
d1142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
5ca6e5 ¤   ¤   goto DecryptVerifyError;
d09371 ¤   }
06af5a
945af3 ¤   decodeData.pubKeySet = pubKeySet;
48af5a
2e2cd8 ¤   PGPNewKeySet(context, &newKeySet);
f9af5a
fa5d32 ¤   LoadString(hInst, IDS_WORKINGDECRYPT, szWorkingTitle,·
89cd76 ¤   ¤   sizeof(szWorkingTitle));
15af5a
a59ea4 ¤   hwndWorking = WorkingDlgProcThread(GetModuleHandle(szModule), hInst, NULL,
12583f ¤   ¤   ¤   ¤   ¤   szWorkingTitle, "");
2fd28d ¤   decodeData.hwndWorking = hwndWorking;
75af5a
d1ab85 ¤   err = PGPDecode(context,
--dea6 00059a073a340110321 Page 10 of DecryptVerify.c
36914c ¤   ¤   ¤   options,
e8d2da ¤   ¤   ¤   PGPOPassThroughIfUnrecognized(context, (PGPBoolean) !bMIME),
3deac3 ¤   ¤   ¤   PGPOPassThroughKeys(context, TRUE),
e850be ¤   ¤   ¤   PGPOEventHandler(context, DecodeEventHandler, &decodeData),
273d0d ¤   ¤   ¤   PGPOSendNullEvents(context, 100),
d044fa ¤   ¤   ¤   PGPOImportKeysTo(context, newKeySet),
a18010 ¤   ¤   ¤   PGPOKeySetRef(context, pubKeySet),
9be5ff ¤   ¤   ¤   PGPOLastOption(context));
d6af5a
791747 ¤   DestroyWindow(hwndWorking);
80af5a
eb67ba ¤   if (IsPGPError(err) && (err != kPGPError_UserAbort))
e2c7a1 ¤   {
d2142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
8da6e5 ¤   ¤   goto DecryptVerifyError;
8e9371 ¤   }
b9af5a
c6d3af ¤   PGPCountKeys(newKeySet, &nNumKeys);
89ea9b ¤   if (nNumKeys > 0)
5d7af7 ¤   ¤   PGPclQueryAddKeys(context, tlsContext, hwnd, newKeySet, NULL);
b7af5a
2fe3cd DecryptVerifyError:
58af5a
99ebaa ¤   if (decodeData.recipients != NULL)
351b94 ¤   ¤   PGPFreeKeySet(decodeData.recipients);
ffaf5a
651925 ¤   if (decodeData.keyIDArray != NULL)
09384b ¤   ¤   free(decodeData.keyIDArray);
cbaf5a
c48dec ¤   if (newKeySet != NULL)
e0510e ¤   ¤   PGPFreeKeySet(newKeySet);
5aaf5a
bb9631 ¤   if (pubKeySet != NULL)
fc765b ¤   ¤   PGPFreeKeySet(pubKeySet);
c6af5a
dd5ea8 ¤   return err;
02efe6 }
07af5a
6caf5a
c172c1 PGPError DecodeEventHandler(PGPContextRef context,·
bf3f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPEvent *event,·
23bcc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUserValue userValue)
55bb36 {
313ec9 ¤   HWND¤   ¤   ¤   hwnd¤   ¤   ¤   = NULL;
8fe13b ¤   char *¤ ¤   ¤   szPassPhrase¤   = NULL;
19fa04 ¤   PGPByte *¤  ¤   pPasskey¤   ¤   = NULL;
6405a7 ¤   PGPUInt32¤  ¤   nPasskeyLength¤ = 0;
16b4f1 ¤   static BOOL¤¤   bAlreadyAsked¤  = FALSE;
58bd79 ¤   char *¤ ¤   ¤   szName¤ ¤   ¤   = NULL;
6f86d4 ¤   PGPMemoryMgrRef¤memoryMgr¤  ¤   = NULL;
1dc238 ¤   PGPKeySetRef¤   pubKeySet¤  ¤   = NULL;
0c7c62 ¤   PGPKeySetRef¤   addedKeys¤  ¤   = NULL;
c9cb58 ¤   PGPKeySetRef¤   recipients¤ ¤   = NULL;
4747bb ¤   PGPUInt32¤  ¤   keyCount¤   ¤   = 0;
571f40 ¤   PGPKeyID¤   ¤   *keyIDArray¤¤   = NULL;
2728eb ¤   DecodeEventData¤*userData¤  ¤   = NULL;
a87bbb ¤   HWND¤   ¤   ¤   hwndWorking¤¤   = NULL;
751e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
afaf5a
6af34e ¤   pgpAssert(PGPRefIsValid(context));
3c1043 ¤   pgpAssert(event != NULL);
47af5a
199198 ¤   userData = (DecodeEventData *) userValue;
abaf5a
38eebe ¤   hwnd¤   ¤   ¤   = userData->hwnd;
076d11 ¤   hwndWorking¤¤   = userData->hwndWorking;
be584c ¤   szName¤ ¤   ¤   = userData->szName;
128268 ¤   pubKeySet¤  ¤   = userData->pubKeySet;
f0390f ¤   recipients¤ ¤   = userData->recipients;
c42002 ¤   keyCount¤   ¤   = userData->keyCount;
1313ea ¤   keyIDArray¤ ¤   = userData->keyIDArray;
59af5a
--916c 000d881af7840110321 Page 11 of DecryptVerify.c
25cc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
0caf5a
6b753a ¤   switch (event->type)
f7c7a1 ¤   {
337813 ¤   case kPGPEvent_NullEvent:
23ed49 ¤   ¤   {¤
332098 ¤   ¤   ¤   PGPEventNullData *d = &event->data.nullData;
ac3ab0 ¤   ¤   ¤   BOOL bCancel;
abaf5a
79dc20 ¤   ¤   ¤   bCancel = WorkingCallback (¤hwndWorking,·
8bd676 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (unsigned long)d->bytesWritten,·
9cceb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (unsigned long)d->bytesTotal) ;
87af5a
f64bab ¤   ¤   ¤   if(bCancel)
d5f776 ¤   ¤   ¤   {
02398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
22a3a6 ¤   ¤   ¤   }
000fe4 ¤   ¤   }
802f68 ¤   ¤   break;
52af5a
fb846e ¤   case kPGPEvent_BeginLexEvent:
d05acf ¤   ¤   if (userData->pVerBlock != NULL)
715b34 ¤   ¤   {
00e66c ¤   ¤   ¤   userData->pVerBlock->bEncrypted = FALSE;
930fe4 ¤   ¤   }
7f2f68 ¤   ¤   break;
9baf5a
08ec8f ¤   case kPGPEvent_OutputEvent:
ed5acf ¤   ¤   if (userData->pVerBlock != NULL)
f25b34 ¤   ¤   {
4f6505 ¤   ¤   ¤   PGPEventOutputData *d = &event->data.outputData;
0aaf5a
955863 ¤   ¤   ¤   // Added FYEO member for tempest viewer
26c467 ¤   ¤   ¤   userData->pVerBlock->FYEO=d->forYourEyesOnly;
0aaf5a
15723e ¤   ¤   ¤   PGPAddJobOptions(event->job,
22e6f1 ¤   ¤   ¤   ¤   PGPOAllocatedOutputBuffer(context,·
37d3dc ¤   ¤   ¤   ¤   ¤   &(userData->pVerBlock->pOutput),·
8b8421 ¤   ¤   ¤   ¤   ¤   INT_MAX,·
182463 ¤   ¤   ¤   ¤   ¤   &(userData->pVerBlock->outSize)),
53d911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
83af5a
71eec5 ¤   ¤   ¤   userData->pVerBlock->next = (VerificationBlock *)·
e3fe78 ¤   ¤   ¤   ¤   PGPNewData(memoryMgr,
d47906 ¤   ¤   ¤   ¤   ¤   sizeof(VerificationBlock),
a22e6f ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
9daf5a
54fe2b ¤   ¤   ¤   userData->pVerBlock->next->previous = userData->pVerBlock;
5c0678 ¤   ¤   ¤   userData->pVerBlock = userData->pVerBlock->next;
180fe4 ¤   ¤   }
9e2f68 ¤   ¤   break;
73af5a
2d589b ¤   case kPGPEvent_RecipientsEvent:
965b34 ¤   ¤   {
7a8757 ¤   ¤   ¤   PGPEventRecipientsData¤ *eventData;·
22af5a
e9200c ¤   ¤   ¤   eventData = &(event->data.recipientsData);
73af5a
b249a4 ¤   ¤   ¤   PGPIncKeySetRefCount(eventData->recipientSet);
400a86 ¤   ¤   ¤   userData->recipients = eventData->recipientSet;
f231b3 ¤   ¤   ¤   userData->keyCount = eventData->keyCount;
7daf5a
bbc9d3 ¤   ¤   ¤   if (eventData->keyCount > 0)
0cf776 ¤   ¤   ¤   {
3669b1 ¤   ¤   ¤   ¤   UINT i;
7daf5a
447624 ¤   ¤   ¤   ¤   userData->keyIDArray =¤ (PGPKeyID *)·
a524f7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   calloc(sizeof(PGPKeyID),
87837c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   eventData->keyCount);
efaf5a
6a42dc ¤   ¤   ¤   ¤   for (i=0; i<eventData->keyCount; i++)
d8b866 ¤   ¤   ¤   ¤   ¤   userData->keyIDArray[i] = eventData->keyIDArray[i];
--8c0a 000d3aaa20640110321 Page 12 of DecryptVerify.c
cfa3a6 ¤   ¤   ¤   }
41bb8c ¤   ¤   ¤   else
d691c8 ¤   ¤   ¤   ¤   userData->keyIDArray = NULL;
500fe4 ¤   ¤   }
8e2f68 ¤   ¤   break;
42af5a
686062 ¤   case kPGPEvent_PassphraseEvent:
585b34 ¤   ¤   {
880182 ¤   ¤   ¤   char szPrompt[256];
597b8d ¤   ¤   ¤   PGPEventPassphraseData *d = &event->data.passphraseData;
02af5a
397468 ¤   ¤   ¤   if (bAlreadyAsked)
c783fe ¤   ¤   ¤   ¤   LoadString(userData->hInst, IDS_PASSPHRASEREENTER, szPrompt,·
37579c ¤   ¤   ¤   ¤   ¤   sizeof(szPrompt));
f5bb8c ¤   ¤   ¤   else
60b341 ¤   ¤   ¤   ¤   LoadString(userData->hInst, IDS_PASSPHRASEPROMPT, szPrompt,·
23579c ¤   ¤   ¤   ¤   ¤   sizeof(szPrompt));
03af5a
f74356 ¤   ¤   ¤   // Don't cache conventional passphrases
54c8e2 ¤   ¤   ¤   if(d->fConventional)
f2f776 ¤   ¤   ¤   {
12dd2c ¤   ¤   ¤   ¤   err=PGPclGetPhrase (context,
fa06d0 ¤   ¤   ¤   ¤   ¤   pubKeySet,
35bfc8 ¤   ¤   ¤   ¤   ¤   hwnd,
40ef33 ¤   ¤   ¤   ¤   ¤   szPrompt,
633cd4 ¤   ¤   ¤   ¤   ¤   &szPassPhrase,·
712797 ¤   ¤   ¤   ¤   ¤   NULL,
65c55d ¤   ¤   ¤   ¤   ¤   NULL,·
543865 ¤   ¤   ¤   ¤   ¤   0,
082797 ¤   ¤   ¤   ¤   ¤   NULL,
832797 ¤   ¤   ¤   ¤   ¤   NULL,
9a689c ¤   ¤   ¤   ¤   ¤   PGPCL_DECRYPTION,
1d906f ¤   ¤   ¤   ¤   ¤   NULL,NULL,
2c5317 ¤   ¤   ¤   ¤   ¤   1,0,userData->tlsContext,NULL);
dba3a6 ¤   ¤   ¤   }
1dbb8c ¤   ¤   ¤   else
a5f776 ¤   ¤   ¤   {
001a22 ¤   ¤   ¤   ¤   err = PGPclGetCachedDecryptionPhrase(context,·
408eaf ¤   ¤   ¤   ¤   ¤   ¤   userData->tlsContext, pubKeySet, hwnd, szPrompt,·
28df53 ¤   ¤   ¤   ¤   ¤   ¤   bAlreadyAsked, &szPassPhrase, recipients, keyIDArray,
4efb9b ¤   ¤   ¤   ¤   ¤   ¤   keyCount, &pPasskey, &nPasskeyLength, ·&addedKeys);
52a3a6 ¤   ¤   ¤   }
3e87c7 ¤   ¤   ¤
522656 ¤   ¤   ¤   if (addedKeys != NULL)
b8f776 ¤   ¤   ¤   {
b8b39d ¤   ¤   ¤   ¤   PGPUInt32 numKeys;
fe2b85 ¤   ¤   ¤   ¤
f91eb9 ¤   ¤   ¤   ¤   PGPCountKeys(addedKeys, &numKeys);
377c2c ¤   ¤   ¤   ¤   if (numKeys > 0)
dea57e ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys(context, userData->tlsContext, hwnd,·
9d7a79 ¤   ¤   ¤   ¤   ¤   ¤   addedKeys, NULL);
342b85 ¤   ¤   ¤   ¤
10fe94 ¤   ¤   ¤   ¤   PGPFreeKeySet(addedKeys);
b29c8b ¤   ¤   ¤   ¤   addedKeys = NULL;
b3a3a6 ¤   ¤   ¤   }
8e87c7 ¤   ¤   ¤
6201a7 ¤   ¤   ¤   switch (err)
4ff776 ¤   ¤   ¤   {
c0772e ¤   ¤   ¤   case kPGPError_NoErr:
f25f2e ¤   ¤   ¤   ¤   bAlreadyAsked = TRUE;
95f622 ¤   ¤   ¤   ¤   break;
5c2b85 ¤   ¤   ¤   ¤
d0db68 ¤   ¤   ¤   default:
b6454a ¤   ¤   ¤   ¤   return err;
12a3a6 ¤   ¤   ¤   }
4587c7 ¤   ¤   ¤
ea007a ¤   ¤   ¤   if (IsntNull(szPassPhrase))
10f776 ¤   ¤   ¤   {
204943 ¤   ¤   ¤   ¤   err = PGPAddJobOptions(event->job,
d52bfd ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphrase(context, szPassPhrase),
e3afea ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
d32b85 ¤   ¤   ¤   ¤
--5466 00069058fe240110321 Page 13 of DecryptVerify.c
e9585e ¤   ¤   ¤   ¤   PGPclFreeCachedPhrase(szPassPhrase);
d0a2d9 ¤   ¤   ¤   ¤   szPassPhrase = NULL;
55a3a6 ¤   ¤   ¤   }
7ae8dc ¤   ¤   ¤   else if (IsntNull(pPasskey))
83f776 ¤   ¤   ¤   {
dc559a ¤   ¤   ¤   ¤   err = PGPAddJobOptions(event->job,·
aac197 ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer(context, pPasskey, nPasskeyLength),
89afea ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
fca3a6 ¤   ¤   ¤   }
af87c7 ¤   ¤   ¤
7bb363 ¤   ¤   ¤   if (IsntNull(pPasskey))
68f776 ¤   ¤   ¤   {
e17fbb ¤   ¤   ¤   ¤   PGPFreeData(pPasskey);
6a1675 ¤   ¤   ¤   ¤   pPasskey = NULL;
9704d3 ¤   ¤   ¤   ¤   nPasskeyLength = 0;
2da3a6 ¤   ¤   ¤   }
bd0fe4 ¤   ¤   }
c72f68 ¤   ¤   break;
48af5a
aa311c ¤   case kPGPEvent_AnalyzeEvent:
0c5acf ¤   ¤   if (userData->pVerBlock != NULL)
a35b34 ¤   ¤   {
6460ee ¤   ¤   ¤   if (event->data.analyzeData.sectionType == kPGPAnalyze_Encrypted)
abff6d ¤   ¤   ¤   ¤   userData->pVerBlock->bEncrypted = TRUE;
e10fe4 ¤   ¤   }
cd2f68 ¤   ¤   break;
8eaf5a
4d84f0 ¤   case kPGPEvent_SignatureEvent:
f85b34 ¤   ¤   {
40ec01 ¤   ¤   ¤   PGPEventSignatureData *d = &event->data.signatureData;
f0af5a
a58ce3 ¤   ¤   ¤   if (IsNull(d->signingKey) &&·
f58b1a ¤   ¤   ¤   ¤   SyncOnVerify(memoryMgr))
cff776 ¤   ¤   ¤   {
305de4 ¤   ¤   ¤   ¤   PGPBoolean bGotKeys;
8daf5a
01c911 ¤   ¤   ¤   ¤   PGPclLookupUnknownSigner(context, pubKeySet,·
5ede02 ¤   ¤   ¤   ¤   ¤   userData->tlsContext, hwnd, event, d->signingKeyID,·
40f35f ¤   ¤   ¤   ¤   ¤   &bGotKeys);
97af5a
5cb168 ¤   ¤   ¤   ¤   if (bGotKeys)
cb7e8f ¤   ¤   ¤   ¤   ¤   return kPGPError_NoErr;
78a3a6 ¤   ¤   ¤   }
b7af5a
3fe3cc ¤   ¤   ¤   if (userData->pVerBlock == NULL)
d9031f ¤   ¤   ¤   ¤   SigEvent(hwnd, context, d, szName);
9ebb8c ¤   ¤   ¤   else
bd6e39 ¤   ¤   ¤   ¤   CreateVerificationBlock(userData->hInst, context, d,
a5cb76 ¤   ¤   ¤   ¤   ¤   userData->pVerBlock->previous->bEncrypted,
31ea8d ¤   ¤   ¤   ¤   ¤   &(userData->pVerBlock->previous->szBlockBegin),
776217 ¤   ¤   ¤   ¤   ¤   &(userData->pVerBlock->previous->szBlockEnd));
ed0fe4 ¤   ¤   }
872f68 ¤   ¤   break;
e4af5a
9293c4 ¤   case kPGPEvent_FinalEvent:
29c52f ¤   ¤   if (IsntNull(szPassPhrase))
e15b34 ¤   ¤   {
fd0b45 ¤   ¤   ¤   PGPclFreeCachedPhrase(szPassPhrase);
4e9fb1 ¤   ¤   ¤   szPassPhrase = NULL;
df0fe4 ¤   ¤   }
a7389f ¤   ¤   if (IsntNull(pPasskey))
035b34 ¤   ¤   {
8a3e48 ¤   ¤   ¤   PGPFreeData(pPasskey);
d3ad23 ¤   ¤   ¤   pPasskey = NULL;
638f2f ¤   ¤   ¤   nPasskeyLength = 0;
a60fe4 ¤   ¤   }
db34ec ¤   ¤   bAlreadyAsked = FALSE;
f92f68 ¤   ¤   break;
069371 ¤   }
1daf5a
fb5ea8 ¤   return err;
69efe6 }
--652c 00016096db040110321 Page 14 of DecryptVerify.c
e0af5a
1aaf5a
7e58bc void DisplayErrorCode(char *szFile, int nLine, char *szModule, int nCode)
62bb36 {
79907b ¤   char szErrorMsg[255];
bdaf5a
0fdcc6 ¤   if (nCode == kPGPError_BadPacket)
0c946d ¤   ¤   nCode = kPGPError_CorruptData;
afaf5a
b4962d ¤   PGPclEncDecErrorToString(nCode, szErrorMsg, 254);
34af5a
331f29 #ifdef _DEBUG
711c4d ¤   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
450851 ¤   _CrtDbgReport(_CRT_ERROR, szFile, nLine, szModule, szErrorMsg);
ab7454 #endif
5aaf5a
921ed3 ¤   MessageBox(NULL, szErrorMsg, szModule, MB_ICONEXCLAMATION);
bc830f ¤   return;
9cefe6 }
88af5a
d9af5a
ab5485 static char * GetNextLine(char *szStart,
078ca3 ¤   ¤   ¤   ¤   ¤   ¤   ··char *szOutput,
e7e1c5 ¤   ¤   ¤   ¤   ¤   ¤   ··size_t nOutputSize)
bdbb36 {
d96fec ¤   char *szEnd = NULL;
c30567 ¤   BOOL bStop = FALSE;
8caf5a
221b9e ¤   if (szStart == NULL)
de7ed2 ¤   ¤   return NULL;
0eaf5a
52062b ¤   szEnd = strchr(szStart, '\n');
054fa0 ¤   if (szEnd == NULL)
b6c7a1 ¤   {
a25302 ¤   ¤   szEnd = strchr(szStart, '\0');
0c6a6e ¤   ¤   bStop = TRUE;
3e9371 ¤   }
63af5a
f3f387 ¤   if ((szOutput != NULL) && (nOutputSize > 0))
a3c7a1 ¤   {
883b0d ¤   ¤   size_t nLineSize;
d6809f ¤   ¤   size_t nBuffSize;
95af5a
003647 ¤   ¤   nLineSize = szEnd - szStart;
d62a83 ¤   ¤   if (nLineSize == 0)
329055 ¤   ¤   ¤   szOutput[0] = 0;
010e1d ¤   ¤   else
8b5b34 ¤   ¤   {
997bb9 ¤   ¤   ¤   if (nLineSize > nOutputSize)
8d7cdd ¤   ¤   ¤   ¤   nBuffSize = nOutputSize;
6bbb8c ¤   ¤   ¤   else
ca2e49 ¤   ¤   ¤   ¤   nBuffSize = nLineSize;
34af5a
0d3d20 ¤   ¤   ¤   strncpy(szOutput, szStart, nBuffSize);
78cdf4 ¤   ¤   ¤   szOutput[nBuffSize-1] = 0;
310fe4 ¤   ¤   }
b09371 ¤   }
36af5a
42c912 ¤   if (bStop)
3d7ed2 ¤   ¤   return NULL;
9a0e24 ¤   else
c53305 ¤   ¤   return szEnd+1;
edefe6 }
e1af5a
37af5a
06af5a
de7e4d /*__Editor_settings____
05af5a
1c4126 ¤   Local Variables:
167b17 ¤   tab-width: 4
230e6c ¤   End:
165f8c ¤   vi: ts=4 sw=4
--45c4 00133d4bd5340110321 Page 15 of DecryptVerify.c
b99e9b ¤   vim: si
33d062 _____________________*/
--b74d 0015c86383a40110322 Page 1 of DecryptVerify.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
30e095 ¤   $Id: DecryptVerify.h,v 1.3.2.2.2.1 1998/11/12 03:14:09 heller Exp $
aef7f7 ____________________________________________________________________________*/
e9edc6 #ifndef Included_DecryptVerify_h¤   /* [ */
47f964 #define Included_DecryptVerify_h
6baf5a
bfe2ff #include "pgpConfig.h"
122f8d #include "pgpErrors.h"
48ec82 #include "pgpTLS.h"
90af5a
af3379 #ifdef __cplusplus
206dad extern "C" {
d17454 #endif
0faf5a
d3cb69 PGPError DecryptVerifyBuffer(HINSTANCE hInst, HWND hwnd,·
221466 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPContextRef context,·
e5cadc ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPtlsContextRef tlsContext,·
5c2ba1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char *szName, char *szModule,
329bf4 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·void *pInput, DWORD dwInSize,
1103c5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL bMIME, void **ppOutput, PGPSize *pOutSize,
fec27c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL *FYEO);
91af5a
d7d504 PGPError DecryptVerifyFile(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
a862eb ¤   ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,·
258396 ¤   ¤   ¤   ¤   ¤   ¤   ···char *szName, char *szModule,
f1eec8 ¤   ¤   ¤   ¤   ¤   ¤   ···char *szInFile, BOOL bMIME, BOOL bBinary,
657fd7 ¤   ¤   ¤   ¤   ¤   ¤   ···char **pszOutFile, void **ppOutput,·
33bc59 ¤   ¤   ¤   ¤   ¤   ¤   ···PGPSize *pOutSize, BOOL *FYEO);
18af5a
d63379 #ifdef __cplusplus
97efe6 }
037454 #endif
90af5a
4c909b #endif /* ] Included_DecryptVerify_h */
b1af5a
1eaf5a
e17e4d /*__Editor_settings____
74af5a
614126 ¤   Local Variables:
077b17 ¤   tab-width: 4
bc0e6c ¤   End:
465f8c ¤   vi: ts=4 sw=4
b89e9b ¤   vim: si
e7d062 _____________________*/
35af5a
5caf5a
--0adf 0004191ba9440110323 Page 1 of EncryptSign.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e93fad ¤   $Id: EncryptSign.c,v 1.8.2.2.2.1 1998/11/12 03:14:10 heller Exp $
33f7f7 ____________________________________________________________________________*/
259b16 // System Headers
662032 #include <windows.h>·
4c3d0b #include <windowsx.h>
dcbb5f #include <assert.h>
62af5a
035582 // PGPsdk Headers
3ae2ff #include "pgpConfig.h"
70a076 #include "pgpKeys.h"
8c2f8d #include "pgpErrors.h"
b1e60d #include "pgpWerr.h"
ff4919 #include "pgpUtilities.h"
a90d08 #include "pgpMem.h"
7191b9 #include "pgpSDKPrefs.h"
a9af5a
dc2062 // Shared Headers
d08e25 #include "pgpVersionHeader.h"
ab5ab2 #include "PGPcl.h"
5cd2cf #include "BlockUtils.h"
24d092 #include "Working.h"
07cc89 #include "Prefs.h"
d0b04c #include "EncryptSign.h"
d41a14 #include "WorkingResource.h"
6def45 #include "SharedStrings.h"
6daf5a
97cf9a static int nProgressCount = 0;
3baf5a
9dd2bf static PGPError EncryptSign(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
a4e279 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPtlsContextRef tlsContext,·
db0304 ¤   ¤   ¤   ¤   ¤   ¤   ¤   char *szName, char *szModule,
1c56e8 ¤   ¤   ¤   ¤   ¤   ¤   ¤   RECIPIENTDIALOGSTRUCT *prds,
9a1296 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOptionListRef ioOptions,
683419 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOptionListRef mimeOptions,
3d98df ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOptionListRef *pSignOptions,
f4b9d9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   BOOL bEncrypt, BOOL bSign, BOOL bBinary);
e4af5a
9dcfd5 PGPError EncodeEventHandler(PGPContextRef context,·
133f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPEvent *event,·
d9a3a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUserValue userValue);
caaf5a
09ed94 static void DisplayErrorCode(char *szFile,·
dc4098 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·int nLine,·
87f417 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char *szModule,·
b311ef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·int nCode);
83af5a
8617f9 BOOL WrapBuffer(char **pszOutText,
19a3ee ¤   ¤   ¤   ¤   char *szInText,
3b40db ¤   ¤   ¤   ¤   PGPUInt16 wrapLength)
f6bb36 {
e2fdb2 ¤   BOOL RetVal = FALSE;
ad0040 ¤   PGPError err;
bdd8fb ¤   char *cmdlgBuffer;
74af5a
7b4894 ¤   err=PGPclWrapBuffer(
704916 ¤   ¤   ¤   ¤   ¤   szInText,
4e6675 ¤   ¤   ¤   ¤   ¤   wrapLength,
f3d168 ¤   ¤   ¤   ¤   ¤   &cmdlgBuffer);
18af5a
8dffd3 ¤   if(IsntPGPError (err))
a6c7a1 ¤   {
98b37b ¤   ¤   int memamt,length;
90af5a
ab4ff2 ¤   ¤   length=strlen(cmdlgBuffer);
95313b ¤   ¤   memamt=length+1;
41af5a
--37f0 000f0be9cd640110323 Page 2 of EncryptSign.c
cc46f5 ¤   ¤   *pszOutText=(char *)malloc(memamt);
6ebb4d ¤   ¤   memcpy(*pszOutText,cmdlgBuffer,length);
e3d70d ¤   ¤   (*pszOutText)[length]=0;
91bd5d ¤   ¤   PGPclFreeWrapBuffer(cmdlgBuffer);
7a135c ¤   ¤   RetVal = TRUE;
439371 ¤   }
0aaf5a
4142d7 ¤   return RetVal;
08efe6 }
8caf5a
65af5a
d2262b PGPError EncryptSignBuffer(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
9a62eb ¤   ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,·
4f8396 ¤   ¤   ¤   ¤   ¤   ¤   ···char *szName, char *szModule,
6dd1e8 ¤   ¤   ¤   ¤   ¤   ¤   ···void *pInput, DWORD dwInSize,·
9cec2c ¤   ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds,
5eb48b ¤   ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef mimeOptions,
46363a ¤   ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef *pSignOptions,
dbecda ¤   ¤   ¤   ¤   ¤   ¤   ···void **ppOutput, PGPSize *pOutSize, BOOL bEncrypt,·
819732 ¤   ¤   ¤   ¤   ¤   ¤   ···BOOL bSign, BOOL bBinary)
7dbb36 {
ee73ec ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
c99d7e ¤   PGPMemoryMgrRef¤¤   memoryMgr¤  ¤   = NULL;
3dc337 ¤   PGPOptionListRef¤   options¤¤   ¤   = NULL;
6c3fcc ¤   void *¤ ¤   ¤   ¤   pFinalInput¤¤   = NULL;
9e95a7 ¤   long¤   ¤   ¤   ¤   lWrapWidth¤ ¤   = 0;
d99ab1 ¤   BOOL¤   ¤   ¤   ¤   bInputWrapped¤  = FALSE;
d7af5a
01f0ef ¤   pgpAssert(pInput != NULL);
68eb8c ¤   pgpAssert(prds != NULL);
140bab ¤   pgpAssert(prds->OriginalKeySetRef != NULL);
6ae04e ¤   pgpAssert(pSignOptions != NULL);
4c7bf0 ¤   pgpAssert(ppOutput != NULL);
7e051b ¤   pgpAssert(pOutSize != NULL);
90f34e ¤   pgpAssert(PGPRefIsValid(context));
a5af5a
27cc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
938cca ¤   pFinalInput = pInput;
49af5a
ddfd13 ¤   if (!bBinary)
10c7a1 ¤   {
90ff2b ¤   ¤   if (ByDefaultWordWrap(memoryMgr, &lWrapWidth))
885b34 ¤   ¤   {
918f43 ¤   ¤   ¤   pFinalInput = NULL;
87df49 ¤   ¤   ¤   bInputWrapped = WrapBuffer((char **) &pFinalInput,·
cfa2e7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (char *) pInput, (short) lWrapWidth);
f6575a ¤   ¤   ¤   dwInSize = strlen((char *) pFinalInput);
360fe4 ¤   ¤   }
2f9371 ¤   }
ebaf5a
0a3443 ¤   err = PGPBuildOptionList(context, &options,·
34717a ¤   ¤   ¤   PGPOInputBuffer(context, pFinalInput, dwInSize),
7870b0 ¤   ¤   ¤   PGPOAllocatedOutputBuffer(context,·
779a85 ¤   ¤   ¤   ¤   ppOutput,·
ed0d75 ¤   ¤   ¤   ¤   INT_MAX,·
05966a ¤   ¤   ¤   ¤   pOutSize),
23e5ff ¤   ¤   ¤   PGPOLastOption(context));
cfaf5a
e682f0 ¤   if (IsPGPError(err))
38c7a1 ¤   {
22142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
1f8110 ¤   ¤   goto EncryptSignBufferError;
739371 ¤   }
71af5a
a360b5 ¤   err = EncryptSign(hInst, hwnd, context, tlsContext, szName, szModule,·
cb11bb ¤   ¤   ¤   prds, options, mimeOptions, pSignOptions, bEncrypt, bSign,·
21d760 ¤   ¤   ¤   bBinary);
9aaf5a
23c9a3 EncryptSignBufferError:
1aaf5a
d2be1b ¤   if (bInputWrapped)
f08b66 ¤   ¤   free(pFinalInput);
--63bf 0009607a77440110323 Page 3 of EncryptSign.c
e0af5a
45abae ¤   if (options != NULL)
607ce2 ¤   ¤   PGPFreeOptionList(options);
59af5a
bb5ea8 ¤   return err;
5fefe6 }
63af5a
12af5a
a24da1 PGPError EncryptSignFile(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
d7cde7 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPtlsContextRef tlsContext,·
5a9eb5 ¤   ¤   ¤   ¤   ¤   ¤   ·char *szName, char *szModule, char *szInFile,·
4061c2 ¤   ¤   ¤   ¤   ¤   ¤   ·RECIPIENTDIALOGSTRUCT *prds,·
751b87 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef mimeOptions,
d3db94 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef *pSignOptions, char *szOutFile,·
ceb996 ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL bEncrypt, BOOL bSign, BOOL bBinary)
0dbb36 {
9a73ec ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
02c337 ¤   PGPOptionListRef¤   options¤¤   ¤   = NULL;
5e0df5 ¤   PGPFileSpecRef¤ ¤   inputFile¤  ¤   = NULL;
eb23dc ¤   PGPFileSpecRef¤ ¤   outputFile¤ ¤   = NULL;
82af5a
26114a ¤   pgpAssert(szInFile != NULL);
dbeb8c ¤   pgpAssert(prds != NULL);
e60bab ¤   pgpAssert(prds->OriginalKeySetRef != NULL);
a7e04e ¤   pgpAssert(pSignOptions != NULL);
8a1bbc ¤   pgpAssert(szOutFile != NULL);
aaf34e ¤   pgpAssert(PGPRefIsValid(context));
f5af5a
88df37 ¤   err = PGPNewFileSpecFromFullPath(context, szInFile, &inputFile);
7882f0 ¤   if (IsPGPError(err))
a6c7a1 ¤   {
3d142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
dcebb0 ¤   ¤   goto EncryptSignFileError;
e79371 ¤   }
c7af5a
238ac1 ¤   err = PGPNewFileSpecFromFullPath(context, szOutFile, &outputFile);
7b82f0 ¤   if (IsPGPError(err))
6fc7a1 ¤   {
6b142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
4cebb0 ¤   ¤   goto EncryptSignFileError;
479371 ¤   }
28af5a
e23443 ¤   err = PGPBuildOptionList(context, &options,·
8fa174 ¤   ¤   ¤   PGPOInputFile(context, inputFile),
f8b1a8 ¤   ¤   ¤   PGPOOutputFile(context, outputFile),
0ce5ff ¤   ¤   ¤   PGPOLastOption(context));
02af5a
bd82f0 ¤   if (IsPGPError(err))
04c7a1 ¤   {
b2142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
f9ebb0 ¤   ¤   goto EncryptSignFileError;
1d9371 ¤   }
74af5a
f860b5 ¤   err = EncryptSign(hInst, hwnd, context, tlsContext, szName, szModule,·
1c11bb ¤   ¤   ¤   prds, options, mimeOptions, pSignOptions, bEncrypt, bSign,·
d7d760 ¤   ¤   ¤   bBinary);
c7af5a
4a1689 EncryptSignFileError:
3faf5a
7dabae ¤   if (options != NULL)
747ce2 ¤   ¤   PGPFreeOptionList(options);
a2af5a
040109 ¤   if (inputFile != NULL)
acacba ¤   ¤   PGPFreeFileSpec(inputFile);
40af5a
364fdb ¤   if (outputFile != NULL)
bb78a7 ¤   ¤   PGPFreeFileSpec(outputFile);
6faf5a
4e5ea8 ¤   return err;
d4efe6 }
0eaf5a
96af5a
--4af5 00018eaddb640110323 Page 4 of EncryptSign.c
5e87d2 PGPError EncryptSign(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
d6dcc0 ¤   ¤   ¤   ¤   ¤   ·PGPtlsContextRef tlsContext,·
013dbd ¤   ¤   ¤   ¤   ¤   ·char *szName, char *szModule,
bc1427 ¤   ¤   ¤   ¤   ¤   ·RECIPIENTDIALOGSTRUCT *prds,
b1d9d6 ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef ioOptions,
3f0aa0 ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef mimeOptions,
8dad54 ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef *pSignOptions,
269c49 ¤   ¤   ¤   ¤   ¤   ·BOOL bEncrypt, BOOL bSign,·
67060b ¤   ¤   ¤   ¤   ¤   ·BOOL bBinary)
10bb36 {
b073ec ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
1a9d7e ¤   PGPMemoryMgrRef¤¤   memoryMgr¤  ¤   = NULL;
27c668 ¤   PGPKeyRef¤  ¤   ¤   signKey¤¤   ¤   = NULL;
ceb938 ¤   PGPKeySetRef¤   ¤   pubKeySet¤  ¤   = NULL;
ae0762 ¤   PGPKeySetRef¤   ¤   addedKeys¤  ¤   = NULL;
4a3e3e ¤   PGPKeySetRef¤   ¤   recipKeySet¤¤   = NULL;
85c337 ¤   PGPOptionListRef¤   options¤¤   ¤   = NULL;
cbfabb ¤   PGPOptionListRef¤   tempOptions¤¤   = NULL;
ad2411 ¤   PGPCipherAlgorithm ·prefAlg¤¤   ¤   = kPGPCipherAlgorithm_CAST5;
238924 ¤   PGPCipherAlgorithm¤ allowedAlgs[3];
027f9e ¤   char *¤ ¤   ¤   ¤   szPassphrase¤   = NULL;
cbb063 ¤   char *¤ ¤   ¤   ¤   szConvPass¤ ¤   = NULL;
ff13de ¤   PGPByte *¤  ¤   ¤   pPasskey¤   ¤   = NULL;
d6ba3f ¤   PGPUInt32¤  ¤   ¤   nPasskeyLength¤ = 0;
432dda ¤   int¤¤   ¤   ¤   ¤   nPassphraseLen¤ = 0;
f0a6be ¤   int¤¤   ¤   ¤   ¤   nConvPassLen¤   = 0;
0bfe4c ¤   int¤¤   ¤   ¤   ¤   nNumAlgs¤   ¤   = 0;
2a8a8b ¤   BOOL¤   ¤   ¤   ¤   bGotPassphrase¤ = FALSE;
88ff9c ¤   BOOL¤   ¤   ¤   ¤   bGotConvPass¤   = FALSE;
4fc898 ¤   HWND¤   ¤   ¤   ¤   hwndWorking¤¤   = NULL;
d55a55 ¤   char ¤  ¤   ¤   ¤   szComment[256];
fa9224 ¤   char ¤  ¤   ¤   ¤   szWorkingTitle[256];
34af5a
5166e6 ¤   UpdateWindow(hwnd);
45cc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
9eaf5a
f87d44 ¤   // Check for demo expiration
9daf5a
b46671 ¤   if (PGPclEvalExpired(hwnd, PGPCL_ENCRYPTSIGNEXPIRED) != kPGPError_NoErr)
3b74be ¤   ¤   return kPGPError_UserAbort;
e0af5a
ce7744 ¤   pubKeySet = prds->OriginalKeySetRef;
3167c5 ¤
198ec8 ¤   err = PGPGetDefaultPrivateKey(pubKeySet, &signKey);
2882f0 ¤   if (IsPGPError(err))
17c7a1 ¤   {
3fd72f ¤   ¤   PGPKeyListRef¤  pubKeyList = NULL;
d54b5e ¤   ¤   PGPKeyIterRef¤  pubKeyIter = NULL;
a91b52 ¤   ¤
e9aed3 ¤   ¤   PGPOrderKeySet(pubKeySet, kPGPTrustOrdering, &pubKeyList);
b7efbc ¤   ¤   PGPNewKeyIter(pubKeyList, &pubKeyIter);
56ac2d ¤   ¤   PGPKeyIterNext(pubKeyIter, &signKey);
8d73c2 ¤   ¤   PGPFreeKeyIter(pubKeyIter);
abce98 ¤   ¤   PGPFreeKeyList(pubKeyList);
17af5a
db70bb ¤   ¤   err = kPGPError_NoErr;
e79371 ¤   }
cbaf5a
1b90bf ¤   err = kPGPError_BadPassphrase;
434085 ¤   while (err == kPGPError_BadPassphrase)
4bc7a1 ¤   {
1b3216 ¤   ¤   if (IsntNull(szPassphrase))
845b34 ¤   ¤   {
d7fc7c ¤   ¤   ¤   PGPclFreeCachedPhrase(szPassphrase);
26d268 ¤   ¤   ¤   szPassphrase = NULL;
700fe4 ¤   ¤   }
ecaf5a
a999bf ¤   ¤   if (IsntNull(szConvPass))
ee5b34 ¤   ¤   {
9c0fc9 ¤   ¤   ¤   PGPclFreePhrase(szConvPass);
1ab970 ¤   ¤   ¤   szConvPass = NULL;
180fe4 ¤   ¤   }
--b1d4 00095ce902b40110323 Page 5 of EncryptSign.c
e0af5a
4ddce5 ¤   ¤   if (IsNull(mimeOptions))
12086b ¤   ¤   ¤   err = PGPBuildOptionList(context, &options,·
72e0d4 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
100e1d ¤   ¤   else
40086b ¤   ¤   ¤   err = PGPBuildOptionList(context, &options,·
b1baeb ¤   ¤   ¤   ¤   ¤   mimeOptions,
83e0d4 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
8caf5a
32b6ad ¤   ¤   if (IsPGPError(err))
bd5b34 ¤   ¤   {
02ce02 ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
68107a ¤   ¤   ¤   goto EncryptSignError;
610fe4 ¤   ¤   }
19af5a
512161 ¤   ¤   if (GetCommentString(memoryMgr, szComment, 254))
7e5b34 ¤   ¤   {
2048d5 ¤   ¤   ¤   err = PGPBuildOptionList(context, &tempOptions,
8014c0 ¤   ¤   ¤   ¤   ¤   options,
5e445a ¤   ¤   ¤   ¤   ¤   PGPOCommentString(context, szComment),
b1e0d4 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
3287c7 ¤   ¤   ¤
580dfb ¤   ¤   ¤   if (IsPGPError(err))
64f776 ¤   ¤   ¤   {
354447 ¤   ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
f15189 ¤   ¤   ¤   ¤   goto EncryptSignError;
aca3a6 ¤   ¤   ¤   }
6eaf5a
eab9b7 ¤   ¤   ¤   PGPFreeOptionList(options);
819f5d ¤   ¤   ¤   options = tempOptions;
ab0fe4 ¤   ¤   }
bbaf5a
81c3a8 ¤   ¤   if (bEncrypt)
385b34 ¤   ¤   {
c7443a ¤   ¤   ¤   if (prds->dwOptions & PGPCL_ASCIIARMOR)
98f776 ¤   ¤   ¤   {
118cc9 ¤   ¤   ¤   ¤   err = PGPBuildOptionList(context, &tempOptions,
a6a671 ¤   ¤   ¤   ¤   ¤   ¤   PGPOArmorOutput(context, TRUE),
a4af96 ¤   ¤   ¤   ¤   ¤   ¤   options,
0dafea ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
efaf5a
933093 ¤   ¤   ¤   ¤   if (IsPGPError(err))
8c72c3 ¤   ¤   ¤   ¤   {
65a66b ¤   ¤   ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule,·
b05012 ¤   ¤   ¤   ¤   ¤   ¤   err);
145fc5 ¤   ¤   ¤   ¤   ¤   goto EncryptSignError;
6c2613 ¤   ¤   ¤   ¤   }
96af5a
4f31d1 ¤   ¤   ¤   ¤   PGPFreeOptionList(options);
c2deae ¤   ¤   ¤   ¤   options = tempOptions;
faa3a6 ¤   ¤   ¤   }
caaf5a
9bd763 ¤   ¤   ¤   if (prds->dwOptions & PGPCL_PASSONLY)
7cf776 ¤   ¤   ¤   {
767faa ¤   ¤   ¤   ¤   if (!bGotConvPass)
8b72c3 ¤   ¤   ¤   ¤   {
364f2b ¤   ¤   ¤   ¤   ¤   char szPrompt[256];
dbaf5a
b03079 ¤   ¤   ¤   ¤   ¤   LoadString(hInst, IDS_CONVPASSPHRASE, szPrompt,·
8559d0 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szPrompt));
7caf5a
f11ba1 ¤   ¤   ¤   ¤   ¤   err = PGPclGetPhrase(context, pubKeySet, hwnd, szPrompt,·
5c1320 ¤   ¤   ¤   ¤   ¤   ¤   &szConvPass, NULL, NULL, 0, NULL, NULL,·
69dfc9 ¤   ¤   ¤   ¤   ¤   ¤   PGPCL_ENCRYPTION, NULL, NULL,1,0,NULL,NULL);
79ae30 ¤   ¤   ¤   ¤   ¤
7f7a26 ¤   ¤   ¤   ¤   ¤   // wjb changed to 1 for min passphrase length
424d03 ¤   ¤   ¤   ¤   ¤   if (err == kPGPError_UserAbort)
9ace5d ¤   ¤   ¤   ¤   ¤   ¤   goto EncryptSignError;
86ae30 ¤   ¤   ¤   ¤   ¤
ff0ae4 ¤   ¤   ¤   ¤   ¤   nConvPassLen = strlen(szConvPass);
328338 ¤   ¤   ¤   ¤   ¤   bGotConvPass = TRUE;
952613 ¤   ¤   ¤   ¤   }
--fdbd 000a32ffab140110323 Page 6 of EncryptSign.c
9f2b85 ¤   ¤   ¤   ¤
7dc7e7 ¤   ¤   ¤   ¤   GetPreferredAlgorithm(memoryMgr, &prefAlg);
eaaf5a
f88cc9 ¤   ¤   ¤   ¤   err = PGPBuildOptionList(context, &tempOptions,
e9af96 ¤   ¤   ¤   ¤   ¤   ¤   options,
643f62 ¤   ¤   ¤   ¤   ¤   ¤   PGPOConventionalEncrypt(context,
7dc241 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphraseBuffer(context,
b2d3d1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szConvPass,·
a9e665 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nConvPassLen),
43d972 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context)),
1fe9a8 ¤   ¤   ¤   ¤   ¤   ¤   PGPOCipherAlgorithm(context, prefAlg),
46afea ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
39af5a
753093 ¤   ¤   ¤   ¤   if (IsPGPError(err))
d072c3 ¤   ¤   ¤   ¤   {
cfa66b ¤   ¤   ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule,·
9b5012 ¤   ¤   ¤   ¤   ¤   ¤   err);
065fc5 ¤   ¤   ¤   ¤   ¤   goto EncryptSignError;
3b2613 ¤   ¤   ¤   ¤   }
49a3a6 ¤   ¤   ¤   }
d6bb8c ¤   ¤   ¤   else
48f776 ¤   ¤   ¤   {
45a7f6 ¤   ¤   ¤   ¤   GetAllowedAlgorithms(memoryMgr, allowedAlgs, &nNumAlgs);
fb4e58 ¤   ¤   ¤   ¤   recipKeySet = prds->SelectedKeySetRef;
cfaf5a
ee8cc9 ¤   ¤   ¤   ¤   err = PGPBuildOptionList(context, &tempOptions,
e2af96 ¤   ¤   ¤   ¤   ¤   ¤   options,
7aa3af ¤   ¤   ¤   ¤   ¤   ¤   PGPOPreferredAlgorithms(context,
dec4ab ¤   ¤   ¤   ¤   ¤   ¤   ¤   allowedAlgs, nNumAlgs ),
0697ab ¤   ¤   ¤   ¤   ¤   ¤   PGPOEncryptToKeySet(context, recipKeySet),
44cdf3 ¤   ¤   ¤   ¤   ¤   ¤   PGPOFailBelowValidity(context, kPGPValidity_Unknown),
570289 ¤   ¤   ¤   ¤   ¤   ¤   PGPOWarnBelowValidity(context, kPGPValidity_Unknown),
5fafea ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
3daf5a
523093 ¤   ¤   ¤   ¤   if (IsPGPError(err))
7772c3 ¤   ¤   ¤   ¤   {
19a66b ¤   ¤   ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule,·
8e5012 ¤   ¤   ¤   ¤   ¤   ¤   err);
ea5fc5 ¤   ¤   ¤   ¤   ¤   goto EncryptSignError;
b62613 ¤   ¤   ¤   ¤   }
d5a3a6 ¤   ¤   ¤   }
d687c7 ¤   ¤   ¤
74b9b7 ¤   ¤   ¤   PGPFreeOptionList(options);
939f5d ¤   ¤   ¤   options = tempOptions;
630fe4 ¤   ¤   }
bc1b52 ¤   ¤
7093d3 ¤   ¤   if (bSign)
025b34 ¤   ¤   {
cc06f0 ¤   ¤   ¤   if (*pSignOptions == NULL)
b6f776 ¤   ¤   ¤   {
728a7e ¤   ¤   ¤   ¤   char szPrompt[256];
33af5a
3e7adc ¤   ¤   ¤   ¤   if (bGotPassphrase)
c33a6d ¤   ¤   ¤   ¤   ¤   LoadString(hInst, IDS_PASSPHRASEREENTER, szPrompt,·
d159d0 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szPrompt));
c1fa07 ¤   ¤   ¤   ¤   else
37cb3d ¤   ¤   ¤   ¤   ¤   LoadString(hInst, IDS_PASSPHRASEPROMPT, szPrompt,·
0559d0 ¤   ¤   ¤   ¤   ¤   ¤   sizeof(szPrompt));
f72b85 ¤   ¤   ¤   ¤
bc41d7 ¤   ¤   ¤   ¤   err = PGPclGetCachedSigningPhrase(context, tlsContext, hwnd,·
367a11 ¤   ¤   ¤   ¤   ¤   ¤   szPrompt, bGotPassphrase, &szPassphrase,·
b034f3 ¤   ¤   ¤   ¤   ¤   ¤   pubKeySet, &signKey, NULL, NULL, prds->dwFlags,
4f7336 ¤   ¤   ¤   ¤   ¤   ¤   &pPasskey, &nPasskeyLength, &addedKeys);
612b85 ¤   ¤   ¤   ¤
9767a5 ¤   ¤   ¤   ¤   if (addedKeys != NULL)
d272c3 ¤   ¤   ¤   ¤   {
65f26e ¤   ¤   ¤   ¤   ¤   PGPUInt32 numKeys;
17af5a
610f9e ¤   ¤   ¤   ¤   ¤   PGPCountKeys(addedKeys, &numKeys);
e54144 ¤   ¤   ¤   ¤   ¤   if (numKeys > 0)
5dddd3 ¤   ¤   ¤   ¤   ¤   ¤   PGPclQueryAddKeys(context, tlsContext, hwnd,·
a343bc ¤   ¤   ¤   ¤   ¤   ¤   ¤   addedKeys, NULL);
--faf9 000750111f840110323 Page 7 of EncryptSign.c
e0af5a
f0c751 ¤   ¤   ¤   ¤   ¤   PGPFreeKeySet(addedKeys);
e973f8 ¤   ¤   ¤   ¤   ¤   addedKeys = NULL;
062613 ¤   ¤   ¤   ¤   }
83af5a
da3093 ¤   ¤   ¤   ¤   if (IsPGPError(err))
f972c3 ¤   ¤   ¤   ¤   {
447e15 ¤   ¤   ¤   ¤   ¤   if (err != kPGPError_UserAbort)
ece81c ¤   ¤   ¤   ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule,·
c8671a ¤   ¤   ¤   ¤   ¤   ¤   ¤   err);
a55fc5 ¤   ¤   ¤   ¤   ¤   goto EncryptSignError;
352613 ¤   ¤   ¤   ¤   }
962b85 ¤   ¤   ¤   ¤
0cbbf1 ¤   ¤   ¤   ¤   bGotPassphrase = TRUE;
6c7f25 ¤   ¤   ¤   ¤   if (IsntNull(szPassphrase))
fd72c3 ¤   ¤   ¤   ¤   {
23828e ¤   ¤   ¤   ¤   ¤   nPassphraseLen = strlen(szPassphrase);
442b85 ¤   ¤   ¤   ¤
38cc2a ¤   ¤   ¤   ¤   ¤   err = PGPBuildOptionList(context, pSignOptions,
d02651 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOSignWithKey(context,·
86d9bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   signKey,·
fc2041 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPassphraseBuffer(context,
d92496 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   szPassphrase,·
95b48d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nPassphraseLen),
fada05 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context)),
1401eb ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
e12613 ¤   ¤   ¤   ¤   }
edee64 ¤   ¤   ¤   ¤   else if (IsntNull(pPasskey))
5d72c3 ¤   ¤   ¤   ¤   {
8bcc2a ¤   ¤   ¤   ¤   ¤   err = PGPBuildOptionList(context, pSignOptions,
9d2651 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOSignWithKey(context,·
6cd9bb ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   signKey,·
2c4726 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOPasskeyBuffer(context,
33d65f ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pPasskey,·
e41002 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   nPasskeyLength),
82da05 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context)),
c601eb ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
d32613 ¤   ¤   ¤   ¤   }
e52b85 ¤   ¤   ¤   ¤
663093 ¤   ¤   ¤   ¤   if (IsPGPError(err))
0d72c3 ¤   ¤   ¤   ¤   {
a07e15 ¤   ¤   ¤   ¤   ¤   if (err != kPGPError_UserAbort)
1de81c ¤   ¤   ¤   ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule,·
e3671a ¤   ¤   ¤   ¤   ¤   ¤   ¤   err);
a35fc5 ¤   ¤   ¤   ¤   ¤   goto EncryptSignError;
e32613 ¤   ¤   ¤   ¤   }
66a3a6 ¤   ¤   ¤   }
b3af5a
2b48d5 ¤   ¤   ¤   err = PGPBuildOptionList(context, &tempOptions,
e714c0 ¤   ¤   ¤   ¤   ¤   options,
8f0833 ¤   ¤   ¤   ¤   ¤   PGPOClearSign(context,·
8b1c0e ¤   ¤   ¤   ¤   ¤   ¤   (PGPBoolean) (!bEncrypt && !bBinary)),
f8e0d4 ¤   ¤   ¤   ¤   ¤   PGPOLastOption(context));
bb87c7 ¤   ¤   ¤
260dfb ¤   ¤   ¤   if (IsPGPError(err))
fff776 ¤   ¤   ¤   {
50e854 ¤   ¤   ¤   ¤   if (err != kPGPError_UserAbort)
17a66b ¤   ¤   ¤   ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule,·
8e5012 ¤   ¤   ¤   ¤   ¤   ¤   err);
cf5189 ¤   ¤   ¤   ¤   goto EncryptSignError;
a9a3a6 ¤   ¤   ¤   }
92af5a
f1b9b7 ¤   ¤   ¤   PGPFreeOptionList(options);
239f5d ¤   ¤   ¤   options = tempOptions;
0f0fe4 ¤   ¤   }
0e1b52 ¤   ¤
c03713 ¤   ¤   if (bEncrypt && !bSign)
3e3229 ¤   ¤   ¤   LoadString(hInst, IDS_WORKINGENCRYPT, szWorkingTitle,·
61f5f3 ¤   ¤   ¤   ¤   sizeof(szWorkingTitle));
ee88dd ¤   ¤   else if (!bEncrypt && bSign)
9d9d50 ¤   ¤   ¤   LoadString(hInst, IDS_WORKINGSIGN, szWorkingTitle,·
75f5f3 ¤   ¤   ¤   ¤   sizeof(szWorkingTitle));
--d0a6 000cd2b11e740110323 Page 8 of EncryptSign.c
040e1d ¤   ¤   else
ea66a7 ¤   ¤   ¤   LoadString(hInst, IDS_WORKINGENCRYPTSIGN, szWorkingTitle,·
a6f5f3 ¤   ¤   ¤   ¤   sizeof(szWorkingTitle));
d9af5a
5168d3 ¤   ¤   hwndWorking = WorkingDlgProcThread(GetModuleHandle(szModule),·
b91751 ¤   ¤   ¤   ¤   ¤   ¤   hInst, NULL, szWorkingTitle, "");
10af5a
484703 ¤   ¤   if (*pSignOptions == NULL)
dcbf45 ¤   ¤   ¤   PGPBuildOptionList(context, pSignOptions,·
9ed911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
2eaf5a
d017cf ¤   ¤   err = PGPEncode(context,
b15ee1 ¤   ¤   ¤   ¤   ioOptions,
e2837f ¤   ¤   ¤   ¤   PGPOEventHandler(context, EncodeEventHandler, hwndWorking),
00209d ¤   ¤   ¤   ¤   options,
5d366e ¤   ¤   ¤   ¤   *pSignOptions,
0d7233 ¤   ¤   ¤   ¤   PGPOSendNullEvents(context, 100),
cd40fa ¤   ¤   ¤   ¤   PGPODataIsASCII(context, (PGPBoolean) !bBinary),
fd4db0 ¤   ¤   ¤   ¤   PGPOVersionString(context, pgpVersionHeaderString),
2e3e03 ¤   ¤   ¤   ¤   PGPOAskUserForEntropy(context, TRUE),
5e3418 ¤   ¤   ¤   ¤   PGPOForYourEyesOnly(context,
a07ee3 ¤   ¤   ¤   ¤   ¤   (PGPBoolean)((prds->dwOptions & PGPCL_FYEO)==PGPCL_FYEO)),
9ad911 ¤   ¤   ¤   ¤   PGPOLastOption(context));
62af5a
f79cbb ¤   ¤   DestroyWindow(hwndWorking);
a1af5a
9f9ff3 ¤   ¤   if (options != NULL)
095b34 ¤   ¤   {
a3b9b7 ¤   ¤   ¤   PGPFreeOptionList(options);
4fd0cc ¤   ¤   ¤   options = NULL;
4d0fe4 ¤   ¤   }
6baf5a
7f6d95 ¤   ¤   if (err == kPGPError_BadPassphrase)
f25b34 ¤   ¤   {
da0d13 ¤   ¤   ¤   PGPFreeOptionList(*pSignOptions);
8af794 ¤   ¤   ¤   *pSignOptions = NULL;
a10fe4 ¤   ¤   }
3f9371 ¤   }
deaf5a
1c67ba ¤   if (IsPGPError(err) && (err != kPGPError_UserAbort))
65c7a1 ¤   {
d9142b ¤   ¤   DisplayErrorCode(__FILE__, __LINE__, szModule, err);
549c05 ¤   ¤   goto EncryptSignError;
669371 ¤   }
43af5a
8b1388 EncryptSignError:
fdaf5a
701e66 ¤   if (szPassphrase != NULL)
d7c7a1 ¤   {
73aee1 ¤   ¤   PGPclFreeCachedPhrase(szPassphrase);
f7693e ¤   ¤   szPassphrase = NULL;
e09371 ¤   }
bcaf5a
6014d5 ¤   if (pPasskey != NULL)
5ac7a1 ¤   {
02b237 ¤   ¤   PGPFreeData(pPasskey);
db997e ¤   ¤   pPasskey = NULL;
499371 ¤   }
a9af5a
7a21cd ¤   if (szConvPass != NULL)
bec7a1 ¤   {
f30a24 ¤   ¤   PGPclFreePhrase(szConvPass);
97ad58 ¤   ¤   szConvPass = NULL;
7d9371 ¤   }
e3af5a
0dabae ¤   if (options != NULL)
bc7ce2 ¤   ¤   PGPFreeOptionList(options);
94af5a
eb5ea8 ¤   return err;
aeefe6 }
fcaf5a
cdaf5a
--4220 0012d15594540110323 Page 9 of EncryptSign.c
91cfd5 PGPError EncodeEventHandler(PGPContextRef context,·
0b3f28 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPEvent *event,·
6fbcc6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PGPUserValue userValue)
6abb36 {
083ec9 ¤   HWND¤   ¤   ¤   hwnd¤   ¤   ¤   = NULL;
961e60 ¤   PGPError¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
afaf5a
45f34e ¤   pgpAssert(PGPRefIsValid(context));
221043 ¤   pgpAssert(event != NULL);
70af5a
fbbda6 ¤   hwnd = (HWND) userValue;
e2af5a
d7753a ¤   switch (event->type)
cfc7a1 ¤   {
d9d16c ¤   case kPGPEvent_EntropyEvent:
3a2ee0 ¤   ¤   err = PGPclRandom(context, hwnd,·
ef5691 ¤   ¤   ¤   ¤   event->data.entropyData.entropyBitsNeeded);
1a2f68 ¤   ¤   break;
31af5a
ca7813 ¤   case kPGPEvent_NullEvent:
97ed49 ¤   ¤   {¤
ce2098 ¤   ¤   ¤   PGPEventNullData *d = &event->data.nullData;
a53ab0 ¤   ¤   ¤   BOOL bCancel;
3baf5a
7c2f8b ¤   ¤   ¤   bCancel = WorkingCallback (¤(HWND)userValue,·
f0d676 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (unsigned long)d->bytesWritten,·
5bceb0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (unsigned long)d->bytesTotal) ;
88af5a
d54bab ¤   ¤   ¤   if(bCancel)
2df776 ¤   ¤   ¤   {
15398d ¤   ¤   ¤   ¤   return kPGPError_UserAbort;
8da3a6 ¤   ¤   ¤   }
e20fe4 ¤   ¤   }
752f68 ¤   ¤   break;
619371 ¤   }
cbaf5a
af5ea8 ¤   return err;
0fefe6 }
5aaf5a
a2af5a
0f58bc void DisplayErrorCode(char *szFile, int nLine, char *szModule, int nCode)
bcbb36 {
fb907b ¤   char szErrorMsg[255];
45af5a
72962d ¤   PGPclEncDecErrorToString(nCode, szErrorMsg, 254);
f8af5a
631f29 #ifdef _DEBUG
2a1c4d ¤   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
040851 ¤   _CrtDbgReport(_CRT_ERROR, szFile, nLine, szModule, szErrorMsg);
3b7454 #endif
e4af5a
a31ed3 ¤   MessageBox(NULL, szErrorMsg, szModule, MB_ICONEXCLAMATION);
24830f ¤   return;
d7efe6 }
86af5a
dcaf5a
7f7e4d /*__Editor_settings____
d3af5a
fd4126 ¤   Local Variables:
747b17 ¤   tab-width: 4
2d0e6c ¤   End:
415f8c ¤   vi: ts=4 sw=4
709e9b ¤   vim: si
2dd062 _____________________*/
--e042 001e5e3dc5040110324 Page 1 of EncryptSign.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
4d8f87 ¤   $Id: EncryptSign.h,v 1.3.2.1.2.1 1998/11/12 03:14:10 heller Exp $
60f7f7 ____________________________________________________________________________*/
fd3228 #ifndef Included_EncryptSign_h¤ /* [ */
e32fc1 #define Included_EncryptSign_h
e3af5a
e1e2ff #include "pgpConfig.h"
162f8d #include "pgpErrors.h"
08ec82 #include "pgpTLS.h"
f6af5a
4a3379 #ifdef __cplusplus
866dad extern "C" {
6f7454 #endif
95af5a
eb262b PGPError EncryptSignBuffer(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
1b62eb ¤   ¤   ¤   ¤   ¤   ¤   ···PGPtlsContextRef tlsContext,·
c68396 ¤   ¤   ¤   ¤   ¤   ¤   ···char *szName, char *szModule,
41d1e8 ¤   ¤   ¤   ¤   ¤   ¤   ···void *pInput, DWORD dwInSize,·
44ec2c ¤   ¤   ¤   ¤   ¤   ¤   ···RECIPIENTDIALOGSTRUCT *prds,
5fb48b ¤   ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef mimeOptions,
18363a ¤   ¤   ¤   ¤   ¤   ¤   ···PGPOptionListRef *pSignOptions,
4fecda ¤   ¤   ¤   ¤   ¤   ¤   ···void **ppOutput, PGPSize *pOutSize, BOOL bEncrypt,·
511226 ¤   ¤   ¤   ¤   ¤   ¤   ···BOOL bSign, BOOL bBinary);
3aaf5a
f34da1 PGPError EncryptSignFile(HINSTANCE hInst, HWND hwnd, PGPContextRef context,·
49cde7 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPtlsContextRef tlsContext,·
7b9eb5 ¤   ¤   ¤   ¤   ¤   ¤   ·char *szName, char *szModule, char *szInFile,·
0861c2 ¤   ¤   ¤   ¤   ¤   ¤   ·RECIPIENTDIALOGSTRUCT *prds,·
471b87 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef mimeOptions,
18db94 ¤   ¤   ¤   ¤   ¤   ¤   ·PGPOptionListRef *pSignOptions, char *szOutFile,·
8cf126 ¤   ¤   ¤   ¤   ¤   ¤   ·BOOL bEncrypt, BOOL bSign, BOOL bBinary);
b7af5a
ac17f9 BOOL WrapBuffer(char **pszOutText,
6ba3ee ¤   ¤   ¤   ¤   char *szInText,
97683e ¤   ¤   ¤   ¤   PGPUInt16 wrapLength);
0daf5a
6b3379 #ifdef __cplusplus
63efe6 }
397454 #endif
18af5a
07ec4c #endif /* ] Included_EncryptSign_h */
fcaf5a
0baf5a
907e4d /*__Editor_settings____
33af5a
9e4126 ¤   Local Variables:
767b17 ¤   tab-width: 4
b70e6c ¤   End:
035f8c ¤   vi: ts=4 sw=4
749e9b ¤   vim: si
61d062 _____________________*/
36af5a
e5af5a
--201e 0004f9f361440110325 Page 1 of Prefs.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
48c925 ¤   $Id: Prefs.c,v 1.2.8.1 1998/11/12 03:14:11 heller Exp $
86f7f7 ____________________________________________________________________________*/
ae9b16 // System Headers
822032 #include <windows.h>·
403d0b #include <windowsx.h>
30bb5f #include <assert.h>
30af5a
cf5582 // PGPsdk Headers
5ce2ff #include "pgpConfig.h"
a72f8d #include "pgpErrors.h"
d3e603 #include "pgpSymmetricCipher.h"
7fe8b2 #include "pflPrefs.h"
fc4720 #include "pflPrefTypes.h"
cea146 #include "pgpDebug.h"
6baf5a
282062 // Shared Headers
99c97b #include "pgpClientPrefs.h"
cf3991 #include "pgpAdminPrefs.h"
4f81a4 #include "pgpBuildFlags.h"
525ab2 #include "PGPcl.h"
86cc89 #include "Prefs.h"
60af5a
e4af5a
664cb3 BOOL UsePGPMimeForEncryption(PGPMemoryMgrRef memoryMgr)
1dbb36 {
faa733 ¤   PGPBoolean¤ bUseMime¤   = FALSE;
171b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
b9af5a
283bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
30a87a ¤   PGPGetPrefBoolean(prefRef, kPGPPrefMailEncryptPGPMIME, &bUseMime);
c14a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
acaf5a
d0caeb ¤   return (BOOL) bUseMime;
c2efe6 }
b7af5a
b0af5a
babfd2 BOOL UsePGPMimeForSigning(PGPMemoryMgrRef memoryMgr)
a2bb36 {
eca733 ¤   PGPBoolean¤ bUseMime¤   = FALSE;
ed1b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
d8af5a
873bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
c2e3ce ¤   PGPGetPrefBoolean(prefRef, kPGPPrefMailSignPGPMIME, &bUseMime);
924a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
18af5a
cfcaeb ¤   return (BOOL) bUseMime;
ddefe6 }
c5af5a
9f7e70 BOOL ByDefaultEncrypt(PGPMemoryMgrRef memoryMgr)
54bb36 {
0a4372 ¤   PGPBoolean¤ bEncrypt¤   = FALSE;
d41b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
82af5a
873bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
37947a ¤   PGPGetPrefBoolean(prefRef, kPGPPrefMailEncryptDefault, &bEncrypt);
1a4a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
3aaf5a
185569 ¤   return (BOOL) bEncrypt;
1aefe6 }
deaf5a
22af5a
d62e80 BOOL ByDefaultSign(PGPMemoryMgrRef memoryMgr)
fdbb36 {
f064a1 ¤   PGPBoolean¤ bSign¤  ¤   = FALSE;
401b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
4faf5a
--95c9 00000ad878240110325 Page 2 of Prefs.c
6d3bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
bf6a06 ¤   PGPGetPrefBoolean(prefRef, kPGPPrefMailSignDefault, &bSign);
ef4a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
b4af5a
5dfbd6 ¤   return (BOOL) bSign;
04efe6 }
fcaf5a
52af5a
c6698d BOOL ByDefaultWordWrap(PGPMemoryMgrRef memoryMgr, long* pThreshold)
00bb36 {
9890ce ¤   PGPBoolean¤ bWrap¤  ¤   = FALSE;
e3c1ec ¤   PGPUInt32¤  width¤  ¤   = 0;
b11b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
02af5a
363bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
74db8a ¤   PGPGetPrefBoolean(prefRef, kPGPPrefWordWrapEnable, &bWrap);
77afea ¤   PGPGetPrefNumber(prefRef, kPGPPrefWordWrapWidth, &width);
914a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
b8af5a
36ac52 ¤   *pThreshold = width;
80c6c2 ¤   return (BOOL) bWrap;
d1efe6 }
08af5a
dfaf5a
03c663 BOOL GetCommentString(PGPMemoryMgrRef memoryMgr,·
d06a31 ¤   ¤   ¤   ¤   ¤   ··char *szComment,·
037abc ¤   ¤   ¤   ¤   ¤   ··int nLength)
24bb36 {
a42321 ¤   PGPBoolean¤ bGotString¤ = FALSE;
801b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
edaf5a
65be29 #if PGP_BUSINESS_SECURITY
0baf5a
bad0d3 #if PGP_BUSINESS_SECURITY && PGP_ADMIN_BUILD
56fb17 ¤   PGPclOpenAdminPrefs(memoryMgr, &prefRef, TRUE);
75db21 #else
acffb3 ¤   PGPclOpenAdminPrefs(memoryMgr, &prefRef, FALSE);
b87454 #endif
87af5a
a38368 ¤   PGPGetPrefStringBuffer(prefRef, kPGPPrefComments, nLength, szComment);
639327 ¤   if (strlen(szComment) > 0)
40d931 ¤   ¤   bGotString = TRUE;
505bbe ¤   PGPclCloseAdminPrefs(prefRef, FALSE);
efaf5a
804798 ¤   if (bGotString)
38745f ¤   ¤   return (BOOL) bGotString;
53af5a
b454cb #endif¤ /* PGP_BUSINESS_SECURITY */
aeaf5a
093bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
a53a25 ¤   PGPGetPrefStringBuffer(prefRef, kPGPPrefComment, nLength, szComment);
8f9327 ¤   if (strlen(szComment) > 0)
aed931 ¤   ¤   bGotString = TRUE;
a64a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
d3af5a
d84357 ¤   return (BOOL) bGotString;
17efe6 }
75af5a
45af5a
8c50de BOOL GetPreferredAlgorithm(PGPMemoryMgrRef memoryMgr,·
431a09 ¤   ¤   ¤   ¤   ¤   ¤   ···PGPCipherAlgorithm *prefAlg)
9abb36 {
5ebba0 ¤   BOOL¤   ¤   bGotAlgorithm¤  = FALSE;
be7a2c ¤   PGPUInt32¤  alg¤¤   ¤   ¤   = 0;
d087c2 ¤   PGPPrefRef¤ prefRef¤¤   ¤   = NULL;
ce1398 ¤   PGPError¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
76af5a
d93bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
343f8b ¤   err = PGPGetPrefNumber(prefRef, kPGPPrefPreferredAlgorithm, &alg);
c94a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
a1af5a
00f69b ¤   if (IsntPGPError(err))
--8d37 00079cd1cb940110325 Page 3 of Prefs.c
f7c7a1 ¤   {
d818ea ¤   ¤   *prefAlg = (PGPCipherAlgorithm) alg;
7683e8 ¤   ¤   bGotAlgorithm = TRUE;
759371 ¤   }
5f0e24 ¤   else
1956aa ¤   ¤   *prefAlg = kPGPCipherAlgorithm_CAST5;
61af5a
e2e6e5 ¤   return bGotAlgorithm;
70efe6 }
17af5a
eaaf5a
b53c61 BOOL GetAllowedAlgorithms(PGPMemoryMgrRef memoryMgr,·
c46d7b ¤   ¤   ¤   ¤   ¤   ¤   ··PGPCipherAlgorithm *pAllowedAlgs,·
c6344e ¤   ¤   ¤   ¤   ¤   ¤   ··int *pNumAlgs)
17bb36 {
f98fb6 ¤   BOOL¤   ¤   ¤   ¤   bGotAlgorithms¤ = FALSE;
45121a ¤   PGPPrefRef¤ ¤   ¤   prefRef¤¤   ¤   = NULL;
fa7d2f ¤   PGPCipherAlgorithm *pData¤  ¤   ¤   = NULL;
468937 ¤   PGPSize¤¤   ¤   ¤   dataLength¤ ¤   = 0;
4c73ec ¤   PGPError¤   ¤   ¤   err¤¤   ¤   ¤   = kPGPError_NoErr;
135c63 ¤   int¤¤   ¤   ¤   ¤   i¤  ¤   ¤   ¤   = 0;
7faf5a
5707f2 ¤   pgpAssert(pAllowedAlgs != NULL);
0d4bf7 ¤   pgpAssert(pNumAlgs != NULL);
6daf5a
ce3bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
f8dc31 ¤   err = PGPGetPrefData(prefRef, kPGPPrefAllowedAlgorithmsList,·
d6ab5f ¤   ¤   ¤   &dataLength, (void **) &pData);
42af5a
0cf69b ¤   if (IsntPGPError(err))
88c7a1 ¤   {
6a6239 ¤   ¤   *pNumAlgs = dataLength / sizeof(PGPCipherAlgorithm);
33c17e ¤   ¤   for (i=0; i<*pNumAlgs; i++)
38d399 ¤   ¤   ¤   pAllowedAlgs[i] = pData[i];
d3af5a
1c8a38 ¤   ¤   bGotAlgorithms = TRUE;
3bdc3e ¤   ¤   PGPDisposePrefData(prefRef, (void *) pData);
ce9371 ¤   }
7f0e24 ¤   else
ce44c3 ¤   ¤   *pNumAlgs = 0;
a8af5a
b94a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
8e70d1 ¤   return bGotAlgorithms;
66efe6 }
0caf5a
a7af5a
83c916 BOOL AutoDecrypt(PGPMemoryMgrRef memoryMgr)
19bb36 {
6d331a ¤   PGPBoolean¤ bAuto¤  ¤   = FALSE;
c61b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
84af5a
c43bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
3d3788 ¤   PGPGetPrefBoolean(prefRef, kPGPPrefAutoDecrypt, &bAuto);
a14a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
53af5a
b0cef0 ¤   return (BOOL) bAuto;
c3efe6 }
50af5a
4aaf5a
89667a BOOL SyncOnVerify(PGPMemoryMgrRef memoryMgr)
f9bb36 {
1ccf4b ¤   PGPBoolean¤ bSync¤  ¤   = FALSE;
fa1b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
41af5a
713bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
cc4d78 ¤   PGPGetPrefBoolean(prefRef, kPGPPrefKeyServerSyncOnVerify, &bSync);
2e4a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
3caf5a
86498a ¤   return (BOOL) bSync;
a5efe6 }
11af5a
79af5a
--ee20 001e71f54d540110325 Page 4 of Prefs.c
929e93 BOOL MarginalIsInvalid(PGPMemoryMgrRef memoryMgr)
b7bb36 {
6e4b69 ¤   PGPBoolean¤ bInvalid¤   = FALSE;
0c1b91 ¤   PGPPrefRef¤ prefRef¤¤   = NULL;
6eaf5a
173bca ¤   PGPclOpenClientPrefs(memoryMgr, &prefRef);
3a0184 ¤   PGPGetPrefBoolean(prefRef, kPGPPrefMarginalIsInvalid, &bInvalid);
f84a0b ¤   PGPclCloseClientPrefs(prefRef, FALSE);
c8af5a
f033a2 ¤   return (BOOL) bInvalid;
26efe6 }
61af5a
fdaf5a
3daf5a
f17e4d /*__Editor_settings____
3faf5a
b34126 ¤   Local Variables:
2b7b17 ¤   tab-width: 4
980e6c ¤   End:
6a5f8c ¤   vi: ts=4 sw=4
d49e9b ¤   vim: si
e7d062 _____________________*/
--67c5 001619d333d40110326 Page 1 of Prefs.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
7af2df ¤   $Id: Prefs.h,v 1.2.8.1 1998/11/12 03:14:12 heller Exp $
a0f7f7 ____________________________________________________________________________*/
dc1ec6 #ifndef Included_Prefs_h¤   /* [ */
a86803 #define Included_Prefs_h
09af5a
665655 #include <windows.h>
174919 #include "pgpUtilities.h"
94e603 #include "pgpSymmetricCipher.h"
5caf5a
ed3379 #ifdef __cplusplus
cc6dad extern "C" {
937454 #endif
c3af5a
c2877c BOOL UsePGPMimeForEncryption(PGPMemoryMgrRef memoryMgr);
85f500 BOOL UsePGPMimeForSigning(PGPMemoryMgrRef memoryMgr);
8673d9 BOOL ByDefaultEncrypt(PGPMemoryMgrRef memoryMgr);
1a8406 BOOL ByDefaultSign(PGPMemoryMgrRef memoryMgr);
fb5fa4 BOOL ByDefaultWordWrap(PGPMemoryMgrRef memoryMgr, long* pThreshold);
32af5a
08c663 BOOL GetCommentString(PGPMemoryMgrRef memoryMgr,·
466a31 ¤   ¤   ¤   ¤   ¤   ··char *szComment,·
147fbd ¤   ¤   ¤   ¤   ¤   ··int nLength);
97af5a
9750de BOOL GetPreferredAlgorithm(PGPMemoryMgrRef memoryMgr,·
e19dfb ¤   ¤   ¤   ¤   ¤   ¤   ···PGPCipherAlgorithm *prefAlg);
f2af5a
7b3c61 BOOL GetAllowedAlgorithms(PGPMemoryMgrRef memoryMgr,·
f46d7b ¤   ¤   ¤   ¤   ¤   ¤   ··PGPCipherAlgorithm *pAllowedAlgs,·
cdab6e ¤   ¤   ¤   ¤   ¤   ¤   ··int *pNumAlgs);
daaf5a
0e755e BOOL AutoDecrypt(PGPMemoryMgrRef memoryMgr);
80dc9b BOOL SyncOnVerify(PGPMemoryMgrRef memoryMgr);
eca6ac BOOL MarginalIsInvalid(PGPMemoryMgrRef memoryMgr);
6caf5a
3f3379 #ifdef __cplusplus
cbefe6 }
787454 #endif
42af5a
51e6db #endif /* ] Included_Prefs_h */
29af5a
11af5a
527e4d /*__Editor_settings____
48af5a
a64126 ¤   Local Variables:
a67b17 ¤   tab-width: 4
ce0e6c ¤   End:
4b5f8c ¤   vi: ts=4 sw=4
f59e9b ¤   vim: si
75d062 _____________________*/
f6af5a
61af5a
--9ebf 0002e57788740110327 Page 1 of RichEdit_IO.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
1c630e ¤   $Id: RichEdit_IO.c,v 1.1.18.1 1998/11/12 03:14:12 heller Exp $
37f7f7 ____________________________________________________________________________*/
60af5a
059b16 // System Headers
ff5655 #include <windows.h>
4b2f6f #include <richedit.h>
b9af5a
56e8e0 // Project Headers
441db1 #include "RichEdit_IO.h"
5faf5a
cdf0f7 typedef struct {
39a49c ¤   LPSTR lpBuffer;
4905df ¤   LONG byteCount;
fa7231 } STREAMSTRUCT;
63af5a
a4af5a
57bf56 //----------------------------------------------------|
baf814 // ·Get contents of RichEdit control callback routine
43af5a
7fccb1 DWORD CALLBACK GetRichEditCallback (DWORD dwCookie, LPBYTE pbBuff,
b120de ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LONG cb, LONG FAR *pcb) {
89af5a
b8909f ¤   STREAMSTRUCT* psS;
52af5a
905e52 ¤   psS = (STREAMSTRUCT*)dwCookie;
4eaf5a
85eae9 ¤   if (psS->lpBuffer) psS->lpBuffer = HeapReAlloc (GetProcessHeap (), 0, psS->¶
e2916d lpBuffer, psS->byteCount + cb + 1);
698a14 ¤   else psS->lpBuffer = HeapAlloc (GetProcessHeap (), 0, cb+1);
30af5a
e98dde ¤   //MessageBox(NULL, "GetRichEditCallback", "Here", MB_OK);
c8af5a
55ce79 ¤   if (psS->lpBuffer) {
829c5b ¤   ¤   MoveMemory (psS->lpBuffer + psS->byteCount, pbBuff, cb);
c479df ¤   ¤   psS->lpBuffer[psS->byteCount + cb] = '\0';
898bf4 ¤   ¤   psS->byteCount += cb;
b54625 ¤   ¤   *pcb = cb;
80bbde ¤   ¤   return 0;
509371 ¤   }
09af5a
1464b7 ¤   return 1;
0fefe6 }
7daf5a
c7bf56 //----------------------------------------------------|
cd335b // ·Get contents of RichEdit control
77af5a
32d2cb LPSTR GetRichEditContents (HWND hWndRichEditControl, LPLONG lpi, BOOL bRTF, BOO¶
14f6b0 L bSel) {
91d493 ¤   int iAttrib;
1d6cf5 ¤   EDITSTREAM eStream;
e780f3 ¤   STREAMSTRUCT sStruct;
22af5a
baa0f6 ¤   if (bRTF) iAttrib = SF_RTF;
ad8172 ¤   else iAttrib = SF_TEXT;
13af5a
8abbee ¤   if(bSel)
8ac7a1 ¤   {
6a9015 ¤   ¤   iAttrib |= SFF_SELECTION;
129371 ¤   }
c6af5a
0594ab ¤   sStruct.lpBuffer = NULL;
a01ffc ¤   sStruct.byteCount = 0;
52af5a
09d106 ¤   eStream.dwCookie = (DWORD)&sStruct;
0c4e4d ¤   eStream.dwError = 0;
2e7d28 ¤   eStream.pfnCallback = GetRichEditCallback;
--a576 001f7ed53c940110327 Page 2 of RichEdit_IO.c
e0af5a
1a33de ¤   SendMessage (hWndRichEditControl, EM_STREAMOUT, (WPARAM)iAttrib,
294bd7 ¤   ¤   (LPARAM)&eStream);
0baf5a
714cbb ¤   if (eStream.dwError) {
0b2533 ¤   ¤   if (sStruct.lpBuffer) HeapFree (GetProcessHeap (), 0, sStruct.lpBuffer);
f47ed2 ¤   ¤   return NULL;
ba9371 ¤   }
b1af5a
1dd5b7 ¤   if (lpi) *lpi = sStruct.byteCount;
504da5 ¤   return (LPSTR)sStruct.lpBuffer;
4eefe6 }
bfaf5a
31af5a
29bf56 //----------------------------------------------------|
afb4ab // ·Set contents of RichEdit control callback routine
8faf5a
3ffd7f DWORD CALLBACK SetRichEditCallback (DWORD dwCookie, LPBYTE pbBuff,
eb20de ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   LONG cb, LONG FAR *pcb) {
6a909f ¤   STREAMSTRUCT* psS;
9aaf5a
4e5e52 ¤   psS = (STREAMSTRUCT*)dwCookie;
ffaf5a
6f6d1c ¤   if (cb >= psS->byteCount) {
af2080 ¤   ¤   MoveMemory (pbBuff, psS->lpBuffer, psS->byteCount);
be6153 ¤   ¤   *pcb = psS->byteCount;
11cda1 ¤   ¤   psS->byteCount = 0;
10bbde ¤   ¤   return 0;
be9371 ¤   }
9a665a ¤   else {
e227ec ¤   ¤   MoveMemory (pbBuff, psS->lpBuffer, cb);
0e4625 ¤   ¤   *pcb = cb;
59d339 ¤   ¤   psS->byteCount -= cb;
5878c6 ¤   ¤   psS->lpBuffer += cb;
fcbbde ¤   ¤   return 0;
029371 ¤   }
6fefe6 }
15af5a
02bf56 //----------------------------------------------------|
b21cb2 // ·Set contents of RichEdit control
ccaf5a
4e5c89 LONG SetRichEditContents (HWND hWndRichEditControl, LPSTR lpBuffer, BOOL bRTF, ¶
1090e6 BOOL bSel) {
f7d493 ¤   int iAttrib;
c46cf5 ¤   EDITSTREAM eStream;
f280f3 ¤   STREAMSTRUCT sStruct;
02af5a
7ca0f6 ¤   if (bRTF) iAttrib = SF_RTF;
f38172 ¤   else iAttrib = SF_TEXT;
b1af5a
dcbbee ¤   if(bSel)
cbc7a1 ¤   {
549015 ¤   ¤   iAttrib |= SFF_SELECTION;
a59371 ¤   }
44af5a
88c22a ¤   sStruct.lpBuffer = lpBuffer;
ad3bb2 ¤   sStruct.byteCount = lstrlen (lpBuffer);
78af5a
fcd106 ¤   eStream.dwCookie = (DWORD)&sStruct;
544e4d ¤   eStream.dwError = 0;
4ace6b ¤   eStream.pfnCallback = SetRichEditCallback;
41af5a
1fff0e ¤   SendMessage (hWndRichEditControl, EM_STREAMIN, (WPARAM)iAttrib,
cc4bd7 ¤   ¤   (LPARAM)&eStream);
3aaf5a
d1af27 ¤   SendMessage (hWndRichEditControl, EM_SETMODIFY, (WPARAM)TRUE, 0L);
82af5a
b4e983 ¤   if (eStream.dwError) return 1;
f53e6b ¤   return 0;
61efe6 }
8faf5a
f7af5a
--fa25 0019abd400d40110328 Page 1 of RichEdit_IO.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
6de9eb ¤   $Id: RichEdit_IO.h,v 1.1.18.1 1998/11/12 03:14:13 heller Exp $
d3f7f7 ____________________________________________________________________________*/
6f00bf #ifndef Included_RichEdit_IO_h¤ /* [ */
3898e9 #define Included_RichEdit_IO_h
f1af5a
303379 #ifdef __cplusplus
6e6dad extern "C" {
527454 #endif
76af5a
5f7bbc //------------------------------------------------------------------|
a9465d //
e1783f //¤ Get contents of RichEdit control.
1bb7a4 //¤ ¤   hWndRichEditCtrl= handle of control that is to be read
d61818 //¤ ¤   bRTF¤   ¤   ¤   = TRUE => return contents in RTF format
d96f38 //¤ ¤   ¤   ¤   ¤   ¤   = FALSE => return contents in plain ASCII text format
a69eb5 //¤ ¤   lpcb¤   ¤   ¤   = pointer to variable to receive number of characters·
624bb2 //¤ ¤   ¤   ¤   ¤   ¤   ··tranferred into buffer (including trailing NULL chara¶
362a8d cter)
d4465d //
e4edeb //¤ Function returns pointer to allocated buffer if successful, NULL·
e93ce4 // ·otherwise. ·When it is no longer needed, the calling routine must free·
01a9c2 // ·the allocated buffer from the process heap by call HeapFree. E.g.:
59465d //
a944fd //¤ ¤   HeapFree (GetProcessHeap(), 0, lpBuffer);
81465d //
772e26 LPSTR GetRichEditContents (HWND hWndRichEditCtrl, LPLONG lpcb, BOOL bRTF, BOOL ¶
173460 bSel);
4f465d //
197bbc //------------------------------------------------------------------|
0caf5a
ec7bbc //------------------------------------------------------------------|
85465d //
db465d //
9502df //¤ Set contents of RichEdit control.
3fbbde //¤ ¤   hWndRichEditCtrl= handle of control that is to be set.
e50773 //¤ ¤   bRTF¤   ¤   ¤   = TRUE => buffer contents are in RTF format
4bdafa //¤ ¤   ¤   ¤   ¤   ¤   = FALSE => buffer contents are in plain ASCII text form¶
89676f at
8f46ff //¤ ¤   lpBuffer¤   ¤   = buffer containing text to load into control
56465d //
0ae1fb //¤ Function returns 0 if no error.
2d465d //
b1bea5 LONG SetRichEditContents (HWND hWndRichEditCtrl, LPSTR lpBuffer, BOOL bRTF, BOO¶
8724dc L bSel);
0b465d //
ee7bbc //------------------------------------------------------------------|
af3379 #ifdef __cplusplus
24efe6 }
5b7454 #endif
245ed3 #endif /* ] Included_RichEdit_IO_h */
86af5a
61af5a
547e4d /*__Editor_settings____
9daf5a
f24126 ¤   Local Variables:
a97b17 ¤   tab-width: 4
450e6c ¤   End:
3f5f8c ¤   vi: ts=4 sw=4
d69e9b ¤   vim: si
9ad062 _____________________*/
--7b92 00161d9939640110329 Page 1 of SharedStrings.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
75237d // Used by SharedStrings.rc
28465d //
a434d0 #define IDS_PASSPHRASEPROMPT ···········9501
894caa #define IDS_PASSPHRASEREENTER ··········9502
3d342c #define IDS_CONVPASSPHRASE ·············9503
ad7a45 #define IDS_SIGSTATUS ··················9504
d9b599 #define IDS_ALGNOTSUPPORTED ············9505
b67cdd #define IDS_GOODSIG ····················9506
82df2a #define IDS_BADSIG ·····················9507
671411 #define IDS_UNKNOWNSIG ·················9508
0b1696 #define IDS_SIGNER ·····················9509
76a672 #define IDS_UNKNOWNSIGNER ··············9510
c13e82 #define IDS_REVOKEDKEY ·················9511
4d1bb8 #define IDS_EXPIREDKEY ·················9512
f05ebe #define IDS_DISABLEDKEY ················9513
9edd9f #define IDS_INVALIDKEY ·················9514
9a9bf8 #define IDS_SIGDATE ····················9515
57f6f8 #define IDS_VERIFIED ···················9516
428b45 #define IDS_BEGINDECRYPTED ·············9517
3389ab #define IDS_ENDDECRYPTED ···············9518
04fe09 #define IDS_BEGINVERIFIED ··············9519
06cda1 #define IDS_ENDVERIFIED ················9520
5baf5a
ef11aa // Next default values for new objects
d5ac6a //·
0cf860 #ifdef APSTUDIO_INVOKED
163f23 #ifndef APSTUDIO_READONLY_SYMBOLS
dab0ab #define _APS_NEXT_RESOURCE_VALUE ·······101
e2611c #define _APS_NEXT_COMMAND_VALUE ········40001
36f6ec #define _APS_NEXT_CONTROL_VALUE ········1000
981285 #define _APS_NEXT_SYMED_VALUE ··········101
827454 #endif
617454 #endif
--08b2 000109afba24011032a Page 1 of SharedStrings.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
5aef45 #include "SharedStrings.h"
12af5a
7ae1bf #define APSTUDIO_READONLY_SYMBOLS
286c0e /////////////////////////////////////////////////////////////////////////////
f8465d //
5b0131 // Generated from the TEXTINCLUDE 2 resource.
79465d //
2f897a #include "afxres.h"
b7af5a
e26c0e /////////////////////////////////////////////////////////////////////////////
547b93 #undef APSTUDIO_READONLY_SYMBOLS
d6af5a
d66c0e /////////////////////////////////////////////////////////////////////////////
ddf930 // English (U.S.) resources
f4af5a
871201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
9aec08 #ifdef _WIN32
8de912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
fd9c1c #pragma code_page(1252)
d81f8e #endif //_WIN32
73af5a
bff860 #ifdef APSTUDIO_INVOKED
e96c0e /////////////////////////////////////////////////////////////////////////////
18465d //
ce5733 // TEXTINCLUDE
ec465d //
a0af5a
c286ef 1 TEXTINCLUDE DISCARDABLE·
1b4523 BEGIN
9e2464 ····"SharedStrings.h\0"
41e0d1 END
15af5a
817037 2 TEXTINCLUDE DISCARDABLE·
624523 BEGIN
f1eb23 ····"#include ""afxres.h""\r\n"
47db5c ····"\0"
36e0d1 END
1caf5a
2b227f 3 TEXTINCLUDE DISCARDABLE·
224523 BEGIN
3be851 ····"\r\n"
9fdb5c ····"\0"
4be0d1 END
3faf5a
2f69ab #endif ···// APSTUDIO_INVOKED
56af5a
44af5a
af6c0e /////////////////////////////////////////////////////////////////////////////
9e465d //
165e87 // String Table
e8465d //
a5af5a
cf6f6c STRINGTABLE DISCARDABLE·
f74523 BEGIN
97ca2c ····IDS_PASSPHRASEPROMPT ···"Please enter your passphrase:"
a595db ····IDS_PASSPHRASEREENTER ··"Passphrase did not match. Please try again:"
209961 ····IDS_CONVPASSPHRASE ·····"Enter conventional passphrase:"
6ce0d1 END
3faf5a
0b6f6c STRINGTABLE DISCARDABLE·
c64523 BEGIN
cd2178 ····IDS_SIGSTATUS ··········"\r\n*** PGP Signature Status: "
2375e3 ····IDS_ALGNOTSUPPORTED ····"signing algorithm not supported\r\n"
62806b ····IDS_GOODSIG ············"good\r\n"
460385 ····IDS_BADSIG ·············"bad\r\n"
502104 ····IDS_UNKNOWNSIG ·········"unknown\r\n"
91507e ····IDS_SIGNER ·············"*** Signer: "
db7047 ····IDS_UNKNOWNSIGNER ······"Unknown, Key ID = "
937a9c ····IDS_REVOKEDKEY ·········"(Revoked)\r\n"
106818 ····IDS_EXPIREDKEY ·········"(Expired)\r\n"
--77cb 00150cdaefe4011032a Page 2 of SharedStrings.rc
ad66b1 ····IDS_DISABLEDKEY ········"(Disabled)\r\n"
63b1c1 ····IDS_INVALIDKEY ·········"(Invalid)\r\n"
10e37e ····IDS_SIGDATE ············"*** Signed: "
8c507d ····IDS_VERIFIED ···········"*** Verified: "
1a641a ····IDS_BEGINDECRYPTED ·····"*** BEGIN PGP DECRYPTED/VERIFIED MESSAGE ***\r\n\r¶
f4e8ad \n"
aa895f ····IDS_ENDDECRYPTED ·······"\r\n\r\n*** END PGP DECRYPTED/VERIFIED MESSAGE ***¶
4c9a43 \r\n"
fc7c59 ····IDS_BEGINVERIFIED ······"*** BEGIN PGP VERIFIED MESSAGE ***\r\n\r\n"
bde0d1 END
ddaf5a
fa6f6c STRINGTABLE DISCARDABLE·
544523 BEGIN
1db55b ····IDS_ENDVERIFIED ········"\r\n\r\n*** END PGP VERIFIED MESSAGE ***\r\n"
7be0d1 END
97af5a
e21b3a #endif ···// English (U.S.) resources
a16c0e /////////////////////////////////////////////////////////////////////////////
9eaf5a
13af5a
d2af5a
41ce8c #ifndef APSTUDIO_INVOKED
266c0e /////////////////////////////////////////////////////////////////////////////
de465d //
c98464 // Generated from the TEXTINCLUDE 3 resource.
2f465d //
e6af5a
36af5a
d96c0e /////////////////////////////////////////////////////////////////////////////
c88072 #endif ···// not APSTUDIO_INVOKED
50af5a
--b4d5 000a1089ab64011032b Page 1 of SigEvent.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
37af5a
27395c ¤   $Id: SigEvent.c,v 1.17.8.1 1998/11/12 03:14:13 heller Exp $
12af5a
3baf5a
aaaf5a
80f7f7 ____________________________________________________________________________*/
73af5a
067867 #define PGPExport __declspec( dllexport )
89af5a
4b5655 #include <windows.h>
8f3d0b #include <windowsx.h>
99feb2 #include <stdio.h>
86af5a
1da076 #include "pgpKeys.h"
71e2ff #include "pgpConfig.h"
6a2f8d #include "pgpErrors.h"
989f63 #include "pgpEncode.h"
1b4919 #include "pgpUtilities.h"
889de0 #include "..\include\PGPsc.h"
3ee82c #include "pgpPubTypes.h"
8aaf5a
29c4de void SigTimeToSystemTime (
33ba73 ¤   struct tm*¤ ptm,·
fe9924 ¤   SYSTEMTIME* pst)·
b0bb36 {
09f735 ¤   pst->wYear = ptm->tm_year + 1900;
f157bc ¤   pst->wMonth = ptm->tm_mon + 1;
87b44a ¤   pst->wDay = ptm->tm_mday;
fcb245 ¤   pst->wDayOfWeek = ptm->tm_wday;
cfa81f ¤   pst->wHour = ptm->tm_hour;
afa250 ¤   pst->wMinute = ptm->tm_min;
0d4165 ¤   pst->wSecond = ptm->tm_sec;
588d04 ¤   pst->wMilliseconds = 0;
67efe6 }
19af5a
452f90 void ConvertSigTimeToString (
ae770f ¤   ¤   PGPTime¤¤   Time,·
4df3b3 ¤   ¤   LPSTR¤  ¤   sz,·
6098a4 ¤   ¤   INT¤¤   ¤   iLen)·
a9bb36 {
a7b6f3 ¤   SYSTEMTIME¤ systemtime;
e00180 ¤   time_t¤ ¤   ttTime;
6936b2 ¤   struct tm*¤ ptm;
70af5a
bf780e ¤   ttTime = PGPGetStdTimeFromPGPTime (Time);
b5ff37 ¤   ptm = localtime (&ttTime);
30af5a
2c53bb ¤   SigTimeToSystemTime (ptm, &systemtime);
1fdb4c ¤   GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime,·
3301b5 ¤   ¤   NULL, sz, iLen);
857931 ¤   strcat(sz," ");
cd4d58 ¤   GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &systemtime,
d6067c ¤   ¤   NULL, &(sz[strlen(sz)]),iLen-strlen(sz));
70efe6 }
95af5a
814ebc BOOL SEGetKeyIDString(PGPKeyID KeyID, LPSTR sz, UINT u)·
6bbb36 {
b0af5a
b7df3c ¤   CHAR¤   ¤   szID[kPGPMaxKeyIDStringSize];
70af5a
77bbd6 ¤   if (u < 11) return FALSE;
78af5a
9df29a ¤   PGPGetKeyIDString (&KeyID, kPGPKeyIDString_Abbreviated, szID);
44c059 ¤   lstrcpy (sz, "0x");
d91e1e ¤   lstrcat (sz, &szID[2]);
a1af5a
--d180 000b36a64ef4011032b Page 2 of SigEvent.c
d6c2e7 ¤   return TRUE;
43efe6 }
7baf5a
c9c0fe // SigEvent
38465d //
c1c0ff // Call after kPGPEvent_SignatureEvent. Must link to PGPsc.
38465d //
aaf3b0 // Params:
d2e53e // ···d ·········Event data (cast)
eb65bd // ···fileName ··fileName (or application name)
9caf5a
38603b void SigEvent(HWND hwnd,PGPContextRef context,
3a63f5 ¤   ¤   ¤   ··PGPEventSignatureData *d,char *fileName)
c4bb36 {
092a38 ¤   DWORD Validity;
55184a ¤   PGPBoolean bAxiomatic,bKeyCanSign;
65abb0 ¤   char szMsgStr[500];
fe0032 ¤   BOOL bMarginalInvalid;
d0af5a
b869b7 ¤   bAxiomatic=FALSE;
03508d ¤   bKeyCanSign=TRUE;
a1af5a
728d4a ¤   // Icon information for PGPlog
bbaf5a
636c02 ¤   if(d->verified)
327afa ¤   ¤   strcpy(szMsgStr,"Good Signature\n");
5e0e24 ¤   else
f885f8 ¤   ¤   strcpy(szMsgStr,"Bad Signature\n");
e3af5a
14a84c ¤   // Filename (or Clipboard... or Eudora.. etc)
ca8167 ¤   sprintf(&(szMsgStr[strlen(szMsgStr)]),"%s\n",
80db6b ¤   ¤   JustFile(fileName));
dfaf5a
71106e ¤   // Get name and raw Validity number
e52bf9 ¤   if((d->signingKey)==0)
56c7a1 ¤   {
ee7a7f ¤   ¤   char keyidstr[11];
65af5a
1fee5d ¤   ¤   SEGetKeyIDString(d->signingKeyID,keyidstr,sizeof(keyidstr));
4d1b52 ¤   ¤
3a7a54 ¤   ¤   strcat(szMsgStr,"(Unknown, KeyID=");
a2d889 ¤   ¤   strcat(szMsgStr,keyidstr);
1fc5d6 ¤   ¤   strcat(szMsgStr,")\n");
71e8ff ¤   ¤   Validity=kPGPValidity_Unknown ;
959371 ¤   }
060e24 ¤   else
d3c7a1 ¤   {
da620d ¤   ¤   int namelen=kPGPMaxUserIDSize-1;
c87054 ¤   ¤   char name[kPGPMaxUserIDSize];
bfaf5a
f0587c ¤   ¤   PGPGetPrimaryUserIDNameBuffer( d->signingKey,
6fea28 ¤   ¤   ¤   sizeof( name ), name, &namelen );
35954e ¤   ¤   sprintf(&(szMsgStr[strlen(szMsgStr)]),"%s\n",name);
55af5a
232904 ¤   ¤   PGPGetKeyNumber(d->signingKey,kPGPKeyPropValidity,
f4fd62 ¤   ¤   ¤   &Validity);
abaf5a
8e27db ¤   ····PGPGetKeyBoolean (d->signingKey, kPGPKeyPropIsAxiomatic,·
c3a8ae ¤   ¤   ¤   &bAxiomatic);
7caf5a
a3d708 ¤   ····PGPGetKeyBoolean (d->signingKey, kPGPKeyPropIsSigningKey,·
eef831 ¤   ¤   ¤   &bKeyCanSign);
2b9371 ¤   }
0eaf5a
f8546c ¤   // Decode validity into string
25af5a
e45c1d ¤   if(bAxiomatic)
295127 ¤   ¤   strcat(szMsgStr,"Implicit Trust\n"); // Axiomatic
4ad448 ¤   else switch(Validity)
dcc7a1 ¤   {
98570b ¤   ¤   case kPGPValidity_Marginal :
b3d5df ¤   ¤   ¤   strcat(szMsgStr,"Marginal Key\n");
--8221 001605c06b74011032b Page 3 of SigEvent.c
7ecdcb ¤   ¤   ¤   break;
138716 ¤   ¤   case kPGPValidity_Complete :
31ab62 ¤   ¤   ¤   strcat(szMsgStr,"Valid Key\n");
8fcdcb ¤   ¤   ¤   break;
bf3a18 ¤   ¤   default :
739b84 ¤   ¤   ¤   strcat(szMsgStr,"Invalid Key\n");
adcdcb ¤   ¤   ¤   break;
a09371 ¤   }
c5af5a
262e49 ¤   // Output date and/or extra info
e1f053 ¤   if(!bKeyCanSign)
edd169 ¤   ¤   strcat(szMsgStr,"Signing algorithm not supported");
98b4b7 ¤   else if((d->verified==0)&&(d->signingKey!=0))
e66cdc ¤   ¤   strcat(szMsgStr,"Bad Signature\n");
cc0e24 ¤   else
15c7a1 ¤   {
48a680 /*¤ ¤   sprintf(&(szMsgStr[strlen(szMsgStr)]),·
0c1993 ¤   ¤   ¤   "%s", ctime((time_t *)&d->creationTime));
c5af5a
d29c00 ¤   ¤   // Get rid of ctime \n
896ff3 ¤   ¤   szMsgStr[strlen(szMsgStr)-1]=0;*/
3daf5a
6feadf ¤   ¤   GetMarginalInvalidPref(context,&bMarginalInvalid);
fcaf5a
a2c1d0 ¤   ¤   ConvertSigTimeToString (
313e22 ¤   ¤   ¤   d->creationTime,
a40173 ¤   ¤   ¤   &(szMsgStr[strlen(szMsgStr)]),
8c0ec5 ¤   ¤   ¤   500-strlen(szMsgStr));
daaf5a
83d2fb ¤   ¤   if(d->signingKey==0)
ce1438 ¤   ¤   ¤   strcat(szMsgStr," (Unknown Key)");
fcfca5 ¤   ¤   else if (d->keyRevoked)
33704b ¤   ¤   ¤   strcat(szMsgStr," (Revoked Key)");
e6ae65 ¤   ¤   else if (d->keyExpired)
a17967 ¤   ¤   ¤   strcat(szMsgStr," (Expired Key)");
4bae10 ¤   ¤   else if (d->keyDisabled)
69b3f9 ¤   ¤   ¤   strcat(szMsgStr," (Disabled Key)");
a1f6d1 ¤   ¤   else if((Validity==kPGPValidity_Unknown)||
f247aa ¤   ¤   ···(Validity==kPGPValidity_Invalid))
ccc2cb ¤   ¤   ¤   strcat(szMsgStr," (Invalid Key)");
b39844 ¤   ¤   else if((bMarginalInvalid)&&
8504fa ¤   ¤   ¤   (Validity==kPGPValidity_Marginal))
93c2cb ¤   ¤   ¤   strcat(szMsgStr," (Invalid Key)");
5a9371 ¤   }
972b85 ¤   ¤   ¤   ¤
81c03d ¤   // Send DDEML msg to PGPlog
cfac38 ¤   SendPGPlogMsg(hwnd,szMsgStr);
c1efe6 }
60af5a
317e4d /*__Editor_settings____
93af5a
f04126 ¤   Local Variables:
2a7b17 ¤   tab-width: 4
310e6c ¤   End:
385f8c ¤   vi: ts=4 sw=4
719e9b ¤   vim: si
60d062 _____________________*/
--2f80 00197a657cf4011032c Page 1 of SigEvent.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
8ba39d ¤   $Id: SigEvent.h,v 1.4.8.1 1998/11/12 03:14:14 heller Exp $
33f7f7 ____________________________________________________________________________*/
97a94d #ifndef Included_SIGEVENT_h¤/* [ */
a89c2e #define Included_SIGEVENT_h
38af5a
93af5a
4d3379 #ifdef __cplusplus
6c6dad extern "C" {
eac731 #endif¤ // __cplusplus
83af5a
1a603b void SigEvent(HWND hwnd,PGPContextRef context,
b8a061 ¤   ¤   ¤   ··PGPEventSignatureData *d,char *fileName);
59af5a
9d3379 #ifdef __cplusplus
d4efe6 }
2bc731 #endif¤ // __cplusplus
72af5a
ff93b7 #endif /* ] Included_SIGEVENT_h */
09af5a
baaf5a
4c7e4d /*__Editor_settings____
c6af5a
a24126 ¤   Local Variables:
f77b17 ¤   tab-width: 4
7e0e6c ¤   End:
d15f8c ¤   vi: ts=4 sw=4
b69e9b ¤   vim: si
97d062 _____________________*/
--3fa4 0005822779d4011032d Page 1 of VerificationBlock.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
01381e ¤   $Id: VerificationBlock.c,v 1.3.2.1.2.1 1998/11/12 03:14:15 heller Exp $
87f7f7 ____________________________________________________________________________*/
f8af5a
7b5655 #include <windows.h>
b93d0b #include <windowsx.h>
c8feb2 #include <stdio.h>
22af5a
61a076 #include "pgpKeys.h"
22e2ff #include "pgpConfig.h"
b72f8d #include "pgpErrors.h"
839f63 #include "pgpEncode.h"
2b4919 #include "pgpUtilities.h"
c2e82c #include "pgpPubTypes.h"
c70d08 #include "pgpMem.h"
7faf5a
44cc89 #include "Prefs.h"
b5ef45 #include "SharedStrings.h"
6caf5a
36af5a
7c836c static void StdTimeToSystemTime(struct tm *ptm, SYSTEMTIME *pst)·
a0bb36 {
0ef735 ¤   pst->wYear = ptm->tm_year + 1900;
e257bc ¤   pst->wMonth = ptm->tm_mon + 1;
8db44a ¤   pst->wDay = ptm->tm_mday;
a4b245 ¤   pst->wDayOfWeek = ptm->tm_wday;
faa81f ¤   pst->wHour = ptm->tm_hour;
c4a250 ¤   pst->wMinute = ptm->tm_min;
e84165 ¤   pst->wSecond = ptm->tm_sec;
688d04 ¤   pst->wMilliseconds = 0;
23efe6 }
eaaf5a
5faf5a
ce8e6e static void ConvertPGPTimeToString(PGPTime time,
6b77e5 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···char *dateString,·
18a11b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···PGPUInt32 dateStrLength,
68127e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···char *timeString,
ce05a6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ···PGPUInt32 timeStrLength)·
1abb36 {
79b6f3 ¤   SYSTEMTIME¤ systemtime;
ea0180 ¤   time_t¤ ¤   ttTime;
6636b2 ¤   struct tm*¤ ptm;
baaf5a
f72011 ¤   ttTime = PGPGetStdTimeFromPGPTime(time);
1b3b94 ¤   ptm = localtime(&ttTime);
ccaf5a
879beb ¤   StdTimeToSystemTime(ptm, &systemtime);
e6af5a
ecdb4c ¤   GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime,·
0ea0f0 ¤   ¤   NULL, dateString, dateStrLength);
95af5a
364d58 ¤   GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &systemtime,
0e3660 ¤   ¤   NULL, timeString, timeStrLength);
43af5a
d9830f ¤   return;
89efe6 }
98af5a
2daf5a
1adc72 static PGPBoolean GetKeyIDString(PGPKeyID keyID,·
7fd95c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char *idBuffer,·
8b9006 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPUInt32 bufferSize)·
33bb36 {
8daf5a
40a1d9 ¤   char tempBuffer[kPGPMaxKeyIDStringSize];
b2af5a
4a1286 ¤   if (bufferSize < 11) return FALSE;
58af5a
--92c7 000879bbb474011032d Page 2 of VerificationBlock.c
062656 ¤   PGPGetKeyIDString(&keyID, kPGPKeyIDString_Abbreviated, tempBuffer);
3f269f ¤   lstrcpy(idBuffer, "0x");
661018 ¤   lstrcat(idBuffer, &tempBuffer[2]);
bfaf5a
81c2e7 ¤   return TRUE;
acefe6 }
86af5a
b9af5a
18137e PGPError CreateVerificationBlock(HINSTANCE hInst,·
4ffc9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPContextRef context,
1a2bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPEventSignatureData *sigData,·
9883cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPBoolean wasEncrypted,
64b23c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char **blockBegin,
9be1fe ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char **blockEnd)
49bb36 {
706531 ¤   PGPUInt32 validity;
5a5a1c ¤   PGPBoolean isAxiomatic;
cfa89a ¤   PGPBoolean keyCanSign;
ad72aa ¤   PGPMemoryMgrRef memoryMgr;
9a61e8 ¤   char dateString[256];
ba8271 ¤   char timeString[256];
aca153 ¤   char tempString[256];
3dc55b ¤   PGPError err = kPGPError_NoErr;
c8af5a
317158 ¤   PGPValidatePtr(sigData);
e80d12 ¤   PGPValidatePtr(blockBegin);
59de82 ¤   PGPValidatePtr(blockEnd);
0aaf5a
04e73c ¤   isAxiomatic = FALSE;
18997d ¤   keyCanSign = TRUE;
18af5a
21cc3d ¤   memoryMgr = PGPGetContextMemoryMgr(context);
c9af5a
1fcb1e ¤   *blockBegin = (char *) PGPNewData(memoryMgr,
5abbca ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   1024,
e4e0c1 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
59da4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
d8de49 ¤   if (IsNull(*blockBegin))
464030 ¤   ¤   return kPGPError_OutOfMemory;
deaf5a
d6bc7a ¤   *blockEnd = (char *) PGPNewData(memoryMgr,
ea54b9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   1024,
b3e7fa ¤   ¤   ¤   ¤   ¤   ¤   ¤   kPGPMemoryMgrFlags_Clear);
08da4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
b03ad8 ¤   if (IsNull(*blockEnd))
7a4030 ¤   ¤   return kPGPError_OutOfMemory;
10af5a
96576e ¤   LoadString(hInst, IDS_SIGSTATUS, tempString, sizeof(tempString));
e6b180 ¤   strcat(*blockBegin, tempString);
0aaf5a
34fa69 ¤   if (sigData->signingKey != 0)
6c6ea6 ¤   ····PGPGetKeyBoolean(sigData->signingKey, kPGPKeyPropIsSigningKey,·
644b42 ¤   ¤   ¤   &keyCanSign);
c6af5a
fe76be ¤   if (!keyCanSign)
d48001 ¤   ¤   LoadString(hInst, IDS_ALGNOTSUPPORTED, tempString,·
ca01e1 ¤   ¤   ¤   sizeof(tempString));
aab2a4 ¤   else if (sigData->verified)
52baea ¤   ¤   LoadString(hInst, IDS_GOODSIG, tempString, sizeof(tempString));
ae0811 ¤   else if (sigData->signingKey == 0)
7bcd29 ¤   ¤   LoadString(hInst, IDS_UNKNOWNSIG, tempString, sizeof(tempString));
450e24 ¤   else
ec3e52 ¤   ¤   LoadString(hInst, IDS_BADSIG, tempString, sizeof(tempString));
b6af5a
77b180 ¤   strcat(*blockBegin, tempString);
37af5a
f7b10f ¤   LoadString(hInst, IDS_SIGNER, tempString, sizeof(tempString));
87b180 ¤   strcat(*blockBegin, tempString);
feaf5a
20106e ¤   // Get name and raw Validity number
56892d ¤   if (sigData->signingKey == 0)
87c7a1 ¤   {
--7e5b 000360b10fb4011032d Page 3 of VerificationBlock.c
d3c379 ¤   ¤   char keyIDStr[11];
e9af5a
176949 ¤   ¤   GetKeyIDString(sigData->signingKeyID, keyIDStr, sizeof(keyIDStr));
8d1b52 ¤   ¤
708818 ¤   ¤   LoadString(hInst, IDS_UNKNOWNSIGNER, tempString,·
6b01e1 ¤   ¤   ¤   sizeof(tempString));
92af5a
14b46d ¤   ¤   strcat(*blockBegin, tempString);
503140 ¤   ¤   strcat(*blockBegin, keyIDStr);
ee1d6d ¤   ¤   strcat(*blockBegin,"\r\n");
029371 ¤   }
ff0e24 ¤   else
75c7a1 ¤   {
4931d7 ¤   ¤   int nameLength = kPGPMaxUserIDSize-1;
1a7054 ¤   ¤   char name[kPGPMaxUserIDSize];
4daf5a
8860b8 ¤   ¤   PGPGetPrimaryUserIDNameBuffer(sigData->signingKey,
88416b ¤   ¤   ¤   sizeof(name), name, &nameLength);
baaf5a
0d9099 ¤   ¤   strcat(*blockBegin, name);
d0af5a
e0700b ¤   ¤   PGPGetKeyNumber(sigData->signingKey, kPGPKeyPropValidity,
3e1fe8 ¤   ¤   ¤   &validity);
4caf5a
eb62a7 ¤   ····PGPGetKeyBoolean(sigData->signingKey, kPGPKeyPropIsAxiomatic,·
809d5d ¤   ¤   ¤   &isAxiomatic);
8aaf5a
e97458 ¤   ¤   if (sigData->keyRevoked)
56b0d0 ¤   ¤   ¤   LoadString(hInst, IDS_REVOKEDKEY, tempString,·
2c3c89 ¤   ¤   ¤   ¤   sizeof(tempString));
1f6a39 ¤   ¤   else if (sigData->keyExpired)
2babc5 ¤   ¤   ¤   LoadString(hInst, IDS_EXPIREDKEY, tempString,·
163c89 ¤   ¤   ¤   ¤   sizeof(tempString));
de363d ¤   ¤   else if (sigData->keyDisabled)
a03dca ¤   ¤   ¤   LoadString(hInst, IDS_DISABLEDKEY, tempString,·
023c89 ¤   ¤   ¤   ¤   sizeof(tempString));
8c173d ¤   ¤   else if (!isAxiomatic)
1d5b34 ¤   ¤   {
95c548 ¤   ¤   ¤   if ((validity == kPGPValidity_Invalid) ||
b02ba0 ¤   ¤   ¤   ¤   ¤   ((validity == kPGPValidity_Marginal) &&·
b6a4f2 ¤   ¤   ¤   ¤   ¤   MarginalIsInvalid(memoryMgr)))
3ff776 ¤   ¤   ¤   {
c759e0 ¤   ¤   ¤   ¤   LoadString(hInst, IDS_INVALIDKEY, tempString,·
b53964 ¤   ¤   ¤   ¤   ¤   sizeof(tempString));
aea3a6 ¤   ¤   ¤   }
efbb8c ¤   ¤   ¤   else
dbc5d8 ¤   ¤   ¤   ¤   strcpy(tempString, "\r\n");
7c0fe4 ¤   ¤   }
c20e1d ¤   ¤   else
aa4dbe ¤   ¤   ¤   strcpy(tempString, "\r\n");
00af5a
08b46d ¤   ¤   strcat(*blockBegin, tempString);
ea9371 ¤   }
06af5a
fd8eb7 ¤   LoadString(hInst, IDS_SIGDATE, tempString, sizeof(tempString));
79b180 ¤   strcat(*blockBegin, tempString);
f3af5a
0ee7a6 ¤   ConvertPGPTimeToString(sigData->creationTime, dateString,·
fdec61 ¤   ¤   sizeof(dateString), timeString, sizeof(timeString));
41af5a
a238b1 ¤   strcat(*blockBegin, dateString);
7f7f25 ¤   strcat(*blockBegin, " ");
eef0f3 ¤   strcat(*blockBegin, timeString);
980210 ¤   strcat(*blockBegin, "\r\n");
8eaf5a
f7f037 ¤   LoadString(hInst, IDS_VERIFIED, tempString, sizeof(tempString));
2bb180 ¤   strcat(*blockBegin, tempString);
95af5a
e0feff ¤   ConvertPGPTimeToString(PGPGetTime(), dateString, sizeof(dateString),
5b1ccf ¤   ¤   timeString, sizeof(timeString));
1eaf5a
3638b1 ¤   strcat(*blockBegin, dateString);
--2c78 001afbfa62d4011032d Page 4 of VerificationBlock.c
ff7f25 ¤   strcat(*blockBegin, " ");
00f0f3 ¤   strcat(*blockBegin, timeString);
090210 ¤   strcat(*blockBegin, "\r\n");
d4af5a
fcfb00 ¤   if (wasEncrypted)
8ac7a1 ¤   {
4eab80 ¤   ¤   LoadString(hInst, IDS_BEGINDECRYPTED, tempString,·
1a01e1 ¤   ¤   ¤   sizeof(tempString));
82b46d ¤   ¤   strcat(*blockBegin, tempString);
ba37ac ¤   ¤   LoadString(hInst, IDS_ENDDECRYPTED, tempString,·
7f01e1 ¤   ¤   ¤   sizeof(tempString));
ec55a8 ¤   ¤   strcpy(*blockEnd, tempString);
4e9371 ¤   }
e90e24 ¤   else
b3c7a1 ¤   {
a0edad ¤   ¤   LoadString(hInst, IDS_BEGINVERIFIED, tempString,·
b301e1 ¤   ¤   ¤   sizeof(tempString));
51b46d ¤   ¤   strcat(*blockBegin, tempString);
1408b5 ¤   ¤   LoadString(hInst, IDS_ENDVERIFIED, tempString,·
0501e1 ¤   ¤   ¤   sizeof(tempString));
9455a8 ¤   ¤   strcpy(*blockEnd, tempString);
d89371 ¤   }
23af5a
e05ea8 ¤   return err;
1defe6 }
4eaf5a
867e4d /*__Editor_settings____
85af5a
a34126 ¤   Local Variables:
747b17 ¤   tab-width: 4
990e6c ¤   End:
fc5f8c ¤   vi: ts=4 sw=4
709e9b ¤   vim: si
afd062 _____________________*/
--44b4 0019bfa55c54011032e Page 1 of VerificationBlock.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
bfbd51 ¤   $Id: VerificationBlock.h,v 1.2.8.1 1998/11/12 03:14:15 heller Exp $
a3f7f7 ____________________________________________________________________________*/
c2c0e8 #ifndef Included_VerificationBlock_h¤   /* [ */
aeb707 #define Included_VerificationBlock_h
15af5a
b99f63 #include "pgpEncode.h"
61af5a
7f3379 #ifdef __cplusplus
136dad extern "C" {
a9c731 #endif¤ // __cplusplus
06af5a
c1137e PGPError CreateVerificationBlock(HINSTANCE hInst,·
fcfc9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPContextRef context,
5a2bd7 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPEventSignatureData *sigData,·
fa83cf ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·PGPBoolean wasEncrypted,
99b23c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char **blockBegin,
941e30 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ·char **blockEnd);
aaaf5a
053379 #ifdef __cplusplus
e9efe6 }
acc731 #endif¤ // __cplusplus
4caf5a
fab048 #endif /* ] Included_VerificationBlock_h */
b3af5a
63af5a
107e4d /*__Editor_settings____
1daf5a
424126 ¤   Local Variables:
627b17 ¤   tab-width: 4
a10e6c ¤   End:
575f8c ¤   vi: ts=4 sw=4
fe9e9b ¤   vim: si
9bd062 _____________________*/
--72f7 000cc3e38924011032f Page 1 of Working.c
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
e9a913 ¤   $Id: Working.c,v 1.2.8.1 1998/11/12 03:14:16 heller Exp $
a4f7f7 ____________________________________________________________________________*/
1daf5a
f29b16 // System Headers
c25655 #include <windows.h>
d33d0b #include <windowsx.h>
7ebb5f #include <assert.h>
ed11a9 #include <process.h>
35feb2 #include <stdio.h>
df90fb #include <commctrl.h>
ddaf5a
bbaf5a
335582 // PGPsdk Headers
dbe2ff #include "pgpConfig.h"
a7a076 #include "pgpKeys.h"
762f8d #include "pgpErrors.h"
74e60d #include "pgpWerr.h"
1b4919 #include "pgpUtilities.h"
f68e25 #include "pgpVersionHeader.h"
dcaf5a
0ee8e0 // Project Headers
47d092 #include "Working.h"
681a14 #include "WorkingResource.h"
f3af5a
966a8c typedef struct _wdplt
ecbb36 {
fd27b0 ¤   HWND hWorkingDlg;
7ed10d ¤   HWND hMod;
474cea ¤   HINSTANCE hInst;
bd6569 ¤   HWND hParent;
606296 ¤   HANDLE hSemaphore;
3aa6d7 ¤   char *Action;
b4f275 ¤   char *FileName;
1ffab4 ¤   BOOL CancelPending;
9bfe4e ¤   float LastUpdate;
037c3d }WDPLT;
54af5a
beaf5a
537cc6 #define PGPM_PROGRESS_UPDATE ·WM_USER + 100
314492 void WorkingDlgProcLaunchThread(void *Args);
3faf5a
75af5a
2f6ea8 BOOL CALLBACK WorkingDlgProc (HWND hDlg,·
106983 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··UINT uMsg,·
271eda ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··WPARAM wParam,
c8b79e ¤   ¤   ¤   ¤   ¤   ¤   ¤   ··LPARAM lParam)
c6bb36 {
d2447d ¤   BOOL ReturnCode = FALSE;
7c96ea ¤   WDPLT *pThreadArgs;
23af5a
d1e234 ¤   switch (uMsg)·
ecc7a1 ¤   {
08df25 ¤   ¤   case WM_INITDIALOG:
355b34 ¤   ¤   {
8559b9 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETRANGE, 0,·
aed5e1 ¤   ¤   ¤   ¤   MAKELPARAM(0, 100));
78f472 ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS, 0, 0);
f6ddfa ¤   ¤   ¤   if(lParam)
27f776 ¤   ¤   ¤   {
51a276 ¤   ¤   ¤   ¤   char Title[256];
faaf5a
54b945 ¤   ¤   ¤   ¤   SetWindowLong(hDlg, GWL_USERDATA, lParam);
32405c ¤   ¤   ¤   ¤   pThreadArgs = (WDPLT *) lParam;
78f4df ¤   ¤   ¤   ¤   pThreadArgs->CancelPending = FALSE;
63c544 ¤   ¤   ¤   ¤   if(pThreadArgs->Action)
cc72c3 ¤   ¤   ¤   ¤   {
--ffd0 000cffa51714011032f Page 2 of Working.c
18f2e7 ¤   ¤   ¤   ¤   ¤   pThreadArgs->LastUpdate = (float) 0.0;
09f5ee ¤   ¤   ¤   ¤   ¤   if(pThreadArgs->FileName)
f7f284 ¤   ¤   ¤   ¤   ¤   ¤   sprintf(Title,·
3bf8b0 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   "%s %s",·
7a3eef ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pThreadArgs->Action,·
d943a9 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pThreadArgs->FileName);
2b4bd6 ¤   ¤   ¤   ¤   ¤   else
bcd336 ¤   ¤   ¤   ¤   ¤   ¤   strcpy(Title, pThreadArgs->Action);
07da4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤
4c7061 ¤   ¤   ¤   ¤   ¤   SendMessage(hDlg, WM_SETTEXT, 0, (LPARAM) Title);
ec2613 ¤   ¤   ¤   ¤   }
99a3a6 ¤   ¤   ¤   }
989aad ¤   ¤   ¤   SetFocus(hDlg);
c9add3 ¤   ¤   ¤   SetActiveWindow(hDlg);
ddcdcb ¤   ¤   ¤   break;
a10fe4 ¤   ¤   }
cfaf5a
123962 ¤   ¤   case PGPM_PROGRESS_UPDATE:
c25b34 ¤   ¤   {
988891 ¤   ¤   ¤   char foo[1024];
4643a0 ¤   ¤   ¤   char szTransfer[256];
8ce25c ¤   ¤   ¤   int PercentComplete = 0;
3047ec ¤   ¤   ¤   float ftot, fsofar;
0baf5a
d2b758 ¤   ¤   ¤   if((pThreadArgs = (WDPLT *) GetWindowLong(hDlg, GWL_USERDATA)))
7df776 ¤   ¤   ¤   {
aeede4 ¤   ¤   ¤   ¤   if(!pThreadArgs->CancelPending)
af72c3 ¤   ¤   ¤   ¤   {
971a2f ¤   ¤   ¤   ¤   ¤   if ((wParam != (WPARAM) lParam) &&
7c059f ¤   ¤   ¤   ¤   ¤   ¤   (wParam > 0) &&
df818d ¤   ¤   ¤   ¤   ¤   ¤   (lParam > 0))
e34859 ¤   ¤   ¤   ¤   ¤   {
22ffb7 ¤   ¤   ¤   ¤   ¤   ¤   fsofar = (float) wParam;
784e7d ¤   ¤   ¤   ¤   ¤   ¤   ftot = (float) lParam;
69ca4d ¤   ¤   ¤   ¤   ¤   ¤   PercentComplete = (int) ((fsofar / ftot) * 100.0);
a8af5a
f988b1 ¤   ¤   ¤   ¤   ¤   ¤   fsofar /= 1024;
0f2ce5 ¤   ¤   ¤   ¤   ¤   ¤   ftot /= 1024;
43af5a
cad8b9 ¤   ¤   ¤   ¤   ¤   ¤   if(!pThreadArgs->LastUpdate ||·
6f2a38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pThreadArgs->LastUpdate + 10 < fsofar)
cf8fec ¤   ¤   ¤   ¤   ¤   ¤   {
515ed6 ¤   ¤   ¤   ¤   ¤   ¤   ¤   pThreadArgs->LastUpdate = fsofar;
821297 ¤   ¤   ¤   ¤   ¤   ¤   ¤   sprintf(foo, "%.0fk of %.0fk (%d%%)",fsofar, ftot,·
beeb9c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   PercentComplete);
b45885 ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetDlgItemText(hDlg, IDC_PROGRESS_TEXT, foo);
37db3c ¤   ¤   ¤   ¤   ¤   ¤   }
f5ad2f ¤   ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS,·
5867f2 ¤   ¤   ¤   ¤   ¤   ¤   ¤   PercentComplete, 0);
b61c89 ¤   ¤   ¤   ¤   ¤   }
435c09 ¤   ¤   ¤   ¤   ¤   else if (wParam == (WPARAM) lParam)
ea4859 ¤   ¤   ¤   ¤   ¤   {
ddc1d6 ¤   ¤   ¤   ¤   ¤   ¤   LoadString(pThreadArgs->hInst, IDS_WORKINGTRANSFER,
440b4b ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTransfer, sizeof(szTransfer));
fbad2f ¤   ¤   ¤   ¤   ¤   ¤   SendDlgItemMessage (hDlg, IDC_PROGRESS, PBM_SETPOS,·
6b7381 ¤   ¤   ¤   ¤   ¤   ¤   ¤   100, 0);
61a1c9 ¤   ¤   ¤   ¤   ¤   ¤   if(pThreadArgs && pThreadArgs->FileName)
64527e ¤   ¤   ¤   ¤   ¤   ¤   ¤   SetDlgItemText(hDlg, IDC_PROGRESS_TEXT,·
709b68 ¤   ¤   ¤   ¤   ¤   ¤   ¤   szTransfer);
211c89 ¤   ¤   ¤   ¤   ¤   }
2f2613 ¤   ¤   ¤   ¤   }
22fa07 ¤   ¤   ¤   ¤   else
0572c3 ¤   ¤   ¤   ¤   {
cfdd07 ¤   ¤   ¤   ¤   ¤   EndDialog(hDlg, 0);
972613 ¤   ¤   ¤   ¤   }
bb8c70 ¤   ¤   ¤   ¤   ReturnCode = TRUE;
8ba3a6 ¤   ¤   ¤   }
87cdcb ¤   ¤   ¤   break;
bb0fe4 ¤   ¤   }
9baf5a
e22c97 ¤   ¤   case WM_CLOSE:
cf38e5 /*
--d151 0004d42a2984011032f Page 3 of Working.c
69d725 ¤   ¤   case WM_QUIT:
c2dad9 ¤   ¤   case WM_DESTROY:
7a7fe0 */
b85b34 ¤   ¤   {
13b758 ¤   ¤   ¤   if((pThreadArgs = (WDPLT *) GetWindowLong(hDlg, GWL_USERDATA)))
9df776 ¤   ¤   ¤   {
2dc544 ¤   ¤   ¤   ¤   if(pThreadArgs->Action)
85667a ¤   ¤   ¤   ¤   ¤   free(pThreadArgs->Action);
f22b85 ¤   ¤   ¤   ¤
6ecc2b ¤   ¤   ¤   ¤   if(pThreadArgs->FileName)
85668f ¤   ¤   ¤   ¤   ¤   free(pThreadArgs->FileName);
9aaf5a
8a62ff ¤   ¤   ¤   ¤   free(pThreadArgs);
2024d9 ¤   ¤   ¤   ¤   pThreadArgs = NULL;
44a3a6 ¤   ¤   ¤   }
ab2b85 ¤   ¤   ¤   ¤
ee93ae ¤   ¤   ¤   EndDialog(hDlg, 0);
55000f ¤   ¤   ¤   ReturnCode = TRUE;
dbcdcb ¤   ¤   ¤   break;
8c0fe4 ¤   ¤   }
12af5a
998e1e ¤   ¤   case WM_COMMAND:
7f5b34 ¤   ¤   {
07256f ¤   ¤   ¤   switch(LOWORD (wParam))·
33f776 ¤   ¤   ¤   {
478722 ¤   ¤   ¤   ¤   case IDCANCEL:
6172c3 ¤   ¤   ¤   ¤   {
1aa801 ¤   ¤   ¤   ¤   ¤   if((pThreadArgs = (WDPLT *) GetWindowLong(hDlg,·
288a4c ¤   ¤   ¤   ¤   ¤   ¤   GWL_USERDATA)))
669eef ¤   ¤   ¤   ¤   ¤   ¤   pThreadArgs->CancelPending = TRUE;
904bd6 ¤   ¤   ¤   ¤   ¤   else
99d153 ¤   ¤   ¤   ¤   ¤   ¤   EndDialog (hDlg, 0);
d7af5a
a7cd83 ¤   ¤   ¤   ¤   ¤   ReturnCode = TRUE;
ab14c3 ¤   ¤   ¤   ¤   ¤   break;
6c2613 ¤   ¤   ¤   ¤   }
e8a3a6 ¤   ¤   ¤   }
e0000f ¤   ¤   ¤   ReturnCode = TRUE;
5bcdcb ¤   ¤   ¤   break;
ea0fe4 ¤   ¤   }
da9371 ¤   }
76481b ¤   return (ReturnCode);
bcefe6 }
ecaf5a
88af5a
64bf56 //----------------------------------------------------|
7155dc // Callback routine to be called by Encryption/Decryption/Signing·
ecaf5a
ac3f0e int WorkingCallback (void* arg, INT SoFar, INT Total)·
88bb36 {
a8cd79 ¤   int CancelHit = FALSE;
ece650 ¤   int ReturnCode = 0;
ac96ea ¤   WDPLT *pThreadArgs;
86af5a
5f058f ¤   if(arg)
59c7a1 ¤   {
a7a75c ¤   ¤   SendMessage((HWND) arg, PGPM_PROGRESS_UPDATE, SoFar, Total);
ceaf5a
57a98d ¤   ¤   if((pThreadArgs = (WDPLT *) GetWindowLong((HWND) arg, GWL_USERDATA)))
4877a3 ¤   ¤   ¤   CancelHit = pThreadArgs->CancelPending;
729371 ¤   }
a9af5a
b3c880 ¤   if(CancelHit)
90c7a1 ¤   {
53468e ¤   ¤   ReturnCode = kPGPError_UserAbort;
f19371 ¤   }
07af5a
cdb09a ¤   return(ReturnCode);
00efe6 }
8baf5a
819636 HWND WorkingDlgProcThread(HMODULE hMod,·
4d22ac ¤   ¤   ¤   ¤   ¤   ¤   ··HINSTANCE hInst,
--d97e 000d1bdc21c4011032f Page 4 of Working.c
f29c00 ¤   ¤   ¤   ¤   ¤   ¤   ··HWND hParent,
a25fbe ¤   ¤   ¤   ¤   ¤   ¤   ··char *Action,
0c18d7 ¤   ¤   ¤   ¤   ¤   ¤   ··char *FileName)
40bb36 {
5d96ea ¤   WDPLT *pThreadArgs;
91af5a
92b095 ¤   pThreadArgs = (WDPLT *) calloc(sizeof(WDPLT), 1);
6caf5a
96c3a5 ¤   pThreadArgs->hWorkingDlg = NULL;
0eaf5a
343369 ¤   if((pThreadArgs->hSemaphore = CreateSemaphore(NULL, 0, 1, NULL)))
81c7a1 ¤   {
e5a9b1 ¤   ¤   pThreadArgs->hMod = hMod;
b7d919 ¤   ¤   pThreadArgs->hInst = hInst;
61b239 ¤   ¤   pThreadArgs->hParent = hParent;
86af5a
6470a7 ¤   ¤   if(Action)
e55b34 ¤   ¤   {
dc96df ¤   ¤   ¤   if((pThreadArgs->Action = (char *) malloc(sizeof(char) *·
9602e8 ¤   ¤   ¤   ¤   (strlen(Action) + 1))))
d6738d ¤   ¤   ¤   ¤   strcpy(pThreadArgs->Action, Action);
6e0fe4 ¤   ¤   }
fe0e1d ¤   ¤   else
cb46f6 ¤   ¤   ¤   pThreadArgs->Action = NULL;
adaf5a
76edfc ¤   ¤   if(FileName)
8e5b34 ¤   ¤   {
7ce930 ¤   ¤   ¤   if((pThreadArgs->FileName = (char *) malloc(sizeof(char) *·
e41c8e ¤   ¤   ¤   ¤   (strlen(FileName) + 1))))
1772ea ¤   ¤   ¤   ¤   strcpy(pThreadArgs->FileName, FileName);
6b0fe4 ¤   ¤   }
6d0e1d ¤   ¤   else
ff5b34 ¤   ¤   {
3552c3 ¤   ¤   ¤   pThreadArgs->FileName = NULL;
9f0fe4 ¤   ¤   }
53af5a
5738e5 /*
ef7e79 ¤   ¤   _beginthread(WorkingDlgProcLaunchThread, 0x8000, (void *)&ThreadArgs);
16af5a
ce7c8a ¤   ¤   WaitForSingleObject(pThreadArgs->hSemaphore, INFINITE);
617fe0 */
679a07 ¤   pThreadArgs->hWorkingDlg = CreateDialogParam(pThreadArgs->hMod,·
e9ea38 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_WORKING),·
d4423a ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   pThreadArgs->hParent,
32740c ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DLGPROC) WorkingDlgProc,
45cbde ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) pThreadArgs);
049371 ¤   }
8daf5a
b53bc4 ¤   return(pThreadArgs->hWorkingDlg);
79efe6 }
39af5a
1b8626 void WorkingDlgProcLaunchThread(void *Args)
29bb36 {
3845bb ¤   WDPLT tArgs;
600cf8 ¤   MSG msg;
daaf5a
4ff4ff ¤   tArgs = *((WDPLT *) Args);
2baf5a
f57f81 ¤   tArgs.hWorkingDlg = CreateDialogParam(¤ tArgs.hMod,·
d1a4e3 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   MAKEINTRESOURCE(IDD_WORKING),·
55f6ed ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   tArgs.hParent,
b93f36 ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (DLGPROC) WorkingDlgProc,
42145d ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   ¤   (LPARAM) &tArgs);
adaf5a
b5f02c ¤   ((WDPLT *) Args)->hWorkingDlg = tArgs.hWorkingDlg;
03af5a
1bcc4f ¤   ReleaseSemaphore(tArgs.hSemaphore, 1, NULL);
55af5a
fdc167 ¤   while (GetMessage(&msg, NULL, (UINT)NULL, (UINT)NULL))
d13b37 ····{
b08dc3 ¤   ¤   if (msg.hwnd == NULL)¤  // if thread message
d15b34 ¤   ¤   {
--da5f 00112e05f844011032f Page 5 of Working.c
cf219a ¤   ¤   ¤   // send message to main window
ee0b94 ¤   ¤   ¤   PostMessage(tArgs.hWorkingDlg, msg.message,·
9af0e4 ¤   ¤   ¤   ¤   msg.wParam, msg.lParam);
720fe4 ¤   ¤   }
4e0e1d ¤   ¤   else
915b34 ¤   ¤   {
50286e ¤   ¤   ¤   if (IsDialogMessage(tArgs.hWorkingDlg, &msg))
cdf776 ¤   ¤   ¤   {
2934a5 ¤   ¤   ¤   ¤   ;
49a3a6 ¤   ¤   ¤   }
f8bb8c ¤   ¤   ¤   else
06f776 ¤   ¤   ¤   {
5678f7 ¤   ¤   ¤   ¤   TranslateMessage(&msg);
6cbc08 ¤   ¤   ¤   ¤   DispatchMessage(&msg);
47a3a6 ¤   ¤   ¤   }
3d0fe4 ¤   ¤   }
426fe7 ····}
f2af5a
748025 ¤   if(tArgs.Action)
e22033 ¤   ¤   free(tArgs.Action);
79af5a
e0a50f ¤   if(tArgs.FileName)
99d0c3 ¤   ¤   free(tArgs.FileName);
9aaf5a
886b4d ¤   _endthread();
deefe6 }
57af5a
12af5a
--9e2a 00183d2c18740110330 Page 1 of Working.h
a70335 /*____________________________________________________________________________
d4c97d ¤   Copyright (C) 1997 Network Associates, Inc. and its affiliates.
374b0f ¤   All rights reserved.
3b67c5 ¤
ea67c5 ¤
adaf5a
ca4a97 ¤   $Id: Working.h,v 1.2.8.1 1998/11/12 03:14:16 heller Exp $
2ef7f7 ____________________________________________________________________________*/
d8089c #ifndef Included_Working_h¤ /* [ */
aca2ef #define Included_Working_h
dbaf5a
845655 #include <windows.h>
93af5a
263379 #ifdef __cplusplus
b56dad extern "C" {
147454 #endif
33af5a
927177 BOOL CALLBACK WorkingDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam,
bcef26 ¤   ¤   ¤   ¤   ¤   ¤   ¤   LPARAM lParam);
b3ec1d int WorkingCallback (void* arg, INT SoFar, INT Total) ;
049636 HWND WorkingDlgProcThread(HMODULE hMod,·
4d22ac ¤   ¤   ¤   ¤   ¤   ¤   ··HINSTANCE hInst,
359c00 ¤   ¤   ¤   ¤   ¤   ¤   ··HWND hParent,
555fbe ¤   ¤   ¤   ¤   ¤   ¤   ··char *Action,
57a20a ¤   ¤   ¤   ¤   ¤   ¤   ··char *FileName);
e2af5a
583379 #ifdef __cplusplus
e7efe6 }
ea7454 #endif
63af5a
e865e8 #endif /* ] Included_Working_h */
24af5a
99af5a
947e4d /*__Editor_settings____
69af5a
a24126 ¤   Local Variables:
9c7b17 ¤   tab-width: 4
830e6c ¤   End:
9e5f8c ¤   vi: ts=4 sw=4
659e9b ¤   vim: si
83d062 _____________________*/
--05ca 000620ba9d240110331 Page 1 of Working.rc
ab0f59 //Microsoft Developer Studio generated resource script.
d4465d //
181a14 #include "WorkingResource.h"
3faf5a
d7e1bf #define APSTUDIO_READONLY_SYMBOLS
a36c0e /////////////////////////////////////////////////////////////////////////////
31465d //
5d0131 // Generated from the TEXTINCLUDE 2 resource.
5d465d //
ec897a #include "afxres.h"
a6af5a
996c0e /////////////////////////////////////////////////////////////////////////////
6d7b93 #undef APSTUDIO_READONLY_SYMBOLS
dcaf5a
ad6c0e /////////////////////////////////////////////////////////////////////////////
b2f930 // English (U.S.) resources
e1af5a
eb1201 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
bfec08 #ifdef _WIN32
e6e912 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
089c1c #pragma code_page(1252)
271f8e #endif //_WIN32
6aaf5a
01f860 #ifdef APSTUDIO_INVOKED
da6c0e /////////////////////////////////////////////////////////////////////////////
31465d //
1d5733 // TEXTINCLUDE
1c465d //
b5af5a
8686ef 1 TEXTINCLUDE DISCARDABLE·
8e4523 BEGIN
700c30 ····"WorkingResource.h\0"
f8e0d1 END
3caf5a
1c7037 2 TEXTINCLUDE DISCARDABLE·
134523 BEGIN
c6eb23 ····"#include ""afxres.h""\r\n"
36db5c ····"\0"
44e0d1 END
ccaf5a
03227f 3 TEXTINCLUDE DISCARDABLE·
dd4523 BEGIN
17e851 ····"\r\n"
badb5c ····"\0"
0ae0d1 END
75af5a
6a69ab #endif ···// APSTUDIO_INVOKED
e1af5a
7eaf5a
916c0e /////////////////////////////////////////////////////////////////////////////
45465d //
40b090 // Dialog
fb465d //
fbaf5a
7ed0e5 IDD_WORKING DIALOG DISCARDABLE ·0, 0, 184, 58
bb4925 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |·
eef85b ····WS_SYSMENU
37f150 CAPTION "Working"
f4309f FONT 8, "MS Sans Serif"
284523 BEGIN
244462 ····PUSHBUTTON ·····"Cancel",IDCANCEL,67,38,50,14
87c96c ····CONTROL ········"Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
823ee2 ····················10,22,164,10
8ac471 ····CTEXT ··········"Preparing data...",IDC_PROGRESS_TEXT,7,6,170,10
dce0d1 END
30af5a
a5af5a
136c0e /////////////////////////////////////////////////////////////////////////////
bf465d //
7f6077 // DESIGNINFO
d6465d //
62af5a
--e126 001b09ab4e740110331 Page 2 of Working.rc
43f860 #ifdef APSTUDIO_INVOKED
de70e4 GUIDELINES DESIGNINFO DISCARDABLE·
6c4523 BEGIN
f1f8ad ····IDD_WORKING, DIALOG
c85574 ····BEGIN
f2c975 ········LEFTMARGIN, 7
a1b94c ········RIGHTMARGIN, 177
b29e31 ········TOPMARGIN, 6
84bcde ········BOTTOMMARGIN, 51
107d01 ····END
42e0d1 END
5f69ab #endif ···// APSTUDIO_INVOKED
55af5a
86af5a
036c0e /////////////////////////////////////////////////////////////////////////////
01465d //
7b5e87 // String Table
08465d //
82af5a
c96f6c STRINGTABLE DISCARDABLE·
b14523 BEGIN
d6077d ····IDS_WORKINGENCRYPT ·····"PGP Encrypting"
3e6a33 ····IDS_WORKINGSIGN ········"PGP Signing"
026976 ····IDS_WORKINGENCRYPTSIGN ·"PGP Encrypting and Signing"
f99cea ····IDS_WORKINGDECRYPT ·····"Decoding data"
b5b78c ····IDS_WORKINGTRANSFER ····"Transferring data..."
a2e0d1 END
5caf5a
321b3a #endif ···// English (U.S.) resources
2f6c0e /////////////////////////////////////////////////////////////////////////////
c8af5a
40af5a
08af5a
f8ce8c #ifndef APSTUDIO_INVOKED
806c0e /////////////////////////////////////////////////////////////////////////////
f8465d //
e58464 // Generated from the TEXTINCLUDE 3 resource.
ca465d //
68af5a
59af5a
1f6c0e /////////////////////////////////////////////////////////////////////////////
4a8072 #endif ···// not APSTUDIO_INVOKED
b0af5a
--5988 001b10677a440110332 Page 1 of WorkingResource.h
739d39 //{{NO_DEPENDENCIES}}
6bc31e // Microsoft Developer Studio generated include file.
8dd862 // Used by Working.rc
db465d //
14fc0f #define IDS_WORKINGENCRYPT ·············9701
b0b06f #define IDS_WORKINGSIGN ················9702
703857 #define IDS_WORKINGENCRYPTSIGN ·········9703
3760b2 #define IDS_WORKINGDECRYPT ·············9704
14d031 #define IDS_WORKINGTRANSFER ············9705
f17862 #define IDD_WORKING ····················9991
07ef1c #define IDC_PROGRESS ···················9992
ec107e #define IDC_PROGRESS_TEXT ··············9993
6faf5a
b811aa // Next default values for new objects
8dac6a //·
f1f860 #ifdef APSTUDIO_INVOKED
883f23 #ifndef APSTUDIO_READONLY_SYMBOLS
1db0ab #define _APS_NEXT_RESOURCE_VALUE ·······101
32611c #define _APS_NEXT_COMMAND_VALUE ········40001
5df6ec #define _APS_NEXT_CONTROL_VALUE ········1000
9c1285 #define _APS_NEXT_SYMED_VALUE ··········101
3e7454 #endif
b17454 #endif
-AWJtZ 000b1a3b3b000110333 Page 1 of binaries1.zip
=/$uB\ WE5DBBRAAkAIAPNXdTYq$ATGd45HAD?#C\A!AAAAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&S9
YEnZ\F a*M9TY=$et>Wd$N!iZB$d!=\bGd5@ZheW$pZQ+/HAAFCRk%IW$NwIaTRCpEBR\5hR1>mA1H*yqmZ*pGc
!Rc4#u mIkc1uRSEBFS/TJNRES5LF%ESG^a%@&B1@65aV@8<*\?j@#??Py4J9jP9i<:b</ePTVuuH6Gn1bHXebl
aEe<cT <FC=&dudh/BkHB\LD*L#lYyw\KE1NkiDQiA1NIcZ^<aJnSH1ESkP^/q6*GG%eY:qESaWEi48ERdHEd<%
AQNq?* /RaFlt@e5>FC?N+TGlT5E^RJh+cVmHA%HJ^EW69+WIj9lWP%6PBRn$Dtbtj+Q*c16*E#:m6e^eHSCS+a
+^ZAD% +i?@Aed>h9BuHPFHPCJbdT5e<We+kmy=K^#yl:m6/XV>I$+*%IMS:lMW1MeI>+An>Zdl%NZJPB\Pm%Mq
Ac$iTA +wkE^R%Gl\a^I>\>R8FIF+Kc/pbSe<Fm5h1dqj6tFdybBY%Ydy5Xa:MK*/#kt=Zib8Y#YaZ>j5EF?4ZB
Sl>?pn @@jK+@jujMWRNm9MbwZh4HC@Z@D<9c9@*P\C6j?>m<DNm9u:VRi?h45^BB8jeQ?N\jpElweGah!Ck9\W
1QBJ5S 9+$:cGNW%FBGkIeb\&>nlCRMCaM*^iEaG>jNkyld5ERXn%Z<I!9XjnRF@/u?QAjp@^Yw@l@k6\ZlaPHt
J4D5Zm /?EiDqi^nuAL@>ymFLC=SqVMN\c&iaKD1>n:MMP>+cyE8I1ll+?Zh#ken+i4/QmEl>E<RuYDAwKDAneZ
uacjRa E@u4w9EQC4WPb4l:\HHa*&k!>Rn$?wct?9mHd#BK^hVJZ5@DQanyAh<pLT^<k=pBWHAWD+6GqlYFe5Zy
ak\\^H MGk6VNZ6@Eq/dydpWn9qdYqWh<8Y?j&cP#MNtXd15uqtC4uGHqbZtM%:XjJNQc*XT\<BwiCNIZ=:%LjB
WQWPpQ j1Xk<<B=k#KnRKbHyAeV41Lu5h@H*eQKRAiPJ=HkPQJ9m*99:!Dej<<m@HeYden<:##C+apd*Y:ByV<^
4A#pC< Cj<uJlEJYLWj5kpAkAMA*CAPaHVW&q@ayN<B!BjnkQGC&LZd%/L$bIZ@\1aJX^k+Qtat15>dFeJH$!&c
V:WBVD jl?qk^D5>dFy>XA>5$&IS/?VRYbbkWVAQXH>$%mu:h6AQZN5/XyDZp%PHt#cteQq<lJR!l\>TT?RLJYS
>&%c>\ GA/aZuLl*RG+&ZT1iS5$5h9NR/A>*?bwEP#+VDiRl*5H@#cBb=jcZ\1pWGYPB?#TqD<ybmn:<JbiT/ba
QZi/>A QkiRQdtpAA4abc/RC=bVFn%>>Ed!ANn6<EFcNS:P4/QQcQFZXc=LNX/IhtSGy/#5Q&\%GYq/1d5!d<A!
<9im!? t\*R5qiKQZXeaL4yS99:I&+khtld6#9at6LBFnli<+ECqZDFR/wnB\uyEAwX1WKu:?LiHb\t&+X\N^!<
HyBp#= uK:4MFKiHwMMb*GbwNpFL:eLwC?uq\SQ@eIHZy4q$e6K\b@m$!&a&5XZ$mnAHZ?e9m4YGR1J!$N$6d?/
KSaST@ jF^*EqcikH4RIqKJ!!%6=GijuhI/*9Y^RF4Vq#6+1n?MX/!A4^5+Sep$yWRJ^QhQP+pal1ZJy/X#TGHQ
>tpTTl k#1+!T\8yt#Qupwt$qSZ+Bp&eH8F>KmAJE$wB/KZ&N+BY^Fp$ujXedpJR*:JKk%PRkm86ERcCppuuXLj
W9%/M? dW!dwGV4Fa#5mLikl^wYF<pFPP?SVp4n9Jd#<AEw946I1n$%%:eRpNmFdS>NkIi&dlQmLwL6B8u&nbPE
D8WpqJ Tm5itAnN6\hKb5&86jEVkwQ4SaWSDTIW?hJS6Nq^>!MI>1V=MF@PPJ@<KZQlp1i1q?P/Z&yNeNC#KDRa
k#ttyZ \n9lT\Yd6+RwVCiX^$c84$ZiM1=H6tp5t:&%%Y1R8^KGT+p6B+nu>1nVElLpDFu<5TMjY/ZnICJymTh$
lc?Pp^ ii#5%DwBejIZatQ!:PL1WXNtGjSl8+RpNkFRt>WLlk5TdIu\*A&P^9dd>#H1Y^&Ww1aD8/L$$%SKauy!
Bd5+S? ljK+ydtD*%aZZ=HC8KW=wS^@ZmmC9Rjp/u!$XC^yu#Cle>#*BSRnABA>LpV4??&ed5<B?1Ih&I@P%/YZ
XL##KP G9k1yL*l=+F8b#lLe69HbCXBkA<M%\#P48qV:CalRm/#$iL+88nmb#DwNn%XkG!/?$hZPIC^F%QHZub@
Nlw#hn t*S^&Y!=E$YGjt+j:?QR5>B6bc+b?$K+M/pC$aE^MiSWZCbTD8W^V+XuLV>%$c>b?BD>e>!qWFqXadl9
l^HmAK K%>WP6=6?<u*DL@$eb/waFqSjnwct5m5TBQN\CbI=Lm^>QnQneZ\D4i?S4lJXTb1i/byC=k4Fei@F\$G
8::\eS KD5A85ZP#!i#\i*C\dM1FPu*qet$qdV+hu9N1JhW$SAcLtG*AV@&TLJY6^bN@\FRH5lhtbdEdh^Ph9Vu
/d4uSK nDTNCt5GWE$AWNb+QmAEQ^n%TAKl@ca!mXnPQb6>tLMaQy1M&>ZPZyTN$Mblwy8APBpWk^6\:TW9q/^*
$WpGcm n%RpmmEZtTWwi6LN!FhimF8:?=WVat:GSSRA=YFL=8CJt##Hb1YlI6J^RC\yPTm6N*NQek^iiMeydY=G
Cem$hV @Sn+QLhN>/Tm8J/Yduee<EaH5WRb:p&HuABVkSwIJJAtL$ElmlYRV^:4^89iY5w%tShIn1Em>cMF=HGq
J<a\>J akMF#D:D/8=%+Sm\EJ@F5IMm\kdSKc+NR=&^!XLu=E4Fk9naZNSma1d++>QRmHcS8cl&mkAWHqpad?yy
HVIu&J \aJ<Tbt8E^J+M:%:&p^D8F&NT+ey!hPd^lQ9$K4LhQGMGmE4^R#KEh$19EVZQAph$4!kVu^+45B?/BLD
S9Incq VB/H4RKH\ddymEHQ^DVd^#BmpA<h?:c^Pi\w^daVFdGne9BJd1lMmamyJT\l*qRdNl&DyE!VyT5Ke1C:
GcmuZ< XQYY&F=Bema4E$i1hHZIbbcepR1FkCdu*lJJSVeBQ4aS5G+W:TTh*WbDa6T1#!I1I44HqN+XK9ctIEpK
VD*W%t Bp<=Je^tmRFF%YJueC!XGAhkpZaRj*SjHn5DDkPkM*Bn:i4b>SDMp/WhHQLdjcB?*PkWPn5TwbGWGIXy
</P5K= b#MM>aut=tIVpwXF\eu5dnR8+E64\<4Me<y#Au/bM/KCFT?%&e=@Hp8QtXJ^elVn=mYD>w\lWMK+wFN/
@/H9=@ !1T+i@%/\GpXH6cXFqYBXYTh6ktdLd\!iebX6%PEt!&t+*aJ*p*Cw#&lRY>T<G+WtV5=CmcJu^dt4B?D
/k=FyC Jum:X89XEKFFYAG&HiIehEyAa5Rlhl&mHR+AwJ!nI$$+wuda6+eH8mE<>ZWnH!59G/dFh:c\?%&#W8+^
45NiyY bdBSC6HKL!GCPu$Y!b$IDl$pJkH\hA>5=mKG:dTG>LV?eeZEGmjh?$F<ailWD1Y!DENY#$**TDn*cLP8
/+bKAq 4tGJkM!SFB:&e!b%L$$FhcM8J#6//4an#VTnD4yq8ZtCL4C1&YWuZh\Q/=n&bJ+Yp@dttat^W8yCh9N\
Z8&D45 DP&An^\kyXEihMVCVuI!H>m#DaVLP:=*#Z5b9e@\8m6:@uRcKMS9k/h&EkZ6KZHB1leT5m^/>W*^ChpI
?tREXG CQbN%eX+X9A%qmt8T/5JWXANF\$\qu?X6R*E9<V/iT!jZE<@l1BAMXH6cuT?y$RyV\yW&A^5n>XP=9ET
juknCS eBNn:D@dVqjC\T%qVtByCn!S%BR/XqSaCA9XHa@hq4/T55^Tn\B:D/Le*yVF\TQCW!Ly*uPb!i!V%@jl
ZhFw88 jL!A:ywR<KNYi&$&e$F48DDR/tT$VThYpYY%IIIdePBEa:tP!AVucChItpSGuYc&GG4V:XQVpPh9$uP:
P&LHSX w6@6RyuTByVuPIJ#AP:SWdN:*E1b4k/+R9YpCw4C8^Yb*NElnP1wCbk#iL5wk^nJ<hkL\VC\mGw@t&5e
N<?$T9 teIy%&cqy!M4IGew%d?khPEEd6mcdWcdT!/jy!^RXN@t+py/+ZnBc5MW4taGC@AIy?bujPSJpHZB5w:W
bT@$TB ed=8&MWd&T!9k$cInNT#bW8ddJi:4mPwLYPmHX/n/MaK!*8ba9WSK&WZu^<lj@Vw5?nR/%q!b>Wt4Nji
mkWcBj Zi8V/ydDS8T6YVA8YjC@>>C\#%<#ljTKm@K?TN4?:u1WYS#6BKWhpA?baA1j9JY\@dTaMP>M4yqPqDLj
QqdeyE L1tXh*915Lj!KdKe\j\hiT8KWYNRuTtJn5=nM/Xq6@MWA=b#&B:e%=EF\66+lq8XqX^!iE\S:VXB:W:m
JS>!kG ^YQdXqnCM?MIdV&qwpjqCC!dh66V?n8&#l&ADmtl1BlmhL@!GkdBwlwN#b1!%\5<A\p#@HQeuKBS5@a*
!A!:FW \:E9yFB$V!tA:^M*K=:wHh\XwuJSeM:kat!>==hbZ^EFeq$6nnMtn%$iAF!i>+umVkC$QRJm64@wL8*R
h@Yiu@ AuCbT5j:A@\@>ltbe5?+5CXFKkdZjRJmPSmQqFnuPDwLShk!Q*S+D<TI<eSRpQAhm8&G+p5N*nMRmXEp
MYmP$n j^SkG\LPA#kmAbe1c:>ik<D^B#ZI5HEuW5mmAt/j=kTk<!5w?lEJPweem/:N&kYYkapWneAG>*?e/h<8
8^#=Me QT:Z:55J!N+BpNJtPRqt%1AaECE*j&nt1qK$\K?#k^#S5%ea/eJAKT/Y1&dWcYCIFEA:XI^BBJl#I\BI
nt<yWJ V8p&&DRj6#STM$ym$k*VmBFVyFCmebRBHw\+JE&/QZ>m:5G=iRA@t@?XanER?w$F9a+DkRHwkaWbcay$
cW\!GQ eC6<q:TiQF>6tnD>QTVGkWP8V/t>\T&1C5k/Jleh:M&XihCNCau@AkwqaqtH>I6d^P9d$B$LmPq8KX%=
@<We#^ $J\9N<PK#Cc@4TkQwhimpy!EKD1Ga4ShSiAj#/?D&a>6i\dm/MniEWCVypM+kK$<bSQEcHu?Y!9<BqkE
?AZj$= QLAI9EeEkRA!bHMkp+yS^bHVBd>&!$9I6NQl//<R6Ica>?\?p#4\mi\bwMAmTnBnB%JcWpVHT6S:nS?d
1Z#X>q L^>XYnK\95y8ClWcR>HNlTl5WpZ\Z?qm5I84!wDM:8J!5ikqBPYG&BlAiqySGY=PmmpW:G#NL+tC<1hw
kR:lEH TN6Iq%@ZVMITm+/q=in\FTN+w1Xtb69tEV6tKia<\EHZ#tmb?ZpwY&BNqKpp\tdnc&IS\EtT:1@DCBRi
8DZLDF #lPQeSGp&!pX$b<CdaDSy5KMR:9lP=S1C4VkRmjb<1WHXX9lbMGZHPkP&>&y*PJQIh:AGFE?d?FyV>F8
q6l=FE P*T:u1<$leI&jbJ6YjyJ$u6EFHePZBq\T$mqV54*8nT4ScS4p56m9/S&59V5KGW&CkS/y8%Y91Qa!a^i
GmAHtm :@/Ky1MML?$+^A>$+w$KQh1iAcWjEa&V$a5Tb=Pb$RiacSjDRi*^*G+^I1QV!4Jw:^t6!#w:iGXdih9V
kt^c+9 AJl^bcIli>SBdS8^<PuY!y6bt5Xn%eq$&DlLt8W9GW*up6dYikPJuN+S!MyVu5qLbYZA=MY+6J>n&B8w
#k!6aL =Sqm$Q+Whm=5X/PJ#JTY#TKK*5$V/mqNQ!VI<%HC6F&bI+*PJnVZdYA\MpIeBmnQ6Eu1ILqa<Gm8ZlHC
IDeh9> L5Z=KnykeLX4H5dX@a5<pp%tPbNSF/unCykGZ+%yE*!^6F8&Q>YC/Jdn\ld>TC>/tnt/X&AYCcT\Y8Fm
ZG+8IM 9P%$IuPb#yc>jb=N*S15F\$VG^TDWAmW<$JknJ6K%Dpn6<FM&VwJtXplbDldepyYJ+&npTZCAP!aNyRH
YW$J!1 RAC=kd*VP!yKt4I:y+R:%5\yeTEh>IQMW1nKCwyS8BQij5=GTpl/S$!@XmqmSCRbI#!iyNd*\eSYR55$
5cGy+P aVn8k6Bw9@R$Xd\?tD%KFPA&IyWt^nH>TK%D>HYWPDBm8nMKL*B^9=m$KR<*a9iJX*^INBhhc=6\A$=:
-Aj*$N 0006675d7bf00110333 Page 2 of binaries1.zip
u<WwmJ CCX6B:IY^bt>aa?Y/6cZEJ$=Wqw<JeHt9SQ\1^6RjJ?$m#bLnM$*TZFciI<FqqXCBdZd5EYF><pHA1dH
4>P8j% 6k6M%EeNTpw9m>V*a8k^9HDXyGp!#\BF5h?\6KP?DDHCt&dDPT9yPi5tSBja^l45mLaVl!>KT8hBV9kD
<%ASc* /j:R1ByPymS5=lEH$XY?Q+QPB8mi1?eYqYj9nyJVubJt4WqJ#\yb:n@ju5*LpBZ4tN:B8<4NJw*%qPB6
AMj@4C V?WL?FLWYT/<4wXwL>cp%^=We\ZM8G/LQmRlYpMH9PE:WC<S9TbGd+FSyGB1:h^SnIBPNBSnmKLujkTi
ZlY?T+ %ACR\RLdR&JlklT<XNR!LDwP&AH5mCtHFnXAaN++/XBaApD!>ySPXCTZ6p5l58nkLB+ahR^e%C$ldd:V
iTLemd EmuS$T?iB%L5pL>kbmaJ^I9I^TyFm5jSadBiAQA8FnH6J6KlGGi@:bkaHh68BF:!nZJnk4WXCTiC+k/+
4FFX#m :9RETAAEEC\>N91=k=PSunM\TZtA?B$@JMWPBH6pG8ti+8aQVCqHMVJGa=^EyE5jK@?T>M+XGJ%Cb&NH
j1A<QN 1:aKQ4F*Iuip8<Gl6!iF/eQT4CI5@TK/W!+qj\*debLIZ!i1a\Z\i<MLNE>68Z>\lq<6BZ5umw?Du6Kn
pL+lda E<X:X!G#bRLItJ#Gbp4YyHG#/SH$#qt&9M/bA?@aX5ZSjqiG\kjIdGcQQ8D>\n4d@1!kJXl=tpdKmjKp
dVN\mu PA&4:$&Qlu$wulKHC\Gt:\5Z^!6eEM<XV=PuIN&BW&I#k$CG6G!u:5GYdTjJ+tpG^$TL8nq5+P^SwR8P
h9L1?? qhu$^>t*/GLSVC:+4n%Fi!Z9<8S@tJV4pBhniZ?<lh%GAjQCC>tL!qRP*5mt6?@$tD4jeTiLAbip::V=
i*$+4d <C=y?k8wCABm^NwAScFJl<?$!8IAc>6t6IVFuXpjTYePKbTWkPH\4T\*?H>l8XH@1?ZtD^dW:\aXApH>
auJ>dK l@aWmJ+AW4B9GMwypAypP!l%Hpkw:Pc\/pb\?AnwkE1$Aa@e%Lj^WYucyeFP1lJ<HF\!cQkRN:tu6Jk6
E86y?K dpRdiaI/X!LP*WhZFSAd1w<?KQ5RmJCe+SRdD@bZF?NNpQGB>?%FmcbShZESREhM9tu%ma6yaD>T4V%T
$w<%HM 8Klm$l@VjH8JmLYFQeALYQu5F:DJtCBYR:kEyQMjBYLEDFA!l*8P\P\FJI6ED#bJCB+VwC=*1a6Fic6q
#$MANY RwNE^E*4uMAua!yQQnn4ccDbCRtiP\T+#N6+\ii6LKJMII$RuRR8!M1ePK^c<DL!R*S=!w#N#F=<np5>
?P+etE !6eG%<u4F5QVa1W5#wnu!ApbtR>/pcEQ$1%MY@J=\*6$:\88yCXFMdAt=%mSp4!AEmw#>FSKnE\VnN5>
EJk#%T =:w+F^9qFbu9iPw+IX+/>VYuym:*NJEV!=TC*Vm?BpNebqq6cau:p=GcFl4pd8$SDuiG1>D$1HAXG+@I
PP*wHF <G<&Nh%9u$cdhp5XcqBkPH^#N1pEPI:$hdw*b?=*k>#tyW$D=Y?T<NWRl<Q>=#d>!HAD/@BNM?#tnRdY
JMc5Nu PDlP>V>Z@&CF&:!58*u=t<qT%=4+*VK*ii5j:Ke+$6>hCq?ylQ:HPLnbm66w?M$/8EH/BmYBG&LuE?kF
e^cTAl ^^NWTh?<CV1MMI?9WBXDD@@>H8E?:w\@h/Z/>/:?M/KN@4Vluk#@5M%DC>49l+a&t?9Ep^HlH@:uy/q6
=+pwC: :R5J&#k#<YGG@Y=D^9@GA?J9H/VjGpt@<a*<Y!Q8t$eES@m6GWj/4S&KJ@+&E*8@5nhm$<GC@a?#lcD&
QQ$wFA #bH!S:L?aMu?jb%1Y?5cGbFJ*>d1>/Y54w:@$:1X*9mu8FE5ehI!NBh%JS5#E#>ycaTB5a!h?&+uLN%i
iwbGX: #q=c&m>RZ5ubey<*&h$G:a%S^cpV=Et?<uc:6X%>ZKBkkl:KMAKn:1Jm1lulEYSJDmC=8yGDbDHc8wbE
wn#41a ZX?!9+/BQCZWN!!MKtinbdHdRBG^l+4!SkabPqqaiFBCeDlqKJmKhnRMwLqTnNZNXS^55Zb1CITb5%+\
S9cbL! CWH**!P46%FytNID=je^9i$5jhR<=XSe%V#qI$mY*ubYcNyG6a<BBj8b/<u/BcI</c1BKC<bclnbZqu/
wuj*?D 9/1k+Q<i<@<>+9>:^Q@@Q8Ka%qb@SNV@9c:a$FS@%BZG8<!^CKN\FN*EWmqe$eRNK?hQhNL*5mA+1PAh
ce:G4< 9W&5TVKKlu5mFM!5WTc:pS5WwAPDZRmPKB?4Qi1KhJKJ4R\W:MSR>hX$NKCE?>mTEhy?FF6ZjXpqYWWD
B^dd5# QW$ha&ehQSWDG$XLE!8DwNBRjFBkmKNJ5FQ\H1R=atQJ/:99DVeNeaiCZdTeKIw&Iha1D45NAw!DycXD
T@m*EP R#ZpQS!>CFmQEIQhZp+aLY6jj=1hjKmh?^/uII1h1@G?IAYhMCeW^Y!*qm4Sh$QhKIWbE:*M#D^&ai^5
JQ5eXB yW&IZ8G8i&&DpIw8NmES5nw?:p^5!C=:5&Cppw\m^5*N#q@bIMSSGc%45qjZ#>jHP%ScT\MKb1J5HA**
%1YupH Yd1TVZV<>yE>bK#$\wp18*!$FS\<ZjaFBnB%DDEBT5GtXl//G6JPi^Ep51%VlE/EkuKk4It@pTa=%BkK
*Qn+!k *1hFCJaQyJJCQPn?G46MDaI%LS^hbEN>:F&e9dWXk=#^TFWVNR<tW<+$#BTBM6!D%DVDW^RWpawWV:Tm
ZcpC!$ 5T>JCR1&5ePEWYkwbh6\yJtSeamDChqp6+IBVe=DG&Gn+?=4mhd%DWT=8/ycYckd+iT<hZB&i/RhEQ:Y
+/+ZJw DH?%QhcclmkFKBl44B?wJ^5t1+eq/Kk4wtYJ/k:K8+pEu#$pB#W4LSp%/dB\hY<=G&$G*y&w1/Sly/81
dGy\N6 +G<WlGd+&DpawJ!<FT&kaF5duFcRt&jk:u&iFP5AhY<:YS8!5/8=Qe%bX!:emwCVCa@\<@EtGmHySD^i
4?K+V# eS>K\<MCHWR^a#KwY4w$W4m#G^S5:ttC>qC%NTN/!>1wB<4TcWFiL9=aXcQhd8ElJBLcX6M^&CeId/Y4
SY>^?= E1^uS4eP*&*l/dw4TJ=1bLLZ*=G!T<MGDRXd8H8El@m:BDQ*lmAe:H#*cM1yYG49n4DG:FIl$4S\/F*B
>XBy6A qpTWq4QZZphpwDcNIcN14pqT%HHXe5cblSL*$ND/WDAt%GcQQn1a+dMHwd:Z#$@JQeVDcGMyPYA$>\bm
QR$p+= ZhX\Pm=pp4RiSpjiiJh88GY+1d#?d9e>>nnZEFiVAHpT&6EdCqbAK<wyGVwddH!NW6Q^y/ma1hA$TSyi
5/Fw%J +Z6^ZpRFJ6uQdK<ltin51W5qGu9=Me#^XFNqNb!KL$bn4:<DTmaw%A+KN9QBl?MMk$*qGLytXu6%<aw&
=enuGh ^8HW*a/l1l4/BDtqQR:GhqSVbqka!5BX!Wlqq@HiaLRQ^n&Cal!mdY&5d1ann+PC6RM<Ehdc%nJWV%$<
SWa9pV LyV5ywj#\?m:Y?K<XIQDyc$$FDS$qA<hP4Tqj5Bn@+h\n&>jaj+R:pEk@VneR$Xuw=XA@Q=q=+@SH:m@
VE:&Jj 88c@jcH/n&>iXX%>K>e<H9>nyP1YETB+\w?S^K&S^B<n<X5nTV>Ep5mELbG1Q$RT%EqdI6X?nMS8*Tj=
4lXH4E l$n<Q*BI@ahIuQ4Y<V#aH!QX6pd?YIb\lC%qmQBnGj1u!BDCu+VI/P69wt?SL#1KZ*<\Wd>L@J>kj=Ik
9Ei>qk G#nli:AW:Z9ZG/66k\=%LJ!5Bmh6CDq8a+q5LmE:PQFd:IYK?i?Hj*\!/i<@=$qEM8tH9?eFW1JGcG%y
a@XA:8 1kIRQW=hwpAwSk4K\e/hH:NVMFY*X$acMPqQ&kbJECk8c8cB=ZL#WTPq8i9l&:L/k$9WB!u/cKPiL4cw
G1?@A* KXH*GNEiDy#lQC$IqtwAnI&iZ#ATT?5BbStP$:!I&^XqyC9/cC=%ED@*pCmYt:yWm9>5hFV#5L1WZY?8
Wy@QmD Y\TM=qGdwtSVyD%XbFWKwZctHG$6>d6mu$T/1nl<N@dtQ5X6Zh84&u!\W$<QSAee*l+D+%X!h:ww?>lb
TR:KXG LAX@<TLq1wEh>uVcma8Z<m46c4*^M6LZIVGiBAt#W?uD@P18>=@5d>1X\M<i1#18hBPcZD1RXjc55XXd
ymJmYe t&QT@+FNmp&B/>RF^%hkZM>aEewej6uRj<:BWTlCS5ymCSF#and6yqy1/+w/Z+el<<KiD6*5c6J6>$ie
<15JPK mLVq@iKkyM!KV#w<p@R+eAwAXkRG:tKNy:Bb/#&9h&9Iq5C5IN%FCe5NqcJ+Z+L=AydSpN%^canP&H/y
ZX4EGR yy+t#wpN=Wb^Y4T1@1L:DP5t&6:9NQ%eKSZJk6Z:K@XjR6j8T15FtSt9Xc1n=n$\uII6#IWL9ypnX<p#
GNdNk6 JXcwKuBVY?YR5P<LjEKAajp8Ayda@Vkl8nYDkDFSE4&MGp=!%+W$nK?J%hV8lYA:L9n>#ANma\X@:u^q
*CVPWL w</9J/!uh=qV/By!yDya$=1I9en59eAZ!*4X1?lGuqJ4Dn@1MH!*m>6cqLmeJtI*e6i1@@\kXkV1NLG!
6:yH%^ ^HC=F+!9^di4Y9PInIW\\cI>iRLM5wam*#L9W8P><cJ<=45h><eV5ePZTKlT%:it+IcZ8w+=IuQ8p/JH
jRP6RR Q<IkGDQyu%yX9V9XeY!yXw>4*a<KDF>K4ZCP9d@i<CpR?q=TaDnBN&jd+a^kaI%c&wFLZa\LDujZ*^K6
Z4AaT4 mQD*IJZM$I<&&Q:IDN$LD<%C:+&XuGT+94aG+VqZ#1S%D9t*9uNZa>SCitycVuNXw\K*^%%G6^+1dRPl
nRj#8h ZQ1QZ<p9#4kS#=ePIT5TY+5\XYuQQb19tY&HEIi$T$Kc#N:1bplY*Tu8X&#!#d65&&^Yd6Gpyt#?mhV8
e5tMMj eK%=RYt\Fq1G$1*K&i$*MdWK1/qbkQSNQlCB9YlPeRcP9!+^$L@%6P%5F>9?A/h*Z&*<^ZQ$Z8Z:QZIZ
kb<SCX t!YQnN%j6NJhFiQC8<Z6cuw%cMCGL6qXPhwHHXDdbtw>:*D6\:*4+Aw:t+m8FW=&%?KH?#:m!==^Tm:j
VKE8PN i:yc>&DA6cdtNPl8V?Fa&>K#5*FniiJ?4?nH5<nZt1JPD?NC1V^5u+C^:T<!m>EB1eyQ<wZ!yGCy6+?t
q#=<&! 5mSq>KK/S$1iKi549+QS?#>LMB+yQu9$4JRd?\ZPE*8MY<ShK6l@Pb96tHe>wE%d=%HZGQCW>yKi8DRS
t>CJFE hhTXVDlwZFatMu9Y/5HBp<tXbSYFe/Xkcdc\KQtLc1i>1#/dMcKXB5&8=e&&:W5NC\VJPY:VB9k/:y6l
1GujIl ?ZtIl:Q4kldVuywRq8AZP&Tnh\nT*eKC!eR/t\qHZehC4B?4Ac5#dl94*l\1tH^jLdL+p*6!JnFki==l
JQHe6j Sj8C6yFJiyt=N9D8t$^JCZTRABKtRJ*QNCdEebcJw>m6$tA!y=XJ&RhJXK5Yiqh\SA/<&Kw@&Pq%!bm?
ET#Kl& 6iuk?*LSICH^MSP9T1KElIKuaZVelCL>WRMmuI??YEW^VKI%5me*khp1!CD4R&w^!b$4HT\51EJeFBHG
bmK9KG 6T9XhQ=M@AtG*NnKKjQ=F+4$WdB=?ALbnm%Yk:QXXn+iHbYTjRC9jC^KldZtQtRh4kG8&bXIYuFpFQYY
AXkS!a iPV^Tb#mTFXEZemaTet1JKG<l\^NE1QK\p:4GRHEHH$hu$=B11eZ?aap>>I5tlbbCmubX6=G?&aE1tKm
!k^XqP WpWGHct<<W<N^LA6aLPTh!Wk$X$W$GT6APG6e?4RE^N%KWnKmZ$XYYWcMB?I9je6Fmyi+yLYI4@\CV?*
!>P^?S qLYtLM95D?Cb:In<*FE&8ARd*jKT/wqLIn51/PiX#a#GKdh4<AYSLJiW9Ztek4QZ:#1D:5$aYaEcHZZq
buJ@a: ^ciKW8GEM\tqc#DjJ!:tiLZ#h^M//*q?EpZLSjp@m&+cLN*^5n!FbbP+Q$%56qT5Z+j6y!ScNchP>4&B
-AiDcV 000076c96ba00110333 Page 3 of binaries1.zip
JC4VcF m!h1SY41EL%Wi1et^WH+FeBbadHc?WFk%m1%TaSiiNQ@6HKdbT$d#PPWuypE?5wAmYP$Shm=#nnlT5AT
y<#>V6 nPMYKB?G=#WpLN9BnD<YL/RB4k\AKnq5W&^n6:@kBD>&X?&?jm$n%BipL<qBYec&ViAMWR+tpG&qQ^>t
j5ea1! >=?/$KT5ZMBdFw+&Y&t=%@^R9$\Aew>^EQ1EYyJJeaII*CG*?D8GNB<J*Z@jF^%WE>>*IZm?ID4c1mPR
l^kT=K M1^!TQVF!Y6>8L^%??LR+XTXN\h91W/8QFwL61!!>c^M#i?I5^W%VMpJ5dkaJXYR%=#9B^#Db8\ELNk+
CD*$dA Hy8Q<GipNJZkbMRVMRjQitSL<H6X#A=%WK&nmjm$QQ8hYVbPCVdLLe<>%m!#IA?uXT^bhe/6H/*u6hNR
NEdb:P @Yn^ybw*:p$BS@EZm5K<QL/+Qq5>hp\^dm#*6JDHh1C&Y:\KBT$H1Z*=dNhBRR!H6%Dy=eu>btPmSy:Z
BMLH\q du=?#em+Kl6SPQ+RpjaLt//SISRH#S%RA1m^4#*5ecu\55yu:T*W@Gulm5wJuyaP>1nk/Ke#8pTi>=>&
JN??@c ^pEjkq+E9FkeZqtQ?SKV?uNE+PQ:%^AeN^8>Jh^A%YQmpcw6IQ/XT=n6Nb@W<8d4WSL*Qa<&N8=L=JnF
*mtc#6 Ph/9TI#wL1GP8qDLkaH*6uXuBbNhY^@Dh%\=Ga^up?p#iP:c++FcdEc+Q/#DH<JTq1/qkVwe!k+>S:/:
9+B!u9 uD\*E#njL/$dHu>=*/GC!MVuE/ESGV%Nl*td@VHKXaYV$LL5ddVliIidhw1*:yG&N#EP&8i+FB=ZFXXu
pj8c*^ iani8dCu>\qYTCnKFKat<M1t:=C^dqEWZ/dpt=c8i1hIhY^p>B8$6\>QT1J<=@EJDXWSqWt:+*=hA=JZ
AYFLn8 MQ9+jl&ml/qIK4AY^E:KDb/=4Cb*CHNFuCS?Rjb=RKG^!/&DB^eSdaeu>aNL/Je>u%XBn/$bkStjh@Xj
c1c6q@ KH*ZH==q4NVp?^kbeL>GNYDw+j8lJ^!&l^a=\YePq^$I9Pd&8cjVI/$l:u/a<M<1d*bZ=nap*NL\mjKj
i$ABMZ GJk<Yi$j!/L^/I!@+W?/h@ML8yTXP@B^\AjbtIV=1DLy+V6Iyp#!K$+md\F!Zl^^iPG6+LEntd:1&45i
5<9AZ: !4Xnh<Lp8KIi=ia:V9d^pwFi/Q\+KQDB6SE/<6p/q4:W@cI9<%u\4jnyeZpK%njZwThFQ%=kyJTFdL@E
#9=k!G k!n>yZ>pYKpZY8@$%5j<1WwHn/iVWk<\XIB=SaY8H%h^I/$V/=9@RJ/KG1u\Ni>L/i9FhLi:i<SWq5%\
GSB&Xm #?b@bke9K<Ch%&18^S@tHQA@W>MW!pY$Dj/ww6iLwm#i=#6Y!ShVaJJkumlRWcZFChdSL^tn<P&*>jC@
AQqSHq cJJNRqL<w\4&9eT:qEHMu4taeT/?tjP?t6^*n^QeEm@&$@Pj8KuW^M/<$5Xl^#Lbe?:=46NVmtXj+4&$
HH@Y/m ^4JeK>KZA@WlcIA9tnyQRp!BhB+>LS+^wM:4^*+Tb>:e^5$8&Dpj?8#5bhB<leXhphR?e=N6w9M9lPY8
5IJ?X= H%wP%:VEt:JdqTqD:1PQ>TFQ\y=<DFV?mDGiMQGTjY:TWl5ZiC6>F=hTVatXXJEMD=^9l/*u^+du4mV8
kuGkA< !Z9t*LjKJy&jG>@V#aEMQdm8/\MQ:D/WkEVhV4l%P@V1T9id</l:+QuA8ECZdI:?Xju*R4w!/j6:cdIi
c#uPdq CjIP\$TXt9j:ihJp#c:j5>LIH/\JnMp<Q1Rw!?tEMnJ&/Bp=c&y/=SuL!W\k%M1iujMI^Q?pWtntL+HI
N&\AqW iGXVhAPDQ=k1/$Hh+!GR!Pj>8F+D$&9cF89kaVG5WH<hhjQSM@qPSR@SB@KVAaPycJ&:/FkHHkGlMcXC
t$tppd =iCKk/DqjV*9K?k4H9M8!kL9<GWFYDl66p<a4q!%&Hthp:?>?<pEZ\/aE^DBSZe%6HaqSd%RhZh^INlB
dlpYZI qEyD?6jLa>w+B$aec!kpky6Tj>%uIXFcb%Kwbe1?FWYM^&pX/=lch+jZmFwJ\XJVSCucNEWb+G5M#EQQ
H\Gl9K F*MCRpHQnlm?qNYqS4dRK$Ki!/PXp6AZEwa>p@RVwpZeYP>q4H=Jtu!D+TQBu&uJYBqHicy%WcQ:SZ@l
EyAtEK C:ZkK6bpl>\Lun=\ZpcP&#e\F@=AIK%hmZ8*V18mF@i%SNik^jWHC1:F#=imEC&$*u1!kc89kybJ+*J$
W5WIJH ?#Ip$VWTyQyMy#!miD/6LP$ni@M5YmeAXB@T=L9jm!<tCS+5@HE@\Q<&eV@=bjE9/BR>w!ANFt!Jk*lR
a*9Jyq 5S^y:nbnAyyKEy$%tJ=uy!F:BMa4JPaN/@p1:KKGbi@Z/iA!1D<6%mtd:D>e<!YT&l^u+Bpwh!StcFHb
t?V#wC 9ip5akD*InKK#\1ZaY>iHZ#A\M9EG#SZY&1/QLqkAy4wKeDLyQ&c=VS@ZKe8JZRqpKk$@6qMj@XwpwpX
aWE6Pn MaFE@H\pRR9>%md&6iGD<ejEYNPbwZbIBjali*b<StpW<JJ!^WS!5IAna1X!nuIuTAuh++I6N*@YP&pR
5wm>EW b@i+9Z^p<Iqw68G5dSw&=QP%8D4p*RbPL8=?m?IZA9+9FS*inl::Cj9?JbMn^>mR/B&<P8i6%NXdGDZF
&4=VE6 4HSk?p%@%l%V+T1<\H4mW1+N+i6pAc<=8>MhW%\9ZDB?>&Kp*Gw=Lm=8BSqu:b$!==*llanH4e6yq&TA
1+cuY+ jLJZS@Iuyqhh4JYAwu8AyR*RF%yYRV6WVu^8Hp^J=:mNNI5Jii:pWVinRlC/^$VS8Y^c4ea@<$Q*Z1Dd
YRHkD* bZc?nAYeQK@q!?NREkJ5Ydnmmitp<P?nV+TQV^^:+=dStA8/LNmZ&I&5L4PD44d=JDY6&wE%MR5ihjQ1
nC&m#9 mL^uQZEwG::l\Lb%t\whih>V9eG/k85KGRqGDjjpc&+y=I%EDb=RM8t:qb%\n#I@\5qha@wtdy9aRCn1
uXWLd> QTK9w&9M6E^#i*NaEFR^iA$^cCW:EZyRG4jh/A=HaDaWPSb=#\#k#=ju$1e9>S^wj+<uLCcQJ&&iBH?I
dtJkR\ 5Jea6\@uBNRy8cXN*uQl5$wN#p:aC@BDCVpM$J<jKBXBWieXA+!51IRRtidd1E?lL:!E=QTT>\Qh4YbQ
+?HnQl YmX4!E*VSwc^aV8Rh&l6tWDuC*TW@Y%CL?muSMk?6ciEY+j1pj9%lV=YHHi$a6<QG5hbNIdP81Z@yH@t
tI<>m5 YJMyKI9hbEpZH!qY:=aHyi/LD9E?GlRYw&6:VMdh1:HEjRHK<Xccc@&\@<kT^uah!*jPTp#W+>&DP+6L
c%t@I< hkhG?F+jI<pI*EjEMbtMI:ZGHmSymKKFuJkTD/K6&anm&PJ4j@EYQ8>w@Cy@DKI$uc8*+5AJDjKyqEp8
Ea%TH# qiZdmEtqiB6=ytCP$EL/5WYmuj!am&GSml%H</J\C6XXnX#?JcApQnQm$P1NFMy5Y=CJb$*w>RRBn+XW
ch$My/ C+jXK+S*^@Pj^%Eha!?QHqQ49Q^/YCEP*iK=B8p>katW1KhiSk\XR&YA%>q#VRJeVEeH??awlP!MXEe%
G/&^PY 1Y=F:n99nkiX?@mtlPeCqj!D^=TjS/Z&khb1p\?T9Eyhhwq4cM1E=c6$:YhPVMa<#*t^1G:yuP\bqR%#
4Ilh*t C*4#X5pjZp<bkh:m#b@>RFut6lA:YTBiXaLX#K>qq^@ai!JZc9F=5iLd/GBEQE#P*9H6HeSB$LqVc!8*
nGdVuR uTC1!@8/G^p/^%qSV!C95*aED5Y=P#!*eKZq4q=khS$eQdS9*V1>L9Yaeaj4Lei$nIbcIi:uHQE8Gceh
1\!QVW <^>Ri5/8P5#^mbyb4L6TQ81<tm\+^qw+^@j=h5S>V>YLAhVu*86yKtMQ=4^QW9&+wR1:e/pn$HGH#&w4
l$Y>PG H+uB6wA:qe\B&?eq?p64qqePSW\@C18<=nhd<j^<aKVC^^CbZFVuL%yhJ*SWlt<p#Rde@EVX/a&Wi/F#
nDJ\Dm L%C%@d=lW&8SYc^S9/pln^kJudV9yy!l8X5mVFIHyKWYc<Y6aCVq<CwA61@/+@JJb<=pkYt9D+jhKp?=
NRyS!b LYnaePCER1iML1ZS^w*p>H@>Cb!aDaZ!P>!KmZ^BS\jc=SuVI$&#iyK>1kApiim&FZmak&Vt^PGM!ehH
mGWP9q ^YdMM+MPnA+WH#1WTW84=VK+QIpnLH5S#jiqlV?NZT<n%Nj9Y%b>tYDj9JDt$6AHmnS*#u::W/a>%@nV
C:mV+a dMj\jciL44d5wCXCQE:^e^mhDKIGBJY<c+:@<6\An*p+9ViTK$Q!&ZX4XY#c@w4DW=HYJWtVP!<4lZB?
1iqQ&j 8mVq>qcF<4Cb>jT1FJiXFPcm</pCdLWTiiBKP+&d?4SX<u*A*jHhAd^HBpTc/JbNdj^bBkyt?WyJIMAN
@DAMQ6 +$RXl/51X16<?e%>Le>dL1BSSt$bA/KJpiCjL4@*iJJ<^Kk+tjp44w#hk=Md&b=5D\/>F9P8Gn#w#@ZF
#XJpD6 ZZ/ly^/imtlDHqeBeu*Icd6lutS@?5mDWJ:J6Ch^bp@&!QeQccc<%P&T$XQ*QmwWMBC#IN:\T@GpC?cN
!+kk/L EVbYae>S#pFQd8Id:P+\Jh%&J<k%wRab>699bRbnckj:b*NjQdqXYIFKJdkG9<Q+*S@%BDneJQu8qXnN
>#S9P4 4VV8yM1tJ5d=9w*Tc\?ZG*Ddc&\ThF$qpc?4q?K$hAGm?KHSMCtyY:q^#VDbynHl=peXdwl6*$nwpy*m
QFb!Jm aTF%V!ynu5%Gj!BKBK*GZ6hnhpn=6wC68>%kYV5Zw4VKb=bLPIWJVMMAkw$l1y!mqL9Z?H/KBZuH!#@%
ah=6JC >Lkl?4=AWGEmhl$WSL!t?KTAR8Q8A%!t>EM8HdA^<d+T<GJIwQb+$HWm4%QFI^cTen+8aJqlaC*GhCm:
!HJj^$ yLZZ@LTahR+$%tA15CD>*dpJhbT@eu/dY%PeH4D#n1P14PPV#p?1jtPek#8!J6teiQ1<BR+G!e!+LeqM
pwMBNi ^=H8*<hC?@w?I>1+PcKI4@lF4wTJ#muXh#ueVM/Dh:&TnbF5hD9RiJ*dKAaJnq1FS>E+KXdk1HF+DES/
mh@%+l ^/CCa#VH>aj*5^<qH#p/<n:P58Xbb???>whFtM?F=h8iy4ah<*l!uT:Hj=J&>FwCE>/DqEb5Y=q*=d#J
&#w%w9 BpCk9LRi/HbiQ@uq!Yw^GQ+4WV1G&:Mbm*D>iQP&Z^MmHwuW/A=/C+AWwIdHu:m>h^MW1><Z:m@pwudT
LqGk/k V+!Lj?KZ%j+!!R@E*F<^N/Piha+Qt<q=V:=VeQ!R<ut<N6k@NT<T%S<1+nR4i!@4MMi%SH>RlP!yQee@
cIbA^@ 9<LZ8=#Xup/B$&HTqDEPwBSw&wWLRYc$?*N&ApmTED%&68A?H<=6WC+ki%c8BJmkS!$S#G>^\\6A1DIl
njbL/G \i$?HLE/HMBJIu/:RLKikW^T?\NXuCR9m&dEQiKmut<$W@<?#XTEdR5uDEH%l=E?j+:5WaWVj9QK1FDJ
IKlWC1 eAL=&!EPC!iw@<6Iun@cnNZ?/@Ae%W%1jELD\uY>GcH\#R8tnG<ut%Ft$N@i:N8Mn!ERCF<LuwTF+<q1
5mP1@E eFW5ccPRN$lS&!AeC%jF+iB+hh^G&<caeL@h8?t^IYE*DiGd@/HjD:d/n%jdGQ?tt&un>5%CJtLlcl66
tlC=d< ?I$89ueNJbDX9#=@p+d96G!ij\j>1EC@E9<N>L$RmWT+GqH6c&?dk%DD1t<eE:<ip$m1eDXXAy^M\G>$
>*yl>w 1LbB\Wc9cunX4^jXmcwdF#aA=M$HEZ@:XCZDTjkN#t^\aQPBcy5t@<*ZdVhb5Xtkt>XZ*t#!/h9uJt&d
#+hc$6 ^%@yJBG?p4VbA%FN@dj&DVJIbQ^Z@pL^BPLZl5$VMyu\>RKJ8EuCB4&1&K@8I!KiCCh5pwuh8K=K&mB#
B&q4DM A:MlNJ5+/Qji@pnBj!dlP/??W9*>bQM&HG/D15&^dVBla@D1=D@N*S?l*+j$>SGdWQYNeZ\qcRNI^19>
-AXWM: 000bf17096d00110333 Page 4 of binaries1.zip
^X/KIF JktdnQl#q*@Fj&W&Wi%*%9^G/GdL%*pkjt5mdN:/?=k&Cy:<8+RR@5BbNhJ@C9V44G>P$BbFjjQcllS5
<Nnj&G V5Ej!/aEjC@R#YyVVL=L\F@LJtXpA8F9D@<1CB9TA9$/1j<k1Gwp<qel&BTAQ=dNlji>RDi4#au@LkB@
ajjcSm LX@bTQyNCQ=ajt9D@WdB*l@G=>Ea@w^\u<Akbc8kAEdkN?&q=^HtH8wV9QpT?AaI@*j*Fjt@XpZp@%wX
j>ItZB jT@j=\j*jYq>uc9@CQn@wI1IYQ^@XNGG%6teTV^i:V?1/P5T@a51\19@9%SFG\S9ck@!6\F6V6dt<Ydb
ILXk8w %INjqiF*ujX%yZ&@86u\XjI&$F>bw/4&8@V>h:4w1\:/yw8?6t>$?XX/9nEa?ph8d:LyP/G@4=mN65$H
/NCK^+ EQ+!mN<W*ZhhlQ8&nuHaQ?mm*@Zlq4wI?+&/4%#+i9d9qbH/d&8L<G%c@$6qSCTR@:W!&8RCEjeubWRp
S48=Xw p@<:bjTX:6?u<w@ccIQ?:\Z/jVD@XQ/Q&tmVn>?uiE66yQad^@:c@5e%CQ*?h?4:NQ?%@K/N@nKM:&*@
cb+cmi 4VdTCjJud1tM@l=tT%D@4=ZS%<nhj^t*@I&WQ!aq?X>med/HEj<uF8hdQQGQa*G?^R@<JVQK*?IwmH?N
86iZjb lqDDdStBReV@EKt/hhRHpjBn=NcSJpVmD=Ep\6b>pu/IJPC&nBel19+RmTN5GXFDXQ5l<y<mVal@?56I
FR@DKR ?\:<=#mS:&EuK8bdScAR%j<iJ$Ip114?Z<TJ^KYBatdT+Q=1p1pJ86!Y6IeeKeb/ZDIcAuEPA4^>C&VL
/?JIX5 \pW+Ip<P?BR?<X8eTIhyPM&wPE&ja>T\!a%WM1dQca!ey8tZ*$*KHe$eb6tZb?l#TCAHcXcKnmBX6\nQ
\\R>=t <&cTaF=E>qQcCR:SNM+8!/R?Jq\$:Z!5hKqllS=4bPt!5BuS*Xk%litYFqBDC<iuBMwdV+<#pjZYQTDl
ITEA%c 4AFb:GmKj?<!=5mT+9kP:>dwCGIk/cL#^k<*18h5?P/uQcDZYZW6BAtHq@hju#ZJDqQLj?@wnE8$Qjp#
9Q!ld* YL%FCqpTt#Qt$:d>1Me:qj4u>46dQ<Nbw^uL<=eL9n!SHXTeC6G$p#qHw&pk1+XhJ%6YDX6ki>kw@tK<
$?#%m4 $TabW+Sw*=yuILM==uu%F>dQPh4MKFN>X%McJ?i9LaePD6bLF>S!h\dqDI@4k=h4%K:^6!=jnVa5L5\C
!46kGM Tjej/V4QmKLjTNtMLKFtaYq*%GINl*89S85/uCil\tm18NE%Gqt%k:Jel:cm$=+1Dp&QQDP?ddJn1nw/
?Q=MRW =>l:#eH\!ja?ll:q<ZB\VE5bqKBD4cA<m/J>m1>P!^+kD9I1\>R!kZNEpLLi/ySJ6F?pKyWRVMNDMR@S
K\LquX e=\ZNXw@+wiP*KN1+t$pXWj/e<69KJ1DC/9%G8h9cilhm4%N81iW=4+4^V>ep$#LPZLQEaV#9+P#S45*
FD!PZX %>WM=:\tR?@K#BE9%qIi&?lIb/e#WX&G>>GYJkI>&kSeK#iK$\y<>6^Fqc5H?abP9G1SJL^w<T!#SMXy
L4Qlh: 9hZ**@6M8\QVh%Q\Lqwt?%jdti1DA8w!jAI4Q>eW>+>*F8ujI6%jZWFPGj6jc4&>i%n+#c%^66V59nb?
K$Tw1V yj^*ddjjKnHnwdX*yiwl5IVPIu?>$LPGB?I!aN!lu+BjWHcNmYT<<wKqZuZ6hGtqLc#\6hu6!CaG=p1n
EBWt:N 5/>w\5qJY9Pw$@Ze/RilNn$$dQy$4AZ/\jIJ*RhaW>b//**4&*K&pqE$+i4wtCJDb:5qH!&dj68#+18w
tcG<Hb 9DS^6E&6Ima>%9\e^+6HHE5X6mJH$:W5%e6Py%5$C%mGnhTeX!4Vijb/V>5XnjYL?lmb+ce19nCZ1\DF
cDC:$Y AbG!hE&ya%tphJqG1i1>Tk&$hlB8@8nb^/Pj$+yeM@wi4QSEG#mJ:VtX8A?N9+hwLZQ=GEcEeid+XZ%p
=ZE&!\ PE8p9qcdc@Niu:*1u4tA:#yh5N/1<44GMj@$E:=Au!Ap5!Zw>89Z?^W:*8RL6ddjj5%6X=ZWewu>Ae9K
I%6K5t d=86h>uBRytG:WIj:F^V&5SQ4W$XTTR@$d^\WL%E69uDDNlE5a#!XJ#5IKbdkNPuZRijWeYI#a#cSc&+
/G&Zu$ RZJue!>4b>t=tmq@*GcRC##yy8&6CP68K9Qn6c/ibRV?Mu^i@uMX*HjKI8t8ub\6Inh&pGEY?QlSukh\
%HYt89 YhjRJ>dn++:4H51<e/$PJD=BZQ:TT6epcm>V?dp*5ipEYLnGLy!SbaP&1*9^\Lwu<mZ>>mYQqwnHKEWT
<TpVX\ Y=q>:cJ^#b$WG!n1MWF?LHjYI1#ERdH5ah>VYw5M45I^/+S=m%C6wm\8#/uMYE5=6@VcHZemIY$KGXZ<
mpQPDb cwT6T\hy*C>:pVt&ZcTQjN#9$Z\=FT<=Zy%+tB4S%L+8aTPWV/DhmS51G/ihlWqVC^hj^laiQCM?la5?
?9H+C@ !Q8wV/S9=c^Atu:c$@eQJPuBZkMFq6BXDTqSJ1ZZCXjMF%S@9E6^99BPN^#Zw%$l+uNDtlh@ThG\Y$1E
eb=KEd =:WihQ/y//$<4TwJ*P+l9biuK4wqLc#bNi?MH#AYZ9Y%C5<?uV:H>Li8*Z94\&t#AX^Qe6?5&<uTPD=Q
kSHk9t !*/%SQ?Y<h/<IbG&$>yw\/4Vh<>C*S?8XQQ:!J+WYB=u1!+<pJlQBqp:Y99YwqEDCN!=ZXWZ:K+GqF+<
BFi:$$ I$HRc+tGeK81p!Jm6ueP?qe@mDFbQFb91bMT11651XbPMpc=%h\djGtMT5^@q*<Vy=ql:BCLb@PHu=aK
tJ4E:M e6#8l?6SJNyI<89tPMEWViQbdP&hZjM9tSCc!qL9Dam6hGTTZJD!MHct99QQ8&>XyF+1P6W*:GqG<d!I
5HGB6$ KcmXTEYheQGJ49a<hR*pXLnh@<=l%>/m\B6l1#iW6%8k^1Wp<=SMhn1QnkZbDGt/lI$/46=bIy#96RAy
9Npl@9 :AlVMqyKk+<*&k?A#>S14ykbtyK=iB5DXt^6QQPt48@nqXbIqaEjYY?dj&\mGF%%JkXTVq*?tjh$qLCl
i@hwLS l+=cZiZbpwQP!1u6Xp8ch+cj^dY8!qFBkPHTt6nIAtF8^VmHy/k<^j*YcS?SlbjtQ>p:<&lKQ5/q1yu9
y86dQC WeDQulp@1I?CQ4y:NqtMXSC9jFJy@yj=HC$J9FNZu$D@+?JMtun@VC=$etdc@1uYYRKn@Gb+n1yEF/$T
D&u1Qb <1pYFN>nQEa?dMS8V4$5@Ed$d5!k<GCE1?J=BR*=Em$J8&jP4a/QF9yQi+KBqe5uZ\XS==YCwXC>/p6Z
njYb4y n18m@GNa8T@Q*hnj*P?li\iHT>cR8TV:$4JJ/P&I&W/hb*L^D!I$?PmPiZXZ=JT*8&i@QL:nYyBFhFJM
kB4DY\ V9cX@8dBa5D5#=iJnTYRLJyh/^uH&!TJ+LSPHw%/N9RJ>wnLcXhjQTTT=^8!EcHF8KiZFd!ZVmF:y=y^
PZqhky p\&4:#!p#*^wT+ub=#K=SlI@NXuJh9$A:SNR*GkX5n?&@JLd9hL!XdNFD:?yPX9pt@p%^b@!X\tL5ZX9
Zt!Qjt L94p9i%6/hGeie&uML:Z\$1uwL#6=8k\d1^duMb?mI>H9p6CaSK/@TWn<$:MddmpbZ=K:G!lBS6QVc#q
/>\Ph+ WHdqPXJ8:/PPP*1i^nT9pAXFNGL5<>T45^yQ54@e>:d#w$$=Sm6E*jHXBQ%p8Y^EX^#tQ?!W&uEh?!wt
Rjw#lN wn\J+Z#w#KGcadNLDtY:T:l$4A4iE#Yd#aZq^+1<:q=Ri>RTW&AXGPyaL!w%X&+mIDLS:K6^:YZN:VQ4
9Yk!kj mqWD<Y%qX4ZD=dhuFaBZ4n/MdY@b#nGh&dQjMpY#^%+:?*JF=:^aV:ZJL9=dl:mQQa%FBl>NHmj5i\I<
%I&<p$ @hn5h5@K#QdcJ&e#h^<nXGL5piJt8%mF8I4i!Zh+y:Tkpebt%>NiwW&ityy&1Tq^?*w99%b18*=6RJR?
QPj4=D IK=taVSpy#\:!<PjwASJ+wV1eWIF$JT$jGAFBnQjCW^BQ%eC^D%Tl&ij<A5qVLN<@Z6HkaWaiI$JK=5:
aT9b+I E$pCN8?PQeniticjmWIHP#RD>EaXZkJ84cnFbB4H^!BH*C:I$LkN&EHB@KDbZAhqiww8=JC:N6h5Jkqa
qnbR4$ wbdJpT6kk+LmCdMXD?8##YN855jh+>ZJSeh1?S?Q+Ctin*#PX$!*bQM/lMG&Hd%=GPLlmY:Q+<G&w&ut
Qa4VQ> h\$!WMB/FKB?nMWc\4ckZmS!!S^pl*m^5Z5B>ba\<G\iFk8b?aAHu5KheN$SeaNHh^Se?lJA5+cMqC89
kTW6&a %R4inlCp=\kL?C5Z#*K@eFXiK<^&8<lhN/Z5t<QtX59iPR9Y1R?mHBiNKXbDq*IK$9Vkq9^Xl4/BN:bS
jRCipl clTB*iCRLIGdXtw/LLB*=^J\ab5b9qYuSytYAA+$XhVJS+$kRTW=wnhNHiSIauy4w@\SEKm8iQCSIM8V
upmqMn MHbLeV>=DAyaS^6Bnw/kcYThYl&<#l\kcSmb<BdPV8MPPR\84lWQ8d86F/A<t<+#&!NT=>TTuGGwq<#D
DjCG/@ a^hE$<kbGXFLXRA9ENEJHaIeL+FS@tlKyR\>GE&JlR?WekK!RC?@EFmYHPmd5y*hGLe=GdeVElimh@yj
Qkw6P6 p1jiBFj5+K=*RAqaTI:=<JWd<iwiqF##Nk5>k4dWF8:dKTPVI!FnKY5S^VP!LC5\dNJ\WJDnWaQSI^/l
pk8w^* aBV86H#&Sitl/jhC%aJDV&S%e=A^R$nKYiYLLlYn>JTE^G&Y#P8/LjQFyiCR/?wE\M&5E4taM8ukbbBu
<l\%lP tilen1T8qD1iE%Q<tJ%jSD^tdu5nX5hkVhEKFu=HqqNkib>RJ/1>dCem:=cRwD!IE:5G^TF1TZM//DG>
eq?ll5 IM5p\m98qeX&L5Vk16/>HXSPlDD=D4AMtYC$R@AA1WGIE$>V9pMqYq11BDBQ+V<nhTy!S5/1a^WqcKL+
TK*G%e >uNTFlEm\F!i&e\kuRj+pGQatCGy4n%mthaelLNB?4GCJlce%F+H?S+JtY#@#LYqpYw!1uwQybVHjViW
X1wdEV !1t%=1QAZIB*KYnKbC94#FFCAP>wPBI\H#?tl:aS$BkNEpe:WkV#5XtwCCITQV6Gy=#b:bcLCc5=D<:b
Juy+1X HTm5CnNX%?Zl!j15QMeDpDuDL>lZaAuB^6T!MS?Da<?\nZ+P/CwpCTa^w%LR+GCW:CN$b>LSyny%:JGn
pib4AQ 4BRqn5ep5$a6ayhl+H&kHkwDh*1IFhp=*5PPa#PJHSuqRKFHtnDEhBL5uF4YL+1/q8b9HnB#F$!d%NVj
^8Chc% XB&>?ZC*@#8#b$hN^$/dByiDPw9+G\aMVkkym9CcW\KXa<@kk=:TmB&:Pk&qlS9biPZS6HQ!#JhI>wMc
\Xw#V% &Nct%&PEq%J1GYbT8CABZ#>#t?/lpT1WmQqQ\q4auPKXEa=*qni+/ih55/ZR=k5T#!!pVEwXdjNRMpN\
=@H<8a *aMauR?p$u8A:LNHZ>XKWBy+*u1lE#4Sd=5+AeX+*V$TnRqjE5wXdj&eSS/bqN?TGW+DB\q^EeNZlkS6
+p9I4@ kFiy+ReeRkBcq!=K4L$DDcjV\nJ#Pp<=#q:k>?\G=%:d<!1bEQ^J6tVE%>8EXQFCp%B5dRhZ9&NKKNqn
MLcqp> +y/#w?aTd?eJ6=KDH4wmP#DyPpAY6/wlMlmJy=@!aKip\d&&yT<1\eK64iQbRPYweaHw<XP!ai<^&DCN
EW4lDm /WV**PAGP^qR>uwq%tKQcPbak$9$iyBkwNLP/nJQ^SXp/H^S@W/h+F<kI=j<&htlTV6R&T?AMWMdwylG
HVI@y4 5A\W8w8yQ@65PuYuL!?n*pQM$k@Tumwn5+eh*CX?QGKui$nkPlHpdlpMVBVmii#d!Gu+Vy\#bpmHHVa+
9^VnyD hyTyaA%/@iZMuReDqHmF8$5ZqAhjb>48I4*9QYFkRmyF&&&nn*Rb:D<c%9tLc?\itRD6@cwpn+k4?$ZQ
-AkK6! 0007038e53400110333 Page 5 of binaries1.zip
=Ta9n\ CMp?WI8/+CYcCLVN#^q*n6!9#T/KH&ZQkjKGppRFjhY!8aM=bRpVKECqF!Di=%+<SYhSLYpeJVC/b=89
^1+:S8 NiYM4?yJWJ\X+h$h\=A*=Dem?$:w<+nIKVEZ*Li%eTKK4L4&/AB4\E%%AcQ4IXp^bNy=KWVbV!FR8#GR
<I@<Hn @pRE%HyC!dSX8Z:AuW\!#4!?/$&cw8%Dw8$w4dNYSAml**:cyD<Me@iERTTH<66IVb6CqIMnTmauByAc
ItDSKZ qX*4Fitl%!l6eMIMabJ\MMIk?KTkYiBR\Jm&@<T>AFX&a*y5&Lbk%hpy>MS4C?NZASPNaY4&:4aItqZL
4d*98/ iSW!C=EiLn1J9phX6FhMuW+Mu?^IRh^Hbq:NPCtiPq*aAGD+tCtq4t?npC<ja^@KcI@N8AemNI?:E?+^
Ya&dSn TbSQ6qRiTnY9:l=8?^t?DBS!9hHA4qbn#aM#:=4bmAYp@tBA4CYuDey%Vw5djk4ncAKm:dSmF\F8@M4H
TVJtEc Wa><AGjVe*J9Qlbj<^MaQRlwdmq:GeN#Ww=Z/Dyl6pMNT6y:KXSn:E1+&yheRYuAm%<B4%T%R#R<M#uq
VALbFa R%!Rhp\@4I%chwCmdw8m%RKSen19@tHi!=&F19j#SLiyCT/jY:^=bm\JhQ>E!M8+W/^VP/wnVmN/C6:5
%+Q?#E \%?ESnZ+HLjYithah<56N/69MlP=PkR&*j@$CQTB4E=^d1klM$AGjSa6GnRE6L$XXjYMcb<e6S@!RLPm
ae$mS1 /j:C!HN8%kSt^mcI?pYqeDbNb!$w<Ne++uXWaHWR@D*VdjeF<H8bL&QXRSX?wNeZ&<&Py\$GPd%Rqnil
GSja<Q >/?>5PyS$6KKQ>KpaH:deH*he&Z>9CqpX&nG#RhZqab:RQ:J9@tYuS:J8VuZ5mlRPEY/QXktS5AKwSyZ
%@8+6w DA8i>8S5D=VtpL5A6IMWe$8#aF8t?TBl@%hu<Z@qFTd>L*tkTcT@GmNJ^Q<1D#Vyd#bE$4@N$p5m@P>R
u/BL\J +ldY5B?c\1K&tl#T@&F!@6Ky/9@AaDZ%9#Janj\94L*ckaFB+b5?5G@bJNS?j\9#1!Fa:VeJWFQd\l=M
J@BW>S ?y9N<q6im#@ab6Y&#yXN@mH!H?!pJQWj>$ui$nc4m9$^pwnhEwu:IbKpl6<Tmj<lp1m?NbL\a!TB8CYT
c>#$E@ ?GMpdt5p/ahIAuF4yP1Qpjm6pV?YIj\@ePnHMwSZ*Zw?j!^D@/RP%LD@P@VHW1TG*jI>ZVZ<@+#<5^S=
QNBn4e lIZDXe!IGHWMHp9EEnG/*5GGHk\tBwi^<jdA/DDCjN#DMEGiGN*Rk<HlRX/lnGD9k:<4wK?K+w<PLqPj
aaA#W$ RL?9G5l>W+*lNlVHyqih5FH\G:Q/XaEElVI*6KV#N$j1Z&kndpEdcaM&Iw/5l6?knSG<wYI^%l:8EcE?
&JXaS9 +Re^XA>GiETwS^mGEenE&EZ+B*1EM6^<@H*Cjd+t*jtZSPLkiD^lR+#X+HkC/X<RTj4H6*m%9:@F?$%F
q6NPLZ @ku&b\WPX!Q>@la9TjZQ*yuN><FJG&Ty1lP?8Yj\8P?JjXVM9!9iQ#%e:e@?u4<?Edeb64Qy*9*h+jPh
cw!SeW \w*u+dD1j*<kia6EZ&Re@5ib9nm:GFF>FG^5cwK8Jh6@Wu/X+\VEl>&Amt:Ta5RpBH6$Z$8k1kA$ph%B
Z:5=*! 4BNLqDTmh+=Y>HJB<h&R$beednm?JD=tmSm&t$:eB8t%iyp$RqHPVq9kW8^DHSBE/ZHPM\4jWG!1$*8/
l:?:iI 5yIY?d$8P1K:eC*>N=FF9BW9a+1cydudhBuVSj:ehK!W@YAIeJIXw!mc\RqcwR!:IGZuPE9RqmMLTV&T
:yyDKt k@qyLNc!?#Cpl$9ZQI!RjSMT:9p=WCM^TY!y+Z&Y>lMhJBqMhhIIVHY<TukcL/qltSmY$!Pl?mnXt:Ym
D<H::k mDuBa%6Mp4lGV+JW*n5:ElXK*5cHqYHW\9&J4Z8nchJ>a$M4:*TPN96!991Mp=!8n+tJy\*CEnwwudBE
8A1Zi< cX&K/CXhJhdVZep/T>YqSX*Nnb&w5LZV!GSDiy/eljF1a^F@>Yw8PE$M%uqyJlX&Q!G>\p45pqqj+N*L
^8Thi> &lY$/R=wV9lhewiyJ%H@8ZCiPJbN%:k<u9$$jd$yqN$Nyp*V:bH6iV+4iq6X5QFLGTj@J@qmV8nuytFV
Nly&c= Ib8/8S8C+YYmF:Mny*b4Y?dj*>dVaCMwV\qn^5AI@kY<dET\5+FMV<qlPSE%h/q8GLSJFp1khwTjFE<P
A?^j1B mHM&IITb4nTMNNR<GKW<l=YI+K^5Iy@$beeh%TLp9H<GXBN\Lu>d?dRlV/wwlyX$6e/m//%\QQCw=R=P
mq$**i ZNPmYP?R:D=J5+9?5KWJH:y94Iy1NlRld<46K=ZREi\41Z8:ad:p*k!qRn+i\Syu6YELBMF^dLuJRZKm
#ShVp% p=:Smh9Au<ZRw$49%D5EC:t$Id4wJ?LDjR+MNq\t=GQ<iI$iP/j^G\*\LpJ$Ln6djK*A/1SD@54+e$dR
FYVGA9 J=5J#uyiV*Fel?+?D9&YPV&!8/AN^%m9j==D#%/l#?t&h<m8!8h/*VYmAZQmlnTM1*d8Q8CMhJ&w+5YG
&ITmWJ YG%b%bB+&@muc4qAlQ88y1jaYX8*hKRHw<bj$j>K%#aAhedW&emJP<d:!t:neIF+>KYl@Y<j?V:@le+6
yXA/ic R*<\TXHZ/=>WP:TTmt#HHQH1I\jEiY1<NJ6<nP^L6+t/%V8!QR8FD%$\jj!15D#Cbm=d%4q$WK458K&Q
^&&we= ?VF&tjBZcwVLDSFt1w@V6$@6Wdq<hMwiG:^!Y?^J/Jkc?Yc/?unALj>M*j&1??>aqEm=P9K:>L^#*:<#
<E<SYu @6YbRV/^BY$VGLHqw#+#CS^6@e/5!jcRn+^uLe&=+jQ4QQL>!aQ#kilpbGMPQWm\D&piqNp6w<dZul/4
8IH=\R R+l/HN?t/8@nNK5TNtIY**1uH<\8:PGuWkN4d*hKG*9FSlVR=5BiZu4P:Z#&y?e<mRWXhup:&^SNc9PA
yKQk+u XX$KkHMDh/Y>Q\@DBedGLR6F>Z*4bE/#/\9a=P=lMC#qalK%ap^uTJ!Cm58q4#Fyk\<n&C^/ZIXtq=LV
:NPKZB qE\>wp<R5I&lkWMwdt49F=:h?$HiGd#CctdKB>pNW/Kh4mdnEyApLt9MS^HL1\#+tJCBuFn1=CP8+*m=
yTyCJK 5i*ue*p6jX%*W!9pkDq/am:1VipJwXSkXF#1qGKTBXXS1^#kKMyw!1TaqhFMbKNChA9>V/!8m$yWe9Eu
*wY#k* PdFBdk$BV*8u=VpjVDpeNhkDkm?*d=j1Nwa\jqdVE/8FuI+E^c99yhytZllWVDScql4XI8nquNEN^m?Z
q?QBLk De8?>4@jhZlh$W>AZIdktb=y^ZdT++SXciVb\DNH=L^ib>lRTBeyR<K:DB89^h@iN4=k@SdKM9kC$?6i
6Ajt%\ b>GbH+$<WTqI>km1J\D4j8iDjNWhJR1m!Z^@WmZ\hnlHaNbyMWbapc%Yka#MjKeD#1ny<jp:1R1uD%<$
I>VH=j #ju<*P1%uqTZa:&eV>!99RmB1d6Zn\WP4LT*EMCh65JD6MXK4SL!:Q$lHdbVu5<uak%hunt+nMV%?%4J
?i%FGy XHC@66aliED1b!/N?P^=nNd^9H5muuX\Ph>X@E^hSM8wVh/8?cZDT1AVl:m9>n4+XuYV\!M?IudbZ*M5
RQ$*we j8#N>AtyG>/9dZLuDjh8G@ud>:A?KI?Z/ejN<?/YF+^u8<^aWWdMS%B=+bAl!<b1*H&:Ri=L>k@tJ?^C
wAPke! 561yQ8%k+GB+ImRVBm16&8+iWF^^ARyMED>&#%jJ!L48#cmP=H/4Tj&hX@\^8k?8hkAF@T<*kcyYEQjV
cpmNJL <ypEeb\XJ*bI5dSHAJdD%>k5t=>c#Vbyh4@N$4Xddy*#KD54AwIGqHZeQ>a%Nwe<Ec#wIE8?>6NyYBK^
<1A66# RqT6<eQ&a=m4L>KC?th#H&bIn4*$<E9ilXcIFE8Q>Yaa9uA6M*4#$F+paNWPy1+w^uwS\S4uSq<W4LX>
\HZW5\ jRDy<w^bq%b#e:dHJ4*Ba!ZEJBltp<8d9kK59ZcKnL$KCF%+?an4YH?&eqhQ!wIJGt5E95=P16SJ9%lk
p4kpG! W^e>kq*\hR&eAdM=LL:k%T=+tyN*=F=L+tPZ*qV/I<W=#?M&>\&9MJ&ERmHn?le4#?5<Wjc%BkV6B@^5
WHqX<! ctee%bC#Q:uD^!QPIlhTQi6WYSw>5qB<Z6eWL%ywyD=Y&u#WVK8nXVpPih9GV>nYCGj$^M\I@uQ^+<M=
b6*c^M T5>uTYqw%hPubQa>RYD<Q%yK6FI@?h<%DLyj&&Z6k^L\jhCuS4$Jm4SK\Ip%TX#VK=C+dyZ:/PKwH*<1
&D@*^K 6j/8WVY#JLd$/t:4:dL&Q4/5!<WPqK8hQ=8I/lZjJSZZjVLK1Z4DC#5\miTB:pGjWneYi<YbN*P!E@*a
6C&qh6 ql&c/@4R*C#hIQnpH1^Xk/ySd<1$q/\@@$5SC?Wi1bem/%?PLm+tZJF@?4Hd$d$kepDAbF5<l!:AC\/l
VS&FAl $taVH9J=Bm>JDpPXb>PkD1>1a8?\GRnpZya@KNwj9GRqSnA>@HJI$TeKpwtl#ylI^L!q%pYHNcXTP&+H
$CpLMm lBmRwiq98KdG#?%b>*PL64q6:GMXY>q6L*^d?6Gi9C8qR?lL66au1w@aT#*A=@NtTAq^^blCRuaXj?bq
A%p*#J !mX+HBw@V%dnYEu4m9LIZE+>8Q?MwPCBqQ4Z8hyaB^@X1J!#l^=tTtq<DLc<#9w5#YDe4i5y#^FW/C=>
G?jyP5 dX=p:Ze:#L9&F?Q5G=K*D^uTVc&KjhbD+&6SYByjej@J6$<#puYPnHlju=Nt1jk>DVKE68IRMm&9/>A!
iCmqIt ^Pt16^KG=l4d=NA*</a#PyPjtTc9&yuK\V<?Z</=tZLS>Cmkduq&RP#u1kiNm1ILCd*Ye=Fj1tIKL%V>
RR/njQ /69/DK&u=F/nQc8FSd#T%&%D8pF1Pnq!*K=4/uDA+!8pEcI1^8YuVVLAT*W9FCkXT@^ej6MFA8yeXZAe
+qj?VL yS?CBQwISCXZHD6FYaa1PqWn8=YaWp4#<L&qqN$n>V4VL41IThqm:u&$Bn*>R!Mq/!pJAV#M>T!t$/Qn
V=*d#y CWZLl8iH$?Lm#pFV\pii^6pGHPyIGDeicA=CyXYk*?59T+^mX6Y<EycH<LuHi@k8mn%<L5TZdu4Gq<IZ
1dCMcA Il5I&pGw8u=J\Xk6\Din>FEbaLW$Zil\qC??!46b5iBZ\GJyCnc:56p@\dnddE^qNZTQP&XbV+ACj$Xi
Gc>Hpc !G+1jRi:mdw^=:P64+bjJi4<uQeS\=VLVH>?<E/^RdE:k$S@?CNj*DGnXZQHY+b8#:TMMdtWC!%9#lND
19Fk$9 hG&kYaQW?RSR?n=^bqWWc8%VZZa#p%jTN!d%+9D^kKZn*A*MpMuJpLW4AW#*F!/>mae/n$?@KuqX%e&C
1u!JIc *l!?^AHpK\?@q5\MT+F:yG5eY\HmhQ%Q!Hmj6ZS4FWLq^kHBHFZe#!Sq8/@nKNN?tFhbQM+I@E=&YcB=
R#!Gj/ F&!YN@kK9=RH8+k5l=Q:jH9%K1knLlN!5>k$Pc19w811$CGdZuuI4dNEZF5YiNHJj?TMnD#FFE/SB$PG
dPT:SD q51:#+dFe+T^a$&ElFyKXX5Y\bBZGauQQtaNLitZN%DdJ\=:y>!<qWt5@GLEb\:1>9S>%uhK<NB?5K\S
XcX^8h %^YMJZeVQ?&EbWcLdmXHeC%HjTMueI/*M$%ch=S#+TBIn!K6I/bX@IqLTG#Y4WnWRp</yE$dbJ/KPVR&
ujF$E\ 1JYK?+qpdMWI#uiuFXa@:S?S<\LHZkDQ!@HK#jDG+jGb:ZJ*mHa^4!Gy/hKbI>eWC4y<WBYq\b+>4y<6
@Y:eFe AK##=KcqI@8XmmqLJ!XK\Xi:YXu8&WW4e5Sy*+4n@huh>idX:@epXe8BA8TwnmV5q>#1aplnG&Gk*=mu
eDTkb6 %JD8*@iW&eiipl*YKPAqhB&dhEZZp%KyREp+StG>Gcn8&TW<jQJ=^ZubE?k=eK/TIFeQl@p6LdKCjJau
-A&@ye 00022dfcbb600110333 Page 6 of binaries1.zip
I&qGkL B!/uLy#D*%ySc#l4y==iLeqVL*MJ#kk*6NZX^>*JXB1=yh4bilwBQl&EhAC=?8qF6bb:9/Zm1ZR*qpWW
mMj:iE \*5e=G5J=c9h=p*Z=DG%wHiJNAySXyN&G<<dBAt=/@u4E\SWa@*j<qR\*\TT$%d%T#JwNlu/*b+uF9*V
&JhQ+E DV?@E5=Yah1k*j^AQ1*hF#CbT$>&8J<%ane?pYKVG+l84R+!XXk>4HCLqykjZ@+V>\A\hyFtGwkP1WPt
H*jK5N 4KX%//&?$lG4Au$!DF1R#5KaSM%d%tM5/FQVGc#qPb&e^RZ&wQiYNP#ekm*P%<&+HnZuH?pSF\D#:J*P
+8Qdb8 @CCb>8Du%*ape/pDei$F^:QQ*nI<@&LZdHheH!ql^b#nE!cNGtynJET4!*pKY*B*!tBnj*9PQ8wy+E$E
DYT6Hl ^=4@cV:QIBLN@tKRadL@TqhcRW4DGlZGCTyWC*mV&%S<QKKVkm+eSw8bSDWNw/ii4b\hE8#b+S@qb%Cc
L6Hy:4 @bL5Ec59&\ZnjtWKe6e:GTB@9M+hE9=ik!<DZu!dJ4P/4^dC>@Ti+KXnLJqh&5ahyCS68$TKjwPy$h8d
6i<:H4 56XcD#JGSeGjQPX5@PhB=VLH>QiDjq:abYEp+A=!!^p/Fq$XK*>J*/LbT6+n\GdhIXkyA=I$Y=e+GMK8
Li:K!# eWDlGM8:hcZSbaF4j+:8w\hn>jHGP:WNt9bD*4@uK@DS^S#%cwnQ!JLJi>ME1YMbAqp1XCkZ&heYbcc\
F8y:MY w5?cDQQYP*lin>1ue&#/D5N4neWcP%LSpL@<CuyQJDSC^<ik>CN*tyiqt@6JMMM>AD&*YqWLPTqHy&EP
ya9@6q ?XHtDb<<8nCj!M>cQQNG&*/=$T$\=YinTV9?F<HNB:R+Pq!aAT+!B\\wKW4\4Y*5c84@ya*>>%VLj*w*
pkAyPC /*><Ia9<9<RB+:+qej:nHw\+:L?MBQ=8MQnLluq@M&cS@^aKnN@TdEjG@^CJ\&>yNCaVjwlWJY?NJQ+a
!E!p:P 8ZW1RDLy^<m6E@1SXZ?M^G/NXQ5lp1T&ydtQVQ+^E4e%l>S@mCT1d+qW^@+a8dYlY9*HM9RQlt4%H<5R
b=n?EP Ad8qE$D>^#KE*#wwZQ*HMwVdiqdWj!^DPNKYp1D?a^u/l<%Q%hZ?b?TQbalA&HJq1/9@4$ke>5hClFen
9M4Y$$ dA*F@R5wcY9wn<WIV!J8DTZ<:>AjC>I@8SB\&H?ln4D@\PIj!^JBZY%4/I?F/S<<LVk5?X?5N@LY$D@@
4Xhqm! wj$P@L8bY+*$*e!6>l<#N?H9d^DmeNk6:N^EE8H@cpeLLyt5+G+tZJIQFDQVQ56BFE94/R1yn*JYXlhu
CRT+&5 kL!%i$qT^\&=&KYD?&u\ZPP!:Jt+8n&+PJF8$JI?#B>:QI$Dbyp=4k&K+$PYmQ9H8T6JWlJKnE@A9MuX
G/5:Ic k>HYFE81kA=Kl*PipY:MahMM@YwCQ@@V6Z$1w!$4^*RQTcVXLV:\dn%uYZud>&/WLa!PFW<CJ=C%@Yt$
D?H^6/ @BV>E5EY%1CmiAwEee1RhdN+DA\y*u^Dkl9^TJ6t8N&XD>^yHl#L<\8wA!Nq+Cqc:hE=V^%<@EL6/9M9
8uJQkn bhHLc?=#BTKJyLV?6=hHwkMhGN=DV@T=AkRG4H#Y$^P/LLY=>Mk\!TbhZFR*VjcG6nj#M%>5#mwMPmj#
Q8V+%K +DNj:SGP<a#neS!jwY8<:*@qm#&<@mWiKEpjd?@\Y>P+Xt5+DW9Rym#>ekp:dpZwaPnyjIdkNPSlWEEb
RiMkPk *+jSJkZLW^i+G$acYH//VbtkTqyw#?+X9^*Q<Bbm5Fj^@XHiR+Rwc\$bZVMy!95iGd?HHNTAuAeT%#N#
l$p:WQ uNRka<?e&dXm@i^G4&itQS1@aju\dF/4+bmSWq@T4F=$\9LHWEtRn\&wy@KCMHJAKd64HEYKHk!i%Fe?
:liR*y deKP5!d8GL9EKGZi9#NDiYKtGWJlEK\DZEA\cI/t*8+tY+E8IbDK&8J/Rtae:cNJWcd@YNNMwVZJN8mP
ScR91Q M!hF8@1ZdX1^Fhat?5Eml&DRp1QpZ&*!lD>n$:SNFjjFm=/whCWl\9VG:kw/@?JpZZ@u5#w$SMu1E+kp
T9p=SK 5Kmi@9#w49j:qGuYqu#yb>K66Wke6M<W=J1qJ$k:^+Tyd!>*RFNDYiLR>cyPXqL9nbcXl66/M$$i661m
aQjKTk VQER$u*K$:*uP!k8D%THn@!phVuW8lwll!pBFe4M%PS6R:>^S>%ECeXWK^1u^L#I/1y%@<XuH&&R>18y
QP+9MV I*bAwK4YdL@aDikbi*dtde>&GFSG$m5NE#bHdKdbAH>6GeqXnbEeNTIY4QYqqSjMYqtN$FAP$q$tAjd=
k$8>RD S+*W416$B@R/nXC5Q4yBqW6Hd*S64:w?I!AmiI5a*6!T?e1m4HP$S?P^5u4%cX*>HAw=#?^t6*AEGl@/
aBq9?D h6mbc:d6>e@*d1k=t=tGT$$9+A/e<VRVGhLmCymP4$W/9J<jCZ5<P#dCc:JIN>6bLjT8YiVIS?kPphae
KuPY<C V8CBdj9CyjX>?q=KyV>LA$jdcS6i$^B=iZVjTZl98$mDE141+uDPuFZm&bRFJ><CNnVkRbZEnJi9<lqc
j+khY> R<T8!!c<@KVWiqmBnZuuCcGHd4WMG*Vbpb>PuSbDGjKke8d4dy/:e8wu?Wl$<d#X\wTRItuNe4JJ*8u?
VNP%ph BG<H=pLeZh$t:k9mSP+p^4l/8/!%kK88E>*@nPi=iR&IBa6BGVwLWjLw8&V$Yn=JThG&b%#Ab?VRE#jW
>ILXRX *q&K5$i1luc%&&GY%Y9i>NbK:kd5GTS?qPHa5RJ%1#/kMINVnik<K9G\$>:QMahn\mGiCbEk?6deQVej
pkiYJa Q8S\c^?P5yB^eV*Da?AN+WDN1XeN*5$X&e@p?a4P9Lw/VSM5Ln\j$b5&^1yIKB\!quZ14\&8:ct/hi=\
i&CeP# K/Vw^GR5aR$cQXy5%h=SHbPe*<9Zee\\S$>kb&eKu=FQ5p#W+A6P*Zcde+QVjQQ\n#GbFSI=4&Jymq><
%\qd9w a+F9S4S#H=+?H**K*GeEYF=/^?6PW+db1Xui<np1y>C85PG<ib9VLAI^:p&VYSYd^5>Zh8ccD4Gl=Vpc
:bRndI /M+CbwBmypVZt5j>aw%#<5CnI<Ldhd%?aR5Km$cj?9Be?:kIn=cbWK+FmtN\Cj*?ZNlTl=tXnyFmLV@L
t5i6J^ S8n\bcMJX5eyNGj:^E@Y9uauuM!E>Y4!pW4&X\XGRm=CeWW=1nt#CSI=hdbB<Mp1ZSM\5^PI4BN4Aw=S
K#Tqe< whwh:kT4k+d5B+BiMWeEmhWh5PJ6Q+tK%a4Gk89a1Iw=+PVqc!wnF=X$Qm/heP5=eBRyhd@6$uVXI\4i
BEYq1: %8?8=:u+6Z9uu8F?Y1\jV^Dn1Kmy=4aNM9PVwPW+&Nu514yd6EQuC9Gt$luBB51\Q:66bEXb#PtG/D^u
P$tLnk ^L%MY:iLNVbGXRIhq@j:8Bh/qMyKj##LKli#GB5*D:=TeTYiIi6&h^mmYq>X%XJZed^iGXSPl^t%$^%Y
1tiASw <<G6DWiVHiFXk?PGTLBu@eh><T<C^C@8D=l*QGPG?HLdb>ukeq^\h=Nd+bkJ!nKw%?GeI:#Cj\ZkDtY:
QpW5e% EmYS&T6tt=dGEAZ5TkSMN&e=?*MQZaEZ<6!*HL6TGunHyydGeWw6%??w&4J&%w/!<cRe\wA?iHAW#cu8
$@<kYR iWj#dFQK1Z#nXK1jdhnDT*nMKtMTDBWSQG@D/!Zhj9:cmXiD&$NNi:p4@Y6T:44cDAn+VD#I5*tY:95q
Ykh9F& P<qA41kKG@9aWLFS>Ji<?#X6#$J>WhCu1Z8eC954c%Z*>ujeX6c#&*8mNJc9PP:>YQ#l>/jPqc#u4AI6
MmB4yS RZGL^@k>>#t#Sp$p*1JQq#\<9cinXI*L%uCBQ*ZqkDcL8GC5XuX1h#ZqGY=+J?TXZ<V4u8PBSBlIMh\m
<ql:n% J:p?FTqFY8::ZH>J9h:Zc^YFS6@J:nJ9GV>MjdF:t?HXhNNc#>*?MB@j<juC&Fw:bFtT?m@KwdeDX$JD
CFCTTJ 4qwFYn<M9&DZa=<$>9=u\lDTKhc#/c1q\=YA&jdeqY6ZZ>$==DIBuC^eea9pNd:?/Q\Bkde:GBuhN*^H
9c@NL9 L?&6@>q9*^=l#pAV=RDGnqC9BcqkjNeqjWZZlG8DLm%**WT8Jh%*W8\iK$j648k+>DmpdN/F!1q+T9SY
lnCXkq W+HSXL<VSFZ1#b44J:aulhbuc#?edu#Z<+lj$?La$#K+mai\uXQ9ib$ID:%4umL:/qY!bmtRC^k@<K6w
5yMQqj <>TndaTZD+8E>^%S&y89RJ6KQ^:cudZa/N5l=>K%R?Hw$SEh#\Z>^AiQPWC4w%dnu9C=5u6En4mSnBj%
@NIljq &+<j$?WPi<+dl4M5?YZlyT!94TAyFKhjNGlyphIYNbwnEa/Mdly+h:PP^+e<dZY4<bmq91QyJNKbHcYq
^qLm^c ?PZtL:8qWXe^</eqpa*yWS<hQ?iuulC%cGw?B:@!mFpbi!#>$@H4/Qtj49yBEe*NiMM^Sa?W^qGi$qV%
V8HZ1> 9u6H1P/IL:?/jZyY%jDynR*jm@1W&KYQ*9l4<qIne8?@yNYRtQD*^$N#u1#=<19cAqcHVI^jB=t?N5*V
8/bF<n :4=8ZSc<y$@4hecnXcPW8+FwS1tXR<Zb!KeFMVXL!*19enmP!C\GK<lH!m#DbNL1C/1J9aNT\a4L=?Wj
?Z>V\u GIKti^aZ#/R^5T!KG<XZwiSn=S^GE<T!!lknBtL&*P#Zmu%#5IT/l*9@6P?nGjhHi*njRhDG*W@m91Bj
ne1Md< yb^Q<JS6dhE9aHad/y?Qe>JjNF&8$AjR8J@tq9ZWQKGNl@Q+SnMqHll$P6=$aR:=L+>$&8FkX*ymRM@#
bi?tFL dk@yMLwZy$BtknhddTk>\tbW<@Q^9JlD!e@P<LZV:1@X/=WNS?Q$IJYm5bp:NQ1a98!8i/Dh>?qPl?GQ
>jGR?H dLL\9*Ja%V@F^6Q>=Z\iJbn5BKQS1#IQlTk$Q8:LjEqC@n$b18^4&8d=>qucI8qQlPh5>m9Z1T4GYPQP
CucL+n Sq$WtF^cWWWG9%^4XnXJMq%A9%1Fe6!<j4Z>u4BblqcIc1R!*dE8u:nwB8tc&iEXAbj^&P=S%e4@tX?y
8?Ll=% D?%NJhb&Q+N:c/Wh1\j$:?%jn<!ea5+=HR8JpS5I#EpNA@L9J>!8&SeM@KS4<?q+pqM9>!YXySPqE/T5
k@qKtw <tGX8MX?XZ5jDw<EE@EL9\Dk<&tRmdeJdlBqmZS?aJI?@6jBS=TX<Z&t4TMi4jtD$^aeYyFijAPqP9jS
Ge8pY4 9:DF&a#^yPnL6R>Ty6:X4h9wB#eK>d*n\j:e#=ytH%@MmK!J6>N:!uF!n8pZ?$G!lL=@*kR>6Q1aL*T8
Y8I+m$ bGuyCYZ>A9jiaRPBke/b%Y\TuDXh\u!nEDWul&HiC4bX8wdQEWnQaC/b&!^lYMVl!D!4BVtWSy/:t/8F
HQptD> \IqdVAm4<%:&==MBKbDTB=HCVyMb#dPB4S1^R:L8LlHbA6FwuTKKySm94%^u=MWGuX1/d>$6Qh+EBKm1
<ph!Z1 1p:tF@+aQX9jK5WqDShDYWy:eKYC4K#bjJ&<Zb&e9YlD/eGw$Jjk&hSP9j8E/$@:dGW/De@m$yn5\\*Y
I*hN=j LFVJ/qSXqV:&\#d5b+XSNlt8iIti@tyWB#T4DQNC/Mwan\#Y#TD8TL8yp#4CYMMG1<^81C/Z^5E:wcKd
6FEtYw %DEA>*ucB\cM/JS+ei5Yeeew<^Td:XF5#?uT+I&mSRL:8DlwSFaLJ!/Q&DnBBZA/XbutMDCu$?Sm:F$9
FW!pyN G:NeY@Kw$1$9y*G6tMwC#:i8^qJ6VI1#1dJYR+N8y6P&H1ep=8X6\/@HJ59@dG1#C\%TC/hZ!mc1?<Ed
dj6+nl KKMEn!14&&#pSuQPN?@+YT<5Fn*>y^>B=AFQBV=1*</Maud*WIQMTyhpe/jqSlNAueM4klu&&Gl>tE*b
I6!YIq @GH>in<14AA9A\Q%!%GnLKun\Sy9D6m<PWKlBBpCVR\>hl8!QA^uu?y$*4h<+&:WD*C<5^yMTVHX</b#
-A+Vk& 0005c1e4a4400110333 Page 7 of binaries1.zip
Aa585E w8&I>+!IJ?*h9mS\eaBl\QT\L%aD/\t4?#@*XP$BSKpKSSc*D@PBFZq:?5^//1@LlEwD6>#:Dwj:j&!B
qADFP* *Vni*PkP@>?da*E+@H?jCAL@\$RRNn+BHtHj5?Q<1V9C@&L?@j%>@@?aj*@jX8KH=6>9Q/V@<8Me>#en
9qM/bJ ^9hN:H=w^5ZlTD@G@wQ^GIhV@VF&M=J8T/#c9<D?k/pIS@+Z&K&NiDme?4@Ad4*@CA/Q@Sja4ZN8+Q/?
ne\I>% he:j5TT%4i$&j><<b\55<S>wJ9\LLG:4?eZ@C:pm@5Q<+9?FZBEJY<<S@q@IFWH%H<d:L?RKV@+H:L?R
q8lZ#Z 1*?$B8L@lYB6y9LcCp9A@q>kej<ZYQ!j4Z4jpj<H5>:9Ic8dhn*m*?NleRVCXlqLmQn@F*c>>NREhpNa
eVAD>@ ymhGMn$PPN1>*!aW*\pbmSG$EqCSkW!:AW5HaY4d?Kk!YaDPFDmLXlGLc?tQSWuhY5AmmywF1VZe<JFw
*Ch*Xq :$+>dLEIJDnt6>lWjhA#!mAhD^MKmBp>WdEW&8TW9tmmQ$/L\Q%Mnap6K9>$/M4DPm:hw<%VTPpHIQL8
KyE@>8 uqLc\R+\H#A4R?lldP<V$@elXL6^^6BnbYyc#=klGdc>@pESXc#XSp/H8=F8I*VAthQR9bP6j6wdI<Wu
wSlte+ Y!KSY?G5pl>#@1daiFlm#*qIcR\Q5iTMc@qE1%\IY&5hS6J=/i%M=5RqLp+?yT=^i=n:XDTWimI/iCV+
i6M\Tl yd\lydlALduh4RTX@C1:/J19Vm^w#/*hcdNeaIC9PC1qHubBE@uy@j1%F:9HL/KnKT^akuc5<VCwmNJQ
ILAkXC $BiphddZnkbdQd\M6\w?wa&<p!tlZVE9L=d\+t1hSEtYKd//w\:aJ1cXQN9LmT/ib1:Z<lF&>TWwS$&y
!M%:QS NnJc9<D18yDYPH#hHRa&u6&h*JEtdRLcyT@w#%BSEYmu1hbd\&a:cnQw6P8a/J4tJqNLDV+a8H4JV*V+
eIjplt 8B>ttNDIHJI!m9bdqeJWnqRk>LT#daYMw@X1$ZLSy*e%Z4X?NA\nwyiYl=XN/E#^^kGYq+8h6B/>%Wbd
<Wp@i+ d@bY5:SlAINV?nThPHVZj</Dp%&aQAuNIWZnLHJkR\nd8:aMa@*>8=&X:kGuLZ*mkTe/:LB89mMh1hGt
Xtc8$! ka?pkT!dP1Pb&F?6nB6c@NAJw>=u4\?ctX*^e$/4DTHZbhp<*c6cp&6#JWFbbD8P#?>=<MTI\#B<F$P$
@*c#G9 m>@>>nPul?+n$bqBwlu*iW&P&:%QJ+ukYtIY^dZ5>Nq!SmLqyDQ5^WlN%^MF9Z@i>$R\EDt<$MX/Wi#<
dYEk5: QkEGk^+wDD85b<JSJnV?:1QD4@l6ID@*&n!6ui/Dp&jTZc=hKS=%j<yY91%l#I@q*#H*pDTcaC>eilW*
JGWeLC !WcqT#^@?QtPRi?w6XJK#*:=t!InF@$@8AXwmQ+<wL=PeZcB4De&ha#p!WDV>pIi&cybDQll<A9TNheG
:Q>++^ Fte8lcT>YPH#/1%*S\/$e8bGHB^ai^u+jwmQHV&uGiL@\mDH+jq&:NTNc:uSbkwuPFR9qL!d<#8h<QKE
9Vij:Q XMjR\\nT5MYqh!1iajj*twY>JyiZcDNiBFp@@E#\+?m+SNCX8@j!qBuVThAu&6SWM?NmGLFaK9au?\5j
A4l+S% &mpm4l<69j$>1:lHC?c:L$#5Zw1GHNSYEc&^=&<lH6K4Nc8<X*X9&!9HQSRY+4!eT@py/aP1qT**5C%M
ZYC+Mm Z#5N5qqS&ePhB5T>cVQBWK^yC!Ha8%A/M>BD+dqdbZuCwpqHjY\YGIF*h&ud/caMXi/FC$:VJGCl1k:e
b?84\L #h9JVV$mhyuKMjKlPHV+?#4YkJyH!uXWR95K5@nRVW@AaA8ZR@u/hPWDl/W#R#FSGe\$1dnhS5uu8^eS
wbjHR4 ZuVy+DSB%=$NZ8i+GSIF58dHlK<F$!jPnumpL/P^dT*i6bNI^SC1+ZCBMH*JXKISA?J$W\&t9dBB6XCF
w\SAj8 LwX4\F^&RLKCISm##:9m>tL+@a/G9w^8&lQymPD>eMR!WHQ?T8W&65i:L8SSYITai*tQ+c>9W@4kb+Zu
jl:wIn Y&P>%D6qy5jFa&&PbW?%d6ipZ^GRA4acb4k:&^RbBR#q6>XQl9@mXcjjP*nj<P4>b&ua$Wk%naYqnBm<
5S+Ny@ StHFB=+V8ZGbRkn1GZ49Ahum!ITWY%TnP>NXe9l?IVp*XR#u:E:%cS>5P6F66*:HeRpPh>/l&LPk\YJ+
Yk<%^& Na@*^c/cwQN!>bNeXQwpLAYX:SiM9THc:mt1u1/QadMW&^XZj%JmBNI4:lS#!4WpV+N?Hqu$TdHmq1Nk
?^q!\Q LKw1^&P9j8p6pSQC9*yFHDZdBlk\pdq4=GA4FN&#*HI4Qb:QRE:CVDw1>HD8^@hK/+keaFV9#MP1XQ16
nh4iV\ \i9Ne%!e&1h!V=n:BD1T4?j=y/C+cMiT+KH:LR\dhmCj<KXqnYqB&c+w=:#8+N6S1uZ+jIQFtecql4mq
ZKKweJ y#w\<E*P5ne\Vq*!A*ayitJH/\/N5N&K@Y=>lI9I/%X*!$#e/X=RNbCT&P:LIa9#\$Hnm@NV9Qqm1^Ei
lYR5db J*myeSITJV45#8KFN6R:Pe8aVM5Q:IdNLc8!!W8lFS>Nqany^dEH*%TijHWiSC>FkawDBhQP9EZ$eJ:I
+VA65E Lp=*a::5P1#Nq!e?<54#4p>cNN5=95j!aD@=aE?m!qPheReZCcqZX#F!DY!%nd8VHWy$R=LHQw\1$aLM
B$Sipw d?q1V8=>yuJC$**9W%?d/hGjZj9GH#6cweB5Sb/+Eq>jb>?u?ZDYN8V58Glchp8Sd<8p5jyytE\9M:8w
^uLN6u Xh&nq=m1W+lQ4QhWXjc<=Vtjh9#I@V&+@G*u>l4yXLXQdJM&Gn@dE#DnYj9Y>YwZ/qiLb+>h<>:b+4Cp
CBLn5: q8eZk=ZL:=4=KKXL%EPnhdtRST=Cn^XD4I?ie@R$E8*wXK&9VD<$8l/6J5wc\EPPyC9d>N/+X:=n%dHN
A=1w#Z FYLLuETEP$5@G8:6+NpLE=?kX+j*eJcbkK?BQ44ZIWTC:4?Wyl5Buq*!%w@$6AqlEtCQZn@wQy54T4y=
VCSmZT pew8:PL^6PCC<5&lFnL$D1!y$hmQZ&h/J9JB/qD<Hh8bSJ:<:kMDu/!cGp/4u\ZM#V!Lh#yX#mh>kFku
Z^L8GE YXLpZR%&B^&54HJ%cb=?qT/mhpdB5TSMcE\y/Sc:>@DC*a>/?qcp*8ADJ:9>Q&Q%&*dG6Fuhd>%&jdu>
IjHCmp 6p>m/%8\C:5IykJ!1LAlb/#Jj48K*pNy@ZnI%ZQ#QcjpQMmZ8+>CR6p8/BwjSp6M%+nH%m1LFRhSyGc5
Cy$jnJ nmh5//eehpc&icK56>>!/%M&u?!w\>JjLC<ZeCp@M\548DthGtY1GwlX<#65tLGY>XKYM1Y%@%&6=9#H
yT4%$F V^i9wK?9G6:l9@1!H4#RdGS%V4V4Tpd+@yXYCeeCWIyJqF:BnuPcZT?5Y$c6#==dc?t?$!9lRpmFBp6t
9h1<FS 16j*q\>%^N!M4@MjVk^K9\Jpe4<j1n=GI%%:<$XCiiA/D\:#yNeq>HG9k=C<N$q%:+=HA48d+81*:by:
+6QYkR !/NRH4<1QChVVM6^jy%<l68y@Pjhl/tp#uER>!SId=pV+K?QMALW8TDbPbSN$lL:<&y9mqW5bEAwW%W/
h&IQ/4 $::qK@4Gw9i:PBKR9lj1!T+k9QE#1hAF#?M$++eKay+XKRP>^SlRJ5k:ttMEWY/aj+XtAQVZ=?lCtSw*
NwNN8e MPPB?kbPQ*G:RPejFit*:^>&YAI%jCp#Q4:k8XbSHI%^VS$y>@IAi%Y*DXWCLZTB16!D@h^<M@&HWm4b
Cai&ZX \dhRmad6?91>FqR^8@Pjw@9wS&iuLhL/F+1@DFXEn6Ft:XGjmhl>9J=$EJhlZeXDnnpG&DNaQ<A8G>L5
MwE\&l +9<IE!@/baEapQV?68F/9tF&/+ZR$KhSM>nq+i+HV8jyN%N&QMdMnmLYJ9wAaebL!EB#8!hlI164X!Fu
9:clR9 ><9Rc^Y/R?LGu1:tmD^4Gw4FP*W:m=#Hcy/Qc?K6CB#G^9mXe%b\?&T=atZ5$yQT*BR>c^jFbn%ZEuH:
<=p>^d ^H18$*T6$4&Ay9*qy:n&mwJMCZYF>6!H9L9Ie?#+wD:@F$4N%!&6q6Byw$4N>m<ZBAY1Bt?ldmMV#y>*
CP4V/l T^IWkAy<PRd*HX#I!Fl/XRj\J/+W^Jliql:+YbD:mmBPF>IkDcX?Lp>yj@9!WBLL9E&I/B9#$V?y!tiP
ltBi<6 94!<I<hR:=uPp1#8=**?KT6<*hJ<jT8DEl$4CIP/!iiDTWcJViCW9Lw8D9$TGd+TCj*#PuX>a%a/hEaY
i6mVy1 $:jWmeEFh<C>MXCSS5bE+d&a4:4%S4tcDyT%9I=%$c>NeNiq4%8iFFyhW#d?+wHD<>C6Iw&:W*ycQnH4
etwlah VCuqa>DI&8u8C?pTmdjHcTY:94#t?NY::hiK6q>jA#u=5<qDly!AaF8h^\RE&dJ4N>5eq$4Xq+w=B4B>
\!8H&a !4jtC^IE>L+\ZV<k<Pw=@<:B=45nFF&P:54A=+JewIB5aP?eXD>Q8R>u$9:P##FBNZi/bJY6@R6GRVT1
lEYRKG qY!\8Y4tZyRl<=$8/QXcn^VlyQ1aR$%jn!kXN6?aF<m%HmwE6DKe&6jFw&dM#K9wjBt<Tp\R+FLw64JP
5i$8NB c5lT$d^Vj?1J/yGeh9iW+VXhdqY/F:jPk^V4AdYdW&9l+u6TnWS$dwCBA:Ca?>#bVnMX%&R8GAlF$eDV
d&R6A6 &V\EkBGA^lQ<Jh6DN1tLC\==C@H!^wWcL!c?Yiy48/&kES#4J?h*QZAMqn4!wN\t?Qn$HbqZpPH#tPM9
n#nYPw :!KG?wa1<9RNI\S#LETtJ/HIL:%etKhDLch\&\X^kcctN@XjC1qpFuclnQZPP=!9QXRE@8Jb*%Run%mV
a/YjNQ C*S+4ki/A/m%/LaMM*!w!$qeW&HZD%TFl98mFntF4IYYC*9/!!PHT9SljFcl1uqEjGM1t?YhB&QGZ!+p
mu^P/b 5\Qi!kH:A^??YZ<m%%Jq:1YDi*?PX$!9BFnqn6I9\VbR:*FXa#=ZBbJAE%h$y18X48$I!c=miybQ>%ab
9GiKVd %^A<n9NkX1K1e5?ZD4:4wy<C8Vuyhh5F+I*Z>y@Tn*b+?8Z?9K%n6@?ytqX:G:46Jj>!jXbS!FJ1L<Gw
!pGkNW >==LuL%>jA:qWnn$ScdJucTkT=*9>IP#/k=Au1p=^AYaBtH*tRq4B6h>HK*Icy@*ZA!NKiQ\/D&ykZaW
HT66*+ 9FCQ4dQqHF*CJIS/L!bF!a/yk1IlbT*hXGtGjwm:S^\JaYRnCtcwnM44lepu+=<qp%h=*uSP9%DwdX%=
aGTLmj Fjje>Nk#&Ynp<@HZlnT:b$hPXaAc/T<pPP^MdV/HAMyNl%:^uh<t8J#CV$DGM<*9idm1M45@*A%uCnql
H*kXPF PK:IiIqbbFlVwyc9JAqeE:*1b*uV4W\j1E9jn*<m4thcP:*<i4/HS>tP</Ji&B86>L^MFhFZ$eAQ&#E&
p?J$&A 4>MP9bLVp^PEKNkh&Wj56/t+\\*m<SeTK%MRXday6*4qFiLX?m4H>a9X@6jK\u46!=BdXEK=tBjVid58
CaHp+^ cK>^jlGZV8&hRH<P<:1dwlmP^@/%5?W95pTbjlGib46/\MwY%#m/IA:VE&YD$$@G*8*!EqhKedCHWdQW
VCMqVD R9W:J/&+BR>mLSmlBb^kt4Xb!^HR9RN$T=#:A!\>G^!$4t\61%>6aB4Ah%lJA5SJ%GeHhVB6qFn??AM9
RIS*NL Ai*?PjyT?4Th?@A4BiDnJq*1Gpuwk4/MN8T\mmhyi:?X/W*Q9MR*#5hFj?JEHHRR>XX>>HT=qFCi?Zl&
ta^y8m etJ!F!iQ^NIEqbB*R1/&ENKCNR*JcAKLMwaK?4h>DNdFl5i>aV#ZTH@JX#A@G/B#%>V!HZ1Bi4F$$pLS
ZBtCtA tc8CuRh16V@L/!DW!m&4&aKYa!X&@HDpBZ5n+AyK!N5Vb+5PLAyP>!/VZW<y>dH&^S4<6EiMEi<Rylk\
-AYyTP 00006a2485d00110333 Page 8 of binaries1.zip
bMARNt +CT@EG>Yt+kqSyZJu8LYn#jJbjkY&9PW$jeZlk/e6:i!W4uQt*Ge>#n#:jG!EMjpPJw/%Cd#:CmS&dn&
?TQJ=M YM>6HC#/\6mtamC<Jw^aj>6KmBQkqtBG^R>SH!Y$Kh9pGPBNh8F8Kmdmn$<@ynZANK5/G+N@SSk#Re8%
:IJHwY @Q1J/TQN!/w>IJ1pAI<e>atFhM%qYG/HZLl@/F4uE/JXS9$wj\tD@@u6bLnI96uPm^jP56#yL+C@uCFj
qL!Bd= *BZmc&$DI+%/G6aWPtiYJ>/eJhjibP>>j6bjy#FI>M45R/tJyjhDQ#QMJY#4ZeJBQMCcP$XqnPMqZFn^
TGy8cV =$I*b?T8hL/8GkC/E#n9j!B*6?GRZGh&ectMGb%de?e%dA64D//T#!y:1!Rw5hj@wkS$PTPkRMiZ&?eR
6wBim& aSmCiHuMSu+Wj16k5Hp+9HuRP\LiX\Y>!ZY1bu&*44*e?<X%I@AH*@L*Mk<\+45FcHe6SuPp%==Z\Z$R
qTXweN ZYlwV?@l5yL19t1LB*h#/18k/Ni!IWLRCRe%*ek6w/b^j>:Z?Q?N$b+I^**dZQ!@M>wVTQ?>$b:+Q?YT
Wc=ClT @=4?G:>SmKVje<q@*YqlM%H&Z*LJE:<tLQ=lL9p@bnH@up6?M=*&u%Nud:G6^j>%L9t9md8Jcu@LA9@:
%iW4nB 6lad:h<ykj/iIZ@nk9wjpyF@*R@nY=4\:+t/9&>4<jY?#aj@KJQ<%+$MXDhVyK9>upZ?n=uYN+?l?G<=
dXAa?^ ^9Hji6:5:Z9P<W*\:>uP9&?H<T$4?8<<?D*N@H?=1\Z&i!4/*<:\@:!6^b?i<V9&P%G118y@VCZ@%+u@
\%@M8: 9>#Z+98Rj:m9^Zi?dFZWmdnjE::@iX?L9?S^@/he>G4jF5KY:h<#!Z?h5e$y*/KwE5lj^iCQ8i8@m<Q*
+Xe1Vn <45wjBiB9#*p&$+Jj<5!@%$WN19@IyP<WVnD*<h>!%#!^C*M%@>L6l<e<Y@yjuBE<4>%/lG*T8iDI@#h
\4BNkQ pWH+Y+we>Z?\/=Q@BjajR4kJ/9<Cm>9ceWQE@ln:V+/19?i#@#8YTN:c8jd*nQbdaLFdP$D@u6Q?:%nC
#5!B6! Q#mM@y:Xjk55eY5u=6@#&9<h?+@Py4?u69>9\H>JYjIh?u@!?u!Q+Fa^l?PJyL<9G?IYYW5&NAH&@+9t
k&+wlZ @t?m8h<j>8wT@D&cP*Ep?^jPwy!%ZZ\YLVT%6PN?c:584jFc:aJmdjkBi+/#q6S8BC*SyJ8lytDSG?\D
NDR!?L D<a#&A!bML:nD/$liuMce9\*&CEtkB95iuwQt1i6Fq59X*im?#B>u\\9uJi8>=%9YHGY8Np/tNQL1XEW
1up+!a lyX5NJ&G*h:#uP+Dk>TnNGDRiwLu>ZkBa%eaXAbmXch1+W8DRe\EA6kH4E8HTbim?&n1#itNZ$P/DTW$
&EA9X$ DDhD8q@JRMSLMtG=c#WNl$4j6CFa1*Ge\Gqt%YbcpTeJSDuk+@kPq4@+TG=?W8?Nmq?R6/$6ktQIjP^M
#Vimb\ M?F$k8SVkpySni1wTin4Ja$MRXQP*eTL\ZTak=t%\%mGaH*+iyhP4CM@/ZkyX4Vyw8qqmK4!$S6i<TL%
Je*Bd* V8P*w%PZSJ&P5&JW>Y?>#jJ$J8m?k$EFmbi^VSF9:$R<dk=#?+X+cVy5H=llalLRXFIuetm9YbkZIEF+
p4@PSu JDGa*yL9qtWtAFL>#H&AGdLubnYV$&4<4RuJ61F!!e9i?G/<1wT=i4/qwMeMJX+a6L>LSHlt@QGSi>iG
K68GGM qL!!?5W%#Y#p?n?J^C=EiN^FZhM=9W>%u:Kp<T>:&NE!tmc%#Cj:*dLI8iQt$ThPH4plADwGA:?48^Hc
Hi$Auh LLI&IElphL<SXtZ4Mwq4C5/*?5#HiEmZ9AE$*>t8hi4ShRXXRe*#6Z9aa8p\#1I!+dNl*K@$l$HN$*8:
/eSlXH dkBLGJjYDnT>%TJ/@&!4&d\>#L=Y@?41Ha?Hwa<nyWmEXC6<#<Qd??4&cJw@Pi=IYAqFeVyqP>5QyP8b
>jqIc9 +*=Y>u5#$ct<@YT^X44L=dAA&#i#u/F#S%/tHMpmHd$MCnyjLZIyt9Jm<9di$!L1E*elV*p%G?ZcjW+@
lZi@\> jc>h<+FSNEJL6u8&VFt/p5T!lnXtQ?LtlH1wZE+aQ:d#>KpA%Aj?51c%du6DbHlk$%lL/ZYjEamIc>G%
W^MCW= SJ$Vih8HuG//>=&B6h+>E9@#$@hHjJ4G46%e#=jaha#NA961l>9uN#599kqw9/6?5YS6l<Ak%@=S>WQc
6Bi$/q Fd=6y?F+T/ZyZ\45G:u=jcShi>M?:t4*EI56eRRFTGCL\#%:H=a!HWhK:$uLK+nQFD<EWScEE<q%idPt
BT=+4t 6malZ\R%T945H#nFWSRN#!EyFRNkJBqWcYt5tBhZw%%\^uyy1SWqR*RG9%eH9eVi/F59HiTuGbJTqi>j
&B/LYD c6+Sa?eWa4LCPHk>6K4=yC^TwjiEa:WNw9!Pu/Dy/JqMlEhi+5>nCFeVpRSk@G!>YX!WT/1iSkM!#tYe
A?iy*V +^!mP<PIi5XEqthJ>RTQ1+u\6FZl@Wy*#<YPA\m*5+>qhk$RF?!<lijN@j54K:WX5^y9G?wJP</@$^8Y
d9Za$m un$:j%tL4dKT*/LT+*aK>#t=TTSu1pQXidId%M=bG%V%Ie#WaVm9I&Rq:a%Vkwbh=k*6aIJl#@9SuL8H
KAGXHD ^l%>jmGwWBVP!+<qn*\wT^8hIG9cB&>H*LIqYi#%GFRj::Rw5V<TQca$CKkSe*n%^Y/yTBS^1Qm$D>54
$#Z>C$ ?:/R=<CwMu9ak$NPR#=JyJEuiwK:E!n\WW%!/X54<dGIWJGIY$%\&5L^aul66teSkq$I$8E4d/H@XE*l
ama4%$ 9PtEbNX/tpm6iyGp1EXPRc@it\?1VWuJy64JhwjaS8=j9?Q!%9hmnd%\\/:t5pLjjb^u#hHK4^HE=1th
wL\aX: a&mV+PdI1%!Y/A+#<RmX^cM::klhW<a%q8c>BV^<dih4yuqYu/kc%tN%%QtB*PWt?jTjH#*eHtFh!Pjw
/6BM4c &!%PyZ9uQZj&eX+:/6G=C@E$S=Nqh6uVZZ/euX^n6YS&^@nTPbQI/LtQQ^QZHSiHVi+Gy>Q&/?ujHVSi
\%Ktp+ :\cLldI*C^ql=e9iep\W9Y>>IhLG?uR*:4HdNZPI=15ya>pX^l*?DtVS=PVhC<udA?XJLS/^de:BDXQZ
@<?n$$ kA%1Z^b@Q5KtJ#TF6y>MW$?R:Ew@9Z!I8KLM*%!Yh#H:Ei\a:!$6q>=Zb%u>%/?bBEHq9i:<JMLI><*J
6=F%FS XQM\>AuKKXR&adR!=y>N#plq!J15Dtu84EwXa?:\kRyPyet#M+#ajA<qXB+>M8WI!bZXXbV4Zy5XetLI
uddIEI M5</F:ItVI*K6BY!ZyZtYtZbp6DNij#nc1w?V+GLI%cQw<$Qyetj+DQk!T!epLNPFF@$<yuk8FBiPtFA
l6KFqG aGSZ!Ga+LH=^LQj9Da$%PjLCVPl/VQ6nn*n$tIVbIhLqB>hSy<WVwNtV?t*6E=eLbN@eEKd:tP&*<Jmm
e&C9:9 i%++j5uQqFZ&YNpE61LeWXI%\TFc9Vm*Zc\k4A6==9QWe>4yuH\cZ&WQIDdMKqFp*bYVV!LuyE$bMnqA
!Eeu#C &YjhN^n%GAPY5u#QWFK?KXG\&P%ZW%K*Qk>nS?@+!Z*Gc&/?/tj$Xj:e^t5ynkem^^IW?yPQq#cnh/hN
RZ8WAH *B>j9#8E\m+a6iNjDeLQ^l+SS%YePTbldb>Gkn#VHnuS%dbZu@*D=X%:#GL&*GENDGPy=%JcnG%uDZip
ePDeH9 #+1e^E>+JSa:*@iJQdT6Fdun$?Q=!:qBMF9:!WP9%XtYqI%9J5j9Dd>@+tet?dQ^K#=HSNEDYe8nc^ID
+6S+ML 1bwQiZ+?$=8p+q#9c1l/1KbNIVLp^yFdi&<Y&ZY@t:Z?Pc/h>:ZW8+GVeRSu:=j*hp!:DF+$Dd$#Anuh
u1!:hE M^qaP!\?/>Jl+d#u<y8j9TX*AqV>nuC4HVc:HIjB4Aet*utA!j?W4&X@Jh<ny/dE5C!E<bQb^j9Xkc/j
4YaMcW +!RJ:1?iZm!RQ>1ukBh#>St$X1@yDZ@d+H/&MEL4%<ZFe*&F:+WI!W**kTZdc*w+4pNXp5KDZAu6Fd>W
Q6EmlS T*#PeCwj4DkGR8V%NWP^MBjYYCT!Kec:Ly8=e1n:pj%R@hJN<!GDS&qwLi*B6jc$9nRM:h1#^^^ed#RV
5>TQBc +&KGu:QXIFQ%</mBwa\uu8%^E11!E%4ytW@4>#6/6X>h*M$Sc=+l+H&Kje$WT/t8Yhhe<+cPeCebP&Wy
bpWyG^ k:JT4+@MGw+1w8!W^c^><NbDP!b1bZQhuMa8$A9hNdn:488&><i1jCcYDbL1q/<dV=C\?$@$DL><?nqE
q<RK>y d^nc==9Mtk@wVYiZ!\MH%yWQiD>Spl1aH&:t#K84uJ45w4KYyw4P9=yKkpJZpCR5?w\q/APEP&Qct/R<
!h@dcB 6ThXSDm%+1uSb^/B>a#TXebm=!M#JnPi16BndJpiYln9ht<kyR*5Q?t?>QlyFFRq!k!45!>yYC5LVc19
5Gb94& MpBN1NB>FVC\51itnV#Ii?uGFwdID+qY^S!LjM?p9H*<9XA5</y$RW^Va/JX1YX:RQWS??E%9hXq?=6T
V*LHA! j6Z:TTupZ?eh#PuQyYye1qEVn\Vj9=^jQBja$mm:Du%Tb?IH6DCdTp<+>Mwmd=^D=!Nunb8<XH9/i<*?
RMEE>n !&^^y6QB8&al=k!enSh#8I/=/BVp8lI<Yde+*nHd+qWy*#FLuYjS4kt&QXYTYtA?Y1l#nX:%+Pb4jVI!
#YH>ic :<dhXwBy$&u9Q=4a@TnLbhEnVT5:?:n=Cq@wPaZlX8lK!8Z=c+m+hRm4C+%nE56i?R5NQluP/AEnH8HF
8@TBP8 =1hyRjGjFN#uLc^5*PD>Q&GVd1>&G%8+*a9K@/#<95wp=VbWa?nbqEqR<=eZ5%$BD>p>w>tXEMQt=QZn
EuX>i% #Z%%u86JLCi\@@4^EVQ?nZp@>C8#L/&#cjn&=:6Sa?>WMn+VuEt%J+E>b4k%c%^ARZye*?CF*KtkRPkh
F\he<N b?BRp6d=&Y9e$$G^V<qhc^\99qlpkteFPaaIqAn$w\@Ym1J/p??Qy=VjMj+<\nGE4dne@RdeybeiN@#4
866?ZK ^d*pMB%V4?XjZ^@Ey5i+ZQCSpKNkdnYyMcQk#DlLGVAH>+Teny:qdCGKw\BXi6aaVm@C:MS\:6jT9Te1
8j=b\W @?mR=+k:Fb^iPu%e#@^T%T*%Y*Ze6^4G=CAiPtX/ekKY%y>LjK%&6%hweCJR85lS\Yb4kjdS?4/eiF*I
X@G8N@ LX&w+CGN#6X:/b*u=H:C%FSwi$R=bniq!d/=&Ji4!R4Wt!:p8=l@lt6P>MJnlbD41naJnpuwE8@FDA:A
+t@bp6 w?yWYj\!u\qhK&u1y@kY<:nFTKRpq@8cZwt#<b5BnlL*dT6jJ4JCpdYBHyaNK+E:IIbw!!nc:LP1\>XY
:cjeMn =9T<S#*6FyS88?EYalnKNP16XpK&$mIKGXLuK>lAcC@u+&m#:=dbaSCu*@9e?kpYQP4djpLK<Xc$Yh!d
BmKCem Yu*XEAW*VyCRb9?e!CX8V9C!\#VhbjF#qj<4WNL/lVn#&<4qiuQQdR#Z<8G$FK+*&8Wh6lF&yq+y$ckJ
?%RV+b C%9D?=WP=>!Z?E4HIhZA6KXb5/l?#eT*K1Gjd>V%NyyFRt8pZE&>#aMMTZ4\:6YJ=+PGX?KiPA/?ceMu
YC=XaD ^A+ePa4J%B:RMXq!Mw94dL1N9XKV<91&lc55*%XLF<Nu=n*h=lZn5p*hYyQt4T9DdT+iihHJ^:YR:wTd
ay>K^6 ehe56K$!/$cMSEhKSky==Kl\&Gm+h\=#@^kQSTW<Aty?$/BpuD8:JhbwWT8J^qy6Nju@5Zj6aVXtdX@S
B$$nGK q8\P1J^:iTP%Jj6b/#tYHCa^PmjF=E^IIuJKSW+XqecanBmHSIqIwl!1wYu!PlTXVywe^mkhuI?Dl4iu
B1FHwL @jCP&i5b/*uun??:989:c%>Z%*Q9j96?:6>c>:4Zd>&4eFjjhT@A9y6%&uZDDByqh:NTN:BNTS5tFP<^
-A9WGu 0005c8830b200110333 Page 9 of binaries1.zip
jH/8+H eZ4mb:^V9*@y$$KRF*:P^hh6<PHuW!u@nRW4ja*/VQQc:ym\\HX+>JCPP/nc>HQjyY%4YQlWNmVA$@h$
K#I/X& Rn*qe*%8kEuIj6&=88juGn+b?tTJVLebGNH=#^6u?#8+!L58eJX:qY$J&H>9<MDSA@dQdH89MYl>=@%Q
n^%iCl q44P*yFWV5=cN&Vw%YXX>>:&n6TeH*jtTqFGR:?l4w/FC1P=HwX/$je1q9cddBCny=Zy96!5\jbA&/DA
AWQ#C% L@$#uAL8YT$1&%tpcFwicdtRCq&<ipHk@YeLFL>SXQDA&yTS#&KY/y%cP1jlm?ep+Sn5&QC+:4:?Cqth
&&dNaF *CXpyduj^eH*Jq5iN%Mt^y8*c$kwah9XcLY=w*i+IYCt>#cu^9mF1<PNL<Juq/b<Y#l9?h98D6uc?$?&
H54Xdd V\<pp^?QnDeNT+@+eb98&wje9BId#TC:eAP:>9yH>eIZ4^&$P/Lic+Sh\@^Nma6mtuN46^q$/1QI&Gdi
w&hh*u Md4Da@e^MV9JqATZIC45\y$y\/6tBFtE8W/jdVip>mhh@&q8hX+ZJ5=<M9B^jhQaC//DhqCtL+na#Jm=
LC\aGB P&M5H+hPPJFuAC+*GeT8N%XimTl!jVpeyteE6S6@:5/!<:*&byw#@#SA:$CR*Q?iHRn19&unA9=V*@6R
iqu6$^ <kMj=LB+Ld+JXkYYaBulW@XLCI+RQ1H\KV#HCe>^18iAWtkpA=SR?AMqjDLCy@Ck$HEGCPyiIHkTjQlb
ePd/=Q kBAiBMKDRHkRCA<C+R8B<B\Wu96\eAEIjkjCm\HCT\Gp<CAJQ?qn@1GEBEkcXj1p%E8BFPdNnaS/a*y%
YyRi@P Y=Gi=IS/b*1E4enbAI4E5BW=S$FSGLbKGt%Lj>/Y+6DuC6Sd^mN5GZVnDQYt<RldCq%!XY<dn:Aq$d=T
Vd&n:t d^!Q5CZRJXecI/=ID9%?ca!+Iqq$VNIaeWYmY^+SNEbepST/LE=n^BWJSZ!FEXepIiI4nLkmqTK?\wk4
9j/$B5 !I4+CmP8IIQ&FaMSX*\*hcR6Sq^BpZGD\ak4CNC?anDmC1LdYlEMSq\BV5SZGHEq%8cH\ak4RIu+CmP8
/Y=WD5 ?KpGca5SX\CI?Awn4wDI8T<YI/:+GS=ym#MQMtlj5Sl^^R>MTF8M8BLhZYLJ9&NM1X>DMByaMb\T<q9H
/ydnpu iQeKeF^4*!YK+K>wy#>@4RDBa5RpVcLu*#@%l@5Qa5nuejmI1bcj#mPtPAaHMa8VdcBu*#>%q@5Dakmq
Sk@<e% ?Jl1GY=dEdNKDMReBk>wpZPIj?yN>$jEqCRj6!S+4alyCke^\Mt5$FHBRVHEwCZypwC+JcF8SW^!PIk^
WEajHP 1Mi@LTSmTlR^A/RkdqqD6CKGAAe^V9bKw#NRVyS=9ASFAtKq\D\Cl*peV6=LwyuHwblH6mDt?N%&jMRp
Www:yd 4%y1RW\K6=V<JYKk^Mta$SpGWBLmmEpymGuXiE!&yB$amHGal:=nB!mlCGKYbcYMFYVLiN?K8GWNk+Ea
yjS@<d J$6H4<KAppImbyYRJTkymKFTlbkEPIl^<u6GJCwaEeREwKZMIH^D$XdEkMbB#PK5lBk$ap+EMc65!b@\
Iq14?m EWNPaB/BMieBAwN=JH1hC\lC#Me6W+kW^K!KibDDaS/B5<wFcPaSWC!PTWq^DGpX<@mMD\M^D9QR:YeB
$H^^Xt Iea<\HJTblBI1bkHcS#tESnM+><YEnEnNl/#LX<4AVFWMR?TPM\neNdpDJy=lBn#PJcTMwNAR5W<CHGa
?eeu#S B*BY<#S!^RcAGQPW@HRwAdG\BwEED9MAVl$A9RaBRJS=qCRjA%dFQMDlMA?RPJWLNQPAGQNamydma<Cw
d&/pnA tAhaHPaBHPaS/DpQmM^=La9HqtFiAtJK^V^A+#AQ+FR6$K*AAiDEEW8KC1lmH1>N@#^mmME<kJd^AmnC
F/Tw=S 9JbBuyHpa/BmHwA+#IMa#AM$i5/DWB\^qIJaKVCQ\GEi^KuhWil5E%LmmKZpd9!C9lY^Ewh=EKj1l>:S
d=pJVW AbASSe^K!T9+pmiQtC<!aTDGaS=cBk?kCQNcBmBCpw<yFjQ++9VuEbM+#EQ*I\ipPQM+Ke#nqjm6mCpe
FJ<APe =yE+NWwY#V^TqHpWqDK/<e&tYlFDBke^mXNXSe>=u\4?*V=c@5Zqw^<dLLZK:6X9NkYjukNAjKj/>cMj
ILRNJY =j56*\pll@lPSq*K*$IH/9<9IP%BZ!i!YQip8#4/t4#e*>9WQdXCi@YqZT5icde*ZdQ\X$&/S/p5*#Gy
RhYhY^ !pm#%!dLY@y^A*/huVB%eFtP5aGdk6ba:caM:=9mS8m8G<n&PFjp$\/P<Qiap1LXN1nGYy=?11:S?5Id
pAEya+ iW:K%=$n%9YJG8:d!#d%#EV>9idiL+#ABtXK*lwu<+Rd@YJ:L8tb/idt$@Pa&&1jZ8iK?/$1ID8#:qyc
\b!Bc= l$!ZhhW1K6M!h?m<&X*l5Dj8kKXD/h*MkbhLc\=cFRa&H#M99CdQ5!#$<Ep#VCp&iKBujZ65%4t$1DMP
j&/beQ 9Y!cl4\<aJF1?EYQ!I/hQR%#t/\NtlNGdJ:jjXTMihwN&RLHJZW@Hquu1X8Th<1NHL8tCISj!#>mXcK:
MuT^!L /X1ywV\t6:hJ8b6lVI>#V6Y?N<h+69HyZ8c5MP/lbXC#\=CqVG$>V4@\ZF%W8hR\@yJHcW#!nRqhlyV+
q4=VCR Zc+wPE+XbyWhD=n+5ndjTpdeh8jPHD@W!T^li9#e:6yjQ@:Gn*L?db/4*1>JY=&!cN99y=W?j^:jLiQa
^aCS+> nWFlqiYV%=hQPJu:8>N$i4Jh@&McCdNL9F<b\*ui&+^6at&1KwdN9>6X^lAH>&bi6db1DQbjP<V9>%>:
MFI%+q lG6Tu1=V!y=6MNVNT4Lj?T@QXSbdb%lPGhBZXypYpNDA%c*W1KAK^mjY!:h5m6Gmh>668i6>e\!<G@^:
R=SK8a h64hu?Xh6%aXDT4haGE+5P$!:8l5u@hW@eVqH8=FSq!$u=h5#i:5mtYJq&6P6e$yGX&iHF@8E8L<1q>E
^t$y$u Xbei*VK>+t+h>S>9pqjwH*4#<yZFI=d*nJ#9Xt?w$HJ>*8dS4EqPYle<!56Z:A8kuXebL88^618Gy+LS
?!jG!l @THAMH>^&G>L#1<b4*C?QhHlcdc?ViH#wYFJDe>6lw%&ZZI<bYLYli/BE?Pn6u?9a?HyjG8Twch6:l!N
=:!tW@ 1YQHZ@W1jSG=@Mam4>q>X^:d>uchYYVuXSt%qY&9BC9%NMD!9S4V:KdRHV1h5Lb@?hIq4>4XjIX>q%L=
MQHbE8 JHihAYaFa$ac@FM:&uC8*H&>^d5>Fd+*QP:5GV%:w/pJZKSVjw+bj8FN%=:WTLq#tbZDkL+c%8pLjLeY
Mjl4yt e+6pC\*d>X8a*lpMZ%lmZly@d$yi9Mc*+^byG@dXC6A^%p!#nKk\H<K8T85#@Y^$p:FCWX9W&epnQ!11
mJ!AE/ ejDPhD@=qtBj=+QjkPT18!hNE#*NN?n$/yi!5Qyc?mlZ4bY&J8QijNHq6c$5Tu6hF%t%a>V4l+MXq4py
T?=ynb =j@wEGN8@=X?:jZ5db59dew+H=T<<YWt>dJ</5RVHn4Z&\:#nYk8hR#%LKLh$8>F*L@q:^V*\QLm/Hd!
9?Eq!+ F**I69HKV5XP4F^u^KZhZ/eyly&bXZG=e6GT$PF:^/St/TZ*h*m#9MkwQD6C5*mKW/bH/cajD6G><4<1
QdRG$+ nb9q*u?c+>KScZE@*hF1$%^qZNZt?wD<*Z6k+!4ZmkJk=8G?@YDbTYJGaa%b>PLbc=^>HCbpNH9&:Ly%
jiCEKd %MdjV+@JPVBy$1R+J=hIq%t&%8cFB*eXH/#itSGV5u6>@l14XY$K9d%&%Le^*?/4*S$WhK:SYHh:^:#C
MC@6Jm S&STVP@cyb&&*4+^4V$*\#>q@hQ>kZeLD#1aq>b8Q:Vj5i>%lcu@Yd5##@iX?XDH8Q1ZJaZ9+k%$6tZ?
^VLLMh >C<\>%9*=I\&F>e&!q>>H%P/+P99nq\5GQtmc6?#MMYM&M\^RSu>HZM*QnTJKV9EYXXRjR+NL6F\eWn6
l?^Cjm cnKB<aa>M5a&DZKe/@QY\eL/^FuqHPeWSW/caj@HqjTDtRM9S*uEnm1dpH//q<ZBt^:Zqy+=@<4@$Q*A
dMkbGK C/F%lXqWSPd5ibVF+bM/q/>%=J#!:Qh5:tL:KL/uR=Gt>:dl448@:ZGkVikS?=D\VcM&D\%J8=%c488m
X%qI>l e#Gqe6cEGRd\6N>lq=!lIbue9Kjue%@KuqVHcc*a@&LM\iLe/51jDjKVG5KT>hd?e9XNTcBGEu$p<+j%
Cl#Xi9 #MDht:/#C%w&jcQQ$P%PD+w$<%QVKlw6Dk&ib#qyd/LHq6kVHa%GKuc<*!*dWJ6/e8Am!+Ih\jFGDRP$
Xku4E: j=p#!c9Db4&>K#!VX@e8!e:WjnG*b&4\eXi@G>H=j6PuY>WhY&M%KP@\m6Hh9nw$M%Anp#+h<?M>b=9E
4NyECG jYuj8?>&5k1bbVquc=?l9wY9NFeS4>:FLdS^q:*&K:uhpN^Jee%?9/=^5uj+&G@h1NTRnk<*V/Z*nX/+
96ZuZ+ JjFa\K:y9S9C6m/t+w1<Hit9ekICNRwTnqSE!!4N=441##!VE988#=RN1TNNPmTi:dL19W%I^htKLqGZ
8e*5Cj k4&t#*T&&Hw<?qq:XqFe9G!1T&DD8/9hVY*JuNiGk=NZ=#<e<:w1%@6R>alD9tq%@ph#8<*y:ntn+4Th
MEH=ed 6=N#NuG@>6n&:hhem9jyGKX>6&yN$<PE?<5Dqm:6jC+ud$65Xc:HRSQ*&I#k1>*u4VR>pt#4Y@PqV1*%
c>kNK> @JBhT=/Eb!W@M44qb*WLjJZwi#L?>6H1J!6:b>9jTH$a8#Mnd5cJVa4T$PmA4AZ6!wIWnYp>&!:Y*Ek?
\?%w5M tFm#j&4kAS&dTbdybuh9HY6&>uH*<N#n<%a@\NFn8?&J!LM4Bu!bpdP%$MNEypNW!1+F9%=&d&b#q*F:
tk:T\% w$bZ^<atnH/hM*uj<b9Sn$I5a&h!\V>*>ty?E9c<R:qZw>:G//HYBahN4&e6Dt9V5HJk<pQnjYXVK69Z
IS1H1Q uB4!@5kw#?54Ipe!5Y<i9bKb9d:q=FDSu^+TPQVXlhAj1t<4Rk:<%nc::LjSk/1C\^Q45^Ij#m/#jX\&
PjA+nu =:V9kLncj:#/:8hh#:1>n9*?+1%+1tdH8%$#d&#M@PcG@9nFS&>jpa%:8KLGLiZ6\X9YGhPddJmw1c/Y
hl@LL: Tc+4*>@QQd4n:5%FKY>V6>YH>m5jt*uQQeJ5nXHM?C8Q*?!44*JN>q>?5@t66&98<y1Ac$?9&C!%LDcd
SLL?$8 tJ!at=^aX=>++H!9*#6eimKQj?QaiMh@4ae<+1I<!9#4P<<G>hW<LH<dYjh?kJN&awdGF/lt!+Bp@*9X
iJpL!E JN5H5u@98n9\1YkVW!kJTdZ::mCyqCKWBK#1<CqkBXtmIJ\EkuATCMJJIAkukTCeBIJ\EuAjhI/CelIK
/y@waw !ppwCCilIJ!EkuATC5JJKAku+ai&1FD\JlS?J^TEp%ARVpJBPApF+TRWlJNREE:1RpE=CRZqJBTEp^A!
ettiYV u\kpQ!Vtj%yCWGyLQCCeQQ>55&ckL1yW6^XyEk*WSbZ16mKNuwG/1BJlK%I<XlhXIt^F!4n1wp1ELX4<
@4=wBi B6SFqRldR5SZDIc6!DJeZXTydp8^/CK\81kTaa68MA%wnLmm$DiwASwn4mn$4YKA^wk4TmTica!+w6Cm
MSi@%B YWBn^JZahm&NEXepI?I4nLkmKSFjaeTX&GamnSFZ@Ca5$lan49n6WJR6k^FZaq6hDEbe<X8ETF8M8PI*
^amEia /=C&GHEq6lHDaMRX9+GF6MYIK$mI?Awn45T&CSmM8AK5mK<\+wwjVJG&GHEFSLcQYI!+E6MaAyd+P<dk
Dm9$$a j/L5!ELS4S^c!u?qKhX@yYtedRaYI=wbJV1cYWwWMTNqk+<tXh5MNIY##eDm#N55tpP5&DbDT@anyRSP
ZIBqFi A>W&A\%^N9laFmjDRVMZKiTpiDGA6I$STlC%<QLL#!QtMLlHw$ZaACupdEZMAmlJLC8IDLEEeB^P>mwm
-AaMW4 000c626453500110333 Page 10 of binaries1.zip
M^YmbE cpEKPX5SW=RpYTR6mA\bHL=#PHt9mKkFKiSW?bmXIlHlJce15T!Bk^mDibVICkEy=BRRe=LE5wK<q<Vb
*:!@E4 +PN\et&ShRpu!n^Kt8mdEPT>AEQiC=W+YVy/NRTXcPc^T1YTq5R<yeA<A8Ik^5u9$j&^wBKKIia91Jak
*BYSk& MlTE>TTP5B+1Tb\XCahGVIpmqnTDpIK\u8>&lwEal*qwWR6WM1KIwTT^4CC5J*GE>XCJ5^yB**+Nqb\a
j=w&Gk amlyQCaFaV&JI/!HBAd#SH4VRWJ$#1M=TjJiRXlQRl#tESnMI>GmFplAeeST^tNTENcVPMJ/TPC5!hG>
!h9#eJ A!ElP8e^pw+C<H*?YlE4eblH+K#t$cIYTInPiR\lbV!GnIy=EEjWAkpe=1FFLbDk^BFLE<5!kqkYl*pA
uLk#\B l*qKNQPAKQMacSJ1W5W<TPE\D?DWH6CmFklEtehIGw@=?4NKLI9DQIBV6WCLYmARb^/W=GPqmupR+DAQ
dhV:^< aDCQj%6I^PLMk%LmtF<c6CJY+nAQ5DmXIVV#kDn#TE1TYJaS^LI+#IM+6V8Abl+Wb^+ybRdlm<86mBpe
jntMC^ =pEe=1GQDWEw#n^JS\^=hbXKLI9DQEnm%N:R#EMKPYp4n6jXT=L*Ey\kq5Z!MW/qEZ%kD!KFuI\Xkc>S
DAPiu= =:NT@q!tTulK+?DF1XCK<P=VGcjdS<8@/JQ:WcVHm?6w>h5S+S>Ftl@FhZTL/@>9>Mq%!+yTh9PMc8&V
VB<6=a P$+bbb@yQtJD%c\TicVytlFuS<J8P9L1d*=In$\<$&S9$&Zb&SqLTuV6bbQ4V$+#6?=X$L>$4<LA@6Vc
qeX=KE lM*YPd&M%8@<Shdqni:cTY^5+TC9!?EZatDnqL:hin=+q*R@:+4y4#8M%k<jh%:#<Mut=KuXSej*Du>e
$L:$:c F1tS9d=Q?MB/6#5SI$:=Gudw/:BT/=SBjG&:!EHZ^luK%^*8L+>biNmE#C!8/h/iM+k#1TRZ&T*wq9e+
NeB<LV ^*BI8DLwF@$Cm%BKH9QkuH6*8$F!t6Z6>JN9HZh8dN$J1/ab:Di&@?d8Q<Pc&91%d*mtl=BAAkFCV/ml
^IHDb? B\khMcF*RlWRMcEJTG>mZWpkEKSZ5ae1ICwwImy11KKmAmJmD$%SWSFS5c=*4Z&6c?>>:dZYe*uj?*mj
L61dVa D+>jWD#PPeiePVQHHGQ<^@u4k^=SILL1X\@q>dXb!5QSG^Zp+TQjAJlyj/?G@NpKjcE<V\wd@:VQkH>H
JMaRA5 VJ@qWCYdb^44y\nD>WVJn%C1GA9ch/KSm9D*T:jSN?qh><X99=@u$aj<I^q6*cT9nkwiJNwtGj??VCjj
DM^/Ft ABqqF:@J8$:?ayN*NWMC?#+p46<\JaP^W^wuXT%P=:*biKC=/j1Zw&F&5?wKw\dTm4cc6=PW#jHP^e4Y
h@m@aZ C=4WkPWbVQG$4%X@yGCSi1=#adhG*4ZR48P/>p%F*:ZQmL?==Xq>hp9\%Nu1RQ?y/5\ZP?/i8@S<??bk
!dqCT@ &K@?>$BPtb+\$NB\48auW%Ntb>?BZ#Jycw&Bhu:95^uG@RE$Z#MGN6#GjGQqTT8K4&q/bMI=hW&=LT^5
t54>wq ?!8*\jSG%aT&nq%9L6?8Xj=<>KueE<nP#ha1uIa6M>:mPZQBAYZ9DW?=V^?/puSn95^WVM*#/^ZhNMEu
pE?cD1 E?@&!+ejL+5u!Y5Ej+ib8*y6pwHjLG9H%CcP>Y^Em:=t&w$jy>Q1^BD+tH8J!@LBb!ZuD=Eb=tQ?6\q*
TF=SFP jckZ6/wPjN8t8M:MK*JuV%SR8:9m#iLZ^/?MaphKl=JuatMXdy66nL#H^P:dQJ%X:Y+:LjyYt</:bp?6
TR5@k8 @Z46tpdL>?6y:ThL<%1^ajKhwR95:%jPJR^qi=/^9XQ?ADQ+HyqHhZ$4+$QqDtDkZh:SmLQT#>*KXq?5
$uS>5D 9y@MP%wcYj@<\d49Z^dZH?E%@tKytZc!#?FmuIm5C&:YHZ4w6#Zph88?!^PMy&Z>YZ/uw6yc>1qk5KN!
K:tjBy D94Sq1d:!LZTN#VyT/t&XuuWY$wH%9t</JT/HG!*NmPqp*Qh#J#iwuFE?88ZjC@e>!9<*bJ*@h%>mdeA
VKPZed S%i+D/miHaG!Knl=^ya4DiyEi%/YdcqcB!+B*?NmhSF&::u=KkP/ib+*a$=uX*\tu6b%$Qu5a9>JHeB4
%VuD=p dGG<%CIMBem8Xa=t:X*m9i>^6Z$&q/CW6%m*=+4V6?@#>q%<Y4$clS*@FqYSdT\W*t$QkPBXqj!%l+hq
M!\Ii^ D+!e^JV6CuHGFe&R:+&lAn^t+a#>68hQZ!NIk@Y<<#1H6ZNNmhlhG/4j4C6&c/YNKpebXdN8?b^yDNT=
MPpXqK *4ah9hh#BtE=b/KF!ni46F5Q<ihyl$m*\WAuTt=CX+yS:ZjM6Mh>6F&iyS#RYC\:$:4^\DXFT6R8TIYi
YCmtm$ YIFe>mGW^1Dj*wIJ9ZWFnmpNT%SPp1GbJ!STKeBWPbwCq4F@jphjHt%e%/bFh/Gtwb>E&eT?A>YQ%P:E
nWY5k# B88@NTjij$ILAE8yRtNlwCh&B^dcn8=Hb#j=j1TdbK%d@*BZatq5#Gc6+bVD4CINH>M$tK6Pu@n??/en
w>iWXE V?W%VdVG:%NZpC^mQDDZmRX=%lY^9jm4+#hnaKS=M>dtNMN!MG?udZ%aXanyp!1:q\HK>#NRnq&5Y4LF
/S$:1J %I9cJVV5GK4iSB+/Z>/%8dV484F#%H$LdGC/X>:NN^MZ@Gq6cGuZ5&<TL?$6Zp?/5L$w+Hy?@qbnR86Z
\1?#5^ 5=!:\?c6DeZ!m+>Xkmd$FYkAT$M6:EQFniF8+hy4D@uPC$%Lq@i:^MeBPtiiYTBRdeM9&uKYXtX!^#K6
aI1#YI ^:=<lW>KTS/TGdM/cEqQdVn4a&=iQ6n*$wDFecy4Ckk>@CmT<dI!!4al1NpJ>&LD%tD:C*#SBa%>L#Tq
?86Y>u 6W?DQK>>j!X5GW#BnB1dM:8tAnKqXi1@#=bMl4:QWSKQwVmmpwbQ#:aCMWhq=!4Qt+$jCJR=hARV:XlG
q6j*/w kWDAlb:H6KQd!44&hIb&m?<mVDy9iBbRL9Ad*@$1<I^yH\411u&=Fq?>wdYHP8Y!qXAj//B&bR!CC$!k
+AYlDe 8>j69b@yh9jH:IW4L1tJL/@j*&4R=4pbq<n:%P*yt/W=hd*Z9pPueun&1LY&Gt<C:R?u=J4D1!@L?=@Z
*aM+VZ *>LePHk4GJ+6hu@X/HNbt?FC>a/X+^>9YG%#ZJ\1+>K4*:I^N9Ihh+F::@FiChetAl<jEQjE*4^$B98A
@lXtBF IBwB=M$k6Z=:beXM<y/M^M4pqtC><+h%#^L$t%8Q!#/d:*@%R%Ae+*n/4J!W\uJTji#e%/FRp/p+&@/P
YbkID! #q6Sy4e1Dy6<&bthiLM<>:^=#411=TPSd=Vdmm:V6@d<?Kk:G:dq%Q85lE5!lSb=l4/Y\ttl@ldd/bID
DWMiGk +TV41wj#5!l\5W:qy$#4l/64PB%Qdt<RSNKXPIJ4H@a>S\%+BNt?+ZTG<%L?\+8PT%P+T^XiYnjStXad
+/bE\J D$S9##SFT8!+9&V!mn^W5LJ4ekQbdPPSpGm!#N/iS$*F&qqtDbd*qPdpW#i&:FjyN>n>@9Lbb9jZSAd?
JG=nE: !jB/#45C^j5iJ>AG6<YuWy+jX6iWQlX=VK8%<?QKA<!9tEc<ieup6hnikbC^nQCT^jmKV?CTptFPaT>%
tNL8JD &+St*MGX*1#/lCnpF1u=R!bdnSA^F4dL$$<pEKq%Sd6D4WauLlXcAjwG1MVA%<G4l4#l4/ZK#E8QH@pF
tG5c## w*8*e\<>9FkcpZdK#J8!6Q8SBXn5>jC&wYN/y>=@!Mqi>b==t@dJtT%*a?j1>Tu&L4S1@?46k5i!F6C=
Xq@q!$ %!GQJiMZ8H8%&$=Ibcau=BZ/F=>T9u!F@MWG#JX?Xjj1:Ja#>Jd%W:5Hayji^q^j6X+@@t*h$e5:Q^>B
&cQTSI utKBPw4>?yKy9ceMjjlLqk&=iVi8>#4Qt@EnaMjVFmTyn^weD*tFLb<TjD+%>c&Fpne9uDN<>5d4$aSa
6:9:S@ $GwBaZXE+yqiWbH*TS>KWM<#<+YmGyd+EQlt<QJmp9/<mj@dnB@J6DZMp?9L8/HiT&#^$BQwqBi6d^KY
9#/1AS 94\8yN\%tw#$TqwcYRjQ5=%5TEEaVH%c=pB84$Q5yc$=+=D6Maa^>Y:%?mdkJd8ap^N1q^HcB>bDFI!j
W6FucD CZYdB$eF#HWaCcSw8tp+a!E11n4ykWj:6&FtQPWEjFNET$K^SFdV<k@aJ6#X1D&yTpGy^Da^ecqWhX#J
:VwV:l ay6ETX4<4aqPqLdlS$>$ln$Cu^+*eqKdh4IlYBJuJt%5J5XdpMWyT9q8pS1QqC&Q&u\51j*&Niu=Ct9\
XMYWF< Z$e^t9:4*y@@6+5KVj>%E>BjFSYcYqD@ZFXwajKu1pIL+@?V1pJVe@N@Ldu:+*Zh%N#!L$49VQ?MCjqH
jyE/P8 !@>%wjc9l&y@*nZ$b?*j=Btc@lpV<lju@b5l+y<yIZ?l@b5lQNZm*&9N@taCtY4=E%yVp:@YY9&E>1?#
8%uPF! 6p#@ZB:=b?*jbNcb@4p<<5>cE+8@$b4<lQc9T+bM#Z:CX!b@9Vl6c9aV991:TlbVM:Q@njkuuGXm?VhZ
>*h6Py dQG@$Q/M5!l@w:Z/9>ic@+!#@41R#hV<J=^F@i5CK%Q#u*AY>Y?ebj+##91dd/H=V#nL+t?t$5#N@lhc
&iI5eN <#>NEj$:i@#p#NF9*eD9WTktQ^8Fat4?Q!lJ@&#Fj&*Z@H*K?q?&c@:uh54@tQ&^@QQ5#:@Yaj:FMj>#
Biq4ue Swu!u<e$@/<6wNS@J9:?!#H@t/*@8BjBQlH^9%@&j>$M6<Vji>R@?Iq8mcdEj^AT@!PB^<k%Pt=LdAdS
b?I>&e $ylwbB?Zpe/IVuNIVp^JV91>::Z<n^+&IVuNQ+WXGj%dH@9Hd6e@y1/MVZ@uh9&:8T8ATAQRElkwl<%P
5XIaAl wcBqJeH=D4PW:EMKi8nCRhK:qpe^PPXT%<nW6cwTSc$1ENDy=5nh1Fq!a:cCQE&RREK=HKa\%qIFm^^X
?T&SC\ <*jHu+=WFwM84kb*ZVh\dHApudX8CqLAw*neD@ELYbe&h\RuBNpktTaKGDmyDn8hwl*XE\cyE/%^=:d%
kGAnVB lt?h^YFL56B\MYk>!%Lky!6VcBS<ph<XbpTINNt\I%E@\pT?GN:AHHt!#*e5PnbnMcdC1wFVkqC9t%:i
HqRu&\ 5W/=NH<iXDdmdRjFPl$\REh/IWuapX\@a!XN>R4QV^<\C*bS<wkKC6D9S1+BQ&dDb>Ja%EQRmS6u9n*F
d>AiST tBB<!NJ=QDB##8jTy<?/aSh&q/Z=ApY\Ybcdc:MMt*$Rj/&NDcB%WjWhy<A$4nBZ@\KVKj8!$H+/1dKR
Jp#/CD Fh^nYDnYT?kWu\QAYLR/hqm/KIh5CHEaY\PL:YYLS9Yh4ueptScnkRpwL/K?F%q5D>S\uV8IW?cA&4T?
y?X:Rc iT+ZiIREjKMKCaBDhp49bVhmmTYS%VN4JREEQ:QG%K&>6JGaE+/mVY<ZZ8jA=$bYqWwn!Hk:!ad*#*IK
Lh>&\I I:?YQjN/tb%Ep?#kE\!L*WL4%$QupbV=G#w&\^NqnpwZ%tP=bFtXMpFKqAN&um:qlE6Q?FkLF@Gy#8De
BDBRNn &EYaSCShcRW*&/qT1WGnVF<y!e*>pRPiKXh*6bk<>Dl!t5@SeBP\tL*8WkKY9ly9<D#F5$k6lKwdMCu8
8jj<BI EbC4eh@T8/KBd86VlYItah^j4/GcABnTFZM:G8VwY=Y4%+R5dhL^XMhEyq4/m&yJGkE!cnMBkSXNpe*W
SW>q?k /1dWeQG#tq!$YLu>8LVL>JT*LXA?B$Ndmkh?kaMLFk1mcRG9Z/kkBR*p5cWG?$=9hbqGHRMHtVqPREki
<pyE$C <$We6&1lNeFeSp*iM:mA>K4b1wwZ:FJCyAqZekwBK!t9DYKWFpQ4/B:L$q^aZ>w/8RA&W&6juESIcY6@
^m1DLh QSewt1p*6<nZQJ@6@n!yXyd1&jTCdAQZpEYFX14lhmpW%Quc&Xt#FnM&%<y^+ekc%%A+ypVDXYJ@P*CN
-A#PKB 0002755170400110333 Page 11 of binaries1.zip
1u+$J: !!LEEM5mnw<b!^I4%K%m#TWn!y#^a+?QA%c%A*XlDqlu!!V9Aqe!$:LR&hERAH<bq*LM<hN6$bXh=55m
k<&L:P !4i!$Yy+kjcl9H%P&!5pC\e:/bN5+Z&?TbHGDJqWw^Z+/cG>1XAZYkq$%mC4<mKc^T1hlF$AQ#cA$B:4
pT@?*E 8BjQD\Ewb!mA9wWyYEGLt^$ly4>pl^/uBuI:N8HiJq\5tkp*GB1JSklTX!DAN>Nl>4mCk+c^&HL&N#^q
yNl!6h F+KF%!w&BqSw=BV<ApPSVY>Se>mPke><C:Q6qIKQ/V+l$n1MCcBk<QB^A%5&HwSaqnDL/dtuCE+JLYbM
Q8MBKK !8Z\L!BAkhqa*:&TV6Q/WJK?kjM+E=SDVTm8m$$+MX*%CJpNq!E:itDTV#8\c^<wS1c+%1!wAH&YdYV6
%h\^/< A#wGI4R!Gtwp@>I^l@?Pcelhjw!FlG&E+H#p8M6DWPMmCJbbA@FjBkCHHXb<WbJF@&y/5aD>D958IcQ@
EM$:=m T!I5l/%ckqWDPX5/T\5y1cC%JRQ+\$&SJ*4*ew!HNGnM!jLeMq%aS:8qC?FlbRp?DX:Zc#kE!MGq>Dpa
ak98tJ =yelJLbWLuW$lWPltDiXlcK9VuakHhY5jE>DcAK<LBAyC+CJ^^GkL?4P+!$Y>Yc\*AI<kFD:AaE81:Lu
qw>S^C <X6K+qZESMbBTPK1L:$Qui9W1KVHjTRQkFVWBiw*^CK61\bbJYE\eRpR>!cI9/!mJLn9D=@LSMLLd$Q+
W#L=tX 5aE!VyjLbTpAl5Fu/$d85tV:YkLRaJ^<yCAyl*QT*MG+R1^PkTSP9GV9/D1wdMb&=L%aDS:Y^aE$GjEq
:V@m!J ktWJy:KLlDt$I+R%bRN=@<CIlw=EKt^W*K4lnJqlkB6<&^Wa@Nj%VEiHAyGjVcY4y@J5B&E1DWY?!4Zd
1:Nh4l *tiA#DX=I\+T\kHcLytmtXpDAakJBRiLw$AD#EV&C&CwyTMu%bWJQTGPt!G\15eu6WiBlZ4Y!QaA9^Fy
!G+y=$ LQ?>Lt56yyV&eb$#j+6<V6XYCaC15:k@G$Ij*eHGR5q^mS%<wT8t6yW5ic6&q?ILdAKK?MdGu5mR:b8*
K6Nh:1 +dDm$akPeMq<:nyA?DbaH<aSm<THTVVM1CAJWJC4w:KyI%4e\bWVMamGmGMJC5>JaCTS56ZLVFMhhFt&
=q<*<M \wBS\P$dA\FnAutSGK5$yXd8c8F^5Rkk>uy%mbtD/%y9ENRAlj%tHZdcpTR/CT5NECp<e%PSa^ZB+iWn
:=D>:b >H!Ga$&QTw^LYY#G%i6:JhWE>ln&FBWWQKDI/nZl$N@bL4?VXJn6kBV6HCl=yVeI5al1=jbFT/F1J&6n
mG%TCX kBRb+!WJJ<E$t4%4S!Fy&SCEqIZAHW?^VT:4Rtk4R9qLC>Pk%Plnc#/q%XG6dPbLKZli^kmdpq:NACC<
mMN/dS FWNkR*6i$Xe5E&KFRR6&dT1+/1+#9Q\RZi>IqCn9Ai#Z&DmII%1MqGeKjyKlP#D1uq<$E$IpQ6WHHluY
wW@Rw1 knc5b!M@TB$p6+FY58#&*5iAI++ulWWw1A>Bj/BZddi<TWp\la<epBDN!B\?eS$N?TKH1nPaLCy:wJdS
PZFpY4 dMQtDBcW#dA<\EkLBQm6FR@TLC=I8TlNW<L!GCiV4kpI5k=KIF:HkI+dIWjtEVl:Jh#LYydPRC**9qnR
^NdQ++ N1RKp=VXtTp9^ESBVnqqu*HdGiW\Y49WpLARAmb9Kpk@qpMD5kk=:QSm$Gq6ENAqQ*NIKb>%C$BE4BLa
l49KV= <!l$=?u6HGcmhP@B$&t?Yiq<!kcJGHCBH!6\V?$cVm+QmMEKZ!K>uPQ&M\Fb5:I8XTH@k6JXV>JSwMZE
?$/BIE KDkWLpwB=?NKNCHCRdmcF9pwX5$Y<VV/9i>wGLq^by!w6T:TwVFEDFTW$V?q?na@%\^DR<N#lK8a8Xk/
Q$K#li 5m@BiyCYwHBM1blH\?6t=aQ1hG>>4!SNj*Pyk$5V>iW1ePFM1F:Nd?<*5A<j%F#!%1/&J?5ujP?+D9Eh
!FC/ca i%DZpG8BaY6A&Y89XNqK48APPBRAN5/46K\kP+P^*d6uD^@He@c1A$y8a:C6?AWmkIWATj%ELH*+4Z/L
4:Dy$W lckF*YjQ:=9Iu*GMG&1Wn#FWAN:kSHBAcCk84FWC>TPIXRy%6imbcVDuJHJGDW+/KdEABw5ItFH\4@1A
?jmj@& M:ebcuBEbc+bMS@/ljWFC:VkmJaKhe9T\B9pnKMTIJSqPcL/&8B>*hL5KTZPyJ+kBWN/5Gb\BHlNMTJX
9CZhw9 &JQC&CKmBK5TMh8PmG!?YN<M$IN9N<lCa9j&$9nY4EeA$A<Yqmn&ndm!LujucMp#CiC!lG=M9^+dkD5A
IbI*5$ mNqtNCyeu+=@#bTXXG5YF!+>GpRyinDF/S?6YYD&DFGF9TI=5+aktcBuntBw<^m/EEwLl#F9uiSMaimP
XHD9DV aBBiV@kN^MtHh/L+w?mC=P/44Ht=?R^qNVXFAAAE?lKpp*ClQwGqJ5<yWYW*k@5I54SqSXaZIPwXV:aq
b*#eX& #m!CPE:mSTK^yG$A6\aeZY@NYmM!Y@ACljlbY>##YAwwlmy\X$uKVqwTwRX:KeCclD:Y!pqLZElRK6@S
Ky6?<G Z4IeLdBpCAlai:la/+kG#SlDI$mCmSDcK%ABPXlIE^G:eJ^9FKA5WR$Ka$*CRT<X?1bX//lTyKqCWD!E
I8h9wq tIAT$HwHllYEBFn1hlKySbeJwN/8kG>NkVk@YpC#CJCnR6$F=M^LGLNZqq/n$Ee#1G@Wy@iCtKXKlaN!
EuKZ9a tAwVy5dCZmK8@=k&@bE?<B+5JEmkd5FyGeb5?NtqLBY%H@AV%&tebSD:A$qZcq6@4!R$W%aEqtj=GiJ?
4t?^k# kNn/8p\K4yN!1?/8NLMLP*iMe8KYdJ$RAc^K/MVC!5aMSRtkPuZ6VySCQyXIT*t@FbCKqZ*tFwCi&d8J
&NtukP Gh^*i/</p+k^hVCVeQ>!J+bMt:W*1me!y&SK?iy>i?6Ej8u&KKtwum?#=mG*#eEkV\4I>tqPDRP$DD4y
da*KJC bmHluyD<GYkAXGBJAC=T9T/WAyyXA>BTK%aYCSI*d%$HT#\L>SpmyqpVYh:Twue&*mM+i@V!?!:aXncI
tZ:V/+ +/G$4BAy1JG?5#4jJYcZe%&^WR*JXeQWXbVMHGHe*t=F1qcNWEHjTSHLJaLanjQwhhbCGS81XQFy#&nB
%@!K6% EkWaJLJ8ET15Wj/ncmA=?#VpY#iC?Jb9:?pn%>kE^ID6>ablFiEmGP>>SL6Iq#W8X!i<#dLMaZM^^B6/
6aY=Ca laQePT$yS#W\6%tTyK<W$c@elN=i*!^DS^p#pY98RttD<HN6SdA<JwwnK$:9qmLY!6b%!AJWKKlGq$tW
Ak\Xwi 1Xm4w%dwCXRwIG6hbnF&6l<RI+I+$:4MWZm/ApBWP@/i8J%%T=5y1>lm1XKZ5=+/J9IYAWCu@$5lQlKA
eau%nA e1Jh$BIRwm!c&6IN/w$y1IWA9Z/Nck4>TyL$+F9Sbakl#Aa8T1y88+M>G9eTB:<VAPJ<CFCVTGDXKM=A
%Yc6+& $cSJ<bp%QKqHtbmGt@tm!IqXaHZDTauPaKkep*A%+IeIW^Fhy$ABwWq>8Z*>nkneT?pI+4V@QYW^A8dX
dNB%5E wJBIFG5AJQLd:HKG^bl4p9=P&LwZbPCEuGCXAAH\cY<qmK:T%iHhKFuDtR\b9$q:IlECIAFt4bk8Y$@R
y^DXXQ <k*TLFMPIED/ek$ECH5jZLnBq>Xa#:TZakeVcF\F$m^P6I\tNcI=iAk:ZFZRyml+k/:4^6BmaMjcTHXM
QQEViW nQHX5BtyP>##h5S=*e\u?qY/>m:DADFJK4HJn^kC%5>8I6aT%EFT#\@J$Rnwn=L\9lSmH=%E6M6mV+lQ
L4<:BM wk+\k!XA9lF6RnGtjeB\ML1FKTN!SdC@!IpC:PnE1Dlb\CSDTcak8H5#9P<LT:mDIACA5kA=EqTF4wES
!:8NwK Xpt#&/VR%^YJ6\Bl8BVyJJ1aklb>k<@IPhIAME8E@hmIJLd<!p=Yby*chFippYR6*\C!akLK9t@DX\pl
L#QPuJ RI=jT^HeeA1t%jM&elnMXADZQLp9/q*ZD+hTT&RkkF^Sn18>lm^#1/8wh$FtthnuuRhD\#pyBFF*QBeN
CiQ$K: Z?/*J+cTPH+T/b?68CwR@DaLpJR$VlbMcyEk>amL4w9QYPJajyKmNHHSHP4X/wDGBbIwCwW9Kc:dF\=Y
XeNXku k!RjASXiINJ/+JADm1=11nVZ&/\id>C8A^81h?%:mVV6\yF&WECQ9P1mXP9m\TI+V6SYeteSQyPN!Va9
Jn&6Mq 48M@V?MpqKQEcWTRPwBYc@:6=tBuXHDE+:nbFYX&LBmnhbZbjuVtB/P9CkuTElMKWMBHA1%SBSR5\h!l
pp=%+b T6?DbF%ZAQFSAnXF#><i=1h%tVR$C!E?K+IE86cS=yib51wkFT\Imhj4ShXjIIE!kL:V1uWqcFK:CpeF
:i?Ak\ 6Tkl#^:!Yi:XE&q5b1WA^DhKw4m6>SiWumhk?>TRwmWMaC*G66j^ycDKukiK4pQdTARlYBp$w5\/k8t:
1$X\Q4 L869dRnpkm^PZ$*5J\w6CEa4^ZXZMVVh<JIPLP$S9P@Yt#QVc5JSDPqX+c8lbNpXIw8Y*AAk8^\@$FC!
b4DPJ> >MNRa4Mp<\FC<A\GXDCG>It5ilB:\DH>RH4uD1YeS4tFJDq9CyGyBcEqKHM8m#E*i<=MRWRne1\cTiAR
eRqMbS m9$cFAFZFGbL+Z@hbLRt:hAe^MwG*@Y#El#iQaSYyX%RE8\Q6I#!IJyMXDyKQD8ElGSBmNP!jchqTFDF
khFVWL h%h&S$BXkT#$iXS:ceXF/8&CbnMVGkGlykAZ@yDt6Cp!>^iy4eLam>n>R>JMDTQcLeah5n+:CTicXYR>
1iVEb9 k%^ZAVE@RwqkkBPP^HRa5%H!W6IINkE8BINuqGSBcqARE:inVZ!GIM%/1TT!K&P>pYNJTbPYFEFTKlac
wAa!Xa 8p\%Xea=I<:aw:4V%p^D%F/K9yT8QZFCitaQkl:aNiMJw!*8j/aCbZ*Em&bde8MBWGuCeamERBbDA\PC
Tk:W&l Y1B9Z6u+bqVEbWqNFdkIBcbSaY\ttuY?=cXRVy!1!<d5M#kmNQ5Y#\SZMX5WSTdA?SJA&QFW4WWbcEGT
6XPFVJ cAlkXwpIq8ndj9\+m&K@nIqGR?bpkd+M%d1uWeJ5CbyRKdSDZ>bRd?aFmjnP&WWZLHwD+eT4C1d^>Byq
Wl5L#t #l5FVwe!1$iSYKLIA1Sb<VCYGu\tC:!RyM5lm=&uq>HAGJepRKmXPlNZAd/a&1ktZ/iKpa8HAB1KhKJ5
I4QRi@ *T%bX4c*CC??*/DHj6kbjEF<b$I:S$$CIEA@q?kKYBDAGp@9B6m@9YMcT4MI+nM>pBqulZqD8ZP*jWSh
I\%etK t?wJVRS#=dknK9%Y*H+Wnl$5&YeJ9p$Ya>e1C9Tq&a@pPdXR%*we4R!=KmXlEWi9m4IuQup65TwPmph:
tSAQ!n aKF=:4bM4N!k4L1\8!SATkEwA:HM+VQ%EFaQFHSE95>Smn/4YyiC/18SB>Rk?&LXmMcPhH6Cu+ZnVH@N
C85*Y% aT^<AFB%bmJuElTIW^d5WEbj9mNLNw\+AmKF+?9iKF6pHYBqTAB*#Yq1mqRj5GBCYR$1CXyCpty\VC&A
w%qJtS *mJLh!V<>6pS1@B$ACJ\lNJn^YqX<y\q&dybGVBWp4+19&a8F=BDqq1An<Xn&ATqAV^+^kRL#EKALwA%
1t:#I> wpIZ1LJ9RWE$5StKBDFWRtmuRJ1TCH1pRA8ZB!9I%IH44G4+cm6AqmeFGMiCi\EBF<a1:Lc@APNI\Yn4
*+lXid *Q5HhwGKyIIP/QdJlC&@SNAAKSBW#4+bhj\$ZJS5Vt!Sa&1I5W/4pP1X/jZ%>kw\61*Tm6T?@58K&!ie
WYq\he BIB+jT@MCSQQZaaCSA\HJeElY>kQJdJqWbydFm@E44um^dqI4GkWJdmF+S^SAu1XmSG1Qa&!RlP5KAI!
J%th#6 e$lF%C$Q*FIpY5LFa%EepVV%%\R%jhVFqq9a4WKB:A<kBW6M\NB:MB\yDM%Eyc>bcZ@<1:QhaA=Vj8a!
-A@RWF 0005b42ea9e00110333 Page 12 of binaries1.zip
Zm$DNE TyCVPk6XFT^PiPq=wVtHBIA!T9XcS6JdDkCNdJa+uKenTMKEa5XF?Gi#?*jJV!n&<E1y9%+n!lH6ZiGT
ct#IG? 6kCJX5u?ypKCRwpn55J9ap!cSJ?EtH<@RDLB>F!TE*R/#/VWM4MX?%FAZ\qm\BG*WunQtk8AASBAE=XS
e6nW:h $Cl^1K!bRpI$mbIM#?&Vw+&eDy+t=5mMG$?9cHTFqw:ehHFe#kW&&!L^>AlyVqw?CuPEJwX<bFkwSmjl
lB6H*I VJpHZPl%cl6>LdE^Vk:qI=HQ$tmVkHS&<T&64A8HLS@6ZB>iCACw:hIFkHkC5*HHjujH9D4Vl\tc/dLu
I=p&%k 6R#PnLNPLt\u>DHh6KI$8%KT^86$C$iMQXP:1+GQdZ:Anp#Pbc\Lt^&<SKeePRmj*=:>^MPInhD<GKJe
MIbW:a M4cDB!8LBy4PqRk/%W^9yA#yw/$1GXGk?NuQ$QY58$F/tW=K6<STq+mkuME5TX*A15#!^D^iFm\<W1Zw
%95^L= lVpbb\<w%4FBu\qQIGSAMj!W*!C\1WLlw1/aQt5!=<jA%6LV6McGj9act1&NBP8KM<jWbPF9H/pm:Tud
@S#Kbe u&th\KL!p6e#15^#D4hdubeATMG!A@YD^:8@q@bStBl:pHAZbyAwnl:Id>=@BbE*K@=D5F?hAJZA$pAJ
&w4RdX *pC@5D>YekEd9pYBJ&n^#+q8^h9K%nQSinZadCC1IuZY&kD\SRKS?S4Z#NFea/V?RDY8ZIX\BPJK$CA+
K!KcZG c&mAD^yNW%X#=:=b981a<bWCbBt>\FZEMNJa*4inLIqiqjdF%8KEEKuGcKVi6jD&d^Y:wHK$hLj#&4Ht
hIeAAR =VL%P*ebNiAiR^MyMtZP:!XZdq^ZQ^IZT$^TQTm<FNN^PCLmCZi+uD!t^E+T@Bwa$nX>C%aGECL$>8eL
jhnb%/ \&WQ>HPGdeHcjXP/dED^<caihed\4yDJ=bZLAhW:+P/WiceuV8YhbIWIEwqbJCMR:I@*P%EwA^/wHLl@
WFHXtR DhkWMPMIy&^XFN9YMtB=il$4+IWDlnkjKHHYbuE=#Nk4IM5=l/5bk1FE<6h1$HNYBCCRMl>kD\$T5Z=F
mN+Jc: EPjiPa8Xe<ViIRq#XhGSRZP^%+QFMk++Y!Qw=?&*qpGDS>e9hLABCE:W\^XDN#6*JP^Q8@QSJT<u/uLE
ydM4Kh jImG9V#q@cSqVM!REnFYpppSR?I$Q+dqmM4J&d/<&B?&hhWLq#?jHYB^Xw\tIycb=+AR9?y?uBydNn/k
KY+bqM h$wN\D5nTa:p/L+4@I\Y?hHi@P:AB%!Ik/P:n!YTYJVNk^C^T8%1u?>FEA<aJMHKa9J1T9i4#!nNeR%T
GYRq9e +?M4I:IuNiY9$th*:NMaidN>:\*=BKp45?PLW^<PLaRliiIn55WSaMMEbcJkPp^Mj5BEm\VW1mV$H1Y=
9HYRcM $MhPPFFetS:u:^mP9>GhYB8BSHpG1<=uL:kR^eX8JaHKcFy$??qb&hLXWn::$Z4/L6XedB:P*nmN+nEm
CMhYPR 5>&H#!tATEledaXBIH^+L98J*KcRTjubaL1>ycQt$::6pnuWZdb$KSk:8EyL!BdQVeF1<Nl4iHXHbNE:
BlC<GX 9kHw6\+%My58\@=lCWql/dQCXQc1S<piGT6XTqp^e?/^I#nId=h=p/Bn!tLRHdGHAGL9i9/5FKIQd/8E
Xj\>\w @hc:%*e4jC<BD?Le#:<+IRW1dkHpkSVdM&XQ6HP5jyZ56*&w&kGDTJ/yqwR5ypL!yjde?R\G$/a*eTAm
>D?*:C e9>Tuuy>BN&D/k+P5=jE<pc5JDwMe&F5B&#EtqI^XMYTq6C%H^15ZJ11NnGeQR8mCaM^KWHtiV$mJVYc
>XW1VQ Q#>F#hIFYR<yF<pmRh+Y8cJ65w=^BkXn=?Z6y$EAS!*1NwXklC9:ID%Tye^L@\nmWM:C?9tppmwXKL%>
>m!$q> NYmtWdX\u=bLQ>MY&%LuAkBI/AB@TWtN/IypV%yi%VMFmI?p<!A@%tHH??RVRnIqSIViEXhyukbbF5VJ
ASwiJ& WMphM\LNWlLkhheSmNnyTlyk\l+uuIt8S8c@jl&Kyc^I*Cm:cEiM>htL??SJt/c&Tw*lRVTTi>YhSFWA
l1E%FY &FNRBqWiE4IXkjqNtBR:1MMI#Qc1WF@ChIW&MR=XcHm^>/Vk1bN&hWkbZWEM1m/B9CwGp\hFBWHwiDtN
Hwb:$i dKBeFlnIw^#%*eBwBEYICCAk*BA<DTnd>*$F>YGlEGGSAujTytSeTlyiY+GuiVIp?p:TleA>1ab4lSJa
@6K^T= nNcIbcu^1i*XapKCPk*ywX!Z1<=J9T!V4@FNKcjLDD*VdYGj@WEbCA+F9Y5*F!LZ$N#4V*uq6R8PZm/u
^yi5/8 ubW56CnCeIc%FCcuK:bw:mMA9H=SSt@Pcqy?BIEAIAm:F!n1LBMH>PL6:Zu:#/YwRIiIpQY5AA>IbbRl
6GDHuQ hNi:K?lyE*Xmpk/@I^LTEGlMjDilVTjjE=9N?=KH@b#uMiLGk4Xtq/caT\&#d+GAchNmwn/AcJFC1BWp
nlYd8G q?J1KWNqT/yebCKM4tLcB@w1TX1t1c=8VPV4&uDcY%J#^4L&PQeRXHQCZDHa1m58m$Qw&jtN5PZthW:I
/SP\j^ HiL>jI5uSHY\K@GM>LpD1^E#kC?jFuyW<*wRnwKE$bH&^Ab>@P^Cpmypi51Qqi5n61bLy@jA<JBe5Flu
9$:6uL 6/pRCAC#>EEaVm\ecytKBqYFF>Tn$Qu*Q$wHS#4LqV5?/\@uaABFQT!D1ASi@pT5&?n$!6nhBqPJ^k5A
5Hy^d5 *hL^!*d\/ae1hi%mKNAcCWIiRA%M48eFG1d!cejFuu?L6=NCkjL5N@j&c^&DmRA1jI$F=JRS>1dGA@CS
y*@I^@ i:A=Y#*RlVq%JEFXhY1^dp89ma4y?&C$5>IYYcI%/Ty#D:H4VMm?Mt@EE?J6NK8=BTweJRL5B8VM!KaC
AKLKmP p1W?I9cndAQVTy^8R1XbLwD6ZV$q6$4RAaHtL:!YSJD84+NC=w=$t1iMHHHHZ1T4BWlhlLm@AliHHntD
^=t=kT ki\:XFN*RR<!c^D9\NkCa@+\>tG@IN<wKmk<9kMAaV9Z#^n&%EHY%:kVNEHqIleat\4$V^jmSKej8teR
&qpi>P VX=*:+NC>G&*%bWwDS@ZlbQRl8D^y4qh&$yZXGndL/iM=mMmNPXeHRqIB6L&/#lCWdn55F*XdT:d5$81
HRpVyi *1P%%hKVM4#Yk?WCRE/=mnt5^X?=jl/DTe&Rl!D%\F^ZmDy8EYujJAYwS\XJtEbbCKhdXu@:#Aht=^ZC
!j#@8W :bWW<=Se/pkVan#pMjw5SRQ+6jFEp/BhN5Ilw+K!1l1eTHKIHib!KGAFVnbJClKY^MWlpS^?Vq/&FJV>
cm%e\+ Fi&@1WRA!ue@Jb8it*>@InjpK\DIkq9AidS99A=CutX&Zw<+uCDQ5&<BMYHk@bt\C4HG+PnCES<==AZ&
BqSiDW YKT65CAZT+JMWJAESY=5VCuu*iHQG:pn5nu/MQ^KP^RbBlA6\G6wmKX6DuJQd6p8+uE9NtE>t/^+n5lq
\VM8SH K?Db$<c=Xn#L$Ka?1qJiS!>u4lqFAi8tuIewjlFQWiV!#iBqHWmCT$/5YYM\>?BK:lE<EV^?n+Ph/?wJ
+%6?ma B4D4IZ\d*qkTuCCS*\HpnZu^dJT=!\G<Fl1<k<MX15BuCt$aPWa6Eijw%!+R#C8tMY^KbM/cFpB$#J*6
Ic8WBh SwkT<<we&Wn@jIaY6M\idLpSISIHIZN+QT^!4GN^9X<HwVjQGMQy&Xl>edR5Y+\Z:ASFTplPI+E+>@$c
XCRn&m !whhEX^$iPtc*@/iMD\qPbeBMtE/qTN%RWL%QDaY^ITAq=YcmDte5bkG9e@PIGT?k1XtD\CqDPVuRJGY
A?i*iw Ed^k9e1W:@tLG:l><k+>A%^!1NYND\Z!>#k6AAhJ+R\/e@lSpJR>WCCdl+\Bh!n^SkJARu%+6mMC!M+h
jLGV>: !&VZyl\pAAnnK5p#X:B5<c1DGi\WPMkX!ipSl@Vak9ld+Z^HiIwyD?5Lu\:NI:I+I#aAWk5RGeCuZZP#
/=d1IL R\BVHB9yBlFeBW?EN=H%^Wjp5NP8PJJWVkETQPdBdWGecwF!%VcYQayHh9!TN+dMY%EVI?Da#G^5\STd
\ytiD< nGYVN@Gt+/E$kD$h^4ZeA^wM!B$J!%@eWV16\%9:mknwXuLhKV/Tny*dYGRb:VK@C+J$5?5BewPbiZ*P
#cuJ!Z I=cFCC^JK/=9YFnCbt>kM?WA\AI1T8ZX/\MESjl$LLCtq<NAIZwk8i!yDk+&y+Ww8bbSeu<VD:*@WK$G
jWt^eB t&pHqCtBa4%BHWp$$Zb\S&c?$JYL#MkVl9EtFAhcPL\SiD*lLFn<F+qaDui/N*i^E\Sa!=<=\Cj8#le/
+uaKea YqI+*DEX!Lh*A?*^WHItu+@^EJS#S^=VY:nRcXdimE+iP#X*VDP@#BjPB@IIGeBcLKjHkiic#SMtR*1+
PPmHj? CH+plH\jHQcPb4!B\Ja5HQEwcZHKmbMc9dPJK:RE5TuaFE/iMN1$T?tmwnNZ=LWZu+hehkaS+cByAJSN
tGLde\ h/L=ItnIuLXkcw6aHpG#hyiq+^kZEe55u@>^1pWJ+it>F&94b@MKAFn5DqMEeSPAk?<jAdl6V:B5k>Qd
4^kY!n ^iBneJQc5#CM^Z+m8HBE#YMEeXVw>b5#IY\Rb?66DqM4:>A%dQuVjK#uXY\PX=DIIJjp>&?HiN#L:^CH
>*hHp8 LG?EBE8\LdZbHbw<aRcatRT%hIK#FYE6XnDLCASTEVmwPb^6%ep@m@C!94wj\eu89WEZk%y6=D\!p=#&
je94Vc B1<bRdHj&TI1$Ptm8A#LZe!Enqj:EW5+P&ZbEW<E4j9awyiRbW&i>Ca5Y=*H%NL+9L>\Fna\:5&:tRkj
DSJEVG @aCpRMA6L4q*?ED9Y@l$Ac<5CBEZp+?M91n@wbEy1@YdJYIL<4K6nkybjLI9lCtBAHLlNA@aZc+9k%ND
QjB%/F 5RPujNTI*dIl#m9u9BRR:ARVJHE:@HNyYakYp><e#pWtREXmeEE<4F<#YMp/l$Jq%&YC$VLFy<XpNTmF
nCV4Rm bb+q#M^kK+WL^8&\NT!*>uDlwu5d?qeA^IYSuXYS&Q9I56/iRlkHV9ZaBGIue+W!ieG5QFGCW=peG^CH
V%jCSd m&#l\h?S^AR&M:GYERY48C1$>qHZuTp5H?WK8XntLqAQMt@SCjk&BL&^A^T4Blp^aHiph4:e^<6GVBA!
ESyjd@ jGTKkwtK:Jd#9pk8t=lNY68IJEN=TMnydA/9J&V/=qT=RQwee&%\Ab^VXkkEb$ByGhA^JJT6u4eG!4uS
AF\qJm i/>cFWpAIdA/i*$*t*?wp$qBmw<KY:PJ1kM+QpE#6$eZ#MkB6&TdubnmC\4BI/E!a#ukIhLNaMh&amF<
hyqVGH VR\aE<@J6wZ$:NuAn?W!qjJy5Y#&u6^yI@ccF^6\lCA*/bl8+yX=\Fpq8SP%=Ve>dFIEQK<4dPS/?Jl8
HBI11P #ykNQD5PIG9tESQ!Ca=\$Td\tC>^$aDDqMqd:T#nB*MJd&GQ:VVJAJS\H5yS!4<9^R/&!mH5BqF5T1j%
?qLkHE &CqmPe9je^pcETk@H8$Z1FMc66\lwGjh++/MkA#td!Nt*uIh&<w=<AWtn>k:qG4A1%jqhw4^S1Ik=P?=
pEGhkM YA%8ZVq9#AhMAyhq/+I@9Jj5MC\5R:NH+9PD^THI4J^%QdpmE:bkD!hpDDyt?*kbtDJG5kp\$Q:4Jt%j
6*<n@9 ?MRRd&ah/P+XNyD&Y@ibC?!BhG^qp#HRMnwM8!h9^IW>qu^X<!cT5C/ZIMkNXD11ZPR!W1m\^wY/uwhq
i<H?>H 1$KITVp:>^R5?wJ4pR@aAFT\Ib\\q@M8bh!X\#=Mtd^+=:=i#pLSP^:Fa!<&ae:NV+CLAMb/1%1+Pj^H
^%S!+a S@5@hc*be$?$P@Cq<w8M&QlXjt$tTuq44u6:/DIcYLPBMF$=I$SPMMA4L:J+QW6mALA%hSSB<=uCW+Cj
Y$qI4X 8ht1cm<&G6qB#c@D\aREVuA5w5^JP%8MZ<REa<$LCGF\P*JXLGG^yPAkMR9iEV*%Ay9dA?E&/<Qa?9qc
-AJY1i 00018aa4a5900110333 Page 13 of binaries1.zip
iAh<S/ ?yWE>IGAC$DPJ+BJue9k98lEkqMEKPTYkCPCM4aVS%RIm*kuPa%ib#uADwduWT#lk8?=dF@P?ZN5bCb9
bHF?C# X%9kwqQPS!6$myuXInk*Y^!/eXMe!RZcw:1ZaBTbcqAkpwY9P%GAVJM?>Q\Se55nCW=$pBBJeMnu?Lkc
M&wjma QA5YbmBGHy9F^BHaaE=t/%D&48MulhZ!99h8u1muFEJZBGQi$R<E#?Bqj6YMwbmyRZH=qi4BLWmm&/aP
9tA*YJ K8C/M<e!ETBKkDkLBl$B?T&/W&5j8dCq@5??dIP!DjEndGap/PIM*#Zm&SMPd#qeNndMBZeV=h\dkC$E
p#JB!9 Ek?X5q%!T!JL?h+k6bNXC?6iP\9lc&p<y6:m9JE5$WlTjlMu\#4y\$KJ8YZwhHllGjN65+lj/+=+F@n/
#^VqDJ #hZpY5A/G\:+j$ETI*M/$tD*Ce@G^HLJEnR&AEP11D@:IbP>I$S5J:KD/eAQXuDXB%9G9WpW<IpPIQ1Y
>kQ!C< DZ=Q@ZtZ*j5e<t9+KT<jRq$ne5aIiiRpYQhBSK!GE4dybhbB?CKM/+4Kae6BCS+=ABStcRd8$GZ>%8?Z
ZHh@%^ WE1uM!C%!jF$CXAMZIY+#5ETDp6%b6e1Aj\RPCEqL*64:n=!GV5PRtm!*K^jq8&4Qh44Wp9pKmFLy\MP
qNp^ZR dNQQ8ZWc^ZANhZZn&!nuE=Ek9tui@TBP%E\Vta^aQt5VhIHipuAHY*11=#^pt5Nl$/GC$B^?X5=cEnAN
PJQ6cR A4h<VCX#iLW1jqnBc\5$$lZ#58AktJaPe/XDTl+lqZ9+bM?Y$8BpJnjuP=nL/C$WeNm1JqDGD5RYQ\CI
?dW=NE !!ikaB*IQIEyJ%nu\SEl1E\D^hA5PRwKZ*HKw\XCp91&WZJ+>ZJ<anCaFy6M@5T?Klide6c&>n^A+!BE
XVCT9n b9t@QW9Z/NASQjC$W@DHG?IyPwm^1>u!SdulY\!^yZt@!CP:^6uIaDBYE:/wBBi\<565e<N$t5mK:GZq
Pd\NGM T<Eq?iL#ka8J/n6CkbAB^DqmYda$/KkX6k\\/b8F=6+V4*kLG%E/8cnDG>uBbm5FbY5CHX9lR9G<55T<
1ZQ8X: %lEeWm!QET$ihQ=#GbBZykKLDiJR6uFFDkB6c?/$Jd8*G=V5\8lI*R4Z=\=6hXyM@i^cmAnP!S8LB#@=
9//1!^ <CyPA6!muAhe>jF&SXIICAp+j%G:!KdDJ<I4$:5Q!4AnW8y!k?I?YYaMV&#uMcF=>%eLmXb9*nJnCX\&
&I:=jl Q$NNT?H!TVKWdRP^hIbmHSDENJB\D^8ILa/%lhtmM^it<wnW5yat\Fb*+9bXCW6m6:\IVHQQndYB<k@j
ZqDHwD P%CJJJNZu&+4=RMw&q8uSi@CEc9KZ=<qV&<HtFHZlWw!&d45hXq=9Mdj*w+i\G<pPl9qlMVpi+%?54wJ
H%<BMJ #W/DeHMSa\GT#Hl&<w%6p8uXBEl5FBHw<EACJqC$V/+RQZMt8/5uF9XRp5WGpMBiADAPHk\%ReK6QH\@
Zp$upt R*P:FI1G/qiCJ?6>CAT8KP%#LqLlPBRpVP5SMIj9HuLY:k#==tew4#uTM1E%e!8eZHW6qnw>Ak@!kS8$
?8MN=e 4GkSu@D<VkK+paP\9KGI$tqJeC9Z@Q#Y:w&JW#QulYWjP1jHk:+P#aNL+*Pc:mlB$c=e6=LGi?*PJFdt
m5%L5G eHCyi\n*T!QBhl$EyPSNSKudNSy*T!$@NY%wlab1FEp$mY1n^QWK<C5DdkY!J9ybaSHGilVNlNZw\J*#
uRMiqy N+=&\q:/m$DM5+Pu$<dX4R4!A5p6ciy/:NDT\$XS?1&Q*Zi6B1@EHDi#^L?4:H6Xui*:?p*$bJ?^c:c6
Apnp5w *WlDMEH!tcEKi&@>%\6^NI&h?cW&+HD+CCWt8M8u9@:D<heZ8#9=eY#bnA66WPJSndpik5=q6jFDYL%+
tRa#Iy pcHtbV*W>eV<Xp:SuMWwDXDI!>8q&*Fa5>JJ9yMI$PL=\&n59mLn>/=mXeclk$16d68@wh*E^?HGW9y4
6u:?<4 ZV6\T:dN9Y#I!HTpc!6jFC?tdZ8lG+BPyntiE=e*wVcD!N4Wp/AW61%XZl*LWI?6p/1qn@^M%GlYd=<A
XEp$@w eSjK1Z1?\9HV$dD*P\d9i+<LY1Ip?1GDp##Ih<QijSqT\1TndkY?lt^w5KH6@ylNTuyecP8FYh!hD@du
1&CW%y APB<n=#Si\LlQc=/SM#<=y*a&>=NC&eD$AnIViWNi=<VSL85<q$^b81\mXNJS^\XIu!RqJi/cQVXEJQN
5HM\GT 14M/1<aXh>jY:BD=$Se5lN:j+Mi$/$CHa1Y%i*IhmnVe%Lc+d%DL@Y4NqyJJcuVRmcm68HEbZ:V*tCA<
c1tVk8 1/AjlKJ884b:Fq?!qmL^Y/j8cJHdABkjp1k^wk=V!$P<a+>^6#k4qbY#X!JT^iWDq@j8QWbQp/mKJ8q8
=JVIw: +GteDqey&aI6QXSI1$k%\$6pFuZ8c\ecXE/SiqK$bMDAGKiEGThmw8lYAc19l>$iEccZtDY/G&\8L*jD
hNS868 kZYI>uL%QkYl*N*?B:KK#\t=$1WZKZ:btKabX>ZE94Z+*aep?Yc>b+nA!Xn<Fw:6i::ayVSb8S*DZ#yX
Zmya5E uE\Be&Mmj$Y8PKK/!11ISZkR6GJdG?>d$^u<*hC/9/e4CkE^@!b@!+$>5eYYYFBtIqiSuT&XS><9VPZm
&#Gk%9 qI55dt\dXX>&8P@$h9tyV#AFWlA>l5#wQHWkImktQl5hlw4?%S+Pcka>eXh+G?eu=<8HVS?u:^yV?t%M
&meDP5 pGR!9DkN1=8$=6Mh4YAn+V9j%pD45EuY8c=$\MH1jA%ANBkFNCDpqCI&a%p1b?5NGKuL8#VX?+SHY=XX
:6a*Nd V1/Z59$BBKCD^>$ktN8ib61PVW8L5ZB1RF?+=CCS:<PAK!LLM&=8%wB^5QWR?4=l6qBZc$M<6LQaM6jn
yAWyJ4 /pYcGl8@D5E+VYM#?pERi&&l6MJYH#TlEBh8/6S#Suq&pk!jTVkB5E+uAY^um6wDKN8aaHRwGK$Cyq4B
B@ppEh 6*Yu1^WWm>PRLRS&$nq^k959GpI1buXTQahaDa4I^w6V!CwN=VeNG:JH4X1n>htAWnI9%<HbBI:5d$&A
GD8M*Q #?F*Fm\VXCH5B8YC<KB46HQ/#!K*A/M#X*Kn>*kMR^4%&B$SEAwiAq1<kwc5d6h%$+%$1h>V&wREFbIt
F&XRBW bHPE4Rim$NVmICpbiEe#RpDhuE5ZRBY19t<W=Nt+%K+^!PmAZRG+KwDFNM*qu#5<n:Vm>:PB1<ReCYbn
w+N&J^ IB@Z%9u<k:KGiyT5W>^6i5Q>nZ8:XDk+YlIeRV6MIc+t+>nt/*ldjiVaw*Ln%>h=>+<S+=8LMBjP%c:u
h@5T<E a%9yI6hRCD$adL>&WF<>P%Nyy9>ymac98INM9?iD414l6X?%\Nt@TC%ib\!PXKMnMndKL<Cqlt&ba5pZ
T+A%!j wt1FE9CZn#P>%Ec$KwFuh1:aWe8bd%cTwtGn@L+B@ek+#S4kW1C&jJEeHnk:aiI6A$p%\9@&ZqI1JPDb
>FE/Qe $+ACl+dueu1WjH%bTpTtay5^H?SW@yDpiqIS+=yPV&#1cu^:yA4Hp5Z!CiKk9tpZCRbBq!5A^CJ:k5C?
!t9dmS Z@VBLbQ/ZHaB4G=C64@^HE=NqDJcQtFM$<@5jnh#+PHYNH?l1QWI8H$n54+FK/VwT#yw1P#%bb\RF991
m<XJhY P%km&Z=+ijbicZ%E@\c%V4:nY!!A+?LDMb%SAdu<hDnut!tQ?E^#5Jn$&^lkk6j+BRA^=ZjPZyNBM>A1
Wp/&5q V5J\YZ4&eNWGlq#:c+%i8S*9H1>>KBRCh!Y+/FmRGuphLXkZNVe6B^qQkl41+MGp6a/<CF&k5j?+iX?&
%^4Vj/ BPk<ZC9j5eatmt$4RLQeWnM4lD%n%TlmlW/PLSTAwPEwWahPH>pYH^pFAjWHIiN*4RQA/%Sw>bhqiYM+
&X4IaM #GIbSk4<Km=ATjuY=LiJ<Ipic%/&nIR\?^eW8@$i9/jneBc6t\&a!Jhqh:Db:JTTk?&!ieG\&#P^t@kh
*ZKPXF ZGV<#c!:\&XAdH&nPh$%SdqPA<jXE&#$a^VkVRc:?S&#c6jL+H8blESaK##aCZYLwW:EwpAFHYb::yw#
Wcd:YH 9W=JpwIJPYZL&AaV/iMCi*5lLlp?y@RYq&KYtwF<eqI8LJuuYTa%5Kd$AHd=tnL6l#LE%R%en?SjLdN1
8pmuqA ZCRHR6kET=/kS1cXeWF!IXb^J8Em:aYd%uCa*@K:%C!Kk?k/bAD6NCSAG$?W?%m#HjWlKTh>uTT!\HQn
C*NtYH qWATJjXh1hp=?ZTnPew*XTjtD#uSFdWlRahKTKM%\Mbn!84/Hh@*4I+KHW<+S=YSRW/ZXS:XlID:bE1/
6D/F!n #&%KBkYn<5wnDB%**RRApbQCt$5Q:4nY1hyud<BE9R4K#X/F\:@8Km<:1VDAZKEy#SXPJCZYYq*JZb/?
SQC/P4 *X6P^^PhcD$9dieP9dh&t8>X=c<eAXY!RbPpjQLI:GYZ98&qnp:?d/t4i#TBNSZ6^X*4>*&\p>V/e6qk
YaRMRb aji&t9e@n6@b<VV=Ye4V5=?iuJuM85%d@1E>6QbWhZ:u\c%9XLWFH<PjV?=Y\L%i>=V*bjPGi%>??YZy
j!<ZI# ^:*yn$@ZQ@6&+?4:!=5uQ@>c8j\n?ecuZ>dQ41liqQ6SiuZdCQK9>9H?b>n/SmLG!C$yKnw:Pwyw=Bmh
uPZ5KP FSeb:ihmV@!hmGB1<Rj<dhN@!a#@uElnct#%@$@eY<>wtFYPWqEulE4LDiCLn\\RHJt6/&AaBHbHNJqG
G=MPjW XTy!GkmtVG@Sq@jIlVpp&EP6Y8\VIAhq<yVDV>T?lnu$$lnG?G1ML>kApCH<B?=66CwTZw?BDSlZ>WbR
!^+qju 5iJSDXcPL:jdZYVpScDMmMpYlQ5pdNEq=^FV^cLtqeLFHmc%aRM>=EL$Id\BB\*Hu&=1\Y@Ea=*W^wYC
*P6#pa ^^jqd@Ckl>i/wm>bK=*diYh:=dc4iGZQZi>1Ba6^#>>d>8JKk=<Kb:CjIqXP/YYVdV@AECDZG!iEL#>>
^L>DY: H>+#$uD#E8Y4=eM:L5iK=I$Lh::5Ec<ZXAqc+uY:G*Zh?t94t^eycW1\99+cSZk:NtFTL>EQ!mYPQ5Du
kBS^Y1 ta$+^J<#FK<k!l6nwwK^%LwBHN1BMh6#T85X/w1!m==/&DT%4\In*V%Dc/GmV&dHK<LA$5MEGAVyy\CD
5&c<&b %E+aq/RF%L:q%SXiMHYnn#BIJR+nIt8LhP\V$^KjG%@\\k=LjJ$t8w%aMe#a^WJ%k9lJ4Wa#RL\T@Kcm
Q/Bn?H Z=hb8b+uRd>CQWY9q>ZCwMJMtNhulbnFK89mWpIT*kc@>p1@y/>h<M=nwyCNS=@X1KZ$npH4NkS!QAXQ
atSpWL 4%W/ibA^y*h9DVtZFuYceAY!d1Pt8<#p8Tm@nBM$@J$QcuJp8^J1uej>Ad&1ki9W%\%MHmm1/8XE%bpn
:qd/MK C8+qGSh%A$kPl?w6dm5NTq</qbpbh&ptaZ@m>Y4q9y&VW\u:5&/a:l$*4QP<V6BF<uNT\&>$Z$4W=bq4
<XJ\^8 /i\P4Bd/S64i>ey:\48XHY&M!k\:V@LdaBA@b&y$b9lNWRQ9E9qCq8lGJp%KeN$t+8TJ5*89q//GpC%C
m88kCJ I68YQL1?G!hFB&5=cWZI<W1LIn<\Rq>PV=XFc$q<*u*W=!dlLHpPun#5?JK@V@yZ+!*dZ+iWZL!AnZS#
6SW#5u i/nSi9Ll95V1tIWKRj>VpbDSI1MtBaq&:4+y*L9\!HDZ4<ey=+w8jNwmbtepC=P*Dl^>>K%CL8#>SaXj
AZ$Wi6 >%uiad^<h/*t=I*L/b>8G+?9t@AwWq\*WSPM>#@>/5L*BG@ail*4Byq%%dQ*iq9Lil=qH@uTe$p%QYCS
^bmBC5 Q9DIcu/qtdmaFh#^=QYh:#Zhu:biM9\<@6=4ei4h>TQJEi@PZbF\/emT*%m1JX/BnZq?5iHwZKQ8nKN\
GKQP=C YtLu\Y\9nXZq!pjjH%@<+FVRB<El+CYa<p4j$b+uF>I@9qF=D:LiRuq*bMH!F9dBG/5q6!L/Yh1im5lI
-AFp$1 000da29c44900110333 Page 14 of binaries1.zip
dIH1>* W5KJ*ahh@T11\SN8#L1Yp#E6R?GHqPP9FeSj:pqc9C@PITHpmTi=*RN?bL1@tQEllV#D:W1#Vj=9iaZ$
#8?4#1 !w9A#PtntS/&e*cX\!k%NMa:X8M/<dTh*<&IRYjaYw+M^NC>!81+bp68d6uy%St99Wbeq5!#\+#l*dj6
yKQaQ% 6&!>!u^#1Rh<jCCDYFDpcZKai1G^^K>m@c&qh+eD^uaieGVa9H\C%>b+Ii>89e&u+IY6>8RQ<TwpFj+5
/GZtb< :M=X/YB:9K<lK$pDD/Z=%S+BVYYNhL!=q6G!YNLtB&iADb6w\$>9%d*J>5pCn5^XBRY&uaJyB^/TeR4I
!d@GYc >Q4ceKAnG*@\@8pFyRk**lt/ju9qk&4I>y68Q8!QVYJmtqWN<^uQTiuuZnV*dqK$b!V+n1wMnXb1yC$q
Cq>QXW Vm\<EpA8DMyQ*N1uE#%Kb$bcVqj$H#q8S#dRHEPSWa<V4&iS9etPIuhejlXMnXT6nyIIDuM%%+YLuhF<
:qXMpD idj1<:T46>6/qW<hZ$C$:EQQL=hBw%:J5**Nt%A\ceh<hIP+Y^Lt8a/M5:Zn+eLiqybw+#\/?C^$Q8*w
^RbLdt >1WZD+&b<!iQ9LdiF4Bm:QbF+MXy@cYpP5nKR:imQN#lw?5Nd9dAkmtG9J^^<tSM+9t4qF4qR/K/XedL
jY%V4k jNQFZ8*D8i=uL8>TyXaqd*ujI<k!TV:!Sh$:8C$mi^JF%tHHu=9kFXmu&<8EjCJJ=@T\att*hkcHcl&R
<A=D4e +n^N$X4t6JkR?uZY/dTN8ajC&SP*TGy4GN$Z+\P/G9P*mmB?HymhD5eTcw8@MHJ9b!8i9FH54G#jqyR$
>cF#>+ !#&#IE^9ji*VA95S+Lin%d*aVL?tNMbIb?*H$Mam4nYw<i&hDRiP#cGQHJ55+lQWW6^Q4R5!^4*i:qQa
T5hAA? 1Z+@LeJ#?LXdtMNF#?LXhX4cy?Al&9F#FHbT*?kJN@@Y^haw*u$*$@JVP1MY/K1!8BSeRiPBmC1@%\Mw
cu\1jq @5e*=\/!Z!4YLw%G!6uljCL^KMMARknueCMS#iGqmb@tNZ?$h*#@GNZTY>KS9Y\PH/%&icZn+HP8cF!1
FGD^Qu &aY>NZFDVZZMZnj*+eZ>9M$Ytd^VYu6*?m!I8XEHy<+?!aqtL#TqHtZFKG@&Q\=4qu?<?Y:^Y^t$bjLy
?:XHTy GqKj:/:9#Q9\jVKiHpe1+nS%6KMce>IcA$q*T\cmRtIPLMht*bt+Q:dmYVE!dN^E8E&ymw9d&\+?PmHG
1D=dp= YDBDVN?6>l4e6G@K&@cR16^M?Vi4h&p!idTSyid*JS/jV?#VQ*5Qw=ZWa%N*j9H<pKnbiF^<*aP4Y#Xl
=mZ5^S EaEe^\BQSl9=^NYV4&Wk\LXC6^iK4&Niuakb9IQJp$4aX*G^&@=Nwqhm4iX\>4/NpWZ?$L=hZVj#L/:i
?M*HCB FW8l&N+:mGY/E\??+c%>9/tnw+!c1QB<CQ<Rq@\IB<?EuE9aBjNd<ilP>biVG>VJAp>bdG<+jQG?u*hR
i:1/lQ QC9$a9/nWw5m9Ki8=dQQ%=ClEi6yN+$SY6:dHFSN$6+?A%wNT*=6*@:^^ed9J*4hmJe?jH/?kE/<tqb:
WeHnlS iWKjY==<<GyV#MuI/iM!N:N&>a&<C?=JI?lH#FTh&pB=d6I>4ZV8%iHuWMZ*::aFXB98R$R5i6%h8hX/
W8kGXI >&H&jhNP*<khN\N*HQaMh\8>JV=R<*=98L*kCVZ??wdmdXh*ZF4VMd&nF*FkR$u!qj$n\^B@5?jHj:Fy
+/c8?C :ewj>dP9hed>cHa/nB$<wCcPP:+qa^Wp9+Yc&!L@&Nak*5XZF+K@1M%\V9q+ZiNT4aF94W/\^TyG@Xyu
Xl+56= wKaL99JaPPmY^/u#9JkKH/Y\V^dcZTmh6F@D<SbudD?y/ly@&dIk6i:iAlV9E\R:%R/@/Wib^eNL5>e$
!=:a#^ bY8Tq6bK%5Ilm&=:qZ=5/WYw6**8d$\h&JEcQ^#ydVmX&%!tiel/abjNG/1NDud1YR1D:?k*bt$*Ky5B
>G\tQP Q%uIt+GY?lY=Vlc4%XCd\JV/Sti*5JIwFejaN#M6i%iBp:ZR?9BFi+\?R@m18+JC<&nX>+4VnS:TPH+K
dwRZRP 9F/\=\91$MhYS^@%+KwGe6WC&FV6C8Bw:R5JNawQPqi!=MqQKhM^>HIThn\L!+l1nBCK9N+G6IGDEeRp
VN*5?u 6\Sl!>58:yc%5!MZ\wiHj#uY?$6#X+NpV*cbi@\d@b*>!HR>aFG>@llPXW4:RGl8%\NI$V$J??a6n4tF
<hyp56 <Ej9ZK*H%YbjqVmXVDb9cb8:kbBipunbFLF\#HqdGW5Y6$H&Yy5:dNLTYKMBF8H@Rt9hiHctMQaRPp9a
wJB\5J >Kd@DjB</^dJh&BNVMA=>\hJ!dSAtJ*6Na&IS5Fy+1KhV<p^5TQ8pJYR/^@Q^p6L^Ry1ui#&d>XwcDyW
E%cWPE Q=!n=GI!BwWw6YuX=da1hW:5eRp/%F4j&dwteB@ih\M9Mc:\46BGR96HiuH9+W:H=AqCyR:1&FddKji5
lNj5WI IAMMKjjB/hQwDc&C#pL#Vn?@jZw8cwLRF>i*EY@Niu5VLMS%JInQGma&Tphh1Ej\NT1\y:R8HEDX:Hw:
u=M$6Y :D>\Rb#NCMY>nH*&tD#8T^bull^#*tuCF6PdIRGLDSQ\$&$4Ee\itQc$y^@\1I%^i1Kq@+YBnqSA8D6I
h=?/5X :XybS8!ZW^MRk>GT1$:<^hQ/DhjTNnq?<@Sh4IkIP4CCZWjbwnh^qjl!!PCFwGH<tunJM><6&DjDH/P>
R=*wNi WALuc1mteKPa:Q*=TwJ*@YbieM^yjHQD>PGJ@caL5^q\@X@biMN/8/JVKWayGeRBR9F5q^q1VI8bRuVA
:RA$wt Gk9^P5D5qacS:nc?V8WP&ADPZEC#uDQWM%TBA5Nt6HA^+kMVJl<#T$TyE*>6^N?mDKF%uD$GnBASQqd8
JH$CTw J^$GX&8ILJDn*t$=P:/Ji*>@GV9\dJipPJ?$Fa/PM%XKVDc=jlq>bntudeK6WG*:8:94#\S6Nu%#e&TR
5wPBM5 qBBtQ$BtGRTh&F9!yuH9>IK\jL^AV9$:dXl4k?NkyWd*WNV<WIPQ9j6iwR>6I//=hEqPIe:IDDX5<>ya
VnSRl$ 9JL=%&BE$*<FQ9%ql6E@MlAe@9ny>9ibS8dEQ&B<@#*V/Li@W+uGj>D/@mQk/J<lC:@Lj$>W?EeR\<?p
KtmNcE H@**RIZj@>9B*?\@k^Z?b#4T9>Kw@m5hKj&*j*uEScZ@S:VFQ*KL@plJM4Q+B%4R+k<W8BZqH:<*y9#S
@NThd9 itPVQ+mM^qVLj++G@/NStd@uQj\PK9CKnwyn@TNA/jhn@M/F5dA!?b<BGj<K8@4Ly9$#*<LW+l>ZV@&n
I@?G#9 LXVVQ*/c@jH:Q>Ke1H?RHM*?ADKc@eFV^Jn>ecD@c1k^=d<HSJu?PSjn9@P$@uMwT@h*eHP#NQ6nPQ9Q
*:nIe% +c:Xd^j**+i&cYpt!iuyqpEijwq8Y+!e6<dFY8mt1kYHl/j/B%K*8IV48ccdpi\nTYS:b^<d$t>@>DX<
@#5t@t \u^5nj#y+Wcd%wX5atBR1SuJjubdGi9TQL$>6JLyi8uinuR@A?>M#YRHL*?LiF>>m\%^%89hKEt/MiFJ
Dj^S6: d86MQSMMNVh1cCbG&Z8Vat%$HdR^KFh#QV$QVe?$>FRDC?NNy1bccbtlBu/Bqq+cY@WTZa&6%W!*y6t5
dFd#tK h#h\MNGu?SqqMwKep%mllkbieedpXI5$W%I\B1Yj\ww*6+:SVR\LyEhw^TbRLF!TjQRVjLcc?c<L5%hQ
ZWFTSh *JJp4=dm=^qlaiHB51K8b:C<I\&5Ke/Pph4$*&/X8qQtd+eIZP?i9M=Dm=K8RdZRC>entduTuM!$6hYD
CZSYdp a<I&dVXLD&PF&aXy$kQZp\KbFC59t1&GCeXbp=XCm/b/Jntd/dM\1C*1%5pi<RpMj^66jTQ6^HANF#W9
L5Nt+V G=eWl#D#XLXpw<&i/>M&4\>&w=kHyQway%Im%Q\$ZH?:u++d\*$mdcM#a9S5MCn6mFTZCNKGbJbXcEc<
iJEPJ6 T/KV1*/Gy=F^JCZNVY>>bIdlXq8D%EnZ<Emt1*i\1:>i5JccLT&RFY964tc1Th1pb8bB^cDmpm%eknat
555mu* t%QJcwH/YuR6h%5>ZScDEY*54/ciGGdQ5A%Na/S4Yma=P#pGi8ydyY\!yGZat+RHYG>tdhpWwyQpmWHF
LSh$K< dFcLNR^qtYhT4YLnDcKnZdR&t+d1P9k=l6Fw=1+i5SH&6w:8<ZaYi4cBmeu1hlcdN6PVZEIMQC^mW<&&
+C$HdA BQnF@Ha99E^w&y556*yRapmbebVM&DTTuSp4LmDS!uhDatmt/cbNN6/GXDh@L*Q:^M$pb=%MS?Q%/Rq&
ekL*%J 5id?KWFB/u+PaTpaqAuVKYcncWac*THS\Ee:^hkqt8\V4=Z5FiQqFYWh\HAKDQZ%<Caui+WH$Z#CkllM
pFq<Wj I@KYhB@9hBMupt8/uach?VwMc4$qKT*C$CelKXJHK%VN^nI+W6e/k1Kb+B5byY6w48Yw:^QJbCSHJ%m:
/&i&*B B&Z//QwHtG8+y>L>@Y&hLM\mI>#$YJEaXECRad1bJ<NnM>QSmLRyp=t\Zn$y$N<=M!XEX!@h^NPM:K4N
nkMqlM Mwq$ew>kPThEi<h+GGwEi%nSRylYBqRuH%e:9@Wa%GbLk\&JYlw/EcbBb6d1XBj:pM$yFN@WwM%S8wGG
Vh:IRY AiGy$R/8Wb8$1e+?pSGSRi:Yul5%dDj4S#B$%bQVNukdlhn?b9A\Q*y!RLS&RyVLlnnHwDD@AE9Y%yDI
%B<aCW DD5QMyP1VmbV%9t6<>!c56ZZ%#:P&WDHYeQFi+@hZ@aj=9<*IZVWQ@m^@!&Enpw^?apR86@#=9+b=9M@
Jmp86/ u/y@V5j/+?H=d^G9yu@G<j%b?#iIX>M@+@n?4Q$d^K9yu*F<j/H>t\!#Q>Q+@1\%?:9#t9!E%8J96Ka@
E8h=t9 wj$d$M?j\Zl@%9+h\MdT:Ci$Fu?nNj@*&4>DT%n?lK>M@8+?@+T9VQ:8Q9?E4+#@=4^YQ?G49+&w5@wJ
qW5E:D a@$Pp9^L:W<a/&?+q1bYQ&E5a<8@@lJc@a!^#Q?t#V>l4L?lNbyc@aT^jme\@1ZY+u?l6j^jjEa@<<D/
V?#B%i /*k:K8WunGXtc9:ZY8Q@piFtaj:91AD@tRZ*i+cd!b>#+cn@ubQ&#=hTM<y9n=u@D%EBMIM\B!XmN%qZ
AINuMb Aca&Zn9CmB+9!l5wy+5:W?Z*w4ZZ8V=m^Bt@y8:u$K@+pW%nl:j=$mXhXQBKQX<mS+=FyM#EqS^a%>q:
!&<wNc i*^?=YQaDH*A1jEb!1QJQwBatA1nE#P#LjZE4Q4S&18K$J=W=h4RE@9E!\p^H$+lHeCZV:&5k9ehR//q
!Hb^^w %iu4Q!VA>I>@Jh?AnjcQ*VL65:ih#GP^I@BIA$IKHuMLd+5ZM!cH!n6GNqVJDpbtn$\PS4beqaBBBHeW
EH@$@C LDwDdCSLm6>9p?#ym@hdGka=HJR=Q?QSPGN8<N:#%XC1$tbepYF8G^+n5ZX+liN^IQVmCj/5E#lZtlLL
HcN*h? !Z9=JW$S*mKKq1TQnb^e5ypyY1<<$5httF8?j?<4$$/mZbWd19A9%S1=&bYn=F/^D1j9RT>MiJ9HPm8n
Q/?m\1 Sd$nmqGAaTb&VbhWDbuS<\J8Pmml$?eK/BQn/1YT\?<&JkaE?5u+me^$h#5Et>>6mZwwehI!j9:8uhZh
Ve9\c4 Z8:XHq:!ZYX4@bP*B=1P!h#8m^^eYX>ZhM?EBK4IX51dcR66SZHXFTWNq^d^6<htQQm&JdJuF:\e8?/i
@Cpa/w \w&lA/wiYPb+^BqhPcNw*k%9*bl*e=Pe9?/NQLEE+&*h:&R&!DVldlw#N5nAuEJ>!yXbpXj9A5PV#KL&
\5j18b +Pw#S6?Kny^1P*5u<*nS+$i*m>?k>?>&QG$=RN5+GdCKq/S:$bWZ4X=F^8ThPH8MEWh*E4RN#GH>>h#G
&mlkqG 99wim?&n*h985/%G<D1p:tCE%c5M<>Q++BMSpSLBJ6Wq=5WZE/QXZ<lV?q?$>b#pY4\pyj5y?Q9yJRwC
-AetE+ 00096f5014900110333 Page 15 of binaries1.zip
Jc/^iS FHb98C^T@Pk=a=QlBbJy*^u+ZY=TImq9$Zj15LTMqhIGZJ*D/?c9WZi*8:dIdI4QT$RZ1/e5#R%V\*/>
%\^P^Y Q@tt&dD6XiZ4/I$?n\8Q1b6VFSMYk4:j!XT@5EM%My\uG^9H:Hq#WwnHZG:^Qc/=h1J/MZTHbH+9#HTX
WBW8na y#:p>1H$jdjX^QH%wY?$:?^P<Q@%l6h$/8&Vn*b8L9w&j&%F+CRcK4e=%u@%<JtqdT?YLQV9JHV99@>\
du4!ED &:Zal*VHH:@mE/R5T<*YCa>NaJ/chq5c6p/SwL4uD8@Ea$/<%qcWhl!:/bBP*cwm1*e&LK:<@G=#BnDS
wdEQ4^ WQbE<RGwPYN+GCp>:=^B19h&MZk*!/$8Kd#Z4:Sd$PSF#jG<#jk!bqaie4H8@et6cnyddDw6:/5*#ejX
A^8w5Z FY%KbL!pD8NhbI66w\4Kl:W9%YdKKWMK*K:H9V5*=@q=LmDJ*JjX1qAYu^AlukA#a5m&b%*i1wVZ!G#e
kELT8$ ZdB@PS<aX%nh=qM$jYZiVV8H8Z%:jQt4N1&D<M4*I!Y/D#R8LkBHc<G1G^#*u:Y=\%iESA/Z6Vii:?eJ
Z#HjSn h:n=QaFj@b=*ahL\=1&Hw?HZ=EQNXp5iSQ6DNldp1qPm\PCCkAH6>#JI??w^=SEcPaZPMDP+i:q9^N+b
qeyEBL Q6l?Rma1mMeWP<kcD5i:?i>N1:Bi6a:NiDJk5XS?dMuc?uqi8FeA5FGMaAqj1E@!eZ1R=/B**+&$h=hS
&<%<Y> W@^INV+C:iaYj@l>\At=C/=t?Ybi!6Anl=+9GkRkNuty9R>?ZlHZ:KN%Z:P611Mkeqiij$DaW9YRnF9R
8Q8L>p Ye6<buQ=pLQl?E6Nq$MimSTQmhjYpl=mCGD$CkpdGhBYH$eu5lYPaePcQWPKnSj^%%T8VWTQB8ma#ul6
WD^8K8 N@B*<jB/::dDiWl^<PPF>CD4/q?eP%:=:N$5L:ETjmD6a@4NnMpD?6a%ZwN:HI=yLMykh?B$uj%&8LtX
DqhZ+/ !eqlVXGF%?WW<9L6FCd#QMT9#X*KVNYSAdb6wN&XHJ%LPFbh*8&e%1@nX=u\hb>$QN5ujQeG/aVMBa>:
d?ZeQB we5B+>LQq#G/>Mb6L=6e#MdGTq=j4$<RCt\GG*q^waRE=&$Ebhiwd<Y9H#wehdN/\H&+=@64/LYi11q=
+QVENI +&MD/eH>i!Stt9aemAXY:&=$5I:uQuW&y#^LjnuW%h:ac9IiL^FT>h:?=IYhbq@DZ^<+>C&%:j!bW>14
Ld6l*y u^JYZIW9*<$1Xi=KdKpCYbG1%^=19?Ll%KN>48uQ5n=P%&P+9XcEi5i&9HY+WBZNde?8Il>@ibKYG4HH
iql4kd Y4JR>jLPY&>#K8=\&&CGWhi*4qhSPMB:>^Lhc#dajLLN4dDET*%klFi%=a&HY<EZtW8C8@I9*D6><iJc
mElF<y Ee>n*8aaWl\=ZTb>u#/AqD*9bCcMt>%t*4TV&46mXy9u9+me9Z%5PiwCytlKj!!lPiht1qu^jWjD/P&y
Ti5TA= y=1P>Le1>^uu85T<9P#qj</6:dk%bDNXPn\qNeq@9Y9G*aNj5/+Ld<yPM5jc1Ki@Z!>WiuF%+JCkbCw9
:4\pLq JcB?XQyqdX?5qbjt+HJLYMH<VWLXCP^EGD/S/4#%nH?Y</9QAiVRcZS^^FuiXP4F\We1a#G=LH>Zu8D<
WQwaQ* !QDMP=5QmRdiW$wdM6L&9V@k<QW<<jBP8\iQk6:\uq&XXXT<5Qj%CPNE1>wQm/9*8le1G!S&6tLZd*C=
EES=4S $qTYqt#$+9K^T5?QG#=Jy!T<V$6&ZL@ScNa:?I5@*$WJ/dH*B/LQ:Cl5:CMb?>V/RH^CtkM%&!:BZ1u<
S6Kwbb RLbenI@5F4Hm\HmaE4t6DTmy:C^FMTquT/%E!d59NBTc^Z!+:Z5!WQXL96/CZ#p^T>qJ=/H:h*l*mZ11
LPlmII MP/W?9%&M\^n@pLT$@Ydji?dld:V&bdP=Z><KQ>W4M>JJ9V>>a6G&>$*JZEP&Z&a5X=!ich<=EBcW?qa
H9WV/A JeLS98t\iMe<Pec11?btjFLF@NZl=8IXhjjK=aXw^=It@=XN=mhiQE#@%B*:6id1kaw9Ldn45tnWYW^j
D*nhR& Xkk/*%cwhNye==NdaST:/iwbn%>hnlSh&/b+y>yK&?LtM@&4m/Ln1mcR<!&uSF%Vbq@E#R1*PN%@Kmc=
TtDI\e =Z+=<hD:m&@iNhwcGYq$#98<K$YwH9G=8Xnb*Q+BEZMdPZHu=AQZ=ph*%R?a<e9!S!+jc@6BHXQkQi6*
6H:VJ9 HWu==FnEI1cb&a<Jd@h<ejW&hX6cG@p+tNm!yT*wJ5\>qN<Y:qRTPi<<n^^:\D5GY/\Kd8A@^eaeM<VB
V?^Pud V6n9%qKL>Jw*$%56eC:Le\!1n5THPl+!!/eXc4a+QH6!kjpM5=#Tw=eY:D44tMJM9mX!FcchydVQ^LCD
W9Jk#$ u#W:#weZNDyL/D1kqm>BB#ekG\Kc%QHbe+^q/KEqmGhYa5<DH9ce%6y%L<>w>Gy8M>Hw&yIEDIkd#DIj
?HdLAP Y8qj<Q=^4Qd1M9wSlHaV+4lN:<i^bp5LJ/yEy&#@$5ptVY48X4llIe1A?%K:\=^XjCS*cQ1FM*BmIPIw
IhuRBh $6:NYCYp/X8+=4Q\66tRuBI*nQ$8ZjiQQ4e?N:\=cA@>ZpVaD+h&N<WHcYTN8GV+/AS%HSj6j=:^+<R8
mbZ/mS 6\LZke:&!y5^=5bHFaYMt<9IJ!>pi%=FadR!<i&@KMSM=tn8LY@<XTulVR&D\8b?kyR\a>A+tSiLD#SM
a4p5Ma uKMnEnXD>=!EQmwRtGqtZh:!ClbXmw+M9n/T<Xn+JGM5QJH+ZN%FTcBZ<?:/:EAP*t*iVySTqYH\/QFX
MS*uwe !q6Jmi\*=uqNJS9RZ5S*W+<ehlJ9*p1IKpp+iW%#kycS1p5Xqw&$/>@RM!u4dN^#<5iGZPe==uDTXij6
41@4bl Akdmded6XCae<8QI4TP8%<5eu5h5%:/\J*ua4CAqJSECuuCFX?nc8N\KiZal>GYltMFi8EQZ*idJ*wc!
$*QiY$ i9hhH4=&8/K6PR%dFjI9uFV*9GGT5LMJ!#k>H?V+Lb/beD$uSJ?5Wem<d*!5=%i$@n*Wa\QcHcN!14@Z
BW$<y$ Z9k!j?!>%p+u?F=N=LiI66@GIPa9WnAtV+LeNCJ!p+&<:T#j88<W9KKIBVYhcDZC*lJwY9hjuRl?*4ku
WZYbNh Z<h5\N>EiN@ewY8**pMF@Ta#+&jHl1?ItT!H9k?NtC8*9yN$p*#KM6$bw><?MX!&LhHA<u$B*p9jG8/u
Wh*i1Q *Y?hWqBAhQZ?pt81Vu\YJ%*:BNjqX4^Xh5tJiDZ6YGS+<8BB4Q@qqqGY\ctIt#mpJ>#aLm=j>W&$*iA/
huY<m$ 1F5=k6EhRHtM:uTE<*@5Ft/B9RMQnDF&cFnt+!&H!nRiXHt:B\SaaTjTKIRH8T5PT$iw\?&jNJ\6DSnW
ud9kA+ Te8Hda<qEw/JPi&YiQatALP+c>L%Dd+aG&Wq@WdPmXK16F46pP@qeIy!*?*J@ja9Z+jnn\mQ^J9EZ1mT
jljibF XM6jmnZ$uPPX#E*a^i5eeumnw?a%?pnk/*$!+N4y!jTd<bH\Y$:DW!tapdn<q4VZ1+>ZH%teyFlyuFFP
Z1#d?& a%!dm:ml>%uZ=bZZcX?NLT=i#W5iH96>d!u:XMut6#Mhp\iW6#k#JDbDJ5CLe*bwM\Y$wZt<65L%$alE
T4^>l@ !6w$V8taR*hCXG&Zi5KQ#6eBYp<GIa#<>y/l4jGlmI4##X<PTNAT6Cy59J/Vl4lQ<SqbN#@:dMHHc#98
=ZddIK PT8%NyEHk:=^M#M%dDPXdb=K%Nw#i%hah9jR:4T^APKA4$q:JCSB:G1G^b*+L$uXnCw=tw^nbiMl<?5t
nSejQN AbA/T>\Tblu?!VSkY<qn=lc%!&kuNWaMk=@:Ey4&FDG/ydF=JyLl#*CV#4JQYk%&8%6qYTQqa44t$lXp
#jCK+B $h!i*4$^emA/lnyX$A%%yTLNQa?eNR?NFePYVV/=Chu%!^9*5kHQ+FPct%6<eGLqCPVJS8LItS9eTL#A
bPpkl\ tjnA*dqDkFqi$QM*:Dn\\*QZ4q6$qwTeTpNbe5YS44!*BISP\tnw%4M?CHM#aDTTjD#N+wb@jQp6*ktJ
LZ$l&G cuJ@FW?K>+/1&>HVY&MSGRSK9HWkdRTcHmR/ee9QX%NhHLq/LdIklTeVq:8PtEhP%NX\P@Q6T4X$cFPu
QHuScD T*FL5+DytCTnJ&T<YNmY&jm5MKF&i$4@4cYD/%jeQ!/KM/<P>$GmJCc@SdTG:VtGn^@/nE!bdZ^?V#5w
/HNuBK i<iHahV%w4qMldp6Ll6QZNPGMVK$L5SVd8ZLAuhmb:8c9th9\BaNe!WTHEnQ:8&+?#m>w88F*#ed$=V?
YV9DeL n^Dc=A@hE!V#%JjB&*^X:4S9d#^1+N>8=inMd=#%1N^mLDZw:/@DQ6dF:@Lae#%1#*6F@a4*Z8t/!Xe:
5pk6X* Lj\uQ$C/hp>Mt:?uZdunaH#uF?/?F#uy+be4S&%w:#%PbdY?PNp&/*ye6@$+FE5S$HV4Lh8lL*P9D?8*
<w4Bh9 ZdiQH%5qM5TAy#4wCDV:TdFip!V!!CuIBi9+NjVLd#d^K^?DwGhy<%5ZTuZHT@c>p4DZp@L1!R:WW&4Z
TKVj<P 8YC9S?ab/u/X*Ccny9<?\9%4e?^cbeIq9YFj9XNPH6!4=6M&I^V61/J6H1@KWPC8e&EZwEeCkLGhq5Pj
Gq+Xkm P4>wYC/@ABJLHi^kJX?E1h/jc8NbVkaXL^bj?Ep%RZ1@Pb!ymD8y#d%X6>*N:p%XpeG6@p+Lt%Lp9L^E
MPVFyR AH<#QJyc::4/m*y#65Wb&y9&w&@SG*kF$KY^wCbce5Xqh>QT@h5pymW!TXNV8&XtpAG!$SRV>Za5MVD+
q!/PXZ Yh1b8P5p*L8GMt&V<M+==Tki/*X5YZ#Sp:L5^<m$e*G%9pHa:h%VP!cGN#RiQP#4b9&c*X*$V94/Q15p
@lK?5L ZdeC?cT<uE#Z+SPn:\+@4&iu%G+i1KM9C!Nc=XPQ&Vw5>jT?<d86aNBRV4^&j5@#49Gn%8TnMN4YSY#c
*FCXHR @wIN&&a1*iJ91pec=TV5=Lhl^ki#:kkGn6ER?l%bPWp=XY6lnF4BibyB#l5>9@5Xd?*YJKw\$jB*N/C6
GjyRT9 dil>5=j>Nib1LK^j?D6HZJ$%Kt#BjPkwP*:VS:9NZK5?/b:D6u*DXtTm*&A>P<LC%<@*lDa?EZi9Qcw!
mQC1MH RQ6&%4PJiJQWE&dTG%PE>!waRYAQ*\$u6=/NieSiVDS/&TVXt8j+Sd&Fbly!%RFkHSwtV^L$GlITt#XZ
>nbJn/ T&=qM$w%a/@8XC1@l%5TtpG@T@qi*n*ue^m>9&t\?uD?lcw:N4pK$V1lMbdA/C%K*5+9F4bL8&KNFY\/
PJkZJH VcljQI:!=:wd#y+@ELS>@N/F9dc%P\8!iSGYYq<56e+&64>5ihnbDQG8<mYZDWS&HYA5nKQY&u@y=p<F
D@kiDi \Ayh9d#Pj&%yQ8FRu@?w?GBG4LX:d?wh+*p46^JbZ6E:G*/me4TV^M:Z*V/9G^@i^N6<S$@SJBS9N/Sl
/%k:I1 BE*Smw*Qq8S@qdA/e9W>V6Yya?ua^R5&S?Y$L6bJTHn9<lq1K>+bGe#E@&1JGY@b$uC^nL?kjSE@&Keu
LNtkpJ BZ<S<F1MFqNiQjqW??VVuQahZ>c&uydhqeeN>um*1VuH>:V#uJ?/V+bw$QdM#8/T6FLy&G$bnNQ4TAnT
/!Yd4M CSPeu<NPS@:u#1ahb+>:KYhK=@taiiIydY?1HLX%cNebEm=tC5Y:il+%IM^W/j=:Zd>%iMl!uGMh^PZ=
jP&?&F &@j9&CpjY^S6NtFi>eNFiwIMHL>EjR6j6#:^Y5^n6R%R=@**&@&*VcS5#>tRaQ$p^/9&P#*Y=RQ>I:n=
C!jmni 5dQVl@tiRi:DLVeu#CZ9YcSQNjSab\b>#R^>Q$^cn\^ImcYc*#ph?Mwy8$dH^Dww8Ttn&9S$eDLwaa>%
q9Vh<! yQl*ai=u=qC4tQiW#a:>JVq*nniK&m:TC=DyY&P?yD9JI!>M:X48Gey*#+=P49D%@k:G56SbV^n$hy*Z
-AFE5h 0004dfa8c6e00110333 Page 16 of binaries1.zip
mdZSAA TWQWq+:jpJ?mH!hbdCJ4qw$@9*d&hQ4Pe?4WV&E&i51b>c$^j4c#j\%1?5h1$@<q1Ppum^y?q64$n+Z<
jJYc5: @@MFM>M@Wb8wy9>H%Cc1meY@WJ9?Pb*/Q!hy@#Rb@5@Tk*?:EpcqtQ>::h?5\FEyF9>ic&:=N?i%@At6
b&T+=l 8eXjc/*?9jd*FaK@$lyVjpJ4d94ZY8Pj$FL@St9!::Wtj*hi$=@Rtl4@6bd/E%4n9>H?nK?5@pd:E::/
JRh*MJ HXQ#q>1j<JY^&h>wj<JZj:iK>n56/>?Kj%<T?T86CiX@wj$Ja=qdWQ>c?^QGMnin@LZ&J+^q?6hLuXRV
:NR%qt /5><Gc#?Yt9&9:li<@?F%8I9kE9@#^@V#\GZjq<pN:PmEu>9ujuQwL4@<TV@d\64@&#F@<QC&u<CpZ=j
/bwF?m YDQ:e^Ea%iV@Aw=E@T5+p4HF:>#/9<An@jhmQ14y@/Antb6bWH?cnyRnFFKCQhWW$dtD^Hhp11GmBH>w
ZRck!e 61^qMkttW8R+=*6j!e=DQu>E$&<:9nqEb6>X#at+^9yE/i1d$Yi!&=>6N#q/>jthC^4>Y?lq+/&+8L8/
u+68ND ldSDuyEjhD%%<:*dA:VQ8q?KQ^HY+j9mk*ZmDl/4/by?6+jZ*nMJuZeVQq/5uk4e%LQ^#d*C5&tjj#t:
a#=YIM MTXR5Su<PPd!VM1$>SQb<h#lCMP%4%M?!99+5&?5Ew1jc^/+Lp4j:9+n$mZ@hu!1%YG6+%dHd9XS=R%p
eRq@FP <:&Ky=>?*QH/=J*pyphQ#%:w#S5w:yq:i@dk>&eNBh$L!/ql/?:=<$cjL%9bQmqNQyQ?k5/tWal+NAIK
&C+DIT y6M/wp$HDn:?>HFV$6HI+^>jjX&=wu4qqh$ZpCBFBRptqttl\IIPR#TEKKBme6m9q4>e8bt?>8*m:TXV
YW+EC& 6DX&%AnqpA1%#wEI%&naZD4BXT1*#%wBD!P!A&V/n#>edBy+N=m$=yL<cMi9@ctVPT4tw8XkYT+>Jb\A
%#ewdE %&?Jp5<4Q:+bh>=d9?YN?$V:!e<n1c5Zmi=iT=$Gq&=cYm9p>jYpKPZVH$myIPyek%YluDW&5b8&tC99
FK%K%l cIL9j?=mMu4X\Mbj\<1ipR#>18d#=yY8ND?C1KdG9<G$XT<A8%by*1qc4NW1GPp+R9bN?/BI6&Qe^iB<
iR<I&^ bd\k@kFuaJHm8q\?Z\eXWa>Y*q5*W8BXENF^WlW=K>VX9<Mh/?dq&a58lk^QjI?LC#Y#KR?<QbX:LPl8
uScw%M $ILEdjH?NTGq!JW!dIJ8MLNE<td=6@I^EKCGY8^XNpXqB$$PBV#<6BDmiHj<?:G6nP+Q9@/!WXe+dX+<
MH4%u# 5AMNl?d\4C%LcC6M1$J8MN>cjc=q!WbWFhny9DpADnPM5uL&eGFPi&?5$Bt\ZEcYpyuYaAS?eZZhMN>!
y9t&tZ #c=+aQuZZRIcp&\keh:#S9tWRuV$Mid&Vd+dSD&\m<e*6=Vy$:BpPyS?y\/JWmESR=Bcba*GEntIZLwW
i4TLMB /WHNp</eq@6qN#i@?dLuje6L&bNNY%5k4Tkui*5&E8M91JQNl#ScEhT\aFG5<@QBXAA/@:WGX=8<<?QZ
u5htu$ t$uuN/#j9Y1>&YcMGJYhBBM+e1T>C?d=kD\TYH9nl6Pw%de6Y1\n8%eMStu&4B//:VH:^5:Pc@/>uYQn
nY&p9H Wcq=Bdl!JSTw5aSH$el!aw+nwX:I?j6\d&tBM=>aPimt8iN#TM##jd8@Qb@4*dQ#*19LGV<!8+/mbwYL
X!aKht SMjkCElhm%wP!++M41*D$/keQuFNR4nwD%M4M5wh$=CkP>V@atV\9Hjc<wjw@b9$=AueqXn*H?LEhZl8
++Jb#a FYE9T\91WHEBAHdIa^ub+$nCMSpRYR^m:HiZbZMpJ/Xk+9JW<:5/6M9&Wq\qcD^Acmk+HeZ6CMwulcu#
jYTQlh 5kX=ApCKQT8lD!Qc=SmC9k/T4:>W&?nPH/<kD9N6yNYIkQnYFp%i8dY?W>pbkAYaI$c?1aJVGLL$VZba
PQ\Lpn a\1Y?QXweTyaddD&9uyp4u9^8=b!@4u&a\GLBbL>56=ISyL5yt\QYVaknW!NMYBGySad@HB&LFBZZ<mw
&!?W@Z 1q:yD1\E4NWcB<@9e<?\AI@bG?VY<1SHL4nbm<W<d4D=W8=uHiytFYKm9uXEp96p$<%AT$QaCBjEZ6wp
$lQ+^< #6!1&=#iWG=+^PttGEu@tPQ6HKeP%*!T6qp8WC*XqlKa$=iF+XH5=dla$C&^a856?B@:$%W!d<yjqZ>8
ND%I\* AFNnL#pWn8*Sh?JjqmMFGANCc!P<!E&<:@EWp4RH%tKdYGh+IGyC?4Q4C<jSR^PDd>Ek%DER5m?VDRS1
?c+SB1 :+Xb/RTmt14kEYQYIP!L%=b&A$kb6=VL6F#Gtec4jqXn:t:$%p9Ia&b&/djcYwJB$+:?uD+:yQNMRJ!M
tnXd&B j&9Zn+wyqE@\eZ6ypG/tH=y!#P@&&em&8>iQiIl6bil%#VD:qlXd?@kAtD>$E9:5\wcCk?6jHa=44:aZ
Apk19= HB4LM1+TDRAkj8R$hX%E8=h*^>tc+TqFc9G\@TG5EADBA^=9&d48/Npk\:b:G!X>&1@NkFAyG<yw^IqE
%YtBF! J<<#5li1:?&$Cp>\/n$Y>DpZCLR$GCH!IhWHHwhinE^@I:Ply/b:aPMhKCyA%AhnRwNRP@iHJV/?&=Q=
AIicCZ <8tDL#^4TDAM81@6a@nFS/Bp*y6Lu+a@Q6*+hMhd*5e4G&=>jHynmqRq55DTwH/=it@*JD<S8<!8?JX=
#nEF== THJQml*8W1*lB:+YJQ%p<eHPjYAPP*T#YTieNBleK8WlaAN$R<&l+FP!EecX9NjSN4$d*Fhab>#q?n5c
9d^8Hc JH4i1pR?&q&/A1iQlEm1Se/Rn#p#RLn/u8l=EN5WHy5uQj6YdTH5SQWK<wIa:VqlE*yL*5ttBWQY4m&t
J@KH=9 n^I#m>qu@B65Ai=PV#y:ebNpA<E^9++1N@Anwnecm$e5>h^>d:i#t^C#@L^?@*=Ve^aL+tDG^tbyK^B6
naWE@P IDtPHllT5^pRFRbYIN#e<8nHXG4NwdELCAZQSN!?<b/:@k$$dnF#GID*:BCLiJVkZkGFPN!JGuiT>Iq?
VmQ58m LJbu=m!eyEH<q$#:FTbj%ptywVjqC?*NHYk&ee#S^Hk9t/NuQ@aNY@k\ZpjAP4NY/I4^Ka:ebc1CI>qK
*/ubST wp<@TRYAT8hpH*mpJSt?mNq&d69qS\W:e*dXnQuuD\B+TXc:ZD9wq=N<ekCI6KkF:Tn59YZ?aXL^qeLd
<^@Aq9 l#ph&=/6/c8=iYQGM4Rk:EwwM$Y46c?ZDla<qJ>kJ4?D&k\iQKa\i&l#bMkS$>GdHRT^TLc^tCm+GIH$
yRZ#u! nTVy8$GIaEu:!jQTn<:49pjM*LE/iiXl/yYD:@#/$ZtEDn!#N^jm&/+=yHaI*/mj16Mu%BcT%:%ETN8^
VJjhpS 9=?b#JwKj/Mw&jdiGR6BEPRWlIQe9iYYakMXl=CP?qR\4pX?pL>S+dDmj8p>l:=h*C\:6991=p?d6d+P
GHV9yP R/cR>A@*Ib$JyCG>W>KZKYtkh>iy*LJwyeH\&<qiubh/p:NYNl\>GLPbjCPJ+1Ep8lLQBw%yDFN$FX&/
wt4YHQ 8QunKL&B+GK+9Xjci&:h*I#&tdcN+mQZ*^1<qkt&EhNNWaZ:S4lB?X4EkX*/P/WP4=I5Jn=e89H!:bZE
p=*kD& S@iYZ=T\CbwF9:*@lP?:bclcn>@#yQ%Zu/tXW$>?HZBG5Cd>PXyKwwC:5+MAdWYJqIIRR*&$D@/Xj^Mw
6m+$>A NaJIh5^l+h@6k^ShF*GkiEKEBy^?lFA*BYWGi\tDREVSnKBG14WA#M$En#!Gq@/KwKSMnqq@G>C+B:QG
8tEiWc 5LRk5$S^qlee1BHn8APAdBY^Spywm4n><eMddRVDFHLnRI*Q!T?ScbJN%8LEq=J>=t1A6%Jety\wC$/j
eL:k:\ ^lA4qQy!yVk:<CA:6\=#D&#Cj5a4CKQui\FJQAWeYEeMh#5y^@\t!hX+^Ay:uFJ^uytHbd1C&cjF/q#S
JlRkd5 ^M9KHcjAHT*QKMBb\&PIiIVp8KWN$%9lGkWualKE*t1$b&Dc5NJ#JkB+T!$@RGtNAABD>t1$bNJtcePn
pmBP>5 +8LCL?Y:Pw19ID4NTRJwlCea\=/WJV=lC*KqbtnK\mX^+KN@ZR+<aqwG?a8e>$G=WlJB#+mAdV\#VlhZ
9NewS? :<Z4GE1L+JAE8**$WhtWMmt\FEnAq8I\Huiiq^n9@YJ<FY@aJFq/kqDYdpJnFwnMqX?$m:H>aICG9<CX
Pj!GdT TM8Ta+uEmP%XyGPTB6tT6^=>^BZK9dPSi96w*QmLB4N5pFEQAEV@Pm^A&+NyNc\E6FTMX%/Zj@^8+1I?
:VG/Nw AXL9#J&8kEpQ^PJZ\9i^5GX%a@+CNclPqkVJFy$9J@q8>e+:M&LcFmZwTG9uDY$aGn1nhKA8ReW*HkCc
S\:*#d ^Yk>5BhytD=LQLDT6YI5LXWuh#ybP&&>Rb4>^&jQaCA1A1kTJ^$C5&Qqq$cJNG<WP^9BiaaVG8KJSVBE
KyqWb! 91/>k<R4A>$VL41<<:wVP#WkeKlwEHi<&<D%1tFFuEHuFaN*A+at^+ktV64?L6yG!q1u9yw+6+>KP=qI
+MJl1* dci?q%i>5$:hqK=c/Y98:/b#e$B*bedMd#e1QX*4#ncVhHX#$*L#>GR4@*Dn>$wZ*?iw9t?%P9*5l*Va
i9<T&q /@j4dj#Q1Fh8XS1DtXjtY+#*Yi8q/$tj5Hp@>1bT#>D@4uXpLIy>C/DbTk1@\Q*j/byiNd@VcVW\D!h%
mNV9@> @W/caJpk/FZ!6HW&HejZM\FaARWNcIByQiJyn!*jH%WK$LinBcpWWMT1dJEbM89>>VXwWJt+DIpAy*YV
V$=E<e <86TXw5FLDGayc#A^yG16+/8+\^/wje?e>%:j?5#Z=KI*8ACm8T68</XD81CLKTd!jpMj&1Z1e%pWAe:
>t9MKc W%Mp/dK/*TKHKi>t4%RcAq>%<XkN>ER%Tk>bkqQpZTi*8SMBMXENqP:9nl?!4j#8nWyyE6aiZ>&+9t1F
BNB!YH &FeDy8?&1ZyP#=n#eTQByP=/TSi:m@L8WF?+Vb/!T6>^q6lhLu*HK/DVbjKVW#ZP:C#E4Y9B:RQM$<#J
HduT1L >//Bu#TQph:uh>dZQ>DG?c!H@Rj%RP1J\A?kAJq%nP1N4l>Wk&S<AnLZd<neGm!n8PFDZHBtc6DhVaHy
ey^pj+ M$Gb%T=uA#jeLR$PhAmwQ8n*+YlwhX%RwGqI=4tR8@5*twYE!GRGu#$YZH$<+K/^j+4SywBLaVLuN=Y>
%FL!9P &!m#EHd*<ec:F$Q9ZkuQdAm4V6+aPGQ<aV#$\+9Nkh<*WP?Ejhm?!S#nc@a=^P#Xbyt*VLQ*#C!h#Xt+
1h<+dT aHQF5C!n+Cq^cYcY8QCTw1^XtFpncedj^ZM<M9NGSD>W=jVh<N5cKDbiGyRp:tcJIXuCtiQPYWHWt4DJ
iCV+N* :kDTnJ%K*!uVE#DYB!KC&T*QjIb4IWAE6<Tb=?VMk\HRBaW?<KcQ#Gi$LHpSDc^yni+VK4ECyP9imNYX
p6wjZt aGS*tI85qVu^BL>jYR=LMnP*5M\iGC*j9waVJ^$PEelm?^duP!1kyEtMkK\pCJYl^?N+dqFe6I1RklL%
qbd9!k mM$WkG1MyWSnMtKG/L:ji4tmWcG%DKpDLWmZM=hIEqt45M8WBK9mM^6ny>VM?ybXpDEI+Ty<bpYYqI6m
pIj1=k &^l9iRMSbGE+Y?!LLNMFAAa$FRK#XiqdqR@IkQc=m=GY=VKjpAVEIhGc=M\dVN<FBNFT@N=8Fl6AML$q
BWEF*R /8wp1yeAt9F&y?FYi^1C:RwG8WR/4!mZ<TWEcAtllm1LkKEy:6J!\SDbCJyCSq*#K!+WIqBTmDHBAtGT
Pa$&WV hAcM>pWSqI8hpYPD$?ApS%W&Xwb8Ep+Q!uN\l>T^$+wG^j5iqBTBqaFulkIAT$\Byy^CYddk=<$w+tWX
Vj=SmB WR&PGIaAKatJ$8R+dcB6@F#ZiRZkI\T$JE+:Lebbti19kyM!5tQtMb\Wj<HGHVubINd:\pBLD%E8KpIj
-AkIIT 000d71a92bf00110333 Page 17 of binaries1.zip
It%\9k VpPK#TTW%PuK#eSDmGY1Ap6E8:+SS%cC$/9Wb%ZAAbREWG&h%/d%J>FS5RByq+!>FHRtR/=9BFQ*uAT#
5>&V*% ^AKuqYi$FQ45FEZ/$4SjK$R@XEB:aVN&8L+qedcn%BkVVJ?C$Mm%dG<b#Th1Rwa55%/l65Xq=lX/!FaX
w:h\Rm PGVP6yWD4h<c!EZq<WEkQIpalSZNK>GY^jhB^XmAqHBCmu=BiwaCAb&4BH+Ak\TbGh>K$b$1y!t+WA9%
eRpTN6 MS#HuNbqSwpLJmGqk*!/*^#@yay5PA4IW?&DKEcM!NFV?1e9Y>P/!?1RMMj4CHadmtWuCe!iP1?+u$$F
R^$t&M k=cXAcMD&!p+#n\PTJABYWwRNR6Pn51DDpEMG6XAcm16KKJkWJqwKi@aScAL+eI>15K#$bDHFGIdm4SD
n8YSX6 4w<GaXuDlJw<6?Q&wEM1uH1\!A+mnJAZ+kHAG5PbRGqNnR5QIWWN4e8LkTKP@G@*18=4>G\ctqtlhMI$
9yyPw^ tLRDST?VE+^IWLVIRt<+eR#CYbPkw%XBT:J>V<p/&?^BZLRkARVk+eSBKG&T^P=FC89lVT5AChb1jiT%
1Jc\86 m!*$KqcMidCqS\4C\e9PJGVPwJTG>hXB@B@*X^^JK9K**eXA>:h\XiC$dk!wDW@/kc\Lq&a9aTbbJ=tP
\Wq+%J Eu*DKFG5It$aTWL=>R\nmjEwWk&SB5X?PX4>^X=VhA=L%^jd>8\W$S6Lb!QwZZlT=RXtB=bWm^J\JRVh
pijN:E ?YAwkSpGalQ\G@M\NKm+eL^u^%EXD+Ipb$<q$K/5JwXtkYZbGAM%N1:PBC<4SRaPd/j4w^<cW4?/mkuh
^=<KPT FYt@ZGBXIEV?F$SeZB$5GplDaBwS4JianZp!SG@^C+h:tQH*HB\SbSJm#CTaGl^P8m!&?kR/a?HKmFCw
G9Nmcb y$D1B9Ed#RPbdSW#?tAc\$kWBSF!=YjAp48\mJp8BZb^*^twG4%bEy!L+l#6aYbABJ/kl&Mw9ST>W>*?
k9k^nT Ayd6:B++9Rlb>%KidVX1&!?>!&A$4B@i8PbCXFB5yTkBdWRSFMe^<YjZapH+pFq:%V1D!>K>pPNE@=bL
b4V^nk P?4lIEGaElFA5VNHlbd!B>#GcbbyPiEuw1%IH$QB1M5p64je\\w^inbS>P^Z5\hJVCn5GkWWRRDwWPkM
^c+#bB temMA4E9\Pp:pNT>BmAwiB$bwP%Ajl6FEShS/=ScHW+4mqEc\ZBqWk%Y6Ae1I1Bb6ZABWyq$AGC^Vak4
1eF%M? YGD*?KPB%8>K<5#Y/IWP<XWX=K\EuFwq#yqZyA5WPWEa!n=w#>%IWG\q/ktFca$B+Cy%*wl:uny>ZiIp
nTqT1d kbV!:wjKHR1A@F=ImwVk6^GnZhiMu^lJwA8KPmWaSe^KKJ$ct6VCQui!B8wJGJAhl4&MwB>RISw1C/Vp
%>i#P% &EYuudEIpdBe/a4IDucQii56N$L<&nN@6ytiTEy!yle$$/$5tAe+8/CeS/nT/!bEmkJNVLVy:Gnj@81?
lQ#>5/ q*b55YQ$dnZctwyR5&$Ync5Va4G8^Bq9NMnFHTT4+GTNj>^LEtbDBAyaikd/6$eI$XYCF1^M@HT@4\hl
nnBEdV u\El/S*/EVp84Jhq^ph!T+SADddhG\CGXdYt>PkuM$Zj@P4l1yh5=mC!BQpK&Z1CTq$#mDT1R9iYbP/B
RC=*lT e4IW?*:k95iaAmel>G&>Q\/?@ha9Q&PP5tCTcEEw^S:<C\4$mya1jSZHiRDq>IKaH^XE:mAmwuAIKe&=
6MEG85 ?G#>=wi&A+pP!!DP5$wk%VRCm1aH1d!dX&Pu:/jdE$YDaye9M$ZY<49A8AJVukDA5>wpPV5WRSMEVkWk
R:n9MV 6FTpi<w!h\EkAyIqWkEDNqdpVVD5IlkuBkA5F#q!GkqZ+DkLp?Ku%GN+>nTKEMSR<>C51&NC#p6a1QBI
tiV8+& Gt:nXbw%?!1Gb*D*G/iTVR?+N/qLbbA\cy4FV#4aeiXacQcytm&tLhjW>JS9pS\/Xk*WuA@*k*lST5+G
RYLPHl ?E=uNbSX#&G@TZIXIle*kR\/X$hkGhb5Z%1B8M5LHc+*ntWFdAIkLdlNQ:Bd%m9QVn@KY1<T:*4#iXq:
ej/Tbn i\y\1e:%aCWVdJB$yj=YHTSE8lilGKB45qdWjSb/lu#EJTLmPP&<9Z\@TN^mdZ+!j:jG=y6Pm@MWJKD/
btZ^FG yEFL/yCWd?LYLT:?\GdT@hi^C<aL/AKyVd^Dh#:$*F?^>\Dd<\T*tujijFh%e+lya8ZandH6cuEheXQd
yKAtkS %\p59nStR/&^EpWS:+I#14cpXmZaD8\HuG$ab%T<BG<@T&!yX&i5<KYb<khM1R98qm?S\yRwiLGDbc<#
cKH:W? P+>byq:KQP>8b#cE4aY&^@adhk/?4hR@XMjdcd/V:haBDaQcm%N+wHl5IwcEaD<!en&6t!&^##tAVh/@
@Q>qJD &FMCLmnAtSm\RTQB\Zq5k8%tXB$yX^W*H?INIARSYCPj=J^u8enb+BBXSk6:<d4/5L&niZMnbT8yD9:F
%udqQm pX=H>**=/hLKHZJ^:1BXLb@V%&IJcZE<45XV%6:dDEDueic:WW%IjZIJLZWiIkd?#R=FdL*SJQVX&V+m
Eh=1@1 a/T5*4VP\cpw5<Xbu:FJZ5C\N5lupSe>+akCqXA<jE*KF<aV8j/m*ES88!iuAV1q11<u:?Rh4nQ6dYCc
^>d5S/ =JiAFw6JKCC*PJ:^!^%#<VI@jC^9$>=PMAwZC<k*^\YH=jLIWAq=GlVmKiLNwGDB>^I?9tED8Cjq/+XA
8y6>qF hwDSJNle6hGlJABA^emcdw@i*kH#da?c=Y&8W/j*bBRIZaPDWDHu9$CQeyc@SQEn?n4AXW%Y\epKyec4
N*5*qE PKBG!:dkI1eE&=pu/V4l*C\RE\FI5H^&iHpiaW<I8C>E=Itj!&c4X8eS<c4=b#^eAj!e&>t5JYTbS>Dt
!cmLtD 14*^bNMIyn8Q4X=:ikQNIHZm=4+S^nSqT?>tNb=Dq$/QjcN>S?SR#M$>!MT>LmW>uel=YSTAeeQilLAl
A+Y16c ?^<i1NM<+Kmy8$mdTwk=>J&c!/iTQ%I$HQJwACGuNpyCq4/MIpN?EPilGHleBlpmnQWX8pMye=HLW=Rh
wq&LE/ QLu5D!9qCn8NShIHBPRmKVpiGcp8u$eaSRm1XCAh%6YdZAEe=@/>G4NHVmC>MjaL&tF8yVuFjd?!^I#B
i>wutk dRYSZa!\FRY1C+b$PN9dl*:JE%>AK9XJl?$qEPXWpwS:wSqy4&EFc8BacLnp<^*&$BB:mTmNwFJE$W6B
uB:MWw yVqWXG*QBihTd1<>XJ$l4GMLBEDyKFVd1KwN!dH<\myVpyLRAMTddY&h%IY:e#N&FFH5NJ!^Y$D5I@1>
yGBnb& ZCq#+RTQ$?lNHJkP>ZJcXhETLJq\BNCZijIHyS9JIHHYFVHqEDF$ep8BtEPc%EBKJu?=e<!IcKlV@%pK
C@4&M? jnLp:1C\B5N*4bXLZVcC%n818LyPm8Fp9X\e^KVKq#t!k@\Wm@hIhFQnGSI+i@jRa6S>X%e68<Y\aS::
a<LN?? kG5iZ>uuQilJCi/1TXtHSItQ5q1^1dup6badWnhi*$XB#JXeGYnbAVWZ?>pi5bkPZ>^Kl!c*%ZVhS11S
V#=+Z? +yqL+8BwKaDA<NnnTM^5&miLku1iIKp^j4tl<%1&tLnyRN?IjwYcG:X=DAA*6P$t^indl>\II=Q$6RC*
n>SuPJ Bwjw6b6=lnK1Q6eN9c@/H5SAJ:j!!/dLlq<eqB<pG@Q1eNdQ#!PLmqQpnwCP1pbM\5V/GTwqbd5pPbaa
1FlypA IKADEK9dwD%TH5wWLCqJEhH&Lw@6pDC^DC^:%^c@^*b%k&&8uVPD!%CiLH?IwXba\F<C&@JIIH5*YhK5
qI*^tK qB6&YM4pS!Y85$jL5WqZQ:Ppy\jIpuSbZIF1ImpcSDDwc1Vb5VkmD\$C!H4$bZVGdkjW?LR4#*mQNaeB
%QXCZq p8!d%ZXl@!wFac1#tX^%tPX*yhqqeBHF$6:J$qDldDAjtm/^nX/&Z+P?qA5l<u^!/>Tp?9m=^YW=D44W
PIFicB DERpQSKGSYwWaM?tt1NiqZEI^5iQh>m\kbABay/qGNc@N:C^tP84d=lAn=C9nPpBLVjGZMh/IWGYt@Iw
V?HcLc ?64:Y*!9ZKjt5kW%JktjdZEulSaeNcie++\DADnd5JD?TBW8WwXA$AlWtb$+mQJP9k:6X>y*GXZZApnq
+J#Cu^ >NIi1Sq:iT@?%4j\*dYFy*\+?>XWa1HGjNG&#FPXbwA:%^cG?/Lcm4*Zpd1<9:VQSC@$$ibPG1D8>C/8
GB\KW& lC:#+mSY!ctA6Z**TP*&4I\8\GHuN$dPekl/wFeQpSZ9kZ:aT%I@SA9ML@GB+E*k8Z\5q\qGDd9Y1SDZ
emneY! EMC:9dbHBYepI+X+dqtYPWB5X/WD8%FaKB=eH!liS#b:SC\lm$^nCDBWP#n%4lnAyMtq#Y5Yk1XMGTZP
n8*VjB q#YYqijdA1#&y<?Q4IbSITu=%a@ba#*NYK49/Z+:Mi#>M?@d*R+Z%?KhDtFQA1Zt4#61wQCi:d9$Y/yl
wuZ+Gk HtW^%?llKnQD*+P:j8ltMbYc9w\CiS^#5A5TBy+bmh:LIaJ!pQH!dADGBt/JLiCq+A+e%G6G9btKNA#l
L6c=Fm \mEB1M8>NLKdAy&dp>5yHRT^@G!!a!/&4C#IXH954w^nIS4d\hCE#%/L?k1n\YkcqDXYMbBCWNq/qRtC
mDPl?y %u1IG>J!JZHi1u*VN+Dkl^R&EIA>a+#DHJnQ=ZW<m8u4/aGCla#MVma1#@IeXA*9tD88c<dJ@wXk*\lH
kMEMjD *9lG!RIALu6>YGWjTY/a&CjGYwQqyi:TMy/G1AmYm8ZycknuaBTG&$YFM4iNItpLWl<&/l<i:*LNeiWC
u<8#MV DwJh1CTJRMT6SB\JH<XtZXhCYP4LMl9<4@XP91S>&KuYCmTy>n$yECI9KQh*dT%huth?KWjmlXem>dj!
%6wC!F w&uLLyYmMk>wB>ui9%cPRA6#Jt/c>wJM*:w?6Ni&ZFZdKij^n&Mu^$y=kJJmj?%VMTLjFL%$KPb1lRKp
IcEl+c 95WCLjHMumM/YDn#I?eIA=AJaXjpEPLlQd1R85Ce&9Y<^Rk8Y^uE>wH!h<NEQNm!Y%8Htdu4G\/#HI+E
PK<wNI IX1&\w>uXlDl$PNJ=6Nc8cK5@EXa:eDVCkL=N%9qQXVKFjLa!@<@>9+:11u6d@6G%$wulBBCkNCV$EIQ
t^+Qw* QTAqwWb1/AESE=1ImDRSFVYhWESRSEVWBBABWWHSnZYHKtIDdKnwDwmKHi6G6?Z%H5>##nnuju:*8Z@9
FhT4yt <=+##9un@J%^nVW#=#Zut6@%HiQ/YJW##BBLj5Jy:RG8WZu/dINV8J1ec>PD/eTX!ll=CJKS1NT9ZQZi
chwXZH 6&PHCGey<WKa55$/KA$m>C@Ln?@Xy4ETaw!EZ$J@8LymKWZI@iZZIaF/VSIZw#y^TZ\AIWTBEDwC!MaK
eSwYe# JuIB?twSJ\>kiCIZ5wSWM+VT4%\YD6@uJYM:mKp?ZV%W@QSY&/?QaA88lIqdtGp%PM$R61kuZa1CLY/A
b>lRNk @H=6bC5kE<qm45EF\:6HP1KhPSZYyZaTR@@!SSNwca\EFTV<pA^N=\IwE%CGFZaa<9?bX6S/Z?REhjYE
y+emy1 Rme5JE1SaIEpaHmK^wJceX$/DQEl:8?>laB&^RtIBj/u*6nWW:5t4w?$dN9ZkSYyjCTdhpE+FnC8H6Dm
RQG8+h j=BBIqQFk95+em%l\NCE9=kLVt?FetDkEk<8L+aw6$6?@!QAD4:kDJ*PpLJ<BHT1aMHJeRI4:Rt*PXuV
KWeImb cL$EaRGRwk5me@Z1wYXwdcVctDajq!tiZm81yWnyDlC&bjq$MpL$/@CT69bmE&DEpeukn9qY6a\qkT1V
wFdQZ1 D&\ETcpC#pwlCkF&4JaTjTRLNAFZH/\6pMA!nQq8jq?4Lu>\QMK*E*KNdT8PRl5^!KW5iDbXRC&YwQLA
%^CM?a MY5BX=$lI\9WZ<9&9=H^8Yd:IpR1\<:l*M/9N<iI5W=nmeaBb6KF\JDd\%&Rw*A8A<aCBS\aj/EWQ8$l
-A9Vbu 0003d5c559400110333 Page 18 of binaries1.zip
4+T>qc wH1IF5^BpwiW:+XWETA9d454^\ZtcMyT69iLW#bEC\F^ENGj!1j4a8SaKi&/tLZTEceQLL4B8S6EQcGC
Y5+ye? Wwl8/CwJKkc?P%daP8>XmlS!LN8GBCA4W?*4dmuHEWF!mqBB^TlQ/JJ?ic$ha1KE#*BG=miHMkAp9?A1
^ND/SJ 8BNCJ%b*8Ilm><9PByYVY1FLEDHhSRywC#1<RBc9jEFHCwRncYbIEl8/qABS?pwZCeLTne=<J&HQXue8
bqcpMB !ij4R<^$?qH/IIS9Yy=9^q<V\Sw4kdMuD#ImlS\6yQlbheh>PliLwF8W$\GIp6hw+AtjePtu:>jweAR+
<qAAei u6L5njd=dBuLCXpce1a#ED?6WaHZqLEClNS^&Nw9FdlR\d!dYBalpG?G>8nXJV&8YYLAakW!q6j9?9#w
%jcu>< IqLGMPJ#dPC%=pDeEd=1FWliJX4IBGn=Iw=bPepGVnZ%btV8\yFEm/bu?\ta@1AdLj1wuuY\D5QLE\m\
=mD1GF pT4qdwRDZ5kFE<GTw\SFlSJnyi\M\bkuuPkMLpTZ1*!BSZ$hd4m69DIe\IK&h$+RATnqF>qkt\mu$ZHA
KkchLm Wcne#@>a^Ah$JAAhWtW&8b5E^FJp$!dG&8iSkD&>6PqPn\Sp+KG%b1aV*1IFn1TSB@%>CPRZ+V9KENYu
6WbKDa IAy:ebpGqGHM^+GTSRPMuPj+IVakbS8pI\BTT\G?p9hq%$EZ>W?^AMDk+nWkD<ycl4>tCRFMRVPeqL>P
!>/9mi Pk$:!eiC$/DAGTR=PeAblX4j>CN^?!WGWXYwXVCIn1B&E=#FkmlZITe+\9&QwYPd?T?5B5jLwjI\^NPX
8\8^EE =46T@YZlnw5i8/cDSnj@kkF\%DRC96IG^WKC!6YVqd?RD*%SLAI$=mlm&6JwAwBNt+IVLGn6PmGj\e@Z
BqVGS/ BiXEIY1q>Fa!epFhRM8F!HqT%dyhHV\aqhD!#ch4DKbFDbR5yeMa9N:T1+D#4+DwCGE?EZ/hmJY:qC@b
@S6nP5 A+QStGQmTy\%aPQyeQYInL<Jp4\iVl?T+n\EjGK=DPG\t!dm4IEhZqu*kX*SV$w1ICEY/JnG6IBG$mSd
MeuJ>B i%jZpwAiCR61XVe?aXt:%9Hn&@%P!<>MF<1tne4*%M1t4WDna!eYA<Wnw?J1D&Q?CwuFuM*CPnEZK?Jt
j=<nlj TF/&I^i6EB*=k6wEIH8hyDEJNkES!I^N8YJB4RQE^qEWt&8>6LqeyVt<1/?ie%$/%eeultnV/lALbydX
X:&pX% <Aw1F?C96ZSTa9>^F%FF#nPFMuqyiYP<</=XAw+6jMhD4W>ZbG!dFblViADYcWk>TM<RwHll*=cHJYnL
hQP9hL GHVM6PXq?6XX@?V=bnhCTAlJ*8@d5FEn<DFl9#6jB168NBdeMpCmGIlT4JnLSC:=CPutCBXNMyaH1uLl
LR&GBR >BaBDV8n&m?SP=CTn95Qq=nRX%XQM<J^L?G+V>ZV+SLYRRlRa6!+E/S:\8a9#:#Kk\Hy$5>VK/q&6+wP
ui6w\6 K:I*Iap=F@t>@%GB%nqF1c1e11D^Z=<IGK:TB%8S+RtZPy^E4P8Cal^t1QVWt6$wlkFE1R&\%!E/hknM
knm?Bq nQjYWM>M4^K\Xta5WIXEQ#h=npT?VmA#KGjB^XwLtEZ6*>6TKQWYLqnbK5Wk#RL?aajR%>J<$$%?iqeq
8iyTBy Ln<!i:?khw8:!1?CdT^i<lESNhXWy8Ywi!pj%+pYtRJSn1k$<Fad6X:tIAJ!*V8mk/<y8p+m@1^@QeD>
^K/Bt& Yy+V=ikb5LMwY#R:Xap#4^@L65#=BR=j=kPPeFw^&G>cu9^HG#<qNC6%kFRHA:aR#A!R^QB:ne*A!^>R
nRqbd# amyAIyVZ^9Abc+Wh%6L=J+l?YHKQGHcP%:lwIHyTy>b9qWC95#6uD\<#PnN6wMdP&TW*HXB%Tej&Xl@H
8?\#!% 98CEq>j@GhXSWT=#AI99umZ8EPjd#9j*AC9ZGn$t#6dK^BMY?\Q&YRLGELdHCd1S5BSbnl%+dVu+&u%I
bY#mwk A8I4edtNa:=Q?yQ:G\EEnkd&W/AMnI!6LTm%#jWhEyV51eVbCe@YhQYwR#l+Vn+B=EAknFIw%^kkdle8
&@V*u@ EpH4QkRXD=9iBJ8AmV4\WA$Xmq$1K9!HRHM#d4VKjV9@NtGR#L4?y?18mQnVjbyc\W+W$lD\MhMdC&JB
=/=9%k KjV%1>Z4IH>K95lp8^VTb@^R%1/L!/@C1clt<p/M@kiS:l?Q&VL+kkY5XuV//p5WA\:DPekYucZjQy/N
N$tpKq ZF!pKZJ/:RXi^+Rei*n&:jN!I*FnTuu1&Pt@wa6KX?qBa<4TNlE6FkC$acZFjFW\TAwwZ>m/m8WyNc<Z
WWPd8^ pXkCXbb+Ikhk<eST%uEPHY^/W$*QYd^5YwFV:/LB#p^u9=\GEG^hAhEBVm%:!4CC@EF!u&aA:Z<t5Z4L
e8Zc=4 <!%P=@TDND9aNBHSpRdqJQA9\WV$jAn#iPVC*iN*#<qpK+T<RI5qS<mCQX?%VDBlmmnhBJ>IE#bhRQI*
F=&Q6# HeiiQQ1*>S4P6944N$H<ZHZHiwDQiEkXR^NGm6$ukEd4q1Weec&qJ5+WwLtITt%EJG9y6Cij6R4IDlA\
AeYnpj TC6%c5XqA&4VGPb*El>yYu^<<a%@PY9^8wlYCKZjBPYGaycnSMY4aLMYHXhWV%8AdMI5q\j6CRMYRYkn
JuR9AQ Fy^$FT!A1AphKYt%6NRNR4PYL1yLJ##EJBkqu+V<^j1ViS#c@pNNH9!8*jkh%WL$#l!=5B$m$+h^Nw9c
J+1KN= 9pQw#pC?K$TbB?iuH8H#JI5iQjp<\M6H5PCZpZj!T%Rtbl14Yc4yXt6S9t%jlWyHRqw6bq+Fc#iZuytA
EMlVpa 5hRyT&HC*%eLRJPTu\&\ETLDkW::bBSZS<EJ?%%cmcj>+NdyTJd^=#>&u=ut&hA!F/an+YM4%$@5lHLY
@<KF<H <GZFpp+LB$:&N?hj<Q+pH?Fi/cKVkL>hk5Mk?nZ=hFMAKJZk69Py/$BYAqCKl&Z:mdpLjK/L+Beu6>dD
8<@d@P 1iqNbj@+Z%lihjb&ITeT^@Ln9&<S!*uqnAR?Ck?jhyQ<9wVWyptwCj\q#Ye91wA98#GpXhZeN/WuYwP/
jK5dNe :PVn9@a9HaTnE1WVc!6mA4=hZTh8VNd/61MQyX9NMBdL6EGPnZT8WW=!A4kSeLp?hFwV^nbG/ukAKBDM
5^K%tB l%tXBu>#uK:WZc1Se>B/M%beAMqkb%L*6j=/Cjcn^im%EKyFjaiV8JRA@9AVEnt\dAjSEpXIZAXq/EL>
5tIqp% t@mL^6ea+n^bKRwMlpPFVN*jF%&IDly^MKB&TS^5wTWInMnwa\%D:pYjkN/eZj!cBmbe&4u8YiiGRC4w
BHM^qi @*SC68JAQK=!YCj\:QC#De5PSm*9:T!#1\+>wC8w:RmuSu:^InLmc6<ud+u6ml5Pk:XFu6dP&DZw*@M!
c\FD>u h>4c4C=I=G<wPYNyJI?cW!:4^*t/1a<jDin@8wIFpB:F>!9Aw@GDQQ^k%XN+%4dtT=qKk:Dd@WZ?1:A6
Rc5:S? hk=b?XqwQ@LH=Q6nDjpkyywQW*iT%$L<h>uclQh9yP&Nu5Y&B$QMm:G9ibq#9m@@pGM^%B%56jnmaJ*n
D$8l\w h<!%A5$#k9ePSy=<Q&i*Ai$tP$1?Ra:k!p*N9n@iHuJp!8cA^byQPPDA5YZlk%?5R&!bc@w&?j!I?8iG
Rl?/5K &mp#J>?W@wkJ*&aD5KI9:SADLA*mD=D5wMdKAlMRSLD84m8u!QpA/5ta6:cnlB+A4cT<*\5EVY:/epB*
&1F#j\ +Aq?L?#=iHGm$<9q%=LS*PTqRL**t$#Ry^mVbbXw?<u9FlZCw6hL:lZ=LSANKbiF%Y1@@*MdGZHjA11a
\cucaX i>$8&iPC6=\#DGA%dQY+XywRhQmyRe%Y=Cn+e>5?1^j6JVX<MDlM/@Z*lwwPVjFj%J%4Jm1eFV^K/dhS
pScj:H SZcN?4pFX9QG9h%qdY&:8$tNKNNdAWAcDyJWt1t*YyCtd!npe&Ic4PduX^wQhaw%EXFdeRC/njW*6L\9
\ny:=J 6C+6iw^nh<Bp1nLX+\k96\VR!6n*$9HT<LVT:F^u/ddB*cTB4k1/dF>wM/wpnYA5Ye%1hlNh#9@mh$kJ
FKSWt@ a9EaWhINA&tGW=PHAl1Nl+eHe#M>JL^n!!$wLy\G&mSb=8&GCb^GR?ydtKZ4SZ\\pwXcQXEbW&/q>yYE
k6%P@J CNq*$><&$Q6\?wu/=MLE/TheM>b>QpjG%FcjyY&BjZ1/Gal>1hm&n5AJQePwHp#C8Jt$L=:L^5wZP:kA
WlZ8iq +*YdQl!aqVtTk/P#+^VtFe%R=dP$FaGe8$/ZDtn@:W?\d:S?uQEQteIw*Qbp+@I9Yl$8t@!:hq+t!+/q
HZdYVN bP<b6/nnA?\ETjy$#LcG6K>uM9aIJp\<>\+qaZ!^dY1qj5*tkq&c/lAl#8uAe@E\hX>S/VQlq=YH56MR
\C$5:h e$uhkPn\qiQ+k@Be>>YT<u^$4Fn58Y8nLkpkiDW\YHehRX=TTDiAVDJ?RE1n*+#<b?^eahH$e@^tLZk8
C<ZdC? 1^IQjVbZT>Wa9jPHjKFaN5c1&ud9@Z%\8VJZ?:11&Flth9I#8LBjn\TA/Ipi\kn^q!FWtceJF5aE>!S8
dY<Ie: N$hFh>/>Y!@a=IW/ykT\\6JHCXSdQLMu$M!jaCit%1=@qh<yA:6%Tiej1MNWkRCa:V//iEpZ1AWk#G>?
W6uIXm kcXW$<EJS<HABa^kPl%kNN<@\Qd!Ad4h$GcHZ?HpCRbNVFh&t*eiVNqkI1DHGRMpmKdC^E<wc#XXhMMS
\9L*>X <kWn/cIZJ1yWWq=kPX+=+dMVh+G^8<%p@$B+tyYk**/9<wd=EFGM!TTF1<6cWd4yH/*I@PKRjGB!:wZ&
t8P#*! ewY>5iG5&DGk$WWhMlbRW$6\>t<EpLMhIjL*&SREMRVk%4dXMEed?juP//K@:^&aK9S:!H?^b6&p5ik>
6wa/ma n44#j1m&@KK<>9T=KFD=m^=yJK8i!9h1RZHkyJS%9V&/lyDYS+kAdyy^dP+GB14TaL#YF:@+Xa@!aql4
GX\!hy ZwWV>pV1\:uFi1I&Ey?p:!lnX/G!TNMTl9eM4JS4amX$4GMKcASXnlZ#tLNk%mb8?LT&JhlNp#yX:lNt
yuiw6E %$9inS&ADdB%q8jdItPKK>V><@XAinDB:JP48myXA%F1w\=ql\JP^?$BG6X\KL5W=EZTJNuVcD:P94/P
6jSN9a CI6tu=L9QqtJ/*$ahI>lc=V^KaT+YPIta1A&\Kl\:Dj9:/\XAm5tC<JZuk?MnTmtMEnN%ItTiy84jkCy
l@@M@b Qq4n&XS9IP*9FK1Ska\mXD6/$1cFbNTMiHdShZtyMY^!CXH>u8PwVaZlEJ5KJFybJQtDm/nllT\Ltyh:
%<!<&X cMi+w/miYtYd+m<BD1#?*L9$J/$jWy@94Q>JKWMY=19#8RkEYJ!5PSAJphSiMAZwEbyA5%6\^*16qyed
%Jly*a @6TD8P?a&KVnHNth=J@mZVG^cTW$6:M!*WSLyDVGPGX5aj+#+n4I+SKAaWqX/\b*qKSdnXhRuKk5$S?m
WXXaAY 9>h1LeX4Apc&ECIIE@c+Pa??yk$6H1M#nW\1hQA?GT?GVYE1!>M9hjeAkLGBAyaHe@I*k#Si%\W8PEn#
iZ:8=K i=#V\E5A#<=9EpLS!Ll#YDLZ%1Jh#5+N\pl6$wjdpNHtck?uAVTjyjua&ka@kI56i<da&:PFH#DTThet
N4h>/! N/eC9jZw+Q+LJ9Jl8FC$YnhDWcGhI=<X*T>:<Q/>w*dkC%^ndhidK&<B*\FC4JD>^X>Ji1hjHJ$uA?</
1L9\X: XJR%$$6ebc:iAPX!l^BF!h&&<@%BANJwl&ZGqWJ1!*ADa#9%=LCMe$XuH9FJaRdQF9CNEmQm<%aYZjkL
p4Kd&E =/aKhSdLep\ka%b<W4F*APPH/XA@TXmLBm<9hmL<acFIS5q/EVGC&L>RLwwL*:F85BqQ#t+i?:CLPq1*
QX!YlW DD<\ZaKc9i9/majTE\=G%Qd?>H=6!GmdW&EYNqVtT1W4wKI+84bA1V@bu99ZJ6c\pN5IN6PK44ibii&c
-AI4I@ 0008e07ecdb00110333 Page 19 of binaries1.zip
qpV<+6 qWaG\lN#$@K:+Nb*weG$M4&dG@EC+M@lINRVjDPS6Ac%qCCY1>1=AELc8\6peqtEuu+@IS6nHVA>1M55
IcyhC4 B18WCIC=MnF9eMGm=kukw5\qkRXJ*!8Ce@BDaa@MXcXb=jclt5kPNZP9dCLjmW@<P?<LAC#TlS@RB5In
IbQm8G YY?8$qdMRYym%nNC<jL1aA*&1=KwupwN=4w?Q8tJE=*by?Mlq1Ae=F?pyAk4^G/9?N%+>Gm6T<tGR*u&
XCl4QR ytnl/5HtJA9&^npcaM5pGn6tWL*W8I4l\NSEm>uuI?jJ@bVq!5$C/JI=tB>nD^*jn+dG/YM8ac:&<?8$
mcA55l TD+QIKuX?\jw=W?DkRq+Sa%^Jj&ambq!t?b5IZp+G%Bjj?mQ4*ZlXq?W%@T&q<<Sc6$nEaY8%mS=SHX@
$T85CN c+Mt*+p+GD!CW^S1#EhJQqBT6F1F@Yy99:S8FpYb8@MnNStDFG+N6k4^/&Wp%i/^FdnNTWZHD=cwp<^N
uHWpX/ iC!+QP+pF+DQLpHH:^w^n9?\wiJ66**D^yu/F&wCAIJSyyZ9@\P#kGC$/WLPkM4yN!w9eM*LKqYqFZud
aTY*?/ YqA5w8Y%<JN%NH1<NV@CLaYc=F\%u8YJCc\9PGjepkKXW+$mKdQ9Fm!W*q?jmDGWRnZHY^lan4ak%Vd:
@VB$h/ ?$jLN!C\NEd86qBS4aB8FMQEpCE<M=eKMK6l%#<BRDNC6SbNM!h#ah4=!VVR%+y<F\BKaENqi18QciTS
>?ZY>e pD^#R#PAY$FF<qcn@EqITCE11Q1K=ueLXdB&dVNWEITl@kRa#81Cq@4e<P9BQ#qKuIE\BTp@ciLpAnG@
hZL?m: ntpFhI=D4MA4Gt!eP>qV4cXQI&1AtJ?uQ=m@j8m%8y#8>Y=Rj#aHwMplm@bc>8eApGJRb&VL#LD^#<e?
k>*Z?H uRLqF:D<aWNt8!Sc9JG=DbbidNJJBZK>&I1b8Lq<Zek8eKAaNV8DW?FN6Bw6b45%w%QRhmFE@^Tm9EGh
8I@\ua hBK94Eiw&kkCI:ZbM\SF@X%@IhKl&wnpu%muk=l@nK/F:Xcw^ySFGw\M1DITP4AbJ4>64Q#=VwTHKm:4
<H5SGF 6J!SVDd<G8BkkAaa4y=KhqYHy5HBb4&JJ#bBS5meXeaRT%%KMVGNRCC>SZF>>Rb/>B$a*@F^ieyI9J#p
pACmA/ \elbb@+aRc4=RpFDK?#$KZk+cEIA<Q11Yl*TV#!JnZe<4$9SljPETDTJ%HdFKP<cYk!#WRAc=D^%%YPm
9%dF4* t8YdqlTVmV<wc:cS8TZclZMpZyiJ5HmeBFF!S^EM9l/#CcpeBekaR@=QNQhMQbh8=Ql6G?tG=pD+F5cH
n:Gw1E 6XyHhEq<9htV/N&X<LZK:?T:ZSShW+G/abE:tT6!BX1I#LhYnN6pylRq9/9B+GmyeP4!q/?nG\FTPPd!
k1pVXS !i%+e\6Xtu:hh!l@jp#bwJ8GS@M9Ge%8%yLjJ5^t9Pat+J*4!a^#eW+yWME6>Q5+m+FGnTFZNb/hmaAB
p/V*9C KwpiA#GI8d?>NHG?>6@cAXNjG$6A<FPQ@B$!ANHkRVDMTICWSXA>NkHTmIyhini^&cRJ6aIQ>B\>P4:h
8CL5Bt tl!PX\cFKQ*^mkWh<CRIjnMtlTMqiFAa:E+tcMWmLbm9LC=ni8XbXp!:+b^WLRWq=^N\RJC5X8DqETPN
bkVSSQ JpZ:HF9uJdC$a6^cVmER<Xih5qS/!kbeQRyc>:j@P#aED&Z!XXD$$l=q+E!M9568L*Tuq!:D*+4=h8>A
=ec%GC F@B&5>+A!pDFWl<wA/!VQ@GcVABh*K6RJKpB<1Vaw:+IVVJTN$Pyp?aRA=?MuejXqRa@1\?1E^SGkwcu
8BNRX$ IXk\RtqFH6%X@CF9AKYYS@Sk%CmkK9ZJG#\KVG%8I#/?LFn8ycEACK/9DcV1dKERITe#laZ1yHY/wK>8
ii&yhl *\b9wSDJ\%ch8G9F5CE#hE$H5k\EMuYA1$6Cc*Gl\hFnn9^TJAJCb+#EXbjh?EVWIBNk8\>cp@6\QX6V
a/Kl8E I4WAi^MKX&#FZS$&pRju95ah:chHe#q<Iuk>X>?=^m4MM&t+ueDEc&IVKFc4pljcEI4Y8M>u%EujNIbN
*bVD8R I%&LPj^uc+C^^4uCFBWA<4uI/CJ5hJ\?9\Hil6ZR?hpIS5L9uDEDQ&l8+JIbq*RTLK@*ZPENtqqCNm:V
h1D9@> YaNRehX+m^9P6FtwwkKC<d1MV%de?yw99=j5kS1#N^Pk/@QQ=?//#8N/Ad\$p/I=F!i64JM!m^5^QHLF
Ec>^yb tybm+:j:<?MZLWEH6hQ6*+Ah1V&>/?FGtNq!hEP#@wC4P6eLj#J#:SW1iLw8XEk^4Et^a9l@LWt\WCZD
D6IQW^ GL/M&aMtjR@etZ5eTJ=+uZ&<nVdYyCWItd8F1YtR!BEDMF$i$bTMhmH6M>$INiC?e5DKDiVJX9\lnJMa
$HDPTA DV/GQF<$h9!+JlIHB&hMTy4XiDb/!5dVH9+jTRu/d?W/<khYAw&CPteCw$t4@AN1<j6HY&KX@J@Xcjq1
^qM&$n k5!NcWKA\Tb\R\$bh?GN8uDBbtNkh#18YX<Y9&pCB\BLi8Rd^9#>&&j6EB@ekb9QT&8\%wt5CKB19jLc
:!&5\% 4bJeZ!IcDW:BTZ<JJGqG@PSqe*@RE9X!Bt5Bby@&P?MX*QZPT+k*X#@>tZ$JTmuXw5$Yp&C9?S>\=AAy
&5IC+= ::k^L%Z^yJm$\IA1ZlFdKQy&T%cMeZu%T*ZiuA=@WF8^LuP8*aRH1S1pwD#8dByKA?YdWdN>Pw1D?q\&
nmuV:E HHN@*jBn8K=ZBKChATuYab*<yR4HC:Ll#HAm@c/XkpWMKK+mJnF^=nlt9=bYq\9=udDS^pKbkTjYpFYa
N+$DwB L<ITw#>KwRwDR!dSTEDZ9@jVTlDi<$:?J:=N^$I>@Atk5bF6qjpnlBpM=<i9d!uWILtcpwK%B&kGQPa?
NYC^qw bVa+?%M*tEABnMXJn66KH1YpycwQGpH=c$QV#NWBe!5B5A*#AKww%menuRd#%buXlwyWR#LNi%M#ptTm
G9a*YF y$R%#V<6=<^Hp:#$tV?%+kp&*LdW$lKPcqq>?5Di4DmkZ&qF8td5HAiXQ#MieC!m=B5\6?pBJ\=!1@aN
&\:58F MA@Pq8@K\A=G!dC@##F8/jG$M/lND$JwyK8pG6!A?Sj?TjlAN$TidhwWGmhmGGkG:a>Z*%acQAhXuTLL
i4:$F8 McyPSR6J+>p#K<GZC>A!#G!!pYy8De<PC=C$RFi>e&Z6aIiP<<QCymwhS1p?>:aG6<iW*+Im9hVc=Cjd
8?LjIl N+H5*qR/ZK?b%&:FY<\t5R&bq@CHI#HAuA/Rc5k:Qumj>Th*m*uYZRuDT&>%ql/=&p1BZ^HWCDB8G\P9
lZPN*S 1^q6^4\#lwIuZ18#Du4?&L>^W<jETG=Hm^c9pcV+tn>ZkmGiDCWq/MnnN+BCHSWG^V9c6#44#Cd:$@w>
Kk%FWD H%iWF^/@RYdANCAw#W%$K?+M5LpYVl/dpVjmFa8t#KI@Ht+4ai#e@bbmewJLAVi4C>8lDlkW!jTC+9hB
q4ZRyH iRp=ujjZEPQBm9BjD<w*X4?EA<WH?d%uKCWtaVb/#EwX/cVi:EVu&1Y4*J&!nZ@&*#>%&ywQW?thH8mX
ZXCMd/ C#jFRuTlCm^P?acy!DPc*h*4FE!Q9ByJ<wLi>hL*64HmYnY<6$TVknFAp\/V1$=+*R?6MN#E9QVh>FLZ
l>F4ja TXARTF\*dmY@Y5DP$GZiXmjN/IEclh1+9\dQcPmh8N!<5Z?9Q?#41A%*X\?*FK1mcyGhhRA:nVS4u&8P
G8l8Yj a:*PwMK6Bjlhtic4ed@DYklwkapJ@/RP$$%IcqtAtKBtNb6hJ!nk4jJqd\IM6E#GV$Lq!/GWay&NKw$d
hT^l!A S9<wj?IbiWcMy=eA8nb*GNHYwIFL89JEmi^%/4/w$jj6?pC9yiqZEk=a%FE&GDD=bNK\CjlYW^q5R8JV
H=WXH+ 8Li%?q\NBEFXF*AWWDGRn>QmyXwB*#WW4unAG<?+q54LMy^>dDJL%PDj4@W*^YwiRN+%kQJ9q:n6Y5/6
>^#iXy Ae81L1ean=>:L1+d\\Tt1ZGdDPWahWWDZHtT4\1F!QQkA+PSDEQCTklXNc#B1EdtJ%DAwAjQcuZZ8QY9
ZqSI&P nJnhZ#X:=kIKDLeC#HZAu&yK8SFRn%KXIBRPcp\YCLSRXX:1J%QR6DKAEY4A9\CXd/aAH!bHl4?1nIDN
9@PTB? S@RFGed!M6lwD%JA\CndhSppNRdJ5K+NPw1DC8T:!mw%?DZ/qd1ckk+>:5*Pa!iSRYmN^AjaQI&Jk<c*
F*mTR= t#jQA4:Gm6JjbI4BAB+npGuL9^5#V>9JIamadw*qJtR$\p$bmub!kQQp^tT#qPEybGw6&uhS$*Z&$MZJ
K8Htt1 t4InSwL9^9L6#1wPHb/hwjK8DnjQiD&jD*%N!ES@BCK@G=J9kSTwZKnBtMc\LquKQ<BcTAb<I>V*wp8:
w*J%ZQ 9dC#iGPiq^Hany4?DwA\jWHut:qW&B$E81IM\&9E@hNAm6^*kHweRey<8VZ1$PQ#+$pP5Np^9DJZS>pG
8!?d18 JVcGpnIMpC8#5@9?TqZX1TIJ#F5%k#DWG/#/JmYK=IW>@i:dh5X:\@lZ*$5AJpF#aNlEINRqB=MAFAEL
\\u/bP A\Ec/k*\G15B^ZcF<FG$#dC4dk+:LalV5pmIK!El:bVu6a$\+SZF4ky98pqaGEG\eDdP%TBhGJCyLeN%
i<59%V i%t^CJHTWu%bAukk+tt$VaSJ4E6:/HQZe*8<npRDcuhly#:CmeLPttj5<c$&mGWkwCFXhLpn1JYe6*4w
Fw#IKI :1cuej6tZ8l6#l?#CVN5%u\cb5Hy\F!+I%?Dk\T=S:QWXAHD8R/9bPeCD1KAS9Q$QXejH\b9bjt@PDn$
?44HVa @MP64Y+i5h%Vn!*elJ\%J6TBq&:j%J#aF<@hiuqGS&Q$=<nA\@j$&AL/ladMdcINM#X?\Rl9Z@@QF\/&
#kFnc+ hWeiY??X$bjuj8I$@EQ^>$8!9aj8l*%S8^5pPyJ?y?D>n:iQDy*a?jDTG#/kXinYyHu4Y:Q!b9IPPDPj
ewW9nn P<yq%w4N%Q##&&#X@SiHZVRC<qWRwk#*PpA45MA<VN5@kKiuQbI@@1>RVQ<nA?G@\hC/84n<J\#6@+kB
\<Qmm6 ?5<aYteQ6@>*SKD91JJCYaVcLAjDHYLI=HBJZKH#IGbC1BYDe#VD1NIkdheIHu4aaLM/aLCTJGh*mJ#/
WM%AEq ^$W&Sqii$mmKM%4B*TnTlCB:MJBtFIZJF$:LlhaNcI&:kpbqG6Z<\Wk4YTqjKP^dGjE5LGmC9eHy4?CN
:bnEaC /SFjQliiiZlD?p>tQ#8kD=P@5Y4=e^mXnk=PZJ8q1d@jbXcmH>bb:qJ$45u=uqQ66X\1eWGc685Fi\?K
YYIDcR eq*AZ9+wX+i<E+WaE5n:<?t:=k@nFdtZ$6CHnNKnd&lmt=%*we^u#1:e9D@=?b=l^M9?@q#c#49\IjK^
mDAXwB HC#cKFH1jJ^+iT@EaIhQRBltMEPM6t+6dpdaPHee54a^1Gqq&yl>MwRQNQuPhwAhGX$&!ykLH!@c&N:>
8KjuGd <5j+^+p9qXXE\5qKETQtnAS1<&%YA6F&JeKltARDCdR^%wnYt\+%Ckq4cmR+%et9Zj1#8m^4<py8Z@/%
ylqC=/ EXG4t=HGG\#uAmK/LXj@!95+#qZ*a?hLiw/TK\hX@4!8TKQBF@QP^>5mB+hQLthtF%E$l9yThKXPk@eM
?lk#L% 5NX&T#e%lqD*>W/@^u!%hP/8e4KP1m44tkw?65!e+BdSt46jhmWP8+M?$KbdG$eq=9*nyYmKQBiA9lmC
bc^Aik c+9ElHtypWNjupXE$hqKKjtC:I\>M@#6MpiuuH9L^6u>$W\E?jD&VM::a>m#$1QHN1&K1V/>qiy\:h9n
bD@Z5N mai/6lE/pX<t&L1Pm8+?\tm>6:4SNCd6tWHm*a66lEh@F/@Sw/&hH+yM/u!\8eyCwX#9dCW$G!jc*&1P
nkya5! M148m^@KCjwnuc=:d!BueyWGL!#X?Sylt6Aei&Y8dP+iidC+Fh$a=<ab4uPXZWCLE5Dw&DeQ:!w8u5%c
-A&%Vk 000d92ac6c700110333 Page 20 of binaries1.zip
X9PIIE 1eW:jhDE<#T9<4H:!G^\ZXB%u/R*K&t/NuyHPlm<dPi<m?=!khY>bwwlw59</+F!J<96uMQJ?K6/mXhZ
=d\Kd* PnlhXh>m*?wCSt^q@KYd@>ej6I%B#?:%Xt*:YnuGid4+^^6BRMKZ^G9&?$6Ve+t9iGtGQi^L!XYqI!8T
B&6c&X *k?*@VGT$L4KdDCy8jdei&<V%jY<FN>Z=><@9JP9j?!JJ9KcV>X&y%WFhl4%uuq46:meH!>baYdk<9H#
4TVG4D +wBpKmDX^q=4PD:5=4y%bSSuJ?XR^n>^6+h6+LH!14J%*XWij>t@Qu^A>ju%p@6QC9==<I&aPHnw4MF^
wdmVQ@ %6?PH+IXEe$#1?+Z?RB!B$k=@a9iqme=mwljDEbMS8T!^cR4eQWn^dt4>k^>T86c<9dS?:bK6HaI4u=&
E/PX9V 6W@mJ<My4#Ilhj45IdiTX>yDX?F1L/:TQh/?n9>HKGZhZ&*9i4LGqNt/6ddm=6p:1qe4Y4!ewuTG?*w!
^4:Y5\ %1+1tm1dKD6*&PIu=BBWHRHZP8&h8SY8M$dF9uut!NA#1h1:61Fk#Yjh96PQnRliq%KDL%#%V!#RHYCp
h1*:lq :ek4:VQ+FHj=/w5APGmApMa5uS?!45?4Vjqn/Qpu4d6&ShL<eXj1/EL!>dK<XduJ+W=F1S@V#5FYa@aq
MVR5k= p6Ju@HFu1h81n+qHYndw?V6je%YjNjJ$j4d&mqnk$D/!#M%6<eDA:5i^%Z5Em5PyY&=aj?e?NY++\4kF
Yw6DSb N:c#m*\=c>jhM&$I:YJ8n!!:Qub+1&9%p&<F+#><>e>&jKA$lXS?tKp=E\PdXl*N56$B>4Ypndjy^mwm
=XC=%n *<Z*DH/ljlhp8!SNVQy/h&:^Xh<5hI!Be/>Pe@ayDF/+4Hu4VyT&LK1uSY&^#B?a/B#4W*?F#P5nVJ/\
X*MXJi 1Ce86DAW6i\@^lGBAk9ZEiyw#^MwyhW&cR9taPiWQ*%1+5A>eL8#Li>q?^A*=jGcI5VLJjIJm<$><S<&
*HT\45 d*eaKKPn!?Q$LwJPA@YuV!VVck?6Lh*d:9SlyQldkYBjaLn<dl<leAKF1:P*:n1>X#G5Y@/Wnw=E6l#w
:B8T+t YbRTA/lFGQKaR?BZaXGKaJ4G$&AcjI\!dY/4cA#jEZq/lFGkw&>$C9$=V89Dk#Btl@6^TWc4+e59HGJB
ba^^CN y6&L>\c&@J\c4aINI9uy%XEm!^::16A@hFc8Pj/*:w55$YKIq8i/5%i*YD+>L!5T#PqGeALYY:TKE&%C
w%AbhX CWj45+pL$GJP\&Vq$TJKYpQ/&HcHP%<u6VpHHw1CcDqJ=\@HWnK88!WY&$?PmJK*GyLp:96jpA&Ru85M
ujyEiT nS/W8e*i/HXaZJljhNydeIX>6cH@SQnN99hH+QXPn*Xj=8V>I?=<F9*Mi?:cPi/BZ!Ha*HQD:a+EY1yX
TliWS* ahk5k=eDdKEkhC>YywZGF%FLKD<yP!%DRFW<KCTAi@?k5R*$Z^6KW#8Q6&*\I$\G9ey:G?+J%$8$+K&>
\mLwpC ZD@#%NKbh@1N/tl4R<ica@cL:Zy$Hj$c$>eRn5$1GnL5iYHXeTM++i!:T\cjJ5CLuZBN@:i4ZLQq8!<<
pdHTjh 5HE$TJ$cKVNe+:Sj8i8XuXZbi8tP$kJPQ?Wy%<bRGQ:kX51J//5<K+>=H9Tb!t6E8NQ:*X1K<#l65yeX
e%=Y!$ b=e9bn$eh6lPublw5#cML^cWaP6nW4I#Knc5cM?:VY9/aDZ<>u^*mjhwR?@QPT@*1wck=SWL6*#6Fm:H
yLJcTw hQ!IikC$QNMu9C9/+8N*n@4Th1TyEGNS>tX:d<<F4@JuK//JH8%w<M*jh%dJT%j@tm8ZY$y4^\#@GDl^
wauiY@ 6#*ZNYJMnciwj=DJcEGE*X=J15aYFFY<96eJ8<b>QAKtZRm\G*H?1yd=9aG4qF5H?WKTSe8&la>iet11
>TcT1a 9VXe54K=IBJ&@c<QHup:HPc!=W>ZWXy:t^IMG/=Mnq6@tLw#hP6<I#Z##:Y*j&+h5\9Gb1^wQFt?F:Lm
CbPeFm ci>$=Q5hn=*/>6&L+J$+i?Vy$RAwikjWdJ9d^Wyu9$bImZyy/M:V/B!yet4?YVjl$lZ4%YdbN??%^M<Z
<J5J+d QJ%h^iEe&9I/6E9!%9ZcJDB^<B:/$wMp/?Vl:+Mc:l6pL#>KJ5^q@KjuQ&t@N@LDu*6:b%h@4?n=KHbd
cbe8JI KZY#@9i@^Eq=Y!eC=<6h4ttJ9qV?Ku!?NyKV>yy/j:uy%I9pR::P%mZZ@\/h>J9i$lF?k^nn&b+#F?:/
kh>b6G *tnunct*L+wdV#S<*4dYPG?j=+nD@uill<>9@Peb/6:V58Kyc!b66WdLN*$KH/%/i$:=NZ>^e8dl<Z84
/dQB6< /VjCQySK#JhD*c>hG!6iVi?*Lj!K>4yNY4klTitEVmApkj8/Cu%#Q>XKF/=h!/6E+pYhZd?1DmcP5WTb
\NaZdB N^^Q&JXnPy+KJ%+m8>PPlG/*8mGFjNqi9S8w#6+5kmYPnTc^9VeCGa5hB^Hb^HaqY^Dc8A4!E5&89=uu
X/Vp&n 9/nM@4NTQGG^KA!@T<6D9A<k6ckDlXhljE%MI?Z^ajHd:&H%mXi*$dm9lZP9aK?L^SPc/MXpPDVLeYSm
&qn/Iw aC=l$LL$CIK@yHH:^dHp*!?$HQp%#Fn>^wyFSEhDVq9eGW*9/++H:%9wF6PCq*PH%=\+X+mXFXp/QP<?
=PGAhQ 4**b>@uS<e$uuLCDm#HQ<\<h^1a@c&=&WG/%tHJ:Y#>RiRkZQwkacic*8mdheK+E?kXQu!XNPtPiwH>$
Y=qRMN WBELT!?GT::K:PE9#jDqDI!VC!H*&eteLP5JY<m#G@aVDw<a:Y&VpbQb<y+<@:9&nL\c^KFn^>&iG>&F
nZVKph 8u/P:4Ew/QQdKVA<NlWy9PE+uKt&P9RJ=ZHb/8#c%bY:+A=1TQ1H%6T*nG\*XaPcPMFi%cR&uPDCQdlB
Em5^MP 1hCV5>FYKjMh$+Kh8#dD*1JdZS*p*e8=^>PXdHZWtDy%VD*/PWVWc!n4M%5+y*mXHH$=Q^hJmuu:G5Pj
QSkCRA T5VCqtPXZXST@p:K>?P8u^*Tp4k#15#IDpb!c:T*p44RSuu591:^VXC^Y&+%8:D6FaPNiWh!&dtbq**\
5S5XP> Jk9u6pC\Z/RuZmGF+HFdu?c$aPeLXA**kEc%I$61!pNt%JXt\8@#S%/PXQ>6ZuHW@QquC<y#m<J+m?Ep
6uc1A/ T?k1$+^5XABbp&%6M9Hh>qqcbE%VbcmXnt$hK6&DBLCSS^M?*I!pFV=\pG<Pb5ZD#eY$Nclk@tduJ/VE
/JVS1J G:jjbZQYuT!bnQB98#HYPXZwpt<PBlTTwY$iV#4Muud=Dp>:W6w<^TeDMkQ>qAT$K5+:#e+1Di$#n:ah
wSkIeK HL\$TLhJ:@MM6NjM\9yV@JbB!lkpHe?mRd1T/T%/=@&?#<:<1$?G8VeE=^%\^biCY=cqyJ6j>SQ/?caN
kbq#EN ?kY<kTm=Fw#SANJ@MG:nGDKNiVCAkth\1^qH:V!il64c81/GQ1MQDmLTc!^kD&#cFq#MW99ue<cu+tI$
uL%!4u PbyaP^@Sy<VeVI8\b^8A?Z9F8YXDH+L4W!/MQMda^Y!uh9%BEFa?tVbu4Qj4Ye4661!?#L=waXjbHhN=
KaK$t= >eKB#M*t5c/4l^iPq666!L&6TbXN\Lh%6\h=pkn@P9HX=j@dYN9@!P@:*<jc89@jE@H?e*!5m<9@bVl4
a9W#BA dub?5a>j#I4W!EVZGIbnJm@eJhM^q:Wm\Na5!m+@LDRyQMEyJn@FNVl&jY1?ye?1%i9wYi=i6tT&B64K
k:?:CX n9y:@ZKCuJu8<XG8aZ=FiZcWaJ/nR*!Ij+wHp?pSa?j6+Ppj!%/bSF$jZ=mRdlYc!&W+bj8S+%jFYF6!
iGtH@d KB5$$Jd5De9Ma5^=>JW<=\!Ya//#E#Q8Q@C4<ep<X$1IZ#dHJVPYp?9N>Ml#nYjcyDH#%miqF#My/#L<
T\mQEM C$ML\5^ZpVZR!#uJ9JYyBh!5wGZt/#nL@kNmTqqidJjAVZMLhKaZ?F4qLM8!5LiNm1aY&+c9mX&VFyY>
hqj=Vm nL1m\JN5=%45qP=k+cCBD4LnPWXtWFi+P@\Hu*Pbc*KSbaJbhNRcc:J*pA9NjK$#JV^:iaCq#iwp4>DC
#54=uP qeWlHlS14m8bttiV6TwuudZC%X<DVR%#>ZCPK+l%+FLm:TKm4KmWDd?un:h&:Y1jZL9XiZpS/&QN*I9D
yWk=Cj @BqiVL@W6XFM5qNWiqycM5&SHEmniG!\n>hAy+YFY9qbP8VG4$&N#TVd4*W8#5^!NdjJVdFk=y6SdL$V
hpE8pk M1L5QA8h:TNnppQ6iY5Tp6N#wm&<#G#5\pL5Zj\>dd$%$F!*aE8&k/WN!&u6tt!*yPW?#wEP=qbWC%6!
V==4Pc +ywR^?TkNdqy/#^hXlRFSMTp=JqHyY+wCF1*JwDHmPhtlFM<X\ZuccC>#BQMHeQ!p6#>e*JDm<\>X9k#
$&R!9? dDP6enN><m$<X/!\n@E5ZJXmZ4l/6T*bceXcM*PjDVS@%:X4e1*TNulFl1=p=<hwwJ&6a>#bLm6VI!J>
/RL4td p*%YYARHBTcc^ijq?1=K#+#^eZdMnp&QV+\w!QF!eVI4*8CiZ<T!ZLQi^Y1X1&>5iunEGyeI1ka/bRW9
nbucPt Q5GbSR/PDM#!nGa8J/@^w/$ITm=t@Aj+hRZhqeNn&nDn@G*emqbp?Tdb&\jV5qdp<i^mjXm&wauP:C^j
$l+EWu DZTWV$KBi*al&h9JitZ$51IWd&<#:&TdkPlpquu+&t!H&KAki&>8w5ictBWJuKmMpCLQ=c9wLpXS:KDw
kIBnlH QC948LBM4><4pyZubi9q/B!&#C4cIe6&XT#H!YKqV:^u4l9Lm<9>D?B6nJ<QqSK!klJM=uIe%*lt8HGY
keWkjk piq^WRYbwXS4^kwjDZSa4E8a5$>TSCVZ%!@N&<a#\n<pJClpbVVNu:&M8wHLZl9wS&h#:Vm$#LWBSj=4
#*M:5S 8XtF:JkWtq5+P#!yeCZF^i1*P+PLW1JYPWa+^4m8wj6FSV8uY9qp@jcq?Tw*euDP!wlk@>>8hjM!Y^Fd
<J\\*W 9C!GFWhQYbZ%L?G5@\MY@Z<?c>4N:Z@Jtub#@Zjl4Q<#VQR@SbT/@K<y4T/8@^+p%hZF@h@R89@4NF\Z
qCYeaB n*>DT@9Z<e+8>Q>i/$d@L:Ti@+d&Z$NTZX%y@:*Y>d>I$uX%?8?%L9<F&>HX?h@R@lj^#1+8@:*Y?d?I
?ILMId 5*b%@i?%Vt:@^X#>G::/L!PcZj<Na@$H+jNjcn*?ueu/%*uq49?G5b^h@k969&E5=@<mw6tN>4@@ZLh@
h^b^dt \%nP#9>/46#?DYP=ij=4W:1=@Kh5a=j@Q69a?j<BG848@4>tG:8=@k6w/H?E!@@@wcH@H+YGM6IM*MmN
Fpy=I! ZKIEwl=5BIeYTVRqpQB\ZYp$ciEy9Jj$&Qt*!X+/DTpaC//n^%+uckbCY<5iDYNy!jZuuYV5b!M%yVE9
^>HXi6 /BFXbdi<*te5J\cK%BY&eGlA$@5L<yluDehjyhH4GA4aDRMT:>!qb8qAF%$@aLHI+J4bwyJ\5@La:X4Z
Nk*W:q HXMhtS+lpe9TZDZ5y:wiSq&9#u?+:D&W4Z6tcG*N\=l%Qb#dub?w/dlqd&Ind$6:aYeicwnWc+n8V+1P
qF^c*w tJ%^HYN:\<tu%Vq\\p^TbJYkNpQ@Dw@SVyCTP>mW$<:W\\GeL&EM\9Thq%6nEH8M4jG*BEGt=qIu<*%Y
5$&dXI !Y<Q?BKmtWjZ^dM?b++@VE/AV^HRp$T&8b5d6>4teX$t^@c$QT&FMN^R:/q4X%JYe>jnF1Sy4?%4h8FS
C4ITG8 6ND<LhH^%m%j&k=BSQRPn&QG8e68N:l5YPF^h!E/dPWV8@IXkZhPY^=KduX\CW/@i+c*au/QSSI^bX%R
YhZ*iS W4\VM*CNMPn?$cC>d8VDS+%Y9u?T8^Dj=BN!wQ?DSkWie:y6J#Zn#qVZ>E=QD694%y:VI>%b9GCZqT@9
&TKkCY 8%H881GQS#++9h@:jQL=hSb=ZZj&dF*ZtjtN#Zb:jK==d>8hyk%ZD5D%m6K*#:KFKRh6DGI>K9^^HV#%
-A4N=q 000bfa3477f00110333 Page 21 of binaries1.zip
jCHuB1 W/it&Xa9Fa^l\l*Scht6pH*ZV=\M%Ln45WLV/+6/+yT8cQ&FqF=p:Im198G$iRmiMi+<8mNnp>q\uX8%
j4@<A/ !^MjmYh/lkq8cDC^^EM+@Z!u?1EC4?N!>16@5Hete<+@/t5<FGl5uQV^l68j=+luHllZ*6h$4<$<?ujq
J4tP?K mSZ9TtytF5:w*jKHY@dRt6619?@Vj4^&dNPpX@Bw<W^FDG9?$/XiJC%#jHb@WZ9byLeq9TnSMBXSih?E
LXYBqE jPbLL5na1QHeY6+j9Qt!kiE*Pkc5caF^w?4Iw^pD+69WWj/iYj!b<pXkQpAu>M&5<\t4$XH!tXP!hac:
AVMH6c Am4!Ht*5da#RcVmc+Tc+>8IQ$qQeWJ9QhqwL>4Aqw$4h/$HwYu&h=9L\Z$@\q56Sd>L5&Z<b6cV4F=Lb
tcdNu$ Pnk^NW664i+K>1Qu=l9CC?//lkamq1aQ5:N/>#*bqHFq*heDH#qjB<=&T<K<@Ppi@pa#kut@\*eA*bHK
QS/HhX =iC?dj:P#Wcl>diFVMk#Y>X%lCVRJLbTCHePPituZ^TQ1B$L\=^wNtkJb58kcF6b!M4?<JKWm9%h6=jq
hQwldd uM^pWCe1wIbyVayy=?9\9Q=bt?:>+ZjmdWd9aa%eH/@biRN1H>6$FQ<\C&+d@?SeP/j$MD+NhcZ&iu5c
YEZB*y c#?8et%E=+Yhw9nR1Nn8M:#5\HFtBSS^\*ay+!nQ*I8djI$#Z^4CdqkY*W+4n<<w+FS//XJRVQL%9tL^
Yj6V1+ =CN5F*J+>!TqWwLh$S&>?#T^S8%\bVui+cVF#!1hD>bJ8/!j&PpRXnEDb>L4>\#%BPVt^%#:YLD8TkGp
Ehh%#% e68JHdVqHY56Y+=@1=pl1w1<$L\c%/H$ENMQ=lY*t4^8*>tYt#a%j\R*%Z?nXD>P+<Z+#wLQN&P5BLHY
?jCaGp uw@T/#6#Jk@D#51%F=i6njN!EJd>FdN=NMc!midchDP/?#RlNE#L@!#?tjTy6Y+lj%/^^>LMph*yYe5<
!aMu1F RG/th<nu!Gi<9t#i?kBHmAK:NQwtXq+*@Rw:y=Ft8dZk+AlCaut5J6:N+uNTnMHI^^m<@qmGu9YK/LW/
:@HM4L BVjG#W8CV&++6d8&<8H8>8/>>wuG<q9FEdT<jw&8Mp6CDi8YnG+#EXHP#Hndt\Zj8q=4:BcC#9q&%*^^
&#Rk5h QcHVPlY>IYR1!M+Ve<E\KjDkhb%H$V6RjQit1yZPCbuP!Z*Qkwd!5^?6@*4!#/yc><HahL*eLM8Ym8ma
!DP:h\ YMKlaJ&i>N!KqXbVP9R%ha1WbcWHL?Mqy*eW#ADS?i:9n*=mGTXkZT1Il@T/9L+M#<#y4*Xwju9>Hu1h
aSK>M: Zi#=e/Q:qMw>^><?<!=u@Z*T9?q\>j5X^5%ZV=!6PV<#uh*k9qcAjdRC\d*&>9GqNaFcum*VS/b:>>qH
E@<I:% ^hc6T:P88C8DhmMT9LBS6uw*h=:cj*:DiPqDu?cFBhHStTQbX@*uLbKw5Sl<ajZA%d<&t$n>/>NCNPD^
BSj+:I >y#iLWVKue6hy?Kuu9&SHMum*i*cFQ$maXiF:Wm+^t9=IeP%$MBZNTdV8Cq!iZdC:ph*%qXVN\RuiM%k
DMLj^a 4qhSR/M9DueVl:F:Z/ZpLY+/\:G=e1IJXdSnE*yteQe19F%tZh=4QJqihV@$6TyhMl=KVL&46=X$@HAS
=5XV<m hc5:!!1pWNhm=WDik?bZAeG>P=1mJ6i+*tZi4#P1k\ced:b!ZdB:?XkniQY1W!FPI%c@Sn496$hHIFjj
$+LlL? Xnj9>bm9ZZYC&cVM1T!pQE&$Wm1&?Yichi<1?:BD*RD@+jA@jZujnIi@K@cPN^wP&wRE^c$q1y/a$Ch5
98XRJE h=>bP@P88/Be$%Kph6&N@&9jdb9TkwGAL%jcd%p6$un4P<V9#*9&#Z9SXk^4/Hi@9Wy$Z%:S8hu\<b8W
y6y%nT +H*5=*4/Lm$BXe@%G6&hF>ejQeHbwDE&m:jSV6\==jQ+Mqd*NiVuq*ZjpcK*$u%@6dDCcy8%B6:?*JFu
H^iVGB uj#m@K9il>8+F&NKc^?X:4<l996*<=6WJH#tatZZ6w&m1><&4JydYut%e8LtubeRLXQmIZkLcQYpBZ6H
F?QAyW dc>hSVF6w%ZWj6@>&6awm^AND:%@wyRV=pKNLMX8m%<Z%&%Zi\G@Sin>8dc$jF1C\>cYnAeikYFj^%WP
GBBBj6 yS&@+b\c\H==?Ye\9F1MkT$E=*qq6a#ZNLZV5JeZ<dNQR<DL5M9&L/@W>C@d&i#eEw!$5muM5Lt><+d#
SldnuD &<h@t9tmdkK%FdX^w4Twc@%b<lqMXT>C5*AFuCMq=Taj*bX<w@8nYh=d^6S=>jHHFbhe^>wiHV$udR%@
Q?5kVh 4+uL4ZRIdM&u9*pJ:&#=cwFI:8=FHN&466mJRtYj^*=#Q<#B>tVHH+al*l4h&yHZH:w4=tq\y:4!u+Dc
>HV9cZ 9&9uLtb@PpR%=^&H\1%e$:yI+^NTi5YD=X#X?56=Y+/P4WhtZJHP$F<1qcmJ?I1hGydBm=ddHmA9=jjm
<%iIai T:N&Xbtjib+X85tCZmHh=Z+bqYW%jVe+8Yt\K:A8&XX%qZAEX5C1S^!?uhXihupljLZERm?Vk&GM=%&X
IBBStw ^aS*9?tk@VJ*@yX99l+S4Z=6Q/RHnq&jCPtRJ*h6&\d9Plw$?6t@@#GNM45GdX8d6kX8cX5nc<8Y:VtK
an$njh F>jN$P%l*VY+G9W9+#64&CL=?1j:\M4&k*W#c*bpXF#XMulTNu9=b*^+=Ek++YqRMcj>&/>c=<:D=#kn
nZ:ZRd h66j%%hJHHJ8dAVDy$c8pqlQWT5l@j5^A4K#@#K4u/WL1$!ietILGp@dS^bN!tep&>!HWyJj&i!Ay1Gl
#9i^eq Neph+!GVM>W5aZ4HlZ6Q^/aL9Ae1hB@H=E&8K&6/i>L>i5q>l@$&%?>1!B<e6*E>Bw^mdDa@^qiw^Vn@
%h$=pc XV/*bZ#m8L$MWSqV!YI@GG?5D4X4lic&S9*AS+^P=n%\iX*wQ4XT4*&??@4dt19$T9kPY+$Pn^N^me?8
M8hjuV W\6Q9w@aAluL4a:=5H55hjyGjhNR:u$uH=16t@b<$@DL^mFaLVa*>Fl*V%jBk<M=4q$L\aFY@1$SNc&^
eGdFqG qPwQE8P^N5Vqe^j5H%iH:uNG$QqhGceKh%88j\?9dlnJ&ADyDmD65nW>nH/i/<489a1B^4tPya^iG$eW
mGFJlQ \ydn*l/tGk$:/*8K5l>&QCjp&&8*yu9d9/&wn1b$i:5J$>anBQdt>iKwqP*#Ycul<TdqYQ48V>8u*mdJ
GENd$L $wI/54^cME4LZEVGKaMZN?T*GwcLkhD<5e@el*dl?<uDEa+udadZjl@Dk%+S:RqnP>T1>@9tC1?\TVQ=
bNubw6 PRij%AX%^>*J&l:at?Fp@<mm>=EB?wBZWcEu\ZWH@Pm!Ry9q59DuAYtwKbFF^al>G\5qR!T%%ZMKHEP8
yNT9CL QZBnFh=1/%MY9jQQbLp4t?1$>$J*N++Ehn&j@HVq!P5*FS??aS@l^M=w:umy1<Q1Zlpe1InMibAdM6?K
XP\:QR *<YXXCi6dTmIVtQHyM%u=ie>1^&$P/4q=F+R:b+*1cFhBe8y\EndYG>H6q&W$Kcq/M*PeHPJ>+jiYKK&
:>*>Dt l6c44tI*K/%!HeKCnF@=Pqa4:WBYl%n=WT64dZ^Qd5CJCG#>hLnnyVP*b*a?>@CM8p6jQlM4/bJc+V$m
ye&V?d YbeDie8G<6+P=>JnS^Ld>wh?Ry?yYGKRCAlqmy$1#%/>=DVWKSLyQaPcKGqqiZZeRIT^tmbt\@D&eY<*
SE#plc w5ZJ!Z$*YyG%/>Q<R\I8IZI4B#1>L#:6@6GY+^Xdp6$^<Vn@LFiY%/*#n^e?=Xy\iPpLW?=:>6&FQc5?
6J5Gy6 Q=+NFJ+5Qq=F/%%%dTZ9yCw9@/n^lte>ZZq@Dhtt/A#da\HiY#k<<EMLHFl/c*q9/llYplH*%H6nXIX4
N@HM!< SGZJl?Dq&LE#Fc!jF8em*A@/#QtqR6?/RHYhYp*&?uj6Fhu5uY\8Wm4R5uAM+::FcEPebB%uWhbaK*Wh
t+uYRe =8=/5n%SI<@4hpQXC&5Q8>Ejh@k@%d/bLj<baRQdlpdB+AnH=Y6!uy54SA<W6?4SNb+b5YaPEZjdh/5:
B6KN4: 4?84Z85i1G*R5N9JHn*Vm@>=yAm8mii<kB<64J#4&VX8e?\XE<bd6c9Iiq*1\>&Y556V$wbQ>i5H%l@N
9!L>%I +<pL&i6jZ@yTGGCtTF%eKE/9VdeSwV>%dc+eT%qut46+bdPY:wTVZ$JQY9KVm^86Q/@w@I:W8X^1=dLM
$jEaMc yS=i#T=y/iyGWq#Fj&pM8YWhjj*tlm4Apjy=y%ZG$b/*$TWdA81e8u$j*Rq$DhHih5J8N*9la8c+8HcZ
*S5Mje J$/+CM88wl$<n>6c9EmdjJ1:T5\=jBt@>CV<e?\KXMR:Zjd&KKnajeu:c/N9=96N!Q#%Ta#weHNP!65Q
VXiN\6 d$9y<ch8u@%mu1Ce%6mJ8:l?c=!dS$Djk^MmZ\R>C$uQRn!XebS4yVuHI!Pup6=@=#a!WjT+l/hQCe^D
&R!69k F*Wi&>Ebj&6GJVW!6!%YXD:%Z6!b5^S%Yw&V$#?Wp!\Z4>+NjA4CL?PkPb!5H#Wi1Md84D@?*wp:Zhu#
$?lC9q wq4n+*appc*ijTE4Thy9IXHi&9uKCNGcLu:Xp$H\%4VINB@6GIT>mHW1&*I#:9^aL9%XjcRwIlVZyiHy
JQK+V\ @:X8juVp$<BaSQcSy^8jQp6aj8QPtFHMhMbK%e#cphG*I?9RnZhZ>JYL#\m*T%/Y*1\^D@+R8e5J!:?X
\#yDLt i/d$T>#LFbQWpdHW=Bj*Xw<e<\:KV?dWD>\9jaNK8^!a*j%%QLP1FS?^Lq6!<p!yNQJ9chEE5B%%d8+\
>9Y5EG c+Q?/=KSu*GMj4k:q#F@T=:W:FnT@lC6XcAiZuR$HD8HC&DEwQq*%k>Q!N%@=Riw=$86Fib9%l=^5&#%
6S$n:K w&4pdSCF9^$:+Zjhc+&\nHP=e:@X5:IF@eQLTYK+eq8GJH^lujp\!\51&*ZQ#?$5ji9l8IQQ%HTCen5?
XCe+X% RS+/=nS?\j+V$mM?5!%^HT4/RhtQP61Z+$&QLVTqt<6Z*eKQN>X%nX%G8P@d8PECP<&LN\hQPiehMQj&
qLG$88 4eYE8QLVn:<9WAcZy$J@Hc8Nd$Qq9JV8Zte==%tV+Mc@quE<e?8GYhl#?&&//*FF>iMQ$w:%+n&QnPZh
&Zqb!l Ke/aVF<bXMb9+HEe=!#P*ie$@XW1ch!\^#uhRYhhH?:H^9:\6dut/jQtj+^\tydERWi4nq$&d19H4EjQ
H9QeVa 4T?9YINp*dZ9jDDchPQ>16anHTNFQ5uFLVYBP\#ymY8@Tayi5y+F:6wBBKX#MPW:hbDQD?y?/hN6n5!D
:Cy/&a ukmL?baw<$!A8T<<j6^Xh>a8h#p?<*lX4pZ<dKulhW@#V!i<#F4YjL/RYP16?a^=Zl?ZeM!V<V\1PN!T
lYdie# Yu<GmX1DAXj5V@W@84#Q$CD^<+VLE&Hml+MHkQukKyP+#P*pEJmpHPb=iF6bFiYj=SMli>Q>J/Ph4naG
BSBmL< AmiZj@aa^W#h@d9KQ*k5<X9a!N4:Jh+4L^d<ETjiM/J#?LLS=mPMy=e*@*q=#HCwYeS6L4i=4DdmHiRj
PACbVG X*%TdcI!yZ?HYhBw%HRkkyE%j<V5>c1>&midH8a>$H<@t4KT8*jQ^jVw4X6+k?%EaWQ8><<!q/k:tX@M
!68&6N L\jIn^+Xeq^9tlB&1DYMSM4#q6>cKH*C\W/F==%J$1q4ZdhyPTLnEQh%8t@:K$N=aeJ\WC*%cbL:<%9b
StKY:i D@iMuHP@@/4Y6ZVFH!ehn^5FmVd9146yAt9@Knq9>EMu::Dn=E^Sd9F\=iVVY5<#:q+4MJkN4MqbP?wD
#k%<*L <%6HiI@mDu/5+*VC^8@MEyGD!/FNY#L@wYq>jLkMji8aVtdRcLa//c4q?<*ZNNSZ=:^D@6I4QNkdWu?^
9/dk#G KtZ!bjm!9ehYwhk*jTdGIk@M!K@?>Z1mc+GabG\GYjtkJ*KneZdPt4eV/day%:MGd%*<iuT419mm+?HM
-Al:Q: 000bfcc7a8400110333 Page 22 of binaries1.zip
?<bN!u *wip<iJ486JZKVHZ^>c%4wPb*cAM*TY%Q5#^S>l6GDRj=F8a9X!d6nqCYG8jw?5j<GAdyPyMwD8mXj*a
pBkd8= 6n^uWl:%!cj9!Vk4Z?Glu#K4RSq%eMw!#T:mke8LFt>T6iHC+:1Zwq6QT<+?Hcp$V:6l@nPd8t*hT=NC
qb>AAa i#HFJ5D/?TDL*1VHKeD5JcS1+iiS=\#CR$n<C@/cBj?kF@QV@kjj9>q&NH@d<%j?4T>Zaeltp@JAM*t!
Nj:R*J $\6ltiPcHPa@Rb/eHcmDtAVqul%Qu<XKPKmPA$Dt9m:+&Fyqd5I>+<15?Z!#yLdANw@Ra8#&/NnaT?tb
ANtW4t BSdZ>w%>Dn*u&Jn%1cQDI1QWLAt>y<$#KeX1mKM&cW&XXMQ@LMea6Awpta<=!<?N%b+JP9D*:mQN+S9<
PJHHlL LZJSQY<@EwtCG<M>aR*^u*5G@MaFtdt5<X4Wu?%\aGemQ=4N$t><%TDbQk&HAHcE18AAy^:=H1l?6RTl
ELR=IV ^S4Pyuw\SkPmtZiSY8YBeCTX4YS915TMykt1MiqIw*HTp>K!RJ+hRX%mMcYkG1CJXhJY4a=4DQ5D%XTS
SLtX4h F5m8<LT9XM@\bM!#k/^H!PJNSBX:Vj*!!AJtY?ALcLeByT:hj4M<9l+VBP8Z!@8h#!b!ScWXZ1cae4d<
9#F&FT m>c/6NQ?8@dQFc!hcYQuul\ae??@pBG>4de!dZSy5Y<%/Skt?K5lRWy%*:Z9=CV#\q=#/5tpa^BStb!h
lj8d5= JRq\n:P==8iXZl>AM>N*MNG5FGy\*\6!A=?9Ft4aIH=$nL?tQ5Lp/JjhEM4#BZ<Xjj9Si>A/h!iLD1tb
bD$I5Z PKN=>HZ+1$Hl/:94QTq:4Gm+j>Yae*Q:@^$k4b9:@%cV$IQ&9#RJ*V*@*Tdl@@\1@=?@>j?9QSW*>*?#
nM%dAD TilG@??%49>FQ<dN<:@Z8un?c\!pP?&@%#y:@P9u8n9>>>4@5uuq:9^9DN4%Z#iC*F*?L&lh@\*6j\EI
u8L!i8 huj:N:SP@:1J=P:?u^yB@%Q=@/wS>H<DY@=HI+n?L!CZ:l:@=!GZd9<ce8u&d$A8*iu@#=BL?u?Ah9<9
?\%PNL RC+HGR^/t+&nd9uqiZd?@+SBp8RetkG&S6u8JG88MZNyntn9?ZyN8qZ@aGSLH@W#a95!iW^c$aN+:E/h
WIH::n >lmd8BeZ<SpAWk\lp^4bN441W1kdQV/+M$aDMTTaYC^npLXR\<JwYnQd?5nptn?/Xmc9Yc%MYu>*:hMA
cy?PdH bHq4/58@t%et/t<juM@mlK@ddT8>ZCqJm?d&yVn1XTQM!I$Vc\XZqNKlA8X<wbei@@*m\HR6ER:JRA1h
H8h#!I F5#L@Ea!uL>TLYMqq=5L#pd@VL&=V/d/5Fp@L<Tn>icFHVIaZue<J$BdmGyt1BG1R<\lcyVCcL9GCC6\
@Xc4A9 ?VebR!cQNmqAB#p4+4yjiq%>hRD59ZHP^ATbXu4<t#uP%SlpL1d*wm:WNkM9V1G#^Zd1%k6>>qZX6ReJ
=tIlTD /m&Lq%RpS4+TlVHD+iFC>cFcy&1SHYCCWdJ81m64^b9Rdp+LB%$%#Nl**VXc<^<n5FDb<SelQd8%Veh4
D=%<Jl 4^%Fn^jY<?iPBNR?t?t5G%8aqap/Z9>1w=T?hRjNqB?i:A^+?B\AKD%L?n6Q*n=B8ywZ&?THtX9+!eCb
aeaY^e c<F<eBqp6HtqtEc#DuMi@ki+GZQchuuI:jQqEXe49pIC41P=4wHwutS1+M+Z\pbCHcMV=&Xyu1V9G5pH
9cPmQ: DWKA6^@4MLTaHW=l*5IiXWn6?15PJpmakPKBbh9>9ZLK>cq%/5%8+!N4@MeL#E%&nqNL\e4=@e<1MILt
@@@t%I *A1e8DWV$bZS<TAM9<CKCehuu*ZY$A/<V+@eQj#ni/A<CGnR84hp>*Z%#c8L1RH%:m:t6n5Q+^yeknp?
C*hWGX d6qJ$=i$X/*R4ZETY^*Yb^$l6A!k6G9YKMJlKyRkKtu8YkW:VmmJ\SJ4%5p@^Pyp<yIVIc&qq4B1Bm@X
lX^6e1 Gh6GkZqL$:AcP/iJd!!Q\m#+ijed#Nl+u*8JYY=4E=9&8B^=WuI$1%p\Wy841A\a!E4YE4:M%lPa^^n=
K!:5hu /S+?BWM!%#FT6QhRdDDi8k9e\SVC+T9F5XZ!8yKECyJQS+Jkm?XAVa=8!>l!*jR14NXiwZ#&?6y@jIi8
qJ@il> QX8t/:d&M?Gqe?1PF=%$@d&HF@G4&kY1^unF5J^X!Sj$#*CJqukMlendnPWJLCtIFbCMy4R$<dAe5BFa
Nkm+nN 8uXaC>ic4nk=c*T8!db^h1mJ55hMD*/9#MjDcdH+?M/pJdNS=1/tHj4EWwQda:STm@&>eHCIm1!Ld5AM
eMQq1j Vui1pd5FGGWYjylYRy4qYEy9FRIIHEE4a^ky$e+\qZkXdSm5Sc9@EZjjhQ?eVXy#+5WQCBnAWt!kuj*d
tHRbQG jjZ<m:@c4M1nilTXIHeQqK1GNCh=wdK?MRSnK!\CCFuXT5BT!LtBX=4:cnu6^eq\HRl8=<q!$M=TMiMy
/8KPmK 4b%yqiV*I&@k1nRFE*4Rmbb+wBT>b8L>%aDEl@4pp/i*Luaw1lehpmA>VWn4cwEG&NIIAMQIaTN4NI:p
I:@FCw !8?+6b:JmSP\l>&ACt$alJQVWt6y9J>/CYT%EHyjlI/G1Wm\Pha5buHSTWt@m=C\dT5d6^8daey1i8iY
FGH%yl Zi:+IFId8&iw<Rpu+WI$IV$\?F!KqWbhu<t>Vkkitu6WF5%j^Sk#pKqpMYlJ5d?\*^WN\&BSZ<d%yjQu
AtPCbW >$=>+Yw4+n!CKty%#W4ZX!*cGI^P4naaE81Qq%^&TD@%@pA^8tRZdkHCFBQXA5RJ$wFBPy?>Em?<b1IF
FyF<Vd VPA6iCmw9GH:$h=&?ymS8R/5DJTCa\dq%EkYPTY*?9+hb8dZiS9KVKAS^M8T\TkD$uMV5YpIG&ANFQ&E
:Iu&j> /^I%uZ>t#Xdunp?I6tPWRpSRQwdE4Qe6b$dcnjIjE6Kd+WIKEWRG44h=$ydw<\!L+ANieQN=$:B<RENc
CtFYKW j+>Miy*D:/u^GFukcq9DjK5Qu&haQIX%Blpb\^tj<686IYq!\FXDmDAZB?L*c6WId6</G9Ncw!EWD4kI
\\>^!= iX+ljNWNnXp:C#E@lepku6kwLw*q%&&YBtin>AW$Hl@HMECN9TTcE=jBi8@/M+HZY#M@&eIKFN!8Da$u
!dM4%! &?Q<5JM#@8DJbY/RjJ>cy<j\/NP:D%$QHw>X8<>>5iPK%aB*uwbXNSQi5/klkAWKCWwhKbjBG!bBNEml
#F5DYe ^\DWi#%we#aMN$MSKp<RkD#%P9c+S//QQ#AaGBV^5R5a5i$@1=91e*9IRTeE%W61TYHJZCD/#Hw8mTp6
bk9&pJ 8J%4c&MH9*4?D?G:^=Sh6HLel%Iq#HcupSF$tQ:^WkchAGjR@EYLL>Y+ni+!@m=9cMei5!h&TePFME$+
cPY@PS eRYCKWBw+k=p>B#aQ>LQdyjI\*F5V1a?I#!\qYI?DFY6I9Nu5mX:q&h%BX8j9:?cQuel=de9P$HAjcTY
Cj?4=J XPp>w9K!85P*kIw5hRV<!m&pHundB\h#/YE%T:uKkc@k/k%j%!GV9b%&Mk/\*tFV4t:KX5KLC=$%^#+d
n4<Ct6 MNtYWm&YimBKRHlmq+Ii$N5KW4?e*:9i+:qh$kEL6@F:GWb?!F+KQam/%*m8dBWCh>8/>@=tLNp<EQ9b
+bCY6D T*MwH/$^Y#wLPJF*n4P1ePV<RKC*%KY<y\Tq#DZXLDlIhH8&ebwwH+QWQwME^HXnYtF=/1RGHWl:ILaq
a=pk\6 Z\Ih1HE4LE1>aanWuu#$yPTM:pW/R^cpQnBKRLKY?N%qYmCb+5ak+&AB<!XG:mjjZS*Dcw8t+\Y>DCjS
Mah<&/ Jey5<n?d<m<8lC8XcFQ@b%4\@G&cm@pAPQlld@=d5+4Vtm+*HqS6?ySuAMDGmlBydX9@cKqH?^Q:p*1i
jGmqM1 qL?MZHhLJl5$kkVt1n?:t!jIQnW$<%j4i?!l+ZQ9X6++Q?\/+yT6EZRGC/ZIm*a1q&^W6l@jy4m$Njee
EAPGma %^6m%?kG$JdJeB<w\:XuEEA6B*Y$jN4NXQVt\J>6t\+?CB@Pj1ZdY1\tub*\C%qAktq6^b4MDaI!9WN9
hM9ADw 6&$FbD$*NMBGK\$?cV&wVHC%@T9%&RGZE/@>QB>ieD^JJdMwcMXtI<qCF&4Qj489J=\?^/5TaJEw&>X@
R@\9JF Tcb?@m4+t4y?@99&wVh?y9hP4X4^bF91:6i@QF/@NbWLJD\^:nLJpNDC=yaZ5NijTQ6?W@Zn/mW>:kSY
9=:^+J eANHbmj54Q$+AX85Nj1^TL4Bu#PcDWW\#1tDM%ltMWKiw/=KJ9K@RMj996w=>cPH5qW^S?RPtm1W\MAa
:XK<FQ XPt6RWdDBZMjV@TC:/:AHjdD%Y8l#DLpRCtM@$%#%Cm!*RnkicHZ6XR:QpX1*5$qHhiTV?q!!$!=KZEW
qY*e8j DI\^Bp+aItpY!H#q:Z#EAZ+qC8#GXj+E8KpwHwEA6l5!i\#Bjknb\bidnGJHIKN8L?ZX&!pQcyE!hQm9
y:?ZR? n\EA\NMqpKe$8ZKC*Q5EV^iC?^NN?+1e6MdR9y$W5CHMlTEGBM1a$qFRRJIhlp@Vady4pZcBbCP?\kMj
T>lV!A <yjci!9NaRmYPcHDK!HJK:G#NRmBpRdZHcPeAWqbeCYA&uFY<>$LdT%:*h4Iu:tS81VH?tp\IlP4^5j4
FR*TX4 M#D1m\AAi15^cwiW^/H!Q#WL>lukWKFMb/*bZiI^Gp=FBepVFuM\kE>Z=@$i/*EMid*8?kHh/Q1jVwjR
dqY:Fm /kB$kLbmNq56YGb$Da%YMW!W@Y4p5aMpAA=pWJ:@TeK:$tdVNQpeQ=IJt68w^8QDM19S5*FGe8^%JYA5
^Yh9RV 8P*uDDX&4DLGddI5SFZ#VNR6TEkqH5J<1RQcwMp!4hu?F8bLwc4EeQapykh1>GG>hb8DKetBCicy+Ven
GBA:w$ Eh>$B/a%8Fk$1aVEtDeEQc#jZ<jWY8E@ZMi\Z8IXE>yM4KuA>jjiBQp>GHI6k6SuPN9M4eQm8I8tl&@c
TN:6CM >Y!^4B%q<p5R@DkAYG+I6t5PPG5!&Ec<jw!!5FEJwBpenjb%huZyyIIjN6yIF#HGGGnRF?SBRIal:<66
w5RXKI +HkEWG4KDeV?Zu:t6Y8*+Jc*@N!j65GaycC1FKPk1VFC%iXaDYcb/RDMtNhEIHYnTdyGG86y8!bhZaye
e%A\%& it&>RkEnTy!cIB@Kjc6=hAaAAnV>ad1CidWB!KWmyke?*jJ\G=y$De6aMkJGAWbPDADALa$\yMet5%D:
W6uBBB /ANiH\M#6H%<nwV1e#55+kkk1WPNT%AD&#uKm?D8I#/:*J%W*RbMHEa%n!XXt=Kp/?WVPZM\ND/JwjYL
&?\y:P $ihwjc8LwV!PIF>pFtjkTV*/yJeRB%GRK#!wD?Yp&kbymaMN+A\Hpk%h1+*I>dy!I+S<Z9@EVXLeS5b6
D!u$hn Y<&JeVp#DZ>+CuP:D/M<k^bW\ypApnHtZbkb885t\/!FRNAPn6NX=<w^H$kD46E?^henm+1@E+:m?R>k
hEnVd@ TyWyq/HD?<Q&$>Ww\5&RkBc$$q6Hdp*kb1p^l#YBTJDE\9DPGA?M:hBSn>!nFuu4YFD>aRcy$ITB%?WC
%1buMc CNJq@eJd&t/8%u\VLZpPnNFGWtTDbD+KAQT+X>V/TneW^!j&6Rd^WCD=AX4qE@hJEZ5:wa!5C$?L$\Bk
RPiIBb \P%D:QWnmb?*JpEReGYDipHJH#w:+=*&5!<@WJ8NAc%KhV/*?6#^mI>:q:!lt<S\lTkw&p\j:#&H+:W:
tSLSVk a=@SwF#<68iuw%\uX>#1VhF=F<VNljAwY6#k:9lZK<+kVkH#IQppYuWLh+ii5/E#:jQDhHh%4m1u\%*j
*jdB%B @$=ZnTwPJGiw#jyG8dt5*QAtR>iJC%9TXiy\XT6N*j$mV>?J:ZkLVkanqMZEDV?+CWuy:m5V5>pp:l^5
9<l=t$ kGJCpmHeE:Q8@BtjLkiCyZBG/1c:5c6%DVQQuEwujRNJnWDC*nYud/*=E5jkw$\biD%ti5IkB5tNk^<=
-A@/Ph 0008ae3b30000110333 Page 23 of binaries1.zip
*%CVV: uPH?S@cG>#p/NiCb=eR9nRCalkTdIdMeNMDMQcPZ*:aNEKeRqAA\CEP4m4Fe<@8#Z=Qeu^iiEiWJTjw1
8Lec!j jG6Dk^/QcDw:c5L:jRmE4L:dY@m*ZR<AA^q+kkw\+RPAIl<*WQlchW*=l%Nia9VGp8bE^R<d=R!Cih8W
AZQhEQ 9/lB8>A:?&j?u5tX54iI&*l6lbeY@=Qyl*CT<wXLmYTD?&Y8??99m4ek1ehA*k#qVaCplN?P$hD=J?*i
ZiKHm: 1a&!dQV5LTajm?h*1VE/VFwRtwwc*MmV6atQN8$>ue#NS!5mnYdVEKS1pGS=m$RDXFtkZhnY9WZd^\Hp
X@MVH8 4A1m8IHqe9SuG$F!QyJjmi/:P/Q*eGMjM4HSip9Gpkb#W#+*YGh&F$k%N!nYKhkdJd=dwZcXll&kt1!b
?M&ADb \/5TVFWNJ9LnG6\GR&DR>N/Ge6%Zt&LXM\X59HLt4KwaJtkCdT4%TBT5epNc@Sb^j*\=laaWjMNN%<N+
$lI^Q5 jyY#DACREkVi?6!d@w*:C9j?!w%9%%Vl6jnteJI#WZBR##+QBtRaC6y^u?FXT%dX$G:+Aq/jZ+qR96RG
@=KSDi PKZKGBNtnRFa?Y1V>8=TcM*NCV%GPFyA%EldyDBKpNae?@:%%jV>i>K:Db/WcTl##E=!\iq:hWp?YYiV
9JIQh1 #BktGthISP$Y!?LiQjiL<wjdWIylpF!nC#ldppw^*Cqnam!j?Gy9=Dpp6<cCKWMi45a4<p$b8%eQmPH<
liplbE Gw%:8+XJ!=1GeQwEI4\<j+nZDqGG/uE4eewGpB#d6Kq1$/a9X<pLFw^IkuKR^D*NbH=CM*jI%j$P/B>6
GQal@c HLdBEQl1JQip:t!Qqnl>QpJDpANXjDHlZn8^&jDR9n66id8$=8L$AY<6WkwMVIM!#!yIiBnQSphA^Tpa
/GuVEM <I&>=Wtj&<S=Gtq^?4Mt*tqwA%YQS/jKTJpBW%S4#+dD>Y<y:9#1jBP5^cXD8C#D8l/RuGKmcwK*^Bq#
:\#&n@ ERc1C*B=D9#1Waq?\SG^jwkK4<d>SqVT$N\^RMuSaHA5tF:wD>a+XXIZ=%BN/h/>9H5S\nmp+1XF+k&u
NIALhw Nb*H>D*d#M%S!pkDRZBq5c/y\6empR8RuPGKY1#mhP*Z#l/DnX%cQ+uSIeGM^*limWX+E?Jb96b59w/6
M=54\K d9YKkL$=DWVZi$\iD5M#JHBD<R4NDeI+SHbtZ@K694*uQk:kDRcMIN\Hyw1y@PAFBC@FeEXWj>G9:QMl
c^#X5I daEaSP<VJ1<?c>4PWIGDDeab!?pt*A%>?9?Edqq*Q4<R!VhB*MyF1!c$=Npk&GPk#NCjqcPTtWhY:D\9
^Mw#JE *ta<1$RI95EFhCClGntdkCJ=c*c=>J:jMdn@L!Z*?:KH8$><h^^<8Hdwu+hh!+\9#nCQyT\jhleMu95S
5u<dQY !98n?b?/myuIhEG8EXa6:c#YTFuRTGKyJ9l8^Mln%J!QJiGlh$<wtniMjX?&\Z9V=Suibd5*a!pXw\@%
a%>*4p L^9FZ9HiiQqC^JYb5DH9<4EL/+jLVq>yZH?q:NV+lVNSba14M$i8GX&@q4LnY9P1^8b^=?bd+!6PK<5<
1:*kn< 4**:heNI:cd*nQQM1/#9P<bu/t:GHdub@PNGYhMGa&l8<>MdQ5mJtcJJI<HNm#c^K\&*HNC:@H%wM8Z!
$QGP!d XYQ!%S@wZB<Z<jh*R#P@4yj69MJLR%#=<%d#\%6DBBmA%:Q=1@SHlHJq>N&XRaM19*PjCKCt+%*nmq6y
W@!+%! ^dn#1MM4*Tb@&N?/GNDdFBHMjH:@a94>8TYM+tE\<##m^>+yu>nd*#66kAwYkYCTyHu@Wih$!$HDV=p=
VPi@n@ n<:j8&n^+PI6GpPD!ine9hL^L=?JGIZL*5E+nSu>!WeZ:^&Iu&niyVtRaeH<>5Dunty4N*%%w$W$V:X!
GVLL5L >8GQDVM8iZAA4%=\hjcDT+>FP=\eCFJ**Hn5iQ&k+h\bZ!T9W:=NdecEdVPAWM<8u*@5h<u+<?Qpu+Vu
6JtwX8 Qp>@S6*PwmMQ4L8i!q5\<Vq#$Q:b>@jQjYNXF=?<8FTqiu^w?6G?Th?c9cp:Ht<:?8Jk=?#n$/<iH*9%
kTe+:? M@:qc@8ZKj=Id4Di:B@6!k8EpjM9VLc?mAnYq@65JI/<NSp:biG8!SDCjQ>+BJSk?ZKhl$XMyyFG*Q^I
K>JWNj ^J!9&+cZ/c8X1tpCh!J!$+4ZYqTEMlpFEI%+jDVQRX6%AcN5SwGF&65NZ$HF/5^#II>t>N*1dhIW\Ili
tmam4u =l?HJ!jn?c>l*JQRYX<C&KE##:=StI6lByZKbbi*G*tSVdTa81c<p$cpBALbLeV*P5Bp/<?iD&dmEI\y
lLS@W6 \wANlpjZW^F%=dMu64Xap9w$?M=/CmYGPRwH+Rq?$WP1+>y*Sm&a>WSq9J1<#aS:F&kBAAGDV/QVACle
d$qVYF NEDPH<8%$ePJZM6SFCAyGSHbX4pw!>%5cq4BXDld8$yNmn!X@LWd8NT5ZFwFF8a!MS*nZch<u9?C/=qZ
5ydnT> 1W9?1+Q8*eCBHX\?=#yG@*/NAL5>aH=!htch/W4Bu5/ZQq:LjY1b%*Lt/6ZEw:u+9\I59**%N\&1Wbb+
ZH$p8E ?XRTE1%1Dw/j#L<T:N&89DL@>jNn*!mwY6hcC%LYG*MAik8YY?@:uu6+uDS4%ph\H9LXud\5e1+DSBHT
L%p+AC $Mtbt9YIBL&#X=Wbt?KCImE4N!^6Mq9=D^K$15qyPl!l?4CqecXnt1#/\*5p5?L=dMFuSHVKibtDT$Fi
hZq+$M 8!XL:DbT?wbW8VWi9jEl?telJn&*aMDY>eRbwp*8Ka@>j*&wHbDQ>uRE!Rj:m%$cVpA/\k!XumclBp@P
1Nt8^G $u%k#KYDdiCR:BNDIq@V5K+KeiXBb\YZShTVZ<PQ46AJCLlSb!ZZc8@Th\yd4FYd+:@?&<:8h9+%Scck
LZH%Rp 1\In=<8V/HNJLS:Cii5Qt1mMV4GGM&1^#ZtuXYhpYK%$/a8DcVRN4&$+MlYme<J<E1LDR6HFGZ4?t*#Z
Ep<ay* wK@&H$hYQcY^A1Rl$aPB>Dq=k+Z+6l9GwuJuT#8/*l@+yLNZln886!eAkkQ+9Q/?nRiijJybeq=\<4Kk
P\t9NX Q<%@je>9Re9ebEhWb6\%c&HhtYZXewBAdy&4XY/5lV4Spk<!Awlh:GIj4cBwHt$tkVC5w1+k<XTMqS=W
t4?SXW KwwaK=!19&DFHj8Kd?4qAPEH$##4aYBYpG>9A$XXRYLS%Q<ClIl?4t%q^8Bt5G=%y*^>FcR#$L*86w=c
l!6d!1 89l&lC=5j<8LL<GC4BTAIBpaM>pJyj#\$8yJ*AYn:/Iw/p%Bm+e+ciYILNX*%@Q:nZct:d&hVTaMiwad
eJX6c< :4C?LKXGEP$<ADNuQkdT+%SFGPTe#4LI&un+<&kTp&n#=GDkk$8k=5CnRPjtkGai?$nn%*!aWDLRpybL
k\#$Jk ApwlmAH&k4@?EMylk?qZSai*du4HIF6uNhpl6PHPJtY/ItDSL%IY4tQddn!@@&ehQ#N>MCa=lI9FAP*E
w!qJ<+ 5$GaEP:^Ck\mWmq:<t%u=DVBlVRNdhy49DAIJY5Xw+!HD9AV*n:N:8iC\u#Pl5c&Ye6VjNkmadp%dDI?
p>%YFR W91:%5Ql9Ll>Gkpw+uH#jyXDhEjIyWYkiD>+**Kq?mycu%:cZ*:Z&#a@p4a\aY<>NdLqA>Ny!Z8W:BtC
?bnk@# 4l*>AIIZ>LjbE=X9JH*u8plGD&VYdypTFaXRQj$5BGHj@1L=F/PGSXX#HZw!a1@tZD&qX6:6KTtI%*tV
EyncMS K$LTCmD!5Hb*wALP4:WbJY@&e^lIMbPN$An!w<?SqNhPA>\?E#pSIK\&C9Ib9QV1\Tc^^8DF\@%*9L/&
TmW+p8 !N>l#dhbhbFM*LB$%<%6^KAcQq=*hGID84XQDiFC5aP#i1W\4b$!MmWiYjhn!?LbDk!9DV5<aXd=AdbS
nN+i^M w4DR4RX?X\uluhZ%4<<mYEM$Xj@&QW+<M^dPRX*4^h?Z><#4KGe9R?iJFEl65eqPy=NEj#5jFJD/I@XF
GiF&i^ PWwaiALPa#8$ESKSF6V4nMEPQST6h^h$AquXE/M*KQ6CDKnh+1nt9mYIHYc$C&%Lu?k#<S<nq/9BdKY6
P+p\y6 NbCDBRlNeq<kh8HpGDR:FD>j4Tup*VTKG+lEQ@uWyabdcZ8X/P$>mNpwnj:mi:u!I=D?HiF$h4*P+MRP
IS?C&w ^Eth1X18X>^\+FP%J$C5&iRVQV:4MPpJ+Gh@@%RIm@mM45wXwcL#!FDYXaLIqc/8aupmeEePDLNebLMq
EN&wp6 5:ij\k9p<%wI#?LEc$+InAZdZklFaeT+!*1DdI%14WJ:cjalCHA@d1RHWEe5HGtKi>TP\8W9W\%:YIBZ
*A>elb uQa+HR<WhKAIDFuhPZt+L+1iTGDidh#Z6A$A4/i95=%AAtSu@bAP/?#hXBIWh>JG$QGu484$ywyiCt*N
WW&?w& eCJTe@pS>ppamplVa+qSYTkpY#icyGa:nIqS??dJ5iyF?@B^:n4Mu>5D/G%aKNEbyVmPaM4!CYc9ihDN
6p&\^5 *k\B>iZt&MnLNi@nn5CbGkAQb*TSHRMhaFH1k5I*+ulhZmGeiu*FnCcW:/<i$FPm6%+*E6h##nQ#+tCq
k$XTjK IB6MV45EnE=iXqP\bAkc#lS&yR:XYk\Vh%=mDC:KR8<&><Li\$nljBmt%jK8#iIu#+H?%%lk*lMEdtDF
HmLY%b @T8%Sh$AqqG>VM^PlA:Pd/N<jpaduFd$F<JYl5ntGTyZ%%a8+IQ/%l+XWlC4e@1&n8dX5DZQ^u4XXhXj
@Th+N\ %D=$+EetweT$V<6&<q8YRYXSmJHd=*d*qGwQV$K!K&YtA6w9ub!:%5c#Y/E\6n@1L>wiGKC!X?6B8a#L
jFk+>q q%>kByKFyD!ebH1b&+lKd!e8X%6JHQFRa6RE^AyF5jZb!<QmqZc:&lFwS1B?RM*uy9jJebj>V=Ca%Va?
ckDFWc @cu#kYM:!lVbSBkVwm6GwY%+dC<e?SJc^B4Rp=i=TumFYIa!qTlcBJD=H#Rla@eIRql59W4wKu+t9c>=
k48BMV *JDBAA>Hi=wRb:P!SQ><kwR/RhStE\Jm6X&%l<e&*V+l6/6bGw5d+WHhn9R64?SDHAa\T:1WZKNK*Kn^
A<9B@& !KLGXMcTD%D*><tNm<qI^!WB^L+YG#S^lD+TZ8JP<hYE%8=HCl5=wu!anclu6i=TSybAXDaYnQ$%MhD!
euqu?k Sb@EL%A&t:pC4FL/^+hY++&FJGXGWw!>F*MkaR^H8hCqPiZqEpJnEEqmQ\^:ASQ+=Y>kF$Q9MBeB#C?L
:FL^=% %p%94e*qj<!EpF^5$lqmNXKtV#pam^pt=l8:ya>NLpDX9^GLp9L@eEESh/P8Kt$By#q:TYp^wuW?VKKc
aT%1y: <l&RQhNYeXQE5@j>49Q*I6LKP%>ZnGPju1adXXS9m9&A%^tRZaW#yp6q9hM+MjYk*8!%Ell+TX?bjYlQ
$Jck/m i6p&>Rb9=lBDDZZ9pPNIJLRqNH5q@?PFWKC8<KZnyql6tBFY\@NpwPDZ1Ww?+i8icAkAS=u4y<E$+dmD
jlwT4\ Jy5!tuLIQX:Q%CA&LRW5LD\<BQwBS<m@jS&A^uXKynAtw\TD%/NLEYZTjVe1G:iRu8CM^iSFNI!XJi%*
6KbkIA Li>b^b>\EVWGIak+JK%M%J<y:Zje!#&E/A?$ttL?&ZL=6$Ml6d:HmjywPcK%Fmj1N+H*BCGu<dCel&LT
:k!ISh FlnSyZ^/GdDwK$c^JY#mpj6VKJ\ZVEc>8G8FIMcKRleC?8cX<mKCe1Y+^>^/aW\\da/Yb=wyhaSle#Kc
mbtEwN /eE$wVVJ/jCH>?i6N$qqmbjtQ9Z=R^BAy+knBGn@@PqjC:DMNSe$!w<8?jV?LcIcHi/QLEh%Cyw&!+kd
9L>mY? AbSVPTt<jDyR^QhHqyIqm:FIyc=k$^/A9AqB<#ByX8?kM9ceEl\uq4p^aKL<W#IYSeAkmJe&<JWq5Maw
m8Wa5I IhEIuCkBJwnkN<\iXNmiabM&hZ^A+!:w+lN^SVYKqeJuEW^LDZYwuiJV6nJmP1#QB8YWc1*eW1qI/Y4X
-APB*p 0003451dd9300110333 Page 24 of binaries1.zip
ik%@qq *eqZE&VRt6iEhe9X$a&8M6KcQ<c>^eV=bTRAeV:T4t*F\W>am@/5*WT9QT^!iYMJLH5XQ:>WcGhp#DkE
um%BE8 cjRadq=4R^JAipJ:YTVh=Z$XXH5aCTi!qXpNQydlwpT+!JEYY<qWYMna4+8qZWkdV+D4SNe!EcC?kS$m
=P\*Bm aN1GHQ9JuG:6j$=aQ9AXaMEXMYe4<>XE+Y5N8L=:bKCR&%qPF<DGM8Vl?Z^YTRedRPRYWVK1D6BMl$+K
b?W+L# qa6h\mu:WHa:WyX<?VX6XAtA6$dEV&bCmWHu!l\M?F:\&lWZp6Y%L6T4+bdX$Ep!plY@J!8M?M&>Z+Aw
F\phcm 6Ru?Fwum&$K$P/XjucRy&WhKq\BG&XW9mtQ@MLky#RIF\Qb@6?1Jw8b*!*Cl!+$e44KZIL9hQBbVB@Nl
E?Eq^c $9uhb%R*RC+&*I5Cu$^5&W<wX<LRVTaS?l$RZAn<hWZLlc9Z^pRCFaa@@YRWEMMcLRSZPlCB=%A$P:A=
eqRqAk E\CM8%+S>qFlA1@6S@IBkInD%#JBSlBA5kdM$\Fk8#Sn9$H/H*T8MaG6deq%FKVBJE8h8#5Ew1:E$QBi
yBi8EZ a#+!hP%>SLIZu?Wj%hay\:pK&w+P1i*tA&DpYwLIW^8pMc=Z@C%lcAP=D**ch6/W&\yq#pB6J>dVBMX\
iq99I@ Bb8HD*mjRM8*t@RuTD<>BRC@1HQNEKJ:bTN&^+5J/KhwcP%!PGi4RJtNyK<T5BpRYl1$MWZW:!yBCewZ
dJ=Lbw *KK$IkXD:&VW!MyGC#%8JCX=C+#iKjp>6w@Hl?yuDyZTl>9WpcZyqa$\M\*EHq\SamHT?hN?^lkA^6Ep
tSiybK 1p+JajjW:C%lKdy<ybyS68>k56XWkSSk=ePwhyD<Mpu6EqnG?%MHAkAcRLje5$NEye!KSN%kw=c5%pw/
S9Z=V? dRJ!DM4#GcB&FS#aJKFVyESQ5F<H9pmHhVDk*QRIyW@=G*QllHEMF\C!P!YF\eIJq@%5ECH4qPaL!u6T
=ek!M/ i6>+ujiB61F6AiwthKQ@Nc%NWEaahI@dEM4iZmWIV1jSGb*q#iZGDA?llw<=Weey#W4<qEHkPGu!6&nK
T$WhbB *ZZCKQDQBMkFkR9kX>uw4h%nLPLVkTX@&GIcp5WGGTCa#$CPpSFERMVjntBpTcdZT1uYIM=cn:kKMj\i
ZWd$&\ HI8#&c<4auWK5\ZCyZTM!4qe8b:@?wm+ck$ARAA94ctbZ\b<Y?@N*jWLmNMM@WpLF\$?p5?tJ=!m\VTC
9j><QS IX8dVkFt5B/amQA%/5W:?Ncp?!h6:+=@ki/VR1dDaA\$:KTZWG=i#kmHNG/XLETMdMqNKK!X$hV=di?Y
K=+4!m M!1ADa+6@SAJ44PNd%litmuNV8HVMmZVTaL?LDE%XyG6B?tHRC=Waim85Q#AK!h#hYSRhCQ?j9d!euym
TGjPue BTQ<8P^J?bIl1DKE5SQ=Y&9/$=i1bcXV*&dl?pHRFA/WYAcQju+n?dG\j^*WVh+d>5Gp*?+/*S:=i<YJ
mBFC6@ AkE45:!HLK#FAheK88S5cjYyMB@*m#$RJP/JwDEY:C<XqByC1Z4mCS*a:IN!qTt$NF9IXlQI\^EhYby!
MLhBRi iAA^R5nqL6>hDA$eKuhmmHLjIl6%^A5AXEaZ>qkNAtL?GLmnedpkt+I56aXRBYh4ZS+>/1\P54t6@l!J
GH9!Jm C:tWQTC$:mJ\6M6^cuW$hQqT\9IP=F/nu45!pZC*m%hnJL!nW=A6RcCYC:kMMV5!\NkB&yn</Q:HqH\B
QblheZ u?kc*MN<&Imi!ViB\AISHT:\iC<KZa@Q*yK<R?*aAqt#dehq##ZAlKPWGmPk\q&=MKpMWeeJluBD@!wX
t6DmpL <M**>Icc<<M?C1>NwuCtAtYWwNSJcGkLa^PFm^H<yXB?Q\kuFcJwZlL^j6B+&Ct:wQLAXRRueBhK6=F4
4*?Y+m IbdyC@bJNPYY!NypKJ?GG<p*YVR>&GBXZ6dAb!Z5Ke$S$8Kq=%>MHN+HALH<8AyH@>qJpwlj9B<RhMEB
u1p&#N kaAdD%@TBjkGN<%J=j*BtiDwM$\9p9MNMZNNS@6Hid:D#Rua8Xwn$G%ZPqXRZp$VE\5j^Q^#1eME*p@+
8QK&uA p?R4YXwNBVBEwBDIhpT1>JDe>aJnTkt1dC<^VFIL8ZI/YG5^D>&aARC8=hq4K#!9%NB%\VE:eTNPkAwY
A6&!Yn 5DiLYc9+$\EmXa=hj:cEV:B\!>BW/4F48bWHKH^+laV6Y>+aWY9he$\qFKl5wa9LwdmkYBlN^SK6/F5L
:Z8+by tdDt5$IC?%j\ATc\?eVP$pEbQWImw+kYI$Tja1X^/BNl*<Dleb<i4=$6I&uhbbKiFKF1FKS6lR9!%PmS
R@XLWq jQ:Qe/Y&k8/%5H@m\qGei+$8pwW5PC1&jI\p/5?SwBkkpFJPZ!9IZmZq5QuEiPka$4aDW#/^hdTHuJu5
6hP@tC CV+SN*jER:M>JM$ZG1>S@Ak6l#b=k$w/JH<D\M+Ye=eyVlKS46pwP1E=PK&<%AFkBYVR^1R+Y\F:1+lP
EF?bV? F?AmRJ\^PBbd*pmA%tbiZQCWnDciA4c#inAQlY6kd%an%D?F!4LEAItjn^A9cCH+SRn8NmSu1^CkkE6J
W<4%S? aFDtu@Lq%+t&hFbuq$tY8eyYQP$ChBT5R?&YEt&RDK*SYwHI:n$EBSNtG\9:<mCj6EC&JkSw?4%M+6>*
C8A>4j tH^e=dW1>VGBkGM#im1#16<&ARZ4=\CcZI%*<lPCnt@R\dQCjp^=^*4lRq:=::9n&dhTlpY=948MFph%
dZ1FyV +JTZ5wX5G?e^EE:*hK<XT1ay=a5Rj4a%hGInIu8ntI1X@y+$wk6<MXdK&tkZh%?\Z6>/NJ/9u#5:ykul
=DHHlK t8N::AFqyHDMEDcBlC*^pI&^WJGG6D?cu?$ma4u\?c5EuBVlElSTeE\mV:yK>*&p^RdLDk!YpeKJK^BL
584SPF J8WV:uCDJ:J5!k/XHtRBj>!VJDZ!RhDy=$1N^eeimR%D=dk\!Rhh&WIR@<1>C8yHaAJ=mIYHL@Jk<i6q
DV<ltl PCQaS884Qk*GXF5E8*MiECLP<!1@j/tlb&Z%A&AyA:tkLXT8>F&T*LA?KZLJFN<klHtjF!\KIKRaPGP#
ceTe=B BJWG\<ZAmAnShAqRmlT^EELmbymqQk\Xn!Vlkky?AeRe&PFHq<+Zl<T?yb!WD9!8uWqp+SkKwMWA/$5R
M%>D<H uQRmFq9etCJiel*tSAn+NGTHLS>*D#/BVnnijnj%c6Tmpca<TV=lHJ*@yD!uRpdHRjk@lcWdJC!uV:6*
=@dlNB R#+C<l?bLpCc8Nmq86c1V\uAbc5EJCamP=JQ=W1*<!R!d1XYCcVH<6HS6#AN*>:5E4MP6HT/TE1!k/:c
LHc:<H JE8V%6CLmF@nbppAtE?C=/8@=N@:\8pW+Xay+uZYMVcKmh+R*qFBn>>#JXYcVRBq!!AATWnECdh>A@t+
1S*XuH pKW9WyI:#PSJm*##IPC*yneT*q<A$G5E&X:AGB&?RJLc#!JI1+SL69\Jn9Dei*YeLeD^:HBXQ@H/&5nj
?LL%V? 1?ypjwk/KiLD8WWqXPLnK?+wjF%dZ6#+DaqmV!@Rd?JRk1a4I5a1MWwQJLpI?J/\BWV=GF*MMSB*PNNq
hT/1n8 YGFyEKVlI4KwVM#P!WpujI18B<j$EjI<TCPmFhW89YIB51<JXKumWnWaLWb$A^?+PSDc+R=P966C:WJe
\K^@eZ 6d6X8qEG9RTH&89K<#h8$dF4BRAnQkm>wCIVdXC6@hpAXL<t8FWPT$=/k^A9#&nuLC^i6t^ktw6Bb^VR
XG>@KW +e%uXjXPAJ9$h%^?ep8Fp68J^M^MGZ+4bK6j6HDN:TeTP\kaFQ6T8Y6cTJ>uA$G>u>WiH>dk*Zu^>JbS
cByFVC S5#ulwe4Z>$P<DWaBk^YtR*cLEtdX>Xi!=JPk\V4?LaH&J:FC!t$GpSFbXl^9S@n+PWQ9SN1P4MJihLC
HE<LK5 >$wWQVNS@/#LZN&K!#bP:mh+b^ilqP8SLA&&<:l4V$bchdbheejZP$jM^\di%+*1/ach%Y$>8Q9/#?T&
=QLtP* Zil#C^haDPWJ=R6Ad<@G4T\I+:+\FeabH?ujyYeS<u:KSt>:=wi&wDX!aGmQZhI8c/8^*K%NaQcN6Gw4
pw*nN> :4!6$bCADYli8TW@lEc??4K^Kqmd8uAKN6%\%ND/t/<JZtPjZZB4P?MciCV:mpGlbBLmjN?:=d/Jy@u%
<@P5j8 <ZACcQNQ&X5Z6WW$HE*46m66FjRWWWnS!8#%/Ik!N=N#nI1eX&&D%^Liut>=&c$Nm<Lq&J>Jc/InSFq4
*tMhQK ylnc1IWWu$94dR:tmhLd/pY:lAy9\PVI@SupDtDyR*ku>baNaiik6WEVH!#NkbkJ^81L#9yQG4\=iX$5
8WwdH# q/N!?u8Jb5Kqnk>NKFYeTcZ@HWS%ddk/V#<Tuw?JHL@C&+#Y1@8?%hyM&JQ6Pcm+WqInahqZyE*j>ctP
NVSBWc EbljhLFQ^NaGw@FjktTS8\e/ueEXCa@P=n$e&pL@FGD^+bwDPKaKZR8cCcbmY*hGK>c9cBY4nlwF1!F#
&AjKV& XmYR=SdwH6ttPJtmanF&X#uNQS5iM9bcW^qe&qeDyHMQdJ$YnQpD!I$NunWQ5=KQb<TPZatk/:Ftc%bW
JRtte= 14I*lytbd/P9i>^Xt4%%h?Ny&Wdb:D/>qc5uKu&DnD\9=h94Bb*!6WYe/5+uX1^?5*@%T>dcM#51b^XL
<H*CMQ w59IVW61Dep@B*yi4#C=yG$#E44ZH\B#D8ajjGy?5FypNYG?Xh&5A%FhMe@F=:*in>Lb%#Y1e9I/wKwN
bBe4J# Z</H:e5Fc@#jj?Gy#\4K@FDMNW&&l9Mp4w9B<!9t@yw1EeP%&aa!a>ec=QD4:thq%*HEjHb&L5!h8>JI
WFcd$^ 8kiyH:t%F4y!YF1lc9kbpl?c*?Bk9G6F#!/?euumwbjW5hL^Kwa^kq+S>HHQmD9I?5emBKdjw*<$:uLY
4p6QI1 D9V<8LP%:9!MCWAW41H9Jcui:j#iPik*$Xp=&*%Ey6h8Z:=\Ce:61IFe@k\bqmqbc*BYRN$qAEK>1p+y
=yn=QW #cyp^JESuLiA<DYmHDBCkD&JPNH<=lytE$tep\SR\pQwMVPw^^$bk9\b4W8%ENInRdQ/5:l+IV9edQn>
L4!eed VdQ1eePD$ZbR&MeX=1$M@b&L*SMGnXE/$La+LchL^FHWu&=Q15PNFN@HBp9N!pK+XKB8L%c&SNbt>JjB
=P^CJc \M*iI@&Z<N#AZkDIk+NXZ$n4=<^Q5L%?MXAVNkNZZpkWkSal!+$\wDQn#%1C$ek=HRnI#6*hW?&l^GuA
YlQ*pY l%/:XA5MuC>Qa%FCqy=\q:Pq=B5^bLaaaeRiB*l>hXp<?+N@V8VC$jp!CQM%ja?#5!p$Q^\J^tqwDWnN
jph@$P M*6Q/VLB&@nJbAm#+@j:SBXdjqkZK1=:mFDM?EC$9DFByhGERi1G19jVeaGL<6<4laJ5cquBHN9uMy9!
<\a*:l I:kRG?@9/WWa@G/9y8#GCya<paIWB1JPdm4qZ<K%&pE$iW9Pq=Yi/Lu=dXy%!dbQ*pN16X&Q:9n:t?dw
XhE:h! ?\Vm5WDduju#Sw>SAP1VaJ?AdYaSNZ*AkG^H=\M\NRC\\VJREPwLeal!ewp5J%1Ju^CDB^l=>N/c=F8R
6b#5%C c^=SAV?IE8<M/^^y!!nNq>k/QX/#8D185teSe?9cd8C!Im1a//e?$EdY=IWcAMBHRDFnXQWibVT<6EiQ
ZRX%jn QJ$=QAERpRQLAHI>?8JRyec%Jjj5a\R&9=b1^\D<VEuANuT9Q$Ycj^+=X:aF18Y1B6B+CNLmll*ktQqE
DGGe*J N5pC=4ybI@N#!C5Tdu59/WlNTR6T1SJmu5X=JkSp1RuyG*6jERPA&8wnAqY9NmQDB$&E/Rn:1>Ti#KeB
M6SjC@ nGy#mj\QjRFty%4QGe<tK4dLA*XEI\\VM#^^*QwJ:cB?6Dp>aPICi9mV<W:dCh%l=WS&K^*GL#S\aSDQ
NFX=j9 E9%V@LE>N\BR>5ywnq1EZbSTl5iYAZZlX?H=hFl81ieRLMNYHNJWpD\hpE?1*1H1wStJilV/cYIA^tNk
-A>GR6 00009b7060e00110333 Page 25 of binaries1.zip
ay>4Yd yeSN/m4J#GHFa:#++#ZT*AW+wJm6@YAbNHdjKFCuwQkd!A:%%knMl&6Se&VbMI%>/tbQ/&a%W?pj+Fnm
&R*WCh ^mdcaID@W5jqX6wYDHP#M=Vq1A>y#lSyLimXn/X1C%+:nY5XFa=NS$GWQYMXdAVX?c=p+ld6TQuq>n6t
/hGyWF !/M$@^/8q5ud6RSZ@I!=N\M$Rd8j@9JTQj4TtiMM!!$nKEh%l4hV8j^FJAPI$Sb@m>icRBA1G$eJIhS>
\uR!Ab Y8@Vh5Ya4YlZt8P%VnecIGYP$YkP:p?CZPhM6Ab/WG$E<6:P?VM$Gd#=1XeIG++h<Y<E$thPPSe#NEb\
RAJ&<C nmn#:@/k#=+#AQky1<kd<k^<dKbp+hG#4NVKjp84IhpqPEDMFAwkCGD5FS#c5%ccH>nDXHI^djKD%dXh
wha?Zw Ge#BVljDu15PLRiS^S#A?E*npdhF1XGMMXj+A??hpQe1:@9jn1e1?54?ZNpXBkkmn?<<9Bh*P+GMLNYH
lT@!yp Gk/#1^a==8PL+bHTRLL&m+<uIyWHVBut6Dh<p<i5Mckj/B%hum>Yk/M<>TFGND:68H8Ayk8Ji:Vc:Ehj
t%NRl5 :HC?i!^Wk#%@8Et@9Ce+#V\*9MbPV$j4:X69ih!/h<d#!&b:*wCDeqiIaAFEqtcdR8a%JHwE:$ATTej@
B$B5mq 6i*:nM%w=PVIue1X%N%Z&tNH5XZI58\n%Y>I9*j=CXPmemhMyhhh9M4BuWi%mk*%CwPiW=#N4R+ZebZ&
d5aL:K A<wDtLpb:8//D+SA%d#?WP%YGV9>AZT^Dqb8t<WH454iY$Y<iFJ@CM:NXXe8:heA8QGI&t8PRwktHCS1
pN85jW Xe&PPTN:dpA%=lN4W1<^BNj4E<*pYG8T6dIYEHGlIdq&%%P6XM/G\Ddhmnk#Lp8j+d#bj>8:\iN1QI+P
Rq9tq$ !F=Mk$*KW&C<PhVAHGw=G<%$Hb4*S/4R&m>&@T:$+Q\QbQpETJa:p%??4HH+bJd/Kc$by/F4$*JeK+KE
+ac\F6 =J5nXGMdTSBNEyW\&8=845KV!p^lij<I5WcD#TmIkcd<A\JpcbI8tA^<kT8p?ww!HQ<Dh8DTEV=Nt?FN
DZ1cwp JB@ZbwdDqY@XXBD$dJ>tiu*V<T=WCGa6#^9C^Y6emRNXKp%twV=kkCS*/bEh>MnjVZndeMnN^aJyQcaZ
n+#pDP n6?uA=dkGdqp?R&ht%>Ikct@=8Zk/&b4=iMMZ4c*9CYYSEN#W#bVZFGKabPJ=qmck@W5Bpe/Dkk&RBYQ
+YT%pX hTHNRN9JNKa=\Q?8Vb=VJ$Q5GN&@>+Ry/d8B@K&/epFj/W%Y=IKpKZyd>Ti6WDQ&byCM&M^n=>QEW&C+
?JTtdY EbAuVHQY+!<>6\#?MunRRKt!/Gk&X/C5B$\AMBiuaGD=W@lb\EnFIM4VEPRdiwwba8@9u=#S1tNIl&AA
d?/AMJ !FCZYKdMGeBJE@*Q:LT5G!FeGAAYE9nXJ6!j^u\GFQ!Pbd#FK?kR+Jw/?jH!D#dBaLkcD=?tDLHCiypy
1X9@LE e+%@d=ASd<K<q*6Bu=t!%EkBM?W1*XR5I?jqpJa6i5\&/AlCq@#K:PtuMD+idQZF<8e^ZD+W:\$j<IXn
Klbu?n hQWWeXF<\Jnd4phGcIBqbHtJAVM%8?P!pWY#1>aXSCAZ4ZJ\Z^>QGSlFpn<IIAaIlbHJ!S>1e<h%!FKp
@qE+*d <#uP:I!%<uiXqWdkQVMY5Am1aC$8DNQF>!N9+>n9Ja:iJ9A8bE5LCEIDkF8<S6RDShd/1QJk@Bd54C?S
VV8<nb /a^WId:\J:Vq^=&jPiiRacDXYXQta?l:H!N@h!R*$q4XHA^<%^lY9W6#l#Q:$Ty?nLJNa&C=5%clnbJK
LT+hYe +Jtd!hW$V!B$KM$EQkRBXwKKPIIkG<d9\\!kNBpGWEc%<eAMuyG5QV8qQwDCMm=B\ZW\!\/eM5Ni&cj?
MEyJKP :ke!6lWyd@Cb=&w@GZiIDNbTJK9NbwiSZlI%j#+hWBqQ5XCKiFNcF+p46Fccp?Zd#R4!$e<?aPRy8p?5
&%TLiS KAQd%BlTb%IjRnPd4HAJ8y%MiqZkyV%8N1Cu4S#>Ta=#X8Wm%kEXA<W\1/QI6G%6Le$D/VdI!68SIDWW
jY5JZI 4Ddq?p?%nBtE41Dmn%H=KWjVuPH9ENm/KXNKl#1nGCcREutSeEWDKKAVBejXTaWw=1IYq*Hb9E&H@>li
*hbAcT :k8?j@c=8BEkn%9Qbum$&pAnD:y#KbhI:1dej*VuDDRb%w/%#eGMBw^NNdq%q\il^qlXb1*M*4!PW<qN
lG#MkZ $iLb+lqwE?WNyMyEV%XN@tBHWPG^k#Q1u*KG6dMQ?TMC$=49:KtHtlEBylii+a$At@RHbkmpL:4<dl^Z
AyF*T& SYTwuF>@l:dbLRQ<%F#QYQ$?a%+9tbGu*=yqwc6H#Sk^ltShXERcY1Xu@L+Aw5V4!NWyI^6>8yX/qEPS
E+<uE\ 1twacIQqT/ED41B1DuZcjIjRAM/9QRbBaLI?%P/bS4eeNA^M5JKZQlcNR?bKph\t8GyKh>Ab*FZ%j=D*
9<@6R9 y%FNyQ*j/F8XtW!EEEKAECylu5MeB4ETywDMp+mAFWAtASFBpXc:EtbEBEZF5SNASEXFSeY^E$SESS5e
t<LV6N EY$NmIw##tnd>9E?=?!>%9+@>@<<>*:&&Y@Pibe*9%yZ%VY9qjZ=B11b8PPSjFWG^!DNWTW!*y#FX?FI
Yl9XGZ TlIQkuDIb#\Wd/S!+5pPtcw@+tT9>FDyZ9=1n54@BqC4p*@i<lnddeI/pX$CIY#dh*=p:RkiQ9b#DAml
XN:A=V BmyIa54Y<6S9RM%=*44IS1D\I5dHFFmVmmHRtQ9TH=<^WP#$/C@HBZnc15N%wNX+iVEhV5dj9GWPj<VY
ba8=I? 5M*=QylneRmtuCS:t8A?&XQp5&y!J\jFYn?>:TN\JcqdYI?*Tp9GZ=9DT^W:&bpC<QlVB*Y=NhyLCE<*
yl@wb* l\KbN*u@VAD$t+qEhMV^&HbIFkWp=ABkQWeJG#whbcAAEjDjPeE/k^SS+CJP?pc5jheNaAXF%8AFyGa1
XX%/+y jA^qyc+ZG>p9H+B<e*NET\hFiFW6h=LHuJCRNN9BDmh>jmWu!4<e/eFYNVCE1SH6c+*chl6I%84Dy=uk
nYT:/i Dd1andj?bnK^HRB+iYkt+>Pau<VH\HA</eJ=Y<&cnC?^jCWblKcT6MFqw4nahe51yyRG+PqIaA6ZWKc4
D^@JeA NapS8LJWT#\Kb>?ml!kmKcSM6*$ZD+Bn#Ip^upb1JQPuKkppyBdW@m*wm>Xljq\A&q$!S>n1bR6WD:HZ
khHwD& J$$Pj<iCa>RJEW9?ujXtRD>t@Rw?VN9!VcLBaq4bItcn:cYEcwp@Si=JZJ>PtDA9T:C6FQlG$KaIm6*$
^hY6@l 4%m:Nqem#PSpdPEh#NmaXP9^whD&qw<=VGC*hi8Ip$G=Ak6KDCPKAYw*?/J>MGJqbylSm^:Cn^^aJeEb
Mc9Vm^ KZduARBh///uZLt8hM^cFcn*8Mn5T1?%P1ll9:?Bk$9TK8<mkVFVQ4DI@Ikhb>bZian:/WGApThj/Y/I
B=uy%j <VHT=1dj/*VHC/qWNj*FwK%/?W=DDDQuq1Ym6&bBnwe&&Fb:%l4hVb4wa/QS&CjZ%\B#X!nV#CEy4e?=
PC\/n+ E8NQu4DQ^!TbKH/4X4p@k%d5>Z=ZC6=my>>j@DRa/%p5cT@YX\*ac8?5wb6YTX!b1BZRiaJwidE>\ItB
iZX*wX MI*pmRdIDWQNGF8:BH<ZN8hHa9EQniB#uc9a=9KCJbQJGEE*d5Hpa:BTIWp!pG#cn?uAV=e@&hb4j9lX
cqY8>L Spmqn84ALmMS#tlbpPdiLnW#W?J8Le8uI6@yBlM?kuLm+a?Y!yF#Ybb6B66NBh%t/&bM6jqpj9t%\p*N
EGR5\F EyEic1jj6Y9JhtP?!6yHMW^G\*ZES@Wt*85Qqy84jAwF^lT^icTJ1iSu9=RNFYpmnpJM*PM=#dL$W<w&
k^tX4@ A^k^RpInKtEm^PRyF4d:NC>HAI4+G%t?jH9ICPqqGq@qS<n<9Y9TS>udbCpZ&1qj<XW46JwdLLpWjJME
PN5keh RK85Q@5V=Yj9VN/jE?DQE*/HNL/?k6%aVDqPNpVTpHmcX$^bPSHlkpMyAZCbCV>%#:MhQji*y4p&bTG6
Q8?Gl? ByAQ@eX/u5#YIAZ5VVet4b@Cy*ida6d1cHE/Yl=VBllc<QD!Maw/t5j*IjJuDNY%<&Ay!K?%dF8<@#EK
kw#Y8k \FtkZGeRj5NTB*Nk*wWuR6*d4<#=cqy=Z@dV4cj/\$#4!t#X?*d\&Ra!G#yR!hWMGYw<>bTt!^hYt<55
#8:hI9 tFCa++B^4tlDyj^SMKcdkCtuV*^t@V!/1Q/&XFpbIl&L4><\@NuI+!NJV!w$KECitH@R8lGDlyt6i9XM
m6B+B4 QNX<>t%5<S61tbV=:wc6BnaZ^=81Z=GlVkdju+N<Z!>LbFB9APlbptcujpajB&Ci4iwmPl+?8e$KAHd@
@c8FHa 96BCS>^lCklMbRV15WRC*mBah5a&qcRQ#ZZXQER^8/qS*>u<MSywRXaj*LTkFkCbIJ?V4wpubmDE%5du
ihWtaS 8=l&t5##:>?RYm@$JnIb5#PR>m@S@WB#/L#ic<c9eK5?<SAAyFCRbh$4EZQ6d54WC%*FwYaAR+KyHCVa
<%RjLI XE*FAFI<@=BV^&+m<+=8jJt958D&ab#q6kZPb<4=!yL:YXqMVT>iJ5EGuDn@?Pi?aP66TkIAX?\*\Y<@
IQe+%\ :?iieWQedpA9!jm^+H:dt9!D=jwd#>5?<b$KlMpViV1!hR<\hQ&$akAabQKmj?YQEMX*eP>Du@tkAHC\
##+!l! ><IZN$\*<@/kH6Kky$T+Gu<C=Gp+hb:8<9VQ%lbc9HtA9@q6nDGGb%itQRFMHNLLP$HP^#<yqp6H8m!W
a+5kL? %ecT\\jYQN+>+Y11HQkmTddF4Ac@dXp!4<n&!ddudc+EWEBd?ypm>u1uBQTSb&8JH@W$u%ce@*5u?/^E
ni:y\c &Z=e5G6u?SkGjKl:+bhTI^bSQwJy!6@h14N4#yA8hBpI?ckn&>5IAaC5=?Q=F&8<:::F/CXK8kqL=#=Z
GdCR%? a6JRlWmF?e9G6mQkM+bbdci&Y9PdHRCTiRadutq:CW4VB?YJiYJZ?kV@a#cP@>8eY&?Q9<QkGEma\=Yw
c/%eD= *dM\Ca:+1pktRkqF9NG?>NY/EAjTReLyP9kK?I4e\1kl*A\IWA6uY<LM>i8DXC<WN<>:t#c!&=e>%atq
X?kn<: H4i@?BkkhcjQb\Pd%:?FHMy#8ZA#eSuK*C?i<%9W5$6\C9eLw?XK%@8^uRp49tYNYP<%Cn!/KcHBcl/e
j1jptW NW#Y^X98t4/^QTE!NY\8qMjilu%Q4\$jY:#F6:IQTJJcP\d6PZ=>c*FH$n+H1%>iuKtTh$T<tHVe8DY^
6ZJ1E\ 48&6P+BG$m<Pc6&aA<>:*#auyL>>b*Fq@=I>G/\=nJK/^1<NkC=y**G*=lN/mCHnY5ER%?KG:FKt*4QG
:c/S9R M\59n6\Lt&SJn/AH9h^@i%q^:?<\^$*9*u?cb&DnL4?b?%9tpQiPP45>4E$BY$^\P<?cd%lyp/F=^%Y?
cBycCh QZMJimMp@Q**AXLHKYGb<M4#9qiHG1=a/BGh@qI$pnLT/Vl!6B@humuih**N6pybJ@Np^Emj=\:#>ne4
/XY*1d N<Qt!ddah/+=6kj&:Dn$D+C9i:FpjWlVm+K5TA1ZXleD4YZWRHY%%5JG/\@?uq@C/L9ee?DKn&:bZ?ja
CH<#mR 8=:JVqh5HGS%dK&66uqKN:aXEHtZ*kNbkV#CpiZ/^KkHYc<ne<yeI=qwWkRGRl4c4e#B%b\dtkGnd+hc
RF8P&= Za5h:DeG968QeAWQXql8hIP#Runaw1iSRY*t>SlT!C1MTa*81h@uRAN%L!cJC4*>Vyk81MY45SP=RcW@
<V8Vhl ihZ\q&bwIl/M?6D^@WMae*N64SNeKp$kjGVtBT18VQ<#q\/>T%wMXhchZdD=/d/uJGP<C>G?9Z@Eu?hL
Cd:\QK /ukTPAaDp8l6Nch/!9SAEh8Ik$i8W<jt^%4D8^=Qc!#E@j&ueaT:C>Ln6qY5meS69kS#ILNMWMJ8?YLS
-A!9Z/ 00096c26ec400110333 Page 26 of binaries1.zip
bFwcB4 uH4hWMI#4W1a4W>%9:S\wKJ=^n5>mkyJCIWX/HQY9Aj#ic/NG:#t!E89*9H$@T$5#>9X4$+LtK$*4&nK
t=cjiR PdSDSVuKI\a6PGwyF+!N?XTpi:y5Q#@BZwX:6DHuEQk1@h^j/h%BQcuLN^b:Q#Vw&Y9iT=T4QmF&^lJS
w&H>J\ =?LG?AeSciIDD$8I8N^>BptRh9jyhXWYyQ+FIH@d&WSi?b$V&?@K1#YHZ>/l@*F>:H*P%id&nuDBwey%
umLRNk K18XJuEnpW:deFGP!#b#u/:e6YmHX?FS<kVG$%G@+98XC5bwtAN%=%M<EpKVL/ni>9KZ9</:jlk1I+Y8
4DCE@W i$Q!&kR>&?/R8y/9:CKdTEm9#44Pqh!cY::#%t@Z95R%KMPdqdP>9kaPN1KhdVCWuF8HdHG6$y=u9i*E
!!*YNk GwAal$Z4*tc@?9kDuwcCKy8emH#bBCQc^p#cPl<jIHRBt5iJlKJm$^ti94:Y*?A*%E<@uT45tYVAtk@i
j/8=Bq SQTYEFXySaP#I%cDVS9PCHIiZj4\14bSRjDh59cNYHy^<b/TRG!^BjbT$n=Kim>$h6KHVkteY$6edRmj
TE#w^i uI6N>=M&XHaRKSn/6kB9Jy+@51^T$&Mpl#86$QZ!QT9delWn&>eCkIq^!\w9a4K#n8W4Y&BEbBHeim&\
Wd>MY\ w+T:Vya?hDH/lNuX=19RBIb#?@8cl8a6=m%dlk$8IT!wQhC:Rt@ekCkC!JQ^>EyXn/B!9MP<9+6cM<Xl
%$<>ME XL^Zm9SKw^X:/$e59q>aM%whyTi5>bVclHNqSkHW%ulCljRYSl/jk$j!n$t%c*RtHS1JT9jy!Tq^#6PY
h1M&JG XB*QPp+hMklC<Yt+>A=DhSiJC6TYa=bqkyY6AIB$cdqCRFi#@!?!buYnd9T9a9tR#<=DKi64GYpdJ^%i
jqBIHu PQREb+VlG&n>TjG/&DYYAN^uRIBmPipecRX@LlpqSXGLSYadqYp$5SRkB>^1^L?#YAi1M%Th4iW%n\<#
YF:6+M e+/h/Iyn6lqCy#EBnCw#KmRCt1qYkX$N#A9SVGI#P%SN\kSXF8thnR:pGQwptM6Sty*+liZC*C?Wb!@1
b+TV:y WIa4<iE&ZV%b4:=<I5i!Yl95PAYD6RKS%XWIc/bSakBGGT?5!Ytu1mEmaeTjlB@b$iXcVA\9*^B5Xncj
S9euiK I6DbYXZ$tZpSiGpp45*ih<MJ^Abc=l/k@eBBCKAt&SIqa##mZmhIVttuabVe94%=j?Xj96?%pqSHmJ=4
b+/ZRF yRb&45=w>bCLP$*=Mi6Jl^neP5G54pdhd#E=+A=A9!Y4dQpW?E><5^1^$q^>&VewuE6+=?AN6?dSYNJ%
H<EZH9 @iyLc?1n5Z6mi?y?VtT5SkMS>npc%Cl@T^#be/H6C:M>dY^>ldV5NquS/:pBMqpW*liqK=cZNCP^y+dY
AVF8d% iRM!hCGGWT#FZ4at1B6MPuy?LZqDY*4$C@6pe@RTj=#\EK>^bBmAS9&9LRpWhE?bXkD%\9w/ZS/pFY*<
<piA4c =X+qZVTZ4dRIwal^Gh8G%=CW1!MiIc9!8\hn=dN#VVTMR+Jt:RQt&>jiXiWX&#JI8nmp\lH%9Ly?8j9P
nj9\$T +XW:@TySJkbE#8!CQ+mPnRCCm\uL?X??#NuP!Bj%T$%\SqeJ<c5#F!$:5jytTX^E/M\lu<HcJ6QuVyH1
D6Et5y %&:dQ1:hi*6FmwE8Q>u=?bw6t::eh#Xa5lVV$:l%iN8Z!L!^T#leEuT*>Xep9GDN*lPi#LEPGIM>YHDR
i?*!Lm M*nZ:S%8cc@DQ^$@unl?>/@qm=ieY>1#ap:IQh@=Yc@@Tn%=$uNm@Jj%D\4YZ#^>+91#Q<68q4&NiHdG
SjKG<Z !&4t##NZj*q:<NGbI:69QFyNFm=h@<?=p&?&@96EME@Sj=C8:PZ!Z>PXQd*@Vd4!9#!4@*>JX&::@:X$
GHkAtK =V:YV56wH@jHlKbp5V5pP@Q1SZZZ%DG1*ah+!iG>MZbDjYG^?y:8R+=LQNYH\>h=il=%@CZ!d8P^F*PM
%+?^+b 1@kN!$KmZmELR>cQ>mS#1:DI&P$#6LIdZ6KJ@GYG*4%XZ6\dd4MD9THaDPh+RqTGh<mNc*pQ##56&^N>
5>WLW^ 6/EB4<<?jQ!+DT5w+hM//+P$Z&\+%SMB=JPNtwn&mLk6e*IZ$pyua/IqE$H#8A5?4#MKGYZ1L<ya#@/#
qA1Iup qZ&^a9?IMh=kVWVpikjcLhdCE\ZuDV*Z>:/eh!/QK^Z+HW/9t^Q+$u%9#5HT&:@dQt#+L186Z4I/=Y:n
>ejMG$ 1=H5!KCwnDT9Kj/BSTc?:IbTS?eD9:l?D6//ci#c:djyn^dM&dKP54QK<Qc$^?RYK%uhnT@6GCQC*e=w
ty9=K1 +*V1P1IlRZ^&YaQnN@>NXl/>n^$?y&$4Y&JM*#c&yHN1Q19#=LGJQe<h<n+GHNt!&PFy$?qu5l%?%>K@
5aI:Ke qd+<h9n>Dp?juLi*?X$H9:Zh6y*K9*Q4nQQ&wM&1F@jV=l#M<jt5bk*8MGm*>VZ5BIW1nDL?jVXadcn9
aqk:B^ $QcL8dFn\b4FPdiM#*b\n9QuLWwP^1JZ#lK<PmwGd669Tn:>8Qj$I+M!a&:C9J9dJI@k/m>:5<e@9!6@
uLNlF! wj=!%QL9l<XyHuZGIcu6L5P@yPut5?d99p4yQQ/c@P^AI?@JumX+>8G#\t<44B?iunbWZ8umM4@B?:5$
FR>61d b/G5%EZ#j9!mY<Lb<5Hld6#LkF?hHXVhIVBtq*:HHH#huQ$iaVQWniHJ>u6!:LwI:R&e*JR*BwcKGu@%
RV9N\# Jp+\*QF1h+>dV&YwPdFC&u\Lk#b<HdddGq^hFY#EjBFPiS:nThGkl5LCXIt<&jHq$N*D&RQhLb5?%Ib@
1:8QMK 6tn%PN$qmF=e&9*^mlQnjhd<FDGcJd!:ye>yG%@qd*N^&BAd:B@FpSnd9>p%y!ww?Tm%jthmw<N\i>D8
T=Jd!9 la?TdGJ$F$eamVyGVew@NeVmXidwNRG!d6H1#uP^8!1I@IZQ8=jt@@qN89unZeQH@+TTdwDT^aJ#Bll*
9AnWSd 88/Vij+n5XMh5u\*S5\XR!?<IJ//Qc4#*BReIE1b86Z1jDR9iN@h/bhVa#bqQS/J+ZYbS9P>T?up!@MP
kZ%IEh GlHPYi&+6Q1yK?YT&/51#dCQ:Bk:/@je49$e6=yXX6/#R#NZnAL/t/8eS^<Nq\d?dY:!^tdyuF<F#=Ni
wqu^Ze *H??a&&edj#&$+V%tV:lY?*:X&E1JQ?wBPedmkI@Sn&:59Ql4M%9\84EIWKWW^j%=K>^dWHS%ewt\+>@
Rik%$l d%Q6hP*T=<:P/%4ewd4>qdDkqE+eVtl9\j1m5lDRN6YFpJ8u&wXZ6y5PBV4l?hEi%4FHh&tWuwVe#5=d
Gtt@=6 @aFX&5i$IL9kuV&5kdQpIlElKHD#>SW$HuS46i^I+!<HLw!qB4kjD/*VtaqP8wVJyT+thE$<E/%5@Wbq
?&PNjN WVPmN8J9GPu:66=Y^Jb8*HB=*%??Nk&Q6l>/PHm9bc@L8Ap<9/9Zd=mXe%^G4a8L%E9$6@5WuL6\*Y?>
Nwae@E ^p=#6m^Pi%a8#dpqYBH5M@*X/4G$Yj@>MS@DEN+88%W%B<w<Cc*T4ydLPR96nQ=&IMjVu!/<hny5ljbT
i5Ah*k V6?iCW\N*9LP5/$#j#Im<qQeV^de&@9B/hV\@j=PjeF$=JN4bleYj>=VuD9Q65y@pjn5$WYc&:@aG:^j
eRZ5*Y N>4&6/4u?M!&ukW4EtJ*$t:jP%D>yQn!d<d:Wk/E=l*<=X/yRej&*8CCyjG5m+SCeZ^NJ?9$#eX4jDh@
Zq>Ae6 ZE^kS=K:Q@at*+96&ZMpt^*?m>Y=$iI##u9p4#NTcqcQ>66h8Hn>kWN*qaekd+FRFnHQ9I/>:%/Bh$iB
!!a>eJ det?!!jLSk8hXl>h/LC6khT>w^NbFFdEQqu%%hI!dqn=+8BD<>449<X&?1^&@W^?hud%Ee4c%P*:Fn6t
&9kS^T J#qTZTTC&IVKw=WJkyeh1%Swd8GYQb5l=A&6Ak<Y5RS>TZ8GiT$FX?%ilqh+N6>%Z$!wZ=dd/mX/i@Dt
<K&wQ> l$4LK+#^P6#Z1<pdZHJq^5nZ%d$b:@e6ykTV*d@<aSTy6lt>&PuAtYN^qewywQy/STm&Qn?<iX<FPc4J
XhVaYt h559##5@9w!Itcn$QHKG5eV?\pjy<Xi9<m=@VG&?bVl18ZyDV@?X4tiqm@HhEqbt:MNn:@KcHj>CQmnY
YJQ56B u?\!e#wYTuyeMd:%<9qFh:\u/H@I6hZe>jdHL&!>PtJ:@+K=VuPHSZaK\C1wTB&mJLJCRJe6:$#@qt$Q
Wd@NTT 5ZGtlG^i68b/Z<LGK+>KVlV8I^/hYX?YM9:HPwW=ZMhe6D*+cNPcZL81>l$JW8uR/qNS^W+^J4%Bq$bD
$*wQK5 >@=TTF8tdn:$JGTF\PF%=edFLh1qccE/Ph5N9Meu:J\/DV8<9#kX$4Iju5=+5Ntm5FX<^m4<%?ZXNLkm
F<D^:D eFYy^=XdS*jhH>mKQH#L$m/jn946YN4=nIPGi%aeSN4dQ##$!d415?H>\TGNJ8R:$9I5=J4h*JNBl#/X
ZVXiN+ 4>l=%iQHtq&yWR5jL:4$T>1<\C6#Wy@e1YQdST*iijyy9cPqwe@P\V?GV#?4A$qQF%VedQ*Cub8e?mq%
AnB&4p ><tlPH:P5RZ<^LNQ:Kmi19Lkk&FL\nu#ZyTd9L9!V<4yY@W:hXQJly$&V?M&BPRh+uS5L4&X?eb/tw4$
Ciw8h% y$WJnn$4!t6*L/AXC=FZRheGdq<W*At&P@a/^!$4iudjqyPL??pBD654ZJeZCh!tmyTl*BTL@CX:y+Pp
:R/Vqb punC+Qbwb9Bl565IP*6QnlS=nw>wiN%RZ#R6YciDdM9*T/9cj&MpClP/e/9qhMKM<Bel@hu/BppRqNbp
Vqc\1w N:Lp4HSGtVLX8uQ@PLL9^n<F4J4K#*i4ct?RJDicjJdd<8/c\$e5ml<MNt+iSqhQC=aXLCT8n@\#=DI%
mLPFXA /Eb8SN1u\bFq</mXnn*ulIWdulWN4Qj4CQ1?uuGJQnI8qH#e%FH>b8<j6Kjjctj!!teTMCP*>c+Nn&<k
VFXCla =<d+HBy\8DbNiDAe*uhJ/q@AidWld%%tThKIaB/q?lhl!>I>S=P#:M+H:eLQtJLiS4+?yCEyu^8?hj?<
6FX!/C >!m>KePRp4\u5+dC!Cbi=8Q*b4Y@QL8<aiPj&pjMylL/#DLnC+SFAZPAb9VN=CQM$?E@LetQblc^t9QK
Lc=5Rl w\Y9Lm^mY^T>\SZqQB?+Q%Q@$K/Kp85u!#6:!mYb?9KdY::Q/RNF8aepTa9Q$m+&66yF44Pji94$EK$!
\?V/q\ j=&D==yS^9dB#&qQiy:mmtnF$M8Ld<:V^klZTLE9B<:TX!icP=$=$y?$iGM!QHdwe5wn/ZnRE%FG=*V1
wtt+*p ^yLnS#$>y9GGS+6/1T=YN^nSnW!*>NtQ4>!D*w%h5/l$qAlPd:BKi@5C!j8V5u>LSYSjnXI=@I1?DT<c
/qb\b6 !P>Jt\ahuucmRWN+l>pLDt8*%!dRLJy?!\%5hen=8CiHMANXY5d\Hk58P#k$c<h?d*6IjV?+#6ZyB9GS
V*\5IG +eHC6PeQKuYpdw8N@*\=+4d+P41*8@X=F\*9@uZjq6V*+/>6ieuhN&$d6H@ETdd9/%1Sc&1=!jWyj64h
dRK=+W ii$lq?Sn?*nZu*#j+h#at#*qj4q?la9&?PW6^W>mY@eY9j@n^IpL:66G^Pd4pG*:m+:q>!<cd96RTF@^
NGW$4Q E1EiRKklK+S^Dc$%j*ndL<E5n6&:+eH/$HP/dl4<ydP1VRQTPLHw\!Y*ZJXZjhm9HeuPt@JPARnlZVI%
*u6Cqj yP#eXZym>jA=G##tWu>=%<:k!kTYbLd<bShhPW^XZ?t9ejJja8iY9TZFuH\?K^6@pdjk?ij#!<WB<N4Q
&pB+wb eI\DNLD*>b>CQA@jhV:wYTH6Ww<1?JPZ=GdA1*ZY%k>DQ>k=&qaE6JTqYq&J:Z<yhR<IJX!d&^Hw\MLR
q5ZpNu P^Tj8<a:&$atk@Mj/L!w6HV+T*plcP>%FG5R>6J8b^R>>k%tt>+>=?9?mcH@mBWQ1Z>M>!qbZkIH/:^c
-An:Xy 00029eadf6600110333 Page 27 of binaries1.zip
1n5dG! u:^GHG:T9PKFd$CLW@%+Z5AhQ?\QMKADDDllWcHwKmYbV$w<L9SYQ=+qaPKytc=+:Wbc?#kJjRnneFdV
YLIb<X tZB@tZY@TFS=P*:1lp%G9il^JREVcbE=HSD+c5:H*?!uQ46Q&/WFF6Xj>DcY*kcJn^#&djqX!m*NtI!J
Vdhh:6 HKRuKNd8uWqEm:Pj^!6ij:b^ju?\VYSSj+#T@#8XaDI@ip6QbhPh+M:c!+&=&yqahEpAQLk?HB>BDk>T
QCXy6N Q8Ee9^F>??/CPM/N$kh6HZ?q+nwWn<e5AtahLB:8EuS6EJ!&j%5yW\+6HL%I^*y/qG+YZj9Vp>:V@WTF
b\SK1@ JKRePH4PaJ>Xn@aThuQJ/RLHBi%GKX*Ppi4@JujcT@l@e?:$9+tc@uq9>jV/Z+/c>94jZh4@CpN:8j^j
n1?TMC nyyPVX5cKA=PK+IZ8?YqLM#I6ktiG=n<4/DeBSq<Qq@1c?tib=u1Q#h>nq*<5wVm\EI:wb%Fkpkk#1YS
?6<WkX =!=jE8@99Fkec&hipF$aalGXaqF1d&WPY<dC\utiT&%5#b&YyDpqY:6dPES/\Auy&eX^XyF\Sp+^*#<!
6>wH^< h/pwJ+yG#wqd/DW9Mt8i\!L*=PL<eH/ydVAT=dAWLqutd^YX8>nL#<=e?9P=e=Q6Ayh:b1XG?C@I6E6\
PH*9<h ew$4EeYFih8FlFuS!E:8$4T<DEj@BREF\jEq+pWm6^LLNJ>qlZ+bEW/&n5Y?e$PnZJFk1b&QycZW>%<l
6E!lAI &GGB#1G?:pmiu!AyY^BmHWanF\c:L9iLe#hQ>:A#Z:yMa4<<NNnGI5<m#M*e5!R5%VF&j1Ip\Mw!4NVj
^4tj+j \6@iLTq4pZjP$mWyITu@C1LPF:pnCdE$<4IF&bIqe!SlKdGb5yAeTTyTtB#5piRXY?4BD$/Ktbi<TLy\
GXC1X1 5ZX?Sl#5+%&cc:M<\D+EZmc$eF5TPVjDMnAu#>/cSydqJm=InZD%F@9NYin9:?<WqX?aa=ieET!%>\?J
FPdK%? 6+8%pHu#e$WBYbIFa1?qPR5D:ALFj4bbTH=mhIJDlt5RQ!#\=&lQR@n=GWubC@tiQ9dt!VLZ#Em*@KR<
Tb#DBT GS!ZqD<uM!%S:BKaGSBVbB/VN5e!T9K#b=Ne5yQtFXutTF^nF#nc^juR!PGqwZPm@Bi/SGXuL*C#pqn+
^H<u&c lj8/?D1EC\5F*w66p\45m<Jnk&%Lk\JqpjcJBiabTXqY9mFFRa5KbR8TBZu89qu8NHL1uAWy/Tt\iGuM
^J@6c> Rm99HEFkYN:e9Qt8EcEPLt/lm>KmM6I#kwMeEQ95=GA96+n5p4TF4k=F&eHBm<JD4hL>pQtieVT!$Jqj
!^<E+G Et*6+YyX+JNq\$>btyc:^MM/^!hhNney%NuY\/<\yDR@&N*L#T5&c+q*:MJET<i$WqtK@<<P5dJipLF<
pKk$Y8 Vn!NHB&WE%n1+?\iI\yLKI%&#9cKFknuFT:\mI%QhE!aL@ZL!$wLVWyG^D=lmW9u&ibbPAeETS%KE!Im
Ll4HC^ Mla:T$6qZn@HShI<$V^@t<DMWmjdELiEya=iL6c=aV:#k6%ea4!<w^\T=5#QEacF&Lk+J:lGyQ<4aN9G
$CpDlI cuH!ZFj:>BDjE6?M8Ru?NLKDh/Fd8F&kXjdTcD8Zpt\*mX?lc<LT<JAm6>SW9+nRPi+&Zt:PTGyMRq^\
e:JjI^ :FLLCIFHYLnQEle*1#CQ?h==Mbdbal4btS@n9TnEYtRXmumEqnnG?Ll:8Ca==@4E#9NK6$m&hdPiL\y\
l#4YCa hbwZ/bpRd!6PV=m#=L?Jt9b!@X>T=EXi@+MmL@L<V^X=$d?Nt9d/H*H#@&jn@k?K9PnjA?Xi:9>B:e@F
$CKZ?l >6@Yi9\H6Y:@Qm:c!@N@Z89^*<Rui*u>#&6h*j?>Z8<q?y@Z@4eC9bj*j@K^@u&54$n+H>S/@j6Gm%#?
:/hjM^ k+@%*$Rkm%#@p$:/d&4@c^V^@:9!@=NA@:@FD#6HRl=Cq@>SwBi=@=<Z/D*@9WD9@S<I>CKQ@/NA:?Ht
p+G>:Y Jj4QBHwTDw5Bpikp4n8YY6$@KSSXB69V/@wu*$tHtd+theG!h%<6/8jyN%@iE%9uq!#tdd/+y?j=/n9b
Fw#by+ *PcIVyi/B:GqD48HF86@djqtFwIFNWBV6APHS5SPj@JylRXMuTw:BHCMQdiwJ!p@Ecy19Jdht%!RiGd^
cGDPcm mV?Z>1WW#9jhM<k%wPA9MKClHE<89cbmEmVXBlQ$/uB6+L>\ikMeQq$N>Ka+p<J6nE/XQK\EPNVkANGd
mP?w/D Jd:mt%F8t<I@h!+:<N8TuP$H@T@M:Z&RZ&w!b?&hhTj8Fu^JIS&M#9E\wd%<LB?cZ8HH&%B#+b$KWEm+
d@pd&P nCGe^JdVKMYAPq+LY:?*#DQS%?qwK@4ImLJlLVpj6jj8/!@j%@///E!?KNGYuN/G5%NARCKyu6yiLei*
@^Hc<d >S!c/heq>VmedGT/*+PR4q:H&4dcSAPFG8=#Y6e@1^bY6w$NED*YQ^D89QlGMJje=:J@mZGI*5:$S=ic
B%=k!< <^edBnM^^m/%MCpb4M<\h#X4cJ5ih69*:n*PlmB5EAl1Xjp4dd%5TZS*$4WZ^q!M8jTY^@1KuAhiXWiG
y<iHF8 K^@NP*J55XjIC?=Jq!nG&Wim\R>uHW$mWWBL18&*iYk9d/@6hAEEZXN5DLc%CNMI1nGZG?ZyuV/X^d$H
RmAD&d I?c8A!DL^9=bK^!wR6?$d<APjb!#Q/^%$GKDa8ddZF4AX#Dlqu%45VMD&u?YT*><C5eBXWaEmZjC/%*b
aL?*<\ +?#/VqLh=+Qhp1aBWSGA\atbX=9lET8V=p!bMbuj5e^5Ti1YH5i=WLPc+Eci%I/DG*G%&*WbmLaqqJty
<5#SEm \t&6Ww*<$N@a$YVth#*mV+\%5^>$C5hbZHc%bGTP^F44b$:+/NLc^*^M@XhYLwQ@cL:%yV41XMw@Y/+4
KQGmE@ \VqS?64ZdKDCEuCQdkFk%LA^pPF1*ynZ85W6dkT6F!XL!%4%!Sebp=S1?XmKXa65YVC4dk>jkKZ^1%5Q
T?+*DG 5@c+SAdWJPiN^XPAcS<h5t4l$@%$5CkJR%peGy<kq!PZnlh^hZG>B66Dp?e#N!i=6ZW@YTZ4/AjVduqn
EiV6Ma y&dVZMD$wn6CcqWhKaEWCKW:wPk:H>$6AX?#mDe8Kyq5m8Y?SjPKquC!I18iHLFa8BX@djIIkG&!m6?k
BjZcDF uCk^Z@uu+e%Q^kW%WGy>bmqR8:ZmH&mthy6:MYpVJp!a8uF!Yjpm\/tlLd15wM6wCMiK+YhA8dCh+Ny+
=BQKj6 /6jnyw4&pWEFKYmpY\i<:\Ay6aaEyM8&tyNtmNW4cL?VhGZdPq8yMJmwEZH@dm*&LZ\Dy>h4BeqX61Sm
F=:4TE +JXNH>nACP4D4WB^KdZ\Fk+<F1hj\VB4KQJ*^VP&/el:dK4AnaeBEy/tTul1MHQD1F/=ZAiwnbS:YTTL
ND=$y@ %VF/YJ9+cw&FwL@m%>wnlW/GAQjMjMThL8mRW:Pu6tIahk&WbMHe+q>A@MlX9DtZ1RP\4AaSBdbjJKuR
PAM1tb l4pF/9GIYBFWwd%nTTkVM6PVCTmk5Ny8d/XkyN!pkY$Ft1S/9ARZQSe1mw<dhcAmcl1=1MX85Ct$+Z%M
ElJB%k c>nRu*mwj<Zmae<Fa4*PV^jGdluLlut%AIjLTAKIGEdWKeD+myZPPjyp:\L\CMP$j!kBp9Em1D$jIVF$
FPe#1y i*6\H$aiHT<ILFL^Xc?e\19VqEFNNIqcm?lwZD&1lpIbeCAFB>P^qVNqYElNcmAiDhTkQcA=c<q/>Bl8
dBWV^e V@ilLbthTjMCJ@A=BXSXIMtq68aRTBk/CtBRe=!<IYbwqE\EG@DX<!FVhyG8*tRPLYctmEea/dY4+ERC
cyp%Rl ENhVM?>*B&!+QpabcHJF=Mm$J#5%nQc%#8Qwt5A#BT%FV%*pTZW/Aw5w14bS:!ynpCn4tp64?t^n5nP%
kBI+w4 P/F^SW^StT%Y/RlMQJBV6TWk$LVHSJt#qFDp#1la&GV!aX6b<<\k4u<&6%p%=Lci$SmP6uI^At=1nd4P
^l!M>K ZNyV4+?bm8<=m8NY9N9Y=lybCaBPBF#VXYB1y\%wa^Ja!*CKHinq!9tiNyWRlR6Kl5L8?^a<DV@TX8L@
>ca8*? =<K/kMJdjXF6YtwI1euCET6ene%AF%RXZdjBRGKmyhS9jihGk\i!4<V$VBM$ynnkA5iHGqCR6FpLiF\m
QRH1Yy TepR\/qPdmFC^T%&58F+XN6nZN?/n4Y5mE5Z96HFcjQ%/>Ei#AmDTtGb+XXcN9LAtI+&/9Z#GX=!FNWj
*X&&c% mJ=mm:5NiD/Zcl=GL&e9P:mCHP$QSpNm8n\LaRK:ZS+uLV&1M?CZ+d5Y48k:#J4k?qc?!\KDleiMNSpt
uLu9dW i6w&Y#Fyy/CCR/w8ItC1ST4c^>WWHRS\^58\XNq1bEGjqSQM&GJa%LKy14ue+\LTmSZ+?iyePmjeqE9D
WLhca= K?=>VWaBw@:bNl\tM^R9>wSk#8GSbBJIPYKmG5lBhhRyFGI4*pJ=nSJbDp@cMJbZ9SQeBm4mMhEdCbSA
H6b$$d #tm1Mqc/HTXaBj@anWG::FF\y\Na6l891nYP^@l\B\X:/bPb8TbFM=TBuFanmFyIPbJ9aAZmKJl5=*q<
mZR1GZ Q%JR#&+VbQm*1yk4innTdRPXPqDBmCRHARcMCT1jMYJ<=pNQhELP&ZnT8/*6H:e$*#6/>L^4!RwAutQw
#ML+\> B=Fh&e*B84E>dEeq!dbSqpcjS\LwdbJ8WM/!B%AGT<pIuGuGtWw\BWdn^S&X<lL9m$qB>F=$+jwd>%dM
jV=5IC E?F%?*6\6CaMiahSP8b!X\qa6N6YDZN%&paY%mA+LBaI*KhlHh*<:md=K4KhNjI4w?R869dpCM/p@*8X
X5QP:B 8jawnnD&CK><lh8DHLyJY+wn=%wEBSjHekb/A6aGIEGX/B5<B5+qYyP\qVKAi/#JVDh=D/S\Rip+$mBW
jGVQiS \jGwK6npAG8#i/iuniyh#9MWM\C&ld8=E6pJaQ4C\kY*I6j^ednK9l\>8MmWMhLIe85b^N4&8XhMjV%Z
K8DCTn 599hnhN^=ia>!b:jcphN^RmC:buBX/<<S\Fuwty/V4N\eiql?>I&dBcih9%SM@y6EX#<iY+*<SL&h\^k
W::IR+ p?VMPGw^*FY4a%C=H*MpB\58T!NKbp9qcmj/+DLE%EeWDd4!<IM&YNLFdmFi&M*PK:HZ8uJqDTDM^cIa
S8Bin= YwiNA&JBXNhTAARWp*V=I1J1#BS6aILSyp1LhSIibtDeZp6*%Ew8ZN?Fi>JBBIR9?Q/t/n+hmESEudlk
GPqMCV p4F/N$uymwYP$9NjkQ\eCdSd&tbM&*CR%LPiyM%nB/WVka>EhAcnSI$lpkt!u+=AL>4ay5/+LLmH$#Ay
uN+RaQ pKF+WG$mhnCAaS%byLF&FtNn#ASY+!eT/ekKmuneCK^X/Z+n!^+!ATRaKViEc#ucGTbE$ke?59em^&DA
B=V@^u ELymI5/m\8N$6S>Z@SAAH6JWk*l^Dk<<\hE?=KkGnbWD9!KALtqekC!kbCRc1ipp5B8A:*CQTHi?#ju$
eI&^>? L8<l:Sq:+PG/%/:JtnaihPKMG1ImV@H:$IXICWp:VhA>!yJNycykAbRE9N6ujPTkMSyEW6HJV$:\6j6%
M/M5%/ qVANmeWX+Cl1CS=IN^Luk?1uP9\5k6aPAJqa8P^mt\<HENP%SZl=K$NG$+Y:9\NyQAR&lN@#=HtGpC6j
jKB=X: CXGPt9Lj<@uc!!SXQ?&1k^WcT\G8GQMSGp\%$akMRT+k\@CWu1\JAqihycj?RXIZ5<T9hG5JIACDMl<1
mBZ$S: *DHDL<SwQA*EAAawcy%$^Ze@FQAd>Ql1DPLJRMJ=&q+iiIkFBZJjnJtnV\%hn>ld44N*:VPE*6wjQi:A
N@:kPh QGL@@1LDSw%><XYH&HPP5hj5n>/**#n1<Q/iW@FNB$qHmK!+:hyHWE+FZhmtpANS=k@K&/m1JLctlAYX
KiQqch /cJFXHk4Te@P5ZDADP^?KkmP^ZVmpZL&SCJdTRJqG@H\CWJVL#CSd>IX=wDRVi!cyPwta*EmRYNnAM%T
-A$pj! 0004b11607d00110333 Page 28 of binaries1.zip
t%bDE5 6D\&YK*jj=:m<k@y\^1T/4*BDIc99WPZa=m!ik\W1A<:+jkq86wjQNmJJ!:Wlip4$BXt@I@G/a$M+JYB
+Y:<CM 8AP4ctGKV:DFYR!a!aFd1e4hV#ChH=ZJDLmiJ>=wIJ/t\Jq/!qph\IGqw8Qp>Wc1aSQFidd5L9^SV?^8
Z:X$lw IC+^E9icmn@!Ji/YplJdTc<^e@IXiKlNX>6JkAeJ!GhnhT%LcWia!CPJG&c$GBc+SRIe$4@C=T6^ZNRV
5bTn5@ 9/TMwYRc<D&J!yZBc1*i#&$Y5nGB/^hDmV#kT%BkA^Y^\@M@e9l4&SmaKy5Z%u5\:GM*jcRiD?bb<!*w
w#J=%^ +kGeDIMBy+*F?#?&CalwGBjPJAMAC?p$/9!SJR:uktR1FA8m/SmwH\hqGm4HTQAbRd<QCd4DSdcV=Y\>
t*/#Vh IEq@IyE/AdAt?tlk6BH$kkLttCF5K@FPp?N#+n/J+#&C+p6D++>H^H?KTjBITClhEI>W5>a:pA/%MY@=
XAKE+a AAA9Ntl!IVKIq^i#1H=a@qE@1Q+Aby^%MNdS?TMb?K!nQe*p%#PkHADyNhRheqA@%bMXEm8iD5DBHH+@
!a:jmD Db*4&u>jq@?AiH9AD1$JW#uy<T$a!$+Zw98JjB^LE$6V:cjAEy1<FwAC/\AMFSqkmRp/Kk5m$MBSdZSF
C@enhu Le/<ccBRp\Fw&qkNt<4DnaFDiKVIBQl84H#Ft:D+&lPVKdlqpwA+AeC/%=>I<pcA:/jH*&51P&$MD%M%
yMRymD ^1d<%tpaa/Ty>+N&p>!1@VXJ:Iu>*AtammVnpB6/YlEh?qa*iehI$<GFj?nLy$*qjVRwBaQkuGA%V:QB
i@/8CY T#JIl$X+&RtnGbc>qt\EDi5mQ/hXGEE&JbijJ9BFDC&pA=\kbndw!8NN?EyAR\dlP<DFFR+kukILciL>
8ubW#k NJS1BL?\k+>m^JAb&tIINPLpiyu#*S$>yW+cc$Qqd1y+tF#1ccIeJp:p/G6kLIkL$Bd%cw8y?P/A*k^D
:w&Zbp nEBQHpbBa\%AEkhmu6H?HHnu>aFC@Pk4K@hYM%YkAhkG\Q/Gtq8ti$bZ6FWC!?#b/AAV?1::Vm4RDlB:
Ah>@YT DpHmJK+a8RhyecwTAI\u!&bc\X+cqE#>Pi5lFq$YblKVJaA1>eYBIHS>P@!WJy6bAQ9l?c*9WRDQ!9><
<knjBP iLG<ijtK1&9K6@1E!B4EL=^\VwMpAGMKaXMu?$qR1<TyhT/Twn9Jw<9PE:SMHcYEB9G\jCcl?4$S>K8y
jF=$+9 Rp&XbiFp$&T^EqT8NqcFE&S5k68DI1RLJ<@EchNIZj+pWG89HGR&jVNYhyw1p+qkIX*CM>IMGC4V5HC>
Y&@9jt A@RRQ#^y!G@VWd@TXTpNWD5>/:X+bi??p%/N/SiZu\mumB^!IT8i86MMcVMcaJkMDyyQjDP\EPDj1FZy
IBVTu9 cZVbSuQ?iRd@nV:kDmE1jXp=IIPdqWyA@MbMjb/8&5:lT@Z4jlDEJ^YP4/!S<:4<X*SI!qZ6@*&CtnwS
epIZ/= ^6aCSQpR%#*jGQptkBVGwG^hlD<F+6LlKRyTVkbLhNW??4K\anmbNjEiD?AkbK&i69y#taqlplq:&+pw
mB#a4L pXWWppkmRt#N:C5pHRBQ/<4WlmCPEX+jLS+*/BCRLqq5uuTk1G=aA5FEiTNLjJR4d8PW%BMlK=daBpDK
h:AX=d 5Tw1Xj+N%DCMJ4aV6D!i8AeAG6=:S*<&V>TDi+*AjAB5+CCDP5yiN?m5H6LIk#1NJuG/#1elyEkHSFkh
Gj9K+Y 9STwFpVhCeBSI<$KM#mjQeF?KeDlEZjt^DSYG<^FB9Z+D1c1HN/y+#9&:6*^>h^?lZmuXV1kdCmjIH*V
X>%nqu uF9$tYe9&$pA#=QRY8KEk\R!\buQ$9ka5Q<5V:tcCmuIWBpV9ENq%+MVHFAy=WHnhJZAGQ/PW<@TkVek
4l=9^C JMXNFLNjpYyXL@R^QCIWV6SRDVE<Gn?eKF6W6ejamBFPBBpENAhW:!jKC8uK/$RqwnhSnahuhRGAAW9M
J&ViTj pGl8VyGi%wtkMcak*^p@F*>NJdQ5ih@p:+*>D<65:kB!pbuVIG?tB+4=dIVmCN+TK9@TGXpk+etaTjjL
I#W@PN *#Beyl4Bd6#QZ*ESElCI$MA#ecaPYkm1h^IBP#aWTbla*!uV/wPDlp11aZuQ5ey*S>M=PlDKuZ<ck*:D
yHhQ9I m\EP&1N4=R<1CHkEITLVD5wyZj+MW%=wjIQNq#jm+HAPIGAmlT^NCp+%41@Kw\QJbI48@mW4N?5mD%P!
N*FHHq &nAtB?cl:wA4jX/qH>?a8/F:1m^!DiLDp^N$%D>MR89L*#VPX@+\Rp@wIP*bp&ey$ABDS6iX9RBpQ<jd
aeh!N@ cV^$Rl>+\AHCKRmL/h8\:m#y=$uTSJXGR>W/!paM&t&RE$a9!BR>AP\%W!^%ulu+\Fk?R6c5%n?&<JTy
ENnH#h \TuQicjTdjV+YaDehCl!pFdbT+bYe&SPDK9tT&@c<Fh@WYB51MkLw6!PJwhM>uQycBeLJim46Rck%tTm
^!DuP* AcMNN=naRpS:9*PZ*uJa19:F^lMiNBVjd*qeRn1%*^y+T6LADNmPA<STRj@BXZF1G<j&%RZ*5RYZpn&J
:MBVh9 +CE#8JPHnypBhBK$Bcip5yT:MbwpQb%CaJhjLqV@h9$LV$Tlw>q6@GC@B#I4R#Bp!Ae:5bGGX8PL/SV+
F8>5!> u@*n?#&=yCD6R!w+>c1jR%J/ikFQDXT#9MDiN4<qk/uH=Z@?wplAHp/ibT84Mbwdymw8E#+lS^GhJ!QA
ZKwHb5 <WITbEjph^Ll?n/+*lnbVXK9CK1?hX5n$SGL6JIB+=tAVG$nZppiWAeT&PJ4P&\eJ*a!kZkpji?pwy<M
B9DRyp F8yHS+!8XV8a6Dli!CFN$HYW1>?pE^kSG@uV^k8SSF%k=ZwNp/MidD:*\lN?cmJ#aMLG:>KNPbMT9K4Z
4J6>yy YPX!m@4/:6&8\&&@VHR<JII5HST%Mt&!Sth\M41J*yt#Ke5Gt=j8@!GSuD6%CS@IBkdP66&8*d6Fn:<C
a&B9np lA+jjQmAZA>n?ATe5kLQHZjmY&G%lK@Kiqy@F^WbNqKipi&?MQ9n+8n=!^<PLH?*=5CkDGeMnLN=u1*\
q!#8Q& cRl?!lM:*i\+>jW*k*jt1i<8I+dRS$:&WYMb@T<BnwV?QAd>?jmjM*>><@++>>pQI<*WY6cJS?i?Zl:G
\HN\JF kG\VAYDMyiQTGcny:6aWqN<$RmKa/AGBk8mlnpSub5PA:F%Td<KL%9WZ&pi>dZCMJ!HXN>4&&K=9MT$K
R>I9Hj /Xn&6YQ*E15h%^@4%@u>YGZ<Y*SGm</4lN/PuVeiN*$4>XjF:I6@5Vu=iN1SGPL8m&HH>EDCS^i/9ihC
jXqXRR n>%:?d$JXW9:^%k&F9V&j9cb+\@j4V1Z>y1%+^1:n6/JbN$1G>TqTRCVt=uLV*jy#S6IQ!Km#nE&!S6i
BybZGL *B/DV%>e/+%uQq8\\Iyy9iq/*5i9c+IQLN^%:XXyc>L/9:JQuC@<58Ywa1nF>?HMT<>DStCj6VPqdPjD
G??bD% qZNX<d?ZqP>KP=t&d*AT?=jy\!>4&&?iiX%!^uH65/5SH@M>H^/i?*61=:ZXj8NLC&??a*<8@*Z8H#j9
+1WQyZ AqadHlA&iPt&c*Bmy&QH<iKiE6=#&*pZlm:D#5i?*?wj:9D<Iyt^\N$:Z@T?S8><$!9SD*ZS>:Dbm:yu
S=mqlS $@/BS#NV1ibH*PPa\e$LZ=wG^Qk8$A5=kq9KpS!%YML6d@/A6^#15h6Mp#BdPu9FG#5PP@keb4/&qC:d
tXp:aW iaa>#GSh+E4jHb61D8$bH9=$cVu4X>i4:#QH?wQnVPIe@uAhQnku/6n:h++Hq/>?=l%/+?Nd<i<jP9#G
6DhVwZ yP:lh!YZYZQMDCLmD^wcS6:18D<94tZA%m9TbW48Qu!dSuNNaAZyJN!P1$1N+jjiDyy:y/jp/<L=Hne9
9k%FH= /QmX4q<Rej#VHM9+5e$FjFdM:d<NyDe?F<#JHw6@>hIG@9VuaZ^H+5YV1TQ&Rdc!i*jtZESGt&u#5l=+
bH:Ki* Xq$1jZDp>8&<NEPQ8c!H<>j5ZZZNpQa/iyHl8iiCS^88bTe5dHZdpaLM^8>h/9AF@@hc4h+lQQ4k!$N?
RP+Mwd ?YQPIW9#bPeVPlt!Xe^QqXP4*DVXW%<V>RwY4%y?41Y:d/&*^d$XHw6&QL$=b%NJTqtu>jwew#*Y8:!<
1WylR! 5hbdu>6HL6!Vi&l6i9jV5p@@:J9$PiT19yhR6Y%Fe4Ly86?i4X!?yH*cq:*8eN:5\>81SjEuLt^@8i4/
H!=+$A 1TM9VhKZHP*!YjFq+>6jQwFyX:jhtYk4uG<%89yb/@uja>+bh=+biHNp:j8B6><T@:1/*N=J&b&ZWtN&
Aq4!Zd 8iD5n?+4%J!5+/j8thJ>S>@<YZn*:1Duwdh>u@#t$qc<?%NRH:mla#TS@eu$>+IHZ$!mM8/WF1>iiT%V
ip9baB y9KBj=P:ZF>NCM\6m1%XF:W@@Y9@:/IDH^:Py$!Y@eNVI>!M/N&?Y/&pIk5GZteA#&tVHbWT&<9Ml4/p
w1hQb& Lu?&:LDSD:Yq//8db^+mF#4tXYJ&#^GH^8DdLA44w1X&&BpMCT5/C6i+#=KQVj=/9S>\1?/ZcuLTPQ!p
JuNA=M XB1Ei1uL!m*k1VJ1V#A:RlTm@:k&9ZK$$S*</Ip/d\F*N^Z6J^S=@#yVNTy^=V#lBXVt$:ddmEdJ8wP6
twSIES +\#b1:lciQ5uk5%FJyTEXJ4Q$APB^+caVIMBVqkYS9khK@i4^VMTVVEwS\hM\SGYecum/BqKV:&q*#dC
SD\&$+ ?^5N*Qum+dt/eLVqJiTMHk!bdyD9=&F6L86iiJBiw*^le8FWLL56yd\cWB+KtI:CbLVa$&IE%Jw84DGt
^H8JRj $pi8#LFTV%@Et<<padVQmNC:lE1G*y>D<!?dTJ9Kj6=4R%F+4ZEqi6H$\t^?qe!KB$?9yE%<#K@uE@k\
6/it^T HAwwkYRhwNEy8HWHl4HS%kn>bl1CQ1BPBP=TnAAWAQHZB%hn5iIdZP5+du*iFc!XLiP+i8k!:Rqe*9mP
JtW\yd V6AI4^u$K<Pyw%hM5W%#8LI^h@!MqE58RuZ#^mkKNAqdHb*QtWCiGlSy<eRtLmihEX\b@a+\Z9K:545l
j=AW1l A?!=9y9a>aQ%iMT!IkanCLKyM8E*5TlFpWT%nhAkudRZK<<WGuVq/qcJ&Iy*R4PA:=:&WP@ThjIZZkTP
Piul/Y \Dmke+j4m/L+y%SJmV:VbkRV!hYa#1E4HeJCXhG8q#lG=1nc4cF=8/mjFM4W4/#GAy9Vh@n%%%tNBhhj
Yl+&yP IL8l4Y5NEGRDXW8PlFEP6Y$wHtk1hHGwXQT?8j\$duNyNt!#qqQ^$jc?5JMdMJ%kJ^>&1G6K\R?imnJR
4MCXm5 G5&6R?u^G4Ycpp=%\lZ#eBnlVW!@^RHF!H=P6TlMQ*&E:bw*Hu>k>iCKVi#Tb1mNXKpt+DYMlXZNX@M9
K=QVMA RpT<Y<j6CuDeWe$b+/8GnVBjEqLcbZw+>ZMP<A:\\<\whdTbD6XCY:$+!JEnd@FR1AaMut*ih?TV=tm$
LT/k%G :>>#:=<Dp#mqCFEiDREmZYM6\K<a8iE9ci$DNWuYyJ+X4HSde:DCkRR$NRaE#6\tm4JtnGA!X!^e#Btp
Sa<BQd pnhAG/$4+XBmDPcj1maTWD*EBSHQm$=d49G*HP?PW4Im%+G\b$BbKkZ!5\idBWT%5wIF\ITch!>IATM*
5\8hHC /HEni\H\BS+RdapCP?baX:VBH@qJBGAkt/L1e%?!IIbWWeK8/PFTRWVw#I>j1mM9J%eYNR#bQZ&#&iV*
*e<npn 54i$=SitA4$\!ni8tttyul\B!A!1C!:Hwu<1$I@G8EWYT@PATwhASSNkC59$>PF#BtP+Il!P+&JpZ89i
uT&15k <Kw!AP/KwM5hX8uIq!+tM#I\ATK!Rt%uZhEW4J9iaAyGN:tkkBELEL1@FbJaGQW+Wj9hnjmPb*+l&w$k
T^YCVt E<&uFu*&lI>XZN%nVlit1HjLp#4\tlL:Pp&6Z=jWCI>y5a5>18Tc%V4TRVmwDwRMCF&4HpeX%VR&?+c5
-A8u$% 000c8d2413c00110333 Page 29 of binaries1.zip
>w#HtK /^HR&qh*/++PeDW=y>kZ+lh5Su5M<N49LLZY9q=Y:^mJZDi%<PQnm+4$WMCbFADaX!KFSDG<R!i>P:8l
hi1c5W YjV#ty5KXwV@9NVN8^hpM>@p*N=iljwFacBXjm5TL!/1Mcyy?%ZH*##Hw\bw+Z/iN5HKY*Qy&puHEPAk
q%FVyD C?MiI%hNGiCut<$Cety4kBVclhw$a!TqX1+B111T+4l1pl?4b>CYGKyH+p<Q$IF\^!yyBW$eu$F8/4YS
c6JdQQ V>i#=4>c?u6Qn/ttLN4RQF>Ad%K/Z\TTPNnXYcB5J!6:=n+dmP+pF5GPk@NLdn%>XDX^\Q!La<nD84K/
#DBQWK LD4plAhdH>HTSRm%8WNZM4%FX>CSYTWiBkcmnVEXuQINVXiCCim&14EwE8Jh!dE/&m#$?*c9Gk+!FVcA
DCuJ>e a*S=nt>6DqVNGeDdLMM!XqZb&FXye?!FSQ^aWTYcD5\EAq$PFYWPtC=9HG!Dk=*\NmtEId5ccVRGnlaA
!9kBE? :CyqpqQVd*LNI*Z8jSeAEBShF?ZP\ST=XhqEK&b\tPqR4JBVMd5Y:NPytMXZJ:E18p/nJJ8cYq8F#V=\
w<AG\< mCFZL/*T%qTSQHE=:9XNj6XVZle1SSjKSAjd:1HVki+mRMFJ4an&4K/6RX9u%c9hK48YXmH=FdPac9We
^/niGI 9Mkju!T8Lk9CVR8\bSpABGFd#VFhEF1&6MbtNXRGXKAWHAMD1A*pR&/wiWl>p/RKVQZkhHuauja>\PlS
h&yF&& :<S!IN#a1mQK^XY\T*WTnIqPB&\+6dNpuNwJtA$tCM$h8?J\/uDMnBqGjSRA=lGuehmSDA!MXQc6^4X8
yEI#Y: AN%>LqpWH%V?mmQ@T6I!K$SbkM*Q\bXNKHiwcKyH$VqwD%TNYGKBwl1dqC16j>Z#q=kSK*BEk8>dJijp
khL^AZ XP\\S6YB\mIAX<dCqkGADdbCKeddqFSIe/1PF6WnKhXq*li*HbjanQX:&&JdE*Gp6Mw^DB=NpA?=a>BI
PK/K:% #LjNqa#F>WY?%c$CHGMS6tk695<Z1!RSynPQFAWRJ\pacJY<N1kT<5Z$iXeN:c9kmMIG81@e/5biGeeJ
AHNlD1 $^XWQ^Tal*bbX:TCAGBHmF=dYSSWLa14E6E16ZwX5CQAec!\wiJc<+n%4/8LnK1%@uIq4WLI^DDK1@1C
pB1AmJ kXwPdyc\b*w9yw^GR8**&kSY1QqEkPSh6BhFVVFAME:L4P\44ZIyQNP<>L^t!9RAZ<Zlwu%#MWYF*hE&
k64umK XWI!19TwV4akIad+eFAi:W?a\XjQBCtW!bi/1pF%P6+t6Wbb4JmN4wLbYC$L&@>ne!C8^ma=FNwAwQNR
LhFhH? \A6V=F:S/k6\+m1d+M1mHG^SKq+dJmeFu!!1^yHH8&c1<RAVQ=biJZLHT:%@L1MKpl+?yd!&#:y/B5A^
Em51aW 1JIZF#GmybW#jEB6luIM<EJlyem1e5mpRy1M+\VWnqk4VBtnBu1nq5^SD@*SIEbqP1cj?*I8SlJ$?l%4
X4$wVH hw=mJ4+1cT*clN$:R/lEI:C8=cReGk$CCP9E<8GN+JBPbbia>KEJ&=Rl:!4B#?Tc1ESXTd>YnFZXDcZ<
u8*6w/ !\W*6RKACGKPZtZ>X%I6mE&K1F#\k/m%qdj8AltP^L=wPaPKF>yXaH9^Iq%kPl\VYBw6BAmAV!^pn\=b
\uXe<t YE96K=L5MhEyRA/SKMXkm54RYSb8cPWNVk*RGl@@JQLYy/nd?PndBnFXMA5Maq9+6VSFy?GX/aT?BXWp
T\^wjL I$Ib441H%Ki6pjj*p54mKtjbqTJRwVcV=#nI:b/T!%^1AGhmZ/pmYq?mQai*IbL:Wm1T>qc$P8I5DlCE
<6HYEb Lww?QCFuda&\qPA:myL!eb\WFLEEymP^$aEabEuX>E1\%cXcLbZDnlXq:6W#Iw\NAw+Ek>IwlbbWNRRV
=dyjnK yZMXedQ+/RTC%AlNI6eAS5Sn8=yRM#ueHXT:>:L>ta5H:Wb41>Hc!C4Get^aWXXbdFWPE#8D1?nCw5CC
KRZJtC CpVQH9JBb=MXNmdELu8\Nlt6ZXp=Y/&RT1yJ<@HSC:FN\dn:b%lqLuJeLhwVAJ+/RymbB#Lm1$WaVG58
nMjeec #mc\c5RKA+k\iVen^nI4THq^bYRki8EFNbjabFShFp95$\X659B1/#adi\ZD1#KJI^iqX>1E:y*^4lw4
C@CiKN ISa^5Jnh&>=Fnl&Qh@$:kTFhT1nqabLmMdM45VNSAIpLnkVJw:N1b5J?$&dn8$Bk>ljk<WNFVpG%!CS^
41qe45 DIi4ZaSKA#GeFa1t%a4niLycS\/IK>WJNVc/46I8dC5Dm:4WX1WD<jNSe5ZNcRBuR/@K1RYcklW#wjnw
HyY6$# enqE?@q\EMyH8+!1Xt<ETDHaYnJGGIJZ<9DK\81i?hXCLww\5TVu!uR%u5Fu:q1ZNHD#\dKWm9=HD+cm
RBhZRX 5FLL/4K=GK%a!QC6uJ$D#B1B1nik&kjWLyGVXkPMSbXF?B46jP^aRWYSXRZmSWAT\59i*JnNSTGMZhM?
4/u9<1 DP!FRVAAJp%i6FCldc!aD5TmMp^4Xt*bQEeltVC$8nIJWHTBmyF+6MkLn@A^<F^$h4/>!AWnEwN1q\yk
Q1L#!P beY$FRlq&RMAY1cdeI1+cQV6I?&^yH8*S=jp6aJc$lkd#*tChTBWA+LKMZ%<ppW5AGCGatytVHARn<mS
l#D&#Z EY$p%$XM#$>:LDndK<6mK>V^em&ASbpplIKFSWBbCZEGSHHdiw1<K^lCHPIm#!uAn6EXI@dawYYk$w5@
/5Y+Dd Y+%XL!TI/NXD1dlYC8:k^61ehKJN6P8Eb<yC&5HWH$*T/P4YjRCHlpQF%Vb/AB\kj?yMRD!4y6$ISY/K
14h<A^ HltRSMVaFILCJG\jyd1JC/n>N5*EwEPpmtkQHBJVPXJV*iiB=WSkYk6J4V^$4A5#BFjd8FhLnRnC#IjS
w#9/5t :M4c>P4wPZIkD8Rp!=N1Mck:WXRGRnX!^AMhmZ=$dh%n/Qh4aXbJu\!9LXmQ/W6RRQZw@h<Wji\ckFaD
cZWQ5l 4!ZW81A&1+DcbRSaRlmbT+nPXmA$MCeDpJaS%hTKlViQB#YTtuAa^ADjYw*hwmJ$bYEE>/4<yXmAXD6V
^@&u&X wPm^4SnmE1j6c=GqetBq6W%alVIhu&MIFtZlt8bnmqde/uGR#?yml%I4$>K&4F*Wc9L/Y5c:tBXu^&b4
%C$W1c =S\PcJ>F!lFnS^bYn*>ZCCN1ey\XI&5X/>IJ5!5J>KLVDEaq!SGahZ!^*5lD8kE*W!V>PaX#+5A?j*Cc
h/q!Vk A\A/&FwdHS58X18QKdK5ELwSlkiP9Bdk*>hY>nqZ=8RVdHT4WD1^n%bbqAqM@EmJZJVkn!SE!uTBFF!T
dy\yk! yAaqBk#6A&\MK>EXFhH^ek/CJmWTp5CKwXWa$ww1WSqiG5kS<WGIlTM=EXAYj1Rej?N/jXMG$BwG\ttk
&>CMcc +um%nY5%KSA5e<JE=?GWMXlT>ItPhaZ:<BteA$qZ=$\@QJiSiQ*<WLXeuj!kN4\TTm+WY&BESnW&VkwS
X/5$d+ Ca^tKYCHcqSYYTVBM4JiSF:Q+@P^cl%eWTSttw5S5T4j:Kj&/FV5<%bwa\tpFZJSRCXE4?nl#j^68DZ^
$$wV*B DHj*Yi4kM\bcWnQN\E\H#8V54ZlclbJT14X^PHSlqVaKN?bI!At:KG5GkFm=$H>=p5+pb^?ahF18LmDp
LK:nEd PJ%R#T$1&#>V6&5*:*#PF/PMkM9wZj%*6i%XD&4q!S+j?qbW?+F#/iiu^AEkI1=Ktc*>*b5N?PCGuP<d
S=X<Ze W6mmhI\/BKh$ID!KeQ%C8ZlT@MJMM9d1JamGaJN\BcSh^K://yp+pK*!@$i5q?TN>kuu/Wc<*JbFHtQ=
hh?=C4 dWX$+cCA4uuZ^>bZnJZXCFjZ%Q/m>1$8X6qZF!$G6C=yyL*X$4%wn*PX%LD+*qaWMMek9Apdui1iL4p/
MCWtT1 C^V1HhhJ99*?u4#L9q/bVbCME&IYeV*hb<*QP5<C?KEk$Cdpiqe6+Pk%%ENBy!Gi<@\!d&@eDLMm:RWA
lIk:E+ LMGnG5J5iCWuh@4y8R%JlnWn61n&DtHn9Sw#1<%:C#cN8I^w#dCwh/W&Z5H\JyV=jSnHkVqlNew5WE*A
QHnNSb E4JSE1cmTEm+=LG=c*FXpVi=^%8S5:4KXtjt6:DTyXqB!y6knyqmhk=Ym+C%\81dJ4PHD:F#KFkpHJk8
!\<5dW WER91adTWYHXy/#GJ5kWQ&wInuq??y%e=y\$e>lwA<RByTWwtu:+pu#YK&\*=KJAp4*K=1P#yP?/b%D\
aIj5H@ ViHTdj4Vh6WS^^Pm9eFcj\BmBj!#LeM@<Q9Tk<jhd=ha*#ciVej%MDC@dmy@i:i$nI5L8%/@>Q1cL+<c
&9EC>Z c@<t@%\Tmujkl:\Wbab4mW>?IM<IR8k=y\6WY>RAtBR%RJSCM1qy4@Y6up6Z@:/$:48%i5&m5&6!u?Bt
*5FtlB R8X@QFj$aVC4Z>VtyCkGYTmWi%:*t!^1h1*l$*?iQbtFASJA\IEmFlu+?Y9ttLYeBa#qMHa4K:teT5Am
GPV4=h !!JwjdB!Swm4%lN5qE+h=dB&^>l6Cy%\*dj/hIdq656YS&*QHyJ=d:qt8ipKH9N4RG9WhH^!+Pu%kZ6m
F?&@MD 5&?iZ8!@I&=:#I9$G*KYt:u=!hCyn*41&1DD>@IH*98W4e<?5TClRZI\6tDi*yR*^>d68jJ8=c:\@X=L
epFaiD du<?<P5=djc^9PQ#DFDNI?F5T5yn@aa4tT+A1J+4eN!Ea?q6Su1jQtwMn1GV*uScSNpQqCb@Aj&cdiT9
kA*A65 X>^jM@m5>M#DyT99@!AT1!=MLm6:5DdEi9PR#bcjd&e:$kl/:>Iq88SN4YkQMY?hhkNYBV*PQ*djeWZb
$bBGdZ Kw9j:q=c<8NSbYd>1Y%V:=QC&jM@jLt$=9iC>yqL9<<\Gj@AVc/^Q>S&XEQCjpa<6KqSwSBRYZ6GeQP4
j/^Hp@ JLqZ\8nYR*5bA#He+DW/F$i@e?14nIw?i$V>MnpL#Nl9NS+eQd8Mi!ut\T4iyaF\BEP\@lm16<Y!:yNk
YA?HHG /%PnRp@5M>XI/e/5uG<TZk&@*>hRFRN^K1ctA/N*/K%L1=<d:chHhB=bb\=1HN^9E1@4^=q+Z&5+??b1
PGXbJC XDV8k=hqRQq\V1n%=dLqA>bqtTpp1&W:^jTkXw6kk1#Jj>X9W*%T@44F+m:d*aMGDyp$Itiw:LKLD6YY
&c5Sy& 5&em:<V6m/*L*DTdZ6HQZn6?+C@S>b8yK^jiKZ&>iGGTS<inSbF%i5XH:ciGJa91umXJap^^1n+>/y/8
ZEF8RL FD@/e>JkTSQ&<6n1iun&@YKMlITaN+pZmkA/XqNL$G@^mEc&qlbjL$TQhK^b??n8D^DXJyq5kkTCVIp6
InA!*6 6iMF#481i44QemQ$:w%My+M@YNRT$9YCDL:8A%^1J%ey<VlmV8?myp6F<SGW@tn%euL@5w/e<#n+/VhN
IuDS<A /i*%*6pu5F?XWje?%cnkE*=j*HPNVXj>>9\!1SkK^neE@6yKBw8q8#G1%yVGCVWtCqVKPMGdbNF#hT8j
*c&t>K SZj1W4Y=iZli6bEIS>ICmVDDYn9p8j/tTY#9wqb4uj/bB*Q%Bp=K44XkhJ6^kabithJI?>4F*yHq/%D^
B\^A1w n%nV!Y*Z+&wWjR1D^p#GhX#n\KuGAlKppnBd^T/S%9IJhWwc?hIC\8K5wbGKZjN>Wyh%Vy>iY#GX8?u\
JZQp:! =5t98?i1y4:=y:^4u/9&jVl*wN$a%Xt*X%yL*c\XZp@kKG&TcLkR4h1y%u!:FLM>i*15hHjGpJBaka*&
nN^hWI piHC%F^/M$?wEipa+nIly:6hH:jQ<!5@:IGDy+%:qN5HFNGP@uP!X4#V@YB8Q%F1n4tB/kS6c\W\JIj%
Gqyca: cDn6MqTEpbeW%!%L<:#A8M#mR^!C5FbZkunk?BdiNT/%?A5AyQPaah/A&Iq16H?RbAa>w1+>4MtPlQyL
!NiBTh HCJ9J4n&k4t*F*@aHd5yu+iFT4\AXuTkiNI6lQGbc>+TS^J9uBPIluP$+bGWumbTAmPbA1N\#W\48dy4
-Ak6q> 0000fc24afd00110333 Page 30 of binaries1.zip
1?TYCW S*tBcd4+FHNtK4qI<hcHPFStV4TIN*cYD*&yCk\Yd495wGMi9$p^Ia$n#DVn&$k^cF8Y/MLRbp:/#6m1
cT8E\5 u4>%A94ESHuJYk^edN>&>6#YG#<RWSFkMbT#N#BnJJV&8LQka19A<:G$#GRE51pe8t1t/S6HRTjB\P\G
FpFb#k hkaHwMbpFXT$4mGII=H4&&::QJNhBqRyGLA*$D<awAETdq1F5MG6quMR#Hyk8i:Ccl+P@Rn1qdW$#KSp
ycj8A* /WnNhtcNCS1QtFq$4N:W9Q>d@iWpjuDHb1:meHJD/%PcZ+6wkRZpQccnGueSe:L\$Mmtcw*@I9ZIy&be
wni5N> NbQb<*RP!d5ML=N44w>ZSd?\iKtD<>!Ih@uwicG%tAiY!DGQyiacD%%Iypb1#NhmmQ9/YJQAiI*Lqcu%
P+>lc4 QR11M#ppNNVI<pCEaYJ<>ap:X%!TD/\*eXF*N=C@Q9WM%t:u<d6IABDN1+aAHud%^l4=hh&L/Z?=bKD+
u6Kec> 8CLAKPm&n%tL\%pe@!*P9t4=\SHQ/*i?Qe<?5Lu6&QQVI?1^w<dNnLeq@iFP^Cajk/1m#!#BLXt:1^Sd
@k@/M& Vj1dq6Gm8!HtLH%#uaeP5Q<!Bh+bhkHNQId4=8C8XMRW:4q>?nwjTl/R?KP%IAQdkcpSJ6I9wlSTiqQk
+Wnam? D8TlB$^ccRJcbNH=leTAuJ&anJKDKKPJG1F&%4Y/<@TPlMAb4L%/pL*^#Q^p*?TbTJKt#G:D9c5l8Rj6
S$Q=5b R\&l5>b@hpmeJhNLVP?\AG!SQQ^Tn4iFMm?uRpkkZGdwelTX6J1Jcb*KwTX+5CPFkF\^j/jha4ST/P19
=bn5?M KZeP=5kIF%w6@@R>9QF>XpRIPB#NiPDP/5@baIKP^Y<aGTBeuCEV\ZEZp=kY:/AtG*I/FhMpVHRPQNKt
8Dwl:Q J?mJ1BhZ&%b*lX*9:%1^dnXklLGyNRd:emqkn>GVBFd@mw1A<jZMG\j>G@yQ&\ej?G/<XuH=:SXbh!XX
Z5YN=\ btWQn+Zl5dlC?yHmWMuaYd\Mt45P/ubWM$1N?VuLc^TB#ukj9FFF=AAN9h>ERNIbGd*l8JFJ*/w$=k%l
#IqTL^ LDYWbHR$=<TG$jGw\Q\XhbYbjk5A^V9GlmM9mPwnj1^%?S6J+n^JkQA=Z<^!$yGS>PHybw1/IS6XwZkJ
ZQhe*D SPcpI/G%w@\t9JSQ/T>cVFWnyA4Q5M5Q#C1LN1$FCACP&XW=u%wW:dl?=M5%1%8/86EY&BB$H>cCTqm9
5bYpK& JiM\DCXG*KNL$I!LLuFp*QcS=a*tiVm\b:plbJQFkAdh$8nX+%EtiTWe6%:*/85*p8aTT^\*n*!VbHM8
j?HmWN H4^W=jJ>LuFYw!@dcWy\qV1F&M>aBHCY%#G!mCG%d^l6a#=W4elKJSPA\l=AD6BNH1FyiwHhdBy<\^Bj
kXWTkP >A:D^!&lMma$jjP4bl=aAHwA!V$EmnNVRMI&KE>u5G5nW<W\JD:Pb\bBbbBaC%XMJNylpFjpnF4!86bA
b=d&?c /KIKk$GHlFk6/wY^QR+w?1\\<4Y?SPGWth>X:ESp*dF9lcQV><**jN?<:q&=<+Zy9&&^aL1AG<Nw^Rcp
wCi5nw GNH9?6jYnG&*cM?Z6e=meNX>#VwXDjaW^uihAEVGGGwkM*81!cEMS!MNuFVVHjHHij?d>?4>@uuF?d1l
*hS6Mu >l5D?ByNQT/REMHV=9!tRCmQkQWBqT>\THyyiykJ$M4YuPnw:/TDYV^NwwH&FmlnpbRykH\II$k$+W9w
TLHR/d eBNGb5HlW*H1TZADcYbtPZHi@uE%KW$?^LqR\wBH/kW+RqW$X/:A<=NNljYRDMiDSV@M<@E1la/AaMm@
mWMY>X \%Qu9a<Ky/LeYiiG4*<$k@cY\NLjAAe?#YpVdYpXhVIicE?*u*l%*@\HBR1*WHXIqb%e>NX4XGuWL#Ga
Iq^E6@ /Mim@TCA\T9*k!lXu*<Z1<T\M!W<hTSNXWKT^=NlK<?tqj4NQq*KqDucG@HcTT@pKPN^QpHd!XWQA*Ki
A+qRE! L6Rc6!jcWD9ClQyBjl=Q*t?5i9P8R&LK1KhyjNlKyQJjj$wdNy9aR>Tda>T<9S+>1we^blMl5\tEbQub
J^N^#n <%&+y>1JwA4d\ei^RIClEylt\kSX6iFimC^:n=5wNEY/QbXl9#*PM>H5N\F/<uY@Wyj?De#kkTN@$*w8
JNA::n $6=>yS:ic9caT4dXaya?JKlaB9\HQE$+DnFmCAJa@YEG&8lEbbKiMy11ciFC+&bKW1EY$JXqYwQVilky
8+*:\Y Z5p$W$/qH6qqFb9%e%<D=FM!e*eYL6qMXWlR\+dmVn&ZTE<XlA>aDcnIQH+%eYau\C@B=6@mIj6JMItA
d\NYa: \GaV4*=V\N?aFPy/R?kG=86S\nV#I4D^Gp*9t^Am&/6*G\ZS8ZAQX4Q:ycdMGHSu!Wh$&5LaE!9KXCnq
aRa>YN 1RJA&BbmqKC1=QHZt5nVCLJ^!\&d:Y@wPPmdP^!>Vh9pTL8l/#4DyL>4A%D&BStZB6+mc<1+RCILjpYH
mRMGFP !XkA6qCNE<RhJEClT<EIkdZMC^b$IIY8>KFKA4Hmen%^Jq9>%EmnJFi<6N1$%d8GDG1dkI%55p\IREWM
pYSDLp PM$RGYFDHT\NnFiY+LD=b8BGWB#Puik!BRPbaIpScw^HB>eCaRR6lNHpW%Y^PG$iX9PAlTF\^SAZ#neC
S9lJp6 6qQqR<>5n>pj%hm@Nui6?e$6#5&S^b/?bY!q=kLw&4>jJdG$ZTTBSA>cm=Z*t+G:>d8T#enlNDHGBFET
lkSaLC =X\e*<d5mS>9I6\a*WPS*?LIEw&qKF*D6BDZ+\GS\RSCq?MIcyq**I:R?C$l\$=AZRNbXp%A9=61?!Cp
FQPX#C DhR$/E^p$64#TNy<a@EJQe$MRWHAm6iCRPKEppDZAGTA1X6wA\AdCh4iZ^wuVhWPSLYRD>yS\SPiw=<e
BeqN#D Yp\qdydmFwQwY>a^?9akXEVBuDi^pLA$:nl64!F55^Ma%=GjBwCBw+JAHj=cZYWpn%?Jk$/#$XwV%iS?
qGKThX nESQ&\WApL/emkM*+nRnymDJRy#F$\yyRD+J8tIEpuZiElT*DcM*8WD^bk6KKVGd4BjwtC?w?IH9@6tu
SNZ+!V I+H<#aq<tKEK^&t@GYmtnhBEDBJ5IWi@R+NEPIitkbkVQ\\uWmkV\VT?PBBNN>Tp/K1DMakhjRKmKAJJ
Nt1?%Z 5uyn<ZiG=1EbMtaM:ha^%\9haycP!<P4VlkL8YTpdAiEWPE6B8C$1Y!Wq+:V$*WH?APWtWN9IAFLNcC4
Dy^+/D 8YMtH6IXJ+Qw>5>65ZVNiRkbI^#Jb$EQeewj=6B/V5<Fl>K>Dy<&=^#j6eCXIqt@Nbi>AXI?JYd6\\h?
EGaW$^ bIlh&RwyY%/a/HJ=aaBR@$W+H!wu>$8wt1M/EmcwLy!STA#=a^SMwI+&u/B\Q^t#Nh*#\>KApn^wtA6y
LL^t?# 9M%Z5J<yIKTQwdt8&*E8RItlm#j1KQj#wZFmQ++w6nFXqS6PdcV$E$CR9p/ha!!9JEneci@::t*b@u#L
Pj>$4c ipjQdeti8$wdj<$6aIMVDEB?mK&q/%Tq8&nJSny1C#GZLH6nJLen\L$/ep<>&RQiBH+b&tEpZ+FX#iA$
aRVi6# L+^ll$%lYSd<KD9wKX5qNWXd/SBJB<T>9Nd\#@Hjw4@IplM*4%u^Y&tycw%ER5>4%NGY5@qDylMV?bJI
wW11T@ I<&5ljKn&XRYH+LaTJcP/uEJNE:q9<EyuZSwtdCKbjaT5&TCdmL8NPG@$6WWM4Yu5cRk&b$9qWuBZkBA
iQE<%$ 4\k#puPIKk881qhFl^pb?dVmSm?k#YSC#iJ@NnW9Ny4Z^AFbJM&R$WRZYeM^X^+t8i8XjFqa/uY9>P:E
A@Mwai /m<bc$V6c+/T!Y$muehlVPW4a&YclawDTLI+!Gqa^mMIELw5ZAh^$FYSnXWQ>Qq5n+t/WFFw+>kdAE4T
KC>l?# A^b+V:wc<%i\=HVMWn?An/G&=>M%hq:IG\/@#R51wcJhFNt$n11jF=Ctw/*%d*&*cb5IIGwB@uIjnC6d
n4kIq1 I/J4j8mDTj4\HXBhA5piuDM9$SQj#@u=FuCk1dIqCHKjw>!N#^KL9S:Zuj^VE4Y4qHG6hME//6jG4?pP
WAyB9I Bww4^6B1RwIWK?@Yu<eA\Jpn@aX$aITNmejLYIaVBNPJy=nHmRtcp&dtqy6P*Y@5:?E4h>PDJaA5*lC=
CF/W?T R+Y9+%ZXDAD!ktc=l=\kGDKG>Q*iYqHWN<LSiwwH6qY$4&=&4>uK$bkFXh5+8%yZyquChC:A6SA#!jBH
iiP8>W N4^cZ%^GtKk$A4aadC&^kCCKtGPyVRE$qcdcdldCwAaP8c54N^*j$HdnR86t@hc^dY*jK61&%?^>@J*G
a!YRS$ Z!%XWYp@X\CE1RendI&YwHRumVpe%WMPMp!H$@TAE9j&YHQ5FIC/4B^:8Y9<:maqtRDRAc$^B6/>S98G
?>FB6u 45^pVKTakTR&PGI+EW=SL64/NWCq=JJWJ:8Xl:ARn+n5ytq=JL/jq\h?t$@X69K/LtPQ64I>dcj=:Sb5
HeiVQj KqJJBH^A&Yp>#Sk&PepFcAMAX:K&kTGSeNTt^&NH6?%ai5^p&V:j=Tj4nEH=D+btP@$aL&Jmy%9Iqu@Q
IQkwZF uwk<@kNeW!V/4:mt!QQj+Jw846:@*<A%VikE^aS/E8jPcdl+aXpQ86DS&$lG!BEQiuA*TIqaj6GXcKkq
=?#4Ey dM@GmeyDe%$1DRaI$$G5jPGGBl\4y8tYtFBJ6&p*!1@M5DiB1>9DN4N!SAiG=ZF\VDBDamjBV<uYl?Hm
iDa*wp V>A8Ztm8jd4*%*PLuEj:Z1$NKDh8PQS$QPj$d#H:@5m:nWcj1Bh!cAQ+AC=$\5dPGC<adS&KZn#cWH&l
b8ca@^ YW\Jhni1y%4QpV/I#uX=:d=NL9+>%5a6b*BqnFk*lMjm>u*LGN1dZnTS&:l>#yG#j+^P9j?eMmG?ENV^
Qy*#8t qD^9n!RiY4eML+bK!$V&P6:>XP8QJ4m?bcc6!Ri*Wyw=Yb<Pp\I\=\?@cCFw>yJtm%WPD9e=iIeDj>qe
eBmDjV ^R@*n%^*$$n/dqZL$HRY!bFV^KJhb@t^hF^5pw$CM>yd&AMbbWP*BnK/L6H^YPXNa/<n<d//ni5@4NV6
%BcZ\5 $?VF9lwEA*aauJ1a%#Hl/jkl@PZFbh^Fik%Pqj6bNQ1T\jj!ih6jAw:!?qHT5Ad:<AJlZ*V^SjH\EnQM
pF\1q5 $cl$QZLA=Z\l*t$!aI%i+&9yE6%/&t\n1=4jFTP=KP9Kb>E@@LZSw<4^YK:#:@9!*y\\4&NSQC#pdRTV
%A$%@? A<?H<w*&^GT\P&??cujmTF/>?lw$M4FpRdD%Njiq=kH9>jM>S&t%F$&HSnpQZE?Ghj9@/hMd6Qd^lhiB
JA*45c mea^CS@RY>Z!n8IZ<:b5m4>DVR#cXVDcM#95&8DWtu/jj8VCb9MH<?%@KSS=:8y%Td+dq@@&iPL6Fb!:
RbGjjb J#pQjH$DdB+<4#4a8#JpjNTSJX#jNNZnFX!!bIFn\PP8m:Ynu!&GYjNqt/yb5e&y:e=?t#Mdhl@i*>Mq
J$DIE4 mQ!$NuYB&&N8&9:LpTLpVh@uP\!n:IJQ^?$IK&=8*6Zk=F9R5DD!i+lqu*^=4Iuu4T!AqcncFJFCiL&+
^/T1ji dq:imn8d\5Q6>\SF6F$y!8QcZhtTNunl/9qeJ%%#A#*hQ:@?YXiR98?VkepJ*?EYphR>mDe819lDd%jn
1Yk/P? ?wA/JH@hL9h4B#j$bbpRDu#?5%XC@ZQ^Tjw$HLPQZBH@=u#@9p>BBy<<4*yhV@nE?9^H@i9IFcQJn1aG
+HEY+E B6dZGnebZJRHnh@A$?+e#w%b$Jeh6E4Q<y?yK5e5%Y=<d/LikZ9i*PNB6F*jk>&%u!8m@5SnB#eZb$d@
A=5^ll nV*5+dy/\%yQk@dG5Zw\$:8AdNC>IaZR58dFma4RK^+dnCD?kQ?H8>6DpuTMk8d$N5$*M:qhhwCke&BI
D<J@ct $Lb:GK?+Qpuc>NVyK??F\QN6NeZ9:9C/Sj1^?XYlt%8X^Xh*KR#5G%hSK+MaN<B=@m8u98=1Z&/AEeMF
-AKI9+ 0007d005b4a00110333 Page 31 of binaries1.zip
ctWPDK QwT^J\Ejw9hWdQeq&Pjc?l:HVX!k+HJ$%@e+8tXkd6T:yT/LlR=Y=K@dYG^G6hq5ZmP<#>\!&y86b^pa
EkDQeT iKt5je6>$Zw>@FK5Y\Hu?5$%lPB:>V%h>*Enj%qtBq<eeB6/T%?Ap%Z51Z^>qlXjLBk>5jb1SEn%&Qdm
NcY*MD mIBMM419D$9I1k+Iy>Sqq@K=IdlQE\MLX%bjLHZ5FPVHL9DHM!QFt4k/P@4qAWT#P+XRVV$/n%5u9Yb5
ndMmtq et^#=!inn:?&hL>!c@9EZDE=uy#dNYG/k!$bu<KMW\@<ZWCen#Ni4F/XF?b?H*h91?QPhMYmt?^5G?Z:
5$VVcP CjP@j9i<eTnHBLuupBH?/@ci!InRAV=X%ZbMy86mdjNy^SIc/$N5=+QHZVPVH>Q$H1RJ!&/i#\*te81D
QLLtJe bjZ<#=K19eVHB6mFm#?>P%qhWtiVjJqR*cQhuqub6nZ*TPCSh?KRJ\&*HyYTSNQ4q<:XX>cM%Th=Vd@b
n!FBMT ejHL$PQjHH:N@um\&DGlb+ui&V?&ZSN$hi*D:Z68/yQWW#y:P>pw8QG%n99Le$GT#qlM^@&m/5Ll!c:K
m@9#wN >DaBNeDZ^dlq<HK\!bPFbdZcN8tw5T46iZ^*/BYd6#54wuQVHEy#q?:1PM8ajl!=4JMi5%HmYJHBjX!?
c!CHFt IVY$tJ!$n$4tNLSVQhQJC$=@@64YY4Jq\&jSYDBFMtq@!9Qc9d$*w/NL^<<hYdi8e?Skb*T4jjk@d5Rj
u>a5#n J^\6iTaXAd>:!E@>itVp\Yd#?::i<VPnje6:nhQe*4nj6Z$YQibD!\+L*nQ1H:ku?\?H6D*djTP55ki@
y48l== K4@wZcmQIY^Lh:WFe9ecJZnIm%n?eIN^\PJB^b:EV&pYy%acjT</5#YTZ4F1a:Gq+?Pap\8^lAdBmy#Q
n1DB/j 8JSY!Z9#<pj!Qe\N<<LtElD:a?nncpQ98M@H:Xt8yu@&%>jFe^:j8+R8+S!M*FCmMuj4/d5n*^l=\WLX
baQSZM bGt=6wRte&uV&&?*/ht6QNymXe#H#Q%@H66X59=H>B:>8YdH>&<Fd^VH?DcVc\QnM4bW:A=jZVd^*5M&
cZtuQq $^AMui!i/hq6Jkl:PjZGKZHy%PmB$y/@66+@wdBb<#D<$#?lY/5>Xu/\4N^i81u^9tq&iMT8K\bNKi&%
ipNSKj ?n5&Hd^M4jFwN4E!@uCk<Q%j4wu?iWb@@l=u&%VJ>Qw&P8?9yZ%BEuVd%=\u6/y<=%XQjQmht9p=>iML
a$M#eG 8a@iQw%?QtZJCyPn:&99P#y8KF*B<@NIXK#&JDciNQ\i1Q4F?/Nh6dSklY9a:#:cpXeLi&yw6W98:$m5
qtq&8c hn989PCGm=$h@VV:/IN*ST&S^*%#nd\/15&McP:J:jq9<L&EqY1diuQ=ppeFmy*T%=&bF#$MiX@Q?=9l
K!IX^A 6wbF:pn^Pi?dpX/$+qae:V94IVGpKHjL?=Dck?cXL5tQHE=b+#!ij9SNKyudQ*6mwW?W5iGP&!?&:Y/=
SpI8l? /DZ<i5ZD#MTqFmiDFMXZY%+bL:+a5>9lETH9SHHPQ/d^=T$>/5:^uik#n9Hw8bey:aeRaW=b$WSuYZ=>
4nwVNa =8iK<BKuN9Qj:cNHLJ+X#4dFe@:+dH%$<MDBNc^ku*Hy!1Yj#m!y9KYIHhm%+bn^a5\:*?Fqk<Q%ZI5L
FbQ=:y C/:>+lDp=&<i6TJy#jliYXhk<R&#ujyJ?hh@m*Z>hQDWlcjaI$^jHQ=5abXFTcq46?4wqh*Me*>6KSA$
?mhb8J Lyq@KP*ltZ9dnG8uL\?eyPJ*Et&i*XdGy*YW%#&<?MecReXYVeA@>K9tY=h6G*t!d9jN\eDp1ILeS@!d
t$BKnp &eD4@LVPbdJjBPG%Y:k*mS:*Y@Lt@>u+!*q6%NP<=tC@:L!y9/d:V5/DQK>G::L\*=u?#XP>Y^S?a96q
Q*aLe+ %lPL*Z?@VE91CN=\8DHEi1%#l@<@GdEhG<wXG%JCKc5LZ<+F*9m5!:WGD=<>6u>FaC/=l/^hH=:=lbn9
aZLqqH id**SGlDD9H<lnhqtyimWV9Y>P9611YHc6+i\?9&bbM@L&%Vl6mGEc*YAHY8*T<XCc<?8n%=?B*Z$By<
w&Vwh/ TJb^llyM^X6*L&\+QYVq9\A1qHjubRTLXA$=Mj8:1j5G^8B>iQ#5$plS1?=JP6&dGu1a4u!Q::p!@b#=
NW*tab SG1#^juEwwDIyZ6hFV$dKM<a>X*j&\8MN&epNRXHLtVM%h&D1+nwqW:Q9I$\dwu^X?>9YLi+I?BNP$Zu
RHXY4? ?/j5#MI5cHL@P#^F8c1k&QIF^=6+/H%8#><B/T8J^WF=Qj86^:!^!8QZJB=Ebee/KCdMaTm:Y^4<9hGq
^*?9e< P49Ll=C@5d%tePt#wd4IS>VS<qi%P@Qi4i$iWIhLZ6*a/^Nccie\=XS6L6#$JI5$m8q+jCntYZZG1=ck
k969D! VHbAXNd9WGFk=9i:WV\CZJ!>tC^>iuSJSy=HM#*ncj/8%!Y#>V69bidEQBE<4m=5ktL@HJ+K^%+ZZLkD
*cTw#D 6a<Lc=^55K^+RcTqwN\S6^=1p#wK51\PL4VCSF6dnFwySm$q!T8QVBI\!hSM*4?E^dbpE91Rn*uAN^?J
@/+ybP &^Mwei&A5kClEm:Y=nquc5tXQItk\:ZC*+jc&jE!iMclLPMya%k:p/$6uKGY1+8^%Q$$<&iE^#WtBqQ1
aBaT8h DWm19iV:@A18hj4*P<FLAK8!tJjp9inW51QnHqB^nHc?Siadm&K&hZ?K@ZSKNe:N1c=!T$DL!S6DIhCX
i#!mQ! ye1m@5dYc&=W4?5&aaiP$Y>c8LaFF>T?\nFQFKRQQu#5j@NthMiH?QG+5Q9QG&<#!m*5#w81NnpXT@bR
hyeB$N e/+T\4PFiGeG***=I15MLkEwhkV!Jeymt+LMFa+j/W@>$K:PSYnS=d*d9HIe9Ib&l9YWik\PyT+@+DPb
cXZeCQ +l#L&qD\ytD\tS>&A*X1+!LF4G?ui\kqRLjY!P*aaSGbyImIB&QDRAut*>=e9Q=9Bl6@@ucHZN\<@n8>
eI#98V $SQ/j!FR@&6/w?l@N=*?1>+wE9%j%S6n=&THyAXu!qIZ&C!NZmcI>%$ettF6NZhlYtSmDP#nF^$FY%mE
n!e\hc 8T$M5A9K!yCtS:nq^Sc:#TqKeR@&ybG#T%I>JeqyC$NmM+M6+II5T?h\?/^+t>LwhKFq@yJ<wahQbFJR
d^=/IL YIdLHEqaewcdSJR%V=kXaSHlFb8XN&?P6dXhBI$5KSDE\PLCpKS+9!CZ^WIZ8>nCVPie8QSMiJq#tK?j
Q@XWba n<R*cEqpwKZh5yKq>ldb9m/J+n!QXPhC:\l^q9ueFH:!jBy=RWcJ9=jAP#X/kW%l:J!<+5TMXFql5Ij9
FQ^D!P py^+jt^<WqbKYpG5le#bJ5btmTA$LSGPhq>5ZSAX6GSS<LJ=YZDe@G\cPe%uYaVXw8XTYcLMNeN#ai=T
I6ethT 6$^Zu>#5XL+\LMSF:Jc/!Ne!cEt<WLA+DZGHq>4\^dbY$5DF4kG8VlHBijql!dp$5wj#uJL\>K^CQ*=B
E^Hami yt>IlPNCaecC&IZ^C$9u^dp:JAcE\SEq4pF<1hm^$Nb^ibLIN!ZH#u^yeXy$WGK1b*!^i%dt9<SCRcp5
Vi9Al6 PTnLZnVQhWF11GhCqL8j4$Ppq#CmKD/ubJt@ha/N4hWmWYcPj/nd9N!+ZFq&jKJh+kLHCM@qXkZT=V:S
T9p<t: NLI+#u#l$wB<h*9H?c+^TR5>p4\K*WXJD1E&<*PDdQ!CHNKhuQMVA*!n@bD=Z6FlCRW=Xu^^/cJ<^GNi
$Zy64+ R8IT%&JjJ^w=*5jYZ9R9:NE?*MQG%!&58NRqTi\X:^:m+?#laDp*NNR:\mFl#kLLtDVjXLekeZ!+M=!A
FJq%KG LA:!DTqcbP$9Zn!utEcYYpR66QH!ppa+=AeuLb!dQm@MymlGpnh@tZ8IiF/AjbKX8jhC/<VF$Y/P*q+!
H$TmYN pZ8!h/L@RtF<t1i@m&YILNJX!1iSE#*eF:lbJpYGlCbGy:qdYPaEFpjNhZS^h%pknZcct:I\!*ZB\pIJ
6@!JTD 9DmlMC<:cYqAcJEk$4HI*D^!u6ZTFQjp=W6hcGS:Z@<It<WB9mXLHayp<?Q6LX!nR:IZ?IVGiBZ/?WmL
Wp>:ul ZPe5!dKdP>jbR?Ji+J$bbi&RpJ%5F^Ch+S#lGdGwMMwl\+NGnuCFde%VBi:JdkqJV6:8F8=iD9ai!^hb
D:pVkT 8Md=#LZ\T+Eqq4BwTa^Z#kJlmIi*l%?PJA1JL5^PtB@uWJK$KC:J&byG6ub\YC\Jha@=&VnQpnDEKYyJ
yd>nuC q1hF6E!!^C+=R=KTK@IZSF9pC?PZY4yEyq8=lKStI#cTE85\j\6@Y>nKcapkm$cPKk:^V*bc+8i\PNBb
@Mk6t^ EmW#V@CJtYM45R=j^y?jK:ZuL%<1t959\hR!jEt?t=<kMTI+=h@4nTL9@^Y>$WQw>q@%Sk?l/*?wN@=9
HWVmyT HN=@Rjc<@$eaWPV>Z+E?:*<9IZ1:@M>4@!Z!@h6c%@?k%9*ja+did9@#Ynh*:*>j/@+j%L4?i/*T&?N@
M:=:4n Z891>h?$&jQ@QD#w>Y@lRcHuj\AQiu9>H?HBu>>d?J@Bk*Rc4pK6FmcFC$!wqRQRP^6*J^N/:eZJy1=d
y<!PSG lZliR?DntH6e@*qGNWPY5c6auR5M=ACK\DdGAeK6wZ6n//am=@68?TQ>&NhZV86DPtJ#+$<9>6\X%SYj
l>\Gp5 q?C#J@Hk@P:EJXASdMGmELBm>R\ccKFQF69@C^/<L%JJ8qyM>9T9eY/Mh44qP:D&L/>Vm>/5QE6:<YHb
&%CFuD :=HLGGlZE5tRTkkR>&lLiD#hYy!A#&pK5>J@JB#dtZKAYHQ/lZ6!58tb%AkYVy*<h?jhkyMQ+kFJe@Tl
\X5DSk uR:5hXWVE?lAyy5^^e99@GJuua+#$#PtJPHPJdt6%hkK&ZuK8jydu##TSD>?8@n5?jmbd*<R@RASlS+T
$#SVl: eATtMI%=8wG@=/C#c!GTkPHQI$=!ZGjPPd9him/PeL8LE+?pM\Wp=dm^Pd=j%CVHa/TN=6Z><d\9E8jM
y6jc1I <PtBh+JRucDchePYFbQIhw=Pj^uHlm^w/4Rn6@W$&6hid<Xb%4Tyn#4m*<W9bEu$VCn/y@cLV8m5R+Ep
8>8ijL y?y?$Xq5q%c$%cF&eua%qVL#HTaynnde>4nYmQkL1icMRc8KhCncqhw8bL4Xt5M*QCmQp&@6wXW\^4&<
$*MpNW +\ya*cE^^RRRZ/8N%Fq*pAS+NYJt<$$\5qK9mJwe@i:ZN!iPi<ViLGHF9leL<?mPnibNV#im+y^yH<YF
6SXKC5 w+/Yw$eZ@:Lw<q9TG#>h<=HQ@446M#>\DJ\PVq!:caIppT9WHRE/>H+e9XFXhydI?LR+=jPD&PXZmRhX
>P8BZT Mkdyct&TnhpF:RkR&B#u<hy6Z5a&\%<iNj*6/hSeYeD8y5E&cTF/E/%q4I*ai+JRmynVc%Nn$jw?nHq\
IVi5Pk N*H>@p!aT?%Tm<I6N@dLui#%eWQj^j1B>$V#>JW^jylN&8h\>Kkq+:4H+&$9P6@9P\%kYGq6wlYKq8WP
&QcRiZ @4F/?9m@*QRp9N@YE91N\5#ZuZ4jCdheEAZGdebLBRq//NZX:Rc!XhFG?84eJAu^F8@+KSVTJEjaAkA!
XaB^H# *?CJQF&<Z1GZtXV^yNYC5/Y1m!i84liJ:N+5:F^hkW?*#ReAeh<JPT6^JBLLjtJV+1Pn:P8R%19jSWw&
:htSp4 +nZF1j1+E*99jY==8HZiHENV$#SGytcFn:#haPwLHtu&TVQ55Jt!hJ>#m@<5!hDQkp\Pip?k!6XjBa8&
*Ephb4 EECFuDaFy<pMuwLy64Yc9m5!=eZLT*EQSqLuQ:lanN1bNI+*=Rhnkp:X+kKEdLK!nEmNLucy14$pn*am
5YP:di \K4%tQ+8b!Q/=ZF^@QD4y6uA+mCSSj&M?+l/Ytlpdu85bRa\q<#wGmy4$>B*mZ4K?%lA1>iP/t$^$>kW
jRQu^t 5N1FYT%KHCFIiy&NIlHkCuekMPiQ:KcL8%He?d$Zb$1N5aG=<NlBk<pB5uFG6D8i$W85:41n>%m$yG/$
-Adujc 000db74485c00110333 Page 32 of binaries1.zip
HTMC\? !HJ#aP:/5AK:R\qqQRt#X+$HSQ1%!\+b+<t16S%Wk/4S:jcEZ\4%Jl/Rj<h^Qyw9Q?PChKiVi$/a!m8Y
R$QkBt AYB*QkXw+#TYyVBXRE1XlI1V*Kyc@?by+N!k!:c%nA8=G1=HWE!nT@A\^SlCbVRbn1LSNlHEM!:4^TA:
u94KpL C$jq>Jjy4qi6\TQ1EE#IiL#F9Tl?LYe9MjABYRj&J\/PEb5Di*>P!*KLHYMQ5JGVkRiiZ@t+1HqCD&WX
?9=*Hp !nXCAIQeh8Hu8=$/NpLH18jRD/ZI1$VQdG+9iTe?LHJWVR&VqNG*>AM+T/uL#yI8REG5KQh&SXGDLS==
?J*j99 JM<AmplCJ=F+?llbQ8T5w/#&Iw!\\aB/A4dylX*1Vk=Yj6&KhRRB/*NMVFTBSVXE+c@pXkMmWyK+D9:w
T:T#uT *Hud\%HST5A%NVG^6h9^FZ/Y4QSM=/Cl^YTpJWbS*ALk$JM5ea+bC%u6In5aFuHE&+%/yB$nB?/R+Fc#
k\WdL9 Y9/kN+A<+RID488Z\dVK/D\C6nY*ebuIFC\?b6t8SNa6m>aN:866n^cYwMKmt>y?p%$5tq/n<9^*kPFy
+9\%Hd $N/\CFeqPXBS=1R4Dp^VmC8<>T#&dNh9jWHt*@EeJJ$GJ^8aAJnwVaL<PRE=Z1jRHLhk^qp!QG#w&NZp
Cb%8BG LBq#+tb!BJW9%:t6h#^/4M:B*MQC*>itkA/1lB$AhMIeI!wtICqLK=46jCXTX8&WA:qS&$ep=LRcQn/L
!Dk1jD WGXy4KDbBb\JPB/ujGyc&bPu1$1^46it&h*6=dA&q^>uIbF??LJt?lMSRF4GN6Ep6XjnM$Ge4Mki#hqI
yk&JX= At=<uanh:qaDER$XPW#TcBIkFpEGE9eI?TWBADQ5>YVSiuXH!K/kEPV^AZL%@1KaT6V$+8YDej8PZMJm
wCGDky yhNmRZeSDlnn\6yM4KDY61:H&K<c<hcHK8G/uu=VIPeDGVPe\Bju8RRP8Sn%J\p\!=mPF<b&<$Dekwc?
CcEHhD G@5:C*c5Wth/Eh/h5B@5c4MEZ48VqY9^ATTLI@PSm81bFR/D$5NM<SRyMiqL%4DieqQ%qDENGjj5B%b!
RKZutE I9Nh!Jw!y4R5$BCeb1QACT+STcSPVm@V+jN+V^mkHn<nau4#^SZH\*V%/q9t1DWAtTE>VXMNRdnwYDAI
L%b9Yd tPCljw=E>IbS<L%eAbBbWBQN5A1c6mZC?e=++i+=IK1W1LqBSPX*pb##KyBe8Dd@De%uZt?dlcBXD#?c
MYWPmd b+EZQcNi#cpp85TTNYMih$E1SJ$b=+yd$\n6lN>AedllJXV<JKZdqSmbi4X!&pJZ*PPyI=VwE48Td<V=
L\6=qk AY&CT8+Ft&S!Sw<whe*8iRS+NY=m^4EKCdMi$Pc^bVqJClWJE\VeN*\<b1e4&&mMS\b%LiL%=imA&RCn
Lj/J<d ^SA@G$qJ>e:Qaa@Pq^8+pX+p6+WqLRjSHlbthMRJ4^/u!u11DmuL\BDAuAl*K#C@%PMqTei\n<?YW=1T
jlQVV8 AZmp\DDkkX9>/dQ+\PnjVCjkdM!C#XZGI?5JuNtP1yFkI\Y1JdRJwc1t4L<AWnAq9eXJeaSFAbwAQSlH
Ma#8IY @np@8jLcQ$B=9Gkh4LDH1hMJ5qy/dhVBV^iqcZ<6!k?wX%ZT<WC^uid:@HVZXmJcbpXR>lW&JM+54FV4
TTWMWl ttyRk<1bIYGk8kwnFydZNL&u!X?R^VhM\NW5%BMR:?hwFdb\JFd:FKQ<HAPhMII+F@I:9XHkVcW@keRB
I8KqWX hekY\Ft>jkJ8Stwmi<lTMLERp\K&/tpGeiJyWQ*SBNqIAmW<eTMN<mFytBlEcIk<aEC*TGA5BdW^A#j!
uSS9Bn ^PW5Za:&=Rq48VFd*MFF4RSmBaY@Be?9^%=b#hC<N*%TnJ*IacJJPpkDVpQ@hWM=AI\d91#ZS&aycp<M
wFHbP4 Yw8S5aqkC/8h\JEu+/D<Y=M5H1Nay/:ZB^\^jZ!cn&=lPtq6\EPt1um5yq5jcKT4DwG\XF?4MJYQW?EB
dK?%GK HLDj\G4!EnuybD9bJFhIBQ5kPW\TS=6ESD>4jM!YwMDVF6JEtq#?<SPtBbBF&9I=bpm$6/dcCBRa<*F5
QSci@Z XSyQ@JEKDVHSMIb<F1Qt@XBL1h46ytLIMCyhb&LIYM:nmP5y/R&t\A8/ckH**ZYD=y8tMZhNn>\%nduQ
ZQKwyi $*6pPn4Ke:tPtib^J61w@EAdhV=bE&$t*+?F!4nIb\I$VpYXND/PlGC\KI+D=XGWjVyAH%G:qwGt/NF9
BW4bjT GAL=JPXck9\BZVcJc?9RR\?BD5q&Lnk=@N%M4+\9//aEV=E$Tpj$BAq=#=!IJClb*IpHB8BPjZup#^*K
#Z%pMG XNHIjy6GSacIGk=u+k1I>l4!BTdK5Awak=eVCLI\Mw!ncBtk9JW=+8TN&uE5lp%#PL\kkRXwRiquMtBE
w=#E&1 MCp$%DIBwMEM<wHiTutcikb//:dG#k1Kyp<WE5A!Qjq=1*+TXq#1/tdy86#Y>bmn/\eZX@FGDwuFAah\
8BQPC# @RSDTnqBuwNX$kp1BFDqG+ImEEcPc<<TNapEdSNJFR?w6^mEKVFACXE48mwlEChPPjTuAiJT5$qhQ9DF
#d8H<m i@p&:&Nd&FKP5VlHJ>*CEJ+$%9m9RRG<?5adCpKdaGQW*@Vq5RckBW*LMaD!>cEeCDG#^PD$qG>I/qwi
MkKNpC RDAXm*lIj4F1@>cJSy/5$yGj^+P9/+NJNeAJ1W9/nlL&11qkwpacX#\tS%kM@p=MyA&E6N%6w#QBuVbw
<C#DK8 p/t&$p#8:NJQIQB6/PJcp9#u@wIDA<lEKJ$6D6G=@wT54/SR@CHNCy=64C=5dKAywW!<+TGbi8Kl+%wS
q+%Y$\ WY8FS\W56DyYkDPAjwBmDqMVh5Sc!NbP/XWRkFGPwMY1%ccdDi&eSNp+XR>FVaDEEqN6!n$BqbJJB+DX
5Tqc^1 P4IZPlQ>@8y\E:mNDXV:Ap>^<B8<5qX*JByCZ5\mAAtNN=VB?5A\Xe*6WFBbtmKi55hEP+Lu%^1mJ+#X
^YIGJu j+1IV=X&wM=4ES@^DNBY!tWhGQpIXyZDFY>pI/j:8w5M*k*bcAE!9<WP!nQR?6YqN^1mIq6k!FDTa5B@
BGGV*j TBme%qNNMc:Q<JF\HZWdK:$BK@du!emG@CE5$55S@mAlb#GH!#DKl#dcJEd:/mcXFK<J\+y^4I*JA9XD
ibNHV/ PpJ#F+8M\T^dtI4hAmKiiIT@D/6cbwlGE/EmLQRwaGIGD\@4c%?\IAIL*G+AnwF<km:wccap$XXnZPWM
CkJH?1 C$=mK5tGeBpS<HDWmk!XbEL+Sl5%RILd>CAMF$E9GZV^qPPa?9Na8NaIcI?VZ<G@9^/^&ApV/E<dauQ:
Ay461d CSnE%XAnyGqehVR:!ikDAj4RVB+8qQ&K^>kaNN+SkJHkBdIP$C+?at!NS81%$:u!JwPDSRI\HqTG/W+W
Hi1yu6 pjt8hDTSyDGtcD@m?!X+6IPqwVMtGCV6ZT?q^cynp@4mTc+5tTtdbeNpA$$iBuSmiaRLZNP+TwI9lq<A
m*wAnK >BqA%E&A$kn5%?XQ/5l*a6X?St4WEQuPkSI#^BjM=NWabTWAuCekKFZ=kK4N$y@QlVSMW*=uGt^MW6NJ
Pw1$E# <BTYeJTF9I^ZjDeR9#CXNin#CcbZ5$bn55=anyAG48ZY5w^lK\D\%FM:<YWQYMkKI@knKNqw1ntYuL/V
L4JXQG LE/$Fj5RFW%W?LP6&J%C:VSA#^9BVF9\AShMaml:iiI\p6nlX>WJA6lK$>nPL#=lGQ&Dn>IyGmbJ41DK
N%=45i D?twj=l1TdyRFpQ8nyHqaLRPZG$^b&LTH6S!\IZBdT$WDRIAW?TM%Wbcmb+ttcwJ^pK8iPWYEnJGBe&h
KNQ5ZL ap?w+i8i5pw86BQaj\WRC*Z1kCJXRm1EaekJFDF1CPTbIk<NNh>%WXlZta?ZQ#GedGAlA#k?Cw4HeBy^
jMV$kZ a&JnBIKnuNkm@=ic?+C1?1!94RYA@b#Ea8KElT*j*WniwpjA&W+kJ8p6QL:5%%tMLbSCC8<p1b$M6MY5
!w1B9@ 6q8APIpKdVjn=^m15\!WKdyKlT/mNwI&+tT*cHIYBXuNW?eBpFaK&RHmB$V=YuACS%GN/RQuDeSWnLdH
i^WGcq DCcV%WMa8IMNF>1DR*4lc&$$Dny6VhTJKV*\91X!6Rq\YlhSaNFpE\%ActNVpE\m1tAmZLa5VSjCaA/:
6WY=bV E5SYlmkCKq5aE!mw#hVuh=tlSKF&%qBV^QuWTNQta!i?//kl5tQ%?!%uNuVeYt$\aDVNNqMDLLGCLLjR
nnT>KZ $ccD5pc!8l4@bS#TX8QEEEj=HXRhMpE<IpQGDVCFLNXGe\+kXDd1*Lp%@iVujC!lAXjkmT%AHStatCH#
%SSX\8 d%E%TpQpnw/1m%==A!6?wc@tWQt>iPAlW==IpG?=Ktba1Y&\cK@blJM?Wp=SJ?9^?:EVIqD&R??=%D!$
X=S+nW %Ra/1>QGw5m?W>8TYamQ1X#KlM4MNASn&RqI*WwHMM$V*X#$8/E1/mkMAFw1X+a^tpk!L5uD!>^yeC<i
$@6R?& h8K1#+P1iyw5C=RQ<FV^dK&C1d$Pmm<*8?e*jdpkH6nCS@DLIGP=:G!*1ycPuADkeKd/Y1p5l>!&$RVa
uDN**# a+@WM:SDhGWqGS\!XlZym+$#^MW5VI5PRQqX!:YFeA!%+\bqEpMN<@majqtmHkdHp6@C\X!/6yMkK&in
IKLb/@ JSlXu1HG\jDuEWY=$RC^$EZKDiAVS8I5WQQJBD!ayRdwMl8t?Kmlcn6Jci\F8aQKFZkpCcMca$Mq6tKy
lDE+<W wXnKSFEP%G?E8qMWVZ1Wu<9t\>81nYT+ncNk5NV>dH+cNhCBn$VTJ++eXKcV6ecteIj?^ICl@ARH\dH4
L\MhJW D:S9cX+ViG#%EI5N+uRS^mW%&AV&AMCp<cRNPLEVAAlGX@j/R^b$8eBk+4MyewW4&<$EZ8uDknmpmCGG
SDL4Jm cecw/eSc5nlJX?bJAP>\Nji:Vu?J%>a!+Y<+:VluI6$wuW!VG:NWBFQwV:eJCaGQaWBD6PYNytw:PumF
QLb\\8 wSSTWIk1VmS1Ak%Xh+nA6KGT#aTjuBS9j:ZGPQB>K^Ql/G6?/K>DIFWjR#Mc9PeyXb^DXhAB?P4lNmw\
XtaD$b bpEG^pncJBQbC&Pb%FnJwYyL*KEpDJB8Jwh$RIWb9$6H^du5uwJ*i4l#i8Jl>M=!MJA!+M@yM4w8j&MC
a:9KVA *TLC4$ncB/bcP6&bBGp#GekADe^pCPm/<Ii>$M?>yqejP5TVDi9!*HXBJ/=Tak+RhPW4CDILM9!CnA#4
\FMRS= Ru6H6@w?FH\uK+eBIE58LehC/j:1TBN\FqjSRykayMyiGem?GTL9DbYnjLHC\HaYD&+B=TkFmGX6jLnh
Xa$Lcl JiLJ*nak4ehc:KC9bimyA1?KA#F@AhBXKX@qk+GXymwHD5#S%j!>c4EVVuuFRB5LA9FGYqiT1y\4l9FA
ZE68VA Iq$=RphZ+@TQQ>#/?<NjX1=i8Fa@eJlh!/Ej4kZWp@yclCe?c1JXA*KlLV?HBTbT+X+RuiZ!dTk1y4+e
jBtbAK +Ka*W5D@B*6@HybW@:cL\+5bESRWFejAEYie$hVAEYeeI#WDS=#N#K!5FkmI<=CXtSXPbVcbYXqb+XCb
^+9mZ% YctbYZh%w%ubdGZhN6=9#@Q59h@*ijb*:?@**j9>@jeiHIeH8Nc=8Fmj/<Q/4QQpP1>mKBkDKLa4AYYu
lMLcV$ RbI=yBp91$VL&pqMBtdkt<djLt&khAWanFMITawPEuh#M:RTDdwnLSP$=iZcLcdKpDqA@q^bFkGV\$t<
LVed&b LCLERy@d4k9E\lZ%PEBH^Z5K#68^4$MVQ45FMJCTK5E*mhYcEDb?L^pC?cm?ia:kBS#u:D/IbQV^wt=E
$ph/L= I\Nli+VNdEkpXNB1^DbikFV=Qc&dYh4PyNT^=89ZPBaDL8k1!dZCqj4>*=A$PaCHQ#1d1h>ca^nR?\mA
&*YTXL d1^@*6+6+%F=?c9YBSuNm8cZ8aiqG>mRhK/1i88\S9yF%!e@N9Z9=!&b*$k+J%6>jMQtu&ejbJ>:hKL\
-Ak/V# 000d823e21f00110333 Page 33 of binaries1.zip
SHEu\+ +uHw?^!$Jwnd9BWPiQLl:>Dh%LYtluH/8/aX5<#pnXS48DV@$cPa#w^XbiK/VwkPF$HK&/N:=pXIWX@e
CNSqZ< teK4lHuP9YmZGN:e<VQ^Xj/Wh%Ai>i^$/a/&P#ttH>l9N95eWpW+Mw@6DnE*QQDt<%QG/4!y\5?ZLn<@
bS!RcG iiZl8?Ye&IIAdQZ<Hmq+XY\qPuT/8q#6hiID9I$H#p@8D+!Z8<JLPn&=i1n\JRLtPZ%^Xjq<9y5#9GT9
pkkS5L I^QBH:jaRp^*h%H^:y\ywkwF+j$bZ6h<DG4EpqPhFBZ8?CkkdDYuB%Z+!8$%hd$jQHRnMbn&duAWY<h\
d&Q89> :*ZPAXWqld8H1ZHdb8:GQT%8np=%uT<N<4WpSYwFypiWXNK9<Na54lPSKjaippN!VIB8B>8awMwN:#c:
RZmG?R ed4*9Z9w!::uT^w*mu@F%\FHa>!1nnbteGyRHBH@\G\4tF*i&nT696>\RSFHMqZTCCE^Q5:aq%Y<LFe%
bXW^h/ HZShenq^?&*Mw99GyPFF?B^*QL9&#jIV#*K+h?<?kkt/^:*YCC>KMDDPAAtX!a8DquCl/&K^!I@NZc<y
YcL<aj &+8JAY>F!n>GS&hjq8uDSQ*VyZKk5qACSYhBuB\A^#Q:T49jAewyL#&#Ch/Req?%6LL6>w>WdSC=1*h6
ltRdcY S*F+qwhWlaht8jFG$lialFmNyI<Jc@BJTuuwP9Q#^mpuiKh?4AS>&Gw<TGpStke=NNJ<ynGX>/lyX?Jm
PnTdE+ 5k$Aq/8hXZ4P#YiRZt#iV6W:jJdR#45R<THun+&kMWIHMh/?ZaVpcKJ/91WMP15>qiYeF/QC4!G1^SBS
1MwjN$ GPtc+CN?F!SX?:mm1ZDu?h=qPq<bd\k<:%9:ip&ZDQD=YtTk/pX@H1^8M1:PuI&NY*Qi?tE8=Z4P^S4L
8KDb*u WhMYY4c$8t^#K$XdRBnLDZ98Cqlllq/PX%idbLll^JAH%C%:&li@Ki?WCYa!WA1:*e//##><NG5?=EZ*
aHNkTw P#nE:&imDw$d&B<W99u$KqRP<VG1N1JEAXZJCl$ha$yjc/&8#+e6@pyZ^#?tNTEa=%:><yRBlq4e<Di6
*cMV*i Sy8&PANc%FptaCl%A\bwM!5cWAKq?Z*mRa/iZ=&6y6Y<c\p:EDce6$Q9!A<XLS44<K$AF$ASHFeq?$m/
8!ELMi K9$dD?5+KATE>u:$w=bD<P$&ZAADH*?4^4AKE1c6RM%?iJKnpt1\e^F8\iC?Yh9PQ*PbLkIkZClA/hi1
SBd?tw wdkXJtc6n1@&Y#FM/upPAGd1*tlYiY9Pu!%AnBM#!?L*QjYi^NeFFT1lL5Q$<*nDmR&tk*bTKh@A:94i
h\%/:P FRAnGad?eN6Y8uBjuh^ynl5QSCaKKMlEEW++wacbdIdwDhbY+&T@kGHyV=&!H>6WF>>DW?#%mD^/1Etm
n?+pp\ G&/IcaS@81R/8mdMPwKjB=ZVdbZcB@$GGCh&CI^hVQht&/ZcWTR6t/WXn4>M+:5BNWdD?b1$aL64!*\E
WdnuhT 8eHyQGBlIPhkDW!G\*FA:Yw\/y=iC*^4%i!4m/uFehWjSnh4nq8+SE>5&DZl/Ci5?&n>w1Ak4t=c\Cc>
eT&5=/ m:*P+KG>k<MdkGD#MjpYyieR<Zk5hcD#YF:yy:E#FctGlAHDHT5e*ANamhMGN+1YDD=FecyQejS<&Dw1
8GS4ZH TeE=be\u>1B<ubIAHq!@cB<6+Q:CWbbS8BcYy4#^d>%Bt<4\Lt86Lq+t4GTBDe$Z1C6LNVTkSeHike%H
mCZLj5 P!<BS<=a>Tt%JBwQ!AEE4+F<Ddmt$jY$<Pmu!!8nH<:Nh&1:IFA6$uLmL:TT9yFST$MTPG/9ibX$GVI*
SJLmQ8 n1nTC4b4Rt88cB*P^cb*ij\y$AGGq4GCCLwGT6EjF&p\RXm56QhheDJmQCLZKi1^9w1%RhQXD>TT=Yy\
F/NqI9 $AIna^tX$Z1W516P>/p%A!ykj^AmGc<&P\WZj>YL6+JpKk&BVXw$DkHK/h#wQe+yqVeb?=db+mmXFphy
DkAW!Y 9twM\BbyM5K5ypuTZmMTbd5t9&1Su&nAF$jlm8ZXFa&!#<NWQu4DleQ*qX>5ZVSbyJ8LAMS5QqZRl$M9
Y1yXi: yX=WqJ5JMueqZE:tK=*C6\hhZ>RqQuZjnyWj$EZEZniKAcySD<AACIi5%Sb9yWI=StBiTEBD/NZK6S>*
\b#YQN IEu6/wbY+ZHjT@kkWIwu^<hYAFQypL^684L9l5@5jZ:J$j=14Xnjb<HuwSC/d/Ll\y:T8%CCuNYtpTVc
GL5pj4 WNQhnB%etEeP=$GW/nIClLSayhqk#V4FtNpKlaWK!QXT=a15JQV1pd&FTelF416^b#AEHI*qH#jj%Z6w
R%<DhJ #*ciSdXI!%NDSC+Ch4EBHI?6CtH@$EtCu=NP:M$>DAIa:?##XiG9+kS$=SX#\$Fq6BqQiJ::aJH&#hpR
LFiD:% <h1!QuWA@AFSau=YyjY8q^eqLL<J4lEi4l=+GF&c?P1HySlAd#1=SyyWASVy\FkWNSmX4mVZ9AM454nu
PIC*B# p/XbRiHmWjJ!A5m8FdC>6FRdP*TbnE#CKS>ZH$/J9p!&An*Rkq\cMCWqQq=d#\nY>Wd4i\$Z/IQM=SYC
68%6eu Q%Wui@/1#Zh$D^p+jlZye!pe8jlehWC^5^PmmE@K&>>XD4BYDMZHqH>n4^KkL?kbeTQkLa<kemDiINFS
Cm>aLa HW8A$/@K^9AR>!*auph\j&Ah#tnbC1ZIh+L+#XVVp^KXQ?kbw>B$NTFydhqE5+b+SFPq%ThRZM6XlR><
%li4CG 6JFlA6@16<\+Q$jNlDeh*uV::?+9n#+?JC9VWBEJ8k^AT%M%bEPq#Mah6bmnQ&6<V9\lIYRI9bHAuAqW
hk%ceZ wjXCWdR@>TpKJDAAcq\diYLAR:6JF=&XWdYX%wQN1Ymcnjuk+ka$hHLH&>Cl*9hF8pn!G!R+HtH6%>&u
ZN1\lc J9@^6+yCc8VhtAF\&=Gqm*:cw4Tl=a8i4t<Qqm*@4eSanLahLK4??b%/*quqnR>iddFhhdm^S:$>T/PW
DBFaV& Xp##J&YhY/\T!RmA\kncuaSWXJZ$YW4GeRm&Hy!&Cq1dDNBIp5/jXaA?LDAISQ9DF>bB9%wCiE<S?QM<
D^iPXJ 8XdEZXjT/R*L$\dKd!8SIAm<D$^1D1QH\Gui?+4Xi%+HMihZHGJ/p1TPbWWBRnBZkHdXqkE\uuNb*^cH
Gjb9h+ GStK8/&$KBeqw<Cy>udh81YKXiZh5FJ<K>BJRhK>lI%R!eltCXWGYh\P!TPh=l6D?S8RD:I6n\/ihaAK
8baQKt G^FYmlXku!NAt8!8XSh*Y!DGCekmFq!GG:y\@w4qZ:VVT/&/u>8PBVyj@A6<eB6PYTXilEBy#5J^9XI/
Yw6cnI RRJtAA58ID+X%qmNAJTBVl<JS\$8^cQ/p8B>&\E&ZVT8D6V!lh!aptWGmy$5aBtXeC\puXWhCp&lMBNb
Zlh*E^ t+Ra$aX?NStEwGGCZ\m<Qb#pCY@QWKICRKiPlJFb8tBYA4nBGby?ZWuMya*Z<@cBeq*I=qWq*YeEnAka
1X6QT5 G+w1&m\c*c@GpeHRytX>BmZ5N\KGH=JnB*@EFRFbyZ*JIMpDA8qY/qM9=YllkFlJ4YPyRkQGVpVXBmpq
ntW%&^ d:qCbJEa?n$/FPlEnZInBNbNLF&AkENQeY\mk1%XM4NhNAP9:QWdQn%\hnnA58Hkqek9\$i:Ib%&=9Rt
LFIpMn uV^NaIR4!VP4+K4C<Q5E/P*cV*h1<hWFjM4=&u&mQA/pcB?E9pIm\&AAypm1w$XVL!XBqdm/$KXiu?K&
&?1C&W QaABjNGXTLwkKZyVeeP8BMlHWndAYiHGt!WRPk+8W$a5YJV\\\@@&Pu8j6GuInMR:njYjtH+Iqa/ZwBW
mDqI\J wBDTHjT<YqH*Y9TCNZ^^NeAmCDe9%pqD^I$l/HEh%QqyAJ*yB>KE/I*I^kV$nG=y*$4$8HwJtmNA^=X^
K8ZW5# neT$G4BVM:Vk^Y*S\8&Gq:jdZ>*iWmPYRkZj@kVH*!mSAEmuGwTNE4F=I1+NbAc4%4pC?5jQWwaN4FjF
?L!I>H whaGaAWKybpCT/L@?yZZ5*+PA99EiF5l*S@bb!l8/TnBB^8!>+Hyh<X<#%Ic1aS6&=GZJYa$CXmQJJ#M
BEy6n$ *\tMW1kK!H#p!86KjhGk%!b+WbJ+RW@M%RWWhMQ8m#CkaKJDb?KM:5SX9aq:?lPh8V8@Fbw6G=j&+TZy
+KTVLt %^yb/lJP=AW:pln9BDc8lHJ$XBh%V/=9l*CMBK^E5e\ARVp**N\Y@EhGwQ4q5c8$5j$P1<nA>jNTEYtX
hmRQGH kF$E!c5D?4LRC*\a//<1RA?JZ!Yl<W8y1pl?htpnwlTECqky\CMTdH\NqFaq!a5BAYPakt8CZwQwDLH1
\DeqJ> 1\FycqQ@H<cDW\855mIG5w<uXRRm$EdIQ8mI9E/Mn:ht%EGPXybbZpLIqaZ!hTAJLw#/Y<u>%#SSHRVW
H:%:PA VhqGyhKaEu1c1M<$k6PHyMc^Pi1qM<1cM=4RBY<a%>!DA^Y6QLp4E6?cF\LeVaB%=wJeA+HeZ$R&EmY*
n*pBTG S9!+KFpM9N==ZqCpLGAwk!\H+Zm4Dn5E?8pVAJlA8P1\d8Mb64GaGn&#5SVJKSLL+!FFlcX<NqLtWEyK
>jKly9 kC^M#=l5huj+cGS%M>CmC?^iC*i1YdY&N6JIGSa:h%P1m=A:w8l1b@A!wLQIbj!kmMWZ6caJ/F9YLH?A
Np>kp# kE/\w9lTdnCmNkt&mBK9db#acB6kNhbIDaRMlT5*cyiT9Ey4TYBuFt^^LVRwQIAqk^WX\>amK5Cm$wXa
S&uBkF lCIWNyKGI6uF!R4B6^j@pBemw!<JqqNLAF*^bQcN6p@>K@q*hbW\pQ6I?Xb^ymqTARNG\wHYZ#e?$+L:
4\6Z!u d\Nw:At1D*#mNwIVnAITJa<&w5jD\ZkTiy!PyBtYpRJS^F#$Ak:JXWZK<cKFk6ISb%FQ>YNFlG@<*<lP
!BKe\i Mml*EK+@l!RFwQApqNSHCK=FtE^BcNH6SVXmy=i%m&GTlVDW^5TPpnw%4w?\!E\E/pHG5$W$wukeC56d
cSHkWa BX5IFIHMkLj9%DJM>wAR/1^W9KmMqCFKqhaLTYbCE+RE9dp6d$yAy%D#FtG!\NKFaKR$T\AG4u*&BGy^
tqNKEy P@=M@eqGD&R*B#tCquCW+VIEBB<Eq^bByTaCpwe!J<T9d*w1<GTJdD9T&D@T+?bhnj4Xnd!T9NlDSWb\
>l!L+H VlapqEAcb*yXPecd%K%S@qRG1A6>u$DpHlD<DyDMFpn#$R1%9YAhqL=n:ZINlE=A#P\APAnJ6JKmWTX1
^Fc%XV :Ki\p!8kF+wu@AZn4!F>SkJ&RAqRJPSZA=$15KLc*%ieuh$?+1t9/&y4a5n%EK+9NE<%Yq+6b85mwwQL
WS$44a $W/C<h>Lt$T\8^DK>86I>cyXAEmTniYEFFTkRKw@cqi\8Q>QJdS//WKcNdu\Gn>I$yk598!R=Dkdk&j6
GNqXM> =\J\Nkuc:XHc/a%1VBjK%yaC!1K4$ikbLCm9BSBF>j\%+mhlcn@jK>EB?AIN*ypIe8$pSj:\=hAT9m/e
1RDeQF 9lHb8Sb%qk@u&$IdZbBeS?C5+!E/BIdYj*L11%/SEZSbF/wnBkHZ$9GN=<d*mXkdTw?@1uK&j4c\V<SH
4>$I5N A?!C$4/A$qy6yN#wwcT!nL9mRj<6Zp<*XAGFq*eSyMW\El<&5$c<+Aw8t<CwP&AMk%E8eIQ<F1F>uQJG
uw%lPG t#c#6wSdBI$inn%k=G+>XD%nAq?ME*MMT8kFWJ1JkEyBnITJPwQBd4!w+c#t51=a=m*pF&akc\!Z4TFF
jA$6:S q5kFyeApPa/6CV9R4C!6q=CmwbS<8D^IDKwm<:SL!Kdm&l$C/S4\pRwAME+6ACDiGPl&S$yJaJG?*9Q+
\ehIq+ FHtEMKb+ENA$I!QZ#FSBb<mw&pRp8BLXtADlyMGLMp4yBqe=jwpL%RIi#lmACV1NlEB<mYInTpEAqnMd
&CPP4C >>Gjh>jM$?8RJE?AER6n4BKPYEGqKLeF6IVlnEV9KNFAChkiKQtt5F1amLwc%S&1wY+E+CFAHkVwXE1W
-A=S\w 000579bb49300110333 Page 34 of binaries1.zip
mk&NbX &bW8wGDndkmY4=lYAGERETRVMVqP$8$qwjIlW5**!DFIi+a#*1WEHRbnPbaG4BL&SaLWHcZ5%SD=GkGR
$A$m\k C&GdmD5hpeCGEy18kGa4pGt?!Z+C/jdN?n&W!:d\+KG:NnXuc#WlwLya1dtmTA9kYkkcN<JIDl/LHABk
!8&kc1 \8TdSFV>\>RQY8*qaqwkRKJB\TJwpZ$yYp9MwamZHcCNccZ+hBYpV1Kj$hB6*V*CIkqJhheMAC9TAY8V
lj$X4M wdL6An\e&cp>RjIVLmCk@K%aXkB!QAlKY\&4qcHR#Q#DqylFnHk<Da:nH?k#RT^GIVy=MIXh/R/kXMGH
w91eb@ FpElyA#lIkSW<AVLIVapFcmH^ejPji>iZ\JtjByIL5JF$=id:!KZwcKFqT4AQwuPdYBeBjJuMJS88%ht
=dR!JN A/X#RSqQ<Kjq:Ap5ndEP^uAHjpT*AFDJRm^<$X#RmaI$pyEkVe\umBa5wENh/^i>EZpWXC%VSFWBFewT
X**&#E BSEG^5Py?N<VDMG*kC:cmbw?^i8=d^Kj!S>8A?uKTGa$k4^NMF<11XiYeJPEaCAky+9HGYI?H4=<S5CJ
5DBJBe nXjQLyk=J!D6?eCLZuw>C/I%JDdlWDyF<P8cMPAGtc/?V^G!*$X$!L5N$lelN6=6nCW=B9<EP>ZlwJXp
A8N$b# pI45hMck/dB^PHReDbN#le9RWyqQbI^&GYAE=ceA?$%A8t@JRm:ITSd!9YBk6GnBADaVJJEb9b&y#X/w
1IkLG: LTqcCaB5qAhWKkYECn!KlC>Bd+GCtJKmAwk<GN/=GhY+R$TK%J+MRe?k\e5*VGk1=KLCPtp$CGyBq+5l
MpYtHN +!4J=By+h*=Yu1*I/>^aZdb\\W:a6:1E8KMS4*HB?iVu6=9QF6Hl6RTRXq!cy!FpNKH!uFCNjJnWD%^E
m+Xi8\ TclyeL1ZBu<F5RmA5:JFC8T&V9wkl!ea>@\>8SA#yyDkF5YXmW%:#\PhK!S=kYB*paT5JtHd\cY4we6W
ki#c!R XLeY4Jat8QGnktM6tCpeL$wEbDRj4k#GSY@c+k4IjPA5u=JGM!8hLlm=ECqHq*RdT1GNKlAAJF>dhmSB
puptBw d<hY6a\9k>NK/8Y?mSNF\@l#&6Z?TSNj+SJjncAX><u1S@Zh1+C!GZ@uV5GVF&84Eacepck^Xcnq$FDL
$E$+Z+ ?cJnZ8HN1<5W*%4GAcA>&6=N:Nil=>$:FQ:Bm!V<HI%kIPV6:I\5l/chFj+Vk&=YIdXnQ1SHiQdQ51mu
I?CMdt \w&um14Z/b1HlnnZY$HnIEy#!T*e4J!8!#*X/*$XnJ1hw!tM<cdWJD9ELc@Vi^@>!9Vih*8\6@iYuqup
TSG%Ye weqZu>\iF%+QlWBey?X\Zj*ET1Du+YIK1ZJ!Fid+XNM+<DW$&RTRDaSdhmT?<8wRNm%CQ1l&QZl#Z9<u
a<1kq5 cqQc$%9S*kuMNdVqD=1S!n#u5?8edSK:RA#m!&qGGd+Jhqk*!uBQ%!ju>?=Y+#tWutN:DbMEwWC<MTF%
c1\:T\ AJ8>P\XmFaX4p?deI^&K%$I$Yl9JJ^m*%G@Aiku8AS1?PFGpXm>$<RBGKFC1Zm>TRC!CHIDbBHm%X&T6
?S/<PI CX+P\CNlHSNLc&G!GTCbIF<$9W%KceG<<!Na^YpHnX5q&en8PKSm>4cY%iuL=IVhVPJJhAbXI:qVtCpk
q4K!i@ P#^e4E5bl:PkIVSp=QBhdP?aMujiT&*@<<W5AJbCN6VTqM5LqjdnnZ^mjYl4Hq&MuQ4JbN?>8y/l1Tq^
biqX1# @XJXtnb8WT=Muc*XcM$JiIR4<=1qdSSiy&NR$6cHnS4qya$>idXWM5&l$p@DN@ZBHZ5cVK%XX1#8BFpV
+\m5u& w&ZNG6t?4SRpTG^%&?8&i^$\E5i6&Z8XW=!QRDh!E55K</DGpau$#l&:blNny+!iQu5*1uJZR=q=5>EG
=::%YT @bM:Wcn&J8l6%B1Sp\</%WnV#=XjwtX/%>F%4@hPG@Y1SCa%Gicj%&?6I%w@W+AcRm?p:EF%+#enum:@
kTwCPp 51>wVb>ZdZylcu!H*SmnM#QuSwdaP#AZpcFEum6^Ha#m/yP59@6$LWV6/w^Q^&uDGX1KP4\&PdSBRkIM
APeu$M 6Smh>W=Pe/^qEb@nYRh9SR6mp/44@&CRG@hhj1iT$L^CcdChP@HNGe&duNI<tDI/KMRqW!LWGll!Qpjy
W^8Wp1 K8?XKcR>d>:uBCN>tKKiM8EXJaVjKC4Wj94BVSeP#*<>XDn!5&XNti>5LRVcM6/@E9RNl%PYYHLAy$Ve
>e?FDW J@WZ^=hd<eSDiL$A1D#e$F6h1<uWda>t*6qLpV\=ci9hI\S!Ibhe>4m%Q?/R@q?=nh9499&mT$1@>\+5
9IShWP 55K\5++i&MW8M#t*km!Z/aI<QI:FMCMJq4dBkW1?%#IG/SWXZVXA>yVRZpNAca+XT5FeehN@l%?4&6:y
j@tZZT B1cIjIQIBW!\5pCML85!5Y9pQ54P\BQNP1MY&Q6B*L&hC8?:CwQKZ?B=\c=*^+^F1RY@E^>1kcljA\DS
1llY@k Vn=QGYVJBwn!!Wu%1=$DTp&P=tZ9d*$%qMFXB+ERLPWawD#:WYe*5ME<XcSYE$QE!Qtk>6NPjAuR4wpE
/b<*\d Q@m94:j*T%=6KA$KlLbNlhYC>T:\d6Qp^Ha6F\hHQTS:ICTAuCq5tZ6W9*lSlRHRK*9W*L$ZqHcGX$+K
#4:Ml! y/GE1!N@R4uL&lX=D%ZdCQ5Il6Gk?QQ!&?jGX^8Hk*tq+iY=/D+VQYM8S6kNB\Te@e1WJ6:a=6=wVDeE
:?@+MK y!k!AA*S15KqjmW!%:A^pcdMAEhS4=iFELcN*cAWl8atX\wH6mkD5lQN#H+#CVu^hEu9cdYl+%cmYtPW
wS9^P5 kaCI?!RFBBHNq/=GBY!j&P*Rjc$ER^*44mLt?B\/Bjj$/eA:1L6?l!yEYEG&RX%BwYQ*ldXGkh%RLeM*
KXP!JF EQS+MHKk5\#BBX\E=XbMQ:$AI9Na!yG:keyRhJ&&%#\WHHh*kSV%+SjHT&D!BBZp?C4+HGtN<5Ru!=hq
e<6H*6 T4BR!MXT\lMCAA\BL@y\yWABD5=y$9a/FwW?qiQ$t8GMQn&aQcMLQ##MSWCuHIG^PZ8pL#hMieq4+AEi
H\CQ6T cm<GtdwDeE?Xdn?aZ^F6lW!8kTd\NZ#IkY+KPBbC/A/CFRp%u^XXkuu6&Bh+Q%LJVB=&jdWH$KeLpB6V
wMjIR8 kjFlk/9<MCkVb%FQ*5bFh$JJ>tNGJiRFcmp*Ae>RBCLJjLKEQc\5Z+nEeP$%y!d*IahWdmV5t&JBb:J\
MCZ$X$ lPK!tXa4bTl\RLQn&8ebT4Bn>9l%qCHc=qa6kGR&dqQ#=m8ZDqm5>JXj@9*=MGlbh1=$IXh>LuEnkM>R
Be>itk k6S?%TSdGeC/&?*qhENX61JVcaK8#L1XhkE&uAdt%cye+\\wRck8\tJ:Z!m@IJK*8VeC>chjb:>J8/5c
IJuGj/ dZ=Lcm1m:+Bti1iccGlJT%^WD!PWG4FGS*@y!nTRTjGFM5c>Hh/W@TktF%HSZaeYLCc4!^9<Tp+b8K@L
b55?BH <RWaa\tRlq/%1?Sp4chTM?V5q&q%1IqPt==nSi!VXAG>+\I!iMQ6d!P:\StMD>uH>hHNV+iYb6w$Be%H
1EmW&V K\qVwYm!6n4wcQ#!PH$Y%4lQ9%Z11t!QN9Ic8a+l9SFmJ^+TJQlGNSqi8Ry<y\bd9p&AWAZ%iEBL#4jh
hP9n$m W#/tL/EeeL!?:I=L?eQ:n=b=m6$MwD>m5aBkH&MNwyibmab&4Mw#6b&@jA>yd#BPd5jwD5y&RAGPG!DL
V4SN<= $:^GVqIyi:EyX@@bSjP6YKlkpXLCQKEyn\4Ai&9::S$9N^%eQppCATL&%Ik4XM4Zyb\4&m9RweJu>1P<
VH8+#c b4SFH=/VB:q4qd=PnT6#4+=>Qi#$HP#/Xdt?HaI:4\S#?u!^+6T5ipl\Ke#F!l6=/L%4j5Lm!*:p*yVL
=J<cBA LT&dXh:u<Gc&Ct8L4W5A5pd6qeQ#??>Qje6Q%Hpcyc:W@WZ#P8WFAP!@%MTGc!CYh?4N#peJ/$b\DQyb
ISJ$yD udcFDFGj:&=HdyC1>#kJM?/PaT#8lD$jh66\$GV?S?$u=ZuncQ=m6TiMhScScA\Vkl#h/\\@yLAlWFZA
KG?%nW 6laWAVCwK*:!<iw*Q&Y*%MFqCCbQPhtn:b\TlIFSp4@Vb8CQ1\\Z/+I$8N=X<n&kLZthJDCYKyp^WJNX
Jh:mpn bmJ8=juK<TSNL6=KYB6Q8C4:G?*hVp+e6NeH*:@>?iiX9:AHni&<#IpEV*=$FeQNDW1Z+BpJGk!!68\l
:RRiNu jkCQ=8GlNhWA\NXI%mRtiV$PQdbanZqDM*#XdZPI?XCQPR&H4+RG&5FW&66E<VD=R!XIQALCJ=DH>c5$
>kjSCW X\J\cKKcMmlTddE+#\WRZENhGRdJaGEH?>EC1e/Ld6%141Q<uY=Lk8/AHCKdN^ka^mwiE5kZ5E@*\?H>
iVCyeP j%C1ISB+/*D6?deGj%Q!AWk\E6#h&1K!tIRqD#%WM#K&d>H<1&c4TyC^K!Z4\iL#RpW*Y9AK!mnRWWSw
C^Q5P\ DZC^5kl%!DWIiW/F9AW&t/#GYMdJ@ZRBlk+bi%:Y4n/dAW>ilC5cmR!?HyqEp1thp?jk=Vwp!DJ$RAZZ
y%jP*T <p6jaiA?F/6X&lj=XkXHS1uMtTJR\^ekPRc=BwdkYjmAtkbnP\Ke8>P!1H5!H?8nmd^q4/l8$%:$&ZP1
^CT@V= VcjK>E*hTZmi^W*cK6*pKKkkAYBcpHkF&q\YT8CFHRnXdipmpthRLSFadlPCG$MdIGyT16Y>uSHeZkM!
#Sda9& GkN&ce^!%Tpe59\5etAEw*m$a1BHj@aCRZcbJQ5N%+F!$SnGYdn5a#5<FM9\C+VFIE/AllADZZpWACGm
KkhlQA b&6lLXa1A1t&LFXFkTZK65P+jABmwGyIJ51eqL86hXq?m9YuhQLF8n*dFcHZwi6q1=k/kA\ABFEI^lNX
F4>Ni& AS>BPRHn&1QBaClQmAX:+aBd:/!IyDl^FE1E69AlA<uKIEBw5XKnDGQp@Rm8nSI=R$*&TkXaRnPm%PXn
WkGqmw l^YZIeBHnCIaEcKEtd<Aqha:tbWci^uw<Y1Md<tJe1p?\EaPj%RAAIHdT=uXuMn:+Kn8:inXDpBMwdI9
QGbda\ ?w^/^MAV+5DD1%BVkFpM!EE$\+$kE?p\D$^:YinL%ZRnE\k6m^w!L\Q8AaA=wk<b^:a$156!+Awc98WN
d/X/TX kn!y%dJFNcATaKwkd^qktNY1JZ^!!Rue4B1mSXPJm$WKcl??bm5NtTIHV#!&4>CJjKdVW@?194I!9<V#
5:nEY8 >p*Qu8IkYT?K%+TZ^/9NF41V1VAbTBLR>WE<dtATVtabMLHH/*y<\Bk<a^qJbtkQ&BDJ\X1Wd=wRMu/Y
EI&^FB cmAI%YK?$Z^iRTXdEK5MXnC4wRyASXGIb#T1ePe%KMikVCwihEaXYMAw=jck+eJP@\Dm#kA9W+S<FEy8
tbJ9WN Wy9N8<j+CAM#$F^D=P\:EnpDSqFBk/pp&Tn!/1TSHEAKwDlyk1:kBFK=YYtkCAZcpAVD!m<4Lh<cECH6
uF*6WI JEXSk1!jKNDWq#iweNhkBm%k9N9&S*j1SH=ihji:b*$bXc$8@A!FP6?uLI@RqCteiiN\L5LXEI5E%aCp
*teatL E&S=KF=l6WL&$19>5n=Ah1BIXYhn5aB@aE8>?pCCq61Ypb\D!phqcuLbPYbM69uXKFG@y8KS@SEQ/Bu6
li5yFT <E>@WcQ*S6mhn/X=4#yDWkQhAEAQA8VA=IWABc%$\=M<wKdJZhbSZF#6VWMZ^DmA>1+DE6&YKjWY*jlA
=\*NGl Y/wDcRGIPMeeSj??D=$6lkbE?e4dwhjiXT@6+Yt1<:#Ri6!^8Bc/Pw?nJkQkQPCBbSN1XwRqjDTCHEQN
n^wcM\ YSBc48p#Z^Y>lmL1&RpK5pFtAja%G$KPJ@CE!E<JlnJ:A&cEjW8kQy/!=p\LhPiL&A$jjHibyJ&XQn:V
X=wNEd dA+/Rta>WTWQwiSpbA8A65ERW:iH6@pB1WkHkSSPZ4y>^t#NkCPZW1!j?W%djSt8CMa4+yZq<SniSh!<
-ApMQ& 00043d9231200110333 Page 35 of binaries1.zip
=N+8+A E1@\SW:Ddt$kTp>\JY:RdVPqT&pkQFEB%V<=yR@IXRZB>\K1mR^D>Ki#>m%YY1?@4ZCB&nDw88&NBkJ:
6?qGhL %aE:G\SILbmqVe#4k6Z?npAwnLtIFjwkkAXAMINVRDY+w\RFuAV&cBcMZKLwEAh$jmSSpiH9#nHtDeFa
>Lw?RM ^P\YhVID!d!tC\c1*WlFyh\NL/!KPHNp#X<h1%!P<#h&dCpWG!YqEq1j+F9mpR1=%5tZ5M<!qH!*<t!M
Gne/T# S8@TPRccA1m5kNR4p+ZE=*@d6bJZJupW:Qt?a%yVBWmGAXBem?qB@D!mLX?V<kVP6EHKyuYbY/CKPR&8
5yPFuS MRHIAwa%%q?DIwjKQJ%L?F4uSC+u6*IC68!8w^cF<@8CQPhneV\>mH^=#?@#QHLmjw5tm95LwinCRubD
yX!:Aw be=I8TGCc^E:+Ke5h%Rb!Fd?T?eHX\ID*$S16au*ZC#j?Ha4/anw!+CpL!=<l5EDkmpc&lYJYB^9TqZ&
K?Dcp/ GYtwlnn5\:+Z1M^%SIKT>M>\+GZAiyi@c$mjckK1CiRbwLDRA4>?Qd&nk4//>t^N=j4na5/qmMcR4a*H
VkF%!= !$>eLijmNu+8QGV+D$$jZF*?8X&hE<*^9>4X8hL@id*6@@9Qj!&+hj$ZCu$huQ+S%wqG?%iKlB*?Mja@
i1QRq+ FWY#@\eTb^9^?#m8NLLh:#&e:P*J#m=P@%/eHjN:q@>i%^*/i\96Q=:@y&Qc@\QjQmiZ@=@+>qXXTGA5
E=p6lc at&1nY/XCDw^ZBmXd#?IHSeTI9C&SqlFI4S>nPmmyiJuXAeMqyNq:M+T8::SEk8>G<>wlm%uCZ:H$PS^
+QWmVD AZ@Rl/aZl5$V#5mE=45^8GqBw#!Sc9#\cl6FLq9I:%$d<n#Ih=!>$i=Q9$%JIX<?==@>+:dpi$wj&:5Z
1GQ$iI t:iyI8AFuE4H?K*PVFZX*8e\K>aPPqL15PFCp@%>8>1^LCyyRVJZ@=K>C&%+T<APiJ!qRcqBI+eE54+<
y^??ZD i9%<l%yL%8XE#EG>yQDd1m4N>9Xw+$ju%&:bF@6m%#D!XX>jF1%tGnFEPb/lk6FdLdE@Rd1?B/yV=iEh
>LwiA^ lB%MFtHM&\1cpSd&uRjNLZT1&=kYSp8/mIEt#>qPTGh!q+W<w9@VJR9L/T@uSn?Nj!t9IBF:!p5aEYjF
q>\ZdJ MI695&Kw8mMJAeQG/IllnbF/6FNJMD*@wKbGwq&hdP#!qe4m%IpdYd%=a%hL&y#$eG?^uH=piH8Y>w$Q
6J&:dn Wb!d#5j:mM$tdDjHy<ncYKantZj^#T6J=@^y4MYuKK</JPZCeA<CTw+kHj?R@<48J9aQ1^wHTPA4N%yL
#tBM5t bih=y%P!h!:nLa#:1$:uK*jj/t:l==?lldi**:4KqKb4hwh5+jpmaKihGQhKGk1$ubd\dK$Ak4!#N?1#
ypS5Y! hbkYK#4mRSR:/=:41l8jW*V%at:8At:HCBl>&4EN+@^d*e:6$q9lqphn9nm>?d:P/ER8uW$Ni%%WVd!&
Sm/M1n ^$e$WH*/B>>%i9yM\K1yL@EdnB$K&t6%^S1j!$!DHVyn9*9Nn4EM*a@tS/9h1d\N5dJii1Mee!MJ==@1
q?&K8k ?*1ddh4XGeSqHRZy<hu#p5wDZ5R+!/&pe@etd+YZ*TDG@\*iicMQV5?j=@^SFyid*Kk=>XTFTp\8R1SX
YyPP*^ y*99%+&5YkLVc6c/H1n4E6h:J/!ePtb\eDhujbVw*PN:6QCNb</=jhPb&QL8?BH49/yY/ejwSNWPuMy8
t8+GMF !^JlBDE/JG1nKJSw&>m@XwhGh?j*b\&N#J4d<I::>Dy>mM:Wt4uwRHw?lh8&6tVeMt/hPhL!lDYa<91p
=bEe/P 4$/XIBR!4jmKn+\W6>uG!N?MhS!+GjYn?NiF!1M9nBI@ML&XRSY>*4nHht6@l88wam6eJt*PZFP&p+=d
D^c<Lh FB=RVN/<hbc*>WiA8qW4LiL?*ETd%@$uhLjZ$Te!K4mcpnPD#*XQ6Q1:VIylF:/y4M=$#Z1&hP8EIlp*
CN&?k> >Z%\l&CZF@&yai9>8><*?tpjd:\1mu@a?mp*wM#iw/e+9KLSJ5WGIcG$L\:>Tcc8V5E%$#a+*=:!6taJ
lWnW6B i8&5Pla:5jXPlcq18u8Z<l:yaPn^$4W9#!=\q^=e&GqQj4d8\nPt<n/wFn>n9@j8L?CNy8@lNN>?=/+9
Njh@J\ ^@S%%&<Ni@5Rc:/e4D9d:y^%>aSi#^pubZ$niqZHF>LX=?6W5LwH!+=Bub$Yepcj98amn4%!5=*P1Z9T
mJjSW= V?aleI8DZK=C@a<TFemWuh5$<GGi<Cb1>yn><eX5>jC&e@a&N4wZl&n#K*^CN/SiP1K%?5iCkYQwLu#9
hdZmB> >Pp$?5i>D&p=+mp/e4Z\+e&:DRkC4tHE%PbXa4FX>MTbi#hh:T\i9V=GC+d<+dt=!q\9jb8jJPZGqS5H
DiFETX cj9nyuP==yi::?pdB=uZlqut5I>IcD<%jI:6H:YH?HdkTY5F^&QWS$phIu:L<$i15e4Q6^^BBqn^S1j=
D:6L?c *jit6D6C?%NP#WR>H^+R*nBIdRSw9k8#+iP5jN*\>ThdIqZMpB1yS+a/KQ\$Z6nEVJ^KiC?1:MYy?bAM
$+YpQZ MwdKyY:5jqcl?bjcGiMHhYYHL6FCZY<c:S^d+K+@FhuyY*q9m4qZ1E\^nL1ce!I8+p/CXaLPpY?FNSah
n9jTBB 1=CTT#YDu#pnn@4X5/b?tqy*1KT?1l>9WR4QeVLtZ?=$$w9dqSNl*jZ^ZGcY^IH*aB6>NZlW1>iNFVLt
heYd9S e8@n4@/nDRTH!B5n>+>kS:GQW:kdNi!mCu!KZ$YK/#>Ydi8q#p$<@PFpe*#W\LWLt@t!W4%eXTtDllLJ
d84>ZB TbPSy\IuG?Jp#:JTA@iia=+=Yi1<Z#Z:*5pY#Q+L5XF=*/M&^KS9ZN8k5*kWh:<>>C^+:*t9ehi>NjH4
yYV^?H ySP8dYj&hdYth5!9d1nu>yLuhZPk6?MIt@i*$+cKt+%%e/8??ePkBawK1?dGwGLhN1@q!^EacaEp?*FA
1i4>HT Wca::Gl6PKVn=>+#bJ!PPV@!&h#Rqa&j6Dm8J^%ja:lZEY8*^D@4*jq?ciTl!#+mIeJ^<K^H1@b%w!#c
GM#QHb SEde=/y6X?Fbl@jB*q<>1b%9NAR4=ZwaHPI?PH@:Gbn=KPCV:jL/y#\VHF*&>AFniQGkY>T>QhYRFSqy
iqVywq SJ&T=JhK6ZQK*m@/Vlkc^WWI%&#&dZtt:%Hp64j1Y=cqeh/e/hRV@+G/eCw%@kCq9mh<b*>NCB$+djkF
X5RyNp /Jl^/#^Ai6i6M:bqK?HcKw@h8Jmpn/>iB<>5VPM?:tiaDlhTymQ!hbI$E#XDV><eQDmJW\1BSiZ>*dCe
&@aFHb Q8l:JdIN=!nil>T%h<Lj9Z?Ei*PMqLcJw?l>E\QXTj?&@qS55ePXun?Q=S?y8><Ijwq+*H9ne?46B=p=
n/c\Yc i9IPV!+p<PBWKp:Za/9:/yFjqRPt&L6#EwCdjGF?G@F9l?BMj\a#E<kKHALd4\WtJ=5l66nWmNd/<15e
T/+b#e 1y$+K1QMq%6Wc&dPF%*F/?6^j#bi@cNNa?&?d%j6<tb$ccd*!^/F%diFll4p81k1Hka?mk%NYMhB&Vuh
\SeXb? WpH545:+5Qpmqc8*lhMD59qdmDi8NeGJ9p>KciiVL6n$q=dc=BmyF%p*Z>uR&PY%4@4\$BT6N$8j#QAN
@tWu#? p%1=:t8@aj*q6BuyiHc4&t/Ldc#e<YFi+Th:qpY#9n^W6Tw<llZ:Tul9/QJEKCH8bub1!K1n:Np@JnKY
DI=HE= 4DiGZdC+ZYihQiQwn!c?$Y=DKt?>@QLchi/FI^5##k*5P:RW^LuRq#CXHL6mF<j1/YDZy8p8:BQP/$&j
Q1+QcD QjmDV>Zt#tXHja#Y9$qe*<AeKJui&Hn?VKHKn@*Z5LPHa96eqWwc1qRu8h?:i$%tNw&b*5iP^l+WEn$Q
yA+DB= 6khd$LG##jb:jZy8ZhE4tF!*N!nkn:GZme^$*:XJ*^IS?A%bwuAE?E5pLMK&VytS96a5jL8Y>#ia@?SF
V&>hKt ?@IR:i>e+pD\jB1Z9eZpIKTt\N54^u^wjAlcJG1>aQq?m=le8?P=<F=ZCyDt@pL%iZSwa1y*/GmRdDuJ
C%F?H/ $B@FSjJ@nGC&^+XRkBDJ%^6Lp<?1S+Cq5t^ny?Q&!&%+j&W?u*F6R<cQ*6JXmG:Jt88tp%jhIle:B&?!
S*@&9m utL/RVH!=&%1F$&Tc&*%EpHAnlT5MbZ/XTMQLl4GyuT61/%Ct1:Bnee9yZ%F$+mh$uP16A5IjQ*Z^h%B
@*:B^q 6W</Mmj4DGQ1WnZk/YQF!e8=%t!X5pW\5JCY!&=b:Nq@+<eBm\LR=/#NcFSiY<L&wY+8>Qc%lhb44Ju8
d$!9&^ nGlNI@1Jq/>cd6S@L$<?cJ&FkM$l&tP5*^n5V>GbP5V8NMM&Vdl%jCmwLDjS:J#@K8ajG$yRwiae?qAi
XP@n:Q *bY+<i$X#jVuAey:6iD6J>9Vhi?eZZlN:4kXKqM<pYc?8SI\e1ZC<$ka@amC9\VD6JL=pW@6e&!q>!a?
j8SMP1 :mSujA$4**t!RmNEwNEYP+4N*<DjZubn>?yu#d>\?hHT*uNKH?PHE8P<Z1=AeP/6@^I^mhp=<8NXe8*n
CL56P# <GPQQpI*QLi=G?:ZQjjEP8hZl@A6y6:4duCShbhNZIS:/1*HBq/Z^WnDiuDtwXL9hIDd>88BNK:\+@8?
^Tq=iI jVh/4eQijdZKmy#9@<ZN6#qtEFp#@dQV+N\^EIhHYh1??wF/VJw<>5H?tp*ulVW9uGj<XQ+Ge@Y5REG%
jR*8SY n5ylE69?EI$:QGnii#KwhYyS\!cV/QRm>59pp^jq/HPuwS>5j>BTHI$Vj?YIG&*46>@1ES:^HhpRN9@#
ZnyjmW n8P99Kb6p@Dh>TnXP<%4FnPTTw&W:<^LW^<+e8ih%t5+GhEh:n#DXWjFh^aM5@QF56S!!Z%H5?Z6$IWc
Ahp!@I G6Jj>VE?!PKK&h^C/&8HqDA*hadnl81!6@*^y$XuYYw9CJZqj5PQ*8qEM4KYu$>LN6^$41b6i?d&n9EC
Wd?MG4 W=@+RnZK&8E1Kuk?<tTR:mqF=&Kk>YnD9iR<SY:j=K&aG!KyqJ6*Dy?=wuaZK5&YwD:e$Z&EWZ9EFcdn
%^nB8N %+c*/Z:k^PKw=Lt=GF1bJYI<=4!e=I^Rw*L/$*4n8beEBZh:t*DXpI\Cc+h+u#W8EXwcK@5P49JJnFwq
ptuT#E yJ8R8TcMc>:pBCZ!\#CGFDeQML^!d4Lek>><8=M<E&E$FtI%=kZ4Hu84e19m8%wy58ta:PjkE<F%9#$9
lDT+%K %a\DVRl##YFp:q?hkXc!c>6M%QKQHE6LCXWJnFCF6&>bmKhjZ!Ru9VE89/+Yhdpl6NIY*iukPHwY#HN/
pPSjZS 4^w/uK@CHj\!H:>q#y$?mR^nB+w&w1$/F91t=wYnciEuZ\WkV$aM>w>VXemJdn!9I!GjnwScBwTHq8jh
dnT+V= &KemV?:hPd!uHK+TNc>!#VE6dZ/u?QJ&*:u&1LHthI*ww?enP&RyI?c8Wp*BtbCa1ln#+#c4Q#N/h@qE
$FBV$L cAS\/lT*^u*D&y/8&Lk@<6t^E>pJb:$Yn6Xn6=5wt1/?6L?*m@B$8t+ZtuyLG%LdTjXHe>S98B+8?H1%
+Sb6Gk @8yV6hwRm\6tP#ui@yDhEJn6BahhXldBw?Sh:>ZIS?B%#!hKZXDXSapu/yLpp*bE/AY#PMI%%eTZPn=S
*^1=@K 5WjaGZhjhYIh=@h&TLC>u\&I:9@aijE@#MQ?u*Si@Ahtm!:p@#C??n<#Y*V>H#=Y@<X5<V?+k9<45<ZX
knP<^5 y9u=Acuy1%%!uM*wVl8+Tc8T:NI&Yqt==9l6aQ6G<6#eLN^mVj:N@*CXE<ZZldQKJCI&d4X>iK\DD4M8
j5puQ: p5N\=nq=ynnpJ1^QCX>jpPpb=t9yG=TiV9hq4<pKmtNqb4BV1VH4/A+dPJEij9=PQqc<RGhHa/8RKF5:
R>4CFF 44<%DpN#6DZLCZcm?tjGJdA>+#PhQG&ne4%DImk5+=D%aZS@?>mk>b=tGaEbYYGBS6^k*%ZJ#upd@K!h
-A#k&B 000f5d71c2400110333 Page 36 of binaries1.zip
ytSqDk *NPnp^t^5jFPPE\1I=LnuJ:45ma^\VnSI!diPD<6&eJwI#M*#m@DtlietbebEJwctt/X=?/YcB=8FlBD
IK9a#= h?jGPDIe&KFP#G#YlyW<HCa^KMnKKVQFMwKS+8%P!WmptjyuyZqalltGYiY8Ck5wwJ16w/jVA:l&Xt:S
J!R8YK pT+ScWp=DE1!e$BaWtLT!u@*N<Sl9NeqJ=9<t=*mKt5Z?=V%H9TXEWqyl9=t6mpJ/@!CE&IC%ll=Gu6c
<qA5TX ^AY/lac:l1^L69GLeq9HnjiMe+lJCI@^6k9CaS^M$:N5VY$!jH\Ciib?ZD<8Q>$pP6J49dNnbE=icFyB
/iFGeM Ru^MbMHKDE:Mlk\L:*C9dH/wX&cTdZC1TT:N*h#LLNRSl@FJhe*!<+?*C#h$DYFcihl#jc&h4LMVdJPM
aM4b\e 56N!nS*nnLIDPR!ueNacF65/^Deyal$#MwG>\TZbI64YM65/lQh:WLqb+e=i@JkI1:le1qFe#Ey&ttP!
jeJ<T\ 9^uhbCZD#b*y/?u8tG1=^6w!#<\6MD:cbc*X!pB1ACX6bcIq^<wtJ5uh$m+Wl&G5y^qblwS\a<&6%4wE
\LFdKD 4&Sd&G%p?*6^w\J!8Lc^/i6!#d#68E:B9wqydL==TNV/TFym4IXQAnZbP##Q!N9iJmkhl%uqaWJj:YZ4
88Wllb +&@m^X=yGph^>+%ccYIeS&HR&idBhmH&ZlHtTV#cB6:1pI&bd4+5!+%4*IPntH+4p%bFy:4cdW\^^&Hm
@^ASE8 ub\yG\%h+#PDiitSH5:ieYuy/?LM+8!6uN&w@FnD1MlRW+=6889GqXbl4AJP&pbK8Jq@mE6pXI^%>G1Y
T$Kh16 K&>hQA=n+<mKn#APm#NeTiE\<?qWu?S5bqDPt9Z4I6\h\4Kne#KTe+\hX!c^R$NVPbp^:ARu@&C&@\bu
/Mc6cY !wbWY*hLmu%pPA+V+PHk^4Ymbwacic#N!ZI#5R9NZt5cEp9J!\#%MZR*CT+\<:INCe^$nKadikXHGCe:
k>^XS! YtTFG&>M@ne4S6QX/R#j*/qq#VbP&EnqPqy+BHBmX<Z/F8V/t5j/ymWt&&T/t%N5Ru\DdM*ZB1*nPpiH
#R9nu/ BFJMp=ql99@RdNGJ=9S@bLbwd@<@tT*c&@&4bw9@neZ:4>!k<*@qFj<n8H@BdNGJ=9I9aGq&@^lL@?ha
Z%buE= J+j@^j8/@uP5w!Q6H&L6cQ<C%5:%H&Q6@nuY\i+j<:h&>9<ec?@w<w?^D9<e?:<mub*5HQ?FwQ?^I/cV
$adn4e uhP@MEl&@\85<:>!wl*@MjbjTC\HF@w@^6L@L:C8@?hai>y@J6u@P@J@R:L@h@@Vj!jbHb#@b=Lh*8=@
#Llq!C J6q@b/Hh@:<=#9?##ZEamZyPqEa8TR^X>6ND\DcIXeZR+GBNTVl=+SumFQtJ9bMh?bZhWA6n\jHc<Vi4
B1WlS= XZ%kdeYQl%Xw5R$Z:cV5=%i4m!Ji$pM1m8?/jWkPIQtWKLhaItDiVS@/bSHQh=>+uWm9a:VAd?8RiSe8
9+$#ay N$5G88nc*w5dhMbYLe1Jh<4jBnMtpLm?tTqj\ZHw!=G*V5Dh5!%6F!apA+^Zhw/<V4c#C!:\\F9^<iRR
5?<RJj ^4W/d4b@WEHFLnZ@P8DN$:ND!u:Vdnt?cG*pW6=>4\mnt\Xhp$+d*h+M:>1j!R$9&&bDHNd+#H&:G8KV
bT*4J$ :w?wCy:@+\Hld1<NM8bY:e^>*uGn/JG*b@bF*5k?#mBPDAWJNTj94:YPElPGc%nX^:jb?1#ijd1Pe9WM
W:e+\+ +l4^u8b^PiqS#C/X6?HbQ9JDHcQjmZyhk:I!:NSb+<&taw&%ec9@DHET^:q<!hwd!#cm*/*m>FdG*HP1
h8a6&/ %/%%\i$q=bcel@t6<y?=*^uun+&/Pu?Q:ZTJaqJc8JQntHKL>n+tlV+TKb!bpKCJ5a/YHQ6%!!y&DRt\
cM:Ita k1Q%5XQBF+nnV96^#XEQW&ad%5VlWpwRPlyXi>p8Jiqmkbe5i1XEiYuyV1XS/kFmi4:HV4NldZ*a&nPl
:6dl1> 4:jl^Ll:Snhm1<=8HbnPZGC@j8^8kMJn#*PT@A65QPPT@Tb*PE?N&*#Z<A<uXld>kV9liZPXW\p&lDXF
%4IqTV 1W*#>>jZ*h4!yeeDTqe=W**t!F@d+ntp!TFSKY8^yadb5>IVH#<qCiEiTR=j/&I=<4&lJuN&>c&1*G8F
AGPGtX <jwj4u%/8*LZdNB:R<Iq8/+VQ&:jKY#6i18&PVu<YVTnk<b91\:9K5Rn@C&i<cWEl<555?B:Spa6pBYL
ER*I6D D5:WPaTLi9WI=tl:\N9t=+NcSyCG>RQP+^G\5$+jM*TDLn6JQ@^>wT?a9&ip\Fu$>jaR?#QA5TL^D=pu
L56DEk ZZ!cBN8=@wGEQZP1</ylButaRM>X\S!l?8%T&&KRqYcwTXW</eAe9b?jb?jHqNI:=*wiBL:$hQSF*4+Z
^W%REj W5qFhk1&:I45WJuNQFQTVhjSVWQk+6YLh1CbtBL+^:?^*&=F95ihe8nR$*/<@tlTn>%&wbl/WhPKqH$5
dI<JE> 89!I8Pq>p6i:!NydGTj<+ZP4cXRXt$/*I:6iwPwT>/ncbl<%%Pl/9>46bVmK:NndEQmHh=Jh^5tZ?Vi%
LpytTF m&@9cntE8?peh1SV<@J$jX&Cd:/j@ch$Y<LwujSP?V%DXFh&\=4L6TH99LSL9$kT#IeLe:It#DWYH$!%
G@Zi&X *a>mub<!*uQ5jQ#L5=8Qd*h$Q$J><HCuDG8#yNQ19W@4<LES^:9=%uyEy65n6huK4nYn\dTM4LT5!m$X
uY5$YJ AWEYYtLhjhm\4c1*@EN*9%JM^DXlV*#?e%L#89wDQV:Y5jd8SAaNE%X^N/<ln^mSa4\aXXDu:QC%+w#L
T89ZLN HjSl*YK9n=V8&$BES+tqpRt8TyNK$yN^hA*wd<QVGXMHbG6mZ?\?dt*5>84+/n?\9CQH1#8N4p&&bG:N
/VPm$I Nd6V1:p@<wlGHi^VTb4?8QWW$+&@nd=@q&j9hXi4L#DLQ*ISAbwWVqH1VQM#JQ#MFTHa1Ln*iZ*h/!n:
\p!1&6 Y/PaS^uqn=%6w\9G%CPB>w6XMi5@F^$4@+Tc=PTF1?^jeD*d5Z1*jX!d&uqnm^eWu<nY/?H*AuL5=KPL
^DZY84 TS*uhn1j&6mWLMt$?4ktS\Wn5q\K#9L&&B@L11Y9QjL8/n9qt4c8hH#<J$H/m\%/PIj&tbpG6*Sl\MCy
m\9TQ# LMeDi/cNpwQ:JR+d:ZQQ86$?iX>Pp>*Xj^j4DKFPYM/5R?+PPDq!&LB8PLM%8Kw*ylqiqy4p9Whn\5*4
/#FDaY hP<X:K*Tubm^4n?j=pwiDutudEKGB:*5!>e@Quql4NwR6c9yn>m/5$*Qt*nNkatL6*$^#k+hD\K\tyQh
m>\1Bd K:N^%$Qdd$i=dB<j>i4>MHuj$#jhNKdy<1cS&yW/FT&c1idSEbQ:E=1jRbt:H?%FbuCe:q<qbcyp5HdZ
lpQCXc LlLl!:DN#+:yBRbNd=Z91>nKDDnYtNi:55p!++4Fki\A>D:9@jJ*J%+hpESe?\+#qQQdN^l/45G5PXpT
PH*&:< @cVHNuV*9kiCm6aRl#^C^4V$m:I9H>:WWh$W+S:&wQ?&D#YXXBX<%h\AeT?/jLFp=>WVYRudDN&u5mJ+
d+C^&R \<PENchCdyd5T*C?$yidN?*RXu9myejGAZQ#p=eiYiWYc6#4M:N$PG=PqZqjtItL@d4&n?n:8dG<*99u
dLEkK: EF=bPFV6q#X&*ljP#?b<T41!?>BDdNa/%LPwHi!:T=NdhY*#VyiK#>SLLn@yN51Ck69@Im4@8h65P!:d
cuQC%# 1H:\VH9JFaj>9!/6XptuQW&:GhQV/nlca^1AY%up9*&ZjZhcbhtH5*H!Z49R<$@tHyI&H*:WQ$W4dP*S
qVk5G$ i/8Y>mGVu?6@K81eZ+=#>1A5@Jk/ch4^6X?y&q6/WllVE%%$!?d1t\8B^h4^lLP9NCaTJJtQm>?p5<E9
1>LdWD Zl$y1G>1d#GVc/\Dn/hutK?>X%Z+S@V4heiiX=:Sn41>&Lp*KGSqR4%K?y%\=ZKlnu#5/c%#^ajQZ*T>
#dtB+R KyQ>BYH+*?Y&*itmZy9/$X#=!dZh@9/4cZ/Z?QC658Y:S$><uuN?yL@w?QcW:W&5>6H</?$BK^1i^L+d
4kMS/q jiyjN+J<tK!4985SciPZh:5DuNi\^$?&^c&P>L6YE?khuHQ+<4kQV5P4#Yy!hFb#><idD/:@iPd+ac14
41uXdw @w^d$?yk9@tPT#*mmD?V+K%KnPuR@4&bwV>VC=8PJpTFKZdCG4=jc>:%jnuGPn/thIyh5>n$NQF&y8hV
/G1Wn% 9$Pyh?b?KM&dncN:8/uQdL@MnG98JPieVM8j8XECV?duRy<ZJAQYbenyN@B*R=+=kdG!?jwP&YTHbjjG
+yAQh4 <kYuC8K$/Dw!ES<mdE@$Y:=9dP@n\@u?/pJAcn#d9Hd!:X=MTP8bbBbG%TiLIY8>jR@V*bPcp=^#FQSS
#uBk6< B49TC>upn!wIi:1+8GdwQM=1WN#>jQF/WYTwId&YQut#d!@CMP*p1>QQe9/tltA4t5/Au:Dk1/>9?Ytb
$Yb41i C:#Z:>+h6Xm5iuZtSQ<!VhH6H#mNijeHZJcS^ZAXTd/Y>R&d%ic@iDkd&PW<wdJaI#^t=4^d=P\D>M^M
B%qXt! lEcES#nLb#YD+EiNp9@KjwW!Md^%>A<CXBay^Z<8DZ/Nhj<nnHdk>4i@l/yStQ#qF!G+P?p/Ye5BXt/#
p*<*Va E=%@IYJeEeZ*D&F8HQ*+4c9^%@#8DQ@p#HGcV<Xe:^9p4S8%bhT@ki5nARnSA<#bqLHPb^nTF1PIt+5p
&Z5ypu d6bwW>pttIL9XN*$^XKauGINZ>^?6/59+Qkl>nHR&i:nXHwC#nJ+emm+@9%h1K<^:5=Z+/5&b%J&9:=V
hL&qa6 *J>e:XV4=/?GH:QH:qV/E*/p<!hm>Eb*Xp>=+>V^e$CycF*=^^q&IP9q\8b*$B>DmTueHI=SheS\nJNp
:e^yC% l?H^il@+&dMhm\iCMnb%S@n:Lwice&>qd@<d?&l%@m%#%j#YX=Nl#?t44=QZ1a&ySEn>Z#8@Hm<QymZc
P9J>VR DDqdX^:\5n4kMihyBYdX6tuc6Sp\&w\>lQny8Y$wkI&8tIw>FE^@Jep#eZ!NMRk<4wt%%!t@NSwRdy?#
?QHaI8 YIpi9pE#hDT8ddChu\=yj&L$Lkeym$et/@!*Nn*C#6BIe\!YC%4eFmnaPBc$+M&CH<K1&9>EPhY9uWYn
!/pIY@ Y$^J\A\^u>*@wXmWh/#<6ey^%6>8L*//?</L$E%XE***K&JLn9&+njcL&6pZP:aRtJQw6lDm$Zd&BSYb
FYQZqF 6bAZh/P<KQLahSd%PVY9uF@LewV/5&#Yh/yX1jhEJ$W=P/4=qY=#<:86\l&5aTE<%J<^yD*LI%%S^kF8
JdWZTS FdmXh8SkG=@cE/\/m&IXqeqZ+$Z:$:>M=@?\Ee$E6^KeB>*6<a$:i1uhJqWPbw+1>R65T+HZG=ZEb$ci
A<T?+* I^S$WHEl\WD?qP&#M>#9hA!DVLRNipNt::/mlKth6@@WaY$@*Ie#Dh/VFN!wHNy*cDkB8GQm=^yC&B#w
D@b!@W J+p:Kjqk?e8y#Ga5NTjGdMlIM9cwy=N#+%Clu\ZPuLn@R$>Y$DM%R\@u=&m!V@ZqR?S9TVbd%KuS>1*F
Ky+:KX /4%F&cN>b8YC>5JdXJ#%G*j\cGn+^E*VCwT48DMAHVXtEi8YFleyVu*?NDtlQZ=<6QeD>Z!p:%MPiw$b
wmJckA QQt<LHXw>Qu#Y1QXG8BETWkM?auABIw::e9SCEID:MiMbFEYZZ!tnRM:5V@5VtRXMttn5!6GKeR<6K@4
#LtwBB iZPwX*QJ1tl?5/8VIMdWQ&dnb6LGCQ@wV#HQwSMdHQ5ZD5hTq+/>Kw&>uiX+V&C>/?@+ihtJqQmTnbLd
jSC^$& tb!u9pd4uA4!uWdDu!*Iu=t4mPw+!P%YC?/9K^CGI6d46IeBGwQ6<*W^Jeq>/EM1G?X4MAPSP*&VuDwT
>hMScc C41&9^!b*&C8>c:&%jY=%#Fb+dW<9@FcmFiWbaTB:hKYQE%J\tEiVMV!8e+L<H$cML<^$><kjDkp*jGE
-A+AR& 000f09db46800110333 Page 37 of binaries1.zip
185lnu >W=%6h$6RePiS1<6NwXAF?<5Lh:eIm^XVciq?ANE+%T$k@Mhi!edt+?TDt89Dt?S5@!&u$c%<<6NH6NZ
yJ4#en $^Pn#BZ=%5RLwa9JQYiyQ4Y!VWQBWia5X>nJDWphD1J>!pG\Dd5jVyT18Qt??4\JH5Y1dql5**TDm1#H
F&Yy&/ GS/T+D:eZQiZjh>NydV&1?p^d?INYb=iQ!MKd@pj@cS$@S98&6w5INdW?P^Z5bj#%Wn#NHFW61=H#JCV
Qq4pZM <#YK8qwwPe@m98G*uhVG%G>@qZZmEQd<F*tjp18@tNQ?4mINXbltD@<NidFtm*?W*PEeJPaQiD/S$*Me
>y8*CW m1YZF!FWu@YEn%8D19ul\?ud:9M*##P\+&Hp%VN&Qw!t4G5d\=aqNe+N6c$?y=tp?\5XKc:ty+bkppYV
kBDXG5 y*1!%8NFNS*?*XqHp8$HJ8VI>=ij%/:c?8Z^Dq!dXeT^Y#QyN6ie:%@dQnTJQH95DP6/F8h6c*JmeL:%
AaqmRp 1=t&ANXpD9I64%VJwVT\I9Xh@?QQYwXcPGGjyM@J:!Gh*&HM8J$*>nVpWkYyDe#lCa&1q%MQq=p5QcnI
pGynTD &LeLtbH@wHJDENS\<Q:V4HlebJZmYhp\w@:qpa1MTiVMn?J/<I1>!N9/Tjm6+=Ey&#h%^^VjGu9T6%&8
YD@?Xu tt=VFS\dcmm6H@%\@Fd6t<iYy=ntp+<hMb<cR9Wml1=+#B^F=DeP%h@c6Y6l=kF/:H\?N9?eEjWw6cLy
jyednE >Meqq=+*EbMN>iYjh54DdR?S*lui>9w!:lpynQVPF4VqP6BZkYHLjWDY$yL^^1ku9e8B/!I<DJS*P>X/
n:Ge@m CNllP^d>+p+^ny*/i<Z^tICA8>9GGYpI/^XGQW/m5=Q=>:Xunl=$:D^e&Y6ujHG:/wZDYXiMHj^B66>Z
th!I*d HjXpi:6R?C:R4?DunZZ\#i%iBDQ^q*HLuXRq4e\+<J&VN1yD&8CD:LL68%:<=t/&1Qb%WydK^\><99tB
bj\/18 D8*!<KHW*cZ^n96!uQwi*8hLT^%+MbIjRL:IN%aqnZmkM5ke#m1yGE*weH?VTe@n1%hHHNtl%SX:Kk6q
LDM9k4 qJ*@%+56VktuM/<eq8w*bHT>@<9@iFQ=9aKY:A8Zh=y*F/*i:G6pq^*a?EQN@bjLAe:J%X9<%4aNSSN#
Np?c@^ K\N9l$1Y!u$Pd=uKZd&HQBqnZMI%Wi4En#X><uR?51N5K?%Bw$E?e1#qa*61@Z!WL=%i>8iY8AVub^eP
%p\ncY ^4tePV=ce!&==iZhHdu\AF**E:8>/6@TPG6iLW>MiX$I:4uRQaI?jnV%/8EL&%&NlANN<hFt*QEWR#hN
yKi8QE b9*$\$u6t<i!4cTKq^h$+qY&66TejmddN%V>F4etKR9LjVJSnS??EN@ldQD??#V8e?Z?Q^:i+lVS><**
HeemZM 9^<dd8i&Z@k#<&#ybjP&XY:1q:dE=KYHlp>XC!=i88TT&Lu%&#!SQZ*#p<V@i=*aT*H&BD*keX&q=ln>
Q?IEa$ +BYj#QI*n&KKCy4iRV6PM*e19c>>/HXKYQR8:GnVWk\CPHR+XBwb%Ie>dHC^*DAnM?b?4>Wjca=9EE5@
8?Aw:? 4m19:P=h#q4IL:9j@DF6%W4:NA6wc^chp=N\PQ:mDjeDZcXP&cJ>=th6%Y>Q6+S@b@P:Fp/ePHMe9DXi
CmPJX: hNbQ54?++pc6>CHISw?L:^TENiY&Sb!4P1<LiJNH*\Re<db+:#6hni&!%1%BhCe*PbYYS=>=Z^:RGXl<
ZpeT<I dyZ9jQVl=^t\1L6Q!\kbh%I@QZJ4D+pY?*#JLm>+^#=YYhC:EPQwu:?PRMyLLy&eM1I9#EVE*b1iXq\/
SDNb^Q *NEbF%?8GZEabNt$&c%LmW#>Z8*>a<66C<LFp6wHw*e89Zq@GZ=kw?t/WI<4ncYPB/\/K/4X+u81>&K>
^GZN?> 5QY%EjL*ma::GqAHLqqHQu/6i8$\J?Nb@PiM=%i*1N&#Yt=JTT98mNR^It:b@&&wZ99S=w!hLnejDb&h
LZRNlH PhL=W5chl4HybYHJTA^>@=uH4E8Qt#a<hjI<w9Eph:?/@^?bQTc$4/n>1@!:wyWK&*T<*Pj\@:Ay>*<I
M!ASq= B9>:kjZ@6yZh@%bA@W>py5Q@pidlTQ8jNA<H%*>B<&Dt=PV?*9u*Jwj@PK4Vj+9/j\km@+%^@c<<:9@M
Fl5aN4 q>5:@I8CmL*VQ<e/$P*@Mhd=Z<A/@YNS\>:qZ<A/@C?\>H?P6dj@^^!@9i5@^@+9lRpH&4>!59/^E8Nk
jpKX=@ >*?B6j<Z5Hd@iIAhHQ/Xp@YQFT?H@=^aKS5K@tua@&&Y@H51@*:%Q=y!BcjubQ::LEp1?QhCAEi!5=M#
5Vl:qI ?h>$Ithu?u<piG=?ep4?:+&$j*@<%%Ce@l<K^hYX:P#+?\8C:9V9Ej$LpVn@F>ZE*8Gj1md@9S#l*%RV
8DBVqI y*>Rt8Dk<9>>Z#Q/Q?y4b9@:8@Cj>nX#e1D@y:=t>nVc9!DR@B@%Nh6#*YR!9d$%Y**Z4bVVSeii=!4L
kXh5ki &Q\wN^QNj>#ZnH>ZciyL$w1VI=u*HnS<9Eu99uP+5MJE?EimPQdw:5\C9&hy=^??&SRpu9/<9qiS8tqp
wLMiaj X!c8hDl^Qce@%dpXCkHq6eGFMZ5&n*G6@>4/?h*j?@9=TX>9965h*V+X+FBp&a6XQntiXjD\TB<cm+JD
4Y%p1N ta^841Pi/w%ZVt:>Bn9T>5*PPnjulJ#iNV!>=N4ej@5tG+<YCXywHLcFy4LEdY%<i+P>Dp=eIlljLGbR
A&G5/A CPllaVlN<?/6n?tj>\cj?>ID\GebEX@A*CWe4JQCn6FE!Q4m6TRRcdK&SNCbhSmyYM:VK&ZPFHYCkwZm
%LLdBm FXLXPTG=hA+9MWS*i*@:ecFK9Zy\FcGilJWP$t8N!:\+ncbqA+$H>NA&y:@e<XQXhZ^^R+wuW/EMGq^T
<nwhDB V1G%t=hZLuhba8dpQhbKk#N<G?ZY^T8GN>ApV^4W\h8LX5ppZ/Ni1*jQJw*e4F#4eRR1G:G9HKKQ1+NR
4^\qy6 >KSYTi9mqFNFK<*PM\LVB?lDl=KDY*E655hBuR#!E:wKthcyK&*6uHe6dbP>wqRQ>dY&%<BG=k?laiM5
\VZN^6 n:5NXS9ZH9YTLu6Yjl+F1VXD!!!pTPNb\<%cPD1uA&nHT:Tw\/SlV@k484$Z9yX$\y5/P/CchcVXHG?P
IH*AKk eI+>a*#BQu9tlX5tihK>#1/McIylFDi<>n6>/+?m<@Ped^<e$:YSj1yBi*Z<Cb>GJqq1lmPLH&ZD#5ky
CGE8E# XZmb<jN%y@dQduweupeP1M+wmklWc#@49c5V96pttNycbk@6bACndpL6I++lWk5?+Fe&1QnSWkKjhY5F
lKX%PW Y@1K\4C#+>m\BkTRL^RP4jHidZG8?P+PL8uH8@$aI?DHZYMEutyT&9V/W*XjbG>qiEpb\VpC><\<iC><
Bw9e69 \QScN@Hyt<MubWuJeqXD:%uuG6CZGSG6pZTKk!kn5%panja/+>WcC>VuPy1/Ca>4M4ilICe#t/d&uLFT
qW6ma# #Cb6N@Ibb/*b1J@!%\V*WqPWkec?RA6hWbJ5%H%*il&j545#*GC%=pkn5ph#n8?mJ9M1!+8TicGLk@ca
tqHVnw VBRtRF4*GylA^K><IFwDB#*?<H#@yQ5t#JABd$P:LwRh/ARy&?M=/?LnuS8Jmuic<1IBiAt/Se#tc=in
i/wHRH 4WpycDITDLTDFjENB*!$K6tVdHG65cwaIAI6:HDj#lCTHJ+pbQTH??CJ1VWLuY=yGSj*/:c+GyG>>+C6
twFES9 >w!bSpRJqXbZ6>5+8NuP:>cyye6CA\jaT+J&G^&AR##*K?e^pMJ?kZTSbI1tn$B+YXd\=<+AnG!mQX8R
>yyGnE inASCaiPcIVAGGtTEne5QLAGCeRd%p?$EwZH9Di<:Z*yNcVnKNu4y#wadIyp%lMFT4:cRK*@>YeFB4=4
NP*k!n &EkIN1+BW1ljS=9TX6T1wTEd$RQ5i/Rlnl1KFePGTS%SeC5<Y8+bnjRy1491ytZH+4=e/*:GEEJX*mQa
!DWY<W :VSI6%aTNtRS/6BKkPlCtMypKwFj?Z9yKF!uIGK4pIEM!amaLWLdRlJXVH*bD:Xun/Y:%=I6ASqGR@DF
*iT?I8 AW>nPLZKAI\\K9Kt<JGX%>Q^4Ly*lne*:!Pw?Q\ki&h=cRtc:WYLE6XbV\iIRIyFM&/LI/q#E#/9HWac
CY#NDG H=E?NBu5bdV1MBai/dbRZYA>JH$pD+qNuC?6WmV<KRj?%IR^hK>C5SCw*HKLEbl*J%GQ9P:NqndX@ca*
djc+Ek HaljMEy6=K:?FlDIeMIAY#SPQt@Vbkede=jHIa!5tFJIk+/Rm%Q%qyKJ?Hn+A\FDLWq/6IR&aAHqcqQq
CE/TQ% SA6eudMb\5+dcPuWnw:ac>PJ$Dw+#AkZ5IRRJu@h86u&qab51NKk@Gtl\:8YKW8pZ\pnVk<EwFWRw15@
ulF/?6 XXhQSq?Lbd>^pT+#%Gb:T<1b=9mk9V9^%&h&Kd6^GCJcQPT1FI8qbdkKPC>$cw!4qjQM%899&mP#?*KF
+?RSXK ^M*HK<kRNIT:pl^SCX#48$YFAp4m8KaKEJnXj64cZkuJ\Hu^/#CMV9FMiRSdTDNP:kaLKtVVSk\$j>hG
b8BhGQ ^*lqR^BAnD5TjLF+qbcX=1MpyqbL:Q8Gw^DGMa&hllCjBQHAbca^=:H!F*pF\M/#>RtH\SZbe:Qti:l4
La<e?! nY<be=MDXj1/GRJGHDR^PFc<cL@pq*e#bCLKBtu?EIDX?mk@hT!ED\SDEdVdyIpypbn^P&hIWQ$&h@S8
pM\LnZ QMaFtF:X5<eTQbH1K4L@TWLMY5WE5F8%JJ&P<JcGXJ#MFRjl9mPc>mWl*ViF%h#dhb:i&KV!RYHb!AeA
R8L^/& ^8!#Y8+pZLKSb6k&#LwVkeRC*Gp%YjX^ATQX@PWyFB+$5wc6j&mE=P!%EamKJD@P:Q:$jG%BpiPRKuuK
i?KqwX Hcu:u8kNh<QtNYl/+jMkE==@h#ZEHXYj8RXlh5aylJyIPQ6VXkwyGKk%Fa<CiIL5GKWGL>e16GQCKPab
ui&9!c *LySE=T5Vh$<8BXB\DyLL5*QIM^RL+/H:=Hm6dE<LE=\:^eApG9^D1?n=y4D5ciBqSyDuHVa^GW#@!JX
tQ4Thm QYHiqyp=Q?YTVmXNWX/W49!ZC$:K%jDylKL5HN&a%C@cJeGS$qNYNBH/ltydiFQa+?@lP8>i4$%/bCNp
lkh&m? bDm9yulnDI8LqWiQnFX&IuTE^*C9c/Xa5ewD/5BaBCk:Hwut8GpbZ9*4T9mk%wZwLdCl=qV+?we49Wtu
wHEchD hF>1!Rwn9!El!#5IR4c*wGWWNnDiw6$Gn!qQ%**RWC/&aQT9KtF?JAPWAKCqiHNN\8pu1n?<^D<8*!\c
j$bPq\ jAV^^Tj4W:l&1MXcni9nB<jQQ>&V1/4:+9VD>+DZMa1RKhRlWbBAm$ljtdJIby/4YNK>enZ54*6#H6jQ
D1utS9 $?VeIAl=N%G<PIqu5JTRpC*&Rycu*1W@H=PP@:HHRZZ<8eEh>=?&1>+t#j<CbQIkhF&Wk&ClTRjeEZ##
\wN\Ym +KpZP#^8ju6T89V1yG8?uG!\k48$B6jTk@aIi@9uk^I\=&Z##%#?#@iQ4wbNQdh65mSnaLMb8IF/p1B&
X8^!6R BT<HBdFC6inl*4WAL%N@n\mS<W/QJ!I^H8w?P\mD+d??%\hwcDMRk?I%1<:TNa?yGDM\JNu!6/yj*^dl
4>:j16 *!^NpayFEp?1Py6KA5hW8abE+Bl&kEWE5X@Cq4:q:WMlQiDChwAbc5BhIuZN@\qE+Ybn>PWeFZuMC1Gt
/X%tIB Xyk1^yiMl8mkBcuc9FE+My<1I&5\Y%<5ny%<j\4=@kHK5E?F%+=weR<a8KdGMFX4YhSuXG1p$\5BAA6@
RlS&Z/ qF*:AWE\?Q5=kCE@$aI$\wdmWV\GmSG4^5B46iS4R:w>=X5i1u:FEI#W4MKIm*6X9Z=jZwKXba^4kN=P
<J1iPw *ykiN+jMXWEKYP=MI4w&Y/PPRkw*DnC4lw+<Kt5latYceMEBFemeKm<W#tmEk*&<qt:ml\1q^W<IYpE!
-AP:19 00065ee089800110333 Page 38 of binaries1.zip
!^q/yH @6ZARJ<th^AkI&GMQnmw$D/<AMnm%RYV#$CwATP\jYJ\NRPMR9IJCpeqLp6J6kBh/KaCm$ykH*\RV5!?
I+=kaq cDDZAd>#SCM6XSjC\aCk4pwGXLCeJkM$B^#%=dX/y@J@L&mlLW:\D?e$Jm=1GEHXtcp\IGhFm:L&RDB?
ZiDbC& EA9\PqZJ9jlbN#LntI:@T%I>BXAL\>mV1LPNttTwTukVlL\Iw##SyG\lRFn1+cMAYYkk/$H%qK>t$8EA
=BFbJP BlDI+cAjmwHEW9lcZB<X$AI#i\%V<XCheRmjj+:T@b/K5hRFAZ%bFF=PI<p+$Jc%ENpZI1QeRHcMKJ@W
RAGP!? IKemJGdW<Gmdn?GpSAMD=laWh$S9F19Pm>ej?InpQVTkbGlCctMT+emBl&lG6McyT$y*Dd@%lFD6R%RB
#peu?K 44K5TFY&Y=Qb4R9^5T<6AIA9MC/HmA6#Pt*\=PMHy/GQK5Bb6N#GkBKnCl11iGHZp?h%!KEE:nXmT^@P
ca:6=R >ydVcS:Je1>Nw5nAyF1HY+ChQcTmCAX/Sm?Rwj1MP>BQ\&H48>C<:XlBEWp&</yqyaEe1m@A1\BQ5l%i
FqibDR &FS?wJ@<5w=49BNp1XEWnd^ADdAS\88CKLB/*G@nQXF@*:%Cj<wtNbB&klIMw%iJuKyN<TM#MC8a+h/u
#8lb+R !&#8Xta&aKkWQ4HZ&?<qZbP:bRZ*AH+yNRLwknKQ?lNJcm$nlIEbPQ8q@%KnPaY6ut&IFB^VGtmARFLl
+?ZF8a Al6hid<Y<=+=5TtMN\<V/GqVQpIAn645MVSQmKA$cR41EeVL+y:Z*n5yVwtnWEI?tXGkI>hE9!aT%?@$
kDlVAD #lj:V4%%<tcnIRyq:uMhTlN?htSjRSL:6Iuhuh^Rm!cI+lBeAAjI@eih4Fa#E=REl1yp1Kd5R?VL>NCN
AR9N+8 1NBVESwMqnI=FLb#W$SpHj&#EtEW4kt\>MpAZyAie@yThF$bW@X:SMPCnd^#1RWLc#uCeVJmS/:niE5B
E^B4Pl Pa5AA4BhP&IY@8L59Enh^ca!lJCKiRVpVN!#AwTClRTFYkLj?CHd/Pm&Nb<qAKRhLmlC6*^iM/ZP8de/
Vy?4F& \X81PYCBBI9\\E1PSu1ej=d4tWhWll\8?AaR6@GT@?J1\yEWTKJZHiXiht\$qRm!6DPH%pXZPD9!%1ZM
mkFc$Q /R/RpDWe4h&+YLWXTd5DPF>CTM:8KDtkjLiQA6IRqQI>b>Lnh8ET?JZIi=NRaG*Kdu^*Idl:HJip/c/&
?S*uu% MektGIR#y%WXN1Rd/=Jktpk!T$ePJV19!jT1TI4^ni8J\yNbcq!ACMqBKK#$KTX8DIDAQb:&JTl=k@\<
FRnGpF W\$8\ACcekyISmpPEAZ?<ML*YhPm#4P>/mBLqityK#mM:#CkAnVh*eN&nDn>tM6c+CTJ?RnD9dbCZpkI
89>$EX ?yCpiaQ:laee!NWuY^DBGDYRBS$bR$I1qTCQe/bVewu8B<FPJVJL6&XJk=8Mb<Vw9&pEAHjNu6KWcbh%
h:A1kN >:+tPKh=V&qm\RPAap=Q^5h^+\FI4>ISP8t9>i9P6jt?GPjI@am<TnZCn+&JTBk\qD?>b@Mt>jT#tlmB
5Wn%1q KR4C8MD+y5bkHb<6SHPyc4!d?W@^YHpDuQIN%4JE?u&X<aL4RpdRnEd6\nMFj?*NPwVStJ%ieTkXQ&5A
<SkP=b aSB^bCEJ9K#B>P9jhT:9m@D9WWAdnK$l9!QIy?BkAa!W8lN5&e=bI+:b1/hyuD16X$8yXYQEcJn!mRNd
T=Xu\h DGTilKp>wLAJA:bD\GCAuEmTHaCDnkBqCTp#SuZ5LL5*y5I+1<\:GXYyJ8d=iT@LLSR1we^HANpVP9AI
VNFAHL !+5A!DPARp<nR:9k*t#KZ@8hKe=\\bnGkI#C5I5AQHGKXLYb!E$8lNK$LASFkidqK^8PEtd:CC%88tZ4
WpWD6N Tl5*dq:i6qd84mbnRiRKK5RL!!6YB4+AqBAYq\@MVF9I$DA8T$9^e6XkPS:!X$&D/5:y*YlK@W:BIY\4
\eRGbd e8MN8lLaye?W1=L:eR1>mSu4:WW@m^P@AVL>WpCue5Bhq*EN\a$ab%yyMwcjdla$j>WZd&b8dqZN=dI$
F=YHGT BKGuE?GcA>8Xd>AJ=EpNYRbJeE$HpE/Ebi?ud>&@y<Cb<tyJ%p+E=GViVcaA^Dl1:lTe*8=tHuFtVL?M
a<A*dW nnhS$\cH>RXCcM8VybduDC%VkII8?by148D5FMSw$way*Am6kc&b5m\6\ZME%&eF6%J*Y16yM/ZaC+6R
5+Z?%6 9NGS1$a/ilEE*hDNV>m@4!t#mj1C:XybJ1$ZED8ji1JtFh1#PmSBNRS5$G>JStdP\eFnPMy#CGTRPFC/
<#NSAe #p%R>@Y?Z+!^BuB&1VeHC\IG9#<C4%X4!W8q>GYHaSNY*4i#IEh4NuRu1EJqaQVe66beWDw?GR#VL9Yl
p4HQDj HCMN9@TBaJANJA!Q4D1Yi@nlu^6J9>^BY^daB&9y*6tpCWC\1NqZiMHX4k6Hny?@q:1Td!?k/aG%MJ/i
Mtu*=9 *uEj51\LB#D$Y&wNQn/88=ndNj&^l>81Z<dcCb/FHD4J@#%4Y8d$Hd&Wn6ch?y==j4N*aqB/%qdARwHB
yhXEb6 <:/w#HdnLBwBZnAy@P=cMqGj?=FE9^L*uZu&jw95*NCXqbTL>=8I<&+aeDD//<S=b+*?a5IALinWnJ&5
uNiBPD YQj</p%u+=Y9:L5+/I+d*H#$T9V/\ZnZ\S<4B=9%i>eew@ZJ>RRQB4!JGEHHD6i$!>>@D5\=a&dZC*@+
LIcLGy D5ZXjkA>eh\@$>$PD?FYX?1qZIYyZ!j@PSJnN?JiTZ6W%8G?h9ASW:i+yGuj?YF*9q>@&jZtjeX:NMwi
wG9XlI %h$\QH&nPG/kPjNKj#M=98*\n+Num>hjn#<%Fu>$NJ=*@hGhZ9e@d/q/nQ+XPhb@iBD/5/4++5*Bp&Pp
K9Ba!p ?#hZ@nXpi?9&%k@nn!^9^6?@Z9^ya4@G1HBN9wKMjG!qIh<=Ke?/@^P\kPAtB#VX!E/V+*?ZQXacKudZ
?nCY%b BQ6\*PtqT^#<^XX*+y<P9dImiZDWuC@i&<&<N1%?@ZHc$GQBQ5ee&TZ%P<XV4ZJ:beee=h*Q^9bVbl=c
aDc1K8 J\HQhHyJ/LY8h%6q5Icep@TB1S?=p*dGK*:@p@j%>8PY/bwqGCBtku9CQDcu4>$YN#&McTuiKXl:<ti*
^qd/&I BaX=R1A?=44n5j=&56>HNW48dd*4E>8WqYVKCdILj*95u@YEQhK9ijVZR!Zh%a?iGM*XpDRXb:Z:@@n#
*hShtY y&D:Hl6C+ip@DV5B&P5d#a<Xn%:jQ4Dt&T<:^W?V=+d*=y>pQ@?%@wZHV=tu>>#cy<<8qaiSlXAIVS*w
tmC=%T i6c6@PIJ=IqZQj:t<ShiVjCjReAdWG@YXJi41V%:\AC<wKdY9+QB?^QNCcDM1aH$eji9e\ay8q\cjpBG
Dti6b: hNkCX^TF@:#5J+>R=l44/%?/**wBVTuWp6**Ii>Yt&%ZAhS\9Ih#G>c<=Ycw#SL@QHDjdycFb@1yCYJX
6B$BiA 8RtGj^9JbaM\\Wi%C\6w4wYKuKMl^!NqGXlISaRB\^YMkAy?pBSVtpDBw8*EW<NZRM6jX8b$HSuBAd6h
m\aWRi e$CCa>b?hw+nCebI=GKI+AVy&LwF/Eh#&a%lSVtBpc165MDQc4\^\kPMTR$k:!HCpKCRGVVpKQEGDSRW
YTny:S M\XIyI^wM$YLSqaIlwceJ!PXTjSdJIl^Q=wek&+F?LE8w&TTw\FBTi\%t%/TN<+!N6YLqHG+<QKHq45M
GFcL/d Q@^dZ#QWT4we9YRpPFBw/^Baq+/>nIZVT9>+8XhEl4kCRF4pk$jQJCj&E*%\%^&mTi44qFFn%*VAtTnH
GGeXF: &4VIG$9Qn\H1Eq?K&ycqu8CM*VGja<ii&c?5mH/6iiNu#^&QA/9\y$lqYM+Q!CM#E><+mG@&=Zkdy:k<
Iq=&*k SQ@G#cE:DhMc1bJRp==t4#N%HC\NY&9DmiPnJ!Wb%1!K^ScuA><P<6k*@ml+::E1C>>1ubc<RhWn:tl%
d4H>E: #Lh?*R$qj!=8it/+6IA?pmiMHX8!?Jq/H*b?tQK5?=H!$TEB/<lPd1N5V\^$wpJ$S&XLPMuq&IeQ4y1F
!N<!#l MlMBlS#%!tVtc=/YwY=Euly8X!9FtcQ9=/QC1VbYM6&EKAX&F>pM<!+pq>WpF8X1nnBw^B4=R6G?aVJc
L5@q66 TG?/&e%CE4\\Z9t%:V><GwE&DIa1=H$nwk%iVMVcXHnHl^ayJVN?iYl#Zd@D=M<X5Zdq#%@m%!uXLEnk
11wyRP VW@Z*J+BDKZ#NJpCKM@TKXpWEFCMXpMdZj5Sadm8tZbwMIW*5WZ>tu1Q8<XyWKp^qMLAM=L^jwBc&9A<
d9EhpQ n=M6Tb:XT!ZbB>TcHjT?ad!tJHZG%Q4EheF#VCPkywbF#Fu%$&1AlR%Yq+:!bAkI+plE&5/d>mi\eMC8
PXZNEn ZEZFTQ6CIKHPa<i/5pMQ/mNWBh%A#N:$EdK#ntC$E%CunK#M\GhZubk#G@da9y:\Su%<Q$ai4yXF&#$C
&A<Sui pJ9<PVI6lHB4:$HEW%ehu:$Dc^a^Fd5SZ>S\mTM/hyWDWtGmMCtIyA>4G!#\%uCY8XuR*ychelCBnjEH
FEqRTX >ltBF6cG=QDY&&bDt>5!H=%D#P+EWS<CQRnMq=P#AI\%w:LQJH#PDmLd>*&:#^#Za9NB:*S:m\4%mAJw
Q^dBMF hW^nSDQa48iSkVuuqp?G%Lu8Y@QejL^VD$+?j:ldNW*lywZ\pwZiE$Fc81tTc^&hGVmApH=8h6ukeP+#
y$HI^p ybhe!9D#FNt=jckQ*#\Wd<!Z4BHjl*lHKm8/JT6!k?yQPP+YB!^:9EH8@aY9=kEJcG8RH>6ekqB=qaGe
lBMFtW M=<wjTn=bZ^YHjHN$JytQnL96wJDB+IIcGp>?@Ck$6c4<R@9+y/?J$NR%/6+#!QuC>wZC%a$>$>ea^PT
T>=kqR 8FuBaPD=&%cTq?QqYnq!QEZ$8cQN4WdL#9Zi!tFGZb+n>u9u!nV>u#p4eN8yZMDk&KIcTk*nBcQ9TSMp
nZ?I\p l/nN+VZ<bqJ&DBi5M5!:B\<A*hA<BXRwQ9Vci/ZKD6+!bChR:iPVPE?Y>/*WnMAVjITt!1BIXDt^F!GV
nKGn>S llit#Pnn\hcH!AE$IE5GTkn>8J%>CHmTXRpe9\yNKuLLWPtFGb+Gq\IYD@4M5dyE:Fd4ZZY8AJMIKSN$
Y^pDYn /uA1a@JV8mHqA%Iuw+Lec5J\B1:p!bJBFF<Xp*\SVY+NE>D8cM?Pd\B=ue4iHE?5TZ!?!GYhjuQThcCp
*55^K+ @TKm:*cAL\Cw<+kYeEKPTTt>W+P^>yD&>CLhh*t9KtE$&t<^C!ejPEy4jc\PbZJDBiPV$19^$QKqaHhE
e9Y>*e kAeM<tNb>$9\jJ9QhX%ye:L/^LmB#<ln&BDcZSp!b!MbYaYM8J#pu:iIq!<APPmV/NH8V4nST#Lk*ZkS
Kn4e6X Lme#4*EQ1u9VjXZ5j6pn<!/REl<^GFFeE\H=%+:e&i<Z^u?+IaJIptHiu%ye>bWSm!I%!1TS!i!kEyD=
1kQKc* p#^L6B48W9Nm%y8ym9R5XP9e/CIYCneuZ+5Dpm&<m?DS^w<kRP&\+RLPlVjZZwBTFQ4L1YlDw*dhYm=Z
>>qI68 D<HWAtBLWmq:*k8C@/96!CNZ?PRdQdWSma/m$d8T?$TnqQ+LCX6&pZAn>q>DK?8?P>AeCicj>4H9AkB$
:$KYac /Jl>wiwEQeaT^9hTuY%hmSm*l^p%d/kJL#Ly$N6$CkC&weJZMbI&b5KPXGj9i::pZEh*4J>j$wa^?^Va
l+T6HJ ^FW/IdID=Zdtq4eX$T86GlVCQG+9bGYMIiZHj5BPTQbj?GdR$46B&wL%8E/@1H=&m<WqwFAJ8Fh:/P*W
1b:6e# y89VQcFm=Y%\\h6DNc+/YiqjCc46T:bq=/1MDqtqy@4%AjTuGckd+%Cqy:%G1w9JKN??qaCAVX#6d?a5
bikQBF ^LdSbGPcuP>%wbCBw$Bdpc6k\w9wR/QnAGLCH6/FGDm4TWtS6/Fehup%elGKWBc<B+CEdey=p=B#ywK:
-AiTnS 000247acf9e00110333 Page 39 of binaries1.zip
&C*651 G:aYYi%hk=!%X1?/&^M1YJnY<P6Q1mM$lyZ$GiQpn5n!CV%nbKQ:%S:=pInAlwAL?$<\8#$iA*#!W?CH
Z+%y$K kc^a1?VDC9=i/lPEj:JlJiihK>Mw/ew=W=>Hp@t8cKq/BkNaIRtwnpEKX?G+Y^=W@HG^:NEch\CeYaXn
VbW:<C &8PS*@WNKeMH18c?^ENYQ1q+^6$l@tBQH\D9dtdk$/+><t?MpXX+mpkRnHuEI=ndFI4e9?P/nK<5yjHk
<9<Lp+ m5Vu?N4YNMDam/^IDm5X<D&9Q\/l<AA9md6998$QVi&8H+t%wKE^\<PPAtXJ1>n88$8L:85uXwdhVp\E
EeZX:+ 9Lp>ykA&ZHuLBqC?5E+FMSPSJTVm49i6AA^B5yRGwu\+:WSI5\PC><4*Pnq&ep1lRSkZIqlTNjJeaF9h
lNKtJj I8DJpmbRwJ@6w>W<VSE!P>:VK$cI%:IBKR5\aL^%KlXI4PHL*d1KQGep5<D$P9WkVNmjZm8QWEJW@jnV
QwlHRe =y\cmA1nQ<*ddDQ\!q>E+L>:!Qek#4d:K55NqeVAV*YGhIPA5B9P?=1Fk&VSQ?Xp4il?ZJa<>FL>5qwB
I1#y^/ b8@*CGhK\$W$kYEyHCj$?5\ZKAHdAdnpi1P+Y*<D#!pcRw:Z9hy4KQtAS9y&S?PVmC51!P?$JiT:8wLF
%K6jkT ndD^J!89L:<m*pkeXc>>yMZZm64FP$l?SAP5dWDRnJ!<QnHNFC$6<:KEmSZ#bn9uQ@HlTQ6naeLBN!nq
tq6<KE &mL+AMqCXdHh<mwa5&KkMRH?RalC*pw\cHXeZhET9iDiYAW9TS9d!JR^Bi:l^^Pd#i9\>#?#/C@Wb^ib
id/Vu> =S?<pBLGQ6#VVn=&Fnd96:mX^P^QA>b@$S=J8W4c<tWE=*MS:9%X9iTqLW!tA??8kVSiSHc/RQI<GyaQ
/N^M@& IQCbI9ALjMSLLN5n&ly+eMbj8V6JdYTFGD$8q1=FnEiJ89QF$u^R\Rj:Ip6tqAZLK!Y!DcXd#pt=ZPnF
W4ZJVD ^p+$#HFELNF&yPaqCt4*kFIyKBMl!4ZX8:ER>k+BQq^C!+awm/X>Ype=GTl#L\Hb9IRqRmnCAK19KG=b
%1%Cd! nGaAWm?ENF4E$adJuXG%FuCT?yWFCY\tR=Lb!B#<C$&Dq8/pmcY@SQXIb:t8mA\FFitqm?1wIp=yJ\=S
6H16Lk qI&W?+9^4kKGSR8ywpTiCZH+cT=j6ZIWDXy1KHj:w8u/JS#M\I^E9=Em=P6JYWRI^%/MLlEL$WyFXMuk
LX@hTG QP#CDFRSK1ZDAFw\cwaHJ&<R!6kIIE!\dAtZl+F/=p1A<bu=qd6qMG?y8LSSiqyYkuV+4wVPqWy%wJ$q
9b?^=/ JVMJlH?njFJRiYq\Qq6EI$IaaSBGNVkWhk1jYhGhnj:>E1<Nc+!Gn>5K1cEq6YmIt+XTZ#KCG?S>84Fp
M8pjVA bi>k/!@S>#\BYRi&iBSC!^KDt<V5VcZFlRBw5X@=tDLZX#m#dZl!u?At?Rb?RDSm46\hYMI+m8yWk$e/
tY<cjt C/tBAm1/bH*6d1p6Eqlb>u8\!GcpPLi!<ZDdlVW&aGdbMqR$:mJRFKD15\Q6p+T5CL?/DNJklNI+RT4q
q*:^Gb qujD#W8e!=bXqT><Wy4bIR411\C^!JGXmD\nB>aBGBeGAN4/S9iXSuKQDL4A?SeEbA!MeXaI?iBl*KM5
&>GBM/ =W5iCkJ9X1FycH5Htwl6lydmiph^qZNVMtte1HQFDdj4BClc4HRA\4MT+W%<X%cI8nFmdb6#uaCApRa\
?+nZ+* h5n=JXAk=m!>EZH/nTZH<9J<Dy%dAtZbB>:e=JeuA5qKW1qHYYXYGja$lE\=^!mB5!!Xmk\qnVbCe5^l
1JPjNP BRDR:ARLEKGWA6m*A#?\\h^wp<c<&:>HXwwbT$/H:hM<iQyqY^:@SAuLI?N>&Rld$4p>4MhX9*haBb%a
#jTql= S!>WAcBmT/blh:CEdI#c*A+9w5KyuF&pJRuZpQl%SttBLI4@Dki5yNKXXp6D=eP@kBpWG^Q6GPm@8\\6
@ahK6y IK<5W^nA>/&ETC?PpjbLFKTd*JdTGRwM$ACAPKZ^LHknK+IMIEjmcVPDJeHjabQ1!PFLEc*9T+wKSD<%
^k/D$B P6nBTmPpMK>tSKbDnh6:Zdp4uP5^>k$WB^&h:D\Ha>tYFIWT/ARXkIn5ZtWLyJaC>m9\B\D=B4BSE$1&
K+6IMD k!qkeD$lAKIkH*16&ReS!5XmN88&XN&l@^hKHuDdM4h@=lm+@K8WeRBann:h8%hAN8%B^=#YP/E$5ypw
$1B=M# !:tyd!MlB:kXRTEKC8ydEpm<HQV!RptjCX1/St1=ek<>EYS9Haq4FAAK*+9Fkt<#CPM9JT\MhJ6nJ/bT
^G8^$6 1e?@JM>6#+\BTLkHZ*C/ISWJkXVEeyTWRWKNbKKMB$8wnBI?BpFXlw*#YLSGKHcLA>486L9%ddTGaH?\
5X8P@R yD%R!ucw/C$C$i^TcTMMRbDTmcnGGwDMET?HRKWy$&m5tJSe&4eHwK1W!w%Zh+wF:mQH%u<9:R!WT4Q8
*I\\hI bPWC&=LPnjmYnSMH=LGTI>5u>/*$+KjAQVJISSu&6>R><wlVhh6KnkSLPuFkuGP=ZE5CFIInB\SwW?nh
HV6e>< 5@8yuFK<DmLnQjbDyGM*@6!mGq#$<+:CC^w%X@Jb<\RJJbY!^tiaI5\NIbC4Nc/G#N8QqKL*$G^Lcbq*
A?>luH >SIkIEQCn8!jATAnVuAuhTlG=aH=6JkpFdWhZDQRIFDwIQj9eWDDqHyS*u&J$h?R%IZMkW6Zn<ll\hw4
b^alH% IWwHh1MbEMBdk\TD!>cGLunC8S8wi&&Sm^TW/#JwjeK^Y#$k#@1wyRS\hA84>=FimpBaRMZhNQRC6GSt
MY\:@L 5:A^w&=bDXteAKCDT<itPpiwmPZI?lF@EakR59VNFCYREiNyXk$+<DPAHkV4qw1FBwdYh\kk6bTXH><#
hkc\1> n@!y9IilN#tike#aCDEeA\Fh\Xd5ubq#1EY4hh>hI<pHGSQ1aKPPtF?w/C+W<#YlnSnwnDZIMRETwABA
cBR\je LX*RRb%/Wh/*R#mdc$ejBHW>JnlJcGtwDVi+qP&FBA$Ry<=HS!RBaKB+&>?T%k@S:DT$>QidY!Cq$c%*
KnIEVe %cHwmN&ADYy^c!pyFEqQS4cGqC*\kSuQl=5QTWc5lI&4IM68RuwKtAeVT/t\5/l\Y9AEB!*p15FPGCJp
C44^Q^ PRnFNqCcJZn5HMp@CF5wVqS#mTV6l&<ulZQ!c/YE9YlPTb<>BHTSjQ$<Vn/L1tYX@4RGuFeqLi?H\llw
DbV9JG ch4FG<h?S%JTY\DLW^Ni>lKm6$FpH4c!@bCSNKHHKYX8YMS+EIPiGZTKL$EdwSRlJTNEt^V%ypcwPM<\
Im>&5E EY<:<jcckF\MAyGqnY69aC^lPNJclqVW8c+E:+BkdRC=?V%wS!FbB:=LV<THA#RD!A^J5KH*IWCe+EV1
A/!$95 L4n@VqRpPSElw!GeM?a:D+nG9abPWD\+I6dY+4a<Fq1c@*8%Jcn%Fm5+JW@#qa4IEud+a:Z=kSd:E/BW
5AYQZ@ pQKN*ye8pyGR8D!lNESIWp+aB$V!dDA8jwWWAJd$+PHdWCMXADXe&M%Ae6IFwQ@P94XR6Y5D<w\R6AT&
Xbi#!c IBW5A1XWqBNaIdt^VmT%km/5S5tLEZtcWJaydM$BPCMe#jAGbqnmi%5pm!\9JRK$/wq?>l+L\Qw%AICp
KZe>$n %RLGckuDC@/TZkbA%V6FCIbj@LF$SIBd&RLpFVWD9t\nID8bk&5FM&\+t%PTMZR*^:cm%p^<4jJIH=>d
w\TVh@ 6B<S98:WCRP\V/pT9ZcjZ:PA#DRH?$C<9bCW9*9WJyX&Fn/&Wmk1i\ACeD/A/NPFLqNQ+GiE^+hAKpVM
45S@GL !IYyZCt%Tk@!i6:NWRQ!ABljDRW+:L6:mpDjX5QRFbF<AZdljWY#GG<8jQyCtc+1KS<iw@$J@5^Atn5I
Gj@!G\ !hi5YLjl!^+qVVTh9HDW<my+HAaA65Li&y:\NWVVwZ9dGw<X=ViM4JXi8#6BF\E/bLDQ$/AIKkT\Ja&d
><T<l8 aayIMV4@AX64j8Duu!P=L#t%+Kq%X@EXJa*YaXSkb!hWNKMG5>pFApuI:4X<tWnW4VM84RDXe%&qaaJP
AV$Pqt NWVPybcbHNRmFdqw=Mjhny4JS+*#VD9*IXtF*u*+hXT^ZXM5kDaA/NtAD$jKIj?^L?XXpXkAdkSVQy=i
Pj1+?K Xt1bEeP9w6GL/iK*T%KGdt9l&V9M!>CbMDThLP+Pn8pGwDLc:Y=?CaM8k9+lGFp9B4*B<S&AP%A/a+Z1
M1?!Q$ V>ipH^QCu>m??5Way/8MRAYKMFnDLwDpCPPnIi\Na4w9kkaV5>NLFKqISu+yN\jPPkByhQ?kaj9k$5m@
c?9hhY @ScqSZ*P>IFw^CTIe\!k+1CpNd$Yw<l^DDSSY*Np1+DMKmFyXT+c=Kthid#wy>?>wyV8K5aHR^TPKIY1
1A<R*q 8Em96BNAmB^RdAiENA$P<MHccAk/Ddd\yyTpJ5uT$%\=DRDbW1tZeyGSEtXBM4BP+4+Lm!hBYT1IY?1q
#M*4&k SRnw:h5GDKmw$ePPQ%NKX+N*ip?!t5Y?c+@Ik?B>cm6BACbNFIB^RqwRWLRS%ceNi%ItBF$E:?MSM^=/
?/a&GE iB!mp!n/IaPl#Y!#Xn+nHSCjbWyp?FKA>b#4mmJ9LiE/I+1$^FJL?DkKPiIKa^Ym^t*BYm<au\WHnJCM
E+i^ni VRJc4Qp4APDm^>G?#/yDRRDT$Tk6di>KybFLG:%95HuI:k%b*Z<Cmn^kiaiRp=b11X:aLRW=cdH5A*e<
%Y@Bp: Kby@4AiB6ZBP1FkSLcVFk56/E9^cYBEAw=ES6TGAIqXeAhpKRmB#E<AIa8/1^wq%Ati&G8LN:>tN4d!\
B?%LH+ mN!::y%$X5\\Rc*inbH4CdqKApkS4MlJ$6=V6C\XW&N9p1Dk=:?F*Y/qdX+T^RaBt\iPP!BJl9*56E%<
<T&qa8 hRl>1&S=B/RwDMCVwcyZReARGW1BycGp6M&F:#%ISS6EZCMyAC@jFwKN#b1#j<Qw!h9uD#ByT5SN/IdI
jaCSnX AbCKhNIFGpMQeh?I*Ka!YP&VqN:<cM6h!1L/4$XnEC9AS6DPtSN$SZ1H\MC/+uV*T>8Cu>Yh/^>MWQIq
k!H%\Q ynBmSAe/IqW8VTCGYQAu:^&9qI?h?#TXjMGuYY=LNkjK#h18w><*hR!:QVpLBk4PF#YM!kNe%S$LeFVY
BEK@Nq $:dG%c1hN$eh*=8c?^A*B6nSN^4=bb<wXy5>wk*SjlWS6JQEK1=CaYV1n/X=i4Gih^>8QZaMG:E>919$
@*E$?1 LS&&$RF:w*DTGm=hmAkGNBuA%<W6j&Y%q94dKhR*ZRTY9t%n\@B9VSZ*pMaG==KPP:\<TR8<w5h@V6^e
*iGVh> eAh8PFw^CWS:iF#5WXy+<Pu^bB/Vp94#k6l:i=htT<66AGZEAFVlEDqkea=%>:4T+JHG=/d:cBdB:8/&
X^65c> iABKPn^S8$1hhuSap<a88Rc6lKuLH%iBdKK?L\TCaRQA!&IN5A=&cI#tyj&RCTLcQQ?$EJ$/G%SPlnm5
G!l$E< GQ\IP/IM?uNMXI!j6XbY\XDF9ZW*GC>HYRh9>nJtdnGWL1j61abj8!Q=FB9D:@cQ+Pk&+\!hmel&&jdh
SMKSqL \KHb5&ah!ZcXM%j8jDXp@L=J/+wcM/jZIu986m>Rt+h8teLRnpPJbIQ!eKMXHh#bZc=69Jui6JI8X&TB
@CRVK: hJSYbLT4>>5c!14=#qlGkHZ*uA:SCWFdZRE@a/yT5cAAP5h5F6#CBKb9Lmdc!Kk/<diX!#yXH@aP^A\R
ua$%iH qZnjmmQtkBQcDjWL=cVhyuuD^5BR+<NhqXGS9#1WBt1:>Nia$@S$:GJ/y*bAW:N/X?qP@$JZIdCE5:6S
!%ujaK lkQ<cw#+1@cYn6JcpeFS/p\4@W:b&w*FB$wu*4$L6ck%$MGRMlPD&=acE>H8Z1$B#T@YQNt<9:Kq^hjC
JHI5&n c<Lu$PMcMhj:\I8pD^/6/djGH*YkW$881R6wu\1kB\#J>Yk*8d!\iL<S8*lD%i*#uat418=yFZe<Y#+R
-ASMVS 000d1af42ba00110333 Page 40 of binaries1.zip
k9^nW+ qB=*wGBM4<a+9CXZhc?B&a4#L/$mh*/hmFRj?tdVVP4&X:<Yy@X=Z/GFANK!:6K=6L1#/ZYlP\?St^SY
y%@By= q9X9l<KX:HL&Vp\GAq5MylhH8WwuXle<h8%$4cI%Pd11V8&Z1VV^KEPNN8*!=nSnn\W*=TdV9e#uZ=@5
@wWTZb cFqwRA\&bCc>DLhlGCYH^&D1$6j$4+aL<%nKkmE*81P!tXuHC%FekRSb5?idX*dD=T9mS$diN!:5JLVq
+qLSW/ lWm+\XSaPkWaEAHCQZ>AFd^Ye$d9LkC\inE!A>YbSah$!/Fw1Q\#WLKaK/mQIk^qVpL8DL!14Q9XYLZe
^Dtmu+ Dm>JtTZI!X$k?n%Bek<1!b<S+&cwt<1GX+wHFpSNY$?+J!?>FPWyQn#knIpJH8hWjhm4@JW8IIeWXPk=
jZNkSX K/1RhRkLLPjB<B<LlpiM!kuNHelVD&H*q%PKn:<!MKkXIuE#?@YlG&@D/k\>=R5!I4nGBnp\1u#6QEZ=
?QK^E% ?RLH4+\aIhGilyPNk\*IB@TFDAd%&l55\KX/mEC$Hw@!^::8RSQn8B#6y>$4i*4cBhiCnpt96&5JRdI1
%a!j</ 4LajchljAPBd<cWaQhmNaL#Xq^lQmKGd>HD<a?W<AAjmK@ScPT+ZAGCF=FnYbwJd^QCH/uKA6keA$AEa
kpPwEK wIEWN=P6!@$BAPENlmWLXBe8$jNY+#l$IBMhVF/m%EkX8!AMtC/5aRhc>wWK>NH%T^+>BmmVXDq>NTJA
6L=\GE n%M/c/DM6KPw*n:le+h/&!m$ERFQNP>HR?1X@Id/pIwjKCm6#?+1%%9XmLl>Q/*XnD4=FbwwD>9H<>TE
*%IPqj H\%bCcAlAMSNLKT/EPbpn5nFjLiTGV%6*9^1weDhZBS?n#lk&4#9$?YN/BtZmID$iXd6NV<=GRbRDlEI
Li:h:C MnnTt^YNV&#*\u*+RjblQhL*YmBZ%j1a5edNqLkGtt1dV+YELihRFdI6ACHS>Z1*qlH+TAqtl@RV#?^R
jn6!mC p?hXw&cNiIckF>SeqFwD>BpNWpE>*4IGRJAbLSVBhbJ??JY$QLEH^m>w\B4eK&i9tRtBwSW?YTtCW$>\
>mL5>F a9RAEiAC=dX/ARIYyM%=jZGJ6+GjuBS5I?KV5LWudMw+\I1B+E*kitN*YPPZLdQ\9Mh\CZLk/%p%Sy%D
TdRHaC Yh$W>S1%VFNR@H86DpWJck%ZDHJkYL6k*TFYGh/wid9Pl#Na&=qM#EliFPF$IhH4i?@kAIem/k+%9M:>
A5&9JZ t?V>mImmJbiYFD%e<hS^B@CB:P#LK6dL+j8AEE>5q@aF6QDYk>NHWX5E=FyjmMkMR#E%>P<J&$<b$^ED
Z=#uXZ wVqC6JPGpjniQltwb9e$S<qtn:JD!=kTWETC#R%:a=lwJbB?ARD:>GGWH<yCGk4SNpZG1VhRT^kI=W>>
@jdREn =NKBd\T9#tVIwF+c#8/HZdP81\bb:eY#mARVu<*VGu*DkAm!/CbBBt$C$N8WT>+=IMpnyMNlYL=Mauj>
t1N8V8 cK<K8hb?y^*NhdnwIhK:&XMbRqMSeRa$Y@6D5ATJBaQ/ZXQRDVWmFhHlV>ck%yC1SG!e/tn6RYWiNk5k
5QGhT! wAq?yP&+%p+CmbtkZEwc$C6BS!6>/HcZkFQ1?Di:EL>u!@QL=ZBlj=8k:m^hMH+qA$\PWdX:6HJE5X5#
K=//@4 1hmLeH*H^VKRtKL<\\*KhQa4ZZDSKqu&lC*PPWQ/LmB+#i8F6RbtpZ6DVZn61cy=WL*TpYJAl6>T&uQI
V*bcTX CZG&dIKbuq6yy:jSD@%Lu@h:VkDF&5^bHh$B44=w8#9AGMFPMGm+/J%b8kNp+upIQB8/jyS?diR1Hq!p
^1R\I= Xp+$A>j?<k:^F9?T5Z>$XVjmN&$WSmN1Ydy!IB5J?KmK8ei\yRwAB&*iICp9$XQy:1Vqpk%1BI5E?Cd^
#^mnKZ +yMX\$YCE#1n:P??RKhVBYB5iyYXmQFmSPq#MS/qji%=ekAN:@=:dy8b&GBC=wj1uQpJ##NGHq4+9cSK
Sp*$?m hATYc>wQLdn:?*Vl>Ya915Nt$VBiNbdhtCyPaY$CIe!Z&>N8NanpN8%Apw6k^F>=cQk%VGcl@yEGAA1>
KeA58d cMPlAqjwuX8EkaiP<Atw?SNt=Iw=H=%5anYEIdVLBS:jl^:TXBww!phVIpll>T6tF+n#GH&+BidEdi?c
k5H5<= l&kGm!AHNPZ&RHc6Y:bXLp@VlbGkV5F1C1\$n?6k!CSm#WNnepLnjJeLw\9n%bAJG%\lYFCj:hwmVFk^
RPW1mT D?wD#wTFLlhiK/R$=**J6*JAw5Me*T:$Ee9:S5%WWCZH$PS!qtJMe@chLuMbRaqZ+jZDB1abDEB68Phb
8JG9kI 6p:iamk@ZYwKwdMk<%1#NAM=X88qF\AI>XtDdq^:LeW#!NNCBQMA:pk<m!4VGXkp5BwbLX?$Fc\4j8XB
C<A^/! qd6^aBRkN%#VM1I*&\PSX&LpWq*tK$CX4Qh8iNVRGYm=@EDaAYt^5bGF\lS\kF8p4?lWBh$BTnPMeSp9
mPZB8+ GMELJAdpLh5AAA9ykIN8&Hj>pjkwW\lJjdBcn^!MdEMkY/NIApjN+<6GnEEI<*aW<8E/TkQ^:S=$1%jb
!Fu1wW \HGN\SmAtaYa9a!C*Ea\E=WWB:B!IbamI9F$kNqRTI5:tl!q:VXt^P#Gl#ba?HXKDF&^\kSmaw!/*E<d
+!8#>p NF^lSaLQNtuI1+<dP85#K>EDPpaCW%$b*NuMb>X5A<p9G4<iw!imwkEwm88yCm#1eINS5^I6=mltRKnQ
9c8Nt^ dMc$bJFcjtmT=\C=@BcqjA?#GD>QN#Ec^w@%DA=M\pHVAAWcAEPS=C:MRA=KFk?uDMIahJZbH?y=Z@St
I!cL1S 5%aMnGn#LtMFP9mTh^1M*Vq?C=nT&L&\k9<Zij<b%hVZ>@9CK#&EBAIECCFAR8<GCBB/EuwQ9YNCp!:T
H%ipp\ ^L+TPmICI1KmJwAI&FBSWXEV8wkImIk>ICy&:Kn<@V>ii?>#>6n*hh*n9y=>#lqunPjJm@Wt/:9KtL<=
SYpe#l %=##^ieDeFZ$kW9RkZaE>dI<:Di>8F%FZI?q@D#ABPDMp8uJ:XuqWwKwBABDDM8YT1Si4j^MLitpy8k%
&>Q\#: Ya4FkuS=<IpKQ^<t1yYd@/IPwFZ=9%Z=JXlIB$CbSHa^dFuh<1\D?e8QN1L\L9^/I:hqi$p*BB\p<XJk
k%LV>j pG!I8B6iMX^D1aJ#M>H%NF9YNRW\D\Ed$YF#wh!4yy<Xhjp45q^94BnR+ni4miISI4TJ<J5C=RpCW19M
Fu%qcc DNjm85p^Mhl=NwKbk#M!hYR?ktDQA1NLPp\BT1@?L&EQuC>XAkR\qpBSE1yPTXKubCyRX4VEjpTYw4J$
6SkB?a @B\\l+c+pjmP\QFcHjABnqi+q?%Y?@\EZK19D>t1B:bwmwXjY?HK:FAaj\EyEin\cFB?WYVhCV*yBd^$
%/iBXW p5JSX8jq/ptjAJS^tZqFqFCZ#EX1TSR^+ty%CRpqCmj+%kCKHkDq&lWRJQIX:aWChitT*LQ6#pG@hXmZ
!XItBq nj!IP9^9m5JXCF<A+/d1R:#$iATw8JA\=ckyaRR9QNAc?mRnPlW^6N%&jqMAaKQQ<!Q#TFBY8BI#RJY:
X%G=n9 Kk?bSM=#5JJtnF/PDXWPw66ncQnG>Zq9M8@>S*AYJk%RyY\t5yL\@GF%cV^MtA<HPPyTN^E?ACbPli%%
!8NtYC lwtijA<=5FhKW?*u!k$c!+N6KIDkM5>%hP<tRYw96icVKCY@:<ABRw/GtNuQT+6\5<Q!@RAIwM#enyZW
l5R8=a 1kPkHHMcKGeCRt&%a/bKXHpbCb1RhFllukLlDVKF>>h$45F/jKSR9J+Yu\Cpu@CWMyj=$&6BRF/cC*j4
9jYY$V 6Si?IEqe#jKc9Zl\FDjH8G/#4mSiV>y8!%\pe#5$IJuim!BWchp?ejF9>AKJ&/dR^9A6dpewZ>B>YW8?
\$hRkB kIW*/5KEtllS1w@45AH5BMCNl!H::MZ>PP+NX?p1\el$:/9+%u+8hGAaJqXS=BY8yaR:5mcJkICwM\wF
$e!KQR #5wZG1T>iEAGNNuCMQWEh9Z+=9Z/XR4Q^C4#VZAyG?4>CAC1qbtDc1/b!yVR**eT%:ciwXBQ/NGMpV\&
Wc#^XD /ikunjM4BHa&8pRjEG%Y6Vpm*<L6he*HWCijF/dCSKN/W8Y%cW@#8T$+CEibT6P<wK9AHIh=CB^bB$mV
ynuPtp FVdmZKXnVB*\V6:Ru*h=w9i<uA\NS+8RBG11muTqkH5Ced=Bn/8Q4k!X^&@qmXL$ISR>Ju\4$^/S@EtS
4#b$<q #bCnl1wQNhKFQw<SNBi^wWdEYML54KK+X?>dD+bP%&E/y+muEXTc%n^HYZ1aTA*ARJwB/nCeFc#CGn5l
\8F5<% ha<VLlCP>yKWu95J/QJ5LmS:5\/+DBHV5!S6ipGy/q>KhJkV5lpH@JNKbIEjPqAd#Rl:bu5LHFVSwR^+
mc8d?C C8B+<RpWAIXVGHlILW:WwklSJElCXaSR<9!1uD6WB!^E<&dMYS&IkG?PVEH@8a=%9VwdyRB1HSND:aMC
4ImAB: jZAyYpXEWtaqcDDN<j^RVew+>p*jApbkL*/4Pd^bH8FmE*/a6MBX$Vtl!9TTAiA*E?JJ+q+=$ZbmeVj\
lSGy8C =>5uZ9:ABhGSH#IdS#ZumR4m^bw@LeJwY<j>ERB+:YSP1@C^JAALA%j8TDin=8PXJCYc\mj!pBc5yAkA
T8ALjI NNWkC^kkHmw>@JpCmSS1ynGh<6M9%iVP$4Vn<T*N>6\K?V9kYm4ie9KJP4hDDT<GIA>R$#P&9Ap%/Tmn
?d9Y+R 6S*FX/$j#5Y^%=dibkKT>/4<jBXYqc5pHW6NRw6/MPP#GQGj#:GRBMDZQB6EkT4p5mZa+4RPM<8qLELN
byWXLZ hn6A!hYWLt4Np/HWu&k1G=A+wpSMFa1XI:NcVVaaB^a1YaAANbi+?P#\th>1@h\pLqVyDEbVPK$MmyYq
bKwdIh 1>>/wDy<wcIWa>BCJ\A1q=>ZcEaMtl$>yM+V/KMycPCdQG<XJcY4b45yM>qEZwpCm+V/W*85>$kAm1at
pPMjpc +V>H</E&=\J4hPhS4R&n/kI8eTFWmjF$Hi\*9neAwNmVtSnXBB8a?PC^plq=wDDt<@%Et%SF!Z\#%BIn
V6KA1D wt5KGW4#jkw/cAZYDA1Tn8Hda!t6qj$QAGG:SuE&jySPCYI&5RMWb:#kjP&#9EIwXck<4+nkdpaCcCV#
!w5wXy t\L*ARJAa^&$#aYnEN%l?Rej6d=%/@%e$PEKpK\eyNTbeJ/t^<>9b!RA%BV$m1ai&P?ueAGd\FWZ$LZE
&T8KG= hCZ8Kl/e$/1cRIk^Bkm+Mw6/bcYGBY$Ddq6hE6kF65S4#5TTW5uy#FRb$QepH/4E:D#TRwi!%kYtpHAR
>6A%eq %XLZVLLw#+nh4e>6!YN1+!YtMIltGiW661WDSe&<$qwIMP?jT@CD>*Nq&wk1$q!eNF<Dpk1EH/w:9>YY
Pw>mdI N!Q4Z86\eE%$+/nT^A^<d:w6q+5FAVui:AdIJ?SAP\qCqN9WKd>@K%6abVXbBY*l=kwFSC:<9uKHP1S%
wPLQDe q?/jRjKmqc9#!&N4>!%#aC&<*Nb8kQ<I8dAM+WwXIZRXKShtBRWwNA#ZWqttVWZem%hF?uA*1Re:&n!W
8<\l=G 1tLdaKi6d&/E&#LHKlM/qC$>:Bea5FXLZhceQuBiB:l@VLi9nFw48@PB:9#//?%wHMRQ9Y/!u&ZdJRK$
eMPy:5 6F@nKL?nSj$ct?>jNhYF@Zt&H=d\A<?8>Ii1@/Ly<Pu1?&b$YJcc\Kn^46c:R1n/jT6Kkw$eV\A\D/m5
\WZDC# pA&q%??1%/1!L9yM@ea+YN>tL++J+5u5Gw!w4I#KWIW?N#VX6iXc!6?@4M5QHGb/!daPG+pu=b6Lel<F
!Pi>iL !@JY%y%*tBk+wRF+RaZyTFEdS4y%SA^kJP>pBq+w4$u<5&bTi@#NTj?4+dcb\>4^/B\=AAlREqIWJY=c
$ck19e @Q:t5qte^d\<!FEWp4M*mdBPT\/A^WNi:*wkGmdNlBb!%qQwYnitShT65Dnap#<he>Nq<6XpTtK?AnhJ
-AL\k@ 00053b44b4c00110333 Page 41 of binaries1.zip
ElF/IL >1&jqqAn^#Fw>BD1R95Lli&K>tK+*Ac&LtZWmQqVbPetD:yBjq>@ZtIMbSHQLS!h@d*XB\T%hPCK:!<D
&/BQD1 pHcT^Eh^9qGJ8VF6wI6kC$XSWlHP%PiJ:eeu1:S!H?qJD<y\AT*iF!%RG<bQ^\M<X&h&AV<Ac*Q>mVAj
aSwMm* #c5\6$qeeJ/^=XKR#Dc+//kT8whWijHqw1pYuGnL*c+A<4:AnbYM\lKnH^t=Vhm!XnTyb:H#bWV8qqbY
E#P5bT &8iuEV!KAC4$5dtj9aNq5ZFnEW^EppqwWMQ<SDKn6eTbMKc>CyCyI6E1ec>ANC<b<%RjHC9SbBwcMbM$
NlFwF% JV?6ad>qIZB!Y+AiX\njWnuHC@1^$IcFNtl\wSRAn@:Th^>>ci$:pbe+$=D9KtXcA>ld?A4N\XLkddah
E6H^\m PcalaX1NWGMKtCNC/9j<NIZ?4T5HSiDl%hMtFRB1VGyc9$p:&nQ^yMhSKFlyZYpE6=l^K8pK:DkAdY%/
5b^nM^ JPNWn&Sqh8qB#qn^AXMA?XZ8a4LIW/Nlb>BleSnPJW\ZXY?cCi?iA&!*ZH*^=aKH+wpG>/P9B:d&<$/:
aV/iV# j\444LDiA8+6QLGZMu5n:WCtu11F1$#S^Qnu4/6LA:Dp5=Z%q@VmTyH4NJEtD>Sl8>BQ&P6P9iyZD@VV
8*Mi9W CF!ZH:q6:!PNikcimj#ydba!LL5L:A%np>/:I//jWd&tmY<Sud#@6yN*!q91@ub?!<bVGLyZ>yQ!/My1
8HL=/* W%dj#8?VtbWu@V6/\5w9G@hA?bwm!5@y%4bIFMSaLQp>hDk=Fi=+N1iqXq?J%\%XLT6bXbZZFc:K@i4#
EDyn:a c%wn*+I$Yw*eK+M9KmK$b&#iYGHlCKWL8qnGnlV*GiMMiH99mjX4DM<+p?TCGNMli#4^GHutB?mFNinM
6S#4k> 8n$pMb9mFZu6YWLl+B1hlFIL9##haX<%9@&ML%eCwF?kB%8n4C*Hp\pQHSlMwM4&MJKyl:p>V#tAW&jQ
5QFCi? BXyjqaNN>KF%tq>/Gu4PhJ!ZcYq%hceDEGiV$m>55VP#b?9k$/8lX**/peCe%?dtFBDaQwqlHh=/IGu5
@JHc+X 9Si!b*D=!pG^uYGKnV\HWNy>F#91D1%8Tw/h5:41%a$Ck#D+8T/q^c@KKt%ne96#lChhL!yQm@HI<uQ#
lGdM1A u5wGi\@cSLmmt\LW%#@t*pAuhaK*:&?Mc:=hcnM?dCJd9j@wqq+dZ5CFECGRnnnTcJn:it$E:qM*YEJ6
hd#N8: %mh!Ietd#Nm<AZ9RNin4Xl:pVLmBC6i1bRA<l@5b8Hh<Q%E=cTPmciB$?dJZTw!PuYcj!iLw/1@4KMcF
*dY6/N G*#t?KuDICI1Mt:MeL=D&jl!5Ge1nE6e#D6elLSyW*l\Ak+kQmy6*qKHF@:wdm6tqME8H9XcT<yKt?>P
EdAw1+ JLGNuP*j*A\mB6ZpLJ\<$=C!!XD#jY/c&+i*dcY/=?ZG9m%XAMIP$yc4L+5/%>D/V=YKZqPKjDGbK4>V
n+bM!R ATlMQykm^^b@##Qpi@1HBM!#nAJMH6/kJJQ8<wq^*+y&9ynayY/!teaGlb8CX&VSP&i1VeYQbG#dlhVu
KNHp!S Z*w8>iZ9HD!VE/B\eGHG@5CJIS<:5u:H&S*tn&uee&/iy/y9:Ip/yXeCRPWQ$!y$iw$=t59aMN@:WMCX
AZ%959 hd6P<l+:KZSXS&<FEM^eJ%jKbtSmt#:!nA/TP^tnH6AuNInRhie#%?q!CXn?FNy\cDTdCFdwIHk4B4HX
E&C9wF XF%K<*y^nn&N%WJR!4pFFG<R\6qFNSwDJ&S&SXwnjSkSV6J4JEWYVRcRy1P+RA#!+@KVl>JZBmCV8@9Q
dPiuJQ RF*?E+Kq*ly1kBR1Vky>ZWcLKJXVynSJcn&M&%DE11CVJEKCXuqjP91VV!VVWFS$NFPYGnV+hme/DQ55
Q*^eM6 %Sbl9YDN=CllEnNnEjhy&KGteeZJwy4!b?QjNAjG6>???/6Q^^+JG#mmI4LG!HCe*?+elTJaSPWT<JKe
%*n&iq lDI4!$<%^ZYd/EPZeHKRyaSL^dW6!R1H14SZ%8<VW6D8^Dip+/QJ%#pCF#FZF=%aIY@b/SeQNj^k8I5b
#a\TQ9 WqJm:JJ5h%nl&cN5&TtjFiYKAFu6XcwjybcME1ipy4/hBIQe4GFNlwk^S:p1:@!pp84d\jQ\VbnqW$+a
1CG+8T b4Y5c=PVLPT%C##%!N4PYl86X+*LWZ>SW&acIRj\CBb:JSV:tyFd&tb5bIAGaDy9\*b?%JcBCJjS4uM1
X@%G?l FW^#C811ll>@JhWW8h=d6niX%G@pmFDA!9eZiYIY9ylW#Q?$+T<%SmIylJ$#HhdFkG&dB/m>e$PHDaTJ
hiT<t8 >G8qd/S!GwuJDKc/NJZ4AZny5TQF/HqHJhp#Abi/6BPW6cjY%HE^!ykPq8##B5cXRWN#d&IRkbu&YMD1
*ppm#l Mph^H?Bc6yMXLklSQHlkV&NDBX\B8\9C5DQpS%6Vte%tqZkAXX!>kRcp!4nXwyVCpdeQJN8qXZT9T?JM
F1\Dk* RtZ%L/5\N%He=mF#IL=I?#b\SKq!Nc&iB5i/W/+bRYc!1<?Wth??K1JQ4hbi=^bD1wD^5$k@DEyQdFbC
4wiA@1 GjHly<JSiK*%a\mSS/=SReC=^B&9t69&!5MyphMMq@/^HdnZFAl/e5mp4GNEZn9>L#w6J&Dt9I>aQ5/t
&a&>CI ln<i#C\+P%DV9LHB\6RpbMXW*%PwWT4dK+NaVqa^HIa>ejXZ#4S#BIVLt\kY#nwhQy@lE*:EC5wFHF^a
%u/411 n&@eI98$^\$u?6w@Xn6yYLpj4d=W4/^tVkE18Na&ap+lXkAnJ@*/S4I<&RcA/ipC=w^!<<N<GESIQ9ju
R9\mCB \<9<mEeDdtp+HqHS+=4K>cntp?XLD&Gq*ee$J8#jN+AniVA9jXkC4cAm=/RBe<qC&Jd>m4iFdT&dpnFV
LNyZu= =\m6Yt=LGn:8AW&nAcWK&eV?XD%ej=@DiaX58a4=d:hW*/ctS?nmlEFicpH&$=BqWqK@PwBPtCp9y?aV
m\/EVH lw8T=a5@GCmIQ&dIq@Z%uTY$wBa6@biZAPRC+##eA8MA:?/GC/SwkFNwAVbFaeE!Ca+XDIimm$mCS=Dm
1t1b** yJEaW%ICmkJC%4/?Yh+dwCh&%GYt%>eT!phjKqNu#AS+kPk/y/:aY8FRXni=H>bpAICL/Wl^IFXJFTyN
+h:aYE =G!55GTXLc8m&?aI*eY414a\R:YG95p4FV\\81VCB<9j8lZKtmP\$ZbaTM=caH:!MQ6upn\Enw/ny5Wy
S8mN^J EV8jH$ZHqJ9T6$:mZ!1&4IdkqpGA8SRDF<:=!qE8KML9WlCI&9RWISRC/SHlp:F4BF8*^!G<W\1ia$M4
Ba4AH5 D?:9hk#l!dGTm8A5TKckI++$+BhRLi=SKb<$>^Y4c6YhCTb=XZ\CtHCwAFyCl/I/NJ:h8B$RLEC^S9Fn
?=m1+5 &<$R4#e6/u1?Ci$Spe$EpuSMkC6Jw>>SCd8BcPKS11cp/&m+T<AkQ^A/nnHl&MmyDpiB?c45\yVFFtRL
B#S!AL !qWMG>9/bRB\qw6ECE@AY!uIT5=Q8RnwHP#ELZea5PEu??m!T4?ym%PSZJtaZkcKIJNa\R4lGA^KW>@Q
V/R5wu mNujG*KkilpLNi\G<dbR+naw\/iM+ZTeGm8w$KmaM!bT89qA6ByH@6L<YjyKDYTP*5*MlBiSD%&PamRl
Da1T4F iqPl>W%6!M/j#L#TcuF*tcFZeZeWa6pMcbHj5ATBmPXKItpN\YEc9ab<Q+##b$tF%AXTyAtyYIF+4Wh+
uR>DZ: b>l>Kmml\W8+XECIe=XJLq9tXDakTw4<49Y8IMGqE<JwtX4DLneLbpI!e/5/1@i6RCad!6E9d%4VTR9a
SJ?$1: =/hwEGpH<#I?SptHE:5Bed=iBRAwJpqP8Lk>cN5#=q4FXC^b>d68GdT#%\Xcm\C=iuA9mmwYn*B#Ak%X
u?:8j^ BaDu:t+Znb&=MQF/YRDKDIdWMRmwTEYA8*%**hEDZX@AZ*bZn#@$!E^CEBYSSW+wX:6K*SR<ukIbnK9a
Ft8yPP hGS+A/ua=&IX$<$/n+51MwAT</BYQdZa:DwGAQN!lM!Qn1VYDXG8FNjK\t6#^X?$tNZ?ut?*8L$FdeuP
LFW^4k ptXKci%G&E+nh>MA#!>wL&\=wX8y#P5<*Cl/EF+GtR\9Z9JqPFa#6?+icT8Ej$pj@4LH&+=WM1y?\/$S
#=6*!m 9+K&b:SB=^L/I4F4TlwQEkSilI4S>D$*Fy8dTk/Np8y8jHH&u1u\eVnw+>c!e/b!J!eD9uypLKS5DN9q
*Jy&:w @Xdp?1l#4IHyni$c<?5aY^YN>b&W>JV=K1\ZwGN*eu^Kap@/ty+cm#*8$*d\b9Nq*^NZ#A\B%PS=YKT#
5PIcN% S>?X+T<ujSdFN*X4@ZSK^kuhQ8PDN<tHIaB^!ck^BBJ$yD99/KSZ<W#+#e#?Mh$Vd4FHd/=P?tPuQFKh
lANep8 WMJ%ucQ5*dVD<DM@dDMNdyEd^<pVjpuu@B+>GHee<Mwj>C$=:R6ta&9NQi8&<kF>dP&&Y<$Z@YaiBdk>
#CCn*m >N$/ei9S!%5*Q\iWQAnIj#*G&I=6569j4apCd1CWXCb/F5hnQ+/9#kW/jku$:8L:jPNViCJDm?4cHF*+
b1@ASe X&@H?@=>n\Q&!E&$jSy@?@9&wtC5R@95ZB95Skw59WR\y<1BQ:<>?KyV>?jpLlqPW\X!/RcTWRhnltN4
apH&y\ GbNH=Vq@+aM\BmX#N/B=dqW4LG^6eyCVkqZ54>8EF^Pl1^QJ!KqT$6Si%I%qE&\6CW95L\W?YY5kk\/l
GjVR>t Al?nk:J$k@%TTq5>FYnqp=M*5M@%4QXWy+b$kw=1B=$*uV+Hthakn^LXP<H#TP/XE1^W?<TR@*Q4EL?@
c1%p*n k/w@lSSaV%!%udy1N@*aj9w95=DBw#D\Bt1$Y@B#E+cb/Q@P=5=S^8&XL>PH*EPn=/HkDXkuAq1Sl1*F
W^uYnC PA^=tC5d*:q1Mt%tj968\QTRW?nh\DG<R*WVERRTiuIKjHibi@:qPQQwW8nX1LD>J8D+LJ?TK5D!bDu\
W4n@Z! 1iSwK5=9^wpSc8aR48\c45ib6W+a1qDB%taZy>:w#kwQW++I!!!jQbw^G=a$/^+b*wP<8!*wHmJ>*A9Y
DiyiMn \hG64q%:JJph@LXk=18Nb9Lci:5&!WmJi$Hdi\it\*HbEdn%HN#&Mi9M<L>&nME:wYkDySX>#?iFh^Gq
@Yu:1Y M<<*#9l9nh!%XhadW+/4yB:hFyHWjW<=<>:nDdN*5?h\P@\mR@c5!N:Z1I%+ZliJcJn:c*jp8%&S&<wm
:GMDmp H@NuD#Zi=:<F6LP1t@SN>nbGdiNH^Rt<@>4=\G#6Si/N$pP6=L*X>@J9S!Mcwp8Q*N>%:EHdd<ntCG^6
H#Fcc^ ZDV8+IQuuhHp#>F^b+KdkBDcicCJ<%DnjE#ethJ8DV=VE@uqdk!Q>CB4@@&>=hEun$WjQS%>@qnM8/5Q
#eMCM8 @?1+X*w=%t\ke8?XtF9ZanZED/<&^^aMQVk$@QCYPLbWE49*bt#B&KP\t\<Sy??j9#&ZXiQ#jPC^&b&\
9YReF# R+PQNTaiI/:H*l&P9VWY6&$m4tA<:6De+=N*++:in56/?Qn^nduu6^/Qd/>A@!8wy>Z@RY!MwiDYiGeu
uWV@?R JSeqJ%HY8CWZymWtB*8!KbdY%lS4?9>RC<Z>#=nhQ<8E4C!5dj:9pAu6&qpG<!LWyym4:!1BVk$Yl8bc
S!NY9T >tMuBR4B?DW/YGpC6G&eaK51=/FVB@SZWaTentKL*4Fma@KN=#S6$RWFn^Nw!mR@6h?NSk:E=kntlAKn
F8!QD# Sk^8q6<pVnDWjVDWTlWLq*J:+9^j?LyQekw5uuy5VQV@>nZ*\5PJ5q@J9S#ZHt#P^y*iL?GGDI^HSEcK
#6EaiM 9NyB1@qTNh@Pe18<!\e5:%uWntecEyjK6i6jejcm6Y@^Ph/QM=Yy8>HIAd/\N+hS9*lWWbS=LRF#lJ\a
W:l8bR NCE9%&^bn>b>hCq8<<Hwq*5Hpc>:i#Ny8&eSA>TV/ZIaepTb=Tum!D+wcbiV1!?&Q/pEa>Tc*+\$68\+
-AG$EL 000ce6a356800110333 Page 42 of binaries1.zip
#Y&ptd atSM1tqqGi6<WWhIDnnQh$A/p41M^eF>u/<ct<^?8#n&ijJd%W+m+Y^XMVQ+RmuM?Ph<KXTJVpVA5PGp
?E\/JC WqlVCJq&JlFG>9R>$ET\1BPPZ:6i9VXq/pbtV<:+WHG4NSu*Dl9bl\^1!%T:<VE$<1dN!X=C5^:Hu9+M
/9>EN< YS9NwqN+X>/?L86aQIe%@l#KQ6*/$ZmW+G/^NZ1$:E*HaI@%^?+a/InyVmT>t?=RR<D%\NNHl+6#H15m
CJj*qM SH%Nq</!ZGX>#qJ9^n8W$thCL=*@55IS#>!Xnd<Y$4AeR5I?<#91&y%9ndjlKLRXB?#T5X>W++m<EplY
NAe8X/ i@6@>*lmlRtZl&c*KX+/RVkpV%yD8G6li1+k&Va6lHC*kPVD1u1cW/w5KL6%N^l:>9I8Hi/e@d&*G85D
4bd>uD H61eX<l>>MdhPyL>%iei4Z*B88dR5ZMu5N?ypIN9!Wmj1lyn>G=DL6G6#uJMl!c1#yt<a^QZji%yL+Yk
q&mey: Mn>lw*&I<!G/ZDGli>16!?%Y<RFCXZG+4PY^!p>uY&%9u+6nLG!1h96^ItR8V6h/\d@/%mt94+4j#KeK
*ka$M6 lpBp/PSVuXH@:TjPY>1<wX<<&?l1qtiqdGLZqZnBw&YTFl1*/&It%Y&*nFinqchZ@<iPX^e?tG\4L+@m
FNmGl^ niiJ#jLjM:?F8B=$IiM84#\h:C=<XH:/Z8P%a?TMBYu!:R<SPctTe@VJ%+VqGhKd?Mm9?&I<4lAt:!Y8
t?T*J= :bth8Fl/kB9$eNpt*4>^KX$@S4de45!WYQdVL>DqXJ>@4eXN:JPJY?hMV4=Z#=q:8&FL8a&:>?&9V^:T
m$:W9^ CcHjNn>>NZ4ITYEh<m>K<PYjLtmPA>b!d/ZL%PQGI!<&:unTKByL!+pe^y*T54LSWAk=GTL4=P@WLu+V
QFth!G :FCG?#Bwe#&E*lX8Gby8RA*d*&1#1&=R*i\%dwDbuet>Y^!@ddqkGYW\?VWtike!S<R$Eu/ACXq%^d8F
S=68:? 6$>euM*CuWFn\M/hm4aNWj:&nQ!*RwIlLjw5LKF/ViekAZtiXwPLCh%wJJP$J9eyhP$k%j&NJPd\CCWy
\bTMJ? ITk#!LnR5nk$y*Pmj+@#?9HS@yaZPEyhZYdh*WAV#mQS+b:N%Tb6Epc!q$k/mKwNpp^hu*/^q/K&I!%#
Q!wF1d Q=S&RdG5MmdKpDInQiQ&?9DlGQI8RGk%iC+/hZdP#4^>WKWXnI=uMY&mRNHj?%!SlGjQND!1*B6WR!^n
PwTY+Q H6*W*IFLIipc^J:E>q&P$t?M84R@5&i8i1TlLN:qyuX&ZLLFu14Ziu55uqXn^/lSB<WLPa1\D5?=ZL!D
E&<lBF #NS?/1BK?X!mkb6@mw+A4CY/N9?yPMK6!^5QZBi?L1e%AMPB*>k%dWKQhjY^NYT*8/+l91Q?m>51SHA>
chaiaY B:ZXn/pj>DucJa$@Iq+*t!&>?uWNjKGl5KFkZ!u&e9??H>/+LbQF6<eM@HVn5I9WE=EhC+1&?>=46Aa@
u=d/H\ #ML4JdFqlD&hye:B!8mLA/kF>Xh9V8VXu4Cb&b@?NDw@M>SEG&Z?8udq>X/jLT?!#T=>i4K4jYiR&X6k
=QeDaY ^LZMi+$wLuB4<5e$6+64@X:=i?:j&$:S%/=i94@JMZXw//Gki<5bN/QyFqZpY@81\4SMa+LnT:<Rnd4A
ypI1PY &aNhu+>88G@Z1&S##@Shb9TEY1:p$?S<<?iwyLwdH<$<\=<$>A<lV1t6HV&1kVG6@16!XGynhw=<hj!B
CeEDQq 5Wjn#:1LuGuNp++DF5MYuhG!&^?:8k?86:HRZ+Q?m@CPcNm$ymAR?iKT49uSttCFn/:Su6>IYVjT/#jA
Q+@E8C EY/&NeMl>>iFHMiT^Qh%%1m\>q8@TllCJeXtQH\?kLCl8y98/V/L@bXj>#4NTMhLMiZStcPe4HRl\c+M
+m^t^D X@%ah>PKp+5WPutY69MWLd9K@Ln6/P?QcF+++Z\m1&J8^P>#5XXYy5Seh/&8#5/k*F+5\ii:DHXK#QNV
bPb$/m QRMNW6p<+QNF/wSVjuc5pj/DaLY45PuR$<abdduePLDwApb:c9#\QZ%^Nnd44<TwuS*mV*waHu!qM!w+
X!NIMB Q/n65/ZbaNeAw/I>a*:5WP=a&9RBY<&8B!6=dSWL$eY8<XGLY$u%b65n>pXen=L+yqTqu\?+ZZK5euHV
bG:!nd cc@Q9Butb%VVq$8qiXG@j/:dbW/MP=k/cWTSZHj4nupE<Awm$m+h?&4hY6CG!jK@qucl@J*/t%i^6$:*
>m81Lu :D&!48Ln8Xyc>!XHi6t#kI!FiL*LnY*1D/+i1LjbE>#45&pnLDy^p:tQjZ4+ICE<5pP$t%h<4qAn:d#b
qli1L^ WN4J=n9tiXl%chtdXJ&l?:myhc+b*458\ZLY>X^PMHNu?J^y6tcC/th+X+96Ly#&**N=*>=8Hidwqh&:
y>SS@C Dwhp+C??Q@?M5N+4?&H:6T>6lj=dLun#8mWX@c@V=ji#QGaiKVl%/=SBqGH<wyALbn9G4CA6*>:Z%n!@
^>5eRd 1>McEI&BDTP\S#<PRP<Y*h5bw*W?a&>+%//*w//uR/$$WpBad@6bY^YdF@!ZicdFL:CR>canl>Iwub*y
$&*8$8 &$NilNRRMR=95eZq5$jC4M?>6V>BV?Yt*/E8jdj\V!pbGmM=LY@c?B5%9*>%n?KE^kHkn1L$=djGt?iV
n4NPW6 G*=Y>pVD!@=1hH$?pmbV=K&16P=l1JJ*VwSq*nq4RZPK>1im>Vh@d65C:6$cEuj+wHiuFiyh!/nXq95!
CJ&Fha mVwB!Z%dW=TqK$1I\ht:!?HM>I>jntV1Btd89PVwN8G95:j@I1Bl%=CH6h<Zp@ac?cbk^@PCA:+9:9t?
q?bZS+ k%QnD/=iQ*4/#ilNud^j^*4&j@?Lt$dc9u5&y:QMc^&R:@pwlLt+Jy9:6*A++<Pn^q&CQhAZ81+4##$T
e8lcKb VF18Qje:nIFyS\E%X@AML%jp1WHRepqq#P6>lG:6l&iGc\dCR%wDNpHjuppLTEI5$@$uQYwVZ4hQj1:=
#V!8^G G&Y&GyF5YHe:+YjqLwlSS/&u!4YV6C\<iMT\*SPNiTDnehIHttGMuMty>&I@Si:ikhF?&+bHYm<ZQ4%h
a^Ka=6 Ey#ic%bN8Deb<A4/5&@IVp+tEP6ylmtXl=@<He!JS8=<t?iD9%4%i?+thELZ:d:*/\9Hal9AS@iQ1Xm@
%/5q4I T9i6YRkcD%mc<Hnm?X/KG?$LMP#F*Xe<Pau5RDitPPCGinlX8b?M+9ei:=HK\T@Lh@WE&Z^cck@c\HlW
tki&bh YSSbpw4LYH4tLa<MIPWMbnaF$H\=&1Mub1tICpPhTZ>VcZiKiW4J6%!#!$EYFhdLtY%/FVqDM:Qaa/VF
:Y!D9B GQVEa?KJGd@lRDZVdkheXjL+SZ^b!pV%aXtRW=1^GAX#qdtqZVA=i$L\e!5<M:9Wjmi6Cb81GGFkiP>M
AcPP^i >?jq%LwVu:+pS9@%<XQ&aQk\h*H>L54Pa$B8In^#X*n/:y>Ni1QV!#k6yQmP*kpH^Cn8*ZcQdllkCd#5
bY*h\K V51SZ@#6ei**45L5$?@L/8Nu#:\8dM8XK&9eC9RmcN1&&ul:%?*N#$wMp!d66N95m8hMBu+/WpIhE@/d
ZGQw%1 ku+S+<d8D>CqQJ^8ep4wD!uicc##G?IGlRV9M6F&N$q&R$#*PdAhGVe5I#<68wkJn1+*#KB+l\R9l9bb
Jh=AaJ >1hlT5wcM!+VtXl4^@&jhuyVTkX8EYKbwMlM\hd*d&*BcQ1Znl9CBC:5b8VAYiPP1w@55dMG<=4LY\?p
Za$$*& $9La5=#Pbw=?%!9D>%F/+!$9=hGJ:B?qam/Re^5ap$i<S$JdQHd?lVnV&?VSt?%Jh=<\yW*E=y+4lX4W
#4yT5Y /@T:RBP<J5h::?6Ph>?y?T^+pqF&!%E8@eC/:b8kd8LQGMjdJeb%#apK<6b=G*YV&@mn6w+*==JdF*bD
/Q>YKa pV4qHwdXC=ZwjP@c/caARw*B/=kpdtFiP4a:Qt?lJe6CN@>bjQ9^?KcR<EKCh6X+tX>\^Z?mk1jV@l>Y
pbk5D9 \j?#8iB@>eI#KNbY69@dZ9k@>@p@RPD@$Z6A6@m@KwaQ#<*eEJu8\htkHSt=NnieF?!:qlajEGaduJKY
=:c&=Q cY1ZqWVZ>#H%VVCPVtVGY?quSKY+&mZw?Yb:YG@\^tEm$6leV:bucw!^kci@DZ&NBY?D1XMKk:dlH!:*
M1PJ^t +C!9>Z+SQtuY@l+euy/:S%!WWaJd5l9d\CtJ=^WeFK8dp?YI\@laeL%M1Z>?VBP14cX@tF/5XZB/Jme5
Yt%ENP LIWbE4<tJeN#nc$X&<:a!h&Wy?iSpKdu+bD1aLdieG%I8FN&RF^K\Dwell1S=l=9!jWN>E:X6nBjp?nF
4AWFhM Y^8$h4%B5D$9eL%=jqaT&><+MJEd:?XEY&@nuBNL>+nipJ?ctGcYq8:5==KZ=e4AaZL$uI%C\@!aIe+Y
XpKKiA mic/V8cBteubbpEi^y:/!XEyCd1BMYF^Bw\@>@ZTDa!##uY\!dQT#jLKhM/\#F?Z6>=RQ!Ial\p*mjRK
XmEj9w MZb^MZe!al8\VA$NMtmBiu/=?WaYun^*E&>nA#?P5$8C5$/&Me<?$yHHy6y:^y6+$?^VnQXM@WMhE!N^
6+c/jE tI!$XF8hdF/ITa#=Pl9DtER#J*>/lH>8Y1+nLVjZ$hw^qSZq^hTP6p:*V#GP5QiJ=PZyydwtJ6D>@EPN
a+^hB4 Eu^>DJ*?wYSjE?:1=J&RHSkTtipa:l^n4S$Sd=dBnIl&Z=jw!/bu8Aa/Y=1uJAX/PZNeniKCW@QVnhd\
JFiyE9 PLR%&kZ?IjtPXC+PE&qS+M:V#8HaP<WaSDJDYB:/\h+iSkY8^6y&c$PwD1a=adptn8FJ%nyb&bal5Yu?
lyjXTZ thbbbwHGlyt?WZ1M$CCV9A\e^5E#^>$@Nbj1FykYtLnYJmw^u^tddJCbuy<ep5J!h%9naYy1!LXhF?wV
Qt!FP6 E/G>IY$>I></jpPmhtckaRDX#6A6KVMil:FLVey$6Pdy&Yh:P>pE/9ldM4Xh@d#y:4pyit9eHaQaPeuc
qej^nY tcb?*LY$=A#ZXBeujW<*9^^1Nne5P#$=kpGQ#QyVuTcSQ8/^hF*VkGD9jGP8d=CB4h5GXwmPb&lpTuS5
aS4WR! 5wh#XI=%kK@??mSdY%aYn<bJ<HL&+Kct&ee!tXai9l=4>LJ^tCRQZbj%94cJZtE&luSd!:l<j!Pinp&?
<:8ilZ 5:Y&wcpdP<p+#N\^\yIVRjiQb!jpi$hGe&uYXJ<%YSt?>4qy=uT98D<9+yycpPSpF&/d/?hy\NA*CLQN
CtT8H8 e!&\5HZmFCRt$hc9NR%nPb5F/HtFY#QD8Mu@<NydlDQ$I%^+ilaBCeu8mcFbKVnMP9MMX$iDlA*iRTHW
PcIC9E kkItI>dIqe*I<I>n&>mdb4q+i9*yMyG?DL>IQ&5n\:ZB?nc<!H<6l1hd@t>JW1#@YR^9@Y?L+c*@ySmi
NNDY:k @5?1C:4q9?qBwhQ@ni^@w6mkY@@ZYW9Lj!%by>9<G>u@SElQ@>?\S6n>T&8Eui&@aa&k@/@YCA6dG#8:
^@<lFL @!?6EZk+DP1YEMSwC#hV4jbIDPyhLHVT19XKC4dVdjR*cQBphnequa%B:bMeZd:WNy6q&?\9F8i+jh51
!Ga\V4 e+VDItAI*!4h+XNLwX$+!^*84cGG?c>*5V6hP<NiYS>+Hu*F/&VE1$Ln4LK4/>4CM&eQ86ie#Lka^GI!
Yl8X1C VX?<&>nuN>>hpYu?DRKDQ6?*19e6EhM9@ZB^%XFYji6RWky^6X&jX**V:^!n&tc>^8HSyC>15jEdji8L
1=D??R aiaHK5L*/G&cC<l^$Gm@q*Z^WjdGtK599t?:L5*b8Qu+ce!:A*iYV9h1yP#aa*p9?eiQG+Y:V:c@YN1p
HWJE>C ejB:+KFH+^89^AZ5m^mci9iyD@@EIG>1<e61\eZj/@c>?#T!=hjjP<y9V:#y8^$L@?1!??H!^?5$8C!e
#tIjkH 5u6GDiZR4S=<X=JVdd#EGAhW5RP%d=*pB^Y\:k1>GY&i5LQX4Y<I>J\T\yL:l:ja9>qBDX11L8<H%=DF
-A9nEY 0004d43ddc400110333 Page 43 of binaries1.zip
dVGHnQ Fw<!+CMXDk<^I@Lnq9eH/@*&/6&w##\p*%8@bb88V@CJp!a*Fej6DAiDp9L*8&@wwY1QVPyi%bKe1X=u
H>9?m: je5Ti>9KL!V$Ih$94/Ge+Fj:66M5eM@d9%^8Bm?/&k:L^TA5d!5%9LEN5Q^L*h/9RVjNLil#!Z&9/j^/
mQ&+&% lMN+/JD=<6E>PPjQh!c*5Z\AIJYMEkDXqi:8=$8>w=#8Hq*4EbJ#XIq!t@MawkeA6jwa1LDdZBaGnNJ^
!LH/GG ^iC:Hi5iKCkn<CElB*lBwZeQdekePeN%qC?BwNEKeB:FS\p8aZAIJT^PSMmDu6lZpR<*:k*KD4:Zn%WB
mujWb! ?Fpb<c=:H4hmT!XFZCmTYy6Cm44SdW<1p%^DXT:5Y5/Bwm!eVNk#hKhuSatd5PA5knhb1IpTLi9?REtJ
WD*ykw @N4R@NK58CiF5^p:dlF:<=4n9@hIhmeFZX5ZeIc!JKDC&eRKdj=Jd4WtdFQyX&H@*P?5\$@&Z%*j@E^6
EuQ+/+ <cqeYaK#eX>1Q:Q?C1!F$/mQE1V8LD6NKcLBTl>1946!RY*Y88ty6YtITC^idnaw$Rbd4laLcw8ktAVl
XWniIS <Y$aMiZ$>TiZJ<+ej@*kY?jN/E9*4K?6$Scj/:N6td!ASRuAZuNB@/h$bFuCDyW%%bBjtTVkGZywi8Pl
LX\+aL %/yZje@WDq6mY/&9*Q15/Ww\\!+RJ?uj^E96TpK&iMc/9Jk:CT??a@kAmu8kc4L+aX@NZ^Pdwl>@8L$6
B%d>QM hk^4Y:ZRLdY1$Yp<tLH6@nH#IdpE!6K#!hRCNGTPAFQBc\\MAy/TXMjm:9TXA*h?:nBV?HnyY@8Q$J85
\nFuF9 ddZiQ961H&mCcBh=ZnP6ZJ!p=d4Mpyi/n^!56XeyAYRk4D:tuq1IdLCZAJ?AX?ED+=y\\#I$F&?D*wDZ
Mw9tWy >yhYARI#=JYq=5iHweWidJw!u686\//w$YbGiqaCZ4yMV1km&<<HApZC&E9^KGkwZIa:4CeidRL15H+q
bYXE&\ >RlbL?IBJi/q889u^mk5RF5:IWilWkEPG/!Dw1T>inLCbynP&j5aEV&k<4u=n/i/1u9<\:=ISm$Muk/T
:/>#/i Mp=jpN6V?%Ai\B?ydJ5$Lk+ChCCGl5l=eYDq6La<qPmK1*>4A:hXebPklRTKdlCGyk$\K>4pREbyFYhb
9qljXh #=%&#B5EZKyA64G4YA/Ah1nJWH#$BHQHMj&$eGBbMR8S/w1dem=$S>IcBHN\JVA$\nd+E\A5+?Xae^E:
#^CuQe IRttkwy#K8^JE+\pHi1/jAH!jk/R#ZtAe5WjJQR*^RSl>N\G&pc<SYA5ZFFFyhSLD<hinJM>+&eE4CnJ
ViJJ?q T4lZ4mTw+I9S%wh/dqWPKZh5kpPWaFZ&HFt^G/aj9diDHi4k>:PeW$\RNcAbbn6uC\Haen5EuQHt+?*b
m@weEl #DR#YjGm/W:i%n68p/11u#d:Z/9cF*ZehQ<iiW$P1>eRjMne4e*GH+DX>pJe9Zak?hIkwHdJ#AN!CT/1
*1B*l& =W+=+Hl9GWZIZaj$ae6$yVk%P8w#:Z&FtEnnL:PI9Da*=BTi=qb^RppMV<BI%j#N&JQ6w%6Zmlh$1cNE
:8I&5# H^XBBX9&w/Wb5<qKAWc\l/&aK:Pdl5?w!qXYBpH%*QW!&KL<?J%5yLI4^$PP@had+KWVB\%LqeE?BFJW
K#^:Pe anFkiB\ucpBCJ1@N9>EdT/#:?cWZ5#ici%d8=HTeHdC<4HZZK^4YZ^NV^adn&N&n\AAi@wlZlBuC!&>y
:dDi@I y=6iuXc$bHQVi=9<RmCn!q5IT*6qBKF<mEI/AGp!^R6%QiD#Da4RdktWB>i6qIdDwqMlcwt$qDGj&>Gu
bA$YXw <=8H9+?R8&Ji\yWMISCla*Apy+FY*J%QcDG$WXBwbkHLZemL4$@5melT1+kMI:J:A6EWP*4qNbJ<WjCC
ZWH4w^ VHVpHmbkKR<!BTX9LJZ+at5wK%YLQ!5NkNViu9l&#Nukbuk=CN#1?Kybmj&p4a@$SlKE<^HG6YTLAYEd
9jlP/i ZIlPle>nTMYecul@yFQ6JEE#Z%M$\\+p:?e:Rwdah=HkY>/#WiPuG>+jQdb9RN%d%AmB6=?!bBYt<ynN
aY=#^N pNGK851Y!JAT9L:=eMWWZP#uWew<aibS&$YC+SP4e=#yN<V1Myj&YFcwlheQWy4pQJdeeE!uI^9b&$lC
?ePDZ! ^VF69CQFSn14VaqG%XIIAFPKXtC@yjM689R<GGKb@w=k<FZQAeup9aj:5C:AZ$tdRJAth/JC4wS%y5b/
=%m#^R &^9B^n9X5/5YI$wid/Vji%+Y:?wqih^RIA=mwTXeDIZ>WtiQhMq*?a1Cb??t%/18qu?#e1LSdSe8Q@6?
6h6>d# :T84iiQJ#cddw96&mnV45p:uWb^4ZYtPbG+?^8=<8XKl8\Ew@YT#T%!HmDq&X8?WY<ZAlbab:cc5PwXL
^jiuLF /!>VD/91dD!@Mena?NK6N<4eEy=4DpbZmM1lTa5<K:1ty4j5%ukX9HH*ln:?>Qh%@w:<*@*Lb:w\VI1n
u%V&8c kmeclu6@nqjTejLlK=4=4w?yALNIKpih6Ia5@++4c&1T9d49kX:&^D:*>XG1Y\C5@+pCSL@l#Pj9!n8K
ZBBbN: Vt9m\iP:qZSKiL9+c1eCmS&p6:?Ge?ZKuqN&:@y=#Wu+bcI&GX!Cjy/9wbd>4bnHGn%F84dX9:Lq?$qK
pj9kPR dR5Au65KtR>ARW:J$cS6#u<F%C#8Q96^@i>jHPVQ&=RZHG!\pQJcLlQDSC8JTq4ulYm^>6?G6VbmEyqJ
Zcc?qZ ?C!N>1Z$pLp&=6IejSEhK5u<%5*^@yDN+T/?9<Wt5JAA/EZl?<B+6Ynl5LL$:B=tEkIj&!FqmHbZ@+Im
IDD?cN =ZlMtLmY#G>HWS5SaLWej$#Bn\^A*PVB44>9#\P%=!A$#K@cK?lc8W?8*\CK9i#8M4m+:NndEmKjICMb
a=$ym/ \@5p4RGA&>\WhT4<<^5QZ&Ac^hjFTByp^GKE>ChEPkaZFWCqWBZ1GwRF$d5&*I%mL!>jSlBuA!CHIq!E
1@/ZjI mSRld:>S\Fnqa>WW=qqFZn8cYuXV:EkY/:?lC6S$14$G51FWt81<KWCNJuX\FFlRNb:nWVGW@P/D\ypT
TGRKRp 6\&c=@uYmn\@At5a?8+%S9ldFp1ATR\JVIBEdahLGuA5kkJa4WIhW=RpwMXRFK9uDdZw?&KPB8RpCh?4
=Pln#l Rd&4Wj^ik\j5Yc?Aqd?wPZp6Qil%/Pt4AP\6RKqZDKyFTM5$BCwc+F6Fqk&E+m\DhKnP+&HCBSXS9A1%
jQWId* k5DCIHuyCmI9SEaA\KTlV&W1?u&#FT5C@AeRH:1N&AeF4kIm?q/\V=EjkGW&:Je&acY9%TReRN^B1LqE
9^DBS/ #C&^@Xk%CRBI9m*1HbIk\Y4\@p!TAknMFDXY4TyVRKcmXbqhJC+FdZwBJZZ5Ypn1E%<$alqnd%nwLtmn
PHK/F4 SAlV><6a=qa=AC$H4Cy#1%SbBJm$Ge6>wkDaKQN5%QmYc5ADuBRp<c?S^Wt!6ci%@BQSiS4wDY<5he=y
HkAjqp hje+Td8iKPk4mP!^AAAB:PXakB4#N=yCkTw?Cyq9ibmh?SI%a5dY^9E9!\:+aaRLPMkDPX+DuMJXAGdI
cLC^dJ XL\GeAJC^jV^BY1<4c4hlZyCZXq?Ay^=VDN4uXd&y/ZJm:J*Vt9JYF6P>1/FatTuckpTa!B:&HdipL\l
G&$y/1 jJ+Zua%@MZHu5hQuiYi4J^Cw5bIwGLKRK!6KWSI>T1SA=eFSJjG!4ARPE?8y>19k&uZ%^X%E!mmP:/H?
WAhubq XtKad&n#1eyXCMnKt!n!nBYyV@+cMXhu65##Gt<JpGwWT%uyNWJ?lH6wqH9QYk>/uH8KuLbpFu>K/p@^
J6Vplc AjnnKm!<Gw?8CYHdWj^pJq<w5ZT^w8$EAK*BewNT*t65tLi@$&tyhM^mGiaAJ<Qtu^y>8GbHkXpF%T1K
+>Wk#D GyTEAR!I45K$Y#<jipcRm8!E/&tdw9kL?8K#bN+aay/m!T^TA59I9Bj1@QWedna/DI6tG1yIM&GWV>B=
VD*!NG llL@Aac*lM!c&A?bWi5^ChFJ^RId@ae/FM#9tN=ma:ne:T@e&6q\mPm%t6\:w$X6?juD/u8V\\9T\5>u
$hi!iL lZP9ce>9Xkn#w@K1NPbJcTIjPhcpKp6ddy/6iZh9FI56J@!C?>TFF+4^LFCN/t6NASV=%=dM4VW@G@:<
Jw+4Wt dPD#YVeknFF95i4M9BZ1#>cWwkhKIqH#JY1<S1K\YW=Tw=aA^+k#*><\$+Ch6wH1wukebLH?ZT+cRjEl
T65j@Q TPwjLT+1eD%nR<?69V9mM*dj\jwc<?6N4C8dI64ycF\C=cLX8XBbXmcCX><CPGHtG?YBeHpIuAl8qij/
m/H6AP acR#CpJASilHAj6R9Mq?5PFL4y<&h$+LN%\teXPZFyFbV#VtuhWqKS4maSWAq<:D1M/i$ADC%%AET1Id
KdZX=/ IiF>c/#H*KSZZNiZhVCu%h?NE@nBCEt\GqNSR<!ATEdqKM&1QKIKbWbYbKwwVyEFAV\X4GP>JtMNFd9N
*<ctW1 \$P+eP:dZJBI+CKXtR\=cnCeQ/%?#%ShI8@PuITDHT:kYRR%8@>Ly/@</aTQH&J6nFt#X4:Q+6Ww4^J9
%tu!IY CGYqbV$j$&WpSFYiKSt\S$5YFEXEAn>cXtkQRuQW^Idn6b<a\RER:naYhFpYPI\Ghe9G*/XCe%Ty%:S5
XdXtT# 4t>JiJhyIID5+^LERwBj&AWAKlJHYiEb*#FnT&C\T>wnT>FYa1dI@XpNR%l!d@X9XhJ\XE9bW+=RIBT#
m:GJT! Ihb>9p5G*PaRin#B%q@&P&eYNqSRMPEMdFe?Q#ND^RL<BCjdJ\RlmVD9CAGw<hQ9qjpp>b\=AEnZpHc<
%64uYP ::djw?1PBi1laH8u4kA4RcId%SKWJjdhmIT=ww?#8k+MQe6uywC6bC9DE48ARi/^lIAyGH+NTdlAqM/R
k$pXjP SG%pTD6StKMA?MBFeDIjI!?GapR#!ytGd=LPRpVX/6VRW5t!DGm*yYuJRLZQndKu+H8@JliNEkII9mXb
YW\?A# %CLLI&EBnC14l5nEwmRXiGG9LGXRpc>QcEqATydGh\cYn#ZIW96\Ya1ianG\K<R*\45mW6&BwSZV!cw+
XwIn%b h>tiRpJdDVl/C$pkGkb5S@DFEP1j\TeH\TY4#AawMc5LdpVyC1Gc<^Qn@GPdB=8S\p?wm?$&IpMIh#/+
$/eGyd ><&BBhYcSVd1B<?Qb+!nDHmC=\&qyHJ$=lSqEBAi&5JP^+t?>QN5bMi:jJt>TC4XpLcIbMX&&=$=e1uu
^>#5<H QGlQKnL9tBh1W:<yWID9@jCH+qlbeBu&b<$m>yPBhBN=u$nWAIm&HAT!KJ@Fqqed1TncdMH4kqPZ?K:G
l6L%^c T6!thMc8lCK%C69AQhH8mewPmi\WIwj+?ZYJw4a&$ka6D$VmkRWmh@nQ8yeI/BMyYIK+F!HFKuEyMPum
WRkB:u Ji%$Yd+>\XhPWjn^\PA1AFVn\F@:K!M%iZhh%H+h8Y99JyX6NC=BL&m4w6@KmJ5XYARNj4w5W%FF&KE<
pSL5^6 u+th\P%b^GIqV^S<=jDYY@dciqBa8TliRLA$BRW?K#nkijS:TMQ=1?*\?*9*i>qJ:SGZe%@eEGIT6Mp?
SW?uFP y&Rpp^wKZyDJ>4ZMLnnN=k9mcjtKm1PRyAlbpc^@kkNMa8@HuJ*/jE+61N*h>%!pewWWCl64hiY4BXA1
bVmmJE 1B8l?tj\NyJlNXt<HNkVVTF1<jDt<$Yw1qeuj6+?<1pceRDb\W4Tb6bRtQbRbn$STIXAMMHMRqW#%#Pu
nZG5^w d=>NjK<MYNRL9yElDC*:#KAalR5^&!4WnS&b6i4LG<?/VkPW8HQ9M=G<eY*tBTwQWIc$pWVhCGE6VLkn
uVn/Pe yQ<Vm6KpbFK&+^$AE@<t<EEqqm@tYc+c^XTqI%NFcnZ$WHIRak4b*H8iH>a9y!KZwE>1kT5I+*HCQmJ*
VWhd\P VFYe4nRqhIKWAj9Rb!DG>?^VAmm=JIkKYe4hJ$XD=<?mIeEw!TTiNWtm$FXNqy%bq*HR:#DnEdHiG@GY
-A#weD 00086d93e4d00110333 Page 44 of binaries1.zip
:&EH!P D^Y^#<jc:w<+SF^5dWe=d8*u^#j&c!6Q#eqaJ4lL<>Z+Dd%::p$M@yp=KP\G$S4TFVXypkw@X+YcwAp&
XjDB\w 1p5&!\m$wX>J14k?F%ELi4&RI8$ByATKYFhbKCdPt=L=EJG/WwLnt>qjJRG^H!jkmqy4!9B^FG*KXNNA
pt$kL< 4m#%AV#VTE=u5!!%B\Y1cE14bC<&W@Qa!6JHTDETJ^u@5/dF=/$cAJjMYaWG\Ha6$Xue:CL?McDNLFIY
+>/<Ri B=Mycmhm5^<:Lme!8#w5^\pTT&%??G=^M+w9ju>/KaSWBN@!%qK1mYN/cC\aE!lhyHq#S%DTVEG9>tQq
ahudND YEpwbm!iKcelLFMYI<pRkwJ\DC9eTtJhkA4b^PqJPuBYn4XXBZmEwhTk==8JIKQ/pX1:nbFAI?6idME>
\1mT?8 ASwtDF@lX1MKT\<Xd<WIla11Z<=AAQt@Kt#E*XDJPE1E85>PlXJtNNbd\wAZCwC#\y>?B=1VlNQKI+Z/
L$GY?\ Ene%eA+8atkNptDCDnIZni>Z$cC+!dPK5CK=YLc8EmBWbiLX^V?/BM6RckASuIBlD#/dJ<P=t/HnB#Tb
<c9LjF :*9?ilEN&V*mFulM*yta91nNP<#&i/6APjNFiqtS>SPbWWHcYBFMhXTY>JIphmAWCcYT+Aucm51G#4^?
qXjPeH GCWY^S8%E^Pl+nI!$AZuZbPS9qBGEYV+&9ueDk&SH!B/DjCdNCZ=G5A$ChKQaeY1Cn8$JMkQ4Wma1BFB
N=4LF\ TIjPa*FT5h4X%CNAJE1Twn=Q^pZH9Q!>bY<5:8YkmtL@u:pNRKuqaFZ\ACCby*pq&YnBWbVR1emiiHMB
pJBQeb lK>VJ*uYR5WJuCQV#^%R$:VR>E\Wuu8WaF^wP6BC1#^BIt&t<nWlAER9iu<5BM&%mYZL=h4RH&eVe+C8
mCb1Nt RPwqLl>=eDI$a@%qD6/hY9KNRiVLyHiE/mtiTVGPd%6?Y#G>YwPIN=B?iZIa$D4I=#/<yi&?4m/iFp#Y
q1ClAV XFLkD<=@nH!p/RDbjeM%iNLW^uPNVEZ@VR6*!!\V&p/N=L4?@iG1uZeBZ=%!w$M=#XAqlcFQ+GP&b/Le
JQbPWi ^ew>!C4n@49LK<&SpjuyiwHH/<biSe>Z*=H:KJTiu/=?$=WQRj#qFBY?VldRG&Eb+D@ij:IApAZcVRyV
KqQ^Mi ^?P6S=NG#5!y#>^6Qmk>jij9Q#N8Ak4K:KdL\/tbZS@k+qSDdVJCYJuy$>@ha&!!c=jluFN*+w>SHZ+C
tt+6n= pX$A<KdRH9I=jSE1:GF$u=q?hVF>TNdklw%Hbj?<V@<=L!+*5kb=?dBJDYSq?*ZQDmQ/ln*DFYm:p&>?
*1\S<@ K1=6LSuD/P:p>5=b:c\A/:XAlPH!^j&GqC:%8kYjuGHLDY&QDq4+^Xk^J6D$q:aVi^I6HG>*8Kp/iaV$
=$ippV 6N<%p/L69Z5ML%uiy:e/#JV8bA5d@hBe8&\V6RCE#STSW1LP5W:B#/%6Fk96hjj4jJ\lHBm$/&A!BqLj
mBhD4* t^EkjChAbqScAeBcSV?lMPDZXXyV+8SbF*t>G#:/?$61dRKKRdVaStE9:uStnM*hm+CpeJG5TmREjeDS
+NE\Kn &*><tkGlH%NnWeYnLd/pu8e9yu^uX:FKRKt*QcIcnGy!LBMLRZY%q/%Xepj+*BpwhEm!kL48q5CI\KN/
c+CKNi /M1KFR^61nyE<k*TDHdti8E<j5TH1%D^5YkpFN!^=aXh+:wD%8HjM8^FTP<89C8ZW8RlZPmaNwK#mI@m
G?#81e Y6wnX/8tIw/?DPTEa9e/*d:VC^mAAp/P4\bTl5mYt/hiwGwKb#6+YCuphcN//?<Pkh\8w>eGAFB=ARNN
SF^&m^ F4@a4Jpp5\^XdtEI%>YmnL1DRD$Y\#9>\V/N*q^V6+@Nu<nN/<a?&*hqniYqtpF8=9ZwhCAdK=aT<K4J
5H\^!1 w&n*+ndStDMBPdT+E!caVLXZT4RIe!j1Qnt<5:=NS5p4=bVlh5hhWK>i64yEIdaACbEt$eDmN%W5\HQM
jABic= Zq?DTY%c$&BR<WAJQwL?kyM=X5@AX:FFwH4qMPNccF&LHV6d=Zt*FCydLy#BcGj1!NQi/\G>K>SAEwLb
>1t@w1 T?T4ZcHuMaG%CNy4jZESIM?6$L5?Q?\I&Y<FE=:BqLMWYWBSHKXt&d?/NqY*LDKBnn:BLW<!VaYmFjJ1
>q+ZBP iLj%GDyRJnBM:5eG:Bb?5ai6+BD>?W=quNDA!6+EAGbaA=iR+B/%num8PBd*$WLXa?WNl6ieYdPlDApn
66h=Ij qm9De9VK?CXtCDRV\cwN*!XEG=Y8JMHaqGRwqcD9YYTY91/Thep\@>u<t=deaG%*A!QMal!<9C+ZY\+G
ZBbwTi QeC\I+tpAcCpZ<Ha&R>6DZZDw@9BeZ&^!ZYCbM/<yA/1=$/JRy\6I><\In$Zk/H!pk4njZW>6u1QHCuH
Y<a=qu F/EICtDA:*$Eq%cpa9kJ=FI9A^ZZXdZ!PwwbG#!H+k$twVe5!lduGCMH<QwI!AHukel\+5BdbTm*TR=k
#PXmQN BNWHi#BHd/R=lT!YN=/d*qS9yCW*@?Wd*^CieJYKqPtZDAGRBFAI%AQMYnLA%m*qE<cLlPqwRESLQ4J<
Rkimj^ \SPC9+SQGF?DYPawwBn9!Z\lSWbl*Nb#Sa^NGKjIeY95WDtPGEyDXCuRa%$/CaFJq>!1k!nKeMwMZIJX
N86PeZ u61<Q!R>Z#+qV&wuP@YFZ9uq:!NJJdwDqXVuXQk=T!qu5/T\R:W5FRpWj@t=T*#bdJASD+B?wiZWdA!5
^<46IP +yQmApNGF5@WSXV+!WE:qCwlJaeF!!Ecq4Pd:NK?Jl4@mnn#GZwndCjb%S%<:Y%hCFL\&lRt9/N#6lTw
#J$NTK yq=#SHwQwRetuWAtln:CQKYSCMbAyAeeEcPc11&StjIW8D/WeqqnaE+iNVWcNaqG+QnBW:FZt1:&#?*8
h?ac?m \dN*&G*SwTyqSb*6?KFYA=wnaY@%1N1$>eY%VXA9Tl<c$w&w4IXnyyqiSF=PPGSi**!WYEqp4elW5FSp
kwFSSh pE9Lt6BHWhZ#a6VA*9$A$Fja19a5+6RR>+4X\y6=>YPJPZY+T=>?*?K8tyR5Z!QW#t&WT!AYta>KXjD>
%59$l1 p#D$%JSmQ%EJ\#!1cVLXcD1AhqX6qdLqtK5WSPw%XdbyS9*iMW@=D1y!j/?CPchJC=uD>/MKw$cQ1=a9
5wu9&a q+WQS1T@j8=Hb8iM<<>56LW\XmCm*dwD%ewcNNH#tuy8$uXRn\+4JPC%J6hIW/q+K&E*Q^eKil&WFhRm
I+$RL/ bcT^55Z+QRCdEC%9<RTCcyyWktqb9HI!=HjjHL=J4H?V+GDWu9<pt11LNeXbdDZyF=cy/^1/Hb=TeTkh
1h$ldd *RCZeu%L8<5R:w4BXIG8i4&aR^?kj%X!hh8kMJTaeQd>+h4wQQQp1:5Keu?Jdq/PTCN#ZmPK$dX\wNaR
GqLcjE aNYtM%eY4CuMVjJ+N&Sb:VNARE/5Xtk$q$\q/wm\*ySJdZMBtQJk!<66yJQtE=aVEW>ZWj:JMi*?+6Si
:jp=tW E4mM&RW+Yun$b%AYlBR<j=tEA1lIYQePTKJQGw6/b&=XN8CV&d/#F>d4T/:aL/ZI8Tc>Q&d+@KBXR!%@
=P?9$d Z\dkyaaC9<m*K$=aD$YlmdC6&*bPF<1N&G4wFFh:qS:cW$H@G*n?/GLhX@JFmZ*d><WaF>#nR>?95XJ#
DkeWqK NBJ4pYDXDAFR8IMER<pH85jZIDhy\N&/A?VP4PwRh<h>$HkPZ@@\/N&91IDFc:A>6ZYSmBE8D6N11FqC
!lNcNI M*StCT>R1c5$XNCZkDi#L14>&aEd@/1V4u/\Yw+999%b\&/&%*#1R+^ZpE\bAYB*!Kl4=:Ml?P*/JZk>
iu&EhS GbGq$i/kJ88@A1?9wLY8dhY1+I5Bqlc:N^S+F5pA8t8kn\e%=ccpXDkuRa$Tj&S%:cZ9G=>Q*mH9Pb:@
Hc>>N* m#y8\/?HRmj^XdRqhuHPIW%Jyu!yqAJnnadC==5*X1<NHL?1M*u>%>S%l<@&D\Ph4Qbb!Z/\\y9DcijB
BtePLK XF?\w^nM!Wj%d5QXK5CLeB&^CPc#tY61?&%eQ@blIW!nY+KP8QLII6nwJum*iwt+BqXLRDFJVNq/^!@1
Mm5Jh5 VkR!/@l%qt\u$>:6ewPCbAamlt6VK6#Kq#YS\mlByF%ybQn?EuZJ5+>54JGL4qE9&dn:<+qL5V1Y+*I>
^&S&#% VZJqDDNZ8KX+WZ=@6id%L&9ak!cZt&*bBJ8Bckc:S+HYR=Ya&ySWcNa*PQc5Y4uBtaPKTFTF1#DWt1u#
ut6=$j i>AQ#y:SGGknD#VaD&bM8A//&?i#B$5<B@Mh&I?<B5eD:AeD*S==Z!:^h$$Kej*p=naa6CijNbRjMeVQ
^\PRw1 GDS%:Y?#H9ILhnHXH81LeS>ZhP6b/=aW:!Ed+B+d5te\5m5HkAlJlyqJH4uHEIaJ5NRhyiLR$lWN&&c<
*:M^hp ?\u*jnnQ+@W&\cRGTMpccPB+$GQb+?96M:pi9>Dkp6W8\@m895KS^H%DM&5HV@BP=PiMpHNH*Db:nwQ8
enQj:t lL!SEAG<KeK&A8+?N#/<iiiING5$5$KaC5B!c5y>qkd<5pd/6utieLneXn:!yeD4T/nuIH<$h6jAymua
5%GM5m n/@kbcc**hlwQYJ$c>MN$VNpLSS+hEC<8Q@G#PHGFZqwZiDFL:ZDm%8<*kce/1q%Leu#*k1P^B:#J4i:
\!Z4kS 9/tu8hWQ4B=S1#:5M*n!1y?d6%84V$pdN9cwc*Puy%@LVV4jY:jGF<8=GZ9i%?@aDjy^Z@IGV>&nI/9h
q1kD9@ 95$ZjB@%?w:*nqY1ne&9H=8SnF66Hj9TinP@6/*/4F8D+Pc+iL!p#yh\@c4dRPNk@@nk4ZPE\b8bQ4=9
y=jBC= 4@4+ZjHSQV*i$PNZQVdi*HLL<jR+@K+@i@N+j8B+#=lj:INdTYPqHXFIW&eJAV+?#@Gdph=aTpB==bZR
n$*XA$ $qDn%S=?8@^CJ*&*V9ti&H=#<GFA!dC@*<NdWTTA6k+Aa8CnleYSc+6l6\cb1QLS<NLF+^NW?AV=&\%l
$y>IY* 51qZ5eBLup@B\4kQkFE<Mmi*hA+CeE$D8HeFw/bI9CPeG+ye<wSL1iXLc?RMhWEV^n/@q*/4\SPD>@%%
njnJH< Z><cj?i@T&/m:^GcGaJMqaeD<RNLyhDS6BKtI4@YmA?8Q?iqD%?CqZPMT5AmcKSXCcljW4TlSB#Rp*cp
>18nRW QFWSERun=\lkNHPb@jGqHAeEjb>N/L*JL@iM9>\jTyc@Sb<L:uqnD?aImPuIPW&>im=pBXY!#LWEakYM
iQZm^t dPkKFyXcYE:#LAd#\EpCjDRBKk#?B#i>TBEA#KD#tBPGb5n>54DQl=tQX9C/*&iT%mHSi!8pELXcXEtP
5ebCYy Q@?YITqI9WITc=>=hw4\eqI<En\wCL+d=NM<iT6#<$/^cRt^yw\mAFNJRG$\tmIHF5ZAq+%S6>^hqmLA
Dc9CKk 1HbXab1kK&=tE&!tIHGw\kT>=CY*4FLic\@6bye^qCCGqtYMyEwIDALpH\dI<N4+<CBa8Q?GAWQn$yAZ
D4k^aB /En#8=5?qHJK?eKNEFwCQDIeSiEJPHAwVjuK=SI=mlc@R9E\MAp?E\ej^W<<qAp#dd?FK:/4WVLb&\\5
?pjRtD JbWAQtYycCVABFIVK=a5Kk#V?W*BCCqWMKXdpW\wNdTDL4tWGc$l>c1WTPQ159dZu5SE$J=BlMbSp<dR
\TPlh= HD^Imdp@b\\bPnkApE91*PEh*IwPM4!VC%Baa@mQ<8mb+8W$MIiGNE\GDGWEPiFRaTRCyNhRpyE4&wiB
5/m#B< uaF^5tFl=tEJGpC1=tXtI@Tw/jR:jPT&pLpKAZR/XA:RCmctaa4kkl\ZJD1>lA8D#9&bipcZMuWRaD!W
#?bclt FqHMKT14%ScNK1H8u19wl9l>QV>><pID$TF$V^9KAih:qQN\9PG^?&&$X*Bb%CaB9kaaJKEbmTCRXAdK
l6BpYB <=i=bR^iTYwcm1KLnCTZ+Tuk=tZ1KE=Rik6B</qSdyGnAeDhZkE*=EtJHJ?*Cj!XL!ihKiq\B=l4Ac<E
-A<IeT 000abf52b3000110333 Page 45 of binaries1.zip
JWNSne 5MkHYDaYTTBqPiyQ8I/S>Lh#:u&tVWnkTl6mhiSy\>Lh&GPSPRJBQ@G?$KiMlRQPuc@RY?54hwK1AHYy
dtlj8! >9K**6VReL%LlW&#cPeq8dKwa\SySwZW6*HPRwB+kcD=^:::K!d=6%/HDH^q8nTbE%p/G*Q%<9SeYjpE
wjL5dy nnCuNl?yGj85C\RR$G\F!LDm=K$4aV=5SFEnVKh>:dBctN8=liRbENDVBBBYZ6kKDTPliANQ&ajd9RCt
qemdE$ $m&6#!T<?bC\/%!=5Ab?J4N<FFcteY:8k5p6e@*H+c1u8yt:/n\uZ/k>4VGaL>P?/cXd*I:E>>J*F!E/
miCtWe k8KLc:p+X9\q4q\=#T%JRScb=yyI@Fw&GSGl+mQ6DZp$GjG$\:cn1SDPhIE#YcEjwXC<Sw#D8iwuiw?S
E%QhXV &kpdtp5tXS?GK<Z?JkS@e@Eh%c4?KQZ1<IN$CGA=8PI=t:K\SbeqD@=:Y@Z6%Ln+tMRuEe>tmT<c:Z\d
XK^dRq W<qT=WiVLDkDm1wRIGm/bW%PbTb1qV%h^jnkEm>WGV+MK5+niW6hZ9kuhTWWA^cC*6DmwpmAy5jp!ETH
TMcZ@# *aLTA9m:D1Ib<#NCGJKVCE4l^WIujqNwieYjKb<MmDa58!>NPl^?1>$?RVQ6?i^8j@FYpLMP\W!8ZEaL
FTk5$8 S8ZA=TCZ#KhQ\aPRhmCyEqQ/b@!uCbCMbDkRk/A=\9>$GaaH8J^aPypKI!LkHF>wVmcW/R*#9\tdT+i4
Ad?eZ! iJWkjhahQRkCIcZCVARF!i?IK%%^lZllabRWENBqeu^+b#dD=6cWCX?Xw?GIPZkJ^Sj8lWB^ESClp$AM
\W!J%T l*ZVAyqw/K*6IF1*VAknFjq$NJ/+*+55bed!lX1CHAPR+XDeHX^1tA:=e*!Y9T5TAJd6+HMiWKa9QJXZ
a\S@@? jtQlHBFAHqcAh\jA<eC#ACNEB^tc\+YJ#h?qwEE%KSJbE>Pi@nkkR+IuRVq^yTC8iNIJ\WSAR:8i9a<e
FcyX$d SRQ\TC$ACPh:dT5tqWI:<lG>pbAXNLKZ9JPlCkM$IByH:Jta+mLTSMQ%+6<ZDlVSKi=j?wk<%B!eXPR@
nlu^/G 1Vqm!E\1+WdBIqQmmJ4\yaAT1TbCdQLepaYkGIJLPiXF49^d>+A=ScRPw\\jW?^hAKh5D!bG\CmGbe!I
VlFVIu Eu\+u^5P4lVCItW#Rm#?6AWQZ%Z1yTF+qREC/5?DP6dd4E6VyS!dC+S*F<GZcwBiliJiBB!9ZPdqX8K9
Q^d5PN ^/h6L<qlyb#@ZWHSkS4/II1C?M\6=Vt?&X/yMFya8bhVGWPdut1DADb1Y<YmW?YBJq1JuNKX=YY:uJBZ
^J/DJL uTwqj@/cbbRSA%?jQAAVBmaM^:+@Yuc=%k#\w1#6$AVEt^EKXqk851TC>hJt>$K1ZLpZ9LkyFLJeC!B$
*1S=w\ RdRBnLEFdK&BTA6kSbV*6Z*\XG4yDkj/mp9=W9wqRHLwJctma*M^=d4q\nm+VM\M<9>!%Q%6nl\@NSwX
ywTYHK YRPy&A!@n=Sj$SIW4Z>4$RTYdlTt8p#nGSDKPqmPLVLHFXb4Ae^=jtIcq5tlh5jmBPICMH=+j+hLFRWQ
tmkwnd @b/En6#/XSwCaYw1X$JKDj&BbYSyh^C!I/$mM4L5WwCbW?D#\6npM491ZlK5Rq5t$kbbFNjN/#w^?lHk
iPy!yX RBY9>wFeYXVTy1G9mXn$>Ny8GC^%I=?IwDLLIT6ReEt8iCpeAB^lVB$kJ@dX^B9I@PY9I5iNLd6S%TTF
ySppSD bjQ9e%yRw5qP=$dkuY+FSRaAVTGnVCVIE?Taqa#tqE:KA^FSIAA6%#kul?!ScX5Bqq^1mYkEQ8yyB^TF
Xp/:t4 L#R%!keNjWDAY%AL=/>5Ad8DpS$KyVSAIC+5Z4SW/$Dmcqqq@CaX5SYCwX=!t%^DpT6Dl@Kb/9CX9YAp
YpGqPw C<W$RcK@IqLV\ay%JW9GEB14YIwE^FRa+^@GM^B6l>mkR%udWyq1?V&l<9GPiDl?Y@tpZFqVB5\4AbD1
Zj!&8H IY9VBJN^mEkQaMWaldaShCkBe<u!FZDA/!PKw$T+H%lWYQN$9Lh+YRhF^N$^$kPY%<A15m?C5qA<jVec
PmRPAH AIwKIX^:TEXB?ik&RKnPZ!+5t&NZ\GLu#IA4\E+PZF<SW84K^I@tt?5wXlVLkE#Ke5ZJ5pF6m/X<eM!%
P&>4N: Guw#E/ta?96\tCytF>m!*S!ib/%YRtAqAWMJdaKqH6et^W8F^^Zj%M%=kjG!I@JMV%&Bk/byjj4h#WMy
PcTDB< =/M6QE!tm9pQCBB@9e#bLi:6h%M5HTcaTlX$@T5GED:4tdGd8GK6HR1!<DGj4FFSe&V&mwPKm%L=M<Dc
<ueHud SNNBV&tW@cu*WZ8kcwPll^La@iCHMb>yEnGm9DQP8dpcMn=9PYna+^GIAWBhl<lHd@H6l@Sb&8<K\#X*
5kcII1 D?<&mNJ*QjD<SeI=lwVtbXiX<qPM/<cH%lYww^N$$D5n+VdE\F%*%PdIJ#XXBy+%!P+@&+I>&Q\B+iCI
Ncq<+9 Lq!:^%*u^/MpDYaF^W?%^hh<SPT=@^bTM4tXm8+*1L>&iw>AwYT+NNPN$XMQWMRAH%mGy>S#yhEAwS&n
L?4*NJ LR@4YCaqHZML<kl^BjNMS$cCHt*THJqc=XNGk<tX&mQTwwS1qYPaB=wt<@MMYCtX<wDL@#l=BX6T@8y6
T6VblB 54La1+^h$5Kj%RIViBYyi+<y#QWCjNM!8h$A+bZ>^J&?n++!A$uGWGn@*HphV<tQ5>ZKAJwWDAFwF=Lk
TjdFX5 +9%\=dGQp@dteI@J<F^N/CX6B@!#HPPwTqetYpZ8k=$NY>CiA>WFm4hYF\TiQ=RYQT8wQX8GKLZiFH@9
FdSyq\ :q>kCFbK#cQIhuNI^p$6HRKEQJR%16bWZwpGhk/KFdn*Tu5Iw=hGX^Xj/F^WHMq=?D:nXNu?>M<E$#wh
^E=\bF ebX<<VMl^mw&5Sc@hb>Ra1Mk!\<K5FFqW9CSS+1nDK$1%qG?\IFTB1CNA=Pu$YZKF!!1n$5:<Q%^N58A
LGhVwM uT=Ita=B/HS54&&Bhm!SaF#16S$Cy8lcIi^==!C8:1WhZlEWdFC^SI=W^t8cBp==neimk%INZ#*aL8y+
u+k\&P HX%4FI&Eb/CB/5GV=$@ht\jRFGNYS#m<Xtj8J/@yGTjjHKZ#Winea\AE1IHRV8jIDKGWXD+b<#hE9B!4
Qt8<ji 4lt1A!h8V>%j#Pp#HyuutadJc@?+aIV8B+4Tc6w:$EFA8XFTFuTaPYcnbNBLh+:!+L&<:5Y+aD$*K:dn
Gu+iPa Iyhhk&pdBHDIN!w?\e+uyXkMKmcW8hNie#C/FQTcbtb1/IankELN?6Juq^n1Tt=mN#&n?cpWX1Z&K*5P
Hd:!tw c6WA/ZK:FV&M<tS*^y#iHna@@\LW>>LZQtBk%CID64yF!4B1Y\cY1tYwPhA1KwATVN?\pHbEYe?Hi1qc
mhFSS9 ?ec?1bE>m\!>JNi%XD^IX/kD<&G8VXe%BVtyEHGH5l9?9I4\m/Qe%ISMci%cVS:kZeJEt+^WKQHtV&\5
Bey@c! X=k$kNNeMN^Ii\k9AaA6\hZ\5edFNAqlwT&5cm4iyGy\yhT#KE>yM9RF@++>BDq=VBYCDwb%Q*A8E^+H
VP&JhD iN*&^Yj/DbCS6wye@KdhFDJb$w&T+^FTwC^Dtj=qAE>h?jPqF!8!^N$AVAnF>h1HTy@=FN@8PE*N6*Sq
K5wMcQ i=G*4^<qkK^l\CM!Bm8168A9N?nB886l+lMJPE:>4F@9i@K:I1bp^X1QM4=uZ?:1Vi>ICSKhI>cYL48k
4N:c*8 #>ldDqdR%GA>4tYRSejlJXWN5bm$t*uCYXD$E$Z6qWX&G>4BGX%E+Xbn@qSADi#HDGEAACDMIw4i&<ct
:ShHI: ?mWAGBn&kEn@qku?Cc1B+\bi+kGwcK8yDPTFSZupBdZ?C6q!/m#=>q!EQBj9DPVwppB<p:IaDMWKq%JK
wL56=\ 1mlCp+Lh$:u1?lBy8XIK^$^G%<F95PMNAMd1kqNhbmXNm5qtl9IKp=wGbaAmXh#pKbLw15dqLZZihi:R
eJeCq@ 6a/FwKc=RH>QCw=KM@YkdJiVQ1IZu&FntW8/KkK5a4GE4eN5TmJ%Ew*=aII\9eyhi/kwj8jFmb<RIR4k
a\/Z6W L<4L<EAVkLKZ\DNqaqpaB%e<XbcH6cq1JJ8nmJH!LjD5G6ASaHhk9LlaVYD56jAIS^a%t$YS9iF<AX\b
LDGjiV B\RFJm%j<wpkYmP89>c:bD:heyAJXhB^C$K*FTpDnL8SpDpL^yIS4b$5Qu#Q9mF\=^Gjmy%!RHG9HAlT
YLKLt9 DEe/YClBSdTMmGJVdIkmW@BMHQeFSR\Ga^ecZ#&tDcLL99SjG\!hliREdnY+?qiMtB=#VGJ=!u%=H$\p
!hm$^L ^pG/mjw5<EKimKplACLSMP+uPiEn+5=/SdypelZNRlNpYT*&emI</qtHZ=#5\RK$q/Kt6S1eV*tXQw9Y
8+KlaE %%ESA>D8eX4JuL5GYBT*C=JPG^ajJMJ/EWB6QbY=aEwXh8NQ:6&1aY#=9GjVYqPGSclhQ@EDGZADpEF\
!h%LL4 &jKmeKK+mFXb%\<b1C&GM!p?jE8K6l5/GdeRt%iSM/wFIcc16=k/q=jtJk+5\%FS!XSA#FcRHmwAwGlu
6m??SJ kDXIL^HJa@mLbmD?NhK6/Y<=TZ+enAPqnhC1XSQJY=AKhQQ:yG*wlC<P=e\8XXi$&yRMn6\GPdbLBV$:
^Vi6nX @KHZAC+X&!E4V5NcDPW4\K$p%>w&jG89YkXi/^RV*aBKWF/4iZL>lY<L:nClZlSKEp/8KH18RcGb:yc$
T\@*Ym $ab#wlATR#q\1wn1&4SYYJ%E4dFkK#CZT\H\aHd4=GZh41\CR58yk#KVwWykGVeItNJA%#dR!<XETMII
CEm<&q 9=lt!pD/iH8QVYwmYbH!EBRpl=jE#Bncdna1X1H?dEJAJKN4aDSNNR1AFEm&KpN#pyWyW1cP>K^nce4>
mwKRLn 1a:Zj\h9nhm/PY:1qbQqC?DnGEXM$eaAjptq\aR^=uKKjL<aS#1jYkR\WEyA?i/>!?*h\&Hjn#yb6W9E
i5E6j< tt45NFW!h</lCk\\S5:>KbawDGk^Bm>H^#\TCG$11h%4IPJ4SQ:hKIZ!M/I#EhtZ9jVe5JhVw\j^V*Wk
>F?%d8 !&YaBQK#C1>FNX/%E+p#nHjD+^C6=ETANtp%&M8DQ&?#D!Yj9HH%^TNIj=>/>H!5e%tSCD$QdJj=FX9K
B=Q^=J =6ak?%hl5qKMHH9yKEE+TcwG<P1Dt+mw%5q1!P$6H=lLJuk?Hu?e&TR*$yEDkHMt4bMADq:qCKW!LJHm
K:Kk<^ ZA#!J*W%=djy1hAI96lEI9ZpAqCK9a4E#WJ1V=#9q^M/K+m/TCKPBnmKEm*A=w9p=*$WRWZTe%BqJQdX
ZS+V!t B>1uTS?LmaZD*Z=Wad1m=NR!LqcDi=kw>mPI$!>DFXHTblnqMJR!1RZ<DX@P6c\NjdjAqBXFp<GjPPcM
^t#X5c mqBSYjRJI4RuThFR@mhAHw&GyM6TG8FMD&&89TK*C/4V<Kp:Ay&kRlDbAm\@QNQTbPkjK!6FCWqG9pXP
X^yJNy t!kuYhECL5kADVlSl\bLP<*<AuXiZ@a=1JS>H4$eknMZwe>w9tw%l+pMbeG*JPETmSe/nk>IuDmE4qNZ
/Pk<@= yE$SKp!y4FEA=G4PK\LAwMa#5SL4FBy+wWuBj@1wRVmVdRt1+WS?!kuZ5C%EJX++Ydm1ChGYw\^mYWW1
:!kZ?T @J>\Jq1bq/+1*1+t1mJJ$6X=#e1RQ1#p51bi5jK8n4<@nyD4dyLHZtPEt\H?hpWKR$bmk/F+AiBQI1CI
GV6twm FY>Z4y9IAd5I6ZAN\NlEQIew%mRK9/Ew:%FkncLWC\=tw@p9MJScqElZZnKHwNTwAS:1\IT<MB5R85pj
8Qnkb6 FcCRj!EWQAuBAeWd<uVQ?K5Ge@dX^^E5R@T^Wjy5SSKRwMuQMSu?BQCZAaklqKiCj*hM**K6*6pca/+>
1@*DW# +4TNGcVcbN:=ZAIBI&!Zy\kW^iFaqmNEilaBXt5IW@CTeHYlpC!e6cc8ppY=EP/$Bd=Ei8c48iI#<?BF
-AQ8da 00032bc4d1800110333 Page 46 of binaries1.zip
Bp%*a> AFFtIwpqHb$qm&6RGjFHyq?5j<HP&Bp86&dcSFL6!T?SAX?4M%6k4A6pTA?MTc?lNK6V1>ZFM#KRTD#k
l+9$65 w\\TbcY9M$RHLq5aKQ48y!>HwKh4a<?FwD>H/PYtW!q>c9M=/8Iul\FNGeAGDjlA#NhdX^d4BXjFm81J
9%>YmN y1uw$=hNQ4nynJtnJGl%@tG+MF/F?kIuL6GRK1yBelGhT%SSQR^ImcRKEF!1j1+*I#jN<E/m$=+aJ\81
Xw8Aw* *y/HVmGQHV@:P*%?=>^bI65>N<^@!^acG:AhbaZ=?Qp!NLXYtSiME?X4mMQX^YMAX!ACQ!uMb!6D&9GA
IPj>uM NJLc/Ct@pWb\eTP+8wX/YEnH=ebVFe&uhSBh9=pCDPYcQLMYA%cVKa%+dkJc1Ilu!YkGR/HC:EkK@FKI
lh?m#N 4:ZTB/>#u/%Dan>>=nH&qHw44jZt?H49iYEyWXScd$MK\byIln6*656CC4H#V+*t$:HmYm%1pwb94^a+
j<Aq5n KTee5\AGnjP>A$JjBnT<uq$?8%hpmNd4pbF*bA9nQcYA4Imw#61MK&uBk1C15E%BFI@uE6TAbuL=Iy%:
jpmSp% C@l!$Iq\^D8@Fj9X&miM<T1M?X:bHdHZCT86:/B5j//*HT<mB+1ebh*:wBAlGnAH\ARHulD9ZpTm1IbL
RpTi^& T>VtL<kBD:c#BITia!FY^e=K!TFKH/QCDntH:ZM1PPn%>Wn$?hbw=H8EeDXC8JXhaw^PiW5XMlT@byLA
:b5iQ\ JJJ9hTS!CeM9A!R%PCNuT5P#kL69+8>?YA89#yd&Ka4EYL$W#dJXJLmkJVVZ+y@Am?BEK&RMi@\i*!V!
5d*%8% jX*W?dwaith$!K9wtV%i5>clh%$V<$YJZ&$5\T=%tFB>QpXNZAVQcpeIH?F=K/y/b$*uHW%F^kkS*/mE
T?9ukQ IejQNAl%Yt8#I%YqPPDQPAP+ITE1cGG1Iu<#EqKEFmKSqCRbb6h#SJFm!^MA!FWS&&NEAcaTL/S\mWmS
?*cI1p =bX8!^V=1TWtywdj!&y</Mc%X^4EA=S/tjqb?Q^QDSbc5cSR%tBB:ZmT==<?XYaIWHRj<c5Wi$/uT+4W
1PK\Dw /AF1*FnqE#/ii<<p:D$h*YmZcMNKQP?bbP&Th>+l#<a6n8KwLpR4TV$kCpSLm1Q1:wJRTm^KP5SLXM+S
1yEph8 iZXRnm6WGGZh&:l^*?d9wLcYlEGi:#1hSeaP9X5ddlBc6!G9\Djj%tuV^j&d94NmXM$Tbw*VtCRCm$Rw
I6k?FC Yc5aabKuiu!4:b1<mGPJ>%y%:>*K&#jqdH5n**$!<h:y#TGJG??>&Z:9\<b>Sy5&*6pceZQH^ce:9w8&
NS:lT@ SS\CdV8*#THAm:eN9*@pN=E<ljd!K^y81q@#XyV=69jAnT@BFh#&mPFmWSiRjV=lu&VHuK%k#4?a8Ab5
iQ4$^^ Cmw6emnynRPJWeY8ZXDKbuV&\=KN*:j%<9mKmaLIHh6jIAF?b\KD4^Xy6G*9@9It8+V9y$8cEm8LA4VB
^5bX<L !?TEQnXmu1A*yC#mS@ue4y&#e\Dppat$WCu!Put84yl^1ay^jqhSVGZ9W\L^aXpmmjCl$WT!b56KRYZp
QKcwI9 @Pc=H<X#j=Z?kFTyIey:u??Kp1pEwcn*pY\SR&jQt<wj5uZEw%FF6?49jmKElyyI?k49t*@9uT1NjFq9
Cm/Xe^ a>FkJ>?Rj&kZw^AAinlHW/Gd1L9Dn6ZiD/%Ye&1eicZ/QB$J/DZ?&LJ94p?Bek&!1a#eV<QcqVh6?L#9
b\ujk< !+hNpih&*R?M59N6*P6>kBl>RZ#8ILB+Zt^:WP%M\h!lSn99ub9ca*@5c==^X9KN=j!aiLmj%X#$@eCq
P<!T<B +\%Sue%&uKd>$\A@1H=V//Ej!We&HVt<@>DlVaePS@pLGZ8P>D5hWj8/p/VRHLZ8MG#@wRMGY6G1Lj9*
/@R8Sb N=MR\ke!l!@>cCEyCb>QmVd>Ld^$a>P=mJcj\Z@@ND91h@4RA^jSn:?Ft\Ndi=?%S>5AJE@SybAYi:9Y
%IDNpK cH>\5??^!&uHjyb*/Fkjm@#eebq%dD4w/PZDD!>HhYFES*?8:!CGhWV9:#mkeZma%Yu%+dl>+8E%bq&d
G$Wt+W ^&/Tny+apit/QNK=icnN:tnHk#PhcujdDtTe5L@TV94a>iBb/aEQ4R??H+?8mjq=9bH$<HV$@e+Hh<:+
9YyImk HD1y4yJD8uj!^/?VD\+iP\k:FaM/hYDnKZY#$=h9uHuwuKP8*1Q8&XQX&lQn+?XAQZ9R>8#tm&i9^HT:
M6J6M/ u8#ii?V$k/\#SNZ#/4tiX\I9Bn:jj@uT/X@4#^?WQ&9@8Xhd?eKY5QMQ!*6@Sb!N1d#$eNiFl#8:%YM8
JCd8&b Pi\+@$6$1inK^T6dLl/<plB6%c6?:LLD<T5^mXeeDl=#5P1MGdq\PclQ9iDK4&iZa1a8Hd^^be9S1<@w
1n=&wj 51JqVjGlW%h\X&QiZXyFuj*%?NRnJZHMS@HB4=IayY8PP9%lc@ym:pmc=j5jjyh56bcRde<>MllWj*XF
J=bc#1 @eNA5=Xp%Z@kWelAZ<RRPY1\PZBwNY!wd>*&b6jll%88>XpMP<cJ?>ce/\/H54\A=yLc&ehd%E6H45\Q
pKmj9n @!JDIeac@MMKppW5Z/wy8a!W9IAD%cic>>*ej?5ayXyVRpbRPWniJ>pIAKA+R5AVM5Lmm:F=I/8dJI?T
XY/6F@ S*KmTe^J5nlW%d&^VS1N+N!1e?m<wbl&<*IwS6TwKXppWQAK6qBbTJeK=JGY8AaB@CTZ4iJF^Seh=*j%
4%EVQ@ ?W=ehdtlVTBI?lVtC@aJCLJAM$u!\+?bwM=+1/SBAmAETBS1e556<cNu\+heJ\=6pkDycEmPAtbHnuC4
C\=Npu %4NIJZ+jGeC<abJhkta6SHhW:89N@uY<JW/&YewkT$+lB9PS+MqAeRJP58pY^E>b*KSyb+@pZR>?GHTu
1+id&\ GVaS6&Hp5WP:EA+X9@@PhFTR/>Duh<j*D&QFQp4CG*XTkMlclG&CQZl+5@H1tZ*TXDI#?#T9KBSEw:m?
iM6wq/ W$eN=XkL/6IX<4FHF9Q%eN/Qt%6<H@?!99h++<RYpER^4^X>Ww*5A9k#mATTHI54M>@$?66tKkWn#^>E
nctLdN #Q$>9?Z#p#mu=$/5=%8t$SYNACTMJn/5S1qHCMY1<$\eYEGmjCP1l5Ip+ZC1*J:6!yQ^I<*ZNQaJ#=LF
F&#=HY SB<yIDPWBBWl!d^bPakKkiYwRD&lTe*XjF+9Z+mBZ@P>5>X#/Y@WK?i/998SWMldRQ^FEc\uTBtKPjcY
w+qP9M @FSXul!e814cdLL<yK#+!c%GKWCin%ZnqYlRDDHM%*l?L1cp<PlmIZJ?pTTP/N<iiQXc&FIj:!\4NBB$
A#t%ZV W?FYR<AiSi+qM:HDCn<C*/KJhp&<eGVD<uYbd*>6?ZG>>dKI9<euY=Qq<k6IkQb:aWGKDLYI$QT^??1#
4$wtIl #=WjQ6@Q^HT\C=uBC9M4=QpH^FZZd\epQ++eYh*LJF/jTcT?^qG/AYa8BZ69CT1DACR<AP&wn+cWDqCZ
lSn$uI t/1%DbBq4kuhe**G6tw%:9NV>\ppDd$>*5<X>+iimnLd=@6CTc%lI5*/wQ?L=*99i%>4WpCZb>#:aZdm
XFAMRc FSTmiFR<iZZ:ya\Aa&ZT*wDP5PNld=RQ*M$?G^bw$HA&?TR=Y^$1tbH^iZ:1jqTX%+LCt:*>il1ZS5$d
=Z>\in j!CiWDj6nQ<\hZ^a:lq@>>PePyQ>86pP4hhF@6J5HcP1kdZt9Xn@N!dNN%M?jN!b9h9:/J&$F=KyytY$
#EpL5% Tnh+<@K8^wuA\\?>LZ<%#&=$*j@E\#bt%ZqHchQDbV4S*P!BNCy\ckBW$A:eh?Xy\ew1+=n/q98ZN64F
GMn89> %d^@68jB^=W6Y:XWY&@e@d:Bcj9/hSQK$l@dju%**/XSA<qSY:>q?6P%&?QI4<#ALYpIXp+T1bqebbeL
bFeSH4 XAnyG4ItNb@*\%\#VSp4+t:bmXXt4eND?eFV45a1=<9F$IT!IG!I$5Cp&#4m6hPlc#R<N#^LM5XTKFKA
*/iuK5 eLS9m++^@8bJ*iFZ&DRFN+YiX6KN*Ab@a=>Q=#b4:RMwKkJp@@l^NX@=NyGqC*/t/ibkjj/I\bDC+EP/
<+!1Hk h<nY=@1*PP4XtYA^h#8k\l5ja6!YM:&9#:q>a4h:WH=CJ5N\eSK/Wb/Rbh#w>@p1AlyEGLK#H?nShRu$
D=i!E+ P?jdVVieV\ZC1ub&EN*XaQq@KW\RH1hbn>DQ=<WFD*?1IRQcPV@*KJbG#8LLl5E9<IkN:^^mAt&&!cdP
AN8IS6 lB?<GnSSAP6ie$<MmXaEkcWe?&4hVX^!qSBa#S1@eDZDIj#:NqHSk+lDub5j#J++W9kE??a\%J=@I\qR
>%y>XF l/G#=RYG#LNFeW4YL9=4N#awyTRW6bpGH*^6%=Yp?5^8hF9FDT>:9^M4J#VY^Z?@?:p\Pi^\$N:u>#PM
!Hktph p\!qXGSS#a5jV/D+8RV$Gw*?H+8WF@T:Q%wYLG6<n/bqGVbRd^/nJtBLp4I$NSW:enBSL*$a*>5#jmEH
XKWB9L V8>E9GKpH>bNJb5jju+#Ml5nqFE>aLlkQuk@/T98a^Q99P/:m9mDE<GDNc#cdl$Sn=YTBR1I1$ByAm@Y
%9D$Vh >XAJ*1pqlGS4$ib#<KLDdj&nhT?&E!1CF8TANmucSDRmcXSFJuZ:cZ%?y@?^hXun/n9^<:?i4mp9HF?&
>9QSnk 6\SA6R6wANF=iIj!RPt?@MQeT%>MDyhp@<np@Xl*<9w%<4$N::@HVZ^><m9?Jp%FB1R<KTKIkb=<&M5^
N>+c^@ 8w<cJAG6ZKGq@@*hcuSk&6<8u\K51^n:WSYl?@mVFhyeKHHn1?S4HS9Qh5d@YlXp!*!W/LCNT<S\PH6!
HHJPD* C#JSEe=G/<8DGC##i@iViah:@J##6\YCG1VHbLK8iFWPW#6l!w?EwBcYuK%aW:I:<*H?p!Kyt?iylkZ&
=+lY6G i<G4cS&*5??BA$X\XT1iX<8@@GkkWlMJDl&Aj*VCQH$pX&uBSk<8*XScME*dXbYC8VI!kGm6#nGdV<+C
IuXLmG tWWceQW&Tw9wE5kWA$lcIBt/yCRAlWlqQ=>hRSe5Sn\$<G%:@BB9J%tX<@b\d>w6/ELWDupAeGaS6=LF
:NT/mq uElpua*y+9/Rmp<&?y/&&$!c^*$de&@e18ZYW?+L*<5YN<9kcM+KdLT=PpZKchkRK\5C5YkKw\a!icAy
F*>:JJ WZe*J%i!8n<1\ma<TYA+n&Z8+l^&j4njSS&ThRDd\yEj>QJFYcW&?<\>NF6ZjdH^>8dwRP?ZVlYV*lly
\1t:\I JGcuXbVYGKMcjYLTCe<JX=F\lHBL1EjkQwu/<%%+\b+u&+K<u48%><$i&BP4MKu@\qT!E1p<SGaA$kZC
Lii@V: E9/StyZ@y?GC5!<NC1!CScGK\hAcY@awSNawB!4*<cHYMLeY*mJ#@\=:ucQlP+*1$G9KHqYN5jDqnN$L
9kF*5c 9b818u6a\NJtqjqB^Akw=<TmdN6PH>+bSL4698=p/5tC4ty9#EPQDQ@eW>dm?VLiknt1/DNGjEJ8j&&?
Zbi9NR bluP4KZA+>l5KwjJ@JhEuZ?Hqt^6>S>y!ZT:@^wq<#<Q@+Eqa@&@\5#?#!l8VjCjC>uSKBa$C+1%yTZF
t&EG&9 ^6d/9*F+\muYXnd@+=RAm4Z6j!j!@K@Z6QlujLQqQ<:<9\Hj4C/HFM!LF?B$a9ZR\Ib8MMdMVw&HVGWN
:wMcbu Y=N*i/Fk%J\^D1ZB=&n>jMpyF+5T=WHppn5lp:c:Gp+I1y%lIW9pDF9XMp5TVhTbbc$?i\tynPQn@BBt
d1pHhi pAiide^GLQJ&?eBDL?CGB8w1Zl#deZZ6t1ui6>6hN=P1V:%+pH4=TFDu:jT:IPhCFa&IG$T+pmpZDI%J
n<Va1L CP&yyqFP<qS%&WAhT>cD4qcFNZD!i5SJ5*lH*<>uZR<&6Ewh*lnEp9jWJJB:j!cPHp9ItW?4PiB$y8@&
M4Xjp? %PKud:H#4AH*6lea*/Q5WM4PDRkYycCIaTJn%+<%?KIP:>&k$SS>e6?jNXHK%>NwX?m%$/<dpJJn/JXe
-AGZ9& 000d7691c3800110333 Page 47 of binaries1.zip
/bNK9b pcuyR!LC>Qk9\=8I<j:JCT5JM+qwVY*mEp8l5l=pBC!9XL+W/8iuWlbEYZ1PPEN=a9tuaX=dDImaT@Vl
R\4?lV p&<n=N%k4X5jD<4Swl88YFS\Zk#XFAY@a9n9*H4H@tPTN>G6YFbpkwC=H9naJ\^?$Zn1VRKnnmtCV=Aw
*c$Ge% 9M9Zt55pZZc+M=tb#5hhkSBua\T%&89DDS\#T*HkJE%IPC>\&PE/6KiYa%>1RZuJR8Ct6=I<k:jSy8^\
d\:B&6 dyH1>KtY*wi*V%b*Ei@kZM6>Lt@ky9qlLc#1TEFuRb:=:bQYnt4IDVwm%nDpyLi8*J$*pdTc9a<*E*B=
m1wmkY :>d:iFihmQP*QipjV<Btl>4eKcWV?>>H$h:GBWSE+Dut!LBu9Zan>c/uF5L>4i8<jD=6P=JhC5p4#Z6M
=\mV5# QZwT#@umL$<#/5!>NwT!Eqhml:/jT!/cd5*Y$QV/lP9$nZ=@cH%8VH&YZ8HMdIGM#kYdqcTHmcHdhHVu
K/SX>6 \pQQ9p>Rdnq8cHB*&L9t*6/9!#cly^+t%uJ1*Aha8%Y54TJCFJYjdyuMQy#B6KEjQS@#NC\9$@nq?hY6
j%aRcT M&WuL^#L=t\a88mV\K>tuR#48Z4<RC@>h=4@Qb5ZcATGH@1Y!H::>k5lIjKWA>/G9#Q#5e$Ai5K!>MCL
hVn1AA Qe+ZJu/QbERGlMHI//iiw<\G!Sj?bpjGiGZk=jy$Au*#=ypmh<VJbPLh6L:p+^/DC1WPbG>F>c^4d!iY
+8XlQn Z4>cnl1I<Q9iX@AlInKwNi1Y#+pI#*6lJ!<1iZ#enk:lBT6ttb^!W#G#j*dD*JN8Ji<++<@dbLYdQ@^#
^md8N# !=:Sp8\4jjeh#:&:q/jyW%^\ZT@5/8n4=>aNZ$98l8>yL=Cl*m*&/N<\1@Vh4iLEEY5qn&=lRyMu<5^9
K9lN!9 *R8>G:qdQI%QFS#8HM:BViiaSdLPI6S#H9$Pk9%G+JVVP8/Y%D+iw%u:QLJ%Sb4YR^:GBu61nLe6e>RG
4y>Jcy e6IE6L>GYSX8GK1&V5uNKCq#1Ya1&ME\a!icj6t#R=1R&=@X^dW@N?R5HQCYbK<@n/aGC%Mi*9uIiPZ6
A#y$$@ *ILK!h4:<Gkbe8nC&TLG?%C+Xm/qucHl*4*lXuicd!+mWD$%pQVp<1/e#1>?D44i=CA+qyQ!+>GqX%AM
#*B:bw V>SbePwF??y>Lc%tYbYWV\Z:ubM&/ej4uQdG*?B+@qCy8>6Z:JA4JmB%QIRDCXiR!>h5ttHy*a*G^Z9P
y59mXB &kYdFD+RVmi/+G:4&V4CtTTeY&L&%F:=c!9VS!QTR+Q?DGJ4GC8F91<j:Zlb?XWEnR*ECE=dbb1P:e@l
ZcjwlM 4n$mwJdZ/>:X>84DQq@5RKdeZ!\Pn>>Jll<+<1KVb%H&8=LeF56+A<^e9$>Qc+B?51anI1!Twm9pbC=5
AdV5Gn QqyZ%\\PQ\khTHcV\S$Rm#PIe5wIwX?uVwi%@way:S//WQV!dH/^Y/1>N#LW:1K^^?4STqthI>uZNk9A
iK69pe >^uQD+=F/::VCGdt=l?=MldX1SE/?YPy*Wm:cZ*HlicD4:=1Bh94\q>MZh14Y^Qw?\aVMIGlW@jPHXt4
96FN@5 5!HeS@Kq=$ZwByZy=>=hYKtE?VSecyZBTV$XRL&L:Kl4eMctM^iRh+Kkm$ppbIMQPpwqCSh&?Yq^Ycjj
\9VF@N qQFG4cqpFiTb+N+w@VVh&jMN4V&:DH48&wXFhL%14%M&8mNMI=^+4w8<8euk\GljBmt@Q#qu:PFMdWwG
SS+L^: V6Rih*=\MeL/p6</dX:%u55b%H$=N:unpZZtL^T:CuN84Y*X+TqPIE+1Z\!chjTSy\F1uTW4Q/uiuTtu
haiu=< d?CS+tt%AVjD^J:P/#b:4LS8Jhce111lQu=i8J=+>C^@V%qHMT^^t:LP%%K@G/HR$nRG:\J\6G#+#hMi
I+4JFy u\hleW5&<&jZEF5#u$P1bTwDTk<j9=C^9d%$c65ij+^c=d#%*SdhlD$L&tE?&@VTh*&%8cn6F@K&1HNt
V#<q8* 1KRqFKLlFPcJ:b#9w6>WXkpbZM%NI%!4a9!F6@P=XB5$G*Ze6tKQY?cyc8NBQ^H>SZEwP9yY%4S8%1p9
\@Bn?\ 6Gi>uw:*:8TbJ><FXMb8Pe6ESb<MPXBWpnL&R:P4#<:+LdtFtalpbjwkq%MAYHECaTqiM*h*EHpQTh$9
T!mljp *>Fq^9nCnyj=J+8qE/IKbR?y\X%Wm*@N+a19>du6nn<qRX^#G/Z?\wBuj#8!>d=L>IiiJF*b=nd@<Iuu
B*&9!6 Gn*F/>8me\$jQn=B/J%=?8Ym8W&?m968E?Vhp%aZZEP*q!EQ1JGL>!aE&:Y9&#iT>eBdb?8JY$e*455k
nB$YM6 %1</F?+cj6y#?5X#9!9Qdj*XV8BG:#my85*6>&KFIYcc?e1W#6PeV49D%Q8@D1b5!n##SCZt@XiNq4Rj
N/1IRE %Z9\Hu=qtSeWcTuN96@qFtTiZLna@WTD?C#+RhhnWFDPEX%Cl1*J8%5eZ1bp@@DTkePMM*4ICN&$ZhP/
\FbkXw edJHV=G+5&186:*ZPwKj/^JuYaFyJj=I*d1LkkAj:%iya<KHeT4%Kj=i4C>/<PjwP>hGD>yQb<dyLhZ8
S$:EY9 4&WTJ+9Y!FB:45PbV>m!G&Te%N=i!YZV9bWTFQ!VeBJmMBklw/*FGqhG:*e%Q&&ZhpRP8/^&Nm1:$@H>
@Bjp^e >!GVQJPi&FQ=D@iVWbTHk@9?X4q^?*18Dhq$cJQhR:YK%a@&8M%cNmGJR<yb@V:D=++h@ZF#aVYmAw+j
p^KKaK H>G@tS%W6P:C<DYjw4L!>?X6Q5Wd:41apeT9%b8Q#aYh%5^/Rjh:hGP#MpyQ4m8uP!j!J*\GKdPRejG?
wNW<hd JuuJ1t\6mVdZ/5NyLD/%+96m>DTu8VYWjhVeWBD?$%#VXd>u=$DFSG9NHwNwiuGAQB:ny**N/J$/lF*I
SXMeTI Y4<\Q@^qZ9!iCuAR*GAMPEQFVPkcd+R\e\@S&NZ>$aiNu^RaX6ViAG!aT<H!SXjpJ*Z/9!QbPen*:!Ch
K=W<Sl Hb>qF4AqSX<M=AJQ%6>cGQ/%llp//JjT!lq:n&:8G8i?9wNMEK:Z6bSdQlChjGGDPNN:>F9TB/bdchYW
>tB:kX i!%91BBbYlJ%p9BcLljbak<P@Qbc@yLD1Vt$8>*<%ctq*TY@pEt@mkXjMwjHbFiP\mI*thbuHpjc9*n^
qNZ?WY YpmkWQ:X*Nnc<9>q/K+h=d>#F@<*wd5Y@!hH<V>Ch/&6@1>Ch<MMI4m8ESFbXCyX^!9JR*5Nm&Pd:M8M
Jt4YC\ MnQbaBuqFYkjHSTpt:F&ZZ=<ZN!GKN>%wi6hHXnM>abGLC<ebwN&yJNZ6ub$XJCVkd/Zu&pP#>lG*=!X
Q1H/?& F@aQSt?$SiIcG^9HyBSZ>:Z4DX#Ve<MVk%I&&Hk:Ynq+=4lThdLYbdnmMDwShP<<q:\5X1b*9uGAT/CJ
==lL!I j#/D8aGtdY4y4t&qc<jepP!h:P1wVW*Sw?q/b:kt?:NM1JdBnkctJ1p<b4!:t#ePp?%luY8iH1Rj9eEt
Q!RDeZ jJ%9eIK9n>G/6QZ$8BSZR+8\PK1n8%Y+lct#Y$bIR1=nuH&KIhWt$T58w5Dbly=8Sujl<Bk+VK^844FJ
bGpED< GC%e*!I$*D\@MIibGBYawPQ9!hIPM>ZQwP9T9NpSedu^hP6I&^Ctm=P8m+=hmub\ZFSmQw8Y/?DA$Mhl
%$#ZZ6 jDNV*cQ?kb?%#wtqM+QZb<i/^!Rt$ZKN54^!I?LYtZlTLTL<C>JN>j#%A1QVVT\V/VRjV$6PTQ/j=<l$
aatHLK 5HeL\&G51Y+$bt^MWpE/b\Qh&+Gc^+np?1hbS8b:GKjb^q4yy&YqlDn=iGYqiwe^cQHl#ID%LN8IkK!%
^qpq$q =pql?Rpy&Zal@\DNG1b=8Ah!A>cbBajbY\VHlJ6a4I*WDR#tyaXHi@ICLKuGecb45?u?qp#D6cEdA4Qh
w%/NGJ dK&##Hpl&n44GXqJLuq?PE!+4%qej8TcNAh1iKal$>e\RVh44W%Pupi/N#W6N=md#hmRt=GYc8MYq??d
tN9ZW& ylh5q?hw4yjK6qn9ciBIZbPiGlL#y$Y$:YLVGL1BmTdS/dpJmcqt&d1?*5//LE8:1A&&khHJ<X\/i**<
ZeM<n+ ?yR%eVEeq!kj?+A%8X=M:cA%cV:e6TEea$81L\:D5+#%Z/@4ql/!ITDF%<#hM>++t<EPmQXl@kPMT\&%
8yThl1 =&Xt4jNPMLR\al5EPH9ye8JbRY:4iLH46D*%>E*!A6%$ebnw@D^P#n<A#=H^>4q?<cqb9yuckX:P\VGy
h%M6tH Dpa^wc!<=L\kQ&6DL?>Mt4WVJ#J6#byeHb6<9>kp+/BwH#iQJIhWHCa5P#*FN#A^IVPL5<:eP>@M%5I\
uuF6Mb IE:dMq*d*elknaEj^!@T%n\\P+QBhGBH44i^N>F&hDSK%Hcnl+iE8Q9:J>t:@cpL&\V*HNPR6Zy4@kHG
Gm4X!\ ZS9k1=&edYRTdJEeE^<R:tnu:^IhbtyuH8Q1HSt>N5:R!DZX%C%G%>ZjNnkqQePVHbutnMMaiuu+&4Hy
QedZKX GipY6DY/69wPKYc5hW=5u%l8G5QF^M+<NaBydBWZ=^BPT<:MeZTP6I>m@Y9w4nZ>9+L8Y66c@VN$%@cj
c$e<P< wd8&@#b$%@bjRui6@^q?c$*@n?BeB8Njd#4a@B6bG>6@udZ>4:QY69<c8t9N?K?#hL9@JG9*d&S6@nWw
y8y:Ei &Id&Z&i6@6#kZ&a6@w$5:V?=4?X@udXp@Chb1*<n?=?>L@*j!F4>c:m^#d>SX=aY@$u&*/m4@*Ru#Pdj
BE4Pw? KC\d1*>h$Dd@StHb$tn@P969FJa%#jJjbt*@+?/hNj&@*L*:H\#6@:b:^:D+=>$:&*?^i&hNw>9>@+h<
hm9iKw VT&%:Q@u=G6ZC48QW/9/yY^iX\C=@>Ym=ct&kQ:B5\mw>mT=FG9<^KydqKF:Bc8VFH?9P6HE1>@TqHnL
SkK/%w ?ja#a4?>?=$9+APdG:*Xi=qLh/yJ4DTEDd@5\:p86da*ddVnh<=k*H=MdGB\DE:t@cW>Y@b=NJlaXnj/
YY*4FM \4:Wctkh6icNi==VlGZ>W&W9*!%Y$jj&mAeJy*wIj=Em?c:RT&X:P?:FuQ^apH:*@AummKub&?:EbIV%
KhWSQD eXWNJ:=4lM9n8mF1jmp5k*=^qF1dFj*k+tm1bC\m1*c*^+uyN$a^YI&D=NtQYW6nEdcjWX9ad@:cWtaS
jEA\lq :Iych?y<W?dFdpdH$<n8^MM\M6bP?^$4R4ZA!ML\#8hb$cBAb+!I^Pn/&59h9aL!CD@*@BW4@E^*6PSp
$$cuW% %ud<N+<t%@lle>/JXM6ZnMTDP/$!ltN&e:>iCTce@:L=X/jXkd:Ri>WZaX>Jb@e=c&SGYPTuhV%aN6*j
VhHp8P iQd8/Q!^<L8u8mbQ<e=Z>cV>$n^+G1H8@HTd?Rt=tA:4Z?qQV&a:dpS%DBiZapijpn$y=#Ml#F/%@Gd>
%p?J#W p?$IqTeLn1WQ%bG/I>6RWMuTA+@+Ek\@>FXZ96*d%a9h=$<dcie@PQp8din!1Z%uI=*?Xyy<H:#8WFSb
81Fq:! w<c4=\@&Hj%<%55BM$jAQntG5m4c&dR?h9V:in&X/59/eiL*qp$eS$9Vy&a9d><b!bm$jmi@<EnD!/kk
DKkqG5 ?T9J1Tj%h5k9Cje+L@yAZ9e5lJt\dhIw+@C\>wLt#nh<JP=Y*&L?D$nmSamZRwBSLiF>%PYZaWj*duFy
TWJq@! ?jR*lGutuu/@cy@BDT!@@uWbV/S1!+*?iL8bdnbjc&twd:^#D/a^BQ+SVqCcQIcllccMywX%DleiQ/l\
dSc*6I pmNu=&nY5*\6555t\@n^Y1JldP^V/u/j5nSRVaXew%^bFimS^ST:#%Rh#I88QmG$6:@*/dBGecG=d<tE
Th?SG@ i#9!c=M8N>Em>cbB^e#Cw/*bZl>F5eQcd<X^\5Th+ld<!Jhe>aF$e@hh#I5nKl1KVI/bpaZn*mNJ=uJS
%&Ndd^ ^&*Z$W/M&/$+*+98+&+b:ycWw\k9H^^Q>/nyXBtueL1nMnH4h%Jt#><dZVlCwGFN:y>51#V?@1B#1=jQ
-Ap>DJ 000b9ac48a400110333 Page 48 of binaries1.zip
&JlL&9 w9*N@PlpZDyh^8l?y5y*F>*ut=4*9@C\HC=bQw%>?Jk*PnX@&hdZ*Qj%#@Zhpt5PA@F4%e>NHjR+H>6H
\NWMeC G*5eQ+=D$QW**S:^i=Q5bqlX&49ZQZj5$MG#NyEumY?64bjG>yG?J>?/qL\98R>nTLT8T\9iAm5e$XAL
KhwYS\ M!4CQI+>i:S/+LC!N8j+hQ*b#S6<%NZYJ#bWZ=!iY^9ayHa\+p%u4pZck=PKqI*Jwah#hQeRa%/!Vl$K
&$tI!p hIdj<R!+L1&c>Cw49Wm:wAjEFBnEAui*l!$Y8MZhXVKdu4V>@:D**qFN>i*ib^KT$BJ1kFAN9WMI9aeY
?n%d&l i8<>wjeP$6VRpTbhRNSRyW5ZEJZiP\mwmDRSEBWSFdHN@e\===$#=:u9>:uu#Hyu#Xw#j:FC%wjj*8!L
mEN1yu H>uj::/84+FP&CjdbjZ5JdnbZLY9NFNDl?a!X^VjPNZh?9w4EBwRS&q9KilFSFINJcS+ETKTi6*i=QyH
Jan!ei B?FKFN/p4m$p%>eL$1jQebnWMA?y&=KDqwkMM4>III#C9@dy>H%$SAy=N*:5duSw<hynW*Cbmh1RbX*^
T6Rb:K &n6mmSPtdK@JQ:y#Y+ulkiGCVG51^YLB$JLtJ/X^5^:tP&#PT:S!Q#MNy^?jJYRuEFMiH<9/M9\MFwe$
iE<#<F GiC8*X^\/:>Q>HuWLNa1b$NJK#lq&pXN%j1<%h\j*?\A9:^+$!DXZdT$RmZD5@k6c#eyDl+:/Q?Xde%G
wP=\d# 8ASiMLRX*$V9Iy=peQ8D#qE+9H<6hj>w#=?bS?ch!Dp$>/W:5E>G55CJibN/Y=jSwn8<YZ96JTX=?mYk
mZ#1XI n!iTNDChJZY6KVI^ZAHG*FnCh>h6qXL&!>kX@NlV\n4jAdVpt:wuC?^PEH^<NKWlaZG@^XW$8X%ML1Xb
iA#Rnb a&LnyY@yjSwwW!j#\=P:Ca<Fy%wTPI!4b#PhM<*THMk$ZAyDYB5iKe=$T:AP4qK<lYWHRIBiLAiNW@HL
+SqmIH a>HSN&6QS&5kX!\@ZjJ:&4p&Aqt+&/ye+Z#a69iRleQnA#Et&E5Zi!V*E!l:@d:#\YC!+:5a/cKtGX!b
\W!!\Y 4uZ*>!Y9E+i6me9XjVNJ$I!<:d#Ryt>9*nA=h/Meim@Q$B@^EphauZe$P:?!l=AZJnW!h&@p%D/^jGEY
<K&9=a pCNQlt6VanF1QdlpEC+\=mh/$=Ve:mepL=QFN55:+ZnlmIM5>e:L>&J59JqnD5#8dFE&BSFtMn*Qw8tQ
MV>e6a Hi<91p8I>#+P@%Ka#ZBuiyFQ&=yi!lNh5>LX/M!hj?9S$Ck<p!^eFZeHw*k4y9uFZVGQn&p#L<4<KFW%
qZHLiW uHAM$%W8$JF:BQh*6XTHE4etauPij&d?Pc=dj59hX61eA&yDq\N<KSu#k=LDN8qVj@Cntq*<?t#%?&9%
ELXPI* q@8Q5twi?Y1#h>p<XQjHNa6H9XZ:5QJ>T5Tuqj9<*X6XublM#+MLc#=St!Q9wn/F\AhVua>?T+cH$T!T
=YVAA5 u&R\MLdHNqCZ<1mZ#5$X@eLjB9Fp&WwAH\m&IBhn8==:K+>bG@@McG:C/Z?y%ZF19lcc4Z4kTSPTc5Ya
8T:H$c j9N\<y5GhG8qTPiTk&Min+Bi!yaI6Ec5SXXK#ey8n:$\8pd5WY#L?id*LQS<Ye%9TtaltZ1cZ:G9jXT!
AjGkD* J+NY#YbVT+n#8pbh>RI:p/j8w4<i<H6J#ankY*b?y+Np4<@a:M4hln\jVFiVDtF?%GnXSX\GDm!MVTQh
\+1>qm YqKjmjaQytR>dM\c9D:Rh$BlK<aeMV4k%tw!K4w#5DjR@8a1H#cMZ>nB!^e@yDYqtly^!u>u#@lHRH4Y
6?8Lt@ 5ybc:D*5=K:tN6SI&1\E9p>GtY\%8ieMIDi:R\$%BHl%9nGu>N>#%aW1p??pmb?Lw$hcp^\P\LYB+Nw:
n1A9/m TVIlYLQ&MZ\H*$=5K:FIXJZC++B1X?ub$FGZ5b/8Lw$nQXnG>%lPm5/XD*@L<E:+nYnJkRQVFnWQ6*Yj
#u%Twh ?wESkVGJ?5+?Hb:+/\I4KenC^t$E#%H#Y+t#PmNFVb#Cl=tL6??Lp$B9:!8EiJ=j+a6ldtpJid9!<<Mh
LEDeyT \iEMbdwu#MIi9G<%jic@BHn/*Su\\9B%Hl8aFiaaLXBQ9VG!Yu94ESM5=yJZJ&:aFJZSQ$*qD\bh*G<m
AdNEat u6eeYIn#^chp%adT/d&b=Enh6GucJ1hiW9Xa@%H4WZVwX8qy%+t8hK:l16+Z/9:ame?I:$Z=$pD<pucq
MVNuRu PD%54w+&=NR/iKcENZ6qNB*FD^$N$KTj#I&Dc6^^BL@eAK<:nd\8NP=1QRctjQAil%14y5VN4VjcEWRj
<::&wJ jdCQ&H/qLqTLt\^*d:SB:!PQb$%LXEc<?=TZb<NeXi1cWDbPQ%Wpi4j%\WnP^/Eu6QM4niP45AcAu*hl
MC=:&q ^ARmy<b9/#mSwmaIq/MQTe%^cilQGA&:Mq=JZNwwFa>iTkpL%Y%NFK:e&Y?l1S?AX6?BCi@ht8PJGF?%
L&II## G#41FW5MFy!TQh!K%X1*<J+IQ/K:/@*q\!qZ^BSN+#KRRd<I!lD^NRNV4d5ti1kR8e!qu>>cih*HcaFH
C$4qw% jJ<=5FK8CbMJC+FhA*i\%?WRnuRaGl/JRB4M^&DXw\e*lqJ6&lhYmEM\L!k=VI#RlqM+i5AueyWt%M^@
>mn^b@ :%iX+Rc=pCTI@*u$1ddSIp<M%F1E\THYbC\LS?QRlnbhJ8qhl$Kyuu5&NlZDpt%FAI<5GMuIZ\5F8DpY
8=:RCY uEdlKL+pyheqy>5YPDKH=69\!m$MBGYiXP6h%<SIuBy/mjp*@AdyZ1e^%DQXk6L1ZNItV$<+CCCHGn^e
iPiZtR cMDZA4WLPX=4:W9yuiSpN6%96>iMEQE>e$XIjKIYh*PlM>TeQVGZ8C<hCQCkS<?I%4%Id5WXl6ZBka!y
HMaj%N ^@DZ$SKN5T@+jyHw6labEA>Z>A!$jb^GjGuGR%4+64^yWTdE&1MbCjE#EXuIKEJTSthZ+d:tM5K:TX^I
SGY:hM bDJ<&/T=*CLIyyeQ4+6n$m9<Kt?W^Gy8wZNC+dNZN%L>1^\YdkD\MAZ5tXaiZb:yi$X/Vi>@HQH?%MF!
IE@?>j /pYI^c9K9e!#%:KCwMZPJy5I5*QRY=E55IX8?l4>A<8>kEXwV6n45?M8w%E!X4QcHB<yQl$4=8><B^:m
mm4C*S ^R>ZZQR?9dYbV5:Ticyh5KtcubX\8QA?R>ji==IFDC>diB1+$pqa/TXDQNH$Y<Yjib*+Nn6GKK$$hMb$
+*H*\H eVZl:NB?Fn$IBd*GY=Rymb&yqq1yN!pLB?Jdb*X*XbZJIM=Ym4ynR4l<yE*ZY/hWbMkbm#G@M?:VWQXb
c&eQ@# Ab>BlRXEEFV6!qjRnJwZpXlT8a>#XLHkXT>aIcR<d*mnwi\DWSlJhn!DiEFbnDLSu$Zqcj%XjwMQBhPR
%jIQhC hbBWH<NT1Q@#l#yjNmZK^!lD<MSqkMjy/Aq!@6*E#F8TK??8V?c<L@%et8G9J&Ftp^LXw!6mW?DV@1!q
Z\piG^ 8ECHJyQcF\F!4wd6eLVL1J<C>AkSMN*@e5b95uHi%@!ld/59NK4!DW#y1h^Dkl>ZkMiJ&DEuih6QY4ey
b^\t@K YFa4&8Pd@$#516BmEG^Xp9uP:+/cpDF&9?TA>&kYwCDSXjykq4t/MH&edVw6XF\AL8?MLVmbYK&DE+>t
nSmwVy G:%M1cD9$VlVNDM?@KR1WbhH+D:EaBT+=mj8+Y5=K>Bi=DIYcEkZFDJIjj\e%u<:t!XA#K#91W6yWd#j
DH9Z+k 9u$Mk$&!mbN%\Q+y8p:cVP?66k&y=5jdTY%T>bu5^>hG9BCeKRb@Q@ew$\D1h8Vw/iF&6GdIMqjiLE^5
*&1G&9 *amlaSGP/I%*h<kPDQu=abCyG1W$qH+^abE^#$P#blkWIem%N@J6jkhwKA6d#Gw^##&XwFHbP^wkLw&#
<<W%BR yGDNC*HFlT>C&^>SqphVCp#WHu$q#?Q<iBV^Vnb%4&VWdJF6H>*>IbaW>IqDML&Iea8j<WDR@GJI<9n%
5=Va?L F:GlkmccV<?EJGR!?X>:yI4ec%j$&A5n?KY/<NP4LSqh6TnT466G:II4dP#1&?$<#btd#mtFIANYYjtT
#5Kmw< Bk$!6hbZc5E9M81>eY+hy4diR$><IM+?=yi<w4*Dty:/<4tG!C5%tdGE6MSF*Q\ieV#9h:Q5+aLEPWXZ
T\VTSL EbwqME5Z=JE:p@p:jGb%!tbBS/h8qwhZm^mSdM>PK/yRdJ%4QZpM4V^6nSGcN:TMk%aS9bc>DjmNhkcK
Gm*MKJ T#MpJW+^LAWTl+P1qi6Z1Eab=nPnX*$p5n6WF9pS@nTb&NemJethGeHqDJXTbC=dy&\SYQPAn?Z4=Qkq
V*dB1E *<=Sa@$:P9Vy:lLP8>A:T&FZcat=t5?8Me@B9#$RH=@Bh<Ya4NSm*mcbb84VqT:d&SwZ?Je>@<mjE/ZT
tPDqI4 J%/?yAZ6qSX\XXIWZJ\*b$MV/:VXq6mkuw1b/G8bdp?TSk:ka>p&+leYjKFTmWenubdEJqk=El<F>1Ew
%*HLln T$+I<mH$XPkIqk>>Aw@+GpVYHqMVLbJ^u4Y^@utLlH8knS?NYtYXhwH+P&$/d6h&HZ!QGt^I#/Zj<Nm?
9<em4= M=6+eNF$W!Nma8Tl6JX#X4I8&$e9+SaZE^c61cKaGFbc=4kt$+FPXJ*N%<&!=1e<jCG&&j\Am4Wm#/8t
tK9QK: kM%GPeTui%=%ND5=kWKt:Hy>I*+jDue:p:RTcl&!VQQpLK@eWlaw#JHQNXCAnqJpyY<GjjPa5Ci$nFE+
p\6M51 HBjjhVV9mE8\k5XuY1nwAR/:Yeiyh+=9WD@Dm=:p#1i@#9%R8@m:#HdNZpy#!X!I$L86aN@*NY>E\y9&
nn^P!\ ?wlpBP8M#\XTWp8!a86F8iF\lY^^d<G?:D:$WVc^9cB@wC/yZ<qkF+?@GdPBij&G:dqXa#\FKT:d?EF#
\&B:Lu KGVkTYhRd?q/Qp#<<jj9A^$?EqWtK?YWFV<pMl&@+w5ClIJ8*@*I@@k%K>$l1%=BHnui9G%u@>V:*lY1
SHkGRp *dDkF*hwjT6Vd=YdSyyShI&i+cNidFe/1C&j:e6!!B4RcKqEbAu=M$:K+Z*>jS>9IAn>qIMhH!1nKDuH
wXhjSk &P!yPt*C%n9LhAW+\6tiA^ZIe^MdZ1VHkIatF\$dT+j:b/+?h^#^jnK/YBGRunT^jQ&S$<%=WeNc<6Q^
!dB<G< bIq*XV4DVSLwwI9bYd%*$k+hl#=>*YMdkXpn^ZWDqCeVyT:m&HWuJpHw=XG@?^4hanQ^!$@8T%nh6T&j
pjIqht nTdb+TeGd:5Z:LMDA^:QWwh#PTw<yw+Vu+WWt*+9QAC$*haC4a::!yiNk*&G:c&!Y&pJc/\4QB<VJ\!8
V%YEG4 J>Jyc1&/u59VS5#>=D9XNi$V9h&LVL#?5BVq#SblQVBTiE5E@9TD^:#iL\wn96$=e4:Jq*lCmh6W4!K+
DSYFqP d?1ZnX8bNP9NpN%uydQwI4I\d6CjJy#K@&8#>j?88jw@>W@@V*Kp>J<:H8F@9DL$>Rn@V*1y:L@uDew1
q8CG\e @N6Ce8l@i!&H?ji9M9<tje4J@j9:m9<tj<1n@<&ble6n=Q@D/yDWCw:<+?#?PIZ@FGew@Th1/Z@QpFGR
$RaRiZ @mhDSkH#h\&bj%h6@/5Y@M@C8d#M*$^BqJj:%/!5\y<dFQL!@=1XW9kL@X4l@*1T+S?Z=N?nDDF@uM*@
bc:1E\ mDJWpQpdWad!m9?uKEMFPdVe*$k!NFQka+cVJ&5T#Hw<=Dly$@<uTaaGulc>H6*PpmXGZycK@*8Twat*
*puVLX bi@iq!91JDMjK!X?=t#hck6j1#=Q8h8thXb?%pw%N5&&VVd?%4$AMJkMbC6tw/CAkJGDRSwApl$GBmeu
<C$G\a G\LT=SwJMXHdT%1%+y*R4HDweMLCTd\GGR&FbmI*M6hAkDED\qNl^@#%btWtyFInyN?iDAuDa\inJ*BW
8cnBci bFqn8ib%/<Eq/&dRZiLEZmTEM\Y9NZmR:kJQyp*dk>>kn6Lkl8yWK\nD/NkV/MH8QiaID+*hKK<BBuVY
-A&i%p 000345cbd6b00110333 Page 49 of binaries1.zip
/<\nZ! niLEjLBHCd$R#nA=mVJ=/dL@T!u8ktG=hWX5yWWCiMSVkh:MRTSn1KhXLBW:$Tu?/MVARaKM=?%AE4pd
qEj=?+ A%TT?n$AkAcH#MnC4y>a1SVBWHEqTiu8hGMJkCTWWEL1hmeGp#W\MCeDS@<IKAD#aqiT+Zm>>RS+BjJ=
NKYb$a RpJTCE+ki=eIEB?p:!@Qw*bQD*8AG5:F5Yc=q?ky$hTlnlE=P!euKyPjSLSX\WuQchSkXRi^HLVDF*Sa
uGCq?C 5Ah5X4q1pFVJk>yBw>Y#LTyywPREXwmKPeWCWmNnlRFMp\DtRZJTXkqVc!>V>JC+HqJ\\#B$&\q$&p%C
:#cVE& !FMhCPwbM*%8SKT$deYiWJ\cK6qDnn+NykVSHNaTb4i#w$kQETXXS<lkcIG5ZAqQR%d+<e<yjFEMDELe
l+XSh? jQy=k#FC5nea&<EG\*!6QceP<mIM$GV6QkwnSmFYGc+CH%aF5RS8=ATeWWb%>kwyYXGKQ$Nn1<YE=E+<
\TQ5?q pTCSKMVp1C9wa4?<84t6Iyc\h*+NXkml%IcTJj!mT<y$y&C$&JEZKqh!GWW/5Bat&l8A$%QR*&?RSlZ$
Qu<$@> 4QS:^T6=p\uZLZm#l/Y5RKt:k#aA!8%RtcRdG1!$6=&GR:J5tG1AV5dJKVF+?tIW+JeWYChQ#4++aXBN
HyNiDK IItd<%1hA@e#Q+=CTC5AC1JdDE1kL81Zk&uHiTdKMkYXReY$?I5McE=8LiDpk>iE:J^k&CP\PA9@/kWA
>LV@qk 5TN$\E&BJaa^=??/5wjhJQ^WEti=jep1IdeCtR8keNi%jQybM@jClRkE6L6G*db%+@*KM*q6<#MP<6\T
cn6Bcn 1Zdy?qlBLS*4Zw!L!#yhCaE<X#*Y<YMRB9yL%@9+DdaX=^n*CpyC$WIFy#>=XBA!*BEDYNe9*l1lPS:W
@/pPl8 QG<P<=MkE$mM/@J*%$R:e!KkC+Bu&Hi4kEpQyDN$c8m=ZhaEpdeRC6E+8?c+E&6<XpW?Ga/mL!pV#E!G
GG*aYV h41pyeDKBJ4qHJJFC!RMNLMtwuC\^ZL?XLcLqMp6i:IEC!yw6D5djIaF+lNXCjnn5#R&*SeG1BRG$:t\
AB=Xq$ lZK1RNEdXMq&ADA1m%*TLJTJ5WiJbT9LqLKmDy=5y<#YqI@t*t/TTw$ZBBP#YMqRiqA6lTT1K1S@h9Iq
hAeXyL hlMlGHpCB$P1qkpcTqeH+5cn5*M@e8e8WMK$%DANl\Bd=Nb#BN+DA&<VkV!dBAMV\EHWFZ$<^JX\MGGL
C@uA?! H*/w^V<%AGN^n?hKXQBkeP1FWdkVJckLuTmG/LcLIS/l<BMGXnB!^LDcDyX+<5jmB%aquualCTe+liHP
#Jbdny c!mmVBkq*hbi8k?Ek/Rud6Sdc+Z6pRQTyRNlmYC/AiS#8m$>kebRLHWcikqK1HGtC+uk$BS:I+KKwKR&
eDcF/+ d<WtaN@RXNa^hh>E:CSS!NIBY/:tT4Wmd+!ClIhREHELMCaFi^CM@aHQR4iDIPCGaI%e/i#/AT^STIJV
#PdX@Q ^8eiDdyEA\Tw$>KIN<8yAAMl/Ap\tbkTWaMHpkTIBjMITZK*+VnI:S5y<QF1qywq*?5W\ZDiN6n%9CnM
QN=Iiu SIkncD5mwKL$/AMA?eeN%hXGSG+?%I5iA1n1Vm$LShND/E\R!::4=GaKkmC:>^YD1WuZF*Dpd#$DlZc4
VS!nVA /XM9c&5pAK4b6#?:EIqDXGN$8#SEQEXPR5an5+WQdQeA48Nwd4eMQR5EM+iF9l5EtYauRM%huJc<IEPZ
K$8:h* R5EPY8+B\Li**LG!heK<pdBWLJimiCkbBV=Cqwc/ZAG\bRLkSZHZdYFXdQS+RT\C&\lk4uSNW\TZ%q^G
T1$bbn u1KH$KyC@eMc%DT6QmwXy=iM8D/SVnRu<hid5dI@cKwBtD96JNB>y1:ECmi#=&QGY^?\aW&KRFJa\edZ
%#II\Q Q+TImLkdDl\:Cieu4D^bnDSTa<4kpkQ!B+@kTSph!bqdXlCWZ>4Pe^8a#8iNWRmHB+BR!F4!YCJaC&!Y
?V6mJl @wM*c?1Qc=^\EE>JEECQR9tKCPZ!wIYBqHckQVAJbWqYacKtP\GmAK:c98b+hQMVqDBnj\Qn=VSd?kuu
YtMFNW P&6@Z<=4+?Y6V/tle@b#95uwSAXA/!FH=XppXRWHNha8lk+whkWKmLqN&j4Hu$TJ?9XBP4ZBCTRVmKnm
^Z9/yl AI8k&IyK=<im^apcQXLpY?RWYJ:n^yC4FIpuL/l&CntT65^phRacKGNuApFT+dZZ$VDwV4qQ6paPeDDh
BH$uba i/ZPA*aD5IAGSJ@Vkcy>cFAkLRC?A8^d+MRAmGDA459ClyKwK$lqk5Mq!bV8$XwRMR>N+q+ZVaT*Z%/i
IZX?B! piK+ZSYXVJMXBeqBCpT!8MquJ<BNetiZ>/WDJ8*F\pu:96Zy4lVDb+ab1Li>E*WRPEYA*\pDH^t=#Te6
A>*<Py VTI9&Q!FDmY/@MX>+AtMTKFIyyeKGqL^!V^Jq!JdPARM\DSjL$WD6iJVabXG>8tjkk!TihnJ94iNJR+i
Xp4m/k T!cH=LN8P<qAVmyyB\YKR:Ya?BEAKwEZip5eJV@!p/Z!W$jC?aHEX5%WAJ=K5=WSCMkM15lq+CJQ8Wuu
tp1X/h N8FNQDuuB1N$cMXZ4mEATHwNJC6dPVcQ1Cwte^ndTpdcmLkiep1q*h4++KLELSY@L#W<IWtjlNW:QpWA
dVQ4Cd 5Pj1/5p@?M@yG:eypYk6Z:lSXt5h4>dYEL8AqCM^6=<8aiIH%G$>%C/jl>hC+hhu<ICNYP:++$t:Em*N
HhY+&I B$T?E!XF*IEA<qEujewYttjWnA96EVk\%cbmm6$cB49ji5Y\$K&<5LBpSEKdA\pM!p&X:LVAE4JEik8F
9:XZ6$ BQJlH1AyhhK/k!C1t\cQ++RYC/AWm4B/AP$:aIDDCDEYmw1uS$q<G6Jn$=aDe5MECT=kQEP6t+jNCIbm
>dF=ZC =A=N%T^bRniE?!wN:Sp9Ck9np*QhmcD%6+GI=kPJQqREP/1eAK=BP#1VHqRCFYmH&RtMkaLLAWRl9Y$S
\P%kQK &8Be95GtS%5uHKAwKlKPY4IMlXiSImI8dah>=C8tH4lKY#H#bkhBL5nD4aHSR8q^cAi^EwlkjP!HTyhZ
^^XjyD %VJebnd<*DC*:RN8dLRYh\/R&BDLA\cTeFRDFAn8HACAm5y\CpX+##T$ATBF*M@NB@6R+RbTYR<PcVTh
=HQq^p #D%p1Zkm#Ik+=9wNCpIAhWIRawmC4GGKEb@KCK^WRiERJAA=hwS?m+?<\kG!6e@?Zw?FFE@J#e%MTmdj
M=d!!G c1hQyKAIZkDntZHd=&D<FDLSneyWAE^+R4Nn^8L=FpuRSt4LILX5WH+>REA4=aey+KlhEAGQ\NdSAEcw
S85pTm B6/DCSpRamyIk+JGI^pAyIMq#HEqNDMF!hl:1LG<>Vq^e&Q^#PGwnGJGR!HEW:i6ERSyA+^NLy>L=CC5
*B$9:& MqiawEkpMB+hSPlGdC<^E4A$*K*9mMh$byYWBC\kIS&MH*tpTWElMqM?\pB&9ap<yI^jP%EL^T9w=4FD
!tyJQk PKee1KRFpJwAkE5p*PXEMBeSS$qEZ1J1RPYKRjAALpImQVAVkN$BAE?iE$JwmEnYAS#HFyaLP$FbF\EA
6YADYw uty^&:KD8mpIuqTNB\IayBb@9!CYn^w+A1M@D<JVMQ516KAAXEReFWWuVWJ^eA$XGja=p1DE\y*PFTwG
jbiBuj AB4B8KE$kttm&%/W*M<S^K8JmhA&Iw=LY%%+aFJAp+JKa+wiqeP!bRekpSc&y*#^EqZDPCd8V61FF6Vk
ZHQ4LQ KV*ECWl$$>tiECTc\RbTEXkGb8+>JP$P=h+q6wReP1AD$:aNtAjK+CFDDbSlJd+uA&lVC&>\dipnmABY
!S1Ah+ LI/4@VEuwJJ4mIJ6D/MESpC8N\GP96EpRPt&:$T&mDAN$AAAel^8FICKYkRq1?wRM&8TE+1pBNTY95RV
5?mluY Vbc\^aJ>AK:GpG>@F\bBPWk=6N^#FIRT4l$w<*aIBeuLpQV41$aEy:pXBh/FjRlMw%HPQmlETS!n=Pe\
F&%Mt? GNBq=pMEw\J=*YC?JB#!H?q&SC+?Q<b1Qk4TRnDJDqcSDCC>+N&KRGm9wLb:1BM*cC4&!akA5tTb9eSw
l#&mJd ZXRRAFZC!H*ByAGZAMuR<&HK6Bqwn/akqJ8W\Dt!^A%&!BH6+AVnXlC#hAdDkBwAtAM%nAaAq5BljaCK
#W%w8i ViBkKl8iAan9BGueRYFhPBPYtL*/PdjdwSw8nMp!ALh+XwAB9Vpd@+A<YT/X/ybDJuELWGH^uSRdB:Bn
Bd*ai: 1n5Ac/kAmRK/Y$LpJDc/LX*DIVAVERh!A*MRFGm*pBC<winYFPWAFVY\tw%:E\!M%CPR/Acn6XDYRmA@
?5IewB AQcCM?R19$A$kmbhGZXWZ<HMm4?VP?nARGkH=*/q=K=nI:dTd5*LDLVCmK6ByGMW@w?NlT<I*:1XaADG
MK1nj+ PqGbLuBYHJNZDED^DLREdVLWXXwWFS$jltaupZdkK4^#ude&tuyFSqqDY+5dIn!k^yJuSaYXIeN&R@kL
?&%WBt kRqmDN5PnH5GaL!K8t+4C45J>1tq**yMBX#k^GMkA$CH:S!K4Z%kkkR+uElQwmQn@5HwkYEhTkRt%ME1
Q*:<bJ XkS\$elIGtX4LPWYE4!>kK9H5Y@l!LBa^8E9AJIR/<R^R/aNjaPP*^D+PVcApZSBn@inB#cBCjqBiBRV
@iGG<< IC9ce\BWMeTA4WMAe4m$MYSD!WhjPkZpH9496kM4&qYBGBBYDpI1:MJnElNIaPI=/*a:RB6DSZuETWkE
*b1p+J l>WC/Q6QWEbWGmB1AA<TH!CL#/WF<N&iV8je*mWnItk>1YA*ju$a/INXML49TIhXI&lSC=CE@h$@jkJK
NE8E^W ukG%!qISD!W1$RQ@&HW*GCwCKDY!L9FAAaS+VyKEIlHL6uZMN1khlpY!4e$AAQq5*K$TRDdTq6FFN?=w
l#!<iR aBNY5i9pyt9N:emp#RApDT5D>YkKVmt&iYMTJcm&eNSIQu+TFhQYXXlRADi&G$1Ml8Q9JWjnAQk9FQRC
64#>X4 *C5d$IWJ%i$j6HR1A8=uHEM=\IRY/GDa6=a^4pELP5B#%wwN4w4c\!&>TT\GmJ1mBXSC5K&eSB1/lHKY
tjcc:k lCpGFBbRZS>+M$64AEp?&EFq=\HGl\q#p&DdD+DaduLmHuLLyq>eM46cDqbSi$Pn\d:6q>ckESiJQ*4H
1+54\b SX*nRlm:A1y\wCJ%V6y6&Fb5\dBP\\qlqF6?kK%CnpEeuF4N=9&R%9aIE!Bbh5hN*ZSFGI8pujcBDD^i
HaiR>/ ?8N$8Mia8iZwWF=MSCneHMtNShJWWNF96!AH%=EXb:k6KAT:K%>yYbBa^wIZA\QQBpqY+EEj=KAKDClE
c#Xj:! bci$5*$#ecihkYmFmLVl:!YKAFjA^H*Pqwd+ATl5T%AibKi8dTLC@e:1VV5DmketqL1#BaITd>?J&ci!
>BQE4e @eYh8TB9I5a#<I5e<ISPp+wSK+bImLlEQCeTF+DaACk&41KQDc!BSbLtGAlE>1&^V>#IT+w!1L#?%Y>j
5TJS\p iAb#caqZ8jnwAKV!T^y!hITp*FK1WP\EF>CQld8MZcPTm+SnmKq?TWLTe/e!DQKB^Nl41tZASG$pcaRX
%RbmVA bSNPVIaNDAEBqi>Iunij1*F9JbKBMW*NEtVemTC<EdSCntIdBRQp$yF?W\>BYRGJB>6YqMRDJPq:k$M6
TRtVZu >$A=$@a?5K>Jm+CFEDbwE$JwNJa?XYKASLJdF#8<KB>tAAQ4>kGepHhQta1QGI^!9NRiJ>#?WL#>8%TH
X$d+9@ 5t^HuGLHR>YP:^1h!n1hej1hD+$:9=6*KX6*^hq*QZV8?p:wX9d5n9Q6jlna@V*$kZLpk:maB\?9QQmi
FHQ\Dp $KPe$lN*9ihlh5@*9F:qw6/+$6/H6*8@X@Ry%*Tn5B!wW&nFDPek&Y*HDHKNLDc9JTB&^>>>5SiLyY<w
NF^/6P A&MdPHqL8AatKB&VATmFj6L!6RwH6y5=WD^P/?FXXT\hnMVD=Rc>lKZuZXlHJiRySPk<PC&u\R?\p4Sy
-ABVb9 000867473c700110333 Page 50 of binaries1.zip
#6lNe= 8aWkqDBR:*5>dq*HF#/5lFV1/YmY1VI\ISFKhe/S9BH=@iybt\RK/<P<^Tqj<RYMN&<d5tQF%*J6!QSk
@&Q>ji 5VRGbWq8TI/BY\M:Yi\LV4CEjBm5EylA^:ukBCcWcY\y$AEdICkSKGtMMSFmnAjRa&jHEk&AyF14mnN:
/%e5V1 %A+heR+IkqLnX^t&+npHN/lJp6NDmRCTHXu9HcGEEdj6BTT\W\Y\^b1TD!PX=bA<RIpd%AqK4IA#&w4:
I@1/lj e=wc9wWeaI$9\GHnSSRAA5!kc$6k>bCDJbTJE1uaBmpa<I?lA*N5JSTCu!Pat6iBCV@aWRlGAljeXk\A
6<9B%d PGLq>kITV&tB%V<1cjaGmF\DEnR9$$Hd^#Re:<*\>nSdh6ZEHEdjG*R%EjSdE+?&E%t*GbkHy<%I$yqD
ScN!uP LeAEBSAqCkGRRbItSubTkRqL+P$n=Qa??\D8WlKPHuCX5#!bG@mD5uPXbc8hL91MA4>E1*HPCMSD5AEZ
eDw8XY TY#WGnt+%uQkIAYI8ADVMCMH%4<EMRM1BCD?DemBChnTEVClp\&jVD:+w=RR@\5Xy\h1kt:9=SDcIeAA
MBnP4R Kw%eV6L$=9+?!:ad@SlKWMP8P<GBFcXN5\hDGSy\6W+\yjwAkBMWY:@AkH+TC5CwMRb!j</lRRja4l&5
W4XBG$ \LLnN<m=!!lI#JiAlXTpEMnAFK9TLL&GHai9FSX1Bw4midAX!&Zj\t&%\dc@D!&l$<65RFZMpG@L5h!^
QQn@jG EmEmteV58IC:ICKAAdDANykD&#dkSCG=WJQyyLa:P@/TA&=pJKyL*MukyAk+qk/CD&LZVcWmBnA:S/dR
j8QCcF PdFnAXCTnRGS:N*YVlF&AwKNRk=i!<nyAZVAhSPlaGA/p>eT>SaZW$I^bkAJB9a\+lERS#=8dDWRK*AV
Iy:DTk qXd/\+&hi=ZlNkj@Fya1aXwaEMFKuCBDFTqWW6HP?:GlV6n^LANh9^He1&DmHRbANDBBSkNaA5b?aTii
LnuNH8 kHeAEL!eRS4\<NAKk?AH$G1$/hqhlFPC*cR/i6umwADi9QY#iIAYC>q8^R1&B$h=4bKtuiLIS<Va&dCc
D*T*nq Wq4aRAWYudyQBBLRC/!am6u\=:Jeijw%APn&?nu^JSNiwE\kATt$D4pyWATTi$b*^888+%dX:T!^/F5N
tb>wm+ hNYkb!&T<pdXZeKD/p5m@MG6#wcpd$<jV?Ze$c%jNdK/m5DqByw9G9J%A\&*J^8atQ^!IH+\+9LmAu4%
q?qALI C9n8:1mt:&pPTwQLWZB=Xb:RXmaMHWmABTu$$Si#%CVR=?Lc8e\V:u6lAWSQ4ES^wM+#Y5@FL8bZEt*5
/LAVnX QwALnCIaGlWlJ+JRF/Id#KIDIEXX8GA6HmGjR69WYS$$/61!VZ&kk5=pi8hIybIpSaeM\Ih$yFPYqwET
>@?J<i FHA@R\&XBQLJQhS5NQ@CC1tma$b#:D/4ye<nAc4=$&5jwpHJkP$whedSR\ZbY&RGe1BmDcTHTIFbb%S%
>tW*M9 PSpFLwkI\5>^E\WwikB5&/^jnBEDMYC1NI46JXlq^WE\FdH&TETFq4nHXRNIw89L!cuK</Du1iDG^\6Q
/K%&Sc HBAb&Iha1RB\FHHIIhe:>!mMJZ&L#cYAt=Yj!/^B/n&G51=8Tt&1\mIpB!C\#TCXQa1NddhEVVyBPjR@
AiC@k1 /nuRX9a<$LK1P^!!cX^eKAHjIADcGe5VTBim9PQ$K\B1D!RPqpW+=#npTJt!CM/h#bW#W^>Z\hKu*eQ9
X^Gje: bjMPCJQ?8QuH@:BPTNI*+KAa4VMAyNSkAj+\R&==T&il\/DR4F&5lRjLjl$WRMHuc?C&#M&KqT:SH1RR
hmJTTS kIKJeJ/CD!iJhwYA/b?S8pT$B/\AnkKKILiAa9VyYPAQJ\DI1Nci%a%HBAGwLwq@lllKPhWuLwNYnKEn
=HeId= ?qiFp6$yuwebkbBi=kue!EIAkt@ITVb%DADkTHbZeGChZR<$ABWQ&Nu+Zq>Jn+@t1WLN<dNXLR1ByCtB
9bhM<I J9VqY\AH?n5Rl@q:R!Ra%qiJam8XA*bQd$t1/PAp\AJAZnKqm\C!?l\\4dG#1iiNuPPE:mmFFjI^Xm=5
RRPE!S 5JVNDB#wlGkQ5N&p$1wW\iet=8XGWB\C61!VQZB!4PDWF6j8Qm^ln4KHbX$ml%G9Hm@BWeTn=FKtK$<B
RYKC#A wQV&W^AEi=wBIAu<V//6>/EPl4l&jA+uCEXNS&1mykQ+jCc\?<MeANuAbG6%yq9CBT&<Jnek+*c/&\I#
R>%B61 heY9Jah!\4Q%*&!JJ:^5Hy$*1iq\+QEFFC<^kwt!p$5Wm8SFA5CKqA5#><pNF*Z^cG5PkDdNeEE=d?IJ
Hph?8h @jZYd9/lhXkC%b=aI4yMQZ*LluyWAbTY5kCEED$=Vabk#MRMmq9$HNREI/wpm16J=A1DaH!/LQ$CCJ:I
t9/4X5 :a<<E1NQ?4lAi*9Rq$wVhmq4+I88JqKWHA<ky#i@ME\m\5ADkRj$A=85+FkaCJ@FC/bH%GweHFITHy%y
QnGc#Y hdnSccc#$maM=FJkeVIk4AeZMVq\hPGZEFtJH698HwAGZ?aP\I8A1pPWpp<1AXZddXSE916WA$94YMAE
!LiWTk T>XYCPbEkVch^A>&y:5B+/c^kJ/\W9H$l>HtnhIdtE&D!D^C<wFmLER<C$>F@$&\?T1jjVTRiq95Bt^k
a><#Rq kqhnm=X^b+H8lkcJZTQZH1\^bX1!8E<^=6@KlV&VJRQk1Mjy:LM1R?m#Wd<wu6bN51NSWCn*HX$eqm/4
wW%*Pj I&855!n/CXuJT^a<^/YMNn=X<yQHDH@eNaM$91kY5uJ^85N:GSjC8CD/T$!D<TIM&:<8cRAY\ARjZ9N&
M5Kj>a JSt!A&PK+YQl8@R!6KbK%%lRQ=BpC+@RE%5^VEAXki6KaAihXq:\:9yN!na5RBQQt#K+h+hmAIeA4d>m
mI8#99 G\Dky<$AAC%iLRAAEb>MtDW*NJ6k*1EVBhLSFYtlGL!uD#ITmQqp+AXQSHX$HDE@\^R4=MZaiqCVn9ik
NyhuW4 uk!yyc*mA$DRPPpE=A#WDiBL?ia1uC#/pt$Tpu@cnEy6?TMZGJV5qnKkndABAPCcA/#\\n#:DDMPc=RH
Jja<VG ITYZm:iRtENiMSSF8:WpAQb^=NDR%kaM>9ECALK!Z<Vw&\k<N:a=Y?RwbC^ye#qpEqAb>P+WkbtA>^Sa
MGkEyb ?l+1ne@b>A6LFMjjbAApdZe:upI%M1$>*6&neTJXHeA\4LRZ#YhPMYkF\q:uyB\R+$@B&8pCi#A5bFlK
@!l4l\ CD%JX<QneS@+VCaVtY5QYqACkM^kPZtQ4Mn1htF=K5CTIT#h?Dw9A\uRqwYt!Yt>*k=M:FGdJIDX#KLl
tmp@=j RA*jNnA/wIIK*RIt4wlR=K$mS\i&W@mFNN4e5BVp=^/kAaA8CA&Ap@uebp$IMe&WtkC>KqYDp\%TARDS
BB1!pu +8a>9Ek<qmPD:lyT!/!Pa1&DyYABBEnV1+eqFIa=JQ\CEmpW1kt\ID$ib/ulY%u=YIXLBT4:ES1pWRc6
ZkZ:ba GdJE4J=K@6A%wBb@G&CA%>+AnYWZ?ZkFRu!hd/Ck!cbNlFKc+aAVY>bV!jGMPS<ZKMc9RkDAa>kDEpC<
^?*!>t 1!+Nt8SEEM/%$AWD?NTXbLyw8QEW+/H5$QPiKnBckZjIZSXMTJ<ndk&B9N>Q!YHF&ttBJe!yiqHLwKjp
Ep>!G6 tcnFbIwVKG*ZSEaT55X<*M/NLHqQn8^pqGHwta$kCl^M6qlLA\4/BkD?WEmt#?ZZ!PZqe6kC=RDVEYCF
P/4JRD GwR:lZtm!ukQqSqIdim?aT4cmqIZj+#AG%$tJmVKcYEQpN\:QWPD<nYn8ecWXjh95NQu$85m1cYIaE$I
?i^bba jdW\$ej%$q/<V5w=%y!ISB1RQC/qJVe+nt@&CJJCJKuNw#BAkB>6R1+KeEhBNkjIhRt%Vy+>kJWkR%W&
k1F+Gd X8HnkP%tIBB^t##*^#X/#RtY\nSqaWA%jRLNL&:N%k@W8$NLV!KCXMmJ4p!pHw8*btXWw!Gd#INPZkp9
lEM?S5 Z&:BjKCeY&cKWQM\*jF%V\wIH!l:aIAB8DDBQAVY+Ve@Ty^CH\J%uGk:6kLaKR:meZ9S8nD#jGceuSBR
8MDHk4 <SmRJhMkM^#>SYVN&b%?aE\FaqbQZ^ueE:PLkYtZYAC4jGLV*%\q%$HLWNH?wE@+YA+jqYKHJt#Fy9na
<m4ih! &A9SdtkPYcb>BKqJAJF/&Zp/RCTaP/TKHPBPVJelT:j9%kPARy8c#CMV#%WkAQXW5+CCEAMwmlw6bA%E
dXH<Ph eiThS$QSqttw\Q95Q/n$/KBIPFuXb!DT:qc8MHACSy!I9pTpV:E#WScT#FSkJm?=pyIiVaRl/NjD$$Lw
Rdd\Nb c!&*kY!teCKI5@XBWy\qqSpWdJiSdHcDnMkCyZ!e9G=cbbeDF1JN#aXC:iLJlA4VTTyD1GwmZwmCBE+>
S*<Aa@ =\K9\=J#+=Q%LmekualIbmCiPm$ES6TnIE?QA9?R9YplqR!+$X+P?PMZT*:cC!XV#eR/e:dK*jn&Ku8B
&dibkm my#!FAm\kiw^5JB!RQ4QE<+b!?P%KA?+AA<%@>mh1FHkyKqLSL^LX%%G!dEXp=BeAnKa+q\AiNlIbReF
WK+\DP =jKqwyZWu%&BW4DY+?<R<XGFA@Vh&D5JAAiG8kkApXF4!J\8Yn\NYD+/eJl<REnDw!qJTtppSJ4@*Nn=
&cpRYJ i6wBjjJB#H&meW1A=jWR<aR6XjA/L\i>EhGMqq\@m^1qBN*=A8^B>JcEny8B$p:CGjW!mCY18qcStWcT
5AN^>$ E*u4KTjMCTG\^At:JD\Z5E+l@h\#MViWjAIH&6IpC!EMK<eApcLyY^:AV\$JTBZkPw+SACX9lVRN6APt
ZGN&l1 qnMWwAAj9yS#%au1nCpbLeCBhCcKAcDuqwV&TDDDJ>C^Ak<\p+ZFmIq<mm%RekB:Jwwi%CQ!^>GCYmMW
$5?ty8 T#KIE<\VYXZVH6%ERP#WTM@WAIaMc$y^HpBYLnmhY=ne1Gka<YTmnk?$<tkGFbB<aMJJlEL$NKbXm1E#
W>9++D h+*AE#MA#=S%Q+mR&QVKw<S#ZuI:G$*pVPyYbE1V><$Fi4AD@$#l!1!iB^p^LCH/TtJhPFCIKYHAC$mB
>TKY+y lWSdk+qw5QVZLB>wml+&%e\5NXw14Sy9dLW*b*btiQb/L8LNZQLBZPHlZQZSZPjd8bHn8bX*e*99=<+?
QQ=6#i #INQ=lEj=@qP=&W?#Y8j#X6>u9j+Ml@^hV:=jL:\&*#%^Z#u>@tSH@M4Q?j*j5&j@X/AABcakA9<wAXb
K\<nw< 5kWh<II%bMEV8lBJ9yBCRb1At6XRLXV9t*ZBFy=TL:!pYYmGtZ&GL$LwF44wF@qyF%Zl=4KISYeG<$AY
SJJ+h? e&Mt<&!G^h65=uZbm+>w#A/I^D>>hpu^d\^SW=D=4$QWFND@?mtY9&\hXbD/L&&a<9?/DXQ?@&nDqEQ@
\m&4>H TS8tA8cj&#CqyKSpyj@@KY4@1/iw5j+@PWXNkXZ4JJ!h6tFlADGj<a:hdqGSjm>ZDwLSMleaTT4bqF9a
V:DXc8 #9ZYV8FPMpGpDt1HKpHI/m^FP\tN\b4hEtXZ?L8+t@SYLKyG1XcXEM*tjM6Q/Z\R<91j9cRk+q&8tuwj
benyAE IiD%y:6h691LmJ>^uLLeNh/81<ZG*w!KbHH*tP%NZ6dVKd%H9YL6p9J@cGADL=LW%+&EmA58YjpECqtF
A8e%1M 5X5#\B@w1QNbY+LKdwwit+Y4yBj$lc6K:!aXI981$FPK*XuYd@VlH/Z6$G5bVS%yj@!#6&NdHmbPJ*T9
55YTiT &Amuc*W:W?8:DYblMV6FVQG:1#HY?5^mCp+GmK+p>K5eCE8/\\8aamRpXeH?DwEpW<dEccwZtCPM1\Fm
!IEcDG X*jZVHdLZpCK^QtpcL4L+q>+5::XZyYFb?EdPy>@>!TIF6+?@5j56QhI>ZQILh:PFXXS<cW1PLWyD5uj
lu\SDn 6KwWyMQG9848<w=@6cJbbC8qV/84LVW!ZLh@jp*qlpE&Y+9EKm&GQe@aIR@%wW=8%+8HZY=^^PPh6/M^
-AclVP 000711bd4d300110333 Page 51 of binaries1.zip
*E:dD% G>8T++LDc1TF!e>=tht19JGq6uFJN+5YK/h*eBXQqR*L8J>=jhH5ba&d*%SHDH%:PR95NdT4>F/KyGw<
9Pn&e! ediauL\m:SSckZ*Gyj>Adc*:*h594+j%5/&>F%MXGRN>Q<H%A6c@Y15t6/$@V:EJTCnlkb+NbT<XJRl<
p%M$Hb %1#WnR?q*%WJEdthKeY9Fqk1$8FJujBDI#IZb5=HL@PiZ^<!VM#hyK1^HK9RF/uPQe:PdLdR%hAZ\qXY
?Mj5/= q!>cY/FqJe1nBnwKb/mJpm5I!Ile&mWEu%iRiiW\j*y#h4/ASh*m=?+>XI1>%C*y?ujl*aYyVa8JVjwu
e9aKD/ Wpa+Sw?/t+aZadnT/P/dHqP#:9Rtl6e%H+ELC%h!I*WCL&SA/YF\C<yK1:h<!<I%Zl\:dEZyE\F4@V6#
w+I5>I M>9WMtEVijj14a!K:XiTHFLL=CilI9Y8$+&RlntnpSPjq==CBN&<Wa9Y5#5B#te$PdXjXFYKcy6&L#Se
&JFeTw hK<<aW69iDH^Qa!t>qCLW/5>5NyJV=>1lZYaKc!LqM#p<atX1cIV!%+Xt^@b4MQMXp?1461+/@C&@Kk<
ij@%R> *P&\WLE:4mAW*m5RNieX@<#!bBXq!lh!=M#>&GQK$/VVW&VLHJ\JjS5X@NmL^>Y+@!p$S=G*5?wG+@:b
1QA5:w X:95pN%?^T<ZVK!D!hT5=w9C4:FC=VwRCTMEcE?y^yn/wyLK?6PM*tZJud:wVD$Q?b+J4D>b&a!nhGI+
nuphjY =+P?h6:yTS^he+mS#yhkJ$KGHZWmYX@B+>9$SZLpNEA5G@+XD>^A##=>eW$CRwwwhu6h$my!TZn4PhI%
^N<*F= HT%dFG4RNJ\a&BldpCKC=&^iP!>+^nB?L&D&1FH+@N+qpj6%W#ELe5WMVT6L>5wb>Bw6jp9D\#XZY$*N
JY@yT/ PPa@ZVGCQR!yDR$>p4QtbZ!bNPW9/CPnEQLT&@llF%!8+9#SAVJM^DC=c:@Md\Wu5TmiPBqC^V\9Fai6
pDFw5Q 9nQCqC&b5j^mTyFtlV16JLXM9Y^k+/^5PTQyZhFdqRh*Vt>LZ%#>!ud9\Zn?>58+X%FB#/Me&B5PYAM*
D<4jFZ 4P:LMpwab8Q+p!c4b=91iWbEt4Pi@/\XuJw6Qeq/p$jtL9!Y*qTpEbF@&=@%dpYdX9*B4&wGdKSl6DA#
&hjaKW &?Su=!%Iu*+$$GmLu=>5I$\9I8k*DWiX*jKTGnl1!yc<ptW?ZeyGQNkG8X5JYN&^?uS:4PMn5<CBYtGF
uP1knR bZnq>l&@jGTe#C5J44CB5W1e=R*%NXtp#DnE!JN@ZnVjM1E?8QndHb**ibPHX%\##+5jwNwLn@tc+^ew
>6RW4T NqN@tFXqb!R?EnXd4/<dBb1je8cKq8KT=JR14G+nCB44K?c/tqG45j8J:WC9Ite!^tebqbbVkQWHVj8t
Y?tMlp &Sp<hq?p<4S%JQQlF1mq%EtHY=C<1nc&D8juJRj5*k8l:JT%5FltZR?\lwXV^midAQ8/Y=+XNGhSaWqH
<EHV:< ?VQeFlZZjA!#LFym&w!?QhB\1R&>c?u$jJM*@Z$iSCKlWC/MQXdh%N6wS*AmmZ:^wc&y*^Z1GF?iyRa4
4KC>?I DdL>%+mHecE:T:1=<#T1:%@eTm*ki&=PY@FiPQLmXb#<B4hETj@4F\XyCR>>bS<#KQPFTuQDp%R@bh:S
EHi4DS %P&9I\4y9S#86Jyq&GTeW?eT/*@B$*aVj+9:pjBd=MeZL+1D:mt5J<Q8XnpX$qn1$4*t:lIp!!<4k6@V
VE&Xc! HBX?VY1c<=%+>jCS+FPjMZbjVE=/ZRCdhbEKE@?t5uuH8?SQSiILDwn9QZdp6b<?hh<4/jLRP=C54>8!
e56V14 8JenT&Gd?@Qy:Q94#^dZXA68Q<u@<mB8?n9GE5L^*D:<NSB/=<bqtm5/\yhJbpY^X9jjQdJ%1\nMyTeV
lyHwB9 bhN?Th4>SCu?mt5u6P9m&$>ScS$6iDh9*@im9nwD8%<*cL4q=wlQ&jF4?%>i%ShTyBFnZ/8hIYT8HXLT
NQtH^C Qu6b9&%#p&^n^ju$+L%YF@B\S?!Xnw&#<yYZ?d>e/:/K!4p<cd#<8iV^5=KJn\c*a#qjB!!H^hy&jZJ+
EwjqKq 5SEGb^1P//6:B*$:*Hj<iihBkA6m55G84>G5%#R1SKL<>+$V\*6RG*#m/Q8kZ&>&Zum4!XWbjZqV@Suu
hk+qlM D1CNm9DXXwSijBt?Pq$>JPF&lAY6Q!b=RWqPWDi#Gj<9M*ZhV!d9ZCG#W@1R5c8Xd$+Kp^q\\+qj^FWF
A$5S+b WAl>ThTKq^8LpB9jJShC6yBb%L*^kJ4q48L*tuSbwDym*9Z^i:6#QMP41K4u?MVwWE$mhCBA$wPhe5lK
l&5CW= y>JJy>LKZuNJ\M&Qt&+Y\meu4e$L^#4De@5lC\QJIC5yFJ/jNKc^=WKJikHGy<N*/MTHGFVB1<bTdHGX
a4h554 XtEw4Et8Gb<Y5<5iD!bJpuI&>^:9dclj9?L+a!59J$66FYYS+5AkZkncSuK4:wqthbBY^D++^*ItZXjR
6@V5#N \+aQN%^DM$u$ibju=cZd+&5iF8MSwM9n6ne!DIFTTQP6<L6nk1V\/&P:pMQ#*CM4h:>8dY<C<pP%VX/u
@<iBye 5q:h*p:=?5+WS85bDRluNVVGQ&S%#i$c$@/tNP+%FR*A!tmZBV>nyu>!1!Fi%/#FCN&8TedDP>RpXF<t
5cCl=1 RQde@PR^j/8JaPIeTy9LjP<b><pEC49PDiETG<CG<ZS46GPASn@W*w4!X8>JDStBGVVF5*:C*A%=TRF<
u\XLLh @1I<FnLRuVMld%+IyImZ\S@t6lDGe^cGmiHDBpQw?eI\X@k^6kL6&h\LI*#=qn^8hu#=BCGMlpAqVnSj
nhc4MC CZ1KMtuZuB?KEe*9Fn$JF\1#p*ZV=&pQEK^?K/L#TjB$XZVJt6hmWYnHTLC>TCIJ^H51^=j@CL/pHRu/
IW<u%^ KyuaJdupm?bSqFl/JSTYRHM1\1jFIZn/BGclnAH%mm$hCCacamwXBjEcQGH8NJcK/HCptDR=L!tML*Be
+B\u^J Il\p%D+C>YCl%YKT#XiqPd$t^&M9#ikk6G^P&?E6\#AyYYAl&ME9pVk4h#I8IM*Kh:IwS&e8%tHQu!4F
ID6J5l D!J1uV=Du=lIcwcJJV/S5Hk5Fu=h1ZXe6KCa*@BeLHhMt9Gt6PYwRpEp?NPMeeHC?uKdC8mKc5ipHNFj
yd8$9n VdyB:XP988bna>CEyPWnNJ&%?6ACQ<P\@Kp5!/e/6RJX$T%j@mE%j4IQ5lH<4IWm?AJQ%TNthGYCXlKn
BWECdW MpJR^pyehhqZ/%P*bIi?Dw<%8a!tThk9<Rl&dwTI+QKl>Btd/C/DECJWHjQa@BP9:9B:WW6YQe9ZqCPm
hTLA:m C8*c<<8ei5tmpnK??yYj+hhN%LaIIllbjWR<d>J49bM^5S&mR9l>8X^VPc5^peJT@5JJHBpBkummc*XL
XniYaC &wwlVCbeV@1Gpj5HSW6jjc6aPRTqkaY>/a1w@6J4Hk>X8bZQGGqpZBYHEKYy!ctM4FYcaMSN%V%=pbRm
^mqm8a CPm8MwSD4caI=5%p*4F84$W9F@ba!tLbkpqH=K^YyyNM#e4RKtJQy55AYtR1qc/lI5I5YNll1@pbV5X5
45Gk+p @NpeP/RKT$^RCqjqedPWPYI^p9HTY9wKp*=wwK$KC#QWDHi&/*ISwj5A+>G%@i\ZlNDRDDHV/WBKM<bw
^6eJ6^ S4bbn/mIYM?IMY=K$\%DGMPhIl@AbF<Ilh^YqH+6#1R5t*6d<W!ED@$B=@cMe8m&t9bLm:QZqENQGK^D
p$b*pS iSDXPq$tR8RW/p#u=E^JGuLTtC>kewa4:5#C:qG/dt:b<61PH1i>e58$dp5j*Sp/4BjiGT^qwL9qBI9c
edP<yq wTh4^mHd+qGBZqG8Zti@*d@+i8&p&VKu+G&8c*aH+#Fc=C8ZjL@Ri*<?=8<8e4jlmu8c=+qI<D::=C?u
8mwIXK +TjZK&a#/uNm:6Pq/EhC^FXtipi\?ERN?##>J5/e!jqFJG=XZ+jlbtD%49$1*DTb//4%tpT*n*PE5jAy
KHu4EJ L>/Y*qD&5?ec1@#V6!/YXVVpZ+&bhq&?pwh&MwdcmAl@j1LyFtNcZCY#AyFb4km8dPA6*Am%bmY<Nna*
=J&AY< aFG&:lHyq1kI6>c@GYnFPKl1A%E5!6ew?laq&/F?YVnTqql^PTYKIhmjJR=*?dKh=n#Q%/61Z&bnw=+a
JEN$^q iQFdMEhwQCCQZBm\N=8QbZHt@\\$/1/KZPPM*#8M9l!59@dm<6hdSyFj\:1jR^?<55P<wGF=c9Lke*TE
uhVy^n 5FHE>tZdn%cIiSQ=QM&#A5Plc*FjVQY6F!?jZ^JbB>Lc6Jp9yeS&^TR^PSQ+nZZZlcPaHJQyLL%K1P&5
?^#6j/ 4bQpq&NZk6$WqK<XKK5bqTb*8!ch&Kdi9GwT*tn\IDKC\V$6uNQV%qnN56u51#l9RY?/QK96euDMbeM\
9lYwi@ T+KV*LPRjAQ#5:b4WV<#tBYn9+wLYuJl91wLT+9m%yQXVkdtl*V%Xm?lNeP#piJBqa1/:ZpmVN@<T^1#
BI\i\J m*wJew=yy!qyLPTE>t<!R/w=qXdGnN9<!LhPy>im%!#S#DZ\Rq4<q#V86Z5BWhhM\$VEmm$>FAb=i&WF
bZB#G5 Ll@4hA9#h5/u4:/RiH6i&nWjC\nXPj%t@9TDH!yW8F%Jy@6d*9wDRTbyhZq!D$5ht&jBlV5KjBnq%Gl/
6De5%d G6A*ddK$RIXQyWmTSGh+TEm+AWcy&Wwbd?tia%>^ie*/F8dd4ik&!9ZT5y:h1J19T5t1*F*u=QK?bS&:
4tN!^a uqwWj^S<VLeLPi<H@t>9JFqZVh\Y<XGlepXQ^i^@?mHkJB=%W5\RPuj^:nN!EtMTA#+<m&tbkeiSaQj1
tX$EBn /6Q:Ku!Pibc6clb%Pn*LD8nj<pYL%!&iGQJ?bAn:pNjXy*dcXh%S\SP4T:L+wItS4WFi<#MZq!6>eJeW
d>:MyB jPjdLV:4Y/R9MZi6@V!Gn?I/bB$E*>d\9!4lViZ#iFd@4bjZ#48!G^/H5Y@+KNkw\%4uWNQae>@Ye9q8
1epNp% >&>TYay:*$QNImuidK&/y/XyYqbCZd:YmtMm*jjNY?j9QuAPnd1R/j9KEQ9h$ELHWy:#Q4K*>RFjt5Y!
pH*mnY icW8!ZK\ySN8Q4IkPKRadm*w8mmw<i!GjtY%#jMKw#Ici>9/?>>%P5I<+%aihH#Z%$J$8!4L*:cc=YGZ
a/PeS9 9^@?mpGHW+P^DiKk49@M*VCTnMH*Xl=mX1@*?+PC*=$95u5ecnIyd@YIdjeWJyZEyWlFYAk>9GG:?k!m
DQm>Mi 1Z6Qq6M?k6&:VhDmbkjEY4E@lqw@%#w=1B/>a8pS>/Lh&6WtXqRZ?bRuR9*^\&Yyt@iM6PWX9u>LXS+V
P%k6:M 9Rm$@yyhEcFa$T+kJc$6bVci9/R#<P%:/8Xh=c@lDG/>@k/@%b:jG=dVGI\DThudK4y>d8?6/MZIS1pI
?LN:la ym!@C65JM!qYXtcl4:uR6YH$^Y@+mH=ZC8NnbIl<%NDqY6iJq?#+&j5<k*ju?:XQ94+:=PZu9KKu>@l*
GuYcjw 9l9JRkR:hKa8e+5+#5$+bE?^yw1D9y5W5KK4%!Y:l1jcha4D/!V:KSQcbVEMByKN$nMSGTk*R^1u<d9q
<WZ!!e :>w@d#SELNS?b?R9@\uuBHb\LM@XchR^5ybFZ$%GWDyI8\t1An9c:i<5Xe!>bDLSuH#IKVZQcL<eLd:e
Ww$G&Q H<mu1nHDG5@*mKYA+=&\hPRK*hi=H\EcP=QF6/t6Z*y4e@wLZRp!=tT5@KpH=Zm\!6T:<5k&=?c:%b@<
1/tNq= <!@lc@HVe>>j1%$^9u5:59w!==\6h*CqPY@mh<:#Xu:Gl=Q>w<69*p:&jh1\aJ@54%?#9nFDLj4<E%DD
i<8q*V YY8clYZXiZ#/%qYkZZBJ+9iTCC>?DktVp5u%H/1Xn?ydE<&^=XeC4##N&1S<+D\/%%BSeEXj/%bwDW9H
eS%T*6 %yuGn1LGC!:l:X:=#V9eP!@VhM4y=X<?HiqZ*68EdJhLqZjRFH=Z%!uWZh+:4NJ5uK/p%#+b$IyX*L=R
-AhN^t 000400460fb00110333 Page 52 of binaries1.zip
Z4S:FG *@>^>?Zu!&?8Jt!NHQbjnh8J@>ajHdMh#@:\!=XZVJj951j%e>We^qWNXJ1@Se^ZQBa$bL?l=ZL:/M:w
p#ak#e /=k/u&?@N$8ui%!t*%/w<TNDh<KcP?L66^^q@K<89=G>*Qw=>P+9\T^H?w/iaQlh5mQXu%Y&Gnc*D!*L
MBh1M> bl>!j6?I9d9#?ecdKQn>#ST:QEF*ch9N&*P@44\<5tGy$a\bAp&&PNnY!bAdM^MKl!d=!pR#a?&j5*F9
Ei<\/c P/89I\&@ZN%>?Zp!u?uyW$:b1tW=Qc/jd&Rj1i&yd6??6*#*^9L#*$94*?1:Sqi6u+a?4@1YL*8:<K+N
eVaITK P/MeA/i%m@i*6qjFqb>NMILq*!#NZ#&=?K*L@TKt9+>Z@916!>K9%8*%=\9cu6pLG#8NG!t1Hud+pIMA
Vu%!QB Mm\$8CFk!WIkGV6MG#4kI#SLm/VkCbZP8<PFacYBDG8MIQ$=&LM1W6euJwIp5mj+icPh=E\Wm@Tkqh9q
\NHNuD n#twYGFn>M@AjN=<Jh1<9L+HP&4THMa?T\=CE$:w/l^8Z96SlC?WA=51G:Q\9MKThT1XduIGF<ti5?VB
@:QEyI e<myFKq!F*c$:Ija<<T#&DWX?+q#*VN1Z*lHJyW?by%\!*B9wEutT=ID!Zu:$<V41C/u?/aCY9SFjtPa
dQ1/d5 \Yiuui\9?RLhd#yBa%?<>AwtLB/GpkX1u\ZIQHF95XCREZM&H9IMPT>dYR%8Ru1Hu#ZV#Miw9k1LXwWH
GDM!l% yyp**Ci+&@1k^#\u/h^>=JB!GX>ZV:Dj&k&nkqhq%tPFqQ8Flt9855IF6B\aJ*:\G$^@!SE^Z9jk1BH8
>Njj\j \j/5%WmK1BmpNHkAlhaj1Z#H6L#qGXaSe$<9XVNXSp$Jtlt/Wk%6D$jhWWi:u:PwL$^#5Nh>bD6i^dX<
&*HKBI P9w/t6B8TT<pw6^</XHPD%ZYXMIWcRc1$iD*6D?k1Zl4kNAA91n#5@C+1huIQqI?HTSVupBPp$VNKT^b
ARhR^! >Y61w6$yb*R$aemncPcGpd&Iju6<:Hc#<FF%pwl=q41/YhCQZ\h<%\$D6T4MFN\Ki%8e*BtccWHcQ*H$
d%#6q$ lhWRm^PEK&nWn*%kD>Z1X$WlKM6uL1lnZmc4Zm@D$NSn4u>L$WA?$puaynq!Ih^I=<M:WVm*!HRp1DYa
<:*5AS ^^^lV+i\>=IiBQn$y$!>I>Z!j1u$==?WjFp:4J46Wb/#@k:6<%dhQ%!NDZZGTYy:5kacc>/ppZ&ikF$?
SF$:u< Twy?tS*=%pSImQFK9QQym9\%ASQE$FeHY#?Fcu&byFi?L^<\k=C%QTE?laMj*j41Z8mhXu:GSDeZ*KlK
8^diCI F^DF4Bn#eta>Z@NT6JLNPq*L1LW=:pR&lhL=W58eZ#Bm%i^%96/1inauei4>RQ\icWh^y/JG#j=y?nkW
q+e4*9 +h#J%lV>lW#D:9VSZZEwT?%I<yEq#e#YEcYlKuNkTeTZF@4KSe@/4M^Aa+pH:QEGh/VaS:X/Sy?DGDci
9iRlae dp@=D++n>8nK*t\*>h#u>hq91LJh!Mk#4YC/LD@>NnjTI86V<c?E^ce@>l5u>@89Gd6@Rw@L/:%\t9=K
5a/q9Z qpby@J4p^1l8MHI=M/B>4C1iSWhNpqH/$a16!p9*P454W:GNjl^<F>pZ6+=iZIq?:JK=88\@EC#=QeSY
Jjw$ZK >NT?a@Q!#j5K1SZ*NdtEAn9jb8EA@hDX@a@uA:<4X?PCQ%Qe<6JewYD5mcQ>WT%L@9=H^4BlWC9e9ay<
u%lcFq *h\%$\^N??*uE*Ku:<dVl6:Be>ThFNKA&WbDNhQ#PqYd4Q&:9wGi*lN6R\\a8L:@FVXnTwwHPBE4&mH!
<itXiM 6N!c9YGdyXEnLhiWn<#e5q<#/a^Z6ATNI??%LFqC*K/Dpn/cQZ/W>GPP^Ve>NR@H&?JXX&tiTP%\+!ub
\YjNKK YNSFq=PSMt/^P8jliSYHVePBVX8d:>kdQbP<JByuM%T@DNK84?KHW!!%EqnFSyhb+#yH44aZ4mtGc=IH
Vbl9!: jD&@Zd6T%+/cl^S^qVhj5iyt?qqRWhbNTZ<nbKYPK+6DA/*Ji^Y&Mhq:ak\#TXKWWTyTMhCH%MKDuk54
ic?VPP C>N&$/JidAeq:XP8:QbJVNPq+DRLYC&hl<uRSI!Q@p^hauYhVRZ%bL1Gd@1m?m=hb\FCtPl^NwP+y$ZH
1jJtI^ *d?T$NC@biK^*&9hhEua8Ec:4Mk5hDd8%&*L\Ke##>4W1K4dpm*Qcll6Q=K>tYqLt8>@a?y>CakAGwk\
TZRTSP ?BS!J5LkT=4$X/SVZ6h/$F#+MD/*Qp56YEnE/M&1eqb>!B=D=AaL8S<KGTCc4/m6&NRI9d%yd\4aJeM+
Pi\G\E Xh$G*c%LF5lYyqJcjVqhWh<BjKyQSnDHc/l/iuHVp/PtbTitM&*PXlWdHRdC@aVB&E?cpc8ZSi$Ru6y%
WyM<bF VLZ\Nc1^L/KSMm$Tcq*Gji5dll#:XVPVQWXWeAPYF\+q$MRMFBVl=h@w4:Y1yCI>w8>&n>$#:LXj%9n!
EuVH6a B\<De%B:wG\Dp?Lb?LPQ4eLlQ?<+^Q!WLW$y1w^!9qumn@Pwh$h*FWw<FcB#t#ba:81ebI8TM@RcYV4i
PhM?D= /N=uC#Tqnp1>J#^LLkaj+P4e#C@Q81L%kPylt<B>Yat?*h=QFwiTHyhpKZa/<Th!jwIGFKuFK1*XYbA\
iLpm*@ /Y<BY<^N%M:k1hTT6&@+?bZJ?$+ddCRjjmiYW8%idX@>/b^T?bC%Q+&R/YX6*?pXBE!+!%Nh^=aIpnVW
I6a+M^ d*:NP@*b+ZGleLydkyC41A<Hb+QB5>Zd>h%YD^A:Z=GXGw?pS@iwPqYJ\XpjMidSyE$96$>c$94ciPiT
Dn#\:9 =nh1T1&9DDapc4y<*jhPZ?qJlZKNhh:n<>C>uS5YyDkFQ8SEG>*F6VNhH=quA&@#TiH4G4NGQ$Z?=t#c
5>ekuD Vhnmmyl>eN#@HGaXJN#dG*=jRu:\?F9ty:P9<+m91k^M>?#cNyL5^MLab\IYd^BYnE58HCcu%=T#q:PW
IIA@qH SYCMy1/>damdZtX%WlqZ&&cEcVdX5y?&$&k@LuhHBG^tY:W@5D$ct&TMLJ*Q>kY8d@Y5GSiZk\P6a>WJ
YbdK%Y Z>$#*Ph54=qF/T6+T%j6FY8FL>qVnJ!>/k=Jud4MYnE#EeQcljEnF:cw&S>J^PTZXD&ct?@5a=SLAP=>
$%Rnh% W>/e%SK4aHR!?Nw<<4KQmiVl9Qk+t9Y/>h9i%SDhT$<e>4>kD*lnMcyNVtaQBX?ahu>9e!d849EyyQwW
eVMT/8 b15\@cm&$u?JV*/Fup%cjYWL9^uhdl*8pZKyk@ebyePBV1=T*EZn6?jnd%yWT*aknZPGw+@MywQE#&LD
H>dI!M 8V/>Wc6KQXV!!>j9q4nH$+a589ZSW99k=C/k\C8#ZH+B4^u/a4Tadt^Ek?Gn=HwaePySb^$4$$IqjitY
ZPty?6 65DRRW9:%4*mu/8XGa&QFu!j%:$FIaRhnNZ8kElVB<NqW9eTuSapqB4KZ@9:yGu1Qu8uYqacj<N8bjtl
RIFFL& <PTqHBH8d:bYu%H#I%Y9t:ld:>=1N=++FZBY5e%4$8pactkY*/&=a<l>yNYYD$=:?e4kFLZ*%Ql:#u/+
F$dV@D um=i6BG<&qiEk:eeN9Qt9@JpY9QV!I+\Pyj<qXu&\jE<p9KhTE%$!!un9Jdat?&>>M&#GM/^5m1&QwuH
QQ/9kW m9ee>1Y>nDBQ!kc#G5#YqS&6Tma^lbS9m!!EBcu5qDP*d4HcK!TNDq#HD6!cGHALHAlqKJpW\C=4FdEJ
%nea/R a!<A!k>jFSLA+tA!N54kRW&j^=SqVN59XYA5>\qRIiYM\p+pHh8h*tTYalq&AaI#G/D$85cVIWaFTp%b
qWBWmk J9a*yB><?a$Ql\nABlH=@m#8G$8X*jwtFbM%qF4$tk:\wdjJKk+e&Tj>n@yb&wYlDKKuR!5!\>Jdtp8H
yRA&:+ Ylbdtp/KYnEj%Va\6I5<HXam\/E<\!Qm*Ce*<5QhNP&9=6cu<Fb8puwF&bWjX<ba54QhHw\>!iXJ%+kN
AV\+e\ KkIdchN4cjih1X\IF8j?9L8im5tDC5i&cM$a!whF/Cm!/Fk?K/+&%jE#dV/&Wb:l=qc+ZjFyF6q?P41d
*%ZCY> NV\JLG:RGbp^bY+MH9c:1<lY4%YZRwh@*!jD$4bwTS5t1nHnN=bF1=&5njQ9^qYWW@IiD?^^F<THn8^^
L&<&LY =JaC!<JQNFja49MRl?nNeku/>#T5Nc>DYS??$!tM=uhmWPX>qejalyTBqCNmt<Zw<1^m5^l@WB+#A=P?
nCme66 /ycB?w=bH>%/hYP=9dp*c<J8WT<kBbh<R?bHpylSwk:b8+JuE6pIq+h9j^SJAi=uRRcRhMwDS$>G\IL5
R9?Sb8 9uwQP@Vnhl=^#&ShN=ZbwBD#PXGW@1FjZ6aectkAtJ>CMBpIM*dX??ikV:C5#6VkMu1X8MjQiP+LuVCK
T+k=Y: pX*/huRDiF1$hBNBN1up8FWj$e=RyjF+w#6hhE\#d5pRi&Qc14:68Jun?/cMYBh8iP8PjjAN+Q!n\Tu>
@VTQbW !6lH?d46dL4n9C96G?Me+Y5w<El=%ePEEX1nNnYXnD5F<bP/P:yqG!N*qXe1t?=^:JW<Z8h++4Ewdnp^
b*\1!D /#d!CDTiQ8W/Zda!D4nN@+*KPLTHc:l4Su>E9u>LXc#4?tLJ#Z#h5ec!?4NuW?!6N!L&/yRY4m8j#%qW
kSk=en WR>jy$j5hNXqK<>5VVjGwGHQl11m=6tS9NKTe&I69GijlXVEckeneMtje^Mc>C98nYchN&Y6$VLkVJ?9
JnluM5 XLaJ1l&@RSm\G#T^!9JRt!t?4hM4t8hXj<#^dGmmj@AuJWd1h>dIA65wqXE#ZQAS%Z\e4:VK8<E<NCc>
+8eXdK hKd\1VIFi&HY:QBS<YLAt9VTTuESLei#dGQ6/edYAeNhq+cjZPd/&kuV>%W&yKlH8i<hD#*eGS:R+XhY
lIW%?\ tL1jQD6CMY#T!9GIdXPq9BtVh&PyYd^MS&#cIwI6WGTyb$eq+MZm$1aAS*>X=Y5Yb//qtBJtPM>Ttb4S
btYcte m&hW5G*#\&jNJe8wu@\+>Kb1@Mn6n<!tli$ei\XbpX4V6$X^DMdy!thLiZJY#9yGlRc\$La!c%cJWYQD
AC?#t@ whn?V=/W@TqLayi6Ye8N\>aw?&btD\hR1KcbIl%G#RW4:uFcZtNV5Fl@QGt8=K*S^Ai4dd:!%!:K!FS4
jD:&p^ 9l<m:@TMnbd$&+m4V5@GT5aFpwi5D%WMnMH1$SABDhQF%4HXq*/cb8W*hR\%Cq@bI4K6j9BTeaaY!64q
?nF$BP 4Ki6iYyLKt4cipb$SId1@4T#GZlbI$9#FQSqhdGp$JPj<*a\K\R&a/FYZD%4EZKj8Zw59@yNyp:cdFF/
51=YPq q*HK\n6hlZw@1ak8+>petFM#F5lcZGMnT9b/Lip/uXP4$i%wqpn%anDSq8ut$=TT8bmwY*9>Fn1MjC@L
<PTpS$ :Sy84H+8M%n1j%dtP>q<B!ptpA8:cue4atnH#qR<WD/C<bcdKHii%QlQu?i>Tt5VB##$L4w@^G+Wcw\9
kaZKZm MbSi8V@8^4D/MhNlt@4=^$!Ykwc%S>E/yXnH\ywZXbyFuc<euhC5+B/d=VjnHlDHth#1bu5u+cJ^4Y<9
9C#y5C 1m?N/^l^?$!pL*9dP4+lPW>PmHw/yj?p#u9@wu4E=HS@hbE$LLVt$Ibp4L>5p**>ydct5*Y5M@?eI9!1
jlTW+p Hn&\kWiIt^51d?SyX$4c5PB+\B@NH<y!e@a?#:9yMykuG!mHTWYPDY^b>G:VliuA^Vl#W$YVQ8WNV/H=
Ga+E*I IMb4M#:@$a?Bq?#mC\l9uSnV?huDjNuVK81pZPe9>PK9//Q:J+wmZ#dJ8nb*VA^CySY&dW+qlkJ@dey1
$l>SVJ DMP\t#>Ei#^DZVhBbYNp4*bVZZ?B%FVQN>@>+m4/4le9LPtb:^#ALq#T\<$9u@:mNd+YN6m/d:8hN<K*
RAWuDN 5k=m*4bQb*?/VWBud?6MnTi9h>X>$:YHMqS#PQueyhMMJIA=Cd9%&<c1qH8Wc+n+HWQ$nRIF6<BDJ^wl
-A>BH^ 000d7c03d7b00110333 Page 53 of binaries1.zip
T$/CbM @yT6DSw?@lR%^!yK!6iSdw:^%@i&<Z9G+6XES:6%%peDnlwKD64jBIeMh1&?8iPR?F%%tw6ddt!jJidp
@\y^Ky :wECC%\RhbRKn1Q%k6Gp4ppVFq<q>eBFF6<CiBD+Yhk4t9/Ib?GjHu?G&wh@WS8hib:*npL/#cb%peAG
5a@<^F >\n<iuHhaVX@LLQd$eVwB^bWWYbFyYe+c&d%nVWGLYw94Sh1VyR%Z16jdDP>:G&*I?t&818j=k4Kptq=
4@umbm YSLR/<&QMqThJD*:p/+@&6quj*:96ht#k$Z+L\y:E#<b!G8?l5\P#9NTEPTS18:/4Yw&m$1CAJ$hR=uB
\M18:J w<nY/MiE&hcM55XuQJtDBTndBQ$e9+T%uZM1k@duH:6F+^:6QL*#*PEA@!ma@>5tHW%K9qq!CX<&>ww9
F8uXm8 keiljyI9aXy<:h&aVTGA*#Kj5VAY99m!HEJZa*t&!pBjEtkk>t*8S6nQ8nJutue/R1YdNP?aXGI%:%&@
m1QPBm <9RZ!Vl/16*tDn!QYbT?IhQcTETkmHhV$y4?4QSd!DLh%NQB1Fy>hH$a<8dF5cLiMaNJc?jnJp9FtJhM
nQXJkH %9Y^+n!66&aXR@T*?i:6eHAy4M1AtHZKnL*CKLMYL?twNm@:dLH?:Ja%iXV1YR14/!=qL1L*JJMTjdPl
b%G>AH a#S5R9e<9W>BlyGtZiI8%DjA+PSX+XZ1&uti>^Q9KE9bp9c#9Ydb>8i5HB4aWpK!/59pQ@duG>tZeK??
n8W%%w ?c##dN4>pab+aF5WDZknZXY5i!/DJ>cba!+4T&L*%8E#R4dPZt8!J1Y+e?@h:t#lZ9Mbl5Et8H<Ak$Vn
PShR\k C6%hCy\KWw&#bL@9k*D*B%Xi85WuuZ/@t&>BQ<RyM>94hAchIV$Cbje#YM\dP6RCaWKj8%VLT>9jq&\Z
pVqHRl q@#+WQKcI<R\X8d#He6\e?jTcyu4b%XW^%%1#ydTJnZIuTCi!ui<:b*?R:qpC=&?niXmQ6LBFMyJql<%
tSGu1: &mj5e$Jnu*$Mbm##FML<bt4$@hw^hi6bBnPZ<*YS<$?lS?*e:Q^im&BJT$b6Y9=kc>iXwRCj*+IndP%l
5ki$a\ LqY>VG\aE*=PpXeWZ/4d>yGa%!\hLFIWy^@4!Y/F1^!nQ%tjDn?e9KjR?w:+IiVuIDR:\ie4ljnbPu^e
5lY#Wq $iL<qeK4<K&ZVtGCN^CYCj+5Ec#ZS!>yWecZJkSauuH+d?!QtjdTA\Q5dE\5ZjqjFG=aHk41u:&%PcPa
DVj/P6 u=>k<94=8hmN+p#ZYPCJqe&cAT:nZpT9i/G<=Yin<J!n!e?mNBG9uG/5PYhh$yc/1:MS<nu@lq:EVhhQ
$ejQZM :%GWL?RnA?Y@!KFw:i>@l8S?KZj#9?GRj5<*+yXhlAAKL5*==abG%M>wX4BdbP&V#$@CN&mXu6>=<?Du
k?e:KR yL^^hmu4Wj1cA:X/mFQZtli#>8X*L$PiDw\LJ6kE<b<L*e//R+M&VRt8/a5&LNLh=&V!n6+&Xhw6i9Dy
EXJ/t> #KukQh*R*njFTbcIdA?u^dKI\Ah8q/LhtGG/nBEH<#heStKmn=qihk#qZjdeiQ1KTj1!c@B6=?YZt<#9
Vi&B?& 9u%9bTP:SjtK=M^ii@%bm59H61@*c8*=/KNqj:9Ru=:Ll45kbmqj@4maD+%&Ld&R9Ze=Z=ly>#Jlh99<
Pp?HWA <9YLt<*u/8X=Idj9@@#h@49Ha:5STd4>aZS?DN>4d4*=@e4e%#^ny:&:dm/eZ&e!8RMj59A?m&6VKub*
E!>!ML iEu+>HLq41Q4bN!IAmH!yewh^N%4$+>8VlRS9ILJ^$aE4Vi@MMY9*I/8?jy>S<p6uwiFY?mmqjuVK/<4
XFKF#& %@CQKFKq:8a%9H4ll54&?SB$=X=\nQknYw%uQ%?X&^?L@=Ve?MYeGTu9SXGZkh:Ke1L/VLETFA%X9n4D
=B#*8% +yD@8mm6MkbwTi6m<Z&qKMLVkAAj9Y#<aQ\V5%NVLCZ99jMn\cI>Z>6:H<hZ1e?%M:#^HBTAEY\ANDE%
QWcV$Z TYPmJ$mPDydKG^w!^ptYYEy1FSwk:upubw&n<\aY5NIe5JSlaDKFF=1P&5&5w6ButmqujHTJFduqJbE$
1Yp^S= qe1#*d4n1H#h1DcZpL5Vw%lk\G@Pt6Znc/lwNGmP6+w6+tHNHtPpQD9XF1<$<88MjT1l4*^u+wllMh9I
5t1XX1 Hhd^hK8cy=ybk/jaWDJM/lHXR$5PA&&IXkD#h#P&hNFh1h6LCqVmGVA9!>^cJ$WEJ=!uJJw$i=e=B#QG
t8iE9E <aWaJCT@*?KYFFLhb<Y9wjek%<wL\y/#ynNet4:kcdp>%dkdt@WpD@jR=9IGpJ#CH<6lWL&1LIqy!$5Q
dCtwZh mZb:L>/ZchFk@VCG>VYF4!SHh6<m$nQ@XiTu:Ei1>DhNpp\@dq!qYZ1@Iju&AQ8puiblbY@KaPQGeB9K
8!CSAh m1JaQnjSBCqXTSyLVCG#t%JJ+TG69JCuwQm#b=RXyQ<Zl>u>TZ:hH&@?&:m>@&cAHib@VM@:4^McFYV?
S<WY+C &\F&+R1&a9:BLmFPBE<ZZ%YBIBE99HcaDeFI%<ZRLqlQ$C%W%=$:ZFHTWCBW%<n%H&q*Z5FCk5IBD1ya
VDkbNi VW5=c%QyEDkX&kAZITyly1M4IS98/Kt6dte5K8T8l>P&qFZ^\ey!1?A\#mKG=k1cjkFt%yElVlkNiYi*
iCRDH$ WCiSWH5nAb\^S6uYCE:F=?86IQ/Q\DP<qK/4u4i<p1G4k1/L1L/bnykDRWHa%W?RQ=VH#qbcu>6D%W?C
cYLX#t *=GQ*%\#$D5aI&#ta5CuHi+WAceKFDeX$qb#qHDS=>i*hVBVpHFR6FZuhkn*CbLXpTj+K8maeQNc/Ew:
hcE9^t c&pTI9V>MSHiARHijAditEkVc%MLLF4jF$/q=+n%X=dSE=P%?$jktR6iX6jMXNqWBc>pcCuL:eadGP#9
8&yp8: =B<bKl>5JmIXwelu/t+WE8V5yTdwkiNVN<a1Kj5K\1pWDh%M?TX>LApSIk:8BAeJk*BiNR5?kn\il@e$
W?LbdX XBLTqyD%h:aZC8RX6iMucAwdC8yKeh9//wn^YI94TpmmHSSe+FSm%14&AV+&F44&@pbBbl4Yqnk4QXN*
ReY&56 9ITRjISa5KK@4+?Mu:TtTlDG&qNX*WLB*>lXQ%nLmFiLIGA8y5a4F&HwBce!DHJ\qdM*q9j&$JdEmjH!
ekbI9K ??nc1>ycK+1wY/41mcJN9I^6XV&q>SRIP8:t$w/?\R1i^n=mn8c&Xp18BJ\qD:i5Cb^K!eeQ:?mE%SSR
dGhD+d 5:V#n=A\M<BFG6uIK9Hy?%y/B9Lm%NT5^d!eiH\XVR#=kySWyBRXhFThk\JXNT!FJAMC%PZXk8FWiLNk
XauSQ@ L\tNIH$ZTT6>aY+bj1P\CC6%XTFCKMFBYF:N!hFLZqhJW5uRKwTZ^+EkFpL\%*QmC:Z%Mk5VW4F$WRyX
TWDyLk DwhVCRq4!&n1cSL5:VE/*Qy</8EB:1JKylK!tH<E8WqKG58KidtJ?VnyG9tH?Dp4?9naihpG/AlE&kTI
LCQ5A1 /+dd8$eaceCyHAWDhW#qR5J%dAX%VX^DbMLeVF%5Mib&EwJm+1JYSqL?<uKlcwI?e8IY6pEYPnccan!c
LpbAQl @1=KQNyiTtaB^8+EIV!e!pQEYpLZkTDnEw#nF4a$MDI#5qe&qQjSCuD#+MHbiWi+PQIL+SZW\$^XnZ&p
kBaWRL *V*RIh+G%lG/PGhMtKCC6/1@RmTe!nXa!D#MD+8^q9CVhbbTe4Y$DFBWeMIa/al!a/!\4kwaj*X4cT%9
ahjAcl EVpqWX+%P$p9+SBqRR6qKREJL&$ya&P*WC5+qact5y?5XcmqyIaMH$bR%$6FGG&4H!EeH8+y/G<kaC@w
CN%/=1 :/yuEKyl/cjq!&j5/Tkdww:?<\A:Bhu@#4^WPjR@#W8XR@@hicu@$X:^Z=5&@uut/d@Qnj*ZAZaK<u?D
A+#d%l @a5AP\YFj<*KK9:=4FWF^d@B@pY\tmL/Z:M!$u??41LW*&Cq@wLF@G6Y?m?C=BTq@#YLpj:#\D=Ftd@B
!#?\I% @pX\u1L59&d@5l6I<i<Wq6!jD<SXqQ<:F@nQm%JS+j<G?#eKT$d&V\Q5=NB@w:Cp=j?C@c?hW@>P@5</
#dAbA? y@+n6P+juXPaj?/e?4iN+d<G&Epy@H<u\M:6@\MBh1b8@\m\/\^kjp#A459eL^n\ReB=1&^awaM#jw?d
C$+1KK Lh>S5HeWDM9%t?+&JcqMYXIF<jKdKeu5RuMhNE^RlIjHS/t?Twe\pdM##j9LdYIHQDp#tc+5pLcln%yt
=cCJR# ETK@8uZFMq+=&M\kwl>*?Bi$D5=>eJhdV4XC9*YBYd+A>cb&w6j\EAVTF&Y:Pm5\/6kY$a/AN<u<G8wI
Cpp<k* w*:GaTNch!Suq&uh=4n\%4nKAc4^pF\aa<F#\VdPI9cS!@H+>ZjqqmyH1qX^a/w*kb5Qyq&Y^<t$YFZE
/iRq5P h!P:PPCZj#kKhGh*Yc1w?uHw<clWJA+1nt^ni^Bw?aPyKh=%YiSR%/=ecIqnS@@91?bFqb5TEKp4eN/H
pFi4k$ LCiPPM\Nh%iQTeW1Pe#aG8hYd?4MymRPQm#puD6n^1>5LB@eGwS$NXCwL>VTb$!!>i^w6WA8F4!Rte$1
>VVc&5 lA*tAjXHMZeEJ^WCYB?K!K$X#n^#t^1cq:jRL=G?&PZq%dt5hI1R#PBT%^IubIXI9YLaieeW91L5Kp^+
tu!YVQ i!Yj6cXy>ub9<!:#G#aZ^uup&9PkMeZi%6DI$G8jn6hmER9Q@SZnF>n9lD@:Jn$^#l=^9J4WKqy?^yP9
k9H\*R &55u\dH*VR>@P+lc$6Nl>**A=<#>1nDic^e!WWZ*an1D@CPlQYWLc<?&A*:%S#==ZDl4Z=uqtt*<Y+kW
<DHj#K eQiX^m&c4i1?Jw?RbuneD\n<my<R95pB+ZdbdQJhj&p$6N9\4jhX!WZ:J*5SQ&c!\QGn#Y^K1Z/:LE*5
%lpq<b ?qB+T6uTTn:n^cR^n9BdQj@H?iLRp5:Bw9?V@T<qmTTSWIw<Sta4J@?N\%5$e?nJ/5=M?LNGpPqHNVHY
ZXNleL B&c\t^#W<Vu=IA%E<YPY\&J5+#e&4T$*^=&ql^J%S<^N&n=+Y&S\l6B4abueac:l1m/$H\\y=NQD5Z85
QT%c?^ GGZ<hFPqGH*j\WBE#$!aj\!uhtbiZb!bLX6h?9XLG?PQPQnHK/FN^ai$dHFL?nj!6TePN8hb&Paq&mt%
kS+kmj S1*FRJYG\1+T\ui+BhSK<#%APq:>M6Wl9uAa:DF84pma:e%WHH*qkYP?5Xcj>b&ijh@:eIw?QHN*kb\X
\6WIwZ iFI/<Kynwh6?8Wbqe&D/>bHHhGbML@qww*M*XyY@ei%bd>!u#mP8q/CQD<!HF@Ky$IyN*%!MBM5!XHMV
QkQ=\w +/acaI:D8iE/e@T1mlE=8cW@G9LNY^J$9uIhVVhFS\e#1*XeL1SmWQGQP9/ww8The:bXJ^Sq*9#K*P1V
ZFKB8D GuYl9+#wq/LiqbDlt</TX>/4KKci9DD&HT+wjb>S>6DTXd8aedd?k#tewiQ+!?ddRQFFKTXSFyum\$+b
Ld?Yti ^^cQ6eTS*CyiC=tMp\69eaY\6y1V<A^m=i$1QW=$>jY<cF?1*FF*nQ<KWqaTY@5R!T99aMHZZ8SN<Fib
IGiyde /HWnK\1@ERpcXItty/G9m!l1=:wl@WWmTtk&^16^8&tJcAq%H+ppuHpbQbCY6^M:StWVHw?c>k\WDt1&
^A1FF# ^cj*PW+ZP@yy/LBHB&*#6#**wVKP#an:+4D%@M%WccE$1beTE&CuY+bjWlX\jRBAy?GTcSDT%tH/Y+Q*
q@RZDK Xk<1p11LH>d1tD8HK&TL6:XX?Bt@q:SI>iHCB^jM+S>9QQ^1E5VB?Pn/D:/H%Eb*JCH6#cc9yaWtYIVN
=K!4FP ub!9a9jYy1Sq:4=u9ATN$NDjZGd&CG+ic&%cpS<VPMmSNJ=:FQYF*=4p%8kYkDKd4*C8=pj/BMNhJFyT
%<P=Rm #%nbd+q?*FWJ%?6%%H$?Mt8lM6I:dWLe<!9?<LF5*niVHpYPHiy%Yy1BS5>qqm$diFuEK89u?Mn9X98>
-Ab&Q6 000b688163800110333 Page 54 of binaries1.zip
J!I+y& M*4ySZm>M8$8u=J6:JeX<*q\8+y+59H1!I4GIm@Eap*9@k^D11:b5#HZXHJtVl8VKa5Yly&lu9STy@ib
CIBktC ?#E5k+W8h%h9^^Y?p?qL\:HwMClGEpKdN\:h*qDdDmnw\ctF!#LDHHliH4h=!4yWC&:Cc=t:1+Icj6W>
&Za\in be/V8V&dh>E?P1+1M5N5uCJL5eT+eaF*btcL#1q=HCa@PYN=uZXe5KD=kjYaA?JI^q6uQ&lLJ?TF/&JV
/JyKjR ZE5a%+!N95S>4/#5ql/DhTXG&9BtZwilL&J5Rn+::E6DMk?!Q:a^65j1ZQj*$VT8:^aE9bRE5Y6YR61?
5qZaL5 #FBtnCebLJhRC*J6yRC>N*b?t+*i6h!%L@E\N9m+^>BmY?JwQX4!qYG%b8peqGPYu%u16hdM$CD@Htcc
1FDKkI jmLBS%\wWkn51cD+<S=Tw5LG&tpXJ^&/V4ylmDWMeZCMyXPA9p==l\u5nwqN:wjd8hbXpa<L:^iC*pq>
nac%C+ wl=I$w^DcXqDT+$%:iP\Lc6Y<4I%V!=jF8V:\jn8mnJ#%:pE!y@#yF<:Jq<R^1>k+Q@$iuP@kk8Pc<4+
Y%j#wB >j&h=E$%>#G#Gbeulh!SqV?CG<\6HjC9:>$?@LB&iV#ydH\@baZ+^Z+/JnWZdunN@\dZ@JM+W<L&+4^@
!H>jRw Ltj*@4qDjjA>4$&^jmD@B/ZB9t1j&Ihhe/J4%K:J:5<#NPh8^D54jiDncQ?=ii$c+4p$&Qu!:a99^u/1
TtK<eZ :<eKIE1=RqR*Lw!9Zk%^n8E>cRqTYnl@MXH9hpV^tt=L&G@IhBWCIN*^Q<5jePk<<kSPDiS4Pd#TFXwe
dS*+up e&meF@lM!daThF:>F9<1SPGMW6Q%dTe/8PtqKE\9q+I\4>c9j*D9SlXpXmY9:1^*b8YZGFjZ@X>Q9MDK
dH#uee 5Kk?*%>>ISS6hH+@y5+j9c*L4pQi!IccukT>D/H/#9>L&y<jIyL^!m@u%?^Ct#=#bV%Zm*ia4=n&!+Me
i4W$F\ d6ye$b*$&\NV+5Ew^!111YA%6\NTu^i+Nujh9KG&lC+wLiS>^%dRMuR@$<9HmRb9ulwJuJM^%Iq&#d*c
#:*iGi =i6$=Fu*pY:u&5J:QdFC<#VMqnqW=*/uSEP@QTVcle1aEjLLiiEDA1j&LN*I>h*Pt1Tdn4:F$Z89e!w9
Ry<1wH uhbXuhh=>LpjteV>awYJ5Daq@DR=cBaqJ4\B$\pn<iXKXKG!k@VCnS5CWFuaq15<A*+KM>&Y+$*p>P*G
9IiRDB bJ%R?lc49R&XckWND#ZXYT+VH19dA/u=Pq+\L$SM+y:5EXEjhR\VcJuWubFMkSG<K$%QywJ4yNm14q1B
GuTqyd &utV$1*+ed^9:Nq&uc!yGpV=dSy>w!p@QH<NkYWbkGR>bpdJF^+*4?jW@SlC>^Zj?NK*\CeGh&p<Ne1:
yVqlhy D*w$/bCdh=HZiDBK*e^:hQYJtIdA6APSw1uN?A&@$B9!#Mi9Ju:%VnNhw4/+PnF#R=Ta8:YjtJk1eZ?@
eXY5u? lQawc@w!L^$%IAh/Hiak%qABd$1n$C=8k4b<\J8V<@t%RXd/GqapG^+QmSKdF:Th59FFXEPQJk:Y6h8Z
C^dwZj &<%/=:@<wkmkF665D65TQ#*w#m$8#pBI6Qj$+ZjylQcK=kTejBb!@W@d>BX?wI%/S/1*VQ6:b#e!C>ky
uFnSFk JS$qn9bj\6hpBQ\K$^&p<6JFQ&cNwdb$6ENw?SK4y>Q#>l8mewJe1AH/wFj<@DSPuqt+FETEDqS<F%q+
*GaEwn EL<G=hGZpFXM*Veud4MKFNFNT<tN=#h+%m8qF4eF&!8uiq%JR6QWXQb=SX$YAEAk>^WD\H4cQnlnG6J5
PK+qVZ @FeIt*qBn:j*\XjSi?wh:VXRwp:qty!AXV#MDa:c&DWTTiFb5SEl$HnYtXGk^QWij$/ZTj&W8@St^@@i
X$RtYF D>laBFyeP<l:Y6PAPiqnyWhk1*yiXtDmFIWRl?8!w<bp>:Y^M8nR=5m5$b*l%yJ$9c9Gb\=J4nS6d8HE
lqCtk> 6%1whZkKNNqK8:eDG:@C1n1T8>NT:p1daCAnp1nuVJWlwX6aYSwYeGXF=DHG=$%ddaA*kJ6mRGYeAtYT
%q!@y4 bbJl$cT:eWX#IZhkV?bN^wyulpWLJey4R8F?TBaN<yl?hR#qSKqdjR%em\+yG/Zb!\tGmZ@k?j^/lF?$
8+Nmj: :9MyTMKNPQwG&nBtEJj#8FEVh=P+RNQ/qqX#Cd+!pjh/BWyi:PVnb>iyB*8>j<hL/HXYpcuuR?6/C%MB
^QW1eB u?Stp&#TBq!cS<J6p/cthhbCKd=t*ec/SL<\&kqjAVD>DiR:ISjd8^Qyb$y@^WS9wQMy*wWZhP1&=J4^
/keeZV SbjJy8l#hA&C!Tb^\W/&J!%6\1WRpdt@EMP@LB#kL%%:!SXkSmPd=*\M\R:XnYEc$H:!>DW*uMn#E%w=
QB^au5 dXJ>eEtaHY<DhDjH:yT1RGAY+jPpdtNbEq?mY^ZaQFXCF>b*YMQ8aZ^ZCeIZFHFed#Zl=M*SJ*N$<*ne
J/8XYn mD@%VE8Y$GB*G9p+puKQ<BH:lteNpXKZlN1mkhbJpl6/ijn:4l1pj4H%KHaciHjXNRYtw*5QP:^\M\qW
u8QIjN C*ewkZ^Vj*ySI/Q4&9*+<Y#6A8P\5!\48Gl9K148>/=yAI&>=J^D*/k9A?VmF>pelJHChMZV:pAVHdXp
uSpX%c e4B16%IKZPBL4mj8/mDh8&VyCqLH%?m/VNFy=kBV=tNJiDmWZCl?#5p:&!nd^?t??@yZ\RQ##Im#:GyV
n\VMjI :ZPh9bD+<EVC=+:\+lXV:c<tN\Z\c!L?WHZ@LL^Jipa<<bM##?dX=D4HP8a>&i?P:w:PeL?m6?11he+K
JhM\w@ Z9S1u+LG^^hDdkbei!>+1XHIDQA!Vuct>QWbjyZPqYW=@9NXq&:PGIHa/9i!Ak6+R5E6%>V<N%q4X!qc
JVCXIE u/T&?RSt8V:kD!l/HN=\wI<aKn4#6#RYet$!!tCyCQ:c+44c<<%wZQ<kLApJPKSPlA5i6H>%<c%yPK>&
wI4F>m VE=ykn*I8b6SqC^Gp=4&XKYbS8bR4ec$NYu$X=YWkEM?+AyhpcW=p\y1k#lS+&n^*m5q>THkp*P%c#AM
%XQ6XA djLSTX*BNV=J$w&<NDZH@41MiB4@$hnd=k#!A9CwRE+*BjR\?pi#t=+X8+&yYwT<*$mT4LqPueR>n>^q
>&q9^a =mDQ%Il1b<d%DaqyhW@pWd&*TWVJpt^:c:T:kdTil$P&eHc&t<V>LVjcjceam4^b5D/q5PN:RM@VW<JJ
Fb%PV9 @R*tbpZDe8un4jbilW!ch?Ime>GHuW/<+CHT?@Bi44+piT@?8D<&8Mc/b8$$%uD9XQQeP:J9QJ\u>&>W
eYtn$! l=cIZW9+bu&6?u6RFHP&bWq#KyuR/\9:6$NS%d>9WTE@$jLKRE69Nl4NJwFh9jWnETE^%d@CBY9DhC=e
9eC+cV T^j\#:16Pn$LSi=5<Et+j/q#F&d4VH^XSw9XydmT*L8mq/cE>6<%#i?QY@cPVq!LCS<cGbanj*6lV4\u
b>\#Tk <cuMQQh6aQ1kG*c/elj6>@H1CQq^Dit6!?nZyIKJuGtnVjV?9W>V4qWtP>+d*4F5c>M@p:L/?8yNXXKn
/TwJT! jL5?lNq@TDHT$BMh$@#/V6$+F6aZX^uCqX%uWn&uYp8c4u@9FRN%5&e8/c@mKjNwq<dQ?H8W+58aQi>Q
4Z@q^E *=D8X&dmC*wnJ?MJHZdH%VcAF/L$:1%Cu\@b9KDY5BJHHa1=+<C8Ih/94$R4iCZhKL*5qB&tRC:*WaZl
M:RF4Q I4/q68m4/YX=*!mIIIH/YZ1Lc6lZjFLZ>+Bk%VdhZ\?yu\XuC@%?QS$$9kli@iK=d9j:6aBClq*lh>9\
yDY^?: F!A#KwtTt#V%nn^QC*YbnE*dw5XNt%^SKceH=l*Gu*Y!b9pp!W>$hT8L*<eHJLY<jbG:QjE1/=B9&l>n
StEi=S h?P?\=F$NJXe&Q\9VNtGbE/VjhXM1&=:\@9?pM</G8BDDeQC1#Kw9IpAYPEN4@c=p6N9%1!TiuaMd/S9
V4@B5G &XkJG5!=HE:\Jan=tY:Nl:awiXXd/*>\p#q6Lj^B*m&dRK8w6F@w&Vmlcj4>4V/L&%:uwB:LSB&Fhm4m
<t<?hd RW9%!QQDlh9cB:?X##Hk$DG5PjTNntG@Wy99de&tD^&KGuyFi:Jd##V:R&>IiN&eINN?WG99@ZQw#C*=
R%WMW\ yC+h@Hqkl4bm/a4hlLZ&cI<Z/i%phAula@#ltPyIy&T%#/^&?PC$Ik!@pumX\<AmSmuq5:hhlF5h/+jI
qQB\iE #55hutRcT/D!F<?5&DhES!t#nmXn9K&??4/PqJZp$+q\lt8a!=/$**hc!:%TXQJ8pYn*&a<\6L+V*eX&
JyD%nT V9Jj:tw*!!6c&t8F9tSSy\&T>t%J<>^T9i+XdREaiCt/wu69<VcVkWFmm:PQ^MTFLZa#!8S$QS61/?!T
D@4+NC eb@<L1jA<1Q$:=E<b>MmBTMl6%:1JtAYun%KuB$h8P\eGm%\@8BF$<$!6<m9wj*FjCN$XqKX^#+/5P?P
W<PkQh BlW?I#ybkN+*tZl:u6?k>Z/j=Wd9X<<dQkNam*Y!MB&9I!S?4k@teY8@+VRTaS+Y%WP:w<RqV#@j*6<W
u#VX6W jFqNJm>&J4X6?iHX/dGE@:DtwhNG+9i!><LWa@:ND?V5H&65%knpVbcd>4^#iQjN9b@!XZj9@iVDRGY9
W^Z599 @i<11hY@A%/<w&M^DI#nbL=56@>hJ8tY:INwBiKcX@w#&*aS8hJQH*hm*9>Yw^taXqPp++yjcY/Ye59&
m8q&+V WbVk5JMum$Cl@5V^?Dj4+9<haZ4@Fwn*j>%>\j!#?+L=&?+L=5@eF#u$Q!u5@=HY>=@hF<W@F+*q@ka4
aC&du! >^i5@N>kyiV@uFZ+%?\@FQ\@bSZ@B95Z/$1l@#W4k=H>e%d1d:Dw9&A^@=1X@16%yj<%m@u#NEI=Kbt@
pE$J1I \e4@Bj5*/kwn?^j5*/m49*J>@qE#@^KYS@?=C!L%N\yLDmQ*=?#jKC!bQ:e^=VB@y:Cp@*^h#H>^d9/D
D&lZaa @J<+N@>n#6$@uB6ytZ>&dnB@+6#ITKH@@=F*@+6H*tuG4/RTmG+ICuFpCAI?l%BBWEwJPdB18%eXMw?+
IyqR=# S$?5nLnZnhNA!EnLdQJ6X51$PhtjL6Q&DQybHI<B6Y+^>Y+dXt@LmZ<!in5c!8FKu!YS*ICA$@mQuTaa
wYAGqj q4$FmCip??XD@e>+ya*y6Kl!wS$K*6CM*Nn!Pt^V\Z1!b8:yV^nR/D\D$R89CqCCeS5GTJpq6J4JtYW@
uk4PyJ wull64T%#NCawF*Z5HDGy/bI$>q+V@JJ9h@:d6:4CCw/c?=KKH9n+WRA/<^&wT1=eJin$HT1dCSkQlNV
$%AEF8 +KdWJWylym\VEeu\%Q!M%=l#aqdGY%4PyMSn9a8Jd/nQ?1pT9ZRch+>jeaMt/dwcbn8^&VYF#NH5=1TJ
=XH6SP 16BHqTK^mW#?!&!R5I&VbFFy/aB*IASp%4kFRT&lHPitZ^nlLAkF+qmN81?jleecMVL%#VbjS+c^*bQj
>&pF&& bci%ZYhWW=BqWEqti>ki!THuKN@<\NI>ZVPcdi+!4@#Xq>K@nBNqFRjMBFK+1?I<JwFb/yj9QbiP%QYp
pSknwl j^TuL#eHW?j5Z8#QV5?TTR1<:/KE6mh%T\Sqe=898%$S*KT^8Yh&TFN8\:cnmF6+j<!G>/$K5k1@E1n*
WPa>&F 6PGmWY@!A@u6QWLT:!l:iBeDe%iTb$XTXute*YE9G#/++/HV5JGM<%tE!%P6$/ieC\hjel!nLhleemYk
RRGwZW #nqJ85:Q5ce9FbET?/6WCeaeKti#n:8MVqim%%YP4&#!4a&Wy8b6!M\8NcayP$PV$mhM5B>m6G@4/44L
bDB!d4 PP#mX4X:54!bh6TK^9un^PXYPub?&naHWmZaM6:XWm4PYuGV8qw+PynB/\Aadcni6\e<u$4&GW!b+WFQ
6wR@bS uSw$ikc>1&MZ&6X8L>dW>W%PBjC!6NTYmhbDVRIRRmN1?bPjDu*lG*IDXTa9F$Z9&dW164L4kZ\HDitn
-AbF:K 000bedb375400110333 Page 55 of binaries1.zip
C:kqqR cCcn%Yy=9m^lL5p99Q#N@ZZP&6\9Yh5:@9H6D5RQk$b/j*1NQtG?4Q+Z6?mVBEdHd#EQIq+yY?IdjcXa
lGMZhj 9Q^m>e$V4V&1H=G$NuWH/=YqSu+1qT^#*VFwmMQWP98*InCM>wa$wZ5ZE6CDHH9p\=@Jw9RHhe<ajQhW
1FXl$l LFItCk<=c8hatjtMaaSmR%CTL!6IYka4&JM955jVcB*dqpM%e/e^?mmbcjGhh>8*lM1mnACC9&ZRP#WS
9qhM:A #dykEP466M!CXLYPA9=D>bpBlE/nR6+4q+N>5n+aZ:H>KDXQ\kHn+Dc:D!&LG1RCh5TZtnMVnI1&Nm1#
eXXtc8 BlNQ6ypGl:N?L<LiBYbj$D/bLIC@PG!HtX@SMjEST/QuiC4#4m>Wp1KY6jLYldJZ*9t\eH#/>n4GHe^>
5P=p?S $XMwMd<%M^!VwcGLqeFq#dwy^^I:Z*A58:*QcMSh99>nES8ip@:K+6JNWV!/$5di!QX/h$&nNct#K@iw
LK^TAi ime=WhieAXS56>tkqK8*M1k@N&#q#^/&V4AK%hjm!%dMcLlWIBnJ#i=l=ZeQAVbM4WqjTe1wRGb>qMYN
Rp@plu >uI/^NdtM>ujp<$8X6<%yy66ndV$mj@RjFuTZQmFqBHC?l4*n5ND56=KV=P8u&WFihR?u4J%ytK4R5Zb
5\Hp48 FpWha9hP^AX=qFtbeumYR/ehd5y&=%n:mSlFhJ!>%n=Qp&WId:G+aTBRnqV%+&RuD&jKkb58QH?jihl>
DqV6kk thSXdFjqq9Q<hte%88<%B<ATWH&:\DiN&+%65lP&<1/8Bd&yWX@ebbZh%c^HLZEk1@R+=ElE6+>Ep18d
uyb<Ru +QRZK1F1#jka&ZG!GiJu*&SZlGtjTZa%uqP?=HM1jCdFlQ:ie8W+JkQ>km%N^%/kk@+JXGl>BGyZYCd:
9Z&YT! &:p4h%ZKJn6M%EM^nW4l8SSL919F+MdAXmX9V*Y+Y:aeVbjI<>MhlE%#1+&C8jlNGyi!>^8bS#tDSa1<
L\/<lN 6/E@PE=P<@Y?$hTwj*+FMCaMN1@VP$w^%w/Eyt4LTji@5Gqe/C4jQd8/!1RmMe%6X^+#a9GiRL6jWtM:
A@y&\E ?NlGaZ>M\GyjR#FjLYnR*FYb?#Q*NX?i<XL1S@iH=T*!V516cdnZXBZFEt:RP:R8GA4664H\$*<KpFne
Pc/dBi j*q<m?/qAXY5$B#4XDG//dMT5Iq!99TIZiphGXmYJlbYlu?S?q1?8yINP^ib$*mk%XFT!8yWuH4F\:%P
aPA@Mp !*8Ljd??&#:#bR$Q^=&<%te>L4+&$>tY^hJMutt!9>QRB*:\4q#B5ih:M8<ca+Ml4SY*En&iE@iS\R\j
A8>/4I 4**MLtZm5$q^<E>*Zel/&HGTGF4B&pal6NG\YG%@4$5GGmd&pGdA>!AM+itj^lJ&*qd#HuTnS%:B!#jQ
=hWQcY !$AmNX!^/YWG#&Vm$\4dpm6B/Ry6/T1hNtuu@Lw%F#>LYST%HaF6PXDAZtjw$/Yhb#?FwLZ6ZSwVnuF9
D?XP@^ FJ>H>=jIK?+ZVPXwq$SHPyLQ4clXTRk!d4e$wt\n!/q+IG=ZDBVp%hd4XVuNk1K@nk+pdupbeHC:Tlqh
GFWXW& 8!I/Va6VDJy=^tbddCM?qYQlBA#+HD?#*Z>dQY4uW81!JKC8u#H&FAy/6LB6+KAX!@q!RLHeyqLAuW9p
$1iZpD kWLjI@:+kCe6kaqiN@GE=Bh=k4IuT^GDh*KqnFwQ!<a:=yFQ&9Sb*6+j>6MFGHh$YR4KA\^wkt\8D<ih
DqDd4T NZ&<>5yK?81#kDP*VZyptqFHX4Q@aR@Zq9AP>dP96\PeqHP!N4*k6MV&S@&j=wD4>\9b68QK*u:LJZ>a
X&#/J: pd9GWNb9+DPF=&BH%Qq=h+6i@$Zp1!\#nQ=h%W&<<iY/qy5DQmRVK6btS6eL$m/aCFnCYWDjeFn+T!m<
45mbw/ m\n^$jbb+P9=eFa144iE&=BMK#ccAaLJyekkAuLne/Nw^IhY4kW#<KTbTPwM?D=E#d^JH*TRAnu/B5\S
A6ye%B JNQb$S9L<nP#Mpj:/YnqWW:wW!aupE>dKNLypl9Q/Qk4R85^$KQjaGyEn5ANMHRn5dYVCAP@!Ld+tE&e
GET=%F TV9B?=:i>n4#tbq418?DTSnh4ZP41M%Q%!@ME5nCVVnXCi#ZuX^<%1>M$Y8QFMHhjYNC!tnN1D>6EY4I
+E<qkZ dMV:Bb4=Z%jd9+>%HF:mVSuScIuZ4MK5i+Ry+ya?<aYN/hQ$i8Rj6quDc1y^</$D\9uue^JwHqLl*NG*
Xhlj*q N4MckE?Qj8HFaT/NX\uW\?G:aHE6@HEy&P6u+lq$a8i>IP#>DTN<eQ?wF>e+&EQd9K\dF54<99&VkN%Y
1J/X8G c5>Fdpl:Xe<QWY#/JMh+aFqdm+8e=H8FLI<Zic!R?cA9ihqe#e<V<M<u6$L&>HPuDM5H/*Nl\V#&=4Ne
^TtkCt khH#pk+b>Q*/a%qDHnp@JpwcDE@u@hqmW<Xy>d?#B#%l9>eGDS*tlPH$wZcdthAb#?nQ$K8Zt$K8y#qy
+yXaHR ?=nJ%Ni%G</pnFR@1?FI@PQ+&?Q%=\bp\dn%>mBFVA4HZ4uMmE8DcaT=yC?4^CShE$M/@J5RYZ/BpJX>
Y>w#cq TqMcqX4T&%#QFHS\ypQLCTjEm<jjXMXk/W:BpyN/>VkC9Q/:ipZ!>L$^9=$GCt9M<>nEuVqu=ET5?p#V
lEC^aC =@^XNaa1Bh8dpbWB<JFNh<njNjNMe#l9W#p@%LQYN!t56#B?&@yi*<qp$t%h<1m+=RpXKEyb/M:LVLXu
YYam68 !SEyA<i!DBGV6V\u+yw\j#Z+^%#F$i1t/&^h6A\Fm*e&SN*8jEBt:Ly>>F@h!5&w>=Pqh49\Gi??@9:Z
IVk!Bp k<CYD=?514T#Ibc*aa*4T8Req4Dwc<et8$cFyFd5l#ele=JC!q:qJ&mS$@tkV*=HMeSl=XPKWd+5/HCk
Pbw5%b m8ZY/N8h^/FE=<#*Ymt$4DhII^$wu=p$hRtHZ@9:%\ZEYwS4j$4>p4Wk9Tb6\k<Z^5Eb&l/cil?V=Rb!
NybTl9 /+m9qBw9#Ki8:l6^nVMpj$:PcV^=\Y6<tSY##iGd/%?d/FqwNiBi\Dq/V$m+?4+aw$bi$Dm<mtc<XCNA
JiCTuF ?#bq4j\Mu?J5yI=jJ9#R!#pDpbL#nib\t4cB+WMi?qd4$VGhmq@8n@5%Z51p1ZRQZBuqSbKQT84?m9=B
Y>w?\4 $M*$kYb+c>Lw%qBk>c&/pn&>&kmQZWbBleA/J^4wB\c4MX@EFK#%+6/d*&blGT=$*\&jwpwyV$6#>S1Z
YhJ$Yb tD?pD6DW%Pbd1!4ZcSlCjk6wa&k<15&ZwFwyHG&a?A&5D&Ec$haiE8Wj*bEy1*AkN:DWJm\dQ!mwm\#+
ccNZ\q Ku:cK>#<Rn^:JZ^QIh+ITJ%phP?wYn65Hny6Kq8RyMl#SZne:jX$98hIGQ#A$jE$X=@^yyN%pd\PSe%w
<JHZe: 9hQu?&ICwuyFbq4#=Zl*d==JFjmy%jjF%/#H?1=YduJGN8t:nPAF#jAm+tYbDAkE/qb+%>X<d#JVkBnM
yn!4ui =G4W+VaVu\\8/dn?A4M1$l=k1+5kD9t*=u%m1$<XN+B?$^\:u=cPehYVp%t=^l9F<FP4Y$=IGnZ=&n&m
<m1HWZ S1QP$EReYkw&hGtc<u+ZV$8bc&lMVb&Y\lew>!/Rq?#pc4$Z*>N:P\?cRipj/**+6%Ka5uL^Rh4+%IMG
K=XM:R #T6tHt&n@AaSF/XcIZHEI*m&9IR9j9Nn4P%<1e8m&ZRlEh/Wne>=@H*Gp@8WdllT>n4$belTy*#^NR<@
c>^Wyj q!@nQ=^5AawIXiRMX!Ep>w^9Q8lDeiYm&Y5Jy?896RhpuW4JP:kRpZ/n*C#tYD=QL<H*T1a%V=pwWKq9
\u4YhV 81jByI!^>96NV8q9TR5abFMGe=QYQc/mwhiu/jwmP&u:MDeBkd^:C#6SDT?uPZZuVEQiLuTAK6!V$wQ*
F&u*Pc QbY4PNp1uh:4$4JLZGMm#*kL4+9EIWu*ct<Zk^Sy?m4e:c@weMEFTSc#AZK%QFHhn<85:PLTMydiCI#\
*wQkmX =6JKJF@P<a1Z*%KY!E$Picl&jP/dJ^VdyBMt$Xp@waeLWH5C6W>cb$<mN#95myl=j$u?c&WpaD%%&Ine
1GBScC eGh#KCd<=k^j6mWVSSTWqN=:@F+ZH&yYXjm:HeFuAP4hC6B@u/46Hj8:ma5eteqc%!CZ1K*@8m5XLCK&
jtEX%$ J?H/\NNqX#%%V?h/y<tTjMV6%Fwcw/X?#E8\?YD5?Z^$XFtLacy>AX8pd9YeZT*@8654Bi?$Lm6<hJC&
j9qAa! $I:=\Q$$8<T4EGTPFDBD6F^+*@//8FdcF=Mu$Zh/6*\#eB+1P*S@44%m@q?p9YL?i>146MI@cc@@jq^@
A*FSV$ R*9>h=Hq9$w*@/!Saj=JdqKW?uQbS?=95QJ@\e4@c%d&4>bX?B85:F?\mu?D@jPu=8Yp$j?cqbL:e%qQ
RqLj9w Y8yj5*?yJ$yn@5bB@>ZC$9?c@T56Wq4t9?l/tH?6/&H?p/+ul@quZW@/Q^Ze9%j?j#TuTXyG8pZ<:>@=
YXl9nN *>n::/kt%@bdFA/ElFATim<t>F=CCB%CD:**Fu49XWWN9XjywNI:TAhSpR+mIB%EWLwImDRS?%u94?&#
ZnDGSP **i65^^:j*6<i?^#Bu>qpQueN\@#T8=u#19<Y/EdZFVj$jjjZwmL\$W6QF%CQPBIcWt+KNdX$>$nBI/W
e6!/dj Rj/D&=+l\ac8Rc4?9kH?j9?IHGu+@:%mDT*^:^H+*<btIQ@a:>>ymAA+BpAPk^JGD&^T%4L!$METl8Bb
mqh>u* jCXIBHHKpFNYkc&&DF&KbpWRQ=iGDtQY8M8J^@hwI<E$Ze/&P6TeA#yQ&/*>$iTEHbkA$I<*FGP@KX$\
S1*nA5 ^^M<wajMq/w%>i\W8MXib>bw:64/hi*4HbMGT^\Gn^WkJRNdN6IX@Yl:JN9\&5>C+INAb$Cu*d6q/>CD
t/ReMT D/#ktLL?d%N#y>:QHQ##YY=>yQB:/P^@>i&?Dl$=SF$FITSm@VBqimjE\ke6y*h*j9iV#BXPF$lCCk1S
AB#Q&h %j*$Vnq^:pDK88qN8$ZZlP<lAc+Hl&TGSuiF4$?j*?6:e!J%qW=9wVt=?wqDPZMnlJ\hpDBMcj<\Q?dh
RpZjt: ?/$d4D@#NV9j:**h*cJpVNVkP9TX9Z4=X9V1B\a&>HXNV6SpNa?wVE\jACLAG6PB@ChBkGeuJeKpR^RZ
aiR1jX pwRau%m?XqCWD!5DeCCTqSF+pmMBW#%%EaWP#Wdc$a&KX=1&k5XCYJuAkVPiLKPB5XHM+\aTt+S>auK:
D=LJwG *Fybp!HMa<yaeeSE65R/WPH5!X&ly>p:?cJcdcpn@BN#S/$TL+LX5mTH&lytlhFqHTN<<ielGinJ68?L
GaRu?4 <u4u1Htq44Llh#RnEyPFapa$c#aeYJR9p?d$hGK\el^mJl#:e6/XRhjAqPmL*H!IJEk=IXpT1nc@TQ=N
Ppt@SH j>+wF&E!1+&:1W&<iM6ChWt<$>F$eYE*$F=A?ReaDyH5XLbjD9WN6XtpN$$^m^tk*YNMXGFLp#c=HDF#
Y9X5we jlY&i*<^#ktiIk+bcD>%5P1cpkk%!*i>+&+$ebZPyc8Cbal+JSW/:@9cZL*R>9Y?YA:bBIj6uWmHT#A\
$qc@IE >G&B/\>@S+m$Qw<&l^eme4QdV!L<4TYa<*b>hEk=:?6HaIa$^!>wyRTZ69$!9tRbQ/NC=+L%##t:lRw\
!BShD+ jp&XE5=:dq?1a$1hq@1Ce%>5Xabc:%5L#>a+M+&/q#91&LIRp@dtiVh=*NDw4n:wSV&nAmEwt=1>GQW&
I$FncD Y:&@Xm@ZQPjwcTWtDY+i/D/R/=N4PYabMSiKDW45EQ=w%VYj/F9$pYcwG\QyEbq&PuuY:Z@#M%Zj&bPy
&WS=Pp LpA1EDIwV8:akmaE^MBjBJ?#w4<<Pd6uIb#LYTE&naLKY=l$lN/$pF\L@c4E5Hd&\?*y/\m:Z#j44mLh
96wqR# d:$?ijw8jP<4t@?>=i5@<!6&46kTCk>9*l@L/Q4&=8HRRiV>B%PHX&<b=5>?5L<hP@@&#GH#<+<?$jW9
-A5wGA 0003498776c00110333 Page 56 of binaries1.zip
MJdy$k 6=<89:4/?i9n$c?*<?h*KM+A<w!EQ*Ewpy8G>KD?CBLkk$1KKAMS5DIYAhlIba1l>Q&qHCFH>EcNNdwq
4jm>/c u1J@BZPFwGYQDTmuH9DRQ$Yam5h>FKBY/ZEpj#MyEn6##Kc/+p%i61PWRHGdbbnSCqyY1bqI?bXdVY1S
qNAE=& #IqYI:EX!V@CYEj6%KmZdPRpwq4R^LC%aJE!G%5Qwq\\Ku<XA5YSwwc^n%p1YP!kWVn$eL5mT%TBj/4S
GN?$IL wKLcXcdBEN+cJ9/>GWCb\^yVkp6BmpmNdY$\1=a1p5>SbwF^B&\=V%LVpbI@Bm1=CAcq1bZhIZIJMhHM
@DM8X+ lFT%WMTPdBTV=DYZI@/paakCee6XBRH<JpWNpYmeSE+I5PA&wJLHE5NZ^5TnLE/^GWJhP\8A8\diBHBA
i?t5lR /Fp*\RkmwbKCPYQLS%HpmGEXF5kY%#tphEJ><mTFYAYyN@$1lbDV\+KTR#IqQ+1Xu9DLH8pY1&bqK=!i
aN:I\H KQXn6FGZ=nWCXm=<+:+wwT+H<@pMKXG=DkAl#=BAT1dMe:RtYl4BCVmSV^t8#hMjyNYJh+WS1jWZl4Z:
BTq*A< !ipYh5#EmDFDwn%JRaFw89tYEyyTlC%p+\b9HiwpI<T?LKi$lHi8mJak&8YM=^VDb*aFk>B1qGH4HVA9
\*6M!c eiXEKtt8yMw<uTN<%dTHcQ>y=qc#tqA%SSX!9Tp#c^KXR*hn=I/STCa=a1*pjwYbiV:44CFnhJ\ilwQL
4LFaPq 6K*XqIABT$DuTFmmI!C8\%$wTi!+a/kSl?IjeX4!/He^d@?EawwLwM:@hN!?9E1pm=Etwn6#NW&ahdSe
SZ>4$e FTMtLw&#nM>!w1kK4Z^w&tYSDTeW1qTXyHic9S8FMeJq>kVRq>euYDF@<jeaB%A:?bA*#$yD+6y=/di&
LK8KM> TwV&>$S<F>N4&**5CBFl9WMi#9i49#PRnhcL1pqZhijc4/>6pa9GZaX#<neCal#^W&BIJcFkQ!AXISj1
5\jiG? e?6qZ/cQH1uYiAul!lAh?R^hZFVm/=HTV9w4u4q%+n*miD/Nm9j>CpS8QiL^e9/EuHBb+<h/%1&S><Ca
I/pX>P 4pjeyS#CGn1&DC1*RQYWaelwX>Ji1hY9dRBC:nk^C\8eJcd>E5<@cnqykJ?=F9Xm&WX5V>$%G1/c/Lal
+Ghe9W wZ\*H6ApuyC/md=&tt:=^B>FHTQ?IIlG#JPtDDFE=pml^+ThyQF?C=1MqN>Wm&l=Pm*pRYcDt%eXC:N5
6Zwh?Y *NBIh1^++A?:daA:<mV*m8+FRPbJwWhi^N/ZD#ARa$m$dMiPjN5yZuwi^QkwlKS@pM6tJaC=/hZhcA\c
*E!DFk jMI8>9I1XJK$#A9CVBqPIY9*PGdVbTq&R+*=Na&>q?*C@bKNi>A$D\tA?MN4SBn4tYM8dHJ@mTa1jdQQ
GC8n\? KaeNNIwYnjNI#<BHmET=FaFmyXeYZn%$8=jbl8B5aGHl=PmIk#P9AANMwC^K1I&KIuVMjneV4uA=/tTD
k4k#1d PN/&P1QC^^^R!ttdl%&neCwXn6L66BcY$/ABl4AD59RQl!Jp/Vq<XS=q\qnnV+J!ym/AeSkuZu?#4S*t
DIuJ@: @YeEqN>nwnP=Rne4diGd6!thN%KaXCNy$\pmV@GRbY%Cj@bnwTVu&A$h=eEN>PPbwykwVFFG6Ihq/aa/
wkI48G !l^L!My*WQuJ%+AEa:qF#GtjIniVDNZ\9bbSG8EYa#l/yeuwVa&yhD>9Ju81^Rh:d1T4pWwcI\TA>KMN
$GnT^: ^kH^Z<>jh>heT=Zh<\Y\*1#5Ckj9KMdMjppQj@JDmYn=69jmqd@Ni=q*bcj5FWNjy^CSQ@K:Qm5?j9*y
%deQ%D Dt+Vj:K#^4+Xul\%\RHP1L:5P?ZCB=BVJ+kq5ka#TwD/SYRT=D&KMVlTYKAjM+B&Nmt/SI*Epae?=Fjj
dVKkcJ F?XL8/JVHYPZp%&twp^F<kenRwBE<5=wew\KkJABwZGFcYMnn@*\WbeI#%e=TA4edL+F&HmtAmal/Pwq
HYQ?y1 KE?LBlMM^MaCpGMeQI#<jyj?ykwan*\uHuCT<Y&ESwaKtMYS9ljR>tIRDBl%TpVeX?jkaWPWZBk+TR!\
Fk+D/< EiEJkRNCNRqdlGMRPIcD#6enn&CemqTZjCAEtGCa5pq=WB4GyuZ:5+G&?ca&FBAGBC\^mbGG>?5#A@6J
bjV4aJ B#1tn8Tb+Ty58CWG5icEAWMGH#AMJ*$9M?R!6l<A%!dj9F<1hu9a@T5djk&CaGb^Hy<tdkVA=&GPN%mu
MM!8E4 \cpAMe1!Y4a!u&tKuE>dZRDEE4A$tbw<tTn1BnNin=n@Di&BIuCnql=H:T&CIXBYI+#!GQR9JPP<Vd8=
LM5T&% SwauBPHTCSB8lAeZBMQG$Cl*S9@XaA!GKTwhBk<ntI$uEGNPBW\!>M<BEATMnt/WAc*EV91EmDtk5l8p
BNjZMj LA!GI&HAZ<VAaTREEdTA?%V>DM#>=E%\D=K5Swcwq$#N<5pD+\!PdbDTC?DAA?ab*PeVFbp!FCC4pbbk
a+1+pw up:bnaW@MbwkCcH5^4d=kut$LcP$t!G4tGZYhMbnpEt<mN+SVp*X&G+Mkt&F\%8dPKpm&Cuaw/qie^K+
NRe!c5 5^5qELRJ<%D:embYk:IX/ZEb#BPH>IEhQHNG9EEY*NWI:nMV=ntQaMRwyP$8W%9AhcNjHNR+b1y&CmA%
c*yDM! /aA!@&uEw$R^wncEEDL9SlR:4P$BuZb6K1KRL/8JKF8HmLCWcGNSMMwNtImEWk@^pK+FI%<IdXA#<N$W
Hq!idZ D1ynH6AWPAMn=*bFwqlE#5/by:qF5/h+A$%Qcy9EnM&ab+L=1F6p&ttE<i9m&d:MI<ebdeYmW?9I6qe5
Z\M9BP l!#C=?RCj@A+tDTG?lyK\4RJ@kwh=Rb4hWqF<wwFPaXTmZ\8B/Hc\tkJM5Bnc\#6#JC!LTZIX<c:HwRd
ebVm*T jD>+ApndXtBNGbJ6G\L>d>FS>&H9HuME1:AA?4QK/KHGWA/Ct$V:nTS#mbDTLIu#VpYuQPlGD6FeGGZb
$e&tn\ =M$!HubnX#yqDJZZbEdbHyWnC?jGAW#aI^XlRbN6T1w<D=i\pqAJw+tcw#lVJI&1:W^aI!Haa#5#J5Fj
^EdTae 5Ca^$&@<WymnbWFIS?PtCbVje!9dRk\/XWI<PACVJANVuPh6N<6GARP8*MJuh@GY:NTK=Q6=lAQpaGM#
#jnA1D WJ8iX9pkHaE1=#uj#XJCy1n**BL/h@FAJY4cAWkEiZ<>LdWb<L^dMd1QIX9^Mi<1+&\nIA$:NEDDXGb:
E@hqIq 9l>JSD9C/Ln%*ZV!C+cM1W!BqA<NuDXlhG^dTeIBNq!b!9++<BX#$4#T:iAVWM=kK89Ik!5JB5c#miwV
kbkV:t P=w\qRFmei$eqL^mb>G<iKD&1Stch\b<q+M?lH/lVMaRh*CEQYIJw1Yq%VK>m=caDYZE%WH*WR!#nW\6
Jmdqqj k/GqZ=kuG&MDG%k#+u<aJHKHjGAMye?VKGQ$/49+yM4wPJFMM$#9iNP$w$RAq<W<aQ:cA$WXJG=#HAde
DFFnC< >GRipD@%+DpRN+Y$yFmaHjF5EBI8E6MyS>tPhXNk/nkB<FX9ZbnnL5>A$W>ICADSKnRdAhTL59<E=!kq
deS#q> bAMewlBCm\tF#NuhQAAEC\pKi9ERBWhI<NpCNq:!d&:4=u!&&qIB>pjV+%#wqN5wDJlJ?yhNNC5JEYS/
+PIANV yZCckZTtW8cH@Gm&1AZYAY$Ckn*\^l+NHpP\bJtE$cjPFwM1y>L$w&n/1:\pwn<:<dBGceBk?pN@QPj$
ITw4q? $%Qk\%n^YNwND64LyT\<WMPDudDjpuXnn&lnD4m$R45^:&j?tD+V/44E:hy=L/AdGQBT\lnN/@>yIDAe
e+6TeY bC6FF=BQESSPw>F>LZCb<yMWItkb?TXeJmljMylBPZmb!TKeJelCMKTdPEnKK9m#ThBuw^Ay==B<^>B8
y<=/Ga 5?B\@^ALl?BY<dB88#AL*@Dq+LD\t?F*+<LDNTP/:$b<nk4@:Bt^>DRmQPaGA<F%l1d4*XZZq*N9jH=\
Q5$!V4 Qd\m\tLkS4:BnjAuBcYNmPZ&Y%JDpiXEMEhH15?h%@Mj*$!=Rd5SSCe5i56mJGV=Tk=A!A=I58BaI<&J
J&c+6u menjCi8jbMpn8WtS!LVSG8Y$Bnyd^!@*SeB=cHPnwt9u!BB!&5+BWIV%%@DAY</t4FGQTDq/cDeCTNMK
CLNVkY d>R*En6!5hQWInBITtqRhIG6LEcjE4EuDjCk:a?h8NJRkBjaDtEbEah*i8KqMN\^R<^>BP8*QYplmN8+
a#AkRQ :RJAYX1TSak5AM/&9W4hj<hJGyWW6Wc=Ec>FWMN?qZ<:?n6l/4mWpDq=k*Cp1#RSaJlKy$m$hJK?^V$6
q$Teka klG%1e&?QMP%mTLG=%I^B4I+HnP:/9L&#%$nwRpN*=JCGF/nApkMqFAiHCd\XXMw=/8:#BYhE1SEXC1W
DmVqWj !qNtttwlJmq#N:QXGttX+\54y/q^\XdhK^mK/FIeIRW1FdPwD%9^#+q=R=F&apHkRVP&RHXXuwe4IWq8
F>!1Wp AYN$nRBllM4diT54au<5l*l9PBl=VihuHtKJ858YMM16kYB%iHkcTEBmjjWh*V@Jn4Ey+G\nSPS#Je!Y
Shh?$5 wP$\B!$RZGi/M=ayKmHl$cw5@miyL$=uw=GB@AS9hbJ*jd!BAMXAywGE/+KP:pXGj\ZC*S1H?+nKID8!
uni9Xy #BZM:N5HaZwaGAmRwlFiTVyASF@aKK\<Te!5ZKLq@pBjEj#C\&SkBeK+tP&E#B+RNASS$54W*:JY1i*X
eVLBqB iKi<Bc!myeY=\%anPRHHbQNlP1WV:=uV1yQF1/hD1AFwe#kjQeG4C5J!6u=V1nn!*a&5/86nJe&KXQmS
1J5jm@ 4EyC\Kadni^8*laSY^TP<PyMIY1F$jFXW=F*$*RI#BE&=JyDPuBWEG+K:Ghuw1R%*?!m?j4%6t#/^hj5
wLFq4\ bAAl#hEV1*+p=RqJdLRjt#IIQEJPVwD<jFNpXLcuaFMR!L%B:Wlm@/kbATemDhM%HNmlpnN45M=1Te4w
8ASV1< h15H\AZaP&S!!qF?!p98!5:!n$ENN@F^n5EqGp6RSE/b%ARW#9$auEp?wNji&>:WwE*b@!VdbbXk\KyG
>1JBk9 ?meCQ<qWP8c5hpaHiN#KM6Vm4W&@$R6#P&ElTHBb:wJ9LqGt5d5yM%Le=C^l8hZPWq:%B:WAR9+p=MR=
!/*iIy d=>6kcGAcna\plp@MZDV9JjFP4/juS4<uSA?ei&GcbQ!BP\tLcB1ldC*5Q9^<Ci<ZG%XF\!A9%@<p##K
GwpSX> pl=?#YF$tJmpjbVq/BNilaVZu5A^\e=!FIARWS=wN%D9A@d:kQyNYjDQtG<iX64T^&$<1>lhIPq@w4uy
Rwk=CK :/jdAWXaKk<<E?dSJ6pJaX>??WL8>qAbcqB>ac>$u:WMN%wjT$VRS/Te!qk!d4$^w>#9%99+\dTwJSF?
\a$PCy tBER+^GjCRQ$5tKM**@aa<Z^9TT&B<Ch4qEK#*!u:TnXJh:5B<Eh?>*waaAJVd*hFA%#\q#BwSKc#yK8
<@98TV ^IF!TyH?X*FmXQ%<>JX5^X>5DWwX:5l9#u?$yMIQk8V!9DE\M9!6pZ6YnhGLR*W!R+eSkD<m/GL@8nlh
t<X4S5 iu:X1y=PP%<tRPn>1/<XA$#uT#i>DACVMJ#@%L6Ea5eT%w$9mXc^kt^Q<6kGZQ5u\b9p:P=i8tY5bB5/
TZ!SEn #%RWAS9$4B5iyJ6:Q:i$AjAX51lybnmM<+?IKGPu*YTqDMbneEAjV\F&ZA>SKX9@P<e*:!SZ+?FWA^wp
FR%Cn? AIpann??GSKBeHQcDVG1uWamApaankNGRD^BCKaMNwemyuZkd?mua+p&:+*%E>J/Y^Jjh*FWbmXFcEAB
R:u%j+ @nPe>kTALutAPhMdu8mj8yH*#t#/cSp\niV>p&R*/lGP%*LllG!45R49&CkBGDIP:mbCcEaFM*EpP^#*
NJF85> yZRLBqXkBR/EiMDuICFa\B?HR:JL1kF!SL<j1*9K+d8cZdA8&?m$@AM\N$CHXEqIkaC6XIYI>FWi\9+?
-AWTM! 0007395c64d00110333 Page 57 of binaries1.zip
8!WFqp AEC:NulB5FyQ<RAD:#jRW!ECu<ScE4#L=mBqLE/H+<ZKB<HWeQE#BcjeDWXY^#j5t&Q$tqct#8NQ6k!b
%PkF*W ypTAA?w=#yE$J8aA\N6wRuJK4&kwRn&dW=9mRRRAAKNpy8iPA1eB4mkcdc$\P8tPVPXdXP9qaEJE?Q1w
y*Yd5T LqEbuA:lSW*%J5MSAPIA<Eh^aAAAeuw1pylBS<wiF*w&pL5cABSk1\lDlTt4JSKqcnDB+\h$S&NRVB!Q
A9k/Na IWMdFc%<Lu$ytwNXtS=<cnM%AJJqnT?$hPMP+cLKdwYXdZhwa<H8l5/FGtwEJ1Y:Vt&ddd/TqZQia6G4
P&%AFC Y$V<CGNBE?8n?EpCRMeGF9ND+HukI&X4\RAAG$hKpAa*PcbX:a6Z^!6eca%eV<?\!XI@9DK\aQIcNl1+
MW<Z\w &KPcXbLKBSZG*Ekp+4\jJBw>$y>8R\KmKS%Rcb5RCuhlm/b%TZC=l1n4<C5hpKae%k18PKpMM^#e<F4i
YIN:Xc PlXlGDhS:?yXV5C#*Le1%mjRdE@t98*/AEM5RdiTdLy:4k<I4F#*c+<9b>^SqYZ/^pST!Ed5Vui4*CCt
%!&ky^ =EWK^^ePTP1A6Qq/GW>mQJDYh#9@n*P@FTTAIiBtMhGR<C5Q>6:MwRTwGppbl\kd^>h$RP!B?LnEQchG
8<5IWd A$kQDtJ?RJP^8iSSCViphItBR&bb<n:mPV!/8FKn++GDK%>DM*EpVC!^H:?4JIJ*qHuplRER^eAtNhXX
#YHuaP >b1#E4ZwZB!H@5iG8!#JFFE$ZAmyIRCJ6GcVS1R6wk^D+lePm5hn>SVK/%/mTpe\tSJ+hbq4LQe>eGJT
PdHX^/ TnE!w>Tn8/yC1Cl\%JI<:hcp*$eE9MM&NN56<SFLZLBNpRRhpeS*nEKF4IwmYY^BQR6?n&#XS>j\mTKA
HK<bt< NTaG@LH^QC%NYq@CtFp\YdKHFSKZFWkjB##61diL#/FcX*q6>PkG8eaPM!Q%RwLqhNDwij$E?h4k=n4L
w+AWw4 GJ@Y#YDwR511wJuZ9y?dRupm#MkRI$6H9/TSVmy95TV<Kh:mWn$1$e1DD*cyQmSVjpucieBM1hAJ@/ZM
c%4RnE eb15Idk&YQiAyh\DT^X5cPD#PM^q<jE16m!P*TbaTV1IXZ%:#GyhdtVCT!9/cW@hpy1nFh9hSMi9ajiT
/PLh/h bQwNpWLJ1&:*E=\K\\RE:pECCKYhb=<TpSp?ElpLh5X1YHXwjIq?H9dlWdX9mecZJjya><j$I^Re#CI&
JyY%YC qVPhQ!5EuQl\p$Jb<RHKDpRk^tc/nBkum9m6G*8*tk?@\i^cZY\FaJ4HD@$Ywn?WDK%PC%X%1+Z8%i4:
?%EFBq Q&J#jC5A\Mt6k@yKZ@<ehjP$FTp>THh/Jju\ui<MwSPbM*bTJt<mEad^eH4<hBZA&nj!EQHp#aG1+XQa
NZE9dm 1Fb??dnE<#IF?%GZJMB#ywZGB+4!c9RDBIcBW^C?b*tJV1>YWMAjyXWlt?aEKKqRkEw6ajl+Ikl$tun6
&pW!=c Y86u!1ETW<kJ$8k?MAdB5T=FSXC!tATBM\^#WXJJ%i<PBd\GS@Xn<>9kJEQBIp!IWyt+\HjANat*l5w?
%%MH6Z ^RTdw>H=apLKSI!cD=!89w%bCqEN4%DLdyE!M+mX*?/ZyuumSAbkwb\&W:acyb^6ibtAqaLCI:An/D!4
\jj4R$ @16iGI=XE^\V4RE/aWRRq9n&iImyANXe+IQpMqqS:B4ntGu\mi$nAIPI#HlAH</FpX4M5J+q<SW^:iuA
JXbQI8 T#\pwIc%DE#kIm*XnEP1cHKp**yStMYT8KhC=LTZMW^4<=B9\5Ky>RNX4DR#ITE#P>MJnANASD:pTRSR
F6=Cu< Z^ACAJwa1TtFkaPyIRF16FLbdcVEMWi?CE!&IaCKk>?Tqh6R8heDAJm=laeWYY@ChQDEn:tG69aMa%iA
ew@Gwh 5hG5n+!i%AGALa*$!u8Q!pnRXQQpACLJKVEAkMuTh$8km?NIBXmmC^CtDc1PlyG+4a$VujlE^?i\clAI
>d+LXA *XibI$XtWVcCkWkJT54>QpKANwu/@4H1>I!E=BmlG1CVu!$6PYY+V45ND+DbDlJMkHHc%!Daa>8b!/SE
$H#^hl Wud5MQMik:+lY<yKIkBPKJZl\5m5c%pLaJpV!RARBh<Q<mhd*CSDETL64\HCFed=?t^heNXWj:Dkjn$H
JJy?qp EbDTKFueWLt5qa^<KQMiVJpDWZ9*GYL\ZnPJGK$YMKIL$S!u4M>B#n@!\dc/*@E8/GVnGwnyGkISRM<b
K&^ut\ RA+q5LTkJA^+AZGh9ML$e%QT$<cuS:YpnWce!\J:SlaNmX+tuT/!i$4HEtw@pS$qX/a>LZjBW^FL>kiW
Wt/Xc: l*Pl1EGuaIaS&y=CYy>&VC5>Z/YYNpC<<\c5BY1tdL*5TWl8R!R%wRdwu>S@h/IByY!D<\uhbS4+qCt?
$4!b4/ <bPRE?<GC15Nnn4e8/tMi<^46uiaLb/IiLl@!AdIwanHNZK=qkJa6:M/!Q9dR6W&6t5d5aAPPmKPAd=d
S+i?&w RCI%EDVJZtI5aJnBp>TqpdIQQen<WKmWmC*PGi/TIB@SAn+BJq/CbV=i9BbRWjMB:+wKJ%k?#$@D^WI&
w9iQ8< ATK9QM:JNwkwkF1WAGWALGh@DShH<=%b:VbF\IC66M8iQBJnTR#haNKuNPIkZZ#NukXkShVeyLRtLlA$
qQ?b%X <au\$TRIc@4npaZM+%Y49DL4BGGV+lkZw+dIpm$wIeCNmHCFVC%#ptH\6SQ=ltWRIAAD%yJEI#R\EnB=
wq/eFZ I#66tjj$J=DR@TV4TAJyD<CA8Y=5HMkER/14WMGqD#NbqR%k5SA5bcYPK:mNHwB9G!NM9>h><El:l\NR
uBP>jQ JdTq>8Bw\SIePF:4DR@1AA:l+m5yhcEdlnRaSd4#=^>wNd>+kw#W>QyjdJDlmGS18XXc^\QiGR4%EME\
pXqm5H ?uYp@RV5jp*Kanq*AFE8SEyZ+$?nP#@GaR%JwWAiXdJh4cel&wCe@S/B1JJ^P6\y=ZI!^GZ%jiFIQ<Dj
6C&q6V V&C<Q*XQ\RMQkD9W46uhW=+y+P</t>JL6E??4aJ$\Z4/d:RwKn!/WJjKu9NS!WENu6Sj\/w58R@$EH8G
ChBKTw &N$Ld+Y\P1p@VbullNGGGV@&iF\GaMHTKV5@ptRbJ\MHpJP\pH!9hwELQk#pEZ&pG%YKJTm8^/\6p%&H
BKSMP$ /l\HZKa!p4SAE4uIWn9wmiY\N=*Y>X*LAbC*+tY%AQA:$=nHW8tFlcZFqHh5&@4jlSD4%%MF:CPA/q*^
eT$F?S h/lVG4:yiZ<uCdd9^LI<d:>!:Y<JM@&SY\8M4&eLX#DYN/bTMP4^$*q*q8W%d@Lt6a4I^^*X@9aMpnha
VEAKk> 96j8RJ:X?#N:K1M/$k\Y5>?a<XQ?X9&H=>q%K/&dIR9QHGwE*#=q?D:+=MQkR*G&kE^AiPep$l@:YSJk
bw\m?K W?n>1/+&8q#<caQEZSmV$VNykd:EGMZCD5u#R\B\?NuN+=VH9?:%end*LIDp#lX9Z8AB#EwSwe<<%u6n
<<5Bnc we>mkWy*!>5M1\cMnJZtq@w>R65J!jyy*tZ5EPKJkIXBYpyqAI\nT\KGQGdDRV+ml95GkTmeGGBhQlAS
cCYikk K*B>98CCHCSn><!TH4M@CNT1iCbQSjmE84c&+8q*AXyKA5=9Z+B1<Pwh^w#6H!yYD?m+YNKWMRM#wRM:
\wmKQw %?k+u/m/kAwDkD\AQV=InB^EwC9mIP/5NR@^=B:8M8$SL59:W##JXp4KT*uKT:\+CllJ*aC6!JcZwAwP
*d%=WB T?VnW54iq?&JXSltj6wT$=<1R%m4%jPXdKk%k/lABNSmR#lBZDh\RakSTkkP\JV8DnKGJlRpAE#%<YTe
l%c+@k HLL\SDG$i5wK^BT1>tkLAKAaj6TcX>cRcE86DmTCYIwPCCcRT65wbYyAa8cXDRYTm8@Tyi4peyLmISIT
VddKDn piDHewd1BbinjMZ^mRqTlT\^58Pk*uF%8XTtkM?J1kIRnIRMGie#SqX+S^Ti\GQaR+w/E!BXwlEucAkI
\yGDwY Eaj\WW1t?w&IbiFJI6RBAtX\h/aTP9XaNQ1JZFSyDMH4Tw!HWk84dL+apELu<EHde/wi/5RAC4YnSBn#
P4Ba\e l+#Nh^A?RWKtMu#K^\\QyjEIq5iymaD9&CE^>>RVQZt!V*p:96kYmRH?c$TS>e4Jm=IRXWWm:\15d<d&
\yInLi ==n9/qA5^cNJ<HNLjjqlN9CkFl:auiHBSVw8Rcn<VXH5<nqEZ=65CK1VutD>NVcC88w1Nkwi<8lFhRKn
KY9+!^ KZFAePh*D\mj6MVNV#YWacKHu@1^VRt54jI$89l9@l1Q4pDM>mBy$A6dCYIMm5CT4>LDQX/*pIWSNJE/
@dn%!\ BADwEi9/^ScEAKS6+5tya+K*PM5L5uy<?K=mkCw<1y+5DYIWlM#XW^99AH?eKElc+@cNwnm?E@a<nSF#
XpKC$N EnJmma?>%aKnlF>*^WPaNR5jESWISc<+MAHeE:Al^bqBCTF6nBHb8W??/Z$dIA/+HwP#I^\Q^F?B8F+Q
@MJC5B EFT8+\Gwl=p8eT6<5bbc9a+bwBbX$IpN$h^VkN\%%k$y%Q5+QETSTe$948X/*Ap>GEIAY5FIYV$AS&Cu
\D\MHF w<q1bF4nX<KIInSE?cL^LWwF6i:^maLA4e<ChWSSjKlCD!QCHpnMIEMbZQpqZ&lM\ESW1RiF$^$cR$D$
5^H/G1 FL$+HAMtj<kWwEaWkTc<WmS5MeEu5lXum8JXa$q\k8AAG:\lBJ>/IIP>nJZkc!Cmm8LHF#PmBClna#hM
6HpBA5 lW5T+%j%mlt=yF6mwuyM1b&FmX\PFjAP^FknRI6wjIA^HqXIFSBG^Icw^EwaZ?<kVL\?G4EAcqGeIdEm
!h@Z!8 au\kP6kMGAhl4Vun?!j\j^!T?AhlnC\D##P+^EBWn%VEe^#nTdq1cm<:Y#ym^Dtci=\IbF:kKXX=itIB
A&&Hy6 $pSA^/jS4IEm!Z=e6XwJ^hqJLTDC^&$bHpGnBJC5d$=WQTGnyXpJPE4CyGDR$W?yhtaIqln$&L9ylI#W
%:>QM# I\HWR1EpFlTD!aSmdGJ9@lR?$RBIw&qZ*BMF4QwKiXJQ:QT?LT>8HC+>:!Bm?yC*1<t/ARRaPnFi!Kyb
89T*/& ^5chBLH&qKSE&>HQ?WTXQ$:dEH:pNG$yhlCdCM1Z+E9daMp9a:p:*kEWa!q@#+IQ/5aD&JK$HlBJuCbm
k%k=l/ lH16HtCGu\C^Rm8G<1RTT%G+8#Fm=JwqV1VbD@ZYW>M>$+6>\MTYKaq!c!!M<kJQqReVa@EZAW\ldyBE
hQ#TT= tZwbbiB?dhwG+J=a/I8Nhj!=QY$4j@%55G#LXy^MJ5YGXkJ*yjF8$wLZiw^nSe!QRP&h!j#*D$CWJy*>
bdC9Ph EptYhYci^6E4IMc/6kp1CI8<BiNyY/Le/DQd#NjeqZp>Ht1qmRwpDMyBcSCl?:1$S#K%Q+E@XA6b46Fl
n?/FbN *\EWSwu6u1=manRM6hwA5VGF4ep^hJ$D4WR8%WDyA\A$X#XVTq$*hS&:%:5kq?G:DCB!:F>@bTWhP??w
=EMpn# 4I@JbHJWF4*=A1IT#mDHKnK$p&By9:+BwE9<TcVYDXJk#Gjd\=NZ&%8Sn&=e%lT>l<TD%Hwp$mGnd!XC
N\hiN? MEaR/Y1!%+aAdT+Jt:lZee16pw:PS5ALyJb+Z@>Q$Hwj&bP*GX8Wh%q+KZdZE!*yCmaB>l:AaydZXIDA
X*5X+B 9KjcQBnkPqMJ4nSG4WNulQa\e&4dDuebD+<BpBWN?@!$K\y?\lbIAn#J<BF@$S@d=SFc8j<PJP8V1T!?
ct5c#5 pClRu:niQT+\QQY4CEhB%cQXH>GiWMl!:$AYV!T+hh*KjmMM%^QcXVJJtYT$$c5@qyL=#E:a\TPY9@<!
58a/GY ilQK%541QBN4tmm^*FJFnFBtu^1T59FNTT:ICnJ?+@5=\h/RCpBE>ZT>YnZi?RkGESQiIh?^Th!<H<6e
e=Z8y$ GQE+u8PE:WtSA!NA^9X6F5&HKKe:Dm$^Mpqy/RGc6DT!&RZA+cTZ$FjbYWHSd@#AV!Qch%<bD:NDAGC8
-ARqw^ 0005171287b00110333 Page 58 of binaries1.zip
PCa>P! 98eV#u$Y9eK9Em$lQXQuSQj5uHaYE8^hZiD^SkCJQdFMtWtcXp5A1M>kFFepVcBMiHY*B@5nK\CwEbEM
1ceK*C W4miFX1>HaXVJXtkVDVK&AmcjD1JB=m/pKbPnGI&dpepqXKwCT?BXwkIZ6&jcbF+41XMXPCpcuecG%JN
M=d:5l YL<P5\Vkk^/Cw:tcGYWtZ%Y/:!eC^c+Z:h\qy*!E1u8KS=hADINWE=*$jZDSHSpJqt+Pe!%!Jb*9<!AE
%G>1#Q SF8:%%X$L&$yjL@8%5bH9SKN8ZID@HE/DyCJ+lQFn=5CDKqB$udFHm=SSIwiF&@YGRXY?Ld\ELRTPwcX
B$8@RM ElC>>uJbQw45cRehZGAFN?lJJADY#W@Ecy4X5WRu:&!=9Pu:$l14@5ju5I*l+&XHdF9MQedBWmum\E$8
\A\=61 N>=+QPJX%pB$n!q=dZRC:9w\u$R5&y8#JjBqBAGI^cEEDwn1WT4PDPjC4qpl81Le^tX/yGI^jLFmVyTM
uhtF$@ LQGJ&K!#>XnLwDk?*<qc$iPN+GP#MwCqBqDn9RpGBDDW=<Z4EY8eE1=k<RGBH?MR>dYAkn<mX#wpHl5T
1jkVFc :#RPBRV9:wqM>nSFn%@1^uhR>hkS46kaT1IIdPybN%l1>B&TKGu\R>c$qD+YERtA@mCewWD<8na4ZDMY
H<wkec EE/++6FP8aR*%F#?\u5<Vl:IJ@k^khG1y!iBy#wQAEt>RjTe6y6XMZqyj#QKDk4Ek\lY1KERTBTm4\eR
D\T^WB 4wLSDPK<VcAR!eyHM%>Aq$atI#5dVKmm!58wV^^$t$GM!Km=JjQL6Z&V=TCA+KIQ5YJZhb:hq9e#/ZNi
K4V1m\ tZhwnjN<&WRem9XXaJC^Y>\bL^$<yHGW@LSQc>8Ipu$6ZwNC:4^dN5Sj*u*c?TI9SZdpTeaGdt5tpTlq
1n#>TL JtN*RjX>R/8\NARn!QVbIISZ$/XbhP?#&TeL<+5H%\di=@QQdPKVSadYPi@iJmw+G/ZE/#N>/kuI%:^p
>CbVm# MQ%$P@=Te8<VJ6/y@/jHju6=l<Z+HbPpK&DL*tM!&SEPJa>LC1iRGw8\n$/Zt6nRQ@mF?&uSpqk<H^aP
%8\!MI !RPpTK$Fpnht*Rq*<A6N8HGybP9#LQICq@C&RKBAm*^m88E!M<?e+V4qC!eKD/HQD:CZ9?I@h<h>9ydk
!DbTBh uKB9GQm\$np@^C4l$<uqGud9daFEnEFm&PiE#&P*46!#I<ajuAP$ateBtP?/Z6eMM1<pFAj8tK*EAk%5
TZ&>J& bQP#\wt#L\$T9&kYZ4?Kbi6<VRu!!QCS@EIhYw#B!GGmw!\JYJlTVyiV44>48Q+=<Q1%t?q\japI>!P^
mNyCq> Sn^J\F5qqwl4JTAlN6A1B$Sc&nGt>9B6?^iq=l5MVhe@=q\!^6+MdCZYq!$yJYhYwkn<nIZ5a\m9lPI/
aLKJEA HRkANnHdakBIaC\GR!\6%RN^mP!59ju\!Xjm*y9=W%>:Zj\4aCE\!adPdDcqty9>mX1%Vj1@Hu*@NS*&
c1*Nky h9uG!!tuK#Ra^^eQy/+EEBQ&iFT6^AJP?I=H*@&aeReHmQb$*:y^:jH*q#h8Ji#i:G/<lRZw@*mhBHuy
4Y6CwW GL:*I@@>><?9jwa9@!L?iQ96l>5jn&?<Qjpq6Sj=<j\Z\>p9*55:B8@9*Qq$K?Q#Hai96^NY:+#h9hQ>
Qp^*AG >SeiAAERkkkB@S5#YHpaGWt5KmJkH$h+nTSywL#XI>Yinmq^8CL41nJMpn%ViThIm#^QZCD6BcKXJHbW
a&QVaV n!Njb!@aTn+>YDJHd<@+$ji8GQRDI+<Fjn&iZE#XHN?F616GqYGNthj</m&uG88G/j%R:h*wy*4NW+KZ
Hu\p!? LG^85&=6qp%=ha6>*h+q69Yj6Z>W9\95ji59=R*ciu*n<X9S#$j5lEQSnb6m$n:/uC#Ja$=uVQK=@wLF
jmBb@8 E?:BcN5jn%XVy>^d9pctX+nZ#?&jjX%*m*E8j@WidZ%9>GF\!@1H##a@*kF9DY\FZL*Y?<kbN:F%L9*N
*b@tB$ L%!#dH:=@P6VpYjG%%<hl*%d89$^=yu9l+kud\\wK5aCQ4*=$iN\Y&p::<5:!dh&W4\9D5/@KV$M@utF
at:Fa4 Ee$Bj<W<dQi/iQb!l\p$MEQEAqE?wiWpXRukEmSZPWFJ\FRDXD?BXI^alcqXnXAK6Gw\t<<W#<Sh%KqH
ANtK/T niVhcWhdda4yS+\mk^qH5:::\nXl:Tjj?p>*pnnHb+:mn:A68k<wJ<Snc>ku&uRL8p9@6CSA+n<V&G*k
=a!Q<B WFE6Q^jZmD??WWVXZMM<uX&NNXZkTEqJPQw@59&lh9<NJ9Y94RtR$tLI@>e$qT:@Q/?y>N$/R&6myLI?
1k/5#m ER@#II&LYLQc9#iXll8#^JELF5&PDCS/$JIHbi<^G&!X:5mPtb#LmFX9Ie&AFjymulKe/S^kq4:y?pJI
PiSP5l @H!pyIRcQ<$:tiH#YlQCq=L!Q\9$L+CwET%!=w<YD#i^\c\LS:9kkbaP$?kne:NJ$?j1ndRuM596X/8V
e4P5:+ L+G8bp+4F*V+caX5uI%TithuwNi1ekWa*bVNeeZ+pm1$&D%8V6Yic?FwhihT<m#:4iN!*1$:@mAGkQXL
$8$pwk dWiXK@1%V6>:/1B<W&<8nd\yj:XX?9cY*ku#Bu+jG/QFS#iZLC1>@XwCP+tbwcG!d+NBNECjlm4@DlHY
HLu4YZ +YnPCWa\!aKPLFV!?\w6dDL%NMN<G#h@J%/=+/i+MNY\uWKL5MC5#T^=mqVF$/^KM&a9kme@S#qZR8X5
eGuT&T @*nRu1$FQ!K!:\TJX#A%6#9*GQj8Vh%idH:J@HXt8T&jP@uSpeSWXZGL:KHDjRe=?&Mt4\G%hQw^55FQ
?mkDcM NRF!J$al+$cDL=ZnkK:*:BdZ\8t!P<:TZuME=8mkF@eqS>8X9YZqHG+y*6nh6F:>kd/@/4JlYE9u?wuh
=iLm%/ *Vm>aQH85kP%Eu**C:JdF$eG\D8\yViK\6=^!>K:J8y&Z@1EBcC>5RuhL:jJlBmd95i$LCi?wp&eeL#!
MNA&59 PPXPSh8D*HeKlMHLu#>H8HYuj?FJRpl?=VlknduyyZJeGQ>pa?@:A?aFVWlhl#R1jumheNGdXHn%ebk>
>yALu^ PTuua/F1=SMlW+>%M:!+TN*:^%!lDTR$A%FG!uHZXhAl?\kcF?@TVb6H$p=5nl=<WZE\S1X#Dy6JkakE
$Nmq=^ u5c!9JMqJ6YJb?ID5W@+16MNb\i*NdJA*5w#L$n9jw&YQJTSX<Q+WlaZ/S4y8C#J8mEaXRX?^YI*^NXD
$9Jy\j :+?q58kbBC4wCqdaJ/jhENHIwm\nnH>LX?=%J?twVWK%k1Ny1#RASqW=HyP+<9\8LV&Bi5nD:FyWe!p4
XQ$aw4 8jtHKJ5uIRFnbWqBu9F1A#$SFy!&E!$m4u%IIZZLbX5h=$n5RJnpR11De1N:dlAn@jN&VmH4\^lm5wYP
dH+dy: llNj*q&%eyi&VXb66&aHi<+^atG:*Wtb/^^pL<LBEwD8CWmp:XTE<%$V+ic<K<yWtwXiD&Ftl?mEJh56
pquu@m YkNNMELy+RW?be<#!<#*Q5GVAJ?tyi^##&C9t!</dC9a&u8!QSIbkcFaK+69F^J%J?QVhJX8c:*hIRuD
5THGSa n^XnV\XN96HjlW&NwalJ**y!NqYMWphN8F#H9Fi>p:t:!q9$/ddd5l/Ed&R!/>4kIB%VELMyNw8G*8\X
\YVdeT 5WN4MTtbB&j?nJH^+lPIbCPd<5Ra$WkqJd>jE5Ktu/j!*d86YHjTi#bX*RJ%i%^56mHQejjmW9T!Xi/+
HeYHiS CJR^MH@8T?N@/8BhDYXRCt*MFG^!6<\RhkJVL!%bE>\Y$cH8d!?+nuNR>+PFkSLutLjTjGTKwbjt14JF
#/<WXS HWMN\decJH&F=q/AG<#i^=B:9Bw$WRW^HRct%8lYjlwl9G:w+ZR*??N^a/*5lIPYXpu8k6pKw!S%m:6k
VQTQqw iDLjW*9\P<NV?uu*J8#S5?=Z*WFFC!b8+%5!!nN#LGupG?c:y?^Tqti#b1GA\8RDYH/TS6@1Dy8>B1#p
>upLlL 5TppKtqVWWa4y@F6^%\w=EyT$d*kKNhpIwHT?y4C<@+5IIeT>/BKVdJ*uGJN>Cu9TT>i*V\H6h1y@&mB
quYb85 PY=IAMF9GB%R<ZEm!*nEXd6Pe4\ci+Wm=maR1661M$1:!HGn6m:QB*KpMWSIib4ky/bq=yYb=+pdk1NN
wSLj:D Z@T:QVlVbI<Q9S>lATTtI49^LNeRhq&$<KX5Li*V=>AqS@FZSwI9Zb>Jk96e6SijmSCwjp8c:<yA8=l9
&pN%Xc yw4HpBXIM:*/QPQ>d6P@QSlD/>:ipnK=#ue9i%DkiYIW&m&wVqlGt*GGNW8<=wZhk^9Wh<!Y^4K1J:jC
>M#PmT 5nZmDMeqMy\YuG^IRBE9+t6j8ah/yI>*hBbhXT=Dd&/B1<pFbK:CSS5Gc$TcqBuXE^Z1P$6M5X<Xcde9
\:>bTj KRCj5K=8+:NL*FYD:!pY/4!!mX*1b/c/1K1YFp>88S@e!&q&1l/N!/4\ZPM$$S$T&LCa4dBWu^kLMkyc
qELiKd ZMTZE*q*a?/@^Wl1W8:J?%!H1*Dqpk>ejX1TiH19C?$h+Hhqbh+dh!k<@=a!X\mE=^wj5J>@pZA:unlB
j$wK*M ^@8XA=uKYD=XNG!w6:ci=T&X*>T%=MBQme#ZcZi8M+#k%ue!h&$j4SS?n$uSGhYe5F=KMu5!J#B/<?q$
Q&qN+& \JFwDtV&i5l6&ct:R=kbk!KqjN8aF6!H8cu9Ym*$*^4ZhDNEB/<Vjn%R&/j<S8YFqZ@dFIlt#b^j>N5V
ju*6Dh 8uc>P%%:p/#l&?*<lH5Z^1icL\=u?t\j14!d84jb/+B>u%Lb8+@#DCB4jl4qc<d1+jQ6iX:a\?*cX?4B
l*1SY6 D+V*/MJb>=+<!B^q4^l?!tYXe&?F=8m+%jJ>j1u:X$4WJ@6RNq&Ska?9*#Bi9KR+NFu^jJ>G/Q!PeYlk
ID*$^8 Z?jSYNK5Xd@aIA:H<mu\QmXVkhV*NFY&+D8pe#\we6B>!1\K/EhYb6/E&&!Mk<$9pn9jmjJYQ*nD<Buj
@Z:&l9 mb$1/HVC^uNE8VP/yHB$/9L>nQPAJh#?^Z5HEPiB*!N*%Bm*#KT%Pw=Yn=j*+D<a?ullqqc$Ck4C8j\M
kQ\yTi !im61QLI4V8&meiKJqN8e9S688^jHY<hm%#8yB@=Nbep\p1Qnlh/>B5Dp8&9XFeMaEHiyI$m4u:R@9EQ
N8udQ: Xe!a<nDicpMH=!QbeYR*aX>6:H=pQhjPpI4pi?5:i/WCeEM\@+%I*XkRIDM&4T5y&hDktA!1DmAZmTHj
\ERI^X ?pm&G*CRymEFDJFX9h$Q:QlY^TZDWTpV9c>T41nWV$8/aT49JMV4SK1\9ThhpWG^>aTaY=cIeF?/Pydd
q5eD!R tbyQHCc#FatB$%FpeWkQD64MCqKjI98nLikCycmA\@JbGkk1e@BY8Yy=KqkqFnTINb:XwZdt+w\=G?nH
eAniCc pL5kRS9b$Jy?IpAmhIiAca6cT6jcPI/dlmSI\bWHnA9kH:wcHi!4PYapL>$ul%5d1J$Ii!?5JYVjK:>/
:Ki#\Q i6lMny8+BRmR*PkBAXH:*k@bXi$l8Gk!9AtFRP#6ZVFZeREQkh8%RmHCE?\>Y9nP&y*F^8FR>i?uuPna
LNQya= %BXDhV<<:Db=+umH<Q+GcattNmZZcWlA9DF@9=@iC#@>^B*%dK=dwIA!aBCCpQBQn>#T@*<ah!ePS@>&
1lSYml ti/jnL8V?K<1\u?8+=YR?j%^h>Jm@#L8LnRwTE^D#qbCuq>JKhlZ&W@dLIRjca*WMAn=^!R*4KIN&59L
TQ=Ht? u>PPI>BA!F>JXlYJhHD^XEN\aXSR*n+tWNLAEE?5LE1RZ+QZ$JFdVX@NVh=B*lG4b1@4HtJ9J?QGLSnw
ZTVX=E yKF5/C18/^*kLauFeKw=BCwkZDE?:kI?KDM@X^MyKCtQ41miSmCHycY+5+5I9=i&IE=ZYN1RZ>5akWAa
WZZ$&S KjNwC8p=Yay/!6kkeS4/I4KcKI\JS+Cl6AiT*^Vyw84k+5INJjXGl4kKIiR%Ve!qlI#<4KYpXC^ScDM>
-A5AWJ 000dd1f52bd00110333 Page 59 of binaries1.zip
8lKDb4 dRR9u:iH8/k+VqFCk5idW$XBkXNKWVBaY=Ld^NIHJY@5+BNwJc=y:?+HJXXT+NIZq6MKX6h*SD1n9KV<
dIRFH= yPZehZq6SZ!XyW^SAtK8@n\P^kkJ^%AhQ!9JRH6#Bb!RP1ia9BAtWI\Vc?+n^teKJjZD<Sm=<jNaK1m:
@Cn=&J &RVc<a9!1*DLPWlLBQH#+XB1mwJi41aPy8amkc:e+kd&cGH@aFW>BX+idKm51K!#T=Cin$@IH&Vq>ZFX
&GpSG\ C4AXFSdEYGP%Sj<^L<*ENNAE/&SldGiw?+?yj1=cClJcZ5L8Mm/YW5b8ZmbKqqlPi$pN4WBlG*6>e!TW
XZ&h8D FC$44P?5^?6wGPSqJKR1ceely1Aww1Jndtkj/IIVFFBTeueV5?W\=?c*$<H=tp9K1hp+tjBb<64\@uGD
VG\H+X NZtqQZmlyQwwc*5$#piJ$>=R*WyQ\E?h^>uQSAE4JPll458uKi=9nDE\eHb!CyZ&NpRKGTncIW#q%TY+
dP%JF$ jGTRHDcK98L8T9yRWq<ZFS$:jlWBLVE%Zq=Qba!59Ipuq58aX>4Pt66dXF^I%kJlL?66n^I$CRqGi884
QRu/E# eTwy?&FXbdF&Cy#1Ay#?kcJRWt+QhYX*FZhNLu$lM\XLRYtW4b14nkG*6+iYydXDmKmiyLYwP=iW6^8Z
F6ZInQ 6+CS4Kt5I/<TDwZ#C6H#qNBDP9n#wZFRWuh%dqWLI*5FHw!qt/&Cn^tj1/!b5:CC4yCMuw1RyI1SNqyG
ttWju\ pW6SEG*qHCBymFI\h^i*WSXR5%HV>9ZVh:E#hVTDpq148:9+i$w4tbqJ1K8I&bq\eQyaeP5l>DuWQcT>
<+Zu+T @Y%6*KT=6GZ%@jYMlEYpjHRNhT&<PI$%nGWWVQ&CWj?a+TkNJiW!5PFY+EBLc*IHaF\qZK\h$S4ebyde
#kC>qC a8K&ZEGiiqbajWM^:XBJhSWjMTuNWCMXj\e=J%WuVa=@nH\$W5eKC/qBTVY<FhF@<MZaVkhqHcKtJ?yn
I<HpXH cK9%n@GGCEqLcZE%PYFnKhEdN&:</ak:NE45j/nRH+*/q$J@6MV9F94@S>Z%Q>X!w@/%AQ*jN9e:lj+w
9c#Eh# =G>k@/LRH!Z^>>m@K9SHwZ+D??en*>Aw!d@Hw9=1ZjS9aMZ@Am9%>%mJ9%yZ?ni\j*YjbZ+D??en@hCT
9d4A<> au?QSW4@iWNc!h@kFSL>F>nj+BWT?ieNYmX@k%h@MhIQLjpd9BKZ@k95d@BKHQ$Z&N@k%X<&kbD<DYIl
jK#RZq yXB@n9$NamHF@:\JlKVM:\V@u#iXSj<G5eSq@u^h>G<RT@\9Sktmpj@W8PI@pQ>QnT9?5\u6Q^yZTE9@
$JYpDN c?MK6MTjNKV>S#?S@/<l:j@Tl4T1y9<4G>ItcZ<tXJGRIKJWPBL#akHN*/RjdV$S=LyEWJcZpdYZtmkK
b5&>Xa hlJ+?+lLIp1>*9Vwk$ljp?bkh&T:>h4@Y@NbMnSZ%H<&u*&wZMI5wH!TZDtB*E^VIDiaBSw#1np@%tBB
yiK#>N diyS1GAHlm!qiyBmRa!cI5bjcYFqPn:4YJl$$G6JYuq6^1HVHl9X6G$QE?hiY8plZlC\&IMJnW+dZGlX
!BP6Ka Xmi^%hbL*Q<a4^^*l^iNJ1Nq%yT1:Nq?T$9/#Rq4:99<%9n!l%A8i:Ejue+dCDW*?5+$NXqccQ4m/Eye
G<S/e# Z4BX/C6/5*NH>BBMaAeYARt&Jbi?ceWWn%Iw9D5tVFhu8&LPbYbl^MlT\+t?jK$ZQ>^SCe<ZQDIMcmCN
Zq=LF^ =tTiND5@XL1*h@%8N>e:4!da?@HVG+>e$NtK>e\#y/>%%<HKn/%c%ZKE%:cH66YBdY66wWue>a@Kd%$j
wCq4+K u@q^%L:>Nj$N5*MIFIdCmX&>Tqn=Vp@JNLP%aYTDZi!jYbQ?#tKe&jYNb!B!@HM<qP+EN5$^?*1Yuw@?
NXiGm4 nQp6&c^VQyl>Ee*butELqVj#YTKL$9Fcij%%#jTB+%4j<uRuM&W6uchn#C>LmY$DB!hJiwXuhQEZidim
6ckYw1 @b+iN!>Mdcy*n5>TT?n816&M<I?EewdG?Mk=<D=>hiD4%nIQqTdVi>6=@Wly!wJ8F%b1NuV8Z%$EaM9S
h>RRYu IL8@&WkmjG5X4hL^Dmyidyt5jI!M<jLN/yY<?eFHNu/5?u9/nGiaDtd%aTLSWq4de%DDyl9Zljqu<#q^
JZ?m%N PiX5\qdVAqK+m1:lj6!&jC\<#51#&LP@nPWlZXA#MG5?A9LlTY%F@E5uH*ZL1Hl8tZNV#@9j>t*elk>L
^*bPTm NF#Jp5/8DDP#iDnte/uKVG^5A\wYBBQ5ui#JdDS>ZijWIlLZ5q=\wuqSY?L=tFDnwC9%D?6Pa*HbmWMF
k<1K@A IYpQ\R#Q5F&4^5:PN8Kd*VHPi4RFHJw&H*J@5DDel8y%&PEAXW/cM9Kj=54M%AJVZ&ulq#=V?WSF<6RJ
^RJc<^ 5ZPP1:DLM4tt#*c^FcS^:A#MY&c>=>aBub%R*WnIQL!*kT$%adt@9b%B<ET1$>Cnn&5+JRp=aeJZ+T6q
G\L4jK *ucXuD&lZiVPGy^N=PA*b@Z=^bj:jW+F\5:#wb:*?Kd:8X?#1RZH!^pEGB=dZ6#tHVNZjkKKINh4D\EH
5MX$I: 6QKL+q@LKK8X=$<T8qdXNp>dDA\p%L4hWAm^R/*epASJHG94j:p4\VAM<XDZwm5#uw=dNY+qBXVNDme6
+tZ%Fj =LujhEq<Lq^m?P1V$pC8eyk?N+^Dwm>4^@w6Y8LLe9uRnci=uPI*Qn^li5FRyqW^8P1lqYVAH!RE%Zy@
Z6t5?K T&BE1@JJ>pjKwSJhh+LNa:+\!#ZHY%Sbb>Bj<idQJh>C^NXCMT8Q1wJc1ieqdE+S:=i4qcTYX1@l?NJK
@1uNI^ Z+RMW8Y$Fy5RbdLpJV@ZNjQYW$YSdMkRe#5=Sa%4HLJFAGY@64qCWe*/cjuE&1G!9pVdHwbQTS9Q4LMc
B9h\l* !DRq\y#k%M5FQupqN&@G4?!41Qw!9X$%6na$?!GcyAR\D5/L%F86VdmbE&VFjJX&cMcLPBpK*p+d%iRy
dn=@M? *%=jj8My+8%bB:Q:5W=#W*Xt5?8^XFX^pcj>ZZdYhnT^*#95=Z5?yli9jh5W#<Vm9\TcVi*cCiY?Hj//
5nNw6J MJY=&@I$^P>cajRQ@*Y>bB6Qc@6YE%?Y>#VP=peZ4#uMAkYWP+TGInJy#ej69=HelAT:k!nm#Z!tkeIl
4GVcEb w\!1nEZekiuiu89p%X?HmMpXbHid>wPNe#Pe*JR!qmSl$y@5uJCVBiQYe>e$A:KeJFhku/HJcd$S*?lh
IT^N*& up^<=mlKCV!:RDaMteGFJJqd=>/SD4Qe$hSZ9=a+@u^i>%G:Pj%V9kV1X&LGk^GtQE<ji*4%IlCb&X%L
j=pcHR ZE5?w9cQt@a$8ZIELh\5F&HME&/Jk\wT/1:!6KawVhaNV8IkpBuiDDLbNiXcc+8aa:&:w%p#kNF<5y1+
c+mRCS 1I!Yb%%G=/dL/8=\c%n@#L+JhLERV#qK*5q16w6P$lm#+9l?i?CT1u%iV5/#PS^VNp%/bDuc?4HL:PT^
^FRaV\ 1btkS>=8ye&\@B\Hi<V>lSnFPitQXFpLGhD#biY^E$P/yjY=y+GKBt$$n=/J@8DIw5/!Hj+C*9jY#Tm*
byTuN# PY&VTbJK$ye%!6Qy1>5ubnFW#n%8Q6!!KNFm8EdQVRmPZ/%aBw&uikkJ*VNXMheq1atpG?Q5acc&XZ%Z
uyn$qZ #Qq=:<aDq1X5@j*MM4Mjl5ctd:!D>BB5n#S?qHw>=#^9qk:m?Tk4!*aNM@@?C<i&@b8<*QE6p?Q?5uAq
X\n9>h <4eq>ePT^:N5qRaMh4w*uM\dXp>p@KFQi>P6F>9iY@lpRZ!1nqm1#*=bBViutTQYF5S:1M9SenhncZR5
Y@@F=R Q!S5W8iPCLTPVI?Z$kl8LN&J4?yFYB^9T&!qj8Y*Y4=8%cn6q9ByV8QV>FVm+\5q\:N=at>d#:jMiZTt
E>i!$8 Q>yLLMnhu*qMQLtlZabR8uSR*+^ICF>c9hJ=+#jPw!KpQju!^c!G/a5a5q8W&*1*=FK?1M/aNVn/PLYZ
!5TS$+ cLLj/4TtDQ9!5m>/+tJJ&P*\C:ZKqQ46Zc=G?wCcnK5jQQBZ8%5@9et@<!ncejd=k?bk&II<$e8C&1IE
K8RiI1 kYF#XY#PChk9+\pI1mbD+aV#nbDkpeXPjQ$F#Pq!4V*JWQPwH@:t*@6qGNul9@TW?CTMu@&XN!X&W9H>
Gy$i*w ?>GY=\LQ?jZ6WnY<TXQ9HiFHV1R9lj&C*8japn>=?QFMhcNuB+w:\um%\Bnn6KPQ*eu98<u@HB\FAbdI
/>*+#@ 1@iFEw<9XjWulP/Q+ChjiB!:E%j:?nlJklKZT4*R<M\dP:EY=EnWRd^6a^8IVFw!J5TC!GjC9cY?wt5\
1Je^w< #9wNyXNqdYb!k+1@%m!%:*F!IFe=4P*Dh8RkMLMkuZ1lyj/XT*y^:S6b6hlWpVAbp9w<jdebEpmld^R>
/Km:WM 5Wy^e<=>$KWMcc*&e\bc&Q$*llB\yecl5<8D@9$!LcK>!e9NhJ+d^$ek\IZYPQauL!b&%wE1=eauK4ZE
nyc>Ri pV+H54&B\<FuTit*alW***8NcGLC+$nuBDPhY!GFR>yb$jYjiRL/YphqBJ5h>+$:5eu#KiqLyS+YJNN1
th/&*j 45\htZ+kQq%juVtau/pF=GyIVaqMp#E+/ScHwGpYplbcV/56SJu8@a&&qdL*5D>Ju\k%?=lA<LL*8NqQ
tCu5aw mQbPRHY6TATB:4:E5e/%=<q8Z5jl$W=>+q*Jke?wTI6pG/JDH@:5<b/4y&dhFkITPhZ@dJl</<t?^SN+
p5F8jM Vb?=TBPn=6/*P%H8VZcB=wbEN1^+PWZPCc/y:==amWN5Aw@:G:4/p1+Jb1&PJ#FhC!1^E!KF/ZtV+S=\
hCdDIK ?>B\NC:FBVEI/=Jiyi+q#LK\GKNW$%+!bpW^HWS8XFEPpuBINVe9m9Spyt9Zu&XL^*lab699mDjRcqai
$b??\! %:FZ<55YjK\5tJXC<dXJ%We8yW!YRle89B^A\\LtYS&pdm&bIKJjjJDRM^/596mC/%h!RR$$><aIV+?N
AJG**q c/t*%lSyC4qQB1qe/RG=lpB?ZCA=mIIeh!+#i5PCTN9\9VE*8DyV6eQ@A/<<GBbIM\<>ZSRDl$8qVB#W
$pK$<9 >A!b*JnYI?Yik1XK?EkR=!WG&aM4%eq=nZeVTjH1G*iPNDKhB5?wG!ZXFKFnH\l+i:$kHL+uD&Y<1@Eh
Y*IbW\ nI<VZZy^c*EXj6h*k!#*nWlj:kqWFw*!Kj:mdV\ENeap!1Pe4XSdl9E6E&Nbqw<T9956IMMMR&:#<F&j
!5c/HP e?d^\k6$ECPE^qSJ+9Eh?B@:*klVunM5GD?n!Wb?>mlH!MG4Pi:DLVFchhZ5RS*%RI$AeA!QJ*N$A<RW
>BjJp1 E:TQpRG9^Zd+DaeEc=jP16e!/T<W/95+?YYDbCtG+!=YbGlJjXGQpSe5i4VYh/nuGW#yydh>aq&DQFTi
+RpTw8 \RZw%>%T%=5a1EceZy8w9D#qKE=mq^bb>bMRCSGZNXI4pG$ZiFB:Ak6Y@HCPQIDhS&ecklcFVPa>8N1@
6BbL8j jy96IEP1dCAL:uCFQS1nLD:W?JV1=P:GWc4bP=/T6^DEm6X#cp:G8wZY!uX<u+d&w^@ihk96%6k+6=1=
@>@H!& ewm:6P$5$MqM##Z&m^RXiL&uKBtnl8ch/#6/<&Ruk:#CCcy1d$Zp%5uub<ny=Pk4A+/debB\B/YEuFI/
CDl:AL 5Bm/SI1V8%&<&jS^Y14aWRjD*EN?<aDTc@VV^!kDR88yQ+>y1:5SR#EVMMCl5$b%lK??<<^qN8n+>X#&
q#8X@F mA:WFV<S+=yIdLAI*j%GKbdp&tl=PZICI+<j>pq%Hu%#R=*%K<<H6cX:4tn#+aD*:P1:$EBn6i*tFNMa
LW+T1X m59:puuhVlS\NSh*F8ldF8QKqQV:d^N4C#&@H^$dV?u98G$:%dWtRJ/@NSNQLElGWK8#9=pijF>jbVRT
*SIl@1 5Fb>lSX=p=!F4JECWS5bQ!SywQ8pL=u469QJc#QZGTWRL=tqbZ>ZP?V=a&46mC1pp/:K$RuuHLjcpy/W
-A!A\Y 000dd6b32a900110333 Page 60 of binaries1.zip
Y<IBBA KTb&qam\unjXYN@n6u:=lQ+PD@IklkXVeEPTk:^c\*YE%H&:^>?%tLWcbmZ\6Yn&9VZ*?Q\5=dJii4Zj
Q%/HjG >@MGHlM%DlPBZqMkYSmbLt?q9QJkpat4FjykYyXVBh$SGe%=G\1j6wiMd#wui8>wRPMI%WL8l:lp^\>G
$nMRNT nwID:Q8>jtpE!BmSD:5Ycyt6*PItW?hF>:%VXHQdX\8G/JL&jB&cc\T+YVwnHBPnVBKKHJ*9R?PHDZj<
!&>nA6 muh=98a*IklN$aVj9&R<Ry@k#AWW%WQjyKtVckwRtXIJddZAC?t?y1EYw+nFtR+HR4\@Edq%biL<6nW^
/wJpGy ki>8e<&M&I:<mCd!RL$k%KG/u?q5ic:Yd%GPBc5^tFDc^MVKj>6Bj6yN9PSTZE/tq@M15VYi8VuKNY\$
h@LIMb #::u!tbJcZttaKd?ZMKdnp^@A9d8DyH^w@VD&y=+Bdci#%mKyd1=S=:iH@l%!SCuSHdAIS8!hR=%GLSu
PcWhA5 t=Qm<5#@SeKb!NPZ/*1u\aL/=HWnnZa4u:p$lD/Q9KQP8M\cDileTBGd>%jcRh+c>#cktS=&h=A^Hdim
8uS$4! 9Sq4eLTRPccjiTTJn:=:\5W:Etm@MF>+5ZC#89h&11FcIqpB**B/^+Fj<lq1*E^?TyM>><TCKcFkdAQK
?bXw%/ B:1VEl6CG%Kp=1&GBSY:m:\j6ml!&\ej#RP8Z>e*+%d9WXe4iBVy4/qW<F!K:A/<Ec#8Ztw=dY5+@$J1
m4+^>u >EP=!bdDhbYudlHbFXc!J>@4d<kHt^!lS#>4ti!6^kb+%#VG:TlTTMSbiwmD*=%tNjdKyn%yJViwhyiS
4M&4HW !uyZ@Y+RQa+idW#ey1XhePP5qQX^YEnjpclRdK?Vjj/tTS84Fc6p9$SY%ZYhKwP&EZ?MwM*AaG1l1q?9
hn^WEV qw&M1#SMXt#NimdN+jHcB4iVKp44qn>a16aIMVSED&y\41C48T:5nV4nI\cTGGMe!Xm6h:cICeiW6P$5
PwJ9@E <llQ4j6A5pPN@wD#%Tun4@QwdXV*SqFLZiZ\@pF/eAKb?\*W1GD#^+!HppIuH>ct^?Q*6i>IQCbJ1i@u
J1K>X1 *\kTbwdNT58$5plkTKQByTYXEc6T@h=hXYjEAJ@>naB/jkyXVk<86Re>Ly4\mD\nqlI=$bR&y#PX>m>6
kJ#+6M =#>aMQX*mGW$KkPM\iHK1uw?QWaQCY<R<:#w6Bk%J@pbd5NBwD4>F<awG9Y@V*6m6PV@pG5lI@a94wY$
^#HEc1 #P?/F9<l8j&#pQi9mmqc<q>em#>ZY>FT9+H>m>FlcPuj\Q:F/DC$#G>kJj+eK!Z&G%n^9<CK@#*&4$dT
c%19RE TTF@A!9>=</DqMS9aNF@:6JIwZ+Dm@y#%$JK<ni\j*Yjj+NZpu>%u*?DX!nWZ@!>9<E4ChTjm>yT9<E4
GcHm^b CjE@9%jT9<E4yNTj:%u/N*n%q//FNQJ*N9*u4wZ$d^AL?eeCj+4>DYIlJj@e6bD?DYKl@/Lh69S9EA5q
M8+itZ ?Sh:q91j\E4@p?Q^H<n@J<jnQ>6#m?4DyeRp@>Z^pJd=E<hDVEL/@#X=:q9@y?Y=>>CYeB9Kw4dBthdK
a+aWNV KLnn+/PD?N1hhuKBe%PXl#XGA8P$yKuPS5#RMl*6Q=+WMe5MIw+>H6PeA&1tn<bmknn/+y68E6L*BeFN
5anPXB NJwNeEce6h:j%NtMK9VpYMp*ZjqXJp^>#JmNwDj=GPNQjjtFDdPhD6ZAy1di6tp=c<F/:eFu:=uNG6eh
X>VVTl iE#wty^6nKt1w46jddh#8k6Dd>W+#pEnj&mMH^b+11\8N94R#%Vk=9yEAp9u?W*IX<:a$GphB+<1>aju
<dqm6& BCB*X*1aFFLG9XqJZ$#h?aN?hwjmyFFtQ@DkHny/uwe>CtSYT^WKi5H4uM+Y>1Q=IpK$hnw:R#j4u4Pp
+ciVhZ **hwqVc/5<H9B8=^1kl6$nYM$NCKe#tb5<l=c?Z$mAyM!9Wyu#S9C9WwRYn>qX&daNPRNaleYK!:&hR*
LE!dW4 kqX!t+#KP8%#VK5tWtmhp4G=5hSXbR?c@Baid+SjGy?>KZ8apWC?@yL5hZF/eM<aC^&>DK\^^cHHKCnZ
R4$NT> 5VcP\jZG<5FAip8ZiWQ9N=YH*5=Tk@P$ddP>y<XtbGbGknjNGYjDJBpG*#Yj8F6#?:j+MMWu@4k/m!iI
NpZahX QceSKp5LalAXTDVpZ=cKa$t*$N*6yaXh>nX5Y^t4M#!Nd&V*4:@PJPTkQ9QX<H^PwYS$wlMpd%i^c@bG
IFuK8R a$V:wI6?<>L1<=%SqNZl/I$cQ5h/pK:<15Dkl=qbDnBj%l9pJh#FdnbWW?iSZwGETyRDS+GaS<>!#>b*
q1DNj8 ^mn6V8iN^eh%HS+5c=6NNm>j*bS+h*W$QRqR$=^5Fd6$mnJt44#XZE1L?e##^K!6M*ymmX^=Ej+wTn6F
wdc8hb &E%Ln:G!?lXmWMT<1Zay*/ZFbt$HcPpXIc6Y\%^Fhn$8Qw6<wH/l+C&=w:>wt6Fk4iEaZStHp&Dyw+Ma
t8+at# =+Kni&Yt4m%N4#HtV#dLi%WT?#5G!16IW%Kb9N%d:5QaX@S@FhETlI9?JM#bPk6<\?l/K@CDhZqq\EPC
F\5QiS etqLwW$Q?p?NT/pyZP1HhHwNbwN4bm=XX5tTk%%j#LkGMNeNJyawa#^%9^l=mjkE?jaWht=!G/*P!EE&
*Y:1!N XSQ!X1*yGn+Ku$*6KTKZ8X?dHIp%5\6^9Ly@q65+d=T<mC5/tZnMede@$?@Smtm</c@6RkiHAFyP+dM*
4wXGTJ 1>qdM=wEt?<+ZbGqywMG\6Ticy\JA<V$4G1\/98*WPQJ8Dt!:AKhhM9y4X@!QF\@<9kS4IJT<M4cWn:n
+N:SVd W&&^eh4MCuLth!L%lb<4w1jhhniL^cy>?5i?jCawIMnKuZ&9c5THJtWuXDF!hD&hZXV41Tde5nl\Qb#c
6GF$XP !Z^ET$M5<6BVq<>cHe8da^HcQQ#yYTH%LN91Valk:a5C?6Jk#/nYBIwu!$>Z?<eGK8\5EI@GkK+MRk>a
#/Vhnu Ej\6p=%knTac4*NPK\pTB+6P>y4!?X8*MuH$Fet#pwl?V@KD?:%GehTQG>bqI8Hq>=X=<kYyqWPlnw@<
%5IAH1 C:8LdAe/dy4NdZ:mX*W\u?#^jCl\\6\@HIh4MM=EluK:Q<&nX&H$:5EHhPaVw!yZ6tbnnD<GWYn#JaHw
?P%D+4 HXeM/>lctG1InRbWyVRJ+n\L=GLwF5ahaju&mCIRu*%#aJm/ebTX<WZI!y:5Xp?t!w=5KMQ%Bd65eQLT
Z@4d9X ^GTQm9hD/tH#=X!l6=%KaGMP!<m=V\+NC$G5^$<wNJL9+?^%:11!*D5C<V#NiK^bGDyWL8Di6ce8%^Bl
/^Bj:# yeJ&D$T#1X5W&6H?Juc\<&HyXH:$Ab8Hd6<#e!*ytnHG6mE>q?HA#S%#d<1d\k1&ubhNNm&lN=y$a@M>
hQJND# hS$%nK6mi+!&Bm9CSp*4#iITe@dSltXE5q8=?at6\T<nHh<^<^ui=h>*hK@XciDkK*=:8>FaXBl:CG$=
y&BWPq p8PpYR9Z959lP=#!>hYem>yVCS/9dtti#\9qKeZGA<G%LS85RAH$5@4J1eqK:/4w#wXB@!:T?1/<J6N>
ECdmV1 CeQPj9wZYlXY1u#Z=+wC#\TTSpm$WZ5ia9WE\ElFW5Lwa8FNhq99uDmj:c$8pdIS9cI9NpCPLLE/ER=n
:QZ*KA yy:+jY11l$k/@M8mp%W*L?9m=?yLAk8=Na=N+mX?ktIDS^HX*yj9R\NZt5<jkaKBq$HFN+LBd+?<W>1/
PCn$+^ $kt$aKbV#N<W*dPXm=*!dLVEk%=Bk?NZI#NuYdTc/Zk?MWYQYubM!V^P<i<?H1!*H1^HBARq<Y4=+bM?
:SQPCi EtHiWBGJHEnC$8p/Kl>ud4H1%IjRGLWtaIdAQP>+ip>EqSBC1hB1:yGu%YVZb^K1Rn^9F!Zt&+5Zjh6y
ccq4RV Cy&Ik@#RcDpu%\\T@y4!^J5l6NFKQ*MT?kQ:SFV:SZ4BRLMGaZ#Iha$mPpR*>>DWpjpc!HGm6YuRi@#=
uPuI4e 9h=e<KG9:6#ETmQB5P^44/I6@:qSMAPcqj+J&LqNL%<mIuN=!#8%R$y%&&jnnW@lDY1a4GVTYbwyP4!/
NIIA%Z +lqm<P$FE&QYh4jeH48?mhFL8JT<9@tbiHK</ZyQ&a8dbD6Xq6KjTNE9P\%MeYeJ@bPKGdI16nLM/!<$
kVAi<T <M*%9>1nD/l%p&Ik/diaVdLn:Z#1:<iCL8MMw4@9/N#^A:6XuV:^W>JIw@V**u>*wZp@e4*KmpXwyNZZ
!9@+P@ lHjX/?MG1KqW=YQt@ajn9\=waX4wMk%Fn=weH*i%tq*pNtq5?>/TmbwuIT>6EqECRZ*JV*jYeN%W+SQ/
#p&b>y E&JnyPkd+/*9Q#Z=jtb<6<5+DlE#NK^$!alLdwpXpZC4VmVeT^H>nw!n9?8=yW6SMn%8#1&SLqRn=J<+
Mm4C:+ WTw<4EttGMy*@^qjIuKC>q8@u^k8PSjdETk+G8$DeCa&VptTdS1=A^HiTY^tICiYDRkwJp?tB8>tpb%M
VWQ%Xh QDwlm9h=a#K/=$/yd#JcuR*qEmphQSKLhMiP&pA^P>M?%kE#<Ru/<mi&<at?$ADKAV@h#%q\&?$><>LS
J+5R<> :/=p=Ct*u&Q#5H8q=:Wi&4wHBn+e%1pEyIN9IpuuNHqN^RL6wD4HtmRu9VQ#%K:5SnXEH>IBGe+6a5:I
/Zh<&: h!KMEpbEF8u>$F%C@/#punFMWG6PWE5NTc$4\<qJ6BA?Rd\6bYa@nR^ywm:9#VQbV<cFA^mTkHPk^:6$
Kh8%em eX=8y?Wyy@bcFEnl$#+^nZ/:^JBek!LH#FVB@RMD>>TMPqWc>W#n^P659mG*1CG6i@XN!ehG4w*4\^/B
VEMAjj +/Z9?Tl#%D^8jaCW/Y+beT\aWX%&EAMSZn>4S?DXHwu*S?mHM+kWw6?k*6pupiRnjN4K9jCG$^Se^kEY
\qd!>< =Y@l\+ZeG*/q6Zu>wD+^d$kZH+IjKeud5GiVtMR>Cw5G4EDV:HZXIJnBCN:SGV*nZtqCSiFTL#+8Eh=a
86&VtA yK4#nLKLw5Jw9AQ@pkH8IWP>mw@l=Bk*Z/?L9WkFWpidGk9akAK^e*9VtwDd^:Hn9E+*hLeV>XSp^F$>
+4H#b: >LaWSdJHSYL**Rjd>N<FNjDapnT1jibhP19P5hwjqQAZ!5>eWakL5CQP6wmLNCW65SDXkHI9ZL#ACH>M
BYZBb\ Llb/5u>WaLYLHeWGVA1cbyBiN4<u@JnqhJ*Cbc1B$1k^=KF411Lw^lNI\IY@$I8Gm>8XD6#1P$:6C4J:
+h*A+$ PX@TBq%ME5jH/m*&dtBm=*TuD/?>C^JIJEWh$G1M\Y/>L=bWbVVZ$I%6y%BR$jjuKPj:+Cpl:Qhkq\!>
YacT@9 !!a6c9>\\&NYN<VjZ:ytQ^a1uCmbA^<^S9>w8HmiETdc5yQaE1wcS@<RQw6PcNp$eBul5nWXKyTy&i8w
h@N?Au !d8SN9Fbw8Y6pLH#6nmKJ&hMZXj>*EHTqLuJd#<nJ6ZZKiSP89\P>Y1Y4%<RWpA+!%KpkuKh68B4qaS&
mXAdHS kBq^!6jHRWnLCZtDA$th^LMVnV1BQTQlpe6$:\m?@q4aF8W9ZC%W^R<!bmSP*ePqimYEY6nlnCHlFL5@
4Ydm/\ J=5:RTi/hcwwhGYcbTY@pc4d%wWAJ8<DAlR/#44%NX!u\@d*L4qTWmYtnRh$9961M@cc!Y4=cThtYtL%
4<c/h> u%+nV#MBI4%L>&B?P#EdP?>LnilBp:5m9S<CP<BNX#=?Ze@/**#RYVh*?yyWjdqQHucph!JbT=6QquuE
8$*>1L =dEdX@Bem%kwaJhMSLb?kVA8=\5wJaN%hu>$SJY?>aH&pCV9jk\#*W^MwI^6!<L1YY4m9p9!%FKlZ>@1
5+S^ep VDFX=kQ1Du@GGVAY>>Hm$!9KuYB/Mme=Ip?tnTG#&k!t$^6d<X<e^Y6aiCuFAwQicu^^p6#1B+t5qSy9
*YtmK= LIpey^@lVXBCyaMwV8$WVb=w<CdB1hPV>=Hy?@ATWIDJEQ?%WC4>+AW?/9kPFGCHw*>y/?ybhSNNVwe9
-A1wV8 000bfb9d70900110333 Page 61 of binaries1.zip
m^YniL tWmRq!4^1R$4@%FK5<?9@6FBpVRnPny^n65KdpXLm^^b^w<N5uBGAWI?mbZ1w!KbWF4emB#lEZLVKFeW
q@aNa9 P6P>n\<iEie%/>$aGV+ZIwhlP&yHTAQyJu>XIc6EN8F=w&KGbVlIpX$5Zw5!$wTjKLd8ZH@WA49actDG
l/u/$X T&J&p$q9AjjmwhWRbGi^^><M@@lV\ALQlZywWCKp>+pa?lHJ!i\WP5CA$5jQJaPu#B@tl5K6Q4::BI8X
?e!#y< ncaa*c$cN8\$u#9eXK!5@cB^9+a8Z5\68=EBtaM#jEj&I?LWCNIRTpL#yy@Iq$KKkWiIAIdjhiSLV%:m
>jnS>B Jh@YhBK4Vq+<9ht6GI<@!mR%+lRTEA5>TSZu?=kdw6H!*N=@I=X8*TG4=*:eMK4:c%E4BJ8FISh:#GL5
+=cR9l d6tlcyhXpNDcVy/@Vm9id64cBh*JwBPT@cy&YiwLL^K5F9cX@jBi:VV6B^R?ai:$Sp\<jaW4ll9$Ka:d
bMS=A+ F*:Rd%aXHnhBKFL*T/hKJiAld%^TaEIMtb$4@I%9VP#+tWL&Bc!uwCKI\tMqhqenN*E9V@KDK1W^Wq*H
+!@Ylw 1T9C1ehaIpHN^6DuVTQ6PIH1Z>Z8!In>:!NS!+n@n$nWWtJT@!^ST+tlj$PmX9d#<@@n#Vb@9Q*j4!wq
QmB5/j >q@n>Q=N9@=QAiYjbBtbj=Y@bMS@W:?Ypjl:4CV!#!W5GhS9aMZ?ZA8Ypj^:LPw9M16q$H?QqWD>^dyT
hcVpMR j+>F@pYm5a#$d&Aq@&Jhtd@Hmp9@1c:/n<F=j+9>K&%WTp#<j\d<G<!T@HMq?h<=@N?\45EleFE>yImM
CBYcB1 mAScZF^KSN#D%hFF^NnX=+<+hBH=+!QA^hQQ@d?m:N>C+a>Z@#Y5V>jV#@9jw5#=H^<G+u@<K<V@YQej
VVLyqK @!q^TiT@B+l@pI64$B?@FQ8*u*@iDiyQhmQ=^&=R+6JTTBFXD<iAENekESNZ=>Ak#=D4Il18nmGlRc:B
P%SehR Iw=?LmLtwV=?4pGPVy+?umGij$V+d?+TmSKHI<Yp+WlyFB!JFQ8hZW4?p<A1I@/*A86@yyH@R&BFT9!L
LtmL=j \Q49H#*@JLD?EhFm@%>K?j@cqHKMC/5pwkDHGEhIy5EKAkdHWeRS/84TD#qm>uhB4jA*TEq^?IH+WG9A
p!EH5# QHN*1/$CJT#6QJ^T?6>T!lG1^jR!@!&qQI9Lpb4<@==Td9&+KZFLuVCYS5\nK9:kc^AL8HdDqYJk$phw
Iwhc^h /l@b=H!RD!!YjJKICq*bMiFTy>iT%GKG/\K6kCHMeQbe@ajyEJ5/HXBVS!eqT4tludM4=Cu%A=Qyi<k*
PKWKh/ ualGbdXlKppFX8\5MJj#WjM6Qa*u^nR?51Pp6V:Hw#C%eIj$Ab%M5aWFhcAB%G@nBZiu/jp6%iEt4A?#
^HyG8a Bi4yhhQqdi<MVeqN6WDP?caiE+iSpNwJB6W!9KHReKm/ki?LA!@dl/*KE+$CpL56#yJDNQP>6QPL^Xb5
eQqK%$ +%PT!a\9aAW8K\8P:e=8uYu1Cl:/WlJbG8CeT&G9iHHR/JIG*dimJXp/ETXt>cm:Xkm#Vq&68>$huL:&
t:X+e5 <h$lHw##5&@R&*H$QwWGl6pTQ18PX@N/hG<*%iwT=lem4bS%$lXcNV6NS&RK#bl%a8mhnA%N<9jtXB4C
8n:5aV ZXFX6&ZTd?1wb#/u?>uc8W@H/LdpVV8m^iDBe59<XD+SW$9u<PLJ&e6$b?E^l%HG^yLZ=wiK$h9DccyD
VGGpI* D86b4tdlK/>8DbX*tw?R?Hk!lHE/dC+HQ@M!9XFSPt?Kcq/h%b+@h=*48P\&+4Ydw:=F:b18TieeiK?>
dY\H4\ &CGhNdYXJwJ?\&l&>yc@/QWR1/EHX58u4/&e+l/Qtc\h$j$whun%YhyweytK:kAW+KHGL:el>AQ>&558
S^JRj6 q+quj:ZJ8X$H14i&bZnwLde^=SB@td\?kQGSQ6yj/M\eDu!L1JPBNRX\nK\>6QeY69kR&T\R=\4WT>dB
HZbl>1 Hq?6>ALe81lJw%A#RaTN:qj#/ZKW$5e1JFIJ*#5hZk8B>X##YCWu5@JDlKRBXhSmmjw>SaL!WYLCjS!D
NHu8BJ *!nuWMJccaYXk&y&kI&WVl$9<Zm%qRcmLA=V:Cq*lm4/\5jl<V9ynb*ZSHjnwNh5Q1lAVBt9jh=cTlM9
9iK%I> D/@^LG@C9+Lq>jBFdZRlH>Z<DM544LcbXV?S//Ji6An\lE:J5#V9XZwDHTiC16Mi!ZtEQM:Dw&Le$8+Q
/^B*!B :pd:=y%^RXNW6MhunDk&ntI!/:<n6d:a\XK+qD\FK=tF<YiV6M^QleS+eB!G$&T8ZHwS^kFH=X4$Z9pl
F1M!5> LhFejSaDwJ$k4nq6WD1BtCcu!E8cRTabdVQNa54>%%Qm6SE6X8H/wcqHDFk^6VTED<9:C6umVeW:Yt\Q
/eZ!Gp YGl%k=kn^CRVWF5aD/=E?w5h8SVWqwD$GBWn1#/cF%V<iPmt^NSG5Ccy1a^RdEpZZjVKQcw/VtAPqt/>
8&^=Ip p:M$yijc5>$%:&#h1+wk!&M?4V%TP>TcWqWbpnIY4eWW?E6A=%V8G9>kj+HKm9ei*&8hK%%9wJk@jIKd
+ZB*j@ tp%1KhiLpM^?=/L9aie*%5pB+jSQ5lKCK=Vjy>eYDMj^/%#Byd=yhHVSa*+mT!88pn!9m%\YtF1WLXIR
NII4b$ N9L5%$<L^@86<?G1#1:tJG^8jS*DiDJHY&=*<mqV&d=9?*TcEl@L$I@GWFN8dW@BH:hEGybk*RPa5N6%
AYk^Qd BJk?wKquEa&iYiwWe=Ed=S16I!JqjuF</T+h>h5%$n9itH9FZJG?YXWYdiby1w8h=^d==+CA9Rumdt^j
h@S:KH icuS8E@bdMd/*TGc@GDZy8bhA:9D<cZm^Yi\+>A1*i4/Ncc+tQnWVpwJuc%Zbkh<95K:ZinhNPK6/?%q
>d>KV= W*c<TCJq*1Wl*j6%55FTl/?n!?I&dC%c^F:TYIZ/lpDe9dXKDT=@$SV%Mba8V@aXi@9hZhW?Tlild4E1
FuRn/@ PKc6h1\6Elh@\j<i>:n$SwM:cb+dM*?%RX=@aNHAw8im4XPyid<48TCIE6PwT&y8!tCG#Hp6p8tiXX&6
1Bh>XP cD9Fb6y<TH@\RMLa@BYd%p/@pa:6*IwliET^Mli\ME5w>!K^lYWPqNyFX>IZ@=HdtbP@IQS<yNadk9?w
atu/DM $VY<<M=QabKZXFRm$?nG&#hBTY/4IKji=LnnAt@!56\9M&qEQc4G9X4pb&IDjQK?>:eH#aP@SP6bZDKb
u!$BQ^ lilNi%%VEyY&4i55Q$QQBE$*&IZmN4=1>NTA5Z$ihKlDy%H$6G5<B?B8M$E9%^\btdP9Zc\*A%9+Cm@<
lhSXKX jSNt5GYycViwmLYbR:%wGLZn@jCt\MCeLj&V!@nP=aDy4\je?^5PdpLI$/WyX5AeC/%PTNcu*Zm=>m^^
B\=l@K N=FJa6L9*ChM6yXbGn$b1K&Pw1pAGDR%P!%m%X6mS@6Eb!<nhjdAAnX!$iWT1eYJK&N&KT^$inQ8al1y
?njj8L wTcn/n^J9bNj5Dd>6jlL!4XRStpVE+q:=9P/bYqIc+9NeyNVM&HpSthn%6FR1t:6tSi1T%l$hp&c&FV*
dGabR% +hp*M+59e5JDmjeQ\!M49IKL%dZt6Tw5A4\GWy/jE6/*ZSG8Jp6y^4PEpZ?$DuZGLYdeNh&8YmXF$1ac
$t1Dlh =4*tW%8:I&4/W&6$:<H#iQmL?<=t/TJ^K%P91GhmLb$<qdpJRNp16?pw4?5LRGmj5+?68W+$@!CJtHud
1nlBd: tk/c5?+kkey45h$5=NY@C>HR9S&Th5Nqy8m8p^@u^6#5*aZ*B\^6XMnmn:1I#Lw:d?ePe8T+VV1FQyXI
Ala>Fa *nZ#Ew!#ihS>5JM&N&Fp+&+$@iBFmRM!NjnGtNH6d:i?$6Fkj1RRj^b+5QFBF&@:uNWC&9>VDRQ%*Fw+
^a@@HD X59cue5W:yX>?H*^^ad^B@QPIZQ@8F1=A%4nF8d%w@4FGt8V@w&#:R:DGdnyB/eS9bQm<j*$F>YpZ5bd
WS6L<w /THFI1n&9j5=PyHktlQX=$ZwD<c*+%LHp6lNjXp>NNwpIjh#+&j&E*!k@LE#TRWF#bt=L*e&hD4iWcLP
Y4?iqX mA?J6VtJp>wK/q!mSFmL6LECFbbXpJJ5wF?Q^q%IY9KBi1T#^kY+cta4Kjq:ui\lj>@dK4jWc4Y\+hn6
Cq\?WB ^J\5N\G%F=u^9EH>8<d:QwD9LycDHntt#:ZX+uBP>YeJZu/b<jY*M:<t:M6SVuI+:96M^<@TXIcyySqu
LQ$C6W V@WGn9cnS+1eS$wdQ@TXk\N51QV>MS/TYewp=D\*Y/qNRQKGw/e$XcW?9AjhjpJQW@^5Y1JS&!EtM/c/
K:>HZ% lH5Pl@AA9R8Xl1L$nZl6Xh&daLC%$SN9wkh$$jXwMb!qc4Q4>PRy*lX+ALAie4y$=VETAG5NYcI#WFe8
DV:cIi lAwVddY1/IcV!@SVEjYKcNR5we@kKG4n=PQGEGXMd=TtIQW&NhyIN4Vt^FNe6=#K&Dn&Aa&^WJCZhnlQ
Kh/SVn Y/#S5TGuJc\%F4WjA1:\IVhKSw6Pj=!N6Hc&R9S9DD=p+V+SC==w%y&IjnV^?NyB<1F*6bSt&&uy>PGG
ap<Cqa IXqmGHk:*YRwYw$<BRFYRHliR#V@lMHG!h5K&h48#:pH&jXQp+86FLmFbZnY&414ujumIph$N>V9\IP$
*Ei%HD m%Jh4N5&n64iHFZVN&?dGw6lQh6Ta+c^P*NH1JMX5M@>P<mei1G9C::!mTC?A?MMwyNDEY=ndj+CGeML
PIjj#J *94lZuj:aM>SjY1%aM@*nQ!n?WJi#!6L\HXwC*AL?Dm>au@CA4DuPCw4Xh$TbMBAF5>G8K*t?H=i$5%J
$=VAub wNbDWphjwJY9a4e@@Q$=+c/XhH9p\N$a64b$^\?E*V6X/HQ>qjdMiML/uQbi6juE!Q%%GE<lYmK%^TQ5
ZRy$V5 NhE>qKb=GP^w$LZePPQEQ>kaBLDWDP/F*j$pGWj@%Cp!I*liL4lI<8=6XLP/akkF&>*9WTc>p6A>kVaw
j?%>Vq Y4Xh\9>?d^C4aa\#B/Ta&w%aWk8>QtWdPM<?iERtilyhNdI4AFtKI%5JDXESdV^KM1dkGdjnJT&KN4XN
y+6SY: ileyqd!FNpcd+aQ/5>l6Zi*D?q>\e#NKbZHb1?*Nmp61Z5VcADa5lXQw1Jt$P11DAuG*IAekRPbi:j%X
TQ$Lyb h#&5^P1C/%y^mBAt<jni8K#:=D5M9\MJ1TjdT:><Hqc%tL:+<ekk%EEC%aFY\m>>MMbm8>t#wi&H!YQD
PCu8\Z yJ>=8SDL/48G?HHD8QVVqqh5XeNGJ+18NX@SE%L1W=TJdy9GMdw>iu#4YW+bQnVI>$VjcQij9ye#*c&6
M!pm\Q \:qLpPcwN1>WcmaPCYC$6WypkWptb1S4ei9M*Ej15RLn%LHy\bq9&%<klPCiAB?L+DlFLGYwY*NFaG4F
>kD#/5 aTPc:KXTnbE6#e?B^BVJ$N=+*RniidF#w>1cmnuB\+K&#4!*:8T1QK8hbLGi%bGhYijMydT<MV6e=V>4
J#V8N# $#9i6y&>$PBat>?K:FRXyIFnVRSy?aQPeAhH&Yh#^l&uZhS!yT<E\yB*SGcPYynVcJk%>k8Bbq%i#n/4
=RPpI8 \Zu9GuL+XDwElqMd+n:bB:bKXE4w#iGCPJ*KpJW=w^?p1^RWDqNX&!wjuF$X8FVm1lBAYl4*W&8ec!+l
D?yD=$ mKhyQ/>L9Wq<Z>9HXek+:L1Z/q$X?6:WV9V4PCAQCEnm<<CdVq=4WqHT8Mw<Ie\+LMtDq<iQj6mbj6uM
$n=IBD yXAA5?MiX8$#^8W+KZ*I1Xnm>58p@/$u@inu/mJaHAtV?D69HpqV8wWHRnJiw6NQ$D$\6^c%JHBMR>9^
>YGY$G *nZj>6dAiC9@eNaBX%:=p^jEpDWb?6%k+I*\^TjT@FK8aeXiw=G:m\w?GnITSMyl+bAH\hFcYZbte<FW
9:nlMc #6&!q&@FccQwR/pRh:im*y6?9B#SM:Sk*qF$<K:St+?BXSdIct5+CiI5J+Jel8ZwS>Je+16D6Bwj:ILL
-A8YS* 00070c0d54800110333 Page 62 of binaries1.zip
bQw%R6 kS:X8YJSu@RZ6$9W/FJXCP%\hLt+dCDw\y8yt5PIt6/#m>YXXpaL1ehSAQY=pNPcDYcpbm?u<k5T%?Ch
IukyiS Q1Rup8%+#$SLbSGhhXhdqEX:>k:uy#??Q1Rw>uMb+tXmZB5w*/Gc6bunJ8P+6l@SZ^q^Ztu1Ftmyi=V!
LlM>R@ #5q=lKEK#!MKPTN9PXY=iV>\G^Ln*D?YMXn$4Vq#I@ui=Jt#LeK*VN>Nw@jah<N9LH:Vqe\&&C&&?TLw
IILeK$ \/pI@@6tNH<etthD^$^@ydy/6qH*i/M8hPYy%y\XpAm#/856H:GQ*1XJH4M$@4kLwaFDu^N+F6TjEtN\
e$\Jnh X:YhK&NthdZYjyY&Mh+p49yRGhnkha:ttShy@hq%91^GF<98aCI<k/+cA/eQL:>a?Gw+L\JD@<N*D1Mj
\>TYwm jDjpm*hk*nB=iHLZBbHJ<?%R:hhad&K8d6:+&D*W5ptle%9*=^58RKhTwVT@tI+8h/@8L#Gike8B:Xej
IXTNMK Q!iu=u5YhhMHbRR$c^%WlFP@@<!<pdmT@MY:PP@n9RPIGuW9&Pn$bqD<&*dCF:4=N<p:ucn:I$S5J$\A
R8R#jc L>yJ=+M5<lK4AL/5a+K&b<DTTYwXtSy5aS1*5AGBEP\=a$j6PTPdTHdP>/aWE&e#CbLce?yy%FHa/e1Q
IIc9=@ Mt61EFT%IwQFJWDeRHQK&dZwPj#<Vt9%ihdqlTlGGQmG<\mjHpM9Z5H?KeNJ^S@Zc>Aa+bLtkX94P9aZ
A^Jka+ Tknb^W<5R\Tt+c<i6FbitZ*@R5V^BRV:k5EpPJumm+499K^W1H6&<&YViI%FTt^/W+N56jidMGByKMtJ
t8KCA< Jc>WC&e&hI??a!jhNRthq@$At@dm+b=p$eikT5<5e/!Lbe4KA:4#nEM@N@VpA#Ye6Wca^aE9R+j6A/&9
/N&Bly tt**6$ahH>aLh:kNT^iV^@F@Mn!1wqF4m=#R:QSt!Q:/+^=uJ4uucXi>w4iPdEt%elFFFClYKVhG<ZHM
=jF=Ln QbdT%$ZhnNDQGqKh5HjXG:eaeQh&G=Kmj<I4XpZNFpSjCPtQ54<6VbA/<E!@Qq=PtVuDX&K^+ZJF^CGk
h:a?NS !5jqbJlnVk!u>*9dKpwMApnuJSY%\?#/P:aK//Gq4*$5KBjuHAQ#tj4D*mZP^K9&NKW#ljyw!^6:XZtY
MY4D6b 9k&LJLYdZFXn%XECEX=uNMm*wT41J5mdDjRq!^He&TCth*Gkn5EdY4>6Ge<T%nVTa<*Y!1LS<6te#kZC
?BEidy iG<hY<b9#P%Q<tmMDE&\qt/9SSHWKISbZu58WkVqV5t/8=KFQ/jieIhkida!%\/i&&4TZ6n^*J^K9\jN
=Rajd& jV4?98B%?!dD%C@T88c+CHawTjIetN*m/M%WS6DW%1%\!&a=4ZdI/L+MR$h^h$<J=GNu?I/6V48*i:Hi
Z<nBG5 whFeQVDILAR:%WFM*F*1K6nyBcZlC:?>jPdHE8D>iD?uMq*Yy%?GlKHCT&eJ68LcLX*>@8IB+N%>6hbC
1&Dq:X duuaN=t<qlW\iMewV4CX5*9wup:iW@&uAl+jpn+61dw?uGDM@BFmuDiB=qhEC&lAj^C5Q5=I89+hYjjM
cm<@u5 9yywC:!6NRMiP*w/@Wl&LdHTt!<:BS8JJ**uIMCnWhtmuSSM:/#q<>TZ5@Y%N4nhl5^&%Du5ZQk$1R5k
+hDcp: 6CQc#*L@dYu1N%DNPHi4?>ANHn:E4jnm\Q#A:Wel$K15i#VtS!>T:5p?yC:ljCDAab&j5m*ZZiVK=4YW
c\AI<! 6Aenmi=1elAIllBbG+:%C^c@D^>QCBjYtB$*>ln:XeJ/Le@65ZycZLF$K9dLl^69!q8$Gd@F\i#i*Ay/
MMQ9G& NB!*NQ^I<Swj9jhaRjudF8?NL+B9jJ^QDKTS$SGCS5HQ99^MQ?5Fy#1KyI@Q*HAl:&W@R\/m4i&:VyRM
PGQG*1 *=\@I=yB^l#:jdS+KtM>@tM:<G5kMnHA<aM*kP+y:85N/&E5KVPY9H?watVyC9kZ%R*@:49<#%6H$uAJ
1jkZ@S /j<j8plTa6L@R!+TE9$9LlJT<neLHj=VCJbCw9:EMJIT?^e#+6<*?h@uH9?=GTE8>9ha<V<*nKVE^Z>n
G+MT/= *d<\ReTS9+FFm9<=X8L95bJT/D@Hwu+DK!u==%nJ*<D?ii5lKZH$*&NS1L@AT9$>XkIy>iha/d@H@1Xj
jlYpE> JC:#Q\FG@kc#@8GR@CqY@H<C?#9ME9>#hmAq@u9D=n?S@&ZawQ?INep@I9RjS88@G#d@qRZ@d+aN/q<N
HNm$ei G!V1d/:=Z!cR&H>h<#?Nu*>e<#@cTQ:*%=V<p!#:j*T8?q5VCDVpmB@HmMYp^K5cEj\*N/lcuJJy&wtR
R4^lRB *\uBmE4pAEcN>@mlKcEJRE9GRVEWm^b8eLbu$qatlnY%FanC^Jwtpw$QMc4l/lSAWGLKG/=<GBS4191R
CAn=iG yhmK8^CVVm^I%WiFTKbY^RhaVBjQb6>W<AGp?kSnmKVNlSwSCkQwGJ?wPt/WVia+k@6T+wFcEeMieQ4u
pP?*HJ GpFJC&i*\54Il&t>MG@<^N6WEE^icbq8Wp^/8<DCn96yhmC*84\A\!+mMWdnmd^TI^>DbhwWVeKa5B%*
+\$=X9 EX41<QLb9KQ>wLZn1V&>q:TGwiLuGp+^bVZFE=5jS^XWd*@D1//q*wlMt!p>u/NqBZGKXH?4Yd>p?41X
%S?Vn1 \ZM$hLDqN<X?G@/C949Qeh^aJDucPL156u+%5+/Z%Ct=8IYk*=cX*:HFm^u8\>G%AMh!pE<l5M/Y5Yn9
i4dP1> wI%HHAS*aa91!pBCX4GVDnEYXi&6J<YNA6?DYaZTuG$HJMm$+c>Jkc1N4HFA=!IYPcibPZScBb<^T%?M
:iqn&L ^^B@h:y8&^c@M8dNbyu9TmquMmW4GdCK9B!iQWwbapjT5yuwX!i/CjBmBW@S/HhIG4ERMTKNBL%wTYNW
541<MY m=nnkNl*19ED18W@DDjXtlquKab8Z#:eXK8pu*$Ih?W^G6DJPZtc6w?:nP8adB/i=R!q*\J*iDh?tKVF
:TYCCT :NQPm*L6mqyRPBh5tY+*BDGdmpl1&b8JPti8Q+9K>DhbDMK5P<^j\wjZbtu9Wi+9wn!YJJcNK^:44lm<
I8p1S$ 8P/qpi5^=YNFN/XGC*$IbjGay<DNHd>C4m6^&ij%&Knb?8MPdjw#Ja!HBbV9m5YVSuQ==S5KX@n5^\8@
^KAV$^ jm+k@?H%wlM5I&d:8tL8$JG$+RVuFQe1lS*q=q!Wil%bHI%RHXLY8HVIa5VW+*l6Iq%DWG$b68/*yXB&
=Pb>l$ >^Y@bY=nq9e59ShJ\R5taRP4^$FtnkJpBnbhl&am>:aj9EH6wtlZC5@DY>:+H89qGSGEVMZ\cZQ!knkQ
%\LJ/K dM!TS%/eReu15X!ZC%W6Z/unHlw>@q:lyI^=tG6Em#K>yPDRGj#\L6A$e<jpp>\G5$J8L+MAid8RtS4p
DjjPD\ w*XbLc=FD91w>6^&W$49d8wik*=>?VMi%iB6</iht^qWmDnC9XTt=G%%Zw*$:D^hPbQ499JMK^ud*aG#
+49AWi *eJKDk+Rt^Y=*lZV8\*1i85Q*@1E^tahL&YRlc999MWaTuS*=m=@lHJi!^B?6%%18jh1RQ&:a*wE@*Xm
@5L:M+ %CAKaD$G=:V^^yTXAE$#&VLIuF$t9=l$9H6J?BwmdqSV?$5wZ1mbV4bd%u<>V<mqb!bKc#=maw6kME!@
iM%dJ$ HuhBII&jZI@ZdDNnB4:BJbYAcLut%kGGEkKahe85YP^RkY\$CQ1IXuW895TJkFAhM#tb&=N=am&GE8Gi
lZyyNl =qZ>dP&6ZCnlKCRmKHa?uJuDMtk%4W6L6QmG$Vw:P*m56aPjD^I!KP*w1**Qwe%nc=HD^q?atHKAw\I&
GTL%Lh lI%YRwP!qFue8bdNXASTwE\q%BX#Z^<IKyp<l<5<#e68ZdS=+@W!1=6XdT@AkGViI$ldE5k9MFw=ZI^@
hu4mY* tR$S9VwKSKna*8W=Nt:e:9Kn$*u9IGl+>+XM5CC#iIBe$FQl\p?bNa859c=y:L4c4\y?#bZ9kyNLbD4H
=SY#V6 ^5Q5mAyk\dauW*uKAn86*?PV4keNXK5Eet*\t==ht5Vqe9KY*T&$J=+&9NhbhP@6&bCey>bCT/m^TkXZ
5RIDB! akB+IQEJ<KVC&Pm%jXTQqPT+LE6G61&>P+1qTy9>Ii$WFZ+t%Ka8@&CewYIDuKDuy:@d1dl$qP?nM&9X
5N@u8! ><tL>N1clBGbWX*>J&VFb9b\#XldYRjIW<N1W6VpIm1Kj^e#5&n$TI6kW+m@p<ZI<#tbFnp+9P/<t*VS
qnTd\Z yhMmbCuXcNT+EZbQ9j+FjZlDh$+&+nYaFF<9\eJL9WeS!Y>Qa1jSXhX%a:4IYI9/kqpIe:<tKabZZ99p
P=duW% @XPe&*JyYtThETt?#XZKQJieVc+yA6*I*>hM1>J8>HCXhyBFLe@KF\88S^!4nCdu$mJdLLQnR?@Zh/8b
5D@!/h =VdHtnHQ4pA?1NHK>qqR&wj4!?pHp\<=Y=6Ha@66>J6<T/IJ#KaTapma:BaHl<uLB8\MyXc?Vp$>$5=N
9Y6ZAa n4yQGi!\RZl%+?GIKj@4686X:&MCMXXejK=:M\5i46H$R5m/DeiIZJWk:RR4AaFQLQ1YnZR?KamDN<+%
u=QWhm Rc!Lt#wCcQNNkVJNbXY=AkH6T<e\5iCAFCXLHWFK=We:+#k\Eakl&&cmYy*HZ:bIT#</d=DXIh!V+LF4
?ZkT\G yy&A<W^A&McW8&^EHdilVb*K^wIHimCAX8TmMyi/>XDKc<yJY%KjkWD::CG9d$Cni5@N%$d#h6j%Q/<q
b&W*6X DibKpBdWLt5K>FX$F&cjPF61ITKiH6*@!ZwwEJXj&Nd@=JnSiX<1W8jyi$=!/Yba+d9IqQRFT+aF9@Pu
>/@B9X XLXYd+^4PK9yGJ!=b!e@K*EuNeta!e>d^AwhiDa8X#neQLCMYyP=Bnb9jbtu$S#j5S\D<M>8tYLFL\/8
\WEtFj NP=?8h:?/phWB91#6q6K<==Za1i&=H9&5dd?DNm6uDGj:@wdP<6C6\ZN\4uEy/6aHGqXZEH6e6/LRldN
>/#6JR &W@9TBiLc&B<&:p>X898!#Xh@&C4y&9h>YwFZ$4@X66X4t5$jV*$@5=HcIcQ>8QhB=4SNn/jV/Y8:YVb
cYjJZZ 9!/RFdFcCk&Zk4uiuZ=QtRSS>lF!LjMC&9KbedwP%NjaCuBJ^CibN\dAy6e:d4uYFk%QhW6m4BwWK*!w
BVYk9V Ge!YqFDQX:S8mMRq/iGtQ=jVQ8BjBK/\!L^Bt<l?Wk5&P*pp+&?B5?&n@!S9MEEu4VJM!wW&4n@45:C6
eYp\D1 6w#T5n>j#c\\qVK8VYG*:><\Y5unBG+*e5Vc*%d:cPteBD9K<:JalPY!uk&jqQC^5Qe*qA64$4V/<^Ak
ajalhH D/NJCi@hPBXjNiMY\ijVI#a5QP>$JTlJTbYybX91MNX>AV/8%d@:&m:%DcGR?uIN/WT&61L=Dm/CbE6e
ZCJi$n KcZ69JFVBSVSauHV1$e#%?1iWt/>YhVn1<bC\c***D:?:*KDYXXu*D6Ly#@qL9b?JL^W9iQ+yJm>p4!^
hd@W6m n+d9:YS%jXWKnD1DwC1ij*b8=E1L*>F6/tq$DG=m%Q>!*d%/=F*nT&:ekV4<GXhi#JG^DuDuXA?@i$Jd
PY?IG+ iG!e6&NcMcp@St+/E68ewM9Xhpl1!t$<LBT!RudbIlV\?Mn/cVZiXyj4cj4B*QF1*+\NaX4RpQeCZ8T?
D>Pn=1 D4Dk8+lG<^nieKVN$ujcRW#NCDBMZn1lC/qhEV*wIePdeSjpX+uMp<CH%JH^B*$kdpya^a$c=<GDl@Aj
QKQ16n 4nA6\Bq=/cCF@y+=KbiC1*+hJctFX=5d!H!1yj4G4p14/<pW=XQIL9LbR:nbeRB?X=!WP+6mlDK1l5@!
Gp=ST8 qPmd<JIY6H/EQQ/5jqkl<!Qqi&TtwE58lW?9duy+8YFYLiQm!Md$S!%1+QjJn=h++yZVLPcdL#%$a1w:
eMD&&P c\G\NN&J8I5><y<V196G96l9MJiFlA6<&515c<ADEiwZH#VJV5dw1lJh6:8kP6y+j8qeL@NF<T#/yJY*
-AJ!YY 000878ef3b300110333 Page 63 of binaries1.zip
&CWSaI 5!&!45%#+QI#pmiZbA#MG5tBLSNc#6&5jEe9c=/aX<?hWh=PTE*Q$tqeywwDA49!Tq&$mI8+E8&j<pHm
iT!c<< >S1jDGjc^JR<kK4qXXHBBZ49Ju%>XJhc?F:SpwJ!p&TINPuNa!&^8hIkKX!J%LVLG\$CiJNc&!G>VX#m
kXnBIc A=LZyP:nNVHXd\XX$nL$+G%\Zck9S%8Ih14p6VNBBtCp4dH>qm/6GhIG*yb5wjIXBFlcFV4qtAutI>F+
dFhNIS $mb65S%Y\d<$q+XbCqVdcakHWX%i?eyR#wawcw+9#QdJJZ+EWu^ZMAmIM6Si?^mp9TenqCIB<#ZMc%MR
:eJH=1 +YMp=%Zkcblu%=WAHk/\JKuaCe&L#M+#D?&V<@add+@@klAIW@ciBYa*CFJQ\h<KB>acH?%FbT<#tEC$
YcPFC* V@Au$AAF@a$QD+9yK6:edVeVM4E<A%cI%F>Ep9*<Nny/MwKE?e9ZpE*PiE:GDwq%C$u^1l+>tduSml8E
\Eh>KZ jjkGB8udijQL9BiX>IVQ/5P#VY!+$/Ihk$PqQn/Rimp\RK*KatDhG5Rt=Z1B=ppl%ELABVaPQ\1m1@T@
y=*Qbq WbS<KH%V#9qYtDyhWKA4yN@\A\@6!Q#Bl*wT>mp*>LSa1<?B/jq6*\uT:TEXMSi?n#6S6P:WS?yl>/y<
IJTli* bB1!l$#+w1mmbdFG!GMRZhBbJYkVqRG9k:bBL+lMpHF$Y9jWW?kuZb+Ep$iJpZ>mMMDGi*EnS$i%p>5<
qk1c?b =6XiGm/LCi59cGeybQp+y>%w!<pXCyE@M^a^+aN@Fn1iRnF\6=VeCHEKd6LD:JF9n+>?uKCVyMKiyjAL
19BmlW 6C?mSSuwSMtpRedkR*eqR:BV+#tt9u^p+bC5DpH95mPHG#*%8QnR@pZB8JWth5e!Y$P?Sp4AGXhNdeMI
dA#!@8 wZ^n5Db<QBhnuQ$FwtkJMqDMTD<V!$B<:ISS@:#+cCe9PAYyGDPn&VBc=HBNbi><cWGWw<+=\5Ji9!8+
%Zk1#n ILIM=Zl/>BFhHciy>tSK@IY/BQ#yB/=Y%c/YPBa!1wZY\BB*1ud^*GK4Jpday<cH\q11!d$^%WPT=^yQ
&Lehw% L^=yXk!cHl%C#+:hPq%iG4PaE:WmjT+Z:nLy6BaLTD+Y4%NklTWAe8JByLYjpS5/<<Qc8SEeXCwGB<!G
ZA&CNV AS$@P:RX$t94p1P#SZCH19j4l41kZu+Nii^cAp5%GcXF<TPpI=TdPS&D?lP\$lZ:QFT%@1a#aK*6+1ky
mCQHMI &Smc!G#WuJ%*M55+RZkjSph+GhcR:AeX$PG1Y6i9=hKCydu9FVW8Sin\Cd1bQue$m?SiEI8kjTDiZQ8G
L##4&F !*VZMHWGFPlEjhj1MlLTNebMV$kip4Qa8YF=Gw4AiE^A/MuFR!aY>k8F+*ZwZwwD^m!utBmyGIR:*NX&
tQ\bjT MWH1E4ajF?$DW1iEQnJYjN$Ki8eRLCNe8k4>qCbKV/E8PSA58S:RSIHc?Rtj^ewm$h4Jy4>ea%\:==w1
N\duyG ?cy%eNEmD^Z*eY%dyKdmyC:VE#XD%ZPqAhy=M&*$Pc@h1uN<uI#$#ELHn@DAp=>%IiVybhI<1mGjHWP%
5%c*i* @F\t4Q8>J6=w+ZnmXy6+w99=NEMj94jViuHne@IA\^**E/cd!?$**%@?jDlh=!Xl%D&C69AcB8tEcbue
FR*ya* <Q\MAjy<pEStk$JDh>FQ@AZ^u*Q8cYMK6QPnLBctGN#/lep4P\tm*p?MYjI$Gw*e:H<XQWe5Z>E+PqP:
hY/\Lq /Cpiedh*yu>8#K<*D55bN9V1iuhi4eZZiwad6>S1Ih\%Myw9@QIVRp9@PKj@Clh>Kh&>eqeahN&T^:bD
%P8WdI N4JA\<HmhTl^qZ\XL<hB91Nk>XLk!ZhZaw/kbPe&Wl@Pi^^?at88*S\l/*wnSeTpTRmV:H#1Ct=?5aI+
%!!>&i FlQZabNBd>:5iNq5iJ+^k8h>!Cj1<n4GX@^#bS#EXdFL?AiAZcQRJu>?A$Vcck+TyDi#JFPbhd6Njn%k
/ZE^\V Nh6!#hnaE!jRquN&P@yImwZlqC\wy?T56:edG\l@HtZyt>AhiH9*+=*T6j#1?#6VT$b<#Q*Zd&9B=/Bl
+:*pSu u8StDy\FD@D1a8cFLmeZlIMYthqE1dwkFpE6\6L!A++@%*PS/Q>6TkGppFL@R!K8lQT@mLkTW4<4+9/H
pKu\y$ pQQQp6P@CuSI1Z?Y8yDIQ=i4bQ+i?%jm4aVa*&Q@w5yATpL<::GTj!H<TmD@Hw8T?w6%Jj+iK@HuHYip
/TWqA< JFB@n$Wm@&LQpu?Q@W5hXAL>V@wjW849p5D@T$j<l@/Hp9yZ@i@QypqKT9>B8Q?Vp5CJ@n$JuP<jTiCb
CbtZAJ P+cicI>S%eDM$5:/iYb%Vm4qdqQWc4LGaI#IttHR:Q8$c4dVu9WKykWR?Kh$>>$tQ1wLb:aBnLGhAHWb
I#bJ6N pW&mAAt\aYDAWt8cSwI*b+X:KQFweNGu^#b^TAt$SSZX>@dAIbX%T=G%XweMQW1kI@B#AnpRLNalpZym
%at+pL 8NPy4?MB:*D5N>\dXMbp:<Wd68^9kFyc*mAqDX5P^AeStQ%Z1C^cMWb$VPtdHR$CVQ#:iN@9A4RW+6kN
Ttb\X^ &5/Kmm#YWX?Qq>SnSlBD5dFVD$PWb9NRB$nE<>@/kNNeWPwI#Vn>Y^>\=w1wHEiC%6dwJuCW:4jGictt
^$qRF& qb%b#nud&?9y9w<D&b8dLR<l*e/X?$6hY4wm4#w4dE!bB?e*HJXAal&aB@4R?YAJLWjhaJW^aS$5e*!V
P<k1XH uD94T&G+^=wpC4XFm#*@IENuh5\c?$A1#hBuchFQ@pD1=WtunYcHH6\hQlNpG&emSVhFTW98B^LZBNE<
IZl:i< hVS/FLDl^dJkmn4u=/<L/l5lq4BMR5XVXK/<VK<IPH:@Gkc*uyit#Z&q8*/leA&l**SkV/8Y^5*PIP5+
Xkh!bc FMcXPtZe\K+S*Ql#Dt\$6Y*>Nn^aF\*NPtbeqa=KW/ZW8a1hTyZWHVhEP!t4L>F9q*q4Gt=LRpb!F<#y
W*8Mj? 4tm:khl%#1%LX+:=qjQcPRXy/bm\9aihMIQ$tXcV/1WXYTFSyq%1YD=9HP1&d\qa%##Zdke>yN:k$DF!
VSjiMM 5S=ZAAZ?Z?#>hXSdc@89n%Ik\bLkDm*FuRA^KKWWCC:BKc:BZW6ym!Y+8=Vm:k/qLeZh9WAy:1XAT*&h
DYLJ<K >>%jPj8<c/&>%6uj<>6:nLQ*Z\#G!DZ!#Jputeq>#j9?XB=@w/h$9!FjwB>^Z:n*y<@PBL/!amky#8hJ
\TIy*V 9=bwtcnL:hVH65i\J<JHWt/jGjG:<ZyP&pCSM1*bpeAGB\4>hkKh<SWWtLLdXeVmMk*JkuQCXchwNc&y
iSeyIj F5cJBLma8+w<>q5*eH!48l:8^PA6^ecq*JpWc:4mBWem*^^%L9pMIc>QI!emV:8FlR/pZW^n4S9H^X*B
ad=BlZ Q*m$J#/BN!#VVNu::&Sh9:4$aya?G/X8N<9N9aQa<#qD4WK/i6\?6V%?uqJyi1eXwY=h^IJ6iHBVTMF\
<5n/aR +tTq+u#$nQdAG4X*T5P*XFR?$Vh9V^+^\>4i<G6tLkyWPQA5$mm\DWLM1c$?9hDJlZWuw4mPkQd5<Q6Q
1Bw:Il q5<Hay*JS6BXhE@Pd^&@M1X/>p!?NPun$4I>H9y!q&>b8qd@WVc\<ednBkPNBJ*nWln&>F:PZMndY&GA
?KhYV@ ?^1PE/<qbS6%elKN/t?TCDmKcme%$YHGyBE=cQeN9cN8DGtX6DK?yyYFW<1FaPJVq<P4SwNH\dcV=lQ+
m8lTPM T>jq6Cb=a\wSw?1TPN?Jjk@lA<iXZJYcQ5Qi/WS%$9Zl<DI*n5wZqly\ybFIt5PX%XSkJCt$/yPMkREw
#1R#+S @aH%yGK8qQ=**V^4mX%9maL6S#eaC9!##4:&e^5Hh$<eV$He$9Z8K&C9\Vt6ylA96k1iCmcLC!q\5?Lm
hK\PI9 G^=GpyLn/KipcM!LCP@uE^IQqZnZ&b18j#SpP4el!ZdDy\l$:wdK?eQe@it+mb#EPP%G=eY<H$lj8lh9
q++RP5 %9A@u+WACSecJTa=K/JVSS^aXT8$+=e>an>$64X>/ee!\4BI+aL%J5\FW/pJ*H!!W:qpL1ZMiFdX6maN
!y:MeB CReG9%a@dAG@YenQYh=+J5<nT$L8S>i$iQV%lwIkwA+i>E4Kt=ucFt\^&uAau6+RR>Z/ILhJy$DMeMl\
eN%@yH dSn1M5YVMm$wP9!A<BN+!4wYiDV%+PlG5JQtXmqZ#tS4>8^F%a%h*4+Ae?P*Qa+%:<8T^%p$HJdthm%<
yEhh=e J/1BR$X9!bNL:m6?tRCkB*>!#Jt+Ccj*E8u=5>n>cHdVJ/>kuj&8XR1Yldi8wC8?%c!Yh8Zt\9QdEYX>
V=bQie yIJC?n1jW*!cyQNtFkh$1@A=d@Eb9R9bui%I^/IM!eG!1XZ\$/jZDA>lA+#T<T/^<1Pq&WP&u4*:1&Qy
E:ebmM X88L/Bh9cGl4*>SR#ASK9ulPR%:=ItaW9<JXDY&QQpbL?n?^L85!RGcPblkecd/hlp5eQN6PNEq?cWKe
Jk8BpW Qee*L>uAR<=8QwL%LiQTawQZMPC=AVhbDRJ>QGP5Kdj5t!*Vtk5XyuntVC/nKtpAl@ENF=XL:iRL#Bj#
NPH=q8 QwLYVy^pQlKc&YYk&@EuSBSb=Qdp%N$ub^H<4ue=*wi^QV\YpJ+Y51lcWFN<KKT!MWm8aj<tDFTKPbmb
W6qe=S Nwl\A#Mwc+NaSmSm6md$G!6hE*:1KQk*6dFI%VyVYEu9X+>8M#@:=EHS5TaFhdm@%<H9Fjk?IbLI*uhZ
p/5>9b >uFk<&%MA!CmiLKyA<i@c%Wb#>Vm#dJ5TX@:XQ^WM:!K%<$=<@KB<%%a+^bLB1m44L^%<E/l&cW%MGlP
ad$V/8 DY@Y+6TepGQ1t&LNWVwtdqqCXXyLQK?6>uqJ<9G=EYPZ\eDhwKW/#8hy>d#NHeDtyDwly^1Nmb#t^#IG
ET^SJq tqCq%#Y!t*ZQ?5KM%uewaW?6V#@jdc>@RhaY<NRH^RN&$q^&BTMcE$/Zj<MWt4<B5?J@lPHwuMAw>@cQ
MXKwCi V6$t1Syhd+<DdYP6EECq5i^e9GQQ5NVH1pw#y5Q<CGi@M9R&mc1eiYEHSP9BdGGCc*c<bP&?$YQt%^Pt
b9XSEn p+c&EVGm$9/=?=1#*<Sqw+Bd&8HTk?+MqIa&pN5M&JMuup9Q#RQGwi8hMwuw^16W!:YXjy<#L/G$1?YF
N+8bR* q^T%G<>MZ/^Z/Dt+b#Hu&PaPc^m&LL#<Lch?kM?A/in+MLkwhii$\GEVtKJC!d:ch#%n6GXHFCwc#E#p
i<K*yy hI!\/Ce%Z*:@iI4QAbR=aD$KidLW+@jlWXGk@cZFVaiKL*4=kukLbhpE#9LPV@Zt:/w@md!d@N:he4Iy
5EW@PF e5ME@$p=J*@H9T@Eju%#kR&H#ynVm&^H=nF!9+6h&YWQ^IJiR!n*w=P*ibqF*GPPA5JTeZL<i=DuPZ:?
D@YaEa ZGpC#^4&Z^mIyl9t1q#qe+jw<*F+n5#tSL^1X/b!KHDZ&V#::VALTS+C*BH?BTTWH+#CSGYlkT*?aY1t
XiR/F8 wyYEqT%jXVq\^F>?t!d<FN>tV!XhZMwBG<Ci:H#:tTV@t+PT**k=AbFn6mju$=Ep#DRMETF*QSTpjK1Q
!ARJH# 1R9KI6qw*MSaqZ$uBaK85W+*#kc6/!&5>t5M!@MDE6*I#8XQTKawMCZFi<%EW=ikMywH$bqAbhLYI#SF
%T5eE= ptn/4n\p1S>i5DhaI1PXGAB&@?H5iYJTu%HweIRn!@B&d5uZ=mEBFH*!nP9:EJbh$+KIIZkEcRF^:Q*!
k:KaW! qIhkLEFJG!wjyqh/#*wP#idLPD+yaj!$:>Lbi1>/uK>YuB^\?/Mw6F+eEZ<pepTVVeQCnbiKdT\l<:lG
pYQSkM DHm5\4@S!6hqXXWyCF5XnCSaY>@1BSBW#Fjk\bPmCTR^ZtT!\Qw\9bNkuSnQ1:C1\lqQ&HBNL5qJhbZl
l+KbBJ bT%^?p#hLMVhYm#u^Z/kba\D&a\6ZYMmW\nGm8JZ<#?8&ChAVi=ZH#e^=MXajh/wjA>yW!m^npNLhMkG
-AKL#I 0009d7a07ab00110333 Page 64 of binaries1.zip
$l?\*A =H!A8qR?hT9jTbjG1eE:$h/Wue8pAIQI+QFFpk$/iM5Q>VnCC<=RpRIeF<KbP<K8I6&QebyeXiDdClpG
^>PbiZ 9McRcEMkh9LFeJ^%jWEG9#PtXIF4EDwTGbF?u9E5Ji%Bu+qqw$&=lB1i8/kpX5L$lLl=>kcHI1ceL#CE
nDaT^& !<dB/ty=!qC@XIGk^\M\cAXV&$BERpkEiM&4R4nXQy<4nwj&uEeuF1F&G#w@9mHaV>N6!C9uTdAQ6!ie
SqkmFG q9Mu<m:uLhDutjYbym9l6a4y@ibV:CVGS!*tQawqeTRSd94p9Xi5dAHTa!tZd^X64PLBweYy>F%<mM9S
\w1*hV 6+SK=WEFt!4cVJKHE&KqDLqaK$6cC^Dj?LjItMnb+ijEGa+yFl=/X5mR*tXFd?W>/De^Tt/qeHE>TEC@
m$?%q4 <DhdE:K>5Dey<$NN!<kw&jqEI*Fh1\Z641SBZkj9X^iy4^FPVYN/$$QN<#keJSI6c$4\Hqc=T\B/JL%u
Apq>?m AT@YVY?WX1Ke:#p*#l6wJhq?T8$ykP4bJ\*Q$FF?BPdtXBLIBEbu!tM?Wp/cJe!+<JcHaWdyHt:8RL#%
anyD1S B:%aa4W+MKP!\BmVQGlJMdYIEwdjqCyL!6M+*T5ZLeah:m*<P8pqGnQeFSb5TuCTQS?D4^qhmb6e/bX%
Fwti:4 D\?yQb6lE6*B>E!Ci&ahTlHq5!#/$%9KRI=LaLhCKuhAyRe/*NGB6AG8&QQ<6GNSEjPeF>N@YKDn9KXh
#$!pe! ^!^&LNmW69qPbHlSJ$9ua#/aV+J:Wlk:>8ReDYd=pK5>NCTllLGiM1^T%\LQh&4ami1Zk6/:?bGS1?&K
8%!6HT QJQdaWj^$cwjptK=bRadNR&WbWQt%:cQ5D+AN+:BeINIWk$9YlWA:/1dPK8mwSTS!S/JVMa&VYDX5idM
J9Hmyi G*dIpNk8n&d1y6:qD^iDcHmyVQ/SD*PEeP@<$hCC4:hj<G6/Q+Q\*L8&iWEHRhQdGpy?GJ@YWwN?KWID
YbW@>L e@$lp<X$@wVBhHJcW:P!hLucjQjaQd6YKaD\*y4tn$d%ha*b*u^@$I8!?b4Vp9cyJ#9WXdEDi=dA4E:m
W4&D@J @HY4=b1Qu\S:#jnCJdkdj=Z5e*HIqR8u@Ma=jHSb:E?1!9>#/LHb^CcA\W!F&L9+a\M8^BZYa?6AkPH!
+MPA$c j/yBqBFAT@XJQR6TLtX9t#BwbVJFyNGF&@Hn5pMy?1h:c#*@ZHZm:A*u$kSyGyi:SiT%nD>q!QH^GB\a
*PQqql TCnY:cP$D#d5M*Ye!*wi6WDPLcjdiC$E/LP4u?NRI*ni5$96/Y5Hlb/Y9RDlQ6+T:DIFCY9XRJ$%Np&T
NXhjwa GjXT:\Kw*u5Q/n<<M^WWV#PJ+cJXKuMB#T44!8d/ylN+WcyAl\N=j4wKnK4RyqnnGyW?Mn5&wB4WTQWE
:/q5uR abc#DF+E9idaXpkAXZXb*J6yhtD5e::yAmR=9X!=PaeTiTIQ*DjCl\ucTEnpuwEVN6Jn/#%k$SPBXm6G
i?wcnc @C\Q$4X*j6XInnnZWBc6imq5:a\I$d+ilc5!/CN4XMyH\i&:/JwEQ*k$Z/&*H$^Ju$?Km$5nItHt1Z$#
I5m$qY Q%eE58Ect4uAPdq#&j+6XM$dE5kiqKJS5QNE6*&#Gp%l^1XuPTbh1npP6QP*yD@#+%tV:<@SnS$D+!4K
&^AAjm y=@hG\yc/*HW<aS8Py+/DV&!y9*N1MwbT^S1:mbSL<KNyu$XWLu4\MNwtHn8P!C*i9Ii%>m8\RPPInJM
C@h<KC Mud<1uytc%5iNtya#9PJa$#>!cJ>dC%=?^jD#JMkY+GclIXQlD&Z5cY?NkD=:+uuK!:5HQR1V>JETKaj
Hh=wZe EDjTLBkB>dahp!<peu$^9#Ww$E!<W!JD9SKy+bWe</eaR?Iy$h5BEhe5#m4%wPkPF>iR@W%5:pQC&YlG
414mYY 6yTM6AnZSZ&qJNW=bS<pi%l\VRBuH:SaTb<HpDRJtYH$?dDqwm\BHGt\&1N+PE5MckEmW?*lRFRWlcXa
Hi#/NQ =I#SZ9MV\DG5&LYe#^M&h\9iZJ>>&IPq4dPGZ5QLyWlwLZQE$w:^@q$S:=>JJ5Jw@W6h$*NCnpDntS#N
tV4Am* GP%QAuHS#e?!h@NYVC/4^LIL^4I9!TQEAIaV*9L>PybDP@hu8:dD@eQwVp$489ADmyj$ZhiJ?E8XkPJ$
JRI/=: FQA!$L>kFK@6X%!Sp%D!twSjSZEKBtGBI1N+X:>y@ABY$16q:YV%%p?qZE*^&E!h?/h6jHF<u8e\jEtY
qR5kA8 <*LXJhi%#DwHhYpmcD!&ZtJIw:5kbj!BM=a@KaVQwc#nK^u1J+e?V>bDYtyji!@aHV::BkeAYFYN41A%
dIGnHw ^aPbulk/9#y4u:GhWWB\1D#DaDJAXN6+R^:nYI!<d#Z4?<u:amC?B8TdZm@FCCw+VLQcPCwP+FwyXdX>
1Lwye+ Sm\qSaZ$<#Pqd9=PDXSW6S#X9V@&*ba!YydCR6j8tAp&=a:1m*Q5iDQj&1b?+BJAaXM%+@pbHpXKb^$d
qPAtnQ ?V!Y\5k%$Ld/i<jiVTiSD%dS&eC1q?%8Nw$m?*int&yKBT&^9iXCHmLjk86EbT&\BLBqV#58V#LSNQqF
dLDPXX YPZwuK#hEbki:Htea=M86>IC=6Cky8SnN?9@qlhQ/iC$u9=RJYp8@=QVn\I1J&?uy9uct#DGX/VdNZ4:
ibb1WZ Q^=ia:J>tRdKYnQ8TJGVVQqSPhEaLZ<II1JI<$tb4$lnNCC@i1#$kLTa+VSRdq?lahXF:4BjM6$@#Yi\
I%5=na TXKS#an!?lu6J*ZuD*\$eYcR64NnP+LKp*V9eI$KeF8@dbC9ck?wP6?<aN#R<Y%F^MVD?E15apIJ9&+J
@Xl9^I I1&/$d\mK>:y5:Fl\<Gl885n18DMwSu?#1<8V8:cdh*/G9u%c/qn/EP!kYMZd\Q%9V5nc:<\%#acE#==
nLTmK# i>Jl%Z*p\9wDc/tCHh<?Ful\!E*c^9Z:ej<1K%Y@A=h4Smk&b*!J<!$1%c+y=<&N:\%GlH&ZHDapncN@
uD/196 6JMa\uMGE9JGW6dWDPmG>t#CDBbS&^4lH&?V<%C\@@kajeu\uPjY54GNLeCBSMIceni$cpD#uuqX+J*&
dVS\?/ ljL$4K<$m*Kdia5MwWPwJXGQqbG9%wtjHu%S6kNmilDZRwccmh9*MmJHH#XwK$j!WD<?Ri5@qqe&DWHi
GXh?y6 WchNq%hD$$wyN@CY$<1A$Kbpt<4/1T+Xk%SBNXlKW8/Mh4=RbbkQ6T@#P>Q:%A@bc<$>y=JBpG<L^L@+
6Yh$+M $ny9NX<^d:NbBZ<K>>\k8<enGbFC*Bd*!I#T51LMPqw:i6P41qhud1<MemYe$Ga%dy65aJkAtWQFKq>Z
V*&KI= TRe&@G#$XDb9c%Yy&e:eT^m+FdHn4%wd%Y=T1kiwAHVWdP8MA%/F9NeJ$?ha/6/>^<Q1nDCJ<yMy*!>@
*L!J%D FLM^aQRpSZ=#!5G+IKCnXEQ5jC6R:>XXjmqnwYV5Gmlte5jb/:dn1XaW1Q++LEcFLmbB5D9&G&4*J8k*
LJyw5# V5Mq4w:Tw@h=i4#RL^%qnR<wNN9jXt%XBV+WSda@M8:kXZ9qy8:\\6<tbBd$Qj@qy$iKRqZ9VSM9Ni9b
6$96pF EiCP#buL1>#ba6u*Fu=YJWjjdDZIi9S$<k?HJup\QJ<jWVG+N/yWt=/tCdt@hHS/MYnXL9L4$&tDRq*G
w%kHV\ MIJy1*bSIjLXqn4nF:9<tn$%^ZBQCCiBAEMeZn/<l6TSH>wV!StiXPLJL!&Hl?wJp:yBw5klu4iVFmYe
?18l%< pM4+/hu8RF6!8nmq^8ET8tpBJuJ8uWPujD=/P6dh4Yk&mLwkR=?hn!SHTbe?D>F>>H$D1JWwp#w^RIEh
#BtwBa &5cQWB9$Wh9ye1Bqq4j=tQ%q&AEAY#4=uL$&?9lt?$%:H/uhBDBhZN>tRHlItcV+M&%id/q=C/B+Zha+
X?M!pb 9N9A?VX:ht^SiFc$LBY@yBq?K=!y^N+@9N@/G!6B$Tk@k*I66VChma:=pJEG*&M::n*j%8*QD$tbJ9XK
&9H!*n 5+?$JD1$E4yFtM=>&YTI8:=L+uwGW@J?bd$dj1@atttd#tdLQQ?PI!q9\@ehbeu5ae8=kcIXqHuBidN1
Ht^ayK T88i?X99=4LeVb9Jw9e^LNGhKpJq?Q4*#lKnHNbXLLeBwnLpmeXmc\S$9AJb5\n^G$u8EiWmER^Vaynl
M:puKC 6Z!=$Zuhb/DnImB4u/$Qk1G$IwmLYJy5ZnH?ZyTpdFSQ=T!EwXD5B&F/aeWSpI*Zt#CmmD6JDV19q6#6
W$Y:<% &<4n=P8j!!XibM4AWe@ltlb*eFXN\><5@#qG55LE?A!6wNH:ZNXy#9BVbSl@SSpH^^>by:<SH9<@ESd@
9$jcWM 6$YVyNSjmTapHQy:$RTV?y%wk1H?4tn/h&Q\L^+C>u9l<^<i:T>q$i?DwH@Q@ytp?u$R>P>blMRj*<9>
H8\w=n ?!Dw*:PTj^!ykQ^>EQV9YRuWu#\9@K@bQ^W?9$?C@wNFT@*J!WL?m!!TqQyLYjRjN+n@W^dBj^>Cm@#9
j8:kj< E/L@W^cJ\/H@l+^pQ<B#@m<c!e/y59ZmnCYEBc>YXAMRt4w#Y@VT\!Y+49wRW>Ea15=j$Adjq99H^&Nl
\1TSEV AWaE#PZ<dYqRQhhCAmj8\<>W?:HCdmqPYH/nE*m@&&\RWJmHj#Z<SqF4D$h+l*Py@:VcHeBHyk?JS:$y
A&*y6l aWlT4&B!@!=hYIXmFlubEc&ytLnwdleYb^ttR!htacA+peA#1jyK:k<!6jhXdFl\FF6:LCVCQZ1K#i?:
iV#q5= D:y^IPGVu6cYiAD4nLZmX+ZcE%KV>mq\eBT#DljV#H%MPynwQk=M\W&uVJE*V1hVKHj!cyF8>KNc4b<6
itShj^ ie9CPL8&ITVW?#5MRQn+pV#IL>bW9$G>X1a>@tP/ICKllT=VG$@Z!n5B>eMe15I@Xi$T#tpY8%cZi4RI
GehdLa 54$5Kwm/1H*VNTA%1<@#mBG$ML6!d#=6>t^C$u>mSq9T6lm&6Lq+bQZG4Gd$&G9lB4yta8qK=YyCS:#*
i9?aWX YPF8^8q*JatEAZbb=iPjkEnD<%494t*a+\jT1+\LAEdh8QY<T^\S9YRmkHuCEZFA>:d^GWCw>9Pp9ZA^
wAJEqF TaGVH<Ine:1F=wlB8!%5n*tG/%ppw?X6JcXJ#JhB\hdSadpKiw9RMD<y^Sd>Rt/88aI=uN/ZQ5LbYn1N
a<Q8&8 B/\/d>ehl=66QWe5b#5Mn&BuicJ^LQ?<anLMmJk&LH&+14Zq5PppeGQ$aK%J?8!VX^dWk5paNtZWi%Td
@k?56R ^@K&&*%AhpbGD/t*1J>+T<jHY8=5iPcNl<+K4wYL8T8lmah5Cn%^h?!?=PPj>=RD1u8QdR*@<T%&!nP*
p$%TST ZiGq6>/kk=@ch+9XIueKIWKt+YM$Yk:##q=E&RQ<mEI=<J5iX>*!n@mPuZHYnH91JW\=/RV%d&ITLM5d
4%6bc^ t!Rak?*WH%%LJ6HS*Rp*/Z@uT+?lRLF\:um&/>nPA+V<QuYSTlKuKH^\5V?5qqFw/NA:TlB^6ub@!YZT
C&QLiq 4pq^1pc?4y%^Qty^K$*TblD6nniP?Hqj\SkiI\F1$q*F*9/8F\CAEDDn+$b%1k/i<mcRCtZMEn/ZaBI/
6bYMTH jWuDwH>?tH$=EI6dYJBbq4miK<+AupT@j?pA*LBlRbnY4aL9bF1$&/wQQt1$Y^1t:#cJJ@NJeAh*%c@R
NXJBuS ^SbLuWC>yiV9#H+qKZJS>Zd:!q^^CGdXn*K%w@CF+VeuG+8?KwucSb*\:P/<lFAeCk?TMVI:XDA>EES4
GLXD+H u$SJw&tNj+JtQGKe4V4LdjCR?$YQ$Y>wmJycVen%9XMT4ZHn+VA#i1aKi/%GPyTkH=QJYtXa/9C8l#\S
d+<:?T b&^bnV8i^F1VBDy1TS?5B6Rwphde>T/@IciWR%B\t=<LTGMedlDbuK+y&<1PYCk=5!MVRDNJW?W#uG!c
uZEac> <#c<!YwjjpH*>bnjbiDlIIeX/JcmjY#mKGXa!NbP^llYb+bRk<6SHMCb!=/6bK*ZjXXIXdCNmpyi@$$$
-AbXbB 000070b573300110333 Page 65 of binaries1.zip
m<u+e1 bDPj&Z6jB/wm$jHqt5Ke6eGl484lc@nN+t\CPJd&nP6NV14Pajl*R!4XqHADM8Imty<mX$&Cqe$YY:FX
nKn:KS h$T8Tk6cWWu5Lq^*T5?b6ih+KLYiy#qAjZ</ncyit>^R!QA=%&JAj?uNji6>:T:c&5!%mnHlW\!PP?J8
FlHuSc :Viy8XcwnW5RP%Y?!$>:i&cNM!c=h/Thi>y$I68H&&*Wl8ZLTe8yp:MHYSGD!8\*&%yBQ=%L81:8A<GV
$*QRan eP>J<Wu!Nj^kHIk*y6m$Qqyi$>RjM?MdwZ*WAGiIQL@YYWdy9DGRDeQFFeuuQu+^<Cq<yJS:le$pLH@9
b\PISl yT#T1AFuiLK56%eCK^<D9iZ@^NGI#ykTWVHXA/*hLqCimESQn:IJ^YMN/R$PK\/cV8\t8APBk1A=+/4P
BqJZRn N:*Seii<6Aa=^%^e%nqF:tq9?9t&ZwQt\>Ta!L/E^:\&wAM<L9EMlG/Y&lJ/ZN%=Q6y:p9GDPnT>1^=H
Zy?B6F lS*9J1iWQSTYWa:b<=EIn6h4/G9FhV^k5@Vhy/4GW91ij/9dK4dpKu\M\%CX!lWH^c%R1+YAEJPq<mcB
&Fl5HZ ql?6H%e>eH>WjHH$+X&/Ye<m\S\J&V8yD&#1wkTq8X#P%/Sd8$Rn1A?*T<qZ55jdaLWa/8y>RTGe%WbW
+Q%bDF Hj@WuXby>bKL18M+^9jImn8jc?uQdk!=t!SB!Rb@Ma\#%hYqFVcp+:F>V^4%XAEHGP=y1@p!K6P8R@Pl
I4jt:D >wljCCED4iG6JhiJ+LeFReP/Ty49V@dw:+AqR9!1**natHwAGe:c<<@yFheHLD4Hd<+=yXk6nWwC/jyK
yyt>>P =dIaVD:jc!ZF/k@W6S*:nwuGQ^MF#c=Hw<G9uIJ4%l#1Zn:wGi?1Z$c@$P@1jKhV=Y#d8RPY<D*b8GQy
C^9^58 4=lq<@##yX?XhKXS%4B1#$QAm:8bTQcVp*CN9ME:n6Q?dX%6pcQMX#NDn+1nZa56H*$bDB>^FZDHni!B
icV>*a GnXy$^8e854D?ac9#RIPjX=w>L:K449hFCZ/Nld#!q#FcCtiE*R/+%+hhJIRF+8R>MJtFG&88:+J4Z<e
!*MjRJ iQ?*!Ajwl!!Qp\#Z!^=>*4@iiNn8/1=Z*GVMP4I!bwTDFPbV*Fi9ymi1E#FwbZldwc!\Vm5j+hiWJDp9
5QNn9Y h8Nh#qweikG/qMQi>&+#/Hu%\bqcS!YH$==MkQuN^1y^4btnVG&TSn1eXH>MQhHqYM@kR$paFQT+@Ac/
KFDGbP $t=G95qYWD&e\>>8uGDGe=NQAq^@SXjHQQbwnp&8\QPuXG*4@4F&N:%McGZ+tBKlAJe$i\4W$KF*=Sm6
G4:NBb h?>=%kXj*M@J!X9cyDE%CaLZ<1?+D8*/HD$6h&*\Cy\9maCPQhnbp\^jK/!pk<t/CFYd=$%9?&uQ@t<m
=q^p#! t<89m4pITaP:yu48WA1dcyWTi5ImTCV&I8t!MI\E\/^EjQK4PHckK69akhaMpEwAJ%#Ep%Bn!!ucRNQq
TJB++q NF*tccE:AIq!XATW54*eNkMRXITNSPW:8/=6Lu8Q=5CPtMCS@Xe&*=:GbaD=b*%ILEV&u\KQ@EQW/$d5
qGk6&M 9&%8neKPDJ>nD=ayecVX1!LuRmTHXKy^@CPiqcVDLMCG?ceHVX&:5qAHjW8NFY1A^Vl=P4Cmp/y$lwR9
SkdK$/ /5q$wJIn=\#JLc4m=T+^HBB#WiRcMaKJtyVjIQ5RIWb^l>Vy4PD<HqA^K6uVH1K$W:A=C^Zu4@lIw\5>
#pk$ME Jm=\HNC=YZT1JBSLbVFNZ1&5@$SNGB=%aT?M<K>^*!K:?eGJ#lD*qIkuS<tXk8XntTPjEw!p!?#wl/1I
qJ+WwZ 1P8RJl6WDZlT+kTRQXQEJnak!4*tQR/!tWhw*M8F9Wqbqwm^G+%=YAE&+?Sj^#dLtJBhhy$M>M!F@$=Y
%+DWBJ lW6@t=Z4anVKh?bp8>@XyjE%m\lNyqLJ$#$deRByMy>KIP+B8@^HAnZbc@^YDaAkGm\:N+PKQ#AJycK:
8n?cG& K9qtY4Da6t6FKZ\i1eW:+9HnWC%6QK=4Fti%TR/etNwdBN*nnkKCb8P?S@J?hZ=TE=WWy4HYR=:@bXc/
QyZl^B iq\yl1AZ:Fn$SC58*%Fm@CV68&Cby/B@TjZGV^EkJ4F5h1hkNDt1+YB\@t#\WcpHYXQ+DZSZq*LR/euP
?naA*d i4qhRDWMQD6=THw?piRdE$u%h1D4aST9@&/icnX*6:y<>6diT!@kp@+w+HmJi/qY$$^XCw+#aR\8Rbp!
Q>&Knq P@aAStHl4WeBH+P%qNm%X$l$>u9GJE/Q1y!DTZ>>EyL69yRPcEd+nkY@tpCL1eq1CTw?h4Vct%NCD#/G
ES/dyi W&pW&dQyu%mM:b$H^SSF^<1PKQqYX$%mhKn8+8SW\^FmKS^nt^QC>RTt>pq6V4=j=ZP?^9tdiC4y:SIS
4=\C/< :>4X&m#JRZ#*SG99HMBTTl^kniTuAE981PCJbCRH:d!4ewLPWCyj/nwZ6Y#C?b/lE4PeI????y:Plj=4
:AA:Ld XV6RVbnVKT?q<HA=tF1<qQlyeqX8@ZubYhYlK+Bu14jMXZm\bmiJaDS1/qwkCnGwP%\q!9JTyb*@lK+&
EBQDVq bEDENhDbqT=M**C!GN<RV#Nm%S91jTmpFmDKBe!q%XTGNV%ZNH6iPq%A:PwZJXFB8LGR/CNXjT=epVRc
RnFRe? BTAqhy@c6c9#&8WE=eGVN=<iZWpT>E+Me$jVZZ^y:N$+:84Sj$>e+J4mt!8a>pFb%BHWe>SA$#Fu*@X!
=DkAnd n@CX@lk6QYFwu<SIncmJSJ@kZntjm:+lPcQtBF8@j6#$%G8lYIJbQ!:8YBEiXb5TLbw?hi!BREqwZhkW
^l#c!6 %d^yHdaKBJaXDQGq?:L4VKwTk5YEe^SadSRyKCmeS>qVZj&p!DS&VZnZw@9M#%=$K5MDEKEHn*&AHTEe
Jd:4Ce tFb1!LqD8>lVLc6KVXip9CX!8GQQV*WF!Q@KmRC&!5EQ9^ZaN<9S#%wiul!Z#S<j*TPIRXN>6KS^QRIY
H^$qEN 9cPb6nN^CnFWDcYm5mu*a4&S9G8#6jFey+=Wj%tqRTp5YhPtEh9yY$uMwTPeyPI#i>D$MTl/Wh4kwN!t
EW?=Y4 +S1$4/XG$bTe89n$5^jDB#8w!%&/<&e&M>IBG45KB\Kpyi=b!j:8I=1Wm^t+GT=5Kw++bI+HhlB<1kZm
HuFwXB tFJJ41kZCJ5Y&NQluPI>ja+C#bFZXQJdnV&ajH?49&CeRtuWKXi@VE@@+kYtJPwLuQD^61YT+Y<a*YTh
XSCRnA iu^JT+kc^Y1@iF=NmnpjYR\t>q8+wwjuwjN+VFd#!V4/6JZEL$99EBwcqXhNC8wQq#Jc=L=8a!X1I<+t
RGb+kB ^&auR<*y&\4m6==BT:yXY:LHIjpLVZyC^CJ:\c=piaWpEyN?Tbu8cRiCHFmDNM6>yRPBVcjQX<1EQ/yk
MF<i5X N<!hV=R@i+56^MBm?M\lac5jpSbRqjBpyJ>BQH*%QSY1>!d&Eqb?H!^6jlW5YMY&jk@\DEp$epeILKiD
>&:WDy FhQq<?/TT9QFTDiTDt6blcY=Z%NX<:jS*4<^M&&WqQSiSVKeaBw<bAiP6AMhEG64S/A>Vj4L:iFnn=Gq
T:QH6c 6JLXJh*uWG8?F/+<>qCH*t=X6RRtc?K!%4BDPM4B:y8Q?8*lH<ajaI?1XY\1N6NI@E9GFTHqh9pGXct?
!I5</< i&1H?8cn!ND?jdm/Y9TR8qKKY98ehQjFd:FM+lGjT^ZJX*FS=?BqcFAq:KGiHClqT\hcLkqde?@I<S*?
5AXTq1 GpNLGcQ#LCcdlJly:cGp!XK%YqLQepDH^dVQ#/m=cA9u6JT#$q6bJ+Fj*FACcyN/MyKBNhMXVAHqV=><
JbhAMJ ic#p:1!%4BAS1AcYyCj%#<b^LH5eF^kW#I=kepISn&:Q/YSt!#@eP<:W5$>wJk$ZEu^J+Qq&PWYNIVh5
5uySWV WH>9?I8@ipqL^bj8*dIZPmyY#Zjm?S:l%NWV>B^H9pBd1wM:M@BY*Id8y+<pAmZFaMh&GW?Blp4hEtTM
N!c9CZ DjbEu&%1G>ty6e/WJmn8qdLdu<jaFdn/u>5:u^\B>#QyM+TAlkKpdctMS@%BH#5Dli<=jMa^d1=VID1h
iy8Z>G Gk#QB!kh!n66^==m5*<Ln8IDE49bLdbKmpi<uaRwp6>nJqj<DPFny=KIVC&L\XPZ!B?!XR9e*56K:Kl#
Plc@@* CI4+RT*+IRYnQC6R$hn$KJKmIpZ1hp6nJY<eCV^h6p?bZYepnY9LpXhNy<@R9e6VhGclcuYICE%de%D&
*mTtKW L9JFKFMLV!DD9an6$C*F?SE:C1=:IGDdF9Fy+N/^iLp<mjDee!J+kZ&i\eieatjmKu5LmD5K=8b4V/wB
dPBl4T n@y<uHCijhC!i^apkZh%L*Hi46Y:XbZ\LFIyJ4LE+I=/R@QpJTXH1qbFX5QJA%c=<>HHQQ@+ch\A?i!A
bdm>N& j!5<h$5%:^GEFEDRjMQNP>X\yM=b\9^I!uZED1RSw<aw<TX^Y$X5MAZ\G<\Y/DD*:VBAipyNJS4$*WS+
5/!Mu* D&VA&KXjNWn1JC\<Pi6dM?SH*1M>lcAZLHD$%n1ICFNC1CJ@$*:S4P/FiDQ:#4L^R:uEG$EN#qV!H#y9
LV@pkM L>\aSq?nPN$q9mW!h/j!qYFRj8!Z>/HD=!?LpiRA$t+?naDP/AV<X<:?d!pPpcqy:XA!!GYXR&>uJPSR
^cR@@l +1pba8XlWkLdjRYeA>#MQE=QnyLcHEuC*d=!M%^KPbbkBB@w@JLlC:^1EYd&KHZjS=B&C4d!86Q@yyaL
AMd^V\ 4Q8DhL9RRw#RXN?RPhL#uy6WelwJAPYm#y*XPN==j/nbQJ#N4P9BbLjeikdNZJKQkYV*l/I9y9lV/wRI
LlEM:F X:%KtL>!TkLy/XTtRJLnbmWTb58t@aL$jTVJceFWW=Aa4ljT4iXA:K<u*d+YVmjB>c\/NEcAE*m^u5CK
VZbwRQ Hn/RqGJiVYD&GX#&Tjk^4<dMTZcZaKunqFEA%qENWMm1u@*!BWBRQjXRX+%YyD<4Mbd$c\aZJyLNjLa6
hD<148 P1H#QqLtVl4yX!Y#i@qpXmjei!5m#=w$W>dSMlEn!?8tAMIa:M=!1Mld%*iqZi<kSiBhM?8*IWjjRuJt
D55^IM h5#8!L^*p+:Z@M&5#TWRh/PqN8<IQA/%MmN*D>%R6qt=i:wBVnu5Qh$$9dqj?1$\Qt<@X*m@Dy9Cj1F%
4SccF# 84DDG8A9\^WG%l/tcI^!%B:WqWn/MeE?JD+lTWE4I#Y^hnXDK#K9C8iPSBp<i@1//yRq9GHul>SMb?KT
&?8<yh VlTTp?1QK?$\1j?6qZa+>I<4:j?e:/:8bPj#*>XlpjB@t<PPSQ#:**<j8w/W?4hFwMV@:j=:qMT@QS+F
Z:KM8q ?@j@@@*^aNT@N+ia@:eK9h<@D8kj1@:Qm4+p<k@t65QF@/hEAPJ*?elI?N@NS@/Qc9C@%Jnl9!@I\@>t
qm4!&* 9kRTL9uZLQ^QB4QAaZ@N@qp^H\:@c@bQC@J\^N<++D?JQaAn@\cLkQ$^?!@=19>B@w?K?j@S:jHQan+K
^?F?X4 @kjd/A@!Xj>^\8H@6@Qn@?ihH<^+Vd&WXXISJp</1aa5DHhuab1wNP1G1!k!Lq=jXD4PM\pnnhDpXkdl
kP41bu \RWH!E:1KM#6L89ey^RAwuF>FEDE<YBHYcjaSLJ@bp&SDmSBdEaHy4=5PL*^:@Q?FZ<T$<#BtQ=#*n>V
DIiZ1V n/5LNQFNkb/5IPB&VeEC$8%alcW6STF9h?m&*Mp@Q5kQdCu/aY#R6+Btw5Ab@HqjPZ*4@XwYiChX9=Qm
!LN$FY pMJLAn1Id#!4yk:$BXy^JCHLYpZ4!mZ/Vn8NH\65/lQwC>Pk*1qlF\/545KCyBNYqw%QdcycSeM$YVb%
<$ahJJ mmjM>ZukiSeL^8<%DjRADGdFnwl\#V9/PCL8W/Y*@1/SG4D*tqyI$<<ul%I1jmXj*S@+#V:Y:Ww?4n8y
B\\Y<Y @G@NIaINFb!c18P4W&$G@hLq5!D>jeZJ&lhPHCw6C*RT@aLXyqVV6#X<==ekQN1**^8LcP$BSKB:M\mS
-AuaRS 0004702bef500110333 Page 66 of binaries1.zip
MCP#Z/ b>y<RD$PuYmD5%!9JEV/VXP>HYN%J:jY\MA^L8598%wT8Qq+LY+e>BYqZt@4+G$i?c<VP<#6FCeEDQAH
E/w<a1 4pbyPt/<=t\YZjSn+hJ8G$+BR%w!bSHpwj4#FbK8J?8/M*AbhZahPn%:u:h/y$QaFhbT4>hDClyPAR1F
Z<t5H= L:YpY*!T%w&uq>S%jQ8:4uaN1ty:?tjcjX@tIL\:Qhl>==qhVH*nF$Zwi+atiFn6%>8t:4c5My5#P^mJ
YnVjtI uM@S4TAG^q==Q95NpNntQ*W:D6jm*qm9j:ZAtw6<9F/Kc@Y:1:S1?L*%k/Ddm/CjwVkm1qGJ#11h*WFa
6a?L>< 9E9Ciu>4*!P>yau!6+WZ+ILS?btYF\Ee?1i6S>@u9cNlE#>ac^H$N?me6=HacH!N4TN6hw1GiT*/<HWy
VR$y4V t@8CKT8G%E!kEnMca%Vll/t&Q*\DQ!XIKy+DjWlcJ+#W4%^*M6My>KSnliwR$/q&lFiip9hBhZ*ZhQN<
8*pijS a6PXZuYa6hI&YStY9JV1YW/uK4LnBWHnXSANhNeaRZJ*!6CX5JD^tR\d/cBVQ?8\pAnu?AI@9i4PZEZG
I@Kt*Q yudV$Z4\eP9D\a/M#b6=HwGm#F5>DC$#Fqd<=KGF%pT?P^>aV6A/H\C?HjRbLEd1XV4XbDKmu*Ib=%:$
AuF\Al t!ZH9/46tZ$#eceS>9FR64*qS>qPaa5?PhPYtGFkTd1\aT#RnIqneMilV#yVy@JHIu#P5hBT%\5y!QPh
h<F%GK @#LlBZ8HmI1wp\>l=DRwV%kELyLD\e?eTL*HiihB6aBZM/Q$/V6?1WhKPh!njnR8t5p9IpmQ9L6dka&R
e\jCDV *PWe>#$?$XIFPJ$i\6GLaLEaS=NZuuhwW9ktly@I=Cm:y4hAFdY16cYJaQTJVFbK*8I9NZVuy%51=1*W
/:!Gmk K!@/=tLRnhebGjY84LS:Y#TTJb5aTqjwZ@cTN8W>9GYpeYCjXXP9?WRL9<tu$K!BM:peS41ZNlY*mB=4
R4j\MH Pt9qyPdNhS/G%W*$X5QiNJp>R+lS<bA%\&6YyFn6^DnIK<8$!Ejqqem4>hkmW1MedyS1LF+TPdN5C:cK
IQI+ea Ym#&cY5=NI6k@S+ELCFiaNd%*&ZYF%w5^JTR*#b>/=bYbHL*1*84F8EuhJYkBXhBH%pG>i&wJI6H<p!L
*uSPHe peeQtyH$HK^GHXtqw>Y4n<jeDuwLhN&bbGbC^WNYXKw!pV6n98F1<M1*1G\m<G/4K6w\1^>%#:HMX>>a
1TVCmk :TJKRlKLi#9&$!SB\ty%kbZmhDaJ5$SPaey/&=8n?VJ:A56Xd$^QqTbyZHIk9YklViq>E=iSjyR@XhG1
H%XXyA :T>c5wyp5KiIyAkN5Hc$j%p9#M^mZQDMa!D=NZb6DZ*heFNwn:B#5=mR!FT+%Ec!EFll<Zp%^MYu!E/y
Mq?k!R l5taVtEFaHqDe1:G:?59ncQh!Jq8/1eM4mmMpmBaL:$*c8p=yYTWi5V</dF:RB8BQJHZE*hDWN/<M6tc
X:WJmq WKQ*k86EVAI:Sci^jJKHTBp!wJ&/8PT>tD9k^^lW:jcPa\:=nhqpbaMdCndjBC5c!H%dGN$P%=qG5E&q
+n*HRN mA4i*cA*8XJQFKDYL/l!1LXyH?Ie4Q86nc^#mYBm>*Iy=n1MF<N&BB^j%\S#BA%Z\Jy/J=%&H*baKM*$
eptSGL LVB/yKhSFM/Mh^>8b<Ccac59uqEZudLGK@Dp8>et>p\9S8yL9%iI<p51c+HnMbe+\>\SueHY/ZA:ZDCC
t@LC5l Qeyu>Nt>TRXqc+hja%pi9:pW^qt+*#a=ZS^VpM1Np*FH<N9d+=8M//Q1%clW5*lct8clQ@%An8=1lYp*
*%CEyt dk4=mnJ61Zu:Cp$\LC:N6dcN!iTVJ<i<^hP^H>>+nN@4jhZjVP?SbjkJ/b+b1j:yXy?%>FqQuqwuJ5uE
JcL6\p KdqI?nHBlNLMtabV&B+AiLBRt<e$9CC5lN>w#1:%yE6#k#n%/py<HjJ^*qFn1P8CtJ$1$l8My9R>q*X+
P81PMR h99&wKnd//K/5\\9^\qb+G@!YH+SLRMPFn+B\!5Ft\9k+Bue$TYV+Ay8j&JW=C>C:Njw%QE\@bLV>j*P
lYkYRS nmhKIXM=F<=PputZJhCNZqtNAeR%@C4:ewFynIKlaeR>lFYED>yVMHHV**h@PWn\ljID+#u9Xy<>w*JZ
4^Cj&m E$cZcthN<DaaFaV\SId!Kj489ZE4dnS>?RFJ^^=*iXYNmKhnKli%$a:9mme:%6Yk*jH#=&lV/YTtXVR9
>XliVS ji48$@dpA:$CW%?t>:n=E+T8^M%#SbuVYK<<k8=#I8dQTunteQlR>\#p@V%#!PIn*P6J1VM8wBtHtW4Q
!5^B&: wKP\KmX*%&+FTCmw=$MNMmJph4kqw=<6*hcpTH$RFkW4X#!DDTGi&@6uA?lc!hGEIWi=qRj8+b/?Be:6
BM5?<8 FNnukmlpuD9T+?dcpH5Y/I8!15YumdT9%XtFbC*u6a+R\PyVQuhXTkcE1?k%V>X#^TDHmlyBBbZ:<5HH
*QPX#G bRTqHFcN@Y^nS&*T:qTYCV=Aqc!tB4Qy+dnJ91DDpX+D+5qFb>+6>amIMh\NpnInNF$qbe!+S$kHbnm:
Pn^Q!J ZIG<FBQ1cDI%88Pmj9G1t4h6$l8YhPSK=AVS:mq\Jm>KRP!4+CE%DyTiMQ^A^Jd&Thk+htuayQ8Wdu8p
Cd*dI# TduQ5!hep4Jtmww!kG#k5%nyV*Jd$T@%\i/&CbuXtE/<Ttc%BL\WhpG\+SXnVny/Ie:ZG?VqZ#ahaYG%
m?>bKR k^dnRDbAdj1NGE+TuQknLL\T4Ey<D#=\Q&l$L4M/RBbkH+HklB+=8?EbpHA$w+1JVaHnGYBQiVB9W4l6
>NiFPY SP+hY*Whm9L&VSJZ%=+NXaDZLaAYK5JZliyHbwWNp4\ul*SePVuptK?nMaJPPlp4?ZE/5XFmqG<!!AGB
yER#/k ^KIYuaI8E9KcSG1<N\j6!Iwb?8>Rl9T1EttAiMt#iNdMwNMlP&FHW!<=V&!EI4$#t!\P?apQBXX5qVhh
1\V66V ^IdQ9GanwwQ5eej<P%pPiHw8i$b?MZtNQW*891iMQQt\pVW8i=RmEZcZ&pXIw1nD@bukWN*<aM9T^&di
6i^B1> Mwc*TY^KIu8NH*></uQW@ykVbLZLWHcP4KRuwFSWVdqCa<tS%NpCwCIV4IMadq=H4Rea:q>n6<58ip\+
Y8=X6i DhK&m/58FXRB5HlFpan4LIjln1F<d!ZhjQYc^t+SPXcTYW9w=mD&QpweEDH$l:*DH:p/j#/eM&=!PXMS
&bY<=t &PpEw1=%*=E*<d:aQRwdc@kCEKIpVWb++eNmH>>$<R+dh\/dIS$/!HwSlX</qt5=/Dq64k6!nNNY?<Ru
/&:T8c #qAN=9&BQlw4\JCPYh:&/HcmEwcNDXBXZ:$cH^!Kqhjc&THD/=8jLZiw:>@%Yi&WG+Zydlmt+y6+Ye15
bYYk#w N8*m114SDC5S*C5jk%&kCV*FnlDJd%/^u!Fa8cHbuuk\F6a9uXpP6XaM1V4Vqli9iwX9lmbm#a?6YcJi
6QSdWM Qa8RZ?$#RpDBjDwTYJm1wl#G8eiJR5EjyJc$+KQJ\ZPVp56iiViicy6i^IMDymnchGXlX1#^6bVPqSSt
W>YSyu #/W^G^/KE8%1QIVP>&h+P:8jJ^4Z%*myWRL+XA+1Q##nG=1<B1P%BBy!KGJ!Pa=W?*i%y+V*D<?XNaVW
+H<P#A TkLB<@PpQVlbwAq5Tka5S8BT><X<\QB%qj5HN?N#PHFe<twM/R1^^^AGj9?iVm\beet^Gpb!e?%<B\1w
VXt8wh tnV9@@WR<18m$jt6h>mb%h4^JkbRw46L%a>j<NPFG=>!u*\8/@//y/:ucK8X6tRRe%jQV?lB<1^!K:pc
md99QG tZSHP8E9pqIKK*e>iKyB5wCtp89<4K<*KR9jjJ/F?+?wdR$\9ZGRblP!BVJH#Pdnw*4H5$kZhN>TW8MN
>*jV+? qkXy#/@%Mi^Ba>+?n^e4AGWdK&^H!b$4<JDC#XBSIy\4GYjNRB/:!!yi!uw9^a>D$em1mcA*MeZX\hE$
DpJNLI k?q!Z$54St:l!6t\<nQTZ^:qLWR+M!!9R58P$CQ5F@*1tcTL<:JY#Hak!pBl&d+**%jVC#WA9mME:lQH
K%HJjc enaNG!wYc$I!FI5mh5kcHG5I4LV$Xpm45pHXu&j1Nt*5d=y/G8cP8k/NHC$w:lLbBwKtBaC+mA81MC$@
>4+&!V >==TLZJH+*NMMuFWCktZQ=ue$imE&VNDRV$*iu:udEm+9!6IV1j5AyHJcXb=*n:C=?+5?QDe%E5C/:h=
bemHu/ BFIn^JZwwRRNG+<l&1eyCI:qlk?iR^#LCTqLHEQPl4atZ\9e%=!CQI:19l$Gkij/w\SN>uhVK6HblL/*
?q*SLw bR!6YYIyA*F%jtMqmn5y<Y:=Yqe^baeWTw!FbAAKkL<S&ue/Pn+uP&G9pnVM9KFJ/&B+pN+C*w/y9+:R
SYHBBp GT8^#q\*E9M@h66FPVwciKQMt#t:I!HBq\P<p/I/@VE8a9YKGZ9XAXj%+8Q^kRSwFcQRAW^iyEKA1C5M
Wj#FVe p%DyTk+d9p?HQ5wN^&1lSYE>p=mY<cj&Rk?L/iRQnTIPCnR?q8un&6=VKtMZ%PANB=MB*^:#D@iW>#$>
aV%w5K dj8<dRATi^pt%^G=4RKk!q1j#8MLK#AKS#KR6tnG*p!!P*#M=Wlc/&nM===ME8dJ*=Zk\T@MJji&NDlR
aDcMyn <hjHb8eWFT&?AScF4Lw*T\>hBpCImSSQJ@W+Lue6%S@Y!ylp8&<aNJt>HAajFSt4R^*ZpEVGESt%Y^ml
:BJ8#6 <8&c@JD$M!T:hHy?h$q9th^<iC58S6GVb!=ikCdR*n9%T=$1Xa/q@CQ/=TI4Dk?W\/4SEeRL=\q8jGNZ
d\aD$b 8tbHY<A*<ili?ikVDX=pJ>DI*:$VEAG$Ddkde=!Fb4!@C\Kj=a4*bdKX:DlSh*TT9nac4a?e#NG9VPbc
V$t!ZM 8T$Cq*i1yM\$Vp?$R#Iy*6E5l\K>SGH>C6\ZajJjt%#ha!!cB\CTnBp1mbE4np<:5^t148W8<Yb8byQP
<\V*I\ =T\lw*$1&M9AFm<AIwLiAXH!YH6*%X/5:1CWbaL:DF+%GJ<eD^@Z!8XTNJF$B6ZTB>u6>Bcd!Fh@k^Dy
h#K5RG l5Z@P9wtiunl/*u%^A^!w6<SHN^!m:DjX*1W*>DnwmR<wZ$Xwww9R%1X/b=?DcJbQLP%M#4nKS?dEXIM
9nXZcE @HKFN\1e#?JlWY!BmB:jQPJK6AVjW#n/6y+#w^b*luVpiFA6y6ymy:MA$5iZccu+Q^tY?&RTiX?@\aDT
G9VWdS #$H:BeQM*VLj#TYVD@X:EEV1!u&H991iw^l*N=WhWieidE?cD&h=pu%uC1=mM4M5/TGcM@VwC:thWDZ^
>nWBBC &TP!iJceN$=18uAjQGq1wI+>TIZ5RRT*9#^FC:#1bX9M1kZ&F:iS+=Smn$=B86D^PuybJB5\i4kWF5%Q
QHQ@a/ pXVl9GX1b/&hIj<>ai5Bt@E$!Pl:XpY8L%\$4\6@t1R8Lac:*Sp!\/F>kdH%@QJBCqK!cX$KR6@^lcH*
&@CYHj Eu!!Z!$cRSy&TETGPmMl<BeDZIlDiTK:\#ZkTwAu9HJ6bY\t5@=&IF?hl1C%Zw?ZQ:Tbbb^Q@?KtqeVY
&59pyV @de<mWNqQhpqpE5TQnhFZck>cAaHWdGTS$8AL#EABpLBMl8L^qHZ8Rjm?kqN9dd+NV$wV+^K6+5pG18M
PawJ$9 yWPq$kT=A:GTLqDi?!uA:yCbeESb&ZQ9d%>@8N\Eu+VK/Nwqma#6yK*NKZWHwuT:!%+!V%ZHcY$yPk+4
<6$bb> *BQZI+V+TI%w>h1Z8mDJ9<!aVLBKiu<LWkS9DpG:y=GZt1Y&Hnd^Hd5X*\j+q\dRc6nkQ1u5ScS6JE\B
Vl#Mw* c/Bw*EqL>F#IaT4nNZ:6\/^WI1tCa?^qPQuku4Sm^yVaTRmIHmEc<Sa*SaFlAJVpRNm^ai5&C?4ZwJQ^
S\@h=D tC!=!cTIjnE*XNJLIqL=<dEyPiGL\Z*S$V:QeiHT4BWSZ:&M:/uu:ZjN9t$HkMkyaHe>u//HL^FH?1dm
-ADhK? 0007dc6cede00110333 Page 67 of binaries1.zip
L6QmC: /+pTpRE:hRNyWRG?bXX=T::Y/^<4\Hj*/5qQ@aEHk8Zp/heyFZI/C5cBDiFchcMjKS>PZtwu^jS%@Mq$
:^RCS@ jAV$j&8%HjE@X<=G@V=LGaZ+8?X5%B@FJTMS9!>uI@=8PS5l?he5HQuHp>WS5L@BR9>+wBAC@6e5DQdH
NVdSnK k+\RmL>tJcZ?iL+=A9p*YPRjq?<S1L>tJcV?lJZ/G?!jVLBHR9?c@hQTQ%L<d=^w/B<*QTAq@k85=H?B
LECcCD @S5dT^L&^!<\E9=jaBH@BSd=h#dHH!5YJP1@\Q/hnjZH?h>IFQT@\Q/NjTYB?PN#lbL+L:CT@\Z&d?\4
eb&<=V Cjkj1!#W9!Sb@\j=Q%Jb<Q<8!X41D+ISWH?WbC*=n$j?H>KZ$5a#Y!lIle+qLEn6YlbW8QuQ9IZ:uy6i
*%XkVW QCN1QQI4\j*$51nB+n\IQe1it$1%W:j4E/J%WmkK9PDq8Y^>1+aC4&A!#$cH1kjbt>%PFCTG5\RybVBH
G$dHGw nFL^q<YQinJXnBaFq%R+T<eV<$h#SZ%A1SE+M\9GNNDX!$#J^*!/G*@WXX<1Z#RIEC+KY%/KJ%JbH5TH
1Xe!LS !4ZA+18QLbu1*AJH/Rb1Ct#cB$NVLcCNFEE:#MCQLp\MiG?c:=\+c5p5P6KVYE6cSH\DZS+QSkK&lW@T
Q\J\nl 9T@Kaj*m/Ala5YuZ#yjW%FTM4Pc9kEpYK4y*+184=Sq/RlWVJZFE#X^TE8Kn*%l1%ah%dk+$b>p!%KqZ
Rmu1Yq HDKnt<NtwW&*P#BT5#jRAm!N/khYM*QY<eI>hX/PT@iu>Wy9!KCL&c/%E>T*>51ca=@hW+Y%%L4eRlj#
W68%lq YB4M?L/WXJ4T@?VQm1:lN%W*Vl6\HejeS1i4<+IppWdGm^#n\\*?YVwQ^PaNtBXAQnpHE\qyThk*5&t6
eC%BND 6%kG&wP@tlqV8+kIXl&cHyPVmFqXeM1Elqk>W%Vu\N^b$6E*pmFB5l6I6X=?EwtC8S#h%ST=Ma\SF/Hn
kB/VVK PGyB6@tL?anQ!wwq+qw%BF^\RlX#>:VyYk^mSa86=lIALd#<*V4n5ani&m>qmlP+<TnQybkeKAbtNtYM
NF$S>8 +TKXX?qkh5:?lDQXHeiS<w&1S@#mM%=X6?Be:4Z#+w$^ci9wHQKQiM/88!J=Q>@&ln9<=6d%E#HNdhPT
PaqGaY 5+t6*CYCF9n^:ntAQNTRpIp@T%mFD9S^htMRKFRuP=HA+B5hmJPy!/Ad8p=!$S+?Dh^E?da^*tYh8!a?
Yn&@qN Hud>1YZhFqe>ENa//Bw9K*FN@$:b$ViQR+h?::/t<41JBj!G>l#d=%lycJDG?eRphdQl<hh<Ypu6lw+5
wDZXWD 9eXyq!Zedj#Dp?hHC%/jjMk^HdbTW+</:uC&#:qt/jX>SJFZW6e$q5F&ticcA>#>FB4VCXI!9S+D+=\+
A?JBwT bM4NChXau&5DFu!IFIBY>&MmHmmQ!Ha8yI^b5EkaR9#B<5RjmQWm1G!%uAE>lmiND<dbnY?u@<dH8WSw
<AP%ZY HV6%F?6Yp5$u&:@SkaC/*yc=P!^*tn%QdH=E4hpb55q5>imDLcd$K6^iGK5i4K>!SMQ/Kp5ESMj=>mqE
%>>t5k kCL>M?q9N?R$QiIM5q=>jyL$yytFLK:kNj>u$V\PXk<qhDhQVdGJTi+ZGQ!>RMLkkCL=:YqJVH!wA#:y
>8kVSX jDc9MDiBYk6iB$nc*>nPAXc5jK!AG=+><JHHaF@ml5=uL+$WDCNX$=1Bl<L:N*QXdXK$pPy<EY8*%F>H
GSXL1n yh!En^Sd58iZ=C6>nA<H?A5Qew!&&uq9$HIJJBY!$ZZ1He^C%AS5Bduq\&&X:n8MMK:P=Z/uD$5pK&#%
E5wS@H YZVy<@F?w8bXQh/TQ$Ah:be=^h&bBX&He9>+q$MVd>Q+$NFy=ke\q#c>RIW+w:#Q#mZV&iSlF1Q\MDiM
jtGwkT T6K4qq:=<JSDM@nIuy#el1BE6miYIpG+MN/iCGdCZ4BPKqa\Ek>68XR#jt88w+/bIXG#%6mHYaI@JG6N
#Eq#yj GZPjk1n4!WTMP^HLJ\$ClSYQY\pS>X\ppPjYDqFXb/V#Su!EtYki>D?Y!HJ+pP@$*6>e%/6NC8hHc#El
EWtLmW c+FB/#JJi>4\jPjQ=5Y<989yANZ48#KihJymiWlyq5cFCp@4+nKA1!!AYJyW+W>cl4+qt9MHBYJCJ=Su
VGA!\a b46NM/<e\ej8RZW::?@EP@9:%CZh+jK^5KB>:&J#MKQaBTDj5NIX5W$M$6LCpTmAbyYW$I54njyjYQ9I
?T>a*k kl9ejh?<DLD$nH<pB@ZZuXh$jP^l@Q%8mD9>@SqJ&MeX#Xi?wbMMWu*%&5hiacJq&Lmmn5jied8VaZ6P
mA<8Ve &ultNdD45$+Vlup/RjZ8K8M4n6cRAwb:Q5:!6<d64ZTilc89jGE^y^@J>%H!EKX+i!N<DP&=!>Tb\qYZ
cbe4qW cjV>t/J+WYHnI=TLbtBAhbZ^ub:q+P/m4:Gl&m8j8aKayypl@FDu8?WC9GJ^AmQl6mjPC&dhbk+5j54h
tp*^5e $+@j4mqdQiNR%#Kyq8TT*u1ZRMPYP$^PM:ZB9P^w/8mlQZJ=K^5>SJqe?u+p/#u>L5w1MVe/=:Y\!?*:
h@$#pc i>Baa!XcT?YK\91>G!EFI#bYk\BbbnTyji4En8nka+biQ?LuaHlh<=/HuMD*d=W?c5>d6TBBtTchL8Gp
u4HL/$ Qq%Ib<H5N8yM/qVlGYc$8wBmhQAu6KnIy:iebm>5k*^RMHTZ1>VC:BHVtTQ@VFjB\G/We6EN%jByE#F#
*I9q!C YRd^/uRS$!IYD%tlS^/Nm@Rb*Mynh%E@FK*Td=cJhm1>Xhl<S\*y>IN<Nhmyaa8p>*:mQllDZht1<5D:
EQ@W&a &tIZ*WbDNYXmANw\NH/Tt<?8\1EnH18%M@Vh<*XaqqFP8@!A$*I\K<Mu<TR4uw11R<Fd!HQun??\F58%
>ylAnB LiN%&:KF!HqZhBiQ846/ZGuY#9a&t/dC>mj^qm#1Y!YcL&Dq<SEthM*<tDTiHWceTQF$tdcHE1X@PJ<$
5!R>CJ ht*G!5pbV@$G@44B\F^XHk?b%Eu99J$AG+Y/mY8#EGjiW*@WuPemE4QV@=GmSN4uRi#IwF@N%G\eYQWJ
ne+I9q 4W+&<C#49E<q/CEw?juLZ?8RZGiQ:PH%Kc//\hK8i16nh1Xj+nad:Bd8&kuMdIYb?ut^89Ey18%jlc^a
ad+e6Q SZj>K?$hkc<aGH+$PMT8ph818<qp@!y>HVj&YPuHLd*9p5wb*$@aY5%C:%iwS\!?dJuZjuA?W1qk?SG%
ICFQmt 4u$b8$?i@>lPY@Jqy6YVmA:4L/b!@DG#NywL<aI11E@Zu\D=95/Pq<PY<99Dhke$VZ+MZhSjyF5cm**+
8IG<ud J#a<P1X*bC/6RX&/YXJ15Rju9@c^n@wQ>D+$bJKVj*he@N=uEZVaqF>KYtHuLKJ/dyN+<q961Deb6uBw
h\<?c? XnX1EZTPmCAZjm=1<ZyHhNL?!?RRR^@yNBmAEC*H%wVZliKGN<iPJQlV<H\=K$TL#=$9^w<*9aEcXihQ
V<$1Xb W5aYQe1/KDp&E@ypunl\KK5Slwh4qiI#\EKR>KR5Li*8$ik=5y+XWkiPZyE+eu8R6tiaGI=W&<y>Im/8
j1e?/I ?X\cm9X<IEAanRPVR/bjeS>CEu%D6jKX1tpAQKSmRFkCVlktc1ZnWTG/L^&Kc+N@bFp4M\:n$jyCVSCj
p*GQWK 1CKyucbjhET1w4Jb+Tq>Q18>:&1L64NXCpqSqu/T4LVe\PE&#Kt$6awu*JAW>V@au\X/P6EDX@*/kDBw
ZV#>%X WymIBMVLEL!=MbkWCMTSMWSehW>=y\6wPA>DR^P@TX1>w@eK61Z&ZSi\?cD+tJYInGE$kF:RG^NlE<c^
WKB/Ju $bRMniAX6VnZ8B\i@=bpFnIN#JGjj/bBp$y=q9:lA%ETM*G!/^65LYmWEHiMmlMk#^*^FE6RClu$*Lej
jE!Suy X+%jSRmp=MTtaEiK+4EHRb98iwi>:6GC^wQ</\YPGHh*%e*n&*Wjd^YaJJX1mVyh@KJ!%/dRm1BKE/>$
Y58QLA j1dMGWG/?B*A:VSKDlYHAD@TMyCKNy?<c6e?ym&Y>chiayn+lktyipml@&I5JYSEuV!qVF984Bin$S8Y
L\FFZt ^&$d>+&E\c6mty^T+tKa#qH$S$+T/MPRdma&#H>RH8MJAyZ4Rpmmapi5juE6/8%8FQC6<NVK4jA+w!uM
tm#tby @CJVnnBlEJyhej+:JJ8>+aAVQd/6kKdjTGq??BV4Twn#S<*S$@HhFTX:FcW51:\j%KE&C#<$DBJ*Hb!V
!!k^E9 61p>%#8L!W5=5AZ6cIMPLJ9/i:VL>4!>+!8:j^LMkkh@+*J/!=L5h16kN6:nX@=ISKA&GS%Pp1QSV6L=
nID6/p +H%y!ZM!R%9qEy?bLh#lS+SV*jQEcdkc^GXADbQ<#S*QH?<yGKl#>abM@/6hHYp@Kb>NEGh94=CaHHJL
ZH?Xpj F6=*lLIVqItR8K?I8q9W$dS6<m&SPINu@B+qA4hVLEL%R*jd$Jln6Sy@FiFhqRG6&*E&k%FZ:hM&QTTa
\FaF15 Bniw1jW**mMM=k4H1<?d1be1c9n<+k/j%!T558S5R6cZqEmMZ9LCXQ91yTDDwJ=^@=1+XLW4R@epu#Ji
ITk%%$ 6J*4>\HyyG*!Z/LnSqFYH<EYa5pc4jQ^1uS5&q6LJH&L:?j#nGq5*Myhc+eWSVaZRSZlpNltNSJ454wS
CqI%Z5 VaiW#C5XLiwS59p$\#wZnbabDW@*!H:jtaSCMu6kib$/VaYRF6ypiGBnZ&lhNuqNbDbm#$$$Z\FPe%^#
w+CYE4 Hb$l&yRQwEd=nMZ4ncAYn#GiDlM1Xln>V\4$$bP&%M:b\w$5/ab4qb?#aFC^i6c:jD9PWXW=j5FK?+6D
$/X\F9 mWH8^Tdjm&Zdyy?Mie?@hb6*yJwV+lE\LCW>wE=/4:L5uJc4R&Gp=^4Kc=h5lQE\X9>PhT^lNSdW*Ti#
y#=mMC $t1^9LAb:wYh$ZF6YinC%Vn1m491^tEZVy$5KdwY\XGLA/Ikdq8wZdCpu%YZu%*JlJY&t%$b:=a=F:Gu
Z!mL\S Y=jJ1jiTG@EADcQWyB6qYaXw1X&iS<LL1PYya/Yq&J%*yeJBi1AYpnG4bNiyAaLWBG6q$tp:Qh+ZAlY#
d*#SiB e^DM+BXGZ%4pGAL5R#kASCl&m::*HpMX4nX=#dT*6TY>#dS5nyT%IF1S@hyCW8ycI!=A\bwMFTWFT!eD
@aM9>% P<PIQE!mSHlcBK=WZ8S#T!aZIne>klR/R4JbeWDdEKV^4dXu#4p<$qZZ<CRpK1q5GB/m+<H:%mQtK4Ij
t1$w$i 4#9RA\^HE54@>D!\Ic$1bY*18K\a@1a:dDWeXE@>n<@aFJApm>qwXi8R4wZPC$+8YK\p/uqdTJZXKKD=
XT<NC9 !bkp:DjmNQmFa1u>mlnHyJ<p!^NJ$ee$!</Z?u4>yue1\%J^>*\H!GD/Ti?AK<D$MVEBNb6L#EPjt^Zp
<1J?X* ?u9qGnEAGX8=kTA>mpiLXBNDeNb!*Vmh6#/u=aC+c&w9+iW!PLPGj8KBNlZ!bEc+pp*S+?p\y+@K%lMX
\&=wKB L41n@8Y^mIk!MZd1@A\l@c6yX>9>&NChZ<$Z<>i#1kl1AYb^wdDiE=B+ZQXqW8IZZ6%4/c<y4*w9@T<@
:CDHTW XJAP6=5&XCRMq#%WEZ#y9E@dI9aW=SyHa9%$6G^?CD1+YLd+<a=8tR69PQH*Stud@bM1Y@JkFh5aEu%d
J5BKNZ 4SC^=dTN8nDDD5I#=RA@+/S5XJppW=!YTqLi+DP<+@N+qP1Vbi@u4WuNBbkHNEc5Bj*l9qiG9S8&Kct<
IIaL/b ^48<9DD><*QubHp<eqN6uN@T>Sm*>h1Z:=aaTSyIW4B%VlSWiZM<mh!>Pc<4w%NV<t:eHKX+y?mHFWuL
iTRZ!$ uih\&%65cmW?m=j\mEMweh4nIVQSklST@LA&E8qE1=/c?XyEn$##IF#WajPl%mi#k6FW=VDXD#XRG^pT
jeW^pu W4yh^ulE^QNaZnlMij1JwNtnGenVAMYJQkH%>k6JFRYceATkHaLJyLH=jNG:>Y8^\6kIHmL:wCB^$#RS
-Aw+hu 0004f3870ef00110333 Page 68 of binaries1.zip
%jb6pt /n4ApP?p9>p/qA@</ApAnth\WTV=l?pZI**AXIN^6+!bq?mbl5#\MIplndJyX=W>6u=GB8*Nk@qF8cVn
4A8HXn mCIH6>RFLEWI=wl=F5B!!<81A+B1tt<bmI=\aett/YHeKcGt%jbni>lASpe*8</uGR=uy%P1jX#h+FcK
X<9PHd LJat6I&/LB?<y:Ha1:*dp/^@CjQn:D+&1^@tu1h+XShZal4ay+=HTpCjPSP?K?un$Pa6JCHRKc&%tJ@k
:^+Hd? Nq+69+6=y6cy/GD!$9Z1\D5uWZN&4u#@um=LNTduFJMMjmI^?C%ulp$HbbB6/Nc%y6RYa5!uc/mCjhmK
kyRVKC Dm@SkHyQ!ZQXjV\!>FMS!DccjW#1cEDLqpBEp4D!pZd@cT*u8>1H>^:iEdL*web=cu*6MP8VjQkp<lcl
645A4$ jKSkJR?FA^=TMK\XmHKLSEXPhlkP!PbGeRy9I#$+n?@WNZiT9hcFJmjSPPPlVhCYKLi1GP8!+&ljNNu$
9BLe+n cVjJ^4HuX+j9EbYQSqRWLNS+X%X:<d85nS%Jq5>P+8!m+6J=G@^Mq@W49$Xl8\/q\@DmAAdFl:ZS&1>L
FZ1<Ti :^c&TmG?MmNNH?IlYH$PH/y&dAlV!J8^l*pSSnE=B:kLE*=:Yj&$4t:HTk*m1TCH=LmK#G4H^*%wpi!9
cG$YE6 H\dSh?5H@Z^u>@CwWW1=$RMk<CF9WJnpRFIb+NF?RL^MMADRX8TRC+/!Hea6^*djH%=?Yh9cuXTZw4e=
!9V6e8 Ee<^C14\G!=IHR^?lcqX\%hGN6IG:1uM9DqJ6u5RWlabw*jY@#GVX?RD#jtMHhV8$S*TW*<M*@$QQLKG
nM@:Pc CqIPTiBw&F=FeN@?$^uT^#N%?cNnZnMep?DJ?a<iZEa:n#5QE<:Pkn<AFZ>dB\tQ!Inlql>CD9ItSh&4
<N&Jjb iqIG!L^TJT6Jpn/K$hkNuZwdmJThZP\=Blq^ATFLP9aM^A9d#PQkBkAbW:BJX%KdeLa*6qZp?VLCk%&>
YWE451 #?/+Cd^LJh1q<XCyJ?qKTV9p$JJ?9dbA>/Gl?W4cFE94>i4^8^Dic!5*&kwBqiG^GW5TM$u:6wt:?j46
+Q%Gad ne&uPlHy=:Q&AVcQ9&uLj/R/RXm6#wy&twl5qpX&NIRcVpcA@K9mqniX$?4i4k!YVdc<#LRY9DJ1Wiu*
#J<E\$ T\8QYhY&WMGeiELmSeejam^ntZKQGia?:?/iFA\Q@nJ*A&J^EBDePw9I^AYtI4\d98X5GQ$5ckk<1S64
S=D&b! F\Gittm@&!n1IHE?@4I<mJJQN/BC5F*^ic6BGnDG1Tp!RtJi:1Gi&CpBB6DhP:E&8LDbQ<eZ<aVu&WNd
/K&MKa +%#:I8FhpeMHNu4KY1CZMeb*XI>yuWEY4:SWd!q59NhS#H<m&#XH8B!B!N\8qdCt6htwlKD>jbRH\VXw
KEM%pR P8j>GQlQTY/K*ccFJ4$^\k>Lt5FBZ!VJ#W+ilj$G?b:w^&Khk54/#WLqb/BdqFJp#!mE>ND!MLCIu1@1
BebP9* 6aYKC+9Mh/DN!Pipm/DEi%nR/ktw=jAV%c&BVW^p8#$Jd$W\bemDh<ycqc@na5$4St*i:H#>wdlnStt1
?&ahK? GLdw8i*=J*aRlj#jckhS1Q<yP!n%?+^51d?hpT*%l>ua1N<LA6V9M=9@&NJJRj?c@dPGFTu^9&d@%FyJ
h<Rk!: Tj!NSW9?ebXjT9J9LB4^^#bF/q?nmqGw9/#!w@:j<eewejHjX@tq@mC1GCE8Cj8@DT9@D#T5^Q?9dXl^
:F&:lq ujquXEuWLDB??iRRD>+PaeI*H88#Km9A\udd*GD!Zi&*ZVT&kJw884MCF:d/hBCmmA<!k/G8q<nYSw&Q
hiZwC= @IDdHSkG8IaK=5=pQE1Q55XuVHEY/Q5J!nybh%hGGme?=/aAIKL:>e<YEm<Y5WLFu$y/e?h&/:QNE!VT
%>LEFE djQL9jP>X!chh\*m+V!/!&DaH5N$PPtAI#K?&^ic+Kim+:$5e8^pQ?AL%1SiY$mjjN5!!!/mbVDLXqbY
AElW#n P91hn1&16!AcD9^uyEue6ta:%E!E5+wPhFX%X<+$*qX6X5?ZZYcn>M4Q!^jipY1!Qhp8<8C&>EMR>/1S
<n4iIQ $T9Wiu!+qkYhhiBdk<nl\GhGpSQZ%jyM<l<h:hp6=tVE?JCBm\LS8!$9HGS&c@p^CPXq9<ZD9iYDLiq+
h8aB5F caQ=Pd6XXlQ+XKBLRNYMTBqYS1>qY:ZemL:AbM&P$X%\dke#/CG>5j^M1HA*W#KWa8@lkW/VySYtkq=V
Bkn48P hbJTD=Qb+6iAV#8*wb55VA6dI&H4\VDEcYb!9y%:!+8<yjjGV$F/mGGHj&Y!/LtMwL:+HF4lI8$!ae:n
ElI5Nu E1!$54h$e$RJpaKwd&<6#lw#uX8uP>c%n9?A8>9&DN:H:5iat$jub^y<9K4*?HW>n&j<C$jw=LiJSJt%
eWjP$i Gu&n1<:HG^#HL@mXGeQE%y=P4:RV!i+Wca:Mt\u&4!N6@bj9X\jD5Ce#4C$dM?\tTIV:T@jdAZcj%+9=
&9h@ui >Mi<6PWmn54Tj%Bk11lRLBtITVN8ZyNa6nXYHyuciY/wX6XMew<lTn8?>@MDKpX^Ad$Aeqd9IYXMFTP!
>>PXTn 6MMy@qlGmw!@1y*a%&9mLcNklZq5D*<Me+dER/NI#Xa$Kck!*j5?Aq@c@>yH$Q=NCFIT/+eIC^t5%:<$
IGIu\Z 5HGTet4SM@GmHYX&y\Cke^^*LuReJd&hR=ZEDA^BY:M$&8I4:*LRM8@iNL+A%@:ecja@$a=*>a%$qXdK
yGndNy cYNy/W9y$*Md9eHjXQXeK!e6=e&IcW%AT?QPGwG^G%mtKJ*Ja:XCE8u6=D@pW?cW+L!iic1^Yc9E8/#y
?qSCN+ LPJKh4I?ZlFZZ>Jbc?BM\%1^<qAA*Cim=@WbQN+yBb84bnN^#JDw/CeQC\*@Gw>@\wqa>u*&jE9n&j8F
=%*Fh/ P:pla:hybXam^%1aC9$DCM4Zm1^waE!=K1^MZN/qPXcde^nQ*6/*?1?hkiMdRQ$:BPHC^mwT9JSX^mG^
T+JX#D ^na?QBJQRthJjH$Q:MqMw^iDGuj<TNu8*C8pj5k6HuFBVX@BV%4ZR*jj%@jcab!twKCR@I*JI=4NWaiH
I=66#1 6c$N^a/l5t?@IdLEPiNjjB&Xy%LN5yK5W!>@\PFPd<KwiaXuVY*AMQNSh=m/!4cM!=q!9XH6TElhQ5!N
R5ZlK1 KuFl8lmKe:m>Xbnty+pNS=it^&5DpZnu/W:^8ycK=?KKp^=dKa#QCYdaNW9<BJnq+*C6H@*dFV?:<>Ck
G1Emw4 !=S9aFtQ!W^nKq8cJJ=MQYnPe^PwmqCwmyuLY/=\4l+Ie=6Kd!<Mew/AtP9WjJkSXHJ8t8a!kVSm9FVk
Xi#R1h Ibm%$J^Qi8AL8iw4!S6#/=/IqHE&9l!=h/!pCL%^M?ab%m!&5?yL$&SbWhXQMqFt#%bTc\G/6h#HA1Fh
PJ?aHQ jPumLIWd!4Fw$hC!ZM\9L+5:Ww<LniF^9CpA\bG96EL$EmA*lw?1AY/Q5NZ:bbwMyBbab1lPm8CL#>Kj
m8KL^N yR<6ei:Qj4RcWZ@Z5lW%E6X\A\tA<%mZLbLwQ5PTWe#68c18CRqEb<wLqG^Y=:%il!^V?XKWXLuKm8+<
^!#Gyj ndJ^@A@yI>FW8BMadjyuHVu#Fl:Kk<KmE5>%\>\j46$49X6T*yQtuN*>Ce*e%1M*eDR9GXbb9S@Hidj\
hP+i<P ZJMIb@6+VSmAD#pLI:q#*9w<Tlyqcl!\Pb^?W:WqaAHiaFLqKuN@t>\BjqQ/Kth^?l15G$HGy$EHGKDb
upjhIh c!p4XDtb$ywcTauJ=nq!E#u!:PWDdi:hduGnjGGIn*L9i%8Nu/&BT?a1=uu44Hhnd=Sd+=QYc<><9WpE
=Jn\Z< k*1eawq^m&#S6nWVYjlnk8?=+<%K5!6P:e>5&<^\Dqn4F>/5#a<M>1ZFJdZ8*wPq4:H8P5Jkp!%#6\%=
4&L1P/ /a=W+EwQwm>dMI:=jm\%V\6KN##6LlK4mnK%LkPj\*aT?+RDTI\^>FR%<ShP4T\S=cRY#!1:aqXPemwe
AWCnwi ud$LJ$\5Zn!n!\aIXk*pL1RVB/w4NI>=ibcu/9b@dTW#9n%ZMMBd?qLL=GWwW4dMYYQaXVMQ9kHR8aH/
Ty#!XA p84G6l1tI1FpR&>S8JSJbkA9HJFKQiJcVq=4tCAd$QMunu<LphE#?>t>Z4/6+Xjp!C?N&b#YcdtkTK1*
KH$CRN ktVN6dGI:lRlF\%WBQ9cl5N>X45/c=Q\e#4yBui%:p#eeZT$VP*?%W:WNd4@Ebk%@=up:X8my^GS&Ly/
4bKpyH Xje65KYaI?VL*KA1Y84>V$y:nbTu$!19GhZbNqn+B4QyQyhV@jS%M+:@^:ZN4E5=#a%P8aq&8$/#&FSA
!8Q6AA uD^PYbeE&M?:H4d+:H*9y%jc@Tm$?WV=etj6T&%B^jhjZZ!kEX1X@iqeKtGFd*K6H9XZ&NLKp8Q>%\jh
:Z5<NY pi:iAIIw$1waHi+nmlBMlCLK6e!:i&!nqPKL:bBTlhY5nWy?ne9bQJhGPZCjeJ^qlQiJ61C@LVF$Lap*
cAXaSh kV>DhaL\JjbeYTD@eW<aGM<FSAMhwb^SI5J/QS$AKNCIZ^GeBC9pW<Q8TuV&&Yp%tLqNe$jHKDq1?V6P
W+M+SW S>k&wB=yDMJeA<XXETY&Cd>K9@EXjdMT?^^Q#FTNP>H4W*!4JhnltGR*twG$T?19MD:RLmw=hP+n&HT5
Ww6#CR I^+4nWF5i<+Q+9Gk9JC!FTCSHhI&RX8IkAjI4>i#Ga5>$\G^R5S9imk9/\8%cb&jaiw8a11:R/ykna*e
yCCL6e B>RMKijjNLe>+hCh<u@<46bB&a+lpK=F\EatDFdjP9KZ56!tPat8jmP^QQit@GcKyZbT*LnFd/PpY1ZR
m\Q^<@ MX8N!dJ=c#ju>IGTTQ6\G9/TN/w:FnG?a!wTFXbJ?kI=?wj=\D+V?J=$Qn:j@Em@5ISdd<B*49?#5q!c
pdh$GT >td9k+wY:*AN5mT:CwAmYit\&eB$NHBcP!LLR1hJ4/eB+jIJAJkHEM#:iC$d:B#jm5GD8P!c$QKbjTwi
AVi8hS G1An6%9MTptHTjJPbYXkZk$HJY!MuG8#4cNCkT65TNTI\Ijh&>tI\C14<Ri5J&cXIt9@\QA$Siuynln*
Tw<F*c wI%:tj>dqTLEibbTKb8i6^IYt^bK%aW9&a#p%XWnhV>$AQNV8d99yjq1tpX^Z/TZ55\1!X!F4QC+!K=D
<C\ZXZ 9^LE1=BVcVZ8&*MVRb<y56<ITeG4=*\lJ+lRW=\p8e9KLTw>H9K!<nMEECK@y$tkiA^N:tyVIX>L?aEE
8=XwVT #yDF!LyXZ9MT?=cQjPuqc+5h4pIC1AKQ9=WuQTtKQkhYC@bRjZqV\aRjuBcPYdNPXa9hD9wCjEjJV=^n
cD!FFZ D+qV@\L4V<1j++kml?TWmMdPuPuZ9tM/HP?+PI?9A&%#?:+ZXCaGIIp*5jA/LWSM!JTn/B4^=:jAXV&T
Y?B?6I BGh%Z4&=GtY>S8K?=D5+?d%p*uulNmRk1Cwt:mZF1ui$cF%MQK5Ecmt%DCSeJH<M?W^>>*byYedwG#bM
pPP^CN %iSw9LS:NCE8TQn!P>p<Ee<Xt<iBh>Ji$@PKdQti\SJ\QGGcVPw^De!#DJlt^J*GwM1F=kapeP%jFYQX
DM<BPB !numm8%qLuXB=&L56^K:ATEqQ4:?^#:LKpKnAIL<a#6SbTAi%tNTdP6=$WK6qkLudIqZXWaw!&WWi&?i
bSSbKd !Su:!%iFJQReHYJ!RGG>qTyt91+iYn$&P=j1ShWI$S+hTEc5=Mp^%nX69%N=?KLaK>>59ybk@mX4jZhF
1K^HNe *T8h$qHD?VaM1PSWYDBQ!>*+/l1i5Flyu/m$dhkQ9/W%Q/^S?qb$qIJb:kCt%1>R5%yP8?b?&ajGu$TI
yy:6hD +\EEEWe<t8^n&XIP!S\jS%m=@MPP\G\^k!Hmk<hwL!yNHdVVV:b\i=RKlj=IXGL@==RGiVTSA$NEaLV\
V#6Vah nNK=QKnuKG%Bd4LYAndeEG6jdp1WaECq<MBV8JYTLYNi%<S^^@HEmVq>WnXe#+Tm$X\Wc6c1?DYCdhA*
-A=lPD 000bf4e856700110333 Page 69 of binaries1.zip
CeNdei Ci%Lcn++DB5=d!!qT6>jC+J\L9HR!c5?NyH@hpWeMakdHBQqj#!b6GYdpX=&e@@W\5a%1WlWPBy@W$?4
+QTq85 ^bl@S=5:=H4TeQmpbWTJh+81\b8Bi=+$+X&DZVa>19heZElCq\Sia*Ft$%uu8F9uaDeZGJCllQcQhTy%
*j/5\@ ^M=IPQedK1YnqYI/4eCBV^mAQ^JAej^$T%EbH<pNTQinVpRcRD$dV$m+^#^@$?bq$t%qGmw:/d$<Q^pk
hH4P>B V>:eh>tNCB\cDlHMMI$=RhkQtl+F+n?!RcB&lkuekeSGbqHT9uFLAuF4&+^WR>M6!qmtS>B4LAC!9*Q$
A4B&uh CLH/eJSYhJCCYZ9hHi:wyB5CTnZ<Em@1lFXcJ=m6JXXeFFqhV5la/j?<R\Wy\>B\e&pL+ntYkJh?jDq9
kB?FA> ^#\9^\:iDH4uGD$T>p+N$M$qH+q^d>LnT5@tct4:XHcY+WG#WJ96#?9A==^kSBTq=%lKXP9u6*jmwH^Z
jc&nwe 1nyty6@YlbnNX#BRFX#lXq=m>9pLiLQ@eZ&##VY:L#n1&6Z^>THdSjJ\PbH@Vwu9#5/qeZ?+maF$^lmF
6qPYZN X<?aV^N*F4^YutSSb+\qRQA!$Blkyd\#YV1wKPTB6EeFMHKD=EcLS8m>&#=R>@?Ebauj1!X<QNTQm1LZ
DweKEN X&8:Q@HnFd@5/ei:<pN&n<kji6k?e4S=@ID*^@/P:&V4^RiePHX@TPk<H:YB+?c\jEkW#Fey!n5V1B1a
VLpt1Y j?4AWZ<WtMZ6h^iqYHJ8hVBQH#9IF=P%YCbRcRIu+$89D6=/dJFpu^DF4SwaW:HnG<+XpACSS<S+JR/W
5ClkYw !dh4TuQJktpIH\%iyd1?TYY!^!i&lEm1SQ5wLcidFX/V1pdF+FS8G9EdTNHKN9c+%?F9FyGT?PkJq?p^
n4KA*n w1SWDbt/DXL9/?!TlCyNntkTKhKK?l^XkXdCmlwJnKVE&AK+FCpQ9qKi<IWXwlP94JKtw1LIR$G\=KYC
DMb&y# YEX%qP1bQqiX>ucJEXGNV9JR:QSF@+^^=>hBbHc*?@TCp:numeAJwGAS%ET8#jeGNtGS?ZALXGAc5N8l
i>aGHb DViqtdXteQ41LeC&h#JEI&+LFlinS5Kl1lTWp<lmL*=5TnMZKWY?8EF/qP6M+wuq>FC8!Lc?\!*QwWA>
lHpuI5 Bj?Gn?MHPpPFR4qBqLa?BlhI/l?I!Dj*1\NQDR\p8E^qJG\Ch56V9lS%aD?apm5tI&+GyPu4Ew\b+Z\+
TeyiWZ mp*t:i<cauuJG9eNG<j$Iw+jnFVN>ticG:#JJ9aXK@C\+4CCBD$BENTN1bbXi1l/>*taTZ=@AQi\ku?X
lTH^Rm GtKNe4YdS*:GlL!LbmcLGil>RZ\eF:p9weSu>cE>:RPb6iIS5MwdPMYaVd*y%1L/?DM8WhQbhi?JK!5H
I8L&Dq yawH8bT&w\Bnw!C*&ZbpIypGpMnjCGQ<Bl@eYKKmnKN8=\iE^ah+BM/4QCT&ieTEmk66#NuJ*BFL%yy4
y@CTDt @Kwh/?aDXRlRE^Qhy6IKt&D1GJ/PX:/bQeRQL#nJW$y^w$9JJm8KntWZHCB6E?QymBuMA1m#Tw@19>lL
I9=aNM *&QK%Y\%c:e%wJSJuk15Zd&\utNKnt/5ZHXQMkMi>F?pwRZpK*qiC+V:<lyt>bq&V+5aS<6AZHkjy$qS
u5w8JD qZw/66\ZH8q/cdSb/9MN@8LLemK:#HR=F!:5dA&Ia6S<M4^1*\B\GXAAHCtuDKky%ME<!6&EjGEbi/mj
KDkpu> :X>>iB/XNinD#uPY%4IP/%ewKEVN%9Ih*PHpB%S/R/dA!L6GR/>4wHXb$5<mwBTFXI+XABd!JJ>SSptS
5TdEF5 AEp%*n9ESF/m6p+!eBEi6piQQ\^&n?qlplTt!BNV9NJWK>Sd&DLFn#DZ<@iSK&:bWcn9WkWSdm/tmt<A
BI4^yZ =%*A4:EQbAJA>98K#EbmeiV&8JIZGk*/=ZmltE*dT5YQ&eyY:IwZNm&hq!^qn8S6uF@Vn!m#A:E8ICNQ
eKypFl NYw/^>cq+Y/Qq/k!kSQK8^/L$d%8me?qp1=jXI=LHt+W#qp8=YnyyDLjDu<wkSiIue%wd!XX%qL#F@J<
PlP$!j jZY@KQd6w94lRtjR>?Ga<HXPTLNW>1lX\\ibpAhG&c:Hyk<a@F>/bc:tFbQIqDFuWN+6V/Z=tmtqBG4<
uP1A#@ wY^!#L:1dy%68l4BFk\bjFpSw$Iqni$@LnnZCnE\uZ%=KBdqYIwthdB!iF5tnXQ>HES&e1khdF9F9uFY
FRlwI8 F+=qSk&::YYVl!kK/p*iWHBE:@ipB8!T:q#A4Ei/M\MhJNn*\nmPF#iQ5/Kn&/FH5TQZVE6:X9Ee>&hu
Rw/DWd lJEDInSh<=LDF48l&@aQl6^EaER&ci8KYW*K*FndAD:\\*Md><*%S\lQeeYnh\54RWwZpIJJB=hd4Fi/
!69mck 4>LWh*j$5d=F^qC=$Sl@JG*9cL#p9I^ElFLjHieLTV+I%5$jpj<F#HGXXj5pZap*A*8L%%c#GijyW<PW
?BT*<d !#Ml4GumZuyjZ!ihT@IdbyeVXQ=b#?9KjWSjm*46#cMS1dkFLMDa%t<\a#Da?J+j!\MXbcZlYF*!X/J+
Jpj<HK V=&q&+hl:a5yDuA*Jc#At&@Z4E?n5mJHk!>I41$\BdWa94ei%?lVb\?<c5lWmX:1cL:L4<bem8@EN?RJ
E>E9=n wI\kIJj%De\kGMA\AKR6KLGD$:GDiFEl@SkZ8nldwI:KG5cdLqbJ+Z=Q\bqVjD\uNyyy&IEyHYTQZ&Ec
yy>$TI ^*kt^wD*JjQpiTR#tHATQub^NqC/t@ddWkPpGDjEWAu\aG*4KZ9bMCm=p^nXJ<cmY!$8VZ!B9B*dl=dw
WFu%^J p*F9=YbX+8#nH<A@pK=@m&b<pM/bVlp%8:9>AEnP:hGwBYtJT98N=Gcu=X=aVE8KLVbPHT<bq#T/:<15
GJVRSQ Pyt5EyE*^JJAD8n>=%^?epH!Rk\@>$%cCnw1^@aXy9%k<j:lLh*dd6\/=k8nJb?eAK>W$!NnA:*9+\V:
JGJqL# 8JqB=d!$wbq^Ep!KCY#8>#Pci!S&B/XX*qZNtS?4Hn\dhXA!%5!e:e^nTnHdLnttcKMDXh$ymmM@pnhP
i8#$dM FD6#>n?@==nCq6qk\+I+p^uFZKB89+<NGbAPqjNtBTT8ipI:^:uPY%FH8nLVkmLjb1mqHhNa/QkQydPY
^cID4Z &nn$5Lnd+SG??IVm*G@mKuFjuPl+QmcbW1FC=a:yyb&Em/qBa:Rh8/KuEmw5\Dj!V%qijm!P/aFydShT
@@^Y^? >6Ta5N#leZV=#uqHhChqw@q>M/YpwpVZBDZQCQHX!=:pb6mt%5SXRS^P@EW9T&q+F?KwTKEt/m5unGZ&
dT&l<d 5=^K^Aeiu59X=STJCS?4FWV<9ACmKKwby%Tu&m?#KWjy8mCujbXuLnu1&$ii^G$RMwy1uM*>d1*$micX
@^^1dN 8LmiC?8DGu&Nb^Lcl/%M$pZ#hkSb*QS9p=A4<Nn:9QN6Fa/d56WG?Ja+@6t\ndqClaI5E^@mjmd<@YEV
D<48nT <Z6N4VNKk$e&*I6D4i4Pwjkd1X+ePMLm<hS+kYtVJHBeml^DmR>XXHJytKBFHLt4+HQul9EY?epqKaVw
:RcTtK tPu>GDuy%c?BtCJAM+N^5q=kecwP=+Pc@8@+?%$jyCR?JwT^eDQqZF6IQ>R!SmwM>+?pdddK$ZHGSPu?
eQhH^F wetTR9^9NXqT!Q<bp+WTq@^Zp+WTq@mdJ85@NM1@!yuj6<qIIj>tu=8W%F?#j>LulwJC@\aL@^NY@K>b
99WItu &B<dNBSW+1>bTcp@iX:J9<H?<bk/FBV&%?!j=MckwQC@\a4@!bwSj<*?tVFERbF@++DFEZ@M@y&NlWL>
w&Iy+* Mj6*N6cj5PJ@a&QB@6l!@66d=L<*qXLI9#TX@>GD>E>VKaH+ucu<6#jw9@anTcAR@<jp=BV>@*%PDlP*
Z1uQ9Y C<$Iu>y>F^+?5eJmm#q<>a<5PyC/wlpCLE!?L\pkM9NptCwi*u8Fd#++GK:hq6N6n^Mcp%KaK8:RbeQS
qDNDqV tZ%uH:!epJPeX>i@^DVjD%eY\NGN#1qPjqL:!k4%JVXqlH9>9M@Z:FQ#\W4:9q^Nm*/L9iWh?FZ\GY!E
etqaYj i6iAXdR&b=bS>=Pu6a1pj<#G1QIu#=WHw1*FJQy4qCkhhXE9Q+t9PKJYc#c%$T:D:@KFa/8CyIuCt$YK
jwu\bK Q4up4A8ckSQe<PMiY$cqBlFd%XEtJ5\kWKktm6Z59ca=jtGijEPmQ59QA:iR:8i?PDA8jB1tE9y5#M:e
%R##>B YqM>jydc@#dhupHMm8dLhD@H44lGLBtD9VZ/q5LCRtyntPMuwSYuCt5qBTNqi4<*Knm/1%P%jZk1TbSD
#c+=Cl C$CW#6E+*/yuJ>#MkhGNYWW9DMKILbJ+4?Pj&HC<<ER%CQHQAB*L1d^ht1pF\1W:m%?+9eLE1P4mG&iD
lI<$!j Anhi#qI<J8^cK5^@4Y=a\<l<*!CLm&nI*6lHMk#/a8PhkhcQ8G?mRQPEM^cwdi+>&dk*Yld6CXinQ:L<
k!ym:I 4P$85e%/J$puL6>9wh:MTdXe:l#uHi&XPc=bG4@=iBh5PiVQu9q</ML$qp@t+e<Q4ItDLp<YuD^Q#n<w
+Hp>lG d^Ra@9aWTLbI%P6!Q+FM*YBi^PwFi$\hqGeiq8Q9Ydlk1/Q5Bu$XV1JaR=?KF/55dBR8bVnSP@D#yWBN
pIGN5! XDSdnE#N=HFNbB??mmlkVbM+F+Na9e4GY@ZjbqpYhWX^TndMulu1w:V4Tk%=CE^McA>WJAVDKBF!!*&/
Wm6hd$ N^#D%DwaI?VKcWIX6iG+STK?*RCA*qEEb4Bq1cLM14nAlVmMw+k8=\5Jyh/cGCL?$%eWMhSw6Ild8BDW
+M%<D< ZP^aXHyDVq?bw@A>q<$G#aNqShIGnYdq?Titm#HTTqmRIFj4@S9/$/+/>w8*\ldJ\IaahI\1QWd$&6p/
T/*^aS d4ZFaJ4\bwtiSX$PY*Se*G+4w$T8+MTnW6^AGRG1XHS@41pk1YhqR#JDj&/ZXn^>wH8aCZYW8Q*CNFGp
YJ>HlF >ltj@^u+RbA@?p$SSWyGKjedSXTe#1a$jwD*l&Yil^dq1lV1/yVpRWTK/>tlbm?<\E=n&S&9%Cw:HyBZ
#=%bwX 8K&G\ZpX?emnap^Y45+V<YS4m1T1yE5*/6JhJMK#Y?#yRc+V894pN+W1@A69l?acXVMAywcHTQmhuB*Q
Ch9&Ji E^V+R$yK^>h$>Yub*qhp^VL^>ipGd5+9qTnH1#H9\nJe8aedqQm^T/uw!LluXRLpSKTd^HiiWDh=qy*d
TH9/6I 9NwZ/5\a8VFehAA#%!l/4A^<>VBembS&jFa>\w*cTT4Dhb>QaW/$/acVK8+>^%LEWLqY@K>KH/DVe4Z+
htbJja <@FhV!LXY?dq+56Xe\%T^SFy<^udNqa^u^*=eHLWm\TT86y5LEnu6tQRY#:=pALEm6>Nj:bH1nBl/Tt?
@N!H!M #GiPN??KqH\P+^8*9<%wPFwD**5RTaLEwdm<QaRlwCa<^?n1Vh5CTP%NW>FXD==eLmp:Q?iInG@lFuQN
Emh=Qt RcuZHL$=X$qnN>Rib%>\6EBX9K^TT#DGBK9H/u:qAG4:bt&iX%8M==65wm>u>h\FJ\VJ6d$=H!YWbkKF
jZdTX* Mq1?Q%cQCJPRZMm4nh\KySKZ+X8R&TcTmDL$6EK>/R<=w4/<WB$4ayCyeAIW#1$b$RdS6?P!^MZXTZ^N
m&EdXj AW?$RhLDjCqH#HRV6KqXet?!YN^HtJ\<JIYVN<&4t:djL*8wJE#Q+L@AS8n!E5HD&:i5QPM!GuVNWNHB
CkhquK CjdI1&^wa!%k<AZ+h5T4*Jn9BHtF>/W#DcJTh5i\>j!uN:MbWw*h%hG8Li+*5Ae1<ZShwlDtSp#N%6He
j*a5dJ A=FRaA8AZ<A?NbAw*B+p4NIJb*lTwVBA/MwCdlT@>9:mMB<a>6qIL1Nn+qq8Bd@E!tF8YD#VyCa=\t&e
9$RJF* XuuY\Mjn59qll:N=ASiK>Pn1$VyRw>jlRH*MR5P?\^N?Z/1w@/#MR4NA^>WA\>TBj?=TnLZFa9Q91>>X
-AcAMq 000477df29700110333 Page 70 of binaries1.zip
*++DPA tYQ&4/Y/^5y9Y#dYpaZ:<aL:SquFTu^>FXVwXTbh1:+T8XVZq6e4V8BbqF:XGDT>M$GTiZS=M1$=%:ZF
TGZjBc 9HBthBEh%k!<E^Y$tQQlp$uV9F9nb19Sa**ql6KnwmdbwA%:6=n?h8^QnjnlWBTu\CnVl1^dKQ%:ubQ8
NhL@P? ^/AVMk>:>IK=lFJ$4X:V+*#j6uaQQe=PE\\1d1%5WwDMRY@mq8mi/D$9kd1w=B89uwyXYijNM!jQ=uak
i9lcLK 6C8?=Z:$*1iG*pI49WXY=5nCBw4CA=S4Kym#G@bZY=FcJ!$4P=eRl?YeaEah>thPXWA6<Lh#mj4hE1t&
tjkbWe Yl\1n@bc8HBm44uwS&HY&F!8a?ju=hnp&^tCEq=9Zt+?FN%PpQHIt:\^<<+@i81F#iVDiTZFN<MPNnP^
TaBI^J 4#!DNk^u554V4i+?C@EQZLn<%uJ1@1q9aEK8iLYthR%dEj/>KL>KbGH@niE#!!VQiw@5wFKuw<X$e@l:
Z:4d1m 8Qy\!Q/\:p9NeXS<Y$*ZKB6e/NWEGN&>n:y?@mIY:Z:JyZ5MXFp4TG9$5^:$J<GML6WT4qPGtKpFVYm/
E+%nZy L<VE@Smc6l8#CXjh/qVkNJ?RTei1&Gn@hwMZkmW+JuTBE^^Q&k<kHMCR8ZkcQ#eGQ$@iZ\*E=aIJalkc
V%N/Ru HG@NJ/YLH@YkHiYD9Im>aq/dm4KpR99NFDB=XPZujH51$1klE1W$aI&#IjtVE@StVJX$XJXemT*m&Ri6
uFEmmq aTe/^+wa5bmc8Mw9&h5Yl8GITlFNEMBmu%R&6KLtI5+1l6\%*hE+jik:BhqdEBcYXyIVW#1wi?A9eWRR
T&hW@1 wVaLQ?ZWG9KZhQEAn9RDRRMp9FdVA@L#HKMkhBC\*\\tRPiuqDJj9&biXnFViy>/<JLRa*V?bHcB1^Ew
@Bu&l5 pE=+hGGnTjBV?D*6ND>/YLT$>tcb/=HY6I%h9JIp=S!lXi?p&\%/9FY?B:Ew/Mt5Y:AlD#$B\SnAVY&i
lqjuk& N?&6!E$dJXScw?Mmj9#<KA@+aXkT*TYynyIWdGRhMJ:c^/d^TVEwEMh#Hm**j^5Wp>Y8bjp<Yje5Ghm!
tXTjb4 dZFJ@A*DI#h<Tu1HCBHAI?hX&1W<EPPpBA$G1IqY6GpQ5uMpd/*ZB>>NZuahTjIV*$pE/dEiJ4*audhR
wJ9a*Z X1XMHuZl99AnLjDt5qnTtZVlp4YY\GRy4FDYJWHmRQFlecI&m9jCim*n<j%YeY$mk=%<$wG+%aenT8Zk
RbH=C! JIh+KRFSIyaSiWuFSMk^9@9$&X6dbmA@@\C9t/CVaXlKQb9I^81k>?pHM<uSd!8%dTCJFkDB9KVPN$MK
NRWqp# &j#nH5N#5^a\C>VN>+98Itc&1IZaiWy#I&^&TJCCeA:j<k*<1kHeW&C@G1id!?B=M<J1+\jkSK69ph@?
t!haFI 5&WB*W/I%ZIp/T:XA5hpk4JtytDau5HkB^K<!wh6^F+^5DHCVHY*SK9iEmG@5a<qVTI\CXM%!<ZGkEKG
+@X6L5 V<Qy:NWik?X*SC5Dd6B1bYq=*w*l!EFuiG91A8%<6=XIqWhN^Gn%*ZCGkd6tC:#51A>dXmGjCJ4XG5V=
:a:#/W e<Wi!Ll8hbTyHE9ipAdY8jcd&Y$hlY64kZ!t+FGCY65m4QK9?b^Gl+VuR&PVbq%>Z*F5=yb%?RL4=udP
F=w=^# Z5FIy#\<Z%c9h4YRh%@P!Th1&iBJaX!<BYk:/$VjF<%Mh%M%4MIJGpl9*IWyVe69pBNpWKBlbB\FJjWJ
G:S4V/ 4&8i>BB?$cjaJ6!F1LwpTmp5j^=L56c#WHLtjc4VVE*lS?$n?$tJtt!TDQL^N8V$BkE\:i8R>:e!9J<Z
X&V!%L N5BYN<1DZYY\>#ik4/wI<eR?Y$&p4IhX4:M**%&laFCb/i&+W#W:P:6\TZyAmZQ=#ZwSAn5KY>/Ti6/6
Xnm6nA 9L5Wku!y5MyJDT*9J!bKA6JeZ#/SSZRSth/AZH#n!\n/5GW>yHTEA*:TnDQCeaV85+Z4A9&+E\&$u!98
tBC!$h ^pDTyeQ&K#+Y:IA@^F\Z>HHM/?6>Iu!pHcA:8FMLq:!4M?k%XBM$&GI?>anB=y%T4F^6PMKaklWG#Ai*
C1K9e+ 8nbM4pH<nG%5Fy>I8F9Tm85p8je:jVdlRpAcjMHCGW9l^JL&h>teeTTa@8eSWYE^Iy\PdGS1wKmKRjCI
hj41cl wHbBNlmVA!uYCme8JwVNJt<8k$M8p5c+AbRhw9/MwF&cMJ8N@MGTb=wTnyWk/+XjERC#p5M%maQJy^tC
?9YhI% ^YXcl\RSmW::Nl^%AKE9?8B+mmQmjC^dwk/y8hX5yWh9P/hm=apTlh1KpmBym+R\itIbkyMJC?t>LDcX
j8nX:! QTcD^14#X#GK6cnEuJFZm*\T=a*uF<cb:>1K8!kb#L+YcAw*XQMEq&NdD55FcJce#t+bll&6^>R%p\=9
LiBNQb bd!BuI+/KJCI?#A$JnABKL@abZ#k=#kJtH>N#?9nWjbGTCSehVFMja484ZcZna95BjeV1CM5NN#EIQdZ
/JlEwq IL:@JSymhLlM=4TCFje$=KW:IdH\F@H9+5N1q&mJ6tNEY=^5ayaN^nnlY*u4lEjXSWiJ?qu8Tt5SAXn$
whpAI1 6d<&Thuedy4pNqCy=J5p##??kGaFp#n:<ZVbq#8D>*%AZDAw6pYF$bSq1X@*<I:D+E>H+p&8c<ETD$=H
@$%!q! i+dR!:RkJXK:5>c:t1F*:ihMHPTMnS\Hyy<lB>uN<XE6=Ak4uP<D@y8PyS9>H&MiDG8wNH!@6iu<Xd%w
VcHYLq Y$>H@&wPDdDw/CA%M&SVDh5A:SbJ#m$>BSj+BY1HPGF>95k>4=R%\hSwuSWCWjLQc99LA4%u11uqCNeq
4=pVeq ^^=yAL%ZJXLhh&?SbBV4jV^A#%/G?>i5b>J>ykj^d5dJFju#FRpDc%nidCZ$C9PmCGXXmp@GI8d:dKj:
E<B!#G myj:LlH><J8iIiGl&AtSuaJbl&h8P\X#64\19FcG^/Q/pI/4Q56:wQM8%C/GaNhamnTwRk=YtV@%+VhV
l&BN%^ 9JX+c8Ah\1Q$8mSRSe@IiGG5\lMN#1dSp8:S4V6^X5/Y^LPCyThC*LL6^l8Kw\BEPIqJNqAEu*XMq^=i
BIP8<p +C4y&B=WZRV*=>\NP#qI:VHh\V1wZl\CX1RV6&<ujNp:&aaIwA:6?SV=V<Vnl$YTBZWb!$=EN\@%#4$k
VIW+I@ WTp%kSK\&Z4PuR?>*=WuS<Gh\^hSljhIK5B%L8^cQ6IeHuhPaThe%P!/6:LP91^MYyp^Z>:XK#kI?^kF
WV59cC bGT6wA<cj^I\5ZyawVVV&Sbp#^N$>Xtj5eLGc6hh1ckSh><HKji<9XH9Rm1Zl#Lq$?PkdbET1aqAuVn4
?VpmV^ 5hjEyFd%&6WQmT?D/qiKa1pPAWWjRQwq>5amZW4NCmTQQ5lK85Wdy>DaCTW<lqnewbHWjVA?IFck*S=c
*bC1Xl KYb%CZcQCK16Ny1QL#>WI^\F\Sha/c+YiRNaQMq@%K@/iTGWL#9#GuX@a8TuwZe$yb4B$uwa*qBMctED
iH%FPM WIe:P5%GW^%hZtmBL4$j!/AN?/FHlY1Vu5X<jb>SdH^Ry6I?@yYAdnib>N\G9iQV\F#j$8YlY/SGdB>F
pH=4Mn EiBheQGK+@n?<T:/?MjF/tQF!a=1W@u\F%kdP4BKjdTI9wd8YNa%/AdNA&@D^LS9pEF6RFm*+wYp4=TE
9jS+>& ?kVhT6#!@9&&!\XGFKcV6dEhd>8JDw:R%W#1eQK1iW1*hQFK/NXe41umY+6+@!hQpn8>T?uKTQ#LE=>E
p&##SF =Bkay$AKi6cjAy$WTtGL>y5=bW=h<4Ph8%Qcn*^QTy*+M<Nj$R4yCAHMptpjn+!Ty=tCPqAGhJ4tLRu:
jc:a?6 l#u=X%^QI:CTNl@^!M*IDl8^&LK:tWhRy\49D98BQDieCTkDIhY?6J>*el^PHDPNi\:ba?q+ER\Y+jWn
AKLSyT i++&M^41NqjeZWlAB:&Xmbtj+M#kFj&TwudGa+:jK^\e8G5G?CC^?/q*Vm4KJDV9>IHM=V:1H=iFRAFa
+e\G&b <D\M&%NZuT\>>*bKyt#k^\wK9Z*QLy5D?jZP=EiY!\##%J#G:8P:1awjMPbTL1@DQkmLDWk&Xy4BGmlp
iLctu+ >L=P+@kTIX=%8Z$#X46=$tpmai<R6MZ5=^nJiyGYA+FYJLeYI*>iqhKLmA<9n=mkwn$Q#J$BXFG%d4#l
*<mRF< h+MMBJ/4B68=PqYVQX#PXwba<P!@H4dcW^IwybA#9/SSGpm>1cIZXCwHh@W6YC?cH?n8Qwp!\+@RnZ9p
pCm?RP VD<^t:X&+Xwi>CDLVb8>Gp1K:CwjW/GCXt:N&e6F5t1bwGe4jmcaq^1jd+&K5Y@cDC19&JeeS+Ikbc!*
n=+cRQ HPVMmS*8:P4%5*h8PK&?mE=@#^/5!+n*C<ctL&M9:1V:<untel8>T*ye8SP=@t#muju\6M:%/lMpL&&#
iaLG6> $j4E//8S9R&&=^YcP#@=duQd9=j%&I4=6h<:m<+%1MHbNpq@b:qbaIjuF!$JB8:K8iuaVcbX%15wL4/+
5**h!n iea@ELJj5Sl+YT@8e8QPWZd<LW$\58/S%96mm</>i\BiK^8LKti!P!iS>HTcey@pLu:i@IDDY&96KlB/
<Xlau= chSXN^L:y/5F$T:!d%Qn$uVZ+wanAnTVdnqkFdaV&u$X=K9qF:$5Sc&9y!N!jQjN8G<wiQ>^n>C@Pa4@
+ep>Ic dYdq*#J&@4<*K^Kw*=pXCiVjNT9@Z9d>%&L!:/4&@^EA>JhtBTYP?G5YnyL/a^d=N%nEu:Cw9&blj&Ic
<=h8eL ^KZ?t9%V$!AB@S5uC\4>a%d<:^\\:I>bmd@B\mZ?tJZ<G!#$V=+Z>6e5<5?PF@=jPN:@V?@=u?V@\HD<
KI@@8T b@@XQ\$H:Qi>YQ@&S9qZ\\GD@>>i4Q<ui4Et@lj*a6qp@Lj\IITdyCJD<eRh:B4E4h6*W%#ZTueNhcmm
A^B^?/ R+M4jJH^FlbcCycy16*WW$C&\Et4&5KlilS6YkYa?VuNa^ZtGVh/atSCwd1tFyI8!*pXyQ?TZZ6/FkCt
/@KeMK cmeKnqTc9c&w8+@&JuXS%6W$MKVVui:?51wWZ$4%*FmT?FRciAQNdBuuy=DylKMZ$nR^9mFu9ADWyZNT
d@S\GM uQIdX*e\NXmRahcuQ&YXtt\*j&5:PV>@5Ry&j>H$*@hmwTn8IKX<Y\:aaH$WPW!S%NN>y8%EBZ%$+?@S
Ild$la F%$#E&5Kp15\d6EN9F9B45cRRy5PCPF>y+#N/PNuKSaV8EnekmT#@ha/kKlQcZ*ay/S*h@94iGmmCmI&
I?MW/% cD%lk9%y?q:GlLuMbBckqKPh^d^WCWu6cG9u\t!4\mV@bTM>H&5a6eewdj*CC<X#kVe%&tJ!%GPHbJXp
n9@cBn mb<5u/SDndbj=i*8#d>%aFh5!1ETBPll4MQ9>!qE!?NaZA<6%%%pj5\cB:hSGLXDkFK*aNGRueWL9%!H
h6$IuP yNd:LSGH1%#1dkutdqa/*K:9*aYYnX4t:NuB5<41FJ?pdE%pDqCd$:A9h%&%1@#nYd%\!k4Xiw1#nbV*
tFJS\p :NwbnF$wqu!Za9pCjKiQV=%?iWS86NM?Y:tndFJWQj$yiB&$*h4C!:F:Hh>PS=lut!A&$nLX18DQ4CCa
:tX><A CkStTdL!kJ#%R\SMlIJuYVCac5$Ci:SaqHTQ9eZ4>TNGC&C&Z?bCqP6eC/ZP?SNc8d%/kPac/=Qw/XYT
ZEjRQ\ yM&ph/9dTP6uy/!KPa:^c/LBRwydjM5e:*Nw:5K%uuDl1a/<J6=?e^GN48py%1nY@=ckW=nDn9\mTjP&
ynX4Jq /dH%Zw/RXI59e&Ejq?$?>+c+:>uc<^<*4Ku<u8ePLm>Q>Gkl*EI:BkB5LTbpL/KAF%^+a=tZ$>%$G1j?
6>5pw: >C%$p!=YX/V?V8<>YX6CYt!Khb@!chc<+VYib8/4n^RK6S#MiptVW!YSWB$9YS@^!+NIWE85XqbyqD/c
S*wyK+ $uLd/+FX##4iMed6b6hp%HuZQSp8iyFdL&TTJQaMi^q&Fp!LDV$^M?!XFT@EnYd%E=VMtG/ypKc^bbiB
-AT*C= 000ff7340f800110333 Page 71 of binaries1.zip
j=JwPQ y\Y1!+*QDDTl16bKNY9e&@=Nh1F#?RLVm=Xbwy9#Y@XId\GJ*M\wV?P=%8C!%t5yZETL5b+&PLcGbRV@
IT!5@y Xnb9#T:>E9<wdPGy@IFMy%a=8!N?TMX=Me+a!%9BYp6%$VFZ+bi*PYE=YcW16^eWD^adb8queZV9<?Q*
m?+9^W P@NYX?9eqZLI<e8jn?=Dj>=1*+/Nq/5RcGJ8k#nMCJTb?jBa+kb/RjE5?PR^$H^QWQ56\bqt#FVuYyMh
D&4>8D 6^6SmH&XXRHKaFpYHB<4k#4/XXF#@juq9PV:tqHTFhbY11Y=XlSA<Gj$RndyK4m#yX=*%@mbFEa:99ld
@=8LtD B9/5Y:\mp&K?yN*#M*T6e>DY=J%$L^:l*44$dea&9AcqT?t+&Dd$!&!5<yNIHF$KpeTQ$Nym/u6qhFSE
*!q8w@ y5Hc1lJPqXmbu<^e9jJW1lnNhBp/a1dGP\8T88=\6@XZ!$h:Pk6QR>/QT?EbeVjtb5MV18\h%!<D&Ydb
5di5Lj /$qH#CbKW%T\TSIYHE:+DTIVa+1p$FnLKKbSb9@Zipuiuu419cRX1TbF#C^^dpaQ</Y!pZhyG<6WGeNW
S!teBk XQbl49GTF#=cG5>FFAPVM^JIc=M:ih:dmVLipL?QGjBpIy\i\NMjST6/1QKI$wp1l\/KD6/aFmZMyTEZ
t>4kt+ dDw^8%\<cFZ&H#V=^NnFY@1CD:&&M8F?H+lj6/^Dqmi8e^jdC1b@$<>pS>db4^bSdBS$^h\RL@kJLqb1
AqktGa Ve^k$pdH*&Z!mWYjD\9IqNi!?CK6/!XE<kcp>k<iKE9XHhL8>@lP4QV:HQl*/NAn45C8NYX%u<PEia:\
VRm=y8 nCMqJjWjyTjd%y!PN1IL/Nau$9Z>p8+@I!mWN6@en@DH:j5<^W!J:?#T>/Y6dcHLL&6aYN!e%*JqLTwh
#<Y6A@ B+clIc8LPh6GWhG*D*LRT59GZ&Wn9p%PXQd:Llb*Qya@:d5n?jKb9+u/p^jJ>Aw!QNJnB!u1>w@Et%iW
IdaCc1 W!CcG^Zc8Y%6p9$K>&8K4X$$:uan/C=c9JQuTMS8c6&dKHu9H:5?GJi$/u=*?X%B&cyF@a&<&+>@#dje
JYAb^@ ac=J@e&B*?1MTVjqi\m>+G>tLY#5>LR$/^e#n6lL88Pq^@emP6l&SBacA@#6qZa*C?=Wy^>$y<HR<5jG
N%m@q: $n+:+a!LIQ4XGChIp@/QA8H%Y/==q$uK4h$hpwnJGHl$$K/9cKQlwVnPtiVJ!Vb8=t5:/tl6<1Q\*58H
ccwLIt n<!EVGtpcWu<XFP&H$Z9/LtZea^qMYYcMweHHa/c8B&u%t4mpT>WXYjH+M$@lFC4eTIdFW/V&&<WQDHc
IGqEGI I9u*8I\eZIuSJpL:Lq>QK@qbYcSXS?F&FT>AC*hqGG5*kHJ?I<ck4nX8S$GFN>9$jhMB=P\qM/I#Z%<A
LTJ9km W&@yQ6bdR=kGY9YbQ!=Q#<:jbq1WjNVRKW1\QL1j&^9HdHZHyqd?y*wCW?Z@m:&@nty4dj8%aawET+JV
4BNY5E wLTq8BNmTCuFZSLeZaK:Fmn8:5YK8:8%ydm:qXJKeZewyjdhn?%9:?hi/%%4QN>?9#*G*u9\S\np!L#t
Khwu18 #DYVPe+n9?9$4WyZiK4cqY*Z=9elDnp5lB4YXN%+*F=Z^1t$C&qW96u%@8%$k1:h1&W=m5X#Q<bcA=Xa
l^Bn=t &C4:Ga#aG#L51QQtw?SnAXdM6+qk%bK>MV/N>D1h*!bdi<wH%da95XHRmIF19WtJdBW=eStm:*JEVtJd
jEd4%e eyQ=K1Ei&CY&KCa>P#G>MEjSwuY4#9+DIMPPj+<XwwRdNWV$PSF/W&dYHCY!Z<PaM4JwYB!8^!KNd<E5
w$e4cM eS^@YbQ<@Zk9b=6T$4G/6@?etI%Ae/K/Y%aRWcLZW:L5S$1?!l4jKhF8&PheZ%N5N>m#k5yenW!5J%*C
kPGEj= 5:/QX\Rb^/Z*mhNcGGYj^XEyn>%T\kM8&Lw:4V9ja8uq1PDYS&NFEHpS&GJJ5++8DLYRH=tyXKLMIM9t
:4+!=6 QAa&NhbpW?tAe$kT^1mEG%Mii:i$j:T$4iCq#B/!bV?8dDDXRF<aP&%w+WA^<y/m%ElY9qS*l86?pVMw
Tp^5?$ +ww9AY^DpJ^HytZXIE%D+JiQE@?h%GB4pA^*kCAaEt<9hcC%n%EZG\T!%Ty6B/BJX1/uM6FFpRKpYBLT
bp6Z4+ Yj58X!e5>^<GwuK&?+DS!PyhZ$hy9Mh<j1GVATh!/H8Y48c+Fl6<Y@PF\\J<1Te1<#<I$u@Z5bwu*X^Q
bh?Q:u +&FNK\ZIKaFKbwG&\/myj9*Tm:*B!1Xl%Db9utXTQ&j6D@HlXeQRLi%SIF8jpntY9c#$lRE*XI:BkXDc
WS+D9K V%e18HY!:9/AHth%@qI>nL*+B%8jy$aX%C=lJV&+EwNnaSnFeP=c9Sw?d+j4Q5cl!CENqEy?#R/661q#
+F!1A* Hp:86h*\=#yYTLGbXyp>Wb56D:*E+S=w+%D>!C+dG^jt8E48F/NY\#X:BpnpLeb*qGQuFtle?Ww1b^kb
JFN/G+ cWew=4?LB?aFRiZlXYF?l!:>MB^+>qcP>tbkyYSyI!?8Q4NccLn#VX$5tuYQJeu8\hqJ*RHR*u/9p$XK
5h%Gcc <$nEhRj8m+MBN\W^YBqy4+jiuyKdt88BAtjuYJ\hc1R\c8HCqm<FT=+J:wyP^Rne4^NF>mq65J1pEh#Y
J^!XE& p@q81N8/YjCC^wP4CM6>GL%ApW4u69SVpmy8a#$aXXR>%k\%X*=YSHMp\/SQBP8iVSNyKTF>!HQmSnu6
TdIHER :bQjKl6cBCw/@ZGQdPYG\^AMT9A89ub>p4i:T15G=#?lne<a8A!&JI4lwbVeY#RtD8HCmTcZ9P%GlML1
!pcjiy J=PVFQ^<?B99W^^py#>klS5m=:q:^\nWW=PL=K9pedW$%HLR@QB/4LW5N&!NPwPS?YBNKZh%Jn*J54h\
/DB%T% QANlcY@lAhE%dnWBp^w=NtpP:q\qnRKqWF=Aa^1DmRq!F+YCYT^^Su8Aw^$9:>c+@hT*Ia+YF!?9#I^H
GctBGK 4GD8>6uBw6qd/lRARXDTSp4bnb4FMB=Y1XhkwnX^XyJE*t/+$c6NDIm6D#iMRtIC+AQl*a@R/=dh$EG#
XFGIuN qp*dD=ab19hbC*JiFJ!@RA^4ibaEEPK#tpjp!<18#ypEk\IuT*B9\m#$X8TepaHVhh5knRmhu&We8p\1
h9kLIK \GMc>ALTw!Tk+@AS^1P!FI:h^H:%aeF:8=kLAVHKQp6?tZK*8Q&CGLBn/PGbIJ$nGH=tC?knPh@a:$p?
Y@H&58 tHdZp>Jy54y!d5FHA!kiy+taLbIdHE8yiuI*ahtR5J=aK#*mLNL:GEc@Q/9n/Eq8C%t$=Z%WhDW/RKB6
\<ekPY QAA!Pd!u98XlwiRd=pwk1+ZBw=J\Vhnu*hH1$^JCeHVJMynq+#JSMKBX4b@nX/?ZJ*p&K=lVyKhPqc*P
Z*CChS XHLw#uAK+pGY4t6uKHLeRyVX#$:JG$KLiM\YbnkZPT:!=Z@1Z%8BRBILB\#AA@aZK5qj1RXuHLl>AD9=
VBd^iI NV1bQbkjS%?eRAT/Hw1$&qkFaWYGyVD:EC<n*1?p@i>qGW:WahDJ1RM>cWXh*CA$t/k=MMyGK4bi9n^J
5!#j=* /p/#!Z/Vi%#:/%MiTQPHEa*btmqqE:SlpbhXYJH%^1BSm<GHJVH6p&^Be@puYpI/cpRjM5\Ma\wICVI$
\:D/I? ET<icq6%A^!%M/VRE!ccA$=ik^/Q6$WSdZZ*wBwBJhlJGbIpemG?VJq^%@hhMZm!4QVYCZRCBQZ??%CB
IJl:?^ <pmRVcS%By=*8FX<!cTN*DPGEGXl=n$BmqID:y5kEt%#&/NZTIc/5:^Z9K*18=/PHID//y%ZI\A*>w9%
ZXt8wR @DL4:a<l9LcqaaWJE!#BN1KD:CRBi!JX*l4:6Y@D<FJ<1?/JP\/>VH&$=e+pC&GMP:$=C5$El<$>PV@t
SybSJb lLb\\ZdK6qp9V%BNH4jIlB9R^b:>4pc5RkB!XmCadLEdJ1GLN/5*wKEbb1A6GK4N?^=*uD6&&^DkhKb4
RNAXK? dh?ZDI9&^9!tGd1Z6PA#dwW8BDGRP:F5X>>>ZaXY6AP8ZFEb5$LVV4kNV*Y&XR#A*HI5id&TTi/DRpu>
8*YJ^6 &5@&4C:*FL=FelwPIWMHH*tE=MJcR8jR&qnTZ&AX?TiljIy1c\cp^*T&YEGKKq:!pG<aM><#uuVuD+bP
4QMa&* ppkjtVSeBmGjeCQyAFQb=*EjSHXhme^*>51cj1ckq8NC>WdKqX@+%N14$tj&tFRLQW@#KW1&<MIppb1T
aYQV$H $ie6>BRt?hnFDyaha<H:%^N%Q>lKT1iqd9Q8D?jN8PHt4$:Y?e*cSm:$4C=McN6!M<\u5V9c4&TThPhV
kE9PEp Np?5EBJF+N6bG8cDDP**:qIYh\1nBn%KP$EVAR5LEBDDXKHZn&:1!EC:X++nGTEX5Je&?eBdkw+Yqem>
Sh6LZh b?H6mY<Z%tT%jFFcL:Y>=dR#qjL&wMB&m=4AA/B<<E4TWcm/>W5!dRJ&NZ6X=/Q1a$N9?ynK&bqR>$\d
<m<nt= &=etw^uESC@6JLI!SYKZ6VV%Cy=/&IXkIPqpjautw5BTQ=S<S1Zen=BlA=5TZGBuX5MF6Eb+MG=hL\N4
^!&?AJ 4G/?V<jtGi*i8>Spn@KQ8Q%5*nH6SpZC:4uYT1uL\n+jtSQ:4CRQwJE&qRLk+ywwybnm^ICI@y*<>XB#
>CN*:e :^VltFK>8yC5R8TtT<PEWQkK9a:RlP9w+:#>#FtZl\:5l\@!=?\abppW:ntMHEt&Q*RGWZq6Hh48$Vln
mGD\6: Zn>w<CDQ@$R&e88+iP8YyM&E:J+<MP1W9qe$bGqQXnmj96l65ky/&8=SV>AEauNS=8u$^jHm9Fi&1X#P
*?+dZ> \8>j4?8@@/=&pTc?:VSaEa\cFZZd^XW9V*nEjBnINhtN$Y:^%1/WK:FubhBDk8%hXKp%WdFCI1</ZiP:
ZuhG6b Kd>b%jStm#t!G@dlCu568>b4kG%mpK/?DbWX6biq#tt!Z%9yZj1F#B#bunX<X<R/$T<#WKj\ZimFQt>h
K@66Ie $W!$/enbjE:i+GL5S%y\dqBIJhVG?bk5?6=VZH+c&+Cy:8G!EJYb%JjkH<M1DhHnt^wVV^p<lXZmG^+Y
NP6e8t Xh/#W*mb&#NuN>+@H&iiP/NZ5H>M^+&bcmY8%!*letEw6Z$y%u/9tIm#&GN48ik=Y*tplbc5R68+4LVu
HnTX*e >ID:GmdXQQFA^9H^9BdYYp$ZMdyBe/IE1LyVh4bpWtSDGN/m1Lcn\9wD4J^mw1PK%ue^k!PWbWYF%amX
el1Q%K %i/e<*iMyHmJQF<55n^@eLjGN8Sq4Q\Gn8y5nPpe$NBbFkJ$5N>Q*QKY:8le4$9jGKF*H^e1GCqjHdAX
n?H/ZW GBT6lb$akVH\bL=Zct9t/$=#@eu/8bQ#^bc4GcFq?*FK%jDc=iL%a8kiN\>+ypG&<kTJw?>/cjb%4F1/
WtJaKL **I6WlTjq5iV:Y5/4n6B!l9D4i@18\wCICnATqdn1DE=awqwQ<@\njwuH4D<95+Z6F?/B4*RJ+=SlXeI
Kq<PDq 8%i$Z&hVNhPclqL$lqF8VM1G=W1Ewpwj4jYRihLiueyVd:uE!^Qb?9V*L*=+j5>ZuV:h&&+Tb*@P8hai
6\bMP4 Rew4:!8c>ckBeZpFH>WT\I1hHWnSa%N<PX:b=JcNcN1t@FwAG5ekHqXuSa5CZ1qPSABtqC?!w6GL=Ykl
BC:Ze* QT>S6#/NV%!!\n?Sk<<mnq?VVPBn%GY&F#!F?=TXejIqNA%8/4>89LF?<nC6i=GB<K*5q1T!Ku:>m5jS
+wtKuT aGM%pj\#>c%uyc5#q:4W=8upbw/p1#!JKTNWRPe%y$FIbG:cl=AMpCjWV8d=En^\dcL9qnb8Ga@m$\Fb
lLIKAN lPP6nEmF$kBIGcjKVQ%#MySIwESNS>LqByj9\Q44VjKFV8DcCyQZX?&aWJdRnREwkBGLHSa6m^*mZG\G
@*1/W< wcSSCW=KHEb=WMdIRNSVGap5lYLCYGaL&PtIGNPaIcS@bGKkk9>LVR^W/L>pa8D@uHGB@?&MC@!QMm/C
-AeFX4 000bcb619aa00110333 Page 72 of binaries1.zip
$\+>i\ 5H?YC%Cl9&qmaQ^@#TL?8KiTIA#/N%nwu:C\9&dlj:bh?F?#5D@Jt5ARj<%C+Z@CI9?c=j<Vc\WV?G9&
n$C+/d V?$SVQB9HPk@5Vk\wj</C+j<@<D?y/#Jj=D@V!dtQ@Iq@&Jm@1MQ#9@\uNA@:H*D@*>M%tVnj@85Th8#
<PW#p: B4ylT1IkPdQ=St=/=+=\8&1:?:Ik:=$J/d:M*8tiA1td^h11nhuiSuFyWl1$8DK8MF>B5RFpIDYPqbI@
IlViXB 6jAenpebAlAGWVRJQH+ie/9YGi>PkJb>F49eV^u?SXJ4ejmLMwhK9d94wT+$KKYiE4#IlFBA8beww:VH
I%lHZG NDWwWZc=CBS\uM1NIkIc@b&N4\tl?BVmYhX\Z=*/tS4%LN#knyK\1aYhWeFW#HaF?Y?Bp@ENSyGCaJpG
C$nlwZ FVQ:G:1X&PnQ6pNBau%QEehE8/G1y6F1qAT^ZL4!J4jKVE1GRZ*Iy1pkKb%yiS4de<j//nZ^<AZ?R/bR
NNP*RA 9NlIq%D+4a^1BN<VTS^Q5^kbMqq&V>i6kp@*GhCb5%X=8PMa^b?P%AN>JuP9J+<Dwl!*lhK/Itd8BN*8
W*98FJ &:1+cSY$dKSVWlL=uMkZt%Q@/8tew+^@D+i<5J&L4$j8HV=5&XR=iL@pW*LPFS&pljQIJIu#m+Giat%A
4i*KXI b>kT$Yj9q1?qbC>YqtZkNF@8I@T:\nMqSCakyn%/@JDYE:En%j8YdlE6:TwXJaN&L#H9B:L\YBR%mQ6&
eXnHZl Zc:HyA\%yn/eem=1M/w+&KnG?adVl*<TR&h6?HW^PX=16<BC\ae!d+h9QwZ:iF1<X?=cc&pZ/^i?9ub\
XQ\9lp HQtlFiGI8CZ4E&BE9Jjh1W%/qY&/4^M1tI+NJJ^%hStS>&VHu4ad/^5^nLy*X!^h8<kRZKe6p>Q/1qjp
Fi#plG b@/6hVBj4tPY8%1:SwWp*E4c+E*Iey8EyIq?Rajda&1IPeN*haCmS$W#nWd<\lkj#Fc5ScVhTDjER5LG
9MpaJB 9ukmAnZbPZQ*!alqIqcwQ:4YtLApwC1VL86m5aVSNMjM/m&Rl$A$#wmi%YLpcKt@jHpp6lu*HwwGn^GA
!QS\y\ 1&PC64S%Aw:Td9L?8t@tG=ak66lXiFj!$I>VE%VVNS#<uVG&/:Xc=DiDBl&>t+W^PwADm!eTk4yXq6#X
IIFGN% mHu%6Aw/\/ywFtc>V+ZCN=htKhCV6/uYW/edZ4GeqcD!=EdKXIi6=whW\c^H?FjbB8>#W*N+JC5Et^Tu
MM*LB& hZERX?eu1w!mPiT^m9YEuNKJZ:t?<tqn?qnwtXq*HVE!eHj%iD<&Hn$npI=Qy/5t$eHnkDjbbiqc1TN%
yM&Y1\ #4jZWMNL%jtLa6wTjm:%4q\Ia&y&FiF%1NM&Hhu@A1lSFnA9@4t5a1e\cSZd5XGVh9#1tJMtpkNmR/cA
^a>tbl BKV\5BI/FWEuE4k!a\QE^YTeh1R#$N?mK&m1G^IdA:KiY:1i^hIH!y:+4DPLPen99mE1tHGXjPwdyMlA
<=t5\= >!*ipRNIhSH%TF\Kw#5y\hcNd=T\R<P9ZTFSR^81!/Jj&ijXPGQamj>VMI<TZN^C%EcnE+K#%l&ld6q\
^jpc#E XbW%?VQPL>?$=aPNG9t8juyXWFXaDRMW^%nypD#caCG+iRc&@D9XkBM+\kn<RCGSV<jIG>pjN%Rj%tT/
qt8TL1 8J>i:Tp1Y=X<Y&m@Hab*#<Wel@Q5eEyc^DD?aJB&bEtV1S=T8bja?I/PnTkpy$N/?J6y>*Wai+^9F<AK
<:Y+Ti bD<ct6^LJ=T6qh#RXP!VFXATM&hAIeSijP*Da/X8b/d+bm1#>EV@5<XD*c4+V>M6u#$hk#^jNb!>4jpI
jR8duE i=#iHAwAV!mqj/?Ttqu+YiAyHX$??=&L>1i=#6iN8VEq8ycHXFitdS^:+4eGDjt+wQhEuZ%NHJI9uQYH
!yPY&> iNLYQ9i<CM@yw/A!Z6\QL\wL&PLTHVJhjKPkeHlw!w/aWI8i@TLDbDR1*6qS*Ww?6WcZXVHZMyFT#Vkp
89ytu: AW^J!8$XiPFqiq!l#<hPIcESFLdAqkyD91H=/NAQ&m9I$A56iV^HwG$HyZ/KGDeQtYkw6R>6m<D%RwbA
VkSZQ< LG5lhRAi?5k&P*dL^5w!y1Zkd#G&Fa/eGcTW8m*S^ppXJT?yPYtHpe^FLNYQQYy@1<l\*l\dt&&AjYPu
uW%Q#& y%MWPnYKJ#RTCB>EmInYG6>c86wLCyeLP<i8DuPa$nc$e1RcRnVaLh&qq<^\\^hHH68BQ#lS1I61/4Xw
SFyk*P *A9!>nu=#bGC9EAtX<\T9t%R8cE9W<a=CKWnT?eSw8=DX^G+Nw^kM=l=1?diG\SapqcjJ41<Hdp*#:T?
&@&npq hC?9KVE4kbNPHPQ?qcy@LiE4SK=XKEm4IyaF9SL<Cc#XL&^Zb1#EyQE?I8*L&uIJBij:Yphk\jcMwe^T
MVE<N+ @uG$/DdLMmS<iTE@e+FR9#VCF>im=e*5q*:FLdeCjw6l&cp9awllZZ?1%NXIL*/ZbjKaaATl^WNJC1%6
Cd<E$R wm*ESdNX4ieCJ=Ru!\WjILbE$XRR$N%\%/c:b:IyHlI&+&HIHQ:n/#XSS\T6T>^H/hl?ht<E^EZmumXX
#jhFn^ $9KK#ZL6iq5#Q\#@hW1D$<qMnPMad>?/*$5h&*t8t8D+4w<mutuiS9J*SV!De4tAHT*^L$<q6AMj>PY<
PD8u%T =/%MEBRlmD$&ekMXl!*llFNkX?AWLW>W^TZWQQ4yWQ$tST%/LX:SI::$YVY6#aKD*Iw:b<YH1G\6*at/
+VZ8nc :/4p^bb+Wt4Ih#^$%$GS/lKjPk=F9^*8$ehS?>mFHD%V4?IdJu4YEWJklQMBhT&u8#$4QSY9^$w#cI?T
E+a<Rk pbcDeeiDWhnY$VKjl5CBqiY=^XK#<bPFV4k\EytAwimcCZhXQ5lBH?BTy6cA6**deu^$8:Ej%:QckR^*
M@/QdF YMRW$CPVKAaG+X=\:YpEL$JMJp>5HG6G*HB+N@\&nR/LM$$hb@9n?@8q1REJ%QwqclBuc%#Yp+N!RX8X
T$ttii FkCJ/PE^RVc1FBT+HM>buB6h9Vy8Xuhw%qchFSNF4$AcAmyZGbP8qy/&u>wS+XM+K^@QV/%jG\^it+uB
88!m19 1tLyqS+n&D^R1A9<A8nyuZbYK#+:M*NKB>dQpLAFnqRcRT\PDPQiikMDDVlawb\K&ua>k<^YPS\KlllN
!hV/+X \1wMTwJ^LYIudM:T\D*!&XA#w@L=YHcbKJqHNj&Sw&G>mH$DdaaDWJK9VVp$SyYtbq*QddA/Cm$%$\Cj
D$A^uF LaH/ti&Mupl+#/Scw^SpS14n6n$B&?\RQ16ET<?D/RAay6e$SIC?aV=p14tPaBy^aKTju!uLH^54>^#L
AD<V4c pnEt^Kn=6L?d^VX@%DdYi6cm*PWlpY<=85e/iuX#n*$Yi+#/\Ni^aW$Bc#XKdDbenWn&$QBS#>#DSkRD
\^$Y#! ?y!^Id/PqhY:wXCV#+=^Inc>JpCB:CP>uNadXwYIP9KD@Pqa:l:AKBMhJBkqZecE@9qwY@ku?Z$thHAw
dh/C>Y RdlYQMRbHVAalTypF+*G56jQ#\?KaTRC:XSK@G6IJjLMBJ@iTiZEe&?BEX*ELE$6Z*%SXtPlYaZdp=Re
YpdDHS e+1hj8HQedFAH5:GM6dniF=hS!AD+9bLV$a\Jn6S:LE>P9@IVJw<h:d%LIw?bN<%9CiEGEai6^eL5CIq
*E&+a& lwnF<ql\XClXa$SnPAm5=j6n?V$^FqdTE@t&>R1np5ba4uQW=J*G\iHG8>R1QB#*yA%+/#L>YSl%>:W$
maLtD9 !<:RjK$GdM!/qy^*cD?hI=R?e&1j^N4Ze@AwZn#c^B=tD@:i5/abw9A!ci*H+KI5SYE9+@HVlK%I1#SB
L6\GQ: N#>Zp45jy=Ncau8@IKaCt/J%=1^cwi!tLQHRAZK\w:A*SZi4Ce1X=Mdd/acHi=+*9^&QnTF!PkiQR6Aj
6R$#lu c!&VV<WEdcYC?e\dPSy1elEuc\S\YhT@jQaAL@yqa*VeJVB8Dm9yAl<1me6#!jZAPl^6@#dSNbjVXS<!
Lm#+yb ZQB+9^*tKMp/^+&wn*p\@1mm*Ew4=n$jqEhiPqiK$$/GMLb$#&>VEw>*6nVWZeH#wA95<pplnI5SC$Yk
G1=yi# RT=SE&$a^9FaElpVLalZubyw%aNt%1b5KE=6*1TH8>DYm=FAY^W8Pnu/y6WqjLmXS:CLh+mKn/VH&a9X
Mp>Zaq TE8pb$*BWu%%SH!DB&1XQ>H5YKdXwqE%<:<pAX1HYaiJL8wDa8B48j!b5$EQ#k\P^ihV#I8KJ4JtTP:B
=Mq#\& SjWGRuYTkG#bJ?yYD#WCQ/N*uR*LGGdQbD=Jt?6a6</XHwGKZbnKM9qQkXcRa4Ct@Y$pjj$=$uHtCIZb
$M??m6 Sla6Ic@^1bZHRR!j&C&$w8SpIbY?eXi=mqi?=%^<TmZ59!$MuKS6R+MZDQPuJDF4pXVupIXqhZ:\FZ?6
TahBe\ =%ZaA@jI!@qa9bu<pNQ1^89QVJ6+V<mKiDpI>C:qPYdXYb16a55@I?Yi!^:JwX1YyM5KZZcunXJ=4#u4
IR%DLh kSA/eIK@pG1VpK9le@Q:LQXaiuAGdb/e%Kb/tF6=Yy&?XRmHWGtqnT\^%aSbmH4A##:B8>kCG=5?+h%A
^$FndD h!YNSL:I:Pa*wkPm9%84L\i&4hJV:DkIyYRKSBRQQPN:DH89:uyjcTWX@4kME=K&^LLjX=#1%qLh<+j#
@HypVc t6nYY*QL1%?Ft>dH$X1/?%me\t^>:iyV<SpQZqZK%M6mY%+WR/#$iJSF4YWtjcPJSVC/m1T@#YS!ED8n
yD:PlI whl4blJ4T/Z&MN9R9Nm6F%:!D\DC%lmZi$ja\P5Sn@6C4yFmFy4=KT*Bj8iD@9cQDF\=#eaw#VEaG&%9
kY=^/m <>KhiRdZYMCmQu^A^m9c1VVLqF1eECAyB!l!JW6DDNdnW$dd\t?6BpqZ<L%lcpV5Zp9w/u9P+dSi\>!^
:n$Q=/ R@9<:DMAXc\c5!I@kebMc@@:h4y$yTJbFnNRQwC=pumAyePD?:aFhu\i&q&t&lPi>$N<dttmcKk\wHu#
AkVDS& 6qdQ@yPwWqy6bT84QmNC:8t$%P@at9%XYDpFc8A&1RCiVRcd\R\tPbt*LAyw^!yYNZn=%MKn+dZa@Np+
C9\eH$ 5SunMnjDaZSECyqM=Vt#Pm$6#*QIcST<?b&pA:BAC%8t*=Dh&$!u$V8KpIqXdhE?9FCYRCP&Eh=%K<:a
yj9ckt ^GDn@W1JR5&9*EE&%MYy&5lqhNTi>K5RjH1MbVAQ#aX\S1kVE$K5*S8d/miY\@^PJc*dX\Xh<BJ&Mb%C
%$Vn=B BMAKA<Q/1?p\LGByj#W*?h9t=/VDIlqPuAd:!wIDlZbE4hwMZ$lJHh>Yd%1X5/SyudJVHl8::@q^Mdwh
$=m4ci uFKit\KDX^XH/:u*SD<BETFJc58KX1%qW1d+wS@4Lh+K9FEnBGlh>5>Lq\uc@A:y!P#W9u4y:QJeiqRY
kA/Pb? &G:cMZ!dDHlKiHt@6dTH>wMP\mPL:FpwpP#?$LRXB!nZYpFQCZpKWH?>+K+cqbeJ^ac^By8Ctn$?9Nc8
&\HEE? h\HKptGd9W$A5hhLIm9&4\4ZJ#FSF/XDw4!h<GLXe%Jd<&Kqt=ADyBiA9eVCRw*n15VYNY^aPJyeP+?%
wBWFGb +dWqi@uA9ST?qnJh%w!pB8iPDZnQF#K4%DJP8bAFZ5R@Q1RGTaH:X^FWPbHdqeX+#IW*BwYKDK1cHWBj
u=tF&t blQh!Npaqjh<hG8EQ^%BcN\PFeAt\I>u^h\cWQ1Nybc>RP61$aDX&bbX&*8KlF@khT%$5b#%KcZ5J$?b
ZKG#a# R49:X#\CQjuLwJ1MZ&unJZpyFD^XB/DyLQ$&bw*/ukM9VS%$FapVRJ&QHBA9+@tXBunL@C#4$ut!+RFy
baW1#< p%M#%GYJ8CL$FSVJ@m^!&Kk>9w=k6F\Mk:npm5Wk#A>6!^y8#ijtLhyLRR9#IdejnIe@Q&#Zp5VYS8FN
9LX*RP GjA\6m8Q1#S:iJNypuL=%6%qTZ@\Xu<^qF4JKq@H<Q+XKX4^SYwe>XnDW*Jc>dR!i#qk<BnR9p#M6n\b
-A/P%n 0008c1b574800110333 Page 73 of binaries1.zip
M=/p/B J/?/m1RI11HJ@?:F^*e9Q8eXB*5@aC?AQhJdu\AQP\hL^iA$JJ/R/aI:kK/$w49J:eaid+$@%8h&tZG*
CI!baq epitile%VFm+NFw5pw4e>MkM1:W\Y*jR!VLjwHytTu?CHuV$b%1T5*HeCB6%Sb/ij?Y+IiJdBKj=tda/
VX\M=1 #dShGPkP!$bcHpKYQYnQT=#ut<8K@Rey>AiYl?9A8!!W:4wjE>#%ZcJHF14/h?AHAc+AhjWVPXZ*6c#I
llISp@ 8EG5$ABTE<6VjJXVuMptR1wp1TYme^/4eBCZ/8QKM$n#YXbWq4YKcAyj>WFN\RNJHPZm/QL$p&jJ@@lR
ckb%iM FqVnS+XT^VmQAm6K!EG#tcaE$!pMH!anSkGNY&k8QFw<mtq@1VL%SkQ:9XumEAGyHcAZR#C&!VpP/Tl%
X\<e&T k9J5uM8BL!>/mM?K5<:^jdQ$$tI8wS*?C?W1yp:**%!dCj%td\HH+$T$=9NpS@DlDmqQnk<c*ZbWhA%j
u$HPQn 9:EM*e&hNqh6HK#k9bSJcHt5@<9M1#5/AjFYN*PdNMa@9q694qpY<<Qd$TI+?#tykX<Q/$HD6lCR6&!D
VJBPTA 1\@Z5wy!:nHL1pq9DiE#GZc=+DY?+AP4q1=?9P<CD=4/T@p=KJ%#^EbKbZ6C%DRK*R4LDid%QHp5>D$S
=jV4>= +cRkepp#t$4yPj4aSjcR/+?5e4%^$q=K\*&tZ?ik!#pKbNh&p91j1^/Q8NeFl^ap>ZMctW9H8?F#R4?y
Z\uwFA pn*?5qPyFWNcXl+J*Fn!4WNchQehbMekZRqN&mie=!NGG6/M?>/qb=yBHukaSKLtjlVEnL/IJT@?iD81
BeG&wH $eluWb\jKwe\q*5?>mlQQpZ*ALYNjBw#@P8p:wH?1V^nnpFt%5A:W*PBS%ad/WaGKV!QJ!IQ5iMt&C\L
LKm#qG =n*Z9Kwjj5pjY9dG>6tuaL%AK\$5%b\d!E#P%^@8<dcl=F%TXDn/9lHjRC&yQ??Ly5kaSGM=in/Q>P9M
ilWJL> cd?%KEATbP1<@!b<h%a1WZAHmN!9!:hh6h@+*Gu?b/EY?Q@cWA9<9^b1RWL?TcWklQ/8T9u*?9J@4q4@
66Fk%: 5^/A@>%RC^#=N%nwH/5F8MBj5*?&ZBle<K@bQ\8%\IZ?twWJ@QH?ImB@k@*nJpGCCQ/@b9>58VAE>G?\
ZDpQK1 j:bh&F?#j/ylEQC@<TL>TVAF<VetFkL?^+Ea^N?aYDDBQ&H@^5VmF@nn=eIRk9>J+eD@Pp\D@?@CNAKR
:n^cDb j%a+CKE@WDkIAeH@G/d=u^?tmRD>@#hMa\i=E@?ZMA%eteF&L6+BbjIkDKi4VERt!FcEEq^pwVALkPYw
D\N1YY Q^h\^PXhK:p\D/F1hZCkwiX5hyMdD/Pw@4Ha1y\@Bb=$N@eTd%DQ!jpWZ@QAtS@8q4pMu#=T%$QMw\<%
I?<ZhK B9Awlh9Z+P=!/mTh:y6YqMAFP%ZVAWlZJHZ#:EMBI*TB8Wdu:AVpp^11cj^ti^cPw#a41>Y@K#^%GehF
N4YE\d y*1=$QNy&I6LW/k>jTKHF8CAChFiW9=p!/5YqGL>WKW^K!8D/\nqYpWW#ESH!>JpJ+wajqInGhtchQZ#
&mpQVc IX!l?t!DdjwN9wnk:WL:c^Z#Ey*KYVWmZTQPt1L5=<M?LQRLLVYNjm6!6I+/hK*^&H+$%k:FmlB>*b@^
6@l6bT qe8$/XC/1Z9PFR#lD5kMEcTiNP!%WlaBT9CAIqi6epm9*I:+pCdQZYnuTjF8^a/hmQbn#1ce8BdWQbYT
==bCT4 epV:yk+qiJbw^Mne4S+h/RkbbBJ%t58=Dqj^<W8IQDFRpi&Wcmiq@Nh5DSLY=PFt@DHhZ%WjH9R&THV1
jq:R^A lp8PD6:Lpn:u%Ft5AVXPLRqS?uV<YWb+IenBWAil<BJjd&QCKMm#yitk<6NucJmh^btD6nI:CL/W5c1:
Fn<!4N 1j#ec&ay\$pn4Kbj5qC4\J%F1QMVn@jdEV&GtcY\l+?4/h4<QS/@uj1WH4di>mkCbYh<4^$qc*CWGAEJ
>bZcIS !cYLh8j+?RM8Np6LtaW$P4$u^aM:/WA^i^@EJiVF6kM8Ca4Ti$H+W!W+VLSGk>ajtaD+@a:Kh=<CY>4#
@E1K%> yJK+cFu9wVGNwC4+YBM:\9h$aX:a&@qN#Q$q:Kb:a9d1<4?w*%4<AD?8P9Qpi9n#@caNwXGnq^1yl$IQ
DRAI?^ nR!aB1hN1=+V<K+app#jnC>Y#6:XMThKa>SWLS@yVq5YaR95qi>$H9qm#RaLdFW@eA6n*>ewKqb4XV=<
CEVR*& J8^\d!XE$6G^n>VT5QTXB+@aKC%1D+pw@#de6ZN\MFE+lml:KMIyp$qEYuqj@?Dw\^MjeLp^LJ%VJktQ
Bt^H/4 alQic#CZI#:!@8Tb6l9BIupicL4kq<V&k@5FQ?TDa@u#8iRm4:J\ytQ6HLcpyTMdC4ktAmk$=WQeuA>!
:IA85& wq>KejMVQhk?&&M>@PqP89cwB!aHT6MdXDNb!MjZ!HE%W>l#+u!tBmiMQFnBHjG8W@+8FVtGTGM?$$?J
WQaNqE ^tcS6*19iElk18JLtL&qq5iYBbZqDW5TH+T+4#iJ+N$n6JtFqDG?q=nNQd=uYTNhi/ci/iNBV9w^!>J>
kmM?5\ +%=W5^<kuZu/Fb:T+4!1<<mh*$#LlmQHibtSc/=V!t/uI@9F6C4?9hJ8/pB1qXj6=bRuR81?>%Zm\y+l
HjuIhk 4&^mTwnEmtl^y>*&9:n^Feup5ZjN8Djd=uRjQLmZM&+HI%<VpBC5VVTFPP4c*Z88ZlSwp=4n/qS9m/bJ
uhaQBS SI8n*5Sk%k5y5/^6*<WZLS9FjnFZd#+:NcEeA>lMY599Su?/H>Wq&jKEpH9l6&:F*KYKb#C^^mG?ei=:
9+>KiP nyT>@jQFjbEK8ql>e?yQQmHCI+cTWt<N1H:M$m*X8CS>m6SbZEWC^qS!%4M/#X^>^:Jl#n$tZBq%4IaT
9W$IY9 4#49E1pp<#Yn%8e@qn^>E6h=*+^e:=tW8k6Fc1E\+jD=Nw/p!+8J5T>lk<h$eN^D>cTe#cwKRDy&1u5=
cN=%!@ Si>A=:%8kjtQBj+=Pc>jJcun%<!H:$>$6A6t9Ih%@MB%My#*hSB$LjlauNkPiq<aG1G$Ip9Z@LtTPM:\
4+$#H8 ^w?!4D?^lW4l@8CW#N&D68nqD%ui*aS1CIaWTJ@hAbY<ZRCIQpTQb6:5R%eq?RRm++YX/&l+TZqi*B6#
iHSITC G=HF^kRj5jW=J1Yu=JR=Ju4E%y!/%bNh?/*t=Xa%^J%X$Ai:6F$D%$6\c<9+=K5H9EI$MXS1&8<ht<F8
5=RNAB B8+>K:5q<8+yTcXnP^6BuW6PiTGNQPaL+Vy46Fc1SGG@aP=Ka&uE+!GNKeDpCBYRPNFueuFF5Z!QYYpN
5wY:eA 69jFl=#Hp?86c96T8VKIN^1l#1PNK!*A%wQXE=e$?di!qVN=c%qdVhpW6y44e+y/&HWpGwY^%b/BEWb=
qP1J^@ R:KPnI$>1=ZVPA\&KbDMn$Pn!B!#455SDTi:w=yXt<QaV!t6?&bn4AT1tQk1N<%#jFq*:\XWQ*&Tdl8h
tTZy#I 4lVKji+%Kil>up!X*:BdVY>5\5VKlCGaSjbi&F5nkw6nLW9CAb+qNlB>FA8jwnYJET?L@GyC6I=lFb=*
l9Lid& ?Qtt%Yj=6eN:MjMXR/u5==:Dm4:NTG^4AhNZ<*b#XC+VbdB5m9mbec68%!hZ8/n\tWk&*9!cI8XNedGi
a^n^nY h=Dh==tI5iQcX=w@Jn\+a@TaI@wXY/R4m4\wCwnFdM+<dl:\*Q#!cu=!w4!+K@H4%8tJuKDG?@Vuu&/N
m@$q:m Zn8k=?\+D$tX*NRd#F+KLN8EGP*JML&l:IJh%b*ePaF5S4@lKkLPH$IiSJ:EW=!*Z&V+!LF@BndkVL$V
>8*\IS 9CQa#^lBJ&lkV\ya^YBL@Pb5?NwaJ:8$?1FM>PtK6%FhaZ4NLIhM$PR<Z9PS\e1VFW5u8A<djQ<ue1T#
JDl*5c /4iJpEN@!+@b*Y^Ft\tiN^GN@8Ch:kDPRWXdASJu@+V=4ZmXDbLXeB!X*\uh6>5>*:mMDMahb$uknW:L
45A=Q> \?8w4m4w4!yZi^dHi4/6NnpZ:BLYmu/%*ewDQ%#*RKj/PyZq:=Km!T!qLRN$jubtTD8CtmtDRV#8YK+5
F/WBTV \$Vue/8*T:lu#Rja\DySh#:wdeJcDX>pQwu96/w5m@4k#!CI!hDGX$e@k%Cb5L$>HSJKH@p>jWWa$Tm%
j8I9TZ ^Kc>mpIBWW*%CTRP9&\DnDWK=G*@Qh%4iIC6+=#+DY>ca5eIQyu+awD8Ek5%Z=%=LLWEIES%%pWLaB%E
pK=DT$ YcpD!5Tm:LiTK=h>=JyDYCw*&Q9DDnq4I=IZR>*#n8n$&RdQYRS><tjhdhww/pnLYTNjK<HV$KKTiLc9
Yc\LAa >#SCCcTPKtVCG4kHmu89AVRFLlK/=:a9l^#hMhH+QM5i#DeCJ9PLi>$GwYGW14/GI#>1D@8XJV4IyJ#Q
e&wn9q JZ$44e\&PXG><5kmT&EBeK15TtL1FteVm=y86aXe1X@hIhT\^L/&1w9G8lw\:QtNdCNmTP^N*XwVm^pk
jJHtZi >P!6@TqBpSW!YwP6#^N5h!iLH6#8@&WiR<A&!@EI\<*N:EVA*!64/T!h+K%V#C5:i9mRY<>q8$hY1RRQ
6Za:cH A4!/EDVEietm^5YCk&p<T1@DyRi:ck\hW:cJ>aKVeS/XaW&P&55^&dAt+#DE5G5hicM6T^Gqh@&NEqJR
LSMD*a w8^heSa%Ca^6bWiSZkL#L<u!FpbXFXAJ1?4/EBMinJqly$R8X6yXmIhJ@<FFeTZtBYPnJ9P\Ke+a:KFL
/S>=W1 KACZ:?E=@Taik%1nqa:JN88WmueV:t\V9c/aY1C16$FaB%=l8XIDyZp!1h5PVTYF+Ila4*QWtWCSXmqu
%<huYG w^il9dXXwB&PC&hXCH^/CDG1hpRl5RTRR4BKPbw:8>lT&8bd>bZXD8$jtQE>RLlbIw1DC?R&LM\pBw4h
q@LZGk ?/&B9yeypMMjtKyk8dp</:Hk6$+@Ejce#485k=jcV/hwG9y##tZekFb9G\bXm6ZhW*j/c\q<uaPHEGH&
qC^Bkn uHZeH1/+%qLF*i##*TqIk^Cqw#wmh$K=c?!:*!MmePZEpD+Z5VE!Yu6kun4qZY*A&/S\Q/8kJ:5C#?5b
:VJ&Zd %A:&HA@+JYN*<QuYl1YPX5??TX899B=iS#4/D5uqTi^#amny9%hBT^w!jXppJTL1#b\WMIC:eeJBAP+8
%Y6B:E mEpy5ewNEGpLbFKZqu>GRVKhSMt4Pu&EbBQVcbmCkShHeit%Am@WJbXJB\HyIXDtYm1<!bXS6lC/Pm4A
4PcT>G FM$L$mB/R1Y$KY?Bby&R+Xd:iE:#EE!c6aW1%nXTLW>Fmk@L!j*dciwhTiC6*NW?EcXE<St+li=da115
Z%6bA# HjTWlIJ=Q@44:5:4/jdM$X#WqBB/Q9<dcdJ*JcX<@91*e\I=mnS%y!S&nFED6IZDKeh\&%C468jdX8JZ
5Fj@p= hHQBCcuJ%YJ*cw@d4CcIZ?adiS&HNFRw^qmVyTeLKkplP&j9m+LG\DltujG\>N#^\PE1!b+ZZF\AYi&Y
<4BC@< #6XaipTFWyln##SX9l!SC:NKimWic*^S?u5yQuc1Yci$QG%<ikEYF:*4eiVF#+iKSk+p19#SQT$#^!Ky
8H&y1S GNWn5I4hGTDE5@mklai5Sa^>&bVw4kie&nE46<Q6QM!5%WNX\unEQZpK@hS5MSC+=ilYaJLWbHtnXDEi
pk$<=^ aaq:?ICqS?L+uK@jjaBe/u&X>@6ayWGY#l:1!GGV6jC$1/@p^h4nCu%HPn1NNH4yW9wNH!F&^ybai+P!
?#k\qH !hcDkV*WNVcSX&D*edFCk\XCB=&>D:yMwkT#hAYP6k/DDl^tblLK$Z+JTRc8CjyWLS!#G15iwXeAD=M^
Ri!Euy >*p?H@bbG\nXK&e8I*A/F:JMT<Cnhaq1eYw:HH!lCTFdeYaYYcJ5eA@dF!^TAu6mD:cTT48!!wi1M*9y
nBiq&F 8:F9M1d!cyNnP=B*/VmCVWcb^bii8*4St?<eemCJ9qHNiFdWG4Ze9IX8@ZJKa6G<#d4/wW*i@w*muuhG
-ABdGH 0008d807b4d00110333 Page 74 of binaries1.zip
He:l&& Kuk4>uD4y/Gmnw1mEB?iC&8aLqS?I$*X&:5y8J!#lZ*GP@Z4FQ5FJ#k6#<M1&eFBXA:!I&Nj!8tw+eX>
bK:?Ch %19%dW$EyppA^L:LJWb$MVL<WRpGHGNT<1:iRl&&?whK9CcZ$#*/ebI<Z<$lJch!V6M!Kn%+Eel5miEW
q+qChN *DLQ6Y<Fq$jGtC*=KFP9bSBhqjFVEt==C%+Wi:nEeMtLjY%Nm!n$e&La5+KqStH%Jt+9I&XNJjFaAbNq
>$l9uE aK8CTGp5KT:TiEluj:qN6KRaH9PP5DThQ<8?w4c/#$B8JEd5c/t\#qYP\\AJXHy9!qWEhLcX<JW@wM@S
he65pD ppuQLnaIcyGJaFJPXP%MWRn8qNSQnPYln=*NQWqj:@?y$^aA4hEDuFMF5uNKR5wSFaQPCF?lcbEw$JB1
iJCHG+ dKPG<>tpy>Fl&Zp1p*JKWWcKyF%1bjll!Y:Mpkl/i\hSMk:aXEwX5=hXhRui>9QZReLHj!J\ekR5>JNK
J!y8VR Kl+Yia/KYWQ1*PJi8bjky/Y<!5lK/A!IFp1JKP=+Saj\<jXt>kD^S^nJ#k5$h<MwX<RHI^:\@iNm><y=
:>a+Fe Pwle\@PINQu4N%tM?+qAR9lKdi^Jm!u^<DYIk?j%RV1GpQMR<qHLI#V*1Iy\>4YhhJ6e9ekX&Zw>qh4b
Q9<PyN SqWiFw1E&FnnG1J4@=R\YXnm>lSc^$eA?ZY64e\$!QBXa#D5buF?/%<mjR9^m^t!Ilu^+^&!hje*yT/L
u4wa!Q j:&yqCVliEc&/:ktdWhPnMmP%A8Q*A4mYA4d?8Y#K^aTJuR9dnb5%%6uc6BdWYF+cPjAMw:!QLKH?SqS
?yLqG/ Mm@/DnnARyiFkY8RlbpV%qR*%GZI:$1WNiw+$\majMlXX9c1yRn9i%=#N%e^tyE/ySbc$bN%SZJ9N^@%
9I#CSQ qD4#R\R%T/hZyW@=kF*PWPmcdDB<yRI1q?lL%=\%qB>AqQ*+I@eQ+b=Z99*i$jMB?DL8NqQNmbnRTD*R
V=@%wJ T5+:eGeCb%Sn5Z/<:%qYddN:uj$:q5eQn=T$jeQll%WX4W@JTI&PF!DJb<tdbX1j55a>QLKjS@m<S9+!
u?SQHb 9GIE%u@YPH*NQ:S^jp/wk+DQ^I8BTehJwI<AVWX/hH46D>aSHnnTJR<KIJNbh\^6pE=$TjTJm$p1*?6w
RtddaP ?Lqd&IQ<1ZiEDGQF+Nk::nn%$!RN?N*$#R?%n8<EFpG=DkdHH<Zet#q4K\NBed@YXJJwiEK*b<KSi6<E
iNj45R QA@YHEa@!dqYZiCm8:AZ:+CXHW<eJnVD^$a5ePtJpbk!&$Q4KqNKYI!@w994T5!\&6#dQSFE%dSnMi<d
F+jY%! L$R1=+EYE&R+*jF::ZIj1#GiuVH@l$GEVY%CiyVe5V9TYuXEJYMmXDL+cNtLQp@i+K^q*qt@1Vkp$P&X
ee9>RQ DmDpE!G^W@RN>uiYDMGKjntXlc\*It&cmpcuXP61?>tV$n/>*^kK1iKGI=i@SD!#S^=1DYt@XDk\n+E:
Z\??Mm ^1h^YP++l8uWDLLJlP$#B9aml=dqHq4JG%1mh6+DW=6%h<!KDk/j:H^cMNSj?un5<%N>+Z#aCl#qTY*P
yliq<Q utd:ywNe9&%==/h9tw6p9JYSAG=T:E>X!HGtqb^kK!neNC%:CjQdk#t&4&NSma\1jjeNniZ+c/!VRT&p
<Z9*m! %ubwFN:8M%p^Vbb!/>Z/ZJM6K!mnuwYwn$!pbtI6\A5C6kh@1//Xi@b>\5:AppjtZQFMt/mB\>a4C!d!
8db=j= &l@#?lF><NwVlPLe88N:HwR:w4Wk^Tq>w$V+kI>1y^9*S#L/a>Wej8#Ln?*L=#Jt4iSE5*:TbTGmEdG+
YLw@CB 4+S:Z*Xb>k<>n?nmw\KS^Q8SLA986kk=/%jMNkdP%hDX%&hFN*@9C58G/H=@bq>SXWjty&?iaL%Y=nw%
p@H4ee HFcD<&nNNX+@\4N@K=tTG%&!idRmqJ$h?!L4JlNHSj%eV*i9P<mwm%1FPCmy\%G#mQ6C$6I#\mp=kYPJ
T+XnJ\ !=mQ9QZBKenS?LGwtN<qTXkKei\BZK*^pXyG8d\YT+&/5I59ni:Z4l91Jt&FHkP\648N6yB&9DPZDmdn
N9ntjV \@L4=!dpyY1Deedn:Bw=H+\!alkMC4m+qh=^S#%^@W:cXj1hh>XwL$Nd^b?ZlLuh\LSk/@%89h@XmEkE
4J!Y?T p&eCc!BB/NejJ+$HJh&N*d@&LhKD19^@NNRienhctw!DC:H5@/Xy$SMyAn*?B&A<\CaRVPMRFC6VGMK6
k1F9nA =ImpjLBlVmciBaDTAQH\^iZ/4hnl<l8#6DV=T^VyMYbq4=JemcD^$YAZ@u+/IZdKl^58Si=GGHal6DV&
iW&$6m !JZGJ@4RwiLyX:j=C#l^D/&dPe5H/:mCRc\8ikdMDkAauj%b^hcJpmEuiXB?aZ:qAiT?*KAbhpH<kZ=+
e^*6Gy *$BSpyVCDC!PPE!AK=<>Y1P#S?!Q:BMT<4@WQmH=@$9&TRD/V@bJkQ@9&1h@L+*@y+I:<y@NByL@d>wu
myBPNX JP^95LA@6pBI?F?#CNmjdBj^%!#<V&\ME9uZLP#Q^m#\%?!jBZtRku@N@1pFRk4>uWH@eTlGAQKjnA1T
bX+eq: @!?N!u<Eaj:F1AkK@dNSEiD@A/Mm>I@D<*>IKCcC<Z@@Bm#e^PVDqIVnpdcW<mRY9yTN+tK>#hJ>lhMQ
>dSMQe twLmCKCNCSb1d<My?4>JkA@*dJit^S%I/IbmB@Ap<ZA+d#9G*+6hM1NC11$qXC<qbacdZH4$&5JTW\*G
u&Mh$h aQP?9>ZDeHIBqKB:T1h1Ywh?Pp6%!a&PVADwXT8i<n$*R^n:Su:p^TVl9K^RZB@:WVM?@BCl8V#dE<jD
ZdpDeb FuYSR%e$@cuEXkZb4WAJQPI!hmlc9HJ\ZFQW5BbduJ8aWWpA^kAE%h<4u%EPH5Xhhe^WA?<Ylm:j1M5M
%tch<M y#yEj?RKT5/lB^!CnK:LuS!YkF\*#ZKN5&&Xb=*^LR6GE:QNGn@qVi\pnhZ^Gy#:t%W&VYb:B8e^T>1I
R%\+\8 &$AutR%KV&Q>Y1h%6P1Ct9TlZG$n1??kWhP698MByYNWYX*hNAytuYbwLGG46Py*8iPBk=<d%6S?kASq
PT\eL9 @XKd1G<$QKF$yQy^P*GwhiRq\bjpaa:T:?k*EHD5cHHVe4uGMi=8!pqEn%y?TDj$nYMT4ZFmj+HZ!+tu
uD&/jm dhdu^X%E#bD5?qVcm%c%mCi\bjLc4iHy9Mic<^HE9ackY:WF?npDqZ8G8k@S\FREcchh@e\e494FTYp/
l8PZN^ @6Ckdeku#MH9KNZl<9CIZyI@DF^EFVH&=XEJ!>M>j:*QB@8c*LiWjuhlppadGqlwZ<$8+AqNCL8qZPCH
6c$h5j AI:B=ynW>$+tCjeP?h%4>+p&uDlne!k=KJP@=kT/c=iM$:biMl41BPPyDnKT5qtq91DSd+B!ijTqInwV
\\+B@5 $k@%#BYmKRT\#A\NG$iMJ5MeT9B4&*R1QMKuW#6/Ye%!%%e=I<5:^45mqZbY1>pn%k5iT$ScYM*@+PP4
L=jaVm jqmT\Z^u1tik#D8Ict%h6lw%FjbCe@VCY/Hj\jp#>lFpd*LFd#LL!M\XE:kYPTLpi8\!>VCS/GYBAe<J
lV9b@5 Y4P^IYT5KbC<Mej*Z1GSldPC9Lla<t6KP\9N>i%mmFY1@wh?AZmX@#4QepCSJIEd!NYHu5&#<^*I@nW?
Z1LW4# /%6&kSS^65L#j8$ud=aX4HQtM&bjyS:/=LXh8*GJm^tam+%MyC+N45bGl%yd9cEYGwthy8T9?<j%/$4*
S@Y@lW ynbw+kW+a/bmmJ*DuKjILTZ4T:ndM?6ea4qXDj9KWkiF+d&:ZPB\c5p!bDLKNX@#+FX8Mk>Z1yXwtQka
ht5Ql+ w==>E4\#a6yRN^L8LCNhS%5eGENe@RJVT8naR\TbVit\R+YHQi*Ia6:Y9%VY4>Sm^p+DL?9RSSdGQ=58
nmE5MS nycIHj@E1D1<1I+kEL/n<1tVC+Ptm1\a#TuSqWL5P^*jlFpaQJcVpuH+Nn%THHC899FJ8#L@:RChmyWq
c/h5NZ #w/C?:N4=D1c<%NF846ninkPRCquHPmtAAbJ6IZ\jukINEqHDLVPh5R84Wq8?Nl&#\hu9KE\!I%$mp84
kteq@9 t\kNdCP?/$!I+6hhYJ!hI=8Fid9SVlbB=>j6cnL6S%$?+tk?5F^@1Gh*\Q^A4I#?t#/ZKIdkb\HmJ4bQ
FG5!#< ZNpXeXR#PtH&tVYqK:XljJ!t#QQpVaJqBGT&MJk$<wt?Ak5aVHKQ1Z&dH$DJ^G9Kk^SP9*q!:$uJkkL+
\Y*n>E mP=beZ/hG1+586K^h/S6^qMnPR=MppdNLpqW\QQ1Y@YZ>NMQti/$p1D4kNSPPma4h%yue4q!%iLy@4GN
h?&d8W dYZjZ?m&AyXQ<qT/\j+\6W1iB?YJ64uLVD1<BZ**uyyH+CqFPjYGR%61S#l#Qmm48QDcD+l&E?t9yPdd
FtXlL& e$w$FLbjJB#=ZFc*WX$4:t#eZwnIq6RkZ1nICWW!junyTND=kaPqe@wnX>ZL$*%6Ny@/Z+1KklZiyX61
ZHXWqK #uQJ%jyCI#ZNuSqlZSSt4uWy6@9M4ZcaLa&^ZNCEdcTXWu@qBhT4u1&?e?VFWq#n#@:*tBZ^uYKZGP$A
LlMalw Wd!/R%Ep:mtJK%pa#H5P$aJqj/1?$cJB?@TJ=T4A/tLSLXE\L*DuDXh&$*8u&caAm+b<^!J+c!YQ=X6L
RQ=k9\ @84leVY6Bu>A<L&5ZGW:9lVLX61K%@juBP#jb^?y/hbySGnVNnWbJw@:^1HN$#PVZNR9b/5eljb^%:yM
X/#?/K C4>=JpR\A4RIP<h&bJ\WKqIdFkjjtynZ8FbT!H<S!L&*NF<dett#*^L4<?m%+44/N>Ly!Z%pCXZV4WQX
4%F@dD iVkN+9KNt%%mD$u8=eTb1>Zi=d/u$>Q\D54yt>RNu&epmJW*PZ!kMX<&&I96M+C6^i^!u5%VGuDe!B5W
bNL\^j pRjF^i1AZ<L$L6JpR?q%BZJIXW*nXu?eM\:PMmHBLGdndQc$XuMH#QheJt/i5/Y$y$//&qw1&8R84%D%
N:>>D% niZaVe<\Hj1V/#5c56SM!IiqVZiBb59>HYT*SqZ8L%\j+9AR8e5G=uKnZR5%9Z8hi?:^6%Rjt@mmWqh<
mATXA4 Z%5pijn!:ISFI?>nyjDnZXpj!HY?ZRK@wGV1$D^AZnBJM5c<e1T4PP/LiBl<!B4:RP?ML$4J$Qk^aY/V
uhR$!8 TnbBl:d^MeuBS+idQZLA^ek*YQ#^CeXZ6M^Qlhd8S^=:$FLd\%:!ytMJhm%iFeX*Vl\$ke68S9X#piX#
j/<m#J yRu^ybI!cVE>8?QH$VWQEKX41R^duSXSueQHJ9PVJ^<G/H/ML@QItAGI/nYQuNHlnl<XE*e6pj5k4u55
6ae^G+ BNqtc@PDDG6^E1H4Jq&&n9=:Tw6aF@DDYHS$?$dFXube+*km\&^6GR:4/LTJmZ=b?1HWNGIQ1!Pj58N+
#VYq%$ 5tb:4T+GNWh<BBwL6#5Y?h1H4P#QCli#lhnZK=DW9:JtcJB8\&Qy6B:5QK/Idh$?KqjpBihQlqkE%A$e
h:6+I6 1DJ6NC5!9/\69&SB\y^WNCD^LtQi:d95:iBB%@ZXA+6whQ%mPcE=Ta^wI?qc5<Ki*TEXCdF*+=dFu6p1
4Eul$L +HVRE955*D1MbPB6#mA=d>qSCDB!!eaEdm/1E&PWkn<jd8E<Wcp$b<96W$?D:k?IQ!yZnehFSNtRq/@1
\Yptju q\/dHEWCZXS/h?A</&GWtNnL*mNX9m^66JEV<!tA$>YHjS^kZ:8y/Hypa4X:N1q@dl<d<bn1*Di4?QR?
I&8^1% A?41yDa<ehLL^Cw1Gq98*PHBpFSTwy>FA/PtuV5i%5bHjE4ZR&@Q@m\dTP>LSh%:ycXbQF4GYJ?ILb#h
I@d15P tXT/HKnD5Id6%qenN+&Ap%<aWL@cn%tHV#ec!atMdThBa:#B\?iEyLhhh5pyb?u&LF*MiARk9B?>dA!&
nay$Qa Whn:R#!p>eM98cMamTcd^8#QZFb4+maH66iIRQHXDu1#>Wyd+/KD^^4h<d6++jWX*AE^SILD>n%FLG?H
-AwE:T 00013f9425b00110333 Page 75 of binaries1.zip
c$JFLa V4MGYZ\iw\y\XB6Xa?p@Jw^YP*n?bLc/tNE:tBCu16Hump&MAuZ4R>FaF/N#jc^=+@G#nWh66d>=uR8n
duXub1 J5Nq##j5R=b4J\mMXXFGPAkPbthXcc&uwBV?GXdAYAm@XTWMZep:A>HQZ>M8$u6bHN%tD4eZ$+XbuEGa
d*4Cpp G8/XPjFn&cJTCCVm\kG%WDPIF6?eMt^P#<4JHqWplHB#Lnunk=Fc\4phIide#<J@Im!X16Rlq=ii?laB
\G*AyC 6:EEe?lJdSl4hlP>Jt8PhA4J$^SL\dJ5jlmh<jyYtq8m@6^D\a9pySyHSNWn8ab5&QqK$IWj%!t%myQ9
bE@a## N/+di<aDN!ih14LA\64!BWDJ<=%5PE1Z9<bC&&w9:tR\GZa6^yZ+ckAyQXWKCq!<XCjnX&!@a=@hmJRC
8@lRYy pRS9RuRk6hMkkunyai1wm==99R65$WSJ9XLQI%VPGcYCLZbyPEJZ=bckVd!SSaC!/PEM66=EcYKlMJR9
kw6\N< RW=qBIZ+9G>yPJm**8#HXZIX+!>bh%^&8@:T1<Daac8*69&<SWT<XXaAWHFF:YCEVGD1WGD:@PDcicuy
liy?BE iI<XRaD$JQY<iu%/ZE:yTR98Dk*QMiSmTKJCaW\w6SM+YF@w%Jt@I<GYc5<#h&K+6>Hw*8uE&=+=MmE5
/ui>N6 cR#kkty1e9MPQkE$GEmQXl@dan5D%NK6B$*lyQ8Vu9\J\pb%K8t5ukFKh%?&H&w^IdPca6FluSFN!VhE
bK8mY? R\nRn$d*K$SCu5ipJ^4CA4jPXk9q*JkYnypR&:X\WZiSk/b\Hu9pc4B$EkimV6JWPuC@c\FSt51iL%9$
FGPQCt 6BFD/y6R^Hw:H5T:a&MWhFBhu5ctCimVXmH*=&en/SN%5Z:F6ae1Z4m%Pm@V15cuclF66eyJ\$n4uR?n
n=/=^? c\CAMAJmGERX*>Ml5M>+8@8>=eF*Vmd%B5EK#!eY=Y4HPLmN=XKkdYYypH4>qpm+J#NjHA!uqVIYD/ah
+8*V^? McMj:&qG<e=WK?l=T/:/ypTwbwX%C/>S@diu%#Dh*i>p$*cQ+D$>mmjXSe9TR^?bamunSlNnF:qhwRaK
dqN5G1 AQyj6e&I>jX<^/5why$Q\?*1$hYANN>8LXKdMm^bb$9J%qEdXaN9RLti\NE?6?uM$mu^R?h9RKp\jljd
TBjD\% G@9CP8ENQLHdI$Gjw$h9puSiI:/!<WY?K>F/h\lWHej6WXlkK>:bRp+cc#b\R^Yhqbl>K8bSMZZ*y@Q\
jeJLa4 kNB9>:q:+=%EnmSeFu?Xd\Z\qnBGcHX1LHn&SB#BY&?!Ah%k+uqW%aw:m>ykG^MdK+*?mLBNXibpiSc/
H<:pjt %A8Ht>!qh$uh5@cZ8^AW!BDH<>Nnj=65LPaSp5yM!$4%JAPVmw5wX:S5FTCj>MJMGYWmF8TcVNX9bF+l
JSL*&A i15mC5Et8=b:Fi4Ze*=NXebI$TQQZN&Fb1&dKN%t+i#D!q%9KmN8Ru4=+y=M1pBLQJ&&Z&aWqeEDL+P$
T44Mi* 9NW9?T\k=YE$<t+*#+LEhpQVB9P>QyAVQVVD@^/\KYAT4@T6/LuBiVbX\\6!e\G#+lMjT\$\&mH<ZJ6Y
YH%B+h Qql/Mc6lV+mPm#W!*DI/TV&/?K!R%jRlX&ImYYKb6Z$m:t>Y!jwZcPNwM9qwhA1%uN1qPX:e\t6lPeG<
BA8X^Z >6dB&=B\4m?PM\dBDTL/e>bS#6=ulXJu%@R@FPkJIh\DSMHwwSBPu8YW&LpE%W?K<!We^^1&BP+kKF&i
/hPSHl JT&QJZSd9uq?R8qu*hq9ca4Ww^G5@1kuwNSS/:$4VDVQ^c<n1!I>#GilXGwi/EHilbm4M^6XNGu5/Py\
$Im<^W nabnuNKMWD\I8yuE%&%BSJFWTTQ15tuWl=9DlADIB8VMeZ+DnMA+*8uJ8T>=ctkR4+eBL1Mu<<IRX&EW
6XHMu5 /jb#Jaq5QkIKDPA\hcXw:N\lAnZFq*R84EP+@9d5F9b!L!SYmK$:VnX\eGELy$aAPMDue=//d=#pe&44
du^1@k dT9h6@yDAYBL5*AHZ$B+H$W/H19Q:>lGdb#<NSmu5Z<cw!YNY/CFlc%kmYVL=&Apn1dujXtMpDhkVQ*G
6wK8y9 i?k+tHeVIVaiSk6tQ>8^=9HN6W=uCbB&C@S>aTM+i=1RF^LhELw<y1V4b%S+Y6b8GD!nWNm!bLI\?Zt!
@YkKA# NjTK\TlF!P&YEwN4CE!B&whQw#qXdjcTe!ea8D8@XB\Baw=G4Edtn:%Se6eu%@#!B56WhhJhbh=Wyqw?
?8mGE& %mkySH4L!%bt/LC$YT8j?hPH*HhV=8m!5BJttK?Z\Wyt%cLP^h^9K!JXm%5tnA?L9phXdRu#N=YqGkX<
:LBFtk dGt%h%SDXm&:wmXXn!Cl44R=LtMSyJXZYmWHB>Nyhw6t@8lheNpV<FFnXj/5&>t6SQYbE:=IM^tSq!Q5
+L1dm< pVWM^wZGm9nKIQX4PHw@T=dllq$IFFWiaQiA#m/B#J1B^:y:lhV>k?^%B*MBiGm*E#ldtTB1b!idD?$%
ZLF$La 1kGEmmXZD1P/94HDLJXteeXWmA8Dw=ZK<YD1WhlClJ+@ej%1Xc=At&SiQR/k?K5EP?SISC%9+:8B4\En
4!idJP +K9Wy:?h!!>YSJ+%Zu:^#SCyn*X$:5?5tKCQH&YM9!I4ah\:AAZIiDly@5mHbT&Zl:y+E4T8u^:IR%S4
#qY<=? e4KHjV?NKB$BnkbD!QTP+RF&eHy\n9QpiK#58ebI/EZ@*wa<SL%4AM@YADtI@>ALZ/8N\N%Pp/?ehRZm
QJtRNj iF>qWi9Ncju$D%ZZ:459!Fw$?=lhw>mcmdXT6LYLkCTD&JmVF=:6X@LAF#p*B!dDquT>k$Tcy%F?A4p#
FyaA$: T6k>Gc&u!N9J+VFudbhb@6#b&PF!i=t*KcW>Mbh&m6>p5P6p=BuP<V/Wt1AI/<1ISAI8RY?duZ+LPHGJ
RdD<$B \K/qGiiN^\b5<N+>Sm&Q=lb<HDq@\X8yVeu%ZQ%T&u4AY&SmmqIjGGl@DThYPKyJDnXpyt!9QE1<\b@I
BXIBPI wAD:%#$lEb6cnu1AjqYddQdYja<hTmt^>QAyVnQWu/%M\a@eZA9Z5%He8>cZ*Y@nt!dT%%>Nwty:cYRl
tKka*c i=AY?@A&:q8*J/?Bi5A#qWhK?dLZ&>PM/DKVja^kcTK%MuuBCH/4Q#9=lmXS?Zbw@PR#Vk*!V:8=1iR#
>t\9NE 1^ZI&#8>:NaTh8!^L6jt?b:JScK4dTyjJ=>ulHFm19WnKZyjea1>:9*Im$Jd!i:aDl?un?d?$PBwnhbL
CyMZeB CXbL\9*X@@QBS%iK!aYD\X6&M#/&jT\lPS=ic9$c>T\Htw@%\q=PuwlKNZYl/AX:&jS8:C9Qpk>GYKEj
l%GMRj &>b>tV++qS&MYq<JYjZ:Httw@*DhidmcVm*^%9!nFej1L=\%?+Bl\>%i#Se<BFJi@ndG5jNZ!kZLayeT
dkEL\B GuAie:G4k+BPF#qk4aPEc8qN@B5*%wcSlK^4a$<?i5n1L$wXm\5IltjcdP?DAJH9:<jQ**ZFh/ShX%&%
4814an P49IMZ:+dL@Q?u6p*NH/==:F:d=bFQJCQa^CItIHlI*FRS$:&B5CJLCAWD+w\EGZ=*<twP*>klPyRc<H
%9:b>/ jRDC\&jmJnAVwH^kT5+ic<Z1unAwT*ybWCyPqC^nwhbBpK@QEJ!#ISEmFYkPCJYIX:?HGcRCFp$4ui5B
WZIP<& L%D5I5PMH9hTm>ZF5?XK#VqIG^YJEERtbd1+wnW/5ZHF/Em=R8@@#1kAAW#wi/klD=:=Kpl=LPeEi*D8
l$SXKL P84TQ>PbHcqqbmYHGWcu$:!*PK?P!qTD=Z@b4A@K*!YWm:TAN?RK=u?^tQ&+k$Q#c4uZuVK&KLq>$YRy
CNiBZj nFJ&9iWb1p8bpXQLFZauwt1uPTe4LADP#N@QybNFR6VVV$Ghc<+*MwKWdl/%B=bQH@4n^4^#t6YYijX\
p$lPaC *pni/iVd$?Wb!ey\AHh9%kI*!FWc1\uE=N:BG>N+l5euHtlC#*hERQp?h9K:jTTD\kb#j8Pw<KNMN66S
!9ye:\ 1W5P?^TLqGL=Dej?!tN8\Y\<5AR1nNDla#m$qZ%$4W&$#6d^6Q!wh:!5@^Tnq>Y9$QtIH<kHF%\9hIqt
uM*kEc i\^R>C8NG1kJLq&CP=?lytZ*WJh<+EdP&9^+uQL?pj\GhnVqSJDaInRB!w*:8%ZP:FHyPCiyZ4#1$Tl#
p9uApM ^ARF@V#q?/4Kp?+/$$A*awl!KQK/jJ@$/EcA%*!+ybGZ?AYETY/DpccSW\$i%bCp!T>c4KyABA$4CnNJ
1m!M=6 !c>bWQ5!\KQyPX!$y=FD%<mS4RF6pqM#ce&Z!$/T9TjBZ6/b#@BHYp5A?n>bc@*nh#kDQ\#^Z*BeA4D@
bw/ZI4 p8MT+9<u^!WE?S8PT>#S$ipjD>buEBV<6>$RFQ^9ec6@E&D@dnL?5^@=b^EqAQ8dAp\A<VjaQ=FJA5m@
KZGP+q b9?5y=CA\N>k?j>p#IJ@#eL@dH?F@kcL@PMX>ARlj<*CBQ?E=j<dLQ!Qn=Wk>G?\j^JXE+V>NR5X?lQ&
1cCQuT d<\4/J?5Nmn+N?aX@=>6>&@M1#<XnaL@+<T!hHQ@!\Z+@9*M@6jV:^@*%D*M*Q@%D$w&nud@itcd@<6#
c\5DLp \JFRBnkC?c?#Ew+W@LiV$5uX\6L%H@?E@P9Qj^/K+Q>LR^ETawDD+R\\GP^jS@R*SmL$u\!1AP\9Diy@
ALpCCw =ND+XQ:^kD>w<CRE?RPD!k?D@N>M&9@$VFwnRpWS\>B5&wQc/SWZT>+JS>Z94iQX%/>BEcn/A@:iJ&J:
L>DyRu H?BJqBAcbEn?&ydMQdH\@ZCHH=!WJQ^!/=R6SWXJ>IMPtCu!IVRBCnJ$npHBbY9:t9F+dY^QYytmKK=I
@pk#Wj Fdtu#S=W:R@d$^WFyb4ic/n8R\CCqG:LH4a1a#=S+lXE&1+ln?E9lD5e5#HCHiS!FtXVVXYay&E<eMHE
WKtbk+ AjW4>#q\Wi:DJ!!\H9&u@ZEMD9RnVi$H@HCHuk@WAGZ:9e4tQ9$!SbZLFj?uejAWPd1=lWT#FaHth4VT
FkKm9w 6M6aFI8YR9YyeYWNbkLX9Pu^plkBu@Qe+A1T^ywFZDq\#mCVepHMK$#KHQRL:=8Wucb4>JZJ6en\mk\t
5CZHwZ #/YHbBE<Dkb$KneLVk<XFG\N/l4ES/5=CSKhb\ZW8R=XGhDZJtllqeXtX/RBD=L&cX5Vw9*V5Nd!uQuG
maEIP9 et#G\:l$B@^ayM6Ek!LCqXXS=1QQ5\@m1BAnI=FqSAu^m^uu?55Z18h+ABw<&lSb4ZbR4PA1<I8=Bq*9
mAccPj +p&GnqZVY>mL:dp^N?G%bk<YlW$pNZm^hcWH4dJ#ZB1VduSn\QjEtAFXV9YEXGpKCd9YGnBaZ*B&wV@\
eMHqJZ +lqw/HTAm&&6h1cjS!FyLRF#P5ij<jQ%FY44Wki$YN@*n:RLpDA9kmW>h&adSj99I=SNWN\6!y?PdcTc
iZDkCa *9dPn4!ah=MTY5HuIS/m%@yN/+FRVJ^#<%9NN61<eWcnXP4duNT@j1R1+#8nuHjdEZLF&DndPAk\Qi$L
&$@4FS 11ueePn!t/Zl?=mQZnE/\cpIYYpj<@#HyX4E@K1?LwM=MdDhKpnl=V&X\Dw/E*chuiu=G8&D=d:kL\IE
qaRJVM mb%9i%DXeT8XA8Cp%nRt8iCwC#5Vhmw<HJ!>d@FSe<Kqu&\:YRAqPh>@lSH5d>PVwwa%uRW<y#615ld5
8d/Vdk :dSi6h6#Xe>p6>4?nLMy%HKm<5wT5?4PXjButt!\yX8cdqGYbQR>N5SW*eVPV>l4/jJi:&W*TW*VF5\l
&Cdhi^ CpwwJcd%dF/SI9Z1F/u1?:#Ay8d+M9^Sn^=+cV:EcbnV1>\iEp:BVE:pCM4na^QXNjwcc@>+AN%juuk%
!jJJED @^Fu=kmpJ9XNyluH%@GVV/d=V5$1t+d4i@FPZ/Tn8NkV!*uRZGhqWKPSeJt/5#NNR/Nc&TPYal@t&bS!
E@IV9u AaF:ajy<8=PJ#A&haae>?!phAuT4SDYyN6j=CywhuDS/$kIEQ#/X6b&<$Zw/Al@TtZ9IJIhl=ilKX:/R
-AFlaF 000e34e609d00110333 Page 76 of binaries1.zip
qb1TK/ #+:T5hYwHNK4VVdIDp!&u!n?ELCVCipEjKXQGt?Yk@bc=eK<eB::>cai694t8nXKQKcpq<F68eTZnI^R
!iDKkZ 4u!iaFJm&:R^?Y$:1X%PSiEJqY/XCKN/6dQMJ&K^+Z#:mS/*NJqbA+4hw=RQ8t@$/n^h%KKEkWE=d5ka
DKR>i! W@w=yk^8y8?Ki5*u1VmI!q!1C@w!Zk*pDQP=6LKtaBHq5nB/JWQVJndAtWy5RI*Y@pQ!9Yakd#iht99B
>%q=lc 4%q5L:D:uj8D5Qm\LQW9nyTeM1I&6*qQqQK$4TaDl#/aFbXN5+j&VD:pDq^:5LIHL=LHY8WJ$c9XwEe&
<R8kwL SQF/cMjkRZhe?tYjnAcKZV1b4iDFq=j4&R4%bjBp+Zp%1cnE6NJ/XqY#RPw$u6qG&DEAy!?VGnSQH9FH
Hl61Bq /WVV6ERXcedQnw/iCu:1d<pjWRq>=Y\1!i#!&l?\@pGu>aG5iDMb5CEeFl#JIV:N\e5YJnFA&$EbHL$X
lTlAbY J@=iXE>>uwt8#/i%19udm5/mqk8*duG$^^QSD6diM9dmQu>*!:B!$n/b=hJ:kWV$pI?AY@5qd9YKBc#6
+n=l?V CAX@b/de8^jEu&nL45u#!>8h\Neep6ZSWSHPqD694l%bIR6mVS!68B4Zcjt#SQ:MhumG$wuIt\<?SLpY
\Cw+mp \4?/y?JJQ6HkVt>G*:mi56\MTiejqq$bl4utYuR!jyijKG#NP$A6%6tekmaE4h*J9@M!j&iI$=CkL11^
nyBinF atup?5S4G/L<w6ZIwE9\!8cTY!KJ9I%*TG/>M/kjpAn>bVC!iyNmj1meIE#Na&W\/jCkJTGm+?JW=d/1
AQqLK9 HFTLJ$PHTunI@SCMa<beK@iQK\n!=ybCIKeYi%1?TFScRQEkPpc<J1kZa*G8WQ$cwa+ZIl$bFiTt4llt
=q55B@ i>cwi@\<$!%Q%aGekH4$^/uF9T1^&A:Xy#6cA5qM4I%lK$K#:=V^pe1Gm\9<JBk+mI\CNFkd>6%TGR+I
XW!G?# Xb#b$Xl5<?jIkB:+K=y=MkiP9&N\8F1d&k>nJ\@Nc+MV1EeH*WFq\>yjiiD:Fu9LBb=M9%a#bL5*eTmt
R9LIq> \/>$!NNWk8N>$wHl?SI6I5\d$WhkQk9Bw&$jVHh<YG\$/#ytk%:lHT>65WWi*FFSWKiHlhTd=wL8Wc9?
@I?F+X ECW=$d%RGHVkJyiEB!Z9+!nSE@1!1mqq<SEBwMp<L:hM\w!=Y>JpQE6NwIEP=A^P=qGyG/JXFdwPZC6N
WN/QT4 eyDKGaN+ARXV#ZhH=VXyPSQ+mm:FTctSMw@%GD:D!tR/V?V&a#^95SIh1N1cW+t$bNNB4mKCHBKj%1cW
YJ<t/b KL!eH*@P4EeMunth$GDHK^Dl5\A4ILm#HwJB4+tnW&qDR/#96bjPTM6N6Habc/A85H<tmd:ha#lm$*G8
Zjy=Cq 9j?Ntk&LS^QLymGA\?V/6ewLJV8nlneMt=mh668BJ6*HDmRTC\Jae%9mHl!6#/486J!?R@%ujWj^SXB/
+c:eFe =?>#ImTCAkX8YIPhZMGih>5KAwGnaID6mYYlwa1*!TANwwc^m#%X\KFueb5$!qaaGYJlYAQwIqV4embC
n*ReuM FZNn>uw1Ia@$bQ^iDA/1H+em&J:m+Fq%mX*+!\*m5dWnJDGlQbka:1S:ABRk^DNAGcC9KAi5><BV?ka+
\Baq%G Fw!!a=CXT#hu#Raw^c5t<qwT*R^6*!cSuB\t*IAQE+95nmLHtJNnEpj:uP8=\a$&PXJA<wmS=PGDjG*F
pM:hHM nTZHTE645jj:HCCe>KcKHJXanR4uI^&8+Ea:1Sc4V9PK>E5tPcM6$cPKHDYF/iTw=d6?h4W/<p^MdDu9
Kh@num HHCKwJRkHenH:W&Kid@:BBA&iaVQiLGnVVJDN!DySY+q%dHja!>bk5XWQi>$yt\j/\?&^B=pdbZ\/\G9
Ktuj+C nkC<jbqQnCCi1ZLljeY8i8bcba4IWSbGNc5<<?%CHR+J8=%FT<9=8aEVaKmK5D&=65!p%1nP:uq^HRi:
9bqNTB h6\*k9P*Kn8V65:e&W#PSqdF/J=y!@Xb/$E#K=h!XZVm5Y$?jKdjXG^=qan9Qqt%Rak$halwIq+48PGe
pX/e!J p1WXnWjy\c!Ea9n\5E<q\nL<mB^miS=yQnD!kD%Vq4Z%@Zc4=dc*81QMCNaq&S=&KPjXF5VuwY\M#8q9
<q>FHC J5D<y\$@JG8u%e!/&X/1LJ5S5<^DClp1bltnpuJ5QaI%><aaGmmC9uRGi=D596X<PMq/Ai5YAJhtiDJ+
BpyHPY !aW>1FmuqRZ/+1LuNCRZcEpjP1&pE^:wVlR5ZhIw#Xp9NI1hP1S+L<LXCc>T%Vb&iRDkZ*%X4Vdy\Su8
C^T&Zw Nmk1AKI8JGdkbw5jlh/1DiXL^1tAZRh6<N%+Kbn%T4!#<BQ%YA^^b*>MK+ua!@m=D$A4*JmkjcWajGt?
+NWE\G T\VQRA*M8dTdPP5N8NME6VZ6Rt:YL!Q4jHFWFV6CPQw#&E?9kjE%t?9=+X*NpJ4G=Pkq>M^5l1abe*DM
a1^&qW u+yKEDP@VNX!E#\mVkJQZ4Z#5:cC#<F5E1?5P@Y1DMw8R!Ya8hNWShLKFm<VeIYeJ+?cKuN&6By4>w#q
jR#C<m iGGMmpS:V:tK/atm^aw18Q&X%nS*w#>M^Djm:XtGXYFdcikq9WYGJD!!#pi1jCVEWT9cl8@KFtCb>Itu
/hQKMZ QybI>MKLtLX$j!cNCyMiChYJWFJLAi8+?mKVVdK6%Vt1G&<8YTCEBVJDSMnAiaS$5Wu^CjCKleu8/5Lm
8I$t*5 Xu$:K&AHjHqi1KukT<K*CyC$8uScD=/8HFa%1E%^VV1uQ8WIdc\nE*BP#BVdFc^dBi\bNNZ?mHJ9dXjp
X1=eyl VdMJW<WNdiaByEWQT<!%1bVE>9BVy<WI+&8<bdF%@c&B@Y6?MMuylt8LE^@Hp!ASE!Wd1MMBN&e?kT8\
A/^6>1 18T:C8BytEXX+:QbT\Mi1A@ycQiyDRLeuZu$kC%G1H14$BaL!@BGiJw\$q^yT9a8k&hCl1>eT?pDw*Y!
YJw!jY =E\RGERR%CK8L55K\H?11?pDmZwL^qwHN15kHV&$w/hNlllV^Ac$ElBcR!:c8Cj:kBY84WF<:PydTI$c
!h%Jt= 8@B\MZ*8N4#$$HPP?&Jb:6aK1CAq6!eI=6GPm+&!%RN+mC+4y$ceqqc1?Rw+LBm**GE&uiMtK9Rm$%i&
kN4+u* *WGI:!!<ykcqPe8H>Zul/i@*$piV<ycQ&>iwu=tWD++4$$$NJJuIcS51>k^VjVR<Qil8&Ty\8tFL+<SR
@?$<Vh Ri!qw6>#JQcyqkdX9iLj9hP4ZHqZd:X<CHCK<YBPn$bY?15$Q?Dd4:cWbcGXG8/y:H^H=AkwqZMX&@1&
&nKN!b >>nGu4TZ4jVHXHw9pPB:NZ%9bbRnbh=k!eq*qlM:E:SXj/p+k^P/1q>eaqI<bqKGelT&*+=H&C&M!+RZ
pq/E^d =Xpl4dRuw@*WjXHj<a61W+%dAyQRj9#$4F!n6R&IY<^\u:%NAiG&nWBXN>A&XclmdbTP=KTqXBFHuRub
S&Nh1V +bAh&amD9umw6*h\MYQ\TM<4eY&Zu1qi4khhDqFC%/ahyK+1kLi1y%#Yw<NLXueSijq5KSDmT!Ai@Yqj
!ZqmQj nq/qulLFZpBTGu6!?EC=u%$JVRPMiSC9%RJh8Xu/\GZVe\9b/+VLVaKL<aXZKLmY/#6j&*BDp#Q^@C:n
&kl+E+ @Hy1=i\5qh8/wMpd@m=A!h1#h>wjAmpLAquwuXS&XiebyWyi1:PJlW>!WC^%\T?WQcCN6Vd*1j5jiqy!
*pmGE? wwlac%S8w!^mulbYT9SauPF!C@h#b@i:dnFaK\!+==jHPwZXc=Qt9GnB$^=B>1nuc?9aSE8qF:p@aNFy
t^tBk1 wNDJ>JXKV$<N1FR^W!Xd64G?cbM/DWeu@/nQ$S1k1=T*GG9Q\eM!R%+VicAWKbH$t6+b5YG+Z/W%KWdT
5ClD!C GGn$9yR@>h&m*@RGVpa5ldb6uDByt\FQR@w%yyTbyT66>Z$iBtB66cq5M6aI*:YEKGS1B8p?i<4&T+mY
M6^KXd V!FFS>?=Q/Z^N:Ch@?W4Bya+F>q68PTku^1\KEtJP:N&I@Kae?nGM$RZCL6QnaiXnl+<j\VVN!t<hhES
6jy\c@ m^*K6@WynNR6d/&i9CP@CbW/5\b=?y4:CVV4SX1E@5VJ!iMW=@d8>LeS?<Vt14qR:F%&t1Ee/uQIa9I1
=Yc6?M IG%!k/@IDG=4JY9X&aLw%da5m!!>@/1pQYMk\Bj5=<MCpcinKyC$#^T/NTqE+qHeb@LMEcLBj:4@pj@k
Cu4kNC Pp@1NKDQ^8W4k::d4&:EF!X6e5ZV4?IAHwkX!tlja%dVdHp:SCFMuGLe^LV=EEaN$+>JkbF&j*ZG?Fia
K$j!M: JMw#t^IJ<H=nCN&*6PWuqePuq/8NZeQDC1wKK5N=Yia$XPWI6&881Ll>HJW\KEhkL>AbwHJM@cdH&6*8
\ipCh* C6H=w4RIA@ShQw@jBdDT/Z#:bhy=wS&yYmheFuhm!Z\>tylmZ?9c?q6&Aub5JFp95d\XjY\V/<1pD>?$
Gnt&XC cRS?5^<a9eBJp8V>TG8lCV@TP\Z9\F>yX@H$*upp&cCpW?1q%KHb4<NWZ!TTpH!I<NX<dJ%q*DAiK#^\
T%Kn&\ Im\VFBu9R?MdtY#QlQ<k$dSm&w+>b>PD/IXihV<\c+F65jZ5lWH?b?Z9SByWm!\!th^t9/*LSZ/dw!*a
cTCR*Q $+%eYqBX%#Vnh<6H9/4p*m+h*=jMZ%&eSQkwj*q:LVHDE^C66+$h1SEn:XM+9aBZu9dtw>=+K!w8@VHl
1<%*ah 6bjF/ZyKn&G*PcKpLpIy+cc>I9SaWbHemVt=tnHDSD$H>i8h9PhqVGI>#NeXD<da@6y:etWZVS<cwT15
H>e1T6 4Sy*^cC?MCdajHcp\GMSe#XLtJ/Ye14wJNm9mCQ++9NRn1I*\=A1iQ$!tyk/Jqh5=LH$qaC$BpyjV<!$
u@Tw$J wXP6JdJw>G6uwF/Cqb$pKueeu^LRHChQ>n14NL&cplE+L!tH$A##Y=jN?jSpMN%@y*Ypi$/l9EJ94L4+
mEQ5!G ?Fp?C@#nWQ+19yeenySb4BejGci>S&TWQ\DXmTM@IP%P*$E+CE$\tbKtNJ:HHMnCN$cj1TdYuTeSQkwt
kPwl46 Mytd#WKWE!iVb!#86JukYS%qp&Lw#*/$cL++haeda1dD8%>KE!&!Lit#4R1E^F9p?5dZ9KuT<NYdCC=>
JNM6n< R&M!\dn<=9X!@*tnJZ:@cKilVtiIaF*5RMtK$N&A!wlwDi9LmJmuyeCk^M%<J5@RHkiNRLYe@1IGJ?NZ
4MFaF8 VBHAHFXX&A/w!LjCiehF$jQp$Z&l%Cp@Rm59L9^!&TeCy>Rk?b!tK4RhahnA&HM9&GLRYh<#bj!BGu!i
wAFGwP qM*l@VDS>X&95Eymn8Jn6?cn>pVPy4h6d?W5A=+CZ>&WEik=FLZ@!ay/R9#@T#NNR6C@<n%CEQk@?S+l
yc<%ai !D<%J^KC@N*tSQ>SY9%QBX8lj!:dC$H@=1y+R9C@blF@p9ESR9\%C@?Vbn%C!L>taZ>T<leT?G5Y?me1
EZ$qk9 TWn\4>p@%RXCRu>ul@>\hVwlCPS9:QAj4#D*d!@:j%?SF+L?bWZ?Q*JM@%KS@@eb@D<?=^<%?8GH@^?T
dndAkG ccLDlQ@9u&q1p$I#nw/Hj=F!Ec+nLWeJ^X$\tA4HMtW#$k@$qc9S%!nFIIXl+qW!#cltpc<!6ZQ61LeA
!S<tuj YLuP&*Cq=SXIp&IqpHIwTJKIbtBMu=pT!G?Jw6TeehPG<%b%\h8t*&QMbXG1qy!Wp<$DCQHJwleeK9Z&
X?iyEu \K6B&caTW#Zy?Sbca:YFTLS8NZH#yREW5e$84Dc&5ZMFm@FLLBkaB/a<%cH$8^LYPHeiy/^6:d&&titV
$6=V6W qu5@P>bjZXZm%M^J@/a\Q:JY?W9wSmPM?8DZeL$=BhN>/SlFw8bQ/J?pmEa8Q^hD>ITP6SQE%N&1M#4b
+$V/Fi BP&Q%!#D&#tNdupw\&9u9Y&\+BQ*tZdtk#>Fi6n>ZA?t8w=tj%pN1kXd!u1j1/SuepGhl/?6^X9ibNY8
-AKq&V 000bc90646800110333 Page 77 of binaries1.zip
<cJ8It BDkpLLq*b$=lPu:E?G+Y!LSELCuqbNLk$Y^:JJlPGCwIYa>LGW#Zt6dRQ^*$kF=M&6GcL:@jTXuWqdJ:
jjZ1q> hjLdQQ!:%Ti%e?VdMiZQ//l!KyGCeMwG$^DT\>:\/pjj%M/W%pVjD$i^5dn^WE1:Hqq=5D!eY/TyctmX
+?L*a6 Q?p9<l<b&:P=d=W1<*w/DAlTbEcDu8L4l5e?T4=^/iN:Xa@BRacyNHup9c?Nd^Y$:a\LTD=Z&:mWJu<j
WJ&TJ* i:Y!R>6pFq4T>4Z1>e5/dT$?jW@%=4#Lib65kbM>cwXmn#k5\YiI$decG$i86adnXY&CWXw#YR:S6Jua
4D1hqE /e6jnLQKZwd/=Ne8^PEGTd#Y\*TCpBcSIA*5Y6lw?VRN5<Hui*dSt4d<4aJ5!>bQKw9hl<euG91J8pA?
j^!YRF /SGu=Wh5Y5!=/Qh%85wNKByB>8KQ=w<SNetQ\&@#G6+ZniC^9lFyHiT6pG\5SyQBJ=?YF+Nmq=%k4G@J
h4#BEW i\h@XI/d&<iN:*<4t@%P^MRy#EMp#Fc%FPkAcmAImnSJaly?yC6J9Ct#N<uLKiYIWePNDpl$wch6/Z>B
@VVY/A jm<La4>Z&1*:pDCnTB^T?WSJ5kqypDy8GVM1Z=^?yXNIC$6nH^lQilnc@V=uGMItF^iP=>u:6nAKk:kw
EXm!nF CGdiZc8c>bG$6W*/!Sy/aKLM>XX#%5iR:6y%kE+lEy*ww6:KR4>GSPiSdiZ\@mu$#4!IKDBL9FS^aH>\
<<t/?P K&%cKGB$d?KNG@*q!APRAwWBJV?:YVYPIt%IR4kyn>e<WL#j*4uKMmH4:K#Lc9!Jkt&tAPyD%85q:1*+
cLi*%b \\cZ#HL*w5>XGPqSInC1<iABi:NyMX!ZYyEX&*j$Ab:JBbtkuPj+>aS46h:pet86q6ayp=CVB6/6ML=C
jj%!p< 8KEp*b&tZjnV>P9WXa4iY/jS@Xa?RejXLN6yNGhNN>$HbLi+iIFGa@:E9K>jRcy+1l=Zm%H=n6KQPG@=
a:FnFb wnM#4Nwt$cKpmlDhlRLnMy&>!>^Li@CBZ4$Y+&i%HPd^m4m665WQ=e6W%:bF+T*j1c>*5XeH+AA<emN^
Yb1TTW k6:KFjpR/clF9tw1ie=hKn#weD59^:SneWaPVqJhLj9$h:E+$%9uby5XSl!P=k4mcwn*kY5*LW%t#V=&
SNl#<j CZCHTnm>A>y=@KuLJ>Fw*TDNiX#b:!N9?bhYiYh48V&i<Y4&dcuX:^RTD!T@?ZuW6MKKA/1I#SI$#?WK
@jH+Lp SlCF6Pm$!//bu?#\c#?c8tJ#qJcb\Xn#Nq5cYXIWJiXdCjpjSSZdKaC&l@t\jF8:JbG!+GYF!1HGZ\>\
>ZLDun #Jyec4HB>+MQH84G5SSh/TtG&L%@SkY^B5%Lb+tQjI51@%JZ5>5kBW%QHh%Iy*m6NcqSQc\Zq?w*k/Fi
akPPd$ Z%ybED/FNNRNRG=m/F+$F1dBy#W?1ER^&YmdY&B4J>1<$XA*/T&qhLbFLZ!#/h=l6q6\j+4?IL!$IQe$
IFiA:I uHtB\bi+RSb%yyjQN/:ZT&6K4:+e?bI?ySe1WQ^Aa/?@/5qVSWT%/E:DW%dk9ARdd%**?/+56#nn!\9$
5<p*XL wJy$?j4GKe#ACYdS<%/=VLc\lhy4N8a=nVZ68y%8>1dHRwM#hl1>MaRFH4Vw*lkl1KlVqQaa?GTY1=ek
BSk*1J BYbi4hN&5y@P&h=FC8@\pCu9qPwFJYpeQly>YX>lZhuYjId5El!X5Xt*@<adSyuh8Z!uJ!AnJ>P*RD$X
Zi%:c: u@V#E@\!uAkHudXp8iB!*@AhbXCik8!B<GMqtlDmNK99iQhYC51$PL<>*Mke$k$LXJTeQl*blypK$wdn
LPD:8F yVQ<dtkw%LucBRdHlJYkt^:\6i@1l<l>TBYZWRE+4WZ8Hp:V8TINSd*i==84C\m+LyD%*>6qi$C?A=14
4*ylL6 *6?LbpC1>F8@bNn5W$l=iB?QIQJXnCd%REam9QjFpAGqw4*N:1BAit%e5kiRHlmPHVXn:=ITqK:V++wH
mJ>%u5 XL9BX!wbd?8=LY:LXBiQ@jkLwa**yj@yaeCQS*V^<L9+1Pw?jIXPi4Wa#8\ByeZ4@4&5@D*Hn$ZlauP:
DG\jS1 pyNQZ%\?TPuK5@@w4q?^Da/P?tL%XiyAT>h$puBu19^&6P!TMy@@W%#DniS^J!9l?b6u&*56p&**nYM9
6ReXkZ S=?8h@CE9KLl^X<N/la+Y@+M8BA/+1&c?Q/$y6m\W8Py9<eVPcSDZe9Zid9Wl/P1A%eb?J#Hu$%dJ&q>
$/6iRI @ER&!y$@<yqEHPe=KltqD@*\pqNyaZhND5Hq4h8CJ6^hES><eCV%I%d=TBD1EP5JCD&R&maq&HW>I5Zc
?Fd=ua PP4=ZC9wPkahD/eP^5NYC>!yC%^SG@%XNpd/q9n&KWtY>//SlZX$:b/E:pC%uuSqqY!#e%m4/VbyeeR>
JLyDVh jFp6k>Fd5PJDklIn*&P/&BJ/t%NjR?qd\@ypI/JtI/6lj*MSeKKnebp@Dn/DaZuwPQbcP8>68qpP5*u<
bb@ZCK Fm5N>:cS6iIlEM<aaBWhXlXiTbn%69^I$<:*BV88@bBS^QyJNbEuSDGid:w>yj@KtnmG9IS=+=^S1&w9
6T!pIm wwFeddTB%JK$epL4b@/c:AR4/KAEiNc6Hu%qYMK6G$/*MhyCWY9\5>/JGw*Gh</HwHuLFailw\dcCmat
Q#9cE= mWjBYCh!dN:P>Vh1me$R!%DD/B@%DiTc5nqLyddXXTMpmkFYa+q%kV8Xm6R6\&8c*QYXmm\EiQ$1qh@I
1819bV Haky<@YKdhh!GFAElhMHQLqWDb8EJ/k1=/+H@MYLpT?J#HFXTt>X$jV6E^lqQQwKN8@9mTbjmNY$b*Tc
#LLEa< w=6%#6XiBb:\PNXKehy:e&%%:9:!XBCm\:W/1^wG#a4JYpZcqjTu5V1uVC@i<ZAZS/@Gd^y^:>TD^9ZM
$^I@M6 ^$TnwVy/&=uw@5mjenHWP?Ec+&IHB:%?61F<Te6FVqLF8@aPpWAd>nR!quqNp+M&kl^RZAb#bLGTa&Tt
SlHqmM 1/@hLQjA/cMcjuIR&#NtZBitMulVLLlhDhZCNS$?tMHHAqAb/>jbwd#BG%Rb5LI4!=8%n5YE=uj!t@T=
$qp+ma 6udGB:^ZRjEYS*:lpWD5%4=6Iqjy>!!ca%VJH!jl/5?Mu=Rw4a$LY+H#n*eQaYZ%\h<1L4?1Yt8FtWKQ
MVuF>u PlG%<@qX#YZ:t:CwTeV/P4A+TbDaE%nqm<cZCW%lEZC>MmlTm<FRu5aPJ6a%t5dq6R+*J:p&QZa+YS6Y
n\6=/\ mB>cSD9NcpbCQpb?\4H?<RFCL#Pn+DiSF?XRH%1yma%b4c4VCt$c+!BqZa&\9#\?^Xa?Y+P+BnkeiR&!
/Lcu!! q%Qp^!d%mW%V$A@Paeq6VKpm%>bQmcZm!\kHSF\*lXFcZB8>!^HZnH%Gk<4?IppujL8D^8FtKk$:Rqkw
t>V?R# T#c=uJ$ju/\Q&4u4IhXjlMG<?HlpZC/Bj6P?cnb1hwG8w$i@!9dH<=kh*:He!y1LAR8ZuyTP&pWJ!%PI
eTpVhm wi#!%HpCVAe:YNG@=K*N=c:W>qJJEDlGJKw4\EcnA6bkIMPBhG15T4=iu$%4uk5t!hK>k:@b4@>Hj*kJ
qRXF+P B<Wm#\+L4:^:/cTi:!q!VEWQNBl1ZdG!E:#wpN!tC9!K46%<lKQZeXL8&YP9Wq%hLH@ZN%qy#nVyWMqN
Yam4lD \6$B^1$D!>68EV4jp^J#R?q^==hdJq#blu5:+Gu^!lk+Hc9Kdd6!^DKnCh<@tL>IK?i$\>yXeW*YPV1#
&mc45Q I>P\b/&$\YHCB6DDh#yqHTSWNSP>!@BW%\j64*$IT^*$t?@4c41S1H9HiqVCQi1u#VuqW^K6b%+JSPCV
C/Cutm ik!@JR#uCVW\$C\j8t=PZuim&lHZqtGeHiS<bRYSedRI\GimRY&eny4V:JCj!hC$Wj&Glmi9V<WY1tc\
HA8u<H S@kV%wpYS^@a=e?a6$KK\t8jyddJ5>BjWy=Na&d6/%ljEujKYDF1tVnwJPShEdj&>Z5bY:^RnH*GIuh1
eW5NAJ #6pcEB4kG/cRdR:+mu!1P@nBE8pLY9R>1BPYq5VlqYR8HXD=hjmSJF4pJR8\C@u&q>*K>Fp/VFLA91Je
9IhKTe t9eJ*5q$4VSyG4:bT&duBI%+VduCEN\K1mdGYEwXIF5e$CLAIiqI<?cwdP<q4h^L==IQ^8Wu$n*bWIZ\
#*>XRk eHtD?K$D+pC$XLGKTl8Fc\w#ecC/XP5C>eW*p>ayX<LSYP5l/>$6l*BtG/^hbbT/5K&hFEXQAR/!+kKH
JCq<Xw d6TjpEXedN5wb8iDM9bQi55S4^qmR8JE$JXu8ZaR!>Y9Pl/GVSc=ZNpkA1\6S<pw<mVe/5S/8P$EBZwW
F:Jh+V :*/T>cGTkTY%Y4mntmJ>6ku/pTi?>NE#19DW+BL@AP&H#QQ^%V*d98GtZ4PewSAd#!6lu4uKaJI954Li
bAPN=6 1@9mI4!SE5WHK=YNFY:=K*9DK>9#$uND\XmjaW\AKQd5l?Qc<IT*IeYH#\lYmp+9yKjQwpapkcPmId9n
AHM8Am 9+a9\*m8%GQ\At:6^PMSaR^DV^91Jiw\4!?HJIc$BhlbMc$Sn#HjXVJ>5HltW@u:NPZ^kymtT^h5ue1L
n+V9in DWJWXKqYDHcu?RnuJ<he*K#4m*deAT:==989wV44^#Qp59cyEThX!5DniB9iQi>i>Q/Py5%QSRGLd6:K
6HDe?y AT+K<W%mNbqwmQh5WjJb@e/hd9DulCbIj99\qLS&RkiDRipZJe$XGWW=8elq$GnuT<Fj+A=AQkCtw$Aw
$6SH8P h<M\4knq4pVqX/Wj:*iP^Ji?B#p>AdkZkhe!mXt%^=5LF^n:E?cVY1wX5GaLF%kd#S?mDmM9M=h#6k+e
M#AlB5 ^n=4dEj8ceJ=FBmBB#\b84HFH#!HcF>u11yMS^PN1c\N:p5Wnu6G:L11FJjpTR9CjG\X\J<#d4Y&T$Cw
!!na&6 hB/<\X@T/XaBiB1NH8SjQZ$9l1=b#S8ETJ^6%l*SYJeFEedeCeJ*tmEFVTIR^*i9MLiZ4VtX%yiyR*+Y
Ge4l/t uAKF@c>w5Gjh<e$$QXZ565h5k6jkY>E9#AG?Z\<eXc*iCQd:P#jcX+WbY#kW+#&!ZDV=Jt\6LGTSAh$#
Aq?L<a VWF&^hRIVd^Z&Qb4d4V+tPJXljeKt8=5&qkD1%yZXZS8IV+P\J#MqZ*Qc@%qJjPnd9mp5mq<T9Y=wHAu
pW/LB: DM#:*uw4dGjWYDN9!8SL6V\uik+DLH8nJQ^4YP!Le*SLN6C\M1:Tlj\*=yINlb8?#L##5eTwtcM<+8+H
R$J>mu *<+@*4:<88ltcJ^*$ljbE%85<LB!ye/CIq9C\tQEc8MNASjpd%&Jj8J:X=QcQZVF<S4k<WQQ?FY&iC>N
m6%DM1 c$B^&mbIyL\QP9C\G?b*NFBBXCld?MCK:uR!/D8N</!L*=t6&qK%:4Rnm9P>@>Qpmnbc+8I#6TEPM@:I
Il\R^Q $?@19J:hltZmXley6i8n9SMyAy&ud&6Dw@qVj:4yqX*1986ZkXm9<bc=&k=&S%eT9^Qi/G=!iDeZ@Ma1
*%n:6l yNcQG:NhyH$TDm:SM/\14u@KdSn?kV@WkZhuAQyS5miG>jQlJd>TyCN%i?uANiNa1!\t$<?>^GJlBXL*
#bSuPb AhK9\%9:#195XPHB*5\Q=#J=!cGQ<d\YS%&LBLPYRDPSaKiy=beiTm?pTYZKB*p5:?ZR6/859mG5R%1J
IRW5+S iAaBA>/SD+!9VD5^IRtVKJ4p*@HX\RNbP?XJ&Cj:wB+^l!QR*4jNAlW%aT$8QR%wQXY^uj#>4bDC1%il
S%yCi& up!8&AY:E>:PIj%p6wb91BmtQ4bikR&eYKc*^<$pFiiXS:ZpJ>5=J>1q<a$*\teGq64=M:#X18y#$15W
DHh!RK RaTTMual<V<HADFK><5Pi:SuLFR@IS/:8KJ5biumi1%ba\\#w5T8CT9&uk!<EL%WN/@8:NHh*+qpGP5q
9Jl6Cl un/qb<wtKNIp44^Yj91idiPLu!/6yJE/9YI<!pR?<nhjcNC:8ej>PT\C9kNNMb:hPqjGeY9BXVN4Q&KV
-ABARj 000428ea60900110333 Page 78 of binaries1.zip
4I/+XN u$cH4DI=K6*+ZA\ZJ#IA*=^$G*+LIuTVQAL#JcV#HHR/pqLJcHRyYcY5?X/bc:^STyW5wA8S8!a>LF8d
#56cZl i@bi:wku/l!u:HLSp*nRPQX:@bBQ*>ZETEuly@P8ujTX+lm%l9nRRD5qF<w9#dY*Aw!pDH?W#@m*a9j@
VhjFaq 5lL>9>Zj@/BE:@cQi+w&Ft:@ZSFYCQJ9&^Zm@:eNCeH?4W+9BQ@*Y<T@Q\:=::eC@%ddF^L/>^w@Q\V!
n?j/9q @<%jTDy=@GPQ@nH5@?aCaQ@^Ji4@aZ!I@=JC+Bj<J+ZAL@B*FeK@H/4@ZGH?y*L<j^!R@$+l@HEyZ\km
\&88Pm <Dha=J?\ku@NIkRE@ykX?t5Y@5hyFCF?!F?#5D>inp&Iu@?9YimjHC6?/N>kIZ@C\9/c@VN%IeRQ@&6a
QH\@:C AQLH?wEj<VeG#a@<a^d=Q/1L@!D@H>VFj\5R@I8/kQ%#k=6@t?#@%PAGm9m@aaL@/YECPwD!@#5Ndk:8
aS6!V4 cwImdbMBhqekH5YER/JERPP!>V&mSMce<8hKKd&l+y#B?9<TK$mma@pmh9K^:+8mm\lA9MtFAh/Zi9ay
AX8>RW QwS>/Eq#DA&cVeCFGQPB6$D5CDLDk:InnnNu9^CcR:XQTPL^WpqRTnXN5NQkWYHy<?CSKi9M##a@$^N8
@uPc>6 hw?^YlXw#N=K4#$$E$^/Lw+ZQkF+$9p&J@^>Vm86DIR8&/\^69Npe4IGn$XLJ8bIc!c<bp6hB^%%1j#a
EPP=Ec ADdRb!CLJ1y/9pw^X/aqYbDyJQ9SRXChPH=l>bYMAe?lHJ&5yI=/+NAET#c4+Ne*cyX4Z!W#9D<qc*/Y
h>twDZ dZY%CF=eYAI@nWZGWb*/6RiqC*t9!%>=BC^et+!8c>Ew+#\$<CLw<+56kkh@YkI^aib::*BjlIVh<+A9
Xl?^XW S9FMw*NNHB^bQQBw1wKM^Tye*\:ke>cZM@LZ/\9a\#dDVS>KF<Vhjtly:4N?5j&pTVqEX8QTTZ=j$:X!
A6C#K8 BhllJ4Jt?D:dluLl8KV4Si51tF>:SQ<#aQX5I5XL&!E?F/$Yh5<T9pwCG#kSnupFb/V?My*Y!+<u=EH:
=GVVZD a6lV$YjE<H&XF:PnAL5h4aN4mGaG<m9\1*bL6!H#+yedV:by&&eyGME\pXZNIT&iQKL=Ny>EB?h4kVj*
?\=&\: Qt!K&:u5+aFW!nu^WF/bt*h^n=u/:j&N!ad%j/LGNI+tq4>ph:4i6>5^WT+^6Pn>!YyAt#Q:qIY9@G*:
D/PpFe X#55A*b?J#AQ8C9M!A/$8i1j5EPA4<Q//**ujb>w@q?mT>Z8/&P^RcwY1^#LamN4VPQAM$ReD>:de=!1
B+:nZZ h\KJbmB+Wbd&w>l:+Y^K8RZlpT/Q=lth\QJF#::&B1FRENGw/cqRm:P%JdeZJnJHImIbnSXyL!/$?V\=
:+AG$% P6R%TnS^wkQ1I#<NLPjbTdy^!E^m%jInd/bRq=@M8b@y\PbecJV6PDlLe%%DeL@V^DEFcNaW?D?RT8\6
P+@I$q 8Km#a!ma^X/aw?pVwja<@CTHwE^l$mc\B@FmDhA6K?Zy!Q5duVhCB=wCZ^68lhuaDTmILDePbnCd^>Rh
9NLH1h LZbaGwFBH:5<bKK$=J6KHTewbi#!i>=JDYX=QHwkk8ANp!u\GHTpVJZWnE%daW6ZA%E?KAqWjC<T#yH8
5Y&h4p ^KBR:VkK$G#uWAyN5@n!ku%9<\&Fa^XPwKZY?%/ueF*:pVmIyidWmDVjy5YdDY#l:J%T@GapQy>bp=Ih
5X#laC Jh%>uutXSJ%G!$THX@=<QmVEbjcH@5$mm^Q*=%Zn?u<uYmY:Kyd8\%nF*&m=/HI<VCc>yh5*5N5VItYt
wh9FqP \NTC+Kd/=$h4+\MuM=t$ZSJNDJ5>!Ee*%EhXmc#HQe\c\b&4?c=k1!9cMZXH^\*5IAGC+kH/?yXE&wjI
k>Zw=$ 1qG%y@N*wnw/PT<KNA5iT$A?1>A$YNj\:wM:h@l%dI<6%AbnX=GX*4bXpwBR>=6\HCRt1VK+LwZ441lj
=+d6M\ 8JKI5V1?hyeHyj$6nJ!wi5Ci6JtP#$&6u!pXB>u@dbXK6#@S1n<E^Y/a@GEcqW#V<cb=6HX$Jh5CyF&m
TWQpDu mmaEJ>I*?\*MIm1$<VRY?@WMFyRbmawBD4XTIj^Yme+cmRqG*nDC>pLGV=!bP%>eJ&W5&pBbdB=XaR&1
D&<1wa i>X4eWY&lTqG=GYd*w?5P$w\ZpcK<I>6MltX>%?:P<clD#5h?!mk*FFRy%tMukQ9V!cL\YPXeNRZ8jKJ
CInS<K ?#&tQVM1t@I&i!YMeTp1\Vk5^@+LLdVw/AMLL85*L1QJhY\q%#WGe/I%=i1+ljZhu?c^K?PDhVkeBb<T
?LubHw \C6=<^8!G:5y$iD/Nln%q=Y+:6k*L+&:JYbD\A@:dl$65q<qJqJbPAe5%b:ZZeP4ILYc!QuTHpuNp$<%
J#cJIQ Qi!El?PW=1pi#>:Z1Kn!ZG6B:HpQDu?enZjk<&&KSMeuZX?%a$:Gcm^&4R++yhYS#&abIb>#c@AMekbu
%k11Tq /\b59#nSALWMF+cF/hkBK=tQAyG?Kuhj699WVY*9%:d\J^e+d#q#HpIBXb<?#XL>LH*aGJi:$Nq8dwJ^
mCkDVJ ZFF<WTCjY*A+JPXkF?lt$D=t$bC8HnH=yH*Ba%K#p8Z4E>8XN?%Z9d8!B%c6&w>euTPWXykQHQe@dyBu
u5htcJ Xc*P\K^nE$\ZA6%b5:Dim1F&hYE:aeh4%LMhdnRdPJpV\QDHT/NjPc*idH%1=9@=*DQ6Ab?K&18Q!RJ<
?Cw!Ga *n4ZBwy9QN9hH:mWShKYha!EjY<wBBnEEE4!k4&i>9qL9mEK4pkh4CdZteN<qK\yqeyyiS<l%aF+$PG?
><It+G +G6e*+WyjJQ*=wlT$p\+n5W649m!=1YT+@L\Dphq\>PqXQFF$K\FS>wJ5ie:&KFLb?:?K>qcdya+kS9!
MJT$cA tRNy9wt$\t+J^W?=eK1jcn/9aXbcD%:#?X:S*!pbqR8ZT4W%K+/N>!5&tTdDC8LPhn>?dBT\udu&eNc#
WZM?a+ !VneSdlHnMkNh>Ll!Dtcj5M&hJYnh:#k*NW9dSWWJ?G+d+cjGV%i@PDVCCEj???Y8MFtGMDGu&9nBApw
#:IKRF jXZeHnbt@yP4L?+HDSJ!9d>=F=Gd<tnudWY^P?$Qy/4hBe#en%QPG=h89qkny5\Q*aZ98lI59P!#$jcY
E9&KiL SLd%%!qkR&K6K<ehIlFR/Cut$IAhcHFpS%CteCXX6944INtwcnbtt@E+8l?$DdZ8D/$V?+nFI!I48%jH
E?AuI^ <tP*p9e$DkW/YYq$+K&QH<\:DtlS!Ij*DMLq5h?\H8u*SVb8Q5em1AdX$%eQ4mAVCW+Hj9#aV#\m5C&Q
G^nkw> 4<dD1nV8!jt5HI#I4$einL+HF=9##kAe@ASMTl6\dP9nK\Mh+>Q/w&6Jbw<XCjb1\:&AW@lML+qCe%Ae
leLC!^ +\pPyVXq8LWkyMR8WeZ\nTad+/wXwGq5kkBMKu#eG4qhDbPQ*a*Q@DdcmnSZpm?NBIe=X:N$Y*Ip!p:5
WTB^KJ !VG:Y=hy1EuwtAQ5C:F&Gw9hX@8W=9w\XtRpFLIZ?B!q=jZPu1j&9!Ac+&G>+S6T*?SydBS>5Aja+@Ah
9hTkaw DZdbc+:lutjpmJJB?LBk<mlYISGB@a\\JpuKYF:N8JLhw8+wTiuANeVZkEMmk%BLnVqYXydIatmMKn:#
t<!mpW w%V=^:B1P$ZpI4/#kDPtLZ:LXEcFdSV+m6lY@*#YJeS=eG1DtI*qjuT/bw&IX+u#!Yk5bnP>9ElQK$:1
6?qF#= XRZ*P@utD%8<NTWhDJ\d<Q=AdVpD6ZC68ypXFIeI$8Zk%HK>niWBVTqkN4C*K4auMSq!X4wlIjYhljXG
5P16FY MPEdwV!S4LR+kJ\/akwwG?K4LaN@Z>1&ljkk48VVI*LPJZb<Sn^>FqiW8RL8J*pD%R8k6M8$pC5yy9=Y
@=BmZI IXcNLVk@t#lV9Cj19p$Ly%P?bp^u<<WE8^SGM:u1!WS$N:B^=TI/t:iPhYcZ@X#Q5Dk+!>=h5?El>t\b
\9<RMw l/!uAj<9D&j1tK%ww?I\TPN9V5+*jFaR/:lchcmj^bRDK&CP4*HTe>a5^%IuqiZLI*IYZt6\aZIXm=W8
!VcXYp BbQ&w\k6&%k%&!Nh48*GinZSmLBic=S:wG5hY&N>$Ka#pWY\=Qyu?Eq??Gq6^mdGQcLtaZImQ4p%nIDA
hY^AZn %+%SZ4wQRRa$*4$WX4iB#G#kA^\+4heB=&H5cyjCZMPn=N<yZMQ+eF%qHcPiRWNjMnm9SV4iYtn#S\Ya
\uM=P4 n#RDIY#QajV6@MjC4m#RPEKTmuD^GKSQQEA?qX11RTcTZeeVNB9w5QGqNmA$q9IFaF$k%n6<MHLw9DyC
#QZ9Y4 Xp@AJJ<REw$8MyeeyL\b<jR<EAYpZHtHK?V!5n5WKcp/mH+LV*$SejHb8u+hDmPM/$?ipTSk=wLKa+eM
6dR1$/ SaCHbYWeba\XZuF^GyMMJ=<4F64Iha+1Tu#j8SM\!WKw!iPBc4@m/9%mmk<c5:y#Mw8aKaWHPt1G14YE
XdJHHp BL8\$6>KKn?YN11a!qAiCu\#>WDy?MS6iQC!Lqp\#KT&&T>\BM5JR==c$ZtiQ&!q5ibjK<JbblSVJ^\T
KlDhIQ wkem/AT^4Nbk#Tk:TW8QV\8+@%aRw/KQN/Z9j<ml65RGp<eK<YJ^8uij^b^w>@kSX6<@*k>bG>*q4l&E
@:1t>\ JNQu!l\qL<?5b=K4!ATiSSbA5Zw4*ek+FkK?a#cFW5d+G^MEI\F1q/>+=6wEa6:C=%!$=#^6$Gi!!5Fb
q!Bq\H yW1cKaAcJlhGhAIXN/?5blm>Stpyk?QH#iiAeE@NepF<>yQKeI\&Hme48+<A#MupPHyVXSjbk\Iy<#CN
<9I%aj cj!RYZYJ9Fk=:/!B?6tHYBp\ZG&%W6a$*nPVb5bu=yYn*H14tcFp?WMK\m*H/XyI5W*VaNTR=Ph1!!+*
6t%TRi /!=Apl<\RqqhMT#n<h%p^MtWbMAERGP<KHZI:D+*8dY\eK\JL=jlAa6Q&5@89YMuZcup?&KW9FY6Eq&u
VIZdE5 <8I^IDE^t6LJiXpI5/=Yi?DljBC9^Ee*>=Ewe6$d>b\<=T4BeqS@\8:bbH6Z$pQX5mmm\NN:wBkRF:pY
XkjYQj 6TJnbQXi$*!Cw#XX=XN:+p>/iCjyI%K@!Zy9MDZAI>E/#X>imkR@8XZyQW5#$//M\Te^>nIi:88Ll$%a
!ycn*y aV1VbMInWWqWDVJX>bQXJZTYM#tP*L<8l>VTCEdH1pd:&*T/YjwuMmI<yq4X:VGiW>!=!ac?*L$P4T1h
Ra$a4P +%b9kN%9:G>MB4^:yHY?DqjuXVT*##c##Lb#d>EM>KApc4tF#bY<8XatV>T>#J&Bcm4GT#*#Sjw9kYI^
jnDBkG >w>8:Ki:eT<GwiRFdcpnnJZh$TLF&kFnI#Y5GZj1E&iA#XIDVyHYQTuLpZtk64*Aje^&/EW<qu$t5CBa
W%YTlR wQ=hS8&WLj%bpXL&kd+@6+ahWC@V9ZwXXH6i\buK+B1!4%akbV?<4#dCPy+eNbtjQ*9JZ96Dm:h*E#NL
Pi<DwN <6bKFVhAMF9D!m?Fn!/BWBNNTPLGMB8TpuQIywEkT:Al+@=?Y^<&*Kpt=8^tk@q?clVn*i:aa/4E%lX:
e6LHq+ cy@G=^\u<#5CM=meQ=68\@4XNqYQNBPipGbc&/JJyREn\&1!!GqA:KZIC+tPQHiWwSK^Btp\i*91\thh
S9&9W! &JRAEyGA!X5eJ!5&WLKF=&8Y#hTyXqN4hb5mQ$E!S8iiA?D/hNV^yL45YEyNdy4kmMapS@yRb\CP5n>i
qLqHT% cRi$m=R+t:=N4XPBR?>4yTa#d&Zt4$maD/i6:X=!Ha9ue=am#@J#=%lFX!eQ:<T+NBc*X&K8&6yA\w^l
y5p/qF @TmCF4cBYa5KYV^Fed$SkuqmZ?E?JYFhT8F=XI9t&lF4G98%EXk><@@D*q>H6du*?>wwBSI5BA5PLeYh
Rw9=1F AEtR6yRm\TG+W#T+c!qRmkS*LhLm:k+FmpN^6\Kq8Be9WH8jhhc:%quniib<=*#*PQ95Qjdi@+b^nh@N
-APucC 0002a501b1f00110333 Page 79 of binaries1.zip
$<@?6= ub6Beu&?etDlc8Riyp%l$w?8S/kRi:Jkh15mFan\kHcq%ARcT!:db8!RQd#pue11u>!Z8/wJ:p/yIW:F
kemDYE 1SEc9>w5cEP=F?n5hpd\h<5JHJ5q\jad<Kd1aL:4yVDP*cbQih#9!R^mD<BSBKhubN6\EhF4K@*N?&w@
!K/IaP /iM@mAwRYu+qnhDX%JS#FIkVWPjZX:QRyTEITKY!W&@E@5\J9GmbWiIFyEhwZAq$nZP#\^6GjEQ%RP8L
C/ky1S X4#V!it#tRb>!VebTVyQK$4cL1&dmEW*L1wde6W<dkYi1jK=whnZwk1j+w6hWdCbP19B^kTKwp4cSE>M
<NZ\Dn ApR$cjna>bW4kI9^?wI$A4He$<HYVRSEXJ!>nd$9t*Sea!=<=jRLJh#FjAFe#RwNw!>hWjM1:nINdt\=
%mDG5n F1GeZF5/IA:=+Qi^:&PiSH8C91uLWnK*54**=!+8e=EhdAc$JhlF?iJyJL^5&!W#^^\%Jd^5bm6%dn/L
JuL#%k %Gh^dVW<@&ak!n4V+tJlc?StcauqVJc8%5#mTn8quE4m&X:jWtN$4:phdPQ<WV9h<:ZCnKH\R?*%V#yJ
5h<#KN L+#Y%hYwtl@p#DG4JQ?m!P*KPicdTj<>>LW*jZGah1na\nWnAq61/#w*b<65d:P49y5ymWn:QK=@l8nh
+pa>a4 Cq4EZjNSa4u&>EB<+tyGdDZeW91y&yDBFtQd<N1Tnj%nG?M*Tkp<Wcu&6yk&RB&BKJu9dC%:NEluwiGD
ZpbSE# R$lKQ*hGyJ#/!E69EFl>j\N#db/ZLqCTHt/hF9NTn&pncm:nY&jH\FdPhXKYqiwIlDa&LYYc+i!q>69*
S##d1b Rna=ZE$X8>>D9^tp</L5q4p\l%u/n*R5:KaSViyQ=tpRlb\Y9d=TB:HckT$ApGiS+84#D6%=Ll*aQH/l
t5P%ZS qYqPkpe<i%cdHXM5hi/k:/%F$^iM\BenPc/=c?<Z=#PcLlhIb9?=nqeqScL!W*ML1hq#VChEkSy8Yd<<
&KVLBE hhIiBJWQG1NpP:IZu:\Vnm5#it\kJW8KnQ6wX%n*hWiw4yq<lk8HNW1lel*>t%8@#P8ua#<jaiBA>W#b
DF:Fap !au9b!!dR&J%ZMW?&hCj^j$@9:T%HM:+e9S/b/lLHACHG+/qY?h@e<l+HC5tLu4pmR*1%G=J9a?<&qS%
TLwjbp h$9D?9Z#h85+a%@*4Xj+6*LYK?^N&$aI/FMD/dMl:E*c!+dTZH!8nWC8@dEZIky!%XKD1M>!%KB4H6NI
l*tcw: Dn#Dp:XS6kV8Nqejt118hZByi%l!V5wm*Y@A+^6y%\j!!&95pGVj4K&h@Gc:eXl9Bd\N<LZZ&Zw^<HNM
jGAHXX #!cLV+ec*L##>uD<aV*9c<C98L#>/GpV!6#I5c%Tuh4j<QM%lw1L^PY9%#8JcVleVFJ16>lqE4*4liq5
LpnX^# J%bJWpaT^AZFtWe=!/K?4b*cJTiyuiHR^+ljhZHidFhYJ?L>*Qm@a?l<H^Xi<yZNjA@k^F5m*8h5/ul+
%w@XDX !?n^<%L+>4Ec??Z<YEGQHwYc:L^ukRC9?I1yl8NT5KWI95+99L4*AFQ@R!#EP<Qc+Ql16?CK\pe@\nlP
N=&knc &!/Jtj>6HB5GP:kA*^JPG\u1TakjRnt@B59meW4P8uA?:k86qT=y+$hAKAGC$nLMVFamW5Bktqt*J@n$
!h\E^H 55S=ChE6l>RRly%iQbkJ>iQaTDcpRuIdYQCh\4w4nu!B:cMe6Z%%G5pXJ$=wyFKlFAwGpiZY??QRTFD$
!a\6pG j&lwJCn&*^VKCQ@L4lw^+d?:1?a@LQe@8ZPlj\$yBQ>=HlAC?wi>GYJCku@N\pZ@lBZ/G?\jn*ITE^L?
GVBcqn c^d&^/P4^ISkj+Q>p=^BCQ:Z4LDau@!?mL@BC9%^pCRp<6i5EP^QYNG@b9<$$BET?^5*/^<u@BE4@E<:
*d=TVA e9/D@H<Kbj/nl?VjRluaH+R!\u?\I\etAlZ:*/cj^Q^@@Z/TJ:X$R^Cw5KR/A*\#jt>MhyVV<D+AB/4J
u5nEqd B1C+8miP8Tjb??R>Sh9hS\BP%1&eGw?pHRVe4SmtCLQjM=Pb%uKI#=$?51JA!9bKM*hQRI/PFhT?nAuI
j*ZqIJ 1G5\h$6P&95V5?X*T>$?^Z\bI^!1%Ww*Gk4nKTqXkeNtSHS1GwK=aPw5Qmi6\Ii>iBTLWw@jPVS8yu>?
C^BCZn lk4PPaFYW#T+Qk&nw5#449Ve&^EH<W+/RYTV:n=VcXCG!w?4N&1@>J=G!QLDb:SWDEaWl>6$9p5%J9w\
\X8q!= Q&/+<^TVcVk+>G!<HA8EcDq<\y/8yIJ<i%49Fj9Mtp<>P/S4+1\Ddmdu*j:6hh$qyelViH&PbmKkFcH9
kc=nE9 PXV*mHq5/HYBehJCQqJMc6t5dt&tedN5ml1p%ZkK&!H:TR:jQ#b/FaQKh=itN!%Q6&jT%G1QWFw+/cj\
qLE8pt *iQ=qV/&>XDG:udK$F+5GhYK8jZF\Dy8@aT?p>w5HCTjQC&iEiq<&#l:J$GEiT&Xw^%baA@bLiK:wYTk
@ySBe/ tn/:HDMC%E=1ttt=Hu!jPap1^$t4k:$uHF8+ZHF>bM8:@ZD^M\//n%=Q89Ku5ePTC&18<5n1aVt@h$eS
JFa*/* :jV^E+E>?X^p@i!l:%i%Gu5ndRHQ/b94&*QZ=i8:l8ljYNMmi6<%Dum*5?%?5@Q>jDjjNlV:\M>$V6%h
C%^/Nl h9^aJ4Wb8yPWd8%@4@YTyYuSRL?6RmBu!p^EJ6J?ITyj+<51dWqc^Ydt81$tH%bdG+Al?:WjlVC^:S/N
$l+Gt: TFNW5IYS=!HB1dle/uuP>^Nl6aKL=9td4+dl\uww@!MBH=Q=NXHPRA:V:l=$N8+<Sae@1T9>5#%>5m>S
A&%a=$ c=m+uMejKBb@4NSj&$$!n8WGhYcyQ:TCeqKtFF?SM$ydQ8M99\&Fi^tekMl<lRR:pnLt!wwTZP*%V=Zd
/Y9:=F Mn!MX1ud:i*QtTCTiZeVSlVItQ:TIlE+4GPW?%Vw*LIS+X+#j>>hKe/XT!=NF#LeHepQ4qcX4Gw\ymT&
TnL?Qy ++?jYG%+Ww>HyW#Pn!qy4iX1ycHQV*wXE%u&LKMZ&MNT9tKGYR!SDITER&=E*Ee6$>uk$CRYG!FLqTtX
<aG@AI \ZtNn@4aMu1<6\$5GF5E^L^Zkb*+Gj@tI#HR!w1NJ1TNiS9**S#*nLLLclh4SCMjt>L?P@id5i1WpBWN
%<1b?t i*\Zw54P^:&I&yWiZMt?$*eMieqyi*YEw4l?hMEiRq/Kyh9T<u#k6^56tYMPM:!=SyD1F?F=?Z8\#E9k
GHp8yD !?^k^H*yq+6QXS?iAK>ad>jjBD5wB&u@+@MpA%GQ9!a@TB\tcT5+P!%C\9SnYdt9lm^^D1IWSmcRMN\C
F64>9b $1Sq#A?eC&jQpMKR*#qFZ=bAeDhb:yeRQ9IwRpy@>Cdnt@WVWYi1c!/iA^:\+LaDBH<yhGBnP6c*HNLP
bm>RF9 Ltuw4y%bW#</X/uGWHPq/ZN?KbZY$>yRu>XiLLZE+w!MyW\6y<DnHiq#TIy:w#R$eu@9cJLV+h=PJ@>H
jp$JI/ u=LNF\qe>atBI=hFb?1bkB\aNPd>6wdXu1tI^lhF>iH>c186#QZwcK*d?d/DC/$bZ?JTkAwNaqPj569V
9N1yBl YAD?AAjykE=89/hdTX4E8pPi4Q:a\a#\HwPAP&<Pbam!5?=ec95N&4n+Tp*QA+A1hhtbT/YR5XP4dPZi
*kM\T* ?Q\Ky@chnl*@yY4JWpkq%^H<t:HeE#cc+$4CIQ=!YYylHL^REnRnkG4&mJ>BkWX48n%IccZVYHT$iAym
/e++^R &/A>bVdMw$DiZX6hH#M@IZ8#ZFPl1IRel#bJEj/$eu:yWV5VXC#\$q1G8^dJd^tyX98wJC&>&\yj=c:Z
RVZ#6K ^AeAZMw1RBHNn5%Rw8i494kDQRutB1dZ41H/jk*yiKR<!*dE>jpXL/pdA$RCh%@!4uq1Pc@8m>>WFB+4
$>ZGEh u?lY9GDmHGKNKeMRALmNSul=>X+J%?@*e>PM#cC58Sw$hca1!?XK=:%GeJw+y@h?K=eem=4Y:&h11F4\
dh1%p# CRIW$t4jl%c?&Z@DV*/CV1*<Fq9$\S\:5lR4H@6XCacIiLZjq=y>W1muwZ>P&5yRa>Z1+k*u4#h>m^!t
b8WetE Ni>%&k$jBl$%p^bA!L@NuNGqq9ddhCnjQ%m6my+@mJqyyJ?@M*tb@Z*\Eh+H?GPS#>?4:8q:W8A^dt54
WHYTTp ZwmJyBI8cjCjWQE*<99Wi:Piy$6X?Nk>n%QJ:I4h+ZLiVGnt$V1TjM>+ji==NZhC%jVq%Vuh6&LhF<9D
q4?DQZ wTiX4=GLtW1CH>+PTlXuHun=#W#TtaPKq1Q<X?c*^^c+eBQ!6RK6wkc*Y1!@I!=cy+WHM4naEeemI?J<
NNc\:C />w/Va@e&mpBQ5qn$i&/DMZReF46pBQb:m\SK@djRac^SK&yCb:yItP5ie5#\MK=b&1ZCYKjp$dP6u@*
=9Vi#R W^6cS>Ed&6bhJ*V58#<SJVKyd%?#GRZ1+y4&15Xpdw>dZw^85+6LK@D6be5W5q&>VKn%@CkWQ?>tkWh*
%<yY>u F&EVnD?t?Fp=<<8&NF+4a@@wN!HbtuwCL%QNtbAVN6HFh1M9WK&%d&XPlHit?e64be*:#e6u:TJXF%?W
XFwdj\ hJ@q1\KcIS1=ccwhMWHJkbZM^w!lL!q%8dHY=AQS\1auQ!1\bj6b%hu^ab!Ll9m5T^H*=*B@&jVVjba6
wc6=m@ ?mFRaic<b\1MHlnun5HhciSKVFbkV+ymL?*XIPa=Q+^!<ihRLV#MPyP#map*&T$*5R=cP!9$1PcC?N8Q
>Y4ID* =$AhWkm\D/%P>NHt!SGS<j#>iPEu=\4I%^EEBA4eLTPe#5w?1T==TYGJkTmbulP$\N:i=^lJwSH<tLBc
#P9I9+ RLnN?tGYn@pBTIGtiA<aP&yZN5==8%>\J@ALK161mqwdX!+T6ywYSqjE^AIDpci#I=IPXnZhJ%nC8!l+
<ltnJ& ybN8tX9Hh6G::d!nCTj%pHQlW\bFMt^%%wN+?:+Q*JcD4y^bkB8Zn\>A&:+t4LGyJHKWGJ&^Ek+1=BpX
c9l9$d Gp6NWN!$cKBIwJWe*=5c!q&!E^C\6&nQFkw=Aw:6+eIQh!FkTP:Z>BGy4CjA=EZe6dd1QQ^S<^TTL9+C
5h^:IV T/pm!a^1p!/Z?J@aq?*wT*WHp%:kG9#$^FHcBD>1:WM$EWP$1hw?#Q6Iwq?yp&?>wIh+<eYIFd*>DXn>
d&%X&h aGc:=#*QVRjG\XTiNa<yPwZbm!PQ>BE&TpGlkLP4^D#c1YLWR&H@%*X@KC5wCIBXJ5VGDK1G:QHX$>8j
P^!G@Y ?+VpbiHqXE<!/++L&aV!n?BY=Yt\=?Z%<LDX5iKW5B!4$htN1qmMQmGWj^Ky@PaAbZ:pMYw?LRi?d$^!
di&Q<> >DuR\YS:AGpBBF9X9PY$i^LFqHqAiB6T#%HYyNSVX>:ZZwH:pSNVAPk%plyk+PGi=i8S8PQYe\FwhWP^
V+cFbC @E^Q5:B/pIyhQbQ^$@KE+/YQ8&%+dbH?$H^=#FqISL+E*</EEPESdQ18!@Y^=<ccpSyhTEpJ4F^ne\@Z
q%MRlq #8+ZmN%$iP#AyJAe^m<Bhac/%ZaLP$A$%njy$SX?VukMAGJ5=YS@!b:u5jeF?BN4pBILDuXtt@ML=+m&
!qq!=$ ?INB%C@%1ZcRIQiHGqBVHkb?Ct^k:\MCV4S+=:DX\>WF+=*aB#y*Vq>mtd/%+qaRH1FYjT6XwlntepZL
q8Nwuq QmMS44Q1#BDteMqj/\b!lT=>9C>5G4pZiCTHh/Qb?%#<\A=FMd954DenhRkX:Ic/X%NBKNq:>WpKNB4a
LbllF: \#?RMeepFhpZM8IEhjIK=MW+T\C1B6/Sh5*EXy*HC8qRKD>*1$IyjmP1ennG9&9HGn+iX!hIN4I1Hkm!
=uqp1^ u#:c&eicii^<aHS$<qq\p*&V!%ea4IT$pFc$^lwLj^#lR5c>&\EF/wHJ6h^/ChE1lZIN?n#AWGnyn*c5
KqL$bD YaG<Z>=5@AtnE\wjFiTQHDIwqm5VbJ4\LG6t%wAK1?T:/dJD:i<<\H#5V%AyYL$CR418hHmkpMEEbnkB
-AWIT< 0000000e22700110333 Page 80 of binaries1.zip
yluPRD &MASl9!+WT*+Tj$CY+G#awiR=p8m#e&+Ge@??1<1$@e:MnByLnE\PY!:4k6jY?n+9Z19e8XZu+=GSbmD
i#QHXD *n5HeMbkM:VM9DkF6SL6^i<ywqQC!*eA!aF4/%:?^4y/\HcE%MMa!kJ=K#Eu!VED\FJiy=^F$M/=AGZh
RVl*Y> 8J!j5Ptp5^9FjcIZnAN/L:EQaqt6FWJjGt:yQGeN&N\YiS=#Dpy$WijAyJBl\VR<#EcdYC%mF\q%E4/?
6#w#\$ INPK6GZnJ?A+$@jMc8A=F\PPKBC>+JHX<YGdN:p<&y5Z>?ZkiWDF@Dp=pA>\plqKLkA+<hHlj#:Gd:I6
XQXTKc 4AIP5I%V6$SQc+D$\y4+cN$e$j6XP/V1qkk@J&aFC$DG5w:yMh6ZG<6I96%tc&T#>d!dl+iJ*NHpDqW?
\wILAE AQGeVnnhuHYVJYn+yiNDG4SQ/y/=W*m?*PZpnj5n@MdJF>d$#=Z1uNtVFMK\ZGR$dLi56INND1%CiL?/
/hhNHB Y^>aE<bH88a5th4wKAJ?yBiXk!pucL!?cJA:<u4V?E88kB6Zj1m$*<m@EN:qSb@?cJbDP5cJRpeudRCl
TqDJL1 a1456>PQXW%:J1VY9Dub9Fq\X+ae86lDMQ*c5JFLMPDe^iIjH<TwhwBP*ZAyFKGFF??$=jZ<cSLR<=6j
e^e+=n A=k8K&L<NK18J<!VkHP?n+D\Qe@54*JY=+WT%R95HJH=1J/j?KH*jK\\/\6NDjd+9q6/@PWjH4M*kI1>
yZ5k>N pBFh$Pa$uZ^yTtJ%\=AZl9%c*#S^ldWcjXl1aHpL&MS*8nVMIi91I6AlPhc9RcWjk<dJ*\e4!5bRGB@<
&?45=W >FZJ5TT$6<*bj%%Z$&8Zy&eVJnGF<dbtiI8tjHFlK?iWw%PLiZ@SppZwHnI4&m9ZWDy%L\Sw8t1NF%EH
nWIIpK jH%hGh:uclnLi\eL54G?G=^@F4cnyuAbm?\QlTad9y1Np95&jTmpnl#*S/d?bn>HkadYpScT%bjY<uJ<
cS\Hyb epZj!GVy>tkt>b\^Y=FHwPa+p:y1=TNV:iR=R%WnhZuKBC5t%ACmiQ9p$NLaL6IL6EVAjjM:J9t#^\^S
?\I@e8 uQp9tCmEP>wD^NSZ#G%B9+n&<SSjqq?R*yGAX5KE:hLpN^HI/kNdMw#qFbqDK6XI@h6F@kMLy4wQmbWM
F?kJAt bDI@>5GqlZmiHK$Q5hi@i+lik@B:KyR6AWLGKwe/kneJ=*Td9M@jYLFA*Yk$iMWintwS6+/nb5nHNb<!
X:Zi&V $dd+cwcSpB&b<I*YKWN%V*1<E4wEZTjjYFa6%Gia/+jSHXa+>*tdBu:^6<:T$^S+YY+Ay6:#iZE?I@Z=
J<<R*u ^Zcpy19MCjcPXXQdd>%=8+Y/FBKtSq%BW#\c&P^\R/kbB+iJ5Gq<NP>$K4nFpLLPC@un$MAekQW&m#4V
cn%$ZJ ZGS!X5:G1X#n\Ewp6&JcAZJ\hBjdHT#w6@Y%>E+<PjW=YAVh>mcT6<XpW=Aqn/\=Y>H<+6SyHik$ywL8
>Z6Zd1 !Nu%Qi91%qZ8F/9QX44NnntIG1StHbF?S>VL\AIVXCd>WKEY9JTNh8?kj%H+\H:&L1p*Y*Vh=G/j\Ywm
\<R&6l K%lw1t%=4SK<%ubXeZn:wCwyaP:P8eKBN&iuj@%VuiNuEk6DlbPK>?J:6ZVj/RP*e1WN?6b*:%e<F#w:
AlJSZG l:+$4AFHh1t9\c9mG5$@W<+e9MjH@e^:YHe&<CH$q9k:\<j!&*1^SL/9NRtQu8ekyB8t4yhH%X14KQNh
V/l=*$ n/Cmqh^+Et=>Ly4iYBGT1++6CHDSP\D@P?1=L=:+ppq+#NqIZ=e\aqPCt@:GDae$IW5*QC5ApiE*EAC4
t4G1%K GGQ:R\JcKpp@QRRI5XdK$T*K<=!MhJX?:tl+kMybe9#/#EtZ<5QiY$X1QE>VhVMt!J>&Jkn@#:M=+6>d
^T9aGX Dj:jG&ja9^yu&N<&#4A@NM:C@&yklj@tekk^ajlj5@A@Ka5ZS9\%C@9ncWBm\mJ@#R4@&VYL@nW4JQku
yAAh>t =+4>Nj8u>ld&#\bY?C>u:Q>uKj#@^<D?/=d!j*@#@:W5Z9D@qMZ@h!mLn@u9W^b9<L+!jEQtJ!:=DI\G
KYwFGm e*DuSk<5Ydim/ZK\l>+>!>GWaJES^pqhc1!5q+?Vhew$tAITm?:MAi?%=<\Be!WQyywy/qwkIBXGRkR^
B=VPh5 m$j<6KDKJuI%:y+KkEQE<iA=a<?bnSYn=6nmK1Vu<6T!4Ney*j$beRy9?9w5cV?Bp8aby$FuW\!Fk6SA
t1%+<$ W6jJuByqWnlX\<^Q4@uB8XYVtZ+NiupcLaVY^DN=>#=d&$qyPKQ?$n*J^hu^K@^XY$M6AMBm>Lm@uY1!
Lw@M1h /bH!dFQT#<k=:dS/R**yB4+4JWY:@=!&u/VSMqbj:=:tZc6m5:M&1c:CI>*Rt&S=wAc*!qRjqH+9p#\>
^&w>c@ C^GudW4k*a+E+DRET@TZq/k@uW9@=LI#AetcIIwYi&TdKu4L#455\>juS>PWCKnNXQXE?:Pd^QRqFKn/
BDh656 5ka6&\aZ!VET=*1i#phWb61I^H1qEpJ5>jp#ya=F&K&$%Ym%eZeR4yP6&llDwi?M$/&t9TZLNP8ZpGdm
HAAQPe E&\A+Y86&SK#iJey^/%Wiuq/iQNLL>nME6^VMWcp$ZhP^FH=i^\ttX1p\1%dVtNJ4XaFIL%GViFjD&\k
&+R^l? uXu&tt?&j*!R89Ip?WLM*6MGFnQ+^An8HYYh&jm5@j9/:n$bViNJXRD8++@#ji+&c8$lutDMY&%9me6u
jZ!@u* TM@YI\&WBTyW?Ll?+6^^kwQYH*=18dy+t?c/4/pL6HShiSVlcuYLiQPNha++chujn6lcYBkhN68tLLy#
C>%jRJ QBc5+?M+8>SqEiW+?YFS6DJt$SyWw$PW6ThJ?JCXW>!J<9y>9!cSbpRDa6RN6>!GHu?YqX1nZH/%Mq$^
&MDjd: >t&tEDF/XRLDLpEe$*QpWX*/46yTDqhL4BIneBaLSI$!/4J<e*B=$wCH@^S*65+@t9RWA6@D*pl*WdG8
*P4dH5 B4PWJBY>$^EZ^>T?6yJidIYMHduajS&c1$l9^i8FTRBIGbdqIN/W^6mq$jjim4XDl&uNM>9WmmJ?CP*I
dqWbSP q$YA8B&QYw*4L#V8IDe8aeB+&ldWl5jaw1j#%&8%@MWI+5!qQ9e\qYeKX9Ki+^@^A?WyAi^+hL$^B>R&
J4>EIn :P8CYRBhu1RiTipnS%Mln:5^+p<#c5=<Tk>hQpFN*daB>%\k&EuK>QNuSjLPc*c>X5mLdpX1<I!=6iCM
?AT9k6 X*XG9k5m1e1n8V<>JD*iLPPR:N&Enw5nVaPGGAZV@Gny!n4cn9#NJSCwSu9kYQS+pTm\!Bp:WK?Vqde*
HVM9FM XQGZhRGFF@*8m9XDjNbS<pZC4Ju*bYFeP<uqt<4F4!NDXThYbnS&j+yu+\\yq\qSqphc1CX#@+!Xa=4Q
uqId@X tqGtYd&RWikch</nHjyqG6K5c$e=F8!LTV!A<&yW*Rw>+W=/\JZaZERIEXNlI+\!+!YKatjQpdcL4i^N
T<wZ+K HLPLEH@ZZB^B5c@ICN\#jq1kHcGa56RCnqW5#wd^b?ul641T=a\E+?Q*K6?+kDkLa&XEp@ALp5t%b^*X
%1k@96 &&%a<Lah8A!uuAC#/*c=$w<jBJ<Y$YcGj&DJhZA5VQcZp6l4je#?\\leP#@&VQEqYwiR&y#eWu^RQmji
+#Y@Hp %IMwYS*+TdLJ@PNdiuHiTLw%Bb!mD9M6hK&5@DSVul</ZVyKJXWTAyA:%y@ZQC\:mHXaK?!nM/e@K<Jc
l6#V9W jYcT<k%Zq!=B=$C=5/4SlqHua/Wd\d\YZC9pde#nLC5::CMBV+u&58ub+6m?6icY86kc$JLB!dq6?bY%
IKMPbi 5Sa&NZE/PJpnc9QXe\T4Hu9nVH6b\Aid=jacRpy>H9aX5EE1h#h?<w1/y^iaiDuGT^THhG$=m5kqTNLq
&6aRJL t&5R>V!+^&4Dy8DR5Rtww*yejJHVhhI*^ettSW\&Qc^?5eA6L:yYYM^8Zm+=*X^FA&6*%:\GP65VC6n&
A=8c&a NT?jj+DupkwN5<V89%&1T%i:!5c^?:E&ibn5uV#jT#?MJndacEnXZQ&aZ$n99<d#eQR&VYR5!<d^6Pj#
&*IC6! TJQ6^/$Zp4pcnM#DHB4Q8!^<#+8bH:46V^uCpb/1Z^XV^dku?JK&CjP%>4lGdhjF?c^:p8kSk!t&Z*#y
Y=NF+X X5:X+q6WEX=VG=MbnIYtuphiBB<#YAyiF<@!#M\S+EE#@XFD8\ilFyeu?9Rhq8jeXw>jpYw#e4:MtTND
?Rc=#? N%R/4*?cbQ>Y9l\Wp5E?F6*N?PtqF4*Yi\WN+<Xb&ljCP\GLikQ%:eJ^hw#aZRn9b^<#\$tKYQuPPGc^
<l&<SZ D+e<QK/ypuNRCk<bu^X+%I=%8eCMhF?ZZ@&\8hZtdm$nmm5aN#1@X>9nXC4EeuI@dJT@YQRFQiMD*ZYD
pH5ZC? \%Xe\tTA%4KSNlal#uQ1RwaLZHw&qd=i5XISY<X?q/YZC6W5nlty1p<?S6YW$\H^$Xuc5e/yap@a&QW5
mG:u*e akCMjH69==LL9Lb@Lm?\$kX*yYRH#SKjXcnIH5>DPI\$/u8?u@WnHipiYZkBhHPXSAb8*%XLL\t<!5Z<
p/Y&Dm S446$wZcP=cI+Zt>YduDiYebS4wm6DX^bDt#l<k?:#5hwSZRi:IFh44FF:%@F@K&6j=qVjNa<m>!i&pR
D*MBB4 =hBl+eaw$mT^YZjapaTa6wC1<D1B<E!i+wPBaE8k+?EYu@^I//>FMe54ud5!wM6#%E>6hG^c<e*iT\t&
DG/=9# dD5VH>M6T?ieH\/\t/Laq>WIwIYZKFwm8hK8e>M4KWbm6hjy>!u#imn9+dFYRhBJi/kHkmXi^HRuR/E#
?9TIJJ Kec4CE\IC*T1pjZ:=Sn9kcP5Z:ulBkCqlmVDLX^$JhHd&/i!Xw9AmTG^Ia>i%cAiG&wAwS?5V=#D?kaY
X8$DYI =cb4e\Md*kj\iRMn4ZEB1d$1E1>4JKJLZSTnYnmCe1S\EMPE<pCTwGhh^eBBQ:ZT/^yiby>R*CIdjVCk
T%qCX4 IkL9=6c1KC=<^cjMV+S\YLaIyYNq?1Jw5dn+*L^CNW/8=JJEwwnw<YcNuhmpnE6aApEISkVkF:yqBM?J
*bDYD6 Hn%nCmYVcynC>$JywZLC6&wy\NAASGCpP4+nuuXBFW9<D9hLC8lYIaqV6T!A&JWPuKAnX5D9dnj>C@hP
Z4@$e8 ymLX%N#*+?T\GY4c:GQL1%wN&JTJk58<>Mit9FDe\d/8CDan6?I:pMCwe>nRu6$YHlmKqq!VmdCy@P1E
9V#k+h DP?dn&jDkh/ZhS%\CnqN5T5!hn/@JJ9FpA%p8eJiYpGAB$P@tDSJ4a5cl^<T>@wi:t#IJh+jaHKC>hQh
B6C8!! <kc5tQ9qqlZ\JE!@LN*HV9CcD#pKVYV1P6c1#bMw&NX+Pip$:yKl1tGEtN\FDkcy59J:>11?El^&5%R%
Z:<QF> *I*X%kBq&4byHwYp5HY?55=uG@#GXn^hPkaJb#QnmEy<D@CKqhQ^+WCWF?6Jp&h#d*t#%>J#l/&>nFc<
F!cCwP nM<bHQ^KkyRHlcpc1R=>G+DM=j6MHKBRlYA=!jFb>Aue#yeASI1^/#FmQaIN5:eT9/$MLNq#SQaW#&aV
5WXnCX C?*&YlPb?/%WeCaPE1y!49h5ik9pYEPL!tD>HwuH$e*5%!*PuwSKFSj4QabR!YwTME4nVwwnMuc$qaE9
QI#wu> EhaXRdqVTn*tV=C9HPN$95@LtZi8<W!JpV@Ky+Xn!*HdcFPi!9kwK:Rj1FtGBwKCSA4%w5PH+nlt9Y&G
TtQnN6 EpP:?jAYCQcPZ49*\>EqEbQ6k%9jBX*1u*DbIDAi6#bW*emAaLp*>%\qw&%6Pp8aY^*GMiXIA!D*5c%B
J<TLQ^ T6tYRAR+NM^k^1bFHdWK\ViIyyAnb?%1I!/JHhMTQ9RK+1IL+bA<$=^5I9ed@Tki#iiDmPIXmjL^mlVZ
AAj5l! *LPZRp/t=I\<TVaV1:q5u5tY8TRTm%KB8tenBdqjt@dW+:Q\1V\WV>1Y8ZnBWNHitqRTcY<!:\HY*ZTS
-A@kl@ 0008bf1247900110333 Page 81 of binaries1.zip
pV+Bd% \@MNk9GQERe$!nPH8<emtb#=E@Ly\q9pABL+<1*RjRYwA//X9IuW%^6W\/LtN9mX!q*PDnI$lH@X\/ec
:ABP?e &!>HZntVpKcApKu#GE?YA=GFcemI&<cXpbVu^e%HF18nuCI5\p>*SIN1X8VHXnY+&@N::ZL/>&c&?DW=
jij=C+ IqFc5@N&AVt#h%u=4=Y6T9pDw^P&qJnHq&V=bhnII%RWA@Buq/DDuG:8RZhdn&m&<YG#DYk<#I+1B>!<
=YC*cn VMVnyQmp:>CtSE=Xy4\^A&ZhJ\J8#=4LPn!B8qpS$RtJ/EGP<l4u/FteTS1c>9i$jy@t/M9mjpHn95<Z
8XtBRq a1*NtQMaLqk9F:I%SaS&WMqEm?\Qe8H>yyRJG4<T%D4A#?5*98eymdccHAStmLkZ+AF1hdnNLPI#84VJ
iIeq5C EcW%Fa&e8RD$1Q6KXlp5R?EwbdI8b=:Cmky5nc*<Hi$D5kq:\N<%H%HV\a1qZcRkpGMy#&YZ+@YW6P\X
u^Qj>* w/h<*=Wk#H:jmq6QIN>Xni86!$k#LbL\+!:Xq!%G!16$ee>=*bNRYdckTeImpTS!Ec!16%ZY@A%Icc@\
\Np#nK jRZiGWId:/kjkH^Zk#&MXnn*?NYYh=hhRMlY\M^DpbQ+wVVCk?6^j!R4K4#bBMq$W=I</Zc1Lt$D$m+A
juZ8h= XyaaN1+XlkIeD$\#iV8I>n&?dbpj+#La^8F?>$wPVi^LQV/bbhP:VnnKTDkhFbyN9:1j8H8*/uHQ1=dQ
M!Yq4a B!l?yW^1FTiWmV:Vmn*X<pa:K8#>\w8W?14nQMYdQ1DyB4\9Ji&6Ik6RChqYWT&^c^TT8t!RPyP\T@:1
>&^L*m b@1JMb115&+YGHNLD*VyV%P86i@uD^#1C%^%e1u#C9dcpwH&SiH#5uWVTJ+dE^TlRcb6KnhGVH%>$iG/
5*JS>V F?P>Xi6NDcl8l@5/5ZW/Tpi6jILpLb^>6X$?DXMpytH?L1j1KmXPdFcCLC1CL5FBB/I?8w1cY=55&Q+Y
SYySk5 !p#l\w+GD1IwX=4^K=9cLedHZA\iEi#%6yb9ubRiDZY@Yk\Aqp/1qV4K1yD@Xt+HCX?G:CP=T!E?NlKS
*^6y:9 HKMBa/DIBK!6KqV>Z16EA=%CT5/S%$c<L1=cqi^>Hy9Z>kVMDipJI?Z8F^*IIWNpi5:*YPKw8p&Q<=&C
tVEJFa R<=NPR9?\cLC>T@\WXlbj<=QWYYhMhW^J<LmC\aR:?#+yN%&A*CEZ&jDuS^i\ENYh^SWAytKdk?@+BPu
iq9uMD G9/>8?jFl^8k>t8MI&PcP!DGcn=ENY@Knm=$j\kN=hSI<1m?<EEp?T$i1Sc8Z<Bc?ZXtB#m+XT%eN$Yb
^h*TY< %5G+WlHd*QK$<kw9GkE:h=95GZcnq!/CG:18*M:FSb=:eM#8CcwRw!4bI#h!KMl/J%XpcSL^q9k!8YtC
qD:yqC Qc@BciT<au94?G&Ku::mD+*C>lw=%nC>cRXj$8>P#><KMH*w8%PkXlL1<jPua\JHX\cenCIF*\1jDhm\
k#N&!l GIBe:%ButGYu\D5eJ=M/h9PJ6Q6CLNqY:S@GSqk5Mht$mS!VjQjdZL+V^K9X+J<5**<S?8yBLMdP%=$l
uX6aCe LQ\#Tj96*t*mNKAeJ@^Z?RiC&uc+:cm*t$CSm>%QISFt=+Kd1RPHP9cjl/KXEX&*8Lyacm<VqQN%!6SM
C=cA<t B1*m?F8JSBAm:6+PpmlC^:eL:88YcdJAal?%Fk+QjubD:<J\i6ac8p:DS\>JHDwha^e6a&Zm1/85Fi/Y
1lMBM4 G&5Mq\Q*DbVIDRWNq<9h^t8<=TS&+l658he91%I!^<PMSJDddN$^:QJ:^X1yY8dn/W=&T%Z6SENLq4F=
mYpy^b NVdBKMuFtMt+EAeL:@9/C:5lW6@jA*n*B1:Z?yIZ&dLm>F?$hcqV5k4R=c9RuVXyV@Q/9G\*^6FVCG$Q
:IQNCX 1:wZ^8KX9KQ\jl#L+Z&Jdj%HI&IdG?G>twtl%^Va1eFiBI<JkPYH:#<qi<teMS#/GV&/?%TVwWjAG*wP
Y>MbG& >k%@&Tb5YLCAeu%Vb\\<jtF=cnDKTm#n+\X&L859%658RlWb9>/^+mD*Gn$j+cp#55b!D/&PNZAkIG8k
Vm?yyc 15bnjqWk4qEZ^<8mctVlS!^WauSILE$!Rba#/TNp<\Iu&jP^I:5>MRh$<cZXkI>a/BC?P9idwyeP=@=Y
tc=lhm 8ATuD1WDC5M@SuQ<E4YqW/KZ9::C+c=6@NYijt%dc&H$Lc%<M4B+p4pI@EGJ%LtqSkBXRjmKdReX+9GY
aeDYDZ >DL>=nwAcCqd<5QN\151b5X:tLC4LG5E$D5=/Xj9cmM:\/TPh9H5pEaVJHbXuw9%SXdLJtckk8WK1ayi
DkMtaj h9Qb+5*$BuSCIYm*Pj!KpPLnynP=1KJ\PwPF?@BmM<B\>tR+w$:W\LNF9YKp&Y9hbG$unLjijdkX:yAG
EX#$$t YP6^iuKYW@?&e!DNM*c8NS*nKt&>$5B6S*%%6t/WXu:B1X1/A4uZN^:@iDYeRJtdy/6IEV9HdH&9:d+^
=cQC!B bneQe#Y5\:Au6iF!CRAH>ypnZqp=cBC:MibGNy!^kSn$eNZ+$4%h<6pwp$t$S9h>dBeJ+k%nV@*yC8tl
q>JA&Z TMNjPuAAp/^$^C4weT<5ycMmnP1?#E>q55A1li#XLV<e%:Xi*hm8%eC\b!:y9H//><IBGQ<*#y<qRwp+
N4^eF& #JbwZkej&e9kwKZ^Jn:^&iB>?\4m/RBF>cTF!lY!Gb#9t#FRD$#daT^JcE/*pb*d86qjuhT&9uenT@IA
FLB:hw XJGCNim+THDI//@wnP6N1=Qi8K?5=:hY84X#uNLuACaHSKy</8iunF&dpKcMVuTeE^nD&^c\>$uA?bH?
$?Ei*M m=!+TJm!!JZ?&p&SZ6a4Va%EtVd9tw*Pw?t:Q4nEWbZ1+?<jy</i1%t@6D%::u:ttc#qF1@6%*G^I*/V
@#q^IK 5!NV^K#1t1n4ttw/h@hqi8@RpN54X6+!p<ehuIw1dFe4&PlTSeRFNS4Cc*>E5itD1=5N#b#^cc/@l=V4
pIDNE= +uqkJpEqRWBtLE:a9#qF@IJ@&%IPaJ+K*\DkR8=H%$#FV>1VBYZt>b4q=A^\$WV*+*Hc>Fq!Q5+CJ#=5
a5pYP5 !jqMuQbtc*JjIYVhBnJk/1KQ*&AJn^=BCq*\@nAZlKntC\/N>lpKaJ:bWRkQ6Yn<?!y!Lw**>@+w4aAJ
dNKa@m @R<6maj>6\WW<H>bdT$Gl@:6kPKQ6qiL\j+%wID>*aACB9<d:B?9TSCDIj/clj@J*B/a!F?#\4A@PXj$
Y:i+S* 4>p@D^u?cbH9j/D@V!ED:L?EDQA@CBukj:VIF!d+9<@ckL#@=e8<caCE4Mk/ADcuJuawVn%#e*RhE:w6
L8t/>C NpyGA#J\8GjL1H4tMk#6j>&mnk\qNuyFDV1ZNlpA<yVh6GLKT*ajXY8SwwSSRwFjbWJ^CBiuJ5^pZFwu
^T^@$m n:y/8nCCLk5Me!!mI&4D><#9cQF+6*Jk1BRXZa&P%$G@^kCRu<K/1CtZmPjn>S*JZJNnL+up%GaB58cw
=D:#ZG ^lCn46D/jtndwL*9teHeA88byh\ZGZ6*LcY6M?Q1*MwWJT*HjIj@ZB5RIj+<PHDE5:?ZYMpSAQMed^SC
$Z85#+ EQ9N/<E*u+iFW1$?CN<<#EmH/KZ^BY54CI?ihM?h>BtJGn?W9SFW9juJ!KC9u4IWA:nuih:>mXaF^*wd
^wFq$Z SDi@MPN6&w5BRD+66m$:MB!:>T<V%T#E6t/j1i44T>jKAZN4DAR6=tW9IV1Z1I8wntlGNT@L598Q+uWT
*^wHnY 9JRi%Qle9dBe%Py+>8d=hE5J=iN!n\/^9mau#/V?<G8yc@l6@uMFwFubWej+n=1iEV*thc8J4&dF9GKV
><SlR# jI+cnaMbhqNJ>Tw?&!<>Zq4e#w\jBtVS%ZkY1VF46lS459JhTdSA*HR\51cDDJM:QYe4>mLDdt5<ZE4#
HRph<W 9!R%S>SGH$RyKM?H<V=&@l=LQ:@p#eiwh6qduD+&wSNkRA<N1P/RQ?YW\?5b=+H5X\LED&F6Kjciq6Hc
I!Q6k8 8mJN+**VLKj/bSGlp8!Qy+^<EH!H4%6LN1XYW#u=$BXuwWBhJ&Q>tW$4uqc4b<nHW?9eihdDL6&lMmjw
&C&#Wt V%H#SyI=#HD++6#49GB=Wqw4&IBLtSp4D11et?SN@#8RmVC@>tRie*ZZcG:tCJNFyD@QW&6<DAH=+%i1
BuTMtQ dBWa%Cmn8kY#&%C6cdy&MMYTlRP\5IMyKAZY1iLdLu>AM#8\4dGu\tZQZ!bQV>5<&Vu*MENjnTCy14Eu
1#Vp?J d8#FG&G:5WebX$:^wHBPtBAD9YA4AG8Mi<kL4Z=I&#K$5uXEyEMaRyY*>cPQC6@DipwdSF/Z=R5Si&^/
IGhQI> b64M#C19d?d8=5V8!MC=eSy145RCLW?^E1eAL5SNepKF:!pL5Anq=>5tBpT/!mt*LG/1i!\cEIy>Tn$j
A/E1aA j+@DMJ>yD^P4lJ*&S5>pwEa+?dHDn@qH9^#^##!G+PVD$N%?AkCKdde*nYyRuBb9/@EAJqY8q&IeTtYA
bBdbD! ?thG+91#WTY$tWcaF:VKYC&E/t<me*uIddpLnHK5#JBG^SY=Nj4w#M<n+d#Xb%beAKc%lTlPV18=J@^c
md^nN% N#PR=I<cIJW9+9GGyH1bn$*I&Z=X&L+tqha#$=Y>clWe+lIui4Q*Bwt<Z^bBK$k9@XJ\V5!<du=4nMnH
n9WL!N M>&$Z++LmDF?=5ABqb%@$BPPP/yeL%B^QHalCunddGw\ER=FCXZDp?hubM$Mw5Td1D@1@h#P9am!T5tR
+kNVt@ 1<e%:YtQ1S18M?X1bIlaiM?W66*JMV?\X:8u=JD#Y9BSLhMi+#Mq&6IwZJ4!eJn^5+TMT4JF&9IwGZTQ
Ryn?QI jTPAYI?&AuK5j$>/ZaXTJZu!ScQn<ZKL$HklZd4a9l#wwkV1#h8<Eyl9^&kYAA=h@h&C9XN@%QiE?Mkw
%$\?XT h<t#wp\/*5^pXQELd*tCp:Hma5&bWh$T?dV%Tu%%R$:8pkKB<9Ci?lHj6^AI:96^1nJPlZh/=JTNdq<p
TnVjp$ C1cC/<c^Z/Behn%iT:>%9$ECJ4kH^y&PLnQX*IkM!&6F=#*!HqGL^RPyJ@h/Y=#4Qdk8J4Nk^CMn:5dy
KnMHPe dqj%9H\RT59CLL8TD<\nP:<wpy9L:P6c<IBmCiTG:H1nljK/hPjG>9jl?nj\FeQGY*^#lX:li!plyWCD
5!M!@% C96:4?LCY?81*\DL:dh>!5M@\<5R:KPtdXWPI>!6jaHDk>G=S&+DX4?XkV+VZQ9P+\hN#H&*Y^>k?HC*
u+/Iqi yVFhG:\D:Awy=%16$nh1Q@K&1E@$6Cu5mW\Z*Rn=&L4!8*K@MEa>dwaC56F/w+KV96#9cP?=8T//M%N4
%aF&4b T4Z1w%8:KCJ&PI8iCd=q>YwpTlpSp<?QQd<Z>aH/#GEl5!N!A+cVwjZA&pkl>q&cN6=CC^B?\PCJ$Ea?
>iZhqZ %RET=^=ZB8XHN<uX<qK#+eFe?6nnjRGQAG#Ce/D<Gw$5\$E#4bcF#SjjP4iE:RD?qbSqjtQ$w>/Cp^Cq
tIA>Y8 >MMccB+@eSFcFQMNlX=NnQYwMS8W8KY&E&Yk&RV/!&A9<A*bIYw&mWW@mDAGDTYjtt$a<VnThu46/j9&
QuTa*n y@&AY>FBV1$aymY<@H#>Zc#*&/M+Qaam^R\dbZM@GK/b9\F$ZHyRQKe^Xu8WJQ??1lLHyJZ</aQh4Dn:
<he5jZ <96VXk<8Yk?Kt8KtQ94W1yj^:+Ct=N^CR<ujN*V#6:6cXi=bn/>8:lJj/u#IF$b$JA5<:\I:?1YbbI@R
P/8+Ne ywZ5Ah$^9jCuTm:*w5ePiwVYCTW@ZQdy#pm8>deX94Y?5tn*eE=kba#%&*q=A#5:mFypCZ%<!!nF*/5#
VJbJq8 GFym??RE^<j=^HV</e9uHk*EQA8>Xc1ma1>mHt5^I6Kj9H*b1iN%C#LeI8/<tS4?wC=j?JI@XY&>b4>u
m@/#QW \:SR=d6i4KH\>$iB6L1ib5b?1^P:QbQwLV*p?9w9?@b=pn*W^>pYT/?V:YH#mNpl=CJj<b:\!QYT6jIp
-A*uqi 00072186f3b00110333 Page 82 of binaries1.zip
EXV9hS p&qG^j1hVL^/L?H*tKam\tG>tphaSbPqaT^adEaky9u8G6dReWE5nEGLm=c/?e%q+VB@*4#dYIBWhe6*
%cwZHZ YimPE5aG:a^uB\FCTi:quSc\a^hk<H@cp/j&:T%YcAFnF65Ik6V:c&RuVh&/!4TJVLy*GdySA%BySHdJ
HWZG$! MbH6RJ=X1l+9&u>nLa&nE6h1Mij\:TY9IBlLuYl:5bi$BB#JH#6!b!K45?LAdqYE4C$6ilLK$EpM!S%D
Mh=jEi L#6%9iw*jVZ!K$PlndhjuTkHlV8FRA&N^*:MJHBG#ZDY5S!L+kbc/9c@XeW!Nc>p><F!+<?SB:41<hec
Pu6q?A PRa#DEZ>Mm1KF<k^6Tey<Ch&/XEQhPNJLw&L6GIL^/D<EyGT\l64SiYQli!9F&S5Qqm/&QRX/Wqlw5<K
=/BGCh lqkuN?!wLQdHT*J&ccI>>PZjn5YTjudAwYGL%yheB?QS/e8q/<5PbiAy<y&h9=>1cWS1hPe#hK5S$?@l
W\W!AT WR>HH<WIRHyY4tJEQeKG\NIT<GMQ9qQj&+np6N&*:/TFWFl4i:$mLKHSp:b4&pTyY/TpT&^BnaC%8$*P
TKY9Ta SiaDMA<d&>VyN&#V&EGy8Q+*#LZ+@M=N?lYY*$6l\5/tEZ6>9juR&ItlN<:PBPTK4ph645Y<L<J+nYK@
bja>*/ +5tm@At+GKM$/lKn>=GI@JnwNSqJXbLqn!wBGYy&WNMn:eQATcGG:#J?/E*tHVpNjeIMwc>b\tndl!yy
6?Wmj= *HmeN!Z55wS:c5B4@b*4%eT6=dPY:^yC@pGVm<PHk5YyjLE#$FG/hP^^T@XLlTkP@4wA?iIaj1FcuPGT
S*91c6 aSed*i&kwuw8jlbbwaNc9mJPT^YI$Hp<9G+RP6\8nK:RS=u1pZ/De<Ij18KAT8?/h&T8D&wmE^T9=P88
khIb4L eu4<m?mk%d!^A?$?IZ4%a@N/e4^/pdTekC@ehb+Ra4%9lDt@R8h@adKA46Hdqmh/*L:/Mn@W8$aXmC:k
#cYHj5 kTmCZtad:HH?ck\jCS1iYHWL\VWQbTk1QPF#S>Z*yiFIG4\kpwqnj@cpNFck*k=ih<T*&@XhYlm^5!Zu
bH*Gdc @FMTw%WPyQwGiQE+R9+qPd$+:9yHcNHm$aw&DBIV%Ya^*yWdERnTew6kM=<w\R<CZRhXcDu5BjlZBp8E
>qGhF< wKF&Q/4/J:W4Jl/G=IAc+4WH#EEXbhu8+>>q1ak6:<4LIt&=H#=Ftd1Pdm4aSG@<+#mCdeWVBte6>HVa
ZFa!DG b/1w65amDjQ6wCb&Ve4>%=Ru8ST!nM4=IlS#&He=SiAm<:HC6?Q=^tyBc$D<YehJlDtETR%+w4ch^yFe
EBa#yw #AnbML#5\ql^c&ubGSCYp%Th\dtZ>a4EJNt*\pKSIFnGe$\>$wLJp+%ylAX1ywKD4Zm6X@Ra6lZAZ*@m
mKK<RX jCd9wtZE/t!kjcuH6:*/qC&IlEX%&5wAYli6Za^cnkW<QuZJ\YCk/JNS%dIF5FGGW<6#cJKp6RaW8pyj
M#W>+c KKmlRct9nQ%c$hhR?@%DiDD>EQ9wh4CYRPM#&X:>RZ?P<%\V4BYHRV+>=+bJq9H\8ZdW4J<ijQd>wAd^
B+!lyi *A?j8XTLJkL>ykjtTtK!^aVe$TpT/F&Fc!C/WPuiy5n>BnX8mMdujqFlY*i#tplL@DtD^pESkdhGweFQ
A<Z8F6 AYq$<@@+k^6Bq$V4CZe4#1GGKP1jPQS5cY+?=Fm%lRk?T>K!8NTq\+96=XwS>m1$Vm&\=e^dtCkWu&qj
qH46MG L#ptbVMVpq&!V8&*q5%bW+FVEl@wSQkNC4:k&GbA^$#YC%d\eWndSkR/eVG6S<DY!E>/wuCS+?^#<8V/
P\&n9e pu*kam/Jjlha+n&a+<mDy1#+DZu>uHYljwbkGTQHA%wF&YB/e1wqaW/=T<I=%eL:*+n6Sq+#!5>PJGSw
eH^e#< m\A:!ByRR%l<dNTicZy4\8<5n9hWa*>euI\^nAZF55AX=bMF:XQV1^m$yaEZNt<#mLHZw+&?hA*5Yi?y
1*:^ca piALPpYZqaj=p1im4Bqi^5lp1CGP9$IZXNqduMnB14NjBB+cAn8Z?P>m^\i>FqdPS5ZqV:K<>1u9p!B/
ulXVd@ qi^>?eujYCX@uZcDH<ERmBZyBqNZ4qVk$E/EI9edWaHZZDQ&C6QtbDSqFnYVPddPw@$GkZdt8wpjnmZB
d6AaQ9 6lCH@aDtC5=S1X5SdTGyhMp*HI1nG1\Spy?DLI$c<TT?Zb%5?ZCQ/kpbAG>DD:ZG66pDLR!tJPhiCBpG
ntIbT& P^ilcND\eiFRbE<9l<SNwMM96tTh#cXRqi@MiRh#=ZZKcK/Id<&8EhML\N9\8J4/^WSlQhMjjXW@5YYi
c?>qKC ^m$ZdHS!1K&<=6F!HR\W661J*^p948@X*@b^uYTS4IMIEDF!+1kt#mVFN%Y!86h+81Z1&WX1TD1#Z\%4
n$XlB: ^uaT<?<tpP$b:1kd&^$k%jKqiMI*AM>yqEN5*N/qen%M^X4W:$YMlAcLuuXw1pkTI\mFwDV\>aqE^V%@
AwM#*^ 416p$LPW1:eK/c6Gq1+EpWlVP&ZXN#yL<MG$XNcp4kP6KpW6!cW*\<WKB\hR@CNm5TdmN*+A4FAcRA\*
wGh:p! MD9wndmSEG>JKecnF*5Ec=H+#VjB9YVZ%k<=Xd9!4Z#KA\aP6@TBatayR+pK4W&BT\qJAPk*T+e>PEIS
q:jE1h i?EBaMXR@*h//IXX4+FdX@*VNmL5u5!5w&IQ4!iEAkdklKcdk=ywF5NpGYMSV4cZ:p=9NZGi58n:e8%#
6jFuV4 CME/%H:%%u>I@#mRe!Vcj<k?4<+E*pq>Z*NFGBMQQpL9S^V5nbR6%$L/n5TI5Ndtm6E>#qq6>l=9cunh
ud6l#w K86c^yBRDch!C9ewwlK$5yyiTRXQJM4qKPWqkkF8FRVdL<#T<dyVijYpZ^<=VXtnR<@RK1u?mYdamRup
Xlp#eG XPcbCFp+!\+=&MhY4hjR:589jX?Zk<Ld5paXmn$WP51IC9j+mCtJ6!k=@?L5nZ6ucN+mn6VHy/\V+k\M
bwd&YD @AmFy\6>6:NhuBQ+Nt^>wTWcw>>Wbyt\dDKnG?VKV*=5<KQFP>QQkwCEhM\lw/u>1<!GkMwLSLbCLPj=
aYGPQl X$EnpYRh@tLCRp+lWY:=G/#ad#YJJ%/u5a+?#a%F5yF?=Neab@^>5FC8%MHZSVKj>&6jE/m<1=yiP@>a
R\Yk4/ #@#y:+8C\Z/*eX&%YcY$Ndj6P1YZ5Tn8L*T/WHeuw/4iTT/H&1E*Gy>pYS5quqBImtVBE#k=jY&<9*ib
DSBbmY kMPjq*@\jhS%4N8ue!k<5GP=/?6+*:D6/+4NY*/6V+:j9KFk?A<FKqe+amEcdam9eiGYwYFnHQ5nIRy#
W*+YGb c#YRiENyA+k<cnt4=4IB$tJ>qC##Du&R9E\6+\6S!IAqp8ht/ej!Iejw+Y5tPVQ=S^=<TAPFuKq51eQp
E+9%tu k\9cF\PK6Cq=GWVY>ESmVI8&I!6R:WI^y1qWY>uJuh9eDt4JY$eqS?&pN!qn4Yu6culb&Z#^8#HMK@5=
JWR!m! HST6iS?1$$IV!u15TQm!/uS5u>Cdi?4qZ+&b#!1qcwFjQ\EtM1*++AWluZ>pIL<KJbcd/YdZYBtA/^KK
@DLBHN ?dpMp1PMeeQtMXQQhWR6YqjP&=Y4!5RYlt:$YK*1q6nq6wMF91pCW/+Vu<S<cn$eJF@W:mk&!*/TBu94
W6lAXn 8@lA>mw^FG8<W4pA%KT4KG*TH4#l</cZlm\%VF9BKClWp$8YSwG1eEBTR!PuhF6Z5XH#hZ1dqt^<tXb5
+=BApX F/ZG?&$!eF5MH9TB+M+Y*D\M5bZLScmp\lpT\d+%VG6BulBh#!6bDu#CR:c65%ikbWLpljt6D5tqkwV#
h>YEp> ?Z<uIDH5i9t#b$:4ku^iud1*<$%G?:G!?6IG*?Q\L?PLy@\Wjn%Hy\Kp:%S*9D6:*ypM4wA@h\mR#/W%
b%<9?^ HCqGpXF%GR$KY6%IqnWPHmn\4ti?:**@A>ajhVTG&WkL9/A8+9@+!:/F/9Q1*SMTA*^P<m+SwiJ<#YSe
=JKWVu nA@^a4PlQQJnB^eh?e:%DuIS&#nDabYS&SL=WMduceIHib>?BlMH?$byIwp*jXC:Ql9ZH!WNqI<mS!=p
k6Wppj e&!TNK@J1ENeP:A#6WB^>9ZQa!+!FM^ied*6+FmTja+#V<tSbdu=RCb<NR:9EY6b*jH4#cWkd6%R$RV=
y&9^Wd n>N>NJqlXlaXQ5e%Jeqy6<j6ZTmCZRP*WbD:h9CwKRR@D$5LGJV#l/$K<Q?li+:@jjHB@*9=n@lZ?a@+
FT*6il &@Ij@wj!H@/95&ZkRu>V@5Nlj+Q>E@pQl@<%C@?VbRF\^F?#5D@yMICL@DZ:y@IjL9w*L9yQ=5QA@#p+
yj<XNK kA9>hZD\Z@aNm\n?c*CA?KQkRFDp@\#6@?@SuVD&@?@8lLF@/$=k/1*581AD=EdbmIlWM6uMkE<!9caR
S?4/XC TZqqhQ%PtVa\alcZ?VqWeDc6qL!6e8:n!aRLiZ4aLP/d??CbC=>QDXN<BIwA!NHBck#M+&BbK+FHu4bl
!Wl8nX uDWNZQBR<pAEyE:a1ldc\BJlQPZI=4jWdEGlMR&9H@cd$R4&$BTjnMXSWWIpin/Wlq$WHIMRb*Qcn9&\
Rw+jyc EZ<N^L^F%XHyj$:LX*pY9I?w9^lDLW*Yq^6MATp*9Wp^TpS1&6!X1=a#1u#>FEkAtdKAMjDd1V4=F&pK
Jmjh4\ PTum=H4hkBdTVlI&be1N<wDwd\%RYG\Le<N&p/QV9hjcMA69<KJbDAEXSu*8WjnT5<49eVF#Znml/QV+
DS?qF& W<mGpL6*pnt^lIw%AN1yp95<%*PC?></DK1EHa=YIITXtT+:?h&Tw^CMw+QNMqmD46\RICyhNN<Tj$Yp
d?wmni a*6QY8NA4nLVlky^9JlEAM>QZ$M$6<T8bl/ynGT4dak!&VKm!GdCX<D#KP6?qNFd>1Zh#KFim:LK946?
\<^Xe@ &A?d9Tp>qe>1py>^1na:ZB8>tKpPHmL=T1Z$wnXubaSVj$DpGdcCySRwKn#YQethLwdQmZ?#MZ1ia*bV
85C$a> FY&R>V=49lhQJebdaq<@9H4jPjjGhY=NA4:$:L$LQ%B@^HyA?*lWwNCTJ1blj6eu!cF$Mh:JL!bFD1G:
Y!JqQ1 4yb5Ll:wuH&iVXHp1cJl=1%5*FqeBHI^8m%+ZwGc\i\tD1\VV8k/iBFtLJ^l#+<5tHE:WGYaL6J?@uRL
%l@/:p P=D%@*Dq%Z&9>D&GL@5w5LnyNW4D%L=EdK=q^nh$LAtlIHQ:p=ZccA#C#AdpQ!MKE$$<y:Xdea+^8J@C
LL*lJL Il<Wei=kRwa%T4&>l=qMKNJX4KMZtB^&#F#@^%h/LLwK&PZZ&I!j16Gn1>!c/Nn<nMZACy<6kbT9FA1?
>D+/ZG K>y:^1h<>badMZT9yPTNHpyiiu%t>iPXW=^mBIkS8u/bVRARZHYKApK&e!LD+815YPtDbb#GqMk5JBhZ
YX5X<w YAHjiT%umMP:mwlLl5w=k*q#QIWi9t4$uM=Y&Qe*uwwi1idELC^/CJFA5\?dGtL6mulDR19J%aGaN\nm
X#&<kZ kln#l$X$V/#+dZNq%6TnLnuwC4>#FC$?5^9Bu<ENLtyNJj>yiD^%t?EX!5el:G^hj8$1NDB<qQn!bVD4
GbXDa+ dWCDn9J9>F$cW5&EZCm6/ycGq>hJaY<FhmPLMPN/u^GVDP8qmCM^?#EYQjGCZTuenDMYN>%bIFGB99uZ
M:am$y 98tIH/mPiLcVXJ%Hb%MyLbtZL6iL%=Ft!lJAYIacTq<8@8V*5wR*\tBwTX6Vu*:ihI\\d$/<EEq:!lt+
GKubn/ Qm/F$Vu+SNZZA&y$JetE<S<T:deuCW=JcjtCRn<^n^dHM>DSi:EaF:=yehmbdt%bV5?%qVcInq/&juP/
!bn6n9 E<<N<ZPwXZlb!n+W?%bbM:d@e4/=IR14i%VeaZ?YRVW<MVd4&W^D*d=\RcHj%+YDKQ/GK<e54^H$5=+R
elcZ1% pE&CPhiFF<N8l1uIQR&u@9liG/=/V*Q8%nWDYa5uS\iL<kMdY\#9=TBnWHiSJwYi&WhNlQ^EJ#GpNnM5
-AKQWn 0007595458900110333 Page 83 of binaries1.zip
J:$<9# 5uj>YbHQ<t89TE6pH^p=jhh/4W$51Vc!c&/!HbPb!E+8iCh^t/*R<PHID!Ga#mK6BSG#m6y*R8+9BFy1
bRSGGQ *55tMjFWi?PJ^X/@Z#V5/=#:<lihC@N154Y1DEJQuy:n6mZMLymwS<Rh6k*l^ED>Gej!qZ>Sd:EBD!>F
KqB=dp C!khZ?Pw=KPQMlnw&$lZM$CjQ%D^IVTGwqn!ln@DE\>c<8m=+&M#*lt\n!:&y#ST^SS?RcXE<^bRJlJ1
V?m*Qy PipDW5/i<4M%9XZe@kATbJ$9&!6?J4VhMALcebeXh1tI*F+cad?Kqp$hh%46@1n\iqV5QV8L5m=M9XH#
kpll8^ pHeR>D/aj5$cqjktp%=^MC/?jHkW5y*T6M6=?1u5Xlua?L6<t:4A#wVX$WD5S&dNdL\/QhXHh@lJ#5=V
*6:WPm QiJF%djAVFRN:c6k1Cy>IH:8T65wc%@/D\A<6!m<n14C66/!GEBQcjD=l=5hnwXwpw5@9q*lN>TZGH!S
BHGHCA i%p\1akhdSZlaDWDSYK%>hX:*TuW@nTZ<&FGkbEXhDNhS+15J>cX\hYd4XFS8hmJG#=c>\4M:i*dWw*p
eYtyl$ m>>b+maX:+\@EW8hM1A<MynD^F/6>q@RtNSdkjkXDRa@deV^=nhwGHYamSw/4QKq+X6#^8a8i>9WyLbK
SC*#I6 mJq><A=GMwh1JXpuMlJ?4eG>J5S8y!H?KtR+iBh8:^9>1XXhwLkF*4!R?VNA%u58ARjG9?lmLhIF=Wu4
a?\p1^ u=5V$4ZNjBQPTcQS\ACbndyjlDpLknJcMN5q6>lIn1+\51a^GY/4/Yk+^?D1<$EL4TPQ=I9i\DL*u<^?
cRej@t b*C6R=5=!Z:j!9Jnjq:ZcVau:l*<jb!wZKKw^Y4%@4FqjW5YQ/IW&Y#4Nyq/CBA6W#i=9ZheSKtYL9m6
yRQ#y: a&cecy=Zy@*DM!KY?aWSMbjT>^b/^^M%STWapaG:&#P4JFT^QHFB5NZTeK!/y68:\Kh$tSGGPMFttnyP
%&L5R1 &GDAetIW<<d!5%jJ=>&n=^!RZ%H6RT\8b\MDK+wBmI<NeJ9V*Ymc+LBqEZ^SeFGGP1jEZX!PTKXZPQNJ
Mh!&el aXlZ/>bB+1bZep<bI6TTw^@jabj*QNk4H*9<PbiSN^@Y%1qPEZ911=*HCPTYh@TBQ!q1h!@b1dA>elAN
Zej1D+ tuRRmY\SMS&Xu+B>R6pwBMhK:cQlBZ/&Lu+KK4mAjJjXVS$ACWN*%N1QaAPhTA:CAd*GmmMuDP^wpCFV
b?uShq =1V@BHaM<Mw8bF%V=TemmA+dkV^nyj1A^JiVLVEelt=!?^WhV19JqTn\F!t\^VbbGRF6i&S4IYLAW?&n
^IbNDi cHGH/aDCbFNb=1\8hIp/G=E/W+J!nt1S9B\HI^EWYT4:npmR+ZqBqmZ*F*J&1j$B=4cDtlhP@XSSNki%
/QI?e^ MtYa$&1eiBHVAXQTdEmCkc8M\Yq\1pN5D!!8qNKBPdd<&yKyq\bqKwjpDRT6^?E>\LY/!<XQIdF/m4%q
9eV:YQ 9lEijlRGp>1Kd#Jh&@\a&Xk%??yEeR6qB1nT&5dRHWV=cVw6^lYFPI$<ieAnNLEXbM/lRIi%%pF59miD
%YtwSP 5V+$*XEXc6=$bqKCdmbeH46KGw:M*Wi9y&*j:a:QBl?<j$nW/VlT5q?lJ^4m?iB5Pp:>hHiccy6jDmVL
MK/#Di 5KeY?%I6<TSIIu1>bGqKNFZlyLYIYdQP6+eDyeE98jF%B%D6wy4nNpI5k=I$DhlEZ8%Ke<u@cAn%MijE
N9FhuG #S=qN*V#5bSPSmnTbTWw<M44NdtTG=hjt*PVXyZK4HDK?MtjP^*mG/4SepXt:HP6e9Y#@8^NJqTZj$8E
%B!WlJ utY?C#4#Cn$@p4MhEJtPXmS$$pBT/iQaAIX&<DnwkPi:\tVi:DXH>t=8ldH^8aYQV%%/b4jHTCK/jQ9N
S&B\SQ P<=EVcGK*%\G64DL&aY&ac1+iek:D\:iIpFkSP\9PYXjR&6L*c+htKb1Th^HFn!W6kKY/KEKe=keM?d/
#c8^@/ ie&+u&dS:pbb:/CptQW9e?E&#VMHT:b*k9bw$RRQc===Pep^@K&kLeJQa4ac1GIWM1GQt?kTFHLB!cQN
@6EAWw \*+q!J1NK*#V+BKhVq/Wy5A$K#uDmbRBuuH9&K*$%!*1KtXKW6A@Fc:yePJZGGDl&Xpk6lJ+G8=KbT54
!6iF>Y ZbIKuL/bQSY*#4jF6yLa&Lb>G9!cZ=PEYYniCWeiNqYXmnW6!<+mHN:?bYQ<Yi\PEm4$dJ\QWPa*nw8X
5<uB?/ mVEKJk$n1PCQ\EQLA@jJtF#ty<F\YY<C+JmTFktkQEPk\JN+/FbStRPpPJ<>\Q\XN<l/ji@!QB*YF%>c
?WRQcR DH&Z@%Kl6FtSNE%%8?X&eC&A:$IC5kEkYP/PN*GejpRiQ\lV>Ci$qt<!LRLXiA%>lit/aMAatIaMn/11
\l@pNL 5TLkHa*V!l9A+l9:<?kh<??P<j=a+\6:hV?=tc*bVkL!a=?ZDu<9qyiVuLa5qhX^QnJHTRK6<F?SMn<H
1qmJqi =kSmVd<C+ZeN<Ra=Th%b*Z$+E6IcpP16I6cZ<kh\XFu5u4+CE\cQA>X=Lj*^Vm&H#F<SRm\u/nVWD9YW
$95<V1 =Z9\9t6H$&KQ$^S!B9*n@=9*:9le+LKZE4yyAQI8b/BqL/8LDX<5CwVaNCAKSHubN*l#\ESMp:%Mi^4=
+MYMXR anq/DSK4?EXD<aq4qPX#6mJq?L@#6KqJG=mQDM9*inXJG:nk?@JdqEnpLTy9?LK!:HHL41qwQyZ9qbXC
M4P+1= 4+pQQukimp<mF\9A8wV#RZI5un$yM*Apy@pij/A+d!1^d5TG!!S\:SRhi@BB5kZA6\a5<Nkat?DC!G#A
HRFltI <Z%Mm#/FZt?:HNIGM*Ca@>STTD=S<V9ZBnAVpI8W?8yyNnlHF1R4kbM+C:wuE\*6^4*XKdm4WDZ4<$qe
keV#PB L6>QbY$X#*Nh+/<uXDePC4!$Vw*\w<MA*=@Ep8?BTpSIHM/<yRAA/8juDSepn@6L4y+hHiXZS:@t#%XZ
$4in1c W*AGMRQ:QMBa\+:YZ%*Pip*euJC<Ge<tPF6QP^Qubh1CucKI#RC//Z6&LZK/pRy1lawPW^I!pTP5<VEK
h4pT!m Mm@/<XGE<XK!VP/N\d=HqTD:ZXtScq@94DqXDYe1EdNKTnKP&&jH?KW8#\AP?$A1^ATj^6^S\>hVBajT
:$&B#a bwi>85>+4KnAYjtymp^!e%TM4c?F4ETq4@&P<nJuQXc\:*DnJ@6<=i^C@EZHyp!R\+:1L+jKSEWc/Hju
R+aF9! Q4QWiN5YEeKm+XiE!mY&%#%pXinnuqDCJAEYk\c4%H!q/\JFM?MT<%e%4P9w\N<q<yb#Pd/uwF==:BLu
VBum&/ c5PCBAbpT@R8ibS8\a8$HpQ4TFtd^H:pEIhZ1uQC6BjlyCjN\JFVBZEhGlWXlAhdRPDG9C1?Q+/6&Ilb
T%XSpt mmuRe!$PRIS&+4G+^9N4m9lM/+aZQ@u&\bDQbW=n%6Zld6pL:Aeuh*/D^/TS*1YVany>KdZ#:juPnj/*
6Kk/Hm cYX1A$SWhb#Qe6QInnN\YpFy9wPd*jFaFHm8!j?QF=FuWbBI?@X%eM/?Py=GQqw1?HVTL:ud\TiAiCj&
&6XA=Y p>a:PNVd&t&CMFaEutQ#PkwZecpVX@qDlp$/tAQ6kGFJu@*lP<8SeV6cS8&WIwP$al1^#:h^<hcpcE*I
w@hHi/ bp9J^4:n$WA@4=EE=68mmpaC?@p9Za^GYJWp1w:5>:b84AT<8Zp*9lyeXw6u$5JFJnm@SbCuc^hwS+Se
FIDe%c CVJENBlhWBP=>91p1<ppdt&B\hhJmL6N#j\5b#6DA1G4PGnS^wDV\ieCuiRKTy8Y5qD^DE:*R&6XA9At
4m<bne itB:5TS68N@MyciwPiAY#Q=B^5YT/i%YII1kEbI$eE^p!T<H61jw>#yYT4iKk#WYMuTQIl4LP?6PXB9#
?<FAPq K&IpQ:NbinW&ehmnL*BBN!D^Q9Zw&l#M<Q9Vea<l41S=ClSXGEBDMc:&6</y#LGMZ=MdcZNIYw&R1bl%
WB!wY? h:mRMVJM#dNIhJjQR1I=LFhY*wlVV&d:A:qwWKAXYEe6!>B#YkVjyXpdRy!yN\?jK$KFcDi%TS&GF@jD
=IC^e8 6CLRc1t5ewqN&qa?c^meq+?mNVk+6WI>uj1BV6?V+Y:91ebTA=6u&qm58D:qN^WFbiJ/=H&KiZ9MH@Cw
cn5T/n wJ$8?Vceii55S*j9Sk*=Qay5KAP!*Dl\%&VQJG6j6Gq=/GF+<PInY@Zlaq?tFWm%Pd4&PlXe1Vmb!^\%
6Vw\wZ l8^y4Z:Q\$c5FcS!n/6C46KR568y\y5<%V8ScW@Xu$q\c!ip!&lelidSai&b*p&59&q@nw/RX8Kuc:Cl
4>/PhX $J:mimMDjnC@#*:+*dDYa\*Dc*tHNBK188mD>ZjB<wlRbXlbmd\5wJi5&5CHwij5l!HXZCeic>MdhiNc
%@4W^5 Smyejl5y@R>/<lG&y^5HV9EyLtIAjHStVwhdDem%Qd*BPWGGj*YQ4c#+94RR9mERXq/nuin*#1M*RXp\
TwC+Dd :EML4p=>yBni=c1/l/Fh1<>tNuiXRJ^1%aeZp#+C&m>WTVjPNKS@jJl^qaVZm=pEC%1#h:+hP=VJ=Hi*
^pKLdP j611^ek>RMA6NJ=d5A9BDFt1@yV1YnR<\%L?J5#JcPi5ZhuiNW<<R%F*<VAe@GNSa&i^a4BtCD>:y1H+
qH:J4X p!&@9*@VCIEpMq8!KMSja%iRVEFKH8*n>pH\!uZiMY/i<+\9&E^R<\d95pFPbX9twH>b1i&n^hMqpwb<
Vke8N@ 4lpVR1FBhwtR8L5lbc1?Q6bF4lWAne!u!E?liJN*S^FbiAeD+Vw&BDZ9kPkQi@IYiyn%aeXRLb88TJQ8
W&+:J% iPa:lttDG\Q4QinQhL9W1/!j%d<TSF@1hky?X9A\8%4?ne6Q@PIPIS4adu#n%&qm1hn#9eZbFkRM^6jF
i\*I+4 pQk/<^Ncj8J9F9m^1>T@FY+ipnnWHVmJ/jWYDt==mI*>S^whIjk@#<Rj^H?dW@?QHeL@^ctLCQ%hy@=@
*Yj>CS T>q@W4&Ij*Z1mL@4%BG\9<Em@ulPQAL?%!#<#<=F@A%Y<E>apd>tajA@>9EI$d@B@6t=au@NCwu<MT5C
Q*!ucM @Y9&V*MAEeF@e9tI9*d=<Q@m<5Z?\PYLCQ&B!^hGCQ=9$\T\<d@?4HiYM:wlCPF4iZP/WB!bIkmw9M8e
>MTjjw jmL1RB+Ciml9PnW?m?9TPtqSeMp\SjEV8*9K1e?*AaXDSISh1R\=FbcD5iAwCLyjaaqNctH6njFh?lNI
D5&%!n C!hd*hMF5VRe$$<1?S^AJwmMtVwB6X8*tkC!!u51p%hZ:BA>E55#:b:/$Y?KuYcTG$M%um8u$Q:p:jl^
?kl+L? A#=DR$pFEPM#JP1K<cPFZpN@tnu$wYQeI>RqH\uX9+>$#^%b=5cQ+%:JXqZuXFi91mnEG8G9GDZ14%jB
*hLXLE @jaWql>!=c\/+4>^nhyM@+\CckZ8QX46BZNJ46/VFYG4ewidn&%eQ8H?CeA8b/Ht<?pQ%c=!*<=wC5XP
!E:$4+ *+M8k^cH^WLH<l*>?Y$yckXMcWlN<$#LPX6wu$TN*I14LkY#!KNhZWb:J5tYQ&5Bicyi^Fw>W%H6^DSI
D6:&R: 9ICE\95e&8bHW#@X%jF1HdZFN8&5RGVVnc!y\iYG#?5AqI%B#SQ%DebcmlDiyB/wFl/S8lBMhPEb/q#/
#IFJLC 8j6:EPPt1wi8nRW%GIh@X<JX:?tnbN59ey4V\PkH6HR#\YEIwY>9$m\YcnNX!AbDGa1YQ8%49D?mA*bu
?E!Fd9 hbl&&DH?D8\qkJ#W1n1Ayn:y+Nl<awAjDu:\/b@>lChX+&1?!+dmC*Ad?\tS/^#^jq<8J9*#PTDSNQ4V
=>i4@p jT*CpnHtHZpmuW<:cQuS5hA8%Qw56/\:!WMd=l%?hK@9i@/mWFYPIwP!uQiP#t1ehBLJS/bjYJKC!pnF
hbi#%j yJ49nDKue9&Qu4A?$t*QZd@\DiLGy1ESFeQ?@MIV:NJS>b:JIC1l=@diM^RquD$ukwnu5b/!<VKPLJQ6
-A1T&! 000eb492ae800110333 Page 84 of binaries1.zip
aK=B</ VJeuTDcZG6lLcM?aGP<&XpdS6Nl%yp\uI?4<i86S$AGEQLEdcmdJn=*iRpmu^MijT&pmPqhpRNH6w$EW
ih55Ee V5<FuLVP*PM$PyKR1bQ9M#ESu$M:Bpq!Vc@S>m4KSJB4M#!=+I!djS!q9X$kI8=^T1hq+QNCe8/^4I!=
y!<@>W ybXYSAw@8Rn*VRwFZSJ8JQln!B51K65^Q+%kMmycqm6TY!WbZV:<R6qPqId^M\5ZDXJGBa:mt@%QiRkN
MLj^IJ CkQ%IjT/jc@qtH+5\#nb*8JLhwIENKE&?!lBHD$H#MSwj<PXPmKiTB>!aKWGGS5wbE4pEG:S\D?YXY+$
&ZaucH !X=lPaHu=Lw?\XKuYyhb#dJbw1cl>c&^?kqMX\5!:F8wM+\m$u:B:m@JDSA6G/Z^>w>pTMhPabw&%=#%
8Eywu1 JbFQTh/eIqDaZFV=/yRA>/yV8yid1XyN^%A1DTDN+Vp#@hJ^P+YwMZ=?^MW@GcwaLHSAWSCw!j8%9Vu6
iic8AV I?89h&+>4&1hkpb*P:<V%apGWIa$X*EW=HLdnRpM=$y@\IlZQDVe$15p?>Z4cjLhku5X/6u/5V5j?m6/
XqklAa hD\Q91@FGJbE^kH4B>a#E?kM5h5dZ5YYqAHbHu@L8%#auC<Y&n/Btp=I56N%C>9DM%Rm%6FVCb:iMe9>
nic@^b ZN^<?CWylMBbTp/1^lul4SlcSeI1h>p:/1iRw&Wh+R^ZR=hJ?p4ypLcHYa@H1A\KPIN<nCSZZ++#nY<u
AbW?#* l^J/I:+\<>=E<e\VSitZ#%8Pc!LwuKJ@=S^e6cmKm*jFbSj!qu!SjLL^YbPF$=t+#Ct!LBQ<tT4t^+8H
hDQI4G a<cVeL$eLh\Zn\nWjcXG:!>@yi>QRBJ/qC&P9L/9GASFY>Y6=?^ctI@^?=\:j15Y$R*ZMk8PetCh&EkJ
XF%pe5 i58$e>>b#:T:FtRljRIp6P!@D6$Wy%tlFJ?MF*&h%d5nHMLc>PSFAdMSXwEp/F+Re=whj\li$Hi#5@bh
5T^y&T 99MAn*#LW=w9=d#9&CaEh>I=NIRS=1$ehjqwCnJbh*c=F<C*IZn!uTbSl:#!6WRm@H+t!!Q?*EI\E\58
qy@#a@ HiN:P:D:G4T@YP:*F$4ep=&Z&=+QN:@1=/EN8D>DJ//IypK<FZb%i*eHMN>ZWa5t?%W!F^u$ji1<P/A&
lEV+>6 cE6hmP56J$EJin&G>=*!&GMYVp@G1cXM>\PNDRGS4ihcw6a#K9ii<LYeuPiphllwVn%:46JTw?<Dh\QK
++F+YR ET>8T+=tQ\1Ab?!@MK9ZN@=t+\t?%&6bQDD=/b66/NLNF/MyehJECHBk9DLd&&F^>C#>$!tw5Fy+KQtu
^d9/8: cT>t?dN/*Z$4$VT=$6YHcR+?a^yGQI4*pJE&pKc$M#54/@%T=1jJtP\uFR%b?/h\i>uP*LEP#I:h&\h8
@LXc?J c56X#hmjI+n9K$iZ>/?/h\a&8=y9/4X\!buTddW!Q1^/IT1Ce/ZJ^j+yIDZe:!8Y>uB1hI%TeElW^nwi
5R!#!4 L?B%uW=cc>at\$cn!jQe%=uHV\nu5CMmRcQj%PWbH+:1V^w4H?QMQb?QM%R1&EZ8dKRInt8+G$Z58w&8
*ZSJkL #Gy!LW8P:NyaFH88h+#tY>h>Sy!@D48jJ!LLGB#HWaSnSim#RFd>+m9q^B:MILH&Se!+/aJwnL=$<%69
AmLl8N JWNjk4jSK!hZTTj?4IwV&:!h16dNLJ<^:<ke45J!L%\Y>5W5J:h&y#Q=u4%%PZMwX:%>Cj\\<j4?JY+\
Y><@:Y :jN8=^p6WYkb>8H*h<BW5QbLc8GI1>ZQlnt%Q:/!j:P1eRibqJZjti?VVk>K^M4beMYYEb?EDD4I<A@b
\9cJp9 6V9R>K5G:8GN41DZ%1MDnnuhdMbh\C/<*Wel?yX>9>kppQbCKhX%8%cw?VI9:kk9eIV+l%ItNcpDQpi5
Q>aTCI <F*wuI5HnMYp58jk>TD8tA%9C&/<K/uj>KdBcE%pGWk4JPnAlM9ZIJ<Zj5KC#W+u4Lw&nQL+al@aT=1u
*wFu5Q e<R:A<l=daHIqWT4+VeJ&Z@CZ$i=:^\>\pG5!iJ&HGuJ^^d5=^&kLSBciQP!WV&cR+5PKuieXn?EyaG^
^1%1@9 bcc&DlZ%\#c&bW=&aAMXdypTC&Aa>N4?/=Ei>N4SkkGWM\41G6c!H+ZHYHI/4pnqK<wGHX\lj%KTRS$4
$8R+CJ %qZ\dq1Ic>1uVKie%p/WI+lSnSC<!P:?wHA!LaX?1Xk&LIWN#BRH?t+mD:Yytt9VTJqkPWC1qXQq1/eC
Ga4eaM A=K&$t%n9B^c<DmJcc5qVYyLpDW?1aIwS$hiQpiQCKqw*>A:*<QV=@6iIS^*aTi#NeDLt4DEc5Wj89dV
=I/X</ AXQlbSM@>LkRT!j#FTPLNWADNTJ!kbNlajYeX=J4aL6!CmFIRDlpcQe<uiQ8MN<kpF*C^WaueI?CPb:<
:@e<YL DR+R*A?4+S!8JQ!IBV1A%&R=K\$Hl48E%\tl1!Qd>+c4PT+F+w%i!t!pwWP/h<J6nl/RYXdj=*c\@a4Q
%KLyMS t=Qwa8eHqD?S/?QW#L5CARkI<T#LN^FCEieXt+Rc?LN<i<\DKu4C&&B\ZRiJuA&\%/T&enIS/$B6pKwj
adlBFQ /TM:?b4WXRQqt1!BY?DV>%b8h+GZ9K!@@l+ijk\FG<$=##JI1A9E%M<*#bwRT6Pp\BRjLEJ5^TLkmn$1
ELt:wA mPXaiu?FkpHdhj&=M?B?yMRHdyq86V8Rm\DLlKt&<nNY8jXAXKi\#Gukq6GRW\?!=#QJ>MDS61YZdB:^
#iZj@i !e*ZcMl^BcSHpbG:DL5*cQ$nYKyd$/=ddV/dn\?ucm$/?yWwu5NB:C%8$N4RJG/!baD5cHRR<?EVp89?
DhMKq$ p?Zj>RZ\>SDn<bLByG4P9NZ:jV9q9TcCad?!y181RiFP5taQ<IjDc6ckMpa!F@ntk6H?J@S+!qlbR#1X
Q$GVHK ?BH*mG5jq9IK8@=<wIRdG5XpLw@i+lJ>yVny9m%cYp/nR$V@pM<$JAj%iwly5<=tX+C8b8w!iFyPjD6W
j55+!$ el55N>DMLCSiLdpZ/91nKyE%4jkDS@F*8D4N>^PnBbKBZ4Y:qqCCi!Z1>+/mD<I6R>#>pZ6H@QXj^ZjZ
Fc!H8P 4p4HJQB@E6XI1I:tmk$Cj:la84l9+<R/C!dNHtui1k#*LQP?HckK&uZKeJbeQuIRWTV/LV<pGX$@9\e8
/?ubtX GS1@mhwY:ReWPC6VemcZdYJ*uk/AwwaSd<5DL^SFBHmD1e8jW:I\NHbN/@VHS9Z!w<yId$biMhpi=ecF
DARGHt 9FQKM&#WTT@T81+M:Cl*8qCc9\lhLmPB>emK+9ilj!RPVA4/uFSVcK9q6JLRGqlPEZF\h%RH*DnCC9c9
Fcj^hQ DAy!DRWE?JTYmcNW*/qq*HkEL6a/jJ>:QAI59Z?y^=i<ywj5!X$jISwKYn@lll>$WBXm8R:*1\GhtdW^
bHWp!K B6\>:uLA*My%?Lc*<Qwe^BQpBIEw+65=5YGnnn48>iWTVS@pDNI+C>uFYB8+Ch*Z+EKk4pF<8#TkI9u?
8dim$h I%bkQy/k?!jmZZNQQ1bb9KDnHZ%KK1caMLq:8!b151=Qy%wYTNkMmIK^AG<pV\+81SlYQN6tKGP@T//p
LRVy>* F?b>t?AqkZ8hqMiD9kbeKK\RW<1QE+\b<T#PaK*wq=ETp<BNS*^W\L:<49a+C1NN/+hGA%M+jVtNwYDL
VL*Q>Q !J\#CHtjAN$:6S!NT6/#PY*npaM5Gd?5mb\LJd?la:9lw:wFapIumn+DQqa9nNHe?6a*AhNSQ6J^4aFS
i5Rp*D c%/j$X8ACuT8#^1&G?$@lEnkZbuk+>\9TJThI$e/XqJEJiy8yjjbt945S+?N?66Z4H1NtRJHHbYnF/$I
5YLcke TjX#uQbK=SZC%>:Jd?T/Jk8:F<nPWBP#mJG^%@JRF:*R#Z$pE89jbR&/&t1IqNZq/nj/&Hil:ha+>>FW
!j6BGH XtwGci!&kK5tAE8^MHpQn<>TkA55jDYe&:C18=:WenknbyR98L/RuE>mtpAZM9F8ajS#HQ%W&4I5+#m&
iJjMqA Ti!$aJtZ&ulea:yR5H!yqP4pm%AZ%IZZqAWY1y#1%IbuGX<wc#n!md51VNZ>jI%=ee\!\GYTNJkFBLWK
aptp+I ZI&p\tB@6qPpe4V*P6ciC8NkEPnuBp/bbG&EbDZH8%DHku%K%quVd*Dm6#n6maNSybNKMR+:E9^8C6DN
CKAXNu 1Bl8l&y*u&Gw%ibnDAwCX16pd4pPR=l/wSHKV8BZN*8XAu#KQw5Ce*#QFJilI:?Eh8WjZ*L*j&6VI$8Y
!MYP^S @bl91>dDt>N9*l@mN5@1F1Q+mQkML@Rlp@LA^%$%>l^daH4mLTBRA+p&ec/^1n=ZyCIYSekV9%HP@jyi
<lHii= nQ$FZ9R?JSeT9m&HyyRX5wQhEm#8Z6$qHdJ4IC4bK4ldB1#R=y@DC1Dd#EnS4\Vl^C+EN^PSiLb8/SP^
j>B^tL PF#5XRWVwWNSB=?#Xelk8=$#DZkyW+4QC=j=jSLp?eP#NwF!m&M=6PV<!<T?5h^BMVnlH$uH+u6#1SX@
hX8FV5 *&:HlVuGDa#E<*bqqFIp<uHuYqWy5NZ::AK<&!mWIqjBW=l^/!>JBZthdcb+!8F</$X^4j5WXmEkt!T!
j8HSY@ lI$GAcCh<HMk:1+%KTZJnLLQQnFnmHH1/YNl>Qtu6C>+aZ1kGuq=C5c!C!t%JEXRQXjbIpyt/^V@Ak!$
u+>V/e akJ%je+a@$me&Bhbe<^Ha$*cbWFGLLR:P!8*l<Mtb+DB^+eu\Rucp6Zmd+c&ZSdJL?i^M+YFY4L5$\Yw
aPmMTJ W4T\S?\Z4#5AbWpC5A4BQm8q+dkJ4\Ec%bdTTHtT?H#:L^#dRe>HA@ME*QDa5ND>NHEk:cJncB#:NH##
JSak=E aSnm:y$cyp$k%!=clJJE\WCLG&1#$d@%#t?kJ91>9>HH%aBIa4$^HMlh#9u<VQ*C9RaXRii:k:E$aA6S
%<>5*^ >LDCcNkn%G*nGNbZV&%HY<*cR!X!LcEI%ikC8=Byq@A&Xj$Spwhlnpm:=IB!pLdZBXa6+ppei\^uFG/!
BLd6!% VE@bqcnK8qeDATYWW1Pj@?XqjBuL$&IDIndF!>KejZHbi$?lyi:>*jk%bB^%KFVp<j5Z&m!DW1XC8Mu$
\$j*WQ 6ALYCbJc$5l9+:$pNdZDX<WFXeMqiYYS5d<HWiDlK=c!#E:8qF=bZNtyK\W6$61Xl\NPJ/=E4=tFwK?M
HeJLuN HK1QAle$Qw5W$wdaM*/aE<abkV\CMAZWQiw:b^b$@Re:^R!neWam:N%>A1Ma?>wlyay?CG<LV8+p:wNC
&qVS?b KRN#/+L!Dp&VmK>k<@QbZlIiTq\ZR/9*ARTnM@968j=$X88&pA1QFe>%>ZV#Z1>I?BF4dXiXq#<yKl8T
\DVatT =/k:HZ+ZE9y86mkmBHbmR>kdAJpj?9tw9?WwTJTIiY^I%@j8EcQB^+Q!W55jmXF:i6JTa++!V&K\eq@\
kd%MK! ^>1@4wkK^N9G%TA9j#ynbnIYK:5T5k5K$SK&?>$wW6Y%QHNElkM8j?1^MnHi$6/Ay>!^K9jtT&4<wlH9
/c5p^a &#&G&a<Zh1lmQSeZ@BBqInH?@bBnQ4Gjq:FHp5hQSu>pMTBVVm5Zwl*!4lieTpBP$:aAZQnQ/5p$8CTR
ERVP=D &Lyp#G^5PXh/5lZ1>9KadMFQ#w^NS$:yANYGDYSE%Qd*:/n\lQm+IjY+G9e?LQ#!H1Rm=>j5y$W@:*ha
F>aJh5 uDe1PCtXTFy:!ZT\F4\YFuZ&iFVnwSuV>u=L9R?Q\#e&EmPB#!nH*Bh+uiC>^%@9T*qyiD6VPT%Vt^&6
&6W?\J tcu<Iq\t^N89j9d5#tApI#NA?Hp!Y>SP=\j%/N\XK>a8R>9G=JDZ#iN!m&?:aF8Sl81jw\MuAb+CtE:>
465el# k*9%HLn>J#i>Kp!=#lWGNhJm#99MSmQQH#CK@CI#@=q/J&NZ+=kLQDj*e/R?X>/=M/HI*i/cN&DV=Fn+
/$tGJC XLFp>54$JJ@QuZX6@pDtlT4\R?qVCyGupc%ZV%Kek9RMkIXaiulja8ttaTdRCGt*Q$plSIV@l^d#m<D?
-AZa#: 000b772399700110333 Page 85 of binaries1.zip
y@+LGi t+IH5Z<NH5V?h9Ak>wjBk<m@BkAm5H<PD$V@8D=hBQE*YMRjT*\Spd@BC9&JmBj>c^a8>5iBl+na*&D@
K>$a$1 =F^S/F?#MJE@un+pK9k*YQmj5EJ@k+Z?!VWL@#W4LQwuLP^95QA@95?mj?P=ElL=E@b9QFh@G4TI@w$H
K:4lid C+d++?*Fw1J@=$&C@VH:N^+5ETn$D%t^9@FkIaV@lQ*uaEpE>yjB$u<$lkmw@8PuWQm@Jp6mj=A5Ca8J
h9&Ln@ mj/jLyH@u*iJ%Di1K6p\Nbl%wZb/uppt:tBRNZ94kJ1cNTE+18bA5Pil=N+TLAECyWEE=/^6Ii>Ja9a^
jEtC\M nn?+ITTC<88R^9#<BIaBS=5J<pF%jBS$<M\GBbP4/t$A<N8ZH#RBiYTIiWNIYEB$le>GKP@XX4!<@Qma
\\h>\> W+c<lH9TBnIS&X6i6EIe:P=LXb+\+\KN%5^WSenGFtlLN8N\:l!?F$k1=eqZaIHn5ETRA?uL>+eecA6S
IhaEWN l%SFH#TXmRDewE?QSEK^%!%ykW:yb5R\^<ZSPYB8i!ypZpZ=nGF?8NL1Ih9=T&8ySkX<hjc1!9W65RH*
Q=ZjPj jp5S$XTW86H<R^q%p\HQJEj6^STn4X%bdZ8jya>ey?4TDc<L*CWHwi8&^y@GIGjc+%>TRl+NiqX+LP6<
taiJ%V qFeuN::mW/X9XLG^il=/4%ELA1RMh9pEi%&886VaQPdKaLb*pd1@=CV:a&+6WZ6nSbT+/CuDy+iTl!b\
we$dCJ H$?j%TY+4FW5^6H^TI#am<nYEmM/N1I9tykm>ymn@GmbYdCm=/6/@Ya&AhHRSj@y$yaPpjJiC^<RG\Kw
aZ!VHB bLRWmyuQ6q#Zhn*JNt6#nY%ai^=b^ak^WXujEX81G%I9\wnH/FClF/9GME*yl!ybMtMM?$<hH%a^mC&p
luA<j^ yKdPunV=t=E+uLB+b$!RNt:R\%cT?ijkth+WHTJ<LN=n:y9<$@RN*dHDEFMjy+Z?A\cQ$^YEpjP>5ac5
q?\y=6 w>C5L#@jTbh<ccb*YuH@=p&*668FK1G$cRT6VLTpyP::/AqT&pC$d^!ZVG:YmtWymBepWa>M$:<HmEY@
+jhB&L H=VXZy9e=6Jj?5\G8LCE9!5M@wpk%p*b?EqlR^MS$iuLqD55\GJVd!4ek+mLAIpk\J9E>tqTI<dN>D94
hRphBX X&5bu^GBLj8bney1!XKc@JaN:%N:Ct^J%TYEu/uueTQ4mQR<BM!/nTBXut=XPIynwt4:>NmyDPGMt/L\
Z<BADZ <1pS99XF?kj1&4B8Mqd//d5q!wNQ$8YiWRkYudIiJ66\aphu=nCt6:SJyA4<=/#Bt5wW8Siu5PG#KGA!
55/8%5 8n>?E^!tP9TPJd=wV4Q%jhSwBq?G#/K>iR%M^Edh4Xu$QHS#SWjEqbY&bn%nq$XDZGyE=ZHXu6alZVpB
lyZFAA wPlN??N$Xh%SqJmNI!T4@SV%@Nt\yAnkkLV?*Ai6\JWbYtSER:&9R5h+IRw<?EnP1=$S?*#VFdn#^a&?
PP5DXY *qhdJ\qQFhuEJNqehVJbd!=RNCZh#FqS6qQ^QH%WpHh$&:KXhmVT><LXAh:4+j^k</Gck+$kZYw#HpNb
h<L>QZ 8X$E=!FHTL?RF1tbYKuqDJD%bF\qn^PqCKm8WiB5m1pL<w8JZm84n*Z/9Fppd9wqnJ:hR=eqaRcQW@?Y
i5N>Z5 Jd=ZQQ8\Qj&w%JtNp9!%kpiPnec\B9tTM9*ceItI&Rw$j+E8h$jtqGQkmHYAe&P9Y/FF>QCAl!9$i58P
c\d:d/ eQWNKSP>5p^kd<^BHel&cIaBB>J9\ma4>*A<W$X!#%p@wnFCmPD?I=1%n@FSaJ?BBtmuyPY*N^=c4&4u
<GD6aM >EjqmhVLD1pSKi155@5JYpb8RWX5tIwuIT\!^PS*L!Db&?$#?%#B<p+9ieWjKuC<R4E84$aD*+ypLH*n
\^^tCq LPe1iFYl:%n@bkF6ejR:#XWDLSkqbi<R=aHHW^5qCyTQ+Y%M<ZbB<uh@k1Z1Qq:H\>@/>MSi^E/9y<+9
ZJLYK# ?1\MM%RRG55pcQd^tpbP^6&855DM4YSHXnjjkNEeT:R%Fj%$?TQL@ZZiAePyi$1jLk^5Ww#e/!<Vwy+D
#8H>5l P5<h:N+lTT5L%DC@Nwk:pw8a^wc+R@&?ywWL8*NlF!4nFCZ8pSYlm#K!1X^RqQSQI6/M/46S:JJkak*e
I\MP:h hGwnitwS9M+Y1Y\Xqd@^?yuR%$8h>^#mj!\%**&ke+uJ/F&5ty1QJK!&:X?IkW4%m4P/qa<4KqnF%NAl
uKd8/I G\JnVaT/aPue9$&>h?qWYS#q41Sk++D*AjjNWqLDlZ=%lX&*$M4il!6YCLdKZwYyn!wAD!yn?$XmlNMP
FCW%a= d18w!EBCw=M%?4:!XmZdyDa!CdC$S*n9$FNFyeXjDL6qb>Zk&a:dTBS^!y1*+X=n+$i56ZDt#DRj<Pqn
%=ujik %tqW<&TV9=EhRH8!R&4NHTGiV6h9t>GC*+?V^bDW%/ddW/aj<Dw$:pQ6&8mTaXVStH=LjT8%=bw6Z^1N
#EI<dC ZdqM:LRL*SKu$@!1ct?a/1K?q8kP\5QhCt6Pq?+SX#PXn$NhLhpZ=nuh&5$5uZEZ:nYiJjAuRu<dleEH
@Ak4AP 6umwyjdWu4Xac?\>PG4XTq4J%8tkJ?AE4hI!6nL*@wVR5nnat/$bMGW&?MC+kWCce+=>I%w*bZu6?NIJ
c4?QY/ l@p5Hj$PjKLAuKV!Gh4<KQ?NC=KH%bu:DFlY>ZH=peH9Bq@V88u:a5iG:Tjel6y6$YIDD4Hi/tQM=eTQ
^*FE+D qTKL5?9ji/$+jlyV!y?=4?8&JPTyR?i\itG#P#%#a>6il:8cN$w<J\:%nQ>Jd/#lWYae9c\HLEkCeH$1
eZTDlJ @E!!H<1JNhMSDMPqJH&w15YYAtMK=t>QIRjn&:P8a6d5w4><ynK9N+@k%?IdDTb!*qF/Z:j?Y&ywYu>M
Sl&YV= ^LGa!F*Z9q\%t@bXRA+ea/CCH\Sn@ewNX?ACMBVMqn+Alt1>#ej>1Ek1E16Ft+Cuyk$wIcNK4KiV*u@E
\GRcWe FpWbIeS69Eb91cj<Sh:dL%+9QTbk8aR!6tEkd9SY6hXi+iE>uhlGuYehVdL>&YG9XC8YpnWt1!8Bu?YV
c?4SN@ :\dd9YQM\j$d9\Q*969Q:yEM@FRd@*=KN/PYi?>n&SLJ#W5?>qp<<TuCHVpi^aHw48TR=R<FAbiXVCkY
6ZHjB$ t\A=IZubQ4hNA*SlyEm?X&TZuXV@*nT8bF+?848@d&DVK=dLB+HYB^+\/BB$@kwJ>I%Ej^pld++hAW1m
BWwQuh myXB^eX$NSaG^eVJ^DW=TJjI9m%t1d++INe+PFweGGcL=?AJt6DwC#Y6DLi4+Y+CeC#/&DCCFJqTXJaV
%t$AG> >\8YWKi1M4!myFIjpLHQ86a6wS+Zeq61%q/\RZ+hyF$bAYSwK@C+*A@PGapIV+!$<1tW1+waMipw\+%X
$%H<W9 /Y\5L\mYTZWy6JT4HG<4:#KVhwjWQua<1yMjlpMtl:86XL&B&=SpJ9p<5tSj&#KQ:M^P8/u!a/$V1PLC
#dkkun #1nP\9i^HPL^y@ZbGTq45XNnRy:%y>8X66/#<DwyKAw=jkpcC^DcX@!RE@?KhM%T+IlnCC!DH&qWYtIl
mbnF!c E+uA$DKcPk^E!8Tw:h+9qwwKuRc\KKiXQbc%5Abd6al81wAKLWFnE1b5quLHIAZbJD^Mul^:i/t!CH+%
k+b5an dK4CyKJ/q:KIDq:HyGDuplG+DqM5p*PYpkjK+CpacK+:AhF8C?GcDQJ/!XE*#*w/yjK<AQny?u%SD*d>
QnQl<S kuj\<Cw5?&RH86q@1iX:kRj6$BwJwCKGEVj=n>8D*NGTMwTBnlZ6@cVuy*ENZp\>X8Shk:^%?/S&$%\V
AR8P>H ZLKh5enpcPZ\pmIG?W*qlyIYq@MKj@#y6CKGCp6i5F9<IN@dN9KC:wwKQd^Eu4PV9EkNG!=bB9PZ6F?b
/BZeEb 6aJn6Rut8c6:VPSd8M8c=A9uc!c1T4@8yMlc94EGmi#a/TL9t/kWjD!uEB:wLMbdp:5RNh@\l=Y>E/B\
EEuALZ M4!\y??dE$VbeR?lWuFyWm$ldb45\l59PIJ6CC5uWch+>*hD%4qjM$<tGy+\Y?CVEB>k+IW*%4^Wd<e1
IT1#@1 ^d@81bZ&Qhh5$:EN>C1IICG+d4FI\<F!ke*MpQVcQ=/ypXNl!5JdE$*+bV:V/WqT!X^kkVh#tWuSaF+Z
dH:!TD $9J9$>NcKpq@YbAZbX*<MHKymRS8E#TRQNFI#L4\i>VLKCyM6*uBlMTYTB:&%S<&=$%<@K4t5bTApDZG
ZZLmd9 u6FSXc=PalcH*CH!5iP=9y^!^YWNkaD/?6VyHN>&%EN<ln/ZQk<pk$X^ShubT5u&bZSXIXQNhJqm9JFK
X#ku>@ y:d6D<TP#KYATR%:n#N4uAll4q^pXRW+^%FnXwVE/THSBWPE\+jCqY::FP=BP\9Y</t<kcq#eXuTuWkd
A18%aG V4u6TFWp:<B&=C^=N!D?X$u=l8<8#a?kMwjSw#leblG5E@tcZ#JJ%+nLMpCSl>a8p\kS^V%**8ei=&?E
HT+p$w apB:RcZetBJCRmPWnRkq1H+!BGXl4TFy%&9h^DH8k/pqWXQVFV<hWdd/41p+cV/FXS9h!^A9S^4J48Qw
F$G@W% +HkcLtc/qXddqm@D&\5Sm6aa=I^<i$kpCd/EbcnhPHF>^Y$RW<F^NbcLul^:KNZAd<J&>TT&^u<:Ql?=
>HdB=H INGHtmdkBiL!QTZNBaSFkDZQw>Dc$k1ZiR=#n=FDHy/LAKB+ZYRq9CD=LbE!AJiL4n/&ePTP8I=ilj&<
lV/dSA tHkeESKkw$R?^jdhM5WFyj*>pZX+DS:SI%eaPLw8$eZWnniAa+kDjYlmkNBReAFJIhTJ<i^K?$iaJ?QL
b=@#Z= 4qW@1!5Bwq86HZnBZ5?J$ZS*Huy1BVL!SR!@KJCI$PeYIYd/&@Lcl?p6kb<qJwhF5DbMp+/I4^*pAh+t
>Q+Au= 9iuSP9PGhcDE/:FuemKTyJ?iFT>J#EFke*N5Xu%k#=XwqD6*ncH$6IpNBdYwip?wnaH\l4baIAyj^18d
n!Fi46 m$Q<G#Wl1N:Jbe4G5\+YVT\&?6p>6WKdNN6AwdPpPN!1=G&kAI@+cR=^E&:Y5cTS=yuE>Ei6qA:#lkW=
Jwc%4X BH/X!^!I4RHAGduBK#=NVWS<#iLK=m#68W&I=YZK$/w+Q<N&<Xw\>uGlt#Pyly6Y+KCbW#=bhK*<AHP$
VPj%Tl jIXi#1BVtVN**%Mc6/QlIqVbn16#ecCk6C6Z%HNW8hERP+@PwN>WaiVIhJAHZ?/4YJ+H%JP^G9ntk%9l
/GdT!L XY@<I&hiTciY&Jd!LMJ<qEEw+aGI>S=hJ6QMA*5tG4^k<u$TphQ81%SFn$*S/!Hl>e>Q1W4FD=X\l>i:
T1t=9u +6eL+J^/JIy6#XIK:I^iYP1Plh<h4+q>cuIYlE\iBj*J?qW^+j>=m4HF@y8e1CAWK9LQW9Rj4!H?ylZ>
X#t9jm V@*^#%dqZ@YX&L>1$V@YhYKI9<Em@wRX?S95u<^HESQ>c@dj>yD?IT9&N%nwH:L@8IZR9+cFSiF@Ak9?
BD8DcE NT\E?#Na/K@lQ#PF@/CF@=4?E&Z*D^n&N?/a5NCj\QB@pubmj!*6^Q/46BQ<%=u\@@hV@<@%+EL@8Ej@
i=EMP% t>TDl#H@L%AQ9w1yk1L#iB=G%#Ew&iKW^GG/K?wYyIa*&m?=E%mXIX*qN@%WT6&T$%%XblpH<NCHJiwM
4$FbD+ kQwwujt1@B\NlqAe$B$EYd5yKCw:%jhDnJlH#+IcJqVu^MKGEwh6A8MNu1Ga#N+jHYDelm!dPiLd/9JF
dt%YbC b9SM5&Z5tWe:T#\5m&W1IbK#DeA9M9F^MM>i^CMlBQ=Bk&!9/cwp@LBZ!TRWl*#11c\D:@t+ZnID#>NK
TeV8d\ ay@Vwcy<?b&lik>+lQ5E:?K$5EC%%RNPjVMHa*6A@iuTw^wXu\WdAM:a+u!>B<yR^pAZS@<yclbMbIhW
6*#15J KqinZ$H\+bm8E&*5m5hiK^?LC1i:wGCAl+Ewcq%ccKtdyde\:6lWHcDWti>d*$>JwG:K:NlY%F8ubeV@
-ARmiI 0003858c90300110333 Page 86 of binaries1.zip
4W5D!% 6>I<yeuCVBY$8tS8Xt*^@LGEF@hBq//FK4EMedAXpA=?QYNwdK=ZmSpd>AJ:t=ki/mnFH#!VVam199c/
\4AipK %:CRXPWa><q:diEb=la^DnElT4iXMb&\\I8w94a16\?qKL16uTB&@Eu:STZkR?tCn\4im<ad^+n8qi8V
hewQYa h^/4DPNDEEDWu4&MSt$&&aC>d:&a!n&yHK*#!8ZH1+Pd>>VE6BimGXQdXt+S4p>$hS6D^A+iFlk4CV8k
FAbp#w XT^%iZqaITDZ*8i9:==J*bdF@MyB<X5@VM8uj1uMaE?NNPHwPBMR@h$EuS#9:%wan&aEEm8X?kTwEb!I
?@nqE$ dpwWkcJtdK5Z8<PKW%5%Z\inS6<pQ\1KN9yI61nF>*ANl:!uWy&V$<4iu=Zq<pj4NE?MiueDw1R\D^%N
&Q>=5C 9\#@ewDNEpwKnn4<Rumpueml=@Ay^n\edme/WXF5VJd56k6%=1eITu1MVmYMMTJpG1CB<$:MT8>bC\R&
<Q+maE 9$pl4b6%t%jqt1wy^lQ>puV8>>Lq^<mVbwM9:$L+AYSqdPt5Q:=ymje:&NF$q?R6j!a1p\G1>kmLaM5Q
kkHLFM nWc^^+%t<M9kdyIb9*<tVR!/TpdEV1P/u\ij@BAEwwaV:6Z^G!5Bky@m5FBLe@uEPNlee&LEl/J=eqYJ
FP?lnL AG@dpcm*?wLY!Cq>&SL5##\n?i!\:Zd^aqECZqMimbmHKe?KhQHSCVPqCtT!C#KV=nZw#DH%:qTH%KbZ
IjNwBy hBS*9C<Q:+W!lteRYiXFbR1?H8yT$D8eL^eFSk8=KSbHY/*!&GWq*6+>C9QEW/j++FiD>C4%\mH:ZMj9
uZ8T+K WtWR*IiW:FC^C+B^A#u1T>^BYmEa1IP6cWhyZ9NWV#jIih6jQkQ<Xyu8NJDhylq#/WjMie^iEJl:KuMd
c&tL5h WJlj%l$w&!tTHY^mRjRm?SGyXDC1*qnKbna<+HJ8MM%A1wYKWAbaHSCHHT!XZ>1QCwm?#RlKQMnyjlMM
XTRA\q >tk4juQ=\!mXYjVh?Iq!MJdy%=TcF*wPGiEIwFTYqdcHP#lXZeQY/TWX9w4nEc%y<YAK&ETYHX^!+n!L
Vw?N>y YLp!hyM4GHuCVq5#VM?#6e%XR!t/KB<a6#5H4B?GW?MScB\Y84qanwZ*1:?^I$+qh19XJ9VS\nZttcuI
9FhWyA $YQQyqdY96+&^ZX@p!4+CLk?AdBM@q%bEF*La=4Suea6W%&>i9ei+4CpP/bw!9i+8Z1R>Ki/PeI>RWM#
BNuK/a 6XkYbVHe!@e6>MHMHaFWh&9\e!1F+:WZbJ::V@l!p1Y!=c^&*qX9^4&a@#X4^MF$Z/p9BB:V$n\qN91J
Y<mb>X FXRBuLm:w4+LijH%P=Xhd1Equ>CMj*Fm8FwpIJSnD*NIl/*d1qB^8:IwlZa?bkL\AFP$<#tnp6WDulN4
EQCmu& m#MjhFtZJYYwW8?@ENA/SGZTPIN9AZL6DPcGl:RbFTjFDGtGm\Gt9K#ELh$DJaH:tkhpQ?JpP*=a<Z\%
>H@9YQ eM&p5wa1^E59*5W/@NT$nSylF$&/6Dq+iXda?kwTH/$nu*nN#=5:hX%iA9#&=SCkpW^&ad1Pnu14Ry#\
y%c+?k =w!Ne@m*<n%JyVmB5h5Mn+DiFdl^Mkc\kT!:<wL>$uhBYn<W*4mC5j5mlP$NHJ+tG@M>1\^6XQ81IFi8
=Z?8aG ?<LD/V*a?!FQnk^IniDeSEuBJj?wwE5hjP@B$>B:MP/baW!<AiPVn&YkwnpHm8CZ/lXMPb^l1PuebBpT
/Qui=% \D$KWT/8V^EmZu6GBHjiJaE^TJ&=R%ZRL@d*RT:FZqL9SCQDa%*E1p19W&1i&NYWNVDZXZkAZELa5w@u
?EKAa1 I*ti/!MmF6+\V*iy>Fa<!N!bVCcF4uYbj98ed8F#h\ip6kKCGLN\lTJ8SA+XmSnX<<:<p<qi6/5wMLj1
&uD\a? 8Ri+%VPm*=4pme+4:myCSZwm:?#lS9AhXYtGmeyZ@cat5hQEuamlMdN*bHt:qW/uq#aejVqW?A:HqG9m
9$BL^> Gd$tZ\^J:LJmHue9*MXT>54b6?t>Mb6\%!8\buK!T:6iVP*jqTmXhwBZbLb\PG*4$w<TI8eeCWi+Pai?
9In=hP #+16JamFi1X?Zq/qh4RY?mlueD5e6&!hJkD^EF=%S8YX\I@<&N>N!Jeyt?qDuT+qQCD<V*u6dbWwbj$4
e=n*P> =/@Fq\8@R#*CCn8&%=Vq$h+d@dwCZ+=yG@tCZZk=Z$%6:#phtPR>iABd:b++:QTiYjk^HXHk$n$\LLPH
DFCuaN @8*QpXL&=KqjG#mQ:8Y%5P&Zy&=/XL?+8?=aPPXJG4I1&IW^A:<GZLG?>8mGVk?!tE^9HBD\ijt!@pDY
/>cpV> +KwTV/9d>^lY*Hq#L<wR4mTlp^ZmIJbhY**YVcd&yp++RP5!BpPuEPkEIl6+w<wPlDwk?TQdWB\*BX%4
Hy/B^L dyWi=/h/!WF*l*$Pi8!\/RKZ+b:FW?DiBGcj\M+unN&TH/&CW%PQn<Pjn5?EEuB44&AR\#/!Lw8:==An
t$Tw&/ 6B?G*&iMn\I%FncF%BkMwntSI=N\ICSnq\:FNi=k/$<kb@SbJuER6L/CPm>Y@PZC9P+yCI1T6D^TT1!M
W1lyHu %n91Z>!Jl@WmqZ$F56TG1aB^/?WDEt1&9plZLQXi\q1iPmn4kc5kNCBBBaI>4<jLmHZG4ZbtZyVA@%qA
D@K/>+ Qn:w\Mq!+/$eFY^E%d4Q!M@?myL9G+qXJ%Li#=J\EqZL:$jtW:@8+EqWb^pY=DIX%DBmp!Ga\dh%Gm=L
\Eb=N6 VctwSLSVVuZMwA/wMP:*+uPP:w>q=c$p>J6wC+\6P\@l%FPMhqTF4c4w1R9?CuDw?R&GBT1B+V5\@8IB
B^mbG& <*CV>>!@HNA/mtS*TA8Sl$+GaBi91h*A%RPGX#Ku5tM1%Qn4SVEP&<X*1=8L5b5\F?VcqlLijV5!%n4&
@q<XhP ihqRyuGD5yP16DmB?%9/nB8huPGT9IYL=9E>YVbQkIhTRaBk/wu$MMHI%%BGMGuXI^LCP6p>yIYJSduM
Bq/RnK ce@<ib>V>qp8==/mR4q1k=^m/dA95PR:V?$yj:uL?+yy&dku+F=wmpaFjK>QuT9/6Blp?XEe/YmmmFeV
M?Kk\M +ZaEIF@4%jnC^T/F*Jj5SH:kLP!!HBC@/Su&e*bREKa/R\/MF9phV9ibF>LXuCQBlK<bl9MCMZqZPET\
6BX!BF 4R5/e6aDDTTw/<A5*$RjQbuQ/lIW81FP!pWS!i?a/IFKCnSMMyIu$&aqC&MVKNBk/lYcqutTIKTKw!HE
T#HeqI N<P:Q?#HD59ye#FBmX5Abp5@/4Nw%8%cBZQc:IRJ@iSH98HeKdH5YmAHcbP4aAXdB\##JybJK=4k@=wI
CIRDY4 bjie!d<uqLM/mX&1QATi!HDh+d\VQ1Pe!Q9hH@/LDXMj%YuM6*19#HeWBWFc+FG1bcWud4!&ZSN!=X?h
F+LZ*A 8NGV1!u6y&4CKA9Nm9?5tAYYl8KEW+EE!44n9*AX@DB!m\ZHlN9IR=@kFZBERHW$A4$*Nw^CTWFh9cIZ
/RKhh4 RnF:V<TFVcL4l@Y=bapT1!uP5FBML8n#N%T#<RtpXc:&K4TZHA!EKkw^F=B!EmEKG*Zl8TjT9LK#YSL5
unZaJi EkNJJXtH1=\ZWt1Z!=dJBa/>JuuttLVDESE+X6Y/p=+\YM:?m9NkWy$Tq%MV>Bp$w>d\RYPAM?kny$$y
GbAwDn @%FMi\nVpINC=bMSd5jIGwF1V8B$DF5wh9J5R%d68W8b?Npb/pum1nkGW8l!IF>Vyh/LHZ$iT<\$lCLA
1iNu%a $ecVJR*F:pB*cDXm&muD1$=#H<1:%XEcnKFIhL>1=QS=tiHnt?Td\C/MH<phCARn16eh?Qa>=I6W6Nnj
:1yuq: 5XI1CyAi<BiX#G%6Wp<m?PD4Pih?qdPSPq%jwAWJKN+9/ppa8hFcNRe*99$Mp@&6DHmmc*Yq6Gd+qZC8
tN6JIa IP=9lXS5J$WCMha^ahlQ<jN*Bnt>6NE8wQWSZn\C8P&!D#Rijn:h1Yu>hJ+DTECk/C=?^j@=$YX:tyYu
EQY%?X pRIqH\cw$PSy5RMcT:utJiQMmk#MTL&j%8X88PXXN%nLGLWK:Dw\nu5<q^jGuM?eiZ\FLnepWdlJChp\
>PSeZ4 IZ/Fh>$66nq%:^>j&lBbwZ9#RpI!ETA+at@iL4YZu9t#R=!DV@\np!R>u^StaZ6Z8>CYdHaSyZB1G18&
Ctq+k< bQ5Vu+n+#PFK<TniLJ%hEubXw/A%Iw/DdLTpAFZe<^JyC!AQZ?kZRi:tS^yLKp%c9&ed?Q<9>9+/K1/%
#nQ:6N #hiFIWBlXaW:TRn8WwdEeJjC*h%hRkklTPG8AWJ\q<I%BHh*CBCC8$MIIXuj/6=9>?uV:<4ynF=:n@&N
:d=t$e e@b@M!Ne5!bX>$#88y:j9J@5WW9%YiTa:&XmpTL4F$eu+/hYqhyE^FK<V<^1HW4uu6pl=9uQl\pApY=8
%B:MFb J<l6F&%BFi<WdtA6RGW@iHM9Ij/mkEaDjS=nc8Zymy\b>DXZ4J5nHbZ>\?@1\j61^t#\mN+MWwZVLH6w
aZ8w@* \ubpbDkmT\Y+aCTj>Y/@yY!jPQuIKV5m\ADDTtiHjwTR8IRkdcVRa=!:1hC8#L?S>a!JTuDj1$!$D:RX
heAT%* F&B@/:KAEScT1y<tSnEwG%Jc^XFZ<#VqP5YHPqy<hY4DCK@JWHSp?9:<EmbTe9N+JI$1\LGkH4>4!l1:
:RWuhC +!QZ=euEC+$B4LApSNhYS&&lnl%pnah^T\$:dZlm>IYCuVcYVJkRF<Xtwlu4p5qW#NC&mijEBXF=VqVk
%n\mbw AXI6Ha+FAN><mNB?ADl<Mm9$m4YIQ#q!*eklJ4m/I*XlX9ktbqTXIw+GJMK:yF#R^&6:=eE:cuHpdcu^
$Kt<X! !S^KcHu>FIEHW:uwX&=kT^k5#XDu@i=&/*4#PhH>p:A:w/1kLtwZu>JYMZ9w$e5GV$9SL+<d^M^MlqZe
c^QE@% be%1CY$ciAT?%4Ip^E^QD/l5+$yV=iiaw$\RpPwZE6ccwQnCHC6%iejb/\qIELCSWy5AEXhBMAYSpP6\
HD%S9q +<&i&YYV5n%HdDF$:jKKbjTqud%ht/mS*/q^/$^m*:eP<=5*$HT4Ab$:M9Pe!%tG5=G+CpylbSbL9ZR^
TX4!C? &TF^ic&hFTm#:R<#K%4diuB5>XP:jYe4=PESkj?Lw!\i5/DJu9lndR>16\pLq/qt&1<:ZWCII/bZp%*S
FEZ*&P D9QPh1Cn#&:k@ud@V&TN6bCe$ZcC\:5N\ajuD4:>#jpkp*I*ZDZ4<J\twJ#XK*?HBa6J?yH?Vk5ia!D*
I9QpC! yPYAt\/9\=d%QCa%+Q\&PbiWI?eEA*/&q^XN<JJaMIQ#u6cIjSBDh\kLheq?ncF/FmB1Ni?dMpiCdGu=
:=w\SB T^c<u>qYjkQ!>!WYbK9:?@$hH?E/88ieee8WbypZjARRew<KRWw8jSM<@IM$kwM1S!!6G\FW/+@^5qwF
?j?hSZ uKVTMFT+%IE+yPZANne<ibj#A^4B+9#B=&4F:k$F:uVE\McZB1wC!w:D+m9CJYC5cnpt&K$1h!5CJCu:
>G5#a: !m>:8JAp5iu5jYCiQ1%49u:58?ac1Sb?Z4&A+Td=N\%Mm/CCEw1WKptZb+HdaRtjyJ6hbINbch>^$jwp
V*?wPn %ql>=Ra&*p?RQFhbhLKMeue+iC/C/E&QYwAuHZZT@iGp:H8Gn#cCuF/eVN6/\T#pd4JtYT&$e5%Q=L1T
&yJ8YB &qVGDm$/TkPC\\p6uN=D5\AN=BiyV<\699c/#/9KGB#h\a1X8P!BQI/>G@J$q++^Yhd<WS$&?G^Nd4*y
^ReAuR P^?B!=t6&HpS>inT4EL9:<SCTwDnNmN>quITMVR/5CB^LB#/Ppaimm/9uCIa$XF</$?jQdljN#CR<Vy1
L:J8!p ipni%=44QLeew!Q:W@BL>lKGZcCR/ill?w9>5pB=ycBcTZn6$Hmp%!luY1E=VadAl8TuL+@!j>STL4WK
PFWE?H :*WV?&YFZyZm?:&h@IQ=$ta!nKwIh$hG*<=5jhYI6un:/IXeV*45+ypuk=M41jLRW$QMcb&ZN1EGi%qF
-A*I6m 0004a675a6a00110333 Page 87 of binaries1.zip
K!q84j 1mhIPeYJH$=kXJdG=KY<p%h:RWJB/WRYWZJGZh$hVeeP/nPPaWnlAQ+eBjGM\wYCw!@wXkZ4<A@nNN?&
#n6*GH =m1VeN&ZX*?5yDatM\!LVI<tERC4%1X^1IRBm??>l+X%!RK#b#=NcL%n$dh5yik^h<+<8n\Seq6AY8\D
6?B1E5 =@D>D8p6=8TT9dZMCkECe=AeT*ed:?+9h\SP1iPY&9Qy8mY$9hw95+iA<>F//R9c+Qe?FNACAaQ=:V&S
!bN%5F Cc<pq4I$@XZ=B/4Jt%bTQe4<F9p<#&L8?6\*Wm\IVIdqWpNNWtl^<L!J*n/yt<yWlT^ckp=MB^6ZG^9A
+D$QL\ =KtNYa*:t\ey1/ZAV%ZY8nt&6SY%G:<IZQ>D$@>9T%#@?jyC@:*qBanAQ!<9RQl@i*qB+K>G1Q>=Nj@p
IqbkWi &@>^ld?^\QDuTjq@l$d<mld+DSw8KQkLG9IdNA#^m/WCAil9$NBj/Z+B&P@Rj#*/=W<c@l9$4%eLBBC@
Ghmwp@ </aLIu=BC@:YS\d:BT*$G@R9q!wE@6Me?Z>u@^?YG@/9ZQC@4nhAIZ?^*kD=m%u!MEG++Q>JCj@Qu!YQ
?>FWRQ A9&9tTY@j%9^J5\8AYB@CiJSmD$kmAQWLFlnE5R^bla@X$#5CldnDNRH9FG<1cB5NI@du&\$V^5Tdnmd
Je8$$N /Ny8hPYT4R&=q*@#8T@eB\qHtAcupW<ln+kuXYee#9hC!K+\Ph4q:I+dtMLJLwp%!mjM@piGiNk$!S!#
Jj\%ZH yQ+^?#CKKH>*QI^@%&/4\a&5eC+chHTjGKWAa1Y5t/J>T4Hkyc>E*4Yl4$E*yXWRRLq+5cC*DE1CJ!!D
6//VY1 tF\P>%DZK%pIk/>KWdPNaCbb&u+NuKc=\hGX1JXQEp1d$/AkC:<yje1R>/@4nlVpGBektq1416:ED55k
$GwpcT pwL*L*ZQ:=<E4=\G1JJ@mq/l5&/a?HBPDt/cjj>1WE9B%198KP8?^/jS*5QTVc*IN$nSj^>cL%Di>eM\
K8/*XG BK8%eMq5wp&e8mG/Xybc$M8DV=G9LwQC^5:SKd>qY%B&9F!*WYy1$bDZ1Rb1ydSjF69mpRLZFeFW>NmV
!W>Zm@ e/y9w1?9t/NQqKuRbCuewyR8eY\$D^lcE$t\k1$eEZh:pM9SjdJ>KYk?LlApjuVEWnWq=w&>4K4%Wt4A
XnpX$L pQ^+qF*EEic*DKc:4yk#N9D9duLNA=Q*\l6F%D@6HiXj#$$jD^F#+1mH8A4Z%qa?q#:\?9w/SQ\45jN>
G/ZF&M wHKG1*ew!T#IiGF1ZtMKEi@AN:SQu@\&VD@=n+4:V4:tGuVc*:B5Z\CEwWZGQ+Wq*b^Z%$XMuA6&u:D>
pVQGje 4MHM@Tk*/CqZNK&^6idDLnei4pl4qXZ#iZnD*5FnYqSL4>Mp@TNaJa&e%%*Y/ZQZ\\CGHH8idy5d#i>a
I&1IBq uKW@mdlSBF<@t/>dkNyJ^cq$d4<E<Sm4HJI#c9te$*L1Rb%l+/nyq%nlF/X1amHMCL#*kDi=b$IHV%&y
PpHdKT p*QInh+<emIa&G4hWKKaJL!V=Rya:GDTACFd=ZHR+R\qVBau*dpuAB8@TWkhe<nm9VNbpBd<+:b+#Ac#
PL%n\? htSl\?P<+kb:jdM>$M+>CD$5qN#Chql:8FAlI/\4bD:?GTJBK8&D$NJ*#KTZ\m+M$&#dl+=$/19S=^D%
*L8w=i jKGae!Rukca4D!/8:K$Ve>+4Yd=9cCuNeL4b8=\*<a=HkWuQ:p>BMwRu19G=PaJ#6t9LZc6*X$J6V8=n
4=D/6j ^qiwPAaIl\^&Ah<&\b\4PF&cPS1l$h>#pj6*dQupu9jwlG8n%W&YS4?!h?6%RSDdhi6eF&w*?Y$T6u$4
yRW4nR H8?5y#!Tp5GI^HTZEiEyi/MS/!#TH/!<Zw*QE/A<kMkCWWWPb%LLnVF#?d6J*4m8=e:<CwSXu<?#IEZZ
VMElD6 Qde^YPh5WRu#V<hSjqQZ&Dim:eYR*k#PWFluX%bFE@u/#kR:uN&Il9P41\Kt@LEFIA&P$yC@6a:ZlJh!
*M<:T* WwpMuwj5KIpXPNBty=hY\S?JmCA$e:MFeieXqNcXTkqHq6XLS^LBV>qT&Z6#JAj/<9MW*nmRkmk!JdSX
Tm\JEE p<m<T6ZiQWVkm+#ae#?PaCP=$ZZywy/4&%RL!JtE@mM%4kVKLW6Z5?=m+ucMH:&tR!<*=cGh*Aw4PYdy
C9SW8Q 9Ap+I:cmn$8m?4:l>a&Ti%t6#c^$#Tb!IL6JE$eRm%W+?b$ybHTtlHa:@FwLe#wTtFLcQDMKAE*+a8>C
LW$w4k /NGHtI1*c%%<V?9hw1LtMktK/=j9#?l64$H$tYSW!V$dZcT#X8=:S+%4jZuKX+Gj1\N^t&I5$JYLZ=EQ
pSL#96 VLiEjew5CT+euiEbDHDae&<FpE<VCVMy$kS^eyki&nX#WDR!bd?wp!N548e4wkq#>eSXp@*tMWj*Zlep
?@4ZH5 pJ8u@yqaQlCbKNBY#BZlIXnQ5wI%81w5:Qu19mdkwWI*4+kLN+@Hi1pBQSci&dDCS=dmJ>\Sy+X$em?K
?cccJY tDPqtP$eTJ654tpL/S+Z=mXBw/XwFm6FN?Ve#:T<l*l/qpedA+?yYEt>hiSC?G<5dwII&=HKpnNVG*EE
EPD&L1 WEyTaDb/qqaja*PiGFyXPF4YLQmpP<iQ1JkZa6Y8GHmk8t96>mlyw!Y1JVky^dP<p8T:?u=:j5tGktDW
LiwEt4 /p/4aQcud1n@XIP!HH6D5pqmyEd>pY6Fy\=@/Gl#HhCq+E1bVHFLM^knLMQ%WX+lPZDWATL<PQ!/S>*$
e!!E8G $d5d</C\CpW:D6WQ:?8i4@cVj1IQet$*A?:=1<TSG^wi+Xj/MaQ%ZXh/h&ZhZS<9ljLNKn>jpMN6C5qH
*14eGI dH<l&QtG/dJ&/ln/KZP8l@w<8Q+lh8Ab4y5abeFLAVicLWm+CXQla1dqFBD>/h#:?eCJwB1\d6CQb:C%
Emj!K1 :muYm?QnEpNGuw6DwTp%!B:awB&:D$EhW$TQupk\b85$h$SFH#t1jLCT6DRa:!nk>h?P6TdNYDuC?J\e
4Wh>Rl /!k9=+4+Ma^Aa&wYcn**R%&?pW+#kNWa$Kp8ZFjjd*ubK^@QlQ8p=::&6hPTmnXlI?*eLD#=l!pAhS#K
ka8<mZ \SC#GqFb+L%Dp1Gl$>BN@1RGy@tyS<QwSA?h@GS?QYtCl4He<<<1nVHdG>MqT!a^lhh?CZG$YlqLepZR
DQn=ZG H>lj1#&@B/a+Hu+N@Hl\Y:S$?&/Qa??XXE*X<Lwc5<^npZplt$>K9Zd>jYM8lItVL>^cEdl+8\#Jibce
S^8b!F 9B?G*yNe!Xh<RJ/:1>tF*9tEWH4bdAcEWN:%P*keN4AN?SHl=Qb!*@!$yHhn9bMw$bk=5l8XtZLnG:%u
JXCqde #j1VtN9N&1G@Y^GjRW*:wBRR51@1eP%c\K@L^Vl?E4CAlC*IwIIW5y#:9DyP1CH4^?kJ\EjYtyJKI/Qk
Y4N=S@ 6F/=c?*Nc/S<aa*>eTX#GlmZ9Hy+j!LIF^HSnwmNK=j@1X1cBi\+\HhJKe**5JZyJWVSH+i6G9IQuC4a
RCNBnW E8/6SXcXup4ZAu6EAD&^&Hp?lTC6W9=SjDbtR@+%Y^/<JGa9Q*tZYtA1<YdeucnJnmR>5Ml95#B4laZ&
uEQFtJ tl5DETujecDMFykh!aVwLHDSXkB8FCSWltSJqeM5CptqJML<yPJ$Fhd$YDK#k\J@qKWnhlkM?6ZcI@K6
wV8S1Y ADy6wZ&/b#:&8!l%XqyR:!4k/GeYIG6\/#/qkLKXIwFJ:CXu9wh@6^eIyW5%RiB9QYTqG6bC8EELDnbW
8>pACw +jc*EjpwnThTiPycJby9%iR^cXdZ=>eyHWT&p!TtKL*p6GC/$#XVXljIT=!uW6yy#!4e/!>XNBXT51wj
i&A^jB +AL48@TVQt$?EZWkJV>Rw=hSNyI$>\Ndchm\/y*mReA&4P==lS8dYiD\KS!mPL=<9wiFNmL&5R!Dj5IE
i6$dpb dy=F!<KEE:M%$uZP9DkE:ACJX$^d@nFKV^IeQ#<KeHq9p&5QXtDiWGIjYqwL\?Y\=%>t&GPHQGdD!%@F
jKh8I5 JYM?YhjjC%bV$*=+6EIT6b%cRPpT$a$ZEQY6u>k!j$k\n94TiR$MTyt&Yi&68nG!jnaS!8nkIl1>^j!T
*bTW/Z S!%+y:S*yKbLlwt@&&jmkD=d/4/A=XSyhay4BhmNQ+iQ9iWVRT^@SQS>hwmV%bQ=Il5#\tZ>EPdt4wG:
NAA:=^ HTjkKi>*F9wFnwa#tblW4GhnSdVP+$MLTmti=:y<qmuLw>Sh$n?A$cVZ4Nj96+n+C??Ac@9N:61<GMPR
T6CeDk WSI+$b&ZG@qXj6AnN4WJN9w@Tq@#nh#1P=>Q+/^G1VQ?KF9PMFu#Gt44uX1TpS@\/Gh%k#4I=?=1TmB+
JCD\&S k4RESmWb^QQ4k#m%CRuElkb&N<W6yBn5HJ?bJGCad6yW+%AchXnN594\Ypw>#@@!jM8I:bDWBpkhDkP@
n:Knh= GBk^\#+H&$Jp^%?AYALWqIE==YMZ8/8Fwj:9aQ4WC6KFAHdV$8Ca!tSCPVpP+M>IDaQ9:Luk!Pi!lPJF
ILLH8@ @c#J\X1?iDZw#cVm!AB@jIKI$>wH8DYDY>>pMdyW:CbmJZqF8yWa#eYpm#Tm!H5EN>Zm&ddlhc58h8%l
L/qljd 4nVpp9RkkVea6leEjV4iN59Ik+BZXmctYElV<EJ&*=K1T\&kuE>Gckhy=%SuepEXH@jS/k5VTyD\IF?R
*GjmmX A&#Y4hiIyh^ka$=F51+Vu*Bb#/BjucHPwR145cRjmQlRX1p>E\R9XNG5>kFGZehh&RnF>wSL^&X9$@DZ
4l!#PR S59aEw4d*mc6Zea4mam9ZhawbmmW!B@&Wa49RWAqWDpFQmqdRTZaYMY+GBilhG!%4RIPPD4WH*TyW+qL
+ZFke@ J+NQInikm5T!%R9Nd#4RYBqJAi%YGSH!&qPWJ$PMBeJXqC8V>jGX+!@TLtFGc@p5KpXju9N:Q^S@bw5^
Q&jWbH TIG#Ql/#<AP*EMS&PDY6!ZB%du<6Yme#bcqb91@IZM/ayeynAmK@py4iD=!N$R@&FC5SHR<YMTqEG!1G
>qI!h4 Q^wP=>@R$6+cy&:R6MHB^GKX:mMy%5Ghc5q&$6/?FCV=bCjl#ELPnLAB\qAahXdM$VJVPup!\kw?$$T:
RY@9pI $S8&GJ=wA*Y\IbNc9\Q\#N%Xe^I=pIIYhQqIH:tqkc^bFpCZcwLwYaac4Rky*WicW$acp6XNl&*cb!&&
*+kA1$ 49YT?MQyyCnuJDXhBp:WS+ayG$G8ZkuyX:1Q>>a5E=bkHZF#FGLEpwcQGJdNTadN#u!51kQl%SD=iITa
JaZVP$ ?Jla9Gm1C9&Lnl4bmZkq4aRMci49yiCQKbQ1\+!:B^I&11c<^P!*KjVm&+6MRVa*nmW+=LuF^YY?K9:X
F1uajN $tuu#t%SXtt!bF^T<&>eWabK4J*TKKwZSFyJ=e?CHJmB6u!1M4RwWj9HEbV&D8p=AWn<8d=49I@5ihKJ
$5!/ZR <&m>!V%Jd11H\Q8TBV=Jc>6k#!YkLXRPQ@%NL+8C=VS&/LTy*L$NHT1!TM$*9c+p@bpiida+yZ/8Kjj&
a<SHm% C#c:6^GG^&YplWBDIb%RXu*^4^wtP@AZ4LDFk8%Qem1ldF*i&B:N@d5\\BpnAc:y<IW@T:\4#n5LLBj:
WbpHeQ DX9BIu?E$ui^nuHXQFeS:5lHp4^CY@/NDnHn$DbBm:ni5yl?mpw@&+9w6NEukl8I1FKnpbhPLQb9+p>E
BweKEQ +%=+=#**9tmJG:9!C$4%$+/XbdD:*wmKXiKSKlS<BdH#Qwu&<#/Y$?p/*LbMFPd>FnZ#6pHD*pNnQHXK
?qh@!w 8$>!dX!wh@KVE59&J<BuihZK1h*d\=GY=k+4j^1:%SN:8l&/q!ZLNb#j@dT4u:K?>YXl$?HTRuh51#nd
nEta8Q hW5GFMi\N$Ta&mV&EyFVKVuwJ>kijmyiE*aCKbc5PYN:mQV\Zpn!+5uu9b&9ii?ndT?ukIG@+!p6GYuH
Ttecbm t9t6NENJ@VZP1dn<DGI9IZ6D:$9bWALiV^j&^?@TmmKEcwt\jGMmP/Vma:MI9bbbBZKI@I/t@4n@a6%V
-A8$:Z 00066e1064800110333 Page 88 of binaries1.zip
*1jkD4 +*nJeqkne59=1+kbN!+L?mln:l&B&*&RnBweSI9LMtAy$/4qkwXbRKt9b%PyaKXyDjH*%ZKyWRtVi8@c
#?:?Rl MhX+mNeG5hD#NKhCKRhaX&uy?dIphEhHLF95djyJ/&LGb&4/8DT=/tq9P\F\yqXbGi^bhS#X^Pm=85$H
KZ<Kj= %$CC=y=D?jJIn%Tci$8PqK:NV:4E#dy$Sd</6wctl9yJm<wk>WQD^e%e5i&huX@4MpcTX/h\S1L#Wt/h
eb&L:p N&#&u6b<\w!@jpkC&Iw4tbLNQuqL=QRTRi#cVQXI@=un>@5B6cM9Sj6VZ@DX9HZFEjaVyAu+Y8WEjl5t
iTJ:9c K=kQ>4bHZMw8YT8Ie?6Lu#jXZH%u86wJqJbl^8nKL*SWK5=$5^Jky9n=?8A?Z?:*wyNq@Y/Kh>9kGk*q
#W8CqB pVknQ9V^n>tqS9J1<dBBybwuS^QqL4yY?l5y%Rtqy^1tuDnbcywnwbAHQ^GuYSRqP9EpaTHNh9CXIP/G
$i1VI5 %?!#H&j<c8ReK+5V+:R:dSiB!+I>!RQK&j4M6=@Mp4=dN\/6eXb>c>P/B:CVR>P=jcj#GjpYThed+QkN
yNZ%1h cVIjuy1/eNE4hEu#MiGWSlua/1eL4T9=E9?C4+tB@Fjl?H?w*@@@TMj@iVH@=c^!AZ+w@C<ENlV&#\Id
R+j?cN C9%6kj$Q<@ijuTLpL$R8=J<uq9>CA$Nk9$ML@w1G@\:N@\5NDEH<Bk&D@?1%BZ?DlpJ?>hyC9$H@YpFD
w/=&\E lH<D@/WGl9L@LX4k6#+!wX@RpQ?5wCGR@%yBC\n@B\WN=@<LBR&F@wYCF91#q9?@EZujSj&@I9Ki9/>B
mpC<85 ?YcaZ#$kF6Xb:ECqmK^y1u1K&hJVk*M9:dk6BA6QLSbKp4+KXZckI/n4nYNZybjHT4?q@bie?tlNVNj1
&GPIkP a^:RT<LujJmBl!Jnc5E/#ck*A$lEQ%u&ptCMaq%=S6nk@=m\*lAnFQa9E>bLVR#tFTh/Gn+4pY#Pp\=&
@wy@1F !61#V>d9d>NM1@9wK\FlFQ\j?InTpF*VTul/%JWNkVQphhYYeEeepIH@cFXm959w=J9w%/+l=B>GJcAc
h<d>Pc eY8R15nMHuLk:L%dY4Tbnh4<u@%H8DHPQd<%nyDI\$mlQw>y1KT!l+8/puSD=aM8M&?ieb4/\^@LpJwW
5MXYi\ $V&9^b9$Vi1JlpT>qpXXh?:=Li+%T#qDpp6&e1CaA1+1+n?PXF<lpa#pwl#X@lyNKG!yu4:KC>CLlKek
kY+>88 Hcm*SbRX4tXeqH*%#klCcJG1ap@jmB1K%c?VVw4HNGW>X?V*Wm/LR\q+4S:!t:jZJnp=nBIm#d>#8+19
eJ^\dH <yqVCK>plC^&H?bJZn\QkjGR@qV*d8kWlhi^>\u&/RN?iNRIl#KTE%HDau9e:?mp//R?jSJ1uD^#t^9E
1^$u5I AaGpeRnicIY$#N8#d\?4/#QlNqce>d/tuj>J4B1+?QLBy%Fqn@u:L&AN/6ZGu#Xt9w4\e#:WQkF6yH%?
!GM?iP \qP?JYAe<RP<P*y6@&yDTa:R:@PJd&jBc+acAY<CGuWnB8SG@Ece>QBYiH$e<19SqQ84&K%Wt4Z6!%Hd
\9\qb< IQ^DE4F$Vh^:c+S>PQkjQ4YtBQ9i*&XZSZ%wTIW*$CXlJZnacV/HctSHVC<8iG/%#TbBDkk$Q8YF+l&&
K#$lYE wH^ecPlEyuEJ!Dqy1QI66H!H>MKcyTWbj?yS*DmEkCyti#a*X*S#wuY@wGHXN%kk5YE@QYhRpTkLRdR8
5KTAD: p#tEneTZt@V$<$l+WDV8@a9HMwXuCu8:$YY1\V^\blP6>BCj?Bw?!l8GPLIM4&k*VwGQN//pWdRBFmG#
qL11k% V%n\hQKDQAKmH^Zi#=B&P:+@RTCJ$$Je:Pq98*1bwC/6?l%6QdJw6E\aZ==G&$b^*KkaPbn!bWyVIp&J
Mjj%Z! N4+tQdm/+EDAB@il<ZyCcn\6X8yCLJM84T?E%WEwyje%@\^ZG1AQLQ1<b:$qcmpXQwF@R6Z9>IbC4WnR
uQwc>? wl/T=QWGh?CYTTpi@9^yLi8uL<#e!FKDc&pZ6SGclMMR=JRKm=6LTjmZb+4&yMVp615XSeuE+M%H6jjm
C+w%M/ mtpn9m!\M<!5yWIpZ^PCmJR\P8G1yEMWRjKQw!KF=XX/\@qT!Y&k6k\6=hPI^ne=GY4Xpkl%YWF/K!^X
tQ=QRZ *nLj6?mF4EJtW%?nR\ESZI&\NPMd#>DS:BG%Ip4:Sdlmpcy+Gp%n8ZHJ8iS#6dW=Vdij8YJqE<yJ6&@b
beRI@# %LcNQ@pJ1nKMnM=V@a^Sn@Vt/$TXMaW/1cc<QYB*?JGhE!k=?IkR@wc4jKJIkhb15liPhMMd%jbBb!dj
4>8P6c TkJKj*Vp9mZDmL>NeEC%ncRn?:db:1eFT>5$LlW<JFjQ4NC?=ynkdc:L4@ChN=K@G>b1KFJh:\1*k!Ic
lC@qSE t:6lXpe<HjG!Q\dW6dJu$l=jqe%yDR^9CDwyk4yB^/M@8CtZ*qiPil4%wWhLi6Fdin<E5@MbmZVMq5iZ
LQGcH$ 8Ee64%cqm!<AXu4=pDA&M$b8cp#Q=bhZW9NL&WGTl9e@STL$>mbh$1@cRAyq<A!8+&<eDF&jhKYKLatm
jA%L*5 M/kLL?hZTL9leM#!a8%!q@W^M9lZT#u1ZyaZ%YVJWNpDEB8X%V^X<ybuBB&^Hwb%5CH6Q5@&1:tSYtQl
iKq<j5 @B>H?bcpmawA?l\FI/:cC:5H<!HyB\1tcVGu4QWmT\cjYN\Ca/NeZ=bhECd^=>?+ETl\>hh65L+N:qWV
u+DhM8 C+N<YEau&KIiQTcFnDN=Ak:S8dL\*cMHXZ:HJ8iSypbdM!LduJ5YC9=8k&Q6lNbSu>JVWbE9h=5dl6p?
TlH+dl =L1L#JhSXTIj%=V+TcSbtw&JF<1GFP+!pqVyJ=@u$hLj%ZZYDIA^P=&i%96@XeN/$$m/=YYMpAp9GKQ$
C4:bbX CXkhE>y%T6yC<*kYD%4L<dl>R>PStZH<bBnpX!W^/^9L#DBpb6^c:heS1@kEDFGmdC5nL1m@RFYej^5i
NwjH<& tAB6W@nMC4DVnyS:N#ZWnWj#YA!tlMAVTN9q$WepCF+Kk85nMqpe#I1Zm>JDPb%=YnbHTYuWLAR:I/dP
\5LXK+ >5j*F*S@TkR8%dy*S^LlTl5yj:I$wHC\itXeFHlAqj&ye1MMLCaKYF?=GZLhhJKAQXdIA4bkBqt%Qk>h
#=8nFa @Gyq5qXw+5Nd<1P8=Y#K<FXK\yMZR/6PpVS$ZNbBNcn+^QJ$CkcWXX4^JEeHB*HL+c!apc9Q/HWKee8u
l15FK% n?:yd5K5Il/:6qj6RbCu88a6*!9y*9IL4uMyb@TWH6^4>b^:e6pyA@A@Yutk>%YuHYV>LibwRHHB<?SJ
RN/5R+ Qb*RS@Fe5Yyu$K9?CjX9>%w$ADK^9DQ6*/nTZn=bTdk/<^:RQp^e=H=/19VtI%D?Dnn<VkVB&\S9eW6t
^S/GCJ /cYp=jXV>u/K=j\RmJab:dS/I*#Vht%Nu9!HKWqC9pL\n#MkTSZ+jiTqyecQt=b:9Dwn^y*G\uXYN:u?
J4#w#C MyTJ5J$4aN?BuhWS4CM+4DIEAiVHt+plB&CaDEc8S?NK>l+4Sw<!yGIdNK<=tbuw8RJuZEi!bqS5iJ*d
SnjE^h QliJ:lWR4Aed8BQF*BIhE9HRZ:B56t>9Iyt*idQZll$S5bX1<6k8/?\*%%8ujTQ5L8WMp!1Za<S8pNGS
aa:Y8G ciJ\RI?P4cQ+JA?@S=HN1MJZQIb5icqM8W%@Y:+YX?/:hh/?wPPShwbqj:+HSlLGPLGM%=#LV/Q9#mKP
VcdwZ4 8<cA!X9dIJPya#cCeyiJ/AL?JbaiHadq5*GSE=My%TlYZw6$91nn%%WMc9pS:/&JmjnQ#@l*V*NQT=Cd
iB^pnk \WWYL6pPHZbbb8BQwB=LM5qhGW8CIm\nw<441*84KqYKnhJDySa=FPQA%%8eK&n!G\A1tDh4N\#5KV&R
WEL?lb 11C*c?@Le?IECDLc5*qQ$p??A*=FDWbqKM6H+8:dnhtw8^c*!\Fhh$/>IyWQa8jy^6A8LQ+^B\\HMe1i
6nK$eI dNK:Jq*kWLM6a9FA>yu55H6&t/+aQZ+e%W*IMbPG5lante%h%@WhR8SiMh4<6P>D:$lTXeSQ9nlZb9>9
cR4WbC hqEhIhnjN4CHReVuiHa@yWYXphk1a#&JB^ke*SMhZV:w*LcuEiL6:BE!b!*\ImuCd4*p@InQjcjKVASQ
$88Bhk WVyK&<1id1@buC=qn4q*Yj4W8TpHHK#+HWZ!Ak>hiAQ>ICpL&R:98@ZWbYEPMaG6uEd&i\$4AptYW/Z6
6YaD%p <pc8*R6Jl%c/RK64FRJ:TDjZYMNnuLmBIIAK$T!u&$m6:eDch6\dmE?$t66/$AK@mT+@MyDHdY!lMwl6
&Te%e/ =DWHyMM8&plbdk!9*?ih@C=Vwi?:KR%tTj>klt%@Y&I=!Z&9#RTP4mhmC9i5!@C<uaP%A$dbXW^tI5B5
5BRYJD b4/M*ZMdnGE=$\miWYYq!P6a1b@?&?m\Q9wq%q\b?TlkhyhL1Y\p/*4e9RPeWB8>unDq$IGZ&=B?C#>t
\\KWjG ^:t%i:hymcLKVM4mBaV\dXd>WQ+%t!Rt!$4WEST5BFGPha1X%9PHLnkik66&hbJQ1X%=MHkLt9V:dW!h
S/6!?9 R5CFJ<<4lwt/RnFpM<%q*\8V!Xwu8qnda%6Q1Zqdck#tRdT*$9&^^JNN8tTt+9#bT?*+Q@AW*i6p+i<k
nQ\4Pm *9R9H#puJtnj^wnbV9hliRC%IX:lMaGZi?AW<945N^u%6*Yi#+LaKqianC!5$uW5@X66l8yJ*6HY9bVb
+XVL!y =*!SP/aejJ9Je5J:NC5hP6hShCIn5HcPM&Rt8R6PCqja\uqp/jaq=MWDAZ@\=D4ahaMt?D8PRI<4tL@A
cyIAqq 1c=@4PBBhZ=>uMqnLCPh/ZP9yG5enNtH&=XP41HWJMFP4u%i<R%j?ub9bWl\A1\!wtyyYhM5l+XeeVWb
uEX<8C Rtiy6yZW4al@mubVZ=alA=DG5qkQGQy&4d9yiB&kTR9wW*1qkE4X++l4lY*R&5qVS<a1\KYHPWSqNm^k
WnnH1p F!M+!cS+@EL>*4d8tJbicI^/8bFdZ*wpdl1:lRE@@^/y:JSKPc9KGLFGItePI#hVeJLtBe#dh4&haW&6
4N\jE@ WL:QhqChnDYH#A=VwqLI#FNRZTea*lLFutXJVFw>eMGnYanMjm9M#eEM/QMJeIP9=j@l\PqGuqBMtwQB
tLpS4= PYC=BTPw@M1q^V?yLm8iQ+CLhTGi1Cq?5IJbLE+awG1cj$ekFYTBR$AawCd6+9B?e#&$R&<$i&k?VG85
4&=Bwi =+>:&H<RTJ&Rd8Dmu>l<+<QYe=K9Cj8GC!1Yt1np6+pEI=>a<MRbIbqni*/?Ju5E^8IH596NIS?dH6ce
6p<Ln$ <HYddk$hPChnk*DAI>9Ak4=cAT?qkG/d8Hne/9$wTYj<k6%NQp<B^NVe!WjdqP%JJkpeqtVi/#aweCAT
4$A^n= JPHpniNp!<ZG*tctat^ZJ6wL1NqEe8Ew*qS?Jd:bQLNnL*6\c8<W%+tNMi!IE=k$6@@H@IPmA>==><<5
6MJ*p8 wcPQBbue9SZhKN^+bmD6LN%Tq*yRCeB/CP!nNae>C$EAiaEm8ciE^aFEcC=!:86L*mqL*K#4pF\#6%wy
pa#DQH \iLZ<\W!!t?pNuh4^jhjkCJ^4eF?B?G5$\!^?J:?t1!^PKl6h1N#*GTeeH5qKeB&\$QyuZb>y&9>D15G
1ZcduQ knth8eHZuBjPCH&Y@AXhXXI=%:C>+5#I5ZV+*6=>\W$nqnq:@9ZVIDS9RbS!EMGeI99:&HK4PE*@LeIR
T&Q=#G #wb&d$?<$LYI!I@k?jWaW8^JYVII5Rwi65FacK8WpuDk5Kl@d*CVT=*&cSNk*DKWRT>DKIuH$u@*1>/J
+iL@D5 kFG$X=eF>jN\D&M*ZKAFA8yn9l*M&^dK&4G=Je/966>&5:\6Sj%#e1ujl<LYTWqnaQlF**Tw>LKVJ$lq
b8:/Jh I54=#H@*GA$1M4mqaD?I@!kYju5hl9Z\/9u>wVP1e&CwnI#18dV<8RI$Abt9ElnM$>Fn9>@BC1!V9u4m
-AJQ%S 0009a58a05200110333 Page 89 of binaries1.zip
9Se>:w V85Zw&BHKhSZ4uQucwp^\6\@\KMi8S%Hj91S4<C5@*1ASG%cWd=S^1c^ZB<DcM<&6^SjAH:b$jecB@W>
\DljaC >9KQQB*DEjd9\9H<wNwWGm5ky$F>5#Y>5F>H+hHdLZmGk/FJpXdX6RdcT$idW:/h1&8lANHM>bGNMIMh
%CC?RZ T@BF4#<?&$N*Ie1:Ic9kSl>:\Y>PYHyDClGN&>I<*@bd5nhd**:Fm>9NGDA\NH?8&*P*T%SbM%yncJ?9
n>&hY6 ZGwHP4BSKiS:XScL>Eq4dCGaqlEy5*?laFQLSVSqTtn>=MDe@h#X8^6h%9G=kFDL:abF1XmCwZCHJ8yB
?*9Y%$ DGCaBqY6nQ8\qHlL+%mN=&#BF>D=AQ:5jhAFQ*tG%6wi&&Rp\=Xwi@Ci?uE%HePSlmhPuKieA<pwNWuq
cq4hM^ *Wnw\^%Y=>A6yPd#J<=1$YnkPmptNiF%p>q+Cwp@/HdnQkZYI:PlVX\T%eNi6h%cWYCl<8V*!1XBbW<Y
T5mZuQ Xac>!qu5YttIZ=Ck8<l*#hnJ%&uKC#WVZVacT#1MKiBM%?M<JIY8/q=K%E%he@y&iI8EMJ%lyVBH&b>6
!B$RIW S9Fy%A=*h5nYp:I^V^tDHd1u>j&cmYYLXAt$k@WtC/+h@jZ&!iNSW9%Vy\*kjwIpNh&*taQ64y8*$LpZ
+\$<WN P5+@%B\\9BL+pI/#b5TaiPpBj@T8q<lctw%k<+:*@L\!J9#c<KIR&\Gn5FM:<&N?>p*=T\^m$lR*CLLu
6=pmi& 4Fuby>:D::9m!>4cT/uWWM8SDJ8=H?=#&^MyIwbiWY4Nn*4/b+YSBN6j>ZGy^JMQ$9SH>D%dkEYCy6+t
cjRBZL X9G!*:^Tk*wJ6iP4lu8RHCqpW/bcnVm>kVQ<<Z*e:VmWN9L*^yAFq?y+Q%>yNe\\4JYhQy5WhBw%iGPd
WYh#\Q <6b=ht!tRS?a9$nETpaykHVkZ/H5D!6G#^KNnF\/M=ERMa%tu%<MP1t8#=L&byXLGk+^:/GLLjBd<#Eq
XtP+9H jluLl5L?@<l^R?F@:dnh@@!Vk1&F?*?Wnu@?NPIjB*DwQ\+R<H<eCAu<&+H\Q\/E@@FZAyB@PHIBAjk@
!C/Y:\ iAGlj^<B\!jl:Qt9J9*@584Rj>96<@>?yan@yw&HR@:b^5MFj69G@$PC@yNi@R54@a?*=#jm=FCl*/F@
y?Wuut FTiHC9<GDj@Xc<Q+j+iG@5Ku\\S?l@:X*Bwa=DhwtNC9cPl9$FDI4*=9&P@R@L?m+d>BR?C@i6eR9$H@
Pbe/u@ ilWC>n9F>56%BNn9FB6e+BiDe&C@W&^R&C>iG<:@u%elwIn@ilZm*:L9@:wKkjm4ID^e+K?C<MLC@!eI
$QQV=b @#<>CN@#9*Be>1NTYb11CXk6#<h!VqHcadFMdE:SCLj5H^AXAlL5W5^Y^Nkd^i@mp/m#6S%KFTd14yt/
wh9WiD N*tK\qF=%AhQBI<TFWXpKln5ywEcp1J#WZq+jbQ!Kkq/4SXl/=I@5Mp9aNTw@X5*PwDdlCY%1J&n/BBp
u+8Cc5 d+SPJIT+kH=c=t^aeq1th8S/EaWy1cwtb/wWJM1JS8<\IJJ+mEYcKJq%>1Y$LH^t8S>JMT:4Rahj$p?N
bLun=G by=Q\mJi8qGPM+FwcRDiCtw6IXT9ktmcP$YQb\WimY+LN5\^DG*n<EBj81Ec!5m*Gm+G94l^yZ^+bc@u
t/Vaa# &B914WMX\?Z=TSAWJ6VkYEAW8C+\i@iyIep^uHGnW=qkVb&j$/C1Yt!wuBM9!y:@w=dD#h4MCp@T?Wcn
XQ\dMJ G/uSKlEw$#%H$>FtbLH8m?JFqtAK@HJY8nHQY\+FYu=655VV>+1\Wc5TBitJbnD=I8JF/F8/:*5@Ncey
1hL?S^ 6ZkM5tkc^W%qF>*4$C5n\LIG&XXcGK=e@w4/tG&HAA>4%m&lpWJkp1\nNE:bCSucSmSQ*@>kLQMeYte\
l8<tJP NnJ*LDAcG8+wJMQ/!c$B:F%p&?Rj19maZdTa\1w#+pRE8yEuScm1d@iK!Q5dtdi9IFb=#M4!t?Sc&Z=E
@1+8mk pNZK\F$=>$^hN!l*yd>mRhhQ?6q!m9BNnw$/je\DEGwq?mYwKLDy6DGF@PYq%>PdRTH!N^/jZ*h$WYh%
F8=yB^ 1!Jb/<YjFlYm+#?NKk:!*Atl:b\?9YkCXtE@jeyK8@R=d<$Ww>:y94jh9Zi6#XbPb+/Q5RJKq?!VESFT
Ab9\FZ #kl1bdV1@1q@@4euZZ*e<ty/:CFE>WMbRa+EYQk%waRj/L9=ddIpjBPSTkl/i4euBLS/L<Jp6^q=6J4m
XjMJEw KQF:dM+W6*I/4P\qZm4AI8961:C6$BwmqPH!wEhpt/upbpFwb\KeJ!G\TKI$&pNJ%ZA96qR@l=p<W%*H
?lZ5E> E4\et:1IQN5t6jF/H<V=K/KaS&X/?<KEE8c?\/aEPGLKS:mCE6KhEwFnCn\IChyC:16PiWyDi!TWR&9j
4!kc/e \XKSBac1t<t^AlldIK*DID$d4c\EW!Sq5&:DWwGN%HkPM@V9eVAc#MRcCD/\*A*+KFW@#JDL+hlm@QMH
6<GVp$ FFjKlTN1:p?Z\kdi?CmW9ESIVJnK1n9ynL+ab<1\PICNRNTCtAQ6M5#>hY6R:p%wp:BCNjyRZFLF^$Ge
J1+B<B qy&Bd6dePyRjEw8EX55JBR9jmtLB*F4YjNnBjcZM161=H1Phw$caW@yNVIY#8%@15wA$b5*1T6RF>@qN
ttjJ>i K4/pJDQJB8c@!LC15cWYl>GVWBQm/RkI#aWMHkLVE&WB1HWFYS%utT%JCSF:PL1y:nGBNWnTyP?L4?!6
ZB^W1# *pWc6$5C#:PTi1GXB&J%@iXH1Ay&?ZjW!Il&\Xw9YF/^KlY=GapkbtqL1Em!?9$R>#eptBiBEde#iRQR
^eVcik bEWN\YLQIdRT8W4eyiP\X1ked5I:lBZP%h9yinP4a4*8VK9wa\*!%*^VuMJymyY&#H$cmR8Hm9DmHNHm
Lnd!&A &5I8Kk5/SGVdZL<kKn1GpFE:JZ$?n#uYb4p8*9Y/jTBDN5Sl6CXT5J^!Wl@Qh+ENNI+DhKNu>>H46HCB
wYVt%> JXF?IH:m5^VnqItHW!5qm6d/IiD<%Bk\jy?BKX*TmYe#$VCK+tZ4a*P9JG!XcpkZY^&V4YySnckkIY>k
9qub1B c+K??PnBe=6lA4IcjdQanY5THNC*J&5BVnGut+4/cZd*temed8<HAiHw9tStkPm?K/iCLm:LK#PyC9PC
\dYp== B^R>5mYip*b\+6L%p*nXS1wKGSa9p6E9Hy$wQ4X<LaiVQtSPbLWJCu=Vn?:<PHV+pMFed<Q6kKqCy>:R
!pTK6K h8aJY#^6^A8d^k1:6XudMPXHViBE/l4/y1TR%FbeTdCuuZID5NNqmn/Qk*KPuTJyGnItE=?5nm@>PHQj
L4!^Xl #E*a%kP#\d4Yulq=dYlC9J+8h88kRlCmWCR4^KuE4Sq#ntTj>DtS@hIEN&CmcZ&ut!hW#8:VTnJtPM6y
iA/dHm nQ?q\n:Fbe=:@K9iIDM&V*dl@6#WRm$@a\Z@FwJZXT<DC4QTu*&cm5E^ynel5Q>B4RQttt%YJDh$#QKq
DWVIZh TC%hp:jQpb5q&!YX+y:^!q=\byCwk%G!d1SA+XMElecK&F+9RZB/5wewp\&ht6%1%aB$1LBYWPd%MVBw
pYm*V! c%Vy8A5tB=\CcEmC%Aw=W>9^ISYYA#R/DIXntSN8=JPX8wPQD8RePGDc1mMW%<*L#E=4ulk&41i$n5u:
XwDIeH c%a#1IdId9$hw+BhY*5ba$w^NI1GH1TFb\dMTRb#SkJZLB8F>SXNq9p<m=&%HtibDY=hIMa/9jciwtVB
i$9Q5J 9j%DD?w&MpN=qwkPwMKydD*q\*^5Di/1$+N@DFHp%Alc*\?edPTmJle4EjSTqji+W?yWwk^A*FJlmk^&
hmp8D! dichl<WKStwLG&KK#H&X/BtYR%ey$X/W4wj69B%$NdSS*d=L&Vw#wMYYRAXucWXI1n:RYSIpe/G=i>S&
4/!lKe jTSweaEw&u8Ab4?l@QB<kB$&6h+thDteYa4YiHue^BtKmKwlGp\uHu9EXBSphVI55y%@*^e4cEn4lnd9
cVyqc$ uRLbkkZcT$yLuJ5!E5!&SZS#k4uka>6%aW98C1=#QNn%6FaDq6%t<5b=FQd<nPtVM?q^:ejDKRI:<E&=
mLIG$w E8MhSdJ@\EHHDe=6>c$JE>pJky\Aa\+?!6t8P*m89a^jm#G<5HP@q\K%8B<E^%A/S4WMKBd&SbuX<A5b
WDY!FD <6R6XkT?B!e=Sm59H1dQn591Bby=Ae%5edtBDl/LWVXnnuy#cI?q1JbhM+SPSWQ9kN8uma:G\WP6<kJ<
CQAEZ! Hu<9aE&@/GiRFaMuV>d+CJ!R6jmQpPJ<?buWR+>?AEHwEjWk6pc*yP#wEApku:+t4Gb4W+mF!P=4NVqe
EH?BEJ Kk\MYC@A:>w6P%T4NLLH<VEKW9TXHuE6C\S&nIB+R:EmDJIKWSJBi1+&YZw5/ijn/IbBcYBBHI1ERd\u
iMq:hm jb+Flal&e4PuV\<@4hqlw!\9VLJtLleIqIpZR9i!>ujMAdQQHe<5#tQXpl!h5iKG55C$y@cE^C+YuiMa
%=#cJ$ $LYqd1pWS>T?uEZMH#5t<j*eD5Z=R/yDdR=hS1A5m\u@m=LDePJPjJ/$/6JANZ8*l8B\w6F$=EF?<ESa
tW@#GJ uwV$iJBLD#i54NK*jLkEY>GnY?qiq<5A9BLQBP$*T<IAG:+6T\Cm#tuja><Pt>8CHQERFS+Jb?%Fki4$
59eLSe *BaN*FdjAWqj\qqN<!QkBiAC*MNtY*K\/^C<:DaeJ%i<d!m?SBFq6iAbm5M8?abcJTtF!djVJ8wqi/c4
yj=%Wa %GtuY&/R8bcSY!5ZA:J^IGW6tL8GJVBMWR@Ja\EP?<TyaQM1tQGt\9Kl=cpcwhGFbcA6wapScaTeY!\^
t*@%i> P#&c1L\Y%^HkyCkYJk5tek8!I9?lAnadqphC=k#5nW=XdK:hEu4Qtp!KT55J>Ica9Q1eQFV+6Gtp56V5
DY+#R5 IJe!Gmy<Q5&PR#?I+HAbdQQke*A6Q=nMcD<!IpnF#+F\ljem+Dw&FJPQYCj<#@elAyGw<@4EGpwWBF%#
D$pw/b cCQTp*dFT:V#$\4:YTQ@M#\tCRqSaFMk@ndh$WyE\tj8FCnhBTw>i<4b5BAuBLDV1GbJmw!jG8uu@MVB
i9>4hD *MG6F#$%wMKL>!Ie<*F@eIuqbR&VZtRphpVlMHn+TNV>GeBbJ!+/IRSAI:cdBhw6BX$eS^WEl9Ye^$iN
/JGFS8 TnAeS\:#DpKB\RSA/CE^\Hp%bZ4?pZ%K@kBDCVh=EM6?J+cNSSJiG%6CC8j!D5+y9Nml9=^!&BdQID?1
y\#&tP PyL>6b1jQ#uAM*GYLw4\/TCSSBq&tc\uD?eRY5N9^EuL8iTMA>5LLj6FARcI5<GPXRAa&hXJ:KJDPWmL
/E%\=T JX:V=:t5pIG6^yS#uFjlXi8Cwjka+AR=khpucC4GmCHu*mBMAZ1ni1!u+*iqMj5Z=XEIt=u!!9i1hpN:
+tW&*h BK$+@BDply+dIN9RaZ<6q6PVR@!AtE=>#GkQ<JE!%JTDZ>tXLN?Vk6QGiemqc6>C$<G>mA5QAP:kHFBl
+RyhV? j1q<1damYep+84!K@WHZebhyR%+^j$!JmX:JdEkyu^m!ReE1WY/EFXAYHQ^cnjXDpFiaS9b!:ZNGyuDw
F*^k%Z :F^+<ql9&RLd%PqA^^m+lL=c1nRFNE^9d/S4t=5#eX6iW5cF$q6QVunm^K<BStmEKPqlPGqK/TnlGG\G
WamY+: >iVei=bnhR$aVDnjhHEy%q6Dp*F94?hdun&W/%JnZVG9DEZ5JRqSQwM:E#l\$b6pL?\Z=44bDqLkjLGp
9AbeWA GAIFVHWM<by!iW\yy!#LC8GAByLM!&FBP4C%=V?GMDJb+kRJEQqnBH8dF^TwhB*YjWSwBpci4XY*:@G%
6!*JHZ mC&G9YZWk8P8m+t#/*$9?R@1eYkYEk9*!iiIB9HNYJEN@nw<PW5m6SCXbKQ8Rnc4uqa?:t6w<jZRpBM#
tquyHa n<8F1Wlw?SpXS4/w&%Ya!+9cthGAcY88QSiea>k<8!B&8pu&kTXBqjWaClh*\eThwGA$+dZmRtdM+V#H
-A:Fka 0005f0bf20800110333 Page 90 of binaries1.zip
Kt8lP\ cR#umXe?<p8qwcN6Wu^jVWFFLAiD8**EEEI!CnSQ+%L+SInK%A&@K<d1$CT:S5R>J8>M^Rp@R5a<%qqP
G!J9F/ TA8%8y*It<Ke#nbideZhC<E@dBlbkKt8Vl#aPXc^CEeGb5uX9P86F8M\&+uT16?4wn1nDykj/>q9Z^&i
>%iijl ?XIT+>aLN5CJM=nH41uX^ICdP?=FYYm9L&F#h^LElSAp\caTQtAMiS=RS6tcLH\FbKmK9h14BG1*Z#jK
j$FPWY wp5G+qKdH:N/Y5tbwRbKI!N6BHFHJXp=$S4S$laJd!?*RbeN\ncqaI>V!!GuGT:SI9QuWlh4hy#I1?*8
@5ZHa& IECBw=VCp?=WbR<?$am/NKpccbpuk#QPwEdAq>^tSSS6bNK5GQq8tWbd^$IN?yIDtjIkB4wX^yS!9uD<
C\8Wi^ 4bG<\1w!M8&nm&%8>EJLjt&kceq5QE/pBItYi!>qbQLNq?EP6Mc&4EbViN$nKT:ambZFTh/#Pd#9jI&u
EVnX=R wiV6WX6Hp4&ZKET#5n&P9Kl1EQuH5D4B5GIj9aR$A+K/N#My#98L=kZ6*&&V*tp+^&p>Fth!ni+6+4F4
&nVPF% m>p/#Ec5!t^+XVa=hQt+IDb=JHZ!Q&w\j>Aw4J!/nk#:pu/Ab*Q=RZ/aMNXD:j8kIK8PFpJtM@Nd&Gka
=mIQ%8 >\V?Ynwd#/9kFF9Akq!+iAKVQkPJbjDi$X5&E!DjD#pPq^VppKPhpkN*i<a5Zq#w8@i&TR=^B:tD%m<=
Z9+j6L Di$Sn:Q\5yNLMl!5Pm=EBIMHc#^DL^GSjkB5N*!1EmX46q#F6/Va:kZ!:dP!=&/?w4KK!>B9h&w6&A=1
>#eyyq \6q:TpH&yybH^#e*My^&l9pN#k<y^$9CM\&&ej#Dh#M+^pXW1*u#=HJ61@Ny=h:eqlW:aQGml&!WMM9V
jlethR 1+NdMN^C*/uMdS4WB:RR$BYR9CcbGC:jR@e*Cij6td*ZePF5bJ:ILZMd*Mt?jeX!#eM1PkFCXCMwJ&Aq
Z@=Km9 qnBZYT<MI*$/bluXXS%E6p:=>#R<&N#%e=&W+C?eim=>?Yy&$&>QEwSCm8P:FN>Rj1y4XZh1>Fp4wlK^
tn1EiB \eEnjl9e<Mw^PLETEh4$Wk<8RFcHPG4TM8T&SP9AFdNiQuK<?hb\eBq&a5ldWFK:i\/wtd9XEpEM/L>M
nnk^5c daH8*k9C*dG\w*ac*k$BwAWBKRp!1\:+\Ni+e:bFNS&CG941L/RBTV=Ct^>Tjt1pS@\S?$TRqhc@RFc<
DGMThb L$W&jAC\nj%#L<I#*4X6@+EMY\:da=?GbN:A+:q*MwG9<aN^<SN6NmN$u4C9>YDM!m\Z5>P=PFi*E!ku
:tuPBM +>KBmmJiALlj/=m#1nh+JLcEjwQW!+5q^hGJDwIn/lB&C6?NDMIVhNFTck\>%8M5R9KXlV<M!6um:VLH
wR+<CV InTj>ZGY!e%WFl6u?CV<PnIQl@#9ujICl@+*9V#mL%L!mN>Q!TQ?PmWQ@\9L?+@Xm9?ap9?Fy+ZDj+j?
@=YiWI qh&GI*/Dl9@KMMMFj+PG\u<^JAa8>D9$L/>e?Dhw!K?<QIL@N?lj&&&E\G@kMPFj?GuEQ?Ze+hD@&nD@
IHka&R Y:V>Z\&#wNBjGGdEZ?ZeESDl@<@p*M*?Z=B#^&HD@^>BhMw+liJ@CcLuqA4S<A^8<yaZn=/*NW11Mk+^
\9ZiA# w^WZh5p4NmSQP>E=WRdNVJ&me=*<=9tZk#lpl\dCXVq=kBHWEi$pW/%aMXIAl/6el:InS>KFy6d%QJ$e
P?!BwJ iwpiyct+im\@11:iT!YFR/FJy1*i1eVa#t6cS1ED198PEI+JAqwT%FKkXcX=QV!6qRGE/6mN<?VSJlQ>
kJL+9V !bq*a#\dIB%!hYhLa#&>BENm@4EV5=<DW<P>+jS1CIu1b%1yupu%p/TT4&XnD1hY?*k&ptuebWl4KyQd
tZVWPy J+4h4mMCtaacte=wB%yX^AbWGhAchh?6^1/XCy:wNu4$l>i1i8k1%!YZAjm4pmT$H%dejMl5SuuWZTuL
6W:H!N El1^JKG>l/dcAEI4\qRG=Y1LK4J9w&NVadAa^@CawMwZ5qF=cRd61Ac:eiW>S/PZc5c/L*j$F4qiaqY5
:qBTI$ ^>hu9PN6iXWSbiQc%^&u&#KKJLitC#^1jE^1^KITk6W%Gc=<R$#PmcPna^/54FB@TG6Dk/j/hyL<y>:A
h>/Jnn =:KD/9+c+ej\A9jH?cj#P>wKeK9^P9a>i9k6n#@=biKC1y$V6F9REbqZAbXVw5Q&H/&>?Fpm?$u@=V*K
FcwG1/ kc@=S@&RJHSZ^%itdF*yKXk9$!jiy8H1#<kull\LE+<:4FymZpub$/y=QcZ4P@>cG/1\5H1q%duyN<$&
/QQamC GWJTdunGq$tFX/q$eK?ui=Y\YS$+YRuFGT5m4=*VXhHydMbq4Z$IGiT*d^d9wF#E#PlAGN8>1+Ze&/+%
Id^^mb &VDYR8yc%plI#mTanTyH8I#tm>wXBKXj<>8F4>C8IW?u8B>+<\WQXE:#Z5#Jm@JX>l1WtDRBw^$pk16J
X5/@eN :LyDGPqGe9^bmc@y<u9SBI#CC>I&#Vdh^d#&ymXXKMY&/!jFDh9p/+9l<yk&qCGuNqG=y*K<<B!^5GK>
!F5uHq #>MlE6nl*S<9=ThZ*NG/R#l8V&Xecw*h4@\1p?i4?@t#VhRZ9GQRa>^JBye=bTh?a$dWdj%/Vb*!Ic@B
iS9NXk Pm$6FPW=FuqRiPWa5qe:k+WbY1ej?XTu*HKt%nIJya$#Y=LiDcAkFPj\W4QwE6u!JXD!@eP%=w6y?dV!
#Y5q!w <cb/e#\1=Q*A%%mY>?bIBGwl?HuV#@5#\lq?<ln$:LyhC=llRtd1uPwDm/Xud:GLZ$FW:\j=nGL9tK?@
REGZhD aHXVy1EE>:DTdwcYdJ5&:E&LdGjGbJHGEDWZ&llcjnJ\P\FS!Xwj*t#TiwWB4=nGNduyJQBV%G9MkyT#
RD1!eu pi&G\*H<:qEDa:wXIl^\>qTCi!@at^8T6<?hu:ui%BSdG*#N8WnWP$CJNSeGHKWq:QPeY8d\YqPcdPhi
hl:n/M 1bb%&qhJEc4Qq5b4!d>Dc1a=NY9W146IWVeu5FY1WG8<Xw+AWCpte>cZCuGaKeV4eG1%:c<q5>qZm451
4h<lB= YLWmGR&TDc?/<BaE$#=1lymk*$V^X$^>wyl=Kw%Y+MS+Z+KJuP=c6#lCND?PTFti/jSE+/<Mqe9HXS?1
a@/Z81 HdwQdjb1SnIPpLl+%Zt&6$6wB<Sa8w9#ZL>#lHA/he^<PYB*aK#:PBZYujjhZC%e:H/#bmYNEi$:e?+4
lZW$+e @djpBk$yVDVTq\+*=bwJFZaiuVyqeE1qA8Hu^%FNN8+Ju16MBQt1yi@AXEup<N#k=wM8\jhDP9X>ZL&&
EtKaNE FHy!c1wF89W+<b:MFV?D6n/<+>FjdTC5?KE?#Nlw$9VE=DTl/S&uQ5nRK#TAVjIQH^dk#AmKDiXW:>5S
hI:CkH hWbq<4$?tJdqw+94@n5l%AQ/ZRYhdIS4*WibZn=ZB9a$jHH*Kd$hL65<lqBPS:9Y^iX$i8\pPT4kGQjm
IL%@uV PBQ@p#@m\+uSinWHMSb*^cp$@QSeh^*#tVQC!keICRXj@6dC^MyljncP<Y@aN%t%#V$tY+?6>wB=hPcy
:pQb#P PiF=At4j1PtV?+J%19G@DX&qY?aNE\Kw:9i5Z^*PG5Q&Py1jMhI8*+6Z<I&c%up!$Zw\uyBZW8ZX=:Vh
Ie^PKb YpSD+iS*/bdY$XW!XK>@Xcdj4CV\SI<>+CYNpE8:QjYV6T8Mu5KelR>Tw:H4IQ*T!?HbN4FW!TDDk8I=
%pYP*V ?Fp<1V1BPW/\lbZHl\YMdDdhNIJ++%d@WnpJayMdF*<Vnmw?Y8tuSRR?JXkN#/4GTZW49LTAI:R%^mt?
SDjLAI Wmbe6CcFHlwq<kt>kNN?\:j*EXYI!<pFkk46Ck*DDX=>@hV<5+C^99u+K%Yya@a+ku9NL>B9ymPZK1Sa
<p##WB b^4y/6P68nTW?Z1=6?T1DtlimM+dWD9GB/w>pXJ#hbj+<HBQyBpuBjQmjyFQAkNmS!9mnQ4BW<L:j4!1
ZHX8<@ n@ciiG#t=Iw%QMBy4DjwaZG:A:aI5d>+Mw@KpLYcnFAQYyRyF+\YCHL<cN=iKwnDVm*pShMt:>n*5dEB
a$lF&T 6EXBptJ<IJa9/BDu6LnTX41*WqY</V>86#KtDu&ql=X:5PGjEPDp&#E:ITWV>NJZ$1>9<k>/YXwKMXe+
$6wHaD Tdt/K=C$J6PZ*6Jt!yCnJ<ZD5j:KR5Q4$\XYt!jYKkQuG#+/lZLc!l9#P+4%d&/cw1k$waIG98kRqw\9
i=b%99 1TeEYTuP/S&P#w&KCP&Nu!1hX8CCW9kkk+Yq6i@6/*hY*<b:V^iyVKVtbd19JLM96>BXFYp1J#&ucI!5
16b&pN kuIeeNPJ<5\yb=>JbLDJmeh11hiiQc@WtMQP5h6cnEGyuZI%q+%h#MmmdPWZi&WhA1T^E&XSu+d**w%b
*5Sc9j 4+%$1hbP#LN1bZbRARMP1AeRbJRGut5wMNpy9hRJYK$:Dq51k@$ab8$t<NjyD\Za?Bq$dAN=KdZAabat
Ym#K8$ ht1<qQYm/<=da&bTywRPFlp>wkAME<DSeRCDqbt5!!YkHauZ@pNq@elTEEn<AhNyL49dcKpm=ekbyZh+
4b6*Vn Hw$nanT^1i8$8:qhB*Z^W89Je8QhBE6d&a^e6@c%G!G*#bB4J$=D9AP=9k=1a+Dna?R*+4+QaF:S<A%a
&&>//A 9j%DwyP9SMym8NHnaFWVdeIHe&XL^%mQ!c9FA?JF*8EuEk5apy54&=?^kqZ9VSHbFLF@A^F#9\lulXw:
^=94MB 1BhKh/PK#c9XbIC?t<iBQ?\\>Db9WVm$WE6qM>Zeq:HZjCWSL99MQ/L\=k>1KXnA@y9Y6D*?FkVQZ9cL
cXScT> =nQ9h:lacXy!/&hdp8HakLaCwjIJu#eE1S$%+u9=#XRL>Zy=cIaJAEEIdTD=a#^>ByMVEmipCk:VA^c:
ZGlT:: L6dm1HG%%Ru8>ZP<X5DW=%%YQeeSJMEy&8+IJ!/Ha9$Aq$6n#eX6N%Inp5EC15mJhnJt/T%nBTd=qmqH
a^b%CY &LYAHX>VEw6YMjRDFb^ikVND^%mn69+AEQK4^/Wb&FN\5A&lmdQKJ4T$eC!$CMENJF:\+1!VZRh>yX*8
>e$5J1 K4%c$pk56R=DP#*it1q/CR:PTH#8Lb91TDYhpRDAun<Q\MJ#I9B>n!EPm^^i4$&*1JMj/a%>^juuCHqN
%#d=FJ 5:6l*y=uq1jX9Q1AcQHR\kXnh>pc+uT4pI?<\TpHyBwS==%R:MLiAy9M&KlNP^M@k5?AdT\c>p98:JPH
uZC>:p $mbb/1SJ8LSXpAIiBj1ZRW<bm9P%mEX+uhq@EnC4>Zq5et5m+nE1#1P^$AXa\$d4Md!S6jj=K4WByc9%
F5%YXk $yE\8^A5W1PhA%e5>+RRLB&wR/kR&5wKX<kI:RBY$&tEQ1lF^\Lh@e9GiD&P9n+tJK@jV*Q9c/mZC8KB
^6<kV8 Wi6M^N@dw?P6?eB:<E!/4&jHye+?i+?:*=tH#FmM:DITA?t%:jqahp<RDKndySCK^<FRY?SSt/1L?!m5
mt/N:q VQIab4B^:4P4wE%BLqI*LJJ&eb%M8pFZJkm:CNS*F>wt^MITwG<ydCAMWPjn\le>LQ\B@A1#HGWn#4T^
u&CN#9 NFtQG8A=D15e!lWKe\Jhkm9YNpHH+VIHyZNh?*WC5HiR8\d$=W8!DAJWT::+b@+<\Nebju=QnN%c6ZiR
SRHE&^ T*6$yKk/a&nlXL&/$Y8wu?t=DV4y9iL^5?KwAF\YyteZ4qDPE=HmKyZiePT=*<dqi*dL#1eZWd\#MG?X
hlc@MI tMyylpAR/XM!q%*Rqak14\BT5dakRH8ej%VJFeD/Caa$=pG//A\J15@+%J>QXNtk&puD5pPIZiCe1>pt
1TW8ie Z%EQRMTapM8H6EZGtMT$^<+qGCyEEtGq@SWPy*&:IIaiKWi:KCKCu:E4aFuaYtH:uW1lM*a/KBdkia1l
Z\%>56 Z=B$W$AKZF8?:bn/I*pENC=5QLALhYc&IJp=4^>#QV+MQCuhPHq8PC1b9whQPCj!>wljyZlkH*p9GwAy
-Aa&e1 0004ca689f100110333 Page 91 of binaries1.zip
%\tEE> GkyWtPCP\D+D>>/D<S<i+P#1e>GQDIbclRQ$8aRqV5>^PL9/=Ai8N&/+YWtuyGqhGa1VXeRpDpciln%+
k9#ZLt Z?B&\6LtiXkI:SibbJT>Dh%8G#69pSFy=/mdX5=FI&6?>K4JlbE8#&X18XdaFXVDyyyci\6AlZ1!5SN+
+9@!Aj 1GXd4dG#kHFN^L:l*BTAy\MH\$$4\NXq\$wdK1Kd::Y$4hjCm#1iP@>8pwCZi<8#F8tPjNDECt\KBhum
LEjPXH ppKIIMu%1jVSI<1uXn8!uj!=1*n>l4T5\j#iNy5pjqW%PQhqGD/wLN/Zii6b6C>D=i%a#C49YGA9@$B8
%H5EJi EIX*Sq9R5cTTb/RZ<?1?R8E4d><5qk#IKja:J1P!?M&BE*!94Xpj^S1jZdi^S5?ZMmPqRWaY=pd&mpQ?
SK?QVp BjZi8/P?LluMld/4Y:8!F=pqAl<^XhEZIH:n+/YDPn+tdn^>4W<Q1wjYm=^JJ?hTml<HVDG<G%4RT1N?
XN?JbV u$BypaadPJWl5uC91M@EHGiYF9??Dy5#8iX\\NtM#JS+ww@\k@=>KNV#RbYX@CcicJeQY#>acGJP+ea@
cSZ!i$ M#hM/N+#w+$=ai!bJ@p\MR8Sy@$*=bNy4k\SSFk1FBn/uMNi$jM8#mAnPX\lZXaYFBF1%/jbM<VKVFR9
MN?FW> 8YqIb&$wkuqEb?%Cl&FJNSSdkhGLLd>JKLmhKi*GPu<\dM&GHe6A9A@A^d#MhhWW8=a6L%e16+GP991E
?=&FH\ RaX*WlW+jJS\qL%ma4Jw%DFwkkBb#JGa<F$Fl9AaB?Fkt#kXC:nCC$aYYbyNlPb\C4n@AEEN\YLG#Fu<
nZewau =k#TR=^?qZX<<b9N1G$m98MI?Dp\aNwky6V4SB1?wb\t=hdi<E\XRYQmyaPJHAJk4=5iQ*T*Mmdi8nYc
=1V#=> GhqT/uqqw/Xi?ZNyEtdVViQXDZR4EA4aIuEYQ!DJE+\j/E\kdQW9\\bMp<ba!51M6V%F5YTGDWI<Vy!T
mNha&S \y&1Si++>EZPFtTdV$Vi9tSkWPZIN+C@YCHc&X/MdulD$^ZSZQT<c$F6M6SueJI&Pt&NY&&8RI?HE$TQ
^>Njl\ :SDXK/\tZQP/Whb$dR!aP*i\8GZBe!PX864Vy&%jEHjCdAD5GJw@$+Le?1haPJh\EYk4RTMJ%?bMlw#V
Y+Yh<F 84!F&6R/itV5d6%&A1W/=5\uVH/pLNqdHtaNH=TFkcQ\e8Y$NHMBDh<da<YP@Fhym?6R&Y9uRcYL$bGw
5D94tY h>mT:*J9%5*mT%=4Gdk!Rjd/Ja>M64*/A!\jQ&J$Sl5T5GSS#Bk$J5pe^hZt*$Ih#/hqIXuKj8u=Luqd
SbY*Md 6GaTQNuj&VhBA6YHTY<bhlyC\M%D&/EwE#QSbmu&*lnRk>4!RwQLb>1<yFGV??CZ#nb!D:NpR=4NGXEN
<E&E?@ q1\IyQF?5RcWYKj/=#YyA9DwyKkun4jIRVh:*HbyuuFh#ZN6*+:6YTDnkj!uwqAtF$H^9+/BI&D@i:$6
GRnnJD A9:j>LbC@Q@5dRYFj>9d@pP&@bQG?\6*?w>\?Y>+Y+Vkd>C@VERnlH/H@qWcG!H<G#V5X/qpRj:jwZ@q
9qFDDY nAWFjwPG\u:ldRWl9$FDj4YN1CD$h&mBZ@l1Rhl9$L>&^wL\*!tZZ!YmBSF@m@/hawQ>KlE6KQTjjVWC
h$kPKa @q@:c5S@VERLIj:CX\5K@>XeFtHI@$qE@$>QSFj@4$qE&@:d:G+F:u@M:1dNi=Npmqqh@c<D\d?Z6+TA
9L5?K^ +@TYSEab4JcqEkP&Q@Z#m1l6DTk^&NL*JH#*IWh>Eh%iFHpnGWQhpHny6nwy\CSL&!j\Dwi?@%IlwBeJ
h:Lt!I &4Ycm@IkiEZjZ^iW5lmCXc\&Laq@!TM?!e9pImKWSG^CDn+m@$NcEKSE8#w&w*llPDNDy:#aTLamcDtJ
LW@+q/ Z4Ndte/SCq+Ymn6KFb:*TNJpANR>JZ$C<\aq$ph%Kp1=!QF$P+1yC4^n\t8Iae+9LBn/Vp=j&yWhDpQ^
>5ADML t#>GlJCIYnLmCA^<inlHCmAJWa%i&F/6t/u:GG+15GFNQ?+/En\:eW^55Qj=nik:Bt*ZVHhm9nyqEH%V
R*$pqL >LIR6aFR>EjlDp^yt95t*@CRn?EcV$+IY:!p=hJMERic/Zw$mhd8=4A:h&%NCXaP=8En^&pl5BwQtjhY
+4CyS\ 9aP4qC\q%LyIQ<t><N&p*4Yu>8A6d$cNBauSiGBVnKJtYW>1E#pun415!c%T%M?PqaZwFdhyFb54@SVX
mb\LEA J<1Dn&X=M9TXVI/KHppWuB6qpc5NZup>tVb\PhBBiiXJ4#RSw/i#qV*Lky#Q=lk5TpP\>DX:QH&t=bDk
K#uI&E +*ipp>1PMw:LIDleiuy^+dGikEHdllh5TX@dj$t#$#F>4:+6dnB?dB/96uyX!dqYX#6X5#F4Rc6YM!AE
eXubJe T%%GM1dNtY9ICjd^CjZ!$^Dk&XKk8>8P\YFeKEaH%REYhQ?Xaec$F*Y*d/!654A$W>^qu!EcKnGI5W#L
y^GC/Z 9J$@P8$lTG^JmM9Ptj68!le8>%c#48m$hdT4Wu\aQ%de^&KS\iGSF9M*Ke=pL@1FP/bk@p/yi\NcI&Su
TAynNG FS/5LPMRHP/R>\qjWH9HD:kVZaqmDASDZjFYKtXEaqe&mT#^m9q:KLLnGSWT&abNw@yT9tQ1j*<DKVTk
qa\X%= =tit9!VLcQQm&>LpT6M=yJ#1F*a=!1iX<wwA8?QAFZ4JR%t+kcQ=keKqJW!hZ=iZXA>V@MA4I9iFRl:M
wFEFND SqAGVX+XNN^eZ^kH9%W=Nm%=B?>?SMee:/VCWe$G:*/aI5=6a!*k!>Ppaj5\cDT=bnG\e\eTpZ%SItiZ
S\qPK# %6//y^Xl@FnC6jy$TZ:R:k@tFleQlmEBY1q%FHXTaQ#&yBt:ieDudBEeMbZV$a/<XF4V9HbPhIyA6<<$
K+M$44 <?RIY#SE/$W/aI%p8k#ZAHJ&B/DIZ$!<jYuJ:?bRyVZW?GY\Nh!1kbM61LB6&aQ$%iBQ*H5Bi4q$yJSt
wtyyHd L95WH^1qHd:eiGlIV*1uN?8F=Lq:==Z&$NLcwKNtq@WRl=4*8*!we>b<^h?SDIpI!T$uKu*1papWIbAN
?dlSL\ dQw=n%<CC%lM9R@%?wb5iiM/=qRP/JQ?HQuY<%qB>W>TWT9nPLkqL5W:*wh4wmD:N$?bB*M>1T<8LYL^
m@y6S# <eSaSF9H%w4ya^m@GLKth\:9pd?L1*<nj5%l!p98&&Su*88?h+#G6mm*t8ypl54T<MdBPp#6jcCA:Pcb
#c5ML^ 6Q4VN%E=1i>m!Mt^6a+Q1WD*5<<!!ZtVI!H$6bpt%!^SwdIn%D1RXt?=MX:tXCeub9GF4P96VKnQ*Dl:
Xl!A=W bBaTXe4K#PJXqdXQIn+lnqIJ?WnEp>\MnwZS$kX<hp\VCT>eK<^5L:Y^4TKMAZ4<=JaGjMY#ih5ep8Rl
4m9$6: HA19!dWw:R/GcbBLY1+6G=bn!:5ZhANwIJ&n*SN89Ih#u$>Xk+8ZGW1h6B+IB$w+M5u9hVuX9P8bJcMw
*mbJk% 6le*15d+NGYyVeVI#J^?cHa1Vm<qc>G5cXZ8tC6$/ET*>/$:cmI4pEKVDMZ9%>yNHp51<#Z9YeZIHcBa
kDyT?b h/%4WAaQ+mBeVdtBQRPny*QiA8dI<WbdWiC+Mh$jHcG!Y=4CFlQh6iVl*8M>WYw49uV1FSY<GSC^Vu?e
&+mi\c wNWyMJypI:lFAJZu=&n5?X1LdbnbpH8&=68u@R=9*i>HlpAM%tRcTX6D@yjZ@ALQ6P4/?bV#Vc\14F+l
wMW<D! *PMVaBddhTDdl4iXm>L=tyNqlqm%ucQqK@5Ft5JmR/&G%#*pm\D/*CACtZa/m5HWijI+p4ucijJwq/JN
u5\^GN M+>PmVYFk&DP=$>I8DM>FZH=qJiQidL59i1W<q!I6A<L6M6t*eKZ=%<FR/N>1?4NldV6LTpE4p$mYB&:
P&1W8T M\DZ&t%MZ8nMJth9/d:q+/VaEn98I:E^*y$undJj/Z%J%w=VQRC?#\m%CZN<1la#tw:b/iLFKd$/bk%u
\wnAey k6@*E*@p$ud>pw+c!m>bKV^M8+LK!PTYX1+Ce%5!&5*QjHB+DF8ET#+>wW^*e9kc*j:h!:S=IpXt?5G?
CcX&CJ iwJEc9K+^%^a=Y%yc<NmX<Xb$jp^b*juVKEj\l%nticK\MJZ<Yieb:u?wJKN#VdtDHVE1Xt4hS^!WJmS
pcbZqh >DZeup:p1/C8Ia>t$$=yHF4luhB6W?t59+D9@V/m<:G$!a\RM^$L#dc#S>ZdFaJ9QWELu1DPm9*4%PBJ
=#TMdV /HPW?+PMAS?/pytY4\E:#<DhM>>D^%YuKM9P8kH*ApwE56+Z/H#tYt%qwX6@:/YuX9nbj6A<+DBD1WH\
E+LtE> 6c*qkLi*SIc5p#bHB\I*@i$#n$@tmi/eAVut?ddF?PWHH?Pumqc%HP<Db&ih*F<aTyFK^CJ8!/PTiy<+
EPtJp= P1/1uDB<=m!N6XREXGWK+u@D*JpV^Fl&SiNkn5qd&wuiPjX+X#WlXN1PuH*PuZ%iXa%5aE#6SNiI5*RS
8?bH/! YF66+!/>HmIYQ&Y$/ce9RcyJX8y=F?qn:GV=Mm!+!i6^HFem^/+9C5w>GB\8?tjeSNjB?V4YcN>VyMbY
$\Bl5k Q@Nb\JSRPH4:bAIS^u9R:j5YuVTKh+Hd:TdiD#:h=CQkVZ1q#H=hNGhKSN<yC!\Pu*9DVN<?=A@c6Glm
8jCnRB T5umGlDEIalmh&tIkEX#mu#pK6?NcTw/I=Y^eTd1h\AM%$VtYeGGD$F4&$WK%%&S:Y%n^^K:jWB8y:=h
QQY5+@ =Znemium1itT>WkRR\:9<SAP:\eqa6C?^#4?uJL655u+bWHAptc*wu=9kDQkYd?nub/M#^?HQnb+86SY
@KaIJ& Lj1>1<Ep!bk+C#MMNy=T/^<LF1t65%FYt+QMd8A#%K#pITJkG:VlwEHCmwn*Eh^TR+TWWiiq1P:A=CJE
*DDL9^ 6ThckhGTendFNTTw*qCZ:BEjwCWHnn%u8YRq+:B$lh$E*@=MShAA$@=aueXI*hA?J<E^b?q=nAX=Sk!#
yWew8n TRAKLH1?%SQeLPMLbAu&eGS\L&PQ\T+6N+QXTndW=4e4RykB=?!XJ5Ym\WBPBZW1!DQwJ45ic$1Zbb<9
5weXR* T^qD\RiKDXic1DwBSW:>\RbXq1pZDt@8e%k+56m+n#C?p1y5XNmW^aZj*%/hhL8Z+MAyT>KtY1JlQ6tk
L4b<B: G\uia$?Z/HZqpTd+845jL!X1JN&#N@YF$&%I&QXYXdYbc&16<@!C41bnnmt8h#e@iiRqV:<4R@F1y<%t
=>neFn qapyqi^^+8AtaIjcuWBu%*aw&+I@ed$W%l>ac6pRbPGY%8EpQwm^8M&jSymycDQ#E6AuX+pLAin!eu>B
1/jZAE wKkk8LY$mda\?!nAq6iEZFk!PF!R1IICFC=5Bbuljm/eGA11MIcQT/c^icYeQiuk8$Ipt4tHw<ET/WL1
6+!q=c WlC!Mj$#F!kI?c/@8E#y9JSlAeR\ylNhK6mDZLVEl9Y/ma@ee$<<S<1SF+/mE^$Kd<cNRGTuYcI&B1\h
tLIu>^ XyY*klP$B6B4i%BY!Z/tAh>45d*N\@BRLQpmZChS#iJVHZa6ZW9bqmDFNR$e5h=8!d%NRLimj!p9:HnX
*kn*@A &=1/Q%RB^lHtNYVZZ&h$yBIP:8buP6C=P:tJS^IwP&pkdBDKjSSa6qaP6nJ!Xl*j5d>kMmtZ#NSy&?Z#
I!8tjF %bun^kF%+ym@HqF1mp=al5\q>Nea<N+tYt4kTWQ<NlR%Pp^PI<T\\Z6!*T4Q$ELZ?EI@uV<w:Ikyh49F
1Sye4k i6#E>q*JZ>%:WW91ZW?mm5?/:MJ/Dc1eQ@1AkY?Y\QbDdp%QqWp6@$kBTka#mi&HS&di+c+BuZC+&FKj
K@ThNG P8RdRD$F>4ln<YAJP\a!414Twi:TF%Gh?%<EJ%ip4?\%*hN>i#ZR^CCh*cimk^@k8N=\!+@\9Hl!e9FJ
VK\j/C 8<Ic5m1hmHhQw1MSwStI/VTyCBM9N##JjDeAQ^CZZS^\C5RqB6=aFHJK!DGXDWE6j<=$R>tb^MRKhWya
-A4mJ8 000b05722c900110333 Page 92 of binaries1.zip
G@$?Ta hJ@9KSq\i*kq/uq%PMp\nM6W:ttACaH=Q%Tl*yLbK?L=:$%mFR^aNI\$mtV&1ECX:<\%uF^L#wEh$&Lw
tRFVKn bQN4Vn95u!jn6C%YL6GcwcdDE&MijCc<Lc%Yc!CZ*I$<y\DanGcR4@Q5wdFG4:E$y5dG<@5%N@4>JtG1
uEE%8d lcmc6hVkQ%m\GWMSlTaF#^AJk\<EWANXm9wCda+Ci\Lh4?qhV^FqA<q%*lA:$ZDH#u8^!Qe>c<y!I54+
##p@k& k4TZ=G>LyPHXQ%XC5q>c9tiw!VTRYnJZZ/y*>ay!YDYZZG995emJ\5IQ$*$\l>*JypMa/kTRYmVt4e!&
GXK?jE <??NNa6tX<=VQAeHlbIMTDldpu+1Yl5/9QKMctnt*lZu>?>!RQSZil\EhA%cSEyl@!Hp/J5V#=1dGlZM
YP+Iqj $E<Y!aKJuThdlM$*4ANe&\i!/8V$m1pX&Y!JDq&Y5hDIF/wHBcmY9bE9YpMkKbX^*GV+t%>BE@uZ%AR^
u1IKSa %yB<*P:=5jmyk\Lbc#CqRW!#$6!?hmjSNVkdw\Mi4hDZCQjG?biYKjG^#NM!n+%C#w\&IM\NTVQ#%GIh
Mj6TLq lRMiVqpeG:Vn6>$X%KMPDcC9#DuBF#CB>Q/A:VF=!d^TpdBWWZ<J?V+dTTqbFjKSF!V::#%u!N$4iIj6
qB%w1$ D%GHAww<ua>^J$K+emeI<:6=uqm!K@cHna\LYRaVZ4b\*T:!pNkWj:Fbj&uLe8emH!ZYMRkKwZhVq5P5
nJ@I?S jM9ZdY6c!i>8Tj*XLluE4*EM9h6*/i5/DhCMMVt6t@nid:A%R/Ma48JW=:B:uF%1eZykZ8cMXSy9dk6u
FNq/j1 ?+N$8>yd&Z?iA*n5JQh56lC$TJ1S$Cyb@6A=VtMd!%EDT=5eHGMIZa1y9$P!wScV*mnc$P4P%uFYL@Tn
buGcwc hPD=981^n>/MaNn^<t5Ld5IW#Q&5lF4CLS^ySK&?ta5\?lpIM/@EEcl51PY1Q^KnwjW!!ZEQhbcu6Lpn
jqqp<\ S\yc^K#YyRiGTcRin!*w/L:XuR59>w?*:E+dc!XG/n+JREbPF4@i6pylHSG$9t5X%9iXY>d6>@uiT/9b
Tk*FRh 4i>:R@etF5:eV^ERpiLhPGpX@jWNDj@::DXk>yAYQNVQJqnd?m=FlktPAAPZSFe&9Ay!?>!eBWGALXLL
%=C=eY PZ@Cmi+Vlq%q9?/h:M^RPuql*yL=##!y/>dci%/*nQuE!8+6#4tD4@\I9c!85d%V1dKD/i&mJ=#Y?uSp
@uiw%p LIM=JXWVm9@\dWQ8%TEPm&YLFe1W*ELTtEX#DhkCe+!F8wMw$*DI>^Ie6/k6ihn:hk$EKtl+><lcMm<u
i/C9Q4 WS@\p?bHaBqB6kJ1H@umq:/iC6!9S8p%#DQpm:uE8FLnWEDi4qBdCCXRHt4dadVElNnhl41e#Xe=$!KK
dS/Z!d Ic9/AkI1DHu8mkD4ZTie6nZJ:#JSyWbiWebC:eby9DHy^Tb9tYhn<nXIV&*T\TteWty/\EpYZltteltt
RFW9!c @JJ>LMST\FtLmTQ#/%id&:Pl45&6/aLN/&1uD46c%4JWY:tm*dp6A5ZbR\cJ+Rt*ZwIBI?1K5l*!SZLd
N+GXQ? TXFThDuBL@*%IuML6k!84a+F8uty9yYWpK6Y^d<XNLQIRG9Yhh%/W\K8:qS91RV!jB9V:MCShBKH/c$5
/tu&DY %yqp1FFey$b>kmWe9:alciX8L@AhI4^Pd\Q:Lp\@JRP%m:^#^4HE@lVY*&99maeCBnmc!Y\1VkKi8Wwj
iApS#k btBH>Be9qLJ4/<tSDtAH\I9X+G*QRG6h+XdS@eAuWRa18tu&t9M8?l:HmK<aNT/:Mi\p^wQ4\VhJ+/4/
buPWB^ hjKQTBJcE&dh\8Kb?p>?1HKNi1Xu=SY*ic4mSR5a!dAGLGq:S%n%hR%d#a@iL#p\pdNhS^&^wcP=G:p6
4EFc>Y yqpF56l>y58HQh9tjl&*F8L@*/96lRV?8>yi/J?%9bDkd&9:j#nH@&\#lj=CIj>nFM^9cH5l/P@R5F@I
eXWqtB d!Had>C@%QbC<N?kj!&klSD@YiMKCj#ZG9jjp5d@1uGF@&1\lbDkQ&6emMCj%jD@phl^A<6WDmi^XMc>
iqFHQD :MTYBW/JB<TkWC\^q#XZqpF=F9FF9^/Kb$J>ibqkCmFLbtK=b4YYK$V>GFeacNdXbeH$aVplTpJ9ly=e
cVZ*MY 1AywcjAwqlMdV854uWIVQEVMZlk>=EJhQJV4q%>5J^KN#S:PFHamJI>lS<MbkTc9inI8HuH%NH1@ycyA
X<XB*m QLeQl#5*eGE?Gp6&wR@%S4RPFq%&aE^h/ik#SN=dut*Y&Qet$am@t6B*p\b\bp>NmZIn@e+aRkJNI<e:
b8CGZX nDRtR$Tn!VNbpBDaPmyPVa!Z\dS%j^>R9GdS!BbZW=MuYH1?jC&y\LlG*t<1P6IJ?CLBe\<HcGL!MaT4
!h&B*G nQ$k>JHwhqiN+pcXKE=XHJK@Xu%kq*#<W8KyQI@C49&VcMXbAyEJGQ?ikuKu+wYc>JHQhn51*8b+XPZm
\Wlmd^ R4yN<YJtV*+5mubL5w+4#bw!mwqC/hpMaRX4<&!P/JEI5q=B8k=RZ@?Ke8^m+LPi!wcndD5QLAnZXEZA
LPQ&G+ pI^8jySh4ZQK\=D6iSR*!A=iI?CwdTE:Mq6CA@XY%IMyS*$mqK/+Mmk6K*A8b/ej8<i<=Y&aK1V1!8>>
GlW1Py h?CCR>KYMBtTdMu!Ewh1m:b#ea4cc4SYAK$&Z=MTjSP4i8PqIKEb:@BXb=wC==YtPw&?wK=P$!5*e9%a
ymEItd jWGWTytSnwlljbC\4&YD?GeuYPNe^pM>8CGXNj<nB@&5V=lTey=LTk:/=RNLWIV\VqMIlauDpu:X!/Wb
SjFY@6 cq9^GIe:QWVjDVW=J++Kk\p%i&KWLDu@w=mG>5PLk1k/?QpVc^Gye8:#y#^yqaG$qR$:wJT8hIQZ$Xcp
?%GP<! j5:QV>5iC>:u8W5Ww1/5MHlqA5aKQB5>Y:LHuhwwn<=+<eH>B>8e%>JXKMZT58Z:ALQ!&d#lM#i@&NY=
pnLu++ ?jL*TI@L8dINMBcj//\c1jR4&pFX>FC:Tt1GESZP+/tw=u^>*^eltMmjQ>GuC8\JA:X8hF<p4D1ne&QX
JS%YmJ @?!VdP?Eci6J?^VTBFZ&&&ci5NCiSLW?WK=/$9q^N4h/<9!Fhmp4Ah6eIGk8Wqe&q4/#\^^k&^qJy#%+
B+?4QD Ph^b!@yX5=^hlX>8=m&XdMK\H<Su/^de?nWlV*&EWW%SLq&<<dJe9dqan#?hW4!JB#^pL<1D9$*>iI9l
aV>=QF Nw%nu>&B=TQYQa<jBw\=5wjX6P!:R@cLNV!k#wL!+y&YHMQdu<4^<BVK8y>6m^b+<DJJYChKtwApal8u
AW8hAE qGIiT<II@eb8$mBk+Py6cJRSM&qIhGG:WQ$i/:RG8\Mwyut5W5KaXC51P!bYe:8ta=H6HTG*h@\Q&ihd
GP<TwK EINX*XjJji<TtT<>kS6?MZLu=cNDITqbq8IT8lB^%hT4tGE5Ych+N+T16GDyc5ctwZ>aXE$?FucPt5kL
e5*?i* L/mq+pAip/C?C%^AXbp%1<uPj6mAKnM!44FX$MqC\eeTVG#t!qdThF?DG8=/<wm88H+:!@1:pqSPJ1T$
ZQ&M+h Ta&AcjLG4A:u5EtLeZCZ:Bq<6*!?be%S=I$DFIhL&kqyG^CXpi8SSqdwMmaCPhcKELH&CJituWDTLJ^X
p=Z=LB IK5Nq8LCe?@WZjkBY?HCVQP$X4pJ5mwZNc@!bTPbGIQQ=NW\n=PE:4P1GYK+E5y4mwY@XN5:bZ>F?Mnt
Jjp4Tc w*e<1WIi=DXb$tm6?b!l<j==1S9*BjM$w<qW^EBFZ*dn#C^B=jVhR/N>SA^nM?B4b*w1%EYAWZptqYnD
a5/eww 9RW=@9T8&!yDQX?!5twa%5&+kB#mbDcXL1?*tW6bwT@:EbX<pqJT@Vd:M:Kb<buGYYiw6NaAYViQXM/p
Za8lI1 S\Xq\w=&$MMZHF6mW:9Wt\bB#>\>d//1G9##Ti!G6iy4ZAjt5$DF6!?IRP\nK^TRZINtb?Z6=Ga1DdMh
jaeV+h Sa8niE9IT1uckheZm&k\$wTYY4nCm*^Y9pXd%VVQ+*\!m61>#W=8b*W&KbeW51+D5P&hKjDLMnN>Z=6h
9lB9#8 IJ+c1j\=j1Ye8*JRlQcc8W:LwNKYW\TLTu8T<1HyntdXS#\&@PLM/ZI=#\RT@c/iu*?I>T#qak/&Wqtl
#ku5IS y\1FlHPd/4M+KhXGcD<RP?wW$/6D^h>nEiS4i&@FtL>q:&hIS15&W$l\K4T@Z*#q4%!8G:C=>YAtZWLT
NP1/:h mCkFt^\?muh8KBamXQ$MeGiTyXW&cDGnPBCER6F>euLX>>EY%wNQYKmVbKwe:1Z5*Iq&=1+!%@Q<+P*D
@cQJKe 8KAi>48S%nY%+d+mwNZTm*dj!8>a::E9&Mh1A=SJ=euIK@4PlXqQkZ\E8Ybi$hN<H\j5W$w!LqI8#/uq
EIuaB6 GF<^u1d^L*!%=AYp5M</y$V$c6Ptp+%11Wt&6BZI&*ZG^!b!!heSP:/MHJ$9b4@y4Gu+wMn:KAP!<F#1
nSSa?t +!F#:dEl5XPFc\FC<Z8t9q^kbeNpDM<Pj64?A/m6/m/6\AjAS@eD^tYh5/!RRYykltdQnJ6\E1#Awqi\
J\d1In q6^S8hp+EMYlV!<jCSV8P=8LTJt69Be?K6IcpY6JcKD+tdXMPTnbLYLdh+bZSy8ADdkw:VLNALqT6R6!
MTmuwh W$?TCP<KFJpd?^qq8%Fq\Bc5qIE@db1*@uqCP>Jwt6hJK%ZuE::LD#mt>Fw\MjFj6:6C@=9dZiH@b454
4Hdk+$ @BhQF\4@@6PF\u@>hKH\Z/R%@nH\<HicStGB9+j@$/N8R5L@he@=d&tBj?p=BTACj>F#C9@Xw&=@u8u@
QqS/iQ JAj?=&<1Q91@aqN^=ZZmkIC@9H?F@$dK:L>>$\4@N/NqAyB@9tpFIL>>$@=dej>=<I8:>!>mQ<L@Pdkn
Qt5CCE <K9Jq<KC9$H@e8Ku5ND9$NBj$eK@R$Q?Pt5q\M@@6&mB*/B@qc$V+Ij<LS4/P@R9hk+V+Ij>LS4?G#V5
#NN>6I q%iP?F9$:>Rc:JhZL9T*/N?yNhk9umV@E@>d>P@WGlRB@RWN?X9$:>RcXPBZNP^9$d>Vc^BB?C>w^N?m
KCVniL j/jYIL?<e1G@Sj>P4j&!ISKA<Q<>ZPA@>%QC@!tK?T@@KML@@L@tZ\#t9@XV\yD@&E@>leMVkED?1@Q?
KD$EWF i=@&=!Z<+:#@*y4>/*ul$L</:%@$cXDwu=@4j>tw+ZTdBk!I<khFwmSWMj?9n1%RkJlt#P\il>pncqka
QGCLZI I>cdkTau^L<IN^*1Lu+aub^J%&S^H!+I$kPeQMM&E\CHkT*!1Qq:VGBW\D/%5:AJWb/E1C%enkFPd^JP
MYy!kP !V?:5e^LWa&!/H@6^wm51*Y=8\Ycl94be\mL#\J#Gl:l6Wta48W++Ju\$&8Q8N::F*>IGaMDPBRhM&Bu
IJl:A@ *5DJ+%ch&A44yS6Jm<4P*nejA@dmTmm:R^Q/kS=Yh$=QR5Pwh&68+5X&^Q@FH?w>ea4WdaZ8lhA>WR%%
^kYFH+ V?!qST\KJM5m+X>A9j@mD?8p<:VLTVCVST=YmME!>::$aV9A<$GwXAW$J:a\4i/HQ/lX8pbF&+%SR1TF
Qe<e4! RQK85A&VXiEaW+WIaeSaZnpPq\QBdqq?VuhddSium%qln4!LHZ*F5Q%Cc@t8^PqHkFk4hln@YEA^ZGSQ
eGuwc* <pH5l$iqY4WSka#H#RAB/G$ZDlclEB%MI5?DV5n%%II?BLmk#\lE<!MyR!CTBDS!Ci/mk$&t<mdpe8Xq
:dD?/A R4TCd1%i\!mqV\/=k1Dk<Ej!d$SZ%$dJtL\jAtwXEldkT8#tImN1!>HMwDiK%?SCn^\tQk<EJX&J^ASJ
PkGA8T ahQmaDq<bAVZ@W61$?$\aR^R>+G!6<YyZE#mpRIuDY*j\i*w@a>jSCMY%MnL?&XGb<nIlaB=lC!eMKX:
5F&1JW Gd#IS$&1J4WnG>=t51Q1XmGVWbJ9#aB=Ijeb+RtGa1!mDYlDbKiLjX*b^GTW%YC&cebeXh?+l/9t^^E8
-AcVt@ 0002228571f00110333 Page 93 of binaries1.zip
:1EtkL <BIM9I5WGM#J$L!ueBt!Ic6ZCliqWV5u=?Q?/Fu^Y4SV%jEnNaN4AuY\JyYcRbJtFLjj+AiNTI>b8RdK
$ahn\X Q%9/$SmRWw%6lX%ICBd56cYCi8XnSenCk8yVa$Z:F$qY!VnANSkQedhQ9Zc&81p^MM&YwXG>w9T+RVjF
nhkM1* TLn^wwKLYVEh@D+@BNPT:eGE$FPdPdlE8%8jlVKa>C9HZp$K@e^Z?V6141aK?*e#=E$LY#%%4dGTk/Ne
Xi#QeH 4JQkyRhYCLpG>HnZRIJGmc\4$CCpBjVEd\J&%nBE^Yl&LmHcK@<q15^i6Fc1F1d@<8pH111+:uHZmlYn
6?\\!5 V^wwKw5Z*t9qK#>a6I>+pXPk\?VZpZWc+PnCcktiX:Ik*8j84CW9bq<@e6mXp18@8ppIJ=56d<hquh1I
^SL8hJ PnQdqPCynXY+dJwZk$q\p/tKBeIM1py@cNFu#dScVtyWyn1<NBj$G6t9yDn*lBYSn*FDlVw?Q?b%J4l:
kMGC$X uIHDt=hCP16eGeI5yJbTMWPGdVql?RjLAMTepl\#1E<y5AM8mu:ZtS5<EedjhG&\Fjt6nVZ1Vcj+6JB=
ab\C8n N<EdASY<k9RCbk*T#j8B5WjeRl+Eq@wKX:=Fi^HQC+$YKR+$EaWhp*TyA$M$L!M5Sq+X%HqbXbBbpCpe
wCK\TC j45Hy>kiM/*VeXG%tRW\b<atBd/FeiFjjGnEZ5W5p:RuEG/S6m4CVIKp85wt@!kB6NKdnBnCXJ9ZK:wa
HI/GI% KDDXd^lGB@lDpd6$M\uCMwZ^Cu^\dHVP!D9:W5M&LC5le@4JMB$XY%M/!&AuNV#LTAZ+h8>5<Pi5q^B>
t>$ww6 l&TFEGEB64X#MSX=w+jqLQ8FyHhqCww8WIB/YI1KRchFJITGdm?BkMp6:yWN4?^n\Q4Q#HD$/%JZSwt9
4eIB/K V$qwe=XBV9BB84yL5^t8F+LlPZ$b\4D<KHW>n*=V\8j*yF?RCl8ckbw>Q/C+4d/IellN9yLqb#=*TyD+
ST8S6P wJWRpmjLTh:QwyFq+t#VK:<=Ld:4CdVaF#QMCpB?t$<MTc+S9t/@cLkZAbPZnt+?FMA+n1Be+lLbFZqN
KCSqaV %YEFHPVuB&^=8nHnnQYwMw1<F5QSjn6S?E%M%ACHAJ?b&k6yNSQ$S4H1TC!6Y&S:t$AY/9yw4>V/8CiS
$Rhhkc B/A=/<6i!##PNVw6/<*nd<KF6uqu=+9K5lN:!G6PcVZtcKB&Jk9B/XBZIFnl>ieKR!FKS>XIi8*\J=ED
hnVt&* >=LC!L6!e8B!%C8lGG9Z/cyl!yW+^5P5L!GQM8:JEi#DF/X=!#9jthZEk!4w8<u9t?^/J9Ej5auYt&N8
wZ^=e> m%p1^HC?4$uyFFE&p\&btDIZhcjAa#k4JTJ/%X?w5h@^eF&qIFc?@:p>k$J?^1*A<DbH5Z&/6RS\ZN/1
?$C*Xp bK1>Z$XFt^DpGbtTX=q\c^D8cYi+:eFTc&p$?WaW&ba5&/PyH5KC=tJ\Ka>wqYCPK=wtVVW:DP>j8<K^
jTbMPM EdPN$cBIPP=yQXPL*@wB5VQ5K6I/VcN\5<PlW9+mQP&Xq<$M>S+pZ56w+9b#IXDPtyFewc**e^1>:WdQ
A+@NR= Qj4K*&J1@nB9yu#ukJl#+TC/+uDVc5?1wplK6Gw1*e6mu*X@QY#F4qQSVKuWnwjDL$nPuXSTej5Rkb1F
m^jKpB nhm6E69d&hd\=Y?SV+5%R$4>\\Z9tPjXK\M5%uK1Vj$1<?tkl/%JR!i66DMdW<\kbF>JReuMhHDYLEl*
e8dnPy $6>e&JG:I&w\E*A5WG/I&D*:pw816+LTt96?k<<NTi1=plR8IhYq*uJEiQBSnC*AdT+wHh4!V%h+4i4C
WJ9#TQ HYX%e?e+*DX\DcG+GW>YjKhjQRCRBd11V=a/SBkPT#C%^ING@a^yi5Xwm?+SPnqT!FS?WXlTTM>u*!yY
S<jk+J j6qu<C!hwbDQdkX9=n#%M=YB?w4>^YR%jHEb#!eH/$X1kD!<W?JTQy/jWWi8uPK#?Q&lFFic?wm?KNkp
8j#imd T$ne#p1EcedQN/Q:5@chdd=b/W::RbwqRt@qniZI*w/ayPBE#t\!bXb@#HDHtNclH\tRV?V<qBaP*HJL
##5WQw Jbuk8q^#9>PMY+LIN6J*>nXq&^RqL\1k=HJp#KTEX85YW&hE*4F=wHb*#$P/\t+=tVjL&ujKpM/YTn<+
&/8k?p !>u<$uTV%IRhI1Q:1N84QtGJ8J%VecY#L^S8V9MBZ^%Ejy%#q*^L?c*wBh*4=!IS#bEF&H^*JF1jc#W:
QnIZ*e 8=@n8@GLShNAXDV5$uW8w\\bSek$H#LQM*^ayJl=#t\>1JQw5updtY!JW#H<+1ZH5dZ*&@ZKwNE4SV8>
4W&jHZ /ZWQ#?cXCZ:FJ+AXE4QA%hnC!/@EX$@=$kD?tVqNIcH:4C@4*E8Kbljj/#adhFh&RckYKB9NuG^#$X:Y
GGWpKF W4Pe?RQh/hBS69d%G:MFNid$1@#C18C%k#=?RY5H&iBLGBIeNK+*h>RGRNuhDtdQlQIuwmRF>&ZX\$X#
HnBXS5 FK5\yaREdjaQStaT5+*Y%*a\C@ATm@!58#*<RunX<5kXa>1YPBmje=$?D:%EFuWl\IeCSe<TSVj46?<=
RPTAK% D>&N=&Yi!!^>D8t+:1I?Q>n*IlI!HA=wAh+tmy/uFX1B\^6MXi\GmX\e%#PhyG:lKmlAyFNu>l^wat\m
Y@1jwd T1N!5H#KmX<?#511a>pdn:NP:kpT\AjI#\&&&G?KikEPQ<KM<9$?XnQDK1q4lleY/iTtak#c+JYZcRjl
CLnKSp JlKFZ^=FDLYP\^lKb>!LGY5CqtGkcc!>i#wtW\j<incVTPNiL<Ay<jGRiCaLECb/Vlk<BFC\^lywn=QZ
#m8lD\ PJYeY%?dPuclIbeNM=/$M</VBE&pjVn/VkDGcFh<w1q\meAm4:GT4GL^^&eT@!+B%qFe@mt*Pw5deCy@
j\GR1C X&P%G%Iy<5uSJtD<?tnI^pu?HM*&ICB+R65b&GZS%^T>KW9IYTY/:PE<l$DhKR!P1SZ?SMuSP5XcjFcY
YqAmPC HDk4H8S/<Ai/%CI!ZWi?:1A*PG=di5PcP:Jn?&Sa^$I!Gi6w#dKGj%Y&:YVeSM98YGuky#KS$bDwwi!E
@ak<ne *hu8H<^Mp9^d@pC4kKEI@l\PYC4kun%iVc9VJ<b<H\KVQia1aB4iF*aX+qkbFA/Y$R4&5yyMP1nRDS^#
F\1%/Q b:qh^ZtIJ!BnA=jQpn%H=*GnBPT<Q1$lc:tCLZkP#dE$CItbeVq#&DpE8Aa/:AHQ8iX%q1SZB@MIkL&q
/ndl5l :mHakt:pSnLm:u6>F8WBWJLkKLp^u#GV^YuK!KQA9Q#Z>#nGH?!GKcQQw*j15bW<5i&nITEy5S#de\wB
jA:uK/ jb6l\G+FYIlH::R\#Ct+kR9yW/8MA^1#WLjLW@HLhHHb:N8meHID^lR/^ebqDYt^l@DSHF&j^^eR1EC<
jdyacc mH*YKnV/tiQyJpm9mJu=n#1J&bItiDM6XBh!XVe+a6*ctH$/bGXNkyiBy^F9^8XNdEh!651%#VY!GG^$
JaPLuS JBmdRA#Bquhk$bE8T#:!GcDc?WMk\W6cSbH!k^Qc95$Z1yn*Bq1FmG>T5VVp^JNFy>ZM5Vln+?+FhnmM
@Cjj5w BkX*Pym>1D^=8MFyc!EE5#iC!+\b<C*n+kyIaut#uqb8A%9CRnN\S?Yi\BA*6pw51G$n=i%E$h$y6Xuy
CmLwL< <lLAtdC+I?%TmN/^DWJ9QBdK^CjJh!nwGCjluA+K^6:Gw^YRY<&9%8jFJXejEIa/D+F+dX!ekpl/n:eB
#?^V%% HaIihh<t%9w+yl>X4T4^4e8Nyep^Qi6XmZQ4eGZjI8J*eS8MtFHj<aNLL5mn:XT&6wh41SQLL=WtL$hG
y&GAhl >u>MQlmcqS/A</KmHap^uD=E/PDq%tD?>eP/@$NM@9%qECEG1ND@#P&d@5jYT9<h$\1H@:NyleN?&:V?
S51YbT +?9yQ*&l@teS<Y?:Q@&HjYwkpF><HSj<DXwAI9RLY8k*cIV\L<RVSQn9$FD?*/Fl9/IF@laN?R$cL9kL
\tLp^^ $RmF@m$c>n9$L/<e@4jw*/p%&C<@MeG@Sj>P4eF?5StWAFV+:>C\*/p%tMA9bB>M+G@S9%N4WMFjLCVA
HIJTL# wH?L@y%ck@:!!8F@m@/hYwMkjpWL@m*/h&wN<19FG=n\*/Hl9%N4A4>c^IAL@C*/h&46%&:*@#/YGQpj
ZjVZ#5 6mH<j%k4@*ih?/<PX8m9*P=@uC@<:\=YCA:@j<qm8TbqNkMu>SiecnF/hW>!Pl!+16lHcVk=@bkXmi!I
YuN?Pn Cd8\>SX89J^H5Z\\mSNDMVP+CljHqE%ILQlupEp1tKtYWLQtm^5V<P6<tDVk??5TV:S:&M%&mPtIPiSD
TAIHSj >B&Djk1%HqT+YuVGlaM!14/dSA^*Vame49&lkBnd=e%H4D\#!w>aQkM*AJYPjaFP#DTpCIljp8CQn$F=
:i%B*d myRjA?uYpl1ItyBL#@lh%ma:V=dyy\Fmw8Q+EtkGJH?QC\aTlwm8heHl6Sj@%&jwB^?k\1nN+w5GMi\?
%aDD%@ mHH4$^c#XPtRn?E^bpnVlh^#Wb9BGZXRw?/5<Gpml==$BA4IP<11e+IVkTJV<AS1XRDAPZ@1BmYGSuI$
qPVTm@ SKqjREajSb+lWG>EV=ec>8*?db88BQ&yEcmcZ^tw=<nlAZ<Z%58jycGQSLQGi@q8#GcAXTH*iHFk#E:N
LA/8m8 BhXL*QGwedeKTd+/R>1lwlIR\#W?D:Yn/JB<?bFK$e!85VETjukkGqbBdVPDb==bBIPh888c14mZ1YKN
T\M+B@ %S%X$w/NlquRhZa#nB4D#$ThPSE\pIK!Qn#15:X/6cm>&@#MIbQI&Ql5QeW#pFT9G\=Ylh<6VH6N%S6X
G<&DM1 h%Tk9Dbh6tjLmjcmWa=KZZD$d%@RKH<Qy\S%@J#X+NjZW%Z5hS4tTq=l=5dyLJP?A&A1*cQ9JGVbAb1/
1u5ii6 Q=pZFwh/n6*b\IA$V?FJiH61R&q=TEy4KH4*ehji=Z%aZZT&&c&pY?Fd/LNHDS>+pDy+14pn$!u88Dlw
upQ6yi l$NG/NG4hM1l\JR=ewW9CthNMD4SuZI+ubRWic@9KkH=b<WjYLdQkmTiS%yQQHEIJumnpWLDhP+8^QlS
mhemwT +YnH6c+6?u4?w8=R/\bXXZkphQ4F<ZF\@SY*5K%u5mR^dV*I^F4$+$Whpem#RHIE8Y=XuG14A%@lPe*H
qcwLB8 B=R1XMhRRh*JHh8L9VHw=Y:j6Gjc5M#WT!Fe%Xq+XTFwH9d5=<9F8>bihWGFJ=p8VDKKZa8Je^RJBqtA
c!MH^p qcZnwW+ZjkDP6>GHGkl@i4M*SI@1ECkN:NWMEcAuAVd<A+Z<PNdRqL<<im?qB&Z?jqJNNSR>>=Da1Yec
@:JAR% cRuGDF+w*JYjHR@$C6#<Jwym&M<eK1pT=%BX=bm=>ehm6^b%w1ZK%dkdX*4=pdPak=TH$bmW^FaVV1#y
tWKMC4 nS8uV@Bq/V+89t1^TDB>EJpdqZJuQTn>W64?m>$dei=*lX%^/1TGLVkwll#*n+#=k+Q:>bd!\qIqbEIl
$BMRqi w@h?Y1Qjp8hS*L59Ri\A+yhuCR!aw%G>=/t!:j?AaWKX>E$NB&!\Ycpbc%&*W^IqWZGqkG8BPFaJuFGc
TenXi= GKHLjj6kL4PDZaE*l%NRKCbDLb>WcW\aZTBuNGc8qlLi1!p/kC6day!a4Nw9j!@WA=H<mQNhC1Ch6\y9
AK&Mq8 aQBLpu5/^@F>\I=!$/m9P>QAtGM*Tkbjy#\teG>JNpn!<N8Ek1$W6FIlP<R@ZQhJ86iFFS61p>1jpXan
4kR#=L AaITH4M+yJX\&<Ey#BXqVDV#b&$&<CZKhYYMt=bRZ^=$G%1nb65&5McmKVe8b1DltJX5Wh<RjlaiN!GB
LuBiqA wQ&!DCX*eDDN:N+8qYe4!>Kw5uXq&K+L!=T<<S%I^lZcptGaD+H+p5VRBMEdnw6AnCtK!h<?1ljji>@D
ImBS1c kI8ne#Nd+JCZ#i\jMJLFTw8^y@w8I6hY+ZBGIe?aSGQ\N5mWS88nydF&=B%VZqVD9S!4+*uhd\XJHaML
-AD=G/ 00079da11d500110333 Page 94 of binaries1.zip
B:K\RL &VQFi^Md^8:F\pFCd+W&>5XMejDn:8TI4cut1>EGMqMnm^L!>Cp6tNCnh:$mbH65Dq6=PVKDJZwm$Y^y
*V<9S@ !jqKA@VWDeKeweRlBiAWZdIq6NY:IJAd5mntCZ9/S^tG?\>NZc/baNJ?tV6t&e4njX@!$pSibN>Yq#pj
*Vd&hV >n@j@iyGyGu&dPShtAd6PFK9=BLBkaTFF5$W54hpFJ#9*9LiVGJPen!4R:YHTHyiV<a6ZkbZeFwa/8%=
+<ntdy nt=<c*YJ\FBh?I:Qq&m8*BjSE=l$PLqD5F=A6cjK5B%E6Vl+$^C?ME%:^@>qN:Ak*#&GHp5/YYtGkMtA
!cGKh< 4+TeuWbJjF>m^IM9$HY><HRdM/t:h?AnGi1JZ!?>RWj6qh4nt5kaZ!:<R#AJ<Fd14YIwp&H>K^+jcQiV
S<aNE! $GRiqqC4kZFCqiDDDcKiYcQh6puylc^b5jI9TpwchB6p=nF=^P^>^*S<mn4d@pYd5BGiN/:FNP>+L*k>
:dZAmK dPXK?yWTnbt6&=TdAFG*6mA15p6:R8qG5KX&#aqPn8q:qLc1=phFEm&uYaQZ1d+jHpS&9iTn!/w8j64Q
d1=E<5 y$Hm?@d1/MNXZ/qa4&GkjS?\uIy#X+SKNV!Qy@A=FbT4&yGuJm?uKCdi16GG9<5tH8\$=ZAlCt$bTe<h
ab^8+H i@Gy8eV?aj%&SpP^=Tk6tekSNm==#ThC+Hinq@BBlD?4P%6:hV6:c>Swhe+wthk<Q6*t\9tR@YRt5BH!
V$TRQF eQhyJDh9%wibyV<$uyi&qn4>4G^YEd1V#d6T8m<B:pAp@FD/4wJ$wTYc</:Itle=$D\iidVBn$&6PC41
H^%F^1 S:=9$a>bKCXueS6lETa+yl+4bPWlKFXBdc%85lmqG8:=iJcjQSh1PY:MHlXlSej$YhkGN1qlLj&w:Z6<
j9^WE1 b$8Wb%$^HX8&^ZA^p>hkujy>y+iAyuu@PMWjWcFad1<?P$+?dcCPi5Xcw8JAa?+94dA\ykSpkhG%$XSI
*wdme\ K^haFyCq9d5TYdKc*hl>H&t>kqMyu/yuJ#^HF9@1p>y>k9Ij*/I@4h@YA8cHiwmn!h%eJ8S\^VV&iL$l
K1wVTQ JM@^aupW?91!qYJ=P^@pq#q\^Y&@cGN>A*k6Q$qieyFQZ#yQpaB*w4u#bjMH>puC^ajK\cNutSABl%ju
%bqXD+ n\aSKlQuXRy?p6<+beGA5Xja:y?w>yZi!*u!NR41@mlX6#q<ZZh+Ry=S8jCDKNildEC!?BB=DB+<6yFq
wK&5QV J\m8TKt#=i<BKL5\t<E^JkK*5dQGWIuhTKVN\u6eaH1Sq$q^yp9H\V$5eXA$k*1&k$THnhit&w=ewBSH
NqnJD& V\m&$GXy/e^JYG9wLh8SZkCj\hNap$CmjS#RPS^u4QnER:Hu$uW<iQ:W>/bQB*CR>A:*FwjaKD>dFeCE
kEC=I8 hK^$K&aNlAQ%AZcBZSHWpkF>%>&dB@kt?:K$<MJKA?Y+X@nWKR#>RD8<=\SSlkMMK&5&1e#IjMe4@CE\
m:4WYS RpK6pVQG9iBi^4aM5jP6ey=SaLq9IAm^lma@hkuM!$<9q@/InaXEA^JW4BiG!8S48Vcu4H%1<JI<Ph*T
Z+h:db kZ*k<Aq4BjIcnL=cm&jjI9CWABQ1Ck\ybu:K\*&4PGMAC*X!1=@yJYbk1\qRGWbZ*F$pK6iZSE5mqHp/
+=kW&4 A9EW:QA$J86+W!$1%m6D&iZV5J+umLZ+bF655L%8mQ=+4GX*$!4>nNulPCY$X*RpFFpCZQ<86:wnka!Z
al@LKH w#/XVT4A:>8*a#XYQeAHH?b5n^&M?ei=+8tZ5VyM<44F%\R\:&<+HQ9%h!tD4#u#h8YXJq+X$j6$LH8y
R^G=cW kD?1IbQMI$466m<Q$J%KGqWpmGb&An^ZXCL4KR+GCqlDLR=A*Sad&F1=!WidqXiGQ5V4GuGnQ5k?>=4I
nAa9Fd 4S\N&CCKiuJ5T%a5K//kJ>c^/di#<I!QX$YY6*k*CSB@^E%!/5y5AJbNMkp&K#+l#<b#tTy!kkQPZ&Mk
i/d9Fe CYIY?ZlGCEnY9Hw\^D1PW?Qp:R1&KM@:pwtKqVmiFP?F<8<+^huFkNY&/+INQyaETk%/ZHBJ<bCSVwS5
Qk@QNj 6t*!I#u#qjlJt+19!C!qt&Wc*C9S86QelXCV*9K:n=FAZ&^/8LyJj\<8MNGpi$MBQm$cw!np6Xp<6NWG
m6XKhK Xk@wKWhPSKHW!c!/FT#EikdpWeA/BaLh\ii\^BAK>Mny<htDHj>9hnA=C>SCSNSue>WHcmNm?$:iHCJ8
N<*XAB YMkKljQ8!iNGC:yu&Akpq\$eJ\cG5dy!ht%Q>IlSA&<p/pd?\QJ?%b&pPhKpy%k^m8$B+M>/yuqc#Kqi
+dp*A8 II?\j9A5#1NqnAP*Tl5QTQ6MIWqCW1nNEw69?FK:=Jp</4#+WyW4THwZi\bMSn$*jtii6$8Ap!RF!i+a
1KP@T: M\1c51lmeiae\J:ha5dQ8&+iH%Nc&:T4hbhZ8e&XhSH4cBwki@AXV%G1%P?QlNY#@tn?1clF!J$E%yqW
caXZYJ L@yn8Y#C/Gy!NyJk&=F<Jp6Da6h:S\h$hJ:FkZIMSmmQiiVKVeDZh4k6TunRW*>&8<PcIIX^=nFN<tG&
%^@$YR V8J<dhll=4aN>ni5Si#Lh86pwbNVkq8m!\5&&WR!ellS#^<d+ye8Ell\$h!VG>D5e+qnNp=q#m5qdeqR
l?RIPi QnyLFtu4:D6Y>n4=tNYN<++KBXt:E<=pAhbS$eT<W@q?wL#$C@a%yGQheiDw#YJ^>mhk9W:AG4A+Gd8m
Ji4qF> NJ4=8R#i>nm#%k&ljFn&&nSQ5WJFG@^1&d4HVJZu=#R$Y#pi@P$wAR^eM4Xn4PAiYmmGHR6A+T^P$QCJ
W=naGe +DWpRiE4QhXAE?Bh?PF%i@*Ay+b:#X+A4\$njE98BQ^D*hDeKe%%mjLVGI@4#/Pqi66NRIciTHnV/b=G
nZCGcM ViG/FN!YqcBcW8dt6d1t=JGbjILp5+R4Vq=VYZV^hqT8tldq5:mGb\E&PA%G#hjCnFdE%mQuT?kFc/ZT
MaWm>i !Q<ji*<hFaZd1H9nTA\%R+PWmuR#VBEKppMNMA#h*b&mw6I=lJTAmHS*malIh#ewmHSLm+n/:9&e@b!>
Sn*AXu u@*I@9E>988e<@:P?Y>k<YH8^d4GYZ/+8G:+B//^dj!i6TmB^lidZ?\4*#wRXciQek:+TAutan/Gn4*y
t\%kBV KMIHLbL+bA=#AN41mB%eZ6MMM/8NbJtNw#<DGVW&TAnySm%68&4nYdHhwV5mhAauuJWSY!55cID6BECZ
@#!%TE t4qcctc<XM&1pI!54S<%iT>CHaI/8Zua>Sk&>!ZyQY$BNT8LnYa8HLia<:=@t>S1$&/eLY5t#Zm?9t/R
Pym&iQ tE?PqGwSe4uK!++dLep%L5$nCh?%>Pw^Tn815^DBila8Bq46PXLGGP$*ACh\XdZd+IjHlNh>JLG8hHmK
Lh:CW! IaZ?A&d4lLJi6*F@:>n@<i/h@*eh?%@W/9>+pe>j$P1m9!p\m%/>\C#/&>/!<G>8B9y9S:!TGQ@N#WD@
@YNP?B VF<1=Z>#M>A@$=iK<h@eDQSZcPG4$JeJakVpn&nwFYn+yTiH@SEN9\y>!dKt<G?YXQ<KjbY5\iCZ!E1E
m#DDRc /B@SX<pc:LKVm+D@mL=K%1CZuX\E<pj$XdIG9YSBXqkE>pj$XdIG8T!yIwk@w1?TNelq9\kSEj$n?myb
plJP1? k%#&C\FS<B@SX<uc=Yyd>D@Zm@<P@=h1?:@jm1d&L&<X\4@=M#Bl$h@Xm$ZFlQ>QtS+Ia@&jhPMbm^%V
*G&5Mi ZqdJBnQ*6WK4a6+YVNQSP%/?1hQZjj6tqj\1LGm&/AAXhl4lAD5LylC<hK*GLk%QBLnLtaq@4u+S+%db
4%/:#I 5nGPbbT&^\<NCBZp1@\MKMdhBQIi<55<A@D?dd8AQ4kYWQ4\uAtJ8+kiSAID%%w45^LN^uNcyWbywbb<
eChZjP *KiE6?Z1/j14WJN$EL+T*G<liIb&H=TFQci!*tXuSqAVijw=$RClKLM*11X<kL4BMqIVRRIa<<N$Dk!y
JG!1<b #%Jwc/HdcjNIk/je1N6EaSJJjGPj8P1BZq?41lQY4ApR9$*@8lLewGHalbj85AN6l?JQV=W!8#ET+NYR
HKR#?6 5yhycAJG!n$e\VShqKyFmy$/kT6VXS4caT+EiP$\itlWmq%4%DZXGc=IHSb$5!Gj:>/k\PuLLAPl!kVS
e<+LW+ W>Yy88Gd/DyXmk#6Kk1#dB%l<GKVRSD*V5?u%@JQGtQ1SX*6%E?DTPGD8*/4@9$=&cMJJ4y1wCSDEdQP
#!&Ie/ j*p&S=PY#tq4k95&88A?1M$kQacl9K=^:X<!eGQ8%DlNP+b^Q8uhVN*cV9S5yAG\LqQWlkH!DVjptk%8
*mV@DT /*aDu+q+nWd$*YCTAM&?%@!m&CyFAwHHB+LdS&Z=$?NW8=YuKqWhR+&#lkT8+96jt:VF5S4c5<\&*?b:
MDjyhk cEBNm6$G?*jKm8u:*!=M6EcZ:D+KYH6H>cpXIF$n$4XDh&RmM5N@m=&^@%%MAm%<b&Bd\Y*8StaVV=cW
5mLjhT eX%*G<\@k&9WY$qVw8VFAMNdtM+uKlhMV*lQyaXSe?8A9q*aIkHi\G^mnW/\+WS@e=NS/<cW@\=p&BS!
Q!GGte @91441nly:NIPEld?+ZjSISlmw1B@YTT+D//+Cb4JyjXehVhPnYyCjET<?l*R%K+jX8$jJFw5qd9=@5a
5:F%R5 a&QT4$c:B/LZ4X*tW$neQbZNB15<RuhH*X%%a>Qw^BVX%ka?<ByHS>^uI<nQ?<#dcl!iV>?/6DW>/He9
qn%4:h DCj4jdE%T$N4/k9?4d9e8IqdXCnKIH*WyFmRIqEb/1P!EE/9#@W8m6AIR=JAhTXhXwnZme:5wI6@uZm1
kE?kl: uIp6VRpT9u6*8kb@:65M%Zj=9n*!6>=>PZNRqDQthqJkEG+*1i!bZh=J:G5FMYdnkin\$L4eu4Q%c$C5
TRZbJ< 8i/c5*9i#JuycH\TbLZMS&Vj#uFiTpT9MuG<8thqmAdHZq>yTc$JPZe<^8=t5hFw!DH!$bV&mN=P4pw<
JpYJud yMWcPk&Me1MT:epd&*>yT9p+pcmMLp<9Fd/e/k*d>Fc+EibmM>9tSZC6EldK$:IaXiwDZ>PLyj5c^nB/
b+Rebw Rj1Al@*wdy8PblI@iVSYLJ!Q:TaqKuKESC4*J/=@aa9KR\5m<!bEcuLL*E$6V6NwE8n:\wqjq9c6MVT5
Dc$#5A 4G%WC:%4B%qIpNJkC5INC>I9R>IImPbwi+yeq$pWPM^Q/q@:?HHnwdbhXnCmJYKjMwt$J/DtqDB^hcGD
Y8AhjN %6/ad+5#mN<uS<dKt^:ilY$LuDAdaGQ:dMajMKyYQcy8%^<a<:t99Al!SE%1McLS8hFe*kh?wSE@<w^q
G!HSY$ mZtpm<VAWh6WbhiqqJB4/P%6+Jy\%M@G>>cFXc*XI<Z>Gc=1TXuGA*PiuuZyR@DuS+^t$T^!T94WAAd<
iGkRqB GV^mZ+DLdYYaQ8cqS4G^4/QXaC4?B!XKa%JAqE^aYYJn^/lYd<kS1JJiL!c!TL\:1mX#B*hmahN/$d6G
e^:Rcb B*K>^N9j+Mc<tDG66^VZX+nSN5R&tiBW95@&PyCGwML+>SPMaFSV/\RL!jPDYu4pPZCEA>n9LYLT!H&8
=+\=mb !ttbSN<aX!#GBZdc*G6%MCZLe%jIt*9ljChQ6Y1YZw#HqHZeli\=KL*yPu4<Fubi8P*ES\&\ibjS#Xk*
+9@9K+ BqNDtQwGa:Pd9wYcDGah1W/Xnd<\N?4yk*/C>DF^:t^ASGJWqkl*TSnFS>\\AW:hM<1M:KkpEq>PneAI
a<SNV^ u&<$V!nn^\%pXtp#KYZhdEGR=&^4S8Jnu5BE+&jt%?q!HX:wc^YnDlaHF@pNj8V11EBVVq>XdkbJJ<CE
k9hqXR MpDE+pXlP=?\YHD16/ZX+Cq5l6Z5C>&Dc#uQ$eWN5>VZ+#$PH!B!hhLeH4nt5<!?5\<C$Al#QJb*Q*>b
ihR+*Q ce6EXJ/wE=GRbCjddqDLYmkm<Bu\/BQDaYGGN8yB:dWNYmTn:weaj/8VJ<dGd>\D?aDm\?REi$QYB^\D
-A>NTX 0006228376600110333 Page 95 of binaries1.zip
emWw1C @GZ6G$8X&Yq*:G/6WDeu$qK4aLY5X4m>bl5i^BZldDA+IJ1L1Lj!Stk%:P:VZDe!t#&F!wi>NiVVW@j9
T^G1?k cC^Cun\1aYa$nmd$1R<TWTy?1?tyHXDw55tW454nqIbh4iG@i=&/we*QSukRjk>yeEQ@=ajQyNb&kM4?
e1y&GJ \1tk$qLWRcQ#%>P&DecK\M+=+iVVWcj4WF/#1A<EBe$la9TRu*a1yDTyNSA5*aPenbMI*AI>Z@Tw@**>
ybTmKi c5b1*HFCMiuAN*E^$cbqN^PuN*h1BN*iF>RK>nC6j5IZLL%GG$y@Wh#@&9Ab#?9/w**$5p4^kyYtZM6/
/@yq$N h<EdyqiCc#h?9HJhC=^p6XR*np/YE9$1>%yZ!uyAii88?iywl?l4@GHR:e!K81LY=*j\c>RIi>!QMG6B
:$Cb9W =QEGlY@E1?1jh#/I5\dtXdVnFPiGV+aAZpK=/6+whNq>EuP6RnnXlmGmPjaN9KiLH!?:1n??J%L:/<EZ
J4&1I6 Be9pQS?KN8Fucqq\@?jG^a+H4+K<lV6yT\#WA=/dId<m:Rb*QRHdaQqFY?JJcW<H!a>!epy&m<S=V>R!
YPA%%% i*T&/liECw8+/dYek\NBdi95!AMm\jnAlVX%bkYBAVTZuHEe\q=1$Tw9>MS/Vn@YdCqpFq<BH?^1>XZI
AEBw#Y ==G6C=JR^5B@MV^<V&iN/JnCyLhuJT@YKMbN#$!I@>jkjuV5E\BJwX\@=:jX#QBk5#$&AEFBydQK*i*P
EnhYnZ n4J%RYl=<lPb6TYb5dJMNLt/GBCQ\tCQ161PBPcYEtP*X<WbB*SwBLmkeunZ144*Ae8Ae\8Z<#L@:<RZ
I=E1ZY D+b4ePYK9/>QPAH#XR9#9Vqt5tZy+a6#wKLG^S^<1D8J??KGApWELt>&4Y8k*ED?hneFVDWn1MPwQ&!9
jX:Xmk Y@/naJ<FIj=YyK5e^N?8S#FTw%@Hu4iqRpNPIBSVw4l%FHu19!yi8E@QNZIS<PWZlac+m%&qcl=*SZtw
AqLY1F MdEIMi=At8DDbbjtVb:5?V$KQhST$PlDL=hV1FqKVZTDaJuJP/EPA<JG\c4pTKWebwh*>QnuDRhLJq&C
TSJK^\ yS\:?&wAR=e^h*SntGD>yu^M!GymBm?mMGVH%Dwa6Ln!1&Ryb!V!i!F9DB/hF!w^k9IHT:>Q5M&EeXSm
T/JZK4 XS\t8InKLl:mE64nX/:IHt\S8lFCE+KD6Wt#*4J+TFAQQ#TVD&M<IuD!qQ4A6kpM^=@DWwq^d4mEX4ta
!WE4uW L6N@#i=u5FnA^K8q>:mRKV1E:8$qE#q$5lH!lCjQaX\W1Q^D$L/y1#Q//BZ=+DW=8&m&$9*^NcCSSa5k
j/4bA6 /VM?D*VwRR=9n\wj96=ijM8t^>*W*5#V+Lh<tGli:n5<ueQ<?Xyj<=quPhp6k8:YBJ/y=iCpwyb&=e#J
=FltL9 FTJ>>^qulGwwRJGj&G:PYlJF&V<ML&5+NB5DjjFh$AlhKL4kHmWk=q#u46+4Y/b*&BBHKqhR>4KBD%?R
uk!=Iw iMTwS\\<6<X$!?tE%mnhDleHqi>!ECZBpdlIKw<%b=iXeMmG\u+y=\n!YY$9eWc<uiJnG<C?5+=%$Wap
8<iq#E X*AA?K^I9V^kMQT:M*d@T#M^/TH@mqqpZ9XF?<*:&MSq8YN%Vn>MTCb\%bXc$P%:RYHt1DFE%e1MXC<6
qja!al l=mDE8pt@%MX*KCuyK^YYHI>*$HaHRqcuL&G@k19bQ+8HM81ca&dH>M$q8ty/iY5NQA&eAG/Z*EZuehj
1E?YP& p*@K:ewGeyJiFnYPy@q5a$mmX1$Tey9VpcnJVR?yNEB&qFk1GAt41j<CpR8^W==HAwHPDdPlIHEcaLT%
H5L?yj AZ@tPpiB:?N+*/BCX!nw1WTCGQpY#16S@N4RNTK#MhWkEY/ptmGQqLybH#p%NV!&nD:uA+KGw4pD%hP^
LDjTNJ $KqEM:DDQLm#Ba4l>6+?Ew%Kj4<ycbCjqy#>E+R>:luweq%$/XTMH+L66R+AG#jDXRiPB*cP&=$&BwbF
QIVN^H E*hK6L:RQ<hK98hSc\l@VE%%<!MNYiC#BJVc^V:w4ypn\5B@+<6EyWFCy4#Z\>=ldiaKt\w<&P5%GJqL
bjyJdB p4:6m6t#NCjY<%GZ91m1kdnMlT%d*!:1TcnTX+ul&p?^DaGJK!w5M<ATDFn?q*464&9iiMbJSIE^Q4>5
lw/t?p TLaA*G+IuCFltXBpcbyKe5P\Vd/cplaCX&lDSm&#LbKaKH/:FANw>64DnN61Em@DMcym=pLQlVhMGq%?
:/6p1? 95Ytl&\uLl/\&/&+%P!=wkn#&VaYe+i!#Nq\peS>ET\j:V4MTXApS?\ibay>V>^tdA6ZVS^a?uwbZ=TN
=niwae A8Tc5>t:auT\L=$?Cc>YI?u8&@NM&#>d\k/8KMF^AhtBkBX&:kQ<+VWP#cml6<tMAN5i/&Aha?Z9>P1q
$Qd?kW :I5i*1#6ymYd\9/$>ITlJQ/V=N+VjGGbBB*5LJwT^46h*:jJQD&/+p4S:y%lWq15b9=6L@$*FL^^6LRJ
/w*$S8 uLZc<e9Fu$FECP!L>GujY<tca5K59pw6&18#JI%J&G<!AS!PuT4qjhR:!5ttZt@5YLKdNWSu^t$/*cH?
IS<u\C Lu9>ac8HHVJjH&?$MI%Z4=S<!m$@SD@a+=9u?Zdj\BFNe/%epd\RQbKtRFRkn%61+X5:9tB=dZDB5Nhc
yBBi9* tBD&kN&@*i@%KPhGEqB4<E/H\F$Z?RhWPy+a=FFQ%B*1Mi!!^&Z/Y@S@$+1=/Q>k^S\mDQ$uF\+Slq#X
!WEM\b lj>hWj!V@QmNeSK>eqFdXPTQcNG4$PDL4I@au>C@YS:/b^y?tYH<#jDRZ/ElX/E9M+^m$D?maXikL!%1
clYbED m<H@mL=K%m+6cw8J@BF>qc#B\JjSau>AR<BZ!hyqSY$IYQmQ/K6pDR1=nId?EZ&X4EE8KT^D\QA@w1?T
FSyl>i Nekqt!$R5Mkj$XjJGkRC9+RY?^Nc?Cyb8>TFR+V@<+VH*?H@$wYL@wicN?Vj*m@@$@iF@McFI&D@6?b>
B=a=$h =b1*@F&MAINnKG5kibMd6<mnu#KB/88L*&Pm\\&?S!?#LVBILlh&++YcT&*AY9dbLu:ESIMNjwT:Q5VM
!TCG!k TLdK&y%J=\RyEN=DP/IaCQD85yFJtW8%W>::LDW!l^l5wZqVS6w+E<P8#8:L!GIimZ#Fj1*+BF@a!e:5
cwNbH1 8Aa+RnNE=FbDM^b648lBA&Lne@nRTP#pFeX8Z8uA#N5ZX<k1ZF\5ihL:YTy#NDTkWpPAc<VS+1\V:\YT
t?ENHj IjT\ZY%/YD1?uWwT84QBKF*S>=k9J6d9P#BWP4F<qLjM::d!pGeI6clGwl8cb\n$tEqc$6um5ac/F@mb
bP&QnS SN%Tn61E>uDWGniGJpFFc?1ESaN*DP\5!Fm*#G$\lYTDI8PGJ:C4!u4W/i1T<8Eu^NK#S:8?nPmJ<RP<
pNK6DQ 8kMJRp6p<Z>4qyhBB+Z\b+dR$GnQ?&1jc%e%=miIZKbDu8i8\GBj*1EaNbI8!5W/NLYM%iDR+NXHikJ*
#ipSBE NjA+Q56nm+it:1=TL*!Y?9Aa1d5LwT5JpQwTyTpK:kVB/Y&WP>wnn6d8/P*KdTcV/T%?$qkYYX+G>K5*
I+@DJ5 K#!*hpi18\ZIbGy#AMmTytmpH^A<=*>*FDiQdL=Y8mIwP%KZK@:8e//?5hXuS@SMC@bC+>pK>e=JuD#X
1b6*lm FF5%Ai/mJ6+mJie5k%:mZwtaDHuGXQGR\cJlldNQ<4!aBR*hP?ReJ4:8u1RqF>tFR*LeGFS&<*l%aPp:
Ac5VCb YKMXIN&p$jVB&R?WdVeu<!N95\^jwKXY<\8%eH9Am#*ITj%i#q##n^h:w5A!dEn\p5Vn%&JAASyy!Vat
!K?N%* >hkIYG9Wq&5AwbRQIQkJhL*aNRD%jjuiBA&V^EPnZ=+^HhiQVya$eSW^E$S^E16BdV?j1k9cNh:l9c:p
Ta#X$w cbS8T^u+YC<$wK$bK8u*RZdXEcW>!#mCJ4*%4PLlF@F4SYa#nLIi9JI+<=l*@tkG9N6Xlm^%hdeLkTht
5J==nR jyV&+jcTL!l5@D=+kTRJB&B%M5Y9$Ec+RTPS=P@b$E^ByhRAuyQKAt/LMGa@CppCmZNGuI<@St8KXM95
X?p^Fa ceT$$P@yHX&jwEhE?G$/!n/<hR6Zb@qcNC%AT>+m1GI*!*\DM6NDVYLJ&>*TnRh=$ul4Bm#+=aIGH=#:
d^:BZ9 &MSNJ64iS+RV:\b#%IY9BFt=JL?CnF>4SI/p6SRn:pnHVTQL%$<WQk4jwY>Jn#N5X/+T1FCtc\1t*tKF
Ipji%H d^@EeZnXPw=RH5B*#acdFByjYXAqQ?wKNT=F<p/1!1Xm!WI1<Ee\$+E5eBeNupm^4#&QF=^pH&\WbhN!
1aP#m4 T1t4dK&4E6j6<TTa<4!Tj9#kMJPGpAIV1EF9:Z1\GZGZ5?pkM\WCwI#Z1hhljYIB=wE9%8MZc$tc11iZ
<k6lFB ytP?BVj4/%tp:h8R%T#SXlPk9>t!LSL\>Np\/#%myu+BqnXQX4>4/:<pHckdj\m/!LAeAa*b:<RyGp$*
H<Ltdl eIWPt5b:EN68*YAMT$^c5IQ/iWV*5:m=p8W=jMmcMLHAneDPL#I>^AnMTuP^=CctWZM@jtbC4yW54=/=
\&cZMD K^$/QMDD+wW8=AZ/y&cBj$kp\lYL+:peV*Dhd^5$PjH$*=XFCXB&=We\ae=Ia1l8RKmYjFNKhmKjQ65=
cwdNLL ^SeypuR\yMm^ZcNl?S1jWhKAXPp!1&juQW6FhZ^+=yYH1H<6*tH!6l%a+@%E=YGIcPbakX\ma$&qX\Ew
4@5DK! &e:6bh@<aR%AG5R^H?p+MHnKQ<6ej$&YT/6G+6:h6b?bGWF9p#pdR>PInDqjRlkVD@ht:lV$<$5ZFcdV
LwX6<k KIpB:H6h<w?G$/<q9:$ZiYBNDp?8yB^/*&*^BVHtn!tN%9yi=^?/d!6P=9F%Bhb<9<=latDT!NQeW#<=
@Ba&@b :tHPIkcaNTQTPKpe%Q:wM/DIyFw#4ChIN5enN&Tw>/Z5A&dH4bWZww^*$\%Fdiq8j@Zn8%%&/\/>uXt:
%duHY: C=^ciI=R!<#lt1P^!$nYS8bHn<YNh*nR:WGRLGAnh@9l<<\Ge:#=qFaT%kQJ??9919J5JB$Ect/DSE>6
et1K4: 4VSq%5H%Jt%:n$?Y8S@==#i89qC>ucjRdTlyMaan1=n>w@Q:>!jG:D1YJ/Q9=lwLJ@XElXQEEA<=jBa@
\6kBu# JHbSyVkdtN\THZtm/t94+hEyZWQmu>88!pJ\QStBd?Z=pG>!/^uqCJQJn8JD5H#I\*B1+RdN>Smdd/@K
4J/P:= >ZF95y^kn#lIREBS1a6b=n9Y:kRyqiyj1bh4tZB6c$X/D*@IXBZ1X+?55QE&mqQj$X^*MB>9::R*p>DY
YClEaN qF\/LVie!*4#Q6e=K+>T@19tZQqp8&LVy^9PVqujGEFyRh51S5WkEIYRZeE18wj&?N^!@#uMky?$ew!8
c:@P^p p!#1pMc^j1QQ%!IQ\Z5:6ytV!p?X&*pWb=lh%HcBSKD&Y*/QMA*kIu5*#4NNihiD1y1AKMn4<<n+&eN*
*AyRy6 C+$@4E@8ZClFC:dj#6t:1WGFBZK6<yWmt=n\l5w@DZCbKl4hG/KGy/*4%=:cFqb%Pl>dG@Ce#wlN=8W^
8I>ic* uZ1GiEwDdG9&A%ettF:8QiIPi6\/jjww>?QLG1Yh$<<ASFiXjc<=9XD#N6ZCl\\Q<?XZYwQ$u+\KLJRN
GGJ1lA wM%y%=WAQP^Vm:Qqh#eEcbIVukiZqa%YEQy<D^Y%=ZBM:VuDW<pQ*dH^t6Lhut^KyQjdZDa=+Y58/V!T
Y!R^T1 S&/<9C/=WVnmZ6@u?P&i$cJJYPSl4EY?$S#ReRE:<T$!9Q>/>t69<1*B&51?y\W$m@W8X6NlyCWP\?@!
cBL9:A qpya6XZ/Aqw$>@l/a=N%A&PJ=6i8C!QQH^X+Gm5<5u!QmhZK!XBydB#%4%bh:!Q^#<l*^4?HSXT4yW<w
am^cJW u&>^^uHpJ#8:SN/*C=/!<C5Eu1XtblJdRS:$6YmawjF6jiJbuNTLYC&EXy4&:K>F#eSWHN1Vu<ZGQC\W
-Aml*8 00062d1281e00110333 Page 96 of binaries1.zip
X5qTS% >H@Q#k6eL<K%:$ACbE^nuq+ViBI*=H^6tNhw+?!#K:=$&IScn%PGuNGy4a&/IL/$Y@4Sq:ncFTcT<GyJ
KkZ@=V h1I##yRqS=?9dH46FKYunymaL6m*hm$%jKP9wW^+Rmny+jDQ\<1PI&5BjdCppWR+!<K!Pt8L$<T/RLl*
Cy6Mq? hMcu5QL\MJ>Dw8TI5nWX$JpjJ?Rl&>y8Dn1<HLByB!uBRj5LuIQ+1^<4lH+TFp\NV@GLen9P^aB/a1R/
N>?k!^ tGkmDjwmk>>Rp5$SW5&QW6QcdATRp+TYFb9G=m9J+<>pjwT%&IV6iACC$TED&DR=8VSpR:yWD&c6Cj=M
?@PbVK By/n\clm%>q^P8=G6Yd*mTDGbY$\hN*Ncn:PReN@aXQYLukuSa?4jLQ+mJpmHDLMd&@QnFIVhG!*<@jj
wwqDp+ ?Nc:^L?lT#^!Lmi*w4dyJY6%A91T5XL=nqSPD&Ey?d*Cw/#NV^:Chu9FtCXW9CAZaX?cc:dCiL4CBGyZ
bVnMTS ait?jcMcIW@E/ScS5p^8JG5y6%lKhBldHP8@/N6@N:P<=$F@<MWRH^uLapJLY*45^AZ?&w@X*BTWQTu*
WA@jF^ *ZV@^R8X@SR1:I@18MkeTeuD=CelCHhkt8VmFLA<@4+d=tjp+e??<+qwXYbunG4B$mLll49np#T!ePtY
%q&LcY jpJmu>Be8/aS&y5Cke?Enn6Gh\w/Xl:8H$i6<&d!G^SGK>eHM?/Y&aV6JbLqYBSRRmIe*PV5*kyDPYi:
4QyH%N yPBAVLin&$1FV1h4P*T*L&#VWbnQuKy$aGBe<WuRHmbKX*lFDJ!DnmVwGPSHj1dATwT11ShA8pwPV<*c
@!NVH* 95ZF8Xi4pk\&qtMcHM1Xp#t*95ZcKBiti:a5pK&*AV!$86XjA1*4DVDWVFF5VQ*nR6YnBD51ALbbkSJ=
&&K&*w PtJbBmEQV*c$uB^P9@MnIZVk=u+alS1X9YjMR6CT<4:9TG?MZAe5^L=DBaq^ZdTDp/tTt&&5Bw8t1%ei
/?<Guc 4/C4w58qw?4wAN<qZTTZPCB>?eYjh4B\e6l^+GP1!w=E>9JEm^LIcy+5$CjFm+ucSjJ$HTuuhaiP!$:L
FB^hwC aXY8W$Jl9FNI5&eCPqC^Teu5PTpRqW8AE@piLBpSade/Q59wdpaY>WV=PKNViX&ci9Ed&&jb<c$&<C<S
XwiJS^ NdJj5p5#tju8CSKM*eyl%Z!MRY61c#eZWjCdIGqte1=:EjRT#@ap#b#kPY8ACJ>8duTDmq8cwlN@XKD@
Wyct5p L8Pn#Sn:SKM*@q&8Sb15i@T9?NKXP<=Va:nXNa+@4MHJS!NZ\VMQC6&P+1WpZX*WC&Hi:emH*9#w&Lb6
Zau&^N nX@KHh?%</q&ZbZlS+Yu1FChL*epX=\PMVahRWQ4tKqPkwdHeewENMXQ+6JDB:&iIN<y4Rk^1dmT48m<
Kw4VT1 YyGbZdq=V&uBn?6tHJ:WA%tyIQqM$Kaqq/Y$RWVd\%G+5w&5Ad^T9imcXmp5\6LEmXQGp^WqGZ/Z8Q%a
LVejqe $p$T99=^8Ikb@1ZTk%e^WtQn/jlWZY&G4PWYnDKGkEKN1/9JCb#8!bH=8H&Q^C^D5&hT#k^N55Yq\bih
RBTj/e +#&1^bW<EIwBF6nACdC:X9q9!bS#FKN6yhAb&q1IpPyyPZ#JXX^JJ:6H:EBb5+Z9W@dt/<jR$P@t+XyC
ICuh#n &j4cW8*T\ihE9ji6=D=?BW58BT@>9LRWDjuHWhL@qcXw!D<8uQ=YBENk\4<S\Z>dLQlQIlk1htWS@G<u
\+SNPu @/j@?j?#d9q9S:!K!wZ<bnL%4>AmX/E9WZ8R*$!t@lXc:C4$JhXD!G<YW@<KLZ\FGu/b&wNA@wmGZwY?
<>+DHm VHFBaH>EZ!X4q+$=R!CIQ/K9pnZabWwVI9yH>FY!B4&pRk?Bk9?I9p4YwJeydCnpn?m4bA%!/eqlj$Sj
:MBd:# JY8RT$?P?CQ/Kqt:ZMd?+!\P?6@l@$4G@9e8<6>pLAL&G^u:H\h#@48MFj8ZN+4@I+4JVHcl@^<9JqeW
JnGB9/ B9/6tM#GPqlb<kmQ9VLw+TyakiI651eLbFlJV+BH6CEPlJ#b$aCee=^ilQh1Be+*bFW/ME5Wk\6b:=b+
:uMb#/ j8CVG&%d9$eAJLJGAIXS8k11RTY5$&Mwb4jYGP#EGmSE+PHbt:bY1R/cL6LPt?>D?Aw*$aLtcX6RdWw#
l\tkPW VaVR6h!%qyDc:@lnIdBX<S*XHPb69TG9uXt/6>R96SFc%>IY:kleK>SA\+>uNGmt?B:VMGlkB/5HpZky
<=LnHb c*h1hI\#cLSeLWW$B/G%D*Qpl\*CbEjm^8T?hXT*:YwL:FSc9K/5<y1y/*RGYR^4dSj8Ck=bQ8bu:8Ld
@+GRTY 5FeqkGbR6M=uFZ>T5lBGw$eY#bG*pVW/y%DumwwlDTlw&aWyRX=9Rl84##>bF6lTX#NVy?Jd9B/%QqXu
p<\SY* L%@&FYu8d@^M8@<b\ZVmAR6Z^LG^=QAZl:WnkM5kwe#m@b*1upE5H/GBa=c<jWa$G:eB8%N!E+aBmYe&
:^pBtA B!=#Z#tReCm54=LmQ9>^IR/mhc/Ikn=C&phCWnLZ%VaeC^jF5Sy1*G%LTc9#+qy*:+nAAcN9ac&H5$!5
5jQ!c\ :+!lwwd>IcIF6<Z&T\4utpK8YZ^9hH?Id$^9EBBhCmu#h88Q1d9w>uaV&H%lREQIw?/MEXk86hbiV*+h
6!AuZw NP/KH6Q=L9N=<EDtHSNh&y9FyPaRyctTDuM>JM&imy=Le8XMq%YD4n5#Cyly$Xlba<5T?bFZpIB5eL/Y
yb9D6j dRcLy?S^l%VjNR5\aZCV&\WphNH/HmCBN?VI?VnKCRK@Zl*dP!9BF<F?BI@Z$W\+<uhVDC@t<PtKi5YV
nN4DkJ Gikk*\EJ<*8lWWLnX9u+dl9Xa?Ld!kFeWT9qiRwhyde?<IiT*dl?ZShYElR@aNM#t!d*G1by^yAh1daS
\RqX64 K>eVu=d\Lh*PLB8ue:LbIt1#QdI$mdEe*/+#16cRp?#q\Y9=L4MBGdB^d6:V=%QeC/RY1*ad#WLZNdtB
Wp$@1Y /bbFERSVEtqjYc4aiF=A5QI14M5tdWtJXk:1>k@jVVe*Q&P+yWF/D1leF<>P*h+Kp5</VcWGyAY<eZ$T
:WqbR^ <m:uQS$cT?uA=^>QMj=cD*GVViuF</KZ>u^YSkWeH9XY^ae!K5<X5cu<N>W&#6nkmuK+cW$edmAuJ9la
kEhEYK adMG%ZW@cW4BXDGcdZ&@GP8cI64!Pu+k>5M+NP/kYhW*kDmSbnF<DF9hR*Ch\Cc\QJC+6y:ZTlPZ6lkP
hVIw<X */Pb:1@LNFnH=Py:pSuWTm$!!QL+wuD1ZmLbVKJWH#MLHJ6kW>luwh#yDNpWEwjh8h1!H*i=*Vc4:hqt
un&ik^ yDLYB1TDh>$4%HPSi4cL*C1cN>I+i#QN%5^hp=Sd4h:nuhY*?>wCIeZEDV4eP?8=p1:nD4hFYj6YKINC
>PGhZ* :8@wP!4yJl6MXjqbJCd#5mcaYGMbR8AuYiQehYYC5=mTWm1H1ldiA&uc#jR+:CEZ>BFP?6VuMk?pQDT:
BGVny> %kDLZQITYEq^11QqeD/#ZXy8q8iI8><S5=b&@Cl1+Za#5V^yKb+E54D$du?6&e+uw%K5by%ByZd+&nPn
IjHylb R6Z\QAVkRjyY651QT9qtuHKm/9E66tF+5Sp5>QXu>&LteK9BM9&SP!GAnSWGakwulInX1IPilFXtSCAB
h>ye4M L?8=Z/8WjNP&E\KRGpdA!<j>/DccXyIp\AEaKFlcGlqND!?m^iQV$IwaaP<=E#LKlF%@QBueZEdcGemZ
H<6D@a >!81Nwq&%neXh/D#S<1W>JHP^n5/dhcy1u%#t!YAT9m&^6Q&TVZXV<mY4F&bGRJ1ZGA=l:P9&+8Z=kBu
bp+=1G c/mK^^5kS!lK5ZD\a?=Np86TAkbDhIJD&p#8$tqGqcN%^uwE4iGJ^$cB=V+^KKMEQDcC!bSm9eb<<dk6
W14Dbi &Z!%Huij6D4^PkSZ$+eRmnVciJ:Qwt%&t1wAJ$HeWEh$Ey/EV5RL1aZ4!hn1n/wG4dBBluepuTmteTV=
Q&14b: $pL6n6>klu:YI$VEI+q6FY/R+^KJE+uI<@X=9Xt?G655N=4icueJ<?>QJiyn%Y&%kYjyD/&SDKu=C%m>
4\iH8: +9:Xnd/IRa*u&6tG:Sq1X5>D5!$==p!j?*MQeH#k6F6>RwJdI8*A<$KC@m/?D&YkRbuLjTcB9PqaYShI
m<5#c8 6*5WXi4^8wA^TPaqjc?BIbQIha%p5uFZX:Zia#pkXXtlB<*n=Q!Y#<lWIMQ>8p/Daqm4bpLcy==n*6S&
TJ/6aw 1@W:P\:Nhu:!\qZ!e*P?5l:%^bQ!>HjauLSM89\t!4+/&b+wjmMPiRN+>>w1YYYkd8<<#deSVTZTKdm>
qC%c&< NXZ*mLYhP*84LaYhSM%%llFcA#9+?1nw1R1&h8KSLcbALtuk/%a4QZnLSISJ%mL/XuC%Q6tDYia*Bm+M
n#cuA\ ikI8?TPpV/Wmak*^yL46&6lK=#5G>p:ju&w@9QM+W/Hy/Pp?LSZDAwG\!>%F!AH1A=!#SthI\IFGhjii
L\bTi5 1LM+J%HAHat:qRWQM+!@\h<e*iQECj<l+Le^qtbcKGCYd9PeTeLuWi#n*k?Km>t<dIyJlBLZ+W6dw%G@
BytXcH =5aMKc:Lt6A5TXeA9XP%!9Tta^tBbtB#a?^14L<%ZZZ*jYK9\bbe<@\*<!eVFHZW?N=VQ$CQdcCMMB1H
A=q6S@ RYN!#W<J?ASmWZu/J^8jKQNHc%Kt?pM^TD^IB6=h#cF\tY%LHGScYHD<+KIDY$EVm>Jle*eHMh@E6u@l
p1<hCe T^#5n%&#&:ny<BaH:nnY>Y!9Rw+=ZWKklq4Z6>/djZ#+WLNSA6A5Ra^VAGqn$<bCbJDcYmRA#HWG:Jka
D!PeWh mRTA?mQ*iq\C=M5I\%P!<wTIYTjPFIEAawQIIQyHLAa!tW+5/p=V^Z:*8#9e5PF6t=BC^=GVVcK9yiW@
RM*c6B LE%$PXtFuc1Bbk6XQJHhldq1Vp+ZP>ZcZ&k1pQ#/A5X68$5jyVTA\idAV9yy=T$W%6<&eGHiN6?Yd?%C
ciQK/^ yt<AY=5b=lbjM1Juc$//8ECGTmiZD*VdnLVMRaC!V?WXIm5H6:4:+qRH1kjS&PjEDn#SD&PYhydpt?dh
WZ1t6c =VKDALQ8*4S1m^peh!mZGn=6:<u%e+<=Mj1*A<laS!!i<XeWEbHJN/8GIFQ!jYjD65C>X5q=PH:8eaK&
wyhemE F+dLMjISbE>Dq#dJ/M&/9iA6/A?Lh9DFiD8it+AP5%:YH+\dmdaqXAGnBW\>Y+C65Z1N:\SPyaCP>X9+
$k>uK^ ZhEEFqHD#cuCjhG&F@5!FQ8B:@EhNRC+$+#la$9CcWL:/TAC5*K*hBD+GaAK?X#wLdpN?m#PuJC9!/BV
XtXW@i 4Xi^?IHLh>J6y*/LWQ@&baIm4ERpc%T%%GLbCy\T6<bjA>nmen@K\ZDS\jJb9Ew?M6AtCIC9Tc<pje$l
@K<nub eBdeDPQpNmhwIk9l@%d6wWWY:PW?>?MLc:C#XaF>a$FBC&C#C<K?Nm!#^d>Ky?b$ZlZZ!dJND>!\pWj!
B/AhTF *LKcFR^FAXi/V4tM1WdG1yWR+^F*D=icPbTDBD5G1kVH1iPcV5DFQ<wMTwTYBb#6Q4W%j@WRFCw<k&*%
Gp&=Tl e@JS5wecYETqj?8YYl:DkmAZZ@y^BE8wABFLEG+LK:PQG$QqRu56da6&5i6&wKnHI5FDHphPIFIi9C@V
?N8kIK uJ1l8=4b=#$#qWN#Z\SSA9n44EymMCmL\DDEhNkp\u%JMLMAh%ZScXq!t$ASc5&@wb#8q@?\KZhGSV&G
&!Ll&= ^QXt@64=ENZWC?^GRahmIdnne>VDWE<QNbe!SHDZZn<iNaHih8S#QNVCV:SMCNbMR>nEdXZ+D5Zl$=Eh
tCcEG+ 9Ynj*t=a$W:/DNl4aei*h%SVLk^nmB44WcRq<Q>EJ@\i8PQWJV>F=9#Sh!Y6c%*4D1FSQ*jj=&Chih5h
a6a&Ap b=a8a!h4myH>ytHH8!AuABY@*JmFRc<bypSH^j@np^aZDMAA:GEWu:889QwcHpKuttATBK88yMaV+!+W
-AlNn^ 000548be67100110333 Page 97 of binaries1.zip
IZ:NR^ I9#G68pD**$9V4upL@Z^<ZBwndYmed#MF$/Q1L^WL89CXYw/@<\^8?NKm:EuWP5WGYXm*tETQ#WbLSK%
1#wRbq +dWHPPV$1@HB1$X\RnXE6LPQb=&$JkC=8tbQ\46k$aiBd@H^hD&mDa>j$tmPJST*4B4I/!w*PLud\PG\
=i<P5P /J!u*S86A?BQJaJpJWSIK\P$AE?Y!#&Y5k<\IX>l\c4I5k4T:wXw8FXATKmt=tqc/WIBN?yF4IC!^&iy
tLG%%< ?FZ8hSBF<K\RN+GR*VR9?&e\WcJLA5B6kwHa>pAauC^E+c$5<Q&8kM#ZcQZ4C1X?dYh/aj9d^I9&hb?k
hdnPAu SjtV^*\\P5DWYBW5n\/?**8V^NR+TESChmdZA=8D=Iaih*K*LJB=>MSWy%pWJK6SNW$ZMqlNGaE>D8H:
k%/!+^ EI6uT:cbYedqGV</LS1LJiMYHhpWZd/Hwd#DG>WwQw9aEhlnG1LmSS9GYl:Dh/%#4e$$d^pVhn^W5A9k
TuQEy< &kG$t/nILJB+e8jHn^1=4l1Njb!kKVb6maVk/^\4SRq^8^DqakCi8QJ1/cHLpKhVF#dJ*#m5ywT*kh6j
j8IC8l b8/Zc#9G8p1yA$%dRy@KnWE=H\w:/1kGCikH6##8LAhX#EQH#*>1=WuyLL&1RTFyikTp^5la6y:k8Kl=
Yckhpy dSMuutHnNhCK\8K>:GD%JNP>tW#djaM^yJZYY>kRMQP?npj6mBHNJB4&kVh^Mcy&^Yymp>mu9qdkt&Qi
p4?V$H IZ@6IIDtNZHIB=diJA+P88KVd&!9Hdt=wV+iKD6IFu8%iJZ\lnZ8645mKZw@Jd1P\?j4AXy\KDp&QRDm
ntS5qC !lZP4=yEu&RHJRP<$A>SZE^em8bMMMXIhqb$jGW^l/mkDWQ<I*KRt:kLkX*e5A&Zua%mH/SB&%GtwEb/
t11HR5 HDely?BNmPDHcHcLk$84#bB@uK#>*/dcDQuHMh^@N>1i@@KSm4&X=*@$H@@!%bB@i+AR@deH@*c4p#D$
:*b:u= *&bDlcE\5Z>:IQL*#@#>=mhl&N?@Ei#jVt:<N!Q8@deC>d<:hKnId&=?k9#n<P=jeP<I^D?:h\V<!8:>
1FRQwe **VMj^a>9%u!@j8Q=\4&@DhL9u?Flq?F9tVtAjKdJh?@Rw6ekd=5LS9!t!Zj9$KLZaY?yEaN?e&T:%?l
QdBY@M lc>AZ%cnl9^t!ji9$FjJ&tW%ckke>pj$XdJ&&Xw&BI:+I@w1YaPIZ9bVE@$n?myb?>h@BZ=LI//T6Z>%
Dnq5cZ #d?u4=I%!CX@JkFBRQ/I9p4YL9jj@:n/k@=*?L@$**@9H@@Nj+9>buMc<l@*kQ:hj+5K@><!<yW*y&i5
WHC*m9 @1h9V6NL<LjDCKCB@IkJI8\Fl4&X*A$6THBN^bTHWADaSAP5NDPkd\:KRVLKb&E=cRdaWAQFjZEjtceA
u%^ZhI 14+dW<m?j%?c%nN:&:8#@ANjHww&aB1I?:AlJl%Rc+8WQ$++lGJ4S^yw/59ibmb*&%WntRBbdYXTR4W*
!Rn#i+ TQyC^m\8V9wwiW%X^mc&q^lX+?+PI&SkRbc*B?K5I^R\4XaWnK*6L?:lNNNW69*AnN!StyKq&I%\lJ<T
HBEQHK wTZ8iZL+Fd?ulp1N1:bKjRDXHVCbmM>T5%p\9L@t9E\/%81wStM$?QnAG*yp@bGG4Lbn$k6dln$@GNne
Bk=LjJ NSnR@mJl5hR:dP%NSp=ujAcVyAtyLL<u>FGVN1RG=FW<S6F+VkPeM8aZquXZI+W&J*5Nm</JkY+yDy\/
5idJ#L maDZY8PeCaGyY8%m4dQyw>+Y?%+<!BABbFBY9<jPME$ZiC%JCi8:Ip!#jF!ZQtG%CXWy4MjnjEFZMKn&
^HwYh# lEbjV/?RFn&WbDeEE918iIhAVM&CSk$>:#G<\jRn<T!$BtlyL$pNqKcb>:^HcBk>+TH^&8NC9ER$?5QK
WtLZFK 5KK8%t8?>@PWKAD>GLP9jbhX^YAXPD4>TTij:e8Mmkb>V%I>?n1teR**$HFdFWPQ5&ZVpeHcpJj>+!hA
+K<Dm6 %#i>n>j+DNb8+Gm1pAY>8>N/nHdC#Bph*TT=pLI@dlPyl/>wk\aVPqq?6ehlSTWin#^hyj+/e/V\hclX
Jt@!#F 9m5R@Z*Hcdj8wL:F:4P8L<<>wtkX1a/PC>R=&TPd%5#t9Q^hmn5iLyG65pH*<&*^tAlk%\dlMDbqJ1*6
=u/@L= Fblh4qnki4wZ=YmKRPSFN&><1S@KDe1%SetSWmlJk58LATnt<nT*:#>u\W4yn/RI9/A=uJ*F8a>!<GKw
+X+hja Xa!tIJ?RNZ$tP6%M^BlI!W<BeQ=&@Xa?uXcKR+D&!Mqd:nk$#a^aIh^@eCEjS9dBiC+l^QYdeNMWuhEp
56Ik#: P$S4bFKdA5GetSI$G4b6^wDuQYe:5kH%Y&?bIMRZuElujTabFe$Y/F<ePlE5cEXJe^aad4VE\GRZ9=nX
CVC%6I #I?pi56AE8jBu@KDl+D=Y*1d8ebwH%lF:&!5ucV>@4cAItRC$$lN85y9@?\Fa\nYkbQcqmA@t+jV?!%8
CS%@Q^ Z6R&h9PudFiDKJA&*aYMLQ%eaNQk=ZRW%&QyWy4<q4/d?6ZJIcMZdLLWldlb&aX^qW8QXbeF!F<$TeEW
JBu!iL *Yt4<jSThQZQa8^ES$ZDdKuyX\\$c%thiGa*YY\dbiNC>Iypi$TQC+EE?5M*646:$j%MP*m15eq+kYHF
YV$V$e >4I=JyKKicc*\9dPB\qE%L%k*/Bc*cwdQBZ*%E#EM5>I4>PER\8/P?KKWltH+yb@*cNRQYNbacAiacmB
HJJtSu Hp45eL/?SmZ:/F9iSH=&^=6=JdP?dQQIcntN=SGFDXJi?^=YlZ8La+N^T$A>4V^nFW9J^\!mI9B4XX/*
<C6/u8 pE1c<@N<5q/#\t?5tKhne===k>=$<AAPA/@qN4pVX!YZ?B\Gc*<$4!VqQ>ij=Gh$*M\!5l&=pVuJ@?dX
ZclyRc ^JT6*NpEqMCq6:Zw&Mc56/*&LYcjM!?1bHQ4jbE9:BkD8ya9Ry9R!+JPM4y\qi\Jwcti=G<%ZZy9Gt>N
P$j$E@ hEi=*h*&yaMCq^4DcNG=T5T!dJlD$#HXHG=mPddb1Eh$=kXMRTBI>XQ&%*nylah*H6FG5$SQC@S@uLu8
:y$yeB >p1qDiX6Ew@k=6$9*V#E$E^XbQWNuP>NEPTjta#AG5N+NWl*XVm#9D9PPB%iqdAu>TC/d9h%lm#!GchE
$=DuKF Yl8@WmwS+u$W1<*>unBdb<+?@/P>?epd9b/bJ+\WEdp^J/yIA/<J+H\h%BQaM=y&c6c*aIn8I:FikNDN
+al*!q BWE5Ny8+F\/K>R<ibNX6lItWI&V*w?k$4h^q1?!>#H#jpw/&IHMIctCKln?Q%dXeupW+WlW<XEtacDdP
ZEVa1# hm!e$y:L8Cl:Ew%T/MLS=&DhK?JZ\XBET6\TEB!uD44hZ@$^phGInT#8EjPwI5KE^&\8E9dlS/FND8cY
mH8\>+ LCww%WY/LPFdSP8Y#EJ5hye<@$6E=lyb:a8?tH6p^bbbt$pt5*6G1D8+pm^cEqdQqM=jDk6<8IZ6Bk16
@jci>M &Yy>!*>mp^/iIIl!Iby8VR1tTM%kB*\i49YRG@%&*SlT#R+#%E@K6&1@R$t1+F:*lKC1Y^1TaPch&pVq
XJY6pY NPNV8K<:\RuW<!p91Y$dwFV:H5qMQLYQ6:L*K8DM!F*4NEnK5GP6K@jVd9d>!X4t6W#eb6tA=!Fb%Q8S
FQc^p& !?YNL>=P9Y:@:yTZ:m5mGRDR4GW#=RES^LuSKjeLpq1:6DcH/pX9Pm!JLnnqRjVlu?F$6?pd8\h>dcY>
+aB>mi <qMNHktHq!Y?V5kT\:<qXWlL%WhGnF19^A&&hFLFeju\di&SmZG*=BiW8PDbNW+:KkwTZLA>KGBMN$S1
X^\eS# w9D4</eLL%=GwluwXZnp%LeaI*j:<?BQ6EbeQQX&X%6=8M5Te5j5jiX1^9\N&\#HuKR#H1TJA4Ri+>*Q
1P:cq* 8$@G=9lI6$@#+p6^Na@ce=Gp!q1Je1XI&1H<S=>$delddMm!*uk/KmdaRZPXVkZi9pTY?/1:?8Cy&tTH
MBbZth >$+edP6J1J$Waw6j1e?/cFK6qQ#1Xj5=4puXYy6Rn<X=bTB!bk$kk1$\h=RyL?NSaaS&!PVRNd^wA$B\
kcAB+N K95W@M9RQcL1lPIBPDH&mII8naL%X\kc#1%!#Z?lq@<?Qk<+QWehN$kNR::\Gw$9@YZj1q%NXcn4QtqM
t%*$$n #mwk845q:a6DwAMk5p51j$i!uZ\qeL5RXplCFu/DYHAI#5$=EY9Xq/NCbQYXTMGiyF8\e5eH%lj5E@jE
9<!jl* u%>GL5hpWmtG#Ap+AVLK&!mMXe4@Hnu^pMAB6K8YQNJnG^w5D/=$JFElD9FSnS5a&Z?BL$DqlGh\RnmS
K<u#@9 c&XKkWKkdA!<&StH\F6YK*WWWm8B/+J6B+^P!!bFlK#Qm56IqK9d!4AqQX\$9C/F=bHnR+5/B/#DFI5Y
&1ciJ* e1tEdDN&9Iy9qSpj>6eC:X*y<84L\%l1AL=/@uQ%R#d?TwuXweG1#<R:NJkqYX!?Fqi1<FJaH1R>1>TT
lJ*dKP :^CM&HV^=i&c+*M:=#1*X$Bb!p&wlnd%S6Ycw^iCLQqdbGip$HqWQj4WZKMpm8k!k8jp=LYQSnwy*HbW
YC$CAu WFRa#k:@!tbXNAhJ*A9TPL^4ZRVpLy4EXbVEK>&$:M!N6wK8Wna#D51YHC/Fyewq$b!9S+&CLEZJFn?^
!/M!+8 lMeZK*hj^/MbGZB\:ywL6A<mRhFn>tPy8WtJ4AcGiJ9!6><VHiBZE+>w^LE@hc\@&c:9/FMPGAM^EGX+
P19>#1 CFK>wCLJ*:lB81dYN4wa5Z@aVlC8Q?J/w#TtRY=ju868AW@q<*+!9Rn/KDX\tm\/!RWG4P/16?8K=$R6
Md9\BJ T:W>h/FQ59h:aNXYVW4j54u^EDZA\YLERckn6HWZG6\RRb#95VkDayuK:y6R^Q*JFhF!J%6SpeY8D%eS
*i@+RJ u>SZCSh%q@%CJ%Ke:A5bQJcbVSPleGTkG=TwXCQDXaMpCi4pJ%p1kh/GcHInn@l=NeGEWJlCD^t:^S5a
=u1mE< nmhML9G86X&yy++w%IA@W^4T&R6iGyFteWRpQBel?9kk&\TG$&FCpQ&FbWEjV\4w$E/T?hGXZeje<!tM
cK&A9d \FJW5\Ci6/EaHHTH8k/YpKK$@X45cIFZp#>iypl!Xj5i%Gq@@aZa:6JAY*w/:5n\q8R<&+!u8wE/TC:B
FbLm8/ Pqq8BZp?iQiJWp!l=RcRF:DMbhe6%>daA&mPkKC/iy!yt54pu:!Idjy+<FGuqJlNV5awb@F^1SCXcly<
YIe&+H j/%:hPBy=jDN5E:?DiFdELMlqqW?l!AG\ptTjn=FnDN>4eiRE=PT^*X&5F$5Jiq6m8@EbJ4EHnih!$<H
=uPZ?9 m9A@KmMGXTd&4aHVk^QX/?!Q9h#^\y6DpC+@ZXP5<Cjii=Iec6L5?=6F=<\<C$uFkeVhH?Aq\FpmK*FL
b@6ZG^ P\bLCn6+KRmRp+4DThG&ZH*>*wIuGq%!ZH1<8e#L*a=Aa5cG5EmW4epJnpQ6YyB&uRSVSYqlDMCXK<+Z
^%Xbnp j/c?4%dZtl>E1%PBn@H6^kGN#=Wynp!:N85wQ5pR*EHq+=b5b/hMklPyamVq=$\*i:B<>Nm\^n+YB>M8
uap^cd n=NuC4TSKqT!?!<nQu4Lt1!ynhJan^um*$B6du*pPj\aNjb^tEkDd+cwc$TFbw&ENDI^?DD<C<X1nFYk
#E1IP# 4MX>bWcl*FuVLtp=EuT<t=mcLi6IV/$MHtwhHw%Eli+H4aR6bpaMylt#$=h8dDmQZMCeDP/ZpAZ*LG+V
lVYp*% 4eZWVbZ$HA+=&MZtTc6QnC%a59I5iplw+/jDTe1DNlI&bdcJqW^kpMhPND1dR!d1M4pq:L/4ShyBy91l
4nbjIu bFu!:R=%M@K4c!9!!WNhSEBb8i4J\kiY?=alHkqB?$AFK>YaGZ99m+mN!Cm%SZ:B/w!a<:6V94K+n/B=
XIGTMd 6tm6#/bta%::X6d&JRL1c1AkiX6qKJ4t>w$1K=$!RPyIL8kkNA>TZ%lFW$4TTTdHmKHaKm!PM?npJ#8$
-A8XM* 0003528821700110333 Page 98 of binaries1.zip
Z^QG%J ic#qJ:<jtlC8X#I6XhE%%*Z/nkR>#QNckcI!e/>QlRZcF?nl!FN4kn!JYji!8^BitFSH!aH%DeKLNFeD
d*56R> >E>=MTLY<tYbZB$pE?6XD>C:kmXjeARF*SS9QiRIL%:iIFm*e?R>FWd^19491PQn9mtydmuGBJeE<XB8
+M!>kd Q+/=i#Gq#bjMZ^XqXYnnB$9<j5N!RIIe1JP:jy&Wp$#JqYP5NyuR4$cnX41\4T9<XaAbilHI4<Ln#MV/
Pi:k:^ nX=p#Tdj=p%Qi1$XnwNGDa:D=1$V%mI>?ceD/!GpuE:XC&$e&5TVSWHI^DST1WteDWTK^^jLT<9h@:nW
$C44KF ?@?/F+j@1<AX?S<S+@<+A9#jhQQjVkET$9T&<Q4d^@@/YiF@6Sdt#6d@:hu?=SqeLF&6:F%5YTDR@!/b
:c4RCu be\>4j@G@195>4C*>9nQ#!Z/Q/m&^j==c^5mh8Y6:d?dqu>!PL>SZ@<t@K<ky*?#Rj^ZcPG4$JjJ!6>5
#5aE6\ EQ<XGuwX?nJb?b5N+4>C\/>A\^GZ$ak@wpY8Rq>/e6E@w1?TNhlqJ^eF@^F>qc^hK1hFIZ>EZ!X4q!/E
D><A#l mML?mL=K%m=hCBFF@BF>qc^h6qkNESZ>I@w1Yd8$GC+G@mQ/Kqt:ZK8L@ii>/:@D@/XY@*8V@F?%PqSa
#kZ*A= :DhcZi\*i>e\5Jnw@#G%ew9@n?>h!^^\$%THd+8H$lA:ld9Tp\dIcdYG:%m8$bCNcyyARt:*I\eByJl#
?8<#BP GqCY<naC+EV@WS^!8*ldRHYAXESc%hQJppElHt6$W8l1X<l/6+4iqa?@%PCeCZ/++WCnG8CM8N6X8I<Y
H+!#tu JBD+>$y/:eZjq1<XMBSn#hppWe#qNA1pKT/9l/yX^TVF51SGcPwPHE&cBV**$XB=DT8QQwuE?jDytYQi
LYA1Lj NWbAkK!5!/!tLP64dEqueF*hWct^KQc%4JnNEPJhu1>tAG1b5Y+HFPJySCy4e1em1\#S%uZhP>Ze:DtN
bI<9!& d9Dm/eaY8BPKa^*S1iqN1ht8bG!JLEk1qT9YXiFi:JQKpmXyHESR6F6wit%Z6pcd1^u$T=ZTG&51XJ*:
RXk@wp bJVE1\#1=nt+PVG<lV%tnb$Yl9ZVcq1tj=Q4uqV#iYW:/ib&YnkHh*1NTXw/b^wTmPGpARVahTdM:*Z^
iw=lV6 %&y?T>!wXb*YtpeI/=X?<q+b4$T*#JdTh>JWGNb@E:HlT:GX&tQ1&^wwP:%4*8n!^acby6I!a/T8C$T!
h\MW<@ u4W>>eHpFND1CJ9i&ap!6ZCYSq1thpwut6Hb$8mI/C@ZSw&Y#<c>&/L4wqc6w\e>e>IbQ>mYM@<+PR6b
JPN6/t uVaS%tZ5?j4aY<SP4\d!KX:\6bdyjBhhhkwNmSN&?VQaE&ZWGA*dMb>R!yI1iTRk1>+4J6?KhC&$%Va!
ld^mh5 %6pk#Zk!PX>mcPH5FecRA/Cby&4nZ?\XDTHMyFLbLNP!n#DH>>qIX#GmC6^<N$?9HY^tEIDWePk%wP&T
@!hMZ^ XE=Vj89HW6j?nt44$:WIX:Kmp:hB5kl#uXpj8QYwmE!qSd<1Nj9>9E^GMPIM8HT6ECu\YIV8@lAJm^i@
C8G>ll /wn$hW+C=b?M<TWPbhht&*V1i!kl:^=E$hQpAEd56D:EEJCFD#aRdBq?kuJ+EPY%M^+:>P8P9TA4jTbc
ym5MqH H/yHe98nRMT\C/HAVKGnT1EF<QaA=G*mwYu@ym5bec4I*Wwut<YAC1IKWSwC?T+TZMl#5LuTY&Wcw^ja
$q:%^a wFCw&$ZqHTKb4pVLYpjFmA>6<Z$64A?:u&Vq$:MSi>MQ<H=NmB%A<E$yX%EcdpW+\8ub8C&?el4\cZGT
FwEWkH tbZ^9PLIMSB:+t4iXN/N@eFWLAl&Htq5ClESVwn1kFL:IXR/t6b6:1a@ReyL\I?Z#DTCn8:#QjNQ@q4w
qmC@h5 &N<CFjk!KF/HW$n!544BTtCXZ1Jw4EN4qW\#/5$D9uHA1&6SG>mTkiqiT+AyY<J?hq=%KG:pdYlW!XhL
b96alq <yWM/9ZVZ<PPQ?&ecYM=FF9K&&SEue%/uc/Q&DqPBRQnCRdFEHB<Y*4D^Fee1&L!Ihw1mnWZ@mB4k/SJ
hAC5Zp q&qLCqHXLkmR4n5Ti+NGt+B1paF#w<Q\<>#Re@WuNVpMV##w@L/E&nZGyNIC:IJ!SXM*cuj8!d%CGM&/
DVd8Ei a6W=6mRc%%L:+:NhR</dpn5SVA9GdtSJbjR/$&m*hTN%IX1TbwHJFGQH%HNZh<4=$hVu/mC?Kp6\hI\K
/T\yle :J:MM+n*HY4jW^Sd=Y8NyELHd9PB%J#Dh#yGAQkc#culNQ5:=%KX?nYQ=wL?=Ky=k4jT1:M!AlQ844!<
h+dRFD XG@=&AeF&udw!++9M5tmZjK:e^8mHV%j>*aNBnt/**eX&CckCSn@lK>u+/K/c%1@$e\+dkwe64=j<L^4
N6KG8Q bjb:1w%kCK=JLYP\@HGE\DPLNhZJnSF88:5&@WdDFtS%*\&K>ab^6IWeJn1#aDJF184T+t*ZYDld1li5
?S$mbj iD$%m&E6PZM4Cp/$H!%$>\yyF6CHyQc+P&TphXctWDa@l>$Vp/mR?\C$RR8DNu9a@WaI+#i/>#q5waIq
5=EVk$ Mk!CG&bH#9CHSV=y5ckc$:ny5Zq#Ma@+%bMHe6!Bh!\yIkXd/NYt#R:u1#lh%8WAJCtH$CcVmy6Qy1@n
tnT4k/ QtKP8IkH/n?Z&Q?TwXL:9qXclC*bT88%6hKP\GdIP*8qnBiehy/N1=PD1AS<LNX+k81W8yRD@p4pn6P6
&yX^1q CS61qi!&/TAc4LBnhb+G/\iJMCFIDwFk1<$MN$kW^n4wFaPbj&Pw^KaH?lZ9!n>>uWTEe:V&=XS%YkbD
JHjhd^ bS/*/yQW6+yG>E/iWYGBEKqm?qCBFlK4EiE/Ej+5X9YQ<1ItjIm#Y4hj@JWNS!<&V@$?/h!!hi%/yd\$
k*WQ>% 6D%jbutH>9Sj*p8teuNDq91c?halBdDShM?upSD:^GkZ*mN=X<#KRFEXp6VZQyXcM:d!?4REHY#DYcm&
RZckQZ YXYyAHQ##dQH%\M5\p^$n1XLQ<9:?d!yZVD:#kd6D/>yK?@:45?jXGV6m*S1eyB@^CG4?NCh%&j^VX*n
innZjw ChehXB1uE$^hw6ykQKbDIwc%WhWTejyeJZ>F#\\lY>?K@9I\i#8N<N44?E<e&R/n^J$uwt$NBi1JM*y4
l#C+cm \Qu4QJYPM/?=BXSd%mdSn#%!Cw%8itRNMa#t/wc/FR?GdLa6mumZ*Z>$EGSA%J1tMH69k?+k5QEDhCm%
^d1@Gj a/u1bH8@=5qd9ReX!6mEcF:dP\WMLu%=EiRIVu?+*t8*a>X*6<&DEpd=Ny>9bNib9Rwt8CYnpQc/*u+J
alWTJl ?XWkbEwh:<W!tY\*weKdMd*Pyj=9Py8JAJ9EDm>u@JN:4=dkABj8kX<4d4\h*wShL>jPm5\M&CNS*YZB
GAbFZ1 <!RbHYS$LK=#*?#6?QqbTqeSXY:ARQpJ5QYEh?hcwEI!ADn$euGqIqII9^?y&%6&nW%Q6b@MQp@<pc%H
^Y5#N? Rika6JhX5Bn5\aebqytJ/e!8#K6>bF$aKJ?K^$cIS^L/KR=SY@w#JE^6lST%Hn\MEDS^/?9KnT5mnp\d
mZCK8= 5neLntQuY?X5I=PC8qqpEk:mnjS=<KqyWpl8lVc@/4HH4^Vj&/yP4S\#CA<NmXJ859bL=?!1mJ8yhI9B
$1W1Qb :P8%8hV91XA>!NF4L/!eS$q%KJ^*FN5F6#W9!C\TldMTkCw4C6QjkpRQXe5I=L=TdHcCyD/t>At/e:8X
yw\PXc PFZS:JuFlBpJXwHB:tnn4aE/>XuTATh@J^cmRmnSN1IMZ\6JipDLTVGXP$meW/qy=%hEdtMZPQG?!p=i
$i9qul bRa15\AMWdwYG*X6b/84R\p*9^q1$/HG&ihXtnk8lY:CZ=Luc^lSNBNaJ:tD8+C5$J5N1>WDGimFNa/R
BnZ/n# HB@dAkWPFq#B!CibI$bq&jGWc!?YTZIKaAWlCLaY6?QR\h586nhBKeDC?:eFZ#KXwkFAN@+mGqPCLVW8
tTy=EQ D@&PAeHT9t\pFVuq&e9X?h5qepd<wcal9mbI1q=5=A1Pk^4LIGi<t9P1u?yAaG=^+EQ4HJdP+J=u\%!&
lT6FRy +tAHF5NXWTDGLu6k:4CW$jILYK=h^14CS#:YAR4&P?Q%R?K^QHJpcR@nH!HhPK=8XI%ydPHI4TmlYuc1
yR$Q$/ qa>SjLT4>$WYH^pyh$L%qu>Xu5??Kcad@ZaAIi?Jd/BSZKn?YEl\ke\%YJ8TPY@p=9\GV4JNI:E\+q^6
J#GAuF =aP@ui1wyGBl+bhqRd*k9jcR\y^Km?Fu:1Rqlt!F/C#u!pi&aMPY5T18!N1lW!EAwRm=lcGu1PlcW?&R
lC#4aI /$$YJ+FFLGl^JbS1A*=R*eXhi:b@?#wKLiqRmXq6qPjQFlwNQBYR^G\BZ9hPqY^h9FXqcieXuB^9HHc<
bn*=5e V$mRQaa@MHqReIeNQ&NLEdS6yWhpE%?<</Y#edkIb*X5B/!<NhE>bWdwLac$bHNnZaBW/#1BBQwVB%X^
u4Gwu@ JmwjCKq$FW16:c4pR%edaWhiHnEittMPJ>TJ4#ui!wa>XKhYw1tiFqNZp9Zw$w$%b/@<?HcC@a^eYRGQ
S:4#+u <#kE@*VZ9!iHi&QR#hEC/XlwX9ZFBM\*KSi1BEjPjApVNcMEWV1A\jbQctnK?*uQ4eeq:%5nXME+1T5a
?Zu+c9 1I9jRpGIjL:JCuySh#ScBYAEYAaI<5T>mk^S&nXF+apyX1Vmc=dZTHYXiZEL5H<VnD/45m=hDEJc6#nT
:ZHL&@ dYRIawILBuZm?Y8W!1iR+D6KM86*+Rlwa1Wb&Ft#XmyC+B8e<^*#H1aw<y81qKMYq:jk$T>MlDhtpwtG
un#?KB W\WDGH5X!\n#hkeI1Y6Y$L@^SD/wnW#Gcl%B9G@p!eFYc<5LSDC8HuD<JRZR&RPdPe?lH*iLu\G^qX5F
<F@/Cl >\p:=XJyG@RKu5uE@L#Qjc:KQYmM?*N4T^ZCtRP^iTT8dQXN+^*ddtq/GY>QSM!1wp<6/1Nt:TNCuDED
JSXeNQ \yFBmIN1R8bu#h#mMKjYQSdHp=a$@/FN4iMHbKT$:Ea#p$TV6htQFPM%*bH/hW>T9:l=%5^dQS6H4JE=
qS#4pc ?&ll=jm>=i<aHCRdd=&cIbVhc>@hC@e$mFuY>XwGDCEhD@K41A$&N=w59/V4&6$6Kb@LJT=mDPpRRKV%
aR!!68 hPmE&k@VEcRDYce^CC&>4aEX$9\**St:6i?$+T:w#9B$u<aScHQPM5E6ED/\91F6K4iK#jS&RVNwV:EY
Ij/6Qn Tc:Y6lWVH#<dJLNWpBbW9+h8q>ZLj1?*$idPJ&5#%QPELF>%jhSIC%h*#Nhq<y%Hyjnh4?^4ZFTQI:eN
Vhe^%m dKuWc6TNEmwjIHGd#ebm8AeMYH4M%/uyeJ^YV:IdSeB/t$&/E=L>PF94IamZJhi>eKc?YQIV5ytcAP>B
qTAati pncyWGw?I>^bh4iJ!<=YyeacD/c&PZWcR4=4qlYl+N^N+:8YF46IRkVWYdTmBmtaYhyVp@Gbk6EltjF#
jSKIm* >n^C=Kcl%XLVhV\Gkt\$l6>6^GtWc1>9@P*VlA9B<Wak!$1aSe5IH=<WWWi6F5=Z/uXh#1qZ#$:9T?%M
c+A+*K ntVSdZ@T>M:ES161YmL5B&*I6HA1qN<Kp^P=P!BAS<Q*Kmb<6JnaK68!#Adp5:eM\n+EYu%$Zb5Qm#/F
*/!iNW itJN?WW4=D:C>uybiqQmmaNSb+pCGDQpcWS+8RY+Z9/cZ4/A>h9I+1WutZ%#bHQQFAn8NeR+u?Ta/tK\
*nJ*Ct Xt&yHhQtTQDlSQSDK%WYCDebRa^%k=@Z5^pVK#NVyBqtZ*CE?KuZPQ&/*I1bW/TANRK+1tTCh&uHZR#&
6@J?t5 9<%Rm^n<j<!wR!HC@&VWwSD\Xa*/*!ZLQ?td*#k#5c68dpN?5/L<X&nS1>CZPdQj4Cljuad?bpZ=N@Rq
NTuHSD nlV/t^Zq9$JD4pDDL=tkkQ=tSjt9$LA4$JjX9cG@YXH?K@SX5kc:yPaPBa9<EZ&X4EE9Qduau>DCX<uc
-A=X&R 000638c5c6c00110333 Page 99 of binaries1.zip
PSPR5! bXM4WGHlQ/K9pnZIyTiH@lF>qc^h=5Tl\9A@w1?T6e98kIRKm@\SjbY5ZY4Wwj?+IaZ?h@m@NPym@&E%
jKJHLB G\yD@LNSl@:Hhcq@9$FTBQy@m?yZL/4d@T<41m6mtN/DQ/DFkVq*LHqBdLq@t<:&?R@V&W4tpX?+cwJI
*NHI1R 6Wd4qp5yy86=X$^BjSWhDNiBqXL&NDG^@9aMIWL6iuVNmZ^LNTEW+lLZS:ITVPXDyT5>cGSkM?9T><ku
Kdy/%P TBY+lq5?pM8D@MmS<4ANNFT:ZWCuPLSX1wEG1IG*T1Cq+d5qD1JSWdp:XSqNQ$G8!u^DH%GD%+*pK6p1
>y6Zj# k#eN%C/eI9p&NKSGE#<Cy8Hk6+1@&lP@L$&RB1AwtPVli4cEclNYShj1/PBeJQewnajXycuihW\aHney
%@$u?4 QRb+#d>BhZ#hMYAAHN@F@#H&6X%V5^p&9!6nLy5uVFP4dac?4q@X=LFbqtnXD!$intJtKDnN/V4yI>@I
TYcWB^ AwVk9u!n%Q156n$iljXB9%<hqy$WXjh/6M<4/?aFG:F^^YK8S+k:QI+lkJhhq+%q+!e$MQSeQy=RQ@K/
HcV@Yq R+b+Su6D$KGM:#Q99T>Jb*S>eXbmb5$C99&c:TtmhlMtRwuFE%JumH4G1djJ%A&88&4Vc5=\Qa5JS>RF
DcA1ZC M*kpK&dWwP&:nW^?Z6>*G8a=V$9i/+B4McGubQ9aE#PEphXJjct:IIPe^w6c^kqqDD&c6ib++StRABh/
c=BnCZ 4<1KaeKNVRHXyZJ:jX#GKAP%+BM$=qZ6PeMi/TcHaRp=cpB#SL#J#&ZT1Z6:n%hb>&+J%y*l:aaa/JPZ
qLpTpu !nK9V6m>pdut*KAWcEd@WlLD&^C!WwI8+ZZiTP$SEiY\tieN8VINGtB8wJN^htM6wkS%#mP#*ZRS&DqX
$Wm>n# J1P@4%NJRQ/tpwd&GpdFQFa@JZlCB=nTNthFFD\BlXGFcjZtwVNH1VNddAHSVF1GK9uW%&Ehl/udw:\h
jn>B%y l#i94?eu5H4K8jjhpEw:MW5eK&Wn+H#uTc6ypyNW*B1qLCEdlu?aNjI&BH1kweTqY^5tuZwG4QJm:LRd
JGWI\l c&56K6S\dP%:FdySu$m!LP9kI6uR6SR/$SRmI&n9py&H*@I1=/YBwQ?APJ9wnK4jjXiTG=GMPF6Qputb
WaLT\k +9a&?^mP>6?qn>Yb!y%Nl?H$4WlZp\WNm1u&ludV55+>EqbMB9VWV?IbPqW>X^n%+Kt#/d<t>>JMHSeN
+N%R@A $&Jt?NAW:ynjdFP58C$$YYkVQJLFEaTZ?+8lcN>5JJL+hy%Dp=baXiLcE^Mi8BiI6lVINTKtXHVCGVLd
jSnD:< %1a*iDaq?t&8^LcNB>Tj16RQZZHAM>l&4EVe:<64KDQF4pm=/Gj*KEK&<</@Gu9yK+%</<6lI*IB*i+T
HYhIBN Ga1pK:P6=5q5tXR64EM\^h*yilEVQjc?Qu!dmiyB895tS8SN@Bhnn&B9^V#c5RuFaP+G%*81pWE<^LX4
D%8pVY hF1?Qq&bh$X4>Mu$5k4qdDJHNWa\D4#&b>1i$Y/C<8Vw$We*JNEP#1#W?<\VyDmF%?a<hEJZSai^deYd
Me*qW1 &qYc6C>SW:Z<$InXHpI<8i!p!ajlpAP?CRJllaq=anly!5Sh:jTieZwT1&F++n8Au9E<=adBV8ePen?n
l$H/X? eiLPtn9l8ekdQb#RV+?e=ZpF1lD*nbK8W&ZXl+&MKq*j1e$6uiiwCS\9>SJ*\BPQ!1cK/JLFRXidPjhJ
5Bd$bK j<:QE/#bSESL8TJkjVVnem>Ed^*@SJeT1*AaaleN?Din!MRiq4:wY^ZMZnEtLX1Y5@F%bdk#FIGqY^!Z
X!+#N5 C#N:eiMPHP=eJ:I%5QVm^A/wtle#8TKV9@Y\@bHGFutk@^e$u:^qq9Md8n1H=Mi<kp^t?eu%JVYa48kd
ZiilnB @Xb><qPlnN=SZCj+BLVBI/MQS&We8=k%8pjN/nuJ\>6<NbX%9k$dEYXa4?P@jA*mWC#4KDKIANKtSR=C
NZ!uta iX4ta/aMw%V8y=\dK4=QEM^yd^ybF:LW/\q#jlRP$?RjEhQeVNG!IM6<AIaBEm*cRen4G9G9SP+k/S&H
^i\J#A 1!1Ii%nPVclN#yXP$EM<Pu8ee$/QeD8k/MXytpB@M\XY9y:tW^iP8/e/@e/pE:Z&<y?GF$6pAl!n:Muy
+9h8hj X/p$i$5$^l>^=X%nC%!$<eZNYnLwiPItci>#4mYyC:Mh:Xt$X^Gek1cAJw$NQp!tl%=#6$YNKVIEaVTj
VKSG>L /6S?5w8?LeKc:B46+9MJcJiqchT%@>KiNk4+/CaR>$P%*TV\\>5TQcbFpNyM9w5=uHCL#CGJukT^>BDN
WSMuT# M4RA$KIHJ5:t\/qeZt*W:uw5L64Q&>RlC#4a!H!%>HYt^@1D:YK<!anbFVpTKhl^yLVXNG!uR4aNe$9i
cN!\QA XVB!PI<1ik15qPdc!XwSL=XFNMwtp>eF!DCmN?#PZ1qT64DjW1#kFn5Th\uK+l:!WE?p>L%F<8cXy/Ci
^uTb%l b6Ka<H4MK$cILYK6S$Hwk%F1R8Wu1VXnidIXJe/jk5ecD+>w1a+*m1Q86>5u9lM*XZn\+8aSJFW!uiA6
/Gl+cb I@e%*9EP^>TYVFHQtcYw::uh/N*dMIH*\QwLS@59k:tR<nThqRp14YHX!D6hjk=J4Bq$B=ke?n9PVE@L
nNie%5 d+mk^i=%QlL4F^\WQkbq%h*BjGZjV4^HHZy!i>=a8!<##nQJ5j1t<jJCd9e#icM$W/RCk5Q4&WhhYqlw
qpW@>I nhu*E=$paViikp?QP^<inhdHYq?VLXq:jm68*I5ZLJCVmE9//kX@V?%p/nn&S=L>VEcIjR8^Ni/4hw5\
Xnueuj j44RjWC=G4nKY4K=@G:#i5y+:5REh&aLASkRZIkqhmHA*=Hu&bHm/hEQqnH9:eE1kjD5=klAGEu@^R5P
N*BLjZ ?uZL@bid!dF^!peSHtuFY%GAFjTt<9QC!mPHn\eSHkmlt#H:5K@5F?j&QYXTNmh+pm=>t\SjBAk*WRel
u%nq^^ Kd9hi^<IFdq+Ykt#@bVD&wa6#@ZW8i?S:+pV^1?Ru#+aQ1@b4?WFdiPA1aI4tbiZbuE=u?LcN?+lLVS^
VR@yQC ZL/1P\B=$tImIPqa=dAIbyimWQ>m:p@eqcqFPlJhE=9hkBJ$/GtSS*uwEYA9@yuG#W$iHj:a/+RPpnCm
au^HHw 6jR+!T:4e#uFL:ReA<H8J6>=yp\$PBe+HI+&K*j#$y?WS5cHG5Z9J/aA^8I1WDH:KTc8D6llS%1YjpIm
nC$u4N ^4%XG>T1&<5+1\PZVeaK^Hct*R+SE<WZ1cjd9qHp%+lCDm>RmD/iNLKmSF%CX1QhV$^qK!EwHLJ&9Z5p
V^tqbw nhL1V*E5N#T*iejBa\<eD&9KJG8JG*<ALII=dtbbI:K1ch#S<dq+b1A9!H8EnV4bF8pc!y++P+alVTyj
dFnNG+ D5l/E5nBC^M&peNdV%+NkhkIAm@\KbV#S<4&Tn>uF*?DYHJae/PX5Y<GGGj#k4>!II:6*uBSKYiR$t6R
=Nl+=q tVnb+yntFlGWEHQuiZXa*:m^=GjadRA5+PMNe*AQZ/XYe15AR\1Jj5aw1q/Q?eV8cmHl*+&V5+EI:bB#
=S%Phb k+BYhAwER6Z6?1LIZ%IGtcl9tEu*Wa&/Pk5<P@%GIW4AeVaVNjXI49CFHMuL$HwMAj5FEK%^iCVwmyWi
CI*#Q9 y#pD/n&8pyTNVjSGQ&D8c!#>RwQJ5TXiSSVqPdV6^1XyKt1RD=I/ZiPFaN9hKX!4&9EJctWE?u=mZPdH
QDDpWq :XK*ty@9eE5K+W+hBY89+56DZuD\ZMk5c=AI1@KWWJq#%HbpP6X6SlA1GGSdtmAm/*lZZ#PC$$ehd>$q
L^PV6+ 9RXen:&%QElPMjMR<PVZ:m&YjWAApNM^n:P+/QA#9k$<AR5cY$y*&<cq\4Yn+Hdj=#h&=IT=BucZNVq#
bmc=9! <9CXwq/w8Duc4=H=:^qy%D84W&t5I4T&?>:KdZTwLtY5/9K4ERX$R9GJ%&WBN*D!YdMZ%&YRd%uHRuCQ
Nyw9yJ eH%/Jyy1nbG&/>j6PWmFu<A=eQMIJDN56e^=mump$FuCKGjIK<L+5R9FEVYuaRw=Suu&uRYB/+yFd9:!
CwXRS< IRyiaXB8<>84=NLBy%9K5JK^B!TcI#XEeVYc5!^KFlNE&tTeEVkKB4wa4$KK6Z8KLmEdFy4YRXJ<WDWa
BNuLjR MdtuJcC1>u5S$\&qZKDGuKRG/W&Ct>IDhAGdjuFX^Hlt@R\K*nS:8\!>MpuCXJyk^aBKqK5<YSb*aSWH
hmK+Pk Pc&R*46^IH#^Q1&>L^d5NQBFmAt8:NL@Y1H@/jWJEkMHX>VAp*6W*#YQ$#&W6a:bqiEuYPumBW#JyP!B
dM<*VJ KMbnYRFAB\nq@:4%CKaiA#?i?\Z:BQJcBjY<Ip*eW?:ND</XWa+RQ!S@AtVZ<ej=\FDZNA/Sip<1l6/G
PCHtQ@ ThCGT+RwGiDjZX@iS\4h\1q1cM455np^ihV#qp4F:qqpl#TPm#^H>W8PVmEEM+bnYZTKy6*m9lm=+1P8
LRuDd: ip$6>GAC%aCP8GX8aRDEuFJP\Kw#Yt:=F*QiMQVA*tbHu^TI>bIhiym+I^H!Ed/Khh=P^?VVPXM@\G^i
aIA\wI tHB=FiGD9!%LJhpTBSa=bEq%P=BPQD&6qF+n+>tTDPN<dV!PNiS\6LF=TeuB=XSmy?p#+lNh:F>j@ZVb
$>y9jk XB@G^Iw9qXH+TTj9bqZ>XP!/p^Sbm#\+&<hPpW^uacAVMh9lWpqaSB+pynucEK%>n\/PmDqwi6bVtFw%
9FC6S% =/S&?6JdmR4l6TZ9!InklbH4$+Jl^:%?RQtulCLIP8K??<yeAtcjmjcLD!kRTA4W<!/Qm6&%y!kepQWd
M4d:hN YQFl>pm8/XGw6AK9hM9IK<KF>Q/$N/ipuD!^9JH:V4R#R&MYIJGai@#*\eL#D@M@WFJe=FEieZK&8Rch
q*GBa9 !yb/G5a\98w>:%ScK*KkK>hSpMC:4D\P@ee6=9?X\lpK?S>eJ+HCSQ>bPMNE4m!e@<%B@Gi:<b8q/L<9
4EIQm= 6Q#@X5dR*!^F@^WcjlZ/MyZ&t/Zw9$KLZIG?dF<E?y8q/L>Cm%&F9p!h@tay?1@R\qikL%ZG9%tK@m9$
Ghdb4B XdJ&&d+IFA4:I@w1Yd85lA&FI9/I9p4YwInLcNE@w1?T6e6K&FAa?I@w1&RNIuIbDjpn?mybk%^/e6kj
Hb\?FX $XjJ&8ZC?S>uq>D@D9>Z\9t@6:d@Jy\S9/q\R@@nINP@L/Q<!$9/@=RKh@d@q!9ejH:XEW:lHnVAEmp:
C&Q>P\ G4lL&!jGWL=HWL:wIMWNeTltb8\N+Hali1R:wkGdyCn\IbIJpNW?q$MT!Nd*tpQtZ\jF1>4YtFTeB5!c
Tnq^XV AAti>K?^Hn$&k#H8JbY6&FdqE%1a+@abnhA#Z*Sd:&&yZRE6h/*Z/C=c>6eIGJCcWF+?1pP\VX9Dayy&
?#6u:H 4DXHRp&V:+WSDZ1w^b^?5q>L1:XY&JPRb1J/MIRi=I:=^N>F6bNGA>Tc1KVywychwTE::Z^QL?CJlTW%
R4TMD/ n#S+uA:ZuJt>SG8A=*41q59RCFZKP8S+*dJ%LkQkYHqp8y9c?e=%I&FNSN8M#upajVZ@nF=#cHZDQF%P
9iNl!= 9\=laAmiQIl9+5SbXET@kTQ&!ZKPqKdqwuqb:LMQWZIjaRN9LEWER:?b*KC#BD*ed=^VjaTu?1ujPBaM
\M9pBd jVAy*qlJh##1VSKk>R9SWe8/?>!!kh/tMibd9i!41tTJ#NbF<^wSl=d/:!d>ENTM$S^mQNE@k&9W/<9h
yuLS?i h!W9BlnimtBlFcHujZ&ey6ipIl#=?*hn8IW1SNGCBM\!Y#D5N+@6bCM5>4Y>#eXRZ1NCMe#wyQB?<AWB
nuh:&M Z@GQ#>KqVedpY4M#l1d&Y4I*>W$:y?=\M=ThV6VZlNTtwIW4?X:he:QI$E%nEDXZaKH4h<w^yh5H44Su
a+Ih88 ?qdQhMe+DWRBBApp&FjFZau19$1\QJbj!QB&y#DLNttenGV1Q?kuyVj=5R&P%Am!F<!*@wTd*Q\X>QDH
-ASMY8 000c725b63c00110333 Page 100 of binaries1.zip
EwJ6iw \+*XqjwJk^aWNWm5LD1a4q*WcDcBBmAk%b^c8elM<<AdE85Mp*:>C1AqHBSR\6^TS8QkPFHLHhlbP9&<
hmEQP\ B^^N&ch9a@$b$#bS*@>eM>?+QP<Mj6<pI8lB15>mZlbD95$NY6d*iq8:!n\4>W#>#<1kd4Q>yZZm\NSk
!aCVb4 qP?B/BC@y?TJIa&G<@BhSwqXDaay#S6pAcF\iZqM=LnFAFmyYEklDy%9kq6uelBkIYZ6F4uWGwmJ&tkM
/a+NPp FjYjq>LWqt5NMTp?jSIDyHhYAdhGyZZc$1h/%5XRj18+44jLhp*&l+1nD$+Z!\w&ywW:weCeZmq<tY/t
b#m!9A VWRLQNFWNQPBecL$SZTEm!E>A%FbD5Ri!h%dDLeFbDJD?Mtm*Y99hnwb6nj&pnp@TPDX9p<T=BiERmIN
GiXyM# Wk5RBZVK<+Iq$18F>\<dQkTcppYq8TQd:>=+Ly\IRNcXhc/NGdcy*H8^=8+?uKRlNR*&euE58yXR@XCZ
=/n<+h TtuNNdm$kC65b9Eb%jY$&<L<iY+H%:DMDpC:#^B/up>Wa$%hn:SC<hn\DZqiRTVX9ESjcVD!b!#^D!6B
RW:ekt =T&C:H*dp6m%=TiwpwWubyqT$u:eIY+aKN#\VXwK5wymGSnty#c\N+1wiF4$SkqY8Wc9T1L4PCqhV4jj
bh+kwd npq$54S\<lBN!YG6+kW=S$i<5RlTDlHhY8SSHcunt/cFPG=HBIV#XZ$X#!>Z?FSp@aC:%R+1b9dVSF5\
%W+bi? eFL9B!<it@=#Yy6pN!5w+N6^K>&*wJ#FP4/epJl*p=RFP1iIpZ=8<hEwic!<SuB4KC&>ac8hy%aW<$l=
&\t?uG GFY!!nFCI1KSTcJ^!Kb$uN/GwD\^P??/EKwcDPWpi@C<N!&mZMDG?yl1q@<SatB9j1B/^F^ERN@AdG\V
lj?I<W %ZTjecBW?Vw:6+P*1=dT1emm$!JJ#kG:=y=h<Nn\:b8*b=V*NI!CJ>tVJ+4T$561S+4bc<#t^je1^!Yw
#cu$?l >J+#S5W*uyj/=%h^h5^4YYNBd>ZSd@W*&EJtWy!Ab/p/k*jFiE$=lLuI5<MKHDeiYVB>!TE5p*yLVPLD
b>Rd:1 E@k#p/6!PkR&bm#nX\taqIbNw&K1a!*AR1H%HyY!mLKE#tZ#PwG1XiauBi%b1SIl:\#^km5a>t/uAV4j
YunN6C QXb@t*dMN&TJ9B*M5LJ9uhB1u!a#MHEK9nlit@W^WYC+Ftp>mF8@?nL=IctylN4=tLt/8VhMlJ^d+K$@
9i5j/q TPZ^XD\qTh9+<=Wj\me9#ZcEqNE$H!uKW4mJ!?XF:p%>INFYdab@V48JWnWc8P*L@Y:n>K#=8d=1+e9V
jaG6@5 >+\Qj^d6CNwMBHnKpKFwXD+CP$$e1bH/ap@==+/Claiw^+@pq&T5n#?+i#wD/&+aCa41*naSZNWaE4PY
bW:^KL >d^ye1I<=8icHKwJ&//<bVNd\E9V@N+jZYh$>wCkPCTFENSNZ<:ZH?pitTihe4Q/baPAE?>#Qa=JTkI/
JQQQdP #niJeJN:ST*dIDctu<FX*1E\I6RL11ackJKyRhqJDLQP1dNQbFV!?&cYF^<nDRPMLAp**^IH9==>P5%Q
X=SN=E b44@ueed#mRa+ZBVeFXk8Wj5E?LnPjB%h84<?%d%c?6C>4p*P&PKSu&\@5ZQZ\BeBIciDYSbQKc/%eZD
BGuT5A M&bJ>>bqam^e59/:9F*Gub+ZhAKmPVDk8B8pJa%ci$Y?&Ri5<BVJ\L94G?PiH5RZBT@>^LWyIj^=>Se&
L?<+qN eP9VudMh!*j8ijC>#q5*5mH6IiH:wkSb+Y$6!YDDWaeNaJP!EPAt@+6WKwmYpY6W1M8><I^^#kC#?p@e
d^RE@$ *4yS<?&Db$yNIkDD+C/h>heE%=SuDq$nn/p?Vb^F=p+Z?#SGt<YDLd=d1nY\>45:4AMEH8SZ/b^XD&h&
eM/&qF X::=<H4HJb1acLVJ/5iyIjTH:9qaDDA5AqK>>FM#=D!>XDG+I9qWcGNyu:+/RweeVGc+FjyX#t^Q&eyq
B@+N9H ^/Hb\TW:>Ked*@EZJ@:>A8!lPk+Bn6&?6iS?L95SPXXjNMtkW:PKK:@BQ8w\tllRcR#k@Tlw5RAIHqN^
*Nu!A! qY\G:W\Q:liRK:iX?y$I/b^WIA:*/d>X&Mt:Pp&G!8^?<hq&>RMNB%^Vd*kWY:/$hQcnp9i<Ml*+Ji*d
1#dqES TnqRQji:C48Ya9ZT@n#yq!cwYh<FpiCF55X+VAA^^$b*!=b>CNIchN=EBAc:+&6FaN\=eRkA?G>We<kG
!K6Iu5 pb<4Rm%LiEB&+%VQ/PS:iG5DJ$DCnKawSXCwuj$wnYWR\q=SucwKE>tCH11/P*S\h=nFRLZ#LX*lHnT1
*C<Qdy 9EAyY:++BXnwY^+<I=kuW+$@n\h/lPeYm>j@BS?9H^@%GD>IBLCIBqS1CXd1Sdk!J=NPHKpCu8>:HR4?
j%BEY^ ImT+^\\PIw^FCC#dHA%8E5ZKQEc=HEeh!#qL!R$=VT&DX<69j8<c?e^uBA?88EX&e:X<yp!^jMJ>u+\I
q14Y<D S+WWPSdV<5lb$N!&jq4RKSnMiD@cS4MhMGqX:/Q$qaCIj%WDQBl?l*k6YWE\?$E<*hakZX^FL*uXP4Ge
Y46uQ$ KuG5*8haW!BAk5VS+X#h+/i44+4dc>KKhiKS:AyX4!/ycD#pEaQn#ljlNbSAyE>F@FhF5?jFLXm%<EFP
:c+4hS eW?1TtVS$DHbS6iI8H1<^jGP*=MDA>YY4et&BcCG9=%RwJN#+T:=M8tG^Vkdc$peAXq$=4e85QI1JBu!
$kIW8R >X45V$Bb+Wn<nA4FAi:kKMC@#<WP4PIed++$F4SPXG&ZTT6I:B$#Ca>Xlmlq9%ck%*Z$NS\1qZeJD+pb
BuRPwu F?IID@8Z>+ACEaHDLc*AlYKQDclNA%awt6IPyeJQWdJ#9E+yll8C%W6RdLKe&cYT*FW?jKCmN8HyN%Ie
/?T@&? nF!Y5R8=1:jY>6*Vu4KdZq:a=\u/y>\Rw4iL>9ctRSAqWCII$CAjA?KAYFkHmSY?EP@lBI*CJwii<?dj
^Tl@Dm wWDcYWQDk/A#YtbDhqY5n=C4QFTJi%XLM^4y1T9Q<b%C\e+JakIy&^\^5$iuWLu!PZ5T!%ItaM^*GhcJ
X<RyS\ +MJpQijT1K*Ip@a%qdnV>TMJu1ZC:ydRZjSPTI/JRh+QI8eHSKYPDM+u^H\W*X&mEN5WC&IL@YIbWCjR
?SYeD4 PZMGFQ!YddHHRM=Mn\?uma9XRmNe1FbZ5bi@He@pweWFWbqP\yB+wFjwSF!l44De1t&6\PKwMyyJNR<b
^Vd5F/ WEu^pbAiBB8K+uCqpj8II6GL6NFpY$\n\u/Bqu4#dMR+wqAQ=Mwudib<6HS98Aq1hymnHQ!ni4FNBBqS
VZelcJ ZSl%GP@V<J+Wih+SK#Q>9G!\atM5+EtGZWh4IWqeKE6\SKKlEmQY9<%yQTcJ%m&=5!M&kmJt\AK>e/H:
uS=eG5 #CmJ8Q+#mWW<5natH*^kH/IJJkuYq6WGceMneS>=M?56Sn:u@wLnyBml?RbP%JGpPBZV5>c1SAd6&TF#
6>J*J# j<aDceiLD5\8C!PGDMlN<5P*<DAF%Ib&+Bd9+1BkI>WPVDJ*Jt!Nyq%i9FFVV@kb^c5Jk#camauGq1M!
M=&?TZ dk?HewbNcA!uYStXCD#c#JaKSpBd:%!CdI\le<=6qTmm65bn%V9&<n65X^n8=+RF^n8jC>b<M6Ae69X5
%DQ<E+ $F9#:dCb$#wRh<=*X:KPyh8+LaJcXS@lDpT>R&&XBmFTaKi?aA=D=eT%>PlS6i:Z/wRhAwwYkZI/8#4%
iZQhk= Q?qiPb=/w51V**!=4q?^e+>LZL/9<ttH#@4WdjRyi=1kn*#S/YG$XiBB4i1R\ei>^Hp<\A1i#M8<iVe1
D8liyn ?1m?^Iekm=<lK4jN&6%^6pwy>8yPq^$LWqb589T$c8#CW5H5<^I4XT\^ti:6It+^H\PHDKbA\==nu/=d
h6IeGn >G$+99ae>Kl^hAn%ny5j*X@DZQie6NRm!Lp%=FSimHiLcJMDyVbFlV>^u%L<ADH=%hh=4*:^PT6\Y5q4
:RQ$k* %YQ^m@F%Y+Qn*8\HjNK8EXC#DuMcJE&SJt\6?l\VyM9$ila*SP:Z/S^/nWq%lEm9jkA\QR+QEaBmDDI=
6q^JAJ +\ZC1i/Vb5BBH%nycw6$j%A:TmpRuV&1iRQl!6kEI8PCb+WIw+LkypESiMcSFmK5FC\59*ZX@:l<@L@W
ESYp:c Xj@nnQJjeNWm9!qHm%!>HI*+dVpc?y6h=4?QmF@BN9>tq@t9$JC4$Jjb=6@5M9<XGuaF?qLd@J6h=4>C
CRS#EH I/=CZ&cdj:QL@Fhw$T9RMMRqF8+*8<^@kWbeJY6R5W65M?I1YaPKZ9deX<pcFHdbe$Q@mL=K%1CZdEJD
VnIVwF EjA@w1?TNemqJ^j=I@w1Yd9e&TL?e$u+:@B@/Y#@*k9?t:Q>*bw%XPT*JYG+/Q<6CX?>JP#$Q:$pZKkw
wPM>Ad yEe#SJ^6F\L+Y%pZiqmaNlwc#TjJHEJ^b$P<hlhae:*tRMYTmcjIw:tVpLi!pFZJXRW<1QSb4y/8JEC8
AIK?@E F\!KC%cRAwG6#5:lARttSKA9b^aVBFp1J5IEWD\>89/eF@eIkSZBd@EG@hGF6EwPK*8uSKw$JMQNmVBt
W/?:Wq iM*uy6J@uLp8#RAEyQ$RG/yu*l<C!wJk#$Nw6p*^t8E:VjV9!e?5tKVdFDEVSIH<IwLNp*H/?IBK6!VT
m8+unp 9q1XVWjDc%LlaG!PE&IcY%>ye&FAhiPFEkFiuenn8q%cc!<CQQ>?P>=K$5?<$hhRJWSVPkdF$#t6:el#
m$CG!p kl!/&%RV9IquGSW%mS6>Ic&Buq#RyBB46hbSk9J#k5<1B=HL+Ckyeiq4ihdKKtZW$1T6I&cY?n4ppY$V
hFS=WI T=?SV6P^Yu9aCW&WqmVNqG/eaZE#k/El%Scc/TA9lAbTIte:/Ked<N=6L!\Qit#CBHcay8&bj1<JCKB1
L8%qbc Fy9++X\H&/EGV%Y>W^B9%JjTWCawR::pHSujFRKV%a=JQG/?*hR+:tEJw?^*n5%*:%%Tuu4YP=Da>W^T
aP*:4l Ht^=$LuaaHLRG*%ZFk&LDqJ#u*D\K:5P/=@Cq4^!jpb/>MR:*e@kt*9e^?Kb>\^iJjS>VSic!@hWu$a9
1lP/b! pmNM#Zjqd>@H*XBA6e%K/uy9qb=X6ca>6dmtL1tTwHW$eDyG9C?H+aq$p=HqW:ut%JI^uD*uWdRJCk^y
i>nbj% Gw%6Q=Hp#lWG=C!tMHw\T$h+y\6QjP!lnpm^eu&VRDWN@Iu8wJCQkR6u%cD>Y:N=bASYCc5Z*XJ8+<b/
>%4%81 SQ?+Xq>*pZ<n4h^h5XKRV%:GcLJ>TSeyhpRlC8=JKBS=\8u8q/iVHmpL6keN*QnBiM#1eN&<pERyui%&
eJY*4: Q4cVtELW!FF?>1%HCR*I@LEV6\96HX&ZJ*mp4!IGFD6KS#+8c&w&ph>8E/q9S+hMqb#DKjQAAyadldSX
iw^lFG !=cddi\RKVMk!&G*%&aAWh:IEFQm&>GA#dPbIPyN/k>n@aFWZ8i!*meeqpabH8Hm+m#4MD@nLVMyJ\+J
PXu1D% @Ph4#*YPQP+QXkq&i!GCk5!<ydd/6AT5MJEj?m1AlXN!DYLMhc^/*KD<K6=Zlhb\T5\9#dI&=!bSc+aI
G^FynE &VDuwm#iMISi\Y!@n/PnZ6WRMk/a>K^YN1AYMVnqj9jtubeQBFat%H%1W@CaRKGc?4Nbm$8qll?LZ=R1
4M$u@b 8?W>/JaG<hPtF5e4+LFKjk=1yNSRCqHLcyhH#u1hwiJ/XiG=wkHD<VZRVi<9599aM:YeZWX*TqP1Jh<K
d+$IJy uyIhTC>6P@:$wV%8pJn$lJlp<J^+yEGptTaGPJYu@+^5qQR418+tQC&+^^+W#YM#bm<=$PHTujDwhyDT
8Le6$C qGJGZ?A4&thX5S9/Zhq85?Rt=/JEw+CWeZE*:SIkR+H/8:biLyiXGahnF$?qXXmP*Q:LtmdjaiGQ\/V+
^!K<+5 NZnl*mFiiW@=8My6Q?bPtn=Lae#VEq!#XiR8*SDHG*&>S5LGwI$be*dEp&8p+#nnj6T:Q+GulACC+4lj
-A$!eI 00099fd7f4e00110333 Page 101 of binaries1.zip
Pl#MDw p=@S<F!ubl^j#dkj4T@=Du@W>YbCc==kL%VyjFtQXeL!YW84=e$PM&b/cmehNjm&&Gu#=I*hNL6^*H&A
9bqSJ! >pWaupCa>R/h&l6Q!dbpT*\:*Ve&Jyp&yWFR@GT#!WL^^Z/@qTWtTc#VD/$%V:NwZ+GGYQ*w?cT8Rl9*
n?k9q: =IS^id@5=I9*#pQZabyF+&AdTq8nP+ItG^Klnc?Qp&R<jyHa#kuX>=L<nM%uc6n#Hb$=KW?Tn5mSdqpy
Sm@akF \<^T^cm>YC+jyV$YCJ91&b^VnbiG<WLb9l6bAKVD9V??u*=#!%8#:*pG+imAI5$*wtkYAVJTutpFYbNT
Gh?XS> 1y*?y$4i*1wJT+/DMY#Ap5+H*VdMC@R9!wbw!9i#6a6i8iHl9%P>wZ\LccVQe96AA<V^aWnZYH8H%R@?
&Gj4=n #d9JmCM%cEX%=Nq#^YP=AqCChB5bbm$V9mb**8/q1h\R1!w$F>LL$8=J^QNNk6Dldc!$BwqbdFc&cLpe
iGFSMa Bt9bu?BJ4KQJ5qG?KEn!Qa>jMXqQRitYdKF=e&>A>1n%C>%\JKXX5cShKE&Q9^$h*hCSQp$Y\e<k:6qT
=LAWFp /R?ybN\VnJF&jd@IZkTQ:X+ePAdIXMJI9Ht4X@McaYpZH@&#BqH!9*SW@edu\%<K*wXu6/!t\IJ%:H8H
+VwN1R 9h/T4P4TPjnKSJ4#J*pu5Fa9PFR>:w^Siu6D4W!DY?IF/<6=*1yDpS/T6XSJA<huyl4*i+GJucwW/a<D
+6DHPl ?ul/G%h@Cq%k:Lt1j=F6H=qu#auWTYh4T++YRnDlS<kNk:VAMeE1!i/Q^w/<D$nmJlm&8u<IYXw4t@l&
#&?P>M Z:MbIQBnQ#qP/B=nDCK\N8L^>lJIJW8dVtWKL6ueIbFt+yJjKu/89AkFIHLH4DPhDcSSQA6bI=BQhacQ
WVQicH B9tuZBKm%jItRb#%NRln6^emh:H:JPItV&XP^X*%8Lu69kdy\/1>L9n\Dty8LE!hiNyTT!9n9=QI=Cc<
C@:h:T L$t/&XRK9E9!wGand/6hSDVkTM$/PyyZyeulX$P!JhEwPcM+?L9\uS9M9Pb$E4^#ea+ep49h1F8!XlyN
>TSq9p !/e\#+bHWX?Kdh/nR>i+yyFP/^8q@XV*eWc<k/i!4bX*&EVqZFt<8y^W<m:tldmq<$j&Rn&$LVe\5T/w
HRS<%c #AZd+i\XFZDE>y+1<am#hialnq&aDY6/j$6Y>BT1GH>CuZXllXqn5GMu:%RHJhtFdTlW/8nwpHq4M:c/
9?BQ:T e8NcCZ+b#^j<dy#qwAEJ9Iq+NjCSFjmlpM:B!wA5ija>+th+!*1&BakajA4>L%aG=DTd@iqqlG1#Xw\i
B%9pGu wXMY/F^*@QNA99*K#AXPjnQ9!y=?YSMubHk>?KQ$@pV%TKN<ulmb9aq/la=$B$B/KBtJ*pFRKIAwuD#6
$JX?bJ jkFZtV*dXatJM>TWL^dm:p1XI#&e#*#*&F<Mhn\WVM=^Y=w4tNmw8kW1*TP#ebL8$IES*CDw*deq^Xe8
Y#Siti qZ#wRQ?8#e@XCw?&<!hKMZ%wc%FH#eIQtL6YdPi*=SJiEW65PhQJjtdI%^LKl6/\G*1K^ZnaLaEEQ6aH
<?&!9\ n?R+A%AE6V4ILc<>TJZ\R/?mb6@a<P*I+*YL#G>5wy:1Z6/>NuQhl@j6!?GFqZqpH=PW1?Xbi4LC!t=%
644SGN l=GP<p6RAAtAcRuDm\*+w8bXA:<I<tE5C<DF\!@AJ?Z8<X<m>>u>4i+MmqbEN^wFM%@aJFduJ@=$d#y*
^S4Hqk NNlV#K\XP5HlA=CW&IR1T1FIdTVqG:!n5L<\D!>YC#l6DqHp\EW8N^Qb@abuwjyS>N/KNwCC?#kEb?ih
?*>^Fh QR>&d&4&h4^ih@ny+cRjW#58FLthn+VGQmiL#/mSNduw=j:?=RRHqi+Ji9J?>IC%G@5t#P:ZP8jIq/Yq
dN?8pK Ey1/iK$1T$PY8J<@ILpQ6*h?^p:>dMH/!=jZau#1Wbq=B@F?#=I=&4T+PpQa1>dYB:qBuc^/5tdYRYk!
y+wJMq puLNNcimGAm<imFWW^bTj6^uF<tLK4Y##=c#QGC^Q4%H=E4Bak9k^*iMde4$DE*FY@qanQ?4AtXAGS4H
:1EFNb w@ccVR>PP5q8>a/:5^^?=CXdumPT>^*89JZ8RL<1=JYS$JK^W8\\&CqP^HQZ%jdG*k@waINdT^9RBW::
FFb#?Z BZLjj=%?c!WjGL\&t9KaQ$dJ=cFdT\a<89CW+BSN<QMD!T4C<wEW5PTt=nw%%\N11>L5Fl6HL:JQTN\Z
>Hu5YJ 1L%Q:j5pNu1TRh4*KN?L5cCJZbZpTlkN=J9WM@i>l*B?8ii4Wkh:8F9THWP+8n\pk=EQuB^kJeQ\R+#5
$!+W5# /L*4nnFe:S5LET5a^^a!#j%uJP@=1=dW!mZXYeI>dYa=HSBJi+L&uT#EyH&T%IYk1QCmaCQnPMF*NIM*
c&!&NQ cFSFHYAGu5EBwCPWCmPkS?:%5e$>Rpa+!Fi&=TN\I\P\cc#wiA<ZbiABDW*Ed/Xp@!/WtBcyeG!P+hT5
XTcbiB +k@!N/jGt@FZNGeh$AiEY4^P%EQ9W5FIlnL\Y!uekbm%cRu%e%MNKqkRT1Zp>BQ@NqhqdwDGR*neEWqe
!q48Se 91NC4@^KI=LntE^hB:/+E?J?E/uI1mt$a+9jPEph^P9a:LDLh4$P&^#:EV6G#yw4VPBB>*muCth:dnkj
T9enCy bLVLYFXGaSblCp%<CDDLQK\JBjd@HI+TlT>m*/P?aRkwnhawcdtqNKMcbE6ZVJNJMnSb//%cTCQ=/@8M
*F1ewQ ::WQ5yM+R/E8ch\$TW1qCa5GM5Sd6yA/=Cw%iPmI:bkDMd1mN4:lcaYB!a<4&6?lI*1q4lBGBc?<J<>m
D\h/%h mq&!6kFP%%ZK<MHk%HG/aRy/KD5D5Kel:eIuRyhDjNFe1+FQSjnPcCP9Kdhbc4NV#au*mZ5ni#Q1YNZ4
9jZmHh >Yt8hNEPwZHdup6uJ**1uepSA=L*TA?QTE@D*NKnWhiM%w#91DT>Sb&*qBpbeAaP%Xn$4!Qju1Tbct?/
BQZ#IH +@e::@L?<5nk/6?wWZnKPpl?S*6Vc*VZJb:>9n5@NGSL%kFuPQtAjPQ5CIA\C=qJmlW&!&iMGKDV4^ma
WYG%n% /Y>%:S?tRG^N1+MnR:L9+ZR</Gkp#t\D1jK+tKGJXaT=4blXuGdIMn6NR+:qZWdy9d85&9dmyh48!S@\
H%BbGL 5aq:n+XK?yi1ewlKPbtTBu<#=N/T+Vi^c>@wF8pn=QemAIVhC:1$FT#!9$<4YPS@6BZ<t&Fu/NYHucG@
NF1RBL H*cG@tdk?P?*NF:Bqj=t+Qm9$QC4$Je=\><MHQ<XY8RK>KY8>DeD^*?FF45Kjeq6m>DjDB#@FX4+C9Tq
qhF&*+ 49R*A<h@ld=K%tCZul^&Jj1T4IqiJY9RT$?P?CQ/Kqt:%JYKm9+SjbY5@i8Nn4?q^eB@SF<qc=id%u<c
5RCJkX PQ+:@F?cX5S@cMjClIX@a%y@N*D<L/?L@*MGnyj?@&HkPGJd#&wRt/ZwRWNRyRt+$$*%ZXiknt>Dk^uk
al!PN8 ^G\%GA*/>**mTkhtmYL\9++bM*4^<u5$VVYHH9kQ$1w5q<nXlX/V^Y&M\WalaJ&Fl^QNwRG=?mwENAb4
hP%NDe nCwHdi6!IZmXt9Sca?j:nbWqL\mb@:X*K!^AY#p4PHF<dK&K1cyB>uRBiShEaHAtW:N^Deib/WylV=Mt
Sy>b=> kMjT!QSp/Y1ImWSmNPwW:E*4BI5FSt/d\LiZ%yk$J?jL/+CuXy@F@q8D%NZyq%RwCRe^6dcG^!hN5D9K
TeR^E^ ZMFk<5dhJ1ZdWu&m=wu:@caj6+&j*/?5C8Yu$d?hNDMEkKKMlV+p:p18#jm/RGPEctN$w^eD=DV%peBB
ASk6tM 69DQ4c15hK8Ynt!8AmtLjZSCYWp1ta8n$b>5AdZSPdmDD>WTBMj+Xu!DTRK$<R#/?4p@CNa6y*>TB\1R
m+1dYL bdpAB8dP9wZRRRq4MHj\LeV6w1*d6Zh4cEY8P^@wLNHMPW&!D8#jh8=?J?AD&BcwjQn4G9&Py<uu>Ht9
^F9lKe >=T$WK@!u>PHnm*Y#%%qe+eq^w\wNEVHDbN!%EH*</9KbJZQZM6DeBjSuNXLK4iFwkIWnceX&tB@K><i
!8K5bP Tj^d?jcVJiWuLj:Ku9$:4KQS:th::M&lJd:BQYZL9y?t6u+Ch=haF?/i=Z\dyZ9#hKT>RCP+41R\9YuR
lYDJJk 1/T1cXH4%/uSM\NSkGJ4cpcup^ZqR*=RPeZ:\CV8n>m5GbZQ1EHB?#i*F8&>QaeCcN>pwnj/T+tRwN/P
wR&Hly N!p5BXVuDWnAa*Z/V6b6qSi=\VFtR>L6kJ@QHS?/1P1LNhHE1@X8cbl5GDFZ=PEe>VLXEwWcC/bA%i\^
5I!utq B#qp&G@/$ARAW#L^nBBT*yCZG$mC!&K6JhZ^8tN5Il4#IjEPRSP9!DLuDW9bXK>?>#1JhwRXHTXYbX@k
&#EJtR klC>iaPPMWjkM&w!S@EZLelS&c@M1y!XZjGCqF6iIPTh@=9VdP5JV#@$an*VP+X94LIQQJVYJNRWcbwb
GjLEXm he\4hCMd/upY^&J8<an/HiCjCaXHjti>G&M/4PVMiL^W#>19TkA1i%>EMhD@<bGYQdyVMWhj!$#QKVYc
Rnt$=< @*NTKdXJ/9A+n+X$F?H%W=$lVm$6y=%N%TwjhPe%&jjJRmR5h:Z1*iMC?Hl/N$?cqlwXM!I=TRli6nNW
X=@PY/ b4GQB6Z4ep\>Db^W+9!A/kj$QtaMpui/5jD&5!:9VJ@EdPn?>c4V<GeMV?kaYQT^phGSRu*ewZw+bWFb
+BZH9u IW?hJRKTR!TWWSMCRmW*>nm?@iK:4S?XF%/J8DMh\F@k8Hq*tCYk*$GMmtPPE\kJb?IV9anSnGK#=cy/
Q*&6hQ q+mRKtX1X:in<ml=ucL#h56K#SakHNe@yXbL1R&^y1DJ%:F@<6NpceFB>VNh&nuLL$8=NlLcZVY/@WWG
$Xq>nl Yb=EdIKA!?R+@Vi:RTSZ@Mw#!Y??>FwimW?eX1ddNIpY5MBp%bBbF#\wPalJSkT1d1E1$:d:L/>LDRI!
L*Wq9K AeJSn*H:F+q&XmM+\=1$6V+$^<AkH\&6pleQ4BNLw*!w^KV:Y:c=p/y4hecXqGZqquK%iq>W16BI$IW1
AHI!m^ =kl+*u#aWmhWi#=KWCCiYeH=#pnWnpt/4JGKkDyTY@Cp5E*%Ia@AbnyVc*@%y%p=9hCAQHjE=Km=EPdR
1@8RCT c>8N1dITW&iWXjEP?>LMkDCAnXi&NuhI\l5<P$t8<WQ/tnynX9Q4JE$VJ+YMLiI=6I+E=&SJuF&?GW!c
Cte5^1 LqbY&MD+yejAK@b$<XhPBlhF9I^=#?jT&wPAG=A?Z:yBl/EW+CSNGj?1+lBQ%MQb<>j!KHGm=I@/mnaV
ZTERp1 L%V:*<WZdZ^?jq%nS:Ba5FlZH?@/bIh%V=>P>WAlK$m:h5l<ZFbIn@WVZKQ9Vqk>b@V!<%iY#?D5tuwu
yDa?c+ ?kc5/:kcmRlNB*84!k<4bqNLjAGy?GKn^Q^M8^<e+a8:&Tpml1J4d\I%S!#tb&@R&T^&JnnQ9W#tE%C\
Dt5n19 L<6:X#!TwWKw8LS^c$e@j1=<pZ?4nQ@&H5ZnmaetlP#8%l1aith:Q=GiTGaT&M?+TE+DCN&FaK^d*@*&
SnHG=K lNGXabEWdZ:#nXi<>N^<1NhJ#=J<wIdC++VeD?1y!^t:Quka*hRnnPpZqA/5NLlY^QAGy:?E/F/T&uqS
p/V6qb A/EBcR+XhQ$GinaljHPZeRa1NW5968k\Pmj5Y5PXQtSeZECy\:DV^Ykc5impmbN\W&p?bA\p4Z%*d9p=
S<Yd<p @^JlhjJBl9n4lKhAe\ISul9Bbw!9Vea?qTjF<nAFbjRcM=1Kjj91A8qnQwH^>q*Q$Y:h6qdb4S/!/u<5
jMVXt> AT9+Y5jy>NV>?^*lcSXujL8:\IuYQkDkK=8V%wyA%GS>n?w<jq&>VM8pn*Yt:GNhd9Me8RcX@hnSW#^>
tj*RW& dTkcFJAL<e*AY1EaW\+JmnwQ?uwMF/PJ>:<GSd+PIlXP/Xm^*/4lZl9+Ipa#wA8B=4<cG1^4&8K<XSld
-A&uN+ 0003de01c3400110333 Page 102 of binaries1.zip
/C9NE1 ^&8pj+ILbHc&mbtkea4V8QhyN9FR>IbR=W%&+KbCe=e^/?*nN:65pdqN5ZRk8qZ:nwLtN$>BjX%:%S<%
\&ZbD? 8N#XQ%y>$/5:E+%VL4^\^n=9Hi9NZdbuWdY!pY/Cl1W>^u=N&JIwtGGGYRM/qJl@pN+E6=9AhnCi@R+n
Da?clK &!:b5kAD@4=<G/8a@84G6e#+pnu=V1?uID<wWaMHFnQA+kJ&:DM9RPy$8!WEtim\dkHNX9HM%9H584aJ
<t5VGB y6=\DLlc9ejHA=AMpJ%bnCHqdZFCbCDeBwGCJNFE@ZmbZRu5Py\p+E$?t6PkES<HTa!%yCdT4^Zk6<mF
8?RRQ5 WqE!A9NV9JEXlZjNCeh%kHyGYmq/bktR*#lkcq!uMWEt^G!\E+ZV\bDT$yIFAduG$n\?wG1=YqlweuV>
^5GYqn Kc9cHS\d$<E&FTjqiCX1@PXK?Bc?iYct=:Ccib=YAIihjV<!cL%B+IA?eu?ieC%VBe%EdqNCZJGY9J?y
4GpIE\ =CBJuGju$VWn#%Q>e\i<\L=*Tnm%1cGNk>8<&a5RDHHGGRA?6W+@YFy4^MFM&K9RX:KG56F<:$!*QAmG
/WbA<i tT*EF=AS=JwBR^y?=X4wlnJhG&nTwpkJ=c%mAy!?1a4F//IVB8Z/>46aL5+heER?QElDp9NtCn%MpM4>
nCYRLD *wL6a&Pywpkj45\W=bXWalhE5j=kcdE4/ERGldAK8L=q:q@B5G!%XjHh*5m&LJ=Dq4HAw1$JPC>?FCJd
h<+LI< 6wu1<8n!=RRHX9nN^&/#I#FIQH/dc5X<RPa?j9P?ctCDI/NmyPSi46pIPpcut$yaHn6JY8t9I1ljHXyu
4A=:=! LTyaYKnVp=cc8ibW4A^YWk8NV>/Sh+L^/FqVST:uAHawh*u!!Dw&eFdZG<dHmuWGnlZKk151TJ/HF^:H
>q&?5b k?%YYYERyH9XBudMRI<NeH>bD:=FWq4EL8@PuMY>cGE6m5RhemDei%4IZS!*at!^RE4+yDR@nXB\!c8R
E>GATN Cn6&>/t/?w&BZ8c1buq=jSmAte#6y/<\4t?X&+iC=A+lww:K&$^hL5B^J/@1J^yEniMpi>M:&ibS%h8=
!QS4=9 %8^Y^6V1+qw&u4Bea$=!k/:I+IZkm+<<6*C5%dqHpq*qlmwGbpwPByA%/j%&XH4e!GjASXj\^QL+E^Nd
Kp4dF< 5nLC<&I&A=YnumY1VM$Ry\JLWy#ebX:kR9w+XtC%4:W1Qinw$L\Da\\Y4?C%$?pu?@dM1*A:*ChIDd/h
FE6D*/ uYwN$%*un!#y$=X9TJEcA@X@q<p#&dKbMiVHQ=THFaZG9MZtNp*\Ft%aYP#QQR1jTNHm6JG9ph%=LIqm
p&^XTy 6mdwp?>Q$%TkY>1lI1B=Wqyb?Q:abiN\up6t@94RuJPKp\+jaE9%FuY$Wi*^\!hXcbX&cjpSMA<:6!Xm
eLV/5J PN!=?nFRBL/=$4YZ\4i:@*W@YM@cDFTE#yN*mm@bZ^<J%MGb&eFklMkQ/L+eL=V?+pwwqhu4k/<!Q!IF
ctG+Q? yNH+!ueh/qjwJMy@=!hn1jTI$@j*PA=CRIWDCeARVc%Ck+GqZEF&K/6=95QujHG5*4\&iY9$Y6ZJbNdZ
tTW>V1 biLY+9ly4K6iaRkklBAyQZ\Hd8<uWI@utn%MIyb/Am5Le?wJGCw*p&4ed+N6I\VAHeJ9K6&*qHjlGCG6
Gl$li# $dAGYJE<CIRmm=uaG$iR&c^EecK?BP5%+LSNS=%/uL^nD4uHSkBZZlq/EP/IYWd5>6@l/XwBqiiydPJy
qXLqQ+ XR#\b!:5iV!yA#/tw*&4YZDL!H9aGC1Ce8T5<b:R:i$B\4wtuctJwC>XBQimqcqS#6HW#laiHHRqc!=i
Gl%TE? 9bV+klHYJRNdJW:By#c8KmJkR9yek8CLcw>8FIjmmw66F!MbIL?:dX6pm:$$u%Kq1uyC*5YbKFQL!t^I
elcCKh 15>jHh#4WIhKdNC\YGna1S!KHLB&/BE5dm949tuDE%nm^8TI!qayL4VyG/kRnu5Q4*dFH:LeDXDKj$&m
6/\Lp$ =E6tHe&NTub1S>k+q85k&=:KF:kJ$Gq&md>V^Fjb\BHaci6aqk#I#*!KFmQXlhT4kmVlBt+:GNX6F$DT
iY@5ep PSRh1KM6//YLd=+@cnLc=pBM$chT9qw+:6tCJq6HQ:49bDA<<HkTPMKqRdS1qSY+>=bYY\$C!%yh?ITi
?lGCy# JwI:@V@59RXaXX9ZNw#Eyl8WWyGTbuekI6&^cRTp8>6Cyd6LSET/T$yWSL1:SETpY$VE\nk@iPR<#*tP
:LX^\S t&@=?9=j@Q>*ui6eb*u&86ecnnZtHHQie<^:^mGPFqWP65F$ehi1@4<y=L6*Dh?d8TQ?K*V1j%ZXF\/B
JLpjAB @aNPlWPkRPuWA&dlH=#FV+km\L1<5J?w?9+KGk$AnWDmICX@w8wLHA*@mcw9:Cj/6AkecMl9wcEA$Q8?
QIjiQ! @Vpc>q6wPBA$DJjqmN>CA+p%KE:LWd?FBlJ4WJ!Ya*+HDRETc#lySjnjbZ&^@\IjTm9?8<w4HQaVqXj+
tTbukA 9\9?@w6YSML@d\Eu$AJPtWBNIYcHaA=@/uyZZ6VXd%L?/55#u/PnRk$?S<%#VnPL#^h$EATdTc#AG:e+
1DVX@$ 9*!NnkIdjA%%8cI=Ih+pdj6SMn6Au9ke%pGFtalAnJNK\p!mljde4MVkJLK9piFBKjuDmYk8hc=LLP^t
<\8Nd= +ZJ*8a+W9TPEPNyu4J+%%WL#Ip<qa1FX4%NYu5u+yZlRT<#GP9bZN$YTDDS5\YcaEh5B<k^TS!K\b%Vm
m=F$k= QI5aJF%qH5B/=ta$BMpw6m^bk@B>/*+WaT4<KMI5JQQuTtR1&^m>e?^e4:dG5YlKl95p!1+GD+=J#14e
Xm/mD9 J\jF6MLb5JTtBy?i\ATytLAEASacWh9%k<Pntl?ul<RyCZj++E/ZwuTCcQ1M:\TS4*&TdFHd\5Iw6&nM
EHI4d% YZ55d4@Wn1\\MlC6FYDZ+NiHE^a!EJWi^$P&bFNKDA:i1<#X!!>iK%Zwpk!<yR^L<1#>W9MY@qk:e8A1
H=uH=B Fl=%p/Qw/XV<6!Pm$y1j#V@HRAI8$HE&!W\P6&nIRqq$$EibQ9T<Di1Ll+N4aW#KH&$%@EBnCt$Bc15:
wRDG9J Dd!WNIGTq<TQ=LCc/:!S8ABC+I<mRQMZ4W^EXuXPZAkLauF<e8MekZeIT!b?l9b:$1&^I\:m<\4><Kk^
#ABwi% D\ppbi!Zd=@cGjDYW/*64p4Bu?9+5MCNEpGtw+=>%>iKBw?KmXBb#41RT%DN1lyTIq:FWDER^a4inST*
nGCJ!L pEG+Ne+?$uDTVFucaHCchhDwMGeV@Da1/RuTAWYt/CGaZWyX=$9YHR8MtEDpP:i9X^9J\D?NDh1?jSJe
Cp#TIM i1pXGquh/RT1meS1wHY?Eb/T8Fl%E\T=W1e4cXj%=V$*RZCy^I#wb#bh^F9D:qK6l#*9GLWM^<=T=Ea/
4e65m= uwP>FctNKA9cp5\KMLDB4u?#!i<XdYl4j$N=8eRBn/>WJPu>%SQ?V/>$PSXAcw&TJ5pSwQBQ$a@d4!SQ
yLimNC bnlTdBR!CFul5Yk?aud9cB\Xd6q<wh<VF^VtmAVFn1<uKTm/#>J\*NY>5uAT*%A@$yI9jie?hhmPlA\w
<eYmiH k+PnLy#eZA#KZ?nIE!nlRJ6FTP=ZbH\/FT?&bCB4%XtmdR55l%$dMniYyc^yluTeIVRp5ZTMXtVIeLYh
q:CX:X d*Gj>qiL1^HRt5++yjmYEyKBpn*N5*GB6CCA^Ju^LuK:KPpKq<iK^NPHN$658R\XmHkik+6JXldMS&4P
wJ5EuZ ElhiS^!:95RX+aYqe6MN>tckVQ#Ib>caJ!9@4y%=4D=Xie6M+q!CIpME/:nP/aXSML6><8\ni+*+Y!9=
PZ&$t9 *N==ypy6$eXEdtY6!G$LRn+5JhXS@5VQS>qy^XWnV5&hSN4AhccKnG^b5PW*9jm\%XZm%EK:uN#b@KVd
hEG^6l liSlC5^*M:CMVW1>Sp5bEQ^ue>XN66wb\yEDV^npn&R1j4l48Z6G?D:Vl%8Z:=yFHBES\*5BmZtWdP@K
F56&Rb #wC?qb1m@uBe*EYHkIXMbhu+D4QP868#^k=:G*1wqJG>%%85l&&SkRMuQPSn\+B8YYbeub\<n&t6Fw\6
:S+4VM Y?uiF1T^>&==mKM&HeEnLN@H#$F+^k@>JFSD=N54Ak*5nWbqXVS$#5wj&!&^C85#wBDljh1T@jy<:A8!
RpjE5d eL#MyyQM85hQPLca\/$wk^thy&QN*1yL=GwHeWhuHNZRRbBtwwSAX^#GSyI19EGK>I5Pbu*<461Pc*e$
Qy?Puu S%taDd>eJCJ:SyW*atKdtyy%5$^^S4FGP*ubT5Ha!1iNIGp#y?mlM+\8EX!:k:ia$1&h:GmqtXt>D5e/
!GS\%? >eq$Y#JuSWS8SF%^p5^jnM\1$QeX18qW5kX@Dl!F&\5@!JK&Z>YiqH5tiIjwmHV+K%1BtcXt9%5jR6T<
Y1/Jtu N#q<X>*Ld=W@KVP@$GGqhVuy15?ND*cZ%J::W&+!d=V$ha1^\E8T1B>QZdPNR1aG1lWXnlZKHlZtb>:S
hb$=6G 8D:wVCL6NSjG1:Du<Scc/$:%k<TCwkG*hedWR6M9a<a<i%!TYcw!l9@k\F!#j=$MchZ8abh/K@ebi@b6
@+YDmV tq$hA\^?Q>Ic<W!biJqaD@?edwuH$up%d!nLq196tM4FFD46kh4X%:bC?N1Q:G@SmT*/1h*4C:&Xtb#P
#MM?9Z R1ntM@mFn1KElLtVH<FF6&*ZALw<^H8MK=!nZ9F&tA?V1SZpDk?p+DGY=+>WWT%X<&jJQh8Jb:nqSSPN
Lw@j@< y1y>X5PmYTIi<L@Vpbj4uFphHR$!=A<V$$m19j@Ia#=R8\=Li8t<=c$hX94qV6=:q#Z?pLubqZw5YL9>
lSl&IH hc/dI?yPaVZBDGLFmnKZAj6N9e=XchW8Y8KS>&PuN!q%IFi?=nRGmuhi6SJDZPQ&up@qDN?uQ%PmI^1Q
j<#QG* enB+>$#*j5S#L/bS&wync=PT#Bi<8J*CammqmX:tD4H#^nIw^R@h%D!GZ?ecdCLRh=XI#\pLtj@cw+u/
luNM:J eHTiMFN?!>Bj&Z:Rw+J%La5n*KBaM?#6$tbZi5a+YeyAK9:y=$F9pV8%9RPQ%^=ZI$Jla*k5I/uc6c:*
%<uc48 JE+d?*>#<jGFL!W^&q?<QeS+^jeBNXq1@Lbiy19@#9*cd<S8T:L<#AJLXp&XhJdBC#&*kq=hXk4?hNF+
$wnaeK 4iiMQ=9+K$&Gj1S*m9:diGZQB91Q=%?J#SL1Y*\X8lP<SJ:6I!Zw4/yEY6Z5E&A^!tdBd/N>L*%6qM9A
LVKP/5 pc1+T9mSb%BHmaFJTKeV4dmR#yX!=wJkbVTD#HR#tWBV\ZqFq^h^FXl/nld?@kLE@i//ZDwZ?D&LW%G8
8#w?HN YcbLab@ideY=<jGb?1^i::6GS5##bHum1VDDRAqE8Tl*ca:K</dtlNcuJ+?8bX#^QC+5*cn$4YbK+y%\
\yN=PF 6K&?PXZ<%a!%X$6GLl8ikcejB61KB9dyYlBm*X8M*+c&n9FC6$BGp6dN&$6W%@mwit\c</S<W9ujB/14
+w<#Cq NTlkA#KG<IN6Li#FI!qXqK$FLi*Dh/LF4jCt@4CQHSW^tt>qF%>KApuLmM@$pHC*u^P8H5w%/m!KIF+Y
eQjtt\ t?bdpmXGK>8CZYJnK!L5^RuS*iEG+6b4CNI/@l\5titMae+>$u+bu@qN\$/JID=#FThY5uZN?/BwD+Iq
Y4yVw5 m5E:bF9dQ1*cj\RIF<8q81&aT8bn!DpqH9YwiakwQiie\bKF8weJI#aE!CAe=$D9QZ4G%Y^%qRe*S6:\
?9/m*% SwWwSJET$FNLPHSP=Xy@+?yRbknaT8BCD>:Vh!I>Tde$h+MaKt+dLG::EDG@%6VT:#%nc4!1>KHS&6/t
u4yHt$ N+BK46aZG=FQqm@S:kpJS+K<TLt>uSV>R=ViT:qInE6uFFwWHFFKt?E\i1yWIL!Ju8>1qm\NIhiwWJ<*
QiyPpa 9thyREc<IJujLb9uSYuDjX!&$+LL>4/W$a#V<NN<X<*5mZM=D\%MF^\H/<?VZpITMy+Ke#TmjZ>Q>iMm
-AGclX 000c2c5700e00110333 Page 103 of binaries1.zip
>:Vq9d ZtRyyGH<VS5:%WVS%4i/EKn+Mq*kEtFeq!Ne&6lJYh8dh=a8n<adat<Mpk8Kw&nWEQdtE+#SIKK/S&cl
kNenXi cY+GaYT$P?FI8#i$FqciGVt6IeBke+HY<m!NHXj111PhptnAkM\K9@*W=9lmC*w#d!/=AD1hS!WbyQ&I
>8!tB> ji4S$NVdey+65H6AlYaA?*cY1iXE@!Z?uCekG$tByYYCF8QkJR%8taa*\jB*ImiW&!ydl<C!%Gk#?RlC
=w@hS? 4K&!??DXDW?4V6iwX8\e%n6S*YmJXIuCPcjBti&KY51nmK!4JS:\aulFMXPue/hH^55VF6kN!\WhITZJ
\MH1wy 5CNI=T$5Ge@h@GuXZM*%K5&H@D!k$FembXp?R!X8ql6LFVL1C<iSEm*MIJ<^K!%S8hjCAjw64q<TA!bT
6yc:6! TX/\?N1u>VliJp/<64%/$8a8lFB\>SYwQ//8EFI@*uc$mLc>!L=wQ9bK5RKl6IYMq6PtFDZhY8Tcpipd
&aCD?t WSY=5aJlh!8bEau8m9bR!eaimh!MPZi\WD^CQB1y/TS*Ntc4Q/T/Tm:bE=TEWTbM6&Hy!\hjnqCS:imG
^h4nj4 M+nu!a5mI5AV5eqZ4ay</BtTi^i<=hPe<%Np=XY+KawSy6$GpZQSjSRJbQ^nV66VR>>i$ItiJb$?G%cl
5d&W9Q 5@p^Z*:GP66+Ttd?dJE%Ej*$iLRRG&!qTKPNZjZGPVXGp5Aqy=X+muA5EhF\h%T>t9LHTaabNYlBWZ^*
QiZ#lq A&><cpjpe$KMXNR*XMJTcVYM5:8Km=dqkchM@WcSWVm#VD9aihGwupR@M=yyKB@>KRS1VHPLJ1S^n6Ne
:B/!V@ i%YhQ!#/Tu@n?#:Ye#qmnkpe@yG4tt<E$=i$^c$t6Gb&c9LEw/9VZ1tS5p9X#Ve&4!15I#wi69iu/Gtb
pcnJBW B?R?p!@aiMkq?Qb6RT8l%E4NKhEiE58qlwpIlb4XZNl1FNZ/kyHkYj+IHiuKuHTLydWYJewetd:BkuWQ
!+/qyj u*n!l/Np#l/$dAE=M*yic<8<L\!/d6EmQ6D#Za>8dXl?n:<mNYAmkY&?F%@APDjJd+5q!Rt\W:p<a6\j
dB@n8i <S4b/:*8/Z!=@/J^%c$#kt5IiuE1%^aLpuCRGyQqJ5?:VTHmtN*=@5DLpj+1a/wp^F\6y^j5R1KSCJK=
b=B>uW SpimpYaqySh5C/tciJ8uGB1J&A5wNS=le@$=M=^%E>a8i&^18k%S%Tlb!M!+SIuc=DT5Ea6T*N5hh^jB
X4um#$ Xw6wWBtX$YPpE>\5Yp%n9PyZjVjYh>l>^1I\jK@+=R6Yp>1jKZ/e%eXiI@%1NM=GqSCC4lYHJ<*pX!tc
umWb5# QV%6KNMe$DLQNKw5QFd5u9<I>6aQVt@n+pC46+%^iu%B\&KCku$JGXl4y&AA&&TKp*XP=wXi+%SaP&b6
mI5GEq ZV4VBj1wY1CWLL*=JX9J6IT5JLCRnGBP<4/>B^XH\:EEem@Lk96by4wZ?E?LKTpPCYjaJlh%^lZb!6C5
ikM^6w hN@M$6c^hNc:eLH%?CWCyb+E1Ipki:FmjLc$!hq=ZGYe<L?jm9P@DRpJ@@6=P:>AR5L?1jRKl\FYin*k
Nty$59 Ij:BeQ!VX94VSCA$I9\uB@n<ClwFBA*HlWd@FlwDAI*AWcWHl+J@C\$BkIdn&EWPl$J@C\$Dk5bSyRj@
GqK^S\ mdL94/CB^B18tp++FQqdcCC^B5NSlR8Hwu<LDTVYaLk5l+F@C\$p%1C+LIhBj\5NJNb\HR+Gl<F@C\$p
#AA8jN %uAV9:D@XF5>AB>G@Q=XR91h?EYkjpL<\qD@:^G@@!jWp+b\@B>iV+1+^<6RGW=RDGelItDRbA+=JW*G
VBkNkY FJ\ynj@kmcVEPLSN&ej:Pe<eXIj>9nP9I$5I6Z$pQ$pM@%SMiASd&TQKI!w6TFZ!1?4p=h5:&p\1&n=>
d!&KwV nHK$KliEEW/Py8DwIT%neK>uwBb?EG*dKZu6SAt4M<N8Q94IWq4jGXTyJ%1#cd^paamJel:/GS+ypGAI
hJJw^w 4cl?PCaNT:TecK1GiJ4Y/:TR4QRJ#jN@P1EE<SnQjF!%wAKPh1\!$ShCBC\^1EbP9qdZlHn&\IKX6<a:
t?A$mk !?+4cKkEP^VDYC81!Huj\*yp/tAGbpu5$AuJ!8q/XXSFL:V!=ybYeHqEG6en&dIYbbb=ZhXVW5?i!q:9
1PBt=T t?+^YIiX%Rca8MEIen<jNhW>Y$FE=1j>lRt$ZhtD1B\Wan?GVAn$+XRkud8tZD@TM9tk98q&qa8$Iq&l
EZ&1aA yGBY@EB5cJ^&HXiq$KWml4K5%M<<?:YijBVb66Pm14hTw=!pb95imc>BYMIpYmj4#B@&/LC9Tw$JJMa*
jnqpES \@T8em4IH*Ek98u/\H>bRX?4WcPp#iP+EyLw+h^c#hLqpm@MNtjcRQ#6p8tKnC4*Q>w&dTn9QIQCHWhM
kcA%mT %Kdl+TGK$#Z%#eJEwlSZ$6T8RIZP&Eum*^ud@J\n\?T<t/65=t18EN:b+=?n*Se/>yWhLZJ5kP*yyLP#
:=@YX8 &iNlN/>VS&6&1wZ:Nwc\&AchW/1u%N4G!^eabBEL:tmDZwa/y5TiC6IaDaX5I6FFTTY\1&LkaG/4=ciV
&c:W*B yPZZ!Nti?nj9KnSJn?m*qY+hDVB8bSqKkj1&*p@SNmN+Yq#9*%iZhNh/dt4p#X5dmW!Va@qVc^HFY*Kp
LICXTM $eVCNe#WhP8tI88u:J=at4cyt:uI!h?L+<S4V$=JQBh+cpmqXw:5q6GSAAPqL$$l<Gj$!VuT+SBty4aP
lh!yX% <<wMBX/nTBCQnK/MWdh=44qhTtN:1N4uqQum<*!J:bl^^+\y?u#Q6wp#\h6d&ejT8CIL5+TPX89SHTq$
epAEc+ mY8uE4uX@QKWpc&:5X8#eNh=K5PZYWclyPqKemq9n$aPib$9KGW:6lli!JXtFZZ9qyD\aw\Ab^w&^nSL
C!EXTJ 5AEtV$M\ttV\muRAlVXX8$N4=eaZBC9#\N<$wWN\DmZdXaMEW/Vm+tBtSCYy@nPMl9SHaS=IW6Ze/B#&
$Ru@*F !:j%<&46lR6:P=kiC1Zcj+L#HG8B6>SLYRkcncS?i5y*wZ+lc1ulE58YRjpISa@I&/t?+CAcl^a9ClW6
Mu:>P> eR#?5%iaAJX6tLP:8j!P#K%VcebEQA*TV/CD6:T58DLJXANkSP^j&D>hA*XP!#M@PIZ8He/TqcPEhB8\
Ta1AqD Y^wbQFEP6p+mpKtd:N$%wnB:4NE&Yp9GRkCVZ>lIV&1NH>d1E8D4tm/yIV6H$S#jXED>GFt$9c6q>eAq
p<^cX$ 8cAEGe#jR<Ij:%+W8F5<%41n#y4VdRa4PmW5$%\!yEZuM&\RYMi^>qG6nSRt=<TTy@jS>EJRKCnS/GlH
@Tapit 6==J8w?hF96E$#Nm#htuhZ#*llnBYcM>Fp/W?SZ<c+uuR$?ptFdQXWGP*!8<:%N4=n=XVnF6KddM$XqA
SpTiYQ jmHDZhm8Q%ZANMt6tNi&PiSJSP1Da&j:5unI9AV=Dbk*p@yERIuX=^Z#FkQe?+!=H:iYM:RIce:5u*lt
Nk<mZ: <HBF&HDlid/QpqZqqQ#Ec%X#1>B1bJC?j=Qdm+kHMd$9q4JM%@Fu/i+dq?k$NX5b*GTQakVdm!=ye*6l
&%+HMC >K6ClTJPwC>$MJ+@CmiPn+*t=4^Jb>pd:u^q1eEBnIh>q>B##>ZP@6Q^\Ahlkq*q%/uV1iZ!P1:a5Wpn
YMp1$1 Wn+%BjNKjLWRJuC8>4e5MqBt:ZQ\CbZ5E&I^TQ*G>!LVjHDSY@QYnYSV$hwP%em?+5Y:c8j>Jn1/5naF
l/>Xbk \n5E6M9PR<Kq*tB+d&y5q>lw$w+FLNA5P/w%*</4<**QZQ<&maQG4Q9VBXV&5\m>dd5kD+hBBwp4Ma4d
\pjuuk VX:Za>4qDLw85?lwZ/G1#ebY5AyRM4NF*G6KHlAiG^BRid+t6u6N6bT\?\9Z+\\KET@y5cNB&mQbCtXn
K<$?W^ huuXH^L%69kD!CRytHZhy=@=^\YF^R\uq/Wyt&:EBWBJHpBaLwJtaJ5uVbd1GB!u^F<LQbK?lNASHR9j
qD\*uk HCXdNVE5Q&QQw$hZHBDjX65djJ>nHySdWYcwKu6QtDiEtNHW<>mFk5c##Cj\b*aI4!AFA%qeb#RpQ?^I
>XlJuD #y>b9eB@@\@>n\VS8buSH#MJ#i$uQi&NdlWHtFE^N8lELPw+*nHb1wIeaTaehLYcaW$=m$h=j:Iaa9Vp
jw<EnW c19*=PD6c\?ehX>J*864utqlB95t5:N!>*8\Vy$<FecajV&4B6cX%^NDSBu/5Pa!<eBR+K#PmLe5wq6I
*CD+m! G/ZYiEqC\E^M>=aNEpqaewR/@Cdayi1=?LDKI!*^k1/eHGSZDQVM^VR?d6y\V4@!%*uWuu4Hu%++\Z%i
WEI6+V @iy^&8in1upju6MJq^pE8a^&5#JmWeyl=TeKa?$piV5wZ/$X5QTH>X*jwt#JNCw@Q<k?e5=1ehKS/IpE
LeiL5? kcE!J5L+cy*^CCZEkulL?Hq$/k&yW/Dd6&WK>IcGctihhl:Yn>b9B\#yJA/&tC>6TD1iKTp=Gu!Lwcj:
KP/udd c=qhd*YZ5De>eq*%16:bwLGT=^aM>RW:bE:/<9#nXq#8KlaMNqtVSFReKn^%Ku^5u?Sdu*be6\%jKl1A
RDmcKD &6uZZmy9eP=@D!yNc!nNem5u5XTu1Kcti&/4>L!@=E$9e54ClJC!@&K=EQ/4!RpZbQBy1e5>*XYl@m4e
?jMu+M eyX68mw>e:Gt:TwPdKH!iDMFkX+!yqSd5hkA\p@bBm1uX!IW1eyDVFWn1E\IpHyFqm$Tq8GeEqhYk4X>
Zwb:4& u=PHPT@&MHqntjRY8p5Hjd$I>SemCyLqHXZKYHJJAwPea+QKH\bVJC6EylydPcwWFKu\=Zm*IGj#%XSK
EdqqkL <j1WY8MW&j9cIyXqVI%ct$8:#c5&wL81&JaT!?y:+FL?Vt?<bj#APh9Tme&m!5&qNQ:kqYp8PZ6LqR*l
8&De8> !bIbLBqi?D^lM&qi8:9#ZJuMTqq?BLFke4B>c#T=w*iPbyI$^<hq=$A4>tFXMi\>1ElFB<Nm$eni+G&=
u4hu&b 9Z^=N!HW6uyk$LSub+T&wy8+M$BGX%pF1$LMN8cYLQY185T6%&lk?qFBeN@A1G!u1Qi<wEyGudFRd+&C
4DWH9^ 9nP==#S^<nPiw1Y!KXuVnK?h$JJ=+?iDFETq\1y+YEyqtZW1&>8NK+NW*%yJRVP66pq#$?j#/&PlEwQ?
Yce%bG tlbpqqbRdJ#nGLiM?b4@YwK:RXw:XDu5LceKYuG=8*%8X$Wk5eCJ6%Ib/mcL%G!$wTWlphMwEw1u!T/\
\B%L8J PD4RTlXM>mq4&wwK>J=mI18RK%V^FMeTp<<G$&AQi^:HE1n6HBWiq4MFDnb%Jeyw6X4uRkkLJlZh+bYV
SEYDT? YFEXwIyy4=@y@qneJT!@ep?%#p1YI@M$$<e%A#PPchp<$A8lE%#1#aIb1R/Cw*Q=Za^!Ia#BMW^D^5X8
e/Jypj =16S:Jede+?*kN\D/$k*NN>kHbk1wL^dwthyp<lM5R=L%$QX^qDdiHMdX?C99!#&R#XIGNJZqd+KpSm>
dVeMq@ &4%&inNhYVSKaM+:G#@EI*Jpi#y1w%@a#uXhwQYGIpPkm%^w%p5\h:6I+WtMFpm&K$P#1tDy:b&#uZGm
5IRNDC %Ia5HP6MyI@lckp$MG&B8ic8nLKQNt\*6NJEIp\:694nZEc#!F6%a9GEM<!6Pe%#M$!6wX9kAqH#uluh
y9Kk9c ^eE1y\*K4qPRTN>w\tb^PLJVkCci%#>jBS^J1N9A<SK865layW1k?pKCT=:a#XtDGpT=tm4*Ct#Xb5jp
w:YcIP Iu#J<!I#tjm$yW4ZSu%IB<%ACIt5b*R$VWN/EF!q6:=4Mb<@S:i*\$t$!MBA/W48eHC5+#LdPp?$NGmA
Xtn4J8 l=!wDFww&CB48lQl:6\99#uw/aVjF!A9FQ1c%p1A9@E1dPcN18m%dJAV*n^F>:nu/wSeMbZi*LSit$I/
\5@8iL q9KWeBKNXDiJ*TI>iLl\tZDF5t/:>AbV>DKYETZ9L+<!H#dnYL5mZ&KJwDlD/eImpm8\GJ8eDZyI<*F$
-ASdEw 0002daea6a400110333 Page 104 of binaries1.zip
jS8SQJ Qc?LP9\m9<Eh8!qbi:aSwt@nZlSCM=Xy@XM/N6=EFEP/^aK!Z5tcnPuEFPA+mZXDnluK^6=$8cQuGZ&!
>IPqF5 cunec#1FhFVp1:+F:X\KXppqp/?MW/$N+!8IXQAZL1KTC=p/d+GEl5pE<9Eu4k1P4LylCC1T/CJBTVjA
6H%5m# $8Jd%8aJue%Wud:^qj/#R1JJyV^!jcT!ud:J*E@NY9XDXAK>Thak8l#!$wT\=1$8Vbbk$*^h8:#d&SXC
iPtjjI t<&ItTnnna&PEq9qDAP=AuGDw/Dtemj/DR=5=X#LnmF@5i*%$/hpI/<$nRu&1ItqB4*De!C&D=q/%<d8
G=XB1+ ENnhSBJ8ZPIcEC##ll/e*b/DJW/nMq%J1qa#Yy+qJ?Jn&Q+GhnRpeb81n&CZw^@XyGwG&%VKHd$WRST4
6^KI6? Qi\w8dJw##8nel?j/Bm^B5E#S+FAba**P6%VM:ujyFwjXnt=C*GV1ZBL/hS?yVn6=ES$$ZMnRaA$!mqR
liIu1* lbKH:64dKYyGX/?NB$K9N1wbFQK\<?iE9*w5h%1TKJ?B%ZuTFZ5SVETCyKa@MP9&I+R/JKyt4K?Q*MGE
dMG*19 tIh+VI%+#JWpt>y4k!=*VG4:99c^wtkLV%i^N<?cB?u%c>wT>=5Ft5K=hF<RKeKq*ZES9:D@dbST+dD@
yZp9$V wqI1HIH=J>iLRAQtiu>RD@>Jc9#p*B++DKnYKj\u=@d<ClwKBI&L#juJ8V&@kwaDRCN\5ba@PdjuX>BI
ql+p$: AGmedC$e>X6wNBA$BAh:B<j<DlwBJNd&#@:/PSyI4PE/aR1PABJ4WDT8h<N?C\$p%1A+@>/I*$IDmVZe
X*Z4#W uPjjbZt^@\Ij!uuC@p&6FI:?mXwy@N<Fi@>%\6Si5@1@^c=A%W1uVQ?u1=W!CY<MM9TVTjpkh<u<FD\a
<mkc+W k8=^cBGC@C1\\pV+CT1nXHH5LTS\>^*llmhk^?PW+1e!NEmCNZe51CkyQ1>At&lYQETClI1hX:n9VR4G
X>E\cW BVeX8Bd#T&YEeRj#X#$>*daqT#hc:bHITWXbH4lI&>QHkBEZQ%Y6mSp=JdHG<ITASyP%BmcDkicQ/b\u
RX\kET HuE:</%wuJ:AaFiN84FFZHqM%u=e5mZ&kWR4IyCJGdEXc5DWpESwQhCG=QyKVBT@cDw^TTtpBc%=i%dL
!qThp# 1K<&:VlnK!!yGl#y$T9NEK^1m&ZFcn#M6e59j5W6Z=uytSI#:Lkw<*Rk%uXFXD%Y^iCLDu&WtXA@@B9%
u<iZca 5Ta@J:QkPiwJ:DEV+WDQZ1HpP:T!@AMSdM#=P%:59a4D99tWVRQXVqKmDydBHXdp*!:+hmWtt+<P<L=X
iC\?++ hpY<FibuwBm:HmP5Qlid>%qGJCPM51jQ%E4jKLFpd6jc%c5t5q@H<E&Pt8M*BwccX%qcDM@4En/jXZ$I
%d9VWI :wmFTEyehDFT>RHhXZ<XcuiSCQ4?h6VYQRiN/k9W+%Hi@BWW\ujXhHIYL&6jJ8?+DyH5?+P:<mP9B6Q#
tCKD6+ 4ihd<KmJVk6>KcEdm8X\At6Pa!K/untYt4qpP:eLipw?w^e99DbkwHwB%6DWbbR6yQ9\KHL6cWPjD>ZH
wZcpW! l8Td9A#Y*4hNi4$y4=&^i^eXZ5%\8j9G\!?:H5XaHpu/=?Jj>F\<%kpSBP#QFwlP@KH*>5u49Qh>nXl6
&ca+&j I9q:mK#pd@4a%a@c$W\D?S?QSyk<u%P#*^nFED=<!\JLABXi#wYdDlcTFT&Kp*:X+Ckk^#hWPmXVedu&
FGJ$8& ZCLZ4cQNML<X9>JTi9H4^kI#q=cdSE:tJXCaZq%FdQk>#><y8yuRR!KJ>\InhnV!9hbuJNaXhKRc9//Z
nM5=#1 &6SMY:GL5d=K=SyB@G**9D5PyZDND%%9T&C4Ze<CbNmKSn=/1Ie*:hVWchw!V5AMTpZS?EFG%!uyJ=*+
IG1MSw KBkkKeNpBIci$ddZWAw/nhhaQc</?DWI6^QIZcM$9&9Z^$k5LSPh1=WRLVtR\@Jaj#!QuSDjp%l^mH@G
chaXV# \J:TXCmc%<t^ySG:K%uyH4GTi!HA<k>mDbYV%+Mj=*Y@4:<:cH:pi1!:khAqYeF$M^*qy6^eXc/qnbty
jbJ^+C M>^9n/9I&VGqYX6PB!li@51>1E88Fi8aR64HXMSpS:T5j%Hc96p6qeqF$In5Q5Z16ucdXu>nnI1?b6mL
uSLdW8 +Y#8HF6P/XD6@KF9h^Z:e<#e*8nT%bYyFuBEHE>B^65mGM@WKH^dK1L!wH=+uQZa\68:TR^yue=M@Dyt
CSw:ZQ CyQd5%V1Pc^=<n\tLPd*p\YCySGh#k9nK51!y+a8E<Aj!+<FpawuHVEWEnY+a=PD516/y\DujKdBkW>=
hC\Vt# n9SFqj>N$E84B*h#HXSFBD@iwJpc^6me9uYuIPtwe6mm5<e4QGc\ZQBwH*M=Tj5%jWJ6bA4Yup>9tIc9
CmX\Tn IuGBci#<6uVyEk%9@qKh!T5#ecGq^@h!?Z5aYl^<!VjKH$\8ZVu!GB?Y6F9JM:K%qkELw?cN\k8PjTq!
4FyulX wieE=a++qYmRM:Q8BV8Td5b+Z8@Lll64*&AWiD&!F&ZXFu8<>FRLJ+5>=XaqM\5mN1Q!>$bijA5G%etM
jI=6?Y X>1/mFhq^8wN+eXm8\w*uc6!/m>/DV59KhS?P@@$<SRwPQILh=JB/V#DWNR\l!^<XY!PMVA4:tti\k8=
q/*$CL B>ih41bYSd\dMMLw&ia6eFN5*Vu!yAbF6pT?E>R^^<Gw@a*P88RbJe#<^G#lSdl%:/9dCYZELS5RbQ!P
T*nZLQ qE@M$Lp=#E*WCj/K8/T>TI5HS9cuBNuDkkQl9Ytt4/Pp8=P4FVH\$YiEGV:WlnYcAtb+#hi#e%<T$ZhL
Mj%%1# kykt:\/i/XEQGYbLyik+G<8*lVnTCG&I6R+IaICDP6E<m^6nKFXyT8Y?PmclnyX\>>pMhaR5Pu@*am15
?&Ij?T yh/XMRSm4W6nY/Zp&Bh/p9>E?MbXjGW>ed+9HIFHJjEENIPQ1KT?4E!h/!F@*Gw1*$NCBNQj:1PB*Z!@
+>1Jnh Nu%e?qLZ?yYwMXXmAV/da<acX/NqShVl^jyDQkTy?BNWTKaH=G^QDjn=#l>dY<@5jG:&HpV1*HQLwLR$
*DkuSh !G4\!tSmKwHXXF>teuK66&=t:=t5\IXJGFqdp<#Dtbu^/%jI*&cypF\RRY$=qC@\/LtJ1EuJ9u$nyjXy
Mk/yu# N&%k=Yp\i:inJTi6<9kmiyuEtXpc?WW/w=?I#&E#jVD/mJ8\%MKYnZ#LeK1ITpa:pbLKCHK?8:Sj5ZQe
PBYT8: #8CIAA9d/ddB5<>bwkmmM>qiul/EYlD4ca/#N@QXDLcVRZba:PtKS5:S<nnMZ>SP#ZPS%:>AjFVb<WL$
D8GZ6W J^PqbTWDatZH6L6L\yiVu:F+#jy+^C%Rl59hW>P^Q@5tpI9K@FKul4=\F/p8VS9bapS86pb/:V5^uyc\
c>=M#% c&dwn6Wqi$5w&TyqX5!>F!n5XL8!JN?#ic&1qTJKH/ei&%Qukui6R\wqh/JPHK?j6mPXZLH5e!je@C1u
#M@$E& G*Z8VM/*5<TFtTQQ^:^PnaELTYyKS$W^Y!&6a>qcp=I?KP8Aky/86N&iVytHkmY<ZAIjhw1Z#whK+6Qe
qu^9X\ #^GQWWMwmF#4@9yXJdP/:RqH#^?jiTLI<1*4IhPt%68iZ:SGpS<$^5i9YKp5YbX/k!m*!^cRcuJq$mGX
djMIN$ 5d:^ptW<X\uEDhkubY#M==a?n5lF1pZGT%9H?$5M/:SIbK/$Z&9jHk:Nc*IRc&4*Xa\!pKSI9t#JqP8k
Dw1a/y /d&mth@^Q6nZYbd#K%F:CyYm?YW4dBy*R>4cYt\?ub&5GWtEbyl5uumE?!m=h/tV<&kY1CqC@HV=yRnP
>k1y%c HRedGkiLqZS5lwJ4#8uAMm+iH%QTd!AcjW?JDFKZp$e1M5d#QEZMM^TEQDWJ@V%q=Gcwqcp6qQSd&TJW
ME>/P9 uP&!ncS#JmljSh5LXTeR!d!Sh=d5tMmmEG$kTa8%%L^WDqKQSSw+:CCIjJRdW=Zcq?BWYZ1=?MwhcR&k
R$qNtI /6a<qSJi9D9+CmDy?8uaWmJ%:&c<\N\kS@FwZX&1dV?=d#ET&G9lcR/6C%w=cLZXl+QSMnJe*%SwyT16
Kl\L61 l$8KW?aI%eTJ+<6DL8um>bET+dZeI&5qZnG+X<y1E^4M^hEP<cRw4Ekk4J9b%KRwI/I*L!y$1<kZh1LE
jd<?!Z d65/p&\WSqJ$aL&wFNSu?yEmTk>mR#>VdN+t4<*K>XbVhJX5ZhGmLFqpZ&hZ/=VXyLkap4#4+w5khtJ/
C:pBm$ I/MhkL$lnW*1IEuy=b?Y&RyiLyHqMphR=H*k:D8/Hm%J9dLd&Q/yG*%bPdY/*KiJC^#k8%AaQTjwpkIu
aLq5Ye !1tmVDlhlL&%#4:Id*em8QZNEnV1ncjL5nyBVHY\9<yH+k?<\*Wb&?=b/6e@>ayiq/<$AwQXNMeSY!!*
a=G?p+ G>XQp#+5I8jc$1kM$8#M#4>!VtNdMZ8CI4>BjYbt$NLauBM4^dqFLjQ=iHDGED&Dc1+yyiNpn!4:^RC5
mH?%Y= lSAF*FJ#<*S9D=q=F8VL/aGM@m%iC\LLT^5N@mT!JHtJCH1KSYLuTL5weD@l?X\Bpdh+tmHkKAY&PXAX
IIeaVu tma!K?i6kF&5>BClDC?@t@D&R%XjuTEC*p&/jKX9X#hF%dnX1EDXp8%RQ@X68hj9^@5W!ySt!cI&^?^L
uI!G?i NH*#!q9Z^QMu16#5mGADqNlK#eCtI\+=4k5uBmH+E^V<<:uN!y#GqA8dK4:DqDp4clL9wQi&RjkGu5wK
h>wqWP N#\p9JV<pR:yiuTBc6p4>5Hd%/J*h+bZ%GIm^WWeC!G9TX?@I^PT?cQH:!nES6!1+Gt8$m5C8R:NXDWS
iBd+5E \Wl:!^L=cA4iRRk5PNXNS5aSGmLH<nH+PE*\ZhwbLMnWWyq*k$KJ1uB>qlqWhTc*HN&nEtKqju!h/@%m
XBdGtJ bQA\!Y5Hb=p\BiYSnLmEGa?IRJ8FDK&PT^ElhBTCD&DPC=y>Piip*/nMaKXq$FKL+u&BwGT4F6H&+ZG:
qinGA8 IYZlP&RkiVF6jT5PHZnW>qMujW>qM8ik>PKK<F/*!$T6j$CDX#a>ttVXQ&q5>Z9TpIPFyT/H^44BLQtL
CK1Y5I DHYKwyWDF<nD%$DYaqSW:A>Z9Ply<i%$4P*5/C+$96X6>uEJy&dPZmm&NcDKcIY4h>?\w/Ry:nXm::+#
9yY@d@ d/^C5dFqc*8%T&$&JEcjq8Ll?tC5N6bEc%/%%L88QaSGpTR?6#YTjQ8S8tQp?uBWn64nBj!E5Gy^&c8/
DF*5p? /*ZSetu/k<nEj4Lkqi*/I4Eu:c9/QW619I/^wd#V$k1NGbPW^bX^1/DuhN?GF@p86BnLPyEWeBqy&X=*
cP:ZYd PR%Pm/5&=#y?bptYVK9>n%j1iJ4&GdV9#<cQd!q%W?WR$=R*jA6cmB/<\SnIhy*ZP=dTnp^HqY1qXQLh
SLn6^+ yPc\#L*k6ATBJPHm>=T4+iJK*e>q&C:XqJ1FBCb8ELyVVH@aILR4DZ@/nw+!4:1tWF&c4+wtR6MFR8PT
mGVI5d @MCpjDQELhX&dNZa%np+8j54kc11$#4b%ylFC+b+*4mTc>#J=54XpC&Zdj/LlRM\pbP&QN8LF18&QJYJ
6Zh1h= c>LuCku%4N?/KdW+=Ei=I$EZL!4p>AiS=I?e/N?yHLl4Y@THY@qeny:CyS4@55IY:u9wRQ4uutFG1caV
pR%?A? 1TEZ6cXwNw5n4Bh=9*DuER96?lX+Q=RuVHRPwJj=+p!I=HVk&mn^Lia%9chZeduNZ598puM\^:ZBn=JL
+$#?\T e!KXXQjp95F9Fq?^NA:X5TemymM##ciDYlG%Ll:JqmAne4c&e*B9jZd6jq%Qp5Hqm:$I<Ni4XP#6bbZP
pFqE^W kZwmd+hlWTu%<=w9P4aNXc8V!*nKe6h&ELalH9+V=P//S+&PTPP5u9*:MVu@?%VQ@9$Auy<!1uA$+miM
Lc:4E: K91jm1l\NGBF%ANm+#<yp=?e/QPumaA+$b?e/QM4cBkRNC=P>Ceu?9\KGkEEDecFSkJAI*D?9XFA$Dm$
-AqXR@ 000cc13575200110333 Page 105 of binaries1.zip
8<ZK:W ZPE@PhHuX>AaAGk+4uyIFQm*$EBmDa/4*lpF@T$$pFnDYj?Kk9<YGpm5\ZBcn9\6NJBak?GKe^V/6>BA
uDTQ!h ak&K^LH8kAd@FlyI4PFtp6H@1eb/AD/WTV+wtN%uplHku#HJ/J?y5TL&t6Z@Q/yuX+L@n//iFjAy!=GM
W!6Dcn tPRZNNZ5=m8NKPl8cCe\:c*t<yM\bAp&!<A&q#t!Tn$IJ6jmSCm9y=p&ICktukwHERn?4KL&Bae!Lh#%
#/?9/F RZDjXTlL?c!KKaSI!Ee#S6XNC>qabydl#1D8JjbEBiFmyTaKW&EcalS/$+LT%/=85&ac9%h<V$W4/y1i
pKccNE iBC<iiG>ZKTR^PDw?wZL=q4$LSNNE/hpDblHCHK>:@hu^nw&XjC#/hed/ZH4tLjD/<@4>&6+nnawnXFK
$pV%/V &km>w4nM&#bkECI\XDFcLNAnIAB>Yyuaq6kWQcTnBw=PZ4F?PPA1FQy$4FyCA>JP<YY$?\!nPGmwTm6$
<9wau@ G6Z4+R!L4/u4jB*:+y=SA*QyjP#!lcyLb!B1RWe<:CV?FDy>/6Eue:d+hl?</PcG#Hl4=TCYL:SphJTZ
5:+/Td nH#FCl*lJ/Pnwy\R?eTtRtB44S/pM5*Y6Cde1KE?\4I:DSp@epeNA@ELZ/6=yc5Ddy#iG6d>LDZd>$pi
Ja9t&m SMdNtY>@*%XD5eKme^L/dCVKhRQ5w=IRK!KyM6w&tyLAnKD$u>G/$%HaSy#BMawM>Z6ySHj=iueep$6i
^B@V@C TjYhNw9kh&KGqW699AIbuqWS1b9AuM+5t%>5pqXMLYWWX::Wq*R8?iu:5c5IdNDn<XL9+A9>\y$nBNjS
1/q<\h 4KZjV5jNS%1WLA$>L&QZWJMhdZY#EEy5@eB/&dla*k:$=YZ:*FQJWK$njX@Q\6B9V*T9I!J4$Np<8^w*
mL8+^u i@^eHV:SJl?nP1>lD#aVtaHic#i%PYIQ%uY1dkm\W1M#Gua*=C%ppl#l5P+^+yIh>GPC=W!tTb&/1bd:
NCRS9M PLCI^H9!YT5#:EmTHaGPGqPT9SZyKhI6jN>We9LXV$SHSHqc*yqGDIZb!yEHNlZCS>pIBLHCdk1e>aNa
buybT+ S5aMZu8SXkbb$C:nER$nGauGJEtQE!a/tPL#4=6/Yt4AdAG56ZJBP@iL$jSM!Y>!wWLV5HM6IH1X<Jw+
!B*L1t &:c8$5=WK@LL5eKP\wwl:J*>6>jPuddeKiNKD5=TQK?G*e/W+%&/hV\%RNN8<R==/<1+N:*YiTKl4u#@
PQwn5w =Me5l1Sin6b&XcK!Y#QHuyh4hIDP!NYp:<abLAm6%Aw!J^5^/a1hXA/68*@L$nSK\:>CyCpStWe+q#J?
Nj%!I& PXKPcA:X\eR:i!HVP6:nQL4iS5I/BZbHVSD1\*QjP<$w<u!pZRG<^F5\?4R>V#^6yi%ytwunBAyCXQ&T
$qJQWb nKeb6lcuQ4NuknZ%KylGy?t%#\1Z45cicVX\YMZnVT6S9H?cb+^^6CW4yjjhTLe5Ph?A*ippX%XcS1Y#
R%=iF$ 5EnYNcmVp%ebd^Q!FN>6Edw6cLd8JJMi=>YCiGaZ#58lQewq5ty9e1BND@Y6E>@EIX/N^ZAW/VCu:41u
B5cdh& ed@Vak:Q^p>56L@bR?5mX6C:5G=jy/hpn*eMlmF+@4uW*:tX/R#/FXZjyW6\FiR>+dEKM91YJ=hF*mAI
G*?%!^ 1#lMN!T#a?K?94lX+=N4+1P1p>?PJ$VQcpp8YZ+FmXHliV9^nmI<@=wcZ>i6B^VL/SQ8NYb4E$@H&6Dy
uRL:&$ nVDa\IWy^XcnLR&9w!1pSjk*J#h!V&LK1X\^/jKp!a&$aA@qDhyp!X1K<J9+q91^%=lQM$5MeNMF&ty9
b6AS58 JMX:$Yu^/LCh%t^P#8d+EquA>im1QGIV+cXl6Gy@\:PIVCNlXjW1k/GT\CbLnECAeeqGaq&GM6p%KPnE
/$cl!P QdbEDRhK8?*JyFI!G/G8pnejmKHE\4e=tth9CphyywDH:&d!&%@V9W4N@VtJ1chE#\MTdVIIek9T+:DZ
!REFn$ 1S44C6C6L:%>PW+NwWYi4Zen&G&BDLEc*TnJuCBkt1Yd#neu!+Sy<^C\HMuwdFK<E<Bw>J#4<$&:L1!^
uwl<EC *6EJw\Rp=X9L95Li46TY&<mG4mLY++Gt=?ib!*5mPy9!$PL6VLjbRYFDcaKLLwd$PyM&^>VP&@A9y:#?
<I$IhD ctIiJ^e*VXIq6<F%NH8<:%L^P6nTj6Jdm%4<*4lNB$VD?/Lc5dPd@8EFqQd^*4IyIRd44YcFJ*Pt/9mK
y1%t5B JG=P#SuT/*1AB=HH:RM6C6Qd/qSL18>Q?+AGXt9Y9b!aZi/pXR!QBy%IQq$JT?E$EW=Hc#t5Sjab<8&1
PK%Sh: WNDih8I*W*@$VtLC8K4DIwq^bqM&$iH=9Jk@@ctuXwEFjlcqJ<nmVbuHdCyVI?JPZL4M4/nc9Lb<pcNP
I\lQLJ :?dmS1YATAXYCPLyHwLQ1$K%>yFdVGA*nJ/a1M6%qwR*yB\tKc9nR/q<!h1=1w#*BY@%ZjP=Y=Ni\pid
jeV#%* hRawNuR@^I5?<=Sh$TcnyM4ZA@M^RcPPia#jEQF=u/tXwtWT=/:Y4N9XWT1n==>HWHa1^9WB+\8b1+$d
Tu>Zww nG@!/:uyRd8uVbltT+Y:Z^eK#d$pP=ciuwbNTMijQyWj@&X&5y9aEZ=CuS<=Z@^<IV\/!#TQntL<BqEN
E!I8S> #dP<EiKHLA8X8iX===G1yk+1VA4!=PKjYXJ6y6l98k6<He1*JdWQh>m!<bHMhhL4qa4p8<tXX<e<ylT6
/MC\h% 6SHlhnJ/?pQ&pmpY&>RJH&c/uXWS1GNjWAR=4^JtpZ/JG4=8D6:?^H<b\pedX!4ZdQYqb*$c:Xeh!Yac
1A?eyj Yu#EIb8p5CJV$w9MLYP?jRyPSP1yKlFbH4NNBCyCLNS%q$j*+He:N=4K6p*pTT%FpF5@/hq\cM8b#eBc
yRYtBJ &WT*pik?/T:RJuEj6/5X&qIm=lc<56k=Xp=SR!S^VVXWlH<qR//:q$BjcN:/6ZR@WWa4PL<EEVm1c/GM
mwQ6t< 9=p!L9JFnj\5eZi@EDlSXmDTYmnT\/EXEw:ML=#LhQkT\nWKm8tH8cLLLa%G!wTL:PP%?WDc8Y4FZhjL
Gt>iX/ C5F1*GWqyZpq\e=CM&5jmKN%8^QDBXKEuDVQBy1CK@w6KyBj+9C?<lnJe1\%T6E<:Jy8CqRB==m?Wq!V
\Aih@: =VYpp>pXet=wL%w!J8@Ne^n&\tN+45/iJBj:mb\5Hc#$teSc!H\N#wtpDHyattP9VaFhw>XZ/W9<1ELt
wGu\^\ ^i@K?=yHy&9PRy&1b4qjPEiL8t&<YeMwZB%=N1a^n5jkG>@YSunnM@=G+V\/SNuD8&T%lwQnZ$qI:BX1
uq8w!X :YZtHNphl\ItupX!WVp&QPN&qF#^a!aTL:B/jJ!&miXN@N1G6XT*M69c^ltcehAK1DR8Ht*#lIKZt4*N
6$%uS/ lmu\!SG%8Y*#1jj?*ZN<ERRTK%VL4VCycZXuBWYI>^GyHCpy\mc8LNjFw%S#NDd5ttT?w&@m#%G\G*H=
LwQwIj &tLmFJ:*My\qZ=yTFp\8\F+MwY6Yq:mbM\e89JV4^qMR*E>E=^*jqt=i&F?$6Ccel#qBh\XtZiTp:9?a
dHKS5\ TytB?wTGl51WRPY1BSuMiXTLRG$/#q^:iZM15PFJP:>K?*uBwq*u^hPMPY6chI9Ce/Phyd1y5StckZNB
?5u!4* bHn#mwJQ85C=hP>ER1:ELQ9/!ccHd=w/$4PK6D<>cn+h%W>aIYI?$:uMwV+MWw5&F6/MmuH65LP@%Gqy
d:yym/ #MhYjb4B9F#/FKWC&MbX8Pnw?aXuBBL6#tEpe4\:LSW<kcV&Mh*cimQCkXq4RSR!\9I=+XD6lSmY^QJ\
+N9P@a &$L6dW*uhFLVc>ce9Ha4SHmnFIICuQHXH>$8NXHH=4i1qK8q4JRaEBHME<iSqhPNZ1A\Xe*XukP*G@NQ
d&Q1wh ^<mJld?y:ZD!L!4A8^m:kbmZ<8Fl5KTRQV5*YP:GET:RdM^qeD%<uCl@pcdmw::@hDG&>/y@T4mDeLKy
ZhCHd> yuBGuYPGqcVVPblk!W^XMY%:YwK<CF&RqB#iVCRI@bS5\**hlhZV55#q1E*XZRdw\!TiGJ/8C/hFlQl5
y+pWp^ :=#iLPjq1uNTq+MyB8=$^L+n@*b#@TT6*FhbaY$bn:QIRwaumeKcumS1&eajqtN#!V//&*Vl>Y>h\J9&
KJ=A$* TBTuZJbc<Gnl*Ap++1td#l?4GRAKe/pmJ/K!jqPRVTFGSbjX:AmBLRt1Y/=R5^6$C99KcyR<Cd%TSR1?
Lt?wak ZVVSJ&FRaCQelk$*$tCHBd@TFJVypIXS<?:8Pmw%E^@6#JtnKpqVL*Q8$#\Pe*jl:N#R+e=wYYp*Yq/F
9/Z%MN c9NJkDZ4Xmyj!+?1eM6KeJKiF$y<&:!ld>Y59i/<>hdyQQ9e!FmMpqYD:/cy*yILJKk%Nicb6mMYbnWV
/5puFD 4FH>&4+85PRCJDjaaHuBPEKDLQhd?8pV\+:9*T!pmlj=1IZLHntpQ?P>a4V?RKkQDa5Y$/=\@NT<cSW!
^d$A*T Gt69apwTQ4R$Yn5Q5t:iYu5Fi89yjTX!YLm6dCn/Gq9iia6=JnWiQWwTQNYBKqQK+&d$1VaBPP6C$j>:
RqZW5N 1yLC$VlWTV*&@1S5b?u^:=Q99d9@jM4iBBu^+\IG@ZGBkQ!+RKJ@ZKD?JD$lKNRQylPCRj@=G^TCAl<\
ShCIp@ tmLTLq::^Cu+Z!R1:AD\h$8S@#Z!FRH?J@tKAAMtZ\?+kH?\DD<lb*/+B\B>?yPneu+FnRGAS8A1#Q#J
m$6=BG WVt@kwaARiM1#MSAj\5NA+DiL=u>PS4?Y&kEADRMq@L4V>S&j\WNJNb\K1Bm$L?FBlJ4EQVQ$Rk\?LjR
ak\Iic RGINJ^GIAQ?DCERn@<hEIQ4j>FMSWM\@i!IE?ChEIB\G^@#jpqLkJcYY@>NLTk5WSQRb?5uM451^B8Hd
WiLLSF ^k<%Nh6GEIypT6R^\Ga45H^X5^LhA&%kW$8&IIJm>cN6MDHH9N#8#\^5Se$bah!QBX5Ry:54y6yR1kGY
EaA?IQ y&n:Eq\NtGwwI\8bl1IEDEc46n#:Q=d5WB/DIQ^5dSpwlSmY>4ipJ*>TH#ANF+P>#qkb:$6At?>T66!Y
n=dSnS ?!IFn%BlipLkimDFc96DmnWh=Jj/>c^/55?*j1*MYPhhGci4=5!N=aG6cKt*nE:GKp*KJkRNTFZit/**
u9uXt> 8e<Ru>9iwB1pEIwMb4lAuZVP$*mi>=XTd^>DwY5RkY?Q#\6yBkqt$PnHWGlW!hh#JEQ8&i<k5y+6JwaZ
@nhA?u W6n:wGMj&F>VN6\5+*aj6W</tq=i%j8?P/ky!Eb:pIB<=+5bQW*PS/&=&^5jC&eqRlq1GF+bDhY<L*BC
jIQySF 1wT>/+G*nHmh8/1mu<8yF/^/@Tm4LChe\$u!TKpRujY5DQM^?>mQYm:NS%TiXe/nLdY!#=%Te/N5k!aV
>/!yka =$nZHFjtH41XY+mT+JRbe8>XH#=L@BV5Pba#jNWS$!b:Jt1Wy?1XV@u=Ei*I&w>N1Fc^eeuJ6uQDSEe<
a5aMe* cXmWE4mP<*tp6Wn&NcT%HS*%YC9S86!4JhaY$=*t9N:&+cuB6bGtw^IcMeE8GhMae>Fip<+JTMMjKcAn
iSkb8Z @wcuacq9b=ETLniXu5q=Q4#G4#R<!5w95b%:B1I#/@n5R>AST^wtyd8SE*Cjy8Tq?%EpjF1#h<kdCJG6
:h&%%c M*T9EFVM^BDGw\Ey<>>Wa%cbC%E4Z$^nie&F*YSQ!tEIB/WemI/Eje8KZTeikZ=!e:u<CVWYYMkIt+C?
jFL*Gu h5PijM@$TD*4yqI+SqHmQbpQZa/whQpD!6T6Nn^GE4949G=BD%94W+=buAuymyNN*jL@tu1pQF#BnjIp
Dl^TdZ @e4Xy@Z/b5EN@C^+5X<HCwS<<hw=elh>H*HT\LVmcqq=8LiXcAZFZd8F*P@TPA?hF?Q*XBDqQ9YAJGn1
#B@41Z 6l^mLj#aa\@B*6pMF>P?HHD6/EVR/Ge4=?A\t6Vk@5DuXha1RtiQ%u/TJ6V8ahNcEhdw1GZ1\n=9%#4>
-A@<a* 000bc3b729700110333 Page 106 of binaries1.zip
G8<IeF DEt+6JY!GK+u\+eXQEtAZjML%\bqNLI>jCAYpmDK=!VTV5nVpXLA/ypqEFw9C6J^jJpbGiP1WQ>X9L*=
Gh\V1Q t>Z&eW$Buai=etn:a+T#^8%bFATKItm>*c<?*NFmnSXcNBeM1JR&8Tp#/MXL5M\b6+8V5uPjcleMha$I
LwNW1w lR6bqMTZ?Km+\p/9T&:\l>w!LFcPm&hKDBX?<9\$h*ZB48nc?bMT:dhV*i:hGH4*B6@*n1Iyq6jT$<=j
q#wmHu M$iVbd4I$<48^W%?X^hpM!YdJ=<^c@G8i#R?6BXGhP>W!l1d^DQ#T#CK?y$V8Zp:L@D9J9i@kEGb?&m+
S6MI69 /TKT1SWXND6!unA++Eu^lh$w1J+ZNK8M5%u%=NZ+qE>?/9tH+yqc>w^Y>HFdM4=T6$X?<IP<8nqKQ!L/
4R1Y5F >md%b#pV<\8$&VyZ!P+ia>@JcGMyKZ=GQ$:PDPi5bEYRhl?4#Nuw5d@6i>5^tu<5WNPJWwd&1wnR<yM4
WK466d \#uY%Z@Ac+>5//*L*ZJM*Lm9ePEQ9w<^l1Q/GK&X!F&%8188<Y8XJYD@qjKE+aklR%py@9eh\tlJ1=m5
yS<AYG eIlY<qPiecq9G?/QjMh4Z@u::nT6mWXde:5:Fen!Whp<QF=9%k<lpL@B1#QyK1+VSQ?ajwZXyjLN9iIZ
9y+aC? CGWm<aZEZX+E#RVLE@LRKnP&VJ@Gjl?INS:V15aPM61N>pumAP1tG6WqY\^BZ\li8u&htY9w&Sa^8jG6
\eedLZ IiX+6:+*w/yG#1>QFlhj/>eaEmZa&1IWtLX4GtGbCqkwa<J@+?PEte81ptBLy>tdc!k1\yjPCT<FtZhR
:u4dPG C*@JC5=nXdXKMB1SyGK^MKH$T<j$ZVKiN:t6<C/9B<K=NZlGm$#du4Fj*uWZ=H>ThnCkRE\pW+CBCN8h
e9Sepd XlutJuciST1e&VJChw&&kNV#?y9eV*K*1LNwBYQ6hC8$bPFdp*\njLZ#1XF1a%c5N8KKFh!yw6N#R/Y=
:5#d4W cnX!/T$e4*WGhp=hN89Kqq^u?&I&XcLl5h9AM&#i^ipqL?#F8<dc#bwnhFb#?H:914Te++TY8b=1tNQX
N5>I=% IBp^&qn:q*+C#@C#^DlKC\%5VJ^CLp??tIma?N15SS=l!Q/%\jda:j#yL<V5laHQ<1Np=JE8ZE<*be<X
!QBdDQ D8VV>MXiR6Xqt>#R5q+=^#w%L1A5E&cuj?X/d@/FpS:N>&^W$=&Sy^k&4b+qcMiX>=G1nI+/NwcP5tYG
imbqa5 4t11aV1CTlL:$HD1a$KF:\eWIa@=ES@ZwYJ5=&LawqpHXX>XuPXqY*&BI51l!lnVGFGcj$8i%wi?jjIq
/Z$F/Y p:pN\i*t:tiQY:1MdIaL#ci8PDT%dLewn%6M51t<S1DXNt@HG!:bW6%8Wu<=EjcC#eS:Si=JFyL?#eS#
b\EpCR 5J9q^:=b:?RnI?l!c%hTbHHYGSj8!idVFLcb^Qcitt8JVS<nHJI6@J>jh:lhT4F\I1tqw5L?N49Zp%K$
:!@DSW YiV#AIMH#<twcqKd&qwjCTlL*d^%Rd^R$J6BT$!>&cbYQEnp*I\XQ/YEq1*NDF?8n%GG&M=e@B?B1NiE
+#GcDb dE#ZaIYVp5#H6c9/6D#9WA>4K#\cW*q**:=PK<e$C%aa1DuT^pHt@D/lG&99mJReiP</\DTcLZP?E%?V
:^+$h@ Q#KVLD=VNuJw4wSj6hbcHZ$&18GV^c+HP*a1AL9aY9CCXDVp6Vm<9QQLkH=uXyGMZPkZ6e%QGhQqZeIJ
E8$=>+ @pXQZy9GEe/pYI$@Ia%Y#yp1==:R+>J$p%=^:=SwhLS@A9L66tTV5MKREtl?mdqNJ1P$EP=hR\NN+c5h
FZGcQd ZeYdhZTeh\^5+by+*#hGEc+4T#cl^+p%h5#R=J+u=YIyZc>4Cuh$WywKYj$T9DWF#&jaKw\5+W6<YTIu
PJ5WJ5 !!Wu\V:hQWTYc/F@l%T19aBGW>lZSaMLu4Gp<:wld5PMINK/K+V1WpuwcuSnS*:k&>NH6@1Ziy$*LtuI
F>>/NV hXhIdFJW>ntHl!!$dqJMLXDF1pm$4@PWZP/9:%aj\%ijuC^q?!dEpeZQ</&n51lqI4K<MqXpq#?uaKT#
+AZMC^ e*/Bw<8t>&!Z1!:QyZ5Lp@M4q<JW*iZYXb=G1+p6tX54*ti^?SdTPBY>ItecVJJQBJ+Ee$&Gy$#PqV\Z
u=EuLQ 8pwjhy?B\qGGe+65cWPmdQbE&&9GDm4*qm%a6>+^Ct5=\jRe4pL&VkNa!>!paNM^\Rb^^Wc:@8%KPu:9
tI1CKu !QcPIYiZ8MBLlbNc4#49ll^>=Vm^Giy#KV@m1E4&1cIa6p%X<6L4b/N/mWqCK*p?uYljIKIeXFEEy&qe
Ad>ZXA T4VyBR$JJ9K5JBF5lT+KWyVM1Cn4*%p<!?iL#ce$VY#uq=XlPWi1uW11ew=WQNjZXybn>+EG!IHA8C/8
9ZnRuZ nw4AjNTT\uY>FdH&=YK?:w$*1PM8Y&eD#cN6DTlQN\9!Zkt!$XYNKNGWQ?1+t1elK?:Zl@ZFt:Lp$9Vu
=\4hnQ 1QbWm:$RnHa#HccathJeq:KqPJG<H6ye5B9hq=n1LQyTE<Sjqy!<^bD4/=#hQR9VMyA6>D<HW!Zua^uk
la5B%l 5d^1Z:dnTDEcCGHnW=EPLpXtK@VapXl8#NnPK:\YVHP#X1q*XK9y!1QeFue#ZV=V\wwJMNYDcatil14G
J>mMjL aHed5XP6n</RuajE#6p:#d!W&i#MI^a4*9B4d&>ySReRQnyL^Ajt5S^\NL<MHaW6kj#cVw!?buKkTVPL
tZ4G1b <R+SPH?KkXqkjX6QiELL9a8#Wu#WNPeFaWFEXlECZ\#pc:9i&Wdew9<1ke%S/AklKjaGn$wM>bXRPFeR
RNWjd@ *DI%B4=IYy8&NF4L%%!@$P5*cH\:k5&E*aau1JPmP4ItREJ1*SqBF\pc/H?b?>E99!GX9G=%8E?l&DQn
tJ5*Pc >CqP#!mq5DcFGKN%cd4/R1^1a5/dAJq#NK:S&m<k?VIi96&PC^PQ1\MjX\?i$/cIJ!9#G#mSDG%MDB:&
?PP<Vl l>TNhCP\\+Ph=ZT8<:K5:d+1Cmk!>^^bt/8chBYJ:C6/4?npZl*>&5j!nT\>m#b&8LA&QBI$mweqDWqk
NWnp6W Ken+HCRC=WJ1eHW@Y<CLVB!C!p!5KP^?#G8YSXnKuM=:TpnL&uEMA6pc\9IMJYGHceBYd$c9RpT^SN8:
BRDZ9Q 9FV*9J^u%^44Aw\%/eYNF>?!lpcHDDkY/#VEuM/yXbSX1dylFK=@RREmdMtmt4SCyhN/#=1*nXnKy&*M
AGHV+h tM^$ldcF&t/y>@VdC@d*WA8<dTG/=^njP!Ib:qqHK9q&5BX=ui^ZP$8We#cayLS/^$jE>Dw$Y/Vh>^^l
aFJX>@ YdPn5/XIXwd\YbES?\5Jp+ETiXRbM*i+u%pVQXjlH4c\^cQI*hB/L@ME%HmBD/@icq+PLFa?%4nc6jW1
%lBu<E bFb?>TTB6RPJw?%wie+q1\5pZVuZLSZebVR@KSt<jEZ^Ebd+TJ/cLCcTA9taLPciA@!hCjkGWaWVG#n$
+j6I$w a?SCVPS>P?RDw9dY96nw$SIjBKH8a??h>>bnYI<wT:y#c5NEZApMDpR5jRIQ1D$&A:SJ%4MXMS8Q4IJG
y!4FAA ?Iw:^KZ%E/D84=Y*S^jQuT*?RwTZ*y4dZT:RHy@#<p\l>591yGiJA%ep?pL^Vy5Kk&cAwneFjm55eICk
dYhKd6 >?\^Fm\yB991J4Z8WuFIM?nhw99:FINPF9QIiR<b5ZH6McupTtq/ej+!1l8N%w?KR*PGNpAP%+8DnQ&J
!jeJ5h +<hc^e#nm\%4$t#:pen+\P5bhZZ=CeeZ8!+Z+M5?He:V1*G%NZAj6bd6BF@YJk!=**TB?:N>^NJ6T%M1
MGbb%B ltZquu#=WXAncZN$Mc9!P!:NhwwM1/WuXGJyDE@QXp>PSb?>9H=NFbXywl&q844tZ:mqSTSw#Qe%wKL#
lENGqc \!kFmB/EyijtW*R&=*\DdRNS69M&YnJj:mt+X^P4h+uGLQBb&P9wYBID!lEqZ^4ZF1I#k6IK$c>>K$iP
W@G1w/ Q1D<=Mt=HZj$A:HAb8AIYemTcQIcRbD?FEYCZG#Fl$liA1^Z=T81MWKK$FhhWy9E+WqWFX+i\%1dbu\L
=4AVne tqjAS+&p>ZnWew<56biGlI??w9u1Fy:yqjhNI@Hd@aVn*mXKlDSi&S@PL5h49VyL:ZWllC<9b\H$um+h
#+iXVy <ZcGu>A\RnE98K9Zh8lT&KWeN%5!=+wcm%nwXeZ:+uVEjAW:V:nuZJ\=cW*j+mM!V&IFtJtntKP%JHu<
p=d5Wk FCIL&nhn&MBh5p4/DuGP5l6!T^w!468GcY@&?p9BDd!Zc4Z>5l*l/bB/qjQ\JW#@ydKNbhehE@p#eydw
V@p:PB DXyZK5ji%=<tZ!=jQP&5VB=5DQM65a*n<Te1m5F4mTM*mtF8!SR8V%9Gh5cyNehLNeMbn!pIIC@*bkhP
9ZA+69 TG6hZ^!^8>Q?pZK#C9TR@1/ZHI4V??euhTHA<Q>h6BIRaMS@pX!GRj=JL5QAkMuqH@#TQ=m4j>KFB=V:
E%QKwi @=kiS9#p\KSjRcPBwHHW1CJ?etDTL/B@etDTQ>EIFC+$=LjRWCBwHLYcCAn56>B\AGle!4cIu/kw@\wc
RabnVP TK#BeC\HICCw*$IDmVWaHBec<#6wKJBak+F^iA$K?T$$pFmD+9ymWCC^BwZnmHMwpFmD+qD$SWAS9+WG
/wZ+*K Et5RZC$Wm9w6NJBa\:&a<Hebbi!@\Ie6J9^XTQ^>MRGP@5qm\4<LLQ?%tAD=:>Gu?D?m16n<@^Pc9Ba=
y=@5w& &m#XnmQIjSFiX?ciAQ6hqyBV$9lQ\JtShYlKmpFdByWn+hQ%<tF%pWpKR5@DYWGbLbQbbQ/eQdRF@qph
$IZY#Z ApG$#W85yS5W<R!!pCC&y9bTH@9*IFyLh=lIGb5FY+%b$ltaykj<kqyp=el6+YFHRhQGMyhPLCIIq6Kn
R/$Lp1 GV\&QQ=$YP5&*^pmk5=bQeT:JDGt58JaT%c\^TPP?@%Cq:44NV$I*%J!8%RL5#&8F1JGKjZ\d@bybbPN
#b*k:S ^<klCE%S=a^kLDITPqLBwF4!Lw&=!8QCMEQF^ihICBEp5QFB5EQyF\a%qGX:DXTRXS1@*$@b8AESWjyC
H+*!$J *Zkn\?y1L?Yqbpm@RG1V^plJLb?P&mZ8cacSi&w$>/9i*yEMqKQwMYFw8*V6dcmliacPhG8m611icY<w
WyH:jl Xp^Y=aZSi/F=t8:tt9hiwwNqhn\C^<#yF8*MDTqaBb81Z%6kn9XHLA\jXZtd55/wdiceWEdSWtbqW?XF
hC6@?P >QywP>MP6!kXt9>de%6Q\c\&&EK+yB<SF=VLc5J$u=uJ56butiGbYGJN6S%DQ4eV5qM8!G$Id6CN:K<=
\JY9*\ P+9Sj?TAjmJd%udGZ@@&6Yha@TVC49C=qC$:aawEXpa&8TMihwMh*+8kl##@pHlejL8Z?SGKAeF@&kDB
=:SVQW ^BiiSqQWJ#V4YF8u@JLu*LaD^LiP\ej<:uuSaeHlNhFy/B<^J\1GQMa#y?Cw56Ai<puBe1<#AqtDm!%<
?89h^& 6%RFp%Ae#iPy?tkwZ$dt/^w6ny5W@B?w@F\buun8*D%lh9V!Gwujp=yG>bQdHCC1JH4Cia/$q/=CaK8$
!ypqqn B\EYTBPtDC56aXptFwcq<wtmP^dEFR>Lk9tj*W1\>SQRWij@/Eewta%$J1q?iu?lLnLbWqJXVqc6>m&!
P?uT?j ql%&Z5*5GTQ#*PCTVy1Sk+$by6Cd9Y%ti?1G<4X9YXaC>KyZa@SnR8?*lXA\T\6Ka>p#I@uk4pFVFl\m
DwT\HM BiJCSZXd>WPcHnw1YNFYayLJw&SSHqdn!yWjK+*CYh&$jDMje*eY*NRyMw4wc*NR1DWwy$?:dSa5S/K$
hP9W>n \n8VDlbTBde&%X9:D::eZjCX!PBkbnck/LteH!H\DNPVWNE#8w=CFDTd>&kb6#<ny:uk%$>TpeV!eQcl
9D:w84 nX%9<@t!451BF>6&b6aR6Z+ChL=i?B>k5&l4n1/=TK8*uV?peT?u?\u\hiQVudZX\d5A=k$GI?:uJbNE
-AVPPF 0008620ef5c00110333 Page 107 of binaries1.zip
>MRN^G bNXdkj&Gk%Mpy15TbA^q#jK58F9ulTV6t/P==tnWS:>KuPIIDPIKN<QG44TaXJGaaW?+b*9n*hSLwE/Q
\CQXJ\ ih#F4MVJqLk#BFbw96LaRYicBw8*CcaAX?%CNQlt!?*CH?i*MdK1>4Vy?wPjcbS:V%<+:\/lm9^&bY#:
L9>>nI FhKT>4ddquta69:eN>&*Z+LII=NW\C?XX?JNZT1Fd*WG5&wSJIdp8ZbZ%ZHQu:R<H\D^=6HEn>?^ny>^
^IYaZp %>ETi/V*eX!L!!=A6dC*>+HTY:Qm?ZLqyNZe=MC/^@ELu?T4ZwuZ4&F*dFqH?SNLh5/t$nE$ZW=F#Bw^
BR^dM5 BCRau%?REZdkeZ4Z<HV&cM>dq*V1bPiWM=e=/S$c<!Pe//S5%@+aMF<W:GpukI$RG5=/k11wuDwEpnH8
*:6<SJ V?5eAlKn#k+$Z#8*e8yXGVk>kF6yZWw1*m^VW/bKwjwB^K:9m:LcK@pVuYa*/QHkJtYp#*um6=bMS@CW
9A*8!h I+8\6i$$D5*Km$LY6WK>9l1\KM>AEca4FP$w<jA+@@++YuQL8bDLLG+eGW*KM+&#C/+=Y&^MpPkNFF?F
4#WY>& 6itd8N8RKQ@:ye>LnX=?BNh&y5C:aMb&#=/:tm+>Pa&wE<#Zeh>R#T$5piRYybMKlPTRH<E8B6?tX:e5
^dBKLc Di8/w%HY5Y1S4a@RK1PuAm&nXM#LZGYL1*m6LB@cKe6TXjjMIEFyqhbn9QA+#VWFnutV>N+Jb#n$T=qW
ly<=?m Vln+YaNB=FJWRNd>E+>H*h=/hD>?6M^juy$T+B+d>E+BQ?Sl1ewqdJV8EnN#QhVAK:/tKqJtcLq/tJu%
+=G@:e m9B%Rjb?4W@TML>:=buYV\!PGX/mVFCBI#/RpiL:146a$R$TWb4B%%?yF>!8R/p=$/4!5#KRYWGC=XmJ
CYQAYL #FW:=%cY!Ga#$XdtDu\ZpV1bE/FXeSNn%me%y:aF:9lt1\ewnn/pNZY!$duk8?S>A/u>R9iiF^/!/9$6
6mF#/d ZlP/=D8>yk<dBMWiE&TV8^em&:NJB<6M+beH#WJ<Pi:\bl@V6TpXjcS/C#V$&E?8Y9d1+Q*%BEQGqy\R
DPEmPp Zj9bRIj/:j1ITZ:E8%5G!5j$<<aa*4$58R?!ISW&@EkMY$/\h/5p8=1^:QtMK8%!RS*Q!WjbITIC8heD
ReW1Y8 PW^LG5q>dn/\#1!/?XGp<Gu!4QDDSeWR+RW!#6PinR@MTR4aNX!46NKk8#/QIZQ4R:Rt&G91Xh4iH<nI
5l<Gu? #5^=%Pqj\p\@%4BQGPuJGZ@+ejB$*n8uHIFH&pKaY*bec<jE$q:!V$1@C==ljlHXp=A$t#Vh4Z^%qmYk
C+m5h: m!V5#IYMFtEN@#4Ec?b1H=<LRctBWjjY8:GeJF$EY1C+j4JHd1<CDcujBth/>JZCJwIY*%?Q4#Aa$?8a
J>/*:M 8$a#wq\?CCwM4dq=u8mBHZte/4tuV1PqFeWY^y>pX8S6al<Y4H\$d\mKNw%?:VymFd^=tnBbkWtXG/6t
:T<!pH /$%5&V?%WwX9P%/5+P8\u1^yFSucqym+?B=i+B849lG$5JIAQ8FXnE:GKw%ayV&ZhhXVNC%cyapE<T??
biA&bd D8WQy:N*1mnHZ#QakqcY#IRVIPWKJuWwS5?@PyEZLCdTbphERIla!6EY:B^Xd=WXylLm&ZlP6DbLm1?!
uZ1ad9 YtbIp&Y5#ANcM6+N+HC&1Ml44@5ny5F4WhR9PH/!=ETN$HRK%dmM1jMn?aiVXCSnpaQQ?GSkVlN4+i^E
mYTuN> ^G&$yh9QF+d6qnhWiTycV?61LHMMSau?RbQl+CSDVW#T5hbG45Gt5nBMI5$!/9SRJHh*^Z@FbMHwD>9S
I!8JK: WKjYJ&:Y\5&tKWNe^m+Tq$XpLljQbJ#P&Tqi$/Aq9J<%HS^cTYLiL+eZ@M+ZT&SB1CwRL4SC<lq@a8AX
WEb<$S !=ThSFS?w$hQRiekNhPeiI16dSSQL+Xqw$tk?S\ucKqN6NP!44<hd+Dd=ER$Q5#/$9YlKbe&WeGXTk4L
/8c6RX <Y4HtRkmiiJB8peT\S@+1u6dN\iWi=%udMF8PhSe>8aSYAeLEGZ^8KG>\8NPtbwbCd=ljk%?*dP^DIIq
tLMl^< bG&Fe5ce$SdSZGw!T:BFGXYLh##!\1YX65tPI<TKVFRBMP:qlX*:p5kAA%Xi/IL@^@PL?yXEwqSYe*wF
mGmZTE $cP69h=!/DZwqh6<XHH^4qw=V@qnKphdLcMCLRSK^!8yHt4L#CG!Zk4cVXaTGB8*!jK=nb&GDuy64<E$
Rjil18 FHucdk6LaJ*m&1Q6F=ut@XNMt/tK6y:uXm!$ct6q:BnuQD@l%y^IaQ^N>y9^Y<E^c&6hEIXN$DBXdA<5
b^+y\> V$/IbNmJ$AB5J$Dm\YNPK/k659KeqFA=RWI&RCwpu\lSePKQTkcl9kYb@5F<I6E6@kqb=%V#euScVEbe
5Y@51d iB>c&L1EY?qK\AtS$^#dy@WyuQM!=ZV+?hb8<?njJZ@G^Qjq+>=pkBw:uQYElFDq/4$y%%k?wwlwLeji
IF@@WF wTly#ky>K91yuyl4ZEy1P$ZcbSHXFW5C^?X5uSpIR?nbNP$p+ASEBI4hBW88+ImQZtVB5tE=4i#6^XAK
KMYdM< #b:iEwiQYi5N/V%T%eEy^54IEtYFC*dLdQ#*JjJ/6iqBDR=qRS4>ti\nwGLYp\I:?8b4K1Qw8N:KKyZ*
@qF!*q yyD4NcFTS>RXtTI5^Fd>8/!a!H^VwlVMEdtmhVpQYAZbuwbSu!kanYpBS$p#CihYyFuV1MK#+l1dwaQl
kqi11N /nVpdAqp6SGXKcb=c6Y/RtWd=?jqXI5!HKS%%h#F:!yQ16<LDp!$PwL@Rm=HbauZ9thnl1TIc&\96pj=
jQH<yC a!5=QtZ$W5Xp1qMVpBSX6LZcX&thCC6nMTP5A*FLJTSJ#ZGbWpm$CFbP=:&%$XdX+85\Nwn=y5*%RM&K
u*H1AX Y$mAw/$#R&ktn@Kh6?+!wW/Pqb^k>JZtHyWqNn6y\cTCJ!V4+bMbiYSiKZYlwk+e$:94e6DAEeGTye*=
&<k>ku e<K<>pJ#ct&Nyp>Gu^kI!XLq9wLG9CW4:l?%bhWTl9hV9::kMlyYw8KZVjb$u8Q/+E*1ZCy@=Y1\\IpL
II^nG\ kZ*HY*89P>P$PLY*F#u/qaDPC*4dq@nALKASkuI\>?R61q+jd!/99Cw!RcuI+ATLSAH#QCb@?FcL+JyZ
M:u=bi =PdF^FbV/84%48ViujDLYy<WiSYbm9C9DH+VGw1ZdVXVYh\pe@dSXk+jCmWBpZPKb+&JT+MVq<TKmP#B
iwu5uw y4j5yZZjeQJ$XyE$^Gk&LKlpYm?Vt$<:4d&*HEK8q$<H==mP/+/9El#XqLPqVQ^Y+$Yk<A/E6ikN55Y9
STiV>u VcCchy!=%mbK?41dmJAMNG@pqRCBSab?K8#TZD$tCb&ue+%$w4<I%bFG\I!Kq5#BYMGX$?hl61+XFBe<
XLNIG\ N</JIc?/bPq!#XiA*LG&ejkydqWPd>#d*>mPph!#$LlE?iGKCXtHDPQS8FJ+T%kmatFi!>hR4%LT^X:X
RiB%Q! c?SdC4JVI?c!FGt?<99IGWmnc8mwmRYnVDSNWY%DHLtCeekm9VYj4KI5S:FM5k*::S^VK6MY@uetSlqa
Bn1m%+ $?VnhA:MuLbMiclKL=5d5PAEb+8QFwF%1SKPEPXV%$u:HBuJ\TPnGptLq/%aKaqanZYtR%e%DNiqVV=M
bE/%98 94ScNP^/\n+#c&R>y/jkC9P?KKah=#WWZ16DaX6E#<w95:&Gjw+*Ea/@qyJnBQbm8?u^Ac9XheWq:E1q
KL<pam jncyRS5@q/w:^^?CjMy4aVIj\wScS&E:hi=EpnyEQPdi\<<bmD!CiD1>4F5nQwXypQ$lICT#yCmDK16e
t*V:!> Lhl<^?bE@PI<dje:1K=GBdN>Y%=IeD?C#*cwlDKtDVucyS6m&Sm1J^QHb#*AZSqPqcc#tBn9jyij1%?4
h+ejmI +B$?YTcBW%@M^?QKjQY^nGyn%4#uFbZ8Xd+pDtH\PC?mH?5c+uah^WGDk+D@?@FM@$5J?L?j>jRLBD\C
LupMZ> @E<CHw+BVMD@+GV?p?*=!iFSB/Z8ACn$u^\i>T6wBBA$Lmwbl9\6NAwAGmiFDpQ@FlwDBI%4/iAu<6K@
W?!n%\ kwaARMN^jdGj!E9@ClyI4MF^mCWk+QDjRkPJ6j%nGu?PS9+YGpm5+Tbp@/+9nj$Z?FBC>1Ck?#5lm$V<
SDTSyF lJD>h?ZyA$IYmpIm@&>%N@D1d69@&hZh9cZByA:nSDD@HFBmG&eJpkqBpIaeyw4/V\*k$Qbkm94$jpSM
al+MBP 1QMZm6:Qd$kcV8YI5kaSPNJWBBHR#:ATERnMmqMG1FIeHWkwYSmFN$Y5HktY4NaCEYXGjqJwmQuK#/A^
Bcd&TG !5Z^NDLS/CNKm&GMuBBWum9*yiuII^Qlaa&$Q*RcEI+&=C$BZm1nLc=i646I9^:5WjXZq+bS!6Y>^$$m
Dp/Ym@ Z$X?lD?4YI!\/Bq/tK8TZ:^YmnkdwH%YkKm!L+B89K4bl$E!ajGGyR!e<@!yeiwwEmnS8+ZnTmCQiZQt
H1ChWG l1T9>IV1itu9JLquJacH%NE/IhR#me@Fh#Ycp5/lG%S>LC=m*>mcj%HYKh*=Mp&hSKw>y%Q!XYWkbeyE
6RhclV aL1YZe8CmFqa%8QqLiXX?/aY&i5V:b$TBa!1j9=jWaQq8=<>%YbXQqpQStYhqTIc:<p<DmP*kpFX819t
y9T!it PpB&Z^9*!<Ql9VBNZ!\@tZ?R@6MIQ#tdt14ZmcJqSHT%+1QQ!lP\@JV$6a\Qc5?$WkeGQWy@<dktTy=e
+h$Mji Tnt#u#&GCH>G1%kiH>=T$89w@jDJltQq/?y?^kmVG>9TknZ8RRTB\1Qu6Jb%S/XE&wka16Zdn6/Xpcat
X?VBRG G#%jt9aH5jj>+pX^1p<lBHbBIt&RLqhW6ic+iS<FT545F5ykwP*4F?Z^T\$*RF?wCKk6QN$9GF#4Wtj6
N*^Kc% /D<Di@9WbQ*e!TDw$<GBHP1Mi8>=lu8S#R=H=P>W=kaQZ1WQL=J%tb4k4XubHIFhXub^Kp*XyuEajSQt
<HElKw ck?bq!!k8$9A?S+ijE<4!?wbReIIN!mCnL#JWtwlLu!HT5GItYX4I@$W91A@<Y!p!Jm9n$p#1:yeP!6@
uk*ny^ J@I8Ah8bwMG^w\pLP>t^e\98IX?Z\VIu$ytP=IbHn9ZCpiH!p>LF+cedS/FBn8t1M1TI%+Yebc*ID9c=
T&P+96 +c5449Cmw\!Q#96R&EV!1aqbpZSJykcckS/Eup:<&M^I\^hA^haG#umB*^TLEw<$9hep<@EByW\w@FT8
Bh<Vb$ Cy@YC56aiLGL4d>CXe$AJcin9T:%6klTbnLlD1imJEt8\SpJ#jSpl*l:%Yj^AZ45Qme6BKV>pqwj/?p8
CY41:P =QcI8HmR$y=<eF^\TQ5^Nq!&k:>qm/YF>#JSYbGy*KL>4H4YMZh%4nn<+KI@cL6GHBRyB*nenhVyBVe>
e59hR< lSKLG4%HGcZ+54F?Eu\b\i?uXHb>!AyP/jQ6eBVhDXT=IdA^qJ>VZS?=T\XZj?PW>PHd@SucbHG6mZ=C
mG&tRm LSpKXcqkpF8!aXqa$V965I@uqHuHH@CJun<mkVX&:Lc/>hG@XH%+Zdu!Zla!I&@$%yF5Cb=8nbM!Z&#b
*HJ9NJ 1qKEuS*ZYN5juAqdELDh5ebQL#S9Q@KR#=J9&$\SNp8#E9FT*deGhK4nt4/qKeJh?+nZ\:1bc+!KP!+K
KC$JeT *mjQXDk8^J+yqLauI8q==&FEM=Xk54Ywplwiu/+%KERlGX^cHLJV#Bd9n*mhktma%A=j!SVP/4tCX/$d
Micum5 w>Qm/\yZl*LB<JyLYS#w#Qk95dI9WNpTCL#Z#W\icq+paTMRnHVp>!M9pPYqXJZ=Kp%#@uGbjLE>y&mT
\GG64@ bMe#8ei6ieYyu6PtJVIMapuRc&^pkSSqnGjQXNmt^#GZ*/>>SnZT?WTiM*ZAI9PiTiX!Nq49nJIiXbi8
lmiG1^ V8jLE/1EE#w*t&^kNNk=jcY\t9Cbw49!5>+yc%y1d!dXLnD4uGlS=6S1HDaEn*:y$X@unFVA^Bc6kl^i
-A?1k+ 0001c5f768900110333 Page 108 of binaries1.zip
*C=\hT Y^^QY:*YY^PiP4:5aJ^PGjlwVPc=Vw!ydq+uBy&jT&?5eaYGeuuNE%M+8t\Vdq6XYeh$uCiPt<c#8atC
YeV&Vi ?@Inp5lh9:S1j>hl\Y^Yu:jPHH!%!ty!M9S#N>qV:L1WbneEc+=tenIcTBdpGuMpC=A54ZkbFPVA4WhF
ZaDX\% S>R#46\8dLi$b8RIh$&4/:bFQ8Bwq\w*Db4#h!Kk$>B=lHj/6uW!eRY!\d=F<nZSpFK@anALeaH9lTu^
aR\*?1 EawPqFWkhn=lJ/y/N$1l*4c1YD9VS4wTIY$m4eC/M%%X\VK<EmItF:Y5bP:4WeZi@:=^+y/H>YPtV4cF
kZwSb> B$?wGEGDP8D6myKu6+lyHq:yTIuQuh?>E*+BJJ^#LJMeLEiYFE98=^:PLHW!u#hRkI\mLQmitZQuk=8D
iyiR\C :muZDS>y%4imHe$6BIJR&BHS!#aZJhX51YI$yX<eQ?NJM&h\\WYtKL>9qVZLi6hjj6:*QLl>6DJ!1XCT
V5mBSM qX:6+h*\?/A+%iEPbwFWe\hJCdXL#nwQ\GqYJRq6Dja$Cl@HFqjiT#+wePy=uid9?!ykqKY+TtT**+/i
9aiLcR <R1?i@BAkh9C88jbDptbnC5%y$?MNn?:^@d%>nB4?A:wtQ9ZW&+FD>9>*lEwtH/+c^>+uZ^+=Nd8#8NM
!=@l=h @5%LKN&5e/nH9A\>1/b*XL8p%X=R>$p9%1Rt1V>iZ848LlH$mlHBq*ykbWc#$Pam*Kj#eb1?ehjEQJ8$
wENmAc w5\d&?:wtytLWKFuAe5l<t/u?y>n8HdYZ6TEXL5@>CGj=@AFt<XG41@9qwJ4GAKV%\6y?ZLG<%w8G8iq
tLn<N6 &$$X*#RiQ/6nj</*/JXkFFZ/5NRdp@me5?a48mPW=?=K^L$w+:mGjb11B@p<TN6u?TTi9<#6n=PQZNu9
SjuP*8 9#Y9Ka/EVi<8pXFb44%jW>$$:^^*Wb1b<:X$X>>+XYR45&q&lCRXFK\tT%au+<w$!&&cR<\n&Xlu*tm=
+YXV:t SMN&Lu?i\Mb*mR49ZiqpRT\JXhS%?%j%dbVlD85G#\mVHVPeP:9M!ia*45<dp%ySIWm*yeqMM\lJ^H*L
bX5E5T +lTM%C\NPE&^4p6+&Nk4\6uGS8GXX?hWk61d5dG?G8FT+58BP$Iuh8!M#H5GTa4eZ+1W&c8Auh65*%ew
PaIccq cZK44WjXhjRFdyBP:ckEu!WZQ?5:<!mm5&c4TPj$%nW=+YSH6K8c6<t!J+WIi&^E8*qienhjiMLy!W<4
Rq&/S5 94LC+$<m!$AYY//LK%/&*@\Z*6FdPeaJKQqF<^4HpXm65tkNmYFQ%%&$VmaHmbK8lbKy^h<@DS:1F8/$
cQ1eJ8 \DC$e6IVpe#FtXe4d%/J!QlAuul%9b1c55ly=j4NyR<$iD&$dj1DeuSJ%Ma#R?d%dlL1MmYcY$yquWZG
?Wk$SL eeFi^hQq$k4*6>VM8CpRd#Kpw:%9=we?=N#bXMbQ%mm+mE&<+cmRqI&tWFRA6i/R?Db98t%c^cbL=4\n
Ae/MPI FTBuYCT4nel/=E\uPYmMY=WV<jhDXj/Z5kX@Q/HqF>kCJP1jdAETCbk6?DFl?M?y!E?PjDuaD@@9SXA+
Z=^Je\ =y+@PjLqJ&kWGkecDkCNp&9+!bE99+JGApHntuMnWL?FSkNA+?RcEJnjRTQBRNC+PJcj!Ld?ClyI4MF^
:Rqk@H Fd$lad?FBlJ48Gj5j>h6^j+LjPmM@cB1/98MHRZ=!a#>*^Xh@=1^R>GR@>?WWGZ>H!@MtBZ/ZblSILJa
aDTjkb \9F?yLLF<qEl/p+5VCT#$=cB#E<qhcn$TJ*>p%L1BR5S+i^5&*>1Mk4K@/uJtH6K/lMtCqJk*mc4ey9n
Mc&m6\ cSTM^BASZVX1hL<u$*GyRhk5^d%j&!NIX*S+6HtJyh@CkSN#L?+CNnPIWZCbwe\5G/WQSZD%KIypXlG4
EXWn$l 1#wb*5PEH%XSb^S/H<ZPyJNa**Y?*/JCe:n<qMRE@KuZlbNmI+m%ZhaKn%Fh8QK>li^nb?%bu<6w1Key
iQ<=@+ C<pGQH#K&HQQ@\%=@@1qIe?KTtYIbit:*9+t^M:Xi++\mP<c\=kH&V4D4I4kBWi\pAWIWTq+Ay@ljNN6
/&iuId $Ju?VDq1Z!I$QeJCB?K:iuPlq<E5Y9Z!&ej1L<+@J*KpjC84?dV5W>11V46PRpZVLM#I/9IS1R\hu?AQ
BhwV/k p>&R8T%iLHK>6l&D/cBQ&&HYm6N=yFqV/6QmwVwW?jDlGLX%cB>mQiFbFi!<y$:/*BE=ip!b:9BHy4J/
t*jSWy J8\bN!QS>awkA1y&BuK@t$I5n!mtFYKEDL>?:64$q1hlkI56Vd#6nb!PHH>>Y?/4:nS51dnaV#Q*YKq:
?54yT? YwYN/ydtB>GnT:%S8lnbtyt8mLEH=Ibi54%*lHTCyw49ui&+6?8hZl!9*Ch%>5?K1qb+uKKu$$iBD#:#
C$kHp% y:Tj+<>wMCLtG5\HbI%b+W*#WhjZYMA*EnicVabT%b\1tG@hZ*l$VC6NSRmdLTInVKZ*MM#H/5EWIT1<
Hj=+<S /PpuF:8m&Xu?ibKu!yie!H%#%$/QjqMujV8J6Yj\K>huX&iQ=\AJ9BBM^nbQS^A<quZ+$lem<=Cm==J:
E\$\YC TLTMKQntm9j^ZRF=9K:Ma&DVTdNJjyl>bpjy#t5/FkYwIVtcmd?K+GmeyVTX&YP@$6D\l@wQ9HTHMI+<
lhH$X/ kcaYS%96QM4eYqJ*H8Gbi&A9kGeiB6DDI$pt+Ji\P?$T#d4ZMu^wVdkK*^:X\Wa!9$p%yLmV#mM%dhhu
l%jW*# D:dp8Y\IqylpjV=Mb?da!TIReA#QV<KCeq8u>%#:CiNe!eR#=JpB\mtpZM\SEXcXyRMRL>%HteMP5E&c
J%=C+i lt+i64W?6:Vpp1amlHqh/E&LP4KX/9q<k6V&pjB<wbAXluQe+pWV&?:u1jH/m4DYqLw6&&hn\G#MNYL8
$dW@NM S!TEA\5?euKSaN>4$$>^Y+p!hld\?N<F<=IjEiQDn!%k!aR>DaI6HiY>bK+RuwQR!=\%:$+i4e81dNZ8
*p>lDL **qa>d/iYhL?\jWlWT1Nmlqt=XbacASde\<b$tDI>+^IStNV\Zb\JKjB$wZ8$wCiWCpDXn<QuZBNATaY
H#u+w1 :hcCJk>Dqe45pmXG6jEyA$PG9CMlbAZqB9dFi#NkV\Xd65ibkRNbhNA\@mD6%^y8ZlV>ya$CtJLcwpp9
6mib#N XejkPlZ6VZJ#\njyL8eqPNcaQ6nM#@Aum6&uL&TX!I?99+P*/HJM#*8M6QZ$XVKmX+PVLaRD$uX=QYcQ
X+&H:w Cd\1/QbcSFqn#W8i+cZKbGp5^Y!8lp\&^$VEC4#MY5=InHBt!>nB*:dd6VGdHFq:946KX:ulbSHuSCRF
8QCbGS @+RHceQL?+ZKBl\T#lh/l&:y^w?=/iaPy8lbNV>kNbEV<t?!w8<Hhaa*jw!n+/4a!b6J*w*<KqSlE$K%
WTkEJp <#Rp#?Ct8dRZ1McPweN?Ja@&m185dR*V$ailD6Pc%YtilWbhSj^QDd+!c8e?IiB9tVBeGa%%441nK@ey
dWaE#b k98%?ZM=<55nlm^lZlGLBqBl4\bDC:Jl?1n=Y&ZD#Ehb1cJb?+:h5C@yLjyetYK\*ikt$l\l!LC$>K!:
yh<%=R &EwReWQD<?HZhAMw&LElm\eD8V=!K5C\@:!ZJ1!mXaZYK$unc*p6?RQbGeLCDyA:n*T&Ci@y6Q/:Y$Q$
mZ1huW cF$Qa?tMm=H^Ck!atu6m!YSkWyV%9CG@EBNuwEhIS1+nmCp11@nBlK4nNJ>am&H5tD$$nKRd*Yd:G8FZ
@!JXSL GHBFwpjP:nkqVR8J$<lM=WR>W&#V1%:C<IIS>X81Wy6G6du&#n&aw^hPMl:V^ZnE*YF5Z&>@Y8$nDiej
Wu>!H* PNX&DHP9c51WMnPwK8@^!VT&ybJB%KYt%nQ91M@:LQcCX=yC\M65NWXYw&4/#E1nV+<:TE%/Fq9I9:4\
qFH8>N RA/T!pN%=h#qXeyC6t#lJmJY8&N=Fe%9S%I8nt!+jhFCenajX$5ajST!q+npt6>iV:W*PA88=nHV9NXX
^A$1An ulZ?=1\mYK5me94#Bb=4mGZ:#ej*Pb>EcH9696GJcZ<R:jwT>mXtpE=h5pBtJ*%e:eq=R:\QL!pDFaXu
l^mPNh BGq:Q=&MjHc9puR*mNd?t<b4TbQqc1Yq5ywKGmt*c$K#c1>ZEQ+Pw@eC+P?jEl6FiM<W=#a<?1DcJHdl
Ce^8b1 $hM<:b41D%j!i:XNZ#nuZ*:Wi/$J%HQV?hl%AciEMEQ9H6?iS=Z^&/i1PwP>$ml:d4nwRWDdCye8uM6M
8N$be6 >nT=@WF>?>WIE&*#K=mlRjlGNtF1T!J1?FEn19&B>aL*Vl9M&1dc:8QmK!FP/D8<@Eeh5m&9uMK<R6$/
a^#8G@ pY?tubkI$4d6k^eCcYl?Pyu:8+:>@>LJ*N>F<Z>lMwiC@ZM!l+ICu5#>GE9?a=V/p/uBD$$#IIQeu<n5
HY!JLl @^Ie<y>nbCV/j#^GQqnI&l<nw=A@$!#/h\Z?9<VL>&aD@*hSC?Cmqp!FylC#R#CHQ*Y>K!@1/neyj@Zq
PBB&Tk te@SWcEGu/QtPcib^ieLPkmC#TSY+I%duF??SpiBDd/G8q#SuBB9p4d>KJphIE><D88k\p^EIMbJJYEt
$6&t6! $WJ:dqbmeBLb%<n\+lRJ!W<d/h<QQ9m%S9yjdw=@Q!<BiHNE@c9y@hWeWTkIkPaw/i#5+9qhcSD=w*ID
>tiN6Y kn!RE$RmaAeZmIML%MHF\e*Ik=8SB$1DTPVB*emD8=EHh/MPuwk/?Aq%<BQ/+EHw9^/EQukR?8B8>MHh
u!^S@P tIP:MRhQ^B#enDt+GjPnMWJR+B>*w*=wD?=hIA+8WAeZQ^/Nkl#eDDt+?eiH*Z5R=PB8!MHh$IP:wRh*
:S:qWN R\<iDV&+GZy\<<GP%d&4k=6kB#jBDt/CH#\Sj9BE?MHN<IPd+Z@>%R+?F84ka/EPQld1+GPlDn+Y/8Bn
/jJVbY wR+?Ei1AqQ84c#:w\9dmB@#VQ9wuy*Ie!E*?&$+\KA:K:Ciue9\V9j?bj+=GAWHDeP!A?<tyHD>B:*Z9
kjtaT! Q$hnkKDBPC#@!cpe@$RnMHAecAkRNBwHdaYGApEneZ\^NA\IG6h?TVReCB1P\?hwILGG5:AIDTVY>9jk
=/^BF# @l\NJNaRPM=\RcCB^N1?HPnQ$WBmdj><uJ?mMWBmDbjaJkIDJNdkMB!Ya+DEGl!MC\$p%tBwZJaDmVWa
V8bp%S C6i:keRcDFiea+DEGk^ZuGPA^B18W?<SGCC^BwQkiniRYMMqWawEA+p%KB1PA\$p%1BIDA+$pFmDIyA+
h6J+mM $EBmDaynKRAJBlJ4WCm8h\PJNTkE%:8B^BwEk?9hRGINk5d%dmC^6njk\+EGEt5RBI=*R+DEGlIP^wGG
H5n%cB AM4?CB^wILG&d?HQ$aB!KAdZ8\HqWDRWB^yRDpZmcN<RRDpWki9hkHIwDNi:$aC!Q/=*a\Dqd^^>C^SR
mj8/Q> D5W^ZpNCAiXRFK=*A<1leF^wGKD<ne6!ILEGl?JwwXAEwP!Q^wEGqEN^/JpkwaB!KA4Z8\HqWCT8h&MA
eaEQt\ bZ<e:+aBmVWaDMi:aSBA&S@Z8+HEG1/VCyE\RDpWni9hkHIwC6i:AiXRBK=*I\Fqj^\>Mk^I4EF^nJGS
k1S+SE MCC^BkZnRkQKwVnG!Ek+pFmD+BknI?FAak$u\a1ER*<QDkPW@*GMQiD\*$Injk8N@C$$/4jR/N>C@#*c
du&9!t 4D\<&WWW+eIRaVRWC6%4@ke5=Zeiei>QYq:tu6@@l+1h5<N*p6LC<@9bAYD&@hp<dG@M9n@d?W+*8dld
Y8d?qX Y4u9@Rn?@5>@9lpBcLTHk&hC@4%K:ajhmH&:\YA\Ek4Wd8niTH&j9@>8>>+5Bwnh\EcKPQ#>H\Xyj:Md
\TPacR mkB5>*::*>?i>N*89SpREL8BnVJ^nNZ?w=n6:*d9BSFk8?H5?%5n9>8>%>/B&A%wlI4CMh:=n$K+@/4h
HFuk+= $L$^#d/m&ui:aYBAhkMc*TJ^nG+SGB^&w#AaFA\M&P/>@L<9y9ZhdkmkhwpE^GVmG85kD&tZ$L*BJ>A+
-A5jI^ 00077efc7c800110333 Page 109 of binaries1.zip
Jl#61@ &Z9P@1c?:*cDAeWJElALC5PSN=GH6p5IaL5^aQd>$/H*:h=u@+DaDj?hYSD!$HcJA6+8>?#ht>X@6*9Q
kHZdLE jmB&I*>u@wXE@jja9hjK+H6>/ui:pRlAhkNnduH$*$me?SKM&F>*A^#j<L$=G8yQ8?EaIHcnAM%aejE/
NA=cBp KEA#XkTPZlRF@T*$IY$LkkHiJ?#%mj8#\?<?A\Q/%mlA5%$ant?NAndd^SHlkFdCeKNSPMhqEQCiaWB>
DnkJEX 6nePkeH@nDMaAqmeAbwya*DF&YH6A\/<H>&L>9$b<Zi:+aC?NcAXPBkK^:hGH=K*IGnA?SaC*jM%=Ii@
IX6%E4 waD<DYn%DwdE+Y@$aY$LDZ#<n6\jA@<=uwSBAI$uAc*<+iSE$InD?kVkeRKF5EQ*<8^*8@j?BYI*IBaK
k184j: F*?G^6p8\YkWBHme:MWIFQYu9/FwaQ=G@\+QlMae%y@Aka?D>@!N@NQjWBRkj\Nc4h!Q9b@cnVq5uweG
iwAy4W Qq@c/#KlQ@yBKLB?ENBKJ^VHCm<TA#9Md8B^56hjRTGaQ?*it#eB5S5R/+b4*wE=4F*8lTDkhkuim=W@
DIK>a\ ?&<wBFD@nRHG&PGau&IP#bjIZ@E*BQ*D*&Bk@kdE>5F\?S6#!Dka@A9<C&K@^Pm:*j9e\Q@adlT\qX$e
y#aY?> c6MwMPTRQA<D#kj5=en9+:y>8%ERRHaDcyhkKA/:D^&LAt?Zi?$EA9@ld\R\j<MB<d1+@H%w8\V8:#$j
>n@4!G :@9<8>%\aQ+G6B1N\8X9*QpT8n?y@bZ+l9#\N^Ta9\G6bCN\?S6#tN&A+&V@=NL>TwV>M\!RkQyBFMBX
5T6eNQ <J?Qa%GR\<c^TMD>IG#9%u$8eN@8@RwTIHaD+pXlEB^&\*D**@9cX$D6*u9njtp9dJ>uBNaQAqy>^<Zu
IGBN\n wmCIR?^GAQj*Z9dd6@8:9\Hcnj\68*HuT#Ac?J\e95<9\8F@&k&Il$aBY@ZH5ccIkl!TL@euZED>9Vjt
i%*&Bh *8h^9>5NB#KPSRG1GMDFR/PkpMQYYaD*J/l>t*@+G\4I*+C1DSA+%qFSWJ#6et<eC>#j<L*96u>k>Zi:
VHFXWI IeD<Dc!!FJi@Eajb@R9>CbRhn9:V*@8eIBC:AjGmWF#?Q1Sha8CIZ:IdBj*VdpD4YmlAFSIIHIJ#KCnt
MDq8%+ pQ+EBVnQ:*NWeMTjiRiPBJS*AFXZIHC561Nk8Mi^5H*K>SjcJS#?\><IRQ+GXJpB^:HPn\JWtRHH%cwB
?%#%AW XYdkSl?Y<%DA&^b!d#/P@nQu\VCAel/k1k++nnycFA^%&NkjBj^d\*:$\@9nDEB>GcCKEDkES%<GP*VN
VZWeIm +Sj/M5li?$L?cVeT!BwQCqA%Cc=1d^V<pLc%9%ZqF@wEGQ!H9^GA@A&wEAYGw&wbBeih<>C@\DuB>6i=
p6JVTK wj9<?>=@aeD<@V5X:mn+wZNE+QG>>=^>8:@:G/Dh!N?!G&jPk/D*F>\An?u&+kV!I$/k\PIEEKiK\BWu
uAqdKP l?R<DARG9F&m&cGaH@+GA@I*wNwbGI=KcSRCh:6EI*?lH>##N^V>y:?lGED?BqR:A+Qm<DeChqk@CH!8
4yLLTt 6Vi*kCL@>DeWBe#jkNwqBJi@D&8ZKMD?*1?4lTJ??B5J#N?APFWMLu<j\1u8D!y@wj?G\u:+G\:M*+A+
@m@d#F XVR8j^<!S+SAkM>b>9Lqu*W@i*bDkhS!wADX#pB^:H>AITGH>TjA@d$*5wSk@l^ZRRG6p/MA%e=Aec!V
6J>DEw w=CA1wS^4HTnANY@+EanDy6ZA<@X?:\@@M>9DWEC?>dAh8uk?6cH#jMk\P*i5^pC?@NdR?DA9nWkZlTF
5>Jm\t /%9@+/nGH>m@NBV&C@Z*ySd&q<APNBV?&118>1>>^*>@:6?4Y*:&*L?$GcCRk?j?Jei\@%\MG9G#=$J?
bR>WRl w5&\9+Q!@?Q/bY*Dtj#Pep^DSRq44b/YmK!IaA8MD^5DlJW<PECnhm=Tt$NuRYM:N=KBq#Y1nX6ct#$C
y%>c\8 TcRZ*EL!:ctL\W51#9k+9AqZ^DH9lY#dBS<DBNP8k^cN>1+DCVMq:+=L4:<Bt/A\4?%PV6le!WdB1c#R
#4Wl<p etK\qkiwIH!CwT^HmcW%WJnA6SMcR*Y:/GZPt6b:9%b\yXTMYKc@Yq^S:Ju1#ZNtHp>I$b5i$Yhc!M<W
AcV5tV QM%XVaWjI/ai4w^Y+MQHMIA!t**j!ldX!:NIqXtpXWb!b5QdKASJ>tZQ>LYEKW4b5bkkIR8nnaIXkY6H
q=uKZ/ uy^KP=1PEd=!qq1^8=j4cIMI&DJLuZK$6pmNj*61CqQMCYaI:tPFM^ESZF1BDl&S^tjYmK>lc1=W^t4G
KdNcn* EFGTLZMFEbBwNqWLSWu%KWeKd6$9>b^bFqAbKdyI!y&b1nC9S1Z=kp?c#HIX46c*<\b$Jtb$q?X?tFde
Xa$WYc BTm&nyFj1TpBKcwMu%\ZEc:mNmjm/?ekEk@&?PyBPmny/&IntM*K!/\eYd*XX:%JkH=R=WZnwE1Wiii%
+H$</@ l91SVm^T/Nm:F*w/1qMh$J1c^NFA>Ku+EKQ#F:t!damPFNmbFQQDZ\jQ4l4P8\d9EN&TW9K$Z&AGPW+5
p*l8#Y ucu8yX8DKe@Kky6tGQyP!V#ZX@W:j:?jVG^#!yNBR?4B/&DI/au#:*Jn%J>SBbBN:ZJ$w^dYddFu6I+>
u$R\>j jGMHm=^aX^&/YjP6aeBMa4IlmMF@9c4M$:t&4?d!eFYRu/K6m<hy6dMEaT5yBSdbE@^L4?46dwFpCWHp
A^DK66 SIP>qEhWN<X/@b!$FCwRF>TXHB%TuJKE/Ap+FdWeV#Ve4$!eJ=jyHy:R8AlT+<XCSJl4mu9ec1iZ6nkG
&B+CNL \8Z^iD>GB^udb6:E!?/jnjFp8ZmV!CZ@DV>Q:8WliIBLFSS8PkQhQm6HC*8@Fc@G^8X^+%wDb1I</Qn!
EGH5ZN ydGk%%@ElN4ijKw*Knp/hDdWDl9bAmMZhm>>5qtR+9/S%>uwjkZl%mNJ=R<191$Qu>ST9WyR4n5mV<nc
m%aae+ AGJQ\&a>Mw<<Q>8R>aCI9Y4Vd1CS/Y=??wZS!Y?W5\X>LLy1BY\P:Syq%!dKq#pMS@$@&Im+p&S!cE<u
$6G+PN Y#Tcb#SVNb%iJWpVa\bS^Epn@ChYYZbjt!:&!jES95FQj$:tL=QGRtDq?Ny\m5Wqa=^DQBlGG$*Yy6@S
*jw9cn bpqkqRR/^th&ij%N4!!N?iPY:CkVEbuP*PbFmwB5w88#$cJ<=\t:5u4PPMh1NM5R$\!?FKVRY=mbTKm<
WheN=J Il9H:+LW6PJpNbXRQCG1Kpu5qMG+aP$TX<SEw1uC!Vq<TV&iR+y*8%$6K*D1Cy$=TBh:8XZa=mlVC9+H
Qn*XEQ TFC8EHN%@XKmTy8%uP\NFk<pC#*bda>amYiTQD+9uwyFZ>#R8KdW^S<Vh$ST11>jneNh*IXcAtM&9KcS
DeGed1 VXD9VJ9NAKZPTFNcFedQ#bJYIF:#\Cjc$W9i&alejiHi!l+eHj9=Bc1nqdYTyIqGQ=5*6J\lEd5aQjCW
ln4V\h Vap@M9FWid9nP@QW:i^&NWJ@*:41hLyLNpR:4%K&l8*GKuln%KeF?M*jIJluTZnyM>@IMdMHW!VS/&69
615&Gd #PX*VqVc>lG=idI%qM@pYb4WcejBid<\MEbIV!Tc??S6bnI&%=ht%!6enlN1C/:wZ1iGERiYhJ:FnI>w
nZJB#B #/+&ZF%>XV>/5:Ne<5+FKS5mFCib<QBEyNIqw5SV*VZmF88Ba%K!tLNq*jiR#%<bSjc^q?q*nV+aQ/6R
46LcKJ IbDMI@mPY>Zp+Z4MWb/$&:5qN/#HLtI&SB?jH9VRYj@WG!qet>5<Pd$Y$VJyw6KXRmCNbFElt>X?X!yk
q^>9B# YDF5IjV<hES8T6?=m*JQ:mm/8JXpMdh\9HGN=E@ThlajSptdp^hRFla4tIihS?EH>yDNZH5ViB>hnVT&
DI<<ed w\nRFE//\b<%dhhV@Ld$+wpC9mLZF>T!WdhFwHjV61!ylP\p^BaliZIVL@ZC9>/=kQTV%je5?V4B=&JN
jH8NTd $*XSm%HubLqjy1GDJ/9R?*NZ^wd=*c#9!LRh&&TKpQyAiSM@tdi:%+BB%hd9XZhhdMCRPu<4e&NGN5FM
cG:%bh 9Q?/m/y<%Nm#%kuaCh15T:^JF:?SM1\wH!8=X6Tb6QSYVDawKY6X6BaSe=1J+eGJP$+8:ty?\1CK+c=S
<1*E9# yjS#jK=utPtXFTAyqyTwqcd:VJjNw>+wkydyBcjQ/N*pXW&W8pI8hV:6y9XYSATF&&1AtVSBXCFBZHTi
ZXke+I VF?6V$FkLN6EYWZ<Khai\\InHw94iE*LWP&caM:%TE&a9QyVDqqyA%D5aGMtb9HbyRc9S*^N6jd9:eew
hNtWB? m=iMmMjX=abEL99&Y4N%cdqMY#^<9tk\bS>tEp^FjLTG@6w>pN8nCwXwk<<cjknl$J684P:QTb:JIa#d
V=5AWa 1==#8n4YnqSJTqljWb/C*8\5Y^<9hXCiHL@Dtu@#W8Z^?CHWuT=Z?=d5Cy@H$<4=hl5*6htR@S@t!99F
KcMQ*/ iX6F<*TC^RaJPdGDt:R$/ak4cPJe468BDEy5ZF#DTm:M?QF4#NLp8a?\qFVM>I^%:+=\ZCaKq4eW^4=<
6h:?+X 6!Mu+j!cc=w!LQ#TuhBkqTNhG^p#:=+c/4wZ*a=5uIe%+Yt5NF&m%qV6GGnijtP$we#S/@#=CB9bF@i^
8cN@YF Ecw%bN6E=u66pQdwtDD9Y<wV^<=:SR?8>G!#@YFucWZbmbVejnl&@ed8Kjq6?p@e/lWTqJ:M1<S$+Z+q
w>!j## @Ip9XR!i*IWP>QDM^e6@cc%:/$q?am\6?JGRuSC^KEYTG\XJba&:*5MmP=Xq4KE1e*ky&J$+@Nc:%!ij
mC%#\T q6d/D8#iu!PCQu\<qB\5b>NRGLI=^1ZG%h1HcKpY#myweA>:&dHw<EcH9jCPlT:qp+Byy###\89+ibSQ
*QahYp :5n^Q/&bRAp4DD/kwy5eFpQLJK=t#:#c$M!&wmB^YAq&?pd%!4wBd+LTX#@Zj=y5ZykTjIKTZ$#wqhmC
N=lw5* 5lIjGQTHdiBqmplm5Qn:Q5?dHit:?E6?JDuGy/8Nk>R?#p&a&LB=<FCaYt94KDm8kK:I!ap8LQE?LS6<
I&Z$+A 8wRlnGTbJy<IHHA*/XD1aJ>=InWNCaJTdKX1#\*DF#eyKY!%F4?a?K>S?9cuPJRRCc!VpXpS8FA>cyu4
9yl>eW wyVL:<h89B1@XDE8%69cyebSFY&h%<Ll6yYiR=N#jc8R&4XEPWD6?4\PeVAVT4YQpMb@qTa+6H8Ju:?N
w8K@Kp eDPLKqJWPHh8cYMn*DFYI<>$k*lC5n@<Vdn9C@ulKALQkwwa9LA4#jKT%DJ91CN&NGK@tY!%c9n&D*SY
>NMp!> T$pQb6Q+8qREWZEHHe8:Thl>ndGNS!PA>%GRC8\$F4dC5C9LyLPiY4yIV$q:pdmEmDdPn\1QIV/5KH&i
WM!C:4 K$$SLlQZidhQZ%#YGVtAQ55*liJVW&#jJRuVV?<!*i:cWemc=QVZXt%yd!*Z4%<K@EBEISKm4T&@ciC@
pikD1# C\ym$uVN$4L8*R%m<PXtX@bhwuIyCddJE*KW1/jD8/#WQPccmP&h#9XjI<PLluKC!GlynpmyhhJin&h*
bCid:G 4Kp$aXRiDZTieaMaWct6cIS8GJn9c1=NCY9AZ/=ebPYkpSF=^<N>BXS5kD+h/*>Q6%bP:uEd<86AeLT@
iHuD\X \m$41E=8u9Ym1CQhcX==RaQV4+<yM1RP%L%^4I=Zm:h\j<4Whw5>+m^:l>mN+F1l%#pNT?aj\<e@W#Wh
:!e&Qc K&qlDiPpHRy<JZWG:KV>PH=FMCPWbC@kNl8:8?/B+=ViLQl8e$S8&#i8KH+S>5jiMT<GL\!/XHBew=dn
GDKTA9 :dLX:d%^5p1C4^#>:y=C+=DK&/\/4yX/me1F8M$5pSC\F9FHA%/Y$lb^+c^F<q\=#=llS?l8VqYk>9JH
h?qZQS =i/u9N9D84HZTIbVcm^!lSaD8jPPp+\edSNi\DcGi4:c91F1VbRS1&Z4/4H=nu!S\*ESclL!tnMY:i#9
-ApDn< 0002423219b00110333 Page 110 of binaries1.zip
WcIKHM G/Wq1Kb==+#@k*Pe&%HPcWN4%!AbG5LDD&nwhCS=HwFCNn>bC*4T<XyD6<HS@Nd$\cX&JLZ>Z#tGDdn#
AKn8ny V4B4XSKSu#@ZM<lbwjDbqbk@9HI59pSIaENwWc^^W%Abj>e*c^i$hXE\%E4PI*Ip65TZjTY/a/&\bNR9
wYTQFA <mIqL^h*&c%#VyicGFT+w\M9k#hK4LM51*yAGj*kanpl:w>LYW81nhkm%Y<Wlj=P\8Ce\lD=:j:eILy&
%HuD/j \1%d#9bLba&Qq4cik1h8J%A!LIhnXh*+HXQpmNMHbMhl>9bCM?*ZdR!YZ!W?uQ6t!m@%86L\YJYAnIX#
#=b@cS VR*9#SF9Y?%!>6^TkXBQCt9:FGt+DdE<5?\y#mICuyX+w&wKa==1n<%XneVVS:t=NcTthdT9E?X?/hj&
?m$mqD jE&!Cjj!6F<:V#ac?*1\V4uCStG>#4$Q:6W6Jy\4F1!V>R^^phl<cZqudhZFPtRnyhQB=+<Yj*V&AJbT
>BS!Y$ V/I^6HB==WEC#&!ueDPqh@V1a#cPc&!YMtq^A!e6F6Ap\+?4=P+WK5py#mTB?KCpK$tFRmeYIp=!9nPS
M%y5\Y 8SIbTI1EEp4qH%&tYC6%/R?*i5*iwWnh1Rtn1lmBG1DbZe5T:#DBQ>y^?XtPNN?5wKl1nKAkpNGYlVwq
R5RyEH ^lH\hDBRSI8N1=@LESih\*G8H?49Y!H?!?KP@%WJPhVjN%MAq=DDwQ<y#+>BI*>JRk+N@@Q?9R9W\eWQ
Ltqj:b NVH$kW+b?pCuDH$kV+a?pChDH$ky:q$h@HckSwbGHiBSmIPLk*5PJPVRB^J!/L<p=NAHEuLwA\p=>IGE
S:5kb# HQyARk=>ICGHQyCR\^#w^YHAB\@CkQ@/DZX\<iNBtAQBPM!BaB\GeuD#kX+eB94Zk\:p+VDR9*+:iBD5
i^@H&j +EG\k\eh!MSlDtVmMQADCVuMkV\e=pAiDuQka<!Bn#GI9*+/\B<+G+Q</$HIk:5QXPE\B?:HHLkje?B?
D4QY<5 #IGCH?dkP&B?jIi>B^%<CM#Bl<D<?BB@1e5hpDD@TS9>bCMP/5id@pW/wZB5epQ>bCQPQ>G+JPqRQ>tI
j=y\dj <$<$EleJ@lNJ8y?keY!:R9%pM<%Q$DnphFA@pcV:CSwZuj!VDVE@RWN^wTFA$GAeq9>pW<5@$RkeWl?w
XI4IZh u$nT@RTN^IWGEt8+N4Cm$EBmDRHD>Y+k5acA+Hw*pFnDJWtHRkPJNVkKF^yI4PE5CeEAmVXepuRwDJBa
Jc:$NB \!XJl<IAmVXeJ&YmMEBmDYiJA\bI4MF\FZXnkMRcDFhJIRbI4PHcPIdCAIp%GK=!ZR!RYIQlKn:FAIp%
5dLwLw ZKI$cDCRYMMqTwMGA+p%KA:ySVRaTK#6d=D/PSyI4PETyWGDkeRcLqEcNBlI4EEl8N+NJNb\Th1k\WBm
BmtVAk DhjYB#RaWA:F5hCGBkQKwVmY8>ARRDpWS^6DR\DqWDm8h\PJNTTPVITG\ABqj^^jDAIHqQ%^SA5EWA:F
i*m$F$ RHGkAiXRFI=wkRDKwWk+DnRcWQdHleaA!9+@Z<yGR<GA5n?PcIEC!1E+S4qwKKAem5JqPcAem59uWDmk
+>uC*= :I<LnRCW@ZFbnkTW@ZH=HFAP^hW#RRHqWB!ChtkwwB!K+&^!NA^I4MERPHwHGAVR&AFHC+WBmVXeSYBw
qkQ>IF GA#R!APH#&GAemkP<R<$DFAPSiN/N/Aem5V%dmC^l18$CA%DA^w:+Hw*pFmDRuFpInmk<S1P+np$HEm5
>!@+Cn RZBI1/LlWEAnD^!bCA+p%mA+yFZSeCC^BpHkiniRYMPyyaj?n+4e@*u%SYn+wV5?kT5::HW???yh?>MA
#ej^mq JKChIGk+pCBH+S1pHq4NC*#u#d/TB9K:M68i*aB&^KESkAcb8IdHmEMX6+D9&N>4@Q61i>@6lwMB&R%w
MaQ*X+ kIynb#AceemPV#n!F*a$w>n*FbT@&\$F=t>Ak%5ELu<nAA*LeWRbA9qd/MM1emHAa*VQA@9uRi#:dQ@p
bykm4i CmA?A#RJk?D/%wiw&i&#kL?k#4Bj/Q*hdpA:YNBIRIN1HMeHw=ERRFMSHH>4JQT*$LDjR5N@C+$+yNIi
@+K:@Q ?M/h@d+R5d@T6j?>AP*IRCMBVj=\:MlA+%TX?^=ukN5HhG<K84@d<:9haGB^Bt#mmC9PDqFl*Shb@+Z&
VLR5Zq AWj@/Y<+wB$bcBTk>wF4MI+/VAZpF%SBMRj1k#CA/wNwFKC&lcN1HI$CNGHFNT\E6JmFG**wLm*w4!mN
SIJ6GM \cHk9d!N?4+LH+nQpL<#VWeh8u9!F=R<MN@6@9/6Ah1N@m&:D>5Nk9/qeS$e@Ph+FA+BNB+F6AAH^#Xq
Ri&yia R$MPW<SA@IyC=y?1mVCA1wqwRI6*8FRV$ilDh&qljpXSGwd/$>@:P<&A&A&wZWJ^?S9^*/Qa6Ve1*n>H
&AR4+m +L9hKGD?@m$TCu%I8\V@R5/DR4<VQ98m*#BA8<9RkBaeeb*ukEajyuAMl\FZPEb>6@8:9+HbDYm^E1jh
IYCk$w l!4TAjj*j1/G\j:MiVBA8?LRkBa/aVl&^cEQX/TD@%J@A6*jJdZ*Z^mk?Ac&TI1LSnqWpi+Z=n#:8@cl
@PYmNI Q>wqRL8S9&W*IHIan864wZ<LnjpNNAdRAm68>GEKXMAXa@bX+cA@^wVAh8qmAC*P\uCMCVHk\@IYHQmJ
CaZJXV Awk>i&F@#1**h?5C5S9?G:R!Bu#aZP$ZiK5>t:@ukH&:aZBAh9<Pwa$BH:L4H+Z<ljEp:Q58*i>&R+H=
q>/iPJ G@$dXDwGjKkcB@B?hC>9:R?d9>5NB8S9RI9S8El<DPTR<TV+F=VL>&/FwQ:$N\TR\n$G$EI&FMi+DAM=
m@RX#L VIEK>k8KyND9a*nI@8=wFDB@A&1ZaF#?Q1^hItC@FCjIQ?ME1N*I*:Id>h?!i*=jEZJ@49jhdmREpN%w
wIp1eJ RE5>MB^&a*/D@eeAYu#Hnad<Fl4/Y?lD%GwR\E?WkWQS:Q6uV*%Z1pRA?q/AF8/SPHkRDQR\FTp+?FeW
$Tk^iZ H@jQ^Q68N/B^HRdRwn<T^:kPe+lCG?RZVwDaX&BC@FB>RRLmGDGACkcRPDlG#CEKdZ9?@kXqWQD*5!n@
?%@d>$ XAaF%B@BkBWm+?mQaIh^nEnw4/n5:K<b@Kt\CTl9ATyWRPIwNeDAaIh^$iBjW1yEIQ/$G+pCbDek:l?D
!hJT4X ^tH*Ii$T@k6Kj9915V@/E\T\@kSRkeV?iiW@6^9%*&M*C9XhYjP:*aDW4#CAmm5RPNT9MICKK@dQ!9wy
A&q%AF GqB^BY:$#>wY>H8M\1CIZ%D*BLQDj!nL\RG6!&Hk\Ql:HD+:SKENBRN?!6T?A6!91Vbm+MC+j\RP8\>X
StERyG kkK8=LjZ6<B@^CkeYI#CAZGM8GIWnkJW*w<4!6C@led<DlwB@m$$=DBq8q@I>an9TyF@Kq$CmnNA6SX\
JKL*<G HKhba^CH=J:>kTSkXY4Wu8&aH$1ZkQy\RLWXeB^%AlkE+nB@I*<qb@/camRGWF$GL5XIDAL%*&I*jQ@p
?/#ZQe IPmja^RawBweDAJaETtPMR4mWC:nF?IE#k:F@IkVCKA+RRLnGHG$!<NPGaTkkPi69Z=$@@ThQ^WMAjYn
ey1taB kGw/aDn1h#CHunL+C&4ci$%+@@Tk:*aDPn$IA/kiBIdn6A<M<6C<>R51>:D9J#d@1d\IKL+B%aQAeJ#&
J:TB4h kWEi8taNQN@8nbPkQ%V8wRlk@kdEMcJ^?j8\$!iAe#C\9j\F@hGjRIH%J+D1RcA+/wa\1MQcJjA/qu$q
+8@JHA bPkQqZ5wwJw?DKB/ECmPtn+M/qD8@=hP#hkQ1?>&R+D=G^DHCMjqd<SliS:/K*u??+uC?%Y?kE=9^kC1
V/lLLA Jhu9$u=8>*<Q^\mHIL@#nN@6B1S!n\FWT\LF5ZESe%k6CSS+9wV9*R4=$b>AkQWukGyJIDk&QYLRl>by
*/BT>q \aB#lQ9%S8Aj%iCA^qYAcppkPDaqa\+:*SAKjG%49*aC<1M@kRD4V>DAm9h^?S9^H&1YB>kjcycRj/qb
wQE4aT @mkS$j$*aW\S6j$ISQ%V#SL#:=Wmj/qb:w?q@l9WLFtyRQ/#nZPEeKdI6lc*Cq>DIR!#GelY5l*BF1NA
=Ku<+I VHDK6S9Lu1mWG#<dYHaPE5naCq1SbZAE^$RTMtnEnp1CA1q+5=phA!$EYCYC5=YTGG#S^d%?YlIcenST
ZYKj^% @FJEC&bSTwVc6bS6LZGlT@p*Hy8IDNX6ZJi?\lJb6nSy?@C8S8GA@bk96nae#KT5FI!YhMR1w5lp5!Gl
/Vd>Mu Gb%YatVK8XLc:BF8SJL5ZyjRA1Tabw4VP/!EhY:HW\^Kd=LIkV:jKHT4<An>8BSpS5MI<T$YQqw1!^!=
#W?^TH ^GyWWYh&5S<@mMC6McjA@kF6<NW#dcm+/pCqaI8+nPF9&l^Tb^=E!LtIMyAI$dk!\IXaG\acM^NBwqSa
TLj5#^ Gm\1Mw1BkaE1t+&LPakka+SW\5KHnLq^QtN/TIcTN*mI?=RM!>FGm%=lB1wnCqaW4dG6<5!SY\5/^BTR
i@bJ$+ WEQTKFwQ*ZE@=XTDS/Yle#Ij86R4%*yKn%VaS\9$S?V%BJP@@WIEc^Epc\mm1VBupjhk$nktQ^6wKpy$
qiq&$D KyKaMun41k!4SJTY@kjlAX<GqphN*eGF=!keGtJ/#CVMtiwHyA5?XMb>NGJ=yGl4WF:6>*D#!<QwLjQm
Y!K$e< @+i+/+=1Ktuj>AYpF$XkFTH$auL9VXNaR^XDC%XASbDRApVA58lcEAI1ApyS5c&IFEXAqKK+qyZmT1?m
#B54*E ImwmI1BTqCcCjpHJu9Ph#iWM!*h?9@@tJP<#M&jttbq*!96e1/Cl9mWG%!IeX+pXK>DIbZc=!&Ddb6Z1
pd/!$D y>hnba4i*WLKDe+&Z4cSNX\=+l?$SCnAJG>h$$l<wDHP>plbk*CiYIie/VcB5H^Bj9>!q<iHhBuHMT8T
>#S@B? ymp84a?El/J=$+I*Ni*a1<VWDB\>yHm^Xd%55PYE1:%DjXS1Z&CM+/EK8Zw%P1&=HX6JP!@Id&a9=qta
AtJeK/ a!m*FnehJZd@Rp4415wq6V/RVhLQlWbaa6RKTk9!e\yLWGT$5VV@/yauKXibSy6V5bbK&EF>*p8lt\<c
w@TS@D SGW<8Dbk1t=Ep^VuYj&Gn?CmbnpRq=V$!/M>b<=RiZpC4ZD%W*piP6ab%@R>!yFZ1=1>/qZpc1Q$qGAJ
W==5&$ /W&T@y/!8Z$E>XGnc>9d^HMuFG<6+S@h$LGLRq@/ZH:j4RGnui1/Xp<qN/%1eT4E$=a?CCt1m1$dV4bc
QNIZ8: :kV:ch@EPcaINd=?XquE5n5^P9tqSjJ=cNl1h+<NGNW1q<BVa@YG=<<!Gl$5p\P*%$j&=>#T5B$YWjR+
WK@1aa QXdT#n4%>qi9tG&yPD&Q$uVH>Xi?SV8EXH+tJi#48pJ/qJ!Ac/1:ui8DN*WMCt/&uWbGN@@leN:NiMhu
TI<mMC p!>qVRq9i%NPlt/tY%XNGYZeLHN%%j16@>\\QwV&tbct9XjMcBGPDyZVQ9WJ<q^#!ybVLX=T96PG=w^Z
c@4q1k LYB$TFN^#BC9Cb&84*%%l#j@yQL\&L&h%K>&56eMB#hbZAwdF%>pM8lci/#B1QJTpcMn\?b!Bdcp1C9/
FwWZFw ACQW!?a$SpQYZFbBX5a:pT!/Mt8k>mp9^wHulSJ$nQF6mZ*HTpwZL1qZ+LcLISG&cqhV\%MC%p@!d<tX
$X8CJ^ JtTb1S=>HPq%NPAewdTp/%C1wYbC@>qXPp=hTq8tX61blh/X$ykY:^Dy$p&wM4#>\L@&\t?qK^9Mm9ky
/$HWMM 9q84hN9C#a$9GL4eH1:>W8%VEjAY4=qY>!KSE5I\wliPDd%1qe5NjaXSZcFSK$%dqBpuSQ8hj=i8?FtB
qSkLmA k6Y//W/Lw#jnLbh?\nYj&HSujiT4=Ka91XcJ$ka^&jyJ:6=J4D&KNp>*H?>P>6nwcKqwEd*:X=G8Hqhe
JC6u+\ 1Ti@9L/!>c$Z+V*l?B^ckPy^K6%b=JV+%Wdc5uV*<TV6N/=Jy669>Ay<wlZc@q##8i#d!?8DCYKJi59>
-AC^kB 000f3b6fa7a00110333 Page 111 of binaries1.zip
:mI&iE qmuTI=Nb9bP!BSnjtKa9@dH^nVqqP*8jNRd/T8SeYHjcbhYW4%9^?y:iyDySyHSF^qm1pM8FE?FSQPtK
jtPV^$ u+Rp!L<JyencyDXuMm?e8/Ey%YL#8ql&K$aqMa1H?WaH%qm9iTKlZqDJLbC<QINT#djW=S:qYdSSWERh
@E6C>t Kc$1L84%q@Qiwnc4#AW$%SLd%\SXy@9aLS+y+K*NVjypEh>YKd<l?#=tR:$/%i:6W6=!pR8W$KtedM89
ptEEI\ =a*QjNh1N:hiyLmj+lh#C\p=T&=@=uKPy8AqeiBSea:XWyyi/GLu><jpqyM9DVd5iSLmb!nFD<9ab#1u
h$yJCD GqW9q4B@Y4?=@W\WeVV>4jZVF*?%B1h5nDZJ6FZa+>cAtZLXaeahF:&$9<=\L:N?d+%cpcayHW4iG=Hb
8>tLH1 <QKk&dtkaLq4A#uR8q<*cVC%!Lh#<K*qyIhh8cMj:mV<e5<+WKlaadW!T&56V^6Yny1JX<k+@uMK>din
%uNhl* >4=*H84GVQ@i<eV@+6PSwZmmVhktb@ph%etP=!58XZT>&R?@GVZi4/CT51:KN<lHinD=a<LG^hG*QiIj
pYL8cd NRX1WHKY\w\tN+4XCh8tuw#T^8V4@m4G=u6%8yhM91\jKR%>qTinKW<>Ru8XYXBXRY\?4j^YNqdZbNen
Nk1S*M Eih8&8uL4/QTLceKK8u:#!Sc:DI:<ai^w/DJFV*%ZW+4+kP##muE!P6tcmc9Edcd54mnY!+8+XZ*1a!F
@k/Y$J LW!5*BKnEQG=LVYp%QnEw9$6\=d<*umunD1Bl1J%jquSp\G$I&LP?p>96G#HSnE?jtPYmG>X5*mlcK@$
K4%uIG @E@J9&#Pmc@&1^$:H9RkG8>PCV1qG6uc44iG!Sj^9wQS9F*<$RF@J8K4XNKwXiJ\^ukkR%&p5Yl*E!T>
C*Gu%9 QEin@+!?^WB:!B?<1^%Y@%K<W>l/><Ny:i94*ZK:K65iq^#\9TX8In&ba+F%C&^+c=^iMHBqya@^yXeG
:1?P*m <pcBVD<w@%qTINZmh1N#iF4iBTm\Z!Kl94wSWZe8:NZhj^<:4Ld9=8Fh@TQQ!<Y8tpRwNq@Knjq#@?j#
MMSL5* ^J=Yue?$%6htyLFVN=YZTDb=BnSB!kZuu/5$njd!Zj!<=@=nqa5E@:&:#mLp#P^nYd1DP9j+\kZ&&BmZ
NFm<kB Ku?WG#t@JPDh>jBn\!4=Xb%/L/&:h8?Q9e1<1Fw/*WuI?KkT49Z/\JjF%!+Yi58%Pnm?pRq#PHq!:ZGj
@1yh+$ 1M4+#C!QQ!RyH&SMj84NG9N>h@L\NQ??l?9jn94ieX%4q*q//Jt4a6nL9tLitE*q?>y?<:ac8?K5td/&
Fjw6&% M>!/+F!ypkH>>9EpG#Xu1l9qjLh!6t=aCiLDT>R9GuT5C1&y@&L\cY9Q&kQ95&@j#/ly6!RE/@ViD*b=
MLi4I^ +qp<&6:#Rq!$mNZyu1qPePh=YNSVt%puyNu\*4mctj%Z^\E#=R+6Y@G6196M6hVKSiuM&Q9<etNh+RuC
%Xp!M@ 4GE@h!6lMdk!>&ZRCK6H%WuH$^anipN@4GRhZ>al11CGkXpM+u*$NBT>V/mtdXJh>LKB\\NGK1+^My@S
/E*&GL d!ZSqmTe&9BP^1%H%T9?qTnQE*EY1#*PW<Wt@&Q@RFueTLaF^LJSCMdRmpJ&d@DeYKEX>Ep1b1\^>19B
pGq%5d i9Fk>%B#%y*LD>b<1LiN%*FTiTK8S*wZbNnm*#uEcL$5%Zq>\Ep\a/JL6D8?9:e4+jiIQyW6Q6VI/5Z>
QR/+bl 4F4*L6wY$cL<R%Q*YK*>Vadj5nYMR=yJBc!NB<eqhE+WD@Y?j:6Ep9@Q8/JFFGbQl/B%<MNL=8LV<qId
4mRi#: P?kQw/>mh9D696@pWyHbIF>XF8@@VCCaYeiQ@i4>XV!u!F^uK&?i/4hwne#8u1DaTWE6&\c#l^&?6YJ^
Ncq&pD B9Xtt^W@HPX:#?K%MNHEmV*1eX+cy*Bh^G%Sq8YPJpcS\B4qD+M@^R6j\@RYBLRuJn4\tqn<tbk$qE?#
y!mBdV 6*BN#9Kw$k#^Xb&cDkl:%*&/it$MyL&^85>VyKF/X%!IkFC&tkkXa=X&byD1cNt#=1Pb&#5ymamBdYdL
JKDRqD JG#dT?p<E>w!Vy$9Im>>q9X6NNYX=96\bXG$65Vk:n8>Em>Z5n4mu:#PG^bn<mw>\FATJm@^8Vleu5BS
iw#4lH \l\Va8MPLnQ4@6Nd$PVIR*@n+h^IK^uNm6h/^=TWtWY>\y:XjH8/4+%qZQcW1CA8K:>yeHu!@FBKGZWI
c1GF^6 $i8%!d5l%pu:^9IN>4eXT?8W8GL:^C15W*1*/WW#%9Blju:GTyQjj>LPY>RkVK9SP*mwNSCtDN8u=>e&
RBK<aC j@A<K$1uYS>Pq4L$%I#18Y=4jhwP4<4Zy&w464QQXLZtDFaGPmqW>KX=XZX&HC*6A5d*>%G:=uXl6NL4
*haAk4 V6QZ*aR4tiN9Jm\a+TZJpJMy%e6Gumi6jHZt+M<%pZdi!u:t@m*DjhK\>SwVJ!9Xk<6y%Dyw5*bi?uc>
VHp&mS >=q$i?X6a$nl=FXe1GK9uSVW8!?p#Z4LltXBl=EeR@6e%%PXtB\y!@&!H?EKd=F8nha\^ucXF^JPWm6p
W&qt59 E5cDDZQ5J?GcL9Pa>\/l&&$V\=96>#%6Y16k?=NC+cMXKewuBCiHllN&dH8jm6PA/?4N%c&E*1w4>i><
1MBh/t $h$1IX8n%L?a+6q=/EF6eKBuE!QeKWtG&EZd&K#wA:<!kd=1bW^6VZcYqIMEihKEl>VIijlF&/$LQ+/E
cD\C/? hnb&iF6y=IuI$iqNER#YS$bR/\hSVB>j5<#/EaYQLS&9:E>K$?LWB!TF=d4KVCe>Hpna1qNMib:y?>dc
1jRCAH ^Cw*YNIKMl%ad@J6a\Vew:M5cmd8%4HeI*1>cKLmla*9pk@b6TwShRklTXP9L1=$Pc+/u9>a$q>NP4:d
+j^CRb GCq!/*p8bDWmKJ=TjP#4p<1$K&99$!/ZyDu6yKZZ9+<pcVc?M&q^eSp=cENVe/=^Vej/I&qFF6bV4^>B
V<^D?# aXmtq+mKnjqXIaH&F@XVWNT?mP%*N>SZiR!b!$mh1MQc&XBPd8\jEWGiE%kn/mcVHuJ*T?849B#8cW8w
9:d%nX d<l6&hDb/iqEPl16/YHSM^E>kMjh5nniV$lj/^Yk:>Lpcm<j%1i/iw9BJlt6\^9qQNP%enyGZMW\qR+X
dFJ\M6 tMc$I*^1JpEQ+!XnCEHSq@%$MKcL%6tq$caPyebtChIDw+*<u<VqH9EJHGYaH>^\dNnB??8EkIMy9e@*
j9yqE5 \dLNS<bm5a6:QwalchYT?C*qFSP=jhNYA$5adZJCk#55aXha4qq5P=>:*5DLSqEJq!<Wlliq<C9!KNP1
XEVa>M PNB?bcdJwp#leju%?dHnu=Ru1AZYpuGIM^Eu%LqZWIQm1^1!>d%ab=tyZ=M:uyW>I89S\p<jZ?4i<859
YZEjRL c4yauyA:5NB+mV/%Ih4:Pu*m\>q6?P/k4AcdD&S6Qa*iw8dNJ!pHmCuS$nHt5ne61AY9MhmntGZ8*qV9
=Jt6n! Sa8hMhm>GZZ/j9ehn=8JF^GadYp^Blcc4Zh^K=takJFjHnN#ZG=GjFIX5^De8IN!VEw*&Mj^b?yIMB*:
tw&iS+ ?C>Cy/^pWEZap@ELjJd/XD4Glqc+\=6^5MuQ@b4dmuF/>w$N%8Ml+=*9>n*wCkwW$&M?*b<AB^X<=pp=
\&Ai#M jbm1\FR#5W$1nJS$mL?y=TN^h^P@^\w?Qt:/wiV@D6j+Q>eQJj>*$Ac\jmmE?@6dG*@4l$K+:/je\Q1l
i?jK=\ EQd:4cdDVALtJQCeBJGVIM<tCJ!@CJ!@PFYA5LN!qi\EJ!Mm^+nI\bM+NmTPDatVI$eLhibd6:M@pVuY
SEDwi6 bI+%tYNNu4ZB#e1G5lM\J#HdWnMjtij<^LHGec^^HP9bnwS\PI+^ntMM+VkbRS^4mGMNec\lnnZM!S4t
XF#5I^ GMMeG=nVSnmE<^@C!RnlGCGenQCenDn>kPQ$A++n%54S>9#:TPwjl%*@9KD@\VIRdW<!q&Cej/LS6D*J
!b+1Pw ZJRD@+qG$@ape\tw+aJGi*nQSVtRC=1AXuMEBI%H8iDuwl#IBa*&QIBLaA5ZNIwmC=qLaM5@$Zk!!qWL
RLZw@P q<AYLtm$S/NpEK:l8V@hlLBaEK:l8T8!5NEkZMQDcGYDeA&QSWPDeA$lw>WelG5IEc%5EK+lBLT!RdmG
R9e#FW IGlqk*ANSS8MnRdlGww&GB5N\nWEm%I&DwS4KNykdDRI%&D81wX5NAnZWJSB&YkR45EIY6pkZEQSFYYn
5Skk1^ RdkGa>HRIF!diVDBHR*CNan:XSWdDeI%mQ8FES5N\nWWbXAIC+F\dib4iN#SIF!D$EaJBMI%CG&WRCBe
aMDbe@ \=HR!kdlGk=6qED+j?<:5NGEj?<:5NFEIN<B4iapIN<B4Y\R4lFkFKdC&H@9idDSRQ+cDwYyMNAcTpbl
uPjw=V C\\DiS+w@R&DeA%QSGq#GIS4iARNDeI%QIVCFlnIZ<PlqR&$lyLS&AK$llJR$AkI%^A<!w!M+IA<D!\K
4nj<DJ GwS4CB4QETB@Da*uCNAcTpd^tSCkNSVNS$bA8Acn?ekIEYn%S!5dlG5w!1B5NNAcmncj++HYWCLK*IIH
F/XQ:L +S1cY8Q58en@\#8Z&aMa%JhB<%CF\M&1NWJkcw*5ppFInlL%PH68>D>Rc&FQQV@WGmE\6Wb&!YALQ\4F
Tn?*lI <ZPy6SDtyVI\w^L+9h+kL:HaJRM=DWT$+WH?H/unpFXtBM&?%^5C+kpB!PFA&<\RkB\P6A$pAXwRGq+R
jJQh>% GqpRiw/ZwVQCQeD1PnkXQPEH#&dWApH/C&l<aFEY:dqidEQkpT5#pjL+&ZGNB^9ZBLCDKSSZli8L:hqI
S:H9@# 8yqyiS:#EZ=&ZPQB^nWS/FALdh5/%+66CQ#qM?::1@:b>kbdialA#n#cllu>^VcEuSH+AFcF\H&QM9^i
X*BQZn d^^ai\N6BBC$>kdcCPBRZHpmaWFw>AlbcD/KFG!P#pSL#4VbnGwnTJ56cBNBuC6KCTHPT*pR?hHZCB/w
dQnDdD 4$qAG^ATTq@QwiCHJaPQ4Sq%G\TcdY<a1L%J$EK&ZcT=wkjlie#B?JuH!V@1DcJ\AGFJ!EK&dKR=FXjt
w6j!Qi wV#?I%y#y6=A$b45pkpL&T#P1iA*D>>1SqEPD@?wN\EQXG@TRnccyDq<Ruki:V$#JtH!n*1DKAZM#QAk
a#pCc4 >TcldFLJ/NERMHEim1D5jH+w!pFkmuL5p1GFdM*Je/^=yHpw5JLk:!yw*?5NkdW*5yBDAVJ?4utRCK=R
aM&W=i TYJ9*&jdG\9Y*wTFHEeAZZVCPJVbCPmmE^%N@l@6E:HjFeFt&k\CWbtEeNmFHIVk5HMyT5!Hw<SbXVeI
Nt!BKD VNYNZVLRSRVKwVmP1@4j*@Z?D*XuHk=q&@:^dFPNybKm1EdIIM\>P#GJLDEaa!TXH65Mp:WbY4R<NJcK
@uF54R <CBCm&#FwMW<Yl/ydCqbRmy/it&XWMbY9j*W?#PYmtdt8L$>^@E:ju<=@HHN@d*Q/:!8<:4P/:\@F@la
ALZbLG Qd=i=X%GM1EdkRPqG\*1<Aa9RDhGmG+eim+*AkBVMR<AFjMAWAi:TAE^D$AI&?iBJ*n\%1IAh6K@AS\+
6dwcW/ @\b%WChkZAIIwhSc@F^84RBRp@+NaED=N/kDbRFZ&W\XI\tpaAN#wV>N=QuG>+*k<u\A1MNwRZp?AEAJ
+=*<tR ?+IdBb+Ikb4RQWHdA1pd@W8/lXLi\Z>SnJ8<VYcT!waFyj6Z<yPAMQwjEn$H+kq8+ncbCh%weQ+NLn<y
yGXd!u !L@@tZmJRmEudyPb$A$1n\GAPu\ZeJ9MXN*j4%P4$Kn^<ama@DIZC!1QAaA/8Pj=Hu@h@<#6QV!!P\cQ
WY1*y5 t/LJkS1ZTHB=WRF^Zml%eA:$Ql+qdI4AkeGD<^N\SZeC+n^TKN$M9G+>Zn=*m6/HA^Zu\SWdIAVEiYHW
<:^b>! RjSe!CEaGA@EMEtVA^ZuRSW1<EB<jHYnkH?Eqn=B:?MS>ZtpS#D*y!EBeEWPAw4%ABV1H/Gq<\k#tKq:
-Abm&1 0008718989b00110333 Page 112 of binaries1.zip
lMPM^8 *<D1S9?TdqB=Wa!k*5L?Wt6lSE@\=G@W?Bwcnb<mHmIAWDaDhiakwHALRAp>p=5DBRpQR&Mua\ec%BpQ
eI1Pa> AKw\A!Pk/A5AX=kl!FQAFYaIdC$pd9EPFWAVkdAV>BHW?J1MS<+Fa#NR8W&MkH&%MHLkZNa*+@*M$#*S
yYWGG9 %!B%a*>JN$/a9ii\Dl/*M&KK%AmAmq8kmpuRA5yaAdT\jS/Au<8?k*eL#CSBD%R?AFRlCq4RPpH+dbDk
5pBMlF %&Y<*D%tm8mGA#YZaWCNT\Hu9kAG>R5F#\CwYlLB4aWSd@Zt5DhG\%DAXF<n\jW%8GI4RZ$6=La:HBI^
5Gy^p# F^?hE\WQCaC1JSFA\WMCGD%RSh+CQAXWQank%5A96Wd?Wt9WL:XG@%L4j+4kl=tkpW&T<EDN\%l\SjpC
cb/cNc >k<#/$FI*>6PpbRR@ElKi6<?aPTSqKdST#N@F<?HyIRbH:Z@@$lK=b5i<TeyTXhItCnBm8G1chFH@@B/
/XWY?w =AFHuyNRc:!k8hn$^6H$PQ$TyYYKMje@mm*<A4tue!51wpnT+XwHR$Z1R@K^CcRT<*I=WMJqcm5%=P8X
MI^@B+ 8GnY@Q/RG9+<!w^yAIi>uT@K&l6HR!n$GGa<V5:9aa^CyV>99JnjC*BC+&l!Mm!m/PnJkdTZu&JaB%><
hXcpLG plBX6EkMZ*S*?&k5Rk1Cq>DG>*\$CtDcwP=!&WPI<6kiE6yEN$6eWWKp^FLyV%@98KVCQnj<H@wm+u6Z
eHI%:1 tn<wq%1biYL+SqYSnQ$nChRk$WYjE=yPA6Clq$lacaSa#<X\5Y$QG<&YiFEXbQc\h\:w>tn=4A!@h>y*
nhJ&lm 4Y=u?4E\A>8nG>ZCSa==!b%kphNYq&l$e54\T:*eFA8H$#S4I1CeyQyw^1ehly945\wYQTTlLD>F*:N\
//Y!/X ?%S=+T!!EVLkQm!LThl\B/P<WDEmXNM?Mi=M9enyQRVdJyNT:yP/9>Y^&ZJBenWScPcGhSKL8%*GIJ6a
$5MeSu I@yYk&Em6L8l%tjFnGN*G<l6Vm^1RaRnqC^8le9Qw=KdKF?5jYMC^y\>bXkL&1kaEi6pthcSpjt?t=uw
1mMMMN 4*>lL%%#ACJqHN^hT+K!a?V$V%X?=YKd#$Hmdny<<nS=nDpdQS!#6:LT%8qy8%&5<:=*>yFQR5kPnuZ+
Dd+5d= #j&%HWHFTlI/*8!panY669MP&WT=w!@CbNiY9kS<9Fj*ILhJQXb4Wdt%YA:1qQyGCdYueR65\?DZI&em
8uL8*N LyR<X+HG>JZtIlM>R5$4:6W?HPPR#n&bV@a@%nc9P6cq:&ank*Ny?WNKa9/a4:&PnaS/Cp$:GlXI/XZR
=8bZL8 dVN>eh+$IM%&C$VZ8jFV&XPD?ZA!W$*%e=Y<YM?uS>jcY9TG#l1IcRTYSPy<Ijm#P#FqB@9XyjbiMJhR
TM#H/X hLVP%LA6eZ$a!Yylq416jH%\>cun\L%LAY#Hn9\ZTT$&\@i4cI5&DFwGP9:hL:e^MchD\S>/&euY$B*?
\j6>Jc <K9t=Y&%aySMF*6!#hk1^&#h:eQZP?*&&$a*NVEjpKSM^&/+qWydDP*da\tw4YeTmD9nHT$LCpwKHNb>
ukVd9$ hwu1l@Vy$ZRh%6H@q1$<BKX4\VI:<%b%jWTG>#^KyY&QZ@P=Y1dG6Wd*VjB#tHIZlH8#=#bPN4@NRGb#
^Bc5c+ =Yl\Np*@+pt>Mh<6t<kS<6&HyXH6>k?etDDV8%<T4C\l>SIh=S@#c=48laXa9n6YiX&B>DJ/aXTNLI#D
9/Qyy! #bK46#^MqacjY>yP??%<b$YE^168<*Xi#kwmn:DE$dM=KR6?P*qQD^JJ8Z&&8P#^CbcFbwHG6m6Zey1Q
JYX5*i wml^%9V<Q@eYt>@LhAd8*%MyQ\A9&@Y\G8wq8kRT/bh:QkN!YNhZT:T1l%+t8>TI$TCuJk=JT4MjDRhw
q!w%1d !@=w<JI?njd?9VHdkAY91ql/IhnYZ6u+dklXNCEn&6%d8TZ@DV!SydTaVN>!u?YS>W=c1@mM!+Zqlib:
X&L4Q> <*LYi8PR!*49==+?q*MId*Q<T1#Ty&Dye=p/yKG5?q5l=PCYqI6PMVc5hKQ6$B*&uB*$\!<$1FtSZ8RX
HEaZ4G P:\C@pi=&WZ^/T4w#61<GL*qZS8WPb4ailGVqNP@!V?#6%XD9Z4XYI&qbSKjyynjHc4RqGyNTp8#4*Q%
SMt9/j WSEu*H^4uPSQDF$KW?66VSb6QFWuZed8LL&WyL$l<YR/WpQhRd>B>CQbN#e\Q&Hw4<S$8l?W>KE!al=%
wiEiqJ 1R5TpdQd+BGH/$c@$KF4c>B49i&J+VbmY#4d>G@qy*YqyA\bD:lZW%$+QQub:T*plFK>y/Jdc>b$B8ZA
WuPt$M NA^a8+e1:N$@\?!@lq#NY@A?bY*ZXY@jiCTeqNJdpJu*j8%h%VTdlP^iP<5A/@X1YXXF<WM88Sw^bT%9
M$5GGX Dl5pMAKKWM?*5@iQDdEjH*R=>ju5D5ww9V!%qcAe*p1WR:e%yKpeZ&#bla\*e\6>5QXt$QN\qyGub%Q&
uw69/M G>*L^tLqjjt$NPN*thWPT%VEZ6>K/lXFD$hEp$@kVEm?!4qZR8T!h%6yJYc5KCtA^%m:K\hqQq>hCuGE
T@aY8V X8W^5S4lS@h6MS4NN4XM&ZqW+niLydLcn5+uG1\CKY!dC8Yd9+ZB*V/Y$WlK5nh&YQY*4Ln>pTB!pZnR
*5!S^n ?quBcQ1TA=YhGu>=JDFjYX4Z?Y>IZnNj4kWX=JISiXZ%X6lRjl@SNFy8S*iY$mpw&XVVn4ktT:Rw1dhd
H^G^9d llSPj5*J%n1yKXbtL*P><b4DXq&HDWZ$N<45JG?aW$Ypij/4<^d^lNMh4l9@GHDKVNwc@=#tRptRydNX
Tj9%S\ H8nHwkNkt6tH4&DZS<t@LI?=abX!p!aS9+J$4jeINEXl?>ATH+1Y9N%K!TY/y1iLYMENB#<>*6&%%jK/
@hVF9t a8cNucF*q6>MYJn<XC$5$$19ldW=/+dC=?+&?iM?L#iM^k\Qh1uZ81@dYiWYjW*X\!bK45NkJJTP$*yc
bZM@EF +iReZJlj8!ZYcVkm#^@=^pI%??\/@?8II$W&Ji@Ta4PWVEbJHR=W/eL*X@eh&*T1SH6E1nWnYQSEe6nn
4miTb8 k89q^wqDCK9Zb^6LD><%Z99mQ5XJyIla:Su^aL@P1^&q#\el#uq8!+5ML>%FEjCSmcMB45:X=W:yd#S#
@PG/@Q +>6ih65Y9BmyVp>pac<TDBXGT$u?5p&/=m%!Pj89cPq<jj5CRI*h!W#*QptIb86^64>8bS/yLMQ&Jql&
C15?wQ bPGIGl*uLVby+5KTp\#*6*u1HZtdCuG+jKQ5eau&bd#BF?ukW!VTT*qakFSlWmdP>M#H4bjNB$Mn66we
QFw=5I lA<+ES69c=b9M4<%&Q/ZpjaIcY&9t+SCq=6<>MGDP%GEn&>Th8R<Ndqa>b<um@dhcVcEH@1T*Qd9L\GX
Cj#QT< TVJHR!?iRd^#NP=*pH$qe&wNbI$eJ*4XSZYSLWWynX<iNhY5X9VE1h=STE+h:uK?CI&litieR&TqdZW&
q*EdAS hJZ6EKikwcy*Yk6^>RP:18e%bF^VQh1\wV>+kHXJ#VyjXj\aWEbMbKi:1TuEi1!p$jG/4#qd1!Dc+m<6
j?WQ1w 41^5*E*bu*8ca8Pm/k=X%Zu&8mLPnt%nXXHSYkMqW\5ZtX4585^SM>/:Rjh#NMS>*pKmAd\+=8*c\RZL
yFRNnm k@8+H>TSqJ#&%HcT6K%j&L4t9V1FYdXJSyy!RZpKVQcJ?1maX+5bDT/:IVI8c9tEq!1ID+8YM?FJ^l:X
LK#X4q NZ:!ptbp>bQ#B1+Elpk*PCJYA?!G$9AR65=cVu8baYdLaXdEaNhRN>ZT8dbRwqCHW6=@eDilK>Nt+/Dp
jTD*w> pwb4::uF&M+Q1R>*Takiim&KH*EnBHBJV^aqPWtwTXPLC/RWJHKcyVbjCe\8qydyccp*w66C=!MkI:py
I+41q/ T!?VD8#^+::j:R+9jhji&kcX&?tSH^Hien^9=SFdVpu9G<qLH*b!#hT9b54bli$JiPRp>6+I$TRyuZi$
9J@/GV c8HmmE<h<&Edn&WE/ac$/+/wl9mL5J@KiP9J^@W*h?8<6umj!u/*\B%aeKZPTM&TGcWPDX9ACHNltbw9
pL&K1y m+udGdu/Amu?8P41hm1enGkt=<WNe\pmJMqX*P/GQV&8A@d#*!^SlHI/Vi4ateQLF>+>?M+6Q/4MXFQ@
ER9dHZ :P:t*BN6$w>>X%dY4!Rb*/^p#49K$CRjEq@\Q51>$E9%SWhP%Q^Mu@mee$uXZ$R#54!N1$M/CeEY^hR+
\4:K&H k:+<q%k*WkLE^%!u^LN19/hJ#l/YpyeK$5BZ%YiLGXL$EyKSqBKT%$V#W>qm$NRha6l>Am:/d=H+BJq?
Bj$Qm1 a$:@hk?:Y>8n6#8#aRRX<^XhTt#bRF9^?!6#+>T=+SLAtNP<*5Be&qYY$healbC/Nay1Cle#//S<8NcX
Vy=NLm 9Shp=>Z$q#l4Le@1F%Y6llN>tw$bw5c:p!WZuQ8M&9qS4Mh8/VdnTDkq6>ZI=Wb1P%XFqwNZjjpF&4jc
=4X+A/ dIW//\?6%?#%GqCh&tY/=L4dDd:chGZ6Yq$hXT/$<i*/Jamtl9WJVS!%DFJ%%#KSYq6SLS8b?/Xlcti5
nGn@Dn =n<n\BwLyEd/a4lW+1FI=tyZD*Eck#W9VkJ8E1FT>I!SeXJ*8DMq@w\nM6&<1XtnM^w8y/VQWh++WFwW
%:G<$9 wTmjLRaW\jMG+wQ#W#uD^M*T9b<jFX?6HB1%mVQeR%jS/4/Nl6BHJDhdQFS#?*MSWX8KhaBASiidK<Q5
V>LjG\ u8&LnXWAAu$ZyRb=yX:1XlkPN/Be>D4C+9:HDmj=*kYRYcXba@qE=q?E5HQZw+99>BlRMkhZ^Lqeh>9q
=4GIZ+ +ZF%a+RbtYm:<dFPqJ6^IaXShLSi1*cJjnW*49EBuQ^ILh&VNQSEh/k%u6^8&<&FD6jwF>Y>mM<$hJCE
p+uWe8 t!:TdY4@&>IXHS+u$\i#NQ6\PQ?FEXZ@:c8<bA@>T/dNdWM?%=4YnWRD<6/G=5e@dw:!\N6>mJC$piui
P^4SGb :G9W:eephNRGKXAI1JF#lPQLQ>5i&cZlbFu9%^jI?V*E#84aYMNRd%#R@QY$\+c?ymJ8yudYtpmNhW*m
1KM!Fl ZEtH6RtMAWQXA#61:&<c^ZID!d:LGkK>K<&MYl>cGJAnpbcQw:DN6LjLbCRY?qlSLcHm/\n48j@!:LKy
*Dw?ja IqiQ@K=!Nej5&BlYhDEM^kjMM<Y*?V<D<+^9W^H@HbkHlWZ<BPbBajSAkHpt1T=V&?QbG&@eV+tTKatk
*T51MM 9tkDj1:8u%6#%M^6@:jGRkDK*=uJ+>6?HJdQyu>t/V/FH8lDleE*?eG&?AW!@D&C*AQy@u/\RH?aCiNA
hLAFeE RKC@J<M%\P8A^qT&bAeMEHK?Mh%FTBRYP/&B=#FIAIjlJ\VDS\mJRcY=8qP@Q^CD@cucBCQ5miM@5Be&
!/H%=E >bdjFcB\!Ku@#ikM=wTp/RbE%+u@<h<hKGn<F:W^5>Xm?cl%>QKHMd*<k*\<aPQn!AMY/EXu\n!D/B:C
kuphte Z8DHhQ8*F@ltwt<t\@E#Ga/QCA9@jd#?CtJT\V&jh%\n=QuVBy#hlZl?i9B<>Jn=M&C?@k\1nP=H<&j+
BSH=VF 89Ie/45eQEJI>bARPdlbe9V+!hHnI+hM>StjiTa:mP:u?aM4A!kl^B$lW9A#yW^:#k\yM#?ctJJCeZWd
^RiRt@ @?NQk$%QWn?I\TDA?QuQa9St?jWW<P8:Z/Nt?nX16qBA<CmE:SWtEM9Zn:?Nw&u4IQqbB<uuwTbi4kG<
1BnNlT yCPkA/N+WYHG4p!/P*QCYn@MSPP>Jp\VBwpTytuKcN>5NK&SZ*J$=kek5#RmhYApL:wQdD9h%=e/:8N?
=#aGl5 j4D^YbNpQn=J/**Zl=^CnQ%wM%D/?N1M*:\NCDHXh^$wNQK@tWT@V=1VhpJPk>/?P^6tl4MlEimb#kak
l^\yhF b:<E9#uj%M?hJ=5Zh%#>QGAi%Pq@ld$BBw*tb$u$4J:qF\H^@Kh!%$Da?P#y@wMFN\wV<CQGlw?A/c/e
-A=a*k 0003d5316fd00110333 Page 113 of binaries1.zip
8aP@R9 Nc*nj^198FunFV@VlD>bpF<I5B<Q*Z/iM:V@IB&H@cqRmc@6b5*+iH+#Ql+9IAJ=?FNuGk@&9>ShVa\p
cG=1S4 !XZYGw!M=eYLlC&BlbTYpVk\9XZ^p*<I!i:b/hph%6=6htdZiG%LbFhqh!YV>VPbYVQd=wIESld+cASH
P6uEHE jtRJCc&$B^><6I\EuBAe8Qyw?eABJA=IePBFXqbt^589IuPHE+hSV:?8m9nm^a59*w8IF@F5Y##?9A8G
PiY1QB e5M+clBNlBFmitLXy%RGGW/Tu>CFdm^$dQwbhCQVVe#hmZl8h&M5*N$aw@ulqTR6p?J4NI=K:=X56$wL
dhQ^#Q F*IXRm/JGXIB%Ben$u<>9jYI!endZy8m#FBe>DYcdwdnWm5>PL\Z8FA%?w#SuBtnYiF!j=XuC?<^kV9S
@4keYB yRMI!p$N^!:qmpKVRK^PtL8litQk9Tqel@K=dC8YDIlGRDV85Z:>Wi!+*e^S9&L%I&e>S5S>L:9JK4KM
NC$jyJ M49bJNY?TH6w@Gc!/B?QpXQRMAcQR#:TtPQi@u/ee#l!^Qc9JiZK8>=9/tmun%11TV4EPkwhPq1pSbXh
a:JZ=F b\9!Sj9%?e@HS#GdXtLE%VHm/uiTQF6t%Y$>916mZ%a>NJH@jGlC=meM&DFtjwJ\P/W^yQhX8ulMH4#*
Q>l#!< 6GtCC:n&EjA+apABDep=w8cL5mLuQT6ZBkBVY#B^Wtq4Q/w6btkERwPw?yEBREHYM5%LF\/VKV&K++RY
AmP+yu yMNJT4^hWyc:XbGWcY?KD\LjpR:y5B@iLRwBWmjt4HKZb%XqlZbBQFmu$BMM8VQeI^CNkCA1jyR8Xl5c
*GVm^c *Vt=4%YTYh$!ACQnTYCkFlAQ!^QBTIeluEjQ6a#C@GpyA*6p!:uN^qL+>5nYHD@&9Y?>B>/#aq8qa:D:
Q4?ThX h+?$5L9A=Nl9IXIhwteVQyt=9L\q*XWFiSyJj4M65t1%:uXlGInBGV+untMZ&t/nFJ14L&L1a>F/\N8A
\Swl@T KQ*<c489/qa5p!wly&&>w/t+NQFWRZ@JN9$bJ&#IiqTquNNnyNL+JJ!KFF9RHLNhW?H41:Rw#R4X$p6K
N=!a/1 4&#AQddeq!E\lX#JD6lS^+\<BGI#MZeCZSMm5<1<#G:TQ4NHa8DiItajatLMLlC#C*F/MY>u^5Km<uc6
tw\HQ@ >%6/%\Zy5p4Y8:T\!C/T5iQ&=6Mk^b!BqAmphMX:^8aiy?tPb5Sp<hk5RD^dba9XAT@Xi=m1i#NENH#i
6pmHXJ Z8wyYAZDm4lS1ApKLdKubmPm$?k!K^j=6mV96aMb#!e=RpPaWIXw94mdQnQ/Ia&Xt?R^@TjLi>YLiHB6
:V\>=\ ^mT/aYNY?AkPtpHi&iid6Em8MyyK5#=h^KGiykpGbeB$kp$Wpp$WbI$Mb\BDjPK&:Vw#VNK=ILW9&?6b
#I:e$Q F*!N=6=8&ny1Dp$kIuVHy&B5^9E$>Rt8Qn=^SAkQtk#i&Fdid?$#W5T>NE@N\9j>LLh/hACyu%9nkMTN
yLj<q& C$$IAp$I:&Vp4lJdtF=/XG^@N>q+1&%S>pGJ?V^/QpW^>yiI@TXm@<9XdXp:dGY/&BetI4w1$tT^/wNT
%phTj\ \jPBa9R9Ej%L/NmubEJWiXJXSKmqE+59yuTdbC\9EWXJ8QJ!wE\V<CR*TdalHFjdt**yXSuNq<da*jmW
EW8p@E u1I4!blhItcZmNp9*69X6G&e*jW?4:I#54KCQLt!T6eYNH@+^95p%dFwRKJwRMJwwEm84+$98Wq!5nIL
X?J?Tc #CBGCmdbqFRMDPJ&mdm>*lPalESQ/#GwB5VY4>K<YmbFj@9+?KDMl\^EBl/?SAR6EWE@&C#V>@y:StBG
MFpR<> t+JkEQyI&*hZjtnNcPaFd^5h>N&h!PAYY>9&w!/W=Mnaew6!L:hImXn:REHGd^jTDSL/JyIS5$LE4Pau
+LX#i: K!:hheI^I>uCltR<4BAQK<VD!b:Ckp%qq86MyCImJ^whmRqw5AaR<>=%%?b4q%Ee&<:%#^$!ybmSKPe/
ECa@>J 1qTIk/@!Lju>m*19w9TW:\cPX1Nc/:W4R/#/m49$iV^BLay^8l>#6dA6Vb@9^@EXDRW=>=\I\Rt*@?yJ
*VH%/t V^q59WWFTDuByL$nV+\kCAMZk1QCGQE1SL\1lDy+?MlVI^kCMRWD<+aX<waXw6hZ:4+!CpHyKSA+=!L9
#JSJN@ X!EiNR9@ulS8DCKckwENca$ISePN^Zd#\dDbPbHd69b+^&^$Qpp%nGW%aqp6V1kt8:/%V?WMaenRu\BD
GEYR@: M$hZI%:S<PDJ@d6nSmJ:d#M=IDBjXmNjXmMiZjC>ndG8pVBtG\BmdKiS//d%KWDqjp$n%I%DVFIMe%+%
j1=DHk eq+%I6JFR&X8F<R5*E>A\elXI*LX\YpW#Y!*wtDI>NYI#alwptwa9&4E4#w<Diw/VbhZb9X6DE++TWiM
bltQDB cnYmYl&hlFPb4\p*&\q@ptIa+&4E8Bw!dy+tp+Bk>*wAlNG8n&nZl:Tdb:5hhhFmqi$<NiJF1!p#wYbe
pF*8!e /!P8>THZd6e:5^=$&L#$KJ1y65T5dp^mmu=<S4\?Iq=jRp\n^$8k=#>FV#=nal<^5R>Q?BZdb&ti*@G?
qFci9y uPX=q1#J8Zjm<eMye/VQ*W=E^D+p+u:$Q5cD9n@Fn@AbG@8InZ*@FJnDCb#?V6pwLD%JS+!ijWVQj8CG
cY5*G! hV5&=u$=TWYMqZ*E!u=+Ep8?9dph%R1MaRhIGCH:mJD>/CTT\*LaGBahVZG^5BaRBh<dmYCnKcEc5\h?
TC?!!/ lF<G>yp:GR4*/XMbIJLti/b8=HCF#Gi5HCBYD5Ty!4NNqh:W@9naP5QeYZ8n6+D^eaD+PEB<*J&<HS6F
!LG?6n K6JVpDAYDlALB+mF:%$<yQD%#tn5Fp=TCCQjAJF9kMl*thWH^JLm>4kmQ#bqKu?TalkDB+mBA*#p:9w/
H9K85c T<>iw!q1uXA*8XheqJ/pH#dRApT<RRD%M##eNl44!ppcakReIPwJRkit:qDm&LD1*#@8RMTIPEBEHETP
6F=*Fe I+CQ$n#h4dcdY?<11/6%^#V^JD$^L#qAZuIRR#$XbpP<eRjhhmTnTSymnuKIHPWRenDak$e\kpp1aY\e
?CQjMW InaPES9ji*k?N1IpZMQpEHDLEiXinMT%W>a$?jVVJmkhJ<1RLjYGwVQZVacIp6QpcXw8m/&JcEahWRFZ
Zma&BR N*p?TamIGPauZ8R*!V4J^*yH\CZN66yn:#D&ShtJEtauhnGKQWGGk&M6iKN+kIT:PIl=aidl^Tc:YTii
!#K^JF Dy\wAln#D%A\4pYyl^KtH1cDW:Gi%G=EMQajIIJ/kMtG:64WjML++YdbytP%++j6y:Y@u>k1kZtI%/Tn
PApL!c 6NkX&TE=&a$d:p?nFE\JE\%je=d8R/5acIY^ieTT9!VLNJTShl@>lJtG1@=BjKINN*DwZLGMR+t!=!VM
D8/Gp6 PLR19?M6$*JSbIjl4h\D!%i^C$tnRybuKFGiwaS=l155LbJm5cwQ1IAyPy^+nt/AmJ5/atCacdm/9T1!
kYeqXq yYeHqTNKtp>TEqRKa6<H#6y$NMY18dHEjK^H:J^cFI>aNYLuB@e8#mq&MW65!5&HG4w$LG6Rwl\+CVMB
R&$j*= 5@W8#^bb/>i=i\n9!Ed5\AhLjyMS=CHE#memY\BEmmqAtLMdIYeZykbt#iWG>T:%CJV=JJ$kHeCp96ih
VWZ8\R 6iEIdYC%#B=m:8HFnI6n=8GFHCum+n4H4n%k&R@1*E&RcPDFjKAlXwabj\aGBRSXpX*6&ZL\5HIeJeYM
?Ny8WY a&JG^CnZV<JeQ\Ntq&TFJ>#n&ITHE*A\?pYyjlKt?lpe=tlyPVcT?w<:PaA\F^nq5$ta<&iAqNp*W14d
&h6ch# nWNNWkl#kGQp?MEM95j>#B<KWN%k=CTq<FGGYBet?hYu!aY<M/1W?TTqRCWkj9*Te<RkuF9aRFX#jqCI
Yu<WA8 Ji?y8ZJHn#B=d=%5#4LNYdXK#>dbeptmhpHNHWkFeFyuGYMKydAytMm*Vw1ddNN=XTMBXBC/cn?1MGbw
9+Dm?H BEInHGn!&=GwTa:DcJZR\yAIB1JeP@>q#A$QlJmCSnA$C1FSEE&XuQXu:JGa$w@WFD^RG+l4**DZl1:\
VBwiP\ GI+1d1B5^qb#u+&1$HqGW<HE9#jT!mTli?hq8X%phtw^nBHRRhe=8!yyHmBFIR:idDhuSd4dL#N\VBJ=
*p5ZC5 /M:1n@*pM#klkwNa?I&H=@a8P+CANk!GEKAGEAFj8t8damwD@deu+q6VaRR5=?=>LkZV<4y$GdcJkd^^
lHp6Kp &FHMyFGmuaKJh1b156Pq&+&MR%iqS&W^1pYbhRyt%qtJycl?hC*YwH/YNKhR^yiCTZM<SXi/TXclI$%D
\dMt8T PI^pWX/ekuq^q/?@??DTQ4EL@JXwTy<I!WBwBAI^:T=QVInIV?wAIPEpdTkG^EhA<LX#&hNpei6hdFdJ
ck\FcD byE89T<qtZqkbMVXu1RhN4\FIlia:GdqKw:FH*1Tklm*wnR*BhQeht$!$ImDK/dACBmMCMFAjL9D6<GM
acRX8i cWik1*KG5EIGK$c\ani5NkuR$?+BL6AlmCEtS4ww9$*B@Lb?/4CqH9eDuk+wTB$\m?$6b&&B$qNtSh=\
D+XBL6 hk?Mc4P#n4Nm+A^LFM^^5#QW*dDSaVnF$6eWTq>VMH&61dyMmY&8M=JaT<:kJVGWy6@X*/mN=c\yqK!q
mF4NkQ aM=cah?V/D*NMneiPKaGiBkqw:R%BhQYm4VMqu6#waa=I&MNJ9T5*TVqeE<LWVHMbH8L:\\DCH1TQtD:
J#Mwle +b%8:6yEMGERei6WQA4lPY\1hGhqK=nE>uC^&1SbY6#^:laW5htd\?D>1^l&FtNjCipG5Y?bLw1$t5S$
IJHNcK PqK81w>1a>!DM4eW#F$:RDpd#p@KDT8Iy5Bm9m>Kb%M\ui%$mnN/^Y/KmlV#k%EYq+LJdj*dQ?\hJIAF
A=tktH BmIDLN#KERjD>DX#S5l&chA4e@MyGBn9K5T:MK869j@B$&+nWYkqdAmEEc=ClAN#%54lJbJnI%tl=dEl
GZ5>wa JEc:KKqN\cT&eu>XXqqXd\N+C=DXll/Kt/Rq=kmn4DaF5>4cm+I?>CA*=W%AByYDYQiS8#a^u#JBMNLX
m6V*nB *M6TdP%BM!<4+pkSRaPLMhD#b#H1Pbd$yqDTt+JJd%X:JXi=*?&&SiY8HY*Eh4Wji+hSMMy%W#DZ4dJ9
V+n\Vd h9B<><mTpHW+HJd#yqDPt+I=d>ZyG\1GaM^%k^QAMByG&Y<Kb4<>K4Jhuy/bR:>k$*^19DLA\!kbJd<y
!@%I:b tQ^Y>T<y<j!=P!+I=SR\nJbSBy!CGZCHjRwX8pHAyakBCEdEKAFP\RT+GkRFB!hZ=h&9mn5kRV$k+u%:
Y*ybn+ JACaRuieVH^&?pNy=k@4&HtN4+KbeQVJSq%!JKSDTb^Ke$=GnnBMjK99Q*q\d!S\CF%%H45F4enAHLh*
IN9+w& *M=VGE:wF6=mu&%BKq?\1#deq>w4tAHZT/&>M#ci?p<=h%ymtY+KbdwytPu&%F!B=K+S=j>%NVccauq6
i=9dWD C8Y%KbnZ>6T?+e6Pc*P@Wi!AA^YAKQZLdtequBLND6VQuSYj:cu=kZ9$\l!*b?tX8baNdA?:Z!Z8cauS
GCGcjQ LEypW#CS:ht&YL54lI5MQ68@Rkq>Ctc49i88dV=q@&w+Y9uFPJH#8K!C&Y9hV5th\?&t$4$CJPHtI5ya
u^Xqdi W@&M6jdb&#D?j@n1:d><@>@\1:i9@?ajSij==aQ\+^h@Ld:%F@?a@5dHZ@@8*Wjiu##=/Lt*j!@/6b?N
!ARtC* j@mJZ@*Q#@#$>=@<<y?@?@/jjc^?:QdJB?Y*@89H*$^i?yV+@d>>?hQ9Z@#m6*@<tc>><Q*p&V>>=J8j
tcY=/K ?55Hq@>1Z5b>>5jd#&Wj?>NQ@MQu#4@:Q*>#:\?jqb@?>w?1T?>:=#?+@Pj9dj::<^@=te8ZjlJ@+dNj
QX8wB/ ?JHWq/>h@91*h>?1u<Q>*A59@46*<%M@>\i@h@HJ:@*Xb?=>==59@e=ZZ@np@IQL/KPj@a:+?S@?^!<5
-AJkB+ 0000daab76000110333 Page 114 of binaries1.zip
im$%\5 %h<>?iI9#j@?lj^Z>MZ:Z***w@=Q:u+E9XTq:F!?D@hT%jM?V/XaDq@>QNX4TZ=hdVjtmc4nj?5@mJ:k
YMeBY9 nYS6$p9T/&Tjt#DpjyE?&cid^c$ZtBjK##e*bQLpC4$+i:ndX9iQ^/Fud>GAYZIMewnB6QJie*y=Y=kT
qTKI:Q !+WbACG=$#V5p6%4cZc#14!AR1^/ENX@QVMHqAqMu6!W^C!N68+iZ5w/M&>Yu=uV8YI8lSe*d:tdV>T6
W!T><5 wVGYJ%Y&&b/>6VYbcC@PHqR$\T+PdVG6ipkl##6ibM4>:cb?HeT<NiyD6EaGht61?F%4\1+%M1nj/YE6
=Xip4V w8u1#B#WE*MKIGKyV:Zw:nbjut!RpLLjwyC#GW5p@D@%V@$t?cFF<cA%+j#\CVEui+=FhKw%l&c\>6R4
pVduNS 8:CLIn=L5n#E8pEZG/JH5$6AcLQ4/=Vw%4#Db6+Ht%*S6EAjYTTFMiHqq8Lh8nut9:qb@QNt%?bjV9?K
lqX=\i yLH$%Z=#p^V:hb:5#e94Z!^#e#b@qne@%>qtZ*1#:R$Ny5ji4N=jt:*dXQGN\$>!yte9d:dXM4*&Z1V^
>pQk4H QZ8!*%bythZ6nRN9hqMpV<*mhEV+><ZYE&4i@>CX8WtWaG&yhIJR@&F=%anVQM>&JkN@6p^8d5\pejlJ
yaaX?j H/Ctb5Xm9::P$@i<&T+616X&Z=4LLpuBDeTdjbdZqiVyNYum#R6Q$HA@%HER%j<6/m=w1/:@$mFy@uyF
G*m=Lb 5^^S*a\/1NbN8n:<4LKeb1\bSjdLhJ$WyKd!WQ8LZjXNEX6TA<&C5/<55>V55=mFYE*6&BhF#Wyt:FM@
/+a@:t dl?ut/8E:NY<FD>4Q#6ddHi*^=KK=ZY/N9ilyQWNI:N<i&QYZKkj86/aFiqNSkFSpS1h4JQF\VLTt!Iq
?WQymL \L6<Z#d>Y#*dqu8#XETDbFc6/M@h4<qmV\\>Y?<JD4HT4Ja9nYZX=e+Y/VLL<+RkdZ4jIu#4yF#5<^wk
$&d9%c iR*t#$@&=u+RM\:yq^X^hFNbI!h6$DmeuS@5bZdi%H#i:?d#k:byJHh1PV?a=jtFN*8qSZQSqHLSqHLS
DbpD&P L?Ym@VKN#8cDD=wQQ8l@<EFZ!\X=K:M*t5=?5@uTt+e99Vl:5@?6N+?j/4=hZ=T=!&>J&A!66=5m*n+Y
?>d$m6 <Zc@mLi:4*/qAjbw6T&MThjiGbpq@Tqy!pmPbTV>MyIGS6KXqS^WqSmicFYXN1Yp^%LTjmqy>?&5?YDY
@:4Y6M IM4/u<6/Pp&N4nbN>h9tY>9tY>9?6:dHD*Y%LLPuYh*F&$bV?/cAjXQA9q@A999mdjQ*/1Cw&\:R%#t%
\Sbj5: YpHA\V&8J:u&qWLNdp%G@t!dB9%X+4%DRHlM/j6/:%PYq*%jiP%iwQVch!YNq>Vteh*ZZlhT*jj4J#Pd
*b*>GB Z&nYEi$^6Q8lwa@nc684+8YRZHwlQT/l+ynE>#TVBJ:jq\S#CpE$E&q!*+RqEnL&&yZySpT@T@ayHZyT
KA1QTc MqHpTeXE5Ti%LcLIW@yMJD#JcmV*ww&NnmL66b8JS=H96S6=S%Hk6j6ynam<QG&DMP>BcMFE&4Q%HymL
aE65w: W68%^qjq!&E<X?RI6TuC6WkGbFh6e6ySFH66hqknMm?M65iZnnKjbL+qC?jTc&Q^SpSjc<P?k!mtCkP4
XjQ*@Y AtXe6Qc&m1Mw>kJlm\lGwJlIiwEFVJuDYJHQSJHZ=m+%I1w8CyqIiVH@qP@F:FM$SKKImYkM^W\p9ZnP
B1RP/n SM1LBSPFZ5#Lm4&aqSWb4=8J6QFhtc#&AG%bZH96VPcdT=1bnIB\WiVFVLMELLa%c+/cC^E\tdGYpMpp
n8KnWe !TItI*AmbnJ1tLRdbw+XCt%DMd6nESiSDVF$=Q\FDB!NmaBlw^Ee&a$*9u6kw>X#IneytC!1w\BdFyQM
tSw5Bt L5:5HA8yta!$JH$tw=dKkMqIT#JpM6KT+nL1X5W\W<<IFVMb6WQQta#cwXud1GiEbt&nulEh1cmZ#T8p
MY#kh> w4*TmkSt6/1:B/\Y?F=*CbeScBN@>\TpCNKE4!!J?a!&JKam*=JRP>y%9aMp4t?W/$tp1E@Z>TY1hun:
pk%RN+ Emw=tF5TM+%bCItuSTD:EtZYBm#MNPGK\MK5VMpYblZYHuXjap1&MG6V5wZbcC!\MNNE&D$BjbBR!cGF
1<1hNG tYa9EX1aTi5m6DCV%n9Q+mA^JX8a@hD4*kA?TE#JF8dAqG^lDp#JFtdTSQi?/WFCJWeYbt1qmC#M%Cdy
:jGt!@ &^LqTh6cRtNmXm5IudT6ldBI&%wm+WudYmLqTh6cIqP!%R1cM/S6LeV<$4cY&HkEFtdmXtqdC@Gw6K$q
l*VAlK NmXdtPQap=c%tEP%$4IY+\6I!%4M9C<6c#G9kWnLY5^6I6K!F9P8m4T5^V!mIm%41ai!bT*t#p>yYa6=
L4Xlw\ <WBc%tI!:1SqLiaGi&qbm:t8946L+XXNZBNF%D?1/@qcFlQj/4u>8bmt:G+*yJdFbnNShbN$LVP9w/9P
@88R%e kY^p!85PMl^q=J%1?:9GG>YhLlybTDJ6!YK!!&=L1yGSQi9Pa9VL$Z^8ZlHXYqp!$:h?9&&%#K<*wC!b
ekiTca Iqe9>C&bJq:^??$\M4IeZ>8j<\tHH$ktw*wD^YVp^\Y/L^QG!qVuMhW!e+lSm#tVpX/EanL1N?E#GZu1
%c5k^u kyXHtLY\/%YS<Zc66kt#SccXZb=bA>VCcy8Icj:T+u<:?:wi!Y+n!@eB?n@p!\D&\=d+GTRZlkGQbH8$
Cu*QJu K+&%q8dDH@NR*X%6%dnXJXTZbG6@@ecJ4M1dnBMLLNdR%HTh!4!H\S8MIIQBaL:G6E8dqb*dMP&D64d9
GH%PyR FyR1QDccunHM#>9&QqS61^YD8<dt\N^:@>#W<h%chyn&T>6=q?yBc%5jXMShn:*Sb$^HhF9:=>B*4a4D
u/L@BS $JdlMG%L*j1kak8/:??!w5^GL@9#PlaSbi9:K11nhY:!/qyDLFH6G6Q@FN8jl:XjuX8@6KVn98>>$QCP
q6BQEI i6p^&Qt?9>@YMSdKJt@D1eqiNuq%CKpe5u&*4!TY9Z8FCccXhjah$*FWy@8eLC8Gh+$%G:>dY$bT@Yq4
hXIZ!G i>=AEaG?//=?i>nhel8tN4Kq:Zt#1?*4ZZaMjhW*nmucq4/*bR:auH$5#KF#\d:duIu%j6>6&MIa:&N:
CcMnAy *ywaY/5/dNyXT\it5#IhL:K8&/\YWZY9V+<X!*djMiZhhA%a5!!VDXM>pPa?l&u>eM>Vu!9Dj$/ZE6M>
\H8PNw d!TL!8?aLpk*iaHymuRdq<B$$dG>e=%HcB@*6LhF*bqmY^?wPXB>q8&:C:PR96qmuYHAb8?<%9e!>5<6
1Kdieq %c8/!cc#kRZ@h5&4<*khc**VNZ%6%5@bah1Y4X?AIhBRh\#>q:4D6Q?TPE#:!9P1u=Y64+Dyi>9<JVCX
h\Ftu! h:Nl\JchW>+\qX?!c#PmE6t%Yi&ZdQ+ItLa9P#uWQpn^tCntbFMhqidcalEM%^d6P&t8Ljy8ydt&1E=J
C5+*Tm e:#/L1X=Zw\F%/i1c>L&Q8$/6=CiHKdQ/>ql\$/m:=n&e>@d*FXY/e%lKq99DqNiEah%P*T@a<w445$1
?K5Zl5 k<l!tLbqPDqWLlqPDyXLlyND=bLl=PkIGnk=Pt!Jp/QDq8^!aN^*>:tJMVl&&cc&w+=h61u?yLp^w^Nn
wA=mG+ 1$^#nT$hk>Zy!>L=Xh*%^c/+1b86K%b*98%65cPKdS@u8kmD@S5Pk@&dD6N?YV5H^1VW=DCMGj?=cbeI
VI\du/ dXkB69MP?I1nu:9P5\h8jl:Hh<?an4h^eBkt1b#GMX>:^pT^9GQ/#pb!*>W^QjL&*aY^Q*J&GD=ZHDbP
Z8tyR< +:Aq#>lT4P?an9&S^YFN5dFlQTqYp<Ptau6d8n=@%PI\5S*uHhQ&%ia\jX:#*>W&N@hh%aQS*ih$9VY/
4uIAYa @=#K%l&H/55R@%%65@n9cy9Fj%jdLH9@aj\PEaey4:n?/?ChDkQ9eyn!Vw<y:*J>4<?c!dXQu#YVc^@m
@#/8&^ ^?/h\/hP><:lW/h@=&4db>:dDQ8%TuhaXW\e%m^*a<j/cdq*D98%1u<i\5Q?iXM^@:!qtG8j?64XHIj/
lYjZD+ %hZe<>T948ciy@b9PS$THY?4??hyt:645+/*%V&H6qu<<:VNV1>E*?%!iwW>pPZ$C9QB=jRK<<Hq>A4#
=quk/* \iZ$Cu=lDe?lek#QwZIM@%%6<>#%D*Q=NdQD6C&#PE#dM19D6C&#PW#dM49D6C*La>1uc&<#dN>c\&Hc
+C&1*= qnWhyt%b!&H>uJc#k=c4+/SDBDkq@@X%#wQbRMTBp#QTR\&Wk1=*EB>P#p\QlIlVeZ%Y$KVmQ+pt8hEI
:Tm?md 4/Tk/!KEqJMdn:DhPXWQwy%8XMF/K?lp4>kXcp=&SKFVe:JZNN=b>wHwhHKtjXR$*w*jkcl%cp=MJe:J
G*6An/ nW^+XRZ>J!GSG=8nwjHh!a=Ah?yP>wdGh!e:A8BJ@DQSVnhAS$e:*RkhmI$uN$Vl$uIc4n<:&nqe%!F5
R/LI6I uwd48w=&?8GHeH4!+\@^<?RG+IT##Q5HhdX@t5:yV$^A*MCctIC+kVZXIM=WHAaH=Vl$kE<*@mae#@Z\
CbyT6y $\<pNcT#i1\yXuaM8/QZp\*DIEh#tHJeP^:D6M*Zn5e\hdVNj$:qcP=#ck#u6WM^VN9ey5P$LY$=VN9T
/%8aY* p<P\4?#pXae!8=NZueeWn&qd^QWBHL!+QqDuMeZJy5=nmyMN:$PedGy\=@DQ$@aN@##61:E@D*9Je\!H
#*EAJQ cX9GhJn&%XkP$:dM=DB6!<\P$:dM+nB6!>#:JYh55DiHcj@N:nD69?Y@1&%i@49cj<6@X>8<ZB@w^Gw8
*heqJJ %\i//FuJjR=J5Mq@D69>41@W+1@p?pwN@5184>R>4P#/1mKS$@XXSS1A?&:F=G@@LnaIqu69&Fbjd5!k
baRutd TM=!:^\B:%YK\+1q!P/aVlnK*9jaHBnNje=!DjL?Rh8yV5hTZG:k:=F9pK<&J</w=SJedW?<wNkNQkKT
pwJbKd L/k>\V$Zc>q<FiS<RRZw<ml&pA@H>I#cL9LltX=R&=F8HpWdDu@*nMIHZ&*G9KD+dQN56n@i9MVNu8Db
Za@GId tn*BT\\H%=99Ti#%>8wqlw@1#jephul:>SKL:hQ:upRchc>iNpHL1yjN$kY1q&*ab:%5cm4!%idDC+yh
X*e1/5 @?Jdl9!p1<&BF^S999mYLZ8C/^%e1JN:1S=Fu=ZpWWleZK>dnpjQ$/PRIm?Qwl?!iBV>pJ%54WCK*D!K
N^4uQZ N=ThdM*$LH9bVM?!q/*be:%5tEbhdcp<w=khZRY4Z%D$V9K!tWaqL=8kh=KZVh%jd55@\VR1?baN=J+5
>w64#9 @+TB*KDqY\cN86ypiWcuQeG*VN%K961$iEH6Cd:Zq**Y></!#:yil:C=VTedPn^jdai<wHn8HB:Fe/iV
4V$B#F 4iQN6?Gjm@XAt@/=tNFjBjiiWW!@&@DQdjbb%&iIt8c44aEZFG!nilSTnPbSTPG6QW^/d5Q*Gc^GE!?d
c^wIcK 9julbS9RHjG!DWklZndapmbi6tqQ<LLbt@eiB=HE*MVLb94kQW=jiEQip\p!&=4*F+k<K8ycl9$KSj$V
n#XP<= LHP48=aJX1!6J+@cb%*LEIQN4W&Q+kq6iSSQ<N=Jtn%liBSTiP?EHRJF9Y#hu86qE*88q\*=RM%:J$V^
NAAaQe e@NiV$\j9G<S5\Vi6+mN?i1jMMFYje5YyCm?h^ap41=qKEiku^$iSj?Y/XG$#H8uadtP*86bVKS=:#R5
6Y1acF G<>:9RF@$d^*55BE<%:Q+k*Ni!iLLVV9>T\R$L^*51X<<%=9NQ85q<%5mjh/6mB8*4hkh#R*:%5R/<*N
/AT*1P ?^bEhuQ#9tYab$m?h$^Lpt?bcWu!9VQSP<u*86pH:=&RBcKw/*W5tZQ%*kpSaWYhdBPiwZ49NJEJYd*Z
DcSb6V R\kkX?>d5QDY#!cQYq+wQYEB>T*D*QM1&iEFSSdy>C*4lqcQV1C8%!htnqhJHm?w5SYQwtZi9<%lV@C!
-A99WE 000b249cd4800110333 Page 115 of binaries1.zip
yTRtLK Dj85q\*Y9u4@l8Xn46/@ITmT1@h9E>c?i9<&q#*Z!\d9Z:$ZYjdt9ZjCWnJZ:$Y\TM#Xi!j5/iZ19enK
G=YBq% >quZMm#be9Z4IT#ce9ZicYGFW9%/cMETXL<i\6=A4u+>lKl@4u+>lBl@46/@IcKj1@h91^8dq\*#l?4>
SEDZS@ &#Lh<j+N$jqe9Z>dymZim/\BQjQiCW9jZL$ZYca:*n9lpHt8j8&$VE8<h%yahXT@hpI$QFi*h6L@\PdY
tdTHkP V9wj6MT6uT#Ruc9#d:c&#6Z=N$Z6ChtlymZP9%qkPqju**I!C?Q<t/J+k9N9mpLm+tYD9/nF!+d=R!%i
$j9QH@ N6Ph+tW#*TqiN5\1c9bQRFT&b6<!#Cy1>p<\8=N>!#D*4Nu*ntqW>m*Dah8cji<Mi+L9hS!e45u*nqtn
=S/%T8 =H9h>C^=&dC/4euLbu1Y9G!aq>VpbePM6D4@q4QbKPjjend9=Q^dS9A8X?jj5tZ8F?jjMkJ88Vn@qlFi
a8><6@ !<Z=N#5:qw9#d>t!>M9$V$DEyT#jMtl1tj+J%b:kY\chLM/@bYTn=VJ>!=w>\jePhLI+@=b^LC!Z/Z5H
:LSi@y tq1t:*Z+#VK<dJn9qPqqE#^liNuEu8Bq\!1yDC<dIm=qiNukN<9\5p*:4JeNPqtGq&%b!:^5YA<X<dI6
ddFY/K a*P!IZM>F?ihMnKie*FiV%G$\ZtuZE#:^D@Z#55+:/Rw?5^=9X^M?=^*WlT!Pc?Zm&tj<$/KRndu>XS>
Z#SW4F :RqiN6nJ$4%5<Kcqiht1QhjLbn4b9G!au=ZtbaPQLe*LBn6btyeN5:dT9G^my=c<dLCi^j55bIju+u$Y
9b:PK# %EbS@%#VTi?#m8tp>%paXNchD4X#X::QaQ8K>%q&R1%+u&Xu#+4*YjX<u59JX8*$q9hb%jVM?!!+FWYh
R!5N$u dNZ$#K*JenW>e&5!e=t=8DYbPX%V%^$%&?i>upYdT@c!ti*#Zk<VIB5eD5WV9M?!8HL^Q18c:umjXe%!
ye9$#E ib?FTY+8*thltt\Dj$jNuutjXae>%@j/5Dd+*yu&BN@4mQyp::M54y!>#<JmTqE9&:IuPNp5ky^h^NCY
n@jW^/ n&aYHdyPbpJ*FQa58$mp=h\1tn!Kk>e8EtqLiVQaP\y9t4$*6Rl!>q+QAbTe9VjF?aGe9e@CCaie9e>C
4SH@AV cChu::M5&y!>#$IwKtj95^DM!6u:LI5&b??#eJInb??#EJLL&j55BQX!>n:Lw5*b?!!EEHQ&Qk6l#J#F
Zim*aJ !+caRla9G?^bFm<dbwNb9G!\b%t<dKb>+tY#e>jid%wMPu8@&i$p49id!B#M&j9Ndn4yQR/&DZL&u1!d
Qn<$wH >utQa@H1:D%bN?*#HkedP#cb&qHa5?\>n5Y&5@hpF69P#W9e:AuXw<dtbWN&TG=iN6M#9%K#&Hc8ZndV
NCZ@4G Q8@%5DGbe@Y!mV*B!\ddq:$*6al*>q+Q6@Zc^NclpM%:9Y:c=:&y^dc#>*4INM#bi%PLdYj9Y#4Y5hu:
p#WF:< FnHd=*&L&Jq9:%6\BmBu9/JC^u@Pj1XtejD5X%SmP8qZckIjt:%*ptJ6TB=F:*n9bHH\:L&itJZ#*puM
?NX5@% !ut9J&dq9HeT5*Li/!E9Qtj9uRT4k?!>H5=Z&TJ8S<ZceCWdEwR5ni4cPXuYpP%k%&6\Yd&AjD&6AYmX
1a&\\c H54&>ZW?1N<>mDh&QcMGcNq*c*<tKwDp6QbQI89De8&j\ZGDGR1\\*YeMY^IHw:nnNqB::Xl6kX<PKM#
:%mpnb l5*Za%q&^4D6PZhiVB#:5hR:a>k$QSb/\M/d^Mj!<a\bl?!aea\hM+/=a<c^!ZHiSq=y^<C^<w/Ba=Wh
aduB$m A<i1P\cP6e6SnGPZw^nHLwh6Qc>hntIe8^!Y>LB&PYDKJi%!aFppcbjDn5&uZR+:PJ>&Pi#wjN4q5MQ#
GM>uhB cbjDn5?uZR+:RJ>&Pby^:HI$+>nqkJP+PqNpGIdV%btmM\cP9M8B\Z^%y8mMYZGBZa=8HL5eal!:HGIe
TM/%*u 8^^\K=J*PeR+hnuETln5etA/I&YZA<FTKd5eYLBJ&iYA&=G!!+Fy?NW=KMM\Cd</B*ZGwAhqq\QV<18#
9?!/kw H&eMeyShDw#>1:Mplm$4^4DLkR$b1d5eeGqTh#uk$KV8em#n&PSAQwJm5tPRw++hk^^%:ln/11+hR%?%
Hi*y>d VR=LDlln=<DaH:6NSDbIH46N6Cub&G&mVenGdlPS#bLHdlPSDcNa&VF\:DaSiViK6S%DManhJ9b1=TB&
L1VPGD PVDP^&+VpVYW^&+VdXw*hy6wp:1^&$SLalm:VVVjN*cdcFP@5h6EHBqVdJjDmtQ5N6GtktP*mekPW&!Z
9iGaQY \\ym:DdSJwFn6+uId56#6+tYCDF*t>nQyVJ&Pc^a^t+V8=ZL&G%m^=mi8$*EBW&K:ZJk@M:hJ5LNK4dL
9uEN@I Mi%=8^#\$*P*mZCLm8%!aIa^h=6wW>C=&$SL4ym:VdSJ/h^6I6^au46NlM9Ke:iJeE>=:ndSy1l#6+q\
=ZdWa: SZu8N6Et4ZP*mbc/MZidcIpde:iJeCiKdZLaFHd8N6Et5HP*mVD@mw$hM+=hnt\e8^\a$*P*mVD4ii+&
<ZEdH/ $XJF=t+Vac:#*G&mJa@M*TdcqHu8NlEtN<@hJ6wpi8+&EcbW5X&Pcl!:HQDue:iJPC/4&C+H^9=58^\a
p9#ic/ ?:Q6etD5#:dLkdG@h48BI/?K:e>D<H:6h5Pt:G8*G#blZ:9h5Pu/&8&GJdm5*Y:aBH:6hkNH%QQc:RcP
ud*uqu ^yc$&\$ek!%y6^5+<q4Tdnh\QK!p*Y+kXWc^Za=lHL5e\#l&PXBIJ?%&A/W*FN9qRDGh6N5NHPe1cded
chkTbu PLyX$t+*eE!4yN%8+ElYTd9hRGyPTd9h\FE4^Za=quH5e1DeV646Bw=XKddJkbRi^hcPkZi*G#lYXhJ8
IGPl*X N*CE11VhdmD6y/Vhd8CacWt:*eCS$yJ&8+HnWmZ6hkMuw$4c:RbKPCm&!%Ek^&+*eAK1yN%8IH%I5X&P
GZe+N! Aw:hd8BRp&K:HBWe8>%AMyFm8^#/1&K:HBZ9a:edTDp1cdedPGXW$t+*pISW$t+*eHKwyN%8+I^RTd9h
45FK%i RKyTTd9hRKJTTd9h\FtkeuZp/a!l4>w8S$hj6X&Pd4!:HB*99P%!CQ11Z<5Bm>P*GTHTF5c+d68$GiJ%
u>/nj* !?Au%#cHYtcS4y=5&&VH8jVQ!$%GdWceR4>ETJ@BYm#<$D&K5PjFPF#RbYitCLYnWA/6=&%yl>yK?cKA
F&WR^y u%hFG!I+S/#/BT8uI>d>kpH!=DA=HdH&F\^iwP$a9Pl!HJkbL<hlI<S^&Al^HDbCHIiNEMhSwXtPR\hS
y!b$Gp !a/nww/y+<AI!a+DI!R:Dw!R:DlW\a<hyShMV5iP%A8tHMX^aIRW^+ESWl\HSpl%HBkl%ZF$XF>%HPw^
K<nBdk n^*FF$\=18NRn%tc++DHdI+DH4M=DunM/VHq<LwGn?q%DS:V/^w<y6e%ZaAX4&5/bw9ZNZlH4&5ww8S%
5>q=jQ Vh6S9c=yP/4ZNY%H>d1t:cli%%BA#i8c61M/ZaQPX/h4$Qu1hA$/Z=&8Rii4$#ZwjHY/By&9V6ik<>Zy
hD%HJS GuT?Pq&D#qiuc>D=/uRNPq?h4pHu1>M%/Q!S5jX=M?5$MhW:e6<M^bp/de8SqZik/%R9W<$LmwJTl+/e
cGu:h/ $aI#IphY*kXFY!@:N\icV$i&*+G1DPLadE=aq&6b^aHVI:j\k8wc4l/cipa:#k\hPc\ZXF*4pbF<wKlY
H>G1SB LITmSNwk6J&PZQRD:cenF@%A=ZVp8B@wPB$=:ki/V5j=mA81*#:PS^!wTnHyCd48Q$/qHCkKI9EV=HTe
TH1*pc =DuReVyP<l\w!u!S^CkEqapNJd^1IdTen9NVL!mYwd$/KRdG$ZF8/BthPI><=IG@wQC9S<d*C+4\jBeu
d%8$yi ^eVM8a8VaqyJF6tqRCE6Pep5lI/V#E4wP5q5DpXypPPe$^qX!+FmPi+NFW9RQjLlD^RF@+yD4bTpEJyS
WmE\kk 4LET19wknXB>49mY+bVqpZ%@wHI/e9$QXQY*:LyV:A#<TMYnR>@^w5<PFPRclQbVh!P&YNJm>*%tYj4m
<5D^J# 6L4aGS#J@4p+4!N=E149PNN#hb+1lb/4:%ie@la:WTZhQ\HSRitDWFS=>t%AlFApEc46hSc^&Gc\#P:S
?I@@GH DqRIlcbTG>VLN/jXKK+ET>5JlcaKwjXW@Z5:?\C9WeY5pZ>DBY@uCG>@*5$:LjV9PLV9GaYXG<N@FqG*
iE^Tu^ I@l%wQW$?Rp+k%:+Cj%$lMBiWK!a%>FuF:Te%nGDipE^D#>Y=leaW@FneZ:AYHFW*&R5P@P^=L4A&QXJ
A!l!6T pkpG=dH\iabSX85Il^y1>R^R8&ASYp=HtP1C1uibq$#AA>ZQ>p/w>teZRyim%Ad$59k&aLh>LpdHccXE
p1HLZK /D16:F8GHj?Xje5\e^:WM5^%^@:?DeYJd@:5QA&TA6qDa%TQcy<hm>pDld=T!:Run<&SA/&ua*9pRQ9y
^5CCXt &CA=WJXmWJ@l*Q1pQqN>PLbJDqTqtNRQKDM&TVc%c5ht!aG1FI8jwFI5jwJ1TTIyWPelpSTw>JC>FJm#
?t$ehH H\HyA<Wa>@%ddHT%TjA<4e+wKlD=SlR4%=I1\Xc>l=ylJX5!Qh1K6qVj>eZK6nTm6MI6yBdqZL4F/\ZP
6I+H&B PS^lpA9cWXul<8TlKJIM5JF*4BhjWG\lHn4@ktKD:?m/F^SdjMi5>SuFb5hSQQGCa48!i#dd5P!i#da5
wKb9&^ 8&i#VW6^dDmTbwpmDkYdNI?CVeTnX4N?i6V1%u5&dHaeBSW9KNmGb<PG^%E5<aKCdZk&yJWeBXqj$GKX
G=nSVI <n$dNnt8=yE9KNmtb:NK@>P#YdZ@=ht5+9@!dMnyQ51>ZqDw\@J5!MA>!mY?wLc=tV!ddY<t#&aduMt#
jTTPi# &Sbu<t!&!bp<G$dSWeL\kwI6i#aEH+?TlSeWt:db5!EVdtVQby8k^dNl&?QKt:!kaC8iDhtbw*k&bGei
yDpF&V ^S=jWGVNHTWSL!na1thD<QIwh*lBEX!6uk&=hKN/Nt!MHwWpL/nh1PDbaDYG6!YwEytH6!YYC#1<LdFe
+R?HBt $PF6CawP=PF6CewY=PF6CRwj=PF6miYNDt>LLG>$iF9TaVYG6!WhXtN+Y&LXD+c*JbbnP4\6/dbF&knF
8LN8>n S1KZ&CwqVC<^q6y=iwp^ue:VT>^6a=Rp61%Sp6k&S$qmyEBNpllJWJMp4lc+>t^IlJ4ii1IEmyYBhTna
Pt9dnR 9QZEMmnQRY!R&F9Qdq8w*uwmKJPu6=+I9?Vy4cjXlyniiq4?:QVY$!yGVG<>EW4I$%6QlFV!>NdVet&u
!tP$CK 6==am8Y=mA&BjG<>EV^S%LQb%11*ul$Ybuu4cbWwq4iiqyi:9QY$9N#q4cjXy%niitLHSXHQB48#M4Fl
S*Wimb $<bdV?R+=8Y6y%Y+YN=/YwYL=c$uMlQ#<6aViak/DjX5TK%c*uympbmZ6=/YMd!<>dTM+iY6y>ZIYN=/
qk>E\Q I8jQLt%\KJ:44chqDC>9QbG>y/lnR@=iZ6/YIF6QWe>tY$niqqn6niX6CeIiiZqdanuH!>5T=Mwy/6qk
u1IECL T=c*JemD!<9dE19i5d\6RSBAq\TiDdbpiX8C@DXFQS65!jK&^Cy>LG>LWJW<L&>LWIM<L&>LWHE<L&>L
I8&c^V WJP@JPyj*KKZ1H?:dan/N8Dm9EV>c=85%L@aYE4W9\I&/q@dj1Z?FdBS@\4a1H<F5qH@+k/nSQ&Li+\T
VnP4tt >T@8Mp4W9:nQKFH@atMyWj>P&$:$dNPi/>q\t%H!6ly%WE4!6l4%d^G!>Cmp<Lac6Y%L<4acW>?T9c%G
&<*n%y *h1T9c%G#bTT9c%Guh1T9c%GXh1T9c*GJLhpd/5^!T*b&&1W&T#b&&yWZTub&&yWuT$=E>9C=1^u\>%H
5pKwlp &h61%Jk6&h61FJp6&h61%G$y&h61FI<6&h61XHMy&h61VH%L>4b/&Ac#6>ZD6ym>4Wc%%=K>4Wbq%=K>
-AQu4p 000c4d6b34d00110333 Page 116 of binaries1.zip
9dcR?D 4WdR4YS91#H%Lhud/tEZe*ydnb16JZ6dnj15JZ6dnj4mJZ6dktK5JZ6dkpq8!h/YaJJd54eq&B+4&h5T
y^utud VH%L>4aEW>>!uPn/A65&L@?&1qM99&lVL@GpL>yyZHK*9pDR=LJN?AZ!/!@t=k8<@w8b?dLe4J815/B%
GPHiFa <>Zn*d6@946>c@?+jZN*8y^&P*>Ie6d&ja6Q@Q:8@i*V*h8dS@$Fq?$iS*&?dQyS8PF/<=9:9@#\iQjN
%B#>eS @hQ:8?h@*@Td4??@?%=@j*9@q@8u&@e*H?@@<8H&Tj@$<hR9!tjQRPdPi9/i*Xn:V\>9j*y=V5+*9@:\
^:E\#u =9Gu:*HB><*6l:e*u>&>@Hw/1w5<Q/mqh9Qy6>?ddQutt&@9d9:y>8Q>t+<*D?>8Q5Y*eH99>>@?hD41
*^5Wmp 1Nk*1<=hemSG8ju$+ePQh^>Ay$LeZby!PmwjjhuSEcXI9RF^8juul:@hQD*ejQ@+<HV*=8ut?^>i9:>@
^%6<1+ e@QZ8=<?*4^:jQn8=8u&P%\54d%==DYiH>LWWD+@BI*@/4hj*Z#</d99:y+i>RG*:@@!<Hn@>P%*H$@n
HuJ+9i iGH+Zmp/J:L9%b89@*d:@e&:?@h*K9Vn#a@*n$<@cMP@8@98+jEuFI*iYw$4/XVEd&?@j:y:9Qu/:5$Q
wy^t@# T1B>j*h?W>dj@@dD?\>*n:i9:>@jQ>*4&#8Y=F?Pt*u#+i=9:?<@@QZtX\lmnik9@+TkVI:?<mu?$1P@
m#h\cZ jIbFe+*?<t55A5P@@AbL5@By9<W!Kt#BQ?M9+hM?^&Iw@M9@\FImqQS@+m<4?55ZtKKHj@pT$?t\dj?C
FteTVT 1Y@+uZ@=+V9Xu#h&**ww<P<\n\&d?BZ?En:$j=%Kmn9y>@lL&BXja^aT68D4u:=:@jDiYll?<^9+?LCF
m<TwaY @\w9En:#*&D^\^d?P/^#!QMj?E5w:^>kiePu@SF@iZucX&1CVphyI9$Xi*Ly?BW*#M*nX?Rq>PQZjnyK
*wllk^ @Pt98C4y/5QnhJTj%F?^\*@F8$:>Mq!@W86&/8*1X>!<J<i98P#1cBW&>hjSDF!4p1<?*E@HmSj>Fbj$
uXTS5Z ZQ$X&=bZj=&uI<Kw9?LYpcQNc5yHQan$1iNK@Iy4QK=?^ZdL<TmhSl!HMQSZqA+@twFLi9Mld$W^:*H<
1M:Jlw m64bS%@yPDpCJX@hNFTBQl:XeMZ!%X@LcX*%e<N>F%h@dchn&Pt9@ZR5CjXZZBb^NKQljwXDI9*k88dF
N^Sh^G b5Sqh94Xni%C=KM@dQ9lm64&Hh4^@Y/dpMjn#>ZnD%Y$\9H#/uuaK4uT#Y:uak>b:MS^9&1QueE@*wDX
F=y<Ki :MnH><Z1b^#TYq&G1=Fl%V!8*1BaHcXDH18#hcWPalZM49/PGp*Z*:jKj%j<XqQ^?L:X<4#TXK9qiNX?
^V+dWF ^FJ/894hK9AijIm1>HdIa^YF=ilQHG5=<qD$h:8T@8y=mJ6h!YQy:Q*+P>bWS?YA4&:8V\jZ@j&yq19j
emT8QX :p>ZDdu@<ZV%Y8:@n6MNq%>@QF$%/ej:$:G!\c@*y*\q+a>+eL=1+6>Qq<JA9@#q/hZhl:eQ4@@4Xcu&
JSKLSF TQ##F:@R#**#$@h*y$<?9hYJ&5Nj<L*d9/muQ+4a@i/HJ:YMCyYnYN$**&JPcNCLIJ@hjZ\!+KXB9@9?
T+P*mH :5P9*6l</W?ue:><<l>@?PQy\\@9*%@>?M>u!m<j*tw#@9Zn*aX9d:TN6E8n9#=><68Hd^:A8#@>9&E6
8!hIYR bdhW+Mu:E%Sn@1>QiF+*QD@D4pkKu%G&45N$<jT#d&=j/@>:iHjT?iKV#le@@9#XJ:</QSPmK@:q:8>Q
:46\c# TKP>9L9H8^?lLbhZhj8wZ:91+C9P9?5$@SWTY9YF9E1Z@?E1NB$h:%:>\\5CG&>@?ZDB:M!@^:D=/nC4
^M6cu+ >8M\1>uqMXk@l>p8tMNG<D\:q4bn=*6IQLdwe>&Phn9MnuL8tFnc95M5t>hlhlY4\/#/15Q5?QmPDh9D
9TAB=D *dE=YLbyS=+<68l>VJR$hNm!+!<iE&4j5t9kQVcJa^Z8q&X%%l\Y9N>q%Xk>NynDek+>N9q=R8<TqV+/
N:V\RI abcS8tNmqhy*dAnyM$/8F5IYe+^F:\MuIIq*buwjPE%Ie5^C:\Pu<Jmnpp:mXJ4uLeXm\V6YdVd8MQQn
NMM%6R D4QMhw@SP!?%Du=iI%6T:P!t^/R^4\Rek@T1&QY>lAX6RaFS\8mh1:TNPJ1hQjEa>=>hNW:aaA:L/9da
QHSbpc aq/4!?$\t>$:#K/jhJkhu@SaIK>F#Zi5B:w^dRK:a<9tpR/#8b@HlL>4GjWit@!<SnyiqtXBi/\#l:D?
4CVwwa &VX$Hl8XPi!+6<Nt$Ai&e?e^<S\%&VE<n<%EYCdhWG\JaXd##&F&a5JnI^QYK9M&$w&ci8P&YMpKn=EN
pemP1# 1&pWd4Mh$*iaHa>%&PL9N15:::C?GLQ5FIhN5m@Ib\k\<lWw5SBkp:HMHL&pAA5+c5BSA++YeQTAw\ee
M4>u<G EuBI\DFw9GHHN<CE5eW/LwuGB&=ZL+RJQc?hn=p:#Haqh?^<JNXnp:HeGC5y\AKPGuDWkKMFHHd9mMjI
86wI46 J4bmYZp:JwQGjlQd+>/^aSYjQdaac=$^P!um5eGaBB\TeI!Aa\aeM?BaAehmnytaa?aeaM\^T\&\kKMG
iVyYSb HC*kcAFHD#l/\CEB^\k+S5A^A++beC#t5G9hCYPPqY8AMee1AajFeV^G</G&Y9C<Hn#QA9$PG=Y^Td/m
meRwiD 4WZ#yy+T#Rt:*bVu5WL#h5YE5W44qG+ZGupM>XW<JwW^8?daaXcC^YG4eJ5Z&jb?48DtMI65P/!RH9VM
XKy*4V >1Xuuy@&<=%RDlPKH!m&GLQ!LS+dnQG<9b?Q5n8M%%d1iRynqiIM8pJMnNu>ZB/dnA*!!awJa*N\t^jF
AZ#uL\ MuyqY>e4&#1hS6BaWG\^%uk5XF/Lh$8?<yl$^kcQle1?8>jFa/Gq^BnHI^TdnFWiC/$Ka+*HR88NMiG^
DSTY@G $JBa+dFkDLdJa*>Wtk9w>I4:iW^c8@T^ewBSHEtubnZAFtPbPYdJASb\%ICnBl\6+PkBS\<+JPCRkGME
K@ik6? HDQktAHHCnkYe/#EHC9uAGPPXY1ABS\%+GkBS\5+i5DSA\+JPAJ>ZwQYwjw$iy+E5YG^Y*M>byW6HMd4
I/bp6a XWpYBuha1+\lyhhnplt#nH!QVeb+#c+a#juqjCP!\*Jn4NDcSc!+85ec^hIpe!^D#8WWQVaa+:YBuQQN
=59haI Hdaw=mHuMnpP!:V?pFI!a=ZmB+w6^n4FCmSa>$kSYphJGa&^Kh#tSdFe1auY5FJ#a5!1n*l5M5c&Vm4d
m!w4n= P4Gchl/V!6nk5XC6@J#DFw?F8tljR/\/DYGD5eJnwhZGYPP^$HylVHk5BQEZcbQ:8W*8=<b^M^qC<#<b
%Tjyu/ k>@HYDTuqyqKkE*GetP5yAALPG4AWRPPFuD$kKMHHBJ\BGNtDyyj!b\y\IT^XRKM=nT!PD+8K/eAa+:F
HKm/uK e&>bJiCwAWhniXhuHX>Ca\6Li>>@5!c!ah4N6D:T=Vu=QJTQ!ISNj6/a@L!bcB&q&GI5h<bKD4DBYA$+
&l^E$a c5DSAw+ieQTAR\IPCVlG\DEDDy/9#YC?NwQ=&k#tc#Pa4<%k9ncD?hwM=t5#tK@NaL+&k@ucZJ*tB@w^
wYK5#Z 5wqReeJ/w9tcawP^ZAN5MXa/a#Zk1AFHC#lc\NEDDkp+JPAaAeeIPKK?YmZA!M<5Ta&^uAKMPaVuDIwF
@PMD?L HDZkcC!9hL>i^R$LZ1?ADj1eDD@H^D$m99>\R$1m=$&KlYhWwk$\aa^m+eAta!*k/AFHD#kp+JCAa\Re
SMQG/n =QPACYQp<+BN\6nu+icdFGDM\V+QN?#+PBh8&1L*m#JdnNZP*&*B<>yk4NeAY+#SQkV8M<5BNlmdNeAY
ZySQ=A a<9QqZH:5y?j+6wiH\QFLiN?QcMa^T%\y#1>6:ccu=9lRy9GtKRAE<bGCdCAa=KiN6+:BpbnRXiIJeAt
@dhT&y a#Vu#>KHn<MB<?9cHM#%WG9A#?XSEaD$XGj<yH?KDeba@$bm@S8Jaw!KnaBnEMj5p*S!hl:umyG81Why
bGm*q! nPWWaKVQ&u&pR!6SVFyNBM%LeHLZ4>pX1#uABtP6B6lm4AeeEuBI\DH<ZA@aat^&^qaP5EFaTVZAtKNR
m^*WHY nyI?4hKa$Sq@ap^Ih:WqNeAYa:TuyBn6KRFnnpt^FtCL5h\bK#uABtPN&&LZ:ulM@B=B\TH<\bnQC!4q
$alKIV jG:SaSRLA8Vuc#le=N?9HVlmnQbDT/t$H\4M/^BT5nyn=LiA?ZhWG858$1@<Qw=mFD<68w4!6pR^!tEB
bRqCE\ NktV%BnLKeCE5XICLPCwAWeLPF4A$RPPHuBIw@/VpRJMGGQ>\!E&*@iha=caIk*G1l@VmyE@Ww#<EdDF
WC=h%Z GQtnI4u=hTM\d#eW/*=MK$b:HYYWTZ$@c9K?VAe?=SpySntGm6WcaI8^%lu4PeACDkp+JPAaAeeMPCkt
MwG=yc 1Nl1lQYWAp\a!!ZAtENj5H>HE#8&lFGiY$FB$</aMLbKkE*Cet1M=SSk#JFLCdCAw\aeLiBwARjdk=ub
H4=W/? H5^M?i&KnSSk\6n$?#$/PlK@D<u<Q1T!HFJbDtpq\Lm9yHNjmRReEuAM:m5b*Fe!8c>ppX>h5=L>W<#u
Q*+8Mt RqSel6\JI@8HFFK@Z/ca?QhSab$CdDJGeqRpCReae>SWAw\=ctcPYqKABS\%+KkBS\5+i5DSA\:^iky5
MNde*k Mpc^i5WwdkFMGF9M$XKt>#8Hu#6YBHMbw#&qtqd1nNH<D>lk4NRAC#l1\NECnlb\>ICnB^\TeI!Aa\Re
mN:cdZ M?CaAej!c+N1%#R#Nlmn5%ZAFtMq+KkBB<Z=K?+#ZwSJa&#/>TC\\Snqu%aLZHm5y<=a#kHGHL*WAA5+
&/L<eH KEhVMa4LA^8Mmb<jXJSYbw:y+!1%uP>ah%n%?$\XY?1b5epauaFSnQLIkAqnM?CaAehmn9MXVl=nnuMX
b5e/8^ Ga@=*DjFTtPM<4TACYPWK/pa#hHXmE<jp%GM#1jWM6l@qMH?R>%dCnBlnQ&HakFHC#l/\NHJ6yhBc\%h
t4CYB! #HT@Fqh5$JlG^hlB&EwBS4!+SndAJtPbPi\tDeKEMdd*hXHPBM4Lp4:WSieNeB88Z\eAE<bwHRB5Mpdu
hN&4$q G%GwNkYaMEd:?!lW/6it8H&Xu>iuZ$eBY+!6VynR@mC\\Xm8AeaeWkKPGuBW:n?l@CdeDy5CnN?S5C%Y
8+//?Q LPAaAeeMPGdA5RKP^S\nMejIKeCaa^VtGNZH$ZGVKe$*hDbP:/NZmw5CY+^S9wAhK=1MDeaw9^PqRMui
8b4/Ei >$XuySHBa%/hI*ZCq5<X^>GkHGCD5X\DdDFYAw+ceNTAk?Lw\BbnFEjHVb\=\Abnk@SFlG&VDkY!5TKW
VPHLaE W+TdGl6nqFMEVBmnuCJk=M6EcH<XN#?tABQGKAaKnDqGaw/SThjWJj5eDJTuw*+b86TwnNFeBePT5b\C
REFWPl VBk4JeACnly\NLIH\<yQi+#P1RPdnAu=Yt^NEK??D84VSdtNmnZ8=$X=*MAGa^VdBBb\nIBnBl\#+KAe
5\BLKY B&BpP!jTtAuLPeAGa+Zi?i!LdAu&DA6lQLjR&W6n4KaAE<bcCdCAw\eeR9MN^Kwaw%wdmDLRYMW!unC5
dbu5!! =AuLuVHKb\A&GKQ+QdCAw\WeQiDwAaeEHBJ\nIBnBl!V=u14eR\AbVA!aZS8y/=F8XcKed\J>>w$^wT^
!+qwiT YRJ5M4b<V1>N5\QM?=StcS&MVedw:F^L9ju<eeZE:@5yS96?LjG+BDaIp%RDdDGYP&MqB%nAWRPP/8eS
JA5hnk DRuXnFG8Ka=Fi^9Se1F=8&K$N5W>wX+QeLK1BNlpnHK:FTNhA^b\#IBnBl!5c?4%@j\FtDCYG@ZBwH^=
^N%96B *H$=GKMcFeAGa:T*DY\^%nynQiDwQkcQ?#XJ%\wPnBNYTi>SC+T@&\hn6PeQdDE&k4bRVFC^SV1JwHRt
-AK:^# 0002131f52300110333 Page 117 of binaries1.zip
E#Q%Cq nPaMDc>TCB5=\Abn5\daaw#PP:ic/d!#anqSt:Y4TDbl&+SJ?tS5Mnaca^T@AmcM4aBnMehI#DGw%lA\
X=eV8& :>>cK!^HK/\H4e#k8^V*d1&T#\M&GKQ=KVDt1CZk1AFHDVlc\NECnl=\mN<:cja!CS5%\Bbn6P?mGM%n
@+BPBB Y=8$n+QV1=$^&p>y1FjAGP&uAB8M$Z+K5IBD8K>+u\panh?kZkG\Sjw*F@tK*1l8mtK$>/pa^a8B$V9H
DGn1F# Yh>PGPWbAS9MRjXpG1a9#EH:uK**SPNNMdI99hNbQMXwDhERL!tE$V!:aiwnlNE?CdDJHL$^l>BeRDFl
<?^D8t D5w@6jBpJw#!/^Vnib&ed*jd5e=?Z/hNbA<RX&GM+9hIbTJ:K5L?ZJBeT=mRQXB5MRi6j^H8LM^BiZmw
B+^Pj% >pZ#Jlq$nl+a#dMSX<tM$jmRWj#?pSwNuliQRnEQ^S4NSRiKn^FG=*wXE:JZmyHhHYXW=1B#kR%=XT\H
pww/D\ ^aeRwmY:1!5N$4<^J8pRnmNTY!d:=DHyuKcX^TF=b!EhWt\^B=%JWw^mBeAte%Bim&JCPnRt%bbD&S:T
/IICwd wVEyu$9hEeWQFF9pK&cn?lc\5Q!<S4t@m9Gau1$taa^<54w!Yy6PDBDC/E!%aw9dJ%SLV>%kwuZFHN#*
<#EZW: e%D>K<Wt>>Yk@ZnF/J\eM8qwn1+ae<^Mc#YWW!APZhI^S<*MRYj/FY8XPTm&4lnX<FPM>wYAeV@Q$bln
bMtT*^ 5l=MutjnuCF#WE=M\#qD+qmW#>CCe+cK5i<GdYXM?Hp6+GYjnFK5lFY1X/AaudqXnG4b+9kM&eVFhYIW
w=lyA+ /:T?ZJ#dnc!S#l!nMMia#EHuK^Tn9Y%kbK>\9WltnH\iauQE$inMLdDBHLW^S$9MRVtXmqG8KdDJHJRd
dkF?<K wBnd1>ZGaA/ii!8&tGPSnXk>pb>GiSDCF665%Wl?umyka+^5DpKSp#Cil!p&tIQuaaw6=8B=GGKq#MH#
cw6PQP 5CBY&8$MPtQi=uTpl!ZG@QnF$c@PHHR&CNlkD61Q:%c=nDFlDny@&aMc*S*d6e^B<ZGWXjP^qt:i%tN<
5BEHb> *4tnYBm%8XQ?FdBJdi=W*/KntFSmdDBH4<#SF*QR91SmhL+d&GTP!V4WF?6RZ/^DpqmHJLEPTYahp5I/
p8*HQ< JIX%mM<^K>bal/T^D9HbEYC5R!K5R#\Q/!ni+ZWwJ<19W$#<HyymXLMLtLjFKJHudVE\d+5:W9KJX@>Z
?6>t/l GS9Epcu?JLDFHJSuyFk4#EF=/!n4%=lDEuNRLR9F/E\e5MWehGc1=$##atCVPA469ZheG>IbI^8SpXBI
FyG#Xk GJ&bS>qB$m6el%+Ip<Ea%SWHN1k6jN/?+#L6#JmR9IQ&!+BN+lmqMRihIRe&tKNX=1B/t+yS#Rbp=jLa
+HDM4b GnKbk@cPP&4uM<eW=1C/:D&wy+>VP=$+b8b*#nWMWQKS@Ih/D*1@li5:>5LuISTnPtQAjA^Q5htbq>c@
W*S!@W \Ab^XK44y^nqwAFn&T4:S5Wte:B9SM%?=tDjYC4:Sy#ubA:&ndn>lDuaN=dK9lFq^ymDjYNy:B5L#@q:
n*B11T +bmC#mI1?e5!G*>*Wt$9aI9cMmu9T:FbCtPViXennpZ%QIAN+qm=F5aYeT\/j++!yJp=KPi#B@Z=P?4#
y4j+8R M$juedTE^=HP$bqn<Dlcp<jStn!PF5XGi8Y<aYBpu&8mjShXi11lm%SJ=tlW9%$^1tYlGPZ4ATPjl<Se
RyP!^L =yZFHJT9klq\bk:&bhkcI+:P91#&wK</?:Lc&belya$=&Jjl8Dl#5C@DHjDM\d+51H<QdDIH?#LW9=?M
FG=</N pc&4m@cAWN/Y^pjnuJmP*QNBYKZ=Y8Q:HBTnjW=km#twyubH5k6#$L$AmqE6c5Zw:C5\aa=XtGPS:8Kc
kQ5%1M FiLRCZSunHRZCVDEpTq*H^m6W%y8bF>c4@!PP8ZPKCa5L>heAed!>5u!em+VMJbZE554tiWX!q*61B9R
5%#ZnV Gb9MRVFB^TktCG\\B<WE4d\!e%BM5GQ#mVpwJ1kauVj68B9B9/Pi1L+A6q^>DK>nEXaaI=@epXlFYCWd
/tECn$ $ZMqu>\#%deF6ymD<5\Xw:1\\Cb#$B$iHSNw=1CedeWw=\Ra?iSiiK#&R4WJXInE:bQCjTCWp/>aw*Y!
kPRm$d a8S@8>B>J+wJ#iWXt<^B=*AXt+p=1A/>a15!^!K:&\j6d!qG5XJkbHjXqJDh:aQP8AMV=tmFPhymn5:9
Gy6#!@ epltD1yBnB9%TIeEXb$I+:t<il/!PeJ%@PG=!iawSnbHC8ZSAq9MWV6#$L%y\Cb#$N/ha4S9Cp!ak@bN
WwMjPK kT*ttJ$=1I+TMLJlRi%n^VnYLCN*^m4FStR$quh$quh$queI!#8E=S&D=iZ:awC^9IQP6GL+$n\MS%cI
$9JQly a&d!C+yS4E>t/e^BPYnABuP\DXN5MRjdMNV>bR/&acn:P\tnZEtaE4I9w%Ai9GIeK>WbDjt<WZphmyw%
\:=M?9 mVBil!yGQt>WZweP4wWJdDIH4$NH=ZZw+JwNMJ&FPZkhPm19R\jZ:RbG<:XS1V=%H%!:A%hBeF5t^&mS
tFwc8% k%EbY<#BMhw^PWc4GP9G+lm6#tLJ6k?8i/qaIh?n&GKP&ytDa*NnNi:V%T6#$HpZaMIeXLjS46hkn6ta
w=E#qe k&yVATN@BDQWGcQ+$E!Wd+FhweRa?^/hAhN?!t!<J#h%/BjGjF=Xu%#dASm*ti56+cwQtn@n?k@m/D^@
%Eh>&? %yXRak/iQ<@P<&jFFuQ\@Hq!DYJeSWK?DCXT1C&Vc4kwSnY@khH?&$T!l5eY*cWBnPbZPqSy@$$b!E<4
jB^HP9 J5^Bb$L5ClVtcK\91:P?4M:/51kP8GI<64VJbF@WSFAeiHFhCMWwu^Aa&W=eRidd5qD=mDDKki!Lc?<A
yZ\@C& w#uN+u6pkhGebnZi4%mN:t\CSuPc%ckPkYKWK\SMtIQ8u\dGjhYwN1SmpytD:q#DqVTXPclGh$e>e?ck
!l/H/6 *E6kNKhBCJp+Py%yAEc?eYFuk:HFHFR:S4GYtaQuVc9*^l^WF\!aMAjHl%aRH%yBjGkF<cEX^IhYEB>c
eKFuph RZ^wBjGlFeTHXlAjYpF<cAZ^wSZEl%aRH%yBjGkF<cEX^IhYEB>cRnqnHh5L#LF+uI@E+*#\@6Ectej=
EX=MeE KD#PS?F^Qm1Q<>F+uI@G+*^$H8in<#nuinLRFl:ua@A+H=QHPh>ywSnqnKH1Q89RVK^DM:MP#eI/NA94
aHncLW $K!5R*#QlYKh^@V5QKdu+L/jk@6?#pCP^ZKw1lEHu<6Z4LAP1b5lDn+VnLIcQKaZ4^5Xa^8:Ay?*Ay?*
deHEMa KFa966>BGPY/mN*cVlnFZ<S8=&X5MkjNkZHD5DAH&XlkkS\#pGP^HDt^HH^*ytKF=elWA$I^14iyGI%y
FqIlb8 aJM=1Ba/5MEeXIjF!1aRS/F/RVlC%ImnWE$E^in?I$qe^\8qYSJ#WH\I&GIP&4<ENymDcpAkR$/Iw&dY
k\BFAF 1%ya4&yq9c1N>c4TZEyRIww=/K=c5WwalNH/HNkpnpc%TwAJeVV!*Tl*$+mnWa%R^ZyqDnw:J+uQ#wth
Qd>%5d >mCM<pAFKctX5Wpe9cVBtBBH4##Pi?N^*n8Q<!+<#99keh+un*QM!D$tmee=mkMSqqt9yLBiTYY>p5b/
j&%M?Z Ja*%TwV%TwV%Tmd4qW#YK%t5X!P^Zw*MinWK/=WPD?IanjX1hNc4Ic^Za:BineF/NSd4%Xm5X#P^Z5*M
FMA?pR inWL/^Zj!cXaa:&cujX1C89XHK^Ze:Bi#eq/leY>^%bm9X1b>a49@pdGMjjyw9\NNamW$!c+=pIIw>y6
NH1CS? 1F:ua$9AjG^J%K$&iq/nP#!ADiJw6C<JdDEHucZF%b/bPik54YJ$dpe^Pp5LnQ8qWh+l5MWeqHiI$9Tb
aKW$HQ PTn9ENiS<n91qHeIVImDe@KBVick9ENp1GjtwL^DXGcy#EF=l+yS*1FmqHeIdDIH:XW1SutH\IR+PCej
W5Auw$ &CIP#5qZnHL!kR*twJ^<^TkuH=k\B?ZpA=9MRVu=1LcitYMM=1C>J:ELlkldQM=H+uE?Ew>#48P1YPF^
CmFYGy Qk1Q<%F=uI@K+*\$H8in<#nZhVh#CI@#MZme<@/=ayQH8c/:tYQ^PJ?J^@qMQM=u=uE?C+@#YZme<=&u
*<YLyB 64$@CKM>aeX+#y<u=T\K!le#^/4M\ZN?ZKmWGcM=j%+<=<?4$q\kL=:#K:cak?j<mk*tGC#HGwEeFD>F
IQ+NW* ^Xcc$=SEh$awS9jVKWb:e5BInyLwLmFkk#pwZ1ea^i5Ww*kh5MpeK#EH%TyYK=qwVX\!=iw1SnEn^Tlt
iW*8G& yBnhk+y1Z=p=1Ea*$qATe<#CHBR#\p&T6CbYnPdKyXB>B5WwbmS&KSJlFDNChFiaR%m9!tC>KyQ%1qDM
IXG=b1 CGp*qVpY!%EV!%E#!%EL!%E4!%Ed!%E=bqT15B!Xa$cqe5^IY<Lnw*LMCPeNmKN^#Kk$14YBTmW$=!><
Ei!$wA hqk^nlpX48&Qm4KbPVltlJRu=ymBHI9q/IuqRMInaaZqRGFm\l4Lka^M\mmHBhlmD5wyApc^4!KW<\/M
yH%?PJ aq>FKI>dMe4nX1#!?NAqHZM$Hl@TiZ!I<QmR\iND&H<WCj#HCQ#HCQ#H!C!HL4E#a!^H5LdH^XDM\Y9:
=!>pW# MwVqCNd&PqMP=PC%9bw\H8jB&4:M\8M<YN5Z*uNRnNj&ljeeeF5dn\@ie=DCh@SJ+V$HKT9^?PA>B&A<
b*B?!V QunQASmQD>=#AMdnk@eepLLI+&MF@tP^@/nBukQK>uVCiM<Bq\+6\unQwRb:D81m!Cin!L+RS4ZkBAZZ
W?&5i4 J&M$q+iLKwV%#M?n?^IWw=4Lmw*EHEPak&y%Ay9MRjh4wFI^4hulXwqDy<YNMX1#X%ln\tylnn1bw#Zt
GE5DF@ /Q!PyA6#WF%:5iLqlI*PHFRjE>lkD44HV11?w5Ia4ht4L48FMX1#/@TqM$jN#FEHe%D>i&CLPin8B5Yp
i4dah@ MIhM=1Bc<w4S&Tykk#tw^l5\Y4QZTZePKWdulIHStq&%m6d5hhLhDeCEPS1Q<>q+uM@P+*\Kn@MyQM:u
HLqBK^ +HE?J+@#PZtew\ASa##PX?J^9nKQe::*T#HK9^e49p%aI=>TpZlDGPX6Kpc=baI\MHM5Yq8%SDph\Gm8
GtTW@X $lLqhCC/S4+SX?a\B?X$CELT#NELe>Ah1w1NRI+b!DFbnp#*c\CnPShK4SFHyu1dm6ZCHHSPVnE/H\BM
KQdnR5 tIQP4!4G5cCGABFlHA61li4>K<c^wMb*XCqGb&wElbmbk*LyBKXJtaQ8tlcWnYIP!5>YdLFi1SpmD4/Z
&td$+Y R4HCi5Z%9lVn@h>Yij?*Xh:@Shwle@D?d/8<@>51:@?&^98@m4FiNh:@SRFn+tm<@/8#A>a44yY6GP@@
$@F$=u N4/@FlXCYc<c:@?&#98@4YjY1==b4@leNDDY1>=a4*yu9eJyGeIG/%Yj4Fh>5X=Jau5qti&X<BwS^>tJ
J9YuZQ R^4dK?E%I5/SMki9EZGPqDq+@:h^VmA\%19Bc$RhMc^Zw:Aew:Aew:IePpXmnn/bR^y#<Q/9FR+qnQh@
8b86+k WZicPCd9@?Lcb8KalejH4D\?b8Q^MV8Qn!p<Q1d\?FC*\B\#pCQ\H<FiRk9&EuRG^?<n&E6w\X+Cmm4/
GcNwlC #/GIl9>e4^^d/u!uLVDTTh#hXRnn9Yk4mpAa^#6:=dpnmllRY^4qdTyYcE*TG<jYeSm?Eeb#&>/w=y+/
G*N9KK H5=X\<Fn@q\nQ/M>RHN$HA1t98>W:%Y^^Y&S#H$9QCj5tPpR%tt>cke\CiP>%M=*%ppjuEiBNHQ1k>Fa
BSDpE^ J@u<4&JW^$b\aI%$cQAidy>W8%\^ny9lwBK%L%kL>eq:SVnIR6@XKV@%\cJ:KAYHL8kh4e=/9+L*\VXt
IV8+6e eEML^Tkp$bp+RiIla$*+iS^dRwIVa+654LyjppP+lwEk<adcputQD\pIm#A/Z!da5CZiR8hDBS6tnQH<
-A?@Wd 00070a4a04e00110333 Page 118 of binaries1.zip
*:/X*G FB5d@Dt1<!pIT9QuJ4i9eQ/pXK4Zy^mhw%KM@VTCiMSSic@Zkk?ELjIX8wCnYAaYJhR94VJHw:NckppT
wC+MFc a^\4pMb^Qite4!J<ypdkLKnNZCMF%\?!V9I>!#nyRd=CpE%HGPebwjQ=e=\DCbDpCPcE\4Wh>GQ5i*TK
bCY&Ck !iNn<H+Q#5^Vt\jua<wap#HP*bLJiba+8$:!B9M\HI6lVILQ<j^A=8T^5BK@n^YMe/::m/5McF/mW?@C
CD/jS5 GP<d+Cwe*^cEXIW\u19kiA>nXGhd5W=4K%WD<n&+c64Lm!6n/Zp=$>lHiJe^#8phti$jWt8ba:K<te>\
@IG<$j /DKF?$B6MYM<j<HhDj\=81eB%$m\9IZ#=uD9J4Y9<6kc6ZIjXF=D/BB5@Dui!^><ulM*DJP9HX\HZAcj
<IL*Xj 9$T=DJwD+@kYa&M!L/?^eY$+>WGu?<5W1<F*1ea?!uVRtukE?$Kne+:DEN=@k\qnLGkLX9!EWV%c^RdN
&QHER= 9ae8@Wm9ku&TwayQHIN6D4al/F&1eQTPB6X:MQNM<5:A=p!/n^puFA6nXPMe*wlqt:!*mNwP@N*F?4h+
aZ%+C+ n*REPh5DSjEJ/:T*w%N?tkPnhwLuuZ!jPp+YhQ+e:=QMSLZcWbYJ=5YV/<MJ411k#^Y1B\DM/^YmPb=D
Q#+d5! 5id>Kp=>Qw?FjIX6Q9Vy<jd?@h*n1%@<+6WuZ>@@::8V#8d11$<?@@D8+cRWy>?jZu*!?+iHJ<W^^P**
YRBA4k ##@:$!>8:*B4<J!*6!Y%%&?LVt*i4Zj6#i9<:8=6i9j8q:?R?jcN4N9ZP1>HADT@L8NNHZh*+?*Aebm:
Y/$c!X Z@:u1%@?<6ZHy>9Hy:<@*4%:BehS^/6@@Mhj@?+*4$D><Q1@6FuK>?un*i*V@ePH#&/j:p+@??!@1=hA
iLy::W n!bp84Z/<%ijjQZ+<QcHN*iQy=@>8R:S@^6@X9F?lS>9<PMSQ^:\+#X?*PLHE*/e<PM#@LnHn+?ZQ@#=
C4F548 qRH9L#@8L5?^:%V<8MGQlB@=<wh*F/4n\*>?>i<Zmk@+<jd!wd<b4a4\#j*Vi^Z8@5QV+<QN/+iH9@:<
!ChE?d Yi+Hqiw*n:jj*Z%=?%iX5N@$t@JF#4j/>!<j*kbhw1:&=>1#y%h*H>/mC$9BiD=/<=uy<\>9:@/8D@u5
au*<9T :8QV/W?udNEPjd&j@Mej@un/<MQ:>!ie*dB@@Kh?//9d^:5QykW9Y9HX+>&QJ%R6j9:>$+ej>AQy6HGj
t^kp>\ Q*/<Tj9M$H@>=9=SihXh6ii9j*GL*<>6@j*&ENPPhM1uX/c%1YC#V1j\P9X+>?wj=PWQc6C*VD6:FtIj
**tF5k L*?q9ZJ>%E9MN?NS/jI@n=WZH:>lNjle4eF*J&M>\J:nND9YA$\CdASa^BHI$RI=Yk/\wH$6pQe=b4Sn
?9HTRA kS\6pKMFe4SAnldI$RM=imBHD?VwkS\>pKMHe9SAnl:IMaK&%IBDAnpp?K+Eepkkl$RekS\T!CGBHBK<
mlSHpW D\ui^\npGMH#i9VhRI+S!DECPWak^+k+k9/dEWek:\#i^+!iF<k^k:dMwK>tIMeM?t<G:X9S=+K?YwEe
Q!:wAi K=BnBZK5wK>Y^MF!9NTJ&V<Z>MFc\ZhVkPWAK\EY>M8c\ih/kAX!qKk6LeACPZL\*S#IpRM=ek&\kDeH
MLE<TS e8SAnn\CLPmZHMlSw9edjLeEeySAnlLIWRI=Ay@*Epjc5ck6kS!BQ/<%iF:ky&9k>&6k&&8N=An/4$Y/
:y*>FL F5kd?QMc?QMc?QMc?QMc?QMc?QMc?QQcwn+N?n:\=:XH9IG<kV?9kV?9kW?8\j!kB9/<>1l>X*%k5>yn
yX*n$W %4uqX9:@4Kh5Ju%i@9\@4//Y%Nj>N4&i:%J@Lc@j9u*>=1:*hq9i%94tVYt$8pLCZZ>iZj$jWE5DBBRA
>qmSQb AkAIAPSXdTWGmacAI5+FAGK6CkA:AAAAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&S9a*M9WEhR
>ay9ZR RYS6cY=ye*S!aZS9euNHhYqpbT=\bGd5@ZhaW$9ZQw/HpkAlwacPGKwp6HRCAkaTik8>a?m>w&KuT=e8
>+^pmV aKN*AYpmI6JFRASESEYpm+kK&LCiL*mPQ1h\Z5>=*9iQ*@Y:Qu4Nb8@b?>/#b5&cqd*Z*H6Gpp4SppQL
CF&6hQ a/CTe@N*:pLBcDkKH8D5DXXSkWMX#A<H85EX1E+idq5HXKhkN@>RPJ1\haZy%4GyY$nAkYAZ6^A+G96d
D:@X>X FnuAQ*V4t1$e#Qie+IBAnaA\8B$en+M4w8F+9PLYH!Y+A^!1ykcH89t:dliG?Z&lqK&L$h@kC6a&6uD@
!T9\#G A:/?eD^Y/hihQ?K\Q<QlMKmheLmj+dBK&J%\?N@n!MF8V1FiAj+Wy%A*8DSFGc&pSETn$Sk$Dp*EalBd
LNyQM< Ck5PeD*k+laMq:dHKlK&p1I>CwXT*>/+dG?C6#eB&^9u:a*V>mb$i\Qj*qC&N%:dt=AjJ?!l*#J<j&#e
BFHpSE j6#uG\c:9bHj*1C&N?kjJ>^@FQYjm?&lXn?K<N@i8Q/+/NC*a4i1aP+X/46XPdKb5d^#RIAQ+4hcB&#X
DapJ9P TT9a!e@N$Mqu1*=+id\<^kCNh6w/d^nk8wNCqLBa^P<XTjlbA@^u<<eYWQ^9keV@AH<#c&6nb&<*q%C+
N1CcYD k6pB=>B9Pdy?&=c8aLSX5i$DNF#B!55%%BNP\MEXhN!<QD^D+SkMZEHDK#TE/lbMD9ALDQDj:lLEd/d9
!pVMK/ G^B5F8np+kbZ?qWpA#h@n>@AYq/?wX6/WnC\6cK+8RT+85G*JR5J*hKqH^Re#yJQJW4\RytmNb!wLc/E
DKKd!F Zi^^FGeVa4GqHF?Tqw6J!<JB%h&yP1/tTlLblu5!>h^M4:w&P!npGLmdKSWjwaiC6&4+&/%?1/9Td*Y%
ER+8>T &=JL%>@XLe#NFc=AeV9w=iJt11$B^?D^eLVm4^*W+V5Gnj4*C5J<X^Acl@&lIVRG6%Z5Dn4/9a4R/D@w
Za%:Ch CIhFKj=WT\AAHABkBnHTS+T9@WqLty&AHH=GGC8IRd%nLb\m\j$uLW$+\5A^pdQl@b+ECB8XZDC#Gc+l
ND/X1X ^6uubh:1SnnQ^<XC/ZIm=y8CiMC>+RM#KN6hjKDiidyp6h5indb8hP1y\/XTkqDTQC&P+p<WVnpXCylb
8>++Xw 6teXAh^5#G*tk=:1eZdn/Mk^Q^+AP#*dR<@CLMLP^@G<1YPhI$FL@LTj514WGZ+hmWi*KC&y@DtM>A#^
+8qE&T SZqRkLLSup!\yB#9&iM*+kjB#peQW/5\eHaNVceYZ+JeVcLiawTNc$VC/5GnyyNlBp$>FhtDJ8q$kBaH
u+CSSq aadEea/b^l5ht<ieRR#R6l+Z5Btyp<=@9QwDCT4wmIFWlR%lp!EpLYpFGp&biY>kppT*tI9P$JXp59XI
mh=ByL cZKphGk?p:+5A?iXDk:bK<qFkhNj&MDLe!!W6ASMLl5=d%1b4cmBk#utNP$qj%e\JDyd4L6n+<yy<mT5
M>ymI& NBd=5IYuAy%b*MDPMDi6h44:a=/w1nh#+QSACC6@Hq5Q@VRy%aAW#lE#MGQLw^PTJJYW#CmMKkN%MlQ#
iiVFyp tX\qi9hX8EwdpDtiw@^*qa8PeklS8VIkqFMhudBXVqicek&VM#jpT%y^aJ\a=&yLtA/ZcF!8$q+>/kRy
yQ\nwi ubI*IlJnVA9YKT!R>LQdJ^1ZBL!i<iklKKcuRLknMhQ:HPBWN/ynNBai*M4H^X\A&\5m>+@n8a4LH?y#
yQ1<6A LZV+C/ZN4dY^a\MD/*m=^iy=TFLFw:KGy%&PmVHELaS+A/P>e1cN8I8iEc=E>/!4VVDT$plWtJlu:Nh!
L&LSlT Pp>BZylGIw8=bH?LqEq$4$VnYDyDc/9yEHMFDJ$RXRwR!P^Xw5dGT84p5$iNjG\Xnad\JJ*KI4NaYmy&
SQ6RcD AcKqc1Mm5!&n/=DVlmt$ae9aPDwPWJ9yK!h:cdCJtQ6ieAS1\K4j1c:XYmb<^4<:ZDNJwTm!N=M4t%tW
ZL=#%= PjB6XiFXaZuuJF8p#bQFA6ktIFQnw\tm1GNCu<d+\B6RKAcAWJnEYnh*Ab%jADS=P%Ej:hyFq?9b!pW>
kj\i!? +YZ$#8iBSbpha^JCIMAHJ<eWaQhMLwN?EJj>ZIRAymcm<DpM!pelACTTZV+/\kFPD9I%DCWQ?ERLT?bK
1HVeYV dWum6I9:YS<HZ+D!qVmt:A>mV6ZmmQCQnCRtwqPqJbF8C%4\6JXu>y4Xm^<mupR*BW5R8PHi4Y#l!Snu
54aDL5 ZYe&uZ!T^%uCA!X+&Yt!$FP8=Wt<Kcla\R#ujA4:^dFI%8HY%&LP\lYu%N&V%DtMbAynNupDAZLYkB:?
lB5kYS 5wX+P4lqKHlPkTT/YSFQZW&K/dBTDX@Z+k&mwtQ*c4Pnn5Y4>clSNS@TT>E#X!VFMi6%EG%<kYEG+THN
BP^LRW AC%>ADS@QAeRlBpKu^IWW*>VEae4bb=LQ\w5lI@Gw=W:GA4T^hVS<lGN>Gl^yBM#+Qw/K=PEb/>\GNJJ
/9+J&u Mm!Np@iM5//*FBi#i5?G4hn<4D$9AMyCF<@IEn%=pe=WSaGu<^B@ZH^AWq@199lIDLhI4n1#W>$a8I#b
l#X*AY 9GeTIWBSI@hE$>@w^BZJ\V%ypC!\F4&KtDR>XW1RlPQQI=+=$aMl*%4P%F@kmI@Wp6cM+JBCF@MQ=4u&
m8$/k? /%V%9PPPBHP^GR>dI<VM^dwE%GHI<?byTpCtSBTIne=iMVJ!tn$tTXc5k&e?9IQEAaYHua5^eDjPl*^N
<CmmaQ tKul+uk#5*jGWIY:R=FJ\%YIyT?JJec/qi^1:^+?RyTJHJLEPbh:<K/=a#6FYWFhtNBMnwQRbThDKVT1
NXQkcL El\C+>Qkl=/QdLcKhI1WjtVV#$huLXKM/5AlWKPT<Eqt1HkSn+EJLDdGRB$&E!qNtmGKq8hqRJWJqGY/
BL:ZaT DWnGbMYypW1!B4HEBBm&=^!k$c/9TAnl#MFGN\Itl%QQ$BnMXRSHVj8N\\>E>B4R8wQ=*?VFCeQkCdue
IWYPqc hCd!wQBL1Fq$9pKpNZ&BikB:SH<&k^MeByBNRa>%KKZZRiTjLw5\T8*!k9w\!!dRGKVFXPJPle6*$PpE
99WTmL i$W\M>F^TeDC+WRGb!wV@d1bVpZ1Sdq=Dy@WYX:P<uX%84LQa<tS$\1&N9#M4EVR9nE^JDe/IJeml+??
XB/e6c Q$Clu%Fk!d@cR8B+KX&n4p>uAc?Iu*Wph@E\$$X&*muCPA8/heVYW!a=:+WVtiQDaWKaGY=k*Sk$%6P^
?ApSS= mqKNk^ckPPlEBBlyJL>VB++\cPA5$RAA/TJNYy<^ZMT1I>VjYe^hp^#&YG=FJ!tt1+ZB=:1yZK?BE^*y
hy#wRK uK#ePwSVw><+9p8MWWNcQld\dB>5>4I<*XpX$SuN$+lV%ddpB\F5IdKJnDIqKV4=9Vhh\8DMw<%p5p+S
kJV^?G l@m^BBcGm@w%/\ce=QA4<Vd8=A=yR>Z\\<=y#8/k&9\1BwqJi=inGkc>1Yj=SV%bbmNNbd1qi%kad+9A
pBijIZ S\:lp$kQP/Nkb+C8D/*wBpPqdDah5>en>88$P#Lp#CTBku!&hGwytNiSEB%I1I%NM?:VNMDEyw6BWG<1
I?w*Eq L<jpB%:QN$B*1#YK=XZBij*$yDdT?ED5!@qQ^uKIhdRVamTwjHmHIw*6GW:auRVqNkSdwhVnYV\+uQth
KCe%Kl Dq:wwMtk+TdmYTn1Hya\4RRcmyidC\Wqn$j^Jc<t4PR4HRB:DmGh*=SE\\?EJwVSQPhV+^pt&@in9V#w
eyXh4A ZXRl+KqYK*W/I$+#PDi>/bpI<!+WI6>$pRe>cA&WSVEhE\@MWI<X$k<LQ?9cw1NP5$yMpm/:Te95num9
8RE$dL nDTkD54NM\btAF\m\8j&PSi:Pq1n#!uFqbQ&9F<X#^!>LW<a%ReDA*j^P8HCGB>:mDqyG+h*ZMnWC$5A
eKt!kK T4cbWnRpPCS%lAeYbY1#$MNthLQ1VJI=LCZ?9J4tq%iV#+*u9c!jSqjQwkB8wXw=KS>bamZ5WjuHcwC9
-A^kZY 000da132b6200110333 Page 119 of binaries1.zip
!EyGQ< /=Xb\=1qNGVFiEd1/NJF>ZhJ6t6\1w941+hYI=##R:LZE$\@wwR6a*IPTB$@@n\m8D%N<wLmlNuc??9>
:paVHY \n&T1AQbc<bPVed5t&+1Xnq4ByA?AX:YX*G:*4iHG$bV5$khkB#IlC9*tX8^8<:!e:QPbly1lM8^KR89
lV<%Sn 96>Zk:1XR=IAB4J*b1<m\5ikG6PCuX$ubw6L:tRn@Fa!/B+?$JCkl:i^DLjK!hlu5BmIhXRHhNkKFI:^
?Y1#aZ 4ib##+/L1XNpC1bK^XB$/t*QcP@y8pRAueJe+bG+mAG=NZt^jC*h&*MGDHWe#$HeV4+b#4dR<Dt4t/Gw
h&99K% X<JIt45\\Q8y5!qLlAl#Pc>pPB\aYIm1e@</=<&#l%l#CR&M#GcRA6C9LHmFM<eC&1dw=Zi>/mu8XAM\
4ZpE&* GanG?AJ<Q@d4GnDQ&6QFlTECc#:Sw^mhytV!L#J&uiPlT@*R/Vpa!e<TTbKGm!A/hATY/#%uIaKn$8#l
F<k@Vn AD+^PA9ktCBe8KTn9XwM#S=RL$:HjIyE=PX\@nVQAX%aShKPChIaJjNy/9uKaHEaV<EIdPnk^>tBZcLn
Q%Za\/ pl*iREC/CEBaQh?YM:Wc/RVle9cFy4/WmiD+bY/IMYL81qM!N:$\W:/nc9lb?mBlkHw\9^MPaMR5ByAG
ZNF5^y m4dBb6maScXX\\WuuiWd=QpSJFIEtnVIIm<ATSL6!Jtaj*l^AeBP=*8%pB<p?<caX5MwJk?kkLthplA$
lBbPQY eC6eYbRm^Zaymb8&Cat$byV5q?twh\/9yM<@ISpS/MtWi6nbFSL#FSTMR?Wj$T^5Ecl4p?%eFJ9yETbL
=Z9K:j kic>tb%MmZSTjAZbayRYljk+5aIVTKi&c&Ka^\99\A\u?J/DGD9VSj!wwnRII*$4T<pELpKK@ha18#bK
H6?j%j DP=jAN:HI!bG:!TSAbqElBiG#iV>$mMqKN=Bk:@dEKQYS&+!iE%1\CjTb?p=qyCeKTLTwpI<G1c<ut95
Z=K1IA 1B!y<PKm\Ze9GR!kZGNItlEZmW/+AQ+LnS>&?cWeILYu5JR@aqtMhIN@DCA/k=CDG?En#*F&6iaWlWQb
khM/I+ E%SE#WXL&%ZnWLmCE$pbGt!Fam\S\4N#dR6mIuMpI^d/Iei8CQGFBTmhj*Y+kbCa?hbnakHAXwnt1?Hp
dyl*Z8 ##&eLSBy#$t#qCtkQcM*y+<\+Ha/5le8IqPhy\duPpPZI#yEcIWVPhebbV56>ma!C#!DiNJH<4J=e5?+
51EK1w <@ba!ubR9EXJJL1bM*R4wp@nN5ZCtVQkewBdZAw%\6:6w9p6QN&VVMaHlhVnSihGTZQlINB#hihTpWJd
6YRP$L R%1h!\bXR\=i*HtEuh/YNV#+iEeKqHcMN%1eEm=AJ#/4CVBWL+TDPtKauTN=StjpJGR>b>Y8cIm\T4T!
ZJ?#ca hmRB=MjqeDwM+ajX#jqDb%w4d1cyFw=X^hNk+@tm?d=CEVRtWZY%N=C\GSH@@G!=&i#E@BTaFD?V?k6=
9!P4Hy lu16$lS?/EACA^P18$FjjF4NjAqJ/&EJhliqHiFp?Tlw$CHHtETn+=49$haiGeENA?St&+R$yJu!+SFM
H>9pyI jV^abeSCJR$\>LJ:AedW<$XKtp=<JhYyJp#DEVAD9ldb^9q1ic@ERKI^#nuDum=mmlI^+#41\DEuVW@K
dYcdC9 d+Z#5*dReK+4NL4$ZR6$TtbkTkTMj+kjR5KT!4nA<5+K+Sh%uahTJYwE^ii+yEQy+lQT81mMDjp<VkCS
WGd8^# GS$yAATR/h<*I%Ji%JniNe*h8YbEmk:1yB%&Laa14CKh#8&Gh%\$F?aTFapeWC5YG?GJq?ein%Q5@/B9
tbYuEm IcltED5eZe5%PmA/w!XRF<kR#k6\HlFP+tietXL5=H$hLpB@aKa4HMN^?TC@1AEL5>ni4A$&cXpttlwj
^wtH\n h#%c@VbT%BJp^w5&jMMRIh!nKek:i/!+eF1R#uM*+BhuiwH>w9d1?j^$*uGIGi=>^1n<Im%Rl#qhiGm@
?tTimb qD>kbt\Z^$Sh?JCR/AyQZb<<LbIXVwmdIdIMplADP5YhhTXmI/^J=5A=Ije=b!+cB%@?WGiEyRB<TWk$
V1nbZ4 G=LqT$@#labZA%&FaLNVnDlH1aEWGl&kb:/PtXiKwThepnA6t4<tLD4HbZK\4CPh%WtC9*NGlQWqM=$w
6+99DR !q&R6TPS#i>4RXey>#5%5a=CXh1q\+1PkFqH9wknk4#XNMAd6pN%klF4@LRYGEpay6nBHP:p%!WLqhhB
Fj:1/p $nI@$y>SASDBHL8CwtCeJI^\?Aw5Iy1?p:+#5lScWA?BicJFk&G^AKE:$^4laW#1>8ipC\:QainDV+AL
%Fk*yq ikSFnZcdTA6&Dklpk^ChW4YGlpL$GB:JKJp\kYkcDNaHwL?HEy6^=8qESF9^uiCuwVy$\e9i+e/8aHWE
>G@!kb Nm5k?yDnduiAIIBDLJ>CS:6+iDLMjSatJAWR8P5nVdIE\caM\q\TuH*yE$1SVmtnpda<w5YQ=d:E9Zip
SAQp:9 n$mk$VHIEqw=u%4bEn8VuiHRP=Qe6GHS@AIW:dJ5q&SC#l11<\!P9abZ\^Vk<+cX*mm^=eHlYZdFBNVh
FTCyG= eDbGYpK9Snn49V&yLSQ$VyM#1FTl/mStPk1Ye6Gp=ZZGQFmE4=K^+=++mR&R&5\Reen#qXt/%RXPE:De
!!Eajn DBYjEi=P5l%YepmPkH$wuBcAe\FtHuAZ^8!yFekWTJImTd9RV@QQD6E:mWy$pR?*<J$lCmSyu?A6/GE$
wnwluJ l#PEB!@cXKVVH1jjw9FH8DLBqjeXPAnha<u=MCubKeYj:@u^Fw1QBGcFu&MwKFE+jCPh%4Hddd15<&/c
/qL?QT E%!I669<\@8+tc?kAkDIKe1eulech@S<1\Rc5Ma*1<a6aJj@EZ@?!J/mInAe9pQkBw*?B=Ed+y<nN:?L
uyiP>a uu+Q1GCXCD?Ny$AwHNKe@eNRIEemQh%l+VJ/:LpiS6MiMWa9Dk%RpVyk!qtJn$&L1q+ecE5RbGNpEyiF
V+6RT1 *&at>laZ$pYQ1E6uce$ZCVD*$\ke@Lj4Ik=LQKIZE=wF<w<H?m4^5<cKi<H:HbC<TXyp>AF/G@pek/15
a$n?Bw !$qkH@\qK&u8k9JJZ@utP<5+qAZ5IadD%P5kl*uKBK+K\5RltnQqL<?9nSR@&u5Mb5WlXMB:8FGR<\TH
u%=8L\ %p1*Eu?+y&I1NIBH\KDGFu\t58LM\\98&1yhpMD=I+A44A&%Zt<q^Ew+p4ASeiC<6NTJw+T<>dAQEVXT
mBQ!>+ 4dkIH9qe*Sy4Hn!Tj^b+Yb&WRwWqcqp:1VN%KeEEwKWbReXLwW4k+/Dh^Q#qACW?$Q:LPmP?MDauuXap
nW1e*e m$EP1dyTjeAh!S^Hww1uFPu$a&LE<5eVJR*!udP\hDtBX?1MEyb=K&Y=w%@RGe%eAkQL%/mdMRWhVkAX
PtPlnn $R=@GFRBa1@aX=BQXXRS#jHtn/F4QAIDnyc:\pAeMPbw=p9L5QD\uR#lD=F6cuCAm=qdKN\P4pCqcMEX
NqcHmk #N*CRu<L^yF@?/8:Hi=W$A4\D+X9t+EYFw:GjdPV:Td@EeudQ4Wh%@#XlL=F<L:F@Z/:VDM5XN55hD6/
^m$#jq 8*&l6lpcn5d@=?#9\ujdy<qdy*?LhJLNeN<ni66Z@m:1m5d>hVnlt=DR@\RX6*QSY^t@SlY*JN<T^H@L
9@*Gew ZL*<QiBaFQE*e%jReAy^?\bX$HH#QikY/8Zm>Mim<H<6/n<X&myQHi:8=B8!9Y6M@dG4a::h9>!hD9mG
M?aLT% @9F8lJ*HRWK&n9T>ZEN?SJ:S9?wA??5j@K?b?F@HTBS@QXL/>S\c<?5\CS4*&#EB@%6Q@1deA>6nK/n@
jFjTNE nLNkCL>i>kiyjlj?@6G>%e*I84yE@G>h@L5HWFLC@KG:m&:>R&\qE:TwPNXiTedeWN>HXFSMY$@e$tY9
tSMY?u LaytJYpqK84nL!Xnb:Ljp?lmL85yV$A4acZ\*qKYi>Wh9i!laC\F1ZNAZ5qi\WD%kF8AChEQ:?lMDJCR
RqSmAR X!j4+MniSF<NdTqT5HhImJcp8b4^Zt&E&D+6yKh$kI/65dEdKRmNqwPC6YS6hQ!wnmR>JTMFc\8WycKa
CaeuPl tKEhJSA9S9QhJ$Hb&1ka$Q!q>46/Yyy+KdyLKnk18p5h\J6+Yy4KW4e&?=&kaB<nmwTQQ>KhS9BHiwl4
m*qum< lSC6=EV@%RaK@9ia@*iL@*iL@>?>^Rt%uZ=CmQ@eX^BSj@AXi5yGKDHhWCSN*$RtFKH9nJL$^hq1illn
uqnLHl 4SW\Ny:/bul^lM/?A*5M#bD/i/Y*JJD%D:VH&mC>VQeyIYl+jR6^KNnYmiC6c1NNC9Y!II1y?=A5HDWq
8a:+\b bCRR&lSXDV$:Da1C6nuCSN>WP!A+GBQkH&TnH&kd8E@cTG!4!&8/PIRcBLqA\jb16mTEibCbk9XidV?>
PCDM@1 RFHS+GAXKVedD!#KLWl:4+i69J1b6!@XWm4a$tYjdRDJ$qF9j<AinSBdJMq\4^wB=:*qdtSC>HAilwb8
:aKPM& !9KYF1L/PI>RS\iLAGtE9ZuRARpNL^hZXJC!qYGk6I\+R6:b&hJZVn9ISp/Y4P>A>9H&<k\YXXPBkq&S
YJdtAh =na/?$$emjwcQ98Jd8KtqFCek4KZ?l=4h@9>@u/8Gn4!jnKBB1b8bBXSY\e^QNHC>wDGkV%!@lL/9411
mJEp^y ^GA>KHm@GnbR!q<LH?SG<%XSN6APXDY&5beI>4K!6@NWS\VaacRJ?wy841/TBmEGapmhjhK1llnTHwR$
\T^nHw k8R8m>D#^56A\icY<mEpKqLPIqVcWFe9!F1j1L>*n#bX$p%h#F#D^h6Eq8#6n*S^JJkcK?tmJV$%$Jd:
K?AHjq SK*FjM&ejBZ*tcu1IQhA\Tk>VZ?KSIkEBaZXWELIT8CW4PZ&+4Bi?@DYm1b1+w1mIcFKuyLt/p+aF^^b
FEl+bX S5YTVNnn1^5k/?Sqcc&N6QXEGEQBF8bw6RBuh@?>?>%Jbu=KuyaT=pR:S!M41l%bM6RWm^aQQiDn=auV
wTRWak qcdlMBnEj1TKt:F5AMuR%WqLnW#Fl>w=R<FG:91!dkRLR=!ulLtT9\TNG8Bl:+5m/P=%Dk*C+&W6XG$C
VyReN1 9RI\ytTFRIwl#T^$4:G:w*KAqJc89wP9DWqb^X\YCnb&eR5N<4WQhHWIE4P&>N/uK1qkw4:*kJt<5kKP
wK4?!^ 1wcYXR+$\THX:D\edKV>%cqP+kRnXV^C\%HNDt$anN6HqhYEk8YD#jhy!ka/ii$VW*L\<bF^CZLV*iyK
G6tH5W %9K1D9+wS$Y$ln$SL$1S%=DTW!cHtwRcTGu8hhqulZaMe6V*p<LL&ulC\Z6pEbI!PudcY\>Sml1?JAXD
8*L=Ze Bcw1Z5Wn%AH6kh9nT9R^hNAl+8#e!Xw+QR<jJ!PMqwGeIq4BY%:F\hecKS+RdApFG*ylR6E/kRcTVtSD
GIhAaa W\e!BtG8F/1%%!cawKKJqbVbb/%u1YZkGlKC%HcW$XXR%uMIqQYTh#qA$k6TN>NVM6TRRpQB/u:8atd1
4iA9cm b8Jc:tRMPynwVEH:!G8/tKA>CIGlw1a1i%R$=I+ePdK#j%D/L=kiYQ!jtS=a*M?bHkwcY:uaZ=>?@pV<
&b8JG\ RQ%qQF@yV\Q/BKWh1S<a>M?SBMWhpbmjI*E:I:E@S&J&S8J?m5RVh/TeaQA@SYKX<D5mCV>Hwua8W@Gu
eD9H\i TM#jcIn+W!ScCd$nW8uuTMWhphmj&^D/d?lDQ:il9/PVaQ>kSL4j*wl?I<6wIL/>Ltq>6@k@\Q=kRib\
V!wTp4 :HiiFQX:$X8>dW5PJSTe1AnHd=p1i59R6:8RJS#*@W*I/Mj8:??M?&5WAI>V^Q+$DMCSED=CdW5meEAw
+MeWZ# RDKPI%liGM4I\J\V8b5#ph\uLk1a>MZ#RYI=Ck8cYYCb#G^cacLMhZC?6IHAI1Wlp1c5dt<*Zjk$4$5p
&l$cP$ d!<nYtiBGkBL%KcQmqla%PXQ/kYq/a^VQZC:EPKm=j%W?^1In$6RiL/#puCC:%^EiQP\p4BqZ/d#ASnX
-ATeS* 0004d2cd77200110333 Page 120 of binaries1.zip
N*F>$C :XKCnHtB?uTBcVFE1!9liG8^#%Y4PQ\%^QC>1J9:EZ#h8!4d9FDV#\=F?B*hFRqnqZG^9T#^&I+@AZQ=
KNy?Ne M8tc6mZ1dFLY=cd5C56Lull^$ZbIyD6Y$DA*iblh!jHB$+PN!4H5DFGEebtd$Qnm\dTT=\&6/81Mp:+Q
$cCYH: #SQM<^!uc&$&\Pni5RKpEj!Kn8?<6R*ZAZFl+&Y^!K!=yJ8Kmc&4Tt!hP1/%?#4J/XZ+P!=VRLGpqaMC
D^R4jS wLnW<p<cLJP$cHACAFaAyqjPH$?kM/P<1HP8V^iWZ=X&+eY8%Fj\a4!^Sw5wy@4$#1ddNKhhVhX%XAEk
$jGZ%C KykbCVS8JZ\lQ$e=<*aM&M/<pEtW#wjX?ewMNMqiWp//BDLWY/6RRm/+!RM=Y%\Zc:%VS/+Sb+6MpbZk
1@c\lb ^4cK&>#i4#C^jn1q!qkW48h^dES4CqbiZ+d*CuI+#wWM1S>j+/??=ABBhhd/QGEB$iWHj8:cMFhmy*BV
>a+E!N KFiAZNiqS/wCXe%\1M88jdX5WjpdjRlu+4Sme?l^/?F:*e^t9LmXJB:LpZ8tA&XDKB/w:eV15yQ>@WDM
DqRI:B JW\H\a!Fb!#IFe#dt<*lYqJj+F*mYc#uEMQLb4VZ=tAMDnZelEeYP:+%ANi9p&$!iPbhJutQj+SB=A%F
hmJVGP V:aTQL8W$HTJyw<98S#uGG=KLLiLi9C8@yM@hFPIa#nYP+Q9cEwkjdXm$1Gtd1hc/*99*8JMejBNpEJ1
iZ:cnm <Eh#%EBaC4u&pYH\@dGmM$/P4<%AGPD1?cT8&:/6:%$WuT=Bi16d#nJXIj%*SX?SdV%T*AbC&k?e9yyV
8QRbPD tHInlm$bRpVkYk9pK=Ni8DXjN>\F\h%YL\y1NH^LVlG19F5+kGn$#4=m$Y^ac6!wKGj$Ch>ljd%=WYdw
Mi19<B E4RETc:M&P5#Mj$TXq&>CPtjjMkDi>YeaEe@@4yIY@QY5:aL*ZRHD=*hi/*lm@9w@a4NjbKZt+YPnV%a
yPdJ>/ MmY@=GjCPEe4N&+MchQJFmqZnQbDB^Z=DM\Y4K>@8N<PL4e$Q>C>CtS\LH!$@!Pt=DqRcPZ?5=e%D\eh
ea5GS< 1/9Qk8:%ul64Y*=?IZw5Y<Buk*a/nZm>Mj#5MDyam+Z8E*%W^/9WRqt@SLtuPX#b\4DEP<eV<+ZEKiE>
Td+D?i I$ZQ=VVq*5NwA=<FucaR#/iiF#Pn95Jbwp+\<:kIB@18yNPh<K\D6Kq4VHYQ$ii1L%MESHHI++=E:GG>
b8=naY plKi8R8tD\?jmc<wKV<*Z\\YyR5Jq:15iNc#<4PlW+VMpPH%:Lt&@apl@mBJG#=%kLjN@6q<H#iBWAa!
CG+EXY cCuytV=&GZ/=W!JClJQtHBJI^NYaV>mRde/ljQL4WS4nFqE8#eGe<R<W\\w@8eTu+9^&bi8Wh!!1/?wu
K:Hkh\ q^my$>>:p!wpKB9AIR*dw:YR1wiNByaIIBqMp&Dmb?Z\/aj^Y1a66P:AA^u\R6PBRN9ZSYPcbkbDt/Y<
q=tjG! AX\Ca@wiFVlB\V*8PlHSE\ncXL%aKB661bKpE$h6aIl9BNPXE$FtS^Rn+:6YP@NSwHIBZ4ERJ8XEk+Z#
VwVZ!X MXqPptP48WaL4^C$WdBS/CLSpm=KBhl1ISWnG=/Rjkknh!JeIZ@N=dbb1A1+Y9pWj6ZG1cC9!C&dVVCZ
uj!k<E MSGB4E&bVWm4\CM>d?9wu\w9CVqL$RZ\&*ndQJ8GXM$55h$Ye1AcN!:q:$qIN@ZW*V@LWSpbu5k#bKQF
K1M*16 G9NMt^@XAna5iq<E+qWtkTa9eYDj&mZij119JA^J!NyjuqcmA9PCYHui!pjGCDcyLdF#b@p+J/\%yytp
\X68pq j\DQyl@I!S!qk\9T$W!cCFqNQCLq6DI=R>%^$y%1VF=a9u&CR#cRe/:>ul*w@1!8KcnBlm\qMF&RCMii
<<1jwa n!%ik*p@6VjCKJdhm?&1a#uJK!5b:95<wuGwYGT>NCHj@NVBJQ/=a9+BDd1VehR1wEd/@eHLYbh+1t9E
bSuPR? ?4SwZcwpc?+NkN&iyT1:l@=yL:WciYnud91iqY5#8WRHe<8qGA4KZl*EM+/&eN9X/MXi>X8GMh+C=eA\
$C+aKe 4D4aFW8a*5jC^TVA%WFABcNFkpZW4qhA<GMZRp@:>bSkd=CtECNyBhW&khbBY86D?I1jHGZ\uc=6qJQL
n8/SkB a!$JqVXedduj@Em#lAN!*?p\>KqY$eWnw%!9XHH^9b+CYW@6dT<Q#J><4qQ@lMl%@R:\#T%RiVG5te6$
MbcJ&4 XMqD6kA4Jl#XqB&l1Th*AL&j$aK*cDTntAucewYV%$+/QTuF1S>SJ#bWi!=bH+LpDt4IdJccNNSSS\>t
lyqe\& EBj6n6lF*HJ5>^@qhbDYeaFbpCp/c?WM/RQeDbhYp6=^p&Y:5t@i+w$wQ\J6:W=K<E+wAn9t?Yn6k*Xb
ujY:VM NjDE%:a1\bjnbpcliqh8Xn>dwLS\my>BTh6>GB4ineqyPV>?<?RhA9@KuLdNdeN//V5nMF^t?F&PB\d%
+PS%A\ hR#i?/DFFt<8yXHql$WY/mj89y=^a1Q4am1Lka#5tX<>\cHwLuV>ay9R*wbJu+>kliQZT\/B+8KEEF<M
Yu%#6a TQiPpPW*FX#n9!#mGiw98m<?+kYT:iCBb&bWACiEHpZ$i4kZEuTnpkZ88P/X@FIw:Dmk&VF:yQb>!?MD
ML%\kJ p/k>RVYTXbQXJjaVqkbHNj8M6bl*<X$PD&Z@QPFRI9J8ZiZa:SIBm4S@eQQ#qX:MK%YA&HD/BhFjKDLD
*dCWu9 D?yctm6DcGm*qT<kFQdke?8!QaaKtl@d//+u>n=TYZnEh&\Ep?l%><q<TA+LC$pKLBRZX8?1Kmp/$5Gp
!QMqG^ A@&\+LV5y!Kew$L/!I9DSjiTY=!$u+5Ike?5YB5Q/NKQt%<VY*#q+QtYL<W=66D<44Ty@c%HITFy4eIZ
?Vl:Ww R5<npJp>EjK8dY*4Ra/1#$%dVP45G94ZYQKDZk4cJRu=L61</L>XbLM/eM:M<%+4>XGD6i?n5%hijbBu
*LqK+j 49\TYZG@%i4k<\tFwj*EF+QTltjR1l9biFm894S9^t&WpGB&*QupZe%S?jtT9LXTD*TDeZMDim\GN+4+
Dq+l#E u+m%NeVJq<Pyu$GY%h*S$QCN<=FJ1T^1H$yT*5^y:dqn4qC!G8ABD=y9<a5mjC#JPStwy11u$pcdNmT=
l%AK6Z Q*<?Siy18?t<kKI6>:!1V*$i/C4P4MCl=<wAG6KjeX#ppP/a%1NQa1XGj^waieQcB/*V/S=<\NS*F^!V
b*JA4& EN:XS6$nCySJZ+/&%p9e9HE:e!mbe9%$n<!y<uSZ!BW&%F&*!I1TYYb&*&Fw=FX^pN*c8i5^S^p4*&!t
4C8^$u 4nc+$c:P9VF\Ltd#C<*%CX@T$QJInDW/^XFi1Vcyl+wT&!T^&X1+?X:YV<hLp*#D<@c9m>tZRA!j&^5C
K>bB=h q%/VQc@F><?/kX6m?E<?=%I!FLN\p!l?PZhHjP!mT+:n#DTm=G8Ml%yBemjM?RXQDERY+C&46aAZt\by
dQm#Dl VD*6G6HYY6CM?kSdEiXqb8AwZAlib$^ESp?mhh1mF!+HPS16m>p>4Tpn*?PT/LmQ^yqAD\I9\!:wuPF?
MemWjG ?6Fjdqyid$LjR?J=a58q/ACtyHattiwmW$mBPM68NuwL>+@%m<Z*Bl?\TipCZmR+^LVLuBJ#uM>kjaF5
58qA$@ J*96>1<:Em8N9JQyPLQ\614>NB1R%G$?/:*kH?$@E8>a+H<8aWNSZJyQ\8?e:+L%uYXN$btZka8d9+mu
iVjynL HIa5H?PW&B5e&H%VA5H<lh<W&V^atqtT=MC!$DN+wSXa*B*:VKJP^K1nL/D85HSlEpX9HYF1I8qm:biK
Zud6bn R?qpt#AH<WE=/R6ZZRj:<dHtu!KQ8NYnnk>u?wyqD#$Z&:@aa=>pLGQwCATp@6JBBTiip\8<I>&6bnPe
qA!:jB n+i98m*a!:H:Td9qwiDWtYZ8*bJ=/=HXqRFX1Lp*dLGV%I+DIMNKHbKnD8pX\eZiGt6JT!\PGunZV:c>
BYtWF* D5#4aVAnmF6Z91welAhV8?ISDj=hcaE&>c?J+Aq<lw:MZBii9qnYIFMP+K%Hu!&:Pp><jp^uJa%VW!Vi
>QQ<NJ b&qX?\J^^q%^<KbEEeli:#EV/!*XRMHqaCNT@$6D:1u*9ZqD4?dc9HqJ#^<DbWu9kC@bayl4kR:k<Kjk
CaVJ?K XGPEVH/66kiE9nw\*ylybSR$Wq:+Yk8NtnRNWAWHXCw/1%I+&wwp:a8e1%<#&4C:A6q49bM=ZnM!MDGc
q#ZXd% i!uLG=QF::G9JTyEjqLnPCIV5u\h6PCCI19mwqF8=ul+m6+c:u/h<wLjby$j=^==/ReqW<>meSE%WwtA
Nkd$*6 qYPuJ1QL98lj?8w>N*:Fw*Z+b4TQJ?Yk?=^X9?#JF>LY:PE/lmeNN!nni?dtl:+a9N!9b=m@MQaK%4n^
K\NLiW +Bun%&+^+y%b/8pY^@u!GE?wKG#P$J^6Zy4LPVKbCy5:qp!/Hmh+=?ZR+w8V?4JhD=LLIiYwS&?Nq9%!
/l<+yN bE\jt48<?/W\&$:9kqY9pYLpwP!Rq55yZE*ML^AGWGAT+aqMpGk@GX*BbFpC=X=h?1#=!wbEDW^Z<Vh9
FwBTbR QMYFc6d4<NhQKce>5YyAunFDaN^GtVJWw4tZ\cRu<4*M46wZ4G5bk#Zhk%%yX^ZYNFtE4W?4Na?tA*q!
a!C6F* 99bb5=tFeDB<qhewL6Wn%ytbPQSE889E^jZIp4u:QXlQwX?IwP+8=e1Q:1q^pJcATki!1qJ=>iHVG=y:
j:J#bh HNd$MtLCEb+nBw6JMtan48BPXc:%@bI5t4YkXw&BX<AYBdd*!6VGX@PAM&X1*m#YSaG9:Z\Pi=#YYTpG
b4!j?K 86Fjhbe=?KqYX91=pq4K?NwyY1JqtX&hkd!Ju9WhkyK5LhJTb#Y:q\M+ZyhJd>\<<1clK#jYP:e9pM!=
Zj!5CY RLcW&BiAplq#dl+=KZHLY5dwpk#&/b/XV$n+\k$@?\8E\8hL/wHb?<p5a^WV:\^KXIYVnhZ4W:&mbRBn
Mp<4VX F1Jp=N4qGDkcVH\9b8K&EKbnlkk8CkJ%QI&=HZmGS>4knBajpmX&*m@<pckSZ!kZ4kFABe<%T@jG8I!l
!aTFl% &K#eAk+h@Q!<<6%wnN1GCN6>j##<FqIS+Yd<?yCYDcNFjY&>aQpwy+1@l!XnH68Bb>bNuT=Jta=A1DXQ
byX5:$ 1q\INZbWaV<\Yb+un8c^Ghm:aheWh/cK@6TBF!i^Jkw+uR:$?M9i5*d*Z&G!iZlTZ?@Bu<aecE9X!Ib1
SQip/d :ceS?SYMdWGJy@EML98^Bc1cELcN%/C*4*%T$HbGeTm&<IGD>G:9J=*:&Mduk^Wcn8HFPi+:S:8/Pl&L
=Mbwmp ^duJ:#wy6h@B6$9H+4Itk>u^tKNCMX?MmjkajH#p<5k^:%NlR@N^LR4l#LYwekd4Vb*a^ll?>P+VAXZH
htMLa1 Ty#>mE$^RahQJl+b$ELd<<ewbbiVDl&n8V8!!jT>=4Y?SV\DL48:u?kSb**4$KSHXK^N\y5:^><>+bVA
FjI!@G cR#GBkCG9E\Cyj9u\5R&9SbZWDI#TyStdLjnFha\#Z9!PV$I=y5ZEqEupuMYQpBjY^$&D<$=4YNScnXp
W9XGp> %Bai\DL^N8*6/$\w&@Za=94FyH5Kq\:$VA^$9Vl#JSM$1l?kFb+PiH:E?cbljYMZL\j$F4nPJytEbDdt
6H<BNI jb9#IL5IJZQGypY?8#4X9ZBShkt^<el@+T!*yKXjZQY=qJbdmA@uB?Lh*bIk6G+@6<@/pnpu4u=WyZa1
&Mc>YX ea/9dC4ne?i>4uAdGn%$+BNL%aGDjK8Q#yNmB#4P=YCiMec+56WNB!l/9#!GKlG$%:!\tt44Q#A<X#ym
%YDB4b ^@tlKD4Gk#/F#Yd=18RDn+<e?Y^q9wIG4\>tKw^j=I^/h&Di@R&VMuRQKmHQ5L!ehL:MFpqj/p%p>4%y
VT^XGk Yh6::DSR<MMyS?lN=dN*q=Fu?BX#yaPa\q&C+yT$^W6Am=YXp+FQq\KiSn1?PPYHjkuN8/iZAH8HhKw=
-A/#LD 000c3b263a300110333 Page 121 of binaries1.zip
PmG==Z p:pPwDwQFRh4C:4+Q9^+:!D%6u16IcMjW$mhdZHI?m@eWM5DH<?dq$aeQ@nE1WVb:FtB!ypica9<\nXY
kilmZ5 \t5XYym<5*tGnMCJkdCaa$u?q8qSKVp*HDjQ=jMX?=<bkIS^8G*!GY#iMhl+nS&^^^P=IM4<%EqJNR@6
NGELkF TIW1HDemewLFul>4F:IZDQ^c=Q@X:hCmF#eHKE#DLpjLlcwJi5C?u$lCbX%9#i1?YuK@iT@TQhdQ*?X>
8EKj4k $*%n=$eD5\@ALubHuc^nCB6GV8Jt:S/jqDpcM#>ipFWewkX//ST?XaA@c1M>8:4^+VS^W$uQ+GNV*@HD
<wi^Mh HK=ACLQYM:6H5<&5^P#lPiTwMu/9e8ySpw9%aPStKI*%VZu\/:kYSljT5+Tp4NmnS\*i\e:&4%:&QNV+
M/=X/e >FMe<G9atZbhuY#n%@!#m&?wpWuMYhR!tWtFI!Md@tE8?QI4^#VJZZH4XQDJZAtET4Gh#/S>4XR\!?Sh
kIS5+c n+?GV@hJcTRF#jnYeySmyN:J8hwjl:Lei6eYLudyNtiQ#!iXahwM=4DJ<FSXXB9I&:=nQ<pY$9c^Zy\B
Q>l1k: yHJ!?A6hSw>$Jp^V*p=an6cFVMRRw5wMqm$ZJY9<tQB&^^tS*jj:9RwqEp>FNhJA%#wDT\bG9^D$A<wX
japkQS V4EnEkhwDDc58y6^twT+jF4pZ5^TkGtL8/!F<#14<FD\58ZhhhPYyCZZB98Z6#Mh:*$SB!\44=4nKlP5
LwZlJK K@h48Fw!mSXZi5$^eei=$mjJA\L%iE+XRlK9qu%R@SS&#<Za/i\Dj+hamiQt?&n8/%XnF%\!yV8T\qqD
wLNVi@ IjpDTk1\l5Kd?ZdGw*jKec^&S\hQXNBHk<Q&Ry8?bJke%E!\LXQ%jVy/REq&!TVkBJBqR#N8GyV9qcda
8pcI@H 5R>/4M$*ZmF&R4:nAJFm5>V%miA#Bl\TTd9@eT!?*=M?=Yd<tj4H$S:wy=NF:>N8kSJw+VwenJP<:SN6
hYa&l% *Wti6e9SI9D8DaqI\h##+Yc>/5/MPYLl=Y^##ECAPSBiD6Xkluh^Qw<<pN$\8Jw6ip#/VB@S=FR/86Qj
\WY#hd whM//t4Vhjt?@e%Yd?Q1Z##CM65^KhmQ?KYBZPG>$1JmjM?LHaE*AX<Lbb+^=m1jh*nlPAp9bN@R+IjH
G%HE>Y ?p^Ku*+b!iJjiLnl5Cyja9CZt$/t#!ijy>l^Fbq\?DB?QiWqKZ++MGpn<A*6q%YV#h*PZ&wcKIuh*9K#
h4+jD! E8YVd<85J/?YII^+jSP#\=AD\cB>D@jADyympDh>Rc=**n$=@1p^m8h#6QyMAy\GE!YNMhILk&d5S<Y+
KKtyty WCTHi%&\Ja1$GM*i4M5eW5kM/RJAkXA6eZSkn!8eQ$q4dnb<^BuP#^yLXke$T?GEtht$4Du#GJYE%j6G
^FV+iM C8It:jFCFGeG>eAqjaHpt!=4$5\:DL^k<V@q>9!S!$PAa*<hmXHRI5K^m4@6wqF\LQEjeuh?H!et@G6G
TJDGAD DtFdG1@kpFC!y%M\jQ8EkhN9B>8ENPm9H\GGjB9n\Z=LGD\KnmE1\kpw@Fam\6EE^T%lWZACGk*HKKG*
^Ldjml <4d1lQ:%&8%SGn^1P+c@@S@/jYiu@^nF:j1n9%&?uak+FF^^K\?#XeV*w1Faw6K*?&@L<F&Y:iQ9wJ<q
M@qLPt /Djlj\N>V#keD1/IW@^Y&uaqFFFKY@8+d@6+QAG8TMDCmXnMXwGKY^J5qc1IIZ\:1aRndJ*aAlC*d+V:
yY5d=p >T?BCMhn6nT#yaH6G!y8l@t*9<4hX5X&kt=998qtY$?@@h&YdZ9@t=^+:DiS6p9AKT4>t4<qBy/I?cbj
+8&=eB KAcL?=c^jWApa4?h\PP&ShmTq+D/NtTE\?Dk&G$^WX9uCjk6Mde\cMI*HQS:cd?Z+D?N<F%Z*/V?j4B>
/aV4IF GS1>JhX&*dcW5FX=JiIj&8:*$P>X?ucLdcnTXn&?mdRFJGIWj:YEdWZ<5ek@+:<yG/j+R#Y@C41h</$h
5qe=*+ eL>qade9@XGu4aRl@4AR:P<$1+n@V+J?c@Z6B6wlKY&j&:KC:Td+jh1&kP<J84*bNyQ9F9Du6C$bEa9>
t48W>m !<&@GeKY6WC@Ni4jGKwmu9nNCLaN+Qhy8?N>V>D6#ZdDj#iAQ/h9c5V@ckT@V:@twZ?X\PGuqD!1p/>V
MJHG/= 1Jh@kJ^ykJ?V@&@im?IY+lL5Fdn>6jkYCQ@ZIT9Fj?&KmQ@cFZ%Q*>5H@d%4jY84@^n+j?GKeCnMj%#S
LEpkXX q6jbdppMS9E@48ldF@&VK<Iw@X?/wm&B6:$H<deKdVjY>9=&&9cD*=#lh=@%4ch>Q:8h<e*!66DjXENR
BkktG# @GF>@<+ZjjNB9@tmd@qdSZ/#u6<WDQ&>64jX>F*RH#%tK&@:B6k@XiJZS@jhF/F@/<hw%P><$R>@8KM9
FJcD9< R9$t*Ve6jD9/=<=I/hi?lj&6Yj?qM<Jlmj@aGY%4Aaj?k#QCEau@#lq>p@6HW@:iG&*J@#%B9%jt:>L@
aDdY*$ /I&&>jm>mZj$Sw1@c8#Q?d@9k>D99%Qjt@uQ/ae*?qM%98j>Y&?pEiD481M#I9#XGSH@6VQ/^6d>l%Vq
RkmcL$ *$V=jaH@Dj<Gn@w#@\cu>A@=N:>^B9+$Eeyj8BQaQ#MkFNE:5m=\/J<mCV5#QZCau!N*byjk5D>F+4E:
Xq>k%w q+u:KSKL*yEnk5Q@FIubtcGEI@\Wmed8!L@BKj+W?Zi<FN\j#Jn/Hjn*4JL9JBWFw=*+Knmq9:JKeDlF
iC:wCB \9?iXiK9?D?^T6TBSZTBZh15/E=Y=$kumV\Ed%KjYKRl*F5c!iuFIJ1jH&<tPDd\NpIhXE1E\YII4B!N
WNCe91 #wTc?:&Me!WG46K!CjwqG8duTHIC^6=yakXe^14<!b+\JL^$YBw*B5I%iJb1^uXDiyuI$1Wn46X&#<M+
IW=F%^ %cMZkt>C5IZu$1=BA=VBwh4uCHEPPpLJ&wR&%JSJX8M86w?e/t$LQlXJK$*Q<Y%QW!4Q*X=TZbJ\TWe>
dMQ4hB \^!N$Bbb\%Y?ZQ@\kmtkyDS=+c&D:WYZZuPaINwBe9CS&j*K*Jm>j8@Q8Ie<hV*N:*il#HKt5uCG?mGG
Nw$wD* 4w+tD=Su>S$CXnEWClB8P\<66NWtMd>5JB<XjF+N%S>=K#8WkY\D?VAKMKuYet6!^y4IHFq9%<>dAawq
h>a18# anV+V<q!jd^S%n>Vul?l^#@>NkdK+I6LY6Y9kiEG5XwNPLILn*AMR^RN^qb=%pMe!Pa<>AnKqyT@kjb4
@iDnDl ub41V/M@\\6mQWdkd^+X=1&weDHwTWP5ecW&11q:n+4&aGTjei1>inmKB5uByl@yhj4+EnRnM8S^4eNl
TmkBCQ %BpEFm?<VyW#GFST!aS\au6j!?aJkQV5DndIey6^Klm^/$&X*B&\X>e%$?YcSq!tD5Y4*icY5?V9=Sc?
=T=HGS 1uMJXlS=T?q$eb!m/y5tnqG$HMhn1u1Y*1lVNaQPA+RCb\eXdS!Ce+$ES=mHhhRFM%M@EEb/llw%I?1u
udXCtF Q!DMPY#L8w%qDdwhp=1i$C6HCc8C%TA^etc^q^wJqWqE%cjHEc<G6btBjI\D#^ZC49qJnW*$i%?=S4&>
15^mE! cABCXkt?cGQDn1@Nnj9F\jD9XV!9%YJ>/tJ1S\8QEl=Zdmt#q9$c%FauE!ndN+!=y5=FGPVbJ#McP9+$
+/Vi8G 5J:V9tb?/FKa4iB?5hBuXYcbDae<1JlFXCYlC+1<=bQktPXPTnedYX:eK<hm?GKYbFRSC#=iJtWuY9#e
DSTI%I hl#6Q%5$!DXiJVQcGHcZ1u@&=hi&\L&T^4Vl%lMi4m:ay1NBW<%4h#*41XuWK/@A6RTauT#^>hXB\iNt
WN\#=+ %=99QB^/<KBq<Gal!Ba*kE5bM8$aYBw6h^G/1dS+j=ePiNjCC4Tt&Al&RD*1%bt*/Xq!kb1XD4hKL>E=
ep5pVJ V!&4d4:56Y=NHw>>+:X!atJYDqi*NH?h#XF&8h+/w%^+19YlawZ%%GYQ/ijy+p5K#E*^q>$q<nJFQR@i
D*E9=! LFCXCBED<\lS1X11:$4TP>1!mFm=&i61lZiukuuTbnZnY8tJp&yt/e@cn5cGKuZXh:JcbjBCAl@eLA<%
^mt@Yp Ve>AQkBySwTJ9b?^V!^ehnD+INLI?/a/QhlZ:qX+bi!bI?WC>AYtA=FAbPbKEw>+FLS#Td:W!9NFb9$S
:EHnIm +#++4nQLlDFHQFZ9te+wEW?:c@:IIERLaWR5h5^*R94F#^cMkDSJhWLm%\?ASPe1i$QkibYV!pd^ZHKc
@S1IY9 SyZ1GqMJLBN:i+HWMY:bcQPEhjR%Za+=md6S%m6ydp1SuZ5eCpiCW1Di^X&qHVc=Pi/D^ii=8+/^mRXZ
!bLA?b ^dt4w$>y?4PJX%>BXl^PA4$XuL*Rci*Hka/F9etD*Q%<H@QMkdMK>6Fy/Xp#:TdIYV4XSN^h<C$/^plF
lh^Tw= BmaA#BA<lP@4EPdhtE99Q64BBNKFZw/N<&A+?$^<eCW$y?n^9wGn#dLeqt1=E8N=A^?M#/>+B@CZ$y?b
TTIAak Vek>L1WHF$TM4C?&QXjkd11/\#J$99P!SXHRF%$l>^=V#^l?5#HZJtqt@wA=Di!bNQRL!q!dZ<yq#*Jp
:&X?9? 6qW4q559J#+&dDXR<KdXZVQH4uA=8u8QGE\9CDmM#4LSbh+%S&dY1F?tYRih+G:A?$NQP>$@b=R5&wC4
hwS<@j Qnuam#n>dG&nNhZW\n5nYi/6bZTPe/YAScSM?VMLa%=RY@?Anb@Kuk4ZjC$mhKDTNHJI8Rm8D@b:\PPM
J<5EeD %ySDC+mVy8*jupQ*!1Z8j6m?WyWXXbF=lQZ?YTb*k+nt/KdwhW6*^k$^HZCbG&VI!AZyGaWQD#&kMt4h
DDZTj6 e&F85Jjc<Qb4\Tp:mVJ?qpI:lbEQ5G6pE#4KF>DT<HA*:$cI$BDJ/PDt?4%H?YC^bd^1Pk&6\yB5>iLL
@Sj$aP 5k^I4?*?aMQ?MnqT%Y\$pau%It&X=Z#>P:c&cS>&KeVubnui@M1ylwCV1ZCuD6HM9m6=LS$%p8<NuLJA
RFeQi= n5Jml\&dZJ4qQ&nuq?uE<?G9qkX9<nMwSctuH:GV>Yb^Q19pGtR?@1ltV%@#@XcNB@4HC1>K^h@Snl\=
9N#b<E P:6?#4<9e:*jdiBFSEM\Yu@1p!9DYCI!T8@t+MFkWHCyM$P\M!GIip6YPhWWucqRJJBkJ!lbcQiamyMD
/6IV5l E^J9kqGCRe@4AmEnbe+nXP:qltTjD#a%9G6n#daV=IEH#AIYkM4DIX=^6#ij18+K$WVIEam*E<K8FCyj
9CFj:h V%E\LL%<YHbD9?YMR1KK$h=G>XMC69w+C%iLG&B#+a+aPV5:yLt!yMZe?Si8$+/9PYyiy6d=Cp1#eV!L
1^!*K& Qd$<q<W@h!G9<ZqjMh9C6ACFPY#*mlumXc%ZL84qy?e9w>\aKa*b#6qj\aeHqNJyV*&SFqYFE$%PB8L8
mwD$TP IwcC<+b=C:J$XYFG8B6u<!\*:uuq=VMbMX*#HH+\@St8?CJ=#5J$tDB\?Np:$hBT*#hHD<>PmiY?antR
8Vk5P^ $KRWH6>ycP#R@eSmekbHPPD<tRqI6>>k@6tm8i8DnR>?NpGbJdH5pd=:F+V4d9Ml48Wi8+5@L6ltkLh/
JK&:kJ wH=?B6bauMCnee/==e:bWA5N5\iZ4tyXL\n/uny9VDhpJPPY&&tLj=MdGPnWh9MG5E#nA1ie/YId4#a@
KL<RWZ @PP6&E69:@6$nL!^L6i!T#l?^6C?%8>RjH1y<eQ5N19HdTYbW+G&w+Z4i>*^5/Gn>K>#*Dy9Zji&eS6$
/HIHZE Y=5Qj!JjQ4^@TNS%?jaimJW14:#M^WPGn\+u%kIVH%LKTuV=wniw?%qPMh&FS?HjBw4aN>4:BCbNt\%y
IQ=mVH G:#uhX+++eSA<:wq1B@@:FWkFM44*pi<&:AWcNjVeIl:YQpE#?GN!\=<D$68n9jj9VZn/:9Bi*D8enW8
\:@c:N >wYGPV?H#46F@X&S!ck:M/aEYqL&1#W=64=PcKb5Whe9MSLI@QVMbEG=tRI/nipS?mE=RLZiVDy#Kn>P
-A$n8n 000e7fb4cab00110333 Page 122 of binaries1.zip
8li#Hu w?aTqa=?*9PZ@MmTNWEkkDIm%waIlI9Q=b!PCWP6thcIW=kN*kMDQ6@teNV6DS99CRQSd^/Bt\DtKakm
YaZ#Wq mq!S:!?/8?m:mcN#$*Iq%4IeeVJ%MESkyb#ahMqmL\9>VFm*JE9pSaDHRVu///\K@leY+#CpdBbWI!FR
bAuF%c VY+bbl%=Acq^kbXNCk!=AZ/%cW>%Jw#A:>\GuP5cpNAapi:Ib#u6#\JQaI/>#pcN9SPa>A5a>R9bD\I\
!l#NKF aStX5I:5=GR/mAnQa$HqY/ItccTWN<d4LH8TkQRqVQ$=T59uAe/h>F$naI*mAQlyZ1wn\YMC5c=HDnhl
cb%S=? B/Npna4+ANYIIuh\WDKn&Clj\PjEGuhYhPDw<*SbDm6kiPt<YLd$ZChh8Dj!5tiwY=kXb:kqtwHQyFMA
Pm%WYa =S8A#8CP9!$kA=NniipZdkIl5\5Zhy%Qqph*ndK:cHKCZ8<Py#L:b*BydF*emDM=kw#5*DXn\pL&+QEu
5AHwy: uTp>wV$TuSu:t9+YGpL&9Y\mWmM*KDVpSHh/G5tFatJ\b<a\Z5WII549C+YdMMkGTbDh=eXG^iuQCBy:
pmu\m1 ejkYMRYhAVQ#M>eb9JlLE*K?Cq*TFqqBT+/+TD*h6T6NImJhFuu=HI+e>!:<QHVNRb!1peEXiluS#<Lq
=#jX6J 6mhXc*1n<Bj/M<kmD<RweZw?Dqq@DGN1I%Zc!=NM@VAT\<hJc!jZ#DQ^k+NcpQX4jWHuJb+K\Pi1i$dd
#+kES1 A>A%cI&1*YPQyRPDqhiR>yj9wleEV^Tikh@W=m&5km/?EQF%B=85T1@M!>!X@+ZM49D1C\4Dl&EkaMl^
A4aiZH Ailw8R*AK%w\^1nQ+QIWnW8I!cR\KQ&+>QwD=ny/IGeVH+bFmVMZX4?Maku@5DkqX+Ft$cmmT@EA8Mt!
^ay>$> 9PamBPplcBeRyS8?=N&mWy%<L@j\t<k\aMA*kIe=16bbImi5aq+LhFYY4C*6T=NWBN>RA^T#BA!jKB^X
G?H8?C 4R8SK9<AJ?>YaVmqtJ1QMjHlj?a9N=hm&l%HCQqCF:JPD*A9/ZeTB*kmZ6/EbITBTTZA+CP4ZjNKqdd^
k=Xy:a h+6B<=SjNMwSc\Pj&Ni58I8H#a=14q5II>IAZD\+wCVLjByk>I%jWT4PJEb/JpHG&\/+KIE^+ZBy9IC5
lyuKCN <*ZJV$B1T5ktu=N:e^wViqTXjkS+/V#A=K&?iRMQPW&=1G?EEa/l\8R+tLVZZ>Hnd88>GeKbQ<G?8cKh
qt!pRp ew$+$I=w#CQE:6Y/@H/*?YWn<>e5Hd/I6VXV$#bp^tQnN?PkiWpX<t$R:11^e/>Twbawh:+$:eJq5kiL
HhetkB BekTE$1+i%u&?dwK@SQ8KN>=>HZi85?==weNwtw\%H#EY<1JBqqpqIjq/!Q&JqiB+SjNN+aI@neFE>iF
qIHWM/ u1jLtIqcpMGYtApb*KbB:TdlulNm@RLLY\eEjaXlXmWRWIn8imJwF91q6MTk%$XD:I#h!u:^WAZC!Gt!
4\M5$@ h*A<JW!#$YK*^WtDQt+NhAXd6=<Kk<j?NQuX8#1nVjjbiniR$qT=1EF/5w@S=bjS=y6tB?t$uEih!KQT
u5*#Ke ZW@$uK6EMIeklYjakT/8bD>P:nl:e/kYL%E/qS<>p?9KEb8a:!F<?!ZTa5/KP@nPZI<5>?iI$LmSpEZT
u:LbmM Hu/YtXQP#W+8>FXM>YL8d@imq8>Lb1jQBb6GbD6Kh/YCknc8+tnuI?Qq9JpAd:kW8FK^1V\?B*5b:@p1
ER>kVu t<DPyVynhK=l%\Vp/hQpSnJZ+IpeZ8>=1C<aVTJ+ZZnaktY6uP5Rc#tEIBCBilDbwP9DQbV5uPlQPHi5
=kYy#H eZeRyk>nDpFXt?#lE\@PHkF!ei?l^i#ltc1Sc$cQpFpQLF$^$nC5Z$XqFkEZi*Fb9?#nL1EG15nhi+#^
qbYPd+ p#9IT/@*VkhXNPy<ti<R^!q**pMmd%M#/B?E/bmR8cYRhV&nSbw$<$5T>B*MwR/RnB:EVIW:IMd=!u:u
iI1?9J @HJ=eh?p8m::K:*:AiiQ%AWdZDtQa:=9cAWl+6VNNCZm:@El+#bqTS=H\$$Sd#:L9aHIA1y$q^=^$N\^
wjBdeb X1>yLmQiql1K!ZTY/K?cBLinbGFbn8pq>%:YiX*I^MIKWXF:yDwwl+FK*\t4F>GEu>WdeJB:t:!jZ$?8
*juV+J KXCqMTpw^?b+aXWELVE<?KJ:\Hykp1G!BXpMHD4?Wt98EP5J9m@:KGiR#VjXX8d<48!X+V?nYM/**@!M
EJ8<Qp JE5@e%kGLk6tZ%>F%q$hISREZ%G=8dcQqKdMjEnVPT\@Iy9jB^C%=!:Y@=A^u#+dmDj/Ju>4LJityY^R
pniYmc T8T%XFImQdl/1lT6a5b8btAd*=EJ4pM\Bhw\WjjJ<=a=a1h$S*IFjN?uhn%J4&<tnjZldBRS4>Ya+dq!
hiuLDZ l*XGWP\t+1^$E/#:=^=B$5n\1*1?GliBq&YIhRa%q6ZFRTiDX6@LMPCWVc5pGL4VqXIIb#/uneJ?ijZ!
+\J>Rj q\%$yw&QalMVV&R5M<4Zl!PHMPapHXYDCL/QSi?Daa#QhiYi4d?bhb>Z=9LeleL:=$&QZcIj\=EK?Fqm
HlW:\y YhLtRA%&*FhLEaGnKInHH4c/P\&!>y4&k@Vbce#DKbKE\X:M\Zl9/EP+Bu%&5CTnH%A&4hR>1^b&1hbQ
G+GdV> jCDulm+beM4&WE>&RtTq@YtbA:KYHm?:9YyqHX=FZ*81Bcqb6ZjHuRay9$m\4tSujLhk4ZKH?C/jYmWH
l@6\L@ IiWq4A@lSm8@1l^JdT=LiiFel>N4d9&aWPinWHcHLPnYN!!>e1Q1K!tJH1JkXhCu@QbhVYu!$J%aZ?bC
*etic& EJ$GV+&#8YViAmNki=!cCYB@V=ILFG+j4REL:HAHh9mLMk4XFuK\pRdkpaJ$Gn6NB+6H@deD#9>1bBu@
S*?*Sm *$\hnj@LB+X+*L?cPl4@q&km@y>PCa#H@9jRHd/&?9p<9#9N>IH@u>kAj!1W<F<wtKD$b\WVmQ<\ap#+
Qmw5dR >Y+E^S$C^@m@lCl@t@Qmh$FeSiKP1mQ?FQp*aXG<$5@LJP+ammYkjw:E:VlVPAH>W!Ri6&M>CbmjIuFd
te1ZR^ PV5l5V>F@y%hEuD@QSV@6%<$1u@@wyH\%*EV\l?NE9=>WlMF/9imj<Ti6:?N^Y@bGWEJ?#*+nELnj+Tj
Kudu+n j:P#Q>^e<a@S:D@jEd%Nb>ki>9wS#9+8+hd>qHaRq9nZdw5lwDE@u!5J&P$W*p>CSTZGpp*w@nNyWmtc
bJl$Ry R&DatS:lLM1Qm^NnmPl9<Th\RE<^YQN*wZBC84T8$jI?JmmtB#K/#8mMbw6ne!*mS@ZReH!RQ6Q%8BGT
!I/qt/ ZH4TIlPmH*tIE$pBLnmhi$M!4$48:W/LY&L*8G\n&+$iaua#KtA6Z+<5cBbqdmM:#SV+M6NRDV!RIQ4J
VKJiNC @H^EPbl=M%FimANdCGatS9Vu>@9%cQTC#k&dV*pyLYqFSlWMTp8nuwdtJA9e5Cn6PRP!W&X8hFWTt48e
nuPIE% c%bVQ8b/V!BEQKJ$aSWlu<XmWakZ9E/L5%6hT$qhCJRZbyMW6!XNiwXiw<<uy=Ye9dpa@WF&uHX^$%t^
IM*ABQ h1dV&nTGPwRR<ka1tatk1LNK<6c\T!Y5lVZyLTp=/w!IP$h<C!XFI/&#XFndaP>WB$Ia8>Ch*cG<5d+l
eTe?^q 9uNaJ*&^l=ht!/qEIJ4chShhXKVJk?@$hIcy9cn#aGhZtKR1Z4p$TI8J=j#$lS>VyHIMqV!K<^@Y/p!q
aNV8JB 1kJFM#bRKWu#+wJ>G=+8R5&G=!yHi%um1CP^J1\^QQ51<p*kMX\W9j+?p#wVpb5t%GZF=HqZR\R$/E$V
yyElZ6 \8m!RiBu:R$lQK?tahTGay?b@m?<Mh!?d=E>PH+V1d:d\qp1N#ji?M>1G%SjJh<$tSeRNPMPM^NXanPZ
>NmIEn E^LXS@IntSNdF%4XDGSRQW%DQn:/#Zhp>ht6X56uBWe9+?Q=hC@hbuZB!#Zi+ea$C@&m*G9IK4nLE5X%
Z*BhZc lbuW@=G^AqTL8YF@9iuSQJ5i=B/S9=iM<*+$LP5c5L?ieGqhPSc%h9hw\**YZQ11qhdW4NmATE=:K>$D
i@8NKp Aa+^hCGW1dkkdLBmmwudd9R\yp>hnmJ?:DyCp/=IC+hPa#WXIA=SLE\NWY@e^Bw:M^QGi?RBhlGWWcna
=!@5&D /EIY=P8+eYeT8dkH&<ZH:uL9wP<w:wn4mc>Q%VWbnB/8kWYFJBP5k&M6#@IEHESh^YJKeLp8a4Q:qGXQ
ELk5TI 8SDypuiu/NZLt++?#b!&HeTKb1y<81I5j!pQNJb>?Z\Mt4uZcnmI#Xn*luny8@Hk\^6<CA?M@A!MVha%
=I$>SI aZyb$PJ%>V4ZGdWlH?YpL$JcL+Kj:P&bi56=b?Q%hAZ&^Xn1>N=Gk=4E%l51Z=+Y8B/B5uh>II6wQqm?
8*4n4= b6pGBEhamq>#iHXY>&l5G5VGGlH$/jT+*<FMA=njk$DV$aeu!Ql5Qh#bpDLRTVQ6e?MubT*:FPX=J+Yn
GM/lIc 9G&Q^%8wCw5HL<XZjA#W5/niq^F<Jd8%%$\/b:Vpci11IbjwMh>XJbJEpu9!e%1pZQ!Z5^ttZ<aVHpel
5=hjHK BITKM5eY>?>>b81=QNZ!SmZAepkp<5+6dH&tSl/u8Rld1pBCuWj=&\8ny/V:n\9qlIcP:wKJH!%:=q^5
l#*Eyp VVmSX\&#/DNHhhPwa+bCeXy4Jd9LJmdTHMc=n4Mn^dTa*9qF%C61X=#kST/T*6>N4A?9IcHL#X$kSX#*
ZF:R\: 5TcelEL?\Ghn^&!%VQ1Hw1\N51kd4@YM9HLE#H*VuKbe+^KP*>$Z@ST\+K#5Yu8Bn&iQ%!+8inZeHePX
wJ+kBV //G+Z1HPbF&VIPTX=iZT1DF4M:*#J9VSZbBe8mdXDaP:di@Hp!MGX@S8j/nBL6GuGZRtG\c?QZM^q#k$
DhtcPT Z8lJpdWSakk%=$#dKCM\6Z&8itPjbV#\G8e%i+%a/5a$Cqp/GZIiwZ<Qn%9mpAciZ8jBuVqP!I>*e%uS
N8E/pB Fe+&V#ly+PPhe8y^T?QBa&::*?TkW/G/mNL>jA?X<&l5a=cW!KqY^+F&A@<Ha1TmlCh^Nl@a9DbnLnj&
V1y+1j =i:SEGH#9=YqWpih::hXXC\h#nYD/i6:1cicltdl8C1Al6aNh$XBp%h=*?C85c/HF<Q#^c:b=CTbaEtY
kX+C9= dF$C+!9?!hcde98RwB\ltuicndMX<YX8n?lVpjJ8=Du*@IIbm%5*^jbn/jAH+u/=L*E\4Yw^GDVm\L/Q
pF+w!y yjnq:awQdAX^iJA6J?A=S4McuH?qE^6<k$5/$QnP8!G4i^#uQd&8/nban=wkWw9uNY%1Eqe/htjTQMil
dMw%98 iwmFB\*!X&4$PB+>bA9tSN/65PDIq!nVil*+wASi*m#8+I8Xwu\1YI\5<X8%m\/Xt8qciAb^NBjJ$W/F
Tk^hSG /h/C=BjiQZD!ml#CwT1:wkacDGJHqWdGuHl@L6w@:p!:mG=P/EdtJ&Z!KEI5y@EFh?=+a*XJX46>C<$>
8pQZwa a::YR/hmSw$@BqJ:6jt/@/mRHqEhYam:hFT>ZccH:BSB5/8ND=MYGJZJe9RyQtIp=+j4@lT&/RS?p<b%
F?>:IN dG!j#kp9@/SV1cY%4Ltt=R9!wmmKXYN9lT\Acp9ut&B&p>&B@^F9ZtmK=*&pwIc>q/lAEXS:I$9tQ6!H
bYTBZ$ NGy!E*k=yq>*yq5w+?$8e9bLNbi#J<X1&E\m%t<L>VBaMhRGud=wBERR*@k=y:%?$beHj1%XuQQ\hWja
u4<WZj ?jWM>8:Bb^t9@Aq>Ee$1m1i/h8H&qw/aI@C8DJRVAR5GFN*m$b9lm\qSnTJ6%LYSydItV6FJq+\Hh&Wp
paPMT= e=4K5A?cCRh4$XM=i+/TlhaMyb?aCjc4qd#8kiJTQ*TIdNb=<d$?TF$?1nXZe5J8InQ<yAt*LeW\N/F?
=@6I>% /e/ypAbY5RyJ1?DS>*:J5<+F1+LJ1>n&q4&PGXQM+:5iHFhNy4:ReeyV1buMY#65bCScjk4n#QH/1>d1
-AH^=5 000a2b22c7900110333 Page 123 of binaries1.zip
^@kFwa B*dny5T\P:h>CwWF6hw>QJ#1/q$H>%/hutT5QuZPL5jQ6?DPiwPX4iDim8D$l+j\GdTEw9P=Dc5Sh#4m
k<%FtN +?:eJyQ^Aw^VW$ji>kputa=Zmk+ZjYYqF4&<bGt!K!:X6qTRHK^WnVuR4*B46?V#S/W$L&X*LGQm?Jud
#jMS@D <q%Zq+nm^:/MV&8:VJLG+JP!L:?1?>uX/k<nuSWQNnu9D\$lQjR>^GFTiEpq<iY8Ab**$atSFbXPwCBN
l*AYS? iae*n&jK\dpln8^%H@kVVtW\+?L8!R4\\V$Q?q&ip/i$X5RaS5?c1IhjK&Qd1<nSj%8m5yk<VVi^Fuhn
WETDPL tm9M@/&W%h&8upRHu:MAjKuHQXDY=4l15%m5D:\9<KKjjhX$MWYu<le@YeAdti^4:*ehe9kpj&$mbA<S
m%nGj< h*PS>+V+IetGT=d9?E/jP\:yeVGNXD^*1Kk6>/#<m/?He#>#\l+JCHSRAw:6q*H%LjF>k!!W1RyG%iS4
@R+PN9 T%1jEDj+pQR%IRyJa^&\S1\wBkymJJh<Qh*Qm*><iG1#K:4+e#u6lH##Cepq$IK@dbFKdqh@K+e+*S4q
$cB$/h e^SHLGM#P4wa58aGnJ9iJ^eh6?eP\=yEEW51LnBcQ%W?j=+@4M/H1j1qG*6i#y46Xd@WA>T#IM%Nj>t&
H*yp&< tPlmL^pAS8a%!C?alnSjSPYS&LL6uSPe^PDhGl?6jAKhw/ST&Fwq\1p5p5RZWV4hL^c1V8Fmu=<BMdud
l4dLSk i5tYW%4$m$:S8:$E#TNhJEkl1Syih>IAuC\e4/\ALH$4M?/c^kMSj6EY&1Yp1A9Iye!>DQ+!yTKXVQXP
iPRN#= M!@FtBQA+iNmkARbPG#H!V$JT9@!Nj#HHI=@wID@l@i>6a?BK/L?@b8/I84je=$\@^Z#<l6bD4PXeQkj
?&Nb54 #M699PS6Y6tjtJi+d!Thu#I9j<@=?</<*Ccj@bFw6kMJ@H@N9Q^Ge<My@wW#?aME9yZ@ZSLwD#:y%ktq
?LFcIb *%H*94HHj!QXjci%jTiBj:68??a@+%%?w@$T6ktFmn<+q:@uJY:9R#G@MjI\9=Y<Zhy*l6+&?Ae*<D6=
ERw/p# @DeP+R<h@CBq@p5PPPw:ejQZI<#jp<D@eI<j&P>CEdb/#P?Iq*>8?Q<qC@^:qZ@KA9?8q=&TEk:>k^:=
==^#&M S^d+u%mQj<jeXQ!6I?!a@=%*?c*F6y6<l$VAE4?b\i?bu6@N+Z9/aR4jViA9N@tNX@\ZV8b*W>ni@A9i
!\5yD> yY/wp/?Z!+:M!:??=C9?N*FDJiKj\%yKm9<k4KZ8:^<R88&pjyPi?G6$VPqZJ/4$&*!69$:KyQR4HW:y
tlIhi1 X^?5lQ<iBj5YG@568QCu^eu?E9JS@HNAeh6whq4YDQ6VJB1#a=lJEjhVJIG+M^L@e?VPM/kyEu/P*Jp%
pkX8+X 11n+W!S?1>X&RlJ@n6\=dKmw>HMpcphymcmjIuGEHRPPSQVQphkhhW9<8R*lWD9P>$d<8R%lCV9Z<?e&
NmuQie lMZ5ZM?j&^CG8LP$Q:elDH:H>mV?*Id?hlHAQ^1SY<mY$#LE!T9Ja#EEHEGi:Btw+?dpKw?Y%@WQ@db+
+^dBuc +=c4p/h1W*@+yY@?+@iQTRbi@n:jHJQL>1MeYuH:h*u4X*P4ldbb56?<SWC\1%9\%5qjj\L@JJDTDkLl
$PYeI* 6\VCwdBa*A?BMQLtut:!8u/B9t=?Y<:8&:KV<66QpG+lIj>eN9TY#Y*>NH*:hk#:e>tWWD9IS6mTDaQh
wME^y^ ?t*+IS6Yj85^NuSdWReC=b&&Dq\PBH8FHycuBt#>BB#?X>J6@\J9qa4di6n<8ZVwHcSV*JJ8/$+w@A@y
XcL5+n eQ@S&4cIV9LWA<=de5u48^*ictV*+K%u&PADL1EHk6*?ncSa\6d9/dh9dFD@RFLMDyIT6@YIWqJT@CHy
QLw*8A q5#jFlV>JmW=IDk\IHn4TX:i#M9Dj#69T?B@JTFtT#4F:Rem@D?REL8DlE4d*RK4mMN5TikWGPwY@B@=
y>Lqq4 %F%h9dbN$MqZu8LtEu\+<J5>dpu+4+\S5/Wa:HbC+j/BmLkhSETn6u5KtwD=V*5V=W$Q?H>VYPlYn>u1
VAKVY# 8q9C?uu=i&$%<@c!yTH!Xq=HuIJh@=Ye8P&9V4eiFAu@yLH^P<tJ@mauFw@/ub!Wdbt<uA?E@8bn=EMD
kFV4tY =C%C*IL@uR/*Z9C\PM!*#<=?Ll9ln/My9:uN9+/tKPK@n/aw@llNRYNRj*q!W%LeciYJ4h9?d=ciaBJQ
\c:l6* &@:YYwkNFDudMeiI+$@1:R/1C:iVW^J\Aut1>?GFV?5\MakGDqDltZwq/dQSNj9R$V\>wGXNtC@1hBIn
qX4a?4 #CS%ZB$W#TbhJPAd:TInSIw6$58CiSK4lmLMTCbcHByIDiCCW:Iiw*p#>N6IT>uJ/@5XSq6YV=CQCCdX
pX%JL^ LD*$dL%wWuHH?%/+Ba!GEwkD^^LXjcuWuAVNI5/Y@CGERAJELFeu@&dlGBlTtQ/Mt5W5N1XP%huq!Ad8
!5I<!X Mk1Ma9pC/yRZ%udu4ZL4Y6Aci9^K<h1L4!WSK&58<*p<y@BJA&?9nEV+Y#8h8Q%Wp<pQ6pu%iyjed9PF
kqknY* a+G1QZp<RiVBbH:pKCmk4y>\9cB1YqG%6t=M/ZyBQqYb#dnKk4H#BW^a5T5%#9aVc$TtKklapBw<hkM1
Z:CcJk 6K4ehQ1aNEbV:1#*w\n>9JZyY8d/pjy<H*JnK1mCG6!:h>XH=DuGtB?&EVMR:updG&/tIyMMnVKDWNDL
$/GWLt Jl\kWW4l/IBL?RMEpNP%e4^d9h5XNcTi5cT5:?jL8#uWVX#BDSu/&n>Ti8bVuC!Sdl?aI1HD:%>dJq4u
ublddQ ukZT^WY8*aRWDR%h^\STpj4iXW<+pAX%JpyGy#%yD$mNu&bq:>Jh\tG9N>H9b?q&w8Att\@an>X4ZPJ*
elXiI+ liuF4XH*NpNqLQp::l*X^<YPHDnJwM=XVqY=l:<h\Gn&N1HK8CN=F?:i9TIHW%#!Qa1G$N&NZ9<H6bhC
HSI#p/ uA#bt4tuqjFb%*MD:1/::4K?c*n<p9:n!?bp^BPCwb#yZe5FISeNK5Y^6GVkE$!+5m5@:1*N9WA#+mQ&
lWHPF9 8muecY1&nP%>5yGaIuBEbqX&mD@JJGBmViJ&<8Qb4A+a^BAG>RI%j4uM4ucj=<^=l/\t>iCHnRbRq!He
b8mDH: twq*Xc4Kp+5PYjj8JV>4clhuH8y$%!#5ITS1G14u9LmPB#IeLDk&uhh#n<u^wRG/#K1ANH9yQ6@\SSb9
WQRDNE QIkNCI+\E?TZTZebX&4&p*H5BZKTX=ZMA\<<$He41NJVdJ\>:*>*cE4jwYQPZ8wTS&#t^JQ>RFTwiJhH
A^p&Ii ^b9T8#$!WP8Lby?F/^ZjBN@b%#IwutFF/Z!Z/n/&StjMCF9LXa$aGqTyi=a><8cS#eP8i#ilX\=%clM8
SNJXGw tqF:=cB::m1/**9nIP%%\9R^=b:58>j+L&cc/pt:GQF6bX=#ut5M=54B$$&yD+&F?6+M*JL6?%!ei>jN
Wn!Di@ ?>Tq=6kM^>!#!B\Rt<1pVBlIaQISu\8!/ZLDpm1DHc5wnnb4mKG$VNt<:lIQ/D%c*:*lbSMu=?=>YLa$
dQt%P$ 8:F!b8<#*+F+&KXJw=yH*mdtlmYGWlQ<qbq*u>4j!1P49/<!JXVN=#Ew$b:9H64nwAH!4%\ddRZcATa!
^9u&*& n4pp/^y4^L4PpkhF@Sh%Pa4Vn/XQll!%b9><B!n8ZuHdlaBue\9Lp^k/e:eP+ZPcnkpS:lu#lQ8cnZ5u
y!i$t/ /<&d+J:JnHN1h$atBFPjmWANAw=wN\wIb5^+nk%F+KyR4Xh+%G+6XN=Qea<=*1MhQyE*H*Cp>4LhKd!Y
tK/%j% 6$%<TV1+W1@W^Yl?8kPuN1buKSq1kwnI^PH4*>bGtR?h=i6*P619dIS+k>/#wMGb=C6^wie8499J:BqV
>hWdJL F6\h9BIuI:<M9+9lGISTEm1W8mKTX8FAZ<j>$J5e/P+Z1NVeGE>bi@B<q/d55e*<W41>QHjhV1WL<:am
jXAq%H PBwn4nFcXKp*!Jwnc/IwQGcw6PKPHNS>m&6CpDe&!AEp:&YPRHiwcH&KCaHRtq6+WVZNWwBkebliKFLY
CDeV<4 @<Zm>Tn/pYL*b+Y+eqEG!dh+#qTW5%6^kY&iiiHRuem<w?!F^e$eb4CK$j1!bKjb5>myQQY1W%F$tjhL
n9Xw$N q>?<kRwm#jS/bY5Z%i+/LJweeW6&K!H4T+6<ZkW&Cbb%kb<au<ZdPP5?\PEQHuZk\B8cX:mbC&a?6dyd
wWwBul LXPNn9>eJLd1uplDc!%?9WZQiNDbGJ&ww/p8^tPiqM=q:k8pE&W^&A#Me4YyP:DM&$&j%iW4c&JS!iWp
Yt9mKp b:8+6tKYjCy1Nt%9Ej*Tli4Ia%VEF:X!TYd6^XFlpEeaWwR^$D\#YBepPi&Q\FyHbZmX1EGY>PCL%%&L
?GdZ>K qht8?jGG=>@#Q&<qCMtS!iEheM<Ii=CWh9yY4uTyc*qWaaFF&6kFD6Y#ZXpVcbj*iib<!88=Hd=\1TL@
#CupZy !y8G+eH:X8INMSw+C+YLuppDl5:*%TGZ#C***wbQX#=4T8=:Y%D$+yTlybCt>1T1RhYH5FjZnR#8Fk8w
QqZmu> nA5aQHq\\da$<$Hi&jGK*cqPF9\d?&RYPMJVpTDN&Ga*dNk9>4YQw9ZmW!iWkj6T:>FXZI:4FPa\P&HB
9Hu%1# \yKdXMcSjn659N8@uN!F$HRACbm@>Q+$1h4Sy*Rh=iuqwaNNebJeHF<MnXcaCdnqW$lS<PqXZlIDh5\W
b@X?B* j&IMiZiKa\%*WmB\ZWDDXG>k%BJyW84:tD^?*nWB+XQ&+KlFYi\^dyR#=QIuIN!%/DS:jAtdaQ+Dm\tQ
i@6RmW KqF/$DHTYFL6nB<ju=^MS5EbqpdenX%*Em:8<%Vm!nN:>@m&kQlRVQ:wdW8B*M#5S68!TcJ9mF9#T5cw
Wn?*B? X>tD5%X&DGJeSi@*H^ba9yj\DQT++N$N@PWLK$<LBb^^&YuM<LFZqmehH\yYVD#Kkdp%e:1MB<u9mWjm
9te$VN DKQpRq@\i8P98N=na8KhKC6$AjJQ%E$$Nq^\yK5A^*acQ:H^QQb/6wTWLHtqK4Vhe>bPQn1#$/M@>5nq
6tWDhP q6cQaRE&^5<Z/p>MRE68JD:Kw#*jH@uWKD*QG@jpkhk:/D*$!d9bpYh6JZwka:hhD!W?!mYt/A#^KXeT
*G!w/k pDTlkAhQ@Q\K^=mE#w%i$q=+>M^DAiR#jPTGjJNblN?k?8y$\/$VT#Z<&A>S^@iX9:Dp:R+:MCdbPL55
?&Ik=l cPXe\!CWe>%ECbS*=84FbEN4<>P1=k/KYW@dWpNQQ>A?1u*G#H9cJj4Ypi/d<Q5!B#:%e4N>cDm8XnZy
H6ZtP@ dX=4ZdCJjhl?hWK+8&kS!DuLFL^SGZX//n!q:i8l@Je#95iP?4Sq*hATjM4H*aJJWt#dk?+:j4q:Z584
c1kEh/ Y:Zwpj9K!6^dhuY>!yP1M5hiJI&<j&Gtd9CkX&F$?G46Bb?b&\^m!c=1C4LhM?e$nFe$KyCNV!8:ZFd6
TL?uwH >KqARGpapERccKW<LTV4V6%=1bEcKLnQb@W$$N@eLaA?EBjtu#:t#/a\L$*8$1GRMZeD8DD#I/%FM=eW
5qEIj* Jk:+9q^q!tqPhTeaH6\ja/pc9Y1^$MAMjZM#eRM$9?4u=Y5EFtqQcL>ThA8weZB9jQuc1@bYk^FXZej#
\WuNJN ma/1N/P::+Tc5W:pX1npS<H$JT9Xd=%pnTW!Tc+eL16?*/>&*bANZ>^VC5+$/%?+iW9cdK$j?w#$?mdI
m?N6u< dAEZ+$XbIm%*wPky<u&y6!SGd4HqMH5&u?LNnXF=qNAPjidBGkS*K^4G*T\<!QEt%W8=eYVmKIP<FV$p
Cj\4:j SWL1A9A%1/<hX>ua@yRn?^Z1B+8VpqJ+bXeCkC<4%%MpFp1Vdk?M4Py!ySjZn^u\H1HSTMPpVq1/F=N4
w4%6?* LYBR$LC4p5E=@ZqHyZ8:q=T@c9e:!\Y>jRb1aMAKSG?6w1dqQTu:CeNDL>pQdQwV8HZt<&=%y/54!!9j
-A<Bw+ 000f2c2a24400110333 Page 124 of binaries1.zip
8^dCbB NbY<5??&4X&XPE<dbK\=A&R+aYnMLFqu4^J%G!TuS8JRc/LWQI??#d1!wH4#!DV#=&9MKL&w1S8!kpj:
9WS?AA =l=!eXAC\E//%ZhnSByJK?GTG6ZApSnppjR%>q%8iL4aD6>TP:GuI::qSVDkRL=SX:#<5Gw!#aI&/Xd1
jS:S!M TNMtFtnb+!wh>%QbHHZCc#SDZ*J5qAI6Zd^JB%M\BKq&m%nb=q5>pjH>F$$?Zkl\B6%iCC>hMc&jQPBc
mPlNT# DW$\<199KpG!:AahC/ecuNV#Ei&XaGM5D?qyP!Jbh<PuW$lHRMn:B8>#BJ<<LKu@F@C<jPt4uw\TyQ8\
I%$kNb *G:pLj/uI/C!9E88\k85E:iNuHc:*wGD#\yF#e*5IS1MS6de+pa8Vd\6QT/!5q6/aX^6SCR\4hEIYad*
iFdahB Z9Gb<TX%uKGH45NQdX^hTEKV:Ep!T1Ji>T4QNhGtaTuc#QhHnyqS+\nW/QCE/<#hn%ma9Fl<kqm19L99
TjN6Rk D9864:!:!:S:iHq=?d%E=A%qi4Y%MVQk<5S//6jtY/SZ%Q9mE8PY/&:mR^ekHqybuLdDLQ1kpbHD?h%5
JHyXKn TdQ5CFnudddt$*6=K>:p8G*pFA@bGebYQSXmCVkAM=jbX=GjPT:DEVnAb9CEDeHqGiVG/tN\ypF+FuID
?/GpPi I<@@mEFq#uD/X6IVZq&JM?K4wKEX>i1%4*9CeR&GZJ1pVN%h4H=ei5XD?>bY8?TaiF%*c<WjkTkp9TjF
Dd/R!@ jd!<Y^&6a@atTn<cnG6IPSP1!SQNd@a/e!\qS=RF1R9*D#a1&YhYtRaNlEl?VnWeC$>=6LjdtuR:PncP
Y+dH<q a>wLHGNCC5qp^pi6Gqa/TWTcS+T8:+QYTty@RnGw5EH&tAR?wjybh6!6mRdmtcwtM=4W#EG?HlXVbh+*
T>C5RR mNHChyyL:JJ/%Y>%V9Xc*\n$Q4lR4@@M%c<85@G=G+Q?jY59p8EBZjEB44caRn@5I/+:=$JL9VW6uM^j
w$W:94 Q>u:$9IycJay=Iu^mlN9E>uCtGb#?y^/\\mp5m:u:StFTm>qtu<ncWM9HXulG?aF>H>W8iLujTI>!4X!
1dN@^^ bQN/Q4W9Gt\=M@GEpYR\:9<yNHkw/DAthuNPEyq\S?Wq#\MKkhFmJqC6I$BMt!CVwc&4:\uYbe/Qm>\@
/>IFRp &BndZ>pe+A6qc^KP%lm6+PlpYN&*$pX!wRYZ=%BwXQCGJ/pQe!6h\tI%%jLNQPQ#A9le\qZ9BtMM@<tt
thbwNW 8jYWtymqhDd@qkyhidX?$<1cLu&Gqlj5t%dM=Rw%R^VyF5wEQdtZ%Ku^Ec>\WTQF6V4L1Jt6y<J!+SZL
Wma:BQ Z8>*K?jVhd%CElV8whcb^>eDZh<^Db5by=8>!qcLiShEMZ$Z9TjwJlGQIB=+i8EMB9t^X51eZjmN&%Dk
jEk5Zk cju+$^9HYN%D8^&Cab@QB!k@F=<:<HRT9<h?acH?+*Q9$\lF\#%n::66N>tnN$@Hpt4ViM:\Bet#Kq\P
$JAFT# @JVC?&t+XPY84K1b\cqmRNHk^IeZH%<?4RM6?nPBpw/+P!+\:nKR*%A*c6>pG*+?9KE?$V!TabTYBdKS
cNm4k+ j=N#/d^45b:yEMi?$4\dNRNARCYJHdG:!ENVP>CM\e##XbPZtC^Kl1^MH9w5y?aXBQSQ6*&@IYGy?Mt/
G4>K@u apPjaK>i>PcDm&pu!FE#pX/j#@&<t!NN&k^1Lc?/GF^h@#Gl<F&nIwM#D>H9uyZ1&*!CX16BD<uM8F=S
@*9cna nGQH$Ypq+9@^/QT@GyFY?t<t\$BnMH<iBEJn$Q?R*Q\>u9HHEApc>biR9=LTQ^8I&a/i@A#/N/M@cBVt
S^/L+L y>C@GeSBw:A@l?+<mwNG+Z+P^iJ*l8J@C5W4K8$MJj\em95dkSX@DpZ>nacJQ+ZmmPmhwWw@l?J&l1J@
X:k::l dp$+#N>Aj&=N&J*J:tn$#/$Jm>%bVimjY^MY@VjRu%5VF4?#NcH^@#*$=>d$h+NBcQVQ#RtHS?$M@Rjt
<PR@Zk lCd5DQ&=PTtmhm:%n/6qWd<D@+eA46J@/QBw*F>uaEQ@jlY6H+S+JTZ5@$WEN#p^qpEHq8w8L=ReVV@c
*Ek&VN e>A<GNMFGaupNPXREIjMPNMZD<EW?hm$^NMAZRu\jGy=FL1@\^+n1CP^peNJjeSebEul<CR%u$Q^t@\Y
l#Jy/+ kwWqcw6F1yci<tlMt8?KlJbP8BIicyFN%E9j?mkKGl$1!M>jD4+Glml?^yiBA@1e=VRmb\dqwumVVwpj
%%4:=# hY8hPNAucJDVLdiTk+Z6mlH*iSq6/wDpKtC$1WP!:K&lL$dQAmaDeZ^5VF\t!WdtetiG%M*tp:!X&y=A
TaWAtp KndWGjNMdybB=%<#1>8V@K6ba:8b9:lj\F@1:CRuBQbb6QP@uTGdqPX+Em>6qQWKqE+E<yeQXB+4L9hY
BP<lkk V1cZQ6%1>PSKRXi+aK^ibR$ReWhwwLD6qZ:Z^y=EPK^Bnm/XBpQVJY^mpnwNKL$RJ^$Q#5bLWc/Q>wFH
1!=<BS uD<4it:/CldQDwqh$QDiwJTV1/TyCLTe6C%@DAP6T%q8#DXLC8jd:#9BHKG*1hldd:8yuF\pQZWF#%B<
\k\R6! Wd1yu9aE*cjdpySF$4pdYX/q5<DQH@51MX?kiDdnFF!GA+eHT%Dudw1Dw#ViVPn1V?ZC46KSSTYdGGkQ
>^J1/J hF5KTC>lDat9MX*J*Z8bl@Z1pmW^RE+j+km\c8/%bEP/GXFSD%aEk<ZK!9paJPP/VhANwt%cN!m?Zi?G
J!C>@d $eH&Y9j\&RcA>q8DwXywPVucJK!QheSH!5yQe+>LDM\<G&by/5MMa?Mh#%Gy\c9/YTJb4i@TRIa8IQ=H
p%@e^C Yb4uPee/*jk+:%ph\CmcRtqn&GqYP$:4T:KLZ&Rwl!bNcH4JS%%I6:!Q^L+BS$wR?QjBXNSkpHp=H&$k
&\wle# qDE*hGDR9pDF+REbNe#GID%wGq9q5Mit<eFBweBBK*EY:p8ViY<=F><<6?KT/<!PMc=Na%Y?hat4\byI
W=4AL# cZ=*a4Sl+<XcZ\Ql<i$w4^BlI#:u$d!pwZ/u\1KWETY8JCVdMqq/EFTkW++*9NM#>\nati<4MB!@yKwl
mQ<*85 !@!X$5C5YH\R^1Ja<q1uy#FLZ+16BiyVd+w:j%K#>6!$m$wM9iCaMCX1&MdM:a6t?:C=8k>X!bpe$&9G
S56w@m 9yj!ELmHP#L5ItWAiwZ%yeA84p+FI^Eh=Wb#V@>&/\nNJMGGHHukk<aJ#bIm?$N8WYdQQ^?<tAt>L/ew
1iXed% +#Z^$tZFF>a@!n<*a*=>XnFuTE^+@y^!?*8h1@^LmSdwE%b!LBeRtc*iME<5NqbhP<@Fl8/lT+5X=JIS
%<hWjk Q&&/QP>DuHtjdFhNB4E\e*DcVC=@KNeDZ4NdN^wQQ8^SVjQ$=6YqWkInic1mYEFe#uQ!6Ca?*GJNjd=w
aqYtAJ lcc?/#B=+=*L1Mp^64:MajZmHP<I4=l\LX+ySBH#</\PcXNA9$Biu?MIdIkFG#GG:JtlX5%YM^l+8!yi
X*R^B/ CtMC#8SIP!RjQ:t*4l!e<$tW*J9L&>h*+pGYumipwLQ+86TJ:ntqlFVIVFN>V</EXhA=u%8/ldWl^KH:
u5%?\l +uhD8J#P=nq9<q@aiP56&XTywe9FbdQZYcG9u1SL/B8\ZelXMFc%1*l9IuqGwmc%4q+Y!:TLm<=HBT8J
lGYbVB IS9\Z5kRj%d8!P:pmG9!>yBppRB!SVTt^4&<?inaWhtNNIMaB1SdB9t8Rq^VDP<m9/*?dKL1uTc<XBTH
+8ET9K :RIJj\B1WRcKWYWySPG<P4%K#>^#nC<mI8T<yN5FEQj*QhX4!Ww<y:m*dK:Qun6c$pMu:h\i!BV%>TEF
cPBKSa 9&j6i#8Tuy#@\B5wD?%1M&*9*:$C##e$<4>WPMFF1+IyJD:G^QLIPw>cl%yXnb+d8=YqN=%kpR@K+lqb
NQQt$h eH?q?$BX:GbQ1Ynj$6hMtaT#/6R:PGBjpS$QC15RhKVj9j%nVydmWh@4W1w<^/%+iYV%Z?i*^&1j&\<X
LS?llm b9baetbR6+Y5MPmNt<ypQi9<PQ#ljnZC=@u^SXYP^\:e5pHXMk/Qm%6##HR?9ZMJhikSQ&L1XMBA!ZFd
@@n%yE D/$4kpP!JH*h#ES=4DNMVBKi4ShKcncLcD%&E#w9eQdF+9W4D>QZEL8+Ky:^T?6yG14TZV+HLqq^#u=V
CQd<J= ine1<\qId>c=9MEp+F#ZlRQk:K5T#ii>yX?*X&lZ=#?eT%p*=cT=bBq1*9PkF1q*G:YECLnIbYa:?i6t
LC<4tW Z*X*Z!y^Ah9bBqeuqnc:YC+&lW+d*EShcVI@JcqmZ=yZ4leG%e!^/PXXKLb$1:MD%cjQZa<\MD?MKtNT
T>$@WS QuV#TCAQuhuK+^ID#=PSElTFSL$Ca+4y9KS+<d$VqPb?&?/=L$<Gh%j1C5TnThRK??NBC5%\GPm1l/RW
mZc%TX !y?Gu%cTu:DlZ*iF/CcPNXdiJCe!$L!P1=i&!=Z#XwyN+mq?qy?!q+y+Fm99*H#AkP$XHLjHly#BZ:qu
m%Fh6N 5PDlCyd9@IYEm^GWqyFNMd4WKT*>8WwEJl8Si861G+K#N#I<&YawK/LHpKmaK#QejCG!uJcuul>::>!!
QLWtub ^e8<Qk9SG&WiaJMtNIP^SPny=4u\m/uyEVJcm%@TL\qb5B=V>l4N+uGNc*qZG?%<^MV<uqnLwNE8mybc
Lp#SRI np=ZLQ>Tl8mBiAZj9yt=P9i:lYiu=H*uD4:Ap8=pjmmH6qw=61N<M^nA++qCS:L1n=q#=*/&TF#^M!Q%
@V:w&b m&Xk/&jp/!BKy*BZ4^+eEpd%ujEb5ql=q@H8whhA>5n?*k8blN!wqNG=kYqeW18l1!DF/V1!Na1$AtjR
IdKTi& RdtSXd^STiF!X*t%!*tEk89n<>uLCaGIZ#VKDhpPJ#/MGuY#>FN&d@hE<ae&QEP%qh<YP+%<h+dmDy<R
lYdY^L LQdjV^bcK*>&I@N5<XJ?p%/aMiYaRQ:e^h5e8ddTD=Eb6:M+uiCPcck4H?!<8I?%<tl:t:@65yu%Ec/$
k=jV+/ iPBnQR!NMDK@^C9^?e54ybJlcqQp9W<JPjI4q&6LJq5t?c4^ynJ$K*ii\PJ=Vy/&GV&eZ#F95@k=Z#1N
K8tRWS ^bE$yQd^QTcGSVhR=i=l65%M%4p=y%m*SecFMthVG=</$L/449=T5W?Ypy?E5b?pbJq%lEXS$6e1^l1?
CWcjB\ 6L>y%$5*\D@ClV\%/TnCJE>6j4FH>ZpBV@R6J9=mSD?btZ6R!AGGlLcZM#Ap8uZh9ukDKXit@cVYtHZ@
TQyM%L P*e=wXNVyK=jDKj\y\#mAC65@9C^^DmLb<Q6\QEQqRCIlN:a<%ZLF&WAlZjJQqPPSTKJZ9GAqiy!F&cK
iR!hLS 1/t?==S816+9dwSu!+\D9pP8eeK@SG86u/I1!F?\nVdCGGid#X8#=J5iGEF>mk59w>>$PHZR#>i@*68A
#^t5F> Y6l#Xy6mawTJ:b*Cl/>Au91@Cp@1q5wJ>:S8qL^kI$:Np!^NqDK\4bd\YjJ%VGpFAu!b!F\k/CD$=pF%
GE\jDR IJCN+wnwCJdWbybady&RpD=b8F\W9cAi9dK!+Hl9Sy$h:5D8B1A#$t58QCE6d!&>6m\4*58^9J>V:k+u
pje8+% #aRyVjkiG1Ri8ZB9jy&VE:bW>8/t8%dtRC9cXe9A?iXhnu9RqA8!EDe&nTc&=GEXE&&8hd%X%Ge=V8YX
\X*I/p hVYphP5T?SZZ!F68iS@P!4&<w=Je>NtK*XF<RSu5cawedJe+NFL8TePYTD:5uIeFnLw1biR#B><NJa*S
^BAutM /KjM!11lC5Kj9Q8HjTu8\IF44M6d4<j:tA8B6^dWEtpTqLZ/tR59!MVy^FTHe5cBqhbQY1tc^98k1RuK
mw6@:Q #ntF:k?@uA/j/>Pcy4j&%GtdVmHMG!VeYQ61J9i^aS+M<YTMbaN*G/Aw91daBNw^ci1dI9AZim9ty?8:
<5LDT% Z#*twS>CSB>ESdGCq@P/?*^^uyP9yZ1i>ljLnjC:M:d&>q=a$c&im^\C$:y=8mG^WqMjcq+t>+qSTqI9
-AH>^L 0001d118c1d00110333 Page 125 of binaries1.zip
newhkp TGkn1F>>^TbPep\6SC**/haE5bL1b!4>GDiBkFI4?k@!bC1#:MdC/464#4cFZW$KT%>&w:tiS%PICw<=
t8<t$Z Qh+>nX$FA$aMZjR=8\L*cH$N&*NBedA>eG/INb\/XdVCBGkBI6!^+eFMnPda<MBVMYKkECMkIQDl1m5l
\VF4@# e8h+D@1Q!?D?%\Gj@@&M>Pk@L19:V+M@PMY@BH>\lH<c@MHlh\4?:LBKL\d:#!a%Si?\V8>j5ay@k!Z<
=ma<!n HI5u:Q\/8eNc9Z@B+9+th4VDc4%@^j=NyGCH>Z4@mpZ9TPXF::Bm:%?\YKYh/:9Dt4%@^i+<<\Acm@pH
tB#c&a YMLP:>=a:D@A+udYFjaj&BZ&:*V%D?\K@#iBIC#lj+H>B*cF^@/N4wn@BQ5*89wHhwZjtX!P^1H?F>l@
Wi+j?Y aFh@G$uC@RQDI8#Mc$jn5Q>E/J$Dw4l@aFm+uXeHS@>^atQ1D?V@EE*/\RHeDmeSMH<NJ@%?!8MjlEAW
mknH&F =9<SA9<XIZD#1Ei*:Ni+aGu^XdXFh6>XK4^S@i^LDLVY$@6><l&jq:mWAE>QGF6W^8w>hY1WJqQ!Y4WE
+TNyMi d@9enB6:b+Gu1*Bn:cDYy=SLLp@ATYqt:k?db$!ZY1>Wheqtwa!=VFhRZ6$R\hnP$QDi!>XH1&?y$M\G
$^!Cpd ?JB$SdllPwP%<ki^KGIjD616d#&i=ML<kAuWTSFC^nCW#^Cl</uLD\uDS&!jmi6KuK8Qby/nSMT8jA\Y
jiu$iq A9tM8L<Cu&be45ApNXd68c+SRlEt1B6$+/>*Z>Np8C&1+<wQbLCHcyGkup>B%:9Dd54lL%t:n1Wpu?9t
*GD4K* KB5=4nN?L/Ja=G=nEjMn!QXSjY&L#u5=ytQ*Pa+SL1wHV<pbYKKP&hcaNEB5iWi#nn4wt#E\Q@Mm+*1+
a$H!1& PWEB^jeN!GkiN/?^%#JPn14h?W@wy=1wJp/^y%8i?yniP=CpNJF56n@++V9WE<cmVyIDE/:\tk%D:&8j
HARCn? 46G!1yX1JHPTn<IiXW\eFae@GHW@bQRK><9::i?bujqnGEIuSlimhKcWt=%<&V%m#SdpMy*ZZKEMC^>&
!VHq1p VeQcN&<LiNSih4n8wt>e1yq8h#mbH<&PCtYud\^WP&/\TN::WMlXLqdZAW<R9In&#B*Y#b/M$D1h99LG
=uQPI1 hYImtiQk*91bWb=PF@JB%@cQ:kLb$KMW8\/#cQW::jMH^=^I9W\t!jc$cHCEyeV4Wj/GB/ahwyV&5j9W
:6PI:& #>K>kcQt:cPN%!S95wBRS#%eeYdRdqT9Ryp8W>PLZilS1\h:4M:*1NiW/H8^V*V\n&bti&LijtIKMZD>
A/Y5Ck ak=hPCCZ5Z>5:5*BWi=iQ+YLVIMQ&*ZSw?e>VdD9Q6ZwbqR&>nTPjd1kcKNQMIF$S:!ZM+J<Yw&HC9ph
1ZIJb> eY!@9jVyCS@lqtBD5N@#JJX4wcb#HYdJ#yyB@dtL+%HJi1885biaKpyD9?\Z#Cc>cB!>1KpVhT??\19/
KnFF%t GcTyPi\q!$aT:nqqRubQ&K5H8Y1YHF:MwLYbw&dQTwFIDFhZ=QDT8QMnGnKC+XTI8^e%+=^F?AN#5ta*
S=>h*S yGA5mi!j8#<!jK:#Q9bNRnXk9QtKHK5/&hA86ll%mmk:PXiFAqYu!=ST#Hk9c1TTuup>&Fhj?YbPGAiM
iBTy&$ n=S8hyYpl=6p/Td5T5lhMC$TdS$&<je#q%@R<IIQFBBaFtDTydl4&b9Ty9yb9k%NA/ZJ@EVT!kF4Ju!p
:#%6\T V*d/G>W^bh*4hhQ6=yH5aab/E6eWT$RiM$#TwB>GhweaRS+*HAC>$D%iEZ=Vln*$hH11/klt!<t+hl#K
$due%k ZQbnGKB98eZB8M8ZY>JEntK=KLbcue1t4M:ALCB1y*+yd5PdI/?<BT^8:wq48D:bNLtj?aGEau^%Kaw<
94qn9> paGT?5kiy#&&9=G&!Jlc!L/@X9%pca>#$ql\wKI:/S4ul*B6uqR+KQ@^Qtpk++Ji1nudktkEjY1=aEa\
:KA8y< Zm:?khKbn>aZ8Eh*k/yCL&T<yb<jyC!Da#9G/!h$Xt*8?yGYybVPA9qj#+9^JV+Q$kI1b?bt1BjGk#wL
&=Al%: 4tZ4iC&p!qZ/L/Ic:=1&&Hel4d$AH!>TDE/MBL%lk>+45pDM5uSjIpZldZm1Byd:1Ej&Y<Z&:SqTJJT!
!J^ph? 8#/5=bqRKBWC<XiNM*n\6Bd5nYXk<aEAXK9V&SkpGIh8!!XD!tNGSy+KKLGne<?D4t9bYB$<JTD6:%aS
HZ\w%n VhB=9e^Y@byXB#:F#*CW$8MlnTyD1CMEd@wi>Zu45@@i%X8hK<q&e&N#q\>+Ldi\b8$>:XNPWGAJd>N<
:H9mEZ GbE4+S!T4S+mJy*#pJ@pq1\>LjNAmMW?<*d<NhLD8!NT9>k>Hu^VBd+6J!W$i6\\m>LA!+5cnK#TTHdL
SbSCm> dTWk>e/CPB:iql8@hAW>JymFy\huRNCp^XPQamDhL&b@eh#IQVIRp+\5LDqwWc=?!MC1$QP&\dY##+LM
ZSic&Y BK*WLKnKWDP8Zc?8I:l*bZM9&D5NY?iXdHlNLL#Gu^w>JL>+wanZ+BGb41tikYn6+<^b5S>4&FZVY?uN
+eNJ/d EVq=<ipI18XASDJ/nD*cJ$yR?^$Q*Bm>*K*\:FEV@jQpwLP*CQwRkW9Y$iG#je+hkXp9&\h8Jnu/ZMG6
VTSEXN 8e*wqnb/Z=B&P\E$H+>lp9e6p4q><LSY6=IhA@DiC8>IZXB??/GpD+=Xukcm8Y6>pKptP*9bWQbZGw*b
TEd\/E dwXpX6Ih@ZkDEH!\R5R@*k<h!&AuRJ<?%M/91u6Rh:#NQ6^G51/L5iYC^ARmJq=TKCK@kJ*H:IN$48kH
8e<&F# CV*cX>l4jik6tPty\EXI86RZ/adX\y^H!W&Kc!EeVk>eNKLn!%:&C6XQP8*hG?9nKZD$+JHte4!JV%@>
n84mQ> ^Ymyp*\<*yhP9%\TG#e=5q9C^?YRXW\yX9?EDIQu8WDb:PEWlw+HeDI?ha%\y:\lZ1^!La*VR8E/5*SM
bLdb\n Wb9M/bH4=h!L*8CAwE5Z+EXy>6$j#ubXKT+^m^^#5h9d>^S^d::@bIRe=H^5e5IXVXqk8QRd+cq:d%\$
/hD#\& anQ*C4dT:TIwZZ+?qNa>F*eDl?&Z9lX:&WC?B#*Mh@#l<DW1#G/GC45YiS=ZwEmP/VC4LbQ1cL=tjQwT
<Z9R45 \Di1//lXZ?YLqP4i&BmSwwYYmWJSSB!>SSDut!TV^jb8+ZmYD#W\nT\wwQ=ViFS*p=1B/C*L\+TGy:a/
kcB+Jh ml=Z496F:VPIm:kPju&kIwYkRZqRD<C<@&4XX@+?8tLVJY>>e^@&IYQPk4KN^a\*Np%DP!@!!GYFE^<V
D&Sk\+ ?KM5u:=4b<aqZZSGNaYSZl<\Vp&5ZZ?H9HP>TyH:cmDa/SeXB@*Q%$#15pej9%i4HReCl5j<ZMj*nMW8
D9D=Vl wpcZMNH/QYd?@Ab!>4F?+HL&=TVAAKT&@<cAB%$=>bD^X+PbAjM?ubP*XV:HXpjR6+PmN*Z:?B@e*k!c
pR=wB@ W#5QMt?B%B^CdkAX&9G%<1Aw9Z:GLu$1t%>j@^!y=YX6a=\SQ:=GdGq=SZ@6lD%FJHcX9&Xb##YYF6%u
wi:*8J d?8b6*yu/6HKqH>=&M8S!t9F%Rtq@dWhp/=pM!dW\eQ=a>Ba&?Qk5IeyZ!NAApCAB%Cn@at?@\^dnwuj
dd5#HQ AuQN#P*d!CcPl=H5eLY%jAM$X*DHYDpuTG%yI11Qwlcdd8?PWb8be1j9h@G#dHI@iA6e44w8heSZt>pD
6I+P5e DFZw=wLE>m!@>I%:^ipX\#!@9F4M6qm1dCD9dd#ARiwnYHN1RJQqG&wdLYJcDc45%VtCDiR=<BIGS>k+
hF#uKc qt=D:4uy8L9V%%?Y%ZDqb8^\aB6b$+&^A%aF*!cQR!+b+R%XiyhDAIQCX%/\An#cVlw5MpCKNR$?MLl#
j1bINJ 5HN1YQb*5EFFIJeZ*F&:@I1:^wIAPFeS6yL5V/<5S=c\ky#nw$@dIDN&nB:F4\ch6b^Z5S1VTtJ/K1bE
!6I%1a PRahJeuYI8%R*RSj19FF+CwG9Nmq69ReXD*6#8+KbALN9b^5b$*j%ESL%RyP%M54k<*FP4\qwn@KkVYi
l6&LJe FL:5lw><pVLtbHkIbKYN=D58$E!RQqT&nV1cu!%EW8j+k6SB?itWBZAEF%ycIqP9Qk+$N!I=L!#:em?C
<X%Y8< K:$+QB<K@E4\NqKcL^I*nbcIjC:hJ\kced#CwA1:$!kdHtnc4T>&J^B*cbwJaB8#i5/8@wSYkwR*b9PK
QPad^F aR:\nt@w=R=5S\KynM5</1Z?^m%y5KRe9TGYK$YXqE?=mh5Z4RWEu%NL!De6&W!nlSMk*8+wAB9VVQu!
FkIh=W iWZVQmh!5Cn>V9NQw9?+u5u@#e\Z8K%L@y6kE?/@YPeH>>M9*<&>@N^C9m>?>wjm@m6mE\H*q>kYAj6Q
e&$GGY a%8@9bn>/ZWQ@>h*a>\@=Snl$j<A?#epw:@P#:pD>t@mCH?hwHMH:N?<#?N^Q<jm@+bWk5j@HI5n@p%>
=^6\GZ Cj<Am@wd4PLQ5h5LwP&IJj+em@td&PXjJ>deAj5*VDDCQ:C49+&dEQ/Baj$hGicQ<&6Tj!D@y@kF:n?#
lD+QpC VcIX@:4cEj4*M&@?tNbXCaQ/@%</#LI91u%@A/Glw:nXZFKD8aFt#uZIH1nn$pXZN?MyL<\tWTS+46^P
waFjBR ITi!:Cd@iMml/\JtC=E58KJpI/GdT^!SLiGQ4jt<=6@tlW%eaRK!IdwFLN?+VESA6T/w=<>h8ZWS=u=Y
ltwN#F 6/M91dJ5RC?&1H!EK?=n<a9ZaeLThPY8qbW#y8jYTchql6hA#B@:/t6?#+SS?ecEaY?<hNV=aj9AmQMu
/&=NQE Sb%jtVAmF#TRG=T=d>\b5KHMb^k$Rt?y6*??PJt>$djj8=$mYti!=:JBIHW$XnVlp!SIuVTFddwh/T<8
:G^Xcc TcZH#TCSa$yApPm%/ci^ZpVZYi&EHldYLyPQXcK!ZS1QFZANpC1b8k#t4q6!jnIaRRQb:6*e=PeDNlT5
Eu?QBb cPMqiRQ^a/d9kA!ZbIZ%=kQNVNtT8k4MVTNII%i\We#LZibS@Ya!GM/>/kb%VWI<hqnS<#yalTGk5X!6
TCjttk i9Wq1@FM&hR4CqHSBnBKRacTR<?GaiS+DAGQXeBB=A^N>YS!B5pyB<+bwcaPpt!9Vnd\uMbw*4$*ZXai
/c#+<e kCwZp/u<bAL9nlKT8B:D!*nc!&FX#u&wi#YKFRM5PA98Ic</VA<:$TY!Yw%6+6S&GX\??9GZ59nZl\VE
CMDdMQ Z!e6ua+6/QelcLA#Tt<wlC\e+\eh8kiA5ZV1E@8BX&BbM5C1ET4TM:nqy6W+lLt96@Qh<Tn4Y&c\\pFW
bF$^C/ EY?GPJCBiNjM1*:mS9EePJbH$1dXMcQMt?66w\DIh/pyQ\aTw=/QK4JnPlKl&*M*@Zck?YMCQCS>d#bw
XViq?N BiA8=I:KjDiF/P#\FywBtEpQk1y4btAJWidDn&<dXpaKQhBVjR>SDJ!KlVEHRhyWH8yFRjP^Wj5ebIhF
IEEDy6 TVM+c!F<^VX5D4?QyW9w\StBGHyDk&HhMjQ4n<au4*QKZ:/&>Qq<YZqDEhQma@\H6Y1Y??aN\P^Z<8W&
DTHcQC cqyL:aeK&6TpwR^GV^ckSI**:Au/wX%<NnLYnZaZm!\WpGu/TKB\XqLG%ZA9%%8^V\5:h<<>A6Ib>BSt
CA%E6/ VYeqdpVLIY#MSN@^6kqYTkK4klVE5ni9Deey!l8bHL*i??d>\EiH+JKe%8!ta%iH>NdNu6peqD$$+G=b
F=e!nH J<*!VHya*e*/Me@Adl>nMYEKWIjcPTB%tLH^PwW*6T<4?CbiJ\+tEJj9uPtWVFqdd1!pyBe=jSR^EJ*1
T?eVY$ /iPbc<*j5IZW1X!N*ZPpLnHmtF!bmEy:wG6<?pdqRSMBDu^VcZYYb$AT8kST5uEjumVDm:pXy5^pQjQa
HSp65G hP^Ww66/8Wy$?lQ/jCRbGC6\K&:#ndHVMdaB1G\VQ>ib^Nj:w4^n9H1jewFlu:m#Emc:VkHhp^a^qkdy
-A%c/a 000be7c44f600110333 Page 126 of binaries1.zip
&Eh=/G #\/XLMq8:Hy+SZ<hhpX+V&me?dqnb%dT<mW>bhMiNdydel:\qC/ec<8e8y$SL@u\6k$44&S<<8tE/#Ip
tmu\JT e#X*45b>FLQGK&kLk/\eFCHdbIN#D&!jpJT5VSVpw:&^hRN\eGE%IkNP%CbwcElCmwJQy^\\%E#QIZQ*
DNIG=5 kiK6qZNn<8:hJp1uDEk$*G^Mki%i&KQ/^m?i1/FRb=lFJbcJ:6bX1?Eqk#y5TM4l>tkQ$5\8#4PlJRJ*
quaTQL &?t%Ejwc=y1/J<IHt8ThB?%=WVX9#?uG6FHHGqlhk4IMaLk8d4GHn6DP4I*44mQ9YNdqRB#q/*eqQ?yE
j%KD^N SL\4VQEW=C69tdwHNDiQ5G<y=TY?Fb5T8hkIQXS+1:p=J@%qMmqjnHiiqYbb+K<*\Xa1eTky9XNj\^pd
YM%*:L E!9FL>$6YjlKIYJaX*SVBMJXy!tQCN84K>*C#cy9*5lXwCDJ6enAM#aC=KAW=HceBanwj@SeN?@Kn8WY
VX$Be* 6W=&\CbWLDClDyE:VGTBh!Aj8B1i5FcF#PnA1BL6u6JuI4u$WNZ98mJnTWYD%mn9!%<mGX^XhDuS^!=1
N$q>6u A4y+Y&41Z+\LyEy^!wDk$#Xt#D/+@lNjDH6*5$QE??%dPJ<ch58y8<#t/*WPhe=<Bw>\R>nh/uNSZXI#
neFeq= 69e6Vq\^>&J9HPJ@!&eE8AwK*69h%=HJc*C>Ri/i^CSECFnYP%KIF%nH64VqYE!%t1hK&jCySLcqy@hj
XLpB%D *9T1/dZY8:\lD9ReE158bVG\j!VZj$nY8tqSy@:W+?etk<t&%@l8%hVI\%nDG$PpRJttFXnl*RcmJhie
IM#a1m 5nImW6<P6qBFIm5%L/jP*dWa66Ebi6T/i84q!19#l6%KVZc=m9t?FuYnc^ND@jKqZHY?$N\%SSpqhiqK
t@YBZ: 6Eql4KlYh1/TFS@CJ=pk1c%ZJXHK85C8&K#J*elW*9EMKnB??$B6^&9YKqjb$#dK=@XnX$kdDAid1$uN
u4%L4G :J*q&84/hkc*&Qy9TMFMdTedH=wldKLFXA<?L6Y/=9e5S1Nke&^6^4uaq%hcTCY?b4<m/K:9W?:RM!NV
tCWI9k $*hS+J5?u$RK?t+\Z+uyRuN\Y#$XmntQcc:9+YQGBdwYb#W5XGH#A8@/uSyL^>e:Pdt>\tppml@BhWmQ
Ma?Qmc %c#aQB$1WllQ8NYRN#ELtnEcC*5+APSuMTmX^+DFua6L>m+iHi51hNjqh4<t4=ZZY8t@XHH*jMl1cd:I
&l/idd ^&m>TkqWbwHynbhp=9*$I4Wa+H4\T/&qVyawZ4qN%kDQT$GKM6mVS!W?y+#hdF9l@ml<4Gcy>eAS#X**
h*mNP? JJMu5?8F&>%4IHib>aGaIHjZW!GMByjQkRNjL9A&#jGj<TYc</pmJJ>jt/6qCYtLGZ/>tY4mDZ%nCkVM
4I6ET9 ZBY:RhHt%ZNMiP6u15Bnj6!L==eP/4q<<WPTB<=$Q!/9j6LT&uJq\CyM1SQpNuX@p?Ftq5t^JTZHBdH4
I+yn$* #FGV@mKJHNc*n\*/eWQikcy+=@jKj+a=^w6\jG^^1iE@K#@l:6i@Y6K8T^QYjth\bnn^Ci9yIRdJntC>
/%nQdG :BCR$D\mY5S*Nj*>DQWZR:%NKeHlX!WA^4bjcwiB4PdPi%KhtX6w9aYj+M6+dX/$h8Fy>1YB/9TJP<5j
wH%RBT A9q9GyKi^P9NJhG5pt1/1%cA+M*NXH5YiQw/lMDm&?eT!*!@G##D&H:+YVQKiYqJwn1jKZkt$QK<=yCN
y<m?Ch LA8#+iyeZY1QwhTJX+*D@qwnuykF&SNA/QBej<86&Bw%j=$85Vjty!b$GSlup#cLYeVt%yLtEFjAc?E4
Q!w\d< @b5+Q:YZHEbt<eLu>WYP>c$>>BBkq>:NIJ$Q85PSMABb1:Y*QP$MjiuyD>VJy:@QZ9J\<RX5QwCYQnMA
SD6Aid RdA\eYA5l=XSJZYkpaqS#Wjeh#bHJJQMa\i8>@Q4D*/&1JDn%Q8cVVFKVq&=ylXKp:V>8qyMi=d=@:F*
&9VLm& =8FW4t@jq&Eb5k\bMmYb!dDYjh>4ptTibballe\lMt^KdjM5bJdKQJMy1XVt#CGJBppITcmpW96N4j%:
=FWn8k ju6d/:h9^*M<#@9?<j/%nw:8e@t8/#:Qc#m9#*YhVPGudh@\JScPY8w5!#m@a*cjT%TZXBM?#PkXT8EX
alt5i& b@F&LuS@Fw&Whp?dhq&+b4#wbIE&HWS*Aik:HMCEXb*NMDVM=GMT#VS5iHKKIp::B4%I!MiCqHHGCyV>
kB<TFF IS/9T1+I!XJQYj:blj4=pm?G@Z6pN!bmKHKqKkB1le=4Nb!#HqWT&u@w^qn*ilkP^kT@G8t?%uSVu*F<
nJ!u1B MJd^yGhw4$Ad/#II!CEZ=W>4ihw+8DamkICLlpL></JW:LcWtnt9T+W$Rt:GM^a1Hu*he*SP\HupeIG9
<55NZj hlVVFE9Sk6?<//DkeMV#kmh#4yNX/u:#mDNVDHStL6@H6SnAJB=6b%GwJIcylI&@P+kycQX>@4RM=Tmc
4pFDVC Cw>S\X?9yR+wBHSqcn*t#YWq=6bFqFH::hKyM@tG==KSe/Pct5>XhMhC%tSDB5GFbVD8JH?#=jD>\G6l
F>?V6^ h/S&Vd81+CH:\%hWFbc1HpwK5CMM/e=%td^hmQ8W%?jlbm/4W86:kTe%cyi$#SlT&QJ%5wEI\/may8X^
>F?+dK wEJ1X:XKwl6VVq>Rcb!Pt1=5@AC1iLZZ99=waiP/k=qKRXY\eK5Y<Q%MSE:>k=ch!l<?h$w=/@hwK+@i
6AYtX! tA9Ttc=A8pK!RWY=hXt68<=Ih\<E5Dk*%6YdZENeNy4NXFQ+T5M9G$:h?L:H+m&R1T<8i+KBZ1CwTZD$
Ja&Pi& 9h&/Qc6HlDDpbGNnQc&LK9NStY4!mqu\W+PPLce$Pnic969Dhi4+wipE6bNi+w6bVyMV:>/+ywb1*!^W
iALhQ> <BiQ1m$>a/%qw&ZAhFQckYI&4/*h+=kc4<cAb*qEWAC%myTKd1JA4+cEe/tcVKn+qK9aYidJYdP?D//m
M:?5qA uNHlWk@W?F&Vt&YYNZ$yVjLCC#ZW<=A4RZeqQJGL41n1aHuNwKGT/qSpSTJ4KV9VN=R#+K\*=%a5cpH4
MeCPPt LhX%t@9?XRMQ#aCWGiEQM@y^!+nI^CPCu#Zdt?In<lbK4jl<yX:Ve?kQ8HD:VMhLaq<nMkLwYR#j*j%N
uLkciH hNGR<WPFEjZM8@Jh>^N#1QnSmH!V+mViDua*=u9KbbM9mw@RliJNF%5RIcMMFG<a/:^*Ck\lljT+DVcp
I>G9&j di#R+utAe%=5pC5c%TBduiG/#M\jJ#yVI@:Tk:>*np9cR@mQbw<nXR^ciuaD4<?c!um$Nd6aK:?&>NFG
qG@B6Z Z6l#6Q5tua\y@bJ!@\I#4a\H<wLH!XGYQliFF%K@Ch1%P=$<c6&lYj1k*P/niJu&LbPE+@w$qS#hDWee
dnP<5V FF?=P%bILa@/1i#9qZS9ubKNiCEXLcK=LJ\qb6>G^iA/be^HY?mp@5apu&GFi4wSPPVAPFuXYhBBSheY
G@Tcp$ :@kq8yVKKhN8#hRw*GVWL>kwMw/Y^p8p4M=+>Id5>JJHk!ZWwiZKtT/5P+utmA1W$GcM?:^VcmC^>lEn
N@J%lw T9+ap<jE&5:nKE5pp$ePt+FPL<>NFL@1G\Xb=>FLdk8>JntD%!/?!u6>@LBWeQGV/CPe5!5<=$dT#lnE
+nSF?I IcWSM$#K!AE@i?%A?\8n>qMZjGkbeR+XD6M?ZkYmK5KTn9tin4NVKeWyVT1M1/16EhPyiuV4TAtYwDb/
\1R9!5 ?/l%n?:<k#jP9$Y8uut64LhcJ9++^:QInJy!Vb#/wB<6@$GGKE&n:Hu6M<Yj>CXhLSjEDJYu<jMWIW\W
X?FW#* p%yTWywn485!%eqTQH+$I*pQbdwLFQ!tM$:R?4@Q5hFyHSJh=QEL=VF!P1&Gb\Ym:>FSN!YFNhEJnPtt
/mmK*> icPeVqG^H9dVbKl*+\&l>RRn$/\:XpNe/aQcqDR$Tlmh+1VE#JNAYk@/4G/ZLJPkmIwdYSY9qR>@/ya5
@eV\!* m=HwY$$yt#8yPuW8l1=JYH/R&6F!Sq#qI>hCq*/pWVSi%1jIu\4VJd1T=HlMLi8a4QAX&YbhkSVX#9QL
b&9nh^ JZP/IEdn9Yi:I!M6=Tl%h>cK<TJ!=5uNDl8VBNt\iQd*\1*9:X8dy1hMapiG%EMP//8GM/9\Vy+E*9kn
t4u%JT bnShh9c!$9b>>#Ec$\<>dV?qm^LPG#D*CP@=pNReuRt!$F!\Ly^KyV&y6:<?#>E9wGAlHbFypLkGiGXj
RcnbP? G4ZjaB:clidcaHWPVd:QK%=>BIeX>:8+u8pct^u$!mW+k@/LWpIHX%m4VZ84ybwFB4GkG@L/TKd#hLnt
LJG<Ql 6hjH$$*TY8dbt=XuY\51Yc=JC?kZZ51dSe:WlAe68VJWZR!X6>XF@TbcQ>I\wNwlb&u#FGh@*M:lt%$B
na=Eh$ +WVcVmE%VW!S$N=VD*N/p!lw:iP^MW\SiA@5eRh9cbh\\JSHdE@6i$cJIC9nP!=tk@=DFwiF#I#RWnha
dWYXjB An&!nH*5dlYiLlW9AMXZK$=dtEwWR<Y$8EC1L@QyujQ9LbT:6R%WL>mNKicE1ped<Y4+I/Y<eS1?H<D$
!+N>#d ^?e1!^d8q^S\8i#&mnC:d=<?lk!Jnw4h@iW*naCI^=y9%ZX^4$Z<Q9Zy%^tiw#XdK9>!X:IwNiRNbli@
Qw<pP+ cw?!bi&LI?EClyTjVKei^$FeN$/iH:1$I!q<&kN=@1=aI4N=S<%6!ybtb#DIZJwJu=4n19JKCV%dYA+c
/%DlHm P45e\VC!M1nyF1wj<*K$@LT#J4Lkh@QY91njE1:1tn%kaMlk%QZItij6^ui<+bB?e/>l9wRycWBZwCK!
DpZ*PA ZLXq+EheGn\hnam=Mh8WW@BGQNmm6EFXJK9%pw8T:%1n+PNGYcDJqjF>Eh$h%TcS%LXmhV1SMD/Ea<!Z
^9X+5H <4uyui@EwnV98VHV*q/WbC^4?iy>6YejheH98<YPyEdy:EM$D=XSeR>>V*=+*#:FkdX<q$&H1J?l<8YX
d!6dhT /qnC+>cXDy/E8>y1nKa%E?nAA%:W6RHW&k%4%u6tcY>j+#S6at^pjdG*!eT$GELwH@9G/w#?*K:!n4Y&
%AAwTG QPK!X*&tcRAD&tJ9$!t%Nb8JqEqWKL>1najWMG8:\KJb?\ZuPkWZib^$hAiFC+8jkYeX/1!I5JQAatXZ
mHI:$I t:^5^QYYD<H/*PF:wy&n*6*aY/L\Qd9@9NyMG>lCn:*ZBi&cTJyw4Z@d6#ESt>QYL$<+MVY1YuVi^1/F
kEd^JK *!nA/AQ&W4!w86*njaHw1+GL&yLT:pYiKbWZG\$!86:G!<9wtm@Z?VB&lqcP:>Di<H?Kw@ChBh^yLa^C
9G*bI> Zkk=p6p1?G5Bt@?dq&Tn@%wRB&:1H4iqwBWcB<FN*SN#pu@QhG=NKSP4:Q\:qk1T#yLmaNkCbFK:?H?&
Mt?5He ^YBIa*^aAk^d$9i%wuGwj:cF!GCLPQR@&=JNS&?>9*e:^8Dj<6H@1wSEQl@>J$Mui%kA\JI+uwpnWYaM
8:by@H \GM\@=?u?!ii#nI*c+C!:u+<T=eukhjyY%/IR4QDKthe^C6DJXyX:489BI#+cKlP&qImWX\G8IQZt6kw
MJqk4w th^D6iW\P^TuH>&Vdb#D6XSZN*K45ykIdpV8C=*:TpNX\WHh6p?XllL4Z8=BI?P!iShieH::9?:Ce:&A
S+5m/N WA4q:I#eWiL^ah<PXaY!:yebSyLI\&i<iY?ejL1YX1ceE>ZbNZ^mlJ$ihYJhDt9dJ<Zid\\/aGqa<qh=
A\9i6M wV^iC$wt9hAy?R5:hJZ\deF8I?AD$NmM/%=w$KB<iH!?&?9P98G^C+lcZX?b*5YTw:%%Wp<QmKu8!H@C
yTFYFG e%&IVjW:5/##KVaGR<Zl^<&lc81QMAuV1$Q%%i!#QDTW+6cG@e1Z%DCK@d^VWG9W51HFIhtb<^5Sy%=6
9uL?<C dD^P=Cldc^@W6GNZ^yyTPTBd*A?#M:^#d^k9ZJ5&\GKT##$$ibIRqTM*<1DLa&Vk\e#h4=E?Qw=D6T$>
-AAYYl 000137ff22500110333 Page 127 of binaries1.zip
h/wQGA Eb5WZcY5Lu*@RZR$!nTenW:9lJEaquQM%@SReJA^G<L+a+AR4eT!X\INa<iX59dY\yMPD=VW44Py84#Z
?^n6:M SmPZZ:G#I$?=68&&M#=4SLn?N9+WNTaJ%R:M:59Z5hBV<Z>uiHh69@cn>pH:S@+IyW5/Ea>bn4=peH^:
6XEEkw !Vn*#WPDZwKn&YS9Vu&N1h8Re&#F1$NY944&t>keY?kh1R>j%l<A+kc+N9jj1ZHQ+#&Tn:t<hQ>+$i#h
^LECiG 4QhN?!<GB1J#VX!9/^GyM@Wn#e@a9\\%b%:*J:l^VLalLFTKh+$<PyDK/\w%jZ@6c9uT#ad>Lmwt<DFp
4k:P6E Lj@N:jX%WH9<$:XVB>Ikh*%hh1@TD!PENWKpMi+8Xn1ka<pL+?CAeheuQFJ8a6VnGyw$i+<C&hnpAY6?
CbFkAl HR%c/*^=d5j?N$5B%q>aWy<F16k6HubM\euYe&=abjXalJ9?ESLJStW&@<qSaGT>PjIhFeiRktyZ!WcP
cC6?Tt lu4Q*njYXkdCZ=84*dJCWY+1>KYhq:lEA<%$Se^tP/tWP9!=Z\K8bk^DT1I*@G/y&NPyuyVe*Rkb#E&Y
*yVJqK =uuTTZLe>p*l5WF=HHu:@CP8wJNnH!kV+nakw8y$mVW+=1uV@uH*mI\dXKGcV1a/$9ZCJW$udS1lR:H5
B4cNth a:pS$:Xt#!#<*P*Z:#8YI+#a?lCG\y#ZRjN4XLY$NEndZ8u*^nTQ#MX>HFQq8^\yqupY@S$/:%Vhu?Nd
nYZXSl #j/\Y$E$t?8Y5e*a6BHm+6CEei$<Z<nWyZtdwEFiK5nu9Mt+kwd8Qn*lqLVYS=RG19ScpmJ&CtpMZ!qD
WKQ*8D \4<j+:hVcP%dXqiL1M>wHKF#:bim^NT=ZG*KN>/V5??Q*^%Mn&HcyumVW#manBVH%Wh$&b<i6R/NuN<y
TCRj#H ZaDbjTV$6N%<9^p9nV?*Ni>y^m4l4@&h%98Q*!!N%<EeP=!i1Xm$Pu*wHc8DkYP%ia8mb9a8t@Y/>A8X
hVCED$ #:@E^$TNVKTH5PkHi$IIl<?/El?8qJVamB<4jY51jd$uXpX*B^II5P9CNJVddhRe@=DDF&y$8wZSXA*W
k>D?@a 68@q$ZnG\Fd*^TIyHJhL9SGwe89JwiAL/P9JT\9V<1<RhW*5Sh/P\eI/6pwGS*t8*pjXbyh8&AFybh$j
Q1pXbJ YeXi95E1:H6Tmbt$8:a@?y8D/>^/n8V<ebYMW:+^K%/mbS+4@c4Qe!11/4181#jF&#%X$?5?e#%=@ZK/
AKl%+5 Dybt=$jZ9b$<J<%aRD6Y*^mbNFtP9bbbtk<Q*1$%miqttAR6Bb=j*IXS:#HnqhLV9iN:RN8?*!wj:&Ta
IJVP+$ &qij4INJ61nJ<5FPF$ZJ%L5pTl!J6:*eRHQDl*&uC=N6c4tB*#V9@I:wY%mq1^EG4Xj$+4JhZJ1BF%R/
\V@9qR *1q=w6+S1T/Q@W!6Y>DXl?JKGa8KBJ$jH+lY:c$hW#9SX?^iwl6hQ9Jh%V\4qBWK<8/>5jMwu\V9k$dj
aR#M\P ?PwY>9%mD*dd:lF\<lSa+#FQw4K>hD%p&LQ1WH4SYi%lt8l$ctm$T+6bl59nj6qAiQLeX$<XQ^+>h=@^
D%qawy i!Xk>GNhqjP^:q>QQI5X%q>>&y#/pGKtqJ%?maG%yi\eWC!TT5uYR>*GktQ6nn9J48JD%=q^Wc!D<*Bm
qSICA> m/IbbKdpM*6J/p+TF6$=V8tX=!dcPMXwZcJqjq6CWMy?b@%>nXq&FlP:D=wZ=dLR4<&:?XH5ATbQCpw@
9CbwSD jZS9TX:cW@J56<J5$$lX/ApB=68RT8=hhP9MSwGEbLKG?D94LNWknbde5J?*FqL&HP@LXW99n4EJNeqL
L?D>YP GT/DbJL*cwlpy1SLYm*K4D%!TVXhCew@R^*SbdqTX^:ycLt/y9ATL@j\+XSy8wKpu1F6#CYS8%jEd&=e
QetqGF GC?hHN%@1JE1=dPXD+%:5bB&JHQ<#4Kwa&ymD/%Muqb>>HQ5VH>#41DABeYktZNVP+&Rce\?<hV+bZTF
&QnB>i WdZlTV$QQa\Bk\JqWF1DEKW4w$=NuyV#41#R$hmH5^J/%aJYSq#aeX%dZj^^19ZRV*w?<S14Z&14LVq8
\D@Z@u 8cZQ^k\hYm=+=MJKTZ$!ah+Yp&ka*H>KHAP?1/k%5GS5/YnTZ/DnwSJ19Jy\K&Vk>dM@V4ZQu9658Hl6
9uFRCI %ddPX/G+J>GPLWCd1Zc/ab4LDbQFKJH4yTt*E1<mFj*Pl#uYmmj4Bj8/?+yd$46QpREZkp?YMX$ad\Qy
6yn!ii FV<hc^b@y%WmJ??EiL?\pB4Xd:KY\@A6!8Jp4uN#Wbj1>hI*ZE?q?4/j@!A9@>*W<ScHd^SNmV\6>dSd
MR#kS# *iqVd@6j=Ld4<X^KH<S+D\iX5=tjt!kSj&$$aNq:&6?LZqb=ZG8@w@C*!/m%5M:H\ldT84i5*QKS?uVS
pPAX!9 Lb#:&\+:9n4<RY^%WA^+%Lc8FKiJEh:qPI%TnK=H#QnZI!a<XNjh/KXi^F*+VW9BeZLX14A&!9=mHL$/
eS!?</ qlJ:YMV?Vd<%6i#cdAj#DuF@KG!E45B\B&%RKw5+E:Q/VSHKyY=6e%pFypVLp:$MYDy@jXyAWX8hdkAq
*mR\<G HYPAwFpC/Q*BDy/yeBZ1?It4RlNH46%Njn9kE#1%TD8uy&cjNViHtGFWC1Puy:e9bJJLt:ydK5ypLCS@
SbpGce 1H*pmPcXw#%hpKQ=b>RH^V=ZJiES5?pS?/peG1cw8#RZu4EM$6CNZFa^X=C=5mA<al&PyE9m1ZiwXynq
JH&TZG kR4DtdXuu>5dLCa^uDD+5Dm4@1a*kL&I?8%TE\JB#!bk$P9WyGa@GiYy:Sn9jLVN1Q1BjIl/!Kj?kXu%
ttYi%9 JP1EaA1DV4*F#kcXkT!/:EeFT@&hcX$cKVRWW$!Fk=KFDcuLqGF$RF\%FdZD5DY>?Kj\b$F^@V8$=Gem
ZkVN:= $#1VP1HCTa!EGHj%5dZEn*6pR/qKLiM/%FNQ/X4W4F@W@TSA#^DQ&y:6Ryt5$!4edEnn+E>ZI*e/\pi%
4:<DMi 5@HK!pdP!ljJt8<ZGZPk@DEF>Nn91D$<:t\CLwP4FZ#Gu6tqd^&wXQGhbdeR*S1$d8qC>A4#+e\5pm!*
\MA?Ib 6bpyXu&/ct$mR#?L8LjHq!=%quDinJQ<ZHk^Mh/59cdkWNBWp1yJ+JIQ8W8\$DnM@#QLV>\@X95FeKk6
ibe58e /$<A8/W\CwDhXtWWAQYLw\HRcPIuTQ#EED>^^E@me<R46\Dm?TEAIC=pAID+IEB<ECR?CBIjBIqjTD^A
hNJQJA CwDE=!DmHX+ASH!RmP$A^CPjAJH$AanqtkEM<VqmMYpAR@#BAId+IJd+IBd<T^GZQ>heAJbWNSj$%tIq
51?wbM 9%+KnFLF/K*qT4dca5t6aRp\dEHT6q6LqyC\JZML&hcmJTS5WcTQbY+6Y:LXFpMkVZJ6LX^C\lbH?9Ve
=Ji:/D %6IqJG\^yLHG4eXLTNmTPhK=6Z\JCX8AVF9B<C8IRPd>\9A4CE@cJ@E\@Awmk*ETaQkXlCGNF^Jk?BWE
/hKmpt pNbMkPFZ=HBKAk!@&1#kRhIYlq?BYNI?TaDlX!BISnMM9\LJZBqHkPFZIPucRYkCDL<C!QSZBBl?BiBI
je&18u 9q<ABeP9N96#p4a\@AwkjVMjkILlX\Dy9CmAk8FZt/MwTX5ajwWtpGp4GH/%PYmS6IZlX&k5tdcC+Xjp
N=by$A $1IAC9@jMTbSHppDpCEReJ6Fa&DYTTF5qwIEBDA@=nFaNI!cVAAc#lkKpi#dAVTcnGIC?GMWk1<a<&N\
4TK5!< &qTMIiDkKAdknQy+$wyB5wy@#LP&wSlL?KWaVp$pAA$nD4Cpd=wE$BmTmnh4S/J?9L66TQ+^ej\yGa8B
c/W=Q@ I^uPpE<k+^a+Mw&M*=^@d$Q^n&Hny&KIAEe^nNnDpB+AAVTBdCNnj$#56!H=^&n%W#IIw/wZAMCIQR#y
wEuZ9& eSeA$PRqR<B&JKPI\aiGE*\AuKp9SD4+AJC5Z@#\VjmKN:jDjm4?MTdCWA^u$p#/jk+AIBX<$I>G@nFq
:P8?w@ AnHdpa#>%ThDPFmNDCj+WGRcGWhYMl/@uYEE?6Hy@=V<w!8HISuPXJ*$pkkACGRqE:DdctWR>W5!BCj/
@wyTNB RDm#jDI#PSBNXnIY9T*J^MEcA8AM%mCeBRKbCTRIp9jqdZWaIQ/Za+AEPI+B\kk@mQTSPAApF*+@b1Y+
NH??w@ :a\pt^Z6jp4G\*IMGPEHwep+B1u\\&^P+na98h/Ga8nZcA*Cmn+RD&j^S:4DAAqpFBMI&^16RiDZcA&C
F#NL^6 eEb4CEd\dd+%WwwlW5GH*Y^nLLTh&N55k9%VMS4PnAmCEZ5ktap!BJJW@GP\BnaVB9AqA#?/<E*Jt?Zh
l56AFw aWmG5/+uM%PGMPRpw#hJnt%I^8J@Taa%XadkyASIu+IFIB^=!dn6VJWB#K>PGeBCeCVD!TcR9yeKkAn@
C=cCm: RjJ&wt?#$@wyGaLVZ&DkJCLI#JW^cQKTCh8baG^Pj*>KlnXZ^5DJaYBJh<wa58GH*q\SdpM!mll?5HwM
BBj\%m DARubWN/6Mbk@wQp:c!6N=PwQ!Yn+IRjBpd+AYRt!^n!+ahBadenGje4@Dd#*VAp\\p@NPu\\=AQQ\!\
#pbB!B HejaQAu@W#IY#9\im+KVF!PhW<PTD:@N^eW&JEP@\t@#$kIaptGE*?d:ImtbjQlB?G$=B9A4@Dd9iwRl
X?RlL5 GW:&pjRPAID>?*&BPP^j?edN6AAGl@/JwlL=^n@Q&Q@pG:Fd?EaAm@&H:@\ZM\tkmh@=L$:!^*iCPA!J
qX5bL! :<TSamb@lQ\@MyM$ddbBZa1w$NkIFeMh@\XQF1Fb8Aj5KCZ5>uFBWaJW\X&NHqkYbCTXPXe4C8LX5tph
Wed*Xn K8tpSRL6nEM4%Hbwymkt?*\8XL5N6J8^$&kqcqBS?tLeDK%Eq?S94JK1NNP&&S<WVe4nj+KS#E+%FqJ6
M164Ep /D+/l<P=P$6YRuId>6E%1hlP=44S&cD1PBm>KMh!emSKGPnYa&X+YeA<Bny<eFhPq*8:ekemi<DptR6l
9mmX81 Xn$pNLhZZB#%&menu98icXF:P5L1IF&>QaF*1mdV8Kyp&Q+S6#hK1TSuJc<@S1hR&hR=Z9&c8TDuX*tl
FM1bec EkLj#pm1cM*SSC!Q6W^#Ce8$m?Q1==eKJ#GWu<<ZQq/&1bA\=pKNMQkZCVu6hPNy4QSiB5F>Jb:5hP:+
lVMYY^ CS^V1BVZ+E$Qb@a<8hIF^5dYKMFEHq4tZW6yPd&6:BEHi#$>R%G/Ru#e\5E186!Iq%EGL>Xb=PtiNqd1
<wc^*: 84I#&84/@TEiuGm\t&dw@a1k=pWwWqk#N!XBXM5w:LJI>//+R4F8ID6V6HhZ*?*>&4YDS9tH1PyTbkpD
FbjymA W*QqBdt6&W*>bci#cyRVkjbWqRjC?*jqK6WdjK:Pc\4pdu/qG5mL5FW=!ltBVqdtS9V*M*JLy=kE<6!R
CMu9NI j46QNV:q6n1k>4LikRh^4h*Z1LbQJWbPw?ZPV1ZcmmuPwacc^Ae/D/GDdBaHH8tJ>>\dP8E6&LZ!ZpP/
&Rn5ZY 8$G?$MHmhEGdw\+&QN@J<4S1Z@kN1YuB&/Z#%%q+%CmFVaVNl=K6*Ymw:qlaDLjE5?pb%b<V+1=JQQn+
M4QNKj CA*:=j*H#PJ5DK&i5#>mtZ=?kid*M#T=PW/1+>kmZu9#$TKlKPq%Q#HH1dT$9eL*Z1yh$!Xku*%WF/q1
K5%uQ+ 9iiqEK^a1NNqK4S!?Hu1kbY##b?>yRTQ%q<j+l@tGGD1p%/nphqAQuy+JGQ8#MG#==$5EDGeL:kGyGN/
MLaW9t @i?m!^c!:q=*/uc#Q=F\lE5$HY#XXNe/XbYy\mDplqNRHFQ<R9Yk/AaG1e+i<bSNI&>!=a:cLdWSiaid
d:#WW> \M&$qKH=T>:i^TXnN5b&d?Tiq*ijCE!44HI%u?1bi4ZYj#C^u<Iwpe>$hAHB*WTRN/ZPQe%Jw#1$jwT=
E*/Fyc &VM>n*MDcwu%Hl5mNL!668b^DAm+%^jtaKebiE?5:!VZ+>Tb$*eh:*B:**/5XQ8lT%SZ$q%JbjHGP<KN
-A9muR 000bf9e45bb00110333 Page 128 of binaries1.zip
XNei$n TC&#Hi1jk>hNDum*GbilDChw>9kd+AQ9FiKc%ScT#VkH4^#Kij<568@$IM*MHeG5mYQq85F/mXGw=Qy=
Pn!uMN 1\Mq:8Kq1dei8=X^l>#^:B9iiVXeeVJu@4Qj\8eQlLZ%R6Ndec49SL1p^j:a\S?HnnDa<XwFWYG*+>b6
9#RGM1 :>h:pnn1e4K/98!VtnNpbLG#$YG%C^BR*dYQe%4#&BD\8/@#b=^51tYi+hDaiT@4@FD9tHnBwYwky&P9
lK8pTj YpGMi*DLPn*cME?6a=Vy5KV5!VjbjCXyTKdneR/GWm8B?<YHQ?eQ@^FJX<tbWY>?uyGkB=TG!^S&C1eX
WdF/YE &CepqabwmCB&Ibud:VX5SlEWiR%bMX@eDtk%%SZ9PwNpK%BZCe6aV#h6QGa<qSmnY/kpwZd5Y%6*uLwT
?yFCp4 S:/!6?V/M+bEhcMbu$MPp4ii<m^//Yhc!AdN5tZ&Vy$#CF?ZFS5h66/+TXNn^6&5iS^y/+QN%pG^Z\w!
#htNkC FE%X#dbZM8ARLHZNFc#:FPwT6\F%8McM<WZIm%h1l::*t:Dlt*V%nkktyE9klk6teGDP^8Fmbebkd\cy
HBtG^# @8#tQjedI:8>Xm>*wwbKHHlePY\dnnIW1w5uY?@8L/*#LLLu#TH$<n898!GDcml4S&M%Bq&KkG9DF^5=
h>+$wV :BK8unpSP&9QVnt+qQFM1dt+uDwDyYnAi:\R#bl:uXaW54<%V?Gm=M#?dNnVIBlbR+$iCi\wcdi*HYjF
*YLNmp Tum%QDT4=Xb:IHk8#bHnK\1*P8F+qN=:pV5+Y*V%4iPn9W+Zil^8Y::l=NF=dRm!lwhEd:nHYFMqjiCa
HQh=Gu HV<kwuSSWmu:4VC9%yPS&at?Zd=GR/8qaA6hhGq=@5JqdpqPT\c>9m=<&YFhYSX9//QK/TZ&$6#twH1<
cA+!+K +EiqR<md9JwHLAT+hQRWF<>qqb/%#B*t8B<1^4E&/l6*Zll+#<C\QFXQa?m^R?%l!BK!wE#X@uQ@u644
SkNKF/ HMiia+WyC\eQ#6X$X4>6Twa/tCSNa+%#8T*GH^>\F/K6::#\11^HwcY!54*Jq!atK=ZL\?y>qeH5lSYJ
hhd!kw S>\il5Gy6??@@Gyq%SFRht:G6Jnn4yZXw&BV>$Q:jt5Kj<HHaa:5nnSCZDkuLMS<?lRuR+6T^ik^*1i@
+Yjw+q :XCZ:@TZ8Z@Jn!9qY1>=6\Vu6&iVB5nySaX>4D9w&$ip/AVFBZ\y^5LqM1&Q&6p?WuXamKNmtMllWc8P
ZQlVBi iT!!S$k!+I^l+aN+=DT*$P5NQi+hc#ilkPZlN5qh8m%/==$?HdBn5X^*8S*AFB^JJiBN$Mw/4=IpRVh&
9$kiBI JK^#RwZLkeq^JK94quu%>MJlATjQ5CN$?i1b&pe8Yq+#%dJ^edejZ1eq1AyyW^XRFkKiKci9tM#pu!1b
etkA%^ Mnwd\>F4\uZEHGuEWjSdyYlLTZba<?RA%=E/m&?ldDE9$pFdD+w<VJ<E^deZaX*N<TIb59F=H\5@lFmQ
E9a?\/ =tH9uWu^<yNV#n^d:HdRpcJ4h*D1d&?BDp*JjkX&*T?*i6BeByu*HT4cKZQNQFnj+M>+4&duSwtdCdID
J=b#4b nI\6RiA?Vb>4X@ByT6/5P@6TP#mQ!A@Hmm<inSZj<%Wn@J*HK@ymlFe1XYeAE\Nq6wt#=49$nwi^?d*j
Sw\#X* Z!R\9QA6LXp^5Y5juGEcD@S?p6Ay\*hWdTbbaPV\/XnCp@YE1D%/Glaln%?>B?PKPh%QiQkM=LilE4/F
lST9JT <$8PMM9w!GIi*itZqZyqu9K?:MB5+CE4diFu+R/AN$&ZIchD</u>@t86K18>hmFB6VZ%hV8eu*w+*Q:&
nelLby D9PTj>+qiN=5Cc@SiKZljYBS%*nbTBnjJ:*tP#Lu<>P?%h:c<%%iNAM>j1d1mhZn*=MN*Geh4#ph59H&
Z\ub:$ X5<<i@uD%!BDdDwNShB^Ga>^*R!Q5#$q:##C//Vj1B*FkqIb$6<8/YQG:@FAE6jhZ&XDLwW4X>P?iu<Q
u\eq*h ujTp*dHC6>FeneYG>m<^6==*V>eCL<%hDZIipSTWn1#NK%hHXh+/>Za+A#q\Zy*S1G^njjcJt@T1y=lQ
J<ZXcc kmnVp<nAMQ1qDYdHD<kWY\1:tRTjy>%y+/WqYT=L*/>qB%Ydu/:m@CQHIQh?halW$>uTCeX*I>aJTn6t
@8j:GG M=1:=NjXEIc!qwnP%YGbWB4>D=<VXt894hA<YHhB&R9Tn/uy&65+DNSW>k\>tDL9=hR>!jJi4AhQ^bQS
=dKjab @!EMpZGttQG:!qKTb!c!PmYZ=Vu!6cD8CWecFq5GAR+G%!ubX=V>FBHIX*4W8nKGlyRFDBp+kVGpRC8n
$W#SNW %l#w6a9yRp>DAb*mDKj&CS8n8C?@^%\yE#&GZPw=^Dmq:8B/mFq#IQ?:TS9@&$41=y/RT1Fc<XeNWt>%
e!YX1@ ^<KMH1GTtFCYEe6Z\p=8?Am=CcnmR&n8WCSWd^R9dd!&@+d1?*d1jLyG^bQI!jQ1dtcF+yM>>QT!tW!5
INAy9A Z4#1%&qtL@akXQMalP6S4tyc@8iZh&Y=91Ppn*F?wPkq&84!c5D4\X5cV\9iyN49!<>=8#V+cFYaXZa!
48R=ju XN<%yT@LPtX=>bSpGA5QpDP4wil^!4QXXLQlmuw!D<6NRWjEeaPiy@iSXL5pVjXw>1IZI>DLAb=#tkc&
p:pcdC i\ih8J\c#ybIn4Mehm18*PeybiM$#q4458?BtR9hwLuuDQ?\nuDTS>+cQ>NhJqcJ#mGP^kJcW$cqWjc$
E1@TFL p=?8ijkbib\dqk@#%PQY8$Ndp@X:$Eu?m?wSTVZ<1^E9nYIPWZkt=<V5F&AuCXWC&Q>GchH@jupJAE9t
uaLHYl Cn:9H@@TedH*@uuM/^eHTAR1Mjlj=:L\SKRSnTITl?k@EeMj1:SjCu<5ejB@$wyEHNH/J*#y??QH@N^e
/KY=5Z $uP\h:H>SX%8j99tyncPAQ^>hjZZM&?pSiL?XQu4:+C+Z*<bI4aRSMRqIiK9kAm@jkWG>i9@MWTRE+pl
MlZdeQ kyd@JjVu49tjXCtY5HXS>hhnhZBlXBC*yWaHmMN8B$aFWd>?I$mEWpEmqAwTj\6IjPekEWwFmXA1TIST
Zn+mnL \V<96RiJXCyIlFJBIyRKE1FWpAmqkpRwFTR&Kpl5K!SIyFJBam8DSCkXJEKyINFFRKIZkERwFTS/DBIp
?mI!I4 W1pkEWwFmXA1TISTRiLCFmVm8mD^QaDE%+$EeZ?qX@>e@j:hp:cpJj=$tH?5R\9k\H?&JXQ?F5BB@&^L
M8A*@q =yR1kMQA5CXDN8G\MG#JpE%dCX<T6lDySNqY\yiELWA/a:YX<CXlT&a:dT9l8>X&p^wmca8GaW8/DC/A
KL<qd< l?FZt!ANTX5aj4YJ6JC$liFZGIBMY<H\K\^ywluA\@A4e69*iBl?BbEttkE<DL?CTBQNAB/GZ$GpmYcA
@pJ++a AMP9INJEM$CA+XeR/a6LARIM9\LJyFEJMQ\KJJQQJMD\K=A$$R\RaQkXTQ4CXIAA\/<&l#GT6nD<CpTS
dNcI<m nkWCDL<C<GVcCwbjAcTLY+EwGH+FpL/IF$VB<C8AhB<LwtD+FWCcMASSeMbB$1kjmILlX&nTG+pkCwbj
H%5/nG wWuVd!AKlq?lTYNwIA1GZ=GDhMG@Ed:@T*5bIIyAHmDaFkYKJY=WadE\>wqBNA^*JuNqMalGp=eMdE5!
6b\%M5 ecMKC&inCpVDmAR5/S+YSJQHNKB6MR>a+59F\u1=cDmVTT^yb$cV*TeGNqeB&/HGj?$Va\EWHMq\=1Gp
&XQQ=Y d$5B$YV*maH6:SNnCEVRHRZBpR^uCk8T:8dR=MMQlh5Y/a:DE4q^PPEHwPDM8ptHH$B?u^naHl?M@SX?
P6uqtP GB!e<AQklB?KhQkB@\HV\G!L\wb?lS<GA!j<ADl#d6L\HAmR^#VAdjF?GABQbN*llB<AI@\&*^hJ!iR^
A+5>$F DZBd@VIG@T9<MACe<ANklN@t?!IytXV++Z/m1=l6DdwREX&FSa/DIJ#FJ$l/IpkTEQ+qtdA6Z+cIJ$$k
8yK+Am QC#JeNc6yNjcIEqAGQiV66$<QdwN!eTVJlCep!akCMFbi8JIT<cRqd^=*>b&!HEepS\u\JEMb:YMJ?Ma
u84%E@ PLKPkh<Y9RwSn=yAIAlHMy!FN8tEBkkT@wNp@Lbk>%>HVTA+S$%ACM+cuZRiBaVIl^<ik>wY:E+MQ%k>
P*e/6@ BkRn@CDTl?lBmH#+dVLc&+Hhmik+Hp:+RZDCn*SFXyApI+#jSMj^&$QHITI/nwZX!HB!CkVTk^>JSQmZ
ID+9nY +t*NqpHmTSMR#ppVEIISjCDyDBqIplDG@##uBYG*hcIA@Y6TBMI=cRJmWHATS1RuSTRJ+e%G^lK&Nd@j
W8N<SR #PL<+9Ql#Ip\eFJ4yNPBIEqA?Fen+:e%Yt<tnu@^?ZDtSBk+YVuTYWkRk!E4iZMY5B$?u$mP+?A5TVC\
Q*T/q? Eu1pq!Ra55GH\&>LMaaIntQlBB<GVm1RRD4+MPTDD+9cFnkPE5F^CE:\aiFpEWtZjRi^cLKTehl6HaJA
6EnGAj E<F^EE:$aiEpILGpw+<pH$#aQM?#8T4cSp1NtA@aQQ<QR#GM+ANIZ%\BanFpFBMkeF8KeSkm/R=uRwVF
#eMc^u \pu!py+RaZEpFj@5+db%<u&#j6yQ!Vk+a#WYV9CS#8GDYAJb!RV$6qK6^LN$t/Z8@qp!DkWuyW*cL*Bw
>p<ST/ 5yI*L^#cVuaaS<\P\%tQ\NpFS=Qb5eCBbCX9*l8!DeuwZ?5SNABuQRJuA^%Nb1Qpd@iY@e9!Q%\?@C<k
*eC8I< Z@d\n\p+6IZ=AQ>>a@%QpB=E@im\@l??jQnWuwVPn4d@8mLaq1/WduhTlCh/l>Ha#?y/YXh\4DGhS+8F
m/5hI# 5nkmGh!LZ4tcd6=CnC:uaQRMGe6bhtF@yMaV:Ld8mGJuy=HdwdVZwbLuAk$%1?aNb@8SiDZEe@YT=^$9
BGpF:H ?Rc!Lkj*P4Ym*9pj4Wq4jnHM:6$R*yL?Y+k++b&/m6iXEiNY8W<j5&WRJV$TM1u$=yTaQJ1IiC%Ebm:%
8:9y<4 chZkmIW9y*pSJc@K96a^Ly#lFZ4Ly5qP=$Fu#!/*WPK^iH$@uREi5!@Dt\GQ8y*N4ZI+yt^MLydL+FNE
WK8mG= m&I^W>8T8Mh#^8W*QVkX&j&JQDT5:b14ubZLh8#$u4$&u>yjK4=ucWI8aNqy?uZ>h&6j4CkW%//NPTiq
y5j=NB A#VXTiwML>/R:VZK9wj1&heu\+&ZD9JeX>D6Dh\6<h/aRXCmQMPtZ1ubYH6C4aw1eI$GHVWH^c?$K<!F
t9WWMu %$!P4TAG%/QGY$?Ih$=EAL!Zh*cjpmI\D*:R/cD5Ttp@JI^qZ<#mnLA6:^Y@5i8!lwYCdAd:ID19aIXG
uu@$wa NjGp^mGhbP4:+Jk*i@>?<\c%BAihFKuH&HC&e/=lBm/u:@ImZL:=$udXCCe+c=%tMVmkqaS!HVNe1Ank
:HA>+^ ^8t:!dMjHXIJ>d&P#qdpSunhdq?%cNALh*m^^6kddPM6QBR$?Zl6J$yQTZXePBIMh=PpMi/!QXl>@c8P
Da<JYu aMi%e:\mSp\/V94GVB#<a@mc!ZtXITZXp!:BT6ZY#JIe@Z=qTlq>i?%58K#nk&*Y%RN!dC&b#tp4?=<d
An5=^6 aLenlB#QnCSW9Jb:pQyWS/6+tC?S>*:C#1PQJkJ<M9hc:R:Qbd>@WV%hCY@Il:tP*T$5jVcm89E^q>y9
DejV9M FRG5EX+uY#t:Q*>uC*J?J9&6#cqPLb5h+ShpG&$bQiuCdQt\5Qd4Rw6/hewyYZ:V/mYYh1%><dWyJ/49
i/ZD8M Q\:<nj@?Aa+PpTZQ1kZ&k?kNFPeNc&d61+b?+YQ5ll@+eKN4Bueie9n/*L*uGcE>G6*1jDel6@&LtRh9
tI^4EY b:j<ih98$%tZ/^D9BYY6upepdlACXd:LB$^N<%=X+jT?hd^:w98kNV>Z\%/F*461h:=Q*:WC4>A\T*VZ
9=nNl< $ynHY1#&PZ5kR/Dh4FSt?&QQI1Zjm4HJ#Xnt@ca$y%1Ym*$&tlc!RwQM4bayNu>:pTHV4c9?RKEIFGHE
-A65\F 0009920033700110333 Page 129 of binaries1.zip
?jTmLp Y!+Z?&TZHM8#ye9RDyhVa?Q*$1PT>=1I1Bt\4Fb^YJa@a><bdTAy$6+?HD/bYS%TNqb/eKb?Xm?=+jj+
SFJeRD wb%6bl<ylyNt\m=W4mFin*HHb?$PjHPZ8iN?^Je>8*l<QTK+L=Yw<S=lqQS%V%#6DF?PQY:9j6=#QpDb
pkTL^Y 8Y85@<%MNK8e8tJc?C/:5*GY>DWbcFX?>5VpFT#hw=8*#ZybV6!<a%%%jjD/*M+>%t#u@C+$CCynFn\K
wNyGnN Dul4WNT@XA>RE:*AS\k#YNuR%J^KuDDAK4@MdbJ4tF/epayYVFCkP$m+BA:ZQd:wwWnD6Z9bq4u%l1Rw
yY^G+D %J$ewtDS>hJHmZ//8L?&^DV8yata&:!NW151k?m?X@IqGZ!Zmkj8:e65%YJ:>DS*&huXccw/wKlbPC5>
P/Z6DP i/uQ=NV^&MLZtDyj=Z$:Z8E$%*8$Z*X/Z6k@pBhNMbH4!^W&%aXZiepj!p6qH#uQ5Ni9jBq6RNY4\1$t
XqP&*9 Ewi+d6R$?uD@PAWcb<Ib*P4:iY>\4@8^WmTd4PMhyDmN54\L<5uRpXRn<cb!lIpyc<:8Ka?L$hW/ym:&
J=^/mX y8*N?V4CF@PM6DK+&Bb6hY!@H*JI?Z+%D+FpXCJWWc>WbH1DXtLcP+>$!i@Qjik4d!WqTDn><hGNL%EM
?Diy+c lt+Y%19?1<PQ*XtPcYeWqX$j8N/FbCmh+9EXQ*>wZ<qV81\Q4Zqhbhndym>Rht>5/:9Pa&?^uD>q5MwY
iJC!1^ Zc8k*4#PDhtFDH4Xt5bWWFRpFZ=MhBN4cG:\c?N@:mbSi1HBtQ?IC1<:\?+Dpd/*:>M1L?/=>L8<4?6V
9cqbCN 1\P*lcWLZ#1@%^J?5GdLahcI8qL6apPnYlD4L6$ZB>\/%wWd8=$1N&mN+XFN:Rmq8qJ=w&q*LMXBZecQ
eR<G+G qV%cmD4DJc/8mqtY5=emyCNGK*ecupPGL+p>d8W!FZul+?Dht9V+@JNJ*n9SBYG:LLqpJkTYp*dteiCC
TD&=qI DD*!d6VL^Zw&4jmcVJt%m4&LPBX+4$\9dZcKa!X+tV$?cT!BZZW&!V#LHJ8Xum6*4Kn<?Q/Q1S4BMXaH
w8%E&4 kk\nkw9+jAIaX/iN$<yb96X%?*M/&\Wt:XwNNKVl%m1&GWQN9LM69QHt#PT#5^F9*DnQl\&6QFa8L^9*
19aac$ 8KZL=Ht>+lY9iwKweH&+5:J8F><Bu5H9cZ%uEG!H1I?>9Z\$&<@9qIc#V11ihtBnXM>NKV9h^#Fk#CDm
pdjh\A 9hFJD1EqK@y?6$8F#T#TYa@\k!a#wP1cD+69kN#D?eLLV=VPQJDdedDBuSQ^@w*Vk$HDpIZL=9L/B^^8
?F#lBV TXa19L1P9+yKm#h/dc&S\JqT%Q9<9KAe&<EHpl#Q/!udS5FTA<NnX\85L81>=eHhp@nIJ\KN@na+^^m/
^:Qw:i K$nmh1Syu8qMiN5Fl#<1EC&L5w/ZcM1l5W4M4Rc#5lhHNd><F6HH&bm%+Yw!P</ce*\MQQJ6l%iFpG*%
>H#uh$ p<NMXCbmSaZGZ!apkAjQ*A@a5jy$8MqF:=#VTiJn9Wbq%YBath>dHj+&wDJ+h?RS?:+ZMciEhKaYul/\
lLc&\u &Xl%5*c#Pyh$bwj&YPiCnHbG>h!N4QjuA\1jhtcyNu*teFpKN=?iyyl:u5j8X&q\a%lZHVF*@MnHRQwK
D4^6%< L4e@#wIGw!G9^WK9/d&^<t:RjYtTZM!9Eil&K*684Z@@$@j<GjHQQky*VF5XQ=ZJVYJ6!@><h?PG:?Hw
^iQ/<5 6NlZae5*L%@$pw%I?u!wR$t4SLPqFS^a5ja+!8#ApC8tH@>FWLZ4*5=Ly<&1F14&6#jPq+1p$Xa9I&Zp
DCN$tB C?RXF>1GB$@$4Q$^QXH/?hcN\i+ZS#wt@NGy6@+w5W>1jcu5ann?khhjW/=+^<dG!Bj>\T>lMy@!dSBT
Y^V?$p Si68A8dM$&*6CnYhQdeKJ+bEb/8dQS4$<#aiFHp8W+dIn4q+Mk=e+#6dYQYAYSVKKY6pnQqaln?11Xt>
n?%/ak M*8P/et^Pa4+Ky<Qdl=B?/W?DIS<9BD^<bVS8@CJicGiijiTIH*1=RTtV\cA?i9hFEGGXE5w88/1$Tty
=\8LJk :FcEnETVkM*yhT1F19+R^:!i5bC1Gew#+\nw8hdEFbH%K@E=X@RK/W4ZCjeyB6#Le9Rce@4eTy*p45dE
QddL=c +QR/<+X5Zp!HKL@!j*:mTX:?p?NJFHu>K/#8$<i%m<b:PyES%bMX@5ZIb=yPN5j8D?SXj!>Tqe\4hXTi
4C<Mnc 8d&4=#:dCS>=Ie=!/9cZQR$dXRKGXX\4cw5*QQM1=t6jDelXN66XIj$S\w=mljXKMu1M>16HT5ikKuPE
iFRlm! ^%G@j54$W8W?y=e5=iKNwV**pH!y>Hann59*8<=+/>4+TMppWGh<$F>Y$?#=1te!yAw5WLWnXCMyq%Py
*+#6X8 QDPy15SdEyXZccZY\+PT/iVTGYYWT!k!ytZtm#%TuCe:K@tHuhjCND$5/SE*F?Ztwn$Hw!&QCnm4ZtCn
Yi<*>S $9j=J89=!Y8^Ip11J\1p4tpi1tWQC?e1XnVeP?DY1>q<<9Y+RLRZZ*mH/EZlQ4iatuA#VZhttuiW:^=I
Q8l?9l 8b!t%I4<R*!uXK##clBDuhBy8j/LCp&iCM8h@eKiLHhC=i<aZ1SlaMl#RGtE!?+8WNRInWw:*c+yGImq
$yWe<D <5h%1/juB%YH1$m%?/8&S@kLc?LWSCehyI!y5tmEjLV5@XXCA:%jtSnTP$4t?&nYn1ub4M1L&lR4HpZp
Hul864 T$u1m<+ADZ@W=9!^VJA<&dPT9A>Ryu:#WFJj>VQn=BXn1y/DIw1Mp^NIwA>9NPl>eSS6a+CuQwS6P!In
4Q+KSF 1l$pMtlEI&\Wbta$$&:51GkjGTaZQt1m+1u!ukMd%I58LRZjm?%u?Am5VGhi#KhRNKRjLnN4nyGhJI*>
&=uVjZ k*?Fc@?*5Z@\4*\8ZGRhA4F@S>alELM6bJ*\m>8GWERMH\WRQ!HmJ=d+TeV*$eVu$MVumI&AlImuEmA$
%94AD< <WGA?CBAjBAkjmFAjA:+<#\A<YhBIQAZaQ#QXh:j%+=d+L+@V^d<I@RNdwYS6>1Tke*B4VD!Xq5!\Dm+
QiaTHH FWataW5cGAi*\5kpdEpD+?BYGJtELYqkHN\KI=P\JRM#dwYSThmT&eViCmN96TWDnINdaYRT6tT&hjE\
5D+/eN @AyDJy>BkPFZGJC$V^Jk?BYGnE<TaQkXSAd<JMD\K\lH?9$TaQkXSQw1F=AA\/<k$ui1kARajkYS9t+a
ulmKuk JMD\K=DMLkIBlq?SBW+JlQ<d?Vuwd!D#9&Y+CRVkj+w*lXA\9JpMd\4>DaH?N<YdX!Z?D?GtEAyP@$wc
bW1+GP N+Z?Bp@@?:+HlQ1jwp$lFJ!itVS6C9$N8@+*b$Tn@8hwW\n%j:m::4?t5t$9lAAGkpEmRwIKkkwItJ!e
EHqeKb RCl1pN=DWbCmEpAywR>FRcXG8qRHEbYPAmwKCNKpT=McAXGRw6IEyI%atLtDX?iPa^nD8&@iD?<QYPi5
Fy1K=$ ##:48@e/i**Zh#EA9nZaymBh\9c@F*q>#M*%pE%BDAQH\SypW^CLYSQ^M89mac&LdAymGeqR/JNNRT!\
ldLA&\ hq#kbQ<y5mtIbRS<>MttIHbN<Eqn5Q<W%^VE+lqJMimDD$5QjFmMqI!5LHbhM1u+L=XhlpTKRT\nGSZ>
X5/W55 $^4EE6b!tTA68!:$ad:wKtMbPd!\nCSn>BNZEMC58e14FK*%eE&@pN$aEVWHAad!PFu/L6NDH^d:PbdZ
AK6:4? yZ5Ij1u6414iM8A!A?nD4+E?AKV9<8hK/dwIi15hj9?YKYbpZ\aaTS<J>QhqRH16bTbI4<>q+I8!Mw/S
w&tW5T jStRaTVVy4<9A+T%q^qau$+^>w8$M5DIukE\AMDXD$dQb^^hAH=YN5jJ+NhFK@\mq41cR@@ab^!Ypd<D
nAj//Z ?knE$WWkVkyadVSq$GH5:\/5W1R?i<\I8RLEMjIQl1GjFu*L8md>ajp*NjR@BPlYc?kk=45cP9luN9dZ
G?\6:t G911WQ4@Sk$>My\KWWhGu=SCS\a^h>b=G4pBNb\hAh\GmH*CuENp=w^Y=PiTh<!GtnDBFNKNRG^nqVtA
X=MMFI WlibV?RtQYNQQ/KM5CZiV<d\/Z?b\I5MX>5b5D@4\1uCmNGcAHlYn:X$9/1T9tLYpwMMT6e4NTXq*K$M
Ny=e&n ^mu#Cb<Ne&+kT^+KGG1SDPTN8CD5a%Qc+>GA$p/5qS\uE@nCN9FyVZ@EPV#e1lq$R=GZAk9RujK:!iqN
cH>m1w qBcAR&5nmRE/wkpeNk5Iw?XSXJS#CWVeN!+Ci*Qi46d:W\*CGIHPbS:P4#q+ND9T\eYFNJKMVZBlXRlB
VC4PK1 $P#GWX^:jb9tXG&jbY@1!4p8HAYLTmjtlJDSqW:S1@N*A*J!@VY:Ikb!l\MZ:?dqylmkwZA?W:+:pikV
Xp/i^: euBl:?jIY^RV$=4I<A=KWam@=t5k\5HhwA+Z&GnAH\\JM1qX\b4l&IKb#STRaH/I@k/e$L**RyKWRIDY
A99$aC IB:\AWqqWuduLkICT+1CY:4jILX9^hp?F&Y/RjEZ4WpJtcM1*n9I^cTF5hnj:1>hhEC9aIZyIKcR=h$l
VX!6RT HTTi?$B/hVRJyXihX+wK^ltWRaP:*cDe=iH5V6h$ZZJW+H9CSibLJCq^8pn+cMaX1bdleEPpmwNJP@??
=RNX+C kFbHlGb%uEHHaY!CRGphN%ID$Ymq4d>F*jYuE#Ya8*q1kt4elj:dNcdBRKGud5A9SW*/G%y&GFRbCi6i
T=:EVB &EedJh*5#y5%%DM/DCX&FChMKR//Fpm1haFZ^b@ty5d1^yTEt4%G5#wX9y#L+>k!lGTuEF%*e?I#HKX/
&APipX =5NlyRYSjFbTjc&TCV6H*lmMIFWqG8$EVjZL*jn!T^L86dde+#&+<&n5kV&:eD?n&h!/tS46Z%m+b$\d
bB<9*F %BdZ#=:Sq#6!SYu\nA$eiCE^5F#^wqe!K+b%PPtk4mZj+WMFGwb=bd8:nq/%d4lDpjC6KIlFV6qn8%m9
t>Z*kT *8#$8u<>^?+M>YPq5$@ddIXicbFRHlTb&b^P+iCW8h8EY&nbjd#M$KC/LY>p=Z+\yFi<1^u$a88e6Nm>
N!Em>5 W9FYaM@l#91I5W&F%N=Q9R$uqnX#G>uL+@&i#KFnL$58SClQ$8:/EmeP5m=jq<HhR@9yC+8Fn?tX&^?+
Vq+8^1 4pNdPqh<y@1+phh^KiyKLEIeTl4QHnD#*6\4$j14Geew>bn8$%?/JCTMq/B<:Z8tQ%R?$9\NQSX\jucq
cYtH6$ y<m#c>uenNYCc#@ZJi44ytTqSJ5V1c&Rp!QZ4!:du6&$Wccc6b9qTtw#:1I>W+*c!pbLBdFkQhhcYSNE
dC/R$l %Rb>k6ZLN>hm4N4$H<>XCA<>eR?MH>SDyPw1=A>+Z59AGFdZ#C1q\k<KIQSb4+eS9ZM#F+6/?8A6I#yl
4#JCC8 XQYmTl/\4q95<9/1FDHqdyn6#9B&9cyZkki><%/Qw6>FZu^biQuSWEicV/NyNEGA>%+@b:1A4/SND=HQ
qPCVj5 WA&q%bTE^%bLySZp\=nLayYl!@!Z&PS=nN#4#?q6bJWIPMyPk%peM\n%%XSNFW6uB#Zc64&H@F#QiRlk
%#i*P: *lPCGE:aZBmkn8IW#u<VE@6!>^GE:JS6y=llE!>L*Wkki&CV^&mB=!Bei@S^$wcWD8c8=bYBn:cW&b%K
CFhYF1 9LHLu:cV=cBM6^b%kuI!6Ii<4IhDF*XTTQ#JMViVXF&HIjm/C#$6dhjeDb\XXhmnh\VPi>@K+6wLLNca
B9QF$: WymDcPJdmw#NZ>t+9bKL!E5nQPt/kSk*IwZNPVCHVwaIK#jD8@%1Ym?Nl\m/Q:\+%B?9GM4/<nJWC4yb
j?+k9+ BIXtt$JqFWc:ce1?$@DmJubNR?Q1FRFTe<TT9j#=aK14J5HQe8>\nC4Syj>EdX!cYuYc5/n+B<H6BKy@
tTSi5M 8*cNpRE#thj&5yBX1%$aSiiBmn&E%<1MJ>\9SeAa&ZE5HaY@6Sp+j=B*n>u+wpPMK%/14ScMFqb^Pk&h
-AL@Z6 000dff00dac00110333 Page 130 of binaries1.zip
CiBIkH %>T\jS/>yj!mj&N4Y!NL1TtH8hi?WJM&1Mun+<hnhiI<aieQm1q&h!@i5L?WR?5QTp:yQKN:<$:#%1^C
SK?mww CH^ZG88qiby@+CE@b@<WpDYq%Eh4eT?GLDhnB:6Y5XuN:@JRutjYE8^cu%$Cc68K!IQby+9aT:*YZT#u
CJ=hc6 H>TuJR>5PT1*^*j8*Eqin!%5Ic@5iXKMY\a#T4b?QH85hjj=D6/516QHqb86aSTyAc=G6h$jiZ&T4*9h
Vu+ucZ H#Q5uRX8##<<m@B9JwRFCe^$S5iM9:\l/jNEQ1N:Nt9G@*AHj+^&65h?LL8W/$nwk\PKTWRe1\u6Si:e
NE6$?8 lt$1Y1/aW8NKbZq*Cn1=9Nh?$6DuFqp5wd?/%>PX9CZ/X:FMcjjE@aKG#<XC<#maqjuqPRjDD5CaHGX1
S!cX\M w<$p1y<VZ#uSb1#1d<e@i5X84/ZwuH^^^E6:kZAT4jP?aib8:uFctaY^yH:^F6K6\*ci:E!JBFGY1FFq
Q$KwAd +eetHANpJbEJBh+VWYlMb#CZbT6tyEkkZ8R&Q8EhQE$@:NFtJ>P=?Hj>Qcd9qZL^Rbp>em&twwDC\>!*
w4<t9N wttaGkhdh<C\!bDDcHl*nY48y4mSwnT!=cnybJqi\hK=nu==QZ9KhM=qn^LS<K::^qjICCKSVyEL@Ld9
#HPZ=? /j?/!AX?&#4FeJELBL+4eu$h89t*Sc:QXcR9ie=j5/j9duT@/qL>?EaZ^Mu?F<djNpYS@nD>t:#6D::n
Pw8HmZ c6=GS=ka@HP#%H>ElMH@:>SHNp9%Ry5WjlmM?i1GqI5F9ZA%=kC8a9691a<^jmt9Cwj=QM1qVF1TuCeY
DM:k#W Tyq@#\M41yECT?qCJi$W5iF69ml@b\:@HGBXeNlIMQ\<qD=&9t$NY\>&%kiTd>9IGAdJX^&$Q+HpQ<N%
8Eu*$\ j\TTL$EFjlH#?t9Ijqj8?T4i>8j!Jj$:L^D@a>5%y6KC*@iJ$Zp9@TtQICnDkC&P@k@5>>%ihG!^c>nK
QTFXMw @6kYqKY@X6?*dNG^^hK@&<Bnj&!Lp%*DFtDAFqnDb>!QdaG%*56AZAH$>YNAQAN^6eceA^DQRF!68Z@n
IJ#EK= bj+da\amT+d?#FMRL@5@6=XtILLYtBEJTnMWYjT94/Rbmc\%WCnNRGVl%4kepYap56c+eyNtKLLww?G9
tC@58J E\K?Y9:N%IE@LtI?H?+!*^@8*#d?$Hut>%MH\D<*T^Bp/V!V<H*CAK:TCj:=1RQM*L<9yDCuJZhA^l5p
qj>mE6 KKA+aiT@weMNCId9EqbMKVpJyKHJCKHHen\YA4%VHbN>jni5:mX\#VES/\!M<M45BWNG=Gu+laALkH+E
FZ/&@E K9l\dp5DZwkTj$yWXqjS!P:Ny\keRq?$%6ZqybXq$CHk5kN:1#5#9>Eh<4BjX+FN/?BP=n=EqcXqRS$H
hKiJ8/ PeA9G!a1QH*9w$=?&\hS\ipLP\PFml$=pCn9V#nZnLFHKBnZBTqETt*LlGQy:q<jGV1b<*8jH8tMj8qe
1#dAD& M8DTXlGwEbh9M>4DKn%aSVP\EN><q!aStSS^SY#TkN1eW6*w5yWNyp=B=cRYcBj5JS1\BAm&NmPyE6G^
kpBilB 4aXMitqDITAGwakw6K#JlFdui>>p#\%dNG$FeqH#QYAInk!XJ15@u+keFb#ESk1:6I$VHG?a<ljDe>?8
bGG!:S TPXwGjDhqES>mC?1h4H>?SC5*\!YKtytBFWNEe>E*!iZhA^wRF1mWNSWa6kAK^Q^Pdc58pwjD:&VPCRu
y<ZyFb w=jaJSQbS1CkbaY$Z5>SNWmpQXCe\:DC+*T?b6pwK<+y?e4bFwF+RD%Am$jb/EMGH*YmMA6FuSDZ:c:X
E1J8Tw $Rb/m6+?5$b!TBc$#Yk!KjZM5!w1qRh*+j^IM>BC+an1aImjITEC=J\jdwh#np\ilan&Ie6uDN8YhWGm
jLbSZ> A/E9jqe!Q/6:IY*/Qp&+>%n9kk%5wRMWiW<PlpniGH@/?Nu6QCl9YTQ/kFQ=SXpwKQ^<u4Wk9%tB%KW!
:+c%Q^ h5k5aRu88%<1*@Deeb4YtQjkjdPCM%#LX!@<NGLa<l4@4D8pYh/!PLie4>I#+9cInG:p8<TPw@eN\#We
=u/&jP JPcDkjEVN*b1cdnyA%BITc$6%h5DHqQ8u^E>>tBV<NCAeape:@5I::LZp<innBaI:XFKChceXq\Aj=9<
#=bnYC AXG?JknGWB+?Glh=Vt+tbKLa^A96m?R$8!a^HtFqhnG4qMa%uGT=/h14W51t^Aqe?bZjIMFtZNG#8Xa=
F/NETd qS8DTHFHLC$4uLch!+Cmb6m/kqEb@ZL\n&XndjJ6F<&S$QnYSHGw1Zkwq@Syt>#5F:mCke/?PMid$y$\
XdE#uh V+u=E^eQFBphqTpKGm5?y=ji*m6h#LJX^&M<J5?i^$uy:tAqV@wWK<:b@bl8d@I#*LM#=++u!G%YpXVT
tceC?W y@G$*i&&j?!?X^p6El#9P>nb4N9M59B\n&uM>nMXy6PhTkK%Q%&NSTeRZGR@aH9Ta4iLL?qSy^jm>#VZ
q81DyL ZdeXhYqhlMw@<8&+B6HRj9%yYXT%/6i6H!y?$9Jd!n/q/#IwF<RytZBFXJT=94@$6MatuYQFZt>VpYpj
\IN$=8 Fh:cDNhDWwd=Tq9NujY4Hl1LZ:&mIEl1ZySVPmLCGSiie=c!^d1lMiTSCjc?du6=^#ZQMlR91ypWR!WR
<d%^yX cun9/JcVbiaAZN%dEwh=1<^QWVCkwVEA6wNFI4lS9W6e^V1KmckVRap<XyKi>uVA^+M<?R6yj?$a1:HI
ddb5^d XY8%/8Y:u4FiTM%Kq:ankQVGDe?nBEyI?bqQWH!@@Cdww=?kJTlV/V%=J=P<p5lt$Z9*>HtaWtGV/h6M
eF>d+& &<AnknB#=XcQkmNCYG?Jy9VF8#@u\591ut^w9GVktiT/Vd$%ej#lDnq%168=E/^k8<nXN@H+ll1?=FMh
d:YQAd XdFEB+PV+?mHl^Qj^1yAnpX55>:utbIK<ZM=G>W*Gn6&:TbZmI8=^DtHdF=Cdc<Q4^ZCalSu#IPG!Qep
JBTtDF d@JZCA\c&eyE%EmqPWbJbl9p*&ByXyk!Z:n6=R46Dw9R&*idP>6Ym=q@F>iqp?d9p%FtpChNw/S+^>6=
D/A!5e aa//hlB8Bj9wlTi:y9VEcJ88I!1%4tDGJESdKY=SWkj\1p5:$N41e9yJl\mbQ9^^I/:Y&KEbTWIBLM:W
iP#lpb $$>%yRnw<+I<e=A<jY8!WEI&m#d!+Kp8yw&wR#%kT/:#>6MYZKn9W*nAp?>+K*?yy%hy=P1X&PILa>ah
1ewiZR AYE>5Z5ha:#X8HB5Ip>M^tmZ:Hk!LWS65y%*BS&=QZ5&QMP9BGc$&bYA!hIn%G@e^yT?+51nW1%T?E#M
?9DE8F LC=B=*dwMi1T=\P8eLcpmj=B*TJ1>=b^h$y?9*6iKGp5MLtJ<>S6Hm$:#/qbwmm<8Qq$%=qdGFVtl*l*
8AaRlR 1QIh5YRcHFdl$6Fb4b&R+ATH1FH*V6PPqWnZ#$V8>PAikQbB@S/bQn>%$8M/=?+uQZBVD*X>+HYAYMSB
^B6H*F W!^8c#%uRlmmiC4EyWCnqmN\e+P9*HD?m6QbS/LBD\XCcm#5i^6#68=/!j14L=bL5+p46MtK%l/b*#*Z
bITieh cPCTPCS</M*#^#+uV&@*5JJw@4B=?+=tF61E56ya^EZ=E:WqNaQSlVFJ^y:Gb&JXhIVTG?%kml1&Vl<*
!k6a#& :yXy1NkX?FwPGe?d/#Yj6X*qBY5&*PaWd*u?5:$4WR&@6BSJCnF95<4P!Iti5p9eGjk9=9+#4Kt6:S1G
*Z8h*D %%4yIaRRAwV1C5&AqNADAma$R\>XRMSRDXWEXG#5qW1wwmKmwn6BXP!ImNlDWdEHdFl*RGSn^:a*%9%/
4=%qHp *iX:u9ji%@W>%@5h*+@*F?GA\Ry4ut9PMe?SPaawcH*hJ@n##ieN/8dN8<6eH*%?aVSnab4JK=$b9uF@
LaN<6V AaE$\yuum>5bqiBb6d1:<9S!$jX#:Q*W!WYuS:PPL*@5Qq/aBF+NFDbQ$8i\4^e?jjE=:&:QTQIC+/#d
FDC?H? A@lK4+$lId%tela*+bF>&@bLp4M4Zu<5W6@6Cali+%NkHQnZtR%hIWWjm5yduu^MZ=G=cMl&VZ/Tia*8
yDEX\b Wd&Kya<j:<?P?tYF4!QNll&Xd4%&:cP$=RM*=^5QQX$>PLb=<q:a5VGy#YHbJ9D^$It:C^$5>/nQD#5F
w6P1E8 FRZ>HtH:9nny=4L$q!H4Nq5Z9!&<Xy*t<>=IbeB&Z?laLVt@cB@8+%j48<4h6&ab:juhc#q@T>H#9Te8
JNM:nS yqnT%ym?K6T@<GJj<Hu&#n%L6*@h?$/^d9jM\%nStTu9$=Wnc6iSd+hY45#99@@?wAjN%Y@JD9e>h^T4
NQKc8W *4bjcjDPE%i<1i4@pHqd^bAhR5$>audK9L^w@i:*&KS9JVjmyKj>n8^<j&9w!6bNcVpHCVZejiKi4>Et
uaYeHh C$^VNBa:\q+#Fy#ei51:?j#hZi>/\@6cLjMmPVtVQh>iFJGi:L*Mjccu?aLdFjWm/M16qWbZ^$dYVQ$T
uGbe<F @:k#w1S\myJD%quXM9Py@HVPq@HaW*9@ZH9=&>VM*5F9P+<9i!F4m4EL>*:dWSHlkDp<NCP#@Q$6patc
^kLY96 mY@jFl!5SKQd+R6ZHEnuI8!bkXJ$+MT=TJ5#iil4:Vjj^<+=9QACuuey%N6FRhTX!5SI9PSd@CDFITk8
nwG:Cy Iek1RbpYupY&/<euT8IatHRQSDAbqE8pJJSu%+%Jt64pqF@+Sp!4:%mal5%!\D+@cB?F@VY+M\?ZMDI+
h9icVQ HwMLSTbdb&TK@T\%@?*P>F*%GHW>F11^kyL#k%mP%*8TCDNJ^anj4ww\TpK$b1QHla$=4=PnL!c*Ek54
Pl/$wB JlPYCN:9E4^a<Db$PT>!X$:DIYb*9RL9c^h+j8L>+&iqydYeQd<QW<M$B+E4B?babd1<Tcqu::tm*9G<
/KY:NK #LDKLZN&1W^CDB@A&tI4H?y&i?aI5C?8QNZ4jec#<V$\?GYwpQ*$^mq<R<499hF&*hmZ@h+H1F:c!YbB
mY#I=^ >t=%LEYbQV\5>*1&I8*A^>e&pZiD*@P4X!<Kn!THD9a@1*n5i5R\?EHKVd@%\$4?48LFhpPdNXT?\w*%
GlqE9* dJ%FkZQX@KEy$tpMbeaZXjHdi>A!^G4^\P*&m?TQ!@=R!*D$+Y*LdT9*:l*/T=8yHu+I/*/*ZJb:e=>h
byKjWQ E4yRDk<XS1TT6CQTZCk=%M$:9/eH8PF#=M8EHN8\jn1b</kk#4eVNXT=8#VX8q<h/>Z&\5<:d5N5*b$#
td<5Jl />@WDt&<56elDLNm/>=RZjm?djSql$t@&DiH$/TN&T=$j6DGk1/LC/Rj9jieE$<1q?Wtd*uZ!u:Xy!9h
GaA=LS C\/j\FpQ/FBidN\Fu<nycEJi?V+4LVn$V4j^EXQV+hF8+BI+EqSVGcR%BB6*/V=u&kQFab1yqaMZ=Vdm
j&$>A+ q=K8dd<dph=86V*1SQlA61J$\FJhX/qH/AhLb*h4I814t:VBaVeXl&Ia&$ueYh$Q>:F$NXeYA/t8Ln@i
%DRZ@1 p@iji?F</LtI:ZL6b8hm4<\/dD<&\+4PwHV%8$WuCbIZ==\VmI$WqF?hP>5hDJ#eDa:k?Y<&GcB>4i<8
IaLQL@ =Ym&&1J<R1b+iAjjmKW?twi?FK%R>=muLMPqI+6$iJaJIWD*c6j:ke1e**>+l=*!tky6cpJH</bGCye#
LYGq1C J&=WWj&<Q##bb+8P8dn#A&Gu89ykm@W9*QeQF6Ybb58::>C5jDeIYbpH8bpD*9Fj@b:@cV^yqHMW:lKP
iD4mlI I4E#yL%:^LIyFhd*!EX>T?b>&l=i^=98N<@XJbwYj6%MtJl!e&I\58VFSm*jD#J!?mBkRy9A@pI:aAq&
1*qHkc W$Wp1$eP1/#hN%CP#GjFbH>/jT5<Qtwij+>dY*=EW!F<>Jiw$qFh6>@5T/>dZAnu:#+XXiVNjFa!b95Z
*@G5?8 ucyqd#\VHVJ=TI/Ynl!L!^+bLh%1u:Zb*6M5#8++BRiq!*d^h?%#ILeK:qku9H6%9F$YH#<*>pDZ@l^h
-APawe 000754b5b4c00110333 Page 131 of binaries1.zip
t$V1>C y@^j:TehW\^bQ1\4hdF=^Q18<QI<++I!a?$LWTQ$C^c1tISIQL6n4@%Km>%y:m@IHS*5bZ+9Ru*HQKp9
!FG&!9 >*XpHlu$F6Kpu#cEb!&IFBJbaqZ+l%Y?6!\mJK@hcH*Sh+ann**HJ\BJ&iX6S>d&TA=+#Ni#HDtaT4&e
F9B<\= hm9La:\Be+*QZ@=GPF^J5Qh/bY>c5##@Zu*^^hlH!*Rh:lRjN*Q+5ZSVR=tM+q%eh*dQiEpTb/1+d*/W
aubyDS <&8Q<L\*CR95*t<Nce!CBXE>*4uF?hLmi>q^E@%QJ*>QYlJZ%QW/=\NH!QVB=b<Q?YQwSp8cRPA*&iV#
t9ae+8 V8nRa&!5i<T:9DA<h$Q!B*?h\/q5Ib1hLc<<9I4*l8X4&#F<EZ9u&tl/*nQ*t/YqwVim:d@XZn8*bhu:
1#tB\M 6\pPucF?1+=VS/:#AuAjC@jt45+Lmq>A?nV!T*F8RI@8l?JQ11Cl!DFBZn=9\9eiIDP/=u8yIe!I6PVn
1N@leF =WXSwG9bpanE5akBm$nY:9V8/#4Y8S$lM&5+n#aA1XWc/wInQ>Jp!&&>*iM/LyjbZiAqNJd8a$S*tuPi
I8mZh> ppjKW1IM%1&\Z5@nVceM9q=^<##wMDJ/aWZn!q&YA#jnDn*b&Zl=5i!m58QB1H4mYjBV5=mAGiV!GmyV
iZQSnP $hWRc/nuZ#Y$cL>#6e&48AX6hXZM:dQh^w4+h/GpbR*Ri8!ycP?i/m:>T8PP8c==1^K!$abXm++NG*>5
Bu&wh= &Y8*akF6^^#Fun$Z&Ri\9E\QeRq&b&=5+6KcM&$JK>46ukZhwVL!y9Ku^1XZmmm>j56pna8!DldquKkm
Hmm$5& 1Z*$9ycmdu#KwZWeVqZE5KIhdCulKq:M^PI*FW>jFBl=@alc68h&!+b!:$Zm#ZiQGV=enlyI>#mH9=jm
$&kL!w %uLch?VQ$MqG6k9ejth*Vj*:ySYy8W@da=/>>@ZT>bp&h&9/EJN<#@yw=etX4!VF!*@Tq/Y=\XN*=Y>!
XuI4=d 9#8=XC^CdcAennJqWdd4nQ^!NZtaV*w!B:/t/:kaidY$wV+:G4ED?MSNL^5@?4/=eZj!WPNL:M!1Qib#
AZu4u1 N?T6:@>m6?Ja/KEVWRanZ4tD=cXY9eJNC%Nw4Vyh6&X6up>*@#J%Jl\qj=b$y<W?89*mBe5qNYEt8?qw
TbXJJM =ia>8=dX!uej+Z8j1QH?9HH+h4%iXF4uAmjLT^5aS1w%L=$5=:e4yc>YHZ4KHD:<yV?Ml4?::%tqyCkn
B1ZF!G /HLj#p&9&p/T9E?eF&==cLucbMjN\!u9tlh9/WtQ\j%cNc@q@n/c!b?CpRl<jNetaJ@B=eQL8l=e<JI+
:AcFZA dp+1idN*?:P#BnYN9<&WqPqXJ&/iG*5Hj&Z9@QdckP9dq5+i<p8uy9q+4p\+qL^58FH^dMQcA>ShD$S<
ZGDGLX &w@=h^!m+j8C@pp4CQyu/5H@*R9q@=u!=kZ@%#G9j!HC@Z#6B9?ZJ9D@VG9+X#p8@\i6\ej%d%1DD?9j
q4teK$ %S4aQ9>Ma@D?i=j^9/:<j#!c=jF*>=T@a@@FpVCQ9&iI@B*:4#TG9%8k@BP5=#@ZN9/iIjJ*:L@ItQD+
dJ1NbK i+dI*:Ei@@^ItMjjM$V?ChdnZ&Db@\dY:X>kjj:Q&H<aB9$#:N?Q:j$h/@dQn*X=5Q?N8uL:F@ib@Y@W
:w^=6l %d>5>dQ@ueL!?8e6cQc@WXn@/lPndM>@b=D??eQA@neK/^>GP@<W/@*9DNK@8P/@WXl8u9@m8n:@w#*?
awLRe% 9!c5j/tu@*id*TWc>tT=@:$>@4?j=@99>4nuQ^T\@^eL/ySAl$DMSEb>PD1lS@e@<u4*@uJ&5e6\:/9K
jN1<Rm wNYthaeuH\lQ@S1::&d?HaVjW<Pm//I^Rib\D>Nt8<^18HGCZ?+n@Hn^A?Qi@N$$?uXjJ:8Yt$jM/tRa
8p^1TL Zjw%IhN//8Le:&QqHiFT@YK+\+b<BIjJtM&P9La#Z4CFdH%MJ:F44NTc>QtiIlV:>bh>1#4LFDPV5w#4
ZQ6&S@ V<GplV@mHb&9LV/&hT!pLN%p9?:DBC$:!4%mbHaGS@!pi\B?eE?8C51>%#*At:^*+uW\q6XjQ#j$6@4y
Vdu<LB q*FG*j*cHIQ?%^%LIe!BKj+>LK9J%\*n14lC/:*Bwb$<jMS$qC:jB?iiD>mIqu:1*AeW\QKqTMhu?!5T
$W%Ry+ #YYj1cC*>9ME<RF#/mucIn$Q$jb!N>%*b<:V=N#YBYTQPl:jQXRqVcjhCMw8eLq^1#GF=B*Q+u8VN!qm
4A49RN =*t!FN4d<9ktS>4XD>ML8iTupZp\9$ST:uFnLHmY$a$kcRG?j6Q$\*q<G8&5uuNu+=MH5/>4jtNHPttW
BGQF51 %4&Hjdh6tVMtShdZmG$PZyYHFZdh9HY=Iqd@w16P=N#wDb94VbPHV@NM5iYcD*medq%Rqt/Q+#qYh^V4
bX^RJW @c^Ll6$44G$QuBy65IuleFi+e^ZFS@dPIj4aHX%?i81K&=l+PPNEMTpMVC$@LT8<Dl:cbHylijc#9Nt*
icSwX# QX%D/+yyScSA4$eLpthj@#d/&=&N>Nl/nFH&\wDiJL?C@Khn\c@>QMiPqR<HinXqeb=\PY@GE1?dJ>*i
l6ARcK #iDec?quuT6%G#>ctPp:bZVI%iml#?CCkt=SV/$ea:1LSlMPL+KML1\/:4qbBycX*NJ^5nm&$jQ8nkQ6
9ZY:TP e6h/>X>>l+*!&VtjLhehHNC9Z\LiQV1!&&n9kSiH$w<iHQBEC4+1?B/lJ?MZ%Ia<bR<Z9S5+jN:nw9XN
dnVa:T %>&DbhH8ZTuWtb6iC/%LS9!L8QNnE@Iijj9L@=w4#q:#:6Gj>n&D4??P+Rh1J9+myja+Y6%?9#wyjC#m
YW6ciL a#Q<c&nWQT?V5W4?I/?ClMm?T\9LIy?%yy+=d$>:>&SN=j$H?56bn%Pcd>/q4ZQ!i6m<@Nm^=V1ZtJ\P
%VG91m \&X8KK<qedh<T>G4#n1=X@+1/h5X<T4^Nei>9MywZ^5mj=^\FJ9>nVcWRc:8@NZuD645<ZnWp1kdpE?u
LkQXAc WJ:?cncG8M1qR#ylN6BYKX1@L4hNpK%:?<6TDQPk>!tKME<b/PuSJ!988Jl&*?BD>?#4$ZwHd/Z%bL#d
RaX$/l I:8T/L=*\pj*Q6<ypHZ>pky>D:*J>Nu<tNe@#u?acS<>=b16TS#ct*6ZiN6NL$:W>ABq%Ca**?ceRll/
u&1w<5 iAaXZHP:@:+iQ=@l?L6WEX8?QIN1bG9*:QDW?Elb/tHy$Z$JYXC$idMZp*VQKcqEqy=%hSQ#Md&6!hyc
Y9ePN? WGEj@Fc*k!6>cKBj8K1T5!hMlcw$S#t8KhlwYKTm@#ZH8p5TjZMCE^w$YRtK^kZkln#dV&hiNywPFR#h
tncBGu jt^@R8ai@:Y?<pN5q\141W<@mF+y&$umXBncDShe*/4k?4l*y>d<Sm&K@LB5!P:8J*dn6@tSd4&@#wbj
dTm5bF jDdl6n5e%M@96HeVnchyBLuXQp/EL*>e%\k#kV5?WVuupIGT+8%p8d/>NQMAI?HNEwdT+\V/9H@!c$46
@&5BZN \aC!R/81Zi6P@^CAN*B8:F@%H?mTw&+@%ntLh?#dlm<99ByqKG9l@KJN?%!ej<Fu/FS!T>IXZF\XNqGD
^j#=/L =Ph6p91qHJbNMXcu^HH##8>=F/XAiZd6&BuHYK%48#/y!thP<:WFBb1TJ5<L$EjG/%IM>4HSni##%E$S
%$Su9P %kjpQ\/icH>G!*t<iIilkuaBmCh&jNVjLu?!=j#ql5QNNMD>SbVu/IiaSdR+#&\<%?Zi!9X^!w%*!PY4
cIKmm$ TFjc4ZXX@WYXp:&*5L:<V^cq\6TcSMN>QTpF5&<>&jp8?%iu4a>>NmSu:6QJ9&i9jFlpced6BS5C?ZPS
B%R!\^ @R>6P=h*Ya%HB&6dDqLyGad:<Q9bk#<Phu*jtyRjhjGQ/NHjie!VeeH*>\^EiY&P>>9e6Q8c&S+j9iiJ
*Kq/yu %B%N?#epHul!j+?%bLa<i?QY+&6#Fp^=%&p\*VhQ*Y:XBJ*#@PkR*LQY%T+?BE!&9:KQu<D1A#jaHd=+
/?#%wY =nHPb9SLw<XcbNN6E=Y^q?:G:@PQ:BMJu4ctpDeX@Zuy\%$9YQLL&66:nEXMtBc5LM^@VQ!\hM9bN>9*
A\t5A1 XwlVI@e%i:<!i=l&kGY\5VP8*8@l+n$Q:Wy4N8j*!ESQ%$T5j@KGQXB@J!546IC=mJ\@YQF8y*b#!Sn*
Zeja?! cqZju\eIY@>e98bBqt9V5hLC8ELY$85Sd?c>WD:&XBd9ZiL@Qih&<$YX@XGP*S88aDb?uCEj<Bpw:h^I
A&GBa& wicqQ:4n>*6#@JJVXt6QWReP*Q4SMPJ:^jDGttuV<n6\<=je:>n4Qt8Dwu@6dy4DKDA1Ki=$^Dn5G!<M
VW6MpI QS6>XJK4^C*atjqpc?Q+&!^Dn#5uI\:b4=$eYWSe:l^clTyIyFyLW!ymVumt4uuK9:L@jlFL@@:ec:6:
PJ$K4i V!S?6ZE4t8l>HYecFFB>#nEI+E8VNeLRLXW^ijeLlML*uhSdN^Tu!!J/^J4lkwi6#A8bt/dpL\XN*^+@
#S%NET 14:$:p/K?uNJ:kd1*bqy>NKetMt1M4?F/biNe+:&am<@eb!hPQ^Hq5WDZYd4w@^Fb\::94he4QQEQ&k6
&T#4Wc c6Gu!yM:/jKyT+n9n<Wn5<m#u>&pjw=yluZ@ZMMhm$@*K^$<>ZJq/M1N:mqBT!u*:/diK*&:!GQ@Ga#d
V+dAA# <+Rn:C/6?u8/?11h&c4?/Gn8$t&#I@jR<#FHlBp?*l:uw>6VL=Lt8D$QPmuct4T6NMVB?%L=9i&@d:&+
luRcTp MYVbwXy%*mK:?P!hwee9^jPYYme\E\udum\a?bK\NEMn>&4>+Tbda@Q\YhR4i8I<c6yJ#yZ?nQc?NeyH
E>jV># 9=*iJ*:4Y9!w=jKmZ+RL6\a<J6=QQnly8i$9aX=A\&1e^h&XZd/cyi%8yZq#E9h:tFNPdlld+T:<6yq8
lG$lcb ?<n*:Vjj\AC5VP#cZ^u&%NS%aw>D?@=?%HV\&#QE%:/q&GVy^Ru?\W?AnL@R&T&^I&p16JT$hGiMQQV<
L!^MqH =ERBJlq:5QTDjAAF>EhjaB+cT9CYJmXJj1!h5PV@uGp/T@qb\Y6+Zy>5Y%N*J/XXK=^#S9:K>LCSiAVI
<i*RWZ 6HDPbJnXpE5IhdH%=KILM@M\E%@XHb6nnD=jda=GLeDqq=RZKViHpqRF\i@#Y?K9ttM/FZE=ZcF/E\Q=
KWBa!6 d?=T@En=6!Ptct1Ij5L>X/+@E>eidn&bXdFMW:n=>i1nq=M<%?hG=<ShhX!FCq<h<i4G&1p!<nPHlW+>
PkplwE N\jC\Kuw9k9FEXd6SPRNA?DL%jpa8EM*TP&E8Y&qV5QYQ!aeDREHYA61S=e?@$NF&wpBFCN=9I>B/cH\
l!6y<F *YWh/W8LI+!%i\JJ6#jBF<em+*:a<4<ePpqA4:Z1d@Z8^>APYwcQ>*/>8LPF?cJu%?wELQqq!Q=WdAk/
5nHu:? K%?l5@d66c*t?Vi?Zh=lepZ#=dZhEjpJ!?ypYZBemLAJ?/^4A69VXyTN$?QC:*caH@#+=JK=SQGYnM/c
\8cV/Z hcHuBDt>5t+4a%DaItP:D9jijE4V8Bb4=EDd>bcaq/?P=B&%JjA<NHF4BCW#%&i&%*6m!h8RKtHDFSjh
qkG#\d eDN/8%Xw%a*dbI=Li%LSkXSE94QV1i:?c:@YCR&Y5Pj5t!jZ>=BV>*Z1nmThY/d=%Lq@?H&ypyq/1/66
tC4*GA Y&u?h*TTeGS\B$=tn$%acN?=Bp%<MHH8ey++5>QH=JJ+!*A4/W%^&yWMujup5\yiua9tPGj1WBTeTT!X
i&BTbS &A8DLmuF8wE8l\>QPJc:Sy@W8c#5m6E56FYPlIwQ*IJHhMi:uK<!Z@5ij6Q5G4LjY^Kqd$%d<#6L+:lu
Ha*jJ1 p#66*\HFctLF=9B96ZcHt?%1k8b*p>\n^a*uyAiV4:u+%YRH68%Kh$j:5%<FC?e$HRmi&ITKnFtKhu>:
hWc9pq =dpmPYh?h?^N9>yN&$:N?jdlXk$@<1bnYj?<F&*Fk@n>?<+5ma@!nMW:hI*E*H4Fu^MwbK4j=<ThCHdd
-AtA=N 00083b7318c00110333 Page 132 of binaries1.zip
*A9eTK 5\@@/RJ9i/&PZ<iiR*WjD%/eTZSa4@5t<1m6\\pc@YBbiPGtX&>hBlZ1*:Da%pJFd?1#iIQh%\LiDP55
wVR@n6 ISn646AW#nc$meaPy^li8GqEcjKStL@wQ&S&mV4:=ytp4Ayq66HtdQNYhHbF:BX9:iFhk?iYK@BmjGyw
NVl*L6 DjdH^HI#@W^j%%^i=w>qinnnwM</B*8G/n=S55uiL$mBHqi+5c&l59*dLkMy8=MLTt!W\VdLbi^6yGEL
qq>PA\ B@PK<M>#5H<<i*X:!X8@C&@dQuYN#H99$S91EFJW>!y&Fl@uNT*Nnp+ElBiL&ZEimjBwk6$jut:wl>K\
EQMleA CK69JS6DNjPyZ@eA:iFYGB94YSehu66qtYwWT@M8YbSyM+9>HbcnQ:TjP@h#E&ZZjnQ&q?Vby#JC8+11
8Xpd4Z :cpnED>*&@Q&yBi:j6Hbc:/d8DQViZYw=:bC#4ZQB=+Wlkw*=Ww5?9iZ:SuN>TRLZ&6CQSN1>?S:^GB5
HnW4Qe 49jj%QZhVp&/>:8X:9DMiF^41iH?L$$NMc?=>mML+yhJG\<X8e>=cy99hm61iMGl<dcTF?jeD6lS9:Y?
!da>J= jnD$&9GL=+LFB?kH*jw*D4Y#E\N8J>FTiy#9*A*Qd*jRHbu86h%Q*uh9$ZV*%^5SMeQaLTFiVRTnpM8S
j>m\LW wSGQZTT<D98KC=JjZC=ZN5pV+lV5TQKE!^=@b?GClW$wab:Xqn?cD%$!F?dtF+T=pR$W6@akVS>&y9b$
4>+hp# <%j$ip@YNitML/>i+Fw#98YF?iIL@LRat@mLLlSl$%c9q6yDl%$VjI9D=kZ<IR$bDM1NLj%/!jTXe?C4
$yZWXR >^LZb?%biVj=hc\EZW&IwG4b/+uuXIjBCY&LY:Q*J/PB#eTduPJA%?*Sj:4G*&l4<a::eK$%NmR<yQ6d
<TGQ>M IVdlYQjdet@1ii@51>WQ@a%Lh=N6JNWP?CY5!Yy^<9:8bSec9#&LY$I>Y//MNVq+ejDnq=muT^ddbBJY
!L9Tw# 5udjAl=iYM:K?n!*&+=dbww==lj9@6Ln/6G\F+<i8+wX?LyccYmkB??YQ5cAiM8:>k>5i^JBEF?JQq>=
aN>bj^ eN5j^?aF:w9\6+%4&D6Xc#BVW#$VhXFi*+LCjqku85u&4LA/8tB!!^JqNWeaWudinVP=h%eq?i&XNZF#
eeQdb$ %^!QjwTciXV@Ipb:a%q:=9M+n<jbta<QQXp%Z@$p^QTJe:^<NqPZaQy6y9Bb>K&p:AhV:Z?FT\@PtV#+
bFL<y@ 9jCH9db$<ei$CA>B55eT\*jH=6N@ud>51dtP&#\yPV5WHSZJ*/@q++Zc/BMB*<PT5<Nqy5?Gc:QFI&?G
jYL!Xd I+1\Y*Z8Sd!:6Zmn=cCplCPLG:jJ^C<*@dZ$YEc:Vadnd\/!:bt/#=\d@K/w:&?I<nn@S?B*=a6hd5%m
WnH*l% %<>GhckNV$68h&4HQ9NTqbJm8$5i8C44$bePRSeT1uS6Pw>HDKGmT=9+aXklPtthVXb%W$H65kBi>t/D
k==$Vp X!a%t/Puh*$&DL*hY4M:<84H@SiPqd=iRWbGwuGQE!j>=C+F=e>D:\qijh=>4IX&KHVe*!lLd68>!ll/
i<&*/Q e:bJ9SP%^ltdthy:b?*\4=65AI>*q@!iL@\%V?PFb/<PlZHwJB$p%5Lu=e:Iu8BX:<qIL<a8$*6BVNES
BJuyFI Y=X$Iu6$nTy4hW#E+J@Y!&jb>?!<>6S<IH@=#Ti=l1jil=hZNna+m?iFV:&!paV:yh#>8pYN\Hi*G@jP
V%QWV# D<1*#i^&8J>n$>T:?PTDien9C&8\H:dpK4Qmh*h8>ENw5<W*+bb*Y%*PhKImlTN&q!:WCjHpRX9VQ+XJ
i%XhFq $hh$^WI>hJ=a45=yCC\Lj*1<>6S?BB:K?#%!<\K9=CF9*cKl&mXYwhNQq9kedN\6?DmShtw>#iQL6!&4
id8K*\ h>TYhNn+=nX9Pjj%?n9J^>9=lpW:S@Zu:jQHjNl=$GB%#SyIPEjHa?mpY<yJwR6%9Et:jXPI^/&RkG8B
SLX4C: 5pt&$MdH?pGt4Z/iVe1Tn4#G@qDRiC8P*np=PFt@!?Za!6Y*C$lBRd6+IhwL5?!=S&yclNqj>Jmd4ZZ<
w>Mtnc FQZ$IP41LXjMyYE@+u$d#\Ad<h8Q!J<HnkEnBY?FIXeibRjHnRSdph+jQ!6NF/K@u9p>Vjjl8i8@T*hV
W%a&JD #^Sp==*nn&:Pae*Mq$b6GC/=\#?:ie5C5?iJXYpF:>e9hG8:8^J8>n&=IQF?m9^!@=>JMei*L$B4w=N/
lEGNWc R+QQL*\*W=EwLmXQBL@hpHZJw<C\I&/9M8NCdNRL>dI:!@w*=iQ<YEQR%\$u^!:<j9!MZWMKc9qJi@Gk
1N&T^+ #aK><Q9jAEGkhTDuVGd\?+*N&J=9c&QV5Mp6FRuV1=wRF@keJt/yul@y%GCDwl+jp^tyF*Q\\J@eC#$S
C9J:X= L@@!QF4dGH^Ple:e$HZ$aN4\nbAnB><1R&PKp#$N88SnJ9aTnb:nZW=Spd=q\biVnutlRV1yN#41@9^P
YLaDyI /1$jIRM9V@+Se86k%<a#!1<L#nVeQCN1?qaV@nd1</9Vj$+9>E@iyw>?<I^=ItRVbp=1Lcp/>YCBp@^n
8h!$T% Liq>@KZbw:KaP?<6QWd9?J>NY*1m4Xu8ZBP!6Y&4t@jC&YG^qpnlY#6C$h&48!4Zm#p<QN98&:^Zl*kQ
u$MT$m %9@!<qVE<$idjh+*hAl4Lew>@6T=b99%YqdA>MiR#4jX\*<+=B>J1Fn:?pdQS8<9k+%d@D+<$dY&K!>6
/$WqZ^ 9awQ=#?4%B%j=JYmc#V#QCVa=eFl?eCa:?6dS#>pb$h#Hu%+>PkQ+W+!j=*>5:XZTEiT?i6$^1@%nG$K
!PEyMG w?#HDc@#nd<ciQ8V@jW8bi9ZVZN#ycR>^$ia!^hT:tp9iDq$dZIJKLmqF^q*BNpWpQq=u>8L*j8JS@\?
qPX?<S X8=:6p:u>:Ru&T+*Wp>hj4G<qm=4I@tiVWQ>M4/$49&:>+8Wq>8u:#=GQ!6@j@V%8eMH%q$1&@e&eNG<
ZMVtWc %%Z&?LT49*Ni991L$Ne!5Ni!L5T>/*:8!6VC!ulnL8@J:A&:w1Dtc/@pa>by<R?\=#?5He$@+nIt^dcH
THDiBN e6=MiP8@jlk*mW5?W9<SGht+@5JLT:hX@te@/wkhh>dw&Vc8@jV8QiFWm/TJ<e>q4Q?:Y>u@Y&T5@:5Q
aQectL &4<4a*t!QQ?unPZJ<9k*bc#@:l9@n&:$*%*X@9QN@V6T%N>h%j/P@XeT&N>h%j/P@Sj8lB=@h%Z:P>d#
^Y@Gd6 Z$k#j*hX?!jaj!G9@N%X:b@e1*@lMjG@t/4>%+Au^&Vt@<PI+Z@bM+RX@cMGZKI#m9:nG*jabWFi>u@E
&@tJd% A4nBL4!e9CZCe6n>Q@^XA9QK!@k=yWFLm$1YF9?nZ6n\#/IwZFwcZ=KSqjN#5Q>Lnjn95*Y8@@C^?D?J
>wR\P= ARDMb>5a/iKpkSu<*t\9C#%FeGa58#*J!dmPk:n&V1#\u\ZMu+n#5Yu&bt\K#+q>Hu^+pX%>^GTeV?GN
epP/=R w6udd*DeW=y!%<%V<wWJ94bG>dnYt:QnZmR/J$d6nZR\NLGN*th%IQFb$#d@FYeZh!aZJ5&%dd/?yD8%
+&l?S6 KPq$V5@nyd%y^R9t:1b8T6%<h/qB:iQ\4/##q=e8PGM?<4J1MLQaiC*yqquDyTHY<aM:F5>J8HyyYe1b
ec9I%M !bZ?XRCC4JylW6DwET+k5H@m9HV4ZwFcKb\!y^AA5WmkLuK**6mAE4*V<DqYIE+1#kl9/M@XI%+CREF9
>ulIQB MpRnaXi#LXieIGNIYEqGy:de#qJQkYcAFJ6RG?JReJ8k=hhHBl<ieQ6?yTnnDFGM=GRnpSI^N$cL%wRC
=W:AX4 Wkbmb!kFc/hN=q=qBy9IpXGl1d\QKVdH1IR\1kwe<68BbGk!LeV9=p^dPn6tXRJX18qKGM?AyR!FtFqu
w!QmEc ZR*^tt!4^eJYwq\4YGF^uy1<A85S991LAYEecaN4Amud:K9F!9%#mPQ1Lmeh\W#95:DT\tbuMYLX@D8R
djKXIH PZ&PSdLC$%q%RjRl6/wB%k$QZY9?ZT#CWe@&$L^QHu*k<8dFKEwc6l?N$>%X<wSN6m4^IPPDGkN<V1tB
YDEa+h KSJ=X?idYZ1wc!*jElFB8#>V#Zh5*I&uYQ19F&t?/GNlVj+<XJ<&HAeA5Ku^?kpR51*^#N:&nekSlLel
VZ5T8b <CHFn4%ANh1BLKZVYJJk&I/AWT6wRImLhm&u45%<c?Ih$XAy:4kDdI=YMJBpE5B>^jRuT8i$BAHBIH/i
T6N5@C w6&HFK^96awYIlIXHLRpn^$cY+LL#ud+Xc\1PYY\aXinqZeXRDAQ1F@AjkS6iE44hY5eYEc%ycLWy!mm
ykLeup abYXT=bSTdd1JKnPDMWyG/*$$DA<GpbB/IEBDhpX&$I&bq/&>KcK?^^</!W6SLB/<KlL$Q$S+jLXHS#<
#tG?9J @hqSnNF&\*4\5X$pPFBK>wY+S>%e1kPup/$NFm=B&\M9KEV>/RS&cXV6&CK:eCDa!\6CY#j/ekun:DQW
u+Lm<V ?5HjMV*eeIwq/S%nXEC1BRLS*w4?bd+TIE5nn6aQ*8BuBp#M!G=iHtnYKJFM<6ZE1nXhcBT^V=<mq#G&
#<L^k@ euVHQ\qY/Hup+&uW\8*MM+=\^4LA$Eb<ZnC:@wLqtmVewWC^M!:AdD1R&pHu^iJ54yk/Rw@9Hi8T%c:N
ha@jm% nqQ:jM\CZnF18PH#AewiHSF#M*FbKBP>jVlM8e/iP8*+B:&*A>9Y:1/9L4aTVVY!$iXPaPMd&t<?M=l>
ltnWEd b#cAuQdykcH>lEBtA=1^kBVGF&Lct5#tHY>hh9XFk^N\516nYcCB8uE>LLB^BDq9kkIyYVR\u<A5Td<+
H:DL#i NNTR<45&Rmbwly/MRXkw&+Dad+wXW+yVnwR6eY&Vqt=uBl1&>SyZR%m/YBlpGP#lAB^Ny&i<n+Li#6#d
BZh&k8 #METYmpPFHVl@A*1RIjMbR=a1?4jV\?PLK<DZXc@\h5y4B96FXwdI@%t@R*1F:NuPVdnBI*Ry4b6iQEt
qKk5FH 5SEnbBQ^iTR>c>mB\5ZP8/KM*BW?JpT@=duy\De+W8JHAHkWNDl8cuaBWJI&JNAQ8WqBVYtpZ4>=TqZY
XHA=jc Hme<QhAk6pp8y%!$8JBtn>HTXTJlimYtw<hIK\RkdRNu\L^*jVbLF#P&VE@RTA>\@1dE&TdVR+bPGYjn
N*WQcw F$c4AdMBt^5M5WeTESk#DMwISy\cGdY1eleAIP6MpNJ4jIcCDKhY/yi$5=5+Du@w1bt:?nwAuHe@S^V<
XH5Gl< lcEKZl##GWIQ=l&&8%T?H6uLI$>^VlqQFM5*hD=l&XVd6#YqJpJMl+m^$km/^/4LeXb5q=CEhq9y?!dF
BLwebS TWe!J<HSltM:P==Sd59S>dJ8tp#d8G*X9IqPq/ll4KC=JQAA84jjPEmZy:t*IDl#FauR%:\@PQ:Fy*CK
\H!qBT Z/G+NXNHXe9LM+GM&/mdGn5V5Q5T:Ap*P%TwP<t$1iuElISHAIR56qRI<@h&R%cK1e:W^b<nhJCeJFJG
M^n1C# 8VP*BCV8h+$+I$+k951?hdT9@M\t%uNHV55=?9lWN5A!bPJH#?wB1^et8jp9GinhL&MMnY=pK!1^9C9G
*1\m+a kh$RTDtYNnB>qbnhpX\:64ZInPp>h@QHa?IL!XVthBCRcW=ylGFV4tE%R/C&1kH8GHJHCe=>F%dY^Jc:
EEL6m8 y<Hl5PBcFLn1VcAc9%\uw>e%5NEp1IcCNqmmVTCNqd84i$HCBGtiZJ@@ZbGMymwFEYmHTt!TLZ1&qp&*
+weHI6 $hdQq!QDyyHja+tAE^9QAjYX6@pKbN\l6LWbEmB6aHkDieDV$tkeue@tA*b1DX^ua\=YWjdAk!^hjaa<
$ZZY:m \5qK+SpZF&F/8/JAM6b=Wk*5JeECN1YSnENGiZk65%Dmi/P>XD<A?=JhyH9Kj:=IBPqITnDEESIGEKmy
k:%PyJ a1t9SPqwN1k8EHNa/IYqLEDwhpA@NY&S4mcNk@C&ktN&R^VGj1jk/bZG+qc$GB/q#Tw^\Nq>XCG5>GPT
-AW5B> 00093e38f6e00110333 Page 133 of binaries1.zip
c<j#m4 !Y+ndwpIiwiH?qM\AGQKWKiQ!aTt>RF%+%LuQ/+RRPjDI#aSLk:1ZB9$#PNh@eq/XMwDEPKXA\!N\RES
5Ic@NB e+/Ma+5LdHYw=#Rb$kJ9wM\/clGKRVuRpwEj1Q!pw/^<kRBFAAy=CYpE&AFYN$qWnleBL?CL!l:Kcd99
V1cYtH ^wL!a=Jpwdq9eyFpdD<AMqjlal\lAKFV$QleI<aRC4W5!c!Kk8D%m=LtQbBG9tBaAwLY^WSXA1%jE&I5
VGJ@w4 cXlQ=9#AeNkkBYVPq::4>iF\!9B\+WJMI&IbA1!<uRH6>FK**<k@/V\ptZ&AiQTcZRn?>%*>R&VEJ>YP
&5^XGS PlNPC=#=BDamSyB!1!HWHwp4cjcSYVcE>c*59N5YkBeN:Z*SX%iGBud/M1ijk\kFEuHQPEp=Kk6PJFwM
1DB&BK jDPHbk+cYV5/XHMlF%DbTu*hTXy\c1dkctT\ki@C%L^qy##B/R!9DI$F>q&$ZXBuuk=ukkm\lH>^tE=w
!dN$5n 5iNeQHJ+F4yF1ki9dd8k*Qhl8jI/ZYXPBXlYuq^%KcFN+THni8DlaECFjmAq+\VCqNBeC/+aJ#B%XmhB
?8F<te kwM@hJ$6MqbR6DaAMkuC!Yl6Ql&Mw+tTMAJ#1C@bE*DEAYjMd/:Yl@hnWNek==&#&\+DTy=JQuXpLN\R
JK#d!@ 8cmuhwcWb!^EuRa1\EB=ETiw<IZN>dl<HdD\LiV*t<mIpyGGm>ltN*<W1!wiGi9BnjWTBi$alKmZ$WD5
!tRywR w^E!aD#mylh!A%JVVDKEt@wDAAEXnjCyIw@ja9!5%bNRS9hhWR?X/&A1EGDWYIP?BkLZn\KmLbTS+PF?
cD^la9 NNeWu>F8GPSlLTBnqP@^!l5WyQj<$paukAwmhldZuR&%6!$++=:KAA^aRSRqpRSiBy\@WN\$R&R6ZjXA
+m?S?! tapG6Kd/!APCmK#DYGE1GB$VP*b^9qt<hmcP*eamJdDAn+A$GQRq?HE<TBpCA%W!JTQX@PA%tEQW++^T
IPLd@Z SAm?D#CDC*Zj%XplEJbny>PZP#IYTSIqkt%wKMPPpJG5>$=A!9A\Aup$pTXJT+iXDnnpFIcBJmt:VLuP
<I8V<c *?99*yqCW\+=t!NycGAQXXtcnNBK%Z>RqFhwIke/$E%BYpE%GaSdhRW%luAnqhNEEZ#Sj^M>jQuk/mEY
XiTAtB :d1#JWDVX@JyZC<QkcYP<wESTCPycFTXHXap^uKI*?AJPmPaIDlIWZeT6J$E&M+I?bciKY@GpA$QPS51
K@8\NT 5bmMaJVA!BNAE:qmDPlHWlHJwJ$SiAYq^ZP$a4IKHVFtk?5n+jyYaMbIpEAA:MN*bB:GDAeVXN6G6HJ4
wT9Vnd Rc<BW1h:%NecCRHkRIn#kMdSWDu:>dtbBBGSA4\lnhuyC#^R!5e5Ta866VPA\H#6H=>F!yM%+*wkGb9X
6*18#d A<B+HeRTXHNRIJ:CLcS!G1kGkabIA\F?a<ARWAYF8wAh*q1?8V<a$I:QA?GS5YJ9JaSSC\$*Ec$S4A:m
#dtp\: AG4V$Bq:DQ5C1b\88q/+QpiDG:M$X!8w\PA#\eVtI\$htTQR*kiG+QnIK\>a+GC546MSVJLl8\b8HVm%
AnS58t qmaRkAAN$PKNkBWGjYSL<B!y4<8\4=tm5tD%X#5JXylpVI!MBeNIL^*8$FNVWZ%mPqlIWt6wZDHiFR<w
</F\#E <Rd\GSwab=pS468uSku&/Ap1:4Z>*I?p#kMijBcXW<S+MnJN&&Dt\wBy/pbC^t%#=aV*9qT1wIetC1S#
Q4$d>4 P/tmh1LHIPaA#?qA/Y^PeXmj:8!!PZ/mNN^aGyGSn&P5JedWAZCN41AV4>%QAN9N+Cdh?EcWXdw:\!85
M4cV@4 4&bpVG&6Nce^YFVqlVuKj9S+J6SH%IMj/RL:!YQ6Q#IEFq^!#<A&G\=&GdBCn!EjGT8$%p=S+Ea<!DaE
WCPIJ5 &p$KQqwn9WSq8lq\\Ki\mcS!I*H&w/$6FaEc/JIW!ykcGXPAtTTkL</Me<PWEa/##aXFW?ldP\$FD*B\
*+jT>1 D^&MNPWm>j$%WF$NqBE*Mqb/RX?JAZ5NqWw1E1tB$JCKCI$=+JX:hAZ6FBGSMMa$5GGtm9c9/?wbGc5Q
XEXAYN F8P^jZ9Ija?IaKS?$\MhyM6WiWYH<<NEaIhleB&W\qC1%Y\%X1t&I@G:h1q:dtuQteInXIENQGcEF!Wb
1:X#Rb mB\M?wTtIm8mhwnCnTdubG+A:A!muC&X/dA/$lnbTYNeI@TVkDE*ZcWZYRWd>LGM^<L%*S=SZ<NM^HIQ
nqqW%P >TjqiWEYp@CCD5JaHCpQ?=BL%qMnitAcVjVIiP\X5T?BmGR6Vw1lQ/Q1>DYPnHXk^+pRe5+MSJ+Gp9He
QaICKL jJ1kp#n&!FB>BkYGkpC4kjwJW:$/VP*:milu9P\X9GId5i<&dd!SwD^q<HNqW*XT5%:kEdT=!6MKpkPI
Fh$hEL Z%ljaw/1ZMh\AkDpiQWMZ8qtD@^BWA>S?64$GbqaPJSwY$\VLF\/#6KSt5<DyIcM\:9/L8K6<FDDpN+j
uC8Z&J Glkl/*Fi/IC9nNVdREE\u6NwAP\BBA=E>Y:nRCqbtnRQ9KI#y9^J/#155GR8l+lMV+:nAbYy*ykNESk^
5PiiLN X<KRKnTZ<\CAT*V$&M=1#w+yQQGNA@HQm#CupIS$tHeKaAEE15i^I5keyPE=FaD&NupMFa9\cMn>1Ld:
jdReJp WiQq/KQBacwHqm@<#Mj+N6ykA@ZFRLEZ!KYd1\>L6hFpiJ4el?m4jT&%P@YXEKA>y/hiR&#LStP$PMH6
qyGHV+ YWR@e:nXGuFGCV^4&:\kbTkhjEVq6PpnE/nEPqQXNZQiNkAt/kQjeLXZdMw!X*M^qw^!W$&HhRdjCMTL
Ap!X1$ ^X=wL6>AXaNV!:EekSHebeDy%RY:DBEHAEtqCP^Mn@4Q/>eA4=L1SjuE#m/LnC8#BeH/$WckNyiG9MG4
E\>9\u C#FX4cc\Gm@dw+QeNYj+kY158h1DXlHA=FkIL:Sm?!lu8bQwVDTpFa+J$MdKL6$?GC5wMXeBSECyp#MF
/me#*= eEM6pP:bGdhy!Hhyt%!uSyCmjYB&*hH5D/wlKIG$kRbIy///BReup#lNNFW:4w!EW!YakD=#6ZE$PKdR
e5@C:^ +%FnY\ePR!*V98NpXFMSElYb%kEcnaB^WHBSH\\*HLMmI4p#cm%SEG1>M9w\@a!6&4l6CSwDnly#:^14
!!5P@@ Ia!kp!VaTSG\wVE9I\dXaP!>GaNYM?+FbMAG:E+A:1KI=mhtl5V?ZtEIcC$!!w*CKp$!jM*X%+#/&DmA
ehyXNV S$I1TiB:wqaLb4Illl*%$Akk/DVnqLwid*HWRmQC$WVSYu&\^+SL$%N9^Cyh6kM*>JAdXQmNwWmW&+au
65^lyZ >DRDjd+GRPR^B<?Xe<^^kkVVu/MDG1FEYJy&6RG!Xy>la=^^WH<5Dh<L\IKYTi$mD?RJahqh1=QNM6mP
Y?49BT Ipw@wjWqIX$//mewEauC5DVqKQXWcYaL>5CINk/&$XNlhWYa%jZyPPBpY/n#pCy+F4jeCIpD8WNpp$I>
up+n:? pT>SlDY@$Rwn$VREkGAPS9YAwEW#%YRM+4VH:51R<9W9Q=hSddEJcEhED8Q/jHZlL/lIG^mBnFWCAKCT
Vp>Mk4 EhmA$:W%=BXKT$Nh?kMHb%K%M!beJSW+a\l8SjY6IGVRnJE9F5hQ\amZ5S4R+#ClSH/wL?\mMEXQnGA=
S<==8: YH&qHW1WdcqC+^ke!#Fj!qkNWhYL+WRDtY^AhaYwTpPyp@Y$c\teq=hV$?*WFbmJY:KQ+:yenct&B1hm
Xn%CcI E5E$R$a1ITMaH?ylne\1BabR&tI5ew+GD%#S9LeS+QYX9DBBP\mdp#p4KKy6=tMi?1y$1wlwyL=l!Lmt
CkkLZE =:ucYnByKQlm^9qwIGklcL9Rt=9Qm?>=AZVwKS?APj1I4?HaS+LA&X^:tNRZS?H<wCB4#EE&Ehtt*@iA
ECqtd: R84Wk?%$t?E=%^/AY\Ed8MSApG?i$WyS85%cE=a4WNDi:RRAT#&k#pT\tySSTEP&JZIYlAY86%cYitM$
*GuV6e ECA&+E/acd6%XhpWiIaw5nQMKLBWS#lhjGL?e!$Gw\&B&WZVYdG:buquikG6ypcmHq$PamS!I/pdha?6
L45E!S ANVJPlpAZn8+V6qP=Q\&4@Z\dQ@9*wkyVlS8\q&6A\cTSJCi!tZ<J\ME>^myS%B:H/^VYeS<PGld?5bc
b%C>=l VRRbhGQ\I%4WTRN:mhytdynFA%YpQueLniMGdnW+9IQ64LR$Ek&l^pcw!mF<BRB1ySS6HWyJ^#H&k&N$
QElyEC kMMe5lyFM/^MpWnVQ5TA5jw1AkCeHq&G4@HqJAllw6VB/LP>VwASZjDI?B+N4%!!XlCIR44c^9lw6bM6
Z&bW<N ^+G<b5tyRDHECEBqyNGyI\A\VkicDZ/qA<Aek>%Cb^k&l*$J&n@8KQHwQq>nWjMDBNDbjQyh&^Bt4AEF
4yH<?# X%K&:AGWK$nK?wZm\LS?#*j>%$Dqab#!G/neR%Vh^l$>=<yyJZA!whkpw#+Bnq:mAjL^/q#ekpcm$mhq
=uH:pD MiKp>VNm8Ppc1YFp%4%hbK!cVXF&/J^+=Y4WD<AK4LKPwq#\HiXj6enLYltKT^iA@eBcY^HCT9c\%ChI
wF9>jV EAb@6D!AnCKJPVA?P>DXSB4!qL@yc45:F6eRjBR@5TJYh>PX#JH:=ie!ZLhGVt=K/RRTNI6ML6^c>jGH
?HKM+D mK9mV!G5y+jKl*G^>p$QcH8M?j6Cu<L<l=:qu@WT6CPuJ61eF8?:6+8SaLC<jLjPXejEPVd=P=chnPTI
VTZ<B! :1=?Qu18=6HdLR<@AiE^Sae*#w@+MW8@?pKE:K*l4ihJ8A5V:=6wBTuqGl/t>PV>?6Ljm11tM6w8%n^@
AKC&&# 5SQ*5D9&XpFHYQ9h@lX<<e6*=jj<kFh4&G@8Y8\eC$HCC$%lk\Hqnu6lP^P?RWZq#4@t4jq6u4@!6#RH
mZC#hY #m=dqcNd#+1^Ke8q1BN1%Kt>Mb9Y%R/jt*p>%$VD8N9abd<8>%^^&e^YHRt*jBGBRRLS*DqVEKp=58IF
?8tQ&j ^A$4?$/\*VYe85kpmDtLPND=H6Gyw%!&8^#a&Y+DTC+>L!@i#nGjS\?%d=pK=wlu:A*<y9uRau4IeGuP
b^=NAq ^en+:9e&%!utMc^MbJW%4/QRj4cHpE@&d*+&*H@wZF!6YMPLtIG5b5@Zn4+<9<EQ$MFjM/u^n^k^Y?Pp
>5h*^k m6uGTyl@KiY1e#S#d599MXF6FF<jticLM?@a>yCkA<jK!Gbd/+bmnc<N**ylM58JI?INq><^!6>PkS6$
u/wntn +tK?hlJcu\%@m++9Y=M!#<EFh4D8#BGc:p>WpqRL+a:i8II6wTYu&eM8$6PJLt1a*&&l*ZR$\EedC??k
9!c:%H \4Lc^Q%G%QMF8\DGqXLn?S5@LX4kicEWbIWMY@4e9H6Ni!J%++\+++V6I4ed%%+>N%*nmb:n5*J^6+bT
%IPIAK iB^n?*u%TGHH1R49&WZQj<p+&tnqcJa:?mn@&L%nhwI6#549dtPnH\W+YkR*\E^:*M\I6XQPKM@Tujt1
lkdQ$D d:ZAP=WQNlX9deWtunB9e#c/b5I$tq^^9K#p+K1%S8bdL\#jNZ&/4\NL**SSyT&9WZYmj&m9AKSWBhT^
#t>j#* M:^b/bD6d<wj88I5@C!:9%Aa^58P8TCq$P4SdbiL$\klDI/:CW:dRqHh#a@#^?>SKleRhqG$qjX\KVW$
Q@nlRC >tJiN#S%5qqSM:w>dkbhh&G+^?WqwYP!$N#Ke1RV+S:64CVPNe&w*hM&%4&+AjXLim%b^pK&AFc$6W8&
Gb>T*H uF4yQS/pZ8Y:i56<wGRdMB=:EG*H5X?hT#DIZ#!/l+NQ=#SaulJRY%TRI/w89&?eXFHy<LVq>bq?b*D#
CuNkT$ <8j>B1wL:&dtY\G<yyZZFHQuMyTKa9\GinAc@4q8?\ZX1e1>STP@CP6:P**&*p%D<P+Ym8>?BkBpJp9^
p?Re1D BnLX&Tn*\<jCPtaS^@LEB1^\jZZayFut%69elHMQDR8y*lP\aj&:eqjk+YbaP:%ka=\HyWy^HNaAWyS?
-AXA%i 0002f1dd31200110333 Page 134 of binaries1.zip
Z@tc>w G=tuRbMGaw*RcuL+4&5ZCDYce&JN=i@>R%c&jZm*Jpwti?C!+Syd/YL5pw6Sc9^emjXB8\5hW>8SnkmY
GB>BlX +L6!R+ah5abTcTI1B$Id5ZPDIbWWDF/uw&wpbS%e#?NRhJ6FZ+lDHVLwGeup<wI8nFS5M%9N=9y68E61
E8l/B/ q?+N=S/1%+QQAIGyPGbtc=\M&\%kP&KIN6>A*CCimwu5pP<@i4YQClNGiheN8Y%Ylw\Eu<Elc^96Y9ec
NLRht< 5i<=Ze=l1D?ldpB!$6Z1t61bA=j+9H6!IS\GTiLh%A$Cb&@JlwA%lVc@TDq+a<lS!!&=9#^EDINTp$6p
I>qVBX YRqWI%CE>AEn=PB!eyQwtapc:!hCb^bHub\=94h9LjAWuKl>b^+QMwh%ERCHFc!IRW^iGRi6^Y#WTB8F
Me5:Me b%$CXh@/ctb!I\H&LGJk1^YwHDIK:K\tbcB#G8Aybu@GQFMlJVI/$>G*iSHL@tcQ&ZAe!*!k6#eNdc+u
1ie%5l *kC+ZC\peVdLP?6:/i^RX1&?tqIulm6NPEj^NLmtJ81=@HT?=JZldZT#1KVG=jKh#E+nDESmjQTjn?Vl
TLBJI* R^!*kWq$a&n*!9*8#@%njY*CA^ZYAE!!^++N#1q/LP+&XC\Yc$y65DMQ/iM$#EdEGd9u>jJ%6!1HcPy!
l9ulSp K%FFp::Xdd%P5/CqIbyyCwhHqFKcuYY>e4^L^^cStlZFaV4nGRiVbX^LK>VW6y!:N%:V%Mu?k*kdRP5S
^kl>YX >@BqIL8K>d^*RJA6!ln$4IIj/?lEdkP+9DeEwbW?$4+A4V^5I=*il8G$$uFcD$?=MQ=$le$Wtc?pQKTn
5hqL/m PT5*H6W>j5yY$4nSeH^6?HyS$=#=/qlnQKWWQEtJ=A4d4NRpQcq4Mn\\qW&HiV/mBZKM4QQ>9lcHYwt/
!BRXDY ^kn1!DMa/HC6/#RtDuZ1GayTJnMdN\m^w:@qLJeK>h/6^pP5/:/=&ZdAMH1iHAu9SPZ8*RR<IAdN:KD$
6P/pD% +=%EGGKMmHYC:Bt+L?b+Kud?%H:$+RRMIEm#Xa@8\jeX?qQ+y%#ue<=/T&tl^NmX!SnNhYJ@l^hG4ZVG
:d*P\\ 5R?n+I:eYnWYlPw#d$D5?ayNPAEPnl*&!ndS$W?FJjnXCkJQCm$4DcE8d\w:@tAIYQb1#1><FE=$&$E^
jut6JN @iyI4KAdXAK#MWAwTpJ@dly$Lh1+<:$J\LyV^1A6qMKACc6q1#+HD<pQwD%RW\Twd#BhRpt*9FK!uH:C
44wq6Z kdhp46$BdpFjta$jP=uTl5a<dwGXCc=++t%8CJ:CAJILmhMp=RF<@!I+Ii!Bj46PG:Dej*yCIe9a$@#y
tYFP8! a6i>^Ejt=FNyWTlC<5Gk&!81EWFE?jRMCW/ACMPbFt4+D4c9QWp8RGND+ZmhAR6I>?ky4\FiyeZhtZBQ
8:$>ph lPlN#?Cm?$P*Qh&HwENL>p8ue>XpSw6XwNp>E%6qnt=G=Q9RE9/^V>L=>Sp>#wGC%<awKbQWcy5eVNhD
y!w?CT >hj6RRR*WI:!n<pPw?G+^?<DJW9#PqF?bXnYK^9\cM8d+*W8Iw1DMdl?A$jE6^Lj89mVmXY%?c*id/VV
*b*Dpq R=9@i:!6tlRA1jt5C<&:Pa&5Xdk%1!c^TDM\&F&$T8ytTlVk<F&T<@hhwAMe*k^&>=u+KnESWLP&tWl8
mdyA8a L+GRVH*&!k&#A9E4cl5D8FKZM<bBP?@$8h>q6l*?hLky>ZWhiG^h6SBFMGI&%+EQ**AAI8:J8%cAZ?+H
m94WTe Ky8qX>SXw#p+6l<+Hdm:Va$1?=QRmeFRQGe9*P?AGGNLYNYKiYnNFqF9\A/%wL8MkBNEmSVBekFQA6+V
IVTNm< me<j\DPlDY>FIM/Hq%+DPKPbkbR/kqPL4t\%!&LKFtnb\pIM1+XE^6N4$FCRDljC9tlEAFDGb4pyT4B<
5/ynV: n/almBN?FH*Mt6CmJ=w&:?6@nTnY:J4iA1^=R!l^qmI9pbqj#pNH=iy%$1%QpMa<8YI?y1SInn<4Ihq$
5R6ViV 6ywRPmCI+4m#%5IQNY\KG&K@=CB+i^^hH\*?lhJT<G#W&RQV&CqMFY96eaWEcq\P<JQpqPNTRiTSRLZE
:9:REL 6%JKMTW8HD+j%Hlak=LT?W%D!YIPGcMyB%1eh&m*TQ&<1nw!$MpaMQtZ@t\a#WGJBK6\Jhp@=%X=Y5Ae
P*yuTp jEH:$E$Sm+N?=DJw#?!h$a4\=SK?BJ4lRJ<lZQJPjMVn5%y4meJM&lELIDHTISqK#RD\mSmNNRJV/iF>
$N9B<M @ukJRwHSKbhc8$aQIe&eSnT/$^PARVG!y9bpVM5WyY*VpH#Kdt<!Y5TyqDFdSBT8CA/4AqcARW&i4F!w
4!G\wS h\5CB/ISm<B9#a4PjNqwGCBeiaBTdpQbAuSG?t6#RG$LlBimtHw:y8lan/Ym=E#e\6E=qDVJ%JINcnqt
8C5@Iw t8<e8WXHb##a:SVChIYA5m%Dm*AXaV!KBLk%DZH8dNdIIY$cly<MAVwI:Cei!lMqe\F<u91LG55QqmNi
:#\TI! AD\QI&D%P8B=e*^D!9aD=S8Myulwi#iEuiY9VTG<IEMh/RDiVI\5q5A*AH!A8M#^EPEt%PEwKeTGqSei
RT<nph Q:WjaK=EymP1PP8\1A<Ky4Ny@DW$K1F&XF\qVMHkk=DG@CyYJMIB^KMLn5DltF=PBMH9tuuT?RRZlM:4
4MLk:L $b4JqVuwGX>JT/e+epeuy^ql/&ERF*HFemY#W/TPFuG\e8:EIZ\F1KlA&i!QRY=K*j>CAA?kJS+Hq/Ja
a#hR5/ 8mATn?K6>XQMqW$:A?wXM9^e/XREw1DKT+\9e:\k>kJ=K>&S+wmWLLm=hpcncSaDN9lPl>aK6HnWA/6e
cT+#4u L8i9ClW@1W1&^cwLI^TYLVBKYy%RnWBT8AVhPH<u4/n1\!npyKP=419SSFR%ZwbtMACkR$#GAd\anIK@
<6wym! &c%VD1<N!qSD!eam9E>j:^cJ6w#RCGGb5<SD1?V$dFHnI\45n*TW1/<#\9hu<G#bCmaSN>\1HVCFbt#u
L^K!L9 NAJ!CBHl5=8uFpF<a^eVCC8M\QTyJb4F!Qn^?Aw81qPPCA8qiBlV\VR@?KwS#pEWYemLp#eYnq?d5^@A
4#wl*^ #^h*ANJhn$R6$d8HAHTCJeA1caTVkVYHDKiJClkAAZhe+^w!d\8GH$CwRIqaTVnF<ykKHtdIET4lu/L4
WSL*Gl m$y?PX#pdZTt1P*aS\ZLBh64JKY#Fi=m<TJ@BL+q$\mRbjMyeDmiA\G>lB$eCcw\Z5H$l&Bd8TbC!khd
i&pCQ! T+w\cl*^kA1n?WW$qaB4FD5iKw!$td\56MSXeNEWX\Lm!NWCGQdTK4aVAC</RI19L9GucF6RR$qIy=<M
8EyyG6 mANchAC&R!QdFbpP^DRT^B*LHPqG$yc=h>6uEH!yVJtIt!:DEB4Ed68RDk1mAFBhudLQ^pkHaRTbJT:b
jVM49D k6Cn5Y\QmQFY^HNThLJFHEQ5FF?En/DAKcmY8NN*6q>*DYJ&RFKNI$DBXXW51Dw#kiDn@LR!ME#jw+KC
VDu>5N w9C/T=d$V\MmIXQM65HSwpSc/&+iBCZ#1@B+Ed111mWXY^:mk@FJnyS\%WV$m%tKVnM59?maak6/@/61
j$GKEW ^FATh6Q\jS?Gd!F6eSN%EnE@1:5EJi5$Ikm>eL*iGCaw?hIyE\Vl%Dpnn^pL&i?Vn94ktSbw8wYCDhq1
\=Pnkt &ZmPK$TZI^%lREj\Ij\eYTyP\hTZCTX!QBuQ^CPndnJ/lyV8n?Pq!Nu#^e^!TTNZQu:m?QY4$VuZZDX5
AG5=F\ !a9QlBK$VL*KLdpYVHY6t?FK+4MeKc9V/Ruwu+6CiRyIaay==L$hT$=4mBINXR/\kBedeEwd//L6ud#b
T:5emB $LH5ckXe^WtTbN^DPt$iMF6pTQuI@n+5@L%cPA>T%\Iq61mKSLpmW5T5BbnbpVWd$J%8VRyA^PhhQKj9
:@VEdw 4QES#XlY:+4C<9WIRl=pTka1:KRKu8nd8wNAyT%Tm<W9AAAIEySkP>$!YLWkQi&ypIy6MK+YpmDEbL#$
AIbTeb jlXLq>AbnSXYkwp&1I4CHS^IyI&G&ELShPWtwb:W\=AC$\kXNB#jZMLJBy/+Xk5>^CF=diPd1^F#:JDh
hM@?Jm mW&ahPdHdV>u<y++9FyRw+/Vc\\qW&!\p+>X8/QwwXaheTbDa9q:>aId:tL6QI^\Fcb^ea>cKm4JFJe%
:%y/e^ IEwdTWeXCQBp=81cX$tJlnKuFpk/p/YV5qiT66GTX++iR6h4t!>&uBX@aJ=X<EFPKp/Rn?W+T=//:yl!
6nq9NM \E^nhQpJW5eSklDED5%:at/i+?NpCmhkluJqiIbEaI#T?KMW^lL<CtqHkI!bI66G1qK+*h?MTD5D$E^Z
cdh+6! PV=Cyw/TCk\pR:dl@EW+PE<pSKHX@8eEM6D9AaJ*pZC<bHRRL$e\Kcq*TAetS%+DTDHG<cd8WEqX!WII
nl5&w< 8m4SRCCVL^>qRXQ8cHwmm8e8N\$=CBSZ!WP\q?hR+DWA\ya%Jp!bYa8=KNFw=d=pb%A=4%?#BcA\MRF?
IX5nd% B^F>EE<=**lV^q+uu\4D&e#DH%elknXT+ed15y8u/JHIcM^V=SdyqL/<a!=/&u4ZKADl+*HP*hXCI>pQ
A=wY*D 9>DBA/F*C@F1mlVakSY/Z8<E^PFWQM@kJGei?FYK=>5n&pTIS$j\piitJEBJmLmCkC@B!Q1?uHH/tu9>
PP1CNE Y+EcELEY6VRY<p8c^a&X+@k6>/@e4KIHElwFXSXLwc&XKLZBG:W^K9^MhcMbNne1^&5p!q>K+KFpuEL5
S*GlW! 1BD1jIhuBpmDn?GV1XWq8@E<E!!\BPhc4tDSZ58Ym/eCpLFViF+M1n#^4j#bYd5#5S%WqDbZLy\4%ibL
nG4TKb qPWT4/Gu:PXaTmlB/A#CbhnGe5l=J/HCLIniknBb+k+ZIh&uCn>9845bCdB/!naHPe6\HiXwbdS5!Q*X
apd+*< ECDZ4Jc!W&ZJe:FDK/ZK%Sl>AWHBpuS5R+=qwD:mJi4K^L<5VmpnbJ\YlP@>n6?P$XTml*!S4b5^cw+M
TiGD6W :+cGDbE/&i@VAPc6a*Wum5Q!*e9CX#Wtq^u5B?Cpk1pYkI+XV+iJbqIc+ZYa%h&9y4iK%\eRiuFmmkPK
!myMWq F!uZ4EN@mq8/9L8pyR+5LdK1$JEJT>D=LNVPl*lN<p=KE/II^dBnJ/PX4^*8b=cpc1h?BTw<wHQZEDm%
C=BSIM BuAI@DN\muu@mX<jkbeM>6bnP?bKPV+TTunjb&#ThD%$Qnqi9P?VR@Y!$hXLBX5^uJZm!>$d&D4wuTi4
P9RStl ETL/<*C=m+W$/YX%C\c6YYY84DXkb&9=&+GYPS<Q//>I996H5bLAm>FJ4kI%e:AC\1<#Q!pBT6Ibqh5y
w&%XM# \*V1N5<1id58>1+Tbn1RAaWuyuFYq4CY\Syu^QlJBYWZj<%bd9G$mKYAynJEX=PSk!6\>K^quhK6w?m1
H*\qbQ p6qQ6FJA!WSN*6$&1&H=:QZ^JcCW5k=HCSC#W#Mc!<Y&%V9:W!ZKAN>V&?Rh*4m:e%d?8k1l$>FVpSll
cDPnQw AI/9Q<Lb8uMIJY>bJ/j#5HkuGTWN$<6<=uL$/>mwdWe#Ip!815mXI\9q^!jZ9B&5j8>^5pSHI4CetcXV
M8R9ml aS?<18Y>XiLZS?i9%j>%kZDm+6y^<11GlNZ<*<^uDZ<*ZpV\9qt>>?c/BZi@9V*@jhtV:&VJP5:4d?iJ
61EWZh c!<>11$c4c=1?9/:b5Xj%>j%Md?jW/*EQYnR?/*^%>HKBbN@@n=b8jLb8mXV*>e@@::$e8%T!ibqP!1&
dN+KY+ *F1*==uhd%M@V6!y9FV@k*P@TlmHQ9</>@#dFbuE!4$#j&*=jQjIqT<yQZ>qm*:Mt%=yQIXWiPJSRlAq
A<I*cF =kw$FeF&ln4!wA#NnDVWE1\J!S!8WEP8bk*#5+b=6!6D4G8H5nhYVDGE!n#L*hTbmY$b:w%Sht1VyuP&
L^#GC+ e*jGLLu%BY$PpRwwcpptt!!J&BPjh@8LLHS*9FS$yWk@naVjcba+=<=ZnQ^C%n=Sw$/Gw?H?qju*ui=?
-AJByZ 0001ca9e4d600110333 Page 135 of binaries1.zip
yQbY>9 qX%<FlP/@y1ka1=VC99pd$69dR&Fq64$CTcT$##+hq4T=T!P&?YXB6cD&W>ZyZW*F@%!I&Fyw<DK<e%1
68@YZu &ZwnWiGdQbi&Z^9#QBuyhylFVy<nTquqXu@u!NY*%y@4j+jt:l@u//tT:aibWVj:?*mCLec:d:%I&!K1
CTJd=a wDhhHDeIuw<ZLFl\ah:hyd&XT\N$jieCppeSi!RZTy+9Pn#M*BnLjNWiN*9V:Nl8M1yhbQS^N5X>Dhw>
^n%p%i dNeq4AwTVAMw&Y%tkCS4qIaB%S%wT=^T#VPS=^IPilJ6GFh^Id^YE\^*YYq?Z$%&C!p5WDbeE6?CQ&y1
kQlZeF L*/ylb!ymE*ctGiZ8:8N6Y6cRp+n!D%p6yZL*utP$M>1DehPMe#h\#b?/&My?%J<dct8J<6Dc*VW^KCj
pST*^W &&1iC/KkJ:An+<?<\\H6Jkbt&:T^d!dRPXAJ8EZ\BS6Lh:>8E64dDkc8*4+uA$9ey8aBXp%VDB$ckta>
CNGnAc t^@y+ymB8u*euXSE^Rthji1=my$E\Kd^Ta%<6\KA6kPSGdb8!#<aCK!PG>VMw?bRym\Nh%WVE\AItSJV
$NF:A# u\GA4:=#WVW8ajQ4tASY69CSES%6kke&bCwkZ1&m+:$DADcin^8N6Jne@1VuckLKKQl?Y^/YA&/MBeRT
m1qP*b 98m^Eukj8=miVn?C6H>?T4SR+!eepNBN@TJFTAuAcFR&/niKAB=GQHaw<aVX\^Q:YS/lp/Ql95VJjY$Q
kHqPNC &/SndnmTyPJH$j#kh?KRVj%1JH\nSnFwq4Sk#+I>jX6>9@qFET>*/b8VA:GJGLBEnyND%X/GWkTRYpmW
hD%/\w uTT!*qln>ELkqQlyW%>Kh84q4c6dwJYRBHP*^kmC5Y+dku!M:M#EwJGDYTQ\I$y9QA<jCH#JmVqq6@Ke
cFA&SA >8Tdh:%ykJ:1bAD%9RC$<$J5J*/@>tqSKw!NMq8FyP/+kL^^ST/M<ctdll1^8=j9?D=6eQF*9<pX%W6I
LCNP9J #JT6XjS95&EiE#Y5SA=X@L\QknZcNatW\KL?Kk4baQQ8+eMi5+I#ymyN>wd%E9*d6NlR!S\iAIHAWKtP
w\1tM8 jq8nHd*wdiG?E#cWb>XT6BYTWMukX5Kl@J5$<Y&jP4kC+HSeJk=+4MX\&TTRQSjKLASEFBbcP&$CqdRT
ZeGdAJ ^DVF5\iq:>%LkQ$ABT5cDKTbeBE4HL@JC&T@^EqywhY84c:aITb%86WRGa4B1aJu//nP$W$tZ?1$:9MG
Ni5K&G BNQ$K1/yH1:plA+\EW$WVKMGNZY#NFE\RHE$C&J@M8pH!JLib?bQ&$9SmJFSTQLHb?QXjLVLi^4YXa:G
XV#\+R 61TaCKimc?uZ>ab+dyRk:i41/THLDJ5wGjC1=>J>n&Ye6C&pDJ5KTQ8EE5w?Shb&S1GG!/#^jJ\l8DbV
mV\?l! n>XFdP?iVa#LnY1mw$XKX=Gh?ySQ*hF9#uKlIT&VTWcXK?^E&XRddIJSk$44NMnd*/DM6D<$>Ciae#pC
^%kWR: Wp:ThMb84AXTjpXdFSbFDu5Fe#wKVIN84/&^b/L:G@Y&h:$w:N4ZE>F*l1p*eJcI$$JRKB/^SJRlXc/@
wYi^QE i%tHYRGC%um>MdXdBw^j:^yZF*Z=DS?e&EIh+mhC4FhYWHInhy\C/uYt^*DkIKQ^XwLmwu9we>XT@cPc
PRniIp QAaZVabG<ilk4S*CGCFhu9a$!4L>hm8%cTFmdm&h94$II!dd1mt*<eE#K>a#t6F>h!IPZJBZ>a5KbhkN
5DNllw PDVHQA?XinRJEVAPVIR9&qt>P8^iB\d#:q1$mu5^bGDhQAJR&Enk9/AEddW=aP%w:#&1w=N:i?&lmYA\
a@\Flb YGtuT%E?lySIh4&41Y*IFEA/\QeqWS/=BE+HGYbw9TTh#1Am1kycputy:ayLXyGKlbyYP1t+L\nk>C:$
1?d&/: GApNCmAjKR9E:JIYTPBSe\+iA#IGVYyaHk:diNHkQ8w>:PZ*n%=q?Qda?BF=kB$>yQiWYXdLcl#wc#e\
p?IGa^ /kyAqBID$RNuTVIIkV\eSRASPQ@aiGt<pp6Cnb%@aP\SQ@%?WZ/ASlqytIGtIyR@QNTAmeuQuStpQ*uy
pS4NjE J>5u\h*Tu:6Rey>um9GwAay!bZ#Xkc&H:Y/9MLn=pYuL/$V^pI>4IY1J>RYXIVC&KuYDaBKn4yBCh&hb
IEy8\6 LP4F4a\p&@8w?!P1Q#JlkP?MGuBM%FYQ/PAEDRXYb/jR?5*yRAqqAcKal?mR:S=HS#QwB*@L9CYIA8mY
Rl<@Mq Di94F8Fb$ZMq4GVCPG&?SQYEX1*tYkL5GnH<\ByWSGP%LVYa=%e#%IN#nyc>iiQ^:XEk+B<6He<k+y65
!Iw8k! LDmnR1IwRa?ADHLW\68RqPTMjeVmklX/kFZH:8RT6:5iV<+!Eplp<KSn9W\#CkB1#\bBB%ZGM6C%:lAl
j<Chne 1m+<AKVS*WjFCI68IHtH5tkdekFhX^599ZH8$TAJJXh*?YBHihINN#MLBiaEDBJJ5&4^4KYMeNEXMKT/
AqHp<? DXKRTIh6/6jtkt8E/6kit^B??WK#uY<S@luD&+%9Plm?ht?y*cTBGWS9X#hDK5ddw%1<6DaWAFH&/pk/
yDTQCH Z5P6hC!pcYZMX#?$#FBdqH\>*$wtS%wD=nu4M<y>B\FLK>GN!+HL5DJ$6TGwnuSCI*^!/L8%BQFmC+A%
ZZZRq# TXcQ66PBN6%S%RNu>nKcnpm^nKVTYItYXj$?<6=a!<j4ZFR@NBeHJkEA#Y=eGBEwwa6FwBF%AK+#@NwW
&N&*%T JBc$&uFuSFnpmFhn^pQbEA8F#Rw8cnkcnF+Y+?j=?iwJjVZH1c4nBG%Hh^&\+\u=A8+ZK?&EkAmW#L&4
lH!S=t TDN+mmVWdhnQ/&Y=YR5w<!#j6VI<8q^/V8XiTy4G/&NcVlGM%BLpqa1IYjIL4EcTc\SY<<CLFwWVRSKM
abI6Rm %ZRk\M\$Cy^chHau\#t+bNR+cNDpR^5YJjKI\y>Qq8mM&RCZu1jMLmble%kMD6Pk:+YJW9k6@>!H\acn
+FFqqW CJ/YWY1yT6+:HkC1R^5ER+GI$lwI%>E/tkF&eGc/lYycS#$1#@SDn/X@B$15duK<*#^^1#pDMR4NM8T8
1XA*hk dictl#eTyW#hjkySccW#j5wK^8wnGk9SYnKL!8A+G9c>5ED/j+TXkhpd<>SG%L+iTkHSS8Dam8edZk/*
IPbN@p XP+H&=\JAmyb@SJ6Fc\:B5<TudIE#yM!iRCTT^>V+qFLMj*?i6anu?*jAQA*C>E&I$wVA<FDBEhnhS&h
NTCYwI Y:=KEpBYy%KXjIaTVe6ww+6KhIFB^h8jd+Nm!8$lcCi@=!nA1E+hbPLRySitGV>tCV+R4ckAZIJVjkRX
=ycjbR p<dKe$bn^Zl5y/G/\kn$9cehJjhNYICRjwb#k?BWyhkK#a$#+TkQ6JtC<LdF:$Ih\:E+wISeXQEAJkNI
Y?/Dpd Bj46SRD?mAXakIDTm5pGBF=t1uM%WIYXMlA#^WjBkk@Aaj%&LeDbynNPAVk9#MF65^k$++/Jc8YyQbqY
LY58WI \FktZjVX6I$K>Auwd%=SCXi5q9!wieW%:VeF+BXWdyjBwYkh:R!84%AZBMl>i+#*ZEFyIWD6J>N:IhYY
GLH4K4 Au%8qp1ql%k<!KFnZhmk866CNIq6c<IKD1<G^1uk6Iu&Gl:=6uF1G#E&d4aAV&S<6ASaDMCB#9m1L*yl
lud#?k \FGdnuXmP>GA#TTkZu$Q5Y\T+HXEZnn:#yCTQY+DFB%SMk*=RiKaa>SWRItF%GmMMl5H9/B\GuZ:AuYX
Th?8lJ *^w/JmFB6D/<<e<5S@TlRm5qVGCe$qPtweeCjkm?Ej5$^tNJYEE/nnu%YG8Hba*d1i@P/t6XKek/A4WJ
=Ae/w! h>!AE&:M+WD1d+T^ZA8pA\6QpPETNFL/y^1L+\mIuFJhdbkQZLyP<+ih<:m9E19H>RLXH$FPCEtAS@hb
aTXk&S WlA5XeCmM#1y!Eb>$EaZuKLDay^mG1&e$NM?\ua$N!5j$kLQkPyT*JnekNGBX4bSGVeIkp!MEpJ#HNG\
d^#d&> 4cXkAqBQENT@e>wR\D*bE6eFIG=$%VbDXaIFq&X/dCpc45CA:?pmS#!an+N@pkNVFC*iS%utw&^>IP8?
t+*98! HHRNVcJC\pm$64%=LJwkkK&R6bm?R4HAAc%MA\W4MA\$WTZWW>tl6KTjC%BA6TMPhklSP?l\T!%A4ZqG
tyN6?w CEd<<#<1KT$5hBNaa4q5M/&Ty6$=C/p#WuuwAFIKJ>A+MM%KHY!5QtmSpW%nEPa*^aecapK$$VQ:Q8u6
@\ARA\ 1kGR/PcPFty6My^lTSce8@N##NZL@Vk9MI!\<I:6Q5PH5Z%u<NWqnwAn>wMe4cYdmZJSHDFBqIdu5HCC
@GYN^I IhCDA&9^$JndLNXlI6mL9d&I9^t=wL5YkF%mqZdt1y1HAEBWP%I<t^teJA6PQ5ZRX\aaPT1!uhVGjEGy
kqP:Sh pZLIAndCABMGjhutkw5pSC?yu/wn+6MaN!\=VRTqTdIuLnV4puMR>w^>QkW=TAQ6*SBIH/DyG=K6BeWG
XwQFBn !u\h#+NT4WR\lQPFuDHH5hmMe=c1BpA6Jcp41TAhkIeAn#e&Aw=?l8P59uaD#wiF!ucDp8lhe<:+Nny5
c=XlW8 XK<k91uVJjHSZBKE9GH$tSIE?bR@/NK*:I!m8Z#BkH:GS\k\m$M>ML<dTPmHRjX:W6>HE%Hakw<CucN+
!SL4&$ *<*9YiWdG\Su<H*yX1JAwJ<J\eNLMpMlbEQ1JtNa:ViMt=Ny=RAw:@MFhBM$E!%tt14E%A!BLkimJ@ub
+w>ViZ c5eN?t:RPWPGBl59i/Xj:nq6l+<&JJbcR55K?*FFZm5a&88y#ZVMH:*J!KiF14yAES8D%PmyC1pbdAMP
Dd9MP9 bK+>NX6yc6BZd1:edSINA=yViu%ca?/#My\9aP!>SG!8a^!\5W5Xl/Z4H#>Fd&hcI6GGwt/n6lE9:yPW
Lty:5p @6WuGH!Wh@MnNXGua$KQee/a&&VQDR4+a\VT4Gd$yYIaaDG\klnduCEI%nt&nV#BNLRmG!DRLKhV5*<Y
+ZF%K* 69G#kNe*wDp&PIE!WQcDb5kwkkF1@SZGq5iyJ#dKkQTXF*@i?h><XJGBY&ykbVHA/I4NJIPeeR\n#Skb
44*G*j wRHhwD\TABPM9b<bTM$KB4AaBb>t\#SYR+d1qCJAA<CdBFc?wHwG1:\qDH!R5?KFqZKPV%MejyByN8/e
CQ%V@n i!ujTq8l!&qMWcKHaV6cT:BXT#bPpFp$LYA>9bDeEa5C!<*lm&cTW\DkTIMBjV1S!cHyKEhRGh&WJJuF
R5MJk9 yCutD94HYLuqml6ku/pP5khEAF$RlyZj!Nw#9+!V>WA/*DJEnC8V*<:*Xp>>KymMAu!6qQ5B?FhPt#PA
%p%%wj BNIbkRTGA%yNyHE<K?FV/yb6Ch4\Z\!\c!:hII1\YKZeRFyJXc/%/w9Eeam$edcl^>G/mmW=5qML:\y<
G%4dD% EW/%!yuKcA4XNlWAHkDRidWjC!uyXNWbCtPB4a18!:YeyT^KXajJ5WcAM5yHhcWqw<qWeBjM&In6e*cC
>H6lWN y*FQA\!=wbn>CqmL%Y9V1WQKVJ%8AQc?%WyjCwq8#D&$ECkH^ulGeB96==#GRB5CnyCwYSjicNS*WR>B
%lBQwR CB%?%a4wi:qKM8L85&<\WARV^ukan1NRCSmy#wP\na=&NWpRDHIWl5mMutBP\#ccMV!dqJ$wH!<E6Y/$
MmGK\T nCj$DQt5DCth1\ph?&aAY\H\1GqGNEdkkBF6yFND5ewT#M<yWiYFF<YbAWyTZ:KijmM8\&^d:8@X@R/k
dh&ht5 \VbITDWPYtGqLF?AnF85tH#GiAS\H1DGHtA=iLA9TaeVnB>*1yQhP:K:!nhwn\:CM@H6nRKqF9BBR?RM
a6W8Mn 6p?L+1TV8GkmekY9:Mjly#NFdX<AABA+aLuSBu$4VBtalhlwAFpRM6aSmNR>M&nAe\JN?Gla$IlDXtA!
HK6AFu EtAEc>p!c^M:><<H1p$DFeCLN/R9y+#W$6!44@TW%?nKPk!Hl%cLDaEiEtjRWNYB5@K1$R4\GbppBjha
-AGK?+ 0008a752c2d00110333 Page 136 of binaries1.zip
!!l$pq *5+EyVuta:1yDbPtVmh\1bb>b@SE1cA1G#Q8TDu>CNMu5EKIcJEdlG\=S5<hPj*%TQ/W4^LT:+mt6lid
tNKG<B KV?c1@^w@@lEbwAb>=w8N>qABiNXMEubaalIBWw<n8NttFKyD#!mMH!NpS>kR*TG$nlE8\tHEFH#VZXB
\Rq?ai Q#%puK/<C/88aVP8kGMCjjmSbh<ZQdYq$aMY*A4#eXQLBp+CZXyMK@/IBbNS\d?hAH4%peJt=ApEP&IR
jh6wkt Pq:E$hE?$tYR!iw4B8w/jY/\D1jJYL$mFt5KeLJC^m\DN>abAuILLpDk:D\lPt/SRTI14^q%ZATBG#T+
>^eFVt YS@pk>!wc>ZF*\ZaH<wQ=aNMAnS#R$WpdGAD&kC\6bLA6hSl*DbltEP\LEm=$=#:^1A*GeQFwyFXEn5n
HG6y?b #PbVPH<d+:k/NJB4BLjR%D6JDMSAdYw/WW#pikDKWAyk&\1<\uJ6W%b=EIdV%e4ALp=u/Nlq5>bkw9KX
pml1/K DpkmKd&\\=5q5IDM1VFZEa%FNdManiceL81a?=1jE\/!a<TGTjyckqbFa+A4^L=RW<EMIGKGj6AC&ne$
Rby>ZN NhNI%E\aC!CawP1RBeuL*=*i6ZkLd<I5YEMPbKGhc$leYE>E%Ikh/WC*EWkm>=E6pSjG!tph$Mk6PDN>
!+B4Ye wSh$B5Zu:A^E%FaIHnWYnXeiNAL#TXw<=p1AMciE!EuVGTMC!F4V9w$w46$Qu=$acjZAJhhBhmppKDS4
I!#^Cj L<cLKd4\Vy^&BlXnBR6Y/KqjwNW4cBuZmH&91H&DXG/MWB+Ndh4A=#REml^lbbIBy=p1GCXlu&BWYE6B
9luI&J /l$6ece/FR%nVR@5*eV+qiHn&=NNAdYbF^t6wYP#C5ihhStY8w!p$p\YYhXLa9nl?mA#hcM8l+=BnKkY
lpN6hW 9\$<Z*XiceDuqPE!!1u>ntDjcn!y^?S?K/Dc1AQ/+bZVhHmdZwcD94aT6iV^%8tud>d+?uItG<puZ*HL
ABGn+6 >V%=ADBC/$NR@SSAuRtVwJM:i8j1hR%hmP%qu#QBAXd/>Kbwi<QcpKj/LdiV<ZQ5!huEb!QQuR^tY>%W
E#Y*iN =R4ndA\65Cc=5@MP6n6YDc=@8aGN>jd@NYcKbp4:BnH5$e>^V+?ql@I6k?5huu:p+b*n6?uddjbqqhdT
KEeNTK *Wd#RmP=eR:#?c?N69MXadMc:dJLp^6yL<KBa?KQ%9pVhu4HF$>^#I*$CLIBkDZct8SmEwKN5$ehnakL
pC1mG> @a#S*6!6bcNy*1=dSwJnVX&N\qP>^FycF6#wDEmIBYDcB:QnD#Qitc&:/$G%cTV#86!^hCM=SMPcuVE=
KHEIJT XD4*/y6Xm<^hkualL$MDSc*!aD9*lQQ*akmnwKWd*WcVN=uCj6?+cHjVka#CaK?<wtBWJM*^\=H9j%pB
\P4w*\ HcG@dc<&ahW$18tNDCdMnJ85Xb4>SdCK*wS?EZlw%NELX#I^q:\=%KS<Fb:DjYPDB+jE8n1a??yq8Iqy
k:by=R Z+kq^>9lAQmpZ#IFPJBHC8!RXp+l&9iQ#J58^ycZ!AXt^QuI?GZ&a/D>9pQenmYKNbd>:\&YPu9#Y&%\
lI\=&\ BqtK%nh8&BRwb>a#kSbHlVmh69YDjSX^lnac1&4bHkDC%*NdQq44j6Aq1mJLYdp$C:9:!uT!5LEJ6*uA
*\1Yl? %KNNI1<8LtpiVMu*=h@BBB+QFhDH:ZH=HJ/SBMQq=P/A6uw6JE/wZ<*XH=?yMht&V%k/q/Jpl=9yYuWW
b<DkS% PmepBdJ\=EC<njt85j6&&ed#l$aXmn:AT&AN<EP66@+PH$!EXqT+tch+l+#WIR\K!$IPW\BWhh@q#JVY
8aWA+e Jc=iqVWZ?!KD6khPJ!tRT<L>84nh#*u<c6uW:1#H!dIJCMp+ZYq9%P=#iLpCaRQ#SH6cNDWIHJaR%@#5
9n=1yl M?LC/>@k>TQVS*adqI^S4RB^@#LunB$!ipip\TB@^ENZaAPp!<aR4cNe6CQPYHm!AaaA#u8PHtK>\TyH
HWiA\a j/\WN6MhcmH:/N16tkkk#qtSdH:4T+&EFQH?yXp91!@nTWbDIDKV:lXJJ=JIMkI/jXPYyyTk4$ISV4=^
\K4$a= VJBenCVBbJ*n%!ntX4M8*Y?G5Haj6&>9*Z&@8LAy?P!96h=nR\9MLn%cW*Vl#eKCH?!Yy!c$PAQGcawF
Z*@Z>? XpaRwAEB#\lCkB:X/M!Ww6l^&#M64^Dbyd^h5jZyWYiW4A?@twymDAqCyiKydQc#H+HiJ#=%jXlB&5=k
GVGDA# HX?lt<*ccH^m*T@DPyZuV$\D>SPjh%dKa#X#L@AlqyJC4PhHw#q+LHVS+19bkw?bm?%@pK#SiN$Lye:4
FljmyJ #^lIcyuYP1win*S#C&qnJKRDhJ6#ABNndmm%@:$NKG45Ni^W9#^ZabpFX%jLSIyuRTjwV%XZ/*&6S%qA
yETBWp <nKKh6NT?WYk6Fc%^TCnW$6XP>kdhY!mNt!dX/&>Mi6Cl!*F4C/#BuF\9Il&M4A/KeV&V!$P:a$\!bKY
%bmANM ydA/A?j#&QcbjlZ4c&n$Y8ZLYiteh^a*N*J=yV@MR#VdN8l&4%N5Nh&>ET&5FRwwP1w=^lM1mTK8GAa#
jPPMh# 9luyj<8M/N4\>VLXGV*@q6XtE5iCNJ\!l*htTV&%yR@MpN9b*N+?d?N:n?&h$S:w&:8&*Pl<ejWuB:@I
u:mbi> @L=Xy#&>XuZXQZiD1R:1?dd4uwGtMp*hh6KD5K9QC\Xmywb\e!V#<u%:Cw4#BZ&MYlK/::SbmN@nBJRm
Bkima+ !&DXcTh4>BkA\$Z%q/?#b+?NXApW9?AGbb\dB/i*A<tX=PhVKm=!SXIi1pD$dRKRR$cBkeJF$BijEMuw
ZWm^XP R=!H>C<h4lVe=@ESp#pXNuL5IP4CWFQF4etqX/>kWXZIiCtNYLbh?e%4+NH89e?lBt^5$<uuwu#<AQQa
w49IjH eN+uw\:?ZPNE*Z9S1\&h4\p^JqD!he&&Ym=VT/cQN\eqhQ&TmQMW@54kL$K@GPYLyn?lQ5w:B9h*te5$
W%FlI8 Nj5@jqt=uV<=d<DZ9YQ#n/P^c4^>/DwHy5AEn%BTCcP9S9W!y=\&eLA:>&^i1XmiDWlm!?h!<I:/Kk&8
=m1:yC Jh<LI/tkLFW?\pJcB#VTMlh$DmmQmDhF1T8?t\^>^Eq8F\Nm9E$%Dh9K9&KF1S1hIaG\B^++b>A@5$eH
Qe>B$K uE/wHq96E5KJA:WWCkwVS+yWWA>Pn#1nBEMGkMdiYDulA\Jy=u%1HAV!:GyX%+A?6R<pCQ!!H#FL!?FE
Nkqe\E t#EKZWReT$ISt\l1?XmFP6h!kNhEFVYcLjV\1?I1/DZDQIm+#NKqu?KK6dc^1#u1Nq9Md/E\%1cnPHId
eEKZjS Vm>*AB6C^5G/1$ywFyDTWR<SBIJAlCipw4mdN4+BA@uFyDEdh:TIk^XVwt$S=m+5F>yQju#Muw==L:cj
c1kyVC Dyb*JFA+iC:m8qEjSVFA>Z68R%mPEGewm\b@T:hP/>pQNdyia:<lI/#jK5VNE4R&$weJi+d&MVim\a<A
TD?IpQ \k<teIFTdL</l5AR\6mYenA\PCHuVC@/?9cnAKMpXNVa1n6RWYcRwREq?lT*ySwEDjwJFJ%DnIGyqd4>
jYk?W= LeXEXmTiA@#e=edH:DnVnd:b&uY5<hq*pGMm=&5NhQ1u?!RqhhcabZWRQPXe\\u*qpiQBLWX>+j:a5En
K$*8#+ +^dRttDnGtT6VmVF#k^S^>L=YGQDbCtqdVT<4lPcM@DHSJD<?5jS9QWPkL<&Wl8bkGG6DiamY@GiB?8J
t9RMX+ Yth9Td4!cqJiD&K%9mMTmVY\CYdJZb6u*W9G/CFAbjZc>*GA\Hi4tSj89M1mm%*Tyt?qupXuTdGT/Si8
PJF?^C T#lJcQ$cw=p^Hp/@RXRXNG6I&68y6#G:D<<XW!/a>Pl4tTWj!M6QB#:#:@%ptkA>&dWF4a%A\:YK+&Pl
p@+SkK yD/XtcXa8XVuTVP/u/mjD/Q%VEnhSLp/W8hAwRLD!mYGE5#$EI@eFZyAN41+W1cqWT6A@J\RBaDtjqSI
LhjmXu ?A>Iq@LMDDQ@QQ&^e@i6SR4>F\=Km&whb>%9LACL5Gm!eT<LJQt:*1QBhy^#RhVE8^QwNCtl^9Y8<+qi
+9%#Z@ K/1eSNcJhSG&MeR/Gde#yW?&FQmYL6Lb&e&T996l\eF:W:EpGH?#8EkC&#*:McNu@WV9j1HjB5DKa\kh
+wu^4i GDyuJ:#acy=@CH+$ZhJSKDt\?+V4W^H%uXPLX1dJR\CMiEklBk#Q>6anGm\&cMlk:4aAwukP@wFIl+ST
$H6E:* d^D9&>=h$nh9&8wW5$>!EMTamWGjt<^\GY1aZKZeIIpd<845+#VTpKtHGATLbb9$4TqVT9WaZ%LA1TGW
NDBd%C WIkbMWYP*eSLjyj&YmqGX=#4DQShiHtu#@e/lY+%QSwB$LIJ9LwqXnH1Fpnae^y9=H44mmWdhXSJpP*L
S^#Lk: 1&4BATX<lTJQ^KjLKQWT6cH@*BcS/iZ6?bX%mtmCTYiR8b5w$q&leRPHK6SZ?j9Zi16kHLmKLGM8\9LD
NMk<$? wYq*9MIRSjFC<?5APpYPu+MpM>qtyeDYmy%5WPSD^uT5\tm!SB4m/RwAy#RY<j$XGpkG/FXhY?DXTGia
WLy4qT S!ldui5WNkV/lm4+B$kQBBBdlSJAP9SA#u\yjRW!k=N@!D/naJ<iG^WJl&TeLAK>RP#dy$BYIC$Sb?=9
F&BQP? RDyJpIan+WG+mK\#CwKwy4+uc&\&:!FCD@WDpuF>NwNVbmTKn+!j9$@bB#D>IcG%VMnB<u\BbcwW+Wnd
V4^QCp q>Wy9Q9uqFPuwN/MBNRbIWcVc<$CyL$JIJ6Qa1IRwbN+!F$GJ$BcjWBRGEbIAMYa8hbny>$TAD+XHE%A
?P?WFi DjqJi$*BtiLBKS:RCRAeCK55SVRPWl=Z9QWPYnlQQBM5W//ShEbliZ/Z/Bb::Tie/G<kPq@YYKRC$8*=
:ca+hh Q=<dE\\LRNlw!ZT+8JenWlIAJkdSlKMXH5DD*h6i=J+<?1%ia\/$iFSX=GI=&hmKe1!NEK8M&CmMF!6M
HWSdIR SJtnwk+*MThIMw&cS<tZDC%H5$1\C4=$KF:G5Vk<Duj\WXAnR#LnL?F:wq5mI#YL5MwhCJ6TNVRH#R5C
T%@RIw PTRSBeSM^$AXeYlN1a^XTB\!BSMiWKbCHY/L\>%+IkFBI6%eVX>TSRpRc$mRi1uHVKKpM$EG?I5aQPNG
Hd+54: =kX<NWI^qmY:!D66bGd4#aRRwCdI4:&@uJ!JdjTw9h\k%l1kb6#ER++T>VGpkwhZ?EMWK!uhZc/\Fmqh
4>wGqJ kI!1m/qpdAeY6ZCmty/FuhBXIKaawFA&YkdCdItCmyttTaR$dIt6tcAcae=HDRXmYPpm<D*CI+nSt?YI
u<6=&9 I*4IX&T/GeM4S$&=TaE+5CPWRRhE&qlyJ$QSmbhM4<aPbR?SSJ!ZWyIAJZIqw?8EKBbcy8BFV@Yli=eD
Xp1?Jt GkGtJFIM8KGaCVLi/qut%cKyHJuCF5YcK?p6^PILWS@yAjihJSWY51p>BHw/SyB+t6/H/aCl=J@4wd<a
J$Gu#l V5RpP/EyC!EpGFAQkIA>cmaP\@LAKlKA\Kjle#/*C*Yk1ZcWw^BLlRAYVeJeVH>%X5RpmcenSIkq\NeB
4=tCDJ FkZK<N=wV6Ct*4qw9y6MMA9V\V?6@@S5XqY\hwPEBWkWQB#LCC@hKXEu!$4CyC%5NGW=Cy?@weXIyCBn
&FHXD* +QtTZq6\i9:^WZ$^u#BwR&a8<1kVkKRK&qB!pRVjl*S+myMbq$8IpkyDmPtIa4tn&jcmwZ!p$^TnZTVq
cE6QBL bWlb$XI/G=%5mu+AJaltIY#DG5:eWKSASPqDcc!p$\dYQAlJ*Aq15ckbQ4y^D5T&\@G=KMRD!\\ANJ:T
X?J!9+ KT6wnyjDq*QuN$udFR$%HBjewBB%jJbwcI=+KAnh8ACq6kedmh5R1I1JS$>dwcehyDMX<lJ*Ki\t!T/#
mu&tL% bF5RA#YlI5^G9C<tPRqc94yKcI%&n=V\$=Fpb@wWTk:E!+FkYa8NqJiFajQBV9T?R%SLNkS8IwHjlCmk
-A5>8# 000a7a3407000110333 Page 137 of binaries1.zip
qRb#tV StyVIhWpTKc5cmwWCE<wGqwI#T^AV=8mlIa+X4m5jydq*K5lHXpZpSm<$pnPDAJG5$W\Fuy\T1E\l6VG
#YLm#p 5qE*ccPNGJp4/dTT5iNBy?51GB^wnA6F%lq11$W6ThlGG!ujW/GE^Aw>teIHlW?WV4uLP>hWqVmKhc@Q
$AY96T uWKjTE//mBVMahMpFG5be^t1e:=>S:/WuT>t^aKSD>CcBSnldGt!j@wXM5IbA68F&DlnjE8EHLBBh*k?
qRAj1h QAqkAAbc+!F6hJe#PYk6Fil\\nqNY*KI*5piF=Hem*!FmBiLyu5kE^j^nVyw\FlKTbRDDuJ%nI^yC!p<
+dcRWj ^K<Cd@tLW=WZSchJtGuHC:&L5HB!INNEkkVIY:#4iMdR1K%<PkncuwnlB<kwKMt$Y+JlM$WNN6+uA/P=
5/\VQp F=F$YNkQ<mIqYl1EH$VaVKpkVFySAqWpR@l=GDyW^jKTH*#4NDl6W<Alc=*pH$>YhaRNM9&pFFQM9m$I
84$DdD u+DX&KBeceB$8k#^pXa\WT?*keLb+5da+aJ#I4ZjwbaEXEhlSM5mNKe=a<kPI#DW?RMG&e9SQB5JkkX:
c>M@11 WhKP8dL&N&JKGQLS&+b&cXakH4Hael\jIT6JWRF#LbJlSD9Q&9$8GptF&LETSRKc+k%%bE6cKFZC6bAA
RDN5Gj AmpG+wyWMY<XBnc<dGNDycB\VKE5m!<bCyRNdbA*W84wVBqmGDC<EcLMBYjtk9^ReNRP%YtK5IN\FAHA
IH/VJX S!E#<WDtmm5&d??eCpYp9#m%&Gqam>Ctt<GKSJDNpQB5Ia$BY5AWh=SkYaWa!VqWm^%caapAEI4nByy#
enW>+N =EmBFF@/yK<ekDFX!q#5/Fy=^AckSXCFQmp>QmGdMpR%kqIlVh#B4YI=T\R$5dwA%W6un91kNduRNIDM
Q6tqHW BKK$lQA>SE8P$bHJR$nLQEk=nXWdA>4FMn\NWWhIEHiMME+/E+SVBby$Sp6cC$YnldIP*b?<Al\K1IIZ
Ju$9X# aVq8+8dFVW\ItQEDb>dlPlbIplc?\5>D9=!w16YmPycnY%#ELLIwPRGFBM8a?SDQKdmVI1Q\hKa^WMX1
&jZnIe w?/LR=bl84%wWaXS+m$?c1aCw$qDW%\AbL=Ec!*t#?qCHDAA1$@SB>pt/9Q%\MbbZAWcSX?DFSbXcjqm
h@K1%d 8qHa5qHhZ4^$NFqYMFE%8lAVmBXSDICY%?=DijKbSVkBc*PumRlP@QtuWCXC8TJAm4k?b@jJT6%BqwPa
6GKbl4 VRhDiZ5jVNlWN!A5+>M<R%EbXeM1qMJGPF+1XBE6b49#Y@R:y\aBHqM<a*JEtTmbK5+mhI1TudBZJ?T>
6u9A1E m/ZaC!I>T<J:nEk:D>J++?k=8I=5<GM>9pWu!8B<\!lJyFmM=8SklY=AC\Qh!RcuPcLyGBRuHh^@Ec<k
SheaAA !u<?eaA@KNC9a5GPV/cY5b/Hhd\Gy1<nTu*JpA&Yu\4!\&SCG$t96X^LB8u?JQy5hEiCQJp6GdWXZ^%E
Spi&KE NTMp&AmL=?CmcFX\Fl49kPLdmXwMJBYY!*>NRS1QIFw+WXF!VXNeNiyi^Zi?4dtA5PhD#<ukEBZbq\T^
<1:nFD e8WeGnCVm<bHm@ulKJ/V!%R@1EttcT*BmqmW%ly/\:^#jQ?iFlR+YGbEYmQ9ZT8y!IKTp#DAR4VaEI?E
k>$YLd mn4%5Qm=Q/i:H4dZZHw>Ay8nyuZF/4k1\jL?I6SNi<<1PA*NT$J%/JX%:ESKTKDCq#B&GYTXaXyaGH+m
qb^JQ# S8&Nty1L+@6L#*!SKJ*RQ=>Y\YwWJ%^<Q!H\!dqhcy15N\SqjlnNFCBl5ImbL8Pqw#Z#RAFGNITGq45V
aptZFX <VmAE!YbFplt!6A*>/PHXpM6y9JpjhEdim$HQDcFKY=bJl9!\kFJcL+*J8!#RtEJNCbDcl+&?SI!bG<i
Pq@IA! 5&*ZXBT&Rk@mlW9/@AG?5*VKAi!pI4CP6kZK6RyGNccky8^pw:E+XwJJ^*+^uI/T4BC^eaDRG%q^de&y
dE%mDu AIRhAnG6SM%hM5Rc8b61%=mAc#GRV#9NDPtki>QSW/VVY9#+/6Y=J?<i@IMnE+VKPl^pMN%^>Zquh4ye
N<NKtT c\kKR>EIZ:!iuD6w@i58C=E&WHV\!#=YFBc@EK*@/Pl9V=^PQN@:&&>5h5@TpVP@tLm5\@*^!>I@j%uF
&nJY*6 ?w5I@^X*=liujZ@cNj*yM9QLA:8@N4wmiARR@JeFKbhDceu&MkhpA&&^dF1w9dH$\m:>Zy6<X$wnL@5j
jJS?@A F1SS5=9Ce?JPb9e5ettJ#I**cd>d=N$c9TV?=MRj@<8ChH=:ZF:C1S!9hia%6^$+>E@S>wpHk65MY^=u
F6eC\9 umRhYVBtSF@u?\<L$4\T!n@^D9=QE>X@9FwI/:1EFYjuXPSp\!:BPT9!5uLm=kjCdy/i5Cj4Q!&ChSj>
Z<<bdm L=n4@>pt>q?q<Ht!*Q+NV%$Y/=>n*j>H56^@Ij?@Je9>X:nqj!VL8dL?qm#*u@:C@!Nb#5*L>j<9!ZL%
!E9E=k 6ZIWn>ca/&^YL+YGB%epqL4%p#Sm@VmKm#XJt\t%Z/N=G=ND4VeA@VY\p6<leS%Ty:tb<t#i6?n#H?J*
:9QIEI JRXVlJ!iXla>qmlue\9=jF46jC8^@=/1Jh%%V@9F8u98bu5>CA&K=i:=XPB6G4%TyXSPqb+tp4!@ii+q
EKqtA9 L4&a/SRw%q=%plnXXXt9!Vq%h@qF$<mYAciydFh/Dbdh%>6?K5E&EH>MpEBhtadlbjYDuX1l5#ubbyhy
$lJQpC c<hCq^d^*p9$&&W4#=4EV+kJH491w<$8VXLE9ennbGNh8j/Z/*+FC!ZmK6ya*aHX4m<=<q$^VM&!lSM*
FqD6$R c>!n&4Yb8^#&9h?w/unlkY*Dm64aVThE@aly>@Q^\^n:t\bDdYh8By+/$y+*QwS^:Pe>Gnn1KHE:*dDL
LN!=6X DH?8@y4k^6t=e=DW@pNH6^P:QX<4cK$B$$RQ4aQDCQ5*PPP$>uh=l#cd:6C=4Z8ZN@F44J:n\X&Pywie
aVb58< yk6:ubi^M5$^KEGemd5pM1Ebk:4!$iRcqQ@I=Gl5@mV4\99SK%=%^^1#L^=nhQiePqVY\S?SHa4<iQEG
Je*y9\ YJa&cnj8qnnL/>BM>yP>+c\PK#<h/ILi\j/&^@:%aPT4@6C^!DGDmDLcFh1^VZQ@<8kWIdHi:p/<AcP4
*k^Lyk bi%9VmVFZ\<JeFt?<eWN$1hQ^PMN6b1CFNI6$<<JGNLGQ<+SC&1?JtF$488ppA$VeTGZE8c$jiwLY/m>
QZ<nII XiZm:^Iy>$:$TbF=4nFt8>!\/V?BM*n5:@JkV9nulW@eS*@QQb#$4ie!quF1y68yeQP9&j6B#t?GaSXN
4l:hmD F\J@e%VGF1c1tl/eeNu!TN*NQ/D6yS*1P$ce&$XZVHk?<h#pKn*8jZDM/KtB*D=F>!Q:6mcT=uinj=#p
He%1PP <D*\8E?BVt9EB?V6h6ji?1DYw!tScy?G84RlY6+tTikjS!NDHaa%1qQ*<t<a:u=A!+/Rqp1Jw5VS4\hL
j^dRQe P^=e8L4!WN!6@NjPb1+*WF&jq4=>NbVuNE/cmP#\uQ9H!ZRM!dJH+&qWn#jBFtmj<%?98aB5VQ&KunlH
eE?++C YqZA>u1dXuuQ?Bnn$F?LQ&cEDuW+FW4H4un/<YL9qy:%DuJ/9uqL!4Xq19B:y?>>n*c?Gtu?^>C=564j
YpEIKc La=Gt=i=Zw!qd!I<86$*j>jT%>1py=EH*h1=R+e<LZIM5a=#8Q=nJwiPb9?&KiFLj\NJ>4q&#P65/yqW
YaWN9C 6%HTpWW=b*e%EI$K=NFay\FHVn\R?XTeS>S6>bEj@4L+Zj%m?iaW=6:WXwluZ^blu&L<qH*aaH!F1%+*
i=@ZXL #iHbc9Nb:edL>*?pHdD6Q6Qedbe?tY*T9:!!t=Emp:<aal%/h8b:$%abKia=!^Vq6uM5/Bk&%#C*8+ZX
BqJjmY 9cQeNJIwm#%ujFGt=:a>@GC=1eukw@S4Dn9FF>VHV>yRV>\qj1?GXZ$?+46=YdZp@N&B5+!:i?+dwGk=
FXN#@: Mc8YPLDHL?kytdu/11H8iM9$eGq\bJ=ymPNVw5y+wunhXb<bP^>5ZqykX9$L?d#=9Xe!c6?6eSiNBL6j
61kKmu >6Ppkj6Th4?ba??l@tVy6=N%bNHt1:8QPG!4&^YqXdIhu!>!&uJG9St?9mQmib^8=ERF5wj5+5%WJ^N8
n\$G#p LX<:6a>qP/YCI4S=FZtF9m%T6e4/<?4GMnHK&LPhNQKIF:H$8j@kW&K*1D5yLiIVK>y4@\Q6\VG>WJ5L
8M@S<X Qee*BR^EQmqw4Dnd*LpJY6T&%nqjdl4piS+eP*ZTqdH:tTVLl^9^>FkT6/*e=i/XE%jZ*QM9!jQ9:T^k
!yF>T$ Luq5I>%EJjGXw%8*l1%4Q*nhZ#^+n^&j16:>:I><=1WLuw$VtY9H65EekG>^6dSH+Z!==hCuHF=#mKhL
6/T%i8 tB66KCV$$EJ&XQ!6%^6yZlk5QQ=h%ll&Sb//N/d859Y?V/FHE9PnFpb?+t#P*Z4tWNYSBR:dNPS8m:tJ
WQJWwV m8Qk^4NX?VuuIy%d*ItPN4RF4#ecJY*ZVSl\hJc+G%HX#Q!u#<WLa?MV*/NYZqMIER>yuwy@8a!\+Nan
88/%Qw :=kTN/Z^Fh>:w5nHER=pKAR@C>!E\dt58Q=LI8@E$yjqA/X9LAIY:p*h?X9d\9#eudYd$V$@ml=p>uRi
Ra6XJc S\+6Z:><eenNhdwIP&X#\QG4E+VKtLC?dS=>cWddE$6GJ6iy=/+RQMS$4!^PM:5!&Sj5<mI9iNlnMDZ5
qbP6t* <Ppm@$ibQW:^X?^5#B?I1!wEh%milFZP#%D:V^E*CpaXV!dj9N!C9j^/^=Hq4&/#4m+1t<c5ac++9*lB
Jmp\ZW b^dJ!im6V=4N6kjY4V$4hjTiH6m@ui=&u?VEjhdJj$M9PXM14!:$DHRWc/djtDRCdeP*5:+llLEA6k\D
<yk4!6 GS:5mc5Gd%l4:>49NNmV8B+!+uSpQ#IeD$/j=m*Ryh<pa#qQ<nK!#!^@@5u@R6!M$HCV<hKT>#iGybhe
Y6ZMey DjVLwy<@?:KpS*E&4>AR&>S#i%h=j9N>&*jDH6*i^*C/Sahj#w@IPPJH=%j&/u<J=wYBX8&qAju+5diB
EDDCtS IStRTtt+9SbMZDSt515H8Gt\6Y!Lhi=?EuTLt1@%J*pQZj/^K$F:YYj#Dldt^#mu\wEe@$CK#d?5*:I6
!HM*JR 9H9jLuu:=XjuR$iil5VdH5ceLn4MhjmmTy+4YhJ^&P#NZ1S4MiEaA<h/NAq#hKMCPi\q6M$D6:ST9d=H
nBi@HM tQpX6Rbh^NWL<y#<V*?*&ZDd88ittGC:SGQ/4ylc18B?BSh?WG^<@be//l*$FDlhZ*^ThaA<Ty!:>=eN
TZ$$>* nR$LbKDIaW/<8qtT9iuA>F/:SZ8?hba%e8mcFleCw*5Ht9Qd$GwS\c6cF&/1:MDdbaSbc/?9y$166:F<
&VBHyV *+T48N<h6yWe8BW@^4^Cc#m<ej<i#%Qt><ITW$$KJ1dl*FjJuXt4l%emNZ>iCH%h$Kw/jFldbhd&F8@<
9t\qEK :4uXk/:1Y?L4t&<a44e>9u?d\dK!k$YH#BP!&pnk?VRd<?V%l<?N<*ydH#mPTybjKu&1\!DjhR:\X=\5
ZbqwmV m?6ujLA>hYVb>D=aGG@5P68>@M#Pm6KRKXcEnXQPehp8FJ6!>>mYVaeb1:i14\%QpN$>#8+4Y@EEjLia
a&988b Ej8J5?91XN8n:1Dnq>jcbY>aVR%ahut?e49@RByK#&D$n=ZZk=?@uZJX4CknXLc>T9*$%QS:h4NN$K8A
8CQe1J <ZMPiwM#k!&9=6<kRk@T4:6l??>?$TuWhb^?KB69e4pdkHtQ5!yuEky@=I#c^q!C\q695aI^i51qPZdq
MmR#L9 Du#?ljEnT@1%D8q\TA?tj+J*W:%Y&@XLEL6/kJ*KKa/pyK?b@$YYPhPmVF*G##<W?Wj/la$9^X@^<&il
y/ZX8d uqdcXJHSKA@49Z4w!+jLTFVmXd@F!CPQZC9h!eGD#&dPwRbQ!&deKP^MJ>PGCMXm/a$t1=bM@wM#BW@8
-ADT*> 000946e470e00110333 Page 138 of binaries1.zip
jWuk!E wJqjh&8tL%&GwG5m8XYN@i%N?=\ZS4R84mG9*ui:>jZWmd\cVW//G&GehKB=Hc+@Wm#PCE^+885%j4w!
VEV>bk uM>jNJ$kc=^D\E^9he#ALpp+IuV?#XwI\@?Wl*9?H#M<@nM/Iim@9wd>@=:y<S<=H9?h#QAQ<D>mGQ+#
aFXLQk 9iHjCju+*$Ma@9HnwHnQ@$<a\@<IAjuQueN@W?9@b6Qe?KC\MLduj#H1@&deQn?b@Q@P459aC^!Zq=c/
t1BC>< BTaWP:4QYXTcqLYwaFqKSHdeWu5:@$X=<ZtbcaWSci/ebd/lZqHy955CRk9!lE6<q%u=?<e8KW>jFK>L
R#m6RL LA:%!I9NDm4!em#PTHWJLpu#CEww<e@^m5@MLb+d6yn6=qwe+?mTGB/*MCE6hEFicFBBXp=&DL9A4Z^J
t^Ae?G jmHLP>>Dq:k$%cw+j@HT&WELm:K=4Lpb$eGy+XF8HGb19D<9ZbCeu=I!Z%nKCIk9mA+1!etQ69bdJQCM
46KDl> THSdHJ@CTM$6!?Fb/SKn<6\nM?QL@Xn=KWLdwKR<hknjJZ%bLmM@*#Zcht:iWub=XP:C5uB&RNtTeq=a
H+j8#d 8Z%bZpbia8G!%MZ=mYY^/j/&Bd4ECP@5=WqBT$4!F<>%nHSh/B&*JF4ku%=iGlQ8G<$KVa#u#e*JZlwa
9T/dHA FP=8q%i$JD/=KMa%QVcnQC\wKt=S<d!!\1\=8pVj5LlFuICF46Gl*Hmd^PlIhtJy&NKj9%Ap+C@%Kq4w
Xp>J5+ +^Vn!ewyCF/TG4KEXb/\NJNVH8d9Fb$eYJAiNM<*P*6SkC/S+?5Zu^#I>@NJm+4%!$uJnAm*h%4kFl$w
/k99V4 <Ft+LJ+:Q*%P8CAujZFbjqap$#1:!CuG*m*Bh%GBb=D#a99<PJ5MNq?Z8MnK&!w#Q+8@MNhQ5MDdQ5CG
Rc5S4F G^/Yqt#HD?N/J*kE?:mY<SQuL!?iHbHI691@&H5L1Km@66?dtmGHHJBT/a=lmmGqGZwaPpR/lp+XWiu8
cyu@nY ElES/i+YEiq8EBRS/bbW^Qm@*uti?%dQu@M<=##98<=/q+8%HQV#??*ju8@i5?j/:u%hC9\1qk+tN/TF
cW#%#b $P1Pp1J\nD+KdtanD!JV69jX%:AXMBD^hJRTh44twG:kwcdKm?K!EdMSFabIPXn/ZENl?DW=$Ne<Wi\R
eWEKPq E\=nHuE*JB?u8wGZ@VX6ZjedQ/Sq+Ic#F%SGC*qJK9Q\m9Ey1iNpjc@J<QBD%M!q=aTW:CW\PqB?QZ$F
JPD6hm YdTkAhh%GSM#i\Y+1+cHL1?+p1eK9/?mQakMaT!lkqCS5ij%$4dZENdZ^KB6dQuq&XYhJS#648HMLDS$
%D$Xij 6K:yeNuLCWt+KT6^P<wdZ&Qu+?YRpZhVNVE&ESaTpRGStd1y<N1k#SRFJR\SeD5yHkh=LTWPD\#KDe+q
J@k#G^ /K55KuyhYqHk&nWIu\qcuX&WHcjQmSL!5HJT=MR1KVwJeHn=5wQIPCVMuZB\W^<jX+TkQDhW%FHQX5HF
8C><VB kW9XDmwuaiPL<Dc#>aFh6+TdcQqciy1yKykn^VpMSDm$+VJcFmI\BRq?SSCbwDGQpa?a5y1iCa</\6DR
9n@nV^ YENeCKJldTIn^c*y=i$4w8Ml!K?lwm:Q\ee9b+dF!kqL<CEpST#+BKWNdVFCBnK<$mA!ZqXHZY=%V*t5
*5Cqp9 Id8*yLwe%MKBn+j@85aN6Im#yC?KT=j*8w<kP^TLEed1T$P=eLb\>D*bZ</B+9?ympFm$J<1BwtJZdSm
PHjH+G $N@nAj<ibjmyC5:jGui^<IdEj\EYk@^4jPMj/Q<p99GQ1ph@nY@AED@HN<VEjw=9\JAT@#9CG!!W\PD*
I9%HC! He6EeMdaum:Q/pA#aRptK/CnjC?CNRFNVMn8MallT%W9TH+jYuqNLJT?G:myDHcBJMRTkZWVy?YBwbS<
ZP>qAu iW\8wVcCLHLliiyyaEhW&ZCRuy!8C4YCkAJk%TyPuWm@EhVVqST=ZuV@?R*Smidhi+4?#LGX//<hY=@w
D=aQ!I qw#lbkI^nhERSlASRJGX4bGQ/%Ea^$VmK5bH\9Gp>=n>qYwBtHFEWykua/!KJVaMAGIeh8Vn*P!X?9di
SwTm\D y%k>qMcN4bmL5wwaaMYL$l#P%4N<RMqbS&=R?>/Lp?L#1$kX+Jj:Jdi49TQQ%5P5Sqd\De&?/\tJDN?w
?tGq@Z i@li469nXVk8^G<GSWtu8RmQt5P\NXXA?yEN:+5^<\%:pEtJl4$98kRWpDL6mccXAPuy5AyIM=M!hSiP
PM#4eW yiMy:l!MiBuLT$WSyGpLDSPBJRIp$A1@18#%N&u@J!6:@h9u@WZ4hmHEaQ?yWjn*i@*HWRkV9<AwqHh#
:=b#8d e@@^u*@<E?^9MpdA+Q<apu<dwu?ZNPL9m=y@H#A@Fin/&^Q<T=E6ehT9B^9m#%p^GP#ZLQIC>$XJ@JwX
A@$ma+ 9\ALk@?cSX&AFj5NK@HuLAL%!&JtCCnpA8!Qh@!Z4NkFYLHj5NA@b?Ew^K>b&AXa!G@aC?kKllV:NZ5B
nlVytT ZWF@ZjkNAd&A41A@l5I9&R9wCm4&G@aC8946y^bW+4<A\!/kLQHj9E5\5j<Ci\FqITG@unqk@/w5P?<j
5#JC8i Z<?$pCITIqAaAwEWWZV$RN6b&a4ASH:M%#=Pdk+m9l+mXn>i&Ql/PjueF5G+8#nb*Q:u>Q4ZPjDH1*<Y
hu5N9X !hN$euQ?/@S1<=jbHwbE5EHl<L<&D+yA@t%thQi!@jHSdeaG?i8jj&<i@L?^iV??PEJ@>PXjY9mZu\8$
4<cqP* D9F9c^\^&L?8ebA@lI#+<Vu^q?KIj%@n@MP*?i5cB@u#GkiG@JN4@uQh>GM!?95%@:FY?55%ESK@8Kd+
51RCQL #?5tPA\B?@PFE/DLK4BjDlITE//wm@<@XqCFa6SMw>aE@Nd5nQBID5Kk@ta*JDWwk6Ca5SMCb%G#:J\w
ml8>4I :mWGRd5yJklwj1mRp<KKJnl@F\^uqh@TD<Id>+KGkdk==ZPc:cG=LNdW:CPThNhbZ?&Md<<FF69WyqEi
NljE@h +59%a@WSTmS%T@4Yi/CI+Amwdm^#tEHbWC?C*TZXkW>CY%:jcjh4LI^cq/@L$&QX^myWAj4RtYVat+BJ
BZ<db? 9<4/jiBpuh*\IkjBHHYHqXXhN:q%eGASGS@uZ8$Z4i4Se#/&9RmPEQatX*I\</&9MM@<nV=tM5wIEi1e
@RCCKD 41E6%%ci:*%/d8bM6&+9@%mA8Vi@>Sl>H1KYWt&*Mk9pCE1\>PIZTTM%*tbRGe:nGjSQjXydDQFmBd#5
GL&ALS VGaBqlc:VApNnwPD&CJl$DD&GC/iPtE<:P8tTna>Sj^RGlaXXkGM:YWT55Vp=m4q*T/BtmylG*RIpp*Q
T!/mQ= ZkBEFhLQ%M1Bjw$CljC>l5b%=ZSKI5ipWw<AlLeY#y16A%jFa&*+%nhimL:i#t>kn$/i1C4SML<EnQLl
6G5Jb= 1Cmw41WNc=DVh\p8%S&!b&@Np<M!Akn=ilF^eiQ&1@FiNkQEaaR\u<>^?\i&LEB=8YS^cc6I*P+pJ+mA
yCTNEM IS#PPAej>FpD\y4jX\B*ywKWFdYd$+TJybH:1=<N^u$MPPDVchRa!Ye98=LFniC*ZBa^%qLPInWDmq!S
c9<VPC ZDXKc9cq<yF8n#TjF45q=?>JI/i:6F^tyAA$K@HHjj*ZPbWBXXI6&yKeq9P?%Xb!??A=4#6JqyL$y@Ki
kTq*MX abV?wd69k^SL4J=d8acLNStekt:Fmc#>kRuZpiwNi>ZFhjeG6nKi^84b!EL&=%m5!^j5JMw5V$d>Ey<#
t%LZ1Z Pl:WeDi??Ya+\6@Y!k*!XlKX+Z#DZq>L@jM$+%Dh@Su<tI&dF6QQD+:+KS58GcBPZbNAW=F/I8Fp\X^#
NJJhnV 4/CZ<CbZ>NK9tIWA\PRdX+*9+Nqa:VGHj8aS@>SAZFCQbMEhTi?N@QF5YSIQ?*tbNBIn9T$i^lueC9h\
JSF&J: XZE@mbe<uyQ$h8ejC$GjdM>RZuq9h9A/nQL>Ma4kp6WM!ZWk*IlJ?e4:@w1GeCq^I>:46YFnZTi%dZEe
NNZR*w mjp:\wpaV8<&9a*:hw?#*+T/mGlNcMVJKq<hnF5$#**4?XL4dwNQjBX!6jup!tZ$kR^l1dnM6FSi#uut
n^4?Ct %VJ6/c>!8188>@XTSmijwE&\#Y+Fh^9Q#h^D9#+\!:MEjyQl:SpEnd:b55KyENRbwn\Z#D:+h#!h+d?y
9\JpcQ MDjL<8d?cM?>=#Meu?dA%LK8l&%%Idit?^WNBQHY!lH=QE:+IY&KleP\CL*W/ueC/V4qtm\q*k5iE<hh
%wYP5Z 6y45ltI#dmPE%HaB?WL9c^pyek!bh/S*Sk!qDA9N?#>@=!S^kqLdG?4V1RWDdVNT?V6#KDZqw@q/<$Qb
j+J<&& C@LD!JIRAnpL=hVJGZF=<mliJVqWiijuT\qpnqw1tYLJH9JM5iXPHQnt>AS+C/1#GTKtyZ=RtlAb^mq?
i$D>b9 <!RXwWkA:c*4bQnjVP!&mNI+5jWW5Wtt?iAWXZ%V*AkPFi+\<VydmbtMkQN?JHB#C+lb>Z\/hhZRbeI4
kyV4>S VbXaqHKFTAaTX1mA@F/nE>Yt?kF$:W1nBCT%M<AnD4LbCL5JNSP<H*AeVT4\5IdcepiQn=#9n&jBPa@y
>jci&d !pZMS9^MRm$uX=c&ZtDGTS6LDNZQ6h5pddptQbyY:<6c&qKnQBCnXRnKkK/l^=cFaVe\c@qiSn:Wh?5?
aCCd?d b!dYu:%hD<EQnePQ%MS^uB85ekTNNIPqmPe?WV$/>@h<cCAVddnG^y!WZmQt<hKAyMTw&K%k&wKc9>w&
EMD/56 =&%I4W8W==5GBXi!><=t4w/i:+Dk\nLC#GNBm6nn^?6iQtBtVRq1Ila^Nn*nTct*$q6dlpD1Nh1Ban=K
^wT:YL +Y<c&T%?*YX$\%t^E5WG+h@J4n:VNQb%@F\d9mLB1G\YZJG@Jp1Qu5nJH@PSt=Cjt<w6ua/Len^Pjma\
99w*=% M&YEL!jyN?AQH9*pb%KWy1@aF^mYT<mK6YNC<yDmFWlN4#aXyLTVHTn$q&aRWypjP+SPEG%&bWk?uZ=G
A8FMQe 4yMIdJ=AmLC?+pNl&iWY^n%!1QcaB/:%kBM1$Ma1JM1NmAJcp#iNBNpJpl1T^BS4k18F6:8kP>kN:GWp
Ni1kuH 5h!C1FX4NHS4nP?W+$==&A8MG+%G>ewMEVQt^%9Qn<*&BRY=G@NSZywm\YkeQLFR#H#^\N1MD%K:?!H=
Te9>Z* &VQ?kV\%\Sj5&*iMGpB8nK@#:F<ubBbL\q#Gt@G\BX$mFPq#8LGF4k&11Y$q?!S%t+WRJ%>5!jmV5>Mu
i>M4+% hZ448/C9t=H#q=mLF1^Ce<Nk$95$<m5yV!%T%@d9FFGt#J@4CYhI/Xn%QSEeYTqQuY/?Ze$qRnS@!ky!
^4eqG& j*9Jt9SacEXS5?PTIThbaGpJI54?51D6Xau%<QkT\J4JRpY!Y6RSYjahP9!HV^hdEFtdn?<I&taE#?4S
/iqHZu ^SpT1+\<MMtn!^kWJ=ty+Cmmit^68+@MEJhtjtHm:GKjieP$d9Y^ddc*XpDXZ1b#iqc*MdWQ1tNIW$m!
G=X6jc epA^&^8a>pnqTpMA+%6hI<uZ^b8l+ewNRZK8yc@JFVl#MPCE+K+JD&=bN^CC1NGG</$lRIP*I+/$*K%S
\+51SG @N!@jV/q9u@pNNBQ<1dD@FwA?b9#YJ8Gdl:w*m1bpH@A8<\55Md%dVKCP\uaL!\?ubhZ4NJpHKT@MKqZ
Gb=a:# TMT@tEuuGPb>Eu!+KEXy%?^n\jww+MQM?YYJ!6y8VRG&uGH8^Kt*kKu6tqYeqt=4E#iYt#^E!WS\ikwl
5Du:^: 9?HH$u%t<HyMCjHCaEGw@4nSpY=YKMLWQGjpa*BKlI?kd68NV+aPGnnBtd%>*bhGu\LdIy:ZntY+%nZe
NZ:D*u $Cuy@t!j/VqSJi4>\tlG=bQF^/hd^J!XyyS:tyVS$VeM&Vd68!wyMnA?P/4am1y>w8tVK$JI&6Ea<X*Y
qGTt># h#QHySd5ZWNVDNpL$w>FI!PWJI6bJ99pi/<%*/5>9<X4@:1?<>QDi=$4=VKdqCJthb?I^!duGibKB:nY
-AqSA5 0002f44668f00110333 Page 139 of binaries1.zip
X#G+bQ du\@qV$=*Xta#P\!+nH@@AIEiTKdG*+H+by\%E5ZupIZRpu18JK<dX@>T6Hw#yNHb!LNX>48+e?iSRnK
+B*$i6 Ni4WLyi4<JFdQm=Hc?G=NEb+bXMal1&al/5GNAVm:D1#HkCICq%Kl^KFbHE<RD8S/u/lh$8:GaWC8**N
Vy*Duq PkuLSn%k<=Bm<>DC9lCFS*t?lNX1lAAB>>H9Y!Qjm$eMAh\+K?EACd:IGYCGWR>Bm<NT4+mHPkd6wJEe
WKLc\9 KQV>$hD/98ZmMTbaW1Q/5X#5+=ltJTX1u4#P^yJXiAm\y\ND#9cP$FWI&T?pdq@wV8\n4+uB>b9kP@hS
MHZRmP ^PK=:IdiF1Lw#^QSCV*a%#E@KBi^?dBW@1H!Nq>p<LBIJEe4AK<R^^>RGY$14kW=:jhbLWJdYY9Z>Sk@
aGdHRp L/CqtPCIWF#1HhP?G>=h*SNA^j*%lSkN4VLeTtDayy@u=dyKyK/tq&4H91PZMlAjmDG&+4qBK#ja4<Q#
=@+SDR ipPM^td!W>hNil4eucVkE>Ak$qQ/?Sy66^DjkqkCTDjL*<dQR!m>M$@lka5NncD@m+ut91RAujL>V+Pp
uIZEB* yF*lub=e*RLlp^CXZaGP=q$QC5HhLN=Q>M+J4G\apFM/Sdpn4MiQp5S4qi5yE+$4G:E/nuC$p4IC4Q+H
yhbZ85 R%IXhXLtIEkT^$%k%F>iWp*$#DwYX&aQmZwHPNkM^*PuTGT#/<DySHqb<lHpduMT&wZ4KAeaAETJPJen
eqV*CK lp+PR6b%heqi1bNa&8Ni<wBqlc&y?J@#^YS@K:^X9l/k8lc\RIbTHe@hI8\QF:=m!Vc=qhhjT/\8RYa8
l%*MtH #bMqdt>=J#1Bd!Y@N#w!p*6epF\p&MW4Aqw@H@>PeDV#lkwdbIPaayNHM4!\EWMJmhYnhHdS64Re:\8k
X!X=/? 5J6F$%RQm>\D%CIL%lS/dj\qIXXe%HXeCt\Cbi%cR>*51yew+9aDFb86SV6pAeMA9IPyiK=XbiC<yiP6
@CH&:> PqPM\G%E8GE%+WL^?m&QFM^WXP1NQh8k6hB8#e&R\l*l$6E^+mIJt%eTuHRTBb!I6T6>hMYLhM+TqNc4
j9=ddA Yl^F<aXn^#+@^nNKKW?T*?&61+>SF+:hVpRea4Gu<4Ww#LBZGCWS1\wNETRjZ!/q^ZKQy1i:jc#XK*\h
?%LYH/ l#\hG/CNY=wX?L/DVy?u+n4kQ1?ID>@b*:Tq9TeL1n>e/1!4HFj>wC%BVwEXcYA4$JH$pX6ha/\4aHY1
%:eJ\P dJAekW\PTS++C^XW%4@tZA+=Md6Thc/:&@kiqq%bhHA\JC<@uLt8uaIjJp\SS?5$e9Jmu^XR8cGY5:ke
c%CAp/ 9aVqJXpDwhbWq*XHGFj1LF#mJX@FhY!Re@Mt:&j$K9lyVm:CJaN>4wq*FclXT4FXTCtDX!W?JE?Eh$l!
16kaJk D$=Maa@+&DYAj?m+P@Gi6EuC#>Xlk+@mZh:F+\bJd#JVtPCQnJCXS+/W*KI5AAFWu^G16n=BTBiGjbZi
RSQC=^ qbD=Me1mQQyn*^6\hkwQ!V:BLR<J&Sybn8wwm#RE89M8hjiHL%W+5q>P9ah^u*ZR6G=QDIWLCh^65JPQ
1kR/a4 8YbEM%$4N:nejWai1HeNSwyQ4pXJy?Ke&E@C\\PpcM^XZMda$@D!>5yA5\9DZ:6YJRk1*9M8hVG9YkkB
IWwV<L D91\LWlWKC\VV14NhK4%5m*!!V$BCu%YnBjjJyaC>95dApQTNuiIuy1HwWR6hc$EDI%FK*6uicb\nwGI
#yB/N# dwQ/4*/?8!/D>8JdnhCX$hbIVVI!9^5dkZhlSCZFiyD6QDX>ky6DX=y%lk$T^Pq*P>%:qn?EB#kpwD=\
MpNT&L QXCy\:/ENq:ZiTwhZ*<ANqGyA9atN^?Yu8&M5e6:BW/BGqRbiPYtw:66P:W=Sdlt81HpZSRe=p*CI%S:
kZP+I4 >n=+T<jK4EAAEPnVPP1?$BBwV&a=YG/R6ipWn4ILFq?bZdGb%ENMA@C!uE:kiqRb:$iMe+<AwMbB+Mi^
bB!S4W c?WGbupcFEqZ:Cju4CkwARXAt/4KAYi&5S+SM5CT+<anIC@R4?B:R/Bn6&P%THG>Nq?4Wt/%FlFdatS@
%F%*aG D$p9Y^h6kq$nQ@16X!hRRKE/5W/hDd&jkn=JCRRu=J+pjQJyNQJQn1LRX/D*=&hMGtA#DcaRJMn=VCyE
:@cb?I #A>SGKD#=+lN/iSIJRnt<!BJI>XPLhELWFLuHlDReubVPikZAKlL<u8JP$&+1RWPA/>plD!FpRjal=ML
9qb>&i E?a<:DF84S%&n!haeQRIBkBBZ1SBhtdWc>@j&8N=\uE=Nu/bA*ZPDwZ#jc%GA&**IdjDHBc@^VGYlLa>
EAc%%/ >ydGyVZiVJ<GM4k69GIwYA*AiN>AlbTP86bHeQi:WZnaNNAV=KZYd5WaE@cHHHI>:iWdnHlP1<:nwT+W
FykJTu 5A%%C9$eyhye68IiFbXlFamXbP9ST\w%h%Vbm*<n!+&b:$<QSpuRK=6dAt$TZAbqND<I=QXGpt<^hIWZ
TcCckP iYiSJcJ%6M<ZiZ^1t%%8Mnlh&?p94V%@6bET8M9NQA*8*P5D%?JJ?%BG+m&Ni96FCWHuN1k56++i&FGy
Ay<L?i :k1m%S=Bid9Xcet9WX#m$L%DMM:L:LcSJqbJphPX1m=b?>D9PXM$=ucp#q!#Ve*Yk>68lZcmI4AtlwiJ
5LkYIM 59V<?PqdFNGw*tn1IkHD\q/jF#nH@L#e*MFZ9pZJ981cVbF!8a=dk1WmIFRuZFD\lpNWF4GmdcIQ^lE6
E*cQKk A@\WV<^>ndHQGKq^CZH=MRu@a>YX^^tM8we6cjaHYEu/:Iju!<A*N^#F4#PP#pbTRX6JeP1bJ?LumHtB
N1^^lq la=?m<ESj6=pT4uJuJ8KBSHLhwy=dEbKW%Spn>!TPF<=mkV@$5mAwj:#S5cF6nNe&N/ATj!u:A&p&E@&
W8LXYL BlL!9&S9IQ:YekRC>c@&^6<nV@<YI+Q@HBTFTj^:aBQ//%A>ZP#QYVHw4\PdePmj5<njlK:l5A8\<F>d
6kLS$4 IuD+BhnjYDF\^J?#CPS9:w8<AI9+#Z*F@=!Fm@@tQWJhkEZ<lyY+AA9=6b&C8IC8aKnj5BjRFR#?/:=C
X&1w^k ZEBZ$N@h>\K/k5J@*XiIC?kK?y6^lLmA45S?a!$mL1C4*#wmCQFjlP>Sj\ujR!Rp^Q<b9piIKQ/abQ<c
4yFZ8* 9:eTWZV*<uD*?nEBm8k=Pdn>=ZechleP+eMlTDdwD&u<%YFARm<R\$ik@y8d?FiZAjXneyd+c$59$EKJ
j6Nq<? j*MEaBJ@8yQmH<:CZ^\B<X<+ApnIL^\B<S@##@?FY!pEtAF@*WylN^Ed*tWq#/6ZmM^CLIhayd+yaZd/
bB6hl^ SBDmpY@NJ<q+$$FS:aY@MNM$AECau1DyL4b@!1\%MK^Z9uNJQdSautGbLFl8?<DDpNa:hHlkDWu15T\F
VlC?pn cVAV8eRBGi8=FY4y*uV?aAia^jq?MLT/#5WTZF8%t!h$CWb?nBwD+ChcV4i\y/S9AAmpXNw:>#n<\CVC
qVlZpy nQbVFHHQ$M^llB4^p#$mheXLEp?hNh@D+!CdE$&eh^\a/#8Z:K:&nQC=W*T=R4djKR6uDHAlKKicATJP
&puwFH 8Q%G#mm/M&4%<uF4q4K6jljt9MRWl6=\5lZpcJDt&TNRH&iY&/SmjA\a4Ky%6n1Q>y\5Bc5I>*i^nLqq
\Hu&18 &DL%8!1FL^c\!?&^14HHiK&Q85ECtMIIZTpY5Y=ETY!n:F1eT6kRCJbX6/J@DDTbLKYFFn?lJ!Y94GW#
LZ1Wd: jSeNRq6PkTB#Xy4\wNB\mdmVPt\CkQA=I!SB?QniJaVaF:q*<BF/B*In8Ii8Nu#/8S\ayhZjw>5ah?!6
du:XT$ <acTWFqye1<61:Bk<A8a6dR#J\y1iC#NL6/RNK%#@SYWXe5+u6BTV/H^a@ZkTqiKj>u%b4%5GqwEi\X/
>pRFpb Y8jYLR^M8+HLt4FyQ==mPl?=+5piV%neE+T?8aubuQYhM$ZENt1W*LQ$ZWZBJB14P*iACP=DYZN=yjlJ
ly5mXN ldqn:!j>B+*iu16M^*i^eC*dQ!Jj&WC/<6RRYSGycqBY>?\*D<?G&MIdF1%5*%ymm8p%E^c8\me4/Tuj
!XDyKM +W\1hBJtphRPaNSlk\#Y=JF/@1S<%DHmNn8%GaSq<W%kHbq&/5jR/c/QcVdMm1qtck14>I9$=JTjy9Su
5yHRRR :iI\8pNGh?qLKCneMq8eG::yeP51nk^4pj8PPF!ditWiH\qYC*nn@SwwJ9iPMS!:EWSnu=SY>VdiaP!^
l%@bna i\56jG:JZ\8Y<D!MZqy:F8V^#lQW<DA6m1*B=>Z>md8Tq!9a99w?Mqu%8*#tA#=RM*aRjq98ac?#IJ<G
4leZZk Zi1wS^:LJpTZ6k4^BhF\lBMNGXFR?/n4&q^YC9?TJPj6P\BcFXBGVeX^yQywBW&?:Fb!!=#mMKw1pi<M
MHpSYS A?=u%Xaw8lVR<J$?I5pK9Kq5PRPYyde9aJ9nM^H!uBP1<*AGiW%bd?wiqab8nk?YFFJ8VyDCdP=%B8Yt
1&BM>8 W5bHM4M:Fqe8?hjEmk^Tq^8:4T/Y9w1E?J=uFM8VY#Hul%dk4T1ENyHqqyFFWm*6Jht\hpjZ%9EYuN/1
G#Tnh1 kqPGZBGMk:&j<G/HGVjw=@WDI/VBbe$?ahS%:\%=euuKaKXFej%C6y+p:!R#emni5qpyY+/RT>n^Mi1d
k\4K#6 5lwMc?=WhQVYy#I#wA@<6XWXAp1un=+>\B&WNt!^pAhq=l5YbuCY/Y5:BS9#t$FuH6IdwMQVjb:4$pyK
Jdt9=< ewRZ/1T/wI#5V?5d/>uw^:5VAjmdpBKA*\EtPXXd8>C%:jNCE/@?/aP/Dpb?=jdEh^CWM5ud/<M*#TqB
PIyJ9: ePd$W9!<AbQPRkdPt$cP4R41!6d^ldR5^KTkhM/H&<XQe/N!6dZmtCM?H5%5q=nnn\a<YlZ/>HCQMGjc
ELaVl1 eWy#I#1J\YewKItj8@ZknacDwE9m8qXZaek%TZdVFwYZt^PqTw/>lYq<mnFmhKX!^TNGp5II64hMVe1h
8ZnN\B aVu?w>4X8pe1e:iyH$\4SXQ^X*YFcphVQk4IDj<1YXNuuJPj\Se^*5?RG#FmWum1FS@j*5b5d/I%/nJX
E^^wLL XX%TJBKmE5$dmMTtCXlDGa86>W6b16pc5MCq6?b&l#y*hcul?1eInKbV1ekyW=LGy@Te%<Hb%m1dyjWF
T@^D6G $8jGBSqcp$EB=etq:c+4KRKq$9NtSl\/eVaE$j\<c$Y<W>n56ScFQyQX5mdC1>lAFYFTLd>LN4*Q8Gl$
:4+jEH mCEMmp#i/m6/V$jIkw4Q8VtSb6V!YHuq8/Ln9F>5e:ei6hY!JZSa/lLkq:b!+?Y\Q/*jhe>c4cJMY*4Z
?&:Wi/ Vp>Yc@A%L&BkVehIDl6NE*5q>H%cpCC>EpWY\WkW>Tl*y6ILjpm?d?1l?p9%$n\G=w@$N<i++=em6+VF
>E65!C CK%iyt%q%nHkEm$M4?wuZI:5&bXmbI#PS^<+MGFh*FupC>m#*G/C#RPE!6eJuh1V<d>Zjmb:w?d/@hdi
FMEi*t \48K%?!&4!q&MTSQeZtyma%4NNNSNVTT9VHy4qPbybHX6WK%#hyqwEuFS/e9E?$^YDjDlRNk+jj5Td1!
GT8tIA #Kq%X\D=jY:4$?6m1cMQ?yJwNN46?BK>>^Nnpq<wX6JZGG5\>=mjNn@lX&+5tG:XcKAtBe1y$bPD<<Zm
mVR8/c l<:yblVPE#6y<4\VC$ZuyHyuDcIFkeAcP96I6w<nNm@S6@68XNw16b5!e>/ypd48K8eh1*W?tWaSHd+Y
QEiCXe +uZkJDXy!A<WXltb4q#M1\wle*#*uQeQ?5dZhX#GS%h*Y6BipQn%^jm#>ti+ym9R#D4^a$MCqYl*lcic
DmH#PI L4tB1\9lMnG%n!jSe\*:Mn5\WR:*E@*8M#<cHcP&uE%u8C:j\$IF=m\!Z%?Skp8M!QJR@l=>&$<QT4/d
L$pT:y >MWCZS/Mp1<D9+W1q<k4n6Kt#nBBQVSiT/p^E^t<%d&SN&LtwHl=8X6Fp1d%^PtqAitSInq:8>:yY/&m
-AA4y8 000d6657d7c00110333 Page 140 of binaries1.zip
?cMcN8 VS>#eipp!i51D@9!Xc\ca6uJiR9Q#wLplM&b<VYKIum/<h*mG^wS&Ja4ph%tqSLV#Cq$$wmPknu*$LH4
<RV*dt ^\yuLl4pt#W9h6NW%FTFdFq#tX=<iB$yeZ:ymW5>/GF<$*Zi^<6C6!L=X/Y:A=kJ5TjwBC#l>j\D%meE
kKiw89 Dne^c15ch1mSP>nll=ySDu^lH>+^%PK$l9uqQuauQptqt/9@d8ZE#%bepGVdemKju\J+F^4EAhZZXlh>
p1AJIj @8WG1nH>8N%<1PTV?lNh\aJp+p<D\!a!Qb=mP$1D<pQG*Cwe&BD#\lX@w=ZkW=I4<MFP=YkZ<c%Mc/EF
$4h4L@ N^hNla+nXdTIjRtZpc%t!aCdjWHy@6/J8M1p88l1G<E6Ac4PF=wh5\hpCn&NVdajKaRp>#!+DAE*CjkW
GAtWLA <5cwn$YFnt\<>GMQ^peFb6#Jbn+IpAhm#Cq*H*TPt1+FD%RJpya\VpERJH#V>9t4uV&GW>4P=G/%<!My
jkhHDH bN*l=IFae<wPp+:a1QHM+%KMh/\N$FX>EwM:Fdb>Sk!<QpAKmA=jJVe8KB4D=$$P=w9eC&j8FhHQWw9<
/j=e\6 PHkqP/@ei#S?^!$u&/Fcn=54aD>?XKTLZGBjIV\4y>JY4c#/P+H55=APL5hc$e:<RD/kb<#Z\m=nSjV&
kHHWy/ \!=>I<jp#bD!t+1l^yFZ>JQ<dbWnWVFE&6YY6nVYqAYqcIjk<WS%p1GFc+TD*HaB5lPGdWW5>Jd::Hka
+BJk/T p=lb1d^&cXH4e\K94>&M=*t#jI:*iK6t&+p1wRulaq*\l&\+\ACGVYFatInlt$Lm6&AZ/Z\<Iyy?Ga+k
te6k>R %tY#!^#^\uKXZ+I#yKpPPLhT/KtTYBQG9+l>FA=iaBhhFIq=#p!%K$?%1&H:nL*DnX6*Y//I61%u8THR
w4@FLY EY=n9E9WAeA4hiT/VyhZ:N/ZBRIRAXi<DE51R\<h/>X!k\pLW<4MTa:C^bQnKbWeX*m#nDm#qi$XTkB1
eY*E<% @AP#WbQyPqFL$%!Rcbi9*F5BaeAh\h:&<anRnT:NntI8NcL>Y$iXYn9klw:C:8Smm1YF6!yu1:6j?QnF
pEyRES 8cQWtG1iZI+kkZFwWMXj+?bmK%*9TB6I%I?Yi*4I6Vh<J5+QN*L!*?=BS#yySwWdd1nl6nkDN*LYM#/I
:@1ANW Z?1BVmkJQVqtiN$V8XE:*8@JWdPE&TVtMHL/AB5NZi9ApDqN=#66F%Te4?:6b@IZylSWkLn=qHndP=Im
D8VkZb cGG&@bGqn@djWXE<w@I$VmKLX1D#YXjY91Pe1q5VuVJ!lLHXFhYXqBD?*8KSty+jd*R<c^a4YW=yt%uW
Bj*h1Z 9Kya4hjDl$T#4t6NK@SZS=VtI5m?qpJG/KdcB5u5yA4MM&ndRK5ut%$q%*45^%PG6@9Kq@l5c/tBi8kq
SF^:d+ ehLuM6YqW:Em8TTXywZSy8St5FW?Fi@FaMF:1TFQbQI!>+pG>=Za^qS8uR4nWVyTA^W>5FH\eHX<1T1G
1wKKl^ F\eQEMPWp8FbPq+6Kt5mMYV/<C:dWJ/&ehB/c#S\qwhn5VDa#L=>Y^T8BtL?5G/IQjFY4VCkuS+P#9Pt
%&CAGj DA?iIYQYeSAK<PDD8A!P/e5t&K@4mwYcnueMV:qldCNWQ&BQy6*qZBR<FK+DiEFWEiAGY*bE<bb$u*qb
^1>?>W $Z&hdYRC<YTXX:>mXCp^mbJj4N\W/B^nIKK%#%Cub/%K<4F:nNFpNH4h$5%wd^eSiK1jy9TRy>PYWQNY
*YcjW? e8EHIHkkXlQiN*!4q?N>9=bRad?+Kl4y<Nd+iPTcVbBiCTjYEpQJ^&I<p6k+hMp$\1%GTeLk>N/>+ql9
^1#YhE Y!HTWKYZBnGtTX!yB6TJt5<lee/R*1ZkWni+11eAGb=&uqiF6&N1?T+m%DCtVBXM9H!dT/m\^>a+uWaC
S:#CP: pKZtt8G@=4W8yIq&Gl<Jm^Aw*qhJm!@<!A1kRhApm6\5#kGGtFnE#wGmP:5@Tpw/!Ra#eN#JiY6nCA\d
GEmVYF j/I@TAdmGaC15@aNc/=>ICkjbDah<Fky1<+c@/IT96SS&DGc9&>j@hy+n\&D9mRCu*WW/l<?mNeV$cGJ
Zh*Jc@ !lQ%Ca/Mj&pdmNq%$qaGV^>W:&mNEXNH<=#TN8<u/GpAI=&u$<i$9*+a*>+iZ%ctn5Ny55kDuYW^JFEh
:<y%:4 pi5jc/PWqhJmypleB&kL!4Fc>4A%yXIAl>>8HpJ#@P:JCEbL$yw4\8Zn8Z&Jpj:iF>Lmy>#d>J:/Yi?:
PY8P8& hhWSiE5*FhZ%$l^P?u9%Y!iNiA:19?m5*eCqi9VK:juq4=<tan!1nTV#l!\W4+F\Ip<H8JCp\e>F:qAV
bm88iw Ca9XQTaM@j=a/YVmp4S&yB@cL:W#:V!/:lG!/bb?<ww*N:>+=GQ@qM=G:#AVhYHZky6$cDPcV&6kyY^=
Q89PBt tp=<lRDiZEZtNMbAD*#hXcY$!wQwBKW<jX$ml!R8T$\H%*8d\Wd^VY1ku/k\jd^!NGWCYKYn%/Xkk!?t
S95Ybd @$^6yTTRZpdT:4$FIWS&/C5Jd5wM@WFhMHBHE/$T@k&Bc^TH49DZdmy4c\QZ@Em>+1tEA=SJcLn6J$?:
$WmLaG Pn/T9:k/q18/RmCGBZ:T1dt18H^G9uytHHaFV$:%<MPX5d/4XJPje?i9XnuEdCTL*mw?u^nuuPSuy\X@
<&QBNT tXTMYV+HhNF?#Te/S\%h61dlYFq@J4wCuyRWQd4G*6\iGP\jTAVTdTb#w>qRlJAy$<6:HXDCq\dX:MlV
b59#mH nQtW66b8h\^cqRK:jIcnaM%=<bQ&%bK/qj6wN&*kHH4RM%WlNJ^$+/$c=#*>Zc\L6aIip:p6pSCJlEVK
j+H^p9 \#5/9qEE+T?Babu\npmKuN+VKyXi%Xw9?Ea/HmcV4>Ti5\:5?blwqWyZQNbn=>N6aVeqd6yd*Pmmpm6/
#GpJ<+ <I?4qZaQ$R4mu<n8Gc*SJuHD/LE4@C@9GL*IQQ/itjb%t8kdLFFkw?8i5WwBVbiH&T8CAd:l/JL+dbh9
^!>T9b 8biiQTGDnI:$dl%T$VmmHqVY$KyNQ!m^#9S>R&X5hJ8i%R*kXXiI5/G#hPDCKHZdc*$WSp?%=PSlDn=n
tn$Sb% d4?&VH%kXlmmQcHXpb!MM$9P8eq5l?RBIIaaVATY15n/k\tXikT9F:np?M>!Q?TYkc>qt9M:T1biN5/M
#XbtB\ KYy=LPmn/c&G9A*CP1@qBV$+aYiIDZV?R4Y$+BeV?C+9<%Xe=M$G#X4d:aNhLbbdG4j1mN4C*>#YT+$@
ac=dd% =Ny\5%LWNlZVaSR6kh&aEnD59pN/5@6BF&VKt#<H>E4P>WVm>JdKwL$&bb8+^CFTtWkZJy%henc%NYNa
B=YacM /wSAQ>ej<+@CKeSw<<1Jb?aJ=BmX<t!>!5%\!H5eZ%ddjbdjhh?$u!*DcRcYjkXR?NCT$ya!ePQY\^jZ
yq$>Bu y$1!dIhj#I@aXbkcX*CV%TXQZ4J8MKQ6h<Z:MJ6^lGL^Qc+%HdSe=/chXG=!6w%\jmdq9HKj#4D:bA\b
b91Se6 ml#Sm6MBH8#wnPu/%TiBXu\>>h$tDc9eYN:inIQWDHNWQdnluepeGVE?49LhD&!4P#?+4ly5Vic8>IB%
BRkGNa 9+B/8LVL$&R>@kS94B8q\9hIHc!A8RV4MYZN=HiTE/BX9API5tu@>eFVyNn@PYjt^>?ldPKR@+SLk+V?
liZSIT tW9#q*MKQ:p$1J>hG6V@tp5n@uiZS9#jZB4^Z:w$!J<n$$nwBb$YJQ#Q&h<=QEnEu:P@e&tR!A8\<N?$
n8=ceP Yj\C:P?iF@ZuLPI*dkqT+kI5=NiHZ5Rlj<:Cpd@PNmR8hkEY<86?Fwj?PR6D@ac>kK=k$F?:JiIZ$NXj
FR<^i? LM=j5ljR%X?m::>pL/C4*#wi+4>!QCSEJESkMHE+XEVS$e4D^<:4j=kJ<4c&Vn=P:t=YLmJKhnbi6#*?
\Lih1? <8I9hwL*lT$QKIINmWD?%jJA@6Dtu^5K+1n@:nbKTQ\amZA&GF#<4$&>RBQ@*jNA@tq&4H?ijBDXbpNC
L$Le1G juG!A9W4#\Q%R\V@q&jHMu+b?h?WHW5&C8YX$FTKl=51mt+GF$u4eERj!=B66#NK:#AQk5qCFJabATBB
wqbIWh KG5E9q\!8D9E<V%NGKG6=9M\Rlj:hqBZH5N\XWn8bD8I<>bdtuBuKc+@\mkCVbt/R^m^:T49FaH6ENe:
M\P:TF %kBiWu&CPBSbhH&<iD?n&=uE?%IWE=C5uK8Cd/T#@YNSDB8+n8Tqlm:Z/E6F4tJq\TEh4pL!ej6S$be^
GVKCyS =P#NRZLD+B:PP#VZ+9JI6lS1*t5/5jeF%chwm9yM:mkCRI#Yw*A4X%IyTQ%nZYu5nwh6D*aCQjhe%pw8
q!MjGu TpwyVlAqN4GHQybCmN&SMNCuyTicnuL&J4<PwQ?/@:I*!IbWC?K1qVE=PNkbH@!eQhFqm#<cXe\lVeZ5
HuuTXm T/X6JShBw$Wj?8HTNM&Bk%F>A>HHbAB?R!Da%LAjQQ^tP/!VwS&E<1beTM^WPl!FjBFkAn4:wNuDlIRT
/bIkpD \N*D1#i=XKicJ<Wyh1b:Y=ZV!E/t/:*+y1=cQ9#^=VJ8dpHNyI+>n>!5?%Bk/u1a$L1wjTY:$k$>5icQ
qE$#pb N#mtk64WdMMcLY:t1Hpq9?WIt:dlG\LGiX9PI?Mct6j#1m*6*=XV5pTu=R&TJ#+$W=@!%P&MnuS%B:#K
TY6Nnk JC1THVDNa6%#\%K9m+9+>hS1miSF:4lT^y>>qR4Tc+9S9EN?/@u?$%1mR1/>^W@6L*TY*Vm9dd&?I/IJ
Eam//q @jyMVDQSD6VcTXaQV=J:wDDmQy55bMna^:SdeBp:6P:a5B=dP>9VuhylA==8D9Q4l!Y#TCl9\\W?J!+q
XHi%w/ cek@5Y/bhibaT^bTGqY^!w?8%!h*lp=ZWA\@>BYd+F8#Fk$S#\hV?KRJP+61dYL+b&#+Xm<@PVbX*:Kd
8Q6eJQ wF8P6Xin?Tm:E?hXdM@e1yD4B+8MCwb9VJ9PQW&BF^^$M=^Gqp&dbtJKu@M!HDPWhiZC?BQ&RWZ=8/bh
X=@M+A NW=/tAcbEH*$JZ\=@45in^tL:C#5Ri41AwBDZwLJ#/VVW*AS*HBL=/6pEJa@=pdjYWJBHc=ykPtq8Ta*
ZB+$ua KE%@%TVEtD@eJi*G\$R*$/=H*<PFcJ\bI\6ypmipiZ8@%V!LdCLEdH6l<QIFkEY!d56%AD/H4D!=Z9C<
%jtLVk =Y*:$HI4W>=Ca+5SVcip11>NKuNEG!5^ijk1*>\Jk**b4h?9e?:*D^Kp=iRM+^anBW#%?W:ZS#Qw5I:S
4t>b=V Z+8b86mPk8S#In%c:uN&BaLGulH^H%Fp1>N&6C^@PeENQ#h/pE=TtMte1YyQAIWeG:=p@?\QJE6&9VR?
NnAYc/ Pnnn6Z>#?DG+Y?@%^>TJTGYl/yd\B#tJ6F:<tjbIF?*\jQQZbS6K5W6MHIqV+l9YXYJ8!%jcd\?c=VH%
TaKp*i lW%Xiw!8*49lEF$N>RHiaRwh:+*X*L/na6!88VX1T=/yGkB<iKX4CeQMt=q%@YqJWaS^EBuQJH<5n@$h
MNGC@i FbM/Gjp*9E1y8nTCGddnq\:$Aim:CcM&1QIJNq?K!GGYjKAG>4X@qy/t#@V+Nykbl/C%mhqnc+BkJuY=
uA%w*m CVEj%qIkJQGqI+RTycqbVVJFn$\EVi/yFdVGR6S9GnEJ1yd6S6GKjewyLJ8IlKZ/6<+$^ltXEZ%K5:h>
^+%\Z9 n!CKRaP$uGCaqqPt\ep$kYPt&wR4Jyecd%6bCD*AN!CqtkFGThEKb%cnb%59nd@XI%?/Kh!jD#eyjRXk
%6jeqD PHY4VZ=@PaR@eD##4uYhn%kCw%1cZjE6F*9D9bdkcAie/X&p:W&!<6hS*w4:hC<lV&5jET1mGE8?baLT
6b*9dt 6lKlkyIkR?a9pWc=@u!QeBWMyJ/%eNtbikqZw+445*W/ZC!Zl6nIlFNt1q^w*<I?q4:IpbmRhuq6@jTk
%taE*n #1mEwKyY>dYhDmihilK*cDPau+/@qNMkbk&ye*LIqIiGQ9PIi\SLWbdYMWXI#&&j=Cj5hw?hT8nFcc*B
-ARZC/ 0001bfe834c00110333 Page 141 of binaries1.zip
JKGa8d ?L>!9=@N5a9VQQ+^t!:PT*ItqNAyG=\FS&Km8W\Qw?+?#KAa+qB*mC$&=ECkAL1#k*eXWqiRJ5&FA&Kp
>TbnZ% huSP=:I9RdqY%RE5:EMWWR?ERTF\M!jG+uq*//lF9N:l*S888BmX5M@B5B/=?MXq9/TE4Ia\FEE^y$XA
NKh\C& TCFDRGEI&ZZuP$VCu1qQM^Nutb\cmNB?lQCSkl9=Z8V!l4l5N//I9ak4cqaA@Bl6MQ>taSI>/YnLj5>w
V=SQVZ tmE44YH:?B+kHjMR?H*wMI9mA&QDd8dH\8!uScI^QNNq=!GaX>4tybW:B8N/&tYuX+SL:S>1YSAjFybJ
Dp:B/H /i1ZB8pKQpmiP@/1wBJ:W&141KFt8B8GZm>pLE=Sn+JujwZ*qI5St%^%<@N:@$:mn@5bFVa9cS//9^Lc
ZSkcy< i9l/<YwPjKAI$pLQEaE*%H#VJP!>^I4n8F^Zl/Iw/\PyCP9D8PhT%%<Sl&y9CVR<W&$pF!ijj!M1DVVP
ym!aId n9dN?&\kKhDwZHScJR+Y$YeliQKl\T4!A&pw=KuP+=G*Zj$jI^RALL1$Ea<F\VRAu8C\F\//n1/BZFWm
ELWFJL d/1A?5TWYW\*>$4YwmjdZ:@6Y6A$jD8@<H$DS@y5QwpuPPS^piZ4pTyC?Zc9NpD==Nn1:4+BeAJay<bd
qc*KRn /+\15YHyZ\lubmhEa!LVmASMw$$ie/ShLju1IkL6!CM<h1FFS\jyJ9c:&dKjeXb!+eR49YYpL$uK\Qt@
%?di!m PY%/9?K/>6DRjD9JiTlS8>^&^#MnbFT9X6XB#maLpi1R+ZKL:jZJA!tQXKt<*c>kRc:?Q*nn&F=y+X/4
F=a!N= JH%ZBt^8FD8i!>h?b#S:TXM<J\=y4waVb<E^=RID1>dQwn@nKaW4lcmMPIXc>qIH=i1ultXElYe=^Kwa
<VM1yl FTC%i@Y6%XJ%q4wI$Q:/bC:Q\*K?A9#kBK<IinK5q6!EBTM4\tnF*MQV8jq\!4tt:1Zqh6Belb#qktkK
%Mc*em ^</^CJ@dkkG%IXjT6!X6%apMlaAmn6pI\a/pKI6hq*RDP&y$hcan$Z+?iSZSnqJ>:NLHk5qBHJ^mG\6m
G6Bb:J P^EV5u^cZkkc1CApH>XVY^R6V?+dT<@TcpQu#J*tX==8%ka=^eaQwLZ#E/GWiJDkji*?*kXeJ/d/ENTq
HdWqJ6 4wh?Rtb9th<F4F#PMcSl%8ZLmPd#kW\\GmS/%I&XP6H\RhcETunKI!5ncA>qnV9ZKi*!:jNR!Xw?RB\V
9H^w^k :Z=9K<qmI5p1P>E+q!KTY$*PQMeKj!6btBAXMHA8Rm/k4HBT6m%WlAMmiP<Vj8C#K>tm%XJnwilEF\%D
q1hGC? e4dHp!m:ayRCI<5=\%PBY:In!%qtA!wQ&e!%c=VTh>wi^L5w4RS!YWjlP$X?hLBM+JJXG<da=y8Q$TAh
/**Gdu %A9D%KuauBXE:Bn$%&n>\?VkXF4kFdB^#BZ5lML#JFqhp99kuneeWcqPJhlX#F9/@95M@Dl%SZWShYSL
&#<:!a @6%L=DDYI4uwGu>pjpe$FS&nE/Zb<Kw\hZlAN@a8y#a5>tNS6/Ma&j:^YCtCt/E=^:=4NFLMiaw@wuQd
pnKG<& aV?hBBW8=uJ*TGqKMalZe^+@ce:Kw$Pwe>5^VF*a<9X+RyL\yG^:CMQVlAP:4TqRAY*8YDP5MI1X9$9a
kQ6a+= !jI$SkqyLeS4*?:B!<*RciwiQ8^JY8&1!8ni#TPZD$WYypy#=DF$Let9:\N/n\Tu&KT<8V\IjVmQ\c=/
S:p@8d #N!<hHDPbLINX1qnIX<&iadP4CMHEYJi1HTK5Y5k?Jw%:dWmPVqcN$&mN4:nTF</YtD*KE1J\*h%Wpk6
AEK!Nh ta@atYqEcV*mqpyT/T%Buq8J/ei/tSRPGXWP&a/<G^!1=VeX1aMH4P?W#u$45R+IE?lAb@TSSMcGpKB#
V$CTZ^ MwZ:+&>*kY%=P^:&mq&L8u1qhlJT>*W=yX85iDGFn+LdBj\SPmlE\9CRn$N:^&Nw/!ajlYu^:wHwbQ:a
?dj/:9 WC5Ch6Vuqq*QCT%uG/ZIQZ4Zk/ye9aZk&H=NKZ6WNeLjuZ1H&86?My1$tJPFNww@NN+m4FV@pQ&cp948
Du=EBD EMMKu?G=kGq+AV^9SI<4Xab!FR8niw*kp$SZeFmpbwpyla5t$y=P>q$6mS*qS?@%ue<R1i@n\AhEG5y8
@CpQV\ !Qt^SwTI/dI4Da9I/N9K=Qj%C\8mbF<H8*T$ih=ZLt=48jZpjqSK#Zk16^%iB1tLb</c\Bn5E<!Qtlb&
IJuPAR 8Q!Bp#NW>SWiAZH%9hV1GF+TJZ9a?jF:^?C1///6KGZmIh=Dd1X%q/?tqBHWBY@whnycTF@SjBDT$^K<
1LHh:c pqML&8EYkK15&KHTDy%alH1M\nm\Qhynw*Q6\kF@$J4^>@pclZB>BTA+^=FFa$5j8R/XJySM86YMXew6
Fc<mDF XtS^M$:5SCiWH1@6<<kNEjP$bXqG6Py1ZBct$h+M!8AINTQ1R6^l:AEXmaXak$5=yQWNub\RFY%16NAR
ynKbn$ /TkFd6JmcISXpYI1:Ac*Zm1PaH%Sw:ItEt*nXB\:T@RyI9aAH15:NE^lc!@iSSEecQ@X41&LW*N^4:eR
8eV^uX 4Ga>1\&k=Tyei<:md8kpqHMT*/jIaJ/5e$9HBlZu@NTJS/uhWcC88lD1=@ic<^WL>\*HYk8qmEqh8Ewc
*:Ki6M :cT\^+pbtwc1u6Nk>S1%\cB6\+SS\=#1^CZRJJXSEmea>+q?ZaNHSJ!8qwy6liFPpltubkqu+q8#\A$8
=Ay9yF Gp#Ppb1:+S+*WRG*:w+JqN:m$M6B>!dQAPLTeleCi$9SM%d^MEp$/RFjFEab=\mc!IXMFPaWBhGR%W<I
XKEM@F PGJ1ttkhtpTVZq1QmZtN84JPlZPVNq*&@Hb=iP$K4*@:pYHe^D=M>\ma>DFS<?*X:mp&\BTd+c^!\#Hl
/1ubW4 #qN&dkD:#VK*VZt>/4ee8m@Nn+V8VSkjQCD1QYIHJ>*\JK@!%DZm/1H#uLCEJDq+GN^T<dL!$JH4NSIJ
VmlS5p #BZt=RdGu%/*1wujDH+NT+:e*inZLZAkee?e5mMT>n/ctYtt+FGw6hWTV4nmwDbtFuXFYkW>4!^5Y%I5
A=F4GW +uVXul8ej5w98B\llCK??mA:w@Qn1P4b>YaBbdaT%VWL9bPZwP=9lF!JcF?*CKXm%b+DT5Q9qd86WPJb
C>TRdD T5!dMHWlaQCbeCuJA?%6NTA&*?hTICFPEy14PWiTtL?ctLQQVpiWWNkC!ZMSy%MuAplciYNSjbSTmpi8
EDyBcT 8jG8^/J/1CZbQlNauc!*N+iEjaj+4iWp\nKEmmu@MTim:!1Tq!8>TBB=:KY\eRt8KmY??RhKDaHc$NVp
iIYW89 XpY15Jt6:$pWjBe<\/WGilV66\6d=qiR^:GWdAw:9:MW!^k1Gk/\4^BG%ihNc6p/TRL\1kB^iMIia!^E
YR^q9& jw@luaGP:&QG#+L$Pdm<:kZ$$Kti&y//Da6GYp?+A#@F6N:njc&mj6W!nt\eaEFl$yM?*Q!KTQMtD>:l
EXluq8 TEepiA9W:YhwMlY^nwh8YZZMn$ajXtW#*AJSnYVS1n$b<$e*cGwP9WbI+J1/w!uW=hA6@WPX:ey5!j=E
yd:?8j b<N8W:yF^@c^*^/ZyF*u!e9y@FwIwH$>*SPPaTHjZi&JLRRqbCwLFqBZMPnJ4hnZhPbyB8^PXDc>&lh^
4&i=By Mi+dGA:FLH<8^K8$a<=mi%8eM%1LFike=MpjdM*Pie66T1>49Z:8mMaNa8@#nieQB*\hC@\&Q>k*9u#Y
Zq=ZJ$ mm5:D<<6eA#X:IVWSnEl>m4l8SCthHd1N1%Q?WIhY@ed=w$*$d1u#?pIRX:P@nhIZyuy/HiJtXWVyiTS
IH*iD/ /nw*q&J:dkSb9@JQFGX@>bID5Yj6GuC>ehM\#KJD!GMCc15cItEit5Jq?Pc/:!*KbLE:5:e6PncMXqA9
=MVn>+ h$iwH!\&*Z#a=L6qSm5e:i5MGLa#</QDH%+DiyVihNVSC=P:^i%eXePK$VTTAYRAmu*L:QQw8/N%*XtQ
Vybc#w 8D<Shb?aJIa=Pd\&TSTm>HB+qpJpZ+BR#V$:ael<kLhF$y*TTpn?4MjpWT5$5lb1WLK6/*SD8B66!@Yl
l6$J$S DTQew6d=t5*lkXJTbqKG/J%&THMl8ycwH!JD?Kc@HSkDtQBbj**pS@QPl?IkwQNMGCBnMVKL+H@MRh<V
B1!ep* blKiZWCtFHm!85qXu4?@5/1t<G\bkFR*/#^V@9!q><kWkGecY8KC6y/>b:DHwbF++QK59@nJI!Q#5j1!
GmnP\+ Zn9nQppy8/>*PV:6PyL9+^AS6i9bIcW1$XD4lc?B=/$!*AGJH^C:WhF*!Zwe<\6#qR\BBqXPtZbyuYLd
BDI+t: *i9&IKEAXj+8F$6/TCD+%?aK/u?Q8jK@\%FB@ebS?W5\W5QJ%95@^G5S1L@qVpFC@lacSML@b15k@*=$
%P6j$M Bjq*M\Ry<deGmw9>:dZ+Q*bam!Q@/bcIK44:@um+H$@\Q<:ZIH?^5^wF?<<aQpnIV%uHpJD@yc^nTAnm
@X?Cbn Z+!ij+SA@!&\m9w=1I/CZhB\RTE8\Q+te^aKiRH&N<aHT9#Q&h<bLmnWBXna4+@WwCR8\Q:tiIwE=M>b
QZX*$X PQLZ@T\lhkEY>t9#RkJ/AXd5N!#5#%uad+/JTF^AX#D+4@NZTX^AX#Dwd>kL/A1K?5*#ZpBZ$N<aclIZ
V8m<*% $BXW:Dh69wC8^CS?!TIlF>CX&K>%laSeRFi@M:cREPl@Bd/A5yBma4>t+j<FF9ELy$5MImIlAlhDRlH@
G@qt8i QN&DE5H/89*%II?Qw=$ISlWnIt@4/8Vt>PNV$M4H*e6d^MnJ*<4L>1J&F@THP9:!V9$qtVST:AKupJCR
jIEQZC j<@/laL>1h<q@l@<4u>p1Q!Zc@+1/=eaE9u@u@H=Q*LG^@a@hebuqa6J?cJujIITLZ61!45R^EGcb*Yk
m@6VBi #wqJLBm>^<WFSl:B#StdDy?lGhF8MX1MbZHnbtCWQ5YyNEcQ&lK5E6S%T:1@\nKCI+#P\^/MAhua!W>Y
V&=p4? 9:t**86/?VLL!Q=nMJnMF+!F>dn&V+I:8##G$GEEbpXkLA%KX/44^Qp&q=w4t@XCN/RllFLNW&=K5Yqj
GRZ=q1 YH4S1M5&SmM!Vk5A%yu8S5+cCZ<VB=5pcRujtNPCQHA&jK@<:Hwa%C9#kiA8^18MLJl4pFF&TqFYDP/y
CP?pGd YDlL<YyQpmF9h8c!u8bNjh>klcua^wX^Y5d6qcwt\49peINb/ujSNPCwaHHWVlK%8JibN^$Geih?6IYX
q?V&S? ZCX+ekX>TwGyWiEAW\V=IFpSKScpG8>9mdDGdiB4iN>@t&FuKK/TXD<94?F%Jcp\nDKibNaGXa^BdBEP
qA>M!P *!WXu&+LpRW\kmTmYlFZunk+thyCpCd?h>q9+m9p/IjK8*Tc*XXnh:%M*=M!BRddCCM$tbwp:mRy#*\=
N:P1@+ $H&+qP4n!Dk^DjT+*AV1*+w>BP6II8d*M&#MVa:IhCWX9WQFc^C\Ia>*:^+TT!>M*d$5N1FMT*=@\V#V
V9%1P# 8@lh<\ncYiNNP>B1SwKY%abW@PPD!&EHNqh=XY?Qy$cMY#=iEJ?WaGymihFFu/WD>pP!?LV8Xm>+#::S
#Lu@^d +nVycyIXq6IaFTkQ*<F?yd8@NWZV99p&lb<jb8<L#!JWP1eZ5:WdppqnPVll%HbPhc^/?FleIh?J&pyY
nWI!$u e&iiMKhQFY<<WEX<WQk!Z%M/mIc>@i/G?SJBGkPnCjcB1Zw/k^B6chnV/BiYSTdKiX+BZ*RXXHZ:qMXa
QdQK$R Td\P4PcEEG\DNe!SSwCa#\DymA4lw5:9#!*J:\TG*%WLuw:Au&/&R1ySTDIH&we>qa\H:nGCqjKKubuQ
A:6!=8 aHFBcy!bN9/QXy/Jmji8SdM:>NBhHdd$HkDF6\et5P8d56?BcLGH#^ye9WJVd4hdACy86KjIT9STe*IB
G@ImP& \@LZZ:*M*bN!<QtR#bm9Ne#HB5^=L=ThD&\nZbKRJS1=tSQCV/@ytbqti%BL#VF5Tt%iK\\hB>DbDAb!
-Ai?8p 00061169cf700110333 Page 142 of binaries1.zip
MMd=IS /=h#lZ:N!i=q6FnLICNd?89GjRE:p^9A$G<$!dqi89a$cGFd6md1qL>6*E<S@59GjeSAQ\K+=pwAWKJa
e%6wtM %NJuC<^buelH?u^JNXaG<FNI/+^nYAq9iZpw^#NWK#M\$$MR8y/?TkwGakyZ/Qbm+W^a?M*R*BtNJDWB
:IJ*V1 CbQmi5QcII*:CW9#*pl/w5Tbjml\t#aE8PtKuPiKwRlK/m%&@QlPu:SZJR1$uZ1AcdDK6<DXM#G&1XP+
hAnLe> QN%N!<eb$E@&+DahwT**V8+^6D5<NWmXwR44*icDKQn*cC/\8uP66SQBMEh^^=WyJAYB4!CVQncT5Vpi
<5J48j nRuMe9dP@KA4qYS5WnAmadQbKS>%YMuNq<FQpV8c?BbJLtAF*kuqy>L<GDFJl5+#d+4y=%ul9h^ejiEm
\?*ZCd #\Sm4/tIAXPut/M>?Z*RCm>H^hu=HyG#T8HKNiq=B8E=%$uP>Vm/a^@u<FWSW:Sku1neVWLB+T8X8B5A
yKSpk^ jMPcCBS6IjM=ZaS>jtLNKi6qy?$H^66C$!^uk8:^l\#T&G!dpiDTEB/4HV/Z4>uDE4%Bp&%N&X:4B6#X
twC=YX %&?5HakI4hE/*4CiF$5R8!4GNu8t9yZqQ!mB!@VYQ>ClAB6BcG&I/Q#$S$q##Zn=n=8PC>>jMbpL=9W!
:te^Ih $&nta:Re^k5!i@ukt86B/>kJq%PeF>Vw\?LXc$%bV6tqR4d1HIy6uF=J&&>m^j8jStPX?JpaD*N^K8<%
56AH<P XtH*\t54XRBp&l\4Z>Sj^P%nJKNAcdc>N*H5#mEwhSGt*Nk&Jm9JGA4dd5nKqA+w1JdlSt1ZkB#8E+HZ
?Ilatj eE^@XRbdjk6#cb*Am@K!*u4qEMHa*Eq156$TXdun#MVJ/>EpA?mS>H+SHawB:q1IL*Cl#6Sh?&WiInyy
LB$:hZ RFkk/8bqV%GQ>QjDYe?!<!1n?dA+VmP84CK%%AJ!Zc5%<i6jty$ya>a^XLlL&<Q:B/qiXYljk%q=4yM9
J>Hl45 $\9MAL#q%&&TXLWnM4+**kSC\wZ9cFym+aW1*:XY<<PbRyAiSi6=q4nY=pH&P%h\a#pV#CQ=Xe6*&+QQ
B:1p1b ^Y=9T>9bnwe<1u<jS9<1t>/hPne?h&K^/&**t!=M>e*Ak?WHCB89Zt64B4P1!159VGP>4jp:5ThQ?BR@
Y*^dQ# %nuim4+Ej!XDLncqGcuu@%K*@/EShq?M+HBcauL\yjJ^mSV6hN6%*RYZ6!/lH4Qnibuq:kybJ1Q<tS!$
\AjE8m 4!NLH$t9b<68:<^A\/1?Qh9YNC6y=Mdi!=p1p8IJ1cc86ki^b$pYA:=N9c?G8iyLhAya8w>kykC6QJuS
=c>bHl MuKVVI1?=N9ZD#e^ZiYju=Vh>dnHH/d*ZjPL6e*Pl<h#aKB@8D6VG9D+^NjVkP&6H!=b@tu+^/=\k@m<
5uZL&= 6656dX9ZhF+?a5>4qm&5HW?8te@kJj9WpF$\G%Ja4/@VJ+^+$!ApH?TdEWXqje&w<VH:>jpld\jjJ>SV
mD9J/5 Tl8$=XC$p$+N>lMJXFB<PN^b=F+RRq&W6dc8wuSckPH&tK:Bjeda$lT9t4qN?\PYQamql4@cDpN*Lm4d
pj1a5Q $8&4CMWVuY:Kbi4NyYKRG91=ame$qycQYPYlC&8:6ZSHTjjW$FG$<$hkF%\wbPFBHpiHW*DZMm/N\I8d
BQhK*C kyELA?W8!e+T+5wM#8k5N?RnP86Rc=dVqCIMYe+KZ5^c*lRbpiVW%Bdh^ZaPI>MXF#Zn4wS$5>cGH9S&
Wq:R+d G=PXqa@qu&B*<*ZbHMiFIt@6bD+NG\WW^4<FmJB<wB::+D>cRc81Xdnec#:B!+c&CSWwkI\SCXFG=AB6
E!\5^? #$hnh*jCYLHWB+:C5bYE^b>C\!p*=6+ZXXJWn?h5j^!^Q>jbW5dVR6dEHNV$\=j/yh?VpG$RG$6GLN>X
j9^Q*Q qq\6c>b%1!MZ?K49quG?N84Sd%#Id/kwWq/@k%wDHh$Z#XWIFjJW%N^E5&$t*I9L<>Cy5RlL!N+t$t=T
@tSXwS Ad:Shj8518>XE:tV?NGR56&!W9>ySd*Kn6>!nip&CR&Dc<+IPT1mD^+lWtuwMC+qRtSBN4yW\Ryda/9h
JtbRbS :4%Z?4*Ea@kL%^9/!I#ZIkG*%EkAI9ctw!/&<X+Gmt/SNVN5!p!ZqGq*c6KjmpZ!mKW^J4X6dk>P$$l?
q#4:TP 6V@=yHKJhmJVni>M8VjL4\i9j!>=Xm\+LquB/FBFwDBREYA199t>ut%lWbqcJY=*p>9&YiJ8YZk#qZD4
Y#Rtlp nJAQktn>R=?=*/neeqXnM!RiZ/u:a^j<1$dm%&Db4&PV/$WY4Vlwc<j1KjCiE/i?:wmdNqDjiLAAn*N#
X\i\!n K8RAZ?EE&Ej>aJ^Ym@w!AS:+PYjHe=5?RLA5$CcbK%mLaPAG$EQ@Bcp4EWEYDD*K4hdaAeF$DaMA#1>=
YTIMA4 aZl<8SyAjm5TklVkRAW^*?mDFGBZ%A6a#H+*JLI:Pjj^MPb^4H+ct\Nbjk<b/TGaWBaw4K<A<?465Fet
mc\WMB W$kJ5+D*GD>LIlbuY>#Q\&ddCXC8tYI*15Nedh<Tc4:l>PaNViFTCEAE:leXC9PuSJdqa%dJ#uuHTE4X
W4RypA cb@m4Wq&u#IwF5N:>NmAJMwAE^S*j<VtH?VdqS@Cu>Ei9cHV\hX5Im*&PAJ#T6nCAGCHkN+QAu%/mXXV
YW1Kyj n&u^VA?*MiJRh^+mQh/Xa8\cE49JeY9aq>8H$wqVm&5$Z5e&uJSuYHX6YmFM$t>$6nCTt=8dX66!S!uW
DAZPG+ RHc9XBq9!a&aTDp=RntXt*H\t:BKka!NntKS4yChSWKay4dZI?X<Zb4W!<1+d?4E?lPi!^dJqb4iLkC/
6e9#1R ^nPjn1wi&dypuuL*@Ecmh=hyCqFWqi<QZ%+>#AkaRlZ!TqHF+Tkh9T@HBcH6GM<mTwH=tN^yQcyy\>4>
wTWNRK &p<VSyjEImMChaY$/u%wi5$mXa#eHRmku\l5Bkn!DAA:K=B1eYBWyD^B@k5>BmKCM1J!?INhWu*!@bip
qWZtGA TZwiayDaK?u<8b$i:wlq4*9n6>n$$AI\#Y:1eNpWA?FnE%K>//RyhcT:XtReV#Z1QGdS1:N/6=VJmC!n
NdYhFF TeXl+$>^YdN/<di>W$HHD/YYqmk4l8>+X%*XG&BKia4Xi@$$:\t=EmV\+Lq$*cp+:+Q4M/M8p/d\*uJE
qWc%b$ !9TAHT%\^X6tnRmS6q>hai6EtDtFjW5+kjy+$lm!j9dJVnK$!/NPJ@ALmbWtmTMmS8W#yYH>KbPYlyGY
$lbYp: =\M6aPC=Ft:bM?C5qG^Y$ScS#Nh\^G^b/\/8jM5Cu9*WX/P6amt?4+4YeDt9eGKF\ymkV?k$FwF+Zu^i
MQ^hNN =SbLd6P>WpK>$1*eDKcX?=cyKtFy:M#4JJd&=JIyd#XVE6@%/FPG4#h%c<8uQ\J1p&wwj^AW=CeuLBDm
=$@#F/ 84hL4AZm%9?n64eN%><$Vm\kbE+5tPc$e!nT/+6@KyR/?RYcK/84kP=Ti$Sw+AV%yycHkX<Eu*N4*nDA
beQwtM /HuNtKiJ5\u1ITBDi+bV5tpe=\>mEWb=uAbykXp#aTR#WcReBcRiZq:B:V%d8:&R@Pt^6mkdVbIIFtiQ
+VPHnu R*I:!AV9EQZ8=B*XlXhp>+cIJAY1L9Hk9w+qkY?D4eXy>K8<Pml>Bbw?M6hW!Ap6V*B&Np<QJk/wDqNc
/uK&GM d1+BMw9Y#8at6ZHWTtXX6i9EuQ/pFL/mw:p+muC*P\:nK%ye+lL/i/c9unp:%FeTA:YZ9Kw%%Le^B+pc
+4u^DF %Nce*9h<m4$mHK55*>*65T\kHp+RqZT+BV^$LFM8/QeKFjK!hLq*JtJIiN?KpV5EIBk?B#e4nS&>bT8P
ncpTD# Ddp5eD<$#EED5PbGPc!=\&jW9*@Yyh<tl#XS&y@qy6au\9wJ^b9D*b=F/pWD5pG*<nl%*%thEP#&HNWG
/dLW*> ^n4!ne<TTdt4&4dpPKIhY+i11MSFcbQlwwI:&yk#W>iqPX\a?nND^^?1d^ubF4RQK!$L*dR=9X\FtC$L
<GJncp =!^d!J#&ukWq9bRpKC*qTaX4DF!LXSYkZSVVJFJ!n4e+cdYyG4jW!FWa>q1:8iBq+#YT=%m1VJ=CeuKa
D&X*lS ^qQcYP!!:d>b>XXZeCRq?iTZHkITk94@mwiAlEn<y+L$eMlQRjy@=tL=5\I>@\nSIGGwZ<VqpYI@^jZ?
q$E\Ny aX4<l!nZ4%M@IeZE@y#>VjWQyBn$A9hF@ic?5A8\$F>H=u/8h9I#m@l%&mnp#>XPj5FCj>Nt=AZa*$RV
lb=$!> j/=&<nMLl@&GSj$=C=Q+Vb5qL5CK@=1FZpBZMMS9&A9wCkd:DZ5BZeHEj5NiRFjR*@RX>AK/k9/84!/k
+:tYQ8 K?n9?8wC8wL?41<8wC9w:@41A4wT?%%jZWBZ9\*y\!D@FjkC!9yN6SMpDQyjaC?kLMT9c>IkaShRF9#Z
4H6^aN NaiR5I5wC@1d?!I9M88kj5&K@/86<A@!j^Rw?jGLj!%R<5?nM*?%FXA@&\4@qkH#=&9?$/1A@QPc@!!k
^dd*4S >iPcCMR94mu^m<J8MHHE@<ECJe*D=lIl4LE%lHC=WQ%I<9+8SmZLElpAmJnc*+=QD5+c1>^qDJq#EGLT
iL<4AB CAWw8mkRTSR48BA?wk?@dFGS5RhRdJQD\MByIF$CaV^/^nbF1/Yu\/p&\F\RwE556e$cVp%8t!il6H%d
H^m*Y! >lpt*JwM\ia8#nnQVl*:ZKWj^6wSdl!#&Y\J##PTN&t%!\ILB%EAGSRKm5FtaDAA>XV?/5&HC@8>N\@q
KNHQmb mj$p\E!kb<*GPXQD1!^^9LKY+^kjCe<i+JYIG#hu^V@hpiyeGl1b@58lu:9:j!V/:th1Qy+TlbGJkTti
p4kwDD NSF5aXJ#muECnjpCcy$b8aYdj/6Tp5+CLKh&tSb$^SIF5\&@Bwen?lX^VTLp!Y\VHi?J$JMSFE45yA4S
VbL:Qt !&&Q!kY?&nAKJY/DV+Z=Rn#+\+RbZeC!^ec+D?^Y1bHM/NE:Kl>BE=5+SkCl%NLEIGFIM$M+qQE^:#Xc
WVA$1S Etj&?KVhSDDqMh*e\XP9pN1\CH!=YjCL1m<Ye#Y$HicM6ha=pbFIEA#G&9li4lAcc/W^#^>GtDkyTTXm
kPF#iI Zd+$WmiHRaLkk9M1w^AC#GA81bAi:hT\uDXL1ecbHHMEj1$dC$JR$aRF1bZu5pAYyBEJq^u%yRDLWMH9
G^jqni K%T@X@c<G55b&5uR>/F<il*wXc^uN!eK?6GYtY1H/#IJYhW:Jka4i>c!5<<nZNRS*hY4kFyjuujQp$?L
lZ1\#M *\*q&YR5t^tCY4iBMFh!IXQK88!Q^mML>??HMcVi=*tPnCeCW:^/qGVV>+qqJ:TFMKTZ<RWX/Al<A<eX
Yna4&P iKJ/8u$>?Q$6N::Xyw?4ZZG^#e<P%8bEAty+AKnLN*u/X1VK?KSTl\!:T#Z=9MJ%hQ*NW^XQTNdQu/eK
Q<LJF% pwFqKbZy#TTu!B?yQGi9^L??atSlW&1V6HNa4wM9b@+F*Rt::#^C!>I:MhI+<?d/>mSn=<ceiN4i>Vhw
a%E^n/ 5<M&!Wt*wjBJtIWFJD+LmF=@V<qtW8@C:nd@$uRqP/<KX%qSJVkaJQj?i4!bG!N+yNZ8%4bEt?G#RTp4
w=S5Pl na4d#mJN88\u4>=YDS*M#H#tRQ6$ja$pC>I@t\5u5$li<E/PaQ=/Y@#G#X19Sy8188j5dW?Fn:B:e#9D
Ehc1qS XX1eY>J?di<?ZKMW9&q^L1w>d?dFunL@$GdS#an6#u$=*d:#&5Dph@&LN#kcF9Q&%euSVMJ?tlT/Z+qN
9Rw%:y SF$pBMhhy4T6Hi:G59WK4^\E$Ha1?8GNqL+kV9X+PDD54L&XAAt$ycRN>DEjN/RTZypmjP8$biKthk=D
4cIuN9 YS8c\YuWRTXC5p*V8hwq8^L8B5tKS#=bq<@Idkp#E@ESim\@6kt%nZm@$C&PZDan#QW5ajy/^Vb&e8aN
aST+5I ZYBS#ii!<CHGNE5?DbicXl:DdJc8qJZA589HatF6*wwb:p+n*/w9>=b8yY*CVR>d>1=$hG@S4$SVJpW!
-AaQ+F 000c8e9976e00110333 Page 143 of binaries1.zip
YNA>Id bjhS4/jV#p4%9Y>6YjPnDQJ9SE@cLlQjqy=:BC6*&\81!*d+@qLS&eGll!TZTRtwPtlTjwM6eLLWEqe<
<?j#Tp kK6A&DbRJCa#YGR#FTwq5IIBcju#mtZ8\AFtFE9>c/dJXlMAMXwGjXJ#qZEw#uRn>dl+>VXLmEBj@EA/
=$%d:T 1iJeaPJKpwBSNC$FW1<&<X*\K>&W&&QAV=d#?tZ6&51pYwNHb!Gc<8Z/QLyaZm<KjXK4wke1%cGCiJdb
ild5S= Bk>:51QyQ^TE^qE9KcYdPyq9SmS1?/X6IqSQ4K:YFLj@RZq5a8tVHIe%^jny8T!n?:!eFG^jpn!p!A\9
K=*mGB @jw8:*MKB@k/u#M%th4\wK:aJK\c:t!?NSZ!YDQ>yI#Qu8A?I<bep?&>ytQ6:n^euSNFtHM#a<N+>:Hn
=ZcJPk cmt95W*SL9h%Li:+lt*Yyn!>6La!y!Z*!bBGAN&Yq9y!jJH/R<Eedqib8w<yqLw$XTn:nAJ\@T+qFjb&
JmlBD= hSYNCYey%@uD*AE:y+d>Qu5RNRPFF#BKQpDTIH9X?ClTT9kiFNIcAR<Ji&Kl<@^/#jSV==&YZcPeAa<4
qp:d%h GYS#^6ky8$qV@DLdN^/4AT/&8<GyqeD5:18=tD^Tidi/cG^XJj/T%W*VN%#plp5tyc8iSi!QIR<eG&^p
\#>aF= 8y1wi$:!Dyci5lD$QYP+G%/*VQ$+p$/y88SpZl4H<T$nM<<tycGJ6j5N8ePnXS<u/\jKcI/p#P++!&bc
iL5VPC Nlu>&Qb*Q5ZBeGh</XhjV@CXF1=l9lPnX^+/ZWt%DH<%5Qpp59Z$KhhXL@$nbl&jy&EME%&>MK%d*K!k
!VwKI? 1=jjHHhZdqQcDFRFd\/Q*PuIbZ?j<e%*&?=YbPP*Q?SaLiqHcXZMJ>:k%cuWj6CthRmljn!!HCDRMFat
%DPkb@ G?Z4^VPM@kR?ZLGLeb<pMj?p?e=n/Dk\tW^6kHG$n54tC?4l1H14=i4PbZlcVH:u<#J:YMdLMuwnN+9Q
e/TZ58 Dn$5Dw>j#n\/$qC1LP*ih=cPu!!:96Ce5<EcqAXMIw+>5B%*ww=j=i*9w*&/uXJXMNd%^M%9G\*<5pQ4
&5Nacq jj*44SyJq5+H<#FIRhcA&>>bpCi9YX>PT\Kw>tN5HRW=q8!B5?:P>MW4e=i4Q<4$meJkNuc*a!dDX@15
bK%EM^ Sw@i5/&FZj*a9#D9t!yn=Qn^!Np5@M*D!9eMG/CtR5WBuYjp:=8MTGD:w:=FblTte@e:Q6:dHQSQ=8IX
anp!SK tuZ^h1YJyqX4RiBl9Rm#$uDPSJDyHM9E48#YmnLQ/^EwR9=C=MPtIZP^X4a*k!Hp=c@\elPi<dQu5lSt
+a>nYk Q/!+ym>l=M^*8V6/68^Gt1V\<HLhjR&d#D/6!jJ9tjS9@CXH:\$4Ab<<Huph5dIZWdXJ<aYy6Sh*!<A4
QaLlRl aqjhe4@m@A\>MeTI>nDLwNKPBeFjp*QlutL<mu*6uHndLjV9p5j#tke=c$i#4t6JR%+THbI!SW%%9<ua
$a%=QG q=GdP!Zb4u5C<R:lVeQi*cjSc#bZiAXAuFS<uJkwiEVNX>J>&B:X98L>aqhGdBPXZM4%#5MPE9R$55^Q
XA8+Ze #%4R\K*Tc?9M\RkZq<Z>1wwyc!%I5I/JFjDMjwyHy8:VZjE4K+hPYMDdw4*:dnYN@jwtmqe5k#Jk$Kq:
tZTQEF qFVhESyN<6A1!<EXNi:m=uK*4RZF^6biEw6%l98AI*Y<:kQqPbtEhDS=?djl?NZKYmQ*$aRa/DQi4A/=
P1eWt5 dXq:/SFSj$eCME#\JC1/4dbj9$mNWc8RYZQ>^QVA$Da$J/+:=^:lkahT4IPK>G9BZVHSi@BX%84IDCe!
liKatG npiB8IhhtN&w&tVF/qVT*XCNiwqC#ccInJGqZ6p<Ey<6N54an>uc+?HF9cMm%R%=B?ZK$@EmAuIE/Z4l
JBpFBp >&SEA<<$iPAn+StJaTRlmeapAW/4tXa4hRBqXkqR\G=Hy$*iIYWpd1N*MJ?4I#CWLZk$R*#DmXy8C5Cb
9N:Ai# %WZW:8P\CAwew8+#nTBtS68jV+yBVj1l!X&J&CS<8yXKEN5:Pq#8HPY5PQW!IB<:1bL@dS&h4SSeJiV9
CM*HMZ KaaN^b\BlQX*<4LQ<!NwTVNucZ\K8^IVX^Iy16VAwmCT/8Tp<j%DwIY+$^JqZHWE+Z1y&uuX\ST^M\9^
wE8!*1 <D\J8VD>K9acNj!X!@utV4a9Y4MQe*=Z/h:?IQRt4?dA:n6!J:^pE4QLH%=enlVbhXQBqZ=tPZnF1l1b
DMd@!< T#MwQS:BRMRSDqqQw9^iRq1a#*Y9qIRpZ#&Gk&klX5:6S4@t&a?XdmZiM&j6hm!CI#FdkMRNYFD=IWHy
B8#eLh \L$&jJJ9d*<Ld/L<E=XTZumuXwHHHycB*ip^4X8#VPJSiMWLluAi6cn8p1kE:yXT6Fj&T>9JeB=yt&K&
#F:%Rm 8?9ud&Ldp8M8C*VuqKlN!:wM*5SB899<*lb6EWNtmCQmRGZue$pn*DGGI#V1y6lpXCL4dEnyNTC#KWqA
cJ5&Ee JFyyndK#!tcCA9RHe%GdPyAbd6Mw5Z4QRn$kACSBpRQt\+\?Gd9L66%EQ<qE1hmtD9BpeuiuJX@qEhPm
E8kT9t %=Y$&6GiFT#kFYuPXPEyn^>BCyEF/:yT/!bAB</1PlPZD>/!K^P!Vq/S6j9cI?DLt?D#aX#V!mu%FR<D
DHZF:G KQpYcQV5k:&9eNJL+1wI$JAAlm%HjMITJZI5TYJj%*8JWMhq1V!+iW^d:eQZbtjb=^T=bn^/=MqK4WA8
EeL=#5 !ewAW?eqa+Hb?F/TX4L\$$JtndLpw%Z@#9Lt?t%FIY+@!=mML+BuhPYW>t85yl>YI?5+*MNe^TLt1ha:
$M%Vb* +5l5bKLD%ZMGQ+Y8\c#J#1DWP8M1GN:1?ppSVc!DkNK5P6twXq+ehSFGG1@ZuYJ\nHQdXpn=tp=6BDke
c6wQA9 RLqHS9IB6S8QG#Y?1*#!<hAQFdk=K?k+1nJ:e1RM1A<eFhqR4G@GqZ?Wy6aR%il$QVJSLZ*DMNTb!A8D
@5/BH1 //XeG14mWyXXQZEH>C!m\P%tGq4C+TFEaFPpZtnW$5LlbnR1j4Ek?VaH#mh$TyenYWF!#JuL5W8Th=+n
YaBqEM AT\^Subec*wZQu+aSZ&<9?lPymecj@T<>^JHE41w>JM!\cbI=/@KGTD@NV9@@$iT=mD@Ni@@leP#CQGj
Gm<^Nl \4MI=EZD5\nE4<K!Q%eS?Mei<n@NdaQ<8a4A#?^9e8wkj/+m<DPLSQ&GSX!ASa4@tpXikQ%NiQVuKkI@
hS6ID# 5+njlN=?4mL\M\6H@Pc?Eu@P\5S@#j=eSiBuFm4^G%d5Am#$%&F*^AX$>h9wGiIC\pKK\*@NZpSapF>H
I=eE@m wlD@X8:&H?V@bJQ1Q!NIj+u<mQ?eqAZ=H<5L@HPV1wRE/9@GVc4<D=W==k>!Nu*kn?y6&Q6#^5yaa5PI
Wc8<HA >eJnHVBkSq?dyPce^*t#D:WjYSZu:QNZpwG?%MkQBjIl>n?%$q$yh/yd>d/>un%GaRyd#9c%5c4Pih1+
a5F=Xe <&kpQL5!yYybJI$WE!#eVW<WNLP$XM/%RVKe9/Zi<aCabN8!RVktiJWV/D=+EAwS*Q=iwmDE:JERIWDd
/Zlb55 PXIVmB%<WS6ddV+5P4\mDiahMZPdq*:9dMyb::\#QFNpJSj<ByHH>u1t8WInA^:9X1i=wV\!qQFBS5R&
Dyw1\c enatKQW^Y**epm+nwCb^i@hbemRGKmXM6@\=TCN#l%k+KH1Cc9kq+ZpZ5AVn%cMa/*!X6FbupwbGkK^i
JZn<6@ E\Bdb4XtqNJ8Hu!4ZmYItXG9jGa^KiRFR:MkenP\<*B>Q5#HS5Z!hDCIM/>H6cHG$b1^Sej5>Yw:XTyD
CKbdYC i8YPNTyJ\S8LHkG!6:buld@M%Gjmtw1XMc/N#nYV1V65K<MmT!9Rd*qjh6W#AWeF\=?w%te+P$k&l5RI
ym%q>d qn:N\CBNb*$#/8b*8F>+lFHS1+AyDP95QPeuq$\Z?=E=tApV@ii<n5<a>wdpyKI4Hn8FJ=Au&b4PeD/+
?eEKLF a<=IL?Fn^1<<FjL?#GN>Bmn@!Fb<u4&T@t=D5/Q>#lL!?ct46XjF<%9\YS5d:^YShyaW\QRnY/=J1<hw
Iyp4%h TZ5@*<ME>M6$C!u5ViS>LKW:diu!?%9CZ=A6VSZ5WT8TKuJVnyWm<YBXy+<XwmWqZ8$>^LD^!N+/c6hI
+#^XDm 5GQed8YpTbjqY@Y&T6@8ndhQucPS&NIK9Qh=w@wGYNjVJe!MJcH*<+:>4G5M<!CSG+SKA4WRt?i65\jn
+h=^MK +HE\y^tHai81@qH5CE9MM\>5th*q?1DHIMbGSeWHM\BcK1a4GE1b^!MVn:ZLlMPkPp:hAF1Z^*QPq=%6
$G#yd* EZF9u^C5uFcJ&1*/M+:hiP%*>$5L%6NCqYZc?>YM$Q6hQE\^9T6%?1#WF>i>w4h>/RhdI!%T?/yhLXTC
c*uY81 T1$:qM*:udMiZyImDaHMMQ<%X8mQMVT^qG@n9&Xp>qF!e&<$PIQ!?+&8W\p!QAtaHn4&aciB?*4=cnnM
ii4/hq F#DCGY=PQuLubZ*5/CNdY19>eDKCEN\jqCc9JHyV*#??yRP$cJENL9^+8bn9P6Xp1IIWyVcF+m%W4Ldi
?qCnlI l:C1k?%Pea49$\VtAXYQV<ylpp<8q:$J6y>i4MT#9nPBZd^ijp:P:>GbNwI:hXcN\+wWk6@4EHcE^Rw6
MCGi^h b?bmD:EiWKqK&#&C8hnibBlWkmLyYuDkTj/KhWJ<8i:A=Rm#1>wKm*CXn%y>BWiZ4@VD#ad5Ey+QRQi\
lw&!@\ *VEJYA>\j&lpuSd5JEY*aXb+HjhbQTqj!jb5BKA!GyHECBEGqdMVyITACYF%petQ&^5k^>D<G6qW^^/:
e*9RHd Fnq:b\QJjItJd@LNyMdFaJ>1bIuBhC<Gi%9:@hwn\Z\G#1:F%WiiK<F:n6A1nqJu??N&+Ac>mPd6@y8F
<9l4pi Z%?u:6j+nn++bN*A:$9ah%p8X1!<tj<XiHPE\HeMPQiyeKH^eWePy@4<wF>Bq#X9\YthdI4+yiE#P!4c
n4RJ=J apl4q!u4JWJba4tCw\jR<VI#mqaaX?4I$MpBBjq#9pTA@pSI8Cd>^BIjmI#&&kV\1W\&*V$:*4V=dCM!
#p:ZFY >I&Z?&Hqyj!qcu8GqIeXh>kYhmL\XuhHulq:udyhK+qWTbL@BnhRC?WW/EI?qC?STXW?K>FaH:h*p8R%
KGW<lj HqIAC9p*it1ZXPmli*%RLV^*+wXYuFJ$*dP:4X?Yl^bZn&q*EYQtnXb$<!L:ttidM8:18p#V?E#iNt@t
QNdAd8 ?:+t$Bq1$q6!XJ64cBlhc=D9ty=h=C&K$bW$mW4##L%<mqikt^^b$5Aqu1<?YdV^uA=Atcd/mQ5caqVQ
RC/*</ *RjcZm9Lci#%&P=hq8MkkEW\6ct!yaLwpL6p$R!?y9m+@\p>D%iY5a\RAZi8@wQ?1S6DYVtZ4Yh8&d>G
%w?\j< X\ANeS?katbVe!!Qb6c8JcXNc\=j\*@<qh#bI5#yb6L*V:1pn?*&$+#$M?\Ju1ENq+!I#P:TEiV\qwc/
V/:CIY tyYtaQDdJJu=b&K#Nh9E^e:thY^wb<GEJ>mW:QI$9V8^DAGAlE@m4DJN1^95ta6JS!P#=S5=uq+M86n>
**pEAS a$:%EQZYXD#9*ldck^Dj6mqdjqqEm&S=*!h%h&<FJXTFH>pLwVtY>d4E&mR8buqyD=bntquJHZ9iy4#1
eGm+<1 S1lLpdmGQ*%>a:YV6wXAVCMRw1Ke*XuH>D\%4Sl<\<Q^65LVjpV6INQnP*Q8NtCtVH6?:$:P/ul6yjL1
N8:meN PuYGS?N:9FaLKhjhS@Y&M:+&^ju9FD1$?1mZydw<FllNmEBWq6jyC8SZ9kDRNXqLE!9!Kn/eiHXH^LMC
>Lnwu: wFdahe6%e1JL6R<X!d4lq6!Vn6>RRG:\NN/#w4uc?bctM:aEtTiGtlYL:4??/Zt>h9GhWKdD9AbD*nSk
!P\ktC YuL98d5:c@RAK<GmS=*IjXaL+N8Z4uXT!GB>&@4d645R6@dhS=kC9V58/YjPCAFl^^8!$p:+LSX/S\?m
-A8i@* 000df809d9900110333 Page 144 of binaries1.zip
/G%CZZ YCmt46^/eup\@5t>G&a$#:P>R?5&+5j:He%cK</=m$$ZDX99QDY%:yt!VqV+%4uWB*:mimp4eiC&S%&m
b8VJ%p T/+RLA#aqG/aeRid$&e!Fp*A!#1HX*AijYw!RLT#6ha&Kul>&pa<#^GF\h*GLpF:HW#pXLhLCB&D%*h1
al+Gyt 6AXX?5+&L>MW:Al\*HjQ&j>GJZV6WEIA/BP1ptqt>pc/uydFl$!G<8kieaY+RFQD*6W5!nwT::MJ6eGB
*8+!E@ /91S@e>n=V4ejYF6LFwVc/%+4\L9/MjFdjAYl:5qZ@IZYaw8n@<I%:/dhe4u8jX/u%m/=4#:t9%D\bM@
#umGX+ lpKR:IKXL%:G#R$MYqT%5H*iNT8k?I/P8DWt>n%TNVu>w#Tm@>DBj8^pbCZ%8*$#BR@JpPcBc5TCa?X+
%nIV46 Ydl=u/lj5$1=VFjqH+4yy%X?nnH>5cM+6^&F4IHt@nly<Z!*lAN+Q+qy4!nSTDtqw/LtTH!GhLZ/MKlR
@hw<MA 585PWG+^kW1Fkl84ThLeE>#<HXR?m:cPK^=Y+/H&4hR?mM>*&\LH:p8YPX+m*bJ<4dG54Lu$RhZe4$S!
a$6&5e !4YjWk64/k\b!8tMe/=hHKQ6YFpa=65h/5uZKHEC^1u*X*=HncBulJFDmS5kD:jF5R/VAb!H^qKm/#V5
>L\eHF wDS+<*8<J6@>^JiWk6H%H4t9?lJ>T1ldKnKVIKc9Te9%+:Bnea^JJXK$muaWi#kAtiH+mFB!DZXK\cy+
Ln+k>V mX5q#pW#hF>\V>dY&y\*?Mh!!@?6Y/4TSm!\NNw<YnJCDn8Qbl+8cQMuJ4mZAB\d6YLe<\jFMci1/AH+
hiS6B? 9DJ=NQiKhJuLebLXYX%n==VS!+YqP\!E?<APe\hqF>H64&@6y+5%n6#IiM=W5@R+!=NFG^hhMY@:&K?+
@HCpSi ZSq*QjQT:qASmwi:W@yFhEl5ZCZD\\*#Jta=nZ8YdW5Z?iI:CHmYPXdc$ZKF9kb8K:qEc^D*6!phuEn^
/e:Ya+ HZTwj1dN<>FX+ceqh4#Z5#q9?V1qtw4\IIt&T>6$RyX1V<mDi9t%6nG\t6c4SKGin!Aqy+6!>hcbGn>=
Cnmm9Q #jcM4m1N\@hZuDuY$e5!Zj+jcBS8hhnSSa5ClD&J4YtI<$TANH/VycW4qS65+XjEC%:4l*Zp<A#i=5*9
TP%MV8 V!Sq\#kL:XN1>1AyFJ9FK+$^lBaaXShLG$N^a4^:SKZumXtQcuh>6K/LXu&W*EBGeuyRcK\?4TYTZF5V
ZdZa^Q </c$&JDVD:%JPlRc9HE!TIe5uy!>V%^=Z/&J\NacWjBR8N8c1\nd!%ZK%Y?KwXH*kEqT%F%DKF?t1%wA
hNNRP> $4^8bq6wDjWHJhP^4ec\m=*=W1wk1qWy%cVNJ^LFm=DBha@+8Xu4!+!8lm<?QY:&ILa8+juCd8N\Xd$J
F6CDkE PhL&#9$<$eF^KL^IPkL4\X6HmTM==5!?FbMD*BTweN46AJ$l8AJ9$&*/WKhIPSCA^A+&6#iI1%cEXVEc
*aS6#W wyP8BTn*=GtKI*cyqMwT%XyB9aX*A!?8KWYD9DlKXL5WJ5:$CLLDHTkD+AT=J/yK/6Q>%lcijatk\GPB
M?4XQ? kl\MZnPA*LCE=B1:Z4$6b^$#L:!E$/jCl$Z/A@CY@jt#Y4^6dT6y*iTY?QaG8I6$IW+6EF8J8hZnjK?b
pnXJBk yIP5a4hFT%j#MQ^FXb\Y/EykcZi>/5EKuc%8uK1Ybienh^ZXEF8bk8:M4mFwX/>$#nSq\R=BV@ha&QJ6
%//qpV RMcuHW^J\5i=QDP6$TFhcGcR!tPhCd!DY1IdcARd4Eq\PPCa8>D>KD/EME<n6WMi=%b=cA&a5Iiy?#^I
9k5ljn <lb!Cm@Y9ZQyPL<@*6nEJdNFJ:4Fk?5h44uLY\\kJQ&EGHpiJaEZH@DP=^I#mPk/d/%HR5=Jj8qGk8W>
Pyp^9y 8TGY&P\5$mj<KY+d!98kSH^Y5i85PA><FbklchXq6j6CVue8>\mC!pAYijYIWlLX\uWp#YQ6:Ra%^?C#
NdwZYY FNaK!$tK*SbyDb!a\5eu%1bNYBuDK6tid8*4JecjE%Qw16Ei:4eP:QDWN\ppb*k%lF#kjZ@kc/+JPJnY
pk#6^C j#nYELwL=qi+Q%\u$lBB%KlBTJwAyJV%$KanG!p@Fk&eE$\kwq/cF8IbRt4k+Y%?$uKb%1!uNJRu%+!$
GYcLVk !K6!T6AReTAEKkZ@Rh\hMc\uj>KhAa8PJi/TVcaN+C\%/Rem>ccZHJh9p?i5%Cnetb^8k=6J$D%VPDyK
EwXkd? C:X#uV$CDdbQ>!ZJHyFFliFL5tGtiR5W\y+44d!TWZ@MwV<LR8V4Hqh:=5!>KY6hKuL$KBlR+j*a:tYt
!hHpG# wQ@1G6#eK=1/XF>KCna4lb/uhpmSuYy?CK@X*/:R%6h^k:*WX4MRRl/:#G/ydET^<#a&DNM?SWn=Jk6J
+?dyYW +&+Iw$jeq^dYdC#:^e:<t?=KVLY\9:48Y@>IYLXXN&Vwnt:6diCS8\PL#>TMJ+tCk+?Eq!5L!4Cn/6SN
#b>CV! ccuVuHBRueyTN\#>NH4P@FPu=Hluc5tKX%<kTkAjNkm5ncbAGGEjD8R5Lbjh&:P=Z#L:Nc<?aS5W8JN#
<5wG?Y I:Cd58V<D!h+!WAykQ>MNeTMmY:\KStAJ>/$\8nIWcWlKF+1$H$!D=Ln>A4q&yZ%X9$?b>#4q&S#n#Wc
td#MuY GLW6P/MPY5F!G5lF*bPQ8l6*ZYNq+AXCuaw^$SuB&G&&McZw=t4nFuwDXkNV?SXBBtX9R%$Zwc$IC@/R
K!LJyE i++9nWTk\BA#6GKKmh%qcaMIJpCdJV<aR=MdS#EcGyYdAEP8Wyt4DwmpC<t=F@VjAPDH^JeBEEH+ZXQp
<JVFIk aNy$Jk+Wln/BtPl><S6ZT>\nen/JmcNZqRRA?uFNk9ZK8Y:iLqdV=jK1$wCtk!C$/u/Z^:nc5Nj#A5kV
J4%Tjp wny!CGXb#H#wmp6*8c+14Qp=dF8KkaFdHe%t!Jcj=FX$Nkjdb86a1R!$6H?$Wi=ZhQ9BKBN/^D!:J<hP
c:KdE% w4blRKnC9TNw:/!FTYC<mVp^VC#5qFZ1+Ku@Tt$1y&*d:hjQQ:GwBn1K6#lJq+Gi$Eh/DIWqSDFQFDC:
/aVRW& C&<>ep/%&VCnZYtZ*E98nNmHG%!/4$8uF<bwc9I5&1VyeYL+/tAh8bkT/KDtt5=d+4$*=Hc<yu*Z!I<<
Ep#Pj> #4#t6d\K?Q1bKX#XuuV=p#JpkVbK#TQt$nDSM:tqeaDb=F4%Q=\N<DpZQtTteCX?=m>M6w+n=Kl?q=*e
ZbJ&w< RyGtQjNR?mPyqw&*$6^ASu!TMBmEipZ:mMaF&i>9bB*=Ew>mH5>RHdBLV:Ri@NAXlNjmA5BdVnQMySB8
^SQ=8b eLRb1l^y\6M=tjC::@BRm:<?VH8D5EcH>9/R+Wmm^6$>Z=8BQPZ<bktpnZF5nY%5qC<%Lt#<p/$ki1k@
p9RRXh >nNNtPB\XK%d@mk%Eck^n!nQF?ZZC%5cDlB:14Tmh?jTT#@apKMh+$&EXIBD?F4KN&Y/V!1<LpkVHaNV
K%Le$9 G+cTt=hwby9Pq+^LhJ\MNiSJN8+hpFN+SL+1$ZF&t=B*$t::<At=EtQhj/QB>JCw/q9qVmI^XRqA!4t<
hd\&9C tR5DKnb5NA+S8kNypRBIkj<\A\/bVi9cDq9&i?Kpu4>p@pC4A1dW*H1?q#*kuEwMNMKq=&MYJF:piJtM
4Emec% 8?J4%BNVc9MkDI$?b#eq#eLP6$VC%41XDKV%5@5W\+P4nYXcK5NtZbTX5\bAiJR8<<<Z@AhLhK9DhY#P
?PetaP ZY6LhHwQm>L4c&ZMVy+jZH$Pwe:m+j18?RFQe*=kiG:R@#BL?VEiC=nTyZb$N?eQ\*IK$XP:*ac/P9W9
^\Hw^6 @l@\!8j^cD5Cbn6hIWGKSb%WeB*bB/V8eG8KXB4jb>uQD#da&TaC>n=:+wY+$>L=CE*hjPX#t=JZy@:X
jXTXM6 %eC*MuKVFBE9!q<%ZH%$:@aqXlDdK*X+SR+&VAM&w#b:HFC*nhRZ<t#<=l%BPHtm/BY1d*=8^CY=+8Zj
EnZ+D? u:B:q$:NAG#1MV&mX/H+F9La1GT#c//E6K=<mjKV:nXXm4p6tV=J6:lcQc%pb#*K8dm&kuKQLJuYHQ$p
PiZTTc W$*CdZcCZ^wK@%4^<@@F?5nIj!*5iYEVRj#uSC#m+le%EeS@qZMFmjk=RQ**BDS@dkRkIZ@P@5/ARI4>
aEu%$@ Pj8:9h%I/AZa*?^H@:ta\M@5Z#L@@=KFZ+CF@Pc?mD>u+d>:Z8RFYQl9&m^?AXd5%$dA#<WEjtcl1N@e
bh/aT+ >\K/k9=tH:#+BZRF@W$@m%>AX:<%L<R9IC!+^K<NCHHaSWV=c?ND@ALC?p&hc1V+BaRFlWN?#j=dbw>@
9QnBbT pQ<#$?RjY&V@ayyI\H+&VeS@qhqDAm:^j*<t??L@up#&BiFdW9/L^GV@q5t?<%a69kcpeLKPQaSCE5Vy
\WdyjR hhJP5VQqD+bVDJ/lqPY:\C@C4iT!/18T<P^wKIM$qcR1J8na&mpX#S*Bm8<%9wMyuKiX^6E^J?bhXGIa
\t#XW/ &&dA$/^RyL4G\pN8JY!b^X#n$:LAR4qm%tFYLhCpLA8\DtLQIqCh*JaEXMQ&%waS1E?!AGlkCcLhm4b@
RjuatA MAAEu%NhB6apH9XnZAqtB$R>$:nAqDb<1<Qa56&Zen&cR9/heYA#W8biMA9Z>CRa4^ec:<Lc?!l!+N?T
@8TkD& =&iNZB/6u1^jEH\j:C9V>XR8Cm%m+!$\JD#bhwi/X^H8AVcqjWdDSHEI\HePq*>e\c%?Ena+ZVYCj55V
8E8mu^ X8YIRXLtejtKt8+<%1C^PL!4Jj@t1dKiHGbE/^!Mypte<BW^XqkaBZHcWR!Hm!Z&8C=>HDh6l=Ju<*w6
M44P>m ilt$?Fm>mtiZ%=nRkE:XNM%TBc*inK$T5dmWYydYIM^CJnq#Y%b@CCE?ZAtHN&V^yLYDWF:H$eGeHhY!
Iw:mh! H/&HWbly9C+/$e\itX8>y4Q*pm$NlBTb?u\/J$eyu9ywh<aIc64F%!Y=HI$cCG6RL>5LLZXDap&LhS?N
X#WZA: Cc+G6YEy%l8eG1!eJd!AFilZFS+6Ay<<h><4c:BYb&\IwQRMK\i8iJYh+qeyt@d45ebYML@TBu+h6^/%
EdLll8 $S8e:hq>>qGY=dy$qVW#yQ/?aDbmJJlcAGB/N\$$FqIGcXtRX*=Sy#^NbN1=S4:1*:I5ymj^#q=jEjyF
Y%d:t^ 4H&HaYDy1XLel/Q59Yutd^K?qG&LePD$<J!<ZPX#lQn4e/T1@DM!buQ4RDVF\&<%B+=^^5>aAFTu8qCX
Ye1#b: :kiy%l!*Q!DYC9\5P^S>/EY48h4FGQE&59DkGA4A&@RtjJJ=#1ud@eZVhYhG?I\p9mwkytZiu1P+G&dW
c8DR6? >!mjB$paWL^kLdu6TttRKy9<eZqT:@Q>55<>MIcDEZ!NN+DIEl4=E@N8<Q6P8/4XJ1XX*NFEcT\CAwy8
cu9T>\ eZ^GcTJpb!*!%1ZaV^JuuBS1c@>$RC1me=GFDmm1*Zmqi&/^*?L#ZdW1N=qiXB=V:DBj>FdA1C\<jSC@
P$Lb1D qTMBIuKXe@MP/IwAHbh!&K4RqE4!mGAP^m8eQwTPuHK=QEJyEQ<!S@QAJiac#\D8jj&HQTmRL4k5!Aty
j@PIl< J%eH!iE?l&qA$^bLGj1j^S:\\h*HP$5dKSk%Yi$MTwPNl=Fj&NheZN$G?Q4cQ:/CJJZ^AX&jK:aMQBb:
qkqewB S^aw&89qNFVWG&h<Bp5j9P\<^GCeE^Q\SEt?$&t$yWSTZlGZR5Xp>:S#tNdw6y6qdJS@S+@$5$I#P^D:
QH*9=w c<XM41!a1$#PwPT*etL=pYRPuG@9pc:S/Ka45q/blAHl>\mpZ&8yetac?aq?V1?H/*DViHGw%ai&hDZk
RwtVP+ DjND*KlEl=?uN:=85?4Kh6MJj1LJy&uFW<EewqP^^dlGMGK4/=&dBDKRBk?AdMelA9ZMkBeE5#Q<lGKm
*+d4Pt WRdV@B&PypQH%$Z%Bq+My$5/VD<>%qnZRq@1QFb@9%YCP:yCq&e<\JW98X&^#9?5JayPi8mYuRZ>i&:=
-AQcG$ 0009cf3eaee00110333 Page 145 of binaries1.zip
Lydy%e %?AlZEBW4FCp6Fa9$abSVI:\cZQDuK>$dHyLRNDyPGT+<XCbi<?#!1:m5y\*PC4&jX/Pd:k&k8?Tk%u*
FLD:\X 89BR4a8cp<?INiG:wHJ<8q#?*M=CnjyH#4$!HAJEB=pTD*WwD:LlP:jq>bdpR@SNcuKJLZab*w^b\tNd
ECZ9W= u98F^=hS<?WtW9jMpT=@mlW?FW*$pwPTD+QtbeVNqJ<H%w%nLHVViB!XQ%I\LZ??q$ck%>BD$9:!kjR#
i!:$y1 iVpHEQpcW9ZP+6Q=FpXa/u/SFY$EHSkI6Ct^?N\%%D?9^i<i:cJLa^t4kap>>k#SRY!WCXd4QwnT/j:p
YjmAKe K!6YM8NbHP&SWFjhyIM*PYLL?R/Y?IFHQ>LImH!?^ACKaK6q%ulk%hcy=5Eh4ML^SZP^Zm&Jby8uGZB9
u@C4hT LRp@C^Th#/VcX%qGI<6y>hpm!&=I<jL8c=H4D<N#iYF<hpHb%<qM^MX5#D?qkW>cuHeXJFBDZ9XC<NIE
Fnn$>F 4&ly=aYXjK94#\SQ+%tEG>RhlF^^an4Zb!wcCpECaZZ^>ui@R5F&T9KX@6XpqY!<n\%:/cZiN^nSj?k=
T<!D@4 ddylJ?J$b/*KX14l?RPDaQZG>BW4T&>cJ4@e%S1@RynD&qn6cV%=R$9yyK5bjbqLDEe6ny%=P#Y@4eHP
+aXH:D 6$+8S\!ZPMlw6>:quQ#FCeQeXpH%Yaw**\SSGN!kQmYlyNYuP^8<8q=nP$p9X&!=\P9hX<LkcETy$RS@
cdImVW w/Rhh#PkD8k+DRWi:Ehqm1EM8\?iCQd+/H:&cnetCtDtyZ%muBnh!:jDquSqZ6Ip8QBdA9@%!$c1:!py
l+*nNt tM@tBB9%<pnu4Jp5jcyhX%!X9&eW5*V!^<iCP\huk<t\S\Z8LP*t?jt+5e>Znn\iB:cL5?FMJ=&F^N^%
WTYy8P /ayJ4/YyS:DXDZ1\KIW?6$=Vm5D8ZteTk#?aPhe?>@KhqSTdwe+j=wD8T!^Nl!<?h9&C<J*G8l$I#aq5
4DLpjP =AdHK=6>Q4@WEdh=cC/1I%Enb@L&W/mAM?S?>FYtchM4bQ^bQVB+#\hCL65CPBI\=6GcM&A=iTXYt<\&
jnVtlZ 1Ana@+R6Nme98!?6mGFtIPm6W/XHkni!@u*+9b!4$@ljBI6Q>*C*$mdkBm@9p!qqQpkhpM$m!8T@*8%?
C$JC>* RG@MwGbhHyT8#%n!FhPF?ymDW!t1dCW%n5#H*auI4?I+i^DXYqbYHJEj11b#4>u%Zt^JdZJw&^<qm*4D
RQYIln 1&HlSDbXbGNP*@BHXuW+!Xy&b?eV?V+X&mh8e\B6!F1AC1=+uY+4=HnW&5B^dFdPELHcelRA1F>TlliV
5a/el= ce>dkFj^%ZE+WJK#>%q+yp=<5InhhGHki&L1SL81y<AI^9STjADtZ8LTCB/GN6MlWHte8Y/k<I><!@\T
I&jyKk u%DBLM^BFDudD4GYJ%+Z8Kh<VwD<KLF+56X^<<q+cua^R=cTHRYyMDBEdu:HP9GRqJJcAZQkT%ViTkZy
4GKBKD Q/de@V+e/CRWRechTXFtGe5@Sk6eXV?pDqdTFw$KwjRawi#YITn^4>ZKiVKlWES$>FKp+!FkYXj6IYDk
cLhhP? ?^M$R>cBAZWMMS&Z8aw8EYcuWnM^<=q%Hq%QM8hPAGqwK!SuhumAhdhklYl*MXPRcKk<h1\Cu&nJmWS:
!BYCm% >4CCEbTAp%attN46nI*1n\<#XFEhFTBhH^!SVZV*Q\K!DjMy8EWIVAHYB\:RW%68a>*yalVXCbHjI\5&
H+>#BI 4l:&5Iy%ZSXnuantES:LWh1miGejGbpEh/IIhZKJ^NeYAlKhqIic8kMAq$LkSTA@9jDk/=wH%qGyCdc+
ZejJYX yMFXKI=Du4jNHRAX:n#L=bk6DnWpKX6@NVSeEIIh/b^X4V#lnm6Z6&Q$5#+lBym:aI9jiSq&eT#ZnLta
iKt4FB J>6:mM\ImT=MlQEqe=$Q%VbTJmij111<QkyMh$tq<LL6=Jm%$YWSAP4j1<Y?LZ:GT&4juJ\DJi%M<E^$
q>/m8Y :S$?^9X\4b+hPc:9kGKdw@\jPwdQ$Hkq^*myaRlt8WwQK^htKn8>8>k$ipRP8yX!lda@WdZY>TD*w8\d
Z8WRA6 i=ammLS+y>V4Sp5QE@kPQ?kH$NuZ8Z*%WC<H:ih+Dl?=>J?M1SlnX:n8H:5m?9Bi<jp@nt>?i8AAQe+i
@aH1$u m6>$y>\HWPFC>WwRitD4!u5:^JB>Rk$+/RdQE4bH=CY?KE!1SB8$JX6JqJyZeE%mS&mSpJVqcLGcnPPN
^GkS:j Y\e5<mmT?5h#jbK5caK:FIL!=PJVHK=^t+5=<CPklYJ%&F%5&>=18!$aw8K%PLbjZ?h1itj@BWKRu6>D
mA%=NP YF/b=w1YnZ\iF8KnFGa9S+tL9BtIIaj4\?t/^MIi!ajS/6F&4A!N^>XC8&*>NWa4&>%cE+<LQTmupN#N
ph1GC& wn\t1q%+uV5!a1Q4pNFwV*i<a?Al4M=d9McqMuB@i&t#\hQuh4KASn>R:Dk<aC4cL+Fd4E5>9YQh%NJh
K1TktA 6p=MRJTReM5jhQJT^&eHNhZ<ji^kI<hh&t*=y8mESEW&6N5B9#+?%N9$%XT4@&mQSJ#jLqHqR#5<RQ$>
*luN16 FS1Q9FN&>IG&?hB181J/yS+9wE:q>tk!lq+WK%IN?dE/HKLZVbYNV<YJ^ki:NECVp!k*T$9X*FKM>i*A
9&?M1! ZcT/%b\G9ppIRJ<SjMpWn6$qIaKEwClQk!uaN1P>P*ECA&acAwil8F/HG>hm6iD4X::T>/+Pi!6MA<!>
n5Pcjn ^+mP6BT>b+#eB%WA9M4aihZ>FbKJt!VVI1>y^c:XDXpAcXB/d:TB#iwu*NLJPCW8yR+QZkT*Ie!iS4H^
V+Fj/& !k$8R?5nYqE%jwHRi4XWKR8HhGL8MW8Z:@B/Mk@/dVSR:u4yJRE1C8D!K=9?IDHX?KbJTa#qZC=CuJMd
Th9nBD GKJ##VT$<L8:&+8a@h5NI\Int*MAaHi$=4iN%ua1kRwiklBNChFB$/#mBh6am8iDuw^h&mE=C!<hu8Am
QDdNhA 1pPI$:6KNV6t!:<k@a$nLTITepWe>WFl@WC1MaTKb1tRyyPLRPHH:8><6:+J1YPGduI%$Dd%wDbnSCm<
tYL1aF 5F>CwJMlQJRSiF>4D%=8Jc84\<ZEiY+QDh>V$li&dAdRL88Me!VVjlDl9AVmy%PaIj5<aG@&T44KNTBk
KK^4u# w%1M@$BJ=h:Zy191w1w?>ndaT*eaJ8dW6ch8LY%iX*lpLSRQ9Sq5RY%SFcLyV<@8>!ul=6dH&m%Y*=9B
?G^>!u kV/c8%RGMHEGE$THVu^@h=iiKCuaFt<%*:W6%hB/1I4Xnt4w469bB#y!p>yTt\l4auw^kt:jRP#%i:/p
/Ci>BS h=*@8MPA=?aW/qJ!+MD*5c4@w%taSFDqq/DpP*=E#9:S#SFl%yX?Z!&\YNF\YiClS+8>uQ@bqTJn\b6c
n=b^kX 5VYja8:uj9IPkcLE=\QZVd*WFi<^Yy:EBbAH/uH8%HQblHC=H$5::F5Il?QG$<CMyQml:R>1nDGH@HbP
TdI/$m R8t4uRDIqhKmh9WDXLy8JTTELP%APwjemKDyG!ZjwHhmC<qB/6%dnT+iT41kJ!D1&1^XQc1TD>+qqFRG
tbkGMA LaCT4+@4b5jZTl\>Emlw/MqBm%Epk=1c>:tA1W+^dTbm&iXlYG<MS#R=XGMMJ\VN4Td88^L&kdmcR:u&
taQply /$19aa9n=1=ccAQbB4?>yE4lG4TZ:%6j?pn$NTY:&V5Dub$+#\ePPjESXVLaHD6/q@6M^9eqXNI64hlI
S5y$Jn \Kap:>p!HlK6D>1w?FtnFX:k!yWIQn<m&ZAPY$56NFWy914tCQaAD4tmV=15l<pIZk>&n6<q!Y4F1cY6
1HY!Wm EaRiGG<uCn8WttS@>5:kc1?NYBb6mTH&Wd$MQM\CHHQc4ddZ#ii$QCh%44:YndeYV@Kic@I>$h^:^T#P
G%6TY@ ZY*?qhANER=yN^=SY^lZeL5P4JiM6NDcJX:N5p>mq^bn&B>Aj*K:P^?D6@8PmW$#Zu>J&>TIc*IhMe4b
LeIhtE K9i?<ty?eD*j/K%!*j#!\ELR>9el\P1D&FKXw9h56G=KW=8yiH4lHPFHYMK!8TLC6YWHJ>q^Vl$F^=ce
Y=a5$# I1e\a!Qwt94K%IJ%cKWFKjMVl1^1j:Je^QcY=KKFu51*Z9L41y8Q@Hd%iQblMS8PC8Gt4*eai6b1T1@i
T<W<eB HKBM+H*N/TM5lGB:S\i9ek!j/#Z8G&^QRTW*nb$Nqa+QF8CyX:c?=l9<Ztn$cF*yn=$aTm=Fq1$Ih#@Y
RX=QPu hM#mjXB1@&/Sbcl!!k1=#aBjZWeZL54+Q8$nRQFSa/^Cb&KXcRE^R<uZl9q^J$^>:J65/?BZqB/TYahB
6#Xl5j 5Y<G/:y>lA>n4Lq8Knqma58BPT\V$K%S^:L1ewIS/peD=KYDhY@M!KW5k%^#m:mMM*ktX=a\JM4ZcJ#5
kDed^/ H#BPJFbDKa!*KW5PhJWiQIei8$&b?#=Ky1lPm?$ajEP&WS::B!kAL@uN/>AXeqDn>qGwdVPGp>VelI=q
WcM1B$ Rjjbm%au@5i>AHLTwq/VKECde*!S6dJVETqtQVWyDFAn&tI8l>pkdwVR9Nn>w+P@1CNANedeqjJ5>IF8
>KC+<= IEYSSPiSe#uqaPRCP#Bnb^mVtuWkSVSBG6?YHq5n?4#M>+WWb1Q?q6AMMDjYepw%#?ppGnJ4lV4=/F@Q
?n&RM6 <$=@?q:5Tac*cuBW?NFJucaBkTjb&=A/peM^wRQ>?&FyRG!1A+b6+$aDB9SeWGNWnhQad%e>SjuajKiu
Q9\FGE &W<$BL$Z:u=b<qDeZwDW?8G#\@1N8DHlVW!9u+F:C#Y1GTM!pS9cn:Tt@uYmG@H@*aq8@6iMD@H@ZHId
*eiC<8 CeSQ^weE@KLG^>?nqQ<Y?$V>HGRYq:la5uppT8\C4Ql9YPkFYQm9h@YnaBhkj^Ma@#t=@5@5:+!Qu=Q4
SdN#W? @+L>VVKhu=Q4@<#CEd@yK@EL5L>:Z6Tj5:DjQc@EBhnj*FjmA41C@5dwpdmA4u=4ZpleRFk\/K?NkH@N
Rp/Zl: 4w@=J@p@M\LE@$e8DuG^Z=!i?I>b>@?bN$Mem9#@V$@<h=?iAM4ZGd=y%EGb#pd8Mb<jI=#tMG!NI+:>
6H/Fu! !Aa*Ri\/mQNS?bVE^B&9hcp^naeeDdqLh4#>Yy!*\C45L9cT#$SY<<EW<WNKb?&Y&QY@u*G\Il4>^^tH
%B+bI# 9%T+yVDZb1>**Wu@BADyq<?4C\9XM+bDX%#t+hl1n#%+WLQ>FIktnac=LR>8J\NKTmQZjLa9tM/ItkRk
@YM6NC bCi%jHD#!H1>NQb^H/G9CjBJ%nAM5d^tS&HB\HIPM$\lJ:J*6Q!NJAB&=FW/pc?%tRq8#mQZZ&#VauNX
TmD&d% 4heZ85&J4J@VW^=#J^tEn4Qutc/E\+>Xq99L!y:TN?TS6#%B%Miiiwe^QA9i$j*wkX$e1tDDLR/BA*KZ
!yG?$b J@lQm%Fl\m:Xp=nKNRcW/kM?DHVt=Qw:V@$HGcdL!*9PD=mcn^4pHbdhS5=Lt@Kw5jPtaqyZ*9j/^BtI
JZTEZ8 61P4#bqNZcdL5/6KG\JCqVS::%4X4dB?p4Tw9a^qdN&dLq<et:/i=\8aceRNqu*8eHl5yHb/=$dZBHPL
k#jhVG qhJHmLM6N::TAiPdEGjeayQ&M@*WMCy/EnCk<c&SR9!Z^!X*^%?hpw8M%EyX9m>6k?mt/h/J^EnWc?&G
J?6/Y4 hajF%\*%TwFeaaWA%nhX@jYnG^LZBN4cV>aPyV*YP4*M!>S+t/R?EbTP=#=QTq+VM^61P6T/>&HeHH/*
KN$Phk KtD6/iP4iZb8\ld#uk#8!m&+Ke1/4ILBL&DYnViEwq/:/d!T1:4j/K?&NG4Hq8<5TM5cee8MN4?=CheS
ub8KAW jJ\jwDWtHmV=#pAiQR8c6jmPqW!+l\5KDpE\qE*jKd/4$&BRCn#*An>e5%*uY8QT#=:ChnHeD?<Z:$B1
uQX=q* ECX6%hyy!F?yebkqa$4^CT\X&1+QZH\VyLb&j#DJYN^Pd5dktdH>B<\pB*VWqPtLqVHj\\>I?@HchJ5c
-AJt1P 000279604f400110333 Page 146 of binaries1.zip
/aThQ@ D+wGy>JGJBt+b9>&#MS6ybZw^KSHAGD91Si4MdcJ5w+MILw5qA*#H:+WDhX%AVNL@@n8pi9@EaD@<1/C
N8&tWE ekEV!Gp=itj<A$T^666tjl>SM%AE:i4Nt<it!I!FQae1j!ELCRF:WNIwXBmkT?NbJj^hZdj4?146F!e=
\/4ka$ kTSy8RRlyS6$@\>::^$YXb>tm!JRScwmTRcXuEMqwEBERyFVpbGeR%HpIIKBuHMYEbGeM\mITM+=w+lI
/Y\D4t qmSb#Qj:i4y:yq8a=5#eM?e?=:tQj=ZW19*di/@/\X:9?/+%9!c5pQ#yNq9<yFyhkd^!RLw<4tp8a:Pt
*<q+P^ Y5H^lqn*k9$wd+JERRScMFG%#KcqR*HnwWyK*@emt8a6pbIA%i4eki6/Z#Wq!uZqiHGK<XqpaKbdAeZh
QXqddq Daq>MaQcR6G1N!YBuN%1>ycc@Kh*P/p6*%/SCWyLjJW+4JmGVHj$V*EGnAD95Ep65PMD?GQ>qFI41K>w
bH61aG 6YHh!EjDEFYPJm56HyQ4D<WJ%y@4kNc>TLK*bRaEX^cXCpJ&KyRd<TP@5uV1&#p=XLCK9PJt8JIGyMDX
ATN?Z1 /nI*JL$c#p*CA^K614J%NK>CmBdY$WP#4jj#w%TekSYl%:=W^Kq6#SdZC8VByu>hLjGNLm+aKBeFGpGu
VHiuAY jWQ5Q@%\$Ft:kVjMa9maPyS1anyjpeLIT%=ncRL&bWNQLVCp1Ki?n?i8LZl8:b:>WWa^$=5bam+u6>!p
FBNKqZ =\?j#NYdbA4aqEaGTI?8MiR5S@RHXew>$XaTQ%pecE6&<S\N9bNVlBe<HVF6Mq1BF=?#@pFZe%5kqN&D
#$%A%! Gt:XQ/NDWP<FQcF%ZMu+KqHwQ5lN:8m/>4SYJ:Ht:YAI<YT8S/dJ=%9wjA\i@V4?l<11DP6S^<hi!dA6
VRV#mR F%+cebW=Y6%SL>$w&M#im*6c*ypj^l<Ru1B=MNM?=qZC%jBq1w!*I@HQl<q#%MBZ=?+aV@BHTn+hc\lS
CT?Eja i/qEYw/+yi@$eJ4=DVe^##/T*#!dNVB6Ijy=\q96cAa8Q4#MuE=FP+Z6L&#XdC%qaKZKY:$y6$wJFC9=
h68Iyy ^9P/C@yDu94\k$b=yqMHP8^j98^\Vp@Kp?C5iD>aDI/91j8ewJBcV9Xq^N$>XL9ZYeAZa6SEA*8Vq^4?
>+=D5J ?dw/Ci5HHhYK!mb^w?Y9!PeiD:RXl#4p1P<WaYSNCVGHVp>9&j1y5%JjVY/I@m^nS@tL<ejhYGjeyKbI
CSIE@T pcP%lD*S==!8N=p@KlSdD&8bn@D$Ni8$WkZ9VXK>ty>?+WMut#R<59ikVe=j$@qPi*dZRHqZm+lKZ5Lc
HaI=VQ c=<4R?@\PGlnu?9XV#NaVPCJG?ubV*&*P9u+9lFwu?/1tXKwqZB%8yAB5\qi>Q5YpaL+&8dX&YMVw@Pe
AKStj# :%dEcHZJeknGJ@IAV?TD6b46c/jRlkIXK?Z/p%^R\yPICV!T6y@V@DSY@iCR#Kj^Z9PJu8:Gw8!=Sq%9
AeWD#/ tTtG:DjMI9pa1E4TTJtXqldiC1Z*eu!84RYCY1p&bndLQp<SmA\i9B$XytFKJwcDD%DhEMGd4?%ImZLE
8a?iiA &iM?uFVcNN%M14\KkYS<!@A1\^Ew<WmkjnLN?lId:Tk?$BR<k:>RnDS=jZMC/uX>Mh/9<95RcKTJ1=QD
%B?18M nJB9c$aDuuh\MpILy**k&R%e><=Mu*98B^$R%1NWaymq+DB@\8SFVN6k$8pqK$kt$>qRe<i/8Z>^Yy%H
L>TLJG 5ci$lQ86la@Bq=y8q#APne!Xq>j+G*e&$1+^en:Xay#p1k&#F9X>=:H?RPjLKHJ1iWGyepZjajT+>b6b
#V=!Pc q9H+T?1\6n/9KHd*+1QWB*^Q96!#a*%cWT@\MhKm\QZASQaH?iu*AybmZbI^y9B8F@PGL:hiLT#*pTV&
Xd&J4% 5%y?$iaX=L@4>aG/5l#p4luK+TH*ZVT@=nZlE4Lm1@k/W*dw#+<8i#HkEhP>XTP<ty<8?$>I5QFKI&he
/8I!>! =ybqkeYj=4I&J&!6cu+IkW#>D^M=P9H!?bMW9bNC9i9JYyQXG9*cqq+N=mX!VKBLN!XpK\=K#mT!6=L*
*!Jdy# tPM@yqbGj+>%aF<8Ht9b6t:1qtyT5AWY1V:DGhCPZ54u$EIWJ#eP?n<4RV<n>*qMFJnX@>B5:Ap\jK/9
tMZ\n$ Y^/WQWJccn%D>IW+jIi4Y+1$8M:TuqQV9E8T?Q1tw&EVmcW4!TeCiT:e15nY$Nml:a:$1EKm>i8kKliT
4*I/@m at\K8m8XZ+?j:@=&#B69&+ba6?56P+9N8#Iy=R<hl%4>+:im\K&Q@Wh^!@nDlF+ARy9%+$*lyJHJJcH*
MC^N\d %$?4WKqd=VDZM6<Tey\>&$\VBeXY*Ah$kuqylG*P8\NHe6Q$lc%HJSu:FDmXDlqjmPl$kPwX@ci@ZH+^
ul<I/V W4kQ:w$W=\<=:@qWE?&lm:Ty*McmTPdyXHIca$ebi>C=wjJyCl&kWJJ4iI*DD8/qwL/d??8t@lNk@:+i
@nkMl* c!*l<RWAAY<ac#/kuDSewPE\jp5F#+cRyM8t$+MwcmI>Z*/8+A5aiwM6ctT?Y88?c\kF?96#8>cMum&n
TKyuct 6Ymk^6AJTYQC^t%19PepB*Lpc%JbmnmJt4DY1FE1FY6R%X:Y:k<KI8hE99BV:LHtJ\W/tMTCy5VV\Y4c
I/l%$\ m1JDNe4&iP85Qku\4tVYEQjK$F+A#PB?JDy$S+nq\LI#l9LRQ%mM&IklPDw?%@bu6Z^%9E#MFqIV?=+w
?m&T%V X!>Xu9$u:P5JEGKt@FW$H#maiEaKcE/n?G=TwGlX$9k8KIwu<R55/j1G9@*JJP=Q<8DIau+RlPNK?G5<
qp@c8E VP\pJ#Wmj>Mekt>hTSeMB?B+MMjcTy+TnR8P$WZJ4e6dQYWb%GDqdIP9K$E*9:FEF>YSp?Ey<WAKFE?K
FCVY*8 ukkPb+#KcRIhe$X&PT64#ZA?Qw\8iiP*a==RZldhe!ye+bM=?RVu<BipkABTY$%ZlLK^=WJ89mV*?EDa
$n1%j9 :^5Q6:hPW4!4mY!GV#*#:@nlkV:nD$+aEu#L/>ub4*^e=m5mN$pQi6M>CD4b1d<YXQEb6C6>XJPP^ZFS
@eFS*8 hS=a96?EPY!cppn>FD5wyA/iputG+Aj:i!5W4\nu!ki+cHp14\Q4qK:wiJd/a&K/!pF\HMY&PZC!Q4Xn
inu&D? ^#h&G5E<JwGRAjdIYDXEFkFX#8&e&$!B98HY+n\h&VJY:LiX*R9cuA@>R#WejETK5e?\\R?y4Q%&\Nj^
6^Tj58 !=ulXN9=a8w8wNLJahYB4n/mDTa%Vp*Q4an8:Ce\!%@JRNIajFZ&Z1WeBH5RRub%l6q/AbI6^b8N+eyS
NHKX=d qR%^qX*laeXKE5GSb6BI\%A&YjdRBuThVRtXG*ihy86HClm!NTJF6^d@RaT^S>I%&h%8*8&QwQ$ZFC1d
^QbcN= %u!:568HE1/kdJSiT*\ucqYdw5wiNQkJGJXANAHXm@1p\>9+*V*nNZZ5F5e$i#Zu+^A+u:Kuj4G!R=@B
y<FRCd hytLCMh*nKy9qTL@aGjJ*91i&ADENGZ^yk/wJZRQLH#a8=Y6*J*l9jqa*6^\TYkQ#JMLY>8<=SlldyXp
X:aMnj +9RRthiMLQWk^pG@TKRe\B8+Q&*\K<LLqLR=Jq=?RY4elMy>TH*CiT8/VLXFW?mN9B=h^NK<GW@XP<Xu
kJkPtD t1\W$tn#R@?6=@nYM+q@@DY*%byacW@>qwiwI%Vq^a%8Yn%dR@+kD+y%aupM5HZ95DuClT6^4:u?AS9J
+<5$jl J:K^y^l8Rk61+=b%=tbIHPl19Nj^IwcwY/@GWMRht=8/hBIXRyJTMMX#+8\<>=:98+8#m:SktHEqD*Nh
?Dwj*K 6Ku@1A$F:$lRJGu>:p*8D#h&8&*Jt#YQp/@IZ6SF@I?JeQ@nC6w@l5yhXpEVlj:YPm\K9Y#4<N<i:@>b
j#^iHS NQlhujq4X8Y@>kH=QcL8HP\FQmC@S>Thk#*j&$L$>+m/e:CRC:DRj+$Xlk8jn+Z>c!#mjC<Q$h<D/5:B
tZQMDW mq/ASX\Ci::%4!lE?F>n+ekL4yZI9<dCLn4jT@AKh6H=ZwJZ$I8Pi\qiZcT?mWI9Rc\@&Ze8>lLE?6Qm
@GLVDQ >%#5JakqDIGhn:$E5iAZaT>BLClT=H#5bakqh5G%?8iYbVGSj/qW@1%N?W?qEkH:VcpWlb:Z5k\ZF9/@
mY<q%A 9&Y=<j@mq8ZK=n1/%6$@8=YLpS/E9ANd4WY!n9\J=EC?yS:^G5*E:%P>#^*SXM4X:tj6AwNL/?LSbih%
tQKRtD IYiw$!QS$al!WiL9S?Kh#/YKPiSqbh+^nB/WRy/Q1@G8ecIThVB>9FhRc8R>Y9cG9THCt:6MADA*qkyK
IpwZmy MaeYC+p?68+PXX*DjV/QNaLS%ccK9:i=p!yHklBKeh<\CKFR\??aumJ*a+lJtW/pt9hGGnE6B5k6L\Nw
$*98MK a9CbiqT9?a4G%Lc=%4@Di$yD%cMQ5GY1VNkDnq1!kYI+q8dp%5#iy/hEQKwMI8#quB<Kjlc1Q/FV/Skt
PW$8/I al#kF$KL1HSFVh*@5#%bpntLMA/*:Tt@S%W@8Ytyl%mPtYwIkK?HXQ\dl@/5dmtFpew:/^i&:q1#F4i1
I\9/^: 4Vmelc1*NtT&LPTj&H^W!Y#m:JH6M=+XwR4/?dT\1A1#^BQQT@D!*Sd:FDt\EYqMH#yR^pE5+ewQYiD4
#<1RQK y=dY+i<RiGRiK#9!lF/j^^#hB*>e5R#kwp4$icbNXSM*Mct#LMpR&4h/6%MHe$5=AWnYG1RV\TaTQSWu
WV\M%H 4m%GW+VqD*kIkw1\=Z1R1InXlS/pbp^6H:=p1WKLm:<VYttXRw?Q*TFl/6tltY=5BT*Gmc+BTIdjQZ/V
q/B>uy RL*VNE4#cG!<@JFw\Rkyu9@kph=D4G*X?<VAS>%jdM49jy?LZqp*p1h&EW:Bd$$d@CG9pXIt/h*&NYE?
55Cm%e <&+^#@8$QM#5AkpQmt?EwM$jQVn+yNYa:+ANdq=E@QnA\l$wZCnSt&yw#w?$=X9:pdwTuDbFKSMt6$1Z
KaimCu 4tM?VREdXFd#u<ljkY!@9/q8%De%peQGHn9V:^c5qD%cy1hXM>R^CCwYac%jZ5DI<m$aJ&D48@Zdwy>L
5nqa>q F#8w<HjJ/$T@Hqa?kIienTl+bYdSBd8E8WXE+9wu>yIaYXwWjZE6a6Pt%FPNNC6Gh8V4Tha5+wnJX*eZ
wluyT/ Q8+:\ch%l!XiTWY<\P<utV@aDdXNGcqp:1p%YXaY=t=*=D1/HyG&+8K9PMZc*6iRM5<&yq^Ccpk*>Wwk
@N<Ahe 8</IkMnW?9be&ie%T#QEHqap:ZEl\tBbH?EGwZ4eN@Z4/RVM%%*atW/d^5KtR>naL5J8PGVXjFm%D/5t
IKu\qi CT9#?WYYpQ\YHlA5LwC!jy&/ZIMAP*pZBFji#mby^$=/8R/L^d<1lFPcpVjV5ancG<S@5AXXFuPE$u*B
JB@E?X B!*@^I\/RY+jP:JuqD!=\:K5#$+Q6M##6$58c1IHetdVY!huJph?y<i#^6AFqi%4DDMIXTLp$NqEjmk%
P4mRGV ahN!lij$1%VlSYNqHV*$uLc1W=1^+W>9cY$Fq4Lp&we:eHh$VwP=4M!=:!4=mw*IcqN\S+9uu6TQK99!
M?hyNB Fphw9?CjBFyZ%yKayV*PBHp16$&kVJmKX<wi4WqVAN\uYh5#>A6/dL$J^Fc4>h5#uZdte8uVtMDE+Vy&
V=\1W^ hRbXlk!\P+PaRQu<:KEk8hSJLSduMm$pFd>9tEn$Md8t495:96YMH$/J\d/uHR#epIp*%9iC=W5h@N@&
$&MdF> cdLRB^+wd@jMnQuh$JI8ZjTRuudMmB<LJ%q!jyq@?9:%=!Ru\X6w<FRpiS:8#E9hVaiYF?*Wm+D:beQK
Km1#C$ >\HRit9W6%w*=^QS=D+HccwV?%EP6RL%@l><k!E+Dyy!*$K\D9qDDqMSk+a6<lXdA^d*ajdM!q\wdcj+
J=mLnN c4+$&+W9Q/XIa%/KBwa@j46!#&XynCGbkHCH8+dcVY+Z=F@I+LM>ZEl<JTTEP%%D!hHi*T<leI$Nkc1e
-ASjPu 0003b5a4af900110333 Page 147 of binaries1.zip
RZa!Z^ MX4kJSP@bm&%Q9@l4Zy5:SM&AtFG@*i+Ce/^Cew9C6E94tqPAY&8#Jb\PliVKbt=CY>T+dNLt=i\LT5h
*Rp<Dp hTBw5=&n*59:QqRG*?q9jAAw<h*#8*5&I5^XStK<h>ea9yeGdJ8d=>FLHE&nYb9a=1!bYA<b=JDbbY>w
J5DWkA !pLe!=\!lP+45J/RVjG?VFY5/t9@cGVD\nw#+=4n^98Dp=m6YVlQ8?w%Y=jG>XZd56tR#=y5&bl5+aQ+
%BM4Ke uMT<w\&=eWHKSk>>IS9VDAJIdNw!yE\^+pEy5YF6n8tD@tn@ul^P/?mQakXhD4\eYuM+9T<CRleIb?@Y
>=\@VL aGQDDdN==M9eGNcaLVk@?!GWS1!CK%Q:DQRi@uk:J9*RlpPKtKelD4E=G=GPRDWmaT<n%\I:haVQtPdb
pJFA&6 hP/<HB=&B&<TR&Y5c\6SB&>AFA=EVQC?8/dj:Y?B555#k1CAlXj!SlH86NPHji$F*%D:F1SP&jbN<SPk
BM!dwd ETZC&1A+PdtA\8eh59\YtB>%4i?<8W1>8<8mB\^XQ4<8D6&!hwkYYHt=#Xdliei&S9#b4T#CtYW#QJJb
M+DyCN 9+FDBXZ%N^anK$8yelICQ%n=F8^dGJ5?YZWwuw:Aw$En8%SRi=yMWbFMBlK@>kk#V+FC*n%e/=&MM+hB
wkKa*^ W%6?Z6@\J>a*n#@nZtFDHJE#jCw#6ZqX8bYuZ4P=ikhtWYuH!n!S4dKw1VR=We<jnZ#?J1^c49:Z1pHq
JXc&t? M!1XVH*Z11Rqa/a1^85b?6k$GStc5!#j>*kVu+?TFH:M$$!&p6HhAdQ6PwH+Q4b8DEEb%TiwnhSJRiGP
b^ej>L m4lC+il\ijQauLMuXqy\*LM$tXQqyR!jE449>pWQbGbIAe8#BidKii/D&+a^icyQltNua5@/1+k#+/J6
P&kCcY kF%YT1m^>V!iKJBbYIGA1*1lQ>dGFV?:tKc\IG8VmAE&Jwkl^:Wqy?9:=P!kaluP1#kYSCnk!wG9eca#
CkLPAA SKZL<>Yk%BRkqN%S^tVCLYHJMVTce^cEa=@AtV\XBCdbi\WE$WXlTk#Kl\V6Gq@HVuS!XZV/Y\N6CmBS
YnGpaw 4nA5<$Q$*l\IT8TccMRX?nwB8A=1Y*iW4PPV%&q#DnXQNFXF1lEmdBSGqFipqG^d#eH&T4d+y6dYh<y4
aNPH=Y +F&aIA4^w5$Yt:DkKE%WXmm4?Sk16Kw5iM9u+<jwP^nm$Rw%I6dRkjnDWp+1$nYjW86cI5eM=T$et?I<
S&lcX* Z!ZZp4^jX*ndENW!lw4i$hphyPNbN6\DGCu#YjR>Yw=%:h+JSL?@RX+FJ^B6GEEbNY+8:<LdX8D=yy1B
/?**%n ZW=>^H>V4%M4Q$+QEpS<X!*iLGaR#NNXDY$^mdq9DBmL*P@JRAYD!:6t\lL%<>6b%MQZKkBZHPk5X**A
K>@/tL Y+@JTHuAc>b9uRpw^$#*BBpY<:?\S6Ia<Wj1F=kK?T?8PT5Z<$pXWQAQwK/uV+D1NV8clM=/N/%HRpFy
DCV4Ye t@:LK?!JPR9l\/Sj<Inj\eI^Tttk=iWX6QPZTpii\TK$6Sh9kYpy:CqQnH!%!l$kmbd!aa?AFT?5J#6m
&KtK>t XT>md#q!j:P?Jk9%cXGNEDX5:@>yle:aQZpe=Rjke\AXn\XYMiZL/cpILAVYQBWI6k/m*Q1RYPCB#iQk
8=MMXw A>X\=:I1$$Y598hP\whY=ZkHTw/EbuRJcDYWp$:II:imMdQRu6NciRiB?&RC:JNw?e:Il6BDu!C!lnFW
:t5&p@ ^mlqSWJw/AN!:HVlV!Wu@pp<dcRA5=pc8?H8WQ<8$^5A5DY&bj/\LEJ1dpI6FKWtKShZM19qp%%dIk#H
mi#\PG C6ZYnA:iFdi4eBJE*5GbG$DN@bVQSNSK<lND%AiR+Xw:nn6j//9iTn4RSei&SW&idW>kRM\n8RN$meSq
WiC8*k Z!5%&LHm<k+FcMH5KJ+C^&CW+5BA=QdQSGWTw8:IJkR4J65iHtYRaXjRXQ%beFSKtDuyn:?Ea:SA<SFb
h&HmYZ $WZ98ElGGnDJ<V1*yRaGd*MPJY&>Ti^PBNXMCL5MDSGl/=Jp/ydi/AjlNK@?awX5K5bcP191Pihmi9lN
bqi?H: 8XeQ8#8p^DwpldB#RJC4G#+@#=CQY@AG^e+t5S!DMlwqn#J<=qnET<p:Ec+M6eX/<9hwleC$hkcGeY?1
K1lhCm ath+%tVW?Si>XXi8^=VWHT<FepV^qGR@eaBiR?#ydVTSCT\Z=^L/A6y9hK?Z&n\XGFtBcKqShut^Va9K
a$S56B 1HpiL&iQe?^@!*<1LZi&FQGS*ZKD9XCWPhF#pPPLL4caqwI@HSN4k6MDEwc%5c/D?JMS@WjKT8@b8CWM
Sq<PqV k8XIJ\+$\t+4aXiQ4HhPlY+JF#RQpnRGXt+GnRaL8FS<%l&yChKC84kA^%c@Xh*@h6Iyw8l=Xtu>cHut
$?JI9K >Yl!5G&C^LFi\QVQ\u48u^$dX>w\A8cBk&T6H>H*nVSunE</D5qtMB1D!8!F^98HMI@a$TEFe<+Ep&lW
6+Q<uB a%:F4/5jnVC<@G*9LHY:t1u8GpN&YX!<dGmW9!=Nt58XRC1%btL&j4nIP>AaG?\lkJ>IBS&ZVuV8&w^c
tYXA$% jydc6yucA<aTj@E&^11W!a$6B1NiacdQQlP/C#4PA/MQwWJ^qF*K1Q*G?w45EKFb8@wVa/=F*%GjwuB$
$B\ETF F@9*#*1ND6S4pnJu1uw//nQG1DGRwHiVk>Cl+!1na\NVtQ^Mw@CT#\:9K$lhGt45nupBXLnnJ:8Z/ml&
ZH*pI& DJn=dXPmJYECK8V=muY>tyjT=LV=&Md&B$ytqKLk^<tp>ek4n%RV++c=n5wXVMQRTeiGZWP/DiF*8im1
np$<$i n=P8kt=e5FR*dY=Fw/S&y/S6dpStj6>CBZFh?YA\yAVuB^FTh*n46A=@!1$eJXwXV*JZ#qYaL4G8qkTp
TF9hub aI8aYXG9*KI4j>H^LHL6Icc6SQ&y!WESkpJBC4>q%Y6VCTMyl:DhC8wyS&kHAG6Rt5iChmj*lSIC?BQD
%?TV*# l1@!/jnua9yYmIimmD98j#4nd%6/4iLk*=&p9P=eP?JIEXMWc1M9PEDCVy^+b>4RMKReFdFmmKuClL\m
n#F<\$ /l=ub1My*KJuFk=?X!5weBdE1NF6tE9%u8n4GlVHCuAaiYl5k4QbiyWjW>C8Y*BX!\%uF*b5C&mQ^Hpj
wL\u58 Xm?j$QA6Itaj9QTiGTc5#\dKR@>mPW9m%QwXT=i>:PNQ1wZuMtJ>PL/<94NGdDpEl8#wF+p$yC5mX4Re
jESnt\ E<%LeI<IPe%*C:K^$jb=IcRdyRNd61%j>EhJn@Li^\G6%wDN?t?BJAMjmeW<P5:p!qeMPBKT1mp$51NF
^AH#GM dVlFeyDAk&a8tiknRViq9B*C%QGW*wq:Y*E!IapHNZ#?Mjej:G6:4t1ul5ty1M/JN9t5j!HiKSjjFilL
8jC&@: mGE*8jMCPSIykBFDFHT%eh?+FcqwP<nN#j<V&iQi>8X?JcF6Jp>TbI#+Hl?l6d#kcJqMl96C*lF?$B4Y
4I1JF5 ^5GCwDHQKD>!bSi4=L@+XCln6bQ+tR4^E=:w4^Vq/m94YWqA5<e:td/pD%ST1!LmM^$y:>#d#j:aC$Kn
D!G+<T 5ERbZ*py:u^5wtH>jMWl:Iwnaaa+/5+b?1IGW%Hw@&iTFEYl@/XtW%EE+niyHAG@lFR8:i#5<5idnj=+
M1G!<Z ?:?6X9T9H5S@%>H@Kn:>p/V%i\#i9/*<Ey&ww4@H+J&Dla8in+XhAk8>AA9@%%llpjN%%6>n<M:Bul?T
K\?\A! J9y:DN:9YAV!A1#IJdAZHXj$Z&QlF^$ZiRt5!AXa5W6k#:j?EIXjkqh\&AZaT@AKJu\?N?CZ+BZ5Ap:C
lmPR&b L<G4C#X+?CYIhbEGD:<E5j=$kn<Zi\qmCWQQ%<Llq!AYVPTC+%/CYFDp?ZWD?H>6d^V=9a\wI91@6DiK
$wJWG& @N98Kmwm@I>:w<l=NWdSj<!ARNq+@Qt4SBV??^Z/>:9/%=Q=!^H@iKZ6biu=q@>RhZB&@M9JYQ*=GRll
1QapFj =B>jh5kj>\ZPnQnnF<^j%8Hmdt*n@5eQIZ@=><>Lkj=9Yw1a&B>dB=IbBlH>!+w85SLaQ>bA@udZ@=Mc
N6tWh* !N<:6Q?5kan<*1$6?l<DIj=iA$GImQ*@*h4@<>*cuj>:8:YNGIdaDmBWw=GWSbdLpbTi#?mBF1meple%
+lB\R= 8!VMa:FB=uTN+@G8XGCBI5QF*q&&khqZ\#6XNI$Xl>4K6:!wcec%nlG?m^QD8?nFy8Ghi*!m=XNqhAA<
:@?Rd1 L#Qn1Zcy8RNEptiVTW#KP#?V5R@qn9V/iF:?#@Tw+nY6^cmC/!cmk<1^#dPn%#llSq/hwZRV6ISwYkt9
#cW1>Y 65VyED!Eu:EBFX<cH:1t1/*kL/*JJS*bEVhDKjl8*kwlLdLm+Dny$#weEPJ4R9YwN\/!l11>XB%9!bYu
pmF>Z5 hakiPT\%NuWSYQmM46py&*/l1meWQDMVHKi?=nMm!41Rt1Y6iHPW?<:%5SjZ8GKWS$l$JwCi/Wj^DV:b
\b44WZ tPWQDiuc^8anLXZ#61qXYw5d:ZJbnPI4wjEmtPPCn6P*1d=>XH4iT=&%h/1VA1qKG4JWT!d8DcdejYpk
XHySj? ?hTaFJw$YL!nF*5m%KwwXWT6j9SNNKD&5J8LSS><hYBDQWX:ad9^Hq==^ey>n*1$<IkCG@Xi+<T6Rw5S
+lKSJ$ PbJIaA\&iGKPehb5!N%InySBTW%Rul++uN!<?nKFdu*4MJh\:Z*L1+4%45Fa&RFI:GPM=59hbncd%BHB
P>HwR# Yh/%Yccn$IuBP/Y/p>N$=b^RLB9l^6La1/enXI6HqJ59+a:YQ^PBn5i*9+ZhGJwK/eiBeCnt*&SbahIl
=hScp5 j=^+G<XCRa*n9D!PSN5Dn!Xcc?XhbPp55ASN5$B$V?F$\IL\<:E#yQ/18naQA*8wA%qBDjBJNDe#5QKa
LJlt#D Fk<lRp&?haNZHn&aqH#<:B1cG$!8m!qYlLtDh^mX%96b+N1wajXTLZq%wqL&W$G@><Ge19dIqwVyM/uI
Z&>bWH ^J>8:A$*GnmQ!/b+/mP+tLhdcNnuhMVl^t:E#K*/Gk!b*=y$iP=X9\C/Meb1!/1HHw8?jKF?:Sw5JHdW
HE+Inb tP1yc<@uEX+D+aLN:c=5e#eN#KFChIpE#@HQ:4eSPaceCbEqBe5:bw/8P4CIPwWN@6aX/G!<%LDmhW/M
*6wRJ: ?%S\+p&NdyZ8Ja^Wa9W6whKVS&%YpCA4utp6^?HJl1TB@K^:w<I1:b+Mew&WJt?<QD:YF$JT=h$5:=Zd
MeD$Ab ly:IBkG4*MGJS=aqWmI1Rhd#bD#nmEm$KE>ZXl:qN1HuEdREN?$/bkM8JQ!<1cu@cBciuJMnIq@kB<9H
>VuNL% P6y1A%\t9WLX\@k@4lhH/q?l>ELV^EdHJGi^aeV9>dFF*W!PulFS8GcI+ypYaKWt$>Zw:1#CE/dZ4WpT
%hhFh> 4=PtX<iVu&Rq:w>#8KPwZyA/W&DhbBpmGXWMRL8y8=YVV1pZNy*!86%l=Eb+dtYXTE$Wyhd4F1t?Wl1V
1:=FTd :Zt8Lqb8D$#NbhJZ8<Q^RKERwb#Fkdt@!aw6S1Se4^L%QjZB1CmbIQKZSQH1HNW@%MR4tQ4lKWH%njA@
yQ4nY? FuEQFG1j/k$:>uEVHNlAJ8>EL?h!1*p1ZbNylX9ZjulCjD<cK<=$6+GyMIqcjPi^Wt8@/kBi8mhCy$*5
BA6:R& ynh/:SyD^6QhhtMk4RVVw6a6Ea$ea6dtikj:/p1nkH/:IPVmQh$utSLqAb1lZ:Cdm!1ML\dw*:#W#upl
68y$!H WF@kKd!46ECA:y:8*t8ali!IGtEbQ&q6Q8SR@M6WAB6Xn#>cPlDj+a68FJkKePZDeibZCkV%abGh+tuZ
kSi$CQ 6VV9dePJudc6?>6V>T\wX$p!K!wm+:J>=<?YDnWh8q&Ha$WjZcZnSeW*t&S!1S8n1mQnCV*^AE#4&+yW
P%R/kX ii@DJ:>SYt+MkHZd6MZPKt@kSlc18N8m:L#&81BLn6:eV>1F&*Q=488Qdh+RlCq?*4$@^HFt8<=@!/\C
-Aqk6e 0000b37fffb00110333 Page 148 of binaries1.zip
YwC9ul Pqdi65n+NwMH1$8^uytGPZ:e6ZYZ69YERQTY*#P?X<pEJ6t<I6ymC$$FuuQFE:#=H?^*l%>1Ea@TXZJ?
u@$5EX +E<^+TtjMu\LFJ<BdSyLY<*9:liV>Q4c%#hN4K@9eb5a?T&cQ9hSh%IR/MW+8VuZ6edP!lR%B9uY^%wF
E9bQ:H #@kM6wWQ*6S^tBc6HbCV9y6SEC5AeD=<J%<4^@W\b@IwK6mA+ZZa5hu:qb?*<?+#!BITlwEe+kI+>ACQ
iM$\Hl 6RYV>qtiEX1$mDEcNVQq=hJ1*YQcZm$qy*@QELWpY4:I==>K:I$%EQ>IhNdh1QYI^hAlyL>ihE@yEjkQ
>kpJbJ mB4pCFiijE?GwyGHPKAa$BG&JXh=\CF$StA=iZ<?h1I?MXQb$Gb/M9P=&lRd\8&X&uZn=JV<tP&!=lVn
65>8NW Wd9H:X?m%NFXKbD>Qa$8I1K!6Z9=FE9IkX!?ljFKDM*eWyq1BTREBpd/#C>uWm&<YW84MdGt5kA>CVm<
=@5HIV 9>C*HeWMnLSJM<W/kW+iMY6#J+Py?Qh:t/:TAnPD@YBeh@9wKt9lVV+tT5b%AWiAB$Mwha\:DWF@HX8*
NSkXRd b@!pMk?Ei<DL4PGJ+$wCSPKL!EMm6//lkM*JXQc!AeiReaey9acupSJiJa>%la&^yK%tFb>Dk8h1K^j$
XmAe5D DPX9Pjy94GIX*pmCW:H9MAHjYyVC/F+YY1p:=w&IZ=X4@5tiI$unP><LY8d@Vld>+kN%chna&@pj!a44
C11<Ri %e==h6+?yQ1j+=\Q^i$WBpIH&CQdF5G=GC$4V&SlV^R^SL\#pnnYP#aMKGe%5I+*IPb!6qmJhk?4iIFt
=&I$BK S?BwKZVGI$9#Q55j?$DIj!46VPGkq#a#?/LRZn!T*m5&PLqQ<Q5NI<jIkFW!S5Y*AT6XStGtLS!6LwAF
G4C=Kp +T4?NKjRH?DI^/A=bT:%RZYe=$E>^!k>bFu4#:m1V<T5BW4+\H+8A99pFJ=VldKYt1EPnQyR6$8&TTu@
^4?kh< pY^QVYXpnqDLuW@KFpLE^@m?D*cKADmJu$m4iM9hQje*6Z4+B>ENap6#?m9t?nln*id#aJjkVw:A9dk/
Pa>CP% l@ZMk4m^SjSCjlq#QquLka1ikeDZj19+m6^E$51YV\pACuM$$ScuTbj6@mj<AR/EeXYduI8:ljJy8+d<
hReik* L\1S8#G1jTBtuc1?4Gnnw1E1=b=jX=dt>16D>#CCIlwNZhEbB\tSJQ:wt4HM<hC4DDmy*e:y*#h:FnqA
m@$9w: eTTNMWX#!RCbiFKkhwn<5Z*bA@AyFnwmJ4XH+1@XF%Pq!ujGFRSdW#hAYi+N?^iaYpW1SEmPeSm*l^/D
XpQ5%6 PG!F5=i\+FQ9@imcIeE<>y^MTt/Va6hMqK<HCd?X^pN4j@R/TZNNb&dT:p:q\HMC8?ik#nJ$^eMyDp:l
&e^9tb jZX6ap=lYV<At?FHA6/IA*dL16a5h/*CdtaCnTHbDyMdHjeLQpdC%@CBJR$LlRL+qI=+/>Se^ANaul%k
m@SwG$ Q#ZL*q6YLaNPunbRWabTWcy+q/htdlQ9abtNXYRRY9^Y\cIYbbRkpYpuyZlJS+>tj=5*q\tQRAT#a6>\
MJjjqm am/9Y!Ct=:lbnuuJdT=eMDw#u4?WnQAtX*lSdp$eEW=KtLPy^6=L6+tWlIWN+JKYjayR+eQ+eMp@%yup
/$1Jl\ !C6cEB4@WcjAZ8%GlXadcSH<KnH1mBTR:b1&\j>?/S&^HCI#KC8N8Pyty&F?IwMa!S6LutcdeeIu%5qJ
/y*^*y //yQ@Li\MStSI&NcPF&P>6!tXpdW?L/qMWYKQSM^dFmdqRFl>VRiPJcZ\HWaiIWwYJ%RXY>j&b1$c8KM
GATGmy 4JaBjeSAc8/H+j<&jqP11KC9SAC$L/HaNpp5NEny15>EaVAwq$S9dulcpRTYLh8LVcIHQbWY@A+YTqee
VRd8p5 #c^$nKIk@dphZ<lEJbkXX=c:wc/>5!w&%HeaETabJVq54d+aFV=ey>XMulZPjP^L<wt!H^>ID9yALGkY
X1PS4y k*m%c=4au%PJ!6wB&mq5NQaQa8>h#Su4dSuHu8X$w5P=IlVbXF8QE:X5F8IV?C&DIL+^\F@=<6=%C@wp
*bEN:D >n>61&!KG^@IL!C#>:#4e5KlT:Qh<qc>9A%nV=Zchly/e=\Jb/>T>ERZp+jD#NknYHDB>@WPn?VmDb5K
Y%V\8c I6DJCK:B=:K&HTZ8D:FeB1YlPtuA5VkCHnmaM=+pHk9ZJk=/l!Bu#a!SV?Fe$jX@p^I*4&/6>*q#^q9^
BNT<\b #D:pnm:SHc&QBp6&1cM\T%G+wI$ZcyNZnX\aT4tj/AaDw6dB8FZZ>Y\+SRw4lPYn4Y#\kin4*we9eKc:
D=:Qhy DN%PX\5*yXj&*lb?jd8<c#4e=a?j^cGI>e@JDMAhCEDJ9D9!N9eQ6P+eWCunI?&1N!a45au>1YWiHnSa
n4P>9p %EHXa<EbZ&*D^dkb@mE:YnW&K/VQeFtRP=S>$>>//^%q58!t#%diwdt%5:C/@G1P=Ijq%*\hD/QlHpaN
nt%Q#t =C1%nT1c5!yE?Z^+u6pVW\Ce<L+R6Bl#V\qu9ZGRnSY9BwGDHXibQELYmIq4#Xy*$#ke\+FddljE\F5A
Cn6=<H EE&w+e%uXkD!m8mq<8aVL=$8ATn&5Y\w1*X1e4IN*4B^J:qtViBVF=#%5Z%e:D:@1IQI4uBjQ<%uETIh
SYT?hI mWI4hkKj^:dc9GHl8%#l&NNQd9GBd68Wh@RPB@duZYbJP\8YhuqE5J>=M\<#5QyZeD6pLDT8e\Z=DP\M
KI:RXM HNb=#yZlDQ5QCK6eH$uW?tm?hHNC@ltIG$A\N4/dnhZER\/eF9hMcFG!Y6t5N^XV<*j1>jC9A&EN>4Gi
+IPF!G V!Juipmau8R#q:nJRt81Bmal89!CyRy<JAWe91J+umPJwM>?jMC?%BKabbi49Wk!pW&m<a5kehEiFayA
ZS\=u8 ZbEMp?^6EB@G!pyZm?T&?aypaM?J%pe9^jFJ*XkCiG=$AtitIcjPGKidmBMJa!m9>1TB44byTd<!cjS^
Rb=BP# Pb$E?MV8D6k^^FGVC*m<bLQ\&M9WmhLWtRjuS?!<ut:8ud4?5GIuZ@qP9FCYi*6BRYGtiTeQ5WlL=Bu#
w%@WEi YuWjcjbCBda%5ZAAWjI%6+HG1d?=?9AY9X=PVa>EAcAHZe*w^@&t?1:<6%CMdZR%N@dlTJ#pV/tFa%8<
ei5cpl /BjGNY9M=X5qquH:IPYTR5!H&*G4>?5YK^5Zp+M1\JmTP<hEQ8TqyDZL>\ciJPZ#q<>pX:k?JeX@hw*M
84tk$j &D=m414j6XIik@TybFa*WTnkh8b@:SidnCGJn5Y*Eie/VKb:J$:&T?Ki=!ciHEi^En=yw9hHXm^Zn@GL
&B$ZQK ab#iRBGX^wTwXK6:liK\qyGtNHd*aMVRmTCQ:RbPn@pR4?i/16P?SpwXuhkh&:\VLpBVnA6P^\Nm*8Tt
#<CiRu !H4X&=^+pdt5I\CetBAI9=j69w&wnSEYaM8848>llYI9D/nWWA9b%PiebL@L6Ap1#+p\8l1VPe@ATkaQ
M$TQ/^ 6^uL6C59\jI<%4Fl4t/GpyT\J>@DtpK&M6eh+*^b+%ZX6Vkk?mY#>*%%m4yVZhSZqL\RaPa=+/HZCJAF
\j8Y?X EwAQ6Hq<D!S9QJ!eF?&8p1Fe&T&9B!uT?8N:tmly5>aW<BW$%#B1Ai^$eFACYJXlby>t!X*j4hHCcFha
CAbJPt !84MI6AnybHP9Zt8<8#a8EcJF$MJ<1ZeuCQP@c:4BbSaQD>Vbm4JuA81L9?a!jq@6P4!i<Vu:!LbSiYM
ID4TFV *!M?#<FCL<CK@t95Bi:ew4>HjQ/P9eChY@V*mM>#5Pida+n?H9H=P^b?9ntG/P<Su?iIpan#%@^:^Pe=
VK$Z=X YNkFYQm@^pJFL%k#+q>nL=V*lT>B4Q?w99+DX8T@kSY>DDuPq>tFL$E5?EZHFj89a$W8RT^l&AZa!^AL
/ld*ym ju+=R?RT^BK=/LmZIJaI=Q^T!D>b<@<y#k8ymR1KCeLEIDCaINVi^5JcWM<C/&B6+iukdCjwcHQQR@C8
Wlq%#X k/i>wIYk4I8:/^?QJJ+&k6wPh5=@@qVF=6/q/\k\aYdaH?#/5+:\b=*tZ/9*@=RE<D?*XDG^Q@aD^B@:
<$m/YC meljXu!Jqj:V4MZjd5h@Xtj+&*#Fu*WGJQL*PwQIPdMY\qAa@Q@?Ya8?@*6uLRKWPuS^e6X^e<4bak/B
1hqLE@ nK&pQylaBW\bi#u*eEh4R1enN=1>c&lIu%\wAc=%E\BN@MFZw&GQ:kPWT/FFlSDSHp^c:6wM!\BRt#Xn
LB!YT? 8h58E1G6ctnR$#*XcCR#KT9MwkRqMZ/mA1Aae$CZD!8PG<G*J=H6p\qVX^Z/Na8G#iSL!!yamdDh:DTw
V=F^np k^R%i9BEPZ=>X:%ZJJZt<!yN=XC?6WK%uq\%$/p^qlRCXjAEb6a=lKbYt$:ZT+=>w6hCXpFc9u1Zhc4t
k%6<=u KyP\a9EY+\k9aS!P?iqw%Vba!+B9#HaERYK\QqEdLc5?AB5&$6aRPBViw/yN4VphEY1QIwpZ5CKe=:D^
J1eq9W DH#P5EI%nIT81KtYK5tDqn=t9Me&QFC#qe:@TnW+F?wRAa<1@$qFtITD=6mT>mB!IV:WjcYqBY6%>K#R
KNE=mE &YaSAneX9bh%\I=\61:V%#tcP#*YQc/4Vbmb4i/Lb4j8E$cYMk1S*qMlidBZ:tEiVB!k<%*eRdjm5cY\
:LG9bb YJ<t%aR5GLhyZ%41JM>Rp@N61@bNdi*K<wtYJ#G^h>=6JLy54>*KhiaZE8Kd?:ca$BJT^9&tP%R#:XaV
IJI6QQ >m^JT>!?8q!%TGu:45udk:ul:KGc8Re94kGHNiB%kG9qN@4988&<Gn1Di4$cP9pya6aEeV@F/\\\X1iY
HNEy^q =Qe+IZ1meyJ9=dMa6janadGbED5?6RIDXu+$Dk#^4mHJGeL$NhEDbBd5/AIicI?B/W6e=^lyph!K^HI8
pLqQj4 $pnCwmG&YDn9Il=CpZl\w9td\QaHCu1P1jl5*6=k=/?+dS/\1k:mIj&?A/hcD1tFce*:JwP8L\VYXwq9
>FRp/G DBRJPadZqe5l$y>b:eqal=e<:^k!!*HLNFKb/lKpd4YWJj+yqGDSS+hjX1nVbwMcJ1WwDZ^Qqu*FWTiY
Nw^qQY Ylw1C+t%@Hk@\GcZ4&%VKp>HK!KGwkHY=V?R1$qqwcSmKe$DMMlPdQGAT4el=R5N68ehjPWTItYK>a!+
y::Ph> &FnXwwccyYHH%mp1K/N^<dy<QR*4Wa>SkSA5$YqnWaEB$iTB^XljK?5pCYAiIwyTVQqS9##^Ipk5*FCi
htFuQX $:KDw&XMI^j4yG^:uXdE&uh1IWFlLEInZWj1SSw&WLM5XW%I:lXeH/ceWqSWQ&Iju1i/e6>#uMbPQuC>
>Y1Al5 N9GqZtwI*XAmc:cPke^DR5\4l6C%#CbDpq#uyBb/pcdAXecQCY/:apLC6P=V$+j/eyWCA*t$uFWJD$m!
W14wlD @b<L55@*k+jXPAPLBiS#&cXyE4XkekYaSGDdEY<eqiJ##GPPey5B^kR%dutu@l>%Z1^9XJiehVRM!X>$
a/LH!R n=NP9eWSWmD&p+A6^KnKem8PLdSP+SE^W6QuQ:M8P&N\hY?jW**B#+?wXYc:Ah*\4ZJ/uuIu4@=::ETn
Y8eL&> yW+=<%VNq/Zw8dhyi4yD4&n&8?l%KYFBnw51>Kt4>C1D:1TkXy>b@FLSlHEZWk4Qn4RXbA/Dn$Z=aE>H
w*w+wZ X%hNkc&988C8p4cP#T8NK\M\#VwiIZ$De:h&tZBLTAQ89K9t>Z/GS\CPR*1Iw=LSdu8&bwTaC^8J<+8!
=QW\Y9 ZC\<>e$ED&YIb!/1LqL8@49BuKED98Y8aM#*#4^m!<VyJ:JY:pWMBdRGiSSFZmF>6&mkQ5&XY>@NAAY8
JaZn6J pB4dYZ6&alXRqdN8Vjw>u!H6!6ilqGb9BmiIih?Bc^1!/CXCNQYEaQ#\<ie^5/+Pn!mET*YFbkl^E&j9
C#dXK: $:A^\5F=SVyuayGaB5IYPtd^ck>CnKwlc=hI+1/K>YhB!:wVXF>pe@uH=J><\b9B\>+a*Kk=\\qetGQe
-A5\wh 000ddc384ec00110333 Page 149 of binaries1.zip
@Qb18w A#Z&lj!dqN<c?kPtSG:9MM1Wh^RIiQ9V>e1ey85?aMmFaKTBn=<p6#haiV%&<!\ym&G8Jii8XJqC=QiQ
TQJZXl m/:T?>*HPHl8MJcpHKp#=P\*da%cX%!*/#lNu%q1!iW=wZI:%8HR>/ECeGI?dmYGPSBGbDTu55jIQ1RG
cqMe^T 8u49e!!dd#MRCk6#^5HT5#e@WTTZAPP>ZtMIqe?1qILNKpVpbG/ln?DqqbD\<D4&14lc#c9B*4^*CaMR
#+G4?& tG6Q86thml1EcFNFl4%tkl+\E9ZuqXB4tjANl$e:c+q!nXlaBq1@hNN1MEy>p=#5ncip8GH\8Q?Y#=Ml
k/6\Kk W:%BP5m/w4uSK1y5XP8JdHI*&w\>1hiV4&S6u<M8a6Z$XE5<WYL#:1?&/@*BYY/?Cta=5/?HARC9^FAI
1Qw!Zt I4mTt^&#p:lq1Z6#upBIYqq+?i59Im\>pi*t5jWLiX4L+98?*@y?b8b@*nce:A>qSDSd*?:D!d1/%8FK
*=JAbG dAqkNy<6w=L%XNn@bV#6MLjQwpMeCt+*jVc8i^8@X6tMHmL<=nPaQ1%*qK/VJew@Eb:I/tD@PGL?qlyQ
8BL+>/ p\lu*tKtH#+i#++A+jPe81!I1@6>LLR\ka*%H@MmwZLq4dlj9DuwlpY9iyNh@!1p:LB?b8Ckb:NVH@ym
y>t@S# 9V<kh>Dl1\#8/=j&+etq4&4L&cVc=TlWT+@G\a8?1mY8Za\$XDl#b#G8<5JQhbPZX<AP*uyVqM<hpu<M
WHEKW= c%@JAbX4E=yBI6QMdub*PTT&V:kVGkPw&<a4#MwGiE*+WGaA/wtKND*>t4XRnhntyid\pp$W*L<S\K/P
aw/u/? $nl6pWPPB%eeB^H@Ip*>PF!HX5B11bHk<D%$Hepn:QSY\<PI4nJILphu<#kDMVl>#GXRb/d:H?tAaeC%
pKIL/a utX>pni>aZQ:=Ely6CI#Y1ce@?FmLn=14YXknD!q&EiwIHA1e1pQY@QE*^tTn*1CKwDc6%R5aiaXuiES
GRb<^m C/Sqy*8nPuIw%MtkAB=8M=DXeEcY9!!W8G#by=#*Vd\cV1bDVaa!\!44wp1F=!lS?qPqJmCpJ16\qJA@
QGNNep k^Z!AL!Jj><lR:9NXut@E6!@pKY<dG?=QpcW*dC<Zw%JAljh\F&jE9I9K:TmXQH9G^/iPAX*nWFJ5<yb
jib4CN J\S\m6EHyJGli<N>NpKw#YB%?cwK/NC^N4EKTVV#GFqjckGX5eAYw4mhDGjHll>m^5dem>:ZKt+BREMF
QJ@$mh 5SKRIyFq<kM/8WduAi6WySeMQRmWk8qhVT\C*^1CJZ&&?ywiAFJiY9edmdnGB41@m6unNcEjEmPKcAD^
%6GB8$ H5MVqy!FpCnXR141k8D1G>jD/Bt1N$Q/FMGd^4\EM9/eChj:FGnWa<6X@VZ/F$d=a=?T?^ha&=DXRC#S
RKR?#! D:MT?EPn$<GRMBKHXJlDlkLcmwcRm#lIe9lAt$$Jj+5VKM:YC+mjiLDe%ehbw^imiNk4TEAY!i%Yi$%=
aD?q+Y CXH1E$?e@lyjylh*Ph=i9IDhwMEGE!Lq/l@q^m&AXS1nkZhb%#tRu6aW%jdY<k<Y%iiLZue5E+wmdibk
:aPKC! wZPIB\l=X//1CV1Y>ZC$/C/=<E!eXkDcypLQIkdLkqYmRcW=ByS#nSND&n$$K<4mhh8=@MQ&KCYhSn:K
AuJTum &W%>ED+ZcGCwuPKl?W+Rp?I++hBijJl/k1D:5nutNTW>*jCAEudL*8$He<<$Q&eQJQ<nTJ$B86=P%MPG
1phAJI YM+YeQ55!4Y%GSiI=bSDDC4tl$BFKBc?6tFCE?q5WZy*R?@d:dqdHiSAi1K8V>A=l4KJ:Mt<V6KKRB6A
e?iP5w c#GC4y1*kQw5S+l8j>8Bw*qlB>6J@B<TS%$P:nJt<FT*RT&=EhMu65\VGEb?cPPW^@TNyEHyyJFwcJY<
@K>KXN 5+/kp?ZcMRqjDb6$\y^XpGB:lAF:p1Ym%H8bMm%9>BYG95?p#IpLI#KJ\J?R&6M1\uttL9QDCXJ6kwu!
bX+\Y/ k?SW$J^ydVXLRS^LR19tIRp#h5<MEcyRbMH1&MSc\KVaq/qp96kYa?&LTy*L!R+1aCH5p$il6A^XyId/
9Yc=LQ e!wPAT4S@H1iVqh1mqXD6aR=aw<B:MpK+u1VM!9BGnjnnWEe9N>$tq5W:C&XaKdP@1?^Y54HHXCFEYEB
IM6S%q V<5^E\p=ZhZDa8K4BkJY!yD5@W=&e?kKl:!V6<9H8nb6=KLN%GKh?#H81V^KK<IGb4&NI#qq8wH:tY+J
Lha>wC 1:W>hey^9W:4ipN!mbY8ui:/9M/iVF8lC#>uku:lQh*^id&E4i?/h\%!#nSB@GdW*k<ERPCV^PD/P\ad
9&#@e* D$T=CW$WX^$wXA\X&P=$m*5iT><pt8qQWZd4PF$+iTV8>aB#W9^bnZ5&8YhpEp1n4RC<?$1%Db9qF9@E
y96XXJ @K%<L9Y%TR8G1hCbbChil%AnP^=/:T&#PqajGIHebA\L1RdNBLY$enjRFeG&L\cTRWt#C?C4V^*EIAt6
T?SbMC yTyRNbuLC=119NGadR=i?$e&XLcKR*IhM#qlmZ1y&I$a<l#=LKElM6Hkbq$=h8*?1l>/ykCe$CR>H%k<
TtGERZ +ciqcNY>E6dPHQaad?=>FM<I>&K&kTJ8>lPNP/lca*WCy6VkGy:PHiDKuuuTdT::kyPaLdDY>SZAqL#1
6<9h\C /W\?4ZA8&KY$u&Zqlm:dl6:lhT9l!QKDwTcXVhRA\+^69Y:=&JmTtWE$9$+cn/F1BM6?M$b#Zy:A^eJy
=e1@\= =*p^nJjm&Q8nqY/RjMnJi:*!JaFbKnuH!Me&pyZ%djLXu#%P1wp>4#B>#QXRt\FP66<T9YL\^%i*WMNH
wLw+k1 u$Q8IGNw:cbQ>d8:?6C:1iKLGpNA1p#?ae1?ybFSNq\QK<=Su4F^Q9!I<JcSaqN8q?hEZc?w8c>d:W:T
EhCD9G +I#iL&eQ4l8GjmwuG/h:#91FIt%5DPD@VMVW1I<yuuduThINl?W#l$p/T!WCpCyWILGkQ+HtHT@+IiV$
\KN%Ek C@=V6SG+u:hy:aHkKQVYjj&X?!p!1Z$XJl^HjqP*KPLj?iXi>h5#+6DW9^?lA*SWnS:PtdhhHtM&d:jm
&KqDG% NIFQe44yB+^qnK&LWwcD^wZey^&&NAp@Iua^%tM@mQA>Xjw#?n+?CDkGb8%PELlIq8c1MR=QWwT$!@ht
ICA$C6 =@Eq$a#GBa\%XHhXpk!/$bc9<%Q/Q6V/BKQMCA<LID#+CPF\nPQ+\i9l<!yYX&nVGXLV#V5J=&<dFmC?
SS\YBE JcAN$=9atmum<9D=?wL8EA+G\yN+>Y4KRPYY<m1iQlP=MCh#R@a:eZ!=QFy=u^5a=X&6?BKuE\?eQS$b
Ay9@M% VBSm+GJA6:t?F@Se!i+#B5tQ#eDdN\VIVAumWDSbM+*$@14plD*=qm8Eu&J%mw+bM$K&#iw+ZDd>SNh8
QJP!aB mLkD:NpjbhSJCw6p/Y^^a=q**8WQGNq<>p=!8F5Zh98k#M/uH#b+yCD1/^6eAT6leMAV8?yBwuB\?y/Y
Q!$:lR YdPjYumVSJ!VHhK$i#%p:hcZTA8ZMa$?pVb8H!95B&Eh?FMPDm5uDCpD16*cS/>Vm^kLYmkj?=V54Vqc
$GQ$$& =tSdhNm>lmQLD$\*+8X5!?PKq8Mj%5?&p<RNkMeY:A8Ydj8:d4QYdZ%N*P:MbF6S*\:iPmk1&PpeELKG
4cLd1H ZhHVKAWnh$iYZ^QwKYF?1IM5K/dicFq4a%LL>tZh>$iJ%aaGDuCBbe6bTMMmDabcA6?Z6JHQ@Zp>Z%^N
A\Q/ee FG1M:bedA?%pBhcGV$AJmJB!RT18k%NmSY^e%MRjCMpZ^5n#+!Q1e:9jW/+1k:=iKeR*ij1^pGN@WTh=
DAQ+u@ tMmQktdudHSeB9N=8>1J>iqd+#p!Jb4ID?B^m$lGjR=ZEq4Z%/\?YpX%*+H+%5bAHq1!bVDHS<>NlRAK
benyR* <8jiEdmnP<<>tAdSX+6Td^h%<QP6mHCk*S@5#Xt$dWlwQjj95JDel=hd*liHFBLR4G4+:FqMC6GwcMVB
cVJyJ8 1p:qZ%#*:$^tp\nc1W!k++wlmTcqHK1I9GXweL?Z@wwkH*1l=nDj$hLh9S!CFY:ta%1=/6NaMlK@\FSn
P^k9a9 b\C1Z*ZM:ST*GuWGkq8F&QD#9keMeT4a6BV+6uWH6yq&i!waa:+L#:*1K4m**@YN691BMI<CwAEM#>P!
bZE!+R /hGSu^CK9I41?j1q:QlwpGtKI%yyJ14ui%pH9u1\?6K*eQZQ@9$De6ik*T%CHL=%u:ImDB/PK8!lmtTK
nE*H<B YMN5i4JC?*yCblKN5IW$ep!tBB89NAaSAq9VZDeW/<CT>?6%CGNThEVyEdJ*Z^HhdaDKHZ?Ze*6=6*b$
VbnR6Q QPHhNR<LYR?qt>4>+%>?nB$>jpa8YPc%?i!:Vly+m>n1cpPCXH>/HA*6&Njyt$HhkIi+/\N*l?:TuJZ&
/Y1MVY PYi<tNje6*#/%86F8tJ@+l&QZFlYecDT%^?W?D1R14Cb:8qb@M1?Ll$6Q<pT&uhy!^6S&Dl@C6#lH*H8
8MGX>t cc?wDEwbQbDQIki:Sbwu%dd5!1jeyhd9m%=ZC8M*519!BN$mLSA%i:414u6&Q\VlQH/NYZ5XHmyu<1bX
KFI1V& @u/tjLtqMBiQ5XP4X^A6We#ml#JI#4y@y+AjL!jtjq*=B%:QLPd%B+kqTMq^G#@DmqPB*<kTcy59KIP9
8u5IA+ ^awKyP4aJcXF:D<qIt6@j6XL=Q<:5$am@:X?inHId@*$TLHL&uL>XX@>J>Z&>@VWj%9ebiy99/iuuwP>
qucLnw aHVn>@DWe:AZnBQ>Hy:/P@cmecLj\%N@^!LE#ue^?n$<>S#5BXbVwmKZ\MI8PF@ST&AlF&CS@^wLE#&@
$ycN4D hme1hku5Bhby!E9\CucBhS4!E4!/5P/H9AT^EQD#/$LIT^ALKuaB>lLE8tkpCHpJakqD#1<bIpZ?G?h:
#5TcF+ CYLBL4AT?<jEBQVjpj>b8Wjp*<hKpDDI:?Yi@=mp<Qi^EtEa+9<jK@tjHm5S&VX!uyj++GnIX8i+QVSh
SMmCqj cCEX?Fa+q@uNhGP=Tnwm%4qYhWN8iDD>$!%B/@Cb1IDpy<^%MW8chID1?K&hq+ulcNlNkc9LZ\JWMk^j
Vi&w1F qwe9!^EFZ+Wn/EK*94w#Aw8Y4Ptk>mnWEHDuV/9?A+\&V=<thy*yJtXyJdhT8/\ed$5hcy+NESBDJ6ep
hZQD$9 bG>>PHAMj!JZLS&P=yWQpEwjd<q=w1<EwKwhYK8LThLqDd$mb>w<4lp%AH$=yXw#M=&5bmdYYLQ!&tBT
4<aFNj GBW?4??XFD+4dBHp8#qRu5J>&KLGpdtLmNp6%Jt6>:R!GAeuwh<CuaRn6&hFbJ<=#?9/w&upYRaHX6/!
kki\G1 TI&:lFD&&dqH**%X69^C1>SRSP!MQe4dNCDJV$E$N@@:9q:N%+\$9l&$i!q^IB8nPEe%+w^KyH\:5%6M
J$tPY5 qqE8JIT*TBMFVPML$>B95phDARkPJQ&LT1eB$h=:uDJW=6MF/yM&kwJlF4^%?^9Qt=9aK&aKYFV<AuXy
Z5yHJQ mt\iNMuYw8kd>MSHFta@qEPw/56%jwydi=+?T+uNiG8VB/\:5ZQAGHL1*I#=y9L<8tmFyPKiLy%H\6Nh
+SCdJM =?95APIAQbEmDe&dV=$RVy54%Pn1V#j8#*:mM@$5&km&F<XMP89VLd\+8VY1J@GKb9F+SF<yG!Aet/Dl
N@&1?d =V!DukA&8ymbjlb:1tV+tiwIR*PTEK+=ht\SI*E1L:G:L\LP1LJjQLN+it9c@SbV1j6yjXdEG8CK1*bu
E+E/Nk lYMbW\PRyWTS9uL5%?SJ^^C9FB&HhKIcKdV5Qtj@di%c\j\F^^8EAeqm?YtIiX1HNbBAjS/iXaY1dQYk
56b4jY <QM!YBl:+BhetBZeIVtSQp<!I=#B/cHWFBNq6t%wS<+%&VZFAZ4*Jl#XM*$El5K9<DT$dL\$C#m1&S#G
*ee%!+ liQXYe8n^@uSW\Bi+YtGJ&8a*bWk9qF^yN=!G>E9LeJH<+nmGmP9wlBSe/j8AFMR5dTNMn1^Mmu??TKt
-AKi<y 000cf828e5c00110333 Page 150 of binaries1.zip
14=Vt@ GlPYJ=ayw6NCYTS1$&54JEGa@y^X65/=MGKjjT4V&#Jd%JnIp/1?Y<5y6lPNeJPH9:D1mLdEc5Z#hn>q
mFXctE K9CnyciKTl#KZ/5M:^y@W6IlYluS&bnEwK9J/\jjCqB=\4E*9VISa<M<69$p=:/LLJ\HiPlj$ki:*<^S
F>d@*e P^t@biKyIpcu1@b^MG&dP$:W\h+>%*M$ui>Y#qMQ%D*%%V/V+y>R!16XTeq5ckGD<:NQ<kjyC8:Q*/%8
\D+ymn h8F\L<EYbI/p:=*c1J+PNShM<n6Q?wk?8iQ4uhHWdq@T\%^<6$q1SqNZwlB5MHwuC4dtb/qZ?!NlBLIl
KI?cZK cKmG<!C&TcWIhbjHYP5/!tYCVkJ9AJPZ$*BVtX!mSb\tYq@d*RQLa=D^&J%Eudj5ecF+uFaB48Mh*:=C
A%&VGp Fb<JQI!@P#n^Fb@GR*&iNliKKeMy<h/WDP&\YP\%FiG<6l#tZq4nP1Q=QA?1EYq=t%6wM&IJ+bIA*p+F
d5P?A@ !*&8d+wFhR9L5<4DLFP5n<X*/E8uBmwcHI4u>a<W=&ASGZ:1cyy*NEEdp>&H:l@^GLX$@tCJ6:5:&LEk
/&4SF< wnyp9aLdpe5Y1&P1t#/9!Cnljp%5WT$%m:*WctB@QLqB<@uRt$\nTi@!KBXVEcnKeG%FXa/%HwCLcwPN
u$qp8: C\hd5pMeM*W6kP>14qViA/eAjbwA+:h8uqhpp#T&1SaZ@C4K>WD^imIqqY@11?/yWZTHR!F4^te:yFnL
Mtqcp^ /EBZ%8Qb#=PG^tJcmQDw&6SRYNjekSb^\EI\t:pYNb+YCShQjBT4&EP#V#>a+aBFZa+/!%%tZ1n+u6M?
kwndWw :^eM5aNjq/bc^#LR5QtMb<1um=l:R#weEhTt/e6qd$eILYNZN#l+=pwJ%16Ah&BTXkKSjNhCSF<\N^uY
+B@:GF I1$y1SbY/18Tuw/@#\!6i&eK%#jVd>W^=p8GA6EDqZQ?F1SN^LGwjeQuMFjj<k<yidh5h+bI/^=4:nyZ
X>>haX !I1*N1qH^Y5llQm44/+?nihGA55?SF/h?NwD4W/DI%KJGY:t=E?9BJuWid*HuT@QLYR4HBpmu>h&9@?e
jP*D1F b!J4e9nlNM@T8Qdn^WVVMHbS:yeS!5?8N1IDdQNM>cc\XAjVA+@ul$dwKIy$+&*BLJumiT1WZmZm8qMD
aaD&#i 4k\Ma>pyX:<Gqn$uw<=11WSN^\Vb^!+6%@#RjpEXGN^I8H1\56H:dEGPbX#%LuH?$Iua!B^QJ?cuD%MI
yYW>*# +h%aEDnm>AYQyYjTk=tRB=y8D/n6\4n6p%Z$\5!#+d#>%GYJ\n8?BLFFBCpW&eQibt??p!++=Jl?ZkN1
S>y?aI 9XhkBA5>QSAn<:IV?@wMtR6j!BcJYEEHCAu9=@4X5W&$44m#Ll>5tV&aGQCI/KYc95QEuqVM4j?E6%ia
c9=d#Q V&pad&L6RjKV=+hy>mJ!WdJ:AkVHeWEKHkVc=c!Q=FJ?56IbB:u%ej9d5jHJP5>=cM/ZK+\GjlK^8cZc
#5jbWA ZlcuF@CK4^WR8/BdW4euIb<^&&cQDRwa9A@Y>NJnK!puC>MJE51Mpb+cJ:^1/d^h6ySX1LAjqwRT!H8R
@K4a>j T^#M<WS9B$W5>tFG+IXenhe+bp&iiNJBwqY\bY6Y&9l=a9e6lkL5etGFSBXmi>cFcqcD!ZnqXK#N#9CX
>KVmPc ^ud*w+KEt?w:pR&^W=d^i>I%TPXa^iGu*^<Chh4unN=</hmijQP+^JYlqJH/qFSn:E54\@y%>AE:M1L:
lqC#?M J<&4>/GDXKhdi=9qa<p>py@Dcu+TJZw6LWTG4*<c*jemcL%uB:5Vlq!NjGM/^1#QM%NQ*Qy\&N&=^NP+
hkTBHL <NYX<CF9Ba#BEqbEVT<$4LtWmDRJI8mh/?uKbT4M&:jTWTK?c?nHy&NeySe^NQR1Fneh4imhY!KcD^MP
IN*q=j \/:&t9w1?uTlbi\J$p9dD4i5&:a18TW*ywIL*\l69CeJuyBbpuwR69X\W?5SF>%PaMtnZN=H1+i:#FFZ
F\VmDi RKuwWQAXjlRbj+6+j#tyXMjNWPDZ*qB4>QhT@\/RC^9^J<:&wLQDQ5uDWhlDihjkQuTIl5^6i&M4EK@E
nMVkj6 11t\5#FtJbLWjDGN!@NQ+*tk@I@PHlF=**D:BGwm/%8hFTL=i1SatMc/QecJ*ZcNMHPa<&=iBVym4>>1
RtV\!@ pGwNw@i^wtM+Nt<Z<#\l51QZ6RCCt5u8yW8Iw+*!SQndDwQb5h#*/P!D!:wHTk6\HQI6MZ&KH?KqW1*1
#$!>c& N98M<:KZAuMV48=ChGQDudM:K5QX5WR!LlGp=48R^6#IA?m9/^#M^t1R?dDGd&B9jYWh<^DCGb=FAKG%
4G=6<K ZqDn+m:EhL8=XAHP*GXh1:^pK@6tk6$/nGL5SX:NhPkYRn:=/@nHc*n9&KJk9!kyeEhPc\FXi4G+8e:C
\<H!@8 8N5#CTGEe\PMuBPKCw/j8B#udFaMVWtn+W8DLQLTLAP6Ci9S@uHq*EFSSDA>iVu*?X\:>8DG?9LQ%=ZL
^lZhD$ d9dk&QCG9\yh816%<@yE\#!jE+ekqZFN&W*\B*/Zet=mV4&%tWp<ub1>AJcTip:*95\\=1Tcl\wJX6hJ
=Gmd6p >yTJQaRTht?RtAqS<w:pc=LuQmNjy5CJwaK4V$\:XNq\6ZyY&N\w*V6RJ@#GFRdN?#p*1nN$JFNB8H1Q
*W$8w/ L^%bT5G:p4tuy8##/TZVXwu+Gm#Y1Y&/Dj&VEueTb&/P@IDb!uD=5P5?IYctt>k+i!+k@$\i455kcByq
Bt9dM? M\AY/QEBt^bX9EYw*&IhdliFQ$N18+lejaG+t1++QyjuwIXcJ*RHYIJYGkjkp1KXT/$Rl8@EWZRk9eGi
w8Ji9Q JZRpFF1b1yCIB%WeY%t:R/>IjaPkcK=jZLSMjXJi5bymRH\R6*TwZTJw\HS:uE#LjwTKXBe9q+a#<N/W
/wn!GB wBuPIC5y=Lnd@tq9@Y&PFBV@QiyntTlb<@h4SNiP&WW=#Y:*y$uuy>^cS?aXnCXFWN:naVJbY:awPHc!
kladpe d*n4SP1*C%9wn#SZp4+6@#DGQ4Np&>Ch\FtwKA+9hMnPTa@NTnY&IDSTLWbNc14djNE&lLBP>VcBGu8F
Zy<nN8 ZLe!N+Y!w+:qeXq5WdZGd4N>Bj1H@Ypm!WM@Zp<Cu5myeZju8kXVNpMZ+QET5\YnuCaP1l&8@WGJ+BGK
4NIwIA WqJ<*d+V9QQY+bjpMic6+%lnebp!/TQ%9H9ekyJVHq<#p&XymF<#h1MLHH&e=bcnP*&HXjNTS*SYVuRX
%\BcHR k*RpcqmIyPL9&n&e6n@PVtE6=hAW>ZL&HAyNKE<ZQ#wX=e4V+*?J$1Cc:X++&JEe$LW\$L&4/!!w^^c4
<dj<l! T+%C1NW5uIm@$=DQK<Dq4T*=JlTH^PnpD#V+puu1Kh5CE%yKB/t?plt&qISQWI#JK+j&L*icW*@@H1qJ
B$G8V9 FNq86l9>Mu5BhPR>c^$yZn<$6*jdwnK\#KyZcd^cc5D:C/>i1W6&lb=PFXqF1S:kBqtS##dX4$>>*%H*
?%6tYR >NpGj4peSw>ZiXPtckH5*Xj>9Vae<iNi*8B%%4W#A=Abm%b?E1:E9%iY&mXQSA%Cje9JWuG%NmQ*ZeN>
5wlZl+ aDPyuqI/iKYiYdp\AEk#S%4FBdRQ8LK&D&ci^!W8iaI*m>%@/qSn@G!jYZ>4\L61nb#V@$BP+l+B^45l
Y6:^e/ S/Kl$FXB5C\?RDu%uVMmCkenA#<FYMR+&knwp</aLtlwYDVIY5^\P/G>X:dG#Hy$9nRwjqM\L!4MdF*9
L>tX^b /Pm5AJ^!ARlTjWtwRJ?!9&<<6edW%e9Fl@P>9EiYX%bTMu=K+S$Gc&+I5!Q:/y:!T$^R5lyhb8q+CthX
=?S!i1 ln6S=nq?:<lPuLJc%I&Q@*S+QK@+>Lc1pGPl84DchZWTX:@kdCPXKCclQ1&\8q^PW=@<e4bhW+%DhdV@
:VwI?Z mPpJ5a@AC>IBPHhM1?mLn@aV5YLpP!N!k/L&N^+Xa:&%!&*m*cQHW\L5tBHq$TIc%@*<q&=&?kWy9*bY
b=QnX: ZVBu1/ktq\!hQjS$QB\4+B<uwJZp9M&V9$>/heMp6!6nw8lX19>hC4TieK5=jJcYw9wl+J%y5q%pjjTK
RnSlhC <K\S>V!iC1:*mbb#@Y8F&bZIqXj!!Z\/Zuj\K6@1+:t@ep!jTDqN%^*#B6TBEA?@XTW*kkZ%BIKh/>Pm
CK!\+k :B:yGm^WEL%mX4<h:1Wd/\F=^/=l+ltpTQAwHKDJQb!wNGq$E>>/8K+Yp==mPbKbAGdW%=&X%#YJV?S@
cta+Jm qXKu&KMWFWIhjW#qe=ImBXhIdm\C\Xy:R/p/%^Z%uQwb4>=@e@a4hR%VK4wR=TtlSbF#=9#i=I^HRP8G
<@iCLG /SDX%yAF!eceGu*SR*+cA9\%WJ<PhG\CByubGYL1CFau6M*q4!ji$=MWH^=tBBBPY&YA&WKL6181MKT@
P8Y6j> DHwcMWQI!p%49Gut5QTEHSMTdttK9FGKHb1mN8Qk9a+R%:thLbW:1=EIA=FZMiul%8GnMk@TmMYw::A8
?b9uVE l?/pnC!/W954=$aKu%njGyIyFuy+5C8F:Y:QT+mjPBMNCNu$KRli%QRXdna&ItBJM/AyEQdZm:VDYuXN
Pe+epn kTMXplY@pM#uW=!\^mQJFGpLqFL+X!L^%:Yyq^?klF98:68YhW8aJ$eD/S=+VEWpALeVNDV8=KY*nRtq
P=n=%# G&Sc$\%$Yi8Iu?VHp>:&y1m^y9n\aQ1%:y&a!Q4E8^8\cd/=!j=ZCTedCKim?*TSE^WA>NRnE@MQpejR
ZBpDeY GIC<68G!liAlACjyteG9lGpNZeMNiePN!LC8%1XGkFn&lSEbw9?akjq@XJj@^$nN<*S=JA#?t!/QlMH?
Ftn4?I YbhH\1CZ%PZ@JwV>p:#&i#:u9!*8H*Z=<*X1Mjkq5BjMZIklLwG>aMbEVQkTYQkFYJFLaC>w=@<>Y8S*
jH%Yp4 4QAF<#m@S+8ek^Y=AC6&Ci#=M#ZI*/NF#5HCL5BC@#Z&klwGEuIJZmHP=\aTekqiZSDPm+SekqeI?AZa
P*PmVk T@AKeV+*pJBL<A1P9PA/Z+JZeJEL5JjkFj\mdq!CX@AL8AG>BK@k==eTpNBL<Ay&9t$hEuwJZ5FEL5Bi
Y\E9u& kqi\C:kB9RT9aNAL5Jjk%WX%JmV$E5RTQ6<?Dkt>BLER=%9AIcGZISd$@C<@>BLEE4uk8Q@wP+u?P@I@
1Gw9XV 1@j<dcVu#*4QPXE1!Q@wS@u*$Giw&Q@%WTw?:iH@F$iyXNZl^IY!9F#cCC*G6JX$KB?m/QNXGAaclTt5
c<FS<C ZctkyM!chIDTFYc/!1D$kTFiC9JlDul$CJ+patk%kC?G=EmAE\^m@eLbc!HH%CwEQ<FyBWGFCctW!\a*
kY^nnk 1SDX%LIM%Y:pE!JC$yp&?n$iJGwWIP$FL>$//q8k<cpQp<b#uM8\j=<6IlBtK#4DF9D5WdGB?hR/Z59I
qEX\QQ i4#pjXW8eF#B&m>hlScJ=n9?aTk*ncP6Z8%Y49Y1S*hd:J4i=JTNLEBWY+FYiThaVq9=JP?HZ!lYkFc?
PeDYac Snq\Xq%S<&TY#pTZQ+X9<eli<+Fb8!!\TKlG^@E1wQbI^e5c!:%Pc*DEGn&Wy^!a\$8ahyYjaiF=@1nu
IpY^pJ 8:9P1qTtJP@YjAGmhS4*R$VjPhIncH@1Wbp:LqTGVe+?IRpQnVJ=q%R?Z5GVPD4HbFQ<AiT5CNq<Ztdt
Z^<SDK Q@$pmEI>%84lbINi8Vw$Q6bw:u*1uym6RL11/+^>RmQQ8n6AZRZH^dY#4PC8i?mR\NnKP#eh8?V6IjXI
LTITWR ^6w$1%5/Rl1tpm<WwDybL&!GSXcTq%VGZMK<1E:blDY&9cdJd>WF\WceZ*q4eqVjZ+?al!eV?NGEm4<=
:dajMj YVlqGIV#nXP?96ePb/tjbwcL<he!>NdqBZ*W?tqFe9&d1L:L:Pjeb?M15X1yZMQ*Jjj6GGwwY>H$qbpe
#+A^Yn <dl^l#le\Yj9WuK>M:V9*ABYDCZk+T@=pJeAbIEjikwXtP?p!h!#IZcT4LR&L^=uDSKK#m:mqXM%a!lC
-AcB!* 000e36cfc9a00110333 Page 151 of binaries1.zip
#?nlyB CEYP</ZZm%j1?NmwSA*@+K4V?tCPP<BqjYJd#yFht=yJlA>8bClQ9^+<^p59++1wb8pacy#@\C@bqkP1
SGW^LR 8m8jbP4a15Gn$^GG:\9TVHmwtb@9JTNZeb!tFcY4*NaaGK#cuNbe16kZp9m+d*Gc\hnLY9EyBRHP\DNX
DlYc%R uu5&9Q$F/dPR4>jiHIYRXqHhZ4hYHwqaAWc@/&+eM*<\Yb5RTay8^j>5\^nqXt^KJPCZ!Z&/GPYld5Qy
kPA=PN ^9u!e$9mm9a4bTYBSj1iE9Dkc4YJ>K9\Wm>!hQI^Bmn%aY1kTYyAVhE14TIlPXe@&a/C^R&/u#AywT68
@\VuPJ uXAmul+unYn6FBNlG1yI6V@+QQ^a?@wXl<!EERdFb\/R=aE#CJiYLXeV#PD?SNi/B%DbPS&&ul8X:9#H
=!R@dd A*%PpG&t$i4XX>p&y+HN=FyV%@kLqV?%MFRWYWCqp&46p\Yntp?tGCu\1uWXI$PKI9t8#!94p>dWL+bG
XFhWK4 #FI!*SS^W@*w48FBVDYp/AA/J8^1DX!QM9Y\m@QQEcd66qN$pIIB5XR9PL^bu*KS9CwGtniNdlyc!w1L
!QY8eK A+5Pa5cZ$NhJ*GGb^cdBFTWB!mSQ4VCl^AZ=u*Ma1Smu!85hKDkGB5\5j?nDQL@\lYdk@E!YW@GXG:ER
w:4Yen utR\ulyk4Wn^jXqEjN65Yp/^tCTcHkEuICZ#S^m8!TWuH+dit&<*!aIK*^!&$n1mSZ61<>mEM>DL5n^t
Y+j<Bi La=C6PJ$NlI?Dti\N\#hw/dCi$A^>u\qWG/QR%44>m%KGYYlkLZQDHyK#AuFD$&$/ma456>pD\EtuPRL
GGK/kk @HtIZuwHiaw?Y9%k$+d$4S$RH?iF5GCi!qW>FeSZM81KeDYPEKXKdBdqmE6W/u%y^ecE++t^YXMjFE8$
TC&A1S wG+?WqVL4$^*8Bj+lM*<ejb#14^t$/EN^+k/KH?XBnJ#6dm5C@JeiGMiZ:Y5hC&wiE1m6RPF61Ad#K1k
4i9lQ& 46>Vi=NA4KQqX\NCMVJp$Ec5&>D4S?!IV&MNI:bP=jMGT*1=etHS$VK\@kbbNy%wIZd/51RCh+!jJdNt
AmSk$/ ^QW>V59&R11XFwMIh^piZaP8@6AlP&XyiiEWuRnWe6HC8KGi+\n<GW#94h=\XRFHiaQWiD4cMP8nLXSu
ke?mm* 5<FmuM6MZqYAPVyhK/RPdj?V#?tcTpBY!HLGD!Nbd@tGALyjd!$FuJq99YSdG5a9&@d*ecbac+^HX:a:
^+$^Lj ^y5+y%5%>aYLFaZw>cSI<CSkM68BE4bX/VZ6mmEF89VYn^=VDSTCQ$^@u5y:VJn4kcNh=V#u+K&e@+Gh
@+qA55 N<:6hI&*4ahB^?T>1hhL<d\*T5FW\tp64l>6GhMD!GbThpShDqujA%=R$u#<!NQYL@:l&^=a>a&I1Y?%
MnjqkB l5^tRiGXtmiP<kWdqE>?NAbqJPqm:5SJZ851WFt\Cm:ijNYKu=^&^l4wmI/Xp!DXY%CbL$a6BHe!pKy\
BB8Z?G m?Z^Y<$mGVJTDb<dbbS8lPal?*J95%bES\/AMh%Cp9^6R<89MJQR8<h=6nwWTR9R:!*>Z1&ElteH>%jJ
SCVBJ< lhI>y5:5##kKR=<G*A8!uEp^SMVa\15T%HhieGR?PB&5$Gtti%L58ik*Y!#ej>!119hyYAZQSGP\Qc>:
Q6d4RR !ZDKQe&*Tb\@mWDb\uTN*8>h$P$k>>tM\t<X+MPFn5?jSa#iC@<eZ@<&tW:R?@EYh1E@>8N:uh:CucTN
<S5X!D cJ@<%=nNw&/pD>9PeEmL&Ni$&cZHn#\KKPWjY>T@dujI$*#^+=R@XFm5t=*@b@HNi>LjDA11Re6:Zw%M
FI11C$ p!$?Ni?H4#k/Q:La!WmlmZ+&M1m4&Nih418YhT@uXR/kVP\un=TNS5%5F?cZc8DDFhAd4u%#QNkH@:%j
?JIQj1 9S$:KHW4wRpuNQMI&jLhVyI4I?4Kiaj=T$WA&dcARctqwYc:Ec4Zhwj*h*45dc9cC*yAQDpcQcD$4iTT
C6KdS@ Xa\n98@H\mqE:<kd4nLqkjD+I8PWIKc*FR&>EBy+!Nc9hcSiLnFI1K\DYDCdT\lhd^Se>&@QZ5jcWq@l
YSC$wY #NECmGPe=KjK6@^#a1i=k:iZA&X\!\LBqnK:64i+GQG6>+n6$kZM8$4mhhJH9Z<P*Q@P?+c$b/qWISQP
e4%KNk y=:5?6CG!#CMyG>1iCh5eCIejM!&b<t#!jS?8a=:eANjWdCLLB?@LXR#SAJe<JuIh5K1JLl=mNqi9eTW
jGmkZH y=NwL:PQW<IJa96k?/5%+C\HtPeMLJHiD/\9LMVnM!PyHM45u8wwZ=R9&*<bKpC<e/1=9t=bXCdwqpC:
l8J/Ih L8NW5Fk&hIiB!#*NF5hXZkq9VGw\YycKAkW?WHTtWC&6Sn8#4qG9WLXZX*q\jL^YdY<=ZNLuqAEe$PpP
qi9Ppi \<G+?ida<l@!jVYI<Cbhu/V#j$@wMLbq8/Zy6pn19\iCN6FC5+y/\kmaNRq/c4\\*eRXcJRYE8NkCMtL
Q#B5VM X5I!PQF%1WdBcm*%JQHWCjmp5kkbppCTwG/tJ?8HAA4<EbK/b=E/#:yQ+WSVZ%VEc?WbBwuaE?NqG6YQ
+c?&S4 8#kZIpMVjhb$uLud!98dC:5\WMKiDm9eV*9*5h\L&YCIB5eXe5wTH!heZaZE?jC/u=ShY6qhw&YeKCL5
a:V4$5 \Ady*tltc:VEX$=j>/:pCXlZW?>/@EcYS5&TZ:=1jQBle&SDJmjMyB?qq+iJq+hblA>+F^+^1^:4q$A?
tm=ue? BWubJBG^FP>4&8BdCk=b8#/EqLT>>yCB18:Lq?4ydB4@SCi9H8pW@@EWJ4TnTtIP\DFAnLB:kHQi4YnD
XkkQmn $QajCPC<K:VI%STaI\R\EX?dcF/:$&B$IB+9M+Pw/VkLQkZ^%5B^9!C=C1FC1$LPDb1d4RIi66l%Xnn1
YPk1t6 =*mRqpdBi@1R/<<tG&bH=nVZ+ETcYAF*:wW<#?!SC8XQ$qKE>mqH5LXSH$ke5+dDGWwNmS4Hpbe/AiIu
AYcY+& i>RPJX>%>m5lStq9!wZaa+?PjbZe9/Aq/^RbTeNaRT/5paPutBLtEjBCA#+1j<Z&jQpT?a@G?Q@VCd@I
d:Mb48 j@VY@*jJ$8PQX!wP%l:@+TEQCj8*+!IS@@bSTNF@i!bD@nWXW?!9W1VaZ=@X^Q:c4!j&%@iB^eVE@t:D
dPGm?S Li9m>eeJ@dH19$8n5L>%AQ:D<lD@JWZ%>%RF=Q>c1kL!4/pK!H>KXWCit/1A@D$y+G<Z/#?tE=<98j!i
nLPYX\ FHAP>kKb/QipkHP\EPn=YPT@^kwnL<CKZRJ:j85&<9ipkHP\$A8\$H?N9TCSAjq:W5A=&A9p^>?VA5:B
*E+j:m ZmA^@S+W<D5YLu4B?X/CX@D#:b/R<E9\/pJ=Cm:/*\FjkqpZSCMk+bhkq5kF?6R=@9%CctKCawJ\8CkC
ValPaA Jml4d?H1ciM8KQ9H@95Z5^6yc&5HV\eZb\85IM4G!9&i/=<9@nT=<dm5!\$eCYGG@dG>@eYRB+u+%#a*
*A8y!h !HPM@j<*4@FQJ^+S!F@e8j=e/mYY?E?P@*?:Aj?JXQj*h8\@yV1S*=%+pPe=@5QF@tD8@>?c@V@6?G?S
=%XZ?n >Q?T+*>#?/C=JWNiRMaQ51EnXj/P9C6qa@Thquumld#pV>l@5FBRbyim&4Rqn%w1ZM*ZTIP+i#+JQyh6
%Dttmk yA5X%Jbj46j\<F$L1iAiyu=SZk=dn>p6b=VXHCH9EJNRa<a5nl@H<KtBX?LjRPyJVSmtXepN@>aIVu*$
^=/e8E %$b\CcJN<?:mBn#8\XB!J##yTeJ>>Mt4C5YJea+Q1J!Tq9KycFGXetd5hy>ijhjMyPiQ^5QwqjKbZRLK
M5D!9! FZ*b6^>KB:ujhEyy!:+yV//mcX/^GcA*@mDX4SSC5%\1P#p1CN^?PR6k&ypwKXXhFhHyERl@<@qy#iGH
W@!p^\ >uI!%4q$S@uDYLcm!YVhIA@V#^J%X6aIW=@!a!y4?lAPS:91qD6*X?=1Q*5tTbd!lI?4hBiHFdY4>tb=
S/YAmi TVSd<:4!LMt#J=4V6VdSweQPnS8tL>LjQSR^:K:dY$qjKJ8*V=ip9ApR61y%A$1@>B&Z>>P4b\P#YjW5
TMHteF j4n4/Ti:GcNLq4DXPTJh+e#m/V5VBa&*W*Lc/*#u8*6Fc4\p6lHi/!t9qm1hI@/mcLI+lF4>TLd^e@pQ
yle%SM Ze9nPP%SkHAjFT>A%Tq%8LcPbtE@SJB:Cjd&dB11Jn/e%PSd4:a=9QbTY:Jma!bY%tnnmCyjdL895!^u
SlZJq9 idq^l4bSjKH%nM1ZSjdNVNNm9Vb>LCtVLY#y\#NB!I@GY*y8Caqlb5Q#9p@%!*dtyG5i>6RhTNnFi<W+
ZEB4T@ GkkZjPS1u6J#NL9Ji&9E=KB1>p&*hP=dkJD$y#c4!KYMRX+L+P4G#WKjV$p*&%Bd:FSB\1#Z/a$a$Z6K
9R*6=H :#llP:cVMH5CwtJ##4uRJ@$DZ+Yp?yJaPlt5J5h%NWJ%B19C4jeD+&%55eyMnS\M^iNdJ!1F?GJF*c#j
ZcnnJZ %X@mTbRICF#Zlh\#/Lj#IEn^DtK&jTZL>%CW>=b5S?D>ij$9\!DuweQiN9R:!8y8lM1Hld1<Lw1WBTp&
5bw4KE XQ\\!$t\%A!9K:@NS*H?Lwuc8Dhnll4+w<E$>@6%dl1D\SR%$kYH:adMh1b8b\^m*w%@4AjqY1+=<ey4
?lnaK& Y*Dt<Fb<WjuyNc9FVWw?Rm$B!q6C\6j4*!54KE:W>\D>J%uyXXAtuH$*5wSJKaiDGc#nHLIadWk^h^=L
?5llcE bny/&#=6@A/P?hn5P@VqdX9\@ZiMC&KK/KdF=/9!IA4?QACbPqNQ1M:#>c=BAD@G8yBV$EZ9VFS<Z%Q@
^\MIDZ 81lkK5MbV!^l*%KdXTZi#NdHiIL:8^\&4N6SdPA\Wt5pu=$a1Z$*l^bqI\NWN9/X\RtqjeXAnQK!#Iq/
#N$uQm $$IP?iytlZW!TL@M1*CQ/CZn:M=YBpWFAKE/DVh$kin1SB9XhWG%=n^a%@pi8b<RX$*#^kATha&i&&Ei
6=5^MX !kK8TPZm\N\e9#l!j^bmbhi>bZR<#jdmeYSK=58j>*ybBnQ!!>:hiPW4VENbLHiG/SutGdR?Fm!HSJw/
QYXB*^ PNdnPXh>jDPu>%be88REcb5!u=lWd^!4bYBc<Ey?FQNWb8TX=\PT>Qq4StnGHRR^R5jJpiptu^uyuj^m
XSNa@1 ni#D*EG$p\a@h<Fh@M?baSRcVk96/I>mZEP&8t/!+MhSI/dZFbj#HCnw:RT8cBby4KX^n!Q9NQIV$R9h
Ac=8$T TTIi^VwL8=nt1S5YSYi^=KtuYD^b&IC$=S\tQJy/R^^/Njj/6Y9^4&5+M:n9F94dlk!&&q*@Y9Lt=$tl
nBYSZa &neRlGHe\6H6WXC/iEJ^/Kipn8h118@YaE6h\\IRVc<4^du5/5d5X4^j:%tn6tQHXA?!6B&F&Bww1y^6
?:byB? <cS/8c!bZuq1CXq@bpK9$&qRqFjc$ZKIldC/da*ImPuSK::BC#^\KbCwenT<Dc?@n1%=ZGDXN4be%iKb
kKwIPt Ei9QM@mJETIDLJa%y?nV+6QD5ep<K>l1pEbw*NM%=KXN%E!=$YX6RI5uF&?daSFJICDSp&I$6y@>uL98
%i8KVN NPT#9b?X#D!eq4hE4quBd6w6INPlkiTV:KbN<=enK:BI*nhh>ZJS#PchjIVl8B?%h8XhdSLX<Vh=cbbP
i?dGC% DyEYARLhe=*$DtYaF?a=J\pM9D<$tCmh%D/PRBX+*/J#jb9W6k\iWktGCGI@F@H\Q<y<cd8Wmi/^L\4^
4/H+h: K:Nn*1=Ph&4in:u/:6PDd&bjHK%$ayeXN<!e4J5LwW+mQ^ayG?tu6nb@j5B9?QAh:yIlhwTiG@NeKnTj
X><A5T !by*c1cemHqZ@!PK:^4Nk&QuPI:8S$wPKpMkwY8+yFitp^ub#Fw&=:8jM5<66!9RSChHLC=IjLZu5Nqc
+&ht:9 mlQk%wK\!B=LLS*MDWZd*L\mtjInLA<19D#Q%P1j<!ChSIu!lQDiqqk4kPFN<m%wTh%6>Z#uDKjmh=Kt
-AkPDc 00020efca7400110333 Page 152 of binaries1.zip
Dtt*Y9 #>jV^I4+aGw9\d5Wi<MnQ<EN<:INm:Ej?GVa@C^9cK/a%96?uiwSVIub9d/dHBDY5L&Ycpb6q6&QPn^S
KNjKF4 88$DqSVw%9+i6%Q*LNwQREwaGwi=^=DDIM6GGtLH6NkYMi9+<Yq?pJH%>H/c\AhSZw*M8>Q%V5+L8dtH
!iqW^+ eMMKW@EuRcYT$m+6t<P$Rje>Gy@Qnd\%+n\Y$iBTM8j6LnBKAW%+kM1QcF@6cG<jhj&+Y9?FL/uE/NNH
bktc84 68WBt!9a>\&c\=N9K/$W^bnu96nNkV:%9BP/@=*M$%nPiZY9dE&N%YGpwh5yPX615R=dqJcLptQLILXn
+@ilK& Q!RRhC@AiReER8XIG$hAVSZS+u5Th$qW\W8Lm9IIw<n+5iGSR*KbuFLXJnuTl=cw!6KF6=Z?R%aXW/Xb
6#jAHq t+PwbXh4>kIh$Z^d#ZZmX?WnXuJ9kVa6d<qVJ<5dXkWZI&Inm<u\<<Jdey^JTX*NK+Z/lHIumY*mQSVK
^mlj%+ RXWXmwYKXqIG1=8tpSE@kb5X<I$peL^PAI=#d^#^//C?B#$TIqK4&y%J=PWVYX\DlYM!mCAda49$>8C/
4kR%ZJ qh\iG:WiSJB9e:BPWNBhjClIBMBcqF<PXE?WL>ctGupV+1n<nSD*+IDj8D>QHn9k99It^I%KK=>lSctV
?9b*1= 5wD1NjtbW^@9/nnCcG#hiB^H*w&DVtH<K8jl%/J$$RLdm6\5$uEhjcJ4yQub&+ZBQq8kXR:Bpw*9laV8
*wIkwe 5iW@d@cHETYakmwq=6BMe$Qwq4D:eMml@Pb!+FBGpG!pp:19GFEaJYppX<<pHcC^j=DPLK=pF4?5ILS4
%9&\CV p$DCYM$+6y6Xi?BRi^%hM1nGC4l&@hQ/Jw#Jc8Act>SCQq+p&Lw8ML<9eKhMC#1$iWk5QIF+8np#wyTZ
epcVwt @/qLlMKJM^GX\h^q$Tj#ZSB*n:nbI1SpIb?HVe6WyhD#=h+hZI4X6W@KFSTtbpLb?%8?y&T?u:GC8<W%
d!=G>\ !&&ciEW:E6tJ4jbd\P%D>*$A996D<>&SA68&:6W5PSXjlW1M9Kd6e=I*KY&a4%Y$N!DEb#X:Z<mwXPKJ
8!w#Xi j<RX@h^A9B5W$a#5^XFeHwq:l!NZXeJqdFC=6Xk6cL/L$B:Nc/*C@*JaL^BpK#ccQiX!HXFhyR16i:bu
b<ZnS$ mXyc?wnu:6<:Vdh:*!5j55AFuK\!+881$wKdQ?1i8^u4@18nJCDJBiFP^nhtuWG+&V\p!nJyjSQA1m!W
4!FFc! *cacl#\aK8L%FXdwF>N8hP4bcbZZ&8L>Gqh#JEKc@K8*ZM^tw9:V\pQaPF@dEXJhEj%^aqJ1+ApJWKKw
iC=M*# J&mw#amZ14^$KJVjYEKPwbq*?eX?%\<T$/a%atE4bhIw/<JP/<A+X6Iwue4KSwZeTJZe^Gd8kdj1E<HP
6=w91W d>1T/kEF5Ejd<4iaF+8Kh5T*E$k1jy:$EDaj61:8KLi\18AKKX*QL91FCyVD>Q!$E+Iu+TFCF?w/=$1+
1MF\R= bK?weH/LSP5tZXEeA!lhyaj6KbaMHm>m4<qR1PeqVqnEHnAJ6T5BdS?=thF11+59Hi>:QqYCM*#?XM56
ALFGi/ NQQ=mESSG^iWlAInK5Ae&J^1/&<V8JZB#V@1:G$R<d1ITJEJmRLQH?w/4t8&GSPiQuD!@i/&GXD&wStC
\imcl9 %!I+q*NW<BeB:GdCX?&NHi9RXY?!S#1lpSKXYGRqdAjI<JB@4Gee1bB4w!$5$nQS>4!6wCcW\cLNGd*Z
CLu1yk I%^E96T:&Y4X$w/u?I:4J:CHu6R>XYmb?LaXFZSam%ptu&hHd&JF56ujh5eq>mE@ia+n4eDk>\$dWkXm
SI#9=6 P>uPC8N<lw=B?V/Q8^\W@wHl/18jjlulQ4y!\tMWLM?Z5HZmTXy4*4QmCYd%wCWccyC#ae*EL^8Z>dQk
i$\G8Z CdSTKRKt5M18eE5XaR%!j9G5TG1:I9TGJ&Lq1\XIST^GGL^4IS+ewp!ShCilFY@a%C!mJi5t&5dd$D5i
1K=be/ EqX>ala^:iBnFm=i^R1Bqq1=4TX$^*9wQt@N6mm&Ru#M@9*WPEC6H^C#@uPEq1G*XXVBe\jH^CwHaDbm
EKtNq% \8m&BbL1PPn81y&\e>RGYnmpF8><LVAjABY$8i>6FlA#?I^5Z!MtLY9+Zya/!!!mX$c5b$?E8%eyJpc5
$1>ln6 YlDyBP?$IN4K&IP&qikPqY#%^S#Z1wFj$KI<w\YZ#aa<C@htuc6:>tBTw%DeuAk!q1:ZnD^jDTq#MM\L
!uNLy$ JyYChXMJEK4*GuW@X%QCIEJjIF^+cl9EVi^lPKXF\GQtY4tZ!4p>D$m&ZR?T<E6!Fh9teY46Z:5$jD><
c>Bb84 ASt6lCT&QGb&aublkjBGq6ucWCpN\kV:WpP8Ic:!cXcpWc+4S&?L+8R9m<W%:>5diSP@8%+upYu#tVbK
:yteMG W=d6LY4\ypY?LlNj!L%N@qWqQFtiJK/VPjhQi5LFdRNK8EihF@VQI9>jh*Q@Z^Pk@>HB@hIK4!n$N+XZ
EdTcIZ FHLbu6t@KlSIEdH#^N#jjiH@yun@c$H&h%@+*:HRC+VC***l##u8BTL!:::\=&A9EAy@>+Z@HZ6SL?u9
a@W&4: 99C@a^Hu&+anj@iFQ\eL9?C+<H?NlTQQ9</@?<Kjk^Y?+FwJZ\IL9\B:CX:BwShkL<E4tNkF&E9\Cmb/
JCBCGH AjaT9IJheK%EL5E4&AZZT8RT9LyRj^cB@ZjAq&CY/QuB#WkS^H<Di\qtCb>9lI<W8R!#^M:@Fwyelquu
S14M%+ G+Ak@<pT/i@I9!9FIlA^b8E@1QYuBhBjqiL@+NtPQK@m>+@iS8h<=6@Xb<njQ%QpQ#TKm9%8DIL<n!=F
8al&?> j%ij+YKZ<IEHhF4+>$qBk1JCbVY9@L5MZRAqy^?^^PY^bKFDlLQmBjR%Pw8Rk<Q\DPk/IAlGJjPP<eal
9dQiT* a:Eky8l1QISW5E++TX<uHe1<?BaAVED8c<M6lYCKq85$kM#b<hP4BANp5VL+apW!YL\u%KHZVM9Vh\G!
u%\8c& LXJwBFWKYBNZAIic4pZYa8u=WLIXMAeM/IRt6%km!Et5e<XRY@epZ/JDLatFtX%E/ibb!KNj!jjBthyC
:T8Lty DcI&G<$S8j4Th=y6M1pEApBAGyu<ImwnKmwA<4u$nd8QF@b/:l=IE*mLWhGDZ#acbE<P4VLGeEtcn/E>
*E$*W\ ^h!/khjD#P:PmH:&8>t^NDk<>YeL/wP>Z@Fii^t1V!iF+MSRK6C*%#pj$eubSSniln^iya:$uIJNmD5V
^S8\\T wL$nqSFaSw/h+uQT\k>pHuyDFT4eJ+6=IWmT!D#i>kFjeTIMlGIlpwqeduqT^99hmw+@^5N<puu5t#MX
+?tF8N Eb9>pkmAyR$Nm<uqZlAZhdHKPk:Be^*bcmJhtTS1bLG*Qi%Vt!4pi/Fl6jRhyD+X\AJtw>Q/?Z4Z#:IL
Kt=&:X WBJ9&S<b!M1<RPT$EQ\%6F*1eF$=WDYIM*yCET%&M/q9jae$q&=V9FD:=k<eDqAJe&I*XIC:C<nT5lAE
:LqAyk jN/GjSI/4D\&I#<edl/1wNcY<V/W>P*DW@Bp*jE/<JC<b@?X5GQ1eZNu$MN6bb&lJ*iWZK!&SbyHyY^+
aESFKm DaS5GI:D45S4GnYqVJbR/e>IcS4#5ekYdS95*E\!NNSdM=J/^XI/h%M5wN#E#1VCC?ABIA6?/*BH#<dM
ZuKn?& I1Vt/9y^/Gu<8CXc/@=d9TZ*8pyt#yTuE>6tH=L:yWquTewPtl1?l/+dm4\4qX+c+DAStcHnbLlq=8*+
&Xk?I6 !unS\LFnY\?y?$yBnS9%JkR8nF1h4l9PtBS:/SX>FB:1+/?hAM4%:>lb$JI!pyn%qhLY&%Vj6&K=w&i1
>8hu#l L:HpMbVQ>*FkPD?>Ea>:ML#Bh@GY<Y8<q\?@/%<hTh<GP=ed5YP?GS@Cw=8>G/qG&RRlhB1CD=YQR:$c
YQanq1 a9hFjWQ8aDEY1AA4h:d8pqPuTeh>TJ\R/yDY5KK1=Q$&k<ViRclRh*Kcp%HYNij>ti8u/$BS:^>^cwV?
XMS:&e ShS!8<qLd$Y9IpKMpSq^%$SGSS55aC??H6Y*GP1J$?whmX#N?8+\\uuXywtMJGJuTW>!:jc<hLelaq*k
kH&RQh YwDl4hVSSCk+!:yRL?aS4TunhGXy\QG:Yi9pLVK4L1!#*A1$IT9JmFBak/Zy&&%d%yV4Ra+5Ll!^@MKG
VktFtM >Dj1eG^h:4<9b<@#%HnThEX>N^5anp@M%AiDSye6C*TGE6QK:D$k/R+QpnP<i/*p8%nX6N:4hZu*G%H&
ueZWJF ad6*Nm9tuB@E!6niA=e9F*=iYI&%%H?p\LI9bXhRN@th*5\Xlim<?yR!IGyENMH>ct8<jcW^XnbR!Bui
u+u96c mij>Mu6!$XB=%?cFh&^dY6TEYQY6Nh#kDlJ>h/udSILWetHpYYbqDl:Xe8:6e?<Iu:NJ<Cuua+G/4m<V
&4XP1e 96<SL\<WDR\F4yF%?Kt+?%Bq6ZY<yL$/Aa\\1iG/l&/p//AAEP?5*m:R5%@PXjA4qyFXcd4C@$am*TIl
Jlm^uJ lPXFBCd>*V$>VC@LFP@pW51wdEPcEnm<Il6N96Kmy*\paqM#H==6PKGTHyHBFEwjI=w$8CkPSb$!YRi@
#%p4EE m8dnM=q+WN>LFCVP?ZFW@RlFJW:E@Ip>HuJ*F+e=6K?8u/PFPB#VR%La5?qBmiZ!Lc!Sq4INJXc99S<D
q6J&dN iZld/R&wuLVKT#!MM1mMI$Yt/MP<?kEDN#JTADnd5c5l%N&eL&+tb$PS1\HXhWaZ:nDt+1$w/1#%TjqR
PtY?9% jnBdhW+:/Ji84E&NL%4XBWPV6==mjIc9ViQwhA511/M1KmmQQ5aPE4qPVZ>mnGGRFV9i>Z+Y/Tkl!^>q
&B1c+h wQ%FIcPYEyVRbeiH*TXn6Iw$Xppu=yd:Q5AMp*TI%FTSuV:I!p$L$L^Dic4<1i%>@6&K8l\$DHk5mSd@
eL:d!8 awQM6>^W&\L6Zi>P$e%XhNiE=4?h=\A?5KCR$SKli^uQlqaq6uT#J%D#LkZE?4Hlb*5YN>nj$bQ9m?*j
8dn^#e KiT%*^AM4&nRPu+ch##<lb@bmMGlVA86FeH*#wjMe$?<QM>8?Z$FwlBS\R=5yE#X$4d6/*&1JqA8=QMh
b9MXnw +5lj@$tAK*qE5Fa$LR>5&6$nAapa^q$&H%hX$wJp4#&>Phe^Pn:uIWuAamd=h8=#CjaAC!6Q!BA&ap/>
d45I5u Rt4@PhFdwAGmqea+<#yc:@Vc+^ZF>iq^5T6DZ!5BQ9FXJY>:pi4ekn^D^P1P5&=lH\#imEyXZl%+GBS=
J/JHCt \LiT%LNCm6pBFB1^YKd^PPR6ZqPPBLBadwnKe&RJl>BjcWS+ESm%Q#XD\*<S<EdhmHw&/N>ddL\uRqCy
&ynTy5 j<l:bt=*>YaVAK^49=%eH1jNdEiLq@q5dh8w?IN$Z8RpM1+nIPVLKRe@?FwKw>@%euEPjR/Qyjm/X:6%
lK9$=X h1F%aj^j4<H*w5XV<tm8/WP=nFeWYk#^$PWhP5ReMy4^?w9nqX?j^=NbKw+I54Bw*>Em64mja&^a6w&b
mHmk1I >9EVQn!5e:mXkQFw55$J^Td1PSJKZE8kMB489#qYIVki^j<+t4WmnIiX?9%JiiW\:9jBd>%B#9nB:y>X
GY$mMn 9m419/wKAn<mqjYkTE?PqY?MaHCnnuGwmClw#&cNXhnSXMW5?W@MThuL>NElhXRQRM!iI1dlkcLMBc#K
4TTBk$ AP?4>khj6RiTu>:q+ElN>ba=ci\QI*6DBJKbhjeTVitYbGhPbC!uPL5yWZj5ZN6:e$495TV^m>\&1*&!
QFiG<Q 4i=A\yuS5LR8Bp8\bSw5$y:Y#WdDEnqj^pJ+q%D@YG/1nDXS<JTF\PkJHddMR<yIBQXB+YNaJZ<*M\A<
Knay?e M#L==LbdM/AHuXa#&j^YZ#NZ4WK#wdh+#4SEE\IN+/ASYM^+$E!M?/GJ!IJhEDiyNJb>8?my\DY?Nb=\
IPI4G& n=uEZ>mc8/t1SI=eX9lH!pb:m&LF@p@$:=cjPwkRLBnJu@1T<>#/MV6Z:!SS#86Ttjd#^bK!c864>XN<
-A$K>Y 0004bb1d05600110333 Page 153 of binaries1.zip
h%<t:N L!ShKieR%ann?=S5?:%aaN5<K8uDYh\4G6a&Z=&lYVX5&jFyA=Pm5MJ%Yn?>bPEiQX<8$q#HW@j?F&bQ
C%Du9J Syen5?eKYe%j=YaWl&9y<I5DX?aT8Mq\WIhHR8d*Tp!@d?XF>cd@Kua9&>k=K9aBE!Q#Xk@n%laCmmai
PqG<VH 5F4Pp5^>!%&%&uS>Sc\a\^*<AXP#!1E1EuYhPH#Ck6uYQa!<a@S5ZVG%j!6!iX%m^5cul=6hjQAyAXbe
cVYML& GL<pVNA#nQ&:CZ9!JJ>/TZhnb@nt4?JqdLmE6#@ct1P61#\G=Qy\Zm=^nNT+L+Iyw?J\\Dq#MLh=Gk!4
/#wm4w R=ieD5JJ\11M?WIj1N+ES+/CS=$6%eS6emwY=jJI+&iinPME8tb+KdCS^Vw@*iekXDG9KGdXGY$RJcT4
1PFD>D n&B!/k%N/EPA:eaYC@j#6?kB=H9^qTQSSeTFG/!SXhaXuSPXkwy&X1:I4wJnRqLTKyT:\ty5^iuD\hV:
d9=?W\ P$Q:QA?@:$5t>LEGKZ+6+k+*LWK<G$li!/*:!V#^pD8ZkVeuwZeZH>A#+D<C=m:=XqdLRFk*SeT$WQ\I
<>?>=Q h*PceeDA9$TMtli=YGJG9c>C\%M#ZaT!Hc%wn/9JFqT5*lk:!@M*qNwCSSD/P&+S1PjaD8\n>6/<RE*b
qY>y?e qVSY4\!\YP@IEIFiKyNdkcYWdCNninmXP<6A#5dPG*pe4l&N*S&8&!5eY<QpRa*%^Mcbewal*YE*Tn:S
Kw+Pa% VPD1nC\48MPAiV9A@AZXMb?iupMZI1DlG1+LD^H:9yddaZypt@Pn5qWDRe!TTkitH?kVadDF\:11>9*\
!==W1d MI#NQZc9^wah4=Ihuc^^8GDw4mX?1I>9e@4LQe<enQ1!%w!N&8ca8MFX\%/c+H1EN<\h<w$6QIY6P$Rk
PF?e$^ @mQ:lBL=lIck?WjBK9<\\jW*AAA5+RYudDFZAtdX#jt\Ct6QPYJYl5/MMJ@pQGDQD<+p6Dd#$LF&RL+i
1t>Y!w <XY$+/<#Z@LtRu<=\qnc+>$R1Pj*h?GjJGN#Q@^iHG+FDtJHXcDbE5RtXt>NdF1FCl1#H\/wXW*FPpjL
uCy+lj BpA@*yia<K/wah=NIl!8FNT%SaHZTMj\l+^!P#:GEI<P1d:bDcJpQ#NE%SPVBT6E!@<k@#=TBy8#TVXW
/<tqID @Tyt$/\@aD5yRC<NBlua6a+u+K9!JWeKRE/HDt$^p/S^D!hZY5b*+dIC&?#PJqD6>jFp&M&4/!AB:#iw
AcRqtB Cl8T8y!%mXkuPlACV4#=DmtkA8F$d5e!bMMCSRH#N$e\lp9>jFw6N8Wmm>pPX^\Ht8^FdwPj$8uEQ+C1
w$FhX8 l^GPYbSt6/wY<%A&6^BLt9Dn9lLw!kLb*h/p9BYcm?TdpHTZ!Eq!dp&$Bjc6t:t*mjENkGMnqa<LtBPd
ct^11? q>nQpkAd6>jyWRAnqeHWL?8wX=8!X+u4YWeFTaHyyY9+$TS>pqcLZkR=iV5DBtlX<XE%p4ZthF9PuNYe
a<Bq<d t?9qyP8Hil#9qPK/GVH!B6PIIK6=Ntd4<84RBF6GG556%9QX^u<$jj$@Pc&Q@EeQ&W54n&K@>=cK\T?4
LXq=Nk QI1hN/&Q@N&S>t?>6j>BN+Ch*@V&8!Q6:%kw:Q#u>><hcZ@HmmA9\IyeAm6!jq9n:+/$9&PFSe=Z:*=*
NP:#Gi yQ$hm^A:Z&Q=*bH&uG6%95p1<uhH&6?^F+yK9%9TuuP^IPjj+N<hcj<Z5Jel%kYhtEnEj\N:GYKJun>G
emPPct n4\E5cDC=>>kyPl@A*5bawteL<Al^j:4&H@!L@p:<n>46@!:Yc+/5>lj6<h@@M#@PBu>d#8dkaaq=5?G
Rte>qy $H>9E%X!?uP#E%K*eQ4LC\T#pL/D6cj>Z&d$lSS6HP#5Qj@T%Q4H%8Zk/aG&ebh%eZJ%ej:L^5n<^?/H
8a=Rd% hZHZh4Y\59qnX@948j=XYwNCaH@emH?q4iE\T?GATMG+ki$j!I8aPKqJ\#1bE:k#aT\EWb&YCiuG!tLW
X/W:4@ Rj:?=qLehGS$Md*=WAhniX*?6MGC1#^=DLibp%Z6+GILM<LmV%V5/5T?$=EVAcTq#Re+cJ=ei/bhlCBP
Si4t^# We>FF+:\V6>4ijlTy&TG=?VLYm\XtEBP?mVnlQmFdbXi?Tpn>eTcX@Mh*5>?c+eu&Md*#/WJDXAe@nWL
*ddInH u?li@8Tnh*=y=I^emCZkmPli1uHN#1VC9WIMeKN6iiZB<ulmAW::V9$tV>Ek%86iEeSApA+WGtR^jQ*#
HdDTQS 6dyJ&#QDX\>4djJYQ6W$?Y@/TDKV?/NpJM*a:MydQy/>i/n?1#48\::Q$=K#iGZP1?Hi%$d6nN+NuH#:
kW&!K+ >t/^59QFaWppkQY=Aa+BVel#h@X94TQ<wENyMlKhA?q+a/bbcY+/W#1yK?HY>G%Z51*Q&11mGRtqNjF/
jmc*cJ !X>C&hwy8kuJHZGpeBThcID:K?8uuhZ\AIK8cqY*1=$HR\^Z8^NBPE#!GtY&*^X4XIuai11u=K:*^u9!
aq&m&F 5Mkq51i^1XD1pDHiQGl=ht%\@Ll6Kk!Yb*BNBZ*e<%WN6n4QN%#n&T*p:\E^9NdyEZ\mMKIX@j4&mCjw
Fa6TSw l:R1kmuu8u4:DwGpMyZANeGJ1\@wlZ5TdjmL%Y5l>+MuQAFklRq6*X6w4b1l#<IES%WB&6y%HG^cI\ku
H:Mc6% M*chI@eB=wFA<qA<*SS1E@VMhL/S^w\:qw/X5Ca:tm&CinjITm8X?wGq\hXh^R\mX4RwC=GqNaHlt^pB
^6>YBF IaM*ImEKdujG^#K+FGX<u456WKiW*6PnnSu$MZB4#PFSbE$9>6D@ZH:pcb^&c<Q9HVh=Cb<mc:NR\NKb
T8C?94 CMDl#StkPKKL6T8R^%D9\WGpiXwDS?\CM4!Yid/^kT>8bW/hIuBJnF$T&B$+iT@FGlpKVh!+Y&CVXmFn
mtRLLE dCC\$R#$i4b/4+e6jYH$P+/kjdQ/uT\HB69Cb\/11kYCIR!^=YpaI?D4hM89bVqCJQ5+#SDH6+K%6Vb?
8b11>Z NP>KN@5kHdTKLQ:hnZbm\LTtQcQa@udYdMIitHIR>@CLk!eFui&jtq!aW@DbpFnB5CCyCYG\qRGl<BXn
PM6$$u :>+EV>@dnG&HRuR!I8BZbC19uX1+%Mbhtb=bVY%jK:Tbe*u!/&/@=>QKwQhdV&<:Lb:??P#YjHd6ticc
VhP%NY :*YN@FZjLNG\6aPj4*P*Qy9&t1%@#u4^hPY:GhuL*i?9CccZ9@><Nuq/:>jh6*5Qd^j&j@u^a*V:?=hu
6u^/5J aZ5@**hh<TeH@&4V4@8i#W:\eI#u=/&$Zn^tKtDA961SXD4*%@hVqIFXGND6PVk?e^%nMLudL^tpG8AD
\:>\^> Q*jRjktb#N\%\8jYRpFXA%ThlE/k^i@CaYVEhJ*y?8AQW>Jl?:9LKGRI!jNn^dAEZDdWZA1Fyh>mlB5q
+5Vj/I n^!l\>YeF5$H=QJZ8#4CKYXB6/AYhcJ!mm<I4iCHX/SdpNiLJtRCjVBGB:dm1QS61pX8FqKYQ9ai%nPt
^b?KL> >nN1N1minL!QEk$^>^ZTkCtS:puPc+GEh^MwqyY/:ZiGbN5E<ZmwJIJqI\u%9/!RTc9i/m/maFtD>=EF
Z5I1!E HN>tN=i=$ZYqt=!XMJciBemC5*M*eWJLy&$CRSnMdejTk=DFZYJ!p*K%J8PP^kq*ZYXqd&qJ$/LS#tld
>:^k$B aJZBipC#1dkK1/q/!emJKe^9QSqYyL%SCPeFZCtT9*LXF^S\F1NlmXRwVM/mqP=#9KXhIKkiAh49CIew
#68ZaJ >$N8lcFL561Y+mt=ESAmbpY:ni<@M?wWT<QJt>uH5+$wI@KWI/\qKjEd$=<q=LANm/S!w9^=pB>$4pjp
*?&khB VRBS!VbwZK#p^BaZddG\KI4XXV%e&Jc8M<qEb+tJJTLat!9+LL6RJ>X?5DGdGpCaI<:bl^NEZqWdR1im
4me/1Y aM+pELS1JXTRwycH/TLFd/eKujbBAwi4SRLGtbtt/TmwAkXF6bV+DFdh8jFbp/>Meyn!lLB*!4Aac%i+
WQ:R$h iuLLTbQuyARY/ke!eRXPa*X\tHRmC\y+8/&AX\M<>Wdj8BpWSSJS6PQ4R&#H>TjD\!qJZpXN?J?a=P>t
bZ$kbn ^c^t\*E@MGY$yi5bhLS\%%Ka<>6**/5+Db%Q54Ctq#wmk:Y=*kqim^dA=<%EL8EdBl%PY8/t1Jb^C6+u
V:#%mP 9kP$Cct!<SymJ!YleH+dEN>I!?!?a$V5@mNAKwyYQ<dDj^\%&9&t%McmpWn6!Y*9Hce8KHP\JpuHSH*I
@Ei$<n yku6$Hi#+K6jt#u^P^yjNI>JBjlD=K>TpT+hmqXI+dL%MAdTV6RTDWR645k#y%*qY#Y=5y+DqSetN<%B
Xw4NE% TQ1@4QjHtHR!Y/w!S><NJP^+QPX\^h<cX<Rhlwwj/NZP?4Zmn\N4>^?CD/y1kPa^qWF!bFyT\Zck@TT5
*H:1Q5 c\FPSwAPG$pIVYWAwV5DtN<1cGA4VG1yB@^=w6h/ai8JQ^Kjki5puYVJ=BqDpR:J<\N#ME5YeYuF*b/9
dl?n:V QQjAWF9lc?R9Gc1X9\qwq9FLQ=nwFR8/!49$ueT@a^&ZbayenmYe*1=Yu&Fb!6CYH=A+n/cuB$6:tBAZ
qDpSpY 9JWK4<%Z@a:F9$cWm%n4WLA!EA>VcR&Z>b<9:5l=B>@HJilP>=mn!>4JHT8mDJ*Sq=blbk:b!4\Y?AQt
ZyM?Iq %6aHnGEkK#k65FAbL:M!p>>p9tKLk:ME8mKMbtZDdTl?b/SBuMVTMC5@6pBd!Y<e5>AFp?Q<+=Fu/W+j
!6DN>H M^:5<&LqHD9TGPikMNHpLIGcd1LSaM^XNDn<ua$RTCqp*B<jV&>/?h=etn?Fn#?H+&5RVy%LlF5dj+t4
\<YbmL KBQ#MY55<<+Y$F<GpHPEPl\ij/*Wy$N5n&QR@+KX$NhAkLE#6JDA%h+j@%YSGT8hY#dP*b6%i^YdG@=t
aRi@5Z 8PNhbN&Mj8:M?L?mKT4VA=jTAM@:*^G$WbKlkTR:a8I>>M!bI5E^kZdtW6jhRLm$AbW<>=bRI1VTwq%?
a41P/8 N?:#?q%LBDyhmd*TS9nRb>DCPi9#/=5$1q&6h@QeK&>>9EZ&aNp$/@VLL@&Q><N!^l??u941a4HhEyh>
$&hBX$ cNw::jjMaY>NmwXGSyX^:wQ96RBc+5\&d6JRLqumkHkuP8t4T::lpXi/eN:ShJJdY5!BkQLec%jbM8\6
E/y1yF NMu^eMmbTaKe1RCcme\ETQW4D:i@Zu%8V$lI=:EXN$hBkALmjDB9eTDGb^uLNn@8=J4CaRE!hACy&#w?
48RSSV j>4mNMiqG1cpK%cue*bq6ymaAB8V<Wa#Y\V4l$*SQ5hqd5<D:LMAYG*^?i<#t*9l>8:RdRW#B$mwka&J
LI19kL 4nR\6&Nu\n*^LWca&!CLqR<ILc%^YEJn&5IbuI>>&w/@b?PCA\#*FZ#yZS<!T!jnS1HD#W8aPwAEX&yY
CVPe%X K1%ukBXp#CA<=5b4$mN9Fd=jpSc=!8JM%V=n8>hFbnF$^TL:t4SWCE:<XS\cmnbmauI&ED5VeZaLTh5C
a&hmYk DuMJw!6=ADMyR^9pnTaD>eCau#pVw\WTKIX:yS*S6mqB?:!B9CPSRY1wV\N:Y4CGc%=G?@?\>>>lVdZ4
HjuVcA 6nAiYkmlBRkhMjRPTRmR$A\>>BC1%NB:L!Kmlla/$pFFyQji^E/Z*pXEXJA1VWSE4P@Q6jjc/=!>%89*
=wARGn i9d?46>*4uMh@ENR^y#QuBqQ8<h#n^5kjut%/W^MELlH?^M^t:5*mBPmuk!AW5aEuTtqlbnccQWEAZyX
9W><kW kT8cb&b<#t!qWeJP1QbBZP>>PPq+Ae:^$N+Yc6kk>?yKwkp@i?pCDWWq8<AThCd/bMMH5PIImFumBKmD
%G*w#K T=R+TmZDXp/k4dPWkCYt4PIZI!BcCt%GM^<&\AV*4uLm!nKkSIGnqMl6=uPt=Byj5JF^Cb+^?AJHCjeb
T:FVJR kcA#/aTL9ZcCApFMA5#eP@cbyH$ldAQd#G$?*BX1Aw1SwM@yG@YynW8ieFcIkPJy/4q/JC?a:Va$1!FK
-A6RE* 0005c5e9fc600110333 Page 154 of binaries1.zip
<!dhGd CPID?a1\Bk9GLQEnuTCCwcLIPI+&L=IGlXnYdVG>ZC:CLa/&/MSXCBWll>Q*uel56!TSmRqbLVlM#e6c
<k6#Ku ^et1jlH:R4ypt%\TSlZTh1cEZ4#FR1THmVPpmqjQlJ>%qC&XX\db^ktJD&l:IdM/I+6QEwM^$SC1&WPi
%>Cb&P TBIdb8uw=Gb8m#F@klNiIpQaPN98ja16AlJ/ybBGyJCQWkJ%TnqC$k%?mS>w=Xp8$Pewj1K$y<C!TSIZ
&MlaAj \%byJatm+\R6KXknNMtSmjlWbq>L+X$DEy6<ym&Yu6nTy9iDc4dwDGBwZKNbw6iHu9uBBYiMSM<d5QGk
a4yaWS jM+DwbJkAZqSCAXkdJ5TIHBhLEcc\lp=nu$9$hN*^4PHAXqEI@ehQuewBk8k/upuDy8ETPY/>qB!\@yl
1eP>8= dc!R%c4tJ:uMSAc\9CmXl81/^\/p%^w#!!bm/HRPaTCQhYMu!wkB=9pJQmVuu>&aF$q$wyLmaTPbc<=E
DmPwKP $MQGXhcbYCnIZKGmFALNnQlBqVhaN8eaMR1tXd$jnKZYb>yaS\\GAK9*KN6FtddFARLYI5ES$Nq$LXhb
5/Q<u@ ckFVMR14#Jp@8FiqkH/WNM/hTCL<=?JRDeuKqX89F\8DIINK9W&w&1J!i!Y+X?6!lptA%tI14I=^KFG5
VGMNdS ^EtR^LP<6WjHG9RH&Ikc+eBSp9ElmR\R$PHi1VThT^HD6k4GXDW+V\tTGnl4PwDHyl!q/%p>:F\#Q6tY
B^>c6t +l@L5ACaqGCMX\Q^4tC&deX5M@h8E*pqmV/+&PEnaZ5/lZ6tqwwa%PC<KylnZ#E:^%FcGEjK\jb&jD:c
$a:8e$ R5j!WTPtPTutV!qwdTTBHSS*dIdS%ARJ/8b/T?$8kMAWYmCI6VT*k1nNtnZLmH&QFV&qwVAYJE&ll9$A
pJL8&w 1>eETcJnH/PPZZ+PQ6=<LM8HV*kaT&XEFB\L5EtWS&/kqdyaw49mWSA94Ndyuahkn^5E<XpWT>4c1tQ9
Q%6i9/ mXE%K&ciVQE9ljA1/w9EXMSnq?p=4M/WYFLqK8mS*Nl/*4D%Y9ACFtqkEI/XI4:=iK@XJNdTian#Cp6Q
HRX5wp N^hJtlp:>K%Ytqwnkq@AmGtFkcZptGMF\6Il:L+T\A=ww+:JaP+hbebm?Xc>e68bDjyWYSmQn\YmKGXR
Hb<<M% 6TRwn$W<1aTJ%81hjjlqY/89@9uQnQQ@CLKmCA4:I+nDN?kVuc5TG?EPXdC%RQA#Z95C^lC4:$F*EMEF
i&A4St e1HYLKFlF$KWJEKX#wW<W\t:\^q&RT8$\GVnkp=+kYWay%T+pqtEpuh+/>YItbEIc+iIC<ECh@VDL\TG
EBtA5w j:wc\Zpy5CDXqjNmyHX+yFLP^V5Sd=#9iFpZXjV/5Yj&Sq=wmX*SbBy@JhZ4^qd1HPW#\EDlc1?=^>k?
CIl%L$ Ej15YJ5mCmTb1@J#D1jq9JlWDI4l86<*BH:jHuLBS=8w!dIjkXmlyAhe>iFM8+?qbIJFH/%^AQbyk#?%
Bj4uPe cRwMD\+aADYkLP/QL%JH<FAwF\k&WjRa+\8MI?Q^WPhFdR$I:SHuliEwTG<tZ>pd96Wu!y<KLkkL59Ti
1Rlu+y B&6G5jjKkd6Sym5BuCS^qhZ5il5BewWJF:dc:a$Qi/p4p4$5kMSEyaED4D&mbC>I?9SFFb9E:!85AKME
cIlHB* $V>LZB>km6q8wtwBCLAPwD5n*:lR\*KjXu^n:MtqX@!WVEX/G4ypBBQpputajmhZ1&iiewMT$16CdZ&K
!N=P@< J9JBTuB+tC:%^M6ILn>XkT1KTtw&alVpPRAN$/SaYa$V:PHHG1aX@l#aF&u#N/Yh6bqMc!>4\\A\MFSB
tKnKIQ FR>VbiLYJ/%#MbdCq6j9WYn5AK:qyd1Me<Sp$awA#5Vw=Z@KyIaNb%Z!W&5Ie*Hd!<GYPPC&iAwC!@P<
l!N1cl FMEK&l\jC+yJX5nbdC$PeGpba/C+PKtPC\FIY\qnqymtXG4KA@D\iMm!>jm!FS+K4a4VZLjXYFum=qlQ
L*yK>? Y#ZlT=/tkiXB4QleXynwXq#GV=eF5NTR*E!6qWQ?1R5q>=lL^W:ya@bGZbh+NIcwVuFm9X$$QaeY&I\N
%^tdNP Td%!w@%TFt1iu96P@hq$AQ9K<!i\%Tmw\L^=mYLhF:8TJcj!DA5c\NeeuRGIkA5DV\mM!QTtFY/BnT!&
Z4&wIj nT5Qntc@^t?QyaTY@KF>aWGm%\kaH1CB4RNJlNdhT?S<ulpAT/IX8KB4Ge*^FtWj\$Bj^>\I11$C<XDH
$P@\Bm DAjb89H!CFJnP&Zel^qJ6NAql&dqyIi>TXA^EF@n@W^BC!B&t8wmXpPnCuCVyecPudQumLdtC$GnniY\
Y14W@e QdhMFTDR^qp\/>m:^QbC1Y/al$LD=Z8CeEPJR1FeCDNFbmjbu4N\w=tS5>uWn$YkJLA$u/uWyNZ$Cl5y
&+EQa@ cqP$mTyt/@JZW6QZ?L+a!XEhE5?1dM=FWRH5M49A4X9CHK#PIuu*1%JW/8bK::HwEcnV!??ZMXDDYG>X
MC?e/R SVFElub?tT*wuRVTEkC4T@!d>^aP?>J:KXt6GH^YyPK@9t?9nicJ&i4$cPLSmKR5+cN49:hW1p9be<yN
E1pPce 5Z/BapV!uu#:#dlYj&WKnY&G*p4T+DAXSTbV/YMh9TQ\mleHbm?\BM<Ma/I8>V9lbS5Inkd$S6D$XQF?
W>*+Jt :jbb$V^LeaVqtD@BM6F4A@lmKkJLwFBaFWlnmX9bK+d9$4$m*IhT?Fq6ABVXa\XdktmeaPtqc+ql@G+A
5=MwSR @ymYEFmbV91HASZmeR<qX?pnt6wiY+AtM&tBqc96SIMBTEynmD1\AcmM4\lQ*b!<eYu&PP$IbF+akK&b
!SS*+8 V5qum5Ct@P#yyN*L*>+?SlmAT?n%dB>*>AB+/R&jFPtMZYh4e*B\%DMh8#R#h8?GP6d6>5YEK:FdC\=u
>FGMNc Ft/F!JIEce@@pP^BW@bPe9cwbK85/EWHMNlypl\mG^#+E<9LmKRnnl++XT6YDKdJeTILAEAbFq+qpkSy
6kHTaw iAe\^E%YYJcN!\EXCW9j\\eFqN#ETT%JD!==QRAIMHDFwMCRheJKDbZ+MwYG\1W!cy:4C6ReZk4abi4w
aTI$5y MnqAMtMQuDXcqkA:a8?ywaaF$T>V\*w+Z/^R5L$5jZ4bE+I6kjTbAFa?>/$*5XpJ\y!dZ:>l=R*V=R&N
ih5Gwn %1bwaBNAM\Ai>L/BW5P\y!WAcwG4m?+CL$h*GLlZBLDwnnJYG9yJ$8Y>%wiHej\q=nGX5+N!8mJwb1N6
$c=nwE tEdDNMCKw&lIBXd#\+Wc5C1W$khq84kE\*/+QynEaX:IR*wkBK8*n1X=1c+*YdhHMe$qRAGyGyTqZ!wD
yZA:qL \Qb%=bYba/LAJWj$SSccFNFH1\:dtp^eV6IAC4G!Tu+wS\pAJt@//M4*YDAQ>m/>&K$hd:1htuk/bWq1
4%9PZ\ Ajqm6=?5nwaCiml:PQ4L?D/VM5Ee/\B%beV1qcaTVa:=R>l1ViEdcn4a*h&%Jk4HA\CAmdNH*1\Q!Fp!
&1kyJb #855!DGm6iPw@/!XtyeaAFm^+nki%Ri+WY9p8bhwWp45CbGatH1\nLhE+S4w=6:waBep6WAZD/tGT^QR
GP5W<# IRtAbYIbPCCA8D=mT$VY>TcRjyI#jlkYd^WRq*dh6Rbqi++nadk$=aJ\B4h+9EFqCJ$dmtCRP!#ayl@&
D+%*9# CpK4SVp8lwq?yCWQ8J/iF4G5!INtJ@Hwlh:uK=ZQy8kH8eFlYhCCJC8hVj\wFJqm:GNPbC^mT6K9&Ib$
JQ1QqS #QWedJa<h$dSC*MaS*SN!IY<Vb@hSh<pCqB4^4wuE!8IJiYmdWGW!GyEQ+1EDm8/EJVFaSS%<SKhACD:
%=c88m 9J6SM4+iVbZN4:i8MGtHHyT4*X=St$>/abRIRFpyK#JHDSGJqVSq=%pncR:jS/wLI!DedtpW*9XuZ6>?
eb1=E6 9l@15y%?>*uGE!<YShWX=e<IE%<Y?jFkGmGX@a9\l/Zy#ERAQhYbPVMmB55HwLm:M5YeH6ehH!>a$wiI
iqGLME J\K\l^t4t1#\c%N$AVR5W/DFS4pM%&=/WKtj44LY8\EYKC!G!+Eqwb!k8+1bZI1qaW5wPaCVSEL:ZG?a
X?lY?i Tt=L>5t^>XVHkDW$BLk&?=ie%HjSWQ&CXbCtq@\Vbha/9mH$N&>cTQJX1uF^Aj91\9ZFGn6NYIwX+pue
kK89>y *WDJ\9WBFVbheZkn!@WQ>8:ReeQYXJbmD+84*AMjn8nQ>AqjD?RZt66=B*9aHy^lJ$HBq!NkBBZZlJPt
qPSI@R ^hqFMqaN&PR$^WCqwMeh!D%1+!jTd%VTS<+4/V>J:&T$:B@Y\F/<?bF9%$F>BXDHSXN=l6=?ERV4=%e%
#hi9y^ V</k^Yh>jc/Q5/lVQ^%9k>:WJJ8Huqbu9Aqlhb<NFV@AVd?q5VPTj=4Na89R?YDjVTRPud<:55C+E\1y
Ekek6V e/lWj*XN=44HC/6$@q!1Ay@d9tWhD?6Pcp:&jWGyicLmW\^KBGtnNjaW65k*dLiCHp&Spn:EPLMkwaCM
%Bi/Sw BR:D!$aS@9X^++cQ&QWbQCB%VNVYWW!<I&KbQbJb\QbAEkCk4ya1\C+LW<qdZPIG+ZS:m8lyqL/AR&a>
b/y6T@ 8JPM<uM1Q6@$kM1c6&%eW5#P!nq@9W?iRc8%kM9y+tCj4$B=l:L\MBcJm1ZAHp!q<FC>Z+?Qica1/MXL
X=JZ>D 1X5X9@cA!BeZL\BB^*QqBHYDT6:WcLi@nnLPcZP:TZDw*Je?\*yI/4$H>tdlJ6DjL>^m!pL$icu#X#?8
TpFZ$e 5hEK&<<6HFJNAIB19IYJccCVR4KNt?S%l\Z489d=YikbBy\GL#<9NARpS&Gub=TZ1EZ4=B=Y!<WiZduJ
\:@kkp ptRN/dF!@Rm:H^ayjNH^+X5jma?j1aHaGKdE*HnlpSwL:BRhKDFw/XZthY4GKdnKuTM\/H^wLT\DN/X&
K&QN:d TMpEbGE$49GQnw<#&4=%ubMP+AbuKBZ>>445C:m<CEK@WqI<RmTDcWkjd8R@y$5Bbb&9PI%N$LZjTaJJ
wVB$TA ?W!X$FBpd84%5&yTM<WLy:1h>JkHAT<A1J*/i\B#M*%\bA5SIJw4TCICaKtpEXNNRdAeh1#$55m$L<<S
69HYAI qJauX<=9lT?$G<ApYu\hSEQ=Cp&n6e@5lPM?Z>pTT/&B9CkIB>k*4NPp4t=\J>XEWFD/B/Xl>:l$H6md
y\4lk1 %q<EbSB$\SSW*V#Jh*hJkLAeX<mSeW?Fa=\ASPaNNQZ<Yw>?LMpN>ASVG?$:#hAS!=SX*8<HbjcKVSN\
D8iaX/ m/AaaBS\kep4Spcj=/>=A8mN%PaKn6wi\VI^CD:*b\ncw>ZAYwDyeAB/&Ba/c/YRwTiilwyWw5C&m=d9
G%19=R Zd+NkAnTXLRAGJn<YqTDIDhYimlaSu8qcH1!dZBweb+6$kpb95nqXEnlJI<jRl<^$J:>S4/MhS/H+D?4
n&@LT: JiNutaW6ALGkt#n8JA1P8d8k^JIVeA@Dl=K^QXCm<=Y8?EW<6YVJqGkL?89CLBAkEHTa&QGFKdh\pT9Y
wh:M8P T%d6CMRX><JBam$ZF$9S#HnhJn1\DthLRYLmV5#59\F\ISZQqIB/RR@bNKhDCt5#LqC%+$mTVQi1X=c?
6w9&$h AAAQ/ZMb!BTpPwBt#TZPkVwE$8!KY$=RB^e&*w+BeR*%4IRCVHHhu=F5J5l\4E14mjFul1Eyu6C614%N
wnFkC: ap@tluVF\a8wawiFKh^EBcpAq\kcLj+pTBIZJddIuWmWFM=eA8C=X%&5Qk5A?\MWy$CHFiF:>?M%4knE
b%Z6:A 6Wle6<b%^dJEM\E#?#l!Wh?wBERXi5bQ:88CFPM1P</<H6dtyXHhcIHl\b=e$^\G<Cu4%VH$$1\l%?11
Q:PXwj Pmu+C8j%aZ>1\YB?@DRVFBL4*6cLQt^=t5qL/6NueCdk$5K:AXy9NJuY:CGQk%j89>MHNd+SYKPAuAt#
ZFM\EV n%eD4K::p&h:RFnMbY+m$R:4=>lD4Cq/YL15wnSd4QBcAEVBq1cT6I:!#HwQqtZk5BFw+:DD:kdau?#J
-AH&le 0004a9456bf00110333 Page 155 of binaries1.zip
n\phl: C+$Zk$eq*SqnlAEQi#Q+d%ypXjiEj+PaZeuY/9aI%a6*j<JPj^uj\Xk=:^YdKwAWjbQMRTpmDcnH99N^
5qG&6# EJdn9NM^=S/VIZPEAhJjq+lhQ*VQ6ipZ5mTTq&XKX?ApY>WIdam6DQ==<BA/\>>MLaqIpXF*ddTRu/j6
lRVwWK &CWEC8/H+!P*u1pJ:/dHApBHEq8A9AS5JkWJQy84<XJ1dcEKXCk:ydaHAtV+C>>58#T&XJ%w^NuJni:@
R5yXIA IJDYR/M+mi4a>Sy#X$@Z+Qjb@hkXZu\jVhKtb1R5=tJ>d*4n+kaJANpWJhm<wBbEXTh*HwHbRW@+P6FV
S$q6!H DEcZ?Rlc@GyL1kqPL+69N4Ma9$DVT8cE#R&=\yF6N#&pqRqR+WZHZXmVwX?5>Lbj1Mcd8R%%qePFabBQ
C>jw$$ #^N?m1V9cWFDB\C1VpM9uV<Y&:tR*ZYcM?N$keGb:=lFVLtuB\>5k4ewE?=!1n6VCPWW<!p@8&D=hcNK
KnAiXl 41BYKY/CpXtSkINWp*!&ASTc?@KVRl=iWTInc@Sq#9b8mMIG>1ERbPJ<6Ch??ZIdL>*u/JeQ?cbS>cdQ
ADAR4R DlKhlTWL>CMeN$$@*<9b#/d1y4&!Wj4^^cj%6:FnQTbIju4$\4wcj\keY965m8EqAKDT8Gp%n@q?T=R/
$<:N@R VMI&QZ%1A\hLM1hahp=V>*!Z%L+</?kYi*IC<!\M%IaV1Z&@qBY@Mt?laL6XZ*/N1pGkyPDFku5HXMTl
6?K8?Q Dj/Yc?Hppw\a*XSa6l=JCTBE6^u?<ep/ZZMQRYPFV\S?J9uB?+yHGmBTC$9M6L5eJBcAaYRVQ$h#mwtB
WnMLKp MDCad+P#bdl9mqDhQe8TR1@?&bdMhS:aR6PbyEyVdybZA+%D$8db?K4QyEDYVl>:??T9VDj$/@B#&X%V
+jPd^i 1RKmFYH/Z=L:9+En@bCS5hKG:T\*EdtbS5qe:wI4pQmip:m:D=L8KYM#i&LwpNlcn*mj!F6\CKuFPKHE
FjIJ\J N#:JGCA@qCMPnTZBkT&<1V!4iVZP%DQ*puFcjPh6+\=^MTA=nXLli1>NAB4i&<NC6WIV8\KQL$SR?cc\
$tX/A! BSuH#I644N#WPHRq\*IBN46>%@j:R9FJMHiFRmku!DWSEX*?\CDJ=^yX6^e6!EkAHB#DJe>E^$\B$1aA
pYa$V^ beWleDum5nKL8SSayla#jcybn!\6T1*lp:lDDBtmS8aKItGNEqZ$1cd>K!t<ldib!CZiFQiP&tFVRJI#
Xqc:in qjh:pJeh?d+XXVe%>d#uudqYXkk>Hbhn%4mk$w8dbB=PEN/yD\VKb95IAHAD&6jwnFCWB4M^IFyK4F*H
AE%%KQ mqMCyX+Tqmul4ZB>$Q*??<jMZu4TEy1cK/G$cCj!wl!6bCW4SJac#pI8AcX!KXG>y&iF!NGE944Yu$+C
aC?4ZM cFQ\MFJ%G$pC!NS\1JDNFPWKT^Yhk\n8lM^#p%<byTeB:*MV$#pE^QqbkTTFtd%CidVXM$Q@iEIWBP^J
e!VCt@ MaNCEuL##wmDduhZ^^%^$8FyWceuHWH:AIddIHFlu9MC%F=!hQm^\5mV&NZyM=lK19WCyYE!BbiphCpw
F1KSSG mc<w8X<Bt8qM\8LIkyJQb4HR><k+LtEkBALwna:yMYLGHedkjAHdwhi%?@M#AcTBGJc%WXGG?G8?<w\p
>/e#&R RCG58wlZnay/l6t9mA/ualmyE5h#:uypdM^eM<N^hSIS$t9GV:*Wi/+qIR/kJhjK4\/4yQKCF#PaaW:6
NF>Mt/ nN:#W/*Aa$BR188jMcj?=KYJGMNVC8^=aMWtC=1dc5bj\wA66WG9hiYd>KEK8dj^dkqX!^icZt^i#D$a
M^CY\4 JNY>:!ahM<PF=NAEGi&+M$YWp=G8CYYmlVDuRh>58qNnaFp\cbk>aXh<YJLibITjMmk8dyYT84@BFFES
LQHKtE R$$#nmVGiaMT+^cbi?m=c9K=a*^Wpt+t9FeCy>YA\jE5K*d$*6XpFXZD\=5WIC&J#QeTPPk%$DuGB+iW
P@^&Jk JHe^Zu5#45Q/ch=J/dwW&?>uH6#6#aqlBq&p$!RPLuaQqJBNy%W1:h1NmTwX+6jdq4b8c>MBXLPB!5y$
=&HG\4 dIq*?=yN/Djm?4:GRFRJjE8eNbpW8ZY!pTdWCH:bah\htCB8&k5SEkn=J5wtjV\NmJNp1etFAi+h1q!9
T?M&#4 K&BPLbI5!b@1MDWaXE5Tiy?b?kh>R\>RVh4mp6:+hTZ1WICFDni:nZ+d@l#XDL<^DtDKjV*GAEJYDdHE
#EwhWa FVRmktaWuMbAKuWXZZ&?<T1?:VBBSVyByIJjBJP9PW*JR>tk\#tbM/umpDni6KjSl\CRMH4a6iR$FyWt
pF>ncw qdZ?!eK5VdHHNjbNYlWnqE&?K>umBnM+R!Dcka!tTjYy!F4DQJtynt6=cHd^Au/H4h\!pG<\!Q#D=nN^
8E1i:> kGJqGDMn\RaDL<NY>:=MIaFWY!k@EZdADhPH<iHGN&:Jp>F<%45l$!?>\jSlbGWhPkCpkImwCE$YRDNS
#//Zyu jWmL?/ltdbNLekl8AmRIQ$&tVdn^FNAHAG?BI$MZ#8iTRL=/XE1yQAVT/Eq<8GHl<y#y+m8/IKyT^m9u
qWkX/& ZjJ5a@k^E$RLAZ/cMn&4/c$t*nR!h?5T?q+Z%XPk<pMi&?D<Gn$4l=TMHpne8kpbdVS%QaaCJH?8$E8h
qciNN# !=uW1p\yay>d/IYV%LK>bEXB<:BHa+H1+@DV&DVKD+dMID<kJA>kbuXHtEG$XpW6J!&lakLpu%R+tJMp
jiQZ^J AH9S/+<cYMwI+ka?\PTY!ZJBFBPCuCq/#kA#RTR<FIB*#N!tml<&ywc:9\J=$&\:Ft9/AEBMn/>L&T%l
CVe@e@ t:9h<j4PABZVPKIadcbSRyA^VbDh+GE5ydE1ha<1=eyF11iuJJ$t<<IEqlhyhi+V!RDJS9b:#DAqTe9u
h:P*JP Yi8+&bK6GG^w*/pV%ay?AwCq!9n+lZ%Ju5P:6J9F%D&K%D$Z>WkACn5/dEiZEARWh*%NKDaQ>LP:PdI/
HhdhSj m:i9JFXR$L>>GPSebdFJeX@8waXy\4:dC8S\XIiGARIwXtl=SnPZpPpjB&AuyX%F6J/A9GnmYqSn8yWe
n*IHBQ aVRAQBPnw5D4&kJT/k9q^XAcK9\kSN6=LmY8Y=&TlGe9wcJiDH4XZV%8j>j=BQ&!C@Mm9Zm6<bG#:%%T
?/8MLZ $pZcVLY+qp+TKy%NHB+@t#XRA\h!ISJK:GnSRZhK>aGpM+AiJ^wAd?WK%HLqJAckZ\VE8D=$i1tPj#Ny
q^\yAy ?4\Ld@/GNRp84=cqV=5*wh%p$NwhT$uTX8$PInqwp$BP?55#CV>aN$SXZ!?a8ua=4\&bcZ9%WZ=wZXKW
Nj>Z@D ywD\aWG8eR#>IHE=A$J$HL9km1!L8/L4HVKh!%CA^!Gb59HmV=wSJ9*TdA>pMMk:pjGWqidGidXd89/h
@h#4p# XW/dmqGdC+RNmXjTVRF*T/BaM=q=HLpVQ/YeeZF4kin^I>yD%t^##lJ<JYL#qB5qaED9q<l\6Lj6iNZB
&&Mka# I<y4p:lYFZ%V?#V8wcDZ=?#B!wK&Xu=kHJ9Z1/BND9IYWMBLN\HW*5l\*Q1Y%FaQWupe&VYXjpGLuQp&
6?4mEk u?^%et84K>Gt$YYJ1aJb*B8TyD8aXMAFe=&V#jR^8d=>EL@%KPh6*XpC=D*^XYQ!GbG+:9JWu&YLlYwj
KYeWtb &Yd9nQK*XZh&XnaBDK!<HPZ$InK*M49cM?:9byV=p66<D44<tBwANH$=\h>&k&wyG%WbDu$*puLndmmR
C@\Pcb ijN>j#V5D6*$#b@\w>In1bqe<&4ak/ZEljt&!VABAHnD=i>:Zj&?AVN:t?N?n5?bbhZ!y+QmmCF^:wN:
W<\K/D *Zup<=t=ib?VdjSjhW@S^5?@9jJ1@<1Gu?#/p&qu\DatF5bED:YbLC:hkEpC5QD+qb@dWq4RMD9b+SZN
I#WHNP 1SwXmIue>a/C@?P4#YeBAe$:Xy@&Z9WiiMVjlHM:Hw!@1?wN#Lm:5@Ay<PS:+MHmY+:9l:TWAa+@Au>5
!yTZ6= BcG#AK8V:&=VHCwBk/yPk=#wk#nyD/<^?4&nDm^kP4#N+H?d<4CA>ZB#KdCbPamb=hAW?F/J+Z$mS>Aj
lNq/cl $CB449%E!PF4*tBV9tBc#9eF:P<ju\%lbu59JlkeCH+@hjc>6en:Lb:kC$LB6\ZjQ?M=5la>KyA<+n^#
ZHuiGy NCWbeqdm/KyemB:@WTI5=Bum!FQt/A@yWCYypHM5Ii<WRttXR8ZRS/bKH?=kQmT1juk5G@yE:aQy8XBt
D+XVEA 5VBt1YNcVPmY%we@%I?66eQPKu=w%np&%R%V\l%Z/^=h$\9qXA/djJ+E?4PV=Q<weYaHa=VVD*B#n*S*
$R+:aM k<qy8$h+8:wV>DSlTAWFGB4#>?Sll@<B?#MuTlRC<*?TE/Xq!4@XuNFZVNHyNNQwYZTj<WayI&4K#S1X
C:4P/W #1C$EC$q5\H!i$NWCI%EAwaQDPcS<V/4nXk+QHc>Rwjh9RjqTmeZ^%\nKQKt$EXJ/Hb@iL!TdV#pZ#!@
%I@C*X <aR4WEh=44nc4w%nN@4Nm=4!&&<S*^S9B>=?lyhNmTXABJ6kBFBM*Vac&metDTQi4yGm6PeV1w&h:=Kq
a4JbnD #$#n:1Z9k@R$%*?ylMC>?>V=ck^BYEuE@?SP?WIbCuR8J*DZMdFy<!W\!d?FaVT!I/AktTITW5FjKPB%
h!1+P/ %=T9Lk<NXjpYVGtCn*S1EBhhKyXA8iKPGNZIDNpdN6#hk=JqPp1R^8qB=kA5q4B=4:?i/NKl<&FSA\n9
w>aN9L 4dQkc#Y#6/&YbGEVwT=q!T:l$jFdkW/Bb<e!we1leh89GIVKc+$V1III^*hp8Q!YH1%mN=GQApBdCKPA
BN6l+R ?#+KciXnL=T%>H?PGWLJWJ%#FdppF>:/6<N?*JWEia/1b*9q5q\!LJ&mWQCBmk>K#V>ei+ae$p@kJb6>
^C&S/& :BjAyiP<k#Lce616%Cb1^5\Wt6wI$HN*REhwhcd^Wb/JyuLjTBw1%APP?*J1t$@J<9+1mmyKl&a^>^WZ
mG5lQ^ *ZkN$9MTE%@5?$b#1/F#=8SeQk&d?TueedXb!8B$*\y*=SLS<q8k!NG=4Ddu6cJ<V<QRN%F=\6ZPqquA
%EV=$@ >YZK=5W#dZ@$KLy8F#e*VCeNpTuTBd#qu#1$t#pLcK<chu+1j=p^pSN\9&tPRD*Kw:cKe*6FnC\mIV#N
?mPl4a <+^N@C&6=q<btQ9in8&\DnLu>#WNnZ#8H/ZaunAciLt%wbNnujV=*dP$=#DqyA?Gjph*tP+*GJhZ8db9
u*%$5B 4S4FNN$@YdMdQ*mKI1pab+D/FI$LtM*c^8Y=AlY>4qW#JkR$^%/iP%G\my?yut*tVLn\R99qtKJqD%TT
FaYRdB ^nd&Lt:wuRw:SpZ6c4DSye8!/JWDJu4<*kq#%dqPSTc%98XhqiHRM8N8u1?TIh$Na\yMFIb6Y??@Y9u>
>tDw9E KL!$EN1e*uMDFVXMkd*kC#!m^ML\>PpG4nRWbmQhZq\?>8*jAmbTAGhuFeFWjn^Mu4%XD^Q#B?*6PRPV
1/ywTt GYHA/Z:KPX8dCEd>A!&>B^$W&IlL?Jp9*S!!%dcc+XGMGq=1PqZD%+XCL1!WKN#=<CB<\p<@8La#Vwte
DjkRX& \8$R$<p\^XBZmS*+qLG4=w5\RIlPL@RZWqc/BAKYYn&<jNt<%>WRJjN%8lcBb<j8Phdi9hyaEQ$ab4l#
6K=J>K LhtTnHI*PnAbJ>lQpwF1/$9nD4/%p5&DbapZ1Z5Ed#w/Bki%6m%cYS4Z:4958qByX?j&<e=JZ&\W&ZwI
@@XiT8 6W?dYNcXu<+KKk/N9ieG9cya/%dZncH8Em41InWaT?yhn:m&>Q=aSj4<JbpQe@LejmYJatj&^lPR?aVq
I#hb/X &PBKK<?^#%&MypdGFmMnCtw4AXGtA8@ht&\?6/KYiQm<N&uEkCCikSkcn45H!ic^tth%?umwnQ4M#XuG
Ty#?8\ 5n@M$#96nYbt&Id1wh+<Y9N:Fhn\WKITN+na%m^EHb9E6G4Nj<m=i>dcVXBk>APeeTQdWuYu=GSwD8@9
-AEkKE 000f3c3fa5500110333 Page 156 of binaries1.zip
6!q$p^ ^X%+$W>HTwq#9X5LF5+R>4CbAEl4!ny@pcbuJ1Dk5Gd8LYK+W9/ye!W&i>EG9GCRpe<n5yWTPqYC#yKn
\:6R@> j5*:^PbGYTHc:5q$bt#mayS?/6YLdGcK6hWD!++#^<B1N/ZJ:P=B^>c*tJ&:bqNQ!a@NuS@aiS<+1Xy#
j<$*EE dGcw8YSik*/?5ZV!5qk<4D4F&@t8IiZaK@jL#hLE+<=PjGiM^wJ4<8lFY/XEe\&N%?1%WR@FMDc>pth$
GWHN49 9D*E?Vw&Cy@KkQQ6yjYDNKt8&T^*9HF4An@Y+Z+W!H1^HC&Rmdw*aqD>h6DtS99uA::&&eDc>=kKL/:t
GPH<K# 8L!#buYcW:cT8Cpin8>Yj4aYlJEPn49t5Z/td*9hkEhFe>*K+e>A>n@j5ZKBMmtSbBdXqYBVc^GbyLjj
6dPFG# ?+l<Li@N1IT+L>P+!#*QiWY#Lke>t/jj6K^>TnJJQkc>JCY6Rw:De5XKA$*8G5hkK$*=>8H*Y9wLlY>4
=mF<KN u56*aVP=MlX\hCKTGk$?\?<j*LlLi=bn1Rl%1@dLSdPK$&^SN+#jpw@WRKQ&lIR+JXm#^Ke@LJYy^PP/
m!iEPp j!Bq?kPdW8FZyG=\mN1QpjPZYKSX?/Y&\k%n+$?QG&Q4kp^KLj&ihN\&k:lny5#Wd&I?a6k6?$E94EmV
Z=h%QY a$LaN<J%F#d#4ID=$X>RSu@a<y1>^L!QGQbG%R$hl=V=i*#AWbu:YuaA!&dIJT5nLyhXZ85e#auPK*ad
4PP#V> 1>&KcR^Em<dj6pquhDtt+kWtA#kiyTWYZ:>!+cFm:5FP19LLnj9dbSP%=69t4A<XPm8Z:kYadE&w41KA
J$T<wp 4^SdNLb+pCiQRV<&#jbNJeb+k/@dFN@9aB6KcPJ8AT6K:!ki#VV:T6WWIja=A<^H#PYYBJ!19M6LG9dS
\ie8DJ 6#\hFPLeGXeb8a+u9nanYh%L:pwwt<ti?R!@<?nd*SbK@:lLV=FWDhPM$Fh84SipHwawLNVJ%?id#H%/
RS@qVP 8JmymPN4ZbC>J*4Xw//k:!=j4V6Dd$!hCinBhajWt>j4F1XdQ#IdlI<?C4Inbn%9JHweSi!HYm5+m95E
a8+H^H qD=8cwK5eNtk^8!j#wb6cX&chFJ=b6q=A<B:WHI$bYwiqE@=>Kcma/ba\:I?:V&P\T5ukaE?jkjHV%QJ
KXRwZ# Z<XjFYV9:n%<w$?q%%bVHC/C@Cm=nHF5?TD>PkNqy:&!JC8=HEX4&#RjhYNJ=T^w4&l?S@*16jNX<=>Q
Qmhn#Z L6wdZ<p9Q6??FKY^QH<q*=FXY1?A9e4<XuQZtd6mh:=/>WeGuna@ij11^mQ\4PRqi@Wd5$d=e&uTh>ih
*?C^mj 8?\SLZhTdS#5&i6dukp$K:><@<=EX:%VQwj:R$ciNL>!QMZnRJ\yMt>KWcR?cC@^&$EmE+*eah6&%D6e
*V9^GV XA!IPBXut=4?!ETepI#%WIE6pWndDDIyRE<*NZy+T@u/5c=5uPFi#lda*GCdSJ:<5Lq+WjLB!h1<RbLH
4^#\DN 1be*nVEqYqTGe1RitNnXt/!eZM%Fw4e\d4GN*^G@kZ%LYSNdpRpatM#XQRT>dhyy46VipV*c8Rb%d&4B
X6B/8+ kdy>lMw&yK=e4dqK=/q6a6KhWS==JJHh8LuhJ98Nwjwq4et5?kRpck*@KGquNY/u^i>d!nXhX>1t>?5L
<#SL&$ Idy!#QCqeMG96Hm\j+&\4<jmueM\P%4hP@6:#XXS?*yNVHX9ZK@Nj5JFqQd9R1/N9<6wyK@l*+/%F+9u
YuT4e9 F&/wmDK1$>%jtS?Ly1tw1W:*i\<CjBmD4$%y6p>FhAl%j/%hY9VC#nP=QDiL+W#q?h4e#ZT6tX5tqM6R
5LIG<y >%N=$k>E=Di#CnR<@unNy%N4>6MKQnWS*JteQY*t<%D9kb/WF5?a41Kb6qJY=^tQyDqt?&J*m#cD?TC^
CcQ#yX w8&!S#*Bn4X\/4hiWYSt&!9\aPyyeE^4ItnjjwG?^4<8tTeJVc\GSaK<XPNmL+%8J1iWpDJVLE%nI#QX
HqKb$K w$i?mE$@A=SjylA%CVtIDp^5F6JFRGmd>J8qqSGHZ@S^@q=4b$EwM9AT6jbL+hGG!%K%qC\EA%ij&PTu
JmAdZk qDYZRIjIk^b??>u+*ERbpeB9ihhRA#M865E>:jELhuE?u9Z#Lum%5+lMJ4%5\@1#M6/WHi:19wlR5SDq
Jt6c<\ k4l:VMGS94VQ/IQLdlL>:GW8<p/wL#aQPaaeb&d6jRJF6:?L@Ek#dnj?w?#c561WV<8V&P1$pE5IWwq@
^1CAqJ M=>B=FjTc@m:%%RXT%@F$ay%n%uLjTKaj!VF?:^%ZTuGiSYAGX^GZ#%j5=pCAX1<&$\DdLN#w69TwkI1
8G1%h= N#ni?cquy9t8SVq=>Dn$nMqu<B>wbdTAZntMcBiu#e4G:w$%yRBhHn$VjAIV8T%X4kwcYyMX\RXI6m1N
BXn<G+ #ly1SRLJ?Zb45ZTNt<$6mpwdcA5DwkI5YMKZ%VG8PFhK&N#<kZFhMYGZqmYuA8W6ee=jRtp$kppuIC<i
*EeS5# JFwYAC<nIZSmlh<RNA%#kZ$+GeF5G5%<\REI4AKKwSb*ma*SK9ETY$<VD4Qb&c\Rny&YwF\RwF!t$QVD
^?!JDd VwRkBtGcKEialT8P^R1Vp1mNlWywZ6iLbeGXBPlR\TT%$$S$:qXaZNYJJTDjVI1WDPtWPKJwaCDTc#&L
9DHVAw eRFl5HWqVPh+uyw!Y6njmJ4KY=8!?:!Qpd<QATZ$LX6W8q<?i4FTXnthT%F+WX%**q=G&NhaeTp$?qXY
undY8< mw4WS*^Dp+F4G!m$/6B>e*\9R&yQm/4Q*quaa<AIWp9D=!NJWAi#PqBZqEpmZ/WA<hupV=ckewtqyyRR
=NDbyW ?=u+p1h<C1J:F\i#<Tu+&\Pi^l<G<wFXd$MZ@AdQc:46cybAadA@*h9>6Tjl9/i9cj*>d@*@d6d\j/VH
&/TEp# @R*>6%\+>N?L*9^%T9H@uAu*6@@YMqj<S$deQ/ee@<<q49?^*>R\%>LZS!9<je@=H*6TDB4?u@cjwYl4
iueu?= /jCREDquH!5JT>%AdDBeTNlR!XNF%mbRVm4IMhnNYXnL&NyFI^kh=CJpKl%+Dwt%hLj%<4MTC>jV^K6I
F1K6wV EBnBRja!uwwwb!edCZ$dY&KaRdC&wCQS+=!+848au=8:5+t5e?m=MAEDjLCkna&c=*pqV%NVQdTSnqPk
bWWmYK tJbQmJXLpCan&NhE*NEFL+pI5=j#IlmwCm6lpadB=+*ElB*Pm&4ChRQWWTEwaYqneREBARh>Me9#cA6b
/4$!iK FM=BT$YcwPAS:ECRptIEC!tGGVnKBAkbwpSpmiF&jwb&NkFIwyGM4#>eJ$\M1TPAR+kVFbTD=P*CLiW$
h=BLVR Wd:iAiLcduKYkwJ+Q*\R%l%BbARLY511EbZW@eWhZh*kIVIB#8d/kWkbAS546K?^k=8GpnZG!h:QKqVJ
++=<!5 \%:RY<dAM5SC*pnLX\4l:/bykkpTWdEVaATj5<TK/^pd8!qn>B#F>Y!pNZ:?k4&hl/KulKmVpJY:Y+mt
IBnE^B 8HekP8!eC%\WH?KqKBqIFDEKCjYXW4WQ5*DX\GwyMaLSKF8MpayipJjMPZWd$^Bdb!YBaK<RRjH\RGMN
w4amKP 4L*/PShXM%&JWFEjlLC?6+8by4@uiTpBnAnS@d!Htyc>eImQJCQa&>#LkPkRnk&D8#un<LdmEn1lyndC
qITj!1 GpFwC!9bWL!qWymI6yKIwd?/lIPlp+c$ydbamIhj5I&#9+!y8JmC14eWnlG5KmpkI1RRc8ila/eq1cl%
Pk&L<J *p4Y^puMJhlA&5XRK>lAM5BCKFlH&5EXyiW6KCC64TFkFtT4+?qt=tS8R>B$qbSTM&eEi+a=&wqJcEyb
=ttJ>K BJteC@RN>XF\pDPXM$a1B8BEQEPqqAIW^b!%pHBlAVP^AFFb*LqR9#B=VXXj8KY=IN\EhR=QDGMEt+iy
\<BmL$ \a%hdP$SBI6ke#qBTYFBCSEjG\qXaZ85ypmw9l4cV>jSKpBe:y!AJXFM$hJWX^q6+TAcAnjRp#eP$EX=
cBnPS9 t#GC*ZTCqN#N%ZAT*yLuhH\>QNHBt6cP!5F1=$#pLQG!!8blkt=m$lIm&ulueTqud+!tpa?B5wte44Ke
=4?*JJ kyi^n4&D%5@Zci&6I?cpIGCAE@eQe*Y#>EYGiclwtI5SLd\5JP&54a*DjZH/aSI+G^$C$ekD+Tw4atut
YmB+#u mJd^EaE4GmD\Pqd!cEc\4cVcPZpBi*W@ky1tkV*KV5\Pa&#u=PAia841+mbmGiB6G&ywcc<9yBGkb&Pu
ZbQhLJ dwhE8ty:C19wY!QN#t9k:HR$qSuBDqIK&p=TwRawITYCB>\daYBp4p1\5:A%FjL*hD<uGKR8Kl<XFZXF
GbY\uN @W<HQ5Z@mmeBBwH?b$<C#L<Xmj+hV+L@TCD?=:Vpj$&q@u8h4:@&FeCk@^4:K#<DDPc95d@\JMDA+d?B
Z?T%uK @ZNQAk\e<hhaBjR95Mnj\Q:199K@kWZ>Aw9/DT#!F%mF9<d?\peBA%j<Dc#TL:C@\c6jPLhm+L@BK!V<
uQC<^V F>#+DX:>!4<Bk@kNamuAFj<e?^9E?wYQAkd^G<V/la<CBmH@*&k#/y<<Cj/P@H@!JMD<n^JRGQq@NjdE
e+HB9y IBV?%#$JFQ:Dp\D^<+4@+Wu\N&?BQ*Ep?E<LMR^C<V>dEtB?npq@:WmAS\6DKCpyakApQJ!QlTbJ&<WM
Sma*11 ZYEq\=tt/+1H+!TlXDS^FCW4pXkl*q\Dh<JhN!NlN5wE!qI9tD&et>HR$@#8?1EmH%Nmteb:RL!PYkZB
?c%tM% &\#8BhGD56Jy#>?46ACIReE/tm*+Fn6ic91ENXDNkINd9c&u1$Dl6A<DVX^QuQMD4!B195FELDc9:45p
dV&bN* QhPV8EXab9R=tKM4Na9+qYN1Acen5#J8%4MR6m^ed&R9Z^cuWA\hSp*aI6hRXH8p4LYCCDhJba&4PCIZ
KXZHP< ?LPI^+DN5CYRcp=JhyhKq&=I+y%%DZ1A@4lSt/*M+Fl5dRZ8umMq&>m*+qWT!DtqMC$+/Hu&Lk6dDmt?
KluB\e ZT:$:kY1RTPkX&@S#H=5aYVy#JQ:*c!MRwR9!cu>6plF^9KkX+yMXEu4GFJe!iRjc9&SII1Myld$jDt5
JB+l<\ 8+bZAIhH1%Buqm@VM/*ADq?YWZRj=bT:pI:QM488G:MBKZAk>qT@dkD#6jLDH=Z$yY<BalBl!H*i=nh9
XhuE\j kZel<SIMWkuPc%iKp+W8M6*Xlkt\mCK%>cEeLG:PQH4WP@yubejcH9SWbFQ&aHF%5Y&C?5bbhGJK6aL^
9i15+^ YE4Y?DyyR>dXiYR1=WCRJnSXZF^M6hRw:dV+Y9a8c\4#tmDWTLBmiI>JY@kyV\#XaRLMiNd:LWcS5V$E
ncmt6& VMjYT1icVCqE4JE^Fe4hA:Ah^$L^qlI41/4b=5bPNkQC&aK5VJbHWQ!I&/$m<WYJ=#^tnP%Ed86$iYjh
k/nt*k yN#<MM*V*K=ka=>1:Spt<+ua<@maqIm>Sa5!tQFAAqYqtdEuQcitnYY!c:8YI6$Sq/&b1eB=#cR$yZ9R
ePpeED e?#=\ZbZSX!JIQ&<?Sk\M*Z:<LDCG!<!d/LnSwS+H45ISNy/Qa5PaMMlu9SH@4K&l$p8bd?J$ZtQPJm/
K8#%Pl CwhZ59iN<*%XAiuLInWANw>+LwAhbD9>WltBS@EcFTtlt<JnQcF9&CBPQNt/npBl$ySYIFS!V@cXVdB&
#@1lcA DEjq$+I&W$E\CyjQlE6WK^hIGkCA5dCaSCc*mqt?*P&pe@iM+**kElAaDL6i+H4>LK@k&me?KG9CJy<n
ETC^1Z Kj+W\Li@VSIcMm^9p&aFETZbS?:TLEHbM/R$Sb$ACceAdEG<?\GSt9R&dmdBK<q=Zq8cIE\QQNF#GnY5
A1$#Lc amGu5GMFp4lwilF&q@JYAFcKAByA&nF4MSdpW8bBq/+cF<@=<6PQ5>e&Q9?+ZW9Ndk$#ENbI>5BpWqA9
<<6jDl n6l4nB5CAB=IEtCM5WJdqq\>Lk@KnAkK9AFGVm6#kyItkwZR9JVaL>%^YbSRQ?u#qDdeXMXaA$F5$Zu/
-AMD:@ 0006c3e48dd00110333 Page 157 of binaries1.zip
Ga#9S/ ?CP1unAEGV@Jw&Zn#:nc\?Sc&&JQL=KtwXF8BytPS#eJw?q=V/hw<Ilu!nGky8GjN=#Kk>!uC6nLA8XT
wjXNlu >%Auy\SFRKt<8ukw8D%y+?yR8uAA5BTTFPN86AdM+1SeGbJ<TAqqMFyqA@jl5eAkEEPl=mTQDl?AWaqX
Rh*@c* TLiWlT4\in6L$D*+EF6&FLP?TJbPu&k9@KtA%LJiykC=aVBXWSB58e:wktKkZD4GWMBp:46IuCXHZuE9
WM#8h8 yXlNdFGt//WECkL$Q%AR#JkuYnPEKC*dcIL8!%HXQLN#\@1yP:e>H?=iCwlnWCbldTYGu4P\VMIN#6BJ
QVpSQP wWD%$n+pBqd1Xn:/&^wRmQ<$l1/*V6/VkwNKK@kiI<5>JSL5p1Bkd^5ah8?MXmG$YBnQyWMiymjb!LE^
JN<m?W EYQJm5NAAQXbp%\tIPehM#Fe+d\jce?JkWIFKq=K#j&8WCV9TBnTA$8pIH*QV@?CP86NB&EwqRYD9B>y
B>@j$X cD*Q#G#wnGCmm#HT&DcNLaEEbwu5wdGAt^+pJ4I=BHAYYQiJ#mYJM<qeqTpt1aiBTqmDq8kD$e$J<eNC
*ADy++ NAAA6^Gcq44WQHSMjMITjX@JR*wZTLARJWmeEkPl4+%PymW%AcmplPp/Y&IyY6IkkMl&CBXYP^M8!K9H
@jKP4d #eLV<!&>9VeF\^Y$*BIQba:=51ilWVktKJTZ\%Jm\6I498p<QnTSSeLK+bIpkkj<yEuh4>4#cSwFX+tl
+j@#Cn YT\SjQy+T5hX!ph&bbKe%BI5FBw>iY1hA<1!CE=YYNNNE1CE%m>b+5Ja<yYZ4JKKYBFnAMZdl8!T=ain
9A9@+& :K<ETVa!+DI\\l+lCcqQ+nTTt6j8ZZpLK/<V!T=VuRt<!<:RT+1Nc+$\mN&Y6hh1BtSySFEqmdhV8NXR
W^$9Q> a=X$+uCbuX#WWCYHYd\KJ?SmQ*PqHAT48bPM/:W*q&QJAqChHabh8cBhXhT\yyj1P<%5G\?mB!/qGPn=
tQc#4* VLJXY@NB#H4wRX#JINdV*AHL/PERCSyc*a+ayy$\A?PhS<#u6bNwuX>lN%aPSdC6V4Ty>RYW^DM!ZHYi
wM8LWn &bpD#a%pi<8N\^k\mRRe5iRleKhmILmV+^/AE6%/#RZbRSmtVjR!AQBAKSQGyJTM/:lNn\:bnC=nFbp8
5>j?*n :Xu*w^+VPbAQ/$K#98GKwW8N$p%Mi8qi11K>\ZJFARjlw*Z#m8kn&:J:A*X+KcbW/XdZhVZVWV/pGhcN
jclCED J$GmMbi%BXh/<Qhm/INDJF<cXJNTa11AP<AGtqGlH6#epdD1<R$B*6L%KB1NHTuNuql?#Y<lhC%86DGb
=eJCb= SnSWNbiaNdLKp8=FAq%W5W^\lbwL9e1<qQJYl/#=YP!j:K*?jWu\F\eGMAnMQ^$a?QiN%D<jGICnqQ:j
JQ+65A PDCRup1t\pE#QYS=$?Myb\amLEKRjR#V5T\EmJ\R\+wLbeW+XItVTXewC>CZAm9B%<Rllu95pV\++cNC
&uYPc> F9\LWLtXN5RL&%WE=#ID@=9mn+it/kuG1qWqiucp4jZFMqa68Cp8/Y1bcXS>>FZmMdqRYqK!HZIj#KD$
J9IJ=R VcEcHDnpI1Mb8#ItE@e*m?>L:9eY\wh+nA4:bddhEF\y\Mnitwy:FmKcwHcmBi5Fi^1ec^>F!+1ZLB?V
Cd=1q^ eDqQWa&hZGF5>SP8?hALD:uN%&QyWPZyJ4^QNmG^*cTZNy!MbJa9E/1?huG^mhDX6Qww^C/YZG+1Ql%5
ZjD@HK 6#/XIt>e5iJTLqq:qF%c5+MCXyJ>1KJi$aIBQuQXKh*RcqXV\bRQc8ChS%\mln!nWD1yMTR9DSXy5d6V
JPI$1E TF1dY#6P@CWW*w>dqt?T+IW?d9VX!ylMcQbbGTi@H%%nbT1HtuA$GY+@+cPl6H$JVbAY@!BKJ^Xp^nuC
/BN=Kh mB99GEnLMiN6cSm\GZwT<wE\4Xi1ZeA!um$<DpW%ZuJbi4R#:jL%D8:Wn/hmhS^Y4/ZQYqI5VTKMT!I%
umBL4j i9DKGc=q^:#\Xl9<5F=yIZ/G#Ebc:J*W:$:L\+4QpY41eY9SMiS*eeZeFc5=CcB/mLR<*ZSiWw%KKZ$J
!y+wJ4 RbLS+5MFjFe6&:=!hc^RV\9\a!NDQ+JXmJdXdH#a/=FP&Bn5dwi##?u5RJccMw$aP&ZpdcZXab?ZNZ&X
56H=Q* /ZRXG4Hl#Pj>YI<@D8&Nj%ckRXtK*^$<H6/:I=<8HcFpK%W+=$5tQPV9ZPuGVR?&ScS<a6XNt^C>+/#$
MP+V?n k$1Yl9WDY5qIw\GHew4E9hQ4SD@h/S#aN@k&Qn9BT=@pHGQCtL%1^9M5=$uDJp9GCkZ&YibAXn+u:+5D
#@wnc\ bc6V%CiFXFe!<<PXhmbYchP!BIV\M:tEey5^mTW#w^b8y?hh4I<N8+hp8hb&u!IjhPiRu^nN9CDmPiXM
*#jdFG m#Scb*tAc#EK!k>*?ycpN/ilV48*AhAkP&1dS@1Z$1/y:Q86IWk9yJaYik?YR<$u=a8pX:5J!>%+npB=
i!jy+R <P\pm6FW!JASi5W#5^Pn9qb\hLMi5>l<c=C>6jcGFnEiHGPb\jZk!/**dT=jI%edY5&m6mRij%hS$=F:
?KyuZ+ pRHt&?XNlbi?8BLHPb5kTVJ:Im$hPHF=ieF##CkN/ZR>BuZeBT6hXa@GDbIhtF$<dFM=w$j<?iQIZC:<
jJa5*/ #mXt8w#*8Nh^ZDH/SXjpHya1d9y<GZ<jdVd196lh>yKm<G*t=WB@XtyFQ$@/PnXuthZmRu#t#u#lBd5M
lIFm\J kb5e*b/W$LEc9bKNQZq*/iX=Rpd$hHl<NTib5qkKL&$Adiem8VkdT^*m6q8Z&q*=u:BFmetV$*j/!$+1
ZcZ9e: e%*=GFw^V?W<Z6uqnn94?iF+Gn*R?YNL@kEGcwaa41cMGdcuAWCwetZ5K/i$>RmEwR=HwSb+m9WdChFp
<=1e/9 >pjbwDRjqYT8h6INWDWh\?DMaukt1ZSTc!G1<uud>T8pYbW!HMkC&uE#R4^Ll!9lMc8%M%FTVpIp9@QE
!Tb8GC l*CeI!Q!*4jYP?TlC+N/>kmFIX#\qLjk/&LB$e5Eu5KnW/6b/+A/Y#p1t/k?P?/E@Cc+etQln<?E??\/
aHLiC1 GRHPSmP*+cN^KnLn/Vj%+^?q>Na4/FXXMa$nV>j!C<Y#Gmb8C84<8PatPR5H5q:T$tFH*KAWT65?<hKw
+?6bZw VXAk&y1clRdw*u\iI<aayyhQe*qh8t#<nZQ:>LZ^wT8%/GA^\WNWJy^Aw>@#FyTdykRQ9JE:&&L4jN+u
49uj\> @=I<S=cmK$?X>@YE1m4JpyGiX>>!J%S$n/1+=&*JZI+=hKHm/tt/G=Z5<^NtAej8tF^ZbEtqpGt?YNe%
uFh:M* TqI6w?ieD/w1lFwE/E!huZ4tTyJ\9<d#/M?EPF=6n!yb6FeDtHWyyRXy&&YhCyw$9MpK#K+<K8kZPW6l
1L*Y:m 6J/lKGEwKCLN8:8j/F+dj<b!$NX/lL8*RRjNS&YbjbSYi\tW8lFc<PK<c<FEGK415+=\T^BnwWFG5cSp
G:y5WH i^#Ja<u@Qq&MYXec:&/wb%=qmTV4SHni^6KSm*M8e1kn*+=pSn>L$$VV8TQY?8!hHb8>qk\!/1c/:/M%
tJ!KRq *yHcl4e6GNHa#eIT9?dI5ddbyW9qQl1%+ViGM/YYlyV<KdRlN+a1l8%>AR5cMhF*1yNL:LdP?$yTjkaY
6Y?VB! uAt<9R:wHt=SRNMk#18tKb1^ne\DJ?Be:BdCCe\<NF4AN%9<TQYnYJm*KQ8kTLjtMeP+bFIc?kY+>mnC
Ll<I8Y %JK%&1I8*WK!:J\En$5#Hn#h!J8CVk^I4+>1h86dW:d!ulP88j!ePG&mbi+8E@:T!EyYb!H@n@VqLk5c
m\E5+^ m5/6/&NK#9Qi<c%bR$>1:k9yTliHVLkQ/n?@<T^Khp>cEyRq&V^$%CHtH#GPKJA=:$Z6^DHGP@H$S?:n
LCn&Sd hn1i$Q6FLb8+GmP?dhj&#8!+<^pY&!Z>lX\^iHPB^y9YBXMlpl?MwnuTI=1?qn$w/QnlJV$#^CQtVuJj
W1qujF :9e%*Mm48jPa^Y/en\cb>JA155u?iFPwHFJ*?b^len&d!@hd+#hhWFk#\VM9KQ&SX*$6Cy?*dAMH=XBu
bq16WS QRy6/Q\+=*!8mihwWCE@k=*kjmpZ5^1ZcTe@#Gw#!916V5IL?JLSpt=^M&@C>^ZFd6W?=Iy:N4K&Rc%?
w<Gi:d BtZqe&uqyhGmR6M$e8Dm<%EVT9:u=ucSeeNVWE#^@I$@#5d$$<*lp*$<u\CCI4/VGiV\<*%Dm=Y^mw$X
F+T@Qw +=Vm?9n*LW=9Wtci*<GGtYPa:9=IdiX:E4l%KwCFhpDMNMb8?B>8*j/MDh$B9MaWVLBQjHqJbq^>GQ8?
NCE$m8 ^+!8cipi1WHMT8VdH%QmV/D=I8R&M6iIMu&$@eaC^<X1Pl4SN\9NmSi9TF6@$Bk9ZL?bkw!qLBmGyhm?
Clh!TD PE!VNj9CedJVh96#wP>tqPTyp>n4d\iP^<\c!>\>1<KmH!6:bC@qt+^Tu5w91X$BQSREiwqheH6>LjAq
h%>i>Z 8%HXh?4$YFPS!+?8hQS*4P:AJyaCSpQTuXS99*dM#k>i8EpXy<nK&=<6XYueVNXP6:m@?\j^4ZV+b%Qh
IFLhcN y/>R#aS^:n@KH\#6P9<aL@q!ech*!@Gint9dbbQ^R1Mje\cd1X:ECSQ<%Q4CZ9*$J%MwWMht9Ap@XtiQ
u>nRLC cu=\FH5TQ8tZ*aSuTy69<b9@Z6EDu\c*%uZbGwP1B^#jcT9/GJcBKbiR^JLWHw<4XEb66PypYw/=?P!I
1Jtd!y J$V@EVl!Ip#YA%dNdBNF>$A8<VTt/R%D^eDX1unj\:ILRjGw/uHDKRG/Li4e4i8kVik5R$DlC8EGpFA>
XC*P!l HVX$iIF8K&^%8yIB8BqTMRIi9EM:nS=ju/QZ=&kiMZ48c@?T?6H<65p68k?MqSKkhNL#VH6l*eX*DRG^
X>QlT4 B>l8jT*K@cSR+cFL<PHDtunDGt*6lDbeqmlDEL^yw/J=$5II/\?q4c9!9M<t@KkIL<?&%>hFJb$>=6N1
HGj+1Z tGHpKy#GI5ai^^BI</m?9$#Xy<>BL&N\6\#5y6*EiCR#uXpCdtnc*NNNE6b=5*BJBMq5dMwLwqaR@:dK
R<9t8Q WuSL$&behQ6a1yH*:VI\h5HaR#F^:<AYWhFEk\#^+#=#:VapTIPXPMGdKMT9:eyKjM&:!ewkkY1btiC6
BL>4@/ a$&548hul14XMn$IkcAwV$Ne/ipC:e&RpFmkB&=G%I@/\E!HK&u$u4hL<WJ\tpMm11FeX!jDkhLkRCen
9HciE% Se+hiWZ*T=#ujG+GN4Cb**L<5K^u??1%wWty@Edb5@V$TZJ>J+eyjDwbe=Sc/1*NA8LEdVpppWRIF9G>
@$J#pE pn*4>yA%8>+9/6#iFdEJF&B@*+$u&R=8m9iw%dhFY!ty9cEkeJQtD$KQX@*?DVMnq*V\PwPH<KYERlSL
aLFh%K #!Q^DEWZcVEZ5ByeYJ#?CnZq8wcPI#4Y>qK5XhiK9cSRF$aVkwu#/a@6SMcYI&APmCDlEYE$NYBIE?8w
E:89&k LVRJI4$TwDwSEQK!GMTJj*Cnym^Sy@/8PK=1Pt=pJZ%DVZD<+VBHtt?tA1W!epA&ieZQajiGqp9hQjH=
SL*TtF EumAF<%nPPuQ^i6@F&Q?Q^T9@:cLWjk9m>hK@+mh@yN+@i>dw><W4^ZS@!Ji8@8:1T64/TtnjD\Eju=J
F*yF^Z CBF$hE*pDW\\YkG/C5Fl:w:uQh!pHPXE#j+t/+ZyC:lnVbYR=&#M<bJIRTqGeImKPp4RR$>cGtPM^I1H
>bw@EW &tqJl<8HEC#MVPRhHFVeFY#WdIZ>9PAl&4IwuL&lIMbX$>nB!SkV18\lFwcX<:J%etWEB\T=!1wFclun
D5JdKp ZWWN$CGC&8EaQVuLAB>*h%Ymyb14qLJ:YIC&kR>Y*W$uSA5qkqI%NkqYF@P!S1Me$WL&CI!aHTManbe\
dD4Ww/ pnC\DBBBC8pSR6#@J6PcY!pw&eqnR@\eWZA=IRFyN&i>AF%H@YB=j\FXHSRe1*\8%N*SS%uXDG/kl>Bu
-AhjPp 0003e385ac400110333 Page 158 of binaries1.zip
J#ecQ= BC51m+i=CIXc&1ky!/EI5m+iAaECZpJ8SAhdTT%CpI?b8ITjqycqy*PRQWyHD/>n+&9ubitymXTSNpKE
aet#eT uBP\W^NnBAj4KIbL/PywY\eFPJ8FBRp:GItIEdB\R<&REBq#HW%HKVe>Hb!MkIG:qyKeK<dWYApnii+e
+aZ*!t ZMbP#NyLRSW9:YjBCBcX>hD$pSC%>9IXDljV<da&D9eSF$blbD\WHRkIh!8<w+Kl5VhCQFnJ\>5yRFIw
XiW!:I MJVwb&mn=G!MW@Y%q$MR%iWa\RlZiZ8E8/ml64/96=iC9/t4w:tISLB*aJmbtL/Xkw14l4KkRclVpL>k
*!bJkP EB:6khB#$uFZDA:TNQbFlupJBtFh<B/MaB6SFc<AXRqZL^WhX*M6#@N&ZlkLi#5Q6I8n5y<lEYpJN@IX
bBlE*C 6JRYF#AZFD$Z/C$nluFZIun+aRIpmXK?TMXRp\BG5C9P&aEkwTttIC\tlqbW6nVZNR@SCND&Cla*eQMT
+8j6uy >R^#6Qe+L!PyDViW5ZL\5BeP<TKe5#G!e*i!WZT&pSj%>pe\knXS994t/w=P\wb@P^hlkdX$5jE!W<Yi
K<$:pb C@AKEXB#5RktPKL^*qwPntJ/^pyTiw:m\YF\V!XZF+T$5yW<#p=QYw<S:C<m=1A1VpSJIb!SD5aEGX%q
ANqehm ESeZR\MJ%Htewb<&M5#YSatwaGmlnlQGI+TMCGGTep=w?XByHYqHA/KlBTLMlBH5Alj^hVL!>VhB!N44
<A@BhN uJNWCLX#5=G$>SV!M9S\\6wR<aGiXn+Khp/P>1EGL5bTwRd!PtLTE4c1MyIwyBH1HN=buBF5=TiHF9XW
K^MJS1 $jLT?=5iLc<6y&Qlip=XT%Xi#qnPVI6kb/Eedm14RpS+t*8:mN5=+nWejVHc!BA*TW6bB&h9C=8j*e\W
$Hy4cR 4&G1<:hnFHd1=%\C:dRehQZRWj@&>ciCNRaJ@!<J%1l@Kh?JRj%P?W/NkIDAu:>5B<Q<jT#<l+w6@&i%
T6V8dn QDHIj^Hj@4*F9%FVE+NE@kbY<Sha?d@GK9#191nj\KL?ZF%FK9\GF9pL4PJja%G@81@Td&DlmD@Hw9<c
9+/P*q K+@<BSd#G>lj*Fei@6haJQwZ&N@kFSL%==?9@G@\/yhK6Q^9EP6Zc4L<d^BLWiuQFYH=*!GYQQLQ5a1@
DNV@h< <\H@8Y\9@^9ER9/1#j?bYP/laZ>bEPD9I>m@DVM@j@1HLt*pHiD:d!Pa/>?8kj4=!TwwIGEwnCJMRSH%
m+b:Xd :+NRaInd#\YSHR#?d*@?8Tu@XNZ!Q^:m@$FR@+i^@><EhWZ=j^ZWWZ>T%SKF?y6=@@@NbQ9@QyNNMS*u
*yM&Ta WaM&lwSA$XMXX#cA?w6+YFj\/jDVn9V:X%/wNZJ=Rbt8FX%=nR4?8m1SjlVhAKYQ!S$WJ&8M6ePct%5I
uFH=%p ZF&#pTMKud%GFBRWlnh&tSw#NHHe#VQS^*!tMhSe@eDTG95qlJ@9YSap*wCFY=LP#+>G9p?4y1C#Q:MQ
Y@BkGX \?CKNV<:8%<#BE>QN=mEk6Qb^6et#L+8HZibF/H!t*bh$FucF1\+Hyn#9WhF=N=dDN^A1JGD@bB$6:P?
S\=S>& jG/=?nENXTllW<&a!+?dBuywl$ib$PP@1J9ej&1=%K9X<MXPy1nc5F8BN&Nq95uP=?SP^6i*mpa=4m8D
WaaYTc JpwA9GJC^9&+!^Q=<%eD:%Jwjd$!*Lni\6W6pjyT1qPk*>jdL6S<?=X?86jA&tmpV6@GR?S8=BE1nLwZ
1<Gn5N AZR&H8bYdN9XW&R<FdY/4Z\!PDu4btN=@1bDnC/i/&ZE@pVmm4@S<?L^tHc:$qHZjQe4?nEhX%TYdXBL
C?mR$M HC<:Q41:Qp4i?VIBT9PFZ=9%?:CT8#W=9C8?Z:DwHNhlMu!+Ntd8YHB9TRp!$1$WE=GucIqpd\?<L?jq
#K=qSM ?4Dna5L+&u%X*SiT/Q&X8X#Fe8NJ495!J<tn4lji5b%^nVFX<ZKea&@69HNNjjpNDS<6ql9w9>a+@P:c
wldA<d Re=k%*K@@<V^8$4ul&EP%@SHL?R@P#PCWn84NeIa%@u/#Z6#D<1b^!H9In?jbI!=4!@dF=knuL:FQb&/
Id\/?b @?Y$l6*5lDDVeZLb%#QhYX:w+tZ!4V6d<T41t<DK1Z16WCtNY\@ap@LP4k$btL+<I=6*$EqWPa%Jd9*n
K6@DPQ uNb#/lL#nw8Mj6!XCt<8Y/i+/P$dj&$5@$Vy8M=D19<+Cc<<&emQy@V%jB4c5pa+jDWkjZHk>JZwwY&E
5It<MR M$#eq/H!$ePE>%R8hQXK1beLSah>1Y/>5TEhAw=dE!NZ54M/RS+VN^B^J*^9T5RVi!cGNJ>%M#KNP%8J
>JkiFS W<i4h+$:LHkZM$lp<mB\dYEcBw9KmhVLnX/m%/di99W@/Q$thN!*L#SYH$F:K=/MH?NkapkEylR8hX9*
eRc\>M HMD5qIA?iaFA!IS\Sjt%4Nw?:IPE:58M6i9BM@6QYnQ:Qm&m^VKT94>XFb4@DQ6Glbb+?M1kj<ZZ\TDc
=:#<Pn 8JwGTSWciX^$/y=F:kIaFH+AdGkGG&h?Z8IhW8</a>AdSy<RQ!mlI$?l*=5!<^/n&<QPt^WmL\q1Rn>J
6mRByK kQhQ>XjSWDS?HqCEhb4YN/ZyPXVZXWXjb1JjMp=GyQJ/QtcbeH+i!e^^YZqkKe4l@d!c4MFq6RluJq=Z
/RmQdI e&A4^ikDM4li9B!V%>KX?ZBHiYQ4$L8mScLL#KX+KD&BmSEi#!PC44DbimG9PQh&BH?Q4>dW5DchKcdL
<5TDCa 6L\+&68N+iL?pe?bb&Fk:n#8!K^GbbM+&ZE^F!ZqtY#9e\9&G^^5D&qk5&1YHa6d&hjdGlB\u14?G6PT
kARauH 5W+9@TdTA/*mG%c=QMa4\*9hww<5$uup^WaQJSZQ#:bc8TkFXZZ/5/\9dV$dQaiTi4>9ZlDE5DAkwBil
$+qS=P JuEHEGy4Hq95u\dLjpyV/dXEYE!&^J:e$AXht?#MbT#6WFwKnc^%$qbCm/qb<<T%K:C5#wj8PT>yd^>N
*pl9bc MC6@a&IdHc&6Pjyn#6c?c*JItuP8Ddy@FN!<<T&&yCKFQlW#LujC*k::$6aiC@ht?Mn@TH=#i+%RqPNL
X@F5ai K8G+%aNu<JRM$>uAndJm$4dp#yAJNCEj41?Mn>i6d9t8hC=%\WI5d>Kq>G+*>ZPHb5Wa:\?$R!aW:XID
N*$@E& dp!5VlYTS:96h=jP!LI</Ky=/\e<\a>#DJbh5+qB%*W#Xi$u9^&!W96P8iV9WjB$JNM<aVHS+D5ty#XC
!q=pPI ^*6DT=#//\YpV\!iGN8X>^GTM8N6e55>V:jlJk$jT:i%\wh:@Ja$=%QZ/t48TW61FH<>cyn4=dH&&dC4
eYJ#dd j+J8H9+YL4ZL+84Wieb=TbSLH=nG^ehF>k@qQX5CTT?N!*MYa9p<hZH5:RPXPPJ:Vp\n+&aCc4uhNnC@
w*1*ub J:T#Xjynd>:yp?hyF?NdZ4H5%G&P:%Q#6DapQEBcZc*99BH5h9H>WhYNelP:!y6^Z^K6%WK?ZQ8w/XM^
cGuH&C Rnj=Iq*LRtPpp\H?YWT$jjEXa$%al%tBu4c%ikF^#4j%6NNKSt#?1:Vc=lZGyt5LEYtQ=1YG4=n4c6^l
%$L$aP i+qYFBm#T*X=e?=GW1?L&=AJ@M#<neZ4N*^T@CaaSYuJGe^6HN@VXtEqmq44e\PiZ#5WTpME?EJ>iQlt
YKBQZj u4Tt$apHZ6/k1p>pjnn&!dTD8En9&XWd5*Z4dJ%q1+LwjKeW?WYcRnID&KyIei9TTXE:TDRRHSFa>LZW
1JF9t> ZiDJCp<A>Y#G$/Met/&<MS8VR<Y1=q6Q&X58Ll#NPZmtL+b9SkhFde:1VRt1SjktQY&I=kbYQhMJ<9:&
V5SGm< ch*5&I:?5tWSX+8q&cu?4u%i:kQ%B4Ad1>6BEJb*8mHy#CZ>E<bp=\ij!9&PK\cnP#nRQ?=>8&!wMtK=
?^Q/&W i=G6HYn!iSAYiLXBRml$/IPCT9CpR5LMSquQl^F4GM*R$GtP4a!9=iXYuLmT&LM#n?P4uu\dqmhiyQ5m
lb!?eN h</dW9LdQEL?*c%9dF59</AZ4dkmwYe?:P4W<c@+TF/ZmS:Z!VLY/Q^mM>Hq*Hnddj8Y+ItmI1@n/:lk
V+<G*\ <hh>^qGL^*?ELhmB9pmY^*/tmn1S&Fakb#eB1+TF=n>YFlWpq%\K:Dk^hXHWt9&cRW<lN%VLQNqbN@6h
H6CT@S N8XLaCHnyw@FRNWJHM6pG9ppbVNh&56?^=@G1>B&9aeGRKlQ:@lnp^6+diWEL/%W9$5#>aJY8=/T?J1T
cX5j*e i6/ljy<GLp1jRXKS/$pCEW/*^k8qqL@y@AEMA9#lEW%cijX6N@@V?HkV%RlF9?wja&hALR<T^!KGM@H%
LcJJqK :=wmS%iGh+>F?mIq\V=>1cN9S=dA%NMGdpp%9w8FtYHH:/DjeRGKQbPMwk6&6KwKNbw1#NkD&CVnqHlN
5?ItZc Rk6VW+>Ve=FC^4\4k1tpQ?P%uQdVjRXcW?Zw!wcFKipJtt:nPFhw\PV+qQTP=DZ19YTYe4@>!S@Amm9k
KZBBQ9 k&c&yJRY>#1>nawcpc4lRQWAyyQdV:yV*:5>ND&MHP91E**C4D?d*ACjb=l6l9p$qWY@ED<C:wW>NebJ
1c9hEK Nn&/98cV8iJ&p4BbuGYk\DL>6idwQhHGjJ4cBNEDnJ8ktn#H*>RQCN:qi%jXJVuCED\eZZcb8*YVKjk8
:^VXVy X*>G+<!8IM9Sy#R@+IR=u<VJEQY<bG8\RAA66ZG9kLndRDddYbbH?Z8#VFp4:+QZ9:k?mplwCeKl>Gt>
ZNHZ*C &68M?Y44nJ5BEXIF@L+=RyAub^QQC4P59&@bEI>:\VB%LNq1Inc=J%tV+ZHNc@bNQSn<YkV&XtR:\\Q+
Z!B<XV RbLXEtc&8Vq4LwYkp&dFZ&C6mBCK>q*jE>4\Ei\4E9M4jyA?/$?*qBVRb=\P>RCn%iQcB6<h1XPN?*<A
1BEX#m $WC&J%ujIM6&ELN9tebwtJF:=:EB@XRDka#L$*G#cLhFa#dF6TGt:9nF//#Cdn+X&^/=#=w?wjR!Fc8w
Jp!<bb bQ4i!nIW!GyGCR8nJe%Fhh$$4\D/P6c4Lp6ukkc>Fh$aSInE\uHK!:Z#4TJFNb8Lnpp&#>^QHWay8N#+
<VdkFi d>M5ESNN&e4b&VblZXR9qTX?#KcEiatY<mj^i+uC>R+y#+i&ZEuJhTJ*?HmJi+u/PR+*BXLbV9651IXP
#L8X!! &<V=aA#=ePIwZM+%hXwZ#\bw$iCBHDHk\MX?K4lbThm4u/wlhL%FKiNX+b/ZSjI/mj+1jdJnW&aEGwWM
q$Iimp dHLu$#<\u+BeTq>nHp4DpY<JXceX4?HXlL+ab!$c8>84>e@iDe/NJ19*h/kZ/$bWA^aa/8KLJj!8G#&D
cKjiQ+ 4>ZCWYY=Bu=ZRyq%Q$DW?mQyIGEiYn:FR@uZRRX/MH#b\GmMqk>V6SJjhc9&bG:hZNnHuW:KIHPc\JCt
BL5$C\ \GBBbIwcTuhDW96WjN9\GmT\@k\X%VJcI6QkZjiy*IIB8c11Rh/\^iyJWKGB5iA\ca6Rhyq>$$VQ\Jm9
G^Ttk* um@=Y1+#ZkQj9<5I8WNBbXC@wWSJjA6?m16@=&JaQu91XW>4eeB5NuSmTYtRJ&F<eF*J9FD?TeZR#6BH
pmBiVq Y9W$mem\jXjw64nF@HJ:ySF=wGJtN<P!iRb+EKA&K>\h:DaR6:=Mbb9+^EtX=9R?dQ*hWhJcYyKq<G\H
Fn$1C+ #1?DD6q61Q!N!8j4dI%^/tKD&GQ/#tQ#9XSd>^?F$lb*k?INjK9TFAc=Anu6RcW5V#QmPDlyyjD%k/hM
$^FMY* aSepp4e9yLa:kbC9B=W56Ny6Pp:9MQ8w%>a<dLD!##e?>?/Da:ynSN=BiSjH\/#L+nZ*lyJ/J5KHVcRX
FFuq:J $\/t4+c4^wZ#*^lQBwam^b/RWZGdB4+Zhc9FQbQZ9%nih&d\h14QebKT5cN*CjV<<t=4tP=EjD=j&nmJ
QnqN*< :FWQM/F9X*k:aWKVc1JV^NlJbN#NJ\YSY?jj$VMjq8eFZGK\e<t/+d+*=^1+=8G/a:pbiKcm\mCeXctV
-ASX<w 00059666f0400110333 Page 159 of binaries1.zip
PcVk*F a!n#PW&tNSZ<9HY=qYFt!@DVb44J*BdIkjVY1::cy<#^AiCAlZe5Zl<T^+>*d1lJ:IQM+B955PQ*51HB
yhQukJ j\S:d$cnLy+:a6&jNuyQZk+&8&HPa1+ZY1#Y:<5kyeV^>mW4p^c:>?d^!kh&wWAAM5th44Bhq\9aedwj
kEByCR 4LkmP<SRWL\XLBjPNMGP$L!p$*wJkKi%XpFCDq6TGiSHtICX>/w=HaMP*6Gc^S=9hW6LV+V4NHI\nS<G
XQ:\hD l:$X5utQeL@c*>R>8uQW<=I:#t>HCG?5NHMSBAPYZ&SA1GjTVwS#QnGYE:8$!B5q<c*GdPBwFHYRTG!M
AV6XG1 t>*Tm>%5K4YlD4^!==&nTYQCyQn^1VPZkhiktV9:M%i&C>hndSk=hFS@wFqhLT8PF4qJ+XdtZL18Rk%:
hJyI=D IwnLCLj>#R?J5wQ^k+kEVlhG#4E+L8bEm=#+neHI@w8y#DJZEhi+4Q?ItWuqCqmN6FtJuwLj%^?Ziu<c
<L5a?L %!HaP#Te9k8/XdNyMYq4wB8i$Gk\T%*Vdd%R@=u9tRpTqYc9b$DqRn/=tiCk=%clWL5hpB^DbC*RKD!%
F4#^$% Eaq5EiaZdt$=d$ttAdVb$uaw%C<iWNW/M$tuw?Vp$RVmn9V:m/+biRei^pI/$:pZ45inc69K!c!DG>HQ
Ze*Z*4 Ky=jX!yn^q\!*MR/mPi4W%>bjb:Mu%*nK4WIVF6&FXEN/ZpJPQ4P446aw^ZJcLnHXQFKBW+=u<b>jjC4
4nCiJA qlal!/^i$$lMp:!qPj:M5H<9bjEPJAH?:pMVua\l@FP/ZnYQyZiPXu?dSZqd8MV>+1*%/:AXyubt:c%H
M1c:Yk cFS%Cb6Peyiu4j+:k+N8NcZq/c!k//mS<5w/MqX:lbAB\#$ActR>PZ=P?!*Zy\bl#!XE8j=*R*4TWbQd
>HmTPt 5:lR6^QhwS9BcuuZTtk:CmK>ynqY=Bem@QQ<<Xq<VNetQ&h1BEQK<4?+qHeS$Iw:J=diq1+?Z#M:jWVL
=%ieGJ 1b1LV=>il6R>$p<\aew:C+T:%c>5NWG5t*bKk=nh$6c9Bq%#?>w@F<!N+T4k%Sy/dpbPP%WT8>HPT1EN
=4#6*n E9nV!4n@HlL@*/I!Lkd%Z/1Mm%FW?Jik9mL1h:QR@l:l?1i+Giyj\=&w*/^Rm$GljkQ:m/\5qMJ9aBF@
AGjB9Y Hl6GKj+%XpHy#&QDKKZj\Q+mG\!F@t55/qjQm@pN4MKjQ/<C@Di\<u?8G!kkjkPL?QN*yaD<c/\<=lh6
&aVVKI @k%i!e9@+4/@\T6==J>u5Cu<B1?R9&4#d@AK?R68KQ\G4*/yPTn<B4F?yVpwaQ:4YEZ+j\Q:G<V/Xjcd
4?l@&e +t<RC@YL4D6F?Z<K>KQ?5y49Q:Lq@m*R@!ibe+1wQ\u$\=EK@?ijRP@?9!jR@*aCZW1tN#/R9#uPXj5P
!tY+!8 $A?@@Xm9I<%JS#iLD/iRXn+?<C1B1y5\TekRapDJcZVkB65F/p+FYwW8CjNyN!SIRlH$G#d#GhuSK\<6
\CRC:6 i:HX&5&ql8bG<@Q*9uI@SRkZne\%llJ9Jw%aWKcn\TphGW4DZAGutNWdJ6^wjEw4bV@<l9a<Q9Q$B9Sy
tL/=ni TIiV4VFFHuTRdJFt$nt<t9Jbwq*kqyeKRtu\GNwaLup/$^V?k9iTVahdE*Rlh?KDLaQTwyqR5/@N5$kV
dQtlF1 %mJ>lQ1CFPAl<ELcuLSP81FAE6LR*69!%WW+Zw%B+WAkkad:Mu5?eMKw+C!DMlWBkYwa>8I&<!F#8u4H
9en<tC kZcqkhKd+Vy!#%YnJq$YweN>K:%c<L/%>#AHwwJT6L+h9EH:Muwy/IdXKYy%dFIThI&!==dYQQI4m%=@
lBipwG @N*m^mXZFq94%wN!X:u4Ly<ht+JX#EqG#m:L9N=^yt\15>K5!*\EBji>9k@Sh1K>VbHjwmbc/&?bYR%>
^1ySnH Pl/byPGnVl1ZnZ/NlVIaGu!8&Gua5PpeCc>+hlbJj>8j>VD5RuAXI+<Sd8cn9&uB&@BHCVF>5qi1L4kc
14^\$\ &%S!ZtE5yCSQl9P+?!?Fqi1aZYyXi/c5SL#^?pu/#Ih5mCRN@n6/bj=>FJAbNNAhj5XDI/d&9GqnFVy9
Nbp^mI d+nBeDBc@CM4=^1Bt:<u+HI#a@wne%XQju5Pk:*#4MAuLS@B*LWYy5<u$NdLu1q4%CT!<RmC@Rk5wKFJ
ZJ?q^C \@#>VA<uFM!L8Z=8?#58j=Gephb8FKTj>^:da<cR899K#NRbkXZk8DX9@m\w<A\4MAqNhL#Wcc5@<WPy
VAnDdL lHn=^X8QaNFkP<=&Al>9TBbD<@#h5lZC&k9NXHknI?=BKMGy?CdIBQSIqZLS\>qt#VHb4:9nWVLQ41WR
eGX$E6 #D&F&IedaRC#9nCA6%Ep>!RX##MR^GIda6=SYcqYt$MW5wiCT=S%$n#QZIJ+!&BceahnjG:j#1E1Ni\%
*q!+NW N!h@*M!/n5hP%>^JG6hd\+tD5+jAw+Xa8:R%jjqpYS5S>+my&ddekw#TZeuCH<+mha*pu=<YPZHlWb\k
<k:im< $lJYIu@ZVdi5YL<Y\Rd+k?Xnp:@^1aKZCL?4dA$d\pLCk\ta=#a5yL6yhktb=t9t!>aZ4h>:ZXl%k?hK
ELQ8j: cjeMXpQ:wCnybcHtFtu89KShMc91CGjut\HlR9GR?P\#5aWd#DGbTuIbbX:D&mP<PeJ?%^BNuQe@$Bq6
PbWpAB 6FpX5M^WGWb^WN=+41H145Pji$S??YL<l&TH<$DBIQ/\JAkq8<6n!A+$Nau^T/mjTjaC&4db96V\Lep$
J>CNP# tyy>G:YZJ!peR6M+T8W8!Mh9<C%pq*$NQYySb=EcWD%Wke=@e?4F6@8tSd?Z^c4C<it6+$/bw?@h8h:^
q=1FV> 8Ep/%V1SRqqy&Jl$d%qYZe5n4@tLP!and$GTwh5^bkbq=BedZMqk<c/S!E#GNMpY\/QJu6lCZnhmY%cP
d:$k#G !PSK4$K++@/bE8<ap%hTmd8&6XKG5pt>bM+Bc>EFbL=FI^!#BF>9&5*LRwKuMh#tM9T=u+8/1wKWq/%4
6bVVGn dS8SV#8yV$6#Q$TbNIbGPa%%Qlc=F!+ut?!44c5/aClC&A\aa=P><Lq+^cb6$9@nwpZ9\!hPH<Cyt%RW
B4T4+< liGIi^bjWTYGqGjK/bLFEdC*XFYjyZM/JGBYV\NbF*iNR/Gh\8cd\l5e+Q8SI\$Qi!/+C/:%q+aiSTSX
AJiZm* %ZyKFL9kbII:=m9C9T1qhq8i$H\R%X>!iTMX&n^<q:?D5<FkL!:uw%Ek+JHINwtV\qm9:aq8=dl6tZW!
Tqy@8L qPy^R8G>/#pK%HN<@6=JVY&iPebmLn^/VcpWHMQCLR^nG@&n8juiD?kw/!$5Wk*4>6?ahIWNlNZ=*Wq+
L#TVYw d?C?pBj+&mK9wM4#4KAlPJ9H^R8wSB#JAb4q!Z?%MNM@E&^>R6tMZLA\58T$*pw*4HtdkyBXAt6IGQ6\
ulGh@$ HbiTb?dmc%DD%m$P$Xy#h>@I6mY\h#nF%Siw$HTL1ekp&uYh4VN?qcd!\4DWVDnHKtd!VVtPuL4YWEE!
!>W^4q $A9%hh?#:T?4iaYk\:&wiS=Z:PyLI!u=:5Xtw@SV8QuLil+@i!P&B#!8HNITm9%T^:nQMd*S:ZZyjWE+
aS4Nm$ /t@R=JI^Zpe<N=Q1y/j\KNR>6W8&54S!NwtCjly#ij*yt/%iWue*9qHqlLyhHw<:1:ACbNV^TLuG:jui
Hn^G#F ihK:5<?d>1IZL=ZYNX<IMyEY%pkqZYpXp*J9hQ$h@ep#QA&+q:@\@IZ4ql?Te#&CbhciG1IY=It!c9K6
<tYHby >pQL#1=qEkj9KakTpFy^^jVDHJ*myZyeq1GKcL*JtZih$w/LV9hn%c+Ad>@n$1J@tjiB&8IyD#E5dVWy
y#MQaJ !qGbl1h8^6*CPultN&q^R6:NVdXwcM!ka@RTqYc4^N#i=Ty%8bl4WL@S<>5h!kRdt9hQ:S=Jjp+*8B*<
TbTek? &ji8I%S*du#TEJ:nLM#%=TXX#4K%XW#Y5%QyZ8Yn%ZRC+5:i&wR#yJM9<M%h/>k9N\KVk#P\RYquLSCe
XbelVN /Z9j*/%@hu@THudlT=%Bqhd8PNBq?5KtV\ID^G%V$y*Gc:Im&u@AqpE<Xn=%HJl!lRdR=ntqc!qd=WXP
JieB>* !&>k<BF%mScP9y+RiYeTq=BM:bdkXSLEqA8M>Km/=\4SbcnYB5ciqkVBQIaYN+i9?MJ^:pa*MuXSVXZq
%*=Q:M NB8&&6hR%4wKIAmEkMhd9%Q?+$%SFb\!eQB\lNyS==1d/:4NhIYNh*\%@c=\L:WNHBmt=8XEu*CXRbca
>LPKn4 l%<c<ymWIdc6VFXWVC9TNFXXTb4T+&jZM^eL@D\a?&tbYcm>M:55ACQMl\5h<DhVuwM5mhu#hB<b*dEy
^5NVMY 1beb#bkb%\nEFJj1/iYiqyY&>Aemjw8TDM6ya!=cB#??n:kM>b&a/T$^m?jH%knHphHAjk^HdbSXWqF1
C!@881 \lYb:d+<aX!P*KT5n+G:lD4b@hV54YyeI1\WKA*eaPhmEj&PmAkKdnKeKd\p#qRqPu\J:M^c4Wau>w+4
*H^?hF Gj+Ab<>IYp\i%H:ybW>4NC>C8R:e*FTXFJT5h=\WHCmuYnpS=4tP5:hp>tYM\>=QTN6qmnn%ZnTRAMyQ
kVAlpc L?%VS!qI\*bZS9Np&5FDwn1N^VamcGaE:tyRnWNRp*S@Pa#!M*5N&bIXP4hn1%M6:n5hR^MHbT4bbu^#
@@kE:> =JWkt1qL69SAPXZ?RWEi!Bl9<hcDyFeb?G\:mdRM*<F6WIjpkRAVIP1FYPw=CZ$QT$M%&1D<>/=5\lK^
6m?>Pl /qRD6PI#b%%/#%cwC^<B=DQ=4PIh*?\>PM%C8wuZW^<<PyVEWG>D9JQ\Z+alMdya1/pm^/E!=\#ehJPc
%!X#DJ wF>$\GSlik&4XS94Cb*kqetKX$@euPnY4b@EILIQGTyM=JM1uGZS:6ikP\e>Ml<W=WkqGSQ<:$$FlEJ+
\J1qDB pnSQbe9S:%\NleRDLwy+=an8lFh/\#I4AyAD\Cb=@5&hP41M6\HDS<pXBjW\1=ZbHIVjDX1Z9MGA+VYC
VT?Be\ VcA\/aQQ5AjwyQ*i>>ti&wyQ/QcS5#IDbbQ=TpiA\@Ej=Y?DelL<Wa\yd1B98cLaZIMjBEtW8p>Ihi6n
4jkkPG Y1clN\$:L68mll9+C^<PGL*NbWj1e5a$FA\9C:\4ccIV#9nkwyQn+Wd>wKaqWMp#S^X?YNW#?9#\1hCP
DkTeBk %:5EY*lJ9TD+MG>V6JA6WZYmF<PWjS&MWNbJ?SI@lQLe+kpS6&GR@eatyD&wiBB/k<l&cwq\1<@wGje/
&?XJTu AwYBkiM$!5qNBm8:B8<ZK:$<p6!t4$FbeBtQ9Gl6d:/9N^lMCtE\!BwbmHAZnBI@Cnj8#qw=i6AVEB4&
c^PCl: /5d<4A$N:kK$AP\%IRQ<F9tB!aRhqPkj5S>\*R\^i@P6nS6k5taPGtTmynCuJ\nmM!L&Mc#$K^!>KyIH
ZF*V4Z GkZ!wypkZ:R9tB<M\w$cjPiMLc=JH:9ChbyPH9T+BaX#bVC>eSG6!>p\/1P?aFFu8#h16X&^19BS%+$6
qQFQ91 aBHkacaZFSL+VY6qXa+6dJ1bly*yltEd6@q5A1*PbT8^8#JD&P%?e>W\D>WQp<w?pyMI1<AiZ/q*L4T!
>6h\SG *+a>Z@P8BN^BIR!CX&qZymDywAnQnlS*pyuFP8qwBRi>pdn>k4YtqJPq!IYqJJjP<?e!qZi&=<Xcu#S!
/d$\ta hIDXkAdkN:WhK%Gl#%/S9TT?Lpik*M9phS8=>$W$/pyuAeL@8pFKRN&kAP@P*qCm8:#@*wYRALqhHdi5
Aq1cKH ^&:9kn&%SN!QIlJ*!TQd>p>mF<J\QQplqHi#Bd\1wXicjYV&8iA%%8+uMX:^9l=n4Iu9YqG+K?auN/bP
yZL:Gh :I<<lLl%99mISZ&j<Ib%BeSMPP61>cQ#JuVdb^*<l:XYZ4%YFNCKA?E$F:11CyMbYcn<F:d^bh5by@%C
YYeeR8 bSJ^V/B>&8wL<4wH?TA>ed86=cJN^W9DQ</Ve?X#%#61=jTNC+G%RuybNh:6*=I9GJ86#==5=5c:$lt&
-AXm>I 000c3e5845200110333 Page 160 of binaries1.zip
??%Gl@ 5\tP<Iibj#ja4KYhS/Z5i=:y<4G\6lwh\Lu$iDYA\edm1nkYbVhwy*N#Y&IeJ9RCwa*/5dMR^9<IZIWd
>^=VlJ 9JkktJF6y=+e+#KZ5Y!1uucRH#M%bCucMGc%4mA:+uP5@XEu1h6dV<W95mna*aj!5+wS\=Z^j4jBK\<K
j=eNlm Ge16dcPj9TLCn+cW9lk^NLKb%@le!*cHHH%hp=ek^+a*>ZL4/SDZdc4NKSDGZ1eYT?PEBlicL:+$Tbii
VT+uZL >b^&GX^b=QbR?naj/YGjt9GPm#FiIY#BQVq^+bZiwy*H:EeqliK*$6ycK$hY@iwX:eqYXG\EucN4Zd:J
kNwc8C \\PGY+B%Wb6RMbnVWa?mC?VQe$wWFj/*CR+4@6e5!yV?>eT*E9!*k<N@i4ld<X?DYw1@ditpmQ:9kQ@=
D@&b:D PKjmZ@wn@iMI=>?mQQ>Sq8B@91dTu^:uSQ:j$=#@i>Rq/Q>@4!/BBTn?#*8=$u>DA9wjZj6@4V54@hi$
&pNhPG H5!@Pk=mj66^<P@$^@#hXi!jPyjT9<dtqbC@tZillQy4LEL?#&Q#Tk1@eh>j=G\wKj+GF9Hu+Yaqyd@G
lA9cD= K9#CmW<J@S9aZ?kaTym@^1J?wYPk+d?Blj<Cm@l4:K<eANHI*<A1@kL:G:!TS@$C?^8<?yZtk@+NZ5u@
FG<e>> /q*>B1>?PW8lqj+:+N>kqlL<#%tJ^9#Z5bnjaJam@M<VVVC@\T\F^V@9lbnjaBbK@5@FJ5^9MA9=C<EI
E4iYP! <^9MRm4?+upX@tpbw9SQayMmHANV?DpCK@=5+Z<5R@+u5ip@ZB*@$#WX@?Kc@%nc\Q>^#j>a#9!<JkKP
cTJH>1 @JP%DidQQJV?y4Q>=iKGy6?bNI!F^/YT6e\w@5e1y\wB+b=$wbS\EiBCJRqT^R^*B!lCGBPydLn/+Cli
T@mZEK jYLjVQi+QTcPL/&XCwYN6$mmH?:u$mdY16E\$pKm*MY^KL+$uZ+d?KKuNLhlQI&Yu!a%ypdVn?wtP@tM
$TXK1$ a&QlQw*YA!^iAb4HcEayA&Dui1Dq9FI/u85KLGPp/WjpQuBBRinh!nHcP^jX:?QJLtAFYKAT%*MBTNyD
K=JJ8c *YF=9l/!Viy&N^FXd1%^@y=:EXRtlkHIwXqbA:YDRtuRySyuL%^jQlm/<F/DNkID=Yc<*&%VMni?#y58
5ZdVZ* yp/e^whlkkiB@IqPF^cWQq%T/X5bt=n@t#b&?iCQ#QCDG$c*=8Vp\Rkw\>j!LQ&\GlF^Tb/W^qy\hqCX
BD=TCj iP$>B4=Em1CkTuJ9QVY9A9mFSR\5TX+^RTA>BLLWPBc:uwRK\t1\hyV&5+D/k81/t$X*\a?=hcYE:BhS
Ehc#>q \!n5m\SKunB+Sl^8Yj:P/9*MA=4TNE9?BIFM9FKGXu\yVL$NF:ALDtA4p4>H+Q*!S^qL9<qAuWc11CRw
lAyJX# l>:qecN+ZJDIw\a$ZuZ5pQKk5nMdn=&hmKpJ1lW^NuJt/IY<?cmkJ?+Y5R^i$:1!m&N!E>^TA>u+:e?c
niY<P% aMt9!c#S=Zwn?/j+><MH45&TbQ$p9MVhI<NGYe9&*AjH=Ct*XYX>XQhX=S+JLepp+XaLa&I4SXIk51T*
FK>FnF ^1<Yhe^t#ca%=\X>$!SXCC$%#96!MChl*ueH%itQi1I#pt%WhHkZit4Lb+HE?bwqCN!C4#NquJybAPej
&/SVlW 6A9j:VZcEHS\%1y+@bn>B1eauj?*wm?9#M8@1+ldH6MSae:><%ZGLHH8<q$V@XYd=!*/b*qicVpaT<=?
9A:!+c :HHnuT8Q8&A+\wThjj>W4thuB*%hK$hj?XunSMS54/+>^?#B^PLl%qyH/1X%/EH$G$d8%Ihb5?>8N1DT
VP>=N9 %p^8m@qw8hbjbQD@LujLc?qtEmy6+8W4%J/TS&Zn&^5\5!L>Z9jIb#ZJ<tVi<TS#iS%:45PZHRq*4tT?
/BlFiH <Y6!CM%!LDR9P8!Pm<BCA/aMtp9hQ<W*SuVjcME4:/p/:L^Sa^KVVJl9ZFu?9JDS>dcEF9yPRC#E5n!4
ZRpDl$ =4/6?ZMLk%Z5aGiA!qu=ya/A44!J*id<%$<<Hh\J8^i?TY@8dDI>T:d$MTZbFd?iDV@#QHn1VNyYYEmE
kYn#mG bZ=\nP/Lh9%bcHJmGYYJbdy>=D6M:P:*+@wLM%QG5Mi=>^*XJDB>QIwb9SVcNBJ/F?WyE:>+9Wk8^#DG
ClE+YV 4/NDD>@EyL##<u$wLN8##K<SCuPIMc5pJ?A6aGEeNBT6C*!$J\?a5QaBRVBb!y^/mqu>$^nD%yqtej:\
kl@Z#\ W8Wdc1Np+CMSPiD4B*A*@Q84etKSD\1Y>u#y\ptTPbqF@FTTq+D:ES1/+%ikhd4JRSPuMmFpIqel?I1S
S+HdnX X*?nWBBpL8XIBc+RXS5^uYN:*#t1tqK=??P*5QMW\?kuN1jwy:I<jLF9p?5@Z6Fd5GBpDWQTTDwaF?ip
B$Sj^u M64hb$FtXZDq\aIaF#=\u>@ik&yChX<JH=ekaCN<eXw5+8uJNPp>bc#CPbtjq*6SVuZlLeWDtYaCNu:S
?ERLYL Y&@aiN8j$$P#*$XJX&^KS*In&NpiPB^>uNRV8uKjl*59lHd%9iIGSu+qTeqld?YdmQum6lQ9p5PY&\uj
muKwKJ TXHkw9jVt?b>%HeL/M:EGD*\>l/MpMj/QSM>>R9cHXa!Fp>YktcdlNYQ?9X%hR!LiRX+:+=WRN1jA=uh
G+QJ$T hlLCnLd\$+8ZZTXA?nKujN&$&@=uY:e#n+#&u/BJqbd/L$KMLVcy=B9Kd@I/1q%V91t!<i*+>hE6jTlp
GW5Bpd W$^wy>1lIhyyBke6jnKI<bEa4nS<&XIN&#X@>ua9#LhNd@Jp@dKJ9^aN^NupZ8lVKp:Z:\qQhWK1^RVP
4G%Qdd EVWJwcm:YZKTh/nhR?w^Y/&!lNGVunI?!#lacj#A#u$4=!I1\6:LedL=F4i44TwV?+#NVQm*C5uB1>YY
>V!lTC kJuc/jFbHmta\:+ppM!4=LV1p>u$<WhFWXIhI*Sj4!H$ewHEC!W96pJ*lp/nw&KQG&B8FJbbinXCp$Q*
JCRSpm RYZ6RFuJ\8KeCy9L4M>l#cmB1HDNGenpcwKQt&#y?Y:1mRCASLiB%cbNa6PDi4d5N8cJwNc:H18#wi+M
pkZ$SM ?:m*6PWhS<>Q9S>^WEmhJXie*q4TWd6&=9&D#PENA1Ekn6u!1ipNpweuYmKSqw%t4Ik4VM6RPc^p>cLp
AhLY?E 6L5bhLe=AKy&P>F/nFw@XFDj1HQ<he9mC%+PbnY@A>W%Q6M49G4u4CI%kYydwlipihYqyF1RCtt+aJ:h
Swj*&u C&*IwX#S4cj8T!/*/npcK:6!d41HSIWRqG^j*ucZ5>n>j6p9EQ%<dp9GE<qwiP<h/LmIV5189lnjbD^/
EDJ4yK #$4$<p$GmYFD5S8//11DF&9ha^*&^BTdI!!JB^PkSLn&m1*lnQiP4$4I1PcYl^:Qe8%k?H$*V9EZ1J^W
%SYNZC tc/5P^TdL<<aQ8PFYp1aQSM@qS%/TBW1iHVlqGbMb@+t9mD%hy@iSbPmW==Ia6\TEBQ>Ci%FV*Wi%cQi
5+Fa** nmTc$:yNMPbup#=5N?^YL9JGPJDR1e<k6*$!Q^E8thJm4n4JCTjD?ZI\qhjR*LIVuy:!+tFQ@YVLtmYp
5ZpT$p KFbm%8I5Yk+*bAK1yNy1a8+iXHp>uL4#jy#^yRVtW^Zw/TW&8&n:NFGVn6H8aimD:Nlc^iuHP^$Swc8H
jM%nDF #$8u9/\dQZn5h$d@HQ%CacJMnDF9kYBBGlIneX+k=<Q1Y9LT*wH5D=9D8@JC=p$@:N:HQVV!6eTHnD1=
?W4K%m 9VPSDSd8#:?P4XkQ5b:u8yk4Z!Z%=5J^E59V/&d^>#=:1WnGeZhhA&y8jthLnZn^6L<l^RXII^MmuF:j
&J15KD e9jD>:&*q8?Q!y919dhhD!bWHyuj9Vt@dChy8yi<>R1ca$aS/Mt+84!y<W=K@WF1eLVjLL<W4%1c=RDn
wy<>GI l&ej&kj^9uIbL4jieRce^cbI<V*p%!^YX!iMQ%YSeX46t/KZCct>/4l=^?>86LjY/PuI/>p:Q8<MbSyY
Ct?a#G JV?@jj*\:JYWS*KcDpyKd/+>Kb>@&b@E+/$m@Tu@j9^d#KB5#>maJERGe$VJL/tn%iu5a^IGwdnW416Q
M?i1I1 iWZpmVuZqS?P\E#q+W*CiyIH4jBKQjDS%CtPieGl9BHR:FMlaYWZ#&?*9blQ4QKtiaZ^BV4SSnA#qDCI
SA8Y$D RVGAFh?y<e%J^Tke>IjY6MQi9c9>ti*dQ$/ylZ$CR^aTCGyy4<wTTSu?J?ek<H5+6Pi$#XYSp<8NEdmE
jPqTBS X!H/T$Q\ZByRHawi>FG$<B^VZ:nWG/hy<nqAYMCPhq+5PG>cZC<%TybtASn*uMd>m$Ntbk5p@&n$qIC:
/$%TdT ST&cRJ&\=LD?qmd6Hyw?C1lXl\Hb>4hp$MkXJmhYhI#/ELa$h?18$tb/6awLJ!XD*X\d*Kb6nmW4Sp#9
I^ye+V mW\KZ=piTp$qd6G@&SpW4JK=VCjPR4hi6JG\5m:!dWAY=!m!juF5DFy@?1dympYA+/^lTTFkcQNcDMNp
N?4i1$ ^\dN1?W64^n/N5iM6uYtY!!VAa9MZ+BN$Y5J848\La/DSk+h=dhNT!cJ?9Tbk1lD$Z#tB$?qd:G%nJac
=qjTip <T&**GJ9:ASNRyibnS^It+6WDj/THd%DjW8NZ$LyC6*<*@QZ5Tb+e:!RbXylyR:yQ\\uZ#54b@HME=wE
KmlPVL 6qq%dj416p>jc=8*$bM9mLjQGlj^/qHBXX$iFGFa/\mlieW\FI%lF4eelN>:MmnIyFwk$TmTdVT4Q*8L
\Bl<S6 KYI15ikVcTBXc=FbNFQ6*h:CyJT+nGyMFjplLjtbKN@Z^G*Z4FHX/YESV@9kYW*mp?uH^HGGeYJ6/neX
>cZw<Q \$hYDeX>RW$*GY!nSjPHYew<N@AQ15L/1mwayS+B5*N:1*SuDbW9\=anE^tYcV6Pae8ZR%+NmacFGD#p
=VI*/p daGy\aWQ5yH&Snj$+6K5+w9MR%Itlhi>9GCNY/k*DZ5VPBNDlu/\aXFuP1XubquLuFH#:9Dykc^!#<wa
l6EAKd 8P:1P?V>CeFWjXB*\n5PuihAl8$PuMi><SbeJp@#lPDh+V4NlCZCdqG:&:d!YJ1AX+tlaVAXkYmJVFKq
h9cTIc SVcR+&eRQl:GktQ64JJGS^XnT%ecmq4VPbLp8CSVZqAjTK4A6TNBq81kIi>*tRtkMpMQIMtD8uMjTNBh
h?/1V6 a?19F>:aX*eZ:yL=ESuZpD1eb8KXtXnLNbWIP&J4TQMhhnm!Yk!nLBR#MS$j#+#9GDa4eYw%X?1@jRcw
N#6:QY G$jG/w?1S>IcCl$VSncYp^LY+!BIycM9M\G9VMaLECMidWH16>l5Y1H^#dVhAad=h?9P+?1&tYG4&nw1
QT&H+F YuJ65>IH>@b>jH!5QwW&a/R1Fed=:nD5G4T4Q=BK\L\:wENRF%h/K*VeqV5IXGM+dJdh=\Ip1a?^TLuh
eLnD%I ?J!w&IY%M+Zl/im&Gh1>&mdW1\^5cI=*#/Yh/A?$#i<8&a^+<y4$jJVDF:t?qC$HP*\RZ@N>+#=^8Fa@
X^8!9@ \#Pcew/=kM65IWT/^LIY+QSSAm\4SjA$Wy5w6N<6q>5dDbMENG\qAaEyP#$9PGZHLAI!KkMd%A?YS>tD
V@bJX^ &V*Hq>qX6#<ce#?NTN1QPE$:^eFd>D?Yjh?RZV!\ilwmaDdm!lej!WkeVhXb#DbFl9pE*BPLjJZaSVTw
Cw:HZT i#*9aWK&>h/QCtEny%Y&yFNt&AASmHI*QRMCW*ZbH&TnC!E*ZAByLybjKQS6ekFEkjl#SByCjpCb/9Au
upbP+J m81mcPK\CSIZ<9dqGh?PED#4KM%P!NHTl98d1\q+h>???%c1:XppFbIu9+G9lPX^&q5q=:IjMB<@IR:S
e6*!AP >H#1pbES:R^88w4+YhkpVVXMLTY:eQ*t?alR=>lMphneQK9al%Y!>tTnYHCQiR*&w%At1L@jw*Iq4Z^Y
\?Zui> 8F^V8$=QNcn9\GV:!lN&>!i\W?d^G+eML>+J&aXZXZZ6#V&F%$?hHkhi1SYX>tKG/Y9j5kaZHVcujW#:
-AICE4 00078a595e800110333 Page 161 of binaries1.zip
%*ZaCF GtkmthK$ce/YGBnmB*#HeCTdG?%F@X!*\HbKKPTV/I$n+45cq8BE%AuSR+%Mn4/kZekJ@mn>/KNu8bc8
&8JLyu $WpBu#Yudc8RQA\W>EjmkEcclcVIKNyh>jTPa:HjJJMy$PI>@CqE=k!BZ6B59qbt9K1<\SuBj4bm9YF\
&Z95Cj ZVpZM5W^@p*t1eGuAi<5!P8QDe?&p9c\4?ZTBJecQ%+&Qct*d8aH/b!=5!<TjQc!nG%%@?J#ycEw@^9K
Mbb4+? XW%bF>c*Q#/:wC@91hNlKe#uS9:5K/^?ychE/TqaTehLnXS*9Y1VwYTDPT!aP?F%uH/M*IeHle^99QP4
aZSR9a QX&qST1+uh+5=\+&!JdB@n\+nWH@d!NB@iecMd<d5$dApW4@HLV??Y?K@!8&R#>@@>>%4J@jIQ@nG>S@
peiMXp emL/S\VpQ\h4EQB@4W:#:\@!G%X^jwISj\*?SVtiu&DpZ+N@Ehu?Cbd@DdDm4<Cw*\D@8V@QV:DCZ+MX
=ESpml pQBjkBZ@Gw#C@K4bT4<BS9\KnQ=4<C>m%D@BtN<AI*<BS9\G\*+Scj+J@k&GIj?<tNBQ<G<\DAu@Fjk*
5\L6lq GQc4PQXQ>G>R:BhbAn@BC4@D#%>$K<S9WP\Zupk@\d>B5X<pKQ\E@\:Fjuuu*/AaE9PLb$d?B5YR<4>w
L$KR\L >n?=5j*NpEuPGAGZ^emmEIyIBXp64!Ce8:PdLF1YEB+R+B*kKS9t=T/L%<QLc4n=i\h+@=!SuMMCR$Jq
Y:?qn9 4d&nuEQej688TWulb&>F\SS?Ek*%e:#@T:8t9\@8@@>9/e>Zmjw=YM9@jIF@c@D9NFV?4/bCBB!F?bP=
^6BC6W EIZ?%:pRyjT@NlimFQ=y=pMy@8uM>$?Ph9>8^QZ*69@uuwd/Z*Zm?pq!yD\el9w=ATFS!N>/a@<5ttA\
+HFjY% j*q&+^@q4$#?^$Q?$%WX@?V$^6?e=@:QP:/lBW$NKI9LV>S%l/d4AM<\Y8DDyujTSjhB+$S^?Z%hKnZH
m$n+PY Dn?q1dhht><Ze8LF$d#H>&Ri6hk%LhKH&&bE4kiJT?#yAHQWy?&/>t@iWj8?YFL\bMj*ttD&Y*\iTHBb
K^>1%n A+<:+<kE:nMJm1Q:D8\ywAZ6ED6qWtQZlaCBhaj^eKthH:WcDV^B%^IqYj5k+DRm6K%=4%!cW=:?k?Jp
#c?8k< A4&R:R8kB4bpPqEAt#Gu$&yZjC8Bp6/ZI!*P%@c=Tt?8LT4D*<94&h%k*%6uFjab!G?Wt?B&HKp^8bY\
j$pIuI i$*WnnM/=VWE499?j5E!Ca^cT=>mDG@5$5nEJQqpA*&QMR4GtVukVGC:nTh>9:V9Yhw&$#aY=n4RN%$c
^<y>Q% ?Sq:&>p:ebiI8=&5ZEQR+aBWEtw5lC>1GWjk!&l6Q^Ap#GKEe5:nEqB8yl#*Bj#FDP=Rla6##W:^ZBbI
wR<MJa D9QCj^\QW4c>*=n$Swe&u9*RK+c<<!YEF^l1+<cF<QEunW4GNGlQ+tP\<XC!RZT@H:D^Ij>6VFiQ%+1l
WA*QZh RaM=:IYC9Qd8dEw>Thtl6J/EYY:AtaWB5*u^hX%4Ry1:Zb\+9FLG\5DT1?yJ\QMA!\6Bbqj6qJnalBem
&!VD=& F9*n:b%%PSPh@cHhCm<Kuuc@iPnVpAn4?ySKitj?YRd>^8XPA&Gn<*!5=l4RSmW$^=Zd+Y:1lkd&a#Cc
cA4a*p $WPM6QtF!Vp/kh9%a4t4WPG:PJ$:m\FQZb%9Zp!a?=K\mZc:&PM95p#ky!>/e8y^%5@PuP&qJ$4@*\!/
JXI@XQ @A5udNMP?&YIuBA<CnY^bydcqZRmIVBdiGkY8C!#TVYAt6$51HwTABmHhnMJBY!MEt#i>kR6<^ZhN6^b
+G>BAa 8@RE>%dLY6Kq@D/ii/^\&*X^+GmqG^yKwThuPjhqm^4/b1*\9ACcF!k*k?y!iDj!h4qcc<ZXwiG?/iiH
yH!$Y& 4&kjM=p>!+Y@au*JC8*/Jt&?i9h$/uK1PTQ9?ecHN!PlpnS&dZebAqX5ZMjH1jk/PhIjSlQGYA\yFE^B
Dyiakq e%TlpXE9d#+#9La9hm/M9MlENSJm?NtTMwu4#8^KtAP\Sya!#\B<X8mVW5yDkpmeY#%4?TjF@X8=SbHW
J/pyJ= kRViN8F^@FNqaHEF1*+beHN=WYVa:@m=Ml#uF$6>I++WNeG/FJ@/TpB%/$1RkM8LYDm:H1<X<CS:HcI@
^dk*!F Im56MuihnVFM%#@IklN4H5uP8mTViImA%Si<?wbjkpp!#:ACe<4/5/u!qK4XVKVE*qMTZG:Hyu1\Ne@b
\/wDYM FnBmEey9?Zn9QKjkL>JZy\G>jZPDA^4PSKtecBkAJt<jQInSktG&KLX9SYa!=E5dwZVj6&nku=<yA89H
:Q\Xw< TJwhQqu9*lm=>C\9II$ZC:*DjM*R&4^6aHdESkyt9D1Yyj9SSm6QQW1n#6=TNP&Ab<HKd/N%M\j<<w%B
&y1XSe yZ1\WPll\JMnbSu<ek/+ZmFEV6uEIEt*m<jLLX8<M4byYN!J&D1y9Bh&Y#CQ*!9h4CF5?PQNSB6#RXa&
5YIY@i :+KbI%L#mRKM5BKkVK=DD4&yCJ&ldNhmZEDj8Vn1GY9$PFHc$94tE=5=CipejV&BdW^XMQNbm9ywm@R1
y8QE?G >Pi\ul8Iu6lES+%t><PQE@i@c&<=qmKC?p%u=@W4Q*S\*+y!pPWaqame?GHVE^jA>>a\Li!h>6b>WKH@
atJFhI T?kjPQ?n!6pe+kmLekZc^%*+=kX5m1t^5iQ1#EmhWIn*Dm>XHYCm:NH<mM:w=^SctbuQbl>mX:Ph//:4
%^=5#X 9t#BmM>Stjmy?XTh4pntEm1b:6=X$J&^9HWJZeWWNZ!VWD\n5eGW5S^*YbqRP&6R+*PkSXhydN:^?u:X
nG@y/D e<=d<9St!eBwhb$J!:PD>V:B$emY<#i+@Y#E$%4jR?Nh#TpdXcPhNN/Ep/Hlj9$J>+\WQ%</\?5p\e4!
6aIF*# IEij=?yRhckHZ?XKEcJuLI/tKqpeWSy=jL^:N>R?l?6?pWp%#>4WB:$4jPY>n\knETw=baQ>DYw>dZ=L
TXK?DZ mHC*<\JnuEHMjK@QlGwIdW!$^S\@AVmZY<h5?Syb!n>a+e&VVtQhXi<hAd$wD4&6KcY%WZjKVDjYAPq:
TV9j?* P/8m9JwM=<<9#PNZ9uc>W$VCcjDnBSGZa8ZQqJaw&lC8%wHql+EnD\TNLpdC5?*c*q$eNd\L9GkTjFqH
#BI1/\ 4pnycW&!DV@bTTq*j*hE$y/9/j^q=XZ*PA8RnMD5&lKt4jkVJithkhbNppPAMubS1X#ydacH\6&QW^8%
YebI<1 GME59:L8h=4C8Byc8\t:pRt8B/@WjAmjZ$Iqyy<@%ytnE!ty8qlF!/Mn5$tY8<%4eD9P?QPM?kY=*P&>
^yZpcu WL^H=QMJ>@/\1tPq/&%4aF&Dd#F#!k<EB$8X<8PP>McWjYqFJSkE!t:^nWqi%l1!#%$pJ91%qP>WBy%e
wJe$N9 /Hah!M\!8Iutepk618kcuDRY6LD6P1>!?6uh$m*4Mpw*K:AcZMCi>%Z%+Id&R6K!@hMqL88KLPjT\jlY
8JM!kc D5Xy+Jl+n4>qWTJHLE^MiR>K+:Chy>T1Hwe+**NicdTAYS%K&4+qhcbp%J?uhm#Ln$bY<59ClcNhnIKG
eC$hP\ @b^:8!=@a+4hE^Rm^Yb4NEn5t@tXZj@1D+diYmcZSqFME1JG^RtGWPM&4>K=5<cT4lP=@iwLe9F#L9j8
tTwL+& BYFMnY:iK8c:PYpR/J&wX?pknTR:iDdJiZ86^Y!I!ly?JN$94RwPdbRSGZNZiYdjq4V=bYL=^<:nLB<L
5@GHi> NKhM5Y+TY$p^IdjH:Q$%<utVuWwji\b%:=p+K:tkbcWKb#@HK+b#Xu^WJHi9Tj<#B<>qJ8*+qm<hY9h>
4lqnGK eVy9GQZ\^:H=$X*ka#Xp&+9+8/8*S!ZG6?q>L6\^hHmDpXdH1H%GWh*!:dT1pCkeuE#VWYk#QNCLi1ni
H9wJKp /P:+Vb:1jaX/6dy+#JBPY%e+86\k1?dC:1$&ja8t@u9Q1pe:1C5G/$V*ZcIXVQF>iLBi:iF5dXmMhJK4
d=%/*+ CL>P<^9GuuEX$5=%+=VR&1L9GYW+awuBl418b4VLG9bn<1chb/=iJi+bqiwnMilN=1EDPXp%CSF1CSe\
YWH?MD IQa4&MJj6t^L+lC<M85XYHLN6iuH>6B6RMTMt&*S&+X9A>%P@bbW51P1It+Zni!d1Dy!6@Kwnjjck?ny
YRjy#8 tKj@ML%LYhF#qQdqd4<P^V8GKc1?4!NBjkuu1QCZRNQKKpHnk+jm6%!>95VBNYVSnHTWPuJ+YyyZY*WB
K%My@5 RIaRN@&RBCqbqjImuib?iq\+bE%dS\\\==:98tcdp?/wC:wG<V5\yLa%P<\k6cyin:Np>X+/u*S!JGMS
49Y^$F QANlyJyn:$tEclpw9:W>tbGN1j9TFZ!iw?tB@q4ZH@8V@#@&@nw5/u@h><iyGYwIacSX8tPaBETpP+d8
6N\Ank :p+SEQ&RR*enInF$N!I1*TA6ImnT1dTI/Pi:%6=44d*&?5DbuL*Pd?>#:h@=\?5c9Pa^:*1?J=:*@Z4i
VS<mNM K8Vn&SNcFN#TlBSI@/%>%/FjR55pEm58:FEMRp8qlcGC>kL6HwVNYBWGuTB:W1X5iPtCiFK6AHC=XwYw
ilP\8D 5B4=JM@6bcmdM1iZi\e&8tQdNmF%%==d45mGZ#C/QDy%B/5VkBM9b!ew*!&j8*6+?1XDwTkbRP=QY>&^
\XMW/F Th=E#N+cY=b^8<NldlXy8QKqaNtQF*Ba/Nk*XFR8Q@+p++bNc:Tih/n<$Tc+$4&jlC6QLDIpbw$dqeS<
Z>=uW# ?4YdY6+4\Ra4RlGd84W9&4588?>RNi/CT9l+Ln\G:>bJK^/I&dF=h$A?cV<p6qKj=em/SGKqP^F9XiSM
%!*dtJ H/ai6IYH*I$W%kA8KIp6E9GHR<PiHb4b<%ypqa$4WY*S%b+@H5b^W!Hp8LF$*4<N+t\hecYqQMVM*KAV
W$w9ie K5SM%QVW1hFT^*AmbN:SpBi5X#EyXQ/ARY/QdScLHyk5D8/LP>5=9E&FK#B:nAW%d:VXpj$KI:Ca=jwF
CRWZJX H!l@Vp$NX?^H>n@nX#Y4w9^Gb6ME>$ScYH!F9X$@GM=6%tAqP:IZy1bJbhcGd4ZKXT/#YcBJtV?i&!@p
C:kanQ cH:tpBG9WJnh+JETL^t#JZF#nG+TI&PcGtt6Qy\LZdc1kZFRSSe!d?QI>hdKRbSaZRR6Nb1HI&TLHd:$
\Th^Nn 4%<<A:wXn$IiSe?BiP%Tq=#Eh5eik>pdBLap1=n<AdYilYa?TpCk/5Pd^PyAY:mmIp*w$a^MuAec^?K4
p&RFLj N9tEy\Ih<Zm:b14myy<uZNZV^/MmXN=Z%XyY64WCQ%:e/Y!+qPyBnFNEQbH/nwNKjHFF4:mQ=+PdaCiq
Ky5dl* AZh+qM&#QA?ECu>+/S5E9y>6mpnM<TCPwq*9bP8YR=LmNl<E#=T>aP!4b88Khk?AcD^DAQ&^1@YHt5t?
nE1C:1 jS1Tk/4aRT8N*!@F*5\*96S>GGQwVBhAB4h\nmMewDIjI\1+Tcyw<dFWMVt@eub^5/?n!tbu6>W@!1wE
8mMXLi Hmkj4SYRy/&5$CBV*wKYB>wGic\=@!4tViaL$$1Sk$<&6nZ*?/8/M8W88cuAha1=bAPGBm!h?DtG<h!<
!<RaC6 mX=XjDR1n%i\W?!kbJZnX%ZqNFnuMJRcVL@H/ZdQ1:1ViPtNnI+N+JkC@qE%dES\DM#cyRPSC?JkQbWc
+Vj??w #TWA!$y!>ltYLt8+%9NmL/CFRp\XIL&!h>LKNHKF5=uD$+@HKNZ\+J@Dk#=9jFqGHAP:SKuhBNkFlhph
WKpIIF %mkJ6$pTIGIQKpZknhy>>nh9QMR>%W8!MWnZ*ki8auRF4HS4eSAn6/%&VV=PTKVccV%IWEZlq*1p^>BP
yd8?!+ tFqL#l*6*4k^wbZw:yXB5i*SL/w$t*M*LCB5t^Y$<+K+W9RG5eSeVc4^iAW6l:66uaH81aqZ1N6*4BEY
iKWFF+ Mn6:>QyXQALTw\Ru^yi*WpEF4a8qMChaucPCIpQZ#PT+BK&?pRh+NCIpnRJ\E4hZ$M=p6%CP<D!aHiDI
-Au4jj 0000ff0894400110333 Page 162 of binaries1.zip
q!w4wS A$BL!DhaLN%RJnaqGeaV:p+B$EiiQ9@GQ!M9i>CaIqJ^6n4:P%SD>wLbY#l?Ac6*Rent68*BI#yp/QVR
H=8Qk> #BI5Ia@9S9KRSJ8tQh%dDC9nVVE+5JJP&iVSGq+$N9FkJNWle+bQL>H4lCI>A?n5A1m9Dwdc4N1DjTl*
WC$HwQ +\@ASVF/baJXw5=/9*kydlc/w+>q>/#P4daRCF+tMk?ddW=6E1yI<baNb^w9SY<$AMhIi!ael^PF$=</
$c?cH& 1TRKw!A+VQYN\\<mI#1C^#+LKG?4/!@>MZhdu&a>^%hYN6$a4PIj?qad9X/d!a=^e1HqhulEnS@+P>F*
1!:<y5 D<XKMtSSILLyJw1l/iF6qS6cbEH9j*PKXZFuTAlCA=cm:Ly4FY!$#pcAnVGy55i9:JAJGBwd>:MZ+b=c
6!wG9: d>=&VA!!Q6wd^b!?E#wwMeQuNtbXBJb@b>Vbq8WDpXl5k*TuXjuQw6KiYm>Vet8wMp5ZMXw#qQPBABmp
V9$HMM 5Z!5eRq=P:EtiCXZybnXK&tKaVqZdPabSQQnl^CnqSV&lZyj4t/@WCwmn+/8GEY#YNZQ:De@Yeq5tNp\
tnCi<* 1Z&*WJj&GyFl+qw>M6?4lTIJQ6lIGmIy*H5myDYcEKE6SGuhcWG^u>qy:6N\j=:q5XyhD=MPME\Zp\uB
W<<YMp 4uBpCy:K/<cl&\tH=IR?!uFcuCbF/mApS#l=1CXh4L:FmSXB918TPk<m>bSZ^XiKG#QK@R%jn#b51MnV
PCJp!& 1G!iYT*%>I>PTY=>!\YeQulkta?DFm^+:Fu&y<9S+!pe4Hh#ZkJ@>hKm$X>KL9<u1$d@Y=YmQ&*@D$:y
\eGQQ8 Jd:VqaYVQ++Z8IT?5td#^\EDq*qiwqhWQ@++a8A!GuWXDd$GjeY1kn@S5P9R1K6w?DXw?JZdSq!H9uLd
RdIHb\ !P9R<C61IH?eNuAJDd6!&>jSGk^&%SY:n6ckX>YN+NjS&6XFFQl%^HbqFRX?LdFhXe!AZ$h5j&<N@*5c
!<?^%I @p@SmQ<Yu^?K?NN:G$KEGj/uj#AW=D1&Nj\j?9L@hyV@C>@/*=4^@<Y+S5A8Mc:l1M8Mc>V@?QHGtb&S
k>Mh\w @$ZlWm%DyA6M*LkX/4t<T%w=B?LSjCQHjPZu<9<T:eST^=<<P>uA#$hLXbj9VAKQ/^a:*1%VmdRbp\Xq
>*D$Yw j4wB\A>qH1u!:KbllE!\\ehIuI@>\KBhWu1ccmE/NEihAH?RiNNwCH>KGb1ZpF<!dqKCEbljc\wy4+%8
caanqB V=L*YB+Cp%kH#aHj:G^QM5u^e&?JAL&VDeBp\>NJ9M*MYl:@PL8+FDjVFXyBNiXJ^1ZCNM9b:@\W<tJ5
k/+!ny h/RLDLJW*XLHTEpj$4!1G=ymq6*F$cIV1tMQGlF/$LcwE*@VD+$pR=B=>XXdT^?@XyT1etVA/Ba!9/mZ
iYJIq< mlE%c@$5l\aLW^hbY?qCKh&/wq&WL/aHlY%MSnAu&D!c6+lcVX:Vt$W6E4N^nFBGTBYV95aMkm^jY/mR
=l19+$ c9I%ie9JT?9bVAkcdwkw?l+?/^uD=SJP/\%<N</LMCkyhSeybSWu^i5q4?\t$^h=j+V>wTj\WA\#9Z1T
imSk>H 6+N1TAMF9VH!L?b>K=VXe\aiwK&%9luP9:VdklA>WlCJL!V*GXHE>VyP11ai?uC9m6=Y?:th<JkQhKiR
m?E=!A @\i#ZcieB^%CYC^CDGIb8\thd4K#/ZH\@\B6&jY4@NwC\H?h=K#@wbAEWTMX@X*4T>%CeQ6ZARHH%4G:
DpPS8c C%65SmdA:&tN8+L=HhbEp1W*%S+J^Bpa/PtNm1k@a:#y$MRtyN84j</6YVTd</D8#d6dTC$\cHn1WSR9
Yb8eK> cAPF<nZ<ytJEbm&\SG>?K?i#9TZ>SjCe*/>$Z8nH+aY6?u:uSRhlScqCEyEHbtc*y6XXN%n<:R*jbc#H
!d!19Q M>H\ni+c+VPPBb9<p8qYR^?B/nLPS#%Ak$G51!5+N=WTk^Je84keKBiDE&H1GCYd?:a1PKEBn:W:J#^L
\CYP!# W4@w+E4qQjJ++C\cbFhD/pMNkFmS96Vj6jkp#8!ptDyGaQ<eb:GNR<Cy5n<#pmA^L>qLJQcuHqhGkD$w
c$+%y1 nDpp84T*EEbG#D#pwe6e&!ZP!i1wppwJHD/>tcpdh<MmVAwD&tPYu59NbiEN<l+LJ1bm/@6hBjyMR>CC
XHEtJb kdcj1I*?R/C@E&K1D%B1V+Q*K*T\E%5H#t^nWMp$=cPe:9&YPjcy<^jdNuk?dh?hiPn8HVXL1awT?jwn
#X+@N9 $mXhk:%McARd4&&Mq:<??T@%4y6>=WbkRaTA5tKa>T@%\Y%>dt:KKmaqZ$&1jYbXDqEwC*=HPCW9Law+
Bt%kNq =/B8ZjEyj1tXQ$>HX\$lkmGXWl+h69?e8+lTe@$\X4Mu<Q6#AH5SbZL/QY/HH&WqF/bc?K<5PdBn4DJc
BAP+%b N8pMPl4e8&MMBM1=i5KB585*C<9:!KNM^B&M?H\kLT?&nZP>CkTe\5dRhC!*yGRG@i&KiipV:c4\S!:C
%@al?m BM@GwL=VJF9+4+Zm#pP=PH#YdL^HC?J^NSp!Xln\BRCC:6P9^dT%XVedQ5i@=W&:&<i/!LX\4K9C>B4C
hi&*hR =YTia<AnFQumR4l\!dF#?LaN^bqaX6V&1XTb<<QcpCTNeIX:YV?JhXM?\nY\*14d+ZBa%QF4GimyyVR&
by<F=< 4Dl<h:1S>i!dXFqb^bnBtPd<q=ihcp1Al6NpZ5WJ!YY&EZQtwl9F^$H$n5?p4iSy&k#C9>V#:$S1\AWi
w*=*y9 SyA5@W^@:Q%\!1^*E1aN#>YtXZ/:n4#=:j9hLJ:RMN\SXJ?Dw6ZTwXaB^==P!!dBG5?F1SXJXQbC/S9K
m&LncW bV\jn/m?#^!!K/dBYAStu=eynenZPwhA&eI#jLA9Eq=8JVadMVTPHJ@LJ<=V!RVYqKji>Z9!5?dBi4VT
wk:Wna V$&BC11*\<<5$wt:l6@ajQK=$<n$St/5*Bl%\tk5^h5C?nInC?tumFPdLS+dBwlp1quE+Vyd/C8@a6AY
ti!=9& ^SS8wTNHeBp#XT/m>E!Xw#n&B!XRNk%jt:nWJ*BbBYGp8HG1DBwm=/\YZeik1TF$Y@!ku?^hpP&#8%Y?
HPRXWl Bki@V<Wt*K^QP#dF\F@%5N$J#M*lE<wK%4KM=a:Xd4acju>Vb&pGQ*S<qm44e!6$54@yn84QYk4BDbct
m*di9e 8/^KN=TeDacdZbS+QDTmHNX+1i!1<k98l/%?L$84j\#Bm=L6jp+!q:w$>HPwea6QymJXA>1ucI\k#B?R
C:wbkG plTZZQ&S/wkR5@i6Jq>qBmPaT^tm&y5q1V%m<LYD6KttMP?PeDb8:D6kl^+=bE+$&>#YP5Zk/I^AJ:yX
Pa5!5i /PD/mVW4I:q8JZ!<dCTWE&%m?jwZ9i9yH?9iAXKF!nnlkk+MKcQ<M?MN#n1MciVyJTTVPjdwbQBSiQ*R
@j$5MJ lL#Yc8Vyu9Kl<bjHlCGeul@LA<p6@S/q8>hYT:j\+?V1m>>IM\m@u^%@N>$aiW9+V\hT6pKW/+c/1T+8
YpJp\* l=yae<TB5\eJDE$+id!<$S<c?C5Ew98bWDH:tVBn*jJ:1pZcRcdTD^>F5dcXwyZMn5?N1&%Cj#K/6Zh4
9EIKJd SVK8C<C*&>m=AHX9J$F#=TNiqTtnnI\N!e/KFYpnhl@XW=bjju%S4CH%<wtHqW!yjhI+l\lERVuZ#FVJ
9>L+6e a^#V\KZA5lT#\1ZBy!tPwX!+dX9WaK$ki@BceKVI*nMX&nEN*uu5>Zk%j*>8ce^>?^k?MGWk1?>J!4&i
wmm:In @h:jNSD%jHScVILGGajFB%:I$hw%4Y4b5?ZW8dpQE%#+@hFNqbBKTFE#!?C?$#M<lw+u%Rw%@nj^!*+T
#QZmPP C&T&9Y^I^!5M/!KXF9^!L6YDyI8bGypCFB&5VaSjPLpA:4u@uu6Lp?ynFPtTudBV!#N9:6djAAa@=Dk=
w/>t+! uK16c\S@i#9>M:#Adw9eQ&SY1FiL4FjmBVhGhuYVLGn8h%IMeA\6$Pjt:wV#eIC8!w+tpHW&JW44P:6h
QS&c%b H*8RAd/1&$njV4?!EGc?V6c8\GGenJJjn9W$yGaYRPLVWj6EGG@&<d//$>h5TFnR<$Eh>**+e@\i*%Z=
8Nq!Yp hu5Y\4/AeI<kC$4+R%/Cy/Cq8Ljw*@wyX&*L!WtRNY8BD+5Nj5tXQ%Dc4YBG!=hRQTa$WPC!iCK4utld
@RAL+6 Rdb<yqlm5+l^<%XZ6m$WS*DM:4kH&t+:qHN?miuj6i<d?$YI=&RVVDc+D/R$/q6:DLJn%^A$k1>yiTRE
49n6GW WHC6i5ZwKBKaRMy*uaJcAiV6yQ\&n<q>9Ew\d5Tqn*qn8!H6#hXEYj*T\X8:lBS>8lXl4=m:\lT5It$9
$bHK\V CNtD&l^MqB*ewl\W&*jPZMi4I?$lRIB/+9A*P6bb59%y%*GQ5B6BHnW$d+n$tlR:Y8WpEyI/\ut=tG4^
&Vu#TW CjctmbdHBc!&I&%*%aM?MDlwcVBZt!mPW$l&9ZJmXa?$M=Il\jTlT>iLZ<X5!/<w@$d=ty@5h6c1Ibq1
VLKL8h X!\?JdbkAacb#uZwIPQIHYA*C#!aLhQmQJTPb!/e=CdMJMV#?aGSj4@LTYRdP$V^nYuNTQ&4akJ:$HP<
AiGhyB VACPY^\yTI5CH5JHBR9Cum1Mp@YeD%E!^#9w:jWwB!e@?SZKu>K#JGD%kT@pw&Ay1/@uidlZKa\@n?T\
i1ee<+ GIB#ZLjZX:ll=/Sau:1mX%+&#RLIF5FHeH1R#@TIRaP$n1w<=6uk1l=AGK85^PB<lXj!WaL+W!HJh/FP
XCCWbh kLj!^?ZNYZGyp?R?pL!i6h4d\y^nL/#!SkW*IbHM4=&k8Y>^>EhS?CNc@4ZV#6bWbnHjBjGXX\d*nb#m
8pEnDN Fd6^hFlu#$i>uny/IdG%l%X$9%t+#Rjql51RkB!CGjDYw*nqC!h8EWStC#mSnEiL^&I9I94InVYeLAn4
@R$eh> p=a&k!nm#Zc6BL+$l6>w%tXiE@9TnWMePCFhaP%WY!E9DRSA5>c/wLb>T9l+4>Z1=:+5Dh58QF:T=Q+/
Pu5iVC >:CjZ%jwZJh#Zqe\Rc1lGIkYjMT%yD@+E^dVb\C<uhVjI<eSdXunc:c?1?^6FGu9qe9ZJ^eqD%yd5Aw9
mF*y9e ++bKuAR6?NVTQi!cqX*?^l8SX>VkAKnwM^&HWZ8d8H59!le>^?NS8L?t\y4p=+yZu4W$$q6pyP9h$h89
&4qX<h Hky8Em@G!Y>54ClV:wnXpllt$uBuGqkN!156WiI\El41iZ^p!?TF=mZaWk5F1^%JZLmHLCyKFHEYQAYm
S\pAFl wAX/l!pKRmW@lB5In9c&n>Gm$KpnEP6I14\VGWeRlY\+9%9!N!IYjw5IXRj=#\W@1KMb6htQ:lh9\/8d
TtQ\He nVnnhKmTy$I?/qM6Pc!1GlD?/d8dTDT56LV9a%V=p%N4E15\JiLmHSHmBlHy\BDYZFV>&jHAIt*@V^yK
PthY!D SeMXWyl*1#1:^m$b>j&*j5Xlj/=#pVGQpSeXEud#Z=T?+4DFK=#J+ERV:cd5h^F>+q^XlIWZBMiLK\=I
SJWFkS Qm#?d1/h:c5quSVJDN\@Z:jdM?8*KXEdc/wQ??KA1TY1+8A#Y1%FpXd#H*^NnN><bqd$<TH9in#cH\Ge
^eAZn\ Z!/XNNue5E/FqBWF@t^t!kP$C<X%A1Bm85QGNnV&Fn\A?I1&L5DSSEGap5NBKVZ@96D44KWMjHT5RcIL
R&dpKY 5Jqj*mcIlBJP%nFw4yNyEpwpFLJhPF+EBLK4^+C?j\*TLeX%Vw!!eB?&jV8B+P6:/=Vq\8tPV@laQ4GE
@Vhmhk eF*D1y<#Q8!R9HVLWZbXX%kCPJGut>cPkCGHNRkJjR>IPR#$CNd%X?RI*V>PX*=TFmVy<tu9yBIjh6wh
F^M<p@ w1L:SZ!k&nG@w+w6:Bd^Tk?J8!udb%9:1qVjHDVdV%bdP$%E:1Ic!=h>X1N918cFeyhYqYP9lCYacRtt
D@44j* &FYH:i8MW/=?c=E\mBtK9hG%DhB!R>Hy^tT:l+W>ZCyS6WE:uGnD*$qwIP9X+^S%Zh4TX5?t%cW>PKi@
-AuDeB 0004ca3440500110333 Page 163 of binaries1.zip
<#<tth 8HTdVSuFp61cY5<D*n*lV6uDtZtt4FbK6CeNTuHVT+9>Re&BjuAHnS$@jK8t!cMlQAZpwtaVieB$uBHC
T8we?q 6<p/H=VhTwIb?D1$HTqy!CdmpTqYw=Ci>QWWkYy>M*Q+6T/F6F4eRqG!+&SpEBBFByDNhTjpkw&6!H4B
>:^jXh mcSk4VyCp^mhPy&QD^Jb8+K&q1M+a=td6*KJiW?R$MT&@4!kqBa:#FuHX<bdjG\Ik1<KS@Ja8:p&@9IT
l@p$qh q@l#YwawSEm:deAIl!Q#eNB\RwKERj\e:bjhq1Q:ctZ*G!SMW9Hq>6MpG=w<IQ1!/te/!8bI9edFMPZ=
^HP&up LRW!>Ln=6>K!l#V!RpBLLeWVl<%/c=l><S$qIm?99EpL>BPL8nd>cYFRF9Q&\A<^9qP!LA*nccb&+E%y
pYNVYY %9NHRq/Q*lMVqBS+WTEF4R:XW?&5=G^$=D=Gy$iaKe%udW8ZchkS5yFk8<GDiX/6NZySLSwyQ4LAjjth
y\nS@% F$n>GK&E/uZDt1GCe1^dX\S>CauXC?#ZCF=9YuJa%/^SBuHEBQ:hLFVwnyW/<ZbnSt9i>99e:=*G:^9q
t#qaDL SAi6yyS!%HhNK&R%=L@uKy9tDE$cyLMc9mD=HC48puWCX#VNZIQMa?:eZ$$&jY@P^6hu6M=6</&EpCJW
ciy$:w !bpX&QW8I+5H!QH%L6kb8jyI98H*yGF^ZkbIWXFe?644Ie:tFT+ca@>:M9+T?Y5XB6%&q$>&?E89=V>9
lC\D%W k9@bK@w@6+4mL*&lq@TPi9@yL^XHG??@>>KEIRnIZ^<k@@IA>c?Np<LC\u>bE!H<q%$XF9:4e+V@t9H%
%FFb8J y$h@?T<wBQK*4qEb>\j@$1H/d>&1$E5C$Q?!:j>Mq!5C<ee8X<S%b%L<#VH:S!<PeaqdmwBe&&^FRQ<=
PEqN1! HQcQVmAC<l<:kjC@d&FFIT+:!bjF#EPl@/?D>d?!k^W*#&c&8VMS#R%uGWC#NW:+GG!WYE1G#Qh&M<@Q
dq\XQL N199&>KT5V$%apB<MVHbWNl:JMM1Eq<ST>Qd6YVLM/BiEW\H%@VaBtMEQ^k#DRjLwE>jLYp9l%%StpMk
1Ym%KK @59V^9:!=9Gj8bNSq@T4w%DZ9yQ@w9k@Qdm<SS%^TiWHkd#8MmiE!DZwK*LH@9SM$i65?/4%YWnIhYnl
/aY#Nd K+w9TPF4$FjYCbHR/>BZLSyC\1=B\+Y91Jel+hikaXhXX=GI/>C\1++diR$cm441mq%Hc%i@@!NF@nu<
!G:t$G Pt1D\c?wccP8ydc4/8twc/pNhpY^DkZ>y?n41P&KXLI@$jB@mpd<+TMd?S<qhj%d9i=jQ:I9Y*YCR9=H
CR+P+E 4@9H6K=@?@V@<?5KR$R8i>*L<41Rj@4m>u>#Zlj!@>/<L4K:leL@Q<94ilFepekeG<w<^S!*+6GF9F>#
G=8q+T #5IE*%ZG$6Xd=WZ^NLPp%u>A+dE>8bDI#$RL6:ld>?%R5AX6j5KRi&k^lFM=b#ICyTVV#+8DJR?*:+@@
#wubHD Pd+4PDy>58a#nlMV4=K&Ny$MSFdpFT6bS#WehRRQ969YVh4HBKBiylWVtTyey^ptX>RYGjSt#Ntjwaa@
4Mt5ul +::HW85CX6ZGu6GNyeml\Zhliaij^qK<u^8MNStkWiwu4Stm$<ldttLpqliFW6^Kj+u$e96#yBjjZ!K>
qXl<&H H8qV!?@F&DXP=p5Y4>?uCNe$nmj:KSW+e^NkMSGP@$^PZGQ$S<h&PG&66ZG:bdI#dP1t:JF%?RubMSk$
h%i4cP btF*iw<PEEm9R!NmDdW/6YQjYW:HjnJcSjmKManN^cNEhTu/>Cdc81tjuBwytpy?$Y5wj1B#L%QZQd=I
PC=R+6 jZHL68XwXCNC:#9%Rec/IQZe@ymwu?aV>Q6m?c@*+H8P$h6TpmhF4&95eqNY/BhVSD/*Qpw@@9RicTht
Y##4jT JenbTC6Ya=G:4pM?m6iwT/RN^clwl64M1#IC*FZ%nn>G=i4hdN*BaG/&==%KNES&c+@Q#GRbD!TwGaBj
^HawM/ Qd5qDZ*JL+KtEa$VZ=9?yC+jNLKQ<A&GkXcELJ?MmZ@JMu+*^BEEQyqq4EKlA8=dZZnh!5ZjtL/uy%>/
p5*qIW e98?1YpE4QnwA+BjKCF:Su>QLjTSipQ8KjuM\^hmD=@eGcy<\jSS+P*nJ5Zl?KK^$:b9e\&l8FLwt!J=
qKM*A^ F56MVk=?R=$4KJVJG@C&w&QW1ulL9&wy+*ty&AlmlVCVL5ip:XmhK@\h$GKE\a^u>qEEK/EW?D\qL?XX
Pw&>ET cFS9:G68mdPbJi/Hbc@i*i>9:$6J6w5ahjucmD%@\LL6AeBh6PJQR!@eq9cWeF4<qJd&p!w@p=55<TP:
@nFM8a hGpM=X!$tikECIE^+N*X^hG@%=G9!yWi>Ik/EC<wpd=QmLdkRmdIA%ShFl?15*!!:Eu1*W<meC@NAbS^
JM:XJ1 >=jPneYu@S6DP@E4!+pWjd!lP1QW6*^\Hn5?Y$ZwPtXlF^+:C!EqB%dG1>/Ynj4XB8>*a^T>hR8YLc4C
^KK<ui q>4K>M/%n$aA>jt&h%C^VRuKXAw%?Yj%N8&q>L65@mVBn^R^>F#tL?M#1F\@T:\dKM$KuW\p:^KX%Nb#
\+JYVt DA+^N+MIm>i?y@Kb=NNM1p:&+t?Ta<5eEFBQch\6J#m4Yt?5#@%/C!*kRCBNwT^1B*AXGD$$5d4^9qYp
=yjmlC u<1c8!H/pMF#QtN\jCNHNqTY8u#Eii6iHFh1#\Sh@T6@R8cDmkeaL>wlH:YD/PmT%D&IL6:d*GGyZK\F
qIqT@+ tlbZpkjw&LQCH>c4K1YeS^yWhHiIBDL<KZmtALLGDMhZELXqPeE1+KDibN5>+?F9WJp8SiZT>cTT5>QA
PptS$B uaLai&t!XMuuS==9GZdjt!jG#bM?$Ik\6PQKPyLntb4Q$4^u&#ZLV?1M4Ww1MW^46=lk@IBLGnPLc+6^
CXpmCC eN9Sn8Y^il5XH?1j/Z*:/RjSwI<bc5VL*aW?XJphE?JVW!QXiCby>>Jb&&dK/85?Wd4XVWpihGhjQPSI
/C::W? C@jb!tae5ZDbaBYwC6cWel#PnKHkN=^%*KXcXDbkR%pI1?V#5^?L>l6qJjC5l&kemQjya8$MMuu<^:LH
$=ZX8* =*4!@ibj%tu\:lZ4\phhLa4<M@S^k?Djawi?11*?%q?u!qi+y!EEVkneaN/wiLTjp>bY/=9GiZSZ%=NQ
^HaeE8 l1@*Q1%yTLH#Skm4h/M8MQ!iJhHaXk4Y!i!k#5G5V>ZPq8F^y&RBwjIyBipB:#9YG&PljL%LCh#q>cXu
neXq4I c+hV5EuR8!M!ZqKPwD5A!X9+8iIbp\hGJhq/M?y5?A&XPBF/F6*!NTSqFM18RWmnX^b&bB%/*/*WDd44
<4ABm% >R#+?5^F/G$S519q*t#$V6?jmYAYY5@VjM$4X\XFlL+*cMjJEJj!E=!QZE#eqMJ/cNM4$E8K64>MtwyV
NS&5%H %P+uKM8Ij<V<wCJKn\a6LZMkHQ!!yFj$pE*eam:ky9L9\Ba<&uch/XP>hJwRI/<*#hm9!4qTb#Pc*T1w
!=h8Xq :F@hci!9Z9jjNRI?8=i:ED8i8MibMNj\91K^9YFY/b6X^+nQuHdBY:j5h+=+$V%T8JI/S4kFQmmbA#j!
^eWdq8 YyjE*X5%Qd*u^%<\CA=c6Zd^5JHT4B#&KB@uS/>!\t?P8V=QkqjjiaQ><wVdhClE/?^W$=nwEQbp%#Ec
%GyRk/ ?<W6Hb:neCG1Y4btd9c6/+uk4@y*EckI@tj*^V^&?q\SD9VFFq9QW/Aq4a#*E>wj>k=aedc:<D48q+M$
WThV*: An%@!n>a?Nt<V%J*R>%+idt!\EH48H*/8>uF*R?>D^X$@JtbLXD9Eu+lKy4/<%JGT4IFG*ipdEE=D&@$
MWXeNQ yGna/#\wduuQ/6$VyjHF>lYKK+wy%n@B5/b=1/RZ=9Z\kXh4QaeTnT5Q?$LL@mSN+u*:%J%*$/GA%m*n
k*LKdE Nn!>+=e:hPR%H@y94^^\jt#TNJS/*m4K+?eh&PVZ4aB*Y?:JX?ddWTjdtK#\FY@Q/aj%>mMZwTbH8bp:
Hc^wui db:h*\c4^IwniwiYbcbE1\=^\c!S6yR5h#mCq5bbdj%CZ=hHMw?+MFI@GA6QDRbw!RwwM^!@dF>\$P1T
:M*S%w AN$X//+a5YXbTDkSm>DWYZFQ*T9M:Y!cFVQ$?:Yq1Ec\dPCiVhVdiM=/J6XNmRn9kId*AZ1yiFeEVaW/
VW>R9> VK$NbN+/XLQ:=d6Yw*6G<YN9>:k&Y4yL&Qd=L1\<eiTjhh%MD?RK/YBiHXMn$CG&tuEq/tD8G^l#<XuV
b4hPA= Iw>=9iVWFmnId%:bkF>VG8Dl6#aiD4SLZS9^W?<:Ihk*!qXXuIknA/!h?+/wF+?T:MjRA=\/Y5I^c/y+
e=b\mw ?nc5#u$qJKy?I$E#lK1dXt>=WdcTV<P\E\PkTa=qSdW<*>Xq<#n+k>E<$e%jp/QnL8Rknd!Bl&8kN^^c
=y?jpc #hnd9@Wyc6R^:ee#6QTqQll%$Il#Wb$AE?LQKXQYVmtjQie$?4YldCJVBa=VXtiiI/<>A\A^*846Nu\&
9Bw%RK 1ZGX<\K\t=/k1T4?ul&SD$EL<@n%>qHEFBP?H$LZXehG1V9RSMyH%KyD/bytb4&q*&y5!T5hpB^Wdha?
T8ie@V im8QTWJ>?4hwAY#N6l5Pw1CLi#H%RI5iEDj+Z6D5$y4PDQQHB+X#95C&q&#H6lGN4RRn?5PVkW1X^Y:m
GL@\S< /jIBTe\jG=aeKi%:*Lq1@TbGS9h^SEq9*S=9d*LTJ!mFD<T4/&GZF<h\#EyuK+t\m5XlV<pi5QE4mlIM
?k*u55 BhyK5XP^j=hZQLY&yRB=$yV=jpk!t!GYw8F8a1DIIm@HATwV=JPRcQYqc\MM!KI?+hl<Yi$=#Ky:En!c
@Ik&X+ HMEbMM&S@1^5N1w:M4hpZVjTAyZeV5d<uuhVewb$X4EPcLM$\XN?&+XQW+CCPbM6MTL5MJd9RwVWcTaK
YAQ#h/ RNyHE>thcF>kTaQ9?/b:E4lT1RcWEZIW1h?l=+*jLil:T4Y/th@AWLPSW&XQAmqj<PRFti+WL@c>Q8XZ
LjQkLL b+>16Hhn&E6BX/+E?TtCa$c$@Q9c6H6NCd@+VFb@ceaPI4+5A\kQQ^:eIwN/:V5\?ZE4dw!%Gc4WA=WX
K::II= wIILwIdw8+:IJ^NmtASCEb+CCk19J:ACe&GDS%#lamZaZC:!BmEV9cMCWEMCI6tRVF9Hb>VuT?HTQ6Vl
p5wG*+ 6KKElYNVk@u4:Y4u&+Ilt>Y1khanpRyh8i=u%84!NaRtd1:u@ah+t?6h61W1>@pu*!qqY#W+uB%Vjyjh
F=%pa/ 6JRQG:e>pq4uQ*GY6kHLQ:G:BatX#?J<I6d\PlqHT&^$WhJHjX5iPmDwBHLVq>^\JC#c>P&JhQ:1we9e
qdT:K= n=NWP:HX5h*6MdTL=:l>T+^=P\1WIKB$P%#dH!XQ+8@IMFc>Qq1>9T9b>dBMDqZMAMS8a54*D^w/XRbD
hn=j#N MQE5>*!GPpQq%/QQ>4*ZM<A6DD#A?kSbhYkIYk5D:$y6W!bqqI:%LQSSV*16h>CqMnEiYc4/e@KZ:j1V
yC+e55 q8:>!lIHHWDkE4kXWG\p^4ukW^cj9=Ja8D9?Rbhy8nlVB=#nliAHAH?qK#%qCX6YnKWTQbHW8Tq4ES1u
!R&tV+ W&LXnh&5qHT/V#:yXLb4wb\KwL=\Ll*yRHCuJQ?8FP/$5Jwumq</m6<Np!/CSh^Aq*ZpcLuX%p>^Rh5h
kMjhnC <BQ>K8j/n+=hl@kwJ:?IqYVRVHGTScLHLTcjP@\\Fb\^GccCSDhPFpbtFcR^\D#!w=aLk5dCiKWEiujF
k@?w11 BlKH?W@X$?RkZ45>WTH96t+^<jpXEyPuWwPdi6&IK%ARaPclVJKP64DRwJ<INd@h!WXnh?ZDMpY!kSZF
?K+bW* VSD\1+5%\PIla6yMt\SAI>8@%%Zbpc?^9CuahZp6BCZ!*:5kACZ/u#MklaWlj#AklTGm%#Wk@@w:?^?h
VK4jn& AbFL@BVW6XPlSIT9RX?=8pEEik*/T6>SBHah?m4HXAS?DSy^=daS%/ESX@mPI5n4$FiqWwtk4pHDSc/m
-Aa##N 000f6d20ece00110333 Page 164 of binaries1.zip
MBk%<h Sc=D\/</d6H4$MJZHLjwhdRGR%/^=/LZ$SwMi5Yim%=Hc#DIXjS%6AbFZZZe%>EcFH/Fh!h/Hc%B4%4e
MbA\M+ IHwh4X%6%wyiS&!\1<^>$i8IDat/m4/P&BCmq>QCEMk@SX>HdAkp@A4/PtJDCEP9wGH@FA&@%p$tekX>
&&+w?p LdEl464&heRGk$P8wK@%^kc>/y!L@KMXnSL>n/9T1L?4Tk9DLqtjI9#*kZl@1$wn@@<9YGqHjpXamqC6
@#q%Hb Bi41B$#JL\unSn%6Cqu$dHnR#8ykm^jKp&BeQ4ub9QFMMi>#LW%5Z%iwBqh+P<jZ<&ejN&A/*8AM=dBT
VH/SaW KbyqplDJ:Z$QQT19LmD^iWk6S&iZYKcAm6ZTC/LPy<j6LCCT<#jq/BSkD69uwdDcML^CPkB@^R@8aeBI
pc1NJi %<XwR:/pA\Pm16aGVEJG=AWt&wQd$:&I?lA\*&jNQL@VHqiaSS<uFJ4JkQk!a4iG$Z#c!W/&=&LQAeBd
j?+AIb 58WdtHS\b=D9qN\Ga+Va5YASGCu/8$TR%uyd=+/FFRM&PQ5u=ilS4GAZF4h!/WDa^jpPCXSn@kaXL:EL
SJlM%a GkD4a8+TW\w8>RCV1FeYbIVn%\/J*m5:<qelq<q=w/\C>$Anal5HHD=!56*mQJmKZ=$AeqT$#eY#w@Pp
b#+Yl6 nICShG+%JT!%>mJA1dAjqHwVnIJ$A8B:XFQKbA/8AkMc%EpR^KqQ<+=w<mIuQT1b$lwTP\44%^n>LLp?
u#:S8y 4TCkHWI#:GZ66t<eb@1MuXMAWd%w=E&$P#9^VhJcaIy&6i98y^V1^uh^6C68mMdS6b<CW#\\^jqZ4ni@
calW&A 84!kZjCP@uV&6A6<4$\SVa6Ti^t+*/SFXV=ne*I^MD:<$MAi$ny*N@4E&HhHDdLaKjQMbiJLnB!:=YjJ
RmI%8+ 9q&M#lQyn?T$ViZ41K\K?TQhW#db*J4K<em?u9EhWXpAu1pKw&1um68<8J8^u:Dw=N\\@=\lRF@ISPhS
@p%4im ^<GHS#HKhJ9yjTWR#dPb%>6*YiLbX+^\Xjykdw<Yp8+5HS6LH^#Rn6=^J/S/!At&9K9P9Y>??JF1R5pL
+incQm JR$G!ZAQn<k@N4>biM@EX@L4pc6M$BRlth=Z^?X*L1+K<jkW6w8H%e*jli#Qhk^/4RJKT&</B\i=%<kl
b?DG\t tA>yEQtl@Yt1$PkZJZNRtW/FPF4bG5n=1J9a!pM%566un%d+etbA:>t!>kB+SXqnADE&w!N!pwVHRZp\
JG@yn# wK%k=w%H/\DeF&<pM*/Np8>+wBLwcX8%@VJG&<qW=W6ucYeDM<#4P<W6&eFQi:8&dl&MIAa8EwS%#IGb
?5:Cq! !wwkqnbe4P*6XS1Tu+m<QQH:4W+@$m5?lcnhW&lJ<eNP?%pF&qZnQqZIPd/B^?GiwFuL*8FIPlw>bTaA
+E:kc* u?FJhI1h#q/TK=jka#%?ud+w9HPZPJm?!KdYYT1@*DK?<SR9%i/WTq\PGW>&^LipTWyq+ET&^@^PpL4Q
E+8cKP mZuJJ*bZuWJlLy=EQ=aL1HpPjdd!p4Yd8pb$9HFFi1dYKhm=J6/#LQEP>d4$:Wetckjw6:h5R@wL6m&R
<<pXec i@CDCNpCnR#lBdnq!J^KKNy9IWR^4tPSZ4KX$w66ZmmXH$?S$j<*nk\/H5&hcq^PjL@Xwt/6S@XT:AI4
aPLiTi @yAy*Q45+T^GlnIW&%yQ?=Qlu?#TCwVER!5Jmh/IiNG$CpE/XRGM&#LdTNb&:JyuC>ulyFa&q#hN58^?
5=m!F5 dn>@NjeyuiQmI=c<I+udbWym:lSl4iVBw:8!*\11>dR%QL#Zw85#Q!NGy!i59*bG!KWucm<GF+Rt+cd^
T1>4H& ?yy6<jCV/9TXVR^HmqZRWquJjY=h!Pq\mX&EW<y>#pEJlp<*bEi/ied8SSYmtF?wG@9t8M#\%cR@$E^>
l?nw>h SABZS<>BiRMWHcp5A?5//e5X/&<d58u!KklVyY^L#m=HbdIhl@FAbuuVh@nE:<tQXc6N1d4h?mq5ZiMQ
VL>emH cb!b</iXhZkpVQNGmVX9Ehj^c<&5ZNS:NnuWbC9$iZSeIEMEtbSWY1:HIG6DDXj<Al9L6uHH&q9Ik*e+
MI4%yW @G56pW4B>ZPuF?uhbWW1>qS9wJSilR9<iE<w<kQ^T#\6?I+KY!wA6DMQA\@&j8RkueXwDS>qKGIjQ&<w
CXIcI+ I%l+^&1mQ+IYhha1HWWemh@mGmF*Aw5b*t:wF+^4M$\:e9KTLuS#=n%jpN8T@VCa&9^//aVY!G=S/QZb
D^#A^? $qu^<1E8eD%TSj?Z/#8TibeSj:=8dtZu6X$w!Ej<R*>aDiL4SM8d#KI\%aenwL&wh6WGuC%PV4u:6b4:
PFeZ*M yti!8\M=dPKj6hDJptMh=uTt5Y\Z^!CYBDcL5y?\uhkTy=:>W6dG8&ckht$5=#qNjbFe^w&AHaYGCEdY
E1A>6J W*hTDXkwmQ>*ZD^MYL?NVG%w9>&Qjpj?H@1^##4<@SX!M^@\c*nJbt:bmZRwtB&?bXRENwl<cY<c#T*m
JmP*t! nP=*:uZhNGn6j>4#11m+ZPP66*>WnGlFkmQtR/liwjA:VQmaYJ\@/*iw*?wCiaQTdaM?W9KT%Y#LKSZ%
=KFJ9X I<Tn1aChIh!$NL&eNqICWk61*m4eNpk^=RKyG4>QA>Va5i#CJpMhKqRlDCnhucPNT46y>ik+Eh/!:c?$
1Jw>6H jjPu4jPk!+y5BmY?>6MQ$/>@L<d9c%5/@NF<q>Zc8d!58j98PnCd=Kbp&:9G$#nS+y4ki/:>@t&:u8Z#
I+N=/b a+XI%y@D#+Jh*ichZ9Iwy@DYjZZmehnCVS^Gudb#W@?5I\\Q5G!nT>@%:9h^=V/^BW>tD>jjWl95aPLm
JCVMdZ eHut9@&Rm*uCQtWtLAL>Zb&ZBKi<XQC?1R:mC+D/SePLJy*%dtjEI@@=kpF+I1W/8ZZBtM5ei>VhIb$C
nqthp8 ci??V$kuyw<QGEV</!djXRuA:i8Vbc\w8D4LM^DYa=EV:Q4e+Tb<SZ+KE+aBnu^pqGq5*HY#Gq1wShhT
mqXI*< Npm!K*^NS<9SneaykE\+V6@$$Y+8^T&\YaCY8IGNXJka%t:S<88:G4lbTC<u#cp:?a11PFudl@46Gw8c
L1GPYH D/&lG<JJAi8mi:Vlba=uVnh9R=dwA>>@FJ&<R%444Q/NI?=#K/ptFwd!l>HVF5!<$9%S#Nb*8/=m8N>Z
u:#\#m jAYF5SR8QdL+FmnPWE!4#WTtZZ*EGjNBZYL%q?%F<ZK=6\wNTtHi8yn1h+/e\:iRMa*GRcG#m:ePP*p8
%y=pI# 6lFtDuLLJ*mBH%ThhDmB<AG1e*iMeh!yE1Z+h@jNV<N*eLqN^t9tM><PXhda9P>8?$S^PI$6#9HA<*54
YlulTF *4n$GjD%PJK>id$4t&Pp6H1pPwBhjX8!Gn+/q4llwNIVt:ll+$dRliKMhCWpWmY!iYl:<Wy%wZ8DN/mE
Dqwdm& F=SuSA\!/dcdD@$1ep@yXN#CVKY\ABXWVGK:m<LRZSTmEd*RN%\+AJC1JHhIaITbd$>QX5RZej51pyFX
bGlTme \?4JB^8?@k:MX8MYH1Mj4ZwT!aH4ZlZ&qNc#!J$WkMdC8+y^b$l!Da<iq8<#Gh@/64Qjy>JcADbQ+Y5w
@$9nH6 H5@FVy:h#4+WmN*8H45>WY!^dMGaIZ?6dHW/q4u?N&i/BqK6EA86eDb=Y$q*m8Gil1C=l6DKN9\FFa9w
ZuH>i/ ^=1<+:$<>M:J9lR&VY\/acGb\b:%D#G!deMDKNp8XL@dGedMmW9!R@tF1M#$HnaJu\^46yXyBhm9G<:#
+ky?Ia 5B/?\/u5\8@WEK:GeKPW6@+YpFS4D!nHHBpTR5ZhIX!5!KP1^45B4ykB:*!m6cPcCF%A4u1k\y\edC!5
m*yKIY MPwb?CGi&!Ey>i!qT=4E^RW@ea!y>4&!:i5BPL=m?$S!&\FIPYq^/<yQNuauhd/t?Q*et/HeaWGBw:Re
5DH9PJ ^je=:PMXTLXWtVFpRXM<A#StPE=h*dIh%6Y#BDG$Z4*<pWbL!?ZI4+KKXCt*amw+dW6LI=jE9e#9FHQj
$h?ZDB E%w&&JdeXt9Y+dZ:FQu6X6^F=XBPh:TFS$*y9HYqan^4QXH>b/<ilEJ:YHj8=!HF\G:j#>15%9&9dRSK
nm\cFl H>i!Cd5HLEY@lG\Z&&nj\mPynTRb9uQD^ZC\9NS%jK=jFDapVKnN?+pMG?e\*<ldBkt#=MQ*p^hcSweu
NK!RnQ #nthP\FFnNc^1^M<a6/FRAC&$LaTkJPJ4PQM5F%CSWy9Sl!1PtQd4LwcAEM19MbWtEVkF@=:59YGS>Qa
/jBPTP eXd:MtmqP/cAJA/k^l%Q^G6SHB$Bky94EBlPZcBT^5Kuyt/B&54Dc:>LjyJM1L\I^?:pPct+K!J*Q*:q
+AkVh! PJQdYy4k=LcH5QC=GIuDd4?Dujb14<wXt6PSdBD6XyIpSS8k$?X+F4D>4:jZp^P&^D!l9t8&4VaDRYKe
8B/HJ$ 59iEw8Q^*em\4<QL@JWWNG@8tk6l=BV&RM<P#JYHXbFd$l+YTTwPE6bqKLK1:S<n4!kwY?>b!&ikXhe$
lAuNG^ k#aI=quH@Db/66Vh\6lY5#X5SGS/L4c5l6Ae5hXXGPKq:eyC6/+W!E9daSuAdhSR4puiRG8wjE4^\S$%
XI%EF! T$uKdq!6^Ae4!8qCPh$QRH$#jNwW/K+!Fb=DMV*\<9$cA4&*JPbj!Rq8nG!?yVMwQD5p\@!t4MD%lRAl
ZnYC6V tX8iS9J#ci#SMPaM#dBVYH\ebpiWCAjPIE>euHqmd488XK8PM^Kt!My>@jX#H?>dwe/*#e\W8S!=nTZZ
N1u6SM eWb?^X:\Dh>#dw@QNe<NE4Bu8w@\%QhVc?<wqYRQcWp+W<uIS^SIDWuH\9E$q<bE*d/RRS>\Se58#\Ja
WZ*Sc# bjW6*Vid5ZbpEY4<*R9m*pi+Y8yYJe*8$:L4TbNjjFu+Th&AI<!n\J8<ZN@bl:YWd9:Ga$hTYb=lYYm*
LQG9<% W+<eV8!!h6eW%>Yt+!?9Q9bIXki/cj1?w%:!JS#py^F9DI5Z>&!:KHVwytGAF>%^>CyVnFQmP4RTn=C!
C/*JhL VHy+S!hp4#Bjew%H$J/WYW>/N!1B?ZCaE&8*wCDHV?K$X5hNu4iATVWXwuq1ScWe*8GtSKYqE14Ay\NZ
LS&aEY tN\DJmtb^\WNC^dIRdI@Sapy+S#:P!i1ay6:lq=/yZaykibkdIp11#qhET?>BM=S<Y&G?LPiuLK4>ypb
5K1+qR Kw#$K&aIwNWn/Ld%W4hQ^q*nhS+j+kFE:%LwIDSCI#L+uT=>j/aFF>C^u9RBlKB?/^GMeNy6<PliIXn8
+cAe\# =EqF$eBdCytdG?%>\/ALQp+FD#dFdueqjHh=!6n1S45c/m#=>W:>hcSJqFNybTLb#ypSi+6tSw?S/piE
YLuam^ 49K5I=hVMWpHFd8X>8Ha#d:eayB66\X!B@6cSiQim4@wqmj=^BdHe1MwHae>/<D=RC>XLC^$Dy\1#EPG
>jQ4P/ *>XTwi:Q*l&8w@#JQuN+Aw\5jiAKT8!ZX:mNw@pEHGA<eM6V+Dj\GyHkF?#wBk?6$$$tWuWuA&b=Q<ZG
+8MI&8 M%YkZ<b>G#N@qJNTqb#MccbJ:i5t<wBmGCuC4>bp6i$8t+6YmbN=^GPVMK!4i^nbae>9ah:+Kb:^\1ae
=y^4la Wi*FIyZGD**t@hL8$lB#1:&QJi%yZuJV<Z6kh+Mudn9cyGWZYeMVTId@t$%LbQLN?=yBEq*<>/XJ:whi
!IW!l< 5G&AJL5c&bi%JEMdAZN=A1^&uAX8G9RT:QH^pqaS1T@WiZDAJE5/QB:S55^aw9%wa8qjbDK5ZB&T=M6A
VlH*uc Z5q5Ay^t$kI5KISj*>?AZVPYYXbmi5c1!d?AAGiPBciaBY?Bli*Ljk&^d5E=8/@1jqiuH9bQ9:LmLMm^
ZRSj54 9&ueq?1^iDHWJ:emiXH!K6:c=Ap=j@Plt1\!TMYPtDJ$$Vyhb?u:lej5lNYApWpIE5CA6^n@SbFRK1db
>6*NDN >qdtT?+KE+RCAPlQmmVS>W=9E$?Za>lw8C%/ylwV=X49cNqeYED>ndMn!qE=%CuC*6XI^!nd$L:/*8P1
-A\*<Z 00058fc7ca500110333 Page 165 of binaries1.zip
pXqEP% Q@&BdX!ZWc8JXB4qSeZZq&eelCq/bNi!eTqpB9dJ*dV8btw\WZZS/@a+NI:y!mBt4=#\XWwqT\l%qlk\
u?G+mR >6q#WV#kjT*Z18J^/Lj&$\aRI8>HAjRn5Hdq\!P<eCLND=:Mq19J#GBaB?DMXJ*6X/lemII\+Y\*hSpt
G+/n<N ul\<VHwwWl+&6qKcb@B>Vw:9X8!L4&#blPJmN&XJ*ljN!^R$k?w$\YGey4iI8bn\A8W6nm!4QKcSQ^4d
M\<\YH pPGV=iX4jYVbjJ^QwZ9lbW/4D=&Fly$D6FK!DS8di?%lH:T>V+4DwjQJ:=%uQ:n=<*:Z/u#^@aTTHweM
1$N1d9 GX==jH5CW=GCA:/<$%*+*<>F?C?9PRu@?>EK@^5%J>kjq/<I\//>jPY9l6w@YuX@HNd\6!W<@*HXTQmQ
IwKH#F $^w8wc?1YAu@eX4DJVV!<wuXj*wm+n1$<FW$<lw$AmF<Ba&/Dk&:mlc=Bu%X1yZ\H$e&ZEbj6i$@#t!+
d\MI!B lIcl4nB&weLZwSG\K?n4cA$G9Y4Q4/M%1MkXlnd$Pq1DI1@c>uY$B4%!#/?n6T94Q5LR/+kNJuJF>RR1
#w>hNq em&yZuGDR$Y9hh18wGHZES5TeeWqk%%HdAnpFY<8MPk@6ij@8K:84?#@1wL^6@:=j/qkZJc\JR!:dF$h
==d1nq HIH+u=?\XjyjqLCF&dwd<JGRBMhy1mT/FX\m45EcjZTQbQ5%HaeK\^Ca!Nqdc^CBK/M<klqBd:+BXCTm
Aai1cF WRKhptP6YGi5LBkW!t=IK&ehcEuV^Ed$ukFT\P+&YX9IeAL8mXM<FBEWWH%$B?Nbt5E&cCq=&Nt$F\uP
?<j!Y* +WCV\Jh+iThFQnFdDn>l=GYyhawHTwXWEQMy\#^1ZyW6D\D+J/^@kYG+pR/9RhaBl%QlXKEmw8lP6S9*
J!L\\\ kYAA$&6+=aw<VWP\%RKDkHZiPLk%Cd1IBIBTTJWuXV+\$GBaZ4EPINkR<9VD89lc1EbTE$ZG/e<1wuR/
eJShT: WF%KWRyEE:Y=eJP8y5yMjw>Ha$P5kc$>ic!yATM5>WVKCMSYlAJQk6MMycb%#^jwAVSk?Z/>PwGdNyQy
Kh+Dqc eytM</tb/AHh6AhjZZWRMneEt>WKZWJiCW#iS:L9HYGYm>#QVPljck^S41MEjepbLAYjq1h?L9hq94kd
GG:Fak 4N%iKbtQk&XdDhGKS$l9B$ui#ZPCbFPTYt*HRqp:Z!=6qEXSq^ADK=L9lt/WMSAkYjC!KZ@tC&DjRp9Q
!cI+NL A/eRw@pF\TJn@1^Nh:FTwY<yNJIcaD=\V:W5i/GbwqhTRlW#:tlI*bt6t\=wNRI5FMI<#GH!REBKejD$
XKtRmS ^FB^D>Y&1QlF1tmC4\EXh<P1kb<Q<11&p84+i??*u6<:9b//P4+\ykuWhnb=J#pG4Xibj#i1lelkHRPy
4lLbuZ ^K4C+!b!NP%htmmN&ceiHj@PXcNj@b//>6YA!V5peY95:!YP&@\M4TS&!uVu8Q%FwckwBp$m*4eEjHnh
!H4:bL bF*6TWD$:tpDEj#%CLnK$$d:byY\CuQHE*/>L/YGH<d:4bVJ:+J?=MB?ijKJeGD$te%t9hAQ*GhaT5=\
DQJAQX puQ\B%RGk>hV%4FbKT#+>twkTu#6RA@1=B9Pe4i18dlGIwa4ZL^eLCX=k@11nR<V*IAM?KEIB<cb=LEI
KThn\^ kcbt\cKlMy&yJDt?t%RXPGkH$ABMKNypnEGQ8e$$/aq4p9AmCmb!/=*Xe@MKFujiIwpKY8qj<KGJAX=1
nm!kWR =9L<$DKJ+TL=$9CQhHwENq+HCB5FTp*!d9>IVh\+Hiut/XeF*:%qD+#aZ9i!P>uR\YBJ>IaRA5=8bZ<b
@al?Gl =<?W?#S+BZN*yPXluB+etRnyk=FBT\C8LXw\A8=pJTXnPER\*X8KF&Wq*WkYA!pPCSy9T9j\%ZHd$t8D
CqL6QX HwN8F9+WT5+BA#5tp&NMdAtFZnEPi$&?$4WR<Sp#:icq>&qcuAkWB8IP=k?/C4Q&VGV$%NGYic6dYuW/
j=>cRw ^/^JcZKB#i^n?WJp/%>Rb\!tS65V:\uq%:%MSVnRaip6Ik@>nVS$u:PF=QEtN?Dia#ty@AtPZhiJB9kA
RXmY>m I?B6?JWNTt+H>ywicDP:Vu@DCbdYWeWmMM$DCq$9+8E!?nW=KbW\L+5b<J6*1!@Y?j5#QJkaXAe/eXVt
cHK/h6 iYR*m$$XFC/1b<1!$ud!/ZnwkYR/5h>l1adDd$MY:QFXL=VePly4cBt\n64XRtqSm/!ycZAi/%<F<nju
>PqduP R6:9Y6IClAAW6<QRYE:FNFe!F=b:e?p9HwB!C::BmT>EP?a@tm\Vw+XmDwdK<d/V9JNGF=cLYe%6?8YD
^u65JQ 9VcDnmh$ll*5/Xh=j/5hq1ny^ih@Na8jHK$ykPbjWY+w%QE^:G\iNDVGh&Bq6\RkY%@lm#t:#RlWAG:?
Fih#$q bA=JI*b##1H!%^AYb6R9Q+/itk:k8LGL4#*9y@=$5jy4+GFGI^V9Pj%KnX^tI/9&DekHW*WAI98p9Q+:
W6D\de PEqNVX:?lw?!a9R6W>Xw\en%5@5upljy8IFFGw8>iJmVS%yc11%D5=@tcD>LJJ$eA!lyVm5Nd\EEZYmh
pSaV8I ILb/DjWTJdkNH=!l>/y!W@jjjSJD/9CcLymj?e$ZyKIMTQNbnKi$PW5tmq/q6A+cQGBN=dVb:WMYmH+Y
tl8y6# Ja9QeEwK6\Mn5+u%NuCLZA!yPHXZ\<P\Zq=Fk>SblCES%1#VQkjFTQ??4JFk?=ke&WFDC4:MQG*?>MZt
QilJJ4 iHXp/wwa?cGpLuG?dR\aw^NB4cZ6+tHA$!\W5@JI?!BuuJPYweW&CZiG=auJBPjk6I?d\>V*Im%BLMQe
JKqJJQ T&Q$#iZ?Ka?*cmd\&tWl==^!?lj91uuDC=dF%F\4:DY&RNm&n:i6RRIH><8P6dqJ=^8JBX6L$cd5=SQ1
*bDDk< 4&Zu9VZ\d#=nXnEJHYLPa%>16H#E^DVV:HdHeP#E\Gm^D1*:hic*nhkV$&Hed!p+iX!Fn+DY81=HMIE*
&%jS>t jlq:FN\Qp>AInuj8T<:eK!Rlt^1VXeMDahcCFew:um*%MAETmdn8+MnQ=haS=h*c4#LAcuDd/y+Z+bYY
ukj1KV Yk\<V=dG*1E+&QJ$C>kdyD1dy1&%M$lNtYZ#$#Zw8!GN?6aq^ZaqV\65LE6!uLR?D!?>Gk1Za9u8@cSp
@F@:?e !>6d*:uL\J&PP+jV5juAtp^5nKbTp/=?W9d+InXywX5=S8=H1NhZ&N4!tH8MSlGh\bCq?be^ZZ>m^tNq
jWI$1t qc+j/l@j1BnK/m&8*QiDV#TG:@u+98K:!/HBP4t&td1&ZZNV15FGELuVid?FbbDtjwn^8+yPhZjGV:G4
ImEeR@ lNttbntKEE?ScWtjwX5P$!*hJA!L&%^j%LFN:%V*NYPHX+jaD=Zhau4d8pyph+SP=NapdmF?JHNNQmcF
X4=e/K Dlk6^M#Y@$diMGmpK&e+yCj%SI6q^!&\B9m$!iw*BaHY%<&9Bhh#jy@REq4+YHqP&6&$$Z55PL!5%iVA
AdAuWj <J9<^#4#<B=N%4NjYMX/G?Y1G4AZl?\Zhb9%pinuuPMn:1WnCcehtQqKI451dQq#m<tLwYTkHQTF$t*h
I+bRi< KFbCH5=<S<Fi=5QMtQ&YMw#<X4P<pwje$8TQ1EHA%84F1y8d>Mi$1NiLR@AwkaIK4BqwMAyR=XjS#V<S
Qtm:^q IXkQChIDLdqauYhSIp$\5?iFSKPD^#N1&ihXYAGL&d\l9:4h=YjY6<h+wVqhtRj>96FFImbKG+B>w:#^
N=9wJ/ ERGu?d%8wk:%eiPl:Z\4u$YL8XJZA\Eu:m<P8hZK&FJTEh?wEa@+?NL1enedD@JK+PaB*tqQ?#j<Aud4
Ajh4/t pG@SNGFL+I=8byKk/ShYEm<Kq+yDCLk:T4<XnJD%\$hWBaq/84lCAmZ\i\nb96/pCJC^eN6t*p+bCwPQ
ea8MBl utd5kqIKXdEYm^TFpCXMu?G+?l=SIu^=hy#jpbApuJCaZI=Ne61>P4yG1*h\httCTcQZJ?Mk6YpCP<8/
*wdQu: <G6>N6Jc>RYQ6B^#CpMw&JN9=5bE=Yh!\W+dSe!ZedI^t^dN*a5IEjpTk9h4L@F:nNmKVGp>yBkw=d?N
!/CTA< V4?6jlK@6u>YFKL+^VjQd98RmGa=LuLiViJ*>NmupI>ERip4Ji!j*>yEA/RZ9?m+qtX?FGABiIqDau8Y
9^P/6k \!Y$+y*bk6CuJCR1dmTNMZn\5npQ^i^qPah%#ePQY+5eZ6C%mu6EHc/WXCkPX:@NWa>j!\6?G898^PY\
pND$M< 8Cli?>%Z&AkKkjGA?IJB$P=96p\l:L>GqncHQbI@H&c@!q5u6?mTh+WJV44$H5w&KAVE4yAMe<<R:u*S
a4>%SK +Y/4K=L8L!$@\tiihq\WW8+aG*5NwHmBH/a#+H*:&jIGXW!/=A$d%kp*:4$ehmA@AbELY>n6Hl98hyW&
AZAq\a <a$i9uYVSS6y1QPa:N8CPu9HY\KH\B/6V@FnBVA@:MbuSy9AQm^cnke?D=*LmeCV*%d9kmWQhHN^PCh8
j<hj!e SZLSEQG1&w!HEw^*q+wITl8yySnaqC4L^BiRSIGi8ZQ#+w5Ia1P#\/wHFRV%RmHQ=Qbl?\GBlXyXDjNP
j8Y>Vp 9Z4Q%LCV#l4e+iMWiA8dbCEt/Ch!Xb>BlI^*R4uaX4XJT=%MhGnyK@DyD*9GBeH9+E^Gp>bEjR>IBu\<
+ST@$* %A1tp4L8C?Z<:84*k>#PX$hPc4NC6ulYKGXPS&6E^8P$q^qVPJSaQFl8TyJaJQ@8ZyW$mVWXGjMalM9y
*bLTlA IJ!%K?KCAuaQ@$CRq%mIq4P6q$Bm#1FQSeFR4wn!PYS*Pe#CqFAWd\&94GQJJ?I^Zn!*1&&AF<e#/Z+8
@NGayT 9Q&\D^Fc*1/6bMTEN!cYY?wNFq#4%%Wa9Qi/=m%C&ei*b<J@A@YHRa48*%@LYT!#!JXnBS%*?cbSRR1&
R>BJND >hLwQQQRhe!Y>LH>1t!TTY<>JKl8WY5E9k&VYFi64R?FqHV#!\q$w$NPm$aq=kpjk?\9!QQGuqt+JH^b
%ZVAhX $^@FRpyJb49F?6tjCG!kMX:pZ>TwQtmeGPTlTa/yQnRIKk4aDEiEGR+i*SEA@!ncZYqpH>?4E:JulSVb
QQY?Ml 8P:^i^b^G&pac&DV>XIFqA6@\kq#pAZ1QAwq=16En@D!i6k?IEK:EZ*GTQ#Jhp/JSS?5dAXKDb@KwHKW
\8mjh9 A!*iVT&N+wdh:TwW^*?w6!5dy1waF191*GVl\q#<>t*5/1chh<VRldA4X=/Y#mb=b@?&RjWT1EqSb!@i
!FAyeI %VWZNy1iebR/6#RCGw*@e%&WYFqHa>cR?B\Ye8kcZ8t>M\<+DTMKKqFTi#%bijQYEyyEab9Ecl5YF!Tj
q6MWj9 %\wkV*BS?Ppe:9AyXIMQDW:qm=Ec>#RkeZakc^6@i#^i5n&@\<hZ1Q=1LVGyPn8=ju#S>98>Gpn&&uKu
BjY#yK $kK=N>^NMViCNAAYMm=kNX<tQi=bq8!?R>BTIy?kISJaDttqbS@n*%%k696C%a#lMQ6MPD<t&DwI!uCB
nu+Ma8 y?/qL#YEE8w=WL&1jA6:1Cle^P1*SppcyI*jdejc=Y5Stl$c6w^c&dT$44VPM!uGTI4Ke@tjTn@TL^aL
eBW6GN nRwwIR^aTdVlXLAymLXb%:K%M?Lq6QDH&NpX8>u#m/8^m4S$EVkA\%BYEW?YZB#Yp^&69>@F=HH*adu6
#iAIVZ Tyq6GB!<l*4Kchn&bwujDm\YHRJ\Twq1Bklq$:WE=k*:Ji6LYYjK+HY%bKcdQp>1Gl@KmABKhl#n>u<M
/aH%@+ j5eXP96hd8CWGIX#wwdb6niy>9nA8Y1PJw181Q\?#S#n^9*:iBWHG*SHwL^MepFJ6bQS#%a:kb/Pk$%H
$XRdHR eC/qY%8=cp#nlkl@S!+Gb$6I#m%cYXqHwA9a<BHnWDyFWth:NnIRLmMK*In?Jlp?eK#WG&8/i%6+jdWl
YQTLV^ 4EdIjX&&>KJ^PQ4Lh5nB5F<W>%deH5Htb8QQ4#H1eSjBA*aSDk@nPVVD\=?FV#!b/J5L45!Tq:5XPqS8
-Ac%A* 0009742ae6e00110333 Page 166 of binaries1.zip
SPAkBt 6nipM9jTq4#RNW#d6c@um%4Rht1::!H<8+BN5T*4i<t8:^V+KnVhL4=Ld\^eBa6$kw+&9?mPB!FtQCBI
&XbMPE ujV!b>689<$i9>e6NDMMhT&^hcNk5$6*kcTdjBA6>A4Q<SX><4NR$ySa9CWqdC#PWGLI/D*yQhynZ?h/
m9d6D5 %uCcitLZIG>/=<\d#*QJX4KZN>mkZ5L1N?:X>!mPEd^1nq?lTZNM6hKN+ePyyS!DT96RtI&81uGVe>hB
JCweEB lLkuC#cGWK4p6?k*DZt$EP4RpMW9AjP1AFa9*w<pJZSc?tt5N>K5PtQ&j8yI@#ThVZJWkRLwVQ1=dDE\
+F*?DS j*q:KiqTEAT#?h8RZeIKq$a*eb#488Ec@<H=I@u5B4p\!:JcppB56L664G#<\qy1lq%b8XB&eyeDteVB
\6>l1F ayJA8Tta?@8au#C:ln#DnnTE8T>m?#QyhNK:hF#yT>iwCMMR@:iMP9>LyNb@yub\TjTX<QYn4+R9n:+T
?i^5Q^ 9tSC\q>V9@:P*wNjaW^iMmHlE91K9BnlT!ap@JFGZDHVY@mTCRtZ$Im4cPF4$HDSK@d<pkEJq>Cw1:aN
NBVH\d 8\=>^X^9+W5GJQ!Slq%q!MIS%/G91n#Aphillc?m4/M%KQT1+:/P%1=&+PGm%>4%K!+++nymR%=XNEFe
^4K4R4 S&^Z#hMRSpC9heG9EN5j$8Z?!9+9ZZDa*$ZXCCNSq:nkq/dL@Xp+@/?Q@:?ln=@^@*Ajj*4%nyXIpuR\
\k/F=9 \WeGb55liWd%+H<^^WNy?lyIbhEAYDi%Mde1%ahPkdkdLua<ePle<bcCt+ZLS%E9GaebETEjP%cS6*Rn
Z>BWhL MB*BQCN&?KRM?ntA*F8YTVhjyj>Pw#cywWR+FcY6PADjRP5n1HApVmA<9n%SjInFyWXwaG@y!=VeCX@P
>/p<Nw \e#Mk4qcY/mAYHtjNdmAdpIuWqN?eqLG$kNA98IuA1wjeIc<l</NuL%&4@l!pXi#e6ENnNKTVTtC5DZT
+uKIb\ Ay*E1dKLh*tqutAVcjD!q@^+J:Hl!pbQScKqJRR=lFc$Yb<V+LeB!+n#ebwF!&Xa?Sp46paF+!Y=\SIM
:%RZ!X GH>uEQ$/<hqeGItD>ELa//PeqZ!ll9bDBmH6*h<y%aWbBX<&yHL\$k@::AdM6<VD=Gld1!4/n5RSRh%P
&*kAcl FXI!BSQm4nJ!>G&VnIy#m\I\HSGXGu#VK4a^&YBVaQ&HTb4KBPP?$\%e&VlI?D95=I91&wC=uB/i$e/u
$M9wh= :LnS4^t+>w<a?46mW$:DbIPD:KYe?E?pNEjIEwi%t*DnLJBpchkMmB+X8Jp&MnZHZttW$8a>?imeY<Su
@Yh/yC L#?h$%#k45=hml:iFJ/T5hR:18Bbe8TS@:S8ct>:E^uciE<Z%>Z!!?#h+Yj65*G/dkeDW4GJ6CNpL\5N
GTYppL TH^!EmD9Jy+QuGKEHyM:yV1uI!!KcCQ5HRKt/>1SPAMjJeEn#n46?HJd1VPTX8aE#/*KEQ5*XCXqQEnM
IeRbWD J?MS?!I#LSaPV1Fa>6<eGtiApK:1+K^&>Gk^EYQQ/@V8y/9GnplmEj6jJC^bA?GCQDHb4AHt18P!cCK%
@T&=Da Ld!k=G*hIR6^!#n8WA+LS4N/a$ZFpaYedqie=Yp6%ildBkV:Y1/VQ@!S^M\L4>hQd1bRDWX#iFH$44m=
^a88/V Q/i&W!W58Ni>t4l585*M+VLNtL#<8tllSDqSMa8<Vce<4dQ5njeNphtuD>duS#WZNCqNlR1PG9DbbG>L
wiBqCt pLiiQQX8\EpiikIkc=!wP4HptTI8ml68HM?FLNXdDK+aY*VTX=++bYcAcE$\QP!Ck^+Q+:&MZVYb\T1d
5taXD6 BIXG*/5RW>K+8bTckD#\MCFuGSMh>5W6#q$jp4:MdSYm^+A^1HHclP!/@JLV5yRVDEn$*pDXZ\JEp%?5
mmk^MX +4RI!RXP<ThL>!bCtSlCR/y8^Py<pKuuH5/nb+nYeK\&*y>d=KT8*F$bctPH8KTP/qw\jEBDWV+B\y*c
a^^85% 1u/nNn:/K6pTPW&Y6Bd?I%kjXdBTkB^i+caDFl/LRld1C1Y>d^Gu6t*XjNC9@GHtq8nAK=5PZw5FuTa/
#hJiHy *\w*Ip^AaLXVi$uSnin<Kc4H<n#kbne\>mDH<S+B&T5%Xd+^!ZBJuV#RKIYV&nQVanc@$t/Xm1Cw<Q%1
+mFwb^ #HV!4bDG8H=BTME*V\Je/bVWlQppluLJ&kThILNm9SC$I<m/cDppQ#J6YJ>NQC&/Mqu8+J:?qC==y91K
N:M</+ PZu>+&!PJc%pmyBYZhjZjtNikbWeS\*BKZW?$4cYiD81NyHkMEc6wB:9jBIF=^nPD<<pD<CMV4YcXbH#
hwQ+kR Y6?cQBtX:<eHl/&\Iey#%=&k1pymiI#?GAP:e55ZJH%Cc6%6eSd6m!E<V?cAlnb?p\nedCZZZ^4G\</q
5MuY1i >QF=nW\%+=pyJ4hn+#&&MDk6bW<c!Jbe!nGHuSKFMkydSQBKIQ6ZQZHB#A1^>Fdw4/e$Htk5^+>V9S6L
Cn@<=A #%uQJSi+a*:ht#NK+@d4y/*A=i@Pc&HRM=VR*9jB/!u9SK9^1Xc#6!uYCHS?deZSNDhu>KkXGEytqP*/
l*IYdG I1\dJjd%M#N9R*MmSdl4%cFAKY8ttYNc&M8Y4YD/$9iytX!Y$RYaA#cGelpiYkuZWW1YkqEhM!d<5JJY
FnAH\D nt@p\>VVup>y@IPBQAawPheCkaLH&qHBMMH?D>p?BXc?iWWC9i?nR8P$&k4diL!WqS1VPV6dZp@ImG%X
@SZIJ% TiW+dH?T>=uZAyA8yY<Rq/6<u&kXt?9QjAak+/lD!CAb<uR6ycw/M/IVQ+J?i<:m58y5lPJ%9bh@F@eb
&HcTn# 9>d$:<+w%\#X11:XD%\5S8\#<a+bIY?cB6cM:i86uKW/&/PjewQh6HW6Yp^9KSwuPC5QV&X98HlP?e=t
>E?!Dw mpSGb5jp?@wSGA#RYppeKA*^eTlEFcW8=&$wX#!HFy6S9?NZB+@8/=Cyj??@WSIYceVGd/q8Yimyq@$d
RMX$J! <ta8AJjiyklYZTp5<*I$Y6h$dm$pKTt:>%=@QI!B&?ZF1F+8Kmd\QS@Y9CVn1:k1C!XH>hw#+I5K>!Dq
S@Ya=Y :!we6d&!ARtTh@9%XVGJI:iNJq9JF1X#nHWbc4uL:!4h$mK/b+VRi?6VQMYT8nbehp^!?%!@e&Bp*yL/
1=M>Wh ST&:eeG/?m*c=5K?F@QL++ymAi+CJ#Z\emwL8TPK8$w/ZdeCdanE:hIMAlkqRhl!+%yh%%>Ddi16K&JT
qFw5DX B^$FjuTFdnhl<*HILh4y4?dt8&QtacjRIw?Y=/I+Q=%>kW#+K%4$8nF*5=wAbD@=1yk?H>!niuEtnM>n
G4@JT* V&HZ@NM>ja!#FHt@\!6>*e5+aN!%/kiF4/8+nIdWBJIq?\FF=I++FwZTh6yKQA/KtHa8JZkS8a:</6R6
P@5c5T mTdb>lwKG5KRYyD6NAbcn@#1HZyp$#ZW:Wb8Z/uKQ1T4!F!WRBApwI8@!@R:Z?Z9wR4+FtkK!Y+e6eq>
AWc!=^ ?dM\D9kVIbPRLS5>@NcJ9E$Xh4&*a\X/pR:NyFb!T%&@Y<@?+lPbe&Rmn<ue=1aJwtDHeya&>hlFCIm+
M:4<VD d4X9Tkei:PPeWu\k$hA=q$FHWLcSi$S@6VH/TXlbT>BJF41kBP\uK!EnL4WJmKMq<imLh%&Fq:ZjnTS\
qiQDe# C:>J\hF58wp5pCM9IW594IlWbR8M/!/A&@&Ki?8$4>CX#h=q8QYKkutQAuKt!p6R::SRVckwB&G+Y&a\
6EXl64 QmSG\jdcSCt>d/*%&\Va\HH58T%*ii>Cqd6X8u1/mhw8Rt=byje6KHJXy$n5yBL/V6Nt^8p8#hi=b/4N
q$^Wl> &dX&@RR>wY!bS:\Z1X<F8$b!nE4pt*1//ZpGt8L*qY:+VFm+uGpGck4N<bbd+&*^uk#hbRR8t*1GmIYG
9CNkL\ ElNe\NAb^LYTTtVKZ+nci^*PZVa*::Hd%e6Pelj/tyAK<m^=NTk9!Y+^NSK#*qZmdI^Nwq^jV4H8T/qm
8^WJbi BXd=yC1TI<mQM>aYpC8XeaP:m?TN84K^/aP#n+84a*wT5*1/ukuNmV8QtXwMQdNa!lIiccE!!I:JBBc/
AV6&k6 kZl^8jqM=LdpA&y4PBY*8d4hi9H:uuV:>Rc=>A/dmeW\l?\*SpT#n66cGId:mu8=bAK5XK^#P6mQ/+ew
@1J%>? w$lwwn!Q=Vk*G&9Q1nlA#:$PA\9>?ZpC>Dc:N6@PChZeLm64D9&/^=AEj1V%JenJR#j&m#dA=:8dSG?R
I\e@YC laydc:46p!aCw<!TJknSeyDTq%JFjKJwDCH9WAK&Zl?@Wy?kALp$:^cNDubJVck@%S&K%N$KCBkAb*y#
IwmlZ= p&&MweKGMAu!T\jTI%EpWZWw<9H9QJHmASPVl=8LlNGb^S%&+WV+?AQ6qWytbJ9#qX<JRM\jYAnwQLH#
^5$N4G j=:IK:65Ab5&6=C$!*PS^X:+&!PZq+i<?*JpG/4ZJhP#ZMj/HMjmPmb@*%FY*iFWe%P?Z/$8>EZLK?!y
SyPhB8 BG9nYw@MjS//1L^/Se45SZ8<qF*XBQ!i9n&I8FBq^u1d8HDkJ<hVw#\*:Z&/6*d#<jkN>#eZBT9*?@4&
mK%qnw F>unL/#:*DhIKdmInw9It<q/u5qq^widml&ahMhFm#qJE=L9Q?&yL@V&YK#Ga^=AKJW*9\9uu+@AKW9$
%inykj c==!!6mLNkWZ*:NyEehpmway<^<!n+SISPWXk$4iE4m8*XJWw$q6%1?6NwBMi9SZIyiP8*uPNdEb/l56
GQLbmh ?B#pKndu\EkmJS!QL#W9pIZ!\b=9NQtbWDEGS\=T/M%6$=6E>^+I*>J\=8=Aj!Nj%H+A$FBKLiCd\Ee:
9ul@Wb @H:EHEJYaAyI$iE?VFhKJZh$1*H&?#1SwhZhTY5Vd<LVQq*1pMlcJLANJwqB*SG$Giw^W>t5EdLYFMHG
\PH*b* !%6<El6:SZLpl>n*W:1Jnbni\k?6j8EVp8bR\aB+wl8$Jh#W=X4X!DW/q6dWLaPynp>4m/9^VTm$=D=w
EE/m5m HR/X\?<uBCcT1:l:yKcwMQYam:DyC#ehi/m^+h+<Q!X5qT8@D$\4h&NVIJXQDHNHpG?ae+Tm:by/I6=T
NAZp4R ?5AE%!Z:FnRd^!M?eIC#VWbX8Ni*R$n*B+a#=jcG*paXmCaI*qYnaXjKhqc$ilZVLucIE^@Jn>Z#6&L4
q^Ni:C t&5M1CKhNK+5%S%PLlYiLW6*TZP<4$FGLHh<4IA+de:dI6We?^E1^+:E9?We+\^=lShbSVbVG#y/8kWy
1H4JdP PDq>!duV+#a:V^/cQy+CQck^X+c<5P<:8WQ56!:*uwh=qMNlacFS4#AG&*dC4F1qp^b@HDeI9#9+W+A+
VRE$FC HkQ5Pbh^?N1>EPmX#!E<TK:X:S%J\WW4kct</\$X9W%=V=NImPP4w!MPtukWt4p&NkR@iun/5WZyZP!\
qZ6RXj PL&!MZ8!np>Pq/?k\m/1MtecyAcLh##?tDT>wS*8<BQ6cCC<K%j&k:kJLIt+4dmcCNL=*ZlG+DG*JY%*
V!\Wqk @SR%4X=Z?cER:^i?^8eQ=$=P8BEQD*5$q=:yN><hN>dQtHyM/am/!Z+EPR?=Ihn>diw*=:E1XL%1>ieu
ujIcQ9 1mIl@j*/+J@A!IydjSP1N*K!l>/DRZ*4*Nt#p\ap+QE@h<uLHX1!itp$LF5W+<k+k4mL&Zu\bm*^#&X\
qG1XhB yDD!SQ/!RC8<uWlPVq#Jc18CVMe\cY6PyHY^lDyG%4Na?e<?9R?VSqeAi+ipub&VyZ^cnBYB9RZa9tBi
*&Xqm8 aD%W!k44ELa4*LQ=wPh:VARmKp^&uZ1NXXd:aj45b1GC^cwbWTteWAp4:&JI<qCa^@E6cbSm=k+Be5u+
GX?$k+ IbYubQ\TakLaVeJKTGD*E9%bN>wkNVRhFY88\b=qZdT8PlVMV9Hake4V^@?Gh:%m<+!Tu$wteQM>u/j!
q$^4Pw <@&%IAhBWJ&EtwnBjV1VFi$FE?1yTQudHMXAIJcT$<<@$>yZ!D<P<#+q!!<yTq+w1ln8mBHlqSju#eVc
-AS1mq 000d6e1702400110333 Page 167 of binaries1.zip
LX^XyD YElFF/MJkD4*!ZY<yKZbM%@E>HQ#laHaY@95Ma@n!FZX!hF?tjMciEDkip1<R8dc1nbhpe=pj%Pi%pSc
+#H1Ly jF/Qb/t?=\$98>pJS/:E4ZhJli*pL$^y&c4jI&@A9tLhbyT<HSQ+$?ij^#mmEG6J>C\<G+$w:q>L*=>e
DmB+GH $dtPRQ#*h1:@b?QclbGmj*TjpTLZhy@@amH>\b!/^BH<a@4$Fbuj\yip6F>CZ>YDjWqK?^@yK:9HL$qy
*i&y#* 9+T?It>e?JKW>n@T<K559W6T&m?l4=mJLH^JT49\>iQGlT?Jcd>5%/?\u!?JcSi?JHd:Kly=ubPP9IyG
E\9<A= @cMVm4mGE@4*wh*C1M9/kj<?9@&9VmkW?ci:/H><Q*D4@:^?+Bmuj=t>C@ud:F%+iY%!i=KR+=?:kL8+
/lP\pR >$YElnNZIjHBmqc9=bJWA@?q>jV9^8=GCJ!=qE//B>uR1bZ*>C#\ja:=T1EiLQteV8P#bD<%Sm4:VQ^6
MT>atP ==?:hpj^wR\N!dycaE=e=huiwWyZW^%h4Sqn@eadjP!qet!ttMt1B:b&4=X9#ttD*$I66I$dTMJCHZ8Q
XjPhqy D5<tGqkKb8HGI:16h\%w#1epNTbWkQT\qD&VH4*VW4T\StiRy1FI4P6ucu*NdtK:Pi9HMVh1p=T*V<Py
@GTZTE wB6<5=/Kt\MtWF<T<C#5>IdkqJR4j*::eq:pQn<>cL*BK8GuS+6R/F$ctwbaw8QGl1#HK@elli4cn<p/
M\qJiy 4a:yb:4HHn=8HFW?T4Pdyac&DBwe*Y/^V>t$#1qSW:YkN*<k=%:t8D8MiN^A4>ip:^\5N#D!dk>l$4u>
RAVwSW EGpBFlL#^c*S:VaaF6n+Nn:1@Ju8<H9?F+F:J^I4:&aGK^*FPdRjp+M\<@D?<@pVe6*#MDNchQJ?/W&d
RZD<8u BJe%mmlTNeB>AQ=L=VH!&XeuW&88Iy4Q4ejXw>+a6?#I$#W<5%FpHPTL^^p#T$:5F1?68@nFyDN>^@W?
eMWhAP LMqPX/LG?a9u$Qd5:jj91ldVDKtYln%eC$HIB?Jh<V>Yd1++M*F=h5:@?HH9+<uMtLQ#h+d$>hQcF\Ga
bjtjk< /Zm9CK<?lt+%*de*9Pq$MQ*^qN!@DYjTm$jp9I/XaeJXh$*G^@Myybh!e!dd1/H6&>%Muu\QBC$tIMIH
n!c6A@ Ztj=P*6Kh1:!L>q5DtjZR+hieDN=wBqbqBih*>bV9hCGET%tld5IYFdSDwn<TJuThRaXXRI*!c5?*Zn1
4Iikbh &tjRlPtaZDC\eH!5TWWymK@i!ILHbVR8^kulVQ?S9<5E:V$wR$SYj*8c#iNNJ9CaIIP%cMVqZ6ncmW8w
C/AbFX CB/Jtc^wyA6PT<MtB?At/b19RCc+4XX!Xc1SX&M<<^X6L=4M^Icb9GKJJtPke5w!+D^$j=+YZ%cdLqnT
aG&1RB V?A6K$PXDPWll@S:Na/VZlX+G4P1cmKECutH6qE4eXVXXy=$E#aWHk?cWM%J:6*/KE8J@5C/mw\bW8*L
j#qXla RQIIFecKBWAZ$\bcVjH!<cMVS46EbBKu1D5L1mQ*#>pHHw1EDh=k<>:G$MymwHbTL<yTMGC^aX*e?&p\
!XM/Bh jyMS1KI+ym5%uj/J<\&J<E#=PwpQYYnaEhT?58phjj+nG@pnE+cMjt%?:nb&w^kV5FR*Ka?8MR?Cbea/
KS!M5V q*9EiFMLG1P+$F5:pE8Y+aWma<qBRd>6%*=P/dDk#ut6AD$>^M6!DJ/\qJTJVl%c4tKukNJLh+y?^A^V
mM<bPk e@tWLuwy?#PQG^V\FCZ4P6BF*Ca^qaM:/RTD^eNVLa%jlD*\K4>hEn$?>MG^!F#iE9\T:^9PVu8V8SwC
#hcM9e K?H$S5/!!VqA*yNq4mhDIp$T@n#6kFy8!Xune^PV8jyHBRPWkGGbmEi6hqJZb5FQ//i!:HKIB!&cba5A
WD&uD9 ub>GTZKnGV%euLPM%m?<IAeLl1GmmLeMZdwn/DGlZ6bZ*h^&4YtjG?8Y9KKN1PHt#4ibCatSmX5MQKp*
!9?T>8 eF@K$Se+PSj<^BSn*\nau6NdHjGC6E<G!%hV*<mR>9E$PD/GJ4whMw9qB5V&Dlb!R1KTtEZ!N*Q!b>pk
%+S6$N Z>S8%iTTYJLQFHNcMywR!D8pDR^D=1&YuChh/<T@V^4muHD8\uR@V*mbBZ#b6*8WGcL\Hai/K>CVlITA
eW/S?4 #/AVWt\lTcdl?FuM%tCjSaeER>dqLt:^$V@hwymJE?>eL6&m1+pQS+X#=qi9E>P#qBq\+dSVnBcJa8qk
^a!KIY PL>HauR&u:KZZ>IblAVQMeAjXNSWX*ywNqQ^QmCPWXSGj<QSVQm^:L1ZwZ*ZIyqk1q=/dhKVbt?6e6\Z
!NHa>y kaLNd5jD14@MVd^u=MDp?P\6mWuB4l=6iqV=>L*Q<lkjdRj=%:9mT=@%RMaiPe4J*K&9QIK@$>QkBi6T
=:%e5j dZQ1Hht5YRuH1ekMGqH&y*p+\F6=K&&Md#nNLqp1qYadTpiM$klXJllHnwLyVQNi::4MBM><bNm=%&Bn
akyP8d XHRl^^jTMJ6&jlT:qtQ8TQL!9ZL58&HycwFKTCN4?J\><4Xm>ieMb+!PSW<?eDVca81?nLWKe1HJ&u4?
dCdQ&B ^KNh6=ZilJWu5K1=huSc8d/b@TDp^KqLVCTAMhTuhKXBD/ZKJt:PGja1<pbVk$#GNDuMJTAC?61q?YHB
cnQ?\q T1tJYhL+l&#pde8:#B@i!@G@W9qk6eFu?jJ?6?ccBp44BGqPZd?l*jAe5#p<QPQV@SSc/AWY#KJcM/wG
#6&4#R GXA!bw$qnccb<=CJ^#NlP8a1SMbAe?Q<k+/XQ&95GVi*klbQGZKW&#@BFkZ<NN=IqjAi1^Ep9=mwP^$a
ELKkCB iBVMYZmaJ@mm@/:JB?ud5RVp8i#hpuKEiA#>Q98<H<\&PncaF481mh/@HH4=19J4dPnEq=1QVyK@C$R$
wkZc^y tMih?yti?:<4Qp##4n$St@lWT::<@BVJu8\n!&keZqNeQSF9Q14==Q9FW5XC:I1lYyTdllGbEFZat*\?
KI@MEu 5p&d/cQbJ&dVyYjP^*^I><wDjyMl8#*by&kuBhW/BS6qb%k+*u^n%Zd+mklJPVi=^SC=DC>$mMBaRBXY
EK*IwM wa!Su6ZkR?/QEAFAP8YXBpPXb1wlpZ$iI8#+PY^LD4\+JlK>$F^RwDl&iaD%NW>e:MeKptDm*I*BDne%
DE=EwE EAT4/EuyMPeBGW4a%8!q+>+QGud^ER9yAk\tET\*ew<d=QLY!!^9!%Z%qc%%=NnuKM9/81?Y&yZti5XB
8dq166 hC1J@Ipq@Tu5AtXI&y$l5^:XGhXMET5mXyRhcdbl6tk/cCk@WPEV5PJ+M?IME9YenIIymk%1JJ>iWQ&R
A^n?6\ \JuTlnnZbet8bi*5Ry&tEQB49J@TKR>6Cm#Z:V<tFMw^+jwK$mm/5T8D^?:t1c!i=1bJMh:uXewMn>IV
4FVl1# eK!GFJ?GTMhch?Zc+Qub8NCI^MX1aKm&&JYX<MHpu1y!#E+?RSaH6aI1X$+5FQ:*R+L?i#8kWQ@J+Z@C
+&\lp5 1E5/wFDZ:+BCZh+BhepMw:>PPd#P:/FLlln>d?F@cM>A@ejD@@:YpjE9Q$yEL=ppJI!/hQkj<9>%b@#Z
WnjPVT h&hIn@&:CaCyF86e4n9P>KBR=?yDbL!NDj\%8aZD8=jCKiu$<lwE<cmt86SpMGq\clZ4aHC:QWM+j1pY
PtZNI+ ZZ6!JHyylE^t>S^Zw=+!KPnTt^#%*#AAWBn%u*YWSC>^qET9:!mJ@uWm1inq%lL1Et5Jhh$BkMIwpY9R
+!6dH% X\$AFEcJZtjdX+SlC%<TIZ+JjhXChSHl/>CR1&nwNYkE=I4%&yhEmQ?Slq>qmq$TIZ+JLZ\XndkGDSP=
j>J^&^ +wyhEmF?Ca&<m4/P%tBZGZIm%>HcqW&XI6jS&qYnC+XF4/P%1#?>SIZ@PS^/LcXj5d=j>Fy18!1+SQR/
6X6JE* c461AKC\KPKjwyF@?ND@n<eH@5%<@NeQ@e6/MpXS@>H4ZnI?<G@jH@:<8qAw+4LZ9eVllMGF@?<iH+n/
n#:ymi 9*y<aNL@<jGBmh5wMStQ5ZXk6iRtZKJGqZ9yXalIH9MLGeYFZ&<&\#!t/ukV4RcnR>k4=#C<J4+LJC8K
FCZ<cB ^&CM?y\YE\A@bj%*TS!65FSwcanKVhtyq=S$tMNJEEMEd4$dI+JQ^yACQ5A:GauC!^6jB*dKJwi@IS5*
j5WEWI &pF%Pqk^6MJj^4CK5mnckWX>y8a&MLm!^eiaE<Wc8PnWQaVP!:TeijC4lJ\$hd%!bnTTLIEMwSt@h#F*
V%dmB* #PJ8eYTyamt#hF^PjwIBG?kyww<NC$N>V=YELQyNSL6lD^WVBG%?PIi#^B!+lhQ<XLP@m^Db@DV>WMDk
N=P^$V Rl!F%uVqVE@Ll4>Qw%8$Ahda>6BMmyC=e/mltlRC*>A<tkuHTD%>:/Jn4ddl8Bn5W!cTV/H1^TBM6WeH
9JMt1& %9&1e1A\A%Xn$&%$c>1q6$TyVpWBn%RcpA4HadGjSpX6PXl%+W$K14ZHi@I4SnhJ1:R\<JneC#9eWRZ>
8TlJH\ FWSKp6ELC1c#%jBp6mVdVS49Qe*F?Vl*yP&W6u>ec&1t5=FmGq$?Xt!/%6a:$qJNBEq&%<%T*h4BqJX>
EXE#AG /bHA?4J#&6u:=y&*h6$mA8BJ<El?Fp^9!kq8+uh*+69Q!S*VtX8*n#E*:!9wtmLw%5Z8B1jPIXEuGw:a
TM@^<> >?RAy/:JQ*%#VF<kH!d%8e@\6NQu=JuM?<B\848p<Bdh+=^%wF6V+/tj9tpH#ilDq+qAj/yuV#*XemGc
==h\*Z LJ@$H1PM#>!49H:eT^jCdM!?i@y$c9pN@6Ph66<lH<?iia/IpQPD^S:TbXNdl+5Rh1\Twlb?WHT@EMYN
wwN$\M lZRRGnTaYS%=BZH#+tE6ZJI@N/NIH!Q9l@9=JtiZkjccEt/uSyQk=jFw<dB+m#?Ab?59J*p/FyXX!R?V
JyZK+V /M5KckpmBlyFVM4%8l\nQM+bt%6n5dyVeLFByijIbb4T:l596bP$cDqL*6$\#IL+%#q5*JYbLQ&RZBdq
W??hK8 phWCP*6LeS54=VG<=>p*q@Nb1kISXTQ1$AIMbXAd>6P8&4%A#j=c51+I9V98Sq:9W$Tqj?l+N/HKRwGY
deJ9^6 ?aTXmS9AY<!NdZ*Et5@/l4^PdpuYu\*ZbpGi^cpwm6@ZqZ4P&F!<JG8&u@9wX5GARI\d*u$<nF&F?pGQ
tK<Dt# Wj$mT&/YJT8&#eY#VpAy%L8KaRdjqa\4Lq5CQ:JP@^GEp#pQpVNwMhIya^p?e4E5Q+lL>V+:KRJc>1Ku
WDpDRK P:IXc*Qd&?bFelhQK+t/%Iq&:Bk6X9V\W>:Lii$I&$XCyiNTe=Nq8M8Bl?SG1Sj?w#Gka%$^@>V/?Yc:
bCFS1i 5chTj8#R6%>6Gl&Y5SMn4Qjt!X9GeFhMWydFSJSF9J@!jLc1aR<9:5lRK5XdC!:?=jFM=#&T=St#k$>d
>LV9FB Xwh%=YPy:LL5qEa^AdSDDWZ\dqqnP^JD8/hk=e46:NV=wVn:yXDth<1plyH*L%a<AlmTq$BHny164T1k
t5EVNH Ip%iANuJa*+PN1udVd:y<QC9XS!5&QjM*CV&+1i1Y9W:jE1:!p:!*i^6:k#+w!VA<9ma?9pJXZ=8H4Fb
n5DPwF kSc>8i*HN58!cmt?lZ$M1i+jJ<5inq8JaY1H*8XFd/tqK&qY/AFMYKPD#C*D6nuyR4B&9R@mt#/n*>JJ
eGu!4R FP>A*/TZ#GRMjb6k!Bji>WZ!BQDTtYT4=^iKjTXiMytKEnbTPSWdC+jZdTJNFd?u9yJ9ue\+#I&PEk:u
TP!nRw &ZJJwR1*$^q^9I54^!^TauWlFc$ba5>J>=VKy%/!eJD5nbVJVV!elj^wC!&m6V\PeMi$6Cd*R&kaM&eI
$HZ>6% VnP6w1RN&>a^4htTA>pkD!<d5H!\bQq=NBGhCB68dTRA!k^YDjGX/tPi=T4pNmCmn?REtmb#c?6F^Zt&
%89uBY E9j6IRtP*wAEE4tJZpDA?IWLV@HWyHWhMjQqjJXQ8X<=GqcM/nRl:@B/#ap$DBZb+ciJQBDe?9lTckwt
-ATLEl 0004ada786700110333 Page 168 of binaries1.zip
$HuKyG =VNqGbjnW@*qb*:b#b+Y98AX:R#a*Z5:FQp$jY+SR$Yb?ESW&WK*byS+\qd=m8hK<&IZ>YeR4n#$QZdc
cl/8B$ Xy>1n\PZCeX*M4%*\EkF@#dWm!@FBVqNkaajc#5HX%&p\ql5Dp@!Xci1*LXXZF%=beWcGy+J&b/ZmRca
JWt>\m lmp+MniMNji>G#>@&G&a\G5kqtQP9@tyc1Q6J$?PbP%E6M?i9H9KipFa@FPEui:TXP&a6/6F$8a!nBT@
=bwj*k ly$kMa5=@=Qkh<Hp#NlEbV$GC@tGHj@lPu<&&94jW@ehZD#Vnnyc=k4wwN=Qc6b?>dVmS&T:5V1J=BI8
8cBlYq #*FHYw#eCmPTy?4KNAdS^eI%eaG*85<mdm\9PikP/N@wncCIT@*q5X8Zm?k:Y*%6*Zk$EV5p<LuuA&8?
M6uM#S G>w5:>^A%a558@Ih#8QeI?9wjISSeejmP*MSY!eGeml\e:<En\!#t*:upiyNBj@pem>J@hLCyEQD:NkJ
a=?VXF XY$HpZE<$k>BbMtlA\PYem#%6NNp@uX&GS!y$:i!H:JyV/9FbCAX>Nm%e6X?A>WynKAIP^wFGC45Tqlh
9WlY1X aIy%KkIE%6wc\hW6Rq^t:i*XeXJlwqLX!#p@<lZ:=:=l4XRYbaiTT9d>tX@6lQZiC^uVMii1m<K*4^M\
EKhQnc TG8JQYk>=j+%pB\9E/DG?j*pKZbK#1iK*+tCyqY65HLIYQP6Fp>8>\@=adB!8&ydjMGcX4Q8:i1CHFi?
<@hV4t /uChNK!@ViS>uCZu$bAm$Jk=6qk:cPTu\6le<XA6RMS6yhFh$1YX&PqJVKCui@q5iX?aw=PBSt=W$Xu&
>Z\NcS 8LSuI4^c1P5=<\mIih5*$5ja$iW?wPeqY6I1!5$q@Aj8RJll>:l^NFER6<q>wu4d9FFk:Y<A+qB<>?4:
6K+cY? ^JQcwW9NHD@\TC\B?!G@d/HH*j9<+uC$Nda@Jh+l#EN@AWwKM>9A8%JXbh6#uSP*LeJMiZ>Xk*=N&M?q
pj11>J Fn6aFp$iqltpAGtJ?>95<IuEhkc1&Tij1A/q=^&j^1H#XhW4AaHmpMQaNXch\pwJCl5nic9^pVt!K4EZ
Ce?1^p e6unMd&W118VuCKHm9$+lC:yJY+nc>1W$ScGqe$/#1CA\81YPPde6WB!n^/9&mHtapW?n<q*bD+KWZdA
GHN*m? !p^yTjR\yNYVP#9KumEbt*w9pZ&YtQCG/*^^XHQPnjJ=IQimYu4</BIbAVa<WYS&R+S:eI@PJVNY6h=m
+MCVwd kMBRLnbmtQ^\Va8e$MHb+!hkV:=p*E@L:9XDi+^:cdcBYmHb\Kac<<i<TE#i^H!65y@wT1Kme:dyIhPD
%4ZH?q 5Qe$9C==?D9pw?JQCN5B&Qe5AQd!pdNcw1Y+:lG^Ah=HNW61HMybTm@J%9Jik4+VK9&!XhDSXnc=^>jE
VTR&+< cy5EnM%XhpD!Tq5EaP8>hlhy^\1<ijaIAa<JyYqETW$wPN6ndMJy&e!=yT8FkdL\%V5<qNP=^S1*1MVZ
F+AZJq D^LI9?ya%ZAYBZ*<Zp8RS@KGk*8519\bBWc\JJ\VVnYp*>>#H:D\RTbhlBKmBn$N*Cn>wP^Zb15%PPnn
nlZ#BN MwR6&8tEDNp=iSPkX1ywBMjd!1H=JAl/J*PwZBuETXa^uBXdJjm:*KS#/ZcJ56F9=iJFG+T5S<1XJA>J
tMGN\L I#m@RP8+I@kl>jHiM6b$EQFj9ES?lJlp%#6CyLnC>j8ci/b5dQ5/=W=1pw=Rt<qwn1hC&&e6k&&mDjGt
Gl5%9V XQ5TJQamQD4F>nVcKcunlBk:i=<lYIiYp=$=l<nH<X*S\8/:bcX9?W\c=Ad8Cm&Ld6k<mDMBHXb/VWd\
B</Au+ cj4cRh9j+V5!4a#TJjeNp?AplG<*KGdPlVM@W*BwW#/9m4/Im6L#C=5n^^q!FTc>qbkyX4^ylD?H4jh^
QXLN&S eEke+mPGJG\&JM8&9EW&T1KJLaci5XYT1BcA15=d%dId\>t#E!=1=JGq9L@KuE^cBpAX>lE!P9FyXJbW
#SBPdp l#mPHEh5P&l#y?QYGJhMATF8bqNJ4^mWAw^&R?RFH@ASN8LiYwjwq%i*hn4keDhSnJFJpWm?t6inkhi?
QaNZVh ^Sk5F!%uIeuETqDRcPaYZ^X%TYJLabLcFLFcPD^L==iYpyIK\EYmeL@J\WW:1t$*>ECmCeFGQeFBWQ^+
jbl%BW A/$Y48#<ABp=A:yHtiM<1IKiwjMwjKwbunlnG/:bVTwNA\W:EPn6^Faty>weF9JcQ?P6euy%bSm11Pl@
WIBN\? c$5bFQKj6QPlWNRjDEAwFHqhA@C99%SN@*F*@tlJ@P58ZmjPFH4JyKp@$qhF1WI9tVV%S@11hndwJbPt
y$9quX L1FSX>GI/>C\1&nphik49DjwJbPt@plj6bAdClG=Du&Fe\iFmF/H95J:k\yD4pMLR//k4/M%8Cn<C9w/
$/iawA YwPn46Cc<HY$BwhhSX>Hc@A4QEiw<HY$BwNj6i*4cA$G8?IPFd/P%1/cwAeX9w:Y4y4HBlY?n6c86D8l
I!Aet9 $P8I:c4tS!n$PtJDIK/mwheTP8wK?nymk!G8iH8A\1>%$1>+i@n*8d*wj&Q@q^XT$d?4pEL@bRY>%n??
uT*eAk L9KTCmpEmj1jXCIF>RBptJmd8ZqI=A1Dycc%wGDGSlpBq6cyeywhAQC^\aIX6=kD^myW9pdShmbi9m5p
ILEImS ?I+e##Kqn=EMT+9?!*hjMI^iL$wC8i?SYHiFWwmn9hcmRTHJY?k$I6aFKdVmLVN!pm=%n%Dmu<BPRTaF
14L>H# P=wK&/=XNylK&?G4twy#dEhHVdREW/pKKdIQX+Z*%^C$$^9!Blc:n&dApAjpLePqB6A4kIyh!dpTT=qW
A/Q+BG Gw\uhjaMJq?taK=HSuF>BlQZ*WHVw::45ADZHQm+>QKACC$I%FJ%b\AiMCdekI??4L4V:9w!/LB>TY8>
LpT:Q& :XXFF*<cBA$qlEn^hIMaMJ$?+:%%qaGk\Z5D54!q\N$QakDaMla#l$pcYBX4Jn:&Ykm9G^lj$pl&n6/Q
bRm89p J6i^Yl>!hjFpc15ldiD5H/NdQSmtPDjGbXNmhlStm/ICjwCW+hm>Auy+qBFJK/h\D=hVN<J=WXW^EdK<
aXtH\V Xi*y1!mY&MwJyeL\TLCTW&Y&MF^*MS/y+Td=bRa#K6M*N&jy<yS^Vp1!d&Y\lmAd@n:KV>MMiBDu>YFi
u9:\T^ aLHEFAFtT:4*Zw5@i\yRF+jHmKEC9DVB/HqdMVRjt/nRVhTF>t#I66#/>1T6ipVqTj>\%i/BWXI<*=P+
*6REKY &hj+hHP#$#FWnet*&8/K:DFQRyY@R4M#?HdSZlWpIY!MyLNVQVdk\Ty6DE#Db/1J/ZNtddi$mF9n$^R6
Atk%^# 9b=\8!aBA&8yddI9kC\Ajtlu&eIKbLm1u$*\5d9I6=*kJ?<Fu:a8A8lqqV?<4NS:mAuH6@N9?1LQddQ+
e6je+! bhJ6DA\aNh+EE:qN8d@i<HJ>E^YPd%bEF:YAGBMZ?bbAMP$kTthDJ&JFueD$SiANda#udI?%^Y1XWVua
l$Cq<P wiXLXuQ4/hAQ81>1H+Ju6uDqQ4uF91Ri#MCX#6N>88$@LCGGi4Z!@IdB*JV8tn^T$bE8dkYYP?uQqPbQ
Jp4uFu E+:*i9nbT?9^:14iTST??4A$hAI6#YNkS#hY^<hEZ@K>e5%I<PmqBF*4*me<l<+lNSKH#<^5jdNSc9N*
P#$WEK 9WbAm/Y!59tnS\DbKQdXb#=tWbyD&4LKBIt9=8C?h*aJSTt=D!RiByqMj*<1EB:ImI@&$H&imH\T99lW
j!wQKL a1yaBV$5S4\NkN?d/u1R9jIY=cldFPHn66%yJTJmPdLEQ49:n6Zb^p&b<nqndjG6P@Rq!M<V:QnMd4:^
V4>*$j hBJiyeE^6+G4k*FQp^Zek1c!=iue8uNMa>a<\QL5!p=+\jQt?djF/^#Y/Nk14SQ1hqj/=LqJNEhpH<VX
tkt4ZQ M:Nqlm*hPnjpSjjR+TiQ@<!9!@L4!PQK<a+k9EHXmRDl$qZ$mJDkPXaEdWbNNCa86Ph$#mNIjttGyQ&k
i5FSwm MtBeR\1&GVLwlJDR<k1:>jX?RPAa?Sdb=L4qF?8%#1Zl1m>RYnmjmn<Fb*6t%1IXJ4hGB=y%H1cTQJdZ
PK/qA\ Snlpl?ywaEM*p#*1/dNcuY\:a?C@Tid^Ik\Dctk1&8A:y<!MLV*Fm=4aVHiid<&6GD?#bFEK+W$\P?L<
5\E:nm NiQ:dlVj!Yy&=MlPuDAYGY8p^j/8*9jni!!==jkTYp<c=EmXpq@<nPtX:Yh\^9dh%D#5=^cGi@iNwn+k
S5&R+j a<q&6d4>mS^JtGW%>#eKcWpeQyVNm>*p<b=T>qw4$ab\Xa<>9P@DD&J9Q%J&u!l6Qpt/TVa9<dTS:Mt5
EbtwA# e9am5!d&6!*&D&EP$1?aqbwRJC^up9=6!/MjeQm$6<AwJL<L#jc:9L4<l$>=QEBb#?!4!>Sm:1WchFSW
6IXDFV pkBQS5CNM$b8jAYj1>E*Z$&h9=Iki?Xay\RZ\hwimL5!DN!hV9IRn11MhdFt<tW8!FBRZqw9jGBq*lV!
w:Z<p6 StW\Tq?=a9y8j@C^PFeWb#hyVBa!D^yBXE4GRX^k14bwl1>Mkei\++pAT*Y@%:&I#E$b8c5cF<QXcDZE
<t:taR <HqYNA*9wG:J#8$4w8M=F&/4\A>$B>jRRlcE9tyIQ*ARX!+C1S6Xmy$XJ*M+tT#bP!humNtDXJ>58!VT
>S<pHq V:a$!1//hhl/yjqdFHC4y15<*RqZG1KS*4T<i/eTwY/94ldKLj%:b\<8AJeGn/HCN/tm!DP::&N+6V*W
DNA%+8 5T#&4cj*k=FGHT<t84KZbHPuRw1:Kc^L9hG@Vewi*!/ep>IIIPEtJKqI>6J/9QLm$Z&d$a^<N8+LE1>C
\<L=b/ @w%X?5^CX5MlVm5B$WRA6jXTX9&<I+#iH>mA=?jSpEqC5qScqGTLXqeS1=RccE!nVw:JI=F!bkG$l8Xm
?TtyP* t$*4/Qh%qFQW*8C>KTC&EB\61^%/T!A595Swkq&@EP+l5Dy=tpd/QIy8lu*i6$NNtm>JaNF=M1Jnc>X!
akuH8l 9qZ%=PY#?cFa5nubnM>y:t&%1:ejGEt/GdYqLRH\!n5qXh=d4nG?nyZPWLGWA*=>hdae/VC/*jPWR+E@
YVYiw6 8XY8VGPC$y%5?/hL!w4mq=$BHqqqF1tum>@\Tkb<#MIK#CGQhL\E!:AKp/J$4M#Jm:6+\1@jhTAL:&yY
!8^RhS udH!!jdHHScmN^qpj45S6Lq8Ye15YX?GZ>kw<DH<cb6GLbeCe$SpnC84/iq6n@QeBRKDjm8uIqChTp<E
@Fc166 >h5+Sn<@n#Q@D$p@EL=tE4#nY+M9b<>adn+A%AVHV/=5M@%Y/5YRTijQDVN9#&>AijVV%/$pG$^@1n=?
NKXVLq *CDDG1@//p!>N68=\*E4?+MCNc&Xkq?Sk+QS+6+nqjd=6aAhjFBeGi^Gw^#>Hi<qJ=q!weE5tNIu*bFy
#6ee/k Whl8SJ*P6J1w$VCcLDu:mV4D#W*<TyL/Z<G**1HjIpeXHc$WV>mW&Y$*:<HH$&GWH$aa^uRj<c/VDRhP
Zm4w\N Bp\@VdqH5y=?M?h#*jLAt%j9hR8$V4WijhQ9ulDwYNb@NA+*NP$ny^>C:9w@!SYBHZ+u5Cd:&QuTSD?C
T:alVQ $&tI+d*i4#cpwkLhcWnunkLb9Y?#iA4M/cDK#QDmjXh<J*tP+5@AZSE*=iiCNE*!\Bm*?9pceuSaN14e
N$=$Q$ Vq@Y1c^db\+w?/6Y#J456GNX%6p^?wikn4$%ll!@W6>DBt>\$w>+XumRN@t4IA\kj/T$&XTT@G&9D$B?
K<a=Y< &#4<>We?P+eKC:JSN&CQ4KkMtmniKcd*B>EaTV!yZZTRp&>e8kKFk+XHhyy5eWmelZt=TTmdi8Y1Xiac
P?@q6h CRAu$Sa!+yd*upR&WE9GDdAWGiTWSD:RLtI^1$qk6RE1^bYbbP&iH<b#$&W*aue==Rc>=4dnXFQ6t%Vh
T6@Qjq wT#\y6^>iWQ%^\*5?LkAeB#L1m1JJXw*8*!<WB^wcqpCcKW<Ip$kniQ$?ICMynCMYjLQE+at4V:ip%QY
-A^MGC 000cd98eac200110333 Page 169 of binaries1.zip
l9u9NX 5iGkK\AT55wDi?X%dTd4ZSZ%&Jh@ETP:ThEy=i&=SY%><TBCBRJ=+WdpQ1StTC9DG8*b:>JjeI+ASmNZ
l/w%86 C@FAXBuY9mA=9/jFnYXBR$w8hACI8Lj#p5EPDmG@t+%t@?&mH^RYS\VnP1&A<^LQ&W^mF?ice<X1!kh!
XZ/q!a =&6X=Yc48RwRdh^DQQNcdXaQe#\Qa=cwRPW^d?wc:9IwTK@:54%G:ReTp\K?kIcaK5/mbPDa8ZGFG*pM
k^B^5y PVA$+ydt4=b6bmBY%nK!jcpCdb#5kuLBtQBB1!iBDTZNnq!9Y=LcNSLP:k/y8\<dSYAw9Xh#j9BW$EVq
Ni1pm6 hQMbe/PbG?1jSHpXXE+Y<l^tA$CRiwL5&k4P9h%CZ9:M:ZkCw@DtqlkjG\iG4<+mu@n8W?#EyklBe#&i
eVQjaD <@YPDCaH<#9pPaFe95eMcJPFjhN\?/t5</m*Xq:DL5$t?yYnd+ekA>KYM8XIH>/k?N%h5Z4Cc*Yqtw#Z
h^><n: bGa4$e&4NHQKt<#NFad#ut\4>bScmD!$iwa6kkLHVcu&%Auu5Qa\Dy+mcD&Sia:9n!nWiZ\D:=+uIaNL
SDEbtC +/5><N9aD5E/yuHY8dGy%:185qLhi#hTB1pF&Km651m^HNRHMtBQbS%Q6E1T@5$/e^yl$GmX:PmEJ/$t
!NFPt> q/TcQMGNJ:mcIRJ%GB$PNd1>8@R!6?kLB4kuCqSq8GFdA#<%^5p/hyBC5W6qVInBnk61EXSN!BtBBk>Q
M+9p6Y dZcwp=!maH^p$G6bPVlbCh!/4Rp5D$4Y?4A^l^EMSLI^ehqAilZ&W!\eiqjT?=Vn#R>b9dtk4pK@CjZE
PB!9cZ b55aII?!Z%L>aQcI#P:^G1B/J?hYPunw=SSJJ1hV4qSVt#NAbL!iK=ha!K>Yt5M>ti%YZqP#HlL9NPVP
Q89kQQ 8VBW\bDwA/!$YC!Q6^Ba!1>cd*cn1kqN@DR$>1u1&PRLnypk+c*8?ADljRX!eMaZ8=SI/T<>\T^=H=h:
Bw$#qu 4Fd\*XdW:^LI&1^<cX<c9:%c%4NG5kHk/AFRRhd&5KEIM>=1B/Y%6^Tn:WRDYm4h5^8qbl6d<!uET:t!
GVA^iG <BYhBR8d:JVm%WI&n$J:p^LCZAS=MV!ly&*uuZ^$=p:+l4F%/!/d&*8%$:K^5ieQQQLnCqCCXtXyAh6^
^!PS5u VcbiIcKde/kHqW5!PW?L+$9I51$me>&n5+RKj<PQitSc%4dQeY+\^J/QGC6L?ABW^l+&+eGYQyp*%ia*
GEX9Yh NYa$6TW=6wpRybNdhF5*K\p+>y4yLK@&DqXnMe>IPB9/V4&G8HQZT6PhHq8SbI9a$+JCE\QGtql458XJ
I6ZA+p t%<P^L9\=kT4=PWN=i=*W/FIiL<hnnKC8%:P&q8ZM\YC$t!w\V>Z:l5BIjHl%W@Zkp1G/ddK^t6J88Cd
hVBcH5 PjIE%1b/AebDR1d4A9byA/@J1lHpVm?C6QL1ylX+b^9K6p%tm$6w&H$c?M^=w6mmulT@dVS$Lk$+ZT<l
QRC6Jj pcnHlGtEBWTEbeN=^wP5jiZe5WW8IV@j4tayi#1wPLl6i>4!^Pe%QPady:iK#4TMpETwCAI&&H<=dAbb
@J^:!q &%JR=H4&ChkmtbKB=PdX!ekhy#:E^!Gp6hP/p8D8VW<1XqMLV$lFwK?VSZ:i9GF/lHP=yC&QnJQVqu>c
:P6DN& bXSGV*=Lil9Q8KtHilE=p=j81MZDF>ddD=\*Iu>nl+Q+eHcII^E*c8FB&?Tlnu\ip&ID!Jjn!i<RuP>q
itk/>t 4V:wI5lkih?cj?W*4ht6QXBSjwcnuBPk8CDP9I%>IMyK1e+%*6b<E@dAK^p$S&t!bI#1V$WAh&WN:IdI
6?E=B/ \Rkbyai!V+M:$CRYJRwd$^9Y9D%N!eqSAtl?@h@pjaDVtWEE&cXLht*Pn+MG$n%$bwNKd?8H1HyYi95*
E?&6<\ GkTQe\NQc*Ct%FPu+C@Bd&NIjyN#&&Ap+kt!mT*^A^$%dkjFF=8*!MJV9:qn*uQAtm>*&cH@jwDQj>yq
eYK<WI F&GGwj=b\@*jV\P/%HCH@m$5>P<N>*>LC@$*\@%9!%9@a<Q>L!:KH@!bT$\^1Ml%LjNL^k9>pd:T44>p
q6yB*q 9NAj/V@*$F%PR/>Dw/:\^GC\/>D\K%\6GQ\cNELpCpeNl4kPjWYLMBTG9AaNl%?%dhR%cNmX=%#pP9TX
hAe#jy =@\/YwQB41Dl%>EcDHKFZR?@n6ckIqjwHH+h4WFSX?kejl&6@hqj9y!?n6c861*l%^Hdqda%HHt6A:@m
KEtaJD NwFjS&^I^BX8Q@\/apPIZuZTSc>%p%%^\SHZEl9<C4El4mP&1*4Cwj<?MSd>d?#@!nL@Y?999%ntKJFL
M9yJ=& LQP@#=L>t&YP?NP6@n<</cC%M@K@KPpkk8h8+KXJB?I:DENkElWQC#B=wehCc+?%+kK5F@eyCA/9HQBm
CNJeH/ E5S%Pt5P#+<?c=RjLtTcd9SpPB!ymVqYwG=kcVjl1^bRuL\uyEuZNZn@5+#<8&btLa<jHj<cYdBKR+jb
F/SB+C e4BL\HTYm>ADTT4b1:lHi=B%@EFcI*pCk1Rm4FWn@B1<5eQiIkPRTqpH+ZCYGFI/nNSLLVFNF5pJ&S+j
#m1e6+ C+e^?I%lp5+JKVpB1TEYPd\SnGZna/c?PKaKZVt&9EuWIHmHbmwe*?4+a#kiB#W61FHY?<b+y?Rl8La\
H9QJ%P :L!9^uuQ+lY\Lm?>SV=P\NG!RjmYTFj+1LjF$<lBudd=h1V#Y/b&QmK*ZKIEkk@pa^ZRHTcM1nPWAhIa
nBANiy p1<pMPF%5R\AhiXdlTNkLPB*q4K@?$*TQmY%HCy<DKZZ!bj5k\#TlT>QV5@EtpyYT$q?FNYp6lX@BjVM
!9+k>Z &%K1>4F\>Y8<WWn+cE$@l8ZS6GY/Z1?8L6L4hhY$u@cnV=+Q$q@EIlwnZ>9:>dH*&BnaKFn4#QmT=u>E
/y^4X1 n1/Qpa4?Cw>wN$n@nRek:KQB#$h59DRXAhtdI5cmq@%>X!%hjmd41Idj=SXKqc&R9<99iyhP!Hl#i<Vh
a>PWdT lh%lRQ?EttlM&NJbBGYW%WIlP>=5>c/9Ic*S6NB8iH&*c@*qH58d4^tSw&>u&%i$y<q*jGJ8%kbLQuBX
%?BK&5 +jX\%ty>G?SC*&bXQF5wM=:6h#ejXMk@E^&1?$KRK?4dA$@8u!jVhBK@TEaqFQlY%b8tLSP+cIXB/!ht
Y8pYZn H1nIqNwtma?9tE/5ZZVAXb:YMHn@?*itjE>I>$^6D*ejPFtCiN5WiA<PR5JK+&kaBA%/1*:Y/W!V$ARW
A@>5k5 k@LZZJyqG%8W*6>nAicp+lPpHy9?eGZ:ckAtkB+:!Xk+ckI>EK$$jptjp8Q5?@ID&bLQLbd15mS\QqJR
q%QRMp F\*MM&yQBXS%t59Ieb4j*LpH\K$WFkpX8W*QSt6XGnhXtmKTSl5LAFYeMVS5ML%tqRwV\kSNb+YKDMWa
8eQb<V ?<Jmy^pqB/4wGGPRA8:QZ4TpF^8yL56k\4@HlmS@B=uuQ*n!%9cCy9Y5QZa%It1E+V=h!eWGQi<L6!TP
aX$D@i J*Vlb/61ml+?Zl^Bhb5HdM!%PkANNi<88h\!68k8RI\\/<C5E^uyp4<u$WSEnh^=45=le>TNt&Heti^t
QC^WPL #:8QLMIQ\nKcq5%#J%5!p<<bK8V+!$JDhAJnJeGE6wh9ta=dQb!F@dLC!R9$a!i%P>Pw!%=p#5T<D!RY
lpdC/n DL<^#JQ=n9P:6=dH65d6>?I1HP%uYaiR@8Gw/NB*KTty$Llt#1=CanIitT!iJG%8Kp^H%pYcJ8j*G5/8
ib8I\b &cJ$/R6dk1KpAyEB8:YZH\9&=yn8>T5w/Zi=IPCYS<W><i>GXXn?Q@d?P/#J6W**^&pJLatWmDTX*p6I
c\ALJm R1km9bjRP>J:d\Km$u99VcV**pXF89RPImLTi&?mw88**uht9VQ9LNmdtjZh^==nj99ku<DBJ<?h=H#!
d+up<N *M>=Z@h=eTBtp8/p9tXZN#&TQC&BTpCqDY&GElVDZqpqIY*alnLP<%Z%<FXQ?I6byjAhaJTM/5#j$X9n
^kVc1V &RDMeMuAbMW89FpYuTp&Ge$ICZqRq&wiT&9$%N^4>e$Zh\A5MRpQ*q8LM=J5!!m>9XZu*WG6?<4nWeSt
n>WHCN ++C:P\FN&ThMlZlpaHD9@w5q#ehul\Bl$*MCI+ZBRG+B=>qNMcKK@A@QDp4***+98WlnL\Skm4\4#aRW
wb=S>I EJNdkR@iZk\X:<D5BjLn^uk9Y!aJNlkd5B+q1B=!AwJt:Wm@NaiVhQdQMy81>jQ4n/LAZT%Q4D/bGAe=
/^<F$j hJK1!KwVLB6\!R=Spyi5Z>ycbTmHp4HhFb6>iG6VddPBKIF8Ib!K=JG=RunhM^a&&aIT$#L#55mPckQ?
N\e6?G X*imXtXm+B$p4PVD^9TKV6H^4#GNT<b6=+9A!TTP&Z&9IPE4Q=9m6JaKH1bDP5*ZmCI9AtV+tH?XElhk
niJ*?E bcTTa1d!p?4W4Eap:5Z$cGjY+%cCmBLeMITu\mhS%GwuKjBSMQi*+\cLmi#W/P?Q$6MDlw5wn>M?$pc<
p*!DG* p=E8Le+ckTYK8*A!GQLt*JQ6V*TkW@4w9FAM?kC1n#hX8/$pmFt^@TIT@#Yd#bK@hw!Jl^8CTYu*#u&4
WLAJI= *a8Z^?i?FAT+S8GciAA8+YbBa:ZXGRYcQJ:8X>YtF\Q*GRR6a6iW?i/<YS%YKnRjpEHdtkZcD8PAyPIt
h6@qc4 Qm+q@aw5QWdYwAH!=w^IAnayCcu#I6J6?M#kCpkd$XQ=mG/hyiFP6IE@AbNmCT5%KN$6CJj>k%d?ZbXA
QwG@Hu V<EwL98lNyc:>#*6=lt1l\4%1/q\Im8a&t1?mk>#@mA@=VA^<cpJ1yFEmqna6::4mDZ6tqPIiu?cDblm
mb6w9& FKMWIX5&pdB&kpVwG<yN!6B!Vu:ZQCn:au1^lp=:i>d\>S:AwA1%XkeqeiWiX/ddMip:8E?*hqBKQtJ^
$qm@#C 5RSYQk*+1k#GKLKZJ$#a<KI/QFwqm1DK56W5D:&4q:1&+e*?NyLdQJ!S?MjmuFQKytH!YbKmJ<G:\n4@
Gqt9E5 1GN*YKm$9maFKa?Lwpj5JJN$/Y65\k<XRk1L<B!4H!X8Npw<h1LawGZ+a>?>udMTL%:j6$?P/!jCTY9L
+j&<GP 4HQ$9#%@auiMRF=WQek&Q&+@>lqtlZq/Q%MLmPbSpu5GE!A*8MCAY/$hu^Xt?Y1QPww%L6SQ9!i!LPFX
kHS$NA aNAa#ZyXVq=j%QXpj&cInD\RcjB/Kc>X99FP&$qYL\FYwiEn\5Pim?D%6yw?6:=i*Y#Y&XqdA^6$@q#m
d#%qLn ZIbl$y9^9B?PN5V1V^<yn:&6&9F>?VJE%SBwK&Hd/=K^5FItcVBXQjS#K/AKQHIPcXL8FV+btV466V*j
TQ==B$ mVGyGwE4:*eWGXm6pTZt4P=#/LGB!$bH656D+ebXYTHB99A8k8DKb#a!hI?nR/#DI%J/A%=!bIGanNTN
+D%SVB F@dGVHpeDY!W8Rc6>M#Syt8:ueB<j1M8k4hebAqey+uX\na\GCjh^St*:XubaW+RKte#:NpGWWnAMchF
<ue*tR qLV<RG^X>m%akZyJ!\9=>iQkjXWR*V8YW+<6DE=dQ&&cqL/iDCQbKDXGDp:#pwGT*dm^68S<8PqlnuH@
4\Tq@a L?=R9dk8SR>/9DutT/eR%QQi*baCX+&^YWeP?YiPB8E1GCj+VT%Y&KT&KX54Cll=py?bFyiXY\?hGaDS
Hd8w!k cehPm4>^>b*$b6YNcl\WRYWGke@bRh\^:m!D=HXehihkPpjepYEabjqiTZbFB6B/F%A&G:MH%IXltMiT
q$NjPN #V56\&IMDnG5j#unwDuSi\TtZN#&/tBb%Vl1<FGC^pHCl?1$Ap/@d*8tKY8JGDAEqa4$L^k&GV4m9H41
F\NV>M PGD>w4byt<jQjtjbS:tln!uJVJ:6SQIJYVWlaIWR!C&<K!%<KD1*Y<Q^w!nIj^B6n9aAw<Q&AG!JBTE<
#b%b1t Y^Ye?%QHE<L^w:<Bm^:k+mWhn#A6>:?/w:S$J$cXdlVuklpM1MYHh4a4B+uIS&mDte:wHEpJ%@&YPDa4
-A^+N\ 000ffeec92b00110333 Page 170 of binaries1.zip
9y/dM% ye1MGP$Vk%!4eN<MT69*FQW\>bVq4c1RhE8YBR9iapWmJ*KGCLPCn1AVEbR8AMYEEXwPPC@d<1WGJM&$
a8uYk! WNCn@IT4eI$VyDHcH!F5Ic#Fa?T+C*hq!m=a>/de5R&XT&W:\NBqI8Z8qYESNTE9EDFe5<d#T>tRdKw*
WG4?/Y dSYVeVR+CuleFjbqnIm^+Hl/=#W:I%M$#eIGmE\/+dVWh4Xu+DL9pMF!ea51WP*eXu#JdA@d<n5u%w\M
^c68<t +B9@pK^X<AEKnib&ZtPQhP$i>HyiahAC>l4t5Qddq**FR4//p:dGKB\Rp>i1LtyATFt:NmD6YMji?+pZ
>9w^nY MG<iJC$VLCkDTBRJJFk?LkZ+dRl5qGkebTWwQW9c=un1JHuJ*S5Zq<yYa<F&Tp!D4e/Da!$VVm?Aa/6i
5Z6nha ^YXYI*MH9@Sl6@W\tCRnJE1?*p@YTjLV\GKw%C$51d!=1j6MDST+hZXdNu9m$yelSZV#TnJm/NP=MacM
6tm\TD yQ8TFlYHJFXy%a5BE\T5^=DNAQiktJRwlnB:dKc\8k/y1nVu1Hp8+$t=jiEqN+cJ$u%V9Djb/AqXQ%6J
YkeBt8 C/c1yHc6dn<NBnQPA@j5=ZZLl4d&WE^=8m%EtAG8yS#QHyb8tGMEl#/^^y^indum48&8a=w1LqN:iKY1
#\hCuc ^yJaKB$\kqdbDC?8jX:Dy1+>1CTYc>8qbL+>?JEm!P654MKlukeV6EXpV<DLWGLmPqC#cmw%=kQ5WpjX
V^wG&S MbuR#aB^F=+=#iptdklk1^FkT<jV\#nh5wFhAw#IKdmFQT^uP%dKG>Ei=S*n5:D#AFuPICE>^%c$mM6c
HW$4PG bV5kn+l<La1e!D:?Dcktj^T<yt%B#m?d<1ud\BW=c6nRCV#LBVQ?NDR>h\t9i6S8@**/5YJlGmLI!&k^
YyeKNy %9npiG5+SwM*+aPm8SFCeJ9?d+&?cQIu?MSFQ8F$C=1XMVINCdK>ialqdy@Z\IjVJ^/R>\p:V!RAl:X4
<aZiEw q>H$ldqbp+A+pWCk1<AM11Cknh<5$y\8RAC:BTD^l1/Ht4:JW\T\TTPi^4D!&NI#&LIh?6CW=GFP%MPV
T$$EEp WdMCAkceNl4QGD+L!kjJ>8K<LWy%+bkaSX&\h&!dCdwweliyawhXbWS5yQGEJeS+@Viy\+<TlMBkD1tb
4>9aTT mZiMBW:5Bp6F#+uqE!a6RkItSjSZcncbll<+uFe4Bn^e4#ljIZSt9Km\%hL8B/HyQkCe*&ReY16!Y<Mj
tYSW!d <*@*MPCej9anPYb5+>i:VY9R>p@D&M:VM<JHPYkIc%XWdH5\#ccPGdIYpmjIB1ZSdH^R\Ke@@M64XXLE
hI>Fcw GQ$EeKDPa5k=5t818jAdINbSc!FY<%lY@BTZyFtM<iDJRLPS<8/dD^ZJ^^*w>4E6=w=uWJCpqa\<AeQA
?c!Yna >Fi9XQJARJ6TK5N4+4A?:n#PuWtmbCI+tp5n?SJhP+=ZqHaJ$Nk%+\hW:h^X*1HGh\^qj5QC$4w>Ahwl
dic\$& IeaaCyTP/VZL&aT5J>Pc=%u$J8&N$iQB?Zl\8YunjIC+jV@4nPhXFmQCqKXGS9H6>^EndByl/Jn6S#RM
%QDhpd ?i+i#^tQWai%YlB6iW6!H\AJIpT?tZY&?Lb=Mj:WE4VZ@4Y=CJ48@GXiV5TcqXHBL?/$$Yh^uQhL#PjP
5/qAw4 65%=Y6@\iVld6S6>tJIKwR$h%a1mP@>6@htdL1DW\K5wi<1?^c*w^/b&NdbwC&bB<5WV<S\nituL@mLQ
J?&Q>F VZCWhw/qBheiMX>Wtb4@*y5w4^@*Iwhn?5B+Qdm^WDw:baZaE:d*neyKyjKPGP6SRhIkT\tmPLdlmZy*
hEu?kH EKX<WSTu?&\K&&>/!SZM$:WQbB+n*^jdL\<6at56TlA5l1!n\SXL?C9?@A6Q8*<b^^/qpyhC+a$SMb9!
hwMwCl lcdjP*N?+ay14ck@VyLXYdMM^yn$+m*bCM$T/J&$PAwS@ykD\MnHG8$h6LBKLHS+LQ:#5hT8N1BEQi@+
IT9V8N WliTR&S4>Iwk5lw*y!a!=%nG&dInCYmpDVE/$^WFR9Lbek\<F?$jI=PD\Bi1mkH:<V?IZIyJYN^l?d<X
9VquDc BLtK$dMATF11qAd5GR1RSPL6ITR5Hmq=DqZQq#hKqASiFAG\JD>l8%cZlln=Bq^A$IWC?a1<LQ4Fk#Ge
p%e1%K ^m$AXpHd#lBP+:4>cKq:<Zpj%1%mM$K+9P\i5YX@/5\5$*laCw^wdKp6KlKi@&li4bHlTII$5qBTTwl%
hkP6/T !6pA4Cu!t1pZW<\ATE+:PH&R%VPt&AVcW$5PWh8:lihQPZ*meKTDBmFLJFWR!P<V+BFaD+ipeZF>te>?
8Q6&wn wYq!mW*tD/M$^cCw6XC5%*kX%e1T#p><CAHwR1$8IaQVWP&tnBQ+S%8JZa9McI#i^k$6S5X$@H*y1Fb8
Mycl8# 9=RAB>CGF65%Qhnk9Mn@Nk5w@^#C?&<LKG/@@/bka?:&:>&&*@@:Z+NG+H>Q%9n>ARL&4*>B@QE@CCVm
l!&PmJ n\eC@@1A:%@4V*pRA9@!KumRePRj/!jeEp+ij><Z<Y>LN9A@Aud@icTw@?JTD#@5#$5>jAI*Z84=X@j9
dh6&#? V::mFY:5u\N*?c>^k1?I/:&CSq*umA4elL/8=9!K8N+@$:#<%^#:m4niK?n4K6c9mP8>k4=8&iGK8N+@
c65RQu $<n4*4W4$u19wPHZ$d\*wYHZ9iiwG>DZbc4AWVjSGkJ=#XIQ/mbc8/:NHS^%E/%h8&dBh^P6\c>:*Z\*
w:q<\1 $S4<tk\hPN>N6Hd>Wk@jVeVGi>$GJ4/dmI**8pWL9y8I:h46V*\*El9jNX>NjDeS&>@Y<K/t?j@ne55N
a\V@Qm k1Z@5Tuld<56CNkX\hL\j^<n>a@qq4<F#9&@HR4@l*ewhL@cDk\d^/YXmCK449ql?mIak6cn/Pc!$/IM
B$Q&FG lpTcEWZVb&yS<6*C$Ch/Zb9yQC/D@TVkwB6V6IXCn4nBp1ydYXl<E4Zj+H9W6I<>ePK9I5>^uqQ6C+$D
!IYYHS hyTh>:DkK^!RMMiRVKTZ%mDtI+Hd#6b^\P1BEZ?PRWq&ZqbCQh9Mtu1ed81l&LyRJLjVZMJ6X4iA61\l
Ka<*:I D5q?Mpc=kWmSl&Hm<$F9FVK&#/9^J8REPtYZJj&dy9D5KaH>&<@a^IuKe5wqcNSFYIM=cbcwkmFaSqCR
/5&cYF A&uInmR>wyH<Fky186ILXuieR>HtQ:+ZI9dGtjc%G6lLAIL66Zc9^cHQnF^:y5LFAJtR*Q8^5WNSuE<Q
J!NAkF M$Eem8@Id&L$WW8^/4hKIqJK1lCVMMhW>1WcK?&\KD5iQWSnDb1<Re&Tl1#j*<&h1y8PQtdy\+V^X5#4
W>kH/4 jVeb<pchXcNQDiQ$eqSeXi6$H?h#*^n##e=EH>kCK>@YpK%:L1w6>YqF948*<wHLFcyNS8Zl!j>XYj=n
lH$5F9 +?MZ&=>Z!bRPIl<b1/&ujBuX9!6aNp=QVa:LLqwc%At4MjGj1dlItG/pKH61d5*JyQbT=9auW!naZ>Hp
Fd>tBL *5jYKBMZc*B=!KVSN$9F&SEBn*!mV<TRHV4J/M?6i@\8p@H6M664S:%Gb?$YV#/4+w%M!$Cc5ctNcP6D
<l#EQ/ jRd!?*V9>JKwQ&?dV!F5tt@mWH\i*%#dM/kFwM+?uZ1e19^#?R&uXq&y9TLcVe<B%GIt5FiHnKQwWbbR
TyV&1+ mpZ8#T/kwnn:#DiFqKRC5+W!h=1@<yKyQCH1@jIkbc<y%hhwAlK>cb15@CSP66^4n?/&=>CIwKSp5ee1
J$Tp:M q+dPBKV?\4C*aI@^#mTAtL=CaLQDJ$>cEjVl>dGl9i:+&##j/GFSDa8D:+S*G=LtF#l\?akpy^mah?$J
%GaQwe Tk6A#n^hAWqyCVuanhJ:Q!@+891<\$R%AI15L8qNqFbh88?>FC?lHCu/lB$FqBdFGE5XK/y*KCtK4Y9S
!K>WYD S/<u$VdyB5S<L6+qXGRR^@8un&!beqnEaLF*#X^lXyd^Z$WC+<uy#h++Abh!?9m&6=WFS+WWF1m^?iKy
&8ASGY Dd+j<^Kc?A84h?B4jkw&PndMDEn$jD@mZWDkWqwCu#S&bYT\N&Kh>lHnd&@LE!WIq:YG>adn8iY!4!ZF
C>\KPh XqKLh1jjN+W#wI=$!@Qh$#=>8YB^FB%tWyTJ?N!S*kX!\#LM<DmAG8=eA6kZbPXqc=yT*/VL4H/#GGJP
i<qi!m F/A*1>jn<JEXZbG6VVB&TmQFyPX&QtA#jqPi1S+uqMFC%KBG?DQk!Q<8/RcD#celDWlCHF>96@&MSccN
D:SW68 wI8kHm:GIwWEaadS+nb>aeD/P<YQ>m\=M>aJM>$hcSIE>pt1wR!8bY@#?qnM=HKN/6/49VE*n*TbiLw$
uPSS?? M8ClImallDwtW!1QR%h>6BYZkhk\mZa=5XCdNG8Dt9AcBpybF!hS!SYqS8@wjIiZ9M$AtL!Y*IFRS&\<
SqJVkc VpGPB5F:&LJWK?\jpA%db#&6<\TW*dX&6u=NqP$GI&ym#?%QT$Nwe^Lt@R8G4VpcJupVVe9FilmMuTVd
JTmq\P *5y4YGaQmedIZ/La6\y/Q*@VNIAbLLSK9NW^aQ*pyBYVwcqQbk6Y?@yCTyPwml:6bLkdD!!jZ?=lWG#W
&5C6PT uS\E?^iNmkYWY=5:5:\5mYeC^5%?5Z?1JF6STC*W%SRZ<+uP4i><45P>+GeKj5H4/EPW=kdqIFlK$/Pb
MByX#G M8&#uSQ1R\>S8L8e6%1ZCNF?S:M\CJn@wuRFwMb+KhVa:!KKdh1wJ@=S%!%8V59np?B>pMMVD$jYj4$*
jY1=PN Q&5w?aMZl&*GJ*<y/&*h1%:%/6MSbABSIXWAh&!I5wAQ@Ia@&%w56Vb%dcT=a6N+kG\9!DMp&tj5Qlq1
N^mb6H Fn/wt&W8t/9wbVMhHadPu?eqal9&*ELqRHHNa6%VDd8EPlKPQqtJPK?\He6kSn!ZMlC&WNkKyn>Z*Wy@
#iAd@q E&QJI$@=PB!&WCYhF/d5@u#E!w%C/pN1>mltu#W4:Knk?*c!NR599#Qeih\HHut1J\1+HjSy#hatu\+l
%*k=c? Z=+iSDF/tk/=4S@DQD!:b+N/FE8n?41\9V>%T\q?Ry:ZL1Tk9CqHw=wpMiL@qPJm66y=%Em6c<!+k94%
HubQML ?6j1y@/TdDP\P6pcG#&uBWPn!bK\SZ/K^Ea>19Za5Sq1?jd1kN#e&jHNXNmELI>Bd5NLj/FkM&S?e^Nh
GBP%ke J?#Jh^X:/#6dSC5lGL/9X^!wBy<&<WHCm+WM%?d4!uuZQMiqDmuY89wHQI<8c&eq#\jYN>NNhN!@#4mR
9+lu1/ 4>1ldje5cB8T?6+iK56>w6+G@$1a%Q9XZ>IX\Bc+pYRR<pY/@\mucKm!y%dhS8Gn@h*:>#qTDS!N+L9E
LJI!y< \19Kqlc9Mb>yh^LLjeLG5ji?R$4l1%4H/5^dlNjq%LHT+wZ<nXDZd5GmwMe*lqER>qn/wMdT#NSl?uPn
R>yT!N IFh/B@*bAc&ehHNFMSdJ>I1VnkFlRy^GL+&ak/>64iPcyEA<CWiRp@4\kbBLk8L$eWQ/9Ei\%X:J?jad
q*6Y*d ATtepidRm4jDJd\ylFN8Fmq6$jY*ei4>Ytjpbc5yZ6JMpBCyMIZ^e9ewqDXXLHhXCQLJaG/IjiDNe=#R
#X@NPT 6uT1eJPaI+6y1e<jFH\Q8XQQ+dS&<tX!=t+\8d=k>>%u<t<@/KW9bD+ZKQP$yZ%b=TRuWG=<*MWhwY5F
mPh=ee /VdW$d=p??wN1qq/e6:MItS<DMHH?dc9Ic6A@SYup*6WdZtAId!+LyNkNZudQZP4X+dR?YiM<aX!&+5?
waV#JY q6aDaJi!>c4DRqTRET?wL:*+K%dqV^!:i<jldH:lMJ9TpXKH</\+@mSHqB:B/9wIKlt6bqVq!Y?V6SXE
WPLZce 6!&Qu5&ujF?6W>MV<&I:K1Id@S4DMY1qkX&Gle@KHS%d^R5/N4KNA?=$9^88aFBPpkJ49i6CR=#dKk@H
@?I&#S XmLyul%?IYSi=6@<CX=e@+=uB:cGApiG*uZJDuS?>\Qm<NcW@iwNpmi15AkMipTMi<9/tW+9nmVudpnN
-AFP*y 00041001fb700110333 Page 171 of binaries1.zip
n^N%mX HLn/EalI<K8TPZi?KwqnWuLe1aE1YRB5RZee8T4@Ey!#EMHlE/NKSWA$MdVQ=KPm+VMCR&\y?<wVNZDn
DNG6VC 6SGJF#P#QRK%P&LL+i#Ql*L6Ai^R/<y1=6d&yVa>RKDnPw*q!iaqu/Qpw6$pd5%ty?\ZQPKk9aHXJ16h
bRqVa1 mHX:Gq/:Dw5C>6/^pM%ddNGFLHt!FX9KkB*LYmcDcG58ad9XRpqan+\Z9=tQYdTwdWk&1DjAnRNcXdn9
>k6@F^ =RKtpT&qHamqbaq/XiFAG^@DEdFB^9lMeKTV*$49%=DQq&:ba#qkVK%:jbRD@dC=bJm+>Ny?Se#Cbyhn
*AnuW& $1wZcHFkqDtacVVLcCXJL5Hb=ln4*N+Qd$BWk=/NWaE8QT=1Nw=<i@RbaqjThCXE?^cq&/y#jbZP6>4b
5L^Fbu HLY1p@GMpKw=J/pbYiZb*6GShd1SDkd4Nq#qW!imV5uP=CL?Y:C\<:1+$^%/9N+??>+^^Pdl8WTWwS5Y
ljVm/J MBBh^YD<R%4uiCiZ\RGt!^%u9uGZucXpJn>8%H+:kebcGm@QN14IpjDZDC8qJILtl?*/P+q5%IqkijZ<
TPKDq% L&5YcY^4Q95W*\*^ChGBd^a?9+*l*tbqS#CHVE+cJjDM@N4h%YM\dm:\dD+B4VHy<>%1tMdYeHa^*%c%
*pEK>h aX*q^Q#>8tbDA>/!V\MQEwSw6SH^C>ZV=SAu4G:PI<QP9TMmkW^?maG9KPM4ul*XFKP>55b<w:8hA\5@
$!ywy$ aCtuDK$&QDB9WXybbMaTMX+=b5lVX8!BhE9BqPIm^CXanCXZeeBlkL+/FTlMSayLXjITW>^B6BBdDE8Y
#i:mW+ wZ6A4AlQCTqM5EdPGnmnTih19HyMI<YCSkw18a8wt%*cmY>!nh1LAKTXilTXLZFWV!FAeZ=*M:K6ne4:
n4WajB 1<k!Y=J!9\GRNb$$IKym9TK4?I\FP:6X+S+!BBtWM\A^L>mQ/Y!X&9j6\#Dc:RS&wbE$iq/m8:KKPcA1
=4VpBC 89!J1K*iCYMkkD8tbLb#9$h!!HVF$<y1V<m/SFcqSBn^:JZWHwYM!DEBeJ#hN1/&VL6pF5SN@9TMWm<S
%^?pY& JT\Q>P\&SWXhCyu:qB+5V?Dhy1&weM+Q9S*YN5ac!XL$T8d+%J+#yJBDSc/ZYp4J9ww=!CI$YTHcJ!Cc
Gw^5=V V5yKeA:/EeCM>CPMtilQyA9L<%Im&XPE!6Ti%l/Qa9HtqDmZHekYK?^J*d@X418^&+Ei$h:8#FkeKB<Y
&Ec!F+ L=*\KjcIJ6?VaHHXbba/VC9&+ZP6iI4d44&+@eXXlnGB^Yd:*4J/!ZK%n/B4*m8b!=F^l8MTc1e6ecEX
KCyI#Z Q$tPmuP%wRQbZ\G&BF:^P4blVPWnIn*Y>A\RQyMnL>S8Z/R%/1I4:quNh=$!h*q5^=Z^J4h^^Stb*Xc\
a%J#&a dDyDKeM+$ue$u/N&&PJe8YYkG*K8ceM#^Yju#Fc>b\8ITiA5Nte<R5apkqa5nFh4<yk4GI94\I9:8nPT
Dj@t!J empm!NBLQi5cQ16=Yhm?>N=W!@uM^/4F*u/8+AJu!Jkhj?Ec4!JG#$kT/tn@X$SWTLe^#SAGiGQI?VFP
G?%n5S jL$*\FP!>u!@Xc5Xau#kk55mk%Mmq$1\byFQZld64H%9/L^D<MmSn\B9LWR!Hn9?DqiWL\pXV8kD46Nn
pD6RRq 8/yedq5X%lt!=*6^Q45y/epER6QEt1N>e/SSM8iqkPBXTX+VNb=a6SW*Sp=:iSIBd#^nEF6u@Dd\C+Fq
ZccQhT yNX6Di8TyBXXnc**6\4pNHB>?M*E=S9%9JPN?M>MBW:PG!AZjNcT!FRH4dyn8/@8^uW@BIeYQ=Jm<bLm
F9+B9t <1>wJhRV<$/Tqb\+k^Am:X<=nE+wa$M!Zqit@AI8LyEKB/<KZ=R+u?M@RHdu8IbKD=DLGFd*@qC=5CW%
NtFn=M =#W&qmcy<FJ*pZhE^WuAH^@pP@WyEClEi:4KN/a>l66JlLL5?HXH\qnbE6JaIlK#@SF=Ml59VVk?QT/8
BiETKF FiJMF+1!D/5e+HNaD!P4pAqW9k\#dl*Vcu<@a5bS>Rk9/Nq\F/=T^iZ\>$@p4Wl\LSHS^/e5iS8QTcVY
wGM<iM >w$1e+//JjBmtQE8eLa*/4YH5+15hk?mpBaHnTn?b=6VE%PdJL<$FujHMWtm#Zk>Sy>cdBqYda@!9:qE
u5dSiH iAJA@YF*Mk*e&*?IDwEt5\E=<e+5yH#pdD&P1M8LQMCFebFwMX9u$&DTB*lJYNh5ljnujP4@d=*<@*yd
*p:ilk Ajk@B%@j*C6H\Q:eXkAB8*FdkV?5t@>wCq&SyQ*HC5IN9QI4p4T9wK>#jc>I$4/C95+49!JJ?\4/8tL#
:QyW?W K=K$@$##w1+:N6>N/P6141>I$4/C=4uG^45mTj9QNQK/E9$4p4T9wGHZ8L=ZBGu@tWd\Z?N&C>^Ec+n4
1MTS6X 4FPBt&n6&n\ikb6wDZ/hWkX8wnZ+hWwX8IuY46$YIZAV4X*9qR9eSG#Z?6WCN^Qd%W5MCNlN^Ic+JukK
cTaPu? Ad8J&PDZnB\Bk@?qa@@Hjmh@5Q>L4@!Q*Rl@><19mmlH\K:5h<L@@\hdE>L?S&%NWLiMbLbtu@lM9%Sn
*&ak*d V%pCC!^LK4R?Dqlqp8<tBDZq9tEyGdK^&@XuHc*VK5bFtCWFCWRQ9wAN8dGHLA>#SZ&@FQJZj^MJQAnM
#41?m@ y8\aC$lLdHbd9j#=MP!Q4R+VLL8hqMCSlHJ<>u+w@m%MBXkAC5A#y11uNSVpSkubPZMk4a<*k%MB^WSV
8Ek*b9 +LEeDAbNQX&ejqBRjq!uIIBV<H6*HYlXlaNyGZGA<abEW\:=lnc#mA$9F5P+4CI=VQW8aDDM5VQMukcN
&h4L5h %KyWwGq:bCIBc?^q<:PHRude%H%=!RLP:u^BBVJRCC9!8qP\S1FuWa>cPMLc<E$Wde!=^SyV>Yyc<FRb
A+WQ^G ?NQW+XAiR9$:!ZNy\hYtZ%=JGuy><qN#VnaAq*hTl6+Thn&5+H+::mF55#bZn#<+jhw5NTRlRD5XyTGq
P>$%$E H^*ay^9Z:dJCTK$%9tm?&^%%n=T<Q1HAiwndp&AqYX@Be!tFe#!jnL!t1eDN5q15ZQ&6BW@A^Ama@&pa
51=GjA XF6ZGWuit!Ci$\b?<t\M1p64d#Bp\SehTl!S&lQT6yhWXEuh:jYP>I=^^ad+mMX^ye*EKp??&L$V1pZ>
aX\NtP l8AHY6>HuIuhcLNK=1mW1d8cFbt%GVWDlumY:l+8hFS:c>G?t!9jEH:XpQ5m+y%:bn+m\kZ:HVZqwqtw
jPV/m* Y#qRZ&jnBJH68GWHw5@Gwnn#X!ApZiPpDy8K$9qcAI/YC>Q4Vb+YiW>$ym9k1FM6Sqeum9=NNc@lTjZR
AG^R%t CND1pt4&!TIp6lYL$@Q\c$RAEk+5QL1V6$yAHYuq8/?b%N/PHkEHPF4dl:8>MY&L!XC:V$n:>tM6VqCn
PDE#i* YtI!6*P+db4&WH6ZZ69n$TZVpN9PpZqQpy^K^um/Aj8X89tn#/#HBHqk%mbKFH8BI\c\h=MCWNN=F1&T
K?aBZa 1Ipc@1A^VHEP?hwtuLh?c8$#ChPQ+%t:SjnbCE\E+mV6lTpy9q=i=4<?pLREE:@K!:HC!t8Wn1Lh1:G+
nPj?B6 6M8NIDYIBT<*BPRh?$6weIh%6<G@Wqcc6::Y1eIMHDCnam6W\A?!dqYFF*=nDHVD=AASRXQ1Lt8N+%P$
FdnlX# %qwY&4>=$K#6N1W\Fb:Rj:VCW8\Q68>4jhS?jIcnXe/tERWl^J1<#=mynk$/np<ephddZF=N!TmyGIWJ
XbSqh1 GFR!+ZS:K4$hwp\jlq8X5PC56XDq!>DFYGy\JNQ$pT89&ddQ8^5u+y8#aSZFKShmb@6\9GpHTty<MR5Q
EDq1jJ CmhmjbJQBw^dP5YXaaeK6kAm/j*VjjE=?>>nY^y<MR&GQluYNPHR\kK4WwZ4FNFT1t6LG:N$1tnXJZXQ
mtXG1Z tQ=RVljTq\&86L$n!BB9TIl6Q#RS\!nn>WYHtq/u*1N&?HkDwZQ*ZyHVXQ@Wl&a%Xl8:mM4b:yu$mqkq
5CHG$m hwHeE86+&n:Z%+GN=NI\Z\FJ%l@5t*RjQI?D@RKDI<luM&R+PT6b<8RFbEH5<++MhXF9b+%VnQAQR+Ki
QJ5LV@ =4@^tAuX$&GSC%FG9m8\8a?hyXpDP@yNqKGRltZI#b\HBS8@?EbKV@pLh1S4$/%NSJ%y@klAyD89X/N?
LR&RMw c#$C&hT$Lp%iMk#:1NReTcbF&%68RbZ*wna/kYqiS5FkP6=hV18Ym=SD@?XhdHIVJBt5=PE*6kG6@QbE
/V##=& C+n!^?W8\$Gaydd15wKWnkmF98qP6LVq*q9!wM4TCu9J5/B85S<?LnP95wJe5+a/LnktD\N9=XSFDW4l
j:GXMw nmR681@a>FRkC1Y#X#ne9kBIWh@XYF?F:dwVJmm!thMu195bFSHX<y9+>&m@jl:FtqN5I%&SppE$YjTL
q?@AZe 1MNJ64qS\cm^>qn#ERn$Vli?aGMW1X?qIVk1ET=KJRFmqiKL5abu&L=KM@hE$A^VMmAI!B*W/H%P%PGG
%cIih^ 5+1jK:8?e#>8P=!u@8Lc=VDB=iRT>Bb++4K18Ym1>X&e4CXtpH:SIby&4KeJyW6h>bu1dYYhcaeNh4/m
Wy=Jn@ Pw?VRCi:Je5n<cZpDP8Ca!y6QXy4G@&Z=Rt*B#VCjJ/Y@6AyBhq5LRw/^Peq!Eq/SVJ15XXMJ#hKc$?F
IPQ@Hh 9ey#q%GL@GkZyk>QIJe6=iEh^l>ib$AJSJVE5!XVX<k9Jb6>8F!I@E^X+P:Sqmj\t9P4jqF?DGiujJAY
*$YI9L yFHmQVButIhL%q4VyQE^T\hcKC/R^TJcS\P5+PGW&QuWMkN#a>Gu$iQnwDmy>hK#b><Tw?Z9YHd1=b8@
9yIFPZ QC\::?\KbJ!49u6LLGY\e5c:K?qwJZL6*pn8&$iRnJCyH4c+#nXKpQqH<jkWh4IcS:T1*8D?\T\nyH^1
>^lumJ ??#l*ZE*&/#L^q1ju8dCJ%FTHXY%+6*JM%w5%pZKGNS$i<YXWS+I5bamG<MH$R<bZk6\TwcX*L+V@JVZ
a8tby\ hQ6B<&IQKb:m#$iKZW@Kqy*ipmH:H+u+VI^:YPlV:H::$8ZdWqVR$=\tSF>EyKlXXSMIt^WC?u#JD4bH
46RDP@ Liah5Q&+jGbu/&^m?#&FbV6u4+!Z!c@^/+yAA^PW1HacRT:&yl@ZqAn^SmB$*KJ^c9dHCupeqJbMpX+l
ZeuFiZ k9#JKe@4+*ki1ekVn%<51j^D*R<1+^/SFW>>&=^M<T8^/u=<9L/I@$4H&jYe\E5d^G^?Gwp+D^#tL@!c
VbA<p* BJk&*Ku$<k$ThSR6mnd*%dGIYHWm$85LAuaSTIZIQ<idLa+YB>M5YGAVZBb=@uK<y!y>KV=mP#*!DeNP
ZN!WBq hlbn6pLbq/eTGNSHMt8L*AZ5\?S4NyRnQ51Q\cKd+A/4u^$&e=\^IFW%*\=5>\u!Ai?jJdJJ5<AE&/#C
IdcZnj DnlcG*BEhBS?9a/bn&h9+:H44Db&=nR8IHC/!ApW\ASCZ?PWnR$4Q%p%TPBAJ$VmnPWL?=jwId5LZN1N
BHBTjV k&V#Z6t>pYeqk\RuiI\?5*u9t%qMdp^W\GZe?*yVJ/!jbE4BDc5k:?WaZp^aEAe>=alCMeEkSk$VRR*#
a>1$W6 <li&>daSS<M?u>1wKYQ:M<!A:=WnpXn!*hWM45:SDum&^+maL:i4$ApXM*=:GR/BH?+RNHFL4ZP56<N!
XAEXE1 ek1^Lkn>$J^$F\ue*<FE^9NE=4NE%9uSDaFnZu&XM?Di?n8DSuAZ$\<$E?AI<?eFQ9Ml&Hj&WkJGw!/:
4V=J!/ Wh:5+1=qcu/4Bm94?XTm14hD#K6NL%1AYVY!ab&qPh^YV?@d65VkiH**m:FZ>ZTI6h#k$PFPwQ^ik9Wb
QI#MMd =GlPh!HJaImnmQ+6Nml+5RZAic^kb16R5KmIIVwewKhTCBH5IXG!IFjbR4JLPG5EdVDpB\G/:/qkGKlI
RRtll8 /ctcNVQ&aDMpKC1=1mpS^VIHJlC5WR86L18Jm\\HbQpG+Km6KawjS!uq@FGkjalW:!dVaBTl5bDue:mk
-AuuET 000594bddeb00110333 Page 172 of binaries1.zip
d995h^ D=*R6N$$6I^1kAG%luVJFDRGI5qcLMy$c5kRjtFulVtk\cuuQe/jyZF$i8Jkq1:MEMyjwVEGww+@YY\Q
N=weRk yGaqX8debDcqiudID1jkwIl=hlbnGt98lPMAi!==CXE8+>uQYLL6%48?EMYEqe&yE\K<pWe<EJyjt=dV
6dpT?Q #mIeJDMTS$uPNG4?>Wl8i^kmTmh=d+h!pMp$ym!i:T6@uBe9#dG&BQ@M15EA$!&?M5qPGiAc5dp=*a^^
D<luVi 9Xh:eNZ<bJ5yN5GP*:E:N\5Ea^FWIWdSJ<N@yKkL^/y^p\+m<puG=lG!^ikw=lcmb+Q*jp<QYaZphG5q
w@TlLZ 4M+Q48+jy1KYyR@Cj@t\>6%mHeud!t6NFE\NenY&\yEy$*9BnC&PiMWX@wc:hPRq=^k\:^68Q!emaMbi
:ky\A\ R6DJ*LdkYARXcK@Rqeqt851*<wHFLP4lw5EVNV$Bh!iPpEN?\I^kaDmnnJ#MTmQLeaJTb\PBcI^Ti^LL
qJhqXY +yV+ek+P^n/NcSS?nmmleT6Li=<cTVyDk!<HFw/+$qjF9FWJW^^\ABGBKVE:ql%:n!nLtmRdZRnjIVpP
&:VnlX NyIF1$ReteP!+l!!JhLAqAE*jptBwR4G=5jLJ@qCtAAk$JI9c^pPK?C$$#tV4PClq?eP#StJuyGK<DNl
VdKIch >@G>@XC>IP!$C$?uuq%hpZJ<55KFcbN#n\*&jy*V8El:6C1h?XB89MCpa5R58qcVMaHV!SqYjjGeLXSV
W@&N8l #4jX$p^DjB&P&+H%j5#a\8a8#<^B+pN^+MK:Qm#PLwJdNI8qJbV>dH+!NK+/ldHCK!Tq!k*86pSIM*:A
ei4aQ6 m6Ih+tQHjEL>Wlt8W4ZW>lGZ9w^i!#MmGW=NGZLyIQGGmGQ=RuhPc#YV/VPahINn%dDJ91hK1jkGW8Mn
b=KkH5 $*c<^\Pem4\*1IeA*AyR*4EXZE!/Vl46j1t5=mc:PmyVq/%8kTq4KtJ9jtKypemT=P8dwM<K8M?+HC89
HC#ne= WTw@XePGdGbQi15I:XFMKDLF/j8TNEEL@YDLTGn4J/cMeX6b4Ww>*+$D*1=l:KaTpGh9F5qJF5a!VcA=
&#<ljt qtW+hG?@atL$>@5^lY+LVwb+:pELX$p?Eqq8><>!ACIu$=i!9LkPkbNMEq*&m>cC#I*MJP:1&mBM6ieY
C*9LBM H#C1G4!W/FVpC1t5LiRW<*JE!B4byBCMCV:1CZZ/hT%YDehKZ@Zh#9PAym>e#kB*yR\+%Gd>l*VMhnV<
Y#!4Wu <=pC^1CiNK1eSjIR$X$>in^J+#K@/W*ddtqIFMaZGN\19+bLuT#EcSw@#MqliWknpcG\ZSXi!6S19PC>
FVSWP% +&9MjI8Wl%Wcd+5aQR*b!m5Ni#P<M#N8N#hEDB$LXB9llEc\=EX94W6H**9q\8pD&t<hlpik*\PH!VKa
NikmP! Vy=iRF:X:Nj\^SKEXeT*Y!QCQEP4T<GmZRFFdmnLIBF<kThTlu!M<^C@@enidKu*R%?nPdTHI1ViH&pR
P@hB4? Gu@B>Yec@mbVPMlVm9^b@&8Jm<^K/m%:pc>!FYNR%*5iG#F9m:JZ$98Z8L8iA*ltwZX#M4DXk&#8mPN9
H4JK^u $^q?C4YGE9!E^FV1%hkSLAXyE5DL%EIWibTT8K#t4eMD:Xi1qj=kBXWIL6H+%?PliQL&NK\iG=KG+h9E
NjJ#5B 5y5PphlQS%!NthTjl\QmhDy#pyHqpa9N5#Th%iI!*ESBc\u:Pw6P=N=B>a+HNtK^i^M<^Zp?i<@Xa/$j
JJJTZB nV:pX9<FXD<<KqE:YlG+ba&qQaIc/qQ$wHA*me?!bK/<XSn/*QWW9AtKQ1u^ai:Nh!8#aGFNjn@mJ/F?
jYui5D P=dw&HpRB5QN&MuNnDY9\dCY?1nlh\Cci$<W$NeTYNmW!CMw+aZt/D%>Yq@=qI!tmSSZqFW>Y&qJEAuY
Yq1BqD XM4LGG#KRKwqa!\?q:KjcH+ySDPANQ*kbGb>6VYQkQH?h!t!S<D?m/Z4mC9cAmB8*laAeZXdAMRXEjX@
BTDZcK %QH@:=PCEFhE%F>B\/@#9AS8Rq>VSw&+I1L?#@S%ITcIK!L14/AS%>H\G>BI%HWnS>!E=4*8&Mkd$Nib
CF\q&Q &wk4I819wK>JLEheEXH@b@y9T^%Z$#jSG9!cYtRE#$&$>4j6NFjVN>Hc6ca&Au+V5X*ZB\IB9+ua4p5K
Z<\6\! R5B9Indic%bREQAdma*98yHjSG#\/:+i@lSS@\j:9#K%@%H#@ZhVG\t:\6T?M1IiCj>@EjZ@^\9Ac@?@
t/Dn%K LABZ!QmZNHq5HL^qTj<c@$ERbd=@anF8ceWuId^/5%bminuMEnW&5M4*ec+H>5/&%G\DeTX$6EVq5NjD
G*pWae 8^hqP#Ga55bH$954Mb?dccPMF%G$tb=5ALm=P+XeaEW!4<^ync1m\C$1W$wbLAY61RuPIe?DQ4pu*bPc
J4cp5+ J1L9NjnMp1Z4NE:V$EJI=d9ihClc$bM:+<6h&W6S<V9^FnQVh?@hEa=F@Mbbd&j/@R:RyGH5*bm>ZhHj
@@MiS5 K5kjKkM=/Z*&B5RmuXTuEpl<wcyX=J5:A6lQVHmS!b&9jAGw\Icq%\*=K6V<pL6dM5*Iy\6V<nPV:E:#
G1L+pk jNT!&hZNW9kiAG!#YJdZT9MPV&dpVkPDk:ESL=u+?F+@IiF#:+J?dlmt&RnyT&cIbXD6pL=@j@\AIJi%
a$I=Dp 1S6DEVABn4V\c6yVd!:WJjd:\5d9I@1iSwj4:5Mu1$e>F=?d+lqeTut^IcWFMly6/dqjluYMJ!ByL\IX
K?Tm#m F&tXQdK6y=+>w:AYJJ@bW@&&q6L/?5hh+:&tlFamNwA&@BYjlMVdd>TPXW?el4/<YnCCPmJH?S/99:q$
8\CBn% aJ6<6iMw^A<>Wj:$/db?CP9bK<LG\9/MV:j9V#6<pS5VElM>wGyIIHXKha\Y?e#$cKu!dI$9SwS%$8hP
MycVb\ >L$=I\N>#@&Vi+FKSEWQqJ+u?qBpNn?SJwic^AN=inRb=ALJ#w!Q&4Xy*aD8ppnB<VwyG6Au8VqJynXn
PimXDh c6^L4&G/&YjFBbH*JkminKuTeJZw<4+$DRuHZ?4pbBlG=hK#kMSiKT85Q*At@%9?N8&Vl<:Pj<9jXkal
Lat?Qh ThF4GEp99ZkIetd@JZ@d#N=EDuQTAE?AnCVQXhX+ZJdVuKcbKHHKaLB$n^9jk!iZwV6%CjMSM&6PZn5&
qlTTJh Yc=mK<CR!beyIMp/ZmLn6R<wZLi6&=leTW$SXI1Q#9J$n^/iXXG6/HnGc/XP4Wj!WRE\@KB!plL<ya?Q
KPdQ&5 5eiZCl9?:BW/C5yJHAZq?tAK/nhqqS5KRkG@l6mLqd<!4<cadTRj18qmLjM#KS\4M@iJwVhne>#LXt>5
p@NPFn pHWa^XLW6h!VHumqF$YnV1ckK8jE9IbJN?Ri\:Z4P%1&JV?wLNCpK%*^/a*%hnntAL?ecu<<l+*>8YaT
JZN@NB nVhNI^QXqLFHty54L<E$E!/ALbFb55Dd4=Ae1*e%Cu6wF%t!=bpSLGthH:<wRKk#yZVm?FmV:niN!X?8
$CkXDF jF/m6uiFZZQ/mXdbR4$TMi$+uN%EInuF9=?P$>XIk?%ZXdyW8V=$%tYD+Zd5?AwCe!bq$1RPc8@ya^:j
XiKW6S wnynW:V9\W+SZp$XD*eH9XIeth&%ibS=LBhd5!uQ==/@PcDw:EndSZj!ZFF=G8BW4>VNuim<uBu?!Y4^
V55AuZ M%&:%Ge6nWRCVaeI%XCB*dI6*V+HWnEtB1aIt!u9EWDJWmN<wH*M!MHFN:t!11YX+AQdy%DXM??\Yi$F
=6cwaF W>Z9Z:Z1?9djcS<\KHauq5mn$K!Mep15lXtwp+!IB/*YFHditmu^*$Q1+8#EF8k8RA$EHS@$MGWV<$WN
A:<6=B /*BtA>&N1dFLVDNLiwwWVM8m5HW5dmEAHKJhH:BnZjnC!N=Rpak4kau5I%p&DnM?5#Sye>W!l>RabHYZ
!#X\e% QL/qHpBCIHaZFbV*m#I1ZARHe>+@tTaDD&9YpE$5LqIypVy%#%8KwRAjn\\?yAeDL?Fk%kRB?NQ$S#Y$
eAXJ*A Feqqi\#%X<Ga@h<++y?h=mIYLAaCp<\^Dca#knR$qVDuWE8C6ql?mbFM*4&TNJ9VTahwwmP:*1ViZ9i*
WBaupj eSM@Qp8B%Shuy%n%bcJXI@KV8DF*Q@ac%<VW^Yw%>5&XuDeqpmW@LyyC=jEtTu=jm?C@^S8FuN8PquB>
LmKjHH EbnZ>IZSI5kwB8=iIEBB<ZyW&K6WLWdZe$c*:&MwM!Q%!c5u?&ZLIyQPnbkJGT=eu*M%EW/&a4qh##TN
Bn^ZXJ XIX18uLt#/SK<aIuK?+a:H<lb/qYZFdjtqEDk#?%b8R&wDbSli48MLNe<HmtZKD#\j#dN<\VS%N9i+Q/
@cC1w# >*/W?9dt=89nN%d1BwmQJtMVW*#9p1X+c%M#+n@!AQZYCFQ!@FphmTtSu/*<\IR@\9+bLQ+dK#WFbh\u
JX+c%\ E\yHKiRQqV!Sqa<JcJ=1G&9QGSyPl@iRX>Y9bPyHXt8BlJRXh%8#y&*ZIt$!9#&4/@p%9<@R*B#%&PcD
^\>8^> qhen#:d9NY?w?Xy:$:Y/\QKiH/9WMl9D\k*WH9DwQknZCtF*W%Hh>j@1FS5wPSaeY:uCYGNKuhJumPNh
<+duW/ T!&TG4F:Mnl<m<D!Ly6&%juCn?ZWk\LX61@4Q:>MTIMVjpM^GwKInNZ/CHNq>Db\CIEaFhV/#pEcCpi/
LN6iZi *FkkNlYjEeqh@Aw&Yl\GndkCp+>%N4eLinRmqccXAt@:j1dtE\eN$=mpMFyDeTSmP=k/Y&Whtt#!qAJZ
6**:BN HS+V?&/&yh:YTCPb\A/&TjJJu*!Tq6&$qe\wn/XI58!><@9V#d@he<4MedSq<k!b@mWjWph9*l:h18Hi
Q>4*Rk SAJ@WVNwDbq^>Np9#GS4S=PR5FmAH8K4q@/<HWQy%m/ZWce^\I>Qa+LBe4yq=itVV9=!wJ+1QtjT#XGT
kGQiT+ w@D%4C=+i$W!T<Dl$b%LnGLe+K?b*Q98&FpcjuNY$h?hGS\#yZYMXZa@AT%QBwZqky>XS>qKA<kE5MXX
KeE!<Y F>Pp6ta5kpY/eQ%MkV1?:?XZGPJpmCS4!6KMA$M5?4cS+cdQPRu+dDeAwcIRNJd1P5ql<QjjPCIeB:+Z
jL^8Y< !<WXq#&4^#CYIAkcB^WITS?@D\^J*KnLBZqKql9m+ly=h58YYwu\=*eTEDGXE6DmT\XW:VQ$w$Yd:bmA
qWB1eX 1<+=$1t+PCX/1$d1XkW?*DRyW8cL\jh8*Z1nG!+H5D=<HBnCX:Q?4j<hQ1P>\DCwY4/pBuLuqtkuBGQ^
nb6Rpw P*41A*wMtc>lQE=T6be!PlAkwXVt8GniF?pKNFPY<\5Tywp\ZyZWjF@Zm%ZGT>RmTSNLGC+1!S&li1TM
L!8?Ec NEaVtCpn+>*=#DYE#KKin#5mR=+Bk^#:D1J5aw8EtT//1\<4Ci@^kw?@YQ1wL1=ZEHpXh5ZbaM!6T9kD
LAdBHI mRTnhp8TRDXXF1tpHGJ+*d#E6/Rwi!KcR+kJepa$CZ\%n6m?llKV\PKM+\dK%8=yT5$%^5ANC#j84qVI
W%=I?X BX1u^NL^E@?K/VdB:=Z6*@H$dZiYlLZ\tW5nE:k8yXhqALP<^Bm=+#8Rtp+A$iGI#XS@wG^JDC6Dk5T>
T8#nYJ CPu^aF6?q>pyJR4c?Aa@t:^B+45paHLyeVlm/<KDcNdbD\&w5>VCDnGZe?<6jk$cP@$X%>d5/5Lm+A+5
NDEM4c 9E>#IHmEw@naLM4aPMjy/A5wKQQP4XchedwnSX9Wam+J#RBw$QI#jPSaCe^M$p>HGJb6CdIjP@hTI4?$
ca:Ba4 !%yZ!A9i>AQcmP@c%aS$CwjmJZHGHMC5SaNESiM:?XtZehw*%eLbY+K4dPB8pJ$\nk&*P\n^lC$<*$l^
JM4E^y pjm8+^$5uLAT9*A<4ZDH5jC8Z^EMF=*K5+4Y>dBTYJk>Q:198$V&%IPLQHbw6>qBHMq&44G+G%8w:PW\
YWDBID <#q9qnqIy=6:Kq%yhdSVL!Gaj$ZttYXuy^eIHY5lQ%cpqVTAi/5apqEe<C6wLI+D:Xp<?@mYq+u/5kj:
-AV&qk 0004208d65000110333 Page 173 of binaries1.zip
mutlyc 9hqljGF5J^G*wW6CPt@LDLdmtGjGC*a4u9qhup@BKF$5Z&Swy%^\tEc$1&iymA!8KZNZ/G$JhEu5huq+
A84M6u ?aN8<YtbQLjKPD=\p8tAJ@6l5BA>q\dpZJB^*<:y>P9:CYE#e<6^pW656GyhKRl1#a5^aeIkQpV9chE6
BWJ?:@ n^\k5Rly<td5dIqCi*YlH?*dA*CB#:9<tm%Tu9hI@!dcA5DD/X%SqpRY!EbE5$G#W^pbNL4e=Nah&Iqh
d*cK8i Aa^?aH44=%$cSm5XQhB>GiCklCn/FQi^A4&eklt/ERFKXERLY*&?+=+nDYCZqeqXdQm1bDWVJ*N96KTL
QDN4FZ %FL$1F6&Ma=MI=cqF1%S^@aS%!!d>=dw<TClluVuJ\dH+VELTyC<qRLV6?E>KkqQRn<%D*c%eW:H6XFy
mpd8Zm ki&Leke:RL?$m?k/JL:6AwaERCVH<cuunL5\LNMqiH$JyL$FT1Y6\l@mND+#I9mE5T<>k>8QA*!BR=SI
c1VL56 !kl!hD^@Ju>?18lNW\k99c*l!:85JtG18nu4kt<K*EnwY>YG8HZYPZkVHPBJtRikwNpc^k/5Shd86#b^
\pY6yY 5S@4X=M+1nc+&h5PV^@4*kwqZbe#IiMY1cq\AVlLlYRMPuX1T1dDIKc6&C\BnKLMIi8dmhBAlBqQh*9k
!n\WSQ y9m:@jph!Ab<9=$Vl^&bcL/^cd\*/mk?YI%pd?RJtH1#u<lu/pc/4KGb1CiY?MmtV!e<@@I!$V/8c*G9
8ZpE>> *nWT::t6GcuX/m!<yP886ClB$YQ5\98E$TBlIAWZqtpe+DELjlBiQ<Hu#wl+QNH$Y#QyXk\H=qMJS$\@
qp*?M^ CBt!R@CieBLFX#mC@Td<ywy$qFS8>\RJ+$l\d1q\<cF5JS^VQ1CRl&%JyL6JKTW>@T48lF=?6pT<GLQk
yS/G+j %Aj$mZtZ@XE@YTtEdypuKH<X!w>4CF@8X=@NLbjM&\p:HHV<DTu>tjWWk4><5Y1E&ny8Y6^Y**nBFT&d
i4&INX T4VeFL@uEtuIGcm5T=^RkN4V6*W5Wn&Wd\+1cpa*jw%1TP!k?>Ay?ZlX$\#>A/Da<9mq:>e*Vch\wMZ>
=R1HZm ^??j81RG?uAna\:>mpPEyQyaEHK5ypk9^<PLFhGhS#b%GSDpkENa#Bk6lJ*@tIkM/VhSEu:aD:nkbS4k
RFB*+& dpI1cbLbYDkEJS@K4diAR>TYwbpBptFbFp5lGBPbS!6Kee8YZWZL61J#K:Jj8D9X!cM%8&X^!bpcA=6i
aNHTAR ?npQtwZiI5<Mkh5n$^+TVD>XaJCRaCd1VkQY=$^/T1?m6mq<9XKhJG91#n++BI1$#LCqd&Smtm9:eAQZ
8dI>cp $Ht<=P4BZV4i?*wHbhSPb4+tQik5T:R%W$:l5EN5Kbd1nq1GLypFuWTeN$Xk+Z%Mnd98Z6WtIb8YD9dX
u*t/Nb Fh+^Xw<j8Z%H6XmwX*wED*y1D>uG4LuY6y\qYutVH1aa8%V^TS1neMuL8lW%8tXpZM^=W=lp9bt5/b<a
=Rw5XA Kw1yT#\McVp5Y%X^k#AcDaMba$MhLXSyqcB&Hw6nM?R!lFEY*w&!8^4LMJNkAeRV!<BMJQB<u&/pS>TT
\j@TdE R5!5+NeHhKq^%\5ndB%imyNH6:yMNM$+8tLBTISJn1yRk&iha+&&6FWG&FTNDhYwi#uTqTc+cCSd#k^T
LMlTnG jbkaDRIFFjRjnRYpLS+Z:wD8qEt6tuDY4juY:h\:\tWwXpbG1kHLkh+:umB+JaH=R*1mJkC>=!8cE+:w
8Rh4wa eY:V<lSANG8\epFwc^LbT9GHHyaRjT:+D4HPdqqCH&meuyZ6LE@N\Ca&R+daKd<8tq*C4aC?8MCn^AXa
>Xa%=K MDmKc^FAhI*J@6?uFRDm9>wKAIGE@>qpS@Le&GV@X:j1V#:aFidnu>P/4/q=S%#SC8AK?yyKa5RX4RC8
N^iX?E wK?yJEbe$RwAeiM+j5RX4RC8wPHZFQNi$R4kCy4uG8@^mqaAj/cSAu#Z$Kkd$Njd^Xj$A4nmVd@Pw:?m
&\Xa6/ F<AXNM>%d=9Anh:$c<V&#:$A$Q@G@m<6&*<jpa=Aw1/\dQ>>q+A@LF5+<9iQ@u>/HjK\4u8JjBC^bZ5J
pdSXZR \*+LRh#:IG!V>nEDjtw=cX+BhNMnHwBKDE@J?w+Z9Lkjl<SGlm!LL*cIF8CC&X4DSRYmQ<9\ttuGBWBa
H?pw&^ 8!m$D5&t@eHT&YI=!<%>L/GYtRL69XFq^RQ!Ijpqa!Ry%AX:P=:WLJnq!6q5m&ybl&>5&RhP!558nE<+
bMp+ei :FnR4J\hjtnB/C:ZFYI\9jMwcak>dG!mu4dQ8RXR9n^HF5K?QE=bFiYtN6/6MAl9+^/HKk/FHFqZ6VVT
j^wtV< !=/?qbRkbQkNAKa!tMXWT8B+pXM6+Swd$qFnt>P^u/iYuD>AGJQPV5RAt\Mib8V#MFcZ+STLqPyqWR<:
1&G9B8 !lP6NWQ5P*kWa$nDpaKpK@6:\e4dHFS9>=*6kB*dy51jXh^&nu@tK**Q1/TQR=9J$6hnYFMJ5qZRXVPI
&uY*At Si=B@BXkChC*@yJKFDFtPb$wLj<cXTQGKLRclZbZ*p?>P8I8AjwR5Si?#DGamqbt&4qTmcw#M*HwnwG6
ySjmq+ q1kjwyDLSNZlY^mYY\RB>G$%HA1MyqDpp85!XZXA^u^uL:H%:EVDp8l:w61KkT?/9c:<yy$%ZpKWW^@M
m*A=Mh nD5FhX\bdi^$@T55tT5:+qT6B%JkZ\JNd8eVi89u@K*etDP@I%J+9K8>b914BpM<EH@c8J/R*X*jdpWJ
<FtKab J#:/$XEtYj>H@*^C/=aP!cIS/h8Hik*Xce1<SS??F@=G4XM?b9hIm1N#I$!GjQIP>ah#RKcJjTdYPuIn
p^^CXK bSCS4#e:kt4aETL+$SR>%Qu%EYk8bPW%ZM6^?%ZQ#ylnb\S^&?&:bcDFWBd6FiWTQu81Bc^ZH+X4h1y6
:dS?w^ jcaplT1HNkkL8n?!Scemq+aE$npGV^Bp*iNplaP:m4K#KCpijeT#P5J5<DRAi?D5$iNZP*eL8SY!u<bX
NkJG89 ?STqP8\4quM$+=JQBi66&lpFRMHE!k%R&^e9%9\q^RPJKda#jL%HjKtK!4<?icLFP%<@6LG&:!8WbKJc
hFbpHc u?pa6@kqp>RJw@DnA$t>/aYPeG<u5jY&>XQR@ZyZ=+wpN1#CtTj+!@5eI<Jp/V%iuTtCF\B&Vn&/D&^k
pn?kS8 YpS/MPA5unM^yGq//n/5Mw*m%aX+bC:dDBJRSbw*uYeFpulnc6J$Q&*mK!G=?8>*/X8YuednENYAaWVW
4iDKJR 6#y!@lkdW<\kcae#myC9YB?:CqTCn!TyGGd%\uN>DjVGecbCb8=%t+4FtybheGEFN=k8FyBbGuhRh!RJ
NRk95C W*e>WWFEZqI\E1t%=R:hq!yKj5Swb6ReQeuKN%J\A4YacB&FQnNeG9+kjmG!wi@V=Jw#DWWW#Wh1D8:#
XiI&eN PQ8w5@jK>@h@jECLH^XL1<8FqY#8!!njQwCX9HwdY:WYbVuNqhWnn$j=pbPDkH!:KCB4bp49Gca<J9hR
^jEqqZ wNe\p/tXDPpDpYAQ!5h^Ca:@+mQGWMdXw9@tI!ab@>%HbPtIq!pqEbtbW4VA\bPpVGYNFTFX^RIH$dDG
i*p\BP Bb/KK&Zp11@hC!cC8V4=%/wC/?KTcI+4M8ZHt!Wpu&aG?GWhm$tR/+4t5PHwmWImJ$aA$HS@h55*pSKq
aBNp6> aVdS%qNNBZ1WqFS*C&Eb/wL\<>k6AJ\:>?P&!FTI4ia!uVTS=JTAN=ti/YD%<:4$6kKpqNLLHmVk6taX
F9!L<t h&9DB\6iHZ9u+Zy!9jj1tY?K4A8QCmkG*DT*6wK+a@HI/q<ynpd+&^WiNG1#u?C4FqDV<%Rpe%JJ6tT8
h:HWDm X@^W6BP$#%K@JC#!u<6RX^XV>LM!*bm\4J%$6S=i8<59Q:YTXb@6up\^?>\j=!AdMiI#itFL/J>^/&Zm
A^aN<N ^YiXmSj&%4h^ekce=%qZQ$9I*!ZKE^%KiSG5KW*\kFK#dl<5*6>$T8ZD!YQeV#Eq11?d?\c8I\*q+T^9
CqPI:5 lI1>WPjqGX+5q%CnY94W=:A=e6yn?w&MWuMjH1JDRT/H:q/+4cVNqDId+DhH@bElXkEB/ey<R6K^mV@J
nLwEEt :<bdW%Tcy^I^Lw*cnlbRDKNSH!EkW&G4qhKqV?cy4MJVTiGXNN=l6C4G!5?i%hZR>^M6LBJM:#njD=LD
V4>8DK @1YCj\dYIQ6^Y>Hbi48t=*$1+Cut?FmII4*Q#\laFWRCRXJ:+MMW\QqtlB*Xu=Rh4K%6P>dGkVZ#nuAy
bk^Cy! LHuute+TF64A9*WNPJkhk?AIb+4pTjF>HNVb$bq#DQ<=cTa&!Xm?8=iaR95WXEGbnVyHXk\B%q8Jnp#T
E=91tH ml%4yp>X*!1R1NWY5iP+k%Sp<B4i<SThQXT4mkA#$ZNZu$?aI@Ah6Wj^&w!l6S\WekjKWe&/ZK:qtetP
kY\hu$ Nu&n4V#pl%>8N$S&XXGcN%Nt6qjujQPFk#FNZ16hNFLS*!@pNd4Np*NRdT4tG^hqy*Vu:e6<#>:*ZLiS
Q8V&^> VY&GWENH:@#1WkKMNe?GS!S/5^+>qe#yleFyTqT96V8?5Gm9>*%5^HB46ckRetVyIqSmL#KwR&jdBdRQ
S!1VYZ X>uhh8V/h6CYh$Gp$F5YDt/qD^lR4<6M>C@W@Wk5FM4$<?Jak6N&tFy6jdYdMQPnjdZAYEBwd:*CmpBy
MuZ4V$ bhPd?=w@:\:JD\E@Q9*K+Ztu?h=9TI@6d<Q9mwZ*&Ic%=C9X!qJH#P>KtPjHX$twXlbX>4+KyHTw#n=?
I5qNtP u<d6Su>yctZ!PjCB#5y:tmBy:k^daH/k@@^Lt/^d+G?N#ET1:?mFZD?4uI*SB/DtVRZXD:?8u>V!q$B8
F*L:qy u&m*KwADCkt^*tqlcaReE$&FNJiaiAjPS>^TyRlm!#t?8@m+VXZ!%ihQ5\V8=nKRVIZZKJc^!MhD\S<n
?:u1p5 9#b!Pn#9hIdiq8Aa%=:@\K=$#mt6p+#X&t8ZdX:&qN=&5j?HRJLiw8wLh&=L6<:QKyI^9<?596>uk!@w
XR>yJH dj>t%<+9qj5=6$@45:yBCY4A+cZ6!Yt<V%9E:M>GI:m/IdJR=d6$CFS/M<aqlAPA^<<qj@q1T:BW&hb+
XyPaqu \NdL95\SVhPK%&:1>BZV9PRESq%klTXE$LRm?<c=F%pXb9T>Y=y#YG&*:=^LeXHTDClmNRh@H@hPXB&w
bpa*/# bJAtj6%N*n@*c@4955pb<e?NwQ+#N*#<X>#\<h*<lk>%=R*jFb&q@5lC9eu6\^Yhyj=VPPw@#8GSmQ@>
+>iDtA HQ/QTw8@#?H=EFjN+jt8KL8A@d?1m@@nXSiWITM?Pe6I5V:$C1B<X*T&&ERmmT#ElVSnPmSZIt?&Y$J&
=D9Ql% jVwp818h4F6=%*wi1h1*5Qn/CA@NBXSVhKIEHqHFEmPHZ%jij?Q\&8@+#cL/SNB%J#j@j@*p@m>:Nj@e
y#Dm:9 V8\@ei4!wj=</9L^*8DWFZN$hHL@i=w^k8?Q:GK?j#S^@Ne#t??Q/GI?=JYu?BX>#Q=IPj:*6@nZ?CyZ
^QAT^E >DH:M@*:9j\%NQ\t^?c@^mDkSh!ESq=nEQAmd$JjX:VJ!*5Dt9ic9uWIZ6SN/P91/K=Icj+#nd#Pld5m
94meY1 yjpKGuHh!AX8R9NeR/N8wnYE\HZ$VdTG8M+@SN%Ec+n4Qt@WVdS&ZZNIBPwtY49?Pwnm@Y9+VhVGB:9G
W#\i%Z ?$V^@TYc@$du/HYj?I*Wl41t\Jn9St4n8ia#?\<=#Sb8:nVeTn\\LkG8*?WN=?YT5HcY6VA^=?LuW9N\
+E<G@/ hLS^6PJ!6:dkR58k8eVMHY\edZ/@Jyt+P:t/eYud?Jm+t9@np9D*L?*jj%Q*MHZ@?^<WdS#6@u=FMQ9d
EIcCkK Jiy9\R1<9^<d?j8<pyej<T>j=E/8=4>QT@SyaH@@?hNI+j>ZSw4<@WL+6&<VJC@@*+PZd#JT^J<thAL@
Rk5^AV QKFD\ju?@9L@X1u@n\ph/6>Q/JBZVPn?Pbn/18j>^$RS#9PQ=?Z:>@Y=An^ZQT@9u!iK9<<9ij:*M$XA
-Ay5GB 000f004286500110333 Page 174 of binaries1.zip
FpaD1Z q+qju!k5MDJERlZ#*/cMSV^EFCPtYK!t6PVIMDy5@:+YS^RSPBSdl:\Vl1TTM?+eL?uFBeP:RiNa^L?4
N^qaLH qB=pRl^R5A6FWw66cjlnnLuCk<GM>GI=Lbd\QCyVI6ylRXJD/k<:a>8#jmXthetRI$#SSVWNZpt<?pWN
ZhVG<w $#%\cEAwZDYKMqm#jLCZq>a?!ayFRFqM\&d*MkyByM4T=iK<ctaTJA=Q6<Mde5Pm$Kk&ZjKd1LeaY1DD
:5T9C< tmX1N#Gy:!a$DjA4JtCl*/9:wXR#<y&Fbm?WLyC&&aERT8q%mZAy&HlQTRAJ=TLK/S4eetlq?9Xi*hGA
56eemp \56:iV^8%cuq5@QI&$C=^B1LqSpkuZ?%5TM4X#K?#ncb>FA?$+BQWt=hCe!XG6DStWAFLC8^u?RaGIQ/
pm<6T& $+Rl+MG$pR^M>b\acuQNXVV1EylB^FVT%G^w<:6+BHEJLhXT8%%56hYeb4IXE6F^cD1B4u^:ckB&a6JJ
Eda9*E qI1PZ1/klP\<wtYV*w91Acc%=aJ\uF$hYS>pyb?bIFhlZTA1Q#H:<y&^tq<TZDbAAT1b1FhAH4JX>#$y
kLM49Y BN>Wa:LLRSE=E<JmbkyAtSc<yRGDy+4YkQDM*4FYiuI%CmCtFCH>kGPL?WpMiM4@QyJYawqFcJk\=C5R
qFXY<m Hm\CFVmN9m54!%qn8#w+phaNjZQ&kK^MVi*RHC1WFLc@!Y<&>Fa&?llt\c!SEE\5yS+VFc\VjD6#=G#T
IqA9hP KdCQwk>eHnL@JmGQdPuX/iaCRm6tYPlSWW^>1bdi#AQQuRE#D@hq@1XKV>=b>$N%Fl$%KejNtISye1li
4tRLQa 56T>#cu>5$jQb/C!16/KpS\^\jCV\:DKltkPN%EA>qADib6byRT#&WFt!XLW@y9c$Gn/1Ye:FpiuMh?m
iCjK4M 8hd9ik9HlBqeQ6SJ!Apwm$S^+#ep:1M?l5NQNq^q6=mEjF<u:WcSl>=/RE*&eiwy9ZwWjj:mF/NaGlQ=
S?HEE9 bnq%d+itX95e&5FS@6uQqmuBK6=<*=KYY6c@y1$L1u*!ZIR/ZHmTjAciiZWi:Z<6XHk1n@%CY@dnlWhl
Rh<D1I 4#$mMNSm/h91\FR?$YSuT95&8nT*MViS>tGV/X%CLeF9GK1KNa+D%W<>8e:pV>w8ww+LJST^FWNw:>:n
ER&l&Q KWMS:XmTQZ4F<Bb:MapQT1W^N@*w9nK=FG/j6&NpNL<cW4y<cKw/e/qMnj8^B&hhcbqqJn9tCMj$cAc@
Xh$iyF 1n9RQb1=+\H<>adey#6VMe:ViH!C:Qn$bYeSu8u\h8>T/yPTS1QG/I<L#!wwPLNkujHSQBQG<t>Y:5q!
C@EpTJ =E?</lPR8&9a/Da\hQ8Vp:!e?G&1C:#t/TAGN%a=ye#mu#lK&@EkYNyTQYPM<=j<#*#!i/@bE@5k6?iy
S98VMq BFYPcQkS@Sn?+lh?Nb?NM/e:\Q+t:+Hd?:mmDa5EqK*Xc5aDDAn5@n5p>k>C^utiC8YWEKS%XNGM=EB^
wDC@w9 WCJJu?6E%YpcV816TTdN+LI?5SGedIhFn6tdXkKqZJ#*aTtN5eLe!t^HlY^VVXWnBJ4<wT*HCDtk1>u4
JL8#6e Y^b!hLe=*Q&IIbP@dAhVlB6PC*cGc#eeB?+>qPDqKlA*KE$kiTWq9P/=H=q?@?GI?=5M=Dya<bCLLRTQ
+&/=6j I5EWHh>H^M5DbMuHlW+>\pQ&MhS#FJYpb?E^?ZFqTC/GAb\%<LBhTqnFbPqV$Eq1kc4+pmd#jZF?j@h>
+aW+?l cVHnaw8JDHp/$nYBRT%E6K^^YWZDtPpcSClmnCJJ4HBl4tCMk1KE$\D=?FKqZ5t1PHnB&+nAJZFETSB#
$YTL!& W<TS/yk!@lKc4nEHDepcn%HC9R^VHLP&ipFcaF%I9ILqX*i<t1<V&c5DFb9!8/9@<V*9RGNQ1Jc#Fl$n
#caEPb F:wYiX1ItuAeH6TRD>qhLPQhWE*&H?Jj9&V9X$>!:lw#Eb4&LmyEtZ8P!uYynuB5<>e99y+:$=VjpC:6
w4ke&j pT\&YDJthX*j^m$=GStl??HyZNMn<m4J4$Wn&pq\?M*TS/uV1yGCh1:kBXMq:>>Rau+wMTVSyPKECn<B
4>F:K1 hDuDjDNM!jRMlauB&+CK5XV/%5W@yLmYhXL+PT:<w%B^$DGd?6m9Wi<Vpa$>9CcGXm9mCJBV^e>By8/5
bH\HTP KQVadaq&VYI/^wuw<VIiGYLD&pbpPNtElMa+988#+mwq>T4b:\RGAZ9QK&=49JKcKhA^$^dpQNjHXl>b
daER4c y!w\eE1lcPj:Jn?LDeG$b?A$@KK\&tSQw146WEVPSh4<JCdluWeIA:RJ@>twPw<am@6ac%I19=wqD=CJ
$PJkA1 LG!5PIlFDE%J@tb#N1DX=\pdli=A8^16XpXJTINE8iiVPl:P5lNdh*ESKHCANdc<b8k8>q9dFJ=tImc*
AC@#ZT T%X%#T?9?&6jj!ayiXHC8Nde@EKEJG#V&VBmXc?8byMB<N%*WjBDqILw#k8mQh@1:$cCuPPY4Pd?lB1S
dL+:lP @n:95=Z9pa=1Hw9Hqk%P$%ly6!ih59J/%^1JY$85eCT^Z!laDe$XSCY$8atNJ+bt4h\Pwe4?WIc8cNq+
&L9JK& kBXm?G#KS%SwL6#uJc<AbwJ>?XVHP^G51PuTDuFFn@hXGQh^*eZJM@iij5$di$iV$*#ZE/wNlnP<$BRH
+J8qaV 8:u1QhA*!5>GlKTbX!$AmC*5!q8Mpn:YXi6$><LpDEkT%j#*S=qqZBA5tLwJZPjQi$Mq98DpN/k=^C4M
=L+MuM LZ=cQTt4@8#GykHe&pEpF:ep1Cp18A:/q#J?a8lCddXZStJ>IKS59S5lL!IEVQM4YdkpH&a^m@PET*mk
p+j\tP j1Qj#jI$GWt#>&+juVIVn?H9FL!HhaiP<GP:WSWGT9:&&P5ejWL9mh%6$ithHtmlGK$QcV=4mcZ9h@cS
\M4GF5 JKhpy4eCdD?@jw=$EGSm*YQ\?<T\+\iG:@JJ:Q\EpL9uGmVd/4+V1b!b6t&ecd*+=Q\Kp>QdtF<iXBL<
KSw&dD km!6L6B$d$Kbq9Y$b?B8c*PM<MXV?QGV5jFZY$5m>SIh>E$DZSddL\VhY+qdN=k/6B^@AKiqqLiTQX<@
RYqw/R %dj1XQCmKQ5%@uItMM*Sd8R?8>>/!?F?$\Djq/j9yy<<h/?QhL5#:e8>p6NPV6LTq9t6w/^>a+*m1IAX
nT^yP4 \Lnp:Y5jp!HZNSjmZX!aGI9%ZVw>%Eme?\eauaD>@P&l:RQ6#6uDuA@VQ#Vm\E^9I^yKi:bD1/i?&AL=
wI^Khn ApetX$aTtW%@5+$+KKIW5e$G=whWFFG4a1>Z5t*L+9QLkj5$yEHC*MeDwTlYBWFJeS*VQJkZt#99kJiM
Z4tR<T nEcT&Z156c*5Q8YMbIc<qY5*6qyB*4HaeI$Z^Q%ndE6^FZ#AD6/NJ!#GGkjeRb8Gj5cn%>8I<JFVkbR\
<!GRM= WY@XWQ1Ha>W^b%tY5yY8=9#ARRpHPXy#6@d/tiA=6d<@/H$WttW5YcR#^4C>lW<wT#QSZVa#t1j6cP:I
\1!w\C tlMR1mnE<t86Yq/N$XJ&NejY18ke#L<W^hDZFRP$@W#CXRAM>q\LHDpMy19FZy@jya#wWaX5ec#qb+5+
tD>/^$ C#Llme6dHWCKFiYJah6TcaK*KJ*>$Li\c&KhQyFFT>iGNJPFPMM&^a5&NpnqDLbh9ItIk*^mCwA>QGV^
A:w#SF WCE8?+>M:Hn$q8QE>@THc+uA+!RlcT:&Pj^:qKX!uGVYMS?IcKu^*PY1RThHBC9teab=&qAic\$G9&PC
IqYnIp aKk5q8FSD%XBVnY5<V/4\V+Qm$/:!&*y*<mnD1nBW#WlaElJ&%k=YikE!NJJR<RGjq:WPSZYTL/hnW6+
Y8$e@Z BIF<I!bYJ*jy8SjtiG!YI\@ACi!L<lmZNAYJHw@qDR*+qGKZ#iMc?A@<&pFVq&+m5P$YXw/wnTTLh8kh
uF>d#D q^VJkMQ<e&AB:NKCYbwB<HAHMMS+Q<FSEJLDd$F\qDQ^KTIknKl6AT<QqHM<4=d%!%lQHtN?4C=Jn&aA
&dw4ha 6C?y+EITMm/98Tt6GSYG=CT#wl<#ce<Fmj5>LPNRKTAy^8XuVCDk+FCV#HF5tEk15A\V4#Cq6dh$4:PY
nNP^nT ER$IX5D/SWS6CQKXA#4LR^mRdLGa*i&K18dQFSiHK?jctF1QbG&4+/lF<ILpTN/AZj5W:e9\Bm\HCdmW
tkJCDZ wy1W6m/XVeuT<@B/8tWLPk*l/@^wCe>uB+>I+Mnp^RWD4nhYQJdCi<<?4BGy%4e?WwDw*jKS6^mdkikF
&JdZ6q :!<aI>VW/WeM:SiQAdy*C&WQyKwTaA8@wytly9EQGh1Hw^Y%V91FFninZLP@XdLbHL9^I6/J+9H!$uTP
Q8QNKP KSJ+M6u9>:1G=MeLAp+>ZYBu$e:Sja8a/HG\NQ?!EnL!TIDlTIccT?D?8F/+=Y>R%VpNHt\GTI\5RZaD
StTG#= T^=j@YdpJy:J8D\A/Bt%5w=@#Ci=1TRTpSM=p1S*151LL+kP>Qqq9$eNQ8e:?uSuk+yPhpk#G9Q8?BNC
ZZ19/b JRKhI=!\eV@D@PiWQT$CIFaTNTw!Ekt1KV5F1=4pI!u5TmWFXY$ya8Ew+uCtY?\TG<5^CjcGnJ<wGA&$
?%#T>Z pjHpe1+4ERjk:mb=m^c6\qY65t*uZk88h4ZLuwuT^h@jJc%XZ9n$WEF6Jh$&BB>:aF%#\?FP@44cRD+/
Sij@h> WX*6nMk#&AVaZXaFtFkq=lQWeQW@HpRjh1jSRK@^h9?=EhD@%i1<j?+1>J>\jAWRj*b<BiA*Z1#=%*9X
YTcDTp Q>%hZ?G%@G8d8u@u%MC9e$5EdpD#ZJQMm8CH*aC?%5uq=:pJnd1Pl6?A=pXh+%BhpeS:Ba&<npdilL/8
&:ZSuR 68?KJN+@$<n461FjpeS:BR&@:6l<N/C9N^Z=?j<cjlP%Zd8VZAD&q&mi@?kY@hHM<Z?%4QmH<jR*6\kJ
Gl96Q4 9&w*>:>Q/j%HccAAC9p@bF%SE&wMw<V:q<yCTYTEDF%kYwG?AjR8kF=MdFAmu<e/GNeR^c=iDcX1!meY
@>#DY/ i&tLtwHm4aE4uNVLwXSj9*hYyXuCJ\mpBd8+M6G8E/u!RTXmbM5EAcLdl<=cJG=BR*J4KH#ubTFaw#:Z
iBFn1W HV4acI>ZpLFV<@jWHYAY@hJAWE&>wludL&F4Wd%BIPEJcmRa5<S=L5VYD:$M1CTQ&WE/6=8@CMam#B1Q
bS@#yF C4T#yR#GXuAuC%Emu=nwmVdiFEAPp*e86!#b/c^JSXQdkIK^Fm%wi+t6HcETDpLTe*#SIB<wKCaP9j%c
$SSTa? iSH/111/hba<yJVG<l%HCZW46eIT>qAZ5G:VCw5kDy=X<nA1mRRkb8KcR%Y98AkhSaKSMRK>Dq&tbH%:
ndqeyc lZk4IT+KF4j:>p:N1ARukm/lp8MY6!ZGp>SqSCETlB1V4SC$<$^\Q1Ybm8CI*!DL?PGdSQ18RZI$d%V?
6eFFwK aN%iY:n6jlN>PJVa1J+&#LG/tLdGmm6ELJC51ANWRF+8hnKLbwkc1ZGe8eY#9Q&^K$E+n$1A1$=^9nPX
+uy6Ba 5Jk/lI><j$iK?C&Q!tjP6WX!A<+H:^@L4ll@hDBKNh!DwpeCFh^cc!j%QRZ=Gqi*bB^KVKCkFbb=iG@K
VyV!kH =!N*w#VPaKmSmikahFyC<dq:#=%FXa>QLuw@JGiT/!6>AKtpPn!6&pZeET9$5J&ujCcmJ*b</jp1IjNH
EyK>^% PlcTm\:Gp%1G<C\d6w@Skn=6e%n$qIN6M=EQ9AVJj!FIF?IDH4A&jADc1Mc<ww=BN84ji$+G@Jw99mA=
m^edHR Vd=WF+^6Mjk1tIyj>VHTb\&/IKB@L^w1t%9b$hqKX1ujQMY4>CyRbmtlT$+\5#hwT8w!d4LZIN+ejWe<
Nd:q%u ZnTc&j4mkW!6IJXhd61yAYFlXjeQbmpjn*Eq6mun51w%X8eq$X%w*@qp:q8?dCwX?5XtkM:L^*94WXVI
<AQYe8 J?jVu\!I*:^!F!SYj%1CKb/nmciX&Y5+dpD61hD9?8dh+>%YXbuAQtA1ADVnpj%iM/m5GSe>RT^pCYCL
-A+NE= 000a382b8d300110333 Page 175 of binaries1.zip
n&61p^ Z1FKQb=a5MQ%h9l=ESAMnNRj\ueQ1#WL<K5cNh#p6iiT//CZ^X8NunkFLhZ&<h&BSV\c#HS^HQ4+>nGG
nj*H1y p%J=$?MBPVI?J1A:4W?kFGd6d=uJ%C1yGHb<i*F6>a61F@hJ6ZZp%9Cw%u5>NCqcniNAM&YlHI5j&cZF
WC:kQC c@k@TkG@>>G&5^1DyndL<n$VnY%j<5lH&&dAF1nV<!V5a!w?q@EHp!:u^\pehkyLpXFRL=jVPHPPePSK
nI<htl dXFyk:Shc@5jI>&pn?@aB@DYCmLEyDwa!aXhBYVEtLmqD^kLFLde!%$eMuT1:<SjaplFI/eFKLTPhHEi
eFBA&u ^TkSKE6Lb%jhJ%!Bq<=YTjaWWC%QBpZIM!/$4a5/aiPbtc$YhtV$l+Ji89JJdA>6TRe19&Z!jRm$bSBW
W8w^4\ dCRyI++IB>e#thY8FPVyb+&+Ky>TDGJ:4TpID@P9cj:Cqt54J^FpR9WLJI%+4?bRaLGwX@m4l5w8PFlF
>wQBTn SZQ+=d+8eLeSYdq\TK9k<1F*$=WaZw=JD>Yp:!*hJTC4iPJeea>BwYDda4JL##?e#V5@uV!WcqheA!MQ
WphH!y @=Yb>G%\Yd:bmbE%\6c+@A=Ye5RY@*liC:51tMFYEAyJ$Tkq^jJQ/I4e4L%Ri\?^a$*!R8:+S*Qlm/!q
wSpKTm FnREY>h5!u*qn#c5LbHN?hnV5mymB+X9JE$ZPk6w@IyLwHkZl1na+RI8bK!\5HlCQ!btc5R1#*!YVhim
FNN&@! &M:9Y$PZuV*qdiLj%AX\FR%ZJFi1*nPRVQi5T\u\Ra#L>R&H/SAc$XaK=k\6<D*iM$?I6p1Q<H=Xp5+u
mTnEW8 tN4aBIDjhhEN<F&eWqS8/M$&^W4Ncw^*@>YRFDA%=yFRTFe9@*ITm$\IENVq\K6u!QQ1@i%8C@n8GD@T
&XRAqV dT5VYAa=Hlij>p/qBG1T^4\F=?ZLdPbNb@b&R^+b9u9hHBFmNLl!=<:R4/bG^St>wNm:e#?j%aj4ncy=
pyl%bl *8iPPm:!4H#4MGN8*yYKZ/HcQlL=1XY4yuyHI18>WZXJcuQ4Q1ccXQn5T+1+p8tKT+XCniYN&WB9Nuwe
=tLcAk iA*ik4>!V#9%<ppZcmLQS9bWlV<*!8l>bMI4hLCEjp=q4aa4TeHa%>jaTlEKWRqNHPbD9BmYBW@Dl1Qy
6NHKSe AtZ$Pi\>LbPmR/qq&NalNdy+HTZ\yDtGkLmP$mJeZA\wIHtAcycAykLN<$%uwJne^5^HqyK6bKG%PZTl
HP@EB# k1jaR+dVqCHT54\T:@q:Aet/ayeMCN6yb$T\BLdRYqF1li94=5IkuYIj&a4Z8j1&hb^Vju619IYHk4&%
JC=K?X n!WNd<euAQN4yC@H^$5N%qIB!4YEE/?yM%bTP^#<Jt\HLiDju@Cmwk%Rmn<Qd*@hCeX*ieTn9Vl5lpMi
@m+4TP YF>Q#Kh9b*uZJ5+6SpkJCY>QdTYL?b^YDq/wewn/SLZah@R&MAA#%KNLP5cP@MhHd>H*XJu%M1bem6@m
aBTQR6 Bn<whpl6hiw#:duL=tb\QaQF56>:KCkj9SCw=Q&Gu*&$K%\yYaky\<N4W1c+4+e?FKP#jcZwDEJ6=1jY
w:?iCt knq+iM/TCqb\T5@T55VuYk9ZpSBKNnkFp+k<Y/m/I@@KWWCQKZ:M^$4$!!MJ>^MKKySDWY^C*aB^yS64
/8L<4! 9q/XNN$4VZMKK#4SCdiGn@tEY=<cN^+66u@IKGSm?>=l!?Jqq@*M+BpF1PV:T!uR$*WNG65<:dQ\mG^&
a6:!c5 +kd*YHwV^PQQ*%wt?YPFum66SBpjPGX?P^\eT/lhwH5jFyA6PaLG^&hk/ME+T^KwI5^T6YE!u<yMi&V<
mybyBp JJ^%Y@SJWN/QlDm5kBa&Xn5iYDBNVD&Y/uP\6PSLLI^>$aE+JS^Mi/=ptn/yqQ66u%dnZ8a+*c9F?&&F
NejcWV RSIQSiSZJE:wkm?$N6VAZ5j::jb9F>\FWa6RDF9&k^uS/nV86c#W/DF^nC#<^SK<IqGn1EXj4HX6CTSu
I^bFYq kAan:nd*4yGaJDpukRa?M<M:<=nPTQiAWCd#cEl8L@J+F^c6EGHWI@$l:/KdR#T?1FP&pKSmEQJ=IBi\
kuJLF= C?5DhEhHM6V&pJkd8/+GX^VcbX6LpW\aG#i8KL5R1iM/lHldpFS9#d8cRa$mk6BFSMaYa:nMeH>Lndci
yBEe*e kTw&uGK&CadK=Y=:V\HAEkk91mXcVbZi&lieB^nnaC\1tLe55%&BdWW#4i:Ki5tY4BdTPEIp<=%E*C\^
yBqu8\ yGQ/cwdmmR?\C1*#bHMew@59K>5hXYu/*QKXVY#T#B%RklnhpMLFcElD/EdJAm^FZ8aJ1d%+Ak@R&Edn
L8E^aq eE9p!EZTQ=KQ>IDIW>Y46u9C<JaEWdic>SA*5TwV8DihSBI6#/b\c\!my?!#n6h&GKqY9qQkHWQkWClh
8XyYFH XH$Q5WP66>c*!taRKJG*61<t8W*kBIG6=885h^89K46*nZnFH5k9%M=HBu1=k4=SBmpc4M&@IFRdX^VF
5I9A+Q 6aMn4YmMRkpeCM+wK$?j>b:1n$<BMKdWcAbYCek#=L:kKq&1T5deWq1WD*e?p&k@C%w@Y$a#B+^eTM!i
Ha^bRG H$TJeH5JF&CeJ&met\a!=t%@^X=p=W=mDaJ<1<+YQelnW!qmC+S@Z/*:whL!a:V>J=ajEP6$6SQueqDu
9d6?NB Wm**F6c#u#uRu<6#uC66P4iP6WjQid4knDm>#K8jME\LMjK=iwb&ZZFu$pMt?I=9+/1/k6dtI&ktGal^
Sw>b&T 8Zq$yBkdjPRQkYl*F?+HFJB1@E$>qA^/cC9>jn\5QiIh<e:LP@BLl#1e=FFIlL#%CM%6lwA4G>\n@4tN
SXXl4e ^9>X+?Gji*Le*HlA\9>5QCDlN#ai@4n6?j*B%R:EFh$?@tY5N/wG8/Ld^=@yc#&EK:y>ZEEn41Q=d$LD
QyETM@ 4>qqh$Y#n=9V!C8cjj!b=4*thTP9cQd^u/HlN/F=ic/lEZ?JS6/ASq+:e6/@SN>Ec<l4S<:*q?mdcP%9
X^ZTBn u?9X6MBjwZq8wnZENd*4pV\<j+t?mhaRQNjSmL>E*$S4<G9TA=E<9H?J9wuY+NiPuP<9$VjS&4W&HbJH
9<nRH? +C@l<D>6\lXA@8@49j+w^jwZy?&K8m\puPh@>:^Z%H9>\:V:?@Q!\1>/*m5eQMVj4p9@=?8>nuBMiTBl
/ch*d8 EQN<eqm*MjIP1Fj6KG^MqDMlck&Z6a@6MVGdJGDXJP6WXKM<?8<&*T&4Yq&PLy+lQA9qZMKTw+DeJq1<
bSIQwZ N^Itm:u&iMc\?65kF/#buB#YEkK<m$k8KmJEHkEi9*>jVy>D6*kQMG6Ea>=GaF$/IDB*pIWF68GiFp*^
e<5hCY V4PwP^Yw@\C9\X!Ac4p&Zd&1bMJ<t5INYS8Ya%hGHcFRKK=yHT%h4WNH>pPa9pTAtnAWP%^&Jk=FcenX
PjJKhA ZpK$ctN=@G%J^I+Z/>5#<1<\HWZXtkY*5SliZQyS>4RNwem<1wSRA6eVLNcPmI^k%w+TX\1GAd&&w&wY
XjS+jV mjq*RLHY6k=@^eRaN4C!1!wt@j/FdZLFep:a/!1^KPR*j$X&6W@Anp\6CtCH/PyW$&+>MZYL!yki6K+T
9%%W:A =A!XySZ6HZw9Jt@CAPAi&^\H1ttpVcJMJL:*^aDM*Xn:X4^GwHZ\:4KypF#J%y>kpFuECBCltQJJ:tmF
c5/nmi DcYa1NlLX5jyHmPkVC1:lT4NqiASqPHenwJCZBZ<QkF#A@tEk:HhL6jjSQnaF+c!tG8Tei?C?D9DK5!p
6RX?nH F\a1iRp?mCDRA:CJ<RIH^4F<n5Q=tTWJu$@!nWNi!$%+lwD:@dj:B9mXckeN!N+nG@#t*6N/eGMI54*=
eib5T< SmwF4kNT9GG:%D1YcmVh:A?8upyy:qetybXGqV?SeY855GBWAGwpFRQpGl%$^pell4DKd699%aCReWH!
1NFJLi IQY9YAbJ$5TJ<EN$l*\1C^>jm/1+>LV=W%u??6MJlMp=#k6pm%Lj?5T!8t@@+>1nN=Q<TI>I?kelaqu&
<AHqRp 5Qq>q9eJu/PlDnAqqN+ZKkWIq=jA!9SWPNP!>/^/w1t/4M/+DD*wTH#:c&TE$D1$wy>K<jH^kSK6A8eD
<!c%l^ y?1PkNel\YV/>Ay1EtdjQ\FQp%=d!qXQ<u?T:t4KHw/PIV6EHKwP*/hG?uK!5++tqE#&\8qXdu8G6Jc4
=EGN!9 MM=QuPc?RZJE&9dN/SNBK>9=TYn6e4#kL@GMc/XJG?bXI^q/H!wD:5mMXc\kBeH$#<#Hi%$cnkT6E/Lm
RKbtWt >bBt!kj#LVw9u$&j!py?1=65PlQNp*A1%M\HIPNY?G#Ew8#lVT*qWuJku<8+Z/e/kHKTM^+y9u1jYdW6
Alcpw= %WaIhhueML*jRCZFp%=y&>Pl/6CJj1y$BcVJb&<i#%>%p\w9+FX+lT<LY95TI>D<%ehk*lW*DP4=&&yY
NmMX$! Y\yW1e:SWT9ykdVB9ZCy8WjD8pn@*uW!mkRDY>KP:%=Y^GFy1Z&tNBHt<BwRqF>C@FTjL59?\DDpaalZ
lk5M6K +W5Tii6T/%=/<>b9WbQC#16V$:W#9kXV:KK1<d/\q!EJ=HP:9JGe9#m#$D$aCc=SAZ=D<&*Jl/M$54!&
\WX$pL RB6W!<#eqJ:ca@?18/B*!SeDK>SGZu==jC@#k#aDe6l<XmtckEVdh:G>$/S/e^iayBk1cjP%HiE?dQVT
aVYph6 WaXSbY=<dCZ#L!hhW*W9LCL6\PENNNcP?9MtFnT=N1\AB8n1kDpji<pEM+Alh=&eXZ1\Td>k5nMBG&cB
P^DP6# \6&eXQ\Y#4EWTaGWZ8jL+J6>*1+S4\E8*Z*NjM@5@5h$%=yV<qhtJDc^a*a8!tL9tcVal1p1DPY4YGdq
MA/&qD /tHQMnL*BNb8V&Lp%$HA4\^N\LuPI^4t#4VIAR9y/Ch%BV+HBSJc9y9jQFyaSNJyP4+u>=iFT<$^*@<k
l:lXjB Zp64GZ%cFjHkNk5yy1AwT@+DcelQHZF1E<#=MIX&6VC!QAd81NqEdA^Hdc$JZ9&1N/>wM/nNp%ukD<YW
\pu+mC w+QdXaqiyGj\A/QjMTc1A:Z#$?MuYRc!<PJPq#Z=T?6WL*E$N!8YM@TVh?Xi>9$8SQA\G#C<1I!=4@YR
q?6^*8 Tb&HH#S>YhJTSIG%!K4uGEY9#kS5\nM:<YtEyYwe94k6JmwHaFqqDbcA6++9c$I\P#TS=H+EXMiN#46#
ncJ1CE QF&MB$SL:FRSQETVbIMY<P$8hi*RVeGP>l*y*Mqij:ddl4Z<DAteimnRRM%ABjRJwWpY4YbV>^I%?9CC
/VyAwu &1SimZ*/J%bR1P=8p5K#/b49&DBn//Kn1HSi&b>ykcj^Mi!=YbD+4/t>iN6q<9Nepd=61i^5u?+\:8Ld
R!lKyM N/wXT%C@AN@XRq+AF@m:&Cmywc4X/P/BEtmFR%ICIwJjEKbu4P?hedbaNF*!L8@4ph>lX/aTnIGT$aBR
qaQhYi TE#1A$@yWF@S=GuWyAJelnZtcRa>t<q/:86CaB^j8YVbT*>S?%wW=%eN>9*L&46JW6MmRtb#WwIJQ$l5
kNJ\#: \4PkK?qE<cY$*%Z/XkWM5@VyKjY5w&#8!mkZMmc\wuuDYP>!F1Lu1NRWYBV+hRXTV9&P<kIPFMhX8aS6
D4yKQb lIDYZd=huIdI#cGRD>Am@:At#m$ncqqn6mhSMnAiEhp<55@bi*8yTw5nmu\5d^PbVBE$u:9:CK99b$6C
TkAmp+ XFI/l:6%YMAeYP/&+CZ#h%pmdS/&CbGQ*&t<<cI5c:S:Qh!ii:weN@lChdmX%uQy#eN9SHe>^hEJJHI@
91aHaI WM&H=P4*?JS^!XlaGV?B*M+a9HCZ\qW$D:@+&@e4y%uM5:K4\=Ww!&bDQ1u!qeNP%DmQH!%SVE#!wZhp
XWm!1P LiR<6NDpp6Q9MX*qFWFLd!dlb<A9W+IWM9#5#\^%=H\T/m=$&GTFi:\nyeEnCpX<H=kuu%E$^^bkA@hE
w+hMuL ?$cFc??9uNAwl&lK4PBaYtm*c5dYX4=S?jq$nFp5$?*8@dB<Pc&n=LqLX><9Mha#<<pT@Dc>Ya+>dw*8
-AKF:4 000bd06aa4100110333 Page 176 of binaries1.zip
CpD#uC G$e:Z5/L+*LADA%Fp^niKbm1:IV$pdBAS@#YW?YHuunIiQeC8YjyC1FCNF>G$18iX#>k#G4wmyljntYK
<:*bCK $q^+auYHa?mSlwQMlEM&WHBFqyZ?h6YSGJW#Y/Ca%+MLn>Rhlc?VlH:KHEJld%VjF$&/>e4^5/!<\H?Z
BpL8X: n*VhWPb+t8ld>t%&RhieYAuEjhu^$a*Lb6b%IE:ZpLu>u9hHwXabY#YIA@Yy+@M=k<eK*\>*1h^@iNuB
%F1@hC Xh^yjS*L8?n*Ju^G>e<N*b5#S*cZZ>?*&Q%J>=Byt9EVL//V%&hDhm$?@m*8lZK<tC\\&\B*pDJd>5GP
Bby+m: !NqK$Qq1qBhP4/w%C:C:#LQdXSuaulSHGiYA:kB^jYHItm+1G>61KGThCkqQ588mm#R9m^uhu!qwWlM%
JSb=b8 P5Ha\Aa#1X1cY/+#?Qa\<FWEGFW&bPF*Q>m=FJE=XLHP/?RGh8*?WkuZ<4QahdJweTk$bbQ*#XEt$B9S
lD68Hy <:BwKuWKYm4LQ5N:RBAniw5%DtG<tdpQ4H&@8HR4IM5$!!Fpu4</w#tKCY#<GYKMuw\!4yb4tC#IpI:#
:H#h<a 5embj+#H%LCcw4^1&eeDCXHRk6ie91#lGqT8&>*VmGAMwIu&:Tl8B^QV&XmJjGXPc6nG^wk=4ZN8i^N1
dnhFcN *l9w/6B6D?=PYWCnXWKYh*99VVm+j^l#uua&YtAtP<EjWRt!9$X9n4KD8aa:V>H$Fi/QFHTlN6De6?Qh
RcY:^% y\GHn<6l+N?qFXjuj6m$JGNI8GF/8tENIPTKaQ8PLpe/^jdBueu*eSbZPh%8:+kk:dlm?*RiX\=<iB>$
ZWM5>q \Db&aDqY89&>JyT<h:XQ9p^D84&9T$16$W=QB5jlLtij&<Htq=/B!EKT?p*V*:4w95dNjN%a4wPB\mP!
l$tVml XdeT?NliA>ce++HI%j/$hP684X6$QET1PAVubk/i%yaGM=ID=yb#jQu5YN!8/+8:M8EqXehQcZP5yd8a
4XJtAw $Dt>l!XFpZJBcm+&#QCed9pJE*wCA8M6J4\<#\uL\%Fty8MEAEawp@ReA5kELt1FlHXdleSE:pIjT9W>
M6WjB% ImmS1S8<M=V!WM:uM:5\V^E5mMciQ/htmn=l\d\myiKA$\dDhGK?%nuEkWNSJDLq:am+jHpE$pwI9*SC
SGb^D% DSRLn^pJ+#Ci/:9<SEKkblFKX$ICHHXWnE&pCdMkK5HSSLN=9YiS4&itK\!IXiPapYccYZWFhjG@b#V8
kd+AaF Dh>Y+uDiK4I>IGHLWJhj\M9uS:AF5jS?58t>CCRpG!$CSjy5eRWT5cJGClty&DhLXMV%8YWI?>@nnh!d
Te<8pR McPG%$:I+JS%TDHA#X$X<6t<HTl*bKd9djP\nX>t8YnA<mGwQylD#wmMNiXGj1TaYwF8Fa%qiAa?t\b@
DHtaY* JhLNDkRcRmc8@?ypbKRQp1Ijt=@wJZqZKF//phJHw&jEAX4A\!aC*GQX+Qlm:m\9?#$tEYPpC$G9d8A>
Bl5Sqn ltG!YtA6iR<bB8T9#NB1eLX6MJK9C%pGt56ZDH*wbeaH/$puC4cQa5LkeS8A5R$=FCTcZ/al^Cd8$eN^
ASPV:y XeG!:A%yYb*a18^k>/d18Mb<8nqJ/m&@&e9NT@@w!@u\/V9kCij>ki#*Rkk48w$cLuB5NTpLcw6SF#Yw
b68!ST wyS$8BY#?B6pjmn&jA9S<FP>%VDHlVJSTDB$D<+/NMFia/4+K!NwX$=^GN+91?VeN+:8q^*Hie:^S6P?
tER18H RSHHFS&6%$jn&MbPlyhZl!q?yiPKlCQ?P?:SS<L@1?+4L@LQ:m59+5d8K!@<K6MXCj?#PjE9R:^J&SeT
eHtjPX n4wBjX*bF^LPh\McJZCNGRZu@$8$\E%w=DZ$FYF$@^tc=\a$:#ZhubFZlNH>b&nEVil4S+:<T@SN6Ic<
!\?yIc :lNDwQ+TjSP6@i%<8y4t@$9$VdTG9Kb6ClIJ?$9$VdV&6^K&1&u+Z/J9wnZE6TNH@mZ/Jq1Dw//nWZ?J
c\$K69 9wuY+Ne6/CD=@^J>E/*^ZLi\\R9:T@SN6Hc>*@9QiR:wj+Q@X=YX@:B+@?:L<q@q>@::yIh@?LL<CMV@
dEmj%= qMyK5l\cN9IqRK$a6dwHqA4A1!4&VywZTn%mTT\:bM\maHYGG!@*>@SFS=wTBpk%L5CEtX<5/FikeT1E
Q1nK?: 9y=R5&:JqS:$>WPaNQDH<%KQG4i\m@Xkp!E#?N9wT^4>FQJH>RK%W5J1uBS&IiIBwY@eZu#><m#:KGpZ
kIt&?! VjN&KZMjD1=iRTPnS%j&pVFPm>bRTHTa*w@G&MB>\RiHV=RIWdh1$F^AXSAXIjCkZi<uyPICni\RE?&@
M?%E*I Dcw5h>#pJG!hnYFRaZCtyDGJpH:JkFq&?19Y*nau=c&^Pn>NlAP%QDPAW>Sky5$p<8KD^JKECQZDFYnY
&yb6ny XDAQB+^<MDyThpctR:S*JkRYiQE*h:hwnphMpwSCWY%YFTt&$t$?L?\m/NNY%ypVVk<pqE\apTjt6=^w
l4D<^9 4QH4FAVV?=JeAK6d5pjd*F6My/Sy:i>^ASA@eqJ/??1p1aC=uSZX6YLDlBJ%yh9mR\k%NJ1l\cVlQqNb
RJMKTm jVV1yenT$!i+H^KD:6E%tPTncV918+@L^9e5AwY$K!Wj<a6HC/<kkKhijRn6!mhKNlI%91bqdTh9hZq%
tmFYe< 1>?PWM=4:6+^G8F#R!Qi:pq%!QRkk8dGqWtnQ!kP*Y4D1lpm!%ENdHi^JBRTJe@KieqLltHH@!G/EcMW
ptVMPt 4Sq6Se?i*DZLAikwq?ECam4iw?+a>y$lG#?KWpAwNiR@^J%QYNXFD48X/?LGyDhSVkHm*JeFIah#V&Y/
N+CE$/ \QVY=MQ=RX&l&$jWT!T>6JpdD\E%Iw>lXnCQi&RDJ&Flw+*u^9wpEj4IP8lky4:a!+/X:Q^cJiVJ^nNd
+jH4B: j$u%J<M\?#pp+q6X>b&XQ6GT&:LnECXD9B1F5=#8T1R<*FVyPeiQL$uhu%yC*P#X<S5+1S/SF!J\FY=N
>#/SSZ NZTlb+DPV:u=i\/C6tpj$p1qZRSVST/FECcMYZE>nlj?&8R^/TVpJaI9<*S$YIu9$amHX6jbYNqd/w<h
V4PR?B E4QM&6*j*wc<b#*KWh8k4Ce$X>GeL16jjP>b@6d/>IHtWM4qaBd!*n$Jc\hRmXR4ZbPqJ64L#n5mYCa$
9n%H4+ mjK:RpdJ$:KT>\>Jj8ZGt6=Y\Y@5at\jwMdG4%Xm$T!=h\+KnQM!lbTaKFKi/wS4HN>SEW6C=DJn+=P/
kb1MZQ t65B*<+uc:T$1&N!l%y:jMRKk:aG>uEGEd&FBAdJV&l$^m4bFIKLwRVl\$?$iA@DejP/qePNh!XC!^yq
%WPMS5 JSu:986m%cBDVH+ELB1DwP#jw+4<lSwDF<GntXwc!uk<\QbJ#BWcP%DS?FJl>#mIyJZ4wh@56\#LH*Tc
Xl1iD^ ?CIK<X8+uT\GBSK%*#!6*kwZyhQjw$MG1weP5=aG!Z@KuR4%\T@5Fpa1$BVRmpTYTXYT<c>9^Eh88Y#V
/XG+cc dLHWwP?PDnCKF*<8DcS@BL%n#BK^=m4EVBHTSP95?MS9@pNuy#AB68SweKRStF6PA6>j5laa*nQ=e1dQ
h:eH!N h=1\Jh/B/LJ9Cw!@VPTwbJNmQEJ/RWA@1jBm5+KQT:1LinT>XmGS!+y&1<J*1tJQu&T4n^%6uE/hukY!
IuJJ/B 4QW6Py6:yk%@qPpp^$&JV>hJ4PC9^?pM#WFTB<?=VWl6dJG@hP=N#:Fd6S*4*&#T9LeM9jSMS$c9>hnR
jHb8cH kYatG#Ic$FCSIM99AalhRV@Y4^&cBk4l!^Yql/cl>#Lwuu>bYWSmVtRJNk1Qp<iZYFwGWLNKebTYTbKW
e@yiMe Yu<99t%c1At1b$#6tEk1Pc<aH1b$AB>dt1uuYIadEqbcn?n/1Yqw#i+!Cy1Ei*MyEFqBW>N44AlEJ*T/
^Zh>$& =KqV/k\WQi?^$SX!?hyN5L%<*@8W@*E@k+/bX:^wd+J51N=Iw1^::aA\*^#MClGucM$+Z1w4*WQ$T<Za
P?SC!N IkT&>yLZT!jLp5&qbAD#:AZjb*&&^PM!:yp9ty1*1iP\tE&$KK6$LLM!qTIa\dSd8/Y<:Fc#WtbK=XYe
%@SD6& $!u=HMP?9$IX=ZAZmqQ9#ZFcB@AJElmTe%Nb?:wE<8WqMJNKGj9L8%knNBG1Cd=NWI?5CFpBL4YGbb9$
NE*Z/n ^I>TTDD=8G/%>B\n1>mi46Qd=JHA%cHjm4jeRA>K^\QR*&tBT6cWNIhhAbNch$$1%/G/Q8PWGujjXlG*
uED4u6 qm55LwG#*dRV8b1+>h/4jeAYn8?6JY:9:4pIuJj<H1aca1/$&Gthn:Nw$#=nY%!WBV/m1QW/T8bjV5XP
ZQ4Xhc my6cFEN$/84+h6$h<&%QV86CnQS=yJlT%&1QA\PKDRFChGS?TSw<CZi<%9AWj\BjYW@<$lnMBd^MR:Yt
H8NNR! R@k?8**$XJYch!H5?&WE4Qa/+LS5=4**5!#S/=L61XM:BbtAkhiAy9PRnl4S>6J1p%*8&b!BRWkeRuLk
ZGkGLH QiM/eb:I:h@EH*ue#%w#5tl#MGK4DFyJ%T4DNAJnSeE8Ptj1yV9CknYtLIH*KI+9I&*4BLkWeXS<PyV&
8cXq&+ \qw@<YSe8JVN@u#h^^F6cEB@At4K<A:Vb54:WybacP9\c^Kt4<!TWZY569yMDJt8iN>hJquLt8XJiHQ+
<dq?8: F<?\^dE>lkBM!pc!ai+K^>LN%NaH6^m*jqGcuaa4Yw*wDM8/CTX%8m!j$6+GQlEB^%FTbb#F8NKtJ#$#
Ka199R Ejn?qu1By9Ly=<SAJh#M8*njPq?hW*a>%pk>tWIyJ^pt1c\9^d<jRW#=?9XXXbJp9!Y$Ku1\?Pp\\DtW
GE%FHc 6epeilGa!Be4<$cYj!^ZZVRwNldL+%YMCa&XA>*bJ+9PB>@Q<+^5y<%ZFq>i95cY?dbV5C$q@?y:=>bD
>M84!p <ijF:Et8iNKSbBTue$NV9kTQbXPuhL!b4Ma=Kk5T6ANh>Z<AGlQC/I?@k:Ej@>k1Bk%K9mMRp985GQ:^
X$*#TH FNep9Q46Y+1nXR5uy?ydpMj<=Gh!RpGw8E?Qt%XGmd=m=1e@FH1AT^uL59*MQid$=MM$!#i:m=4w@KGZ
8qIKY\ D%8Aw^Sj<>5t9w9t%6\9kDXLm$e:W54Ein%adZH6l*4bM$t8RtIq$GCA?KN?5npb/M8D:+jKt@K4>!BX
^k@bQ1 ZP:hdM5$5&MT?<A^EADDY4S4jc*jW5TtInC$:+R\a*1EbJK\/GRZ+=S?>6Tc+Kh!$<8%9tIGuc?4&!+R
4HD9ji /jNlw<4!Z?b?ntYd!EtJPcVbAe+K&kF:Z?E>Hm<BH+Ah%L/CNqmhPyNaFnFiV!6N<yQR5<Wb&klF?/&K
hD9&Aj K$p@+\XYKER+G<wTHN:1>Cu$/TTR8kXd+GW*=5ZqEN6wMdNnWYcZ*8?Db1!c%qa<?/I<hwwVF!MhbW?$
p+yNEt cL5i<pSqZpyBw+=>LKec+qHT1%TthXkWFmnib$hwEKHAbP6Ew/mK1tYXb?=ij5*bB\D$&d%QecLbVCic
a\wj$Y k>lykM9&QXmFddjm5q#eTQGl+^Fqc&c#t^Eat\hGaZI9Kj1dmaLG=p6JupS:=4B8d:NB\ZlX!9l=<a+a
EbG!m: Inb/!AmSTNb&TJZBjDYHq:ZZ\\l+^nbi&!4b^54?%9cl%WnB8p*GQyejkHk8i#\J*4&+6D9q*mXT?L+6
Yt%@&Q j*XP44LFa+QIC&QiI?c<+=lDIt>d:NB+<hB<>WD\*RlqC<Ah#<W/Q1kP#*kkS=IG#PVn%>84bq<kYTpc
ySF6%J 8yFY:=R*\t%#*?>aI>b&wp+Mu!*6AVFhIQ$FL9/y/8K1?+ciuRyW8XC<tMWHGGGDb!+e&V$RY6n=K<L%
QHK=%F wH5k$*\8lecYF#jmIeM>kylPAMtabiC==MwGe>emL8AibE9Q5>LSeQ5SG!91G<=u4DJZP:XD$d:hayw%
9RR^b6 DpIIwDKaa^KmENHd68pBt#nhKq^+ZYVhP&V<&@+\<SkA8I8nLhyd5XYq^&4=ihhV/Z*iCQ8!@AHB#$qJ
-AAldS 00020c2944500110333 Page 177 of binaries1.zip
+D>99$ P=D<!=&FVkq=%:H8iCj=nq$<AClF*G@Xc5j/kAP%XXGp=kn*m@nBN+Fni^Ikkh8:wikDR6lk$yWVKy>:
Pa?nSI %Pe>=u=PW#I9M%D%8tJBum9Gl\%>YZBi9*QQnlmVS#yQhj$=IJLc$:c6$R!6$!WKQ5D+=jcBc>Qem<B=
n491dM AjmNKp#9&\ycmpFiaRmW1#:uA\kLG\SJ$%8/MH!m4$aKV\SMe1Lc5bjLFpN<I?9EX4a:%4^<GBR+!6\p
V@a:m% 4QVB4L8lww5TPDk#B?8tBZMEkEVPNRY<P4?VlCDl*dDJHuj<A1!YT9jC>c!jW/FpI@HI>*/TPJL^V41e
y&4@K* DA^FHHT^mqtbd5?TB&w?TG^dB4&TbK^1W?TK=<bI\1m!GE4+IQWAKwqX4VTj%h6kj^1#%y<YKGEEee%#
acFD>9 e?\mLCYXX/uyu<y8&@+lu\mJCV^YK9!GRin%JZD51@Z1<tp8KRjhn$L^C=96u!jWdu$?lkj:*\<&JW58
%YdAij K=\IQ1m$=uLRkcjJF/6p^B$+bcCe\Qj$FAu!9pFn6wX=>SLt<&45#H8GLN!8bZY!mMRe?hWYiX\58d1Q
?p$cY1 VDqwB?la@5n^l:/Rn+ybu<MQRTXQ8Ibn/YX?p:L9#kJX/\%u9RSn#HbZjcAZ$%?9myW!R*a9n=GGQbbe
jLeLkD Dk>QmiReAnW8tP#q#QVhS<C\?1S56Ee/qZLKdM@C!bTSFpMj?VTBJy56e=Ph?hQdwq%G?Bb$TVIl8qby
y6Q^Ft p9dRV^XVy!ZBT1/>e<\y!mYmINq$*bH#^Fy!4qLb^YqXwG*&pt$^<BR=lcNAl@PJE?1knZVS6n4CV@/B
Zi<K6L 9:wN>NM*X+k&tW\\hmnJ8q$PIqdSK$tDENGKuPKcD8&b!LTMPe6buRiE^=j^d5ca4Bi^acA@Aj6cC8V6
5q^1i^ mY$JQAQtCm+:wB9YMhu>ZABDH1yH9MR!6qY+bQZ\XXA@G=5I<bT*ewY:qwnd?J1kNBHR1k/whV\w$^yX
VK!<#= wPDMIA?BXQRQ6ay68BdD<+*Hwa@#ySV&F!G*C$S:Dy#!q$XP?VBnlJZdP/ZYYtMP%XCJDdquBwlW=awk
$Y$NB9 nTBq8k9ke$DZE4u!AuPZ$hRhVmcYcwH*iVqX@N=l9h44iTLGudNt?/DJZSZNI6:nMX^A1%KF&tG?*GNk
u+hLb= nSM*nP?/\F9pQ?eh@6<5Z$d?e*nmqRa/pl>=laHPj$Z=M9@N!=j=4/^cSq/S^wn<X@@?Bld+FYtMj/c9
=dT9\4 6h?9TGQ<M*&6BZ=FG8N@k4+mnjEK?nw4?Iw$^9<MDd<B#Z96!BF@mWdilPc=^y/:Iw#^Q$QjSG9Ic>1Y
MpP$n% I%F<j+t?mhcR%+=e+K@RjDjS&uZ6&yF<QH?J9wuYENh$:$H!Ij+TjSP6\c>VKl@9Z/J9wnZ+hW5ijH^@
Bw@@Nk md/J%8DZYj><Au?F=4?J%1+*5ju@a*E^<6<Ye/<*5j?wJ@/dme*Le=YJ#Z>XeVE@/u><=/Dbn4CCXk%G
ajMn:$ ed^/a\&T^\aAYdNP#JyFc!=1CEM?bXcJQuhcRQF:<mt*^&<y%FeD<JH=$eyW:>iJAq4<Q89eAaeRj^<Y
:w8$cN 66MQDAmFLpYX?@D5mIdp1:CM8im9npakqAwYVjQbTw<Vep8&peA<wH?4H8Zdnp+@!wc6=TwA/!lyZ>/d
&JR4T* Wau&GyEh!wEt5L>CGBTPcY$/AnMJe+amCDQ9*Abk^^%@RPG*SQ%wb=u$K!tZZjH%D?H<u4MALMM\Z^KZ
8MM5&& :!aEm+iVw4M=@NTGcMMW=C>w1<Z1?dpAtLLtI\1kQ58&\cHF^YcktPk+5SI>P<QdT6eT9VbJ?KX55=Rb
i@L$kT 6TRXAN9Ai4a#ZH>^MyTd9+SPayu/A/pTQeFQIjCpbD@QBH9cCHR$aFH>aY?@l86e<%KNLdZ\KYYwlC1J
:jP#8H 6jH=ANHFFt?*A$eQkuNwlamTP!yR@RF!TWIBmmAI/8YLGl!#E6EmyTL4nBp<DaC1%h@qG84LqS\bpWR>
dlNX== 9W5Mc+n1uw1J9?$L4R@5jpQPW>Fu\^PJ1VVGHKF=kS/jm=a>+PbF8SF1X/QNKN<P1$J:J^yQ5cJJYe<E
?iC:la 9VZKh<D/4HyDW6u\tEGQE%jqI:<h+=BhnnP4/pupB^GqD>9juF8?*l%*p@RY@?wPWmWWIBqNuFJ!X@tk
dq5CT4 biIC!pjbpAjVbtu4AyX&?$a5Pm4H+*yT><atQpNndJ5N!SMJKY4!R%RVpE+ZcLJH>jic@WcneTa/Fp6E
\^aE88 T&=L8Gnh1?h^Y>655!5*jCGmX4=Y>La/!1Du>t#4mZ#n+iM5!eaw%h9nLeHa>%\y8MSEQ*XGiaV<WNRn
c>hAPh J9u&i18i<5VD@IVn\INZ/D\TiTS+Xm<CQq6>@#/pjMMR@1CyS1%^*Je5wLMY$wi?w?/u=pLNHH/1lJ=!
<m&^iy EwIjlnm?8AWPIh4Nb\&LhP>qHESR9*wM\L49A:&FEFacK:6:L/LNy^aFjA@A4lpW4N&bXEee9nRndlnn
:pa+6V q<LZpHD>6WCAyVjCcSj5pT/F?wZjti%XwL9KJk:5%GAuhCmn&Ew41Q6MP5ikHbp#S6e5a1LE:1WWRpuW
QlHVV9 aqGTchCb4MTl$b!/1tm4?Tw&YFtiyI8*5=WKc^5SKTA9#w<mIAb^A+k<8wS$9Na%/u=KtRR:CiBMGG1a
ytuJ5b PHPcMJw^<WaMVZwl@Y\:pN%8SKBW5j#uwL91aui!!@#>BTYG^I/ai!@%llKaiR1HpPWMF#ZcJ!^e%pq9
bq8du/ m*9&\=N4YKZ5BN^VWYEVGjc1MTMwMWt?QZw>?45B:h%6$l@5B$\J+:lL6^uV$5:8cE:alBeiC/M$%P>w
8*&d/Y IhIN\d8W$58u+HFJ?wRJ#p^Jm+m5%W<hDp/mJd%%R#&1CAd=RhH^<lTPMZ\VP*mS41N5!nj/?%TmuE=B
h^bk=1 9X^R/ZAqWSdRPp%n</4YSiS!yG?bmDW#ul?qBHR?wL9PZEnDWmbcwh$jd@=F+pS4uAylQ/PXqK4w=pmZ
CiS6c1 A9R&ukt$tS^hRKBT\$IRiVyX&B=C%YX4bhj49>IyhVlGV^pReP6Ip?1XL\ELk:nditHCeDKZFYYR4KL>
Aa9lwN :Ak>4!WBm/ADktDC4nd+LWyXmTXX1VaMZa<i/<J#WFeB+w!1QSXl*6wRbK?wbW6+I?5jBJZaASTQcXNJ
>tuwQ+ pRu!BA@V9PYKMDCcQRwKA^T>WNZ/TS&a4P?G1LX=M+M6SL>K4TaNId1V+=^l#PmWYIjy*1D%@&Q94<Pm
?Rajm/ @Bi%d^mJwYdIATtX:lktKJYeIRealpcp8%6ESL1:ScY:Y$XE846FScT:RWV$>//%>q4*nmZ:+dh>*9ji
w9@hjR >*:9@\aPQq^j=nll+D^PQqihhqCK1=6&iK>RW>P4>hI&RDh61cB+:XCYAFnR>8*R6B#D%D#RI5>FPjdh
%Kyw<n j5i68Z%VaRJla$&9$EkX@ZTlPF#16:MKmlw*CAGl6CEXT4!hleLP/TD9h/!Nd=SwkRaEBNK$la*YpI/K
\NEu&t =P18=9G!Pt4Z=+P*BadWqNZ1J#n6BkwVwAphlW1BE!1Q8N%Y4hb:B$4dKI6J$q^#EVI/99qJ*mK9i!5h
?@C\1^ PDQp5>kd\K>heyI@Z%e&p*M:4l1RSjZ6c>kI*p*TKVq8X@DpEBB<LmhMSa/u@i*ik@^Sy/TR4>i$hdD=
nIluEu 89KA=N$jj1u%HZR<BIRAK:i=yke&E<bhY@^66ihDlHbSu+CSAkJ>@Pq/u+*NB>qAXMn&EBk%6\#!bR@H
Qe?PTj CL+T>F9\61\^JAe5CuCb+N=G64?4FiX:Yi*W^J4LcWDW&C\4hy?#5Nd&Hbd&J@VdDM:G^?auG<E9l#aK
CA1jmZ 1QnqjASt#WW?MtiWJ?W@XiZh9Qp$Nb4G#DaE^K?hM!m&FJVA6B\uZ%kXbLYV1$tHGj!Ypn4wkW*@1CkA
KX#yyq ieu^acmp$>S$IB=TpM&aES>$y$1qw*lmH6BeeucpZAa5JXhC%84EM=k%9\/ZF\LL?id8bZ=aMW4Vi1he
L4:H&P QZ=DlHWhCdj<ATu=R+8d=Fd11+jCK#kd%hCqY#%6w>BJ<VZew645LIkEhK#:C:XMHb/X<uhZ\iT#1jS?
K&+:64 95Kh>>H/iG8W8uJT<^WbdZXiY18cT$18n4H&8p$/W+!5Lc*K5iKj=X>+N6k*BpX*SePHLp#q>C#HC&pt
pN<i<# Y@CIF4iHGJ=+8XTX>p8c44@Pd8CLeKptYQFQiwq+#p<<h:6jKE^ViTb\?PmFt@qQk!>>e4CAV^bH::QV
/XFJn< %!kkPwpEl5Jye!&=AlKyuBa9n#teKuXa9XH&B=TlhMe=cFFXt=CSHHht#KKG\j5^VeShe+cH$4j?aFq?
<^BQcE @DdVYeS95uDT8%N5=$k^DB%wj+P:j%aw6N/Q%MdZHtp#?PNS?a@VX:ME!e+6iBG=njJt#VV&Ay6dNRh?
6p@eid !9S!9At:Zb/lmcXT::KET*I=*uD%nFm<e#4pI:Q4*%^kuTpHA&w%>&==dqtuH#YMq\&d$w*k?n?nm5/>
wmpldR d>Q+&yNV9jA5kcE/Q/*LA><bp=cpNnBJFQuH9L!D\eVy=Kjt/kS&CWq1:dEH<Ab4h*8KtCbi!acAm!4:
w?EB/a XFC6GTF/TXB=4^PyL5n584Vi*b%1n4N\6K4ePLT>KDm+8Cjy*Nq>LKS&\qX:$H/w9:AR#4$ML<VJ6<4e
IYEDn* B*RZCEt<eBFeZKL>wTIT9buJV=J9S54\NakpuE$5hXtiwKne6k^CWQ4^Z8illwuXl@^tQ#cwHi6+9D$@
PLiKX^ Pb1&A9YY1KVi8I!8i9PRp/T<jEuMjVXTuh9RVckcWpA:X54:IL@:DN@BP&d<LDI^!#u!S+kPd!u?a<:t
Cet#5& *9dXTEDpjSItKQ+bKH98Gila4*PCLQa/Rhq+ujyb!dDBTT>9:/m@Z^+My#i+Fy$y*Ie=#%+9Y*AS5MtY
quGk5F ^&MHBI?u=tpTlY=d>t>SCYbcdFdHAtq6kuX?XkZ?*LH/lJu:+Z!?$55dGdlc8N&@&k%J+5$XnMmI&uyB
Va!Nq6 BMAh=<u+GHPi8%GiMKc*YVt6!y^iP^TPeyV%!nekbCN=bKF:ZVH#cW$lRZ/nykXcnB8>yVBu8NJ>n#lD
9!Vj:h X<H^Byu@n1D*FpGk\Ewp!nXeYIHVuGBZN*8iVH&Caqh4dmR^Mi\uYjlbw#ua96#:SdmbwRQVjhLA/1:S
iqHw?Z 1PleG$X$WtEZ$Xa=i:BieLFj4i4iDeW+cw:w1pQ=Ly^=X?FbHT+I1JdVK>^H$I$@8Lmq6Bky/Iw&Nte?
=PeN6t 5YK=Lwe6QBV^4ZWI6XHiZ9<a/mCBh9PQAQdd%W\K8%tFpFHB8$d%m6l8dVbX1u5<my%G&<SGFPWTWGYE
HNi&\q nw5F%\V\eC9\YCl8J^ddADFp61pA8V6Cmj*B4mpepPVH1G+*nk/8dwcb<Fp#XGl6l##5ABu4%AmLH@XY
+K&ClQ Yn?#m<>TTJ$Zmy<yc9t\E\mCWe&^AWHM<!j1&*<R$aMYa&n*4jl::RXeW6WPe\Tld#uYbu?/BSHYi1t6
Q<Pppu >ch8*?juqy?F%ujljMC%:X=LpnVPE?iIScQS9wE4Q>eGMiH?c$LecPkRR#D&dLX!hcK$&RR=IX\XHGBC
Cd$hKJ A$ymu#:mnTH@1Y\Tn=ZhlAYPGmRaQTy!F^iPX56j6+=$ktRQ9\YAtG$G9*HqQntRkP$wG+eSFc/1cY!&
>PBlB? #%4QjnkWP?&jj6+?SlN1#WJNBXy+V$6\t>ch>XP<MZPhYqMZ$4a&*B&QpBW4F6JZC!We+JdYIA^nE&66
GF#1<G @&w6#BLcAwq<hb@!jIH4NYF5c4yJi>utS@VGjh\qkG@&utl^P:\*NV#^E!9XC%mqN>A^jPawBE=>PFh*
W5J++= Yt4n>+B4l4^tM4n86jDS&#6EN/C&J:V:!^4M+>@^J#nL8Ij^6+HbB$JHeuLpJ@C/5:eFlqnphMjk^*=m
IMA+?l &5H\WFBwwteIl!lyeM9&jI45?V9t&b=6+ECJWWju&j96+AV:m?/8?J:6:J+Ni>+T+H:++ydN8Vu:BHbH
-ASNKD 0002438a32600110333 Page 178 of binaries1.zip
\qJ\<V %6$Bcb^@>6LtAeXpGi$+KYXp+e:\RnQB#>1CVLLaV#KwLDEL?Tq?\jZ5Faa1yMN!e&IlBLT\8pZn:eh=
Q4n?Pd :Z1!Fa!Nj:P*n1GQAdRd?RDYYJ#eB9KAup%\#*B?RK<!E=uMA56R:P6KcwnZeA&dLK%6^/KjF/8+5JV^
wXW$6K y8\Pw+l!9&KVShLA#\t+Bj6+4IWR5mLJb<WbZXd?#T8hRD+@aVX^aGkWIj6dVISLLMea1d<>JHj?6hyu
jdYTZQ =NThXe5yE#ADwI6lBX/iF<4A6mtb::t>mH<Mm?nCtu#WpSMunG+5Ry1WH<h8SW#dD<t1y\#uSCj8S>RR
6*RaX$ nVc1<DKwFGycl@8n/pkMk5T6SQ#thMKaFICb=q/cG>#e#E+!kZG$G#/B%bKwudNBHTwQutCp=iBk^Rm6
@qCQ?H tSwl=I$D:B6EEimNW\#CVNC/?I58$#F4e5=RLJn&T?b5pYF4K\hC*?CZX5nI+\Cbb><9Y#8i9qa4E?Q9
qLDI9i :4uYRT^Jhp8ZVhY5<^8t^?kEb<E&DmeqYhGT<\qi5a\:q:DHTIc#jTpb$cLbp6lL?=?/%i48N9!/XaK6
:ehklF !l>l^MH*Rb8jTdCYI+W8I4S?:Kdt8tIH9D$Ea%TB%u?IVca<mIqluW1&TaS5lC8\\JKIBnWiJTet%Key
LPmp%i nq5RWL^Ree?XyW:%HciSB>c:WcTHc=b*l8&LtF%YhI9>>%!Nm%&!Guj@!%516ld8@:ct?M6H@@$B+8>H
KL=w=M E$d<@i:h\kkS$d<@?Q9@QA8L@H%AJ!#!n=9ACa9<+*=RI8L@//=QRuLPuu?6%mH@Y4NDSeS@XXV<F?6=
Jyqe6a lQA@%@MI+T9Z<@>wVj/yn@qFnTX&=bL:F=4LQ$PLZaYGZFbEmj<P@R9J=V@VmM6KV*Hl*/KlX/E9K#*F
d4p>PN ad>F\/>AZ:wT@+YC=5@RX<ucyT6^ehHjw1?T6d<1X*=Nm@<GnaBeJY8Z4eRSEPHjw1?TNSn$Ml4&Y@SX
Ww&#u9 5kc>bC&NkCB?m:=K%1CZTGRRENHjw1?TNTkWeRp6@n8$<FY!htp>n^D?y*yi:A4%9Nm@&bkn@9=m@l<?
m1*BA8 :/@1iSGE<Q@htF>%a!+>c<FDG>*R\TIn6!A?jCH$#6m@*\6MJPS9hREM5n?jBLG=u%?A&J/hM^Dk=buS
<Ze5#! 9kPbL%/R^RW#V<n8BP&CTRPTWaT!Z>+e$4+#L=MEk!B/GCnKuM@8R^Py:F@F8NS>VKHlhGaJSZ$+ht?q
S?l=d8 B8<^$AFI=caJaIFMaq*\QD%NkL^1uR8BwK&DW^T:cdWhE&>@jDG4eGtyFEhhZK$9I\Fqwm>>^$nTB1Gp
q4nSIJ B6!k6PEw6+Pw*9T=1mkkKSmeJWeinGcyN$*cH%PuNFidGRXV!#Nkel#RQPPP9qB/hWi#^/41hYeJpk&L
EJ&M%6 iY1VYmQ^b8hnqNV:E&wXjAy*?#ZAZ&/H%99jI=X1p^:TD\N:wER$Wka@/KtQHtQPNh$@JXD4=PV@wVT8
Y#@IcW HtY5y?==WX=a$Q<h#FR/\hT@4\yT=SLS8ba@P#8SbCu1chkY:#RVp8a:C+ijk8+1!!I/>5XnRde*Hu@?
Z9mXFB iujy+hA45NGbc5y=thn>kIdS5T>+n66ka=KKIHwW6eti@qCTP^Wa1D/lIYFKV:*l^ZFNipi@kX:VNC4t
dkC%b# iJ+!P6R>&NJpciNE>/qF+!!aq\A4b4JltMh+akaTY=+XqSMK6^elDbA?ItN4R&4S6qP<ENhi#4HH#M+K
MD!@lA mNVFhXHCqew*Sp<CBRpkn@uKa!kciE8HEl^%1b\bJlH8?6:K^mE6LQW5\C&wV+PC6nuul&Iy>i^^tEle
cWq#HL #Jj?mbVW8wy=QTayA5SBcEm8#aktkyPARW9D@p9GBPw9V*JK+G!w>&i6Wdt$i@hMV5XGMYLAm8ku4Yc?
huGYZX VDRmRAH1Ja88N+wcT#MjSK%?cL8I/wA%y+#!tpPESh*Z*8ZWj!EEmBB6jYn+&yQ&YN1RkIE>SEA/a9@d
L^u<>^ LiieMjtMt=H>IiQI+a*ByY9aEbMjZEuHb+Quba:pKj15we^j>R^eCPKCb>/ctEZE%&TDYG4\R>*QRXPG
cB*>Bw >B+5<dMXawC=BYqldSjX>w!9VlE9<1R\\=VekNSedR&aelAFDjq6\ua:QBjQ\N/u%dX$X8?9=+Q>+\^F
t\WJC9 yaI4N&:I/iuHw1J^W=m*DA+j!jD?1JGi4u%@DWu4X/\lmamjAGh/C<4dG4:PM+jew=T>4:Kmh=c?aKW?
/A@k=M R*$BIJnH\jWQBeiVDlNyqK>#FM?uAV*elR/Yn!ZMb/6aeLkBuDHcKVk&yHIWD%&Bn99qFJ%dC*aP68wk
:I?h1b HnE6F8:SRAHpIMF^X6=?hM\nI$T9Q=m%Z9E4Jb\YeXk<&wa9kDiZWJ#pkunIkyNBk9FHAm4ccTGu>h>w
=Ntj4b TaeC>\JEbFcD6SJp:k1XlWAq\l4dVX&#bMtLj:\q>tcTWXtF&#c$KDV+:5h@1QBy:cYVl=/@9&<@tw1V
S9n^=A Vh9/TubFbdQ5idn&/SBS1c<SuSXbqe!^9H+i@5*9w$?LcN49RQwH?yRhp<pjL>!iGP<D=iW>5Z:^M\nH
%JYFbl !ay6P+mkh1mmGdICtw*uJ4al8bESql^ERd&WZJNB*qGQ<cQRuHtRQY?PWwS?Yu\Ywl1k^JWq*\:WF@<l
F<R9uh tSR@M?tCtd8i#JLTh%mA/%?kFTCdZ4S?Dc<IJ>&@6PJi!Y1PHu@BC6ZI4EhJah61ZS1?:9X\:llXEyEZ
64QABd ak6^!<wtHJ$HRuw<hH?aj>pt5qF4=q^c*:dy6bVBqQk%J><\^wYHTwRim88^h+qcPHLjVb#HhNN*Q4M/
t:CI$^ Q$5nD/^yY?M9b4dE<+?RbT\*?ZKHcd#Nen%Hi&CAPbmiiqi9@<AYm6Tl5+GQP&w4ld:>bmqt>Ka?KVd+
yAL1i? l*I/m?N>C/B>/?TpeyV!MS/mycp8$E:mtS1>@ah9XTWPBA1MiDj+&S<IHuq!l9APd^hp!*uDC9#K98ZJ
HQL%iR GR%ct5L8P\$X6FwJEHAwcS##cLnM:*\l<wk?\T@Nml\P85Z1RldVL55SBVQPS+Z\D9k+LwSG^?u!$81J
Nai=mj aiK:XuR6lpmI#WN#4RyPG*BmyAYeh?V:ST!?^Gc5$GTuLN&W+?LQ*eJ>aDlyNVjhW%\X:>QYR?Tnt+Yu
WjH\q@ +dVXcR*dcJXwdNBlbGwX/cCZA4:e%FtIRc4hT:J$H81PHtjdilp?VAa^:?G+VmGu@Dkl/daa??^ul8iY
c8n94^ yVa*edXJZu&?X?jpwm^Ka4GcZ$NycPPBp\%4uK$6jj>aW5P$ME/*@LdQ<6&hc44I6l/dk$C5QGtNnuD6
$ERkMm 18FdKhcG%X1Bu%Tjb=pbLBqekGKKw6qq\qbSXupJPw@#yI:i^%EHp&cBqQcpjV:YtnEbBi!uq=a&%8C%
c&i9^N bbR%VDXQ*:tnF+W*iihD=T%4!&Ktw&QA$MeDm*Qn+qm@XNL\q#Y8#i*uZ^!k$EMEEj=M&Q*+dyHt8^4>
WP9@ZY Ri/=5%ZE?>8#uip*P*1cNY:J=b:Xb8\R%9y^EKqGBw\=S*kZ+e\#/u$=:AQXuNY8GWTZ%Q\AYI?KhuY5
4WEIdc NB6Su1F$BeBeHT6F=b%PhR@iaBZ8K*XkXZM>caY<EXc+wZkpJNqQCTF&Q+G9G*+!%/Y%wDbD+$cnX^<d
qRiycK M>&RZ*>GF%FSSl&%F@K&C*&eq&up>@BHX9!pA9!^?AMuX&D=D>8KWi99wct:Vd^pdh>#Wp&w98/y$i\<
W41#Xi mJ&<KTFp/lwuJbu@A&>BqT^C=k+Z:8yH%b8qaZ1!*H$m*yGLRcQ?D=#%:CQeP4YdH?NFa:YPPH%E1\>V
R%+/Xn MN^FN4J>l%%e&wj%d/h6c&dL/i:amJM&/Mm@T?NQl9E>bN5/%a$dSnlyBh<XL@qYibJRiYKy?EIww%dd
k9a*iK ci>iGMT?I&R&b$^Z9GT\wN\T@=%G:#Nc$#\yn#cFeBea&ZF*c<^\&a<ZLR\b*@K>Ba>RFMn?qqHtY5qi
8y:*kR PlL@#EJHwB>b:68a+LwS\d8+Bwd=ml5Y5+HhHnKd9mPd@bLb1S1E#<6SSAR+<y+quIBPhKI%+Gi?*ccc
F=WQFB h+Kcd\8GNd>W#dA!9N#p$ESkEdR\ZBMhKpYEZ$Y\4<e4?^a6hY*piLQ1\qCR?dmC>p^P#+#IKVP5?4Va
F%lBB/ ^5KC/Vtp?GRpw=kZcw5yQ8Q5Q!6&Y?L#J?Dc:FC@V#LWGL9i@m%Q/*Tl@i6/FX+a9<9?<<Z+*enCPlJB
4\ee&# 6JSLJ$JRW4uw<A5cPNS:DF%N*HQCqi+N>/#mhKuanT:#YiDuNkWMcn56IwkmZbDd$<\jQ>m!?m8cVG>Z
pe\S6i Q\+L@d\1l8#L+NqPjbq@e>#@E+$NK\Gq\ie16\<HVHPKN9P8LLSlQyaX!cmau<dp%ZEw5TQyn@BY1*Ck
CB5jeR B!B&@RMuXaaXdwcFqySJ4>w!<$iLd@RF\bq<*BmLL\VSh@:AG:1&h:1&Y#/qFnwXG/%5\R4cMSIJ^@:w
tt#V:# ayaibbkWHmNYF!cP8Bt&5mmLb\QHYTYL!<k$G&+iLX=c^Z&AcS!\HCK44q!J:&NSM95KBX^RnN$WemaL
mEA5q+ TWdkhLBWu:qltV%qjS<HL<CXaY!6<@enH4CT^:Hdw*8bX=>YPn&EM5QSSEQS!89EVJ++C+?&FF<Luq1W
#iiCQ5 6\TT!RKCteuI^>Qm=m=M?u@K%/a:&KtSMKV=L#Rk=>:aB9@a/8NXLA^ILI&\bQ<cVKdHQA*MQ1^Q/J$p
@^d#iW i*DL^Y^!NibGpJmj+:B5D>t4mN\NhXHCCmi!?MmjR@/hAtEAm@k9B#<qYjZ1B$8n!mMZkJpQK5X/BuPE
K$jTZL MhCw:I>VC=5m:QSk49am9HXR//A>kT+5$Yy$WK55m46Qp:54JNAyd$FQACee^N1*uYESdVXE1ujSt/4H
&Y/P<n RShhJ?nk?pYWj@KPt@iZGM\SS:>FQ6wh/HAPKReK=T+KkVn!FDk&wS<lMQ:8@JZRb8Pp:Q*PjDlFPYll
A^/S\a 6#%Yq>NqBMVXck?yZcPIaSyCEWMZ@/mlBlS@F?#u@<wn9^5</+/*Rak/u/tRInw+ISaIQ/KtiDa5SL#9
H^\<Lj Z?aEZiw+upcZY1!iATJu#!wYX!*8QC@4h6cWDSDkZqFy?k1Zj4C4IqPJ1imK:ktqRyDjPTEWwE+WAjLI
%HtI#S T^E46^jSI@q+WJ%betDMC8V<lajcYBXt>Xnuy%14i6*C#+pXkm*<6V:\P9Z?*cSnYb#Ih@Ewt8+!Ya@K
j?mcnI CN9kX$EHK9\/6w/YWmQQJiG+:&K<b<bIDt6>y9CYn/RLZctpEZW&VaG?w*ZKGy!$mG*^Y*!m6=!8W?L^
W6%N@+ T&^n6+QtEAW/kHDtHlWi:nGVDB5u@1nw&pT6>!Z1Cn^YRK9nFHQJd$VSeGy^t8CdAXV+>R6#!?B>YW/>
$q4i\@ HTK*E$ki>$blR+<L*Nyce>eS5T#FR6paTAM%:F65&E9>$CFy=m!u&qqFMeIj^/5+JRVZDRi/=K81uPTQ
=^n#\K :un+\18q$Wb>C>*&w?H9S\P*TVdqHLlhdZHllMq\WpN>YLpp:$&jhTe%+q/japq6n!d#dA&X+%y@Y##G
/GhMdi RdGR5llnBRl:j/@Q\w6:pi%TiWb?wJ5SLmYpQR\h^VtauYlQ/lP$G:M$t\#>B95Jb\hJGETjc$GQ8bB+
Y$%JN6 *TyGQl?^WAYm+Y!Ka499mZ%wkWdJ1\G4mlEEjyu5&Y?e>QIAe6c6tM\+4ElI+R!TT$TJl:cV4DVjJI>=
<14jWM @pLE%T#5FBb/nNnYR!!ie/Sa!m/nmZybLQLPXPPST/kyymAQF6^j1p<R\9>6bNMIajl@5R/GR@/=DwcJ
M\P=ad Z:pP@96y@?u9@*<8Zj=Sp9<@F:1IZ:la@\\6ilZ/pwIQ<R5Z/=?l^c>CZ:KJSEAl9$WLZ+FGZFd\RcG@
JDw:Cn SeP8Rq>YhEHl9$XjJY8ZPcaSWJHjw1?TNjlq^TbW:Ljw1&RNh5t&H\GD@Bb>qc#BLm8!ahDjw1?TNimq
-A$@>t 000d7eead7200110333 Page 179 of binaries1.zip
Pp6=@4 J+j@Fu&X4EE9QduId>FZ!h4qqi!@h?6k@lZ?#!4b@#YT@q5qK\L:STZ:d/$:@/8TFaiL@5>jVKj@u:&a
Y5mEH% yt4@&&KcXcA6<V5qAS+V5n$&THFiXGCRn*cmt<>huL=PKA<5RSaEdGAP?i6EPpCyZb8y5iLMkTGMZCKc
9@:WZS q!l?%8!wa#\J@Fdh4ShLD\B1!XEPcJqkSyF6%SwKwS=*wSIcDu\1KuCHRYa\WEbF4BP4m1<nAT@96ccJ
h*&d55 uwI4k5jKyY*cB&Re::#XQy+A1jECMV*m&8M469yD@AIc<9Xq<bndAu\4W5bIlD8&1\/88AAiu&DCmMei
^&n+@L *&eRjY?Kpu*dQ<W@I6/uAe*MGW$Gb6Dh4R&Y:Bl#SF6NKl<kGCFI<:5Q$VEu@D1*lTd<=$eFHNy#$DWP
E%!>?A k6jRH:?WcT4WHHaV?Jpm8w:p1l6L9<clk:\@BCpjlZLFC=h>P9>n?1FHG:Z!4I66wId>m4qDk!mbmlbC
E+RH%5 kEthX8Yc=*8J:w$=u<yiIiDbWb$RphZGKJm1nL9j*yQluTam6lC5I?+@Dk*Jqc<HA&8ILIbBRVahEMSS
L?4$8C @p+B%=#DX<um<\1kBPkcYqiuqK4^LX?FR!1nt11\*wJE6AdJ>D5B#/E^5R@QWLSk%Y9^nu^wn^Et5IpG
hFF<+W ZKeZc!lK%D$nI@?hyw4HBEMLH%^nBq9=*MmS&cEt$IE8%4?$ju1p1tmPt8Cjhb#XWqZedB6ZPWc*QLkQ
dGEYAT mM&:Q!Vt:6*ljGNH#uBH?ah<X@%kk?c$64&+t9F#HKeYWHVI6:@</u=uwW@?=l<cqH5%EI*yhY?QTGMn
Jetl/Z HLlRqGqDGi:+ZnSyPNLyYyRIEbt^MVRNGEQ@K5@CSb*+pFNh>W:KC>4h$?9QhPW&NKn94kuTh!k:YpmQ
IDJ&MR <ZGiAc^I:#$P4GC=*SawAQnR@5RI>bCLq4N/=RXXtpB*kW+iIZ6yS!KHu8AW*=&X5?Zaki>Cc6H66=Fq
\nK>^* FJSBV>Xne$#iJS5c^cmE8!6YenGpMnpd5NyC^uk5pXw/4@8WY/^MBweXCQldkH*&nm6haFlnGGMT@$N$
EhAPWd 1dK$k5$4W:NDHcn<ZiYdM@tp&66R?YJMTlblBSHJ>#qMRRa8e$Htmp+HSJm5u/m%ALw1<:4peZjBm<dc
JH$J=M 5:NyYdauwc/PkhQ9<iZc\=ZHy\:=q=ZDX/B%ES5bi1?Z5Zat?WqeFQeL@I9lE<</NABD/NI1%ybkm%q8
/1^Ru> wtkPhKYt<4KY+RMlSWl*L1LjBqmHXP=*w*<J*@?W9T#^CQKN9Kil6qCPq$jd=c+DV^yDihRlh<DPmayW
T&*NLT X*w/F%Y8wa8pVy$LlktQ&%Ka8JY&Lk%VpMCdtq6aGK:B+b&uQRDJE>bZERFZ*hCkIZT4D:Hmj=n+MWQb
=t>n9$ ??t?H%pDb\pm$i%G&H+C=V5L:Fp8k!W55pFRDG?:wMQdGkmNduubmnWaGN\lGy&&GmF!W:?iaPWKeG&y
Kl*a!m aCM!BthDNZu<Y^mkM\yQ<&Y^9WQw6BWBjjbHGWJ^B@cXZB1/%%TNutmQ!VYqnY=H8jGydp9*IDpMF/Qe
8F8MMM LJE&!eQ1J@#$>&$jqRQMety$d/:a?\5BFajy*!4^N@N&9Ge:55K$+H:mYZtPLda5PJ4#CZ/uR=1I>Eyq
#Fi/C9 +S+hEX4hCXDiSB\#yB&8XtnbIy%bc*lMblup:9t@wwkj8n:heT*&:y6\kF9pJ+wEjDq#^@VWeb^Y?E8c
8>:8ej %Q:XcBI>%t+CIhiXyc<XbVeE=CDFJJqDEuJjkC>%<G8Rp@&nFT\yid^5JFVtaFDFYQ:ddnDKCDkpwMy^
W8GC8< hG&G>Nl\@bC6NkGu?H44F#>cXI#iitnQ:DNYpMyKhMAAJ+?5Ie\:?miV5D#4X&Mm&S!Y<+p$WbVnYEl5
YEEHEp K%Z6SA<AWbHLS*TB*bXEy8<8M5hnZ5ua?nwZDD6^QQMDLn4JY9XFIM%wd9@q4/YW*LLd:NJmDhhT*WwH
9eiPQe cK+yYVBin>*\yZYKkVIlmP+TMp:P%H65e+dAB%MCF:njjKEa4!M\i\4d@MM:l5yZn?1MY56I9ECC!yP?
y?=Vbn $>m^?ncQtREwRQ<>:=9=6#qGulE:1TcFLYQ*B4PeqmR#Ek<HeSh+dI/cGLtibn@e@9q$tD%CbtNT:=tY
WG4%bA @uP9ek%Kkcu?$iSG#Yc%%%dhDluh^%Tew/Z?E/\Np/6eDGX>Q4\hkj=qNHNRm?F?1=<yiGIyjLhV8p8@
NI%Kl> 8bX$MVC/n4P?5KKML1e*YF&hWuidVDq<H#M=^8PW/6MayJ>K9D/@+K5MKBWq@ZR89:N*u#6IV?Qi#Ki*
q%i!$= DC+:#G?Pe49+tyZ8S9t5&S?414M!Z58Lm5^jt5ZCGi+VmCYE&Bk@y^HD*GTi8?cpcB:bq?Q<qP9SjJ@G
*G4e1? M/HD6>e::>HZW5&muEL&yBtYeBKdhNdj@#BIZYp!<CTVDbDQ:/V@Kciw54T8!VJV86<?QV\:#AqX5@8k
eEdD%? ewT6b#\jm+iK?=9hX=wL<44&b9lNa?ZDwk@Xqn&d#u$1W54Va>@cn=SP+&GlBlT=cThenkBVFc9WBBn#
9NEZLS pM:R=J^hVy%ASTC#&9BWPJnk>5CcWG:qCQ&GGL:CS&9TRb<^B/>>W\!G8wn$<PQ**9G>CuMmqm<tc=k@
EC>JcY d6PuVF6$QCibT=VwDR4lB!@!ykI>R\+6Ww&d66AGtm!G+PNk=T?Q5J%?@F\F%@QEC^/&CGd5S<nli@b@
@5X!D@ V&+\#Vqu::e4LhBt4HVEJ$R>T?X%%c6:juLQ!8DnNJ8aS&nwH<=mHwGKL^S@nkq+q<y=1iQa5SXXMm56
BuVJGb :/55a%wVt+5!CZCK=/Yny?\Kl$#AE5^Y/taS8D^RL1Xc\>$MqGZ%%8=pND4:iZ+=mEIuK6=wXeHmDZj4
aE@mG> J8>+c4qEE*6>6Q?k8\BP\MLHq%9ND\n>W%a9\pqINpdV9iKCY@%NGp4HwWSY1c&GMwH+u^$6mknY8\q&
XASW@G =^!+hW8>5TMtN5+?qi4Vi%Yq\k5dPMG%wFYp@6CkQt+&yKL:a46TP%Ku54j#T?u#htKQihab+JI+mIQ1
4Kd+>D Z6>NNWy\hHG=wHY/*1CB*HdunCYbH\@De<Yt?bZi98^nAkET@Y=i=ha=$I/@JYhVNnAacNK8l$jTq>@!
$@J\q: *QquT9F/5^KV5KYIj#^JuNpc&NL*QaF9Z:uZtSBP%+kdkIKVj+B%GWnXGkIqa/NKKD&&MXu&D&HR+uki
>#T#bt MbV+iL$\SeqA9TKMQ44jQ!kRGh5hHV1<HnX>\L%/pEiEdW&MZP<EhIn%+ehc4nAaFJyaKN%qGG8j6d%@
k>GqN\ /?AH\VAVaM#Iae&86e5\m4!qaY#pFl/\L1:>ERRh6t?Fy1#WABbDVdbItEi%T#?VME<Rdy+L8CHV>yw/
I4&aNn I&W*q4kI\=cFRyT@>V\@mn&iQ:Rc#b$*:bkBWG\@V:\VEML\PqnuFQedmNpJFyL6yWkE1HlIZ$nqRaTN
N4FM*A *LhCCuMGC*uJLc^?D<8H+CMNF6dllL$CT<y4R+CD9nT<j18kmQ!MGHkT5>MSj96ShcykRT&p@LCG>!H#
Aj?#SZ &uEI!EZk+E!njD9cj>m4MqQk<B%^B$XHqeMEMWTyZi5bhB$hm9TkqCkb\VVEjeCLY\nhMYJ&y^jIj<G:
WV&/FT Ap\1+E<6diQpqGP*:Sc\V>^SkALch/6a9\6FB1/4AF*+kwM:K!D8Du6P4$/DmE+WDEFSV5YCd*n=$TCk
<j@CGM yIA:Gy$:9V$!@Y$m8&nh9:!AIt8AqBY=Znel?VuQ/=tRTijaI51pCI<DcX?NE<@FCTj#Li=FY^H/*%Fh
nZ%mX> QF5w+8<*t/wh#?Cjh\b>y/hciK>TIPVjHtJPK8E@AdHj4C1I%lQPd>m#i+1SiLG*kl>nC/SYIPdViVWa
84IcMk dGDJ?nL?PMLi5K?I9Zn:GZluZNBlmIaQB$8!e^$QSE5aRLD\tVcl<=+C4+FqQ=uLF#pC1+*<CjdB!1mB
BhBb!Z ccTDq^?kBYnduA^!k*RX\6%yE+?p?cq+=R:NlCI\GpYypR9nwJ+F\Awnn!YMw+5dWq?KQhK/^<GIKM6V
V>HeX? QqVGHpXY5FFEJ>==p9BST*dtJ6j^45AiP:qBij*bdqi$wE$Kq%5T<h1/q@\D=dF=9?Z!BdW5*lLw=<ZB
XFRyVT yVD?SVYDhQ?FqSGkY#u8!&Ap!w:wT?K^nVQba:L^^y:%+NHm9iZ^HQ9euAy9K<y:t46M9Z*u?ap+WW/G
c#kABq Y8^jNJ$$d6Dw#NEa/IQYXVqE5n&eQ5Wc\R56aGMPBbZQ5CBd8P!R9KZ*HLbyPeZM*>LjnH4:EQkiXn6h
&I4SiT 8Fau5FEuBF&=E$KlWd9:SH5$an^HKHhG/GSC^J*ID/6K#V+k4MS%P#u:e+ZaM?dC^/VNAP659TX=QZcn
XB@AJ* #dlb8Pj5n$pYtKNlab!#Mu9khC<SaHS\Jq9nJ1jJpR9p8b&+mDKZ?A:kuwM5tX8QLkj$aaKdCTAR1Wlw
:<p4NQ $ckHnV:Gnw11:hAK$E!PkLVtC5#!!LwZZB*caubNXISRaIB81F$N6MEYYN$jFRA=dQ<I:XQc?Wa/Ynk>
EnRW%k Yi5=&ilHC=>u\=K+5&w$9BMkb!<5KVKMEXY&BBKX4TPhbe9qNAZZZIn!bZuCk^<A1N1:+p!C1=!%=DWc
C%pqDH F:e5Mew>Vn5mNcRq1>P6abk%!D$4W>C!kWc?6ZSb!&QAKKlCE+c=/!nCJ>Z+MTt8Gbde:iW@V5c<?XmP
uGKll# XC$?<#GFPRjXNibB?j:JBh&+FGGKNQXkw!%+9R4+%jhlwwC9c1:%\>9BT?4J:*p>=kW>Fp8K1<R^#!EQ
ucWEb$ cIN^l>DXX1mK+9iJt?qa4L6!D9Gw6Sil6u4cjh<HjkmwE1<qBT^STZSbqRi$&eS%$h$@kcp@&#b^TIth
>=>$$/ WuF#=pwM<CytD6ljdhcFcPu8QP!m5K=PE<hhVWT8:\9HCc@:GXS49bRFFuQVm!hVQ$Ghi$b$6@9d<!YK
dNW9lB ^aX>=WR<Cm1kRMW^Zd1@S9^:&?%@q@$%+6>4hQ>EnT&C?PecY\S?=S4::<*Gj?^Mj8Hq@ejE?\yF>C?<
mR>DnZ 9H?Glq?F9pVqkQmFq@jQ$CJZwC>#Z!N?+iZ>M:VaXYnwbdV+:>C@<QL?M**bLlu^C!@9u/G9p4ZLh5pI
u=59$@ BP!*/K6p:VL*NRKB?C*/KqtDmq*&4Iu?Fu&X4EHlq#%4X<pcFHdJ>=nIXdIG9iV@DlAm\4>FZ!X4q%jJ
6$^Hu^ @>:5k@qZ?D?6p9<^/Q%dqT#?C@pG+6</j@/%T9:LE@X@%:%ZZ9jc@P>a>@IhV^JFj%>uj=hV6!=IeE*F
:p+k%C tE5KSG$EnZaiNTi1h\utyA5D<hMA$ELl>6^TM8tacaC1>@1$!FBHD=m4dLPeq!lS#PSNHhaE\>/tH4WB
/HP4ea DKtBY+LS=5u6nAS+e8ju5t*S*cLA+<eICkLl=<i9C&1c?BNC&+yh!9m&Mi=Tw@#F>>u9c9GJ!&PVG*kW
CGCh$q mpcDVeG!qA:w&b+9!NcShyyYDK*$WjINPD4Ch+$At^ApR/1t\?E:$uBKkdp44aQ\K^&C&W6QGFDAMVP^
DZDH^Z XKMamjh!jGd$R!!PKYVaAH5%5PHR+*&\>LVA*E!ZqqcjnbE&XWcch6&S5F:#!dQIRb%y?CKauPL8N^YN
QKwWda 8teu!lw5#>blHTjLwiQ9%F8H<McD1I@QViw9FH>$NcbRK=l>i*bABbCyZ+dK^Z&e?*d@mQcc8yw?mBde
Lj5^5m RL@/tEJFYG:D1+5/%X\^&u5XFaeC=#NN/pcIaCdJ=DkV!CWlwb/YZ/R^^VRa6iVWaSt^$Y%\=^#yP9#n
pWaYXm %AiyF!9jLV=i&CZu<%?I^MXim%6<*$AZl+Ct+bi&BZu6kc&bH8B=TCdhWi$5?kmZFHZbIbiye6N/wqHm
%?ey5H bq4P?=+A4KLp?9c>Ap6QT*J>!^u&?Xi&Z6IW+GG\+/Ga8hVmc!>ZbdKkb56*F8T:nZPGZ#&$+i&&S@8m
-ApLNQ 0002600509000110333 Page 180 of binaries1.zip
@aAjwk nT#=LIq/hQ8Y%Bw<cL&SaduJDY1!BPhB$XN>1bub^c?MF&BZEV=$qp%L=<$FPtaiXd+GbYp=&jNd6%ej
y^EJpV 44bq*q$yZE+I/uAec6Qulnl%pb8aw?V>^ZNTjY#q:KBQi5MuA%juDMh1$kYmeHy+e<6>$T+\45%4dPuF
L=:tRi pJ^AZ4ZkAQRQY1<eZF^i51A9$dNF8k+FiE&:<6JDYS&V+=RaLjd\$Pmb6+wpV@Rp*FDbR<%b?PPB&Rqa
:dG:kT >enZiuI/!%&!GjVi&>:$GeFk?:GkC$TpH&5Y$5S?H5lF%J>K\?66WN4L<Fl:??/TuL6aTBdDN5y?cCeL
M#kPG> D<NE5cV19K$9ZCtmS1M?#lue=RKY//ElVuJu5+*Py5$I*c*SW>:!C*@1ie8@Q#DL@I<H/&aKmI+Nj51H
M=dE?V YYnVEDPGCQ/Iy@4H>\t@dKemwmNA51a^d1hal9Ap*kRHa&ieuES=Yu4tQH/c8%A/MCH?eQ4$ebGcVIl*
eAtlqC >nE#R=5!BVBulayHWSW@S&am^PcuXQ8lh/pFQn!\?9*4RQ>It!\ai%Jw>RY#^dk>1\Yl/uA8T+tNauR^
Z1?/bN Q/:bSQ9hEi+jpmR%&C^=@cYlu54q?*NV$t6nKX$#b/e!PYeQ=bMqlD6Yd8RiE/6yEV8%B8@c^IZD$DaT
?F+/=/ GcM$4*+\lSDJ\9%a*#S=LK6H5Qm1J=!ZiE#kj8b%R\9VE#?ViHI6?:A6kL\NL>hPF=ML*mTAS>4Lm>!R
?Ikjut u$&+qXXBpJ<%/5^EaZ<h#WhtY@#N4Gl1RSS^4ecDW:V%dQc\C:%SRF6pJhlD#dAJ+H/cCjZcuFNFl1eQ
WWhl#\ X6k!y>4>\aa%6?mL:iiSu4kjR:KEN6ub+EENSmV*XZqJn$=CX\15=ul9/J@cuLFc&<LmywL9V%51N<=E
FWJuRI EYlejC!w*inPa66QN8^<IR%jVhRSmhK<Bi!ZI&<!bT/R8n&YVbLJt$+k&\>SKY1GCt=&HqP>Q$?1SL<!
IKH8RA HLDTCE8b?+/ucymd5L@J&KXBG9ZDB8QMjGww!q^%Qj@VT&+jRkb#a/$N+yKAa1j?Y*!PcGP*aZRh>8c:
KVulFy Pa6q+!YE=qeDDe%pFqacqcn\Wj+yKhE&*y5yVd+n*h&tEyLVh68NHDm=%8?y=hhG:^K&&Td<bLD4::C+
@4E8SN ei:4:kJuudG!&jSJ1?8%wG>1M6y:H/^FAH#%w@\$LepB/NS8G<biRXyh*A:ucZuye!EHiA#ea/&V%HVn
hKQyt4 NlYdjA>mcwj6k^+\11!l18yQ*wpZ!PRZ<wYV=\J5Rt6YGV+<aqkQ\lqNQ/CY*FLN*YluXSZlmbI+y+9I
\EGW6# up8A&\+k&!t\jwI%^S4B*+SDL^mB<bGya?R1nD#Te#?QP/=Q<mqkweHL@ReZ5@FJh1Rnw=9dTW#>pyEH
b\eHVV >bI&p%@mqcNXBj$b4JpN@pn!>LB4JMVei5?HnF>Ne8Ht>iV@1yQlhw+awW?W64I@<E6@@wNwJ96HMMZV
*N&cJE t%W=DyqyjnHYZWTQ&FHP@Xc^iIXQR>>SZK\ZeZ$S!i=ub\LZ^1aZT$5Mlw*AE^BQdNhiQ=db:\16=:M6
==$%AA 8Le@=4#B%TcnkQ61>C/aM/XH%49wi1=BdQIl9aLE>KKdjmSjp4DLREhlLHnAaBX1Z#htpKuT@IVt6ZA\
GBbpGX 9jTI1t<tuJcFX1?C+SYHJwG9i+!FqHKTwJ%TeXlCXX:!Qwbcjcey54HRn6Bk#huudX4Ay!TNYyeZDRHT
!*m%^# YmRS&8L+qTH9GR1KyZVKZD/Xh:#/ttubLJ+na:%IRaIL5RWFnAYHTE>/mMbej<e+JeQ&@u8LXu/dQ%h*
<qJX#6 weMN!Z16H\e&dY?iXmw<KiKwepTAAMQM^^PYaybqC%Snm1\ni65/V/A>$ERJDpQ!6S>9I^8KPWk=$&/J
K<>J61 mT/8X#S\^V$!bCRQEuquPBiJ4??:Enu/KGE6JR6i>!H+1T1K#E<ydat%jwM<#Xad@TTjwSCG&1mFqyy>
dGE>E/ LmNkkDm!KS$Wn?wN$Y8%q$/#q11yu/K6DHp4R8E44E@5>RkAPliFQ8uB@am>+R#%u^$W6Pt5iydpl*L6
jJKEjE 9wkh@E=8mR5<=b?RG>e5M***$JGecn?C8%EaZFu8+J>:1#@KH%/#VA>W<e8LP5Q$FBhY&RZa+WTWmLZ#
wVJH/N ?uhWwaFeF9at<*pL/@/n/e<:5AFPi4JACqWFh4Z><I=wIXLqu#@SIKJmM6<i/Tq<KGJHK%%/6SZEGYA!
45kElj X&CVP1Gp@F&q>8YT&GSQ@8Q++Xj=FcVYHMVD8mRW+/>Hm\AXbJwkEIYh6=yhdj5BXZ=qcMeR%yP>%NbP
=1DhC\ ubmR9S^Cq?HTWq^Ei^Tb*/>e&u=AG?A1S^Rb9L+c9t6bRM=8TWnEdeciRGk8bl*t=e94+5+SCZSWwC&I
NYS+nn NDS^GlY1%i^pAXW/6JhEqkAi$VuZI1Jhn8I!TwNL5\6k>EZhGc1b!iHSp>b&Dd*k4@de96%t:wX\PZbt
ZWW!@V <?lEZ#b#ty+aYmRdhRK@G<+cbe?4j6W:?Wy!=FHy/QklK8WpJpYt#pkyI8HnkDXuEwy*^G9j!Ej/HVpu
b9S#Q& I#V\:+>l%FST*TmTeFc+#Vu!m%Z^E%DeSTV:L*8=aj=:^Hae#A4d1yCQe<QFn4^i:Vc$chEFJKYG>1=M
Gap1Da ij9%1kYJ:T:lbRqHqQaW#^*q\*9Y8Ml\P8&jq^F<6A/Q91>G#%:1TBRPapb=?@diyw/9hWP45>SM9kKG
FCKLGX 6%15T+aJ\5ue$pl?/yXRBMiVQK&hZC1I+h56d?8<I&$bI^DSt%4yq5mnp?w$cpDth4?WP/@5FRi#IRiP
989/4E DWeXN/c#YwYa!R%uF5R<R%NY1^D+p!6w@Hc8wpK&VX?8In/PBTF:PH6H8/qFcy:$:9/T*pE:A44<AKHR
ti\P#n LI=MkmZh+c1VJku1#I6+jhNYSVnyBlV@BCydAQX*l*b/FLDK<!Yb\ycn:%mpjudHmMG$?LNqwKk?mNtw
F=q\Ru XK8>mGcTTN>=HK5SHKjVmNAdn9MS6PIC^?u&w/kGhXJq%LGJH+uy8AhJ\LTMk9$X/my8W<8Jw$kY1J?J
>Q#\eX 69<BSRJ+p:c%*R>E+5nmaBqc$j5<HiMC%GS=ej^tXeylui9FwE4X#tZR!6^=cHlVjLutRu5&*kbT+/bd
ICcP?@ AlRdh9w&NDk%*!JSpX&Q8HK6:Dm9=Q#hKFpSS:<eew&c+CG=T<9pl6tVSL>Z=Zk*Fey#MjYJHS9W?B!<
%$!5+? c<!FCjEB+=X#\5TKLqN+$hVWXLk&a:VFtAaKN<Y#eS1K&QM*N8h91uA@XkGcLjFuCupQ8Q1^wW4!&\8S
R%HpJp P>qYMTKdjYJ!@H5R96%+<E$#^iHQBBtN:M^?*FREPI6plimm!l48H4mu@*l6MIYu@KmpPnT%<AT:ZX&L
4Bw<n> ZF=YaMCGTZ>YuH#A<hGne1=8kBFFmN5\Wq#MLmtD+QeKb6GiXIEW<HwWYt6%NYtG#pYn@b?^ni4p#d+w
tupPD5 chJdmi^R<nj&VF+ked5j<9QbK6qL^Tc4kie%BSj4/yq11GSh#LE1#?kL%jSaIP<>tpL:+BX$=e<*Md&b
TY!CbB k!j!61?I?8TXR=8pRmTVPnhX&Y8M=F6%%<Em:H^54Y/!NP6JWiWuJR#DNJ9*%a1D\?dk\%=9EQ+#/BCM
pqRM4\ JbCEcNN4$1%eee+N!8C*>nGt@&jR?4kZCeYAht?5TwR=>/+YcGEEQJ:HhpPt$6hMP^\#hIm&lTRytCSN
^ljTn^ VYAKFiYeky?nak^RJhS=$mtHN%W:nQX/J:NZPt^PLnyYXqj#Q\/HEkHqpGMq$AjLE@hc?^QHMS:L#D54
VmR*tZ Wpdl$YHlm46t:RR$p+NKc?44Sl!!96Jihp4kn*jn1NAdlwt&Yj^>h1AkqH4>mBZ@%^8&4#1JE@8qQ>Pq
8NGdJl 99yPa*w9$cQMRR>iH$BS@F/F&C*Jj+?V<k<1N/JC!n%1ml%Fh8d8@DZ1=C4kT$m^B5C@y$uPti:%cJqu
9G8FuY MNN*l<D=kWG#5w5VEnhph*GNFd?>BYebK5w$XECS5#ZDD9N=TP%lnQcD<aY*1=FLuy9b%&NIk8VSJ5dp
N6jEj# nW*lXjF/&h61ehG6yNu9Nk1DBq\I<pX>!i+4y@Y&^^V=<eMdFCuC%W9+ZE$SG?e&4m=/nkweNnF?6jP1
Pul?NQ G\:X@Y+tb?V/A#kL&GLqwqt=JIuG1HGd%qYV&yZH*i&&4#l\qD?Sc\pY4>^b=BRK$upV>IB@t@Nb5Djh
GI+i\H ND9GIhRiGGTn:jZSMi@TTjT@F?@?9>+4I@:c%a4<X=4qj?@$@bht?Y?uAAqyiyy=@P*69:=Z?K<Flctn
hRkZuj =d>e:T>ZeDJ*64B%5tcGReV?WYDIt4yd@w*>1/*D#hdT:V>iT@T@&GKL@<LNIZ=%N+j+L>$emF<wlj@l
nD5ai$ J:qCD@$LyjCjwH?lFQ+FjXp9?R8q<J?lwXilL?5qj/EW@nM$@Aw$R8R!G9Fd6MlX/E6QL9yd>FY!B4@$
+Pqtl> =PK@R+6hJY8Z>6Bm\4>FZ!X4q>w%^GC@SX<qc=jcNeRR9$XjJY8ZCckSa1K@SX<qc=jP1eZEj+eY9$4Y
IRJNTu Lt@R^j?nH?Mj<H@cwQ>nj@*ZBq%E?Fh?DQFj?DHkj**l?l<@^m:?Q*8MDYan9/aCmY&1YDV+!FkZ8KBB
t<V#4u CdA*b#+N\c6HMlKAiKe:AVL?GFElGhpnt91e=$&mbFE8>nV>WZ4h+FAb=Cp>Pkt8%>c\E<&h$kITe#8K
i8l6R1 DGRZwRN5LQb^X+<JZIM1D!\y$%aFDh/VnAyA&<y^Ej>NbF&@i#VGi+NiRcpM6$8yjQAiqLGBd#AIPq\y
<%dBu& lwEV\NlXwHCH\X$\eA!5SIq!TD^6$c*nCJC8n8aiB6h5wj8EpWPK@b&/:lc>#b$VtAFZ+Wd+qM*:B%4>
jud6Sj +CF$b>@htReEhebpY/N&LWKDK&NtM\?&P\TFeqVE@TF=^S$WA@#XqyRCH8#&ey*>n\$#hWnP!\\I<ILa
@SP@ta @%mwMi!/H+*akdi4=Pqy15w:Z#Sh%*K6h<upGpNwcle+lV9RN*p+mMV%W!Y*6JC=X=A!c4*QFZkYSm+S
b&kFpp p/Wn>qH1HpCtiZK16p*clnbc=XnZ1JR8epJ6^h&h&p*ApW>Vw8L5a1yKjYc!TSkydQn844C+J4VRmV>#
e8*c!b RW^jB$?<RX=$tkw<pJj=SRTY?kd&wkdN*95&6M*lG>T?#KP9GlBqyJ&KNCnG$F1JFh^DLaH>AtL%K8:P
lqWCjW $>aq$bVME8Bb1FD8*!kRDc4T^u+Z$jq1mJ!eySR%L1%KXZ$5%CB&wi8G@QFI*B4k5FD+W9X?<^5uiV#%
iFR!#1 B^=XDk6q*14t/k&Imnb=$:\AyY/4#LJc$w:uMKuMb=QV@A$e=DpV!$*kn:X9BE9!Z>$^TdSN*DSA!wQb
/TX\I< G9Muu%%L9B<\VDN#jeW4<:Py9Fpyn&:KNF\=k+ndb/Gllce?>4P1NDieKL&Fu6ptT?ZkKTSunQ=y9I9B
MSH8*p F#ylm@**:duYb8bym+?C+*iyu+cYGk!We1I5e/qwZ=GVS?jtQw=Mj9GPAQMn^b#YE!RVI>ZAQeXR?<=p
/t9FhN MBk5+Hc&ECCZ1q+^>TAn:hZ4XC!L5&*<IE@B8nFitXN$hDyaVw?Nm81%C/SGpmm*8yNPL6*T5/Tj=uwi
FeBR$< qwu^#d44^mqiwZVpjy8$qpB*Q696!Tb\8n>*WuF/R#D$GDm^LRHA?VI8p$JJt:%be<jX8$+wQaW8E&Id
%w$P/j 4w=cdNCb@$cyXPL:yiaiqMAujQ=CZ4G+Fw%P@Llw>ankEhS$kb6w9P//Hh9DCcWNJe+b?D$5u&jq8Xql
NnH#uy pb5%%?&GNC#ALZ$Y?/$\im1cb*6a<wHB!:T^pwhK<b*ZiY4VXAc&Tj^LFM4kp1&b\c8tEcuBlh1nd&l1
JkC\NX :#8GX\V\m:NuW&*pYRBT99B654clX$lS*BWuNcKjcQVLD4ZXQ=*ZNjy$a>&^&ADt4pciCmGbZA6>CBXN
-AaVj\ 0009375505b00110333 Page 181 of binaries1.zip
JaZIuY $T^#q8dF4p4B6<*KTb%u4Pu!65IGKdDR#HKTA%b?/Fl9l>t$BjNDX^jZtAEW5aNXcXqq*MCN^Wthan8=
96JukL =&@FXFmq&?6d>$tj!\b@Gch4V?E*6c1\L!9FtY^R<D*MnHFCy:SuZ!><B=S=/k5/YYta%lVZ@*#64ZuB
eRaA<& c/8m9mJkkG\Z!1Z<ZHTCyHA5YL=YZqBZyqHwPnpCkA%bLqdAQY*YZIBDCpHT4HY$Yp^&9yL&d<&pqu8N
lkhJj4 5+CYL*Z<Q6*D#RH8SMT<PwnwF&h$MW$/E+E$j5J9mZ1GV&E&<Ny$XQli!aEW$>9Pl$A!1e49^kTC!aP9
9nGYbm 4XKQ^wyEHhCQ@J5*ew?jp6ydPS:HCHuSTB5^&&YWV@ZZ18ATnWRT!DBEcAT#9HYldh4M$tpl<^DKBXe*
GN^99% e!qy5+wYpHeX*9R^GCGykN!^&KRI>u?GM+R8LEH\b&uN:Gt8C&lFA\yT>QeQTY*GX<qIZ=l<DuX+5#t$
%EB8S^ h*>T*\PAMYnSb*GN1#^84+CBt\5/R!yC<!W1I:#&M:eDXE=811P:H5jP=ITa1LBQX9NZtlZjJ=Z*Typa
5ATniL wJQTbt:\F8k:pWl4tH?Z#6yX=uSk4y/N@XR^ibiZ%kFeR/i1IhjmClp@jaI@@6EWt^PT@Q/+u/NiN!>H
AyK^RT 1RB%djlD:55dWA:^=?NRiEMaK1Aa%5=YGT<kbV5B!m&@X=B6+#Cy4eyyPMaVp1h$iw1/4qRk$PRiL>m+
dH*=*n @Yu!VdZdThb5SL^EH*EyeIKhEJb+u=44Qd^!leFjQWhb4XCX!%%XDQJp!B+I+^jBjX19b*&:hBKQ^EI@
IeJ^aF EQuMyGt@p:c/+?&>cIp$wqnQ9ZIBaF*lYeYE*GP+uT4&ycTk:elC%aCaHB*<XFta>8/&j6w:5Vu&BREl
ub^ZiZ NiG*8/JyqcS4D*Xj:A*h?*^:>c:e$\G/adiWJ:j9+R@AQWG$a##CIl&1u*Vdb6JpVi^F^/D*F>$Rcya:
@&N<Vc Ym*SC:ab&cM6cuQ^uR9Vnp<Iuu+wt1A5T1u^B:G5h=c<<Xpc=P9jKI/K*6F?e8e&%EHX+PL6!&B$hjY#
dEqeZm WWMuP+iJlji*<pDQu+cMXJq9udiy1uQGA@K=48hQET&/Bk5FtNuWEitSkJ#PQ<1ntdd+Kd1V#bpCl>uF
5YAbXD M$m+&/lN*X&:htmK#4=+T\l/D1IyLb=&*^Pc*kY*W&X89IyktQuMYcViaEcm<pN:hYh=WQXi!8tZA9Wt
ytXh@b Y/Pd%uwBF>w*Qt/P@n\In9BTqS5yI%+$G^q9wRM@=1EHGWY>48FJ:5PD/*IGDHZYZX5K+udK+=h+@uT$
NQL#I5 <Q4lB?8A5<G&=\?Nu^*1Yb^HlGN@q6T8XL*!YlILX>wW:5Am&Wm$8JRnR>T?!AJ?A4K@>iq$K#EJSc=e
6b>jjA +#^%/FZC/$Fml+Jl#CdwMDej=lX<FG@!/uh<:pX+l/Scy%+><A\/GB#IMRjje*qaBuVnZ\+PZ>hZ\jF!
4Fw=H! \RRAH?QF8?I=lZ>G>Ra1+j=eE\u9NFqD6kHCYqXKHIq:e$mGM*@$GRZFbZ\yaA*tny/JZThD9jJRpV:B
l/eu9J Q/>ZY+AJqk8lZC4mdlF\>Kd%6<8MYkQ*q$%eyECPBGSY4X?6jhCSF!1q!?n\=Za=Lk1Tld#C&4NI6dN>
hl6a>@ >w=Nw/D?@E<LGGLteHk4bm+\Y#CITIY>EYyLbN#q+<mV1><=uX:y+N^B%b6k/FY>nHKXtN*Iw?FmHa4u
deCY>$ :qR+DtcPDKTpWMZDYycMj4TcQdH$W6uiD=W>C?Q=iF4+q>e*BWJ<I%YN<DwIW=eVXWe%F^D$AZj*Flu!
$6$Ku& *B=@$6+cB6n%I!B6WpZKkjdJ=8YQiWqGq=c65pHL8w458yXmu/N+CEw8$l#/i/4XhFhcnFZV>hWQVewA
H/&9u+ ^>c?dK$86d$VN:ncdqlyBT4?8Fu#pAtILLYSnh@P#w8>$N68#F%n#muEJ\eRXbd9w?Qp/$4=i!!*lXG#
HbZ!=Y 8RZ%n!pC::ePed1ypC$+CT+n$@cPS@q:@!n\/ptaXFYY#LG54F9w+4TVHB#lu+/D!1%WY8CQQlK/W?5T
/L#ptR iPa1V$CM>lE\E:RGn:B*u$F4#\RmKBJpK!u1?/Zuq?$mJ\e=S=h%INalaPkE9:NXuwPQVWHyEICah/PI
Dhn&aL pa4>nGyh$GTP#JZ>4D9=E!Y96d^LXGR^5dD$ii#/B!/J:&d/%Ndn:%jG%aCe?kPAi8C/S>Xu6yCd\RC^
t6cjDt 8dBe%@D?DTZe=%^G#RSuqcS8wbwRMT:Yiy/<t!aPThF$cT:%/IVGlY$>Y<jJVhY=8>YRdW1dQt=%Stlq
e9?\>1 F8HNhFXeF?By:qd6tLy54mw<MA=*&Q+FwVQPQXk*$y\YW4\e!D+bnt\Cdiuy5pqD1H9H$J5P5Z4I^PX1
mpDK/l K?I:#P9GZIb6why5>t1hml/q$dn\/mC\pQ@E>9Ji>CMB=6Yh1NKYDqL<I&SYB@6GqSdTj:p^mFT&^$\N
>:%dPA %4*P6+<G$4N1<jE66B?#j^i\JtqWD^ImD^S&CtFXS$h45b?RRX6Zd4dJm/Zbk?iqQ/1:c1$ZT5EL8@h/
$dl>wb tI&F/i\=b%XKjG1%C98FJl&+nITCP$jJ#bD5=&5^!#6E&A**^Zp%ieC8A>JpNHl!m6ymjX:qQYS+9n&=
CBt81Q Wdni@^MbI!K$/NdCM6C8@<ShR1&/@4Q!5kEbRF:Rh*:5y#iXj/m1epKj1=LkHCy?V#EQhy5GKq^j:IS^
u=NY$H T>m*1Ce!iFDEBnkplBWIIBi@wp>EBXWTNK&n5Q=&B^#>mhy5ty=IiRTV=!+yXy*y6W%t?ullKq4^TCpF
Bu>Ke6 6Ln/kM6c18eYX5Cqin^=P?qXu+*F!=ZpnIIe\X1u#TP:QZi%:iH#=/+yDHG9RP!hG%\G19Jkaid*\pZ#
F=Luny BeJ91Rbq8:qq@Ve/^#b9eA5alRaS*>*q%jS\1%=J#I*8+A^Taa^ua^\$ThWKWT>\JlI+A?/t1Y%$L!Ra
\EJSd= 6ihPEL4WC+Xql=q>W?PI8ThpN4qb?yXY:pb55ktk!&K%YBaHA:IWqbLN5XDiN6c^<R=ZlZq^wubZD++@
l$Tliu wbeXXIXhKw+$TI@Jy8P!5iH<bjDNQPW\a>T4w%Wb&#/Gndw=9YPn$X4=/NQ/BK1Y+cL\*XS*bm6y%STu
uIP5V^ RJ*BumHwcS?641Ap5LG&Zch@N$/?8HdJ8HE!m$k6Fl6:&qY=tHnpEFp4aFtqL5mw%*kD\H^Qi*FXn%SR
MGYQhQ $QMXmChY9ZJjFh&L*9/=Y!%>B#ZlYquHY9jDkI%V>iTNwaKj5R4M5A<*eAB&*=#4d4anVp1t*tCIc%Gj
S$^w5@ /mTMe&F#VjaMFDH68n^qSiWpd?KGV9u+eT@iL!/Nc5NC4qB5V1ubPHK><iDnqyZ!K+Jh#/E5qSRPNS8M
d=PnJ$ w+hPw9NLMCIRbXLiW^jdAW8M*E9pQu1tH9:PtdRJbTFHd=t59t&VjD\<QHE84FHu=#+MGc8hZ:>Ieaun
y$BC#@ nMG%m:w6BZ>+uebIR?%$?KkVDi5k$cb46L&lQ<9kjhlLFtNIyphZYX1LhFd\u/lHJ4&>E#iuyIKPe45N
>HCt:e 6BIDhm4Z%u$NpJ%&Cl$IhV^W4@M*e8C5#J%?\Q=h6iD=W*QyS9!&eQ\bn8Z#cE1KhyNSIP5Q<=X1p^LF
yYQK&j ^\VqpPD#c9#?BLZ%?A*bNP?HFIXDZy=:eIZA<Z\5SwVM#NH/aYpJM=dP9MBjW!@TuZL?j5$m$n$AV=+w
jdMwY1 4THZQ*J#IPT5J*>Y!H>aT!n<<tY+?H<j1au+j%F1IkL>b/tJmQCXyTd@1Fd?1dV=SXMtjtW6!T?5^Z?G
aVkt#l F4$KjXqV>k64<b?l^c>CZ>KMm9#CY9^ucPE4$IlLhA$m9:AY@^pchkZ/5n&*!C?5^Z?G9p4Y+Jj5&EWk
!4&Mpi I4>FZ!X45E6QL9bd>FY!hytYSERa<q9$XdJ&&a$eSaTl9$XjJY8ZNiEm\9Djw1?T6e68=CkmLQJd>FY!
b*n=p1 httQLmL<V%IV<T6IVeV@nhSEBI:+=^=hSQlZWlP^@*h/>Q>@YcI:@P>awm61W56w!GEpkHt*#cqBdHp&
PE:ueT H$S^5K8y*i8%<w!AuQd!EyJA>qm/!8*JhDBRRFN?yp5>!tm&LCuwGC\n$+wSd1E?6nkLne8H$4dnTY6K
*%G$JK !dbF5^GPnAZiFbNnTVItBenW$+HjWdI?qqK9ECBZD/GA*JPCV>ad@bBM5N?HcdhJD>BJ5lR:WlDkWh8e
*+kmc? ld49d&Gm&aw*WN4WZe/$@VLT^&Plu5ttkn\qdm%hlL#%+$jRCj6bMTu%L5CQhph*VVJ+amS&59WAB@5#
*:b:Yu hKVAl9=>ZdE=6c\LTq>TYuN@BG@myiKGG?I/THA5=Q459Y9V8ydQ@PXG\y&JbDE$R6\#Fcywip%ZFPmJ
DFi4N5 JupiKwdktwi%aKX4HcRSSe*WZ!dJ:&KXNdjHqMdbM4YA+jt\X*DNS1Wh*ya$mQdTide1lE\SlTY*D+NJ
B:a+HJ +1a!YPy&@P\yCc==J=YMXlBy*t5j>V?E666XPD6@B1G8kVWt8nLt>QNC!Qu6Hjt?eE8>RmySa/:jydt6
Pu!p&F k$GM!BRNIVi@PVVej%5>QjFhKtVZX*CQ%ktSdVdy\HTji&TZyqt<!Vw!GbNb%Xk@&S@T=t?i>#cw?h/h
A@Q$n= Yee$qn9>9JZMa=$jQ5m$Al!SL&/F+QJJZ6m?E5P\\a/5=BK/K#M%d1%4Rk$#$bqiWiQHk>*^aGLYb?ju
*Z9Q9Y SC!Q#tem#J\&j$wKidwPQ41PywpJ1WG<1+@=@QnY<N^>k6JBD&iypy84D>?ej+<dj\p$uRwRB$mHctY<
FKpIi: AWl@wtctMt1m4*cZm&1VKk@l#NN8C5M/qb@LIDIaA<!&hd:\u+tI+bJR#eG9!YBw&L%yV?JMXI$h5jm*
q5ye4G RyFXIJqV1h/H/FJtLInP\B@k+nFY5?dZqCq*%*wNM\<6i1:Pit*V\#4:=P+D>tDKlCwh+48?58bGSREq
=j4^ne XbnNV!lbT/Jk9EB9PbiW466hXyM!epGTwX&SwZy66QGLL%$BPcSChBSbL&4u+X6j\C^BpqpJ>6=T!pbT
i=laFV 4\EdLH1<=CdPa!MXC5lHnPLbed#JI#pEcB8c://B+###AHyG:5Z6BE^w5^lAq^iW/5Am!Y@c^S1<^/Yu
nL\4Ee kmi5LEuat:1C>!t/Yl&:+<+59<YXd?Dn4elV!e^JRt@^4TwKY1DSVi>Z$RFZCwqkw49BhZ+cu$eeeGl=
ayt=ep 4$mL&eFCqm>Iab\AD?YMF*FMkdWSX<4y+5#tWlFB^Kwb!d#ijw#u^w=%/@*G+D@>lw91=a9Tn:BmlNPF
k:!6Z! 8St%pV89uE!>46R!/>Qew9E\Fc%DBn\ZY#IlJ:GeW1wtdwcL*IkD/@cT^w$d5A8j*aaq4kmCY#S$eAVw
YT*e8% t&wJbIPRQbLGJQqmyG$TjFDMy9JM$NaKMq+GD%A1JmiDV<6Nwi%w9^VDqXZyGTIV<#HuWEPXy$ScPP$>
tZDTV8 I<p*u9EiTBFKNIZF#Z4FyF^4:8Z14:M4QjPidBAeQ/pDW96+8\Y$nuH*$pBK!:cXZY?kXVRQbIbp&SHA
$$HcDR mE!wd9LDVQM^!#mb6DV9\lQceihH<Hm8!p:t/>jpawkF8&LGSJibKm#/9aji#8Sc>lcD:YLlYA*dy85H
X+!FC9 w5V&Q?4L&Ge#@IhDml?iP+E$LF8@^\jLKV1u<$w+bQnQP?m9?QuE=wkPE=?FYw=XGZdu$Gq^WIRq\BJq
//PaE> TAY$qi*#9BhSKhdVSy#N+^Xkml99Cwq?66L*P:R:^Pk:1XHXCwaSa@CwZe%QZJ6KV=e<=#@/Bp6u*?:$
GGk=!H <c@k1#tWIqK6%QJpc6pjIAKhqH@VGh*RhqLl$Zdjl*\?+dDR@GS54/Y9NPw4^=Ik#c&lV9@^qu<tiN!#
p*^lqI &Y@eKJ*?\Zi8uVw%%CcIYmhR#1GK1q/Vt%qWy8BbplA!YKNjSNmmLQjAbuAwhekP69K<&md>yupA!Y&l
-A/Aw$ 000039db2a100110333 Page 182 of binaries1.zip
\aKFeI *HAy/XRdG^Cjc^lDNG<p8:^>n@4FVDc%EZZeb8!d:4he*MyQu/X%9R>=8j9$bt5NcNRjAdj:iQ^iWh5!
uP:S4$ manEW9V>Y8&11jW+KpiyC8BHaEBBctm9cl*Gubmy1lhVMucZt^l+HR@YTpNP>b=6:*TTAZEnB^P1QhQj
!kcRCe P:8kyFw>LbeBt5&ykHYVpWbJYQlXLmh@L1kV#Z!n1y45iniD5@k>HpPJ?u6YNYWTPW4Nu#%&Wc^dDAkb
^HBY:@ pZ1D>+C9^&A:/^kayYplkwmZ^C:c9VFy!P!qVI1$m84Jc!9=eJR8J\pk969?Ypb5pJ45#j*H?>i9*#?M
=V/ae8 5FqIbB99J/JeaPa6+1:dky=WJI1kby!NG6a>l%PYF:tS:%%GR*9BwLNWE&iZp%a<dcbJmmCMyMVF#@18
6qLeFu N&Nqd>a<F9J!XF:9EE:M8?SuN%baX>1tJFm/Sa@!V*wR?:*?!4tMi8*%j4t<b5Ry*&Fn@SGLptQ=CY9J
ZlqNbl h5Qnt@JDE8^=L:6:N6#PXd<?jbGW@AAuR#:mK<STt/FR$*HNRR5!1K%VSSGpm8+jcPhn@pJ9%X\CdDaL
69H^hw ^DQaD^wViiA>:6#=WK<1lKP#GK56l?J<E+RiT%XN8>uX=dG5\!lu^!6Fe<P11b/q+/9ucNy%yRGihj?<
lRF<XF !Rj%C/Y*d=\AyE96J99P1XBL$9ql!8CH?aluBAN<cqaP6nN^!N:d$<9*1^>^h//dFN@:FQ45&eQm?Y>G
aHM8E8 Z>/wRKYn?*K6u6WbQQn^Fyw>d*%PdGGSFSPy5$$X=kI\EiB5NX?@mBF5eaVYeac1k1V9C1#dI6HShk8!
B6DK&K ?N4ZT5nTR49:=a*^kch///<P!HWIRBmN%wY89PM%\hRZ=iN^9dNH^IYjKiBy*ai!wNm$+qh:lb91Zc>T
w*T\:J X*tVZPD\+hRpN1Mp8%GA@Zk5Vu?q@Pll@BP<DaP1pN#EM6<@&6&iXQ6\hcJ>$j8Q&T<PpSe@m^IulI=6
WFYSj1 4A^TRbIlw#k??@mi9hmj\!I&Rq>^I%:655>4p4q<IdA+KF!M*aN&^5Z8>*pMSTYu<Ql?JkeCi1e*dE+J
NTW<IN KML\dN$ITJchF:DNcl6+B\#4i$D?PK1aK4?u*N5^Ei91I^KPJcI$*H@=Rc1we&CaRlH@ceYb^lu/lpnL
FRCy46 jeDHd>WMFy><BHHF&/MpD6$$m4PKEdKtcS&k5:tb+bCQLuBD8XmCuY<\XQ69thnE&N!mGJE$HjCICn?Z
R!<hRW /?a%61t?u?AR!=P4!<Y4W@GB5YIlbGmh4ENQ9d>S6$eA^=JJbwA#RkBmA$LkK4\AqWu5LMhjLM<Hl^A>
1H^ZFc q>9QecP:n*@^QMkE6IhW:&tPR\Gp1NlBC#65dKbpiVqpY%9pWPCpWuKA8bF#D:jD$4/Gt6X/Q6mJbE/T
h#^u^M ^E6/JRP#yMHSI+mJDLcLy6ZbIuGTP#%YdJHbG8V1lZFGj?XWZtkPJpPPGqR4ia5+MQLc?uENmum&>weY
Syaq+u M5D^DVAcMKc%AV#8YK<8@All:%+*=bMN!G\Bp$la>L%+KGnq6LAm>L54h%Selu?H6MM!W4?WdI#eXyD!
e>phMK XGbqWVP8?nR/Q<AE<+\Dk:J16:XpZ*XRT%T*$^kJN#^m<q^t@6=N=SR!HEA6yw=pL4Q4V!Qk+\*eqCJJ
?RDnLR %NutVdQlH<lV%FD94%4:#pYX?q#&MYR*%B:=k!?^bbYhV=V\G5Xtd6w&8!S@4/R1GaITGP6Y:!\<n/DI
lTV*y@ >#4M4%/np*JRBQVm:BG>q5A&Ibb5!1li^c#aE?>R%NT?11pi6c:cj&n#9M=S:I@PIB\I+EW$1!pHb/u6
9Sjyit L6#NaJHpqtAJ@yLKBnN!lL&k*GeFkw+Gj6*&?lDmyDZi&XuHTLncu5t<V4dT^&m%uH4wuSTm%W/k>RA$
V*8AHc u%qk!:@LGpkAE%%TaA#$NRNFt6qFIul1@aqP8MjXPAlGT+u\%Y\iKwT6Zdji*Bu#R:Bd$mKbM4q$ZBQE
\n^/Hb :!^k56ieuLly<E*cke/6eldLk#Z+8pH4KNZ=MZAT$#1B!1TjKai#5B64@8SNhdX54F&eLLDZi?LD4d$n
Zbtn96 /bF9#HWdbG#9!Y#QA4C?+j6W^pSiwjd*PGy?+FJhW^5>:1$?k<WnAJ$*9$e\p>XMA#ZtJDGyMRq9Gc\e
wmX@6? $9waKiIwkDZJMYNQ/WjSVyF$>cNKYGB@>uy%>VIL4T96&:kpclMMwb8n66YTYJ$KTat@p#DFdPKawp9n
ZKm<9+ JCHujKVNl<n*Tp5ucEYM1@q/CdRZeV!DDMJmT$aWPqTyR:kE/\Pk9I<+V%k>X#JpPw#XuHhd+tia:eXB
Z>%k#E Y/e4H1hTCn\/p+ZIQpp%et<%k6QH4S@wm@nq+MT+5EYd5MP:aK1:IRwGIZmmG9uDwd!#>acIli=:J&cQ
%9Dw9C n4YyTC$TNq6NP>cH\:#JWH%tP6!w=e*y*wi!=n?jCTtahdh4ctpN<ZJbc66%!W5ml=$=4e/MV@Z$\Xlq
Y4ku?c ntQy@aiWZ4:cVl@$C1y>pw>XX?aSK@HGJXdjib<:Edi*eTRc!dNa^#&Hp\NhPSnbqCu<Qb@b<XuIEiL\
@mhI8= dNmFFZdw4=LyuN+J+8mXDAXm9Td5c\>SSL*T1P*u$A9ApnGEu>=yinLVVptZkKnGK>P4Q%8TFhu1Cut!
GF+6uw $cuP9PIWKmqF/qW\6LkL&6B!jc*RwETDV/+y9IAJiedWbjGbe5=:?QkFAyPCk6u\yL1^p=XV9cX$9a?u
F9wYLj VyHY&1tu9B1XeEMd<+C9h6=^iA49JQAAy@%\A*Z:aLG*kpF%aS4nX8^d:t4y?9Ey!neA8JnbQS/<dCAb
C\1JhT >a^@6@lkG!:Z9?$\6a!KZyi=u1$inwC<LH6WCn*d@$G4eeTnBHXSim:CD\WE:Th65*9l*/^T/4wt><jh
h=nePb T^jpIqDIj=j?YRV/Z:TSmMBF@:q@lw6e8Z@?i!Z^H<8PZ!mc@*FZ!j@uBqupF+4tQ$QD4$Jj%1#>R6H<
?!VcmA b&mSK>CZ?WSEj1Fw@nP$&FZw!=4WZ!mc@\V>C$Z#Q>PZN5m@WDV@Gjw1Yd9MJ!ICk@$YjbY5ZddEFwEl
lVS^8u jw8?T6bkIyjSw4>FZ!X4q!&^SYDm9$QD4=I%1Plq6QB9$XjJG9VTp<N?m:=K%m:9u@?>bku#4@B@%n@@
=R4S?K 4?u&*@yupX@58EZ?4aDyZ$$wj+u&@@kh>/9@p*je%%Rk1TMEIG/D>t/HjmXckTHFBZCF8et+BFtAeubL
/bcll? #IDdGc\:Jl#<uENn\P:#Z^$tS<Z6&SGk6!YLjb\%K1MP:RMPT^RMR6FBYPH/uHSLYlmJ9^Wa&IdYqbQu
Xq*BNi b>eb/>#cS4dHDuwmtEQAHYL96Kn=XXFD\F=4lXFlNw1J/mt&Y>BPD^6dljHpGC%G>hy1W%whGbT6\yR\
8qJKdQ p^^GYTdiclnpTw$h4$55QS$GcmZuk88TTE:BbKelqeQwC6@JQGT@V?nS<Pm5!R8=meWnc6$a@EI\KAtp
eZ+J55 %nLkhHjDI9Rah<II6dZEkS:p!@mlddDqi\<XEnX1%+w5T@@pB<tVw?&dcGBCtY1#^D5d#\?pn+JuVlZ6
T+iK*% nSi*:yjTXkYl*<cQicXKhqi/<u+%E1a$LDACinY!wRadj6J&#*@4^Wm5%Sl&8LLkbt9j8W<>N!llaj<m
P#ep@h pd:L9Gt<^c:?Hw9^:QHnSEaNL@5@:GeTupYkRmdRnp^eEei1at416/H:wW+9Jpnabj!h:<w6tu$!Ipy%
5Hpcyn Y*?48!WHQaAGKBDR^LBJKlRIVC>?dP@Zh?c\6*W6@>6K*6%DdRH:6tWV<khy%+RG+tcjdtIKXHkb$j:J
w6Kqjw 8FaqZ5NY$qj5HwwA:?an9u8HQSH!L<6C%tcSWXGpkR*CkpeLm:h^Q!qEBcl>RwSQPC%GPTXqELy:&K+y
dMqPkG X=Zj\j<Y6VTE%8!>h\*%8T/YpqT<y5965\6+//dn<h8W^XCWM/k8X>5:ZB9:*uklJ/Ech*GM>IM5W4Hm
c5FQ8R Id$Jlkp9GBhduD=b4cYVy!@^XtPj$4l8K6/Kbyubp8I86K^D*pw#WW<ipJJMF!JDuF:&\VA&^L*FK95<
?FRGu5 C8K5+6RJ4k98:MjL#jj1@&HA*iBRQnDSG4LZSqq/1pJyBFRRL4*w=aT^D&lRt$XST9JZmVYbt6tGAwX=
C4/clj VFp=4nQTRNuM1>VE:uw!@*E#*E&I8b?t?C!JVwP%WF>DdFScSH+CS%NN:p5wXD/JN1@D6mCEH#=aZm^E
:kw5yl T<>a?dApX1!dR!6!CS*my@#R:y%*NXM$k*qmmQT\+6te+biHn#SMR>C!m?PSp+#y$cdDTujM5p$6*i@G
t+e8k9 Si1ahu9TuT=4?kKIX:\/cW8acR?4EC!jVAb/e:6V?Q&Bym%*C*I@<YqTJ!Q+CP^!G?IEu>@dScMPGmRZ
KwEK:l %q<Yd4jw4MjjX1XY9bXSuktRuy$MV9@E6*T<=X&wDFeqZL#B/BDPBY4NVJpM>L=Z\mjB$*WkY65TdGWj
^:%K\: C!<w9!QXha5Sn#=KyWdiW:&l$tCXGy/*6#@M1m>>PtF/P/ipJX!TjjNdH=XMPMuy+\EVe#4TDAHlYu$5
&yLPn$ uFCIX5ZuqJjkRKBa#<Fk/V5mZ4tCm1<kPjK#mal8XHMLh&w\W\iJnaCnWVFCE$6ul\$8IckI:#?VYDE*
IRaiRX @EMu1aV9i5<5mNW>ycVM5EZYdEdD9Kt=GumKqH9b8$Hhhm6QCDnM:/ZBc=>j@1Sj58\YTnaXnb$4Q/!p
SupV+F CDYb6+m8L>R+>8lLd@A#$84@ypM4dq@<VXiy*P\a1ZFjIbRGaChn+/+X?RM8TAlwGL?dFpy\iD$nCyyi
/9*tX9 @wHMwmR%tbYDRPDVl\MX%#NwlnkqXAZSXd/htQPy+ap%m!FcJa*wdX4ZM=9KcPJZ8k#%lpE$5wauyIY1
Ft@Vad @YFn<n9ID**cSaT^ZRltDLXKiahkmX=DTC8teP<<AyI#4DWMGM+A>^XWX\b&hG\pA!q&j4bcNw@1*P8t
RE^wT6 N+@\nh8I^d*j5H1D@&LtRXi#CMAZY:#/$B=WbbX?><Q1GW@JYqleclV+WF5i4a<y&Jy@AuQBkCewV\t8
jae9pS TYwF&iWp&ne1FY!yDbTZ6QapG%TymbIRcL&mq#l5WTcLeHmdpYJE^tiF/c<:!C6pR>Bcj:4@\9pXJPlP
cBkbYj Q5t%%AeEhSYwCu&L\1kQ!laQNbtZT#RN/lqRBFSXmQKL%XVwkh<we\:eTP>DCpnR59bM%c&Jn#JpkPbu
LHKSPF *cnkKB:&t%VWkt#nk^>T%*9YTD/hb:#5*+jJ&RcWnWh#E%^9R^m#j@^+MEVqDNw+t1nPML%^GEXp8WEk
ku8!!> >mGd?u:KR&SZih5K#Y/yi?4#Hy@H^*bk1hCF\4KuP%pWY4+K^9idYZZk^M?M8E$m&?teNTtN>bcWcYKT
@ImuBT QE>!d#8V$q4QkwcWl>!9LhQ8\ZPbSQpdui!ND9n/W+lM+I=i#A$X9ADB9PuEJ\QdiQiXM1y8DCq/l6Tp
n?HGNM %LY6GSTcVLwKiDW*dDuSpiBFV5MyY=^L6KYNG#KV%WepCX1u1l14!^:^6<*e=+?*MX?+u=LN6=WqFYNy
F$LF>P ?bYL#j?GJBZZB=&5X$R<C:+:GV!*p$uA&$\4F&?i<=DBSmmDu\4<aGA/GH=Em%l!:6=>>qmTe?>^ha&c
JG+9%D %Zh/+V8EJLXSC>DY>=@Nq^%la<iBA?Q$hdLy>*qBPp?iAF!DYN\4EF@&De!GW4ku%=:/Yh/e@9ywe1Ty
Pt<9#N TP*\5$9@LddYBhyR%l<h/i=nAu#?$AMqHD49AePE6N6C4?yI/F@VeqlF&?F<F@8\X@:Y*K*RjNFYuw6j
b9W>LI #=5dcLRMJlCK#1u+&u9i?uK%bL4mmIHq8iqdQHZuD#P/*4KY4>Ij>@h!!t\d&V&NN:S:M^D+mZ>^b9id
A=F%lN $Nt\+A@?L$RPmcRRPMu<>^CjHjIMbFX6qqMC#kA9yK4R1A?N:LYA^T+?m1S4CY69&Rq>J>i/b\jh4:#a
-AP&TQ 000efd8456200110333 Page 183 of binaries1.zip
Vd*u9V !#$D^AEP1$lpw9\QmLEH/I\*#yIHi&#+MVl>GE5Cb&mYC+pPnp$jG<u<\PJu\ydC&Q*CqepV>4MVb+PV
jppXTn hibD<nM>hd9FM49#WH+Wt>nTMQ\M=?PbQPp%wimj=mS\=^Ve8Dbm@?F91$!Y/5Zj:R!?^4iiX<WR^#X4
V<9a*Z tQSjWLCQ&Zm$^@Z*=Ldin:yan>6Fl$yaYe<CCt:cYCwtY!+p4l!DR6GB1F%4q+!#k6*cRm%:5@M9t+$9
<d%R$N X:F/$8QGHI8c4i?yC$$$%!:MXF+FW@LR+JhD!4ilDwhRl%QL8AJ1Tm4*@Mtu4C&<bSjI$uSk5WNq:!J&
LV8/p/ DRnD@ac:<=nI$Z?QdQihpDw?/R><FP&l:BtkY1$Qk\&Qp!LI^^^lVA+wuIA%JaB<ZTcI:+GLF+Lbutuj
*qq+Hd j/a/?DlilH9@:DE9hL9Cla#MeFGw&WEqEqKyV/qIMlqN5SPbeK%GBNuq=%i$CC^VHB>8j#WENXGB#Kn%
/Pdl1i 4:BjiHWhd/n1Ray$Aph>ywX@GqVK\pe#AyEtt$:>jkMYL>nQL<Ij*ZTJ=^>NQ8t6@4JumhQNihwy@^Xp
!T1mM/ EBDuyRty@4wZYEjSyKuB@ZI5645ctnP&8L9JSl/E&a8Ai!qclQBqq*NZ4+>Mt*TPi4FB*PKR8<+1N%XP
6NcJq8 P$m<Qt>GC@q9?yqnkS4?ymPt*Dna8YH9WPL8cPiFX/X9eKDS&=T+VhZn5i9N<SR$qK4<Q&6^>QjcTEdJ
1W\TZw ^9*:Ha6NIBYy!P:Zk8+MQ>R<5yRulh$Mi/JP^TK>ZmwAhcK<DZwypE:S\eYeZ$9>lBWh!wnR66nQkq&T
\*KnVE CN+m\RJc8+1Nc^H!wW:%G6GB/K$uCDaciFV9k+IGWjbBk=ZHqIwSlAL=1Scn%uJE815NPF&KCI/+&$4^
F^y:Jh 666C=J&TT+N=mNyd8Dc5SRuA=lA@EAi4\I4HMP4abw\hNIbkJkw*StLupIdCuLjFp+bVahQAA*adK^LH
P5Xw?= ^PSh%>Se+a#baBFFF>uikq6R5/?E&&T%R>qbG>m=JH:WCkcJ/a+*$bAqCDayDkhaiu<kDm<\u:MKuTAZ
NbEu8Z 8M%^JHW>YJLIcaw5HK$dptF$MCe@I5<%*9$=ajXh91Rbq=EjJ^ucEy8*<NF5hSnpQ&8k!A<M#wiFiFT4
ye9e#Z 9QyySW$ZBEN=^GbZFP1GkX<^S<=8<NcGZ%eMF+F9&dWS<jb6SaQAlYidcB@ee@?INlcA#ZPQ$ZmWmbH5
mLeq$c GcyWJ!JWI4A%k!n/CFd^1wkL1^/Nda*Se%nVSdqPt\>=RaLE$WpG?WV%Kh*6c/4#:$jPw=S<&1IDaTGS
l:&!j^ L<kpa*NZZ/^Z6^Piyq8S9i11X\=q<9eW%e#8V6cYTJt!$q^^miG*eZY!$epnkyRkM@wetw/c?Z5*R@E^
duh6#L cTZB8l9I!ItLJ\&R!VZk:Pw\WiENQSh<I=9RSp%MFMF<G5w:luqD1&IccVIj\:^Gn?<5R>Wn+*Ku@hB5
CV+4dQ KwE&c$4\=et4WCDJXE\HNMwCdbNwDDQwKPCFyRI^SYilmq$c=G4<wGd%mI6iT?pZ1#Fm4j$XHLeMhma6
uiMNuR P+k$Vq+=dCp&JWYn/td8X?lcpp6*%@9$pB$wWk$wKp!@D>c>Y:YD/?ZSmQK#R1MhXmRCJ9e6J>N%X*Z<
aA5m5w 6%=b>G<a8kC@:M<qKbeHI/=SyuybF!kw%&?8Npcy5*=Z6=EPWIL9wH!YC&@aLm6aE?$cc!$KW::Su^mF
1>h#C+ %FZK$#dKi:He>PK$<^mG>:c8CSc^CnyAKp9ZlkWZ%V!%TSID*PnmTbL#l@9nWVIe$8*LJ5NpyS%piYnh
VN*Gm5 %CZBhjAPh^=h/QB&Ai5>>#qqReM9*M^*uBS%9?IH:N=*eTyhH9?5n=SeL*8%QPSSq#\>LTl@n1<#R&dX
mbbKW# 1C9ml/?1^bF\1#K#et%*ltT^yq#d^hFqWbSDwlbut8Dt56Q\J9Y$H@PRB@R45%QB:h!t^#T:*y:eXu$5
l9DVK6 Jl%mSywGJWy*NQtpd:Q4KXjjj=!W4mu$\:Hp1:8:ZthjcIt$+&Na1pdJ<XDElhGKK4ID/KYTCSQlH=5J
%GaY&$ Dd#?B/T9FXJI=tNDKY94t!%/>tpkPtVN+*GKEWL5#8NS\W9u$mL@Zud<9:Y8@9jt=D>SX+9?am+6e9Y=
TB8KVY 6Mk9=>Im9%A^@<5S4%R+@$LF@Ghw+c9Rq^ZP9%A^@^pchkZ/$5L=F!4tQ$Mn4pJjXnn@R5Z<b&nSK>B\
T\=%Ym pW8K8F?wtQ<MjbY5\eR9Kb^F4yI%tNkq%^c=T6bk<M88Dj$6?mybk%&mkSaSkj<YjbY5RT<>8el9$XjJ
mK@B/y &8Y%4el@uA*@A@=Qc>6@LIZ@X69?TtA6I9LL&jBj9wn@P^8?+t\aGa\XwLeQqR$Mc*b@<jY#Z?bB<ncG
RPN?ey ?i&Zb:6RWNWTBl+#54RLn*Xi5AGV^aRdjG?IC>1X8L9@TJXWlL\cI\nRADKTA9bcDZ/Rqb>l+G$!$u$$
*6&?k< \Iw!y*WB$1dbYHb%hleGb6NI?T#&c/ZHQ&5e:HJ8*nZSFPPM!KW?w\<hQePM>LQcK+Bk?$#c+Qwa1qhk
5wI/c$ SQm^^AhSemc%#K4T/tJY^ddAMja?=<E<eM8T!Vw<>ly/E^:6*G5PkV9/:w1&Ch@G$IaIiHjh^X^#8AWw
#DVblA aEGcK/DGp96=CdDRX+M\LAdDAyjyWB+bPXw*wA@B8!hFFSYk!4@PWXQ:h=<%X$A?@1B1hLEl*X*+$1\\
VhZdq\ WJkyn/:l+NGZi%1tMTnbWJpGDH8IkHR+/#8I:#Y1pHkElpQPLW19m+A&JB>MFER$kN8=+#%kA@CpTdtF
5\y:a: %XLE*IchwPJHR+RF&5FpiALJybPahmM\/Bw/n^bb\%A/p>jYwTAXpphLV/S>BG*yIwSy?\^\\WI$@iad
le^Bl9 =G#P?FtpneCVi4F<6HA//GP1MSjj=ypPV?R=ZYiDnwbW&$6Pp=p+4Si=p#c\::bWu#LMQ%N%I=DCd4Lc
RLXWiZ 6KFk4j:!u=DXL>InmhcR*ae$hei$XN<*eqB9LB9&Xjc1X&Z!XeAdqFHjqRjDWeImVjw$6LRN+Ph=tm4:
#H:%N5 bd5T+?Tb$a\D%BTDQ%&j5j<BSP8=%W@Y:V*ZXEc/k:>48PnljibitKCaiNi/bDI^*9JR#IJ^%HBI\dIj
PYltt\ i6y:yp&l?tq54K1b@Y#jQjt&l8h+>FHRaX\Y!G%?*6nl#qHXe:1LFqM9/P98<9d*%NMy6iXu\t$bV^DN
TepZZ@ I:J:c5Mmilm8h*HylV#9IwAF=Mynaly&pySCY%Ij/FHI:?RBS$CbEuIiBG5Y^wjPth<YLn#q@W*:@JtF
Vh#<J\ iy6tqqh$<ZQYJ?+tubM5#DdH<Y+Wu1$L*>5W^h/1B?dK15d+em?VqRR<C=CKnNB=/^JhdnSiJ##mHhA/
E=!cGu jiibVFP:=5CRiXa4ln=iD6iQ<!$6R<mkHY/mF5E%PydPcp^h%G%:*8IdV?uTa>QX*\V:1JWE<VK*4>Di
6l*QdQ Jw5ccBEY+VJka8P#RBA=Y4?n%1C:cd1996=CpMI?*MN!*1KH*=DAC1eq\Zldk*1%^%pYNl%pIy@aDQWN
k\*B@S 5mA+&Kp9BI#Cc\n4Z4Q:Y=Swc=QhPd56/l8RR1FKLDTblS6T@bICSyyAt6LP/#>:R<PHI!qllcJltcpW
lNIcAi V<>TJF:kdT@HC+4wBWhEBA1@@YGcWHKp5CP%$115%&LYyH:&$!>D^htuABDn\+1$pBlyD64ACNZeBFBP
?+B$W$ w^$C44#*McqNEth$Wt%qm$+Q#jY$tPq4KjNmcb55V!J5HyMa6t4D>d+kRHGRAK*JH&+q#W&&Zp*Qu&!Y
<1V%i9 4$yDR$D&itcW&tKXIjAd61mL9HSq@TV:*1!E5?M68RauqanFlwK>SBq&AJLcPCBj5t=Im/C#MK*h<d1p
$>mQ!\ I@:*:Nqhi&!W5R6F>quLp6yd\<Py9P:+&ZF=W#d5SWhP\4ia\9Sd#AHB\a<Jh/mH#@MbP:KhW\8VSiRM
?Kt+HE NEEdllKFKIQK%p$dH<ahe<>wqph\E#9:GVNnEGjES>cZmZ6GN^nh!HcC\mk&w@l=#=BX+uT*i#!/d?VX
y?I5<e 8jcKjb>w\Q^lM%u81ElQ\4KTDcL\%yQm#humN5GAKQalicj>K6!S1X?wIk4SPkSL6*9TVLhD&D%JD>X:
+EC&dX ^8@j6!Bi9/5hDRuDYdAytGB*CY&BQV$6u?Y9P$khnIhYSiTb$pa?IcPT/c:Y>Z:*jp:Q=K5@jT=t<N&u
q:ba@l M+R6&V=$QkPQbPL:hSpEB?H6PmNTB>Cp&Xjb5WEWVDlLjN9ImZ85!pj!W>4!F&\$RWCRXm:hC:eDYTDH
M5<GHQ 1BR+q:1ERqMctM9J*VYaNWSV+Dip%m$A#kY1MlRVe6kqa@1%!9$%Q^cM?KY*5P:&VQ$RKViF<$J:>pA=
YTCP\? dbPmeX=yKd!:XhPp4LKXd/W?FG>GLDTwE?T$td*yudTj\yKu1*eSX5L@\BcQ%ZVIyHltyZ#!&?+k>=B9
<J\!$h Pd\6WX%eJbQ%Xt*1dClac!8KtV5q^nHmjeVkH6WCh!8j!BHE<?hLJ@mV59h*VbC$1ATb>tLb\t#E!tSL
^A@NdC 8@p+Z:WRD@<eI8%Gl#5i#:edYuaIS1pd:hi#!qp*!?6YD$ci^$6/dZD*FYlRc=X!lheulFENkdiD!q*J
mHY*@a Kq!=54\iC:ujBGk1qc/!yyJK8qkMimuNJ*DN\i$bpmDcJJSeYSJempGF5@A*><VtR8X6KCM%QAhk#4CR
1mY^hJ Hbn/5:ktZ9uTYcKSX!qMFRdESPN994Y?>Sw*5:PS:MXIZnh4VP=Ya6SPhEySjG9&+Q1HFPRQRVn#IPLn
SKDYW1 pQ4bFHVJ&#*Y%6G>pD#paBp*J%B4Z$$cb@ud<u%#tTq=bulTa\Kl=$+X^R:D?+W^:t!<a*yK*:ij/!tt
@n1$1Y lDNip=h?Y&N4CA$QWhRBu4BT!&!C+:RMQ$XTu%11#+pw#yi\bu*Sk&lHN4%eVu#jd:4TY:ah&J#btp>b
i^\t/e C>jY6:qVmRe^y+*l%ASMbbD9X1@VP$eYNHYuYnXP>:?%&G1&e\pMPPuR!KAKhe$%EkA%@ZGntTM4/emp
DIXJu^ +apTAdI$lddLC@y%iGD:N1=%@?=^c@cN+/&+TZk&bLj$IcmRV*B^>dnPR\lF$%9th<Im1@H51\c=jIqF
nHb#XA %lqn85ekYVeHZV$Ia#^eR@S8IR8+d8>mVumYSSXXWIkJ?ubmYj&bDWP>*dq*\*ndk:Mu9Jcp<^H%pBW&
:%*mVG 8w&\K1bqj#uV8FN4aZAjlcI>+e$ELVj@YFb&m$^@Y+B#^6t64$+WK5@\LFVS6M9DHE<^T\B?#PMZ^>=y
uqCdQ5 ^$?HLPh%5>A/1ldF&d?JLDa=mEV?$iQ%a4WI6*5@J!J!E?Y986u>yayJc$*^1AykHKL&a\XbktFGlD1+
+BV^<Z ER%KlTVc:kV8DRet:W&chttR>GIe4G+RYj%WYRi?:RpGLb1NFCF@wA5S1:ZYbd1pEEbTi!:mVkt6#ZSL
E84N9j HpYXQRq6jHb6<uGu@YESCl=RVKDu?14TQ6LNHQ&#tHW8cHb^XF=y?+A!yw/M%Xh!b@<LQ9NcQ\Kwt8t4
aGPPah 5Idjt#@Qlq$A6PSRVB8/MFRX$qB\N\?W4KwRG*#!Z!h#\pH69/Zl6pNYK5yHL1+A$*8m9ZahekmDbn9^
a/@WED %R!5FIM:MK96ybJ&9y*+ub>*il8/8lFd4aCPZaNkbee?*m<nT#SLl=p%tHHB=jGk^X!8t!hl*k<&jQ\I
bI6eK9 #b=&GERMJ&+4A$4#XwH^<G@lbk@n5!mJAb5Fmle<!%lPcpc&I^\$B4R\VM::5d6@wah5wYC^le9<LS&B
cqF49p @%h#5Z+VP&*!ayR>P<w=HCVpI&t96n%$YBeFRW8QXuWapbRbBK>#T&+bTHKWi*DFJ8T4?bRy/6e1b=49
:>6QBp :tqA9?GVcKq+j?Pne6>M4#yWp:Tm?ldBH%Zta:ItI4MX/1pi\eHjjD4EZ6uqA$8WA^bHtt\Jut?RubPe
-A4\QL 000c19d568f00110333 Page 184 of binaries1.zip
ti1Jey @uTIj1u1%JI\\X^G<ewi<BQ1XKP$Pu1+YL&YPkXbiPk\hdN/+V5&?8HAdCu=wAH:VcKijRP&Da+Fni9M
9Wt&RL +PZB=B+%Lc%FH%&=!bY^jk9y=@%h@S4+?CKAZAVPkpyE5^XJ:JiPi@!8AQ&i>J&cB!!L=Z*Dl6cS4P4e
!qh^w& YuAHPm%FA&M=k\j5Q@DmMyja%Rb*?n5eV1:6yRkwdmdbTTKCMM$+F5?lZkb5^mLBE85lY/LWmy?ed?HJ
$n=Edq 4Z+a<u4lZt6upZ5@!TtntQy&LCpjba?IMFm#6S*whHMB%P6YS!@e4*?>W5hA#WC^A=#LuItIiTHTV/VT
yYG<lu ni/n9mhFdVJu^$bFeVM$YBbk&!Y%wkWHE%MN4YyJF>y^B6A1w^l+M\l\$llZqY&XMCt>?iTE*9Pq*?kK
W:!:$5 4wpGh+G69bVbydp/tbw%5B5t<&@Gi>lW4eEW<G&qXjYh!SeeaA9@FX4*!c>pltKq4ESl#A/J!uqKmq>C
KStInZ PDEL<Y?CQw6u#%d#^lKWX^yAKDLkha^YAcKq*Qy%*p?/NJX4q\*+c$5<MEFkJAmjX*>l&NXYH5MH*!E1
XYmHRI h/Z&TVVj@eGH:%EjLEP+&D!PL!@ISml6inhQ:AtSmpC$@BbAT&=TVp\Aj/m@%*Nyn/^/Z:c\=$:e@KM+
n%qbQp iZkRYtb4$eL!k:D%I4IaJ!XQH+TJIw1W$+ybqXtLNjJjQ5w#Il6kwi:XJPY+PSkKphtSB4l:/N6ZH5jE
#=54:b b44$G/X+m\A59mWTcc*tt@M!>bPt@kHeNF:FHT+E#18eD@jG+eP6ACdbB>R?\IE65iIt^EJ$C*WWS4=^
lEp%Q5 8JCRPy#dYKXR4u#ccP4$Ba!mIY>Q*6/pa1%P?Pm?FLj*iK\JLB#u5FIRtG&k6nE4M=/J=ikST6JutcSp
%KM#K5 Dj/a!%<IYF1Fw:4Wqbm%\d6?\6#q?>p!HGSGk=N&AN#y56\Q/wK^I\W/%Sl>l#ITa5WjA=D!L6b5%DhD
Xp8e<h iW^RKXK&54EW6Wdl?jSP%I11I<+&9qyHmaHJtLy?PNABW/ZEe<%<1qF#<5JpQWXjMR/t5lmK<bNT&S+8
:RCP1y 8m>l#h&$V<BQmV%j>hVWlG@F9pZIC^w=hA+ZdmPA9GQ=8cdRh#aEQ+hJmS\e4$q+VtqTnnnK%&k1$&K*
KcQT:S !YAl<%LeHYKNu<mIFk/5lF#=/5?%X4RjALG16MDGdahEwyqTyLHZ5Vt%6pMlERFRYM<@A<k<=akQSPAp
ZwhQLT w:DtdAnwaQatWH9bKQTh4W*W4Rk&C*\1I!W#bGiiN@6Qpl/wMbLD$mZDd#w:tFdHi4%TmlqD!G<Y8Zl5
4kuNYt #udyEqn$9<<TYQT@8kV?lhFb=PyGb=FjG=%FjtE&@yenZ1pe@aZb?M@R<K9Rq=YE9#Ad@^qc=A4$yiZw
DVe+tB L<#Gj+aY8\y>!S$XSZ=lN9+V>C@M^9>MZ%1P@5J5@Gjw1&RNj8uJaXimL<tc&FY!B49$=Injw1?T6W9L
pQtG69 WVHS*/K9pnWw+nJc@Hhw<c6p:jJ1>b@M^9?A@>N1XiVjLGJFlTG@1Fb@bVcGmeGE@?e9au9@J=mNM$WJ
pI5E6K ?K5^+^YtDpn/EL\*6A*hDwP^aBDyBBke/4aEwEeu=JpS@F%MZG*HhGeVW5\1b^4w!e*@X#F^ZSAePXKq
5Ti@M@ aXlMS+BHy$pVG?W^C?<5i%+<GB4>tB&MtY!jpRFwMYN8E@C9+DjWWByeDA+p?J\JC@A6#I/QP9B4mtCF
?+tX\S +dN>!K%6JBnWeb8IWdllW9G6VLLhJ#Qlc<@jG?mq*I%<QS*%mS+D1F&ScAG^6Z?mtd5tJ#<aPmlkXV?d
e5pqLM CuJ:QXnlP@<9A>pS><*PYtWE\<jJWi!!:DCe>lFSi\$X5FLMyJ^:AQ!S1mDCeDd1TD!MkJct6*%ePHmA
Bl>lF# Y5C4Atd?/mAc&d/wX*wmd@G1+B!MSJmLmSHA4cn=Xqtp:!XYCTM1Z!*tei6NcH=d?aQ&Qn%BlcW%Yme5
Kc+W&L y::iZPHBZ&i^wFDSk9$/WIXA8QmRA*iH1hT*kn+S8LQna<y65FWDLhuVm!=H4Vh*Z195WNJPk6<uX6Cu
pNbByW P:M+9lcaycS^jRphZ/%4StX5$hS9!<R:K8%V=c+y:y=!$ZWC>BX\JNB<H*WX*GGPJb$cdjapmKG=&CLP
@BJ1XX <t6ND<61A/R#*1wEKwcCK<\Y5Ne>aeFPL+yK6\Q*l@j?bZY:NR%k1Jjpi9?R64q?$Xii9>k%y\#La8#K
ck>aqe @HuT:5d^emdZQNQPHi/jB8>KV@dQN1DHula/ZALCil&K*&u8cbl@b!\\TEE9CRlbHu\wG=%u9LjADTiS
u5w^tD cZnKtt*Ru1F6TBdjI%%\5@eF5S@TCRMYu>\qaib=:8mpbCk>RYR\FjAeTt:T!>&D5VK=aHPSS\#J%Ji?
#ZZ!qt jw=ud:5?>bt^j4YbQKCIpG>M<p=:d9a%ccSZ>JkkDFj9/bT$l#X#u!CD#t1qemAj68BA4XW5pX=4/*9p
%#+<ua AM+kl>WhP>p<L=YAZwq8dbj==@aY?5R%H<4NtR$Y=E+CbMd5!81I:GR#VFGt\=Iw?PTiReJ>9wW&5ne+
duJX:p pac1!9p\Q1N4HB*TEXquAmySFiGh%jMF+?Iq5XWtjdVXE%!MXMYC@QFhLiDFjiIDkZCq=W!pQ8*d#?+w
hh#uXT hJp<Q=:P<$>Qe/PBk\Yh<PpIINk$ZT<kSRFmK=n!>BtHGaXHP+^VQ1Wn?nybie4VRT8*YT5aPMMBA4:h
ZAyX!c b:k*pYEtS5Th<8L/CCY:B89DkYZ8/#wZ#$mSGdw=LtA?5K/pVJ/M&Ec6JY$hBET/<MAu6IA1CH6tpVt?
e4Pw6T ?KDt&pPp8F&Ylh&6#K:tWh1Z<:6Wd#!EApdj*R%V@nqJVbhjcnPa<XRcyKJ9p+IyqkCe1<9ltVe>1H$4
*E1#+? *tIhKd%i99<\<a69KL$$KMZG$=!:Imd%TNuwI!tVeHFd+4nZA<:TnFIu:lTQ6NJ+En4pDJTw*Zc1K:t6
\eyG#p DJ+CT%K:u%:!mIM^T1=<pwicIZ%AKEwMp<WlQStG$$?99iKqV\I6KH@RkiJ+eh$#4yahREh4tlYEY%cy
nWA+\G B8LwpS=iuy5C8NySme*ejDwF$pC/XEV4$>4M!@Rd8wS#SmC@K>t8mtMkXh>?CweT/nHJyd8Xdd!:S!1S
+j!bPc d\!MiBn^a=dR\PnyZDp6nFiY9qCd45D<pBMYpH?ZLpu=*k^n4I?XYqI=/kd?i^KB:CkYM#:TS^\:>SC>
RAutST JD@Li8&M%1epLAlBD<cPi\d48pSP=4!1ntqVHjhujb/BTLWa1=Fn9pL*^yywXAMM4?5KjLd:Bm#ZeK&&
kq<<>X HTIudlj#nTPYtQkcl:&yliL4nJA!ySw!tw=\Ewy^thDBGeQLAAG/CqQhY$RDZ>^pY%jHj1DTR8FyLBcd
9KkF@y Qk<jdA?e/^@DVtGiqW<:9@TpV=KS4WcIZJ5VdZ4Gt\:ni/1GmP8in1S*G4!FtbK6p>/<pc^>byulSY68
8?A5LK =cCd6twdR6bIaK^Vn+\ei^HG+W4\eLbw=5+A+lb1QMCc$<ekp4+m^aXnKAym9$KnM5+YIE+pQqwp!:k#
c:jPRa SiZR8n*B$cMl^mV*+1EAG=+E+!*4?#\l>ZP<\&<j!>Q6QK:ZTyH+&IP#\jl<!qP9$IDlybm%1piWVN5R
nuwlA* N4w1j6q5?/t9R$EqZ4456/LnRBPp?l=y+RYMH:I1:n*^inuF$N9:?Jw%/yCJjnCN51DS\wWM5&iQ:?D\
ei4I\l #YXZa1V4D8QTEnlntBT8^R6%KAZ46Kw*u4hWEtA?4dP*=^l>A\::j?ceJ:Y=X9QeHh\?C8bIZmyu%Vb<
chTX9C 5<uTF58h5j8EwZYG9c5L&bVmZWTMenIQdhTdV>m$=ncP$I&TC1q1Ed*AWa%5Lcb9uS1Cl*=jZA99Zm6a
AR/4j6 MnQYaK&JdSYjQePT$A?\8#6MR&8?H1kIyIc/9u?:#TdT\eJw1LuA!$An=+W51tn94QuTn^@/FV^*ZlIZ
6p$nZ> qV&p1jiD\KLi+NYa#u%a*%5c4m@QyGchIZGhEi#SaGyVWGlW=<FVmLFYtd9LC/1cnQRd%lh*F^bXP>?l
4<L>?k PcQYDGVjHnTkJ<@J&Y!KBG/@wHMkaHXecn!hQ44#kJI<lIkpnW%F$I5:9IW&RuGE>AD>Mn&jjq#Ki$lC
9H6C5Y ^Dh*SIk!Fdh$t/*5P@JNYnH6E1uwWWKA5GDK/NqV$aMyw+$pbYFid*Fc=X!pLaKPddTk5@@EKdEH\XI6
Zqd+pb G8y!yFbVPh6D*bKNF\SZ*$bidKP*yF*$\y?@=wKwBC9Dh:^!kph6kd*nuH1^>49tJj/JCp\PKwtY^R&+
<qh&c1 GDKlEJ9ZjLYA=XjN*eCk>nM9Y*lTeTdRbPYc*R/ARP^<!E66CClQICm+iIL9n!HyHFWJ$aq*8cqFRRy\
@+FP8B NpTGM!*a>Qe:cGtWCCLNVHIhVw8FLLRkkDh:!/1Bl/P=l&6e55yll^yDJNwhDAA4XmnFaHTanY4<cFpB
8IwPnK =K^4h49*ZM<@WduC>^Hy1XY\!h5X@/c6y!CBW9qBiQii+TpQZEL&KWpXmShPh5K8KwF56q:EYebC6n8=
il%p@m e5cPqXcj9\iiYFCHJtZ*K4wTnh44I?6mcN4\?\ay*tD4Dq<#Ie+*ekMMI6uYwj:aE>X=%lGna4IEHH:F
jLAWuY n=B\wZm!!e41k!FBAncT:\qS8DatCP:1bW:Bq^S^BQ5R=\WDtH?9RhWFKq/Puw*w6i\cCdhJtWbqKX>/
T4ptLh wk9eJESRXZkCWFX=\Fjwp=APm?PEJZAiLPSdLGCI&n>1lDuVcQnaJhDKLRjC6^NSdmTATA>NIu6\:4SH
&<IF>J MY+/#tb:ncADi:GAw?EaTZX@iPc$4aRDqDpm!1\lBKmJwS95!tJhnV?!>JG*M4/&1blPnmQknB<YFj#a
&$6kqW %XB8m<qJkIA+<M^N+*pRe9byaiCiw6W?+YtDla+%SF1XPJHM1mYjFJ:ec<&NB+Vuu8pycXqAk+W4$X86
n4:E#8 yniDmQ!G+jX!JIMCh*tq5WLSS=!DN#i\AGNPh&w5E*1FVp<Shi%\nS&4ye9?/pF\y%:EwV#^VcR4e>*/
NT#!mh uKp=ET^\$+F4jWcS6bSm$#AIT$4wLW@5m!kRb8#!mVbuj^%Q>?R9u>t%%/R9R/6u9>>pnaL4MaZba+11
kS?qRb 5+/hyqP=Hl!:4<TlmYVTR@kehB1D&^mdX^Mp/\J:<mbqi+APRmHPJNHl+WipXa\nT\IXH/+LuSb6i?XS
?W!591 ALV\c59Zy%$IJcwKwh5%@VDK&>iYNWZZpbEP\$KnH>?w1iq%>n99AtjpSTIn:>:WZB\IQC6eia\#eeRY
i>@#=A iNw1QIDQnLuZ\/qQ8ua*8BLJEh=i@yt?CFewmIWb?J$tYntC/LqiNG&#jLmkye:!\KAP14RKb^\$eN=t
8M%i58 mV*QS*i^eh/*=C!*tC*i^A<lMLQAZT%S/Y$Luk5q4HY&mkTFFCBL*$18Li1FNCMH$kY6mSbDPlTZVWpJ
9nZAQT P8REw\T/m#<K#uYFHV/1#B#dKNcPWk/%l/P5DKKSw\Z6H%ZC/DcQ9bD8iuMd+$W>w^&dV&THhmAPRG*y
tBJGNP 8iSNbcF+mNMKBFM5CGKinR58QS^#?WN4IVXBV^FYP</8k^tihIJYeIeWP8#QC9Vu85N&q*5YXt*t#SQk
jB5<j8 11GthNkbZI<:tt:X/a6l1MBRXi\d*9EG4aEF?C4EyECK6*WNT@n6h1F5yIpy@SREt?*P68KCcknDD6FY
uIE$Fy NTnD1j&kA@nLW>n:Jl1eBb>J*HB4HD9+CZ^u=GhWRkjahu#HR8L>lwlB5h5Bk68NC/8PN6Zt8>>+CF!A
HYb^TE Au1lut8GG6%/B<1CH1<tXS\$w6A:p?&dbP$d/^YaAS?IM+C@hZ:Zd41?1:V8bE6LkjI?VJR^nQJ?teMn
\b<:@u W4T\<#8#QIDB<iTanlVAjWBqkAXN$4!!T4Se6aC$Bt?u:AeB5\n6?V>y&a%yVRaQ?I#ymJ%\#k8GmF#W
-A%NPR 0008c3cb54d00110333 Page 185 of binaries1.zip
ZYFKlP F^i:AID%#%Z>&+W+kYTA>LJPZVEZJupAHu&I#^5BicDPLj:pu?pd1e5NIQnah\YdEw$X9%ehh<1*^yM1
/5kl?$ B\lJ*ywZlFeW/qV5kK\cY&%=5:VmtP#6ASapVZ1lwi/XImtNwa?6DTN\XwP\jlt44c1l>*C:>P!6>@ZV
QN<B1A KMdMTZ^YEyj#eB/X%iF^/\S&6#<lhXpVqh^5nQeKuG/S@@tcjZ4G^Bc:QL64cZFBH85tD!/dPl^Y<w>$
kamJ:\ GMMh%qE8/>dEu!Xd??L%$mi/n%Lk=ApZ^^FZEePbE4HPXL^VG1>ZJJXNijD:WY5=DXZ>^MEJ&Y?IIK9L
6h6Qh> /6V@d+y>@@Ia!9#*Gitj4Fd@1=JjWYHwQ%Y4w5LCX/%Y@>E!@FN@<a9T/M1cZyFjTH:@DC%/Bj19N?V:
JbnJeD NT*&Y:V+FYm+?K>LI>FjTH:@DC%<BSwtLuwJDj$6GuaXGudb!iG@SX<qc>BLV!:!Y@SX5kc>>PSm9$Xj
I=AXHG JY8ZXw!m@>:!m@qZ?D?6GQ?6>FWW>k9y1?m@>j@?c<Ww?u@Zt%iZ9u+$?j?q>LXaRq$QQE\CmpcC=YZC
tEMm4y #apc5jpA5Ele8AWn4AJm^kR99&mnW%H%#Sl4TdA^t!TdwMBMK<6Ih+<NWk&mBEpDpKZe5LbpNDhyAN41
qT6$@W +#YXnH8M8Z%$Dk^lJLZ=9ETJh@IHaXnD#\TT*Mj#atRkMB*+HZZGc>HaBQ5DMqq\=#61&jHuNML9ewLS
GY*1m$ amII85@AWFZ9#^w1Ra>R/Icn*9!^lpZaCaVI/@b/T%W!/jEiAS:pM*Ew!=5DKqp<@qZcRd\!5%yq<y$!
F=^F4M q=aAi\X1/iuq#=y\PENGG6<&^1$MT!Xt!n=i95^@IcQ1&!jRnkj:kk>KTFypcDmD9@adXy><NV8eF+\@
EYq<6$ $\GjuIJ$pShA5tT9@/R/W$q!WA&BR%aRES^j!VTjlI:/h\WMWQm?+kbS&m@Tj/wK6*&8=>&L8T/X<\\n
=6cCI# IKZjLiR^/aN<uYl&VV=F6GQJ=XP&!CS#Me*h\Eeu%AbJPPP\NwT>pRkw1h1bb+WT4pZdRP?HFbFy+5dA
h\LW4d VebE>CahXNHp%Hy6Vm/#!<=l8LThHc<$hcSWu%^LRdcbu^j%J+YQ@4DWQNIkXBMZeY%waDJec#8ehXAh
TFI/RX Ry&J!5KhIX/q\Zbj//b<l*c8p@^Rhtq$8hMbYYapDM\VFGG$BytD\cw%C9c$ub>Te>+S+F%QtRCpA*ZJ
!e\tB6 VQh9a<VIYl/R$#:!tm5nRmc8wIl$1pNu8Bcd94+pWIuJ*V!*wbN$?Y+NQJu<dw%N*>499#FMMZqDn<T#
S6dt@\ WP5/H5F8Adq=q/H>D4qpjtEj^aCpY88aWXdii89VeS1=L>Y\Y9Q%Bp1I4XuSYF?%%*MTVX^&VVZ^wK#R
T5H!I8 BabQEFHbc^#>?NKS@91n*CElYlj<CDl+>EKMc*RnP<M@@Ipt94S5PP/NIM%>cqqtlN!8BE+4VJ\1BphS
ZAPmC6 l@8cP#ViLGA?meenZFWkT*+<:AX>q4ILV^WATdZWJt$65\8mB1\$99y+#+1A<pXpAYS<A<@n6l6wbbkD
NkuEhP mSqt+Th*pe:SXnVDjkW>!uywFWnWi&^RtceXHW8y\TDNYZPNYhlGTh+%Z#EjM@?e#TjA>MWEu1Xpi=6T
bJF@Sm eTB@NK^MJ=wE8%^u^i+>mb^pDpqB%/DYtT:p<Lh#9>#86mNbXd%FddRj+?8t!TPDy@n%Mi%5KcijpP@=
I+mny$ P@Q>u<TH6u1H&cWFI5c\cjbmC=6&*4/n$c$S<<tuJa:QJXNZ/#/YnTGJ\8t#tVE$Z&TP=iZnlZHjL>MH
S!EFH% &GmFpHtM6Jk4<HL$P!Hb#<WHp&V8JASpA$6@CL#BjH\*cjFXJTDpD+c9IGnmwaqBlP1KSkb/=?cTq=TK
hJSWyd =RPqyhtuqPea#T1ul+^I=uG/d@ucm1cmCCWJ\:GchIH\HBS*i:p9&kZG6VYNachZENZMPTHaik:Gu:Z^
\ZRa%? LX%HFbdTdcS&?ytZ8n+yDhX:Q8ZT9njpC$jVSC1MF1h?Xp@pJDMh?+IGa>K+B>y$/98iFeAQTVD?YL*i
*$^*cu y^dX:ylKVaNlc#St4ECeYuGIkTKR@b9?LE#=tVcnTJEI\e<^dS6jb6i1iuCMB166:I/MWyYMIqXGCn6G
DS=QQ& ZYZ#GA5NRLTG<NNyaE*IaqXX&ZlMCqN+51!Jl/$a?na#u4a/t=5Mul9TH699Bthwcm1Yj8R#9:9LJ+P?
!q6EX5 B9@BEFX8p?@#Tya&wq:FZ<M#$dZKVQqa9MuEKy$q>@@D*u9HSbX$:cLEql\dJBmRuPqMN!1TJhNETTI=
=AnG!9 b\EXWaqNS4KAmPTep+mJuDMImIlIBpFJIwb^L1m<*@9P&J:6=>^#9*6?=#j@:Jty6Xqh?/t16b=c>bTd
\tAbbN >DuP&SQL!hiZtN=WZX#b=MT6P=nM*WSw%!kSZ@Y^EYIWwGZYJe9md4#?pySYVTF>GF4InmHM&C:jPNX@
t?TAPM X&Y#D!J<5#VW9@M+u%lRp4&G9II9^1!c<$=yyu6#bbPXEP+YlinVFPuFRYPX86=wcMD>Fnl%@F!e\8:N
D<DASL 6T?yTmWLlcSN^T!u^=Z#lWBGVYh$X:YjX^T$mcY58%qLT!FAG!nF=J&up5L9$lSWb=:quMYXLjil!$Nd
Z^H!4j aMQ%apEMZdNWSb>b&&jQPKb/Y#@1H^>SJ*C<^lp9i%*A>Z%X\a$:hwV=n^lQTYAqhNXMYSP:*#Te=AHu
WC:A4p ^1W?dFJV<l%tC*>9p58pkE*k4E!#:<5e5SQqT=q=\Z%^Q1A@Z/WyuQh5T!+/lHFWS*KRiuWljMCjwYnK
eTH8Bl tJ*<%a1%ScK$Rw9Le8d=ZIJyuNd>ZF@W5<9Q+/DPM\?aG6aw%MSYB%KSpyMKwEiHn5>JychVY&1CNuNj
!Zd&Hk *?q/?B+Viia=WT!j:IdWe$p9=e84I^CS#jNpZ#:^KFJ%=*?/bIRm5E#IjiSuQCLJ54Fy>t4qYA=hFK<!
N5\SZ1 ?BLl9eDcw4F:RWHV%e%?hlmB\V8tjeuNSE>DTtHMq*h&BnX*4bd>6$$iu1tPkVnE<ZiNmV?$KHny8TdZ
CQwED> NW6#qu9t!Q$db?VJWtbPi684hJwENa/?8PL\VJy\=eE^K>Yk6W1yb+j1S<>aPW8?i@BPN9yp5K9X$e/X
<F$^j# ZDJY51qbeXXBl\hEaiy%4=l=$ldd#y&1&R*+KP=QQYBBe#qjY4/+STW4ak$*>8il+A^+p8Th^6^PucGn
PGiamV YNV=pyChwuGQ?#VeX^t<6!m&VXt>1@yd#4+&#c^uC&i:j5K<l=RRTq9y8Lw\NZ+^&I%tW?AhktZ$n$Gc
jh!y!t !=hTy@pENkiCi$pQ#+$NyL5:jGuk6!qRFWlu$d6l#6:$\Hl5?:l9dqlYeZJ4>eK4#8kt*DWh$nYcJ9Et
tEPGJB !+YqRD&c$lHLaQh&jybHbDQd8NyGQ5:A<Mh&T@XQiZ*iPw?c=V:eDNT@&ku161Vy>Qi=R+5IKDY*K&P\
NWhwH! cSkpAytc4$mGY&ciAYGS4W%u4FFIGwRqPe8j=BIn@BTmd*e:TIhJt?XWCdwQ#cXL1?hcp\l*BEl19@F!
^eu?j* Cq$aZNdJn$+6Yc#NEnKX=D:XFX&eRI!>deFATyBLR%16uG&wTmN^NdDB!FLR9D#Jk64+A@i^&qBcEE<Y
%e!*BW XREmWNmQ4GNtlH#!V#YF$:nw1FB5#CKWaqa1SeEXJ/Kq#4<hp@<^%5Kp!aXFE4hF/5K!Yd=I9/T5+tw?
5NnL:& 9MH:Y1E8D#hQ9/ka6VTp#nF?mXQXR\ETM#$bY%I:WGFwA?y\Ln?XDJ1<q9Z^Fd@Q=&AGKd4hW<$DJ5Gt
#jIStY :/Y51?mmp65V5<wdCc&y<nncuN!mWCAuXwEp>cc&V>cbWm1Jw*L&w?ukk4CBMeH$!^T=M&8?1TDZeY\=
*l$YwF LtDthG>$DjGK#+L4XjpS/+El6+$^%6pqXGTdCcZ4NMZwu>nLy*%nLY^FZ%PaB1p<VPCaw<q@i!J*lFjR
k1JIZ1 %KD9:BF1=^KSL/9Nk:T9d^!&dHD6pLt\4HyF/LG@Db$<yW/1>Ta%^:kL%Q%<41VyBqY6\q5GikN\P!8h
ahpFY@ 6S6h6kE9L?XlC&!5y1NDH8jNDwmK:#Cj\ld>BnlBL9eT9aK#y8N=cLKAGGkK?tW%51e\AQ$GNJtwd1=P
i?Dl4? ud/y<qlc/Q+^MlaL8&*LGJMFmLK&%Gct1iX>yR=R>u*TYbNu=cuPhAnppltwk%jqJp&ktP1Gbc*lY@Ad
n%\!t5 WJyH?=<E44hwZXlpi>\6R<^qZeC9Bm:Tyy5KSjyTPTe>cep%#^q6j4&Vq1*Z#wm6HFyFSkR8pu8>eq6C
@:$tTQ $6Vdp*CM=Q19ZLS@*KKccjjSJ*BEl1aEGV/WcYw49WY\dHPQ@SDhXK8PbNAZnSa8XNpd/YZuL*HFD\@=
1kyL9V X+C&@^TRGRil+pnd1p#6W:5jZ<1::lP:^4waC4Xn^yGau1F@mE&QKPA1PAKDH+u$KyS=M:N?/Tn9HEKV
jPy5>X @*tk+VbSEhpKCT$X1EY8KiMtT&>^9tq/W$Vp?HA%E&hZFFtjp8VY=n#5EL#!FQ#t!9VeeiVNW?@Ite9K
PmnJRp $>^WJ+*=@K6>t/+1I?YKp>T=>C8Dk<pF6k$6cTTDlq^l*p&Bmyj==#!I5F$=qac1<\1BI=W+V%ymKW<q
JH*Jka meqaa1/d&&tp\mq#&De4:n+qyetSn>X/RduY%+599n=C*#IY/ZuEw%mJjtm1QDCPY!jE6CPHA&9ep/<$
i6+ETb Au1mP1mi@WK\K@6F$XR9iiEqy&IWVQTql$TJ>tjjju$98qmi<PyHC>FP8hVTLdYXwee</ihQldHKSchi
bY!MeC yI$=P9?eZJQM8#WV^cPi!%Ae&y:+9M*Wml1SMd$qe8naGTbh*YYYQCc>bDp1ch>*^#R?l6nPC:tn=yZH
F6&AD\ =^M+q5y*LwyiRR89wcLMyhy^uWw459:ZJJd>h$S>H^bRG+qc8pJqLn9I<>kqI\TqqJ$>bB65t&PLi:Z#
V%VRCn V65eW*bIitW/ac+/qS?kbMl+q>c^Hl+ui!F:InpljiEt/IGC/*pw\#Z*%bYREB8=??e6H<1&icy#1#a=
JRt=*: u<y:6*/?<CKC*<5@SQ&!/hRTq:b+lAhmX5Y$#:FS<LP&>uqDu1a!yZ8YbL+kHWXZ$YN<I8<QKXJhIH+t
PpJi*> k$69t89W6Y\WdJKJCi=V<b&+qEA9m$CJ?D1TDujJ/dKeu+9ZuH=#A6^F+j8WjY%Ht%QmhF@:Gde?LS%C
F%MEF? Gp>*c8+JF&wJc!u5581H+/N*8Kk@!V=ql*iXjmpwESi69ppqaEm\?l4%uL6ue*ua//yu<utBHWt%FTTn
#bqI*w nJHV9jP%=nL\TA!#PmLlVX/el95qXINDy4\6SFIFW6bWJKC6byb6j9XmMELd5ct<5LcTaLWt=yDu5hNl
PR>aCD m1mA>jNe&JS1^WS=i?$Fu/9Nm59u4115ni>wK&9LY6m?dcJiIMpWdFDAVqt9%b/=qG$w>ML:@R%K<ZAJ
nWV9*\ TQa4q+E:^E8hYm*F=A!=PPjcmAL9ijq#nCSha>H*iSD%t9/41$eKq!MGbm>IY8C4:SV@#>6!@1iRpiL@
6ew5BE iR*QD<qIeVn/B&Rp@P?K4?J\\I19B*#E*=mP9>NL*%\ERmiK@?Biu%?^SkG^S8C#F9<6c#RAc!Ti!n%^
F9T\Fi KPb*4GERANaIQEjJ^YHR*:KGAdHGW:pu@kPF*%?^BwI%jHYi+nDpd%pD\SweV&Y8PE#<6/!BaA&P%*QM
%k^5!B :%nDkYANl5>#PQT*4IFkDh?haiJ\?G>bA<EcjkIa@qjX%RQnu^HA@!w4@WwAI<X@RADDj/T/m6=4?u>+
&8GNID niq8a<n@9&6M/T#9!Dbw>jAnKH!^WDqB<$@$akH5bC!p^EdKI/V$6$*G@bTchI@Wq8\/5kZVTpRIppW@
nDT4q\ 9<Sj*J\?AC=^EwLFplL:d+>EXddIR<V/h#ZF=F:J!VJCKt:DYK5C!NdwRV&/nBA=lQblCHbE=#P4&4c^
-AjbAC 000a8681e8d00110333 Page 186 of binaries1.zip
cBEJ6u ZB@%/\:DQl4m!!<pTcu=4eG/4@YZtuTJEa>dhdhVhy>wMiYaGXY@C>E&mHl>Eh&mtWWhMlJSe1Tj==9C
Y^FYWK c9S8E/dNw%iZ1W#MKaIXMtwFN\ZBZ15^SVy+/A%N^5jjbSw+^>H$SMR^>4%BT#F@4:p15elXLcT\:LJd
Pd9X%h EDGp1@QCCZXc&#K5BVXDIj*=&md=!\Tcy%6/=lZanG<FBVF%h%yc1Kyt1MHRNLhcFN9%>bLAk1VaeXQ&
P@#ahp 9HD8HElE^i$@IcTD&RPyb<qu4mtikkj$>V\<eV9Q5VQD9?mPeFQ5//kkIt/=yqAlV=lkEFR@L/VKj^w4
PNHGJm RJXqP!YB8B<dcX@>14hCapYI=mL6!pcA6L!G#tpLp\=l&PhHI+PIl6cktnSD<HyTh1NjH%8Q9MGkMHce
C/*^CH ?ZZF?R9J%6HnX1pclFKFndk4XQjn?6?q6ZPNn/q4cJGCH+mIqG!?i&qSan/6ucE\dBIS4ncBqX4Clbqj
X^eIPL 1Sj/hE<GM8%DF56b$5NjRG@5n@SCR\qV##EMI^@e9NZGK5L$SuQpcGiXuLV5YW%TPKpaw?F^q&+h8ZP=
ieieX: J=VK5=nt^<nVIty6\QXeat%8De\%5YccK1\mkqcdk8>kqJTDZKT$$1aN5&#9^+&M5L^KMCtE@l?/+jZ?
8$Vb\R %HWJh$E#p<MXkl/C!&8QE:c9*hZK<+4tcK=4%51<$G%GC9I#pw^V61FtVRdqbnjYKX:QjDXdlq8*qSDn
B>=aYu D4M\=4\1=+B8EwI5$k>66wd!unB98RnSaWw%95:4ym9Y#uKB/eGGq4%8MH>hFe9$b:t\C1uH4IjR9RdQ
?jYIi4 jV*/+y5Q8d=pmcQknFLQMeGkLikmqe9p*I+l@EQ?aB$MY>N!M?V1PDSqb6aeyPjtnWt/y%?yCc8K/!n^
YkjCAM RH?ky4iR8+kkT*15YCDQd1:eIlcnDIea\I=qTk\yFQihPlYj@ySKM>SH&i1=5M*n<HPeA5cSwBQM=hqG
TQJaSn 6#mpHST5tAKnC<huGPcTHB<^m51dJQF1GYt=6d1juqp<QB:LI&1@jKd=&RP8nGG\8VL=&&KT6Ne1^5<%
D5L=@c 81\>BKIN#TmNR8Bd!i/k$J$T@lQZp1wyKG>BlmX!6^:iCu*t1EyY&uZu/l5Su9Ylk1RLp5dtynB!9*eF
Ka*@KC CR4W6/4DnGNIH9WY!u\\BiP!mmm\ni:ybnyM^<#cVpt\plT#NH9jCi8DNFW#Y\/TQ#56XECcueik=/F>
BnJyPb Vh&i>FyB^u4&F1X:%VZ4HJ%dYbZqeh^FetdXWEWie*NB6MKqy\KwpbG=nhFl+l^!J%iYBMPRJAeeNPh^
XkuPTH Mce6$$q4!mw+/VwcyM51/Ek<FXXNABa5JC41thpEhjW%%\iBI%c=:WS5+^@4w:S6HFwPb!XKwBQ4V1A5
n=+WqM lcWe+$AM+1Sq^8#FV&Vj!QmkhX8qF?VtpunXcR\aV:YuG$cq4^R?u/TdjB@4QWe6VMZKT>A9*i^=CE1q
G1\=N= *#J\T=A>l#ASKe4S#dyncmwdWiRbFqtk!AmH^uh6\1K9Z*1RyTcwptTdea8D=d#KFb4dnk<8qw^W1BK<
D*TdKc JnThcD?@Rh4RPM>mb4Kb:EdSK&6M<1i@KNYt/*^dm6nJT*y*6\unZN$^ZFTH4TJXJL$awhj<k*NVDW:/
ya+Xba KXi^*b+ly<m>eJ/#VnD@WbK?!PXduK>8RK^&yZjj!4M@PEpFhjP>qXhD<&4kIwLKMEPd%Ia^=n!Q@5kX
dw9c*b 8TI$$X*dXtEbKt=\ej$FnRlSBA+paqBHd4K+iXH5jw<<W+9&<hmq46#:>>YaDh*Ve?^$kuQ8e/EYCb4n
iwc>1T *P&6u&l6^?n1iX%IHZ4nBdH9p>VS?@VTM4BC%WX$yn&ebuZ4iESD>YQ%yk!a:aSjih<hD>M<q96k:&^X
*qkl85 <nZq+1aQiw6B*l*P4@SH:C=yMXwwFw1I=mNtCnjJGd8TCBXQBAk?6DiCcLqcdd^jSL:miD=*pe!1:uH@
6myRp5 YYJ\yXCwJ@qy%XYut16Fck=<V?Hu+:*T#>XTM<q?Rn^GB:EhTTS^hGBKVMu@jMSp#M\NW9ClwYYJu5TG
y/pG^= QyXYShACjYR6y@EiCTmX+ed\?YXX*jMw$MCmh?K6JY66Aw6a>S8wA6+:FleQp#ahMYN=i=mmkQXE+LRk
SpiQBC /b@Rh8h!XTq^9T9n:C/<=Gy^BP+9Bwp?=?Jipyhe^RwQ*uC5w&6VQj/8a<bdM</qtjJS%hML4#=IquHi
\JP\KR 9>9J#mbp9:GX\6ybutYha8tR1&GERLlwGW4PZXcDhXd@+c5961bH=mQeE*A6?6tPTjnedephJ%d!/pHW
i\?W89 $@tTD&eWnpVpZ5&5ttTd19EK>nP/J?+Ca8/<5$\>%&#F6b^^i?A^1FYB8pjR9E/wk$&nM@*Cbha+HhNS
ZDNRAi X?@LR@hF:!#h5!ynP!dpiH<^M#q>DLTep4yK:jk!:@cZq<#i*bhC4*Z#BXW>tj6EN!!>yEc%I$F=X$c*
=YD6^i iLIpTGe#/QcbWc8+#V?Ctd%\Piba4epL$L!&9P++Da@HyjiQGmddj*4X1hDjiRqSy#*m>Fyi8B?tGyLm
PP9:cL d6p\QVQ1pEZk$1c5Lh1q$BbYE8t^by>?YVq*ZHVG^mpEXBL%!Cp?qn1qI!hMQ49lQ4ZwPyu#SDQFe@KI
%!F8J8 >XbidRnp?cLZyNmSpyI8hiey8XZ@V@:dqbcqi1RTFVct5/wS6?Wb!pM<\6S&klXN+L=9!T!wLALVt1^+
jw?Tm= SY!t+lZ4:y>XS?VCVBS*1h>PNFpkQPe:DDkZZC\d1M9Lm/p+Sk/bV5@5FtiPHeyYImQqw#=4K^aF!k4^
Y*qWG8 CLV#Yu^dGkVKXIR+S\8Zm+YpmqkcikX%VN8wmpY5KuiX1$bW>?S>SyB%XA6&bVhwmRX6@/GYQ>\VbSA8
iEpwed #lDYkPRd4TyuXlQ6G^MhKikdH?5&jWHWMNBYKNK56iw+REER>my#qD!Z$^%41lcnX:LPc/>JXJchFlq5
SLXcyh Lei6F$<$BTPcCkmmC%dnjS4Pltl/W>#RNRRmbn*dIPJApiN44YjcM=m#DcKpT*RT%LE$>R>WRNBT1cm^
dM8P5F qXhE!Lp1D45MiL^YP6wcCN>dQ5^H1+n=ad$Q1!pNq&nLJ^jnmC15Ncc^1=aKI8V/@9aQ4X\?YwQ+IiqQ
9Pk5@p GWWy=kZ!IV&4d#yydpd8>8aMIAYpPydieVquZ5*qF<?&+HaaX^=Tqw?Kj<uHMCn\puQN9K%yG*&YAyL#
u8SLlM :9nm=+t8Q?qd9dYClWYlbDicD:H^MZJEk6RHLcFTT^b1p/+qt>56Z^=*MkT4Xq6bW&Y4plu:4tnGRPAe
kbBd\# nmM6Z<V<V:pFYS<mMKSTPE<my&eShF8p?^uJ8n8Tu?lF6k^<889>/%yIbBIWXt4eWy9P^:\49FC1ZGhN
ttJTu1 /6G?pQuJFE8iY/*e^/^A4#=&/Dwl>nlVyQhc!^whS<:SIG8H5$VpG:cp%HtH6$/!mHFcN$qiea^RBVZa
wt&/=@ put<*uKX/@^eJ:D$yW<l^1Yqd1W!1X5H#6M!FRTVE:dM#Z+In$J=ZW^dX?emH?44Hw=PYCTmD1?<H6kS
X$>>B@ EKwa!cW6MXl$pt>Ew+NkWH6A5*NE:?INhM<:nJkC9PZe+hmV+QZh\LiX+>\TTRTqn9BnM>#KNT11=q\W
ZA@=?A Lk:QnwhBH6C=9<mFpBIdptbS9BJiAIHMSDp@Z<*qSQJM^Dq\9$mj:Fati4AcIYI^Jp5B8W<YjMkKuRWG
KP5\IQ /dRw#Fyw\>&$+XYTa#hQ5Fm:IAI@Q@Ph<yFjHiE%%P*mX5NcwPl5P\:JhER5+awZ1Qm4TIRL=ZCHKN%P
dIL8/$ \Z*den&T>Da!=c\<yiZPK5MKqP$Xt5y44!6LJ9Fa>=GGmmud>>AwS#h5l<XcSw>$>TQ5CE8HL5Pq:K4p
WbF:ET cVh#Ke+Yq\*4S>pM/FpQ$QDqh=JQtXDkLAjppD\iQ8=CHPWjc+q/!P^GI1J:<5Q5CMktNy^:JnYPVXbT
P5\IJn $:dHC5J6Ld9tW4K5y^NAk6Rt<M+/%eCHD*14//LZl<QwpT:Z9XaZ$n1:w959uR9c*upKRuJWdt<+k64h
WbJ$1k TTp8/Ap^!*qG1VIqHmJnSb1?N1^pw^=5S%4R:h#58&eL>qWcmWHKGTbwuLHPDqLDidh$4BQ6NBhHm>l*
/6RX1\ !h6>/e**$Z@dLKNw4h?CndJnT\#%u:N6NM%XB!X+Lc^ek>S<n5%*>BKAlW!@5Tb:QLS<Xu9quK#uq+VY
qBjK<& L4PPqY5Y/GL=Ej%C:%kT!+:Y*SKG#Ce^SBR&8ZiYe\YJ6XdtaYSQ=>!=IN4CiqSTSnd&jRGKy^BqlmFa
qE&m8+ tV48>!Ju\idR#J1#+@EnmLRTIT%4dSH1L\1WFD=/Kh$SM8i5/^N1dCN=yy1Dklmbd<KWC%D&\nTly@um
d4YYXG L8Q+e\$T:&nPY:eEt^$N4>WM\Em$NK#MY*5*a&!kk*JiaZ*L@9G6Qw/4A1=MFCF/nW/#$5jt&ayL*nNc
+!nP1S hh#R&ltF4imSmm5\9#?EiGA:>/e14bEVhaCVuPS>%+8u*4dRM6t1PtbJF*qy/5l/cTja=$pmWWLa&NWM
HyN^tq NTH!Ble&eVp^n@Ly!Bh8VFcHdCFFk\n>ySF+cM@/+IjVVl##4*W>&uLPbE6iI\ZV9H?wEe&p*e4ITHd%
6d4bSP mH^Wj6:e#aWn<PmYndNity41iHXT^iH@a*ST^iF+hFI9:9&dmy*q^Z?uI@bca:+@wCDjH>Dj*k6FR^Dj
&hahcD H?DR:\@I:&*R1P<FbqD$>?P9MAlK@IDnFbN%<h!upmH@ST9DD9SY@>NV#H?Vnpbm@p=HI>GA/Ymp?A@y
ySjqTA /B>eEuVRQRAI=S>eE9R4%nAk%9kIy^>eE9R4%kkA%pl<^CwC?X9YKADYiAqqlQl9YcPBYEQ^EI\@$Q@>
9HV&SL BY5pEK#B+Zk<S\LBG4:L5MTSRLAGR?Q:&@Dj5kcCNSni*+*<LY5kYMNQ!@/uADD&9+^@T59C@$%XXS\N
DBFwC! ?<E5?P@T\Q>%GhdiFQh@/*IB%?Xc@8?5!&WSZS$A>%HIZN%tCTJK%#4!&M>BAe\D8i^ES$wWy#wmK=di
WY9Y<Q JCGjEZ?Q=w!4>k\4#p\1?FB4=JFc>Bq6&+H?L91+Yhw#SNQc4QeI6BaT&=a1FhlBGW*FBSV?*FE5lj*G
/t@FQu mYCbadntId:lMC&\XKQnCRpXJ!d^$/4>PXA!iipGLJRWCqtE\deet*XIpdytcyFdYpYMqH/!S9^14=^$
b$=C6T IG%cL#TWpTYBu:@k*CB6k#Wdny4<PwS!d&/TMk6@RAXF?/mP+>T811p&m@m$DVdSP+pn6T%PJ=Mb!bK%
n<?S$< u?^%!Z1J\w$RjT*V9ck+&JN@uy64P\/nmh^I5JSR$Nk?dabEdbi#Nt=@wXe&iPYwlu81!V%^?IIPZTR:
dEiJ/c uNJTW*bR5G1tHYV*B@9bKkchJIG?eyC5hL&D=jX&K/E9F@!W\FGYI^N9$%?/I6i:b>lpmJGGR$%&Y?5C
pJq^WM FK=Wa@^pN$h1S$Gc!G=LP*ieHi1=j1?h4l*+1TY+bm%V//NS9dE1h#?lHJMn%SXmMQnR=VnX5bWVYi9n
F6XpD= !+ph&mLL+!>yk&9a%b/m*4#Nth\hlETk:<w\*TqJcXP4IT1RJ%@==K8+?ykK4J+$iw#qKXah^6I!/HBl
etheTu yGYkTkwqq#C8KiRiiVpuyjhI+LGST^6!#=?SEqi>$>ZR>Z1hw*$%wti5ReVHhLiL?SaEdB$ni<Fd?YnX
XM+RSS BjWhik9#E6Jn5ZjLEeTZ!qSImT\?uhw#<tD@GH*KBHYqiub:VYP\:H#pSuTRqM=XS8q6i=+k&qQN$#NW
%<JSJy H*a%qJ#IH=@4C&ec#Hi*@CD!CBVlN:*<WhI9R+6a6!j+KS$@%Vw9KA<<G1n/te9y=8=8j4=y:Rq8YqLR
1GQ\lW \P/VIMTLNC%?N:qHD&RS5F1PFLE#8a?mMdL4<dEVq<#+66p#DwZXHq9iqSK>HClqhW#qQNyMS%H/EnE+
-AY:+J 00066bd021a00110333 Page 187 of binaries1.zip
d%4=*I *T:Y%@&<88Z\@Y45NjC!yBj9NdKV$dc*NVX*cY\:GTX*HqDi6i<^nJR<XXlnd&6KpTJDba$l<l%>aVF*
A?Clu& $mC$GqyKp9+<t>&EimMSpTLiSKH#TeN\8jda!T#>RQb/y&9VV%jdFdkPE?ma&BI$LE6+/qP1!VDj^Ia&
+4W>pc !=&hww/ilIdp6dCjCL%Ce*/J*&:wXju^wLTTDBJI=B6u^k!qdF&6eV5:dVQtp>H&mVP1>ib\hc$ASXuE
BRKiqb =MPZ8CBZMGjPKX9VVYFQRb^:u&j=$bejeqIk8Y:T4u&Lt6pX96Q<Y?WRW<PnJ\9<&>?NhmVN$k*D5PhD
/E#1k6 bT+JpNphu*?+11En!6cH/PXN6BT<GLjkqGh=X<#YYNId?#Emy%+\mZaJJhj94*H*MMGu^uyV>@qNK$XQ
Lyt\G< Rae=C^N==@PwG5dJ\HQy<FVGliA&d%tXlWi\8$4TiT4pqqd^AhDVjwPb*eN#ljuc69GMyK>bQ^1Q?5u$
NGnPWu G$PciPFiCu$c<JPcFQ!*GL5Yq6tIPI8W%RyLCLD$ES>=!jKYSa8dq<15ZLZN6ETanuPjtuwqYCmFLCX5
B4&5q? u<5\QcybdFW5Z>N>TP4JihapW:=$>4E1nPtknJG$e5FaR^:#Mi*MYt4BlcRHe!S&65XHyYFHaMZ*Vj9A
mL9Tl9 Ak?6tIaG^D:JH%/Dt/wPbimuGGm>tbQ\MN4$HXEI^k+QyC\uDMqD8yPqLid1D<q%Xik1\FWMa\N98whL
QEjB8a cCki58E9ha^^FT#\!TC\6Z&1ych:Lqbi:jJd48\AnjkC/tbPl:5<Lw=J>Y9i!MpFYb5ZVG$&m=tG%blY
5>:thu CnQnl@+X9j^!q!*un&<Yl8dwjCbJ9meS:VkakFV>cP/^TJMH*knqF<n8+a@>%H6%CJRQe$FYT&/tp+^T
kGlYKC u/l$W:twTcHL4a5+pY9V@X#uT:THaqkpm1^yQI=Bd$$9*hN<DkhtP8=C^*?Z>w4!YW6!Z/%AcRSbJ#<d
eWP@WT n$+\6bR4XhpnqPB>biw+Y#W1@lmX8<Vab1*u#wp*e+n914dbM6d#84?ltFjEud!dN/#T5=H58JDLiL5\
DayaMN idhQ5XqERw>mwEuFRDaD#FFJieQwDTYjVeJk\mL89P$+/?d>E/1nh4J!91>\ihmIBFu:t5N8E/RGEanY
ea:??R 64HXS=C$^!:u\ebXKjE<F%J>=I*wuLy1Qn/\Lu5*wi$&IV@&&ud15ET!pd1<ySBQniA&c8D?A!NImjH:
ye?MEj !8cpT<c&$6Xb=PMB^b8jt=DV&<h!eYZaPdDWJ/dnBZLk^KpuyJEWleF*w&lQZnlSSmWhQ:/8w=k+c1Tm
D8e=#& Xql^C8hMFP!ZTyN$c+$qe=J1bu1!whA#IE#L5?<%e$@SM$*/<?=H%qT^j5ZDqj$WDcFZItGiA<py^#u8
*XHkyh l4:Y5Dd%yP=:jQY+mk&p\wRLbJ$l\BtpC<=hHX^PpZj$1QeJ*wmZYGJyM@Q+pF8cK!b6%@:GcuHZM<+t
%CGc+! dPYKmCS*C4?JE?aFKilR:6^:J\GFq=XEeu$c@p@:TbXQWR%j+5dNc\yeWYiWeM$T4FeRLLywMZNZL/6V
TkH1jL K%8qXbEGimNF1$D/EN98YqLM^dQQJBmP=bDNqL>MI:DeJG=ZR/N8LE#R?S\c<8Xu6b4KQ>&bL%:@8wZ@
M6ca1d ^e9FZwZYcq^py8pGc8ZY>T&^lMueq<^FiX=%NDhwF#/j//d@\mMTR%DdY/nIeqSkA88>$R@#PhNRHWp1
uP4wT% q?T6hdh<=/n9J4XDh9:bn:mVI\bbYmNhSKLYmlJlbKWK*p>#DWZZVN</jV+hZD?hY/u6!mpDYqJ#lq\N
GwP/$> pDVptFAQhqdk=S/SL%e6@6kVtibbmpc8CEaGL:p+whPFPT:$:1c*^BESj*\jyt/\$qjVI&YwHPlVwJ\@
EuyXNF HZ6Phwt1ae/4Z>HNP6=wiXJPiblehqy8IKYtQ%ib<l1BceTaK#WlbelLJ%@BML1tF4BDH6klP@$86V1j
^W?TlR pD>jaD+*4+?ytB<wl=iCIQE8:>Ka<4T+@++kmdhtNN9b%:H1WYSuCF:T!Ty4p$^EKGZcNS9LN8>RL<$M
dAEHIi Bn=$Zt#TpX%K5J!+4m#e+yRTNw?RDI=jILEmKbc+dFuuby1mdIy%DyBc!dt5MXj44bdmEJG&+&1C=VuF
YHTyl1 :Y6=59ehCQ5+jcDy6G@kGXt59Kc!V?uuK:lMpGZ/hVu5k<+y1XbWlqLdIDa#!YJPI%&VmY6t8b*baB+%
HqESH% p#$lG=#1W>GSnE&WI>BcpVXyccE^nGpb+qaDR^??wk<^Eumat?u#Kp!h18RtTYblRd6PaTFS+R4X&V#%
wT&L*6 X@#eR\R>$6\M<%#4XLMYhPG*!dNXQYEEwKKHh+I<bMm9Z=+4:SI4#y=?jYLFklQG?#1M9*aV5mVHIVZE
Q/t&K* uB#ekTS*N1Ht<M?J8J>VGnS\l/i+m1MR6E994?Z!MT^5/FNbwVq*?1ZR<X$H&<<lEnRce&?cCtXw5+P/
WZ<Mu& Wdw4MnV&imqF@Np4dl!kn48<5J9$d?\F&Wqc>PI#XV<NFkh6qu/l<PMjt55lNY/^>dqcPEamh$JMe?KY
=CkFM< 4*1w@cqCnVHS46QeXB*4\aGLnuWi$%*cJalB+c+lEpNh1i$#Fi9T5?9DnIIl&c4Wnk5>IyA?84TW6n4J
F=n1>m &Q^4nw<H1#mK84@$l=j/RB9/X*5<dVZI&?KSnN##ij!Swep\6Tk%Y$IwDlVSHi6D68C9L8l\<Sd=<4n/
+mW<R1 Cq6!<:T?i@/K9b\P>I&^M:eBFB#cEdbDk5XF!jG%16KA/tLnew$kJFkIPc&IV8uK!6nkhWFREBEqTLYF
w=au<M +L4cykjWy<uN>#:QXTKlRnh8#wENl4IPRd?8WiZYqk!=Bt1PChX5Dqy6YZVWVkRIX*PwG&qnpy?8lZLI
dHT\>X qlG!ZmNJ6&@d8c+B56$mWT%L%Lkana5^KStw6qHBCVa>=uP:e1aqlpaY4XW/bNj^yh@FjZB=TyYQwLm%
#FcIRH pwy@BkyQ9R*XWa?R>Mqq?>J&qB/ZLnW*AVK%XP/CjKE\6ZQd9SM$j^1i4m=/=F/5nQT<#m8^!>1pYW\c
Y\1Y>P bP5IePlbjlW4@jmI++iLbG#tptVXPCPCtctE&&T!#t1Rl/m1uFMQ4XPdh>NwtP/V+:%qQ/yhqbtm+SG>
yd+DRJ NcyR>aITy<Mn+!N%eYH$4H1F\p1Jem6=##N\Sj$bSmuu$k%K5QXa%T9chlZCiX/1W6WW^W!*m=eF1=?e
&?yy5S 5$?$5?TR+=4umSJ<wBEJlnLa/jyj6V6tR4CqH@:GYaqkdt/$tM!cJ4$FwVH8W<BKZ#STa61XttX!4tS1
R\Bha! kX#b^<=+l1jKIPdIA=Z^u8nTm>9dVhk@batj$c6V^IZqw1naHySFSXFPSA&&QZcS$LFKPlewb^/!E55D
%&Ke1B /T<\jCYu6%A$qG&y&1mdLd$>Nb$Q=?NTdJTcwC/1m?*?cLA6#MjjbD:@RtV:qDuyTF98nk@JQdc#1b>>
!m*><t NdX==Rq!%dVnby+P5J^1Hn\BClbVDBbIZ=F^a@9e=Y5T:%>CMuJb$h8%8%5B8&YVaD8P*PCQe4*S#YG*
+twtYP 4D/lyVA41=^5Mchm&9b<d8KKdp8Dku%nWX1A+&9SwnT:*ulEiKW&41=Y/d#A<u*/eGMZN\/Z:nThcIJa
E@%?LL u9EQFpwZNphndb*9c8@WqX8@hVy#RaDB%<a@SS:qR?=hd%Ql!IP/$+#%ZLEBdWRyM!i%>%P/Bdi!k>=:
/ZiwSZ Yyw=<h&/cHucPpje$<LCjN&F+c%==KEqV+$mi\aTdZ6q>VG>K:1*#^^K#^=8$wud<LS#95$^jq9BRji6
\c!5RE V@jFeF9qYnWC>&ub>&CQ$miLbTie\4b\M&LFjTqnn^nc1ZIyn%=6#>dtGbGM+W?%Ycc#=QLJSN%XPYKQ
&>kF@4 Yw%ucL5q:Kb9=cNmtp9llpAijpp$kDwVyGMh:ialZHTDiL*H$&9w%k\TTu&%V%A//4y##k9L4SW6y<\A
1XM:uA H8MyK:TS&yNDNBA=&cu6NpHZ+cT!%pT=WXh^GZ#p:*>i#@M@y64*Q?@>?RX/>X>/BQ>G4/LlkPuX:!#H
Q/y+>L Z@tVH%\phEA/A!BIj*CS$K>a\+Fa+!NIj*CS$K>aI+FaR@Bbw\BaI@H?duEk%un$cMXS/N?!^kC\S8C4
klY&8E *^TH@Ja%EK\l<NXum<N?!^wI%9DY/+wnj55cCNdkiD%H@ba%EK#B<iFeHQ%d%pC\BpQl&aSAR*:LGknY
J5YP&q <NQK@!qAnQ$9+=@T!keF998$Ml4!k<8/^Q>ht9lj6DITAj5@9>w*/j@Q%d/E!y6!LA@Z%<FXFA+SipNX
m$A&#% \6QneGm9wtEQ!FH\e\@PVK49EalRc9IiyLLB5k@l&PHKTpy5ZA!t19lSGjCpj=y\:G*\I%BnPSbNKnR4
5LI>*d %Weq4ebDX?1\8RA6D#hi4cp8t4Q8\SZyL+F^&9!D>Ell+&Zh1lPbH<:XWGqD<5Zmi*t$?5HFI+?\MXcu
$h/HWd JXSZTe%M!?LC*5QGG8W%>MwCeq^Hil848:Em5%jy:n%@^^PIGR1jQcE*:kcuGP!mZJYZWQQ5/V@h1RqL
qYHYT% !?lC1A4\hTH5i=Y%XGM@cKltXe9XSHBqV:K&Z1#/$*SI:$/+KQ#YTayPRWwVRycueayV+6%^9ELSV?9!
9#Ndd8 *$c>kLI4*%jk88MtaSy@B\EtHe#i@X4i/*pK\hZZ<^BPWZSN/J$VK&&a8al?W^mqLI^XnZNcp%+56ulw
uwJT95 cA^JEkYtKbaXMi&JE+*QJ\ZQjClGel*X!%WRDnSD45b9j5CcSGj1:TJi>Y=SF$8eQy1umLl5BL9Jbh6>
:5L9:? 8SibtRFdb/uVb64LdydES?lSy<DqYcb%+IZB/n@9eI+\?@lNjS1/ep&yt<DqmZCQ5b1XmyC^T6qRDQI/
CR/*+C iIjSi?^<*=&m=?YZQyic65!JP:dX:P4eM4:*>Dw:*:My!kHut6%:KAl:#iqFQ!W1J>KuLL&>/=11Lh&#
?RC=aa #I@XjNk?uJRdVt?jL:FITGZjNHq$jF6WcHy^q@TaC69YubleK+H5^u6cEa>8h%?>aP5&!mp#bMMCZ>Pk
e=kXkE Mp5WppWZQbiIFnHn/SFGFwbEVF9B=H8SnjG1F6J&1haFMalAti%p4eaC$>a?qqw>/%DXcXi1Iw#Pa&T8
+X/+JH E1GWEyq<*YPTAj$KKu:%pJ5EdbpiB5R9X#lXT?8ct9PnC1pEuGBttqdXiX$WuCe>KZ##T^QYVbXna/#J
&9TCTy 4KHcSde/y5%CjYk$H6:n4QG!%:$TF#dhMXZHP&X?IeYKQPi?j48P@p^mm$1kcTa!PbH?^N$+yHQ^>J&+
FCc$bj wjywk=WkHl6=/e+eP6\E\w/WtmiuC:bm%!mqF6+1%XVDwjYe4dLSRdCC1icy@l%1abD#t$STy1%L@Jtd
Z+Y8>? >^FppT+y<T1M<XtCXGI=imu^lcGS!uB=i8tFHQjNSG%q+*P<Wu$5Ic&5HEdZ+8YjMuLin$$=9=Y5G$Hh
mP9Hb^ Xd:DKNH>8pyNqJP9%j<VuFpk@QdThiuYD:kWYXMQcw:1p&kQ8SV6eD>*ajh4Djhqu9lJ!V8DtFp#c?jc
L5jq>B &V:!cPtwkk<uHy6kb4jWhcny9V@!pV:%e!IYb4pXi?YptJaQhbJA@AC9:8Q:TSJ^XFWmmu!!hM?JBbIe
cHSabk Z?F86#I>Q&a^+/GuwiD8H*I=qXuj!l>^VW?kenL:>pW&PS&QqywkuM$SLMJCq+ulX5MIliEn*VBi>jLC
:M4cBh #KGTS1XW#//?PCt9>ehHV%q^T#W?:iI*#\=w>Jb*FC\1ndc8WqG==@WW5<!CVVVKCA1m$Z!MPW*??nk+
I4<%I9 Ih=Rn^#^?C4L>JJ</Qp&6i%^n=/Ka=yyD1GXaPV8b9N18j9q/jVVlut:Y$+5eNYmP^+Q<n?95q#hkyS6
b4J9e1 9NK4&>$b6CSXTBiE=8h<DG=P#nEX#mR4S?eaDn8YZWXtyGnb<ci##w9^YN/SCbD+PEnPSG5H>t&51RIq
-A<<1: 0000ef0352100110333 Page 188 of binaries1.zip
mV6@YN =jkRwuji=jMb*XhpjN16McS#X!t<JiP66Kt\n4TlAM<F<^#Lh?i&clDD&&YZntCS>mL1c!<S%tdYD&m#
+XbDj? P8<SXdRVJe&+V!cW8lutapjVhQ!CEPRDQTi9!lRK5*G/W#JW>/N5AmAdRaaZ5<l1QC$uXN#6C1nkyMKH
q8!/b? GTM=QLhWaqhI#wYiISwKyFduL&:NQZjd6ai::T=V6*DTJF5Z4LBb%J1t4!cQwWjYy\hpN/k/*>J%=Fup
bhVBIF G1T<PJ?%5<NpJFH:jEipKK!N9+XqG9EA+ZSy+kXJ8GlCb@#>#DhYD>b$YeJcM5hM=9t/W?I5aEe#cc>+
WKJDFH FV*kDC*$N^C:!X!5i/>MqNLLGC/R<$4cM&S!Kya:bjq^Ke@6e+hjK6>Z6R9/Muc1#%nXy?i$%\YNq8uF
D+nkK+ 9JKn=WG4&TPhR68Sd?h8iYnbya6p=eXNCGnGc$W@<k?yT\dHq%=/yXa5Pc>95?kHCXwi4LnXmq+d?dIa
>j\B6q ip?%y&FtcqK$14G$<k*J&B*IYa6V%BVSN=F%HP=tuy$ycZqjbHyJ#y*$Y1qGHt/w\Zmw&hX$RMVmE=YG
IFnJ&^ I4PW*#Jh<ul8@tk=Y@II<^<Q\8l/Z!$t*eL1uTmk/1%*ukl>Vca*n*nt<aY8MV@b>FLEACthYcN4WGD!
8Ht:e$ >5iHud^85dbZJ8!91Kwm4I1jCAl#SW5\XHa9SS$V#lHB1TtcB^y1Z=8dP884+WlN9e%eX>F&N!GlZRuW
NYQuHj qp5nw%K/bh1QJH*Et8A%5F!X@Hnk+iEQk&9u#udT5pw<N#8lb&N1?JSRCl1$jM5NccCmiG\%^&Emw>#j
W^F6el N#4<#ZMn*R@\GG&mSnb?*CWpj:A*#9Mlt>+>y=TFm%GPH:X9iCW9dn@+iIH?k@#1PaacJA>6RNLbw+#J
=TNa!+ ?9\+i!WNKa&WWF/#tS6dLE&5DZt#S!w<$neC8LHJDI&cnQhWC!?G<?y:$nK6DD>5!PV^+EiHNcWcw<?+
WhnL#^ /bmlJikj8L\XyXAT@Kl$?YXVn:!W1X!4@tcEItIYjdX:=XF81WEjliZm>Sa!!eiF$cK&^p@6FERGaJ:#
8#KB89 *FylQy?Fa<<:WTCIKh!Ln:WG1HcD$ubhKWmJY$nVY<T/J8%tKZSZC\mneE@Fq8!yDEB1>pQtw*IC^\IZ
S#k*Ej IN!&YPmK/6C!n%@B^<j=^yB$&=8YHKS$HKWWKYJ>^#aywpH68KlYtR?1@9yCWaGYR*<wX/6G4ldJc6GW
wlX<bZ /X>cTX^4&1t#HB*l*IFHq%i86FJEN>P5MPBIbPRhNwe/G!J/RLI#u?ES5D5pMwFRBk&T$bX8PWTSnNqd
59/u@I AwW&>^!Xy9WC6K*G=VL:n=uph+pkCDXLQhY=Ji4AF:Velqic6ck&FEpJDH8FH5/&E1!HIl1IG<VeKDVd
N4y<nu lJh/%m?V/MqBX9^/GMHNm<#pw^>Dh8Yh*D>*nua9jTCu9$XFc4kTPqyI6q9C8iMdbCuNu!qI4X>aXMX8
AH?C?@ t>dI5hA%i=\>8+b6!VEyyyXKqihI@1jDSZym4tjawI<qw%6Am>8RtJCdiYF6$F#hni8*lBJL?:>5$A#F
I<Dac4 1#Qwm%LR?L+^c6XHe1@PbuqlmZKq@WpQk%cX=Yqwb8kiyPhVc\4QLuiSNmtCAmIbuWwdlEa$G*I4q4EB
%+q%m& 8Mh&QR!d=VA%#5>PacjyNVnMLL6=qSnP<ZLjFuCic6G#wH@EG:kpA84aKTQcYbVJ<a@cIFL\!#bEeu=Y
\$$P<8 n+CJBh8@GNVTpR?q\uaL8^^:ZFu91yupPcm5R9SBBDcyy5w=ali%R51l^w>Pe?cPEXwJ6BeZlT%aT^qG
dHHC/I uZZ6=HHQh6bbpyh/LP>PHX9=/iduq<Xyu1JE<jKy8#\Vc!GQ*$Xa\:t$LuYwum<k<uHRN>eRLmlB1^ap
Gbc<au TT6ySaj94Wy#ZncXpeYCCiS$q^ttw6c>d8cnQ@ENZYFwb!nWaFm+^N^&Qi+tVaNAK=lT*&#II*WcT!*X
QT5QnH %M+k8NN*Bn%W8EdGyle&9Xm5VEw<B1J:W%K$/4niT>>JbSSHhn=@\pL=LN8\^A%mPGZRMaj%CT&=9n#T
ZED%p* Sq1da$GM>cM=cjqhdlD:J&ictYnYF^JX#4B+$AZNw9@IX1A\Z=G*EIS%VaX8eZaPJ^!&HctJaV:j+S/5
P#>WSZ AAGXtLwKZYD4eH<RF@lkWW1y1u!mA4*BaKIeG=kAe^#ahFZP:hkm6*Y+mZIpNY#yjyM\4:ychpt\H*5*
YS9N>> qM1#q?!y>4wKKjiPhcNTpiFXw8tFuB=*8+q:NwmLWTeF%cW<QG:K&4Lq^T&w=kh?ep*BYq8?hw%?dD46
L/@4t8 NQD\5S8Q6FYai55ELail$h^Em&15q1I%np\lla85KuPtZVATXKSL6=Tm9P1cdYi9t$DQ^Mhh4WwDXjX&
QG*=GS mDDWIL%$VPAh^>wHYZu\e&WPHc8pKm85<hu%SA<!Qc^Ene4Ew8cw@FQ8hDXKbk&J<ulqERiV6:HXA?p#
4#\DPQ >jNmm1VXN:aaq8Y:twhb1WlMY$mY#wiw5YXSGd+LXhVX%TZNl<4QILpWMky<:5<jeY&#Hq>Yy8L8K+^d
+d<y*h JF/nGiRVlC=bG/9pQ5:qdlMXdlSeCCGt5TKYy8!TG?T@ZI441Ju458cmG%nh*6nY81L\$E%5bMD&:lHa
*:+I*\ S!6mDnXihd&Ca/w%jTWmbKJYit4\RQ\q1@>=?<#@GNd!Q/?%Ae=cwmF@9+5KDRF<F>XBE9&*>Q\HuMn*
%LEWpZ CqpA9PMQ:5u=FY5$AG5p99LGH>!V<\9YQ:ku=\jY?MwdMhDj5waB5Eak<QA^GQl9YTMAYMQ^Td*?RF:*
kkYn99 X/!BaA&9=CqG@Li5kYANm5bunjpNc#RECNd\Mtlw!F@9bDw\@mtDhqCL?bXBk/H@#1ClIV?+p\pBS$D?
pTEZ%m d&Et<MJM&@?6k1qu!@aFW<&8utWp#%SSaA$m5k*:<5S<G68Qc=VKa/q/t>+&?ISiY+u<eW!e+?RyN^u9
@p6n=V ^+XN/cFePE1=?D:!5yEHVGiI9%%<*@WHpnyCVc1XYqbNWLyVWbNXW8lW$YqT8twPSLY&Ib$k1hdJ8S/+
:HK6Hq qn/Y<!dX4kXbVXtLJe9I4MiSQ?Wn+=V:k\tqJpXJwcun>*M1/wXneI*=4pX<j6tkHuZHjGPY$$nmb=Rk
Kjlk>h /WecWnX4IVcG#dFL4^^4pDuH\DWdAdNtSkZZ5C!n=hWFyQJ$ZJJnETISN\+@!Wk>+Ybm\d@c*^WkJM>w
NW1jd& FPDd:Tbap><!IZtmtwPV1l!=!N^Kn&ATnXm@iwFByZc/q/qbZAy:<wu8/bu?JpahP%VSK9am?yq\naGN
JW!JkQ nm\Xp?G$Z*G>kK#YNuFk#R!H%wnM$%M\XlQcJejQK599upAqtay%!W!$*uC\%LC^Z\kETXe6\SEV*Kjh
p4d^*R ZyaehRTQX4EaGc/epLX#$6ltdnie1XNbVq>:u+*>1DSPjNb?VPjFTT5RY/=yH^XW%%/CtyH/mYmn+naZ
Cw=+#V <?D\5ain!4ihn4a>9l%F1XVNpGCkNIlp@/S9jE:FTMjPPB%:YHwD<WSRcjL#X6@IC%DBwLFL6ttyt=tC
p$cid% PKQ:+R6M4CwXuNjIDJqyjWbHbm@QE:6jP\XZI>TbY$45?&Md@XtN<K/RAVZa@^w@Pc#tNcMCQWJE6BtT
FL##PC I:m4ptH^pWZ8yeQG?9dX8>MDRSDj9y&JV:R*mqJH$QH=jnE!ES/&b4RNNqQ*:>y#u1HCcGhta??dtt&A
Q%Ity= #p=DJduqKIkL8ZXX/h8SLbKPJqtn41D#1?tJEjijTpVLhdEcNESnM?pSMNu?@D@a%q8?nDVaZT9EFBQL
b+LMZJ 1Tdija:GhX+D5/*:j$/i=k>XSy@I<eXTJZQ\l%Fdn4W$T#EeV!EkLX6qcS/SKn&HMALbiccu9B5jNc1R
jXZ%mc 6D&:LIlPE6*%i!AXDwu^=qEMPpy9j5S>w?cLVPKZ:9D/DLnjI#>WhNN#ncanMqS>l\w9!9qIJ?e:hy54
LM>dld <+yjn4mb!ZmGRZNYkF5^pLk+VcZmYZEq%@b>ye$cKd=y98Nb!+j>bLVm!JKEn^NnZ^PG<aL!ek=%=1aM
j8hb9t DY\>9Fb+@l/$:9Q#HK$EG4?ER+1YN#u%9Ct8pS*>&L$eh?^t8IXeS@TI!Q&HD%MKcYQlX//X^R@wQ=WT
15LcVC <W*QQbK?uS?jc9dShiGc:kt+NC4^<<W##lW4l^GP%yVt@Q1WbEZHGa<<Cu<katB@dVWIa%?NJh!^$%4i
?*D!=u !CTyZb6R+jHKmIRnmSXT#lZ1pHiX?4HlyBYaZ%WE9Cy=ZBp+%VW1p\b/R^PSk4TQ#@K9!!%e@!1Ctt>G
uF69&n uL6cIeFu^$R<!ECZYBwI1*nY=pMQ6:/+WFHGH&K?NEaStA\@LXyY??di>EMZ4>ZXQ+Iw$G>QRES\Lu%F
%e*i@& a##H?YLVQi?&D#I@:m1jmG%8lc<9QQIQjZ/Bd+C@nCqD?/E>XNhQ46m&^J65MP!S@16C*9KXX6G!AG^u
K?#pP= uJtYYp>lLy1<QD?bSK&RtYDpqFZTVy\WBF9abc@S4GKTEJ>Y6XVc4l/*E!\a\l?<uiGXRWyW5CmH9NhX
>&b+N# \FS4!*J>uH*49LB8P8hV?\e5t=EBIk\W4jaE%TiIn%:j+S+?j9?#\=6!j6y#Ck/GNlZc\#M9m6:%6LIq
m#>*JK %XI#9Ga*Im6BHBeC?$aKDim<16%>EW:*eDK?XIdGkD4F1/*8yXYD@ll=yX:A@Gu>&M<XPy*c6<>Kyq<w
mIe?u6 lN%&8EtKRl/JEHMRXWiiduy%nt/>WjYDY=?BIIa*dN/Ee@9T4Sj9MCE#^We@=D!yE&tyY&!yiSy?K=1c
m+ISqu Jka1Q?X+nILikjKbRZY88PnVMH:hWmGPt6F$h98=F+>adIeX=qi8$ZYYNTuKHP<*%ybdu9dKCdp<lCG%
IqIecA d=9$<pwZ9PQGw$#Y8aTWQ@Z$1Gp^#FkDIbID/\TFDYblGbdt*+ZTdIkXilkcEM1BeR6lGk5Zh?&IT=1S
HnKiK< dG+FQN%@<6I&1GS9p*^pQ%6kt/#5tkeyHW=8mGPjGHi*ScFcHw@dCH18*TlVq8+jEcTkV%knP@iPT>cB
b+SRKL #VW%>@:RXiFP+48B&heb/4ew+w=\miuYEI#FntQ=ue+NBd*^i*?/eFJRN:I9ke5$jhhnA8j*+tHp&CQ#
=B*k&G pbY5un<y&FESDn6hhMP^BlQ*KhuaJ?*KHm@PP6eGQZTAQe?\6Sp+jWdESKZYK<#AthJ8h5H?GtymwTN9
%Y1V?/ GLce&tS9#/!QFZlL5VD&IdFTHTt>My4CSuW^jmDA89Q?\Nn5&eS%!Cn1&8+4:<W4T<ZQb$*<cLq+ZSK+
b!Dm?G cMHtbdLZ!A8/Zl?QeyQqC%J\^e\#C=&b%LuyP4qFcSt5&^=>lu8=+6qbLk+dh@HS<:pKV!CH%HPG<>@c
8lAcSN 8Bu:kC>1Z?khPJtdSSmBdp%4n@h?\:a+!buTqG5ec?@6X?9%S$cP%BVL^I4PeQDk1ACVA*n$e%8cm5?a
d^pRXD /d9F?R8#WR+Ew?T>e%cP/:jh9Q/wL/<FucE:wmNdmekX8N#c9nmWb8A&ZGQ+eW6:lb/CK/uk!q$ldG=<
4bSFGk tX*1ync9+l?R1cKlhLM6=>KMRH5cV\Jhmtj^+uKc%DcbP\pcFB/BaAXT#t8I=H!Kc@X1Y6ytMWN=1&/u
+RBEPZ @=lI+Rc>+<KP>^I<w!aSD&MicM1iwFVhJK>eF*D9ZK6E$5nI>hdHpZi>DJ4:YLL:<c*@dy8><5$<am:q
j?m^6q h:Tm6R%V5VPFV:kMi=XM:m!IJ4!NmG5FqX4%8BM98iYwZ>VR>!Sd<ey4AdW@j6LCG^u6mlR4*wZkhGqE
XXn*Ic 1=&5CBYM<&\1l$P&Z@bENGWQlQV\u/HXi@:tTMBCjZEiB@KRq%==$@cA?*CLbj%TJbY>=hMCS>!1MeJJ
D9YYbL &i56m+uDt&$qtciPy!TDmF!uy%/9d\dMGlDN&*eWJHp6>QB%/wYLqZw:X$i@RdXcyc$/Z1Aw68!q!q\/
-AB!XF 0005a57a33800110333 Page 189 of binaries1.zip
5ETeWW 1:Ql/NMilY6y>%kV6RCVeLcLQq+Yd6Q5GTwul>V%tK>GKT<Z8%M=y/\WF<dcEjVQi*$cwQm5^nC\ew^9
l#kA!A QhZAemW9=PEZlep@tkyD=t4DC%9pe?NVLD/Cqy&hYnpYlSH?:e/+pMCudi1nFItnF9$5pjb@=CuE=w!c
Mnt#QP Sw\dBhZqBuFG9K%@J6a\EBa:K>dQIHmFwTlEW6/ia1HDmGdldha:85XA6\EQ9c^VAb6E%G@cNPq*Z%11
nKPCPX HY?jlHe&#R8LLl>K:KabnccK!q8$d^@MX1ppikB1Kt9qqKG8aynYBG?e=R:&dweShRu:tJjjPncIe+X&
HlRHK= QVh%DR+S%b&>eLT6WnK!*wLZ*Wpk/>AG5<iR>+In@+Z$45mq$b*F!XmqYJXC&=EClVN!1lhXw?QuLaS+
HLcNwH 8=IYY$ABT&Ly:1juPi@\Q1!n#<jNtk<VVF&!YQJ9i<R@h?!G/yVB#cHVRZTSkbLW*AQC@QcBJh8t$jy8
LctT%> ZhZ#9wa!bHVDPV*WdSKT\SFC<p9b<n%!Eb6W$=NcqBK&QaiyZ@6ch\%WqjnKM*#&Ykw?dwhL+#9!y/Q\
##^Zdu /aFnJZA8lC&S8VcGZQNa!88y$#elDY1\Bm1KbwZe^iInZZbyJ8:yWScKc#E:dt$Kn+9qCk>hyq+6lY4#
hnnMam TAk#BIItce/ikM<1NneQjRyB#FE/aTJEINEh+S^#8t8VXk14yw!Xn@uyHIZlVHLq$mGXKXZ8%W&TE>cS
5qbeG# \kL?DaJjcKnSd^h\SR5MP&VtNVCCeuiTJbyG^JCi#/!KSAtER1%i41QR&ALL%YB:imE?@KIiM1Lu@Am/
AASN6I E&K!QMhycc+ya<&y8W&n8YB9T*>E:icSYj9L1iH/^pYJtp6$ktYXD$C&:?PDFCkhc:mpbG@!Ilu<!A=N
%FyKnY Be!9?&=?cTwpiIV\iKlIbF9R4AKP9:%>?T$^R+&h<lq\>N6bPd%!VWGlSqXHD=^R1l/Q\%tXabX5JnFi
+&PHp+ p/9<>AL!GwLL$W=<pTL=$XukLcGFXdil8S9lTYde>YaDIW*yVidb>YcXLdG?T?jwQSR14l/LyMwa9EE?
hQYWdh GGGT@XDiNMq&MCuy:TL%TnZYIhyHt=@C++E8nFTc!kc51^B*cP1huLG8//abhHy<a!=@kEb\kMEA&taR
deGw@S \/&nRLbdCT49DbqY@qJHdFI$LG^mVT/Tj^*Z4%iwt=LG?:Ct?$<XHYJDXYHnEC:TTE$cCnCKKd&<ncQF
=uX\al !6SH96Pwb=FiRJN/ic1d::YSkGA#l?HXnlp6*XcVh^Qqdj=F$IjXw6AnMGiD9E1n5J/L$%%Z1$LtNC<e
CX8eHA &n!FBQEc9\&:&*NQm/elnd6?K=>dyYGFl4#HiBSnwYTG6Ibw#5@JMB<4Y9kk6%I*\:XnZW%w$PidX6^V
!P#Fij N4JGmDPZQ:9TWjnE+yC>i%9TGj5/6$Z\??b=SV+H+1*4&/dNwB:XKF5^?#\t5kJq?>1R%c\NPK*Mp#t6
aF@cyE yjW+?*/QL66*wJ%M1c&dV5Fu&GT^=uq%:=t5u+#T8A^:=MZqQ&@l:Ml6MwQHa\99W!9*u+/Eu<#ThtQE
Ij6t!F hhXGNFF?iX#Xk+^^:XTjYFyD!#DLQTHAp1>KGd%i5qVA*dNj+i89>Bjta:lH#Lpk$Sil*NBcn:kq?jDi
%d96^H iZG\w<8:MBCnq+/TtIc<9Sp#S:HeAPlhw?8I1mE@nVtB6cV9lDqDp:Gh/SZXC^i1lAY#%n>\YFh\LNTS
neEE$y 1qP=VeaJ5h#lb=IY9ZCc6/<yaSkmIPlEdMhuY@$BN5k9Q8b#d@p1:5\X9jF4A^:T=FH?+6ql*d=ZhE59
NnNK*Z mLE#HCLK<&&&HPqZy%cZ1c=R6*5a8XDnF$cw#HQMXF@wWI6i?1GJY^6!#%FPW8BdVAE:NPAK6TTJ>*a4
MNI\l< Yn!jFP8PW*Vd?Ya9m%uJR?GH4pRIRdN*1N5+u4T$C/mpXVA=Q4!*/eC%Ej#&pniJeQ^F%A%ZdNQq^Mbb
FB&lCP ycMcDmK8L%GLpRmy!YnXAcuZJG/n!njeQ?G&HI#m=Kl<l/mY9lV9bt4Dh%y%*F@*yLZ*6iJAD>5FqJeD
HpaZ>H n=>5+bl#FQG*Tj<#PA#yd5BXy5%hp<!$l8:94@?$\1m6$epm!Ht1ihCYJJuNW@bCPucP6%KGLLy+KTtL
@6#<mD PpTqWFHGSiZR4Mq#<>ju:Bw8lW!qYkjE^&u61m9Kd4>t*&GwnuqneM5Lu1^LphNVlL%/Ib:a!@eb:jRY
/EJ#!j kicqe&8*Dt</by+q%q<p5?$&SDl:LYyZ9^w=e*Q>A>N$<!q1YD6M?1d4K&/F><^#ZCTXa&4CH+R%Vi+W
hk/*=# JcueQ<^Fw*iyhHi?#>X4dNeh$*@m$4&W9l6G!dXVd4K<6YADLnSF&\&PAC%D5CEXi4MRdHTd/yG>&*t^
XNpMXC Ia1G6<KSe#lQKna#kS$:@V<P#T=JN1?HXSQH^b%L1&SiLlQL9L?wNR*GY^YLl5D@y$kmwCGI@!cuDIj<
AIJ!Di uXPGaRB#!6>yyd<SXu>uCR@EF9:Z4DD/B^en@a1%PBB4QDYh/B>enQR4%lkA%pk<6a%wKPT*4KFA4QHW
l^5=Vm N1Kl5N?!lkP\^1hem@/BT9K9YAQBGl#QLkAcm9w6c!Bak!Q\YcN@!^wI%8ARQL$Gk@!YNSC5\jB>MSkR
DWJiwm 4MERiHAPA+I%GB:FZnRM<X9YRLAG^VhCacnj5kcCNj^:CQ<yp+#>L?Pj:TH<1@D&/^+C+kic8?l@F%D?
myXbQ^ %^+CFA:@Q:<KN@@@CM%hkckal6$YYKP5<klWY6H/5bl\l*%NlJq1%PP8S1qylG1QeP%IBjXXe%I?el**
c?u5py mZ89!8&QuF1B=HQKPqBe4qVYik%n4+EL?+QqlGibtZF8=pQ5Y6y$bk^!t9w>n<T4+<%a1^D%Y@I>ay>4
<BnVGq BP5&I8Tc!u4t81GRLH%6eS*CcCh^/pa%AZqIeZ#h1TktiRG>ajwk>^:eTMmdi$m+FV?5At!pkqHc4/=>
+i6VIp 8QWb^jIe\huV*DNT%&^ecuEH%Wi>&TwH/TwMHKTQ*DtX^p4K!G@qy6IwQ<e/FWCu%aew:4Bltly=?P#\
\4\BZ@ BhRyBZmL#kMXbaSnV@@F+eMZ8d9Xuk/Dwd$JXH1NR^6*%CDq>>+NkIe&cElGKk>:m99BA*BI8ldH<=^Q
M+yPyt =D^:<$py@HTJcb:*&B4=mnSKdhCdJMn5nEVIC9/ldKL#tKWuP*a$*Lk5\ii?:SD$Dqi!111nlknCRX@@
huSZ:F pcTb4NSIFS8*Kym18XVZ!CV?^R8G11TH4CI$+q>Gu5kN/4@THPIT#e1A>e#janSJ8S:ab%FVSWp*jutp
V#Sq:1 1PIy%cJApe&X6hwKY!:Hi=4u+dcclt9mn8eaC5GQ@lB%8qw5N#L5@1XE&@^X=m:M8qh^1dZK#<MPp$jj
^RDD?* hQt8*HDQ#qcXGJu%<uM6l*b?Y</pkmeWXZA6=q=P%X:91$Q>n\4l@6PcmLB4mJjiQaQ/4+XNEqMhKHle
I??ukt A6TQQEee!tc^yj8#%J/qR<VhLCGb8XdmHn*ujSFHE6cn$hkhR#>u5cAQq\=J%XGa5KHW?+?Eu<4iqSy>
%^jW5H 5M6*e/p5u#9V\N@NGXKYw*laH9&Itm&ZK6i5K:tN^W!*1>?KICQpX4XiiW4FXe&k?:/<6alR$\kJi^!V
E#5:9^ YtW4d&Ee9a<<j@FRkXh%Vm@S6mGEJJ<F8^wTH/GwSqF*D#JLb1dnHSMM&cS/Iq@<^<88+=1Fbny%%ZZ9
W#CI1B &e&V%cVnae$n:>tQKb>H4JE4<&>t5NLDdpWwS#RX/qi\VSJduMMJhGji=?\elcby=c!y*DQ@\HJ:$Che
lYB/i: WI>HjkDLpqB+#%G^qLml4y@+?XaV#LXC<TGjSH>c:CVY%wiVieuDPE:VPjlNmwGmJ=SQbRAPn>$=J/DA
n!wGR$ *#\&4CkjDjXL!8tpayhXCua<8q8S/=y>959TGH:M>lcmMGhM/:#YmWm9yA>DS?c46m=u4/aqnQljNnER
XHSM$q plBawZ*Ew9!un4C\H<m*yt^PDb^FmKM?MiTQ#btb+GQkwld^J?H6QE?RwH%T9Y4k45cX*d6tdM?N<u$p
iGcnZ+ %N1KG=JPSJGCp&<L=4!X8FY<b6?F:eTG*MK\it9A+:8I/\^my=Q9pFQB4>9tCuy>VBw?1!9C#/aR6Gp8
QX=JGn /MVuHKb$ma%E4#QG%CM@918I^T:n?K&5eH<Q*nTFwWn&$haV6:kLGVPXXYVWlK=A+uPq!#$=YYSn\qXZ
XDA=TV HmpGK<?1bHZ4qJYY5\p\wXcGaihW+Y#*MnEFuK#%SWtmMuZmm^elM$\*C8R*9G=%#t#RQ#1TNuBqRiNi
ZT9JJ$ t1+by:y*mI?A@*bQDqGh\CFBdH$HY89y+c!Fc:RqX!YZ9D+LS5P%WK$pyi<9cdG?5Lu?NQeG>+yClk!F
qhe!Yk 9wZ\1GXKpqcd6dc=t*J9YF?\K69$R/e58/tdG4h9pbZc#bbEpkmelGA@/ll+&kh6tk^6t=lyFhXG>?d8
mHKba5 R1N6H#EKyDybFdhk>AX9le>!m1#h<SM+&@TI1W9nYl!SiRCK\=!ZBB#ia!iT*D4QMclWaK%&p?aXZI6N
1BBDww =<YjakYJyle851$FKEX:Nhd%eH?mKl:LmHd\VQ:a^DL#be$\mFw\RSqF!6<4IBHjpe^4Y?CJNZ:Y>NHi
mT4F+P FcpTGJ%B!X@@RD6b\p/mdcjBNN^MZtn\9Z>T@kV+kY?V>Q*8*1hc=5K!EWtCiSDBdL&5JRE:j:QKwMV=
Nwd%JH ySLy:CAwSwVlFtT!tij??eAelh4K#^tMuZ:PBk4$55jGeaXGTekLbLel!S*itaT!a++u1KwXw#Wh+kPt
QZNTWt SjnL6G=XWe4#kaJEF@\a?bNnLi\1ZJLTu!qniRRK/e>ZkFyLQ\mw8BBLT@HXcnqb?8N!Dh<qJuVML:EZ
dMS>T& h6!N>LLZnb6jQwVKTWdMP1VhEn>XhZ18#yBTZ#8F+tG?KwbJcNpBwZY!!^%htaE88P^CZh\64XCRw<tL
S*%L/D R^ciGGyTuAkb:L+/1Vq5I5X=:#/E&H:X6L1pt4XNRFM\kFW4IcVXSW+&W$h\NpW*AN8!nk8JYFkc?ckI
AZ+@6A h4dRLnyjj9HTe9I=IX:Tw9GSbi4%XtZhy^i8H$YNX+Ep##$Ni<C6y4+>q%49*y9#AmFRyyb4#S=e*jcH
@S8H:y m8!hC=P\/VIG9k?mI@^/K8Ny5FcT99thh+i\I+@8y&i?+yCNn>Hc<PqbhH<Zq&:8R<w<^aPJhHq$^?m\
=S?PE= 9M<#?4Zk4k@d$@!4/wj8=V>\kSDjidYB85b?!t/FKE%%N?A6$9ISybd?WhLmIQY$N/A^8V48&qWu=P95
<DVaE& VJHW%/LdmSYFaS5p68L#d+YQc$#=nHkS>dBa^cV1KY8?Ry*^/!JWwLJ#KW<<Q^E&Q9PbDFEuC$iIqFRL
EkRuH! cN%@$@8I46b/<JnhniEQITY&^S?Vy>hu4LeD4#B>V4i*9<IkhLML&*Q6Ttda8QX\=5w#bS>E6aJDdH9?
+1iRLP hItm<4cwVJSyZ##%a@%R\bqAXSE:qulj:CH4kdL<:aVC:EI?Kk9FWq%=bu$!Z@&Rqk8Pd!J6Q*@SWKA1
CiwiM6 +D*Z4KZkhIG\ZC=$j8=bn1XiEL1kE^S8k::8%CL$%45pN@Yb@XRad455i:#u6c6Y@wCPujJa!NK=LNWe
V+\Hei 5bR=Xdd+JXd!X9CAS6$#K=N4@jY^wY$*e\iT?:5?hDPDF6S#F5BPViptReiRanZp5&\=T#T&phENSchi
btT:M: P+FjN#m@:%MiN<XP6cpd$C+l?wa$:cu<D6Y61a$Qba:cKhYLYPe&6Tmc#/JhKWTHi59j=9DVHmKwW/:W
6IeM#* DlKkN><SMR$W=hYC<8p*$Dk141FEF5Bcc=JBhknIA6HR\E5mYu:%eBu%6:C5=i$6%S5E=b?>b\KD?quI
YqM=y% #Fjk94l$YRyT8%kSB\<p*=iQMnN>DXlL@+>tYNh*=WRqqANdM=IqSZMSIaFWF5wZA9Yu=Vuu=qZdbZb:
-A@D8E 000df3ba8f700110333 Page 190 of binaries1.zip
W>wy#< A^@tl6\>SwaV6dc>ZVHmIm<1tt%KbdW1F1B5<haa+m#NEnbB=tKcYq!uVq5IP<RLCiJmdXiZL//4kybT
t*puyN F#XqcVlY!&&\TEqJCFEI1&mD!#>H><lXCD%WjE$Z*#t^FPSaG4BpZyk=FY5!+:<#wMJm4aVPcR:knWAy
SbwBIw #a#/B+bFBnqGDHuVYJaucPRPc%c1qd#plT\TK!DKXMJMl1^NlyJ=qQMLPSaFi$k1SFP%5<iXb4WFepTd
DEA$&I iHjP==#pn?uqhY?peb>RHbT!!npyI5@98QH++RcPY>c4JL&JyuB1knTLaaGNqGD:QM=NEDJ>1#?&q=\p
8E:I/h tQFIeIEjJL9cP1mqdJn@C/qJBK=NLwiVJl?ewW&LeM\F>d>C&H+Ym+QI+Xl\dZ>A:dIa5N8V4y>jm:1u
kK/LYX Pm<XY!w5LlS9puq>WAp41uI%J/?MZ@m5q=hGT1Q?wVAEanXJ=W#^cEFP/+%qAXX<n6L$Vyu\FX4*/4#W
YF+nbL 4aEhacJCY:/!w=yRkYYmc+:&*RF<%QPePmWZVw9R:JR=b^Wy<4<iPq*?YaYl#/X%NZVwTLT6BcTX&W^?
HMa=c$ 1e6Ncw%m6W:R!+ce4YJPMR@KV&Yj\cFi?mC58qL=tJYdaKq%MS\ZqdQNWTV+^Vl$>Ky!DlIpKBapL8b+
&I^uJd nTD1$SF4j&1I6VQ>!1NYH*u#Ve&?45+F=+H<y+j6Fk<QQ&ESp/kl4i*k:KH\VX4N%%icF:$u<+G6tG\?
5!p>p/ :N$^$c+\^<Ynd\5NBcyNbecW%qTy8G*II1+eajl+!1un$h\>iR:4eEwVBX:Z@IXCHYJKL46=41LPM:AQ
$:=!\W CqJtak5BFLFS<&YFbIWMI#KnbJ&^\:%QaA%NXA%LH?RhTYtYiyadQlBDKlEQk*J&^H#N6WNFIG>I+L+6
\?5RhK XQCMM@NeTN8qq/$^uQMy#%^L^TJHNLYcqN>G??EKKW^j/nXk>SRIcGKy4n5pKQBqCw>$tIGtFG\>\4GC
Vm?%%K 5PC?b\T=FJ/^>@kl>kFcH&EpMJp^Ccwlj+$:IA56:4jSIGI!5hk4^K*<e1Y?L\X%Ke6T4SVy6cKaQ=a6
9%ydq^ JCFVl=+?$&wbEt6/$>@l4/XFw#V\5TT:1+JwRR\/Imb$nj15K4Y\AZZL$BMiZJ6Ciq9FTI6Ll$w:Y\Z!
qlTX!D \>pPiuM^Sj8E5YNipq+:KG51E!*jAd<ERS?S#\$#C!yi+phXPi96eKIiwaj#$X9k1K*RVY@SB/hm\pJ<
:T$:1k NXYDJmteDLYLQGA&Z$ApbbKp:$=uQ!YWy*En5NjmTLcZq*ydA%ikA#*mMH*pImjZN6q>%4T!:+$cMb#G
ZwSNKL <a6&qLcV9E#JW?>HDXQW<h9XnG<CK1XpMy6p!/+wBEyidhG:^mNK@9a^KjEZ$K1\S@<Lb6%nH+mb+\1V
i$$#ym yacG!iVVQ#Cili=lu6FcyWJ4acXK5Q<885$B%tGiYHYjc@D/ZS+PCbqpLIGbcXYQq!ieeP+BM?PSHw<H
Du&$G# =!>h#uC$ANtYtJL^P&\hJX9SPMiAeZE@\$L4biVXkT%m!^9X!R^GXC1@$*FT9YDnW/ZWXyAAm:d@M5Q*
q?n1Cu *CqIVb+eXX/?IBbC$>9qIi@dJCdiwl%XjG@\PPi=MeJSG<%1!W6KBLble@c^S9Jn!#jEu^?!ZNT9dZwj
%Z1D<R %!Z::6WXmuW=JWwV$8eCbBqG%hIZ^wc1KB?hZy?lMb&&1m4P\ddcuD8uPL!=Fc:lyW!wqGhDRe8T/bSI
!\cqSe uiAld?e6%<1qTV$5PZSc<Z%cmd8/miynq:FBKj=$TDG+<1Kmy5hJ+haX1?41QlYc<:MWbwuD!58HLmaq
1duYay 9S8:H^aY#keq!6Flq<6F%&hST%j#+JdwNWF6%%AN>&>KBn+>SMle4BLNT4TM1LAi$w>\EPlW\PFK*A@L
EAkFNQ lbDiIY==eW:hX=euJPabWb^:cqSjS@/e1d6I%e*D45%pBSV4YJ*YpLkSN?F%V&I4jn86P/C!Q/Qy9jAY
^JhA1> hcQ@<<1q@$>J>@?<9?pZTHjE*>X>$RnA/4+HQM^jGb+jZAl%IG\MkDd@\aXR9&KNAGKNn#/GI*@LGkZA
#=Jj%W Gm>6Dlj@LY5$EG6<&\X\#P>a@$DN?i@YCH^j:Ah1#4>mDRS4CD!CAtkE@Li5kYANAeXunj\6c!Ba\$@C
BpN:t* I9/15H6k@FMT>1B&?!5Jm@1B\m+c<RPFZhm?J5#@LiRGYMk6X/+q\81Ap@EQjun^#98Z%>M&+qi^HI>i
QWI85l *Z+Dw!/d^TIm?&jjIKJeyt*BNJElly>1dkc<pVm>jqYNEpXdnlWFcXK^W+LiNln?RXP<m$W$Tp6%MqGX
PAqS^= FDp9mXDYn$h^c*C:5uGalTue=Ta5*Q=T+RK4biH=Y5khHc9%wSYKNl&S5>*TyEL%NwD9=%SWjm?wFySJ
N&=JRp D&uDWV&M:=QJmHa?RpwMQ+PY9^q+dL!qZGm/QImaea1hqD:EmCE!RI&WwW@D%*pE$SlmRhQ9p6V&8cZc
?yYbtc /VlJ@<YIQ=tCSC=*!kaSi@I^6qR#FJ%6nd\GFWi86^+BW>QPE&1D1m<QW8ek1cWFec+Bb<:Y?uXntjZW
FJ=uT@ jPmy=N/6TeH:/e@HGI?nnqmJCGyKiD<8HIcQI$>9BYaJupG8uhiSdyVu$*1$ISK!C@IkNnm8k+\*Qn#G
Em\?!J 6M1>&%ITauN&BC#Tjcq^c@MCW:X&#b$LRhVbc<19\K1!q<=E8tLS=^E$Ru#1hE+Z9EjEnYcqhM!mYM@%
FKdTW/ G#D#lVYXpEJNTXF$tne6LqGj<EHW!h<%mYRm6lDPIE4ZSb\Ydpd!DGCM^VDDMTI^W1mRh\THDh&!et9q
V:4\P9 6plcmmTyZK*9QqjNN&c^NGReF/T+YVVNXnM#4bpaSJRq8h6ePK$J^1F:w*h4mHI5/wh9Q4C+L:@LaqR4
/kBL9% ?YBYj<Sqt\V!cdp51R/<Al8QFK&m6QSy6*@>yd=d>PPS<T?k6Y9du!I1&LFwYTe=Swd6pdqZb!Th\K?$
u4q?Q+ RRqL$=C*t\?tuw*14l1khe%TqW<?Edqt\jD?QiK$@6AJYRP/c4FiR9@bD/iQV/J$%+&Ik?BBb$p@%TW%
<JwGPQ Q^*4H%G+/$N@tuCVy8e#<5XHiQB#AjMSu\6yy:!1tM#knGn\qatQ&w=1>QGb&L+NNZ>@E+yBq?N^C/%5
j*B^p9 SWlJmkLm++mXWF&D$C6htwjQ\BWhPJwI#&XEpZL5uFw#GaAlq^^*:%:tiEkeL+^<NWGbPd8:PkB#XT5n
bS/Dmd G:udjIEe8\1Z/uKVL4XqJeuRlwNCV55X^Yii9SWme4W:ZwJQh<hPy<qX@?c48\km!bSZK=*PLw*StiiT
1$kjTY NCJqBbB9:=\+qcQatmuac:%WIyhQMHS@?9q&qFtPmn!hbV4L=yyGQ5qaicbQ1D:aT:5\1CEyY+<>ZTLM
PbJ9Rt i+u%WCPJ<4$=htJ5ahTb@QZSyiPF46ENL</&w\*aLdR&\mQ?KPPNn%%MEjk5cZ@@Dei:/Fq&:$eYDW>d
8twI4= V$\QhiyyB*mVSYbqwFE9iau=TE5@/N/F>I8PEEY/$e&BRiXh^/RhetT:%M:hi*eM%@?klX51I@?M@$Kp
1QaJq\ eeGC?*IRNHdt!put:m?\Xn*C=IbCinW&Z\yC%T@mdTM&k@!/b<Ld#lT$1Z+!X+ci+&&=K#9KWc4G8G8a
jX&+4R e?&Qj9CAn$$?Q%q8CE6KwDqX4$^ea4<%:nmTdb*dWFlK5?+8&*4/k&iYHjD%Q\I=W6kT/bMw\p9wBKyH
wDVCtk addDkhZZC$<VyS\/N1e%1/*!^6\446*iP!?iWIViD^X\ecE649ND4GuN!iS*Lc*TnyQu!5!MP\d54!*?
a<j+>Z RT*upMHaNt@!kt:%qE:DM<LcD9BhVe6Hnm8uw^>=dwecW^?XjTN>ptQhpCYAYn?K>lu^ea@QDm>bHNSL
lGKadN NlW^dL\%L&h9?@IX/wQwyw>RM*cR<mhEQ!M%9mN!lPGc<\+:G$HZ=/iZ4cySBcE+A:dS+VB&LPWpY$4w
*4*CbE B>m#Il>qMbulIpy>Z:CMwFJ*:JDp$6cJS6pY8bX^eBH1T<CL:IRa4=WJiQ%F>Z/=C+u$9heL!WZeml!P
A8Eb6m YLp%nuLaX:HQ1+=KDX>LN4q*mDhcbqM9:QSPEW4$8uc&y:#dnE::k=GA6FtRXH:mXpZ4FX4h!*ct1www
%QLC4A RjJ8hb9V!ni&Tuy1wl%H8^>y1mHX>Wu6djRHPnPw?S>S!GPu@G*kee*/:q/=^uJWNAp/Wq*9aq<8kB/<
mEkd$p $JH%ti+#cFmKabwPi8AnmQn\@FAMq%*GPmJep6JmjHy:RMajT/=ZXMGtFyQpeX!&eW^RmNVXy#e!Z@QX
*BF&FD M8$Jk*A\%/#L#WGSNZp!A/a*S<?EWR\^#Vp<4CH*BB9S9pM\heHaL^\%TS?#X/q6w:A>hp%cb&CDYR!p
wLbJtt =#Me/+ywm<b\GB^lMT@y$/#+KLTCjGM\5B1qIF+>BN4Yilq=%GhW&GDW#KMGy:ZDdn><n>cetq#ImJT%
PhAWu! yYH^8N1+QY6G$aqkR\FLR@+\*MB%TDNL6@G5ZGjb=M!#l/=XEmC\N6dw&baC1yVju5p>i$cy&Nkw<qa*
nu%The @>p\6?98/uylRTq\p:RMGI%bXJnB?jBCi>t5@lnt9LPq<8+B6w+&CcCcidpElaChL\YXlJG=e$1hYpTI
haF\@1 JatWqX^p/NTC+=Dh\:NXnKmLP&W!u5X*X&pb:RNjP$<aY$k!1F$?LZ?+5#hanJV\PXFB6aXeNZXT=qB%
w%=*=c 1&b$cwTl^Q*LKVZPG\KF6yMZw>6E6TQZ#A<N%Dbj8JlZDuuAN$5TKV?EwE%qp%t<TM<i6&dC=66jL&>F
5Z@/p8 ym9a5TytNZKQWbN9EQN?>R:*y:Y?:e>H/+6AE?a?:=$dKBkHha9iP5@1NjqW*8Z^P%hFj4>?^EJcLRV%
$aeab5 <nVlH:cT5ltF/SawnpEF68!naa\Xbiay1HbJNuVAhmF6uP<RZic%Xu65a*c>wn%P/jXp<QML#PTadyYm
&1G$:4 YcZCZu@!e&i+JqQCw6JYLZl*JHK8G>+bFLl&qj#>u!l8tcD#dw<NK#XjehXPH1j9j@P=?GJT>A:JSRM^
uZSdp< :a9M1Yii4KE<YY#j1NlIj5yI9cVPMyR4hWb5:pX^h1V%WqqIH$mP@?Ydnq\id$V4XaKqiE61qAc9AKFV
9Xm%QQ ^/Wkh#pTtXjSdKT$8KH&TquTXaTnJnEESBQycK@tdq<1eci6&mH+5!?BKYnXQbGkXIwpG#thiJ+Li=e<
FjyA\m Wjmt4%HPMa4Z6ii=y&XpWLnPSGi5l&mYmdJk<XWbXZ?FYm!hN>d?qFHi=c%IpmylPVqBGFtla/CL>!eF
kAXZ6b XZQe6G/@/ak!ka=k%I1n>bl=CiWd*GqK>Guj/j4Z69K#WnSF!qm?99V5CYeRIy<HhiG5NbWak:qKuXu#
b%:%b% hphwIJKkyhI/Q4l=aXXq!hTNmV^wY5/PILnqPKNKSI^K!9YRQlN/wm9#w8b<Jk4pH!Yu!<*V$/=!bC?&
AcXcY4 9<pVE5$58R/QWbTQEVY%:RNbVqiVabl\5Vh:JK@KY>NTJ$q%nGw:lNQ/h6PHC4CGSD8B%F@GlNJtde+R
GNFR:< K%^SbNbV#DYl>#Y*TV1nIb4m55bPaw:eTD$ucu:L^1iGt\FLcZwl=w%Q916&P&iiBbyKmYyLCp9t&:Tt
\haXN\ 8SL=&qq/QWJ8F19Ha%&4wpXXBn6Z4pewm??PinRC<#?GKpD?N=W1$cm@K%YmWaCXKk?!ld@tIV?+Z8Zk
tYbucy /mMA!j+Q4qj=FY5+EG6<Ti<Q4qj=FY5pAG8<!j+Q4qj=FY6^INd+TA+p?4i5MRC5Ejk1#XCR*:IGknZ<
I5RbXa KVQ14?1BB<a@VbpS@/+imQ4S&YjWD>RDaVDW@@q*ljecjM&W4S9!8h@WWWT*B^KdNR\aw+<wKTA^&NwL
*#9l9\ WFKNKGn?\89L5L^PEkc:5<!y+nh:VyC/EhcZm:JVed%L8V^/:^AynWA#1>//^XM@cwW$/jTbi^%*\hc*
-A#&dW 0008d5ad4e900110333 Page 191 of binaries1.zip
*u#QHa MR%6EaX=Ze1+4Q\BllA&$LK6@W+\BaH>eF=aHVn9qBld&PdDN^<dQkp:CI/nTEXb5B&pGiHwS6!JBt!Q
yWCp^+ 1KP^FylG6pN4DEYk=jyJmt#+?u:hp4ejVtR#@RY8pMB!8pt\lb#KV*qVnp%alRNeSdEtFDETwSL?nL=E
V/n8hY LBwLF%9q#\h*XQkQ5bhFEll?dHXR8h#YFqwZpZBYJM8HHbVS*JNF+e?NmMtLni%y4SJR^A/YSVBMnpVF
c<%=RJ pNuA=VI1Q\u*tpt>XtkyWT%?nHD5Ttwdl5QQMG8GD>k@FwMK:udI/c!<XA8mJ+c^kZS1FMF/+CXLh5*6
$?=Vmb LEyYQaibkb+lFRh5HVanTN1mJZ^m>!RyXJiemV1T<XT4CFTZuX/=Mh4q:HPQ!\NDjbAW9jjX4:y:Jb5%
n1py>! 4Ily1Yj4Zy\>S/mCdpF5PYklVMK*@eE$qAPPI$>nQ&/#D8q\bqmbC5>K%ZTn5tYc!kbF+1HXI*9h4:pt
uXGW\W lDEFTh<=h4KmWj/D5<p\e55b=#m>HDhdh^JDh&F*ZhNY/*/NXjR#Yb>GDT%X6LdQ1@hQyjI%*&>SNE=t
W=9+Ln y86/+h::=IKyuIk@k/u4c^JT^CIMQ!mMPc#K&5#H^%jY9B+$WtE/J%%/NYQw*G&+hpXN1Z4V/kM/<<jP
+&/9?S imjQHu+=iwNa6kY1X>*1EJEq#A1uCHKILL%$=<@LG!e9pB?P&KB&eH+It*i+P!j^=XYe=1ZT&*thlZ<R
LKqFql $1\+q54e$>I9uaW@e>Cjb^Cb=Z=1MR6?>=yleDbi9!dwlc5hc<%Y9G5c*/D\&%MQi:wdYP9QYjLGKF/#
Z:LqZX #GjhpyaKDuktM/%JN!V#cP*5$#8%\YeZ+lM<&DV@SD!:eY&C:WPm*lQpE?>T>>+8#SkBDZ/HpnPuZW%%
mF=yRC hSmuLwEI/XLm5aYn>$NE#AaRNSbc:DLVAqjISqL=#mdJy*q:e:mTi#J&WJ^:@q\L/>VBTp!m<!V?c1^i
cHnMJm ^5DRLY+#1kkh5AqPKy<I>#G4^*BKn&iJ=TVVMk*+Ne=RwQbaNd<lBT8ltZ$phX1#:\L:YFNZ5GLIAGiP
M#b&J9 N1YiqmpeJ&$qQ?:#*8lnLKJ5yCeAFEe@\!pIE1H1w:<ZFT4hA+jS@uG^TbH5kbL&lK69hS@eKwQ^&VCn
>JEY9L Cm:H6&AY@jcC>JWLJ/4Ft%1aG%mXRpBl^SK!Vd55#XeSh6d$b*NJhQum@dBGmpFD5NAnn%Su$hDNWBYm
jAITW1 JD+lN8$$q:BpJek=1Ta1?$<t+VF#94ty==R@9k!TTljKqQZNb9T8XGPkZlHP/$uyNtJK5jhaQdq8@V#Z
dP5l=A a8jT>C9DAqq@CpIQ>m6!*+1Xn9pJTbDQ$J?&^ea4T9FVEy+TII4Pb+8LQ*cuaPK!DQeH<p+\tY^n@CpJ
kiS8dt QenWDD5PV5HLW+W4bbX&YE:kcCInG6w>Rm\RpppayK1yyH:LAyN/!I&Bk*WYZYkp<%#EaXPt1<8$q1w4
S#p*GY QZ6RQibYQ5=c:!S*61QjnYH8??^/8y#ZZ#ZqCAXmDb8F4mY+dSKWJu%b5XZ%<^Q$%KnRMYG>R*^by$9c
L/*WP+ +munEdQ#c%dF%8d5/kqhpa5Y9Zi&Byj/^jN%diWP<YtSCc9HVn**/^1R%*C@q!e^T<a9iDY\<@QNDl/!
NCQqqF y/>M^R&p8RXJDh5w6X*=XS*w#/ckaqtdqbQp>E/ZJCpQGBWWB/4&*I</QHy>Xd<^6VyeJPpiWuthFXtq
5+<jVZ Vd4ch*k?jqbdyCww%1qCCP%VP#JeDXN<KG/W#?=t6qKMFNqJSZyI&#uDaIZltaVnhhTW8ie=c*N#k^<H
I5C6PT &:K?M8<T/%I<DhNYwVX!\54SF%aZ/1kt^#B\\<Q:\kV+9K8!n>Ly^y+i14E8Z>c1GXcNQMKYE4%m#T%a
KQdRSq j*9FH%yw^*1=<FVF%TK9Gh&Fb!J*9qB+/BY?i/YaIbEL#\<me!hJ8tenh@!Kk!u9>eYe&<Y%Sp?@RII&
Tq>jmM P8AMw^$uKnjeNX:TmRWhM^%n6GmHth%Q4PLItn6=8!PZQ4DeR=ijK$9jRj#Mmdu!>9DdJa><RmK9%H6P
u@YCR1 %E?4unEyH=e+hLtCmXA&&pA:^!C=Ii:m&nmmipMTy8C?pKYHNeP^jnC5t>\&T=dW$l=+NJTE>nchFXcJ
aN8L\l 6Jhm!*>9VPYu>1S/k1+X>IKZpw1uPLlwe^LYES<YpBaHM>S6bZYC*d+I%^=\+@Gi&dXJu&Zt5@>Ie\TV
HWauKy 8JlFD$cQaS:#+TaWB<c#V\c#BWmWlFm\MTHkk/J@SK>TSS&bSSY1%B8$LqqR5npL6q?WYQNGEXPa9:Vt
=?4LQh V%yV^T!hd19McPYPGLR^>I>MC4%*5quM:/XTqhw\8::/^+66l/YWJ:P#I?JN+^niu$W<AmWcyDcL1Yaw
wAjtpW aahiNu1p/k&+4ne6qJKYeaYL!!Gq\P6lt5%G\$5>Xae>t<Lb+9&p?i/PELKV&N!Tt9IMVhNRY^tLD+A%
@Q#nad NS:yw?<%VHpYj5n^NEqy$LG4DF!65Dj$*yZ!A*^8EC!+&#P8K:S&W9G=6y@IYyqaVi+##&S@i%tX8ti9
b&lqWA ?c41=WN1BRX#+YE4e^NFMb+8YMe/=5yJi@YXi\t!A5w9N8lBWTMbu>GP//@8SBNj%B+9ndX?+Qd^4W#E
Z%LkCw RQC>/?>/ni#=*8BiX?4TQDJhAGNALDFJ#V+Z%NJ8&+wn:S6$Ek9tK5hwe<yjYl>?:Lw%qb4IiWauLKQF
6ZiD=I t91l4Qhd1WYnZIHKE!RpQ$!lWIn@MTpW/4<4t!Z?k!NPKPBHuFA@Q8L$A>u/k$6nAaY%+4>u@4h1j6V@
FG^S6K YlHwZ*6Hi%E^DHKRSj:ui#E@$6V?9#e%@wIkpP9@G+JA>$Rtj5^^mQ>GPeS@i!mK@@eKH@a\l@44WN#:
A?&MRe d$kAR%Hc&huF+?9F#lnp>+8hMWnp\aQ+\eQ*1=+^KPnB\$Fn%EHn::e+W?<>HdRYQ&k6j6Bc@KC%?MG4
%ahmlk ^R<cw\<cH>\Z59h$$By>$By>$By#$By#<G4MRYQMRYQM>:pIBwEeZDZ>Ziq9:\F=<CB?<ID=@kA>cA\>
5u=&>t cQ#>e?&>CH4RGu4RGudRGudRGudRBu:\9?AH@\9?4^jB@>Zw+EYIk>cIk>cIA^<SB+$SB+&S$IMZIR>c
Vki&JW I\>cI\>cI\>cw@+qWQl%/9*ZFLZ*kQnlHQ!Dc!\P489?6\NXMQTQ=>AjZGQ^h&5WGk?h<+N4LH=kDeh#
b5%liE pP\H%%n<\Hy9?9/^NR1INRTj=?IA4JEaFB=4NBB4QLenw*>\neWQ4Qet6S>c@?Acm^>aI@H$?R?85jmB
b9:Z\q NRKB^^wI%yB\QAReGknYpFA<TEWD\SwT*&FNNBC5IVB+5IaGknX<%>Tk$WC\lpDl\SwcCNaRiK+qR1PB
Z=V:J\ aA&B\IM%DBC5IjDeRI:GAMEcAwwHc^kkYENA<GANA\S4eDRi4GGAaA$8nkh4GCBak/Q\aA$DBG6\jAiD
icDjEN MWC\Bwjn\SwGCNdkMD^a\\DBGl#/a/^lIEC\lp@aFAMBknWaGwHHGknYaCkMHt5kYIMlWZm5kYANlthV
H^hR<B A\MBknWau6WjA\GCNSkWn5ecCNd&knW<%pC\lp>MFkMBknYwPJ:9DRYCNTkKV=>DkYANlYhP^WBlkKIi
P/Sn:E JB=4RQEcFIdHG6Acmt?MRbGAwl=<ja+CFQZk/*NA<S1?WRIFFK@B<I^RKKB+Dh<wkRFcR>H+4AG6wTk<
/aN<Mp +^5GcA*FI%GBkeF@I*dA\BC@EV6kaMnjmB$\MNS9^A+aGKA%FI$HLVBAc/k+98<NcA%F+iq#PASR:IDu
pX%CZd i<PlkGIHQHMLHAbw>ej#9iGA+nWIu8<NB:TG+5qmMZBAc/k+u8<NB:TG+q6L+IDYWATi<R$HknWaHA@Y
q#:>S< +BlA5RMi4CEA^Y6+<nEMAknYwHn!MR\CEPiBJ^@DIPCAXu<<YEMA\SwWmih:I+BkDT@qnWGkj5>eHFDp
*Yp=Jn kkjyCQS9YYN?^^wJ?T%4/G>b\*:L?n@SbuZSk$NMCRwSla1mISD^9T>!RB=@yZj*@p*d$>#n/*>R6ZN&
QcNePb ?MwhY?!V&dC>\a+Wl?%Nk4C9RhbZl6DF*hLKji>@R4:?<:e@Damik?J#HQpD^#F:jpMlEAltL$$F/9li
&jInG@ D!CStG?P:@%=II+D+@d\#A=@KVL:=nn1t?M\%F+YB>D^@RpE8Vhk9#1?>%IknkMnB9FMVH?yWQ9QHwem
kFFN@n AQe+hP@nIPHjwaIABBWWIFaS*^4+q@K&9$BFHDlW>wJG=N/C<>Z^9S<A^HFAqCRK#^KIk9<MKu9lB8Ai
?8?@mA *+QKZn:<%jGDuhQ@liPAenEpu6WZlj#b4LI*+kAQVk\HAwQ+=nkEBel^RIpeHE@IklLHD^Zw@8+N$B:j
uXatn< ?@AINQT4+\kMHJDn\LJAQP5?C9NVnAN*jK<yA9WNK98WMRDH^RENVmmipEMe?nPw:FpBle4i^$Ek9$Fq
:Wqa5I u/$G+nmk@BPDB!4m<J>Bbe<L\FBB:/Yy*/dD@S<A^HFA!T5cV*A4@6QB8bekA8%^!J:n5G<4=@=F>EAe
=L1&RD B:bVkYjqFQ@y+IV@A5cli<p=/y9ni:<ZmPPA6nu\Jd:mtJ@%PB#?K$5?AkL@=nkWCeS^RQ6^CH#SIj1u
ln#1DW K!hGHQkC6DinwL>DBRIIKwA&<^D+ppj$V\juL@V+*n\PF@<Gqj*>GCCPA&PY<EAFnj!y+^Dkn8>Nlcl9
?&B<\J $?H?D\DmPDBcCk>Fk9:J+IVAIL@R+*8>nj!&e5JSkFbPRH8ReA!iqSPN?ip<DkYP<d%ajC?8?Pw+EkLE
5#nFl= eWAdtHA$u8pRA@$yXBDAX<+>tMC?JSJ\PKBEA6D8J^\j:+9=?ewJiAGC:kYTePl*1MAARRZa%mp?!lu#
mjukjy $<EJ\j#KAkVDjIeKFBlWkP&:+wMK95GJ\YD&m$$An<$>9>Hjb5N>@+H+DY#QFp@Kmjuy&IRDS<4iSAIV
qLA?pZ @:b\\6AAFp+aBNCGL@#H:MV*MnH<nkPQc9hYp:%M:=9n+nBAn5Q??%#%>:I&@I:DkE<1i#&P?JbH:Gh^
eGC1Hp RB\HSJNnIHke^^9Xm8>NPAna4/#+MPm*WAWGl\J!HBnHD5Qn?I@GJlS/5HJCkZ8?F/SCMh?^AkGGFYAM
*qNq1D QV/5@C!5lYF?kV8Ej^&l?+=D^RGNVmk\il@Q/ISC<YMF9X<?B*nJ**Ma<R$4?*MnEMeB:R*<?DKD:*Yp
6VNHWk ?EC?Z%*&C/MVC9<&pWMScECPA>yaRPMbuXDpV$H?C$uu*4iD\4:F6j8@AInuKEAdK8J+QQ<bZa6EATaQ
SnT1lI EZ59R8*N495:<TkwMJD@^w:G>:ym9I+nAa>P8Qk?Ma:+/nkTDcnHASWXwH=eT9t>D919nmP?Pk/D:Pej
SbIhF4 RH6<D%ZI9TZw1?QAqmBAFRqIjE5RDQ+QPd+QE@k*1P\#@EAeB$VZm8QBPKB!Bn^p:=+%/4i5j:whAu^K
ILlBPG R?!#WZ8J:u/uIhCAynRaMMaXu?Pa@*:NLk\C1BaC9@XQF#DkY#H\9Y?H&HQqc/elAIWMkAwyEPJ+Rkd+
y:1#@G #*a$EEnA5e=?jR6md\L=/nkeA5l^RL#Mn!5l9y?*?K9n/P@4%:=KJFCa:tZ6?$#aX<elkEIGRCWeiJm\
\bmA4# :<hD<Qe+>Fh/HQ=>jMGBnT>A>S<IjPML@1Q%T@^kNkY?FRQH\L+!aX<hF\i$jkE1H5HDlH$@jwM9LN+@
1j%4tX 4AIWK5l>Rku=#ZGEPCDHAiX?Q/+<?Z=e/K?PI\@a*q>\jA@ZeBn5t?N\BCDHAjE!KD!lDkL=$^=H@$1w
*@M/jC A>8u<hD:&#HAil\RL\QHE?wk^H?/V+wBQnnF9#4?6eeBPw:?Leh@81PBBL=1:\Zu?+w8?+:D^AHFcEnI
nXZ5uQ j:?P@@6^N@!PI+A:n9^Y<:L9PBLRAkTwWAiG^4QpI*?!epL*</=jmJQ&p/m9nkMlVjj?NCBmBwqu!Wj?
-AdwyC 0001107b7ff00110333 Page 192 of binaries1.zip
:SZ^mF hL5SC6#^QeSC$h?m+u&8HannkIkbGJ=bBTu?#>Ad?!h^wMl9C^AWBYkBAqTwA<ZkGb^I#D>VjdG@@\>F
NJ*SJh jJ9HwWlA<#mkRl*wn*it9=<8^b8!Ay@H>&MKKQR:XGCAwAKwWAiK^LQp@&ilD9c@dQ>%%l?%q?j5q=il
Y*u*Al 9liD/Q&d/NY*5@/I9=*%@@+jj@4ij&pI\KDj*@6j5kH::+Wl$V>/L@JHN\L8neZ@deycF4PEyA^?MuSW
EpSCDM :X!E4l%&HHFhy9K!ny!l=?mpC+j+Q&Dd!WVCKIlmwl8\b<ESn1NR&\=ZPJnPMhGCI>5cCtcZ=>KW#u:l
qe/JNy >bDNihVm#m4Yw@IC#VtwhDAh:DH:lyit6K9X4ea\TP%k?W!@ZhXSibRnZh>!FylXutewR:BEQtwPSR^N
uuB@n5 jW^D\SIypPWYQSX?mqPGqNm6I#9jjq>$1>B$*E^&*LFIK1QFZa8nL%J?eyq@AuPePXLlhH%QC=NpTt@H
>YJkjF cMHpD4*/!$FJ+tVdcdh^6ni+IcZ=e$uyPL>8$!MNpCMW!$GFy1a5Deydkh!S#S^hy>B>51=^\SCLGd>t
L^%JHA 8mGbt!eJ@hXnCq&&WlajC>4cF>i8eB>b+A6+EHkj@XbLy!C9a>w%4+l?/C=6%16<%*S+lbBJ5aT46u8c
qp*BG8 $LSY$*&8SypX=tBa:NBnmFdI5nBPYt41CW/wwRqFKtS4I^wT^&@PZmMMcc98K6a*bCeq:6AYnKKCH/6V
S?a$%y mh*<W65lLbWI484X?uBT8XlIj+^RP61aDhhBb:lS?1w?h@4JG=>#l+8=KId1SDQmq&AR/hnyJ=Y9yQyl
T\+mlu BV%dhK!+&HeG?5y1YA5J1t:Xb^1km^d!tCBGH6ZtWe?R$Vc>+i#XL1kV:GPq#49#l:u!uFPd+4XKhk6W
aZ\C$4 qbSZW<CknFRli@=w?XL&=+mp<<yDK=Pc/6B1:tJYMiKcW@&1nBdHBcji/bTlBllNy!1X5&weH/w4i$di
HlPc:\ tN+1$YhXS#6PhimyLFBX9/JTQ&4ZS5FJ<S\uIJGca/VV\lAnS*<b!\c/hW#m=iR#P49a<:1?Fty#A%k#
kchtlX 6e:1%cewnhZ6*Ku81q+?@TlXPmMW#XQ#D^ycF$*dV%1E6WpGuqT@8B#:+yucp^C446c8=\>F^<%KF14P
1TNpuA Q%eh*VS9cP8HY<?AaR+NL?<9C/qbcImMe1+@XZ&/@caZcXl$w!n99cETW?9wk1aL&mC6td1SA8VE6Icw
4&pi/P <m56iP@d%F5\eW&jVcZ!#t/qiwR<*?YTS:#L5L=+mKb+a?^PC56AMYLiT5>lipq<&86Ib:QFwLq\:9tW
wK<EEe lYehlAduY>utQ:HSK*%k%#1u:D*/+pZX&6BF>kFRETw>V!*myeYEHqj^QPVb?/Glj9Yiia8u/puH*R#$
KnJuNc n:Ed&d6SEDlup#FGin6+99H*u=\dp4Y<MWD+89Si=Y!$$S&d$q:$Gj@%yMNF=Yw=t%R5Hl>9nVhG1wa1
#cW#LA $PiM#STE#%b1LC^RuD#u%S#Z=G%I=!VEV!1XjF+mW#?1SPPWjGEHZXPt=D4=jIQ&FlF4kKWqD?mE%Fn5
aqM!dD n1<&H+mk+cWaRX8V6wY9*y8Kmb\/X\4GZdla8NIjqi@yqB1dZwpQMlDB$t&y#YYH\1CbTLqF=wYSL514
/h/<4* PWHp9N1u4F?b8/njLBG5#q\jVHC*%#8S+%h>8eF?Xpn9ekQ@GyVai#QL@1Y:luTFE11dJ*I4&eq^PR&%
GNplGN 8dK1LXkSDay?IJn>yZ^p$!HaK9<^dq:Qlty4>ySWPlKu4&=#*tI?qkKthBTGuy@T$ZJwJ%>9b#$NuZ&a
XJ^YqN ibN1GhRI/d4\6CW!&ttF+9Vb=%#D&bbJWeiWdti%YC&wJ45L%/ynFDw^IS9VX&u5?iW=VJX9BSwG^F\#
HVdEy& :qlti<Ti/aKqQJYw8J*@JN!8^VM5XDTPbPRC=XQm8@QVEtkDLk^N5km<YMcndniC!61hLE61Jp1NQ\QJ
p+@6bT >c^AJmIRjIme/ncX5dA>cWQLGY?V+49*d\V*ed#RpuJZ#:I/F6p\Fh&*jq+n>Ct9Q$HDy#KCZm+:@!w^
@n$^?y $k1hSJ!#jyK*ZuS/nkS4>ZnF<tTeA?Kn1k:Q+<8FR5QFHkuKb:*XFbNjCImNWDA4Q4M%!euITi?tMT4Q
YQSbdA uNYV+XDS%Dp@e\jtT$%aYX/eL:IA8#<iqQ$/kZTW5%Wu:=/A!jcnY^6juEHS&<utQe$*a6WSWA1@a:!/
&9pmp1 pSXM8bmS1&1M/Xijl=Y4>\w&PK/wKHjSkA*h^4YhuY>n^9JSMKK&V@1W#kRamS%D@1GkX&hiK66:\mbb
pKGByL p/hjupm96#yZ>LH<D6!VZ>m+?$y^=i!L#TB?t>5PceP/>%+RaM6t^n*1d^t8al*8ZhAlh!jNHRH#J9Bi
S/S*!b AB@>E/+ZBqiC?X$YQVyVMZceiP11&YuYZ6iCe4W5Fd+&5/PE4p$F=RniZJmSXXe^JI4k*8GGlbZEw#V&
LM8kpj +lP88aX&\e:L>$+8Rh9WJH4t:LuZ@MR$YAN8Ra$MH1QCZCDq%hcp+aqpht4LFaZ/m6hqSE/:%MZWw!*!
ENAFKp a:hZ%Ja:DEk9<!ZZYlFja!1K^uc^lB1wMBKhV>YLi16#?VY>mFy4X/*MyhMTX+</t!5*PV*EyGRZ6uV:
hnH!WB bX/LZNlNXE*&+^Y+F$pTTYl/Y#h%nD66$Qd\1ey\mL=5twt?+DYdwibnu+i/<pR\SZKcpYD5lR?Ck&PH
BM8T@! n!!1ZuJ\%wy8*L^J4lZ>?q!m6+jaS6V#\!%D6%Rb/1mip+#+D<TRta@iXk?NWWyiYVht</<aM$$@QCQ$
\9uFt# Eh^$P/6w5@cC\?kjGi6QH@bG?LKLqn6Ti#kd%WlN#Bbh//%Hy1HE5=e95@HIu%NXT6MyND^:i/mH6TuG
FkYwPS M65*!:GRe>$+h1W>SKqGW+l8$&KZ4h519tbE/Gm4u#YW<:=lpcj^?YeJYdF^y//tIS1iNn66M4#%N!QN
@VH?WJ 8BZGJS^Bd=&\<SBM/q%qE/e>5!n/CHXaD=&Xd6Wn#C9eL:V#pV*A:Z19n+X&Nn1+*WCuh+:l1u5Xk1V?
%FT5R? @1qhdR1Q?1E8#65M@VDZc+G>l=VNT%><5G^i8M#<RDqLYp*:G4R^ITNAc:hmnh^Xjbn!d9+:4wh&y\X$
qIPM8: Ey<V=y#V%b%RNL<=>ulABXFi^HXIbXDE+wuW5R!D^6b&u8\4%J/l5%*8*MdCniYwe?dVS^5%VD&8u!Z!
\>BqRE wQp#B&6!1!ew&Y?HP*Nak<Jy#DCK%1=DKq::1Nb:4hQ<4Shb:8VpywTQXNJbMAlj*5lLVK51YGm=uu9@
W<!dNL MW=T!+A\>jTDb>bi4#e9VBw/51YaV:*Mjuqd/<\mRWtZXn?8cEZ5#Dt4!%tj?1=w:LC/p\h^=D/SX^Wn
T1/:HD nayy%4pW&KQHw=eaVdEd?IDRhA:c%BHn+yPut8yGlFc##Z<w^Ga5hJNw&wXaSBBG?%labBYWZR<y@Q!G
WQQl>@ 4<u#Dh61Pcei^=T=^Z6T@@lZ$Zw894dZ?ynDbW?>p6$CNjWa8F+9h@D8uM*uF?kuXw^+Y5I=K=yKRtCd
EcKmJ> da@8Pq6*5bum?tKQYlbbALd$yabYi46>YdwhybW9Xh:Aw<XSCPS^d6=$dY>&n&uZt%B\k<8E+Y9@&b8=
XX%?8X da5yA4$Vy%#j#DZd9%cw*+b\yBM5WaqP*wy?VJW>X^Z%eWt+lya@n<TC=4yR+W^pmmqhiY%*<Vt^mTGu
RD>pME aRbX5E=*%GTY@SV61V9$QBV=9D:t/+<QcVWZ:XSDaWGY>iF>e4hL=*VD?B<Z9TAKauuZZ?9Z\?F4Q:&n
FpbtmH >EY+<!PMX5jPuk4i?jFDbDGNM1hAS>&%Ai+u%18ppKpM+TmS#B+ZcG4m!8aDqew@M6FbdnL?XGD4hatV
+kZPe4 >l*YlbMFnn6Z8>JJ/SNuuJ\*Kql&qcl5#+JTq1^ai$N!T&n?!QRNC?\uX>A>&y:PS#^?qpla6tVIawlj
<MY6^/ kLj9XHD#Cc=hRj>cVHP/REC&jD+FtaI^H+p#Z/B:@6^q<dq4ZQVDFCV\a!RS*kK<Tl1YG@JiCdt<\kMk
KAaZ<M GANB8I$9#QWi@h5LDNBuhKEtEay!CGLc+\YYa9P:H<^:9Jc^<GCjNZt4E/VH/RRq81\jd<GPudaJP>$m
8nGWED !5?N5B<TSR!bY@pdHlL>p/9=V&+TdY+LE!8yaP:yTB=aL<@eXb=a$%M+c?:b8nQqKa++n+y$uMLNFVjm
uW5RLW 69Mpa!jC?pA1?kJl$i5WmaK&9DeLKcJJ#cQQttnb%*4c$TZcMX@9c@tnRLC^j<=lN8#nE4m*%Z88@\^F
ZNJuim =JK@=hRqH6>4NyQKHEN*5<6LA=j5ccuil:Kw!hWu#D:$DC!pKdSZ1dA$D%:N!L$?uQ5=5N>\M*?%P&b<
T%F8cb =/!pl=X=e*dtVkp1J/w?kd#YM:8RimQ^kj6tiy/@HVWCJ56KX!ye&%L@uH6*PJyly>h*PESQqPKnZlBI
J/VEEW 8b!=5#\e&66>Rnc>T^W5wQbe&twkVVNpNCRQ41V1TwtPGbcKDmPLj58<91WlMPk:/eLjTC8KXtlEWa\I
bc\d%^ FB@bwbYltc8M+iWkbY^qLjMT!jLPeNkXCdZF&81Vm!nj/?hj:5<S+KjRw$XWY68i585VK4!FYukynuC$
=u>1tB c=u\1k1<=V6PLWDI9FZFeInybLlqDpeLXYHcQdlMVwSmBeqKVGp+a:CJM5h4nM\8BhHA:ab$Wbqhbh9c
F!^ScQ ?c$9h%%ZND6npHqe!Le4e=!uXaX9!BVZ?m6MuiNd\Xp#pqy?DLLV\duSBFb%1iV8/kjlA4cXq@*yJ6Nh
@j=p&? B?P+$ZK5S#jWX:d9wAwV6+WVl?*$Qc6LL>CT6SLa4^JMSqQaB9KtJ>=WhKZI+l@Elc=!lnuaKN6YMG4n
$=<*KE %DTw:PRKk=#?XHTNmI1#\ac*a=9wJE9V?BQ1BARX</iq#A@>Ie16&yh6cmYqd#Z$B<<\RZ&iMI>8B\>V
1lMG<n 4%^H&I4ICh=8:m?$:=TGHqHECFDNhdIYYJFmG>E=BMIN$=>u6cmG$n<uyAbX9iZQ:&dSl4IM<8cI\BIk
G9KP*h :JR4JC=F4>qEcGK/Z#N*$at$K&?+ZnuPYMVW#/LqqNneG9JHyyE<?Cm^\*HIa1/I68Wnl9y=<FED9wjt
!$DHnC q9YZPViy5*V%P9SdD^q9!BWGYuDb^nDyJ+4iL*^q1\c^HYlVK@/!uyBlFWF!Hi+V@m:H<y%!5JXY8N\T
iPHile LSY&h1ileQqQmWR:VX*%n:WZL!nGC!S<RMZwHw%bESal$JPbyp/jGFCyLJ!4XQh6P?jj<<HF1@DNLjN?
L5D8$l W#qq4X5!4%S!Ch*p=/=yF%LD$<!/GM$WEcW6D%R<C1TbX9qJA5?kXu!jdqcmN4tKBPmajX@dG4G@B&%p
1ZSG\V d$+\=HmR16yTbpML%/6SBi+85lVd$8!/>4hLVi@t^C@L/:?<qi4jNG$tXF5aeE1EyLA\+DIyAi=bVDE%
MhEd<q MnCCtJ/tXMF/#HBFq!c8&b&44Ma4l5RyhEPewjy/j+kw4b9pi>@lqmwRCGub6k5jc#\$1*9DjH1*m?AD
wHSS/Q YP4C8a<cI$@+*:FT^JA68ml8N&Dj$i15!1IjSA8tby+pZl1VS/$?4D6D\lB>>VL9:R+>ZI/etQ<eatbC
j:lZ%* nGlF+!cNSyI\>hQ4&^edulSwtaJ!JLIPY#wmN845^iye9Dq:G8B9YRhFcJIpDJ5>ZV#LnbujinF:qd>t
FdC+$* 9JB#ZHeet+P$<B<QaCS/p$eqiZ*Z*cZ6m%*Vlk@=+am*aH&CaSX:i:HDYM&1ttM/LVil@FSmZY?K$NjZ
MSQ**a i^a9waQCZKl9ZRNbd8+EV\$:/pH$4\eq4Y!/*6VJy8mn#jj6p=Syn9?^u9>*>dnjF/Q<d<4i:j%><j?i
ERQEkK :B$M>VeFTlkMmjpX&V5a>EB*Da1AHV\kDl=RB\@w:\@jJhL*Hk+cI:<#RH6QB/&SB/%SB/%SB/%SB/>G
-AdRTh 0008a34d1c300110333 Page 193 of binaries1.zip
utuJ5< HVSGHVR?WNQei#ywLZ:RY9!k6jlBc@VB1>EHnhEHnhGwk^ilD%ynDqynDqynDqyn94<cBwEeQMAPHk=?
Vjyaw@ Gk#!4$dj*\mDH4TGH4V?nwm>l+QG$IQG5IPjBwMh6Iah6Iah6Iah6Iaj9By?$Bl?$Bl?<NNk<IQYmIQY
<YtG=* B=<Qh9D=aAijD*d\?YAHu\@&@jQ69in:X@8ZN6+B>ja*59B9=P=**Q+:%TkP\:MQkMIA5Man1AiD@Q&5
y^iRik %k?5WSk<XL++FIk%G5<Y?6?QY@*IGwZQe#kRc!Rib9u9J/b?bI*A$?h@q\L<pVWM#:d1*\<>@ekcZ!Z^
BdjLpm */WAj&CN^FewIk+Ec$l<G<LmRLCG^Le4m\cCNTRTV>$CGknYpAk<&*^wIFlD\9DR?YkkYENC<a\TNBC5
1k&dAN ITF+SkpcCNaRcD!nBA$Ec\l^QKMEDRS4iE/=:XpD\SwCkc@QkYANkc<WGRMEc\kaun:HAMHc@5dyn/&B
\dhkAX aA&P\hQuGCBak?QdFeaA\SwelYh<a+BkDa:EM:+^RLAGS?D4e!Bak?Nd^#BA5AcH+yqdMEC\B9?^NN^i
K=!1Le 9AIEc#A<i=^RCBC5\Z=<BHdQGknYaAl<%pC\B5M#K$IlRLAG\#M4RmFA5AdDM!6CIcnjmF8kEQHjmF8k
c#EE&= EQS9^C%RCPa*+lawFQIdeR5WCmli\@i>waDmNZ#jG\ywDeXk<FkDYpN@LHK&b+$EFQZA<XmnAMW6iL+*
\qSclJ FFC<l5D*9RHFc*A<M^MWWL\G^jP>aaDmNRki4MEA4cFwQN<dBkMW6?D=*nA+wLkF#@iGIRDFLZm?N\^R
t&kqRJ 9AdH>:eB^Y6+TtTlMED^GkVj>\c$l8KdW&GA%qB<e!weAml8\hQueCmk8AZQGIMDm6j\#cq\RQEc9npX
Mb@p&= Dmli\#iu\kG6wjntXDkKWN!Cb+#BkYANn+#\unWcWN!CD!$aRHELH4RkkGANu!4hh%d9@=PmNPlj!4q@
CMm<G@ R=\N5^ep:B?ck??FGmlAj^wR*aLGA@P@qHQ@>XAQ<PQQi:E&Ck:==nmk<!qRBCC8B5@=FPlj!4u@e5\D
J^Pp8w kj!XA?ew1Qk*^&EaRI+DCqL^uE?B@1Ye?/@uW+Ajch%da@iX^d+/DkWGFWASL4:%<!@q*Q@6w$!\@TMi
!5N:eR ?$e>>l&HACqYlTIBleh\QM5I<8iDE:lTC\dCkWTl9#1PSEMAPR=weEL^RAYJ?BqWkJ<I?myA8H>Gbh>^
kVH@+t qDkk^\EF=ll<WQu=+Q\FGcX>+eF9WEEmkWEFWFTQL?hHw9?yHph!IGHjwaIABlXAKRE?8kEF?YtQa+Cj
&5CL$Q &6+@a@khKnBAWEEB+u?SiGIhFP!uQR=<XwHC91a<Z^&HAwIKCqDmm?jWNlV%<<EJ?TYNM<!*qSMJTA\C
5Vh@@4 mkI$PQFqM1mjD$:kn8<NNaV+6=X#Q%$E+nmk\ap9mWL>R+N#j$eTkj1&emIAuVPEA64LR?LL*<RlQ#5k
hj<6uj Cj<FTaY>H6>D%n:^l$ABkk1knWAE96SSHQbV^*<l4IX?hj^4n\N$HQ=dnmN?18MHjD4eq*!Ej<e+AlDG
q=aXLC ^aF6C?Fb<5XSQ^Y^kQ/KpC\C?4*HaeB/HBBHkYeZEC1P@tj$YGH:muIa%DjHIYlAnkQcpMK#ARqFR@+b
p@L5<C mbu>?kI+G9:XeVmkW&>RRD8uCH\MBS4&p*PG?!JGkKG!N^YKj+QK@9aXEMeBDW=<=Akc<e<eAwd8/%Rm
F+=w>w 9\Xb?#<AmPPABmi?9R*$Q=S#:qi=\BHjkm\+EqCRBYnDF<<>bN?Lku/mZAXeu*4QD#n<Y=RFS\CK5kB6
hLJWMw F?P=A?%:FhM@eAy+9$IID9&PFWA!FFBAi<%+4q@:ZuYFV&IGD9!I@9+pAh8ZwwB<t%1APA/I?MT#RR@F
:pSu%E @Gl$\4=DBRWDLl/@6+L9#$L:V5QEAWEF&C+*H1$\KAd%#<!H?#Xp??XuZ^%HAAwQAY&S\<V^nE=AY?R\
qb^!Fd JJ=JChAYPV=4GAV!#\nZ:/hj$P@JABSRMkAD64?PJ^tARYA@C=TA*!1^u*hD9!eDWEDJAA#a=n!ibAAG
VSZ\4& Rj^W@^&+>6SiMLlQFZ?XKWMCe^#=G%R^DQK#$BRqDq\SCQPNK9:1PCC1GAc5LAAQXR!DwQ<bnP<4Ti^V
ZC1V8c ^X<hl\HDPPa*1GIaFQI#1Q!CpkRM<bXy@cbwB\k1\AwT<FDFMPk@6B&C&N?F?T=qlARpbRRDXM&A\ni4
>Md>ZA RH?cN\JQ9@b#STVmt*kWEyDiJA^aKRTi<qEaFQZVHwj@mkRGE9/>^^HAiq#<N!yZahCjDp+w<E&:9bX5
lcM%M= u#u//nke$K\C4AkDlYhYkj$$MpXAj&Y*ERu=yp?#@\MAPA+D^4nmtXXkQ<5d>*YTkWIFljw1QQJXIA$D
qSN^D6 CPPA!n?RQ:+Z?Q9=Ad\WA@DIhD<:*%i\??w+CkHIeWB=I=:KWSkM>e>wVCQ&L&Z+LtYERAKDCmBTB$@S
6aImw? Kk#&e<aX8M+aiy?FRu+ZASRH=DkkWkhQ9T\Mny>^*d@*AREe+=B>8bX9nkQTaIIBKuqB+NFkk5Fl@>AC
eJ1bkJ lIJ?JZP?/w^lAGEeWL$MAw<GE\!P?IjE5d?K/aqD955ZAy4IAXZdIQDWGMQk1H>tY?H4%WD:i!L:SCAK
lk\V5S WHkIB%aYlmhakcQ@Ic\kWX<h@>4nAB*H@I:nCMk@=VnpK\9%%ZFkKSACEKtDL\Z/ebuQj+qnm@>KSA:@
V4D*%1 ukQBkiXAkPy<+Ql!IMVQl?e9LJ=:RIF@V+Lk\JIkRIW?eH^JEAL%D$qG:n8?Z!?#j&ec5CRIWKEQHF<T
!LWlni lED@W%$8D9*1?he8B?k==ue<S@=DY!L:+5K\:?pdDFn/B1nTB++9jWQ?uBRT@!Y^!?@yG\^a?kcw$kiG
SaaL=$ L*%DAn1^keIVZ\I1%5F9njyu<wF>i8S4mhS?y\E1bIABK6dBh/5F:D?LhdD@bj6he\@/Z=y:*??1$Q5*
?6Ct>< ?d=>#V$E+kici:B@4<V=q?aiam?8?\e$>>lyRQ/9GtbIEC\S4e%8=d=GIllYM=C6hB9!!E*FR<RuZL8\
y1VZd< HQHKPdG9Ap9QRAPbYpBL<tBH!M$IE4Bt>Ik$KJCGQ+9XMhBCmF$Kq/YeALbFF@Z+cW6yK6DJCM1R#yqF
N\4HZP KyQw%FK*N5iELPVhiHSBdLB8>d15N%6E/eKEdj%h#aJ??/i?&Nw\CI8KMk+6:alXE1iR#+KGyHhaucJR
iTKqb: !bHS+Rl*I=Zt<L!MFmLHNFH^ddPV%LphVVI58WWb\&JV>XAGI9:<D=XdAcqu&^FCbL+FEcRG4nZ&@D$&
L/tpnF pIu=wGdK^/=k@lIKbX!lm:khYRJXP=h$#8h<8eDLXahZy#!\@AnyDm^Z6e44L+MkyZE5S:XGuC11pVAj
lwTe#6 m/k?aY6FTM&XT5hGTy\?V^BEVEXQTBMJSw8*tMqJMnjIVF5hd5cY8:M*8A1VTATJ<A?DI&I/5LAcNa8\
Fc/De4 ^NLZ=8ma$$MuX?w4Z$5=5tYFdSY9\6cGm:jkVWee\jKE68bD#i6$$+M!Y16QtEklaDutaLyXm1EP8uI:
EV\V4J Rkwu<ARma6dnEmXIYtwT*8\cja5ENQm=A$\LGhad>XPc6q@yd4!w!F:/64q!+&H5k#?RQS848<M!<TVC
P/9ukQ :Q$X\w<at?APGmhJmiH!dN1S\1/*kwk6KeXqGw5upC$nmGh!=!1M1W>ZX*$PWBA88T$kq8N^i$*qnFL*
>T5C$L ^!%e^8&SubNmF\ZElF+>81PI5=My@qSS^9Zc411b!9!8nLdlNep&8K<&PbZHKVe&&b$nF:XGb*9wYJ6p
KmG^@i $%?CRhJ*HC\iFXXNpa4y4b8#Q*59p4%FT1hYFqm&M<Z8W4S>S!nW@LAWF61<ea$c%cJQ=eZTyEbtRaMF
PT!^ZM t$D<c\8\d9a#FAphZbY:KZSk+cSHXbdQ4>T/*4Kw8*=GybBGWq=*@yWek4Z@ZnEt68?XClm5/4=8Jt+j
46M<ll uXa>%M4wIJ65//X6#=cZ$YGXYn?K<:+=aTa:u&EktHC9X8dV>SkqP/MwHnXC%Ziu+kh/lbHZXEbECBPD
@X^Wc! pIE1%^\HlJ>4tqdy$BjI8wJQMJ@>uD4C*P=VdEe4Xj>bp>l%F@Lci#:t<=q1A$!teE^ij!JZ45%w86XD
>nm?c\ I\$cp#VeuciNDa58A/dXh86P<&IiY%HHEVLDLtj84Sy8@!H?Tcn5unQypTbX5N/%!LEAPaNAhnd%E:HN
h>$1P6 wljiPbGZ9Ym5^wkk4uKjI*phLY^:T%>R<H!9n\V*IX8VL4>*Y6^Z/kY59c>w4G8j6TYZ+6iYGeW!MHp:
iJ%FTC t:LtQkWFBkl?<R4/+#qB:nl%w@@WJhQ$qwikpM9TFXEkk4u1W=:<$!uta1=S4EeDiB@n:1AFECGF^&4Y
AcAj$I Y/K\M&k9@5RVihZw:9R5MmhIRm*@Jpqj8695ySICq1aF&GZ#\9?H8DMQl:L:@:n/IhqKpjK$VJ1^nG*t
kGc$SB Q9h5=TtM*aV5qeynT>dTulblLJERJjXI5yT65Xa1>elY%pmYqpi!S%SI1%>Vy8@%@V=8%*H=Z4@jj//L
G=+uR& M<=%:9ib<::Q=:^jJ&IH/jtj!ibnb&Vcm>$DR:S8w1%L4NNdV%cH!Gli8T#W9CEc:>nji/8k//WMH!t$
*9StI\ 8tiwQE>%X>Q5>1C=qwY/kaWuyiKpBTTYdSI5ReLZK:mauk!=q8E!%B4MhGi4dHmi8WTt>wG&@^>&BS6W
I=ZZaG &6iJ^Y*?@YBpRt#KGh$u5amC*X>=%CTB+k<9*9&8<YDYLMZ&\::?==XML@XIZ4ESnWk<L$L4aI8W>?R4
dMNCyI %1:S@N*hZt9F8hRX9*%iH8q1D!:&QL+W>=qnKj!w>p=9c%Q>LM9alXJLc?iGbeWW5:hX:KT#SmLu!pZ/
Yl\b\q CCb%KbMX5*FPbp>ydX*HH+/XK%8WNIQKWu@>EXebT^D5:hI4q6yNEyMKMN8ZwS#J/Yy:=@B=d\#\!K68
V$QiT1 WDK\iiWdF8qabRT?LN5R&4>qn>na:Me8/WqjCG6XBj%8QSS@*86\MGc9?G?Xe<8eyhXhW8j6M4&m4j<B
@$CVtA ^$jS$t!Y#GF9JF^aE&j>b4*@&5dd\qL6Y/$4DI=bJW8lmnKXTMjay<id#EwXN#XjNZI9nF@hT*i$eEwp
$JQ&$i >W6cq6!^nt?$M+?RtM%^Vd6T4dInI?&PuR!Nu4Wlad>*ljFJ9^CK1e*GyRT?8nNNP/:lyEY$cB*SH#dq
X<k=:K %IXYc1CdEt/W^N/<Wh#!1G8:=9PLjtWBWXEG?LWbWuwLunwcb1cbP?>4d:l8/m#Ya%T5pNDFZ!Mh8X+l
En\MAm RpG<J+Tca+&:%4I=^6>F6*^XhG6/SP+j%8GqPLt>Z#/i@S^*K?iVCLHEN4ShK8\PYHt\AGjj?ck!+6D?
mk^Hw= 9Qw1X$%<W?8>QBHq!G164#6PEic\<\q6F<<5j:8e9P$Tl^Jlw/9@=HTjSuyXP6?hk5R1b*ay#uL%Z:n#
I!J&TT RwX^hZRN<%JDw@*QM8Ic6:5JGT:**>Mc5t&98:jc!QY!9AY?MdqidkSLeVYLlSGenjqp$SiF>$QY+?cP
CHtDYX QF4HaGW*C&+$d#pTwBq!$J?F^/hGqM&6pI+?STm#*eEWL4AtT5ycNw4ipZk+Y&h**&a=haQ##ENThlqL
CL9NW4 NM5?j>:5FdlB68V6>RXLnLb$cqA1hT%PTX>@L8b!?BW^N/a+eXH?<Zj/FN$+>un9MMQ=R1W>Md5^W?FD
RTM%5i <ZF:+<!6M8iaWqbFD:dqtqZMicV1PPD>\HVQY<F4DW9n68\LYnCddS&&/ID4p/K:PR+ZH8tY^CBD:48G
aDnha^ Anb9KnSBJJ+c!KLXjpDc8jVP/N?=P+aW@5^nZ:qeeQhC*1&9#^ZQ?S8+6A?@qN1bIGl/^^C59JHaDCJ5
mn%y89 #KR:e<8X59KBdVJ#*4w?%R5PcTtNLmccC6dT&Sti<hp4e+QqV1cK&lie8yuj6uTkSuQ^%bn=ca5p98Ae
-AImCM 000ebed59c700110333 Page 194 of binaries1.zip
lMH@ZY 1&JBZ%Bud&K&\+edu<%nFa!9H%hQLYBqu+:!P:&n4MD1+@n!>bqHLpW9JJpi#N@K!aw8*EMLiHe%4eJ@
aNY1cL p$cB+e4*?TP&V#wdu&@4MXmKdJjPpZq!QXl@>&ZdZEZS4c4#iuNtdjG&&@LM?>&4qLQjmw%c*JjYNVS4
@w<I/# G#PY6qC<jbMc?<?<EG*aHmMYH>HKjqDj6bZFa6&#Z%V@>=bXP1j4tRXIReRt*\bQhj4HG!yJwqYC48kj
yWenAA w>h>1wpPi%:i9hilZNE6H!%R+cKbb=?Xd9:!#\DS9/JJcW:C!/^4KqI>$/n4<B&jFBh>>uCnBFY:4<I6
<TTtQd eZ=GG^kJXySKE\64<lpJ?9nFRH\<a1Hc$Y%CH6Vp>QHW8F5Pym>GY:%DT8<6tbhbS%=JY#8kZ589QJ+5
Ie$t1V :PSY^Pw*:iuXtKW@Yq/deR9Zj%88=HTjdY4Nt@61bpGGy8d#!lyTl/LY#$i9K4nKJ&qyhG#^56hId5&%
AnBAF# K#8T5NQ8Z1^=RG88n1=dY>Si?cK#ZTuYkkWt:pi6*PKbX:?5uHe+W4twVcD5yFnWe=%DwuJYL=Jp6dVL
aRJMdp VFPEtG#*ZRLBcMcFqp/#5uILy>KZe/@JKLFFVSM/^nLZ*u&\Y/TYMp9I5D/D?1qthy5VS>Y?n#G:tTA:
DRV9#Q !kl!JVD=eR+phdi6B=%IBcY1=Fh^mNHPCNG?bL<8jj<M@e1AG@kIk$k?uQM#e9HS%c<>pSNhP!41SAP$
MF19n5 YV&^Jpuc*<K%T5M@CL*/atica6h>d+9HAe8KRB*^^<at8Bm&cLBL8*djnhkheajCDk^q5E\++kQ*Zh<a
:YaIeM <!X$KdeFF/&V@Twq<QAYduA&j^q4CKiX\hh1d=Hub9nG8e>nRM/JnVhw@>L5WKd4Xd\Pu!/%jw&p?FJ^
HJE9E1 >nQuDw6D4Dlj\TLPk<:qASb@E=aIiSS@abYMl\Vw56X%A/&a94&+:4b+jayptINWhYJN/t%>jyiS?+cn
qmQqVG e#:6iTe=:qcQJk6chI41SyEG4mb8>FleQ>VYY=1=JEK8QqPtRRDQWiKW>kTabHQiJw$qZmWFl%b^p4Vh
WPwuYa eiW4I5PmFS\Dw<\1^a$IIXaijleXHmZ5<Ee+J%L&+SW$JaKbZkqY+WVVyMXM*=BXA?&mJaZ9^FJw:b<T
cR^bMF 9E@>%4d#5>d1Z1?n#@VPeCIQqSA<6<tJy5yZyL4JBlDt<peGlA6#e1K/>tpLt?T\<htuXHL1u1yiGI/K
?Jjpb$ 95c?JhtQnym%?Wt$Gm9X=LD6D=?K1#EtYSQ&YiiTe1/%G%ZXb^4:DkRu4/l*EEy#iStw*h==?LHu/le>
X:yC<k @nI%^McPD6%RA6XNTdXn@tEu&/<DQc>1cdNpH=HDi\tiCY%bTh<!4JGhbMwAHh\LFp%h=Ib*&V%*njSR
VLAwJ* %hi&l@Eh4eItejwTk+8%C%5$Hl=##SMREM^IZpnbjWuq@Vcp6GG^RblJ\kNm5l=N/*BZ9Wa/\SJ%1$8T
kL+@6< 9&jqJAL1>q\W4l<RPJ1bc:mLHdw+h:=5ciHGltnQ#P9pd4dYaLymS>4+1m?9mc%dPui8V*l*<X4m?\nJ
SDA8?b 6q+Dyy^C<i:#T!+VA%Y!=Ah94*udRJVWYbdSj!Sh%R&QN<E@iV?@XF&?/%CRlL:EwbNPS%<V&HT^qFWl
y5ld+h JXe!5t:YhT=$5TQ5^ui1?cbW4>:q/HI^<<%q64Bqhd!i&&6>:$?9#L>q#kN1AewGA?yBhW$KhyLui>N%
1$&?t8 Ba@yY8RXF^j6J<jj6>k#VBdp5K%<hNyQb9Rje>>y*Xb&tTVI1u\6Yh6j?Qd^lXAl5hh%ttlNliPwuaR6
:dpw&H 1#6yja=?qy!4jE=Nl$uY#jJnVQ>*Ai%=^Nw:TQkwJ/!QGYSwtXB6djhRICFT4iP\XeqVt+nwQZ#FKN=F
1&RAFd +P*StmSqNCGq&/uFYElD::Glbmt4\nSB4<=9R&/*aujMMu>%^<ll<&A@4dImE\<d/&=T?iM&u\*Dn+TP
XhQn<$ /i^eEKmTMT\SFTHm?Kd^#cDceX8#h?Pu^*!Jc=pBV*SQ:GPGqVuY*:WaVFwybF@wh$TFPCSaM&C9L:Ym
Y6aZww m@A@D8y/ItQ^bqI4e:?5Ki>au@DmtH&N\L#unmYHHVuG^+a1X*dLYbeJ/\c<6nab5>Cd:%VXHQI&aLia
MDi#eW #8<QZ8MJ91#SbV1SycbYCnGTPeqZ4a4d<+!h^<ZiK&*k1:hlPi5l^F^Q@EXl=J6c?MjpX!8qip:+4YaL
u=R+ci G\?/l6hd&mEy#Z@$tL98FS/ZpyDuCDZy=w8iiSQe+iZm9cAp^jcIyey1>HddI41t6+Cd&T=e:Wi94pT:
e:mEE4 CJGX=YM9byeJLMC*=Ck=QRq%/qm#!wM@&H5hQ!5I9?@lH>=dCJJnt$/jM^qR^A<5$^dKb!%<$&c&W$8n
LFCZTT >b!J/6$c=R1BwdhuD^\XFG*tM^WwCB!yqN668hluu9K>E9+:?<N#Cp:8!Xq9>DlnYH?n!4=Yw?IDF!#9
tul8iE GiaPPFp1/PkY?nRXM$hFZ%EI#tiJ*V5#LI#/hQX!:Gy<QVwa1:ydBB?&6neq>c1t>Mc<T>a9VA/%#W@W
81pt5e L%B!qyjnM=Sq*dV/e&EI*@YHNneEwt/IPKw^i@kZL!A*T!?$IF=yPDPeiQC*$#$9h/h:N&S:XkY6CTw\
lQT4Ty #T$/?d=EaGGF%ip1Vt:h^:^Le$jbc^ihtpW+=$1P>LBb=$M@SLPeR<pcehnZh<ldW6#4pZ^kauDHW+it
wpj*9A %iNuee?1deWGHei#@Z^5$l%6>kWp:9KR5uq1hMtHj6?VbkjtW#PF6JkdakMTD>TQ9A&YyIVqdb>>wQ*>
pqtm$S tB=SYq!aZ&kZQ%@4kXiY?<%eFpS6Zm!+pT/+yu%+%S6?Nc&L<$?MW6P>4/ejY$CZZ/AW9#q^e&TQW=VX
XbbM?V C9@t9njNuc=:*i?u^u$hHR\=<#/plPB%t8:V6JS%e=N:9@ut4nX!Nkb!kRXY%dw9!/$FmXe1HLTGw46C
?j6?cG <Qduc1N!B6\9Eu*PJjP%LApqBj*FLuByP6Fk*Q#$&Hc9+Chu>=wa&T8qY?Yt9N^jJBw6aVQ+\m&j>aV@
q1>B/q 8c!V#VGQLA5SMT*D*>hcFH+d<ZVWcN9G&CE>S%89y#&6Y!FYqP?8w=dwWG^Na*VPIFu=?6Zj!lTZTm^Y
4Py9>W DbSp1F!hy>1lYnjG<Ne*TNDRcT@!cMEHMuFEj@twED/lFLaEy*@XSyLc/?PZ*^KDcp!mF@=y1!S$L!be
eW/pS# 9waTa1V\k5>LRD=BS/Q5NFQ*htbDjQJlX<TAet:+yX9P%p#D$dbumRH!G>TieAdWZaqIhpNwYwh5/8B=
cl!WCC i8y&iw<ldVnh6HGVjiAXF?bYDGkl<8<yy@>#cCH!:%Gu!cCFQ!:1?ki$EKZ<E%1Iw6PDFkL\5%Qjj/D!
W8^QEV jylk*AEiEA@\kHmAB<RDQCAi+G%%IaBH^AM<wCGk<Q/c^#MEQJ+l+QEMAa>uCHkdcAnkAR$BD&kIiBlD
\9n=m: \KMZAl/$EQCklaD?/%i@i5SnFRIi1^D\YIYA^!wEnIu@kjKklTkQYwn?klcmQGkl!pMWwn^EIW4?>T9i
?89^$K B!G<D?ISCqHp%\j^EIWwD%GI<lCFKA>SmQIRlTn9kcC<B+KmQQwl!u5mKP?JwPl@$Ah=t=D@8d*=#+6P
lT@CeA JkRIR^>EJkt*@dM%Fu$RwcIR4dEwQ5kp?dSJYtNEaBA1Fca%Fc9uNJnYGMRJbBLm+!T6Wc\^b<C$^1AQ
5X\<%C IyMRH!hynSG1RCaJip*TGmQbkNBk6EdBmBekNBm6WVCP?CM$GK%SMFl&CA%Gc^RMql%Ck>Ec>#nb=K%l
>@\h<k 6Eala#%9GK%SME/:I#Ra4cEa%%MnhBm6wSl*SCN$GK&lGQe$I*Ra4YEipKHDcA$FGGNPl>Ec=lpZPw#Y
^hW^V1 8C9Y=K%l6IdF+WHwMF4D+9AkhBm6ah$lmNBl6Ac\n8$^aLTGhR$k\wDSGwKqXAcM%nA4w\\a4ZGL#yP*
4SMdpW l6Ec>\nR=K%l6IabMtDAcI&MXa%t\GmNnHYmq$GjmZhkMGdkHRCJNAQ9AEnpGZkHREKk9AMJw#YA<k+$
d5TNc: nNdwDL\DIFFt+B$AmVwD:\BIWG5wBkERpPk#<A/A^ID!DlnQt$!ckZeAbDLW/w@XGtwN^VnGB5lRc!nG
6Z1IP! WVJAlqyDMe+YAVIFc9*GGuM1%Q1N<d#JMF4Dw9ABM6Rc!5AcNeaMXu?ApGc\?kMESt5AI>pQEBm6Ac#9
XtyhIp NRSAiRiMMWhRKP?AMW5R1DWWk<IHEC1W</Bm6KbBPR?5u5NwnZ6CdjLYDCnukhF#AKM%BMQ6ARDq%#AI
ZXu/di *RAkWL+F+>5BRP%=aIRhAIDSGmb>EADK@>e^PkCtVGcTy=E%J$*RB^HITCpAWN56YA5StDL<leCnmL:Q
hVb%5t \y@$RRR!WkwAqM@EYkNS$qSb<&pRjd=Qq=@$RRR!WkyRKJPKebwcwFNCR^n$cjEiTSNTkV1VDFAwl+9q
TCbwFw G/aCXbK=d<jRRZZKBH$RkcRQAlVKHtNbFuVK!RpjGiCCIClW<KQnFBwF18NRp^QL:/D$KR>Vp/cDI1JR
J1uq<n jp=PClV<CcBR^l#Lcp%/jQ%j/I%yVE=8Fyd?5?NReV6AkZL%YC/QMmWLD+Wu?qC=LD#G#++nbKmPR&*l
6Q$b=d aqqE!yVJVBI<i8Q:KHQDmN^CH\1XYkMW1Q%jBGN!W1lVJB%w$&Pcen9PHZHan6Nt%HH/j!im\h$DR1p@
@9KW>@ Na:T+VRPNVt^QDq%!t\JiS1WF6LQ1CC*+%BMW$CF&4dGil&kVyuMSPnV<Tw@wwLenpM^VRFWLR@FilPl
VYtNiJ V5p$RPCyXh@@FJ$\YTme!aI1BKJat#9WKbpG<Qpy:45KPtG!WDmVBXXF^LyjCXCubPEB?BH@EiKhtJ\p
p46QJ6 1MpJXaJE5VcqwE1RKAunP\t1BIuhi845%4TeKbmRKX!$EpDXL:GmqRC1jkp\KyAA1u/J*Zy1ZCRJj6Dw
&QBEAI PG+bq#6w*DIZ#KBBFcR\L55DWMXQBPMTEkBX@MS5Vj>9MiY?T=qLnQp^cAnWP^BW=SVB8LEG$JEy1Rc$
RYIHWw /hCyj$\Vd5jJWFME18#K#TlQ*uGwWlmYX1DK46m6J=5mqF<RJjnNpi>4Auqm*TdD4h6RNX5!Bw5e$PqV
i%peM9 $b<a$$nl$uHWmZk@FT4iD/AK9nTMiD?at6pId#m+P@HVI=\B1Gw^=udWyM#Gj+$+a#wRyipS#5D@Wujt
*@XY&: +XC*dS?ZbYRb8$KWbYSuq6>kT6al&ZeTEpPVjW6*ybK6eS8!qt^JCAuJ>1C5&dI9w/R:bDiYGG=8%j*E
*6W>h= $@8?^@Eenjjujj4u@Z?8Pe/==4y?9@Q/u6@4e+I1NXPXw#B:yun:RQy<Z*Q:I=!lRNYy1eyStF?$PZi^
Qle+!j XV>EW$X\wmtwI4emFak/C4Mui&MjbB#pjkquKHAXemw%MPCu\Mj@!+^@@?mPHLWdPCk=CkBZZ1emS\H\
>Da*p& Qe>jcQB*?*j8lKN@kMJA!XEA1Nw<NVpKkP?=PhHkH+e:YDap<kjlDAAXPCl^lEydaPCu\Mj@%6E\?!Ce
h#TM$D IZdbYL8B\=XABR=KHKHmX\LA8RKwhF$B\LpC1I$G=\1kPl4^H+*iY#<E@^4+@mQ&l?5C\FpK1PC/AMTi
D?jei> VFVqji#6:+jq:+@tHa@*#n<BJuBREkXAdeaXj^Z%/99G*wq<h<yBS1:$H$Y8@G5c^kDj**Z:\*WBwK\R
ySwlQ4 %HBhABK?y:mCAy<Yw@hJ9RKR+ARPKt>iJLZ5EwNS&5Fnk1+QI@eJ9RLAiVCwbMWAXi#m@8LiPdV9D*pF
<PMumP kQJ9WNNqAPViXZH$jnmZP#4G9+lZ!1ACB/YNWGtJBQ\9%EZ\&N<jnRV@^a$CqcKBew/k1LSEAqB:d$*\
/?#c#Z J>d9&^H=I=6Hke4tAXC&E^TXdB/kVq%W\tDR<H&pcM1:uy=h:\aw=n$A!4PCwmKcAmnkF=%a9:>!pD@I
-A#DTb 00001f3382000110333 Page 195 of binaries1.zip
1S!hB= wplRyW+ABW1XwXL1BFB:I%HB4*Eq^G=lanh\eKpKCy\#m$y8mXL?Nj*KhmmS8#*LhkJHkq51wFSQK9bp
mw$mYP aG@wIulC>E:XA@EnW$GC!%SAYXcRXG=XARB!#?I!/KY!a/dhEh6&&:ymRC$XWJaXJJWLZRAA@DwK?p=u
6Mk+6T \6*AqeDNPLndA%R&=$<6K@@V>k8>H+\i+pi1kkCZ1kDkJFM1t^Q+h!Lej+*>RaTD@+\Il@^^%*YZCKj+
LW\8m5 +::t9**9#+l\P\@q@*>E8CcN#y<V+cDNDF1C\lYT5FSmTB!?E!iJ#GAR:*<p#cFhFbIbi/JYpQhIVP8j
c5I!L! hE^jIR*!%XESL%k5T<j>^Fk*:lN$IN8*<9&Lt^BhJull\h=CVK&n>J6dHT:l:/I&@FWpJT<^mwcw^t@Q
J4\%?> >4N?ck^l##QBKe=Jb+WcL=CWwGKyqB*t&?R&1\KF8X<>NImZL4#aywyjM=dDqy>SyPd6u/ieC*tAMy<c
Np/J4M E4LP\MTJl=HD^Gtw9EnV68abaRI:i=JJ4GlWR1VELWct?=NAy>k!uKiu?daH<CZ<ESFNH\EZ&&cyD<W^
n!^+B# $4JBaYnGM!LJJwyR5TMjwP\Ib#5GmSkBBql+V/^ZDaGk%h\yV!bHdLe>LV\Mm?nTG8XnwE8M=VePNcD=
<u%89B 11WX\MjD85cXWyj=4MR6Zmq1NX9c5Gm6Jc%NR>&Xn$E$e$m:blq/>Bp<l4+@WZ4\eVi!@WC>Cd!8&C/H
c45\4: JiJCu1q$&W4w5E$+ZapbH/uZIJ=H9<HVHq/ieKSP=>GB5kElM+MQMwdtmi91K+46N^+KDR=a9D9YndcL
m*TD/T Za@lT4KZ6S1AimDd<muqXl45m@buI#VT%1TdX<IY4%1Zj&G/AG#IDPP$m>d=S4LciCZ$TmuNW&:tbh?k
>@ClA^ J8>FmN*F:$qJ>R66By5#:FycHPa1>hcF#QDi6&ZL*HZF/WF<R<N+V#u%=b5ce5PLKtjP1X5bF45i$P@%
Bp1NAX Ean\IB*&$XY?QpWatW>wiwRuD9aSl\!i!9QJ<e&c58AGYF<<m:p:>FEluQ5LY1KdJPtCJyeJt#JmKWDC
Rd$4&R QXY+<J\548qiu/1ZhVtu6yQua<paTE#Y*\Zn%Z1el61BqZSQuQK?>GXB&4$=>XeHEkp<9iXj!lD%bBNV
JEuBYM ?JSbIZDCyeRV?6Akl45!9>*11!!jW?hH6HZ9WIBtRR<!kRRucmpEjYNR&DT*Nn*qen@5kKYRYNQI6jPC
JZ\KQd !/9eX>LNN4kh$P<m&BY<+A8*C:iCIdGDem4EWpwKD%5qcY=kiPMp=alZF&!6!8:9C6<yS*IYBV1A/nZ5
*c8Yla Fu?9ZEEcEL#i1h6eSQQ!Q5:!\NP#kiPnQMYYhkLCiYl:Bh+JBZPniiE*MBePq<5N=kijC?eQGtM*%$6N
t?/k<$ QLaiIY$%aF51%aheb*9<Kn!EP\=ZdD1#*@jjhm!Y:WA+&pH=H\#nq:48KJjjyn&c#Z#tCjGl$JZnL>Ni
&V1wtl 5Qy#<GK!Vy@R5^J:lF&K+/:GMe?j8?:upJh?6/EF?#VW6k::?bwkM9hck:qM5VQd/<Z!!+%yVcLcDu=M
b4*8n6 ThtjSyuy@N5J*yV*ZI<LnDN=DH#XyR#ypnPn&bt:I&t/bZlZ*E:H5>11^QtKT8JY?iPd$ih:H<H!DtNE
L@Yp5k ?a@e8l\*FbYd9Du%+dFk+M#kXla*CW?mc%d%Ch/K&DCLdGKtAQYbwww/X=nb4*EaT+Z:$TbjbudqjJLe
QZyNCF Pu<\JQni=+HBI?FF6KJHuFRe^5j^pV/eB1H1q&kQNMDT6d@>Ft?m\e/<JTe:TV!TuH&D%mA4\WnQ+GSX
EY$T/V !Xqc#pR>Be4^/@<\P/pc!ctD<QnGaNS!VGK!l5i\#!ASG%=hIDd*/ZyyLA?pyGQ+$RT>1TRH55QbyM6/
j@t%6: ?+L+M1hM*SN4$Ve9P5@&1+d4E%LFBeV=##FXy!e^ubVLGFK>*y1tYQ4&Xacd9+6Yc=hc>=SZ<WjBauXh
?C#jCb #9mC1bYH\w&e^mWQ4Ie!#jYQ<NwX4nFBGjMhIw>NaRk=RaL6c!LG&etTn>tNDBC&e@d*!JXt?dYh@byP
%bB4MJ %^M/d6&eVcI6/5jiaC@4eq<L/t>mulmLL8$?Ec/y&*j^5MQdSNME1h#Vd\WTJG?H=AiPD:FI8I!eHce<
qL*%N& a#n\+ECFn>t>WL@ZN!=hPHp5ciNtKyHZi$/D>ymF@KXGaj&aBYphV1ew%+Zc4Cj4e!$nA65/T#h!dk?G
Cj5tZ+ hYITi6#b!+6#!*<jEYe=dBQ/DHu1Ru1XDC+nW##E%qSKR<:8w4cjq#$QIejpXhIqW5=CX?cq=:wbhH=q
HKmIGZ qqp%TVYJ$e<E:15<i/<ypM8d&J>b+jmb!^DhTQtAiKN9TDhaY/$!@t1%\X%E\dm5@tZuNG1m9cInX>@y
Y*^=9u H>\u*A*ylwFH#WMy=Aj*89KGqF!*ET$9VJ>%//h+SQI@AElZcLV4VdaeNj#qu<lYeMX9?JQ5anC#a*iL
NwVZ4P uX:y=1ZeR<!w6/6$$E<$KywidK96i5#nET*ycpjQ=Z9SiLRJH@$CYu+/a<VeauQYjCLT1PGXWCXPN<Q*
BE\&Sh L\G>@KpXK@XywX=j%WLH<uMGEN$^?Jy=N6h+wbtiT%nJd%jX15WEQmyjSjinu$5@V$wyYk?KQ>5jpdJl
q18j<1 u+tGSCWI=X\NZnwybb/R:FHc*!j@uy:MVc#&qny$BWH!Kb&&yW8+/%ZdhhWp&uY6Lm$R?BPY1@\\ZK5t
K#uTcB k@N4j9d>=/jG5WBm@NDY=SLFW!PZ/%%VTDAQk<>e$yP%+ehedI\LK+Y/MFW9b!B^F:pbd&yG4!V$CXX?
hw*jd* \An<+<mqV%\&q1QX:5NwF<BS8?L+&a/ydR#*%NELkXdP:*K5Wdm^8JRZ4uYQW5<4jS=TZHn^enk!TR:V
m$=iMV EFKXpXDKyKWV5!tKJaey4#d*T%eyS9\S>JH*4/5i/IK#c/^1IYN^M=wnWyT^4/e>G9TCB5%c$HkiTCVq
:&=LuH 4&5&4kWZ8y1NyduKuWq*pd?%9:+NM:<^IH8bcj/Bick^L#w\Ee+Y=<*wdiQ=%etwNJ<q8$#=wbdRBc51
XMpWpm ^@YKR5u4\=qKAX<QREWtE&\#@&b>\RnEP*4/Bk^Z<k/@5!dthWYt^b81MEy+i@Q>keXhQh=nLmKS/Kuq
Fn\l^h Zb=*Z8/>DM%Lut@PPlp#AGytZY#J<5&=j8&muK+:LPQ<nltZEVnXk@deGZ>+Zd9tSe=uc?9yTN4tw=Nb
FmETdF &y=#u^AkTI%$QlJLCNma5+:j@uAWb?:\^1i=+PajR^+TypciT#bKGB6QjBB&84PJu8^huJpcBqR%p:Fm
hatPcM p/yL@YjtqF<@^Zt#?J^1n%ZDd1/K&=YiJlqqA\F$qJ5/4@RKWdRtw1p+ibp#6ce/?8l#c+uR\dR5YRY>
ZpuwaT E?JQ9\*Ly1Z*nKqI=8I>9Y1<X>!YKj+?iq+/F4XF*4S*PV^:6k+&G\*Y8/$?ukl@KtnXNjtX#lN!l#ZT
nAAiqy c/Jiy1DiNaM\\#yk9FVP>pXq*mCHB4<tVk^\HC6m>qq#=GtHwTC6qT\qj8u#t=5$=>lC:l^pkdk6l:un
w^eCZq =l&eJ<JK%PllT@$/9XX!nqXPBba6NFZ\ElGGw<9G19ZmBhY>t^t!mZ=uXBLbaD*iG\*Vb5DahG?Pk==8
=9YI&9 A!<BX$G&JVJXdE6T6n$PaZVK>N9pW&N<Qn@q!M/8Km>GebXMK<qpZYJN?:1!pie5DjQXbk$*K&e/ny15
BL>Rl+ HcTQd#M$5<GT6!Jt9cMNQPQK=6mbVaSH!:QLn>\>Smj<X9ibBq?I<9Y5P=CqTWlJ+DuES:cmnIE+!HcL
8Yw!?9 k#*=?NC$^bjMnyA\?XB>y<SqAM<yn@h?^<?A+njF<EhLKy9^H=QJ+aqRKa^tW<?QyH$<\<!+&t>+?BC5
pE8kLA :QXuW^HykLW5R&:b6FDVieNYJqbjVW*maRHuLeHHH\Suy+SkqWJi@i1j<jiKQknAdl*9Ytd8hD6@5MYc
=5S/&< dNZp4H8XZm<q%/JpJcbmyp@CL/<KqylCV@F81a1aDV!FE?ILDaYW&ynL#@B:#bNwN+Jydj%<5RN^QwFV
=ch5hE >Lqc$:4FtiyVhqApGbk?&FTW#5FRZ>M<@ae&*qk1iKYF#C4NX9ZJCA5DamL$4H4XA*S:mi&E!&at!MkJ
&YR$*m iJdtEw6KQCFn^Em&1\n?Caj9cKL99qmNcA\Pu?8hqE9iwD9iI=8Y8yk>JV81+&Yn+/J+PmV+Y^:6ikFN
l5WEeK n:n<*W?11dQ/C1*V\HKlK#\cKTpn$H4##mX:YY&&cM%GByymChhi1+=SZH&n6atRJFLYnt8/bt#cydS5
:dE@lR aaCh$>Mmp5pt!WAi?:6VTG:AVbh9/4m!k=+h@iJ?m:ACnX^*L6$4cnD=t<Et#C+*p$$!$mBtTT&Ytkll
%8iu>D 1SZ4E%ktlaX%=REXPjyi5ccMak=@dy@/e/IY558u=Lu\A:ES&RXGC+5T<nND5KIBaWnAWJ/9!kD>y4V8
BF&cRB Dc^Ad46V$CeVN1q/6kLdFWwRt4HS?G=6SS\B\cq>XG?N<dSkS9/$6EYlJMRSFlKMawa>ZK^*jI*MuBGe
%6aV=T <9dV<TGJc!@1b@*iQXnj61bbnDYZ$<%P/HQ#I=TPIlHc9aQQ>HFR/hEl?Dme9e\6!qT:1E@GK%nbR>LV
B6*ju= &Xm6m%GCjI\?#Ekj1p/pcTVLPFkN<4M@mcSbphce5?8DGy\?<%J:6W$mJQAp599CSL9+$1IqFw/^CHSd
!dZH^* >cl>iqncQ/YWm%q%J6Aq4le1<%5qb?NFHt+/F*alk1qAy:^:e#u>uVH*>ZAJ@CBpe4M$%6cAd1K66P&4
t#QP** 85@caA/n5KeX8#^l9W/4c/Tb<SL4=HS+M<Y!jna=*MNF&8Ln>Mnac9LjyZVulWeKeJ61CEJGADc>9NWw
cuCLQ? 6MtijXE!wnDdFKLi#M9qI\S>#5^Aa?5S5cIiG/6q5H$8hkJQ1^Mm&t4==FApd=5CN5ZXc$$iKb>NtCl9
EtD$ik h<4lEFZHd5F<:bJNi<V!L+m6Kbw&/4wya8QDEHalFq1RabYNR!kiY$eiZ4WtjdPm+KepYR@5Z+:$t&!^
q*6/kj V#X<EDRJw$TPhHjLha$XM?!CFF%88>byY9#BcH\EeeLmCe9c:+?h/n!6mBeK5Wb+Hc8wBRt+aLJWWC45
>puhmu WC9SL9t#6WN:Ty8=yDZb/=aBRT<9wDZ96kXCnPEK>LVmmY?mqw!paejLhyD%NluCZh#TclV4aj6RNTmM
$^md^A ESy?F:1IkKQ:G*\lLZLhTe8%IZhIZ$1IL*ER+/n/ZP@GJNe1!M^<+@SKpEHWqdAeJBD@@TAmNYS>eb+C
k9HB:@ 8ZL!clkC*:PcHb6K&@P6TYhpyiIqVb<IM@1*#@+mVnIiRC:=:>kp>+y<t=dl5?#!bLNKik/#P^\/HkTN
i\qh$= wLaBiuR^\@*^e#y%EGA5uX6Nm&L%6YVNLmSK1&LcnQIu@QZCAhtnYItAPWXQ&Q%XXR<u1#Bn89nmA!?p
kqI9l? F/!@V:KFT/qiH>^1ZP/L$X8c<T#bhtG9>58N/e@uHF6p\n99Y^Xwu$I^u&w!c5+#P8l?XS&8@$@1#n58
1W+6<u 1mVd+!BlEJ8k\:LcBlASWXD:>4%X*Y$pKnTyEY\FWRRBASWSDBmjSBqR5tACEWWBRWGSN&NYXFCCIBLE
NDYy1A MBlAB5ReX5h^H:jlP4M:ZV*F!8i>#@89?hB%PhV>XhYyP8h<T*FueQTep9utDS>VNFh+DVTNC#nZ?YTt
TGWA?u 6cdI<aL4/=i4R?cyY><eyhpXLJ=6pj1#iE!b#8DMS$+19?aLX%:j/%%Y8WNN!enK&@@/wuYBe1yY:iyX
/\+e8H i8L!S<9c&>8X:bd:%!/\/q41cj#PSn=1\mVqiXMVLkh9?<+9>ND$Sc4qNe/:I%KD1C:dnchC41wH*KyS
Aj^LJV icb/QitYZiAcC+j^i!QXYVejY+X:hWY+YKyeDLRSZ+5wHK:$jHhRV5^p^=u4d?j1eS5tH^#S%iC$6jmh
-ASXli 00044c78f1f00110333 Page 196 of binaries1.zip
N*Im?$ h+!>8<&>^It*/*m8S&=9hB@:%tF4lSNQM!VTVZRFPBe6P68k>%t8Mt1J9jtXauHA!9W8kR>L!!Jj^j5?
k?N1^l d>$\%Ni8hu1/eCd4IH6CCV55!!#j8<M<l>S9#:8cqSh<bL%<ienP1^*BH%@N>N!$biC6cNZ<%adP/m9G
wSVZ:K :DeYtH8imG=QZu@VdFZyakTVnRL@6$\&CmCadMHhQ>u+iRZ@<RmJT#HIM$n%$6V+=Fj/%tV#qY8/ncV?
\6QpMl RHPDAmtuRj>cywNQkaMW>TeKHJReMiJV+AC*=+1D:k?>4DHAkMpAA!aDDJkMMGA!\IDJ\Fe\GYDAbIAB
way:FM p\EGFReaRB^kik8A4:>mHkT@QwkB\\EGB\eaHB#kMR@mMZ?D+eIBH9Mh@6eHMaR+\BDmAJ@=EkPIA\\k
dibc9G DnCAPMAA+wCA\eqBllAHGWIe:CZEhZ?A#IjiS$PC?VKDnIMER+GDDDMPM5\+!DDnIMPMk%#t$R\!DnJ9
VHe*me ByLM9\cbX\PbX\PbX\PbX\N:Z<%ZLl^#FQu9l=^TT4WaYj<%Z+YTe6PIqNcw5I&Wcm5y4XG^E\B^Y1MC
%<Qat% GFIKy1T$SpWSAB?uNiwwZ$4Np=VYmBSpCuJ\YuMR\WpybW6@dp&QEPt68Vm6ianaQ<VSG81KVA4mcA&R
I69N\b 1Na+YpQS%TmIw#WWZa&CPF1nL:&W*lyHc^VmPuAK+tkN^XiliDlcw%CBeB/P%qB<Fa1Hw#XWASDF\>Ec
HwuAWn mYBYWV\e4bEIblZF\>EcmhI=D$h4JPI?Xw1Hw#Yc+TK>Na:YTJVPiVlc+!IwklRjS&8wc?<yQw:YWG\&
iq8b^G mw?nNV1XRZy4HK&l&G\WH$h4KDad^ejSGw4NS9F^6Ibm5%F<HK$S1ISkQw:YCIBTm?Bd@BaB=%9<FkGB
m%Dq^> =ZtkY8NwDTJ+PyRA!%>D<HRwAbc@l1AuWkK5NXTAWKwAc\*qw>+aD<9#RQW=n6dwjau$%nlcA+l!NeDB
&Mn*lT $SyA5JMBB<6jI\CmNbc@l5k^BS\e4cG+eIBDajp6FKI%n6awSCWR+MB9<HwAB<6jI%F>n8Y9IWndkIQq
LEF?t% 4!FYA$B\5L\iSJ<VPFyDWiWA\eZ!ilB>VtD=c+nhHCC\@DZEjk\RYQ+can<GCC^@DdEjA\RQ!&hCnFCC
>m=I\c n?W#whTC=c<l1HKAm?Y9Icl!kI9q4!F&e+CL=c<l9F#A^jLZEFR=\KY\QC/EW4qa@lwj%ie+YpNT=eC@
qMYD8@ bbL@L/dmAT/@j>IZ/e9CaY<1P5V<$%m8Itwbp=1G@y<W=ZDySEEJTkK*nliRYI+tcktXqajiF/wQ6*6@
9DI/$A *+PX\/*nBTTYq+yc9et@8F/<D=a#ZDpTp!5HTK\#TbVu<Bj5^D+b*5PXI#G=ewDEP6BEPT$p9%@Kewn8
5FS@Ya WWS@ZXIwImC\:MacuTl*TSa/5T>qPRTpJKY4E5N=PGW=kMIcuB#E?pjJLEDG4=mn:=itI!5T\!GYWmm5
+D8kmX a%nE^RNAFnySElHB^wb\hitZL#EeaEtF\6y@<lGiq8\<>D/MVjw1h&/9XEk<1iB6ZlFPH5Z@q8$u>W&d
n=1Ri? X!C##wQEZ:c:S$5QGa:EJMMBkLj#SW\MRCaACl@dTHT94uVJmeS\RGIbn4h6S1#cYCE%Pu\q9VZ+y6c\
y8E+p\ j%lGBBSI!ujyVmP^AIaAK^/H8p5FTAWa@n/&<R*uha>4$PM\$JYcPIaL5LdeCIhBN5C\D<lIAX$H&!NV
dKmq?G Ep?tEG?*n*AaILh@CLwEBLwp$h9nYNk4AQGPClAc^\wn$1ZF$q8Dd&w6dZ^^i@%c&4Z8\&#c@VSJy>G%
iSH!N: lVmhlujPkQBYwE^/L*/hIkHyA58i4RT>p<M^HP8RAuH\C*k!/d$Cdq<e&^:IGapJPRNa$W<W=A^kSV>S
WbM:@a tDKAFj%E6=bXB>#hdjnETb+Edpb*GwE*t@L\\qtI&bVZV+^Q81C#l<=Ga6LbAFdeFWXuA#^?@%Tq$4My
wD9u#/ \i%^1kpK!/uGC64T#4yW\&ZVD:pE@5I4$CYIultN\MImAK!IL+HAIkCy>MQ@kF^FR&L/lyWDYPFm=HpW
6G=j@Y X4kaItC!kA??1dXMRCk?\+uPjcAjJtE+CjDiN8<dM1+Au><@&^kcZ$JQ4n&ANaBq?Lepi\EBy:<M=$q8
RVQ$9e 48wB4GG6Z*lSdqSeR<D6J<NJRyji8p5MB%lTEbDjpPIGBDLy<!VXJ<QJZ1qRYFLBm/?nwntC@l!euN+i
jI4>$w J@B/HP6<A^WKE5ne9JF>wB@!JZq\E81XAP8MAT?!n+knRa:51!H\Di?YCW$FpBkPeXb6mJWYkL1\FW1q
tktXlQ H@:8FiQHkdwHyARpTB6P<dEM^#5e+TAMq\ZBkQmuP9VLwih!Gu>J@\M+l8MqJQARl56G8?G:ynR?W4IK
X/PGjN TYl/iJd#95q!ju>BXYtKH6FnPJjEMl\4F\J^6!<pPDKuFi!JuCaR>\&tB:ETKXA\QWnIHy*+K%D*6E#D
4Nw<G9 5mZkK\GYXLC!MClE4lKWCq=pDKj\L&/lKh6>k?qB4BRPFE\QE4B@XmB//8\dVR>m=Z?kcH1R+QhQFIp?
Hlan^= ni+dVk>mJa?keH1RK=8cn$?D=WBJQuIQqR=4BeLKQCES8d/R!?&uFalHR>%/%u\8X1RWa1Y6pIlIKiST
X*A%RH @eYal4yeCH8yhHk>nuXwmwmWR1=5eDC@L:MKjd&&^HC5TCup+l&cRwVl@H=CNRPP=LC$B/iHJ^Y5R%NE
M5E+d@ yBTT5k>Nab>/9E>WPwmX<aKm$pFT>54J/+9lSP@KTiC6uFkbL%#E#dTRqP*Z>kHu!6EqiD%PF5HHe4K\
Tn$^@c Eq/+mM8?IRu:d#1p1ZV$%TB+XD1IqjCCw6JBW5cXb\IT@*a<i5u9G$+QatY<IA&ZTX:5R+@VSeX>!?GD
tMG:hu YBp9KJ\i@NiMF>H9dZ6^iwR$uF+QlK<Zy<eu\b<L1PEj$%t?+9Vw&6L@j#m>&l?jTejy&Rmn?KdLSha<
mAL/Ny Xe8DSHSt8je$Xb65M&jh&FXKy4y4R9lGA\YZYiQiDqj<ehZIZc+FcaMTl!+>ihcM\:9:t$%c?L:bbbTS
hbiVZj !6de:Ww8kcj<DT8ZeyydI$5HuR@WMp!QEWdq4iV=1i^pqa$^#j/ea^ESe9L9#^/5FlqTy8YmMeW&uX>1
*4qkni qc&dSL4FD5t&<JJ<nwk1H8*4Lc<&by<tDh64qa6WaA&YX>?l^ihh<dCawZ*S4MZ::/Ym\1DlF\PNFchE
djLPaY VnT5$>1iYC:mu4JdEyN/4NPVu#n>%6TP$!e/Vbc#D<c<!Z@GjZpt@\%b/4cXdYbiThYj!y\V\n=>\Q@<
/qy9XX LiZPM!?juX&yj?!jFp/p#cnLq=L6XFp9VXbP6VlJPcl5W/P&c6iMIT*b>1NndWcMjYl!b$By5b\IZKu>
pHuniy %hIpu51jy#A:tCQmPbAK#Yith<YeH%/qWh#\&:nJuhZ51JXPVe@PXS=/54Pi=LkN!%a>?j#c&b%9m#T4
PkKJ\& W%m/\=R%>/uiKnb<q=IT1dBQ8N@TWhPd4S/?cccZp4!9E=8%85ay\E1?&N!9NM*IV4jT!Mnu^1SVe$QF
%$S^BB b!?b?I<R#&Z@e<EmeL5Y#JeQn=>H%t%ZlG1JFqXV%X<c?+&<p%^yQQ\P6<+!&IqV/Bj5cd1#!9SiqXy!
<BkH\q k1YyuWL+HL:dPC&ZKnXLX?i$5QNDb@u=b:6Z^i9NuLiwQ4b^<+S=dW9*bNj^q%Cu/%^#Di%c^INYSTXt
ipGW&i n<44tDh$Gh6!+F6BXJSw>dw<y$<qkkGqmbiQVnX*4VjP8\PdX1m:8pa+BD/8cj*9:/!Gi=t911Lm/uY>
$q@Qnm Q\TyNl@LHd6+?APZ19cISbjP9huq9qJDhWVky+u4D4aMK@i+5nnN4T4?p9d&+GCuRp+%#=/VIn\&?<*l
DmIt\C /TWZD/SQHKTpWB^$//E#/=VGuh1+cm*Y@Y1dm<e@5+&#Zwj8H:#*F\eh:VhSH66$%9qPT$8<<jP>c<u4
tX&4$1 t^^iQq&nutc=@+:L!bKyG>?K:Wjj$VB%<Dd6LGa=i6W<MQB5n11@q*FljX4G&uQ#:>cJn$S?Vu?@/:&4
^wtR\X Pb@dcuy+>^QQawY\da/Z5teWjCiPT&ni:#^?aQt$^X4C^D%i1\\YQk&LtC!ZFqRTIjhk<PVYDi<4<\jN
*hTG6c nFYdNcXed=By%64=BX&D&KL&Z<Tic4Qm$$*P6N+KhXaJYq6?@W:+$KTM>ARQ^<lE>eL5uAnNp?NMNV@y
*jAnua Dwk5%jb+GPNaMap+wm5/:H:mSYCpT5HIew?BP4>8F&5iKN?jNEj+iFt1?/6#5E^:Z=iu^dSJldbe\=*J
p\Tq4M Tk8VRldGhtkM+Sc4/V#l#E*<>L*C49b*DyX^QM6QmwJh&ledS6n+9u\XH4XdNXw*d&&m4b*ZGb>S?<Tu
m\AkB> w&edY15YQiEM#:ab8<XKi/S8bNLIic1lZ6Fd1E8Qyw?Tn\kIhbkmNCwd=haaa/qZ5:YNQ#:HQeun<eRl
!++mKq ytPHutR91jbLe5/@>+aMjQ=+kNhNqi8cuj1iXy9uBRq%jV^ZcA&\eD#<JmFb*Z@t5Jct#NyDy=d::LDK
V5Ra^G !ST^>X$>qc+ulJ1%iB:Q<Q5%NQNA=CS9%4Z$lECY+hXk^+8PmtI:Fdj1X?1PJbQmc&:dK<pX1b!bMG&E
qFkZJ6 \wTH!wc4Sl/$bQtbX&Su/taZXe+Xb5W&kZGV*%&%FpcP4b?\=aBZTQ#S9Ina^\>*:T?$b&XN<FFX?N5+
GWtVZD y/MmcDy:=dB&+SLdA4dm+bKM*cuC9>u:nl=Z?\@>!/tSC&Nj^%Gtba1=%pMF8T@njKktY:Wn#4ZyJ&*Q
mLhCG* Xe&LBW@*&BpP9nhm%/En9BcQ=kpu+!+w*1tj1t=hp9/LRXXX\tJZneRLB%JudLdu:ZMh$d:CTpXFWLLd
+jP&9W 1/pl@KXRc=SL4yhmhBy*8pqDRXJSh8Z>pRp4%Wy!6DLH:8uaH=#q@T+t15F/&q/Hw?qtCh/BlY881T4p
cA+aQ$ 4ZcKCa6wDDc$16<KjiyuDWthpqARY$eb4yq!iJGX#*<h$\>Zn+/?NdH=@JZ^#ea4c<jt=&mY^&pHL4GT
kI4y5+ 1^ywc!WIHuN:<t=9M=HPa@8+BiHQ:T5m#$\CA^14nHuu=%6:#>IZbd15YS8Tq<JP956?@TRq<HmhaH@#
S^ENu+ *BW@mE+*^n55W/1dayC8PeVE#P/\SeXFWWaAeGebPa\/$ZA>@yFbt+y9/Iw^KW1Kwy&BZnuDqw&8X*aZ
4ZibR% Y#q=c8^=XKL%?YVhmTw1j/%ySIq6h6K#BT=G4uH*:<$/P>uG>jn&nk6D>%a@mZ:$\VnA>enJ$*1%:d6Y
?cC>Tc 1HZCQR9tumlyuZ81b9jwRRdC<Y9c#!\$5=bjM6GLE/&%8iLAtl$XDjN?5mnh5#6l^XZ@TVqFB<SlD+<$
6^iuh! duyXLQ\lb9jDR+WVpm1dKqkL<!$#J11M@S!iuLjtYYmC*%4HDMZPTWHnk1\!+NwNLm>NV6*+/LB@<y\/
KBB9bR a@c+wlT>XLidQ$TF*e51ceyLMw$%c#mX\l@/5?6V@?H?4a5*<+JZh>&eF8ZuEVXhPY=lWy&bcRV^In6n
SpE+6H t=Ha#c\5SM84$HZH+K9=Q#eP%B%nIa/>u/cePq>M<FpY9=WZ8S?j1/F%Z>XkbE4uwc1c:P8LB6%%m98+
8RGE<j b@%Sh?Y!N&aP^Z5i4@nRFRYYlhXudYleb=i6^M9\8V>wbFPd<+:#Ht5@c9^$bYua^MdbtTuQd6@6hQeu
PZT+Dw Nta%1AHjJ%&P\84XbNdYyh4bP1LXdtyiJ/:\j\5=/#>D5cB1*&b*h=jHC/8j6u+8ckqe>eJdhMuZ+Iiw
aZPKYI =?hM^K@iykqhFE!%YHiP89/>6PD=lCquN=RXd/m=Mu/d+y1MD^Y&:#Z!&u&HQiR+Zb%CibdP$XH*&KEV
SMyNe+ 4hp<wQQ/*iJJ>^=<pR?pb6kdYDh&/PT@6+#k#D/#\G:HHqi&aF4nZh5!q?@HiHW9cK6Cb!/yMkIuan?@
-A@:mk 0002429257e00110333 Page 197 of binaries1.zip
1T*Y=R d4SRP@y=+SG=6:?t1:W@NNqt<Wc*hM59t$=#<uJGZu6YWQ@VuBe:%J?uX/Yqd9X\@M!/FYF:?uV+1Jd<
J*w8ww Iiw1ZSj8yS/jw5T16K*&ZKIa=KJ@9t9<>5qtt>+HQKmPCypS%<dN<!E84$&P*Zh&G*@?C5M9CpJS6ew!
Q@^8t= jiiAHWMP6F*Pi%46Xmp9@%*L%A:Dh:qDudQinqYG%e68KHMMYq=+H9b$jZ%D4>M:!9QKn@uKqQp&5Zpp
9wmENe %#W8%T6kXyiJqu=AM=jqu=Tkj:WkS%!VPXh%4+K^h8m&KcFQH+Sbj\pV6m$a>Q^MqAGX!%w?WR##lVeL
9?=Dn= q?iWbc9iLIS/#5>L++\>*$jGPT<&ilDjNq<$*wLK9HHwB:u6N@^u6:E:89n^!@$*=u\^WXR$mXlp$5Y?
4PRi6e >WJ@6pHNib>@dM>nPd=+@Q$l+Yc:q:WhhRN#ylGDtuQm@biGjj1k5i@D<bAmBc5m5<8NBX8E<VFN%qe?
CR6Z@E V9l5\uKh6I^#b*#LJ!Piht=H5$N?eeI^tGPX=W?=?hSR689aMjiwQM&HFj/H15=t1%/?@<!u4k^wQJ/t
=tcQAJ QunAhy>SH6W=iS$h:/w=+T><G=R/ZF<G9hD<Me6A<jbk18A1&!8tdZZMJJ6e5Y64M58d:V\\/IBtVG*d
95P^An ZGYXKe+HD/4cj5tyYcWib#YVP&dE^Fah#kWh*+DXT5N%uw#VNd!y/&PwJQhI@dDwcG:RE4%Ndnhc*mW/
ly=yL4 /tp5pc?+4yeRNCdiY$Fy:TXLeik!$j#FdcWY9nhcL#yaylS<6>YppGXd8ZG<<Hcqq/d?%aPG%VtiAbF!
+dL1Nk Ee/4n%8%BEcdnq5%88I5QBSu>n@WuZhWFMt*^$%kIAkI8/CwkCBBkip\ZV&KEleRWbICIt5kP!aWnG5A
kT6EQb TR1KJJXXX\FBkkRF$+wmwpkRSFEMGBa#A1+BhHh%\+<b/H%9ZY4i=el=::\@QKiQXQY=$*&4/%6%:@*W
#?#Cnc #@ijHNYaq:NV1:KFLK!i6JJ9KQiD#NPQm>NuG>TuZa>K5m^WNni1Nl@5+%k?IGQdHH%@W<&E6phQQ=n:
DGG#*> DJ6n*HdqnZV41*8n4?$jF:LTRDHcZ>EnbQBw\&$jFm:*pm=jY^jViDt9&dSTc:iXpwjG<<XSkjLVk/*n
>*G&9+ qN:FZ^l<:a?Smqih*6dd%?<euiBHJ6SSVp>Z^L?p1lQqZ4Fuib@WX/R5%\?\L4<X6$Iy#&1Rh%dYVF%j
PpT*q4 lW5l6T6KYlX@N6Z#TX9\5F+n$LN1RX=Y!hcuNh8cp/PcK>NiY5hpuie9YlBX<empMCjPcI!b:i:u%K&%
k4S@i* kT4nE*jJV*TnM9#X56y$a^wGy=$*C!!t*&1bScTaKcw?XB\>X4F1>JIJ/NLEPSyN1#w@enptLlP%M1\?
LY*SZ5 inejNem@Ky5dccM#RD+DKTV/T?5$VSCt>t?&?>C?jZ:TWytqV+\51!@WFQSZTt:bdlBXtHCIG8p<$Tlj
<:IhyX &mJ/8AQ9/11^&/Vqb?&u!>Z/GZ:MT>4Gi/bc>6R8&YXV+Jc%&6y=NpQ%J5T6VP/w%W$!tljIZLnyPch6
@BLy\I 6ajR&t8R>lH6=j%iN%/*%/lTcNReEce^/%yBqecKJ=8$D#%\ttDGC+?L$u&*>HYB%4MA@&n*<8!uh%iN
49DuAP RR=ii6ItSNttP$ynjnN/bDlLNtBa\6X^L+%+b*J<>GYH!enN&4%R=4BF>ZhtluPpa!1GLX?TeHP%mbcN
QtQtM^ &?\=8p@9#hV:W:+6*:P/MMbw?ZndwmFZCknu\ucj/a+c!yiK4HVjD:5%wd@dp@c=W855/ni+D#8<PF\:
1>kcT? hcm%qWM^V&d=>IR>WyXC?ymbw@H#d*/&!nB4jNQ\dKbQTM1X^%9%4c*!Q6R<!^\^hI*k%embDS$?cVuZ
>XV5Dj u&19L5@!p9qn@1Hy%185A/QiiWW+teX@P@j+eQu$tuF^d?uan44YNHijjw/EHy*i*:W<wcqt=ecKBW=F
Re6>Qb >?iW!<%:dXIhp!<j=&Fth4nCQ6M$&mFAXw=JQGj#y6lY:<<L4\yDZ%*NnFu9E1ES?j:&JL8tJ8WKS*9:
V$JpcL !:NQ#n9iMQim\YXbB*jjF+JDF6a^\YHDuW!jV#I9LX8#a:#X:N#N9HW5j=8l48w/^/BqpYlM@j4Wh<<5
@H?jDd !em+mjtP%QQt!61yk\K<DjJn<kj<H1+!>eVli\G=qpuPMdQmy*V?Kik4=?*uA\6L#G&FunZ$?d4dK=%d
XT*4mV y>nN>11@4FXn6*Q%tXn4nh:9>j5qdYa1XC\Gtn\!iLB$$M4H\S>#u8%h:h4+p<=JJ^?bpThH?WiWBJZq
MQ/<B< lH$hwb#y6nA1$PcGX:QXwFK*jY9d^^NFS4wXl9T^N#tB6=^m+9Z46Pm5a>@T8:i<T@CIKN96uLSR<b:%
WhK$W! #kXVHZc\5?%m#Sdy/518e:Y68#!kjiBjF6<p?8cqNGX9&PJu8&hE5YL8wtW9E>KY9/68tV:c8XW=X9=K
KJHXkG ?aC\IL&\5qu4Jn1=^a%#8:*I<JDN=liKc+ccd6q?%dLnp6Nl^#&pjWjED<bF9!?jQc?m\uXt9c6NR/85
$w%H%= #1mAW&*nHNhIu@Kc*dS+e$N+c4ZGAmcyZWh/c&/5y>E&H#Llw9G6Xj+N\nh**SRiLF=4w:X<1ZiDa@t9
8+*4L\ =W8m?H1/=>c$VD&5X&pnuCmqp=DJyNDc&6+=njKD%&=51qW+bmidLb^n+L9X%eCCb^1dwDb1h1e8M%=&
lTLP8n +<Jt*@tdV=bt8:&%8jbw5!Y^I%/4<8pRq#5K=m=ne6:q41u\Dcw$=A*Vm*!1bGGYGdw!X#bAYF1aGcM@
AjAqIi jFPPTpDH\!D*NEiH&+88bph@THi=qbX!?p#qc>&6J\y&5AqTZ=$Qd=>1:G=XF?8eM!++dWG1lc6:Z1L1
qMjCtC uuThnV+/49q6W9$KR9%KyAa**nQIT*bw5Dl>M*Vhh+8T5/:<tme$NE=PQ8WRemQtd1LZl?PZ&e8d:%\b
GX/8PA #F!/:P/?:u415pGdDupw&/!?qiHccBYj6#JhK6W1eMQ8\9+Y:&iebENWb&^@e9FRwQEP!@hd@CjJ&\y4
yLKYnW nG>b=A>^PhIihwaK%%lt1LdQ5Y&8$//96GQMX8:$t8b%+KDm>@LyS=TG=K^+V/qimy61d/juhXw9@Sju
LW>AjG \B>a*@u!/%K!th>w?^GBC5WlIT$b?4N&u*=u8jSpSYZ8>cw\ISth@19@YQ<t/ceC*$#j^JcCWQuDViYu
K4RR%d n=\i=ZG/XK6iJ<Zhd5YViSnIH@QQE1L@hekj<<</Inl!n/ZR9=B:dLe=WPRi+yl9mCT+C+1:+HMZmL5R
DY*=>9 hF>RZGP1t@DZieY%y4nYFNic=q4V*K$=RCGm8ec$kL5Su&9N=%4#8hb<4nYj8#ZHQpRM%=nle#hm8NaM
kH/YiX %^y^4SHZGuG*Sq^n^DXt@@=yLQe*q98dkL8SkL8SkL8SkG55/G:M<44jZieX^j$Z+m/+SkVBZZB6CA:m
8%mY^H THCNCi+b5h#La4tZ^ZI9m?XiF58>LJb:YY#*!@wd\5h6aQ=4c@Vjbh$eW9J@l6p\QXTZ>hCd^i$u5=Di
HlHBNj 8IlLD>XqQjVGaQRaQk@TG^e$/cFA4Iji8MkFu\V$=tMKIykic4^//M%mIwM>%Hn%$B6l\uM>%Hn%$B8V
>mep?a \<9\Id+t1qn58VjE%*ARQwaQ<VX58l$j+t6<DLcBaTC?StP\DR\D<VWck&%kGIm9+e+#bSmI4>EaiBHD
aG/leM RH!N^yTlMA#E%:AJRR#E%&kC><\l9wdN/YEk9wbN4GEk9pbl1mIaBQE%*ItNDIL+G8:aSAbBjA%*hmGD
J@y%M4 IL=GabCNDIL+G8:+RRbBjA&H\tER^Nh\KB\GRZ!N^CAdGRV^NS\Kl$ERZ!M^RDmGljkcmRHCMT#E%*Aw
JMYdb5 HIcF?BwPleP\EF@DwZAaqkbyJ5^e\pJ<ViSVQjeG/VWG><^Bik$*RqtRZmN\d\!p%*AnXMADcTdMG^MR
W$^=V@ INYDGcECpF:DnXABTK@lS1kAyNh\I%VA@^LXI&C?SQWIRHMw4p=AAQE%HH1aERlA11huZ$M<pF:np=ni
B8M!C1 IL%GCVC>RZ1Nl?5NtpM^1#uEA<&ltNWe+pF<DRjlR#\GyF5wVG<E$m$<VG?RZmN^*kLTc^laCCJAe!lt
iLtB^S LakI$B!KYR5mkkVyF5\#J!mRd5E<e+IG/ScE/R*Tc=m%ICJAik*#XWRE?kLhkkn&C*RLImC?lwZ\IjL@
Eb#CYV LIEQjbd/@uqSJkW9M&jFApX$uDwD1t%EJQpFkk6>q94?PZRKZl@j8edwR6tSRJRhIpE/E+P!R=?q9u>&
jhyy<< \DhN\+pjbDjJnkTT:BAJE1papl&TnIwp+GCcVm<XeSqElw9K5CGGk^R8bk&KQp6>@\^MA!h?mIw!SIJR
6lWKVe dDmwKBNSZ!KQEWZ$FdFKINcma5NBSbtIAtq4DAaiWbIGJ^@%#uCT:DKewpGGk+R=lpCQKL+p\^p+9ILy
i*=NCE NJnZ:Twp#FXA1l/u6CkppZwI^#X&Dp+Sq%%5PA@tK1A6ZJ#Iw\RTPTh\Bq@uPp>e5>byPA$1$EA$cHBm
Ia/9h8 ak&IJ91t8J:wqQ&me%HElwMKNBANGy!aMAim1V+!9QMDJC4*Fl5P1uNANGl\a8weEC%leBIE!?5h\K@d
/qMCEX XYA!CSTPw#F%DwlGjeQKIn9%6RkmIVcel4pKdL&P$dY$=JpVQnk:>bmIy!p&uAK=CmkRTGNI=Ik9eZAm
PHuTW1 PI6PlDQkhZ$PcXA^KRJFEYuM9lLmW^L4%RT>pdWW/yK%I4RB^HBRYAm*@PL#?/c$pcRbect6&HCGBBpP
W8#dil &1QA:Gkl95Tbp+EV?ETE!&/6R5G$Cmn+TiG&\@mC9lJbqLnWXt\+VK5\5GkYbuA!lERjl*@HSeYp*X1F
=F/jt6 ktpXBlaK\\^PS8Kcp?V%Sl&TdJi4pCAaKkLFdCpMDBW^ptbPm8DB9?PMtC+yNl#E:EYkkC>FaL+1DPwd
F\b<:E \\t/1>JddDkDi?KkCJ+A><Rq!>yi\L!:K4*FlwM19SEw%I!4>EcIpLk>ATe>WmK8b>jkJEFMdISk?=/a
Fuqi6k lRTmJG=QpL&bPWW+TdHlILkLR4BNW<#uEQEqGp:%=n58\ptKDBjlKmGG\*beMb>DlQyIn*e?dcJ:IRE4
1nC8Eb tEc\<Dy8IaEEpu\enlwS?VnS9bAA:4iCa9P+ktpEm5$nVQ+LA5Zt<d&yQ5L*hV=jEeFDnMiEjSlkkZ%M
SX?kB$ 5lTCBjb^w^MY&Mj&SlL\#kk?j>Hm5^#ad5wpcIkA5\I\R+RXTDKe%\9Gq!n6th>qPAQ/KAFVCnBDSCA^
+K^S>i wAE@KEb$wB1@&$%lb#wkYD+Cd9+TTN/YkTNYP4>8hDienA?d9&DJDDkjF$le?hF\!tVud/T:TTZAnVBa
&4L@N@ JkS8I$!A?8bwHlGylP:&eS4w+/B6GX^+YTCRRCwSubMI>ZGcJ<:W:II%Rq!FliXkaNn4LI?RyI4l!EMS
bYC:eK apX$lpMZPbABGR:cq8G#GMMymRlaE9=XIV9@hj5+RaEMl&Z4<nGGk:J%Ch#Qb4/w6<S6#>+knKliM9Sa
6Q+=ma *yip?4I<Rh>Juh+^>FlR*ktPweeTE4e>+WR*m8p/pKGLweeHGW=?Raw!T%B>+!yW=&JKhNSIF$NQADIe
W*A1!1 6LNCad=wBF>mGkKe#Mu\SBXaZac#IB<uaD54tMFJTJ#<iHDew8nkEccd/IbwpPH5F?TE5+Tkd&b6t8S*
qmQl@W Hh\ql9>BhqbaEyaW%4NPapuJAWMiHEXHm*P@^acDw9p5Ch6bEYAMq#D=<RS\N4SwC%=$=KZaeNAPPR6K
a/G*Fc 6TE^$Z!Y=QjNWaBW=/KC=HY:Ckq#FhDPCmcc#=Kwd$:WE=ZCmGmFa5N=MFiBFT:\MIaL?mc&LBJm9eM6
JCY+ku 5lT5/kE#=W6M6iqFPqu9ea55KNWGl%6p1d=cNua8Au6HLYSB1Vc+VVn&u/p&n9@X6^9?^?5J@6iFDP!C
-A9BjQ 0003a31887700110333 Page 198 of binaries1.zip
hQMky* @%E<wkj+H@9j<&n?l9<SDQZ@EQ=*$d!tb@mj*CWyT*YNp*4c?:b9mR?w<hEnD$ny%KecKH^#ip6K*KT#
i9KpN# /m1nam6?GVn$D?pLSthmIw6pble?YnqP>5Pi4hdTu#buB^XeJGwhA#VW4?WK#m+\8LK=&njmd5!HIBM>
DjcQT! 9WYD6dbMVjnWZC@:yG#L<C^HH?cqRX1aR?56JDh8Z+eI:@j$p/^^^:B/5:ANKkMnC6^Q1%uEKZmwDha5
BX$=FP 99QLFP>ebjy+aQE6<4!>w=j!aAXH9+aV?Sai^ZqdH%5%V^+/L9??48bSai!E1$>G%8kW<JV4wweHiKli
=DeE>e il^tI&h/>QRCbVQ#4WJq8SZiuqK/5TPq^pZW^T$4*l4@i*y6WcF/Cm8qYiSES\^WhXcd>44FYXu&kn%6
cnHw#A EnHl!G<tpR9N:9@meGl!l%yytP^jMyFHd:RKnk8j@F\@iMV>==Nt84TyH*T+&e?S6!NJjccYFKF?l!l6
HtD:lV D*E!eZC^c4B#CDZ:!jSE\yuw5uTnkT6jSCjKuH*:w@PI1V1Z65?i?eiW>q^>N\h!@*D*:CMjl>*Vec:@
ZqTt&* !#N%8MKC@bZtbpLXCK&WB4@m%<M/Ht1jPCyWm/!ZC:=TSI&:!54%6^>mWua#=yN?dj%pl$HuP61MSnte
dP4@Q< !4$6W%6$^YH+6DjlL:/:EB#<%t@!4TDl<@Rhn*@Q>6n%IH@uQe$pq?Yi\\e8?Tw!8#tk^dY?+<LaW*8C
RqHqa9 c\jd9nXyqeq>bBaqQ&jEASZ?DLZ^RXNjBD@RnK\:yt$$1m:6RCT>@W&@B?d#Z*<dWt?*Jn$9:t=#+h1h
FLFe\* yPwX+!Z&1SbX!?:>88NmjKV?TE6b#<aucNZbliFlS/MH8CeYcmyhPYZptDnt:N9ImR$d>c!Ta4i4jh9j
8e:PQ< /446^S9Z!l$nqN5!y5%ZWG<\KNqkGGW%\!Wy$@RXqcplMPhhTl$++%iVh6&jDNtZ1Nb#&RkqL@p@C?@1
H#w4t> &IWE6D+bFau&TQZj:^c*=K:KEZ*Y9K#mbNt?VZNm:ZQ@@E:Pd$V!Hd4&SpuBSHb8+@qh/?:W@:mHimL:
t?9Z+L aKH5Ct%?j>QAI8Z*Heh*!Q>&mRy#5K=K4Bt1%*V!c?$\!:%nykl*nVkh>H#$naSB1%/<Yq8REdiyTWuG
dKCD8Q +5Y=>4SX<+=a:t6^Mbn^16l9@JI>w&\Z=@>&XCF1!/p^tn<b&ETWHtC61n%qJul@a@/P%w=N@Gu9#9p9
d8EqLJ b:TtJC<dy4:P&HVu6:jVk#>i9L/+jHZd46EtGbqD^+TQq#c:i>dE*dZ!<RL?66w*TTy?=IuR<Hu4iZhL
F/biC1 5?M<$8huId46@dWw:d&Saee?&kX?JCQb8N#p?KS6IcZ18/QYJ/h6HTaq=YyRqnY%Tnb+k/HeP>WT%hKt
E+h:/K R!QVVY$ZHhJ4dq:j+KY+9dSYQ$6*<SnZWG*Q=$LVE9&BGljTI/!n\uibyQn=yZ9N*#B?A*p\?i4l8yi6
>l8@9Q LwWdm5*j4bY41cyPKlmpcuj+/kuj*!>EKqYhQ&A4XQ6?m>BCZqQ*+K!hI$h:Vk4YjT<*/a*Z8b%BN^&M
@%L>jJ 1@bQtnZ#jN4ik%KGKl5!$?YdZewG!T81ZM*$nXhIt4#XYhNw%h:\N+pJ+cPVB4uH:\=eQna>cH=T$:YS
F/*hkE Nj:djijcG1ZWG:/89L8*$Y@>p9Wyca5PH4?8jnE=/FBV/64$cQdA@HA%Kj$b@chjDQCX8jHcwH=*lEp@
/CB:XW H:utaDiQ+=hKhm*!q6*:8=jJ!%54iEuVVSIZLE#ZjIDT*#^WV^IKM+/NH/=t6qVL8<$lV4q^9<Z*4yW6
yewaJq Q#weIXceu>\e$QR\Ye?!=1QG+e#<mMVpADu1GZ>cT:bb1a6PMm<&:%nnKLjDkq$FnmWHT:+18X<*^YBj
>Cb@GB >nu>&tjcwcMHlMdcCweW*XcIVH$:hhwHjicC/qD9c^QZLFdaEI5c@Sj8H=T=R9t=bcN:Mhp!MGVT#@L>
Q\dXD@ /9#H#pye9%E?Y5$pdY*$6l9^tdHW^6B!J6S8\1\QK/%@WHK8qnJiFJ/&/:*R^YVk5<Xj1>V9Xud%t@^!
uPlFRy kQ@FM^q&m/y5#*\c8c>Bbd!4!5Qt@^B*=qFSHF5Dn\mKwLmAEI*^ndKL\9R/ZecXXXRY&iKGC5MkEJmB
ZkqLEl tRHEF+%^Rak:EnWcjWSHBSZEJYKMEmK+kAm88Md+RBF\F\Xm66e#VK8MZYMSPh@*l?i$&nX%?@c684i1
L$&i#> :9*%?L/HG1P*=?!+@Pj?$?Lm+Q9Zc$NNe&I8j6yqd8VS=l&Q*J5F:l94Qm%>yqCwLA\9jXl+CWRE^w*J
#dy6l= uB:pN$!%6YS=li@km$w@ctYYR$#9hb*Dj1\w?inC6B@ZqbSd#Vub4#??J5?+6<nHL8HLt+F8BT*>G1/b
9pQyS4 @tjC&RP&dlc*GtdYH4<6Ldb&CVn!<F8:Z\n^He4M@JlBF@@!jyPDnQ#1e$VDLd\nd>%!QGTbXi=$>hS$
y?D&Lt /!p1H=?QuA&?jqB?QXi^euL/Gdj6Qy5?:9%+/YpqHZa^6i/d^56p+<V<@GD4+ib%$bYhj4l!+b:Wc$8>
QMIlAP RcH#u:H4StR<9ia+ENRuKQK?mc#i?jtLejY?@#$%+5nGZQPdW$P5HEJdT5%/JmX=ib&#WDW*yJ<htF:\
MPlS?S $4bl=:qjQ8:#iX*!4P@<B>6eTdCQ/V@tejT&t6ZV\88F$Xj&dh!p?1*FXJ/n84c</:@1uuptinh=FE=W
Z*:G1: D1mjP/nkq!4^=j\45<KPSYVi>:$+>:Ep4K=8hMHQQ^VjuDwy@@TEVt=NQ@@:X=8CpJDa/TqQF:thnLZ/
Z%jktJ !Eb^bYY@l*iLhnaPjDktc8QlZat*Lp>N^%jah+9wE*C#=KiX/^6K4d/#QdA<:Nk*qc11#L5HFaeb<^Xq
R##Y^N A:+y@M&\=E:m>M!E=A&uB6ttVT#hJ4F4GZdi+W+*u/Tlj/d&8n9/ytj/F@=^w*aGY\hYql$jK*VcQub?
S:!uiq nMjBhSH*:Dc6WT%:5VQ:tG6h>L/AT:j4$wtaHau%J$KPhQaL*Zdm+TDDXb9KkuP9@4#i&9/duucFJm=q
HmeHPR 1+a9t*@9t8e6898ZKh>c1ewT^t/e6!#heb4S!D1*IGDmbjB!ViQCl5H#cl@N!K<MDZ\MP8XcHh:y/uDM
9l&w/: 6HB=/8bJBuN!HdcGd4&<mSka9#R4b:mZ&<Vt=ZPc?pd&QHn4l\\jA#KH9Nlj+Z<>/:8eE49eK&e#D6#?
D&$YL* 9HyJiinjD<P^+#>>@9e?!/@P*SpRa=>RZ%@1F##kjqS+WHD&/le9Q9m5JqPSNV//Kqt\P9LAdQ<E$\^X
G8M6y& /jY^5X*?HMIpyYYW?@1YL<qL#i8#:yHq!d$LS#+TuQK%8?=4h$\Ypl+?X=k#:wG*:^^j#>Q?a*+bZ#+m
dM\hZm ?&Vb:iPdVu%+^6y@ZqFMV8qJyX@?4#&i%##^uQNb\?/GyD><Sq^e9tZQ&it=R/4G^%!Z&^kEn4?V6:#8
?9LCtq SA>4w<+XB&\45l\GXB4?aqS@jQT!?iTn4P1H*:bpD:kq96t+N^@4tyt<&4%R/6Yn/@yPi:KcXiZNNVjQ
Pk4LVZ ^S>1TXYaXT=PLSW?9YjY=jHGWbXbiVLXly:bqV*#n1&c@L8#WXhl%dVB@q>64ZZi6t:a\kAZ<bcp+$HC
BKhyBZ MYQ?9nQH^1nQmQD=Jw8PPJ/PG44NbqG6ePIPwXuhSBQM^4lpBlES:qpT=it&%:^+kI&BQ*b<w6jy*L/i
16m!>H NYb8w<\EDbZ^Z=9t*8<W9@Z&n5q@XIVe<QuA99SPn98#iRt1GV*^MI?t5X<bNB18MmplnhL8jJGRq#Ct
!8+VuP dQQ8BV/LG:^9Q^8688SZQ@^G>ml9k/bnn\@QMT1\^B\<DacbJ?BVLu\\QPw*1+mp4kbNu!TM\:aNHN+:
*nJ1VJ AF<V54lw8!WYCSdJLI6@584>mYD4%GY8Ra+%qp*yb1E4L^HX+hYTQ*:4%XT5&yKlMmdn5!:Hlu^uX@*W
1!XcK> 5L#:$q$nb=*MnYcMQ4mipj9=KQ9ynR=%\dHT5^/4FW@4n6midnI>ty4%+Pnmy8&XShQDK=yh8u</:tid
lCTC^M @D:XWZX8:1=F^hZ8h<$CuJ<eFD5+iGhimKtIFX!k@AyZN?T>1Mt<8P4pR+ial/w1u#HZi>Sb*4D>m:^4
Si#FI? /ch!*YR$IGC9IHm9#e!+Zy5>*M>pQA<&*BIe&MhZ=yuR&jj/Qd6HS1q?jpE!dJNhXGHwt1\S>WQe9Gwn
YkypWG @e8KQBep:u!&6DGkapt9@a81Z>mdyZlM4=qppXV>QKLY^Y=F!?L##e+Pp+j+L$+=+CphFtyVK#a=Zic>
N?^CR? j/d>+ye#X!#MtQ%wbXyj$\l#P@8nE*dQBNca$>wNT5ja\C/#km=5/?>lN5j@Q/K+S!u&/:8P@/HH%8HX
?p:JJh #^1e:6?1M*$yJW:aF9t96P$%^hB+@LaJR8Md^MQkV@d9q/#5cjhADC/eGDDW+Z4c/aJ#iHVnumm@je:l
I<GycL 4l5tDa!%:uNH*56i9Q@BjhaMT#dbLS?V?aE<awCTNA:5@QJKye4GJ49:Q9QP&cN&*h$?!tQ@*+?T!cGd
KF<:l& kdG*$\JX6PiI11ZMZ?+9mFWQnl/\PVY$1y^eMqd5bLQmt1p<wGnFqmL*LX?cZ^4qbDQJ$DlZZD99\6V1
mV@?n* CLN!R&edqiZade?:qEiNpS<bh>jWXD:bS=dQPQ@8%4mpc+aH5@8klCneW:GaiHDE9hcmLH8i\!t:$d5H
KNT1Ib ic4IH51E5Tc:/LK<iN5dZmiQj=i=KNDQyDq!m6PCln#DGnin9\J5j@9Iw6Vda/Z^k9WBbW>&Qj!=l%@+
CIdCLi HDPZj/Z@i@B=F@M%qHtjd8d%M@bP<4LI/aMdbPQm8MGPl6Fice=!J$9XdG55#5y%/64FKXdQ4D/$LmdV
9ImyEA a4d:N%NuMm=JM$a=YF\Y>mQ>$%L#%/YhL*S@5uJY+8Rl8/%CL%bM5nQ61b\=NLMt6Kcq/5Wh%iN>k:ye
8*pcPm tGYc@jl?$P:<8jpPqcMP>VA#PW98tNujh?4XYj@6j:4M6VJ%l8*Zb6q^A<+Z8ViSS4%Lk%XdY^I8nD^j
iBkH/e =VQyi6DV&+HaQd@\\1:a$<C%m=haY6+&5S:6Wn1m?>bD/WMC:Ket4A%bWX!>L!@LQ1=VBBXWjQBMqMym
Ak%pj4 WXD9WBjqn/wVVm5u?$iRI/&4^lZ:nuVJ6@W+==Z\VQ^>y&qy?T>PjPbeeh+y?FlW4+LyRiXV*Dj/L*Mh
P<GJp! :V4SL&4?9JPhybFh^jn/RIPRCXXq9^:1/&@ucbM+%5V4lNQcLp5D8@>=JlE#6\^W>L?/hBCSdlNW?yiT
<LAMlB eHT=c^NR&nm#&&>a+@B!m/ct^#Qn5%ZmJ9pjQRVNXl?G4ptL4F#R<1T+y>DJ%9?q\tYDWbi9le>n@M+d
$VNbbb b<Vq>8+d<ZlT9<mFm5lTR*FFYWnC$*/uI#QMin$@%hPp6Gl6:9!aNJ9+W\&PDZ:JJ:6=dB@1b?><^wlK
^PDwei \T\Q=u!WWyHIyH4NK=ZM@Yyl/kHt$ctZ&TjunSiNq1<G\:w9HBGB&^de*9Fp\wKFT<N:d$u>*6H$SX>^
maYwdb XTB?j49H:k&d/%dFD?:%W??eYR?YL#/XQM=iPd#=RZ!j\\1LC+$1F&tJES=^Xi:uY8A^&Vj=^hC/#EY%
Am+aDN E@!?q>:e$Ki&bZ#=+a>:h:@9WbDT#c9B?&:L$d1QP+@:iAEn4Wt>ItyJ?nZ*#H!QZZ6I:+Tq&@8jtPlc
\1tk61 ay!VVka$6+!W>Cj9*a#M4k6$*Pih=LL5*J/e#4+#dAhj5lY6KDw#d<ZA>e*Gn/?PVtu8Ghh%%T19#ptS
6tN:HT NZM4YA8yuiZ=+ib>S&ai4L/SLy%5<@8cbY8@TLX5hD#Y@iLNI+MQC6hQTYpPVin%^hw<u>DAJ5J<Zeal
Pn^RLZ D%NF%1lGXbVjNVhB/TjGN55QFK^NNq!%ePtCq4>wk%+CAS@antqdq@N@D4bn&lduIIQ6CCGHZu5N6tQ@
-AmMXD 000e7a88cf400110333 Page 199 of binaries1.zip
:4\VFn DY<Z&A=k4ji#F\S*RZEZI8=Cm$kDHE<NeD\%kHMaPeAB%RAHXAMeWA$R*N$e@A=\<D9A\i<A!hHjAEi@
Y&q^A4 A^#>DuD$P$B!h*Q\P<DB:\DH9AMWS*<DHQRPeNA:RHP@!DH9AMi<A^##DuDMP!B/>Yke/\+\*E$Mh^QD
!VY?&1 @TLH9AMe<\=\#D5AZ9$RB:$DY8khIhSC:>kLm45ReSjeQSl*n@aX>iDIhK>&%>:c6*8:%yuS&8c:!ZRM
^w*MRG V<$XV&5I!+Dl?h\IV&5I!+DlKb9mcR*l&nEpkhIcpmVD<FR?<dTGbFw!JIZTG4bF#FP<^NMc6p@L\^J<
!45lpG 8#ZF\HVPwLRY\ZTPat5WyAmIwXB5DWb+aTkWY+N^:SkK^hbklBiGR4E%GPGFwXB5DWcta!kWY+N>G=Tl
aF8:ew WG\N^tllKBSdk#FcGA4F%6SjT8X9nYJ4JCSjp1FSdI&AXA5\NI16EbCWjabG5VWa+aYlWY!NkM&KNI16
=%QDIl EdBbpWc^NRJ&bpin&BwBt^XyFF6ny!BIc^Sd\!Ey!R!Nat5+lN@ImFB5Daj\G^pSm1*lBPTAX+Smc#mE
#eY6J: *<mIWG\NF$K5SWT?V?Rlw6+u<lDS:^N=mEV9E*tItQiJQESI<Sy5nDHC>+p<GCRjCpq#bSkpH\1lKDEM
5+X\ny pk?FnVGGSIwhINdCWEniH&I6DI161e@y?X5n^Y8RKk?GRjKlDMSTGTRjCtGpMpCIFD6ALBYk&J1/:J?@
ycpt9J Na:p@YG6pZ\w#M+Bpk?F&VqA<1ERYlkDpH\wlBdGABGT>+haC$C^NaKAYR6A<9:<PkhCyHlNTEJcI@qR
ZPybN> CGpWCJF<KA%4niSDIat&REkmiZ<C$yyC<6<mTG5WY<Mk/bNAmGJ4tAnYN+16aVV5jcQatl1h\>5cR:E%
%#iHBm KB$PaNn:Nej@9^LEkQ/5dyyGL^CqBdTt#yIR$EkFAABDmlWlBRAA/#AMqL4GWhk1PFIBAMCRAp%IARDR
4X%AkV t>XNmhwBq^N11ZkEIlWQaElSKt^Y$=jX*V/&D/Yq+lGIXD!AI+Y+ECwi$J@Xne:&$cDPAN+18JBEEl^y
!9mG?W Q=PkIIIVHXP=wMH=$WS49amIRlIecZDC*In?4G=lP/1*eVd?d^&eFBJyB8BIpVqpBR4\D1w*^Ft:Xyip
Z1&G\n ckTupGbmHGpdF4L+BVnwtD^/Ndth\1qY\RtWRpqAIP*lR6dh+B%b*i$auP11lhdBTiFIk=NAY4^Cq9!A
F$VAeh $F65V:aDH$J41ZkEIlWQEEk4Z<l?ATD$a/C\>4l<hW&WSuAS$8AppAcuEBLc9kPkmG:n:Q1W%Ma1cHA=
PyIEtL RKC68YE&4lhtkX=?naqwDb6NI#lc4IJ$tEhCqy/A%F8yV/H#1%n:X6jWckSH11pFTCiB5Jyc\A6RjK%^
B\9Ww? >MHJ8u^%KchceAKy=k<kHTPTGGS\pqVH%LZmtuyY8qX\mpETHGtjkaG5%5tPGy^$c$G8SuBEG$jcyIDF
dSdkZ/ +/SiDBVB6CjII4V^PIEYn!PhjlK\iJ#Tm+GmlP$J5kl6QE/k^iNIS/eELB/u>A>P9D%LN%#Wc8M+E1Wc
\%QV#? IJ&:\4/WBJDPZZEI^SAkud9CY?9F%LTH!Mi\p\NwXS1BITpN:TAN5mqE/eQW$HR:tPTMBt/uES!J<\qw
/&*pNV 6FM+!I#G!$B<JVk/BS/nKM&YtWb\6GWn$uE^:PNTkNcLYTQRNe/8A#C/hT&k*4XDES^y:^KTFRFwjbk%
dhD=!6 C6*=1V$%4cXSIG=GIS%WR#incL*ejS!>mytlNJ6SG5HSuB@TKVh$M+1ZkjncXAn$tqyM5^tqES#N?TEh
ue9*Pe pWM*w*kbmK<FJ>G*VIYc9S!N+GnPD?q<HdwbJTI/b9YqlkGyQ>HRml6Dtk:SD8hl#p?p>/Ma/L6wJB6B
!C>P5> Wq1wA>wuGwAIdW<H+wCRV9ayCMIZIJ*5\%8Dn6ppIHE%M4>%a1CETBMDWqwALDpPMFnH5KLXH^$l6i\S
l#8CG? Ewp>A6B!CwRR=<eRHdP>VlKW=p<4iA9J?TEqJMA?9AaaTk@CR\*HSedWaBwiim8@CtqmaNA!AmEVA%I&
IbR&#Z A\u=qmXA!&cA66d99>BJM/\a/9YKt51uQpyHWByAT!iEVEyA9@>CDuWw#VK=>ekQXZD<9RVZG%!T/Ike
Qu5k9Y %9<V&9FFwI$96CRMCCIHAQ$MZ%F:anSCm<lBk<kD^A\P!I\G>AiZ\9dEcG1W8Wb\IXKwk=n?AbuSkH=G
#?PV9! G:4#a>V4i$^LDEQaQTTEcLpn@N<q%Fbq\H\ITbQ6YajkqJaaS6NIkmP6@IAIInlT+kp@*yS6Vd=Zc/1D
EFIZ&I *4acmNRi4lDdNhLPCu<8u:dmymPYE1^l1LM8Y4qCPJLkTD54@GtE&kwliNyIP%CC:Dyjc/aatypm=e6k
I/wWRN AKJ^9R^EG5jcA@*C6ABkDAWA#HcNI/WwRY^ej:aM?nh4%GeltCa?W#<AlTR+mbVjBJpaMF&TE>hYT*LC
#5jFj% ?ElPDEG>InuS>F5eJ@bZ&+!:wGlq4EVk+P@qL^kdESe6nXaw=YFKtZ\/nk5XA1@E/AmJw%by$\Taum^j
hiPXFW 48!SEG14/qkB%FYadIemQmqEQFKETPTKcJqWRD5L+b&Td!R8<uV1L=epCdSQ?caRDJ<RDJ<1=JLIMQEd
N^dBdX V$*Sd/HeKSRJSG$qAKV&:=:SewXGJK:B^DDN*@HZqcGJ:C<Pw*TqBV#TjlwqE!mmbIt^ERK=JC^CwI!K
#m+^>M Xklt6*%6Ip\Qm@:%A*A1+kVY=P@w11^6Ww>YmHG!bIFTJplWTND/j@M#kV#>e\4W5TN6Ic8PQBmQQAGT
$Hb@d= &DCqJELkLlMu^4E@H1bp4i1%QNyCVtS>cPZl>QFKHy^QHy^HHp?bZBAup$5E$hJItV#8ZiK<ChdYI\/t
9cmJY? I\:BJ\/lS#%1k+tY#u=n1JH@WDP<tmB=85aE*qKqZBcSKGa:F4C##89PTY$NeZ9H&c6^^itB$SquZLu#
kJa8E^ 1*FG6^%u8K:kFP<+T^F+TMZ!qHn%!^P\S8+4EW5WmnB=m4=HwEp?T<h%Sicdy*GcX+\\ydy#XuPn>jXL
68A:Dp 9lE*<jVL9VhKX%WmHXYJ&1wK$=XSBJM^RmbSCMIEpc\MR\X5:^J=9D^cIStY#M+Mk8m+?FnJ1+EypEY1
=M1^Q& u$eRL=eq1j<*LpWkq5ZFl$*9IW%=<!FFRmVn=Fet*$!QC+KmJAL965KwWRL5i*%n?5j?tX*19tSC1K65
u?RicL *jpj9EQbjQP@Y=SE@Fp5/:WF:M#CDm/FMm\&Xn&&\1RSAnibNDJ/h1L<4dH&>nNBDJZQc^J<LwARBE1W
Kpia4H TuXHmjH5i@iXKJNq<5@aj^T#*T6VBQ/!&Gn^G$PFFwJ@yqWhJ$ZlPqwq5LbcJZXMtNS>Gn+HMpYYKBjI
kT9q=? =LQDyNF#NYdSGk=J6W?q+J+1@y%QShF<e#tl+$wI9ktW+HMqd8!p4XF#tB:hptkP@=WWY6$TPl/FEPu1
=Bb$ZZ qtm4Y+J?l&:=9I?*XB!d!A:#FLYP&bBB4tDhIl5*TNRVRN8lS%MM&wQkPwKVjP4p<$ij5kyp=!Q%jJW5
bNBZ#e %he^li96tNMkwTMI^TeIu*>yjaicWe6PqQ?n:5wDwX#dN#JCDNWWEYi!%GTjtZjiGaYadJuFmJTqbe\M
QL4QuM lwqyDKFV&bQ5$1wPlZDRS1i$Yt1EW/L/K8*bq%a6y%QPN>Q19N/G4>>j9#@NQ<@%*M@>ZNh>*e@niTPa
pMj&>k @%yQApuKP<FT$EAbCI+b<ZA!5#lW\A<XTN=B+ZGbjq!iJM5p@MISe&XwFIeVJ6pQcCbLPH1^mJbT4tSI
l>tY/W RRpdI#ll?bd\*LC\eM:wwT*Bu$6+TN+Aa^KiBCEVTMJdRtHD!e#*5pEcalAQT^RRE@Hq/SZI1HDC\GCG
CnM&Zl lauJml*&PcjEj@EDBe\\/YEnYPCpkjkcNkkHA*BGAdCA4V#D8P^\Jk@Nbk1b$wDkJ\aE+lAAPIeA\BE<
9*uZVq I#A1nM5TA@qK=cQhm1YWa?Ejk\EkuA:AeV1Ap:4d*LpBISJ!y*Cm\1RlItDBmTCC<DpA=^AAPI/&a:P=
<@BEk+ pwRXB<mi</*wHR<XDy^RuKCdDw/5AVm!Fw?QntD!8G!IkTLmLTjG%qApELaG+JkIIQ\ATSljVI9Cj@tu
L%T&GQ 5WB\+ITARIkckCN1AI/w^RPLW?cLt+5IDSc4/Tk++E>tMt\emLDDm\6:ThhIuLPj>J!#q5uqnTtL^kIl
DmSd^q YAAV+YewH\MRQ9:&\6aQClAAqw?@mNlZ5FC=Ha5Y\MPFDaB\M\DH#aCq>CJ89bl<lJ!RCRePB!5VAHRF
JkAu=t wXW!HEMVLGC:Z/FCD884LSNZbPL\eISmq\9j8!B>eVunKi<akBDtJ5A^N\G?6^MR#tMK$G\^AEH+N/Tj
hV#5c9 +<eW5AK=EcM%dm^AEI8dAED+mMG^N@DhRZ=iWwtZbaV:mXhT\ylmV?a9%6%QYMMFw:ymJJlQSE:EAWG>
lit$m\ A\n%qRSIqW/\qL=JCHkynRdtn/i!TNyeSn>G<H$8BAn*E?C+u\DH@b=jiF>mMCYi+XMBG9\9Rj4<l54+
P^i&4$ 8WmAFKAEmA\R+PmQACeDHwJ\<el4R>pe*tkeE/^G^?CA1MC*hj8&5CBpaWu@Zqk<FDP5auAFp8PMV>Cq
&cwpId aS=>X&eWbkIEI%^9u\AuFe=en8DV>ySWZbDSLZEVc?%<G@%4^CBNjkJe8+IAy\HLPZ+T%lkZB@\J^^ke
S/ebi/ 5FG\qJ:Gp8SF4?eKA<X:DLaCHIWL?MuMl56pEI:&CilStnRiGyl>NlHmkt=?ENy>BCG6G^A99XELa1WT
1##bBR F?\$FptdB\ndNRYllI8H+5bBePPpN@JAuBVluhAKVQAEA+SVXSA99TL=u<et\B:IkbBc:69mjw5cAIpc
wtYmPX ME:W+GSlYbkEwKS=NA=5:Nj#pjEaDwR#TTAe?+Qj><^E@BLY+meQE1H=S+RiJIIRZTCP6&>?iLIklmBq
?E>PQI Lw8pV8aHt\emGMR^t\h!=ECEdB+RCy+IY^T!RmM+kp>6BWp*pTpy1DtCAE+IK$w1cMpXZSnREF$B+ZRF
WnbaYV lNMXi\tAL&nEbqXe1ITHTbli:M+?@#acDZGC8^mE=AQEh+B\9kP$lG?>l1/hiL+T^:aheBQBB#EjSLlT
?TpLX$ tkmuR1:l\wDR@\M?QDCl?EG<B^GPJaua@/W6M5c+adFa:Jlu/CaCnknh:HBhJPI+A9Ly?PKHaKYmHQ*w
85@CbA 1^TW5CGVKm\VY6K^iEa@#\ZDKq?ZFK=lRwRVDCJ/cZlI!FjSEF8%V:hi$M8=$W\Bi#RT+p?TNbV9RAnj
aSVYYJ ETGu$h@?@wH5ERp@I88w$HB$CIjDqq!>CA+JZa@&+@lLLlqIjk<VY*cl%PpA5Ah?SDlDSwVVC^LcZuJZ
D^*1Jj mP5ZL9^!9CnB5T#5Z^$wLB:+8YM?I5RLpcAtq\mXnZFP1wt\:T9wDMJC@aZ4tcNhP5\M+Fq\:EJDiqXE
$Cn!p: T?t1VIVVE#5iL*V>N>M4mVBL51Ep>&\+ZAHEAMNkHj&b&qFaIRyClFMRw8X+EYPP9nBt?lpa?%Mewdm?
L:TQM: DDmi$lElVSkmuP/T+JVDmSeK8a8B^X5CQ=h/EQEu\ZEhCR544&^P=CkEJJmLX^NBRIIV#NH@aQQ><+9m
t1Xu&V =j*@>@uFc!eH+V?@THFJI6u^GE8I!k+H5eu=nS\4bWwS&RP>dS*CDl$iTVJY51^VtVi5LZ>!ue+8:+1h
^e4jBp W:I$A+/jIX5RP#=Th5duPapAa<Ya$qTEF:</CNMTaHGuK:F?!np?CyPq:JJWFp4pK8c1mQV6mn/W&ChE
&=H%@A H6ea9C>paAC:Swb?FYXk=J4Cpq5MhJX4DlY5qT%lAFX#Ant!19y=/yKQM*dJJE=TtT1LVEPSmA%Mi=8b
=/5lHd F<kQPS4%nCMC:R6<E@pFmccahqS1XmMDX$%nyi!wHQAnbXt*Li!9PVbk!>M/tQK1jHCSZX#=TC^%&G?Y
-A995% 0004ccbbc6f00110333 Page 200 of binaries1.zip
J*w/+V \6RQW=A1/?wh6S*ed9qw&S?y14G15*n+!D^^19%%qGwcmw6*nJ<NwtlyQ6/IidG@q<*<jRkhe9w<59tT
DA#p*G b6M#9JXFPm59yk&BTw*au1m1dIXTib/<nm1c5@$5#ut/RZVq$tM1I<hP<A+M@&dnYn&6?SD8A8M*c%jY
RmRM<Y 5di+uAZSYy+A&uhY$dT#AR=JV/6uw%V+H%cd8:>AGT^a?n!ZkHR@@84Pci8HT#%tK^V5!!/%ijbuaMdN
RiLG<X G@Z@YZ9+>hB=@t%\l1w>64\?\\VjY1n9n\A?>LiqH^*5WZa@emVW4IZS!cI%K9&/dNMNm&1EWq%B=qyb
9Iq1$p &n9lI6e4Huhjp#&!YlCJ%^p*1qh&yPd:Hh=mFD<kYQHM5QYX=/PK5AmnbW<>#*bhDqjYdH%/\1@E!@WN
*ce?+T Zw9KPMuAA8:w&!wmW<\%iY4Y*S1mD&/tt?iJk6<9cTj^Ey8c:4+*9qLY@j/?+QqAdhKFnQ9imD+H1?*B
p%dMGG H=ek<Pm?cahc<\T#41Q8K=i%9:m+KQZ^DbSD#w%p5^wNp$e%%*c611+MuKY\kibXjh:$d&F&V&%+uVdi
I6WFPI K&*Yeew!$:@MENNu8AXR15:LLKBqXt>Fy4%\@H9#<%qk6Y%4%En<$b5bFT<RF<+kZJZYMC+8SmbcZjyI
j?FnwW T^68h:G+euJ:w=:jNHqDc>649yhBqm#6EPZ/1uL%b\m=%chj8YccGD=aF9#Q:G*#a1?aZ8=hVynb$pn?
9jnC%B a#KT8$y*t6Y1B^$F1$Jj%&kjamnLcaF$DK16+G*VFEcPVq^?pc\i&96RP<Ya$4lCC+$8D6#?n19!/BVi
^@VbFp =M&SyNcey?TYJJX=w6:V9=\/m5u9%M4bmdp*8$4Y#tK1J:=p9byQjF&I@<w@dN@Iq&pGG#1bim1SV%yX
Qw<A*m Qh/#cA*X!?^ANSbqb^5SbEFZm+8=Pa9^jt@TWMn54EaN6R/nE\y4/9VM&88%>&=Z#nBZj%HqqK:XTkce
pHku9Z bT//utc\C&/q:A45c\Z1NAI$:^#dHY^?a@9Jq^HCG#t=Mcy=5$ZLTS#9+b&pwa8Q19BNt\>PT+k@56SS
4?MMj* \hqc5WB=61yJPFJLR@Qnnn=>\SJ9cwMTYNHbQ:CYE4:c^Iq?bJ>&pcDm6puyew>BjcWDbHj4biydat!L
R?+W?+ DCl8@q#PF8ABP6aqKl4VJ%jW&1L5M?WFI%&Y$8\=epk>BdB*N4^bK?J4B?Tluh14N=Eh5/!L@!1tN!d&
/TWmBu %5uHyPu:yQpWFnWcc#:<y<MC++8L>tNenFqh*KLmteQ@S#@b4BW#A&*99P:euQu9Eu&uD$REY<c+48uY
Zi6jbB \XnLph6$#tMeD!@5M#JT:h?@PS<6wuL>T6iqQ9>6\VT4GyVL5pZd#NR$T@5dhiw&pBY>A9QnZcwNYd@5
m#<4dR #\Zc#8=!YJ=t6DHaA>M$mbQW:DP>iGhZiw4^>jR#Pm1ZD:1HVN+CFlhQWlRW9nydi?/!:IK&q\A6M!Yl
1pT*GB PS:#u><Zt%j!tyILw8>$GM%=9Z8G:5XtWZ4h9hSi>%VQCEKM6+lde$A%Y#Q#$y4tFaWHjT*6K?#WnZ=l
j&!8Sp /Y?9ZW+Q<hQID\$P*9ykN\PpFS*KV1lu1V4GukJ!Qb:8:!PZ:yk=54#w?pBaeXtM$BZBFQ%B\?6RwlbZ
6PNK%i 9QTm9\bK<nRJ@HK:lppB1PERuY9qTViQk>*%=1^6kEL=HccQR*SwdhYqTuCync=VGuG%LWb6mY#Pu=G9
Y>MhZn =@9:11t?&6il:#Km\umeW&+WmcILA:Y9ihup<nQdc4Z5puSVX6L/5qAP4jZ4=&n9eu>E8?&KWF1+@d:y
<hY8Te /Ziu/t^8D@bZ&JMKBEpu9h@FSVWdbm#CVY%p!9ukVG@pq1/>X^\Z<*DYc5R>SuJdYK:Z>aGy>@1w&jVk
wWPPn* qbbHy=Z:H6yhWP6Mt/8ZpLNlcb/J6cMimkY$hy^68Y$*8\A>wFHi<6:&Xnhw&pd1ihD%WVV54Ntyd*Tq
\\^l9p KhLThNce6lXX=m9htpIc=4eNE@5D6@LnY^Z+^Z>1#VSN$&EHINDZqCd9uYLw:PC@PWD*q><1J4MPq!MY
FK+A!1 GT1@ZSNX9Vp@Y8YIt6q81!:\\V#Y%a&M4aN#NE:<jj>9Qick=W6&#!NQ*cI<96wy%:N>N@cGY=iB=6*!
CI:VLB @S%QbP#!mc%N$$Pt/c#qlQ+%Ewe4\=E^y5eL!4Ya:$I&albVWE\MJ8HFnlupB9YTkq<Npp!ZV8%jiS^J
yl+BVj Kh&\XcM8&hnQ:YR9&*t4Ye4I!8n?S*6YBYemd4mh%:ZWiw=:8cLGepQ=ehhCaSE>W=k6NDJwiRm<ZNt<
MCAARw i:nJ>K%l9Yp<aEM4QLZVQhMH\+!#9mjjdXB@!X8=uI4%B$S=:Rb@LJ@V:S6:Z!cSHnp%i<=N=+d5m#MM
6i6Qw6 668&mJ#ppY8!+9$&lh>8cNm/p>p:D>R8Z1#6D9^cl*L*iGX<:iD6#GhZ*c/@Pu<GcJ:XnmqAMuehnSY<
E?eW6T /Yu%T4/1+F%e=ZbH:6pTey\%bu>J:wIDDwFKcIh=Z4W*l@\XhubjZH*4\:E8ckKbYcVVHJpT8XGn<AXN
9!<CDE yeyKGLFd5:#dASXudtS$/Cm\l*9!ZZd5:RdEW:h*HKh#A6P@dQ@W<yWVPPbT!*4aLHVtQ=WhH4mPjV/4
5MWdZ8 ?:we:4#ij?LwkCtTWTHTE:/jewK*$GFlP/B*KZL/!@:EM=GZ*^aFS4\JLHFi?u4d>R?NFpKHC<jI=^=V
nVhX!M /+aT4NyCLBdd%>kjX9>wewHH$cY\iyiYQh&Ijuy<T^9CKMS9Tihmq55Vhw%IZ4C69PYT$@:8+J6/>VWb
\\mutn J4@8jHK86Z:VMChbZmcww@H>bi=iYVc:6M6N>51h#Y5a:=NI49:!h\1XX%>i$cp&:cA=>WW<qXqp\&Sj
cAC@6\ PP%<J81m+u&X+an=kS=1XX9tumH*IZ6WFSTCi$@\ETwB\/5MqV9=B:bicJ>meKbR\ia%JiWM@W/:kR$%
iwP6+P waGcYS/6Z8hVjCbRec?Cpd/11pm>YE&%8c^YcW@R&w*!JY*::V*hi!++blqE5&6ajb*QuEJqk&!Sbc6q
1%6uaV #AjNHT:+LwqG1Q9jNF?%CM8wXM<9^i#!tyiPjH1jt4T4LPNA6ItSub^>6B1RcSHDbKBHK11C4#yZ6>R4
wah^b? &QL85ncbq$Tjb/?KVjlh%qXXWdG\K@$8ZjGE\qQjh=Z>J$61/E+4XLd+i4lW%Sp<SDL&!Vq5RTyjn**a
#%<^y4 n$VR?jIP5q%t^b*!l$5:pjt>1y*wRq4B>MK\/e@ydct4NtEXPPTW9+@8+kWbKKTndVA9n/$4+\X6n?$J
!hXn<5 yK5lqBl/Nep#Y%%I8\<J!XSN9%dH%CC@VNG69G=T9h/X@GSuT4u%ZKNJBy$iDV$H4mn/A!X$489nd8hL
M/IeNI :4T+hq#1ybkk^!%*u&V:wK/iEGW6t$\Z*FZ5*WYQ>wuQB9W<iy&$nR@8AlL&Vy/EmpZ8eKQ9YWk8/%jY
nM<>&S W//5HMChGPlcMjC!abAlKG@tD!pq+bJ*G^!$%m*eID>*Nt%i*w=K@$/L8aF4&*bZ&ChXWQe>ZFGZdMW9
hR@kI6 IRMXuYVXQnY&$NWhy:4N!WlSRP\b9u6N*dNy*w#G\Wa@eTJ4!D\%YyZQuJ\>56nXI$%i:$@FM@eH!@cE
/XuWcy Cb!ipKtyB!kNy*XiP8m/4*qVilw>tHeqdVC$wVG9<?cdLq8!p<KTj9qZCey%?ZZI\9=Rh%8jk=6XEpY#
L4HGIA !9R1elk=@V!DLA/lDjet1\@MPGJdWtSkeu:1WMnHEPw&E&<pi#k<W\9J>!mcc<Aj1Fy9V%1jEyVk@y:G
c$K&!j \!CH=q:M:\$TcIGX$/&YSN?+9Gu6>C5HDpVN\M/8hKWPbVq*IaanLn?!!jAZHQ5Ryaw:qMI?PaT:I?</
1Fe*@k 4<n&dwc^WyLB+m&u=4je>C1>>KViJS>k$+%JRAt:Hdj@TM+=D1&yFh9>TIR*q85#y5ic!H$$j9#Y^G!c
c<dBZ1 kq!44*&8!iP<\P#4PFbRQ$bP8i%?#&NkICGHqn%AmdFh&CjE&leQ+h=qHH/Zc6>+16T:4EuJ$ZnVtt$H
/IJ1n= 5XMjj@VjM9Qmn6SZ8nRuYd5Y9#mcBVY>E?9^^t/TSb#TIN*Bby6IB1pYRe&%uJ6<JEYi==n&yqD$pB<m
!&y<y4 </^cu6^pN:>\$>XMd^CdC\J=PY:V>datEH65q?XGtm1/EF@W$nHSRw<?e<wR6W\jN#@SnD\!<D^5ejXY
P*XWEm thjyC&j+h#!=+p5Z?:CXM8&Dq=%%pa46n9+/JHTVI%b&CT9IpNJk\9<9ehecI%h=u6NAVWk\pJbL8EYV
E6Y^@W lDyX1D*ui:>:L\a9*5ZGDna&SmESqQH8:P:A:M=/hwjEIYyFpWlM8Daawcy1qhTSVGplyBRRVcW&ZAyW
KCF1\k DRHTKERmSFE8yEydwNBRCYm@==*b*bu*Ji1Q@8kQbQdbM>>#u9jMib:#:jiie@=y#WejQdj=@D5PQu@T
CBedd= +5&@<^<H\:jtN4=n=@knq+%XE@i>?5c4:#u&R@iiN9dc9Tei:K&><DK/1:*#/eN*@tyn^%q@9iP/Q@u<
+!:NlS #N$@P94$5iuj@Ljdh4+=j5Q9Q@#E8<@=?6ml$@@4*kij@epnh*=@h818/!>@/jyNl@:t>Ei*@@Fj:H4w
MlmFy$ Qd>$?dXZuunplu@?\8M*:Z#&kwejunqkLu9<%B@?&b8du9##<S69Q*VE&FWd*uuLn+@j@I?*ZVS^&pXH
bkhCn5 998Lc&<a/?=/\b:/tjq*db6i6*u:h#@@^N<%99&u9*9w5nY:j@T8/ZW*:D:!qZPiPi??hS@<=n?e88iF
iIjd%Q *::@8e8&HHQ@%?@:!DNt::bQZjQ1c?68!u6jjiQY\+<>hjDwM%9dD*##<K*XQXi8@e=d%aPjQndhQ9Z>
HN+GFN &=??>bm^1>ji@<1qb$&q8#?#=W94#@@Gb*5ujP?uc*/nQuuZJWie5j*eD/*999/q&n$jnh9D6=:d5QV<
Ib8mtd 69qdun:mmR8??9Q6>:^$#c8uQ@uI?P/tu@nq5@h*d%5+etH*pc/%he$j@NYBnR?eEW/+iG%+cQ9BE>5Z
4mu$$P 99VE+d<>+<AdF:**/6a64*#n+n9Pc*=q:XP*ZZH6?eh5QibnJ%bQ#n=?#ybu6=^=&8@>:LqJ8&d#eT@8
#NAyBY 8jKDl=@>d9e4l^+><LQh>!#5Qi+HH*?5h5?Z#>:!:@umdej5i@t$tYjPNP5j?@BJ^!&a9##ykS6Q*tBQ
=/>F^c @6!/m*d6j6?/%=?:a4d*>I&Zn4**qG&98d6:y@#u/&iu!#@<4?>:aP18C$@/\?%Qd4#?yy>M*J&?F1=\
@n+n?@ W\<h@PGYjb@<4iP9QiQTB<c/L^=%*b&dDu#=:@itnVjj@b%nZ@:1n1P?&K!&LjcPP91qF*b?i@Nbu*9@
bYhHNS !+?ePud?H#%:<=5j&Q\4&#>:@LWjYZN%?MRtW^&<+>jji8^4:VZZHHn^uVj6P?uZ494A:PN*@QeZb4@*
*jWKE8 L$eh?>P*4n8$<eGZ*9@A#*<<eiDp!V6Q8ZZZKRi8iQLM&/???dGubt5u?B?<@S5XB!<t@H>:w&Llh@1N
p8w^pX mq5c:itq#n#i14n<9@\LM\Se$JnnV4VyS1?NQ*qPhJ9:iqn+1aYKZ=5+$&:YHJ=>5u8l5#VSt?@*DNX*
YLi*Nb hZ4#W*Ij9N+HCN:eZJ#56lcYPq&M8DmJ9>6Ej6DT8a&FLe*Y#P^TLYV1*%:K9%&Qi>@L#4RdM+5%9l$b
>c$AM! ++#%Z?/+Hnj5qm$5qmXNDR<\Zm+61/u9dLV^X@QP?q&h8eb<?hZYyWc:NhuZAqY:q=y#F>eT^9*akN<F
E9V>6% &a$<?wTR@$WNlXE%9Q84c8K1G6#5G=NW=Kq5XYVl\Ti%QHmY:>5wG88$y*/lIEM$4CnK9?KPQ4Zp@*b<
VMY$\G aqlSqJYcYQY*MLlyPk<i!QI&c9w!lJ:%=lehwmV@/J9i=nYm+@PVHh!Zl:%6VW<*8?ZL*F#pP&H4i:9N
-A=dED 000c9236daa00110333 Page 201 of binaries1.zip
+#:Q&4 1<wtp+$895JVucZGJM9B@:cdm+86Yu$c@:ZLj>*G+J5?&=8jcZS:e?%GD:e*d%>5N^buc@Z&+N?=%u^9
%4V6*W 5Xd9#JTV/eycui<Y1u><RQHy@4?Yc9WN<=&q1ib$dc*N6j1?ZtiymeZ*wniHYu&t&!k:bmmX@i>%P#Xn
+M$T?S 1?GN>naYt>m6Vlt>:AL@at49AG/&&/&F^Xdbl/uG#A#?qNu@6&^RyLc/p:&=/Zd#W:Z/R4P:NN9yLcKn
wBBtJ% 9SS+5I5#9XcdTh4N/XKJHiQFq@!A9A@^@*d=EK^R<&>Y>&V\&:&><w9!d#qAZJ9tZQ@jyXb:18#yW4e^
P:H^Z? %b^4hE8bF995c%jyB$N$Tlq<1hAqW/%!/CAL4:?wV@c/ZZaquQ9qPHc8dM:9dbV91\tqbm9d%me:C@8Z
bWupRJ S?yPVVi=8:dJV<186#5#cJ@CZiw4S/Qide/$Fw8<Jtw!%=n5j#PcM>%t&iGFht>^eH!ZQ6qb:JWK65yJ
P:Ad%l Wq?cLd>i@dE^&T5PZb@4qh$y4qSujG1T:>54+>aut%P6h46Shtq?/FNq@?acm=P>N8>k?T4n%@6/nT:?
ywZ1a> HL$YQ<\Yn^/RDjBFj1ymjXQ@?%LjNGDiNH!aN@Y4Ze:p%dJ5/u<6N+*Z/8i8:M*+aJV^\Tnn\/PM4*!+
^:pElP uJ&DDdePN6\/9PHYXbd^yZK5L^ke:B&DD?*wj&l6jej\y*a5d:Z//dpTRK&F>9+CDp/6QaMl>m\Q5Yh+
Q6*QP9 mD&4H:%p5GMZ#Zc/?Ew*8<Z*!>i!@Kw^GKP^QEbniI#GaDec1&M%?1X1\ChYT6WenNJeH1W=QEy#>hP6
>t=$XS \ac6\S/%l4h4DhY$mX4ND?k:k$>%By@1DH?15:#SK56Wm&@%LF?TRcX/k\F/k\F/\\Q$Xn?+j@D:yZ/l
C@iK*B >1@8pH^/\8lVy91Ld5aN**<9&tdih1Fu=aFSu!m?%%?LZ%:m9ZSw1=HqwAqVY&qeL%FkVF:yjeKnI?^1
Aik!5E +=8l5p54>:qQ<MNVX8+^t1DcTp@WlPWHeA=?eQ!&45EQ98bZ:l\6F&Jl>V:VYE544YkV1hb@=lj@pE8\
GN5Ib^ 4dSyuGe&SP6V1R$J^Ni5RELNDTPl+1i^n$IP#+EikW#b\SXbA/n<VGI4F&54N:W9R/qGJKBeI#5KiXMn
V6KB&n L!C1pYD$SYAWpK>SEqDb4#\KbV^MdkVC1^ShJcB!XElAiQL:KFTP8DMCKlyZl/<&^J^C8TI^JqtJb1Bm
R:KShG &%kPp/HKT#RAVRI6JVhpnERhWBJw8a\*bPT+SYNBw$A>^4Xm*MRQTuEK6WBJwqDllGK<JNqR1ARc5A>B
TVC/mB nyC\D:I/iPtjwT#*wb#Y^lw=d9bA%dab1Nk#9C:MYD9Kq9HkZYNmqtmw<d6&SqFe@y5$1mJVPdELGkRc
NLEBA+ HXA9$A^6S8^DeTMeiVECY1QKCFGmPBcXFYnCpR<Chad4K<b%McIPa5>\i$@bNpwW?=6EhV^lH/T&cHGM
XKjpIp K!NSjB<1WVM<p4QMHMT+$YNeK/wiT<GNmYLQI6:BbiLw&bL^WnhnppTJ#\BSHd!#\bAS%eE#%\$bPWKA
1IdccP Cp5TShY6HBiVEB4=umX?6CVRIFCQ</&T&!b5Y&YBbn=nw$S=*CSS*nM^A1:%m:bKwnkYV1IYdF/\GRe&
eA4pL6 L>l\GA\FM+wTK\=PwuCN+AZK*/kk1pP<D!FKqJ>GqTVK*%R4WQc?pCWK6mkWa:M!Akt$:%GTLiH:pPWI
Zl>eSh jHbuPRKPlbXHp^@&VhqJFDZLZ1KwYR+T^Zqemiyaanc^9*l$ycE51tNL9lcjqG#\M&9puuu&XKHNwn1Y
>8$DRk yLcEc!bdTbVbyI4EDm=XIAP5pT4a%/%R\R?!5%b<?^#upK\PuplT@EF5/#q=4cmDD*\GCG&Bn%5WI\S+
LJRHQ= u:YmPmE#&?wI@ajMwnHIYP<EdLAZh8mMY*+pLWS:L&Hp6@XB\H^/&cHkYwa^>yD8bSmHi8k4d#dA9mIQ
?e&GY1 4XAe91FVj+CC#&iJkm=Ww&npeahP$RGKL$6!E8Wh>1MwZ9ymdAwncA1IGB8MRLqAkTVKq@Pn?%B&GCiN
KDjICH F!nHlw%JwtCLYcD>\%EJNQCSZ6$#R6q6=HNy/H\i\L^%Vk1G/J\XZC4p1p4BCdCmSP*hWA\9\=nPDF%N
*^u>N$ LMMP5FM\W*wFM/YTp=k!Kykyqe4EqEwqnMAbySLZP<+wqVnluFE1M$@cqEyEy#NKbYbKyVI#yXTbK1cM
C9FByS CkaqcSmWqBRMT5wKB1YX+lM8/=\%CkcqJRYD$qwFk>I/BVPqFJ?IKbX+ap1qpylT1TTtXC1SYM+yqRl@
tX#$<q ==SKPK%#T1WFyXM1eXZkuFJytXKyhE!yXD1tXCwhW!1XnmtXTmT\<$wqjMN=NRm8Ry%Zk!C\ZhCDkDKw
aE8n#@ WuqRBqW1=JwL1qS\H^hW1RJV1qK^?\SXKucjwE4F:lPWTucjwFT!?$Tqp6$uKyZ5QqGybQiJTmY:V%R1
D5mq&K &Z&mW5u8E=XKhy?wXLL:SKYT*Te1qi\?Ta*N:yQ$&KBMe8#M:yP!kpGbK\YDMl5Fk#KVkpGbbRW#8$>&
qtZdw> CtbK4&CtDAyt!1lkyqR1&Z%WAuI?i=YAYMp15FIJ>@E1AjE?WPNXA8J6t<c4BMT:LA85XF1tXCw6W!1X
u@9Lln qmtXT5iWTmZe^/5++p5l4?IIj+555KKE?*mnKPE?*mlK8I<uXXm+n!hXYLmQJ%Xa8I<uXXm+n!hX&MCW
SSaI:R TtXkT1W!MKXTGblT1a^M1XVCjd^KX:!?yeBKJh#H1*VFi$5K4FVCjd^KX:^#w<BKbYJKySL8+%ZW+XWP
QNbceT BXcWeB?9wk/9ITm\w8SZtK8w\!Q$C/\Kt=qTFNbl*hl+GZWPD%e*Zpch\*QQC&\WDEyQCkcq6^KG?*n9
c/q%$5 FM!WZ5FMGSVMqFHBVKqWEqM1qi\?Rcqp>\qKJd6Q$GPDM1m^&Z&mGy9hJ/1^&Z&m1mC:V%RXbQiJ1wL5
lFN8!6 QqFXpN$u1k1!?$SXRZcj1FT!?$Tqp6$uKbZ5QptybQhJTmY:V%I1&Z&TW5u8p=SKhy?pXLL:JKYT*Tey
dqRcGR qi\?Tcqp><tKp6$uK$y&u/\w&Z&!wtV*!awT:lM1XXm+V/lWaiE?wXKFlj8ETlWY:lM1XhnMqEyqbp1q
IuX^Cb MnPqWytbW1uMVCqXG4lQpFQDAwNTVk$LDEw=NT\\KPZW5MCkqFQDM8FpT1>kyk\KBmWyT4lQIEWJ>\tp
*GVPA% KPE?kSRq*CiRwmTtnAyt!1SkyqTFlj5E1\wL>\qYFSd8E/^TCjeJX1tE?\T4XD1tXCwhW!1XnmtXT5iW
Ywqt&4 T1XnT1WT:lPeWku*CW/ylQ5Ey%VCjaJVK8E?RRYnkj5EFa\G:lNWMKIHyeCKE8+VXDCmJ/ZA14CSKXXl
nFE=a9 I%P1\pctXIYNVKpKG=qT1YV*WeFw&H%WMBy&u/BW595EybLhJ!mX:D=B1YV*CWwq8+@KT<Q8w@LT5Q8w
Y@Pb$I 9CS&H=YZ^P/n<yLajXSiE48Q!p6m>%F=Ti\?Km?J*WjqJT?@BJYZ@JjkwQKT&H%WZlK:n<yLa9hSiWu5
Ahuc$m Qmw9mh%H=TY^?/m<=EYjwQKT&H%WZlK:n<yLZk$KKm?J*WjqJSc@VFS=!a6HWiWqPZ:@nCw5*Ci19CT+
<Xl^HK V%S=Tb+yqW4QqE1qb$1q$nPqWku*mT1<5Cl9wkw94M1d1MKL?C$:SqHCjcJSqIEyXYHlQyFWaiE?pXSl
jD84T\ +V=S=TW*hWcXq\V*mTw9id$814#E8y/JKm@SjFBkyVI^yXKbtFKylQ6EqbhaCC!\Wku*mTw9ii$\14#p
cIw9pe ^ePwW54CjcJKKV!D%$TXW4!1GFXK+iXpBZaKbpybRjSiFDkwtCtnkyp!Kbky5+JB1aISV/M&WRWn*kyZ
$>JSQq aKWT:lNXMF1+V%VB!P8pWRWnXm%L*CqK8E>WKaX8pkI4T4lQXCtFF:kXYFG!?/mW58\?RSYY*WhNJC&:
tEd:q6 n=yI<4y9XBNJ!?/nJyKY*WeFI!<VS^YMq6%HBcNq>%HBcNq>XDBchl<XnQ%*jKqk6P\?Klk68+<KS598
BSJnwL w%LK598wqLL5Qm1qLL8QTmuL:yMXJd6QXwXq><t15P\?YSYY*Ti4\4L:1GC$:D+1GC&:n\yG!?/nk6G!
6He@JP ?/lk^GJp8b!VqQ%Z^/tW\9JmkcPCHiCp+AA+K^mWcqdH4W^J#i1\%tiTt6XlWe<pNc9D/y%JKln^>qcV
uEilwb XDDmqa<t1YDE<<eK4FRTW!1X^JSKJh\u1YDEYq?BqW1+V%LBmNY:Am8XeJ?pklH4eRXYKl%VKyX\u/ST
^FkI@Q Cp6yBXcWeJ?pbuXaHDNJ#i1\CtcTt6W=#=T15J+yXYE>W/4C\u&T!p85tSXaFSd8p%SialY5\Ewq*Ciy
HM@^!V 9MT/qpp1L:uXJKu\\p1XTT1<5CSXaEWJ>$p19LDIXGBFtblTFVa^yTy5apyX&MTW14B\u/SthXl:MudE
4ESQ91 b6Am\i6tI><%wHn>uS9=1tW$Q?K8NK@RCFTMc\&#4a=4N^D?6pHD4hHA!qWZXWNyCK\eV^y8RYWM#eyD
@wwNS5 ?R&M9^N^bD8?\p6^iD9du:?pwj^npE@X/AYIN%WPbX<j>ACnACQAJMAMMI?C=e65$qDt>WERDW$F?!CI
!jAde: EkpRSEpwR16STpKSb!Kl!DPSWPTbTCn!VCRWiTaTmkKI5qAWRJTFI9V5ym\WwWW#bcEIQZ$yC$YSmaTm
N%uQM1 !ESCWYRmwTk!pXAWtWkwRl>e4wRmNBHuTmlCF%!8lCKeSdpTmuAi=pww\qtaK/EwM:6RlM8CZAqF8CnI
NPSNa5 qXCWtX$w\kXBN1PKiDKTnSEkmA\JEN1NFTC$G!hA5B59RGajXeV#pt!mAJp>CbDb5\DBVpIS?8I!CWW\
LeJEbh u$^CEcHIJBVlEmGVWIRLlE^CET+QMkqFMJbMRlE^8%BptX$wk66pK^VlYmFdwRl8p/%RlP8EdIWmZCXp
^AqMw% K^VBk4IXml!#C$YP&aWmZDSpK^R=*mYlCL/WuXCE1+n5lCJeR&RuFPEKIn8lCGcXuXBW#I11KIpTREFW
B#u$Xb pyC1KIlKhFAqakJVGcyEVGAmR=YICW^n1BI^kWpMXTItMIYlT5REJnBWmbnA>IW1ESPa9FAqakJVF/yE
6jII<G VGDmRyYICW^d1BI^\i@k4pSM&PJLXIta\N8E1SI^kipKXTItMFtlT5REymyWmbnASIW1ESPayqAqakKV
6ViP=l qAJcAaJI^ARtKAZ$AtTmIEDIFDHB4+G9SE^k9qLALMDCdpSMwAGSnIkJ>BtTEVGB8>EKKBRXS!MnakJV
I8LX@> q\IKSeV5RlE^8%BE#C+WEdMLSdn?MmIt$INIS5RE=nBpSE^kBpNG^AVcDMtItEA*aRGFI5j5RyFnh1HI
cp*Hkb RccICW^tCmkW+W4SmJlAq%<BlTLe&tbEVDkQhlEVD9i!GSEV8PaqI&IC5^1?$B$BaWFG^AStNGSEVKB>
H=<1Vn n+!ICZVypSE^kYa<9uwiATMWmbnAlKYARqEEpakJNMwXWCmCBSpSE=m@FFAwkkWbESM8wb+mJq^^H^1?
Vn%$a1 +cRQBwCCQjF%9&A9upLDh=9$RRIw&PFLFAR:jIqEh1DFnWlpB#4bmES&wGGNTGRH?6KISHckK+%IbAic
\lPM4A #+lEh1D%nElpl#iRKdIDD<kqE6tBq^wVmi^A!^tS!A=$qlGJ:EADGbHID4TQEau5RJeapekPNIMSmi^A
N9F!A1 K^mS!A=$jBGJ:EBnF=HID4S%Eau5RQeYpekPNGpSmi^Am^cS!A=9\T/!\#8\m?^AK^iS!A:Q$%KSHinZ
8GAFVn IlLbkdc5AkyFjG?6!A+$YSXRKIIFYbEh/KRmK:IDDXNpSZckL+15!A/$Q=EX&aHupbMX&iED5\6F<CW4
!T8?%\ 5kN9Gme45kPhW&SFh1AVm1#ID9SBpSZbkZau5mI:$P^EXtRHtyjIm8^A/^JbpS*wWCI45kPNTGSFh1Dj
-Al=q4 0005bc0230300110333 Page 202 of binaries1.zip
+A19wk mK#ID4RXpSZbki+l5mI:QK/Z4MkPu$Ep55QDq/#ID9RapSZbkXcmAw+1R5eRYbEhcA\mK:ID@V>pSZck
<5?iH> #ai5!A+$?bAX&aFiH4ImP>C!R<=LpAA/AV1AZwABaBAkd6V&Rmb<cdnq9k<!pbCJT/Qlh95?CKIkbMKC
%/jMBC ZBA!aWE8CEWYSCKp$BBDVwRW&tHImbBC%\5=EXLwiTEuR8y@/u1:Jp8PI#*#Ztd+D?ht#Ha9%M#\?Dcn
p\FPC+ $Y!YuBq^BYmkIWjcZbp8GpCS:BYIlnWcFKqjL*?n#1uM+$@MZA^SV%jFG=pb+jHlHl+KddETBmqF5FkJ
8Adcwm k=VmX/!ERc4JBJW\TPuKcT6lpNINlXdCIKWwF!6lpFKMm=W\TCtW^WwayBT^amWMWwyZ5SIGKaYqYAtD
S8ACE5 qIJTHIaucqIQk=RmV/!ERWwBJqdCIKW+Em6lpGy61aeu$yK6lEFK<TbY\mCq5BI4abBTWItXMEkyh5SK
qdw@$n GKRWItIqDFIKELETBmuFkXkJk=VCQc!ERWySHXdCIKZkDT6lpNLySm6lpGw!XmWMWp*G1wbB15qa%VBI
c#+^A\ KeDDclmpFN=lNR^Tm8K\GkayBY6aDaPWkm?5lpFKMSbY\!CqWA14abD1tm@XMEl%Gc5cB1ti>JllpFLA
^9di5b lhW\TCt8\twayBR?aVWMWk1i5BwGKeXIYA&DqEIl4IbBTlEQX5MkyeAG1&GRWqmD%VBIKZ4BclmpFL6k
pth#DC NR^TZSc5lpG1c:=W\!CqG%i6lpFKwR#YTukmGc6Y\lPXIlmiTHdyGt@*C9$^4>F&4*AKlmiTZdyG&4%C
?@nK/k 1aj^THEE%5J+%GYZYlmQiq*1+ap$Z&ylQFJakdW\Hmq/\Fwan^RpaC&MS+wF5BdGI:u<4aZ^TJ=>c&E<
%y1TR< pkQjYlmQ=Ki*F5aniit6ljFI#umH+auGWk>QNJb/iCLNq%wan:4tT!&MS*LaY\9npj#!%5J+JQi:6VAi
54H4jA !e68La^He1bdC?PSjPdY\ukp%:m%MB:y/Ki%MB:y+Ki%MB:y&Ki%MB:J4&+6nEh!u%5L+=G<=NdCiCSu
VSylAF 8LW\H5pXdm&MS!6QWA9npS#d%5J+JLi&6VAi!Z66La^HeqJdC?PSZNVY\ukpV:T%MB:JD&$6nEhD?$56
GAuL/: nEe/HYw6nEe/G&w6nEj!Xq5L+=F<%hdCiCTZ6QW\H5u#dD&MS*I\Y\@npj#I%5N+JC?!>VAi!Xq5Qa^H
InGki@ PmB1Qa^HTy6nQa^Hw!#%<ES%1aeu$mT1l@FIDtL4aV!TH>lliCLNq*wan+dtT#&MS/M6wjBEdRtFJ&yL
ne%q:j KD^SY$LlmdTPG&E#S^=aG&HQZ>=YG&HQZ+=XG&HQZ#=WG&HQZ?=TG&HQZ==S8:49Z&EYDE<p8#VCiCS@
^i=q>E y+$\H5t%cTPMS@Jm&knnpS!YN5J+JIiqnVAi!VhyI+^HepQcCPPSQI+&\ukp=/KNMB:J8YknnEj!I>wI
y*J!i! +=H<mDdCiCTZwa$\H5qqcCPMS@IP&knnpS!BN5J+JJ?jnVAi!d%uI+^He8@bCPPSQHp&\ukpy=&NMB:J
<kGiG< cYennEj!#>pI+=FeeVdCiCT9t+$\H5u4bnFPRA+&m*ECe4BbnBPRL<%muIDebldnBPRl5^kuIGia^VkB
BuN*4! PeM5^kuI:&W^VtB1^SjnBKd5Ww\VtLJLMW=Ab$p6^kuwJKuFPIEya^ZnBPbK:BdGI^$66SkuwIPqF8ME
h=b<Ke ym^anBPa5tA^VtDKk5W+Ab$#6SkuwKSQF8MEbq6C+atYBR9n$X\YLI^He%t\MB:ydKuFPIGy/XcME=mc
eQ5npD d5W+kcth1BkuwKPtF8MEhNDWay!AnyqcnBQRIXPLeRJ#LQZ\SHPy9#&S9ic+pXj?4Pe4%Id>^XF%l*I6
LZ>F<: u@X<\HT:PKyi+awJP89=CuZaKWX%dehe*E>*1PC/e#S<RKX$K^E1J%^Rd!5ht$Zw>W\=RmYhmtY8uFMw
kRM#wh W:qpABZpFB>#JR1LeGWq/^GP&<WB>IDKdSZj$54HE>@TT5eV*=KC%uJ<>4:!/WYwbDZ^&hhB=qmtWtnX
qbIWQ= YPa/&^#LXHSLnY>yHZiPL$RlL#Y?pHWCP4+RN\Cy^li!Dkcl#K4DPBG8I!$Shy$8mZCh@*mGjS%^DY>y
k^B!L: JedJQeKX<TlAQYciET1P:mKp*H9i4/+QPbXqWu&\Q#NF8l:ntTuC1#+XN*Y!1%6A>hd#M>J4PJ:@WtpB
MRjM>@ L<:5P=8*&y?SX/R?%YM1>1M@@=amQ*4+Lj?4Zy/S6/>iu=D<Dd$>Ic*/&@MncX:S=#Q!CeR+At1*<j^A
QuXB9n G9%HKM8:\5kBnh6+414G/FED<8Kj1/4$C!%W\u9FPhQK:>LKb*nJb9tKXlD*E*wNdZ=GK<d+Gc*I&&i$
5*Lu6H RtCj$ayFjWI4nLp>w^WZ?a#K:bK1<SYy?Pjc4*Cp=>19aKVu&yeXejYMX5#SM%LE$ZQ6FcI<u&8@Aw8i
hlGd<! c:@Cmy=49+KKut89pPV=ZQ5XP@Se?^W=>F#:FVj$ZQ5XNjSe?^W#>F#:FVH$ZQ5XL@Sei$%E?9Mjcl4T
5YRL!Q \^>1YS4?$I99#+?6JXS@jt#NNEKV$#\nNDuNMpKV$^\nNDu6KaetN>j/:Bt6>hE#W9HQ6X>4w/jc=:W!
i4<ApE G5>w#hKi$bwqQTQNphI#$k#y1jd!Y6y#p=N:$y/duQ!R>6#p=HC$=!au#/I>N#t=EP&=!eqZcM>NVp:B
L6>=Za @N#p=Q*L#$%Pd4:<*PVp#<9QVW/P8@#e=BSItJ?duI+:=iety!DC@Q!%FWKau:?&nnnq=/?6TMH<@LWX
j\I+LV J=mj9:cPNiZu4/%BIai9ZXZ<<@81K9:=jZt9#iF4i/@N+Y6:4<*lc*89#iF4i/@N+Y5*Fj>e?/dmu&9j
Dt5BR> Xj!%>uYhDdyW9tm>&8$K%D59?n4Kpc<h5c!ZiZt$<uyp/\GKV^\WGFq9q/Suh?mj=8Kyi+Z!%q^edR@w
qNm*%X 9*p?+B*/m:m+ll/\*!:=$q/l5mqeQI19WH5$F+@mHjwd8YSli+W?kN<8YhWieN#KPh><\Hp4=*##D9&>
:YF*%\ Z*#PD?mQYb@W*ad:QP1T%i$XyqZ=FKB*$+9n>A/#*qKP5N$8V4p:LMyhHtHXN/4QWJH=F^j4HZy@8uk?
9V=/q% H>CFi1m<#FJ=dk!C@w*/iIa!V^j9*^%/iSe@+T6WiPVFM%>j5+^/+/4u#QRP9jL%*Mt:R%?d%*ND/AH:
m@n$:Q 4b+dRujw4iQmK:6Dj<!L4?\XKlL!pl#uFe4ShZF&QcBZ!XKEh45pwHyA4?i=<H4Ai46pc:yDZ!Bh<mp>
pFGF>W wFj?:Al*/G@wpp9yAd%KNhdVY<eqahIh?t>h$mW>wH/#SPn%:QE^>ib:@HN@/=hMRR?wQ/<Sn65q4e+h
?CEW\e h5*t+/6#=W6KuRj$q##mC@H1ZNLyQKBYNLH!Zy$/+\9^>qqu4L^d4$58ukj$K5%aV^?1Luq+H6C4NGM>
+uAp9q ZiVm#*!FLcuSS4ncQKALqScltp*+HDw^j$qyhIhb>R\6SAia/+^@:u*>+ky?RQ>\Kd^pHd?55SjL**VJ
>eBXI: *uYHQqJiZMEQ/G@ik4y&lC?8+D8e5k\Bckj+p6QwAej6p6HwDw6YpBH1JdeYwd?q%mPW6aqCc6:6<ya$
E&R1y1 HPnSW:5!LZN9F&>:8*e64?XyA6yd%:1pmGq9Vjdm*t%9Vjdm*u&F!wh$!ZJ$l&/:LntPFp\/8hdP6@tA
jS&!wV W1<B?p8:8I\jWP4^#:%9ZB#Bh#kFY+T8*u1E4u/?#Rj$lY!dEjwL/WiEZ1WSwNbVF%@1A*1XlpZwXSw=
<\TKT8 \uc:?FL9MKuMG1HKdBH/E+$bwV@SnQXWp=*llTnS@eWl?ID#h5q:eajinm:u=S@R@:#HM4Wj$piE@Za=
dqtSV* KZ?H@5$:*1h@!e9b>D9$V*E=tj/A=Za=q@/A&m/JV?VKq#Qyh/n6I:\R@=KZ<?kQYG?Z$?kQ&G:nmJZ*
F>%c9e WYMe5VH+>^qHjCL@Q8PIV?R6iS#^mj!=B:/SQ@jq!Q5D%69q\Q5D1y:^mj!=L+jhH>D4Gdy&$lJ5^K/6
c+=@k: 4i@LMjeH>GhQPWKXGb=IpdPZw><QcLjL\i<:NP%l>Rlh*eIVKhJ#&I#RZ$mPV?VV*JHnE@q$=*K?@AG%
XNGC/! ZScj!A*/=Y#=A$wwQyEdqW6&6n8W4W9^MZ$Y$qJ<VJ?F6BRj$&elLeZH>I:RLD/tVL4F^@Ri*GLZ#6/D
NI@P/d L\ukH6DNleZHqE*Gl@N?%QDlbKn^+ab&N<MV/SDSJVVwD4Nk1JJYB#&&ic$Pit##Yq#$&PdL&m+?IuS4
lTJN\M E>?Tw9Nc:P?K#88^9!6w45j?ZyhS6RnhYMZ?4uqcn@%hw@aqaep4XD#ZJTD6FTwm:SI<hwji6T>lb1>R
LJ%pG6 5=AY#Nw/5ZhJtQIK=d#1wVG55%Qh+t>/L?/lMc#DV#$$luYp1ajG5I+$>hA*%=GtH94tPyN$!c@#kC=W
b6ke+H a#%h8jhay4iqu8Pj4@eb1#VXN&Pbtq$EC:cP>X^CtB:R!^#lJihX#@BEMle>jCQLQq8=SBI?wKb\M$CN
E/<M1j S\dwn^p/q?tAZ\@VLhMGSa>qKq1<^^imcQEi1/VieWuY<+Ac*<NL%yL&p1nuFTwI5X>d58/:KHIe9Q%%
5bEPVT %:=HX/LFid4W?88tnWdh5$aQ/AQC?WC9WJP@T?#DHZwXL:EQh?nV4+8*@AF>NJ6BTQFDq#CeP@R9eRuD
96AQ!1 /je6w*1:iLaj$J@wcBGP&?X5>\QP&?X5>^*Y%*6^A>V%9%HIP<dqGQeDq69qGQeDin%6SPn%6Bql9%&P
K1E%A= eV?kX#/H!p@@#W5M$RQ/?/^Qj&+!h4hbc+A?/q/mD@y>d$y@dlH/t/<=RI*p6WVwk@b#Y^JWtWFhZ6lL
kmQHZ$ aNEhNyZbA@SiiAtb8WNN/*wRpp@pE99\kQ+?D+9R*?eSupk#>$9p^S*/5%<Pph?lQ@9qEQpDik6=:nK&
LMKDRq d1KcbWdw#Tb?I#t8bw*1c6:^e&lndea*4^u^LPE6cb+:T*mjtkDPEq/h:9K=lHVhwVy5DW?p1%%tdA#c
htKNea wL&Enh#l/pj^N+e?ZQ#N>auDY>Ii&mXp=k:Xba=RJYYp9pSFnhhRFGXPPM:&jcj!Ql:uS:=ViRkQm!ZW
n5eNA/ Fe\!A@X/#6Qi*cFi>Gu9Z8HKHuipwKXLSYijEjynnTNCj/uu+9aBhV>wpJeQab+9>SZ1BNM<F:eQKI@<
D\w5#P ERyXt9MbZ/D&*NJ^t6E:uc8A<L94i1\nY/R1IajKKlB?n9C8NDPhI:\1^e&uI=hIXaNeI>ZL#m%Tjhne
BywqJ: I%YwRl/SD6H\bhaqR5eSupFG!9>*Snyi:!F@w*I@HP81>Z1F4=etHph=ltM>\6PjV+Xl#@:<%%4V#h/i
qLy4&5 &cy>5tja%<j1AXdJ9L*4ii<amy$/X%F*1pSWq=Q!h/1$Nbin<1>$Jic?uIC@W!ZD8iTCiFDX+b#a9hKX
>NFy*L SjiT#8FBX/lZKNhYRM5M>X$Jmm:^X9MiRcb*e?=^*ct!9cRT!q$yCC?bM^=WcmQWdF%+h\pPi>D%h9I#
FDMhiX Zduynl1iiPYJP&y+9@W%+m&w%SXG%<K#cTcdnld1wD*GhIp18qQ%y$6a$T9XcmtqE6SYINAq5PlB>Y\=
!i\tq4 jQq%uXk1+S9*>S:mE/?d9XJ<+uWB:hFCCX4yy$9Pn#6hpaP#SL4iVun4GtuTJV*JuT+dNpIh=kyYGnQT
R:\nBp %TbD8i5mt$9YqAhhc9lhjcH^ZF<jX@S&LEi1Ntu^h^Wjp>wS1d=^9hSZX/p1LPiI<DYG<ZmG/$:EpkPW
EM!:Y! FTnqGc+QYjwV%IWCZ1eWwKy$da\Kce14lV/yV^&*T=hpHc@\>iuVM!^L9V:BhaZWJc*Hk89Pp#P1<:jy
Y<A5KM iJhid$LYQa>9Jd#^hZPc9VZdp/@jj^9mV::8P*%d1##+ZCqd:i*%99GXP??MMu4n>jXi#@uE%+&lCk5N
-ASELK 000d23aab1000110333 Page 203 of binaries1.zip
SKSk5\ =a^:hPRb=uVli65#S>:Z@d>94@HCFW^1S1:uNbbn/@eL?dwB8yP9>##I>h+Kuqhyn>e8N4nmY!944\b@
A&#@tj SnThjN*w&!8=/6<d?d4Lp@XjadpH/:Mme\@Yb%$18ZuQMy%=<=:Z9c8d>!!ntnj9ih*ItqqQVVN!=u6i
FcL=SS >$6t9thNtM/wu>@1F6DZed!6G#R:@tHqqn<Db1:@5C/qQQkQ61:?HJ6@YB1dw6cN6j$5K95@KL*mT9w%
jR8AM1 Iqb5+c#+:bWJ4S1\w9S1AXcpZt*AK^kRpm9i5EF!^S\&TK/+\\dJFZ9aILumD^5pX\\m*<q4HCIpX!^m
?XLZaJ l?TKS?!RXK5=J@q9YHPCe?q^appPTLaX@klJVdQukKVtyHNAWmQQuJCWVb<Vpq1G#AuJ91I8ITpdQTep
5Cmh?y X=c#A=I4#>pB!bZy:ICp#u!hC/I*QFjbpNRS4*M^ePI1DEphQ#$TJHWA>WlSW5bIG!QA14eh\C4dDFlq
S6JnBu Y=VMK+GbRVK65mGyEMb##ZJmScltTC1W<X#RuXm9KpNTy:KPDEth!#wKJHWI/!mR%DG5w$BTb//PA5t<
e#M^#E kt$l1ZNZB/!QBu+:aH&!VqRh5D/KZ4RD%ph?Ln6kjZR65S&\Qkyd6AQYS>5*hp:t*4BPR1ZL#PiBqWd4
&@VcK4 MwA@5NJ+ZedyB%am4<6\@MCT4JBeYeM1JL5pK!SZ=4AK!bW:4EFT^/BTk/RPR1WG!bW54EFT^#qVk/R/
Fk@:AS h?1RXLB!/yBWu$<hp84#1WNTjj+M##?^JAep%ijQAQ\H%8ZPhpdeu%mTw\NLep^kTe+w1VV4hy%JQ4DK
LQBh=t uyBWu#@n+p?5X#Wl8XJ@HbBe!d<PTK=MZ\epX//9A=I4&>eBTjX=T=Be!d$TJFet4\VJqe54RZJq<$1R
jc55E> %NHK/=#:kbY<!!CyR=NtpNT^TVNI%qW&JGWKLENTy5A!JGWK#598V/#QpCGye\mYIct#CFak1jMIB88n
^Fk//X lENt5D+KpnYD>XE$5Bt5n/KS#YB>=Hp&k@XSCK\b4I?T?ynB?yTXnI5Q9>J^<iFZRm+?@E4J^ahZu<><
8##CL* ?JYBC\>jX\+8QH^hYdn\<FyAY5dDc$&>ZJ+S/*H\<Myaa^ttX==&!#C>m1?%DNP4WDnLML$KLdRM$/8R
jPBdF\ Re5\9ZLbY+dy%Y/Abbli*il1GcbZh:Scl8qX#K%qtN/1$>WbyqhddJblilYPc^ttX!GMqtF/FhXyGcbZ
XFw\4Y pd?YaZwX\G5byqiB9yblilYicSttX=icYwdy4T5jFp^9ZSt^aH44Tu<F$/9+TT5\9a1k6ALVY%eTLJli
NN*#Ll BjXckiuXDcNYaH44!uwF$%6Zmm8a*41TZMH$%yZtC1c*4pSZML%%yd1C/c$4&SXM4/KP4eD$K5VaCp!9
@tu5B9 +wt6\QR1&NWK4I<&%1#A?5nDakZYS*h9YwH%WjTwFXkjBbSckjXyK+MXu4K6HFb+!4c!YPEy&<ynlchW
?L%Sc: cJSXQ1YG@<1u%JT@<mqqCm1jemY9+qP8>FX<T8Xi1LC^dYY4kw%6K%<XdK^Pjq8FnXZ<4XZaYEY?YIYN
ySHejh XcCJXhlalaSdla%X*mt45LF!w%tFnhWi9%ZaYAX=YaYNXa!9Xhla^ZSala%X>K=X&FmhHdeKG/8D+qbl
%KAb5i a=X+!Ty54LI5YaYNXeT9Xhlaljhcla%XLK>X&FlFEFtFnhZ?1XZaYB$e6\wd1\QlXtFnFi%qDVc&4!SS
e/*$m= 5LF>yatCnbWL^ly5dF?ywtBn?$wYqTmylE&\5Z*qlwKN:T5:FG^5Z@tlaGPX8<ecdG^j/cBka^ZZbk$&
^t?DQ< 61@5V:C^jiX@k9ZyK>pV4E>jtb%kjd4t>k*YS%9J%tB>81d<DhbHG<uYaH&$Z&\h?!iK>:KP@bP?Wnyl
D<4PRK @$SlcNc^j>JZBmj5u@TX\\u:J*%qeeL?TX>=uLB@$qetJ?!j>JZLCj5ujYX#\9=JZ@te5H@TX$au:J<w
YQ\#lm Z5$/>p<WuGah?!iK94TP@bP?#l>n@/VLFHV5u!lXkuZ5u<nQcB*:J:4y#V4&V*Tqt*Z5*54=d^&:6\1G
8L!GZe 6+:hY$Y?Y<j84eLe4YQ*X8H4%4F:1%l%/>m>XR!/hi#iK8DePub9FX%8Hd8*ml1*n6%d*aFtHd8*86ZM
M>@1@\ Pub9hZ&bhi#inuXPFd8*mnT*n6%dSbBd^?/6\5Y6a@hYaiA&5H848<S5aQhYq+db\P/6*Ma&5H84bGE&
X#FNVa 5H5:Xqap:N+1mNAGht@HTwKE*h8^$mBl>%bSe#c\i#6Y%mQ5*w/X>\nYS<FcNtB>qG#LB1#QYItPaH&W
J!yVyS S55G4I>mTY#A?mlBqk%aH\X@&8VD1*NQQ9#Kd<THZ^tP?QA4^^EjjmW$+5P9qEb<?JZWmA<@%:F>TK4Q
jQ*\WX V#/<l9@Jl>jej5L$Kt:NJp!9Rk^5\9VPqZpAyqeBhVbli8hKN\DVP%>VDpD!Ni$AJFj1AbliHY<#P5+W
j:\JKu N&6$uPpLGB%u?kJG^=t?kNF^y4BYw?NM4>4wPNP4Nn4P>K1NnnP>c1QnVQGeS5ib*1uSecb*cuTeKXdV
/$6G:k /DnV!#M/#lT4c*Te/T$bHYh/T$dHtR+yGl%uip6G^=uip6F^y4hphJ#N%a6lilX/q8p+$?9IhJ#yhYR/
k?!=wa #lT9tPp+W*Bmy8N5?t\>$*Gt=<=$uPt=<<X^buj*5p:KuAEmF/!amRE5:?*bAh?\@JwFbY8tjjFP9GHF
/@Iad6 Zb^V=#i5qFZu&qZXXyDL8tpu\uWJVIVL6SPkLbhHlM5XEKE&9cPR4Y*yCLYqGwZY%SqScF&hEaZ!86Wl
yJG$\E \uZhRaVcba6Cc+<6C1tn=mm$W6SHIe&/T^VTP46EwbYNQk16dQSSTJQ\GwZY5n5K%dWSEcCt*#WK4ZX+
eNR1mD FGy4uSjlYlbF1DXiFQJJh$bd<9/e$bdWt>GYjEVPcE5?Hti$JS?NM>1TPnjcp4w&&yI/N61TL<I#&yI9
iK1lI> +VQcpm@kM>1TD<5bdepH=a!&=EN!nt%Jn9Re&=KPa8daqyV<J5i&JM>/nt%Jj9We&=K</nt&Jh%ZptNd
H=:qNJ $6WpPdaq^c4t&Jb$+WmPdWu^TDt&JVuae&^Le1@u&JdpZM<6C4qq8MV&*KFdlp9+#kP/WI>Cdlq!n$J8
B\4@9& GT=d$\<+d=iN/V6$!*Dbqu:AjL65Tn>k9X&&yB@RlXIWe56\&a/?R!XYTXHILeNqK@wBZTlFIdeMq&*w
^/&QYG B*Rlm$J8GT=d$A@wRlcFqPjGwyAT/8RwyD\*=:bIYaPQn1<wWe/MYG:6<+cVC@bC#wH6Dj5Ih6=!e5H?
j+TL!+ GC$V&?&</iTC!?&<eiPC9aJn<>96h6//eeH?/Ph$/eV?PPet+auu:d^X+k*4L5D#Tw+L>4LQdhb/H:=%
QwbQkl JehqE@!BFSVa#yuPA!6Zcn&NXH9FK<!<ddCP>HbkDZtZ%j5d%6HB<\&?ab*KP?**G@dQeN=Zj5E/QV+m
IY!<Xt %9l^*4b>\V4DQRNiN^BhhtIiYMtZLn5^J@b/X^TmN6J44KDylM>qj?@E@hbPR*>m@\#u66<d>4dhemNP
dmWTN* 6@N8l\6&!e1!hh!:<:h%nL69ju9e#y5GVn!WD5KI=?%M*H=md&^u/9aL>lidYIl*pnN>?\Z*&=uA@aK>
!BII4< XTXYePy<MH=dYXe/Z/^&8n6j4HyC#=%acWIH5hi:+iG%Th%dIqb9aAX%4ut\knwLP%lBW\wMXqAyDlKc
6hZTZ$ yl\hq$*CN?^h6b<G4!?5KEu9ccjBi<M/$Hh?+lQ4jGewSFt>hQ^9S1!D^YeG>A9P6#MH?kYZ&=uj?+L4
T:SdYm :e#\jeFKN61J@b&MVP!Ga^Skj>@uje<ZZG@une<u>ki@dKKe&B<?<!phZjbYV6^8=/*CF?\96l*E19it
18A@jK :Htdnc>KJ#5dHpeP#QP1/^Q:#Q9McH:Bi6?D&N@*/dMc>!FDb9i!1D?^X@B$bd%lXjC$J!hPnnP^*T=d
q1ejRh ACjYed&$+V1phN1Ip?5k#nuGuF#HaM=B=8R/nGN<yuYm59ClFEq@mh$<?Ty@pK9<^Fi=D5GXy?hcb?N$
ucq>!T 89L66?j>6>P1jRP*hbn^hAA??F\H=<+y:<qX#8qdQdtPA=*D?^5j/\DVIF<H*XCj1XVWb&4qC>eY^$Fh
?MC:jF uTM=5:Bj?E1Qu5t%J*LPbi=<Hb=Nb#4&C>jSu*M:=?R/j*N$e8utk*\hWp9kcS&Nanq4T<et?M4\uw%e
X@Du/1 >c#W%iHLT$D4!ZZp4Y:KKV4X^Qi#<5W*9y>%qLI>9b>%6p1QY&dAK>H+iXH+He>%e8%M/Q=q84*NY::W
aqI\\+ Q6MbY9cqn9YeCW?@%NtN$/^@thd8@PNl9@S@jG8SZ@1K+&%!>&Y=uhihjXq9:c$Bjcp=+F6=M4J9Y88\
BQ%wtK &h99/juiC9<1Hi@tP^>n4L::>b>?@A<9::>:N>:>!<<@@QDll#???@!uq*hj@>QZ:@:?8#>@?PHDV=<@
YQT4SW 9j@<<hNQ:@:4l@@%@6N*6*Ttc@+1yXYML=+9^j^Gj@Llt=<@1!!X<@un8*@>/iZVV:h$4q/@T6q@>aiZ
4Ai+=y @@u>l^@?^:8@9/Z#iQ*#Q@%jmt!9&*@/6j=yd9@yN+y&Hh6@?khFG=d6Q@&n\6GP:V@>p@=y@%j@Rj?$
<Mmjyc %@16h5n&j@X@c=>5@%j@WbFW?&y<1c&5@X>>yYmY9hb@$q:Z9@FQQ@@==hPHd*@T8b:>1@^u^a@a>y??
uMwlXA %udb96#@LQjp@w9?m@=y@$X@J*jj9@FQj@9#N^?@Z@Z5&%@+9h\h?:@>X@pI>u@%Z:TZ9@?u@/wN<Ei@
XV8ukD @1y+T<?/D??6ych*9@*l</iQ*@*<:d&l*<+dVL?1?uZ9?PZh%=<?j46?j:::l:@??QHV=>Y@j9*^p@@*
kC8?8$ ?<<9:*:*+a?4%@*Hq:?>i@@Dh>:4999\?eQHH>=@@?+*L>>??68Q?pH@?yM/p9@6:R^hYVLFdYN=1=Y>
$HQL!= ?:$Z@>5@@@n>!=>jj9n<j9&%/9D!$$?*?tdw9&4?q\yIQb<u9@9h!?jXcZ@?<h%:@?Hdu#>>?Q!*h%>@
8w@p\H @Q:D6*?:uiEi/&@#MT!>5#@yL%Z%u*:<@5Q//%5@9$L*Z%!:=P@?<eMjj@:$<w<jQ9*$?j:jdnjijjZ!
w5<=a< ?j%//N>@?9tu#!@j9d%SYa9#ny4Zeu^Jhq14en/mc9#?*he@j?QXZFZ=:R>@?QVidhDQ**=&uh6=uhE1
V@p?Ny S*i%&L8$K9=j*u@@+d9*1+V@wSj<Q#><@yPZ6j$+6>Pb>6XRjc4QnN:qXe:9j9=Gj/@=Vd:?ntt<j/8#
%!4/lT %@:V!@6:jj<Nndil+18=YqA9=u@@@5jQL=@P9@/*t+lG1$eN9u/uXMl9P\H?w:b6:Q!^*</:Q9*HeV99
^L++pQ &jRjqVD$@FHJiT>FKi%y9@^w6*ay!9L6nBu!H*&yZp>hW%dJ!!<4#>nqS&Wa8@!64!@#?WVK!9lt=L:&
QNiKae Suk:4a#@/DQ?6\t!@?nL5*^YWmqL&8YZ6S\:#l?Xu8dWZe8a5<=ca4^6l@mQ9mywq^>>NVBPwZWGQy&X
aK@>ih ZljuqFNKl^TQi6bpVjk9^c&J@4!W6/beq=<%%T4u6>HS&QQpnj?5Ke:qDbh%FQuW%$V@QCZlQ?5wdnuj
WVBGK$ 1p+$utuN@Yeh!b%u@hbS&i9j/+n5=WX4abC9=c%Vyyijhdl$ZM4#?yX$Qw>PQbdL?>ES&ZL=XD4?iF:$
md!@Y8 /n@4YyS<q1h#pLYh>jhbaK1Z==jn<I!8<=>%S<!q9q1w6M9*WH/Jh9q:HbG<6qEq<nl*cj^u#iM8uWYZ
P>YMjh <q!d1R=NulE#@uQXNS?uZq<Ziq#?9t9TiQq:*i:SL9??V8Yi:X/l&PuT*6c6/Jj/nZXb:Qu*a>$jiD:Q
$nLEan C8C+9N<Q6@N*Q*!+=ZV=/eP6uBZ@<Jjdyb>@?P96#I9\>d8@*C=N>C<jdyeG<Be9=5\*5H:?eD8#Zu#>
-AS=KY 000a8ffc1a900110333 Page 204 of binaries1.zip
IE\$Zc #p8/6Pi@j4mh^+*$w>jy?YeHe%#AZ&:q5hQ%1%@h9un=+d8Q*@#@Z?VZ^CZ/#%@?$u@#>*@:<iZ&m%?@
aC4<dZ @@#??+>@%F??@?QLV:11<q:TQ@@<&TeGn9KbmiL*j*Kn@J*RY\Q=#e6Qu^h+%Qmjj*#=+i?@qa&?@djd
1F8T>I K@#F@@Q@@u?*H*:?@99L@@99h<t9Qu:u%jAb<=6i1HT?X9y*6%@<$<jjj=T8T4<d=XZ?9*@NJPm6TYW@
GL+GLl q%GiH9#D=?>jd9@H:>>@+@@#<R?*Z*@<+dMQ4D@>u%@<+8>9?W!\<b>i@9ybX%T<NcXQL*?Sk@@6Xd@@
c&A@CR =H>&iV$Z#d>?i9uDF+wT<CZXF<jd@@uIwLn$Q*#^:^=E:YD>!\>9dF%yFbp$Aq9utRJd8REC$:XnaG1Q
SqZyuG kc*R!5BYXMp#i$&8>M#1TpRhYejj6uYGNnDd5M^uc<6=FhkKGH>tjaZNQ4P^$mAHN9li^6w4C&\FPD&#
PpuHbZ 8TJLIt6+L*PqPwt5R&P8iIQIJnYYn#c\6Z1K4FFn*SeR&YB=!\*$^FJh\S!BbdTZ%NcF=5?5d<44c$pW
HJ&ELP &KSGZ#FR#&!5W>8SVYmM6h<TtLL6kVX14ImB!EaGK@ntqqii6eBYLynALQN9%^W@kYW<l!q6A%u4aP*a
EFHi>K 5FdBP91YX9t5!@LASVcy5hct#/\ejAjqRQ>XA6MB65/#Bpbdy<8Z+:jWXeQRHi6&yeAK&yD85PZ9NdRl
Mb^IDp ZRIL*hE*8u%Ra>$^HNtp^wy/jGb#<$:ukj:t4R1&VyG9$JlY1JEQctT&?%u+nYdqi=u4@EJkA?NMZppQ
p&EZ&w I%5^caG6E=mB4SNckc*<#wF%/1::\mPd4E5>$Nb!VSm**GLn@Vq41F@NiC@P$Ah#LaX%KZ!&11#TpVYM
e+!$84 $<+/u&Q=Y!PdjI/Xm#Y\!Y>WhcNSaP%At*R&!hbGhYC$+<=k@*LL@N6bMPiT8eK##RbduPjK/^#aTB9G
J5InD\ ==$4c&=p$CnHWeqT&4BPbuuDNly=w%E&GtYnWVechcQSNly>w>Fl4<w^<wbN5wu=WHqN9juMTtKhm@Hb
FKlny1 Twb>L85IPXkuc*uDJ6pKRAq5dDVGStN8NCa%/pGNt6KG\j:yDD\b=$Q%!Jm9Xj@NDqau@:bX5y+&4JPN
*He@:+ 9GEdDe=Bc8J/1::/M=>bYb/Y\BLt%LZRd6VT$wd^PW4QG<duYIh$Iy5dnWtN!4t!M&4WSI%1ceM&Gutn
\YQnpG pVecbcNSN^y%w>E&Gt&n$Veca/M^Nly#w#Gy$R=1NM:9NhTTYh/\nWdicK!A$Mk\h6i&/Y>6$><c:Y=6
nek+Yu 6L9?tnH*<bX>Ip95M=*:Fn/%\J4EYTM4tF@y<=J^QXQ:81Wm5IE=wX9^A&\etIe=G&TG>ai#Sybla?9k
CibtRi HM/uW4DbhdSE%4Fj+t!TVe#%uHY\8XIZB=bwP/hl4ibhJyMXnQ6%%pVGjcp/&!Sd6^bF%5kt%nQ6YAuW
6+P$HV Ap6wc&*qlw\5w/$%#Y4AK6ycP?wk/%kH6GMh>A%5aJ@By<Xw8!%^9/t>J4$P#LAj%lLZ#n=1ac?19Vwm
bbVJaM A185e&y<#!9FS&R4MnP\hTZCM/5H?yFdMH:jY1qd8V=*%5m/dhlGa&\$=pbnW1Mh6tHWcIpct#YP5+%G
!<XlEd *tnpnWdbcNTNS6%w6I%G&&n$nedacI!N^6^wdQy$*@Vyuw+Nw$a*&:CNS6=wqI%G&YnWnWdhcDT5VZ%I
#iNyXl *yR*5Fjj?kwLiYdn\F=LG<8SGln>Bn:5H&Vea*R&!B4GWGiNnH6j*wIK&YVjh^NBqnCGilM/!DLGWGih
G\PGBd 4GAM>cqQJY5aR>9e&LX%y$=pE?8Qjl#ac?pH^?S?eD:iD<:H?:FTiAXYKquF@K<jLbN^#/Mj*QQw^<S+
hEEenW :k#niW@51<+ctYH?%^QHbF<%a9:ZE<hpN\eaR*91B>uAGPwMddjdkVHWYTNLcG9>NcFlaBq64X6JbBX6
+BSkQa 4d<tCR15a:*k4JMN6liddC?b?<w>J:cZdG\9PdP>KP$9Gh6Ldyn@PY6puZX8A?8Q*4pH$QWkbJ&5=A*n
q@n6pQ ??8Xhiq6w>E&Gu&n$Veca/M^N^1VG8QIG$cNpck^LG*aSmN9NDc&cY^5$?C?RB>6W>:GNw&NdSwVc%Nu
aS1M^X dB5#aY*14JF6dNQe&KbbMFj85^4b^ndNnY&cG>5$cb9G?kt5phE&naP&cS!$ViPkdSwHdbP#ThdSB<jS
>bD#1E P=u8=+/Mj4Dlu/&CyW^tqT\u54L=&#LJ&KihhdKPjhGS8djy*RNn!mkH9$jlu1Y#^4@qZG?Wl9ZYKB*4
ypR69D &4F!BpXG*++#nA8nMpdE&TSL%Kn$<VudcPTNS6=wqI%G*YnWnRb6#6n5P+:N98Qa:D8P#d:n&P\:n5&?
LFwW1< +>n5P+:N98Qa:D8Pb8!@LYQ8QR?8%dR>BQac5Bqa1tTYN1!V=d^lG+&!$ckdnd4ScB8N66HwG+&B9VSu
I<1%S# uY#tDaQ>t*bW5yR&nB4GQedb8h/cjTT!mjF!D5c4#HF$M94RhCWetY$$MQ>LP8hCq1MhEw9nd>KlV4JK
B8+?Y\ nY^^DE*Kt#$mY@t*I&6^DTE&WL?XbnG!pXGZmntTe4*EPalG1DlueNb5\\aba9menYQDNly#w#Gy$R=1
nH^6*% 6HS5GDYc&ab6NQJGw&\$5QbVBl64bQ^84SY!#9dZBnX<+a%9&VF*FI9>R*pM$Q+!da=C#1HldIDbWenT
c:mJmV 5YGN#G#DNly=w%E&GtYnWVechcQSNly>w>E*GtPnMVacE?*Kq/d+dn/#mP6L=bPyKG?pPGh\lnkib\Z>
u$Q/we QI>c!LDYFYNhS4eN&&mMnedecE^1#MM&nBw#WYQc5YEdnS#*AJ!XmY<$Y<W*tn*/NXIy<AW/w@$4bcIN
wSEBTR qR4jmhkk5$KYn\%4bGYnWVachcQSNly6w>E*Gu&nMVace/M^1hEP&#B16ETN^nHbGeaK6!T&aaMMi!%J
ZqEhqP Pebni/pH=t6yE\@mLPF=/?6hlbENM5!yubXn\#achcNSN^y6w>E*Gu&nMVaca/M^1jF/P%qp%DD&I+YQ
=e1T&& p>qGI&<$M9118tAlG&T%pLXn\^yb*&n$nRb<Ye+Rq!c9cX#dP/8X4MHG%6aLGj#maw$Mi%>m%PkHNZ^P
<4+&+! 5&HW/Gad66FALL5#uF<R/&TI6jKP&nDZc\cj8nQc6Yc$c!*V44XM8>a!:b1d1&QDNly=w=E*GtYnWVec
y<c<Se hcQSNlwN<!G*pwX5HB9Y!Dk@>TcP8XTdmQN%qmy@#?L?t4Ne!SAHJhdJc6/\nWddcQTNS6>wnI*G&Gkk
:L$HdF F6E6N5ii9t+=n!#Fjh9W<!R4B>c\9SnY5M+GGe=dPT9HlnY!86GwG+&&$ikdnd:SGB8N5hGa%KkH%uVP
>9qy#W Glq<=YKDDGepuPYNS6=wFNk@*Rwh:iR+D1\S^:1yQnL5:?y+%LFlnc#alt$$/pcndVVcS1N9NQyGa&\$
=4IQh1 =pbnWtMq+\EdbKtR&dFlnT^9NPD*e\d@8ZaPMbcNlJlid&k=:lM/1:tSVdJY!iBnEi6pa/M^Nl1VG9Tq
hn:Tn! mqGnJ<#HujF=8%Y!uDc5p=YNS6qw%I%G&&m$nRbm\Z#&9Pt4I&Geu6qmuL/#EtM=uYH9&lu&45WtGjiS
=bp/CY bl=y\#ace/M^1XEPcyTWNw\c^jKG+S9Npm6bTS9Y!iCDFN6w6I$G>^Vt#Buj#Z<S*&$&9wQb?A=t#^9G
Zy1yqc ><#+wVRbQ!RYNY\hjTKdbQDbcJYZNt!npVecicNSNly%w%E*Gt&n$VacjcM^Nlynw#E*GyMcCV+d$:G5
?&aYwW Di6pqnh5p8G<u&/GnuMGb=$cbjMeFj9Aaw$M?<Bmk\#:\Lyhi1NSNly%w%E*Gt&n$VecjcPB5=6med=l
=NeIwW K$k>5uaebFn4PwQj&SuPFF4miVyuNhy:b@DnYGI8Btja^^S4bQDnmFEnHhSI/hk\cmT#Dh6w=I%G&YmW
JR=YD$ nWdhcNTNB6aX<1Rinc!SDh8\RaaeEJd5PDa5^1?b46JAuT6!XPlG<wG@4emJINdBtFhDdJKqTtby\#ac
%aFq95 icPS+=#G>DuIeIbT4JQlDKZaS1N9NMbGa&\$JnZw##Q4Jj48#Hn?!HJCjI+#^Bpy*WPMPXH!e6l&lW>8
^4lmRn YCjD?St^Tha*GtPnMVace/M^1bEQc8TWNw\cGYiY^Tab#m\4#XQc5E=Y?V%1l^%*F9hRqN+m^5Vw:tVa
Dip@#+ yuJ\4QCSMb+FEB6pPJ8l/+?QDY6pdcQSNly>w#E&GtPnMVecp^wJi<m/kjuaML/4lD*pqR1ELG<$!1a8
wR*j$d mPe!ZT?e\A^6$pen9yhY?F=c6R%nZX4n8&>>w>E*GtPnMVacp^4>PDcMGn*blqGn&$an<@9&#P@dm&$a
n1KuM% 9&?9@L/>dVSc*H>^!>qn@J<#=F$\?c$tGHKpmE*?4eX>aIZ&VQ:6^Q!k=1Pmjt+uN/!VIX?RGJ<*=+%G
aAuP4k &YmWnWdhcNTNS66w>I%G*&mMnedk6<\#:yFbbR+l5W/Y<wbNM66w=I%G*tkW#KX$^B*QMVnQ1cNn#8XY
DC5<6G a@L*5M?9i#p5pR&<$=qaq+qeNGIN:Zqm9%MMa/M9w&AQ/1#w1<+/u/P^Z<:G6na:9>EemZZt&4=P^GPK
c*:IGI aX/5yh<ER?+&Mc#QG*Py/LKS#h<&4EMXM6HAEGP6pDda+qc==uVY?Z8%wC/MJSHDGp^ubKuSN*WbqS1:
Y+WHhM =$CPCt8Ni%X65*byDZ+\b>!*$FFX9PiYa+!tQQ=wy<+\h&!Nc:ZYEH>qQdF6>MT>ky:k\:Y?YeQ1dNwk
EdP^+X />RacL5/T+d!nQdi9!:t5h$R+?1Me<i?YWN$JV$DR*!:GQdZjBwBi>w#?/A#&D1j!YPjwYjptSD4LK@\
S\F6H? G&ZEwDt4qZXGLKjawEa9%ED?TYhe:*hj/tc\nnGkh?+F>V:Sj*9u9L$Q46@/+L#EGjy9H>nVF=9W!I$c
u+RqT4 mIeVG>Vk845#D=<a9?@kP5<b9?<a@L=nap>B=<d\:mhmeE%u!TybR=8eZQe+t>SA@Kq8M$@WkE@EYe*W
X\T<Ed cAe%EH6pw<B*:A!?V&je1*iGhnBKS#9\V+=&MNdX&yF^H<=HH4RDb&kHw?K51lnc\clY1aFeX&KDGwnb
H#\L/5 YTpp1XHSDpb6cAe/c=VAeM:XhNcwpuX1eP@L8%E<T?E4F@lI6b1bbMlh/R!^XtK\VbN?i#HayytR^>X$
=tiypA 45nIPnZww>K=It1WSk*Ea+yld8FhGuPL?bw\QVKM*Y:6+@p!b^P&*cjK@Ea?bWBhY8Y#?RRG#>a/u/$l
J1#1K^ 6qG*t/P@KWWQNTd/t+/9b4KJP9jE66aNhue!d=S8A+>4mH\\L/I8Nwq4P4HP<yCZTYqI+>/I4kVjMPV?
tPJ1WD #B5ju:Me=&8/NN\TYjTNPc5dned*puBtIC61nBw+X/:<=yWc!CWq%1FlS+EG#/Lp6c5QluFRdLI<nIN=
*>@WwH :jcS<j8/cij9NbdZW5d*dea/e\$l^9duE6SALGJYCBZ1*H1mBuI#b:pS1aEa14\TtEVYD:::j9Dh><S*
jiIEnQ %a*9Zwpt\BBH+R\^$YKNGwk^FB9+Sl&?etjaq^L45AeheXB=JRpAR+:y4PFwkCEjdW/GYGi^8GcT?!m8
#uRkVL teRthX8qdnh1+Q^Hq48YG6m#FG9R!InyFb9R!Mk4thhBNLJPnX!wkXkDMjSyN:HY!iLeN86T/\VYE#WR
iT%MNk ?=6%$I5cE?%W!*PW^#YJM<!de9J%Beynnkw^&H5hH$^p4A6n4QMK*mL4%KmFGw*jcDb?I^@p1hH=nidk
+&@wKB N=1V*$n*GkctkKRBl6\JanGGZ6H<eY>EDH*jD8RK!/<Z\\bYEH?jhW+aGkW=G4NX?JmZt#mS\ZdKaXHJ
1QHnaQ BnZkX<9cNKhG/hSA4L*ayEc4%MBillnjXWYMeNdGN#W\F<*cyDY!mZjjEA?uE^^ypA%1bNlJDaRNDPiJ
-AXDH! 00057ed478f00110333 Page 205 of binaries1.zip
IwyXB= hRV%GGS+ny!\llZDe&m\kG:CGqb5WAN4YGha\+w%c5AZLVcy$T5%5IaXR%?R\ay6KDMZq^n/kk<>/A9b
yXtMkm pM@IF+&hhYtI&ZcG*A:caWRdq&55pcGN=+=+jthe>&V/X*X*Z1bGah9wqY&nN:cN*6k&tJ@RS&VpbuGG
<awd&8 8*1!alecGQa<^CdLR&!WQJw^D+c#nHtE4\\&9>ha9\V@nDQphqD&CM#=T$K?j&e#W&Nm#q?aC<Rbe4YL
Q#hj\d ae=jjImCl8H<l%mnS8G:6<J*d+mheab+idHP<lBQ:R#u!<SkE$6GZpV6%B<dlnqN!bu9!n<9/6#kl%D$
SnETEG EP!L#>BlZ=#B9lRq9!QDYF6/KhSA@lK^Vw*G>>K^N?eM?/#PB66>H&#*#C@1p^^?n=4ki*hGi%wV>yB%
MkwHRi XR4tj<+\@/5Jb&Th6a%G/>SAZp/^Ta*S1IH#nYJ+X:4iBS1GtCe^&AmFZYi!TR&el*BYEnZKwAbmEuV>
1=\SK* #EGN%1kBQ/jayAdH^t4eM/4=wG=G*5H5$<TG<nbne9W?QeAt%4</:^#6t5+:R/Mu4H<4<\k:M/^@uW%1
i#6S&M bL/ZD4?>YKeG@Qa/GZSRw@Fhhe+:uR%1\G?9c*+TNTd:?aDjZk#:JZZAd?<M?SVEBnYRW>Eba9QEPnY+
%HV99I =%bH\#!5KXILDQuCuTG9yBn55<>waCih\V/*#Hqm!=\uP5M<Wcp^wEF@6%mnB8iJ8mcJGl#*jatV1MF^
5!>^Kc Z?jK1eF^Z?jK1VGNG5lZpF9BQWuPE5aFb^kZhJXpJ=9WRA+Zb+nb%5q/#LP%ZID8wA%4k#c5Dhw\b:Bl
mCkl4@ 94KCDY8VN5\b&@PpDhMbjG4RlnZiwTZY1WEd%mb6tLNGDhw\b+Mc6GHK5$$N&4DPe*Jm5GGdM@nPcMQ/
Plej9@ RS9Yia?EM@wNqH+n6pth*<>kdJNhF#/SNbdH>ba#nPe?HFZ1eu*84FPD/*Ph\W>ptD@4DH+q\@^bb@Cy
KTel4h kS!Day$c!P$1^uhjeS?LV6ecNdm9=>Q&Rw%^WAQ=Y4LCjjB>9e9E>niPA@5$R$h&\iADF$MdH\h<+M:k
uuV1Am A^hDG^<He8p=R@!cYKeG+wHFJnX\@6\ZiVl:Lac>Ay*>l$bCLG#iuQ*QP96QnV!ykV!##yDHY1^VA?ii
6pP^BA Xt1=&F=<Ba8?Q*SbV&RN==te$ij1$!E?Y#M?Y<6<Nl>aC^tj4iHMw%LcHhSwjLcGHE^mk^w+q?>5Jtwk
^VCBH9 X:E9#uFHtln&BVS$R/Md?&XHZnBuPAjyDHeJmVX1%E\N?ySGd%n:#WRj*&RPTb>^IjiJGMdccac^h9Je
h=ZXXl t^nG&tu$mVmd%KmNG5luJDcw$R5%eMbJ4FPDh6eb:NDM!H@kLMEPPaMhekZaIcXAyAb!^#k4Sk*eq=Dq
l^GE@m #5Q*#all#4M*/udpk<1ce1E8HYiN59IIH&Vwd<wnZMnR*=SHtB4b1IHeYe+K&:%QE/tB<*VPeK=TdFID
q\R@jI =^KeIiiAYKjG^L^+V8VZE<P<YFQdS5c?Pnh>hiKiC&iI\TkH#%Z1!6laZqt4A:Ai%+%qnYbpeh%a%8Y<
MHJ#S: pbZn!GRNGmXbJ^9RKMk::R#9Sc^VA#qt!41AFR\?B&j\PakNc5Du+A\?B:Ha6=#l9FA=&Q=<<ZH\i<#E
?w5Cle 9=%a+/!nwAWMc^^u&KeS/>VAtVP^TR*pPHKGe%Smk^4IhXy$NSE%b4T:8tpl&q&^cHih+T+Db:m#Tc^V
>i@DnV A:FSPp1L>y\K:qRyTuALDS%1JWNjTAZ*y?kwdcLGRF>R?m61+C:mpumZZ%H!%E!G91AWENCwPG<1%1qS
Pc>R$8 ?K+1:9B\ln8?=DJEi$/dNypt%uuPeDb*8j%mi=HL&5nm9KpwKW\nm@Mtb>cwkX!VawMcyXAD=<?Z1=Ic
y+Scu5 !HptN1tBHD*PS1LGGNSAQ6ym*kpLGj49Tp^CF9e<uBuGI^$A^8@X#G>beh:QGi=pKIy%1YS^j/Mw%wX%
PD>Y$^ tb8/+G/u5k+ppp%w6FTl+hQ5SDcwkZ!SSju=1XEcNZB@9NmpB9J!!5ZM>1KLD\QLQJjkdPKdK=/tpE&W
yWpb^? q#AZ%a\B*%#^NAcG8YlSQA$%MBh%l4tw&KRG=1JF<VVW+F^AkZ*RaK=u5RaN4l9FaQ<!%+%qp\>F4FPD
Pdlm<F e!+F5MY&pbq49C^uDBnYwYK\y:qlHiwM/%A^&NQe5A+6tjikmuX1aB$1Bu81PCNwhK^D^YBQFYeEna=%
+4E4Zk 1FnD8?<+h%IW@^I%NJlNMM/SmuGP=A^#yGLIQ?T5HNSFd9WmR$+N*AqTbLCw$SM%pNjAGYI=^Ta%eJ?T
*bPuPH 4!1\9!5GY:KMCSl!tIw%c8C8BdFJnXKykZ^>alk9%Sqmi!the$hj#9CdD=\Dewb#RGJ^u/5wnDcDIZ?^
aWy!1i GP5*+Q<Xt>VAPSHhGyTwkh^<#pctB8=/E<PeRhhnX#La&DKSd:Q+4AV9&ce$iA:FuQB9eijj894mIEM:
M1PT=$ *iVhL+w=wRd<:EZZJFEDiX*KJ8cpKPcEGnmuyP5/$A/WJkG@^@9FueFj=w#n4/<1EnX\H1hW=qX#Sl84
e&te>Q &JSM%9l:8M8?dHL^F<Yt+Dq/ThSAd9YmI/nW1JMc4XGnG#YRE%yZqlS1VH/nQ4H&1:#jXA^49:1^PZXn
c1FX$b e?4G=6TN#cpdt%M*N1h8dE:h&J!/5Vq%a*Q1^8dWne&yG=6VN#cudt!Pe5^Ak*j@PPPc!XtuS5:WRA:5
nS?4cD wqTh%KlGDiRT%hW%lS4>wEb9%MAhdtKVG5n6Z>4B@dYt1%4BE9a:=i4NbI$cPBM5N1lSKnX1wpd6%MA>
YA@bBd PtKVG4%SA:GtawMcmDW6LZH8/A#>9Qu/LbPlu:iE9PI4FS\%EDi5K+\KNSB9IhcwkZkLMa^qLZHQ9QHP
%Qd!8d TVG&weR><&deM*jGNtVeM&?d6X4d4NYcIa=CdLK<bm!9Dba*?E=6<J$!@&Sy#K9tLLE>b&N:#5lLWuR%
8I&/w/ K56DQJe!Zl\5n@MZb@#tGZ=:Mhn^^46?^dDGcd#Z\%qt*!4ek*e4tXpi>%>$6Juqec?qFb^qXBb4nCt6
uL>a1N ep^yCy+t/!\95=@:J&J=hdA<*KGqdQD5H#:\5##8=ddG9X!j?dB@6MV?$Vb&1G*5WMMbLDH5h#diH?YM
jY>NhF ?@#?c=*qIai+$qSm@G$<#%Rc#!+=!?\j9dB@>ML?+WMK!&95H*&\j@VB@5F#&/Zy\lP\^HFtGMibpT9L
tkdZR$ \>&!<9DSQw>G?#\R:!k&YN=k?^8V:Y>!H>kb&>@pQ4CQWQ!?E#E5TntKNX&duN91*mYY%^QL\@$p!mDE
+#VYd4 ?aa8Y\lM1W+LGP=<eab:KI6TqdA<:wN$*q8khK1b=jYD=TE*9SncbN@Mjjyt:6N=:qNyZC9L!=*qqeL!
t@JJ4c ePdCGi=Z$\lRYB=m+=$l:=5a>lp/#:1J\j:=5ydjnihmhH5WdL59R#Ht>W/jhi@$YZjiSiiM+/Z!6PF=
VAk/qM P**Y9qJL%KDQ8uj/4H8u#>wb^kA9DV/9Q8m#:wQ:5Z%\Q>bby\d*Ld#KB#Y+H?84jjcF\j%aydTnB9hn
?/wba% uZX1eD@YGh9j+H/59&dMYV6#4D4nj1#Q>GAVqacQG6!QhVcy5dFDe&PHb8*WcIWc8C6WnH%@D9d>nY?:
iMpBt9 d*#da?QdHl9j>6n+65jG6#$&98&^<Y&QnY>:dH#da?QdHl9j>6n+65jG6#$&98&^<Y&QnY>:dH#da?Qd
KMiZKN Hl9j>6n+6y&lu\@hQk?GuFlmuS1+w$yd>Re%eA?qM?RZFS9WRH=Sb<k9Kwb>yLEbW<btVBtdMeYuhZ#Q
1eXncn q9tiDihThTNlbZtNdh\/&:klb/5#=H$4I?N<n#Pe:!t/eu!TVbbZ?M%#+VjQ*M5htZ8=I*j&6##a*#L8
!D=IAy F>i1EZP8WbA9!Bu!BVqn9NRwnGMeliQMKB^uhH!R=TFjZ>E%:m^958>Z:9YN!4$?H\blh$hF:8&m9JI5
Pj8Tt% D?jFudZM<l4:S^*5H*Y\j:TNHYwdP>Rab?p4MQcQ^ylKH?K^J#M&99i^<d&Q^9m4$ZDP^lu8MSHDYP6V
a^mu/m C/\=S<h>Zw1<bQ9#6T/i6^i&Q#h%iH?<*$CM:c>*64<?&Q+/jX+?<4D>neV&N+#6d&T&9<EaaX?c59&N
Z$#htK !9a*P69j/G^@k@NhViFRu5@NWJ/9c%HiNN4utYtjN#/H5jE=iFXwu&iujjc=FM5d5M@#wL>&<p=kb\u&
5SC&ke &ci5niX^QnR*</G=tj9M#h^uH6!u>qiQQeF=MKbwJ5aW#aV#jtLaE=\Jb@9EMBiRP+y@m*N<SehlYSje
%YP@E6 8iaMh?E+w!&b8lpQnLbpttE8yYP+LA>uQJ*Sqp\q+\KnLZHG>>Lyb=1h?!B8TVB*uJ9+Db*%RL5cme<:
!&LZ9J nM<:nM@4E^l1=EEN*EFSqDKPG4kQ1Pm5B#W+Z815B#YGWYP\Zdp^kedE*ZFmdG5#5c$yRVAa:nEyP86B
X8d@JC DiSHeqdaX&hqZ=*eH@Kb6%EDh$<Xyicn^pnW+J:$uN!Vu4#D\^epS=\#/NS^uDPISb6a%@XJaQtkB8+Q
GC!IT6 1C5epY^TA*t*hDN=wkd!dqW6uctB?!DFGnX\h=jalEcCD/*1j6NC%1GSaNie\c/JNY4A4wpNcmAY^%qL
ji9PRK %GmhGn%VA*j8X8W?ykb!MakNcBnYcuZh:puYwGHI^TA&1aFeDFY=n/tBZJ%XY!k5D@Hwhh&PADd=ut*!
D4Iy8$ QYjE&DlDnE*X6ZkwL&i&eib&4Rh#8%bhd<@!pQjZ&ek5d$!WX\=?<*L\t^jpI/54Tl$55:?X\9=YEINS
*64QXS q@ea4NQY<R/FKnPE<tSN\BLdZ$%5j#Wuqwe</5+1?*/6:Q5X=>?e+j!dM=^@E+94I&iVh4eh6L56$i/&
FL%wLX ^Ddbey\nmdFN65I&&dBu=K!^VVd5GVu4dJMNi$bX1SIV&WCh?<aP>a$h/6k#ewb</<+K^+BiPRa\@5<b
=q4H$t +9?eDa/@jZL<Hhk#Ey5wd^l6+pCP/cynIm\Q?eihXa=H>E$wtwF6e8CPB&iVdZIidJQ#aJ8emZcT>:1J
AYjqW? eT+\M>9pSH!a5<w&PZG@m:PNHbwdP#Syl*\=CD8WD61lhNAPJh:uIIa&1i6IB^n&q148+M=kjXNu4Aih
%R?*TX Vha=aV*wDP6Bb=\*ye&<TiqLYF+bLA>*Iwq%qwh:H=#l*khu8G8/Kt$K!nQpuZcG9NM/>XqaHuLmK\6R
8LuNHd but+L<Hb=49%k*ZyPP?u%JAa8@&%aA:uw\J5y#P&k:Fy8&QVhkjYc5/\XlQn8^?F:*=k4TdY1IG%t6mk
lbNqLa B6b1#4BYE?9W\FyNnH%\e1*tZ\l&I$&8%j!Na1#Rqk\%8FbLp&5%b=McZK8q!dYc5$EN46X<8ZBRk&8%
F!Cn8j NLqYe+c=w^%e1>uB6bw#&ER:cHQ5wM&^k&5%:@yGDc:XjFbe1MG%t4NPDc:XuE%1eK%tB>h1huC6=55!
@npR6S >HNLuCM=R#?*^LYc5$pN46W5ec*t4FMDijPeej&tc*TwkVk!5WEN^JG6/+/ykd^=%R^=<<VR#<&RW<Ib
G9Il/Z ep1IDYwkQ5eb+uQEPnW+jyklFphZPYPh4Kwp5Ip=9:eC#Qp6J::VdH!uPjQ>=e#*q?F#YMi!<G\/DE4Y
6E8&eJ YL>BY=IudWp=5A:X^i5w4^m@d<u<91WWqqeQqqed9pjBQeF%ZSIPN6m*tI8\GuMSmtHPaM^FYHYMFN@I
ND?MW< %<S+B<\>IVbbH5eWb+QqIZi1GN6puY!VFdqV1:ZEN6pT?*uD@YZPeH?b9Nm$5c*T^4bGG>5cdY^Dntqu
C55wu/ A*N18VXRZn<+99qcF?X%=NdW$WQcuL/^Pd&!VVIut#QE$D6DDH*Xycj+=u*T*w?DdZIkl6/b5W$P+%k:
X?i#i* M69pRA!>nq1!VR:E$P6YGddJMhkt^/ThuAjd=ERM9Snd=M\e>&htt=!XhuJY&5ub&Q=tb@9nuiQPJ6yj
-AD+8y 000d41d874400110333 Page 206 of binaries1.zip
>#@c5k QyADy?y!\A#G8Y*i?CH!kS#PayQq6eV!Yth=+&B=w:E<^NDL?5Et=wRaitiIwc?/qI9qIabi8+/F=TGG
\kwVD= *luuQup#>>GFYT\Q8XT16!4MP*$+^:#VS:!B<k#uR/58kYJ=8F>TEWCX=iFiMti+5$=554#Nh?8XdcMn
GC^bTE u1H1t8yE^4a^Ct!VM>mtQG1MJcqKVp1N^8<^i1aG>$4#+F/yV*&MG6\4#d^##Su8ZBQDZCZ##4Yciihc
uX*SY\ #d^#4Ydi8TdY1dHyC*QVF*nutnQpqBWd%Bl5j:^#VR##SKZ4/&R^Z5Wb^?S!eE\8B</%XTWwyAdP:+6%
H#9y4I cuB6+G^TA*h^PpQep6mkB8:mXHcBk^1+m:M1Rh\p\*lWE9I+PMNhuGKhGwmjhMc>eCYNw\b!:+kNc4SC
P/*9Y$ nb/w$V5%/KhVKph1VQS#JWJLbPnu^ZBj4#NDQ!<<h%KXm+aciXIDiS!1$p>TA:qW1uLSWKMj%PCe1^nu
LnVm&e ZMyFE?hISdeSk!EtZ\^nT6F6ctS<#^t=45Rc!?PeT!p+YS:uZCX##qWK=%!qeM/%EkcBee=XC8he#9nN
:SCj=y C?heyZDP6bLkpLG@Fa:hyZLPXT4uZE4mk9I1=%!qe5/qlCk5n?PMpw8\QM/=C9QZmdH9N</=hLki=VZP
&dBYX? 8ZS\t?X^#1WD^T!Qe!+hhGX=uHQyACdK/^5:%Dh&1B9:S#j&n=:bQ*yl@?mX@cM*>w@i&V>+Q%nXATTW
6eGk6e N\:&D^$wIYQ@&Qk/!5dZwTB/qqjbQ^SwV5d^cPA<mSnY^AwILtS5p#N^LnAV&?VEGSM^65uJiIE!K>9p
mVqkFh bL!AAnhbH8jAClTM=Tqa4aB^L*\FJJFNqwe#JuWF4IDlnEqhASJknBhR\EAFa:!AHNV^t!?HLXnCPF$V
=Yh#9k +\X1\y*W#nlH1y5=p1?&C59DYea1^^@LG=mj!4p#!LBQ5#d4!S4L!+Qq+c+nb:mV5K=NRVDE#Fb6R4G<
6ttAuk Cb8>8Ti8ckNlpGFPW#N!ia6%q4j=dl*u6y$N696Bj:\#65tB?G^umM<Y\>n6M&1&A%@4WkQ*Yn1dmSwV
mj4cnV 61u/Ylec96c6bFmu%Lt^B*NnD!dnl/19hcqSPnX1ypdnN=1N**I!66HbwAb!:V4nZMWb&u$:pGNBDP5W
Fj=Fa+ 4#F5eV8Ra$F5WAP=hy$l%/=aw\d*1b%NcuCj8l*ey*dY1WF@tdj\k^4$wdXEH=w#nIM6+T!QM>\#K6cy
F/aX8G pVM%<1SGchTwSw$/1NEKNZCtWK^Vk@c?di^><:W8NJRIuA#>9QqcF^4G&FXunS4b1MG=cDQPSZWEpB1%
?&\EJW W\M=NJ#SFn64%BlGDb^Vh#dblnLPyFiq+$H>hK5<GQ$L99\wLI@?lbad*&uGuilXcaBa*tS:#yQ68VCi
EIa?mZ ^lu<:K%p&yKTcW5Ke9T5NJW54@H:c9ECll\>#mdmT=V&CPZX^L+qV#9bbHueb&&X?/\/k54!GG@StL@h
TiVmTS GeiWXlp9*^48uuLGiQuYnQ&<MX:ic*i\QMdLP/PNda!Zh<d?$dkQ%^4*+hyt@h5&/>?&Yj?&#j1*dhc@
6KtyNm ddQ?db9%d>85j>6t@h5&/>?&Yj?&#j1*dhc@ddQ?db9%d>85j>6t@h5&/><&pE?lK4WZ!&P<jB8Va<?a
byP#JF HH9t\Va=GT@jy4FNV5dL6<q+iY>CqiW^Z4=N?wCe5W%8%4>65@:6t@X9*/^@?&d>&#j4*:=b@@dN?4h9
X!5JHe %4>>5@:6B*I5PGP<9K/5R*tJ<jI/+w:!E8Qq?&d>&#j4*:=b@@dN?4h9%4>>5@:6t@qR*<!H?td>&#j4
e?E$?X *:=b@@dN?qi=yQC8nG5/N$$dZiS*ZNiB+&@#\Y?WPa@%qS@&cH9tGNW#^/PiP>6Xu9^GJYG<:AX*ZVw4
J<=SCP %CmMKi<F?e%14=69XLpY/lZ=^=XSP@N9/!DnuL4:4$GnMT/wN?RIhWd:*B6!YK*W%tTMui+!9JH%k#cm
Q@/E@c J:b^d^^plY&<$%ipuGJ+nuEk#4iQSQ5*/LNYPt/!89p>&8e?iLckV=:@WP+5jLhJ9=4!Z@H*/B6VD18w
$yNI=D +c<A>tZ\LthF*KGhnwP?8*F\915:deq+Np**$yIb&9nauIeh1dE8CZh*KhML&9ktQ=I#R#@!Hw*=yK?&
YH%HAe $Ki%jaY@dek@468P1eH<K64/GtVII/Jin4ZXtI\@GBQ^4E4VG>?j41&Qjl\6!/=:>b<@9j@\@e8uL*:=
AFa5\n !!>?<d5Q@?9qymP9Z@#m6#@<+iQNJY:@e99mF@@!<iNued9@@N9j@LhjH8>j6P9%M4?d::8N>:+i?K:t
RMJpiM q/:+\t?@G@c4Z^:j#DuK??>$=4YMq@VNN$h@?eN*L?Nq@KHu>@XZ@@&LZ@*1m=<?9@@$?c?jZ9:\lhi5
&h8A+W Dj9m:@:8H@:=H:@+*%BLA\RWAAIACADpXY$qN#G^@&GAARDZi\IANAAAAGN5cYX8hHM9eGh\L*hydnM!
S%q?dV L$q8e*SldG^qem>pd&N#L%BHWEq8e*SldG^HhYqpbT=\bGd5@RhWFEpZN+\QcaCBIR+bhSnTpCeHppQP
bN^KpX MA\=PpVJGWSMbAHJTeSEqk\CKmK4bJGeXESWpwmAmInb%R>e*Yh*^Xj*ih:#uj@=u$>QNV*h@c8/hi9Y
W^/#!R :iyd6?1Kp#Y%=bD!KLD+*Q#\PBmElCKk@5=iaGXqKFnB@GCAG%TB:LVjdi5H&TuI#T<EmmS8QWHb?p%^
RTweEu C@aQDZJ^C+ameX<9cjn:lY\>5*WF??%KpH?A8u<+%A/K^WD^TCkYm>@/R+R/RMG11qC\t=@4htGw9^c1
e>N?I: 8jW\<k6e\h4GF8wZ/8P#BWd?ejJ*HQyuPA\B9^MP<#MetpneCaj>KR/@a*t+u?K\&J%\?J@m$ImheIT@
W$BXH8 +nTC*J^CQQ*>NJ%C*KB\VWWppWlAIyEwJA/F\&Kp6lw&!N<%%MW6CA1*S?N^Y\q9n$Ak%LaQL68HwP&D
ZiMp^d @@dBij9k6H$I&V=A6\?c&\jQ:WQ\u#j5\X<8?Q^=eQ5#u!<a>QbBj98A&D+k@:#l@thS@*uaHt#%b^F?
LTcnuF &\jZQ^</<KZa4T1ai+d+dFZP$!<+^MuHS>:b*>>d/t9N@dj1yS*p=P6t=PT>XWi5QFaibalEPt*hN@J*
K!#QA1 *aEyiC^S/1@MJQ/5Ej=#?H54IBH@NjI99jB4J:R&ejb!e\tBKymFPwh<8cLu8>$9Fa!*14d>A\qX5QJ$
G?iQtZ DjGA+nBRBX$*#@$iIXAWC11k:lpTVHaL$9D*DjD*&?:AlC<h%ee@!C#A!eWNmpV>RbTlt>@?4&l6V=?R
Ete?\S LXayGNyccd1=?L8/RdhyC\:ba1e9GBVJZEAtmQGCGYQXuenN44lh:Atc#1cEEp5=9tS6F>QtlVCXQit/
kZMuLT 4lTmYK/SbLc?G?Y1/&WHlV^Dh#NmTRR6GLSX^/>bjc966?=96$Ybuy?4Y:mdK%SB$!*M$<YNw1MPSY%%
KeEHJ^ DlVmD+Zm<CeI@i>blQ4GImRG@TiQpCnMX4E:ePq9VML<nWpaNAL@W#aBAFAAkAqIV^5X8j+QNtt%A@L+
e6N^iT /TE5RD1%69XIVVH8j:DynmMEFBe>G>u4kYNqI&5W#4!NXIh^>umc6:nl#9J^MY6&PBEKKEAiWHhp*\#C
\B!\4J hlej5H8iJpX%eH?V4S8NY9yRtaRktDSQVhD$I\muHk<B#C#b5?\G*G\/hbpQjL#L&a&nLe@<mD<pddcL
GhK8&= qyqyN#5j^<1q6leeTh1mcd/KKlIu?ZZF:6@TdE:u#/PuyW55#keDFI$q5$Hme4!un>^I:Ae=H#yI4pJB
$1>XK: &hY%uJy>eHK%J@RjS>t+SmY6ll&mVIadZ811!P$*#cRBND5I$=&a+Jly86H&>4A#pA:e&8WCMmP%$@lN
L@<D!D XL<nkRWhWc^X+RQwFFcTNq!BTqXpWkyIF88E8ikPZEuS5B+yT+tGl^R\G5nTeX=y+=C>pqIe<QB*N6DT
YEW8y5 HLNtSlL1FJ6G@pNF68JGD1c+NPwcj$eRc&\84LN6+$1c^mTpLF=/1ytuAyqh$5lPN@hRNc*#jd/ImlhV
SRm>u1 \MP?aBd?jLa8&wiphENTJEhe*+\6n&=\5pS!C4$\+kK\uaqR\Pk1%4&*\lX81MG^k9DdXT+!!mFE=5ym
\@AeQG %V#i%k=b=ZTqK6a!PuP#@y=SEyAA+%^6D6jqEpp+SXVTJ><lbY4tn?!PM/EG/SaXm99c:SXJTGd+Li9?
p$Abqe FDC81%C+:WT&%^uA<W=E&&k<NKmFn+8yEKIE%Pmh\HKXqE<beC&$?Rqq#K&*51MDA8y=8YENQCTJpqFb
I>uiR& w#TZ\#C/lIXkL+ba#:!H^6#FV*FZa46i1N/ly&cR!BCaS@!uelwQRX/I?kqte@HibkuV&G/^y4FM8yaY
5:S^FR !kBVBRTbFFMGEMn8JyLn+<X%C>lnS6/*mMT!<mRj#>Fk64VEh\BmJiymwuM6a?8qH^1qWwe5+^NwPIC6
mycn8t qPhP>uCRKe^hCSTF/LQ1hcy95bcJuQH4nNSKXmmP:5:t!tWTaRy+XXX$XXniPhqY&8dS+$LIY$C&?u6V
FYMLQc 1iK&P\bW?u6ikCIakFYVEhd!hliD<#PAFt<:+4*hhbGqB4b!ER@wBX4u5\#F&Y%napJA\D5u^%TG#yqV
##L%/K hAcBZQb#WRKw&1mmFRmaV^MHEE6^ii<IBVk=!NjTqh:nE!p1uT8#JaqT#?>niSB$D5^Z/ym/L=AyZb5n
yd>pyA !m</tuACtR+Zq*bd$IbtLD?%%/y?@C:1Wi!qIDEeN>T4lT$!BiY</?SdJ??WCidIADFih1w5?Ll4iVJ9
ued%\6 KmJiMM8=RJQ>@Fk$!%DLT=m#eMX^NjhpNR=ntcK+6:\BADq4RBj@laXEG1lqCGlPkTV!6mKS9Jwe%&cq
u:b6wS E9qCt#iRnI^Z$tFHHE=W:XIqc$*ST6A!XTRuMPt*EY^<GMINI+M9A:RNAPCCmV^AIGwkeqwRy4bbpaAy
m&5\1@ a=4LQMSRBB%NSC1&$SXt\6TR<qFN6ElScTet\G<9YBnFQL1F\/Yh^MM#PHqQP86=TZA^1ZX6&MLtb?%=
Ln\n5l AYBttpS/=6nJ<#RWbRYi>kQ<Cau?!V*yi^PnWh!:V/p^PhYQkT+\tZhNTkqw1ty$^hLicMeW!$E>1K\=
Z=m?=F IG%cbSmeqm\lTML\=^NPH8%Cch^c!nba+EmM%wb4SZFIIE9+?@Nhi*Y48q=#S+P+&E!G4KXk=4APAVYI
&DAdaC >Fu#DCID+\pEpI*GHl<h@bA>LqpY%5a#H>qG+kBD\<@EGd1dFLB?Ty1y=iLauFGcMXLtd5M#145KMjep
u>d!LY M<hb6&m+&46HnlBpwkjEMe:q?*uZ*hH6Im#ADqSINpeaiMuJTAKJ1ARFR@nW?eFuw!>dSV6F\?@d>QLS
h4!EEe YP<8RdSlyBCn+6BJJ4BwMa?lKTR?#qANMlMNJ<$RSM4#5<CKPM$qtk*Y4MtK+!PXG81EWqPGeMp#kCc:
F@q%/! utIlKYePNywSpEap?TTX#q^beJVTc^IbG6X6TP$M+6@MV^CGRJNPehPa!kMnc^C#!AKFcG9cRnX@>1ni
SbHp6T ZDwuKARkt+wec!Nt%4QKQ%ucVT?^!^Q5#TTdSKYD\=RVnpjK6>HwBuqGMVHTeIqBI1EEPte!I?$LM>&K
4Q+dY> >QN!<^#i/dP<uPW9%Gk8jB^LmZ/waG9D#<SCAP+hk$q#I@%Qceyla?@&chLPKDAZZG*Gec#Bc>WMcC!k
yy8h$y Fat#nlwhQE\$$i*D^TluRdi&?AdNTe:dpRTt^EmIEG1Gt/F?DB#9+XmqYa$BF!I+cHaL$FNJ95hDI?nW
*XDCFl MbbIAIB$ukw*wI@edhWY+8eMe>jTCH<k6/!dHNjSVPj>G$Y8&>CJluSGX8+FK/h/4$qmB+^iHT+jD*m/
%B5DEC F#J:Wb:t6LLInFcc%QF1Y+%:@t#B5mjwbWyVhR8/d:1ER=qGL&6w/Bb#mB=Pa1a:d%D:\yBVI@JKww&:
-A9A5: 000dc58778800110333 Page 207 of binaries1.zip
WXiBVn Sl9eTCZ!wHPG5#8\41CKVt#T*8YR8tF*?tq?ER@t&YmKVCi<m=q?eDh$=AA&tVVXHkM=!iA/bWZVH!Jl
DdQ1Ne <>a^>$ZWQ6*4nuS=M<uARP<6uqwK=4eq^Rdk/8I#VH1$DFH^tVBY^Gdq^dmCkN<KDJGh1p&\@Cww4/??
TAFu$k ^EaGH=B>1iDSYB/luuwWSkLLS:dl1Y^QMeL8JDC*EekKwbdI9J@Dth<y:F\dXRaJNSZNRbAqteP%p/kI
cdqRa* Zt+8BFlnIwa9bVXy8aAaC9IapHdiLI&FlwaplXM>=6MV/Tc9:$N/:1h%WYEFVdha1hEae=yB8YpyJ/QM
K!TP%4 P^BTBbVHQMl?c\bbBPNl$aA56Zklk@DI$/:N8tyW1^QJ<A5*1hthWY<WyR*J@ZL#>AFbAJiw!Lt>#mY8
&>cnGB n6dIM<TEeyLpt%ZS:NFBih!wAaklaBi9E!ce@5F?tJPPTYVd8Y#><CRG<XcKy4wal:m8eN>ntdwe=JAb
9YQ8Au #c\cw*kie/pj4=d=^hYWM^Q=c\$QphY#CIBdmHbi/u9tiDF:SMHlYwcZDaw5+beq%GXlQCQ%NJpmB49E
D&ce1Q 4/6#1wpc1IXWT#pZBPi?TKK<S\ld^8YFTl\=5lIXhD%D@B#?n6u/t>>/ld9EEcG=/!bPq$#a*:wyY?Y6
k^%WIH G:L&CQC!QE@a>ib/yFE5PajWB5ln9iQKjjJY@K:V@N\55>qG/yF!dI4C1&@&%mJ8=bHEGALa&*NZyTLH
cBBlTT \PwQBh5:n5/YqA:uT9p8b>FM*XMZw+Y&Mk?%!Muab#Ed\611@h65Ba4G?FaL8GeuaG1cMwZVbVAEnX44
A1FX=I W?wdtw:hkHbl45lwVFTj*Lw<4EBdd*DPpK/ia\ZI:iTV=Y\Lny!#8ltCiC+5VZWZBuk>eca\S?%tK8eX
RhE:^T n+R!BBRl/6$@#Zu^TBJ1c=AM$dq$EkDc=RZQTKb+RP5$4j!8=%$q:cwASpPSPB?A#@6iQWPtYZ8clHCy
6nT@iP kNwQ6Al/y&tbk9Q$HYh+cNLj6Z9$S@M#S=Qk$N%TddwCT\$i5/!Cw*D&TAAjDMwMPC\IFT=68%+NR:L:
/d59GN N+nTMB$uEZk=uD@Me+AZX1Yyl\Yy>PIFXLWCSbAwlKh\BDIR>u/&d=jIlHmdF\Mke#hAYK*AqnP>Y61J
M1bmPH qe9bB=!?JlQF<Zq8kD=1:1yVCni6MGPBw$4pchyAaaBcEL<VBtDMBAQAGWScIVN5VCJ\qWnBTYj=Suq?
n8Dch6 KSIyCpu1b=aZaE$Yce8:M#>%jkHAV8N#6akjKL6yR1&ql<pDNEHeV5qTXFALXFFEW+K6Jytd?ya%&yyi
8QXFGi 9Fit4eE=5yK&+Kl+XIAHa@yBb%jY8E@AIA!mIEK41Ftk9qY&@VF5yp6aR\I+:<ZpSCHRTQAX=5I$t^WT
%=R&^b E&CFS/YhY1@BWA<YZwQwn9K6APudM*j:ppYw4QT$Le!qh#BSE8!*X6q%EDCwZ!FwL\<MS85pq5W/KSXb
%5%EJ+ FD/V@:qLRqC$nRy>9REnN$T@yjPeXIji!b!q=XmW=p#hDSeS+qGu<H155!Q!JCJLm96j4>Ebk4uGyKuG
w+LLyw ZCRc+WLwb!w@=PKcHCC>1/mMQ&wJS44BQ\aRtbGTk^ynw<>\h4VpFWiC&bPWSe^F!1/4JCA\lWiV5>Vb
k?T%pw mtDMWeK#e/$L5N%#JGNt&kHHnmnSlRW\nX>%yKER#H^4tFkI5BYm?1k:?ZEQ=RyE&*NTLYWK1W>y#Ytn
?WYj8X DLthIyTk8&Y1<%YlZChy<pRGeC%RA8eLi6q&C/WVVAJQYV%ww*ubQLlu*Ht:LGZdNL%ETCTctbM$!!JQ
hKl&ld E6:CIyt!wHKAY%\K6eJi%$WKtup/J^qN\wVWEpZtSpq#pWDkmyy#&i+mY!N19e5GYX$PY6Ii\W=4!^Ib
yCD$WI hKR6FW\>#B541lpyRCM/1\W\Wm8CA69mtJ!niWbu=MSpQYbX4/n9blF4aYqLB5lQ!GF$/TIQ1yu#l<!$
RJ6ZN4 XN#MWCpc1$1pRmaKSAy<lKKwnCJ11y85+VP:@Ry!=Yb#V^TpRmV+GhYi!hM%cJiq<wQ:p8kaEb&NB1IQ
klDFcI Xe$Zycqh#EH8I6RIV8d*kwb6e9VJXB18?T+hubES#BBAd4bXTB*PYACNa8#lRT6KLXSTARN4uR5R^1:j
8AFB:L JiA$w59yV4Zl/w/AGhC%/FdP=$6Kau$uVDDPYja$WhPcWVP8w\+ee*BcWpELqJ?qnay^ZcdTbP=cwCGc
%QTJia kVTnIQ\D@K\pNPpCF$niYTH!9J:#RLya4cDwHBe<lCa^KcPDVN>a\PME&D&nK\FkBYV:>e#5Lm>8!8^+
a6YFZb !N&?dp!KDY!uHuR6AT85Tn8h&RN6P&<8#CY!P:yQ6RR&\yMw##&SkP>>b&Al1GwaQ^Sd^#ZcJ#KnLXAj
6*ih4A RBjJC*AiEW:ty=?b^4j#9w\WwA&h/alEeX\M+^e^bGcCKiX55MFqGct1jN\NTLXBcSFLwBp9$tmVLp1+
X>ARqK T$8Rh@b\ThFDRS1QQaDQ#4RC?$V5%R4+cd\TyGc+>=wkCw1%kY*tNJEl9SJ?kJt^ZS^*/mMHlETYiiy:
lBGp@* =KuSLFBe\k!B8b<p%chd$q=jCl6lTVbutBN!u*QtwuL\FR!$S%pKRBiFSHJbe*^w1V:k!GwGX!HI:DR>
:/eDj1 ^qGmL=XKA?mc4&jmqcD4mlVHQSRyYBeYtiM!Dd9Rq5umJMdjQ4Pdba&JSkVlL5nThwLN>%NlS^u*c%Xa
l:mV$Q Y=EK6iak*lE\/<kZFTHIY$$FdLIh1BiMY8iuNpNI\lB<G%Ppp&?HLFliX=1c@b:&yDKAAPLaFSkD+TTl
+E8@5i lCPZIXG^6P&$:hFq+MIGXwkHWmRIEk<RGu/wHluP1Gb@Bq=+eA=FG*pWXNkqKGK<^^R8&N+upA8Wcyiw
^Lqejj M#ITwpZ^mMjIlA9EWmGRHkD6dRS5^ytuZT4Ym8<wQ^ZSykhc<wy$hkYyTcF#@GMQPP=^B\kCPGAFtnVW
E1nqIi <\eu\>%uIWITAIF^d#nJEkmbNk^*TZL&wW$1p*bKHa&&=SEyiTD*i<IdS>1wJCwNuT!8ljPJqT&lQeWb
J5/V%G Cl/i=KaPmSRWI1kZbV9Ep@LYEi$uMi!%9PwWkQetC/*^mib:B&jb<WtI<Wk&ityT6*wp!&*J>Pa:6E/V
u$$kya M+l$wiypJlyN6Pb=$?cZYjPk*Z!X>G&*SWq5kQVLhFEHQJ/dbX1h+#RF!e&R5XtS:mVdIcJDTlVpZhFD
nlP$h\ ATkZaPaih%GebJ%A6pC!BAu8R98Rj*cA%pqE4EQnaDQjTaJA55=S*5I8iuMwZYVRa=8KVP1D#F6W@mlZ
N^5ZME S1nm*pIHwh9Mii<t^h5q?A5<*6>C<JFALNA#hIYqCkh9bFLd>4k>9NA?u8EEFcL8MZ@*JtHtE:ARAHTK
d4jMjR McjqBTeeP65mlkT5<<&1ek9aFd#Huw&RLC+GRcE:YY+\9&C=Rj:Ve9MZK?w*k\wcSj!yQaXXp\QP&V5E
8%w8Fn b8A+RW6#WQkCLjyMF#&qC$d9!cEPLFaDVD5V?hm$!YwqAda+RVb/SqFb/CAVwd8pmCb&SA&iw#%jLMDW
PEXB9I T<X^<A@YS^$W8$<LE=yq+J<I<CH!5<TLipJ:HcS=p:W%pKG$N9J=lqW=F=NB*6kcK#l*ajtpn@#q+TWM
J?P&yY \kI!liKkiIb^tKji\XT^MuKI=E*:!jQ4TI5i/n+M5iIRK8R>&CVIibSDi:tV!B@ykW<H?@MIGNdckp=G
^%etmH X=!eP8i8w>LBGnAjAdnC$qnu?WwMX51SnI=KAPYjDb>^J=+&Ct<NBFK>EJ*J>ahq!mni8R#t&uS5NPTd
C9Lp<q VBAI$&McQjL6p+LDB=WjGb++ZTQwWe6nZGaT>+mB6=5?K*BkCbETR?&A^BZ&plZBw8EQcIGGCLJwc4$a
+b9l+B K!a=Bp/SV+1teMC8FFB&6L@>#V^ND9J*MZMLkhyBFemc&qAFe:j\pK?YNI&9j@Y&#bWK&9=?IhD6N6SG
:QeGZV R=H+L+&<*X=@t8G&d&&dJbFj4b:d>4e9X489#&tFl?malY#dZ:ij%DHdiyL\u:6@Md=6*>da99*XW1ql
:^@q%h l9qtpN6?>K>&W@#*5^hj!AV@^!c+jSY=hiEQw?AY:X8W?G%Jt/jjjmkP@Y*iR6$y&P$LWpHZ#TjMLeVV
itiqe4 ^iu9JSG?L?p@Fhw1Vk*1:8RV9H%1R9:#XNh<8*i+P+Z/lQ\>N?LP5!:BY:<MQF&D@#Rhw@=kAiaQNtL@
kXdF@J aAL8D>5w<m6#pX>:HBL:S/MkCX>6y!nEH#ee94A*hH58B@GjiS$W?89E#q@ubj=m\j/#i/1bcinyEdBj
mWS4E9 8?m*Hp\pw9:YZWY&@pq6JXPpmCnbumlndtVkLTIC$>EZ6ZSS5pXR4eT6SET<@TSp:E#*iSBe#GW>=HFI
%GG:9: IqwC/!Xl1cVt/GpQB1E%yZXD=au&Cwa1wY:?ykSj4KM#\X>MZp%DF/QlSjBS%=EkBZpFB&8Lt/8cKPqI
IZ\qC8 \jb1T*9A@ZX6VW#eTIFIyB\ayC%4w?6LhmVyE+$X4C$Rquka#MlPM\ALw@45FhQePmkdW9$p>4q/YJy/
A=6Ry8 +6*FFS#^:lKlYFMQT+w5ii8\#\pM<ndYFQQ&p*cu+9!p>+61B^P5=EV?%REM?9ia@!?L@!?L@>@N+1n1
9am5Pl Dt<SFQLZheYYS91446BZNEdA>EKp1RctMmFTB5+IeS?M4hb?E:T%A54G\<AMK!1q8#hW$5lM&pAJ9pYB
lVS+i8 4F?AQhyG&yP!q!lF^SyamIJB6p++L^WdHXKIy\WBy8bN5uDWEyMSp>LSXFHZ6%QZXNA^q#I%wPn+B\Yl
+KZ1l* @Q$CdR\CdAQ&\w%lY%%i!<Wl^DDRBR!!X:WqTbpHtmqaK?u+/kiImARFKW8+&i^HI>\ChbV&&<14tuu=
^ymWk/ pC$qkm^h>64/p!\h>jj=T/wH&$1VnJSWeSm9LZWnE/!Q&Y>p=Kawd&plawDbH?LwaPEQq:I*D\\XW@h$
+ct?Lh eWWEKqwbBeBqSKZpub$6jiS$At*pbDWMHDT<9V\>kpSWqeEkX&q#G>%>yw+EA*Z9jRR*WaytCEbB$XNN
pPp86N $64hjy?j4/8/44!9VIAl^W%DYeVYAaaqYNmG1whK!9tJGjnw1SCC>MGkjc4wAAp@dY!kG>XHYhFRJ$DF
T$hqHF ^MbiLMnV!6:PR$*K*\+F^^uk*X^h^R&DDYHT8u9lKpawp1RWZI4pLm8q:+YXAaQMLiYDTYSyPa5R8JGi
hZ\klF j1C%AeFATXKHLP/tBnNZh@E!qhZ\<yN&eeSSVIl/THEQhcVqZlF4tI?bp\>?4=tK44RpGIVR%@LVFA5Y
8mq>85 $$Tk%aqT5tIaw4YeEkd68Sh4nciwm8JFkpPIH8Ltcp+wF+!GnLKqBp:TS<>j%5uV$qyH&6bD!kRM5nBH
jiJwaa 19w:8@5y:ZMutjpTQT#F#Aq&n5bYbD5N<SAKGmpcE846/aHSk%M^KJVWQtqqN^Nbj=KS1=P&1kabG&Lu
QEE%^4 DAab8^9I88E5nDAia8bEQ#E1&Z?@9R<Cy/jpHBKI^eyc1NkEiQ1nKBwKAbyGXLMRJSN*S$X@CY$>A\ej
9<1IXI G=Km54p5GGVm+laT/GMj+PwRCLP&>N14I1=k11aWcmc91IAl1!JqFRNMMhK1h95hdPB?ctRuWb!^CqbK
cXF>wR *XHXDtpWlNqLq6WCk?TD#Qh1!Ra+ii/FES&<9YXeA6*$641T6d!Kk^@CEa>W6!hkSVVq%TZ$FVXCVEMM
$@&HLw JdTWZQbcIS$DHR%<JdC!Nl=kpKT5qLmM4y*P%nAK4?=DWnBTIK6kqjiHPCD*a!ShCh=GD4wEnJ&:lnbG
+uiB/l j:?*p#FK&%APn%V\pqh&<LGYF9WQ5kTDnD^SIWnhAEN^J\$nmwMGT5yeQ$Sd!TaIy/!FFyjbc/%91Y*w
*FAtb? Gl\54iMww/ik1P<RIP5y:^JK$k>WM>MuG1qLIMEkNX>*tJtctcm&8\aKGWS\%pS/!&8=tCL*+\JCSCnK
-Amb:F 00073d6c62000110333 Page 208 of binaries1.zip
c>Te*h p541elESEV94B>S@+Xu!dW#!H<<TNPHuumWK/q6Z$jl9k=&@Dtm?<^n=P1L/#=\<HwHccWwiljpyEwjj
EKM/uc $SpDlj$=E45#E9h#=M+PICn<V=FaAt=HJPGuTQRQpMTjIqFE#I=8QImjI#E:P6ckpV>HwuipFw*/PSKB
KC$G!F *lH=e^qCEuiWIjVQbRm=5\!lj!=DQ@IqRj>NmQT?jE%>hbhSp@4!1cZ>4c@<Djd*V!pw?y8QF@qd$X9>
Tdi1#h hI5P+6dH*%c9\t=h^BE\Z*1j=bb5jj*wX#CGayHj=$*+*kKA^YNRQ#WBeCSFnyBdp*Ee4JwMGlmPIHql
@m5#h? MD$hW%:$H5:abKA/Vj%pkL^Ae1GYlk?ZqCTHeQK/PmiXyCCcQc5huBibbJ*FEp@HiWd&J4%eEyN#S5IE
jdR15/ &S>!Rq5>Jt1BRwAIX+kG1yWqICECV?hm6DmweEYK6wbcjWE#TnDbS<PywPm&B+SNS=VGw!6I1yqNl%ip
R^HB%B aIB5ZJL59Yl1%LS$wMke@E4Eq*#ZYiCiLnbRdYDSH#uuhXWD#NWiK<AYXNT@tJAyNTyW%bHei:qQjm\J
9!1+Yd jRX5eTjb6hh1?c:h1%k*A?InqLYRb=/b>4^H5I6ki!Qh$cykuN&!#eqAjeH:HmG&Kkqp*=J:^9\P8XWM
jN?#>> @hXPelhW+8CiSde&4#/T+dlVVttq9Au8G@S4ibtc!6Rm#c!HILZE*iIIEm^$lnH^^nPQWIW9>AHIWwkV
:ZduPS qRW#9:X4w9k4YX&!qcTpMc4qm55^VnS6BSS+1cScRaC\YpXj&Ltp^LiRkmRc@ZLSCltjmEwGjXn8tMwk
<4<>5A S#Yp4qP/qANXt%TQ9%!a:u+=j6k4tX<BlGtCAA*tQ5:DB?!Y1$HLwkX>8N4=AQ/c+pMeQR&%ZQQ!eVVX
:L^*e< /SidDCbi9:q5%nX%@+4MB>1/yCV>RyXcPycB8yaX>TtJi8tCnwE?4uSVuY1/R>GQ11IMdim$tWa<EpHy
Eq5+*c IR:MPy^n$beac4kt%lk8!n/*ntN=EQC/B5^SWCFNb%lbLC6!wuI>DyI$?Zne&$:L8eJ4=TK:c8ZdK1jK
lW6VC/ !*Hqh&%pdKipKuCHcE5dc?e/YmbjL^CcbC8%SmCEMX$!6JYq5y?%8y41ZAtY:T5a8l5KaawGSbu:<Bh!
Xc81*k D5n6d6&kZaa+JZ%M9!chq%VW1wLecB9G>/HPqAJBpcu+qJeSFauHMa&>L^Wtp4AJYB@u1R:y9PZ&6Hkd
%4Mw+p JqPwjy?1@pY*6=hhH>heqAm/^^4?pZT=5e4nMZeZ5jn>W$WF?^jPW$qFJSui8DXTcY4?XD&mbdt5bN$:
5>GGjS ltulbk6=:lulIbK&wM$+Q+5>Gj/Bk*^#ASRn$XIFib@e*/m+YEY1u#yJD<HpCD9R^TQ$u\E6pQXPql$h
/Mj1#< 8k?PMjDMiI%T\dyt8l+$JMi&c%ePc\4J$BqhCw&9FXaK9<yVQ+aD1:DlZi!<=dKjlXV1HI!aBdqqQAB*
=9uRN9 G4%R9MamF:jj=WBET@6WIcu!PkMj*eWki<!na^N9ephGH:@!/4Tdi/699Z^Stm:$$yF>!Y>PZyEKuZE9
bnk1J6 >q@lJ?PI\$Ej4=$H#b54tQ1yY51d::diD%aaZdy&5>j!wh&nk<Dbt\lL6nnVTVldYWWNSNN\j>JwKEdL
JSBT?% By!6%eXmmnLS:NQ<wMKXAp4J>FiS8V&mAZ#4eM:=MN1@1Sh6+YP%L%ueWej?p@^eelpI9cI\M84Fp$Da
Fkl?CP hB4*m8u*EcD#PMLGt$uYEE??IhLX#*^?tpQPnW#RaEw&+\w^5%<N9*VndX84e:WX^yTGje?qDi6W!u9E
b$Pl\t j1A\I/DQ&\yCTG$4=JJpK6@uwKh69Q?ebJ:/^h%b%RR6H@DNTuQZFPHKKmCdI/6wL+B!l^/<%/VW9RbQ
>Eu&D8 9WbB4e8Tyn9%e$45wVc9bC?8q>=/b\ET=+AnYZ=j8<FWD6d@$CXd?@RM4!+t*hGXLiJCmy>19c&hB6jq
S+IpFy a>Y9n8a&ZBh<cN?h=^?CA^:$XVkdWy6Hjn^=cVH%+&PDJ/p4RI@?BNmXyEwLaE?C>Lu^=6ey*Pi5ly:/
eQK6kG Kq>=IJ5>QRVWI1*#MN>uuJHPMc+q<q&FRB:#WDkqZZ*n%NI>QLqmmAbyV<X+!Z=L:Xy:n8pFJ11RQZZl
KhpZc1 :YR^4dXW&Wl9ZTpuZ$NM>m4Qi^M>TmRGCLtiY>MY+GHR:t5TVEQKiYu8pb&AqwE+8FIPdFw@%aWDE>8%
w5P95i ie$Y@XJF18Eyy!Sp^#YQe@u11anM4qXEX%k5K5PMc@q9F=H5cGW$CEA*mpj8%EK*ty:d1bG=ql:8wSD>
meV4\F h#Z+^&V^QH=PK?>4mD^Qqj!JEBWZ%uKqmLK*%V#ntp:RKtCYbwwXda!^nd4IAqPb/a&/lwG%RaklT&VJ
eumI1A helXRQjR4DH<buI%I?tlbiFlM!1DLEFHn=GccqEZG+hT%M/16*PGGcFH%$h6*#wFhHLiWd$IyHSVeq?N
&JY9I% WyIPTS=$JPPVJ#5L*BJZ#8*TZF@lqp?CKWp6QDiN:6P6hPpG46q@dP=eyk\F6TQEe<XEq5+J4&XMTl?Z
hLEFq@ tNS/F^A8&<hibL=tZIi/\PaDY9Natdmai=8Le9I*G:V+Wc5aT8/n$a@lDL^/u?Fe=d=1y?WW+pn%8dhL
4lk\nk uaa/k#8$DlMhDaql/S?MXc>aQueK4:!<kQ/>Kt:me4!!?+H?YX@t6Qy/Kan=?j=%Dj?F?GeuKSXybRk6
=RV?=R ZKq/8$9S>dGpn\Qyp=PDF\^Ve@^it>*kX?W+h#lXPGXc%SWWj&WlXmqdFBR!lQXp/%$/R\uW!:tJQmXk
?8q&wT EQ^Y8EGXKVQhhnDt5CBXyF$*t&@mpdRA1^Mu!JiS\Wq#KPn!+bqQ>8BulcJ=HEE&Rddp5a441+?he#&H
@^^@eI H^j&SlcNq4IaqA*b^W^$9+9pe::8j@JYa\YL1PG8*&QNubwJ^==%CVt>a4h>9qlMKj*A$wm/QG8bEm@D
^C=RQ4 t%*Z&HFj=bJm@HElTPhV?B1L\i6dCni:&!6iVjEQJY1n1#lcujJmHW/<4qi+iS4&!KHNJqTpRYyT\pm9
Y=<u/Q V=15whGmiayXRQ>t<lW??W&Hq??C4>$!L4Bw<&NNQi9by:5%JP!d^lyuEe@!+JuC@b#Cu+eh4W:<>DK<
Lm>LP\ 9YlBYLXKaD=5&H:la+:!R:^T><Z8/aZL5*/9Vn^&!^P/19W!W/HTFRm>HjQRjntJP#j/yWB\9+e^j&lb
@iS66q ^EH%A?GC+ttI1M!MKaNV9H&yC>hQlHL=%+9bFeP#tNy4h=&Y9<y^V%<yVwc>htIJ&NLQAuB!H>wqLXG6
YZRq>u jVc@@jNXLit4jWYFn$BypRE9ZlyIZAZQEDZq\C@cim<&#QKcnGy/VYd*Z+lJPeH/I5FZM8NC==&ZTZii
C4u\hu qaXdiNaiBE^N6NJb4?9N@J:#8=ly46D%K4hh*SLmy#u>^SJpnM^GhZY9#P5Hn4$PaS+8F&w>4d?QdnVM
w%?qAL t&HWRHGNhWmn/*G6:5ZMuLR:$taweGTjX5=qC/EDJ@dnZnK8QDkc@Qq\/iWde/w<eiGKl9IutC/:QStT
@V<eF/ VkAp8tNPJTl1tG^<W8mV4ti:iZ#AlR#D5!@euK58:%&Zwa<+6SmGkKZRFc*G:1>*eA<=Y>Vu1d:J\ACZ
Yl9cEh $k8Z4@b\$Z/LZ%YqmPb4IHnFnMLjXT!e8buEdJV\1V:<a=!ZQt88qMpEQtu55u8pqL8\W611>IY*:JKC
uk6wcF H@dLb4Ew5yY@>it%^8n^d5L/:PjKe&deF\&T\%%wX##h*:wTnp1SnYP4YC55kPIQHV4KP!K>Hy+\#Fqm
Yq%VbD puXJ%%9IQ?G=&NlyVtTMqa/$bVFwapawJq$+W!i:1pmcIZc9KhP>dhZS6!/#wB9yRu8Tt:w1bb/5!1!u
bl<q&P KpWtNJWi9uVlFGBkN%HK%nn>P5+WpL/i=@S+M:h/h*y>t*hu5<dnqyuW8cAVmkF%l$5a:&nC%8@PM?X/
\%DHQR Lelh1HYaH>kWjX9V1%yluBVkWwT9nGaABkCLIT?n!!qJu>ddi9c?KFEa#yX=LN#mWubLXul9SqFL8c$1
$SJhR$ :CPdZnGk=*JbhI>$#BXA=$$GCii\ajA8Phuja/dqmwdpaHipuCeWP6btm?cAYq:T/hwK6PZAnn9\#9Xn
8Dd8=X y4q:c>\SGhXGF=8PGc@/5h8#bR#aynKy$+9#c<wJQP<b1u=h$#E#+q\m5&++WL*k5SlANE^>Gj$:\+Zu
J49Zi\ pl4Y6pc$\#:*h?qD?9e49l$kDW5QGe+XT+EB*j%NJKtbX#Z:JXG?Ekt1mwbuyc4%d\+<lc@8Zl5!9?QL
ieFE?6 EXLRi&yaphW@5+yn=y4lNYuR&IHMnyGkEXVD$e?56meN\?/YNV%#Ja<E6jdTV9Z1WD^Y8/aG*TpTEYj4
9AkSwG C6KanD%Y>+tV1:Q$ki*FEnhZQEJwE&:E=mue:EtnVhcqK=E&wk%Z@*nE9jqWRkml&%mylk$F&9Suipe:
etCk>= q!\>eFT@$X%YRRlVN*RM9D#:dAFSSa6q$JBwNGRAbHA^eQW6uKKLZTWwCGb$ctcL/jbq%T?XXC946tZD
=4KbT% $q@Wun8l&+cYw&*N1GcJNBYAZTW\%T1M1#IAR9Tmy$KidDLMe+^IHWC\NPk@yk%9ZLS9%B^B/&icQeNq
8iNAFR 4GBe*8<9eL#pA41@Np%Nc=dW!G599y\!wm^%EayM%<YwN<pY6d\CptR&8C#B/*IhC<BTd^mHh9GTyt\>
5*cH+1 de?1p=cw^KKY@DX#:X=ApEKQeP1VpXPAbVcGeLhN9&SS#Z!ZId$Zi#SbYM$X!B/L$@LGTR%#/#Z:!<je
\+8t*F A6LLLTQ%XwF#Bae$^nR&I>DL9ja>pVI#A>IVYWRN$mqMlXHcyuRea4Fa<+l*i1V=\+TWHASDwLHY5HRZ
ENM9w< bwlTZj<mTu%RiPbbkXJSL1G:T<4j@FCC+:9HW=ycc8L5y#uW4#6F%#P>EN1dpuT&yQ18ceuD8HGqy?aa
N88EjV #aGQ4+TIPuj%jCPHapwtT#TB^?iWW6=baQtuq*LjBCCT@EHy*iHA/PTyGqt=t4unWA<CyHd/hknmYcy*
dIV*ph 1QHL+4C1F?d=cBJST>W&ql^^KhM/IP@pmYDKC@Q%P9/:<=?td4MX?Rkm&X&jh@JLe:m@1MMy=I\chd!X
ltppma wVM?H4j/Ym\@4X<+IS:%KDn:Hc!eYVNC65bd==cqZKPyppI<iDM?8PM/!FhMBnBIdTN*#G5=Bhnw9ic/
F?R?Hi p<b1#<ClY6KnuMcC88SVbiLKhtu8bieat#iZ\^%nqT&Iq9JcS:p1AnP=H&Cd#h9W%&/c@KtV<#aXI$Fn
6#S\aA QKP8#hXapE?FSNEG=LBad5qTLq8Fw=TL8eI6Cc$TS/B/TEiJX&Na9uw*%\q&MIeP4RuQeuic8W>Rp*=9
FEqyuW 4+9&=t91c5CmwZi=6R#>E^9&@Bim$M@i$89DEt?H%6?595M&bn6YbZ>$ie5Y+>/h^5\tj\ZIp/*R?eV@
lC>1i^ F86#+$?SP4^iq1<QBQNt5Bjyi#HA@W%\Yc$nX\^ME:Lw8X9#W</6<&+ELD<IN6>w/u6DYGuN>:/#\W4n
?AW8EG KT$ayMuu+<P4ukPJCaRcQcqkm/*?6FB\AqMhc!#YmZBP9=pw!jTCi/+kqTuAjqPLm?u!edA*uWu5m+\#
TmCnP< Ly4EmQFYIJmMhZqnuIQCp8@aui^SBYJpDEQ*#@T^ZyS%h:&QKuPp<nIjZk#CtB4+n/#ht/6PYtFdmK&Y
kH?GCP K^tL4^?:DM^:jueyApZD#HE1atHPllqp=F!ipFIVVT>yMy\*bNZJ#G\ZIYiEbu8pZuVAy^\X/L<@XPKm
hZe8K8 :^MPcSVycMq1^%#!C>*!F*WSd%<dI#ZZ&Wn*k@Cc//uNBa#5RTi%E1^AZXjaVPn5Aw*jQ?BVCu!ipqVi
e>q?i^ uCtXm6E4pkbMiFpS*wqGhPl^B1iS*6>?i!A6>?PhlbQGV^M5^cq%!i8Al?9?y$>IZLN&:l6naZM9iB+I
-AD/BW 000e462151800110333 Page 209 of binaries1.zip
Qn:l&N nEi8MeFF=:#8*JFuh*@Ij611X@WVi@Ih*p9Cy?ljI/%hmLJh#Y>h$qL<t&iY1pNiPW?>WWk^w*9:^5ek
byQ??V J?%^Ru1<\*^!Z\!9L:BHPjJy$AFcyeWT9@:e6*j6$uDRn=6<hD$qdQC!DWc&X@X4d>lb%?1TZ+h/9iJn
\>mwba #Lpct8Q/I5EAmXbwYcNPP!Ii+by=q$cKjphAQ>NZQmYn#mRDdYlLQ81YA=i8K?4Pup6:iW=CkTe>i=?8
@4^iG! 91JYPQCPjw%b4B!nHYN^5n/H/QtBDG=Z\GjAPC*/MQ^ta8HAhaZne^wqW%YWIyqq?pu@BVt++I5Dn%u>
RK/kJ! d^X:XlWNdCTXSwNHmkE6SGc@JH&G9pi%KYj4A<@idFeL9RP9F5V*4YIDQ!pX*aDG<D?$QT/PdHmhtSNM
R64wKT 6^!#6Pd^Q5*$=P5A:=a?VEkP<t/1lyXwk@=R#!tl4W>>p*MFMj6njRJR4DayMYB^^V=mGDP#nbh?iI=K
>1de<q y!K?=cS>X:X>^q^e^6Bu>h@=$@alM/BTHM+i:>jRd*K99=>y1c+R$!1ZLib$eMc$6\VVhneYCa1FCd#h
&Qtu*R t#BVum1DPW=ila*GBwmYMb<6TwJp*H::P^*eJIIiHVISWX@MYA14DChL5#?+RL!VJ<$Dk9a?P^ke%Qik
@Pw*Ft LI<juF:M\NVJ*1J%XV5APFiQ+Bai$umdEb/B^b\Hlqpip\9^4Z9S6Ik=IHi?CTG$K<baTk6j^66mu66t
kNHd8T *p$8\5nFS$jjKT19Vk^RD4TYb@ZP>!i!Em>HY4hq<Q8kJ\NiTc^:Nwi@t44e4XE9\:8Bb9h=Qlu^&YVT
\@kT=t >G4w!VS?Gj:eY9Zjp<9LR=Q8l5::MAk4Q=%^n<l?ttKm*Ddb$Z59IH!5PPkti:8@b?wb6iQYc\XA*=Vu
Y6p!@$ =&L19Ip/:=W@Tnl+%GVZZiS:KlZ86ejHPhyj8#R%9Kh8Wl=^L*^9/nNX!/iBkKpNQyTZh*5IX&q8W=P^
qBHSqN 4JSd?P>B$@6<:c%CI6dj%jt>tqaSKn@<euQ#XX95&\Nl#w9NZ9ceIi?Ye%?St%!Z1p<#:\G?/Da\cB<?
i6hT&H HlmjtDDRy@!E%$ib@cV@/WDlXJP=9wnuCkG=u+=1a/K#$PKJ?P8Gqdj%Y?+&/R&:YDyRA#BG41j56RjM
V$M*CM $tlP9&EYPBLGc51#XGqaQt6TEN>ln:t=Q/GZJcmV#qynL8W!daG^#%Fd58=RFWMC4nL$TAK11nhnQ1\@
uPEM/A Pc\%$thP??1>Y<emZK=iH^P=a:J9<5HXP/+F8M8Hb!?8*APRLS9&lkFiVD?IW44@5bQylu5qa:&p/WPG
:@aNnM #TTliDPbT&ihC/ej$n&e4?9TiDeFc!Qb@Ka?*Kw?i9hB@W6*itX5m&EIYXj=E/c<^ayE@@D8TbHj1BDS
mD<PL4 BZhaphSnik?EP8/V1=ma5*/nG:t^GFCXWNikaip\tmE++m+/IB^dj^ed6CR>F9>tj>Ldw4=!=?8ahe!%
+qKJC5 t<P!yCAu&pKX/HYF9yDTe=YZa1cqcX?6PM\Bn:aB9WmG594K+IXtF@QC+%A%&Q8mPHP+c8?%RiQTXZ&t
!YwX?C aV5Tu>1V=FZ>nkK+#/bM5Qul@w%i8n!*V>Z:4#ew:L:<Gpkyhm/\qNa5%XjV=8>\JMlj/:8X+Z&qw!@b
HwW#?Q 88J!%\$cccu\c&$L4Ky=eLQya*L=^m86iZRN=Du%:pipA<F6Hm?Z:dLY+iPdYL>lBN$RD6m5*PucjC#P
R=6Z:/ !&VmPBmmXScpJ4MwYeJ^+6\5/F*d>dJ=@8K*VHVih\L*HP?<P9@T?lcnMQTl4am#II&&&46d^Qi1n<J:
w56FLN EdDIe4a=Jkd/JFDpBDTcXaSY=?MC:L1jID$6AMHB\^R=Rt/#S@C#Rh$JTB?!J#FJ1%mpaIRenE@TFpY1
^FKCt> NjYFyLLCaBubl@8=p:1:Gc%uyqB8KC*aPJ%lH6p9MVq?LyGn!WWFhbMBKIA=6%<tV*8JM\a#hqA%I\uM
XEaA&/ 1XbiFP<k#XZR5aHwwWhGuT4w=C^w>pH^y<S!\MWEH:A^kFlmSMwuKibaK>$:@b!WY+^<dN4#Tn=5LNH<
5yk1qe ?>bMRiFhRjA!X6euW1Z$y4tbAwa9yHky>XJy\tW&B%e@8qn%t*6$VLcu>@pm#1REidXY!ppP**wcI=I?
&/=e=8 R\=Ia6Wt=n$5K!$w9Jpe@CJ>!KSl!4ea4Xbtdub/cGlDMitGAq1m$CMPp6jpptb%p8ZR^X9EkjH/qeAn
\QGcWh 5KVDq5<wBSdLF*%BVdW$?kAjQ1ClKG5B1dC+wE8iTbh/GbV5RbcP/=%Vqt4&FJMDRD9k=VE:i48lmV@%
9p>iwQ p@1:Z^RPm9uD>WbBt\DFjHYD$pamwBnWL:yB@ZZNM8Jj?#dl61u^DAwP$jB\CwJ8*#B$?9yn&#MQ@Mh1
yQL99* !G*9InRc@TYl5AkwmwCH+lDa4WTAIuF+KJ1AkPKRTCmKmN!/lwPmpZ<<m>8/l$X5W:Z>H@#6bKj@KD\B
//PGYL m6/iw>6/jD5S6m1D*:1G&m4mY>FkNIH+Jj>6G4:S59*:G?luCj!F?K?kd\tD\WD^GQ!Z$4a4kWeR6<+^
Sp<NBl Z</^YB\Wn$NDCYnWXwH+LR1&T5YneF>8EnG+4S6dAMJ&Syk@@8IIWC^1m#NdHNnPEI>CRbHd!=T*YdGh
*@hN8T \N8HL:#b=6QZ9>8$db>@wSPL@pLThkpaQQGQ/%6paAtwL@\Fw>CaL^i&j^AI/C<*5Jl6E4dw^Y%qSMS8
4c:WkR TR<Gm6+tE:F%H+jhIuMLk<S>\aG@qjbZC9:VCN>+>aZ1d#?&H$Mm6/nc465YE:a1V!V<4i*?C9%YyT>b
wFD86X dEPJY@Z+R6IYpIDC@!EJ&+#+i=H@^H>lNkd@J&9?IHV:!yh&\H!>lN=?>M</dTWW+W<JRj?F5*n5j^L+
9bBS^l T/69N>APmdl>d$5K6y9k4&qdA4+q<QblY$!?TeA@$#bqBDV/8<!@CMKY6IC@NPwQBBYQJZ\Skt$B?G9c
n&IB*6 :unjEun:5N*\*\Vku?pLG:F@CMFj$^@ZpH>R+QA#=$c!p+>VmKij9^#F*>jJ:/9!$uRLhku!DNliPa>D
PApn=& Ed/d9eMk@:WmI9^4SjR6jY5h=LiP>cYq@mQi@+Wm\mBR@%FEY#yu8^%SKQ^@FNGZD9wQSaRm@6>WSF5E
6eB*YA d?5P\6eKdVjX>9q&&6cCZ%VlN+*%yb>>8:6>+a9edW?*d4MGl@>V>9/hJ91mkd=1wm@Z6+4<In6jGR#?
/$/K8Z K:i*&jTN$D@:!>c%:R#R@/nEH&48t!bCj8*FTMSjNNGj&uBHVaV+T6$ZLu#=>i81mQlH#$J@dhb@1aw\
ctw86j cMI91/J6Lt#%lL?1Ik!B<P>W$Si/@&#K9?1mLj1@JjC*!9\w@S>%$Vaj9#Z^n4wI@\jH@uu>4*$R@P$6
5q*pm\ >c&b@=u?%EZ@1Mc*c@>TF/u:?:n8yI1?>$@GwQ/%K94m<9^4D6>jCjq4iin@\weJm@/uD^MY>a5?VFnp
CL:cd= Dn=MtP?<TL//k@@Wl\tD@TpTS>l^I^wM:8hI*M=I@M?S1B$*><ERjw4EIua8p@lVJI1+w&<QF9FV=I@<
/?l/YP dLB@i!&T9\G@i5q5Kct6ES6&1&*@+!Z##i6t&$uti\eeLPy:J^uM66QYj?<p\<EcZ!\CtQSC<4Ei=!k1
Eh>SY? 9M\M!Ybm$\+Zac1H<tZ$BSRVB$lc5u4huVRJh*lhwut:/h6%8*#ka1Qc5GmQEn8XEpwek#=<l1^%\TIl
1SK#bm i#b>\A58M*+eFk&G8MPqINXNL>IL#twJVV!hCPw6cVEZX=PcN\&a<AZ^Jq>\ETuSLhj<nXZTlcd%W+#G
qw>$p9 Bhai&lmnBLJ94iqG$Z&BpZ:nalB4Vu9#YH6GcX+IL#1n*<Lp+8pG:M8C51tDI*bch:&:PE:RMcmu\JkC
lqaMb& =1CE%IY+CR>#VZ6m4HQ<tbmMZGa\A/q\qCt:VIGLQ=Z\WN+\e9?^8F6S%lWLd!6IDPTc8cuLl@edKP+c
F!hQu5 jCJ*&jBPLdC!wa?@in=9<V/tM:#uW$MKHiY?9P\/ydl6qRWEaX5P8w/+EbWq!hdkT^t/J:Ym=NZB\FHF
pWC=Gl NI/4#l5y14uIRb:1GERMRGyFD*NA>1a*>BAd/1FpbjuAM&HVCARVYb/B5+$5yE=DwpK1=&aw6WD9E>49
6@FR\t GilaA9kdA5$XlG1SANNhKJ<8&T16Rp%H@y41D:RCqYNVNRKc##ALA5B?u%CI>p4LBkM/%hyDCPlEi!+>
tBC+Su Z1S@8p9Fe!4=ymycYdG$MSlASqhTYA#9/Yw\Va/IPbFtJhpKDY\a+9Z6H#biMpI<IT1nZZ#18qiwy4dA
\=k*wH Re^Ea?QG&Jut<dEXpyA<mp1y$q=8Cmt>YZnC\PHYGNRPHIh>/XM/5bKmjcElhN=IdnJJ#9X#9LSDnKmw
bQZ*KL /hp:^L+:mpQ+4nVRqNL6hR@ueVWu4&H:l&Na?$ddyENhEFD\?^98M?SP<\!huDJ&=+:LYSLIl*tm*w^#
pdwHTN 9HI4lF6nD$11NET<nb\uDp!c?4hKY*i:VYX#MWp#/I&Fb/1CPAb*X:9I9lcW8#1XXJ#!pwK=9GADnIE*
/@JQ&a 49l?5NMa%Y>?&q+%cewqW/q<Y/u4Dh6BaLX9^EuVt?@Q4N$#41hN!/\P@1nc9@j>YKQ<M<He+pn:1q*G
aj?a<* D@Dbk9C&C*/u$#5Z:?VAC=tC=M!M&AJXE*CN!=iKlK4uV5L/4@e4Z^/EX*=YwH6?Kl*!1LtYwAcIH:CF
H\@C+a CJe\#be5K:cb%V?nMZ+9uSR&+iH?yDmh!T@>Ry1^D:?y\1Hh:=dStYpyD=@SB$*jQBZ#cXJi^6/Wdpk\
RauM8j J*TZFht&GuNy>Zula!@HZ8NcIBnjYSWui$:4#n+KNyRHiX:/99uCde\J5:lKqi6Yl5WLi?N5puL9Dyt%
AA65ZY Z%QS4cFPmhLBF!cqh@9+S@cnZ6Y/$XE>6hQe^PBne?<:k=>LPV%iW$qjV4Q\ll/4AE51nK9*1bFCI<9I
&=qpN% TtL#1p9bW45b/h>yXh+YXy?IY1Z+C?mjNV@n#8M%aW%1cm/JXcHl/!8!H/nb=Hu6iIRTIC5Via9@6J5Q
KY^RXX %h#V##yRKw#u6Z/$iVM<IqC=Ad1+c6YbD:L#j9yKLte//!#N95nqy44+X>eEdC9#uW\8mtkX$@GJ\4yh
8Li+wm QK>G!%<1anMR:D9$\mm<l@a?b*4TqZnym6*a+<6Cw/&=/c!$QPwuN?$6>KyVuXLlN@Nk4%*iBqqZZk#q
kiJAh\ 8WZN!ppP\bn/NNh*u>6$+McE8\dBIHDenWF/VmDDbhcP8dp#J=JiHhIDihAt5wbdTYXq\!Qpc+G%8%%S
uKytJl NXLiKl+G4yXbV6ciaJTqu+4Aij=He\?QXAu/G!/C:A&:umit%di%Z6KNN1Lbj#yaLkyB@IDK%:!hLd:d
VeS6DF 1?A1K6Gy1IScuh#j?9T=@D^NNuay9C+?b#tEw=8LC1ReRwBIQW8w\+Y5IpNqEdRk8N&G41+:i#:\aZ8F
!nXE9? 6ch#mTdE^EM@+cutyyt&?c%LTRL<k<L6:yYc=@n9JeX#MVhbmah!uMwe18Li8CA>TlC+MP?:q&q$u#tV
%Mt59/ ^MZ?^w=L9K=uktbVdmwW*RBddZI1d=1**WpcFB8a/\F1JV@wc9P!N/miQ<aR8w@R%JHCKuaTN^CF5>=j
tmBe/I DIP/kp5NcY$9wFI>XySPc1@D1^VG:66=JeDbd1%h9Ry$eyjyhDJkV<yS/ijtL:R:1dpb4!t=GZ=5&T^P
PJnA#1 lEj=Wt*i\!TZdD*4l5jMjJC8c6FLCeC+5\yDSM\uWC\<p1ZGt?j6y=dd6A^NeX%K9bXqS=+W^nw9c1F9
d+QK*W 9t>8:bNDGDD5Zm\:TNp$e%k*IX<t%q+/5YjB+Rk\e8FYnt/uqQn6t$uJFe=X:$Jlh&*6Vy\MbNQBSL!9
=G#Gq* HalM9Q$beAp%6K6E<NTS5R*TaNXh?CPlI?/l51@yAEG#T=*T/JiibVq9:X%ZTXm6Z8MI1DtN$dQZewi$
-Au=>6 000d6d4ddcb00110333 Page 210 of binaries1.zip
Qd\FwD lBW4Fjia4p@y%cB#eqS/FnJhckLXjK4+Ct:Hq5ZI:cF1&RdEYFD=C#P%YB9nj^6d5kLSXP\#5tBV=4H*
6BP!DA 1wmJX$$Z9!q?9R#9!J5nZ@%P@*i/p=XbKVt4cIt<V<:X+%y=B\%8Fb=E%ky9jE\a<!#4N\%4pDCSF#\:
k/\@i< uhJnihBE/u%@+hZjcM^AbbK5=F6t4T?HK*K8^uP:ia6Z=bNa=bZ&NNH5u<>ZmDLd4F9Gl8WZ9Fe4d\nM
/cWiCX pK<1TZYj^QRI>nFqLD6\tc=ttipHBqZWGF>MQ9%bV*e@aYdmcp&K=dZDFn&%jB\#AtH/:%H?\Sbm558i
*KXXb? $ahhLCSGS/SmTM$L*tb:?dKeJZ>L=6GZu=w&8WYqXuh$eBI4%A*XRLtH1=L^JYj8G8qQQ:$jNtTh4HP>
L@Fm^Z Pl:bQ8Ln8n+^Du#@VMVkLd=ubhTT4V$8Y+5a#LP?//ZW<19+Dpe%&N&?8iTVqmTH++W*B$:=N$wSQ6=E
T/HlI< 9>:5R&bhKbY*$lH\qK?FQV<+:T^%$bH$Y8!i!&Pcm6DNw\HJ:+L>E&X?+%/^&T?<aN6><1*PBRGql#hZ
!N!MC% MM<u$1Hn@9EYW&Lt?i&EE$b#Y8JJ6QpaDS@je&WTEbh1%kN5Nm4>:a68b5+9C^:J*t5:h4jb/6Fu91V<
CChJC/ iE&WFj@EM+6RuKq5Tql4aaTG1ww:^DiKF!*h&Gy%?yDY+Re6Ey?wbVb^CWC^:4tIe>bY4*1LJby1eSDh
:k!TKy ZNM#^q%6BVWNjuqt:<ZQTR>ebB#NRXGtMNaZ?JWlER<\V*hX#BMB+!qbDhycWaWeMG4#$<\L#16DhJiX
TeWa6D dkdEQuF?4/M/Z@NlIYj&k=@I5ewZWbJy9eXF:%N^4F$L\\C=Gul6HIc6LBpI+6iNnhXPnn!T?DEK*D4N
W=L:6w ND%TjcdQ@/&X8?b^KyqXX@EwwIPN>bN>PeiFYpNY\\uLPPGpJK>cBXpy#%yGi9YSXeldH<8+&NkS/5#<
\4CZ#M $+ni@lt*i6VuH8h^4VcE9?9^WpHVJ!CXIckddEkZNtSp6IitalG>Iu>:WXljIh^L#nC1dcp1#k$$!GHw
!e9iq4 i8b&V^Hdmi6!bRB4?uJdnt+RM=NeSeiH/IW+c9yAS:$idAyEQee$8CG9Q@TG6wi$Z+bhIqXc=nDI9R^F
NPPkME LeDRZkhylnHQXE9JHJb^95pPc$KLTn!Ab^/p^cYWluJ*VNF4<q?yj<Mb!CFF9RA=MeipHb>TEk5KqPI^
hy^5<= ZlyQ%peMRh<Am/Sp*88N4F$An*pN455Xqa@NG*>Y9<ZFum:HNC%dNKZ1$TF>AmCV:5wAHnMnj#^@EXn%
!498>C wpDYiXpQq5yM#SK1T=BJ4CdSX59RZthlLPT5ZBE\PMIP:?VW9Lw:GmMXGC*NtX$NT&e8KIDHWKWATY<L
Pk%<Xa ZPYq*>huyQF=Q6pcnLHN#i?B*iAQYDcJQkqq/tCG=nPn?PYSQV&Scd!%1/jeA=A#FY\Lyl#hdA\eH#HR
BcBjj? e!D%?k\8%RieeHuwYhEFPe+pP!:cNP:wPXDjQkp9c/CLEb!VIDeKpR%aqHJi:m<+>+k?e$p>TVaw6VT/
yZd9^+ =%qHn%VqT*HcNC+/MipZk>KBk6KAe*JLNNJBpW!WTHkmJ^^RIVVZIl6pJiq%a+@4W?uM%k\8kF!Dw>\F
:hk^/l 461mem&8KItLytIqaVJ5kmwJ#e<=Qn&ADa5:#>*wNM/k9e8=jq?tT%btywJjqEp1<A\1/L$WNaM4a\#Z
T?%RTE MT^=5%Ge>4y<\+I#%%qW:BQS=AHt5W<!M!hpa\#jZqVAbQVyTe1kCp=\ctH=ZTSlHR5PnbGwkCjT\CLt
JFhmFW MTbu#pcSyh<EMqJ\XDI#6!pudR&8#>4MVAShDI$EuFJ11<CaX58>bKMa:$c89=etL<LZynF6F#k/>k1P
LlbmS8 YRGBbjAFIKb#WS:FDFejbajNkaIjwqnu?a68:G=#q\&Mqu*lRK4n&a9pFFn1pYGhl$b/!>PYkEnubYk^
S\hA?l $9$jbRPQ\q<?=5*Mc<%caT8/@wciQmuIZy/>W14@NT4ERl%n16lRLNl@m^TalIm?CiYtHwLqZ^tX+p@n
=pSST# $jZw16:a1@\$N:#88hmEyyiLpdl#nZmbp@m<pinGAc:wt\nNSit^DutpmL/Ln&#REaGRT*Bat8G#<d%t
l^e<=6 WcyhV\\<Mjl=H@lMHZj$VWMwthtXBy*\^Kn^!l/t%WD^?+a#MR1dYt1$>*W^q5e\t$Pa/6LaLIqELN4a
DmA6d9 YlaPaEI%!#Y6!\X9bqE?MhC8KG>>CA!91hGtmR&yCR#GES1VF4kMkXtiuKd9JLPEMNuK/lBZNhylkeEW
HHKeqE Lp+&yp8!N4SFJ6HDey4!#Bu&Jlun?y%GXt*?Mt=?eleJZnqH8Gh5LVeSJnqaY>RceHVe%4uGlPN*P>NV
GqnA8H Xy6QhtF:VC:%e:>1p$4wpeItJG8?qR*/LI:cb*j:4q$kP:>9CtiDFKHB#JGBW+iPYRu#SFy@u&ZGKV*h
#pEKPW ?DuAihKEV#KGSqGD&dL1mDwpScjNqBSmP+Sejb^B6QQ<kN#$%$STMSNlN\JyNPqQcLy#81LMT#j*<t>c
AVGQ:$ 8yud/5F!bWW%ZPA*FhBQhGEuuWPpZGPQtQM/TjWj&iN>e8?tQRnD1D51+kG@/eHXPwS?w**J6T/dimQd
wAKnT^ /\Gc4S6!AENjkd16+>D>eeq$<uHk?^iW5>DLk>BmR$tGXPqAX6tZ4tnanX$V=+!DT/T=/tW&MLq*qk!+
ub95>% \$clyn^**5pNm$Y$tjydCcLR<e!wD=RZA$!WDhpZaG9%SJMaYuqaJ=EP4Y:=#qkjdX^5=X>$\+S!H5L:
Th?e+j aQj^^6DdJV$uJYVuMw>lYRLMnwuS:Z:dNQct<dL5G*j+@l4S*M<W#ujl#5eX5HF<GpcBGdQan5LA+?t!
*d!Ed& e^Xl8T5W^wa#1JYIN>=8uEe#?P4&lMlL9^:D+HehuK5L+$5S4Bt*ye?WQiDXj?XEaN8yw$mFA^qD=+98
bbIVXH H/1mS9LRw*nj?VaiPHDlbRVXXPL&J!dL?^/^d&W&d8q\$Wyub<6Wt^=6<ne%=ZVM&cM?pXB1l4WIGbcl
tPqHGd uVh+iRMib15VVpSlD&l#=qXh#CNSd1El\/a9Xn8!u:un4YJw/%ElL<n1%=p=#$mF4bYTat\Il5t\BFVI
c^*q^! MQp&/aTMqd9$eGLIw6#hwNy\L*qM1iDa$:%<ISYJ8h&Akwm:lSGSbkF<EqLWKkW$<dC%nt@##eAuG\>k
/ip%GF NcGhpl\V$!cy5RhyV$LnK>K5Sd^/u+qYwylGb<P!t/Z=X/XPej5>jT@:I9Sa+CAm<aNN=d+MhJR@5q#/
VHP8hE :VA5DCkhjaMTjXIpY\$^mPY>caE$QdpHX5$$eWBdy<cYAS6McC/ai!m:\YV4ZI/=i<NL:<NiQptFW^c?
BZkQEm e#h*hX^upp!ZK%w=KwA&!H8BD&y=AJ5@?Sy*CpQE+#W#BIJDw>NPR:Q!wGj1m9BPAlT>i%W?pV:\q%F8
l@?dt$ nCP!y?!PmPy^HE\Vd5w?Ip6t64!QL+un!^Hlqq+=C45iTL^ehP?X+Fy\!F996MBBNCuRd<AVJpBEb<4y
GjnK<l 6P#mM:cGu/VS!B+Z6LJJ#mRYn6+1iQ5=11>t#<ZQIVNbWBi>@eT:bp\QhpQilbkY/W&bFE#a>#W9?kXn
C^t>a# D\jl6V9t5?PA+>G^ESMC!T*1DJB?@>D=wn6*C6:RD4%?X&^#njQ8B&4R^iAEG4tPn=ibPk9!>^RjEN1#
N6Knb! <WC\BZ5B&Swl8A6t$%cRH\aGHyYqD5SY>Q61=/QeCH1!n=pZ/#FV!+kV%T?$mn\Ty8M4JPVKyB<Md%#y
:8%RKq Jl$!jXhjMw%>uu65Ma18Bu%lR:%4kN\u/%t#pDSe?ucW&5iKIMhQFNLJ&QiRw*9mn>4y6YLultuT#<*y
Lq+M#W 6X4Ayn#c9K/:TAICpI%e6D&mE9e@EAFDiVe@BD*11KEdiF&u%V!<dkCwunK+yu=i$#IyZZ>EYpQA9=45
tSEtLA Z:@nBDWY@h>PWQ?4tYk5=4?^ku/*plQ:1!5=5V86=MS?b<9<8l9GL%n1eQ<>FQ>*I>>Z+B>GQkL?D!Qj
5JaBcH *=jC@YeqHBL^9RWd8<NT8J@9\B!=W?Q@u:\V@4EhPiK@&iRhmjy8q*ep<licWM*Q##>pi&+Q@$itZ>eG
5an%AS E9/\n^L?MMAV@tln\l?QEQ>+lQnHI<R@HmF?6bET@*kG?ZW*E!Vm/:auCP#Z9*?K!^jy?eb%JBK^k^nl
+Bq=6a 9q6A?uW*qd<5!WRSh6#VHjXVJI/\+!:!PQVQpimhpbmjI%E:G4b^&J<nEV99Za@:KSK:<*JZHQ:u!B@5
SZhY6K q$@+PSK*+/RBn9l#JGdu9jaSQ$imhq!em@?=DGESP!=<^9>el4auFZhC@q!GMQkhJRH@e^uCaHh5Fj#Q
I+8qPp bRm#e=\G@M>qCIQeebp&@8e!>CNhnTj<>>C@TbHcq@il&ha4$h@ej\888ZXGJPL\Y/yhRS5K^!F<A+Le
djVEi& *PWDZN*@YE@>l$L>w9d?PlFy/Puu@WYn8t!4=T$6l5MR6<S+/&Y^Xep9&5w@!HXL/h6>ui*?S$mHu+5u
^%F4I$ j8jbMMLj^hM6PGTLj4V<q9:E+*CIj$Q968MEeu98G@eL>Q/Ci5V5&PRE>A@wSTF^TMK@wHh:5t!dZm!S
5+j&\e <A9$@wy1*XEyE:A@yBiQ\j\di4hW$Bh/6*n*e*y@*1Y&*hS&wlj@j/D*Z@F*c\#&lX:e4<n9L/l$+w/1
I!u1VC npD<Id$EQQ4j$I9=!q@5L@CZ?A89A<KP@CZ?1L?lWGn<9?q9YBVtD*4S9>DjmKljiGZ8!F<m?5j$dw&=
VG?LLX @kY>CMIj>KIR9$D9#@5dF49n!+T+W*@DdNPL&S:C@D1>tG*@!m%/6:=yj+HiZ^kGwZb<dSL^Q/AZnWTn
I:9Kqk @+%?\G#:8Y*Vm!j?A4&@$N?RP\=umMRj$a9GaQ/N@GK&&8<L9X5D*y@Tm$V<9MNlh6+?=w<9kb$=nMCk
aX!?56 @k*F/D@iGBkM+Xew@wZSG=/+M<ZwH%GM\tGS@+bm%B</DaNG@R4F9#D&\/F*yln:R+1*?@8@wBn^l%dD
J*aE8L @MwwAwu+lbEnl4A#^V9%P/\<e85%RQ^XiyFwJBT>%addBKPJtF<l?Pj>d66bipiC@@+F@\*+y\eSdp8@
1IY/jK aLe?NuBE>Djn\u<<mL=>*9+>nBVm@=#nh5@=a1=AId@t?KiN+p8YlB&!SH=95EDmMD<Ql<VK$PpW&W6C
EMAVIQ ^J!I%#Cq?e<?9tXIDwElb%wyb^F?VAKML11*&R@HAV=Pb<*jkeAI/XE:S56:GMGwL6dSF@VPTLaEN8&P
TIDZI@ &aIbEqGa=VnZLGDEGeQB+qyMXP5LAy*6$5?kPem@Z+YDS$a$MGDBtSk#=bQ4VSy^\\tcM+wmA?+<e5J%
El+yEB mjA%?!lD=KLMRQGEKB?!Hl/pXa!MLFkM/Yd6KayldlSN\jEH<diiKuq$E8K5XT#T*E9Y/Yc>iMGBy5R5
SY\wFp BiZB&yLSDTGHRW:1^%dP<45\JX5Z$WuH9W#WKWtFh#1Xn#Ec6#yYF^6wMkXQ^L=/BtH=BH\i$=EE!19=
L?q=KI SDdLRk4lIyC%Ju6V$F:c^XF1:BAmSGn\ywdC/8L$Fa@*4NiBeESRbq8FL9WJ9Bc$\RDXFRQGFu19qAk\
bD9S^# M1HdGBDDVRlBBnwTbR#wn*A6acCL%Sd11w:S9ZW=WGtJ1DyLe8H5yku&/EqEC8cPhAj/BN#1TaE/j:#J
bL86%S KiQC^RB&NiFKD4S:!kheZV*e$:l^PHI$Q14bhBj!+4mFR6!+4A=mwBF#E#NwyupjbaSYu5WQbtZjR^1K
iNtl:* GB#6mX?uC&eR1/pem!XLS=>4WFQI#^STyC*bjX&Eda/BXYd>Q18aLpyVFeL&ZNSIYtZA:Ct:X9aaM>R5
%6tHmh qN=R/H4tCV&y%4TC5+a>YK1ylXq>X=45^Ia5CkL&F=YAnm9<:ulV*\I6bGW=GNKE/QL#>Sji!=qT/tLb
-AZdy$ 000abf3c58b00110333 Page 211 of binaries1.zip
8X:CH? :uyIDmtTa?K8tnHtTV9pc/mtNG$5>wVRj>JlQHnwliAe^KSt+yMAQCy@lLi5F=biu=AG%8P/NXmVH6jF
\\ip:Y a>+aA:=wJ&Vd+!?Y=1PcF&t/D#Qa\\G^/e<#DYBk6*&p@PCK%8ABl#hlJqt8X>%8u*Vp4p4peK^ulbcZ
c@&G#k 6XiYb+Q!YAp9hEabcnlePZu\jlN9X\6hy*mX=MLtM9%mIF&l!lbGh=Q>pJ=q!i+Y8R?XGP/hZFYT/M>d
t+yD\V QcS=G:ua?EHu<KPDA!#k@RQa@SLP6:8PPC!*VB\i6<a@Q8=<V#G%Mi&iw4tSy>cI1wbHF@8Hjk99CN@T
9kH>^k dp>Yj?V%PDwqBhGB?:#nhc5Qhw%tL\1R*bDH8VhiuaE/uSX1mcMh1qJ\C1R@/#l5KnQQ>?K%cn^EL^#S
TEIC/E ZdE^Jb:XFw>1c91<d4:+b8dP\KZjLP<y1\1PPV&H:qe\@w%Qa?#nIT9Vmh@=$m^:Zq%ykEw#tDCX&61w
>q#y$^ Nqla*NpNqJ&Mc$=GiPa%Gquipm5y!TFZVL?MS9th#dpebp1*n&Zl<Dy^5%G5l<$lAKRG=/TDS4Pc/npF
*C4qW1 16*Wa+cnIB1RDJCGiG\HiqP=QS>X/qqiYFXyab=51w/SJlWImMb%yA+wYqtAeq^keScA6PI:Pm?pBtt#
hn&Lw< ?F$5q$8D&:1=+wCXS<H1@MmL%4#bV$lu#P^RS4jGEN1a>bd^J4eWB8Yi+6DWqEhBpXI/pKb!T5SJ6TBt
Pm\L/$ Cj45cHYe*#+S@i!++:FT%\LI8?&qd<Y9mMjua@V9VNaHi9t6TbTYJIEyL*pQWS?5Xai&6PianXATM=pW
L/%mFb QYTpCp+5SkeXa9iGV>eW^?D&AWcQKDF<ND&%Rt5t9\BS1jh\udwGVGR^tyF>59bma4wuETHwb1lbJVI?
MBt6SX ttIFuSBC>4JYbuD@dtNG8NZp#6yhPILWZjY$M\b?cy>8BRb5HPp>^j%C?yFMTR+qN@^/lZ&D$&ykd6D6
Bb^DWJ w*!YaY*5VBbtcAaP+8QYS?e@9A%QDS\ePcBaH1X^+>R#Q$jhEhhE!=nSktVH+I98YEZK?HF1+/YqIY*y
8eBRha B69:y1ec%piXJ@qWJGNjSTj*Hcw?8DFa>FVjIuPTZ?Fh$QCh?&@PJ8?!$#!\jN9h%9dWJVd/<:4XX#I*
@eP1\G djInC?AMutBm8bF$Bek#SqB$Cb!4:*^$y6*JFGJbdn+>1#94\DNwt#5^A:Q&<qwRSm4&A*pJYB9w^c!:
@tw\T@ eV+4qm1Hpa*kkbG4VR>8T<$n9TMPY6?hcH%<eBPa:ly4M8K#t54TXC+=XulJMHt<<9+hq>8@GW%MXalW
\DFZ!: b6?89PTadS#S>Gy=Dq4XXqR9G>F%SEb$6MmmMMc!kM^688F+WF:EbiT&eWj?chQVEy?<^wqthI<kt+//
?C^WqG $d%%8tlk9#+#/eXCDB$Gyb:6qTbid1VZEj&^bNa&N\Hyca=e!K&\4k>QN5lF>F!+#V>9>Q4/kdXQ?<y:
LK8J9n #=BqjY$R#wSa!tZcBKchNnqHw9:q=Mmj8=4@%$9&pMn@^q<e?T*Y+X<N:eSjuC9=>5:?b##J:!PiI4>#
a>h:C8 Gpilhw=Fmj$=>ke&emRT>*Q5n+Nk+9<ZMPH9R=>9$P@HQun56:HQ6!HW>6nut+@?*@Ip:lC=AIu:u!IZ
J/TY1D MIytBHT=RwZakNG#dZQ$GQ:p:5:A?pk:PcKAE>BD4Re4uKdLTCeT$EiGb88Zb5:G%8=F^9J$Abi$ID/I
YX4!MX 6GS/mGu/lBw\qk%iLPAV/!InSIw9%5?BiBC1B1LMTKdcHP4T/k\LVmu/>PcZ\h&hGRtLF+:>6p>l6Hu%
nP+^bC 1EcEaHL6+ySH!*uVmtG9&=Hp!$pIjw8piIKcD>pepcS%!XR6ahJ6qQY+cJVcDW$$Q+l%K8N/@jGmqlW6
8:+LJ! Ji/\G<+lw&A6wMQTFTyeWdldjK^RtpP4PdwkZdFXtCj&#C!R?#$+&y:AB=bDK^*VZpR9P+4\C#*:XL4c
IR?X^J QmR/u<<VT#L9wc&?<4HWADeWS>eaMA8Y$@WSnJ<qFaliATeWQL=ci/lw^&p8JA4^@*+@S9%ZWbG^&P@D
q:V&%e ItN?6S>@qV@p%>Wn@=B8%QeSp%HI::cn*dqQj4<H:9jaH@Zu:*jB*cHeuYi>pN@9k:5DFwQaGa9:PZdd
TSIykt dLwnF9<LYP\Q!mZ<Ald>A!#^=%nM#mbQ=Qe:+8/A*Zt8Bju>u4k:aFE@\Q/CZKG^P%5I$L<kX>54!ZdE
1iwD1F @wJewZ+kp?ljpK5jYVZR8Q<B?\6!lj1BZKEJ@\Q&F?RKTh!=jVGIZ<H8ZF@ML<kXE4>#H<Tk@kj5L<nX
kn:AXI D+eBGM#@A9+F!j4ByB5Tk@5j5L?m5ZA:T\jtX!RL9dMBC9M4p9YD6\4&F!RL?\QDF@aZJA8><@\\Ew9/
Hb/tnD ^#n9Y:!yH%9N@4S4jSuuwd<j=@*Dn?4:QHi\t@&=yuM4V#^?l#\^P+$hCin@F?^t6J^dnBSqhiKMLqtF
EB9+WI aIVXuyyHAWcCWHFkeXG%ktb*XJGRM+jIwCK*k@DhqbHq!el!q+ae6le$yC/KPXcV1ZHG*Qpb?Hn$ebSy
qXYIC= 58B4iZ/\?L^k?tX>hLd\BYkq=9XSdaEEiLbVe*MR54=DSMD?6%kQXGY!qGnGtV^jt+dFPp+cH!a1w9:i
C*L/Kl HMNFNdHyaMmJEN1a5kWQPGJNY!ND4b/CuF69Q4Ndi>MY@TnjcQFb:^AIL4wYVB6VB!h:wk+p6+w$#@nB
HQ@%:S lbIMT6W6XiM!G$*LJ6=d5M5hFYa=D5tw9%MylDBANVFAhYG5k!K/#4hwbj6JpM5%K\tREhXCi9mN+/C5
RyD1/W >=@daCZAYyqSPqT@4Hi@dS6$MH9*jdca>Iew6tL?yciKJ&J&b/M<wk%aP!=PqjDHQ&%+u^*Q:G\?wbbm
^/ec/p #u5ZY8@6DkG6edlCqJ&<l*C5VkbD?G61iYVeNSQq!4m4DW8t<um%1mE+j1m#TVCP&!YplAHeb59jQ//=
Mw:q<h DtEh:QX=TFkn4V%nbKN4+tik!:+pnXek1M<c1bHKu^FmNJ1iD@ZcDeEH=PiDCYBW@^C&NbX$RYPE=pV/
qwh/cF #NCtFw@TTG$wB5I/Z>W&T?RY>IK\RZ!=6aay/<@WqYcNPFD/hTyw*iT%GkEbB4dm$L**5B?GLiHGBuhi
p1lue8 6&i%RAbEwk5Tc8yyI9$qca\K^mBDdMXH$WaRPen%@4YJM5VXCdt:BIPw=M?iRJNu4QpMhD^#c=b1%YX\
w8Sk&4 Jc#Q*C\\<=XNYC98dPw#&%VI<9#\^5B#1ahBb>>EJ%?&9*A+np/#J<@F!SipHIe/<<#/CpctS<BkuC=E
CE$TKu tCnAYp/IR*?+Sy^5nD?CjNn<?*tyqH9cSlyK+ZVy/@e>I56=:BPDVHpenJYPLy8+=C*N^J9LJHeRCYG*
Sk+99t <wq<n1NHy#C^u/>+4!t*Vl8YP^#q9dK&pmldBX=<mq+X8m/mENDpMy^tML\4J&?IL1>VK+AaP@d!!4YJ
M6:*5R pSG@D?6p=D4QIF?4!/GJD?w9l*C:G1><9B!w\Gd@GmC+F1wSeaGBJunm6W1j$F^clS#bidR8Aj*^a?YG
Q$KtSS Jw6EP=PhJaQtpuSyLRP6S6CeRdaYI/a=NhRCQec%ju^q@h\4K\ECGWCYQJ^bqc?W<8wIC<W&BB+Vb6^a
HCn+iL :*KW%eYw@k^h5VlDY8ui$/+D@A@GLiSL/wZy$CnK?Z99w>wmd=Tk9DJP#hFm+/>G%5b+eE\JH9QSK>#d
XLmyE6 YByWNV$9h<\LcaYhIhiQ6^RRqpXp!&N8$mdSEk+<Z91hS>R<LVqVniEY/\Y8D8PN>E1YCApk8=Rp:tCY
B$!NJ6 Ml!@IwJYn#c9k%X^HGb8V+wSHSy=?GHJ?Atuaa#4S1uRjSy!STABKL=cICyE6/<j\q9*59j<:iWDae^L
aiQj@\ e/J$VWH<L\ty4A\K<5*L$=dSS#^NZ&k&X6Bj=u:*Y#^q6:ce/DDk#8qhBNN#lF68kDNmMii#k6nRi1<y
KB:!?d hXqC!pj<4!1w#Ci<H4#@+wS?JkM&4PFGpjedZ=wBatuQ=tiuwLhBdFK=HTh:twSjP8e=6iKcq<dP:lH1
h@XANj JQj<*1ewZna^yPl5/9ZKP@yW?aCbXP?yT4t8$?Mb6A=#D/TB>L@u89XE5hKGJ^c/:^QH^dhS<t*!%iL8
Yq:4CJ ZZtbJnk=VnWF>e/aqHteGj>+$$:pnl8hYNumqIHA/ceqC$aCyNb:nW@^##IBTQ4QtuB8k!N1%:ZR^%5G
$C!ZZT KQt=<ZK!k9Da>#iEmL%qCyEQcPMaMceDi&*JNi/um#ttQY!:DLu%<bKA914yI$\MNBlIV+6/6?Y6ARdY
FN*jPK DkcP8FbLt4:b5$<Sp\Z#H5Fb:*NNXkaihYk$C#\%n&YkEjTZiV$1pktAK&P%>m58&:adK=yZR/d&qyL/
:/CDXi &tn!++B6V#jwtN6A5lkRP6+JNNuREbw$C\jGV8S&^b1D>4Vknmh5:PpeIaWtX\AdZCin^a+H^i4GyX+5
=lj8tt 5?*b=Y#kYq%cG1P4YtbVH4ZjhAc6T\<9tXKT<SpM$wlIZZ1A+GE6am5=RtH8cB@?\Pt<*/kTc%uibY6\
:d@Cpp !Ee96M&BXjY?#W1AiVIJ^>CNitRuyt!*/*b?m=d$Mqj^1>Bu+9hcZ+>N&DRjylRB$GI#X/ek>?5*VpyL
#PTDe? Xh$=h%=!<:H&da*h6TJqYukm4ih6A%@4RautGy8SK?BSY8X8<i9:Pp&WTq8iSETyT8$PbhR+QS%H&A!d
=k$P5l q$A^Fekn@P6##M9d$TFJwDLwPj14AVQ+!j=5%+!8bbkNuVnH:$^&4@&GF@eJ9a5<6<l=VVukBQP6GNLB
YEy&I? D9&we8:H8Ntkjw8:RMXtA4Np&@#:L9D9Q54Q?&=aaX/K=p!QKpy/?h@qXe/b#W@P4ZEKma/<5JjG+IFF
b6lAA& jPTnpW1*e@bu:lEE4AZLp^?:R>+mDG/:\YJ$\1/IZ%a/Ma1S9qdkjnJHYYd<Xnn$<R!E#B=BnA4Rb<\t
JpVBVC CNDQXAC9/D\GWPqbn=ANlmMRwe6TSDaBDeFe\kt>1h/AHu+H$\J!+SBHh$#mdw@*S@$>e+ZyQWJMVY<@
!h#Ql< 9MF:ECwGa\$a:5ZL<HtK<=&PTcMe*X8M$5w:@id!DiE!Ha1AXQ*ySJi5!T^p5IC^e+=Y$tT\?tFVy%ne
HH#j4y \t*q5^6F\R+4hGEDL^Q8q@y^t!t>9*w^?%P*%S&DAJDI+WDG>mC^?=Ihj9:HA1?#C:?=iIM6C=uZ/S:V
FpX4Yl tXX4P8Rdy%y#%DB=\&ce<NS+#m&pMPuq^NN^KiVVGeSIFWRYpiyVi$\q/j&+>=Iu8Q&&hQjN<T/#1:%k
9*\TGj tqK*$aeNhWN&&F4V\6AN5Vj*QI5jWVu6pXc85<!qnM:kI@4u/uij9V5qXH>EY1SX%&4RRPtG%^G=m\1Y
n\dc%m YejGmb<EDnM@5:1JV5/iY!*XJ\:N9XbM:tKDtd=\5G!X^IICk8@d+Dm^Vw<b#kRY9ciRl+B+n=Du8GaL
86Jw!F 9@YQBy/YLm&>ItGk^\?:Xe<pDaJw/kIDMG5w?!iZ*!\4!>8E5E>X5J?1i#J/w=wCjXb:lR<Sb5#l#%ca
1\CBp\ 6@Y!i:/!\t!/^!bqWG^%=Q1K?JV>ytDyRqEkMqSkke9#!nMF@/ddD5jZ4n>Z6>n4M:baQZ\m&65H?Hk@
1EVlX9 t?MFYwLwWjP$>CMTG<ake<jn\DuZXujG/*/M!pqcwJBuu$+@wR&Je*YY%I<EQE!VCFBiJ@l^aF/=kT/+
%pNBJS 8?bS%$:h15\4<AqtQkqaJ%k<h%hinI#d4*#1Xq?hyHYqJ</b>IVt8Kd!Ww6XRIR^^>GR@clM6+cV*XMy
%=Viyh #%cNYc9h$mttJ8w*>:>PLG+lq$dM4ZZ=yL^?@GSVX=bcZhJBBE@$mkMPGh9PQ#:c&$a?in#itDuE:&uE
1@@i9> dM$/kSH%&w@4j5q!TS\jl@Sdckw*&?DdLQ4Ia9i&DjwPR8#:K:yFlqKpldciS/tWPQJ6\QA?<CDpWiVT
-A=#<l 000b693c94c00110333 Page 212 of binaries1.zip
BNcGC& WVbBm+Xbhqdw$eWe:w1IlTFqkyRhh#1A^nn?HIJJ:\uZ1ddu6DGSkamV#NKSBneF&Iw#cD9VV<ib$hZ^
:CpHdJ bkADP4SHGadwybiKDDt+ctwDjPjLy$4md&9Gl^8=wqq/yLWDy8X/4n6#NK!M1i5G1aL44*hF*E?IE!4Y
n&u\1^ 9jJm^L+w<&=%$=Fdtm8Q=WD%JiTK#WeTd*&SjeNhW&\FM^<iH*=S1%tWTy?LE9RnJ&TqWja*\I%m!=!K
mWG?:u E+\%TQ4WYbE?V&anY1XpmGED%MGQ!#AimJ>Q:p8cC/d/9hZmiK1%b6SkVlV:bBF#qJZmYJ4c19#m$=VZ
qiVpWp :qGNFmLd<wwi48S^Ih^@\ydJd+qMd%<Mm+l6IFiP4at!&pKu>W5?ka>9/98+u=WnH^l>8Fh1Cp5bpSKL
w?>LYS QMmmTjAPd/P%l<eKG$NHFF%/G6WnWenY1PnaeNpRZGR#A:mp6CDkEauMEpqSnlqmFH*NWMXYD/9ndinj
GCFTN> %bEeL@yKaab$wXMY8FFb=WPdYFB4SJj\w5F?GN+CjI=TV9up9HE=S=#nyY/4#iPGqME1laT\cLmkeqG&
S&kyLT 9b=ja5HItV/&i+8a?5RTlyY#SK:LdC@#D8mXkN5/jL5?NTj?D1$9h:^+XZbeAY?\&Ztmm\RI<A=Yp@i?
LVj?*T DPJ/LqP%wlA5K:4^EcQPJRQ\$bJ/lDBnTu<JSuL#ICNNpY&BKEa/FMpNFS&nyGGDN<Q$#LlLZLmkTmW#
9*+1%I qdT>ZJ\t^KVkZ6/=:Z=RbZSeLb:@FRXDmDM?N<ddY*iPZBBJiS#S*DdE^yIIJj5b9/\@C%8E$i+aHQd9
E6Z?Nh C!*?ud*%L^5k@5j$8uYP&9yi\9$Zh6m@4>#+6j%?WD@d:<je$>e6?N5GcH<4Dj@jYH*^*!%$RiJ@hcZL
<#@LAA 6!@Hj*:nj9>N@>Z#+?i#N%nm#:E@59dmED@H+u=kLjy?aeWPYDS?b!#1F:DIuc*M*!?8&AGL&Np/>9*!
5$9#m+ m8?^Q*D/SH/@\GIH:M=dJCG@Z&K^A^d#A%:lj\H:I%:>kq^ljtD9\j&CZQ%kHRET@\6!lWH8LM@+Z=A4
ySa=/t >A?5u@ljpK5jGkQ^9!BaQ@L5\9?CaPESP^9$<L<kYBnmD:C@IFka*A>w@5hTN?Tj#ta@upD>e/5#+!*X
6:tjaQ 8IMSDL@DcnjW>l/d@*<$k\1tb>ARlq/Gm=&Pk+&tL=BDmB/dQT>F:81WR9mH+5<i4cakIS+uT6ZNwTeC
SWLw#K GhTkwiEEGYbml:94^tu/=5Bhida%J%p!?Qh*61wn<Qh@N:kTe$duJpcG#b<j%QBwI/8>dYn$#DCIpaFG
AXQ^mN 6*?KAPH<%Hnn=una\!mDjN64NRq#tt8^HGkMj@#!?!AlaQtMK#@T^^9^y4HAVFWc>/#6+h*+&ZI!AT8q
kcSj5H c<wiX>lMX5LNyyPuGAyQ4KMa=BB>h?M#PJbG8#XIby#c#<TCIK^!*L4<DHTu@Zuaukp1R%k9\9iLZb16
qC6!#F CqC?6L/bC<EPRu%=MBSA9!AtQaFMmEPc&W@nwlyhJQF$%yPR\dG8*#lb=jk>yt@Pc9bY>uTmX%TT^*$i
EulYVD <R>tqSRmtq:MtBKHCq&4XG+GWE**/G:EBuI!n+XE/h@KDHGAcFHT!hk+ljj=J&XY!WFXwGk^Yj+:HQ&1
kiXbNB $M5dia9E#1e9uce$P%pQ:NN?GbInR5tXjeR<6lFTN14*t4+MPT!TdWEe8AnJEeMP6<%1&d$MQcTTc9wk
PWLIyC R&\!iLJVVe8eY%hkkNMZm:e^E**letF<PtejiN+uYpBq>Em\1nd1:D*8ETeNCt?Zl9iKtAu1>Q/wqA$e
Vc5bGI DS?4KGTe?*/V::C5jQMM=TMYT+bIM=D41VhWPTai<k<Hcn++4w*T88Fuj:iML>KbC@XlL*d&#B5qt@TQ
yiVDYS d9K1#ibX9ykD9QpR5qG*>Ei>J5%E4tEZ8IN$u*Q5E^:YauBclA:*>BG<manQBX/98&<>>ZHQ8=HuL&ha
u&%YZC 4A9iE1y?l&i>q=8V^!BRy8HpS+C+<HkM><kK/Wh$FTAG#kAVGlnwPQ19Q@$a?mp>nt:w+%*Zi?we@R\D
4LPkp& *X=9y#JD/*V5cE+H:LKRi&\=FuKqH&?n\k#%EtwM4TjLA@Y4qwV%l+h$?qTVDq9+q>lI/IR:MWMeBMQV
pFEj\X 81?%Gn*@Vanyla*kVXn+Y@>#H:ZjwW4=T%Jp/1\jp#9ub/S4BDZHXVPCN*p@bZR=eJqdc%JG\IlRX5@&
6ZlwI: NB/#kBNeEcdHK1RM+G//=*i^TB&Ap*Md^qW@$qS6mAMKSJw6*q<by&A^T\<w^ZG6QiPuI$*p&mw9AdWV
+MT##b B@YTA8C#QPyNd^P#QuVH%H%<n?KwHJ9\pZMF#uFIqeP1::qen&G@FXpXJ!8pEiG6%c?Gq*e?uMu^Q6bD
Cwdb\> !pm=1GC%!>#ke^^mA6L!SLw^P<J8*#Qt68I\>e/VM%L&KS\CJbHNII+qPMm$F/K=aM=Nlhw#!HeDFEYq
uS+%j* *hynY1PHjy>yV:hqw&p+^L#+G%=8$@ti&DX>VFwWj:=H>atM1LL>6/DwWw6p:>GkML&XYV/>X^nQW+Yq
Y*\Jd$ J5!9SPp\t8jdY\/^*cK9SXSa#/beLEu!mB!Z#NcTe&8BWnI4jm>=mnl!Ktp6u=W#9d?*<4bq+/h\qCij
AckPbN hEIcjZ?4jpc>J+@c^LppCTWl?%8A?^i/LHnTm#>yGnSj4!*YVCwqE@Xah8$TJP:HQdHV6hJ8HVCS\mSu
GWb+Sh c9wXQBZlKyIc^hQE#FptiW!dhJX*:1G@u>$Rc1R*<V1FJmuS<iW:#1GJ^cNCllYGIS\jMb/c8S/:?CND
auX:6l nPNLAZ*hGXl&y^ASGCNkb6K#w8qRihhH$+d*D=$P6wVy$QQS/jC:u%en?/+>!PF<^/j9?D:+BGhSTw%L
qqciH8 \ISJB<K1@iK^X88%<Z59Q&tP&n!+%cNlYc#@JHMp6<m!yM!dKuVe6Cu?SI=XduHFA:pWu6udyyP5^cQ1
T/E^cm EqWFw&FN/?M&pKCdttMkhWZWDdN<48wnp1tX1KYVwk@jc1YqMneJqnlib6/$d^1#%Y>cu^V$H9nNF*Z\
d:9dDn IQA$N?K8TmNi/9e?ZLh58qqkSaqHD>p8nPt/\<j\ayw!V#wDn/!JL4q>/=j9pA>\jLc?#S?HCV*XBJpY
tRQHyN 6G/Acb%$uIN@PD\yGQEY/NG5iE?KJFS6//icWnE9Cuq#?NbGab$BVbwD5F>T/yBE\!5XT=6:uF\tCY+B
!pdjF6 lt1@&S+9GF^T6QXa$%LJZ*A\9B?q\ADTR>X:V5&=#&B%cYa@^jMK#>DF:NQuD/m<KHH8*m4cu+E*/aN+
#&d4JV u=4q?t$qQKT5l&KipXSjD&ih8jTdwNkDN\Fp5Q\F/tXSMe/5XPIi*+X!+d#mASjDk\>RPy!ny+IPQ#hJ
FW8Byy Pu5MEq1B6in1GP+wN:k=c!>ZJc+S\?@ym#FWBF15Q?EX#m>qJ9I%Lq\IF=jZa?yqHT!k/L1u/aPkHymP
:QJ=i+ dCDASA>uyeIE:SMI>e\VCNDG9jKLJ?8uJ?bG!%Nu4@PZSE:N<t!Mcc=c<%Qm5cG*Z?/!:*=6XyIAdBVK
jE%PVA N*M5i+BHVy1hu>^>6FiQPIiI#TlZI<t=PA%d!J<G&$+c5JkIX4u/cn&&54GZ9<PTbcLKeK+%Z?Ki&iZj
BIupQ5 6SlJc<$La:BB*X8eMmj/46<h<d@#@8l6yHl&=uq59pXj?:TuX@Z#<*P=&HR8G9H/y!h&h/PV<#+d*iY1
=QpN>R QCyDjK&1:h\uJydPPl!T=kTQ#dluV89AenpP%q&\?bm8k+p9K119uj\!i/+\N/uYQu%6aqC*96Gbpli/
A\BFk@ u*4jqEV1!?9pDhbWT<Q!tG5te/IQcN1eSqqBnH^MFV@N>:JIeNc\SYMw4GyhS?*+mqjnRp+>Hc9N!Zpc
!q\>!q w<w#<h4Xa9Y*9D5y@T==D:WNww:#PJeqcn=6TiwBZ@A9Y*FSy^#\Xp$$?uD?Ei&uF?PjnCaj!B>+@!bk
58L:C9 =J#Tt6=uu$8&d\WCLjqjpAj#Z>jG?/=Zq?8u:D4#46Z+n5$p\9@M==/RQd6c?8e$>*F*T#R#>qMYeLpl
FCi>*! 1!*yPK&W!qIbpXcbH94!mw9BGR=mN4a=a56q$1$^y?*!>E!c*Aq*>juA+5%:ydV<ejV%L4KmHyK#/b+>
:\E>5b /T<#Pe8td8%XLK<:>h9ebhVW4S!iQS1G9+?G95%>=BuuF:j/<ZG8Hu*aii>Q#uC@CNjKHHqBnejNea9/
Cj=^P= d=nEM6m<Dk!/+?pQG&lZG=TW5e/M$qc?:>LttGCG^!+nL4mjPe=P?/Je5!bNXX6cPDK8wM+*yCSi6qM?
+d:FX1 ?VD#IYBbyMP<wePADKM8<HJ<>iWS11@w?1ZH$948CbwtJXV/%?PcjeWXp#dHabn?BkihBcN=\/WCH$!@
A/+NSw I>n6E*A>i#k??apa!XQD<KtY9K/aJnlS%nNGF:lEm@ECuu:KeTRAj1!ELF*H&<!iYWj?CI=QQqW@h#?y
kMIFKB +:LaNJnn+^Pj5Kc&cbPu5G9JkE%Q$6tL9QW%&eWM$8d:Q*CLcj=&+Z%%QXQ4SYDeKPbauY^!ppj>ST&8
<DAQSt \N&bec<kp1m+qTG6JiDlE&QH/9MNl$d$9a8YX1CGJSp<M1!#Wth=&1cd8<JP#/8&euLWcNw*/?6*G1RI
9WlPA% GwVeeZZk1RwBu!ADp=#%FqyM1ENXbd*:X/b9ZJTlw#?HIVQy4ZFkSlN=LmbeZCEd4McCph+<F=TQ%abp
K#dATW ^p/C?/8E+TBklZH4Sjq1mSl/tWt@6h@=X=LBw$Nk/C&8=W$V&cXn>Rt6>h+54D&QPKD1k=>WwY5yZt9c
Al#KTw M?=G6<LT+JS/Ve*MHpDucB9X>RD*InBic9JVpu=hyw<Ve&c<=l%d/6I?F$N9h$Q<HMiPG*<k<eV@!$cc
KL<F+t j&iZIj^ZG$wR9:iWEH@bWpLe$XJC?Q:4pQCL?#pk9%?^@D*&S%aYA94uYB#lB?XmjkGL&@qLtwD>Bi\Q
P%%t9T @NP?Z$G<A^c=<=e$Aj>#:Qd!+B&^lJ>nMaRj%Jj+C>mh>:FAj4?m>*55i8eqpWnmL<kX/khYB?I9!BWK
BR&qw1 9VP9mL<kX#?$YBB@RdB?bHWka9<HLP=@\Q:V/pBA@NV1kQ@QKnnWV19kmD965WQeWmd@F/\PKTjm/ZRl
pqTYt$ /i:!Rmt^6KNhaibB1A:YpYlPCwiCKP8MM&*JAAVQ^/a6tkHwTIIYpM6n%NLHNAuyiw<S5MLLuN4XVNCS
mCFKmW KI<PVWRSD&6A>GSByl<^Tc6yXG%5AkQl>>WR/T&aqPJ@WH9ALth^Yp=kGm#^M4VeHTEAauyh!X?\ekkm
5!ZtaQ cHmKVt:An!CW^AnLjE4PaaINSyH%H9n\mKR^AV8VAtaC^jpuT6Z9Hi:mWTZ$FPij6i=%MJ4$KR&hdV*1
Te!Pi< ^CTVAL+hGHCjW/iPNj=TPREi/Mnjh<qFkDSFn^Y$bPnWQ::Hu\p?mDGLTlG5WC$biR>Ja8@%\Atb9dKJ
H<$ZDT Cyl\4bS8w:R?EZ*PZdI5p:SP#dl\kl@TpCkdA:4BbpBb^nh+&!+4Ju9u#!kmjGRWl=8<wl9+K<H11pLA
NG8R*a CpLR=\9ywJaMHMK4F\I!4J4/VdR@cb%j:8JEFG8LY4py/J1Ib6\il1waCj+/Wj*%4ySPJeK\^B#K@E&^
+P8iRp Y4D%8?LM6<=C%%Jt*LQmnR+:X%**^jDA6WjC!YLIE@*TZdhwtuLapcK5$4!%%bX*!llaDQMl+Fuh4ZhS
E&L9#& FVqRyec@#XV!w8llJdHWJm<deWSV?FMN1cbZQFA\1\5KWjiKmc\el::N4ZY^Q<?u&e\<9NNT#8u5d4T?
CwBF&D Ra&TZ1%V>T9K/M8YVh=+FGJYm+EPC^t+8GIjii$8Cl5BRVRqdh!5=jtI*y*ePAm/appHd8%B+u+:J1Mb
6yb!6E :Jd?1N\94^!tJ9*:a$dba8FQV!%<ZKQe:uG<j\I%qat6dyQu1I/<c5M/BPC9=bHD&?5+VhS^1cRFlb@H
-AQe$H 000028b510500110333 Page 213 of binaries1.zip
D$Ia=d IlZ*IkjK**wJ^#h5/GHdnL*Q$!u/a6#=kRhc@TRbbAi=NV1CS&!9^6EY9XBlLh=qIJdT1h6#hi>4k19A
/?Se\= ^E4*SbleDP<^qVyS\9mb?!!HSK8y!*+MED%d*k6FT=8Wq%/iQpPqG1Mwa:>t5LjSFIMp%$P<jQ@!RIek
I8/tPH NBmtqAFeB4k@h\Q%yiAN&59>CZG$M/=QA/i5KhJk!lD$:IZ!ltmlTZ&X^WWkYL>dKCFIjWQ=unj%/iqG
8ZdQ@W $d%Gi\!hTDMaK<FZy!<*+mi>Vb$^9LpC%RM!KEWhk?F>Q1>Xyi?j/Fi/kl1>M9^Jd>n^qCH9&bDkhG6I
\bh4+c dY8CJ@Y6pH*KXQ\GwAADX6KJ^M!\bWhKPhCRHKm%SiMC4==P?P+^$5NAN5<@PQFiL?thV>*N^W61JDQ%
H^YEC& 6pK&/6nN:K!LZmdcQFC?#WQ$9J=i6wNE6m9ahQ?wb4Tlc@Ycm9nCK:PD=95ABhDj&5k%FMw^?TwHk\8q
:GKAEH A!D#R@jq1L$D5S94:qT9I6?pbAlYM4LbIN?VkaF%5KtidPC5h&4@AApm1\F#+WLFJ<d%CCljekJDAmQI
XERD$9 mKhciiuQciiY:>1uY>RA4WFyG6!Z4EkFeN45bPjBpyDWIi#NGItBRti>kATyZSZXd1cehIehp8NlMme6
b!qWnZ THd<LtpK:Zi\=jFN#btb9d1DInN<aa5<NGaF55^hDa*lEm/eXDnd4h6:MHtAdJ91*DRJ=c:8C*S$LJ*M
E^cu88 PWu%#a!$$=QmCLn?&FNZ9q#?>X*=NWp9AD&Cd%\#YYLdV!/4W65t\8/dS$!EIV$?m>&MhDIdi<VI=ZP6
qXl=cL =X+MS5K8Q$$/S&X9X&Sl%wTmDj4TMV/B6l9WaF\$&T&?lGpa/X#hy&?GhJZYI&heeH$ay6cBX&:nka6#
GZt6!8 u#kpuu%nWC9cYaQ:88wmWWQYQCG+TPaTPWyhYdT?+PQMm&uXSj1e$*Qc*wpL<ECMH1QPVil<??t5wJwS
hmJMXj WYJI5<j$@dQ\wTM4$D:J*bpwutMRYw8KlkWH1thAYHYHke\<Q=9b/DFubJ\cBM*FLhbH61QJiZaF6:#I
dAMQ9j @EIP!BFHP</#HN$Zy*Pwi>C%!<bWFYKdBq4p::ww*Y%N4S!KGuYM4tB$95RKc4QXFwQ^h#Kw?HDyNTBW
wF=@#X I/+6SNnuQw$@I<9c%XbcW8$/FyeySW5dR:@Jcak<!Dct*SLdMVH8</FZAi:PKhbNdjK8bwT:8$4eCB4+
wdl\5^ cLPyJM>=P:JZk<ay8c<kuGbk%<me>dH>Rweh%9P91Ll/t++plpbyLakayJMHbYX+!Y+V@Jmqn#hwGp/I
D*DGPS JWtJ$8&uw&p9IId#Mik$acLwYjwKmy$T<QH4h?!ulc&14bcFbESSYc6H/jauPinpdY+Kh==>c<4B&^Z@
@/T!Mn kZ/59##pil?ydMSdI#cH*yFT@WIM@5bdX/SFTjh+%D*cW$WPK?@CFRnIw:jicbk/h5te$Bd*/C@hA=Ae
lpkG\\ W:qb+*1y^EYCYmC6:X$n#nd@!5kS/ZQ\=N6W>kFb9c^Jy%A1C!8plNF4LKnjyDbS$F9/!V#k@F\E&%Y^
$Mut6# *wXJS5YCc::/J+ApPbuMn@5&t>6Ll!Zld=EM!RcZnq1MRpX+MlV#db>/*yXTdY5GXcN:\*PJPd1TBbNC
\&ZRih /F+@8epyW*^jcy\=1/Bipw4@Ti6d#8be&lX%d$^JbqbAm^l<6eFc88qb#h5^IR#!ktZ18w>nJPcb@Iyj
DikCZJ H4QlT=>twVb^Mq#N=MMwJ>l^bTS1qG+kL5iJ6ZHlYu$dSW%^MX^u^?lhD$TpXN@H81=LNGnjQ/ST%\wW
>GRl6+ PH>Cm/&Ij+/C9edRen/J=%nwI<RTuimb!?G+VwW8nQ@6/BHJ/T1$wy8N4?EJ!hCMSA5bpI*w6MLlpHL+
+89nJR tKHmpThuInhGq\9tEntn>*JMM$?h=#c^?q&*JlWGEqXMK&YtM5m@6\1yCHb5Ka$IHFjuNI11!4kkd>1Q
BnVAh: :#6/kKd@nLkF&!u?cA9Vi=9KBWlKdRPJ#DH/Mdh6yw\ad%uCi9:*XSQ9>c5Cy#@:t9&t=&e@%nm?EcqV
cb&lWe =c5by*V:&VZBJ&#>A+G%cdR>1&B&M/e#<k9^48K*D>18!:\+bdY?G>X&mqFCJMD=wLBewQ%>Q9?BZ4N4
yD<c8W X!*!lVlM\<<eQNZWJ#Wn&BdIXDFkLM9Zj4Q^*kyQdt8cQN<L1^KY#+^JAB^CDQT$V1m!j=cC4$dh1b1l
mQ:/Bq *Fu%jtY\RB^QjGGZ:LVThdjnBRX+$8T5L&^9@ApL=@9:5iu4SLFwFP8Dw!JuNX:<jtc\?j:?Vn%8:u/b
RekJYa Pw6*L&@MDji$uZ@Vw^Z*Rq#W1iy\R\@>b=Q+#//a?4ckld4N>\G$Ck1buRuqq?kA+WC&&nK+nRt4Jk9t
YJbuF$ ZCi4/jQLXdJLh$!c*>WLwtwID=NTb&QnLjYKn54L!%i?jn6DB5%pMm9\8%LJ#D+h#qy9:/4QQF!qd:=%
%DtXP: Yh?Za!:^W=ne=q!6&DBD>QW%e&<@\THR?@=1A4B81c>kdD/kpHF%+!cXQG%WZq5>1S9V$Te:Mb!$i5>=
$e5BYK Fa^wB4N8FM@NbI4by5eq#e1im/Eh5&h?nR4RZ\5\ymRKunZa4d:ahQ5Y6dI:!ER*d!?</FW@/DYV@R&6
n/Spck *c>V4V*hhy>@Rd?jKaCBnV#!tKKe$KwL/GPXatR$yLXIHmA@Lq4qiImMd?m/qj%=+GNe>^%LI<GSqdeJ
lK+IRZ mZCN@8Xd#:$Y\R5>C\@hNSe$T1tjGh:48PXYmV6T?+ZV+@wF=M6GbAH6M4tJEu#<5bG5kdq^L\y/GNhj
wt?@K^ hw\XnK\*88GTE<=+cSX!m%NP#K&He>+X%u!j5SC%m@:%LLP^FTJVLn:?@mwN4+K!8u@C9tYGZSjQPQp%
*IDX+I !=XD\?ta1J:q:\Mj:ApRDtj?XMkSc!y?Ab188=m!/DbD4aXdtltZ?FbBu4Gia>MFKc=Yj%lJ:$*114wR
/apN4I #N19I<K<@DH^?uA<W<jVu1m+N#^n=p=Qnp6pWq/PleqLAMTTcA8+:HXZ5pi<KM4?IW>wNb<aL^lL^:P6
GXkWbJ HR&Ciq$\V1yl^C\?Ke?tKG89^d1uewRHqLA>T$yQHdm:^IW1n&R4y>uV4e!8RPyPYJa9pWbLwhA!X6Dn
WN=w>^ md!y6X=Ba/aXT#d$PI<1^/nwD:9GZtiPj4LW^jtA:b>*JcXy+u!>&SR+uSp1teL/Zm8k^lZEW%je1Pe$
a16%Fj I&8>Bk\w#VVGdiKkP=LGihpt$edch>CT9Wlw@E!FhTV6Mnl!ZFSMq+K&n+Z4PnKY4cujpBX:#Alab4*=
VSn*mu Nt<WtPddJe<+E!dB4>hdu@R<&WJ*?j+TAAq:n1n5<tVSyRc$6HGB8XtVn$cT4=RjWCKS\X+a*dc!\lnR
A@KpCb 9e\Mu6n$eA/9=8D4bkt9FVa&V&uJj^AH/ua6NVjYKlnJunKSXXTjaXdA^QY*%bdJ5d6/mC/uAluTVhXu
eydq^1 LwlF!lT*Hy1d*M9\mNuj94bWj%$t/aa=WCjE@uKdy$C<n\a4aHy<+/1dk9kV=&1yCQ6Ec9+</+!<91i5
&m1V8+ jI+wmI!J+89G8V?J%PP/a/eF<wAj6bVPVIbDW?I#8%a&LJLZQGGjEl=nll+DQS9:=P6jmbyGc1iim*M:
i<T5Km Kd/aCZ=m8Y4c%EM:!@b!/Lk9JPq+?yV8b?N8F!N84tkY%M8iqpC6!INT#t!BCiG*tdwdB9chAGTPlB&X
YmtMBG iTXm*K$:6=G<tFp*KJlw1kVV+$y:Qm6a?na=Cei&GQ@k6wcydLTJ#>4pGNNn>l1Lmp@=a6KiYAMV?Ae/
9y\<Jd E^WnMh&H4lB*<AyVMe1<?nhk$VII5H!aQA+P8M>AQu1:a^pI=$Y:AhD1/:ynnZcIXlRmj!F4%=/Eq!!y
<9H1&C ^qEBy&%aH<+cEwCQQS:qZL:*yEhn%Hm8T*uGy\1eVRcu59dXZ&Em=#<c&BkeChF6t*+<M@q+5Zy\wCN4
<AXen\ a1Lt1Zd=m9XF4h$XhVZPIi>QM4BX%SM$dwedyk?F!RVTha8mjZle1=hD!TZXEpPI4tSjkDe1$a\&\JL5
h&Ne?k /TwZt!CPW#>9/ZNnNQ>FLtqpYNqCdy?#b>MNuQLHFMj*FiX&Euq!q!ZhM1*j=yI@upD9G*l4MSbRlXZ8
EQiEHl nA^EqGiDX#bHiW?!*pt6:@bSd$JEQF6t#juWX!QF6IVwD&lA?Bp8YC\nEdbJ6a:u%>wWbATd%/GYLM1K
Kw:$Aj 8wN</dH#L!Vh=PGQZ:<ikE+j#qmeah9H6d>jL#&FG#4&cKB5Hn1>/I/+WIa=8KkIu/i+An@SM+Y:qnmT
8<RVBG /QJIMRZ+SX9FMpjQqGZbqhd\&HRpuKynRb<GHW6@bp*&&#n9j6?>%qIBjAR4iWc!=:Wl$NC@VCNWB+J@
Rn%<\& wl=RM1XaGX@YeFFGQ@^C#%w=%&<+tSwNZe5qWnRdaEd?8S%?%jYm%n^CuC*$Chp?TR/hZK*L/KlRJl!Y
+>\h\p Sk1B9+JdQR\>jyJl9:NGM!6clmMh%JZl9MEEuhV98Bh=*DEL6WhnlKt&jp&BIB#GD5tXM%BNhItM&cPV
ibuN+m :H/kw^$l=+LEVb?1Vn>X8y9J1?>bq9tFlZGyQy9DMWW%958HipwMR^jSMm%%Wp^cuGPtkR$?w&>nJ9%q
/8:/uI lk<S%9KNRcpkD&@+E&i4tV:dyZR>Bj/M!G!d^^^J9R?S/L$eyctjJPCM6M9$6@JjIt%E\lR6Id5#apXV
^?9F5l B6t8qS^TL?b1%i\^ZipdYek*VNNqaFLFukICG\qZNBR+a\>\Dl=BDNNqLF%&m8%BImTKJm*JV:5Pw>la
IPlytb 4!1\Q#=1>Znm%8N:Vm9XV:wiK!\MSeWjJ%j65WMtnF=&yQ1Q1d<?QHSdc9jmTYG!XeBLX58BHy&WF<\K
uISA%1 cXu51&linApDn/Blya&d=mwDl*:ZIT8mc@jF5AJRGSyLwBR5*Hl?My?h*%MM>uK+LGSDlwhAaX9M+Pn4
j<H1Jd mt+L$uniG!bSMmG?J^eLn*5bKeKF6*d8mA6D#L\itheAR:W!&CJA#TP$ekt*ZNp@ImDAAkdT:hiqSiLK
X>F%I< #yduD9TQ>Wt$?:!Y>E\tFtMYNjT<8c6<\u58qb\p!TSbTC*dTYQeu*m=B&dYL%t%11TtHJbQj$1=edlt
KQGC!h &Vk&#CqQhTZ\Cc!yKnJDA6mwyq<4n<cQH@E6*yQWXj#YPTEBWGtNPDuJHK&ZpHV!dbmPb@\BnaNF56kT
y!@XZB &<D\EQ#K?QEL8\<6dK/5Yn9u:VdXX#8TSLKbEBHwbu1t$H/RbH4m@SyDj<Tw@M$MF=Cud>l9^!Qb6e:Z
##KCW> #=ic6*tkwVbK6ZBQnuJL6LS6@kWiuaWe9:c&C>Qi$lVZC$DZ+KTY4QRR&TD6yeNy+98&lpqh5l/hIa?F
*Zt1i= d?HWA!m>SVQZQAQ!AE>*8ZCBi9&caGP9tlbjZWn@QZ4&nFn!Ck5IbJeZ?P1pYCNG#%DpFNXWdR%^De:q
n$EJuQ Pdp8D=HYbTj6P>GuALP?4pDS:dDi&?c?*:<c#9NeT:c=<<*D6tRGV\bG8tHd#wMdlb6*RyC^SVHTq<8/
NkI<5> hBwA>WuhR9TH5=4<cmi<8d!=uE>F!HNTTnk:BcXphiq&u$a^hS@MHtQPq4h>*X5nGM=\=uLSA\l#>n+@
aMB9FD bFJCIw\^@aMM@GYu>Kw+NRn1i5Np:L!%=Pt8!Biu>*AtZ^WPamuijCNa!5l#IEEup+i:w5ltSF?&RcVH
VVhbyC ia/6&%4HQY#FDduLip!*dT4>^T8SbAcJFydwJRXw&tZh$cWd4RhNaMi=yF\/bYe?bHIQKd9$*y%9c=Ch
lw@CjZ 99nPP#&8#@T**SWA8VNDqkkCK@Ly<G8CjPpb>?:Zcl/6XWEYRwhqSnGuaLGH/Lu9/q$<tt%HMdbpP+4I
Awu<ww :@YNW^=T+WbeDd+mAmI@aMF8>yaKPQI$QLy>8^RK\eB?MD6BJQ:jh!HFRFGI@&L9elVm*+jSStL?1@C%
-AdW4X 000b1bd645000110333 Page 214 of binaries1.zip
q/h#D? Z!KPwklj>l9?F4:&T&nu:hme@\ljm@t!V9Yu+Y9@Gnn%Y@nc:Rmij+@Y8WMe:j<=jP&ZYKEa@HiBb@?M
T<+ZDJ w:%%@S5q+D?D<t:hIQ+q@8tZAN^jI=N?m\*/La:&q?i&M@>b<Nw9pbN^/C>t@t?Bc@<c*HZ:HI#/G6aW
ewB<tM >dZp:hK?lVuhB9<baQXd@P&9kXn@=MGjpY*@bSl6^Ljw6*@<R9$+n9dj<9kV?+$wHI:+%?m%@&#+@#GR
/AThhh >4e1@#TR>ni?:JTIGPTjMYd@Hpn:H/Fnj^V?F9?%I?^+@X9\&m<666*pP!Ret9BFDQ+cL9idPH^Lj+4C
utaYHl N^H+LyP9\bt@C&#:VST&D:<i9Fa9^MuH$&YH<LZw:&etWIn@bq<S%Qed<cN?cTQ?:ZqV%I/:+KP?*<wT
cjKIjP lWD?t1e*CwH?BT\K8#MY<*Q5>uc>P&K^9+BF@+Bt*M?^tJ**MWEl<L?A@XG=lJ>nj#Tjl$IR@\j\Q:iC
SFw@tJ @Ad>Q$&5Ej<!5jbN=9?YJ*Iuh%+W?9>#=@$%h>+e&eX\M9J?MkMh?Gm&P^#P8ZqkZ>8F@/M:4$iAaQ#1
TDYtTi jWWGB6wb%<4P>uS*TFKMYTX@8<@WbN%^pYc9*N?mSaXAGmdB/yD+GpIjyGuR\HBWB*ujWBE:Y?<HajJ6
XPX>YL DwBkSd!cIi!mpYd5VjPH#CG5L>dJmM59ite\:CI8H^<1%k8dy#C$X<5QcmQ#1C8@Fbn6=alQCjj/pG\p
*ekhw9 HKS<cjdck6Siy*R!J6uJMBhnQDb>VYJ9EPEYLD/KqMSuQIm+IJNTN?t4%y8\d11J!SmEn\EDi/Q9ntGP
mKN\Kq WP=iN!wPIF:ilNSIpnWC:FRacK<=V86+ly6cY$cSJ8@H<V#D1&KmTuF\65b?ZcH4G+dBN8Q6$#eBikP6
6JAe@w 64t*dm&@4\JqbI*\1Th<uB6P^CBMDc/4e@6>TB!?H:DLiDl4/S&ReqaW^Cm%HulE%hNmGRLKhqCV9D&e
eAB5W# E*qih=:npR^TnZRZhkWTaiaey>D<SL$>t&wuQm6C/pLNPyYpcYJhYy?ytau+yMt4GuEd8YyTXMaqhh>q
JA/&J1 tWnh#S6TEZ?mIb9w&n8j%=?1?!\pYGKBQjXA\uDci\=yB6M<q\ANu+?qSyeRiYS<c5\Sqn4\/>$KtYNE
\kLRL/ 5y*uDJhQePKNuN*<EPcYkIjEJe>Zwqc1t$P@TitNPa4wyqJkS?Tc#NijN11?uH?H>Mni>in5Qc#n*tT#
w%n>NW $PQ5/uG6ale5N+IH$uc>^G1J^q#@!G>/TZIR<iTtp#%YhI^B\Fi$cd>@D1iJRh4%DWGK!nPBPy&IhJ=K
:qCAMq w@H+Bkl4L9aacePwdYnWuND^abG!!$Ew&c4VLZ=Mh*C\\9dh^DMG59V%^@nGI+=HXPK/Q@6ZdI/?Nqm+
cl9X?6 m<ueB/m<dtiyYHX1/6\S\PR+pDy=p5c#:Nkkn=LWqaELa>/:DqMLQ$y^DAMGWZF/ATK:c!?eEhwh%Hbp
im&nuK HX9*G!Pk:GFkSa!uR&HF#Dl>b%B&?LAIEcELLHkWA<b+?Zwyb9u=<ieQ+&uKlK8la\Ln!?j>+e=eJjN4
CS!/5W H>8LmG:XajS:8lZ>SK/qc?4:TVj!LdPtS=@Z4R5<iVwW6m66!5A>PX@m+wHF<%Ecpd1LbcmcLPjZe!$^
VtiAnc \Sup*<>LZu?aLjVT#PtW8Qd+e*1K:cuWm>c@u\@jJ&w$kDKMN/?4LuB*V+E6?G9:BpLM=iQNpuby#N#t
>NR+HY KMLwJ+:1*TPIQ?MVbTceQwu8b?wbp^S4/=516NW=6P4weLGWjGT8mwnb@%AlF/*GN6m9EWjVl/?&#n$e
b/qhy* jX4uFQ8MkA:Y91CMRp+4KI^Ryj>$>MHy!L%SPa%\1amF$1wJ%Sem=A1Bl9dl#N<pd#=\wB%^Z+J5QuHQ
#QJbK# +le#=F?4!#6h4Fi:C/u5Tl@G+1VK$DameHLlQ6m5KI\mR*T=MB/wRmu\QNSiJu@NEk/C$F@KNHCPw$9*
YW=%=\ M4b<tqR!>q6kwS=ya<#kLuZ%qjnXW6!8&$FE%pAGVnm$a</?<cPD^?\8?jKSL6Q:JPQi^!$Xm+<lc8y4
d+B:a5 RCu=pty^*niDVXRGt1p#y@MGRNISbcd?6+$888jj99*Y9^^RcJj98d\$PZD>VJ><=jCqp?\#^ea&9auC
j^im6: JVtH8&nW:>nAH+heDFXRYW:8hbS?F/GB1#LR/*8m/tEW!hQtZ1F&DTDtA+=8!?9!QMWm:qT6ek+y9hjD
cL<:6W Rq*uJAn=iRl+#w?8\P&wX$+GdR=5pAXeh<na\iaKLuuwFJN@kd9EHT5kSpCD8eKqNnC48Q6EWIFLln8d
EDmCB\ /hZKpDPy%uIi>DjZX9iaGX:LDG4%GZ*ujWqy6>6+BDc?EMXtb*uu=Y%Yi@*FlHhc/#+Q:+m8Z:e<8B@Z
a8i/hS Hd*L&b+6AkRLH$mkIV*4H&IHqIy&HLlQV!F+Ht^9WitI<X6JPYldQFI:DD!=tEw><1^#<1DtWMiSw/P@
9Ak>a? 9\+itF$S>LkSbdEJI=Nyu5/8Gku#EJ5dL^qCHFyDBhXIp94LHVhF1R>a#CFTDqcn4&eEQtZNS9whuLRE
4$4>wE #BPw$?pJeFBQc4QMpkW8>?BGB@<qLb9XjciM5L>dt!ltFAY6ulymVyj9PkKE#8*X/^?F1Xeq*#\:LldI
i*L<Py yJb4u@n\qeCHcqd4mqhX\i@iqa8Dn6^i&ZY>n@t+S<EnD85%#e!RZdRT5Y\SbFM/6VJIAV@J@cB/+SMX
G#ELEP eh%Ztb4ImFI81MdGKY+w%%NyW@614ei@B=VN4Y&5ZdT\^RjlTy1q5\SSYp$<e@l!/JqhN4/&J6I9/RYy
*$?SqI Fab*yCj$uQ1PFPhXWe/5VQ+@:L%%YF^L%n:cTPQ8:8+$nadk:8+RQLl:CARN:k:B*S$T*N$%RHCZBE$I
\htAiE RT=ub5/ePbQpt*#j?i=>:9$>6@?k>?:NY*961qY%c/%c>T+%#m@G6u$:SP=QSKWP6PZH^>Dm8i:*nd<b
E**jBY thy>IS8\mITBG$yVJ\hQy%%69>FL8@$CR&MyKm\id4^@9AKD>%DTJTT4HyN+FE\hQKQmB8t%eeTX1w4%
84>uIV F8e>C?NqmRMLyRBYV>C\JM&Mk<qkVI!u8k%CX^Le1ySGI4hnadZWT?w/><1CKi#RyLI?Sjuy$8#wuQ!K
CFXN=M X/NE&kpqpMI=u&Y5EKB*k1BL9pAdDnFmAuND:!&LKA+*Q?qWWdu:YL=>RTLwF^SP?PwR##c51W#qI=bE
4ERF1H XN8mE*PMNY\#%^ea\MidyZT*Ib9*d:u/8>>\9HWG=FZte+56jFDuq%hKVEp:Nc>Rn@VeAu6YiZ!^FP4K
bm@1Qw FRY!HI&&!Ad8ZWCwB#pKnw:1E^<T8m\JS6wYqYCXi?eK**/th:L/?BwKL?Gm8l\*TWcy&yb/!JGjk!wy
jGGH$D Tj4pGb$!W9/<Sd^PMqlbBK:^ZiLT=$EHKT6$Fyh/FSB/!KB<V\<Hy5I$*jcWIV&^ycGIdLLlB/tF*cTb
jIFZ=% 8QDk1AcG8\hGGXS1R<GRpEmcSiqQw/#=\eww@6NWLEDW#k9Vb8u6pBRkAdk##A6%KiwA=RG\jqyIwYGu
k6/BQ$ A\6pA6ISR%J#R>Eid8SJLJ6uKJ>e4wXlWBpc/pCSjR5RpJM@Fh$?qP=$W4XDmtSn81APj9<eW6Y/M&kp
M*TF$P R^tPK<#RDn#5w/?pF&eY6:db9!*iY8BkA\R1>A%pJ\XkyWF>nyDn+RcCnBA#yQQp:ET!>i%W8Hc+p5It
>cCT?d \YJJwjDJ!PPt8+FXeDdDZpyT%hScT8LVWn55$mMa18NaTk1S!Hb^*QDH##:/%:HD?dGqmhu=\\BdWHjl
>X66?X $l$TuPVaaTPtnR+>nHibn5!kVS^PpNF=VCYpBI&=uF+4BE!EBIhQJqG8BFYR^SS@Nq*@kNlHkWJ&tCtn
BJ@JHX ENPyhD5eGL+jjD5Ep\4$m4LBm\mNm$QkTdi+>$DK\k?M$wd/GCXJb*#I=^YnF6WZLKAERRAZqqe#uP:a
Vj&H*B RCm$&C*Z9CLX&a6\&yR4D>EnwWIYntc?KbY*dZ=R4VBKeYt>#qCCe%:ik#?Kw?4w=DX^1<&$RF\ineM+
nDPVGu 4lhnQqpwDw%Cy&4qAVMET#ETuC\V<lcJ=WSS1\N%5dG*Y1455!R#k>M^\M\CW9Z=bIlXmA@/njVB>6Di
YSICe9 BK=XCA4VK</l#c$<H@Ij:4WG@SYP&9>6S>q@=1+Fkht?N$+=iL+#Vnt+j>W+@aiSAiLk?yGS?n&JLik:
\:@/NC Q6nj@Ca@NH<+@#Q&J+HBwP>JdH>\*=<am>>#&Q+A?&M!SlA:#*@GeuJ^@SnL?\9aH!hCA+HajkH:E+Mi
qe&$^& ^Q+LYLaj!@\>1iu*&J<EBwP?J#Z>AjdH?Y>AwF@R1=<ptRCBjpG9\D@PG\WC@aJikZ<epA\C@aJi@YRd
V4V:TD NAn$C*4F<YM!SlDwF@V1y#+ID4c@A9+F#jwJwTKI+^e$m@QHG>%BHB^@AR9?C%nPj*Qa@D8BNSed::<S
5w$jdy G+L?leD/>#H$#&X!@ae!@?pEa96utj>$hn/Y!eZ#k#K=j=ARlIid@j>Ga5QtWV*iAKKIGmm\WKBcCPJk
$^6R4M D=/aaeqVIDI5tyebuSCaKEK<S+66<VpV9t\kWNSGBJ1*YMRGKl$:tNmkI8WEKNw1yAVCTpSYltRGaPP%
MA#b^F ml16=+\ttMC$l\hDTZ9$YyDlDEp+le/i9*VLRi4F5lJc6YP9FTHH6+1M5RA>#yqNW85#I@YB=mXJDp1N
L^=8e9 $G^+&klJ&e1@ySEl/1Q+AMk?cCFARHyTE:P6bIMX+ZG4\I&c&IEVeW$V:>um^8EjB9i66VQ:cBTLRC+V
##<>mq mlZNqH$H!b5p>$AyWVlu!6wqLGE#XV^>HSb!w+@Jl1Ci9A/8wkEPA!/AR$wFd=+ePY&qtWW1RPldIFw/
hQht?C JBHdy%5wmLK\e:915nNwkX4PTGjwWYc/AJ5Xd8EY:\@B+&m18MkBl6QeTB<yE4ARWCkdTN11QLB!1JF!
GR*P>y !iJ/$QJniwLJ*?X*BEIWP^DTdNRy%HM1tWDnkbTe4dAR@PTM\V^?bh$j8Q*KnhtD!D8XRjL5MTaeKCnN
6#&1#X S4lXG/LDPQ&W<cGMRFVCkKj>HGIZZQI#y:w$4bVaeFn!eH4>*C%?MWyQJn/?bMBTmZ<5/m&=1LN<$<XI
6AE69/ eG@#S%EQR9H8kCd^b9anD\L^Hk=*D6Y/MT^<JemYpB$%FKWXpCc+kX&<d#bmDq<hl?lBc?+a:Et5$hDG
t+q#%i K#<^nVAqumQZneeAF*Nl&DM!Xy&8Pnbnl58llqY>59<Wy>paj^yqK=FHM>:b%ZQyWnhSF%mJLP8q6SFl
kI$R!w +kLE9Il<P64qM5INy:CLc&&Ikp#9w/\F9mLt/Sq#&uq!qcHH#lQ9QF\ilD//SVmkYTC$1n?H@MZLAEWD
1*4>NL ucD@1:4HqwbcR=:Z<^\l:hhnX!mC5m&^WZlaKDN&ZDmnm^yB8cayKJu+NE$X%*^djB1<8G9#djXABD@%
NWu&n9 Zn^/h^cM:hZ+=eVCKbeG+RK6!/R8ZLq+<PhJ8Sp^Qj=QM:*/VWAwt=HmGSP/Lj!Y=e!F=wPQt5nXy%H%
M4jPQ# a!49PSkVFjy/!uII=BSSSWeWFatt6=VH^W#GLatCmY8KbTly98ah/14l%X8jI^EEY<ZLR+yPQ9pEbJWK
n%RMn< qQNjQ5t#wa@tp!jnR&4NhB@a6F%Z+wq/?#L@nYiQ^an:nP&CIcXWY?:%Qh8JY6LRWJhLNpEd1jQEPmhd
eaNV1^ 95^CI:6eB>6E<qHaTuJ64njhAY/S1+Lu8K/S84^SJuH9cNue=w#Ly?9%N!aiKQm%9uLDZ>XA=%YAnIBC
dKit^Y ?YGZ%TdXmH^yJVyalq55KCYXNkL<X8uJWl!wEG$pub=$VX6VYtJZykiC4m+XY8B8GY\YBKGVubj$P!JG
5d5Pn> IYX$+R^KW:IlJB+NGjhMB&e?^J*eN%l/Dk6=Dn!X+6^R&T1Lk?me$wXp?HkWCW8c<CXmB/+:pK?cpWK$
-ASeQ6 0008e8dcd2d00110333 Page 215 of binaries1.zip
Cui^A! X>k5X%Fa5j&4w&VeZj4RH<C9Hh4W$>ll!ibyMk!hWMm:EFZDV1+lR:^!b>+bSeKR*XVFNSHJ^LC=S?<9
kk/=Ry T#4liIYSB\IB:@EDE9R\VSGiGJN>wQh@XWBtHEIHB+KSGaHyj/>$*ky#H9hEMpSQu44ppN\!#cS1!LAK
&nF#4a 1%yEL8^$QaM*cYtyP\uyheRpMb6KFiH^G6X/Ntei<FBp66cX*QKhNbS#SDw!FE*E*656miRZdQMdQNR1
^DywLG L^%yiWNTVQtyklmBZ5TtF#mF6*P<mPjAALZScAW&!ijX*wiFY8%SWY4XMZ/B:JNT$Ju!Z>8RN<c<wVSB
ue=PnW >ka&kiGTmZnN=51a84h?Pki4>DFT=eMwN#hA?qZtAFH@XG\&6+JZ8S\T@9JQ6$#6BP9PiVE&pbaK\GN5
h/X<%E L1ajFZwZ<*AR*Q%H4YLi9yN!JL8Y6y\LhWt9%^9ymy%?Xna6R&?FC%F//FXSw=Yt$RC=nLh$tXQ!Xp+>
K+yMV^ #NRFN@i/eL4tTa?JX#KEQ=@^*BmI!Ky&YM@a\WR+$YbC<pnA>H\>K#?*YM:mEtuKRSZIn4chWc1^SbKk
cQ#kq# <M#cRJ4ShIWa1^ePmhXlXRiklH!CS&e$6at#HFeaFh>54?tc9%NBGh\b#eBTY+JkmP5MyD5?QyK\Na@E
=k@+ap +!KL&Cq9ww9d%W?Rj5H@$eR<TlZBYJ%kDGS?l\LEwSc9p5=ELw!aEbIc6m+/1M$&*^F\WjX*H8ehjyCj
j%%P5J *Rhmq6A@p%=BwQX@\q>:j$b\MiXye=uCeX=PBF*@<PINRlG984=IlyBhRRaH\bM#lM#CHcKwlNw\u5Ww
d^%Y=S CJ16<9VMcjP?#!JLlRh88XMlDmm\=EHDltbwM\/mXSD+p!NAnVb+Db#GI4#Jii9=1MT8V5i#DY=6luEE
kHA!YN BSC9uC%9jJ85m&i5<&%McJ\uR:%^6KHupQ\R=Ak&=d*M>6b=!Xuj4h4%pR=b!a1%nNZu<mG+TNWQ\+1u
uTHQCk pBX$=ld88DunQHV#pE#=imYc:S/^$K!MSY+ApeN=4$pi5w<<@Bu6J%\lE$MjBFW^<=KZ<X$ywKF@bE#?
$W5APD tYQ<@?p>wcA@$=V@aV</Q=:JYyw/@&$V=>@NQjA@%!Rj4WdZ9/>/I4QKt=qcG9*hZQ#dR9mnee#NC@4*
pA@hWa cSKa:V@i=9hbDkn<>!W9EQjju\j$n/VnHP^@u?J\eQ#??>@q+9kHqSia:S>bG@+RpQhj4GCP::P/k<D5
tnHZ9> @!Qntj8:#C<k4q@N@QL:=P#j/?j:1T?a@hh&6aK?b%:@H95#w@q:+9Z95V<#t4@uZj<B>miG@9i</>>n
eEa1w4 PZ>mGH*Q8@+DLQiQVa#9ihh@kPZ<me!<9+AF@*lF?Z9i>S>kj=!aFQR>:@wQ5D@iAR#m@AY>?6pKPmjH
iZYdHV Z<D?kq/BPZ/5p=!@wFe@!a\B+9\F9RL^@PT?9/BZ9@Z>H&J@Rc>AQ+tR+Q\F9j1y9e*%C+4F^j%nV\+Z
>/@Xd? ?%@Ak9+C>qeW/!iiHC:\Z<B!@kW5%%@Ae9<F:L<q!Qwh?X<ElQ#Vy@CdL+D*?\SbIK+jJMkCe@$jtTH4
yDtcd6 n:!ldQ8q8RFG%VP=$\nI@T?XX5#y/G^ke9$FRp^cXyJqAw8FeVaS@IWPV^$$MJ\D<SV*8iAhNy?\Nim!
C6P<qH +FK\VTS/BB4cN>$pl<Q!SEhbcKBD1Q+nMtVXSaph/+M+FLQT!P\Kh+:%=Z1#*idly+4IG!u<1wpILCJl
891!#a Q/mMHymean*<6tlukwHYmQmpRFCZW*bL*T6Xj9LILa9%&TcVdBYmIPRZQqlIwqKL6$$te9y+1M^KX56S
aR$89Y b:$t^EFRwtwEZF599LGp+5DRYEk=5t/<uMIyDqkw$\ubc?Dc*J5bYXGy%eqk<9#PDb=ZK46JqWjGQLH<
P:1e@C MZFTBGSG:>w#k45!tQBlpHVTihwh$W\\BMbG*AHBa:%qiNJhIZbaTJRb$a!NCZKJAq#!X/S$RTYubnST
:HSl<Y $/%65tBX6mPb\R1Xdm#pC1^K6uyR/\8F+T/^ay^?KKa/@Ic#IC1e$dq>bYw64NG1b$Z#V+P$k1CI>bqu
&/hJJk ekwEneVuI/4IF4CCa84tJ<a\/YdP&y!\bm=DlpGT5%J>&5H1Fel1uYw9k\nHMG?lM/9KJ$P?IT4H!&wE
mSYj6$ %d@WqbVBd1%/yZ\m<%K8W$%YXIjdJTI/eQCCdSS4hBGeDS4pIi8JXA$>NebCkbC%b%Z?VGu9I1TNh<T5
X!q<1P 9WlhttYkPCL:Pqnt^ejIqZlRB!p+F>H:R@?uYd$?hjbZc/yBaP<*GjX=?bF+#&cAibIn=DbXhN8j^pmj
FjwCb# Nh=W1kj4X/\PlC<^M#1Llb^TVVMA=Y^8Q9iYZ:b?mMkL546D1p>wB&%5SFVl!u=iMb!h!YtS:dD!p/hu
*4:<ND hkC%QGPMYHtVV8/I>W%We6ew*/m69nbKMt4ach6pRDwT=+^!/KtTe4*1B!thD+P#c>yGX<5hmkPhinbX
=IQQIA a>Qwdbbmu@R=R#+$9tF/QnwZi&G@/+F9ZJd&=eci%id/<@H#8G&jCSi&ybaBbCpkh#F&5=%M<Q+*:ji!
ISnEcb *594iDT!4^wT>um@LGF=9HiDTjB^cJwaZ8AW&lC4@YKikpZ+XdjWlbCbVYX5V4ZEn*WJ&E#:DQCMAlJe
5XLcLG ^89Stc&X1CbhyeM!hFAFI:GJPn$IW<4QVpAH8CQL++EJQnpA<hC6yiJZkR8ui15HdT\TZp#DDNdj65&?
%@T<WF SCS*twRSY9uR98D\K55@#VRYE1uiIm#C!JLXy*D&R$WIM$y&QKZWSPwqKdRaE8LbqhmReHSY\tnp?:JG
k/1A61 &iL4D\$yNMtQDSQI1t*M61/Tc/SeEF&6d=H8:GR:mcAb5=/N!:?8lI$/uKXe!XqXD=5Pp&i<dYwHjCd>
!CQ$lL HC=^P**dEttWIE*ykt!hk%ib1a?DEclt&$QuIWm#mpKcH=F4=lTKhB^IIJpTq&C+ZGl&/MM9X8KXRByc
=q=E+n kEVVh5hRJEu+ly<+@4AR^I$*tmW*+^4tAKFCwCGV1<NWLXPNAJX9@BS#/LKClmPTnSQH/&BI8n#JiWkl
A:Cm8Q S$qybJ+jNSQtA+n?&pNhn?lV^9BL8pEapRyS:\$kWp*F\DYPa1^@m=+XNRQ>1>&IPLp:1=tCFRJNR/T%
ZM@9y! 6\Zbn9R/a>e+:=PF>VI@=1LRtEiq?5*5CNYpLNN6/tpP9V><Yua<uPyk1EPyuIu+c4C$wE@DVy=A$:ac
ZdJBJE YVG4n<@T%PwNEQBiuec\GRH=QBR88K6@KEAlWd&iRqDbQFHIFC<ic\9cT=thRD%G1RYinR/?cy$1jWiR
wQWahY C88RDjFXaTyNZH:d5Ah9MhdyTH!cQ\ID5ZmAYI++GWPCn*KR%HNPLwp8+!5a%F+py\mnFZCRud4cN^Z^
DAbpmk C@#alThE?jnluIITRZm\R19=ccKK#>WN^wFp\%Q/mDT/Kyb$V?tQ*?$/$CGM1dEF<td*^^=Gw!AV^!/<
EXWSmq 8&pL8@Gp*XDJXGMIRXdbuK+y<X:651dKFBct6P:M^1N!h4hFdt9Wp:b%i5$=u1l&%?pZ=4P^>CSeQ*M/
G51PQ^ XLIKnW@9wQSq8j^mnbXQ99+k8@6a&/blCq!YkXiNq&%dul/m%be!&e$YM15\yVN1>//9l+NHbjeF+RLD
KSctNq ^h@8=I:8ymJ^pN@TTT&<5l5N=ySI?qn<4d$9<?!8qtjMQ=@c=*%=wID/Wc^DciHee&KwFqqM+X*lZw?p
Vq?95G /195b6X>WE8=d%!e!nQj\=iI#EiD69J$#FJjuacL$/8@%plH\dk4hE8+HBmhBaWQPLC6m4?k&5!uMNiK
Xh8GBE wbpw!qbCm#^uR!t>l\/PYTqCZk$$hTn?EMTb&W!DAMq6NNjYnR6ui>wn\#$cLbABS?t8ViKiN=^E8>hd
?yN5Wt c6jN+lj*mbXXlCH$KZF+mFh=FDtlR$VeXGNIu9Mmw?\Zb>%/%TLX4?a?DQqX4?LcE5F9M%Q>V+6%MC$J
$e*ZCm 1AK*4\9QujL<c1IWa5ciNwHB*1RG/\l?K+FcAY\?pNqYQEXE&#G1KaHDAG:cwI#+8QkTGD<H#mjRw&u^
W#?^pW #wm6:1p$hITLPb<mL*XpyBnwLY?9k<mm541XjbEq^LIkAS?FltQpwTF5YBLJB5ZnG^>kZm&&!W=D9=m/
ni%>N% eci<na/LQ%$WkW!Fa?/q&py?t9%C%eqbkd/ND*hcA4q^Cb8&^iNLFpb?681^bdw\D&&R9Ewljjm89AXb
4L+F5^ IEcqbN4I*Y^jjtNQi9#qK%eWDktpSMuZ%K#IFHt5Ewl<!qqyZMqZ^+Dn^9Q\MimBmFp9uNbT6$TClNFW
/66qHE jP&:%JIpbS=\*545+Wuey/hPnFTqC#1T4+ERjiSCby/PJ%9pGS@S%TbI\WZhMcwYM6Nt&5P1cMcF^nA9
*?<#IW WJ5IeEehR&1GQ!^jb?SHiday/uQV6XeF+4VhPC5KC\tHV1#aP^$GDjNcIh#TFh1lEQb<kWXu$JM4yXXk
tQ+etW <d6iINycCWn$b4qW@C4E<c&E<qMMm\Hp&%Bd=n*TVPh&%+uGKTFyatSB:/%6b@4Q>8u!iW<6*=E<q/yN
HqeucT LMnW:nXE6tlNBtdKBB4PF%XK&H\&NhM=j1+*L&p/YVBaWSAt$i9!$HpiY=uQ+u?<B<qELR16\H\CZdHP
FEH/He =C>S>PtRjtCYKb<jFCnCAF<4$Fu1%dtP6L/NSDawIRuPp4=9pVVW/FYS?mTnR?qtL?/TBmitMkdVPyy$
En:hi% G5Sn\uKa5b*kn!akH!QGY?t!XLY/ViEpM%dL1KTnlHw/N6dN$SuuBt^P?HTdTHWeRC*YLSa%Kdu4Ci&6
Hy?5V= Y+Tm9VMyTYeKSQQu64@&L=DKyAHAmIkFMBYkuF:1\B%Y>Qalu?ANYSG<PtH\k?tB&B&paya^hXmMFXWd
VA&$?P L</8!jXYb4VR1wHFPAtJ&!\hN*ecL<bwYXecJ4PT&SKT&tPSRMk>DSEaR:B:BuB/J1eLW#\QQ$cTM&\A
T5+Dmi BFddDDPA5?eqi!56yDhS4A$ulQ4#+MYe\^DAw:quMwhCC9h^6C!1CLutReF%i@#N!6Z68*Awaq/CM9L+
XqEYHT nBuK^:t?yc9t\*\FFunQhkbV^h@n%CTTFk$8XuEb=/hwljG<MeNRL&BH&K:P*wQJh!IubeDTS:^Q&<yD
a?9TVA ym9CGJHEqQKaCj5AGa9m^\+n$jMNjbkLBnk:G?tK=5kJIbXkbK5Qi+KVcXd1^$dHYaGM^m/NJd%b1:CW
abW:G4 CWLnaqiyGHM^yeFBKhw6Du%Jy*n4R/6^SnX1F6nP8TNk*&PQj^1LmeFq#Abnad%aCq$1%^uD*X8F:aBK
+A4h:i DZee6CenkbR:b4YGdj/M+knlKLRi^ZJWttW&W^Gi+bYh#L+8St/#*Qlm+HHM8RTL#QquD%Gj/Ppkt8QV
>:>Hy9 ln+\8EyB%l=GdwIKJY^/H!mW/e\qN#=aVy<6T<*&cZm!nF:uFAFHXc\KDQ4CB44Yw5>P!4cVt<4$j%=B
hRhd:K jC+MSb@D1TKI#wGSCdiclpw%GZHGct*wc1>p\AAb$4jycLhmei^HlW4^ht<<dhn:!RmKI:RltF=8FKDM
4>L>K^ KAMZT4&+aH&F^jSb>WBFN#mL5he<c5At5+KmRK\Ew^yNF&VQd%H9JVI+Y^LTVQ&G/imW5+Au$Y4FIj=T
X<D6At tT=Rd4DXe8l!khJKdR^P^?R=Q^ccXKEwX!%Z:t6qwjKpkBwKIhZbIHEMYa+6$SA??:/my=StWMQtEYWI
N<%>q= MPhklQ*mnBp&X^kHL84uCH&D4&1!M/He=EK>/<Fi*5ElWyKBDPYtjySik@8aJHu8^J?$u/wMTQZbbB?+
Gt518^ EwtbS8ZuiqXJ8hJV<+RIcbuLPLk$c4p+^ekI!Lm$!KGlTXIFTWuuQTuJ#91pTZIyXqj9Lck</hbdtcV1
nw4wlB IYF61E\VLRWEuRba59m@aPp=N5$6+\5JZqVbAMj#GIp*Y/#d/Fp<WSpwDT#Wim5?CFPw4$byF%TiL*EI
-AiD$8 0001370bf1300110333 Page 216 of binaries1.zip
#bwlPS YFRBBMVX1hF1Ky>>bCmTwi&SbbkGkPqp8BJN=bAIeX^lb5R6NimQXc++TMZM>YGeR8bicMJy%CCECCb/
iPh#i8 %W9J1papc<R#!<Gbc:t/cqpb&M!^KReNKX^\TBaJQC?Bjq=B1^c&4HaqpqQ$RdPRXXtW:WH$GBtW\%n#
?qQZLk BL*Y:nYa\d*8w<!Y#mT6nqpJuGKwQKa<HceWJ4c4M1jhX/:iyAW%N/6BVF^DB&/4W<M+hG4yV?k^L8&V
*uB8KB %*MTIl^IF?k%uFVPTCXd>8l^lk51<^KkdY$eZ4MVX^4pADE/DPSSjkhq/NqaMGeNYBeK!>TY^RAGS+b#
5EtXk$ P^IDnET&:qEFF&M8E?WGq^w1dlHy4WQ9HT=i148?HpP@HWXVwSVCqwJD4E+ywu5FRXdMLN+:@Sp1=4Pa
IcAZWW \DZ!jcm^Gn64&H4F<Xjt/@9^KN+kI94i@ihWVFRm$E#hp&JpVt9&*lAm6uam#ucS=?\KMF@w5tt49L:c
4ek=Hy +jCmhXL8PqEb!=CJ+XHLF:P/a#FHtV<^uaNGKWEM*ED5ZXiicJFYDHtc6\bnZEayXEKP#p89=PKIlZW!
RQA8&j C#L8DV!iRmXDRqA?VCc%KSLw5+tY#wPa$HE:#FBth?P&Kyd>Wm4weET$HcZMZSkd%\t#H^idd!mIX8h1
QBXl4A HFbad&y\/Q^Edpt^ZI?n*<hck\YI4KyId*y?RlWa%G\pc6jtEkhVVT%+1KaXPKwP6HQalapB$wV8ktIZ
P\FQRI pW^jR<m=ycAk#yhLya$MhJFy5hWXp+8DkLd?cBHX=l\keEp@ZCtbp&LyN4hW1jJ=9Z&CV*p$ZpD&RDCq
Zi/TV\ #HtjkI<>uDat4+pdwuc>8>=lq6dMk#Z<JLkwmNem1VQ/q45=\=EN\YX+Yt:^NXl!*&nhuP6epA<P:/Gt
CPR\\L &=GG4qhW\4XWd!D\Db5YmX<abRlie5mW65Sbq#e<A5iY8ELwWSnVuTiut@FuuIHAa8?SQJ#eewM6dD\G
k#DEc$ h#!Z=%EHZ=S&BHKCk1WatMu/c%%hiHKu1n<inP8cnkwG&MWY^yTtCnTFbbmKp?ZJiyiW8TdATHy4C\nC
wBqLmj JiPa$=J5ZXw?X!bGw=ceAZkNa^QC<Yl#>JCmN^Fj6?cFLKuCmQT\q=Ghyet/?$d#En^H<PWwtcA\b&uR
hS%=QJ jPCa1bAAAyXD=qECVR9/\!Y8W=MaMYD5CTuN+Vt@&nYq>mlhN@9mC:>?Z5+Xkkq?9BRV+b*TudFZpAS&
ZMiMFa e<*VbHYe+m\1%:k\Qa&ZTqWF!#Rdlu&m=ydlp5d@KuNDBJ+yINy>G:96@b4DT=?*PEQeR9pm+M*Z@qB^
mmle6e #V#iXbR$lZMXb9GLcmZNLi&?ydb?E*FaRwZZyF+lJeyVkJ!qq%u5:1#ZJ^EBYK1:6Zwi<H:^uq4w*Xt$
FLeZAR ZlJI:*\TAawBd1MK%<wu6c&Gl5MWPTR:Wq1NGCWZ\qT:BuKhjj=Hp5qdiTq$ANXL>%LIG+ehmXAJPM*4
4p*6\l CjIKcV@G>#dbl8dNb<X:yuJ>wyXLWkaPB=aM4>LFT<$di*$C:ZV*<mjiV=CyJE$d>54&h?j$mKKmjQXG
kH^kDu lZ<h*&%9JynFR?CI*u$Cj!kbFKJ<$<>RFFwu1TlYhlbkDy@KW=kEPA@TWQZ:^K<8#Ye8XhJRXJ?E/P%a
WCV<Gy jBi?V!$<uj8e!6D+!myutWLYhb5^nnMDQ1ekwjeK5THncMX4BlG5CM<>YAtemW>lq6N/F<R*9@LD4eMk
dk=\Jp :9?e:b6X&6dw8buIL!%t<bD>:l@:%!BJ6h?&C4L@D>c+@y!M+8@dlS<L?/@&FZQ<ceYHm?N*y>69@!9!
\phM\V >@WhdnJtDna!Dp+!#u<?p:!Sm=Qq*%dCYNlA@>k4#Q\9^@w@*/HM@8i6m@@eP@l+:dj1@E&G*+PA@4tN
q$hnZE Ge#?:>:CQ/jP?PWFLX:\h\6c9B!@5KAqdGhu:@K*6V8i9>e<mJj6H>@5@%\4@N81%#@epQ<8:9iP+H<5
hE#uuW ?9*uqc99p*X<n@*bm6u*!V1?^@=5H?Z*!V4?G%n8Z<D?PP5NmJ9uQ&M=j:Lc^5*:C%n\n:E<dL?Abj@^
Giqk$m <*:Q<@9j\IL?M@bu?#h=jpG9\D?::!@wFehQFnb+jpG9PDl@k9$F9j4yKlAQ>@?p**P\j>j9Phk=juEl
>ZIt&& t+Q>l%*/*&mD#b^h@na<eQ<Zc=*@pQh9k<t@n5N!qudYj=QZ=G>q<QKRedB^@!*VEej9e6k:tbw=@TQ!
A%e?8t kP$:WZn@S=Z!V=:cQ!1Ft?6ZK+Z:l=Z!d=#G9%eK:*eL#@@hTkE@n6!@Xey9uinZK8ZjKJL@>$Vl=Z%5
pt\Z4N Ip+!Dm:&9$u$C=L<Y$4\*>Z>9%4b+9wnJjn9?9juMnq?pL/dm+*6@^kPaXQ&%kkuKHbyq&KbRHV##tK1
cia!Dt n+$IMRPBWEb>QA+<eSFYKnp&:eaIYWRt!tMc%ca5leh8V8>PX\Zbjq6yP&^86k*JY\kY%bpq\8KyRnLV
9*M*p4 /a4I6wWpmGTE*CkRnY$P^DJQ+?*5n%VLW4F+TTAP8\5tGJHwphjcjEXRi:BbDtRe>^I+i&hZ&q\FA^FR
RTjNJ& ZMMWDyy<G%^t$h%TDiF@DK/8HqVm1DS1N5hCRFSn/A9KmYDE1B5DaE%SDC$lHHHTZh5Rq4Al!H&m6qWh
$QL\+5 Z&t!PLaqwtPjMTMSb*qm^^mpwFN=k!DCu$qN6/WT6m+a<A+tD#+H$MlT*EQBSFR!5c^B&JI#CkZS!uA^
BJTjMl \nHGB4eamGA9P=<iMl!\Hkpe5>/QWl^66tZmNC4q\ahB!IeyL^:n^#8l@a*wPM^j=k!:R4lbmbmn@Qa$
<iqp6i WhFR%Teu8BknkkE8!5I$WRR4SaptmCYD+T%>V1eT=#^=PeQ\nK^VPpLWXZk9F9KS9A<Y1DL6uEiVee^m
F1/=i& C\mXGIT5Ee&\4BW<W5cINTPK:hV:@ql1\ImX5<>$RJPhPNWMCJY!bmTT^/c1m<w=!8m?iQ!mCD%Kp>QX
R>\c?u XD6H@Ml=TeaGDF:k4EM+tFEGV4kdREnkEC\$l/\>E+RRD%Bj9V#Yc<nLGbMqcect<FV4DL9ypYa1#%Dy
AHBS/8 AwIuS#tRGtPMt$HXM\mEPpi/cFlII&&e:w$=R85<BnW!kXlt:%5wW#/WcZn15TA1iLhG1phIDFVa!E#n
T\+/=% #a@ewjXYjh$NFYQqP4?\uW&LC6hl=W/c^&Y^^FMmb$Ydc^^b%4t#+WF1IqINPETMB:Ty/8BA>%6/a/+$
Jl=Tq& X<?HuYWA&TbH?ZwIadD:6eL:i>+hy!W@KV5nJ9H5MET*RtMAK6kRFK8Z5eTNZPSEk9tYbLY5M%GIl=<Y
Q#/\Cu :RZWunt\Z5=@mXlA^^9t@#K1kJ:JXq$8nQ:cIZen%#nHFk\Ge1:cwm?CFQ&cQEa!Rj#jeEWYCLhpi!Z*
F6d=+Z 14T*&hX4BKIk5IJIeQ5cujVuQb4Tb*a%#F1^aCk?VyD\aZ6WS44le>b9la?5PXwZN@Fqa^$SP#Gw$It^
&dKq5d =e!adp=J4^pmuZIF+/DD4w^kATH1l>?=S8lBIbA=una$ee&h/lGjel5\m&Dtkn:BLl9!5EaaIdJ\wmGR
@E6Yne dHWE9T4a=?i5DE/4c:S%bA<X&\PmaIeSGFR?Nijw@kDR*yKH&bq>$nNZ1W8!TR<LF<EuFw?^DFGL@Zw@
4ajlcV $nn=P4>mibVT$a/@Q1j\AJnhZaqkNMqh4RYy$=YiJc4<>q8H%BuTb4/81Ay?Whe%j<lGkyL*cLe58Vl+
K#wcJi I\ySPRKRT$tiS%L^b4mF^ap/V%^1h^8h1CA&i:G*=m&PCatcYq#pS\&Y#//aGWPid8a\V*P!X^i\>b4e
#5<$L# h+dRY!pJXuj!atBp4BmHyiyIA6I%/A8/Shm*SC#GGDmpcEyEwhS8yCEku%DVZZ+e4@eSRb+1=k:$eSy*
eTCJql Dw^D/8duQ&CuJSQLVmk/X/Md$n1kVtmE\#l<JpejCe41Pe?tFdHlq+\yX9y/DIibk1CRVZiFFm<ylut:
V64h6@ B+$AL$JulyK4lKHITJNS&:@+BluKBn4/$APIB*&DLJ#CVY&cWSkA/l=GM&SVn/nG\8<Q?\B9!C514NjQ
l=9C/D ?L#=QPc\:Hq$hkP8hp!@mSSID<Z#NtYAV1e4N<%1Vu6AF8MMc?YymSXhTVd9/#&eLBCqdq@FIFm>*=!!
CABtMF N<SuQ#Ibm5HyJm1nwl#Bm9phZ:pJ/eGM^lnc8?Dld*AB8mQtjV5w?KaCC=QFVCISb&5eaTaGVGd/b8he
KGMVEQ %a9Q1aFS^+/\5Mya6SymR^<eKRP5*9dIBPBN+PK:lnI@4b!d5#pdKZhnJe>y!!XV\mW8F:A5tGYBVB/6
@aY!/m mGX&EWj#&S@n=aShw9bA/u8H&w:bwG>d8!VYtb89qc&EI&eW&pK>Y>dYat%Sihj=9GH#E=ey*aDl#Tm\
Jw^K$! t1=jY*c?6*D/wVp=ep$w9L?I4MckCLC+SHmBlw!/Yh^IhdC++qYQLGiMIm4V&VB$W+b6^lFep%Q#Q5AF
*kXwQR nI?#jN:HQe/hI<bJHCG:E4PuIN1GbGl1NBwJW$h\tY^NwkebNDPItyy1<KVY&PmdZJ@hnu4=5RBl#b%4
R6^b$h VeF/t$Dnc<#pJPL+eQ&%hWJH&\?EHekL#nn%Put?wI>Q9T4**%X?<ct9qtd5GpleBQpQ+:K%+\>a6cH6
=jjC%p MAtb%KC:>ac<^6!5jl>&%9Jm\tMN*/Ve+:4e$XuRIy/eRm:W5H\na9lVCEeF6Y&&bjmSV84V+jw^cmT&
%+TptJ ?<!$!YA1tPVLp*w*yqCCbHHyy?C:DSyD%tIN#D=NX&16PLIGYJ:dyb=*c&k9le\$St8D#hE&ZX6+K/!Y
^w&cRK ^y+WJe!>&jJ#5lXE=ZHH&u!VGh?T!D9P::Tl9>1T?>\Y/uuP=<N*TLJee!nE6TeDX464PyRBNT46YTtu
6c49IW +!Sth/9LFYkC6i86=al\8qHJqnkyVA1aW@!$e^c+N14ZJajAP4YNqWADISX5KGX8lA!^#KIiR:>l9qie
p!IPEI +plSNCW#iPNAPwbYF^c!Ge=Btl6&ePEdk9Eay/nu4WjT%BdL?jDdMY?@CL&lJ<&l*E/KX#C>b/RZy!>R
6Ty:u\ 1%RXl6S=Pp9PTkMRTwtpMPWhPCZAwkwVKw/#a!BP=Iql+JDaQ?BWJI4JWwG5p/Ku%TwH9^FZ!a*KC$Y@
*%lq8Y /M:lwR$TC8e<FRjVIkTEw9p4iA1@Xh1Ca/1cKYewmJX%FAtc!&@=QG=5L5VVJ6MQtVL!%X/QQZJDjL/+
iZTZD9 u??\hCe/1%4#=j5*RcFJ\4EX#DYFWnkh4n/XD!ZNA4FhDG*t/&66c%Zbc?T=CSJlmGb#RWJD+\b1DMn6
Nke*#e ^iByXY/BXJYniEd5yC5:%=5Wc\=ADwCnjhY@T5jLW4:XV/tllYISqIkSeEltu@n61k4tcl9G?Bbq9V9b
?VpEnc WpNnwH9l>R14qFL:J^u9E4Tbuhaq8FjVpmLM\iQh\N#kX>%XXW=j4J=B9qJCEA<EAk4lGLqmD!VmJFdT
FZLyZ4 #WJGh^pm+S%mT:Vamu!CZ*jV=^+1GS1tD:K+Xl$*!nFwI99wtnK5W^#YqudYu8K%uX4Mny&@4I/1:j++
H<GG1I BD6/t*9i5h9::Ll&%e\GtZcZ@9ZTZLk:ZKT*8pMLI4%cl$WyK!&STSYIjZRAkt&\5%4n&XHk9NWWLN1<
L4wD95 #++jdClpMT6V<c5R:@=MA?cMF\W^\MJ/ICDtewmAXYwHHXpp%ZAFiAaLV%cahkd1!bhAGq&bae$I59Fm
1i>%mX 4Ry&F<YEp&qAZ#?**9Xw4Rc$Hk6aBNtWup^kYjiZWkhdql&*HLYKGc/\uK:MHQZZHB8\\umWMhKnI$G!
y!5Md+ M%=/^EdMQjh=EeIpATWqIac%9/XG:/<DA&X+aBK<d:pKId&=X%NQ@>GjK!1Dq!Z:W*jEaSnp+VDCERNK
E*EIy* Dp94MYS\V5u$bt##CTTcjCp>KSM^aiY1\nD@>nnLDwQaJ=alAI4^y<4<V%9q^VRcItTn:yPXL9ImjJdN
-ApRk? 0002a3778ab00110333 Page 217 of binaries1.zip
*$?>I+ bhEi4VKhLICM<y&a%dI&m6%P*>I#dGSc/Iq8m!Iqm+l&!*G5ibn%=<XwuR#J/GQ=TJJKH!wPpW4NVVaX
CS5iRT G1!emp!4m!aPm=uwm1Q4kdtHJZCBa9b5%#$I:@bE9PWll>nc^c^LXWX^HM@j5bKX1#I:PIudlNFtDJ+P
HYPA8X /=IyjWNaLEF+D&6d#n+>CTJdYT<4H+p\Fwp$:yAH%hl+#i&ARZIc\^RVLPX&C:dRmW:De!4?$46CZeeW
GFRq5R :<W^mp$yM4yuPdjBCPIi?kZiGwddNpIYalbNCF5p*++!$\a5pNiZ6F@dAXtD1#u+WFSJ^A?/CMa>Mk&F
5KK4/C :qTkmLc>8Nih8L4NmGM4*ZwSBF?b<%MPF1DM<9kH<IlPEWu*W%=+Ep&%btH/<eFjH>LqH&DGuS%MFuW4
wh9*QH eI1$<dCE<qn^KK^nQe%dQe6V!qj+tK@/nqMWpu84n:#:HbWaSuh&5e&YFu9u?p\SWkSVeZMqm5yPHtek
8VMB>B *V6pP:mnW6=%bTb4H^il:YXEn+1ID$l%EpCMhP\cIqVa$dH!FJlkn^/EcC/A5lkKCh\E*ucBGHDat\?V
+8T9J8 an\8n9E<TRSW?D#cwb1l&F5/yt4$hp:iYklYdKdCuq*t^9D<w@i5T&jR:mkqJmZ4:QRA!uSbGVcw@+W1
XG$!+^ \j#=Ib9FG%#IDj4cLHE5wXlp44EDVdF!AV9@I#EkiKu$>4ZDHLQRIuLeHM^q+XV\=\$1Gt>XVGHa*hin
VMT%&/ ^bNMk!DRLF9==4&=ZLi+*wdIa5D\QP8p5j8Wic6b@\5/RhpyWeWChDcEW?6wlTC$tP5iS14Dt=anluGP
Q+$yuF JjDY!tcbJ6pX9mCLcZHEcXXuMh5$m*WSuLe$K$w?M+LeC!YK<*iM:VhA<L8!?yJmQJH!FPF5ybIAkDt&
BpNl@Q J\!NHw#F9neq18ceNZ$im+XXu5/EPY5+$*4yw4%=Bwi5%#h%hRyIJ8y!PVGScPWkpkeW9ylKkY$RTacw
?inJm< FGZDtkEHHceew$d&e+*#DPhmJqHKRbkiTNQwA\NFKIp4Rlk&m*lqFS8S#hid=#+YctK%4YtZJHce^>cF
$Au&hw Hn%^FyYuLXST@B&^Kq4FecL1nbX$?EkqIhwlltJaNP8hTl\m=#CuH54^aZTR@D9a&+%&@H8aNn@b<@@u
I=KtSS LD*@d@N\j=<H/H8Z!$<TY+G?#\Q$A?^QuIP<*Q<b?#PuJC@QL&BBQ\/*=8Z>Bi!Qe^h^5LH>b!!a=!ha
t9?SdW >q@Ae9$EC@wFLD9Zn:Ee@^u:p:*kHD<k:@5iC@/J#L?kX^!ku&B@Rc<+j6bG9/BZQ*PGe4D^@IyCk*?M
bmtiSp @SZF?9E?DR=&64?Abj<L&H>*yQH<^^Vk@\\L@<&SB9y?8#kH?+<ecY\euQ>@mQn@PESe@6>C^Q*CJ1?:
BenSch lH?LDm>Se8y:Y8YXWe#@i*V+J+F5Xj=J:1=+8XupYEa6eD$dq6\TMChia!W+e55bL%m?8Z\Kqq^wGK5?
:NJX&= L$cFED^&cRYPQLM^@SA<DXDCFSePWMQ4#?Q\uw:<NKlMLpGiaeW+wt\+lC%LH1L$JMy?*\+Lq4^a/::J
&P*>Ln cNCSi\B=5Reu4$85j+Mu&q?9JTStm&Y64Z\hC\8?P%8FAXql<?<Wl?jCR&RYj4>SHFaHq^#KI=VW=?&l
K/eW66 K5Wm<nPN$J<1<VZIiCm^B=HH!#=yEM/RY!lkn9hiH8NWP1BFayh*^l1y+@SXS<biicu#G4qVqcTVHY^Q
6K86$w %PS/dMW>QKP%@&TiM<*EHIlS@b\DShSn/d/@R5++ARlJKG+ip8TllBQEwXXAC*<XMW4VIF#8^V$Tt%Dt
a4&4>W NiK&4?#MKe8n^N<B/u&nwh&M4Mc?kS&n^CNqJG+J\ZX6&8K*amV/DEJ8H6PihCIS/dea<#uIc>G8RGFS
@^bT%l nlp=jdPCc?c$J>\#i4+bk^w&PZl4ZiLaFNy<NA/q>Y@4L:IGA$#L&%h6Mh&LkXA>L<$ZLpcd<ede%X=w
pVFjkh Yei1ciQBCLjIMkI4F1i=4DF#!$nC:EhDKB4pYcK\EJ4qM/cG9mTh+hZu>mY&T4Rplhiwi^*LM?%?+RhT
jGCEMb PGc+mY5=ie^/#CPuuL?p5CcaBhai9j<E^np&WllJ*^&8wl?4b&ac\A8iKy@lZ@ncZlQ^uENBBanky$1A
u=amk> y@c&EDh+@j1qNaZtCZQ<>Et:9L1GM*QiXj+AP>9BZ8@:Y&j#dcPI$epJ4tyqLEHth9p^41$Cl?W=>9LV
BRT=WN =Z*HiD8!Qw&JCc*?t68RV8Hey$c9D=nTNI8SEy$@cTwt$nK=VmM<W#*kDL@<$Lt8>IXAm$65I6YGVd!^
a<^%%/ K\BlVTy!mKnXBdylddNM9VBSm>&eT%%Xn%tKYh95*ijy4?>FkB/w<Cu+AiC#kJEaRiG=X@YcHyE1/DjI
!EN/Q< VGeR6CbmnhEnh%#F1c+$%T9H/!I$IceqiQ/9i1$#86T%e!1!<nV=ydVi=91h?MXTe!EMjPDZ$Ck=eICl
MeR\MS G$akFJH$S#l\#dXAmXXCL?DeZZqjPyiGladkmaA/T%BqYntPWT4I46#&68M6=LpPBce:1\FS$aL@/Zla
/iAHFt pMA$8SpR8uMDH<$PwaKZk?QCdYGc5wu4uG4=6hL$<XJ?yRQ6\Tyl>iA!wZTVdTl^M%8CX#nlidXpecGk
FikyP& dPALq6^PL1+nJ=M!jKd4:NbkZ/8h9jw/Y\KDMJFu8%<=aD\Nh<QY/b!EBtNbeJDSp1paI+6V8GYG19mX
MjN%$c >%&hai=6$=$N69cwEGPAcl<tkC/j6t?j\pA*1JIlRFF$!Za\TQYla8/\aPN:Jw6mkSq++ShVa$$WZld6
HBaByR eLDpZadJM@V/abB\E9b+P?DJnNtGayAV8pHB?Ipacl#RW<DIYKW8LatuI\>y16A*Tb8?iPd1$BXW1DaG
?RFij= MZWEAiQRN/N/Nb:&ahP/FJ5+k?chQVcXq$hW%PTHMykiFT6ERZqdijP=Py$>9\J45N1WGeGTV^N^*yK&
aV4J@/ eK=CdY/:ed#qTS=DZDC@mWK=Vk8$CZ#FjIDpilu/9w8Y<kGDWKNCF$Wuy%^Z/B^V@aLy1w\=!wH\Ywa^
R&<4M4 p%MI@cn\?m8C%ERt/THyYjG?+&NMVlF98V^D?tED\B9nRcF\hk9S:N&qyFw4?XHt<wdi5EYT?u6FFuJL
Ic^^pS i4Lmkqk#DmhDiC?a\F9<#LI+bd6R1ic??1aMy%&@YV<CqYFqcZ1*#5KR4<>lB9V/mlpaWTecmNMq&pnc
u@a@8D yREZSE8HXw#DmYBXy#wS9lu%5X4HCi#=YPwu/\Y:\%p$abRw+YuSV\81e>QNP&XDN=Sc*BCWukYK9h^<
T1MKXy +RjMZt?HjA*nu#b<d8wp9=Kw6jB</\MDVQ>H=6+pa8w>L5!\8yJ698u?5tqRtjX=&:cp\\icA*tHWD\F
8F#qbc \iD%D^F4SJ=BGAcbNM$BqJ5Wh/=5GJJ9GSq^i54$\+Tc/H5ZwEVIN\Mw>\P^MQ6\<wTWubq^<:j^%1%R
deGGMc EGw81<$NP=SHXTZjqJeM%n+%KVLS/VdHLLSkyTaad<S/q!=nDtjhy?e@th?8@i=&dKl6dTMBVd#!FVhM
5Nt:#Q jyM\Q:?k1HyZm*jWi>IAQ66I+h\tRVd%\KPT4?X4V$pYYN@5:ha:^iI/<</EyuySjlAwq&@QLapci!kn
!S>FNH >4d41SY$$NIZYGb#Lk&%^iKnT5bR1pA+T%Dq%td^w&<TNa^?M!!GWuui!i:Yul4QMGcLNn=etYjQN^b%
/t@j/h :%m$a@+YPnR%MX&@Y%%F6l\HL5#yZFYuah!&jFFW!EQ>wW>1mCR\S5X881a5MPTL/%Bk1AFN6!C+@E#9
pMbD5D 9HlNcZp$dVMn<SPu^PE/FM8b?w8yWqm+?KSy<91^PlM@Fm?14QhtjupaAd!6FnZ6PPyY&W:k>/1*%uQI
@G4#W? ukZD=*c?VMn+$k#:hMXS\%t9hZuG#ita=c&uMmbcBAm5&imR#ie+uJ$9HTQQu!LWC+<&Bhl6=Am\1Fi<
jPQ%hC yacT>^mkGabMu?*lWnqi1X>W%>/=^c%&8hJe<Yy#ik/?V/C6LNDe:u+L=8*S%FI>@4\i9<4E&PRQGeqn
EyIBT@ 1bp:NuN$d1Mn^+bi6$ywylWed1eD%kF#MecnWZc#$y<Ap=AbYy#jVqY4#Ti=*@aHV56^9+iuX<D&j/5*
/C#HNd j8:DW4VhtmhIblnb>wt6^I^K\IE8NE=BYqR\9iSyP\E@LFpW=6G:b#h/V?e?+ajbAKNeD+e=ybqwi?Xi
\q9@Vk QThSD:l<lamu\d!wZh\hyIT^NLmWFSS%a/9lJSam$@5CTwtt9KLi5MlHTQG\y99Y#BykN1dZ&<Q9K+WR
wWNETd F\IFcRpuTCWQDA\$:q^Cwq*^q>!MDp6Ba8V=8p5P5E@!:+@dKilEiZ=4YMm$E=yyRkeBbR+uG+aRSD?j
yQ%/w# 96N5QBq&XPAW4IlSE5K$KGdqbwiI<LG?56wqmFKF/\mpI::hSd*6W:wJBKVw:?XLFE=P:KJeY4npWMQA
IB1Bjd HIn%48<9T6a9FmdBYB1uVR4C=M56M#=Bq%6>LWQ#JWLmkSwY1KnHQd#9=ekYQp=!SRM!CC5&Hyn*p&TV
&FaPSF 1N!Nknup&wQSL5D1l:p^**KT#M?Pe>RA\mIFF5E\XL!EwRuSqYJ:$YqiEJT6a^EJQ:R1b#pD^!+LJ\H#
ZK=yFh hX>FK:RGH*q^1YC?qp=qCynt*cMMp!i#AM?J8>PFVYjqc+FWX<m&j!yuX8W6PtcL85Y@N$l&HtHIFdyw
GTS1W5 YPQ9LE&nh<V\8jedBlW@$/hZp+cG%<mVXZaCAXSi*FS!RmCMlV\BMA9NmVSV?bqaMbXK<NT:Qp1D!nm1
jmnGcD w6e&km^+/ZB^y85nqQ%kFMA/Wy/KeZ>:kJM\?5p:^tP*TTTl*B1c!ihlA6%1?y6!REABQNt^u%JeFR#$
yFidkT aw!yybtVu?T8XMFL\lB%mGEh@+H8R/A/@ZMh+?pEi=yl#?qwQQVA5<qFCe4LlNP$VwjGN>5b!JZY!E4:
:PQRcK jkyE*?R@T%d:iFLKYE5WB:=iJwIPpSc*GeJkyKin^uhWpKT!ky>?Bp<4%kqWJ@Xutym&YFF<kSF59HJ$
E<R5$D L1=kpc/K6MQmwl9P5D=8IDeD\@SK!Se%#i&5hnPi@^9hbjpiaE>Bd*Ba=haeuqQMY^H/BZkR6Nq*GR%#
6Rl<YW dqnGkJR>9IFybeJT1YG:Sw&l69iSp@$XXu$u%k?n@nna\j<4%BW@>IZ<6@\jHH@tDj#qWI>@l9Z>Ei4B
iKqj#@ \jdjmZ9nAHH@Ke:6h%91*!&$:$#l*<p5@tQMGMj*%IR@\HK^@^nL<\9aH>QieZ^QVjk>qyQul!\LHN>V
Q&lndm E@+A!@un=@&it9AHYI/jaEG@kQ%^jB*H>>TE*&NBuD?&\L?uJ9\i?%N*^jjelD?+MhiQ*SWk44?A=j=B
5M6&b* JNB@Dj@FwKVH:k^?SIF=Hn5=N>h@DkZmAQ*dJ9jjyjk9QBn@DQ@=#aQB!j/>B?NjKSD@IdiYw4HXd!L?
@&LHM= IjnjQLbp@\kJq4dqIQ6:eC*bd<+4Xmp#!?eYn!MH&&?l\mKYL5=Kbp/m>4aP>uc@DTk<bI?nlw&>p/1D
kKk4Xd pepnYM#M#hLEVEXT=A>&Qi:je4Q<$%<mJ14&A*@J\?LDS\CK<KQIbkDVX\AAAPJlGSAIkIQ=:jQ+F\+J
<9b$%V DlaPCRWBDk+BBR$bGRWbGR$h/jE9ClI/KkatFmaGKl+iAREiHmWFBRWq:V<@EQB\eQAI<In\<IkwmMmI
%?kFjb KPkwn^>$#L<XkItHn94+RejD\eZC\5LF?R%PREBPVpbP@peBD=$AhDnAJARICwICAIpPAaWP<hALpj5w
pheJ/= IC#Ed^@AQ#:RRClIGAkA:PQhECEApJBR@*4%<RewcCDM*!/mATAlwKAkwTFlaKEi@$A/R$BCwWMDkPRa
KnETDh :MLKMJlGFI=?YKDaHFn5GlHKLyYyDR+e+%M1J@<#cqG\cq^84aq#N/eadZ^iHSi8t1qL#@RtHE$AQAIi
-AX$N9 000c70386f300110333 Page 218 of binaries1.zip
W@=IJE jtCC8ES?9ecMPl*B?hbF:?#&ybq4WGJBR>@e#yY=Y*BTaYQ@@P=udpuN=?/9p+8cBld&99BIcXq+lKRW
L*TPne N\<8:q@V<$y4Y*1Gyyc<HZy@<JYBV$dH!m554jVh<NLlDj4n<#^KCRR?QkM$HBTW:iQ#wENB@!a^WQqS
=GZYnu allH9%lRV5$yX6jWB1WI6w1^$^pHFXnWH!hPqV4ZyLad%utce%M5AFe6H8+*WYt+^AqwVX*W8e@#/u4w
@?e*j* /Gi&LkIV<89@LLKE^l>C@%Vt@$Lpl\<AcADY\^IACiy9\1IDBAFRXXaGym>XhZD+&t=yXk<@<yBHZk5V
Ec+CyW CMZ!Vha/Gu*4GZXY!R&EPjBLR^Z5d$IVVN*lnyWq1MKQLnm+$WtwQch/YjYF?NSiMh#LLh&1ZjT<Mc>+
W\bjq> %WD@jh&EM!Q@MY&1KQ6Vn*\@Z!V+B\DD&6DX#lX8=jKh?YcL!\QA:h98K5EJZcBJy\&E::9AJ6I>6w*p
^FdL^X >i4t:a8q$dMQu4pd/mc65RcpG8w$a#V<5w:1KmjIAJ4/y#jGPH^NGXiI68!&X&QCH%*B8!!mD+A<wj/D
6k*5MJ <q/PE!WL9$NpH&1mF>8j:6Yd+p5Wm>5aS?:&t+?&:n+1*VceY^CJB\C4GBDD\#RH9w%t:X*/nk1iq=L+
Tmt&8P YK\u?!:%XnA@ANn6IdE8XCYt/&W^yC=kBJyt@b$kPRc&bw%WWPY@IWtln64luQ8Gtt@^5/?<LHpL\cA4
9QP&Ie p/M=e@&=STb^&j^$KP8&#Jh&9pQb//y1uwZ9=AGA<\%Jb&8RSPNhwuq#ji!&tFS5bF<uPaX+KJcK\8A4
iM^pND W><EeNPq:RMA+jYSAhR%E?*W:WC?=K&TIth5Q8V#//ee$?YqBG%89EdiN$tj?P>6awBlu6nGquwZIePq
?<J&>R leW6k6t:8jZE6RcC#K$b>a#G/%EJ#e*L>#I:95MN=:d$X#AQkQ#\/J8TV/<9dy:6QkCtM*#QbH6a8#^>
&+Qpep *8=GQ>*ZmWl#:Y>#y5#Y&I*n^mCCkZcCGpD5&DH$uLt9T9a>b>5#6B>SyPFqYu4BRbK@wwj=AKAFhi^w
1SaDEq i#LiX\#eT$+<ANSBm=?VZkFRMPV69HqRy/Qk*i?1!B+AmZ=:mnj6?k?A\b:$Y>>@H4@^9XhQn85+ZQHh
KX^w41 >u+AZKq!*=c^W99PNV>i?@wAPC\p*YF=LFNJ<ID<b5H@EYE>KQmHLL6@K9a@FTW+4J>%u?$:LZyXBh%!
9El#:N 9^DnG*%:<ADRHPu+m8j5P>^=WZV*nPWB5G$$*9GwqmND#/:5BM<FjG>K$9>e:H?TmQV4:#Z%:FE<5?&1
>I!n4Y t!dT4/TCh&ynj!+&?n#=?RPktQR!=5///@HGDh8p=>Z<@$5TDh\@>1Y!udZdCN=@dd8@J6G@%FjXA&C+
pBt%y: >q##Vnj/Nn4496V<#?WPjJY6i\DMw6=I?VV<%wZPWd>1pj\jK6DYA+DQh?:<$:$E$h1@C9iZBQ1Z=q6+
Q964<Q AQ!yh*H+@t8^J4eF:^>%G@cPTqDuXLdn^BQ&6l#%j$Mi868:Qc=a6cNpF!1wd#$4i*wZ\Qtew5w1:Q1F
hqY!l# jccVwnVE*ZjNhQ1W8!WmQEt\#t*$t%bR9+$ChC+#j!@j<QW=dyIyW1*\p#J@QM+QW>ApDiX9Z=jNHhSt
HQAhVP QEe!C\??dpMu$qRj4I&Rc9u\/n=^6tPuXQFL^>E#m\iA:@*hA$CZm?k?4QwB<NJ*S9TK6Z=6^bj&&WCq
<Hqp8! Vh?bw!@*MXJ^^<Qp99Qn9:LiuN!eB8liWHp^>#w<jb5\tNEDA=tiYCT/<j4mH=e954+i*jN^QRDPZ6>#
>yTDVq &>SlmSXC:LTEL8EZ9bbuTltVR6hkVbZ$nZ+e+*hCH\D4A:e#/dii>k<AJ5WHAI#kdpdA:tkYFKu:$u=H
At#wSw +qZYSQTN$4nkRNID+L#*AZB1et<=h5@j>ABIwu$ABJBiKAljGJ&!j*qbhq6Xj8@6P^*5?Ki4>te:Hde%
:WM9eS k4h+D+A$J>S$$6?K:Sm?thkd8KN:V4w%+99X&Qic@REAjl^FTHRjACPQk&6Z>Nem51@XHunj&8j8Nih>
m8d$CN BRRQSQpD^p<u?B&a$/EaT!H%qHDA>*1Ji?R#HX5=qk<A@L\HRCnT$WCqelcSWW@Q@Ie15<MLK^nXlIB8
tl+8VB E#ZGN\YcPuZcK%I$WhYMVI+*l9XS^#u?XeS9%h6HXG&:inXHp%bTyP*=m1*WJKVFN\k%qL<JamWM6</Y
$+bV6j d<!c?b$wL$1aJEqe>4Cb?+tRTLRK?nD1%$^dJcG@%L+91RunNjTl+@Ec9MY6/nu6Fu+KGNbQ4:#cc\#i
E#ipwk XT!SH9=A+eM$NZ6V$QpN=SL1>aR*8u%=q/MLM\=?+8H\?CAQa^FDHq<e+!tyDV^J^ZQm<qGdbq%J6mc%
Zb!b5k WQWAEwEmF9wtE6NZL/=/J%J5MNcdc*$%b<!%ASH5R8%%X+cTpcl//nm8*<^CSmjq$CSwBD@Eae>qQk%<
h%Jk*< :R=uiV*DjjDNmD\wP%Xj6MYj<n&qM&dn6L&EC6icDeJNa5ZdpKGmZKm4X@qiJ1GTLw:NyLa1SY5&G49*
NP\EQ% @W<cLG*qwpqbREDl@9dA4Q4q8QMKXN9:SHZCWT/LuFX/haTdnEES/Pe#t:6Smu&HFW?8@TL5&d5l6m\h
Bw9w1i 1ImEw<T%ByqHm@uV*@WQwEWd%EyV16i8^\?&/w5kj$nWZ!TljX:\+8RpwF:d1G&GQG5!nMYw\=ZkXVc5
?Q<m61 !?KLV%<!%J&P8Q1Bd@JmwVkpRn1hYZDVBu4b?h?+Q!QNX/<=Tw1c!yFGG$dQ&<dh%CdltYw$Ybkn8ZP\
@lW^Ya dAlal\Cw&T548^tIuY?4&em:4:ZjPe$9jZDZm9GYpE>Andn!ijQ!VK%Ypj&>^Ci$ME@1mJk#K8?$55<q
9wm9qR del$H\RVh4lVnAT1<t\yd=RtHFYWQbtw5w6/jbabIb+XIbP5\19q^%KYKhZY?mPnpm6JSq*9lFEXacpZ
:kW8m: !RDwF?/6iEwNqpaS5e:4uemcVJH\/Ku+K+Cc+XqLEpil:S$IIRi&4LTtP6^ARQ&1u+Hi9ybTA/^S5K!6
i1BRQ% uX<mlVmKJ\<C\JkQ5@EPhAju/Z\=p+l\95uat^b:Vw56e?K/*jw&DM:RShMP?RkFCdZ\At4A!^>LhT@/
ka/W<y *RJqw^pNQAEHySm?TN^^8Wt?BYH5>ieXJKJG6^C/GIq56E=wJX/wRY/FllF4ZZMRl!k?/ITiAh+BqnVe
cDENPK >9P!6#1LIy6Pc!=&W@Q&CD=SHkInyXmG%Tnh!FEJ=YP9R=iI=l8#bknJGCAFXPwHFmIACBywZmPLX%R:
QT5C>? pkY#4RQ\/IwSQ+6dLnj1LuiSGb=S\4:9wiP5m9VcLPccJ>hKWpa1$KF/$/lPX:9kZ?&tPylIEZDR8&DR
pj9X=e bCptENl=ebpTp/C=Y+Ntebj/Yw:N&6y>*aDKZk=dyylj@VYP?4Kl^ABw8VMMt%JeHWCHAACwJBRNGyea
Qi\IH: i+bNdYDieECVc#hGuGtm%&L&m^waqF=Y6b6jaJhYm>w:nkSI#R1JuIGmtL1ck\ZCXd*b\94H5cLw%mPw
TQS!EG PC<H$D^tqYIW4y=PiH5&9cy&^5AFFN6SbHN6c:\=W\NYNtHQVe\Fa9VLy5\6S^PE#K5PBm@im1u/yMyZ
<ekwIK /dB5<twLpiRBP1A\\48/DD&lKQ\Bm:hSiDh5F>yQ\d5Nt!9m+q/V*:a\yyjaCe16ZqKMEZL*h1ZEnR&X
:c*N*h #uG8LGC:X5^1^uyNLwTa!^@M\c6P6@W#S$yNW<MVqJL6q\Kk>9GP%j%<6%VV8i<=iY5$H/d?Pc:@iiDi
jCm4pt ^@#l#$&\Z\I&n::y*m4+ZD<A*5EJMl/+/XTM>dy9l?TG#&+VltAb\6N&y?C<>D&jynikK&lylyP=1e/Q
E16IY8 ^Ki5II!/jyQZ/pYcT5AleajQBw*G>aTp@V*/k89J<=FGH+P/!c1>ta4CcibK<:D*w%aZM8iy%Ib6&5Ze
!*K8\= k:5eb$Zc%Gk<FqC4BC<+=I5!p#CH\nBnRZZp*8FM>8#*?1wd*HNLmcF*dVYwb:T^n/K?kF91iPek5Z\@
APN?!y Lwtc#u?^\&\FuQ8$<^cDTuWIi6y4<HR+P<#yG$$YE?lmabiq\dF5LG<j5/&lqZt@41h%itR1kc$K4iL$
/LpT?e >1pnLNqiuPpH=V&:Vp8ZnA:t<D5GLpYP4&lRjbW>CK/SVbWQAIj?w6VdCMc^n>FBqL/?N8V?1KP/^Pwt
Q?Fmu4 td^&Baqm6iHB&npMkt6^:GdR*pe!dwZQM1?ijJM6\#6=W\H9q!aYG5Tku@ASWH!W4NdK\SFuHEqIjLhe
hF6qAL \/hQH$PyGL=BuEwqaHHd\kI>+XF&RykXe^AZWPCy1Z^?Nh/Rw<jb*b<wkiStFbtK^\mq$DDP!Q!=LX@Y
k^?LGi t9M+M%jPZ?y6LBth&:Z8hWB<NP*ERXHKmTG=dRE#YcVH#Kc++&j4lJ&6$MC<hP4RZluRwnK#b*&ccnlV
>u<H4\ MJInJXEIP:GR?MHeHjt@9NqK^pYLjAhEb8+=JB<AGQkL$Zw6/8PC8FDX:St4%@iJBYm#mVA6BFF=*NlQ
MKb<*S $PAPblnu\8e8ic9KB4KKqEemLWimhVTJW<bQ5p8BAC^CqW#<bt44Z4W4<Bw4F<PW8yEEIBwT6M<Qa:Na
c\=#GV 8mdQSTRPK^?<8A:aB*\%H\64+dJbLK9:lRQIB$B@Ebj>4bY#ehZD>F>TcHkm#n8IZaPu9lInN@*Pu*nT
XplH?C 1yLd/1&FH\DILK:QGN/LqmC4KnbZFdlduD:qt^dB!Y*HHu#V@*4*Da>+$RjLNJ<c+q\+Y:9h<QkWmHJL
SA^?M5 Fane&bpdM<</E+KIqB%!jC?F8>tSt4N^HVwbhmyH&W@QVL:1tTc6Ke%^enkn\t*HWW954ledB4$jkp#*
^&Ek%5 1TIK6==T*Pukp@e+T+4R=>^yRSe/c$pF\u%5KQ^\duD#KT5*$pSjaA=jcK6Qwe5L\itG:h%ui/:D5BH*
5IG^KZ k9jnkWq15jnN<VYF*<\GcCDRi!k^pAM$n9tbZq>L:@i+9m>9RNdS4YAda%$kGn%miNY64hXCEWTVnTu#
AcW!#m yW9A^P?p+nLeW&DF4h=^9i>>&JiDEbTNtaaSmV*:QB&Jd%uKwlm<LtVuqc6RyK+Fu6HKDF@+=DC\wCFq
8F8an6 NcNXP&d$RwbiteV\$k%GbebAZ9Qc:+M^kFMF/hNJH@eHk!TJl@k6+NTb*I:mFYuRWFQ+Ean>tBk:Qc+*
*bQC?C 4L:/npYi$mRVqB:D$6QlBKp4a5b%5Hyc1<!+XPk1#cyS#XAP$TF&idckBpp5A@lWmVYK^I#CTbCnR%Ew
LCa!N9 FLaZL=l=c<#\PFL>Bh$FM1XiQ4uu\<p/T^P<nlq9>Z1e1JZh@I9!1mbb9S*aQH!CiDD&KjyA?mP#@jc:
w<%q51 XAy^Liya<=58?\lRj<&yASWwGFGp^%E%XD49EJKi=MtBZC<tRTlX>9%SGEIdF>^t$he!j?yY>9CTTqe<
Z=yl9B Y\#iNpILElyQGn9$&kE+ES%y@E\@wW4pNN#G=Kp5qV\tiEh!Za@FINjuT+LqwVwb:8S$A4j>:ydK$=\+
aT!Qm6 peqH=WH#+hLWA4Gd\q8cbe=QMmW*V1L+tA?cWY>E:IY+9^lLp5IY/:+&iGa+p<!\pVE=ak>&8*l&qnwc
SDWl4C NuZD6bQRh?Cpk>m6HbJ1WcL^8a5$4+nXp<BKiHXec5NX%?I4PK+/Eq9#mJMWE$In8$<quJlth*1H%4w^
Nl?lTX %qI:MZZR:ZIiNE9%WYdl>nNZ4&qk@?jDt!^$S&l8wZRLQ@T^pilP8:e%B4DJRHCZwFJ$NP6M8AlD%4/K
y:ekqI 6!FCW>G*milZ*:!6B#/ZlJYQJW^1=!nhG\h=qqjtL:EBnbCt$X:KiJMVj8T6bLwn%G!J%5SppIy=^%\5
^\umGy kZS!<PqwAk@LWG$lB>wX&4lm6:?kN9q!h^+Hh#NKXCea\MFHpFLpAJq!V!MIX:^G/t+<*+lcZFqPE<V:
-A%ihK 000ae52d83700110333 Page 219 of binaries1.zip
X#$ZB8 m4Ii$FSA1LD!Wu6T%S<Hyy+T&=1Lc*YJh<:#TLq*kn^I8FGV/JZw*Va8l1VmcuEXT?EdS&EVVK1wh<jQ
eXS#e8 y/HjEZJJaEYMVi$aFBi$c=Y8LP:W?6**6$c1I:ZcbD^P*lk11K=V#uZwXtb6&=pLLb4+!tE&q>WRZlZu
nDCa/5 LRF<\Ny1J:!Hqi^1AndkB\C<qiCX1?KN?APk/u%H6$:$ud:1jc#9$YiG^N$i^hPp^!FVW?$BpQ@5=m:>
a#SHbQ q44+AVA*J*mAi>>lZGL\F>FYm!8D$$#e8<<W64W:ED&pWW#bp8m9K9XE/T9u5m6A>h?iSEyuw#*n$R$:
wQweyj e/8QC8>:1SkiPWKT5QJwV:a#hHA^t^TPPBhF/4P&/aypVBG5TBmW9R?5XR$uIG/^dWClDK6tjS\>#j<&
ymjw<& nnI<AB=t@6Ikm8!JjG&N\HP8+cEihRpaDY@n6=b:i9E<@SJ^A1#%XRWjmZ9Ec@=Lp$>!jt#Zb\?%t6&X
^+K>lX k#MX@>eWjJD\b5$SX^:Zjy9TYEQe!d+5+KeT<=9uP#TY1*8VAu+m^iYq1@u?RkLaqjj9FZLJ>kdlaMMD
?N+<Ru d\N<ViLAiKbWJn*$==@1?^<Am6PC@V1KTYuT5R*R#bat#$Zy6QJm+>TNNDb9pZqb!Hh/J%*V&^\4=Ea5
?KY=?Y C!APWqjB/6qW4S*&G>VIZE>eB^P4at\NiqRYDF8CbRuy>=y&DTLJZ>**AXHJ8Im1=+<G*>p5#H5JbJSk
A%jk*m Gl\e9P!*SQTKFBuHDD9SeSpGPX#=Cac=Xa?\E>jG%yAYQkBEuM%kkww>SdbGF:nNKbGe\hM+RnFTLXS&
\w^G@L $Yi+!VGWi@:##NT6lb\>XLutM<?WAhmZ%>%CSkwC//dKHa#V%u9VBBa+86a8:=wVW+ImXDe$1Y\Xt#Zi
/KRQ$K h8^wCk5WPSiPeLdcF?a:4Tken^CW9S4&XF%4^qe*IaMK!hyaeVX*Mt$=<@S1B/dYHTl>jZI4mhT9\1S^
uIy?MH PlkXJM5PKd=y>RCAAFNhh1Q!H+*8!VbE?BF@npWikw=iMmh<ic&I8=NQ$JDBq/Hc!#SFa^+jn\JJYp<R
n*<4$l 5LH#LQlNdZT!T=p?!?du^Zq^mW&??PcTm1hqC%jd$NXdtZVZV1FDQCl/l:waY%dZP$Y#tC\5iIwuahL@
9Zl1^k Nu*a=uP@hYEY*AL:uyG@<dkcG!@K<GF>89lM\h:dX+bpRGP/99pV%T#qHt?:wI1+yXn61GGwC1F41G=C
y:ES#u aiEdL6wGJ*GYtmKh?tybt$K8?6CQJlm\Cd$t6wH!LcYQFmDqb+K?#EVmk$^<tp#h/cVadt1RLIe\tyVJ
aTbIRh biP&8PYku<^uYC1MI/:=Cmbd\!1+?nDhtKDWWZM8jk?\N$JykIGCkHdE^>uNYjAh/FRm/in1QaESD:hQ
P9jbQL c$GCLp!WwHL11pk\H*uPeuhk?aYqmu\J5ItbRSbJAd1<aMj>e85J><eDT1jTB$DFAu1$W6PMQdCXC&+l
Da%$I5 a8cqcj/=QLpb#y!/Y$lhHYW@4ADqBtS>Vq@tpWKe4dVGJL/KqyEkaa+u<S&X5ekWIQc6p$!MD&6D&D6t
4RIec% pW+<58DSm6dQPJ@A4&jJtWPTA=@:<%!4CYykj?t<Cj@1tGwpteS4^uwjm=aSA6DP%Hn&ZqH%<GM?!/hQ
\V#\X6 ma=qF9Nu%L&Nea\$/eBS6AFKaB#ZL5bmcdZGX5eT4LGmpPQtM$aK!4a!B/GSR?nETZD5$>=EK:9XlM1?
tZlFLV pA4<XkYGStu9N$n$SB?HCFCFLuDy+E%a1iQ<JBu1E*e?Y*qyamY4Vyh@?tlwdZa*Nm4LPEBLn:%6qmFL
tSPLn4 yc<Pyjjt%1%I#uqm=>%LDTqmwuNtjA^+@HAHW#ja?GVtM$ky#86*EVby>?ueB*R1ZV5+D+D&=FpXDPte
Njdc/i T\lXwbMlSLL*m8<F=6SdT9mL9$Bcc4+b/KN#1QNV8!wp@\CLlk1QnK4n<5T\Sjayyq1hwM1&:ikaW!IG
Ndn/<: 9ZpTC?9IjJ:!S4K>TTPPF^?G4NYCEn<8PmZQ#CaGcLC8dluYX+h8&%luI>qL1idaPwD=6mhZ1@N^4I1d
1Z5EW6 $^Aq:Kj\Ckyy1^&YJK*FYZ*huhCu?mTTWP:hY>tlhXR?Eyp4w:eI?VH=WQZYC=$illc*hjtWk&Pa$wj5
?QaG<m aE<1K=lAZi\QyV%Bq5Q%JRWe1KAD8iKN@M&QGP*^J!QVCGPN\!>h%6d\&5&4t@*^!+ZjakwYbyPRaTln
F<VK^< ^VeZ<iaS88\eT#CE*EHp\?\&*84/m\<bmJMdd^*E>kZl9?VMe%&8lK8i1cnjZ&W$FHpCk!ANSknFKK:<
4*BaVe ^wDTDKuI94ReT9p8MtkFJIpWI/+NT!<KPuZC!A6nZ$Gc9#ij&jNjNRDB9qX\qEC4eTwdXlhht:p4X?eh
jw:E*E C*\>tqS4PdP&SJe?&c^44nJcN4THe!nL\E9I=8XI<^w5aF=*8j6m%q4DL/!cQAY6lDAXh$P%>!akW8nS
?Q9u!L cqb@MlaE9@8W>/QK:E$++!T$^Rwwu4*^?y/A:w1PWa?:V#?h!$d>jb%=u<1R:VGV*Wt?44tq*WjWV/J1
H6uX/@ qDjPklV+ndDy^*qqtt9\q$>FS:+RyL!Ynp^?hVu9?AR4F4Itw9VCLMbSat9EFcBpi#4Icm/%Y/Q=i8:1
T:SAuA ?Z1$$qP8!&$:q$@XqAjhV#t$y#uqLTM4cpM>9dt>w#@BS%/DAwHT/>GjR<!\m#S!m<M6!!6d&:>+ieMk
1RKYAV ilwLE&C?^>b$LeuSeiSethtJ9a*S%hNb@iwnP@LE$Sc4lp#41A$dY=L/YPncjjYX1T?&+dQ4&h&^B$Cp
X5AQTu kw*/\?^jM!dep\/8=ue?i>n^LVkG*^9NZL*SqiHn^\A64k\*aa1F6d^Vw6@44q@P=qHhiZjuJATWnkl:
Hqtk?m TeuHGR&*TRnI9uyCpnZA*nChM9c6dWj$t?^#p$FpcPF:q@a9d$b&Z4wSa/!NDB/:DP:ll69*IXN9>TV#
m+iT9% +bIm88\w&tBVh/TNq=pX+&eaYE+Y6KZjYJ=T8cwV1X85Hbjy:a<+&m*DIuqyNK#EN1:^n=<FZ5pDqJh9
iP#RFW d>J&$bNWDe*>pwWEhY5\##$LApqec6yuZSNdZYbbi&:PE!MDk6hCI?jmP8CK88tuLCN4*%*$NSc<LE@@
:Ld%L^ #Bh$CQjSDF%Mib+N&^yV55hRMQukTD5@!y!b$d>XGyFptY/SaLL^t?<dN9#\bCwqNiTANJS$NLie4:=I
HpnWIt C=u#\$l=R5wXZ:<<RjKTp1E\9d^?pSI8ZZJ\L^<@\tZNMFT5S:ZApbTdwkbE:<?6L^F?l5c&m<!t>XXu
w*GE8F Y\w*NdmDhAqb@Xw!iHp/@R+K%cR?#BQk1eSB+GWq/d6Di/hj<mu/kklhQH8X+lXhR>YJ*X#P=!1=Pln9
cwJJ@8 yjJ4E%cyaKq+pe4IthhXiGiYF!F&C4#S:kY:T//?Wn1?@SaQkE%S94ND==mD6dQJ?khA^NRDwDjahY8B
K+R=W1 #%cV=>dA@l@tL:Gk?t8F1E9P9A>/<q/Q>&h$i:PhtlMiwbeac%K5+5tLAJTtTCXL%4uJp\p9DCYQt1c9
Cj95p1 JCH:qlPb@91LBA6D&XRB#B8IjbMdu@^=>6X<HYe4ZE!DqJP<1LZ=HWbSZK\+Bbu1wt=y6&8J?<=B/uu#
FCtZXT B58ZV#nniG\yMp&n8A%pVJ=V#8XEmkT>%%4waZ?#qKEV+jX!9c=&tkKZ8lAZeutPCqSSp&%p\/BQJd>T
CaJ5QF ip8=YTTi?dqj8wH1nlSVJ1+H$dp$NW*!E96NlJ=H5F&y:1himqqk+94M=VhG**KJGjn=iZk%ZQWGH&\%
h4XN\q SFJ\1kAZ6S9lb<T&1@w/K?X$P4q\Jnd%4j9V+RiAPmy=WV>8%whGl8B*C?Btb6GJRpdT1iwQ84&RcN*m
\>b#Dc meDT8N\MyTd:Y1$bp*CjtQMdhJeqD<kMyCMMWQTq4@4C%*a<qAeA1u#VRVlNnn%#1e!<59*#=!B!RJli
M^A8BJ K9uq/=+yKCZjCwX4:Ia:TBy8\h\hDC1#A6jGmFdHM#Nli8VVt#BW6Be9mNT%Q8!n%!+QFZp=9bwK$iEy
p>yi:9 JW/Q#we#LpnJ#J=$y&kP=C6Mbn#ECe&HD9=AJa*jK/!@MCq6bFkRNVye:k+dKi:YlcFu?jq5Sbkqupl%
@4&TIl iYpCJGETQu*yb*:y!i^8q5hZVPtN%G+/ZSF^eMM=n&eeIpWY1y&a4@*T+#%RAE>nBab!b^qd@?uucG95
qjTQqc 8ad=XQ!*DheG1&TX=T>yY=TJ+8A/#EH8pJFS\h>EY9^ZPR1CQdepkwFTIidpbl=VKhuZAnWhLGT#$&?j
N%VZ*b c=>9P#KPGJJLQSWQ%cGV^DdBEESkB@A$R*@ViK6<TCC@yB>dpC<MLAhJ8mL$*^cpXp!b1cB&b&C@dtS+
JTAu<m HZepMi6!Ne6$QHhj+I^cBFt56FMpSW=%\$y&dTKSY&Za56:<!TZeEtiwuGh%DKNMY/VltaKhVeecuNDi
8Me&pt AS9@K$GWd^AlyG!Y<W9!?DP<dN5n>p\muNdPFCCFEb:wDjMaF>m6Cn+#4y#5FWWnK=ieK@j!tkAmMqdB
RDuH8! 5l:CqJ/QWT^JdZ%ACaaTp4IhV\NWlWEi6hl5S<lb5m8%BNY#Y#M1R6bIT@&XBS&I^ueiL999e?16P/TV
KPIc<R PJG1\:!5XLQp@e!AL<hX4ZZpdw\QG&@Ww5q<JbbYbi*Z8E6#*hqLGb6\Ipe\?L:$Ce48^@R&wS*5XP^1
Y^=$N^ NwXbdL&CnZy<AR5X#F&nRC6XMIbX9Nc1>Z9D/4JVL@=MZX8=8F>R+=NyGl*yBu5hyPcJT@<H1^9wGbnt
e\#Pl+ G6Dk\XZIl%\JN&%wS/yRuilIlL6TNJk6Fq6j8W#y8G<Kqnle/HTtab1kcM$9@L\%P<P$mDIqb=&N:=Lm
IGkTAD eT6iwCST$:Sbc$iW+eY\9j4Ae:qaSeC#Id4tNaP6YH>HKNjk#\HNTE/bN4/jMWE9WC$\ZE#ciq$MYEQ/
w<y\L1 $w%><dTw=M4n?KM5bayMeTA\%qRK\heLbwKle6q?\?<n@=bNn5d<6Kj&#J!pK#!?MF=1<Y*WIdE\5j8u
K4D8pF 5F4dC@6IFZ^SqEC%q:\ibT>&%^m=GALd$1jV?8Ra/bJ<mBau?%@!+9GlMK8iul*!dalub5ej%um>5$Gj
4HK?PL wE#EhS\cm>Sab!^lJ#j5uk9!lm5R:16!LYy!p&c/$+^YCl/u!Hmnd1cqYHtM8W/tKPN^aqAEcjq8G#ji
ASSGE$ EtB=GK<Hw/ktN5!<^edb/%mYWKA6hC*1e1TRWp1^>BH^AeA/=At5ZT1QJWNHeFJZM&Bab=l?hT8+QZtm
RIubN+ A*e9^X!F1ZS?t^\P1a5dClHpM\$IW>e%Wt^Rj\BRBc^SZ9@bd#j*%^#SyI!>6c5nI/bTZ&8?5y$NWc@Y
QmJD=+ V5ZW*CLW1!56S*6Fb+1=lP4R$^ThWMPPN*>y65!wIaV18H4!<n&^G5?=DPip449lB8c$mNPNCd**Ci>L
a!K^Q$ +?iMw$=dP8#jlPLd?GbK8n+9JVTylThnm?kXL#W56WN=l!b>i^KXIZ#KjQ/=1#E?EXLIjY6!@4XhFw1X
/aekD: c\1Ta/wJQ+kwi6@>K*89GByE=ceZ>Na^6SRInuGJSWKH9BY\Qw#Xy%$EZ4V#HmBIKkMWSYZFEP>u:MI^
^!Cq\j S>Gkk/YZe/t##:p&ItXV66ujnAp=$NE*#m%V*:lM/mP?CJjY5Mku#+9FA<W&9Yi\VNNZM\6ZSe1qwTRQ
HCAAnd la/Yyp%y%C1pD1A!t*C\Q=bLX+BdLWeTl1:biX8!tl&45:AG<VZ\dNIiK$!FAWlbiQm$qY&:iy@9&wk&
1@/STb nXa+:<PAEmwCSNMF$u/>q6l#wq45buTT<@&4PAEW=ap9Vl*^a=ij49j@iC$ibd^Y1DyAXL\iI:&Xit:\
4q*kpi XMGYW&@4#QXy$PZ8q+HLtuSmWhZ+WaLKiJ59@HKulL+TnByBJFwL5>clqdt^5S/$=A16W6@EwQCTL$nH
-A^D:: 00008288ec600110333 Page 220 of binaries1.zip
BmcT/V =4?AhJB6DYp?Y@Pa5T*d^A!VS>ZA\dK$bB1mIl$5+Tc$NqRTT%^w#JC%95W%b&e1$%m9:lbbPPC^<GX8
#bkcyb DjHc^*q?:@pA5CMY$EP4T!aNNXVKci4:kKbI1akVjwE/Nw<n5jNJIl$#bAp8AmhETYct4At:AWb$iQq+
=\h58y TnCKV=HH^/mn/$dq\&+#Q\9m?&/w4LW?^VDWCMiR5QtEA=&bJ/I?iy:+a<?E/$$&XV4Kh^+A\&@Qu%4j
BHHwJm \E#uGZ1+FjA:W%=+KcRbuRPnpXyY!hy>L+/d=tP+KwA/:%ta64pcV:1qXhkQ#4YmpdhZ$+PPF6D5Bd+?
hP9Sip N4>^9EwnK<eahqw+HZbkuCnS<p%MFEtbR8tc9QM:*?HGe>w:LYdB:Yijh:JGwmumB@i=A8ed/FYjhcD8
INZ+<p kZ*QI*nhJhNPS>w&c:>?t/DNPKnWjW9*ADmAYj4k%^VFHZ5@Ck^l^T\tYXQRc*i+:jHIjFKl<GEuVA&y
/VbEE1 5J<iI*<YqCY/bVkN/ZGZFjb&!ZhH>!6t$V/m+FjeJEEY:!l/iaSbqjy4Q5$1d>L$ch>l61@mHtc4b>RZ
N:lA>: Yd8mZqSYu=@l\\AcQ??WDTS*6$hKh8NY<EX>M*%?4#H\y4%!95\hRil!l<k6cX<Ae<mu%!Su=Zu?/=&P
k&4a!m YLXbC/=ZWXt\Wc8<#<+49F<@AFV85t:D<itPZET8/&5E+aI&pm?!iIi?>8!>q/q9tl^W<m<+5S&ClwVA
eVB4PK nt/m@LKqiiE?kcBY<cGbaXihau^SSiKdk1D4=?kw4!j*/qW^D+DDb*WQkFnQnl&h4/n*Bh<iu!Z8>uQA
=1pbZq 9hLAam9w*utQy+QH?^6ppQ<>*T^GJ*XFdXnV$lQ^&T@>$YPj?M8ilA>C!RBm&$65NSAKAQaj:MYy9P8t
hA$L1! %9=X#D@K^YG@@j#/u?XCjH&:=<AVZ8aAda+GjNQ\qGNi<GQ:WJFC!5:6/5XTQ:u8wkabV$ljRdXTQYZp
4^t9n% W\cXCJ@dT@9d5tjpD+Dbn8eQAI1L*/LDTP>pQ@8iM=q<QaG>#at8<VC:*S8*jK!J\WTNJ@91TwC\^1SP
bSjaDa AL$RQc+h=ejik69*F?Zh\6R45HQKSIE/85GtBtHcJnABV!pjAA\Lk:=Z4P<jAIM%/j>cL^:*L+RjAHRt
lLwqW@ ^\d+94\ZA:iXYcQQd6/SQRD!QARQM?&@/n>L/dl!iZanGZBj5yj#AQnncVu?LB@1:@JNpJ/@/&D*Qh#Q
6>n@&4 8w!G9XN>6JMa!!=\:!6DH\BTy:=#@JiC9@KWwdT:>ytbXH9FW4ZTNq@5hPdZkqVatb\\!Ckm?%>lV4?P
/lFk*/ 1TL!!j5c9lhJd=<dwITRSQY$Jh#cX!+yie4*?w5MB!:#<uIMj%&n:@C:e%/5P/CqEI>jV>N49d!9n65t
9SX?EG P96e\jWX1lX<:w>VW?/<cq?ty:NQFwL%Q#Gi:&Z!L@n8Ae?9:4Nb/4i\l?8a$CTwLuFE\mwIGAGBh9^P
+?J?Y% L+Iu615aLKbGmm&>=N5KXm!/cEQyiqI&q:<FBQG?Ll/Ke6:5R+ER$5^/RRc*%@LH/<8M*9hl@m?>9=C<
dp4JJu bmhqSh!XGQnl%+AFLTD\/AkSPn*LtMEHtB::m!M@t#:68>hH!%DYtR&:YRJb^t66H1QyM\+X+nyy1wtY
<NqM9h F+XGu#Q#tJ^Nbk/mWiS/>e4Ck/E!?=bieIblHK@!h*#a+pkw!&1=a1\@\M:Xd^%WEhac44cVXhX^1NJ^
99EGlS G/tj5/W!AmSHJF!4B<HjMMcP$J8$ymHChYtX1$tewVe#IF5@ACCh^N%6Mbj#acA#QRFce:M+WCYek5?n
<BG<WN w&%/6pah^:Y*GckiAHCS5C?VTVJ=&CIMl:Wq$VeTi=<yTB!=jJGba9ai5ZW5Y1Z#iA4m9ui:Xp=&EKW9
wi456! R$$T>&Y^h!Xq>5#$bXuDMGTqW48LyZJXPWRXE1y$IWadKLAeR^^1<XcJu+$D+q8=diQ+b&IQ>ljbJP8e
cLJRZX #ayA+9eYCFi8+dJ<<<&!th6ePDNJVdDHI^MNV!b=&kW%WXdFa&XPNlXDc*jk*wd#?j/Ja*<H@1G*aBNF
MMQTpA &6lctTYd5Tic>VMui1WZX@$4?8DK@mJj4+&ZG/V1mY/LGt??QAC5?ZlG\1paDctIJS^%9D<w9td<T8*%
cw=N?P J/@qh+8ma:MZ$Z&#u*Fu$6hIy>>+e6@6#ud5<ub5>?JVDcyHZm+=TSMZ1&G<VbKbuS58%ZSi#!8E9*6c
i?I*CH :A6/AHV8e4TayhdT*4^R8nh:AQmN@Z:Ry&%8E*1jPT8a/498:QQ*d$eN:ZRK*/IG%N%u%$S4@@lYV#Ij
6!T=KC #Dw+Ej&cjA@L@a>9:Q@*FSqn%ZE&$j\A$CSQMiK1i<G9mBRp\=PD%Z*:y+mEld@YpZ^tTWCNc\DX>khA
yhn\C* a%+l6:S=5!e%Vdp/4yYcT9Cdt>&t=mm<n?ldIQ#+Gel/!CK9#GdNIn%y4Ca8lSX1WwKb#=MjX:^jtNjX
I1T*y= %$1TNJ9hSQGk$EX=Q:q9en<i#*R?jpX>EP\=DQp<lpL#BuP=8H^iGB!dy^hhjTV$ADkX*S#wGym@RwnY
&+4DZY cJZa>Y>VHLE>#hd4Jh&$C\:P5m1/98eytmicmk6\RkliuMtDtnpdbXyqKjw&5dLJQ$DJG6+/Fw/TIpqC
V:ikb9 8Vu1:wS^B*?eZI8G9d>5++YK4wnE@ABA^/>cG4>jPD\QIktw*N@QDXIPYVp^wAX1mhl>VKLBD9SYRHYe
$cT9ya V@n!8VQV1C=aQY=?!mVBhynZc5SkR>>CGKwn!tR:KYTCJLP+$%FwaD<w5&Z?ct:ibCBqYJ8TlMI6<aK!
wcYw$T \1i*H=>EknJSC49+aPP^I8*wZRp=M$+Wc%986mnVBIweLSqF9Ynm^tDyCaRMN6eeGKpbD<W*KBdYcLtX
N?9ZKi 8=i\?$bScu6Qk#FK6ku!AYwj/S5+QMQ=#jm>?Wh#+V+?He@T>#k#m?lIJSMk1&Ht/<n@w^@^D44<iYcb
hIchKT n1#Je/59cjTT6?*5np:&e:P5KBX$Ca6@DZ&eWGc^NB+6DPu#=ClebEt%KCPEbYq?c9&<=nkcqW+aM8qP
JJ5NYT XpmE!+$&u+61wXDyjh/5c:hP=WNkdyRu8YtWeYc/Gu1@Cncmcp+bR9VJ/HP*yElb*b%BHS\NqPFCGlF5
Hm!^uw Cp&mJ6@RFVdIqle:ApYX<N5db5N$E=%leVBik>lKLXXwI9/!CJHjnPdGyyi>#Gbn!StXF\M68d?iFRJI
Q9QlS4 nGe$Z<<VLThL4VAFPJn8udIb1DH&PM>+1:jwuwnwJwdJ?q=/BZGVbMR/qR/8NE84bGMlm4^akNR%PD#C
:%Y?Gh jk9Q*CNqP/@Kd^A4/ZDjIDJA&ypFZ!GRka?cAm:Jm=\*JlCZRK5XLPXhCGEQat+V%A\ynV*mAu$R6<SM
FiCHNP <p\M<&bmWDiJC+nB9ncD9ud9W!I6+A!%ZTuIE&dHkQ9cR?q6!A1ht+WnmA<G::M4V1jFJb5*pmVI!R+P
uMbC?a Wjt&1FJ:ZC#GFii:Zbe5R>P$FLdYmS?lKI%Yw*Zk5<\y%#wJY8K:u\/<iTduml$jq$T9Tum&HXH&hp8I
ehhm#m q\*:mTc&?HL>nEle5>SIqB=i6THKIVJ/W=GicpVYGP:6a$?h+&iN%=5^bn!TMWaiiM&#4iKbBGW8*NT#
TBkeRe kBE?/5XjM1mk:p<XTWl=wW!t$1BW=B9ybX^TlT?a^uyN?\Aw>Y\i8y*!:SK<W?$icmniVPJya>Mi:Ruk
GZ=\%W $SRIL#iXiKPjHpNtR4XkLB+c%6@?XlT*BEVdSTFN\VFjaEZ=SQZkKK^\^jViwtM>/:=ph+9&R9\BAQ$A
QX8mBe 8FJE\H\YLIMhNDDRtci5L!:Ddua5T4?MjKdyGQ<%>\Hk:*6VqQ/H>P>4@u8@/^jEWwbRJlIyhMb?p*@q
w@e<u: m1!!P<!V!n5<QZRR6EN:Z4j\^bLTb<K5V@*/>!ed/%jeDd?Hj=!1biLTy8c!qa@Q$G%GWnPIZKkbMm1Q
*&e!AA iGLb<G&>Vn$i96BN6tnuG&d5>VI8b>Rj+<+?/bBVJ@$DdAj!BV<:XZ\A1J$qyeY&9XJE181ME=l#l*u6
MjI:*W !qT$#>NSJjn61tM>m1Gwd$AnI9yeF9M/>:=%EXHYQa:?@YLhT/66>Wl=/HFaQeJ@Z\Pi@G9n5IVtlkmA
%m4AZ# e@uq#Vy>!1B/8F&EnD?515#bS@1Ld/e9Bk=SPMp?ClMTYhSXTB9CLpEIFZ+LC:9cmyt%*GCcHnTEJ$Pp
BC*m#I #Hb:GXC?jq#8Mc+EdedS+*w4^SXJG<MjBwXC48Y/:HZ>1SG8mSGbF*JW$<qT9/twG@b%MFK$w6R>Rnb1
yQE<IM G^D!CmwYy8XYc:6BSK/9W:qNGBn/wW^X^?N!FQ?#D!?JSE9=:b8EF5MyI1*^8V:S<N$qQRPMM1^INMKa
hlEK1N Fn5LSl&NQJkB<&VwJ@:<W4R?d^c#PwmJ/!H>*pBY4klnWd:<9P<8/B6%#YpcckEh@8#1>SE9i%+*bR<S
a$C\qS 8?D8jdL?W?<8nmk:DN<C$e$p4uVHR\iL\>kwncdV?K8W%FhEIbTu&Ekw%=/&S6VS!XX#Y%Jj!b$waVmN
4=F!pa 6VD8p>?LYH<VqHjLdc#4VDBlCLP9A#^6%/JW/\m+FB>FH<F@4kTHBE<%iXukNMd>ZJJEPa%GCPH!58Z4
6GDi\X R4^j%eJ%<*NITu1<>De*$cqEKV=9HkDEj=nu#nH@H6M%i9LdKP9:>%GYGjZn#KP=I%@NNuMm=mSY$thK
<p%Tpw JI<*m@y?T@Z$:C:6bibm>66/nyi/CSKP</Bm*TKY#VbpS^*cd^<j:aT5Gja*T^GN%cPbGc>1+!JFin<G
W5pnDY 5l&?dD44J?adHKT?XJMYX#qTy%a%$&BWpD%&/>8Jk#P^NEPu5pB<Wp5GRNtiaeC**SPtw1BHP^qTlq9i
Z5au81 :%MVqNC!q$LDdKJinK=VwLKn::JWTFktT5J^VDRNEycj@IIF^*id>/\FtqRPITEC>R4#^n#Z6**4$hc^
cpuL?> 9GNZi:KwI%WenecI6=uuiQyFXTH:C&\q?KBSQABQtD@<w#S$=qN^C/HNiqknaaWWckJ/hNNIa%MHjC$K
?Fd6IQ NPEXNM6p5RjA!+FH1&Zt^4maw$ALZSSdumhyi!W5:BbyyXVV6>b6\CimhuPjAwIIMI#9Q/q1Byl!\\Ij
MAYIR/ 51qn*u$l9R%ZQElJteW^naB+T+*^/8Xmcb^PF>EEH^&GqNZalbwM1yXEe+dZ!\!Xt/qi/Fj?FT1YRy*A
&KLJAY pt5lqFpw&@PwkwLTaM8KSJqpJDFDS^XlV5wcYP!d5XV*/ATmLadKXyXT9VMq6+>8iKYyM?Yyw<Ha8%yT
+hLNZu Ck<AC\^9L@ZRIyt$>a^<m*!q@SyRbkR/uGC\@8<CldX\Yj*iVy#@>a<=H?*6$Ph=!tuiKF5i=kql^euc
i=TINM H5yW4QXA!9M*$S?5YE!Q9yyqCy+L<4caIiL+b=X#KA88PV/cujZ*KcZ!BCE4W8?IYkPeSZViN^MA:>dw
QkyG#9 J=AVZ1cbnGlG86D!C$^<G&41^4Sj<&Z\P<i#@cP!@:WBK*qNk$V/eweI1wRKb!E/tE8+w//4Fn:=Hm+<
QGen?9 *kZY>kGkj94!h=HVR8?@Sh?LF%*&KitwPR@a:G=TIk:^u>@a1MZWTw$*$Gq:pSISJ9FEhyMJpGMS*$iW
4#VBTj @@jmZ5<bh^XbXw>\HSX6#mkpTcEPPTAXcb++cy!N5MZR\IP=HXypme+6u!M=ktLbF=%*L&:jQ:/=wK#Y
@ZHK^a Ql*bZ@Q?bq&jeqZe*#e?AALmH%>D#<Pn9*d6?XKYQRCW5+am#IeE4\p%H8?p/>5%>Dl$Z@n/Nhl@8Y1/
Y9q9Cc Je1/WmVFJd*\9=jW9M<VnMedm@Q>W$F@8weAm?Ai<Dc1/p:Cq+a>@hEGY:jX9d6:4Cba&5eZ#D*MZMjc
CCQdd/ @N1y$/Nh:1*uP+:+qjnbVeT>NM1jB\euSM96ClZCal4Qm85BmmjKtjWcn/@Lh?i8KW8lElL<XCVid!bM
-A!tb9 0009a462fea00110333 Page 221 of binaries1.zip
t=l6K% %pjCiL&%<LRn6V:YQ::<yNMPJiQwE/FcdRdXQ1JqG%:cMjFWuT<$MhmGbLHej=uDlT\RTVR%LlBq9QF?
L&<iB1 K6V?S9N+8y=Kp@lF<aj*1%Lmy8EJF4GP@AAj^KGR/PRq8>K^&%d4h9BSe1+BVG@kJn*=up!T<ukGa$<+
twW\PB =qcn$ptm<cR/eLy?P##lekKdV8nJFjK*y=ljJSdj6:dGVS\YnIdp^<9WTiWZ/?TZ4@lh8%i+LSj!Ei8e
YH=d?# K=dQ>^$lcJAJjwlT^FaiyIeIQb#NQw4R%%TJk1#Vi95&\69$PB<l!qZB?4d\%b9wtn/N98#l&41G:9:M
e=IRTq $pHKIJ+CdG$%l9N4wKqX=Dj#/BFLVA:tAdKyQn^Npe+du$VQKJMai=u/B\Dhy*aK%#E=mbtKeAKM>6lm
A!EueT uTDXwYhBF8=R4Jj#?ikbP8DMnPNYpYwc$HNEA/9/VZTC9Jw?%VJGI#NL=GLDdm!6HyZAW/YGy?:k9nNE
%:^lj< *8&*VhIF$hN8kJV^dVYwh6c\Fu!\5WX?aBw<Xk=q<Vd>GtuR8*L*n@PQY8RtPl!qBkqkTnVSWLL\K$bb
E1i/FP 9y:B6uyK4DJ*pttkq=6EdXmQiFV*yB1a*w5<ai@>F8!^a=&qInQkMFWnw@R1#t8WAjYE8EWXWaQbKRaH
qHYI5J qLC&INVjuq!=HYS<6Y9M&LF$?6SB#QF4RQlNBFVKCdRc?T8H4RWRA56qlaYZT=>1Tt^iyIu=41blL$D1
y5F1pQ SMh&lnS$?iITVR1QB<9PFFN=h6c&+/6jtHHqYDwZ\@H:P8QTtL6CME^a4=1c!=jPiK68^K!!i1yZFK^5
hPEC*K W5&5=Thal4QBH=J4N$@+hCZPB@GKXikJ\BHTm<wtTAQ\P&>uCnQ$l8\>VCFk9?AKT$YGF%El>y/bW/pb
NZ5j?c F%@Pu=m!R:5I%PVGlM9MFFmK6m>491\y$9PnVeLHp6\@HqZlWNGmKBa9V#SiR>deQApKTcP!IdcyjP6j
N/j=ay wLZ<ARPBFekke!^!VB<1m^&^kP^IiTkbD*N=B>>h%X<dp$GlwbNAnML\B6t4e*CK/a!@6QR?VRI@^AEl
A<dhS+ WX%F%&RbN$A=iPiNwa5#jy+!dt>a\ICnPpXiD%#*jtebe<FtAqb$BHh+4^J1RAmSFbdGG<jQ==bepS#L
:6QZJu Pl@/b=yK&LXaT5hW=kSS\+uW&V9iy61BF&iD6P&$1SBKiitc*8^dCKaKh&pyM$?9Gl!WIZED^J>IW$yD
4Hy&^5 %=SY#V%&m%nAN#pa\5%!^AeARed:n4PT5dCPj\q=Q8Qn@ecw9DWEi!5hVC@+=j\BWLqYlhtu*@>5?\H\
ntpKG= P94ii8!Qw*S5h*#j?H5T\c>X*L<jeNtw4=nhK%=:QAB&Y@<+?t*Tt@^XePN^tE/:?PQI@GeFY?SX=+uB
GXMyHq FaNb<XeIAn:jPq&Q*Gchun$A^n#4nC8*YM>>i^/Hj5:hQ+:G\qwmPl+HRqVT&+Z$Q+=ICT=eST\Hy>5e
9PRB!d %VN?IJbKnP<V*$:W4&YebQh8D+BZyBecDEW@pKmQH9cm/Sd\KHKhC81i@VZE+!&NT:*@1^IlDy61LB6B
quNGSy BuTY1RkM@WJCeqE%aR$/Yha>&GI@1Ip#FM&%V!tC&+@NMEi$W6Y^^8a:8Qhw^@CWhu^Z^Yk:L??@B6^L
GZB&VZ C6+yn\%@8:8A9a*!9epLK#9:D<ZCF%6y<6uAP*K&!pZ#w/HFNRlu14*mPpQJiDS*>H:\KN=Y^HQ\&dSX
$/u:R@ i8?Ed$<iAADB*ZJ%^S>We6k@1<R<u*S<:SV1*1yQ:a<Gc@:>!KQku=X5>WiJCuH8Mml:Ge?98G\W#neJ
iCHI^: yVTWl$bppaR>@F1u<#t4KGjiPM4>/dZ:S&DyGV?WaEw>FDnRKmqli?*n>c*9jP<DwJeQ>p/jYZDd&@i^
GP?Kc@ LXQN8>jPWAIiAJ1!mq>JTY@u$t>F5**uytj8JZ@VG8PTJB9tB\Dc98CX!?NAHQ8dqNwh@^<5kS:&!>AF
:YcL^/ u8w>?cV9+eHnLJ*!6<c9VZ<&Tc!NWtaFBRt9G/ncEeAIKSCl#6G=<HqGZ@hGTe:Rad<9TJJcA&qRJ1cV
IaeF!q dcuWP9ABwHYihchQ?RBwj4#duM*c*$+yjn>X6?%QLba8$^8Dy5FP:YFi>=k>R&MTF$A#$#pD&+i><hn5
#ceMZ: pbu:aKJ6>=yuEVS1/p/8:uG/$aZX=QPC?E!\*FQ^9nL&AdAm@Gl!N64@@hV*:&eMk#m6pk\\li5Eadiu
CPDI^w ScPQ</n?=H9R<kNkXp\L>+lE>RFRq8@:Be**ymIm6VZhEV@+yRR?ybYVbIeVM4JE9#&Siy#lW^Ya6*WY
9?=6l9 mRR!4ZLKeBwMeZqNGKMJ+GhE$T<XB$uQb/\jJ^\Xn*P@8yi!k+J@uNcwtjL=NE@Z6*hpS?mh8iW=<j5Q
%8!!tM cqCeNcqVpi/e<4A\k:+1m?4H$5/4dG1LQ5FSJ5k4\8EZem4c!FG9ZJ:epJ!>>Z5AMHN%ZKc6Ziq!#:aG
*1%@Q& @HGGdha59X6%9T9/AGCjJ:*CS<G=?=MkNWQY&*ndWiy9/@e\!$N$V16SIwl%I8pJ$jZWp:98Dt@Q?Jqi
uyBJnS ?k1=tQJXFCQBWh8lK>\nqeQh5KHP<^e>1wFW^$i!B<DnZiR@ucV6WEJkKBNiYFA9<eLmGDCjhwm56A?6
XiViT+ GJqaik&W>n@y\lLZCcuqSlQBD1HA8wb5+QYYVN+I9VMb>4%!md:jSQ%dyj#6LQ#9b#X15qyY8=8+81>1
LCS*e* <k6&TewD*!X4RLMT5HanuH=:5qCJ4!$$Q?@&iX#a\ql1MT1\NAn<4V4?H&*$:G>6qQ/uFk54%Bu+NpS/
@SnCNF &/j>&J^1QIKW*Z9D\4FSBalab4Gmc^\wWq&#b=bTaIyt\V@4hLu1d??uShVL!8VHY1*&Hba>ikB+bZ*\
nK=cel :iC:!@JiLH6+@!P1Kk/&:@q5&Zq=Pj<QT\!q@Q?l^FAb%I4?aF#P1q^iktD!h#4+iS9XXqE\\9+qEGWM
1NaTVN HIw\VQCd@WCtW1jbliANwj\GtC=SStTWWiN#eBAwbQlJh$#yA$MplF#yeIXS:u4LMGk:q:$tbuK+i:lM
w+dW5% %y1S^Xqqp!NKbjd$aLnHbw6SIh!GHqt?T+!9Q&KpW+t:C1JVYcCQeR!I%TMd#!11eCqQ@tR!^=Ri9cI4
qBDKX? pl4W^%liJe=m>IccS^X^hypqCQPXeVP!hjyuLESG6daujA=#56K1G#F&#c1!a+bjNM1/%$FSmHeBCuL^
1X9%YS +DPe*HHu<$N^F5nZ5CFS%tmJIlmtZFkX<c@MY&64^4V\^c^q&Ra@IAakiwlinPcyjQCVTbXit5ZK4R>&
G8ZDi1 KNad4#6<y:FYk/um/jBd/mj1<6\<9N:S81i8$kn8wlmkWS8Hnekk1MB98qQuBijNyy>FpdBWQ1b6QJHd
H<uN45 R6E%u?ebQWQYkmnuqKkC*=dJGKDNB<YN8<=K^t8@q@8Eblb@Fb?m=HuCIXJ44Z5SF<R&S?<=ne%Xw4Z6
Wk>H9? l1NiBwRcn^waa%IRqhJFw>D+YL5^%8WwCXKnaK<<W!iyD>ccu6?dZIFVXnP\1cAYlyFVRG$8H6ESK?#\
lmy%99 L!Tuw6XpGKbcEBauBFi&cLAMKHIK9G88pC&9\^1b=bhP:5MZp&pIQl16t^?@8ahybYemqWR=bT!&uA*C
QY=ilT +#9p%>SBqe!FeT4n\cq5=qhF?EyEuIA%LX4q?pyFXc!Wt*Z@@Jm@F!^Gm*Z!aW>=u/ZuiT8YNRlPYbub
\NY&Gm k=u*VK+8RcVb#bHW?AF*pp=lI9SL1T4GMtIAySQ!tD&*Pep1&k55/$lpVLyLwV4Mw*MY1emWVC&c@J+Z
Q89kD1 EcJ!pR!9^X>qbqGM15BbN4LC!S#MM*m^H$y%6%M%F/mddDwAP@uIuW=DJ46t=GVui64#J>jqbGKaR+\<
b+TKRu P>BM<>?p?:DdeT+$=B:t1cjY5mydDBhy=t<y++qKu>tmF\#Yq&N*X:AkZGEXBS=tGt$=GJHSMWAYup18
%!la6T VDtm=E!nJRjt+wutt+9KLAp&#ZJmIkb5?=TI<cYwHCG@F+6/Jb9hAd4&41NA%GWi6kYXF4kEGT6:^1J&
Sdyi#@ cdSa>PN4Q+GKpSGR=4uidXI?=hGNaD6QlGWKFC/d=6^Zw+hSE$w$>eh&RE:BKj<em4p5M/?/$*YCd$a%
uXSbmV k#IhDdIQ+T5DW6YHG^wD/cLEYYHj9eM&ZYA?8KM4pTbBpC$JWyH!8!tlHW\W>S=nh1b\^eXt=S:S?emm
+kncbm *PnXkiW^npP%ycR1Hy5T$@QW@LA!k&NJNbu#A=8//hiZHDkWa=<**e*CX8#CjYB45Al&DYQWFWH!q:RB
wVeT*u BFMwN^kmWS/68PwC%=qL@m11^?@ceX@In5y&Km4&mctKuCnkDq9K%FukDMNKuGNEXIyQh>qYN>H$FL#d
?V<FYZ lSqG$aiK&<A4GmdW6lVZK$#I^T^&<kCYmG?LZK1EHC4DSXX5PAqV9Iwj:/R4k^h9V/FJK$eu%niAm!Bu
eR9uHJ *AWWL5QSwZ!ERPn%W1W=BFtKYdEE5ASSHS:X$ju9:A1JPbm*#:1\m#pjF?cWFB=yEjqbX5?QXi$lBJt\
LAuMM/ P:CFKDP<9>wjl9i9X$C\E^CP8?AYLqXY4keKkcYiIlkwi:L9#K?JR=+G9+qRN\B&j%m/uM<iLY6SRkkL
5YP<WJ 4!k^k!I5e<<dw8G9^ZGb%mPk%Fl+19&8L&&aed1qHIZ/5J$/?E^LlMWJNLp\Na8uVlcQ<^w?eaWHK*hA
!h:VEw 5>M5NMK!l^HBKqP&*Nld=mXCmhMlEb6^8Y9Bh9j:5HByBE9ZNE9da+E/DQ%>FN\*WWD$5iJ+YYHSPZQ^
R+YHHQ Zl=a\QBaiG?*j>Zp\iL$RnBEn18B?F!9EmbBCub+J<#+F=RWLb\Zp$wIjM>nCQE\w6XW^NBF!QHA\b:d
$*nMSj c:u<JDD1%#m%F=!^\:^F>J%#8*G=pRtEM$+Ijm8B#\DFBKHNEp>:n#MVB#NqeLY+ne^+metPn4eQaFSD
SFJG&< Ry%ei$XJFqK8nLWGNbpdth/6Se\al*>E^!nAK#VRV@hnbabW$6*P^X/q$IN^a^yK/q^N\X41lNqZn>4k
NimjpH yNK@I1bSQ!/^JCHaRb%>CSZwmIFhibYb4/b5B?N^kJcnTyNL</HAS559IYqW\lyCdMqmCu&dG%NMQQR>
8&TRuD pK<QKV+kV5AHAY1MVIJE4@e#DlICJCj@:uaku9iw<nVKkYC/R*d5LRk^B5BGLS\J+Z<cS!k>Kac<q^?I
+8Ze8d l9dDTRH:L?d$EQ$qH56@I/@<uY*8N<S9%HJ@b/V::#Jde9!QMny#eHJ<^&#JCj4XJKce:D<m5iV+umCS
N%C@AX +^eVH*N\kH<B?^MTT\:PZ<B!@AVL>b?^uL\@#pHB\j$LYA/iH&N=@nQ&N*4EH&J=j\H:+!VCHGC&Z<C!
l/yG9M @bkQE5#?u:EeQD@Bku+B?^MiT9A9/BZHV>J%kH>B4*=n=@\l>lj$/4e<GV@E@wJikZ/TB\d<C*wF?uHT
HcWBRb e\:\L?kXP?>QhPMZ>P1uJKYe9/JaZD@8@J#5@<d8!jEjE@*?M!jJd?!i*N<u?9*:aQb9>l!aubj>@<>Q
p=HPkN <n@PV&L:4@qJ@yH%A^yN!eI9?GP%iR>M<dwyH48NDh5a^!6X@mP\NJ$^Fy\nw6b6+^chCmERYhcPq%M+
!dh6am &\pL^W@GG\5b?XJqD5cwW+t>j+^8Fc5?#&IDP\n1lWk$EF%Nt#yaPZ5QL#k&*=blkA*Vdnba8LWey&m/
uIeAX4 ?H^NyydI:t?ySECC:Kc9&YDm!pTbyWG6HY^BWM$>hAwZEbdeE<liK8<FRiGKV=AwVbW^P=Z^>P+dN:Hp
+u5*yh &WelM51+kDYZGXlIZZJ6LLI#apAebVWmc<Kk&Ik&?d/y&\AmIA6t!Db:X:FDtbD$+e$aZHV%GtXjRAH$
tp11yk <yD!hy=S@a#eT@4?!\?!^H$B^IwMM!/>L!XHIiL6tJ1t=cbIJVADu=51Sn+X^y^$WTjE/b??6Jy?n$Ew
-AY*i\ 000e8be39d200110333 Page 222 of binaries1.zip
HJhkNC !%6ci#uG5InS5CG?1pcXTn?PWh!DJ*J8E$P5\ec+nk8Vp&KVNA4lqMQV%uC$@4tuK96nIBB!*dR$mCJ:
XR+P>e >mM#tkm##9#ShWp+cMQ@>1bu4Hh\qZ5/*JuNdGLbEE5ZQeXI!q^^4l696ajjmBTJ$9wdR<ma?8i=!AAY
b$1tyq CF6\:44TdSCBANJWEFV+?jT5eERy?EmWcjEP$W?iXF6w@Gb^4ic>$?TNYW1ecwSAh@+!*#m/GSB>!Jab
WW&+J5 Nd19kWuTXXi?VbF8kHXYuRheMhwGGH:dkp$*iF:S<+JVYNVTRbBQImE=CF8?>5Pbc<Dq\ule=8L\S\RQ
ZX/<EI y*yN8w8B^B/b*dPWle6LT&G=y8#u/JF%a5>F^=Gdi:FtqLhdij6W4tT6*Kil5BuFjCLtd$iYDdD%k8ec
W/%HwX HKyip<iJlyY$4V/JDu/LIkFp<YSed6yBcN\QBC$t5H?wY/p9jcXHiT>VhMdH:H?DkH>nCFQmRXFKbaiQ
lK6P*H /eYpS?@1JyVjmwY4\8E*yLdEJ/pXMRbj<GJ+>G&&?/=+&Ney19KTh#qN%\mRciQKX4bHBGyYuey=pX1H
TT:R/M #CXFi%:XttF8BnFMYE^BjCpR6ey!#\>i?IeRyRY<#iY&j5Ndcq1eGQ98qiJ+NX+#EBGHJJiJK^KP4aIL
MdjP+P /YnYGwQy+&SXm@p#SGG@XZQW!/W/MSldbTJJd1Nbdm1k^GeeQu6y9?bb@%q#/=^*em1lL6N>YN+Ey4IS
1^Z+1d <uVn+p&>KeWb$@#mjtJ4FJ%H=Kd<Qw^^&uV%?h::c?\FeBX<6MI\X9Q!=%teey\X8RPThGQTHTHFb^Ka
L5^lL* Y*c^H!lFuWNBKAZ+RWDqnCd^tIlAwJDcS&pdb*My?Ie<E:8h^Dw?thKu*WJ^*88bdHSTB%/PSYwTZikE
/*R6?A uGIPq<9D%V4F\nIeNphLL5Kcw+tm6XW9XGh=Y/Hn+5bcn+GAWc!^Sl?p&I8VWCS+R54>$kT%HqI9mi9y
dH/jt\ kq=9a6wqL8XSc8%&&F:bLMyhbyTN<D4a?WF<VC4d$Viu6epj8+j>TNPElTnjQ1@$Sb*BpA^Xw$t:>I4i
BTR!%% K^Y%CKe&j64HK^H@68dNaAR@==W?EE1ESWE=Wu%&*TA!eqFSH6H!tF1#mLiR\ADbwuhh@cdS>nC@^WaG
N*p!FA w%J8aB$>l*$hRwI?qNCEZJy$KMX5*&WC!KH&Yj=eRF@b6TIA/!Xy5ak:Fh88=46Pe:8qN?H8^Rnlijl8
T8TAX9 :#cuA@*p4#?wiW#yR\T==eQkyLKd<BjR*>#=>ad!y?Ydb+:=j>TYQYlZaYR%Pb/Y$@?MVT1<6AB><6JZ
dX!e&Y IpwkpKLjumWd&J>pMW+=!>Wh9@M!yLd5iC1>+TcnK/PY/#M!?8KiM5ZRptjLQD5dl1FTAcN?/69#LnbC
&>VB%6 R!XM:R\>MZib##T/#Km1JRX9G+eYS9ie=e4Y/Wye&h5G6q8ndD%#JM!uT>P>1pm:Z?TEhp&y=JP6ce&Y
V*>HIS q4qa9SRt$ER4KEKnF>>Q=b=@:S*BRCkNXuVVjw5Xa&@+JCtW>pS!$RLhb6/aEmYup\jt15jMwQYy:KKE
J$Xb4C ?\a@\^8Dhq^=8kmmAC?iG@WSFn1ZtAqh8Ae^A#\/N>h*$cBEJ^VlE6:<%%Mw$?:LM6a9#m9FjbI/up@J
1CVLRy RRSPhZIVD/X9?hHK6$KuP4XD%+8%Kb4lWL+dW8mtk:I4$li4+j1KwW<V6EII=TNVG*KnZuCahpDLlAp8
b?Yyl= LmNpA<IYXbnEecd^V5n&GG^RXDK=umaqb9n#&KbSMatKm?A8HLl54Ta%1\<m9NeYK?PLJhD&u5JXitaN
iS!B@! #<b=GMB=AE?5G&NZ<&uJINabqhn$m%HbKl=*9ciMSjiML?LM6Hj\\V1jiGF@:liM>An#SH>qHdbw>LP*
#>CYn8 Em:#P:PiG/K=6=#8S&eChIp+6e\4+d*wanny:aBadQ@EWLq^twy9m+1^d$/F>QDFQ&Z9aI1t&K8?8?I*
q%9WLJ \1*!&kJNTQQTL!VTYluu?hVqi<AWyL>Lm+eKEJXlq5unbLP#Y*uS1?!E/%\1N4*LLm+?YDmDup&Xt+^B
^uX4jJ *=:uRD?enYZ?EBeBui/mTqkEVA:dhNacCG%nheF19>nJPCki*M8RbqMYWHuP&^b?u!ji?%Iy:9\Tb8tl
=ppCkt bune+<$FWw6+%N8kb+iG?1hIi8@kQeqpC:Cm5=$wdV/bl@R1\B&8tm^K9EDEV+N>mj!NcW?R=um!6K$@
==P<w^ wlyudPhw1/iy^&*!ekXV<ENY1iYREW5KLNdJtdTIG:AZAb:\lTleH++8hN8YSd4WBV\*FtH4&*T/?&j=
9PEhPn &l$k>9/uM1R9#8a/KJK>?/pce%/CC@5V:uZDZMdSW>T%w:t/&eV!L41Ta/&ew1:Xl=#YGV+kXWiSnhdM
CN6!de X:H+\?i1HC#qWK:*Nke:QhBYT5GDHKJ9kIDi8?&Q>\XQAKNW6=%KTj8F9jIa!SLVF?aiT&Ncy5P:6AG*
/Ec6*w 5lYt+$kAkiFdIZt8I=neI?lZY!Elm@<Zi?<B%qT!^k<u>JLRRRVSWJRipyN#W1mlh\m>mkpRIQR1hpNH
p:K\u\ SWSEShhCW:EnwtIHRWXFSWV5Clb51Nlhhh*9uIkwTh#N9h:9?e4#**9*ae<9<<:9ubq**8p#Cm1HN&<8
AC9dR9 ZX#wqFLl?d^1WFcCjN>l:+n%9J$6D====ByMZ86>h5jmQk?ndS/d1nPeD>*64P=+WLjeMLBJ$8VJE<8+
I!PaA/ pq&uHD*pGw@NRjt@9j@cJc$uwuEPJXcM@N!N+cE4LlH+5RiW/i+#L#5$L@4>u<tuQ4%E&X:eWP9\%IG#
iJ9?+* &eQ<eV1*c<9yDS%m<=\46K+9e5qQw<5>4ak55jT8tFVFjFHTWCh6jE>TVm&CMc%RIkWdB!h#*cDW&*iJ
=I1kaJ 6<WVjGlmd<<*Pi!iF6t@9jCS1eRV#%qZp%S8JYpwFDc:L#uXnL>VnWq?<\#j5>$5c5q=tecK=c<TDp69
%6wuW& %HTZt@P5hZXN+mYDRepZeVhP84SE&<nk9%=\HG=>5t*:<4c=meWd#<6IKtPpPA5/B?/WyaF#lmwnyG#n
R6w?Wm #1/:W@B&R?IXYd>i<8QYhKhw#$T69R:duE6cIELXwqkZ!h%/ke>&/9w11^I96C=ybq/+h&@##A*NTy&t
jAW@jj 5aj4Z%<:KZN</+aLe8>6&$/eLqL#:Gwh1dS$*uyqw9i5hihHFmqXb^htj6k<<^a#TiLlpL85*G^@H@it
QReJWP cLDthV/?&WiyDuT/hZJVbVd*uKGe!Xay%N=qC?KTTu%:=?I<FywMFViydQCSytcZq1??%DWnLhq=PiaF
qyIeC8 8@JW&\DG&FumeV1t6>SFlh/jZ6^tdn*5TjCLK>=dWXFhp%!=TPK$&#S9d^uZXHpew?48E=ZDY%<9i:%6
XW&6wK A?Na@ucV/S!=<FhNW=%VD=8/#N6!WiEBWZFc6H==qXt5t%?T%L*C8JHt:pi9uIyV<HdPQwZiP#+XyS5Y
u4Wn%! G<1pHCpcin5>NuNda+Xuy+j:mnuMe$PkW:!PRX!^SdG*e9>5jX6*tY&8Qh4GJIX*T94m!l5<Z<c?:h%n
e1n41* E95aG1y+&*CH\qp5FS8HCVkqmeYddNQ$p8%WRJ*%ZFV&hFtM8NEqe9=$eqj@y/:I6R=QI/Rt8VAdAynD
PcYdj@ abLpkZLeu9LiP*JZyL*Zlm%hKH68@/Npy#I%4a%Q+waq%:1nHyihi#Cn5?+&8^Le+lW#Wk$&bnQQ%iTj
N6cc^1 *hB^@t?Nyi?W#8^XT!\PTMGHGk#99D\TVW1#Y^/%NmCZ/qVS8pTDwy>KN:@ua9Rciny6&=+9ij/HPlP9
6yYqdI 8m%SuJyb11BY:d=dG<l1NGqMQ8E*$!X#t<h88YPu*Xdh>%BAQT%?LVPIaV#Ni4Fk:?6QR$buC%/aQw8t
?bGlYJ MC6ZXy:k9m+^Xqq5iMdk\%/6ymYq*Kiu\lhy*K+M<hS*KHMQVW\yMTwyhP$<:ZZG&8ZCbDJ+Nt%S<6P1
kX5>nG K>:FYL<mp?M8i:#j&Xm?<>nRq4C8e4@:4p6VT8adeb@=P+W^tq9j9XEy8BLQWDeNAn@Lhda=JVMQP1aG
*T+yI@ Ge=\nV:&WHLYYypwVPK^nX%j!K@iT$wiqHmba8c**M!>R<>\*bH:4=&ah>aSNYj9NA6/%S*1H%!D>jDj
EY4Z@m %*l>!#=>+/ed#$:8&!+VXuH4Re6RpahL8WK\:eW*$^nK*timum$J9@^mn$u>#ADbdPl%58T&I?+Kk>P*
5mw=:i hFQmX%$9Y&LDVQ!\a:d6%Kkl@>/V=hYTpkd*$1IiP^%=>SDV&Fj1\4qmit>d?nP^HhmbVcZu&PZhZwtL
#LR^ce D=/bqb?<X%NhdLcQpy<uNh\+n5L5^>T<judlFtQFtVAy6RhZXwXpjY!/&L#!RW>V!cwE>^$:A+Q6*E/S
\Y6\AL u:VPWAb&5KWWAn%N8y$N$:*ty1W8Tq!eZ*#m<Ya:1iYAk4Np<IQI+6/yHJq+XhNLP8>m1&JZY^hNTDHa
9W*nK> 6499JnSNNn&yb4Zu9Q4aXIYb*b&JN:ZXe5thHc+>LuH/4%J&Z$=yRS$liGV$MK//P$5YH9u#1Y#KywQb
LupSR= *a59Z!u*%9j$#ZB+NXV^qH9dEF9=&Quy8!W$<*=@mJ:lKm<:IY=@N!kbyhBW5ijF1nj#+$#KC*4<8*b9
Zpce*X pC4j/6VR6%\@dVa&P+1dRMu%l:mZ=&Xkk&wauM&6YQ!Dc!6QDByQqD1:JA^<EAJXu*<%jebR>B+NJ9qB
kicen@ &h@B:JShthQQqRa@P<P+Yuy9%a*FY@6ZF#BYLyF&:4<=<i$^@#$qMZIH<%aM#@%A<qtS*y@ytuWm!Bju
y#S1jb =&bR^=AkPD&JVT4>/K=!W*Ik@eudCwyGyiK$LWZkZt@%wP\Pn?VZb/c8SGGcF^\X?=m@W*H1:qLP%VLZ
La6GqY 9lNNP>yYb=1<#EE9W6q6?H1l!V6uV<nIZh141Y<n4uIBynX1PT+6J>54u6*c%SA$yV9F1d/i>pC!hQhp
1&qGyP y!TY/+Ru/18jJ//\Ti\yZiJ?MeuwTASW/F+\B+4JhC<n=5pcqSVhmF?>P&9CM#8*EFLZ9cIQ6m/=VSW>
PEd?y4 AJnW:dR=a>+mb!nDed=ddu/Z+@\LT^hIjKp$VaylS:/j:d@G!!G:!GNXW+4Y&>yXD>JdK#QyWuGbdYu/
@BE81\ JcnL9iZ8m?kR>*4%u/EMh#jGm6me?&ZC*+*?NlH:@+w*pmAl:\DVSH5ntkSBI5mTlV?PA=H@ZScm@pKY
BImla# IwI5JH!iDcKKIE9/lT^NBFtmeFp!+h>q\X@MPbPJI5mC\8j*!IAI55A9bEpm!BJ?IT8CZbF?MhhNF5G8
=I#t&A TPSj!IykX<nCk%BbEi\Kih=M1K\Ih9ZLiXT!KId%m%itKIVjpCZ?l1#A?>K$j=&@@j+mE#J@T^Q!9nTF
/</^dS >J?@#kS?j=$JhyDjH&empuHCutdC@9\&E+pCjp9y/D\^AQ#:6l<WnpE%$MCk$Tl8PkGuJmiXl:=HV/ed
hA$yHV 1Mk6Et9u>1Sda/V#JMS$nb1<>NVpm9IH8X&JW6wK$6H6A^?=Duy!yb$PdyyXZwbL=CV%cpPd\9EV!1V$
@<MIa& qT8/E!B6Pcu:iX%H51$t!=&8H^#=\4ZZXiw1>ChP*lt1ZtqcYPquX8%61H4tIZ1&W$QA#9C#Sj::#n+I
@myl&R MhP\4?t>qN^1c:A/\/u8%d!&/aV15nlH+&4F$8MV#$86<N8^Ibu<^>L:A%LSD>Ky/<4nQbj*DijtKT/V
IG$!6C Z4@=c9Iet\:Fp66DH?dN6*Mc8EW%pBDYWFG?X?MIPQjeW&Qb5>m^Q#>4SRRweE/PF8Z$H&LRj%/R$Q<y
m#XN*a !Q<:C=I5=Pq&I6^w@Q>41%9G@&i&8wt:Nb41L1:yR#c+4Tkl!G&ZdQBIuLWu#>Qp\mtutPwu<q$X6!!9
/LWLmE P++$8K1eJQR^6J&Y@QFiVc:D/ME?cdVDbdXt@Zp4FA=qcCcje6m1bm^Z%l*>l8nwj/Njt/mZiKi%LMd4
-A^DbP 0003e4e948200110333 Page 223 of binaries1.zip
8I1u<h %QG>cQwh&qLMM>5@T5<EDC!XQJ@$8N#Q9nV%^aHc6V+V!Ww18#/BI:FBW$:whZj8J:=bB^KLhK6ARuji
Tdb6P\ H/w&:yYST@^*!ij+HD=V$Sa:ejeX4l@>JFHdbF>^=4DHwbMa4>1IE>5>4qHP%^//ahY*#=J=<J18$<%I
N%S$GC TjGKP?Vte@pQ>nZp$W9\ptI+@$NF6h:4nCWJQS9>h=Pc?:X&%e>:MNF<Xe4ilI9>D>9^!$\:IT1^*i9\
N4<wdV *J$FPkeYKKC>6kc/W:He%9Bu*i@WhpPd=65:u\Z>B+#Tb=WPFYMDhZHuiu6j^T6e%Vj%tMFlMma+XQR$
HkGlZ= HuHah:>FLiTF*QpCTa#JM@$w?cWedMKjA\HKh$bRj5XQXp?%QhKy:L*i@NK=yX?i:NadaJ!!*5=6Xh8X
w4&P=C yuLQetj*pT<hplQi4V9wGPFnumiynw5+eH9:=h6HHWM4aq<?CiPP:MQZd>=#wG>6%^PL4aeZFKwB8i6Z
ENPeeD :E<NG^k<JdX1yum<q=iW9Ec6YE%RbeB5!:PYDKN*H\JT$m>Q\Zh1*=:%=QyNn<H%MVMqDke:JX5E/iQ6
Am8cGQ X/:H?Ld&*4<JtHc/=8h&?*DT\$+w4p!c:yqpclI%YQiM?#Jt9tQE&jXD?WiI66JLI!J$ZM>5!9X@6?dy
HwGQaq u^4eCLp!+G:a5!J$*Lu#1hYG^#C>>VMn#nb$FqPGm#i&b#1^Lt*aGhLch9Qe:ltyZEuLcY/lc9iNFLDM
FAD/lw h5%VwY<:bFNhjQee**Vq&M9R4A1HShqWcWdu>Q:MPYHu4#%bni1jGQE/lLX6\$TT/8c@6E\<<d8eI%cn
bQc19E P9hNpqNQ*NW<iX9XwR>*nYjqykZ4Gq^yK<:QN\4%6RH!m//qlQ64ad1*Mmp1jT5uQdqehmtQ95uSXBLZ
!h=kbD LGHktwlbFil^==L>:QLHHC9DulPcJ:dP\p5&HFpV9P8Ta:W4<iGX+Aum$@ynTTVYhp9ZHR>8NKuWyT^t
d4j89t h4bc8!u6$!*Lu<elELe:DPwNBqdM&cPp6d4myd=u$6:=?E&*68i5/\nj8>*:+iC$LXiHw^#qI:I5@QCd
q!\CF^ >X/@n:&iuu9&cPS/ew#^Xc8elN4iWE*Z#WPVI+<R>4SjPt&kXhCLbm65uZ?$6t6Xp5w&=nJV#XN\>&*V
!*/<$& 8ZAd1bISE+B&JF8HaCT*9PHcSLXy8#$=5/1qmA&WqTtYKuuy!+^&Nt?/d1Gq+9HBl%5:Y\</h8iKAhF4
uJ9qYV pd?!=!E$VXude1F^tN@SeQ\/4?nyRFN=TjZDFMPI6^&dh8YEF=>NKL&:amHS?HZF*89l1!8>hibZ*6yu
?4ak!i >pkVG*uQQhAwiIQBywXVXb4XT%@qd%thtCw*yWw@4wJ^TVq/y4%QM!kle$845hJNSyb+b&454Jw@wtM*
&wG@%b uV&#^c>L:T6PLH^Y1ZKW>ScX@T94W%P>4?9w9/9eP<tpd:H*S>4PNmQV@QyX#qZ#<*ip!d\PVw>VeKh6
&ZcDK4 M?$*PS+<wncu%H%a=uV4?lXZqPwYu!&#Y$^#C!Y%iC/8E#jh$>*w8!1N/L<*K#=PHZ<5itTq?q/j<5j4
maIRL* a?y#hqSZY@dl6=@%MT#!?Bk!>an=AX$LI$$nH#Ym6iFy>Wn^#PC$d1e*lm88T+tL=hl/>bnnh%6QC8M!
K>/4kh %L!mA\Pu!S^jV=+<1H%ynp@K9Zjk^+5L/%HJYJNK%StFH:e>1X&$<eQ%/u%@DQW+bk<=ES\/dcG&TN%#
b5uN$q TVu&@a5t4B1?MPKbp1B!:$>t:4Z*YyISnQVk%K%%6tjc:a>L/nIkI+ic&9P/F?\MGjY?wjnRiM!u^y$:
lJ!H\Z chYG<+1*GMT6/aycZWjD>@9jd5Y4!w86&ni=hVZkJXu4un5aWX$$+<yX^9/1neF6thn&4TcuD%VTdn>=
bNdEEF 9X%y?:GK8CB*<#?iBp#&MKp^#R9c8<lqS+#Q4QplbKqN#1e%kVP#y$?>mneJhDt!95GpVQGt:cPcadd@
\DnwZC C^Qu#99c6?5P46q4**JEi6YNwW:6qE^=Ty#jJt*jJ@Y$caq*5FXHF@89@PD9N?uEZQb=!6uFW>FSc&?8
k45Qb* u9kp4Z649WJA#BY5:y+NG<K=K>V@VQhMu:i9K?nn864J4JP=MaB!NDWk?cD4/e8#ZX&Du$G:pnnHHkh4
4\MntL ^Vi9na+cZDV*@KZl91RN9bW9ulPj9@TIZ%8>%h=^\Zu#ueiQPn#>I#b8AYbP6P!>qwAD:b5Ha+amJ#Wd
Id6yE8 8qPXFu>mLw59*Hd%/1pc1=SCm$Y?\?!lt@i5%8YH*R:h9mXDX1M^/<IKuXZXX%?hu6^R5tCi1uGhX9y^
Cm6wn$ Hb@=Mc48@XcY!?uBEi#q=>$VLE>G*6q<Jnp9*P*JlbPqVa?!imVS^K&tnc5YBL!>iVLnyHjeeL+PmLZK
9$hVLQ th4l$Ci8&pF=5VyB?+M*=$8&kpLD1!Pp!\FSKh&aq!iHn=/4*ui#nB#b?##A+VD\>/+N8ZqKh/b+=P%5
9$R&Ti 96TlGi*wdP9wNV*mtHZFy%jAZj!lm=jmD\S8J@VLijTT#5^bb*d**Qaw:+tDi@cH!D><QR%VWjZ!%y#I
B!wV&u ?5P6p/i>Md8!ea8h#h/@l6VjHnw@+%:lWFTG*8eDtwGp=$5?Vk??6&%>D?NFji14*Ei4=?X@1yX=&qBh
Jp5IjX \>l8I*Z!mpy%qh>udiNFd1uil^@6H*p&YY</@5Q6@kq@P6RyQ1*uTLE=Da@ntpLc#1Ee:mEQkt@J*+R^
6VQ1\l 1Tlc>/JGLidqpbjtL6C#W@uDWX&+lJ4!=1N%A#%DjY%i6tEZnb+^*Pw9YH9JFjw/kjX^ew<T6+56P*R/
aZM@wA 4i%qPuuDMQjL:9TqnY:4Wi61ZGbbQGkMq%?d6Z8hd=P@eRM+^<u@RGNDw$!:4H9D\ea=leQ9q==/*jlW
eZpEwh 45ww4w1lRm\8pW94c>9e6!mS$eM>P?QWB$!cYSVdJ/XmI41LJqi+Xc#CZF4l4jH8V4deYe?CL$9PjRWc
9wq9XJ RQc8+yKc5%9$FY1MZGYp=lAdtdPNM#Q\%\kNnb+n4Vj1Qu=1Pwq65qjA*lywZF6peKP?t*G\/dbC9HYl
&V1ndN &?c6S8&1em:t$W?WP\?4TL%i%LN4^e/1PV65HSq4L:y8\lnWV+k*P:bLZ9%m=yyLC#1eDm*i5%J6%&Sm
HEwJME %=&V/ctjZ$!LJe\M<CG\5XLQH?#wdYVpD4&i4dB=*tM/J@4Gk=K%u=PDa*1A9m%86!=&Y$\XC:9aF>dy
M6ZnIV Wi6XHD4W9iSq:?4<F=9eb&GMbjB:Zp51Fii+Y6+hTXlhR4DIH?KMcM*TX:pyATu/:SbZ:NBPGJ41@q41
#i1BhZ *DW4tTPX8PFX5uyd#Nj%eBKqW4Pjq&!4PqZ%>hte9E*4*FMiBG/44nS81m:<\yJ\qeSd8*Q9QKq::XW8
+*qBe! 6Rw%FPbpEtn&>pJy*jHwi+F:Nu!RKb*qH!eyLjYIM/*DQj9&Bd$IaLclu+:yE!at46hlM*=8e>icqI$c
He^/ah $Y6jZ^1i\>Edhy18u>kj1&C1*/p6*1A9<XK9wM%Qht8JbQIm!W&b9p*Mh<<iPJ$6$itM*F/nS1G4Ei:9
P4K8XB D*JYmc&VM8=+j@ny&:*dNjh$XIPLn>pHtNl*eE%R!TGwTK/a4IFDndQJYc+1*jCeQdDCDMwKk!/VcS%@
i4qX%X pkQC><T5BLPMdnZEpKMDCW@Q?leE:*8kJTWYmItXpl!w^Nb@qPHi5TH6A/KXCCbu@S!1Di/=+BcjlX^&
:PwNiY RmV/u8%V\AIQ<M$S&6tiGc4lhNMbbIMkKmuJKm9hV8/<4j/CwIC8=wA<e5FFc4R!hj6S/y6ZN9eC4j&h
%Bei6@ >kVWTKk&VH8##ZLFH15p89CZ+mpWpZjcj994@y8#w8M**+K+d^MP@6>Gu><G4cLMu@+<?pS?hk!knI%C
5!5PV! ?ihZKV@NC+$N6i\DHN*h1hDweG65y^1NPt:wqWWNMZPNMdjt/Id+Geepb8mFluwqi$dc8YWGJ<hqSFyu
aA&GP@ l691/l4c8d5ERLb/DNbWJ>DcGRDhINNI8qYcpdE>DT8ZVIBe!L/iQl+&1Tb^M##C#I*%Kda5!\BdF?Me
S=w^c1 ^^k\ay1%Wc1>FhM6QNZF&NQWPnLE\VkXV@iKmMk!C9b#TDRQ\5ybyM>I+MVSA$J>M:JV4VMaZk/J4uEt
@!@QM+ kG8Gc^VipD+DNE>uBmid8+d:SXuQTQGJhVQV5+\#$tXq&P4=pi!6>IMV5HIiqn+EK\iGdiI$A!cFdPt8
I1Tj*m G&@6aYe##h9N&>MpJCnWkpMLI4A#ZdLTGd+eXpK\u!+?pSQL!IqqWyltM\n^S1qa8jRRV4^NuC=VQ+Dk
eK&lhQ +Ryai*6:$6KC$muEyER@W#Q@nLTAWD!LGpPeESHqdS*kqbTYEPWacAwR$+\M\/PTVh&aVK\e!>e?&M4P
tiAVDC ^mDP&tb/c5SW1=na1XM#\4\M+#KVtcT5aH>TXFcCqXpWpDID>Ke=/GjEWGPaWbEeY#%/nu8Kp^8HmyYL
%pSCNS %*QSha?$#6b#D4cqbSIbVAIAlYhFiilVcB\QN!dpRjeKmjM##w#K%M&KknWnYu1p+m$ApJJJ6QL&nnXn
^AE%^@ \Rt^55M:B@w:GSlbG+jdt6uclJLV*Dm?=t+LdIXYEhy@5>EdJAD<G:%BAqGEnh/<N>!#pH&eNM4**h:j
cA9Bd& hu?QV6j^VRJTBViAWtkm:9/tE9>hFmLRlM5C@!+LWmHl5mRSbMt@pAXFpCZ>I4*R9<8T1L>IL%pE&X>M
\/1YJy %FIyI5mTjmFLFWGY?A6b&4@LAnVl5nRS:A1k@EJYBL5CjyFZNBH5C9lFZ6FE5K6j4kDR\N<SF5G!IKL\
hXwCI> >SIc?Vhp^%5YP!9:Z<XHZSnQ#<Bja*QBZy#WJJ+Lm?HFAh5hGTL#1lKbVQ*tlhI!a?G&M\JH+Q&QZ^W1
RPQLGE *&=!!4?9Su#jRY:lk+PwBMHXCB46Q=@EJu?j^Ec5bG\YG/RlCSCe^@/=I\ETCPPt5Tp$mQd9<>kwA6XA
t\yX!K A!6h/MBm6McThSSLucL>1A*B=lJwXB8Pd1SqLT*8bkBR9/!!%%98>qD=Ti!8AH!q=^DkH4klkqTXS?h!
5yHyyk uX:p&t#\jS!wJcqS+qKZF^ekC>:\>1$<8#qH%66qQZX=9n&1b94MR^k^<cR4QZV1FG$bmbVk\?#>6>Nc
D4dm$E I%ND4Dd%>/uIZnIcwNeEtp*ATDuTB//qY%p4T4jZ$NP=DuwN95<y!b6D#K8W<!XanK=aN\&XQIu4dW&^
SE*bXG FQdiQIp@=<ehtF+qK=+Y/Q/+l1!q64kw8n&lNawkkZF^/GEwpa$tLkXI*S8P4:>+aMmJ1h6+LhX$Eq1<
nElBCd a*uQ5Ic%iNlPHWZD%c#bNXEu^Rajb<?#\/FKDjR$ecZPp=i**mwQWnS+R<htNik9EuNnVLZCnc!cJq8Z
?tL#dt 9tFpH#:^tu\?wi/tuKQTPqQ5mb=85\PP#\wh5W:yD:^XHdFL+8wq^dk!5w9%KncdTJ=Fqbw5dl9abYSZ
L$Jwak H14W$6F#!$@ZcduKI=Yh@ykTya+LFW*/*Pm8HIu<8y=%=mXNBciX*JbE4nVw!5K$HuSZ6q/CPbMS$H5D
qqdajH qV<\c@&T8yFCm%IQXCY&VF!te/4<mhDVW>^WMRW1=%Y%:kNuAmhhSC>&^CqKYDpMXE1Y%dY$mKF%y$Qi
K>TuW8 q/8i&@n&1YPh@jyYtwMpG>t*%+QPJ#yQD$K4ujeP/%?=M+/WJ//=D5V18#F$8AXBe\!^?1HZZqup#A?J
BclDTQ 9S:MZlH9QLMwImHe>%%a@I**T@h!dyJ*:tNHePqu!deKE5==SS+\cJEWu=B!P@jPlKWQb>>b9jQ=*L5V
8>*Riw #4?dj*j%<:<YD1DcNF?l/%C*C\a%jhTLB16VhW48cbbQZZT9iyj=p98cF\DKumXWLR5Fei:>mki#y*t9
QpaD$? iHBR\*Eqi$%eRPZDQ&&u4^!c8Dqq%hBBq:V1S^NZ#h:+cI=CV8&nR@m<8uncl9tdHuh\H=b#1X?Zd+=j
-AGm?E 0000c6f934800110333 Page 224 of binaries1.zip
hub=&W G:!#+buY=4V6#<I*@LH4&h19Hh8iYYte1^??$d<^Q%b:eqHLC&&Ze\iTd1=ce!lN&@dA$hVDC^+hm=5d
\<8BX8 bdN@SQ64?+tS#^>WY%@Pm*4ittch1*:5WcSG@auM!I9/ZStV+w/ij@Xqwj&b6=E9ZM<qlnFDy*Huy$&@
4$#@T^ ?q=uGj9/?@Y:E&q9d^5cZu4>l!Ibk@t1YDV+eaQF$95jw%iLN/J4:9laK8k*Qu<!y?DAqtijny*i>*^P
bwPtD$ %KQhL?ei&:**cSF/IZV4!><?T:yK>F6Zj9k/bhuDQ:>8*H%QM*@Nd4>H:A$quVwFddMX:b?@6KpbtnSF
lZ5IkK @1w$/>Y\iM&uCS%9?liPVQ*:cI&W/5cA&w^h5?@au*LSKQnIXhKV5Hiki591Y85ZNt%YQ%EcJ68ycdDR
j/yZJN q>k6Lj*qQjhc@B\t\$HGD!NbTM%WFnPaiqSZdcJVcLb!Qtk1ZV6Ju68+VH/RaLAIXc/ej$8F8:9WZy!w
Mju4Lp Q?FEa/XCV^VtePQbq=Epnt!h>^<!hDPXN6MRei+Pcn+D:M4Z4EyyG=:eRd:&=p+bXc!t!l:NdJ61*&TQ
tG9Vuj 1cF:TuD*Klea4edWMi$YXWnyeK>B19SaI#S#l91>e\NLjAPuLNyDNZS/$%6YMj8h@hXLy9wSbNtBAh><
H@CG<% byP/I!NhVc#RV#4>mNFJZIdEmT4bEtW9>j^<DKh85Y%#9B?YhjmKuNJncTt$=qVHSuP%i#YBm&6DDCSc
+#pw<5 %$1jAPqmA?iu$X9VWJq#GB/WA^IhA#6WL$aF6Vj&*H++:<?!:t&l#e\Nyp/Qb$t&M?Z!CZF/BZRD>Va^
JL1=tN bn:Lj%JunacE*lFw$e\@y8m@KclR@PI9^Z$:TbLLp1<BdeRb\<bm=/=1mKH$=bWp#Ay/IlRHP$HbkXbN
uh*!#> ?tM>#KCBu<?nW^<&j*qdwNJe=@Ep@J:lM^MyXt^a9uKCtGTntLm>StHQIT&bp$&VbG5KI:lePdGm6wQ!
nXm6IY 6hQZhy<FHn/?FVE*j\hN=5aXZ%nhLSjuQ:$a>5F&!%Gu=QJyDe&E^$cFNZa!iiB$&aF!TRp/S8:Ea=pT
:TD\ql JaKa&GNy!b45TaW>bSIhQXX1?aN4L!%cn=%IuT>*+pX9iIR*=:u#%u*B8@4D&&e#H8%#&W$?BS=k44X\
/juDVY Hmp?wQjy>5*q&NThj^$=EQ^mINJ1TRai6RGn/:Q*$C1tFN4=$1ERu/jVI*dt9Dl=@dDDX>LB\?\W$>b$
EwwPte iXcpjqVE?hp9ub<eDhu%bnHKL+8%e&B@d6G:1$5i=4/5@$M?:?uZGVj@YnkmlY+L?Yl:yQZ9=N$ub:hV
F58jX! =u!i5W+:j***^YP=M+<\D%kX4a9T#Cy*@&9R<6%<$#6VVtkGaAc?VC!bHQQqSP5j<9i/QSeS:8l%9mDJ
Ihw5!a At%!p%i?wJ$PjVp==6d<bc?q:L9CFQXmI=e8j?*mjmd$$/u4Z^VP$PqVJQ:$NYFH:q#=?qVa8dA$QQ9Y
?:QDE@ $hX9yFnhae8A8MlhmmjPn<RP+CcLMbwqWhWye%l8NqeNN/8+wI=4/tcHqnAX$Ic#b1J&M>*Sq\4q:qR5
yupdiF $tVTqY*FD:%D8Wp1MhhbaimbGm/+tbK%5YHmTu9ZFXcHTi64!Et#!mb81Gm:DHXcwZHNB5@Y1cuqh$p<
@CAAGY bXRRP^wQ1W?<yqy1E/4n!KSNSQjFFqXESL#Fyq?*Mu<mk:t<w9G!&jq<4!p!1H/qE/$=mme?8m=BNil\
&pWGna *jRp/AclSTPYl5WM#ESYt=Z+mN=E6FK8Rl$1XL!GRSLZqNXAEblqQV=VC^w9VB!+yTk%tAtKj&!/a*?N
XX>PhB lqXKX8MT:FD/d6aFFeNwKYceDQ%YJHi\An\=$1jRESnG#hMkm4e&Kh/ul$w8X=E4NtyT%b*pZyDHBJ\$
&*$T=y >cR59CT\4FJ>^+Rt/eF469LwSG#SmKqm>kM@!ccQ=mhL4CVTeXbmFZ*w@J:Gl:X>&tK+dn%uLlqNh:Ne
t@n\Pk QInV!c@Rp@X%I+5VJ+QmndP$/KFPTZ?6&VG*+<:%/>5=+t%Qy$qYJIp#a@GqVVPl>yw8ldbTqH^VG!t@
jak/S4 =y4W#T$=Je#m!bIT/&ZFtbM^ZE8XW@S=1Pld$YtDinyPCe8yi9NN8WTtbD=>y1^?4AcclXPh6XH>*4%4
Ww@=A8 tAL:F9&V/SP$tVW1teS1HciQHLG/X4T5jc6Jy>66dd&?NPt&eMyy5cM!apy&$u+uDPpnPbIPt1tL>*RT
MXCRXj /HSQnH:/qCZEW=w8n^>M19Mmaltk^PRKM\qWNYEyVp^CN%8GZmPq&/$$YCGNi@$b>%wKb+b68/NWM!!b
@>PJkH y!iQeqGwTb$knuq^9119md!4yPXqT5%PlW<9Z+wy%l/V>eXMcF?:CjhWh1B#$pCu^t/D%$899S/pV!D+
BQD?l: KNuZ!VMQmdWN//DLhT\<JF:/KLTHat8M5D*J!5!*P9SlMh^h/h4$D\yG>>ypyKR*/:C5J/ApJt*byXXd
*C85He 4a=cLN68ytn9yIY?IINY$iH8WK+NS/Q/JHGQydt>W6#1Ch+1PnWaLY/1wu&F&ydN5m!qTT>9/NCjc6ji
JXnB&w tqV#XDJ9q1I8R@HSbpu:P=4&A>4e6/mBRk^8YEE*YWXJ/i?&6TwwM@tcP&IEQRq$ylw/SG\EiDFCjYp&
u^DunJ 9HCE#9bKQK9\SYXRT^GX4wk:MXq*plwZEN?!GX%VKNZtwFBD^:AeWLXHJ4aNV$C*!ZDV5Y$uMG&&m4ZY
F*c@CY M1lpChV?mdX#yP\^Y1edFFHqmnY#J1ATyJu8546Kbj!cJ?N/Fi\nJ:DeFNw\e9Gd^XBe8Sw>uT&:5LYA
q:PjRE Tt&tc95DSjwyDLhWLw<:kS8N$nXT^HZJwN4EeP8pYA?\NW<XtY@q$cZK*FtK>4Eabd^mG*W!W&QT\DYF
CP<\?G &44J*G*m:iXc:hbw??a=#HCykYE$M$>qWAb>%peC=cGYN^N6:#CbnyuE9CDnNlHHhbNt*eA\6<pw9qI@
&D/hI& P%Vq9%ZDi/QGEu8JqPZmi&caNB<R:+HMXB4tel@e/#&8Q9BWFy&4V+SMq:QMZ6<%:#$!b$>e>88>Gyhm
=!%eDS <C49LIAPe=Z:bytjLX+@6FmBNu$>>PL%W$:9m%m#/+RX$wT>+wR*W\CT5WYYPhDeAjl*Zt@inV<qe#JA
qN5<9K <?Xq@I5*pMXqV$IABTL=Rqp/EMtdyKyM&16PG4+KB4DE>+cBYacA/uSIhRaqaC=XiRcStATTIml9ettp
!BKcZ1 A8wdQ\wynbcXS#8>t:yCR$FXt?1@ldbmE!%k8cZ1S18>B/%IibbqG/tZ>%m@&YhD14eJPE/=@IjNmm*p
b4$j4e kCYYq%MwK#J5XV855wL5XI@cZ9=54Syk9dViR9YTZS?c@8a&ji>NP@@DhqYTEwG!>6qV:RP^%wGGDt@?
9EAw/H 5k8ejQD!iWe%bj51XcnF*mu4V<iAl=b:h#9&PV15iPMecGhZyY&h:Y8>>+tLt4qDm:6Nhynh&>p8yI&P
NAqE>4 CWuPaIb#Z+l#aJddC5ny*B?kYyJ4>nK*:B^*6SS*WMeq#5c>15m=yhan5N+#?!k6eKWETHN9Yi1Sjh/#
BMLXjT bb@uCyLH4n<h\PN8LZih*>:*Wd9588&St&1T%>6u96uQZdMji4Y\9X859N>8>K%CM%w?P:Xe>\w55G*=
a1YIC1 $$@6d$j\uW@&Xka$$She:=?D6Zu:q$@XdC>kn$9XZn@IPCDIL9CK9yj/lEBRtyE#JWnhl9GP=c?YSk6<
$Z@V8j bS1E>k:!DMuJ5Z%uHqTqC?ItmR@eW4J9W@S/IMQX^cNY1cPGNbuX?h!GCRE%+ml5RNc:+JZ:uAMyu1lb
M\w@EV <6^?td!bPtlRwRa*8Rcem%/uWu6KCh&tki4Z6LhYyJhP%CWwDFk4/dyM=p1ywVdy%#4IDA^QwJ@R^QtL
aQcL*+ +XyR>tXKZDGJ6kTbNw$J8E4ykZKWjdR5N%NS:ucEtuQ\VB99h+jJNb>1WHk%>JATKq!<9W1%dbX/#Tib
G+PFI: NpAG%T^Y!=RhuCR@MG6!P/mK\tt<i/6S8$FyyP=>9/RMF!@QcyJyB>D&LbJ=<*Ta/^VkG9$EtDRwyeM<
1bpedM NZt\JGTFi<!:8RFZ$nT86CuqKYnac<n46pwNJ5nTd/DSZJp&B#T/XK^YTaw%TbtiQEY&W**tQDZY6wqM
iG%eKP yRp>e^c*DY8l@XX%y&tnY6Hw^>4i%=VR1>SYdbb9T$45cbp<PA*#updwQ=1$$q?l9\QEXe4Tk=XSd&Zd
a6tFEu dtA^Z!bIN&y!!^ZyKyIDtyNRQuL$/Et5Rpqetj^kq&^6lhLAY<t<cC#PWnJ?5\L1pEKNEw4=Xkpuwapd
1C<<DE q8K&1DCQTR@ITie%1LNtK1F8/dS6#e1?G4D9RK#c#qD\DGP%%V^%>/S*:JA*NpEHLkb>PDpjmqt\d&>R
8%myEC :6%=X%!#Qy^P?9A=1:>>Z59ylVp&C#>e!j1w#D*\my\:!F*>e5E5Zi/H1@+l6@NY9@P:bylH^h4N$8i1
uM>>^l &!?pTlhM?HNBNVS@>jPaXqQdYVy?wXd=wbVCA&jee+klXHT^=6Vm@5NFbkHF8biKYppF%h=?tud=%^\D
ZGtqAY 4<$w@Jm$cEKH/$hJ9>cqlhW4T#=tBIZtBIa/=+ZPZ#!499lhp861^\ZWlcWjm^b4uq:e14*++=ST/5aq
?n1!MZ %ANeTLJM$*Xy>dtqRcT!c^bLb#$y4n=au9ZZpw<l*y1dq4dMZ$V>M@ncH!Y4H!/n#q$iy445wGLI^ApX
:S8CMC %c<1R=<61tbZV6SiN66\Sbny<85Y*6hJFXSKYSlq!jWyXbwhbY5<q+V8K=$X6FR#dQtckQK\EEn#m##Y
p/@&dI a4Y=p#\6h:Y*^i1DihWVF//?uq5h61S/VWu%>cX4cI9Y#J/>b8LGcq46t86d%<:i8Tb5>=1D?@/aiHC%
h^Vee4 jZ9XpMPBNTjZ#V/#:8D=hZ>iYp?:5u:&>jWHd/@@e*AD:iGG&d%K%D9HlmNQtV:emGFtH@!Wt/^98d%N
ld6KcW w4%B1X$PHiem91%Mtt/=Gnhac!?qNDSV4hl6pih:&by$!by?%XNPT1\&ydbm^hy=!1k9+nZ*JHi+JNR$
uJX5Ym wF&iakb<+8cw^hXa!t>&EYM=:Wb%Kb>!W$d=^NdPW&\dEB6aK?HmMIG=Xw*:Y4dGW4bYW+*4JJF\n:N*
m:?8\Y /Al1Lb1?Z+cyN^tXLq9nMcH6u4#8kHy:A#c9VcptYAX%R&4klkIPM^uXJhXG&I9T\DJ>6*ND^dqma4Bk
/Y<q>I &&Pq6pRh?5D##Y/1dd%K#H9KKA@b?8P&ZAZJQDj^>uRF:4q/?hbVedNR88uK1HLW+Ct5jjaEZLJ+Y!YY
89S:k? jpPYum1NcyFGXcE?*hJ8u/SI@/mA8wEK4$VZ6Cl\>>dTeVJ=&VKD&YIwB4a&Za\?W!Gem1Ju:eVhWEEF
q@kn+D K>ZW!A<&aLkXYt$KtFMP1Dc8At16At=6dJ/dbG&#:I&wTYkF?jnZKiETS*B4^XATc6^QYGcZB9iaAk+*
jCkjF+ kXpqY^M5^u$4huNEb8C%I81i+4L*PVW*FFFDYQR&&bww:dZ9yZB4MTk*ye$Bl#e:1hHjTuH9VYD%mhH:
TqHbyj /\j$^Fp#JRhuaypTWwPcm6dKt/bFm/N*VKV*w?q@uMLbayk8a6!%$5#Z1L\BCh\NLHM6lk6ID1^XGDBS
hc*I8w ^A*I*y\tY^PPSS&cHJ+6N6C9NC<cVdiX$I$W4/uXQN\m&?ak%=cKR6ZI%l!T\K$Ty/>XSCtitL99eLGd
NdSD+J 9Q$<4b1QW8981ZEd#^#chNV+lV^>qlL#pEVdY5uTJ1WdV#XRhGt8kVS*l*yd4=k>Qbb?TIq:VKwtY+I8
tqVuW? kYXcc>RP!HDJcmkJJYcb=CBPRi64LK+5F6e5>/qe\ebD9pbMATWunjL4cb5qPatKSR?wh4%4QyW5!TXI
DG$I#? +X:LelPq$J9/c8RtMI*p8RaKk=G!:Z*!#DJM&=BmY:wpW\KNGyDXyS?yiTH%&XcmdWCP@5el%kBt<NRp
-ASEFB 0004072b23000110333 Page 225 of binaries1.zip
qb1idj %D1J69T>*AGb6kSyi1wa1ljh>pWC%T#NXhNANYph*6uHHh\?^$ncJqCy4RjL$5qtX1DdDt/dq4e6iXIm
EI#dE< 6:nnNAdFdW/kj<GWMXQcwqA%>\j@jF<R=*y@#Xiy6w::P!#dJ::b&B%:<8DZ4K??NSk@<kd9l@H#H^+L
>p6*up G@JM:J!5hY4hCL5N8*tcq%y+cm\8YLKtTquKSY:RP4qtq^k1>:HJp1EN<WNuZn*%jQd\\$D<RLIP<+6+
tGbIMp t+y!t#XtaLM!$$i<ZW+6L/+&#pYX6W$Bq!nShp?T?$IBuT%4Q$qnIF!GG++b^KHc4PY@BD&c@Qe>#I!H
PXc<?X hqIFAWNct?=8+6=@yu6EHieta?<9^l^T+y=X%?&Z1w%V+/Kj/&:De9QqcmRtMu8Wc51t+JK%c!ey5E=N
HhITMD H8DK&:>X4\qYRGGahy#*^=PneNe/dc%Gy6&&bb=TNuJT$q$ZP$NVAleu$%+qdRjK/?1yHmi?miyXR*Y4
h8pbA5 =+XLw/8%eiG1k&R%?&cF#*>>+qyQbK*elF:@$en=!&Qj9/d$KNqh?e98Y8Hh<%>qA9=/:Q4X:6uZ9%@>
J9M\ZM hjjXS:8:j&@<yKTH+6KZZV?6YnkbK%QpMGkw+$YiIq*meC<n6MXqwp4yPm=*aJcEXqSS>jYip!Q4jJSp
i@wZ\% LM8calI@*uk/\:KmZadWiCPbdFt8m/chTD@t/:P$<tD%i1^/1dN^^l!&:Z1@#d*%RZIyWYBhi6>>yj5J
k4iAqM tD>ai$KHX$XAXT$K8&+M?uY>#ZhY4*SJZYt!<<c#=Ma4FqDT$im@=l?bwZ6q&\MGVm!/+h15Y#GKW!yP
pj#Pm@ QZkh=4W4RHPFye\I=Jt>\FG@e6Am*P9=M*SB*+^*%idp:d:Fl\i%hp8YN>!:I6cJNqSN*V@6tI%!!@64
nDwjTp L@L9!^=<N9Jbaid>9P*6&bd#hbct^W?@5RjT@$C$:5dITJ\9dwwP@ZQ?aAd6Eic9D8e4>#+9tPEVH@/l
/%Wh8$ >@PhtYF*d944TuGZ/@pY^jjk=<tmb1i@w/c6^Z^wMX*l<yhq^h/SwSM96*9K6V<>%@V*bIZ:icl<y^b=
X1kNDP <a$w&8buN8q9>dDHLG+?X#l+cX*mW=iS%$yjt>I?e=&\k:k=b9JP6=VEF?5Nc:%*iFZI%n46X%h4:Pk>
WCiiX/ d#9GeiV5%Ct:>i#4@FB%Fap=p4Enb/c&ZM1/KZQR!G1%$YtXe>NynypN#:SQ:*Vjy1iAM@md#kBS&c/M
lQym/# RElBVLuD*ulC/<6CR!6@wIYte$=6^\n%wk<ck^i@6>MPD1H8/l>aWI%%&Vt!a1Yedjc?Gi/>d+:GZku\
+SDS4? QINS^1!<pl5X58@h\ltd>up8N\41%GTw!i>#MBE9h/PqT!1k\%>IwS\G<Gy1Bh\S>cI<P1FkYj=bBiWm
!TP>wS Pjibcu4*bh:md<SkVP\4EqI&d<HwLW>eLJt:GEPwm&cpT5?wDW8jlP6wT>*Zj/YIa?c>*!#bWW4Qn/tA
>epb\D 1cNZWVW&M^J6K?1/DFAXicHl?K1mn\PTXaXGWcRqMX&cCw91E%1wT1!/BXS=^+SW5641^>NeFTTXLM&+
VKj8S+ VLi%XJW6*AG<WmNXLHFJnbJ8>lLhc@$M6SDNhSRneb>!tZLewmQVK$waaiATQVS#TtX?%%yC9nnZW1Fe
lQ6Hc# m::YSe!?hECnwNZL*ukE8Lt>^F?qWtinitj/&1^JZhT%&6J/CiqKbhGeC$SF!qPVCRY/dV&Jc\h/%q/R
Ll<XN\ nN/1Kj9m69>plt^>/L%yT/j6imFV1IhcSXY5%:VMY6GSZ1%diAIXPqXGI8!WXPwDVRi<dCNl4YNFNKeK
X?NC@H yaD?p#q6pT614Y#^LBM%#KKcc&5h5cuq/q/5Fc9qk*ZFnbR@L4BdjW?mF9XpkTwtn>/4kZ6+VRdLT9iZ
Q1lVNN ShQX<*HtplJM$+KtAau<H9HyByyT^W*>atKQ$jL8bmZ=VT$TBcXG<6FZ5p9d/SMeR?$W$GWM/ai>E@QV
acid$@ 4$kN!6kZ6V*R5G<Ku>h8bI/t:^X#=A=MSuty!di5R6iYq5=FS/yJF#>\88y&iDL8q6m^DP:A6ZD!@ESc
ZD1=j? $Pa*L4y=hJw<Mb>\m618KhqY89nyTZhDeNiuwP*eyZ/h\#8k!b<h8eqKk*%Y4w$jy5V$#bq+#yLm$ulb
YiJ9Z@ Y:>Ti:=e4+Q#!5A@c6*4q!q@5ZJ>aw!LNXqi?YK!@Wt*uhM8N&TnG$>&8PdhR6>@WFuyH?:49qXhh%Mt
It/:K: mMqwG$Bu6wW>dDqkNylkiqdYYch\^EqeXa4qST8etGi&^kja:?ZSjNW5WnN&A8ycP6b+K^VZe9WQ%dlp
lwlVu& YjwL9QQb=CZ?NKwM+TI6Hu!$48$GhPGAyPtD+dPEQeG$=a#WmYk*j:YAwjt?B@?$m*@:q*V$5G:Swud>
yYc?cJ $Dt$Na5QFb=eNHD*q1c*uQ%AWJte5ZQC9ku%cuFqtAF4T8h$!hB!4hkL9Vetd+WMN/q6Z8q@KM!Vp&Pl
1Gt>aC jquQcZp+4uS^c#&8p&p1=cCtZhTtIj?RPwlic:6mC%dcVlXHFY>jFJCa+:6N*YX4pPZYwMRtLip5ky?9
CpQAlC 94m**$VMyN1YkHICXc^+IF!!L6qEumGFE1h11PTdb%RhK9H#Q#i<bAY?8AR>PFY<MS>4j$%P=1tZYeQK
\L9Cq^ Be9&/\XeY/J8<NC=jFqNR&nR%6nyJ1>Ch8nheqmWQp*NGbXPH%!ZXMlIm^Sdu&Y!4:@CNj#%@J6d5hLQ
SW<*\Y 1hR<uJGSBMFRYbKyWH!c:Q>58FE5y6yKae>M/dcE/Kd*6mi9jhdPm9qaLH9m^SQy$ui^P#ay!kXiP>/9
uM:qLJ *CqV&HyM#dFFB>PW4F#<<W=Luj@qQ6\:Q@QImPYQA1eXyW6yP#/8k5hN^CX=GFZ:%k&w\RF15Z&D6p6F
VdZk?l phRJ8yM+1p@cme6TeGCRyRnKM$^HXFX4H<?@^ZlKT@W8P^n5MBR>$Rl@itDhyN4Ky>e66d&/9FhdDA:+
Y5D%5> T4C&WXEMI+u#MtyTjkMV:H6$^NHVc/=/*y!?d1y4k@QHJm=ZC6WiGmhb<=nTi9l9:uT81aS86pI^E+WY
h9I+TG T&BL/D=8imlttHd@ZZ644qyw+TT:$qhTcie9jWE9!hCJ#YAdEQaHH9NDniDe:Y&u$9/tX>aF%IAKSbep
EyR#Ft Q6NSdYI!AQHD:kthu\8bbYmHc>+VeEb8a5\nM9tEZ6YPRDNFXJ<m15Jc<WS4Mm1>VN9lGpelV%P4wNcy
d1bZCp JR6emG1L6bJAS^1=q51ed@b@FI<6mnt=w@LR6RM&!6^?#SM%tXKjZVpyNq9*#h#jn$F4+1L?:N!iEDeL
QI*e\l h?N8>LB*\eFpH+ML8nhnZ&Am:h6cb$qe?DI6#idJ$h#>H?=1*>KZ4LGb?@D=#wdMTa5YMSbMyFyID>#T
&+bAJy L$4jlV$^K$%?<I6hejwC\^Q=G*IHQPLb!?tXWk+jyn!aXLI<$>d>DQ$&Eh<YPVZ#YKlMhQ@j9bFT8iy?
/n5B4V T4TVcbSHp^/6##w&??L5D*cQ$h8iZdRqPT\bKbPni&:K*wP%d@c=?@mw+=14P>5CKMuDR$/^&1WXTtkW
=dVJSF XRt%4GPLc?yi@&Zu=#/hH4M>+>n&G^=dI6AwVSpy\9X4Y&Xq$jbq<utV@:\:><QCq?6j61Muj^m$q8cP
nA^R44 HFN5@:lReZCia9G4BcSnH*hQiVB9heZIubnV5^ec*#ulhuL>Z\h/KqL*w#8aKlyHi!StApy/<*N*9=><
:t#idZ ?9yeP<:#?RePjJn</Qde+:NjFC/5j=4Sen!uTR*4cKTAc4P/<mH*!k$n%\6dRa6Hu!#1S#4h=NBM6<Vm
$u^1#I BePS+kpytPMLS:=cuQq#+bTB#*@Z9%8\??LH9>Mi@4X^!+iFFp<?@d%^/P9^+=<ZK4::i?G=9+>*ww:j
:Nmp9t Rl>@m:a:@QH+A+un>GtHB5RpNAtH=S>!beSRn>QyLjJ6ubm&Qt#dA+Y&6+46Ep46c546Bm46wG1:p>Ki
j6lbDX e:5&F51Wn8ml\tc%q>1*q$%5d=qw*/uh*nDJ@ybPi>?W>8:JDlI+?&H6E\d/DtwG:Y?uPp!c=wDSP=G6
8KYicV j&Ki5WPppWPL%wq5p@d1Gh^b^5Y^Fl$TlA+%aweB$AGTPy#AnpCwI=depW*yKKS&XBFKBwIKH%l%hFy*
BS5m/% >Nq$QLD6iG9ZKWH9XLQ9NHDwBB$:ub\/A&%pbIS5w@1&69+Q^>kACMKBBBLjMdb9i/d+Dp$BAIH!j?/V
@q*uqq ?/@9p%9/1@9pTw\%W/TL&:hSJ$ylI4R^S*eM1F&WY#wT4abF8/Y1aZa!WqV*DZc\XeH#1nM6:ZT:GH%F
^wE1Hh 6T6C%W=&^M:Y*tj9qKB^ICPBRVuqN!>#a8j>hbZE+?dZH6\F/+*P>y#JwJ/kKwkdhSkjiFXY1mc=NEAX
?N1J6L =$yTtc@6jt:a:c=#4>M61:PXnFl6X*?T\!B%Yj:Z@IMXJ:/c!FVeJCpeP$HwJbW*4=P+jbJ+>wKcqLic
Td#QZl n<b?6bwAY?PtGKQq^elFd5i1#L=</46@TEqN56&6EdJc59*ajqiVV\!61W&1P&=K/S/?GRC<6YFeqGq*
c@!&CF T%cDSqR>dwVil^M*#V#k/$SZKDqV??V=dpuqA#8Q69SK=hG:%jd+&&^$qdL9VJ=YSN#4**6YdiX!w#Q&
duE:M1 bhP%Iy8he#Sd>ylqVk1>=@Y$=>44LI<?%@:AZMJy&dhFtW+#Qh@Nn:1<H*Wb\!ud:h%Y+@>I@Pm?P6hp
6NcnLd ^99GlIt:?/bmZwc!/KtZZQ4*>h%eQL8ReTu$Qq5@=w:J$JSJ^j666StQHw<\4M5uup14AX5denJ/@jdP
*#IF$l WD/Hnd!y+#aH#NCGD6&bWy?aC$41kPbGPiY?&>hip6CX9jhJ1!b+Y+&Y@b<BFSNI6Fn4m@J=qh9$n85Y
6Al>P+ SQj6&8wWjcl+V@wdXXP99<XJLhdPHiTSEA#u^IF=?9ZKy<<%y8^K%/*QDd=eQdK$\lwXwP\Z8QILYjQF
YFNa*J +Y5M*cFLSnHKT%@Va&?Yb!@L%W=Hy>#PhLG=5+#pep*%ZXhump*Z#VL4+b#Cdj66St:iDVmT$6CL>61p
>L/19M hT8ajFK=Y:uy^lYyDbP!@L/aL%&Qh9ycqV9%w5YF448bC?aXQj=/LVI:Md#nW&LCa<1?EJYDG+D:&X8X
c1m4F/ K5*#I$P/GVTTJ@wIyZ=aViPyIeYM%p95:>9S=TBG9GC\ucI*:#c#6y1NQ*N5bYDndb&%ebL!%L?tZVX:
R>YD<y :&*/!N@6aJ:ik/dlTXc4=8k&K?^j:T8npFlRNP$9J>&Q$jJ?Yj8=iWeNCa@tdhBhjLR++c<C\96Jqd4u
RNu%B$ HyiWQN!t@YnYRV*X>iTZnIq%lMj9YRWB=BjPPq1#WF@<XN@pJyVh1w<XK%>%Kenq#CYMBiDjejXbR8HW
jSmmLN ^^M4T#$q6Pj855WP:HK/dQ*=Mmbwd8N/X:\/aWtB:y>Pn#iy:kIn?/:KL=?DZnVq+JWVL!8nZVqG/!\>
*4WFwP CyibLAZ/$:wit^X@8QQmXyh^yKt#Yj/m8Bc5!tC8!\5h:huqD/<jM1\!inDS$&$kyWN:@%^X5<8i5l#!
/bh<ib t5Pd=LndqHcw>J\LKd8T:K6Jd1pIH/\^t?%Q=JmbGBT8&BnbA4ueZtmXjWuZZ!9Z/aW=&tdSB+$dEkYR
nl*@Iw &<Hm6cEL6beHjuLQ&1t?t/#8iNu9ACVX&N8$+8&J&MRh!**Y:G9YhAnyccRYNw\<4k\#cGKF9T?1/b?\
e##Dyt T&ud*q8LNmWV@94TKcY5dK\>bSH1&kTK%F<1/&id5*j%cNVNdu5Si>uV=*H=H=&!Gic%Z*ImT<>@hbK=
5KTjQD %n=$1Mebh%=H18iP#t1>IGi*<q&:6I/qVyI>WpGaHLMJiy%mPJLJqVu+y1*b%cM!X6G\&ju\^LkSnKFX
RHl?ul <*1n>eN@#L+JVD?y8TFl\=!nuFj$nZJmwe>11S*%Z>=6ic1j&:i%+$mY!\4je*c#?4*WyK+6pZEQ+wd$
-A!hD$ 00032059a5400110333 Page 226 of binaries1.zip
\LJZn1 4Dup@%qS5m:n!/#A^WbV*miqZ4??w>Z5*dNyeaX4/1h9=dVXGnFPJjeHuD?Z&NVi1H%+%TF=ihiDmiS>
K6F4n4 NhK9I6Y1N4u4dqwQdl&=6MJeN8u^E=Z?81n%/@:1yuR@AG@%MLVPd>*EhJP=HnXL4H@Nuy*:u6?y/6*@
j!Q!Ht T9b=<!S&4hTLLT=11/<&&FW>@6JVq=XRiVucN?=Mul9^RQ@jX@W5QSjNhuWM/Vt<CjN%J<baj%4@ymKN
\ADML9 BSN!Q*AM#4$%8Z1yJh*q*MpiR:WXT:c6XF>a?u:?ny!*1d*QkyawmT6L!%u9/RWa4EXa9j1*D=a&4TmJ
ARTH+y A<8Xtj:VQiY6H^XNhjAW+&c8D/6WZ9S5=SV\Yuh%k>Y^XMZ!iPP+%i\yV8&5kIP1n#4C=u8@D9jbNd%$
9NbJQu n>8n&iiQQ9Ebuk^M?*B%@iY>heh<P?\&Tjk8$Dmp9*ZJI=eHt+>%&u544H=<*c%8u4TH:4Rbdi?9HA:A
B<JnSL uC&N$EwLjVW>PZ>FKnhuY/WV1@41/WY8nREMCG\e8LqbNt4^<yu?c:!N1Eq>j8DbdS<+99E5/GNh&n:>
ARDRF\ ^=FY^u9MbtW9KPDt8M&=!E^PhBb:=&^!^j8CY8C/5>PDt?8e4\DYV4LJS:!QXijG*VIPZ?QPCiq54</Y
4M/<BZ ZHH!&a=QbQ#jK/5@Zmu?K88!SiJPd^44#c/\<4*Lt:L99488@HTY//E@X4HcmeSX#!TZ1VZLYZ1w1FG8
Jw6R?R 9X8::P1y$*6udamhB91*^#l?*uYD$H5!1APj%/A%jjM4ZJhT@Myat>ZF!yj$B^=e%c*@+/@b*bc:d1*e
AI@*K8 j@=?k6EN&R$ER&cTdZZ&Z?VZHdH>K<<4lQ6c*Anc91a4Wm1nhM>bBucjXb@@wX&!V?^!e%SY+@R8!G@Z
<\HlYy =W!L9dK@+eL4ka1aJ55:p5eDZjIb/DN=nlI6^A$nWT1PHHPb9CPFGkN1hL4R@lH\@?lJDDL8&&dL@?:\
^4n!WS BZX5:!Vj+a69QV4SDq@R1PC+Ll\=Qe5q*TQDHpl$hWl%D+?PT:WKnuFn5bt^Jq=VYhGiH5d?Mia&V9:S
q?>?A+ F5F8hBauPN!X=WPM!awkpKP5+8kBIZFa8iubZ6Fl+VGPbtaBi9wyDN5Ia1C>uc5NQm:TIDQB*!:WQVnG
bPK#p< Ma+XcW9QIPm:BEM$A8Dnc1J4a=iXal@mCBCut&DqtKTa%DB4b>LW6KAAF^NdQ:!L4=XdlKPJ6#*F*<\c
&luAaC :^A+I!AE<A6LDtcEyYhblH4HJaJ&DGc/j\RnnWZ\%tQCWZl#TF+=+TcPLNiIpQAE1\AdN%M4j#1SElZt
X$nt?6 Q5M/&DZK%N&WSp!LMy#1FJiebSqutG%5=BRQl6lEb!S#*LPNM@FaPbKD%R^uV!ky^TjWktNFmw^kl>CC
m!6kVi a%Kw=k=JM!!uP5j+MRLhM8^TDY\eQMI>VK$nAcNIMM/jR\>m5q&6nYNnA:B!VpppX+/XtSeR/t<\I=Qt
Baltq8 ayytM=XlA8nmR#kPJ94YCZ/taXa^h5HbaibG?wER&#jcaWbAKNGGdblptSHm\\\G5HL8wiHMNHedTlw:
5pDB=> mBMjQ!$8Wm@SqP%I6YW+tWa+yTSatce=^GhHJL4:tL4=p*#hdAPM51kl^6tb<YqSjl/YQlb\mVl=JJqF
&mM!b4 ip=*M9YdpYdwEMS\DtbTk?^NuaPVkP#+8MSpln<4$V9PJMR?%VW5MT1DHSEcD^HDHWM>1h/SCSuyqy=a
>J=:*E PeDMuG*4dDa>NnWnP^Z9GBWY\VH!e$mJV!cc&j6uyh9N5AC>GF/l&R+kJ<PjEI8QbE:%!5#Y5!DG=dku
HQDVkG WhlB#qk=ZjkjS>M5SqS1ZB\^$<jF&Tqa#>KC/kJNN:j*hRuMCMDHG!TbG1Ra&&e=EVP6:N^#:HRDDcpE
8aN&Vj w>R$InEGd<DA!wESiwq5u/^\$MAu#lQQTYYFi#A!uAlyVA4FIT\%q8XACnjJ>plK<a&Jnpqp5KdGkaHp
h#HTpZ /HkCcjy$t:npiBQ4CK^ejGC1YTIunbwhqW!kSJmptkV/EJI>I<J#pnkJRjk$\&RLc?VEWWTG4T:JG5!&
j=#$=# N!eDVPh\T=Q\SEw&^!A\SR<4q^peE?Fwut1aaP^qGDA%$T#IJt^G4HM&#b%Mm+*W6ZJNh=^BTaWM\9Bi
:!n14< BpdVKj=^uCnD/E^&MtkE?Jq/i<hciYQqPAHSN8HV1H:V5qJmHV!>>FM+KW\wK%ZQdBw:LC:c\Djct<4&
4JbNcB !9T*$IW4kd&JuW8$a=y^GqHZI!nVQ6nYnyYmm=Y#hM$&TWmL!wlPMDR#!8SM<:RK^^5b$<NNVQVVLSut
$&y*uq WIT@yY+I^>q\#l!lS&!Rm?@@m!M&bIDMj<TGDED@!SEdeHVQPWn>=lhB&8n*/FEdcNTyIVhKjj5Ln9+q
9#eSVC n@+h9ZaFApb@GFWJG4$tHTKNCw:i4A/SS5PSS5PS9pe\tn=w%END+GlAcBTH9u?QCyJHejLwDu1IQB1A
*iXe$J @D*A1AcW$aCnl?MkCuZe1cL9&?+l14C*JWCC\LtGd+W%:q=:+ZjmI>hT@c55YjlyG=BAEWFY?CpRpEAX
/6EYSJ RSaAlM9TSJAXjmIKJBL?ZScmkeJqmTLIWwuCbRESbKFj!JJEpCYSle8CI5kTjmE4kq&B6F@wLIJhkSVl
NQDn!= NppW\c=?ejIMJIykX!BEEm+4kq&BkHBbRAT:Rw^i1K\IhwWeZlI1K+JhpZ/SX+AIhpWTjn<kCIlkX:<+
E/!+j5 LReCI6kXCjmF#mLaFapw*G<AI6nXL$:ckaAIhkYRj!E4kq$BpHChTTLaFWAT:86II6kXIQ^PR=Apkq$B
G>8#4e SPF%kTTCZREE+ZbFE5G8mML98\SJw4TDFPG?uTTCZSGF9:EEppSyB<FjyFiph9AZ/SYqHSS?D!MIm6RP
D=nT4R C4e4WKS&WLlhkTK%k:?RFcWhBIYZETlKP@mLQlIwWn9+C%qS&pG1<HwEm6IPWwVdFTlTP!ne^+Km6IPk
FiPt*y eH<FmhIP@5I@R!K%k<L4AmSKP$n>Bc<w:TBbiF&ASGpHj&HQpCn6ICneNmBS&5Fj&DNEEcWNFY+dpCn6
+:CXpG IQWZ51K$k:?\b:Iw:cD\$?wkYcS&<Bi!I4YD\8&KLIJhEZ@la<pm&NY9D41DbPl*lMt@I!!CcXEI\5&D
I41w?1 VQ$NYhy@L$5l@Ia5<Vhpkh?RJauT=SD8hmnkd<lC9!FL@k%b!t@IWu>Dq9dj!@Jh?wJe?&DlD8KJiCKB
muQbIS SEIGRTLi<wA<TRnB^pImAHC*C9#*Y^=AKqGWn8E96AcEcE*mcR*AuYiT!F4DGmMVbD!6+hbKBK%F/h:>
iRm=q8 w86QFcX:J@^JTbAK@aa5?VhpKd<lT@$NYhy@L$5n@Nw/AKTQJKJ%IFQFIN#$<c!DTBVBPtmmDDy?$Ttq
HhI*ki mVLw?EYHl$d/DXu\N&Tl*=Aq@+a5=Vhp1j@k<bAmF>X*\B+XGYWm%wH$#pY\DqGGLMKj*+WI@?Tu!aDw
KN9d/X Hk?8YMm<J$>4RIVdiCACWbTJVwJ\4WY\cYRYS/k5/Vhp\h?RlZ=Dq9\d5yVjpKZ?lm#69=eq@wNXEyFH
D+nB<e kEZ%6ERKDuuNBdFK=BGMj:hKWba=pC&jR4WYbSk8jAwPEtYb+=i!+D@&Y5mm>:Xw<QCX\556kEaVJdhE
yth/Ey GeTVjyFd=H@Rtp1pm1\%QMIFKN@/YkCXLI4YIp$BWIX4Vj$j>RFIBN+#*#!6+h/mCF1LWJ>I\l>wl$Sb
\:^>1! wAEwbPG!^N?RBZ=Dq9Rd58D@cQRBh+<B\4jSB$AWajRBmdK<A+CReK*J@/MiBJuCc+>=YlPIwtk6!8LR
Wl4\:@ L*\%<I@>HnL\u+!bmJS9QRkmXbRilElLT+D\HkVyj>dCpPH<Ju*Vi9Vc\H@YY1TFKiGL$lAJ?N?%m<mF
^8?cii k#!6!cJaCEtp/V!TeK*@wVdC@^jb$\MWGw=IG4WRWBRLEYqSnQwLC!H@n:TG&!Rm<K%>R4RZRY8KKM6^
eGyCam FPFcW@<*YmN4GYT+1+^$VMlEpi#/9=<6k5D@$Y\S51II\eN$u6aEWXyXWbd#!MKjkwQAj/mNAHI%1elc
DiP/cJ \@qMwjC$l1mm>L6EYR\p@<L#kiD@b5THZEeL\V/Ey:XIQpTWyWTIJ4!XAWYcc^Li4wKW*=Cq@wa5:d?Z
Q1%/PL lj=^4wpt5t$l#@iBw#WCE1qGmLIRCj&mSwm!EApJ*\kEmdIR?W9bj:BykEaS*i5SCN>1I=^d!M1*CLpq
ZPTwNj !1n?F:%WmQ!@ce%=bW!A9tpN6?\mcC*KuAD+m:\YbW+AED:tk&n@9T#=u&wERBc>S5DGk4#Tm8RYpuQ@
lJ9KmY uq6ppiaElQh>!MA@cj&jYCaSl=kEV&6RqJEIYcRbBiGYTRd@TY81!JcJLG8TmKN=VSIy4$YbWTALd!QI
44D4Cq @#TnRIFEHn<l:>KTS85VTcV/JM4KL\tpChic?4?bB$Et?kEc<b9YBJIwYw5!w@ALV$<l@KQYw6hGbIRN
#E#d\j X\NEc+At!k!hKK9PJPGdy!FSXy$B&m>TVQwN&j@SCAn^A5mIqyhdJFFce%HY4AG!eN<q!yw%IH#4NWTl
Z&@$Hy @Id5@&wMR/D\S4hIt$mpmFInSFu^BwV9TwDG4*k#^mVHZlhAhnIm%w8<hVL/85D*>+%=4\5RBX+ZkMc9
HkTZ#\ bR8Je?#FAwA+G8jaK\ZI?<pWIXGP1\KBuP^pN5/I+ew\Hu8ekjkQP^K@u*alp:/jdQFB#9%BXJIRJyIR
*=mG#d J9jW4G^YenI4t=PYmuQN+eT!@+H+y>qMRYJGJu5tD1ICQ?8BbANSRA>RmB=EuH61htbcdE+Mw5qQPkDE
EmKn9& j>mF<k56^tlHe+Q&@SphF$=tFyI:*<@<iLGRV^yl:FSRDl!bPemuL!SEZ:i$ZF^&Gk+=S<TCnh8Hub&d
*TFdR4 qytE5<@KTw9l5LLbYYb\ktL\@=TRu$>&jE@I6<#=1S!yjJ1V^&qPya#ZHPDVuC^Ee<ie4P!$FLnPbdE#
&mD&V= pc5$@qHFu>d:j1kInXhStFFVlBAH5tMTWnp^4GSeXp=/iqyt>n<^I&*?4=qHda$5lJp1lFt\hHDbtT^P
</<#BM Kme%@mehII4ANq4CQ^VR1A=<tWEVwlJNmEylcVtb8Dk&P#ccFbPE+&Vle6uJMZC^@KM?AQn9?qDH/WMV
61PFB% jCIFG4>6aqRjj#d5A>m^8E\&K*b<6w#/4=<4wAnbImRj^t?cGPWFeKMiCCdFnZN:AJH$u>h<991DVJ<R
Ay6R\X j/+@NGB<#ajG%^<Tu<dCjHQA:K^5hk1eWSp=uE^&CuKK<J?Wlu+/X#TYY&MPcdTW\QG%uEac4!Xy9JbE
E4Eq#m Qm&F?ZZp^S4a1Wh#pnub5*G=uP\EZFy&Aq#4b:I#5&AQ?:QPIFGWE9/ihiPw\X<*KcMFmk9?Swkn+\t+
cV^6!n 8LSMZAkHF5:N\6EkM^!NcwbnyedmjAJ@WwhKEWph+4l!y\Hne^RTwm#$u!94#a4lyGcubTZ<4B@69>F9
$NS\X= 6InHc$TG4ZNMw\CelY6caJ1\nw+=Ei=pWplI<QG>uG<6uaCubWZDj>LmeN?Q8eLc&<PXAS#ZK9JZ&i>Y
AaWt%D ^q?#^6GSlND^:tdmWZ^L$W?yJwwTJ@n4ZCAVSMwETQDKJ^IS%9X@ePZV$mZF+t=1FZF+:cYFaye/b\bt
81MWqL Ame\QjuK@pwY?ymBcLGGdnZKBAWZ@iYwE+6^Na#GA98KupnT59La%>ZKnJ5!>eFPTku$Fyciyy@e6#8d
KaM^Rd %Jc+^Nnd6@wV%Ta>B!@b>%=PJ6\/4XjAcu=6QnH1R9EjQVX*W@hlyB#!dVaZG%uiQKuyJVq<ylJa:LuJ
GT=A4I ITl/me=EdNb>+4ynCuLqCm:96YmMScHLZajV<=\^@wGRk<^ib6C<qMZ%X>>CS/u*cMbK&BJ^9=qjQenq
Mki<6u 4mj4@bcSD^AqjVj9#TTeYl1$MYCYu1LTWDl%W1bL!&BL=i!RP#$8XS+jH#*c?NuQqL96:iLmDYbe@\5W
-AbnlN 0001c70e02500110333 Page 227 of binaries1.zip
SBqq<C VIHS!M$DPEd$m1&?p#S1nn?S5*=RLG9y58$a>k%*S>EF:jj%=JTu5/#&=$>TinHXX\!eII&8Q%Z89FYM
LJqA$q Jq6ei+L:$BH#iy@mDt!X&F+M!!&%k>li#TD9/hWecPqK?u#p$M=uBWcHMJ=8!YiYFukMc?+TQ\hi$EXZ
=p5L^W SGwXh!tFQ!%tqcb8&@j!*nFNKjRSXHPS?F+T/i#>!pi/8:#ENe=c^M#!Q:pHZb*a8w9X5w6Tht=h8J1e
j*DEid m1ut\b%XT<kZPu$?q^acwc8#5F6YJN?X:VS9bK6iN4F/4:EQZ>@\6HmuTiBXM44\Cm*QE@R/*W!!9HbR
CqAAM& !4@%MiWMiwXGh\uc/Y&dXPWpL+&##</J5$ukpR=m>>dIT=D*!l&tpY=w:^Z&Zt@%uteY!Z@/kL6P5dR?
Qhni=H $?!aj6Hm5q!9*PY6jb>QKkWG6VG$4<l&HFt@ydFF<?<:%!\Z!i1@1PM8e:Xa5tBbS<WdH#Ybc#JL%da5
ue%S:@ i58caB4/JdbHA4$#8T4CyCWuCH!uE#?qTC&q5464hk*n*Hq:y?&^8$&by/BhKZ4QMw&dCi5PDGY1QLZ1
H<+CdZ <ebYHT:TEpjZ!ylqDnIb>/99+w4>K?<epVSqQ9pDH:\9aG:h^in?9Bqq:#\t^aSPCyJpMYa?K=dRTD=J
lq6Y5G nTd$G%&<h:/8==c#=nRdnXk=Y?enWm9$%*=kB*p5ui!n@Qa^8QV!<ARn4>jAc<&hT=+dudpV5tp*+NX@
NhcQY5 /!4n=9X=n+&Ii!$HQd&$demTZ8GtV@y6wRQtcM?XD99P6A^LYGwF>Qh8VM%hMa6%NRR5meH:a+/WGBi4
bRl=%W $YMeH&5D^:VQp/w8KnTt1HQ8FC6/Pi#FZDWwaSeH8DG5>q#?GGC/B:&/?X\QED<W$W6m#>^?@ic/n5A%
/d4%W9 &MR/8\6jdlVE*h6edb46wDD<<pB&uG9:t5hGby5\//:R$=i1VJuSDm$qh8q%4bE9nW*\tulM^9184*cX
CJVw9C RSJZVcL*c:P@ZD^nTDpLmm$h8uWyHc8\=yb=mj@4&^GQby>eXG*a6&9%!5>8Ya5mkaaC%J\de=5qyhnD
\<>Nj9 Ji1h5YycI@NHQuc*QN/^w5M+NhR>#MutZ9pN4NNp/=/y+h8e^FL5!^VV8:XpD!S<8wQX9SI6jiRcpbSj
!1>@e@ \yI*u*Fi=\T1LpN&uTY^!PkW*Yc@H$d=y4uhSjyiMD*<jLnjVM:FHw%XdZe&4H*tl&hi$h$ZRw<Md!@G
IVpyke ^KtE:J^/+:1iZuTPw9G?a\q1/&R9Q=PW*/PH=>+/ZBd?6DynRc!F&MCV1FhG<!!Mh^Y5tc<#k$RI+YCn
q&P:?@ C6S&NYt4hDLTa48*4DTK/y>4LYt5Finn6km6iJ%PyF@1:N#$ye$k1YQt/*qXukhPjR^?hnSd1ejT5H/!
!me#K: J488$INpYYR/\Dl!Q*P6Zi!/TT1WZJ5@=y+w6qDVXl6J^u4w*\</hZdG?eee\$%mnqWip@$>PI^I4iY%
m66HyK K*e8CDYCFQwj%nPq@G>9M8^j*B*>tS#ZQcm:h%@96Vn6&>!Mw#h4SlKYL9NMeR1Me&p!\9qY#MG!mF@q
4^?:Nk N#nWT6$euy\&puh#1+#u=Q6qqStM4Wik96ThDj1XM%>c?6ka#Z88%upwk9VZpFQDZK!KuGNpiT1yae8Z
Cq6^pe FS9PSmThI/=*ci6hqe\\<8^#Y4@^pBZp4i+jtE=a=4eXCEp?@HD%!9e#%5pYDp*1hbq?ae=cT%QNIcMm
8ById= ##4QkRuYm!*ep^@M*kkt:/y/qyJ\#*8V<&W=da*1>JncY/#1pV@6uYVtK\$*yM<\PYR=:dHG<SXBG>m4
:Ch18D *6de>9k#Qjm6q$>iG^t5PZG\>>BT#4uKLPiG=cbQ*p##p/h*TcMG=&4N&*%WPjue:Rty45a/X@dtS6@G
T=5ZDe 4Zt:dRR>PimlhcX*:1XbG<y<twN\B<ZXd&44:hl895V<1ZPd*+SX:55ZZCw*h\qTuQnIIHF^^9:4aRE?
ib4<JT 46k9YZ6Dy95j$e/N9#lEMDQe@LJu\94$/>\e>*mjp5GV>Sq4Yw%LW19chPV!nMQu@uY$h<jS%Y<ewq>4
qL$TcG qZShTt=yVH<?weP:AI@8@@n\9w+/<ML9YFwAwiQi:aZLd6$lp!/na>^i^5Pqa:jt:P!/+Vp9Fb?t:>1d
Zi4iYc w^>LPiA+?Gcp/<u/&DZ#T6pc:1WYTh%6+yu9/^QTM^PKVymc1Z\\ZLW&6?jlhZ$Q=\Im&!%#5&YwG8Rj
SaTLtG N8?lb#mijYJT!*Nh9:jSDLedm*be?LStZeKV5\Vcqd9Vm*\*SPuKGJ@cPWKynGlcwu/miI$<YD^9@/Qi
MHV@N% a?ZE>?%PV&dYdGli$Zi=lc5ttcTDdZi+TQ!ej+bhXd5Pc^uy9QkpLebt!hKb6qIH%k\@ZhecpY/ppPhD
LGkM6> 8GRXN/5b5?IBC%k18*qXd&@699#FlB5^n9uuD\QhWw*EPVttn%M$a41uKL1hChcbeKI*1u?Zidu$4KFX
#<=iAD ?@?ieiBa:q&#*dGQ>5+@%!y?*p\!1Fw!i*N6#>RC<<1K$*jXK^XaI^AZXd<p6ui\X?>!?8Kup%RND?^6
Q>S1Y< ^IRGZ8*9Z1L?ka=hhMY@l*n6l1Z<99Ml^pa?Bp?Zt?K#%$$:6*6PuJuS^P^hYyGZ4&<NG6LQ&5D<^Ky@
C*CkNY d9/^wthV?8:&M9&Qb<IMK&@%qX#CSIyFHjy!?hI6>V%Y?t%=X\JjZJu%b*D>*B\yh8E#<iBDnQDuGYt>
:XS1w? Pt%Z1C@W6q6qFcu9%Q^p#V\V6ZB?JqZu*yEZ>>//==Xup*WMDy=?6>ww=/?b?=:1>$nQCn8GXZA@w?m1
<=*pTa eYEC/dZ#u6j#$!ZXdc>!X*>\i:Q$VQtj:=Wj^:#ed>uY<:+Tq^EcT%JjQ1*H?QPWe?GS:m/^M^yZ?n1E
%e4A8G T:*$@=D!j5ALb>a&%PiF*:Qw$Q*/TYG+TN@pX4haBcJbc@LF/yjuQHL9hi?VNGk&XdIwdM=P4nb8KQdZ
JN*!V/ S+Zyc%ppn4AVB1:l$1?qDL@SV=R19:A^y8:Am^6?QuikSaWuNqX/h1DtE8chVAaYD=M*q%p9/S\y\:ke
R=6QC6 %:58$>l#$9Q>c%ij*jGBy$?$#Zhln4lpLyDw&6GlMbMR?C\=Wqh5e>%&+QqI:KqPqY%ui:bdZMnj*j5&
Db>=*X Q:CwdkZK!QK4Iiy4YmT=9PZNIy^#a6@jdwF@e?qkp\ZKK**&tj\+lbd#<w>LnI>Iwu1\dbhX9DW5p5:i
B8lWL5 \Xb=yiH*84?W&lS5*C*Y+I6@Pe#%Kh^@Njt!m4Pm!l:<RY^/tPub5GX/Jied8=di/9d1\@ia9h#^hWll
V9a$PP qk@*4PV&P+#lHXHKCZ/G#bly/Zl5!@4<P+!B5:+:=/y!%i1*thm?wkh8Hdu4qS+8EX4ZR#lmqEAwLD:y
eu8$$u K*F5Mec<nDHhaH?a9qG</h4i1Ty8*aGat4Q^5q&ZPl#CeN$h?aPVG<y>w>>*q#bkG6=yT$!YiyK4*jkm
&KkJ!+ FX8^MXN4a&hQi%P88Q9m4Bkq9ER#>wL@=@T#u?8e6n/6t:*HWa<hVC8LQq*EWu9tmY1wPhHXQGi^E5e4
46FLZ* TEhlp5h#w%C>/#yJN^dkh*%$&*<<@9HKb/>$6kci1d8Y8E9qYNqW*HKD8WD&phe1Y>yT#dtD^y/9ylVw
w+Z\4l ttVGlSEcb*dj5^=IM*lK%CM/#h4^+M>L?T%:6H#KVIkbSJZCF#j%l8bPubN6jqBd9N4dS%yQuKQH8QGt
V&k/G8 /W:169*&i#Ck@6PCSZIFV=S&%G#:&8XV=D:N?dIGw!91ujj:D?e*K&B*c4ncj14R!q/&V&:*&ydTy!Mt
+GGWjL tM*D9dhm!?R/bPKZZ6H!X9A<1cCkQP?lc=1&w>k\wY>9ih#!!=nW>IH<jKt*nMe+b1cZa<>ZXh!:Bu4=
#i^lt^ <@NKen*9M&Vi:%*q:eA%YWFVn9qT9CJ&!eCJpBmNnyK>FJRj^V%LW\W@N**tl*9hZREPD@c/9KyM8Fu&
8G=IQ9 B$=l<uHD=1d+bujqJmQ=lXKp\mD^tdymapK8ImKQ*!Ww>Bw&Wc=h+:64:S?9W^5*>1EI*wVp^p1P!$=L
y*6R51 SY=D?9/j9B?IQ\G<^&?NuNl^4J^pbCdPBbuRaKjG#EdGZMmNS@H\$A=Eh9wEyKhq8?Tp<mbteSd?cVu\
bGWWDk kH&<CqSBFbDp\kQttE^Pina<nwan#IyBSwAWE4Kl^bGXQ94MLypGjF6V+Q%1DqASHX&TYjFbPBI+tt$P
+<n@:8 */=qMmiT!WkIPQ<I<LCZBqDGM9ddT:+MFnKQubyt:y?Y\pyFLk&Gl@cetG>JRSIXpM%PCebSpZlDS@tS
cCtdh& \=4nE$Q:D^IDpMeul1j>n<SRjmRGkEj19NZqeRtCADkWuCwmkWCAE\V?KpEPcet^9$\QERB?VlBq@QRR
iDTCB8 ij#P!6<4HRy=LEE$keSRCN>CEAt\LhPI%F<q=q51?JJnV9^XAXEB99RR@/t?<T+/hPCjIBm@V@NdHnmu
4FA>MN ^1RlW=%IAnq^ei^M&QnbYd^qD+9E6Nqb&b!aJIF+^p&%naWmn%:TNV+5KDkyRaT4?:@NTYCq>NBedmyP
=lkV9Q w&!ku6ma4^Y4YYD91quSqTFS=5B1t5Wy8/tm1^L6<Lw%*%#jREc*EqCtF?NK<+5iXCb\H&hc4wq&15Vq
9jZCwX 9Z/Vhj\Put#%Bi$/bh&6+Zh@DuGZ&S&@?@VVWy@6kX8DVc/5QV4#+I!h%=KCLh<6QljdFG=&bT$XFZX*
9jW!^P 1>W%6jS=dp9$JNYmGWyaRY<*jkju9?hphCb:Jl\plyYJPI@a6G^YDM?YpQ>MbthqeZAYeem@!jC@tc^S
EbC/$F H=PRp^4Q!5^JTYdqIM8JZquJ4K\EuEZ!/N<WVtyPF5+mLS=&a$p+m$!E&mJ<qGLP6:>\mX9kW>P!a>q^
=@VpV9 PC!Jl4QI!EuLbth^iMbGI?M5+nNb5GLIVYRY#ntbcVkmZE>?ClVN!tInc1ZB5eM1<H/InS/F&euJuQR5
t6=%I4 D1^DLC5?HmuLd*@lAHBTPbp^PTq^!i^bPI6$htb&RqyPFnLHCX9*1I4^Pb^pHpp!P\:PCX>u&C/kWjJ9
EH@6VX EP<@M*u&Q$dN??YHJ1P@S8jAQ<B@+jLl=R$:=h9jdE+!eqFthma4qy*C!wT#Ki5dP@aH@YkWcZA&IM?Y
l1T#!B l<X!+KJDppWpk*A/enI#ii$B+udlep^La1hG5&BuRTVDiVaY%mItLZ*&>=k!a?QaKem/Cy8*jh\mPT$i
>:Iua6 YjBBXwZHT5Mmp^*Q!aKV^$d!JIWX<<$!&QGbdFnl>PTe4NH!#e=N!<1Be=ADi!mL:AV+=^?j4Jke8Gt$
DyXBd! TMtB%aEdBA5iHw6aFm>im^l&LCe=tRY4qQ1VFK^jCm54Jmiby!CX!95=I+iXmhSHLQKSALiPw&TnPJ\d
m#@tFc 5BP$5Q>tL^d&w<#&Q^i#@djel6*wn&!^@&cY>5++C<e^db^Ha*EineZ==%me^+Sl%#kc$H$$wQ9QAh%@
VEuC&i 5DnDV5ZCb:T\jWiFjL<JaT%<j=d!@S:1l*RK*QS#$yNu\?Bw%RwcnTLwi^SBQ$eS>EM$dFT^\IT$VMTp
&5ApyE &bq\p\8dJj\Vc#RP%9e+YD@H\SyXk@WnL6c*4GIljtI51>mn5dC@^<L?PSd&D&uPcEDP1Eceu<N^j5yV
tQjGlR NyJZ1cQ$ccNTccNTcV>LyZ$Q>IMqqnPV\!9m6NGe!ltNIGe$ky!jI<n=IVl:>Qj5d^p%?+hC@G*L8H:p
pN?$>C 6/Wi<p<49?NY45aY65dFRQu^aML*mjdyQ*+h%$6#kV8W*=i>ZRAebY!hGa+ZHF8PAuuuwpa@IN!*8#!R
TVhS*L D%emup\nR!ReTB8HWAp+!ukA\AGp<RkJB+DnEbltjMSWGt:515=9CI&IA/nnEYS:%ZkE&Yn%M$Il\tHG
HHR1NX A!B8uDaW8CM=VlpKHAPJPB+l+pnna+E@RV+yCEjmR!k+$nk1Kl\#NB+k+5aqpkbuJnk8CA*&!?D+MMn?
-A$&KH 000777974c800110333 Page 228 of binaries1.zip
W<VI%t Gey+BC/FeXqDw%J\\FkaAE?ECDkmEj\bkGAA?ktkI1eKju\DeD<eSpnnERlHB5enFB\bGw@ReGV!PAVP
1VjFw@ aDJqQALHVB&Q\DHV^mMWHIW\H1HlKPM%lLPQAw^HTDnKiJ*le1GM%^p8F<y+uiHiAiWuubGdkeln<bL\
h9!u/% eHiYRwdHSMRjX55DcXRCDY++1Z\kuM>EmMaH\5bMyBL=RNkimFTAH/V!?9QnRhk8mD>1Eat*y+>MkM9\
%JG<LL S:WbBatIPJpQyJJ^AIE!H1VABp\EBECI%!QmA?E+TRA@mB#>+XPJA95DIwp@V5VYTH^^IubCJNQ+RNkC
t+@GNL mYRmQ+memAL+RSL9pBejCQI/Lu\k#E/G?EE!4%QDB%J+l*nGk^TEcL#!ADJ1I\I$jlBJJ5RQWulHnMcD
WeZJu: 5I<p@9BV*$Ep=Qm$A<kXnpRT!AhTEHEcQ\n\^lb<IJ#JIH?e5BpTRaAjSJLJJ+/e#!bTBEBauMIZJ*IN
IHk4J+ GyFK+khl5/GC@CCNh+b#HIl5<mhT!j\kpZi%Il@+:TkmH$nmuc:pA&FnwBH+RdmMcES?pM#4+jGBFN+=
>5+F?R W#/RCwMpjlB81kl<!WR8>kWI@MppEuuuCEhBEAFBMpJEHA>C!Mby+EebnaJ\4kMkmR>EGqPKAEnlHeAi
bSNh9t B=IlC8@E:HkR4wLAn*aAAWpEGq!DARDpB?G$A\Ilcd\4P<iD5BpCQ^#Lh^APCjKHlJCiAH>ISM<j#hq*
MTd\j? EGd@$hQ+D5J^RkR?ELbmACKPA+pEPC<BCPRHTd\ZyQlAtB$m<+NW*t%8jCDCV8WDEbWw@CCmEwZGD<L5
:P\a^/ XAI@CPEAK4@!TBqSAV+R4yeAqVRiSG+VBal<SEkLA\D<IbG?E$DkB&GXACI@CMeJ<LEnyk%R?HIJ&bkP
>9i==Y EQuTVwLLHCCP##wA8b+awI+9DkA=Ep?CBEDp8kkKQ$nq*TE^HpT/Y&S?ehlwTYTIH/VBIJpQlI&YSPau
9@^FBW Rm/M+m5nADp$S?I4I\A=DWjmK!MAPibG+m5nADt@SlJIP*L!q<19J&#cJC1@u4Byp/n<i5L6EauKu!F\
j/YB=@ =TJScj\kuCIcj+4kTpCm<cYIDBMBNIkjlC5Cna?IDGe\meAjpw!eCmd#k*CGEAXAK8>MB^>I+^%VGR@C
1yF8+@ Np@mM%waSD4u@M4DXbDEb:RAMnRl<XWEABtipEB?eTy!yEhAHPShj<pHR4#DQ*\kuHcRQ=q\?bD+*B4A
\A+Qnq G+$R?MRyTGqCjGtu<Aa:jHEmZY5TTRAEiFhh<+HIaITQua1e*CcS?EEK:+kJH\k4V?I4am45AAAcu==W
>bBQMd JP9I@HEmX=mR?jKVC1iISPdLiSwSPRLQX<R$+N6yjn/R\n6W<#MIT%J+X&d#kXViucjnRTLmdTA?pITw
:YVHtq SPADiV/bQ!SmT*!?DkaS5?ELmZVjAA1jTpmuDKD\l$T8YkD=&EuI4TRRmS<p<t:wHkemh/<DAJ>K!MZK
Ijk8lD AJ>>pyB#qAC@u5k!CIuGF!h!IIqEGF>GJGT:HwqE+\jlpD?cekkGITyeQCCBH/Ql94&&<BPG4H\ScH\a
Yqc5w! QMIit=@+nmGuKaq<GIV:>y4B#^l!<^XyQIaM<*@$jpa^SBdm\<k+<IiLG5YwPJDIq\+A+iBLB\ul+E5H
$AuLZG ZMhAkC<heBWDAd=$\BpKAu#ykK$EBQnTARI+EPBLB?!XRIA9HZD=kkBjPpCEq!<h!I\D\JePCPHkT\e!
PDZjdt $$QmT\j!@CcJL^%\a\&T?NKB#GGR?NKB#GKR?NKB#GPR?NJBSnn+$pFGPQnTRcdlRBJjPyBV8CT?hFCR
PKc8tK e<S</aC:VTDIq\+KGRiCjPtA?*Ak!JeP&BGAIF</1AAPBQuTRWW+?NIBi^YR9<:A4lIE?hIBN^$k!JeP
<w@Bmp 8BEHId=$$JD:/jnTAZjjRIk9HZC#DpJ</aC>Jkn^yaNG\+HR?HVRaG<ARtR?DM=VmMKHIS^WQk#lwQFl
:ei\>Z XB^IHy<PG8IQ!ER?DE+dGiDDaF:!#?tApJ+1TQlbbRnpib#9G45DiCJ9tk4AnZZZ^nARN>a^G<QIPK1A
Dqp@p# LBW*%6u/n5FXjK^dNaaBPBw@B%^%cj\eeDYq<ZQAXbLG#+FMF^H+TiC/SmV\5<AXm$nky$H&VR9pA#Ld
Z+cbXH SBlHlJVcYJ>*>AAy*DSBNN+>mPQkd#i\E5hMiN\Xb$TIIAAn$=BnBn48eCy^4DWeh>KYTPGu=B$5J+:X
$B<Pi: pHEu6+qnqYVe$Ynm&FB+*L%k^LFl<$@ZPCD#A=AkVPbhi#5K@*#\ESm#9=>kbP+cEwCSNu>5lDH8XkFk
qjWc+/ #GH?BCQuTWE?tHiHCYt51j\JSn4YSAEahqkpkF>9kAd:NSJNEEa/#V>5+j5FJAVK6=9/?GDp>m8ASBTA
?BdK#p !RD9DD<jnDSQAJpkCJPSjSH<MLK&RjylQlAQl45P5C9:WYbnKP^wjlV\GA1::^<tNadCDtm5L@aDlX*R
B>%&48 &QB<DIY#E^\d=9%ARS^IFhABNtCRK5AGh^qA1kAddNWkXaANIPBAtkAd+5%wAt\A58km\Ab:FyAt\Aa*
TTRhJ& >!BNkA%bmCAI5CGZGSAE&JDLN\kCdLByRkRBN4n^lkmCdFReSBSkA:<ht8bHRS^EFGCD*RqEFGADpZkF
$=:$SW &GC:kRABNkk=qT9ABnh+ECDAB6e^CBBkk>$mBAm\\VaNpRVaaJPGTAJ5bJmNJMAG8#PIJMAGD+wlpkAd
jSBVY! ZA$lWICNh:Y%AB65@SAw\IbeckRK5CHH@WEBNmwSB$ECdLD%R=AAG>^IRyAAG&#uECVAlq!JAAt\$d=h
^ZZ1=5 Y5TQ\9GTBhnkylEm<:QS+LaSIqMEWDl*!DRBFMSBFKIAmq^6VlJA+XRI?BIcdNGRkC?lEbF+^:NBTP<D
^jtqD1 HF6DGAMyPJBC+AeSX#T&#k5#nJ*&lb8^5S4kBdeNa>ZMC?Sh@DV/kT#Sjyj^J8FyiGSeTeW:J4DT5>tb
beq6yW ?P>H4Dty<ZmGK\Mjq=cJb:A#5>JTYeq+SmbuJk9b:nFtN6>mIMQMiGICt^YLH#$pml<>JIwnnnF:k*BR
<XYFiE IlGkWjE8uQmeVDb9%Z4$9@EApWju^M=K!p=L^\i\a*I!Pht#ij!n^\FlMJphp+%H#m&tydJV&hqb?FkP
?Jpq%I K#p6Hl?hNw9*A6jQVHC:BPKS9X>8mF/BcZnP6*N<9?abP<uHi#*qy:kAkAACw=wmB?Me$tJun!pPmBAl
?5/Ib4 @8e#>Qm5tE\&P=Z*SN4QJDAyBa<wT<V@PHLIm^!b=^5d/9ICp\C+d#Ec?N6yW#nuj=\&lS6i$4nk<IkL
$Q:nb4 HA$iqB/j!T5djF^tYk1ilWjP+ZHTe4L\*$<&An<MBBGGS=lE&u<kDI+Zl89Y1QC+A/h+=MAy*le=eQyh
WC$<ii F6pC?d*GiWN+Kn/XuR9uRSLiHkhTlQ:kkAQH?u@njuDEkYPV:PN?eMKBa%*+eV<++$C1$KleeCBXcFT8
Pa*#uD PHC5>#:8B#eeTBQK+a+DcWI=QHARRYlWunmIIDR1L^^EEB1XN\+mCFZZB\eSlZL+=KT\M#p^YVn\l>Z@
P!i\:q @L59Dl1du^n*A\MHAWJn>MNBwFDqpDhIlTwZkIMkwXEF#E/JVp6GhKMI?#pRB$FCI\#CRSTlERdnwDGV
yh#>Pa aiB=1*DWH=@IZT&$H=@Iw6BQu!Vi#bBnu<nWLPZHJ\T:IQDHJ=q*jhDaJ#LB?SMS*JMi/:jBu<kinl?!
KjJd+u !E&jQ*/p<ndKjj?m<i:5@Q:F\j&k+HB\a=$H=I8DG?5l\=<#ehCQH&jmKD<Wu<tBY\+ll&=JR4a=P:K!
16dMmu EajLP/+d#<:mQiZ*LS:juG^p#%#YV<j6A^PRXmALS^:49TDuw=H9:^ult<=P6j?&w%Q\LyF^n@d\?L^=
p!iG!j L*5HbdHH!H=YiFatP\=L+L%el!X<?\h=pbWMIZ&1PK#eKEbA$w4<k$5h\*n:FQk^yA@Pl@EtSjp\*9Ru
&FJP+Y Q+d$cjk\*wRnQ$aY=KAmuwAjk\VD$akCHESpm\E@^4Q9<SmE:IQm^=AlPS>G=w*e?VCiXjNlwCA9GSLM
ct4@Y1 W#K!G5KHWbA6IZ\aFbpE=5iRRTpjSpP?BDBIIL$$wtCb$*mDjn/MN<:t^&mCHL^%Gn/MN+ZEn=EFPZk?
qtYk%T p^?nCuL\ckp@SlMwD^1!G5TQIcPp<SkSIk9aEBGmCJRHpW\V5AMmqTlRHpR1d!GaD?M6#@Jl9Mq*jw^C
D5>?A5 EMB+6%L#a%SBZemCcaPHQaIeFLKkj5mE?ZkMIEECNkV*^AkpAR!=XpAAw$ECGFWkD&AuTSIIB^IE<lVb
dymH>T jRIIaL^XVu/MRlHARCEewEA>l#$aJJAHIFtIL5lcLD>GARR=KFSBDmH=DCKV^j\aVeBQAlCBCAqmFAEP
j/m@d< mLeZml<V<NpABICCHCTB8kynbEFiTMB&pX$&A9aCIY8*@JmkQ\X+I*^?nCdkD\A!ATRIanRBDnIk+Nhk
hh%a5H VMC9AYVi8l$j^q5e+MN+N^9!ad#Vc*\aBSVpEG!*ADINEPSAblH=MA1BJ5BBIR4YI\1!ma$jI\ucAWXI
KGlTW5 &mmRwI%V!ICkLtT1kL%R1IL&R1EK&k8FJqkZ1ATBhk6bZBBIG=Y*@*I<S1MJ/EiCP\&kAMddPe1HAcAk
SZt!kZ J6lZkVE!IID^FlZ=MElAQ^KBKqB8<DlXwM/RmETBip+mApRlGEWR+&%X+MhwklkwlAMT\kEJ+TAL+TAL
1=8phC +cAI+cAK+cAK+cAJ+cAJekAERR/ATBTCCZIkt!<FMTEeJCEewBAPWKC8j65hJaDSBDHB@kc!uWWISlHE
Bu/hX1 1EI+1EI+cIIeJGVZHn@G&<a<HmQ#>qn^aSAkmQFP/jFlFIyAQTJVTWI\tmBGE&l@TSRCWRkt!EESdQNk
%u!GED VJCDAknlIAulIAulAIX\kEI+ICEebCEebAGjDjhiTEI\tmBGlRR^GqEIJ8CHRAJN\NiBSIKAQ\YJSAE@
nQeHP% D9haATEaXSAnkaIad*YbH^QCARulkIS\pIX\WIS\WIS\WIX\WIX\CQd=RaBAEIKSBVEmIIkBSQ:&F?+/
!81W%8 C9TyRRyJwK/CXElk9AyTliRBXWkiWIZpAXXIHqCF=AE<9lVA+QGqEE\\D&mC@kYpARJ%ARKIAttDS+Pk
D&E@m/ IMcd4?jDREkR+:$n^w>SBDFBH\bnRnkwRnmwRnmwRnlwRnlwkl^\S$IRI^KFaIIeJIApBBQCRSKan+BI
P<uFT8 wEBjGeawkllEEwLSBDFpyb$jw\n$&!ETXcBNkaeRA9M?ECVaq+LkbqWkHJpICtKARJ<XIyNARR\pCMHI
n*AlXI klkECMGEeJCFeFCEeFCEeFCFeFCFeNAEPTkEklBMpIMmYC>lVJCDAknlIAulIAtMn?DcBknB1IIaJFnQ
Glh^8w KYTCEE\IB$WIB$WIB%WIB$&k4aXHhIAkSlGak!LD\\XRABMea=NJACmIpRlCMLIk^66I!I<J+aCEeJCF
?E*lqJ eJCFeFCEeFCEeFCFeNCEeNAEPWACTTD@RKJAYbJBRd5mk/BA&\P*iAL>W:m&CbadKDk&JXNB\dKpC5+u
#=RPtA \llNEKNAklm!J$WAw\lmNCEeNEEPIZP$bB1SKARV=KABJCGaEA/TEA=RaQ!B8BhBVHCMA&M$RW^\nAPQ
ELZdX# GkZ/NHD6FinH\layMK<Mh>EF:A@8KSPEaGSBnARI\cmCGCmEA^LCARulIA9lIA6JB\WT^KlERa\t1A6e
&:%^iC n@n#n$cpCjl&Gl!PLIABAuP=NJApaC<\SlQEREkRk+lCMIwkSldCRSdCRSHCRSZCRSZCRj8@&n1D*nlT
9pc/au II#?k9pQi<p=FFAWJXp?JT9qFGu*8N1D^^=LpcJaeuLK4%@\^6G+**h>/yuZNFANBe\IB@6YP99YtuGc
h*G=HT aHR+?>bm\6HR:6Qb6>Iha@:MRE^ew^#E5MYP+&^:TS?TVVL4bLWIJl^NPJy\hPF\+ZDlGMI^lCPEa^:j
-A>%/? 0002d4887e200110333 Page 229 of binaries1.zip
ZZ^\%6 H=5N51!CVVBDutG^j5!*L+d%tZ*8@QnP5?LtbC*\YW?Ha>l^d4>bpGGhd4Mpc$:YlcMLl\8HC<eRnlCP
nhL:eK EI+yHFM+^LMKnM$&C#J4bJZ%G<kJtup@#pu&C9M^:&M4p1AeNp9H>!Zt9+5l^t+YbIm^t!Wba1#6u%\R
uS9bNJ VDlTPBBndd%quA\^h4MkR+#hVDmceHVl/MLl\8HCMaRnlCPEa\4HFI/pa$WP\ik\c+LSaXW+tuA$+inC
6>JnH^ $aZDlYMI^^CPEI+RnmpeKS^J^>+RTEbHNVy1NeGEw\qHE++8HC+eLl^DPIb\lHBM+bnCpeIl?upV@Z\j
h%yRc= iCe:#4eY\@4daql@&&!R>T4aJHQlGMI^lCPEI+SnCpeKS>LSC^*hn9Mn&<j>!hw^d:9bJMQeiVE9kk&!
Pp=u8k IS^DPEI+PPc1uYP8^VDt15=*+?wiSVA/9FdBlKPZJB6pu1knH$+YJqmRaS%5M?FIPpa^\ikaS5iwGCP6
hmceD^ WGKCBXq9bP/w<#GMLF1RJXp!dw\M5ClN5CR#J/6$SGQ@ne:?G%+d&TRL>1$I>1&adJPSdQi#5E%P1&TX
H\@W+Q :YW&6yey/uJmH>Smwm=Zq!aVhVtup+t/VFGZca!VYc6knMWy/nJFZYaZDqGZPSmLM+ykk&\!VmdY$K\X
a1hy!p =PWZR%=?5$tG9L#6@TwJll#!ay!u6IL%/Z%KBP%q5TSLa>pT:cXbRZ5S?%>5d$uAQX64kmXbh#JHi&p&
KSCTd: PqpW\RdbSH6yqtk9dW%iWLa%TC>k&K6ti^>KBYPi+j?jRVt!&jD5c@I=6=h##kiGNhh>uHcRPjI94ZF8
cy5I#u 9$dF9JhiMNhh9jjZ&1hh:iN?#T9d>S:%Z*uMc@a/j:6t4&P>6>iF8K+JXkS#\cyk/q//aPJi#MS%R%\u
qmX>5X :5>WPXJey:=QqMNEic9!m4KbiAb&8Bjd9:ym1QNlki6c1&?9Y/#@L5eXt&l@MSlL8Gh^Mi^BY^N5/@m?
lMck&9 %b\SD/a#=p\SV?hk*JnBGDEV5cpZ95>:\X:u^dCP9Yd5d@d\:j@8@Hy=Q6*euN:@@iZubb<KPd*@>P*^
JBmRHK /a@Z5!h@QV*6j=9:jSV#\#<*D?iii\jFJiQT^<N>Qj9Dbd$q!:t$<:qedt@YAK9Miy:*>+>4bnR9Me=*
^PJ9*5 n?N5=iIq:8:9d9<>*h/i99?+i@:^el^qb^K5u>/>?@n=#>N@WE5DBBRAAkAIAPbXdTYV1cuJyG\QAQLF
9QRlYX GRA%AAAAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&S9a*M9WEhRX&q8XZNqeuNHhYqpbT=\bGd5
?TB@n9 9ZXAXF5dQw4E$D$kya=$M^&ATHi*THiDyIFIk+T$AldhZSIG*X$mKmJTImAma85FHW<P^?G:>*j9Q>h#
4+1eqS >5\\5>/>*%u:ihc5>hdm$bbZFIGIR1q==q<Mn%NVREBkpIi%M:YpJIlcVQ?ey^%IVN9K\Y:*D&$4L#6*
Kt$n98 H^AE9h6Ch@h9ZV69D%<9G#69EATBjW9P\>%u6<*8P@Bj:*l=iMy/uAYhBmHkIBRElECkh=<\IDMR6bRW
p?q!mX mN4P*Zd9a6C@ZqS?6#Hpl:ma<TpVpL891?88MPVum:@L\Z+uB$jmqIQ@Vk/Gk8GTR@^YDwH#i5nj!pE^
DMn>Ta 8PSR9=WD\*HJwj<1J?hqb?Zn=PE8d?XnB?KZF+hkMGnI*n<$BA#BCP#iYC<QY%<dP!<R9!pMlh\>WKbk
AEaR9V MFlt:<Ft:<F4:<Fn:<F/:<F1:<Fu:\G$>!C@>?C$>?D>^\it%D@ieQ*n\i/Q<@!Rki$>mP+>kQeiIH><
uMGLaD aQ@Hyj=5dEy6>Meq*QeidQ>w=Q@n5kLa:?m^?\$W9c#e:DT5ZHc@DWIWwR&**@%R\<MY^*hHIZc@?%@/
C\q*N% DQP:99:#+i?hDRH@#=KR*?IikeRyCQ%jBj@CGC!:ndY5ui%5jEBmi4:YQn@iWZHdI:!a=t=Q:9$BBapb
<T/Y69 Phu/PP/TGkaTW:b#euDeHRYk<N$4!#4=iG9dieq=8Hq/8P<NDtnR:lnk/8Gq=&qq5!55d?jubGPu=GX%
tRPWWJ DmTtd8j85H5TGGKZptKKV1+?8:hIVF=PZ>:P^5QYD4TuyLjQ:t%$w/d+Q9%>k+BGbqhnP\LdIILhj><j
deM/&h E<kSpAH&@8$?pqGSpbJS$XCRpXHR$FFV$%BV$>FV:V:TWNHVMnACGSqwYXna&Fla8Dk=Pdu+@9n*9aYA
G&HY5L pw\kkCD?$CFPk8<hBGP:J!a>6QiQAQ8QtITIEHCIkJTMuIKTnwD\EBESIVElkJSw>+HR?^AlEV$^Aeq^
&W1dCS BwmMDwDSm9NMMBCctEZKXCZL%cw:?l#GdL*J:SZ!lpeP4yiWZY*n*acR=$9P1WEi%4j%cS?dJ?MNJchk
SR&+t9 aR%LWXDM4VWeN?Bu&*4^6tNmah9PN#\%4/=#e9Gh9X@E%j#/41tqHbTTpaN@=LYCP>$Qq>?nqa$h#$cq
qAXuMe FVd$VK><EMCwuHI/h#t>1LH*$e8Qk8K1J5:uw#PKt@ytXn>>j$yAVED?jacAdP<4uTSIYl1<nuS>XPQ\
*8%^dN jiVuT?/*yBudq$RW!\y:%K5J4i>EiTWG9XaNIt*pw9#TiGFb/+T=<HuSNJ>:QIGah?!*L/eLXZePCG==
ZiA&QT JP8>G?Id9!4W5:&!\Z\1QW\ZZclkL?uWZ%Vk4j=>>M?4nQ%+KS?\8H#BR/V#ubw=m1$$>L*uP?QYqc*^
>QdHWe VjMQy^h8>=iyDVVhQj<5+@bpR+NW5Wu@NHY:?n$Cwq!dq=6Dn+8jQX:^W<6=GbE<q6V$Vq6^/eHAJc4L
@yLRZD ?qN%#:yQjl@HZ5maa9uW/F1etNl/Jtnp5y$<k9NBdZ9>yi<VPq@iL1I@4TbCiIN6nBKT%:kM$d=P@p#d
$n\aq& 5m/?!iMTweLRD8WVLiuc<^?4tba6JL8#m5c&t:SK%VcDTI@VmwbH?y?5juCy+TV9PVbq*1PYd*peJlcq
E@p=WM Tn*:*=^*>Z@HZZH1=Q^J1b9WS?dQeL91VE!i<kM>D+4bdnnHii#qKtZ@5e<j@G&@E\l%?K?H%!L!WC@X
h5hc:6 9$@?WJjyqduXYMADk66/DecNS8NSAdwuVmaCqyjHPhYYlyHuW1QQuXbu9l1Y?Eu^:eY:?5emHwkcm+y^
KZpkde P4QF5R?eZ*@/CuZc^Y<:8!IeXVECWQi=%Keq<1lN6MLX5m:Ia&n=jVXdQLpK$eu9W:eX#m\PW4F5W+5i
?11$%y $/dlZXYiaKNJITDTcmb+/u#6@aNuA/w:eaFM^>aMR\q6cah8uSQ*9pp4<@XdteD&$^H9:Sm*V8uQ8lj<
twb&K> 85?J>iTwYyY?89TT:i+D6yJd5k!Qp!%tE6/jcLb>lSV\pL\/*u&GQni^$8/p5PTphen5X9jy<JPn=ch+
^qyQ/B jhcPKN5j$:#$@iHih!d:<4S$PNQ^5MuNc1Hla<Dap+<Am8R>X:dLuBLFBM=JdA<ZLN&G1Zw5N^McY%/e
Y$?8&b wH*p5Pc*ek@kT*%T<>cPRX%NjPaKQ=Q?&S$md4hQa9%p\EQumuZ4JIk4utqNib&<YDn4DQ%$S=j=t#/:
bW=VG< +HiCa6ki5wjPLa6J16jeFn%uZ:MK9c%/c9=DNPV^iQSNm+=9\<Nb<WpBMWjDTm+Gpk#XwQS&\p\jYEpc
k:IPH@ 9@hwuuYVbH^<M8<M8?KLRGF?^#PTn/w%GK+@+Fet?%Bt8*Bdl8pL^@JQhGM1dkeM8yT$#i1N&1DiJ#iS
5ByLIE H&YkPK=I*WK@E>@?\C4=P\GQ+@uIqVKWe1y$a\TVT6>GIct8X4%GHiXuN<IuL<?dWjjVQu9mC@yPMGlS
dS#h9j \quctXdDaJ!S=M?>8MiabiVdT#hFZ=eQy*+ybD9hcN^=a5DMbVRuc1hk@cSHN&*A>aWTC^FyWd+ZWpZ<
*@NF!E 8VXnYahieSm5#%>aNl16:aGZ&JT8ylkTXuay#6>Dj4N=jQ!d&/hu/WLiXF%nu+mG6XJXeq%Q&pW1G1*M
#G+h6W 9Y8:JQR^!GZK/@!d4^a/Nh+pZ?>5Khe^HX9IeI654Db\9BYj9GE&iMKR&&&?L@Th\\?!*Zk+<M*q\ePK
*MWB:R +bR9Bad?9BLNhjBy%>Y+S$441MDb4ZmBn?Lh@XhZE#J9c/eeR9Riw?jd$Y9%L5LE>*%TN5mceI?$IH1&
p$uQEj a9L%I=&>k@YGGw#l%PWu!e?E8MVj*/w>R1nuAw@#Qm5?<#lwLZidSwZmkiDD^!i@V?my9wX@TnSMXulR
q/EF&8 F/*1tYH<MI:Ym<m:+DMHyHHMS8Y&dqY$^EYNF>qDw@G#anQp9K$N6?u9K>?>\nqSh5^+/nlT#LqD^WGk
ie9Gp8 !FD^^c1S8:LV=9y>mhNVQJQ8kwL%w?6A*?<EEXLLFG?9Q>d/BH645nVFKY?TIneynX^i8Z#Pd!Q!W5BL
>><tt> qyZSQN<+E4Mik/Qec%C4$1=Ka/etB5SS@#n&BVLm4<KQ>tk>hQFn/NKF6KiTbhtVhi^DRlJ<M@KBmYZm
$HJX+8 5QidF4iPjyVw8@46%QmpMt&l?1Gt/<<1<l<5qQ9RCn/mLFNYuT>!QcHqdud+$=!G%+hX6yT^WPPSV&jP
PFIYqt unH@V1BqK6y&E8Y<=Slwjt<CBL?y#\%I#itSFdyWXidF>>FyMe*<+Si6I4EKj/<N6>nRc*S5ecLjCiwH
MKyj58 cL+VQN\hAbKiD+XVtX\4!Z9ma\5>@eDHh*MH<eSKQacdqy9c\I/H&<L*BP$aJL*tK9eDm!>Qq<tKH*5y
B@^XY= Id+VZH!e+9=kpe%B4=e9%YhpDFup9hqKIJZ8Hl:$>MF$LIq@mel5I>QuCSt11yRnHa+6*$=+:*L<iiCh
L4:n?Q a4u5q$at8Y$q:8Gy=:%5N4P@Cp9*HF/5n^jN<9Xh?1ybdc4BXhbwhaj*=N&ET^&KQp?TQ=y>QZJTQ%&y
#JmNw/ K+45JI>*a1#m/8y5*/^ce!M#?%u>&mTyqpNlu>bnyX!&PpaiwSM>PE?=ec>RW1keeSuL%b/#AD$>j><<
tV\ch/ w5%k8\I?hWG6kZbGWSFi?F:9>m:>F\4/@EVI4^5$jH*CH/=#*jqK/dQn/qhtl$R>?By$bISn=@S1GBTQ
$R#9QI l#j6XADCe=?5iw>E/d%*?4J%LJ#^yW&CX6<khQ:eP%4a4Q/>j4kP=G9&+K4/h+JN@YPB989HqHjQTyaV
c/p>W^ T/bW^li$ijTD!>ISR=a5N6GdClGRLu9#/+E6*#C5\:6D^DL1!/N:j1H1w%cIC$Z1=VqjwlXDZ#1e>NQe
<\AD$# nyMTEXK9He<Gun+:KYXLG@YXD@D<P<FXQ6**=%$!KH8mC#/%$H?/wwkRi8#GPi6TymlDnH#*:6Su?n1B
CLu$8Z ma^%>eXp4hJ9D5/*niwZHSa@G=XA9lNeS6puZAuN@ud@V4cMZc:n!$#bG/+&H:I<cq@!?jM>EQ^mHH41
tnLKC+ NPX\iSnlkqn?YFGYD!DL=LdnYcQ<T>@Hdn^/8qKy5%!hhIy$4VawL>BWWWL9LeqRDp8>@PpLPtQADXLy
6Lu1*6 dw@JeI^/Z@GyKAwTFh/kR#emB<SVH!:SyqtP?Ql=nF=hN<!I9M#q$GBX*+hW@W:A5T=q8FZtbqqba/Ha
c*waln NmwjYQSc<#/V#eV#d\YqM!@4u&ZZtqARXk@hm=iVi^y@ScFtd%Sbl4+N5H@^>qn@y5R^hTYm+Ju5e<an
>mn6pp F>/\nu9dJM/mVuH^tCpL6lh!ee/i*iye99FPVT*hI:DCN8^/5#/R=MG#^C5*Hte6n6ejjjuy+1%4Vpjm
%ytcS& \tVb#+a#HZ:D@b/95X%ITPD%B9QMW?j%mS&mS9TqW8VN*Gq1#qu+4eZ:AucY=L1ZZKb9#i:?Zp+pLZZ%
1/J:9Y em1\1\pS^^%!<AMSABcT9FM@Zl<$t9XwQG1!qi9B$=^lclyhWZnw#hi$8!19Qm%L/Y@h8*%XtHpYhHVX
LWH9?T uHj4SZQqtmTVT?XR?6KF*qLL?1wcVlai8RFRXtdtC@N&V6dh:#1b6H#mT$9W>K6dbt@Jb6Cm#PVQ*CKQ
-AWIcS 000f77fc4c400110333 Page 230 of binaries1.zip
^y<<Kl e::dYd=JVKikPLjhQ*khGEL8d1<MM9jCbBi?/VYN>%l$PWTqu/#Z\GV@#iVKk>W45^mGJKZWtXQG#a$q
:\lkEM pChJ*u6ES>=dmtQ94$^HpHeZK&&5&?V5*kti6SPDAGunn#X9PdYbNK<6jnQVeJ\:im?&:D5BlhT=pT@N
Sk6$jG m>iyAhQGL:Y9J5qTXhQ*uVL&6#=JkGRXH/<qe^%^bu5l4CQ/mq\m?ZH1Ti&&hZ<n64w&KB?bFapNcXHS
F/WyIK c8Cc+PD%p*9E6$n#ejV>!4t5u9dtuaJ%<phd9X:&%?!jLW<KPP8b9Z!t<$D9cEF?w65=S6@m6TScJ6<u
!c/alN HAu&@jJPLJ!EA%*SPWX<QQYdn#?ch:@!B/pWDkl\GLBjwQXkVHT=uq/?hCEtWw\4w+bDcML*bCGQ:6nT
E&?Y=% q11BhZ%W+<t%iPC^\E9jS$m+n&X<e?CqQm^*pY%k:cE@6%CCltAb#<uu\C?dD^Y?JEj*YSYiT>1RiD^&
F%YFZe V5K5:+V+l<&T\><JdANnd!kXuQQ4NHD*mQ%C\5^8pD*mTuBCIQw&=QTy+#GK%eyCh<4+Pyc@jB%mNDM*
Z?^tmc M?>hjcw/h5hh!Y44CPD+:t^#q>*Q?hIDlk5?&9e<iZ4L?==CZjH6K+4HmyT<E#&+Z*:cld4Y<lFDPhh4
Bie<\J 1kamKYea?I+K/H\yFNBeF8h%VZ%=Fi^wGGp$EjqJBllCyBy!Z8>L#khd9&?jLmw8q46Vu/w*YC6=yAka
cN9IE$ IAhpJmnJ\4/QycR9u:D#jt6#GV8q@n=?KiQLa=9FC=1/8m/QbD:XFW4e*44h11kaWLT\4nh+8H*\1INT
euFVGW w=QnV9$NFa:#ijw?Yw5YBiJQnyyN&81wiTlC:kmRTbPPudEa8V4!uiBi$<&:<4:G4+SwM@Ya:6#8d@Ly
ZHIGmB l%6j/NZ#ZTm8i6kXGZCwiDX=>a=W:RM1q%wh\!!qh!e&cX\j:bHq%@^?epdyk>EZ>Yj=WutjhLN9=#yy
8iC^=H ?u#AiD?LD=jmiQuiau:ttPc6c^:Ft*pT84iQKt%<J%B??FXm18KL&jA*bE6nnj$imKd?QN5ncw4hXTq&
ppbWGd #jh4jjwZ!<!9FTMCAj%#\cl8awSn\SlEJW@HV><#SE%CF$N+/B^HATH5Ski^dkjIGZ/aClB!1KHDFMM1
GN1&Kw *bXaXVumCeK\YkEebd4wIIqSAMdnBQX1jDFhNthGB\JqdbB6bQJy$ujLRWtnKwTHE91mbjuyPwmmBckK
1*J!NW 1DlbNd8TYXP8iIF9YSEukaLXHGyN*A!d:i1jinTa8l6J=E&6?><%>#B1Z6#=i1uF$6Nap9e\hYTH>Sun
A4yy5F 8@cwI@E>6q/uJQPNSK+N&H6/lwnRAZXmFLqpD^XP8+1P>WVI9pS*&MIPW?e^bPyZMwtT1CQb*5STPMCa
!\ptGS Z>Y#C\#F8tJaKCMpBEtATY+JmhTdeaBbe^A<m8hF^k%:V>R$Db@NthLQDtR=%:QaQ?c!$WEZl&yDNa!H
D5WB/S bPH5\+4XS>Y9D<$$^X?aH<$uc:>KB:CKen<MYE?\b&@%hQu&tE\&P=wL+MkmLakeDnYP8=j\6mNj&uHc
BAaViH tWZGK9p6hTFId#4>*1kZhDR/qQ$lc+=%=paaybX$Jqj$IaJ!aHlYm#a<@HmqNww1>K#8dDlSE\>j^HFy
iNBH4T L:d\aGX*IQGlunQC@XaE:d!1TZM*BEp+X\y=V4\YqM:k6Wy=puCjYpL^E*\h1mtwWHVD?X*:tYttw>E=
VL!h!u cZ$a!tlHY&BEX1H&bdIZyXEeQT>A@jBBy@PcP\AB!hYQAK8M<!\AnbTQ:BH$8c+pJPWc8kuhPuQcRmVR
ymV\k! VS&%mPNy&lkcL\W9IQWL4$T?l#Ki81\p=Del!EP!\5IpIBA89Q*Nw1j6=YGnb?eDPk$T$=bZBIuy&=*%
V1iY<A \byDbQeMKYKKH8+?wD%wK5JAEPRQp<5iDQ?\wi^>6Ge\?YFt\Z/teNbHTe>u#@/$>/tTHkRERj*^/X>N
T=@p#1 M<l@Y%=@ZI@/V<9M*48R*Vh?ttb&qhk>9j58G=#eHWAIDAcCNd4KYuud@SAXW:b#>dQ#edK^?98qWQ??
=>pQD$ %J>1:q=QBtS9=i1>>%JL?+?Z!9y:Bl%:K%>Zu:?jDa*dbP!>?=icp/**H>ayCPdHE^#/+\tBjjyyVwak
4Z#&B: \D?iwamjuRND@4Rk\=E@lckS$J<9#H/atZ**DNHkQ+*TCK#a*@VC@A?tdBn/u/b5GP4*yt\^&h%*aelj
=K<a%@ C9:X59%9+!DtH/a/JAcu:SeK?c$pCk#FKRu>@VXSaJ!T5N>LIuBL\u<9CeM6mjm6JAKN$=kJSj=YE4cQ
i\uX>> JP1*pqAMV55/FQ%:TVkKy!Vt>=I\uN4Cjw<lKBmu9\L&i\^BMDk^BQ5>lmA\uLmF@S=D?>uDad<H$V+P
bFb\Em HhnjRKV!a/nXh@J^6RQ^!\n<GIaXj@H#d&J@H*NB5F?PLP%jX>+hG*dX\P\P>:6wR?\!C+tG@&C<+T+1
F*lGi9 +d?GBp$RHQQ9p/N\#GW\8?@?hnJD@LjJVD/EnuZItqDAtk:DHlQJbWZRaa$<VG$Vi5m#^+uwMDWyIXHm
85mT^8 XV4:MGyFLwlQwMT^lJ/F/uQe^ch&b^GH=BI:4u1AE5pAwjT=#4=TX@8jE*Qtk5\X&d4qTXVyFp#S6/R:
cl:??C tF+S?%lCD%N^9:C1A>yD!/=dMemEDhZdlFG/l>IQ84+tE+pt5$/Mt6D&AMaw!waGL?mmkS^XZGhpC5kk
H$Wepd RNa*</GKhJd<+tTWwRIJwa!<RCwFeSuyBT<\<#QEYYhR$M*LLM5D&au=Rc@Di6m*bJ>pXTBBwMXPWqn/
?>^#tn *i/Y91%a6Abk#Sc#GENMuKlq?jRY$L5#^$1/tZ^/*Q4P9SMPq&\mwFcwdK4/DwjM!ju=kJ6Z6kiAqePj
>c%W\R !%h!Y1Yuu$m6%XKA4<V*cEQ9m<SI$aFhlYnG\+qeGLbw1Pi$\e*4A&RDKLiXydhm\ZL1w6El8uT5EXti
8:Fq+N >l!Ij4yCVqEZbW9Y<nh>1/ZSMS?ALXFeq6N$FPye#J<m6B1G+DJqMi>+FGVWV^$?JPN1^cwa<<w/1TKJ
@RbkH< ?I^\iZDIJ$E^Blb6AbSdDAlV8:+&\%JN\\GRkAnDq*yplWMHle16mIC%iT1tH5eADMSn>$V+6:/$pBAG
WjR<NT ZZpC5R:Tb<bw1YpLWbYtKKBq%W9w6iNcCX^::%bKc:PAa*MGQyMeTmqnHwG#DdF^d/PbwN*J5t?lA%8M
AnwtT^ lJMp=i$GqCR%@Tah#ae/$@Z9Meb^>pKJ%J=M!YVFHEdiVam!I=?bGL@kY8Z/m8tE*Bu6EyjKhw%i$1jI
LZ8?A6 dX/BS%6^hdTX5al%6/eIpk$/jj@td<!XR@L\/d6ZZ*A?kac1*iwS>^QSp#+pt&q\DF!%%qMd5S$\\T?S
\^INak yeDd1a8lB4QCkPQWCSJW1R@PTmc+uAVWWZq@bmJ:eZd&R<=#Sc&W&nY+nKBYqiGy<Lu$$M$JtqkjlXSd
?&4lm+ dV@jY=IbEXiiQ!*qim&y\EZYZTB4R&ECZG%t:^tW%>b:nZaKX9P66ny*\h?>TnlIY6^8+EN:>wbu9>E>
JZ@n\L Gp*E!V5Keli?>TEjq/iIw#=iCH<RVwN$Z>C>e61IEjMpanJA/pZ?=*yWdWih+H\W<EEKKa!J45Fwi61T
Z6QGQ6 SZ8KVy5:d8mm/SQulqn=>#Dt6?DD:T!WG:%utFPjLFwMQ^D\Dthl:%&G=qmPQ:X*%=@y<^@XA*VC1PRy
bDSlnV R!PEe<ZuLbm+QQ5?jct#@GV!1Y#6<=NSHt$/mma!ujQ/^$pLkj:B$n$NCW&Xy*p6+XLJEVjyhiaD?M$I
\Y\nCk I@W$@Y>LEnuSkiD*4!WXu/:/k4nMGmSaMP6\VBJAIkb<B/:l@!THhk4bDKTZ>hZ?QyZ<?XJqc#VEH6!X
eel+wE a8ZLhbqEtXV99l%\c\WGeJ!?GTy<jSn#\WuRN!B#t%N>XFeHQEyCY>Pl*D4Wdu&=ZAXaRK^H\Cu^Ji!M
9*J8W/ kl*4FJ9>JBHJ=iYuPtp&6<I##:!QwY\bpQ8R$tw>^p^Xien%b8T<LheVy?BIK/IiwmICwnD>8H\w:*HH
Yy^Q\8 ZAw1d^IV4dN4IP+Tey5%WNn!=K%PYYN*>uNyMh&YcIBil^@*\A*J8DMa=ZQMH5@kwnA/n8E?JG<b$$!I
LaKV!h CEplB:>6N+%M/BHjwyRw8T/y+qRYKMT1q*<kJ:5nXmdtSE>4Q$5D\jP+n1Sp!k#ua*1Xn:pdC#H=N#w4
hILCtV MWe\l/V>@hX4^>8Y/KLV$FDJ=HJqnLaMWZyVbu49aQF>=AWyCp6?Kn$:IyaE?^DDe@Mb@c1ma4&#k>i?
p+CMEL dE891ZKKuW8GL45Py>J&DA<#>p4qX>MD*P::S+wD#^Gq#Gd1M\TiZKX1aA+a6/!a9C#+%9kd9Y1FI%%1
Y8p#qn klD=!9LNDt6>GNJFw9&pFH$Gc/dD9dPc&&6&bBp%cnSyLQtp8wdn4BjTmwZ9DjDbWkM:KE?9X9HYLGyV
=wL1l@ Q#9lYFyePV*q$KNdRy=mS!qi*eVFV&%^\ph16c@?wc&BMbMnQ!Cci@L&?T<$NQjC!+cPb^X$FJp!TeP4
4++T/Y =DMcynuV:YRITcMtGFCX!Wa5&hImt8ydLkD6N@!$=GGTX^&BYlHtn/p?ZyWkj*+beN4aJ1QR?k+%K+HJ
99W<I! 8KbDP%Ny9YHi4SCC1?+$4XP*!k\T+H^DBitZL/MKA8X$I5+ZW1>IXELi>LA?Iwli:EB1KHu&Ec8hy>jN
Z?@!ll ?8KRhTb9>CH\<CFqkZNKq<XuT1:cCH@\wX=!V4F\<LES*S/YujIndmmJ+ABV1X6Ll@BXhPV*9</lhLlD
kk\TS/ BVqP98/=pj5eXVG^J9mYH#k1F$XDBwa?V<pP&B!kRbX!>GnDZuPbFI<B/k%TnMta1WijSqhM&TZ$>n!>
Ge#Y%= YG:I&p\9*q$GG9TlplL&8Sai$:VITMQLhXR=P95m/&a*%MPHB>/XKel&RZK\uY$yXDA4eYDP:%5P^:nW
4ucWV@ /!@m>wLZyVZ1ncE\?QDT\yKHZqZEmeFH@TG^VhdXZ\>qi#eFLX+IjFa>hbE<+paQcQ#<uiR*E#+G%$T8
GkJ*p> n$Sew4#\*m4>I^Y>?u6uK+Ep&Ld$<QBmh>b\We1R!TZXpDm\>Vb4il%4Z$y^:E8!R$+J6$Rn=F+h$T8p
yK@bS= qttYdm^eZD=9cq*#9QDGMHYdk+l@$qnujKVAwWjE/$=qd/5cltpjG=Jw^JZ/ITlR#SI1h#QV!>yBwlI8
ecqnl> Wt>=eu4w6X=EQj^w\CSSRDh:4G4<Al5MNh>k\@K&Q:GP#1iV>i&*aHQ#hE*A?#QT#Pd514Qt#\wmWb:J
^%%kTt #LpDb5l#MlI&L8e5ZVk8DMSEcb&>Z&J^w<H>\Y#*9PH\Vh1t/c8*1RKe#*4hW/pqW=kZP!in&H:Hn9Y&
uBHy6& RE^1+nk%T@8$>WJkY/!m4qK@I<HI?^tT5?SNM1%\QkGdYlh^ZqpJ%1Jcb\lH?p8hGcWHtZMe*KKEpwu*
RbQT?b 5qR#RupEkYR9?>Z1yStyS#:y%://KHdKh%8D\TcPpFw*@Z^HGpFERk*>T$1lK9?eFj8uL@\T9^KCi$A!
YHiFqD wPak?<T6Xu1j\LJSNLji=V8lnk8V=+cQuG@XyV%!wYJXLt8cQMb1=>Pwa<V=6qC9#\HXYaKA&>djSTjX
6a@ZFK *Vj$l<aWm%qDT$tlpaHVu%/k/$IqH*4hQiLaG%daGGe4&FN=djuE!@/N8M>$y:+L=6hbBNcJ<>8?@#aW
uPRCAJ +QH!&ecJej4*MW>=FV5Km\!94Z1XCm$VEn^=@>1HE#SYH<X5JT%NK^bIW*:4e6=$E1*!5uBGJPh5u#!X
dppW*! XW@ZSd+b4\/Km&IS$kXl5YEWkaIb^TRGSKH&D$l:LnpcG>B/GTnjlXH+hHEbD!@wEY84I/KAp\4/epwh
>*J>^D BtR$Ch$>Ib9t?k4/?kY8Rj!bXAqwW^:8#KDMj991#?HRIy5i??=W+4tMb=E:b/<R?>kpZABNl=i6T1tG
-Aj%B* 000834cc61400110333 Page 231 of binaries1.zip
J9$!tL *XL/Rp!Ra5a*J8=MSMTVFE#NjCElRi4qJ4m:/&!P5c$HR^*BtHLLqw>chLE&TIiE1mTe#anQq1d\d6nK
An:T44 Le5K6I4>uCwZQ!!jI1YRB8LRAmMT#uqF1E<&JBt8?NHqQDHXFc<1Ya?i#Paw=5?AYRVbIYBlJqZlnwtT
TDnCCa +=*MkR96@CTb6Yipp<tZa>*ywbA\Gm5^85:F<9PF#NamtkGJ!PBE?dp<*TG/ihu?AanLlASAPtNWMwmL
6heQN& Z%4uKnV^1N!mbPiehCJE*RDR!ABaKawXN8F**8=p$%GkM!1\^T^#iEb^*M<*L/TRemW8SqA+tm@IMbBq
R4MaK8 %wiQAJ#5V$p9ih5:w11?YBJ>Q$=5RMp:=1LJ@:=c&A*\D8V&/um8Qwa@m!9!HMWLHY:1NChBWqI=KR@B
MmV4uB AV9T&pw88wu<=<eGucMb+GEpG*DlV*B4Y*hCeXI8R&mRF$AlCS4!pb@AFl1CXlEJeceRVK*t+dc@Kn>w
+A6@FT ey%8$>SG*H#y</EqwcPp=4/JXL:L%4wpD\q5#yCSBeW/mpK:m\*y!w/6h^pwbW=YXn<m!8:4/jyM%EMN
iEYiGe GwyRGyL5kaatNI4E&WJ$iEQ+Ek^WyG/PKB9ThSJeykwt4REV/%MpdWM4I#p1A&I>ycVAK<G9hF<tA+j#
n:R&>a !pkFKR1Z1$M/aYTiW8jJ8N@Gh?mDG+pTWw<\DBQdWlN69pa^ulCqMFVVWM\eD\nhhA$<R!KWS/i?%Yan
<DyZQ^ EN9uih=DiSbXMN@IS$aMWL^jVKl9$^Qe#p^Dd$H<6ndEZw>ii?LNG@p85hJk^u!bbRHTR6WVwiBk>XX*
#ebquj In>b!\RDdWiIc=Q=pk#Fbt+\+!6JcY&ZYQPkJV&Ph85LPbuW!uLm@CuPJa>P&FYQ=w*SEQle#nSj6hXF
l=B#yS 4SK?DaZInYa:1m9JnD?W=6aGn:jy6b?H!X&Rp/8<V/hy<PbJd\T+^C=RlQMSabnk6&FuTQ+e&kWyRjpl
p^bIRN nJwNL1jM!ZAFpJe5\KYL/A&4w&L\81^e5*V*nDyD#h9TZwJbt5!=>nEyY!HndF9l=DXiY$FBKBYl@YZu
19=G>R JupDbbK=%netVyV&q$8FXZY!#^AWMC68%QbphC#wW@XH%MYpeL1C^%*J/wJYY$8nLF=cKZNJ6@C?XwXh
GV6w/F YXbkT>N6W/uph$8W4uu^:Z$w<=pebuHHjJR##W4B$jSJL1yR9?Hw5^kFZ6mT>HPC%\dPlmeaDt9XPREn
hIy49n bDN+=#Mt^i>$!KiHGpyG#kj1dGe=151w9/NKDe\R%KdPbVY&JXikqJLuPq?kJ/TSXI&1T<uI%d@lPYm$
Kd*:dW =HmVc@4t=S*$8/adBNKbn6X*MyeNI<+blP1e4m6h!SZ@Ip>14D&R<i/XkTCSEaJQ1N9!HYE/aRyGKYqe
DF@9hT 5#*&uI:t!RW?BtXyLdp:LK8tncKXh/4aBqe/LNV1VcSVKClHJACKu*K$hY%FPM+$GlP^KBA6tTm<=Jqm
hpSla8 6/dlNGTYJTHIKCm/cX?\mc4bKZBLQW#Z#$1tnCB:bpX=&w+byPp\AR$>alY8a>Yl4<LZC*^#&MuujqR>
HHl1:i euyqi:lK#Hp1&Dy!Y?LFuC&$WVjTQNL:1t?pLZp?=+NemtD6FZ&mEZLL%e@p8jhX*I8hjER+%a$E1=X$
4ZF<J& KBZuZ>GVHHiw=#wSu8hed&*AVBNRhph#KyYnZki+TZ:EWLAuQy\De6&cun<&56i:/n1:K$9t%cBkPZB\
j>nRij P+RFti11uAINjTSThhIPbj^tw<m=<BCLVjc/q*BHGc%#jc1NYKT#u*laJb$BHSQ#Y^RVV>:bR8c/\ZRt
yhuR=N AjT41?D8@Phih:!>*6?\AFmwK/=LS9a!P/l11^d:p8wd&jymnIkBH9wc!kH8kLN8Y+awkJ/5t/eCX/qq
*9/AA8 dudN\@qM9qaNt!:QuM!=>!iMp%e+R%5p*p\Npd/C=DM1!P8Qikpm8RSpJwmCTTi5aDNVS5iILQ9iEC@+
DyEyhR ^!?=h$Y+S>^t<&&I>j<pDqPRJmY:@GKJapuYG1wy*ZAp#Pjw4b^qn9F1M#l=8GF64W$LMXAcP1=\/aZ+
TLyC9Z ^ja5?Ww6%?1:AYI/iw\bGZZIG@q!y4:TFp!K>?W&u1y@F#e\MKP\PbZ1d!K>cEJpyDibL:8#MWRjKD9=
YNMFuL cdC!%\^iKa9PZ@jZ#1q#M1@4i4Mkamc>jPYhM\tRJd#>?NGlBQh*N%ac1RN#IKdq<%G&SWck%/edup6k
pwuLTl CP!VS^BM4+#TIZGkd5QRkdH\ZPV:NbkDc!JZlNR!ehcbb^kp&W\+CINtJbILMaM6Sp:tTJNIP%i=?C9I
C$8QiK !d<ip&S5w&4$W#AYpWT6BAFqyIApER$mq>CAMQLqnMPlRYtR1C9#TVW6buB1J1KHGc^Xptllala>=qPb
RE5VRL MbPL^<jdD^pjpRdNF<IcI^<>96F+!!J9dP:1W:8ceR*Ae^QW>+#G9DP5y\P/#a&1&>SH?E&/TE%T%4/T
E1e*X4 66#!wQkYH@mhKiq:E:PXb%D@S=kwL@EybRI44bG96EQnnuhjCJLdi$>+JqCbhK>>TpnIaiH&GLh?u:L&
D:%a1< 9q6R9?uwi$?Pd+YhapRk/jic#$LuF^5T9XlhaS/X\>wm?dbW5RSQ9tqIP%R<$wn9ya+N9LpA@FI\ajFJ
CJLYw4 eVkDIPdX/mu@pnDCEWdEEcC&M$eKyBKtQ^<tH@ji%DMnTNa8N:Gi<Y1%KhyFL5atW@dcRllb6eS&PPHP
iDDjG+ J1e>dVp5%NHtjF8P$W$S?uI8:e9LC?jW*lpIJeiHT9qH*1+1JPJi>/upbyGSp>K*iX&y<c4&MdjCcjpN
8aj4G& qE@\BiW&:jN^+Th<8!Whp4?cu/X%9R+*J*w6F^qV58C4PHCnyBPpWeKla4h?PwK\!i/L%IY4=\1YG$W<
/LlRWP XT=pKGl6D#C/*!d1CYDpa6%PP<%%pw=/\hKF6YK^@AJLYCN:j6GhQHD9e?T!n*>#HJWQw@TF!j6<PR<w
Pd^t=G 4pJVP8?FGV^\Y6$yJHkS!hTplbak9SiI4KS&8EdXe?@T6H<#\@5H:Hu*A+/8FDkGc*AF<Ll=FFh=1wVa
^4<>A9 !K:AE@n9Hj=Y8:X&i#4jmj&BGwXaE>HwFiI/CwEHc8ShEPQCw8nLy6eum6ciAiRi*qPNuX=XRp&9QB?&
F<8FD9 uXeq?Dw!kHI<*tX@NTBZ4>9bwQNL^GV^mV/=!t\KbkVFNSiu&c*XlM=m<wTA\GtAVTL=!GT^Xm<^4FPX
&BZKFV Rp&X#q4qbe<=1WJ$YJ/yZ$=W>9Z\pSMEm:$BL@V9*qnwLZWM!P4bcmmPLk9Ij8>&tDlht>?8i\EcMXww
*eBBKl RE+Xtt>1C*^mK?9tndCC#mMmcGFjwbpuSC%I8qD8PXYuM<i=Iy:aIun/G#+L/W^hFF#Jh#K=6n!iC=8<
=@LeGp @k%tj>NlWBMSPY<STWitSylJ1<D#NImKu?MEicZ:E*XwnKdhkkTyLmNQb+*#AwXDKD@%9a9nc!RchyZm
la%9yD N\Wt=YRi>8ce<qt#jbeIw86>e9Qm+*9BV&nPaKl8n4GSea@\F\D=ybb>bSMYyw&?V5W>FqIq8>%@a#W%
MQ4=\^ uEb/S9QmE+Cdq6ZqATuLmHTWdtB*!?B4?SGm>uuXy$\Du%=<ILPYi=XR5Gdcta$kZl9lw1J^!4kc1D9N
^?eIjd nKHSPL*phpa<Qt#+9pIuMQ%=tBn*=wBMRi1ee=kE/VhZ=:SV9B:L*<JjtJ+cFKn$C6kw8uYMb#b^KijJ
$&=nTy mcNlRS5e@upytWRdYR4d6^YDG$k6GqTdCc>9tt\P*&Z@&m/Hyl+SZ4&?1d#&miwG@&QVQADnFj/m<<K!
I\WjEP JJ8!lmkBQ?:F?<YbZpdbm=qZKZ\L9i#w?JE4yp&<F?T8K=/S+?E$beulT4yMn>HQW$4IEe=I>/wbSW6G
TKT5y^ Kq\L9R<+SXEkdRtaYWEHiRLc1i:FAC8hX/CWe<JPF&4Cc56DBRl>M&P=H4Sj/\Ip<B4JERI8wLt51<t/
?mwh/W 88jD=!+eW=WV@<wcmuydM^?\McbyLTtc1jNi6j@>he#:iZByKMm+iKJeWb!1jSyK1dX8+jB5W%Q<A9T$
wL8:5W \FK@DV?bNaEAe%\uwFX=V65KGJ5biX^=nEE+QFcBpJBD&JIj%D1jp&aKekc#^aHp/IMG:PnkS$m+/C8#
cH<HS* V+pCPdkIk!ew#MZC+^RI*>/6l=%pn4XM@knPNGME58hXJ16:JWGnYSc!R\N19jmS$Yy=56y\IJTFMm9y
!LZybM DAqND#!FnCJMnTVYE5^^t51QeDy#ZJ&XKl#kJG^jDtGNJkP&8t+BSc/N9$=JnN$1ImyS<@S6Yk<AmuFS
RkG@8# h^C^Y&Y$mFThA8!+TQjaI%kjm:Spla<>e=YaJmHMW6Gi6B!p>t:<jLdBEeH^t8VPwcAu*1ZQu4nd1SWK
K+ctaw Sa8!&P\aPSdqLwE\e%:=y&IhYE&kP=4Xn<+N/LFC$+pQy\HjnqKq1XlGGB5w//!XnM\jZ8WWjB%PJDeL
pd<R+: yMwmdKlA!eKTlmumCIA5EeGiu8!AK&1^C^kNd!91/Lk$IJA!PMGbHduiD?XCJdki4ay+u8A%JC+WC/%9
Q^!APW 6AyNYwaLlbm8B15%TH<@V98aGEmnLdGAwe1S1E#LDlXP&nu8!GteqdjmcZ86TtC8J%k5qQ?^mHJ^+XS+
:t#w>$ N1$5Q=%KcWbEc<<Ky&NYSbSZSG?dYJwNH%RkaIJPuR/$CPW=LqjD*i5SVT@I1*8i?hw>K!LCKMqmNllC
\@dTp@ @XXLL=E8=Ty^/iD\nbJD^%%b?wqlDCY=mVYD+lP5eyykN^4S?SKP%tmZV+t/yaV<lbW+9dw\>G?>8u@*
tVSppt =mJAMK!nRSEFkwP^L#EkPPVkjq\a=5B?ZMTiMp=i*n=!nqbiwD&*y4wX>k<wa8@DH@H*i+=WGA!G<+Am
kaALw# \H>@D:*:N\V:GSwFRwKSj^#Wj@*nwMjilcmlKDRI68eBBaN@HPnhLpQ69keFw@?mAiaQkX<c:9&>%=:/
ZW^G<p q?B@HZ5C9+S?HZA+HITCw$DWi%hDRmAkFBm#i&Z+n>h:KR<wJA!ElpF*4+n/eXWWFQunM\\e8j9?du9$
D%4%4u *wuk8!jai+FEk^BR^G+D&A@%WXAwCLKZhaJEw9++>5/!h?qj#*81:d*??S$R5B</:X$Cn5L<?GBQDRRc
lp48V9 CwJmICAwDQ:n::*ZcDV5^@5I?J+K8*ejkh\>E\aBkpQlINmiu8DhBpnE4y/:RlDp#^Nl4@bZDZ=%DQYQ
::iGm> F:6/@?1^H:4@?tP9NRT!1>9iN+V6juWMB9&H/J?u&L64j#uF4&@++%S:y<D5j15jC8/iAR%F@ZqZpKk@
FG+d/+ #@DQY@jZj61:ZV?/Bj9?Z>?D:&Hl^=6:nj@+145HFQ$uyLH9:=$Aljn#?IGF*a9@\MI@D<#il:9a&L5^
cc!MZ8 j#%?+8LQa\<:%L?A<e>nV#M$DQc9p@?ABln?^\*CCYeWA9%D^V%a@QZaa?Njn#$+WQ@C^V?QH^&J?AtN
<>W!?Q 9^+@*@5JidQjBwFwY:qc?Vm=i+nwi4lb8YMHQup:d^59J<?>yCpEBwZ?q@eTDn:\MId/9#&M@i:+j*+a
YDbTP$ k+Plj\=n8$QY*9&GRqF@ZQEH8@<^nEE^@+<Pa:6w&l6=>1:<c^ndi+*GD1J:^/@l:ke6j*&+>\d%D*#8
J$XaDu 8cZ*AL=*Jm^GD#cP@Sm@5PQan\>&4@pDa#<wk?%::P8>Z91q=\<Xju!\??diCYD@?BI@B$u5%TDaERD:
8B&Njy @Lh^:BjDea>naK!Pi=j=<ej@MJBlj9IS>85t@!<DGS!GQ5BA6uhLhteRj^*I+Gn$\Rc!H@4@eaQ@PyJl
NC&e>W wjH4&Q6P%L?k<e@nQ$e!:Au*H<qRQ*98u?@@p=^:>=u/%<*@=@HHTQcQ4@H49RPPbLIi44a+B:J@l&HA
k$bBdY IRei!DD+^>XlNju4>cD@R>kbA9LQ5DN5QN#9\<:kGB^lb@B@BiFkw?=?G#\Gl@>YEwuGLau+9TRakXMT
-A%9XV 000582d4adc00110333 Page 232 of binaries1.zip
>p%$#< ?X6JPAJu5BEe>X6JGP/kKnn/6=L:lTuB@#dD%@+qmA$XAtNDlSB@CSZ/FZwpy4q:?@/FWAV+*+FC8<^E
QB@#JF @DbRmC+/cEV:dm!Cnp1iSA=P=!ZKRW%MSJaYew!inmwmS<i#\^ZEVl%J?D!6n>p6SIFHqmn^Fyt5MBuJ
tpQPE6 k6eN@mF9Puw%lpVQFq6aiNye!Gna6m$t@PbeiJWMPEtA=awC<W#RuI=YaVSFtI=!n!M@J+XCuhWl$%A#
^LInaA qtkK&a!/<4LhqclKy?4K6Qay+DZX5GKYLnTc@Rw^+YnK6mP/qap5yepyj+Rj?cKeM#R#Z=WjPmG$yCaR
+RdQYy piYEMZKiwW<>LRty9X:h/D&w4!%/h*a8#JmF*=8Lw#imZcclTS*hFti#dTyb&W<eEbKy9SKtcuV+MyWT
/qyAN& Ed*@aZ?8iJZq$ENl!pY!JDy<qhq=@E#1hGVpW+JD6mcI9k5mjGe$qJ>6AS$X1y:LqE4ZXAcucYPK/aBp
1D:Y9* Z<9E:6IB1V\K6iE%@i\9TP+Nl=G^6MkRhqRI99BlK$LT#6!up+1jYTi4>jVi@kb@XjtW8tT6FHLw\TEm
NY6SLC IbI+mmAhwK!d6A::Tj1?ea48?a!PElth#aE1SVC@DpNup5SdW8YEedKKcG4K6T>W\Yy#+1$Xn=?#h+>!
*/mQjb VVhV:$WX$XA!Q8hWeKt>!q#!?1+D8y4Y=nt%tN1L65RI1:/A%1dkKEh&jm4hmP#t1M@*%$9/%FmJ1t%K
PdYF+t Hl&m$4J?wC4Cqe9=pwV?4EtS+64%I?S/1=YQBA\<p$?VlDGJq?pIcp>k>F5VH5>BY6ZVFpW4w%QQtMnE
cQT:TA i*$>%yGXMmyAp#mwhP^SCb%>^jV+VFQFR$cKeZCPnML=&4kc%<+n>%I#PwwMuq>@jpwjlhcGhiW$9:PV
pKPj?u &dESIc@&K*95EEdphpc*^*9<4b<Sp*Pby6JPk\=tbGwdPWLM%Pqc<eV\^D8t&T\Z$e<6lwV^ai%Z9^*Y
/$EYHy 5AZPHw56d8<mAB1<=Y<ACl+K$ta*#bK&!wkJ%qTSRp44<u@N!Y1\bM>!NR?+NiJ#wX$SRKW&pG@V4*E!
$>jISS uSdeNC+pq=!^NlL^\j9>IiwK?&cR!*PFt$Hl#Wh#9K^18Iuj8*1yp=RyjW:J@%4e4n\En=6J$#FaM8um
*YR!@k 4*Ky4Zpt<Ky?1ku8MXMDcWP<qR^5P8u%yJ>FC9L8=uq*?8@mpmSC>W?:%^G$TqH*$qMtt%Wy:wkQiRN:
V$LV4y VJ4NIN??uuG=%@WN@5cI/*&/u%4qw/E\I989W?GH4B?F>Y$G6n@bauJF\>>>ZQkmTKJ9u6B^F&mZ1mK=
/?JWKW FaAeq#8Z5Hn8T!!9ua=Ti=+t!=Il5qqXDt%\+hDFnH5=ecLQ41yTMMBYZV1?Jta:RD@Ee4$EcKX@l+C%
JCMR\# ke^JAndc%FecTct1yq/a$eV#6^%&=Qn<KJp16DXel\nqtDi4!8+*uNye9>Q^jhJq$$bI9WiY=A%q@GM#
X4bu&^ a?ya<bM?kS^#Ve%!:mJ5qRW4ZXdJtedkI%i#4yw9yPeTA1kYi\uJ@F=uulaPy<PeIXIpIw+VX4dZ@mTW
W+E4Py #jTTKJQ1XGS4QiD/+jIhE<\V:pEB^TQJjVbE841i*c%Mh^J$B&=+8@kH=XQLll=liT/*yll*qSSb8#db
c5mReT :8&u1GH&RL#tJCEVWTi%TASH=pji%%uJPhRm$!n$uI\A4e%*6#Q4HcwAP@/e#?cKZwKpKQ8ZSNi*c=M>
DyL*p@ :#$FhBe8WD*jhmu:JNZ*!F9RnL*8uEJmN<w&cCqQ4eNntCTTc&=6$J#dHSS98Z=#LGRuPHnBcYNDW>l#
%bJDby LJ$6cWjSK@aLaJu+qlGdTI\m@aqi^njm^$$aVJZcL6:bc84uP\?XX8Eyme\kw!A116VK#bMquQPmHtJW
ZlyFA/ pLD5#IduhGmq1L<k5+61FuC$=Skw*1b?W:YaIY$d*=caLnmSWMI#KX*Wq=kPeGT:FLJe/nyahCi4I+&6
k?&i&% q16aIVmLt:8d4yYW/\4lFbX?bDe<PqE8W%ctB+d1WL%%W%uhL?Q$+?69PuPHaBP%%^YA$Bki:8P%^IEJ
X#X/T6 hC+tGuEEPy<GPie+@a^+/e9dddtahbJ#T*W+/IB9*/5<F@Cn59JpNVcb%iVw>L@whKbH<+Pd8e8L6Ck1
Z4lX>S <8l:=BJWy=IKI8I@aPR9pF5=ZQl&mXh*pPqVHPY5WFGEm>Yna@%1J&>?5d/eYl:RiX&JcVqAI!VqiLBl
b^6BE= BKQ5MDp6IHPPLbE*YIH6CMMX!QTt#kYbI<@I$%&1BI?#Ik#d>c6$bX>NSk#/4L^+#E=S8?=dYbFPS5Hb
^piK/C YPc%+wuJ=TbteY?$8M@@Xd*y%hBY1dBRLGKJ>PkhNb<T%un1=*%%=6WQV18yEy@PGpBqV14dZ?PE6LAI
i^DkK1 uEmNIWm8QPNWM>jZARW?B5S/W$8><6*S9jBGbe/QwG4S=+Q=1=cuw?\Wq%<uXHVK>y/6JDt86qJ$PAin
X5q+6* FeQKc686pe=uTj#w*EcjH6Syq&$9JQP*+DPH>L#KkXE4a>DcF#SpydXy!+^lSIK8XJn#&#BkaNLWKwZL
C?=eaS GTacL1?%K^b4NAc?W&@LCq+IPL/I6>eT5CqlH$1cccaIC%+?Xp#X<Q*SYY5H5ISelQd#6NiaLK5tbuJL
81uu?y ?+*+Yn>9JWhESMTy@y8nmdcD/9HTT?Ptn%:GPp=aZhj89V^P9J$$eSWWLQ!eYpp6Qet!#1ViIhXN?<1:
Zm&/j9 yRcZ+ZiWL!+Ey:LbQLqB\dwJ:DAQwNMQ>!ub@kLR:w86wB\<+hq4e^#bqCIk:8hTYJ=<i@Y^*+&R\!:N
5VR4eh C1bD>e+PJi$JXIXH15J8*nah*YFHQB+>%5:!^i\/#aaHnX*=?pSVtYuZuGtmk^eQ*IGeaYe&St6!/VZq
QL^uMm aaIG<b+VKVe=!86hC1Ai>FXD+Y!GA5>!5>y8l9T<TlF41Ga>&$?98H+qXMchna^IYFZS1kZ/?8Kp?T*:
^J<cCm @NLV%heZ$ZQnRI%By*VdLw5Nm%5/1Z!1:BX^ihC!^6JE:h\XDycNw<Yly@9w>Y@19#>5K^cN1t+!+nGi
F>X=JJ FnI9<Kh@#VF%<jK^HZI:qahAQuDe\?ICSGpp$$ZPX@4Htiylelh9*9y\1ZEB@9+cVGYW=tL\pI+&%*Za
?>>pB@ R+n<@S6FYXDh\Q=$uYMi<Dhdl#@+B?kuBqT5*me=FuEdHL@$RL>mSZIIeP64?4l@ke##T9EQSm1p!ZX<
WwWVD/ P%<Q&>yF*^udeYae@JIM45\5KH:u4D*=:nda=aSLXE%jT#QdGh+QcWh8HHpH@@\\^4u@TI\HFR@j8Mth
YQaR<q NFk>pLZ8T9568n=VB:ebw:h<M%PGI1N5K?nuJP=W$19T!=?G\*a$B\Wu58?QL/+G8t:JelQVEM!N1@h<
<YihXV nk6/E#M$aY58&t+=uD*pWwuMyJ$jHRR>eT8i%8AjY!ie*4nmSLd$W4Y&mVA64WD<YyG%S\jdZAHwS1YQ
%h9yMp V^HRb+W\R5WX$c%+nn#1:uJWCBqDc9/cYm:^R^Z^=Ji#=+nHNJ\K4@NqyKtanm*wy4papK=wu!<An%D$
j?W@Gc 8SbF8+db8!+4d@bYpdwMiZS>pLNiw+wWh:pTwqtwR=Y\+e$==8*BQGP@V6P%4d?AVqRSuQKM4hNiT<9S
=lNu*^ FF1WN:<5=Xh^tTTuwY@E<kauQWBci#tPbmDPjYAk<I$InY9<%XPi/t/qY+lT/*PF6$=u&phd/pb*1SAC
ESKAwt nL?<@9bC*uMlRdBP1\ZGc>5<CP/lX^^IIKh%R^\m&SHmtVPJu=jueTb@yc@dy#qbFj&hX*qA?EqQ:D^F
/^B\H5 9k8^eM@Z?G*q1tw15We5qhT$uuKHS>m<SRJPSF6jFZ5BVK!F$Wh@4DT?Aen+MB?4$>6%pYL:d8RZa\L:
^p\GDj @lL>T@%ehDtdpT$L9tVE6T+?MjG1AT=?$T5l=bc&whLT%Zbh%XXIqVDGa!$98aR\uGy*9%Q1l$K?LbS@
Xm\4bn pBaPCe4=!P%=DTVEXqi?*h$FjDBG!kNcKa*^8>M*pSk>p$BJE#ttZh=nZAGqKq9l1Bl15uBWq+q&4XI?
?iRRRN #TQkGS=#N^ccG>EQnmEN<6K6n/9ccLR:\9D1%k*LnR=8/</Y&X:lmJ64W4*!DNRLX!h$q=T&bu6BC?*C
WSe448 We@uhQ5wl+kbX8FlDNV=uN*q@Ibd$#&AwXihVTh%%c$!*+tXt8eNXy>*QR=8=<>Z%cVSk*ApnXkNKK?Y
#W!y6y #StwGZAJK*bd=$E/9i/PC==tlEAVh8+YnRt>tlnl8\/nYBRy5D:uGp5FYwi:&N:*D4yja9p+/X8jitH&
=a@Dly t/*5VlbWjFKa+pc5wGKWi+kW=Xjc%R:>ZBK?YFJP*eD8DkI#%Vuy5cm/N#%qY<p<$b>YT=S+!AdFC>$#
e?4\8K c8a8ih$KL9l!YXGKJpd?%qdK86J:FkF^M>/81C$l*mD6iFHAyaF$Kh/ietn15VF1CWXT:4iFFWLt=YyE
S51=*e QI1X*Zbh>c86QFDthb&Gi6l5HK>6dM<J1RYpwC//ZFhGRFhHnmV*i++My?1m$Bui/?ZJ^&nTA9lm#abt
=kE!B< *&&^9CP*68pt*B/Ywq1tmwWHu64I*mBPc65K&*Gj8dN$*8FFaha1y+=16WSw#+Yed1Z56Jh6D>nImIMu
kyZCpu BtI+X*LuE54tG?^qy+Lc?1VJ&pVcJ4#$X\RH/+Zppdt4Z/RIa5m+mdjABELL@A<ktX1YSS4X^tTb$wL^
Hn=nyt nJIkdWw!C/*=A4q6SYpDWGmdV@k:t6#6YSJk4%c5D4qm5#=<@tR1W9DhTc*+MSItYYGSjDLb#iVCI%4<
bRB6K^ S:&a%AYK4MpFpie!R<mW\PRlDijKa>RAIa*\Sw!&8T=6E9tXCYuC?^TdC?HemtTmN/TadL5YMMb=#dwl
EByjRc /$cL#edb+?S!w1IS=YVh^>pIH^n\h85+RHVcdk\nRNDXL/J6>i5G>bjiFabt/ynwd!VZQdXaTNjZuDRn
kDY@&J LB>G*JYmC?um^qnXYcamcAJ#MYcKeBHEI$9BVt6LdZICcZLt\#aGt1tI%=c>K?e+D?8pNm5JZV6X&!T8
wH&YVc qWVlM?BTN?FT\C>wWCSRQCNFPAZ%:ZHi<dj5aniW4TatdBPh5milRF4XKl4QF>ucMn@&yVJ4G+w\>LDm
JPXnpn LGMnpZ:R$i<Iu=iYdiV6#kklZHib$*GSLcZw@Ta\Z?aap8jKViK+8XM#=?Ced$9lQTZapq<##?PI#BYt
1p%D:L j:I::^hBQnia<6#$T*b68dy\%jnClL>c>yYQwBDqnkDq5h5&wAkl\q^S\uENQ!/4q/IQcPnP*WFahncS
T>Yl=> &Xnc9H#tjbZKZ4b6+cGc>$N?=@j&JQRNWF?@EIyPE&KMV&cM=pQl$G/I:%K##^*uHL5t<t8ujPyAbhjP
BERqbV C4&@VY6=Y<N/*SdAyDt^BNqi%=\mPGHZ:Q$\+GP9/Mu*>$:L=^t95tq*$nW1yptMm6/Ra#Yc4%H99HLC
M1%ELN i6%R@<9Y6bnA=NKFKELBH9TabVR=/y%N9w9@kw6yTJ=89D$Fp=:u6Y>Bl+e9ZaW:#!YSX/cay&bKETRH
4mt6NG !:aMS^J/E!RHV1X/wqF?je<8EXc+lPTT9bh%<A*#c6DPuZ?J1NeIhB$M!yR^adEXYLIqd!ALu&<<4jI5
Y<=*MF wu:I$qlG6iQ4Ke1E:Q#aq@V9GGtVR>+YWlDiQQ*RNHn!E>T9^EbX!$BRK/d<l4$Y9?C$iBCCMt1F&uyA
%iXwDN t:!lTuQ481tmuW=IVc!!5YnI8nG@MVuu#hn5nZDTFMQM8CnP>Xlj1#kYdw5Iy4m4CVLVLWy#IeHVWJiG
RlS**V =5RQt+IjF9&t#<cARlQj5@E@QJ4>k9An!5iqX5t5+FyK@jBblJYQ*9N#SM>6RDjNFGVaACe%H%/*DPWq
YC8L^P j&SqTNn9^@p11K9m:FW8>=hm%&4ZjSwNAkk#BW@b>yCt/y\KDqY^Fk4DBMRGY>lMZt*LJY<^EYVByN<^
-Ad5/j 0008aaf76d100110333 Page 233 of binaries1.zip
mc%Pa< IYF%FCt+=uPun+VFXQSS1hBH:=6%C8iVu%>Q:^uGTEqei@LII#tw>9HbltPiFC6Ke:94lDhBhT+CtVK*
DPDB=d Q%!<1c^#8</$%Jn4M5wwQKVq8KNF%4VpXQ4*pK5Vd$DJId9@y!uj*Kt%N=:YPm6\i$/c4CYp+tHTQKnp
=51nnG >mhaWJMc:XtPp&\8Phu4iR<HZy?NyQWZTPtdyTDI!lPuSG?%S#Pt<SW:&QM<nb6@KNApedaSy5*#bA5B
HyHeW9 ZEldEVTSMy9&n*jTm&L=IlS!u!!p#*d:bT4D>eSQ+=d6#?QdN4&Y4+j*&ApE/iSWi=itM^k&$Wkd4am&
%4T<nM FBP#$y6PeRcywpLVTbQF:\ib9A99WLAMGW>&IE4<6F/i68!J@81XkLcWG/>wtDl=uWmZRc!c=X6memJD
GH=u^Q THcJ!$%GkT=!=tKZ?pt*HR4m\@qC6a?C!h1W8=yIR9w%T4cEmJ+d#V?\iY^VDYmmpK:Je#F\1K@SJi+n
Va5HBn X^Fnn?/kPB$ew6n58$DT%B!8u@L%B9MRih9l1=&q==w#qS:uNZ\88YNEwHml#4L&aZQiFjL*h$WEtXSZ
Y+dn$Q &hWWPB#HW>Zi9KpLbW&&j1A:ccR:iX4Z+LV8+\X9h5j\1!JuqVIEJ5<aK>4Fy<qVbNC+=Fnh6WXVyI^=
l=AEYy Ip:dGdd1dJ@WNYayNTWilm9GIk^99lNQ466/dGA!qZLTkJTu^jh$=\LGWLE:kl9V>9G+/YTjF%NYt&>H
/l6:Ac !=h#==p+?w#VHI%9/LK?XT8JPVW@q#6Zjp:HZGu?Xk^<y&V^yR:*ya#&=&/KdGS*:qt\E&>i8Jl$:c\W
u6hZlB ^$NQ$^al/Rw&nuIS/:\#VnA9G&GZP@!=Z?==e#dbt^bwZY*y+hkJq/\+EXC4bJSa+*lmTH>P=mq>dEn#
kNlHT? 5Bdy\Nb%9%W6e6q%j>t!\d9X>5b$kpam*RHQTlcd^>>>N#bKutnY%GW&di!/AWq*hLt:1Lu//ELdjVGP
?SaVt: I@+=bk@bH^datI4+ba1kEy&6^^=RijneQG>q?pZ@5MZN!*wQy?lEAZd?aTS*kmJdWhISy$1qydQN=$wi
?EqB>M N<:*EFcK9Qci/hGNFZntFYHud=abhG*SmphtJ8S/@e*\@ueCjZQSk6GhV!jQun#uP:4W@NA+=d4nuMDN
$KGq9q &=cS6M@T?h?nVY*i>abw4bB@jS%=#5*D&E9J%Qdp#R*!4\/#5tXYl$ZcDR41y/qHkA?6akiu:uWPGEmL
XkkJ=l iHuhZLqqhc@jy?*B:IqSij?Bp:ie!YiQCy+?T@HNbXFK!@Y>S&!c@>J>%kZC86qdWSXQHiHGHp>Fal$1
e@J!*Z wt?eML>!##wA8imI9Q%eId:<81&M*^9:l5tG#<^KW!NB#J9iS^>cD&pa!#5+%dP/ZR$V&4t$Hl6$e/jZ
^nB++@ W9!L%>HBneqS1!l$/P!C6QqK$NF%n&>dFLc^y+8i9Vq@^jndY+j5ehhunK<jpLweHa:+ikW^P&=Di9#N
1Y=?mt N+M\98944*RtC?ed6*yjYciStejQt@I>9Nj=>Lbh@=F4e$hQV6%:@VL\lyK=!>T>kHQ!T9NJ*&i9N5b@
8hiLYN bX?=K4QE/Cy*<?5V/ekh$M&qi!>u9=HQ#!464BTPPWA?9Syii8C&uM<WQ15T6hK?dKD!=b9a4ZJ%:&Qy
K%*<Hy GZjaw=FYnKb/a@EP9h!a\JA<A>F9kBACj8:peM:SlAF6tiM!qy8eX6^FXC#SqGCh1Gq6EDA&ImR1qw%Z
R>P!4J C>lFVKJ:\>mYu#PKIm#KN6?In#uYD54j!5cCmci\Inq4/^NKBRSt6=@T#8eF<e9aAFX85muAd6ILlIRW
Y96iy6 $dCTCbKSd#?Qa#5qG1yP#Bn5^laKmDS$uq!Fq^dy5A#q/LR1CJ9AYLR:aTWyK&ZM>=Ke4/ZhKNW%E&RI
#dKQtM #5#PLGEDH/dmVYw@Cn?h%EjDE^uk=K16J#n19uXC&Dwdhb<1?<#uLQWa=58nmJBa/m9EAl\WRpR5G%$P
btLByZ nMt^lY%>lcFBpM6#>5AwiebRX8/NeMa+jYj1I!EilX>b+kJ$yNIHLb8KjWDZ<8qMAnnEIXy/h^?=?@9R
cb5yQt ^:$&W&Jy+*=@H&#>6Jt!J9>y5?N1=Wy+u##l:ZB!:=chE<<Jtd<&q?66L>@*PK%e#EXaT#bTD!/lcM\S
>bn8w? m!tN4SI?#hbhLZ^>y^>GNda$XQN!&8Sy/$y:$4$mGVZ>\l#C6Q!ZBh4bEy#llDdEV\w$Q+GnK!B1%WB8
c&6==* HeGBtB\SlwVL4dS*PZK=E=\LJ/X/$nJm%K9u6Lp/qFeKTIR*pn+B^St?INPdXYXnleMa66:D=KE&*=w$
ZchiTp ?=<<bd@nASRV+qQ%$6%8&uRnP6+nq6#KjT>1:VcqtJM+u/!t$!T%YtHduJ$?9&\G9BMT/\$mkcuuYyQA
m$8cYL lNQ5Ydw!>YTIDTm1laEcbFCj$Z\9*VFYL5LMyMeFtmRZJW@Bm5<C\TXnWM+tym$yX4CnIF&&&5==ZVwX
>iPRRc 6@aCkiM1=#tmn5jMCDdJqETLEQTJET+<nc=pEE?W:KtY8JmFHNM:1?yT6*p#y+VSiVyQeIjkLpBqjQ1?
E5p+V8 Fq1Xj$!+$Ma@eL=<mSA$h:d#lTB=t1\h=TKF8wES+BCl@YFWc/Z>XdJEd*/P1hSKT#aH#y\Vbu*bTc5=
QVttK^ <yjX%ma%cPdHuk+YQn%^4FPWM+I#h%%QpcXP%/!bQW@$i55KX:a+MwtQb9=!wJM^INEy9HBXpFX<6h*F
Z^I\n& t=>C#1CmeIyb4:BlJp&/YLdB?j&>:A8YN%5ibF!=uHWt\&bl=yH*p?IRbFM%4N/N89>^+Y9phYi8pw^&
/DuIBY @ckbXl88c^GaKHeY\Mh!D*$H>SHdIae*qdh4hHY#FYdEdw/6bS9S%cdEbXG1^w$X#u!l4Cw>jQ6C$Eea
\QaeZ! !V$C8KD<ihDc&Y5Zu#<9XE!bQM*@FEtu>&4GVN4yG$>eYSaL4XCkTjT#8$BKcuDpJ:K:FMyZe%#PT/pJ
WL%1D< AZPAe9yQyuXpZPLVelKtCHZHBwm>:ViIGQKMw!e9XNwHc@iZGNpQb^#KDP+68wPy#u@c$&8QIHbVP1KW
!whW@N @an^EKQL\p86qKTn88Vn*mJ#8jec>Ya#yy&P!CkEHbh:i+/RLJ&ZL&y>K:>cZ5qEy^uJ9<&DkTt/1S=9
tBB%A& nlA:ShuA@Ia/Q9FD?Kk6Z>mK9cL%9AGJMAEj<Z9X6KSe^dQl/&WQGMT%M1&*\u8pTCyJ6WktL!j:kb%a
IP<ee< qWqhTH9%hp!iW??pPkK*Z5nhI^<ktYX9ADZci5?FeJ<uQud=CM5#hpCk/HdNpZPH8c:yWCj&b:CA19$t
\a5w#e iwyaQHwkkmj+Spt+y@tQ8:D\yVE+EV:#Rb!96qamWZFj8FX/T*TEu$/ac@XV*nuYPA>Xm8KF$<eGe5wV
QCV?kP 6L&pbhKyLqA?wiH$Dy+@wj@=KN6#HhNkY://pNmRXKe+5m#64kR/HKF\CMn@Gky*wKA*^Q@p>EV>!?tJ
=TicM^ ^NQymjYm@cM/<:?eukl<ZZwI?Q<8?9eTM4<Ej*wD$TkelRN?%RwR$\SB+Q<8TwBA@65hCQ?6L#AI%<%H
wJBwC= @ejN@<i*RQ<9hd@@?Cb@Kj!N^8MY!4m:i@n5BRJljuaY=ti^F<#Q#5BkT<KA\hluKQabnu%Gay?^q+JA
&T@166 5A$l&Ida/8MRdIpiCFb%CBVdDwy6B<XYKahA5R&l&Ia\dEMa6mEMi$K5H^iC4SID\acKWpP\LtAIHQ=H
Z/ewJP pbw>tQ//9SB5yal@>Qt@KwJkm?H<yedG4pc+/wtDj!8JSPN$tCMl9=jEZheDCj&>JBSuaAAT>u6JME+u
D4un\1 QSL?Y$pEBthXGTVm>=IwuBXipMnjT!J\*^ZW:!Zl8H5I@Z6JCM:RCiV9MRVHZX<I>Z5M\hE+1<1kjw<l
G#Y$Nb PBJuDS#W:#EE^%%BH@X:DP&F1iKT@D&G+GCe>^Q%i\#BeFjQRj$iR#AWV5Tnjw<lGBIu+qG@^^AMn48H
*qiwE1 jw<lGP=^CQ%:DMEkPH5I@Z5M:aXb+yL<QackcJ\>lQ+>l1BI*Q5y@B=DWDn8H9w>l1A\*D*$i\^BIdl:
VJ$h*W /QeakwJ^>>D9MRSB+?+lQH:LpDl:CQN:DP$*>eJA@ujS9/QI#66uh*wLE<XkpCkE=I<b$I>=!q<DBhYh
?!$KCT *F%?VIF5>8bSGM#QKG#IZ4Du#@lFYR<9&>%b&tpR?Mh@@:kwHn?EeJ!*FAQH1i:8FAtC\tAPwC>mF=B:
=&+TF% ?mI\KD#$SiD^p+@:ymL*%SeNQpn@I9b!NQd$SaQ^$Qj*\EjmHw+\/Q@RF*ERjZeZIV@$SeL^$BiD^@RG
jyKy5l >#+iaQD?CmMPyDAM>XNlPPd*CpQA9&eeA9jk?*MYn%NnKHm*?\?k<i+$@wjG8?MtHl4@uuMI*IQ?#@WG
tW8l*M dw$lENlBNAbnTajQIAEB+#F%^j%n<*Nq>E?N+d5cR%BIJQkAG5NSQ&pH*^&!<NAan+p9FIbda@S?GmQR
HwJPZj 5IPkA4/:Q9tlMRw9njFkH8=abRkE9I@GWBkKimCN>=J<>nSG+DEWR!B+VLy^L+WkEPn?jd\:I#?A^4Cj
=CJIEL #IQD<YEiBI<yP?=66mAR?Q+cH&m5kEQkQ#YGI9DSGIHH<kTFY&Ne#EQ5wRKPBKMPwDEM@ZM<*p6M\pQn
?B1adt *#MQnu6/CaGk>>Wah1BjEBn1J!ykcL\$^tQBC5E>HpQB?&kMR&PRB=pE:Z&@H^wn<StQwSA<qwG+^&Mw
8=+6Ge hH?N>#IQ<heal9tyMRKMn<c@b^+Mh\+HBA4jZ&Q$kVTG@l!QaVA+Ql4n5hSG:4MXGuJ@nVEHGh%k+J@M
uYhnK\ k?$!A\?N<Xmw+!/XDIGm@$Qnk#B9L/*+l<b+nSXRQJd=MN#Mk@$H<\+$HpNSQ<hnKBwj=5H\aB+EN@Nk
B&TSlA ?#IQkeIebCaESj^pHlTFD@NkiDAQh>+XBAdjh##iG^AQwDH<=^IEm5CHiVA<DBVwjjaT*Q<*D\+:!Q\a
W#hB^Y C9$=E+LC<GEiDA@#B8:!=lDa95#DRJAHGT8kpJ@Mk$L^aS:5><#d8%t+NIcD>>eahbCFNAV#<#eQC5cH
INA\b^ iZA<#HM\*M!DR@jZGHMRXEC\c^AIBl@t\jE\:8F&V$Dk@<E<>EFRAWH?bB+ElR@#+Hk\D:hdBQL*lEu6
lKL^!a Z+J@bCAmh*?hEL9\RGKZd+b@yB*?<Dum&C9l:+tW@#:n*54@l^h#h#d$<+^@8C=*V\qF\HGeE9%9Q!aW
Wi>N5M naH<99+=Td5XRS8FKC8%ImhS+k$&m8QM^ISdGE%tB$\WYX:W&Vp9WR+!RD5pM<kSGS<dSqjIAi/ulep>
^^#tMN >$ddwwEah51I/5LNBmeiNm4d1ne*/BdFTNT6TbVQ*w&F$eu&yYR%NHkLl5wW%=$DD^YDE/+witjXFlc/
FChLk/ SW=b%y^Yd4C!yGPm<u#nTtaJKYTm&h!c#m#&B5aw#wj!=%ynkB#lZME!uud^LdGK54EEQjd<hQSDnS#y
++8FZ@ BhT^WAh\Gu*CuD$aiCTeb!^LMEPSa<IhuyX!hdKPnpcJ!Wq:it<ut8$::NKC^Bk&%:Nj$p=!&XA*tbW?
VmZcI* BB6MQjY<b$FCwp+DclNky/BTdPeQt4X9ti5kq1RB#:1L5\c!WN5*MCZX6V+kT99RSeaPwCEKT!y>=W^Y
NbC&dH tpYtP@%CjCNn4KHCW9eVQ+t\HJC=mplwlCWmT:wNe4j$ljbl+pPi81\IitEDB9qETTYtLuyQHYbFi4n&
FqtIaG kGJm4l%HF?V8PYbFuXKDI#$/4le=i!AjbDlX%GMJkLSWd%ene=/*8>d%FRtGFV@wNja5#q*lyul^Et!!
^E6#iJ qmW1t4*Y*Ea#pwC1HFub/KuiMtEA$5RV/KDq1D1$cGI>T*e&\wq<Zpl1cZ/tq\/9ZKRd4!H$y8nRE1Nc
m1<&*L X1^?G<:SKZbI?1EMMTEqRai?D<hu/T116!/$WQDcY&X\4c8Ed1?Q!#HYwbG%PDQ=K4RVl>Fwy:iy%k:*
-A?@Z: 000b9d183c400110333 Page 234 of binaries1.zip
Mab<RT c=CB:*w!8>HYpZm4S<^8/bcu@MLL4GiRiZtYn!aZ1?^P?=p%tuY=ea6Lc58y=$=qQW<KaK&HP\PTlN5+
qdl1DV b=wnc6TQ44ZJTEeMQlnI+dIaFn+C*+!4pqBp1RM8b4Saybt#6S86G:BdVPwVWW&AG?Ke&^<t%p4a&j4#
cASqJA c4naG8c4YV?8S>^#YMV\lH55yWieTq6t98<t5ZS1R!6nAZM@@JdD^%tndQ8h<NGwy^ytn/Dt&pR?DdMQ
pQumpX Z#WGVRuT/WnQe<qSda/$84DG9n4:>FSWZLC/ZlTClckNjTJL<ZuReK#>EjpVGq!$1S:y:nGbL#qw%G:c
RGi=M@ jRHE6//\?y/=+SmkeN9n#R%tl?/6G<nQN>+kqYn:b/l=L8ZX5dpYFAJRGcHFE9yZB$QCGY>KNFYl<$:W
#Gi$R! /E9ap$V65C*LYVh@8HiWyjdmi#i4h>ejZCl#9W:Vdj%SSu1+aum!lt@A//+Sa5kdw<T?h9:?@a8=u!Wn
RkFt<K :>#&9GHSQWBTb!ENhL*JjE8RSHMpMnTeSY85@:u\LjEJ:Yqc+<&l#@TZC5JG/4t@*B!YCd*pRXLG^p#I
N&$>Z+ em8$&&nn=cP1F&N&5&<V#\\^9V1^E@Z^qCVdlRR9196uyZh8JC>eAF@ip4w#$#SeBZAG6ScFK^bd!KbR
NpT*tR lq^yRWbMH!bwqTiBJImTH1YVwVpNQ+TkJ>?S:Jy@P$$i=N<*\ay1pF^/9M$ZH9iNy9NP!*948%!lFhHA
<*a=l? i<w1LFb/L:*ZM\:Z9qkLyNV=jDKZnw$wWnYc:ukuTJpnNCGJ&ajP!pPtj@6+*R9mS\M&ukuLHeQN\E@/
/M8Dy! 65/<C1Ak:uyG\C*>tVA>SZQCNCTB*aVX#W9=b55>u6LlXNJKd6Lb?1\SW6V$=^Y9CyD#e8pum#CIc%!D
k+a%9i QtLQ%X<ZH8*VSBB$nBEGidAubaFWF%mFW?pe4*FqI6EEE^!<@N9y6witNMJ:L!Tp#D!RdW\Ei:G\y96j
6h&FLb Kat>HA9yplLku=Pi%8+NN1iyHTWpGJ6&ECcXK>Vb95Y1Z=buqS5%eEwJpTIi*l4Ve4QRb%k1Sj\&qj\H
QdnI$! #SIk8^aZQZi\NNmkR5F=kP&I%DYSa>/%q%%F:eITBDm:e!jmd8tc!Mi@NBQN1!&?%8?5Y%+WB<@*te<a
RJBXq* ZjXZh94EY%BajtP<QatCq:M/dj#+tLl%:1Ti?Mj4q^MDD+>>b?ep#wQEWQG4=wpDD^H4<&&HmMwc>=P@
MM8*/* +Da84e!8W@k\dGLD=BI#E5l$@@^Vqlua6jLNmGanXb?K%tV:HM$+j!KFPVK&/G%j!t%RCMH<N6WVkG8C
uGaK=^ nqdX<p5bym?W:p6F?cwN#K<K4+?XJtdZQcSWMSEcEI^q#lDyLQ+MiNX?6jdhFQVlHWpKaW4/TneyXuHD
<LSniA ZGY41lumR^R<E9=?N!h5VI#hH$%JN\J6n4K8AD\PVcM<yS?Z\>bKSL4K6h:!TK9ZebV/%Y*PyA&/YmD1
N#C+8& Kpb9NV/tYHS=euQ6Q9Yu^+@VI@Y+kq&8TDiKXlAT8>u$AW:!<==M6u$I/q<LQ\E>*tnb!EJ%8n1MtHtl
T1c66Z T!i/nd=hPP$tRZ&EK8ytTC8Bu4dKM5*^SjRtdT^NLi<pMKjZJTd9Ti8%/qXL4mjP%SDZl1:Xh+1=u\p@
$*WlAF !WnDmyLlhiwVh!/SHVeZ6l^!9mF@%CTZSMhCdX9ALQI/HX@#TIq?THpG6<BbF/4D6j:%H&cnB!?W?c+P
8F/l&: Mw@XteVauiMC&Mbk18?bN#RHQEK<e*%EQu1D?L/!%R%E^PLH^*bZmc=89I!A9k5ldtc8@Z15N<$*:q!y
XG%ePc lHV?$hPIASK\RI$VujRd5>VPedyV&*icu&ZWmASM5k/nq&QHV*9Z!S4+Q\bN>F@RK#Xl4NH5X*!kT4hJ
e\@>Yb =NJ:?dY5Z4c*tH@5VW9nJtSQYp<\!SG4Y\ncMbDt=QZ1:hp4Sy69\mW%cw=u5>ec*?G^1E@baD8h@n!E
ieQKX5 n9YV1iF4SyaQ1LPHd?8>wuy+Lk5B4YVh!D>J5pEqtPR5$1qCht*pNthqeJl&h$SEC@e:kdN1HRqQ8Li!
19IIi* FCSPVn=kl1+GIqmp6^VqHqBj84^K8Jp!q^i5pRZX$yB:$TPmkdpw8RRQn?h$in1adwGC<8hj<^aQH##u
F9#IQa kVdtiKu+h5l16QGc<qLcue#6&e9DnW>6X\Zj*@R%NBw>u!DCjZZiIFVD#XypG>:AJBi<!jT?XWbcL>m>
p+XB?8 ^4FnlS4ImdTa@um?jFjyHN?b8LN$Z%hpqA@ZFT+a*t&<j&@%!/6:Z*keN9$LLnluQH4?V9P<>aq#w/?<
8$EjW^ FF>8WH\6/VI44hVWm$aPSWmKH:ePm^iuREGQNH+D^D!YMLw9cXV^SwyLa9Zi1\YE*hdPLQ6DwVKu^YMZ
$8QkG& *qlpKTpR^q%u%H9k8k$6Z&>^a#Tc##Weauw\dj@5eQwZQ=@*>^>&jd:h8HHm\iPy$/>:J%yP*\/?H:Rt
Q<?H*c V4b8+Jj?%utt5@?BuPKhm<j9tNXN9:8Ry&jFZN8aQ^CXA\=&+&#IHKMPn&mw&DpQGG6akq9#e*9RJtR6
h#<dV% #e?Whd\wWh+5MZ+tb95t98X>jH+ldR?C\Lpwl1L!FeNdc5DZd6q9XA%9ua^J=nLA:ZVpApaAT^NJWDSW
bd=5qZ #HnAE@$y*4+eLEPpajLiw+=a4J&e>8kZLS:m8E<jXE6HKp$@4nMV$/:/cY%A*cRiL&eGP&pBCDJ>I%j<
8^*%1\ cHYdRVKHFPi@J:AV&9eVply8m^R&Z?++T>6J:yqK6lu+iVQ6SbqnhwZkGmFkVeN4JL1!Z*6B<@W!SYZ=
knmV9# /HLt?CAjbaHnDd/4C@cEq!NZhF@hQ&5ZVXa\>e/#4/uA>1FLCm!!kGbpc%K41dcmlE\d8TN+h5y?pLd@
!batNH HB&6cNGL&uZFRcwK#Suc1=4LGS6E+I&8kbC+*Nb<Iyd!D=eGc^mXJ+#YZ=KhMS$aiWXLu<NEJ@XyE#wF
M=?H%R $YC4#Cl!WH#YXS4CC\my=NA8m:AETj5N<p6CyL?9X+jEXF=/$@YJm=:h\+q66IC5ww!ww4JP!=hJ?CuS
jLMcIN /F5!!Fhm#Rb4kZncheI%6&@1t5RmL/!Lm\qjpi5d9j^kDb1mKyiCS@M?YTS#CRiA:h5A9F8cG/4npWFW
ZhYtKE :bKYWEY\q/EpcCW4l$/VRj/GHQ<5iGYyJ+=QM=LQqV69>BW@Ve*S/4P4TRGJY&G=ZmH=TXHVTVECY=eE
TA!N6J pmL=1w9+P+MFGQIEhA5E^^wFGTwLp1+JM=RI$w<W/4dqCt#hkh^%tw5YCALm*8@8H:XLjl<Q?5hGh@>4
WI%9y< QWRIA9\@lBbC@\\F@SXcCQ%nDaNZcCEE@XMhCB1D*Z*8%!=$MP\#A98Mdaj=&R+KltCjj:cnlwIS&DhR
!iCeT% &Gh5R\m&IZc*Q!kE&\:dD>BjY$lBwhmGWG^DKLalFN5R8:WhFIb6B<P&?:WhFST:B^$WG=wL^h+HKB#d
EQR:nJ EI+>IZbqB<ZGbWJ@qSZ/Fa@+c=*&n?Wp+6@dlGHLD@&qZNA?m&eE>Qi!?$R^R9+h5Q69YTStu?9C<bBF
+QA+dX +ZdlISB+!PI8PASBIQGRliN&c!FRiMlCeV8aEGk<bCER*LKa*<5mMLn:/6?lynlpWdn:CwpH4lBI*H&F
FHDKQ4 ^ANZCN\::WGRiPAKAeQhX$k<eLXQLCaEmRi8>wuGlCD^\NW?<bkRJB/+&memE+LEA%j:^GSCpHnkCk:D
Jq+\T# *XewQHAFl?D8K^Ri8ILn*lESk5IDX*5?YJ!!iPB14!+8Vqp<eAYD:>NZiPB1u\lNCAwQZP$Vw\qB+aG4
=mB=dl jcI$ITk<eLXQuCaElRi8>wuWlKD^\NW?5bwRNB/+&5?InMaDX>B>Rp4RiPAKkn8iH+LGA%iRjeI5$Hnk
5B#Nne C4JQ\AMcD%#6F*\J?WiE/p?LP%IWAwbD\NADlX>mQjqIJD:Sc&k<MIuCHSpL?WiA/=<1:$//\Ah^EmBl
ibtuM< Q>$cTL^e?Sk<+L^QQWdIQ<Jn@/I!E4\:LB^Abc\9H+tZL^?DB^PR?#n#@^El?^iXEZ5iuwQE=TK^edu+
K6iVYC 8BR^?E\t>@Ht@!NI>p?XIVAW/pCStJmjeVSI9L#=GH#twj8+<#Gw@aEBQwm4GaF%=!Q\e8hn<J4C+l/c
yMY^D* Mj9TD\W@pFh^d/*+R&X<@QqRMD:$&&eZd9B?>N9>tV>RaMyi$6AQqjF^/EQB?E!e>>pYG:\j@Zb@Xk<W
WIjXye aaZAi9RS?Hn$wYB<=6#::FkP*yh?cAV$RFmGaMPK<ZHyR<F+$A?B&/eQBj@Z4>>B^tW+Bp5@jH#/WDAc
Bh!mww u%WSG4jKtQ%Xl9>9keZ+$A?C#?IV>+RMCwH54#IT>V>FF8NDQ\k?>MQ6%whC>1ej=EDn<y?l^jnRD\LH
IK%d*D b>tKt*/RjipHB$QA@/hmm/ERjFdL8QM:wbB>j@%&B^Qw@^SenA@>IHk66HHVD:Ij@TDI9Tm5A<R+a4D$
Fw&K*k k?BDQ!k?c*VeGc%RKGSjLEQlB%IbnR$p^iBDQ!ki>N8:Z#lX*yh?!L$j#APwnQ^JQ^kKH@yB<cEjBDj>
$1V^ew wIn>XV=a<C5CG<TN^Ih?WH!MClne>IQ8T#<EBuKkKG:aV@4B+QnRD+4G^*cDt*=RZQSD@eA!Cka?WIn^
mjTN>K V@4B<Jyn\QCkH\!Be&pQlWH&W*q*XaL/u&KMajmwnI>%DdhFEA1D:cQ!:4CMQFmRMVdWEa*CS&X<DHP+
<Ncn81 DbFRGGIjqYG:cId>V%HGEH^W^wh?+H&Akh19q=EHY&H@GYcM\Ehq9M!BKN\1:$e@KAJ=wEF8d?#=GYiM
ZWPFZ# l:WIC5jHpwnd&k8FR@d9bin@FtmMD@*k?BklEdnyB<hFQ@RiqqF:$cEHmILFyln94hu^WBpQ?8&NlDlX
WtHELX S8BWGaNBkR?WbA#BJlqD<Ep!l5L^aB<W6$WhCpj6w#ETDV=RdDVm=/RIkp?cMSTPB@pk8P*+WDltH+*S
>B/C#l B=6k:M%Vj&kM^&hPlADna^HHnRwEbB<k:\ITebDjERk&$SmCV/I^FC>HPG/uBSRjS@lidkqPYjnjI:el
+Q4>P< j?\e>M@RdSVmn>B6%B?l&#Ap=F?l&>C@P5n@KEG%b\#:dim&QB$@je<RNRqhDPGle^\FlLAdHeT/HTA9
MX%YX4 #GE1^dbDqW<<SVqwmIqpwkbMWZFhR+4GMlq$b<Kp+#nJc1$SHB#W*A\C*BucIPc?9KD5l1CubC!WPVcH
5HLhYa TLl6ETG64ZLSQuM&jHF^mmq>!tMKRqjdKMAl>Ly$aq\$q6cE8R%A%GEcSj*HiY$LwJk8P//awBE9iD&:
qJ/XMV E:ApV#\VFCyLWy5a%E/kD=t9CmYn%*=NJlJNEWG9ZG5LB:LESbl8BGmDWC?XPEPS@6Kk+<8?=^PnMy<Y
$liTtR A+<k&8JA#>\c^Dp/>/K//SS1CDP9*qWYjI9mGFPeJq?*qDuYau#I<JZInXla*YP4\!+*QYWY:t4p&KRn
@DI8>? hJj$Y\u9Vk!=k&&ei&#D&/t?%wmT\Lk1^<amY6M<kSTH%DcAbM@XnIld4RkGJmK5k4R^Ml4G$pN6YhLq
KRd9un \NwSF69J8HcRHp*em:9AEW/bAT%KRPp4b&b=/4NiHIy^aGq\@ibKD^*=/Gu+WMTkSMS<e:?i+B&AtPBL
&/t&n4 *u6Ca&m&e9L?w^?c%QqNC+1F&hp&V+L$tL>Y^:<FA=HHC:Zl!5F!GJI4nI+4a#KiLciJ\k:hkAJJS9R$
pLtS=Q /el#!B/icHE4jAL4$Zu5#qJL@!GGSLc>yS8yp?^Li%!:4I=iNa#RYA>BqhQHQhdYT9!JFXtH$D>5wEM5
bn6F:< atnIbIypNZmZcpXukIm#MhJK4hNkBbTbdnQZb<XiiaHyJTJ+!$ZiB&AVJY@P#?%ciV!ZC!/X#j$MKLHl
8h^9YQ @Kk?R1DNM=SR?Xab@8LI!MVR?me+$E\tX5R4uDF8=mq1mGqljDKSiQJ$$j9F4<GYCHim\Lq*N:>d#NXJ
-AR/hX 0003fe7483400110333 Page 235 of binaries1.zip
EpY4td VwbcuV%KH@=<t9ha>D#VBp?+WWQZmT9Yb/ea+!*Q&w5q&LH!5me6aN#%461#8P9ELS4jQ=WAL!N?h*F/
DNE#cR mCel*#lc&+1>LIV:L59yG5y%#^yPX#9PEi$nq!tSY!L$uN%YBA?%\^m9bALdbqLjW!HiJNm!Y5yeeT91
YblwS1 tbc$$=$@Hjn+$wdB6<uchj@bM@WiF/bi*Nh194>?*XN9+?PD%+@>cV5>VGuJ:&=\PHA%uRpwaCe=<:tL
jt!?#= yG@+ikY>:y5uD$pH*$ni+S6/i\Mq%9d&!GGD<Zijd?6M9n%^=NJEi@yWC^BkiKI15/YIN\aY=ZRcQR!u
I$9p>E u6RG8yyp/yWw/uYS98k&Q4LG$9KCdAu#cXQ!Eihc58jT&LpnCT?S^4h/Zq/lSVqWAtu8Z>CW?Jkq@Yn1
K*cqK/ &=iF>eZclMwbB&&J4!T$Z@$m?Ba?W5Pi!:uReh^SPpZ$JLVcV?VhmQlD%^Y#=n\@>>blDJ<bTYaHw@it
Gbk1um TqMdm\#=$^aSkQ6LT1LIAMKRVEG%\TIQpXDl>DaKZ4PXhL>M%I*tmejGG18y/QL*I<GD&RwYBNueIiF$
R/MhhA #hy61XE8W\T<6eBEPhW*Q5?=PRtJjKkGm>jP1=N+q<4JMF4Ec85IW<6W*PuJM=IIJMq<\64K1>==:RZM
^EH^Vw Tuk$4edi689FC/EE>X9TT9XK^&#cYi$Gy8T4y:\wYGiaFRa?Qp9%hB*yyhN*:L<<u<8#<tcm%AJb?hH@
P<WEES BMqMN*ZV8uqWaXKG:*b+nmyyWQ>>bAXmqFY@6EK=u:/t&+tXM&eetEk@c/q<Kl#$a1DLX8@wTjXH!ej#
S+mQV6 diQ5*\w1DCBQIum=H!RPy:CJSy^QPp#WEt=91JGi&m9!WByEeacJM/JDQmQdXC$qYqV9lMDbGX:KI^un
1Rm?Zk tw:1ni?k9MJjLSuFZajVT/Sbjcc9/:&J/nqQL<j*nnR#&V^aI:%$hlD?%MJyXXYP#LalJE\u>w*yp=Dp
kd:&6H kH8H>i%#1+KZJByjMtcZ4Cu1^@u*A<Zay1u1WCpDRCYkmGnt1h886ab8&9aYem??MmZANZQ$G@N$HX%H
K54h=i 5!hqw!dP<<u#y&wqZBGMLR?#WVIl9yyMT*&GYHyeNN8MM/<WRCV/eL==PXW$N%EKpq><pbG##CPAk6j9
*C>d</ JFtJ<LL41b8RKl@F6#Jt1&V\Rq@FT=Qum&RhjhY9M+pZVVc#T1>PDFi@M^paae9VPj*X#MJ!=uB!>kjq
cDHJYK A5c&bI$n8YW:%/kjMtwc^$pnHlmY1LP%4=>HjL1Z5ZQQ+4bKX1DY+5XC@attXKHV5SWGRSF$c??wTdwC
Ql%#Vm B*9ALW+#V#KB=lhY#N/D@Pi*GaSYL1:dI/XncL1QeeVV!E^DI+WaZJ+Dn+apBJKJK/Mj</+!A#d95>S/
/KTNVD d%+c/DHR=Q%$qIk^+Qyk9/=<Tpac?=!M?>Zn>\N=Q%KBQ/e+k&&LYwb/\HX=5p+&bT9*mlPA=9%QawPd
BERK>+ mn^YuF41ap%t#y!yDk81w:c?c^Z*8B:TqVdM%qB/jlFm^>&Nj6=8<%+u5XyW95j+*8PFMM\S^^H?B:=B
%cp9l: tac<q=&HE#>DG\mAJKD?R=\K#hKch/lBjlXC6<5h/6>LQ*t/Le11uFlWaZ?BCe\!>9ubpa%B>>hk9V6>
=^JKuu lS6PdeMji<?i%G/:5TumT$JYPI!M!j*+:Cy6e@*Y>a\9ww?8K:#^TmkFYmVwWBc?9EZTM5J/6WRQ\+lY
G?FD%N eVh<Autma9tqXpQE@iQXJ&\ZjBK>t$mD6W!iL1*PjH:Y:B>+B#V?@EJiGe8Tc@%e1Fmuh46Q*btC+eaY
/<:T^Q VAVL4e@6\yR1NjQ$4Ye%Z^%Zb^9Zh9<pahdh?F#$&bMSj+$M/lQe!!SjVXXQYLN4d&/5j$8tpSt*iZ^*
tZdVeM PLj8%Xc\+ZjVJ$Lqn$Y9h4T*Lwp=Kqc:tJ>?N+N!<HCu:t^G<d!hd/:\jPd9%PlSD=9@+y@k61HTqaX+
Wi$EhG F+y/y8u?\cK\nni@d<^iI^@iN^d@TM5yKJP9*mYeI1iw1REcnACp/%K>1FD5*Y+@$9uK:^P%1ajX1?uJ
CeL$@\ 4q8J\+PuQ%wmKbl5:RBXVIR6BaYip!6<^C$QHa\Rh$m8?N$KHZ>#VVj@<\VRWWSN>EW?#LI?QQJ>#%db
ZD=E1M \Q8LJdjI?@\jpD/dQJY*iTYu@c!lb9qhw@N9*Nt:Qk\jt\?kVZ14?4u9HM#WiVVipwTk:ZCwmFKSX=H1
!4<:&! Dh?E*4VQbqi4b^#INnuQCk&F??kpSil>lbC>/tG%TDb<<E4R=ppF5X&XAVpDXY9QSH+lYWVq^8FlhN4a
6RGi5X ?5CK<%NDZ/>uVw>KWlutQCKjjTl:9*H^/9kH@iW=u>9Z*nVEQ*4Kjtjqt$XFa8Ct#j5HY9QjV:a?CIXQ
:Q>X9+ dHM=d$iL#<4^%lZcL#6/VXH/%Ze9QN5k8?NT&8SP=%85&^k&+iJ$XF<S@hGNh:k5ddn5%mZA/w^D@W!@
nPJblC *^Ab<&6S*ShZqEkKBSiX%SjYt^=ZGwb8&6:Zhq+aWl\Q5=d69i@\Ynhy4V#bl9jB8t/ZMlq1AFBB^h<S
R$$e6B >!E*Fw:1yG5hEH<@kG^#D&^*C+tl5nWZT*l?BiSG8mQd4w5cTaJ9Fq8CBq4X<5%Y/DyE\D%4KYb4Gh$J
BA8wCK c^/8wVT^/dT8h4S$4&pV6u5>Q*YNjKY4I8mCEL/5I1hLyPuXAZc*cC6!Pj8Z!Y+Q&bCJGjaVRTu/K:Xc
#PMcCC F1tDBtl=KJR45%6#NMewNJW<K<iwPFGl:1mSY>&Y*WAd4$dQPW8?J/mShtwc=mw?CZ4lt@S4\dS9TFnw
V6CNZ/ Z6PjAjYeTcXNDKjSwYcyw89YCYW:e=pPW5ctE<<KaYe>A#mnYeGkhQbB6BRMqP?8+#n#+mLV1pu*tepn
cYwCFj yAN*hjRwB4ld+\JSI*iP&BlSny/Hqd>qjXQ8jccI4w1Xnj+ICJLIe1cSba!EFWy/:E$nc&u!5hEeWFZN
pe%w<d eRb&V1>nwNE/WBK$/<^>4V:$Daw&S?%IkqiYMDH:^PWWbHuaT^GnR!X?NyFNa*GB$85lK@pL#>XTPDXA
a=anch AhT<k+QqF\c=iN!Z#4p?Re5Ln#JaY*1!ZNbK8&P4@yDTn<yqS6?nAnBm81B6@6Sh?MZaQTFNNRC$iyF/
KuRHd% WwnlAYpSKH\lW:InE#PQnCXMEk\4B%6jFem6B:>aXR?h4S9!I*MacXpATm?8M^P9QNV?qCNQw=YuiqPi
:ZLXiV a:l4JFYaVEa#GWyltb4HBJZYnw#q/B<4A9PqTT5\Z!t<%V4c6\41Kq6b%S#Kl8jQ!A/8jF5B!Mk=Q=1d
9j8&?i jm^dcJNuc^V8<+dH<R&JQ/4Gd=MR45lwZQK!=XViXhHplFPL&X!&m6^6*$\/Kp>D6/AJXLQP=nGc!$mK
eR>Fja na4m?enqLJ1w@FS8tpnF!t515!@DcQI&W1Iw4C%h1JG<I>Hi+<m1n<!9yLJj<XaL5BZXjKk8kSeZM%i6
Xt58#e ^pt:mEm4:FT>QMckF=XVJj!PNKn$DJ!EIEcCb$S#9MGM<Y:4=cX!%*BJ^^LJZqM#^4H!!/4uwm*p8>Cn
tw\1b1 aSqqH5/wum6?Kn:=jb@MB>4MXme8&/%E^nFJ<Z&Z<qG&>F=4LD/uYFke8HFHRnt@HPIbZY^iTE!tSeFj
C>ThtZ +$M6DVKVChK8nT&eYP&B\RX#p?9pmF\pmqWp6nYn8DVNW\I%JqTWje\4/F=1AD5%GZLNmn<XptWkTnuK
&4HTlJ XHYW8aW4myVNw<$9?&Tiw&$4A6KW\Aq1J8l%kKW%1e#ZdhS4I<=8X&k8ciuZ1jVJ6ikP<E@wF98iKF4%
G!*FVK $#ei:RJe68N*Ae1uSI?$Sp?p^BA$ENP1lE*E/t5TA^Q=KALNtMk1ZVtS6juFJj!%FJhqEI#ThZE/:!JQ
!!KPKm 1ndAtRSIi!!+QePYR4elPaL9Z9CdDDS!XJpEJCyHl5qBmuVlLWPQ\tcRC<J=*PKZ*L9+?a5ESPe%/q11
JW>hFk jKdDFR8X%ppwa?\9V*dBti:B?Q^NJ=<ESiX1=He$LeBZ=B\5Rd&YG/8c/ucMT:jk@GQ\hy>yR%:1h=@<
\Th6E< %C=dKD!#EFV6>yMP69:mb%>=l51/B/u9e%Z#nP\hNi:HDJhdTE4W8Wali5wP+9Qy*HQcbCtjZD%m%KPj
Tb<5:t !$W9uln9MGQ56cSdwituqF&EcGq&NiTVP5FHVV9jc*m9?Q6/ZdQ%Xc%n%VEI1Yde!tJK%Jq/wM6$YVW%
k1Rw*e KXHq&Kt65b#1KbZ=bbE&kFlI!1uP<u:wK4mn1b?LZe#l56n&>MY*ABTMa5MY\cDHcAtTy5leQqGneC^W
w^R%e4 W+dLWCbZ^C6WW>adkyDVk8iek:>HtR6%pV*py8bTkw&#dF\XM:#DHR%#kD9:*dWqM/#^id5:5/5JMd4t
@>MZpY =ujH1>=Y8DbW5p@bAtPZhpw9VXYhTuDPEnCii=ywWL#RWX&a/ASR:<RTIRW^Y&yt=59&kM9%bbK$ea+$
G4n<*W L^&XW%4D@J$wXJRm:T+cB54&Vc1H9\:wIuWtX*G^Y%u4/6j8quBNj8@1\tNeQ?l1\Fa%GZ@K@?Pyip5L
H@JbDE %@\d#M=%=CKM+Cn%1#:>t9=u^nLi^#E^^XZclDF5lLFhcbBAE6EN<m$$Y//RqJ*tGQPm6pjQPB&6Z*9!
RVlnHG 9I!V15!S!uKBF84Au!#cAM$iJD*N#*ZJhtZyT1Y*5P+D+RVLeD4@W>*?\b:B5qBXhVYL$#T?DpHFHXeG
*A%4EP ?Yml1X!Gq#e1R5QIbK=eDM&$C!kJYi@d:Hc9%VC8D8n*n\PkN#T9ZCuYhh>i8pa<aV=W9tJpy^!9eMYQ
RqE5uD +GZDnLMm+iY%\@SG:@\4BN>YwBK%JN<KRlKZdLhaRc<jecG/QSI>V64V!5?!*A:iPiQ^MEe54i^<mtVK
!Tn/n! E8pFSnAF^bm!e9+%yyZL@9jp>X/we+eHM6uLL?4Jp#!Yq=b^mu41%CqIne!5w6I^bu+ayAdSlZ&>NQ+y
?y9Zp# /%STDyH$A%@BuJ!E++TEPQJcwH<Q!@>@I/<F?9hwjn##YtBI&D@#YtBI/EH!Y1Daa6qRdQ+KFJ8@A5Zt
?H$YQ= 4<C\?T5\dQ+KDJ8?A5Pt4<C\/T9WMG#?Ck!d9\LD=1@A5N<Zl5%jkYHVX&Da>BWaNu&FGwdNZ+Fl<%hk
%$bmFa &Q\XGDb@BadNZ+Fl$%hk&QRXGLc:1YHa@BWaNu<Fl4XL\dD=K#B5@kwMkY&H#RCC@cweD$Nk@qb9?=e^
4<9$YZ /=<t5u@bQ/HaM@\&S\Z/:>!Jj<98p^5D@Zj8^L>q>$w$+JTF+CGL\8$\?Zj8BA=bJG:Q^d>#J*DI+w=V
/<%JHc l@+:h\KH:D/86H@uV8CR*TjT:6?=E@?Y*T@p:h?=E#lp>+p>R?KB1@&C\JB++G1@cC\WH4ncL!\KlRi8
:HN1%i >w6QR8GB1@$ClXB++G1@mB$WH4ncL*RGlRi8>w6lRiGB1@&CTXB++G1@1A+WH4ncL:\ClRi8>w6#RPPB
>h^^k! 1:%jK=!!iPAKl48+MSTNB/=k?@kA$ZnkCkdG*XhwQHC%u%McnRi8>9MPw@HA%Z=8YnRi8ILm*5EBm5aD
wFL65m X%DelX1lcD^\6Sjbmp5Yk\i8>4IXeM4mkT5I:n^QKAaQZEF\=*qCMZnkc4@<FmnPe6*@=%&RtQ*<+Ykp
ju$GIE +pD=Hkl5<kRTH%<6Bk<$:=NXA<Yk>9Zkw\<TC+cEa*MuEHn%E^+<RPK8e\@FaQc:6ZA$GH&kyBw+N1pG
y=qWGq n@A%GBmj1TV8A95\MGT@wAQWkRI:pNnwNTRWnI@G?E^CEXDeG8PKSeH5\RJ/wGK/CG#5/F+XhV\$^tj/
\PqGpX mn5>G+a#DiGH^u8V=aQW8<iYCpil<NEame?pGaNda^SPnjh1LINSB<1wkYP\Ji<l?KmM#=\b>=wIlnML
Q?pZQ6 +ajKKM\Bm>=n1@VD<alhk$H\tY:nZw4BeGalaH+EktEPNMIlINk/@XAMQm4nRV+E:lWkDALdS&WEBH$\
-A:?:A 0005ff8f12000110333 Page 236 of binaries1.zip
=dDhtw qdF:a?\hiKmMB@5R8BiiMAlm9%:GwA>WP^YPnX&D+:M>Bk!C#:wVmy6?ENT?Kl<5RlCP@Ep@PBwj?pH\
RD:^@4 wS<EN@$k?>IQDn=R>XR+hyMMPBIj?pHB?K\/ehMQC6qZ=X&hD=Tikm*Ln5<&GVAwQk6qNG:/Rjin*?:\
>t6Fan h!D/\cE@/dhZm^eQqjFba!N^$\?/L@$ki@Z!D/A!h1MMPARj?pH^Yb:DehMQm6wj!/kDljTn5jRD+$M@
AZHh9H KB:$k?MP>INB>/ej+pAb/DAWDF8\H^@/\jClH\R*@YD:@9yBwRjcRYZQ+95#QRWj?5H\wS<aN@%k5Q%:
u#<FGw ?WD^<Z6Y:y<q?@GlH\\Q?8*hL=\1:$e@BA^%wC!EQTL@4NtQD@%kTH!5SdnyB@5Q?1HSB<1w\Y/MAMYH
P=Yh*6 jnB<DG8+M&yk5Q*wB+Z94e+QpqGDyS<aH@4B<dHJ\ZDVD&eYAkT<8!4BHA#Li%d!u^p%?QR!HB>#H8+A
LaFGy= iSnPLIShqjh?T#Dkk/ZW@DRJRQHJcIQB<VEF+nc=\uCtIj#T?WBJ5FB5Tl5Wu=R&GB\jM!J8W!<Mb!LC
ncQTLR H#wnD=Tlk5at%iBnFaDna+JE:wMN#H+/:!=NIAjcPAQ<$!/\q@4<i=$SiFARm68$DWNA>6Mbk6u>&V=R
D@nuBc Yk$&kRKD^phuKD=tanB8ujjqIBm?&>EHK8GQNX@m5#WRDIEQB*H9DRSDIQ=Db>VBWt9k&NRcjDmIRPJn
8c%hmM &5dNRRV1Q*VGIA?WZINNaMKuylAML*e+:yyCMMT?HITA$RjKlaXkm\yB<Cp1BMQHqR:BZXRI>uhZ89aj
#nqhh= p9?SIjQHlkbmt484uu@9$R::1+9>n\!b9iI=@#e#bHycVNEebIBR?4RGD*aPSS5HLtHRINq^y8PEY?Al
IQXwn< AElR4XZ8nPiCLalFt=m^h#9KkaX>8B81$>IY1I>5+$hAmNuwSPKyAEVy4Xh!Se8w?WnQ!4l1G\BnFLqp
THM#/? bAb$pWBYN/:nQbtLVp*ZAEdNu4X&4uV$/%#5SXQL99B$<H9&t^!&@BKuP\E*#LYd>Hqp!YyA?k\ilmRK
$apY1j m:KHKtj%RIp1*KPNy4XM+8k&pGIm5RtEda\GpQmS/wwcH^&qd&XIR>BVm:mJ#9dnye\$FQqd::tPGAe=
w&alVq \^iy8cG>Q1Ae<JCGWILAAPjqp<ZuF8SpKpR:pB^ckND4VHKJ59HitMu#QY&8kpI68yYXA9%5jWCKtDSQ
HqQlL> INX^hYaIhaIiK$paydI>C\uS&RE/Mlh%bqTduPhKw%l4tncKSQn5!l*wY4>5jKq1N9ky!Ky@=ktk6XmZ
Gp<ZY> I=L5<S1JaDTqhGuE<iKtI8pY*RHB56baML!VdERd%6+1L:lERllKuKVGqcuL*k+6qSGkVuKFCEXp!h<D
A4!aPa !^>!FRAPC85@/XJyqi+CDyW$VRFyaS%k6G1NcSqcJuqdT:BKN$G/b/kp=c&pTKn!wNl\Cq!\D9A<T98\
d%=5ih hnAJSql9ZAGqR#L^VpJ4EIGR$S%J6c$!$pCI/Akb?l4wGi9:84tb/L<:wh^aFu!QmyWE+q#?>L+A^eSl
V!S@=? RN?M4CBbAn1@V+$lh=t@uCF55<FpQKAKMFRq9!^jjwmpX%!P5YtmZp9N>4Q+CEM1eb<ee$iB+IV?nhd#
w8WH!^ JHT^XR^c*klTabw%>tQPGuC/$RD6c<VD\ibCRhQ\@6cdeDy1H<RSK1$:b1V1ikchh8cV98><#R\dNVYM
^PXRbT J6LhDbIt#:u4JBq?NLP^JGEG44JPq*ap&pY$bmniMIH1Dkij%p%6Dl/EV4^lyDlEWEEK6XL@:9cWwa+E
cW^RIG <8TPFC4\%Vd#jVwLp>JKyM5HJqH&n5uby!qLy?\h$k\@^>qe5$>h5pqiVA>$8dhlT9Q/kejy<w?64!W8
!\Geec Bn+\lmQCdR:Jb8yZqPnCD@XJ^9DG<WJnDFb:VX4n:wW>h>Fulp:IlyJ1kE$mnaVIByI&/8XnQ4QCSpJ8
Ga^+6B Y$n:nFl&V%C5=WaD@Y<iht<tJ51X<a4%nI?eKW9\PPpX&?8knStlDGQ9$u!1RI:<MK4RJ@uSTw=/h5i4
kKI@S> l5t%$4NqCbG6#8LpNjuA:h##mYihtK?BV<#Dlp\1?Wty*l$tal#S#wS\IBjenkmHPed*9PuqJ^XiT6Y:
EqX5+> hWu4$!FyP/iBVB@^DDPlGT&T!huD^Eyp@hWjACNbZ@M5ySuqKHVP<%JjKLkVhup5?\L^IYFkjpLjWiYp
LND9q\ PhGT1Ad?bIKNG%5?wqpn+9Cp/dy4R5W/t!\NEbb>6&LQ&pXw?Z:IZ^k1TYm4%liPbaYe:YSJXLiKQSQd
8q>WN/ G14:m1Bjt^<Ayw9lI6yW+1y!+a8aa:6N&EKX?EbHtj:y<W\q+TBhVlZlXul4G%>?qub:qw\HPd!eL#d%
5#n/Pl GQ6m\G9Y:c1wT+jXQ441JjJ$Fy^TP##in4mWqQmy4>Q<8=%4@mY9alPlZ6QB^cd4X^u8//1lNkd6BuJT
L6Hu5i ^n1j1QZcChy>/hWjB=n%Z::!uVi5Je&d#Z4kbaqw*q4QJimW*TCthJ!*a@l/$mj*\ZPK*?jaYK/+T:MT
&PL$V5 #nu1DJFQPIyRP&KpLT@c!qkC\L+=wDSy!@/T\tlF!XbP@i4YaGtZ=LpkmebHP%uneRV1Auplci>E4bnW
VZq#AE 1/!*uV*X?Rh!n#WGZjK=@LDQBAWypl#K&X^N:He?yqK+#yMV9=Tp&!iDeqJ@ZkA@u#A?+/SY>BTcB?!w
^dTQnY $&%!$Xpqpe@dH4w/@8tt%4E6y!5WV6cc9W<q&RmHHJMjHhNK1nWm#MpRHm4tV8N<hI1^nCIKkQRE5KS^
&8uW6j *HnyT/Y11=FQjNemJnydW:wV#D?u#Z1L*nPyj:%Wjt\#Va<pXKSm$i6BM:9Xp%P?%RmGZ8Qq%#aV?nuX
lCaYKG 89YD@j&CW<J&%/=P?btc1FR=qW=t%!LLJ^=JtNtX&YZYXhi!bn5C<6NjJJCWkMc%tNJG+4pWElHlSGFG
#<Ae9C =piJ!N^Wc<YXuuVT*KFm#=FJPm6=LZ9uc%V!w*Ci1p%Re^%Vj$cG&tl1eWhC@&HHV6XWSpW:haFBtAQ%
5kYq4K /?8wc1@bpuYB%/+#N/+%jS=Ri*6SdQFDm>Eu6&ej<\L!*:%yidlpV@lwqECt%PiR+S5:LcFk\#FC+65$
dT?c&< %wHMqqjYdW6QRBI:MAAkq+=8uVM^^TH+NS@%D<h=Pi?TjGST9N+9>@wEXXcjE%CHaeJMl\SaFlS!R:<+
>u48eY NFwkZC9@HdJRV#\>cT5e&e51u4X\I#*FmXi94%H186&VG6*XI*wphGW>RLd1iHC4@YX/:ZdinPZ+FjYV
NJj&BQ uYhnD9N!QI?l9P#jhdtE*cb/Z4:RycI:M@9iAyX<1!QmMPBNSJb8<eZW4cp49Sm9ZN5!L5%1bH\@E=@K
AddQCl +6&T%K&hG*$bc6yPy6jV4HLmHZww@Ic&GpdAh>?%m^y\9bIWy+CbbDR@9:IM5H#4jb9l9Z>^FLnel65$
J\l/5> weYiC8yGM8@#/8#$jeFtLdjHKt4%*a>6t%LQ<lHM1bMH9y:ejF!n?*tD/qDDHaY*N!=EA6aH^>GXb8>c
Al%Q*q LmRV9nb4DjW<##Ky*G\+GT6!RyTB8JRyCpnMCE\VilyGWpY6!mQjRwaW=K<wtkM/^9RWqlT=ST?#1wwT
pLl*GB /HkFi#CPmkY$=lP?XnV</n4*mX:XIhM&Rk#DeE=XL$yRpPp$WX@&&cLRiCMYQeY#Jyd%j8euV>QE&Rw9
cPTS1T y1#W>?h:Nq%&5#\MDQJ:Fdn/ehG\LwXhM9Z5puKtNqNM81eqT>*D^wuK*Ki9ny^%eTHq6C8#nZuX4yH*
!RH@?j MIGIY@$!lbVj<=5Th\<u:XA%S^j=S#BSe44Pty$SN/aYK4u:%9F^%C#:pVjqI611W>a>@i@=4^$%ND<*
VdLT?F nH^1k@F?1&e#jF=Llq%!WH/:Pu:!E+<V&%iHuB&yp9GQ<cjhZ%!KJ$Y4FV>?8i#yWB9yjiTCcb%SJHh=
\WZldF IC4^?*EhWwut:4H!HuWp^ew%>6I1V4W*c4SMJGuY#/@Q\wa$WBmJ@ACD*qM$c$<j*!E&9@i\@49:+lPJ
A^%N+Q &#5YV%<&*4F+%&L^AlB+=>6:Y#CAmq854*!%Q*CPFQ^BBhAREc6t1#/5i6T1p<bekh<mjC&Ty$>daTck
L&ID+E w>lTkhmCl%<n>#CSB+hP\aJ8KaNPGQmC:a:FeFeR##Cl\qIRd+Q&\yKd:Nln@l/QbTyQBT?QAkb*Wly>
@Pa$5T B:I#&lG&m5@IiNjJEpL5P=H9dXiL!\\Hl5wH1Y%QFnjhGkJI#$W66!^SCT/yW&qCKGutFVci4%k9qB5@
ESuDmE Z/q>WhFKyXm=QDLkI*yWP\Kc&eh5&Z=$biNG*XBT*WbcnYnCT5JZ8m9^hDwp6JZjch@R%FAiw>ely#>D
j>eE5V VRjl1HXQycPub!m/YphLRWKZTWLyViESMMWdLh\TSXZbySp&WRq&4WkaWl&MLyM?SYe:S8Mi<H#WbDqw
uR4/u\ BV!p*1Z/mNpPKE>@*kB!X1S+?wXqpk6BqAkZRTb=MGMm1LbKnL:<Gy8RF65bAdc1LQa#Xa!RPwa*4P^C
KQ@H!4 Nt#>iw^9bBY/8WP:tJinH>F+VnLFMB$tpA/Ijpt61ZtDayVEept5jP%5PL>QqYqH=6KFIXu=$TLGM/$M
*Ej6a* ED:&MZ1/1n^GikS6amMu#VX/KB?D:nHRF5>^KI^DF*tyR+N^#4FN8@DWqew=pKX!tVM@tEY+Jap/u%Ph
6hRSNy P+?R5yM\n<^W@nAS9cX&==1tYm=b=1b&>%t=yTwm8&ZCJSa%k158G^MmCb+m5n5=qhhIHTnidX:^AL\W
l^u/En #JMV*I\l$:=I#6BMQ6bKZpD\%9wSBVG+VdkjcPpw5KWNwAM&8JNSTQjSDN?mhk9!IiJi1lnTw&d=4uH@
dFCi1C t!9N6>::*:&J9%jM#*yVjI>diD#+Em\!>I&S4FXnHj!YHjIYA9EYuu*>EFd^bFcp/^466!DlupqQ55t^
*h%dbB /R@Wd1JmWc+<AkDdKn+!=\A:cpDBMLG#8*bTSDn*n56Tu<8Yw\9Qt8ct8td=QJk8Vtm4mnTyny!lpX!*
KEHyWa *N$:HeQ:Yq#984B8AVt$S5k:XSnc6=$$yD%WAFRjP4Z%VFSk?$PpPXXtG+%$N+meN=%elA?/R>ZhS/Q:
6<de\h aWndG#V+dHe^>B%&A8yKBEuGuB!HRXQIV>aTZ/yqlPw^!VAm9?yVk&8?\+FM+HHPNNJ9KwM:TGWcju+G
NySVwj 8J^uAtECwH$%Rbu#JBu@TVh:/RK^R?=pbA=1S!Jn@cQZhMdQ$Pd:!Nml%iipjYXZ\jLkMlK+D4e/Nh?5
G9XREu :wc=yiNE:KJ?#G6L%i*415J8Kn&>15Cd14Zb5ZSSP%S8cn==clXkLyWJIXh8SX64j9$SpKXn9DWTE/I1
M$85ZJ +pTwRqmaWK%*THdA&bdbJ@e\RNNSP!XB6>9kYDFFhFCt/V9CMl+1$qe!4L&?Et>9pnHi$aYX/PwXCE$K
XwtmDb /aHVhd%4^Mj4TP5Rk1puBehV>eccJYB*$$lh4>m?IyBjji<%NWXH=>l%R!&XqwcZ&EbAA:XI4hZSAl=#
/Reb*V PGFH=caBHE$>d5CayX<uI9+8H9MPI+/+y8@h1I@I$/P:bJK1y=>cJb!1L=J/mwCH&yDc<H&hHWJ@!#uq
/GQQ^D I\q=BjJNHDy*&DA@T+jJY<j8nj/:#DNMjBJMN*ZjTbkk%mZ1Gp<dXFn/Kqm<8&QB1*wl>j+XBYwCA^8K
u#@GQ8 tkEVBSJC*VnieY9Xcy>#pG<8kG=#+ly#BYwn?YFiMIya##=eYIhRimb:K<im:w%F/t5>Z#ELk/?uEEZ/
knaGSR W&/Y1eXG>WD6Kicd*l1teh>NY*T$%NhS^P>6=jkEmJj$NimmI?mG\%15:Jl5J6%XDSnptFPICewAta?M
Z@ln6? Ciiw<<h$8</a%J9b/%%**cF$kHbdMep+GJ+=6ZQI4hjN\C@A&PMeRa*8IEmd#BQy5tp5EmGwy!*5A4k/
-A=p@j 0003d8496b900110333 Page 237 of binaries1.zip
?lXWF6 ucCy4&j45pTlquLy$NSJI&bb*SEDZpWiX^wyX:6k%u1ZW@ZL>9+u:N/q8:$VeGMi6QBZe1?:=:/b\^%@
58F<T^ pZ8%peih?NYE:a81tihX5!:$<$6^MTn6CT4I#4Kq#lH*RJuED^8LwqJuKnlndDnHMPjP6B?@Euq<C*LP
CI1pCC C@/!Y8!+F>iF\:jQ?=h^QY\<@9DBie&MXjL**H:HCN+cmM4V#LX#X*nQu@XiMq@5/?lip:hetBay<yVZ
mwQdFM %XQK9EHdiLc:E1w*N@M??NK4Wd8cI:L^4&Xll/T*TYZlS+J>n55Jt5q/C<nYCIYeQT/V^mNueFi=qPeI
*#LBFP d=#wFSu?!QM$k&YBVlBt11WLSmGj<yqFcW#%nGu6wpXC>StDQ:DC6F=K\+?FwEYkH!/EXD\Du\&X*Yc@
%apeh@ #CIRbZ#q/kTTT=$dbp&He>eW&N?D+9@j!C/B@V&YH5@5EnkT@e@5EnkThbD5Elk&m\RPBtPjwhluPQab
w9?Biq mZ*?iTW+BN5Pkt$H\SyP+NkPkGQXlEP^DcHalqD5CcHahqB5P^m&jApelt$I\#cEaS9C5A*l&BQC5i*k
5X+J$m &Hc@>1YE\:EN5RXS+Al5R/^6B+:hakcP*i5Tn5T&?=YQA$jC@=bh<55R>E@#$4<mkYFa\h>tieD?udtA
wS+yyM R*cj$KJ@b!:kpN$u^8jjtR5+bQeJ69q*=kIP&Z&mZ9/h8aBDhy@\p*>uL9^dF4FQHMm@M^h\!P+VpQH9
Y!J<VZ #AWe596ES9\:e\GH:D+lCmk<eIZaJ%aAlRi8EQ5+:XF++A1^n@eelRi8+Q8+5XF++A1?n#<bnRi8+Q5+
GB>@%/ h6F++A1?n+eXnRi8>8J\eM4mkT5+:l$naGk<eAXD:>NZiPAKl61u4@DAFR!?V%@lkc8>aC?e5unkcy?K
bD9h\* l#A$H4ncJ<5Dl5EDX@6pieA\iPAK85<am<EDX%DeGa5\DB/+&1e?HR!DB/:&1SRH\?CB1*%165E\iPB1
*Z&kZG u?JyMA\i8ILA>?p4QHC%Z=aHDQQ@nT<MDkd9:#hEHmkW=WCJHuA\HwDiJ>EDDwd8&%i:uRZ=Q=Z1ARjn
qRMS*T Rab>Wn*kaQl@>DMe?u<1%\MP^thCmV9ZA@/QnIC@^ZYkD?SVQqC&B^!M#&RWh:aH@B<yAZ@nEiJA\bl:
y:pkb@ JTq@d1GCF+@\tenCeA=&eMm?HITkEAjLWWFl6<yA+<NBCATj!Vh8DpKk@+WN>IG!XLB:bcD\+TAEH\:m
tIZ5Hd V6GER?D:/+\/WCwhAw:hLAPBD\el?E!?$dk=CEH8H/iERS+wV\YK*c\Gnk<HIjlM*FG+PRlB:#@YwR/+
?MS>EA n\w&=\1KD\eliHB\:+:l$lpK@w@j*+Q6TwLBelCMD\il?C^E+dk=CIZ?S#@DD=c1k6$\A+MQB/H+LGKl
Rp9y\X 8DpI@a@jRhTBK4Q9YXS?d1YCD\il?HARnJ8DWPS@/H!kddu&#Ek@p%Z\+TAWD\:CeY>yC+j?F\hSB$4>
min1eB kGG*4IHn\$EwQk69FG+P\9=nLwyCH/mjIhk>c/D+eBCG#/Ihmb8D5Q@m+IGKY8>N^Z@t1?DDRSk?C*++
bMlKiP dk:C@w8DGMTBEqc\&&dkp^MLl!H\MZDk=mD59#mIRS%wR^Z59lu+FGmH\@DlIP+FMB#&Z^#EHGl:Et!J
\8Hpie hlk?Jh4lMD\+CMP><IdD@+PDB!54D<MYcajlW/RhDwjka+VC#WE+Vk=CSDERPAy!IGlk6&&D+VZhkPNB
8t^L=S RSn8!l6\PE+KRu>8WAI>CDV&myd<CD@HJ<5WD5jHZ4eQBiHI@ZTGwNAHY5JC5Z5cRXF+RRMjY^>pH&mk
Z84^+H @$QuA$&jD=RCAwjna!jEuRICS+D@T&j$@/pWEDkCH^5n:lRRPAIuBYGm/N%qC9JAYT6aT\EWu%&N+Al<
5t>yJ/ #JP+VjX\BQ\@XD=RpD>&X!MwQ45c\SF+MBCKi%enPAK=4<y:qSpPpp8B*XaFu%&N+AkWQpbkDG/X$j84
S9?*#F DIMjKJZmb*IiBJ>hniAIjQmH&<aQS+L*X@qAK$EIhqenCD/:G5GSEH^M*mneKpQ@R?WDJZ>kh#YC+LP4
GW/a=\ ES!JB@$k8D$cePV?>D6akTEIhqenCD/:G5H^edBD>9uS@48DZj5Q!j@I@jlnS^R^#S@:&Q+#>\Q?X<j:
GLT6?y u:pj8%@q@><h=eC:w<CiJbJah:bVZMV8nkKM5A4TPhSTKcHK!y$quRtM$AbjAWcA+ejIcq@AhFu4e%KP
&RVX=w E^FV4VEI6S$1bTKPc?ett+q:eXiApXNt\BAI!FKuaya9R*6^KFFe$AVZd<=yR+pJje\HaXX\&Zq$m?=I
6?1tHa HdVEC*!n51SN8kX\9Ku<ipS4<epnPS/lkK/IEy9NLtnFb/kAXa/LPAeJ6dIJ!^Ah<M4nIi?kIYDE/Ijy
:Vyl^I wda5?Y<59ZLWyI\$eX!TI#Rch#?BS+<VQJemwXypB6La*PTVmkMTQ/iFE=E6RS9$:<ylItTTNR>4$^N:
AKZ<qp G&4/?q\$%wbRP^lPi1FqDLXVB!?aQYT1%VA^ND\Tc1=m1HDShly^<j4yKbEVN^&utd/tPn?/tqhk<9kM
\SFdqi TaZHR$PRNp8PJu6$Ln>Fk!8Lpw9qbenV9e%e!CB/F=p$*VdNH=E\&n=l9nPwFmClI=Qk+KR$enFdQF^p
CS6Ri^ 5%McNeH^?XB+tZE*BZ#i8E<!Y=>E#$K49q#P*Nb@MR^wTG&8qjKeGTtWaM<M5ElhtLyqeN$i\?8hMeN/
by?Iq% @<LNuFP#Dnj5M+=iTuSpFa&:=nBnu=\FPH8ml@*JtHM/ypktR<Xj*ah:$Aj/MC%ncLk5>*METW&wS?ah
TQ\4!y nY*Ta%1ME\IJNctqa1F699JHtB!=%MKq+#^#yTW<>c+5!%lqpM&MuW+D$Bw1Ve+c>W:8pHL%uJLMe?l>
8K4m<e !#R5^4FqYmE$6DZqIDbwHLA5M?b:W%Fu:P%VSQW+RFLMSV1T4blPpER>ich9+QZn#=W6l/TL^%wtST=E
L#!MJ4 8^>i&GFi^dkJTc5ajcN86@85qCPJeJ9atn&j^KER89BB&$:1>jH4Aj\YS/><yWeEWC*#KEu!Lc?h=*Kw
=VEceR C@$$jRJaMdCCP4Plaw^lKnl$Na#Md8nGaYp=%c<khdykh*6A1@HS:W^lBn5/5?!YHk/H#AuYWDw9m6c6
da\M\d L\*QKP5CX*y=STM1t^+//y56>#:L%\NNM?y%8Vt>?>bkH#K9>?wMTllBInp%S5H+YIcai6I/e&tL!pDQ
m?MKJ@ Q$Du!J$eEkJHDwwuT5QVLBtAkZpPmSnQ+q8HbCL%q=>KbH8:^$%&Va?#QZqeGnhpn^BQi<S&JKuEh<SE
6a+\E= WwLJK?>yE\CkCYTS!FqwM8tBu>keGAlH<I/aYkP5Z\/MKPmhwmj1D=h&bD9TEVc:HSJ!NKamYDyn@CK*
+b&VE4 nP^SVj5yjbWy$W\:8V:Et@XyNcQVS<\C@PNFI>BKnm<+Zt#j9VcWn%F/FC=1>/wm4ZwD$B@%EedqG8Sb
$!Dh61 VT*ha&\TKJMkCkkc1JQh1dY#6iS*6TN=Yek1RujhhXF/@JdYWE<<\!p!dXqH^A:cj*cPm<W\=9W18J?q
*//K^k K@QR\EncPNJ&SPW!tQeEIB%+NLmy$Rt/SE&S4ZM4YEtXW1SRukVPRA#WWCE=un@\?HyJpS<D9?*$hY+y
nnRM=Z %/%A#cH$J$?!>dhpa+?i9#Q%LVm:D=R!!5VIl1LWGJT$mFK@^e6&V6/SS>yNW/ZNy!>CT@9ay%nbmPA&
8SC\ZA NXJKuctWFN81?%aD^VC=jF>kNmIpbyVeVau@*bGERVNjnb&GN:JW$qG8AK&ItSm%^IHpFF?tp#pL*+J#
SSJQ$h ??1KNI@WIk6w#VpS+F8\wR^WF=?&RG>BeTHd^aj<uV#An8<GFMW%P9<Zhij=%XVc:tFKAlIVRAkmCBb/
a1Ww=m N\ubJFFKKFIqCSCKKAlTSI1ETBMayaTITqWaFIFBBARyWkhSXJ1wkDRyTyEmTClTFSZFPVQ9<J/%=nZ^
maW1CV lA?i5<+jeKe</@+q#>:Qhh$dF&A*M:t%$p1:$<L#@ptF^6@TVHp1u?JKFpT9/8YZQ$\@GBL5P^X/HmVT
FHe@49 a9V!u9941c4E&EBCm8GYlB*JMD^IXK*$%YejXdYAnB5j#uc?tn/uj/4+iJXci>^#DAR/i#TGDp?n$EmL
SJMdRA a#=bCqbq8:Kj>YitK+bq=muw%mJuI<#VXbNeq/n:5Ge?nh>cmWQ*/<&&6jHyK^TFFGpEq68HX9tZP9Ve
Zk=*/? V<#8e@nTmEpdq1jVTW>1leZVdK@1Y>*?aKde%*el<$!l#>8I?YM!!ceT#YeB>/RWCSW!DeaS$y\Cqp:4
^WL^N9 a$APY+ycY&mu:RYVH!J6NMD<+L#ItL5Z+uK%@BVTpPyBptLyEZhc%WJXHVS=j^*/*cGt?ym1T&^NbKGc
5#yZ6^ i^58+=4$qKjulFkl#?WhHiaFNeFyQbiCtm*8nFYj=>jL@tylSaHd=ynHFnjPG\/ILI:dl@J!TV<NE^li
&cSEbR pDjKY&<$QWjd:9cq1d4^$nG9CcP>l:y9>Z?:WIqRPEjN^i?$9bwNZ%T+5n>A+41\q668!d8A4/K\=/hd
h!J9ES 5TQ$wyRRB<jyI/QytRNj?%NeJc+##MCXR=I$^GW8>?FdqW:c@XGDitDhB&Wkq:+PwLqESQpX#@yKiu<P
PJDKMi :4Xw6@*46L*qJ^!6/<>Zm1jiL6I$AMFdR8\tBCky^W*qFc8@DZyhm@BS</n9N?Ib$N^6TF*q8/FySF9T
EQ\MtP F6Q*ehlNPyB:?tpaEm8cGiGBKecTGduC+@HjMqj:XKW<5*$HaNPF+8$Yk\NVQl>4M%/$<D\cpY8Xu&u/
mEbM1< NWM#Ee:VT+kTI%huj#*G:d!#:PVhwEQbtyd9uu\<GbRMAc4tQ<KmaPQ>Rhi8Pb5qtScp!H*5tjtFLJue
<d=5Fm *WMuTASekq15ib=Yn9KQAqJ>D9@!:ly%?MFI19BBt<IIL#YS#Nbc*9ML5/GN\hcXqb4ElKXh/k&j4T5t
:Z%9%^ \y+pH</$%@q<%Ymm>qnaa1cn*CiS?+^c#%hibuE4a!EtWPjM^a=e=Ln^c^<q=b+WI&D=%1A9be\4Xdj4
6K#:6l hF=hN4?Qnhd/%j!1qqw9iySkmTW8A>n?hQqd\AP4lejwL<9NR#6Z*CQmPA8HhcIDht*4Dc/i11m/$XBq
H8@cbc *y6SIHFlRnLw#qk6jmqW4Iy5/tY*ttFHqnXF%:Y+9wZeJuHMt>MY8I&Zw9Qj?=LiC^^cFnC%Y:BeKbZu
#Q<IH1 EwA9ImTPCK15LGl^J?KQCmJBFB%8!pH8BTIIwdTRA:$wMQTt$Pqd^<^1DBZ!VCYF<LTb&:P$wIhpTKkB
c@MaAn RW5>+6>/NH?c!R8FZI%JPE6TFt!B&FWdcqwV<1eJ&>eJi/ddbi/%ThSjKy<^Sd^S/mElHD%dt+dd$P1K
RMEPG& #V%QIKZ8WX58IX^H<>bPdPW4FwNNWQtWcFjiEtE!eQ!#$h/LH@p>atCI=bmyqpLajEFlq/DlpJHccRm$
qwk*aT bF%FeL!$e1##:k^EZtnTbn&^/eM#wR:C9ec<i>@iwQlGGR><G:yh>+QAlqD*LyE>E@mVl9#l!!CPbwKF
CDQFN\ yRcnmPAKj?qKu1!d5G\KC?*\V@cnAH:?L/I<!R!CjXHLT%?\tF8%PHG9tF6\Y+GSYMeB<aS6P?Q@EP>M
p!^&&Z &GuSbJQ$RCJST/La*4c4VNK9YtJyYMK9Wb#^nej%$EXiclwn!:S5GVi8wZ?luPiNNpKcS@F+G4klW$q&
@Q6d$J XJ6BeZTKuH5VqnV%FX*m=DT=/FP*CPKI#KLlP?W+BWF&+c1L8ut:yW6C!DRF\6c?Eyw+RV<5>HtI@m\F
A:T4PP <!RV<>ld4/6dn?4h<9VipV@*C?c*1WLB4=bDFa#N=ISm1N&SA?X^<yMeD4=&$jH:Qce4>1mkWZ+GP6J!
QaN$Z$ Yk#1FqtF8aqDTjNH8:\JF*%CyWbyq8j*PA6yJB9!G*QV>Lu6R:nQ1MbFd<8%XntScaKQNZ/uL6PEAAq%
-Aj%$G 000732dddd100110333 Page 238 of binaries1.zip
?bh&YY \A!k@PH#cB1T$<Wd^P%9y6^nIl$M+utCDG?AP8H=*luQ^cT18MaaZB4X+*e!iL#E>#np+GP!T+Emb@RY
PGCFt8 AyhyLX?J1R8H=w8ni=\<%LlPlW$<=AW%cE8@SZLq/B#/SJ@:Tu>K:auTkluN><CwMJuFEBXLjXWZZmF6
^cW6TZ N$awp4nYchTIAlu<ahVR1/:$<EXM&FVP!!iLQRblB8H&TcT%LyVCMhwE+Hw$lD95qS9lW5+c#jL1IEN8
/VlCjV =h%>:i/a1LkKHYPF1JYQP5@4B5\d<ibX8tn?\cTbMPY/+Y&c6V/9hW:X4y++P!i:B5%1l8aypGVt:GWq
aX>bF+ 4n^=/L4T^tMl*9V<?EHC&hCJw$:nM6A8%/:JdHIW!VJbH$qe=#nb:KE8n/1+wC=+p*QSkw8p8WIpLjZR
=#MPn8 q@*nX*^NnC9VF<q^aHIT%/IbtGL\+dnyLGH@5P<+V<8\W4:u1n<C+lX<bh::>W#b6wNeI>&I6?*6BMlc
lV#Mt4 j&F*!SK9aM:wtuw:+Ih1ILaKFXyAEy+L?ZaSi*uG19mELYT?W5wZVLG%aC/ib:Dh$5>*8@TARD5WWS#I
\EFM&D FZ>EbM&iSu:6T5Y>ytN:/!!paQJ15?ipekTpS5>LE/5qXR!h*1FAHJZX$^1M*E@t:W?lBRac8h<A9&ky
84C?HH /9EuNHGm$Ep=kYY\EEY*Ld^R1pC?P$L*bDC?P<G/6%BP/J^>RNbCidyMibbJla5G/I/Gqai$d+P<kVJG
c^>bi% 6qP#F+>KtFFZ^!H#+:<aE9n&+A<&:h#Gy&N8uQcFJ1u6&>VAu\4y9Qh<*#ML>G1Y6+CFlTKEe5eyAP^E
ehKMRN 1mdGD6#Q=dbwkl&bCy!NRp$e^F/bQ@R\JjqlZhdHZK+9?IH!JZjD$%t@#*bQ8WKuT9<\F+^uGMe\\kiJ
5V+\#A *PaYIu^d?$Kh+1<:hXa+?@@l9C49NIN8wEHdA>X!BEa:wKlX6MIlFW*Hjb/P>F$q$e5nR9andlR>F@!e
+d\+&K S>w^aSpZDkaW/i%p:Thh$wGM6LGTW>D\mCEK:*ChJ869:*G?jEVKbl\#ViSRNXD95uTnZ=^Y>n>ltPl?
Bt=?lB /D1Fj5FQXJL!N9lpQ&VqI@TC:Y=19>Sk@*dZjnZZcpRIV\=QelW$dtCX9>=#NNL=9W%*y!B@M5W!pZiH
=MH99M BwMAJ+jCXI=NnLy?hB@bEu^q&dC:N%mKJEkPjBc$L*BBu*al%?kM^=Rl^48$YR@tn8GRhpTZYaFJJ1cy
^Y5NI* XTd?$cH?N$JV!<^ED?1y4Pm=mK9cYull9DF>:#Ea^?SS@LHXd@^?NKiJ%iT*CBD+uilN&:N9k9tDnm:a
1d\X$q :9i\%VkbBFDy9@ubdcMGm+WHCj9SE@!1>=+Y%Rt@1^wSLPu*CSayKl8F&i5Qd8bJ&VQ4jy@HH<G*=bEY
8YA65B ++ctR5#46$V#Ja=Hic@+LLbZCQ1nQ#tXEE6J?Bh8E>T%R8<9^G!nqmC*@Ijtudu$PXM$^<D1#B**\tEB
yY:\qj W$+QnRRQ:!jHNiKE?lTp=diiyMGkL9E+KYaQG$H@p=:@*>BB$Q?E:6uWRRDWh#wIkN1WDwLGd8kk8A$*
yQJ&I$ A4jlWG\<lATN&*AweH?@E:ClnRAd&km\wa*AkA%9BNn\SwANd\Va<EcADY<E&FkwaPQ4AB9cCA#a<EaA
%P5Vm? %D?qnH@jwjtQ?#:jm\b@L!EdWkd/i>GATT%#KRQ>9YnAyJc=qIH?ZnSkW55eGEb@L^w\1YW8bcC@F\&a
JuK5db %CJb4JZG@%#LR5yAj!<cMKuF5qk4LB8%Gm#YC5hGLZMyA+%qw/>aTBqwLB6>^WLKRGQb/C5YWkac!$bj
SwDw5^ 5bA!$Fk&?w1FqIHG56FZLKRMNJcN9pKnYK\XG*&Fb5Eya>uwK%bAPB1L?#?=Q+::\iEHF9QVeHAeG?*M
iF#HW4 CkjH5V:<\G!Ku6$eDa=n=^iYBR&Pa**+khuW<LuN\iA+hu/eYeDkPNbun%k$>1i^+Dk&<5iKBei^Qu9E
^S\55F dPyWdHMwPI/N9\RYKDmAaB$@DID/YTR+kGBuq<KeBAeRQ+mjB9JukiAAky*+MRjBAeRQ+4e=yuw#HDmA
FTH*&E ANnbw&Cbj&VY<eN5Vt9aDAaPINnbXnHH\AHED?KH\j$5Cl^A5LMna$/BA<kj^A?4<dMkeADJ#tcPPRRP
\jR!=H IH<RQ^#!b#HkAJKN?LFk\AHpD?KHR@<5BB^A5lM@=kk+kQ#B9>?t=1X9mkAHpP#5QypV+AAT?+PQnQqb
EMm\bC ADmAbCN?LAB\AMW/j6lN#V:iFQ<NwJD5ZJe\n^>#B\Q>%%l5>W%6$@@Tk@?i@e@PK1Qa8R^nVyEB#BWM
lK$D!: RE$DaJ?nS1wn@9Z+&Z@S58\<ZklA5ZMB^!J>1Q<Ad@=h?RQ\=4<H4j+F*t^M@@nuc#IBd%B@#eH+j#%$
D^$\W^ >iyLb&@$iAjZ=YqT!lcy6kmT!RM:EhGWLV!Nb\=FHyT=anlJ:TR#*t!JEDja=6HpbaAXN=yA+XVT<c1>
qZ!y&* DbB^:wC#GC6SKL*WD16$@hqkdIAWb@/LSHSm1&^ubG\nkC:B*$JeqQqYMJpE+/t>L9nTV%Pe*>8cH+Bw
yTVDNX 6d!%uyZtK:P5BT69=Ww9K:1B#/<=#+q9kNhLC:+CISPN<bX$=*ATJ4cik%=bL^&&B<N@/jJZ5Yl8m1Wa
^k\JCA tD6:1KX<dp&:VCttpSJBu:@m9bPu\Jk1Ii&dBd?6wLK!Kq=+?=QVpp1+bb8Mjt9+jM%n\i9JeKRbiZ>%
9mDPn5 mjLMN:mydn=JAiEeR/w*8MLXm\S^&:Yk+1ET55K6nXpVmFm96JhAc&u6EB#ctXPDBR8F4MNlRw%TXZw9
:YuD?L mqV%TwTNY#T#>TGHD^CZ4<+l/6@nLjVymA4+Zh:qJ4qH1lEW!^&6>YB#e!LkeMC$6hhj%ca$IMPedJd!
pm1558 \M4BFml&k66a4$hbp#<MZ*L5*::HZ1\+Bi@Wkt1=euac&VXApVL8Ndm$8?+!!WKP9H!cX/GVP<6!b+i8
^>heY< >+nm<&4Lh%dFme5AjGnP:hn?anP*N4Huw6=C>+9>l#pPpBe4SeNiy:+Sw^GqHdhGn$1*:/1&Ztu:+8<p
Xw*/#S Gw8F\<w$:#=&>I=X9YmBDh86&NkjcA^H>Ke61L@8Vb?4A@ii<4E!DbR:uY=:yww#diy#d%^Gy+nNL+y9
#plTc< c!bD5$<+^?<TH^6L8dGh4p9^8DukVQF^%:SyP5hyuQCl+qSS\+P6!44/PT5E9Sj9Ww?NY<8<9+9w<XG*
V$Fbje jXdw$TIweKAXX1p&B^1+T<GKAGbNcMwK/b*ID6eGP?5QF%#:$#QmdE=<VXY*whc?T*A:Zn8mu*QcRS:Z
Ai^uS$ 5VJ$!<#8R!C9dM@Lai6Wh@1N#L#C/u$liqXi>yN*9Pj&4WW1tTkncDZY:\Xh+LwBb>Y961biH49Wi8&w
Id6NaZ ?buQyd>L&ndbRXiT/%Xm<#V</t>!b1&LG$duVn$!h:uP8Gjdj@PZQ6/^9F<i&e:tjNPbD?\cCX$PJ#b#
t/jp$V /LlHea\$%IVjYRa>At^?HcDi<aR<GJS/uLP\9YA9JC/+A8^8j=VdyX>NaP>Y%PL^1=qQFcBt$idq@4Zm
i1Qhek 6mlGtEtI$QaZQJ>:yZInPn=@jjn^I@@IX=*\^cXXjD=6Le6AK:^nS5dAYJJ4uF9@kntZHH=HBpe&#TVt
nSkCZe >8$6N##pwmMc1#uN4R6VumI1IKGP^q:iSVp$mPBk1/SDc?YPP/6Ypub9h1KWSuF$e8E8V8/wQ=PNi&Ik
BpEyVX hFQ$#Nuwdi<FiiCHnp19#by%m\XhA<jZ:$^$>qQmBBV^!@t9:SWCIS@c>y<\uJW<eD8F+Gl%d>yMThc#
aVpMeb MjtW9cYb/BGXDIPcRDME@M<ekeNJbLC^mLyiwN&9i+>+/M/M@e+XDW<XJ9>&6F$L4Gk<Eip1/Mb9yYEW
c<@%h& Gh/iPepFyHRQ&Lb48CttXN+LSJYjd8Wd^KZHFtSR?+KKMAi%HMJtDk8ZB:edK15M9b@MjJF>69&c4jbW
+S$9SF L9mGbVihJHbt*<%68qHkW#DD:L4j4\5NBejA=dXpGje+Pj!m+>aZT/^uad4ei&mWIdni%A&wa/V%bbPq
4WKy\F pHIq?/^h$>=8%QAHSRwXI1M!Sle:NbV$GdjZ5*8I=#@I1bCXpplTMKPIJFQX8k>yL%+G+:JX*aw9a@/L
>a<S#A 9j<Mm&Jd8+XlRujVRHhL#mI=l/anIGCVM#SSwyJ#VmIte5/TFTZuuESEJW9PImAkPc5pFjP:ZH86>i!%
%kB^n/ \dN>uu&?>@*Phb$jhhFh>Jl#%1!:1tdhaa!dL@wu&q%<ZN&BNl%61b&mYZHQH@QVcM#TjDLD9cGk1T$c
dHhu/@ bW1Vm4>LSqn@LQ#R=DdNDR+qtCh?^l6Z?Dn1un::1HaMyjZGq$<%W*LQnJuP&G!<T/$*SARcqTQ6lbLL
wDyP<D e>eq^bTWclt*n=k9/F@C$BGu#BDm>MVKkJ=D85?=S9P+4Qyi!#>BKik5NV/+8F9AtKimpeZASCNGWER%
\DPZBR =V5+!@!%8/q@/WCb#TcKhj6TT&@!5yuV<J!l11MMuQ<d@b48?5#Rb88d#P<N1cpB:4a:1jTN?dnQc+LX
uimt*Z aahQQ5\iZNdh8Qu&!@/V>LV>ly%RcC#VJeeJk1hwb/%G95LLeV=&tJip$SpFewtb8ZEcEu!jGHb5A!6J
XM/=kX i:R:YnbNKcqM6bI=<MTb<\=Cn+t:6<j:4Wp@^kq>E<?bGB+$d9YN1\Tlu*&EDV<T<ya?AEtu=<!WcyB^
JE<4N% Nb=>X%aBhJ6t<^&L%8H!Mmh>IBmBie+Vp8eD>aM$Yt&btZ5YPSl8a>H>G1Q4l>iKllH=cLqu9HiRhiZD
i&hWm8 X?@=d:Ri%TE:Dw&Nn%96=/HbS/Cw$aB#+k+XL@NRq^#HMkiW:dPF!H%+Mpa@ZhB!>NyY1uMc!$DCcuRm
/dMi\! \5L8*YA6wul?HW::Q1P$kiQPwK6WnS<^h1H##BT<NuYCRJd5^b*FKijlbHqHW\*?G6j\queBHYtT$jV9
jXJ1Ri i?\W!##%nhL^&+X1bVyKbh*kCB$B&M9TlHeQFWh%ktq9=mw?qK/$bCpMZcC61AnL+Jn!=kp4wLpm!#=C
4$n&eW pa:1Mm8??WtlLNy=$B>ZZSZAqiDwV%i<@y&Xe>MLRDmp\5FKupu+8KYQnyuV?k&&=$AE8*JEHY<>cC8F
^S5VnY PMjYkDuHicAq#!@MkC4*!/%1Be?pY6w?!!y:9M$:Sc6=8=\&VHLAqK:j4C9%ttDS=J5Ph6jKmje4S!?9
uV+ybh *ZKbZCmth8Jb&Dq:$YQT6hak+M&LZRQ6GkQY^*wjmBZtKm:+5L9b\uqw*K>?=d\8%tI=8tVDD<&ieIV#
@dekny KHW?Q<eaPZ?=?uZX!CV&uN&8?/8!h>Zpi9#jHcN9Kqj=X%Q1$!/59<:Jj:DNt*anpqENW?CT*/mL8>+j
$4Jmh% e%q<nYD%dq&b6@cM>wY%DM:\:6WwLw=p@c&w=wpyu<41c6&6X/AQHLem48Za6*$pXX@=wy&yK<Qd<@Ry
?Ad=FQ DiQ%X?qHV!:*jdyF9uqJF^WYPayhh>Xu=J\YJ!NTj/ERhXE\Ha/*YTZ$@4V\@ZY*>5c:C$?QQ4=/?idL
VaBpQ\ 8b49:kZj*i>>Fu%IEP:^Wj9Ly?yQBy$5/RXP5jIIh1LVA1Bw^Q@4AXA$+u<WAEYmVkSAj/@C@HeB$N<n
qP/>ub m*<5Rj>qaZ6TD?5ja@8XCAH/bNu1j\iM?Q8T?p@w@&JJ@Xj??w<qNj1WJjW@%/V?8cV?\jL$j%Qb@<NW
?q8<:Z >p/%J!mmRF%GECH8S\K:BlTA?mPB@R\kFLJyD+niE*imkdJ4aF=Cp1mh5QF:NnJSJGJ\QFMaZMZ+DG1y
WWqe+/ %=P^>LX+^<8PIF\9BitaHt1+e&<kewXRT++mMQC$m@L9JeL@4%!Wj/<PQ8&mSKNQ8Ty@4/j/?%Z=q>:G
e!XdT> L/WqwNFmj$<C?MP$$Ynp1bj5mYDmQ$d?>+D?/i?^J+8JV&LFVk@+wp@Knb*T:?p5dimVBeGuaH@mZ#!y
-AbG/V 000e29ce7f600110333 Page 239 of binaries1.zip
Y4Pj&Z GZaTm#/hER6>51n*JBd%E%j5TiG9W:A@eVCi4M\>=ZlQ%+lHu^V9Pwu>/X*%bHu6j\j<C=cFQb*DD+*C
qD!FQX @kjaZ:A5%Pp!YtmW^Q<em+d@B>lVyLA$WTITIpmpGFbeSN:B$8P*J+/I1y8Qq:8N4:Ynt:$IZlp9a8j8
TjY*Dh JaK*>jJ&h:N$EeF:PjybYq@>XbjZn%L8H=SaQ%ISjqDe@H8ZF@yju:FI>N?j5V<E\NG@*bh?JA@><a#>
N\kd*G $%Z%?#MYijIb?@iK%%Qc@P8=@aiIwiF@Qc6@6CtPQcXN%CuQdVnmF%^l\E=Lkk+!EWcwEkh^$q$tMua/
^%&HA9 ANGBlBch9WRp8DDTj>FLlAWM/lVLCZVAJMTGWyT\\AjPIPYZ9MX6^GppEtI6RyJ!t4$BVBCd&9&:FG8m
tlM@\E RA$4wIy@c!!TR1+@Jdj%p\Ew^EAbpb5#LINN%RJ&EucXqLlGVLHXG@p*AiAMMAYk@NtmHul!Kt#9aD1u
w+4mT\ nJ>8NI^EVGWcd>5GmiAITTPtM&P$<RkiT^#F5*E8k5V41*nyHBH&NehJna6+@//%PI+jZnJNV4M!@a4K
D1ti:n KtknT:#APH9FpS$meidN^EAKiSVJT1h4$*:p\wa9<LIcnViGBt>J5#^+6bL%\TY!a1kVXqL@8mh*+>YC
eLeA$E %4HIFq<PB1nFhYce\HQR&w&1QjZCQV\jWkl5>d$^#59tjVY$Ll<kdhpQPC!RnbqhqIqS9$<81uJNlCa/
86>jTA SJj%uc\PMaa^dIB+<TNw6Q!IRj46J5$DIbjw>ee6:QKG:jBIDW\@wnNRq:qqTX&wJ^#Q5EuVbpt\5B$B
SSqQqt cV:p\qqjV/SBXyk!$hYN/$eS^l/EBk>A^*H&#EnbRL\$WAV\lAcY>EkIP<ki&>PLRKyDPqTF%WqR+bW5
JmS\8k kYL>FVaVlEMVN9hJET5=C>m+bHpl>MCpWMJbAQXpBw$cu1Xy+Np+wBw::4%DicGG?1\<A1=HV5RIyHyN
/#k^94 !c&FQK5$$GiypWYl8k6=^1?5D:$AjVVkaBM1/PbNFIy$y!nlEBt#VhpWZk4PljVp8@wQ\K\LBj1jW#QM
eGi^D1 6mqZNSRmXY/nEyARbJ!^/kAu^N6FDALj8lJG?F#RwyWI^dXj=ykM!A89E6m\W*^nI<4W/FL\&RCE*B#m
aZ8k5w S!VZw\qj9nMLmS!Kue^CLWQ\P9BZb/DHld!=dW/MD*9S/Zdl=MleBlEa^PFJ&QPGK&=k@>A%YVnC=Vyh
$Wh$Y1 L<$RP5=1KY=IbWPQac=9\=JkhF^FmPJ%ulkVpGyI\<WqeBiPSM4%+=PqKiPhGd+>#AeTY<!ali5T!N:9
X&kpFB lY!c!9T?t^DBPLLLQ&DVlSRETYqnP+p?18RPhF99NStC%+*jtFtX&9q$Q%jaYww#>u>baaEdLhb9i?XX
I1<FKw a\te1D8MliP&i!qdu!q6ZP<YbHZZ$^!qGdTt8VX+eL%:a<\4+K9:1Dh^:ICA*d\BkFFn*8jhwPp*uM+=
BAAFuc ?KRLWENV1QHMc56eJ!pTRIQHTS\$Ym!ej&@<!EAMiFbR1hM!FX5??I/q6\e?j*h\me5k9SWCJA5!!Iw^
Sk!IAu 9818yI=@WqJ\@QHi6Rh/qw>LY>j5QymXYh>M<CN8iC>WMTtyClF\I/p@#HIa?lkLLXMnnqC$&&D&CnlQ
4a+<$G Y9I/iLLHd%#kJ6#GX1/eby1=HRD%e+VKqZh>t56\81ad:a8P+NbTMml:AE6WamRmedt6D@aP4<+%npB=
YJ&tBM *VeQtI9i#ltR5*ed$wl88?Z?Lw*PuwPGT5+P^\hDaeKcQ5:8!5XRXJy&Fp#6RP1CIGLTDTYdYcYVb9:!
^4qdYW #y=9ba+#KqbyFC/TZ6XwqchuZqT:b*bG=!!G#=d<5qjKnZ$SkjNZulI?#\w<L*yYVuq^C/VS/tP>:tkw
I:b5!k F$ZC\1!A$h<iEuqkm!YqaCqJy8T=GB!q\&q\hQ8Y<p$ES&NB?$\k&p:=a:bAJ>N6?jNtaydN1KJAE/9%
DNM%%G &+^YR$p^wNXN!H%=nX8mn/6d6?1tW&%tjFVb\#JTQnETE4%T4VR+*>@%9n8?T#a6y:hVY?H>YyA<&5Q4
E*/YPM mFQnPcB!8n#:Q4I^VH&FY6VTPX6QwC+$\?/tbXG@yWb:$T$6Nn\=N\PdP@YMqEC@XQL>Nn:J!5GB:Ia:
A&VnEu 5mG?k6yFkX&QR:ACt!/dBlC#:9C&<ZpHk15bNnJY>WT>:XP^hleGDb1!pESVY=ZmPkBdcYti$Yh/LIbm
Y$*kuC @QEynA4Q%Pb&6bBKnA>yX$Ah66GF>+5eu&dCdVJt!w:biuRaR8RPqkeiimpP6wjuI:>RYt91m4qG^dWX
=tk#AD <Vk5LFybkbm/k<Qat1npHtl4!5RK+QGV<\:<%/I&^WD+@k^#=G1Aw*u6w&8ptPLZPadllP@QP6VV8$V!
5Le6^L BW@PIj4&VI&yXjkk5mYI:H4A9Dp/V4KW/*pBGXXtTHCeCtHcT5a%A\>1Dq!n11>RVTihFbP+tGyVqILS
pa:?9n BJNFmLt<VF6Rq%Ac/Q8eM%DIa5^YktJ>uV*aDqtKpyC!**/*Ti4hJB4&L9QKe9N<#QAV6#Du<XJyZn:m
Y$%kh$ ut6iWJpBQYDkAuLdh%yk!KT^?dPHhcbXihlt*\R$@P*Pde*1*L/!nahMEBNCk+\<@YyqSTDhc6ANk1AD
!\dlZc 1b*Z6%k^DKcP:<\!lMkD^%8NeQYW*#tcCXa!ZhYWc5RP!6G*BM41:BJ^\e!C<M&#T+hTPq6Z*@dVk9d=
&*HF%h YB/pnG?=qDaT<#D$Q$/^bSW6Tn>pkyCtIhGQmi!ySZL%&6PlD<?L>pb?VZBc?XA9*MLBb@caQM?q>W4G
W%nliW pLS6YqEci@IhCIKej%W!K5p\L5CEh9$yy^/9!RV/TRJtjX^NQ<l^QMB++pm!%:\ed@uGqT$TIj9TaCP!
CA+l14 =ZWpY*PF@WZua4h:6I@!jWbcEXul\w:9SG4<LhQY%Lja1>++iD\c#=w/i?%?w?*C<$db%K\hFIEFqRM?
q!l9J+ tdDVynVqV9=4Ab^*A1@BAu?$>=qXRmWJ9mjq+m+Mp*MqpSpJ=?ThbBp<C#V\D@N+MJ?lBanB6IHS:9u?
L%8:hD qXy/Y:%m8@:9R4WtD+NyW?/FpAaIFE4m+%Pi^NkHEKul?\tJl!9ap*IHtG\@&^*uZKAd@1#DFZFXZ<t!
&BPIBa ^6*W^Qmda=#EyVt:dNGY6<+94%EKDCI9\=Za#@4pC%jWWhhAtm!NVew9X%P=%w6h!:w&5tB!6J5@8Vq@
NK6#%V YWjML>Y=$j^ieDb##e8L/W/QSQ4P5HhM#EiM&!YQcP*PY#>?9bD*kKmRj?im$1$bZ58HuP@mY5/K!a#S
Yjdq1/ Ja\%Ac^/E:/t&<R$n1dK&Yu\CEjMj+/%aF4+w6G@V%n#VIP^>TDD14KqY:YQNi:Le?5lQpkZP46haL&#
b!*b<1 +qy<dQhS\i%cnT9%wbB>uw@%%Y>mY*^Aq1&TyTkTtww#V+=9F9T>ILjKJm!Y1uKG6BKHlF!m6B#iyK@i
R%YD#n q#lHhFl=6#CTd*YkdM*I*qRPt@%b9$9\mwVWVI%*PQZ=n/cqT6?K=d\KFl/\9dqY/D>6d@ENMKk5MLZZ
PN?u@8 *S^ZAEJ!DeaB>\Vq1wR>lAAE>5VYe*^EXAwF?4cKPSM=iATBE/lLZL:Dna6+XNlGq6nKt:l#>pLI6pTC
QeTAiV \GP=9aWREb<NGXY\4l>BXcGwSbqY<k&Tu9i4Z11<pAJaD%dabqw$>lMPS#wA&?ML#qHYmCPG+Lk?p?Q>
JFSaKF /l!X#qQRDi^$qT:*kFb86wd!6QaaKqwHblI6eCZAVdh1XMqNqBZ8DeiYmJG=ZW@EBBGZBZWq\ZIeHuH%
nLAW?6 IE85^G1?u\tl$\d$FBCyBJH$:9DB$I:Hj9B9WNIy:%1cFRG*:SW=/#GG?=8Z@BJectyF@MaASj6!Tc99
K=65wy 1Edj>K16Cq9SZiDEAH8$RB%kY?$&4>FFIZiS\EA<&But8FZ#J4D@HWe?caVGS%!!*Wm5Y:XL!D1dl4$E
6tK*^1 ^R41QQ:/wcmHRhp$a8<^iTkaQ6TmYq*#YaHtAmeS=:+ZY@Ttdhq8/&:5a^+L*kR^^nYKt@^$bd5CdY=X
Slu/>? aa=elSFtX#k4Caydu@D+Q+5lCkC:*hlqWdH9l!Aau5d5u%5hd%FYlZYKDEBA9ppX::eXdyDE/wJG4!yd
Qjwi<H 5yEXnA4CY%a1ikXFKi\S*8RKMWAu%$EK4^&#tE/ID\V*VEBZJ#G&1=<qdt!$6SnK1ykuKw^SDD:\+tp?
P$*Mp& Lmm/S>!$+\!D>uQw!^NwF>%$m?1w&YJ#Dj&pJ\dd&bCE<p\tk<y!\^+K8HZyEG^D?\QjJ>jlXXt9l>AF
AWJ<&u h#<WGl>Q#>q&DAND&+aB$Ch8dVqV!k<y?:MF!a^c=i=i64bnZ^GpJ*Bl>@T*VilcWDA!5ieA5<$BCG/L
myctC9 EDQXS8$/d>/E8B+:<P>1<B+E>klD/npB!@S<#&l84SXJEu$CP#<^mF@Z>T4b:DdD1^He=:pPJVmw+u$Q
VJS<IY #55kqD9XQj6*9y4@umeI#acW?FiupKnTn*#pQ?R!@u5iw4@V*@#nyi**j9@yui*H*l>bV%1Y44d@/P8*
^4^t@/ 5Vq/ij9<>p4w^janl$VD<w<9CQTQXL?Lnna?D4?4qTCS@?*6B^*Tn=#NQ#jwQ*@=:&+@GKckQ%4>==*m
aTMPML +lJ5&N>/?X9Q+n?!cDG@A*+j^Y>@EV<T#u=%BL<Dj66?NQLu>tM@FwXqk&J@9D#?Nt<aDQd*unF@uK<j
hATmST ?@>=JD@?@&P@BA4%?@+@j\9>@eMj@@!^+@h@@kd?@ae@G9@6j#?&*^9=4ie@@@+a\a@Q9:Pn@iCY?WEE
d:J:Q= @j9P*+:*u&j/^?ej&+@jIj:w?WhuQ::@Qke@\D>A9&@Ij/Su@u=<Q/nS@&np^+@@hRS@#k9$>\@@%KMa
t&u&D& @J>t:<i9@:EDnjunC$L<L?^@6jHHKQ>%<u?H@6ZGu$QEaCV?/:V<NntuG5PQ:b>u/5j=?9M*j^:Hu@6?
+\EH>* FCXAj>@=+<h@AQ/emD<6=/@>Q!aH@X@du=Q%8#H</!cB?wh^@G+p@:V>/<Z^+:SA@:TMj>%?nP#W@Z<$
pe^%>u @Pey?we^@M8GRa4@dl^@uiM@6n?u@J<NBQ1ubb^wBQ/H^j!ap*@i@tt!j>#bFN&5*Y$e*i#b$BITj=L=
GY<Q8? !Fq/&@=?=^HFY:ya?nm/8R84?qm/PF4@eThW5QY&>uL$<HH*?k$qDn@F=aI>*hu6@h5*hWidH@inQ+9Y
!n6ip+ @uB/a>H@8JZ?bt#@8HiKIj+RKSL:S$HQd^?\1H@ePBF\?B?8I\RC?a<^I@/59nQ@*XZ8?!QG>eNC@9T6
/ep!1d I:B@TCH>jbnm@*caj#1k$H?MD@*HJGH?8Iqn@kk5aj=wH@QH1DHaj\\S<$j%H^RLS=<a+D@:@p>#ZEu<
I<IE9? n$IG+lIuRkdm+4<c!Q9Dkja944/Vp8J@#5e@?X<Sy@5!V^J@ueTKuX/ilMak@n$Y<=PW<yQ5ZchkV/jC
@V#h!@ RtNR9+D>Tj:lTR18p%n$V:##J#Y8V5GK@RTL@jha%M@/Fj@*&B?l#qP^E4?A@WutI@aZ:Ay^i9pLG95L
HJeYN+ h9XD6?BWLPI@\Q/CZTHSy$id5Klj\b=?n4C@aFhI=E?\tQ<A?\6&laCjdl6a<j<A?\6&>hNkp@k9GBaG
?l<G#u e*4H+4>!\$KidyVm9*LDRy=8HPK@aFk@myhQ^j/Kab$8#IWY@^ZDEn9>bmiP?bWL?QRL/i?%y@m@pQ?4
\#M:<B HI$@a$cmY4<>kXEuH=u@ZJQ/X/#ul$4M@:FJGla>^IVbNe>?=GbR%cw$YGFyGMM+^YSDheYa!CBZ#by#
/APDL% ?9qFWpu^\eIb6IDGbhtLte*46:H*ykCWH^<H$44X#jSPV>M&Wjw>jAFkmitc^WnelyDRI+4A6Q%FL1Ye
+yW=&a lHEqyRqA<t9YRwV+6+p$4FCPyMSXuS&/n!B=q:Sde<w$u/QQYiICB:H%qwF+mR6B^AKMdZKQypej8#9k
-A@Bd4 00004685d5100110333 Page 240 of binaries1.zip
#wt%/* 5bBEMB+d9@6bLwwEu8k$DmT$wj5Y\h+qhZAlH#^QCkpm!CaHE8Znu+84/$W@AQFVy#I>LB<Zb!yw4@GI
\j158% c/qkTm5K/\@IC=YT>dBkFK9/p9m/#>q/GInkpBhkpZM=^y<QJe=ZJeRS^u\Tc+QW&JLE^^+KnVb+WG\S
#85P9b c%w1GH=CHjw<Fc:L4iAqAqc$VXGAEe%+mZn4c<4m:SY:4RM+id+N?pbZj/hEPPXnu49Q?J6hGQuF!BVb
btkGyu YpXbA9hWSXaLn5DY=RKjaNaF@b?kNa9>EkCcc<LTYnZMF/SlR%^H:<LlNLMV8nAKy<dtwY!?ntw/W=H!
b9ptDw Cc%FM<biYH%Nq+CBaME#Mi%5dRHF?5G/+@wkkqe!IN$8Vyuy&Hw^H*WKqIw+K9&cwE@HFTN:MRPDS+4E
m%FZub aVSttdILH+R8IBc>%@1^5b1eY$HI&\dmH+d*#\8LAikL=<&BFi5W\?a8*b<aS9VFdRa%*+cFpDVeypaN
pRKZA1 !GS<IVF/I6VDjX:DYL<>iC&n>j!%J?pyM>j1GhPEGAb%n:499QyaST\T^?k/P>=6eKp+^V/^jEZI:EN4
:ZY\Hq DdwlA/tuWl4dEQ%tinpu5l5pW1n!?6pb=Bl8#aiLkFFD@:!aBW+i<4kX%b5aWY1k>>#p9ad<VahBR=jQ
9!/<Kw a8IKh=q^\&F\G9B+\#F!idTDZ%BDHCL%yDa?nMW<eqnl4T?>%>5=?e@ZGnkY<bYhT<<EcMmD%QaTX^+*
G^a^E6 1DBYBY!c?8@wQqPM64%l1mpT>!upeG$/B%>CK/adt+*9M%^a<:D>GN>BA\&^GSmSi@VKQWdGEneTCKA&
Sm6ZMb 9AliyY@6J9KMLSe#>Z:XKZ+&+D!jVZL$\Z%Zh+98$5P&FFmiHwK9M4/IW/8uM>@pM1R9nCm<#jd8PBhi
HbNmka RC^aSBE$tIqeD+q9PwM:XK9MaBACEHIVb+dHL<l/j?WDt4eTy$$RnIe+Bt:^JXeieqD4u:@6+VL#ti*h
a?T^tC XN^qwum6dit?6DdhF>TQVG^mGpaj?kC?WXCBZG#a6=w/a&CDS6mI6l#GpETZc=Dqb?C&kp<TQy8MXyL&
aG=!RQ dy8pYcL$ZQbunN>wS#TQJSY*HR=JtRbw+*eiy\RSBiH$FEcpu#a<eAP#JPXC\&<<Ki/15W@maPWVih#d
:\#tZ^ !IiBcqn\ldi%u$p6GPI@?*p5yw/t8&qqqNa!By:E9<BRGBkC5cF$WFK5biL*FVBu=BnAlLw\WRW91&mR
Ww>WY+ !eFLcV49eK5>8Qe\TZHeBSGP!d8YWZ5pR#I1F5:I$@?<:K6M#PkH5iLHQBM41kHe8hd=CKG/aS$GQZLy
?\\TX9 5<R+J#P/kn:JHjl4?Y/q&?N+SBB9H8mCaa*iSJ5\T6m*DRNK*Jtd=uPLNBjt?$TSwWuXlpJaC1EKI:?P
SyRQ9X n:Lqc%DGMycKpGtCZh&&6yKc4cj9*R*KLim#C^XWW%a8caV:EiRPn#yhyZSp#QeA?a>G1Cp^n=&@h#W\
+DZJb& PFi$?*w:u%!XwRnBSLWV#T*=P=Y=NLETE@BPQTPwemtQF<PwAF5Wlj:N51wu5t4%HJNt:^TAlLPNp<@M
y&1pM4 qRTbChZ%+%9L<8hNbpm@\qI:yDl/M!$T8iX4WA9y4hF$ciXDapAIYwnp6p\Q5aNq:8Ac*eZ$F/A#t?:X
&!=CIu @X66^kLi%lqR*%LRVempKhPpH94elSL?yRtFI=cm#*e>u><huey5!N=/ZRikG^M!jMRZbVWPV*R*JMd$
Vt!*aM >qTdP1iWHYl<Ey$m+cGkl8J$NRdM>GY5lK*%Rm4yPM1KN@!6IDAHJX6E6XP1H?MPhXT+FV@QFcb9X5I:
4@EBaG PqiT@C/Z^JCtj::u^L>%^Md=Am6K=yT5W%hl?tmRnDnR+*GF%&bD<dtkLY+&<\\bdyFic&1<\RLm&SEm
eeCS\I #$@h*!QDN=9@*4H^y>KA#tH?l\JKByZqh\S=RmP6TP$GWd$mG:uIlBwH%qj6A#C\WGPPuZ=n9Inl=ZPb
Lb<md< +<SlIE>55:@WaMcE99^HGi?c>Nu86L!RaKQI<Zc#aw9M%J&BYM@4NlS+Fw*TN*&bLjR9T1T9MF=TLXY=
#Vm%D+ WYS*@ca>$neI\NlG6!F\@$/>6BL8TBR8$Ij/=K$HM:5caKCm6AR4IaCL:5ebeIh6*1A*=:X=Z\!m=Qq8
WI>G+R 9V\IiVRwVXa4!SBa?#EZV^@&mH&9y+al96kw8p/=SA<6P$S8w1$X?y=9nmF!896<$lZF+RatQ:9$YYP9
uGQP8G pcbeIW:6cp1PlBmBl&WQa^pBy1$Gb91TR8&Q<lWVY<Ku1>pnM^?4N1HVWq%9j!QC<#&:=G^$leNW?Hm6
6&!4>S nNNpy>i/qn>/AQ>85%?Rh1uA$Gie=$a8T@KwX=t41KKE=L=pB$w/8/h%hbBw@Wq9?!WAbhy%ah*EB:\9
m&?CF< Z\Iy8kSAldF%=D+H/Y9IVA1+Y\N+Gkt1@uKkZbAd>#LWYuH!A5GqSJ*AGc8u1Ck4tVe9m$NEnjSk#e1p
!>Z+Xw !!%H#!HnZN86GC$tF884Aa$:bCR4eytCW!!TVhS!EkQ=q6cj\$Y#8F5!dD&dQ!>Y8$bchy+hAS4L4DP/
W&XkTu H?^8uT$t5X46Hyem#hlm<P&^Fu>aiK>jW\1pMFaaa!qH4V<NHbZ/BH1&q@q1Nhkqb@y&CIHdde9Ptb=D
Qm@4#c 6aEQiy>u^SRWY$m#W$XKCbeD^Qp9$qey*tiwhu6dY8T%:tp1juRl&a#I$pcSib:JajH\mIHj^8A6!Mjm
wwplSN ^X#u<PYQn/8yjLN5\!W^DF%QMX?jHY/!+w<$Z!?aK!$$M>L5pdkhT:8P<B:d#PSYaBi8=>tQw69!dEH+
u$cuSM e1cyXcN!Sa>Qcmw%cqMX=Ba6AkeqA8IJt%uFF85Nd4APCwyCG=D:6p<iL?!R#K:IQcPZk1IGHN&\w%Fd
juKi9N BwiYdXjHN^h=wJcX#h#:+?6kNBDB?AbXl4+#J9upT6y^!=ZXdPenu$^\m5R/jL1:4a6Z*NSa*IdF9HER
TBbV6K DWAXT&45?V<1e<By/A<L%EAZB>%ZAe:!e>QSp=%9a@M+*&84<qR9h5DeCb\E6L4e>1yZbmC41yA#Z6aP
4*4GuH B&Zk8tKQ>\14NSe&=*\KAiWcpNLNhj8mWky44i:IbTC=pANdF/RYkF#hqI/=TkXl$MmZk%Y#QHRAk/B\
kQ8&j! M>KYT!Zj#GPcb$ZqHmy@!YF#pK4YQS?*1b@npLk!GlcVD>CIAMV9NumIQ+6RJ^m\GXZZ14Sa9XnE$!@R
mtc>5h X8pT*!\kB4CV$6\Bi+ZIM$Jni*YK1m1QB*XmjV8+Fw8y%NYXtel6Ah*VCl+XGnFMD15n>N6Q/hjL#KNj
h^MuMk $K<*=L1Bky<>yX:9D\<jFW/!5pp+q4KPVkJ6HmeCFBLBXeI?5?9kGJ+9b9*JV+b#!Wey%A58EFaTIF&V
Sw+e1n <+S9F5ZTije>5Z:tBu96aS8Vh<P^4hmLA\mX>Cqm8qp!P&@FSX4KN/84wjFcDqqF>6JyWYPH!6/nIY4n
?!=#nm PW<h@ELJqK*Z#juwt$$=ud#Yu:qj?%pIt$!QmekpZ/ViMuRnNVMneLpXtTntKTMSpmIS$mK\%uR?#\eW
PeGl8Z WtI!nPiQ%<iLtGT9\i>^*!Zl*^Q^GnZ^ttKHGRIS!<LL!!6=tWLBB:EhINFFe&HXI!CXw?kdb=E\8F:\
t4u>yJ b@m!n#@5ipS!p^1qm^ty%W!ZTyL%uHjlkGC?nDyXY\CmT/TiCACI=cLtF$P<Z?PDtc:5mQW6m5R:<d>X
\QbwR> +jR/SHVLm6b>S!NJ$Fd*PGHZSJG$&EPt6i=WEY<Qa?5N4JWm66:KXEjJXBepVYyqaaG:aHj>S1eaRTRV
19ZeqW W6SEBywH<SL/$MNuH8/kEKtB+9h+1P1#VpVB8bWwwjhc$p4K^M$L6MaDI8+*/jW@$ET+k*51^Vy=?*k<
*tw+J1 ALyN5Vt?dd%:NGiyX455T:*E9Vh%=ZAkK!p?1Ilp$4e%5kXH6jQp+ckncnWk\YXFqPF8#q9FZSq%k4t*
KF!:?J P5KmXj*+HhbewLZeqy<^6:8<n!RjS\4I#jhed?5cMSiWLBF%<C$:BTq&iE<Q?J=#?ibq1!ZJw5Xa=TaE
ML<#V6 4+&kleeXZ4<4uiJZmkNZcAKEJ\/MW<aS!#L*PYiQ\tRpP#uAlXdJc+HTjd^!K=Hy\Xc/c<Femtw&KVly
:YRc#@ YM?q%iELNm^pu9B6F&=?dny%kpD=^C!b\GEa1hXYPE\?=a1M*IR</maJ#dh\K^?^RI@#9TT11HVSmR^l
FIc16= t9jG@CH/\Ah+Vym4Qqt59a*V=GNa5RiRy%KD#eT*#a/Eyn>S*8RuSSB@b@9=*^JqR:Kl@!Bc??>F&j:P
qpaj?Z AQS4WVdp9@YV/#8/&uwL/:1:Y44>T*hm@^MjLpaM</<?ZI\a?lh>8H??GQ@L/@bJuiR@jhu@:Ie>*W>*
CdGpCH pk#wJQbu@6?VP5pu5V?lq$PjbQR=Bj5V6<bJuiSV5GI@\YL@QjauXG*wp#4Jy&C^Q<FK@AIYjTwYA+j@
$^^DN> Ald=E/#aL&BQ>+hm+L>kX/nV1ip\<F?\K^V1J@*?kq&lED@B@wJhIW?uieQAj<G8pJmjaH@B4lA@/@eZ
jS=JcD :Ay^Pw$DB9+LhwXAuZ/P^H:B4u:tl<YI@aJl@aV+DCQ&K+d%p\MY?^ZDPy&pC9N*@ld<Z<n@qX@!#:##
HI^Rei H*:JW*SRMQ>M#9Jj6YNI5j@D/Sl/59mp#F/H*>aTFVAZwMwFGCeKpGLLmjIPektt*jpVXR1THic1VMm!
^6bVjF YT\yPFYClSumHJYJXd/EK*QjnkT&dM1c+h!1i:c6qlKu!EtAiqj9=MdZ+NBMZn*JnDa6FDwb>ucy9VV4
>Qq+<b qA4*u$6V5Zen=DA5&1CRP:V!6?WT9K????V4%$>DS1lm\!DT4tLFXMYJAlJBPBq$GePF4PFDlKw=Vuhc
QJ698G l/l?b%*\C\y@W?:FDC4y8FeTyJaZQF4PHm\uIDmt%ubREck:KIAdnX^wCF@C+eSF66l$#wdXd4+tB5uK
9GMSek C#TTEM4V6MVtAkBN5KSFQAwIX<nuD!MG##%5m@G\bw*jbWqG>LJu9SSWW#@GT>ZY5WBb+/8p/yyn//=j
J&5&Iu F\>DFpC=lbeWYB4qPI%teAu5kMjuS&RJBwCcuWmBb4^qLKh1FiILyWB94mK5?R!:DcSN4b/qGm/ChJ4t
c/8FS4 lZ6NkGn$/:tGJQV1XjDwju^Y\bJp:t%T<8lk#8P=H4KY85eX:5elPyZ=h@*YS#ZKZwn$N\Y95R:1:G$=
I&k<LE n?JyPIYEhVYi5y8wY@VA&*Sh##n&1^>MT>RMqC#JlNHj9YdjVy^cDnC9>>m+MXCnj!hI?RZLe#jVYAQJ
i6ji$Z B!d$4%<S!qLPeYBiBkH:chR@kHYCL=QZ9HR*!ZnCHa8dMKASA!IeZ9qQERKY%LZ\<WcQ\mwI>M\J=ZIM
Kbk#SZ LF64w&5b\>>48L4qG?VNJIVX8Y=\^VjNBVj4GA%yhIMRYtd6c*kn9PS/VIt5QYT1klRSXq:TYX#F:4N^
uYh%4P DwEH9JZ9J\b9<A%R8a+&A1qp?u6APt@PGnqjBG4$X#ZdpD:h!?RBaX<#Kd&8^bMdeqa/td+jjcnKCcM6
^hLPq# G#wC+<S$96lAt4&bdiiH1/k+bmVZh@5y5+$GCC\6qAVS\?*QG1VQ#<5S+u!uP1LJ96TI91$Ma:#R^Eh:
T66NE* 9:S*8yTyatAm1?F^:T/^a:^l\DaCQp=#%pH6\V4!pi!BFn@L$aV9KPQeyaL5SAB^*X1G!Q9kiaCJ!TCq
cdNuy: =>8Z:5hVM*^<$I4e+R5wD9Pb#y14aJd9WwEYt9i8jk@AQh<tXpmtiGupDm$jdGc\!Y1cJH@u5b9L&5HX
A9$Pl4 $n!8V1bcXpbhELE\Jp9kc4^YS<9R5bk:$>pBWk^<ujel@yA\bFmJG\S8EPh=S%nubP#KuW\$cthKHS!1
BGwGRW QDV*VGdQJJlB^<eLjpP<wEt@^!4AHC?!Z!+CGy!m+L<yA8EHaHA&bl^=t6#Snii+FG<\YRjIZHJV/XH8
-Am8?H 0009dce74e800110333 Page 241 of binaries1.zip
jFC#kF eTl<=ZPNd#9:eV4jX^d>\#im6ZMWjPme?Aq>C?FaY#=qSaFF<kQK^N/#9Nm>4dPJMSinlnZSDFcVYbpF
%R1aNG X=MKl@4/MwC51/6FKtyi=@5cD@bwZ*d!6+&6uP6+RK#ncBbb4jC+ZTub4^&uDZikEPeJ!&DRZ@JAqL\V
KBBH1! VTeaITjj#kEKTT$%k<5aVZBmH68yQMXEM$mV/CCu?LPeBS!4Rb!jKDXWMa:qep6wI+Ek?EmYdZAp&E!Z
iPi=YZ @E!R$B9kIIqN#EIkZ?VlYhc!Qm$#A*=jq>6SJ8yZ^bptt6u!SH\BYtF$CTaF8htF6S>@8!hq^M4#=%Wp
Rc+^hR 5bd^bbJD!wq^Py1EZItLLGeuFI8EKREkm1:eeWi9CF/!5!HkAC%Y1jckckSIR=JY#KJMM\VT#1H6T+#T
FPL$\$ 5ALey:YkMDDE*N>R!*E@6HMZQ+Le6lY:y8qy<LTYd>XmDVIe4R?/^ta\@hLw$$V&XyZdqNKd4BBJHY<:
eWWLyE #RB6>DabumNC8jE469k&!ELk/LnCN>564ZT^uynQ>n:N\&1D:e%ZuXA5yD#9@Ak6IbwGdH@H6jd8Yd\n
ncBZuW qV1qW!uXJ:AC!1/GV<WS&5@Zm8tca/dm9J8%=RqW>Eql=pLm!RN#Gy+?w1lpYT=$Gyy4CY?dIiie<Wna
KW6LyN YcBZVAGj^j8aYT8?G#aQu9DL:lRLE<nd$!%QV1km1t>&Wq1j8@d1KyYKGSC^6Dc:a%EN@8kVVQG6WH?d
KRuViR Dkb4+\M*XZp<I\>keu5<YZQw6%8/PF:w+Z&6SXXk5W4Rj&H<E?DS%HEV6qD#&pCL=qMGV?PZn>J9GKbi
9n=yGl dy=$wleBXkSq9ch>hEYY1!+t#p6Wm1lR\#m&EyB\lYHWyc9*@iiPSh^bV@PY4CXeP%*iNA$lpF1=8X6L
5c4tiI w16tcT?N9VG?iaSw=#L%H8BSiw&pJZK=Z5>Ba@F?dunAhMp:^*IjR=M4na:Q\^S=ta@6SnCb!w^$KAdu
kZyJY% \a*l>4Sl+a4k6LQ5%LX:SP@G%KZNPGqmZS8YApn\\?V&FehQL?+%&nq@L=Z6IY4!bC4S<MtmGXB#!m!S
DZ%nAp eB#Sy&Yn*E:%iJheISE6?hIFhc<8%d>5K:A@pe:&W4c48:qAXt$B4hch16TAY=8Q:n&dcX?SB&\S=>d9
+@=T:+ +h14FqB&1$q9GIJn^tSbJSRJ%qtY!*^a4Y@phD9tVC:ibbVQ6?tnTHqa:qM\Jkj&dw$9TkYl$1&tb1lk
SLJVtG RRPTSMudQX/#l8ydtPi8mdFlI@!T<4$i8b+N8MnIGiW=9t##XAXn%&%na%Dc+9hRG$kR=Z\/#8Gnw!1D
+k5bwA YZDXBkIZ^>cpCZk+yJh1$niX^L1!ykqbBJ#VLGGViH\EZ5!R&9c=\cNRyWI$YWEm?tBRmaaw$NVT:SdP
lw^dnD yCFy^E><Rl6QV^q6jmZH>/YBImGJ8Jb15+SQ5<pG+:WIk+^:=SE*E+ewFBuiRHA$Ck@EP?u>*dj/Chqq
Qnh#YT Gm*MamImB>%JCARZ9YwE%JD&hb<DS4MV^?T9*ZHMGt$t$jn&/nGZqV8$R/F^>>I4YXqNEQ$&HVHeD5cp
X54<$< S1TJt>9FXAqhJi&bt?P:Z8a/icH=I^nN&da/ih@G6tXp?A*1jA?:?pc&uN#bT>AKuhlQywaKKYd#P4qb
4b##Qc k#X=m@&eW6elQ6a^ukuBmp$Hb%@&JTRTuZH^qd$#QH@?%8$RaPVR5$n?dc4e\a^L+RR8\hM?Kt@&XPZ&
Bl?T1M ?qd*\8=i&!I\5S%XC&8&DD68+N/<%EYYX4lFyM&\WY+aC1#bC/<1C@%tb#WPy<Db8DiblpM<THc#8WI6
V:5T8Q qd:IKp?LJbIXACy5TZ4NitRJA@HARJ#*64=6PIEuMBME^>qbeaN+qC+K>RaytMnWEH#9CSWcCJaV8m+e
ZCHjAl PA%qG*dd/dInGLjTe9HbhXDBN!t*HWJ66y641CcI*nkQ?LkY51%V4MK6F1*jVpB5ScHPX/CXeK*!Zn6N
%QQ5XH 1@8nl4$1^%B8NW&q!j/8/&TR\PdS4p1*9B=QAY@:ywRNqTeFZbw/=NDEibnNhh%TE#8Kn=T1+wpDh?YE
wpIIuc HlF8FyIy<JPF&9H9XatN%1uuhNucq1Z\#PI+F95LKBpkd&=$*=Qn^hlyPmnudAIwp\%Du#M/EMmCpkm1
ebXT*V ZERK^VY%45i9Fb+B*:WJd*Y69ebEe4$8@N6d6%=N#WPGHy^hcFa?/M9ieIaNBai4b$85AumJB%jap$M1
R?tZYw wP?p!Ph1N^qhi/#eEc?RbPP:DSacNu5XtXHQQV/m+E8^jZC4YK9MGb!ZNPeR+VX8D\?#t!Y#yYeG+e^J
hhh=XE aK=%<P$CSp=uFiFpMkAaH1&T>qFl<tDSRn&p^k#ly6ul+yw*tyeMi4:QKkJM=+PE<HFhJ?e^VLW>##ZY
>1P\:! Ft$:yeH&Cq#$p9NNc*6wJj@aY\FSZudFeMY>K6F>4&84p<qk\QW*4Ll8nP#1%H6w/H81\Z#Fu1*AJ>9!
P>iXLc aC&h9A<1lLSEc<L<+t1%DYX9^9jn\i6>+tD\qwlDX=bYpc9CHMV&uuLP:IjB*yhcCI^:?Ey\<HFH%$eC
Z19WeX uES%ttKH^#!d&Tjw:AZ:NKN>F#@SL#JqXGS!c&CKbhH^ER\QHHLdBSIwm!G@TFTRDT5I=SA<h1y<Ky/\
%dwCF& ma1Kq4jiXmVJANp:wmQQ$ZMd>bH!dL5>^aS/PPV$R&^1HHLtPubW=IR+wD$qVtBT/kIP!GFkYa?V1tJQ
<VitPu %8l+CdJ=&@8J*?cdqu&@da5F1NZe%<1td&emX/4ZFbCJICJ@pPdwcq:w>$KlNb+kimFa+!KidAYp1dTN
>G\idh y/#SlV&u>RaX<>Z$6WWcpFBB84tY8uX%dLKe\m8=lHKeXW1mCnZGqeZhqRaBBBtG#11R>cK\6k=a6haN
#T:?&I n8pAuB%PRFk5iEeyRX>PXFeLqPNciG>Vd6K>dW68NX>yHiWy\mPuJ\CibEa5$5yCmQm6Rw&+@c/1SC4X
+DZ8?E lAQbT1B!h58H*=SWF1Rdik=F9/I6cEwQ8nZ%y?WctyG4CM+Sj%AHIDI/ieHVw:R6T&*5T%SkCaAkl#8K
5tJJbR :pD\YG=!Ab6\wNC\IZttZG9SV$%@TtBnt19NGc<6eQG%+hDS4tJ%%aZ>L<>*:wFXmHJ:LK=5V@N*NaP/
SwLG1B RF!?d1BF6/hJD6<u:1N=I=XC9y@u!6w?\$lDjl<<:QZGcn1jp5&1q$l+5J*^&h\tLM6bSe1+KuALXlNj
Y$ZqV@ 6b19%/K^IY%t#&F*l89&y5bdXPCEID:*eMC<SMJ+8E^VIe*8DL%=DI@t<!camwc6=:hHnXZdt&c9D:S!
/nI\u* 9HPNiDNAl&aZFu6T8TmmBjnTACWGAD@lGQ&wnttSXadHGL:E1Q::=dlLpY&cin=JE*d4:p&8yVa*TnJW
FhneaR :RNpy</4<SLWSGb#iJhFQW?Bp>Llw4BkEt*d9N*FLjm/H^e8$M#>HV%Z8I9Q?$nl1c\dlmyVQJ4&K&\G
4/yR+l :@EJlWXZhCZ%tm18?$X:dG=RkW6Jk4?w%pR=>S#%:LP:\FdpCl*Y*Za8>wQdc1yAW$\P>4LTl5ZT!Y<!
HYLibj 8+51wn9CNtBPe65nYKnASq89\Q8y+GpQ*Rt^PK@Mjhl\%$%IYi6EdMba5a^n:YCi1<h6w5Xb&wJGw5XS
ya@pBV niCGIT1V&PB:=S!:=j^iWCV6aLDPwMb6dXJQdlwAbHhEwLq<!F&\!N86:I#5lCp>Y#?CX#!#=J516%X%
#SHCw# ?Bh9S=NGAAXku@41?niwLew\#EbFn$<8SQ^$D#Lt:\!q@%@YcYDE5Q<nq?=JkSHML\tM@P:TQXY=A!N&
m/?Puh \mZ$b%4!9*Y6ap+Ttb/CQX*JAwPA@*55?uS!c5^JN6KV&J<wLGARmF@A@5Vqh=JT>CRYid4cCAcB?9ha
LA9^X# ^E>euCiJRW>mj?w??%ht$D?l@\6Z%F>yeV>eWZ?!J@!6#hMpidEa#Q>Npj9%FDt<Z*>5A*H5@:+WPht!
j5l9k8 1SYMI#HBGmhyQ+m=dK9blTpjqq@^Pq\p9?%%PQnq+BF=WQK>@tL&En\HpL%i<llauV@F$IcQX95Y=XW8
@Qpe*C ThMtL*>IM4m*b@WJRPXk\>nhHq8IqB+/L$+B>4RlwK6QnBFmcBm^*lTV?bHPFb5Qu1Kyy&+AnhRV*+ZS
AM>bKW cA+CLn$QW5hbVT6Fn8MTSIJ@JIySIWj=G=\kwHh%k+9h%GG=1e^EcFVHGKN+8bhG6V/b4WK*TwZ*/Nu/
@j=#+w R+6ptmjBh*6y\B1jJYlHquC?Xp>#R&Yaihud:M<W=Aa@X<?F%Mt<qIwt19yIIyb/e/?QqQ1y4tTCPE%9
jyi65* h:9LBuH@e=6tGq&D&Lh!mQGGD>kPH:QnRRD>JQDtalC^6FGdLGBI=4I\D=&pnNA/cBl*i^E9%ZD:$jLw
qJ%hDe m56R+4hXX#4%C#1X*J!^ZR%Ca>FAS89Q?qQ+i=b*WL6NqIGe?ni5Q6qZm4A!+w^RV@Q1mhMa#>ed\WIb
A6TBqI bWL<b+?ZGFY&wmb<aDhTDIZBY&FAy5jYcV6:tE:TdWuae!yuX&:CIq9cH?1=F<tj?V<tElRalP!hF$5$
qV!Siq !MW6yRPbYaZFqlp#:AW==I9WKN\\<b5Wd1uln?+AGEXiC8L/@ZYA&pHy!u^A89QCE://jHl/GYumGZ+N
%ADXt< =M4tCE4<@4uMui4*&uZYLaWjM&BBBG<Z6=>\Z1lGNY9V^?Jb9aWJ9T<qCM+jjL$jeR9I#Laji?$P#%b^
u>Yqy8 b*Y586GX/^8CXY@8KYhYHJu!>lG:6Su8Y+lZE*jSu\>1tY/NndRWA^qI*86e5B>Q&yF8H$RWdtm<HIJA
j!6eBu pY?!kPK*BWKwJc?l?LI^JAVdDCGYBWH<&c1wRQ\LS8imwGj9duD#mh@T&yRAQc5bQp>k$pFj>qtn#+qK
F/B$M& %95VR+m@8+=dEFu\^D#w68\SaNM#X5/BHbk4X8#VH1b@Z<Z9qnE^WWV:FG@tPun>LyNXXGq1q/#SyWZ#
^SENLJ &?>8dyl@a?kPjeVy8BAIk*?AA\48#Z9+Sw#IphRqn4GiShB1^lcM*XiThJRjmDDR&e?Y4ME#4pypYG/$
*D!&QC KHJdnLJi8k*R%Y4lDXeqCJubNyS@>66H68%n4pZHXAwyqC4&AT<^Vc=#u#F%LX$naEqmZ$&*L#S<:hNP
SBD+jc Rjq<Mu?elK\nC=QN5b6*WhIEt1cRi6ZKD1i::*HB:yAb61!t56@+SBTPQ#8B8A#hC^*qw%>$pHh\X^>5
%+8*h* LM4#idKyTS=$I%y5RhJth!5p$VK1J6+4@PNeh8jXLJCH%Nl>uqAHa&J#n*ZLQ8uT%S!G4X\IT5T5+iFt
$*ayy$ EB@1n8?l@kDSwkM$KDQRWHV9kNXAtRXm5u%LqY*=GYw8jL\Z+>P*quA?Z:^#mM<4FD:@=5GHDAi4c+*P
lG1S!c Da8D!1W5L#WYZW6mB#?^d#TDmY+nTm&VDIuSBQbbA<+Z*I#Gtbl<6i<k8E1hPw41RT#Lky^wGj+cu8bG
$tuH:Y I#5GNH9^^n6d>EhcCSMlbq@IM9n=JImeI<DN%QYGA&Q@wXk8@I1FE=M=WZlKq*NbbQZ#QSy>i#PY<l8S
ntcV*N PC*KG!HFt:HRG/\FNFHi&e?j1+:L^ypj=dyjPB!%YiHjT<bVYW68ZhXpS^D+DtZt9P!1%MtbhnRRBq%W
lAVLba /Z4Aci:V/AJPSA&YtqN*lJ=DqKyk#DlXN5>!k^:wLZXyKVu4FRtpN1ZhMAZaatIHQPhFBFKb$\b$tC@/
lw5ucV C6+KD*/l8j%ADM?%1\u!:Nb4/*Ge^1tkIyyH8D@=&jG!H^pqcLdMA6$D\Dm$CN5eW<1n8XdP1$tpGEXC
!dnl<8 AHi8dN4hpJ6q#$ny&#^\Jh8dDY>ZIMGBF4c=PZ\%VkV:^Nc!5dI%tB:KM8eCNj&FWt=lchIiRRSVRQ4p
ueNRA5 dWy%P&?8QD^8WcPiT@/\bPRS#%S/et&^F\&69M$DKEQcyW5+eNIRulnX\i9#Q6cR@$#6bEHim&t&wKka
-AW?Eu 0002633117000110333 Page 242 of binaries1.zip
jbjQ8b EYQV19\q#CXaCuhplNV^W\:ZG&yDtiR%8^Mt!Z%jQdbMa6uaFqd4K%cMB@ayH#PYM:&cmdtn!QEyp>dw
:\yCy$ Bt*RG*6/uWqnt<<?Y#8Fh9cQ?M=QjkuJE6CFBeRb=F#SNB?@#aDM81p$/m4*jlM%aClA&DRJnwaWNDaW
%?bwkI p+#68b^NwG6mIubWI\#uA$kL*#Fd^B&y\%$ybM8ZJjdhQKKYMwh8Wd&knR\+j?HTGLVww/t=@d#ph+>#
mu>4CB <>NhI:=*<dAPW?68Xcj1SDmw9EXmutGZVPTk+4d8Ipyh?HJ!pWEeCDMGGhSHWkay\1ZH+>h&?D%=X+i?
NpXQqI yDQj!FV>cM5#D*idJ&p^8D>n/p4XuZ!?%dh8+#w=iaX#cNDBVj6#C/cw\5!9$HR/P#=Yi>F=4QCC<pN\
Ry1QAK F18%!*GdY?JnpkIba%X4j?t&+HG9u9B:PpPT*+Yl:DYaT$y9E>#9ZTkpGQNXFkjKq:?*65t$PnimEuKZ
4#h?$u k4ytY9B5%TcN8kVCV5@aIpTq+nG5l+LCetD&HE<L\>9ek:G9d#R!R:HMLlt6*4dR9hScj/thSSw!R?Tk
ZB\l4P ^*5^%1%X**6^9i9im8$&\I^YXQQlQZXpZaTm8DtCACe:S<E6Q@e1C/!*P&F5ebpq/By1>>YkK%de=ytp
MW=dc% ZZ*W9dSE>wR6CVZ:I<<:>lwd/*Q%e99:$cb15>6<mIu=<<t*c&+Y=nRKJq6=1ii%I#cQ+5aP+E%uBPVl
ZZq^PX aS:$NAh=^+6&6\aMJ#mdQ:Iqb@h$RRylQn&DDmHH&6$H>#ZK45b9G/n:>C91D+Qy5mya9*a=KT6+KHZ=
nl8@T= jR6YEmA\<%\ltklJPc<%H4in?%Hkpl1Bk$>*qkQdcwL<=uA%B\CIQ!wVYBPKQSB1QSDX4\HI%PCC^>%N
kGi?Qh *qZLkt&/6Q6AC6EPmcQZS>/ciKt8%pb1HLp<tiE%1\?SM*ENq6>=w/c6Q:bdBHHuPTJaH<@@VCwEGZe%
Cmya@G /XhRGSw^nCd^/8&yCl&h9We5Pjyt<>m1Ku>d#t#pW<Pk!B*m%dnZCEQ6bGQNnki4S9tAm1h9qMA&BLIk
mKCktT J>TY:wYw8WT:KY$i5H!uiK9&XG8*8HCHVEei+PLA\9tIA@%ERL#HF%J%u?R84Wi\H8t+u58PeEDZ!JpB
?:EH&I n15<IjT<EVS4H5JJ?4eC*ZJ5=RyiI^B9p>96KI^Y+HZeGb5Fl8y4SeZBYeAeB>C8FanZpFjICqVmql<t
Hn@1pw %iCCd!mewISjJ4BJnNeI6:Jj*m/mQph?4^?ccK>5h96N%8e&@PKYDYRu!=BpGhw&:BWjucaiRW>i+cVq
DIj8ln 6pR&8Lkq<<mb^W?Wc:M<^W1htSMejdXIn<QlHnSKJmu!Qme5IPyNWaanFcK/b?XNhDIJJaenLdY1!LHD
I#IEnE qEwe=k=R:cQR6A>8hSlc<qcF>Y%WF6KBNbid+IHG:9c1Ct^Xa>\?=*%Q%/DnQZ\mC=KMuL<+DXyBKDD/
mcK*>W :hN+^^tK/*uJHjqAAqmwW6DY?*V?iMXI6e#XJ4tN>DMnRnX>Y&j/?i=Ge%Q%DZ5mcm:W4i>au^hYy911
S?*ERe n589BSjkdG+F6=1Q=dl:YKn&Y@B!E<KI=WX:NBLHP:K>AKT/Kjt&XljKb99=B#ZJlJAE:+TRbKY>4Bh5
A+RB6G *%?l85<S%S?%i1Dy4SK$8B5#lN9M\bE89lInR\8YCXn4Vp6HjuL%9u/9dQJ1wR/WSME@y%LAJjG1%!9?
Xh4=Ct 98>wL1td6cAGV$m*#8IVY+%C\A6E\WKdcw!AZaF/6^tRS&ZRq5BSmTKHVSaGAMAIFw5h?>Whm#:4#dQy
%NMVW/ ibW@\>5R\#*iKD^T=QHk!jIF6/JRqCKkEN!#Ac^/%/8K5:RRN9TK9?4aQj$p1<apP&uAkZS@H1K4wCk1
+C9Sjn GpDYyNwFk8T5\&!nGGp\9Dy*tHVM8yNYu@kw*YtVbY4VaRbtJa$%IbNcLCGZYZ4ApwA/WI=ND=6h?N6\
QGY%i> R!R4CaE#AdKVEnn%dI^B!mZ$#tCWuKdj8D9V\AnV\iCpD<HtkhC&e>^kP1S%8Kd=/E\X<w#Qb&8=6%TA
<*DGu< pcP*JNVkD\Bi:SFbM8LQ=KJ!un\5:/8?klP9cqdEHkC/TaeaTh4MlJM6Th:B*8H>dFGDi\/AI!n4^+Q*
ihF>+j +%6XE/kABJ4kkK$DN9kNYL4=J8ZLmH9NldKW6=N#aZE<w^9<iFyJK&=T4h+\R+<=%>ZCm:8:M/EZnBLj
ZEiW@h 9H&i1qikc1^=S85h&^hjZR%6*D8ADIj?q:/eV1QuXahuuLZiGlkd8QTP<QVX?L*W?dacS*Zk=c9j$QwS
Hd=@pj uijj<JYCSAieiL&9/m6=/8+a&m?h+wylI/Gawyna:daC=?tCVl1uqJbdTYT1nw>BZHY!@Zu11<^W?Slp
:KcTL: @CXBY%cbWA:b*u98ZT^?pGXn>RCN>!LBw$Tl?!wq9:&P&MaQ^9uaX6ulA8*t^5VZRnDq<AI=BdBMPM+m
8EDA#! A4d8b*?8W>!Dl>S?K%J6Kq!/c>DHMBmbb1IdiliW!HN5m/dqwJDBc**#8eA:MWARD=ctTB:n?uLbynYE
IHmSe\ lA#t5IeptDjw%9iJ<wN=H>eMmF8lVQBp5RaVuwa&lE1JW8yyV\tTA+AEj4m&E1lml*Ti4N4Gq&=WI?%c
paC:dR eKNNw14K86Fc54GHp@H/1wqmCZ@DQaYRblG=X9t%mqh>6W#/j94q?9E&b1E>#ZlA$$w9K#/8+\Qu6FyQ
THbTNH T6D1a<LP#ZjIqN=*$Sw4&qePyP/ZRD=Ey^KiKh5Ju*1d5uC*+aW%F<uX>Plwc6KAdVKj*1QL#9BQpXq1
/p8mQB A?JBG&jIW5#GFq>h5?G=G&j#X8E6c1545Fihl??#L%$*5K@=I$>9BR4tCXKDcYaXda^?<V/86\e5kFuL
/#<tXK 1mWD8L/WQX8aJlcHZHtmHTLuAKu#JPJKiCFyW?%9K@R%eHEnWQ#e4dDnLHw4#$nNWM*X$Gj#AX8T^e>/
YNi5#a :EC>#^5Y!5PjBqXPXj1jC/#nc+?<F%B=Ld^$*ZtnPulq5>lyLX!+yPK=mlHXNe4TFkTm<:!>iII19:=4
KujDAF QZ%59I61l+*TFNIwZ9F&XtRq8TkZCh!@Itp*L1dIZTKj4^%knJ+k=?b6FCaVmSnq85q%hNY:Kd!Z>XLl
dIG!Sm Y/9^NbGDBnuj+C6%&@:&?ekMP?RcaX^E>Q&STk6NZ8EKJn&1K%JyVPjVi8/MF&$qXIcwpBY6LMubW*kZ
ydQZ96 cKWELqwZ8/G5%V\XQ/RP&PFWi%?Tb^yi%WWm\*XlV5Wbl*/GZ*T9iq8Ehb:jJ:epW=i!yujljmqNLRI1
b/iTnW KHnE^:edPF+MAD\Iy%SajiJHKW8t<#4+$Ch>SaKL#^<u4%RF14EVa9DYyJkYE6>^:TtP6!d59=whKI9c
@jin?W CL8VDAA4BdSVcjVP4BeZq<nQ6KA\q>wDa*W6^y@!6CIbi#*D*8>thte4j5mP8^RAl/XTHSXuMdI#6l8V
/5TBtV pFPwK&d5#*X:ZV<@VKTq\\y=cIdmP*wWqmj6^Km:Lk5SLaq/L?AR8Akypa<ulq<&uNNRJmwlcb5S1w6c
QSMTVN ybGi6iYI:QDM\dWyp%pie!mG$RZ#\@Dp*SBQ4haQSKAZ#Pw$*m:$i*hEd:5$TZu/nV<ZTuI6PPeG1HVV
FFTy=w my&t^q4R9dqRBhGG4SAH^nF!T$ww99CIjPZ^k6JV9tPG/cuuJ@ZMm#^*ZNEEQX4GGyLn6nuPleZam:I?
5e<^=< HYm:Xa^CwJ98C^*iVK#<FN8qpGQuTQ=E?@#E8t!+Za4YS/y<=Vk^SmyaiuEJ@/9E8p\&*Xi^wV#DSpZn
uRB%15 X/uVQZye9TuS+^$RJAZEj$ba9CGtEAmjiP6h5C\>Ftl!99n?%c6CTAqp=D*T#K8aVLJ<a?GH#<Icned>
pMa/?X t?@\DlMe:=k&PD9=DAit1Te+16^L$^&/XcmjylwP=djbX6JcQR^<$L6=LYh84hV5ajthe^G+%IGWybZQ
1$FNpW nqw5htaE95P$Dw9#:Z#*\H^iMwGcuSd+KL8Re^T\&qLGy&1n^w/&*M\VBQGVWqhMyCpt:hVGd#Bl:8a4
mXaLn= +VT#*t%j4*ZK<F*EpR*%%m!8XiXV%G\ZJ=BRPBCL6&%9bAVTwQMw&NlP<^n@J<V4@=5>^wn@EbEDBwp>
CA/%/E +VFGau:Xa+^Eu?a^Q5uInpGe%Hw?NbEZe=KR@SR5>uTQMSL^C>nVp*E^TPT@^/J@+4qFw9+>>1ji%:>V
%IjD!w h8Q@k9/99K@@SCKQ?eN\@6+t=1V*Xi\H*?@@&atAk*aIGqaS9</cklb>dnq\Qb5?qd5lWHFNn4BtRa<6
u&W8\Q TbX4:KFbA/&piAidWlLASI^yHAbK?kmJX?iqIQi6CY+PuL<eN>uh!X=BB!M4P9nAihaw$At%B8XC>Qt\
cRTZYh =ePHNRWV?Re=wm/WZX&Xn:aJhSG@B!ZBCES\lLG8i=ejdd>P\jMB&SM6HkHbI=&ca$elIHm5yawhR&*5
&&Nk=& I<V\a#IK1@9l:I>K=pD6bj:#M6GSNBXClGW8AwJ689ZER8=:\i$hEN$99dBPelB#GLHZi1>5:l&GStZK
FV1w/4 =Qe$AGKKX&jDmQ%jMFhY%MM#I>9L*A+c?D=%qZFC^$tkKM8/?LWC$R4>#&XX%\$QFMZaLCHhPd1Dn!Xm
lb!D>N %H&cAWViwF+SneAPDFC\BMhh+%!SRAkpynu8ku8Id\GB^KQGSM<ImZqw6An9Z4+A>t=Nd1kMKZ5VJ=#Q
/q1Ci8 l$PN%A=tTp=wIKa^diYBZR<:1Ae>HwZX:=Y$6%unhFqEPG@INJ<S9B/qGm9&*L>d:n*Vq!a>jm=Tp#A/
:@J$hR 5pX^HL5m9b#Kp6M$e6wkd^5iV@9<11N8#G\*4=^nn6YIYu!Pw/mR8q=cl=yeV8VZy$u!Z@lua@SBE9w^
C6CB&u ?6i^y8pH!^LAe4XFRT$n1a>BRM1GRB4V^JSej1twWbjd5p56ahe8ZDH>nAWT#p/wSLF4iQDZYPLCmP1w
hpk!Bu /!b:Ta!qIltA8ZiJ#<uRqnk\&q9Kyb9Mp#*BMK>Wpbe\Zw41jp54SLcknFaM#86LX6#9<tuW:lVp6yh6
DLQpWh S1\SnmV%>QjkQMiZFJ6%&WbM#Q*npknn<&HV#T/YPNQ/&I4K8+nhw>R$GwPaT^\N#%+&/=m:$>yBH?Ec
&wPIA< %%SbZNlnRR>A/A*A$>t=?NHiCj*LTLtZklF1NKw8JN1N^tadSy$Iqm9Cet*NWtS68nhw4=w:y:/Xdycn
/8PTaL I!i$t6bJl/yc6iFLcAY&i!$D8kZl#$\p$8I<cC/*atbekJlZFE$mi&cb8=Zbc<>&\tcFqK>ekwF6cpVj
<*+Jyd F6*j+N@ZMI#dHnqcbB1Y4aBS+n*+LN>+/4Kl8Vaa4>/Ww/D648Y%K/iJldpKNTCICIIVe<^IlGN4R<=*
lL^XF6 5RQ8etlA8ihb?A+t5!qIZZT4#Vn+&@BMiHZZePGqP%mk9%tR5+pQZwRC%IcnYKwd8%!!%CT$/4KWNa$R
n:/!p* wYSy\mGtc+#:Nh*k<CeXm:mpq:FIqeVZ*ZZVHkX!ZG\^mWG4ZIiT=Pu?!E9C\pY@9TBqnb%@:!V+9D#N
Cw9laF kbCKSwXQ6m4PlDM58Jw8%<XpZXaZT:ERu=*BS8aFni\NBi*jy/LR&#t:W*IIj1n?8VG&9IAV\aN\mh^Z
W^>!Kw 9lAG\py6Ln>=5iX4RiaaVB<P/=B%I4FMZP%lJCqJ8L&1BLh6n?/^e8kl:YT!n14V9aBw/$$j=%S$8j1q
@hk146 VppnZJiV*>cqCXCS5q8jYhHAB%qqRXG+Xew?XHeRYtS+WlCwyQ=T:bLFY5Ck#hR*cqZn:KmGi5G4wmRF
ciH@D/ uA?mXTp9q9jYFC&W1X5SBNq\B1@GE&hBHeNt=hL/Qqu#+hlk$X6Q/$wi!K/ME<4S/ATXqnGSEWeDei5M
Jn>DSR LYMSGFMcJlJbEWjXWcQLM1XGjEWwm$inLYIeLP1N?b8#QCM=8KQNmTp4eq$PNyw#&4Twq8I1Sw5HFB9K
-Audnq 000717232e500110333 Page 243 of binaries1.zip
qj9*c1 9atYbYnKZS%HL%P?4\^Kck1T81ulB=hM&RQPwI>bXddJ&B%>A\pcL\G^E*L6^Q^8AmLEK94ZVZMRZVll
F\i?K% l@d<Sb^bVMlqph#+Nl\Z8amRSK\IFX99ShYQmmEBc4kcSpB?cQ#VTX9itpqD:kpnunwne5@cYN&?Aq^H
a9!lmR ?Y=6?MYk<Tkh%aQ/<t=/I*%?5*1kSyhkI>6>\:J8wwn^A+$b<PuLud?LL@^@86^Bm9?Qqn5w=IuqDk4^
!Ad!AF 1<5hqNmy!=&VRi+@iLy?+jF@Wl4m9\MY?=i%A%L<*/+h@8K/%@1hL?@E&8GjNTQ?KmJA@>@A:c<FdtE#
l<4nkA n$tLBSAMeh=lpPNX9DLN%!jba*<FdtY1h*+Edy6%D+BuQG\?R#8=mGmkK+>pS9NpB*taGwJ\^5AG\VdQ
lCt?1N M?%BBB%aPY5&HK@eE1=pE1%ydZc1^A#t:!Ih@&>I#GD?48*^!>ehFuHm85PK@iy%>+iha4D\$//@p+Il
4tk#Z9 j@Ln@VMN$?pJG!j%Rp=mj%K9mDtyF*JK9?I@/Xj<F:CI$%<*V81FuMV?IJe:DZ6TL?RWLP4$^Bm$&C>k
4!k#\d V?ja\/AS@^/LP4&&E+NG@u55<miJMYnWL&Dly:>Pwu@B4lDau<#XL>kXA9YV8jwF8$Ke#uYHRj?KZWu<
1ElZQ< bK=?\c=??mnC\Q<V<C>a%p?Wh#Aa^H?ASj+H&F?\4B<TaKhm$d@T:?qFl^nMj+D>Be6Cu/+4n5GI@\jH
Q:X@mL K@E9/^RW/q>EjPAT@!Lm<=hj+<e/BZ8T@SZ#h%dHW>4<c?$D@/9N9!T96Z/@CE/&KZbK%yw+R8^@q+kQ
h6K1WE bT^MD5Y5*CNH&D^wJyF/N:dtECWX1l<S$>8bBBA1SRPlZHAHNBmHa8qV1yG6GZRRaaydDJN*pRFIFMn8
Hd#KaX WQe@6tM&yKCF?BHqL4D!MWT4lbheyjMkC=8#VF#E4<8IBT5ZVHyGn51ia&#u$XN6jPKD9Dj6RH#%iqYW
y&Xwij WM>an?h?c+Y*CA8E&%ehJQPEnK+6uJl$LdyCbP^XSe$@yH>iKj=D?tj/h?tjVn<#Sk?@Q/S@hpHu//5&
9>\pIk @B\S*p&jp%KT^<cbw>WL=jVZ4$Vh:%!6B+8tQ$6n5XH1NLqinDWA+uJTXBRENt^19:lkLC=itwyw4lcA
66mt/% EqV%Eet>K%*K5Et5V+m?XFFi65y/D@tcHL>YIVwwNNbR9anum89MYeZGlyV$wPI/^ZF<+PXAZKN\wK+Q
S+Aw!9 W!5bpR!L/PB%6/ek>lc%XkBlmRe#>@ch^Ye=k=<XGGRVBlV8Z+l#1F4DDHXc$WDnT9Bmai!ShnVR%+F8
J1eHHW NNA19NZL:nh<iEpNQeAn5Y+*FbQ=cEKjqlWAXaaHDSR^PW$*cI*VbY4i6:=PR$bw<&aqARpJwJGw+u1K
QN<Jki cl=jdcYBCIjEa4H5IjE$R@J<HdM/l#88Rp*I/RPceX@mYQlECtji>GlK9n&tj$JcYQSl@jtA/ZC68>XC
a&jRmi Ve@NVhE\&tN4m$EW+AY&/YDFGntW+m@4NIymGdMb1Q81RRMdNkmG9:DEHhI@e65=t5/FtVpIkPQPK*Yl
W*Y5lk lwkX&T?+&5^dAItSqmdQZ!C>Z8yMkZh56am=pSI#H>aRDFQ=6N?D^PMcZRW^p!6Se81*F!m>ahARX/hy
XVQc1^ =P=IHD5:dum8iWXLbcZb#@^Dy5uB/^Bb9YuVK^jYM@l$W9Al6mM$>tp\5j8^YhJ&nH46AD\CmmY*Fq66
l#Xcpb X$4Z%pZjPCM$?I+:tMJE9X6MbDTLPH=lJEDG6^!I:DH*BFLZ?%GRm?k@6X8Z4^^>\:/ea*BXld+mdckj
P$VhT% MT?LuEA6LJqCJFhmJRaqXHCdp\&ZDHi$K?PpMdbTG4YK?>QWFSTaVC&NFX9Z&Khc88<icN>@R*@$wZe$
yVlymP JKX@i+K+?LK!H<%nt5ZtqehA>ZeHG=/!q#Pc>eViJS?94#>\ji5^y?E\VD\aLnW9K!ePw&>cmbWJ8=@!
FC^lVi pjG&J>CQjpNC#9?^@=bB!<TDwMj#18Q?>@pIw<MQ8iBCkXDNWSE+Q<QEjRSMV5YEF1WCdGj**X!Ti:Tt
bbW^yK 9lR1KV%1M=@ceqF^9Se4tAw?8&A1DP*4ymi^/K?itQcGCm<>D$:L!l9uakCSPD:lbI8NP>h?S6pB@DRb
1&<F$b +J<R=Q&hK\u\IZPmQ#qP6pCiT^ycC#\kmuQR6&9LQdl:LPe^Zdip8:/pLXVW$u6:qX&u:*WeT*%<9Ydh
9#^$mq N+&64tuiBnM*LeTN1%GP/m\&hStVMY%i$j/I:yD+?$N%\YyqTR%=l=HL!SWmRIwk^:5ik!XybheTBAEL
uF?!R@ h@k?M^BPw5\XGQ&IR*\i$$h><6CSwyEiha1F:YGXmmQy1aL9!k+^aFF%ad!bDhqWcujC!J^>6p4ZCqt=
GZc>*I X%M%>n%Y\t^cmt>9>WB1kt4qjFw!J?1&#w<8hqN<%A>9D/$VRw!Sy/LRSHMeu\CEt69eD:1PmqnaAhTM
c!Z!K9 ?n&M\tBL+wqRkc<Q?ByXe8*E?dSW:@Jyb\kytaY<<qPZSpd+IwKHX6h<kl/QQ8F>\YA&:ta4qqwhwi^R
%y&=Aj 9C4Pb<Mj:<NDhp:CMQp!LQd=AbcMqmjQ=wZ!B5m%tm@q5bZVY+>!n^uy$Gh$PZiVNCp:+M@EJ=mk!#Ec
=qpn!A DWyp*JMjNG>:j:wlqpGlD^V9VuG^5NnKYGtmqYcaaP@ZG\!4WCF&=>d4qp1Mb+1eIubnhL4BwCtdXc>Q
RlVSAM F9:i&IY>El%kbilW+hwbJqqKc+X+IQta4a!$4wS\E6q6eAEX1HjVk@!JcdZ+QYjNn8L$NMXPXNhW=DSW
/k5HtT *8CN8dbpV?#>VMSq@!H$FnLX/CW#>dRuYbBaWX?TKDW$P>4hb:jtGdQwYj/iJwEdcFB>!uJtw95>VN>#
&ZL&6P $?:LdqyT81Y!hJnk\D5!>q8QHka&Tk<$QQY/Qe&Y<:=B$4#lkZ6=wHeYjDJd4eTLKCkyF5:&uFTh$i+t
k1NMTY PRi4+5a*bp*=nyCkSA\JmMNF5*BJ9dA?MF%\p/9TcI4JkM5=KbXjyuR>?a+J>XFWipFR!nLhI#wVl1id
=/leu% EnCF^6&\4iSQWN?mHI5t4dVME8FEj1i<=j#+p6K8^!E<5>KVnM^++pCQ#J:?C*^F:Cd^1MF+iQnV=il8
H@kRYX ubJS&/4>964k!chu>@$>%cLqiWnIZy$V9Kimw!FYa%DW<$d\6eHA=Fupm/^C?66!NiyGL$mN$4=H5EBi
htE1u6 wRp&KL4JR1S8M%lD*/JN/%IWn8<lJkHp+RPT:?\!N9nejSJ8Jt=euekVVGq%aZ^#Tie4^/h:^&\=Qn:a
GRZPYY <HGGybiMQcPHLjPPledeNGMVGqjX##*lH:mQe6/L5?\QKZ/56LM6YDR\iXtG%#4Te#^:MnyNY/XqhE6C
BEbpe? 9mQutp=Xm6$PjWVm#QQc\+edKnt!6pIHyk%X$bZFP*^4DI%T5Qhl?*eh8M<6uL%9NbE5/XLIu9J?QmZd
JnHhd! 4&R4SJK5c#j91YH8+<R/dLWLbnBeu>@bJb!PK&N&?jLLLb?Z6w$<b:G1E%d>R\%9Zkw@cXyn$l+pCh9q
>d^EK1 44dFcNk%Q8>Y9/N!&ay4mS5Xyyc&%H@=dqCwF941T/dJ/GeZYV=bY#yiq\w*5HQJ<p8cR>uAN%9N+@M4
ZBy*ZM yj5i!9n1DcVW8GZYpidKq>^%9HI:TFu:Pt%A6uhLu=u\kd>yMk1^\nVY5??uWV4DFF8>4nj:+d*II+Qm
?t\\TB ?<Y^t8PQCy>i6u9JdpMG94iL5dF<FJFCBIH:86<TpT@jlE>b>IPJK^**^@ukH<!ibE+u&^8R!XkJPn$&
pHjdtP SH&5&=tdZQP8qL*+TN?mWtD&$d9hIh&!8*F>1aY$ILNC4411m=mQ>9T<LniN4LID>\>9F>!h%=uB%BPT
\NHpBa #TB5u&6eMZJSnB+t^S^Zq#\@S/n/TP@<y/M*l^ZX8=?>LT/+nnV^NLeLm%@^KY$@^q:V19c#e51d15&R
QpHw#c <SZ<\1hYEj<C?*:P65&tn\448K#4@ptD&#>#>+&8QS@Y&kN4$SPk=b<iLtj9\hSI>8Xdw5AbEuEN=^=#
Ln\A9n ^iuWnm@t\TdKXTb5*h5y?eEyP=86yaamyCd<BX=Skq@8lCl>myXb=>V*KM?:4\K@Z?nkGuJQQ@VJk>Gd
ShmYAX AIJaZcGdiwp5bSE?F6^bk&j1>Amtdh5PmW8LkeX%ZKR!i%*yICi#T@EYlS6pm6biG6dJXSVZQ?ju^jNa
F!Tt1* GdFNVdcb+MQ4d9DwYle^&TtX8RPD>YI$LBPLdNeM4ayMwju^X9nq?WYViG+<TE$l&m%aX>qm^ndD$<pj
KnIEdh *&pq*16&XBmK/SpNki?jWdw=XI\tq^jb/#hEinm51#PB\K!ZXc!8EAEtKZ1^N16GeL<=cIultqR4KG58
%S!REj J9GNJ<6K4FHD+9yNwBT\Iwy$LDED4J8p8ecklIn&aJ$jm%%SWy1L+:PLcZ%XY?H>%ma>S8tKYI$FZ:@S
een4LA T8\!8PkF%>=L!9HF6@%LCw*$?&WQ4LMi<SDqDe=?W1$F>hK%8i!Ki#IaKdIY&Cyl8X5H88$Y^kFcb*4$
9i5DDt !6K?<VTIS:bkSRTeZPXmD!CZe*RjCd5NnBPCHiA?+jIeQZS%*RYjC:*bw/j/Qi/yL/:/lH=ua%9+Rla@
>K<@Ay $N895cH4Y$8pi&BKCdq=ea$H=1X:k=QIeHZ+GppnFXYmGSW@8@8ZTT>%jkT^AM<Knb\/kFJD4Q\hwEIc
yic<Jd $CYX$weQH^nM1nEZyGnb=:4HP&ca1tYH#wpe/QSp++#kKZlm/=quy<K*MebCy6Y946CBGYl#/BQRG%>*
5&aENl E<=T<1llW\m+A*<I$l&NEn8Yi%*pFyPq$:5HIF6whBct+QW\:Lc/dNQVd9jEknNe\!$^Qi#J=Y+y5:Yc
N6<lL+ cT?8kaQd*I1ZpY6bnRY#iEZ\M%5iGME&SDE!q6QFBeEGJJmCFI=kmm$5!Cqy9PpKFYiHE>YmBBtmRlVQ
948$:i hb1WCZCWPT$8KyKK=^#Cda=61dahi/\em?mYCKdhkXKbCdYWQNQbFdyXRBb6aCyYYNiM<+1$Z8V?wjkD
$R1=!e Sd4*w4jPD%**LTuaw$K$A?uQS$C11Ehw&L4&F*ip<6$kdh9R<G\yJa8B45?W?VaJRue\@S^lZm:/CVul
Bap$4S %RY1Hm=SNX/Z>STt9d&T1&kY=iQPW+95q@M1KeJjh<acK@a<=*+mKh1Xn^VtXLtWn:\qAXS^mmhq::qI
Pmy+El eD5JB*yTqA#LLtp\5@p&Dum8VN$/+N$EtWlTA8p*LA/wdbP1/8Tnn:J$W8+4^=^SGF^R6XbdJ*BXhNtF
9@ZmRJ WbGX1u!BpSMM\Xw4HCMH*L5$%RKHTM!y6R$lXjKWFYd:I#::/$V9<m%t!%I!I4>5h4weV>LNDi1\Xc%?
6BG&@w 5bDXXtk+\@iqL<Gpu=cew*><T>VMLI!8qM#H\Gd9eDj^AQ^qj>9uGCiLW#^#D4WR^ct@Vn+>c+Qd:K#R
W9Pnp? FXRp+\$j^N?$>M!K5iP^+^y?%yNqH#ym#FXleYc%LDWb!y*Tp=RpQc/EV<$w+jE4C^5=V^96=X6NQS/9
:pMkyb D>KHQu>tElbtCku86^mHyklV>KXaPVe<dD^Ty=$/:C>^l>1VwcjMiP*Kd5heVl*X&C=!</PuYD^WV%E#
VnDjwL %>iKk4hLSmd9i*+4GNGHyHm+4n5Wl%?twjG\Zjiph99mQKX99ha^Vp6QdjDJM9Gn>I/Ra$?$9^n/$yFR
%GK5jD eSJWbukX19AT=th5n:HDiwIh8:>THHtck!AAkqFZ8!1ZjbVD?$6&HuPPluK&:?@RpBW#Fl+:LM++&wLh
5HNcH# >F<Tn%iD1Py8n/q%itmw>1pKWSmC^*8i9B>QQSliK/&XdMPDihLWh%p9y**DF?KVhSG?*KTtB$:V!5dW
eZpbVP uZ=cI?DYTHhkQ1N4#Eh*#L!%%!N9*Xpk4K^eIHKTLEt@l\kG!cpJNHq9uiyIc/<?tIRQJ!Lhjc^H%6yQ
-AE69a 00075e299ec00110333 Page 244 of binaries1.zip
ukhEAl XqNC5jA\iuGG?:kwKmYl@^pD^PE?t/!jZ4%=9/>jd@5X$P#*Nm<8$b+l&4MTX\VJ*e@RWn#%h4Mc#nhS
MPChdh BHZWGb:%\Eck*\<CCIIqTA?5%/<ueH*ke99IcjPSIn#ieF\JbC9qHMaGYhYSTtJ^>c6!>Z*n/uj#T=Q?
%5%i4k tQ%kLQ%eZ*E?6SI4Q5*dBX<&W*QBFc>\l^@*lFSSeE>QCG:W?9+6THDiZTHhQi$4J=dI:mJI<Rw=JSY^
\p1^9y J+GPy^yddPkn#\twF??Pq@NIRK*c$*4Y#lLtmGjp*t>>>m+1dSWt?T!P?A1L^L+I<i%Q>RM<>?>j<w65
HTLRDm 9/1YiwWIhS@4d*j^P8bDpKHLe*@9B>FK6XelTXe%#K>Gh&li9PibZpln=QM$TX6T<G#EG^8QB/*>X@bk
^aBJKH D:4681Y9Q^mBHQB!9HnB*$\XTyb\W/Z>bm4u#YP:t9RQ5yRN?A@j<MhE?GPTY@Rd68EJRV^V%5jM5B&b
wKBD^@ :y+\5p:bpIN/kNh$Y9InN*G5t>@&Ljlqh?1#<cEb5+D:YmGtJI:9%ji8Q#5K85q@Fb^\C:!T+qKVL/+\
euq$15 yh$I\Ayyjeb@D^cpFGPRa45wLNa5:!&?A<GIw&6/^SMHY!n/ZSPu*Tli8TSSiCylQLw?&MMQ*PmeZD&?
9V\*mX SZ8LY$%TZBWukjt?=eR$i!PI:b4W1cKSXJ&&%Akll@*#FCpKq!PXk@H%YS?1+=MM4tHQ$//P$CHQy+ed
EjeH+H $:%lyBjSFE?Qw8<lb1BVY4S&$iQNb1yNt!6wL@Vewhjm?n+&dchVnHR<bE/<\^6Q#G#V!J!ANT<WbiHn
MCJCVq b:F=#qL>>T#XuujTC%Y9@dQD%EXm1@jF6t/ipS4V9HNPZ?ic?5G5%\Z?ehL!8uS&@ktPb+#5+&:j^$6=
w?Y*i9 p8>/>>@lFAB=&d#pD*mWpS#CbZ6PIFudDqllkWq#$d*G9dnB\@P&Wni>+5CdIFKM6!dS4=HnY!NWq>Qq
T6DZ+E *pF/nSydFckkq!4eeD!Z@TY@RKC=\I\>kEM>Xde=^e$iTERhp4bF#m!ZSqwjWY8eVm>BenH4K4pRhF5I
HeqadE <6wBj/BW%\*w>V\Dt@RkK:JK+tEIpI<uST^pQ>VMT8+nF=#m#dmc%9jaY59146B4SDTH#8k1q66Jh<C\
HEiCiB 8\j99E:9d>P#<ZdcPD<nR?8468qpVlny+\&SulHFIILSd8VlSi@c^&:9>A/9phq%/Q4/ZJXpaVQNF?SP
yYL64u 9\bbp9S\t:%+u5TN<\EJS+WAklSPKj\?$aZ<eWtd:Nt^i@tCmZM^+1YiT:FKRqCV!#X551Y9??m#4JXl
aNdVa1 Mh%mh>W%H!m#CEuP\SNi$#LHNWEZh?iTQD5@cRBle9c8Vb8XjTZhZ#T8<&ADb^<NK:M+&>1+p=uHG\y+
@jCmqT PICa!+cbc>AX>HycNKEPnhJ%=wTMZ@TG=+!R+1bh8uaXN@H/%ljNT5L#=6mZV!&Q@48k!j<+?w6qR<H@
/B@Bte 5^nW*>XSjnpGJZE!>m9^!:FjmXNn9!i%X9:WbQ1*uJYap%w4J:E@m#&h%Fw=mj%bWjbJ4bXV5KmjaMX@
PmC9aB Aj8Vw8!VYm5u5V@#Qy?WYnpFm@kJX8#ja%Hmy<hmVp16uIJFuH/<J/XYVtKSEn@B@wJhIVE@Ph=j5C9p
!nPS<q V?J$+4>kX\mJ$&Pc+4>kX#@nnlV@Bd6CmQ&p*%?\1=?GumS?\dDEpKhjDBL@tu/BSj:d>I5@R^tmYt^a
uyetcH PPJpCELmqQRLNPK*1@H@&Q\LPYBDWtAukd:aet$ItBL@Fm\eVe1#yNJkI$F#Fta<V>nc/#8<$R$TW=uD
\L\kRV P>LEKnIP9k<e1cWBp#GPba#mqahn4:!5&<Kuknqtk9D1q:lw4>/Jh$R\51VX5CWM:SKW?/aNK#HP91/J
#8pe:h cS^8bn6a+Bt4He\1>Sc\CLwWaH?iec<*8Nb1KW^timBIw>iKJ6\%$YM!ZLdblkb4tYn^1kq?ubppqBn?
tiMNlk mkmn!eI!>!DS9+1t>QX%WyK+Vm:+n<RMK/a\eKI*hZm8Bm8hA1ZXHw6TElkH4$@p\!MASD/GNGSB/6E4
MQNnH: Riw+y**l*k/9ntyTakKG<P$YN&bRTijmS@:a+MV98aT+bpd?JbWT>Qtq%w!M5Qaeq+ZT/pWL=p1=uMn&
$/d6RD 8ln4k/>%pT?FBwFEh/^tIJZ1l8NAKM+cEmaMJB8Sn#&<#l/*+9BTEcPby$+y/&ylVRhB\VhSed64>HSn
8$Y*p/ lAB>85pXqW$W*uZw$tK+Jc=@*qAEcDTD>dX%wkBdC!1N/q8ntX=MQCjaMl$%iPe1d&TJ&/ZyV1PNy\DJ
==6$=4 ip8!AAqDbaE9bX&dKXTGpW?=/<w>dHcHSmAjJad4H&%IcI<MIQk8Gwnui1u5Gp#F#yeBKlHC/dh=JWhe
#idCl9 dC@Aei!+^dFtHZqJblM6ey6y>BnetmR&@^:QZC!Yt%5jlFpnJ&qM6YGhqQWQ8ZF:uQ*&DY*5cE9\VJl+
<1RLyy 9pT$HcMYb4RJ5!+Ybjh^\i1Xkc?$=V&H5aXa1Wb+#nLN!$^dq:EZq4kDCkj@>?=Jh5a<tw#&DDqdCcHM
cKuGLh M8=*4P=wZTmecke>98iT/ThaMV5h%#E1HA?ld*b?yDnA^b>1je^TjNm\h&hkbIISc^ud8!HZPGSlM+PG
py4IT1 ElqPhTcBu?p&wT5%VR:mLw%RNDHEmtweCje8DV5#*yJ\:L\l1nTcy%Pm\?w??>#/kaJ$\lWK$#S5VJtC
@jYhlW WiT#5<ib*edAYE=41%hP6DLTp?L\Y>ZM5Hhl&Mq%%$Yh6^hZ*N6wMJ<8tpkCGCdM^&h8lPJtwE@yS%+i
cp:VCT QhL85&><5Vb+jb1T$TKi@>t=ZqAkyNjbWCS%?\/QqE5RAG1qbitehj5/A*+<%D8e@jl<einHieEG&dj#
DES^D* C$<!&QcD=D9pN5M?BV?@Be!+*a+5?9n\9L*J=!S1AZ5!N&yB6wX9&e+j9h#:Bl=e5ZHP/iWDnu#pwk8h
R9::Il dNHR8YliSNnJqtPup5NJy1&p<p&<q!LnNwiaGY:$BS?*F1P^cw+iScF%8d<FJY9YmC=lDcIMJSJDm/II
W>%jD$ J&eeE9J@R$d5dIEh#w+YBN/6jL=>S^!myFD?L4nBWPAbXJB:91IGX/<@t&Bdj6c^$mC9KZKe=ZIyF/hI
EK/8Iy <HSL%DlR4bCk4%mJdHueNA=lH*clb4TidGm@^M#NtKTMZ5EFd@wcI#\YLe&QGNapC*M6Ce4KLiBdjHE\
a4?#ES R$I\!XlWDIGa6i#HlKNDiWPyXuW?9a^kG/InRe9b^!XcmjM<*MKGBDjQBqjaXTbPEw$@aPc6#::uEtiR
!V4n^G XamGY?kj^G8p95J#>$+d%%9i*?/Z%+\GNT<#XbnGYV\Zly5$&q<@S88#9NI1NHI8n1G<in6Z+T:hpD#i
mG%5j> JCEujN\ym>ym!ql6^><uTcjYQq6h<#EwM+Z&8V#yDy>Ddp+im519#DhPihQ/eap\be*Ei*+6w#m?FP$9
lcEiY% ApTqVZiZb\@Fmk^FC+\QFcE?G!CiIE*yAw4PWkSjBTleqmk\+>pPbW+B11ll/1GIl:/9I<S:T4An/%K6
/FF&hP wLR*q6&DlwZG?GJy149hkeWw5E*QMp?u9e\V^cu\Wb6G#<p>P8!TwGI+=G:5%a?YTnKmScn?=1I<mEtp
G&h/!@ ZIHKdXtmpw=qb+&4V\!&Ybk:@X&!%aI>Tdk:XayCC%Ki^c/qbNca9dliFTQtb#VL6TdMeT^:yT#La8KB
#@Hlnb d1Y^P4wqkYiZA<C*NXQ=$Li?4CbHbV1<uZklkD=#y%P>6*/h/*^LbTk<#>tty#48&FD@NZt89J<D:Vn=
QCDM&R $<W<IQJn!69M#\>hBBqiZH+=ku\JI$u9dh\i@KnWHI%Hb*pAGMSD9>yQ9DbG5weNMLQ%dF%/!ZXjKj#e
@&8YLT SKP>&K9Z=/G=4SI6Qm/%RZj9*BhJLT*>yH=J$@8B!*1@6dV!#ZWDPZcjB!<btqnIRcZEV/Fq+bu+Snu*
5:wI*F *J*Ct:X$#FL9A?N4P<mL>=itqp*MYe!J:5CeHSHG=<XwF5HaXN$uBPw<nA!@ZScc@BX4M!qLkucV\HJj
S\FH1C &#Biw!i$tpXca<nZ$h1VhM\qm*^p?4Py=lQT+EteS@WS:HLP?<qZ#LbM*e:wt1$Y4?E:QKtV8yeNTATE
cTyP/4 =8q<cdD5TQ\&E:Gi?VXPW>$+d96uI8R@wnLpn*D&<n\*BX1Na6+%CIcHuW9WXHh>M8PbW^KR/HARhR<>
CFSS+B 8@4CBmM!k>LW9w+L85Q@8QbP\6VV/jM\k1Hwb>uWm<kYM1Iad5Z:Sl5>:**b<9L#?ycDP%Zem5<DE\W!
5V4BN4 VQu$4>EEdRyZ+:iGZXP\yED\&BN=k5PH*lS5>wM/?JZZXHHNN:n9C=i>HCRqNLpKp%<EFd&yHJbnJ4a&
?\\p&# DYjcMBKVX>4jjKTRP@j1hquQ!%:V&+?Z#R+Du4!@MCLw+LJCwRue8ctw<VD*+bchJ=uZ*k\%YNFAt/BD
Dly=#? CH::I?$G5SP/9>$ytGCKWZ:\#K%K:1i#>SdhnQ6%8?q94/uaP<8P&bPE1NZ1E$&a#&bQ&^6?jj4p/Ym@
S?Dcq\ QcZXQeNK1\mT^KZyEyaq><\#wM\Zu+d!=C5*yV>T/u?u1E^CZwhw89hKQ9l<w@chkAQ#!?j?ZZSjL*%q
:=mkiC QN^?%T>#*yD^Pt@X@Ftu!uN#C5:9:#IXZqN?@914XCYjRPPDR%H!dpH$Zi?:^1PbC^PeLP@+lS1:Q5=<
NkQ6iC qVA4ZH*$ZmqadCKRj$Sjn1H^ec$X596d/K5ww:k>6&>u<kj\!B96*!@84$biMH@/NTCcQJ1V#c&eQHtW
<*mYZn *&R$51W<nABADkcHYCkGDpJGYR*dVEkBHQEKhAEKSmZ=8QjpW^65e<AXZR\8p5!mcF^p?DX@%#mQm&tI
=kG65^ PHaWqXM^Y>8F8:k1W$4B$?6IB8S#JNF&Kamee?FyhT41@Rwd*TE?59aAEkSZhSbVhSFaZCwpYF^#8498
%=n$I% T@b5FFJVa4\:P<bF%?9ml1>+TR/X$iFl\+e/DA^^LK>S\KyRl9Cc<VMYGQ\K?SqAMI>LHH+aK\4V/&dI
Jhy!Hh $V+L!di+=!bX<b1V5Ebww/84hw%6HL:ePwL9!:@8*CqLaV<KHTc1YB\lJTG#5F+mA$^/Fl^#qdaVFtay
IBu8D> JtqVPuQ6Dw?B4d%y&@ylyMPK+i#E1$c8Tn*^Fkey+E59akSGImDD+DKRXq6kCPJVaSPwkBY9FAybR/&E
u4ESJ\ uKjd<wtL5%Ac+uty?RbFJnSWTQd1DCNXnhP4/D&>PKGq5d#Cb#nVtJ5JP6id4iapP\M5Qemt8%b*Ty9E
@?b4mh Xh6WmmjH%=ihP<*&p8+&YuReEG^dpcmi/@S/\<iVHa$IWQLjX\w<VNA@Emu+Xm%VYcQHD4nC%4Qe#P*H
BTKWNn STVFyqwX/IKd*%iR&dKKYbNDh>PTd&VJ9Z*L:jLERZ9d1%jEP!1PQY+*wMRluMVBJ%EEy1!L:w+%!Ljc
u5>bHn :LtyMDB/4VS<aXZFAGHL4<AKTZwp+N#1eGBuyiLIt>^RWHYF%m8Md>N9V8pIRJC5aneeul^8AHd\Zd@b
DdqqbG E%HNE:id4cnNm:m::D#BZ&eBJHk4WCVIpQ\Gy8CqNBD<IaTukbi8Ia#AEi:*%6QN6&4ZV<9LlGhP#::%
=8m\cw FR@jZDEe5nk/LwyHpR/d^pcR%SmmR>TK89Q&\@qkqh=md/%p9XESZkLPTL+ihZaWG^+c^XMHXCq1&\=c
41jbjJ 8+X!5nNN&K8Eiiu5P!T4Di5@G%WK9!qZalj5Vqey#EuNw&VmbubZ#^j=%1>5=B1N+F%EIw%q4VtSb#cd
CqcAF+ a#hdqab%nYF*Z=i9*T\pb<?RdaJ&#KPPG#M8/IL665BP:EmZ$RI<^EVnNiS!?qjKCb4$JlQ*P=VhLIEN
hi#RM% +N\^e/nVmA!RGqGQBHw/+%^*?KkJ>5PemT\Gn=L9ZKn>#F<@JPHlu%^*S>aSEjR&+>c?yMjiQW?QkqEX
-AYR5m 000f2fc75e300110333 Page 245 of binaries1.zip
H=PK>G GJ=kM<\ddPQkM1TSGMX:$L%ZhmMq<qa5SVAajw666#?58cRTd5Zu<d$kmWH$upidq\CqnQ48dq4F*1i8
FW/&cd $e?R+<@YBNMqaQQXL#GLSaX4#eXC9ekJqaGJ6&^q?lq5$Y8BPnI84SQ1ASY/bp*/$\/S?&yl\!Pl&X#<
K:Aycc Sy>4IA?n/:RnSP+T+NL&m%cW@ZPHWbpDm@/&Vni=4qjt4Li<*dVjiTBNqqXXX>Y&LmWZP=:B66C>9dp?
EYEHJ4 Z5%JIhK&K&BA@8T^9yGL\K!mA1d\aN8*NI/??B8\EWbCyTC\XbeG#:qVCdB$hEImX*$dnte*q?$AjyCi
#SciJK TdhRX4e89<1eaRjdww!Di\dl^??w*CId/+#jH16+JKq%LZ1$iTC*HC^Gm6ZHEn>6bt8+jNXwyGWN+b6S
c%$wLl JABZWlutnGp@!+aVG*%XwLPY>$J/9>W1$aXMRi#:D<>YHHMi%h&lySK4j1#$uEqtbVFth#yD5MCb%<$=
<#L@<G wm:CF*NFw?e1Q?mK<uBid*#E=FW5**K&qlqM>$DQyWw^S>ciJpq=<=KN<+/RSwd^46hhWZFZ9y6a8=8Z
$Yua$! BjZ6h??4k4p+XQC?Du4tVYL1G8Khk%5tJBL&FdwF*Di:I6dSL9k4K1\S9aE>^F+>Lp=Z%GaH?jj6ZAIW
!/5wtw a=Me6C@cnW^h&d=86K9d=:/>&$9uHeqXYXF$6cJT$cZPP:cyu?S8:1C4IN&YddHdaL?V4:LdpP&Vih1=
kDqH@! im86V?k6>RJC>hWlDjRlAW&9FpbC^$?CpL44L6Y\XcTJXb^ZCYpmhHEZW1Bl=q!ktP:8>!\J1!kXAH:N
QX1TcG 8H9S:\1H!%muBMpa<$d+K@4+TnT+Yd<H%Hp5&KHI/y\tX8wwld+:a%E!$#N/tVla*E*@qiCAWZknbViq
1M5:nW :EcAw<l*ZBWS5Hb+t&%/qhPaHtY6qwi?^quK=hNW45!\$*qYp=9RHheV^ejq?@wSRP&5\^1=w#m>!@9i
M&4uK% TtnLFTP&yanlmDL/EK>9%lG4>*tH\?ll5I$SL/eCAD&4I6&!M1+#cF4M@jcZiB+>qTcLIYJQd&5QA!Qh
4^PFTd Y^aLjjT<4uYB6+4*9NPBnu=d#uT?<QyYm@eZhFL9ZdG:a+J/H/D##V9<?kRDImh/%m+<!t@a%mF6YE<i
tX6jyK b/*A>$J\!&X>k\QhkBXX11\IN\%jnP6S^4+8M?tyT/EGj&^<@\qRM9%<^/j^4T@qLX?n:^4ncq?+nptR
nF&#V1 QWm&&J51I>J^4@*&Nq*CyDc:?EHdb/uG=@qwZ%mNEwnt&AqjjElGVVG1PSN6:ZPb&+pMywJSNnT56+LG
4@q+kP M\XD/TZ%TTuXZq1Whw6V%a44ebJH*a?N5etj?Iw%64:^MB*D4X@JcTH4dSK9JZ6i1!4BP<<Et*%%^q%<
a#Z@6e \D?F=*wVq!5GtXFbM?&MuF!8EE*J%KRiYpSaC%#18qt+TtWAdM+SwR&I8Yn?\DC/aPPTV*PDhpp5Xt9p
hinX?+ K5W\I$*b^&XQX/mFlHh/h*a/y#FCEcM\k=u\j^:?aHyS/WJA>di/=TLkIE4REHPJ>k8I@pubJ!dLHB^a
9^/CZB K&$%jqa8:6NXnK5Ybd$kVG+:>GbqahFBST5$eH9^nSMY8%aWu@jKVibdElN$PL$pS#aB$415y4SeyLRW
W1q:V9 +LDwmk<N5Mh/%?hd//FHEXmaVej!laI48PbQ&5b^K+Y?PR+>m*i*d4/l$:8TKHJw6/tAHy?LK?e4Nyet
u55%H+ I#ZuPjnGu^VZeyRV6+%QdX=eN%Tke+&ye!kq8TS:ZG88LKpau9#!>RQy<Ki8TnI\<Gk<V$RXM*PD/:eP
l<=Ehw cqc:>R1HHp8#q\K9+8SNM>dj>%\N!%y*!SlXWP5pyabwte#EQd8PjTpX6NdnaHeukR^5iL\m*VNq@hpN
8+m<aQ \uaA?B#GL8=n>=ttEuT^Tj\waKnM@a4$@ZIJH^Nm>W#TuNV>^E?!9kHW=+@#!VB!iIK$>@9D#y/b+u%!
*nYEub AZwEB6%K!JVbmp>TKSWj4^GyiDF1Y+>4iS#wEj1y/Y?+i&^c*QKZNPV>wQjM^/j59hHt:VAyBl6@&+:N
Lu9J=% FV5D4*!TV#taia@Fb/w9PDI\kbFGN4%N=8=?iC5Bim?@GnjqD/w&+KYMkHAYndCHDu/d%<^dCeVq5F^i
$kjSWB ttSM8q>M4=XwKaKaLNAj>59WNWC&FE6F*%bF@Jh^w%5Y$:Q?Cub949dH:wHC>MwaJSjXbqecAq!\H&+w
t6wM5y NY^Lbjuc$EHiM6/\^t&#nYG9?t>L4Y@FXT!BLyVN6Z8ETJiL?MncGABuu!\?tCq:/Z8??=WFmAt5?nLP
6jZ1Fn ntQ1IEu%njDNAVwX6>hMaJ?d6h@&w>p?Rl>m8e$?Rq5XDHwYw:$?Kmjh#@m8Du&SiFFFR+I<=?XIE94#
P8AI1= 6h1w^>a!h\FM&M:AN6*W<IwdIpJkAHqBbMtm:LYF!Eij#*d&BhI@iM^D<:D$ke=Hw?L4XGNHbC$tAujX
MGF$6N *?uVI=>XcRTIw8LJD6:RmlpYZ*J=Lt6k:j*+/%R:kC<>Fi*Fh<qFeKF6jY*?HjIXLc+>=1Gi+K:bVZA/
SRh9>y Zd%LF@aXLj/K^I9bTGJnTi*i6XeQYq@lYu%99KtCDuPZhq?:X$wuJ/>4ndy+adeXiwNw^YHtX4ShDSuL
dR&Jc8 56uDp1kZSZi#DGFqBnJG&\FNpCP##S+*lX:H6h5?!:n=91KHybKXjXYX%S1Qm&\>tXtXbGN8Kk&+^wj*
9pBK1c 4hEKS\$@TBXV8p8\p&p^keWh*VX8QqT^#FC^9NwSh*YC\Zh5?E8uiibbVhS+#i:u=WNd4i4M^&@44bLJ
QaGG!A ZLj+LFP4E<twH%=a\*^F:uW<?!dB<SNYBAup@=<EmmV?S<XKYDn1Z\NFYDn!F\NFj*y%@>XZjNIyL@G4
4+Ql=# lWauSebPau<YbDwyMuaT?#M8lyMma/hkj<LFeFJp:BV5/cWX&JMma!i^Q?Fm\J+WGV8J@Xp\AQ6*qVH<
\m:F&G Z>D@qWNj+4@1FLCIp#WF&H>YH@8Lm$ECn9$@uI8l%$1MB8JyucV1W/IYTttHK?Fc1CCL/R<q6t\6p8XI
K@RKwL X5**i8kk+QNZkCGjBey=\MmTy5XG6<MP>CS5ieyeGlM8d!VER18==kcT#CYahP^nW4FN*ySX54!VhbFN
JGJJ$k L$PS/yd?wWy+WlS+&qQ1*ZRbT\DN6jTl<mtqe\J:AnW%wDNM9WClDyW=TbEqy&%54VZd6qmX5<W+X5^c
e:&y/G HMeHX>ih=pNWQLI/LJGN95pR@8cPG#PwhMZ4w+DwRS%n9qZ?y?@qc6hB>cRD%^kakMVNPCSRnGMbHy<M
BW/m*! h1PBqdiwNPjlLc!a\1kIVBnDKF1Di?G!mVw\YXq=Y6+\ayX%hCnFDl#IE%VthwACj?w1p+/lWcXGP=%Q
Y!w\+G TZ^mwX8TW:<N5TpXe5DlH$6a1yTkic#k:8lm4R\HbyD*hRLt<8Ce!C>6b%n59t4KFdkL%\\eVI6Ba:w/
jlH!DG >iVIn@\yTJ&Vu\8eEXSdRp#K+w4^%W8+SZE=hkYG^c1BDB&PkX!jIaWldTcjYL=6:<C98qHhw6I+$wd9
M@mJ<M >Dmc!k5tF#uA5yiMcN5<cCD1GnpaKD#5tb6\mLqb<^q&+C%KI$H>iAywBhMT9nLENmwAmmXc^JkjXAG=
#nq^F= lNFuB&u$K\LHH@cu/=il1=#D!cR1Z^SP$%nJR#Y\%6c?G<K\Je$Zq?b!ZZKDB!5cSwDAKcidnSIc*Peh
%<I$P< u&19\SqAViMD<WC+KckZPy:Clc#!C4&hW=8y*>yiqR8I+X=\CZ9Iy#yi&J//=FHwSGHh:9wCA9jK!ipY
+9+Liw %qBCCqnFHPXck>BGJi&>K\wl<P1K/?Y6hdT\^4Ah*@eSFqWQ9qYKiXkCiC>6i^Yc<$H&%FA$L6l##EZ>
%Zn1WB #QKpA19q8p5SA&bQZqj9yq=9G19Euw&DAkqDR+!*yIy%ciSmA@9TPu@\Lkl8V%y4XqDTElNyaDl&a95b
jH88/# =8ip?w!<Nqnqp9M+>h!wSuGeXm\$:Z%\a4/>>u/GQY9QX>L\yYBk:LpKXP#$hClN::6Q&&IAq8$ZM$aW
56a\Q9 $y14c1$&\XP$eDdI44RBWiB8w5=!qXyk$Fl/w=ay?a:P#X+Xt4T&RWbbAp$Z:9a*SGFY#*Ni+u^/bS@n
e@eJSS <tc@9j4<%dBTm+B:t5Hc+n19Bt\J?ilB\M*?ujM+nc@nBW$nlG#i#pDC!1PYZwcXJh&He5Du@a?W5ATL
u^1Huu =?>=p^4!hDW4bHAw!LqHGZTKe$\?D*ct>hQT:BMqB1ZKW>Y/n8uMbBRnJtpqVcC>^yjCI^QNb/Mji\l@
S?CnB! >BIJ$+P<<Cc@JQ1^VD!nbV+&XCW<qINbYK:lHm5Swa#cnjF$\?EJN5/XeFWYhE9Ve14yuTK*\RwK#ATL
lND6Wn Ni&kW<4t%<5FQ1qE1=!?REVTya^<m9ma*d6A8QBu:mLY64H^RtH%CnHb\Q+ZReqTwXG/F>8Z%&&IR@SW
8pLFDD qqKHyFIn9?mmXIWVui#/<>qI&#YK$+W$EEPL?DpI$dML@SI1hB^jnMk@H6kDd6B$J6LpDM\/+j9bWZ!F
qka<+W DC/!ut>E\klXT\&K+kmDy=Lb?lSL%&@GG=SXcaA@ZkyXShmR:<JT?9RF$%EJm8&+kP6uqq:ZyLVYbu4%
K\X+K/ *6?RwmjG8?BK=Mb$S?jX?1nm>\dE^FZ+HeeiN5Nb1HSeL1=%ZGlLR#RQdNiZPCw?Ckc4tLKpSKqEAV%4
<?@9Z9 n8Jj*H&yAmeMI<>Njea>d&5a4l/9J>C$c<bMyq<1qwMa>QEBC=ydZc?:eat#Y%*=XbnG%RpNt9!8J&Wd
5Y1jWi iqbe*Yk$Wy+Fb6!K#hZa4b\I/&NLw&c?45%>KZTh:G6/5+KI4<GnB!tNT8*A5/In+4&/ZI>5ZyVJmipX
L+BkWT t5\E+8iVq4h5yl=QQ#Ze#JC*eIqct8!1/\=kNYbTehI8t?Z5iNQ<B8\L&eM+t/qdVBneIjHT5\^Rjm>W
\q=I>c pT9lyK=l8!Q+54utDTjRanEwybBW@:8ni58XbMtiT1<lp>t5FWl8?@Nuh<cHcAKT^Aq/c</t:A*#%6*E
!YG4NW iT@JqjlT=W$bED\XWKuW+%@Zm:/iBDyCc+j=5WJiMLmJ+jwE%Cc9mc5HWTt#>Vbn$ZcXG?RtF#M<Z/66
i*6Q8M hhk\bdwW\6bR+$*L=FFMCebH6I:!yd6^lHubyw/ijdqbDGp9J4VX/?^iQ/J:Cbq>#^DVI#5eknaM>1wH
XIYcS\ Z^wi1=8@uba1j%QH*C>ci*Y\PiWF5+PDV4XA@1CCmY!Yjw4k@QThe5!PbWl$e/wX5IuldFchwcj?B$jL
9hQI#l NkYL/u4c#T9eJRuY!XnL#CdyyK:dBDtR$JHPQEnRXBldwSL4RqtZ?<&q^<MFZ9NF8\yLcyS$@aKJZ4B#
HWk8pP /uhetM1SSaAuFy^pK>e%mVRBu&6wZwc>9<LnEEyBeeyCF96*?e@@:^c!&L>4mj:!Rlb^I8MJm@nXnKe@
WJcL\b X#Q@8pa/5Sn>^?D?Z9W8j94/C95LYA#&hK#+L&CSQ%qRT9^:LBy:cuaJ>1R!/Wp5/9R1eP^JahJV5Pmj
:hGIX# aBH@Hw9EIE@HI9<>>1iLaDHWL\\cijwJFpQ@AlcPPB*:C+d%p<Jt4Bn&Q<CK@+y^wE:H@wylwW@9F@E4
Vjwq96 lwW=jc+R@=J=>Cj!j@Gm<qi&$a<ZFjSJ>Xk5+nVmF\tW&Q@NQQ1QM+>5jtRiYj#@IQNId4K@5n%c+dB9
V+^?+^ SQewHqRKh&HlhI<BFbdti6$41hNiCY&/IQ1T4:<N$q5tETbMdMHRyLFwVSL:imKRwdEnWJbVjQn+9%KZ
@Q+dyP CKWE6yyhGA9cp^YFbZ\+h:?JVZCC?5WPNSkYkcXCnNLltweYI:Li66Jut>n49VF/qapDFLK9de@VwRph
<9kQW: :GlRQ1@%y&Y6</%NE$TkF!>*\<l6pMnKh#eM\!n%jl6+d4jH+uMDj%NtBim:HLyb?bD#hKbV#ZkMFJ%w
-A?uX> 0001725de8700110333 Page 246 of binaries1.zip
e<Ze>1 VYeCuyC*S8<>#5ACcN>JwdB$<+Y&\^S4enRta#c4NJjceh$&e%h&Vj*$wZ8HX!=#X81+aX!:k5LtR<1X
HtdBC\ SkFRc*W@aDN*66XM/6ApiuH/!Sp:dT@J^B!ByWR4qyHquCn%8cQ/w<>DpE==<qjiL/XiGd#D:$$*EJ@h
a?eX4Z bGn*ZLEGNl%tH>M<q!XapAARb>?+5i$dj4?pEW$dJTH4J&>P*4+*!aybDIFXX^6u46!wpe@<ay4VGDCl
nD<eEl +<khEQdM!pnT^&9G@5ZeVIYTb8>Y@lbuZq#lhE*P1&c*8:Ck^>A$ZyK?uV8*ncG#6E?Y?p\<FndlZT<8
+i8!/A !tKu*l&^$t5u!&YMZEkqQ=j=^KiR>W66=mASDipHc\p/TLMY:wW^SYG>d%mq:>cm9/uT:HDne&9#1?ny
6K^<4C wck4/Qqn@Hq^8NHAc\^hbhl4+=9XCdS/LXyk1etF/6KqB=#XL&>1DZFjYQpmeYHw^yhe=dTGX&4h&kT=
Y+Ae#B JmHed1:QH***%:cMdP$TJXkRDMiI<p*t9L5$Il<KkSE?:!<4dHKQa!4&4cnWKq!@NGmib/hlb=\N8un*
5^N:LC mV#=^=CmXZkE\SLpXj</S4PMNI@dkJl%a6#IuaiIPhKXtJ&<NIB<u%w59KW6yH<@!9*4a6hiV9ca=TQ>
L5cZm6 <HZtB#udnP*PH#GS4l>d8mZDKD/%SA^WEXdLT+Yh&>YQ^J8>E1h6l!^@5ZVZmTN=muJpHB1kma!XyA#M
hj5P+9 KTG:VSyuJ:I$ja@B/E$u$<6A8#Eq$YKia6PAMdjK*4Geh!F5>KRhX<G8T/1<>V^Ja9hM6EpN&S8XuPNc
#VHT\F A#HJXZy\@?&#W\%=Z4XW=9qdcl/ZI9une=QN:1#bQFuh=L9>YlJjWTLIuRFw5^KT$!@b!9pAPY\Vl\hj
4WRmw6 DA=LLDapdJi:LW^T6a1yNJGdpA61514#:$NPlhbkp!@yWLK>bT/wtE?*c@F4=i@6=V$@L^>dJ1<TeaZ4
EIHwB% VphHP6?$&LC%#YETJFe^/IulHY/ql4neJt!M=a*S1CIHK8K4l6/KYyZ<bZeKunMC1d19n&^nck%cN\&*
@DRH9+ X^uS*S<W/GZdVjVNH>eT+M=8LR@anu#<LBCi4/lDVRF6WL5Zkt*%eFn6TT<S8ThmkYic^4ujPamKKNnK
/4aWhm cX96W4^LFV5n8Pa8Z*LM==6C?TKE<@lm!4WGlN8CRpu>6?FkFV5AFjkFjLGV/uL?RbSuJE%i%@b+WwPI
c4\?cy iYJ*Q:dkCnT*M\AhHeC1wH^IITSEFXjj@mGa=JDm4nq%qJ<jP%PILiY!iiC6*DTiP+uhNNb^tj=m9kdK
wCAWea h$mby/YIE%=LQt:4I#Xq6PG^A>dSbMLhltL96CASCw6byQ^YlwXe6y8NPqtp%<R6\G#yAmY#1K*+56KC
bZjmd/ @l#hMAN>Lu1c9Dp*^^i8#W<HypjZhHhc>&W1Delu//4%/XyEkmNq?Cbb%y!*>S1eCBdcbCYl:\qL5bKi
=\6bGK 8m&AVa:^i*w^d<FhJW$5BWp=tR+mTHH\QT4#>>D!lmBa@1Fp%c9G>ZajR8D<yN*Y1$bVyYq*PpPBl?\&
9P9kGd =%HN/:Lb9L\<Dcp*iLwPebLIu9^Ew>k<d\hl5&HG<Rjy4iV!F:QHX\q$G?4MCQy/Sjta/EQ4?PW&*K@G
Pnij+8 eAtE/J<q#l6Fc#JM*>tcTV*RGNa9CVI\jbn#Ct<1Fhq$KFRJ@H4HL4R$anQakWR1%5&4nGNRe$PIA*k6
RQjpul q/ZKckT$b1N1qlZNnEP$9na*8FSwjyhS:WbP^dlmd=1=?j!e+/DI%S=Jw=6ui&@jpV%+jd$qEQ<kXa@a
uE?n>T ^b*%/jdPt:a+%?YSiHac#E:Jm#qdwjm15#$TDE+Lnb&=h^<yTDk:?D?bm>Yi\G/@aYG!LmG?Pid1!*%>
R=5Rh= %:tqe6=YHpBwk**k:e%qht\=L9BK*wptKh/+JiYba$wQ:Y8<uajCt>L>puuZXdc=t54Zmyt$APa:M>=D
S9^IhK =mn$>QmB:a1iqkjLlPM5ibmL4!9lJy*IiQ45>8S#6@IlEFq<d*:pyVm$DleI>BT4M8wyyIH*j<8!&m^R
NqD!Dw ab+=PP*?RLAue<5pSJLK@5HX$qFQ6<J=%8nHS>!:/:&Gu:*jijb*b8<?Py/q5HD^qM*8N*/X?qmw6Kkm
\&aG^4 VpiPKeIX1=&%?j*/GE^SH%^j5W9S+!SS^9d/aX\aM#$lHpY$eQ<PTbu?/:/KI/L1DL+6G*^YPHPu8*i4
YeMyb! Rh\>RaYZBJ#q!wa:elSZ16!?nhtWw98iA6:HB=VP/6+:W6<JC@@P9elNH?#+>tJQC?8H=RaF/cQIyk4h
c>J!wJ $a*hi5M+\+ZlwG*l9e!k<M?//*1*>4ln44>MG#Re!KhFZ&L8*HMnY&$8V^/K%:/=jI8qp!hm9+W<5?e1
+ER+\? lhtECp!+8iT?EbL:<@1LtnGt?$yj1!*<HmeZMPa1n<wKGZ:C&TtNHM8?<V6/t=MJc>nTeQ18ukhVqRE=
b+N9N8 ^T>XHQYwK5t/j$MQjktpIHkeQVYypIIu5kIXR9BlI+D<HE+LB$G4bep\Nu/8bulZ&!9PV:9ccd6FQtA&
#+*C9T HE^W^LAC9$HRA:X=d/++b/B>BMQ6c8+eFhnw=\TQc1>teI!1Tc$B<I68PuB>&#b#IupmY?6lmbHE1pTH
j8u=W? Ci&5D5:4HR=%h/!>>P*8ylc/Ae+5l9Vhi%MwmS+=>mBl^adutV11:JET\6d9\<wCHQ9TwZ9Hly#?6#$p
^%Ey=? 5%VqA1\>$8G:&AlCKlkKk?5yCm8p1HVLWk5%*J8?t/@:QB\QT?LL&PR#Z=8?&?$&qaSDD8M1QFGAM>w$
Cuj$BB iC:FM>@!RbRWY@QRLVJl\BIAS@M>^+\4$EE>*Ma8bC?J#WEGmAy^Ddb\HE<9WFldMa19C6m#QantJ#Q5
m&IPZ5 cBGZ\+RYtVX:^96Xb#!La4NyP+DBGAbX4jwTSE!6ecdDq?K//I#kh<GnPeLB<+DkX5/PLSb4u1R?BpT+
94dB:p qb//%CYT+T#FLaL8\atTkt#i$WA:lnip5eNWQED\JRQFDkQe6Et*Acea$cP\9S8chFp/DbjhAw41=DIX
tt\&Bm NYTh@e4+MicK++ySjwGD#:l6NPL4:I+Lp8k:M/T5$#kJ9ECL#k#>1^1/kI>ibQdcAj%>+>F5m?aCjmnQ
?atIWG 6?eRkVw=DmC4Tj=pA4<iq#BFlL&CR<@//yBTj+=!eI%KbGPCmA@JRqDe4ykmC>jdbCt^66Ch!I>i6$GB
/*y4mR Vny4cC:KSjVm*CWNkGb9n>K+KdeZW+Y&bQ?\S$D9e+:%WSNhHK\ilq+^M6En=4Kh>d\6Kmap1jR5IE=i
deQ86e k6R8u&M65eX=NB6B#?%y!#uC!/%HXh>6qM&G!/4ZiCBRkmWaRS^mbmwmiEZP<*w:6S+Tm*Aqk<h8papF
5I^hlk m!XH<QW+RlRGRX6uGa8PRpYX4mX<5kC8QqWlRY>ia^&XQWeb!K6dL?l%wC5&JBlKIB>aAyYu\ica1iY+
E4C\*Q M1?dmqI>ap6?au<tc!p<IGyXZ>:=PZX*=JTYlj:iISQQ5b#\Vjhc*GZHWTjlTP@myyqJCMS8$&5hJyik
%c<8W$ K?8wt?1cpT%e=/ab//5YycBZ=c^lwhe%I*<:mZe5mB#uwXciIJken$m/DR4NT%yBMuccjcM$HJ5Rw%NJ
auNP+H M>m9y/@9p\n&eRShQujpBwK1K/8uaBEemtGdbYGD&LdSB^XMmiG4pF/=+Lb?cFJDVqThCCJKbmA$:E\/
EN11CT SNu4a$/@k?N+lF1pPWpDbCNaWXEcGy>Vd?MTFLERHSb1w<8ub:?44R+I6BnA^*mlB!Z>8>?D6ewm!1%/
W$JhDb uK@ZEPBk=AT*?G8!?c:11Kwq^GyEhd?@@ba%wpmwjTM?^KJ4K619VnEK9VEhWiBZA!:Lmh6uR::ZDZ/8
*Ht<B: HK/XnRVdpI/n9FpM>D!l@\>:j\EX%=1%c<NaFi/8\X*KKAyCTPH845HhLWCA+BdekwZk:k+^*N$6Ci+R
?uJjJ4 IEATa9@i*d9:hHiT5*uQ@5::u??Md&TM%IDp1nZZ149Y5<c<u#tul+AwkT5l8>TF/cyK&XNBduZ!jy^B
Y<Ht:> D%K&m*ItYS!n!pJFD*V>StMRFM4P<$Xdp^SScFJFakjHSGb9/i8qlat:m\6cWkw&L<ce#8IA=Rc>qHXQ
k+ZS1= TaS/6dY*NncPqITtBbkF/ju!W1Ayh64c4peALkXPdRZQL9EIK5jVPWHLY\1d>?C%Z:dC5PB&GyYD6$\J
w:cGC9 R1K*6^YX5R#h/BLJ&lLJu6<#ZXj*yJIayXYCkC*kipctm=:aGHb#G1%S8bbSBiHdVhGt4&$<#&!u$J!&
tVNEuW V!YC^mC#DZES#/8PcKC^P+tai5ZqPNWXd\EnMS1JVuVlEy@!+5lbNCT=P>J5+9Ndbt!+Gpu6ba1Wiy>m
E#R6<n :$&5GY#DJdSe<LIJkKN!qE=ZZ%=NK&mY61LG?PSdbiuJFD8>%=CIbSb*bNj=\J^FTbaeHX5T4yZywQK!
ClSZQR e/<$b4Jai6NNQpFl+KlaajK^XXE%nl=eF\EkiBNjt8Aeyqjy@R+>^nG#S^R8JWCb>E:a:aIJA+hL+%4%
Q%uaI& \6E/qQ58C?T4HB+YC<Ilhe#H%MtuMyRP6mT4=K$yCZhSQdD4Y^*WeH!CV=P%IBb<*FFWm8<@Fwnq:WdQ
Ww4Y1m m9RTiqu5:YwMkiGn9Pj>:Yp>!E/iyE1?RPq8uc:<>KY8Bc%8A:+bVnSVYwjui?9w6Yu<GayyV1!MqJDM
?4@XL& k<A51Vi?yH18#j9BWGMYY%StBRACiRn&CpZjT9!X^!+Ekj/j$wyZCQKuL48RwQCQ!WuBH&dXCkuibFc6
u&*Yn: 8LP#!&@@&bBSCQd*h^WTBQ*^C9:nFjLHK@TQX>kj4@<eX@D*DKjk#\diC9$+VQZ9b*mD9y=CEQkNYKGj
<4AuBG Y>eRwS8\pF<eF@Hu4KD\##P4EPEd5L@In9++/8EuLPVuYewjS#*<!MJ?*6hV/MhSD#>lBZ@BRt@ARu<S
:IweC4 M?#QYcnkL>kd/AwK?5X%9wG8IMK@PN<d/Aw5>HN6RG?k1%>tp1E*ENa9mwYFaKC@\IL@Au5naj$<?\&D
E&a%Cu @kWY>ljat\kLDQ<=C@<L4NBjaG<kLDn<F?!@/<4K\=NSRBuPL<\QEj=6BiGZ5#K#BQM4t#uaPh9\t@E4
kJahM* Y9u!1=ub8j>#cj4d?9HdV=yi=y=@?+YTudQD*=atm><ZWPHjq5Vjdp%RCIkSB96:/%AJF*hLK@jj@k*$
B>#^K9 6#@@Ee=@>FV?q*ARWBD$n*Cp:H=d9?*M9V^@D$4@6!YRZ<*L*NHP+9j\dlwb:DiS@H+>BeHR9^X\*!A$
ScP$id <H>VcL>hNPl9*!kwTQB9Eh+kM5m9IwQDRLA@IqM%>#T#e@+>LE>d1*?J!wQj^byj>djj8Z9eNEDwd!9#
hlIRIJ :^H?:h1BBY<TIjT@N<LjLmFEGMIIATQ?F8kNAwV>IpDwd+>d@@kc/Fm=&%u:@mNAec@j@ud&6LP\<@V>
Cyt=8t QWK#@=L<jq6$\d@hq*?@lPDjqHYDCAZ@i!Q<:SL?9weT?65V*P?B*mBA?H@+cJA@*jD*#$%?9@6wCMTQ
=<GqHM Q61@68@?H$&Ej*5A@4>k\%?>BjH@/S9?cAwQTe1wi9GHET8CbqXI1n6D*RZjibkTuY51D&c68bEPICSb
^/ySRY wVk!4C6mHhp6HMipeAAPR<@ak<VnKwXE!#+KG8&KEJimw8Q9R5juFckKm/EaBBX%p8G6K>Zn>pD\EM$K
!$q<\5 >T8<w/n!ijdb#?M\JK+LW#4&lTPt%I!wC%$!!Cw+ic>D8P<&mRLJbM*#bm5ntBKNcCIJGwQ&I*ELHLt^
n+ei?Z p54MqF@XZnjX!PJ!1uHn+&dap?FDnqb$\jFa/qmK/EZqP8KyWiykaW<4J:me?4cPaI%D!La?*>!5>!8?
F!4dcE WQ^\GRpt=IbIHClp6k*j&?AdGZ:ccCXRn+L=1/%?Py+eti/X>k#*HFP+ib8lwtY&Q9>=Z=i^#tMj6V/B
-AMAEi 000032f163400110333 Page 247 of binaries1.zip
?FBb^1 BhhD9:jcRWnSN?hql#+LQ6#HWAC/A:BNj%K:DW/IpC4yXyl4Y*Ki**\iLCQlyS%k?Ly%>nYlt8i#%G+X
E+m5jS #&*S^CuC+e:tKm<aa:IFqQ/:+SIEQ*:RnBInqG9FB*u\elDC9a/n:hw$@!Ien*!mhDnj$/eVc!Td!YkR
p+N1?^ yJ\YcQVy/^TDHCKY6ZWqY!bJ^tA$EEI%!9QphZcER@\L:9$$//uuw<>1mED9EDXlbA4*ZeZ9DRw1/$CP
pT5*5K LVmSCPjQ@1E6Dik<bN*uw6cDbIDaY@mnhj:M&$:uw1JQekcFShi+AiyX<nR!8Pn$Yb&QyVYN?ZYDi6l4
iD*=nt /Hew1I%:H9wL!:X*>lkcBw\NPZW#wKm9DL>+M<X&nQ51y>Z%Dj<l&Id8d9+LG+a?KnAAkpi>Fk=@*h5e
uWp\WR V6Q$y6^Kc#k>S@QFw\@yA$!TJW$9SwKTE@BC!HVq8T/1JleVcK5\?bSSCTm%IGtt>4H+y>n\c1L#lF5T
/L@Yd4 K/AS+:h6y9&$m^:n>+ie/t6&W!<j8@JnwMy95<H>L?<ySlkIMLcIijq@iKNb\Y=GNXA1+ZtK/l/kWa#>
Lnj%\h tFQI$tePY%<+j4KSKRwFl&lV#a#\C*W4peFnypeYQlNFdWmjDl#^#EV>IY%DcNknKw$tNBN<8WE1T:@y
w4yFKy ^<5!+IRZmDDLHb?lKTyk=&lT4?^BaKcnQC@K&Bh8W?Tk+u59/<MP>Fc%k$YT:kG?CC+jy6t%i*GRLC5b
kSXQ^M BF*D+4jS1ielZMNPZ!L9^%T<EZjXB9HVNu6RbW:d/+u##RHSthhi+ad>h8e6kcBlqIT<XhD*4R\$nXk!
WK$t%Q Z#dE^jPL#6Y5dDhKL1V&C6cW6^tn/E?#ht#PuKkQW%4EMGSpdiGj*6ejGc4=TG/$uL*h\m?&^F8E/kyL
*m/y59 5Iy/SaHiMMy/ZimN8c>^N+*%P@ayJ=dduXyl*jkE%mk8%/t+QGF5w!RNLG?RY\^pmAm=Sm5iA?TuRtC1
p>&$:* >cE8K&:uFFhRm?WN>$pGtSZk<X&J:cl=:1d/B$L5tb<Yw*Pt^m4J#pbd6K1N68GY**ic9h^P:<e!RbZE
qkQmti hK1im&11R%KFe6wpEe5Z#wc^l/jH11RFm+>ZqjGyee9*+hZwJ*Sa5>bwG&Ll4ceKAZYiN>yKYyl4p#^/
8R^KEl NS!Dk&:M+Zay1KQ#cdWlBNhAQe&8FaDqPc!w!bNTP/Yyt/ZYc/A5<aDLP#t>j\Zj!wNAEyu98^Rnj=9*
$q><bY e!GESN!Y4@upYZIGu<8IeB9uML*M!qRklE!8a\qu&=GQJLb?QQQK\I61wD15E1k<b><XtY8$ekG\kZjl
5Sn^P9 5Pq\hl/@^&#Z^TpSiYBdyRTwe4etGDG!a:QqC$>6c8+C4!=8GKVeGY/by=?HjLwc*b?nL#\8RAk4Dyl\
MVbiS= *RtShZD1NjLTFV>&t9S\hX=@/:%ZJ&:u1J88+>+aCcTn11dThncYAi&%l4n$9m^Vu1@9Y%MQ5$*8KFa8
Y!CC4S JITd199QC*:ti*#b6XG\KbWPeA/tC8l1Vi@F+kj$?np@/iQD&u>kDnawPSyCTj&piJ>j6KteTn>Q?#1^
I8QY/\ 1+jVB&Sjub$J$QVTVu/8$F\nGZH\WIPdPLFS#/mN=#&^Ad6dwH*bPe/ASPkhBXiatPdYTmQqEj+pTRp8
F8l:^+ bE/:1*pem@:FHF@\a46I+u/ippY=n%cWmKkl1Nbp\\q@Z^pcIXT%dWe!*8eu+6T1Nd!TQ9e>RKnwFZed
Ja#J4d IJKL/D+GLpu?NKhAGVYJ5tNieiQLMj:#PbPeS8X=w9&\pFhe8Eh=B^<pStNmVa>NW4NP?JM\&VFJ=<dp
t4hhBa +\$mN96iaFJ+<$YP:c1w!P<cM:1#NG4X#FPKadbtC+GhI5p5t$wCCD8aSwtD#!V61mtd+hNX/$GL+?l>
C*lw\J LaiFdntp4\uE1NCYb6#V/^%>6i!N/uyJG*FDu+Du*lmpn#MWCn:a8#eKDlPhY&%59YNm>B\e&&c/R:9*
$p^qNF HFb#aYd5qld\w5hS&D<c<:HJkGGmiCmwFHQw!>4%Iw:Z!IM>:KR\GX&T%We^68YwEkQ\Du+/>AkG^dW?
\abiBa ZqN@XDpZ!iR^AiFK=cG*=tS>5KjeAa9enDbe=CAbM!WWIt9I?9Km?WB!bS4&em=BVhc=?QEma$i@jq%*
$akRmB 1JiZ8YyK1FELuwGdRT5G:8:#&py>d9Jujdy&1c>8X!S%WSdm+TP/=?5bQn@ucR*lL%P@L#D\bAjlVHWc
t:V%%h W\W*$lP8?J^?/=L?@GZ>B^FnleydX*iYA4#:=qjiP*BKYYu6Pn$nd&*AF^+jjqTlYZDy&8&e1beN8H?u
\bqlEZ i!*VYM=5#9MebHa>wtDCjXItn:td#qdIb+yL&N\XiWVX@\X9NN%bFinjuFQkH#6:?%JL4u=SdI=GjjPL
nJVhc6 XIkTMM?SWbEpWBy?=Bn^mVhY1>P/y4<K\TWCRIpyWm4mW!1LQk##+>+apSy$G$q>1Y1\n%jS11Cm##%6
H&ITRw MRKZ1!W^PwY@QPmMLhdB^:N5NL@t4#BT\VHN6deP6I$=/pN:!BmCN#11\*+\!k?1AlLk+*#5=XVma@>T
yRwhi? d1?ZN*\MXI6>jwRY\Ciqw&ycj*CE#@&q5tm=dIi%R@wBn5LHW?/<CqX$HKZJ&5qED^qYAy^P@B+!P=Bw
bZ$lnV JiABRHaJELQFZ%WVwyCEM&qdP>cWa1%ZH?>/N>JwN%!yL8KkdmT%M!!**!yi&@w=Q!Db8a:=5K<Fq<*b
^$At49 bG?=d@InQ<1$lZ$9H%@GcTFbNa?iCRbnB4cimbXP!Maepa^4M\6KdMqBt\4bI>cZ>tkuH+kp!bYLBHyD
B6VX*G VpMYL?56MKbm#T6uZ=i*+lJH9aylZ!/&wCmXGMDcy8LJ\a<%11/QI#p4G?lZG$S45E=I=?HhKyWVwJBd
\LN4Ry Zm4!+e@d5b>RMRAn:REu!#IhF/^bE^XT@qE9hYXnFI1416tm?A8&cXZhGC5:%aNtRXQeueZV/kuNnQKJ
14c:K+ ln9P@KZ#%X#&yj&V48eWAL!mk$jPHqENbtm4ujXZmehV#LY=EPpY^YI1Aq+dbpX#ZhuEPb\bX66?99w*
L^wG<* q8:/6JdEDJbl>=LJ>q^c8TDWVCiPZ8Pik/ENyjJKCq\%i+hm<l#V@lMhP=^dc@IytLmyGHlZej%BiFa=
hbLwNc hqbQ&Z4>kyVK*6dRPA$LewGnnKyNl8Vy<mKuZZ1#RGY=@w>Mk/Z1jA4YjE8?#MYy<he:#yJmbd5b:Tq>
LKpQuY M&DiTwmk<aSM?=MAVWliMAV6dAFYb>/ViCSRyBiFC6R?j%D#ml=wk&wqJYD9PSM%4D9/eh6Jy8a+hTd8
uam5aD M?XY!Ia!/>KayhQ?wt/nBX?mRam!Kn#Ienc<XYkVn:>$WJHW*S?*w%tPhj/>#Q#:RQ^nb=@nl4t+ANlP
tHB?MR EIFV#Q!StbB5+FD^5MW+i=1NG+MK?\1@uuMn^bA!w<=:>yDmah?!*9t+&*RDPn9:H+@1y^NL:c86A8?4
1#:ZL1 Wun$8><9+TGM4ZImCD^^1&d6$>Cde4#a+6RdHt^$N=KDEhRiVB<i9hFR&ll*nALmh\d&yJjKNDS8h@1P
CCaZ45 =VR1K8&n/R&SGD&9L&4tybhJ6Z#?!EB*N$j^9K%LLc@bHY$J/P+:?mW&QlEDGMmZ!A<BXBuc/TkCtb8L
dT%T1C ilWJPX9I\5d+^=XT!h=nL5p:15ynpS*m6llXZ8t==qMiCwG6X9t/F#*KThSV:S5>Qih\+W8#RRGA#*eH
dFR:1u %nlbVqGqLHN:XL/#*TGP6Q>$!mCdF<X9uWL1+A\ln6BP\BdtV1EM%>MNYc#E&1et^&QqIXtyJ!8b^dB&
jIAcqw yjG8G@VA!nWnpt14NnY1yQ6TK$qR&%F4j#RTbF9V/TTq8mQe^^#F^1umSa!cywJpN**I#T<SeqCwtQ^N
FVM:uT G?NnCJGG64^iE/diei>DRT45E?85:c\*8&$DM1+l1b$6tM<9AG6l%6TG%heD<u1dI=:Q?mi*B*w^<NtL
HRlS!h 6I?&NSju5CaJpL5/abadn>KMBFFSYD#9ZE16JJGWXK:Vi?m<FFl$/:RHp96#l+1^=6q!:u$J^D6Tq!B/
%q<+Hj $pjH9iuJW9ANRTcZi/tABCBZD4^$4huRGB$^Yi6\BqVi>:YB?SQQDy$Xc5&9dPF<CVyP5IP&&uZ1Qp6C
YBSkEp NnNMF9NepC@KTc@t4Mcu&HQ99N\l*NEpl:1c$<EYw9TYCYF!l\dQC=JGB@>8<tN^SR&Zph:YWh/\Ej@1
@WhPLG Bk6^^X/*k#9W1a:%5*5QYq48na8$nVmi5lY$DHHG\%kqyKhhB+ed=$cHS5S5:qN<$=a%e>!*b:Y\N^<#
VM+TYb q1w*n4X?e$J1\8Nt+ykann>nFCeYD5yVV^:iDNy=5QatLG*=?jH1c@hbjiTA6+IMZ=!?G+Ecjq:QjSa1
9\u$Ip E=Th5MhTpb#YHW/VQyeVh+4ZA6\C?Ru5H=\k?RynZ1P<IWnP@RVX+?E>LhZMuSJ/kVk8<<YZ+w8P@b#$
$=D:?D ?e/B%CL8R#lSW>6&5L/nVaB8e9un*kZTw1Z:S@QHMZnRRlHwn4@#SyFt\VI$jtcVpSt=6+*@^kc@WVl1
*@>Jy/ m$C#aZ/*dGEZ9y^mA>CKDw:Lbyk=%c$@d!ViyIy>mAVceLN44J1Q<X6DZAaT>:au\AY4LnMw^6MuuVN!
CDW5tR bw*KpN%1+>=/94ulhy/Q*5ebH$nG\DMkA!Xk>Mb&tI\ci=SjA41Fyb$n1&C%qc\yd:?Aeb<u@kRZp^:n
%\I/ld KEGJC<A^Qt\45y6ITDJVeLECKhVk4c$l1>HbDnqc^9BbXkkJkE:/by\lTAQuhwJN65c*#q@\yB#$e$5:
pZWlAZ e@Z1\*H+JMAY#P*8QJSt$bht9inI^\LPFXLF%588I@V!VYK/$DSAWd%EVdIB+&m^J%TJkC!9EqEtM?:M
kWEi<A P/JVeb#GH%MDZY^y?!C=i\6a5myR<^c>ECnAjAYSAV?i\ukQ8m=T=bLnqp+V?uTQ?4d1TWe%a<&\R:#i
lKIu9m py%d6H9BJ*$MKqq:*DhI@pu9!6:PGH*5I%B4!KI&CKF$u?Dq%XWXKKNneP9b\WEuV$*LlEFV4DGGIpCH
91yQnL GqF$$GFL9ap*%CW8N//WkIa9SGLy<ECJJ+%KaF1lFVPjl:?LVDS6/Vm@jcpR%:p4C?j^mD6iGhuG@Xy/
HX:m\Z RVI6HjNTQawbE8LetplP!PJdeC8$jFuBKw=Ln$SSRb4N*ijJ$9VD\$#69P=CJjcK/Z6M$&JnHI5d59me
@Bae/? +A<elBVdEWFKdTeYPKBGh??$cpPYpcAL^!SY?:AQ=CetNK%*pl+Yu&h<uuD>4Q#bJn/mq=9pMwFeECGH
=ZKdae =JJaFi:uuZ6HW/ZnN$H\uC5pnS&y9#@@GH5!y!SQj$k6i<lwbt9b?=kBkK@Xnq#Pma+MGDQ%nZdkp>h:
VH^HqM @JtpWIE$56\I#*#4BX9L*H=$HRh?k*TI6n%dAHbt*bCS=%DjubR4@8n^6Y!b?<j9G#5!lmw@6cEkCXcC
++udVk G>F&qk6Sc\cM+\1i^P%mteWXmm^T#GF18pL6J!aahc8JF16bH8In<P+9/4b?N^qLqajcJN4PpM!hLycS
iZd?MX %!qHJ*/KbQPWMG1nF?/uF4uh+@t8bc:GN91W?TQ4&5hJam9tb9eIG@hP6YM65kcFh$/X/X@$1*QHD%yZ
yyRecJ /Wahlky=^QDbQPSTD$:XW#\QC>6FcM!w##$@ZaE<1#!9cT1eSD6%cS!tmVE8!QQ5**YN9MRd6ZK#G5t9
w>#DYX DCC/LID8P@Km8A6>uN<XVKDZdlJ\bjCh6#Z!>epGV4yYmeWDQ:=T9B=wj&=F!DMa?nCbMKta9K+W&eNB
WE+?Ii M%HFH^Ep!XVy$>%XTM^&dXZX\G6GRkJP#naqnhM8*1*EZ1qaQcyb5@<tEK::5aC%P%59ViGynb$qERyW
A!6T+Z +lj8>4@Q5j9@1:9>:&Q^@wi:@Z6mX>HP$8Nj4A5l?B>G>B>F\ak@b4pn@nCpEWJ@D$Aa>Qh@F+d<QZ<w
-A<S6N 0006ef2fa7c00110333 Page 248 of binaries1.zip
uX^e>/ DQ<nn!k5@E>HYpDT^i8*p\PD@4ZES?nHhPP@D>/:5jp8DQ4BjEeI@=jMh<Rj=+\R@PMX@5i4$L?d:H@p
ZQl>R? TQ<n<@4n!L>@ZL\@dYA5>PQI9=?\R4>kwVhkaV<*Wu<e?jen?!8V@eiSj#>l\d>k+Z@P\lA@L!Q/eiVj
yik8i6 V%n+L%nEDXnIL//X<J?#$F?a#pKkQ&el9:nPRnjRFiRZ=!6$A%%BaL>kd/A4CPnu%$4wB44/yep8JQlZ
SSp8Mi +J5w/?jhIaTElQ+Cm@kL:A&W>c6cL\VwL:Dk9<BCduLu?Qu=It/kLCn5=#5DED?#CBF@N?DkaH/\4bYb
H#kJkN Jd?&^?@tt=15G4?8uc5X9/eL9/YXw=YuFd?%ucQX#R%YaeHjq8C@G/^kwb5a4AnB@:dkjneGj%8DId>h
qQakZS n>>n9EF5<J@EJ9S:dAlBIjk@nHM4C*hj%:@b=tdPq9>mbEw:thp=@qh<*><?96>9llBB+b9EJ9TL&GAk
\wX8Vn pCDpn>mpuj<6Np$:G?j@qelk9/$j$N@8=VClG$YG?A<:FR:/W#9%H/YIAm1@QT+J@9l<</@h*j>yy$J?
BX4tRu i/@@4!#^@+t!^FVkBQC@1!E/PQkS>=hZnuuP*^6SpjcW$Q#GInK5/qmKbaW+R*NcAD/X\TRlp>IiRkwj
T1JjRF V^^HpP@Cl!!T?M64A8na/i:hZ8ZGWIuGXE=^$jHENwP*BI&NTCK<RwjdE4F<wWk+AQacW/K*!>aC$N%M
N\JG\h yK+BR?i>Fl+nnSJuRR^FGhEA^\/C1P<GJ>wPSMZT$5R%+KX<$l=N^FJnnP$yqCQVEdi%EYulT*PSCpej
CH=\Vc +=$p!EibBI$^Ia@YY8i4c+n\NnqZIiQnSP48uNBVC\ynLWG6BR*9n?yKK#DyMDJ<C<=#IkLKwn*aG:/L
pMnaRq ??+D4ZNPd186h:R>Y?MGl$WSaA6>ARC/FLd9BnY6<+VBbcIXaE/\dp$pXqqyD+/Q?N1MZM5RyL\hVq!5
GyXA$h T!B*IBFWGTEi=eEYp<:*^AWBC8miN@@EcLCA*+ZTC+p>DlXh5t@%#9iFteZiEq%J&Sb+IDRYZmNp?bHl
:^>cWS XutL^+tl9M$DMttH&E*Z/YYkab?\14%RwSE5LlkV%hikTTidwkXGK4IAQ@Wb/inPwhlMX#<iHP6&>#h&
DLunLq !N+ViQLRhNHBPuYwYpj^wl<awIR!?mnV!MLBbpNSE#N&1kdn4h*n/t:RpbAeeqce#6SCwwYtMGSF%uF4
SSHK=m @>YbF//l:4Zd+lyCK+e&bMHmk4^+5%h*XY%^tuVl@1dcT*ahM4@VX%$?LTbjeTDddc=>we8/NhImiC%9
K<<Vnu kFeMGX=+c<%d4YS:+#PFanKn/!XmtLPXDIecVm/bll$p!WdB>e#c!QcCy96K>a@dHbW\X+e:L55?yaR5
u16dhS CEa=*Yd8QZ?h58FywN!i\\pQnI/c&XX*^F5pWXMdYpnK5VqR^uwJ#<tu/PTV/Y4YS@y+=<W><+/8AiNA
PLM=Ww Ta%^b>FYw$?jbGbVcH\KyjKM4FN?&pjGTW>NinjG=hMA+?QFV@t^<6LBL^H=SdiwFnI<+>!t*p9Cb!mV
yh%k1? yCVELiYNYIQKeNJBIFF&jem#FGNehaqeTVjmb$\?<jpY>i%GTS&IAZK=m4lWu*BdWXA@F$4+Il$ZkKA9
JdcJkM :Xp=XthQup5c<F1%AiDe8hHIcuB8BiP#D1w^%ueD1qqNbY!YVX9KM*9Ji%p@\:S$aZ4j+tCc9>1!/?iR
H\#$6t kTHtS@SyZ*wlq<1pw<nMLRTywM5RqX1%C$*pb^C#>u:FadnyVBkR!Nt$aa?jey^#&AiapC/LVq*=kEH/
/R@njl KWpkkln^?A5/HH9cb@#Kd%N=hPHi?iyd\jiYL@A9#pIc$ZBHEdAyG1me=!GjyaSkmD<V%F1Fi=A/4&:4
5&pV:I SI9VSXJtED/JtKFe&F4#5#8Z#b\J+Cc&EqYy8*^*8>n!FZWj/N=BYq9Qu5+Zi>dkSA!Fak::\JMe6EMl
C$LIEw J/p%wXt1D6J#JkINJ+u8>=bb6@Raebti#*LXDiA@%nQVinRwHHGJ8Nkk+!=^<A1cbh!Z&aJFmVu\FYqa
HBuZa: jMdY=A:XXnTlE#*hbYCB86W:&?$Q^P^T46$l!$yRWa1+6l@HZ<yDAQ%15:A6iN<W=duFhSn%ChN>ZKVt
1^yedk CWuJ$kNT!\!1+C\ppPDe/6Xd$qP?5BN*W?+E:X8\Ejtuq:8dnle/SK5?jyKiTJ+@1aSNmMZFG%&MuRb9
qNV^p< ^Vt*Q*^6HdjVwTqFnW1tM!hdZtppQD>ZN&WtZJP&e\%V$dPPC\%+Y?N<F4SWMpSaAXDWYkmpE^ny@X^H
j*Xqk/ @5=RY?dhRMWbI+n9:J+&<?J$L\ZXRb^ElXAq<C%WX=<*XVK^mQq\EW4LQDF5dEiW1bZjZQEE*&JRCD?D
RPQF>E P8>Kc85^X/GGckBk$$jqlX4%tPB/I?X\m$:R?u59:cmRtB#1/a1WRNGBC>B5\Yl^enD!huqR!AQG6ke8
Jn#PS: Tqhc<eeN#&w%EcHuQd%Cm+hedcN=pY#BZRNqR?WGXkR4a$Ad\^c:L+&Zi:b$Ik?M&mulRm*L:<>NPcXX
G#Yt^e w:5S^mTn!qWe66QjP15KcTH=pLNAn!h?RydK#1EYquFnL/qW9Eehtk+Iahd6>5%K%<$#E5t>HpA<<iKk
ZW:RQ1 l<c<k:&VEVK<c:HFth<eZchaVDX&Y:Mhb^:eB*Q:PqIq=ZqWBI/6F*>k@%KbR?elPp$<Ic#XMyHc!G?8
C\HT*? wqA8a6%=9yTj@u4pW=K:\AQYKA&k5bVM$QQnAD\58I:Ea1Yb^DHi6^eNX=@^B/i$XWaZ/5>=&1j>TC%&
u1Ce=T ^=/>QEKZ+A1Z#lh98!*ZXAj!Gp4ZRSe5!dah8dhc#/J8!*cat9%tAi@Viq9iF+N\TQ<>F>GmCib^*cV:
?CkXZ8 =#P8!ZW$jCD^#5dmX/@^W8:dB4CYLQW$\4D/ehuRe/dTX14=5@bKqJ1#eEmSY9k!ZJmW>G=kHbLiMP^A
&t*:\I 1bI:j6dmVT?W=WTb$hJPu^1En$b!c\lN4MDKF>MXVS*%>W4ui^BnKNauTcRe=jHj?yNRc%^^kuX=5GFF
W6ym&K YnBJD!@wAKSTJ*SGMy@:+P\i>ibH*SJ6F5lnc>PuK!&NmS@=%J4ial6@cdiy%WFXweSH5&^4nkRF%:@W
dqR&1F WF5!jjVc=Y8jmlTY>b+J>%i@8mlGdbE<54i!u8*+=<JZw+Vw&RpQDd>/uX^=X!iA5#=ewCKh4Lpy91=#
hHBVDH P#EK/BJ:Glpphu%S:5<um>=$EME1h!#9$K$+TclMj<DFBqTJeyWIH+@55=!VDEuqKDqXPjEh9eyBYj88
pQVa\A llJXl&M8R#jFTTRq!+RcQZy@IMRkB8kj9VWFBL48!%t\++\pIkZ^a=9X&NeHL9!HS9&J^Q!BW6w1%:J1
NtwJwi cCHKST4li<bP%4%XY6<EFG#L5/T^IR%aMR+!!NbH6lbE#JiT:kS:y\pn4k$8+*GK%k&:=TmSw\&eJh45
SPZD!e i#EP9ulaK4JDnL:FlHmJNiK8Yj/uJZ5<aa?qDDn:CQAQ9nYZn8EyuWVWpnT#m?NEqdSIBiAqRA4nP^eE
Cku/5> yIDa1ZW>+Xnqi6/YPAd:ST?^K>GK&\ypA^*bNX4ZD9KHKb#=HX9*+XKS#lc!BAXua9taXWHa@j%EBApC
/QlGq% up?\6*#qKA^n5Mu1bbcqQ=Ei$LZ8H&ZnYSMAiE84*n\h&LMwhM?VecM+\LMl%59u^AwuYB*4MdKb=A+b
pMpBVL C56IYA\hL!6KDIP+1EB=9lpewX&@m:CMkTRTyqH\#PI=hNiYq6Rip>Vk5c<ASq<wZFX\y#=Z>jG*5H\^
SlLcZw jLZw5QaC8WQkmI#Cej&eqL#%/DQc!P!Z?lY/*bh9*Kany+pbS6:l%NX%l&PWKaVX&u=MPmlwmZ>VnmtJ
&!\YJS la8NJhYDFV<8ndZ^9H/\Ncc5Mb!1eTR^cmR>Zl/YWn1GK!@XRdTekJ9cG1&HhJ!e+utIE&&FK%Qqb#Z+
nZeth: &KF5Pn^%9y:kTQW65SMjeaMl<Z+?mcRGZJ&:AB^^d@<V&hAIPa>%D5ea/REjBeat6wIFBdekQ&b5LuEy
jpMBGB 4<%=d4*=W<\qK9t4qjya1^w<AD:nhaR5$MIw4?+P>i/5C%CYl4hMPwcib4w*b!e*y#K9WGPF%*VN>Nm/
kkV5X8 5L/ymLn6R6tu495:X8WlLn/SaXTG%DpPH8l=!KMERRFd*:WBnmGWiC:*h6pk>eVbmAE\DyCapGM$GhNh
54wMeJ hmTXRJ:%Ei?G1c5Dd9R4numbyWh1<YXu?GZ#=b^w$dk?LiitFVIQ&h&mXlJqPknu&Alq&TVj$dFIZCch
R>upNQ h8DPXkQ$9Q5D!^WD4?8@nbm?a$lt#*NEc#%mwc>@a+u#FS@L@=PFP<HMt=jEq$#SV4eXDQ#bn=p^K%qD
9V1p9< JX1tJwT*KJIqLV<R^/SNFQt@1=DmmH4hmc#iR9yZ9cY**Pkm>4?9ba^=mKHEYwqXWhGBi+j8XE\K88yZ
FT+Tn$ VTK==+G6Lw<<M=jt>Jabjwy4?<%EIi!L&^eV$/%8/JaRa<PWkQ?Ib@IZR1NidAjPLWpbhp^^E8cZPFY%
1aTjE@ 1hkMHJ+%8/pj6Ra@%1<>V$mm+IGXK^SKJN^HG#K@4&kyPJEmw>mMXjtiZ9P$C+I8#$8EZ^H&aly/b&hC
6K5Sk> my$B1KWXedFqhGVWtEw4AS=kGGEw\J%<+ektV4aVVZbRRII%pjL6I<<TI@H+X\npMqylI6W9=9C#>pTY
9cKQIb WS@XX=/ZZTSR$WMML>I=Nwkl1P!qqMAq5Mj>IemZ:qR8IH!h@C#i8SM=ba$Mcp=5^hl:ZJQw!jKBP$E$
<mtLc! a$ImnGC$n?WnJDEGc@LkZT>TP=yX*E=Nyhl!Zu:=>YCa$IA:4Hp!\AaX@>GIcG^b5<1JNa9CW\!GCJ9e
Z$N\E* TH!+Y9%4a>mw8PXH6ic4<pL@GDc>mJ+A$%qTdh6EAnp@/dSDM/eh/dTh%4JI<::B+TE+DEY9WhFT4WYp
yZTI\q PQ1?%5T5/AuuX\?yVeI*jXnIQtiEqdPwVj#!+>Gaj5=pFV/y8BPX%<1Le6ajyePCnI:%BkTqBNq1%1XP
y^n8Vd 4TXNS5M6y=*hdiK>4b#>dPID%c+iM+^H9N%iN11EAj6KN5i#SDh#Dm6ESjp4QM>iHy\$HFye&BcwII5G
6Z#Y!K DG8/9\=qiEq%5=<d<GNMa:JaZ4J6\RG+1N5G$RC=GR6LG$6>w1LE>%b?II19^Nky8y8e+D%qN/q>5P1F
pmccaI #BTaIQ!Mcl9?hL4jnD\4ep4FZu*/iF8dnNnVL&^QqY$?D!<RLt<@+:nlDKk\SQcw8E<?DA*J*>cTmKKq
:umT#+ A1w#VC<ZWn4/8D%Eu#=9^eGVQLJW6duG/^\Be6Z#qu/G:pTEJ1#RF6J+<iAhcBkcqK=11DGP>i+DyP9e
wtDKZC CEINTn@\nZwd6d=@WId#kFNFIk4ui/E:RS%XIBYcm9VY6#puRP\?i6$DWAaKZ4G>VG@M&Ij4RXbJdEun
>lK6Wy EPiR?*1IAHV*wPdH?1+etJ!+/DcjkwCEAS>yLCqNlPcKQn/tYN#h^9RlSW*#NcIWhctL1TpTF@VI>uT:
QDK%ER b*uRE&bXclw=H8//SPM6cRp/=11=%6DS1aKY6EyFGq</MhwtcuM<NXZW6dlmHKYR^cCAT?e6EF1%Tc4c
1>95Fu tYG41cTTY<DJ\6?X1P8>cZR<E4jWC9BYNB=M4Cd!*&@88KBE$Zi9Y^lT5dRW^J#Sp!IiTyK&%LV%G+=d
&LYM^d ZXhMThKu?!KWdBR*<\nLQR$##heP=6>9uq^?Gkm/dn$6W4F>A/NtL/>^w6hmVDnN1:tjCMP/V%MV$1KK
Pu&X#m lw\A\XC&:</d</hdY=qD4J^Laa>\p4kw\5bFeCyKY1$IGqk<!^@JmD6IMp^wy5%+IBKqZ5ae#X5Tb&#5
d9uci> $uw:Kla!%M$5SlK<pa:b8a16$yF!9M@Xd@QyVhl:%6*+\Ckbb<j/plRH9*hFn5A%F@@$XY/bZq&LMK::
-AC8?M 0000bea399100110333 Page 249 of binaries1.zip
uN+NT% 1M:XjwewGwiTmeITQ^9AKjV9\?4?8m9&Z#QC@u*e*W&hJkVpl#JQBEVwln*w@yESRpB?Y1py@GNc>R@u
pWp84m :X?NwJ?uSwYlj<:?wmG#pDD5B5j>SaZwn+&kj<LCjy=G@4ES>I?5IPLuciRjG$H@lQ%F8:EjG$H@lAZ>
TiF&tb 9Fn4^$dRQ:I\^E>b^I?NwH@C\u@Bkt@A\u:B*pBZ5J?dhRnRDZRFFWd<uL&B41A@4$^FkG/kK!ka>uQ&
+AEQ%9 B41CRH@B*pBZ9@KjECDEZ+F9wC!lu:eaS+BBj+G>kdIEj#:ZFRG?!S*4F/wER@@CeYF@kSZ<C?^N:qlk
n>KqmH !M>bwd>\ZMSjaIZ@%%uIVi=aQ=>VnICA@\J:A%%B+V?@/$B8e5iC@j\#k5D?Am9+H&:SQ%9y@?EY\Z>:
VBjyI& VlD<:cuk>*$kj:lF@!m+?=6d>GMVT\RE@mj9?W<HCkL?+#*@/V4>@y=@hJV+>@j<YWEjBH!DD9/AHnPW
5pZ>c! dl^?cu\bb9TpHBweJkwM6HNlFRwd+Tm5+mmjNZh?Pm^kD#k9!BciEB6GXEaHGmGETk=K!@p<n^WtpllP
4e/jT1 IXKdqkTG1ld%JKW!T<By<Na5MynWXkmDCYSTa8JWCDX!JP*S$QLnY:S8>@TlM<t4#SE!n/G1QdPE$PHR
+JRwFC DjTD=C+IJGBWR^cdCKblE=^eyb$m5=!hhqHcS&YJS6aeqQIJeh8TYYy4b6!qPu5Wi#+6GCA1Fb=tXP<R
DiT&>T ShQI>D/A8q#LPch\nE^*KQ@9=lSh<:PR6bGAiw4amJBk%F5G+FX/:=XR?bVHVT6+ET!$6$T68jnV5QYE
%WyTi6 i\><\H$KnaF+iq68/$u+M1uQ?$VJ$WLWtIm1hq?&t*!&S#W&lN$N/&ie8N=I=H!ubpRhIa<L?XC9$FBS
HqK9>B IX+^@GaCXmN=Mk*Du8+GCE4e61eNS<@dk<Z%IJBe+W!>EtS6FqldIuk%Hk*H\jJ%>n$e6u=mhK^X1>:J
FWT8e\ EW#QP68L^IQ5u@EpiMBDihR5pFN*<V=L%Ek/1bYSSVAq15ERJ/ccSAn<DCSbt#l!kBjl9tt$mkhqKWQA
PZJ%%I ^/u&icYX!$^Z^\kal$WXWVQWEQnJH>XAeVCm%@\6yIZS@HCLB\bL<i<H^aWn\Ny$FKQKM!ddmq1m9b!I
9l/=V> Lpe6VmWQ#l=XAIGH$jy5DhZcc<H^au1FeQVG?AP%i9Re19FN*8+N=b1WKERjp#TCVBeKVdkh=&Y446nm
Mwl5ww %Y!?4KqCZ:T@SEa$I6i<D5kn\=6l6N@RTNKc*aKu$FqZN\>KJ6HGlLCC1GD9intyJJYX95&9P5&+Kc/R
XQX@^I *nb&c<q*/6<%51k&di?kEmTltymlDXqQRKCZmaTSQVJcmtM^ZayYK9VtE^XCh$l\G&5tWp<kbAJ$W:V=
TP$j$Q M6^J&6R#FTi^JKA/YDMpbqXG>QtE6jKc6VJ+BK\9ZD+%uGNTIXtSI4*6J4^5=qq@P\^Nyh\Sk%yJG#tm
*Z#NC# 9&%XkpFFbPE&:*FJGL$H9Z4lPQPMQGm?V%i#KVItYQM&q:nGI+YS+ej#bhSPW/b1aMV^E#TKw9mI\#!N
/HhM$9 L&^h=u8dSdM9#Sy\w!Ycb%=mWE8lB!/M5wmky\Y9j^u#uI>\LwG5TB66?=K*RT<uFuDwLdZXPy/M/bDl
KWEMLA B%mKl:!ZHEt+T?DZ9EBVe6d#<tq>cyp+/tCC=nkXJw=nc9yLPRXK>nh:TkIeA1J+CDIeHiNaIj#ZKbEp
#\h4D$ aiVwlpV*q:hbn=!@YV1@p=ZH<LMk@mR5l&\@/MBIDJuY9*SJmH9\W9QC@tpmu^BPWqb^MZ<W&ZTkD\jG
pT1hS+ AT$qdGw8m>HJhKlKWA4=tI1SWX9=mZmJ%D95jAeRInkH$m*w=#dVI&HFNeR4muDDYRcbY>YIj&1mWyuJ
!E@@5@ GjaSHLK4mRTkPKaQNVwP1IHKybD=Yw:Tcwi^c<#A1qaDNF%Dwu^:P5<tcppaW:T<qYeQ%mC%aRQMlhPM
Hupa9W tRbE>qGyY%9N4w6I69i$L6R@pECBdKGKVK8aIIR^pIN8QeiG>eR+Y>cI5&!dNy^kMwMpWMYT#VH4k>SV
jRdY=: =XBnkYEee5pqEphYyl/<jhMDiN8mp=1pM1CBW\S+m6\k4T4!qu?h\58+HLth115Kwe+d>pJ#iAP>epwl
jFPWq: 6tNi$lniwa%+VIyeGAX\<JWwYym9Fc*KWy!?TZdZnB?Tt=LN//W!9YlZPc*Yabe^L?!TKNP\==KStTMd
!c+D>\ NyE/>aE&R==dlD!b!$qNqh>BaKI:eFDy#^4^^TqJypRM=S\5lcqLcFeMXlSpHVnuenM#qcmNN?m$#/4M
h1R@Ve PwElhuhEPWMdm?##K&kSL/iTu!9cYw>CJ6Ntd1jT#Bu#SKn\ZbE6*iy%#<GYw?*5Ei8>Bc:R*njn8<&8
mWFkCM 1MpW<>XuLV?>WSiuJ*Tw$:qcZbE64He@:^Jti!1>FI:mycb4Jk%bt=!y=Sl<Vu8YB/wVJcPhJutNY1TE
MuiJtJ NR&=P+u>AN88i%i%j:/&SK$Ww6utpYJD$I$Y\*TZNKpnLIckq\:blpNG&m/E!nDG*DSeST&hll6W$uVL
TJGT+w I5SP@l!uipl8XMCY$ymuV6A=cM=6wbYc=8Bk5SnCqjYMTBQ*IG6Zu!kPDP*>54>A+=48^DR=QPJ/VEQe
pL*YMC 4BNVdwaG^IumY\X:P*wXq5#ee!<<puc#T+YXiCKHndMNXd8K>ahuHB*Z*6jaWyn+*N/uFWKXjCuPheD<
IAQp@P Pu9!!eu&Yld&/=q5X*Z8+#c?ZB#!&^GHeebPLCPM<:uN<*M:d!&K=Y6K4yi+tW6\iJaD#X\NNDY!6#I6
1VuIcI QPZmWa*N?&KE:m:dj+?1$++e#H5WTLyiw#wq^66iJW66RMTI6hmPuJF#dc!H!V>!wFwB$!4T9YXTd8=Q
pld9Dm jY6YcYFCWQ#AEHXIX4=#8Yl/i!w%Dp&P+:=9wMGLZCjWq^a=ECmjL5uEYA&>ieqMlHP8Q9^&CX%pQj1p
l=$C$% #:D/N4<WEZXwTA\Bc8W!LLI*>MZt\Wjh!keT#iN*cH1%ZLph<\I^/hX:R&Muu%ay+T&=TY8p/Y*ZyMnM
c\A8Hn BPYV<R8uWBKH/Bu=bdyn<4!w4PcG?$=eMnBmqu#QI=GeDI8qSA<kC+lhXm::yClQ:ZQ?MtVe&P+p9&G1
p?\@aJ /9nSywY^$mEYiBVhkwQ^4Bi@IqhNPTX1m^K9*4&>#/QjX:=6^@?^8eD<=<E9M/#y9GtF:td#%8Wmw@hV
G@bj11 <:M<QnMiN=b6uC#:4p&k:dyRnRYjiJ8tpl1G1iF6WL*BNew<6:I=JhLLbLa1:4aJ&phQY:hj?X1>XG8B
X+bFM/ d#kj+bA8cS%&>Ba#BDh1?9^N=c8ludMe$PKIyAYK/8w\Shdu&S:6GXpdjFRFi5X\4\?*HcZJbB/1y6XQ
:D>ThE Zae9=j45m=4eu=5Vq:%q+VRiNd!6&dFJ@&/j%uVDW#F<54&Z95IH+4MYmY#u^$MepQwA4HD9GitP:PKB
t=HL4B SjCcun%&n!?=&#eCZDN1Y%iBKQaYP6%bMN<#ydcDBN4QT69w8!bVy*8RS%YbRZ5KDV=9TH9#Q8duwWPP
b+Fwut QY4RH<>?&T!wL&1MYcVDH?P@Eh*papcCmquR:9th5TA<@G+/bb6*AmF4%b:b8mTY:?dl@i/e!6i^6*eD
EFcHQB ZT+y*QL9wYQRd>#HIZiuK!:S4E#*L1!\N!dZ5M$w^u@cZCTjFHWyPQCFP>alSj8Bt#aRS:QRMh9!yMpt
L#+i!h >TH9^aL=@CSL4^?I#M<JmIH8LHyM6Lm=lpVjidDFD6*6nS?pYhwh^<G^#:iiJEA8i+ScT=W4tW9dl4Ba
1nip/N c\YNE8T6ZlS6JWd^h9WdneT?uAMPb^^D<w9YQJC>?F6GMty+YANZE!F4m^n?m^klm&1M\E$Y6Dn@Jbq9
n*$XI: $=\ubWe\ZH+GJ>+MBI?QG%8mSZ?<yV#T\eyXKV#XC+lnP#q1c%9tHLF<\Dy5&d6EkLL/CSl4cY$!8=M^
%@dKaM !l/DmJByX#&^C<jynRkLe%^N^WLP!ARhPp>@5/cVPq%dC!e^eF*Bh/B:SVDb1>dyhMdJqNlFm8MV5bPC
F1nF#A S$!ZH>FYFjbFK#c*#JJ:KdFtPFFWWJ=>KJw*qRCSa6Yj8T>t1@StqH&XICGp9e?Gwme1aTlIB#&Tw4yI
+5ny1! mQeXSTY4nywHFdcK:bGiYV^hmdT*J^9#J@d+heih#L$9YY+^$5M\dduuY$SdCNQpC9#yLjdF%cta6@JT
PLRm%1 YYMZ1@^$69I/thJKTtFcciMT9m=N<ki^E5X4Cc1kAGp5NYt$JFXk>H/aQaVM1IL%hFIqltDTcDC9+IDG
WL5nIh il6D><SSHRjN?%FMLmA?88>q1aIBQN#dASkWyhL!nVQ9dGe^lE$Gk+SSd@^I=ak5JhK!\GFNZcW*8$En
We=^YA eGhSu=5CpSAG6\dbApLP&DQP#kHpjceK?Nuw6leES^*T!K%NqwnEGHc#YKJp^ui<8Hha=FmNHlYydH%$
>AXG@# q>4SV411n=%PQw4%huJWp+e@=4DGm*b8H$y?W4K+e6CSj:=ASHK?9ipG1tR6/ANkd4$DD=XqKKc9YBwK
Yy9dF9 EH<^=HuM+&kmSCCYplSSAIXhV/$yNVKBFX##4j9H*#G&u1eGcEyWACqY#$9ma>cYCwy/FGtT6=4\HFlX
y<Vu%A D4qX$K&q:MRym=wAl#uc<8+^epbC$MAaZI1Wwm@1w#RX8M?E=C&h<*aT\::i<mmJm/wR%tkZh1BFnLjy
K#1w@? >E*YN#/AA8yik<aNuFyW6yc@P\#c^ZbeE4Sb>RFE<V<I8ck$V4<Tm*FNG#yZKppR:Z%8aBYTyJI^!4i1
yhZ55> yKVQB&&?/%Gnj>bSL>CRA#kB+8#eShjCe^lAHmc9:^IbYNHBHTa4bP&%BiAhNXIaiJ#N#G*dkDMKZL$i
Ku$FXy ycb58Y@uSih4QGVnjIMy&MHR&njn+Bn>wYBGRK1iipFFVEuCqBeS*mc%<4lTa+M1?P4FcKn<j6AAGJkT
>yiybh yHeBn4JN&q6*m$paG>Wj<u+:e=wPK<Lj>@Pc&qbTQJP*#Ra*WKu!\=hu\ww8/wbG%hKHZh*H&Weh&cVH
A5hL%/ =a\9#L9QeaBwMn&1C14nSK$>%tiaBHH1a:TKy$j!#BFqmS>eeAkb%!KAHXj5KwmwnllikmF4eW1QuKk<
>wWYZb yI%6#Ij6jy9NWCId&FYbC#LW$awRG&H:TCMB^%6K/!\l*bnuRqFb#MlNZ/i+C$k8ayhk$DjIj?:GLWXa
pqCdJ6 C5JGZIW//nb4EYBQS6Wce58?b@RWXHjC/$FPP>ltTqt4CdqPt$ZBw<Qphc%DitP5wG8YA$XNyb9GVHP4
T!muJu :h458TmL#?69G@h^qyikcJapGEjR\K%NuAkalPR>YEy<Zk@V+I?WhiILeX+S$n9pE<*ISEa6ZyXk=RKh
QywIuA <ijt#Mw*LiBc\uQ%knwe\wwB$uCWqBa66ePk8HS8ACE<QElejD6MMWti?h\ad6jhR&^?D%$qRVXMCkkc
P!WRAZ iMit9yje%%eVi!u#ESm5GV=k4@SRm=A@<p#R\DERk%!q4*N<!NJC1:J1CELlykE/=*VViyiK^&tuKXN9
*aI\C1 X^#utGaik=imEj6IQndHKRHuZKhCBFh5@XIqHp<nHG#RA$I5PeLKdjW$4q1N?@\X$X$S\NnXTF&^Ha^?
HnYDc! /eq&YXcj!eX:ESE?DqX1=&^<dLAFnQq:FtWcKTT&WV4t:PYY#ieAQQiDD$4Zq4&lXqNiK1=CRAeSV:JM
m!TyLu Y>H5cui5uqJW>CItFEhMhB#G9k$Ve!@J^PpM/dw#kmje4CbSSS<M!I%>ZiNqtj&RG/e!H<11B&qqRlXa
:^$$mb a&FjbcpieXCJJGS>\1H!186\X*B<q&dQcCHB!4c<XcNm+1^6^/>Z<?ldi\c%1ZQW5$Gj\$iLFcc9mYeK
C?>16S Ku^+6<<ap%TmVS$BW9j*LwcblZSF>FVEuC9LR/%TR@F%6em:R1pwn1a@&kIeB$jT#S#<XZbM+M=hwj^Q
-AF\wX 0001a5d843600110333 Page 250 of binaries1.zip
%EMyFj @h*n<Si>V*l!h?&b>+5VV%Bic$4%SeA:R?NQD#MC&=*HJC:J*db+:K\8STj>hMJdmXW!W8jeZPhN>GZC
Th?<KS DS#V##>PS>Yt&bVWadESqYa\S+/duyap8ADB4qZGn!:j8XqNS&GqPMTNwLB?N^JG\cBa&!FM$:4c\&88
M\wIJy 6Xk<ZY+m9685uWlSpIyuuD!c+FdiE*RBEhhwtQMypcJK9Gy#Cu<e*$jYI*b$K>nH@6l=/pGN/V94IKtM
%VI@&d mBM1iXLB/&e/:4yWceVP:a@BTMF=n6SHV+K>hlC5jeaI$L+*w5Jl$&I<:&lp6Q&n$YXM!RHJy@TD$5e<
F/:R%S nTlF6u#MDD<6y$JA@w<yy$JAlQ?ZZCSB<A<8pmDw9%K9lIAl@1$8/S?yu9>IT9*a$QIjSX^@Pt5V<YND
uHVqPQ !^@bZ%lKmB<dY9:I\u@i+BH^a$QLu:BC9&Blj<:?w9pu+5iGqn?!5F?^<B8\k4>klY:Aku?i9Q?^wiYQ
/!Gn\n LFVwF/#\Dhmjn*NC\G/kK<nQS%<laDjRFRV&C@aG891q\\K:kdDA9@CnaDeR%m@KbSC\G\kL@w85M8\G
TXl#*h \91F#+tA*WBaEKGjb?D@w/Hq@?l%B\QB+ZB?TX9Z*\5#?KH@dE#ydMp9:YNlc?b5<@8Q9@eM@C@Wbj^?
Mb@#VK BlA\>Li9=k$/XCL?9YGt&n@Q/u>Tq@HQ:Q49YZEl/I>b<Z@6i9uQ4Qn9%aD@:/:L/Md+Y%$GH84j/nK\
hZIMC? NyJ5i<$=IVE!LKnmp@5=%LHl\BT*y\kILR+GAJwjii?yMD%MBC!i1GHMVbKQaRnm^udwDctF8w&^T:Ip
N&wyp% #&MRj*wSSP:e5DVae>8+lhm:jRGDAdh*GT/ew5%9yWVE$/i$6ZuHq$mH%\lW8kJb1^we%KB8ZC<$wRai
k&M1n1 1?YSSTm#\N<kV^W6wjn9Q46l\ILS%cb^VyH&e/?PGXjjIqGSd&+*1T&#$uYLI?*JtwI6aW8aVL%GyT&T
9JWK6L YK@JawNSuyCEw^WG4n%V%GSwFiF=%5he+&!kRSQS=Y4HD8KqTT<JH@a4GBJdV?G?Fl9%cB8BwmJ#^!W6
CAmDp^ R1ZwaPm8$%NAM$qDZGmnyEweAF%TclIDLSSP$YMiNA>JAG?\pcktdmkK+TZSBc/nKmL6V/4@w>nDIek/
HQ<F8A :pYMNPjHq@9QtHklcilZw#%MnqP*%a/^ZITW+>LRJ1R$&\:II9pTB#Ckq&HLRuGd&SK#LSIY\9w6ZZu1
MeY!*a ^k9%L\n9SinkI1mc%b45$B6dQPDW!m%4Fnd+V1S*>RHp#<TE?>bSS5uG$FPEdTVAie8#eGXS8>9Rc8$y
XWWLbi J>YYF!<\nBCpXyTne#uME?6MTEMj@e5%>ak\hKeyP?YYIHZ1Fbdm5EtAaM:=qLlPt#y//&M?N$>neRp&
yju<9J /Xtqw\11TJlQGVQI$X=c<&YXFiK4Ew!6ukAPjk=@C/%:R/t@y#QKVDF9EVSTcDX9Ay@Tu\t#<>ap4VTb
8#8JQP 6nPV!T:RCZcpk+dlm?ZZT9:i95=E>&V\Np^b4chb=+GuI>ui%ZPl%9lCwpY!F1nSByu8BWLe@YlBVEu$
aI&89n iBN9j9FElKE>TjB$<Z*y9EYb?G%Jy#yDG?j5FIu^ljuuHHwu^^V9W?^R+:>n&T<<J5>AqenV%qJ<X=AJ
uu!ECb 896aWd*a^QY%N<XM95^t>eh&#CTV$$BJ:j8jTJHmW<A+:cYyh^i5hnMSkYGDm>h\&X4j#<4QHT+e<*NY
#l#9eb pBNyJ&>thX@iVRaLp5wP#:uPT\j89W&JBVw%Z+6!JEdu&nLcHY1S*WFcZ&d=1eJ1BRQFhuM?ttlt\qZy
WP6d4i cQqdb#?TH:wBT=KPP@6uAQkTVk?A=e*mnMk9nDV6D&Kq6!CeQDlQLa4lSMcjJB4>Mpph=IAKX$TTF^?#
j<<R9N #Y:HScl%WIuKYZ>N!&GY1Fq@DW$$LTNbn#ZES%&L^ETnSXj<:md@>TM@F1RG*>RGMGL5GN/ySmIJE^A<
#:kj\J ^GeR*nSyDJW5kQNN9lEDEm!q8#4dHX\K6*+<\YGb=HS%EF=B:Ca^+/*ZC\&QDe4hJ\td*<>LkqDk>qy*
MMqbn\ jB4Gd5D9T55ZjE^NZjk?paCEFVa+Z:NcwQBCbcm=qc?*!V1615YBmR@JbBFW!F^=S?#M1PZ&Zy8%=t1b
pCN8ZF !%k/5%Lh%q=\nH8ACnWM&TkY%?X\4y$*P1&MXGNI::DN\8%dyQt\hcEyYi16Ih:VFEXMWymK1e64=hAd
#M8RSF VVARJ^YdNVpqtdWy$q\!?nD>@jwY:?b>5m&MWh?b/8<948Vt#LZawP@n68<CZPjVZV&e%CBi:Q1QyaKS
BMdkE1 @BmwnA6n84Q$i*8epVL>1bG5^lLm/B>VaMWH@Ak4hG!npehD1K9QGqjL#d9LkLLX&mGlSnXWBlGJ*QPF
+Hu>@A thhknIXX^%ARyKm?It9l!R95i*JPkVDB?BdL&@kt&t4kt9DF?VYNh*=h<jX6&^p+P1/i!y=L5XyYw*H&
6da9^Y AX:G1K@:F4#%nR<i+P5*e=huu84VXWl$tCPDlP6Q*@Vu$MQ6<KI6IBVIHdd4A1=wp>!K$DP\+%qcYV+B
qy@FG/ Vyb<ZtMK:H8I<<5=$iaG9Nhh:<AA8TepTN9WySi=\K8Ry$<nuNS%y5hL/pZ!u?el1hd$K$!PM^cZW@e8
D?Ny1@ 4P&i\Nu*HdKJpNNeXuMlVyuQlHwS=/SPp%dV\XqwMXamS\<?\X1B^/5GHZae&9MEM^JE4?am#9cd&P\Y
/QX5QP SQd#d4?5hXc$Euy<pNlk&wbnN>QtcTj5q6R!GnD<@4aN^RWX6K&l*IuEDG6ec\=P?%l/yehSqaV?DuYj
yZJWnH *>NW>BXL=dmlTyu4ci*j>PdSZ!G!b$hhI>L<kKwntHiZJN6%K$9F8/FW#46eJJ8p8j\58VQdp9/SP\G*
eD1>*Q VLZ/a88Z8%IL8cIDbp>iIIRG%<EuaB&Hq%^LKc61PB%#%5YN&JpmwT:tK=%RjlhT*p@GcI%XPjmwceQN
*:9\ht 1WV6aBY9PQii8!FBea!dh%REE=\qYIbI+tae#hMj4XQCEKwm&$@imw?=9ay+kuA5=nFJV&=96bGjQ=51
jKPLkZ Q5LL*+ke#BHLX4b\u6D>PLt1L@:R^6A?VHAXF5GuF4G%bnWXi\81SNW$X6j?EZ^JBy4*k>DPF:$ipQ$!
huT6@P uWZNcq9VFCtXiYhPG?9$6RiYYcB%:+wqBljGXjLM/whNkVLZH4*J!6mTEd1JKc8e&ANZD/WF!<XZq$?M
/j@Fph b8#jJcjitVnBaLdn&S/edDTVQGZDJ@L8adS>FmTmF>H=mP4SjPLuX^:HX8hX6K*pV<pjkHRZQ&iR9:R1
#Q#AHM #ca^i#d9jqRmi1Sd<e%PmCP?<RuyJH/<SCbTZwKYT4<mG&9/whkV*y#Va+*yujLd>:Cb4@i\HQHne^c*
89#ZRH ^*QnDS=ITpWZ1F><+K/c<4\#Z4a/#bKmS$$H5>:JGea?q=ja9S/1PQRLhqkiGKRX5Qdeie&Qq:pk55Bp
aVPy5W w#BbZb=@5jCp^b6Q:JH?</Fb1i/CQB8<i@MGLZY?#4THGy?pn\IiNqT5uyc>C5Z@WHhdRDi&>?t%p<Xl
QY&EP% &@iLFLeH\k\yHmT4wQycC/8=k5kcbdNiZq\5ityuH=qet*XHnHi:w5XHF5wi1:=1P=Ve%N<m@dMuG6=t
\#KVBk $q#Y!hS<!>1$Ni+nF>WwZ5LJ=*lQZ%Cn#Pn$%y*L+P!\9MZY4Z+8PjJ!mW141b$kjP%Y+Y4VCb$y85IY
k&?>ZQ AT6eSt8@^*!d^hJpm&/%>nwba:u5FA<A=B$qQH&N\TDN=u$ajjClmP/DFRH?KdjXql$1AeEtm?XZb>E*
l/lbm# YDRNp+wA^ZRHjuwA<k%?He1YC@5bke+ZF41^4a+!b*M4wIIZWSCAWQRDaSWG!ptNjd4cId8Wep9hCJW^
XMnTYX +B8YhbZFY4hbSe8uApTe+!kjSlljYBS4d!^@YKJw\RY41T$H$q=#1/B$1\R$Iw^b^S9VQV8PXMN^Ln88
yHq9hm SXM4^VMR<HHCW<ln#JMaK4A<eE@qKA5Kh*Y9JRmw>dN!#nXP:MD1a=A#=>Zw+>TR=6eEnV>k6FiwY&/S
6??1?t q4NS>FE5?LnDb1ATmXVtiX=?4PSS68QFw$%8k^lXaB\M6W#9$SK*Su8Y=D:IPG!<:#\SW&V9<D^Yqm:>
>q#/eL 1Kl<dhS:eM@J/1TTG^Pu<uq/$XZ9IVyF*lwk:+AA!L%TqYkj:q*ZX!NSe?FSpa9HG@mlWt5IW+DmHe#J
nl8RD1 VehywuQ:>CHNn51LJM@ajX8<1Tkh>uJ1HEwG*EYlQn@ZKb!lH4tSRW5hC/NwqD/Kc4*yma5eZy<ZERQp
I/>+$B nwcM/n49PGahPWTHba4yHR%G\/j4a^&H<CRG4Rj*LPTaiS&u6/*9JXK!Sa/Lh+:htkc\n?G!^@Q*1/T^
9h#*Yu Ji&W&kXnTwQJC4eWD&K5$MYkF9JemT4t\A$>?*lBlj=uSWLA<DiBFR#4wYIGWZw%NqGS:5@6c$5Th$>%
%aDJi> C^&D5d^l4JQQ$K$\CH%!&TNMCm*wLPT=4RKAqpTCW1QKJKeXAD^J1!L>wT@V$/5jPPS=FW4&?eM?QEw@
*@G>FY h+YXhP:n^9l\^VLeJbwim/wt5A8LPW>Xak\#q^5iLHhl%KBt5dJQ*SV4K!quikh#cInE&XuV1Y?!uMy=
/e^jyl hp/!imR^4?R+aNw:ZhJI6=*:Ilqn\L1e@YR+$@dn5%KbkYRAR%KJp=9>FZGbW<qdIZDw4Z$:6mtGcS6%
9l$$IJ N8A#Nyq16lRnl+M+?4%:FGXHw#PkMZbd/>HqL^1Jmu#y68^Z6qaZE<NNp*WK=uq9lH4*thDFnLep*w#m
yj^Itk lE$$ydAhJEZY6J%@FJ<+yMQR?Lyy8Vt^$%:X?Y&IGK*WIQ$CT=jLiV$1<V$84^MIa*Q5Ca4>W&tZ%?m>
&*tad\ K&l%nFbny/M\w%ECWR!mM8*lP8iJBaqJdX\dN>\?SubR4!lwTP=$qH*Nt5jWTLMaicekBZ?4A4Tb4Flm
9!D/:F J%bIb&Mjk*X5D\6X1uGFHhRwaJP>VJIcI*Hn\TQt%:DwI=ZAJE*NMCm15QE5$nI9P9N5^y\<$m+&?X4J
ZIq1$* Y>P\F^>tc/GRc^CD!q>pwqj<4Tlc\lmZ8bqM=V*:lptaTd66+6Z&6>+aBqYL8%nY*PddDtyDBJ@V8GiJ
y#T$wW Wn@\M+pp=qw+EEEQK84h=6RJZRuM&VT%XLG<SC%Q5Bt1%q16jSV#:QS\auS\<M^^tR5H1km5uB>IZ#^n
*u?&J# uaK\%\!k9NPd\cTQ#?S*@\+8pmKawWdKV=9nnAjaS5A%Ku+VCH%D5WA=w/SZCn@:ZtHcjF9#e>pWE4Yw
AKaIh% ^KHJL<*cuZBNcqCJEWF!nVtLV*=Fut8SL:@m?YW5mnktF@68:\G4#$hJC^=u5R<yyJ\lSN8l6ATq@lt8
l\:6*M B&YN>mZ>8Y@4l&FpGLCkA@jmeajI1uecJ!@mEY>Mpc=Y%5yY%paX?NdVKm4&T5jHPQa/i5EqFDtQ6Hw&
!G/DL= =iL5=nFR5q^eCYyINySPhe4u@S&G>VwPd6qkE>8pK>V$N#LDm:+=!+YqF@qh?XwNYud$H1&Gu!dE5Y>4
qaNNiH ^G!j?wmy$9pI&yb#H/m+8M+qmyl6VVaWJ==4nE1/E!6l*NQtWNVde%ID&Gm\5#iMEBwWP&kLcFSmJSdM
eH\keW aX*5dt%/&XbX<qd6EbWQuCyVk4\+1j^ajN$VA4CcNX$Xc1Wy1iDInjETYFZ9QjT?jVX=RqTq81VEGA^K
?Ne?nc R$/B^Eam>=n=A/kAn&9FpT=RdKMc%*u4lEDl+n#B@&Phn6>pw+?Z&wiaR/RMYY*Cm\eqXXiW#Yw!NJ<j
>1cX9# l#m4NRc\S*1>p@b@dGG6!t&Mm?p*Ei$n+Ft=t%w%&ik*B*kAjmS%/j>I1$q4PPcBJh!NFi=i<+Tcu>*%
Gq/:@6 KuYFt\TLuapNkKQTV/aWNj/^D\eDZ&eqd<*X4qhtP$QFuiCbDPW>N^!@6VX:Hi5uY$KRQt1=JF:EdK4e
-A/HCY 0000f35ef7100110333 Page 251 of binaries1.zip
5Rjyu$ Scw<EttEamY@EckFYkW%XSK\dLYGewn6l8C\idjqVeQGJyn\jAVHHJHdD*R6CbY%awVX\eyuIE$AnMY1
EFk#QY k4ZVTtWE^y<p$>&G$<MSC4N/AC8$ay\G+p$+MMXKIyS/PNW4!5@Ri5@%But>$=SCHQqn9G#hlI>1+J48
y\!EdX e&Vt#&btX^TKGS\VlA8Sk>B=?<GnjQCdZ4m%eyXpe5tCqZMc9b6D+tGP@95HRwlnitGcM</1:St^kHH#
LJD6k& w@iVNT=?PW49k:kpbQu>k9yFXku^CiH&J<IPYKH*:k*&\9qDHK5%yQjCZuM#&nyw?Ie/Q4Ehjmd5+aP!
@didEm ?m+#eH@Vi4^5JQMh&uGQie>l%V:B6WN:maipCb^#QqB8QXRNqbnV$6b1Y><b4$J@mLmR!J#wjJi>Wq%t
<BK5Q9 /!neKWN#^cj=wc1HlA<eFR\q=RjP<I@&iF98k/BW>@TJRZBWW@J9K<*nqqb8ZHM?8nS<y8:#F?lc^RhQ
PickJM >J8pVYPIabhLST&wD6kTJwYYBH/M=ie#SZ$BBu%SXXhEV>^HC9Nm>1<?CSd=Fm#j+cwBe>QIFl??KFdQ
DI/^lK MNjBBH4DG18+wI9aBKPTuE/+CY:uBMAiY4hu6Ji#Z5T>Kl<6ESa^Q<@\@@8pn@@t$lDE9$@#8HFTZ$n\
$\9>Py l/T?EP!tyTF@JKZ?I>Wq?GQK<w@tc*?ik^iE@Vu:1>!@wPCj5*DEL++L9\H:m>!\wNAN&J<Q+EIIIt:A
EH:8Qm ku:BC9<=K+n+PR5H*aCF@+IF*+CF@aKF*ID>^dYC*$BZ5F><S9Ad/A4&1?QiRFjRZ*k5<B9wC9wLn\X?
=FW$&Q A%%BjuZeG?kKA9&=V\K@kc=?/XeI*WBa9@IelMA*8Xk@*@W9hANl\cG@PC:$Q*L#j=D@5>#<Q*cy@=/d
HTa$yM F@/^J!VmZ^9K@TM*D@>>L6Q@FTNw%Q?*n/AyNMRIe$Vp+tQC8TMb\lt&*>6jJpZGQ\j\+KKaZ9MGca^&
m=K$le <TtFdFFFwCL*SQmaMm#J<Fqe^>64WFFKSQB+5ltFCSKNcQwkw#&I^I4kGIuJq9W/??RZi!8HKD\<%^%j
RQT%@T P%ZyeB4=WP$QZnaRXjE*A<&RTE/R1\MGdVmJ^B\\DB&KTSnPXKatXPjP8h\?&JPN#\^AD%wV1qt*heNW
u>&=bd eDTjJeMLS661Xyli@pKG^!K*^D9ak>euml<1%><%*IP%B=6A>%q6qT4QmKWyieiCVKlTKAC6=yp>K/YI
\p\!KG 5PP$VP!*L\mbiJY/?c%1RJFVnVY&C$ZnXVn/cB*FWGkbE1dRYDDhR6Aqb+E>hlRp#k8EtK/&h^Z!ci6w
ZuGP69 u%5Ye&w:YDLyAemL1mDX<#kdSEwPTlpIk5cPhaL\T9PVbLq=?$%l<Q6m4DdDthE?:>htW6@h%ZStPX8H
W<J>Ra Q#SH<lk$tCJj#k9P>nk8#@Dhl^u$<JAnnJyNi$ZDmMK4DRVt?iJdeIkpDnm%6iVI<1yXNLFqeEKaZ*:4
hq<Lqe X@&CX5y%66yNNyVTMW<GG1pT<A#QX=1R5QctteP8H6hVw<BAH@Me%KQP$?kIR/j1MX5NS8pGV^^=WLMV
w>6%T+ &Cd8G^k>T96cJ6h^8X%9K:TDAc1=dwu#uFP<Al9LK>Fq6<qNy$=plXNjEXa$pNF:61nN#V=1YH*t1kc&
8N9yTY $ZbPaMH#VX:K=W9=cMke=*?Q/jty8I#LQZ=9L%$i<\!SdY!n66M!e59%iQp$tYbijBEC!kH#NmiR:h8q
$A9&D+ t1Y6S\RSGybM=t>SMatD1lZDtHV8j^nVj?F/H:/me>?wu:Ck#l<\JqCw&K#L1Y1ehyay>#KB6eZpbTTW
>B+^=+ X:\nnQ&FREb59cW@ubmbwX^lw8h\\$FKEDW9:8i>wa^Qy6J!4&u8#tKXQ#XLXi1nI\NRdJp>X1A*n6q4
KENCey E>TKwi&^hYK&*?681^9MJDh<=mP\Vk4B@Bk$hy9Nm:?cnt#ZTD>Q*p/IW+t>Xdc*?5$p^L64XKma$j16
*k+dpp /dI%AHYDRIC>LY#b4$QC<jWciE<b>iuuem6R$+6$BJHJtuw:lGnP5@$?/%h6R:uI^E@apWkp/W1uy>8R
?l46+Q <ahmG?:>J%Kwh?5c$L4*1k:Za/!BmhP$\w<HCM^Y:\BAZ#Gq!CcI<XkE9MPL:YwnRk#JJD>b9D81w$<V
kDy!wZ SmFeX@YK\qcB:J$VEPy^ak@/?6ip8S8pmLlaM>X%qtE&e:N^JTy8V#&8Snu=$1PAhPSbJAJ$1luwZM5D
h/Y?Yk TJ/R<%ld=>NB:w6ZBkQ95wVkwF6YKJb9&N$t#+9W#\a19ReD/%uJZwSc!AkMkjnSM8T?QdyR+!A^X$HK
LPuRjl /Bl56q6nndAhC%KKGFqK!SpDpRn?!YFe&5@l&nH6D*k+YD6$R#/cPK9968?\%%P$Yh*#\P81:N>/byQu
pT*kIe 1njF^pNXpuqu4@51*#S@8MmA=5Xc=i+>ljtWpc$GA1Y\dRCZ8E*S$B+YbS!ytZNF1kD4>D9&k!9hey15
Lm:h!p cuL:F#1l$4p^\^=DeAtL+BHYJ?G&NRB=PB=1E/dZ?Y8MTl9&HRbIl>KSnKqAbt=&Pn%ZNqiScCRkN<KY
CmQVJF 6T@hX6p6A#B=TtR@y:S>/SLlJ&TkciFbqZLHkBIRJ%PF48EmQh8uNFiZG<4uJVjd%w!PhE!!T*=bjbtJ
AY#\Fa X!ah>yLZHn<VX>@*ySS#N=5!6C\69d6WWWmnpp<yu1kyY>9tky#c!\na!GiaD@e9$SRQdFS+#eN>cy9&
wQ?I$M ?E6SJpETW/nGwe5?dAN+u&IDX51iR5wnkaE>?It>nP1i5:BV/1PRP?%FLC^GtX/A+Vj%+XBM=b41Xj:!
yC\uTy q$BBukh<yyd#\hG9l@J9y+i>yjdKnH=m<+d&8*+6@8S#^ak6W?F<F6#kAQ5Ftm&\a4A9WW=y/**jE6Mh
B^N!wN j*\HBp^*bX\e+WkP?Zy8DZi98F:#=$Sy/R>$8ti#<XkhQ8/D?XumymEJK+k6#XL*@F^BQ?9YwmZ=umk9
?Jb?6k qhpRp=GLNhXkcWntBX4>lK>#CqWilB@:$/iIGFYad6PdLmeb6>6L=tNew4hWCdG^u6qRNC/\=K6CeSHt
pGb!#S aYhJbTJKYd1%*L*:uJ4BSiwDB#EWT@+S=KQW4kdT@hE9FMP=6B>NKI#EG=h$EA4NGJ#y<n?T=:<QiYL!
X!=<jn KdVKLF6B^#JVdGcMNDiNWu1JEq11N?Rnu^epWwi&YY/Lymw*T&!4%j%X%5DAHpIYF<wp51L8!KCuW$t4
H^tSQJ yZZH<bXteiBMp*9u=lL4IMEV6R1FdPWy!+X/8#%4e=yG1?w+w+q*JQP=1eyZ%G#=%eEAl6J!@EwBC6aW
AtJ!!p AZbCTbEqu\n9AIK$XyT!@AXZZt8GGW%q:GwXnY&BGQd\jjmYkj*ZB*y^n%XPyJpM!PKVJ>uRXX4\dR6w
4Z!Fnh :=8=XC6q&H^F6YmRu?uImd\n!NN6ny661CZ<bdYeZ41Wi^a/Mu&F%<%w6bm1*eh15Qwm&EhudmVJy/4b
b!bbFb +DM8mab&hwkjY$9lm\Mw8eFl6q:lXucndXbDR+Rw*YMe!%AZp<AuwALFQ6/R:@4&JdnkqpQNecK=^H%H
qNyR$l F#uqeyp&u>$>$m&Z8Hn^JtDVA69!N@uS$T=$%ylphwe$Jj#w=p^MdQtib+<hKVC>ML&L1R5W65=jAtA\
1ey??n Du=cR!JGkt>MD\:LFk+pd*um%@SuI^Sq4w%G58YGW6K/NaNd>PpP9Snj61ai&w>pK%N$Q8Yaj!5MVJJ5
QL%8ld FFWaR:bAA#@hYVEkDVnt69+!4EJ49B/qK&@\DVbAbB\+WYSjyy#J=qK5tyKhb94>%aGJVithN&I^!t#D
A9&VGe >b@RGWFTNN?H=cIq1bViVVM4GbSGMbd^NwpQwFp:bmp!8kdanhwq:Ct#jR5F/H^TqjNtHj>c&!biY\WA
J@SQ8V 8u>S<QqYEkIktE/Y:Fa9<QTTblVdAN+J==RPkRPh$DnKNLk=$aVSkwRqM:kLe/^5K%yGA$<+VHAKX6*i
K=L!*^ \ZiLE9tLmCSee\EwJwyS>py4KVkDJFkXYi#lXKLtulyY#J^19S4FA5DNhECu6a!cn?bptPXG!<iKlpE4
n&K5pF 6Sd5ZB&b!V!&&QtK+edlVk>FMl@G+b46&WDLp*8>F$@LZRMhFJwu4\P6VQl^TT1nPkK6YbWPDVcme?5A
5K+@P/ eTTMck1KEStqEy>GtwpqbuWa^\F%Z?y\Qnc:Th*DTZ^4*>9SjYX1FcT$k?hTd$NiCj!8mQilkGm:dA6?
QDE:uE GwiXtMk:\inM8pANKpiJ5t<wX1WiwMTNTTc\mh@elbk=uRLaitMFEQISWSi5n&mX9h&5p%%\XP+u8WaT
+Tw#Wh tq+lq%$I+a<Gl4<Pw:%#PhKhkPT^6<!h>T1eZVtW:nl^IF#:V\$K1V#DlpGEP9=4P=je&XVTetI^6XTd
R+?P@p XCye%ERqBNa1H^<WXZpLDKFE?HTT<Q8Z>1CEt$CA?a^Yi9in&F<DR$J&68=6+lqcPdAMn!yEp^ApELlQ
!V9?C^ a5qlhQn5*tjnRV5e<Mt6yJyZRFuDY?SHiZ64&#>SaT%6+I%ek@XZ8WieDiH$pEyPEteAaShQ5wRJ5whF
=MqTI& meF$J*c=X=pbA!QGLbI=lnX94>PaL*=il4>!mnZSQeJk?1DW<cJyi$elKb@j?YklFMjI!y>j*h+aT!y#
!WS4^a /?mbZVt/I+Z55cWS&qy6Z$XZ^dCiY*?k\#Gy??tP8$=XeT=@Cc5c>\k@V1\nC>t>#qGX94I9quEpIa5/
/biR9d Eh*+$+ik&Ctt9a&:!c^i*E&<9WE#lCZK^WG^tDFt>e<RY&@/MTGtw/*C>y#NnAd6?D:G@FldWCL^+mua
ul4:&N aJnK!AIN!REY<+=e*tJc?JlI8cYPXcjT6wiIa1K=ltqq\^ZI@BBSFQ5aBDIcZW6ZXPE@#DXXl^t#=\9n
IA%u\B llm#6!p4Jl/GkRDwGMcM?VmqiNl=KhTu6LmyJAN>e9GJWiGd%Q\:X>/qbJtq4m=>R/nu<ACNmC4VHV@P
9/j6\E DD@FL<w\hitmkpALQKZhnNJ^DD?a$uNy9cK6wtiaLRy:k4ePiCXByVn5P+Y:?DmiTH/JhhpLpdS>t5SW
WuIMSM b@9TwG/?nRnyE=QInaB*FZ=F5V=Y=?LqSC<W51JQFn<1A#?Y4:WCqKbI+?i1cWZ*=jV\tYe4I1bQFGdW
Fl6&KH 5QTtkDQdG/?mH@FZ!^XL=<&SHM!QX*k\D4>&i5#P=V#P#cVTG$eaum>+juGId!C*A=QQ8!eS^wHL9Ilh
!tiDB* %&aZNIyZjGA\W@PcRBPN>MJpVpnyZcCqR1G!nA/RMB14==Np&Db1ieaZqihjt4B%>$%GP:e!$R=Tn$b%
uPi9Dq t?y9<c1ID$k<TNu4HcE#tw91=^#Sm=Z=48!qu^#SYG*bc#>GWZKlRJ=pEGNu\BetKilZN$dCX<WcVX+m
mkZj+q b!N6jH=RGV6thDuCcYw>%9%F\86M:Nn1unZq9hy5Z8%TR\4Ci%=::=K8F4S4\E*aSqjp@JZy94Y%pmRL
MEu*eI !5tel$*$t999eDu6cJI9?db^+TRju+&k!ci<@Ha!G:d:XXu!a$Y^DFKl\11#uHX+SJE4m%?KJt?LypFn
WQQSQa y?4TyC:<XG@?pjH5wAjQQaMSqFILFKMbR/KBZb9i>!THISue4+k4DauT1?y\+dW/GI$Z5iIaE?IZdBKl
t4\ehi VLmQ/AwW!QLaP9itDA^Lh:Y=NP*J5FY9tAmuCD!4c*Yet1&qMFw1cu4^Iw^I9$p=mbm4N8$FIZWl%=p:
kLm4w^ iQIS91Vu@KNXP+h>EiIqnGdP1P==+@m</!dcIi$C8/I&MQ\FInMMDt%4p11mIAq:FL8WT1@K=NiW*Mbw
AA@Vi* c%q>T^+N1q=XBq@C*9ADQWSe%l/\Z8h64PHdD=wiNd#AkPCHB:N1^y>4CJp/cH9$=k&^H4%KwHibuw+Z
D#Vud< hLHiI^wc$C4BK<lbmC&qVE&6>Pi*4HyluTp1m??Ym85be1B/Bk+pii+tFPEmJDN/9?c\?=&IFCS*8!K&
-AR\GF 0003ea42a4800110333 Page 252 of binaries1.zip
K1F=l: J9yBli4DD@DT1RY!deQ:n$?WJhcW!=MiuIuLT?6d>IM65RhwYBi$aqV9+p<mYl?GXN6=I*n4tBeZ?I>>
/GKW5T iKw<FqYD&G^>KKI6FM1XI?T5SmVA/aEbPtF::/qJTCFlNukE8G!pW:TC?$<yE:>Ty9H!w^#!iyjJS<Vb
F<1laT e?AhDFT:1%+%K@^&A$jJmEm5c4ti<hBY\mkpHYE681y4dpq$HYG#u\<!&Y+quF?6+uwK5FTCTlDB$SGq
&^a*4m /LcwE9Eeaa/6=k&5LBy**kWK1i*eNmXDlMaq5wlAQ?EIT@Vibqup&JkZMkeKTdwpw*ui:mSQSLhK>PYZ
5+9lXN /hqmIbyu6DSqba*mKHmaVM&Y5Gp8JKuC@akdy1?b\mKbqniAGSTG#Y!NCQuGdy1IRS&QmnVBR8bltTI^
iJJMu8 $c!^VE8a+pP8Gj9^<8IJpN&E#EVanFEa1M>!jIh!&5h!Qk*nFEPj?C+>cX<F?9dnhYWRW?@u6l@ujn4P
4kZ^6F Si*A/@yGuju%/VX1u9A*a84Ly%tA9G9$9M#Ny*tw?S*$?hj$iVVpV@&wdnFJF%!DC^qSC\^\<+P@*SIS
l4lHT: L^KSIDMR!9MVwR=CLd^GakYhaGZJF4X@LjDDL^cSLM/TL5wT#9hVL#cRRlMJKL$P!QXVLSb^KtJpy5%j
G!=MNe ye*ZIpcyRBMJL#ZRILmY85WwlSXWkbZ%8L#ncWGY>/*4F=ZZqSZZniZLX9qbVQphCiWmA=X??Qp$ASZL
%1:enS \hYbu@NSM#CRLJZL^!Wm1nXB$4Whu<8Z6&5!9>cIZJac@ld@TN%u+5KPX@ZQ/P9ZM@Q!^lwieDW<+&9w
m^yt9: 4H^CK>lw%kEXnpLXq$@NXE/WIBLb<AGm?/TmF/dW:jnpGREL\=Nba8DM#uiS=E$4Jm!t6lw>=e$ljTu6
:X$XG1 EwL658qLcQAHm41$:1!G&mtbTBbj<$utC5F&l>S&b<Dp:tQD+FdDyBdc%D5ln#Ka#S4Z:tX$&tXTy\LN
1!jnVR dVKZ<4Q$M:M!1@Dc/:Q%&:M:!ZPw?=:w9*$q9JI49Q8W>t98>ah/A+@K4IuP9Pmm=V#/496h@6ShiTla
KPa&&@ PaS%Il4$1%#h#:py@Y>%$YHhYn5lYH@h$^HRuRQ8>LQy!duh$<tMj$*d/!@a?@^8h^=L\Sj6En4YY%>+
j$^PmN /V6S!MT@WRW4>&iVh99Sh\ilMQl:E>PaDZ^^/9@m!tDtVa^TYQR<caDPLj>=GG&?M+q@jyq@!yASmNc5
6l8\5i hWRp9*<%BIYPQDiL61@n#yBS/imZ1XL@YST/8H#S=94%:&M=<qY48Q$=K=%G:<b#9qb?b5t>LVAbkNq+
q\q6RN Y*n!$%Bn#:PyB?X6:WB\y/QII>/H&aF*5uMEtS?qb>5pl+wK>>DJWEQcV5$nDc6dN<BJthJV&dJ6uiVV
<iDkL& >K#A%%#AB%WjNlSudljQ?KLP^k>nCpR@w%hl9ZN*6pBKi5YE+*Mu$?&?nE/L=+NiL+TjbktZb8Zh!>4/
IQy5@/ ?qL@Yjcud64kDmw#>bWZL%c?hyKn=6I?cTIQbmW\uuy>b?+%<ntF<TB69muhi6KdkQ$*L@cwGBhi9&/m
+ewHa= RJ*JE*?eJ^:>>5:d6<EbbGb+yCdE/$\\k8Ba/q#$6<d4d@MbTIMHche6d#F>8>ZqVdki8j+G<DdktpV<
uG/#VW mnT+CMkaTCa8S<Zp8@u!%q1k^K*%iWJWCCCwCS?%jn9\#kaDFwq+DluVAi&cQeDWFZ96<*d8*R&tDNLP
PdpelC LaK%HXLGc&CRqyw+Butk+Sd%N=!<LI4%hAJGMRCTE#&j@8Bq$6QPYcK%ch#PKN!%jmKt/F$^+/j4=pSh
yj#6ct w9l=Sdn4TW?@>c%qj1NC^TL5+1Y/Su%*=*Qiui>=a8j$+1Xuh<uQHyJSB!%6wB4RwFciQ?R/j<XJa<bK
\6q!*8 EjCG8m9<@c5:::<n1bk1Z*>69umqRQ6K?jKY>5XV*a99tyi9!b9w6X8i/LFcqKc\c4E8IWR5Hn/&WJ*S
hGp##1 b+e?e^VbTPVa4GF6N^C<uR?pNy!:c#ZX46yW!AB+/<4GuM#+$Hj/p?66a=hpZ!ZYb@uQ$JjTZpX@pFT@
#XIQqP jl&Zaj#d%<X5/eun#P!=bh1XbiQ!dPHY=e?HPcLj9#@<>L*nPRwcCpw\em*!\^eGw8<w6>aVF>&?WYKH
%^#V>b BqG?8@^mAuwXIYY8%4cKA/aNqVY9#<TVpMXPpGIq>mXVIGhLpTpt^VamWKXLp&B*!<Qw=5DIX>$nF1:m
w<wj1V VyAPH?B!#\LAyWXK?>dePulQ:Ik1B$#VPm+D8#AnF+<TP&$=a?RdW=&<QiJ!#BqlWd!d+pG4SqB1LKDF
mVK%SQ w<:=K#D%w+miaJRte$FKAtAIiqL/8C+SdR$cdq#9qp%HLFk!FnV1DKapeGW^e?*Bn*+iX:?Ewy/%nNMc
?>Fhah WmMp?u4n$9<XdwSBDkMqaRZ%IjkV*bPPhS<19E5$%MndwVH4Wj^L1>@i?VGC5^&*iNR+:!XV^S%6uM9w
X*^?DQ PY$#pYGbw\/pStkT+R=GcNaZ>X8^=MS!bCPTtVE\##/nIi6kPA@FPh4C8L41QBt++9dEV/Tiek!hQtAw
:<u1FG dV>/$N*jiad^hLKI%=?!tK9BlHb*/EkMM#KMHKh:B:9GpLI$@%#1MY6R%wNi>ilVM<ym8#y@Bk#>MEM<
NE^m%D #KV9PA!S\aep6>kVK>mn*i9cA4wn8JRel>tm#mXm6<F\KwdV@G#?:5ttq%L+jjy\16#h#m!pTtM>Cq<C
+D@L1Q %QE6yBh/RYKe9yQyy=>mVu%cuTCP>WW/QH#>?>&Jdhe\!/V%&Z6!E@%unALSQZd9qTb&qpBKDJMK*YG<
<EcwRA l+4tLZCqT5hq+H1iWTip1$iy9%ubk1m4Ke+lhlki&^\^&5=H:p/L!Y6IR\*Ea@P\RlD\tC!&PFZ5/<%:
hmliD? qXpal5?NpB9ZKhN<5G9R\dY^d9KYe>+VQyI8tG&CZ#yb/hT5hL^:#wSmTjY<>p:Y=b$En:XQaktNy%@9
YT*u*$ Jy!Tw&AA%#9M$1nTPYLMm<X#ue&&#XmFLh18:ma</p8HPKhnCmiqYku4cJnG?VI\/NG#Y>6pWj8Y&Jyd
ku$b:K LdGdY=NbkkZ#dFpu>!!wM<j9Ji>I?TLecdiV*56SYu!KLLVSn:CW9&Y=ZpRX8W$5b@w+1!Vl!THty*qS
WBPcN! WmdVJlk6LWXqpW%aWw=cd5qHi@JINJ@Q>RjL<lt1BJJ6P$wJ?ZqcwQk\a6$G?$>FbacbFqFm=GlB?@V>
c/%BN8 :#=q#E4GMb>GCeScapi*Pddut$8T>6kYCYST>*@N6a=A^dyL$m@tMuwq@NIy?/I>iNd8w^lq=Dy%1HYm
wM?K6\ Vlc\>9GP:$8#EupKZ/aeM:?Z4dXHXP\%<yGjZ?+@i?h@m:L>:QN*\nH6&=hPBpFBQ:QA@*$T#p<6eAF=
KYVF@n J#MdK+u@uXd+9+@W8cpXLk#/aS+ZR9m@NI<L<T?n\@:tn\5L@e\j@*F1##?Gp9%y/$LEn%N:j5LCj<EK
kX$MNA *+D>SW8>H/j&@Mn?a8+Y+5iyQV>llZ:BR9/elTF?Zqj*+>Tiu:CC9#k8:Aa5?Ph?MWL\#%uwL#+nBQ\G
<DbA?C LP\Z:A%$>a9bYRnEDZV%T<<ZIZ!VD?uuG!?ERZ?B9aG\j8W%C>>AYIKIu*9N\6CdCQ4u+lC?kdCkmF@E
+hE*+L LQkZ&B?uKj*byd=bJh#9W?AEj:6nR&Gk*?/K+B8W\9%:G%T%j$d^Q:Qd@%H?J1DCKQ!VEWYIj&&Q?pje
E$8b^c i14t>4?H?D<C@>9K\!mka8d$6^@AnAK/hyci6w^RKIlSRM:K#5d&6=WB^mkkaijywYdqL8um=P4m@Q6!
bII#X= kjndw8Dw+1:yctd^G!6q=Y%uaTZ4d8d:V&<jC946G@%u*n+Kw^1CqRIjM$#CVK*NEp=QGCXq4w+w$8Gn
:yZLMW nJW^4h=e>d=#K%HPWpPaNX&bI%ZBT1Qh55XaIEQJYqP+!Ajq#eNcG<*&4c8A8*q16qwmdBS^5pWchqwh
*M1e8N X9Au1tXc81Z6#*iKhc6$HLR:64%j*C9S=mA6t$5j5&p!eNJ=b6ZCIqK9@jT>9m*c4tjc/%4K:Beu/u/9
Y!#$h\ :4%4w?bH^\=9$:bS9dwMChD16!l6^*NY8J</auY!bDS8AhWe&:&k!1d=\QJ$\5bVJM/pW4Xt*K4=NmM\
\u56<h id6?!QGD!P8TX\@cBy#ddw?>YcH54HN6F%Xl?H^@jPie=$6N:wJ+<b::=#5t4^?W9>u^:nAlPQa8:=@^
yTD/Fy ?jKGaXeBK9:8?6Qp\eN?9*GV^1hH&:cqZ#Aal&tQ1y?jQHQPb/#k^pT>p<C!i4><9PElc1Z!JC1YPGEX
Fm>N#= Vh/V$@$*Z#ktp+N^iEDeG=6qYEVF=H&&bET?eY=p:KiF11GL#!TuS4*wi@1PLHPqauy=H\+pHRWYDZJ6
>+D/jI QTIatLRa4yEc%b^?GkS\4PbJ1*jWkM1RmAdV*GLD/APQy9CPkSZH$F9y=D$etYDhE*:lVD$quuh9W<<$
kJ/Qpw ?Wj&8m/H5\$%=u^FE=pTLTWcH9C9qedSRKDaKmdF=t#^D+#^Ke/RnRtC^wtjS\8ypS*8kpa9iThk>RI=
B$RJQ= WTH$i&RbKFw#9C>aT#&e$GuqL%kt>!VP^^:IVCYq*bJVdMwyi#nn4R^Z$%L%815tt@cMaWPnSd6cWV<h
P:V4?J +k8Z1:?5hhV^yBP&uTQXuPNWc$n#NZ&hh9:AdF1IJ<%?ltu5TDl#aNDDZ%Nu>LQk$kYcF@&!$yN!T<PL
V1E\Xi Bp!qi*M>duBX/QNnwZYEM::S1k@dNk%nV\cKeGudqYlw@>^K<L%6C9\YY/9Hee**%/tWH%9*\V:8CQi$
L<Z>W@ 9*RQS5Xk^&R^Y\wZiuD9@6kXC4=dFK14%TGdLt/iP@^S\L*WeV/BVcySn=Bq=\mZ&5MDm1:/XYGayQem
KiPHw> ydi88aaYccPjJ5&Vh@=9&+5VCB$^A:&K:QT9kl?8j+y:ycipHmheM4BIIBm#KnIe:P+GPEGYYb?LFl^y
W>X=tW yF4YeCqMjX$*Q=+6BYTcbVhJ&4\DuSKD?&>j9M%dCcDuc:h6D1=Tw\HRt<ZNchc\+QFt\W5:VuH5*9b=
dS*Z4w jeWJGC1@@9J\yQQ4HZJin>bA@bd:V!kmq?P6uFI1D!t<#^m<A614Z:55d\y1i#/yH@jIiL*RtKHhjQ<k
V5y!:6 ^C%ZIC:PZVT*@#&DwRYH14Bhm&Xb?NR\9^S9<?S6aNk?A<8%u*##l:8ap@1MHmwQHNaVZ1!jw&BtjA>+
hC/phu %@jyGbq*iQ@yG@I1j^9^lbid85JmQnl#%h$c9mk+nlmtp>SpBZ%1lW5i\==Hk?FhHH9b?SnMIb$wEqm!
LR5jDt !5C<MQp\=\Mt$8c&!Eh%*<Mhl$/=M<^XJ$PwbFZLV=?*Ad<Q+/G=1?mk=Xt1^blp&\i:tA&&ybPkwD9/
&ZXNtC J1kj\h86SJ8aW^ZX//^9!:yna=uu1L1Be9qk#aLEB98hh:FBBj$IS=Z%4n9ejTV$dB>>qqcZ+@*PkBLm
#6\Njm JXF#YmPKFPe%Pky%!>k5:%EMeF1pyN4JXmt$jBLekTSTNmS*h#C/FByE6AcGa6?Qt%bVXyGAqh4V9#NZ
hLRDtB bZAFM>9LiN?l%RJ9w^B>+4:n5\<#d&#RhA\aIkK6<BTHRNNX=#=Z>N+YaC=/1hH\yEMl/V&Q>QQVhF:S
l8ZKaq 5KyMdVEP1WESWm:dqIWE>w*G4?J!4Iy1T>WR%m>=$aMq/uHAFT/L^y+ei#%@At=SSBuikd@G8IFW?RP=
>$nnwL QL?FuNl+WYttB/T&JPQ^S!HyKt+8QQ9Saut^PQeVDe\pa1lRKNII<5PTATDbL$?kY6L*!!w+lQThKJLj
X<jJb= S&TPc\CW!@5+uT?Tp?Q>:tp8Qk8&V=tZuS1?K<iEil6dpKc8$YCA*$H\XyFkW&:Hh5jbAdpWSSwNRD$c
Q1SWCA <8^\V4w/&h!ly&$%j#Pw8w4R\EZh%*?tRn1yuAVlV=m%4d!4qGVhhFptTQ&cn$e:NLct9&JGZ$i=d/?J
-A^M6q 000b8562b7800110333 Page 253 of binaries1.zip
pqeG46 lFtctq:i:Y==$W/Nh&\8itb8<y^^eK%*#EAunNm=$9l=ZaNj#%lFVtGY<yAh+=!YAPTYw@&L^yapll48
ic*n%c GX4:c155d:nCmd+mu&!^K\y6G5HS/>86>*un*nSeYuiRhlI:Hjj=%8wCh@IY9m$B6#?>$y&1a^HJcDpS
nZ#\=X >eki4SNeHRcyH^ZdhKnYJL*YN9R=%la&9C>YKS8DH8mc#NThunX1qpZK?+:<?yZRDH11+4d@wjHq1#ND
$kQGWu qJdu\M6VZyAED@9yZBtHVbw*+ptG1LN1R&cIm%FhdY6G5TX8X/V#>MyLIw*Zl5><p$DTt>*W6#qY=S9<
8c\V>C $k=$!p>DKhhELiL1Q?G$Nklkeu?^%Nll#8^9V<C\WHCJ#P6njT+^\:XKX>GiGK>SqyEp66E\GPp?NV?T
uF#<h< ib@K%DFbW??cbA4B\FMNiB96BnijB6DItc#i#YteC^p@tCJ/Y:Yjp5*ZN$LX%EAwClT>lIeQ>N&XVqiM
ZdI^$k #F<ZbK$<k@j6P#=!9ZSPte=//e1/WluqMi<@DPA\6j8m?hTLBG5&/4QYt9n*S68YmQtqRmPH5elCe\uW
bjI@W/ 5Tki?#qSwyc4=kS+5&9\@8FA@XY8dc@lW:Z6kDV#hIw^P?EH$H!TRYTl6eWKph4>:k#hYkYb>wZdnutu
w8RMq\ jD$b$Hn*6<@R9m\<Z!?A#*%dE1XE8kBct*kha\c&hwwh5H9c&aHj%&kD:6S@I\!Fq<S5jXb%&?YZGEKe
B#NK<L nW\Mjw:b8yNbIh^j>4JGJC>S:nAVnBHHtiYYIjNTq:JhTYj9T/H5PaH$=AIJt#G@^j&L!:ink6QpCb>G
GPWp:= K4%!@WK8I$Z#SS@:Z%GwJt@IGt@blGc?*/mhIyyBiWFbtP&%FV=4jFjG1J*$^cX:$m1P^&VeV8iW\Rc4
<&=bW+ ?lhW=XM5nq//d9dp&\M8B!/!*VVn9X4?<tdudI1n1c>ENJ/VS\q>w^#:qKCkJjw><j^d+W^?nZZHuZ68
KH<tl5 n:+1Lu/<bZn<wndt/69lRyt1^</L::pjH1I9jZka8mh&1@9DC+jN/>yHY!>hHu//!:L*<Y&F?k95&QC:
TFXiwb LmeBd%><?I:=F9I$<n#\*6nH:$L:Z>XKL\Jj9j:+$PZh6*5iH:@j*j*/5QZh=#5V*^/?@bKB%jD>FIBm
p:C1m= >l$FlI%!5w5!Ta#1\IGcTI>ch\9%qB\NSHB8Ia%&CpaHCcK:I5SDFhH4^DFA$lm8etiFC1l%/kCRN5BX
^9@u\= H%BuDDk%A+K5kK=&\Dwu+KpdJ5kL$>WZ5!+AM*RK<#Re!#Wc1!+P/#RJG=TG=S1CYpCL:b1QA!4GeT*H
Y%llqk /y+DwDEBmLL54M^SmCy^V:9\RH$+wWBR*VB4+uQW8uFY%^qe8%+#6StAjDAR6^%A6A8aQGpAdbWVcSKe
u6&A1k #tcABwnAAD\4h?n+Dw#wKIK=HFiSEBhwj5@W*W\<V#>Sq*BTu*AKqjD$>NdyMYuTdhI#eWL\HbIyVLJ/
>hdG@h bY^$qR*iW>aRD&LZPYK%FiK/J<S4P^yH:RSkebK#P+V%5yS8QJV%9ySkcWy%Xc4/PC\*ndQ+SEJ:Iu=m
=%!B=G R*^\e4eFKZE+QuEjDJY+ulbeV\W!JE8KyK$QJkQjy#*>VycWRHe&BW#CkaE#\GhQmVt4J1Za!ChZ:%tB
up!%/K WLFnWaq>ChZDTWGHhP46yMR>hFM#nA*+6QYtEQA!^P$6?SH:wN5?leR^SVEIHjY<5BJ<T>&DXEPan8kD
4M!6ek I+p+T>I4^tSC%9wJiuh!/wJTy5Kh=uwLtu44BmVIE65VI%tRyj+8c:IdZj%Z\1RQnBwQYcjDGcjX\A$W
F@CR\B emS/eQ:ZNKc$8PaE1CV<Shn*&M>ipCbZ54kJe1lb<GlE<6R@+t#RcXBjIi<^CXd+#A\^A$#XaVIY$/1*
Xe<!4I *&y+T#I%BD^9==p?J6LwIp<mb84>RKQ^Ad9PBJ%EEKV&+Xd!R<1y:=kNl@#91jFI#quhM?uh!lVW#NFJ
u/qywA ?TDVL8BGRcl4/tjX+i?EL*kVb9lI8aCR%>AWhWFRNIw4B!ya=Q9=QXmnN6#DDq/uD!J%EwJ/RT&tMBwD
5u>mbn lN+HI%n5$N?HI^4nEP<VPR5&$XI!lS8jCL@QF+EYm*mWm%T&<c1?9\%698*Sj49^^i**ZcLRQqGZRST$
5X6#JE u+$TRRn@dK#1:<&&@:@&HZ?^jWjn@@Q6P+BMFelPWR*i?QNc8VWHFmB1k>RX!N+km=L4+BH4==j&plin
ikZY+N ALT!HdIYQp5jcBnSdhE^/YCy&ap\hKnWNIG+Eq\w41+BNl%H9Ct^PMbHKndYFBK1<kd@NDcGDD?FHtWK
cJinn4 #6hwnmBA6&Kem@XkXJiHNYd4Tp6ciQK8IbAcp#VQK6%BPZYX9iq@NQh\l<=j9VmTKB11Xky4GhDGc?4<
XPiJT< jSj^i/\!J8RBES/$#J\Glwy!CF=mphPkDTh?b4+A1QQK^ICiQSPlc=HpZJ+!RMi9h6RaQc=*mXD/!8W>
+iGH%W V:Sh4:S$5cJ19*^GKpXu!L6t+a=BJwa1684=8p6qmRp\V&cRCtl?1I?AYpW61THXFjV^a\@GG#@YDd<X
p%/DqJ Tt^?bw5uPa::MJ^KB6N&8uZ9AB4iF5kSK#&4J^+jV9XqRZ&R$D%a*$S\L/14j9C%@*X>eEu1%$b+<*6l
Kkp?:c W\yB\EQwbyqtmNVniHJdtZ&?&\naYVHbEkHqwcTnT5hXibXNt@E+SaSV/l#AXNQ4DmIeAY^&h:^hDc$q
@G=Ge+ !E4LE#yFlQHSPH*<V8l^&IZ!4pi#95Sw#n%H=Z=Dn<hJZ@N8c\S1$\w>G*W\LKeWPBE4!nj%WPa^pjte
uPPlV4 pq8ij1Y!c/^hNdV8LTX?4F8nhMeiPZjG?M9%+WB8&&9L655DjMDu*6kHDtKmB%>B?>b8jKiG>?Q>C+$F
Xc8Jh$ #?/<i8HwTY?!RdHM$L6\LQ$JbPZ=8b4<#eI!ilQZ9qNP!b9Q5hhRRcWnaVTWuY5>\+e&NeGKAlpwnnub
I:yBkh 6b:n\b@+MBq6Z1N+EFk9WwMAdd5Ll<**J>dD^ijSdJR%YRPQe5k+YDRm<jcLkm5q<F/SBb=qWXQdF6j9
A6bqmP bQTbGlLtZ>*FhDP:%iM*RqHHb^VZNEhDkdI&ytuqieD*AatR!!p\\BKWZ\>y*:N>c>mw1^c*L>nH+iqw
pct4Ik QK5yNYw*JMkt$Su:thWWK=+QLekIC&*R^WEydc&FQG><SSEqilVk*/ZL:Yn?j61?LptwyA>udwZZF9>W
uJ@1hX pFSt%9hYkelR:Fw?mbCpFVa/1TGAYI5M9e#=ec/+8+LcYSEdXXD6//^:WX&8%GV9ERR+Rb^ad5Hiih6X
BCu=<4 VbShV@G6w?b18P^^TJGc$Im?kByJ^\ahD!dww$TKAVWD\pRc=!^ihZe^wjtZ!uXkW@!^in:=e5H8+G^L
WD5E+P :DcK<inb4FtI1D=85t?HX:=\aXPy4cLu=:T6WpLXD8t$h+k9XB<K?hn1?Dna!=kXPC?y&HCPjF#pF5i$
:6WYDY */EdXt1+1y/abR<tj<Iu49C*%SIS*551TeX>wb^Cn#=hM4!?>aVW8@+dmZ1i&6waT%RSJJAC$KuYGX\H
e@YM1# e5=*Jc8h>%+$yYe46j8Yi^jPGHLLQyjAiq>bGIMHt?9BwcSb?AecyFH*G>+!wL\4DdWB!4R6uWS/\?Bw
q8<G1m jldbmG%&uwe&N=FES<:4GdMu5SFJ+<#e=m@qWwu9Ce#=FaDEXW8u=ZYqiqQRRa:+m8yK95uN^djp@C>I
l6Z>Pm WYTmPSHRTQ$YY<6V^45#WYVK&l$+1HHS&1Y5V>AN/hK1utCpk<qGb&Z8\^aZ4jBu%uQ/dQZ1n:6HNNt>
Z1*hYD Ppdjt=iFEqul:Ye/h>+PJpuZFC8JTi#nRh5I^EMj>Hap$GE+RMM@qD?QTyASH+15yLhmDadX6^QLS:LT
\1iKLK dyl!FybW%L/YXnLRqkj4ILh/Jk6W4ARA>R$/BpFXqIZYGTT$nTW9PyIdldGt<4<bN1w4L8h\mPu#<cq/
6t$1&\ qKN4Acuy>8P+DiK95ccL:waTp#%BJkh?=u=\H1B$S9$1DCiRSA4*9nqbnb$d%m8hVnWTa!p?W@Y9S!4N
YLINl: mR6QN5$D6b&CRWD@m*LNbMG#9JZGyanZSK9!y4k^#kM+YSFuQCn*uH#DRJItERjF*IVAF++$>/M#y$l9
MMkR:w \dH8M9WAWb=bWtCZH*1nqK\?=n!@puZk^h+\k6qBn>tNnN4**hCFk*Qm+1WDQ8&JMP@yaVGeRw#Tk/Xj
Xp8l#l GMXW/:%J9d6Y1Km%l=@tQn5+55!nMjCXPQ&+Q>M$ah<=t^+S$bNi4mLnZVdi$TM&@E^cV#A*&KIqP#kF
@bj\@c RD!Jq=+=JXj!&6:WwlIY+D4VIe5^Xi^bhIBYNV5/*&ej*QCT<QkqZ+!VDN#nqcaZ5>Lkm$d=F8?nGS#n
:NP+G# lLpZ6e*:LWjLS!LSYZ+%T/&tu9jX9#5=y=yRGT1pcB4PLjISpE#aNXc9CwKIHE8cM!4GSL!6S@^uZkTT
DTE1/= w&4K5Z?t*6$<&G@mF9S=eup$Zbb/D?@A#:XPPVla+9F^nJ:^yc$AR@*4tNG/@SYZ?<CA^5=!9Ea>I#KC
1aLb&1 #*G%/nN*bTe9Tj*>l+dh@je//Rw8aBESqJFC#6eh$*V*BCyL6SaIH4%Pp@ha#d>@Gu/>u?NSJ^uRNi#G
PQKai? ckhk\#AN%9+RLF\KHXN?4BPTW@=<IS:nJQG6Ybli+=PiJ?H*qTckmZF#:#>\IY\RnC+a1AuNC%9*WA>A
L6LTE^ bwtV:cPYDGaAEZQZ5F^?wMmHtZ8YkkH8:$/ZFJ@JL^wXq1TC^<*FS=@5MI6e:m1pN4E!L!cSRK4p::J&
E4PPFj $nZA<T:eFNL5NN/^YiCqq#Gj=Xt4lLJn>D+y+cqXbmB=wS9^meLI#!<#tZZ!&X46A/L4GAQW%?Buc#Gq
b8Ad$P nje<<J<PA:=lHQVq^YynSDD*yw6K/+AAyn118jwdTBD4e%HJnV\id6&D?bak6RSYp!Fi^k#M5CGF4RKH
w!D6m> eahBlki!dRY&Y8c:9jc:5E5Y!@M!Iwj^VR!4/!5mpjNRlQH8ljkAewHD=PFPnW8W!RFY!cQ68nNd9GDb
K5m*$\ &T5d1S%P^nQkA+\%=AqlMQbI^HFm^yu#6*B<Lb9>m!%A+K9aAI!heV^dM9!cNpGXcjemyTCX$jI6&^NM
8De8jw JB=IleBF^BMVYX9A/1QYnIN!=J/w+ppI\*M&@eAy<edt=bF$u6?E:dKKmhe^1$<pnbq6&/qCdQX+uhj8
iJ8Z#i IhFyVp4=CdP4M\B9Zu^AcahIH>Mq1HI@j9NE+qpQVXSWmG/59%+5A%\^h>M1QT\/>^H98Xq=4M1B>#%u
CMHEQw 8IF$&ccFutH5n8Flu5\Yh^P/iW++e!9KNH=<9G#E6HPwQE&lPZ:R6Ca:KmW:NXX++1cXNJYF%9*wwFkk
9F5B6X pW^TwqHTIB^b$DM%c1caF%#lHE9eLcmiA!A?b#a>tPF&Q<W+yK%$qS+hDa<YMTt/>kK*%RA/\l!Peai^
Z%\jw= kAC@#6DVVw+Ck=meIZ+!cKuMWAquia@:yY*HKV:C9kwt/amAR%RAKCcVRY4alYyG5WF6!Tdn6TjXi*mn
j&/*6? X6QDhhMQBp*kw#TC&+MQ?qFtT$@KS^PIBaKykT@\PTk=HD@PRwT=Xb%H^5wbmy<^clT<HVT>#!uQ%duL
!*:y5C wqEZNytKB\GX^D^l*#Nb&R$T*CE+^Z:KXa5T89iK&^cdW=XK1+F^kLYWPhS$wDN*LAJT*Le<NTF1YHI\
uR$dKD jJScL4@A#@&^n!R*lXZC<Xka1$4NY%I5H+<XKHQ\\JHP8FPNkCiWHhKlE1w&DDkwbn9j6neAP1$c+QW:
yl6n/% q+^npHKHde$@Q&?aJLGnKV/E<>Wh9TeK5Iu!=\$^DLI&JAWLHaXBm+a9SpQlDTDucpYKbKQBuWN$#XSu
8FPaA/ S>*dyAYPFqc*w/QlDVLPKXpSwE^!iaNG4Lnd5yPtT56t8HSTG9/ZCp?Eb11FNiuMWlC\^9QJ9n14*4WF
-AmBtc 0001b34841300110333 Page 254 of binaries1.zip
#H1Nn? !\>aKn$mRF$EDJXBmp:6jVq:!49diMXCLI+:KWP*b\u9i6neduRRF8Dlm4IelL+V=lV#mhWtiV<GnulI
tC+TyB jH=Z=PlmZQPiIKD?Vm1bF@TJcKi+nGd?:ed*Wy=t&DE9=^9PtWkaI!jbQ$NuwTDRjehLtXMNbSiSB/dh
bKw%iu P!k::=H9kHX#?BYj+dd!iP<hBYZukB!NRF9H<NS1HC^=\8*QGB!%T4#LLpu<>\SWmY119GwmuAqmK%^#
4E@5wa 894idC1>ch&y^b/yJ=d^J6kX^K*ZkZLMP1+6i+=@EGZ:4KaC\BFp?Ikyn5uj+8h$:iF/1GH>uFthPTCB
^i*HEF %>u#8u\mkAeH:nAISV\CH1kFXtLe$@T$kL&L1FIa*D*VY/\*WW#wmP4%d\ynq5n4^4N*ZS1E4WK%&dAP
M8!9E\ pD6aK6J%G??h6A+?qw#D9BPDJE\NXA/1V9uYNtJYniJFN6&n%t5FDHdJ9t%h4b!R$*K#:/j^Y\^eHi=i
EdM6IG Ye%a4nK?8eB9Y^Zei5&J<C!G4b>R+X>?iinMZBHP<HIkjyEh8Glu!G^u8wRXc^M^A#/WM>9^MZiS$b<J
$eJlAi y1+KSi+VcTKHqdqtVXH!Eu9:t!KcBPWqEY#n>*k<NYX>!hq>XGRGM?*Z=n8SZVl5MHRJmjIlnbMCPF!q
5Aa>hL B$5tQM%QWMbw^5FbH<:5/Mb9TMG6KRP&TLi@y&P4H</JX=Pa&I!Z%uChn5:6^?I@a:y8Xh\BT?>iXSiV
d4=#?+ &jXZi@@6C+Xat?X<k9YGw+^@$WFP^n!4Q@Fhy@S!w18:JpqmKky!P&jVl^:MiH*X^51PLt!^?8SbGBnZ
cE9y9T R&uIl!4\tRkB$k?<Gk5W6hJu$Fc\+$YkbZY*Zm1lW=GR^hbY?dDa?NWh6:SV\W&=$FA=k@C*VnKea#ZP
MIF$?E iy*D>&#iMb*y!mY$mG&iDp^+Z!ZiSi@=np?I19k8GKn4i4L>YdJ=Z$&6HqGuXTNW5LQ49A4tE5bl6:Ll
Yu@WV& i$B&Fall/=:/$W&=&&quRp&PR#Q$dwB<NLG&NDEl?=!GHWVwGj/CTqu@t&DbMnMdw*6C+<\/4iVJ4M>b
%5&Wua VwBYju:<^I:iDRqZ8i4Hnhblu/*u@j^$Am%+>tTD^D$n?G^*m?q%mi+X<>$y+nc:Kqn:1JC>B%K8&>L5
Z$5mu= %:a16HAtXR48ZL6*u>K^@<wtHi^?^Z/9Qm/WZWb#nHh$pX$j\R&n+DQHYDaj9t9Z4?i69tkX61G8G4m\
BXa&%5 mP6DIHiZLQ+nhNupnN^*bIGWZD@\a8T*&=HGlB%tSEp5F5P:uh+D#*46e:t!#kH5!iuc%kSwAT9?TjlD
?iCkJP &P9A%I&cci?\<a&RBG:*BEw!^%C6Jm%QIqWhW#JEmAp:P^%:ENuWeD@Htn%\\^PVGT+94Ze@#/m?l+nV
9q9Pm1 QIb#M=dQyY/1y$%?A=#cDRN$P1R!i\J:WET/X*qN!hmyhhnNmhM/^XQ1mPT/+R6B^w?F%VmZ8BGhn9#M
iqPJ$D bhj>pitd1Bu/Wi<6q4GR!d\dMVyw+>lwRGDB?P>:mC%KiNemeM!y5IJGCQQ?6whawa$JJSp4CHt4c@Py
w!/c8@ <PXV**PG41>Q%$?\k<d^qnH#P4D\P95JWL@ut=$Rm=@jan1q/*yP9#:KRMNAm*L&hQ$L\#yy@9wybdA>
+Fk9!j 6dk:Zhe=*hwJyul6Hk%>AcwQXbePXhjBLTaMKqRaX9:i4Y9l\1=P&1+1i1bVT8RpeVAF6qq?wSpbndk4
A$pSDG :dLwLTa@\m+1\5+9lI#^6&kRXMH^DCLyFI\jmbF4=PJ\INP:@Q!nY/kj1n1GKW\@Ey68pj8>bFm@Iqyi
4l@mm? 4^Fb\%&:J5:dI<>HAMZj=j6>15*9JALRECBLCFA@FB4mF+wdaVI%WZcGMhAT%1<HE1\h+K/qM=l>4Z$G
eieFMn #ni#J$DyySGl4Q<5Z6eVtY%K@nnVB@G8Hlw/#Y41qQpJ&TSyql:T\CZ5q44S<:mAKL*>cZ1^weFuY^C6
\MqSaY NtyBHn<cHM>mGdCYnF?AkSZ$lqiC/KhNSaSBwQ?NP/4?abH@D9#8l@@hS9<9d4eTB9$9DcWX@l<VcQ?^
JnLaT$ *W4+u\%9@/##!D@&ABn@S!R@dP4+i*A*&Fpq@PQR$J?\<F?\5D>uBiGCQ&eFd<CCjuFe?J?#5F?h4>AN
pkC%L+ &F<hF@HuLFRR?uNY?Aa5>KehZwS@HBu/E@du8:KEj^\b?mML?jp8NGE\=C?\N>AXBQcL<:&B4mB\<M@b
DMD=*D G?kKA9+Fi\NhRTC@PN<d/Aw5>I9Q/Ac/Ak9@I8ad/PyZP>mEIVeSFl#&e^d<F%nIZ&B9IC^BCPnuLP\9
+SGm88 5Q<^M@Rj=Q>5?>a@P1V<9u$L@8Q&LiF@uSu/D!6EEQddLju@mt+yd9@9/bb!JTVRkWuG1+#4VH9HAj%N
%Q+hG? DneI4YGAy?K//c!#EqSC%lX4cp?G@!k%Al\PwYQ5^b>GY+SYNIDWYiW5qIKb+pu1LJl1FLXw&c6hZVW/
1bIq$P 11i+4XtA=e<GJ%pPTeymybtmuQj:%4MZT@54jt?AE4NY>4&VKekJnVejYhM%cCH^yt&wd9Be1Jwu/IAI
GyBJt$ \HP>Iqij@JYmn$<J\N&CX?mACa!F%Lp\A\RS+qkIJtqG1plWJQJqDZtAld4m:Jm^puyqFQL&WJe$YVN@
8n6<WA e:PAVt\?RNJ$6qqb4Xqd//McKB+>cMqGc@1J4F$*iSmZnRc=p^?SwYC^bc9lKI#DjyWu=B*G1M:ymIwT
j&b/V< 4JkZVClwDJdty%DpH1qRRT<b\IVKqVHLmwhI*u*qkDbjQ%pRS6RSk\1w/yyuKS8uGB+J!&c1dWdwt$+@
5Qm^8? Pq>!u4*Rcp?iH8tR/?jVtX8QD!ebw+B59me!%K^XZA*Y&^JMi?!nZ^qim%jnaCqCLiYJXP9nd@Y^\I=6
h?8>:e qXdNC/M5c86/I!n/nLDP>au$+?ESda8ek\bAaR1AAt$Pi%9uiy*X/wwlW^@jk9N>qZdcuS=6kk:<4>Dj
bc@bIa G=GHVe!mNjJ6EMGZ8^ww6/tq6>MAQE^DLY#NwAPqwHPEaZQ<mDCA@Im@W@6SJN6Dy?!CJi?Lyu8cR#Z$
h/bWiZ ?QF6kPpZXpZlcFLB&Fi$H4iMCcbSdI\><tXp?V+<5G1A!yGu*XLT<P$Bhq!NyNJ8lcFnmZjPwQMd1#1q
>CT+?\ HaqRjL#5DV*YMa+e&JtiN?1^u4%/Whn681kkFCE#ktL>diykSlQIyXp44VKT1B/kFL<@ZE6PktN!i>i:
tcj\lc iF$jKi&N1%lyF+w#KMSQYR>ASjiEEQp<a\X&qm4G:CpTJRwl4T\4KZn^:ph=8RkuZ?FRn4L/Ac+yu=We
d%HJQh #cGm?:1+lqCIa^bnw%h1kFA:STIaF&p$^P%>#kA9yIw+\+M^YIMJn4<kZQ>@:Q$FXF#htnWKF?+cHIIV
*q?ZlE *A6*h*h*h*eQL5Ehk48:l?Ai*N&h+MF9#8uVy$@*t*!h?@Y>+@:*H:eaA/1KQhjii/&=yG18b#=w&+9M
68E1F@ EVVRt%V<cA&Z/+FqTB<RFmyJ+C9$#R*w#qbdmXKQV\*nq&%QPwpGGkL^*5hQS%%8yiR/B$KVTJNBqCKI
u=V?$b W=4aH/MyKVFGE<&ZK8M$4yAMtJdSMNIBFE6JMtRkc49bSnA*6Wmqm^C&GqYGMW4&$Ll^a!$CaE4:nWmp
#\BqVZ nG!N\cWd!yG@^<JX?J6QY!wPipkQnVpZl<KARJcC+?J8:\D5c#*/9:V$KWX+k!AWaVMSkTXZBJpdTCQl
TlS#p< &>J!MGmSe+>?wly4=XMJ+nKcm6Y1/SL9<NlMXHWWV/M$d^KHpD&e6HAWXETBGh<N?TaRl@1=P<>^iM/I
uZtX&T $&!HKeKk/l%Y9^#PkhcpK8ME!pn*Ea>=ZS$5Tk$cF1H^=SFi1F5Aucpm%4M^wTWjZYK\XZp/?MhiLPe<
NW#5qY Jya^X8!<<M>ni9!!bCEqbNA:WawC#ybblYqRb^CnReY1A8FGWuj45P>H^<kSZ$8+GtqcQ=9I?eT$bkGD
+?5t6Z ci/VE+dyqH\ybk5#^>P9Pq&hmcVy\nadC5C5hjn#!GuD4+cJ*+&KY+=@44!Xja!%>w<@+YSJla&@Y@$I
bi*589 tpcl@aX\:uV+qK1ZIiJSRP&t=^RV>\I?6&hKFZc*CGP$CILKp!+@*@aNDedLwVD>$*Dyq4D=:pniJ$S*
Y6CHWN ^X5Vai&^?J!S<%R6XV&i6W%F^=8QnFM+tMJtH*eE=mc^MWFJL!kC9>LPiHPC\4=*ABFS4ZGKpKH5X*Ew
hy91bQ 4y6wp\<=LeLK8#^da+C=1TWM*KQakwZ^nhKjjGRIjXR61kiJKpMn$WD9bSJKJKJ#bCKlD9?m1&9Cwp44
JI+=1y R$c$d/CcRY$YGH^uuA5X$*=iCe>kl=?=be$M5T?XFtD!tAy=#\R@B6wd\q:dXF%lEZAWPN$V6+NF^5&9
LYdR6F VhHd&\NDiX+d>q%Hia>b%V%:lN\/y8I#N$6kRF^Fcwe4%8Z#<bAM=@piHk9pqaRLPMnK?:%MPeRbSIFB
dL1X1t 61$A9H#w4>ZZpd\J86aq!kXX1Dnn<awGMGPS6K+ZWqw%BkmEuGZm$/Mj@TWpJFJMTX#IptIqC15F/#GG
*i\!!Y F1LGApJWyEDHG%ylVCt=iYcyR@G?wCWW4/+wKPHw!t#yCBGncYwKiq\Tac#RBSXaK!E/ii!McASWGw:w
aM\iE+ #:byFF6qmwDMDnVZ!%BK>tm^KX4nV&4h/9GDSqCtN6=thF%L=4VWjYcbC/=jkFZDc^y6C5^n?W1H@wE!
?uDc\q BJX$<6lR5>aSn!HubSkRc/%kRltFSl*T&ic&ZiH?qLXuHd8Q4T4:WSiYw1%Tw4PN+dqVXc!8=/^B&q%J
PqGwjc kXQKwlHhwWE^Mt\SCHqRK<DReAWZI<DQIebRquqm/FhGHhX6!$=FNB51kq4iFkuSKn!muN\Wn?X!eJS5
b:Vh\X <W=+&u%+&q/tH/+RGdl9HyDHKAeQZpdiB=H=ELMNVXT4!5$\XRweM4MhADt1l9n\QhLjAmGkD4K*dnEy
p?aYlX NyQY<@6>eCjtSIZ11bJdqBSKaAkXn6SJ4+bIMjeqQilB?n/48$?ABm@Ebwwm:tnh=DjB5b#X>*1KRkp=
VkMAW> ncQmLXKyYh9X$SCFX!wQLI9u=Cm$<nIy<?6BC>KBl^e!hVl$P=Bj9Mu+mHBhRN=b/Z>&i*hAX+%SJCA:
L=^TGa >:*<wDWB9piT$1V6P?X*R66^G>YRpc9<S8J*m4+K?/4#?:Atud\?ttVT\t?k1!ARYH%WZ<=a!JSV%P@k
#N^YCj 6JV6956YCN$8SL^D+DPb:6:I>lhujV/4wDPJmbiDXCtP$AVD1ni*46Hjb8l=hlcPXj%\yaT$Yw:\I!Au
$<C^Gi /mWe#VtG=6/mlF?<y/VkhFYa/n5y#ptl8I*+>>pQl#up!WXRH\M8dwyK+!56>W<LAlZNJyck=5GlbyhC
1k!@+/ ZJ%4QCEAE+LqFI4>y=?1BhWy+m&GT5JMuGB5m9yy$@YEi^VE@T<m1tBlKY^m:X>:FuZARCBN86#Qh/%H
>/ZNqn \%I?bByd#Ljc#WaZ>Clc4pCL!CJM<1bdcZhV9<4c>PXcPYaD>658Mk6k#y8yRKBH1A4k&nV=q^GPSuVA
tnnqmV 5HK5Pq=LS\TP*ZMmPw\*%?iQMdIl%yPRV6+S:maFF<BVVthScnd%b:LZ1m5j*c^BXmGcJ8hdiaQDKkwW
B+nKMl IDPlPK1K=iVaE*yEFtKR+lXdFTIHLmLKHLe/\G6MCh:L*=RIQc/eG^1ak#bX+WlW>MHV*nnb9G:cR1>L
Wj>6Bi RJe^c8GCdt>Mib5M9L^HWR%m<Khq:HIqkb$>^IEZ*+MIhXVJ+ain^Jtl&@<1Jm=WCL^BMp<A^>pM:wp\
uI5=D$ PdSGBSZeu/<+R5FVSEA%MeG6i+e9*JhGe/Mpy/1%G+T4kKamPhqaY\CJLIanKL+1@qHdj\%Cjn/$yw:P
G#W^6F cn1N$RHVtB^8+BaClhXli@cAaXL*W+<cLZ6hj%6$VVHc=cdFcSTnMBMCW?RH%KlCEXyEJn&aK!>!<+>8
-ABTyy 0009589203200110333 Page 255 of binaries1.zip
j5$=H= IhwCNZEEH@TRCI$litIwi\NwmDP@BNyQWIYIMWuKDaEYSyu:?F?XBVPW%uA!\iF4u#Cht$S=pF6Zqtc:
Xt@CF# Yy/PIJ^Z!6mlR&S1D^w\HETaHB!1IEZ+\Q/wpEClL!iiQ$E84+h$hYLRMq6WK:8LJGNAlP4VCLW86Rwd
J8YCG: QYFneLm/kcCBnjB&eaK$6!n+<kF!@GwG!ZFSu8F=**Ae:mTtNwK1@bJJ1Dc?qE\b$bJ@aa\V*wG8%bAM
RL>\E& @:5hiu%m19>=y:X&kqk:?kj^X/qR:Dy<eRjQklH=kqn@NpwYXMyaRdP&N1p^u@w9/N8u1p:J#aSHYAub
*!AtR6 h>RyTQV8jDq&6EE@^IJla\S*1@bwqD:bR>yCnpJR9ap=J=R\9VckpB5*FBeij=dLPTeL#PnFTlt@RKtF
58=FmE XTjenT5pLT!umJekn1=8KC#6EAJ11w5EYyhk>DG8l=^d8#L5V?=S$bXb$lW:#8&>dt>GeR9c:\m4:#VE
/jWSjC :AL+Ia&kSYYqiZ9n?ik$T*KMDa^i?iI1DEtSXcqEQ%F<JJcYncDQTVR#XJG\NkZ@AN>ZMZwk9K*MIYNP
GaM!F> L^NMb^>T6JQuK!6<TGJ+TB:p!Q9SWy=B<9:Ce%XTWhAIk46lKC@Y%5=lZbwWW\^N<n1m/K4EjKpZEQG8
>Fyk&+ npS=@:Bkewiab8jn?p:mh!C@MiR&w&TB?ZHk^?QiJ/SI\+p1<+WVaNKie4:WX/=IZp<!@<<tVY$T<C$=
9\B5tL Qi%H$>uZbTcd/+kuVVX&qJKF&iKM!km*N8lPkT1T^J%:PqkHZS6^yNu9a6PpA4mpJk5weLqN1BZAi:1w
5T*@KA 6QQ!TBH1J$&PSqELnhl:#ukeep1I^^ul?NSG1NTPTdRy6lZL#t&T&yEX\lCqMnXGR%EatX1aq#TSVnTq
QN@1yW yn@jCK?j4/CPQ&A=<&ENA^HNHP&DkH@#W^BmQ>1^LhlYyN<yw^Hi=R^1a8u6p4+Jp#GTJmW8NdZNJCN@
Xq#mk* BRh>w\FtS?+1M??BGmk8$uRuTE8pu^6uGQY!MneJ$^56GiiaGY@*T?c=R#cep\j=tiR=j!BGMb&*bHN%
N:5=An FqV5q?P*ME6TMy5w+^nE&IjCk?+?Slm?CdRQpSKJ6KA5NN4lMAaYG#6jt\qDR9V$ee+tp?aHt*TnY<^J
nR&Wnj &N$X<RJ$LBek><D#8AJS8WG6qHw@Y&N$Aa@qcFkh/jY6TZbT4Hh9:a\i?K/>IRCy<GS#mJ5DCJDVGZ5*
<FRDYp 69jc89&!MKc*4lGTyy64\Dyk^uSLaHmtK+8p1klm=SA4pqRKwRVctktX<8YXJq5I6LMZTd?S6D!WcI1Q
@!&Ctq KKc9%ll:id<59P#HcelHNSMYh#en<^Pc#<IlPu8QFmb!*tbLd1lm4BZL>L6pdPV9*jR9*FD4Sj&*jMcL
hCw=eR =mRTQC=#:VDT:F^EYdiBbG!kNKyPXwIwDqlwQQekbt4aDw9+LE%N#K+hFKw&V1+DlIdJHG1C9E%VQ#>:
!t1HJS $HRZ\Pie^lZK&nHC?J\S8dy8>$pS16TCpXWTJpAa9mnibB#*%JRNiyEh?KZaiSS1N%ND>\FNwQ5!*B%T
:?=Gt= wP$@R>:+%m$W%BR$i8a58GEP\1tTAbn99dHm9N*1?lhdKhtCpJm6^:86KW?it&n:+FQ4cB8D\nGLNMk:
Gah#?8 !b^TX=6DpTq=IdC$\mG99I4WLW>T\uP?lS?uid8yiSn8SBS9K9>RC<jTSHDjn<T/h6&<mHE4Dk$&dkn6
XbeuTw na?FN5P5n%a:lp\=%>>@=#\Etmp?u*G14deREtwVt$cylq/&kQnnVTA<*8t?Q4\XHWYKBn+X^N56KY4@
\q&yBY Iy4>\I5hBwph\W/IL+CaqVSwpi$i\qwE!yENIXCnTLc*%DIFl@!llpch!NG%*RtL^^yL\I!$mV\=!%uX
!:+&G# h/?udqi&MYGlPHlktXkEZ>F>>NNyep$4/5D+9d6JA5iwp$<w8d9daEL@%iaDh+WJ6c%w^$kT&n$+DlIH
iIYwXK WY!PQLTG4lDlRa#H8@nh*MmYYA%1$GtpGXS5cX4%yikq%S?MaG/ARYClX5wJZHJ+TukaliBmuQhiMLdy
un^!HQ SjGCYc#wdS=NdmyNcX^#8%8E@4VwPZTpcytHw<clpZil4PBX&DVYVJSnRtT@V+#?pPe!PmZ:RVHYRXlL
cVw9kX 4D%ueT+Gq?%hmuHmDcS4Dat%Q1edHpq9jaa5T#yaymy1n/nSi^NBBw4K*5^<jiaMTP:6n>a>pFA+4/S5
>!k:AS 4B>JLcH=+#<aldZqteJkPEQttj+uq^u@<PC\HQmeV>n<X@?tEPHtqA6wYVT%&#R>tiQt65F@XWb<<tq?
9<:>/j Ctnl?kny=R#@NSW:kLtXK/uXK/%X@/Iq\^W:+K*q1dT69dI6q:u%KdJN1:1>9dKhK:hqydl>JabkT/VD
d958?D /%MHduMudlZB%m5BpVAB%%wuX&Md%%Jd?^kB+eaZ4/$&4:t8qe:PLbF84+e9K!ehYyX6ZtNwAtX+Au%w
%lcWDi @B9hZuHhV/*6HiAE*QkIV*5>Z4$>8cpAQIGP>y&9tYLh1%\h?mA>AHeA:tnQ$$F9^pL9X8/AkWm@6#wA
i8qLh! h:\#+?$4AID9:a$DYIeK!AHklR==%jbpFA@t4PMd=A/$*\>9d9SuHQW><?J:*R>+B\>+N+=wG*VniSJ\
=tZ8X@ N@jl>a>t6u@FK^@PHG:9eP6h:i@IKB**8llj*SnGZb9wPJ6+Q5ZPyJ#RGpLZ/wFjA=upkbn$kad9Lt@Y
:?j\P? RbumRb@!\YLtwkIS/kDSRtRXMtj&6?jWh$w*E5yKp6XZLe\RCtNjw=*BL8IEp=Nwl?bTB*LqwW!dDE<Z
lCeL<u G5!tmynPyyQ9=bwEce*!cLJ!waywae<Vi<&wt9K%p*=+n\@^SAi=\q#9^XZ@JNVkJRu^JI8+w6Tw*>8a
CVTXwe k>:+bDTX%d4T:6Lp=dDK=hDT:6YmM://!6YKt:HtqVcM>>D&9LZ&>GX6dY@C8:T6a/d*=YD>KRaARn/Y
M1nl#h >VKY6dPS?$GX8*CnS&A$G&w#G^+AWNnm@4TSnd*%m4DldhT&n4KNV>8N#$CKV:*nQh/Y#d!bw#DPm>u:
mb4/L@ Ck8FJ:D:e$tZ4dCnm:Ldidd>C4Q=@t&d%&Kn9Zy*ZYi>T&=h%&@6ii5dj9nE<?$c#$qd^$6LJ>^SJ>#p
&BcS5Q !@8=LEJYLn^P+up&njw=6I5=NdJyH$?1LL@nlw9wKupc@5E/u$>LQMpFL^pN8MIk@HwNGVKNPGdLc:W4
d%H$*i Yt/4uh<89H#YiJa8ulIP8kK?c\&Qh\Z6ck>?Z%94+*u1\+P/jEMj!XRc$<QH!T*@GqAGAIV*b&$DRQwA
jt!Fiw BLR*jCLZSCnZYWjZG?>8>AHwinJZAmLZG*wDd+#ZjG^n:c$*BHyj*!m@B4^h<hLjE^lejm&@:*La!iT:
>a!?RP ik8/<lZw*jl$#&i$VkB^8bH\+L*V?!^\4/8%4i6&9St<yRi#A<L::1*#Tc6>9KQ+kA?1:#Z!^c9+t&>C
q!E/^N Y*bK5&@Y1\@aMRAN8yNkt9lZ?<*@VZD:j>1ekiM@=$H?a:YR>c>1Ii5j1+Y59%RLtj/1GDC^@<Wj+Jil
:KKR6S =^^@#XH<C!##4^YT9?aw@kYY<hjK&%>#FQ<X?=5<\^^@#XH<C?^9%MK@=mn?BSd+c<Hk4#tKj+H>ZV&#
41@wul @kH&N!4qZ*MW@\LL^Qy4LQ6@n&Z=ha=mD8a@+BWL^/?^\D@kFR9\%?$L@ANi5j\/%\AH<A>+>V5XG9kH
LM6&BP 9GL=nXwI@ANiAZ?n4AL@kFjA*>Z#H@CKtj*Z1m!R:Z?A@RNiMdQ<yu*@kFjM4L@tM<5j<I4=N+Ij!^@\
>t:#NZ m9p*a^*LH@CKmj$*&D@kFVQDd?:*D*nF^QId:B@\m8p*CndLH@CKmiuZkm:LH@D1h#5FYQ/AX+!@&d*C
kNkZi/ <ki<a9!%BR5H/^@\/4i1P?5jEI9%N^&a>W<G4N>58YH>p\GL+hihpQWQmMZ!/*#5HK#@XVu@B@J@wb#@
H+ETb$ $?#pd<w=^%>#kHP\@pI=b\Z?#@PM@H>BlL*@N\RS$5MiEiea6FXqqF5AWWe/!!V@tRM<%dKJ>%M>#nuV
\TuuGB YLeC&FDF#B6njWC*QM6Z?B<n*HpKlMda9RpF9FP5nFn<\Ckuc^HejAFBMwIYj5Wy&mH#P9=8d9EiJ>Jl
MeeEFG <$ZV#FLF\NmiY6kE4I\/%F/K/DH/Ze<yKCL?!RuyTtk:1GBtbiJ9$hHI=tm1SNFtc5H9EumBe<nZIy\5
8Q^Fq! a>jG!%E1NlacRBAbXYSEF$+yFMThVD$+mN\pW+d=^1!/JaRhqtlL#ZEcQVQbJCZnlZpnG\<6CDV\I=h=
$\+qm8 A=6wh+l*l<djFnBh\Ki$:!yNPaNbcA6^6Mi@c=t5^:X##wGDFR+dL#tSwm9LIP\8V1^YQ!q##:$4kpJa
Ap595J Se>!RYS89M*ikGVSF5QiTmTnt^nJDZPmnRkpkS!wXD+=phu@6MJ54cH\nu%^+C^5Aqp+/5\6y?EaRS16
Ld*uRA mRNcjpZ*@1\*ESkNJ&FlMZP&!KGCw/QKD6!Kt6NqdqWTaVHRTG4NDec+=m8\=9R!bDm6X!*5PDw>p&K4
TF<\cF ^T$badjG%B?6amYlm*T\@519QcFeW^<k&BIi5WDhM1%+E\NyMh&BVC$AD5CEnAK4cIcW>GQFhiwpF5ct
qu>q9C D:C*dL*^wWdPdWiptn^ZwEy*p!a=>>:Hl9mc4qlJ8qXpRVGDFHqBcmchc95mLWk+1nt8PheQ=cYMB?Pk
SREC!n @?ldD/=llA>!ea4n?4Z5Wwd:9Zy\I^*:I16Rl6DFK?:d5PhSw>==&jkX8w=F/V%L:QKp66iY+Dh9wm?J
S$J!C* :D6K^*M!=pRq*Y4>aDNK&mdX*w^R/nS9T5>\K9ac$Lq1<^q^?lV?b!ZVWGc9$h4^@D#>kQJKI$W6:Hw8
4aItT? *wQK#^<c%mPuuGES:iHSIP%Z%=F#KBB4MmiF$bN^6\$*4i%PkbA@?D@1QqRBQ^Y&j/ub^CEtNI4k#!H6
BA/Y!A m\&DXeu+=GkG9=*y^nCmHI+HCb+/\kpGPNNldmFCLMByc>u*GRP4wWMeu$J*5#+cJiy*J\&:FK@l@:=P
%\qq5P TTq4l+dF*WnuHmPSBuQGn\aFlhc>HF:>$aEWCCuQn:wKWILQDjpA!VA=nT6aKH4l#WTie+GFF*kdGJHP
LCQ!pe &CmmBydhK\mMFEcGmq%@tNjP<#KNS@&mwWb6+4u8#Ymk$6>4nDQnucN>YREB\c<<Qp!q4VT/hp^F8I+d
y\e\jY AN1wZLdJ&AC=C9&l&<QH6NSqqJkaG1YP\+jC=1twBHEn@X&NN!KbL$**KQhZjqjD^QjkPDpHPLpJTi\V
*uZ#:I P6IJtECb4?ZyC8jBW!pe!KD=P^u=bDymR?VGb$Vq#VTpH$T+HuA8hwMGuCGGwwcX\MlG<!ea!\L^S\w8
jKN%dh ?MMT#yt9pqHw%XPEBITjNIA\@QI5MT6B+!K?M/ZGcdhuFM9&Jt!#5P=!p\4Kq8<Edi*PmnLR=jkLke65
>u@pmR L1RVSG%w>+j/6EK&QGYB$DmqlJ/F<AbXijQwtePEw$@k!C:k@KJd/ta<Q4awBy%MS?%5*=!?<X19a9G\
WW8+Ak CJwKqhmuEuW\#DYtMH=iE:Pa\*AjdeJFNdYJ<KdK88^<QBQC1TAMm@TAp5J&jmEY&k4iDKRk*^R\K$Kn
@pey+/ M9?\PC$5dB65yW!bQ6jbN&=J8Ehmk<dB&BNHXwn=Qk6F5NA=JE4HW9LWtI\y@<BpA?>S>*8$hJ\#aIpT
MM&W/< #IIYj9i4w6VpJTPE@Ca&&jYt*&TSnTk:4RIBWDy>k1wPi>l*?jkFMyZiuQG4bcPcZtc8bquX5pk:J8!Y
&B1#:n 9%DXl\E+LY+ETLJb%HAp^*WbK%@e:>$GLbQ>k8P:jT>=J4CB16*jFwTyte4dw=6Gq^AYlkT5GMF^YPXh
qaPX=8 pdaiT646dp8CKe?%6@!*+9adMKI5cl>=CnclGT16LSb#e:/FDab<ZqeIb%&lGZmuP@9h&YkEwjjhh1cc
-AH9=D 000981624da00110333 Page 256 of binaries1.zip
m#uaE> WaRSk?:t+t%9Et51/6EX+@h:LPWw++\TIRTEc\!nSi&GIjJw/P#!B8aF!WE&mpVd9CyV>mAqT9H<XnZI
>p>y/y jq<iSTkXWYA4Y<FC1I#FmJwH1e8B!*%SGliVM$K%C%5Z&y/MBtW@+1i?QYamXGIwLybAPnI>w#NNlb#n
@$w%$\ MLRQNZcITBeIa^*<Y&e9VX<a8En/K<Nk\VDEpFA?$a\6=nNXQ^h%W#/BjGu@=F9tcXuGIki8*/eH#iC>
ESMS=P /Gi\D#/Y%yyyWAIMPb&VA=PmSZIaNW6l9&Sb>wtGhVp*1*EmeScWtIJl$uyCuEJtC9YF6/Am!uAkc5Me
9yV#X9 6\qmMB9aF!PT=1^R/?wjX@KQZQqAd:*K%T/i9Nc1?wNlYZkn8tkNya$e@&nKpi%LN9F<P&JW?>SV/:hJ
E8I>yR KyXa65BEVB!ialeSP4y+#6V4S@MwP+?Lcdh9P1D?RR!8?W?yChVRiaRuF99bWtEJL%DY#X?cK:kqinD9
FCa5=5 VE!!EpKaBknCW8uJFqP4+@jb+Q8Y!jm$dZBZK%#n&pRpn$t:VWXb4N*eR@u!LX:>hm=W<%&#=bVii/AK
/HCc%V 55kyFiHWj\+!4IJuCV<6l8w8^e:?E5kF6*H1Lq5>&9yytemkDn=*y>p45!?w5/iwp1EL!9dk1IMPWmu+
9DkmJl X5#i8IB/*DT?@MK4CY*%^?Ji/$HW\WTpD=ca+Il5$w/dTMF=<wYkE1pVJeuN<EVeLY*Fm&E&JHl+Fub5
kd81ty A4m<I$wP>Ic+W*$5qY#MW/A$mS%Rk4:uGFc#+=6\J%VaT&CHe:V^mcT#J>nlklqm&ZG<Y5^!SRH:G>tQ
HT$Gin 6^nuJ/VZ9KF6jtVIhwA^Ccn9Xeunl?@TDLF\EA!I5^eDdwGL#^MFL$lmIIYpuS@GV5nVd/5/\AEVCEiB
Tqc1jY ayTJI?E@k1u!QlQ!I^cjn6E548cL*%e$PFDNIk#^u*<!Q!&N/S6*@+1Wb$5#<Bkp4m8cCRM>CWV5@k19
Ww?14H mNC6G>XhBG8Z8G+?CD5iGBbiIYy6t^Gq4T^lP#bEt4R=pHq\N!Sq9Ynj%DCe1FY%?=&&/!+W?u5F<wCR
4/nkLq ey>yZR@Mh/E#/P@Tm+mIp1tM+CdX=mMS$MDw\$9/=?mLJqhRcRqah8y1Vlept4lNB@V6A$CPGacp<9YI
j51Yd^ ?k&!I/i>c/iC1:8@PS?><m9CB$@bNtm1k8>ntNClh&pqiA?$8%+Z1V/Rt@dt1jcH818ZGKJSHZ:&QR+%
#d@5IN A&Pqn5HjJ%pbbqZN18/RX%95N*5*\^E6I>ERyd5Q698k?@!5JH&nn\?we<EX%GPI5!q:AjtjPDB4LTB1
$beywc wKeupnCGIc@NjJ<XApDpZWA?MVpJ9pHDdYe/yJjpVP^MnJVZuH=lbG?kic!1dWe%Y@ThdAku:%B^IG#8
PBcXL% LwB%!CIa<5Qn*@^CdS$iq1q>ab\CVVl&yP9uAI5\*IlC/abmVqyTm@eD:n*TD6N*lwIGl\<YR?GwA$Zh
HP/IJ* =e+>KFl*H/*>:PQk11%Lnw@VFQn>>Q5CypVV4%!4HFRIw#>e%pCdTkAPLbWkRqq%6^qmcq*w:XGIn:BB
liASXE dNTk\9G9pSSI^5*4wq?qFS&>DpP?ktulpPnkmtdCp?>QITZdp!?S>c*Bpu@Bk?j>WnjRPG*H>GERnRcF
ZVRJc\ >tk#^d4mAF:><jnDE+P+p!H\W<t^M:pRjcAhG>M%wN/L\Y1Wwa/b+aKyLw@@qn!N=ITaei^:y9Yh6DCV
+aXC1> 8wSpF1JqNw%pKjJ^nq\c1k\</$C!#Wnm5L>tDdX&G9@RqDum=@/wetHVCn9#/tHy:A?RcW^>p!PJmbQ5
qQShPG =eP9NlP4KmPJTSG^W&cdc%IRXFcETqajF8APqjtQ\<=J?^Y&CK!8%QQFj#Tk*5Wa>+!KPwme5qJYMq6\
@Y$cZ6 NmqStH@QanLDCj8G\Myjh*i$uQX8@m6kH==yic%&EK*iACdt!y5mhVV/NEVt8!uNaik:9JQKuyKeHGcV
VtnM9$ M8dNZLSi@yH#9yblT<V9Q%kqdQ&5*TlGIaBk@MHna<GMQbdMIkRmpm%w@lAw<?FTQ$VPh5ReFD:aD\qM
:i@^yu uI>YdIdEJG/aP#IVD1STeIjVdqH6GH+jmcmuXqc^>t?&WCA6Xd+IE6>MqHawj$eVFydX4&%?ihXC?Q&^
+?^:QC G?%T!Zw/\j+Vamn+6ViJwYV5SA1^tal!R6n#bVCJyDEpwTWQe?16dSP9dB65jFkN$&jcE>TtaXN@/N=*
MqG6/J EQFYhwFDeFej$S!>9qhEqEmRtt=?wimKa9lM=4V4hVkmMDTlcn/\^bRNV#kwVB$+*Gi>@hES<VB5<J\E
#lA6*Y cbTRGblAkCK</hm#i:MGp<R?Vh@pXG9@FFkXG?iij$dcbpJS^G?DhiBHD*y8Qa%F6t%IAu4PLeSJKnyG
I%Q^cc 4k4h?ZPM@@ekLe46CSka@H<J$kyF>Nj%uQkA4#<C9duHLQl9YS:iVP<e#Flh#F\haZQM#P+C#FtD#X%>
9dJ@uw eZQG$Qp9LFmVLF#VLHLM#Q<8^Ft/qqw&XX4tZFl5ntEH9GLihX4hjdXt:Z4HYt?J$Y/6&kZAtAXkjLXP
:ndKwG d4SKu5T<t:Q1jpY/Y:KcZ:Pi::h%@YLdhI==h&*q?5%1@kiM/yQ6@KB%M+R%+M&1P<ulH5G&GeWiE>$Y
ujXD!V +^H#H5GJ!M>S>eKinhdJ:d$%G+ehJ4Y>G/+nJ1Mn/+6#<wd#kyALG=8#G+@L\u9:BTRHVDQd=H=HNX\u
meBq!N %!W*NkH:?!C*bn@ublhZNuyZNm>*VDKHqATZ=F6*6XC*=ue8#Y+PVTe&tAG&4D884l=ih@daKhTYdMQi
$YLTe* #iQiY!yY@PM?dp5?#Y5?t&P\8Y*541\kkkMkk9y=l1ajCP&yNl*nBSqe?%AXT<^J:6<\<@+YXAiFE5YA
waM#q\ JD&dB&ZRe&Ak!ih:j@XB$CLAHaep%6l%HyuPhAdTMI^mHw6>pXRJk=nRHe5=>V&pDC5+BkNN!nHEHTjp
m%*AbE QJ<^1=l^uykJlw4J^\iVP$MpXnQV*Dkd>?m\dm^5pFkW4LV\q1^\w4V\^RIW4Hn5?&@i1TZaYJWSQ@In
b/+<$n tmi\ANmSLa*it?DkYQ&SdpNaAFqE>Y@i*iBI@l4SLhQkY<GY:QYS4uPY:D9SPTDl@qn+/4YS*RRSSCDi
JuubhA LihaID<IW66n&S8\RD=HLJdGBYSnkd#FEeXF5b>F6PISdH&Pj!DF>5iP#>&KZi\AaPMD5CYmDNI?eTlF
Bp*1Du a*/L8j<c9^WZtVIe#q+eIaChuDL1G>mj$wJB41AQ8e*kmpX<6Klm+Hby$By6mIF8cMlEy&<JSd!XttyI
$JPG%S ^G=tqGMZ5tMR!mwNliXPqPynMt>k!w>8/5?Q&#1X^VH*6#\n8i%t<?Hb4PFb4J<5Y5?!:#=uaVSd1qb@
8GmEt# d11$d4&%TuPJVL:PIZ4Lec@Pcj4JR&WW\Dq5VukT=lAA<Le<IIldKJccILti8LtQJGGQ%HtQ#Lq1EBGd
C+?*pd AN^eqD!%<aJ$CP>H8WLPh@tiWkZLKwYiJwX6PpZNw+ZyTJc5C<ZLL6:yH5XjlSE&QbK\Nd\jR\Ak8cY=
&mcdMK ImYQj5Yc!jmiJVk+WVk+ciYedpYQmACRjaT6jS!edIVH+aw&qVLQ+hIen>K&yZKe+QI$XZ!D/<4WV/Ye
TIRNaP LJ<=Mc5+i$5+dcy^#JI<#*LT6*J^u4KVY:$^9*y496Tp69y\HQumE9qm:tY6WNc%i9k8@CChS6%a!w:d
?H<Z4m VtC:NQ9aA9ulIe%R\R+WaNt=\yZi^GKWcm<@#/?=%G1<l&DC$R*jyBYGQb!=6JG6=YQPGt&BjhHmttV#
wW+N:6 <QB=Je/=Hd9eVc9Xe/P%#TJ5Jc&cW^wu6:^MK/ta1:L6Cc:/pd^hH+CtXh8GR>/l%Wj\BPd1BXLX9yTE
4!Sh=b P\9A4ddSc8:!?q4%iN*BGh%BJQLF//FDNd@#ecu$d1=nydjmKcq<?Y<=XmyZQ8h/hqdk>EGqn%c5+lb$
uJR1%9 +CM<#qY&bZT9bJR9H@S/u4S=tu*F\$:PtC9BiYl9e&l%//#F<KlX#Y%hGK%hISqwZwb6y\<eyQX#^@V4
RjL91H 1ee$=I<:CG>pl!W>#!dCi8iZ+E\1tEN%c?SQApIQk#nV+iKu#k!%e#GeGYCwuV6WABiAJbHGLlPe1nCm
MWYuHe uRiFq?!M%^!C\b^?SBC!a6C+1Yie%y=^y>cM=bjyHy#bbNZCFj:6+j1#X>!pJ+mXkh9p!>?Xe$/+!VXW
WP:!/F CAAFAKS@&1B@Ywh//n$Phla1NGHR>H6cG^*/tjh\M#4I$ES!M:q8ZX4>W#4MW#wep=6MaF#>Nn4a5#/a
MZFF$y p=98aF#NZ@SBbuZAb4PRRRNewdKeF4R1=*!R=n4^RdQC=*Zeq6+uVd&EL*Dh+iT<Z?lMtF@VYhbuZ5/K
<HAJI@ ^jVJu*/QCM*V8ynD9LAM684D6ck#9N4y6IcS8?wnC\HmNyNX9P^n6jA!C<$#6/yn6/V#MN8yMQ@!hWZu
:/=mFW bMQucDM4j:&Va=MZb4Q#h88XaM8ZdE4daIDd^JL49jt1#eAKiX&ZRJc&#1/4\!CH#!nTQ1qlKTnp?NCm
yp\Q6j !6+IZ?A&*?mV%N//QHqRMy&Z^9k<#\T9%+T:T<cKXYnHbcb/WJm?kFh&$yF9&qFZ%6F4:nF9+dH4ZtjV
8W:tHH \%H!LCJ9++q95>%4IkB*/mT:@&S?b%1*>%T*@em*G$@*&^qk=#T=>*S>/Zl>!^y@u8B%/aJ4/tl>:\L@
Rq=&Ll bd44+YJq/il8+dT4?9k#$pZ!nK%8<ji8$55*wm5?5m5@w6$q*$/^SEpJ5QydcelB+*aFH#<8WWtd!?9X
S5eK\% <LRSa<lAV5tPySA6dj/$Bpk65$N?9cdXm&d8&!MC!u5@n@88ujQQ:$/:G18cae=i$\EEwYF9pihN>\@5
e!WcZR $R>?u^/YV*/5%=/6D#:!duS?Du*pT*5kTD9uK**+<8X<w@ibaNCGd@V=<:hHnKuL>dpZQ5\Z*@IjBH9*
+Q:?:4 G&i9>/%ZA?PDk<KcM@cRQRA/uPmQaCk=LWdkHNkCPjqA+A:C^?/eIBB\hT*In\KRJAFlLW:k&FGDwF8y
/lBWB9 R@^G4L*m\1utHXYE&QCF8&EW?:1CFMl>aPEi<EYEtHH\^WaTWTNmHFl!DNMT!Q^9ye4HTb1N8kWAB>XX
%DYEyP qdI#\$yhkKw@Bt^u>EBS*XLbX@@?5pH4MmR\SK//>DqH9$>$KX1hXh<e84VP=#QGk/Yh<AH$KXK>Wi@>
&EEXy@ !\Ba4T154Ee^9ZQ<TN4ZtPnS<HyCGG/q+<j>w@6AN^uG5aMpjEau#JEBN/Yp&9N#XwSiVDJQ9@Mj&4y5
<LMdRT BLF9IZEt*ZqSk1TE\DBmlTQ\MAP!kLH<HZbTW$SYHGkm?/Z\>nIYVFhVwdnaFuQ&\K>dDBym!i<SDkL#
TDe</q CHMnC+:=99dP*pEcBCL?/DJj=I<Kke+jCkGS+<y=+\$4w+iEyBVpA8YXB!I@pEpaych?PC1D^TYuZQd<
a$iKpS ZEKFE=FjT1YbDpF=HJtAJ$cH/>pJkEBi:^<5?lmmABX*hECKk\1T5<+ipR4\mD=I!!YP9t1w&l^BdRnB
yFSN@j F*i<Tb*AN^94@DAaqSt@YVH6:MI1W<Ye9Q@Fdyp#1H$+%9yVTM$1LRS9hR@?K:HTNp$WmX#FaRJlRK#6
Qy1Jy9 LiRW4CwEYctuIXa^RF+*R:FY$j&#+nHw^#!KEeHEI51Sn/5X=SHH#eD/JMNljH<+Ge*!!6Fk<>d1MSd:
V\bASb #8wKcnd!GtpZQ*$AJIl@j+P$F@H\+l&Z?nmVKp8YMXCGLJ%n<W!uapFmH<#AdLtmq<MT/^&6q5Z1BM&C
aHqZat 5p:=:PaLD!YVjF4IEVn4A+pe*l55TW$@HDll#j9>NMlQu4KJ$&lJhKplAkX!MwyHe^\a5!nBa6m#W=%4
tBqE&w MWa66/94VFa$a#Wylah*QDWATKZE=5EH4=Vh5*$NdbyYZ1NEM+=^m\\pn=/JqVINZltuliTElNmhS>YW
-Ae>9t 000e38cf62700110333 Page 257 of binaries1.zip
I6Rmc\ Ik=?yVV*d9qnY%!ISWe+$SMRS*VwTcSDw+4J&Iq/SB/:YGP5@K*iRSSFSnJKKTWWXnL$tX\jQ5^blTRy
J*ALm/ uNqH&:hC+/ZA/1>W4cFR9idctHB>XN/&$8WP4d:BI\=W^Tm>q>/lJIQ5HjRkp<=W@b5HinXkbb<KGAXy
Pm$YnY G!BYhAe4i=Aa?G@+=Z#\HpLe&8C<INWt/u&hG?Bib8/YN*#^e8R*QB>I/JXbqkS%Cy@&>X+C&jFeZ<YT
ewk89y Q9a=b:TG&dJuc5mJ#MEdKa4GNa8\tdhSe/Si/!ZYn&DtRCENH*+PSRVAjG=@MLtaBu#</9u&8jiS!Y:9
:hd>4< >a9d/h6G@ZhHM+SWAAkNYa:SnSMhLK!APSk+waYSiT\VXHj1B@VAB5RAia@adujSlAqWDb@lyL5Qk?Kb
J!J!$4 aSak9>w8\@4@E>6qYQ@*656\5Q^q8<#jM\@<$Zcbj?lM@%Y>?16M!QyZTjZZ<mRd\*?Qbj&NyM4G?Aja
wVjKQY *&^daYQ/A?^9k1DbtQ<A!@^4lbEN?N>nYhl?Lct!5j\B>6iyXnnaYQ<AC@!%:Q*Z6DT@\LL?yw*a@\DL
Fjw>6Y <J64@kNi5j#GEID>D*n%8!%e:H@AK!Dd4/X/>n@kFbDy%>^k@\NiAaG@4tj&Q?AXM?896*G\@\G9tNq?
I1+:Y> *a@a@+BZ#L>S9hu@kFjM9?Ep?^@\myulN?j>A%+^@&cdHeej<I1J:hj%#QEH9GL/#ZnF<Ri<?8%&m9?e
RtQ^yn qpd?u>D@%jaC%u@hZ5D^%?$F@=18=y?B?W\5HQ@@Ebkj>@?Y\Q^86HFY!9cdCen#DF6e^1Nn*^QP<uhN
hi/8wE C$S\K$8aA%RW^n<k9qca+dKWVl8tFbY&D^$$&:Z\#=ATJbJmR6ywXTSAByVbq\SI=kX?K!iK!H:4yuIe
\CAulc 1A5Glibumewj+8iKJlI*^BMaFdhFR\CS^pGGy!1dd1FV\FLEq6$CQiDKhR4VdI8i^V6uptXPqYiMa9A*
JKYldX kb!pNliAl1n98Id5dTA>pR%GY#*nXlmNl9<m8/MD^T<uIL\KlKiI:YPKc4ASWbtXc5edEMm9&XCDXAaM
b81w\$ aew:4THY^%kqijHNTJjVqdIny4@BpIPTV8pJ1ERH5/1\:F=ICiV#n+yQSLaHKa+Hni5&XdqRZDkl#LFI
IBXJi8 !NWtwc>?WY:TEiJcW\cLaQ5Ib4#HmjC>b6SY4%Fjup9u?!q8pKK!+nEVPJk96wMe=m5?$$j$Vmel+cc<
b=y$lI &V$TTb>G8t:^^bK*Me1cW6CKZy!bn=yk=q9thF6lqtkID?MpMNZ%iZ586Yw/CA4tBmK+ldSnH\I!D:<Q
\*lRHI ZenZac+iGhMKbD*F>=&8eKGHMFwJ++TewJqnh#K&8d!*jlIZICmPS^bwEyY5mLnISj&a>WXTILFp4q!^
C:a%=I 4?F^6M/=8$bc<8T8l9KlaIbq9N=uTtFtL8wHM4^:EVJn6AEWHb5mFk?==BI4BI85E\8tk1L!dMhq4Ia4
H9uB=Z tRHp9E5JQ>Mu:QZWD4ybQHTnY@dhPhhJn<id#l>\VmuX!>/!eqb:TtIiG:I@twQ$6yY1Ve:MYhB^VR^/
dLV+H8 Q@DM8?lkTuj%?C\iPEKARjh@E<!&&ZA!\5\Y8=Fn\VV9#cw9p@qteWCWqI!%1G@mknnE%CHcHRG@VWXX
An=8wc #FGZ6<*1Eub6TeM@Fy>Jck?cEhAeBGmybSMPqN9eyA5c^ly9*m:bSE%Z+e^b?kwYqJ\<u/95aGKPY?RM
Mcmu+P u/=YX1yG6GSG:k1j6\!&1CJQ!5/jqF/XkqQ5Z=d$k<+$Pc9Z*R%lnHcLTu+hP=81%C>mkLl1cCRn>dwk
#ybjuM anPQJDX$@lp/$XD=bJ5yEHCC64$n1TtiTkXcMIpdBG$DRduK%LH9?=uau<IIJXpAe+?@VHjtSm/mkAqT
6@e5M5 QLQiMN$:\tCMLaTNHuT&F$8F<88MKE6mTV:81+#hB^CcMQ#FuLnQkbYbYKm^VlCdT#PR+enuktAy6GT%
8K!^=a 8B@HF:FHT#&kyntqkh<:Q:SkR4yI=a/EuBQSC:ASIPE=A9lCw+jB*$GG!Lhc$yYZH8VPHudNQiGbjnN8
+iah6B 4W1&%w9!6#a@p:nF*D&eYa/LpI&kJClqYu?Y^ubSmpRdIBhdNMdchJbnn9CZ:!MTyMC&#:YS>EnSWPPt
4jTFW? wKwVGtMypuiSDDcHR<w*h\&B:H&HQ%SLRCMmH+WdL\!QyM>1w!SCEI>h!mwJ^$\E!DYG+J<%NRuITybJ
5cRthb ZTtM=:ca!tEla=44qFwWFD$Gnw5nLBjmL&e\EXuKyIXpt\tS:MwlWIhKJcm?d=uZa%tNMJeS%#G4cuRk
E^e\X4 %6=J$Yh?DBTh8<4X\T%WqFV+Rbt/R$YTtSMSW?lEh\!>S\MMhd!wXc!Fld:Z!%>&n^qCB5jb^DI8V@FF
Q6Jj4# CqAikmHV*1HGTylIC=G>?jCCNp41!ZlVQS:lk4TGt^=SNcWAnl!G81N8lHA^&W8+BJ/%<b:AiRG<u?6H
QBZtaW :HmFb/$Q?wNdP@1wjyXVjdRheY?=mJLiVI8BdwW:^@Bw4Dd?#IH!h>a=5cEZyB/E6MT1wkqi\q:TREKV
%Ap5ph >k5Iq>DW^Ei<hylwA%4YwPbIHP$b@E=J!YhP$*hic$A4?N9^V:LBWw:aV<5N=RP#HKYE*/tD//Nhq%eX
@TkBqE @hG65A%iVCXmK+LeEHe4b>AaTwjR^Cp9I5t4/D<*H4a6DLWF#pemKk+IcB1%ecCyQK8&^YJjlh^tCcS8
+uZ$%p &uyVV5pTJXtkpA1uJ$RkeG1!Fy#MlVAQ\NHh4G4enc>j^m1TLaB6F?iES<DNtFCdN5n$VcKATQENIlMJ
@&ADbH =HKhjc4H=hh6@5+>eyAQnw5*L^K4HpjyLl/6%aHNJZP8S>KYt=6L1^TMR%ZiM@CpGwHGaK@mul>9caCI
9STt6e J<*JMS#MPB@t4XG8p^PtABG1^$&GcRP$hy+9PtMM8<Apq%y8ThZh1eXNen@9lKqJ+ieP?Z+<aDl>=$Sq
KViSab aN?8QkGH#l*YWwb8$1?XW*e/c&A\V?8?4m4hGJC*CB6X!SRE:cX^Ch5@i/kwYpRwQ*FEe!cauMEIJj/J
6F^KMa V<$^GDEl:uP1JbbYbDBKQm%b1ht8VA=bFF4JS&95:BcXQMw+k8tTjd$MZ%^y4i^+wPtJ!PlTAq#D&HkI
^whdAS C*@qPFW@wmT/!Y!>^bB6\<@lcpJXNq:CyA5D$AAC41<eDRGbc6bjQWiC9!B4qc1GWG6@M1>Tw@J+&K?@
$!u/^> j%h8$q$nMD<ypY%b=nH@GPPRaF1#tcMj/T<jM<wTIwd^NR!P/Xw@nej6!/&IWh44AL^X8mVnWQhy/<=K
AKh6:% L1=1D^Pk=:%N1t&>dad/YbJ+S6:4ek*mKNGHJjWFNCyLDRi=Ew$F*c!Hi:dKCe*dct?\=8#+?ZG9cJ5h
5jp9ZJ X\dBy+MwXbb9GcD?^>m>\4e=eym=JhVS$T=ZCK%iEH+8e>uX5!Mdb^XG^Y*/*\kJRyW%WXKG1QSIi\8a
<N5X:w d<MJ*m5@?GtZ&WBqhtjb<BT9<1T:RY/dtGRWdC>BQSTR=lqMWci&?qw$QSNjG9A?8qKTm?>hN5C4pp4\
EwSntG lqA#GH%kQd\+%SyDNm!YblT??%FI?8P<cE=E?KGe!8kVlV6Tme9k=DZ%wd+$>^qAQ9FV$@Y*NtN1>+8S
hQBwRp jaPaK<ThCLjR#WZb:$=mnSB&quE!:9h\<je!@54m&+M!wbBRASD&+Dundb=:mlhW?:=R8+$R5ZXS*F8\
EjBVeK H:hpwAZF\CqypTYNbG$tKKaG#8pNyetQRwKlLZjKc1cQpuiyYubN#%QM^hM6B^!EM8ekn8HLjhePNtZ/
+iZT>d p?Hq!t=6:c9y9^@b*a*Rlb^>l^$>nF&&>wYA/NaVbd<6&^<lQQ+8yqlq=cpLqh*1AG$Whu=Y64<=+m@C
=*4<ed pM=Kl&F4aT9=MeSY**4!i<XW9nBhuKRYen6cuQSWDP<McPCMSHb1jlHulP\5uSJC<RjX$MMVRutIp4d#
Nl\B*l Zb^+e8qGTIc*ThBZyNQu/18qn#l9@kKI=G$GH?t^!pPSca*D+iCHa6d9Gb8m?$tN+EPSc>EPWE1SIPcQ
//c+?L /R5Wkk&NSp=>w@DcGApnHCl8+QqNKi6w^t%HIk@NLwHYnP#Mp%uwlDbwbcp&S6>V>>i*T+MJn!9Se<!I
dejYQn dD<RWhZDP=n8!4Ct<68LGhjN\k:NttH6&emDR&&k:PW+ul6kE@bmt@ql%>^XX>?%Fn/DA<=\^ilBWGD>
XqN#MS !blpllZd!TjBETLBWFCZcC%jR+<XydD8=CdZVwlj!Z=<H+y!unwA5=4km==\FN9CL%Y@6:PYQe6^Scy=
W&B9HN MDF/H%itmi4eW=8ZFJ><Y?5j:im4Iyh*Xd+GinXRPe#$c8LcK/KwW\eGE\@#dl\/ddLA^qA!SEG&hH>j
K/I9Cd $4/RYAp^&QSHt1Bk8ZE?jG<K!bRVKYZX/uDhc5X1J$!ZeyX#V9T#Jj<mRkkHa6>lRWnBSkV9b$m/AnI$
9Q&AtP JwVD*KICaT4B@PEQ8iG##@8B8hHLknbd\BE1bW5a>y#FLFlpR%lGq5Dnkkuw9H:6@HiSHPIhBYR?!QYb
9&at:L Z+@b&QaL&YuZC!l*C=n6C?w4hEhk8Jkq/ey+8E89Clk91R/\?w!uCEwjhSSBaI^aYcGJYa$MweCKpuhE
1hSD@y IWhmJCtaNQMaWm!4&IPmAlp=tj*6KaNYPde>Ta!kk\WF4jPV+EGh8d4S?aKMYSPJBIXE!@JiCR$X8enK
<8F/Bt $Y1?CkTmCIM!<P^t$k1/m>$wCQ9dCQj$\S8*@F6eK9&&KR#pQmV^*?NTndM@/Q@N8dTL<BTB<P@Pyj\>
dh$eVS TMV@$MYqGn1qd4=KA@8quaiqG<cqd/bpCCYp$SbpmF:BE:ipb4hpG8bpkRe!5*8!#ph!cB8!\Aiylq5=
ETyYE$ =\EAPw\eeEH&bkkA8EQTZ\ckQeptwWkVA9BWKBYTwMGV*m9MdmkAP@BW5QBW!JYB+\4hh\T**AmNtC1E
I9d\an >$w1pAT*tI4?K+yJJ5yww$w1J9JJD9KNaqKNFuJdd&4wQ8w5\hIp#GKd/EK#QMJRI5LCB@#pMCIj<>HK
k8$9PV nNuBC+YeMhn4IK&De6mPE*tJ?\X9nGYh1apd+$YaZ\VSM+H/BtmNZ$TIBYpqknS9eEZSGEXh?9tF>$q/
wNqJPH @jmVFy$T9hT:>eRJLeThMMX9EmV$$TB8MmR&S!YB^bIN%XLAbuXZT4udAMN8AGaVm=4!tlE4m=H#yhE<
>LP=WT u#HcnLEKnHHmqBG\*ZnP!mlb^YlPR%wFZZFi#ZniTB1hZLESX+&XR/ZSR?qYTK&SR:qSVpWF$@VPRcZ:
$dIn&R ZlZhVDE=V84Y^tLi\?I8RZt?XQ1P*4Cy$e1%%c1yYV&@*S4+ukEwGm\/C=pu/hAA=DiEbBP!R:9lJ$>i
N&>w8\ yA1e5=tqFYRhC*G&JAY/j<AAETe$$\?C$b>NlEJLp?nYp$R4qE!5qAKkT!t*Ym&RKd5YP#b=Te%JtC?\
$e^LW% 1LmcKC>\+/u^PT%\KKy+1N&mK:4^Pd5tPKMLKLlJPYP1YGJKPh@48KRaPYEK8cRI8h/y1h&F8^HmkDS:
Ep<:Bk 1N*:KC!+PGMG8d6YY#a=PC=RP:4qi4JTY/N@E4ph%$kE$Zch=Ap#$ba9!FR=F4*S$WF8+t#5k&!k&aH$
&<e<*! *41W$/=@<pKj5eE+JZS4IVGe*eH5%$LnbcXn6E%b5N$yb5k^<*X>JGJ>JhS*5qh@b\CM5&>GMpl?:=BM
QXe^Di +uBH:1uc/bw+yiIc:iHGbu/Lmyq#@^FLRIWF/1P/$MejE6I5tMd8Ml:1Gpa1K6L1R5GyCycykkS*apGL
*e@!aA W1H5a1w6bl>b$IQa=AIZ\&W\T#W\K*&8**\J>Wu#I4ZS%/jS><LhS4lIq5L9=>Ccy:SVE+VbT@u=LTtH
++y6%V JIVaVpTMA+MYBwW^H!pE=!LXRd^di8!XXj\djMT^WQTD/i&VWR#WWB^WCS!c!B#bI&Nh1hXaFRGA8DmM
-A<BnV 0005971146300110333 Page 258 of binaries1.zip
cS+/Ck iqQ?8LnY>*G8>1nhejEcbHG5JRB5!ukQq9kqLNRquwRqNw5H^wRH94ltilMDYmMN1jlYP5\Yl<VYh\1E
a%P#G+ eWpc#B+8MIpk6Iq*J9HaMP48u/^Xp4S9M:R6ZHpm6Pu9S:JBten94\Wc4#n>#XN8i?*epi*aXmIdW!KQ
Z#?Kmi e/Vw<EppK:%BI>Nc&6NVupt\Qt6=NP%kHju99Q?EASYRnGR@@<:A:b%BM/al=u6HdK@Qd4qt4FpY<$1Y
WQw+pi 15EKLE+jMXPeq%Bl$LbWQF^MQQBkAM9kTWb=H9V^/TT!PPR=dw\JuKVk!Tq=L4mKG8RJ!!RF8Z%WHCKJ
MTA\#\ /X#=dZKFHBcFu9V!cw^JZ#%Sq/Z!$X+KNC!KH5qMYl%!Y>%K5B>KZIJV:55F\b!*+wR$*Sb5NKKJW69E
m=AtJ8 nL=Fy<\Z>l&WpmnE1D:w@Vn:^QyPQG$qG?6>696V>8JdwMh6TZIHYJI*YQ1TDM=cFiicS$N9qiciJR/&
>&SJRW %PNbqihq1QLZ/9V9tG%cXa%c1nlI4qwISw$!Nc=T!55I6iymNa?tMQ=yhb1ttP&$V4nMqe1DJj*$DIeK
Sy>4@l cC^j$A%>bS&ylZEqhGeSG5Dp&bVh!yQjmSPcbC*ib15@BGJj^GJS^ty^iHJ8XLd:XiHey*miXH5FtZli
Gl\P1\ T/%Ey*m?XG6>e5KT5*n/ZI&NaM\tX/J1a9=W1/nXYP@tp=9Sci4X*J+TcwZd&h\?bhWYue1&yY&LR:La
BBb!t5 JJtjTCM+Y@Kn&D8&ICkyF@/+51\66?SyKWQ$Iwy>\ua:4i5n%4bG9=<?84>qyh@!b^E5$GD\aP@Ylbni
&?WAAp QZ6?t/aYk8\Yp5@aaJ*eIu%iM^/4Mu*QCp/=@kVQc9$hG9*QPkQeBkQiJ9&6IkMhFwQeDwQiiwucLwQQ
/X1Cqy HpQeGkQQAWMh\RQcQpQQ$eMGAWPbTeQQjwucCmQiyS*iEmQQ6b*Ce81LeX>VP:$V\XQ#QET%*?9eKHZ6
+A!Bnc H5TI5/=PYi+ER6w4R/R@h&aAmebFL+T$l>lEcmA/9u%%ill4QJ9A8JnwI!Zy4?%=MmVX5lEQZPlNH&:G
\KNy@M ?jcbuZ1Wl>KV8*#/YW=SAGVGl&Ptp&itI*iANSd\ut?&p&<+$&uYS&dPl&&Y&&BPS&N&VYH+Qe5<n>Ve
A!/Fll 15%<y<*Mt6tAn>nM?\BLH?yF6@!TYb=^C9Fy5pw+Y1S9qhnjj8!Jiu>dRpMV8#HTt*@y^VW4*+c!=?#@
D846nZ =HH$cbF5ty@@@h4+/59WG5@et5@Ttp@R&55EACRQP86wQTeMl?h!k?h/ji%pR?hq9S6puihlQi6qR^h1
%8pq=j @SX8+@*DJ5<aAB>1m^h>/=Xw$^j4@j4:>ZYmhX?!LX/p:T:/#Y#!HX?+#c*<udYuZb/HHX/J*T/ILZ!P
@$VL:e Zb&*HX?bQX&D#ZYSudYN^je4B:+iB%$?B/<B1!5Lu5@k/wWXyBTKIaJ#5B!yLM&D1W++pHGT&/84$m1D
lM*PWB E>yka#AjIjP6k>@lc:b9SYQiju6i<%8D/FEd+jB6Z<FCmFu56hhal@mB8+w#&99pW5pVj5FDi<C#Ii@n
a?5tll h9HmF9<G<6%H:d5i#QeZ48<dKJeE/Jh?MJhj*u@Hy4@IC44Rw*Z$mTL/biI%n9?eS@6@V>u:*=V#@uMc
q9AE&5 :n?X<^kb@8t^?p<>:?h:DH<5/HH<T6Dn?P5Z<^!5j@^qM@9@BM#^Z:/y=9l9M+D@M@mNZ9duj=pa@@JX
mla:AG >V@1+:><X<*<6*#i@%<p*Q>&JN#a*!Llk9+9naS45cZ/Xc@<B<j@%>*!@?L8?QPeVQ>hj@^JN6bjhEkt
PJPS&^ q4>&TKa@WhkFdG*6jl/6>djnGj/>Y@/>t@/V%n?jMQ&m\@/<&4>Il@?+k#<\1j>=JQAQ$I^M:L>B5@#J
Wc#%B: 8hq@h&:YQ$E#Mj+G#jaHcJbj:#*+iTV:u/Cbj*h8nn>AM#H<B9%Z^@yjwH<*V9/EM@:Q+E^@hPi@cZHG
R9B6*l Q&EdG\QLd>DA@^H/V>nG<t6u>J>w%9<St8%@lGd@I:/\@RdN<V>B@^edi^Mu=@??kH<Miu<jqu/?WuI^
PTLcQq hQ::G>IY6qb@H@PM@qaI$<<SDMnPTMn<p?nAu%Q^*<e5P$jnu>P1FmHD**@?enH@iVn@n?9+=!#@N?PY
t\?Beq 9?Y:bj%Hkc4@wWH@&!#Q>I6b@n>d=9?1&H<8Hln?9hn@YDD<9X\k//@K@Si&@/NP@n$>!u>W!6>ZlaV$
%hnZi^ 5ka&j*@BRpm9btH<>&WGI!G>8ItFtjuQCiNuXj&5HA6uJ*pVS!E:G*5:&:@NI?!EQ/eKc#6HJZ5Dw=>k
kEn4k& aSNZC!MVMWeDn*?8XSkb&Xla@tP%Im!p@I9X!69m&#pAWiDuSb5AnQ$BQ^>9K\AlADVp*^+@j$QDR$NB
/q@<yN \!QCRpQDImInICAmICCn\Q@<nRmQkwV/D8$hKlIYFk+PFlaJMVE^Cjp@H&@hADlwRDcIE\kIMiC6D#D>
miWM8\ 5&AwpL<>AQ>+kEPAkWKCAKCkaYDlpAGkIGBkwPCkpFBkQ*?BPwGAk1GAA!CIWBpFFCDjGSA:BKA^^iXC
aFC!p< wheKpu^XuNym^nD<V8waiEptBFTK#/5#e8ylETbQ!K>u^XR&h8/h*wd?EARDm+Z>MXFE6KBBhWcFA8h1
ZH&y+j =:y9h9jG^CW+1dC^j&:9%6R%JLtwcYB?@+=NVM*MLVTq8Hq\+iCiZX#h*D$56cSqcQH\B!YHlIcFS*lc
5uti?i ci9\$6EDFcipy1XuSHyb&<n!<iQdGkAekQY&DID?&!*^AT=?ICuMAhiwTDMWP\MHPLTF$FKacC!uGenp
W5cCNq McpX#X&HQ81qP1ydPS:1G5>pa&#c$6^T+/8y*tQM9d+a<b9w<nYl<iEZ#HkuL=>\16!tHFHnD6qc9\E&
MW1y%I 94i%LV#+w44huRRT6kX8w&Y#+SGaXK&<Aim@+T#Ml^t4ykpJWlPTF+G*LqndLPaaWaPC\LRWP?tt9kFt
BHCWZW NP*wiG8i8B@pb@c89+/MHGQLKJ>DD=1Pb:BcL>Ydn5h?ajA+8hEyQ1yEwY%<IX/K5B\%5T@cZlLIVaYk
LccRJq 1!l@+4<5%y^8aJ%/*5t^ppFD%u:EnM?J=/LPQS\d/euhWX%Y+j8GdZLj1$FjchkmySaLa@^E@Xm?yc$w
NZTZ@l 5SYML+FHNZk*:tu&Nupid<uKTPtc=c44DFpRNB$EJqb6eWGhc%mYX$/CpJ=q5RG?jK#1>yEGXYXw4@8W
R^+!n% H>e8<Q4j4:BuZEt646cpn8$88T%4lFu>1^6^eaucX\>1FN$PV&M><ijSlum4V4/^icbD6$iu5G1y%>e=
$Ly+lu PN6+:B&>RDaC%I/IMm@G+Rw&%&bp8HKQujT%WLJ$N9lk#%ttiM1w=1/t68nCEH+FGHnb&YKj!\5*G:!8
<!X^=k !JF!e6SumcLiL9CY?XNC#ZAiWiylFdd1Sm<V86bml1k$>#R8qD8L=*W5V8!<qtmV+FaTY?l?l4Iu:id/
RCbiKS ql6&dNmFYeLy$J1NK4?*1R!Q9PtXCR!:+lMFGJ9\D&R/WhKi*Dc#DJi9&Ae&d4LZWH9uuha%P8LqX9V#
Dm/qZc DiXJ=AG4KwE95Y6bjkHjJA=hihYjl/=iQ1ed?T>c5qqIbdSD5h:DeK1Rm4pjHRQthw+l$e:C=QaI8I<C
Ne>AP* $&X4dTw$T*idq8N^LWKD/YmFTNlc\\!5t*%6/w$i=Wdemq>ycyLl=ul9pHDjAD*dBN6e@16cw&*du=Gt
16iXKM /ku/BdA5nL\k<<$Rdy9ySX%&M&j#pW^Xe<GNF$dHED@#R?jHT4CAQ:pdNFp9DyQGpF1R/eiXqHMlA<Bc
h9KHX/ !Wp\9/VyC5:5Mc\?BI:P+1LHKNAmBh^+#MA:/:F/YI$yTtCEqtuyTcGG^qMa\^<Z#MVyNqVl:a?Hj\P/
LPEyF? j8?aVmiG4S&/ZWnDEa@REn61JeY\bNk==bc%%^8VI?^M1h#@SBQTdL^:Q%?Dt1l$6^ebVMGZJn1:kiBH
*KVyiu $nFwWmZA6uijblD^8Ibi%bDWK9@5jpFDPYw96mJy!$69jZT@phJe$@y=XQP&Q?&a=tJ\+i\qEXlSZ@\e
^6VNnk ^WhD&hL$*FhDR\<Wb#ElV%m%cA/R<p1%E#d>enwB=8MqH&4%medKwht?TXVlDRABN5V<Ny%+>Ln1h9>l
WK>5<9 Rwy/Bi/V>Fn6^w1E6R+a8KteQP^pVhX:nS16EktIpyQ9ydqeN%X!#Kdn@4i$c6JVqiuZ1l$lI$8i+\:E
/X^nwZ A+*jIabK:!ceKu^>H=BpVGQG#%$$IPecI!QWZ4!CMDeS$Z=&=\q^D$M^PIiCnV/aa6Kdky^#m*Ht8u=m
Z+!GJH GXRb:N%+Cte:=J/euY5D%@#!*8I/$SHn8Ga1%4\jB=#Zh$HFD%iL@Y++Z:pJZ$VQqD%4E=a!!muQP*t#
cukZ&I 4n>ceC/pj1F>*wG@6!GS$ljy:G>uNE/jm6aE:nXDR5Z@iH<><&u*DWB*pt^Sd9=PJn>LFNmmXWu:kycp
w&dq\J DaP!%$!WE*5^F>@%R+a6?R*A$JA#c8FpXK&FZ$4P\:6Z&kLqu+:^qAKRK9XIZw\4<%BTXmNw6CV1%Qp!
=^G&Eq E1m4>:$FS\:+mNK^wIqjd\M81Y8^Q%P5QwYtp4Z<ERC=8*XXw+@6B1=MaBR9S%P#bh@AAmFl?e#Dmua=
VHeIcZ DCue$Z&?5KyJtKpM+Z9PdX@M>#dDjb&T4H<6G<+TBKCL^da8=K8u\LX:44!VSj6bdS!Y>TJ&?$n$1>pE
IS#G%h K8:uW\T&NF>#$^8Q=GTa1=e6PW>p:CDPp&54CpJdJRJE<nClIpK=+kchFlBFLLwGX:\:>lk%t%L&*\BM
<IWWKS S#<d9MPGFCiy#qY$W+&==D8piq4ySRI>4RCSl!$eR:RaICihtaAkh9mD>eGZXF@*lS5JJcE4&+RQ%bZD
yZ^lmR tNZ&mt^y6IcGC8?u/T4/eEC>:DL=qK=TD5T!/Hl$DEhih&9LBy&Q:GD>T6E?+hBQ66kW?E%\QcR:uJ\$
5@S$66 #!>d\*J\Cw$ei!IM\Zc<i<W:EJ><n66:A+!Yd>Bd+cDF!!Htpqk5B>>WD+&pqPA9Hia11C&E5Gkm4X^p
>H4*a9 KdFcC%/8e&uwpN!tW4+5HZw:R48S*6!NECILwEMbI61@cMu\yZ^P\=G6Nuu1=NR1PVeA$/>NkZGCG1It
Ph5D&E !It/1ew%&PikM$8S/awB>!A^:<6MD!6B#>>YmjNkIE@m&wu$TIdi+a>ddWR1JcJYiBykiRM+B@b\\54D
l:IqTF *1<+yK5MqHLV5GmyNGeleJCAjtyhE@6Aw5?%1*R6PJekN**:=FQXpCY+18^mVp<1^dH>\FbT9J@Q>#cd
qL&nIE :T<B5JWVTCnH$q&jy!k\QC?@^GBl+bw=@IyhS**\BtDZi8AT51w!b<G65:pyKaBZPejN>RXMKb*lQLej
%%/T^5 +C:\jiB?1FmQFl49My>b%>D//DkP:FN?%5$W9^R8u#t6\4ZR8+=&yXK=#jLWtD$*4A<&jCyIKu\DlBuj
aq4E/+ n*d^Z@EqZ%RBI>>V<6dhqd$BhFy=G/aHGh*JXC^+?!p+:HN?lPA?+H9IBtCpPji6H%a>15^=Jni?4DwT
15?@!n @BlFk8FdMp=kFiMi8^nBG8Muk*uuS6/&/$jIq=/6ItMqa1P:^LecplwmGhDi#W8J@Aaw9\8h&at9H6d^
Jt%Ned QV?+tkPZ^%*Jw61ZA91#aSnVJND*CV^S5&:RHDdlXDVZTd%dHLihw1yFnYHbX@jtL6Y4D%EjNw^^L\k$
u5!>T> RWI4W^R&pB@yCSc@^^=/4pTdh&ZVFJ+\jpH^emu8yebJDwGB:bEdlmaRqZcG^6jcQB+4Sh:hp/HiLD/I
X*kKLu Q\$?Rc!#bEa*%Wem?FV:u9?8G:9?dW:4/t:$tCCN%%%Pa5>@mj5dGuHXkG8ML\Xj/yW?e>=KX>!:ee/1
YZ?$y* *PJcBY9DPQj+cSKGbMb&FVG1#*ktuViadKnLF1<G&b#XbBa:VEH!X>/I+$>Wu>F>w*kcb4ejd!/@qc%I
-AZ84< 0009454fe7a00110333 Page 259 of binaries1.zip
blb&+$ wCyk\JcJX:FV:tt/9RHCqb1E!J$eDkma6JH1*!%4qL+BwqSH8Z\Gh5k+MWy:R:I9F?K+*$QF9AGRZ#qI
\pHMWT ^#N^4^KW4K4H1#qleC1hdR5%*\A$ckbwQ4A@*kDnc%4ZWEQyI%cQ?LWep:ej+A+qT+H&58Wh&mcmIN4$
M949CS bMXhCM?b#/QZcqtNw&6e&qb8VW*%#PZ>tEY9^cW+6PKYmqF4hYaRtY=*PCq^68y>p?FG6cp8$WdGLjX^
tTQpRD QN5Tln89!nbd<Wm$^>WXFk!41+RSh$##!^@BZlbeRG/K=XJa!u=WI8KcEX=ZH$Ae^HZeQjKe=c$jX61B
Q:$huy F+kJ6+Suh/VB@NC&8hP/\Gcy9W=J<X:IqjHJ*RljCEMX@k^@!i!5aeTHG8lcLdT+^Yy>RJDbyN5XbPRc
RlVda$ YLi!XwcE#=RQ>kcAL<?18:wip<i$w1C6&wpKPCyQaM#>ER\nAlp/?I=#9SGiqtbbmAeG64d?mmTl/8Tw
W<&ZlJ YW/&5Y1#>EK/%Z8/cWaPa8:n6nlBkLla!Vh=4W^LRYd!Hq>C%yXBGP@dp9/TR$=4%/%A*iN=B$C*Li*i
AW+V6R +\1KwABcM*9tP?A:$lERa!J@A+Wt9:j=<*TZ1&Np#=FkC9ec4wnd^e&Pyi+9B&VF<e^:abPVpB$JL@E9
=bH?S# &9S4YZLn&iw%#%?9$tdP#V<=wGw94mwYaa<+^kmeZTy$CHD5t4Xhm!W*\6\w?LkXc!?Q/ChnteW#XBZH
kX@GKA 4GLB88QhZ1V66NSF>Gw$&t%w9LPldq&bd6*$d*%XcSHZ?ZaX$4%>V55%l1G=11JDQ*aya5jniuPl\KHJ
6G@Qj^ >RQdcP?hZ&IJp$=t=LjQGTqhR6h>tm4nQ>6kS1MZGQab@LKhP?Id4p@!pqnQlu89?@Qi#^GWQi\CTD*D
pVC8pX 4w#j&Q/MKm^uGuZP/<MNM:lnHE$Y9S&4<q/!l8e4GkjCe%wEA6ew=*nu$%nNaKYQNp5Lh?5kMyVLt8lK
K\nwk# =8F<e*LILA&?RTK\*!SCK5uWSY+hWIFXe6#di:yb!Z4*8yX9Mt>#V49qcLcHFcEcW\ml$8a6d8:%ky6=
6TTS@V =LR&dnN^J$+cq=ywyWwV#Jydi1F=M&G%h@@a*:l*?Rd+hCd+88e*/%Z1\@iDu$pq@@m#wlHe+DkbmR5B
<:qcVZ Mk>9bww^%<?XPcY+mW*w$qt#/H*Q/mLa%d%5T<ee><a?6TD!&4yA<R4Z4AwNM8tiPNRbM*4%#$bePI&#
&TqZH% YL/mVtMSTc?%X^?nKl>L@BGJd=bDpu8mb+%E>nuNCGlpXmK5NEN5Rpttnp+i:<<?idEcbi\1ECYtPuY/
%X1@Wt FaF5&6wtH%H:KN/XJwt/+m*yBZI&V=DL6dw$ZDbWcD^Z>YEYNn8ZD1?D!teiH?:GtH^m*i4uCtTjNHIp
9alRcl 8*u86TJ1kF1+BYRyp/*9WtISu9kNpJV%5QT<wHeQH@p/jP$*M9F<?tyX@SRm<ka\@4E^#CP/=\hM*FDY
/WVJaY 5WSbF:QHhmiRL&&%X\$MVhSlu5+&9Z4=qP:MNR/uwQuXDX9?ynS/+HKp/:AdJSQyTt@!!8!#!^4tGJ8>
WPc@Th l4aaTy$RMCKThJVJATYF8CNpl@Mk!</tAWFNdEE/IpGPcRqI/n>DENW@$I/BZ^D*CWpy:wpD:Zt!<>w6
M^6^VM PWiP\\Q!6C14:FFMJaKhJBWd65JiB!IJ4^1+k/8alep^?F^^MjF69?$N$GK5h!eZ1<h!\t8$+GLp6^>@
RtXW\u wMmaS/CI*t\ua>X:d^uGt&=kE9^!q?ca+8uTq:^AYVj/D6*t!YaYj+eHcXhHdh!#KP9+Iduj=lA1%>HQ
Z*!?pV nVT@j:P+>*1=C=6t/CD6>I8MJd:Y%XYMnFhyQ*D$=+J5Q1A+<\*R:e?dtcw4A4/k^1?8P$k&?CFnm4Ch
&m<ha= JFVFSIPa4=/DBt%P$@?tm5RW/KdcKCN:6&b5\ynZ=lmXG8Sa=yqaF6P6?BH@^+qYi<a\&a^#yciSq&w!
+4/L*M mk5!%amm1D#8Dmt%QeKpW5/1wc=%ww=Hk5V$:JWPHa\LZMIdAGNXhZ+%q4XWV*9dA@==?Fy9u#!bSac#
i8KGKd h<SW\an5w>Q++XJl#?M*t4u!DpY:Q41=d&?VEY?A@>T!D%@&#H^h@XkYZuy@W1DPP<Ln&%mZ/#ZB:MaE
jIeR6i j8qne\uNYFP=#e5BptIt!ciWSi*dV:F&9F>&Q>P91Xa5?>T%9kFwThR*Z4FqHV+@DHY?p&!ahc=tEKIc
n1Kdc> LNY>Cnqi>TqFSYcZ8>d<#uLTHDBS9!jH?YB*VTDcmiMwjllte%FBy/IwZ%e1n+Sl54&Jk:\w5@8\i!&Z
GaYC</ a69SZ1tq9iI=hLW!#yTa1Ckb*l6SZWK&\$A+p$dFP?D$*t@mT#c?:n#hnaX6Rb8XKm\hdRXSQJ51TF\9
D#qHRA DhRbJYTwR?dC?QJGY8PLkq*H9Qa^HG^jX\Ye:Zy<M9X*aqHP&9XWBVMQ6?JX54Ywd*aP&GXT:>ANd1J8
J6w%Y= /GNh:FmQt@CL$&mEGaMl%!?@8NF<PSGR?&HVyWGZLB#Cqm+$\D:dZu5IGyER:16?qN=juFByb=*MZnB9
y<lM%X i<=mqbTc^E&HH\hk=%5PX!tQL:X&idAb!nlYa$+D\c<\DpCG?^/*t1B*jRm>e5\\TP4w+RpDN^KTHBNd
\aduTG EeclW9CnHjNDcBXE%\68:qF/!BjI=D5%V=hGt4T5N+CHk*%Zik>/GL!Q1uJyyWSQNFYjSb6JhnaTjdqk
Nc<mcu HMc4aRTIZeFF1CjNB^%S@EVJ%81c%%dtIh@PI><+B^\$IN:\+bmj8aEy&5MuVS#<hLNwH18qNb8GJ+Y:
/Y$H%m w6dE!\nGt*PjPwXCDh$HI>H/1:9QQNZqEG%E/Y/\PLiy++=nnd5in=uBWN+5Xq?a6LD^6?jlW8QbZB=d
!aE!nA >E?Q1%RE/:<5W**^@ju^?iRNWN#wIlw9A&8jCEuHSGqKA\bRDEkP:Gk/Y&?S&u?^qBET%WGu4cIyun9u
aB+jG? LVnl@G=pmVd1RmZ@PVlQmTCMl4X:JFibKwICDiAMMAmJ\DytCE/aYW%iV\KwjbyJ+F:c$=C+?uc\=eEL
KIH1P4 aYPYS6:k66@++ND!VeW5*Z9+AiwA:nQn&4imXc$%>ZZb/<1>9pJTASJM*4yLGuY%59t8NibtT<**Hd+1
y@*1+p NdX#hDu^Pl?+HPu6jn\!TaFC4*+:XubI<kD%nJm%lZ!*<qA?&1Yj<w!!b:HXGmNiIDZcdRE/&F#XNPA9
nKndu\ ^+mpF:TqiWX8T==nBukii&/?b59ta%^4cAFuldP!4dhWtnNR=FBSc&?8?=VFbLjuN<JH?WDZj$H1j>!Y
?L=:@? S$V4\^qSY1#qj1@?/6ZeSb$B!%*6aFh^#Qp=LT^&5ce/>+m=D+V5$<WFuY4FF\RFbAeYIQApHn!:l#wZ
t\n%c4 %pwNtX&BXF#SSb=MaQDiXK/85A^E::dXyX@t=t1q>yNTR%amFII4hD/#YQ>QupB9Nwc@EtAiW#R!V?Q<
XCpJja $Fb%5LR?m^85^I/MS<Wwj!1DRFiT8@K<mD&ne=6N9^lDDj1tu44cl/VTJE@eIGi*YqbLMDaI#/T^N:pl
d*VaYS Z<=H1H&y8SD&@p5M51@^\@4F5KdL^&TM&6X%T#WyM=AYW*WnG8wJYRKWB@m*/bNq%qaZq>LSjJ%lM^eu
b>*W:C K%!Y*Zu+b+MpcZ$lwKLVy41+=LQZJbeb*^5kM*JG<&RER#MC6nH+PJRZbT#1+^9k/<hi9/FKGSip$ZaK
yl!P+X DqWbZw5#$55u*=>niI<p\<I%$6YF<QXiJpFBFe:A<YnKZHZ?#9j!tZn^c9+S>/BbA6<YmX&dh$N?!a^4
t4%EtF AymySJ&#%TM\d\D*cG4wXkj^!l\t94QQ:?Ky6TwF$ue>6CVVkS&^a*a8K1##q<#Q5wdN?uVbFSw@$PR%
IJGYT& Q9XS^:?uq?N$lw?Z9Xhn=pk@Q8aHp!AC<ZDRyQI9R%h&Buljl:%c98w<bH\nTJYQJ6+InqjuV#l?N$ew
wSCb#a hC\6ibXLM<6uI5D8WQm1@GA*:Kh1YFq1Pd6@j\<LTuppV4^K!!%B9pGKJdBQ1jq1SW??nG4ZiM>/Nqml
+8\BNE /1>/:HRXGc9ujbnhXY<hdqN$>D*DHE+M>hEjTRAN&9%CRP?/TGPBBhja1MSCWZT>JIJiyC>kLqqWdhGt
<64ud9 R^?qhhXq8RLjMwdq$+tt#R$TtZpS/G^P6XHeG+DF$5HKdXp$#X448DcwZBeTR8=<Kdeli1+bQbH4iYjA
NhD^1! eD+kiw!IaN4\GD!yGCi:qd8+T/B/u*qhny/+8*Xd!$lkWkqWk6S?+F4!K$pWyy5Sj%qiRd\ZTN#u$SML
l*ckGQ :=j>Ji<>^+@tPHA5ZiH9aGF5^Z?eR@PN6L>R4?Kh!PWiKiy&=h%>4X1dFp&5X<8$P5yHPIT6qnTI5Z/d
%E*w*P !Z/IEHI/MMK%VZjNICk?9c<jQ9d4Yj/kCnhnb8Y%YKDiF/%L=Dj@\@X?k^!:Q6nZ<XZnIXJ#aYE<Y!8E
+W$>qA A>^%!A/14JRmidWYqeKZ<QYWa1t<YS4p\Y@@$@luQ1%nY1N>KT9VGS>/BbQ/kK!?*CHKAT1@61eDtc9>
!/K8pe PIh>BCnyij1P@4JXq65K=qE<J^H4kDW\<cBn?=:iTGYj5kPG==e4p/KpwmQQ<?\FCPF^C:jd!QB#KY!$
=9>?iw ah!4%ulS1E&DlX/pl4V^lh&mV@6T=9EIR1QFJ@Qn1B@Sc:P&$n5A%bYkNZ++F%qy:+%F+u^HAd&:dwMG
/&qjMK 8q<aI?XM+JYH9wy\^ST<8^wKEiI?K6@R$hF+IBkhVG/5bAlj>S95dFidnT8h&aLc#jpMj:V5q:k*iRye
YZt@aj a^QwbJ%Q>+c#N1CCn1<e5Xn8TJt%VH:m<ctq4QCiSTh9qbISQYaBWI4*IK>\R41wXZj!p#R/$AyP*KF1
uq$#q? 9piqBQW9Q\\MNZW9+<EYW\<<G:Te#TwNi+meu*tP4lB6IyGP6$>GKZCEphAKR9@wiE*R&N<Ve\MGIl1P
Q?=!ZP T8QkZ?JQXZIIYIS*qZl8=8LymQZWy#H6!nuZdChw=*kDQP<C4dt#m6eH:<=a&I&l84GKCK4TiKaNa#c$
Bd@1^> PnH1?Pd5K4huiVAI1!8bl$mhq@N!XjMc94*Nu8GdZd$Wy#6V4+E?LHN=#WJQm\tP1ATX$#PICFFMkQLS
%4*qJn Nt!R9^wj/t4N$yuNPpjdWqKMZFmiWKBTBh15986Q<41jTMq=XjF+V$ij@&ZGV%^HR:8PynqBl5G<RKWq
kYwt+D <6=&n^e6qtnF5YD*TY:c8jIDu=lWdZNh=AN6uunKiSR<hkc4$P%Ty+/wkKI1A^yaDc/hNPFew^RQyt#L
9NKSMN :MXGeGjh6hQ1HY\ZYW\9!uQ?XLWLb5h#@<K:/QM1u9h$aK?H6W4NPG?AL>CQ@NXu^p<@?bSSPEFZ&Sh6
Xi#Jl# V*Lnw+FZ8<qJ!/yVYq6w9<H1SEVWjw&WYy%S9aA^#Yhi1S@N@kaaGwl>achGC=EVNW+J5+ZHDV?$/HwA
%GuWT1 Q1=8ZE*+6h!&9T+<ZSS4p*hP$lY&YSnG/bA=1thFLN\iED/9jYpQ>EImPw1HabE^!NhKE9SFm=iV^Y4%
+Bn+HZ /+@?8ikmQ<nm5c:w!N>:+SyyTtdDXJ*5!T%wEmE4EFPq?jyX%eJ+6jS?wB<>1mJ8ldi\iJk/kMbEYLBA
H61bi/ 1WZ!@h*PJP^$bG*JyI8/jKTQyYN@K+G/E>wQZ@S!t<p*\GeqY1aN?ecA:Xud%*b!X5b9Z+%+$+4SVRRp
q!teLm w\eEu454dR/Y+K#Va%LkSL%%J#!T?ZpnE:?>#YZ4q$MZ^b?nRAlB/aZBZt=W!Vwb/YAIt/?11KMddCMP
NZ9$<% ew<?tHmR:\*8B%<p5!Rec1$#1&MVtNAPTXm\?CWN>L=au*w/q?:CLh%W!54Jnd4h$#5WYCJcwFe$\^9H
qFKtG? D&#FVJZGJwjHDBSKXFIyQK!Zq#$ILwnPDM:j$54iRe#a=BJqC*cpbjG@JGuP6eH4Z9Qd$d!1cn#R5H86
-AwJt/ 0009d7bef3500110333 Page 260 of binaries1.zip
R%Ml^c dCHG5>>aZP^Zj6Y:pyekiR=^hyE9R*iFyaC1GhTZEb#e$G^5?\Lcl#Phd/S#ld:@5:q/eh:j6bh!$udG
5D*ICN Z&$nZ4$VEbF#e$SVI?JLYGc6LNM<$W8NB#^P=LQNNX#h=QZElG\Ye\awQDX?*<tT5i%akWXTuKbM=WAR
@eRpQW dC@WDLak9u#JKyHVXuGyXKVIjh^Qwl1uMB#Fyw8dFm\@dm6Z&5TLyn:VdiGTtPPV/Bt:8:ABipuBb!T^
H\GX:D EGh?YZ^?9j!+pVwqRS=@c^a8^XMt=6ZuRn^6*G:yk&JAZPPmy1Tmn!$Z^lYWEt>HK<Ip\6\ydK$YGDe:
I+&8dw Zhl%dCC&*^SEu6wSY1/lqi8Xtw@yi5^GhncWYQJ?qMKEkJ91mn#NaK/nit?D1eM@py%AjF:4=cb*B6VD
%=Nw?J y%Z\+^$ePWpN^#V#&*!5H8jD/HY^6A:D+#!?a4Q44K&c5%dwkZkRR1RnFiZyP9c$e>D^8lYtpQ68P+4\
u&HKSV YqkkXy=jt@#JnWGV>XJN1NyWFX&^XRpiI!GT>KpI/?IB!4Zp<IHhtBdTcLtGl<Y<$6WeYXR/a:nHGQWd
nuJMih AD&Hkt?Wa<FFSp8<8W$GG/G@dBEEN6L>Y%F=#+iZ1imFTPG1\AJpD5YR%5wZ1cZk:IS1KcIay6=bXWh9
yYnGAL PIp:hhA*kD>pi^Ti6jeTLQVP:FaLN@T6<WhSn$tH*VIC!/e*kMFie@Y6i%i>uF:ka+iuW*G@ZDFHaRjV
bE&8*# !5t4YaMJZ>55^JCq#hG/AF1J*&d9y*#IuS&^8MCB\w\c*M#$S#c@m+6:MeTky+&Dw<D4hI?W+dd*wbuA
$\!N5j #^#etG:yTjMFqX\=<Z/!:Nd:N@EW?n1lyYli#ZIw<SKNTF^/1MA5+kZb!D8#8T1+Id@D=V=^*wjRWdDZ
dCFXa4 <Pj?X4I1:tEDE:*F?luy^Aii<XG@QkjY1>D$D?5:E+@Sj68SZ8^1=<mbbn?EJqD<P4w<P<F15met:L:e
um!6P@ Y\TRZ**:@Fq?^9c<WabbZahV%aH$:pyD?qI!lDLHnu>X4D<A+a=*8uVa$X#VE$bAeJTYA1ac%w@w=QQd
Fa*%=N \6tndY1/Y*u@\?NH?VlBNNhi?KW/pIipB+Qml<e=<lmS89t#qPnKM/1KVl@5:6XKV@#!?!C<TSc>5T#R
cWRn** nYjGA#<c1Z$bB91<=45R4lD*NwepWt+V6Fhj&l*6XQMtjM%J$ukj1JH/yjWJmlQ$5wHh>#<<y>uD^byL
<#V5L# ybtdy8uyd>Xh%8!JJe!^LNKhdeby^+Im^$ptuhJT6lahBPTyFj9iAK#Y^Nh/mVhjPC\8LVSHbY:b>:XC
Hc8L$S I/B8ZkRDplTYQ%:?KG>pG@wYZ%X><+Zm!FM6=Rb:**#H%Ml=R:E=86A%LZca*TI:?Ek=QPC!X/*=idRN
Snyd4C !QdItlu16/cq9hb!6$e#j?!*Ke4TWZ<k$W@ujeREN16yeXj#KYiE*G+RqXj1t8yb@tFHCYtHqNYS@luG
KNXZl$ *+lk>HM1R#/N4uZ#dL/?!lpLLT5Sd8qm8aV=JR9$*hhZuc8>&/aA1+KV%/A%>iyeP^j#<>Wetd!>E?L$
6ui1ZC 5tekh:upknhV?!R68emNu^P^j+h@CcEj\?X>4@1WpWk$BDyABd@Z8tP*LTZliZmZ%9FpdF&kTWhMdFcP
*j8kCQ %tmW>LKWli#M!\$I=nAh^R4>Bwn5!K4RdQyEu8am>?F5+EC5SduJ@i5Ju6I*?GmeP^BTAGIEp>Liy??*
cb!AIH IaqA9>EMq*TM$kVF:ZF49NPbej8d^>+*RP#HP/nAm<>9p?j#GAwYh\+cQXI$k5G4e&9lNFee=^N>>RV9
ce%DhS Ay%M^#M+jLQ&iHCH<h$+R>JM@Q#e*I\eTKhLLHdV9TLDX4chn4/mk>8$w^NkTBT&Qu@6=D/%Bw=V<Wdi
c<VR<X QlT&y*//!t>EEj$mZBu&Gul>?@ZAcd@e!yTu+1cl=GV1*C^n<PEu8i*TTLpL4:8K9:%Tl$!\9AEC%Bt@
X@/RN^ dQF^md^iQS\j&Aai!NYu?uC4M9@au*ct=>V$mLJ51%#QKNGT54tqZmKK$hIwFHcmaRL1jaq1MFpFWbAj
qD?/M> JM$Zu8p:a!88y+Rp8dQ$?kS9p@\JIZyqXdR@5SyN>Ln^yA6:@^?!>Li*1a8Hi6PllY#89iIHZEEd$\jy
=*6hCc k1HaqSXKpD$*48D11^^VQl1it1:G&hQKY%^K<QqtlaJJ!W=5QEiqi#!Wj+n9j@>n1KTq6c1$EE/&e?hS
Mlq8J& a8qh^5kQRMMFtVTYp**8ut1p=##tqR#+Mu%K4Ia//^A9wKiL@kckIqS:^Z%\iy9?&!YM@&6lj@@#N9Q#
5EuIKd jVQY==&4:LR1D$ed\=eD=mPF?YuTlCmB\nn$yjmMiNdlV<ui4Wb:Ml>w*<uEt>WHyPX1lh=mk&YLwJh<
RbMSZ: RTKY^j6Q^hcq1wmDS$Rw8?A@HSBN<hF+6^j:t8lIYdF5n^e9L%9cV=n6u9H$LWm\qjV:p4tEkjJM8D!@
DGlWp: #j:t+8a8H8wa>>&tPu1L%^<WZCKqjAS*TW%JcP!wGF\<5V#Kb!@:Yi^+H:kE&%q^18y6dJ!LQ5EanwWE
5KVPX/ qJIDXtHkwSEp6/1TKw++>=wZkF/LhyXB>p\4R*WW?mDd@SK=8dl+:@@%nQyiK!e<4NNYJ\@V!>MR>MC4
=WmD<b GtYX>+8bEaie#ep5u^k6ha&tYXc$?yN:%6i%nP*^TS9nQVVNh4<Gj6dN1IVk*Gw5#u#P>*P$Q4$h^c+T
GI:RqJ &CcTCw6p=HwGT?t@MXn*i=9@#R$8ZKlSe&tNNXZX41IbkMh\WLWT\DEFWwEeM+?@!n>*VdG<PCqQh&#Y
Y?a:Zy L*5p!Fpa6>+W*$^9!=wcehYVVPtRCZbR%yCVJ8N4Zc5q*:^w1Z&bBRcWu#lyF6Kh1&!uL+>kmt/S>VFB
:4Y?bl ^T&Y58kGDZJ?T:+b8lquhBi6/X#TK6$Yu$dZ\Ae1=lI4K@AH668/>Wd>/:WSEtS1!ycYiXB6!>Ay/jAK
N8VZNl h:ZYEYKh=\V68Bi<:!:thN8J^bWdjTF?Gp*Y9IlV^KZ%W<BEL6NbG+h6RBXncRlb+/WVnaumM$M+<$+k
LFa<Y/ i5HiHc%pF8?ewc%EcJtZyB*9$TuD6lYmGwc9>d%h@t#8p^/Siey/h/t=$t<F?nEEZH%dwEbFwJ@@ATVm
G1JVt4 +G*!N#W*FjhRaFu41*@519wGWFGbA+yte/YEj\#ERm1pdWi#m&/45Yum>4pW:\n*5Mt#YPaiLlMwQhJV
JdT&WE n$jRpt1NaKend$%aeGK/RwX\k=PjP8W/WQ>Qy#DkT>>P6/P^RqtbtJ@P+QkluWlVIDy+F+C@NN4Stt?q
^EeD:= c%B@NhD1iPSqW6S4XjL/5VGcqp44BD>maP\%\=PJ$B+*&t4Y?N6\q!/Pdu&=JiP*EmtE:jK\Y&H<A1bl
pimbc\ $ukbNEWHmQkGL6V&/C8dDFc@Z*hN4C5^4D$T<QhWjTA@D1m9MjI6Tu\NtdZa9Z^I^LKuZ*j!cP/6w&Ky
i?wmwD */i>$MhE/uWj@P#I*aFWCAK4KCu@/W=MG@jj9^66PuGy$85%kM6tdDlH1*eu9nY/\wc+>65QVcL4cQR\
11/kqZ &u8SjC?tQKjReIJ441Q!5bqm1mLi5=?h?N=wQclL*D9A=u%MXJ6unRWNeWP>p!D%pebZJXE\I^JiKicj
Tn\LG# y?H:bjjNlBy@FYLVuQ>TeaLk5a@dd9Fm:6\TicZFejk>NW?\<pmWk<na/JL!B>hYhVLRn<JH>Q1bQHhy
iFuXyb Ze+DPYTd\kZM\RpBDQVM44RAMcdnhYK8TMd=C*AmBZXq*LE68DP@RDP\+<PCRm&VW6Dc!p5+Me94FWMP
5Z<bj% \8GwI6@jlw^@9ScBL\#i%RWuTldySbZYb5&%#ELAM4AZHZLau1$<=!S5qY*a%dmYew!Z#CCL=DddcIdR
cPJ#?d 5VcM+PKYXJpmT%yV*%#:*KC?!?Nc=kw#!/S+wu8d?FFc%R8yLuZc\1ct#6t$+1byC>Tnlc=$a4:Dp^ay
a&u?VJ JmpS>F9QN\Dlp\dQ#EZ8dMXYy#>VRX=ZbqBpQqn@Vy\ZE\NXd=>?=6@ulF<MCV%!VMN:w>SEbS+^/thE
RbwJN! neCIt*aSG85ul^D%mBE+yhQTDYI&%&Zhmy/Da<#H?EqQJ$6NwFMMeLE$Ghe4+Zw9SFh9?9pL&yphVMmA
6qLJEh X>bijcRey*a#pT>^Hb!@cbII&?d5=e1Hl=<n#4?iFuVntBXHyZ#>&E%Ba*u\:mB4Hpl\tlwRS#4dWi5:
VyZZe< LXj+6Y#=5TDB^enAP%b1%IpiTTAu@e9a$F\@<B9%wS5tZ\H\kSb@H/NeP=y#t88\+Epw\=QC!P<&9$4K
hb=k*K ^mc@IWA@Kl/nwB/uulu%@NSdI=\e+?@u@W8ZQqA/adC1im!1L^$6i9AyTH?QK>iWLPXB*%Y%uytmNG:*
tjb5ld 6IZ6E/eeMPlccSH\@Hp@R<j%%CLh&C%hNa?IPaD&+AlPEaW\L6@>uP\&tLet=%KaBb:Dt=\<ZdZ+>yL:
BF=i:: *iC6%^Mdm8/KY1\1TZwdC^VF46K\b9bAFDVKb^y%?nR#Q/:na#1!bAp%@1aW>$ycI!e$S&JdHw8Yc:eV
dtYTGP RVS4lnIb4t6bindN+#w=P^hVRhKtyk6TXjGQuG%MWl!GA4ctelLy8bT%?y\I@btcYZFN5\bw5cCZIcXm
Se@cH8 8CE^I66C%LaXFGI/MYIXHhM$*4WiJejBXddAnLTdJS+GH1t$4e@Hp?AKAlPPT4aBGd%wRSILh1jLF&QN
Cky=Qu %\W^SZyVuFIb#tEkC6A6WSXZZ\#Z<$y=AD<ZE5jyLq%BDu^#N$@n56M@KA*in>%9<$Py*nTmZu/bLnAw
NB5@G$ 4MwH+1SP*tIkPbDTPyk+R1F\K!SJCFE5GWi%ZSZ%Ia8\AVd?9h+XCEFq8&EVM8eZSPc>=+1YH%1pMI>5
GCn%$q bIXVbPPQlG56NJ$@%uWY65?#6VBipm&1Fue4\e@IVqhWIVS?!&IBK^ED1w=>/QSut!jZW/VwBEQ?qFB%
n!a5^5 *MH&XVQ?&PG4u*NReuN8H^&6ZSK<lReIE9qeWZGQl/h%FiTIi>5qF\^6<CqPWuSX94WX^C4n11Cee=J\
p8CX&: =A?<h*>ulNq@HR/SQXnyT\+^&wAb&pep^&!\u9ME\cRQpyuG?IPAw>1HWMW=mC@yDXIj/y9Ch+QpRVt\
mwQJWE Xkj6n:BF#F^q:aMVmu8<:lCdQ<<>D*bGLM/#A>$^utMC%X1T#yK?nMAeE<V%N:T#NNT$ZEZXDX8PpP9\
enG<Bp du>kdNiTHD9<@9PD8K5kRbAdPPSlL!!\i4T<ZRhVheyFntH6GQp+<iY!dCVV^MPnZ9\1^A!?:Ac&WIR!
/<Npju a6DB+5Ft:\jR6dN%keXmdTDNkl1d:4#RWVKQppcX=cZwmd4%4m@@/t\>dm?cWK<q?@!d+mj%?RKhZktc
#CM:X\ d#^>Rj$GFl=?bYqE<!=IDFyjZS+JJDH45NRZJi9FlCnqk8bn#Jy@eN#8EJZ$&NCQhVt\ZSi%:1X6%mL#
NIBeK: &/\9>6KE?QIh\h/$t8!Muu1=@Q!\NZQW*K^Z$HG@6&LqdB#jM*Il*!YGbl/@y:mM6b6L!M^GI9p/Ij*9
qYSqJK 6Y^mkJH+@eEV&yt/l:C^8aDVbBSH?H6$uu@4ppt$iTKjbYcwjYPJB@%wiqEBm>WKu?J*CjDZuHkS@MJG
E*SFH# H>d6C5#ejJ6LAMlS<L4XNhW\?tA!h+8c@DZ/4k%wL<y8emRl^RJdVCMKFbk<W6?kQyNakeZWEa=MTAIe
eS5ThL SpVQP1:/+1qpV!R!u?Qt/4?%66>@tW^k1:j15l@b<%9mF%Rw9<6ae+mVqBbZ\EwR\C=<K1HW9N\A@Yb%
atNVmV \FSE:cMpK?@/d6mI$RYjG?M:NWGLq::hl^WLDCPX=94PBIY==NQZ:QbY$Rm*NwyC!/nTAed*QL\EWQkj
uZ9PQp L$I=9^^?Kj$<@e^dPiS\wK6djP1y:e8u>PD84ZIW6*T#I1HQNFn?EAluTEWWVSeb5KXBt:*#m6P11/BH
-ASDT5 00062ebf60600110333 Page 261 of binaries1.zip
mEEBhb ZHk:jTm4y\YcWq*ma*RVy+jNJ^:e5uZnMB!D<lYly<iY8>EBh!uiZYPNPk!Bd!@hBC<P!bK/?M1jwid+
<!9V+n T/yd!n9%4*5uQA!$kydNcn*:pGj1b=5^HBt:#+^/H=cQYBYQ=!@%8k14K*8!jK?&YWNMW\5NC&#LB=A@
MQw+kY 4+GZKiX!Hj#4VGiwS1B&R@1+kFS?!h6eLw9Hb@Yb6qRPL%nZd/T/?KK4?QD?l8NF:?mG#$W/@yBkc/PE
jJhe4h @wjS5X@?!jjZV#ihXDP9FD?5Rq4@9dB@t=t?9T*>MpTK/Sh&dE^5\D?IeaQwNRD$\NJlI+kTk<Xq+5AT
/uL\aS aaCDZuHIayl^lEEZl4q9P6LlRWQ&wpRlCkJ^^RaERX4G6DtTM1N14wHeH=XDI+h/+<ByTqpkEEkb#Ftk
AF1$y$ ?aF+\/I%AnXn=uR+$b9BR6c<+B\FAmj9SnyNeXYS$iFhRZQZ<Tt\I!SDTn\\:GGDX\%mN?Z*iSpD^Ryt
hyuue@ HeItBRm\9*=Rptn5etdPZnRH<@C8C1ebtBy\8P!weKLDk!h#paLp:aLF/A+Bk>tL1KCd&1mw8X4MKcQE
%lep+u &BCBalSjqDhblA<qDp48hhZG6ueNuI1hqCepPaZp11</eLXkety/mp8Mu=4GmyA1FFVih\9@*L6dD$&j
BLeZ9Y MymMb!#c1?qh#KaC\b?VKC=MhYBe?&#N11?tP^@cWp&FAKkcBlY<Lh%KNa/6@^TlY%Fi6w8j#Z\GJ*>e
>qeewD RV<1nMYIwI+&H=+QQR?M:tZub+n8JRa8B+Q%/8MEk&FNweFjpp1jeaX=$&DSn+hya@ZtpVyQ$hiM11QB
+/MpaA &HRdapPAnb1j6iewP8N$\IL!+6GQiXh>kTS1p?\AB!t^^!W:#6ke#Bq:Dm9>Rt6ik6b1\D?=J^Ep9duD
QDSXy\ GlAbk>bTG@ZAI&5Vqe4\LcBduy%DwEYiW!+8!EGE4cw<=uC$Kk8NI<4y!aPLXRlbTWnlLFYAq*$t$^<N
8TBbHN +hyjut9Y/jBIPbiP@S8:uA4$Gn8pe:&HwIC#nyB1T&?lnQdCnRncj4Q#LV!4:JaI?++TMFFPc@ctEA%b
9@@GHt jZ!Q^T\a4F=@B^=wa1RZ:XLw#L$/D+GIN1XMEt*Lqt6>Khy!n&dAQ&\k+mGppDAuSpGDeq&GN^JaEA\F
!q6Q</ 6Di/jn>We/*JQWhpE+P5ip/w9^JXFitK4JCcJL?wiVN1^KMC4N#^dt=pH>tcEkwlEXG>DGHlcaql8NDY
5S*iXM tFB=aFhR!nSR&G>==jE>!JZB&>NTjlhD\WFp=Wyl@8:\lH6KmE:8k&WA9@ci+SakIYb=B!F%^TRh9a1y
wQDA/b j&EeiX5W>@$64?F%9bGRKY&&S:ye/>&+!pSKqeCu/ibuS\naACXbLEl&Pw\y!FV1H@QV$W&:J/^J>p1S
nJQljY $%\^DuL1N!<?GPCa@EcSe?#6GWJPhD#IK<=da8^wGpp<HN1:5k\Cnni&GVbVX4ZCY^<e/hk*FqdXAE4c
>WtG6\ h\cm%Ey#6eHBG@e/!l4#6!?j+nJh1@keIy9j4&=FN1YjHdJFLbkFd$@wl4c6P*dY:LM>NPnICMS<ny=e
F@p?#E dJpLmy:@CEdk*cYN1tBjlVhNc5Rjl?ewBm?RlNNqat8VHn=kk&SR^b6kjSHhkGAKSdFY#tcNl<*yKV6C
ebu<4J cWjq$tPNWGPmcX=#?CWwBp8w:EX?hHM6SB$@d!a\^NGTWn1DDByPba!J$%wZI+PRH%9IGl&iIZ1S%:Ty
6c+BQJ G#X8k:\jkJZIQCa8V/XQJM4RZYRp/#*EAWNp4n^F?E+GbF\wnM<Cn!^n^^bj:\SFic8FMWS%94R*V<:i
IIWIl9 Rwa1>1dJQ@KBWC4ek!BYMDaNbE!ZV>T>VXTJhZ6Hw5^lM+iCHM#cWiFnEn*MGY>Iknu<\qX&/Dijhpt\
nc#!N8 wpa%^hIkm*+ZCnFHcP\YJkYJSY^l+eR1XiNGme1%h^$8Pbe#N*YJ^*9Ca1Hn6F<FymAq>*Zdp$y5>=ZH
R:y$@m qAh=YpCDVR6NM&XT=Nc5!5V6C>:6bDuRLwqRDM5\wTm!T=Ii^w6NwnpI&AQyc\PC&J%VRFIN+iMN89hL
9tRDyE TwWV\QR6+G*Z&nQC6N9iucIpHl%y>R+wbkeN&TMGFMb@depqIE=:V\4>9RwDA%Eku+iRL@#$LS%kKyYK
89B8V4 w/\9Sl6a+?\Kn/WM#8\w9VZY/t16M8Sp%LAeSKpi:+AtV=NTwhFP9:tjI\%dau1A$wbZ?L!:&D/1N%M!
HbG$LV pb4A1@P%lRH!INt#=1MHL\KKdLT=N^1+@nV&lA&@q9\eb1dnNJ\!A/*Yb5=yQ@mp#\mM9IRy=!e=+<Za
!6I&nq !W=t<e%cZ6J8@44CyjqpPIVMDLK<HN#na&jyPBYcMN%G>JF=:=QyAT4p*dcCCnwP+QJpu$YuTeJIt!Lq
FeRYtD ahT+m^XaYu?&pqV46@HbS!^>YE=^<NR%WFnX4>Su8k/1AC^$nk<+9VV&dBVh:JJHy4bKM=SYFYFLaqS=
!IH#H6 >t6n&SwX41hn+JK#C5H#EElJF6yN/+QJ9iTmIIX&8C%?HQwXXK&aqE&56%V>F4XVkbmhHh4h^%kqCLP8
/AhW%6 C?PXM$E^!Lc>P4cTE4:X#IaLRm:Q^j5nRX#YGNq=W1&IcJCH:%u&FGSbQub*B%=Ti+I+=u$EM+B^4eEJ
5*i\<6 j/i?/DYyC5nbH:u>uy&$%a++5CXEdD@RwGnK#Y14Cw&dFQkbwaubtjbYuZNa9MQWMM\F<89JBE6HRR1m
Jmj%pZ aE:pASEucXyaIVRqS*#ea&tjkZI&cy\:e5:SHuNky=/@$ZDSNa9y@GpCW\KBSKV<D1Y$X%!T4tpwaGmF
%ED6B< !5\tB<^#i:KenWnnAbkhI+W=hZTB%tLbKY$pFBa9<d/$?c=mAye/%?VHXAVRqBFF+/Wq6P^AISS/1&TD
qDBd4d Y5j<W%EiyQKyVb15\yhHpGa4=?h4VM1?^1Qdy$y!::H/h:=G+<i:^#1YA//T=H+XP/wd\p<mh4ky:KeC
88Qm8* Z$JX1^YWXTGT6w\ZKY^1NT$cY?*VNh+u4lyE+>JR4WS=&Yqk<Y?+*JD=yu85uK/MX>!?*%!F*+jjmDdi
JcF?d4 8DMY/*Hj$YM>l\lSJSG*4p#TbZR^1/t=4WlJ!VAc!<4*CGJDEEt<\&!C6m<$iQ=mdFiIbX>j>NthnX#^
4T1C8F :I*5M9ydh*QW?n:NN^jDEySI/TuiiM58P$P^#!pwS1Wp>G<5\&%wn??yE8K@CVP&ydm*nhjjHn=AVEI8
\bww>p #D>y%YQCM?8eE$><lj*P@BWeKjtk#K*mSu#$WA>Q=EL!6j6^ZTj6&N4l^ca?<hYGK:8:uwGw&Vi9EhX\
D@laNi HcKTRF6Gj9@^!W?6SEZJbiHe*>:NJ<Eic<b<PXm=?kd$#wit>F1?5N/pR1lY=+RqVu4R\YyYLd&SQi=1
Dic&ta b?&htS=L8dJpB:L:p*/n?+4AnhSPFWXJkwetdFNklIS:yl&\TTk96%:l@dZT4SQ19F&bHSK&dphZBy99
=WNW@1 8^$X@1D*V$qN>V/X+YYi1q:cuB&lu4nZu9Sp5+FRkXhiJB^:h4tCWmH&P9#:d#DmF^@YW$Y\uAi=hit^
6HPXSN Jucm\k@9IwVRmHcH!GD:&IMaJmPc!k6aZ\c\A1mGwAiec\9$6\@L41Q6k/ZGII&>A*Q+G\y8KlppqZ16
R6GZcJ NcII\IYj9cYPJYk4SAElmJIp+HSlRZV^9Vp>LnaY+IYVXmWSweKdw6C?ewYtC+CieIwe&6+?SwwB85BH
@nAMFC $l^4?tFLHlyhTM5/mD+$<4^p/V!5D@ywFIB6w8>>lIKc+9u+4A\V@h?dCA&jGRk6tRkHiAG/MIVLp9=l
$RL!?! CN9+5CT\u+dBa/Fj$\#B!i#:+5AHcEkua5Fu+?u<DW49kn/^m$J\&=Sq9kqX6IW&=QRd?t+/AwNea*be
5D9A^e EeW?!QGjnqJBh%YJ/$DuGQL4IFI%&hwQTiX==^>P9@S1RW?c8>HZRydaGlYGIeG%AQ$6SREDp?LuIdcm
<Q@:Ed 8nSaTk4m:FPJX8G:<qMj\&ZAQW^h\<D5eCq!&Kuh!RMqE<E:Y5mJ\AqHnm5n&Cin<8#V#iWqXT<6Hcla
h/e+cd BiECla!WbjJ6Qa#e<FGWJ<&Ai!cKa^iW5N%wlIT@ZkK#@N>n!$<9!9m*RH*Y@*AS?Qj\#:?l@^d4?a<a
yApZ9@ $j@VHkNM9@H<eQ4=T54C&Pqja*S@H5*&n!e5DQ>+\9d94kD@5MBkbGV<^:<atj?Ba9^*/\FGS6b@HM*I
Qc?:$* <W<QAZwlP=i@P^u<l/5BC\9d4&Jk&j+**SCA:H>%R\C!@cE>!V<De9<TRj!LWPy@XM?@lJA#@Td5u+un
5A5!dQ D>C@6V6kb9kDNC9::>CMj+Jt@W$aN#QVH/Bb&Jq@k&d?H/GBj+AG59*G=wGb=W@R4L<^T&Bt@SM$<Hhw
\>DDuP 6n>B@<=mk9qQ8Md<P*5L=n@l&8>>GwB@RnbG=6<$GbD^n!4>N&RD@kub&BkajwNt@l?lkj<n>B?S:Zhh
DG@RkP FMn/Z*$EtNn?P^Pm@:Ap?L8QAP89^qAk&!>emNl@D6*@::al/4c!by!tDj&d#:+MY1TwEInAS$XYNJ^4
MwM#Ty +KXA\c4bYNS%IQ!h8TWFG#c^b=dHDm<F+?H6jwC5p%dBVLwL^#l:WAkF&d+wS!@h/uWdGq+@&ZR8FdJI
K=NXl# QYlPewe+%VWd*4R^E\i69kBB^mKI/kq6blS#++wByqYY9eBNl$!?WS1L+n+XA:@TcSFZlhH4WIC$8naY
9eSR$4 =YpGFS1pkdkyXnBIkmk&=Fc5QAWE#cI<TVChNl6mw^HDBw^kWKI+G96ZK&W$&P<u8q5mb%H!cAk:HaIL
e^BXP@ iRJn6nnN8j\c&CIBR\=EDhH/c:lNk5/8cLBSw:w:uDE%cA&$+8>&#$nqck#n8I:ELSMk9@c\ASk5NhM^
6K^Jn< Ka<n$eF+RR8RB!Dyu!kktH4Mi%lcBK!QF?HQnKK\R1KlS\/?#hJCCecA\V@^>T8Y4\/PTnp!bNcW>@B*
&dDy$> R^K%XYYEjE&Z^mbXEwcR:1=S%??YXjLG\J=LcKilG4cik&Zq!LZ&RA/^nW!CBRedp?MVDC4lB:Lph56#
8aZAjJ RdC1PFE8EjE9IRcn!D8mcb!iMJ9A^/lWeZ<EI\9B/kq!1WQtXCX%$BYJt*&ibI9NthGYXNA@eX/Nyw+$
=&%eW? H:a9HISFVQ1l+L/CYXtJwbHmC/intT6V:c&4>1TQLH^EIe@MDJVQSbcdP<\qttI$D9hjW!j:FkZSRB&M
Hqqyha IKK8XBlyuDJYeq!uhLPIFW4nZpLMaG&>A!+kdVqLyTwkcwVAF4Wn\:<w1<^myD$&K1DhkHECuP66wQ9p
/qK6yZ <t%!46jlyBj>yM#\9ww/tWPkC&NTB\YiyW=$8jPY@^VLJ4HQlp9L\jSCTQch:LpB=BblM:8!mkpTTWll
iY*bWb 95ZKnQH<<yWYS:uRm9Z4qtC$EHDTWh6iTeR/!Cy^$lGBamq6yChHJV9pHc@@APV$jAS\ndYFj*YD\\dG
IH*&*D tuu/DR6n?Zdee>:Bq5FEeD+*iZ$&GGZitGX!C\K*Q=yuDldVbpw@ENpVnh>p/+SI4Cmuwc6Ba%X9:B9J
:FuBJj e5MZW%C5BX>\nanGB>HPiM%Z6=pH4$T?SeV5$V:9V^Lw>ItQwetG^C^FAjjy*$jihK<**e>j4DL/9WA*
F/EWD/ </<qntl%K%q*uibBbp#>Kiiay&*L=TWlbah+pZtVIu4nnCJ5BDw+5pnEudTWYTTpc56bC!HkA@lhRlDC
IB#mB$ VRS&ljjSKF5l=aP%eNAEk+t/KaJLcnny5im/FTZ!=Y6qI91\>KG^ipbM!nAw?6GL#4jV6=ly!$myh<Tj
I@DKeS F1&qkMWWE<LmHa*djakRDI?$:L$TtALkKn1^$^TBkA6ew%E\l#weclL@=YNwaVJ?!XLF6l8MZGSH>\ky
a88LtP lEacM>k8+^$E\+tn9c<5$<6BH*MqVD9L?RD!h?<ZCiGwdcwpJ9u*<?Nd6ZPKiMmQSCAYS:@aKB=lRKJG
-Ania4 00034cf078400110333 Page 262 of binaries1.zip
:Di\kG $&Nyw8pM9=#n5Pe+=mXMK\!5K^J*n+PwuPa/T=Z^D:Tmk\YA+nGLY!BLd8caS<*KI>F$<Rw9JajE9M6M
em*qA$ k*P^G5FiH$yMJHX^qB+IemI5#:KtVyBc%<Rn$a&jyR4\Pip^w\&N!qXjhSdT>!j4^B:FS5C8!T*dc!C@
Q4ZBjy %4R/%HcTt=qD@pa=QbTV#mk*XYeMXi#b8Ddh1XXPGe6M*55$h>SlwpR5%^DKG\uG:yLVucjc!K1:ktNP
4pp6P8 1!GF@d%PJEp&%i1>n4Eq+YmEh%/bhWMbMne:9#K\bq/y^icp$ESXR4ihNFANNuleMyZB<qRT\AVSQaph
Bl6?6c qNn\Db&dknIc?TPwj+8SRBkqdEDJTXbCW$dM=TM+aL+=Y>BdhEKh44c+yQphYAM$VBwL9TwNLykX1in\
mVDJ\D $d=e@+jlSKaIlVtPP%kB9NSARKJt4/KX?^XYRGJ*PnVwwk=qRG^1/Rtd%pkLC=$=BGQyXh&yhb\V\phC
VB&L@i !tVmIXey+hjKak?b$mT/a4kHTXIS<!k\B56TiXk\SkkJVmAR&TVRZk+&AB&>G:1iX$w\pVc+JRF>t%5i
#$Tq1@ Zy<B<k!^R!>Jk!\k1E=km!!Swm!?!>Ja^1$waI&F=Skc4D#CIH=#weaq4%pla#mZMXB@e:tw&uT%!q?K
iR*#Nd GwG+9/=Buh$ckhwMCSV!LTnXCMwRMmpeey?m8+cKJw>F+qNtBZ^jnjR:DhRyW=yVA8n+P4w1p?>^#PdJ
MIu>@C E%ItL@FHXkDKJTcVtwTSSFF@6lDCH1#p>A*Y@Z1GPe#AS9n4nbIa+EHVIQAm^lJH\kMuyp$m=#$a%Xyc
h+jBl4 Ak:9*LIW*u\:nPbYCA*ieQ4u?kLFMaNRn9&t6pmE:SGYEmWBB6ZP:PKAEVX#n*kKhXl#SNRFiAYaXuMh
d>qdyM &9\m$%!*a\^eq9B4$wV<KyhE/FHINSnW&ILw/LI=99RIG@B6eMFbtT5TaIER19^^N%B1u&IkQS**$E5$
aPFM<V 4tcKYF#bBc>APDy&=aPI?a&5^aiX*5n\h+1G=L%XXPq#Iw4:QPY:qMm5L%AP4WiNwGh=1LwnL?/P=DwK
$598RC FNcJ>\Lbe@GayBLah%upN^VtlDMjG%TRQ><>=ITJS:D\!u\S#X4W>lDZkAicjK1hu/yGHGSSEJHJPc!d
&>L+bL !tb=w6%4>wn/a6+#kunN\yi=kALRXw%QR#TC:int^\RSSE&F9tI^k@!B6/%Ee?CjY&91$lKt%idn!B%w
?^ladj G$TF%hbK$48R\GPCc:/HkYLM?uW8lMaT@HQ@R:A9BEP9q:*G#Rt:LAB!iSLNLu^R6NHW4*VmK1*kA$TD
XI@L6E :1*i6^PeimnA1H4yP*d4%9L8j8p*%c?kM!!*Ab&Hn:wZ<!yCX+uECM4XtC&^uW4d!9$aQM9nVVM9Yl:W
lMMK>D IEX#MlLkh=<K\5SRQ+>9<P\!LlNuZn^11tdyq%Y#AH!^6ThCAb5NS!dWh4aZkm=I:?BjZV5$4:=TnnJw
du4P9p *SCRb8iJN8wYhK!cn?&k&%:i*qeWl1^kp<FdtnjBjDV/8N\qBMEeYhlE5hH=*HGWa\RHhnNWQj<yJ<i@
cKLMT@ bAm?i^RkW9Mwq=!Q6P>i1qq5Pk6Q9@*ML=<Cykw9N\EBbt$+M5$Fy<qq%CbNLKyM1A%y^e?h=%6HLWqD
1$IcCF mFdZa@\lE4ZiFw8$=:!B&LjBmyeSVy1mq:SST4*8SJhR!yC!F:B9qA\Pb>6M:hyeHk%P#M66FTbw4!?h
EqSRw6 =*yFuh4ck<yFZhW&YtaG/m!hJ\1=9cpeBAbqiKlCm9YDRqFq*>t<&NNG=HHeYQiKXBdT5pia^F9+\/\?
SJZ\ei \?F$4/yF#S%mkdI1pmSHnnuL=nW!qi6PRjL^=Iji/B1l/m%W=B>4@ikI^XnJnLRwS9\eF@4QH$t9GWth
eY5:bX laWuTNm>+DbyTdby?+/XGFYXcyIl+&Bqk6ZkLV:ICMHZRkcBl:<lpPCe?=j+lp=pRLu:HIZIm#^?EtLj
<8?>>i N<5SMiu&NPd&4F46aqRpHm*nuc^V!8QD=De@:pqWmi^SkS9/kiJ1Vl>THR/p&t8m@/kPe$#/@h9=*djb
@TTJ#X *PG?GIpSIM1?aJB\XQn<\:hF?hJpZbuq%>Pdb*JMk8PJ%cH$bDMR$NQAJcSWn:n%V#Xp:@5:LkiH&GLG
Xq&mWG R5pnCd?6=+8YDa+W:e8?\w6%MIeBQqQ6twElMk6n8P?yn$k<aSwjhp5Ah\T#a@#NkaARb=PCA$6*l+Ij
E:F#bu cYAS5JcC<QVmBaTcEDp?AJLEDJ4Z5tFlIWqiCHlBIepaCNRETqQ&i<Y/i^L&#A9BCVLQ!:y16CHS?%NR
j*%duY M&qA8F*+l#:@B96:en981D%QJ\lQ?$LaJb5w\@=HISq9K?n$TAla6wkCn1JFwiA1w+@@B*6@ASbZ5/$L
IQGb@$ w+&:8%9n*4m:8:6LeHeI:ldeIdm:E!C+8^MkBNhA<BD$=99Y6<=bi/?XjZL&Q99=#:**j?B=8tjQi16G
Pbj&&h #^w%=/m*15jL\R1D!^c*ku\%kn!w4dJHE/W$\F!5jRRn1S/@?LtK^TDP/+9Fn4jqK4!X<I54yHGSeLbN
1kFmwY A\6%9$YS+SVX+9a?9A#KD*bZ>X*w4uhNnNTqnE\#>M^5qN\aLFMu>i@Jc/EuQ4J?#cYWL*^V/m>!Rk=6
@:SiF> 8eRA/:Ci!K%qe$y/:jGiIRWGe9n>9LcG&jCdN#1<4F:R$PFY^R#?W9WXa9hR/H6mp?4J8<JKIhEL!nIk
^Y=^8j M<uH+tB61qNW/C5uKi^Bl1@?EkiBE4Z>amImaeXIdF@%yQdiHt<==H?tYqlV&4@\Q<T*P&lZPyw?Dn6^
YXC#BT K*Qd4Q$MpcDbWkWCp^B9/9i94iLuj:Q%wjkJ8lDEbLdajMHLF%!546#QkuyEh#GwuFAtceHTtFADFeMK
>aJWV\ 6imupBIIk^pKXI?TXLiZ9uBy\e^16VqlR6PqFl8S4K1TauGZTJDtZ#TSd1=p\i#Del65RhYSG@#AqNK4
DRWEV9 l6ppDZCXC#=ANAj@t$a>t?p$HEA+!9S9G9ZVDF6@yPPHDS^HZmV>h?u+%h^=%FwE%G=F%DqEAXk!/m*!
^W/<iq AMC4Pya!!1&PSw8BByakAM!jbD6A5<WP=%bHE$6A\@lX9eXim$NN!@&N=t&AXp8IYw8*%yK6Nycb6u8W
!\e+BV FqceJwiinpcBqpcmY8y:LRCa848T?1$+!c&Kq5cA>1&GLpij@yKW>qKR:yKGbw8eFpiQtu8dLyc9IRiQ
6llMSa *6KbEei6PwiBWe8#WXGhWn+tk\e$=a$G%MlHc8Wl!BR#YjW6G5mQa$=PbJl8nSj<hFIjc>YQ/Ce+%a1t
NQqcbE #Pdi!GAnTNA#T*mkK\SLRKda%cRSG?!ItJyG!V6yW*\FQ:eAqbln5&CDQ4T1K$R+KuqAR8%E!>&Cp^w:
JA9Ylj K:ik1AD4XN\JXG+yXN*yXY>BBH%WcK$%NueN6tC+?AX=iH*86uh>hy#>/CKB?GCNiCbyiGq#>ywL>l/#
!iXbL! /HeVh66yYLGctGuLcEGW>tqdiHjVPF9*GGDECH%PiCd+GQujHVX*<E!p$ZwZ+aPI$R45MA1puP/?PJPq
KRBYBq wIkIalyQ+&qS8HmmPcdNa8e@IAZJ+yt+aGkJ8LSP&aPqIJM&++tpwatpaKVV+Hq58*9Mw=JP&I5A5Q1W
K=tdEp EdanZNyE:Mpk$eHw$ME!<Ld#5I\d*DZ*<ILApenm$dbLeeB1eZw49LV!WE$aWIQm$R5EMWZRehJ#:W%I
<w%!am MbaZ<dB5eFjRQLE@9d*::NEZ=BnW/h>&=9@>HE5ppMkpHk<5McD6NYAXLBA5qkn48%wcBQ\!:C@+aZd8
9T9<%\ @/Q<MBeyP<5@WeZ1wD>IT=:@DBuM@t?aw4<qE9^b*h@b%n@N?ae5nH><!9b9!FcP9\qZ19=q8?njtFWY
4GACql WpcPQ<^na@$j*$4B^M*F?5>#VC!kQ=pYqu><?&e^c^hZN#E4E^hT%y>H<mb@Hj#SwITDtcP=6ePdQ>4:
tM=LF+ P?j^^<p@L8mjS9\>HjPjCSD@+LB@69/*@*@Q6HC\@ChbbT/Yj&cXPZu?>*L5euL?8^!:j=E&@&Vp9!DS
QqGyZY @tLkj+M6=kD>B91ZVDWH&&?k@$mT?c@S:L?Bbtj=qiWe9+Ft+@=F5qMP#6>B@!yXKkjZ:/DbjuZX8H<H
Bjq$^a @T9!pIQuN>Ak#q>eNW/Y*$G#ej+C@V8?>t8&tQN*uI&h>SibhVub@p6w>9<Tt8P@lPd<q>q6@<MKjm?:
YFRVb9 LS5QF!uuV%>t@*t9@&NX=ni!&@+:hjD@ceh@TB@@QjQ5u@R^D<8@wI@@Wi@:h>QR59&QNLVe@#MNLamD
\il\\q =V?ZlldE!5HC<@>wG6wH5Lj@@=KGN9&L6qZ4\pdcjA&i^Hl@$Y^<V=id!KNA#Ld:SlbS%aap8=+t=&Vq
ZTIIX5 6LGEW1!p:WTI&!*Z8tP^1S^VptnDuD&+4J#+tW&X89ccDp+e*F/Jq>?M9A1B%EQZh?cmV%B^=IuY<KyJ
QwEnC& dFKhpH\cQJ49#iMc5L6tW@epb&6?pLyk#I1?An4n>5pChbH%BjFb/@RdQQPh+1Zt91cc:$Cb^cLQ$A6*
KmVEB/ RbBjGey%jCi\EQE8pK@uPyKV8C*Ydw8CQy@L*^&DIShRm9RwGPmb+?X/%9*/C6kVD%nkP5wqiKu^CLkm
P5t9^B F#4P9qGMi\Xwhk4>RCP=tZ1kqu\FXBt<j+y<>&D=nFEW5FR:<!I8>e#tH#ZZe:L!=lXAV9GT&TN?>PZY
p>VKK/ 68pXpIn&CyD@W8nt?ND!/SW\G9pKKHZ<j/Rlwhjb#Q@LVj#jd\n$ClC*KnF/H94$Nd+*p8KpW69nd4k&
6=e?jm 6RkL<6nDuVVk\<@YA@+V:R*LFB/hC^L^#1Gap5c@9<RIe#q/<F11RdY?8?Z<Lq=ZSII8u4awbJt6@k4R
8Ktc*4 j=$:Yu/RZt+SpMX&F:EF!jLpJ:mcD8ua!tK^uwZV:@PwN#H8BB<tJ/Jm5TPwZV4YR:B=K&4q?\:bwQdZ
i?6u94 l+n!p4SpiC61ME^+=ZhWwcFY5JewDY&^ecYWtJdWacd\J&REFSVw9w8^n<J:M=:MWtSIT+CQG/F5I&SL
JK4=8F &%XGH<@5XR&GCBbK6Hmqh6iJy8>=4^u\\=:pm9:FaiwF/@&Lu6SV>C5k8!pk:GhQyM*>:I&ik/>j6uXi
c#MGwA Aj9NAcN%Q#1=@1<G#L#Pu\4>j+&%9\c$ZHZ%6*SBklwVn^e5wRK!9?D#X*ADEPbc9*\PtQwW<L>due5Q
Ih8WR< R&GcFiH*JI49L%9Syw4jZ^4p9191YV^jj$>!*:4wXl9\8uA11QeKmJ@8jPpT88aCj9wZ9*$M?MZQbeWQ
NkJ%BN ZkEy=#M9^k+@^<n6#:1Yj1i8=h?4c?X*/y4>9d4tj1i8?h?4/:@%iqqa:K64yy+8MQ?EmAh%5BQ#iDhb
9ucy?Y iJac&6X??4B@<Me9H@@H%c9N@HpKHXDBDqHBE@+a&@XZT%FV4\Dc#??jin?@A5bP>j@yM6c@X&%i4D*L
HT=wMC @:D\nbmk*Jy8pIam1ik4>>4HyTjBYdl>i&I?>w+qiT*N:^<Tc=c/q\cd/JwqEuCZNS*w9qn=Ky61*9qd
>#L5VI h#YG$%i<XAA>VnFnWiCISe*i<BiqdcGen%?jZtKM&K<VS^*APZkbG6K&l5e=5ul+m<eR?kqmK*MteFHX
^6aN*c cN8*MiD=tqZyj?cP>#dip+ui+aGNR8$:9tD%mhHERL@h<mkdbI&RYqd/%GN%Tllh6JV/DPy*ELJ>HQiJ
*Y^1:W 88VeDj@5WlR^!bt+:8Pit4IJy=G>Atcic:lbc4%q8a6dSyj<w9lIm=%ht/q#$LMFbaBGN#E/jw=/6XEi
6RR#1D h$<WbwXTn+IeXlMyc&DE<HW@DP?R6VAltmCp$/j+$qVnI/yi4@FEHJ8KAw>h6WPt=h++p^\4QWuy=cCi
NMdieP 5?y:JP9q%CGGt&hS?6K5</*J&mqTeBqlSZq>$abFC41X5>#nF61k#SH%LBpa&5VRS4+tjbAEk<Z/4QR#
-A8\Rm 000fb2bc65f00110333 Page 263 of binaries1.zip
mWIabY %b6*\cAp$S4b&c5cWaV<W%GylJPAn%dQbG+<+YCG*qlbVQwEn?j5RycyiK=HD+<T=P6jIu>e5A=iKi/A
>E<8kC TuZj1aPp?=QwQV+L<=q?5E!6EjF4+%1bA5ycEL<4u!^BGD6GB1LESKq1=%aM=%:\/&yqYLa6dP:eFuY$
Y^thdI AR!G#cu\!5uJK%Q*cK14+VacPEkSiSeamljPQqbi?+^GjJiZ\KWFJFm*4i<Le+KH6CL>+*CmkF:R*TaX
VJ%$n\ d+h5#t9nm#e5aKMZu:*Mqc$eGc?cFm!C%Na>GZ8L5QG\GW&KPEQnL9TllNCutu/tQnd9yiA+CCYhw+PB
DqZitl 1mqd$^NWQNjl<t%tKYbi$?#CCj+&?ij>1W4ZMXlQcntTPC@jnJ^YR!bJB=#6+RpK>=*c8!1T\T<+jh?C
m&<Wb> #Pj=b!l<yu\\t\9YeA?!#htmB*F^X\KnT:8<6S^T?qC6<a</w*ZeaY=MM4nKVqk%*+X!RDwa8d9jS::a
ll=n+R Q=mh8>p4inPJGVV%<cZh+G%I1tX^qV&NnatIDjhM$m=AnPTj66+q4w8X$&1nwhPMbcIhE:I&h5RNqG6G
=+wKcS =Z1%KNESQ?XC^^%ATS5c!Gh8JZw!p<ta^85RjI?GBa#l^SI*F&^5=:$#C#An4Hn45YL*Fd/#\c!?\L=*
cKkj@> l?AH>MTP$<!jA*$$=<6X:5<aalLy!%Ni!<\@*Z#15%WmhH#%dPQw>ml/IXy/APIVI?ctI:h1B!^e1ZdA
aTtYj& PAh*c\jtV:jRWF@4>k=I4YLIdwI$!QRcTp>H:DRQmJ\l*&8p=k/N=d5WEMN^GWLTa&+d\6V&h5QqD/K9
bNbyT+ V^W6cucE:T9ubbPE5!uLPXCaTmh%S@RCVwbC+mK!ItC*F<uWa%E&S^HnD^PAnbG#VAQ=kwJ<VGq44+Cq
MPEY*A Y1nF!9MWZ+8&>JlShbc6<+9AuI<ph^wdEMK/:M@?=?:h<R++NIY5:NGM/*E+T\Aj%VSXujd4==4?iCHW
jptdZc Iw8Dk^Tb&*X#LWJDwdlk?QT>mPAXn^KW4?WdTa1IH^SMJNL#4c4BDWeIw9C<k4h*pnRWNW#/P5B$X&!M
X#pm?b FZkHJyXq1V5/k8/46CLh&bKQIY<HcHh//j&Ep%1IlE86+q55*EHnd#=WZ<b+FDdd\=EbTC6#J:#HwXCK
QdA!I5 L@wcN!n%ync6I?wd#u\ThV^6#?jEMWXYYb^A#Z6l!\ITNIjF*4TLH@Hi?NaHZkXBjZ1PIhqJ?JKGI5Lt
Wp!RNu l4c+>&G!cVYCGLX94kpVQl!j#M$AWinitk4KF1><%\?SiB!mK9jB?lVIq$b*itFW8VHt#JlFV/KKG9bP
%/QNSG KMwkQZ+jDl:n&bLQGbjTpcM+HFu#cwIX\YW<8yI:dbi^$=YPDm6G/qLLtPCy/PuQ*%:@>ZClkLy6IA!D
wGCPbb t5lV>hq8L$Gy@yliKMyDj*^Xl?y4HMh@<kw\DHQR*b%ZJ%!VEK=FNJC6uj9=IB?*yP=#w4A&hE^Z!q4d
HI>C^! XR+1TcRTHS9#hw$JjbMaF?&eXG&F9K+G&jI8C\DN%^/EJk8\lmPe1V5Pjw5TudNhbZ?uPN!PLYjE$?q#
N:<W!J 5MP8S9MKpI1Z4SjnN8Tj=BiN@MmpL?h4HMuI9*VdHy98@FaZL/K!V6YRCVZ=PFXn9+jnQ9CLu@9!?#y>
%PRetS kWq:b+^%?ePF5Hj>ykeSISkIq=R<#AFybMTbB?$%FK*^X&BHliRc1%jFVqZRJ9CyP<hppP:://Y<CM^e
%>IaI+ V8E!hSTkIjIwCkb\BZ\=cmy?E\e1/YjBZK=9+V+CH^5eCc81>TYe>wPmClE=T&@*wPl<peL@TtcCpj&m
n9B+q@ >nQRD8y<BTR9h@#V$:e?Y>uilq:PNyi^!FEePt8%kEy>h$=/A?&5b?b4\1bG@JXF^>LlEqPh<WidQt6*
I/m!j= RyqdM#!4#&4#+8ZqJd=BB1j/tkeKHtT$ke&%VLIZNAX9eVdbMKCiE:#c/Pa?Wq^<XbH^?@R+:V\<V!yc
@45SW? Dq=bd/#>JPWk<lEe:JG<Y=4H*L9DT\JB@CYD8Qn/wnm$HykjE+eh$k:n8tI=NQ5n1KbY5Eq:L#+PRiTa
R9=:84 dW!+N@?k6p1ZHtQ\q6VE/lYA@qt^#cp4l4\<XtywJ:!aN1ZbE+FEpH<>SpXB>K5WPiV:T?<WcWnbiP+H
\RFjXW D6F!G/N5Dkk%j@LWGq=\G?nQeqZDDN&aD8mB/ba^\ER51B@^bBwh#n5?:yBi^kw<@PNJWR/SmSy/T<mL
<a9C&T 6?@P&=%Wtu%h9$T9*KX@6K4nmJG4KP1<QWiy\^i8knL%!kk%Jeb>kRbeW//@?*wHbMd@EbS*kJ$1dJX4
W*$h6j uFPyakES/\AF5@byjC=Ml4B%N<mp@b1!L!HX1&dZVXM\1@mGi5tjZIKtn+I8FeJnZ*GR6c+qNi5a4hbe
VG:5p6 puS6+6aqPDB+49K6VuV!aB$6eRy@A?dHc#CM/6J>@Y=n6?DAWB<RPaHY:mk6YLGQepnIT$jFSp<BlBKm
&&N#Eb AuXlt?Tu%JH?bIdabEpAmR$u9>hmMC<LhC5P5#5MD*pTnmS4+*mJDQ&ncIENTmStu<+jw?89eI9<WG&q
<W%bS5 YE9NETlKqck4ZbnR/Z<Q>JX^ECdPXVDVEa#j8juS%j9hceB>eA%*<J8VGe%B%ek5/YYS/@*H$Z5@bHA4
ucjIy< 9$Pt>?#MRF8ua^APFFyI5*yp9^pJLQy!Th9&m!ce!WECYPVmk?wq?kQF#9M4wP\pBYd*=jC4u=D6P9ma
qWC9+w WA=S6$baaXRJCe\=RtTYM\+!tQq>Q:Hjn<9hd@ywEN+X6V9w!uwnLDw&DeF#KYFSq6@8*n@&4Q<eIChC
P\Vie* 4LLjYcFNHCpTeTMLS<tSW&?KCc&GiT<QqYIGHTMq<^!C=:pn$hqyk5dHTKywYj6S<Km$qChIW^4eN>AW
IjiYEy Zmd!BS*N\*XEaiIq=CIDQLDFbe^%mNp/CHjX/ZZh?SDb=5L4KhJ9?6Tw!Z44WHu>>EZ>l@^utGNGEK@@
8qPEc1 bd!+>M>Q1+=qSpd:Y4en$!#eRC=YLkwK1SFHyVn8>^mZj9ZMci8cZjHj%NI%>hdqBq=&h&^N$N4MGiL4
Kb&@wh lq=+YRw&\%Nl@Ca*4c\^=t#YC%IytSK41!9+E<MX%a%WC8EuNPCM:InKJ14=&>:4T>#5:4Rc^%NtpDKj
MDtXJ$ wKKeEWXH8@i/pLB%NZTJtAHZw+4w8kDwC1jK/jd6#l9EBy^ELAKDija5#e1BRG&^<c?XM5t:B+t+L@n&
iPLLb% F>@Ge&\ZE!bwu$ce?c@K&&>+/MB+kc1l+wT!\PnEBt8hDu!W\ABY=TL=9Dh!ciTWcX<YdiCHCTI#aZjd
&B:#V? :?ZBA88GJ4?%5LA1<VBkZFk>i>^Mtn>aRGCC6b@VjC!S$&4:%JeaEFteleFd:A\5Y>1bGC9cQa=YLc1/
!VCZbX @9LD@>uyw#G/@N%kGmk5V1up&MjEap6aCQ84&c%6N@%AK$!DEtmhIk1%t\IMZRddb8\^:+!<BeFuMGph
dQ$MHC 9Qq+BMmcmYlqwh!ImqCbJ+8jHTmNlZW*e9CQQ+@??jCA$i@S*uNW=T1TB6LmQE/4YpT#y?hW>8Cn&\!/
kASWNF >iH:X\W+9$X1upLVXDdZmF9PH=4JEY<\:i1^VtA&qnPY@HBh@eF9@I=X#G&MSa&Aqt+#%bV%KqGp86NQ
Yy%RSb *Q+nuG$QB\&WZiI4\J*itR\#udmuFPZdWWu:RP98Dq?$5R/HI!j&4bwmtq/tKLJXTV@:D61F#?:PnueA
=T\5AK I%e6dQA4aA4haAlDS?LYLWQK:ZbuQI#MZ>nX&H@>dbIu=wmB$kG%d\d&J*GGjYML+$depH!tEp5^R/nI
/\<?e+ DehIKjiD?^wKMXNkGqCEw8NhhnIl^?:nk:1$BbLc1t1*ZH:Q6X$Wa1P&JQlw\$a@AFHDIyE!mj\c1b&<
/k1F>p ecYPkY&8hNp!Z1%/9cR4KKKa\4k*&uE&L?IZj9%9=$EwhSbbBJbJu:%H+RP:=P!$ISwVjAnnV\^NF8*P
P$!p?d hq!MY:^#=/ucw<a:$KwK+iYIiNnRJq8klWSYHL=^ABee1F8!$5K>5biynGTYhmYW6Fa!CXXtQk&>/d^t
\a%Bk$ WL!\9t6hiFADCjZQ%WER16clt=>1PS6ti@S=cH%w@lC^XG85$c1NLbWhJHY45/ieI!ADIFRtcZ=:HFVu
\?8Z*u &DYmbW5kQc<8E/\*LqcFilG=$hmIwjHtWaD9dum5*D5VZ4#XKZQQE=NP6JL&Zy5q=d1<^Ha+:/aZY*et
ljj=&= p+pc4bKlqCb>PXK<ewIC?&ABk6EjT&ZIG5>$E#Dd9@M#GL$e:WjA#GKmn6yB/<CFwCYhqlD\1WL=yLK+
qcW#HT *L:Thc%W^#bpGW!B^#JCZ6e9*llYBX#cM$NdXQ5+$149?hHcT%*PPI4*kbE&6q!VFJlM=?K=P4iLhT+%
VR=ceM A&W\XT9l#LXWyEP8@t/iPMMC?PHlubEPRXIB8?HNcYA%W>eeAhVHwB^uKlqC<jFml1pLYQkt^?Q+QP/*
MIAWHS %k#Zi5ZyLM?GqmTE@CGZZ*=E6N=@@QeVi+y4Y>:wMuw9dM%MT%?9JcJMTA\k$mT>^k?juI?w6N?mhW<?
%*h>M? hKWQI?RKFIY5*HSLcJKb:VLnHB1>T^VjkGitI=ST8IbecdNFcCalnEF4pZ$a^j@p$G*JQ#M\%9+ehD&G
:KY:D& @R@V<*?K&w<j>A\aZ\Eb?KPc#yR>aQX%R=TihM<>a>^W%:4LN>&Ct#y&k>>h$M%FyTHLqVcGXeAP>4Mn
S!yQE= B6aL?qwjcy:Q$\W&PJqN?Audl:\J@GSnJ4a%cIc:?W\%X#bNp!/1q^5wp*ql><W6@aFb+hDmbRNmE@pZ
pqiL/4 %HcGE!yLyZPtm>TNt6$J>Nuc1=XlN5V/&aqCeQ8!Ym*$kYGHtaW$CZ%ER>$Y6%V8b1R1#8RX<ERm8#ka
Su8KA# A&ei9R@lXZZ#E1\%LeY8RBiDTm:Tn?>=<NIZ:&uY*>dhcV@VK%>ny5FQwia?<?AB/iDHTGNB=I$VF&XC
Kj&TEh EatME!NRR?W@R5edJ54mpWmJ/\t%FykCihSw/d^ekI+K*ShAuBju?PYX*BTZWdKAcl^DEH8Wk++X6tyk
H\p=c! =qF+nTkZJlFm>iE!5DP*4P*tdJP*H#ecS5wGtcQ<q5L6Y^Q6PpT8&GS$jiMul6S*KbWaRj8ZX^4:4GZw
ne\VqQ 1QDQ6Sy4Gh&6BhYhW1jHN<nd<C6S/9tMnDcuLj=nyP?LpF*@%npNTcNp$VK!VdBLGbZI<qd$EpVVIp<N
h&jVEV l/jQnpc<nC<ynJDLb=/&DK1b$lLd#V*k#@qd+RS8SKj9j<de>$bXM<:&hpu4VeFA\tYcb!tLIk&6dYM+
Yk8Q$c >kL!*Nacy!\F5$qclGbP\\a8YnSLKVZeN<4Cee4yll#*HjC?h*/<ydY6GIb!tHWW/@L&8#jc1Xp+F8?T
DB6%Y> JPpj?<kjXb#uV*VLP*K%ySMqiGtp6^kt\&w^kqp%ThCqCBd9=\5L\*$WQn@QhV?V&VH1IwRk$5Ab#$Z8
Q1d=AS P6l<4Slqa*PAcXN&1y#SYCa+kSTnZM&l:XbDDS$<\CM1ku4t!Heu<6ja5MTQ4+ap$d&%V#5R>\b1i&ep
Y*h^lE DLFaXR#%Q8@S&ASp+:9dG&W!NR:*5+MGGTjWWt\Gl<=^5=41ESbmCFGyXp4dt9LYG6Hd\JW%%LHS!$MY
w$+w1$ $S<WS1L#JGAimp4JHj!YCC?qkLJ>EbXQcN#qJV*5qwiQqAeIk!:5lp8W9u\%d*i+eFT\uli4w/N#9CGw
iD8AZ@ ATh/m$nC8XC5#NZiLeXBaeYYQKdX#apcbmpSBFjESVV*TFIah/%HLFeVy/Kj$K@miDYISaSJw8kw<^@=
:%HNJd i@hHY1!D&j:K$$jN>XVtEZAN+jpKwK=^jX$+j6BQb#Z/EZTGp>M9=$<9c18bkH?yKcTADN>=VZTiY4c?
?!5IP$ admc!RT5ppF9pIYENcBkiE?a/6wu4d#IF$6pi\D4!Q:DHddtVcRE?dByl=JCqGqlj9DY8^mM^yXcbmdG
-A:QLh 000a0d48c1c00110333 Page 264 of binaries1.zip
BKRBX8 kteTwA\*+b:L8Ny*Y6b:R++c9HGml%nXd\ceX$=!6MX\4pShycFaWwjnV6FE$ekESFXldZtYm^1t<RRR
8WK<d? Dya5EP#Xm&L5@qZR^Hpd9JwSQSMpbh+^!ttLHFQyFd#XJW5CEySFeWA$/9PQZQjqCyn&MTMHQLuLXA6:
WWNp#: !FPDYAinWwJkT<>pF*tF#Y6=*Nkp:Dct<&5/#XHA^B*Q*CItt4u%l<NRi^\&4ijQ6E%i*>pcq=ke/pwm
pu6R<? %#?5y#BD^ybwjZhy64>EFh!\J+!p*ak?C%LKPE@nL4duGE&mwIeE5iw!^C8nmK9ZqYJ%IRDwk^q99?p5
:w<iim /W+d%%EZq+k\1m1N>AWVk%uJaJ&\HQ/hiRVy1MIYb+tJ^?q5BMwWS8iG@+C<K58?tbKcbLPP!pemQ#ml
#4#XVl cw@iF:ewp>kbXDwtV:Zl<GRRiND/GXn@HEKdE!b&!aPZ?diAlNE+T6XacRqN&hb%^^+SNbHRii>p6Zme
lTLNaB XEb$G@%m1QRM8KpqL%B=Rlwk>++ppDuC1Q5lhPY/EH>hkjJD=bNkVYinTu9VK<B:mqbTAJqZ\ijT+W%5
qNiJyR ltp$*D\uEpFZDq+6SmT+SFX>GNDwT5>+JE:?J95^i>iH1YcwW$<jF+%Plw+mZqG<5W:%5HV^54>KmPYL
A=EeQC \m&<BNH*=j:M=Xpwqma^aCuX4TZ>KCcS6q<Vp5eQeSJ6L:8ZNuKYyH%dRyXtNR$WQI^hhJGuL!%j<Q&G
h*9Htj jCiDG<VF4d=lFP^%FYu6Q=<$aDt8cRn#n5IPDShXV!Gqj1+E>p6$wFhdn*P/y&KDcTSe:BX<JJ$5&uCM
MbY$u$ I6KdXJuBXQ$$nQBP9ZJ+PE4Pbh^w1VDq%9!?+6LymD=G=?hn/bIkJ5a6DqJ%6LKlCb4GjFhHRJd=p%F+
jX+$9D /lj$6%KVnStm1+WT@Q\b\>1nTcldWIpj+eHLdRcK*Fc*#=L%Y^4jPw68MK11et4T!X+dZiutlMQ?+nG%
\R?y^l hQ^kMNnc6ttel*X\T6tNHdleR*w?KumHC>1h*JqRCn=@tj1$\X/H:kVNHp8Y?JGcVke^Jh@?Rq:RdIED
B+jqd& mit6:K#AIC1*DFymWI%Y+TZ@^!YQY6JNT*Iy:DY*BjDJ1pGR>Dt?hF4=WVH<eEHWI*?/Yb\n&:lqC+^5
9NRlu^ >u^mTqi<Q:jGS4=HLD*Zh\96^IX$@K$ai$PC#:^ZenER^:1n>S!F:=RV#KIXGiLL<?81lpapC4=A9AIm
eu?y%W p#:nI#AKyZkeBtuHWikPW!tZwNcNGNI1^NluPdL4F:6$/WwMNPJL%w4:=*N\1Iy5XMkmF:j\Gj6?+>Ij
AHDtwV uBPBmyLMDilPcWhLGA*LjT9WMHajwy5<T/kui+%$P^DJ6CZypbywKZ1Tk@ZMWiVEu*6pwBq#+chS8n>&
RDmTy# WAGQ@bbZ?Rtm5I+KWh/qB*W#a+QjF8@C<8=#$iTHWC8i+#m&b=N<$%lqKJSBLl#bNISLLK^%u\XwuXM8
:>%w\Y uQTERn%i9RpCa5X1kNMZtEHlS>t/BwNIa8:aF:M<ZE$V+@upp=hnwyl*TlG>WmZQl<N!#MdXN6d!tpI5
VS#8Rc ShiPqSN>SM4PMNqy*kqPW4B/&=EC&KX^b^Hij+%NmuC8LM%hRl8D%S9+\8I>nHFDm/8Tu/EHXiNC5#j:
iGK#4b ^I<CS5l4!bmV@nCbPP+t*BHJ:j4%pV>YA8+lND/?Fj^M4ab4cC\>u$TVw=PbK9qXCu@Yw&+CHtiK+R%1
<jS+CT lqcmJ:?I/&M^DYGcBmpIb5>&JZ>n6@Cc+d%ci*hHHIX+Y=c$il=beY6mpV8DnTCV!tXbN@&:=EqRVFVS
^beWDn N1K#GKmwK>+de6?XkQnuQYH>K9<=&ZDXyMVtjjFL=&NEG&e/>Gy^mjiTYd!w6KR^X:L>h+L9@i5BwA=P
mE+9tt E8$wA<hWaE%>pl18X*F&CDp>1$&J+C5Aei=H<I+ciGk$XYimQLTDLDbX>J9:K4GJ*E=+i>ua8p9&YG@I
LAC#uJ KI^wX?RbhY5KHc%CVXF98+cR%4%aqba+?bE*#pl6qa$%w&ueIhIIR*SA5S!Sjl^DI:5=*=9BupHi\mqM
j1<@X> %iMT^JDFZSp=H*P>JL*9jqwS6Z$^?H:R&duyVT9MDlS5E=at5SLAKw&E<C*#AuVILVyW8=GQ1!Guc<%^
Y&Y\T8 <FTyVqHPKB^JHMk1M+I$Z$YEdYI?uq//=>eTj=LnZ^=hWZuRA1<ASaehlFcB6F^mJhV9nYN@c>WF&b&H
>AHTud Md@%aYkTjN9E?KTLJ&GkmKaI@=&JQuCyc*d=D9\KRTKNYXR9E*&4PRBSAd+eLLumN1mkaH$E??yLltRL
V+l>6T \&Y^M=%pDJtZ*C9Ac+bePl+aL:Bay1L5yQenYVcinDaDHT@JK1WmmhyR9!kXRpP*WnN*i5CFL8L?9cIm
+>NJAF WIRtdT5aFVdIp9pIYiHE8Z^Ly51815hPqyu>W<qpBV5XL4Fwk#+!SZcac6>mR8<*&Wjm@k:qH<QD%5Z9
%GqRbe =lLIGd&lw!IhI%Ie15mK\HhNhB%%qZhPD=Dw:6^dyZY*iwCItwL<$kiiupTmIa4hhG^I49L%nNbR^aqT
RHp\/G BJeIpM/ZHB8NRQ8^mMHRPX5yNXuNcJ$jcj%*I9DAPht?htAqSnI6SVC^95+::BIWP>$B9hai5CRiE/uE
<+kJ5# k1l>YAl8\tN^V*1N?\lT#kH?9/:!K9HhCREBje^/%kQ&HQ?C5k5@li1b!BiVBGcKp$*Dut85Qi\HlnZL
S%S$:$ /4V>Hi>>/\:h1tIL6YTY/FlqVIQ88=tje+4:bZFuKiZ?@Nuwe!SJ46uAinN$F$S>a9KCh=w@>mPLNGDL
Qh%Nhu C+SJcRD\^IYb5c#w&wXJ$1dTYA\>=p@D9IH1<a<=qDFG5&t\%K%8=Aj^FVmqBn4J1WRc4Vbcq*?+u<bM
9K5akW EX^LpqTPT#C&h8YE8QGTNZh$qNRc/R:eRS!9*CC/ZpCSkikBRlc6J%yq$@DeT6=6Q8dGVc%X%&+y<:Kw
5tb%qd <Ku%G*!&MR#SLS#G^5lma<q^88J##^IYH?@kah6Ei$SHl9hE&n+twqK$RX?TQ\S*ydj8ia\LtnVI4M&K
d1ieme 5NLVlD14$*uLMDB58hbliYt#quLPVPHd:>qhF5>hS88F!TlV5D6XP?mw6*lmMLIayNWkjh%MGtDRn?&u
:&e:yW Vw:AE/!nLmI#SB=WmZ\WNku@9VXW=F9c5=419c\#MhHPikh&+5NMlDd>?BQQQQ&P?1D#/5&DL*Nyp6yE
DkaX*B cNmpJt?5cjtqNVKGJR>ln6TP4#:LM6a+&B>!Z9VRX:\%XGcVPZ=+5=IZmLy8H<V5?FS@lZeLt^PFb^HL
#^<TJl ?md8B#L=qllB9T:XW/=G^RIJhabjB*5T*6ta!dD1qZnLt@mNnc<!Fid968?wM5#i8yhyS<Rb!#CbSGTJ
%6EJm\ XklVeMCZBChEV>Z*6@QQ=VjVYdS6<+G^mTbG\XRID<REatZd^*Q8G5&bllQ+<nFZ!*u!cJ>q$FZJ$R$=
T#/mut >a9KkSpb?J\byV4:GwG$N*ZbX%4#MudyFh<nB1FVltYMGjK>*MKk\6YPFBRiG5:NT%tV5Y=k/GkpCmk/
=Ndphj ?=^iayty>tn/+D@X%\w+Vy\m+8e5J@hQ?#jRDW@PAaM=P9hJhTD6t%NXya\kIydZFuG$9qtk4$T#$WN$
$KeiY! *B#aiuMiN?k?X!c8R@Sp5h>9/?#J1LKl6VPI?4E?PQK!1d\C:CqMljCNR%icD^IVPttpd4JEm@MDDQYW
d!/iG* 1!iWY=K\Ce+Y@mI@SK><jY*=a4L:wbyb?bQV5Im#K6/Wj:8IDjitN:#KK/w!$n%/eF9#L#c:#jqMe<kA
MX:J?T Q>+T%!%nFV$ymFSltQp@%mwT=jauYBF*8J=ZST#uH=I\CP#C9!^b*uP8M4jA!KNbi?>@qn*Pd+9Hi&Pp
>9=MX* k86n+<GAtH111IB:8lm4PcE/*\IVd$Y?69X!5L&#A:R\%NiI4CP6?nIA@jG>GbAK88*hQN*aIA&tFmRL
S\k::Y wdX58AC@<!6Aw:W!Gb$aTkhMYVT%Bn=?WQ%tBNjEFEG!PGRWQZ<8CMk%Zd!LQ:%W=BXLk/+w$16Mj\I9
^\hBA1 yHSA=M^uD=1iqp!DJF968M@haC:jLM:B?lV5an?Dd@!4SjGFE%&PSW*h>A\t!#X&L^:<IGH=+PIGbbnJ
nA9%t6 :h!D#5Je+JjQG%JaXhGDX?$cynlbCZNyq$RkC1GMM\+Wb9*VbW$tJ4jIJF>e>MPhVIhMhSeLSM!G?BRP
Hc9#CC $yD%cm:Fy<Xq?>y#=l4?869M</Kwpy#Nl/BhI&XJ#WT\S\dPpdbD/I1!NPb>:wY6Y&+bu<uKMK1E!Lub
EBe=WB Ttbe+Cew#4J\?qJ@N\MdV@mc@Sk4:MMa8PIebKtMcE:?ZXYyCpai*!#%5=mA<i%41NXw!T5*q@DaL9pX
\T@qFk \w<\/nZ$cI?m!pLII=mNV^5j&/QdBHXck>ip5I<EG\lep^VcXba=C9a@%$N>P*kinF%&?YE/Nc<5?tHV
=my5HD ^/I\C1>dRnBJCBDWh1!aVck/eY&4*NwiQ8m68kt6I@1RbPl1:w*I!6dWdLhWMttehdPiQ@EKTB&wqHJw
9T/Tu% p>puMJIpd=A<hp5^C6$k%bYwL@adtV8L!:/8QIhnJCQYdD9p:anThi4T!^aDlS!4*ZGSuniQ>Q*+XPWn
GmQLkn ^>mYild4T+j:DV8FcdcGq8RVR!#MBLnen$N98:!mH:IdRPEp#T$8MG=EtX&Wj8Ai@a+VZeC$1I<F9lD>
^FW%NX ipH5M1ly6tKH+6+c?R5A+Ywh?^XRpND=C1n\EZ1RhZ\w!Z+JF@*&WuL$Cnmt:VqJe*#AR?l=TC>/BSTZ
HNE$WW 9kI1hZ1P#JqiATiG:%/T5q<1LF+B5/MG4+DFdyJuT1=u%jE@K99\Q!6Lj\YIpdt@AqS9At=T96#K+XE@
t?dt^H :cq@S?98!6PLFp@B*YS#GYR^Gc\kn4<hPk6k*dt/Vb*JbH^1^Z+8\W+9>P$@n%=M+yBMcEy%KI%chFCk
^Z/NSC j@?/YQh9:hEtZ*q^\XD855btb8+XAII/jKeywlNR%tL<&^pD?J/GKPmG>nYT!5$b$mXTlVX>?GDLT/M>
uJFDRW 8D<FCLSE=8G?T#i&b1JEqa#^Wl45\+N#qI5nYF#*H\G>?NyTwVq6GkSS5GbY48RV$^@u=iZc!mR5>G:=
aPda#? >9\abhRhHGVt4/>uH#5bd6S9dFBWILI!Kd>Q&GF:ehLZHbLy14Ju%:W#@h#ZleEk!mWhZM@KNan:LtAE
cc@&yH &&lcL6ICk#uX#nSSw>dR#KXe?S1X>R*L8>mHpIKnL@^Ibn@cQM51M@!/$Wi5llMt!wQ4MedS>>l>6ZaI
??H8JS :9n5uQy/BFyc&N=hLE4ah:Q^^a^ZXw?d^<Z+1BiBjb>%=?+?QHVwNCE<<>\9n6d#b\SK:y*H/6CXLY!E
MN1bJn T=cZ>twSC@G/@/DT48u1lH#1yS9#+W$peBL1@BSS&i*$+j4FBWG>*m*?eCKSZ4ypQ6&m5mCL>+tXbE$5
JJNH=H /N>&6?Z@wu9yj@4P/j@$HjmFkEM!yq5p!jtBG$Vub^894X9B^1tSSciemtQ+?a:Qj/+/8RcMi:==BdB\
KHJiXj BX#=4Am>Ly*km/%Lqb>?<=IPqZHRn6iAdqS?I4n6Y@ERNF!1#keyHc?N!1P%XR\5/RR9+$>$\wHZeH@d
$b!!5l emL/pukn^<^p\<5bnmPJ5+>*@pK4a//qGm5@LXNAkK#?lch:bm>YiVVTd/%X*TKKLByF*6Y$88n=1MKT
uKtRNF *>4I$e:tSTc:XuQ5<E*&59deD1^iXwy*wY1Q>waV\<Tb96NVuC>&PPX%<9ywLQyueZ$mZVHqlupu4W\m
BQDEJ: GH$JIcyCeBt#/\XAebTBbky=I:HWKetqI@Ph^4e+wdTJE9$H?$M<B?=LGaL=@iQLPmm%&?c$jQX=84Pa
wNcQTT u4$S&nC@4&Pp/eGFR\P^#Vj6qhY:WSBd/@6SCn@EY*e&bA+:SKX*=^\al&VJN/yYVkteCZFJ*P?GKJ+!
-AYQ!a 0003fc8927100110333 Page 265 of binaries1.zip
ItJa&q Bb8peQLMd*hh^:CWYL/?@Vp6JCGTTa=apJeRw6lN\tW&t41TlECSKA/QVR4\qBDTFpK>1Yk+?kmBE*Nq
I\tKY4 $HEbMRPCRb/RWEZl6JA<hq:51pVy?D/CMt4NAc8VQnZnmqtm5!w&!dQDuTda5T>SR4?A<dQZHa$iMyTi
KcAFXn !X<BK%?@*DCi9kLW+H/PRKPH=?!Z5P/AE^Plt=lZkFFV\G^d*dM<>W6m\Pth+\Q&:W>ZCZ$F#DM@?@><
nA/WFw lwl894>qij<k<R1w?>S#yLj\W91#b8ti&$i8b\TjkMZ?kGPeq^+#1qhAnpj\Gl/V=VX%GTchibKa4ZBq
YZ:9Ip TDK4aJ5^T/jTW@6C%&YAK/T@a>dPA^aK?aa&dy=$TylPBC%P\wcDQ#Q^y>hqw*<$1ZHlCq<AZ@6eKeQt
9GwBTJ 9J<:alF^=Q**pPnmYB684j&G6TJMpySnQC/I1dqBCnZL@iwWcJD@%!\b=mFDI!9:?\PqeSGB\ajkH@tc
BGq/ch cFl:hbSlGt>SNIGtVdK/FWNXByhFX?G+ijTPq*SnDDAue$Fq:HFV/bEW5ZGG6NcDmY*>a9=Ld8<VJmw9
Fuk<+8 %A/ClBa^hVZ5NT6^99jlX1<uWD+&TAjR?nij&*ZN&^e9\kGHLIBI4AE*IiTbXJDlcJyXF#5BX^Yt#p+L
!j@y<% Q=JQdb%yw<Z6BYZpp*mquGRnLR:dA>ED^4m9j/nk5q=hm++iDi%pu!D*bkd+t$YqGSIZRbh9Q+/:4aM4
%=>:A= @iB#$H6S%R#ui*Flp#Ih^VuyPbwGXui6QN+hGG$$DP+>9Y@=+I:?a>p/A#6Pdq%&Eb$P?n/&p:=/qH/8
tej#qC A:qqcQ5y%#1T^Z669%%<+wRB@XJ:8ZJ5butu=@N#%q%9Y$A!y^aWSjJWuh5akR!ppSbDkTC%A\4DDkhp
^XQ^DF qd6J8!AMV69Qj9S5?^DMq<E@4E84#58%SN6\CY$V1@Y#h+V?$YHK@5Fld9/u\@V^Bn#6#1<c4Z%B<86w
XZjKPC !iLyj/8d$<&JI95\uF41<jR9!J!XE%=SQeGm8yI6Kk#KHqIi>V^Xb^Lwb!j:\@Td6:4nNPStTI*lwVR%
Vi!5hJ <LIaTYDMa8KGk5T+%\ZHH\#nZC%8&+I*LSFZMMaWEYW4L<6K5c5Bc?Ej:&i19J&Zci61C@QE4Wy9hdj:
Q9\u#l M$q*KJJDbQ84^n\=cyj/5Niwaww&EP/Q+cVV&L*NVVZINi8?WbwPPyYI5BiG4IN@Z9*l5mN>cD5ay:qq
*!!l1G kKYZXDq@YeeeLpH/e1uu/EkIh8#Ni/:#%jS=jcQ/eEWuln=hXwci8uIJVLYkYJHQ#p><15ndb<ia$XEX
@LDFuD M$QeEQdkW!y5NBPakY<ikI9!K?Ae!J#/Wq@9e#\6hDMI9Z&QLHXKtj+>^<w4C5@H#T!TmG8e*5wm>8Gm
FS*y9m 6$cNcLG^edk<Rc/uYneGk<cJV>t^FTFh@twSJ</XX4w&N&6:hjyI8!wKL<Mu8ECZ%A?KXd4k/tFh#N/S
mGRk\? *S1T?WTaQDe>J1HmA5SN@4G>9QdyFVA?ElDSdC$:&TBka&DIe&DWQEc%ATTAnyKND<+&4qLkuB/ZVN5E
XX\1Jj %a+t1mhbE=yFp\hdkd>DKaQ?c#$CajT56Lp>@Ic&JaqLL9Ak=4k^+Tq?phBun&<5<RjXY>&Z^+u9b\EX
W!J>e? qV=1iBHR<il>pXECNGIWwBy6/LPQj!^6*WNw/9E\y6G9%%XKWaSyIWj1qE64kCA?LtF81BcXa4ZG:Q@a
#6/XZ1 Vtlb+ani^y&pFDb%PyZtweGEK1j^=QM5%ij%n:\D/c=@+Twm/84ZC:W/Q6L9AKF9CAnY%/@/CeZ#/mtk
9PD%p> Wih\ql&N5S<S5#IIX?iW=b41%yH1FCiPuMHdTdBMKDa$%uNFtX6S=p!^C\hVJBdFPkHiJk:TK>?j6WBn
AJ6XuH /XyuRe$&GhWlmi5/^!<bdJ8IaEbZTCh/?&Hbj:@*>++4nRD9A@JGNYE:%E8Sh\qnw+&Q9@<aq>4n/jR5
%a!F^l FDS8L!RT>%t!:Qm>nFbEFbIGPA&tyimGn4By!+/64tpjj#ily8c%EtH=lNCT=S6%KTMXAi%VqDI<1A#\
X&:W!I qII!^jaBtFSkHmmhBWdaPB/aK<^RCABV@wItuKlMe1Ypc>4c8tpaLXT%4n?5W=kww^Mtm@/$WbpHGh$#
CMS1LG NGJ@?e=/Q*JTdlnQ5m$?WdRSYRKVLeB#VH$ltVl*tqCZ\DKI54pk&Ga!6y6kmW4$!>eaLb^jLj8h+K6#
NMG=S5 Lu#=EW\@4B=W*Ic5>+/+WbqEGi6L/V*h>@EH@\wV1N!cZnp4H9ILhTe\YHwTbDKkeEmI@@Rn@qdG$+h/
K#CWB* c=jn1uL>1Yt4R=*#QSA98&ITFBJJab@M8!cId:EB>NwGda\!eW5cIYSMWH4#lEHi\PSmk>ZdAaJ819:u
?6Q8uL #HPK\*GeqkRZhm6#KF%Pp1<j9ZV>mw4a5FJ=ilFA\nJke5W1/l#idnGZk#NydlPG191VAXIDlAZGyq6$
NN<I=9 RwPuF#*ERmj=n6keHPlbHqHqZC##@PPwiT/VTjFM^F^$Z&6ScP:aN?Dhlmm8N8QRwMn6$^e&hbDWJa$B
EeD/5h T>>*ImI9B5?iP9i9MTLJWBC\bVAYZZKT^Jt+5ZeNubkb&$4l&^5YTqIpiAJW6eWl<aDElVR?$Q#qZ:5!
l5jXZ6 :8Qdp:^>bcJNRBSSEDB%NYTEjZEhYA#1Yj&lm\:Cjc$iH555D>kVR*BMNnKW&S=tSu?JLqlPBdpDt=IX
4BED*@ 8>/yGKeyRXb=jQW1n!^AS@<ekj<6+R9F<a6c8u4QenPn>AqZFG=#klQ1A$5uDNc:WQN$1+>L*Fq?yI=@
T4a/$* 48@B1IhS6<J?J%@b%bZ*?n1!VTmuG1h=L!%k9cmPH5ZjWtJR^JA85pp:WB%#uCcCln#H^YVcmT#q<EY8
+Q1^SD =1bG$BcP5icY&Hl>MuqDjL^*^Gu9muI!G+IAVFXydeP5bKG/IM@#GbnAN9*iK6@N$9y\C!@:nbuV$N6A
GqT%*n TJd>$SG=?VQ&uq4Kku5tJ1TBpa5=9KI+dtSTi*Ga6>@:J^VIl+>$ZBa%D&<<eWp=c$*=XcujlVT4yl%K
ATPwYJ XlRR<dyQ&nHayeGh*hLpe!w&yHiR#ddHG=KhA5%:!q^ZWu$5iSYKRi\IQ&<j4A#S<RPLeT4ak8+HZSV5
8+AM6Q Xbkcnqi>/>l/CukFVY$jPtS$Jh:Qiu$8nFhQE\iX>i=^Y=ynYkIj5*LM4B:k5yk\K1GIk$Yd56kVaVX5
698&Vn iJ+WeN5W*wZVY=hce<=qc#MB$1TLEdHXLttb^<XIREkI8R>cA&l9WTbat5HFNdM&tSXy=nI/+5SaNcJB
#A>9ZK PtqJdj$\a65StqF&CdVNyH%pwAK%McX!?hCKL/c/lSpjj:qX@9lBu$Zj/Phk!u!Lt!Zu4#VK!JWWZDbT
bFT<G5 C6h>6Yb+jHjua*<5dW!yMbDeP+hF1St:pmMmTDSm&E:4J4e$Z>#R$jXMVcGEiHydMMR>^PCT<i=:ch^A
SF8X=j 6<@NIEwKI%YC9lJ:lXDy=V\$dHphe&*qi!Vl8PC\P!Ppi98<IEe#M%eVS&jit5q\#jV**#AVm4b6*P/=
dWm!!L Hy!k9mZdjh6L&bDhVLtEQXDZWFN8pPVtR8>%jqhAqd4?EdLucntKa$CK1RC$pc!$!YGG#uM4TAiqdLDS
ZwIpK& Sm!<iKbRd@A8bb+CtI=eQkPcJk<#6jyB%/mS$l>6P=uAdiid>*Q8GF=htMeSj&XX\uBN@p/&b8l54\IJ
&895I& 4\+umM+uK&8HeY?KuICH#N9mwb&Y@t&<5NlJ+kh1m8cynwwnFw6*/hXd&QND:k#HKCNwDGF+84luacI$
/^kel9 t5RyJqKVPY+j>bw!J=4n/Zp/QyuXpW@8aY?Qu1?n&<DIT/LRm$H/wX?=mMItmS%HCGQn@mAVq?WmMMj/
=JNj/X ed>>\k!qWiFAutw@X8ac@=jwtIDt@Q!n\wjtn<byneQ>%uAIjeJ%9G*>*QPhb:8J:!m6Z9Vc8ldhDZDW
iu5\h* a6R/*5i!5VQppEqRywJLK9AR:*%V1Hn@^=wklHa4nki/H98^ZbQ@YWtm6:KAc5^q&iBG^eyS@/mdctmG
J>VFn: +#aqFiXaVCJ5jqZ@q?/!V/:nSd$LhkNKiy$<^lF1$XK&M9aHtSlJQt\<cFp?^jM5<XXcAqjFC^VBB>dy
4^Q6@8 c8F\?G+$BnDeu:J&@LFA:?I?Nq1*jXwNWR9Z%e#Ii4PmRY&h64M%DbE$tS4Qj9MyM/PF&<=Q<E4L8plK
XwF*q^ cBHqYD#n8M>a5yp+$#llnASH5Qw>#wlSn@$%EmeBGiT5VeLRLR?YlY@aZl^y6AXln!<S:wkV*^*8RtG^
<jWKu6 9DF?D9&SbDLREbeSy\^@/FS6CiFS!K/PpkAc6*&liTS<i9QkXqhKL=E\EdWKyETHq>cIF/jhGB&^@*E%
ZZRFBk <iwqkTy&\INCYaBEGwS?Je/+JIdS$*e4DpT/8%nHcb4:cp@PtYm+LEPiuKSB5^EdPDY+>EKmHJiXEjMn
IXpLX^ RCK$u@nA$Fu5PMM5IbtPtbMnVp^/ZZH#<cu?cy#i!#:SZm?%W%P/ZMTRTT+\bV&!d8D5X!91T!i<AyYd
*y4hhw J+LGdS:tmBecCdNj#juRSFp$C@cn*nT$NVS$ituCl%q/IybGNp^Yq!X/Bj6^<K*W\phI>d!VV^9@y5\d
X\I&X/ ?w=P8k=$1Xw?iwBh+Dy$u&1#a4dRT4Yy*by%Ru@u/8mKL^qh4:ckRnm*Ecc<>eRS!c!aT@9J8SCuwdEy
duS1^% :WDp%6dbuu^aP8+X+EHBQPIa1X18JLaPMdE9^@Pt6iNYq:bGNDILM=+Dm9J&yLi1Q%WRX<6?d<F$8jb/
KTIh!m pL#XlG<nAVJ!&&ydnw#j&$GRw!^w5=Sp&%=\b+$>jn@YFnMS&ABdKS=y8n@KhNa#?KZbb@eX$J<&=a/%
#V:J+m %\aca%j%CY\epZ&aelP?=*#idh*%5a>c<^ahu?%e?!\j4C!#yi+u!YP5yXqAGyb^I?DpQYiQ5pT8\>Yk
FNj66W T=+R/<YFGu1qJ1tC18HjZA6tSKNH:tQ6CTyRWykVN=HibhhDJ6BkIt:?>qH/?8?!jRJ1TnEcC:X8^%Hc
&<wT%Q =&bYu!J5Hn%@iI=?T@HL6h%@ZD@VJYn8<L%w1P#N!/FJdMIHP=Eb1@SJd99!@w<XP\TN^4iT\*4eu$%B
>ewwhQ \ZEW#L#$+DWn:kWF@c6QQe=\%b=wGCjZqD8Mn+Z\:Pc8BZ9X6kaj<P*n*/L9!Mp\jt\N6ta5dWu5BptX
<ByewG $j6@&::q<V@#l1L5QPCFQHZtGPTm1d/KMnXDa*lQNFknNkt?%EFS\l&N>lF^94qu:4$?eih$t^d$6u^J
qFMDY= =m#8d1!p\cea6aZX?:h:pIL/PWV<W>=>#djTe#WLC$\XtAqQ?t5KL:#QL##PS^n4LW&/u!pEt8mqKYQ4
Z*Ze>q QdRQ*!W:8^hl=d\h\PX9e<1uM=BWbRqHXq+5K4dF+ZZbWSywatEwMwtJk%/V6n<:L^X56uYCnR=bqNuV
@hMARk !mw$$tld^ad89K5F?yYbN^aN$A>HSqiu1Bwp/FY!eiHQ9qYBK/HjXYnRE&IciPM\P<J*=dWu>WpYP$B6
iScEaW 6$B%J/>mqbN<W&8BVLw$/<A4CdcdX1ttu$6yM<B*\9Z=&pHB<>Vk+u^=nX=cHHXSHAHVeB\9^5pITuhP
cLDb@Z !1TX<c?II=Gub=?9/SYRRhD#R<D&@i9K<aNBqiHQYP?#$aJq$pbEQu8S>Gham4b\8K==nqZ&S%<F159R
SdAmH* l8S^a\*eMZH69cR1TbYltGlH\\keZ!PRaB\:X:IW++<514kcBMt*qEtemh/8dS9qD4Ej5RbJ=>#QXjRF
/Y%\jH m$n9C\?6ki<p+l!TLLG$AtLtXV8d*HhpCBKZNjEujcVDje>=R!JnJyTWccX*+?dim4+C:A1A>\*eTG+C
Q<QTwy N1L#uGYMHX!CqaPNM1R*T+e:adpj5BI=j+d1ReBb@kGPL6GDt%H:LC4PW+bRSZEYl6VEHJJ9FC:hTDIe
-ApZDB 00057ea397900110333 Page 266 of binaries1.zip
dGdJhd YLY\<<%Imy8pl99=i%eh5b%NT@iRulcbHa&R?amVuT84DP\KXnRTT>yp1nXGGlpa6&GXuZIGwTeT9wZQ
%#JXDd 5AHlHBKN$jNEyqcIE8%hC1Sk<5/FhSlp1?#t<@uIit1Ib&/hw*YcX\jjq5tAp4G$Kw>nYY?#E&&a?\M^
&VbJWe FCt?kM5WuNTBT^BZAF*wyMPXF>B%$1NHShJTc&?PlC\#8uRh/8MNYpmmennHl#REbC#M+TlaPG=F6Y#w
Bh@HLm *1WS@X%A<E$G?<m!t&<NK=A%P\^iRZbJnJ:hIlAIA^G%ZnD/Cpn\i??=L%JBEKXm%y*EGV/P@TciYb/F
8dt!K^ iT^XpH1QZtV%#S<VLKP1V%QihqGR#tMMLuBwqpBKaSNNR<bS^+XnTH\V>m#5>6pQan/pnC=J9FXb$pFL
n:lTh6 u#:h8&4h?=K<d$\+?6CM:>ekiaqReXdYqlR@Z1p#Ic\TnC:ATuH*Lb$yy4^q<nwSeTtZKtLJk&LdNtS5
*\B1?Y IckPM=PmLQm4BDViMcju58Z*$^Y1w!pum:cEYbcalVk5HR$XETkW^Y:jYT!hu=WLKdN&cX18$u#at1LJ
L9D+Te HASJ#nhi^qj4SBl65jtHLKL1SYEVDCI*GR#Sy?wA6W6DY+>8Q^Y69kKa&I?!/pBVS?M::C4$M1RkXR=J
dNKZ\y ta@wp%*lE/NpJ:$=1P^\Ft%NMqTwCk=6CBLQ?=D#DDtFFnhinW/E@9nMe=H9GR!Aq?^c^aZIDnPVHTpI
$cpBR: Vn1C9M#q^1buQi8P/M/?A9Duc?V#?qHW4LKyVpPyPcP>\K=YyXn:pXdKF+JP4iD6Y^&5wyn=*Pk1Nw^J
5n=%W? HHS<J^68EqmIdaN!&wk$#eLyV+\cE%JatuT*&mhiqJ=%WIYL9%+au#9?aKjkHHAAT=EmRVHtIIcNIM5i
E=akqu Pq?=?\$G$qDmkEBAeQPL:AebJ5^paQHkSk+p*ApeqqVyIK5@kE8YpLWlYch>+jChi64c&t$W>6Xc$nmW
R#ZZHp ILcFm\?Z#VqLLW*ZuN8\>Vj!qnSy<*\p/S&ZS5qwC5*p6CjCyC<MuCIXI&c&cB>CN!kCTpANFjHFaZH:
^TJL=l /A=RaE^qcc<A<*Q+1jSM!K>XFjtcdF&8/Z9pmGVc1WW:pKGymS?kDI%RlFt\lmI!\d^KPl:/ewalE=V/
hlAQHM 8a6W^TVFT#L99mS:@pmMINFetkF*LIJWPPFBd+F*KT>MZa@&I:TXjJV!k&PM!KTKJu*IwRZ1LXGcnHXn
H%WW1k ^mRKbl\h#ek/n8hYBY88GBmI!p!ZaPn!B%bVj6eiHKM6/=NNRTLmR#:Enq>Zq5M65F*h*Lhk=188\ZX*
D^KRki eB#E=%Fp&5u&E^Ht\+j$4/5DHpl@&@KcnB*tTk!V1mIMCXBw9^I**?HEK1>FYjnaDdj>%yN\461=*Cdi
+I\qel u4\e?SETVAc4aP@6w@E4RJjp?<:#LqeN!8Pq@&Z&e5V#ja@Z%Kua!=NSq?X6\T9Au*tV#Yj&FhCD<\&9
R5!a*A &!4kT<#*&M%twY>Dn<PPj+Mm?QW=eyaWjhbi@a#kjcBeKPGQNAlKF>+y<e/uN%\c@db@HqVl:TIk\aER
mWAeP: #?tJV1G>&q!wlpJ5YLTI4ZKm:picq<j#e\4u@:e1eW/D4*dq<\Twn5R<%B@MRSWepM/Iji&=y$bLK*CW
juh\l4 4hhw><d6Y<Ptt%ZV8mut\EDKMtlDajDTmD5J&=kS?<w?E:J+M<1>8/V?M&A?4#SlBu^dBdPT^m9A/waI
#^lMEM 6Bim#5W&dy+pkXHWZ?X?QN#LMcLeTA6LpeSl<nTRnq$&?KaEaSVycLE&hQ<eRa@Hw1#wiLkT9N^RCNY?
qp5H$P !<?yel4J\4@kiH4=kLV\@9QWdTJFyLtt8$bPH9@wi6K*d5=^:A<ywmk/i?%cmXVh&C9kiHmDc1KLb8\B
+A\k9R KN<qe^+>^%q5?Yh+DFaqA^9%XakVK?6jj9k#cc!Ta/\5ayW!5c>*dDWqdPI!pi1FYmbyk5Da!$<&mqI:
lYu#IH uNCmKhmRB@QcE?hd%QQI5+1pA*&T?BSIu:i\6\PX%PIIl/kGXd#Q#q6!$$w\Je/ba=6\m?H^*$Ab^IaJ
b9a1w% \:>pQ5yhE6$>J9EKqqGIZy%CBWa56Mi6k6lR6#4ijeW81t9SdQ/Cayh1d=@$?S#!a/wGah6RL$a9K:WL
IAyMyY htDije>@*l@?e1XEue!AEW=:qbEVL6<X^&>@:QSMQeXPuQG8pY%6$DikFK\:Ii@aq+GFTG4#w$<Z!>4S
^>GL%+ KGqyZJhPTiIMb1jb1\iC+w*khnRnjN#:QH^ANRN9Hba@=eNmAeIbX@Fh/\AmD46Q9c?APX/6y@4%X<Bw
N\S9wH <T5k!>W@c4=uQ@#Lm\V%$$L&nYL1K+CB<^X\ST6$pQPq$K*8l$udK!BS=lZAj9CMWSI\khV#FK*$w+#4
NJpt6H KJj?Sh9?=&SXNYCKy$j<&Pl1\QEXRJ:<an*%RC*:CpknCQmB?j=c$jH@q6cC:G?t&Ja?:q6ARGb/9bNB
a!c/N: kmuC!!h$kq#VYI\cSmBRV*#H<yatlZ\WCT%Gm6RMn\RLWL9ai*Z5?WZV&1!=DS$NNW/mm$NXA@JnaWaW
Ra+K>P Z=IWejbV$?8maQ&e&mu/nL8JZeQwFZPlYY^C=el<5wq5/8w:iPKY+hbe1\@1#EkyFyQj/TaVmqALV:dk
MdL!<l Z$:MFAI@we^!\iaTH?>T<jp/Vj&<T*pBNBGL</DwS<8a%*ba%qcpG:A9Ec4wLZNwd4ZFmBDW@GPmZ@:^
:udBbR 8+Tuq@1umn?pEC1p:NWXy=Vu#WI5dG#LHu6m4I5#%8^kPEt&Y=?Sm>aNZppQTPFTyNJ=4lj$mWtpL=4i
jcp@NG LS?AZkH\^e4k&Nq?Ctn*jl::V/KeMj+j1*itQ=X1F&qET8GAH\ZqFSSl:R&%y%K$iB^>PQ18*+Ekb\t8
VR%tVD i&qXwMET<Rn#Zd>d%9PS@j8A*F9!Z4%BJ48cLKhwTlNEN&cq!HilupMB@?j>aW6BVY+BR:HD9DFIY%Lc
a$ab+B BB%eCJGAKdEEnnn6b*t4X<CH=JFujej@uJ<+!>VW9AJphNb>bI:<a#8J*/H%=*ZZdqnL9!:quHneXZl:
daJkcZ inI$mq^!XbE4MTBItCu/b^iiGh/VuM!q/KD:q5c6bQF?*pk%?h19D%b8\/8bi9!T$NpbKl5&F#e%y/d$
y\%=ES cR>a^t^u/M*I?BY/CLn!MRl&<YF1%wp\DE5!lYS6\:&Z%Tb6+dP&CM\KMeEQ1nAt\Y+!DT5Kc&%R!RCH
&?Idkt Q:=!>Fdun+JGm$mB9cV&!ue%G&Epy%#q$w@^#PaJSuwT4wR4Nw$nJ<=euqnR?XlC*Th\9W&j%!kmGTp:
ER:P*6 8>wbMIiR>q+B5HYDp%M5!nCuD<=4LWP6ma/*tRehXw65*A<*w^8wLl+T*lFM>B$R&K%^^c$QR*PhLi8b
Mc?t8* p6&=pdycP@TMLB?I#JVcP:X4Dn8VFyQCL\\MujdwaKG:4Mhn:n=5%SkijJF5$i9a/@V!Dp8I?dSa#pEb
kdN8?Z \SNB$V4\pht!aSQ/@l8=Y+4wbjjuEW41PLlhYwL\<wLnwBc?hRX/:?u<I@DtyBFZH9EDcWY:/^wib@cS
jc15!P 6W*46m!@4NV8#\6><A$yCJ*B+!4inT\a:1Xw^@:P<^\G\5h#WyXDLNt#%T9wqT5:>^EEcbV?^QtiiQRQ
ENLk*H TRE>=#*HVIe9qRj@t?>*JZQBt*kuZQCPy<KYi1tCk<8Y9lDhAq<BAb<D=k%tunYt@9Fk=uW=//&M$Jj9
VuEGYb Snjy41<ADiiKMnH<!*m>FN&$\5@/aJ1WGYjM1k1KjCe!L#?h<lXR*Qu?wT4:Q#mK+*YnHC#XT!aQ49\b
&BF!?p X:V9aWW!kN*/wBj&MHk8Jn?@A6^@i1cu$K$Y%@>FS@kQd8lFW5A&yun+Sw/qQpnm@BCt*@@G@>FS$AHT
%QIRH@ k?+$m11lpG1uwu@SR<=dQe&Z:?tCH*?<44\@WaE4!@ZGIne>/i<E>bA6dJm+=!Zdt$:QNtpK><aFL:$n
?1KR/K F!$5Q@%8/lMjWtc#td/!XIJGRW=1Ca<A::4D8S?m8pub11hbuXkb?4#NNAkt&<T=>:mFRITP^H5uq/&n
HT>N++ LWcHi9iXB>ph$?u\da4#h<!KXbQ$Ml#!4%EW/qlM^cup:<&n$c/G%@8RKu&e!6Z9Z%By/L/h5PbnE1!a
h:u?d# SJZpc:X=?kiwS?Y**w8t^4X@HSLiF\=E&jEe@Nc<!n\9jeASd/GiCa8Iy>JSP\u:1d6l>9l8>qN*hB4L
yF!+e6 KJ+&Snil<u\k%AM$Pd89t8?DyCc#m#ajB*n\iAEaP?EH5Ej69JcCkb4B?mt&+WA5+=aC!Aw?hjkukd+?
DtNtB< Za>5m^Ll6GY$B?Y1KP/q4GK5<!WB:I#tBIc\DBpG^SP$QD^kbAIe9bF<nbXMmSPD44:#1yK^ycjMWpLc
GSBLAD q$B#NBX/ZRCW9^i&AJm/>il*l4un&Dla&E1>aN\IVmIQd6i&H!8eZ\:%%\N!Zi%j*Kj?:iHM/&#i&V>>
Wkp1<m ?u@mpDu:le<n+B48D&KP$jX%L55:9JcyKJIlKY4^RX=hR*^<EwXe!LJhh5+tCbq#j5RYT\=YLp!bP*>d
k6&kYR P/Q?@8TS^G\FJet1u<bdJRN5LAm<4KQEKZl6YmQ4SEIEeww>XNcTXAa6ed^<b&dAkh4mVC#ELd\uVtkn
YRS*1< b*^pQn:$R@KJT$K*<H1B!AyJ^TDVyB^J<ib:Yl+iXVlhXed9aDN1Y!#pjXXNuVW*#lVSyKb!puT\m9D!
MCENli 9tyu:y8=LQNVijV8<ijdXBtcniBRNnceV!!6J&9ihR/WWd8^YY<N@iX$R#YM>+lFFLieN+miRGGq?R*T
wpHY!P E>+whcV1:5nnJbyl&l?9eMA4^n8n9W#G=jAL1!c4i\GV58i?8iW5RhXq6qYb>4L4$95>Z9N?IBSq44Y+
Zd%//! H=ScQ>RDWtV/DNP1Vh^=R?qyXCte=#JZw6=A&9iiN\9^w=Wl6NM^P=ktikEKDLJnaBJ8p+1jGA1L:+bQ
amLiA8 =wa<MYXERQVJ=QR$D9#+PW45Rw=^XkN&CFC%SblPp5^t8/m!ZILWFnH9keIcXWN*NVB$h?N!nKI<c!4?
5@%a/5 5dwe\thp/?@KQZXX\w\/%yH5%8hd+@tmW9hXL4pEDS=edDAW5:@6lup84:AyPDN&BBtWlQa=DeqHX^%j
Q%QkXl YeDa\BQFp>9h9mHVQYe>h9dKpF&E4D:/R8DmRj1Bc/nlWRAp>tjejE@&6#D/R8#Q$DlkK@#QTQpX$Ij+
aQEw%4 Py@:6%n/Bjc9+QwJhiy@Bjw#*H+FBQ<6@H+FRLL>Q%5HL4m%&VPH=edK8!YHIS6cI>WXwhiF?B@nt>Pu
=Jallm %?R9jDMKbk115#^Jki^KDuZpQSTmRm/a91%TB\6QQWl*LYdqp*u=:Y*a!eP!WLI>!@AZ<Sb4XS1q>%VD
W&lyn5 TyRDnF$aRC=5yF6%:*&hwubNLcwVKat+P^?*\<bEaRWu<qhAmN5#8cH$!pNKHX/eIBX1BVKqwy?JXtYR
\=9alM bQ:PTJF1i<q$=#/#:N*!nEIH>9jLB:6GJ*Bw#T#6\!AK++?F!jD16<I:QWRm$N*PJRcdDFtMXi8/qe:d
Bh68#V =IH:Hb*kG#wyCYGcldqeYBYWju1>#=@c&+Ktl4yRQtjHiJF$etFjCHp+MG:=j>*+/>^np:Mn^HjLuW&a
51RPq% <:<ZI@\*=@+h:uX^P?e@PQ$Vi9CQhj*HVj/4e<%H8mkJ=<&=^FhZ*^Tn6*THdmh$1B1Njn/P$DLpBbTZ
PE^5^W Lm\GpdQ*%uw45EJeyAZb*!8mlik1uQ4MS>u8mq#%Qqmt:$i=$XQH8aZ+ul4WHC+j6p4hlE$YCwLLKF@j
nWdBIA *D?+*<Pi64A$&myR*IVq%nC?A5SiAbFM/Yen6+=Te!&9AA?Zt@8Fd89*4$8uLt>dZ\HiQ8@d:n/<4QVE
X?l%^4 5:$pZL$CnqG+u5u&A?cJHS@EJu+?MQu4H5TtZkHT*kE*Ecq@9Qaew#C@JF#@LKH%5?A4+M@Zk#>K>9^X
-AWmD5 00073c6725800110333 Page 267 of binaries1.zip
mRH4mX $8ktI98988l@qu^hQmY=mWn@F&h?%tH$d^9:<t<c8i4=t#X@NjLu/<?T+*?XDF5IGQEbih=>BZl>E>w:
<l#CcK K\*+lWA=J<?@WL>m+RL>X>Y9Su9%8RqlwWQRM6whCRkq#h=RMJBP\bJlpaFj5W^Dp>LJ>ap=P?&bp?I1
/XZ^Gm R&KM*WT?\TYaGRGy>Qd:1*Q&$*C\R8KnM4=DlIdI:I59b1yBwwd=R<hKA#NGppJEbFKXE^QQuwJ5NH@j
B+T!ZX ?pM/6FcuW:PFHT4cGRXB^jKlP*5t!*iCnFFVXp#ET&@!a?XWYQLJIGYbdt$5uFSa/AF9?YAJaLLp9585
CnmpGd ?6E8dBC?PJ4XwK$+N::WHwmHIWiaecpjjkjC*b>LDRe^9F/dt!=:dD*YuS!5jCGBQYGCena+hwCD9Xc+
BcHpac nCWc?FK^u/lb^Hbb9?QFV4lcTYmD/b5/YdZ5jL9&dMNJ^^CwPpqXc^9a*^^8F:nMZpMj?BtTCaIjH^MT
Qw=^=+ qX5QMk#XN^CVXjuDXqT>ZiAqJAkCh\+YCkKSA*aI%b\LK\\%SRAi#k=@1$Q$c?BXG/m/HVML81J#iKdw
PJe%:p FL$<qk8YaAhHwAdXJyd&JBK#pwdl14GtJ%C%9l+clAlw:I@JY1YDIw5$^^R@XV$BlaKHRGJHkAuue<R&
#PSapn dFDD^$ME4tKGd+94+<+WEa/*IqIWV*DQZB>>ES6k\D@qS+ck/i?55dYn\ya91P:9WR/TI=IVM\F@cBe@
=:>VdE DeNBm4>EIpCb+>AjIK/W^dmAa8%#5mKAhkE=pR5XlP#X!d45:kP1?%pY<HlE^JARc99pq=5ZSCCAeXBk
&w&:cc N9P6$CIKJ4RjK/8!N5ILM8^&X^#Hi*GF:5Adi/yhAj1wl6kLDJtSM@BP8a!!FGu9/<bptRk?c8\H%$<\
H/unJ1 L\!bRwF#EApyP<hnD/nJtB=cLT#PY9bALct9>W%ii=unVc5^VHQ5&Mb/wCJjQ=LBLMl4eKnXB$tw&a?m
SmWCP! a%$WR+N>5I<F&mlMMAyy&WGP%4DF5*FV>\qHlMYFKEC&1IqyC*i5LHw6IDFjqCC&kND+!Al%&X^lElS>
L4XSCN Ae4<i%W8Mk1uFQa=\%DN!@Y6P6+AaXdhT<Wa!>wQA9RX/\+Jh9kS/Mk5bhAbCA@4<GtR4YY$>?Jn:XMa
&DbR=l VMIhTl>!iSLC!RJX8B4BR!htINH1iIiXP5XIYltDlXkq#>:/jFQ1QVW?lqb6NplGpy@N4?9?ntB<K:M\
nLID^i GaIq:B+p9C&w$*!@!ijF5neliQ8wV5MV>?k86HK6P%MEe&bYbntK>ML@MMD$\X>EVIhhn=VHZV+C#H5>
6AF$i8 Sm&yZ&+X++bkk6>jeDaG^MSWF>kKddq=HlQwkqSP?AE<auWA@anGW:G*q+wGYJdkmw<e=>YKA>!BJYYN
epXBlk XKNedaMk*!LCRk>t6qlD\S*eBRMV\#M:/Z+RikP>4ZAQawB/HtJlMbdY6#p\kQ#E*M#tMmeDwQHe4%AF
?tWkbK V&ZH$^$wS1HL9T:RwNujBpeMwj\^I%HCeIWlDZL6T^tm8V4ZVidqB1G!#yC6W8Bpt4L/Xq1LTeLtDCCw
p1Rq$& P654Ykn%*=@n9Zh=G*6?&<a^jI8d:&!6%PBDS:QEZp4\TKt5WCPRD68%<FqQFY+atV1DSVu!</tiK!kc
Dl&#8c wT9!pG#ZLkeK:FMmX:/8HpX5l8%Y5Kw$46Y:HI^Ry^HyEan$1=$9^\>CZ<q1KwwXd+t@%u8HncG^jIwP
498Ahy k\mt!:SP\/$D?mu4</^Gwl\#Ca$G#!IA&LPubd4/S9ZDmDC1YBS>*H1w=Xj/bJ*hbZJ/?%hNEMSTEJq1
GAuDRY N>HC:+%l!jXnRl&SqHCW>!/*:p&R:SI*?>Z:G@ZE4aI9Mm%+Pb5J%4LG<5a4:mm<h\!CIK<LLjw5K4Vi
<#mXp4 CJAF\/mJ6GIZ/MIZtZQAmmc$myb/*^InXQwGM$@db9@\i5H:<WB:CtmC^6&+#GteWwRcS5<EHA^4duCt
aT+/Qc K^<R6YeFy?QIm#I:AVAlNPPqCT<pElZ:dn8yw/?M+nDW%FMnq%$nS+C<#mZ9RPdLqedjLIwMZY:uIYnC
uh^WJe <RpLGN\kMa>cBS/&9qMq&+4XYnb@QKEZ1ZLDh4@CTlAij>LN8R$XVeW::mdXI/*mY<yKk>1dPWp&6JHd
#J+S#J RHdwa8$5*heuaY@nlANX>Fn:M1<TW5qSbybYHKemHym?4WTb6^M4R$M^YwjT@$4EAyt%LTWm+5PeaAI9
F8m$w\ Bp96S88G=Am%>FY6epWm*+?^e!yQe!+#qT\tke$eLB+:kq5&/H*aj655L/Rc4^AmSMt^Phn+6cGWL?Rp
%hidI# Y%u5&h1QB8C8\nemS>Ztep\6dmG@kdjWH<iGNRW/#\i5EY6/MjZknNc5>Pjp&6Y$1Y#yCi!X\a5*wKHS
&Em<cd nVe?6Ae6uBA^l6PJT:QlHt<#?IVLmRNy>/aLJ+\>M?N>+Xi/IE8^yWq:ch<V>pE?lMhWwme^Ym^lV\bJ
@A%bh8 GJ^#>qSL+%XWG<QVLtV/\iIhcHEyBSn4VSapiMTa#\1ja=!EB>i<IY54jp^&Dih!@YV#w@iNX84u#EBQ
E/Lm%/ tSEiHw&KZD9\9JB9Dh#:Qq/m+Qq$Ym&YVlBRR%ywdyG5T5yeHP$TaGJVbPwH&LH:i%SG/u:8Gd&qDDce
=@TYRJ =5d:kSc1:!c$lE&j^SaZ%bkS/ER!AF6EalkKTa=n9DBy#\Lk5HbL/GqTK>Dj!5Y1dNRW>IhHGN$lNZZH
MKpRpe q1*WVQ1e>M!JDL8b?D!X>Em^m9X%i/w$uDyWY\wmLi^=<>JeHd6yKQCPL6leX#1BEnRw%LF5tR$eFD:B
Bhm&wl kM%HQHB4%e+Y!!d$l/jmVQik?L+jMML>a>k?e$$J+u^PQBmIA@Dw8#VKZL*tR6ALDBi/#M^w+=9kA#GX
$NbS^I !$u#Lb8+!QJtHB!a6ybm/h@muV9cJFM4=#CdZCI$C=V4tLeJ9EcFQ/cha*CdIjJN5Mk8#^a>=D5mQSt*
NX=CSZ :yXqV8DQ=&*#D4\9m@!&mqukn9SeAP1u>mu\Mma>#YG48yL1jT1QSjPWD<p4</iR$JyB&mB<q*X=h:c^
\C@=bw &?NhW#%T:m^J8MkLuSR^=PLajtFZ9\BipVCi$6+=SNK!EQ<yL**Gl%d4Zh/T5wY>!nFj/%j5aF#V6$4?
ldW1Rp $C<6LjK=Y&bZYTDEWTuhy*^=kn#pmnQBL5uZd+ltiWpiPHZ=W>#>##hLY&&V6JW8&&RGQC=8ee^CBS\$
?T4496 i5S/iR>L>EZLAZd/IkC%H/NDMNj<ij$Dk8<&ZtVwn/YIM!6*PF!66lPwdV!CB^qC1IRZ#Gqk!R<1EE%b
Na%$:N dCA>SmWZtAhDLi6Ll*D94FElAbGINS<&lK?RpebFa16Z#Iphi6MWc>IkAZMAY5&9:?+@%PmQKcRySAFY
KXVYl@ :F64m=Glcb/a^++R/?wdT@DAJu6LB4pApS9NMJ1*Cl=4T8Sc=aEG+8%XkWMRWP1m\$jMbiWj4c&c!96n
H!nTmL :WW@Yt%auQLYZHR%HcPunNa!pY+qYM&@e?TNQ=d8KZ>IHCpPFh%KnRdGnI=jIA84VaBaHLY>wb@eatZB
dj:kjp ^ECe+A/cy6ISau+$Y*a!\aQRbuteA!pW9bdW8<$elckeY%lw@j#PXH=$\W@RDWD1T&SiS&a$a^eK+&Fb
F$J*bZ +V<p#1q/I=F&P>A9aVqFWhPL*HRquKB/dcmQB6qy&6qb/dnNwnWVjX/lZLla1TDSwmuMaDZ:l>AL*jn!
^/yTw= 5VAkVDthI!ut+uBaQYSEja\T5>FDhHBX#DWV/@YnG9A11=th//u*B:pcqGYFR?HILdt6=KtME@GEdcmM
lPlWLK R?EB+bAAJ!4neHlVQQDD@P:A?QipX&TAJNlAaaL<TT#ld?RkTuIZY9J<T+JGR4!kDA\RD$YnAMWXQ@IX
C<PTJ: M\ZbK+Y1A9BKBdnNBqSqRi#LBDc1WaE$KJNp1FVqTdaq1NA=KF&pKPjhKeqiTLc9MEY8cWCiXEq91XTh
6h&5q? TJmcpc+mkI*iqI%G6K4ltCI@+/<aCyhEPleqaKMVypkqwekR*XWN9cw9jXIRnep%k$58HZwd6VAaE+mD
&wV>qy %1YQJ5tXad/ECkBG6?WFRD?pWa&mtd?p!kjka!Bm1n+!>+JSw\jR5eET8=LmA#blkkyatlmyZGcA?RBm
&EH5KT +$%mp\JY>G#c^ticc^BiM8iyGlIwGauDXa4FJbuN=JwncbjVXa>n9wQNXaC#$a^%QyqC:R*X9AJZ$l\*
\jdHH5 8k1*ckn*hTIQY^JiWl6*pl&Y1k@mRkt9c\X9W#Xmd^WFSk8jc\hjW#iQYl<@Y^Id&l/aTkt?KQm@uEy\
+A%Pda 5j#*CL*@C&%*N6K@lBj?6?X<8Fn@p>w&QKB@%4dlaj%6^jT@6CQ?9TwF%:?RB9qLQ9+*qGT+&H+H#jW4
1c%4MX NQ99wDq?lid+HjT9JLC=PH<D#eH%C\q5L1:jRj?!di:jRLQ@Tntem?h*$KBjwLqb@p6w%6>A5@&19:q@
mYd>Tp ^>jaj1ZY#9$:95dG<k5yGG:&@^L/h*#6%@w:*L@ndJ!e9^Ai+8d/4e9&C?El:6>^NndYZ$ktejQ<%tZ:
F6h=u% liW<LQ>i<wcL>Z<6ijN*pjR@JG>?I9/F=A$Q/:@knHl?h9H@1=n?*/YaZ9S@ZnGh>Rln:^5REiJ4LDWN
&tiSin Qn<P6LY$Vc#RBRI8dn%+MS1WTIIV=kS$u!5waWCWAERaBtE8l5R6E58?EXdnK!EImi/pJ<lVW!%KCAXS
ZJ=FCJ qI1NHPK4DbLb4S?kDGeye5GhC=I9uR6QmiZFG<HMEPdqTnqTpS^KyVBB:W<N5ePh^$#Rk+jEHMKiu@u/
9Vdw^9 >XqECppCqbZ#W5ADW@Mt>I!8qE:blyD%/!I&HuT!XYSjR@uG^yCC+!M6##m!tmie^1X>@S=m$ckI1yb:
Sdy?mw qiw1awPGy&yLDSRRh>lERe=CKeqA^X&>5H%ikI$S/kyVR5QhD#j<$lL:YG9ZpFaelS8k#L9p?quNKBT*
:XyVua &<k:LwSSCF=LZSIutJ*Lke?w+!J@C@Vy9A1#Ku\=6^JQ>&:<p*&95kH91D/164&n9q*nN6>cpHAycGaJ
knF=tB Cab9ejbcG=Xh+#Qy\RCa&Q5c%WT>9FqLF%!>!FAI?nBBXiX4d+Mh4t4SYWl\TkqnLZ89KiRh95<1LZ6P
bh=F?a 5:yAHw*cI5E\61*%TnWVBXKeMP:+4!9SyluCZN8h?eY$pj!KqJVuaBK5yl4&B&&W<&BReNJPV%CC5?^/
:Q*Y\! SRZW\C/pnH&&dF5iQ49d8Q\#Ze*CwD^w?C6^Pm5MdehCESc&LVy4M8Ga$KdPLuW<MW&mS*>#6<A>XPSy
!nmLpD ^&:pAeXWMP4Bm!Wi%ce=+!@he/n:B1l5:%P>iD8M#Hqu@VSm&D?muwI=%ZYe<XITj>e&4Rww*j<KH1bd
%\IC1c aRBi?=a1TIn?ukwiTZVR>n#^6KD5+aqW&CYpu5!IT+L8=e9XKX99tKDk5nbtkdCc\:t:RXc:ItJ8ek>6
9\>m+Q >FeeCEyl5$*SDaX*4N^MRGIdkkpKnlNud@\:@Qhp8wtcTCa#>BD9EhT#QG#G^*BLl\Id5E!d\?lTpYtl
m!XJT4 6mwy/Bnk^*6=BC%j/nXXMcMTa#El6J9j\J9FtW^/LVPECBMM@J#@IGY1B5QYn5\Y*h9Dn&pYTBiSck#K
>idPFW 1mb^!wBG=m5lRn!Sw/GRwP<Q>6e*iC^:cinA!$Qdpu&kI!eTYL9h>\dq4$1T4eJl!dFWwDX&GlEy<jXA
@XPV!G uPSET*15qw1TSwIHh!i/E!$<?XNII1*RnbmlDd#WHJEjPPiwT$+b:K6!Dj1PI&E^+W8e4hw^bhIw/BMH
LShTC8 6nPThdAF8H#1q^ncjbwmYYak6W5VVnh#1N\X/RKQcRlhQ/c+yDyA\PRFa?kL?#C8V6FCkeMV4IWX\5p!
e<kbWP N+KC+eF5!JVm$R\1<bpIIM^*KbR$nI4d:iwX:ZGWW&Lbwa>&:1#>eFFwQ+pV<Wm1mqScWNn1RLMhBe@K
-AD*iY 00099caaed600110333 Page 268 of binaries1.zip
A<^@?c &+/p$nDkhZpY+lD*C+ju#//EJp8GEc!hJp#RSnd$d4*QWJYV6VtPLQRkncHX^c^c!NpuK<Y9lKDHNCZ4
FTViCP 4/SuM!#FFPZN4kJ:m=hG:wmi#Xd6tuKpEVcjTJ<$YIj+6lpcj@1D4Yyy%TE<QIEZQXCS6VkA&q1hmB:d
!wmCa# @nM+MiJYMK:G9VtCBkP:P9#kQEjGY+tEjP@GTaptetAF#ceBZlwwR^KInMA4bRQw!HAY9K:9lT9d@SZc
babdpw 5T/J?QDEiAPmH>#TAQ6!$Q\E/Y9+bqZwGb<\nNCb+KccQe^Z=yPFw$6nmD9WjPc!J9ITHPyy\4Gtb<y/
:S/Cat k=ib4k&:Rba^Ya9*?Fw6S6%e<VBAknQV&kV4^lZynRy+M&jd@X8b:^j5%hHAMeN<Wmq%H6SKt\NHJANP
d+CZH% &WZ$jFaEn=c#K^TpC&#$jy\^ImBTYWBDK!aNl8GDSw=l&E#*DK?PNVmiiccjE#6ZZ>bW%PSqHXKDhhB&
p*H$kk 1ePF#41AunytC?Q*dBYR9XRF$:bheHTPbi!?m1!h^atG?VMD8n=X+Cu6B>4dq%6et=Ii88WJYwTnD!hZ
@P>lFG CbM5iL/Fk?++<SkFSndCt%!!N:h$ZaPI:ZIE4a>TPT1Yd+8nC+Z45KZCFWmXDiGFceBlX:IWa^c=Nh^Q
m6#F+4 *4CIECX=!<@l%RbS&yyiFP!*6N=keT:!Itad^tIFqjwpdyV5m!i1?4W$+nBbHjDIVuuZVM6*c>qS/Wp\
9dYqXl 5#C1\l89HK%JNhTGh1@PWilXe4$/yW1kJZ^ai#uVQmKwpKtVWq?^4j5\J<EJmX\!m<kylWtD6?I^&%<6
LnX^PB IA:>64@/4qPjLZ$@nENlT1K%te:BJ!ZWbHA4LT@iMbwR?at\>Lm#QDhjIwY%NkjI$X1iSV#D\9XYJRSW
+Y*V>k adYZ8HpVuGmHZX+GJ5\Mt@bY&tZ$CQ>:h&Yk>h1K8VqG^bZeEL@d$#AEuQKe>*hapX9T5u%Jm6T?6E?D
tL%\yE y?W4y+9*I<nluwq4:mu>!aajL@*<EE9ZkI&?D=aJ!<*V$wcIXm\V$1qmCElpVcZk<eYd1N?%i#w\X%Tq
TEVhF^ chiS\=MCjhS=G/u&1nK^cn+aFHYCQmhbMW#Nh%6j#YRldL4^BJ<jdP^<Gqn%u:t!JIFG8PVB5@5CaBVM
5615yt NpqAwmV\ICG#?ILyh*dD=pM/IcqAVdb^+M4eHp+lHZju8t?RlCi<L9Rb^!kSE1!Z=aFSPtF#d!*\kRdW
HCVqAi l+Z&^dA$SE5!=AC@h+8Rk!w!ti<e:IF$IP@$5Yek=/:ADVd<B6ZjeY@Dc9%Lh9HA?TqdqVL?+/eR!VhI
KGY&iD alA%QVQ:Gw@R5^dtTZBhPw+dC@SMh9B*VSTcNcX*HA+*Y8j*:Lb$+qR:L=DcmE4AnZ1cu1wQFnHIJbV<
k?e@:K n$WP!Am+G6<P1kKXD/LkNaWd6&#YVqAGW<aDwYHT^kcZn!SGm<ZbA!C+VeNedGLI%W5ES@a>cmB$V</l
TX9>Yu T?mLq<QRaEdAp!Ep9%SJ>nDNF+dhBaSIT4\LFT8S9a?t&c/Qdk/VFS<8N/p16p&wLJVXFBQ#l4Ja%yIk
D5W#Q1 =hqn6*#D6GXD4yZRluSRkXRyA\e9YYqbjkK%*ET=h$^ycLI4dFqeDdXX#tVi#Dn1>abS?W&kFdT^m=^W
DImByd puh\^nMAE\4R#yy9CpXcnmSY!$jSTph8\!\1iY&/\&V1\#<E!Rwi#6l9#CjVT^ZTJTR&C8#@l4Znu>%k
/n\@TR VkaiVdMH!XLFDd6nCkqIaVSiyC**aaEL=DEYl55ZSnD?RB5+TpZ?Rm91Db&wC\pJVm@4nDZZ^dT%Tkaw
pSC1Jj bSAh=TPj>ZatJl@5^B*5baH%W<\*B/w\^A?!iP$6+R:CY<qumWA\\QZt\WiWm9Y/TeeawSuH!yG9M9dL
pqBCKY R\jcRb5BFFG6^p1D!GetwK$%RbP%&kuuHlLL6q8YC%Hw?nPTBjYDWEkE^KjKPRi$1JNZ+lKy1KQpY4FY
LZb^Zm YybHa4EulpnpATBN4WG1hqZDBZyc!njC<w&SYm1I=9SW9nFHXXiFC$u^l9Q/S8dc4w:uWLBY$GcGhlQF
+R>ZJ: 5a!EM!Bc\KA&5p9G^1Eaua6tn8WH4q*8#GqaESAF8R6h/#8t\@DRTCV>mBuiL#A&d&uNIcETHCkeLAL:
LlTIFD p&D#qTtX6b$1NVDkuiFTYjdN:c8uPT^N&WIX&TI8hIaPIAG^+t#5$6T%A+!%TE&RJmFbD5q+LMmyNK/e
IB<ZjH JlHaanM>HE&tckuyINI9dCZpVSHe&cTHZFEk8:Bp>qBNXVF8GVkZ#>$GQIyY91KQFC=hm9uG%CHn%Q8<
k<k%Y4 @ANL&IqJXM/1XH9nVJADPPPijPV?Am4lILG9<C1J&HNyyCyb6HQ=yKcb?Ip%BGnN%ML&JAA:84$BR9JY
jne^K# 1F+dJ9MJwRE\\m$5IqJMBqN$Q6bDayXh+uJjEwBDc\mEkPk^!VjPc%FHnBAG$=kQD:I$ZPE:aTj5=6cE
ilYcL8 J99KeDZR6=ZkDSj%:e\QTuGIYbS*FlK\TtGCy*VAHQQ:bFyCGW6!d5uY@tblP#yK<dD=S^muh9EjEyJe
SHbAQ! WuaMHJia4GIQbhSyEuQ9$YhaBw1dq@yqtHeE4WMMbYq5ipydIhG>t5&Fp>mZXTCTPw6=dShw%t:Yye5Y
S1Dt^\ </p/KJt\hh/+cWQib<Pw^pRPPkF8/wj=*b#TpN?a$W^=e>eC#TIh&aiY@Rc+Lh>wKeNVcWAQt$1KKT@1
H+ThC! 8mJDY/V!/pnIIyiBJCIyYAdby+@FF!eV4tw$=I1STIHEB>BDCHGk<u4Xk%EQ4:D/MV6i+jNAm5aZ/@%\
FjB1=+ u4Bb=ZB!?^K9hDMJqmZ8n5by5YIcbRy8FHXhp<wQPbc#qABuLRqN%RENLZE&q6S/XiyJ$jDJ:h6&mZhb
=PR6/F 44%H*$:l*YY@tqq?M:AkS#4E:yFJ%qW@55i/ydKRNaFc#nVZSl#/&46WDaZXJbHcS&aGZAJh6cF\=u?d
*QDn?* HAeT1#bw\yDcp$taI$1AY<BMmpq=!S1LtI4ZwSZ6MI+:qWtFR<*Sw>>ca+n9a<!JaKyIk/qqa!@p$cpX
Q1>=DK R1LhmdlYW@h#<jiHMyBmaShc+GCHEN?R<Mha$q%Q$:k8+Dc6CBSCCY!JCLLt>c5h+#6Z+i@:C4F&YAp:
Qa^>mR CSYBCcPN&GM9RtKmmcnnClVZ\5=>J49epkj&mJJ#mH1Emdccq#e#&&KC/MSZNIjGTJMRJX#Rbbn5=LB%
^mD$wh !hDJtaMq!H5hKYDDtPPDtBeF/KMcNcZ^&KIlGDFWpe4Ly=8$FGQ$pX*%>NTRpjIH&ClyECuE^dXWdW/J
W8?kpu 1#Zektph&TXwPjLZM1%hIiT*81HMR#lTL8GXu+5%&eci*hqTtV^<MZjS4NDe6Xp>5eEQ?W!N?Fy#jdb5
XI6kcY KD^KeDFtcSbbcJM@+ZF&&A+%&KGXCC/QEXC$ELl?6^K&wW*:JC^/RL8V/eC/JNJ/Jhh@LHL#M@#?TkE=
MDRW+j +YRP+%PJRPGA9A^JA6+:@mL=DZ^Y>5Z^/8*T?Y5!QaVqy6kWhAPXJYLqhwmWL%l#R8*BN\BT4h1?ep&q
Jneeq% iIbFGuLJuRMLAm1M#\qTdblni/$>>APMd@DBiTepLbSYMS@=9?b\iWD@X+8^<:D>=>ndu<l@at>bYdl@
KbpSlh q:*>P\*!V\VL9&C%iNl?q:*q+jkNNAjuL@k+H5:@Ey44N>D59:Te?*jR9?IliZl?B@$LHyKXliW*$H@w
KJhJ^+ R@>4NP69wEHe9&wd>D6why=jwNq?A@%LF9QupQt6D8j?Bjy*uI&ht?WZ/N>^NlAH=!@R@!T>@Sj&Q?Rl
Gpj@8m @//&@TeQCiL=b^:!d\Q+*@GR:B\@1@n@ld%4bmw!d8Y!wYmY\8ZA#Y4+tQFRCJP8WlH!JJpmq\+4P4j@
Zw$==j \a5YETJSZPESymtTay?TRVtDjikl1IkJF>NtIMST&HiA=m$ALF1Q+W6dJB&JTJypb&tS1tXIwAiwZ$6Z
m>Ch6@ 1YVi4#4#+!QdcTAL\A6MHC!hen?e?VjHSeiRandBXYX65hTRbbN!^NHLduGJ$AjP\ECBRcJm>+tIp&/F
/d$bCS Ic1#6JQdEbD!m#AED4PLpkpQIQY4!BMkT\TJW/Q$F?yB6#MyD=D!%$\&5WBSBXW/ZLHDQk^YWmCNR@?A
$&n@8R tuGX^C?C>!tEww6GEH#8ld@A4GbAYB68DAM9uMeQR^PXHwc?1D^wSVKSI&GHkyneGIYE!MF9CaPa*&eQ
FPTQM/ leDh^P!\dV\jWWS\JiYGayN@GSZF+MQEucJJPPIKlTmi^J6GywjGk$IEuZDPIkaPEVRE=ZJ*lqWDN6tk
lKPN=$ !AdyXbdt9E^^wTBK\EDK5#Z<4XMLaTTCC8+%Dyk1V6ZQpk6aW@dCT\kYH1!LHPWmQAy*nJ/YW!yZ^X8<
TIVB%e hp/8bQDBFE?+XQ*FLW#$5u5RLGJ>1hb<\&IKhm%1CS>PPCEl>F*cWemeXD?WISIbaG1td>B^Gp/$/PEJ
4wBdJ! V=y#h!+6%uCB\4kbcQ&&Bpb%A94dM5\WnVQelDtNJ</FDM&9#&RT6quC4K$aXacb>e^@tF/cGCdWICp1
Gb4:1= @bkT!hnVyKJP6!IDjA5d&p=q+VVC\6WDGe?&PydJb%I^nVeiCbhn/Z61VD>9wKJQihjmjSZJ$QST9&Bb
QSM^Xc \^le/>EMkmSk@^wp!ap:GRRX#I4eWWyl@G&%&LtdieL+p@mST9CZeMaR8t@<VnH*Kl&HcNCupM4bd#iG
bHJLA^ NXM+Z@6ZSiIMtpTLIwnRwCA+eLR$MQ\DtuiW>%V/Bld/>>PuJ6+R6!41BTy#P@GZ!eCKa!N1De$>^niR
bSM8/y uQy<:RG4bXtH^dV9ZqHt9<h\N^9$<6MY=9d$p>%8N8//>Wa&Yl?pa=lcXKjlZXDyuhnd@dk!^PEmh:L>
\B%T#n +at@iG%Z8euHSTTTyh%6Qt^^aNAuj1<>GDCIy+<k^TkyDA4Z^l#M^RkP1tP5+Sk5%<ali=c#MMhQ\q1?
=C!e&@ ISC#5DL=NMlm#yp9J5?pC>>S*4T5YEYe@WW$Fm?TN&X+S+hj\H&@q#%<#^I^n#+JHl1&Bd8*ABBnYt%>
I/Fqc+ +6ceNt1aTbdNdZ:cJ%E^Yn8P8WYKVLdI*y?knD>k:G$%SYdaeCA<yF\J?%btKcwTT4>j%=!j^Sb5nLta
*Y=IZq Fn@V#kp^:6kiWJaN8\%?a1hm\>Xk#4$ub!+S\>VCZt?JQ4$Gj?dA1IM5&4>E1X^+H#:8R58XJq?G!/:D
:Y*/>4 Mq+TJ9PhtpA:8#8Ynm^myDX$dP<1\eWpMWTt^AlqQ<uGDSGI!lL8TIq4+t@Fe86Z9\#1!RD9k!@+wIkD
LKS8$! y@nnp:S*mw%:Bjn<KRk@qnBl%15/BFa?:h*/DENjKny&Ce8/in?N=:TJ48m6Fh/5DRwWdTJeScAIH+bL
5yh?N+ n1F%!WlF+QnyXqGEWiK<AWW1u8AZZ89*DD6S*P*ca\Q$L5=YImDi\kWSDJiMA6mKLBX6hRR%BWL@^lN9
mQ*IMl u9wBGiWcDPY^T+uTXP$N+^dWN^ZFA*mA/YmCKa\T>j+I&VWY+$>mdpYuF6ZVdE@&K/\QemYCElW&anIa
BXABVh qRHKbC$C%SIJybwIW5w^P9HedleS!V9%ctTj?h16eLeuXL<Fyd/FK@%BYy<CQ\RJ%5^X>iEnEY1LWi*?
Bnt!KT tBy+%Fwtyul?CaeBu*D9tRpF\uDX!W5y@>kaLF&lMZJ1M/dGCC1C68=56d5jV%Z>?l9/Rqj6CRp:Skup
^La?#C HY^he?&Y^XHG\AFV:eI*VYqS9K1*+WREyuMKLY8LGq:=DSCyKXYXTL^/iA=lD1bPmJ!1ehR^PRlMA4Wh
hlFMI% J&eXENR/YLaRQ^DyG9G=w?DW#Hpice@</uqyq:ARXN\b^>H+bnTpR^i&VDId&#5M>uabM#Xw4GVS*yit
tepWWP wybC9L$Pnq@myY8EXw6BNj%a8RIFH9bMeanKDB@/hJqe!I<pp5FJaZGQA!Ec::YC4l+1Aa$SHNm8GSSJ
-Au>NJ 000149764b400110333 Page 269 of binaries1.zip
b%JqRB C^>WQyub^P89ANbK+SYaqKLt++::R+Pn6G8%neI/ZkF6Gd4+=9*86Z<*CG&A8<18Ew4$ZcKwCliTBGAj
uAVGic t@SdTB>AASLMnmpFhhSP%XS^ENK+5IT6JtL5^Za5GVMWm8&D=%mGJQR^am+\JX/=/aKW6Zh%H^*XBnH1
j/?GJl IDJ$VIE8XT*Hj?*KGK/Qu\=TA%ADNn@RhjSMi6mQK1M+X5KNpWJRY/*G+^adCa&$<#*MFV1VKH9Ph!c^
WyRBI< lZ9hL+K\GF:WEt!ZEj<enVDjEuFcGSR<t!m59$XVm*+CwdPKB++/F<KW@#ETW4kWe*ZRSy85q/XD1u@+
AwYymN +Q4YR=Ey61jCME66q6R6aYe<>c&\:^meDa<ptyPN:%w:5+pm9:5Gt&^EX:$wBiHc^RpY9RS$DXcLm@#^
/nQ!+5 !!MwXe8:5pZK1#b+8<HmQn5:&qPH6h>$!YYjI!Z6YWKYp!Z<aq>wR>5=KB!jL#k6*VpHQJA^B&VCR=tt
qwqq>P ^+NDeqDT?GMM9#c9:VG@TpZ!&lYHe64#KT#l6NBXqHIYmY&DttEDClE*BL1GQBE@akyMS@4a*R4La$TM
+ePmQA !J9>c+9%y%bu@<D>/WeSLnuG#FQb%LajYdIQP#8?!jPKahPj*QPw<t*cHAwtAD%Wpy8bV$T98XP4Hhj1
ypSQya w=h#JXcqNNS=>J8<+V#jQb6jXHV9W@nD%i8e*+<cVHXknlK<JY@PLXuw=E\LKGRPPWH/tNFciGGy^\6b
MKwuBp 8?C%Ry/=IGmq$KM<t<6FnhbE:I:<1baM8ujc*M#G1kXipkQ/Ei*JNiBKpY^+TEiL@ttnWdn^$@iJV!G5
Ltek=L q9JVYWn#mu#WCyTY8:WI#V#pMCV%DhCVy:tnM6t#6BVHXkL\RGEZ9WKu8bC9e?N=*VdFT%d!mZcEt1a9
JDXy=j RbNW!IEHStQ\a8CCk+nj\j6jcHceN1e$n\j48*haGMtFtRDlLA/G9ld/q8AuTMdCeLQK4KGTRYEHnm\&
pl&jJT #qSZH&#X$!t6d8IKFcnYdPDQLaNQ*6VdSi\yJ%Yim<KJRN6YS^^?>L4I/l<d=DY&C!$PHa\qFZVmZ+w8
QIL+pC ZBK&5kQ&!m5M:!l/RAH!#TI#%BLtnTH6tG4hQM6Iae@h>pJ\tbCSJSV%NY9b1/aTIJH$N%kiWIRHWID<
B9alVN y1V>!A=$YlHA&9%!#Zm4@ZBi%aSH=Dup%L*ybtXjFPPnR<uaa:kdC/daR%R#nDpebCbY^H%W+a99KQXZ
6EPL5A *?*WN!Y/N56!EjduEMc\k<W*ZiK!Qyuj=$NPI$PbF<Qa^cQTXNV5\&<=I=CcM$A$l5:!H#jaCbphJFya
=n:@Y$ >t>bA4iW+ekQC9bGYSY4@h+wm?/5qpj@uKVH!=@wtw+A<\dy5tZV@PH:K!>H%+Cn?e/dbSc<:8Z>S8Ji
ldcNM6 FW:ld<5\eI:Zeitw<p5JRalMHnC4WGXT^A#kC5hHc>S?:$?wTiADtWCw6X5u#BWmcLYtJjG4IhaI<LQ%
dqh@%? iuEHili<?ldnZ<ld8+@>nMjpWBV/pjNZLYQI*iBanMe1k!\D+$cwalyyqKp+nhHeFKlE4Yp*Va^uc:jt
%mXZk& p?HQ+aaS$&tF$$4$N&AQ51$#6Ft**qB9^a:8!Wh?*IjB*Ictimeq/CIVtZX5bTuPHWP/RGW%4l+wuD:j
c&THy@ u^kidRJ/R\P?=&PhmI$\9*u/licAyqd$thaTPkS&</Li*Bn&TT#^=R*>P=dAii8pWTbI/h=BGpP+Z6Gw
SE^N8% @M<Nbun%dbSYkpIZ\6%XIB@Ai&kkGc$n6lV6M*$SjP*BYt5S>QLIX$PuLSGcHb6#G5V!^jXpV9emkPn^
*aDInd nS1MnXLkHHi9enw%AXjTmVN$pt9^b?Ln?Bb^jMd\H%!TSD#I$Y+aFmT&/4XdY<n=k$lJB=j&VcVWm&>K
<T8Y9W \jlCqjQunGqa#ViVyZPKD4+\*5tn8SZ9dVL6u:MY<#wey9LD&wFk6wZK1EFV4SE*kEkw<T=IJw*lHKjS
%uKXW@ SZ5Ee*jAl6pAcYV?mSSL@Npm5ycpjHBCkXmMm<taA1GV>Bu%pnkpQi9iGIn8c:SW6SWWh4GCEiKBXS/q
IwA5Sn 4/lX5&KW6SnVStT#Ck55@*Fww==D<Vh++k$Gb4V<lHMK$tDySDLkcMPNl\bt4buqV14=6JnymWGVB/Q+
8ZaIH6 /N/B5VIhpj#?kZIwctTK4ymnk@bmBZuKMK8=wecRuS4t6e#mX:>>YN$*Kw4N9i>uqI&XMG5Zc:CCF#WY
C^D:eC B>>kkc5/j>Bi:GAeYXK+JSNjuPJ1\Z<na!%^+/pAHFM1bk1l&*I<V&p<$@!Cmm+w6*q^udh#cILqhK5W
WVYi<& Zc8Bc4eu>^cI$ajFTt:mP8y5M/pGE&>BTRYJBtTeblA6$Z+:njlb?W#d>5WDJuc*!5$hT6nX/SGnLEFl
jlMFq/ ?wW^%iyR?S1q%l4>dEtuqA?qmy<J/qtbMwRk>A9!QQnSYaKtGPql@R!Glk%n4b8b?&eN!8Gep@e5q6RW
EC:HX* hK:p6icF+dT\tln<VhQPFlbR6uEpE@H=KDm+Wnlp<DEWM:k8/M!pp84!q!eqEl#Tpje%++wN%n>R*mmB
btQInG NNGDdlNKVZe<T1<6nya5XY/KdYJIbNYLPDFI+G*bMeAb&JRkd4IqaR$b\@K#>/X>aRPp/1jh9=HwLiII
Q!k8yL C+6ILyKcTALT%EH!q*68tHRjwXmq>@je$Tq5HF151h#e5R6A#bDYXZ&TYAqMF8T:w@+iVX?WHa#haLY:
+WIe=d !p9ht:hTa91RXc:eAchPpQTPeIb1WbeT5H6MWBe=tlH+CqjRR?PJH6!F^nNE<>RpPCkMl@M5kNJCG<qC
*+R5m6 G!!1FAj#:+yt$4l*mR6TI*=qXNj$qh+pEZIi+%TF?/ep<G!t<jhMRGu#P%aW>PpKdA6/bJC#<!W=BSt=
L@y!EF <$b<LGRynwIKntLRPB6Fbb1@t+eH>Wc/ipLFVVwmJCDSEXlX=bXc=6Wm=%RQFZ/L\F$>ANnlmP\anuYF
NiZbc8 $meZQ1m1jFuRACy#RP1Y?HSGL%bXnZceFqc%9aDk^/^V\h8kQG1$6nG\W*pSI5RH=#5XqSYA$1/&Vp*B
AKS<jN &5+I=VWTut@D\BHhw>?9WGyIm?Fdw*ej>hDIumNF6WcP*u!ZLLh11*>D/\QF/PYG:lTJ:lLAecJXH9>i
6aGlK4 emjT^awX/yLKyWWdKnnd!^<J%!bhyk=*L\AQyIRk?w1RBlMYy?Xu*u8@l\/><\u!G:dVlRd%4B:Wyc^Y
AlCkdM Y\ll5&LESY\<JVEI%b51555bNVnE!$>lNmciyk!P?\hS8X:e4DW<WkhekkX<p1^Mi/Ni$%h>F8RlK=Fa
GnEQNk tALE+BMJ%C%I%Hpt&A#=VN+A<FZJaZM%!D&qlCNSDA<%GPI#B>S?t^cb<?d&T@Aab#ZWVF&^1nk$?qBu
hKW+w/ <EhP/ubh>6+5J95$IF$b?atPt$J1mt::/c%JC=W45li!<Zc!=GLk>?9w@n4kZBw*lkVi>Zq*Y@@^D\cG
SpCVp+ aTECmM<E4646K*61LQQ&RLR5m@A&8L%I!1I<n988Cb1tTQmk\M*Y1AAy1QD/d:nM*9HPMMZ=E8EhqpBq
:C:XNH uyM9k@jI6nuIe6H!D&D/6+Hmq$ej1Fa:J6I?i6keTaV4RehY1W<*BkM:6ZHa<VwRiMkwhaA?kG?ll&Lw
DmYI+\ HkejJZ!DpPN5m?ujnl>WukaX6m8:\ZiGYBwFW*yw$ZPHSZCX!WV+dR$*k1?yT6CYcIPdbWt*RVXW&DMX
lp>+yX b/AFF&<nT:Ac6Ae#lk:/&N^wu>RF69Q4M4<J++T\Kq#8Q4aIWwX!9ca$Q8R5^dF*n!Bh>?A\T:MRTEww
Z\L<R5 ^Qb#\=@^48yFqQ%ttlbEm84GXPFmYNXdI4Ph+LYX4uL4t+dVlHbGSw@+CTjh:a/m/TVc+h:uaB:KiPY>
Ph1wcC l!btiTMZpA@BJA&M9d:4C\Xl>>aBI5j!&cY&D5iqb8byb4RBm95q^pl5dd$9ip&mRi%hRlE:Gjm@yLZ@
W@c*PQ S9@?Z$64@:V9Q$q45:H?M/*N^9Id6LcIk+Qn#>J@eN5knn@L@*#D?je*ZH>@\@%*&959H9\9G8:jE*!5
9VNG\a @<!1@8$:@R+Q@4QY*$G#@R4N>q>C5@<Gt9$Z?=BbYVu?T&nP*$H@$uK8*$G#@k4N@S6wNt:RL>A<9+Q?
^bEhu> Xh5kq6>Ak*/^B=wX^QyjR9?P4@&ck\j>q4P^@+JFB:H@J+e=J<5@D*MPu6>i9iLk@yinF9S99hjC%i%9
!i6Vay a=#>**$j4u@aZ@!Z%Z@iQu+i1dtd89*=kd!%k?&jSy9>WRud##5I^$<W^$<Z+Ql=e@nVFEeZe\8Zu!hb
1N:qbb @9#:J&M+@:8M+jq=m?dt@6Mh@:Dyh&#l?8?!lb*6y!E5*H>iGLc@>>H@\ln8@<aLA?Ll@HP6:A?dj5eY
@hAQFW uu?*pQN*=@?QFuL?^^:!Q^h!&Lu@^WIPG<5@L?S\@HGQ?u<*qQ>*dTl9?t@iWQ=TAlTy@&6D?aT!GC+8
Nj&t8n >IWV=wSMu=Wbp9m&qSYtlQT5MteV&RA9J^Vb1I1w<4T9CFqaRbeP<w\bRktKnIkC=C/$i8Ra/wD/^lpT
M^!1=Y V@MbD:aKtIRwJ9L<Y!ZXWDS?jnbSFR81A:GcIZBM=AL=:+LN!FmI9C11GG^Tclm4^%l6!T&EwNYY=tj#
ku&W^G eHcuAWP&t5puZ5VYwlIBqb6SFiMb66WVXMSGA!m#kTX?hi#bbV5FG$keMi=NbW&#$yNG6Zy>QGm!CYI/
5W>Ch1 &FkC@Bd+BHFMZPlJRQt+wwu\%6\<!%hc?&deWmLT6nnIS?thbR6?*BqudnP=D?l/I9#N&IJTWm&V==R^
L>8&Q@ VSt?HAKLnG>L>$XVdWG#=uMY<jql8FMK&M*^cbwd$=MHZG4/Ni*/p=<L^XL\S6CRwIkWb+8!ynX+y^SI
A8#T^? n%%\#Yk@IGMScd?ltFdS6<y5NZKj!mJt%B@RNY^La<@WkLJTu4!>^*^#Bl/:4@\JY+c8AD^jI\kcq\y*
ITy\N$ \6::LLPJq?h#y<AyRa^iycNGc*J?/%Py#/KTt<Y/NF9H8bDAy$+6S8eSHim1jPStT1Kq1^68NTtZPG^4
WI5=PK 4=QQ:/GKDF9j<BZwyDX@L:B<8Bnah!J5@Xc!5?!\$8\y+Guh@wc41&cIXe*khYVuS==B#<=1K+q*/+MB
*M%+PI =VFHZq*#4L=ZSFF1^@Z1F8lt#nIlM4i^%HG$JIj6pPEKDEJXeWyquC@<ZA>bFV?AkYiP\FN/E&N>%l9q
A4Xii: cS1/Zlk*Y/hXdc8k4D&$Fk5lT=h^CIkj\tIuPVuLBB$+TXlTCl+aG=Spap/KCVYAn!km4a+pyj<%6:FR
hejR/j RY/PpHXw5CN=aVJ*WpTMedD*DB#<DVyeP/e8K<5X^yEJJw1KBM*F%mMWcd!<CECY$cT<6K+JRDTKJ\?Z
=tS%hZ H<kaNy?BB^h6Bn&Y!mp^CK=baPIcI/HjGh/QmntBb5=HYeDhZ<mRLp@4qaS\ReDeKJ/=IELMRmZ>TK1P
kndCQI *YM!kjRuQc/8mb^E4t+Ey$>BtdT1F<X1tC^Q^M$m:ZBjkkBnFDW/AbY1*^/9lm>lHBTSBeG@BJHltqEd
kiMJG% ^Fe&1Fped#9Aqe#PXbWKYRBHR/Nt@cNRJEW#cy1<TQ9kjq5lJb%NBGCjNZ%mN<$tG/qdQJGNyG4XF/ke
9S#\Pm u*C#ybS5H%&lp%YY$t/QTC&AJq6eHXPR/AiWP@bu*9uE8QeA+^#1RFT@EJ1d9CcuQKEnySDCZc9YGJ:6
SN:T$M Pte=YbaZ1cu6cmh4GEej1G1:CB+HBSbqRGj?WFTl%1jcHP%F*46FbG$44VJSAE?jbphEVb8n^KmcX4$Y
4$Lm6k ipS\^1XdlZVWhy&%SJi$dlMupM<\G^=y1N>uW@QEFeF^B9eiHD#=SmYE%P#qB$TGI%Ibb$G^VBpE59y&
FJCS9* NqXBi^*??S8^jNL<TJXE%j$%*AHER=6Eme>qD:ZlIjd5l1$e:l@Gn!cT%=Iq*R<<1D8la^lT\=&\H9LC
-A\kw: 000cb9c6df400110333 Page 270 of binaries1.zip
L8mw+^ CeAJXpR/k^ujTyGZ#Wc1GH5m*hESl>DdSinIp/k8N$k6S?DwblAYKJ##\ITnDkGMjZQ6nRQbIyVHL\t4
X>dunm lK*Q+4Ay<dK?+BPWI/N$=^5A6td#hyppynXTi:@V*B1I#dy/m5<Kj%eiWWWRMJ%Ytb=#L/!pQZ&T8T/h
I56G?5 =9KC6mMEjqPbn65C6YX5GW#h8C#mDc:jIc@8:/*^!J^jh>mit1pcpEHleME*\!RpGJcdI6c/V:cWbt&F
wh1#Sn XIH$b5:IDRpYS>R4<n$B\aDYN6MyApmwwY@>i$BC%EQNTckQYM+iu<$=QLA6PX!t+:Q&eC^CAB4Y:X:m
V9@q@u l=tXKShmNh5/dja*HY?Yn/k\Gn9VY^w+JdyNuSDZPS!KIIWDy#@Z5M$Q%YNbHm\+NGHJj?1&b^\*=YIk
h^aYA# %qtk>\WEI^F+bl%p?lH/*!tWtNP=B%iid9dXlT6>bCey#Iq1/<N=kh?8!u<%lCci@u+=$>4/NeH!dG<8
d$VuEV *l8NT!duc=*4Rb><uj4&kwndjIbcH^K#jBa5e/ZLd6>d4YD\#e:<#=8%8WbXQAK>1KeRRhC$Ah/&MlaE
5tB!Jk @qpL64GK:PwVqtGywYXm=eyS1!8X8>#LtKAVec1kal41#R@PlYG&S>diAqkh!SqXy6w^YiuWH$##K+y9
Red#h? >QSP*15niHdc%JCW6tac<jG!Ph!Vy!14&TPBR%pP#T=SR%Y6^QShuHa4tC=YZ>ZSp6adT&jRk<5yJYY$
yF#KbJ aX:dPw/N1<iH4tjSHlWkRRiKL^c?EYXVZ8L^@X:dQHyRbki\QhtHekiVB%&^X:<6=Ftn&>4AH!w</mW$
RmRu<E k/>yDIANt:AL>X1q1d1G+#NeLQFKF^Bku%qq!^y!bPZn1XGY5&@@Lp+#GdhG=%n=ybQnRnjq$/N#%68C
w^LeKu ^>Y&4*jbMjZXI5Ye$JQ=!#JCG1V14Q=%D/TIuPN\Ct+1X%^RXtG$<ei6<PAuclIml#YXtY<MZkEMe1%+
8$LnwC K$$H$Mc:N9q51P4^8w>Z*aaEE:K49h&cG>yKtb+tZJbjBqKPqaSI=?:5^+I%Q8Iyn@jH?4ty!T8R%Xna
CdCVV? QjjM8WNGublW8MeZuVtl^F&h$K5%t<Tbl*CKQVC>?@#AKIb$KMc@%X1^Gkhnh==:^Rphnm=m/5Xj/Q?8
:^XnS$ $F>A8nRP6yb9+AdwWJ+Et$Q>nR!\E^+4\<$WPSpH8$k19Ww:8lqQKl^9hSJ@hEW6jRe$6yPHAL#d?YNL
q#!N?X dqT>clIeIykMKynwMBqFE=RMBa\MVhI5wRIeb&#\WjIM!/p+5cXCt8M\Zcc5aYapHB#hFF!=dK1^aSnE
5/Na\* D8QRnZ!9E?5JGwI5Vhyy1KK$D&8?iTSNPJnTVZVhQb*TE>D$KTcBuMK1N%4WCE#WGm\!GRAHG%WQG:N#
WFGpPd EE5iB:/VCWFVBYH<@&H9L/Dmc4K%ed^^h=eEk45$nTaEh*eu8L6DCP+YLHl\h:iR+A:BZaNdeBK<@?Th
ddE5mQ iejibIc=e?@*ji9?j:$Y4D/u//ucy<+8&@8yZRJRla9R<K9ehwJSIRjR<MjQ^e?yjT^kC&?jIWDA>KXm
!K6Gm< FndB&quC45?@C!X<6@6Wt8JV4AE:ZJ6bpQG*PGEIhDtdT$RK@e^!iKdQmCKmEt%GIEC5<Ywc@K+<4Bkc
du=$R6 a1kY+kpLE%NlEQR!:K:Xyy#ZtVB8@SCbSI>1bb=tjVmVRlShY9uVAEMH&>*KJET*jIZGN5S9\6VNutPF
%k/RJP %SbBGWn\1ELCFXXYqwMkH6IXwk%c+y\Z/wQMV/619Z68=cYB:!FX1/1PLZJyXCnH1@*XB>DHR<aM$TB6
Tcb+kC KELyNuccR+@B1D:aaZ:G1Mj#5DGBAEXtTQt6b?mM<A1\ETiIpYd#F\1+WRyQwGMwwV9e/5hFaEIlKS!5
*%Y!T4 !ebi^LDaa?i&MEY:+:AGWBlS9dL#?>dbDP#Y8>uZI^$dLVZWSR&5:EV$PIVJ#T?KFR>/16ChcbQ@m5R\
655SG* 8&yHjL+aA$uQSJaPZauGLP6R?hXl9WCW15D/AD8L+wGIVd4=emyX6J#>G49SZ4WlQ<h\\998NbS>J\$#
yaX$iI BtF!44TKDq<V#^Snjw=XAic6V>65?PpDq/yBd54ti/mm6+YP^GIIu>iKEuT5B+uP8B^!8BTN9mMcqhIh
C&K*c^ %!H=GBP!1nGPbdKYK#CStm&a>ptTk?T:M!&F+6WD8K=#?a%4w94Za/@L\#+hFKiT<5PjydibIjGW9<cZ
PkQW/: /lIcmK==t<m/h!%KwT$pheDte\+!>M#Qt*p8<pI>d1AN6pYym?4>>5514NHqN1Q$8DAiSmE?cu:*mWNn
WXKbmY aR*iw<dn:w?<t\%<k$+H^hyZ1%5D%iP8=AyA4MyPG8&n\TMRNlV9PeQM!GTq*GSqMZ>RqMh^u#V6Y=15
e!B$hu #=YNACP>AHSk&:R!PSj*=pePtDPPZAKPe>WFBAebS$?BE\@bdtlXcJd$:na&!m=wtJ$YSe#:RFu6!E56
lcm<// XGHX@Jh4ycNGpWdLMyjIVDVKdi65hQ^CQdiPkWtDwi<pnA6VWMtRGSXhcCP&SKdql!?@qF&!w^%:D6<9
jNdwHb t>IJhhe4kk+?kGSyIM8#Kln5+%#Gw<M/TD6R+d/NdwDM8pP<lpVEk\TLk:+AdTItkS<S<yJFTW?%uMp<
?iN\=E i&:HCpW%*8y%AuG%yylcSCK&+>I:=NIXe*RNN@Jjm^B4G<hJK$i*I1T1ZICewHT@Wdbw>lS!Sk+W?\e5
dc9Xe$ ^bX9!cqcjbYjL=h5bFLmbCC>qAWJm&Wmb//&\>QNDC8/HWB1?HSL^RFupi+H<*$G9+d!I?tc\TSND8%$
GQ@8ne jV$+GCb$WYt?L!$Xmb@hLC$*R=EhNl&c*jAdp>F=6Z6kN:E/=>!FZP:/c1DN<tC/ai!>YFX&&Xitiw9Z
Qu>nM^ @AwD>aEP<6MeBeYZkn:c$IBIPu4EK>J=qH$h44nFtuB#&8ye8VBwwjIJEw/uqTXt:PGCKYWdqeDtG1me
VTeI<I y@Zi>L6y61jhmKTtC191c+NM%Ribi=lp6G8!hQ=QciNh5nqw#qDqQcM?<6F>elGb4nay@M!<IT!yJYl=
dKYCi: >K^/&EL\Bi5W>Hhq=hNXjjmy\k+G=TPn&/Q!/!Na9!M=?KQ!5GN+^GPdniQcCDqtLA\=*JM!Jh5bTLu%
AalY&C h?yMu#h#hQMnD\??*Xqttu*>nm+a?nq>?518R8>kqj<AB94dP<m+:N^ZIWc\I+9jR=^pS49Mh\Ja%VRA
>4ay#e iLyBHF59ZM4QML<wILleK98=mPm@6JSRK=kZMh<LG@DkEXID=hyXW58uX<Q8\Mt@h^p6BeIud^y/IAJK
>T^m6B 4i@WZJQTS1deT8C6aCCpqbyVcT<<WLId#BMNEWa#+PcAYGL5TtAi/VqYSHQXjXiR\<Z4k*&kEyNIHEN/
&jya\V MV^dIIF\9=wID8^*X\@:pwCN\SD>$wPQtj!IYLH!@JpcXZbtTNQPTpB4=$6Z$lDB:e?CpS#5%A/8eDVI
&=nNqQ DQHGVqTK\jIBeI\5+ZkK#wVYZ+tN4WJeYdiMLdQe+$wNTlue/D8tinQdARQD!uB$9VDc?K!l5:4>wn+#
yw$p#G F=u6a+q?S9nnQWRPp?I1djIBT4WKRa:GZQKY6iHeS<hcE>q!?QK=8G$kI@WdYFuX^w$cLwZIaIedESSi
IyyHn^ +!itAV1pWq^K9VB9y#HbpyFFp1=IDduycktm<c@d/KViYuTlTnLBPq+IBFKJ?C^jl^i!EtDEVPtJ:G%e
:?4l$i FVmAlLY988+m#:@#adc^!WWJccm+E*AHIthyp81>^MqQTKIDVubGJ#>X6tDtG!E?bwkTb\1#E#W/CD<$
F6?i6a EtaQMk?w6t!8M+qa1/M+bN+SEYFPKwyY6qdpBKaF&GmCCFLp4^K<LqlAkNtBKliS6+Ym6pV9KX<w?p99
>EljB5 W8RnkRV44Kwd4BZqCZ1TM@ePp&imm496wWE1dNltBANHQi:JTQ&y8BTNcECbd@YN%dB4D6pcVSduGm5<
H&Mu!= qMlt*h/P$Pq!=LwkFV<61!E=b%q8KY1E4cWEWiX#WRi=bkMl+RTZ1&>#6pKlX@BY%>JVi*4*EY6#lwFy
@PbHdS l1<KcJDunDPZ8umYE<YhCcPcKR1KbFNTViyKCBQ5G5R%P*W9AAP&<=pZ@mt9T$eTGe5*b4\%a:j$c#9b
BWZM!Y c9yR/hPt&F<p?Y8/B1*8EuLMX^aH5w1ZmY5G49q!FJwE%hld#BlqX@cewR?F9Q*&QHwPIweVLcTF%AHI
/4y9pD APSE:c5pN:=pRX?Z%&KmmaGmBAmk?<Gkn&FRnkyAK=BkW6=R?jC#GalRa:DZA>&mV>>k$^Lkh#Xln\jm
@M+kRI INDVXNDB6JuAq59LTJDDl\ywG8*El$wLnjqblWlLEdpq$GHVaCRT%DmTViZ#n*AJuCZIPecCWn6A#FQQ
j6=R%m 5ZJT%>u=?%9aNCBBn8&BW9yC5X<FTkw=%:pY#RA%1SPCRp4$:FwjZe?+Iq6=dddnqa=InYljT5Hj\IV!
9*6?wI %nVE*J!pE#AH^4W/IQXM^wh*iGJ4ujM^LJRt8JHaAFe5Pj*Keh*pydVbat><G6:H#T!mJmG+t*=qZ*\l
p=uPI9 #L>NX:PFWy<Ie5%Ehnl@:>4c&!*Gb9:%DWQ=F>u6bCXcL>J6pQFwS>l4L>X+++9YauGpj5#9L&CL?kai
YLN%<E =k?*!4KhbZAEIqMatkZ>:^V^SC$#b%^5HHw>qZ5ablAPEEmHJ5u=jjH=bQb:A?SK>QEqwjFq&YVbAwN=
jeAJ+p Q61VZ5+YX?XQ#%^ctiHdye?tYX8t6=6+YF8l5:<nKKZ1cDW>GEe:!Vc*V<^FKe6l?DV#R6u<c6DR*m4C
jJFkj# L1QFTNqT^y>^5<XIXCe9!<1Iy\BFCWR:Y+K\4=&5yX*\%S9lkqu^QD&#h+AL!Whh4/D/\8&MY9bC=jZd
:^kK/a nw^Nt<Sdqq9V+Tu#1PJ<58Qi+dpplGuQLI$htYh4$*55<^R%qtS&%/R&?VSc4PRlbiTnlEcR$p\*jJB9
CI:*>< ht9Fi:+6TEeCNcDGePweDDHSJcZ>+BlbtTAW&GD8Cjp\Z<Q&+>Ck8#cmi^yBj1GyiqWdHi1uI#=iTp=1
DGjFuZ QSFcA@Rw^hAu/NVj:!^q<JuCb@yAQX^iW8<R*mp/P91L:T6@<wj>9?9ua\Q?F^$A:D>^AIC+@#$@H?l*
I4<4:p Q^@wh#<jmQMj*H8ku#5K&H:m>YADQ6c>^\b/DQyZ#mI&>pik&Z>bN5hn$L@c5MHG?Sk$/!@ei&^en$D@
*V*9WQ cyMMK^9*a>C@CM:ECtJ=DQyZ4pWR/!QR9*cTkaCQ1Vc8Z&^WAV%G&WA5wF?k@:YLDRkC@dGF5aE+@>DC
?9PWLR &EAen*Y^5j&=ej%BuJ?:&ECkQ@lyPj=N=\&RC@V\?6qJRS^5D*?en@HikQ:watPY+YdmbtJqaiECM4Gb
>QAJ!1 Gi5dMRpaGbudtDLyM>pa8#I=P^w:MNuwY^5#&Vw\/S5bPSk:Pn:c%RWEp4K^e@@J%eZ=KB<kmQQ@yIDe
Q6b^m% *KR@*91QeFp@=H!MjF#@/Q=mA@=4>>j9Y=h?e*?^@<#>BjybDG+k/@?PGN!G>9>@8I<JYSkd8X*eDl9X
K&NJTn X!1lB*c@py>HBIFmDnFTZ+1E?!$D9mqml&Q#JpeHX9#>B&R&/SuaMu*?Fj+Sjem6iqRI/jpQXbQ!9i^A
I6NtN> dQ!6WGRq$QdLct#BPXHGtpy=ZGke:DEqcCm##lij#>\/iWat+?qaA1Bc%utulA^l<YWh*XdaaT9LTAlp
:A5^tR J+ejql>PPe?kGj*#+MVEB8J<h19cl\Lw+N<iG%wQK1/qudSJkd+<l=W&EnCeVwDecFVFlX#Tk=u5w1Pa
Qy1^XJ a=t<RB!15eLkHj@!#le$C&H<Xa^=$BmDh/Y!dF$ElkMKlT$A/n$=MiMZETdeL$4%BF4/^@Z$kaFRW!8I
!=cihq ph?=DJ$&#9N<A=k9hA&^GbWY$Rup<SbZ8DcV?kVRyK>iDCK9jBGq\qcdmN=BS?%EniQh8iLh>qKhj8Kd
-AclR/ 000f40936d600110333 Page 271 of binaries1.zip
kAnQ$d 1D+44eI8W=@DFIDw1*TLL<X^t8ERCEt&dhBiwnjElpJPw<Y8R!b5$!NE!D@L5YLZ<lS:SN>45qW>P?&k
SA\kKF ?Zl$qb<>I8e#!48PGyqQ&CJa5\Qw$mZLDcnMJcZn8PY%Lwa>cL!a5&\SqT95^CPYLWi6Ky=y4*\NmDNW
PtHk&8 uM=uk@t^Fb?QWNdD$B5HL*Xkt+$*PNk\B+@IVnM:hN1>a/aCh4bHjYBujB<ennw>j?=h8dDAWF<c>J&m
iJ#>:? HT?I/$pw+6TE<wk/ECh^EX8&1e#@\CHy8&WPDH*^aT<PucZMWbq?K\=@&4SBQc4$Eq5bhjM>%8A*hjQT
cHtIcR V4/%eV&T#k6=cX@QD?<RD#Yq=6\w=/FKy%G%+uqcnT1GbbnXRCG/qVTww:4RjJt:MA4K#<\Sb89=+Mm8
^#Nya! y?ddESHt>QDJJlHJmHdXB=XlZpIZ18Ni*ZtcP=?S55lHlm6&G^$EpFe:R+=IBTBbltdF$6TNBkw&8eEk
ww6:6A S@QC+qcPwyhRCJu*hYMWV6@:E*HKXHI%aqAyN!9VZ=wkmh!!hW>P/^ALS^<EElRtjTTa5:BRS<HtEXW:
lJP=Id Ib/$^GQ1#nNwB<:&DBw1ipNLGFcLK<CTGeu!GRZRWYaQ+Zi?>wTX?C1i1PKJyIq$b!JS&+Ru4@$>4GpC
J+:?LK 6t&TtIL5NqEk/$!4/kZ?W@cPBM^dXWdLKYRwl%u$tjqQ$n95dFZXi+V6ANqZ^9$auh&1TL1PGZHX>q1>
/ubl1\ T5?RB=ZntC^*PayeC$mZRy*hHQNh!ELhZ/IH6Cn*^Rl@#1Wn^6C5V@QJ<8n1D&TqakEta>He+RL$WNbm
SG59Py NLkhlY6kBLiT=*Iq^Xlu$aW=9&IpS%LJ!t+^CFSQ6mAVNiblBu:wbX>eY5i\eA?<e51?Pk>1V@*5nbH*
Tk*wL# SM#X=YpEkdQkF1bM+udnY6HyhV4:C+JT^J!uF6Ld#6dLjIwEt:LFE+%?&N%L*AYb&RI\8w:PLM<XRj#E
XRidC5 ?!<!?Ie5*Ke*yiVwQ/SIX^uj+&dQMY:YY9k^CiySmyR:SJA6JB5dX+6Rhk*54QW^j>cA#5we&E@\\Hde
=V>jdB uJ4t:Yp?wAEaw&+l6@FIuAlm%T+\Yi8mj5\lMu*ZnP%aMV=ZHD$EV^yS+%KC#VMTL9a1bbbX?uByhyK1
^/HQSJ >tlyI19i^atVX:Z=1c/Y1QhFJliejBeSqBSSup%$W?EE*e!cyWF!aHt9RkubE/nZbQ+Kb6mq!teP+dHh
wLTy+T #6*Vd1#lG%>&nGJDZZ*1KPbJ:YmmYb+D1:8:+dwca$<lyJG<LKDaFlElW&I!qcaHmuMHdqd*t4$qWj4=
bSXR@@ pnl!b*q/k$h^:uuRn\R%FW8:LFKI?e+kIJZMZKH^yVD>AutTN%5pXcSlL58:V#P@uHbA+!@yBdQDF4Ee
a^hB4P Cl14KyS9tGF@LAkEhTG1KP8ei\66MRb4ehBYDZVXil%EInAQA4y=<I/*J!^w\5WF68YM9qYE???pX8#b
ESK+HY !hIJ/:WLWul>qmkQdFNIHyR%@%n&=ZJLB#+bC6:=M>d:@S4MG@:5=?X!n8%>iFTGV96a4AJX*@t#%KJV
<SphA9 lZ!MQ$kGS8S4q9caE!$/<Xm@WZ=IANy^upAmnN>uGTAw@WR$@G/$n1H\dWE:9#aMk?l6X+e@/+BVQ#W?
\Dn*<F 4pp=I4*IRcR\W#YlYK8yw>+!%1ZbkcyaE@\ZG\4q>I118XJDD8Da=J/%?epT6!V$Lqu&aym/ImJju!6i
e?$p!R C@:k5@/^wD5=yLuYJ#t\mwYc#H/SqX$EEWt5IedcjbaV#%JwMh>1una>F<&n=iDR4H4PYDWY1qZVV:uN
<Ku@cn TQ9?T=Wau@k#Rn#%ekuu8lLyX<dD55$iemVNi%*VBdW?:*&dQZtm=K^MBZE?TPXDJkK?&Pn$Wpwu4!$/
/8kR>y qSpVdHju1*?L:GMVwe?LY!n&iuGHLapuNS$iQ1p$pF>/PulYIX<w815>j@j^y19SN$mZ4/$j\BHE<bti
Q:qTdl :nXK?Vj<RV6VGTVq%:uY#tnt<AbQ$D@W9pGCc5X6&&wQQ>$jt*EXhDP6/JFE8BI9MB1Qy&!e@icpqF!q
&:NwQ9 ZINZbF1kVbnFZEZdn#8a9\CF:8^+8eMJ/*=Tmm$%ill4R&uI=/VN>HF8Yc11=%4Q9EAA1nNWZCm%lpki
FCeEdL Tet!pELVmena8FRF?c/D8wDq:GRRyjj?G4L%tV\:ny&SyECYYB8&*JF/S>Mqk<iCNR=Gj*cAQjETWkaV
/CB#JZ !Y^na\QlhwHmFEyI5!XR5iI<ctQi#iSiGQAFEP#ElHARV*a>ES+RA<5nW$t%I#EM\T>9G=c9!I!jJSMK
m$m^R= YN9RK$kJ*8ACB#Pyd\Qh$CBjCcNY=*qcF1ML\4Iad$cb4JP/X1TNh+hFh9Y+R*@PK4peSCSnRIc>K<!p
H#QZq! *W$QR%C*lkT%b<jCIFS?la&h*Ip*NJ1Z#Y??wD*Z:TK6CRdMq4VDn$#Q$hEpS/&%bLjBhqm%m=hKT:cB
YFbX:W i!Y#WNVHlitti$@k\k@qbb+!Md1MlB#cH9Sw\BBPw&W&m=%#qeFP$Z5=wPA/qaq?D&cIynGawm=&:^Yj
C5WcPV lYbASSGCl>=EP?!#*d*CaJkEb&cGhP\lauBewbXYDq+Q&5Z#:dElYJJndQEwY?1!!tNG!laCERw4k$>R
#$At=? =XGkh&D9K*6enDj^&%b>K4Xhk88dWFMmyV!<pYyN8tm&k+?ST<<hnDAkK%@I<w<*S16P:Yj9dl4mFLm+
l@lcYW pubnmy\/bK<Vd8<TG=p$mDuWtJ+/6I*ZwM=dIZZhne=c?Y>bw^NK&*FNWt6HB*AJFLuDm>nC>nb?L/Da
::iE4N lLaVHKhK?*1yAMV9GXK9P&XC4kV/n:I>G?YGyI5IauEtl%!L!6jhC*wPe<wEnwucSG\u#y=:I4kKb^?J
L\HNtD AjtFMN?RtP/VuKtpN&!c/mnRJ=<Y+^kSmHd5RpYL5/5eB4YNpN&A5nZ/EbwlKm>M1FjRtGJNR@=/1Kj&
bC1*Pc E\6QK/BDAYc<q>wPGXld6MNRFN6*aRbbHSlYpuj19<u#1e@FAT*?qjClwEPZCTY!uMQ%I8Kqu$ttcu<l
NCF$\Z C+AjGqDAEN6ZtX%+JtHCLdSI%iF*66?VQJ^?6#X/*tcKKu+RqVeBmyXX#!YX*1ATl4FVQ%NpDS^9&BbE
Y$N%9d La%+/GJD\/tBdZbWa\d4n1Al6NWW>FYG9m*yI!!Gku!X$G@jk><#By/?H$nJFd^lKnuBQ@/$R!Z5V$%a
?ZX1kA R8&I&9&m&hnu5tjHGNZqhVH/6hk^Bac8bHa^>$k6:B+#G+bJGJ6jYDnb16mcju=yuKtb/ecBIiV1Cc#+
cTiEQ< ppt?@@C+ktmWjCeE>+Vwl9Z5Q5%u8Z#h%Z#bHkXhSpGqq\Bd#5A1#9/ER>SNFNHQ$uCbNN8=y<Wy6^6$
tacR/y Wbb5/JW9n6BkGa8PQ/LSjN9<=tdyXLy@cM6+tFI4Z&u$HV:Am$$RubV$y<a+>u<hD@#jn\Q?iGMd?$?5
SX:Z+i GH>kVZL<!k#BDu\Mt8MZ6l>&6pik&hq?aZhmB#$C#ed^C?5NP@5n$L?&*4B#QALP?a8R\/#5uQ<S?k<L
AQ1#lV dCDwZ!?\j/iW@4dA=94bAy9>J\65EA54!@@HL@$j+=h&@9j#T^uF5Vc?W5lXG5R<*^Y*mIN6:?AE5Flw
nld4hq y8DS:wZnRLH<mF4MYn%BA\Q5?BG\GENJF%mZFc:LA@w5d+LNn1IDSS5FlbTLP!wdHw?NCmY5nB8M9LP%
5e<1wy Na/b6LP5mM*X\TPTFYKGnWd861<+8h++#wETD>KRtkB6$HBE=Jl%c!BZKSh@b#$hZ+!kb1A:ntcBCLEy
dwkAB< !j>TcSIHK+E>B1E?!wCL@^I4j5Y!VDD*eBC?Yp6:ERa$#G!5A8WQHEYNRRb>EW#EEy>pW#DWimtT>W/Y
j>+V%N Vbl6e^XdqYEKVScEa9S6Xy\^Vp^yKT8CZS/WSIYBPTDDIBTkdWm1yFVd!Z8tNMYpDPLyXl+tCadBn=:#
+R*^Y> k1qP&uhu@>/wwLQbCE8B4qMd\I/%mZ<yD#TRGTahNY1Rtea&=h/b!P$WAE#E:Vb1QcjiuqH$L\y5PF=K
K#tDa1 aF<9aXPKnM$y:qjE$nMk4q4LDGpQR9laB>$&e6j1I<#?QIYwtTqPuLQjuEGnTBju=a*R>qTpVH#k<$=i
JPqhAA 5=Hti+^Y8^h9$D^5&/HeY$%>?a@TlE>qe^iD=QME+l*L*FbpVnk4Bb#6%bjQ!C^t^JmF8uXRC=R8mN4+
tL/Cuw 6+NaC6k1Z8G+:DjdZTILh\qX=l>m1#&SeZa+Ii1%SISyl&Jh:wX/9#Cm6myjmGMhdjnMPkmm/!9eKMNY
ww1H@V Ye5dN<BEqk:!h:Ve$ZXyPjq/An+EHF954YNmGeJk!/FJWG59PyLP^K=IyAbCHTj1jZ#eybnMq=8G#e@=
pkD64b MuEkENyXLn&FW!=P<dMAqteSWFTIuVwaPYbS?ckCQem=1GS^l1LtmJD\ZHaS1/awcGP+5H*ecM?E+V#E
G^lDc@ cPQI<AwhptkEVH5qDwSCJM*\5wPDi+!ZBM+@SiHE\^4Kw8@Ye:beE9uNcMwMj&54VAwpDXBXaqGb=$p!
dN#Wuw ?b4mlA+NMW<GGRJ4&cqu+^>NCCPRd+%DhJYmH$QI\Bjpij98?W9p6!&duCF?h4ua/1?S?pdFk+ukeRTK
qi?XmY hH6yQk5nIEBt?L8B^J8i<eK?kY+ZRkhl54dABuuc/GXZw+\KFJVR?BQu/NEaS?C1<G@KQcHwpkX6SWH*
:&JR6a >>^@%:*=Ip5:%QQT/dkJc\NHhb6ty5/piX^ZCWhEc5%K\kFW@M\nYSZ=K1nRqSqmQFXSVEq+p!\yi1Sh
@Ed<TV <5Z:\m4Bjq#:F>5<cbJ&\#XXSmAdya$q4+plV5KyIWTqL!PKtDB9^QTY?FPSyNL%jBNa8=+n1D\uVJeW
?@cX$6 JK\t=H/T?B\tbhmA4GFLNyC5KnNFq9&qR1a<WyS!1CThwQ4a6/=*?bKRA6dNJ1TXSw9S4$96!&e=k<WT
ajN5k< h6B#WHS:5k=k<elYQ+jqK8$EZ4h\JaXDtipZ+\l5j8VBL?4$8IY%FlW9BwW<kWISB\HSeWHd\awqVtkG
cLNiI= 1:=j8N^M\DyTRWca/F*K4uEW/adD6nkCpW#BmVyn^p1&W<pnEul8S$pj&yJPQNKGbu4^6T^MdW\&^e5h
kWJyWN p#WKhwiD5wKWe4<jYl/eH:@GYpyJ:eZ8XP9$<WBkdAFSZJa1>#qZX6CK=V&Z5M/N>WRyjcJVjtQ/SF8V
dJ?kA$ $JStiEjVBj&\*PHYQG8TC\:tNY855w$19>?m8NI4uCmDJ+F&:R/$PMVhR4TqH+yXJwQR8\l56HCXPB!e
B9EWa+ lpLc&dSpiAZm8Ac=VGC6P*MYdH1YyEdwCKM*u+u1nM*69Lk?eV5GF4TnankV\4dpc^&A:h5upPyA4HDT
P4!:lE c<j!P?u+NhN=h1Mu/T=BwSmeybSW=aM$RSbG/HA9/E^%aL/A+MR@K<G9V5bG1Dq<J+!n\QZ<cn<&%6q\
Xl\!^Q nVw/VpqBpa:EunVJa^SkH/R5?K#@&WB1hDk>jtt#p$ajn&uldNI!>t8*5KFDj4L<P#+WD!G:XS>YPFXH
R6di8c X9uVW*c4p^d/G8+WNWwTw*eK<Z=\S*4dWaH/%dXn1X>^\&uP*FV$k^<Ghj:Be$8uh!cLa!#5BtbR\/WJ
p\wD!Z >FpddIXwwJ*4i9eWLD:k8<<V!yD$w*D\w?bZdCm$4#8l+d8#>q#ARw+Bkc+KLtt9QF!>ZyFuDRXyMTm4
!V1:*$ SRhHtYem/:hmE\\GIhpSbA:mj?:caH98W*!dLK\iB&5w@j\65SBMdcRWH19JdYQ1lVSdMy8bu+@tu5L+
L=L!$8 W=R9A^*n=Lbl1b<=F?a$^G\%>d=L/1eW6I%^%Ve:Gew@*@D<\IA6uJ>HaAI!>YP<?6dM*bJ9XI5i?Bp1
>A/H$+ pp8h8!eu9m*5bMqH4HVBkR4pFYaZP<$h*kDyC&$4GMPnLnB#\4@TDbM$TlkwMnDItw*<Il+%Z/HRR:>C
-AZSR9 000259e466c00110333 Page 272 of binaries1.zip
M%YDhw Tu>AL5%D5<?tiNNDy!/tG1hXt*PPFB<FJZVSR4i>4<Fw9AGB:nC\F9e#5TFE\KB%YG1aZLF+dywjul=l
ZA1Zdt IG1^m:u8nt=m:qd<&9eq%RI:w%!WiMTaM%AB#@ZG+W#6l@a$t!/m>$9$w=b4McM&^%t*V<nV#wQkDJ8&
eIk?be q&ymTqLjLN8MJNeJM5kGGCC?9:LP#>9MjWJ!wd@qMVyDY*E*PJ9u:5L<@TY=Cj\Sh4H=KhwyGuIb$D4u
*yIGjZ P%dH&\wwdqMKy=V4eS!l*NyL$+k6G%65ipW*a>F9w\Y4LhZlbZe5Za/4et5t*4b$&Zk+=!<Zk6k!Pn!M
GyXalI <>HqAnu8SS&Ke+X9l1y>tjQB\udKd=FL/YmETl#&=MCR6yj6E4Q^$enLS?aRW4M*?<6*5A!KMLI*1KPD
dlm/YZ \^HYbhE%KQFcZW>:cSXXbYlELMbFLCLcIw*EKcKDmmbFVMWAkYk\w^+mpT&4pBSX\1DqRm8P#W6d>IRq
iim=j! !n/l:9pS8^Sw^P48CMHS!FWH&%6Z&>9FCJ/&R6!XDRyF/VS^J8l&9a&YQTIE&N^F\DLKeY^5bR?11S8:
$dm>XN *w=nEccFjCwc>QY!@H6EF5uL<1eFpdGFCPpqM9CXbWG^hJP8S*wXewY8C1V8il%XeF#mwYmRKJ$aMw88
AP:p#< MMT9LiYhTkpAmF5YC5?\?djIJD9mB>KNJJ\EyYhFGPV9KPHhVIHF!D5imFHI>BT&\9jPXJ=X?+B1ju=p
c++e9d W>^PDG&pMC>a1T=#XIhw^F8Zd1aK$<yCBRF$lqaa=A=YH#N41t*W\p1&/E<mJy=mFGyIFBwIyeJ8+ji>
$%NPaR Xy=BthHSKH&wZ@im\wXk8%=$GKq*Xw$8?>55qa&cwu^ECTZ4&eahS4dmPITDFbQZ1&yH/yh&QHb46%6=
S@>Knu XuHhq/PKcq$wa4&Qn9L^mXYqR!kY@QCu+=FRI1b%Ik8Z6cn!wQKD5^Faqc?CZuDT/bbBnSKFwKLt6KLS
>DHuST />D44SLT@LdbQEQb=c?X&:&Xl!P1<=9pmLEPl?QJXIWM:+@/+k8mLCSj9Ecla1NDuTp@GF>hSApqLXkZ
$^yVdX QG!ducS694RX=<:qyRP?b9\My1=RNS&keCkLli:6$KJAd$YqmRw:66n<QJJQb!JK1HPcBELNwK%ASpVA
8J/n@S u!pT%XpQM=HL6?np=*#d5Y>mFBwhbjaX8h%E:^I#Yu@D#?RI&RKG^8\4dE<IubDIFjWbE5^tL!mMmPY\
ZW6B8@ WWk1KMDYT66SN+wln+F@&qmWtSGVFtipkIWG>Z^a&5ipuhNRl8JaDn%cBd&V+XZI6MFiT%Fw>R%h4HmM
6#NI!L =8SEFhp8HGY9anGGlh&cckX%ML/$b&pawb^$\Gk5ud8XJdaW6DteKXaB^TC>Gpy8mJMSP@+PV%By=5kJ
H\lhpi m+W!\G&C!YYMFm5twG@9*q%9!+GXt>@^:Quity%TKL+C5X^MASG/HCZX5t#+yS=tCQJy^CX66Wq%InW\
?GD@?E :RR#m=4KLdL5NX&^Q6$8GTJt@De$p<M>$hCwmK\Km$YkkT1K+LH6m??lRh1&\HSnNVEHZYH/u6R6:K4J
EKWSkN hCXE>ZXLMj1I/m#dwI6<y4Q?bwh^9Y!HI*TJFPu>e\$dYuLl$Je%l+:WHK?FR/yFA?RQNQnFkyblW+Yp
:dYp$n !L+ljpTM$S#iBZ\WC<dElB+NJm9i5uNk&?e%Wphk\C$HdM95W&JmeLZL!GCLmK8bCdw154?51ul=%t!M
1P:Gua #XAqIpJ+*PmNIaIjQ$kJp>9Kd^Jl>JR#!MD?5\1dLiS+9tL#wAD#B5$5w*C5At=Y/iZ&MAHiH8:W+dG4
*$M@ic T9!WFFj4H8/IM1R6mlZ*Jtw:ZJTEk$ZAP&e5mlitdWQ&%1Zy%1lS\\BwiMC+KLN&/YFuQ$<$m6t5KQyu
D>&>Hy SmeL1SYN4W4q%d%SyQF^twQ!GG*&Ylb=b#lhSlL8#>5\FL5\J68wy#K/jiwe&\#6NwCX?K\u%I1LEa&%
wH^paV 5i#IY\yQuDaPbPDN=M\YWjaY@NWZEehkS55RS65ejRVRlumY!$cZ!6Q6*yG?S5?9F:%h^Ik9YKNAbpkc
EQ/cn5 GN:H4K$n^5mRHN:nLmS$wi$cValS1iXV&i+:nFbQ*uSI6%\&qNTm@haI4uHW84kh6bd?+G?4ZXe:TIpK
Fn$HB< W#jjjNme:bA5\ml@Kc64P%WcZ>I9aTc8w9hFR&Xk11:L^MnQ4b9N=l8EEm&ENae*RWmFVnG6hy&Vdn!P
Yb4LZM *4/S#68DGTb$GwCSkEGLy8!!X1!!Fp!#nX=/$wVt#L18F^TZ%\HDeK?h&ZwKY<TGyGEkR6lY#lADi/L&
SXmH:u cIP4C!Pp5JC\FT+=j%B=cIRbet=CuyJ<>w+#yMSl&Hh%pRDuF@*dL8Yi@4aM:H9aK?LC8alWR#QNC89<
$c<*%I H?P#:?nAutLw:JbI#mbSah*4Bk4wIIR4NHJ^W=cN?QDT!/lJ1<@#%4LdMllIqGHL=T:EXeXEekE$%e4*
KVB?48 ZZ6k*A9$ZikRS!:eYFaSwZy>=h/eF:A5^ll9?JA\Zm1w>mSlaJ5#^dB!C&Ijadp!C>WC@A>kR^!mJGBV
1>&wQX HPlYWde8S*%pucjp8<+BdS^JR6KN1GiH!m+a/H1&V1SGY1!6ZCbmTHw>Du66Vmey*HuA%b&Y==C@Mn>^
^dVcS$ @N<%Q*H<F\?ca?Z?TW\H:u<#ykQZ:%\946?=Zq#@!QZm?nuZm?Muhm<P%5hc#VnaHwQ?qhYMA@RaNPkZ
>J!!wP hm<P>9<I#jEI>I@a5n>He#+G#j/4=?b/DJ46X&n8^/B@^XLnbHpEtw*qX&nYS/CBZL?we<:H/BwR>K8!
#wW>RV &j+n>GN$nbZ#F^bc#5jw&1>64J!QWndRL#l8uI>TN8C9$I>SNmD4L^w+=&PW:bj&Zc=HKS94L!Vua9&Q
MZhyMP $I>SNuc8Z/Hb@mM$/D>=a%#59/DFAdqbRS^M\N>weWJt^wcYj!LGYS1:P#KbQH\*h4B#MLh^iuVWD9cH
6:D=ih <iTlpu?L&5HN>llGHBjH@^uS8LqJ&S@/PTCI=VeJH!Qb#&N+@FN>iYR%QR#RwIh&AGIDpaK+H!jMH@\c
mjt/J= HQ@/IMc@eAX@?DYA4D<LkQ/*^$Q?Yjnj#<u>1@T@<h%JtYZ%4Z?:+CBqXnM*enInbiWGpnKLG=8dtn%M
hJ!cS% SS//+wiuMHh!qDh&ELK%64P%?VFD+TJ>tISa&Vww&ipdQwCFnX*MDa*FHQVh@?JF+jmluZ@^wkkLKj@E
=FXt!i m\KiBS<CWAWibDaGGQpAHn:kBaARAB:&^?jlQ#\!QB\<MmwmQD\mKnwKCmwKCnwG<5N@XGRMNE\5dC^M
tHR+D5 NH^<RpJ<jHI!MnJ!/4><\G$AJHlAKcANAwIMAP+CnD>pDAj^+\Q+<\ecBkwTFkIAB+?AmIRPkITAkwKE
L>AkCI lwTFk*4+B?pIARtFAR&AiadJK1AAm/XQb8?LDa#Jk5PyEmS9X^#:\wb4eE#l+HhCKRSTm5&8NuV5aBit
>Mnl=@ n58y+eBVNuL1HF?Dy@JHRMRuCIkZEe&6Xb%RwTE<ZV@4t6\+N*aPjJhZ%#&%iYHmEyTRZ><#9jYNW$#N
AtaFC+ %DW+5cClh&d:P=i+8yqdTFJla>@5#mW66+TG8Z6weqFV@>#8FS&QyKcFS%lKejQA@N+%iApADWAG#\Qk
Cte&yS j#\TH!B=!W!V6DpNlYMWkq#iA\MMaAWD1DH8+LK>y?yu:wZF\ADR%9>DX>9k$aS:@#G?9RXLMICMHA^I
#$wyi$ ejV/j@HTD4W8i?hp=>w@Q<P19H+CYN&JV^w!/\i9DS:dWjM?WkaDVtLAkDW^Myhq^hPLIRu!YWH<ZkRK
ye5nQJ 5cidYXGml9&!t$qjlHc>hB9eSbanjMph<e&k&VA:a!:nlX6iaqM:ct8h9+4uNR$\D*numMe5my:Zii$y
=<KQbi lA=:=/XP^w5$kC\9aa4>ampHX1RBKkYG$l$k+5W$G<EnF&@cFDaHtlmRD$:&i+1$q^uD#jq$hRJ=y6>L
b>n6Kc l<K@wKh&S>48/D66Y<K<cEc8i**Qe*lMDM1!jm@EalqpWAYkLq?1^6Cp88bnud&::bM&WWE@bdY5b!Y!
MQbPjR @K5pw^:Mh%yq4S8T*6Lk<S?9^*69!j1lIyT8>X>+b?Pc^b/J%9uSS\uPK!6H>@i?mb6RyK<EHCq!HHQ1
mL\I!C aIpc1@JaN<hC$BqE=e!PamSiw+tAATZPDdile48l<:Q1<@9j?1&65YpbY:JFIuGEFNXjnm1$ct9KIIqk
$+b>I$ 5lA/%>F=L>G8*=jDjBw@L>F!BGt1qI:$a^nTlCwiaIk^wT\F+aYC+Lip6IdJ+JpRXGK+BAj!=8RJ$!p1
%cQna% innZyR5cV^j6^B!eAqkq*jJIA^4ttLwKZ@nI=?iG/beT!kdd+:<D:h9qXtaF<h\!KH@:%ndj<#c*P*hF
^Q\DFS Cmi!YV^c9G<jE^JiWRActcne8^hLER^I$kADNlbM\SN@>+IS4TP:YH4TA:+E&NNZFEAB^4ymCDtu^*NY
Q!bAnc n*5wpAkeGE%jDG9we4&*%H&F?HEZ1cq<>pL&SiP<^IuDlnR/yqCXC&#Di!SYWFj/FGF<ZjyLBuX<Sc=I
hnpXMt heBC6?hHM%d%$c:F<Yqh=\y!bI1bENu<<+#1VIQqn:$*Y:bZYHB*CX@ec=yVhY5tI&!1BKBQJI*WJ>!S
MP9>Z= 6dqC6yI!Km$uWK6Q#CJMcMqh+hYLwQ$<%Dw?ei9G<^%hkAG?*qeFjPDJud>e:94K95*H*Sw1FcAW<klk
wA!*V$ JqW?lnPGT^V\C&D^Ad^*YdDd9wla@t6cqAaW*ipVHX*<6XlPWuRBe#L:K1l1a5K^n1Hl@jKNnGw\aAI#
8\dJai bZ#cdWl^KE<G6d$h?mt@Z!c/AA/$wYJHN%/I&?hFCYMZA@4BNSQw>>>ZmK$PbtNHMBkEDA\6aq6NY6F5
V:a+P> =8#uF+VV!JNXBClRtTjV^SyC&?d#pywudBt#pkp%>GQIwXqkp5YJV61c6&@6&bt9AnQ8bi1>\XN@>%w\
yENGX% B+bVtVqW4XyK=<DV/ecdJ5PJ1jRe811AGd:%$CL9IRa\+NT/Bn##>/DlXA+4w%JXc8QbRAwTP%aNMRIh
#MM>Z$ 6W\DPNqiw6c*1*#=%4jiEKuiJG*i$k8Z>%DZy8DS>KQ%T:VhH@hMXu1QTTa+:9q<:yQ/NSKw>e\Ea%Hk
j51tCB =F?1%:al=ALpaWuSCkkiey>>>R@cNQbH5dE!dyL=Jt&u\pj8#nQ&G@d:+N/*4JT+i!5HjY+VNwlhM4bX
XtkDEh RHw159Tc=cCJmCVb!@Bi!@aKh?XM>^uuquiK\R8@BbByB%WlGBC<k5&Z:GY1nqSbj!HGyHDN+HaC??=q
5\JApG H8eIiD!+aK5%?e%L/j1/@XwbMIB>>TE=/EW*GT#pk9hqYi6YT?8X^minw5L/kwMMtajLiHiTab/XJF61
%#Z\Jp GRGD/%J:ZDSMuJeFqACd*t<T@dXk\GL@jaqZ1c:*WT+awNG1!@cVty:+%<@=YiR1B\^+5t>:FTB*>b^J
6:EM@* EAbR%LWXk!FnQ8F^Z9AJI8FpR\nh>j#/tQyL^bu>4nb+<55=::FK9PPRt&DE%ke/Q%ty&lGGjn1KFH<:
kXG&W& *hH<DVCkhGZmwXe5M/^L#ktFN16C^@a8dcL=WinW:+X!:9eat\\P6BH?M%Z/wSY!*whGaIBC1!w#*@h^
iG@Q+/ :@KXC8/XDM<G=%ILqmZNwdC^lXK9%EuX1K?/k1*DcYj!+<#ue+yElbi%4W5yjkWi#9kT*pVJ<#S:@RS4
/5Ft41 cKH=B*cD+8PK8>K^WdSQD*w#S<DVY+uV*#BL*8kk\kA\SinEkkm9XFWSL9CRFE+w\nnJ&#a?#!?u^5lB
eaak%j BM@D=!&AAV%5aACt>56@jBCVB#u^>nNP8mbd6*C>4#nt@qG:j%duHa!9:udqL8D&8jHQGPQ^NLXnbXR5
JbGk4D dXiEP\8N9=:!utJb=wyR/Pdt4L@b@bywqSJA>!&llW5qE6@i+IYMiRb+hI8Ne4G>N*je^@W<EJ5p=eB8
-A$y^! 000f54688f500110333 Page 273 of binaries1.zip
E/VmwN Scnl6eS1W\R8<Ti8TX^TppDjQQQ*/AAAXD:?Vudm&!MCMCCW/euI*XDGZ5Ni>@d>6h^F/5W/5Mb+W\@F
Zme<ha <b+4JjG&a\RMwF4ki$#D?K9\BDPD9GpJA+98Pdnjn@EqCpSnNZ8y=ju#hTbE!HDeJpIK6*X/G^@$u9^/
C:\\L? \>Jt9<+6=WqS=WuH<#i/!<8HVHTTSWnQZ1F81Ft>N#<DXXd1%%y*c=YJRN#TT@PPiT<ZkAESy9eWne=<
@waI&l *+Hi^T5qiBp*8*#V6nMSA<PJ:*#aS!:ZLF/hIjHhyq4>w=L@XHHk/:!@=@FNpyS8GP4Kp$YJw8#GK4\Z
jeC8<n %?Z6^FwkJ&V5uec$XF>bnT\5S>*A>HA#?XDd?CILnRwMYM1%!JPSe@FKBp?G#i&15ZRJn#@NML4X<w^$
d8SWE* qMq4C%SZKKTBi8*=RZ@pZd+l!qIJ=#Qp4PmuA&5j*uC#@QWbYQb?p$dq#>KW4qV<6E?c?ui1u9D5Bi!&
\j4NCh aA5@y\kt&neK%q8&=NpqCZNk4ZCiy\eJS6\He%/#YIEdIV:\NPIamdTEQF!kZju8t8nqLIS$K:*WukZu
5ER<<5 X>^nHIW?y+*e6?6^\*l*i>/ZQh=4R1kF>%6!F%wZBthk\B91/?H4p&TN/6NK&Ca\kFlG/q:jFA!I5<:+
WA:@X# 6%TeT+6BC1RwSFw5uwj9FwV>Yc=w%*G*RXF#kH/*#6BDH9nNCqk%R#m@1FZ6%%@N:yL9DS:%Yhq4aC8E
bc5VwM NBVTLE+u9>AZXumqQWRiySw*BXL@@n^>d5L#a>+Vcnu%y?pqV^W^%tQj@L9mn#%GaT:5bD15d/A8$ynZ
^&lkmI QFH^>8dbQ=ZBS?pyC6<j1yCkj@6PkJ9aN/QjJAb<PpWclk\iD&iPbYj!%FlH8G%4PMj*#4t!tSG*%ZI9
SLFDJn h+XWyMEt&TV/Mp#W>mW1DL:b+?**l^eim5#>4*8TS@ViZciuNcdk!S>nda@eI>4*V=TM^1i6cBFDEHkq
>n49AK :5wtBRcR9:1*GNdkY*taWjVNQM!=c%Vq9l?$u4KDAX8qW*F*N<!*ph=ZJi\Q6iW%?KjWD%%y?9T@T9T*
BcAL:E YXc@=aDSqIB@nt:$a&pEp!BlwJ+T%<Sh@SN=@%:V!LiHEt:ulL%NkDeJi#\#aT#\6IJVbc>N9FqF5KlL
eNI1Ie IITn5$5TNS&e6kZjSM&TMYyNXd@?Rln!#8<be=&WHYY@R461Vk!=>dhM/MCMIeuw9nHSTDLalWpW%e#%
p9FRQm *WAT@JYa*iMnQ>l!Vc+6bSn*h$uQ6unb=ajy?8A9qcI*1%b5QRX8i$wk$4V\EJFa^GDDd:KEKm@dp&B%
!yA*$F F>atLAYSXp1PNemMI*PM>Q88jWiaup>=wZ=c:#WTT%4VQ^b?Kp6QLlyLn!P1bn>wuRRjwn>:8j:qDKh&
pCk5+c lLyNld#liyB\eyT5d/q^%GFhX$hkAehjR!K4JZWC8$a$P5B8C6EIi+hG4pDlRGC\cTyqKk>VpJbIHkAG
wK*\mw aIlEdyt8>&TaAQHijP=JBw??E!46JCN+!lpJPjT%!kAcB8e6D5/#n:KT4<9RQJ*V1&DP^\RRYW^Dlldd
qK1G!l NbudJbW>XdaZXyAhj/mh%X^q1#aaEEYXB\c\%IAB@jWn@>BI!K55c+:J6J\bmkq!6%SbyMN^KCljRpI=
E5K<1n <Jy>?D=APPp1R<Td*a<wmVYFMpVlJ%hTw^R5W5Vi&:8FdyX\cGtIac/JE@JS5\SJd5:XNnlWaZV#QkNT
:B1W9E <C%ei^?Np$Gd!1ZCVkaT^AuPeWEWk:MLqu4ulRQlBWadbVG*Vb5C@A8+?TJ6&H8V:BjS<\R1G6kayFuI
c:X6ae Edeq9h%8Qn#9K%&!C89CjCuEX#/+c=a4jp1@Nd#WmntT:aV!Tq5HVw</SBinE*&9QS>1V*bD<%EPP#%b
Nhnic* aN4Zn8I?6Ay54cBAhP<y//9CREk&:&**YeHV&6j/!DDwVm^buj88IYc!BN1GmE$i=:u6lH%kwtaESpL5
WXX$hR G$cN%Qmw^bANR=*G$yme>$tuq!K\&%dk<Ym9BNHth<9D=LF+q9w9!tGW+yRh+CebDKCyQTLijMw!KI^h
^B/uFY tAeMGlMji$mKu&>5*TiChPu9yq<Pcp5XcXCFcAtVcRlZpGb6lJ!V?YXaGumMd1X1^D:@pC4?NTATRkZd
Y<K6N4 AaHlGd6?&\uJy>pnZY4$lnM!HjG1V5TMbR>F4&MHXXS!i9:<5qa//<1Z?C>HFDlh*449^I9ID!C\W@8+
Y9=^Ha EBWY+L/Rc?RmjPMplmtD<$GepE?i*CFKqL1+K?KhF/>Yt&&mc>th4p5aDc>hXcmAYk:/\FhhTnN$8/YT
*DNA4k PqEPS6jW4ty?e5^4QhdwN$YW/9!clS6whCWwWeS@cKq@*%uBi$6>#q>Ku^T*\SWNH&jwXlEV8*VbYBRL
=@H\!A Zkyb5Eme\iNw6=/H%?t#:&=5d8D=hDLqX9%hj?aVjLlC!y161Jbk4Xk5N%eNVI!H1D5ySF6S&+tq/!%n
kLRHbI =^#dm\B/aCmNm?AGtt#PY*LN1DuLmmXRbRiDhk$MeDVDQ:WcNhMbchDK5/Gtt!49TX/$BPN14Qmt5t*p
FB$$K= yEPpm%^+nIEbjYTmS81+4i/R^\5KIB5e#X/yY5nV=B5Ld5TwyIqT:VC5@ARXIeacGkN8PJd9@Hm4G$6i
N*mw/D I!P+eWwJqEG4/1\Jd9$YWH&eiMcmhAWqyCT!FP^P#YGYSRj9MwQtDnGT5FTRmF8<KA1/Nc&Z:KM6DKIZ
qZ&AFX 6Ha#hlw\<jNYc!PW5%uyXC^ipy<nk!hnl56$SB^BbD$T8GT4\PDFANeI6emZL<p@VZZy6iCy%S9w$Ky5
E:/W&* Cu:/pCh6EcVVbE?KF1#@c4/u6$VmlY4ME^aJY$/eT\HY:E1Fu1n\Wi+hYtqQ#cZ&TNP*51b598RMKl59
NLYJcT MW/+/TA&@L>e/YhMI&6/J9ckS%ZXD8MJ>T6Z1aL&hT>Vq\h5$teZ#mJwV$yRIjc@8b%RHP@QIK%Phqhi
*?B+=G j<##i$dG@WSjVXkqdqL^kJj>ByaFlXX8@D9>unmD%$6ij\e>&8:>Np?+tD^b&1eq#5#VARtw4YwSA#/V
i4kS1% y<cARCI%4\Y>4!?*yAcFG^QIpdk6ulYCXPqR<KFPILT^@u:m>9iDEYT*4T&EI:REl1McVba:CY:tC5=\
#BFbhj K9%Hl>QG5DmbEcZ%XHaah!WQ^a?:KZ:^?e5E:\S>mtuk?DpIHpcj4REX^C^qBj=MKD*AAS6hwH\^X@EB
HyKB<a aBd\HNqwXMmiIG!NQaF6mpJ?\C6wMI\tW\Cdy11u%SkhSpFJ^/jZunleca$W<9YwE$tW:5</\ltt5!hL
kA6KD$ E^dLB1$9DV=W%a<jWRX6jidEKe%QTQeyM^5iVFw#\$=jJ?lij8&Yheb:e&iDq#+qetCcIuwhaGJ5@+Vw
4cQZnj dmQ+8?Hc=Ye\ABZZ4P11SC%e1FHG+$S@pyn^1%GMY<H$jiEdYpS<j*9TRNemZwlbk!yhn^4K:K8Pw*$W
kmL?Al C9pQh<beFBEJuwYId^Ypc&Sd*lXt</R*1qZ5N>VnFq@dJ66TN%&wELI=XK8+5TccVWqi&$A1*:ZYjnB!
P/^6@n 9VZic4%8$jH8t^/?B=/>86Nqc6&\NAEDCN\4:m9\Zy&!%*lH6D\M^&4lFXiEe/$>8ybkREu*#G&p%ew/
Y*=45Q <<NIQ4Y&j!>cd*8TtAIG:J$+Q\#nYu#k$aeF*1>?=d\eHQc?eG5GA&LKW9>:Tyi<>T?$%DYbKm?6a:T=
iw#WQ/ =!K6jS$>PmVpIEEte\W:H?WkaY:J@9W?E8XVc^H:y/!Lp?h9nAmJ^Pet@P*!EInij?8+W#p1P#B<#++m
#dTQ9? FVHBY#4>Qi=Mk>#T*ImybLhZ&cAX!jXJ5DS+nGCL=PylGq:ADAdI&h*S:*QP6C/DAWiYJ>:P^>=6Z$^9
k+@?1^ jhBP?R/NW?@=+c=I9kPH\RBT1N8*N<pQD^MNeT>&N%Vn*je\HJQjd&t$dkC<H*VbpYHqFMDZB\a$Jhli
&DbkD$ AWk&9BeHPZ?Xm!q+ZPm@NihPZ1S:Fd\b4X8&m+wKD>QEubZ^?+a<qe%ZJdjcqyLjhwM=TXbZ!8j8LM>u
Ih4?nA bp1wJ*uqJyd4*L!?n&/i9Hqd%>8kndCFh8!/5@9!+:Zc%BjtTY>^4/V#?/1h@6:ktXdupdh$cu#k8b?T
jiQqBG PLl@Elte:ej=A@<4RmQE@G<JnjCbkm:VIL1Y5hGKMLjCCXDwK>uS%61c1jR6qb?iSy/$Au&uH!<*i9R#
W$d+dX Pk!>6uJ:WGXyS#$1l8ApRTCW&\=uycMSFV:VwLk>c=tA<ATVnD>^P!5CY+k<GR\dnRBuAFVjMp@=F/5n
*:\>>u 9nJ@:d+iPjJB85F<A^cL%JbI!JhXhCGhD4=Bl&pSBLqb5aLZpuLX^h6<6wRj1X4%t*9yphl<nHqaB5>*
ZSFSqR $JEhpXHdP/Z^dSHdT$1jQb<F&eq#\DDRa?MHTWY$6VL/\\8AA6qcquSpa>KCiZIWXJ1i##$VTSYL!ppc
Q+L\!p ?LBa**!QLe@Bm!CEinw<#mPC@aclV16h^kXdIdbQRFC6ZYTeDZpY=!&VhEt$5YFk64B\+#^TPSAdycbY
YZ?SL1 ^VkR\p*y6Z\Yj#:65uLaew>tdjW1u8LJyT+h>SGl$%9a4G4wXyn&:KmVpLD+:M!BVHq=Ju1BcEW/FPqB
d\CSai n5?6nFBYW@Xj>\9^6%G^6AM+pFj==?4L$K$IaN6hHCa=??cuTw9LLEQYXaw#e<u4u\HmW!MqwiK4WHeI
h*w4Xu @ckCIGidM!MmI/Y1YBiA*qRTPG^1ZWFFq:MBmDd:4hLVe>YMeqNVtF$huHKPwtYB:WtYK9%l&Z+nJjTL
RkPiQu &VYIy&%c\DAqqGJ1QcqA!F+aTL8wJ*4KZwdTE=/n&IRFYb>G1PpFtl9y#IC^djk1#lqJhhQH^PZ6/^41
Y4EEkZ P:Y#J<KDZLAe9B+E51?\/WW<<Tq>\#9&nb+JwR+>KaH6^S9/IHVZKn>RQ/EE=Su?=Ml9Km1NFAmEwc%!
!W8!lp w?yhT<>R%NaIDiTABMSmEEkc/qtCi55LcXJjYV=lFPZualBY:Z@XER?EyYuPl@bWYiduhyey*E%chelj
@<BySb >4*&5FWGa&>Zc!V&i?uAw9D\1+$mamp@<Z@&GX4aVdn4m#KepN+\MaNJqP/<+lS#FVE/LeWM6wAk&N6+
KP$w\q 1J=qjFKd#AwbGt*/tTlkI^E4%$T:1kMNd#M1eBdjKTwt#/CDSS+JuY%jZ8FE%^<HlRDJ\mI56F+\Z!X#
IM$K\* juTQW4D1C+@+6$yEM5SmPYSWX11?BllXK@qRKkHmV?y:1YVulq1a%n#QGutCE%+\KRFw/CALQe/Y1&/C
TKj<>C +iF4BLy&IbH<u$nL9?PB^TGCi*WL\\TjSR\J@TIy&1IZ?W\aY#4*PBW*wAy=RkGidH#&\&!nuT=M6R%9
SPIQIY j*GTW6Md+>$kwaHKjIJZN=$&XG:dGQqD1KlXk5HM+9m<QpXMmy=<aWib>HkWA!*IR9W\!KBGYk9MP9I>
jPXXnT A$G:imyy5u&BLEl*Rc^u5aubq@X#6EH1Z$LjqTGT?y9=De5QTIbZ1*eqt^&DZGqV<H^!RE9T8^um8XcE
dCLVY> @w15PESCc6dB%tW??e%YpVtKIPtNCG#XW65FLSNLta>buFR:M/qNpLdWT=<+X@qZmdEC:D=#:jpdPyp9
y1G?K$ GmAYPTe6?eFSRcaXIn:9wll8&8dbjkJke8KjJCyPXFA^#iX>/ZDCMXd#VB!LDq/#X4yH*HpLFVtQ*Xt!
KMC!?1 JWDXaWetlZ#M*chhT?:T\?&AqDSKL1Iu$a\Nc%$IW4b1HweMY4e/t^JJ$b:hIyliQl&bay6=bIqlRbK5
#llDdB a9SnW&=k<dlYQd#iwJ/VQ!h$^&JwCXqTGGjDtiyM4&1@DXKyS$N>kl1%1L/MHGIc6bTCt1:awAb1LV55
>WL/Hq *QDpVM/BR=S^9G1kD$H<NeB:B%%btuIcY6&8w*c\$EmBAd/iy8+Lk#=nW!mL*?LHM%Km$jhN1K1$ILJ\
-AA*4J 000a8b8e5c800110333 Page 274 of binaries1.zip
\BCA6V l/^PD:&+MKc:?Wc/*MSpB<a\#YQcp1/6KeK5C6l*+^Mh**W4nH&eLhy*B$N6?cNTZHlZM/pZ$FeJVQb\
WQRc*: &98ZKea<RX1R9u+c:j#5Rey8kWCiLXR5+$ASa:<pj%Tlkd^m1M>lbDw&6#W$DMeFWEJd==J>LMF+m@ek
PujLV& ^cH^VCpYldcNQlnP?TkyQT9pTwiNjKhl8lYncL%1ZiTN$hQ/$R>wTZ6E\1W1JY!VunC^P%pYG*A4qJ%/
%bEd&R =mM?ti^?eEc/G/F&+@DKNLDlN^nY+S55tPSKP\iBXp:b$/Lh%#6?m/JceVkFVZNjWPC$N@F*m!dE#%bZ
EbI9Du wTk!ppN:#Bm\4t@md^C<MtX^+!MTpQQCTG5u/J+GbkuahIYuqeeblC^w1IdAEp4Z8WInNwcw^t4Gu+dm
6&96it ESM55TV5=G6wc!E=mWWV#p9EpG:Z^qqi%<MW6mpGq8kZ=S9R!Inw^C$P91^Z$B!&&@Pcl!:F<Be*%j6R
\A:6P6 wR5JSRpyaIEAbB9wV#=#mwYw/y6nSB!lt\=DJQCZX1IPTeQKl%BPZkkX+B<u%mkhL*%:$nDeqlPl\<SP
ReLe&n ltAm9::bGi$*9n>?=Vet&GkP@EA6uiAL8#ma/9G1L\VJt<yBY>*MQ4J4jDd68/pJDH\ebw88lW1@HI&%
?&5\dI Fu=MjLwcH+eyN8#I!\=Mdce/hiH<LQnmHpnA!81BMCFnKbJh1TT4#>FcX/=WLP/S#Ee+XZDEpmLSAJPJ
W6G>DS XN5LV9nZJ$@9N=kk%4@X9*$jK%bkIjPlDe5%yjP=IiPlytuVlG*kW1$^^8aS!l49jGRh/%QTSJmqP81E
t?RdHu D1e>1#4mHIRS@V*qV=5&98cMw*eJa6NLkZuAmw5TYFXE%=kVElu4Tj!k#:y:N%eL$#t^Z>Kne+tb<J<j
FC@W/c >WY^*1J9/b6IV&B>bN1a#je\QV\$C#R^C+A&Y/8FyWw\L:a!Z:P^wHPBl9^GR=hPd6qZ/K>4p>>YJGV#
V&qc@4 B6IdM5eZet8S1>RIGudLy4kcG4HiXw@jN4?!bB9T#n!Nk*!nRqCR&aDD*4@eZy:CKt#SIbmlQJkFZH#R
RG+mqH LTLK&nPkIp@BVm%h5d9Xa?QZ$%8L$JcP/BPtJ:#nlnciIG4W%S6BpYpG&&dCIMZl@9t\^kmkcnA$n!A5
j#nhtG ST5y*!i=bDS=TuaLlQ5pE=IClPpC\lA&d/A#wc?hlYJQGY?Fdk^EF:%k598KIV!pc^ppLd<ec\m45K1N
^>p$$P IJY&L$ucL>=+9A5JDhCGF$aWnYG=&hqIC*wS5*GETcwNDak\PD/6HWN8kD=Ek>cXQVHEkPXmMpjN#&W^
YLBRR6 4i^GD4G+PwchM\pK6wBGSi*!H?H!1WLXlTYDB1#6CTH:htiGGB$SlHSE\/\N:KFPMjC$M?1&K%ByD5HL
il6iRR CSQ/&Y1&h!Itdi!pW&+V\jWF=lZ1mSVDRw8@:bl=/mQQ\N?FuE@a9INBXEVKJIXGZHI9VcM14@Bb9Tl*
w*6uMI Qld9mWIucmAKGdT<?8=cjyHFDlQXJ+P$6h=cF=q!hVq%lc?NVIX^cBkDm+4CW9/pXTJS5WMp^KXpc49w
<^ZA:A 8SHN5yG4R/nCj8Qw>SIGm9%M5nB8C+XAVW6F6V&PJcS+wS=IZVQk8eEe^hh?DMw6tKn1QRWRDKdp!PdY
?YbhEZ K!w+!5B$@#%y9<\6hT4a^d/ZVML<?&MDHeN$^ucN=kN&qT#epD$>IHq?%9WmKNktKMp+TPwBm8I$h4w5
jB5$$K bmG9\4AmlGQy+nWaGBbXTZS6&&PDWmF8&AJle1EJPFE:p^^^/kJKiMRNl<$Z*YRB=cQS*IKCu6u8CCL1
CSHmH$ G/Xt:qXlc%XSWu=:A=9FQ4tHw>b$6ZJGl9%SjqWDw&\PaMF!&wBw%VEQ=4Y*?Ac%%:I$%%FB?ZKcu/XI
&=teeA bZ!CtM#ydk5@V@n\>>dWV^9NeWWVMhuk\<cyMkn8WAiVpX46MMC>6N9#bR/LlQZ@VCQh!GQl\*#&tWJw
Gil@=i 5T!#S<JHF+F$uq\9BPZa:^j$ei:@G/FEj&h9@enwB%Z4#^T9j=6<#9%jDDRKBAL@RD+HAqu@LjI=<LeV
E%ByNL ?SS@jGH@@R9H:%<+j@@!D!eL@5=9?$jtHQhQiJjen\+>!k%/BJ1h@Sipdt:&^/DbYH?B=ukMt9XZcM=H
5uFb#X wEH59&CMeuM>B5*&1?jtjk!c>ihwIA9LI>B5*L>C5#+G#jp4NQA^cQbjwS?nc&^A6q?kH/N49/TEA%pi
CKE*@y w&\@at4?HQ$abj5XLS9I\9pjwS?ndP\e9=Ke?#>B5:L<J=K#QpdbRC!@K96S!5d%K#VdV@uJ@@VSH<6Q
T&*MZC ByJ!5HQ<%4+=HlWbF5n/Z+&c!\u/a>SeV4b@c:lk+@nVWQD\lj9QZ#lbj9@C?9inBB5u<GinBJD%y&F&
TAGQRh @@Saj:>@=><qi+MilAJ^@IpV@!NY<&M1p?N@TykjJ%p?#BbAD=*pD=piI<5nYjB@8*QlpSZ#$Ai#QYV@
mL=%6? Y*ljIQinlPH/u^LtS!ljql?VLbdjbH1MLH<+!bL:EcF<8j/Ypj@uTh#j=@8*b>5?qyHQ?XhGQ8k9nQ\j
XVhwPR =Q!j<QFS@lWlH<V=6<ht@q<k=G5DP9=ZE@JS@p4Ij#>wlKpt<8EVa1tk:^6Zjkk\IGJ&yJnp!8wVGJC:
n$YDGl **yhq4wZjK@F*L4Le*SjauKhBRapDB=h!*+AA+4uQlX/d%dj*MiXk\F:>dd@^$Di+NHW8paSy8<N^TXN
a8@#MQ l6+8AJLV=?kZDK%:?+=kkD%>^uXF/tR%GFBTNuLZXi/>><qYejC?9IH9P&dVR%bZH/Ya4=5Z\aBF!i*:
8V!\Q< p4XRa5Xu:>mSimI6?&jpt$tXHBYy8?:?N5ZYa#P?LLWZaYFE8h9\5bK$\JPtQ=eLiQX15uZ9m@5hGDAF
@$FI\j Bm\ZkREjn8@QK1=$*y^1<H$@@WEI4jlBLCTw?SQXyMcp4VuAuLFElC++eyuhTR?^PqFiAK/RG#!iAAaE
mKD5ym 9&kFA%SL?K+\TG+ujNl%+IVCquny/b<4u5JaB6WH9wPAu9I9w/*nmbAVtRDymK/p#dQuTtek$diVeJDG
Xcnw!t DQlmK>uW:85E5w#eet<iZhhykAF>IYDAXl4KJ9*4%/@jG<#D^>LkKhNXpRZ!I?Qi\BDyF$^c6Y/tMF@C
DbZDKH *CiJpjZFLh=y+nQyGK*Ym>JebZ>#:H1&%uXliB^=#>Cn6TLiB%KGC#ATJqP%TEHkM^j4tMJ?iE<Y6b%c
h>P%w? NI^M%kcN4:qme8YH$4BH$=haW##68:$Le<WLY:JiKAQ+Qn\J\9CiM=Hi94>@hbF/5iaPu9l4hSk+CqNH
Q$$DRK >KnumV>LiAen4mhGK1c\cPAX&H6dQ\kGRNmCAe1P+Mp$D#!T$\ZtY=nYP+ZlHY*9Rc9Ya%\\+EKMM<5i
<FqL:p DGB<iF%6Yk@%V%#&ewCZi#8B!y!mKYMjYJ9tGletNwaD\I:RY%HkY=H+*uA:qVwy>**<#Xe\kN*pA898
YuKWDy QPP%>:DGS?EjlLuqqVNXPHWDmd#*iPF!Za*RMT4EI9T/e>lkRQXR5ub%duXNyRy!X\$/AGhQa6aADMmy
X4BX+q cF%l9DT=I*y#j&Zd!Rii&u*%?/$u9>*m*Np@?n:wShA188L>Ti6+?J4u=8=$Jel&dGdqKPGY#T91wW%+
\Z&wmA Nu^JQdj?j4Qbm4#!KLR*iQ1Q=T#<KcZa1=?W\+I!%X$Y<Cu\alJ*Ry/#ADVYM<tLl1huQ#cIjFI/KpW<
Y*Z=iD ^m:an%WcJk+mn<Zp/E8<T#BKjRWG8DtVZQa!:*GQ5=tMkGiP49/m9eMb+NHjLtM!YLT$=X!J?QFYTS8h
1=!<iV N^BHQjuM#X<S9>XaGLTK!^%L/t>Knu?/J=:%hA:@S\*GYaIBS/k=aAD?=y$a%VX1:9#u$IK>Ej#RC89%
N9lu>W SnQjDi!?4Ed@PuN6%8HWl?d!>\YP@:n5i=8eQ@u5w&n>B@T8XYw$wcuL?8ZMGa<99HqVW+6MNp6GCdS=
MjSR69 \bM11@CCNG/VG/@8B+EcSj!JE1+&B\1W1BF4:\CV!1w=YLXNp$+j^EE*Pl1b>ZWSa5mm#^%:8N1\T*yp
^TDplX P%LVhJ!6#WPR!qkb9@GH#e:w8h#N?A/^Y=8FSb1H:C4kNGlP*F&5AX8qLhu=&R6iF8W/le$GkdadDq5V
n%lZR! Qi8t/kyI1Y1H%FWipJN8d=hM\SQy?R*FA/EWH46G$R/mGQQSuZqml>W#GqN#<?\#CE=L<YLYCth*M@ZQ
h9>j%u ##@XDL:h#h?5K5m#%9qPeqn1aPG^+S>4mV4kkSM&G>u>YmV^Y8nlqbVWby^T4h\Zth\>1*lR>ut=K/\j
iaD6t/ #cQGK*4tweQ<Tu$d&9DRR&t$mn@W>IXL*L*\\pM1lyXehnDk?wMEGEBt@bA5\ZceEA!+$<pFA&I+H6JJ
8!GuTj ei/miN?Zn*9*yZyj=/YiB#%$RG4tjB5!4ZiK9bVjp!mmlXM?JMNV!uhdIWC?!&T%ujt^m/Nt^h%9#p?8
aiQX*e yJ@w1Y>&@eyDy@jGndc6hR%FKF48BLDlk6R#@mGhq=j9TXYD49:pka@qi^6l/HeWYl%6PEK$!Iya9c9E
\b:^I9 DX>>tb$%NDqcttdCShM5BuFKJ1I9ZhVXD&H5bCLImD\RI8=Lc4eM5B&A<6M^kb1iRcLiB#YWKi?dQwTh
e:Ge9% VuJC<R#m<cm>bXG6Lh^>SW#%hnCt>m*9=qCe:MdacDYA/%ktPdhI6qlm*+?^FkqJInMhm1/YmP#5ljkc
/e8?MX Pl^JucS4&@dA9Hh?FRL%GyejwiAW\wBjkj%^p</H%$jlD=*\kW#DFIY=WeRA6eGlFB:C:tFH5Q%dj/H1
RqR$\6 l5c\ZcVpNZeKVM\/S4yAD=>M?auMjNIZNRYAh$BYEbWmQjw8GMX&bTkSak?*:?\n+Kp+1e%WctjnYGEe
?h@k*: k#ceST=nQZnAIYHG\mj8qwaC9kWk!&1X:+B@YEW?dJ86yP&MjlCHT=Ey=ELQ+X=4*dPN49j>%I64j&+I
IZuHC> VJQuZbPc#Kye?aFRyhF!i@a&I81EHTh%K6Eau?n6nd=QJ:l<4?p:ZcBST*wPF^*k%5VtS=nLK*8VBy/P
CbkmNj 1$mwZdd:WMKb1:ND$Adpj4Y5qNAVLmVd&DL@A5>p$:aIyNSH1c!4<P+bLq>6^ci?F/\=k>it*BT5DdRE
APVQBe &yWJptica@e4C!Wp+T9IlyFppYRSClmClj9<MHDcwYDAR:h8p^wR^$9jXbYbJ+N\p6ul8+WE5i9S5ubB
\qERb@ 4&6B=<MJGIilKGR<94%iT!VeT4ZFG6!:@lTH:SVm+FE^u**^RuR41TWqMp%/LFpkSl!YjetZjkn1m<JH
DJLTV@ &hq*$>pq8a5YHFapkS<YBd6WJJSNNP@I:YPSBn<?HX>:4YDJNkn*WnVN<JKZ=L8?:9Q4Xi5Xt<8+X:6y
nK1#>6 At>qt^lMk6Cn8LD&E>jc$CWk5GKP+d!CaVRqeuX$*tlad:+/>!/DNFM9XE@!^jRDA\+Q!c%uYjda\DN:
cYNd+B #M/=#Pn%+^>19TyXnC!iZZV4^EZ4WmF!*GD=4mmNJ<!:#<k&W?F@%M5FpK^HpXdX9cT4mcchVq>u8qEc
?8AC$y P<DRqPJPcmnpk5^1EnYGB4Sl\8YwpqwS!Hp&Pn>=8nc:KGK%k1#R6#hPp!N?!?W9CC<*4#?i?iRd+i89
Ay\Wj1 4MwlDCdtAiFEFBq\/Mc^%KdbhbAlW%ELnuLE6c*nR@jl/y@Di!AyRAZeE%Ma:\5J^HS8Z+k!a5&q1y8t
q%uATP >/mum<Tp+JJ!5cL1yyR\TpjXG5ut1uWT+T#HWMS$YB6jWPkX!\eJcjCT:u\^/@Q\Z@R<pew^65!6L@^t
TGkiG: \<YJScAHSdN*Ey9=n6TV\9hXkqJ@AVu?eE+!Pp5<QTRt@%jCwtei#^u^9mYN$5Xy96RAFVLitZ<%mY#d
1LEX$K GPXE@?JX?6&b>Ec+@:/!deT>RHA9ESj+LPEL\=i%9eWN+J*PwnLNcm\p9id=4AP?9Z/?88:5km:?AFFI
-ADh\+ 00015c7269d00110333 Page 275 of binaries1.zip
naCc91 4A$PdNwpP:*5%Al+>G64=kFj@N*/6bHReQYCtSy/#b:<4NduRYmyF^cLiSd!5JRiM#6hDFVy4%&9&>Xm
%kBW*c cjNCtypB:jBb/$44MSp*DQ&SA&i^^lR?R^&bw+h!RwGGklMSq5SnCH+XBTiBtlXp=@4wI5>VDutPby=e
+=V*m/ w$qh:69W^bqaSC><@iaL??uP>TY*\</<%SH=Iu<NkdHELFelckmbI6>5Pi*LDPS/Vq!M?!*8>XntaL6Q
$<IQN9 tScXV>p699lM*jaRJVZXwLS&Z+mXu#@Mj>T@+S>NiJp<#GI@!F&LiN@RDN!^dipKjKw#:aPE8M/blJ1=
>kCLt% j<qd+=X<^p!&wqt#\R>>y:A9wIu&QYjq^=\RDMl9GZ/a9:lpuIiBAh<WI1%jDhuRjPi\ik=q6q%aeF94
n^<=jn Sq^a>+1qudAVyn6ikVSdNMG1GK+TD:9*Q9YM<:b8*u8e@1EFm6yP/Q/NBMQZ6pM4y#QtaID+\#BlVNA1
ci+QNa +==/4@tXd^eHDDnI\eyRtnuMNtM!1W4Bt<8JHZ+9N/!=G5E@Ww!PHRp1#kwXt?TAq=FEY:qLTW@ccy=c
I:MHTF #PGiTM/Sp\ScThCqcZA^H**VbSB=khCVi=*4jN/VW4e1S+Tw*CMpN8+>S+y#*C=S/l+LWq>94qGY^%G^
!9*@6i JkdA6kGakGDA*$uAB^=@9/S6&jB&V<:XT5=Cm\5M1Hy4bb!Gbw%EWW:lG4NywpJV=+ACtiA>E@Q&l1GD
W4>e$w %@VY>M$YWeca^%C$^55CS*MKjWM?6VA5K%+X=QdewtbI@#!iw!11E9h6Kbuu=?tyY\SHbcMN=W?=My&W
^/p/ZI G&wcVha@!#ybjmbB<S1lG#*I?uTG:R1:9Q<b^XL18iZ+YT+<9ncFa6I/4EWN&iD+P>C5dhSWBj5TE@&w
$&W4!i =&H%5pd!/F^kwE+/Rt=\$CtYtuyubFVQi@9/tbiY%>*JW!?t=:%T*YF1T\4Fa+CqmSnh*IE=Y:u&E9lB
6F5e>K %G94S&>4y=kZV=9Qc8#QXT=yc$W9KBym>hJTZEmkC\8umPIY!lqjM%Zy6Y!h4hub^T:EEA9*I&uu%WmY
!^1B=T :M$atWTn#TPc4$jk#j5tVyApIjS/L&Q:RI4qXD/5MY+%J<9k&6=WW1WY8+eh!VbM&4c5ZEA+^L$\y^Q=
>hR*kb IDkWcQH=ZRZPD9&J$@M%%i9iFKw:YuL*hJY/mePZFVl:*eVSWty4V/8cnGG<iAKNC%RJ\BQW/V1/TGwQ
&5H$j! //?uYiH^SXD+c:u=NP5^nT#9jJj=+ZFiLqW^q%u1yu/?h<Na8E=Ed/e9?$lycY?^AlHq?myES>qV=XLG
PmTWwB #GXR>M!+J<9T&Hm46#F14?j%ibP+Ru!+P$XIV#mY?QDk?H\Gn58/6m!n:6*=4p%4#>V:4$cNDWF!w4kc
ByC*@P l5d4$FZV1p^:5l*^9N#IIh=9Y>b@VEA?dj#a@9!L1<%@<68@Ttp*M9nJ/p!*1u#*Y1iu^m=/cTn/R?>8
*q$Ta# EERpZW9$&$/1?dA>nu+H^ydBN\\JM\pJyT&4F4*&hQ!H=yCnJhilp+ejLp*Bp*Bqu<4!=@jKdC55GF??
*6<K?k ^*mu1>y\d9R5&q/YJemk=b/%+WtLKLGDLeuqXeYE4@QSqi149D1$<Xc6/?%y8SqipuKQX?1F8:8iPGY$
w/TBSA $w^^>!ywib^qF$hT$hi>jBWu&*Y<pq>%*>5@j*8qyE%&QVQDbZ@ZY*K^b:>\+QD%6I69A</:G\\+9\y@
ZpG$Rn /DdwLMiD>$t$#<%9*m46L=w*#G+&BE5L*jP:*n=MF8YT65GAh=VH%^pcN?VB#PX9$me44G^9ja+8Y?<#
CpuI16 YH99qSQ#//=HCyR/Y4ZZB&&W9?1?/!&+LdIXjTY*4@8&e@@p?km%Fa*HimdQQ9lH&ybQNd8V^^W#ZDMQ
m#hS8E cd>wk/ew\IDwJ&AAHlk\5eYReb4@Ep%8*>9wiQ%myWdue1KBRcJ%W>#l^Z*XRME:4!dN:?X1j!/c#d5Q
Y1j&1d FR^+tGZ6Q9Sk@<+6F6*pl$h?jS:b5JNShl>>kdj*/i$M4=^mK^1mc@@DFQhTdhS:uCV9DaptmXLGDN?u
E?W:Eq C:!^mm96!=Qi9ha94YM#JQq<$q=99>#H:d>^ujl!4?IIutc=/:*n8*qa<#?5BW%@#84<p$j^H%mhRBb8
y<81ZI :9<9H9j@RD^8*>@mej9@><jnb6*B&nmmRIa/mKCtId#Qw^Cw6InkP$dC^/>c!<YAEan>Eay:QM\Qt>M*
DLGBLc A4SXm&FtSCm5Q@kekajqK&CZ#h@j>pYuWB\9Mk@dln1R:XtuFH1R%e/e6BmK5DA/5wC+LdE+a?$lP51=
?5^wt5 pwCElPNEDwXkyAEF>%lM&=F1y\BWRG\>1kwdHW>ydFJlF9L<GqFR5ia5Ga8XJRRu1=L&E^+aTJb^61m!
9/wKh> J&I+<4JtY4SBVwZ!8DWkcHK/Ycte=9i\YWuY^wkJSyk>5QBLYSCcXyW/jQIRML:$nEnK6R$\YYE9*:IP
&:%^#w AA#i\$J<*Diic=R=MpiMT&Wk=#nESj#MnkJV+#ji4<=QEFk$ta+8qMSA\^Jq?B+uYk/qSaYj<=^4aB$W
CBmGcM u/?9W*hX1CA#@I=KQ/4:HbIA%lbK*Sl>!QnAuB@=q>TPylwBB\upNZS5ZH^G6ba9HK?i<X9kKbc5!yM%
Ky$Gq: KWMunKJGDK8Sh1641+?NRk*J?eQkZ^1LhuH8jEt\utR+EtGLZBhw*I1KQ$y6XHp/$%TnDL9R\yuE&I^8
Ga4#Qm L\MH@:uliaINq+mGc5Aw/8R&Idcy>kW6l4m?NVT/hW$4Mnb!m^9@+44:uanW=J58ajaA!Nj^u:qBu@9#
Qu>dWh m5>a:H4*K9ZMVbiX6Be+1<L9P^km9*$YwlX=y&1wl4KiK<eZmH*GQd4>/eJTb+IeZ?C4jLtJMe/KL*<e
dKRqp? iwej1hLM8pAEnXMG?RW!W?pw9=mb>h^+kk6EC#4^8ZDw$Q4^G#TulXaa\eJ=!PR*RX<e5n8FR?JnS9SK
cQ@/Pk #qqKk8Wd*+&uKeBZI^e=8^F*b5j/nE!nhJn1qTuHkwHT&HlRyAcwTybnqpclwbt%G@=#W1?Fhq>TbPWI
Xe&N@c =\9S8QQ\h!9+RV8%!+>%kBAabwyEwMh^mNXWltPcIAHXIb4e!e4/W\6Fub4#9yJK+bGILEY>LCE1lM8C
dd9P*> wR#DBH$6+WT%d4bWphINPF=bpRk=knE:&HAJhl5=m4qlIXZ>^b^$\ep6IjaKG=8RwemIV^nWZYK>kM!n
XK6=nS ?RSGk%I9B>FlwMm5$iE^yHZy&RPVwb@mEe&!TRJqab?\?@pb&^MpINM>:d#$/%K4tR#y9R9uwt!&pQE9
YGy\dh C18GtiFMFCIR<uFGF1kEjhn$Mw8aqBe16MCAw9R/MLml6kqDWRy1#L+#TK:RG5iyHaAYhKS1>pqE8EN9
#QF/*+ K=wi^<cWW96/%^dpD6!RD:mDAT!@wnTCNWCMj$tBXE8WKGE!:i89F=IQ8tSXjwyE+WcD@QpRZtJ:J&iK
&$M$8@ GCFk\\KQNuwZ66PVCytq@wp$bQqy?*8e+Pl4W9b+FKC<i:=R5hE8FJ98^yk$nnAh@GIYm+Im>weNt=QD
m$p6j8 4ELNCMTuL%4%1L5c1HMR?RjVqPp&FtM^jC\!llD<NWRJXcpBJ4:V+X1/E!A/VqjhScM%H%SE1%GcC\D?
PRE>da ZI69<JttACSkNh*k^ny+\CY9j:Wn8=VwuYCMBTw@*1Eb!aTWFI=hPPZ<y!SpcGWLC18!?GmHn*E14@nL
>6#Jm& 4M5#A*htVM#X4Iwn9#!QZ9$1</E!T%Xm5M<uM\VCIkES1=tYm%DIeH@lk*j=^cjpGc1<e8%a^dHV>1pW
ita8+A autIYCT=I$EnKR6Y6eLVTXlbtGy64A=E!FVjhK6d+QBii9>Y6l>1Ydj/w1TRAFcniRdnb<DwPDwPlBJG
wPu?SD ZX%QSQ=empVb?^*pal6bkq=QW/dZ$b=Jw59QybAQ=wY5:BmZyGDh!\ePiJ6e1H#ukwnFTFpG*eN/ch<N
P<@HSd \=GEjl%*:cam&\4Tmt%ZIZ\4tMTHyK9&!n8^e=l?DQPbuqbL&4M#jcMbcPJu@EGN:\y6Wa+l?IYTy?@#
%*AyBE *VMDm!Z^F%JE/<jWdXE1q>ALQnnMM/HRk>C6/%M1=$9aGQ\Xb#TjLCY?h<ZNMdR1qChN!&YHKFJGTh?L
/DVYQA ljhL4G<aM/JTFFn8yKu#LGJJ59YeVEan&ASi%+Vj>h1P*dT8!6<u$d*^Rm<u*H=ChYiq/FP6FQy!V$WH
cdVGGq GWQ^1Sj1t9lLTZ&EpLm=$ctZ8H5H\^D/wy>5HA1dJd8wpBIhVLQueDW4HBqjdp:/Jba^DGMEEcPMBD=Q
J+6M!= t4\1G%N6Thp=GGc9e61$R4kVbMB/?6//Y*5NC^SI>Iq\tJEeNY6i81RBu/d!Pl5Ea9^<SbYh<Mt>C%$Y
985WMy Q4/lkPJGpPibMlNF\p4DMK^ZTdA\?hiRN\@V*Qu6Dk%iww<Mei@Xab:J5#>^4HdbNHyybWtBD1Xam>Sp
Bi^$W& ^Ee^<1LqSi\u?WF:q8h!/ne<l%d\*Gw5qKTnSEIVAQ^SiGcEb@XlAj#L/mECED?jjRD@Y=qhj^<k>P<b
<JLJ9H ZJ!pj*aJ@45MLmCR:d@tpkiC&Q:I+AIB@#$G%=?ycu>qb+Faj?y*B@/S<@Iu\S<VLBRIbH<M?ljBRwFA
ud<Ia? npik&hq?XVdua>C5*L>Ae#$CDiL?Fb4:MiljQVed!&QRwF?lYS?DB9+KDZ\E?6eey=?eI@/VTtjl?AWc
kFBd?k >KlKB@$C@Slq?!XVmI*nQ$J#@phw49<I#j%j:Ee+@pn6AZK\QjbAdCDH#*8Mj#ma@Hh!#P?h/h?\44n@
>%15*m ZhwVP!eyG>eQhk#Ld\!bS=BA@9/ee@t@%85@I+H<JSLnd!RRny?SRQ:&AQT@LG?=8Nn?F&^cSGE%^Qnj
Rq=mZ> 9GtSkKwn?!NXCb*Dn%PeCeiJtRa>%yHK>Qq*RJ*/IeaEMA#?ai%D?>F/&KljAF5<EWy/<8\SXi9@bEem
@RC>jX lGT&*<lA#Y*8HRQcBlRDjQZ^RZ6RThkl@9B/H*>VtS@yPB6!y@kAdmk!9p$QVIuiLAhKKiEeNC^:GmeN
*PTTbY DISdCG$b?@5R*Gq>/BMqFRn?<W?V$cZMGlGP$55<LI/9pX6FXGpW6PdCV?i5yMp@<tPnjB8mN=:HeuMG
Xwd+@= Dc6cF!DP8q!<NX116%Mp/FG=8\ImZ@B&Q^>l1j5IL*%<Ht!8NjZC5+kLNbYaiL!D@Bbj+VR6Db@SwRWY
DdklNW Y$Z^RkP&F!jRYSMIbjV^HSQP\GTjAEV<!19lL+BBiGYP<qhM8d:<y%^c8CLunVw<8QcIFZYy!H*I1yyd
8&RdI! jVAVWkAcFkGLQSw>1W6=i8T/J%i=P//m1NmVnE?#/&V&+L>WYGum9K!V91Lk\T:QaYyDN&NQW=CQ1K#5
WD>4*= dnKYWt=1$u:*94QM:wN%HG@9Y1a!tPQ<I%tq=PR!u$ZX?FiLHqW:pS:5J5<6AnElySwe*a/TXtCV16P>
I<wh!! ebYAc:AI?@bHw!>K?#1%#>In*mm:#1FC!Jm!:1tJ8Z1=I8qN6/?<4#!da%!CF*B$bH&Va?ZEK84BYVqa
FkCa@R 8L6SqwQG$5h$8$nEE6E8B:h&/#4bCS\/VmXBQEe!#dlcakn?MM^CWmlQJIR$yp\jM@b<i/i#VTuK+MC+
B>!Iy# n*X6cJaw&6V5c*>PDmj\EqeV%&!Ly4plaH\=>bt>4Q!dN%!WN@BCTKGwFi@a<HAQ\RpqC%yDXdb=G\/l
$d4k*h MbkGAd:9AnuWd5hW#y>Bw&JmenluZ$J/ey6>@WbT6n$?4C*%PpB!m\BE%datAM*/KkaC*Jtkjj?MHPRX
:4?9>@ cebVD@5XAh@B$=iJ6:?1t/Eu4D@K6!*49IS>QHXJYj/%VDiw:ql^&LAwk9@LcChq*^qySk/W=<qXGZ9m
Fe:^K4 !?tebl#Zeq@PSA4WV^QaCaJb>aKh1l:%YJ:lMGnRneACm<T+?Qi!^ePdbRTk8\q*VNTa4#m<^=*QNmcn
-Ahawk 000ac6521e400110333 Page 276 of binaries1.zip
aYKn^n GC88bZmQh+ncwW6mAL:YMWW8l+1uV/X<jCeTEeK$KX=p8>y&^@WpElFlFtp:TF5SpaCkNh/@!FJXGB8q
8BZY5\ \^5*In#kN6q%h=C8*mwW<uX\a1u5I=$>CKSG@mDp+=8hmQA=$NTMSkTt1Qt#B8cP1n1%E$Lcy&^a=hL6
5wiSQc &w**KNCNC9m6qJwl4FbblF=NBX9DMiT<!CBhlhHVNTR5KiN56q9$F/i*1T5D&1lq^tp6K1JcYE=%kyHu
W#ih+I LKZ=TCI$tL1B6QuG=Tc8\8b595=a/kH<?T<J#BF9WhE$NCae<ajN\w#>e&hjBGuauJmb$iSlY@kZw=?J
1@5aj< td?u!H:&Hl5Q$Ti\mF$@y<wpXda+1GP*n=S1+yNPbR%!<4!=a&#Sd8CETQPY^aSn!L:X^=uJ^lYLM^=N
Yl4^\Y >n4E5ZpNiabM+%\jH#cF?VI?>G^$MS\ki%++R+wlWabRkpuC%F/b8kFSl%Plu<@<kI#pX*:nRt\Nb?F?
G!CGml $pCGn<KFHJHG>Y+<aL>5q?y+$XplHBe@/^RebPYVWc4CRhqPF8je$ckY5YMFw+TJVNQA/tKljN!#ISmK
^hjp%$ AldaL+JNp=ea&9$y=eD<+WCkD:tjHP&bq<ICDVJSb<$&a>S:nR<Gm!pX+d!JAwF*H\MF:%@hCVq^IS=>
KPb5B/ bPt+t%B8lWcDk%#bL$FRDh6%w9EIiVu$en9*6N/6>kMMHGeS4=w1/wen<\*>aw?VJW^:nd\?ku#ZL/:H
Z5<y4* N=6iI=B#l6Sq$nRejB1!@h9Q/TYW\qqeP=IGjD5YlR96#EkHmnK\iZc:d6d*#BnXb?lHHiak*6jGPd5M
SAQY*: al6TY@8h>EAQVhNn=1N9S@kuaM9Y>nhLyBwF^tub>ZJ=/im*!h?jLhP?/c=/@!JWm+e^AS<GSSV/KR=A
V9S*Qw Nw:%G/uSuY=lNkiKkP?u%N\9XBn4$jKwCpN$Bh!S@5?Q<^Gud1V\1KyB1wMWT&Y8dRY+:qVuc&t:+nVt
&&VPnq SX8TWl@yMt1dePW>#IX\KV$pui*J+ACVP$W\qMY#LjPTnmde:$H%4>8FJc\^w=\ZyALjcbY5YwScaeQA
h+Sh\8 #Aa!?>ml+m:dL?+=hS\^5n4Xapt5mJDbReVK\RaQl+6P5*kdt1?*y5Hb=4ZqE?nue9alH#KwPu><ZcqM
b5HCX* +N*i^6JAw==<FECpjiVdMwq:&WF/wBqW1<K5RaHZ*HkV6llbE>6AM/K+6m/&Ei=B1:W&G^q?c5%mhRNX
=?GWWW t6TcT#lyaP+e8naQy#Bp@Y^C@EatJC$H9q8>Tc/X$q^5bbCm6FQQjH>*5V$YikwnB9cil9LG%$+e4\N6
?DhA5w $dGJ?&&eIGutA6uG!Xd+/%VBd*XwYpm5Mli$VH#9VAKY?R*C++Pn*c#:<b8b:u^lC9GeRiAFCN<=lX8<
AeFaW* ^8Gcd#:MZ!kZN65bZWYX4<jZibk1GK5Hu^86CKa+8d<?M/AnS4PjJh^kK6S6M^ijnQN6SwT>lc1Qi<8X
PeLEJN L=ilNT*64TpIPTXLlqhXL#Hb?KIbTcNtF%Pw=^qw5%</8hMD!:>XwV::iTCV@?6&&?nAyYVA68RVD%\!
4Lm<Eq kiG9BIDqJ&ALHM@L//8&kIAFKC=c6AAc@5LL6a+95B^jlC9l&<cS>@GLT/@F1Abk4Yhl55ebjT!?!wDa
CqItMk %y$pAFcV^+kGeBR$%A\4taWwRpA&R#&&pCAPH&#YVmj=XVQa#9^XA%lK5qkD<q4&uBC8WZY&HD=aqISX
DT1BP8 R!iPhZmaWT6^A\<8Ii*u&Sk\l5a\w+G\<8aIKP@lIL$aBh$WPp4k@MMS%k*I$c*wktER>ARRDdylDTRu
$pcJH\ TH5pjAIR!E!+jI^kP$\R$D@Dby9A<&jC/@HDRb4A/?W@<\qBLwXE%l8AZ>*wYENHIA&BltlGdqhGQcHE
A>M1$e 6KjF4GKA%j?A<TYJ\JeN1+wZ/$RAc@WIC\PEb!?DjcKA\!1Q^T1GSVyEEKMIA/ABRHVnbuZn^6lmu&lk
<BA#9c ^:#CAjnB5^4nATB\jTB\:LY\1&Vlu<ulR:nm/^hnK+Vnn:unaunC5$yDpdISakRVK8kR^mnD?RAJ1:1\
Z&GCcn FdL\FN:mXeqD?44A^dRV5@aTQuQF5@?AT$4:JKcGYCGD8G1h?PRn>14Cp+hjja5l^4+<XanBG\hAAcFI
@?WS?> FL+V&6<>EZCBB&I>!YRnHu>C^84:SJGT#L/hdG!dnDWBByPXFBPCKCaG:/TMHMMaS$GGhG!MpqWG:%TE
e&MwDG MycI@JTeCtlMFY6Ji51Kh?yMYZXF@jB@:IbGRb+k=k4L+S&6R#J6qkyiwAahMI@PwXDFy\RLYEWQ4KN*
N=MqBm cCR=@Wl@&5+A:Gakb$MFaD<j@@\ME9Ku=l+R&@?k8ij^Bl*RL@baPD=eTbpdPj:688+9C/KHBed9i?n?
cn:yd% jIALK^9L:&i:@Hub>yi6Bc^5HH>Kk<IKa9q#SmC&9=y!lG!hj>9+>>iqH#5:=<?YL#>bK9>lkjc4QZhA
/XpA6< EMen$L@eXAQmjATcniMZJkIR%&QRwF?l8S?DB9+C#e:!CDV\X?cJu^^Y@SM$=/@R\Mik&Z=lI9nJahW@
9mnjeC RdQ?Ck%/BQyHHJ?jw^?nc#<P1jp=?nG/>t6:FD9uw%V%F&a<h1:@CM*>u/A=H1N5dG!@cKIej:B:5HH@
J^8WTW c:9H:@6hj4N:eLH>yPQ+&:PnH49=li9*#T<@4Cc@d*:=aZ#/L^%H\e4/a&@w@<Z6L^D\kNQ@%h6j$Q?/
N*A*^b @TXFL59M#^\\ai$%+h%MjkIG1GH>Z#%\a5%^=%1cNbq<LLPS:J%+yk<LuM&4qqYit%Y=a9QYC$d9jmK?
Rq5FR? /=LW9SVdP/qZy/In><Xd%@tyaIDm#G%MDSlR*QTyKB<MtK\DA!m5\IC>e68@RYYAS&Qc#dMHuiynh^RY
6hYXQB ?p=cCw*>XpLX=*BcQ=m8jQhu$pLlwCZpP%:%w9KhJyLEYKMujd:?<6jb@ZMl9Q<Kw15uBNZL4&mb^ekS
Ye*^E1 :<ZTWiB?/il4CYcY#:!Jw4!R+d#Q1:kmN\WDXB#jKMtAAWYY>?J#aMCW>w4!lQiiJlkR!?F>wea=BX1=
%9?AVC VtnhmM!+W^u?Y=D>>DeQllt!cSuW=?+ElMwZik%b!uSqenIbH!LC9CIuYnin$K+p*yAe^6&$jq?S1@p/
6FbB\K \cMNB1\M*u@\ckGQbY#>icNJ#F&w>^VJCYZZ<bPdIV>tth\waJeWBi$iF:EeIVMCV*w4Kq:F:lY8KQKA
uu*+%\ qDltCca99wqKhmZ%=I/IHPVH@W?IqVI/N4te+/GMq#V<PLl9Sayk9MmXB84!PQL5BkEQ#@VpA>>XaDMa
@@H$Nl EJjRBB:jejS&<=K/D1KaRlVjq/qP*mAP<H+/KjbM4iAM<8Nh$XHC==+YAb$>kDIjG6**8?I*?IjclibC
^yqGnP A1@ie?+K#BB/EKNpijjCD6:4q+EBG:Q6/wS*l#pNKCbbY^hpELJ6SVFCp+Ei1DnLTewpR/L/dNGX%^Fq
HE&/bH mMX%&LKD<pQF&/94epH^!*Z6<!C%a\$GVZ?<h%#FCZR>aTFqJ/Tc6@yFP45#!C#RGTeL>YBAp6ddK&:d
D^t^bD GJJdC+jZd%/+nDBWu/+T?/qw:C16?paB:6kK\IAZGchW6qe=jPCJJK@pCVAkZi+Km@N&LQZ<e<d61Zhj
9XS>QS e86Y^E1?E^m\HZe9QQ!k*Cb@m?Leje>*6REG^LB=D^P$T8?CATQW6/Gy>&dD%/b!>?=<G>I4b/K&E##i
6D<CB\ b@%kAJpJGJDC&q??8#9w16eSkG>!AqiNl8!/?=Z6C8$&4QE?8XZPQKQQi$Pq>*#+?4Z$9hADyJ\9**bm
$Zh#bE *9TW=A4H@w:NK*&CL^wM/C6=8^5mWY!81C*tjFJcSh/Vb=CibpR#LK@<QeJk?>XE1w51qa@cYPQZB9$M
nYTRAl <GVK*/BT#:<q*\djm&l:T/<W%I=5<J*T4X?d*QHti#>:iAk%pkuP*TY&A1k@FW^8ZtL8wnw&L#KeHawJ
l^@$RK RpG?YQMQP$S*/j=*^Q!dA1*WWy\9>mSkXLi+e8Z#nCS:lkpMJWVQ/V+CTeCATFpu6j9V@aeKnA9*QVMF
P/A/mw V@&8%u@iJkPi@58NNp#9Zy8Fi*$d9w*NV<LiJ$Yj\<CAbb$*jKj&hm?6=5A#@\kh@j&GHkLjiwM%GMDT
Gjcicy RHL15ELGh#t=LiJ>^QRy++14piRl\X<d$?@R<V@j1Q!DQnqt6*=QjCX*t/cN>mMBiPIjwbN@8nELKZj=
%*IYL* heF:mLH*N1&l:?$>P@ja1=9BmwJ:YTc+68@DV9ZXSCBt?\aaGPZ**YbGMKLL=Em1*1\MbRNVS4LKmp>b
AWM1/C euH5TnFd+l*YQ=j&ZnpTiHapAwmea*Hw<1dYIWc=WN8J%qAHqd:6\H%CnNKS1bnumHkn#VE?=hYH1iI%
n^Ct\S R#eVdE8MRQ^J::\6F4jwS94V&&h*T&=S?l/J/%>uQMFVMd9jiY+4dCtuK5<y+I*%?tkI&by:#AbF!h?y
NR+Lj8 *^lE!=RN:u<RXFyNHBW:d>8k*ZW!tGLW@cD+@1SG&:JR8MTtY<aT@#\T8<XHdd&CyaZHp>iiM*ZIY!%!
RBBP+V #Z@!jXk!Xn\6!XQw?/?jPG/WN^Z8!*pQ/=#\#Mbc&T&>^eJ/=AlM#VdPS=mwau#EZ4+@WiiVLkY&lQBK
\D\6n@ GCIZ>YHGF1y+%*b:ATZp$VBp4qh6!>%>B1b*4h:\W=#u^yMKwuj%nRM==?pPC1Kth5Mwq9Xbm#>Y1XK?
p$5tJL JD88kwyQ8=4\iY+*^:@R!PWCA+CinNy8Zj4Vc^u=ZaWk1G>h94b8+c:j!&y6QA^ZlGp:FZidM\>Nu^wQ
eBLD^5 c9Z%h5y#E#N8^\&jiPKpb</wA:WY:!Sn11:$FXK%w?W8>I/I4eYVy=:F<k6V&F@k?4!N!m*ndeF1dDnD
RRy@VT /a:4yL$:lk49Gm6m:upXkktD#S4%eXhVL/tuhb>EJdnk\5iCq??\mX&E=&Shbu@ka@Wt#+t:K1X<bqNp
*8S*R> ec1Q!S1MycCR&E#d#CI>b@I:Ml\!DZ^@Papy\:Xl$Sh1*@*m!@5%VeE#eZ*ZS@ljA6C$>ndVSbG/yLw:
C6S>5j @Pj#GmjSypI=L^QHI^m=D#Vi=mt%yHIiSDa/4P8ih^?t/tlqV>>uVHFu4p9&h:%D>9+mh+6Z*+@k9F9/
KS#1tK #C&?>IAT<%SbFX1/BX/Cl1<bVe:DWJPbycZ+9kD!&bw+c#^1B/bpGiiLh@5Kpp/DFWu>WF@Y1K^:IbVL
tWD6Z^ 5Dtb\kD5=G8:$14d=%hNbDM?AY^&t=&l&MVTGdYAqaP\Ge#Rm/$Epe58e\cBN!Ll!bK+5T*<wke95i4J
=VDlTi 1M@w&?Ew#LcmK$mluZGmVC@*EI8DMaKYQ^Gqcc1iaYy:&N>KpA$NuM9T<WNTWFew9X4*a\RDbD^<ni?Q
V/RNX# @NHH<c@W+u%^:ynPYYimq4!m>?*L81kp!BKE^JGSlWWK^/HVY?AqC!tD4$BH&l>eb#dQhSX&T#\a!SVw
\kEdaL Mp<9lJSSc=?kmAYby\=l$4M*IWq5KG8TWyGi$y%i9JS19H9jLe5dXGX4>T#R@WXWN+FpR&+beSSGSQA*
uJWDPQ ClZNT&Lnwi5NKW6mnA<6j6+KjSEV*w5ikX:wdmuy#=XN\cNJ=86KYDy9QQ*^?M+6:EuR1A9tXk=PduV&
CH+4V: @e>Mlu$w\ICwyaddnpZ9@pHQEDBkZip>DlnR$u#69dG&/wqW8NKbQ!@l#pXJV5hXSmjF\k<nj6JYWn:j
m?FN5q e6JPYEPk*XQKFY*&qiSb1&TiQdhu6#qYQG6@dRWW1+/@/CL?dVP/B<tVTy5MN>6uG+Qhp&Q%tcT*+18a
dDtq?y +5m=uA&!5<\eX4@w&AATQ+b%&/9A^l@D?lWGGNBV\EMQB4k:u+MB@h%6q%CcndZ%E*pJ*!lVCLPVWnI\
4GX\6K VFW$%V:KmELF/haG#pZwS?NmXDhT4&4kP&k1TKi>SFTLbl@t1C8aC%EYlt@pBQbAwR\^DA>d#p\cH6?i
-A41XD 0000a685d6b00110333 Page 277 of binaries1.zip
=9B^!k mM^<9TN1TkGYYNIJD6D*ueYN/Sc*+ukd1VXEWZkP\5eL:cC*Si>JFB4yK6K5qd=E/XS?c:GJ^4cRVBwm
NN4=XQ y918pSPZWbRM!HYmNCpJ9>q4MS*j#q#YkbHCNc@I1Qw>LPZ?IJl/q=n&WG/E\L!e569EPK>K>GX&WHa@
N:wCWC Chua1R%qecG&J:q68nh+Iwa9lVEdab@@8Pa/Z5M5\ENm?H/tj@J%PX*#/a6Ae9?a+tJW\#le5#HN?B8+
8R!V@C TY!L!!$=FkHGYp:YVEm:<\6m81\w+hCAWmn:!\#/Y^Ha:t!/IHF!E\MIPR&ycZ+Q?@XIj?%anV\1>uQM
6TC$*b 8ZJlwb6XBWMd=w<9tbY?LNT#98m>CJuWEpR?qi>/S<G%hjK%V:TNVc\Gw=I$A^uD8WJ4Aam45N9!5yXK
KC5i@A 4$!\tye4btEm^:cKuMB?m>/M16FZcjK%A+=jJc>R:BB8Lq%<n8iJjaqn&LS/Nm1VlX9R5$J<Y6amZYuP
B^R:V> MuEFtY<hJ%5&dQRTlHi//mumw+TTETEpEcp^J?<VdbG%*cPwttQH>E6LTEQl!Pmp4yW9+&%REQLM$LT6
le%dYX hE*1E<j8JykLw\:!<*^%Z<EnqmJpK$?GRjK5%XmYaHMw\ni^:>LnI+6ZWAwIFq1kMYqNjCq#ZaD5*uI\
t@n%CV qDAKSL\YYBT>wA\SFQai:5*w+nPJdM4j#&D6wp=AE!+SqXVyX%CkLll?m%u!>KdP$&W\eWliDBpI*&=8
Z%q#TZ 1BHG=m8m@\!d@J*EielVK9>Q*4?Nu9?m#cB=*JJ8pGF^e9u%!MCSp\WctE&8!VEqKZ6&$$SIZJAL>6Xi
H&+9Ay $ImBtASkBDd4ICjY=yMhLPZHyWLLXQL1YK@yCK5h*1e#RSb!6Za&l%$cSJa\nMwc%Y8<kap!R4#Nh1DW
X8Bwyu i$Jl4NBNAIZ:NdT#4BBXeXS+!H*k</$lhIlQVP/1GP/Y&hLqPwqt595\MwA&^mC/plRB?qM!<1K:jEhL
NmbITl E</5Wnq:*Y#!^u841j!AaqCRVMq8dTd51ph\6neu5!h48JK:/1G\#$phJmThP%9Q=^c+#pXK4=nAdi&\
&Z/8cQ R*btE\wWYe4pn/^E6XYk*BbJRicCE<+u@1?Q\FN^u#=l\8h^dCR4yNFXpbWM&eMFl$W6uiBMlc?I^&nc
A$B5^A Z?e$D:Xl98F\*GPZyCqV$QcS5YD>#uMtiEw*H@1GqwAd\T%\#i$$1h4H6>ZRWcti*4Y54ncWeL+taXXG
k?=t+Z K^C1kk/^@P55#iK1$Sq&KCS:F>KRMEW5@>h&GWNSNQG=?LiK8RD#lmn#m&&P4L\1XMyuFQZt6GT\w6:L
bSmLGd PcJey*ua#qdKFtM>668+jSW&=Bj+4EY15iJk\P5iuw1uqJHeXuck/!G&dDu&RF%&6J5iI*lC$H8lDNqY
Y\<BGJ 9DuI%My<yA!6/\?=EqbDCQ\TFwDT5M=I=XQdEJ<eS/GIDJ*#+PJy$%lcb>SF:S^=j@\%!?N$YV+n1C<J
d*Pd:8 %?ilLG@*4L6#kEGtkDDH8ZncQC=Q5V4SF@5&yH=G>SjT?ZcKuEX*uVl*T@KPt=K?Xjt\lAe%b^1MPF@e
eSlE!j JM:jZTYRV&>k?Np:p:Gk<Kl^Z5bVXmbdT/C$/IHmQY1L8d!&a#aML4%I=y?\X8&jRNAE#W^EapDKEeFS
S?nTnC 5GWn$8n/DJm9CiC:twLm&my+QB\ST@6uiR:MD##iY9&ab@#VPT1=K>>WtYpV$8Ba=Md/iI6!Hj&=99NY
=:lyEZ DY>LVVhMn1!iZ1q1:cJkY!\@!iH$$R*Z8?ZKcAt^/w&PbcVR=CLq4ZH+tG>q\8EN+/<N$bKaanqVyPDW
R9\qyF %=p@6\SCt\<*F>kpWR&1NVa%tXHX8EYLn=ZYWwwV:!^^\AY/FmmEiKYum=h8la$NeS18^@KFblekVyuj
ATH&:Z c=DdlE>kY<8?Nq9D$wJ\y%TXmZ!Jld?64F1IRCu#knbF^#&#Q51<LIZVHbNQ^6>4ppTh\yNw\utl5h8/
cR=!@Q Vm4=MN8*nBAWY^jVbMZLH9%p$6YGC<P=^B?q/c%eAw&y+Ga&SDIhFGcJLMY6h4BtXBN+Ju/\cHqlkb\*
G$ViXa /:XQ&V:h#F8R&eRZ$HM8L!H&##tPb1iqHNw=K5#>F6#mtuRHtKuZBS:*@Y%u?#QS9R=j>Raa?:MeF5XX
Bl>ndb ap1WSju\IPTC9\W^&yj\/LVa#Z8MRHtI?NkwP\eJakj\HR&<B\NMeSKXG#Z$^M5IlbQJZT^a/Qi+BGuW
>jC85e 9kpWXW^IR%mY4NAp=>Y+=:G#65LC^JBh9PHR^+V1um%ePPy?yj!^pcPhMb$mXu#e!MmA+NWaJm$5tSiJ
//8JAc RpMlCT4h>ee8PRwyw&=FIY^>wY>a>tYa@wt=6X>QpNXpY%L8ENK^Lq+HaIwNKiQR<R4#\YMnV?L55ebb
e?KnJN JEyRXC$5MLT:\?<M$Tu+aZ#n*G<qQHqPnAdd\QwM5<j*pBCnM^wmNK*tw<L4:9:Gtc?GtXNH?j4pGqKE
\GH4Kb YYStjSWhdwHpISTXJw68cnbJJZ9j#T*NYYwMKRiBRFT^WJS8!&/=icJL+%pL+C96N=yc8EEatNLq?<hu
+VV9LN 8da>ESA\GmFE#6weQ!IdbK#?5!WRARlh?%uaG8n*+^TGphG%Ck1k#VFXY^RE\&+VGdI=tTVSuuWZ<@n1
=@\wH% 9F&Jtn%\NFVAbBYY#:GPX<4M*D$ADlTSSmQwVKa9%R<NqNK$5S!VNiqBKAKkD>?MTPiy1CBt$lZ?hwkD
TB:6Y4 eIiP$C>H:@WwGFCZ<VA=&RTYRJbCKNIILKI:\5lLATB+=TKBjZAGEESQdpZZYTF<XRH?XZBbBDZGhMYF
QnDLyY KlA1IkAmAJ^?lD1ylK=SKK+Gl#8p#:Deqp$BMRaMVa/B89Xw!8V65P##H#MhW@B+$4?a=q#XGLt=B!6d
pwMlXL V\k$PyP!GChk$4V^uN6CA5GAL5LYP/u94$/B#FequL6*4?:#dm18CQB8y%J9BW4AkMuYH!enpQ$+S5p:
E?k5>T lN*:P9G\heQw%bp1yjQYi<HQ<%wj*mN8Qk5pqMAjSB*\1d14kIkF&bQSS@wD&n!@D<S@4u1?$EQynLP1
AplFkA FTnC9!?$:uNjX?\>%iLhh@FnX><dT&W\wMV6aXY?@>5S4lNJj*>u/*1/CA^RQZpRaPdijQmmVPt?dQ%i
plGpKJ 4PJ&I6u&MGELu1tMF<N8KGSN^V6WIZeS<J\K4e6G>^CEbk%IW+%C>wY9pM&e!aj>bTcy?=wFh%1>6&>j
4pql6! ZSX\V6jJZVi<9Z4cimb4Y&cSeYFLe5449bZ&J8>kRu9R$6=&S\JVnPp#MW=$e=TQ>/hnp:>j>I/AJ%*@
lXyWTN d6p:uIy$*t?kbcV1DBj\HJQ?4p9>VtJe=?WiX=kE8SByFE@S^1Ie^ktl<$tHY?pFjJ=ydj4<*B9FLXI*
qGTnp6 TpK8Rt\S@ub^=<9iV+V1FKM>J!8/bj%qm9!LKLRhAXC4WM=:emP\wbpACLJS/\?RZ1h&eePuZjhcp%M/
a@#LLW /ui/%4:RaIDL4K96@Xu*jjb>ql@=DhC:/FcWPyL!5nw!NadP#AIPR$k*jwQH?NSLwLH\CYISYZdhnYn?
a8kPJD ^=IM<FTG1yBTubAuue8q&Wj^QA@9>@bh5Sd<$BhRiY<1Q>*eHa+@#E>ibF!kecB%\*%H8&@&K8m/Zlj1
@LQ#R1 4\JkXbH/\blb%uuZMLAhIpdF#+IBSc%#aADy*bZ\IL<a=yKMycS9:#j#tZLiEIywGwSbjW@9p@utH<aG
LZwJQt :!68?+jX\^>Gp+i%:M:SZ>c5Y<P?YLIN\8yV8ak?hG<XlmHDIJy/*+mTdMZhw:TY&^aK*a=:6#heDF@A
A44&*l i/jIZZLeN**KRV6:cBP\K#PaniNYl=pJ<?8yuWCRR%bM6$w\LlEJqL?KII*ILA$AVj?6GI&Eyk&NAA:&
bl>CC< 6j%!nVihh%9F?jA?=&uBLTIaIQ*HP?CbHc<@*?#KF*/j:a:lL6m>V1wawSL>$Nkww*S=Ka^kSPBBFPlw
VIHAiW pyi*y*et>\>K:j61N*ZchqQ8E8e??iP9:+Rp4dQXncBVG1uQ?iTyIAHDWP1b:Q?yXcjyN>8Q*>j#t@BG
IH:yya <8d/y:q5NG+dEIWDHbtSXc>G9/<e6dc*=1969D:/94K/M5F<#99>=8nah9jh>hPd8??ZuPiDh&l9:t>8
\mTStl mc=Nj9>m:BZ<CR^+e+>!>>A>CK%+Q%#A*mi@!ny1ZjH&>=b8@V%V&#@p#kei&\WDjp>a<j994*:@uj:*
5TpC*# $lN@L**+>!<Dj!u>@9jTYbFTmeKX$aAu$KQP>?SR@*KB?YQB%<<ZD\b5Ew^:d&GTZQy$S9^qNYk!Ay++
D49y>X ?6MXyu9eVan*DF<J8j8@MJj>tKN9bA^+u$d5<y$lwN*!/@ha@Y&PW*@KEiFF@%$Z**:GXE#L9:KmiaPu
=k&tdm D=cX\IB+$\jqVBL*ZwNCbVQ=t&W4iPc*LAQTni:ZTC=G>91Y@/q%dVmX+9:9e8MDn^:>XeLjel#:ecND
Q?B5TL D8l6n*c>jYFp?!?5R%9D\it1p?e:=:^MQXKN5d5MtVFby9L6BIJBYh<:?&&6TRWwJuyC%CbXVRA+MG4S
T::&Jk *$wK4$Y>\iPHl5wV\*#n/A:SkttS*M@JBw44dqVE+K#5J^pCJh+LluR6>q>Ka1yF&\VdL!^$GYb?4G$&
nDJGT= pVJjj^hN#!KK#G?9<6\6+lYHFZS#V>KAnp$Pc+A=e8a6lH!l+enB%&G9Y?XZty#=m5d/=KWYc9d>ebQ!
&N\SC/ ZW:F=^WNWewiCSu$8Rw/\weHjYHqCA#byaB9SK6ySlMm6qkn#$96ljM&amJ^XERpKL:ll%q\aDy?eeR+
LyNe+R u=n!D9FpHY<b<eu1j6be*\lp\M#Ny/KqEWVDJeK^ePy&@LP8/FMu<#WG*#qiX*PtekDm:y?:4J\l&V>W
1Xk$Qi E8My?V>ce$$G^q@WdDJc>MyaK+9b9:=?Pbe!6pp954=d&wJha99NMqb69QcGSn>5ia%iT81%lL+jkhqJ
B:QX?M !N!cm\8RZVKK45D4VyS<X!MP1d!M5QY=YWSFV+$M5YhV#%BHBaQNl#KZBW@\=H/5l1CBnWicQa>ntuTa
&d1Q?D aaDA<=Jcb&CGd%+Id5=MR\h<6^MKS/>ekwK=b+Pu9l?jNI8JmDKES8HZd:8/jy@8:L=#YEXhe#BAR!pH
:/G>w^ TR\F^mkw>Ba+EtduCJh/\SqWa%W!n4<nMEiyDYWwWAu:RlaIBSJKT<>LbjlWelI4K<4Bb<V<FVC%kB+5
m&eS1u QZHAVN:aPI&S5m^ZPlVdL=pacn&&EJ?jFk<ykW%>ENk9?8#N:y*p?9R:$9AJL$hJ:J=\IXW:MAANa:tJ
/w:y\t MFX\@AKj/W9nFFpnyqbNDYTE+Xa$dh1yc#GEVj#tpTy:==8uu/iu6dadQtkq^JwA/cLjpPq55Db$VV:L
^!m#Hl jY:FY/Iw+@knpNSDt/8MG<yaFLy986Mk?6eGu15cR/eK&m5qucwJw!t*ESiuG^NLPiWij1Vh$5uIh>>9
bj:khI iM%nEe/HPac6GWqdyNT6>VDtFy1AqcZHA?XTE5QSILyYyuWtFJ+qca=y#ZlBKh8TV4yCXY@FyTj+w:\1
$/@4uX !?^bbX++YaXh\/WwNt?9hjGN>CtHbDM:aEwQay6Q&B#lnjmqaLF^FKRjYu*#$?Cu<hJX&ueG%EH+PdN*
6nqNeS TbQMhKh/:5/#cB+ZuYq#55R=<LQ$$aJXPIB9wQtty%JE/nqT4EW>A9X??C4anlh+E:nj+eJV^tJLG4^4
RDdS@D ZZJ!\pm?b@M1L16dt/c5mWSC9a8Wb/mmmXKTTW1<qD%Akb&F@T=RE%&6dTtiHpCGQ!%/9$eLKW4Hc:!H
#wa\:D Ll?tHKe4bJWI\R>L/a^ZaR%mX:uATI\4hMdB9w\j^jkc<*waVdaycI@wVlQ9Ry@h>I8!iRL<6PwFla&+
CtKAdS X*tcpI*4bikKK8k%QmQXJ#idlI%BNn!XqZHK=Xe!u/m#aIZ1P?j4KGb?M:@NHM%KdMphQkMD6P>LI@?q
-AN8ih 000697a795300110333 Page 278 of binaries1.zip
YyKW:L 1YP81qp6:4ctjHc*b5>$1yuuVR%:<aAlKe#=6NI8#y9hZpjyF+pC+&ZG>R*Z5$Hn#@W6Et\PVwEaDIn6
+S=FY6 T*PFL&5p*+EP?M6yGEe+=Cb\Q%W9Ck=B/?Ep+VJqCaMB!HGIFaNX:F!E??L%#T#T:E=l<DQ:CXZ5Kk4R
Dumkbw 5bLXTqPTbKXbq9\mMARPI91R<:MLY8Tl8Qk=pWcR9u+$<l*9>1X@hKyX=Z>/R&=51Q^Q8\4yFe+n*9b8
<ZG4:+ u6jDEF=BmJPHASWD1hc6mS$iFP>&&p#F$@IVLW#l!*hhH8>4FuyBNZ/FZNe9BKW\K%NDhQ4jlJTl\LAk
quRdMC y/94mEAJqTAam4<le5l5#4W1Inpakmn8uXT5a!>ewQTSl@kT5qTyyVE:EA%BlAZ/pG*q^Zpby:>mH:M=
%iNI!S dylCZ:k&yS<9aSan&5YYyM<1l6We&ImIK!j&#w##$G=E4My98EJcDeF8jFH<WDt&V&jbXtKj\9<LMAYA
V\X8Pi 6^tW@GNwiBm5D:\iP<\A#K@S+y&6?iScyuKV</:VMFyaR*Mk%9qd4nw!/>6Rc#5*\+YEuqR9DVn%qZtX
ni6XDY QQqRN6n<qE*WCJQLIl*L@4Ib&Tyw*N$khq%iXZ%VI$LC&m=pTMknQ<#dNuwlj&yQq6wXJdI4BtllFcQX
EDQ5HB YtKLq<YLp!BlJFCbQ<mMd1:Rc@Ymc8w<>Vt>yX\y&=$8SZlGDp$FDJKt*W6<<q8BZDCkNjXiSPyl8jC\
MHb5\i DQ1c5abCjZi:ep4*/wjn<w:P=*yacPK:+8ZEFY>qwkLQ!#!Z5^G*=dk*YlFQA&ySwQNFHh\PNjALn+8i
C&8t6+ 4:F18T615iG*NKb\S*5+A95$XKK#H4wRJ<m#!Md*DR8jL9Z#q<\$Z@EJH44#<uNjF=E4?\$QtkX6b\\m
y9y9e^ \:dtwe8XLmm&Nmh?NL>=Pl5=Zbiu4TWDTHXZmHd$W*$Xw4TtT=c#&*e^XSb+\Kt\8Biq8$a6E1PZlpES
^/*!^A Ct*WiqdGGLRpI*8^kkI1?ektt*C1%tL8XWQPk!cw*!$hK>X:pH/c^udHq$h+j@W\5\nLi%k:AX8:CPX8
1tL<ZK 4qw*qF9QSF>h?n>$k6/e6&GJ>&dD>/Vn*m9DaADbn*S5*mGk@^>:j^$Z%=c6C/CF8$8ARHB*KDRR*N*h
tn&RhN *b$A\S&Ci*B*D=wR*C$+Ci=P<AT6i4C:V@j8:y*8uNQuuQ9ijjeQjqT6t6>ae<$%=yln!nhG#w<L9<E!
jKQ$Mm 9=&w%h<%DyJdq9DWLV!wjQ8B<:w<J1q$<dn<&8K*Ld=@%XF4E!XuG$yhQ$wY6VjHmEcwVSaJhkc$pDRK
ZHkDhN >h49Vu*dTlGj4hKajbEMQbtMAVHpm&tyM+P#&mkP8I$JJ$$lut1KXn:G6!Kqp+$9=/IBjX/A48K%C#VX
ANV4kH w:LKquK#paht^49yHcpN#P9l/8ZSme*NXJ=%jct%pi\Y4tXek4ik/YiGcC>W+:Xi5%>FDK4tZD*uFZmc
J<S:5H 69:8m\B+Jm*cStKn+=9+a5jhB+EhkY$nRwSC=$!FW1*eN/t6WtVyL!TTcpkpCy&!Kjn^eK$9>=PJ5kMI
<=wGNi SAm5V<q/KjTqGGkpE!n<n#nL%P:$8eu/9D9MkP^WJdc!hAeF5%ERw\qYGqRbQ/n*Xww41m^Z&<AAb<:F
<!VcH? $=KVk8QQ>=Z!QkcTKRkti8LVmRX$=?<Rb!L6wXB15%j+<cYqKB?THAnL/EJT1AEq@pmakYJm\1CZc<hW
<hX^dl huBTVb!%B?:jmqyum/Wjp8Y@?cYW4ML=yp?CARidn/+yieHV=Q8@?Z86Z6XX<lddY=t$Ey1l#%N8Z14<
:Vu<Zi >L&b9u=Qt>L@a9NbX/QV=&6Lnj@hi!eDmB@tG?%R*<d/9PGYM!K9$V=!+b\T8>9V4:$/A5@q@NQjq@/q
<^>8\S GE&AK?By^J@@w^WheVy6t!V55t*yPF=8p@p9^9y94&98Cj^$X@:89$$BKYFbT&pi6E1J4d*6X!Xi&jPB
6?it\5 =:Ripq4aeR$MQGmN<kM+q\b>jt9V6#5@?d<Lu6n#@au$@/*@+Mu$MRi&k/cLCd!WFXMtjE%am&B@T\ZF
d:wIX< E6Key^tL\Iu1/5Z<FciEjeQhZbp8^dVkW6au%/SkW?1%KBKV*yA9&T?8?L@e9m1hQH$ky+Tl:Z8uie>c
PeTl+N lk\GQBQB=>le&4RHblpPuB1<4/hwKJCM/4&\BAQ55#Tl>Q$SnXaKy+4mLKH\ISEheS^PWK^PP^^k1D8^
/yR%S: k1M?ZAm@q&CQp&a8/eMajyhRJSGbi?5hI9ueRhBLS&^HI&KYYm&ikKWp<N:kk+FKKe:DmWnV:GI^M%F%
^^ymL9 DZb<TD\8dyIMZSWKh8I+Ja#9GICDcGm^W!#u*yYD?Y4n$a?VihyQjB!ly9=?V&@/NamD?$&==>*\kutJ
Rq5wRD t>q44<tqSiq>8uALi+dmpk*J\eW9c!+*Bh8Cp4!b8VEFE/*j/EF*n:cRZtLaH>KN^@I%*EV4Kpl1t*lM
uB4^a< kJc&\Lwic5&wqjmCtStpHyaW8#CD9$i9$bkXD4Ye@>KePQ&FIkYEn:IZlBZuuedD^Z1KAQ6>@pDp!5\%
q>\eZH Ep>F^@%bq<aL*@Q6i4n$QaACJ8:Z=cTe4@HKuKc9StEBaEB!:Nc+HWpdcSFJua:YABqN<4Z^ct&j#kZe
1ZImJ/ eIRh#1a?h*QYCp*ldh8qSSR=Y?#!h<!c%hn*F:9JX$k6qZbM!><5nAmX<KmX^:%ItQF\1A%jbk1CVG?+
?h6a>A Xb@9E94P**L$L$::LZ95QN+qei6k?9C#Wl&^i59lw<Z@hJb#@4+6?iq\*PM*cnCk*LNn&<KVHqSNDSJX
mq+D*D AANWL<A#4I?\4K&c&=ceG\!BB=Yu^up=bHDqJHBP=uhdpkFTj=*RedDl6@ZwN%$yeN%ZuqD/#jcCAaMS
Z=My</ n?an&?FGc$WcDKl+@BL@iI6b96X@eV?@+jF#nRhhlj9\HFDb#4>#c&%j5^5&eXW=wZhjR6S$*kSK9RRA
Qan5Dc *n:#E:nS=&Ct:B$M18AwtwDcb#Z4!Gq:n&ii+DtyZQSYY\<APNV8mc?btmM?Yd&%jQZ^8<=h:P:?6h9n
NwyRTW *B&y+86N#KL/*N#<!D#ZY=jZQl!NC*t$Mlq8#eIhtIF$HVlCm<YRPtDA/JjhBA@984+mi?Z#WIqhlj4u
!Y<1Y$ mTh>&14EY+M>*REdj1MiBi@j*4MeNd&K<Ae/E$i8cJ4Hyk+<Vpap^EyCIVwt&#dh!uRN1FPaNHY@cu?6
$TD5R1 T&idEy@R:4M>F!NqEGLEZ=1Ju$j?bu4^w*VIa65#yK+bh>$5?mdBSHQ=T<YQ#i>ibw$uP!bnD9R*yqP#
bk\j&d N=$XTKYKc88$*$FD+aX?FQy*&%>Gh9ew54==%:*$P9Y!NbcAHmJWGeAk?eR>=#Lw5:mYyZ:!YcQ>:eD&
qQdeWD ^&bZtjDBbAyC>RMB5c?c515EwjdIpRGiBI\$&ESXu*jEGqKt$Pnde6R*XHqqb%qHdHk^?@WN4Ijw&/<w
WC4EFP 9np^Gd\nY*myih>MaaZXPbpew%*cHDNP$:qNTt#i#V>ajd\b!j>=S!ZF:d!Hwt$$Zyw5Meu&YbTbDTZ>
a<MXK< e^k*+AELbRN^&9h=FV*1XHM1teGc#jDKjP+Xcp>S/R1TT4FCp<:n\QYeC\L5nZb%e@1icjea+=H>wp\d
:\XHuS k^XWmaiBjmq?BYdCcG6>ya9m@NQtc*5QH:\=JmtMZY4m^iRP1$@:@u/hL%\jNbJw>j+6V<j9QwQuhwnZ
YQtQZP $Hn>btNPRGKb1@?4H+u!d/nH9t9*b*p/=i8F&*$#Tqetw\mY\9p!<Rb=Z>?pie:6PbH=<#jQ*<EePXa%
tGGS4? CE?bYji8^%KbAi#$\aDZVm<Mt&a+aGc*t$Ij?4adV48M==wlwN1<eR+W$H8Q*I9+WKSCjCNuP4bVFH=<
YJ6lia QPk\jjV<RLhkkM=Q564?mWj@h\S^Xl+P%9<Z@?^@LQ=b+9>Y@DQENDwlLB$cGLEA!XIP@lHXltdacSLV
*dmEk9 SudJVt6CYCu$WnJYYWMnS4qcdZ5/8cQc1HYa$kqF>yk/FiD#EFV4IP/GkI\a*KF#cN%^tC=JF%!SyGlY
F8TA9! hLFJInX=ntMeLnt^d#/et<CkIHECGP\GINi<:K!uHBDuXJGZuaQjhkIcKpl:kkMZl&*$c$^GiVBFX:l#
%VlBdN #^Tyw=ph/?X#&Q+CF#MpMh$GT$WtGMmMyHHWQDpYXl:X#nt&YKbEIH=jEPZBXC<nwJ6Vm:X9Y&y%HYbj
+1c\1a w@i!<=RJl4Plm8EX9S6bSYlitt*$d=HL1yIwaMVa$L%eS\5bwR9i4uZbFm?FNQKy+nX8$9Ta/1lu$8KG
^RT>RE 11%%F^l?5/WqWtdW*PGNp5P%*t$<^>MtFH5ZwlBwna1d8:RVnbT5Ew#yS8=4KTV1XnqVZ&=eyHDp!+6H
PTFIpt Q+M4J5KwAeV5N+>#^B+^M+wC4kCltD#%yd1mcHdiy%QD+CJ/mb*wmHVBQGAwR$T#jNbbF$iRFd%eXNJ*
:H=B$E YBj5G&%A1bjBhaWRZGMd5wP=uLB6c5P5GP*1u<EZ<n!EeDJ%=WN#CaZ@hnRC&<mWuSpCTb?MKPZG9ei&
>\TS%G +>49MZ?i8bp:1aJ1h:%:$=MSkwGte#wta+$lRMj=@yXL:9Pi^nZdiNRkD<FbERHbnZtZqWWiW?jt&b5T
GnHYAF 4TC@>LhER5NA6QY8QE19aR\VAZNEI+?CRjkaalJG#<>KXy@eWT@GI+tEa:>k<*>l\a<:XQSGF$J96>mV
\tFS1n Jw+uM=dL?6KWZ>$<6$m1c=1e$M!B9cTlep^l&EpabB1?K+K%KB\\5R>FAV^N!KS*P<::mk%uGRSS$G\1
&T?DA# ThNjTwqywuB:ENb9ye!R<kWSW1yMBaE^lZtQwyPA6kXwL#9b+Rde!5uk%>\=T^G@qmMMTl<$MHju:HVV
!%n5Mt iSGReP@WZ+TI9?%J<l\K\aWN?k8j^$aNAXpADMbpV!5Y>?m#LXeV!VwhZl:entiS<hLPa1ZQL!LIC$W#
$?*5?h iYVPFRInlPjWLlTlpR:EyT@$8&eT/q&h9tBLjaY8u8P4+wm@TmMNmcWMEHRHP1i<ct5EuRap#NwPIqKV
M/NDcJ NC$mb\&!SI/j+u%$t>HFF!KNkw*ikp#W:$nt/Ramh@Ypj$XDWE?Qn#?PRB>K8*W^TVJ%!65i:S#k@VK@
WVwSV9 >T&?8J&jd@@/^5\=^WG!#pi\X*k*W!jLA6W+GBI\dJh?X=!q?EI9M%j^NB/hBItF#Hh+VikqBi$:nRlG
Z8@CHl &qB6LmHV#B$XluGDKyJDEhXBptLa5@RmCh&n=%KCIaiB6q^m\+FpliK9%@Lb?hZS+KtM&@Rb=hDHL^Nb
Qy8&yh !Pk=DI<\kb>MkZk>Ba5c5iH#@hK+CikVJKk:b=PnRe:dNtaeMY1S!LN8lY9cAYM1EA8jBF@VVXjIkIJW
1WKG5P SuhdZPXD/DKWuKPF*/8u*!a5E+/4\JeN6<:=E5:P!19k6KQMKm1y+pE9S$5*CjY@\c$:*K>5\PLG#<9h
h@%^wt XpmwXaYSmaaX$a=YZtJZVInQ=*ti#EJAP$W1HD>q?d:M6D&LMC@qWKtKdlbanNQREcP?NSZc?XY5XKkJ
#E9S6w mARnT$nPI%\^B1>cQ$#J?EYH\#la?ZZeiXFRKPJyRNe>DAV11>DP/bewAB6wmFeRlEE1El61klFXXa81
@pL#Qy /yJL?jq9>iS&%l8i<YJDIW^b$P@Nl$F=t5=:i+hQtKY!F>*SjaE85w=1tE<QL6/hm1MyRCYek+PV^>NK
I*j&TB =?6nc1VZ6\=e&Quaa9<&6JDE6PFDiP?/eC^?!iDCM@aWPu1ZJ8#^X*SFj4b=FS1!mFB\L%u5D5&1^V^E
/H6SMu h!w:i$#Sb<^VlKab16mF$kniRqi>u=85/BGVFQaeW4&i\nZ^!Aq\tpKCli8B=pJMqh\dibhu4Sae8l*B
cZHVTC n?Q>upjTY4GmH:hTn9AMmM4tGbwS4?*RqK1=F+Jm/VG/Kee/$WIu>1tRCBZ?tR64<p#bb?Np5^J:</Te
-AL=Mp 000a73a843800110333 Page 279 of binaries1.zip
+yP!SP \+jnDMBRd6^$1A4?BA^SwLH&eAS<KLLun&!m<M@T4c@V1RBZ8B8GpP@&4=lCLb@nwaRca4H!5pBEA\JQ
bBK*ma E==Lwa8mdIeHw/Q@<WkQ@F?LNebN<teG%u?ct54J<X?MEeVN?a<^k4k=@uP^^4lb@wQk!9wjH>n?L94a
C/D&eb u<qt@$Bn?\Q&*=@y54<Rja!V/%jRQ+9C^eu>C&mPu:FePZq?AR*p@kq>n+9qX>CeQ$P#@k4/J%p6&dna
*J<HbC jkZN?nM$?!?kYVq@\9dpA9+C?8h5V!/PZ*4\u/kL%/<wG@Bu5e8+jpZbjl4Dm+9:q=46J/4K^jQ9wLu@
WL=*Mj MYAZ5^\*E\<VP!5QD#eV1/YbpTtVtw8X9RYVwwRmp+cXw^tV1\PV1bt6tc5bp:tX:Y<E>%?M+MXBA8V=
E!@6nX W$w=DybjTmuH#j1@X48u=H8Q68*Jdn^X<qe1^@cH5e:?ch9@ap5>DklQ8Sij5p8!e*Q<WtZa@=:#!<u^
@?pq@W 4#t@uL@n@LK#@FG5M&:kj=:#C@\L==iF?/?eZ^d8@^4uq=9%@!#qF#ABtQn@q+^*/dy:H%lc$%B+F#IZ
FRcWaH H/cJI<AAc5\HqAI\aLb>ETR/<B5q>:@6/!dq%CWN8XXJjWMMBa:uC=yb\VPKTGTaA$@tt+cP>qY851&P
&QA+CI uTuRujhKTRIapCF#h*#lqT$D5tM?cS::n#IC+Iqp1y#6jbLdGjetB*5lB!&V<CI+qWFESYNC91L:D/?Z
YwM1u? ai%jKIQ$Zu+L+pKn>YQK?mGWEbdWpTy@q#9YM&\\W8I#ah!le4/c!>Sia*LqdEt%nwa+H:6R^H5e+Zmi
jjap@! i4/@/w4j+mq#+*4!AZuyJ@Kmb%&4mC@=n!c?/9m%VdW=W!mBAi%D!IXMj8DJQR&DE>uX5@kP4h:jq6QJ
*A^SFX He9BAA%%mPS1P^HcJZS:<m?d9uptaABDuh>kI!n6e:qt\KhM^qaenMln9R@EEA99:K^K$N:daF!4kkH8
/M6=Iu BeiRZtinVi:R@uNPkTk9/1ywy<wFX:KeXlZ4\IAW#a+6:ciDeqNJN$CIEl$cAITLM?BawWwtXBj4StI=
yDue>\ bCH+9akVwlCFW!lMm!VeCV!Jq/Xj&u#ut8WXphn<^9SZlA$SwF%>myp:VX8$89>bqYVjWW$%>Wedt\\S
i5V@99 ^H5^wyTA\HS9n5NGNKG=NI58kTTjL/HleLNMjb^Z%W%kREFK*#Z%ii^HCG5&QkEN>EDp?4VFRDnk=ay<
iLtt$e &IM5jc#/nFpA&5#\!#VyRSMGSNaZBZSXM9jE8J%8Jd19\u:EDXDE\&?b1Z8AAWu^!l*mQJQeZN&<L:+w
/#+R:N kkHuEX\Q:&Q9$#/Dy@??KhqWLhVY89Si<CnGK\%Vc#&Lk:Gt?*kTZZWT*j#EqB%&Wj@S9@kd6hcMy?LN
8iID4k $!deE$?&QuQ&$%uVd<Vc4@LYK>iLV$#ew^IB<E#/QthFpSAl#W18FEXKR!/XFIE^:K:%J>l44p#mp$i6
&aD+Yl lZq+%>wF8lW+>j8c<ZhZDQ=/JT$/$?q4lBKE=dauahuLYLZSRqZW*w&qNVDAl@mc?Yl5HP*HJBkRCB4>
@QXu@D ?$6BwNG?ZJJa!bQtShAw>R!JnkG#uk+yyXF>Akh%GRKGw5J!Dun&:>wA<$&F=ZDaP?^Y84a$^Qy$hD19
+a>nMh wCmhR&wt#B$1%5Ay\IFH?bZ=1mG:n?>AtEBqZ*j!>ymX>FtX#YcVR<&ZCiLKQ8Gm4y&QyST+l%P=t\5:
D9+ENL !+1DW:tCWLkMAIn&wbwPY:FGPS:E$A@l#5y4F>yP#=&yQmJ8=PnZL#/RMR+yuXWjNbRi#tkIkPjTH*\H
VBad=V y4F<#Jtq!1E#=!QwLC%6=GJ$>L>YNNk=EZ^AqT?c\eG8p1^iJDT^^yXG\P4jqmA4:e1I=ytl+dl:iX<*
Bjl6P@ cjB%nF!MeG?KFFEq4pw/:Qtd5t46qc<jkGXP#<Z>u#pi1EJcIuA5FqQeFtjHEn\QjqZqWY6G+1V@=8V?
TE&XV% +%ySQKEcH58lwp*#VbR:wiY6ZH6bTb@Z?Np#K?#H^q\iuFS9IQKal@ML6i6a@Z#6J^884>?aZWTXQVjb
<awDNw WWRl9Y&jpSbnBT%>n%JDeKLe%y/J=i>Ye:%=RH!B\uYjaR8i@:9&SyKQJb#p$$nA6>bLL6nGiFHkFV$b
145MeP :W5CZ^P1dhpW%%C9p^wnXbBA:T5:<CQ+lWk<MA>ueRD9A$+i5n&T>Hkik4yyTd>b/eb5DhNXVV8*Jc<m
cPA@TG TVk<1c#Jyp@!Y%cqM>iK=6X$P>\F#=8lNm1PmL!<bXW&qYR9ydbZte=:/ha\c8Eli6$Z9l!q>14d$4Qm
EiQ\HS :Ji\Kj$%eGV+tY4b!X:PZ=y>!Vwa\BMy9mEN^1Hm!hj+HuQmNTiSKSWc<ZjA\&ptQT4<=VtV<c>jyQcW
b$i=1J e>DDld=ZVIj9d/aA:jmkFcM\<QWWyWm$!&@j%NASl=uw6!bK%MX+jCQZ$In+P8NmZJCAF^qmLKkQ@PKB
J#Gj$C *CQXFMtD?/XNkT#@He>HAuH4LJ%t8iaTd<PJw$n8h#LA=C6EhuGCml:HKF=I1>Z>XVkSbEi!AV^TdBlA
GinGFn kyj*tc#GCG>%SqHF<?LL4KkSE6!Ll8DdWa$N#jDNkc:\q:a$MyIhjR6wh!CDY@GYy/^<MDQFpd51CVy9
w>#9Wu Qpa\b4>=Hay%hZdtNV#qkypn+$<ER^91Ajhw>GJi=aEBLNN?R$&ju$!8KXLE$B:S+a>M!RpC4Jd9A6Me
G=IXu6 E4F4j5ZY5eThn\b!>wXAAPlhPb<j%AP:1keI:6c<>P\i:ZJMcjPciD?>aPD$D<8Dy:Juj4u\V+RuTRew
Z*w&P# 8:<a8DZp6%YSuJEIchkETVZ=QXw&4w=XZd>KMKB!p:JJJmtLKI5:Su4!I#ppHt1=SA#k+Su^jaM8GDB+
l=Yan\ I:BV&TQjbI!68%^t:dVL:n?:8L=^uHyLS^h\qbEFBt#e?KYX^F+kF$&VGNK/PTu#RB\PKjN/*JtaVy8w
R9lw%B tn>:^kGI9:9lE=n41%!@BTXCJ\/SJE=GmqDaD@cqMXw4S5/%=P\>69q&@m=IakkM+DDW8V+GZp>JjYN1
:&TcN4 ?ikEh$kJIMFhLwy@qu9Ym?uDJk*l+wZuL=&cua6:ijBGpZ6D\bd%d!1KXKdqw!Qj%lK=5!YFnCpbNl<*
Bm1%dQ ta!EEuGGD=:J*8tZwSQPY<$#E%J+b9n&8ktR19M?bJtR&=VcyBeTb=T!qS$GKw%<k=#lpDMR#==tl/jX
TC?D?B CRmIai\<p1V&R:!?:AhqV#?I^5bjj!F4:yFP9R^hcqXJ>XIl614WZtGnwL9QpqEMWG1tSGqjTuWK^Z58
N5?q+F N\5#c5:FC6\:4&DG$KiqJ=9jK@J4l9Qc9eECRS9Hna^dVldIM\!nhjNmBSkeeR&8!dtAiLSV:*5?k\Hw
yjti&R 6w>G>/?9b!LZM*p^qpWXT=q?<MZ5cj?6pq@H@Di@t^ICp4C&aX@4%a6HD>kYBnw?aA&ua!i#R=^kjp+/
k#&WR8 ?%+HbDZ5aYJ1lqWpTYL:MHDdpyJKuFjTb@MT&m&Ri&kySlK*\=Ra&YA1>kHW+RIGnHFujqh9bp&#mChC
pI5&V* kC=D?#J@++RA6GPTi1Gl/Vtw>1/FlT@?daXQV1Q/!:WPcaEj6\?QFRY8/WqQH@K/ddi^p/baW5T\mCC?
&P!<IN J%Z1IMdKAe>q:@VcM^y>ECJec1tAI!Tch8NLt8QWD#cSC$q<wiD\uAPiaSk9Y>hVNd6^nh+A&Vdhy#By
Y=JZ5P F@>LZc/=wte#=^b&=G##Knb8$+m$eAa#^Gq5QS1VAN%JT54*5?qk!RaaCS#IkGlN&=jbLhWaY6w4ttMM
MH#/WI ?bNd=kut&AppTTtCT@=A8>qu%Ym*!&DAk<+1TQ#S:iM\d94S@NaJTe4\IGDt9Xh<PpBMD5w\:A:quB94
!^?ihE WZ6m%I5iP@MFGND:ZPDSAn@:n<djiKbB61DbT5&SdwTBW<RD!:Hu#cL\$8@H6F@Za=P%6m+?iq$bIDTR
e+=:M4 *hn+/5Qq/1ujld&>P^l\W9\+6n=/n!+8#a<DL6e><j%mSqdH*Z:H+@m:5:S$DAc5!wEBeGAA=</8A?nY
!\d^YF +X4kyyu4u+9%A$@5/j=ZkD?yV:yc:LRW8ZLdY$mEG8p*cISwb1>S^n4KV?P/6pRpFu<+A>*8?K@uwj<K
8^uC=Y <K?tct*KlI&lin5dAw?<jm%:pB6bR?D@=j%D/A$lW4ZjAL$!GJDt?YkSWHIiDiJjtuDh6%4/F9Q$6Yc%
&X^@Ye &yJ+NDpMSIlHQ*/5AZLN%F#H!eieY>HY*^Kl!n!c%Qb9j98a8$>JW^q6RHiQ%\6qey:!uDdY*H*dBeW#
Q*SGDm ?V%qSQ$jSiYAy%JBKa&Q#:\EBp^Sju=RH49Xuu@+<hlBJFMFulK\&ln<YQ:<RKd:Y:4Ywm1@%heCq^E8
ANVwYp 9/X&@YWeEe/wBthhk%Ejjlit?BuZEYm$9ATS\eG+ITA*t#/AdI!H#/:ETj#hX$uV1LJT@lmE9/qmlP/R
N&/@$t BX><lmhV8Zt#Y*VBDDbpQduW!I!BSM^AI$5jcMR:BtbiaDP=#G?WD\\+k@*<i%P@DaPyJ?E\TQ?b8wVI
RpXHZ/ S4kZ6*n&6EjlhB5M8JD+pdPjee@nh#@=5H9:/LKmGn^&d#>Q$L8Pu6SH#TJi<T6&?G<1CJ+=!Fpjii\I
a%dL>M 5TeC$%#Z#tDAVeHh=<5^EGEH!BJ$<eD8F<aMB1RL6D$Pdc9@V5F?tX#>H1#la&J5tGmE+$5ntV@T%N>d
<yY1hD &5e=WW#:P#CANRlET8YK@L6+LZ>JeX#LtRe/$@W4Zc$kmj*?jM8S/jG%EFdJkI^&\aB\V4@j&+=6MVCA
MJi\Hl !IehbAJ*L!#:%^#cFu>P!j\4$mb@X#unu%X8/yjFVj>C=Yb?Yhy@i<6^@hXpqD$eq>#*WS>+I=DPW%JQ
P9S/eI GSEnbDwb$y^i&BQneJai4lLGH>RCHaFSB&9$5l>QEWW$N4hdh#T<nqw!c6JMajLjpX<uSA+ZumF&jdRd
X8eA^D KqXwXpBY&y1VKMFVGwtC%SLD6/ck=*1SWV>^?iZNlmQ#P^nw#@kXnA1WqILIXh>NFK&qc:<9:4!W$^Nn
TBA5>m *C?V4FeaPTaBKAjX@1lGKl6VTT@lpLjPBE>p#?!WhZyqNq9bl5=$qG1H^DtViK58Btiwb:X@c+EW&yFT
@NQqq* VTMmj%Ya/:#^C4D/$bldRI&I@uJ>%DiZduRkup=/SptK*FCRmHYYy>^FhihS:q8h^IQaK^$RtiQLj&FP
qnZcFd N=/=V?kF+ZRnwHPSwIZ9PVL9?ZA>uL:/Dt46ENu9PAu+$Z\%hp9<PEl+w**11Hca8HY+Y@M=juD^Db9&
ikqBBN Y+W/eVnM8H!XAdwtj8Pu8=y*8j1n<&:^h8eB:ZGAcIhdYb*u?1jm@J:M+*?HwH>cL&Wm#8EX6ZT<RMpP
!^P#!& 5+CZGk/E/GCAWd5E=GHP&jBM^<+L9?5km>@4<5c#MtC<dMw+ywqmqI&k#*+:btNP&nP#X4T:aw1KM=m>
M9w$Iw VG^uedLw\Zt9T&/YSi6w9uwjI*W1@$KyD51$e9<Bi!Be@K%QHRJD+\IG#wd6WG<H8SymX/5VWkeb/9Kd
ZuQlP& #Y?Mne&SA8L:GFMp>akcGTecbbBbMK\W#jQdX@^TKZV<JlAXc4V#yk?yK%t*4u$\%R&aP?!PqZypLJJT
dhtNX9 kFe4>bP1L/k!QDVwhQV5pkcIlqFb81F1TaC=wM8EDl^<L>iTDmN**Hu%i>B:8pHhm*^IdB:1XI\%RdkH
&Zy#W? +!?$qDGK59LXEHVTebaTT5*i9my5?cuPPKy1cWeAImtiS+<&EL=$mjA@8qyh#d@ww^5cL*I^9cV^D#^C
AEThQw nR61uKF<K?tdyytEaX5#w14k<pH9#EuPXM5Hq%Bi9SB$8lM>CWiBNeYk?dCDuWl1Y9Tc5TiTSj>=\EBQ
y#jhG: P!%X9Q8yeIY:8tpkHqH#!+IK!j6!lC&I==5/RppNS<*n@F:*qBAAF$#@%>ejuDki58wt>8aSu<&%MTu/
-AZ%Ii 000938a611e00110333 Page 280 of binaries1.zip
W!&HT\ N$Lj$+%&*WbKudphV/XFccN<&V#Rn^MMVqHWVFXRiee*Su<Y\!l>^LpI8&lql%b1&tJF6KtbIMlh:/Tk
4T1C8p EMj^/P^lZiL$RNb+h9EEatC6I!Lq?L><Rd&=&J%lMl::Gq8y1GyC@btWC#qde&@yY*\XmcX59w#ic:Pi
PuGZiu jDtwYRhVw#FCF<kPKPeCDHuh>5<n:Jd##CRbl=<J*#JMMRK<GGKH5F*&i>FR6!#Ae$uSXJIJb5&6JEB^
DH/RFI QKlAH++1\i*lTt^d?wn&SI<+Eb#GCSVCjjd*>QdqPJK=>5YbGd&J$<TwMYeW+jbdbKK55A?%STMEA6Gw
d5l4Fd m*aS$bkdthwkhZ&twykntaA#N!I<ni*pF&GPPEH/RN8?Re5A=N\P:qt66Mqu+hhYt?*Z6Jj6Tn1mmimM
$QQ5yl u^jImp1HQRp\#ma6hbcP&<qhCyhpMM6%RchmlFVCmM&h9qVIiNPyV9INA#4:!tKPu!t&%&ti?bijP$RB
d<qR8k E?!6L+*PZ1@cy^E%!H\qj%F%IeZl$SBhB+?G$SQ:kn1<\1=%II9kRHI>+y8cM4N?uq4+\&GKQEu:E9a>
bMcK^? ?ZjJF*k8$Z/%1?RBdy?96/$NL6AE:wZiQ^uu\QhLEDMja*9Z^c8a<wpjwHu4%Pt\GTJ%P5@q&qMM:QXa
ZGKyH& 1YJH1bTHGIVb#/AyFNYFV9*eXCRQQ:&?h+wj&PH%WyaNLm<AFwS9iRy\KP*Z\5WTuXXut>LnTTZ4J5VM
RFmEkE !HP<!GMeCHthj:c/\/JZ/hYbV9/cDmnh<RqJIi4W+B!PPKdFdPR?>649=n$Z<:uA?8NaQ:4WMRkGlD%/
*qJ?C8 6i!QA#+=mBlpP@d#Iw<t?@^jq*L?N+wWe!l#8&Hj?X&aR<&N8WcLZm@K?&%qYQ#>et!M/889&HXEqkkD
dc&BMl ZqmQynIHBL%#Tj*wN\4eI+#6KaB8@c/^Mmb!Hm:BkFN14n!B8*$\aE*iRjnS^ReDPnNZkl?h?SI\IIAH
6bCjVZ QLZ*/m>jQmE<Vk\W\ABIq*>Q/D@K&eVD+hNEq%B$=+d/8#YQ*/&Nh6?N#DWt+E&^pmcqj^MC5FY=1^M*
y@mkbW L$W^N<+Z^atteld#+ApTBSm&qSm>/E4CENH@%IY*P$>l8bd\ZMJ!X:$!cIP%Q8SqQ+#P5h%WL6c$N%6n
DbFit> 8qT??D6?Hp9SmLXln*TQ!E98pE*J=nu>%AW!c<RJ4B=D1+CN8SMt%SGW#LhE^LG<:=<JucE6ZTmJL:y<
=@EWHG RtEhWJ%=EI+\H<*LJ\T^IHa5pyY@?u#uEV:9MGm6PVKpKFAmBcZcAcD6/jFY+ul=QYZiCpt*nGhpFTGG
Zj<YlE edcFa6u+ZJF+AN*unRykuIET9j\bchAL6R$^jBFZ:i#5beh#HkyVhYN4MjjTl#id4e$Z^B$C+JpeF+eh
!^ADE\ AX>:8@8Bp:G^n4THt>>?+PIEtj#a&Xph>d%jY4!JZe*I<GP>8@m:w6hFu*<EQWk?n9JIIiu#>$=ZcDil
@G#En6 GTC=J4@jL:6&umA4a%6l/BZ\^hXCq=%yZ+/56dXPPP<Qb$\#KttaRjkKb:GhWm+ZytKKMKmpWjnZ1TMT
n+F@wC 6IXl\66c#HKk*VkIuFP!?&kwkREXAYBA9FVGRZ4ajZQPDia:<jH:!Pi*5XCIbk?@@@qD:IM8&u&p:K4c
+jdaIt nN@Bt6?Y<1NJVQ*uJe^91\9AAI&uWI8JZLN8^Le6^Dja:>w4Tl>uP=%k\GDl&JYiBKkcDmSG=XB?IHDq
SJb^GY KHBP?:h%?kiSl6@p8*^El44L*!5u$?ZbKHkbE6tA8G@D:u5ijRm1^ehbi8LKVehI@CH:9y^9l@+#FLnb
WEyhKY :5HQB</duW+1K4wRaAA>%ND1qj6dEK#CVRHZjTWc6h@5A9M%95BPqLwDu/j/p8m$6iSdNkR!TwwCWkyu
5#b!P/ qS+uSZHVm+Hp\n\=Ib&+<4MaFWYhEDG5t/cduXj8=^>m=H\l@cYwiK#E?DRjakbMaq/=uE<%+:aZ8PbF
S*BH#h Yu<VjP^4%:X>hu!#&*iH+eiMNepqTXNAM>i!FZ><HDEFLIWWM8@ndWiEB^Ic+mpG<1SaqS9/u8M*^9W*
hP8kpC #TMVlYmW8#m6/l+C4&t*!M&n9!QeMRRV\u8DAX8uqt/cZWRTV*XiQc@q!*y5a58PNhQj&F:Duii9H@V!
@b4>%Q H*66I5n!M*mCG\^ID6k/8j*+/NlDWh>QbwDW+SI:Dw/j*TQuZIk:*Gm?pH>5:RcDW:cu+J:dly+9RhYV
9B6^45 jy%DV$FA@/ik>CC8<&cFKTV>yM8u=N=55hui=dS/a1?B^B>Vuh@+SKGW*9TM9Qd!Yc:/hN5&*eZkSI$A
+IK$lb S&X1nXkQ<in!XmtIZDSY9!@V6!LkT$!b$V>jEG<NFmJ=^1wu4pXkbpd<aVXe+/Y*wVeF=4=AY8lMu$BK
:WTmGM mlR?bjVn>N5IM6w/Saud9eXmK+CunwQBt*eD*bI+LaZ#k/u:C@%%nmkWB!/i+*TiG=jCKF\#^#*CpP5!
iq9<:i ajju=\\#>%p*!iYWDT=:GPIyWYQ&yPuaNBSRM+14tqR^X*Eu*!PKIIySy>5/d4KKLXu*=lciDiD$TDin
QkhmSC 8EHA\8LatPAq&byi*#lZiSu:=Ry\Rn8LjkBcW+aeb>:YJ8+Q+k6a4$WGG#ji!5tlw5kRn**Y@i!WJ!SA
++*5+e !/?B\pCT5!4l4I4VCw*1YLIe@jD<=n*&=JBNZ9>dLHwTV:9qYA^8NZi6SEN:$=eR<?nV*l>9+w5%u:@^
#ApM5/ a=/:PES#dGb$5#YBqc1!6>1:YAy>D>u&kZWpWj^?Qu%BS<8XP$1=eyldB6wM8hmamF5ZEb5LdiC5Cqd5
XStuJ> <:bG#lDF*yHWWmJ@<+Q/W*:!p5>k\JYF\\&^*XQkZ:@l5k5\+EF4ETT^/Di4C=:cZV$9j%SJMEDh@dHD
wXY5I5 jq?>$8C/L<<SiP#jYS%dQ5$Qc9>T^9?+kQFb^1\8F#jeMI>tb!AK@h#<Bka9K<:6c1CHMeGnIupAJ%Fn
DM=G^* *WBljtc9cSm6G&MYBD<4ZCci1SSn*MRK#nM^tJp&65Y44?t%6LBAl%JI6VJ+&?<a9&J6J4lc!XV#?<tS
$iciYt i&/Pj#^!#<:K\@X@S$+&%9?de:J%hNSd%?Q^PYKPQaiyKB*tC+dMkMYDkjJZaWGJ>=LESk$1FMXGIZiq
GlY^\E J1d/=$ua4GyLc/SqaAB%qZtCRTm6S1I6&FQ95dp@Xkt%jZuJ+u1Jnlj/ZkRYu#X8VWlY6WAZSdWc?^Mh
IcZ^B9 c@?b<lpKNBVt6QIAK+^t$<\FMm*dtI!cp64Wi?6h=VGlcEY8L/TR!^a\GKJhTNWNc!aKGp$\bWn1t*a&
!dL:$Q q6yJShL5Z*Eai^8bpFt$t%BTGE8B$#L?Z?&DpTbMl&W+4^TBPpmNIy4cVTFS&ClBqB@6XPc!qH#aNQaE
CleMHh ihiunZj\i%RI#hVG5iu>>?8/Sujw+GP95tmGyw4k/MYEaC^^y$e?Ne9AAC@:wqCD9KuVRuk!MXlRMWR\
?H%4K+ 5pj^jjnRWdHZHLFS4w4N&YJ5ZIkR1&*M>BTEpWyZZqd^/4>HnKKJC?GIV1hR1/l?TYQCk5bV1wkdRt>a
l9eD*\ pmitkY9B#9k8JXbDyhKe6Yq9M&&>WSdhjq=FBIi#yEeYjaED*/:L@W*S4M*=F#1LS1d>jp%Cii/SQMle
laTTcj XVA5NlHi\^R/Mac>CyK=@5BCuy\M9Py:#lV8+%F&E4c9TKaELe\jZyqFTdB!9wp!uLtc@?Ly5\kZNXPy
A55u8D &wmtty+Q\pbipahlD+bmpLLYdN$cb:9=KL$1<@yV=EQ*@Tcjp9KC%wqtI\#SG>LqN^+Dj4M:cb&CBFML
=u#@pC $!4npw%WeFMa&XMLt6<cYn=hKiIb$Ah=4!jlWu+9HhDDK1TQbHnABhl/j#YWb#G4dcYCTb>cYLhtR<b4
>M@t?c aci1lIhECLK!pejQp>S<$Dy56^9W!!TXqG:P#B?BRRi\leFd#mKhF!E#jCB5/KXFT5E$DD&$HIVFp>e%
HSVkL/ 8NXlemRkL/aa:J!\#w:<ymahTnKC5!=Vm=!ZDE<Gq=KG#Fb1Y^iBKI/Z*@*eXRAc+?9AM^Z5>e*/*BBb
NX%ilc LRYJ/:XmDFWZq/K8IZ/NX:F4\!EM1MqJ^C&CleIjGu&&?^ci+WM*ImZPB$m1A<9DIpNW<\&nHcRR&@E!
bB/w<+ S>E48w\HyiZ:ld@Ma:%5Wl$hq^8^em?JF#qW:^#G\p*=449mewuGw6w+@DZ1TG&4*X?l*FkY&EY#EHRi
ByGBT> kcb*DG8J#=^m&@uY!SlA?=wlMy6RM\PNn+M&JIh>hctMmc%i+5M#Ca1EAuKq1MId*wSSI1REjJT!<Bda
^H:p/D <^MPEZlu^%GnS1:9w$kS9b\tM6KBElHPb:NA&Ak:hhIt+/%KHTCPT>h+:KSF?E$QkdZZSTC5:LQ?t>YH
<CuB9\ F>:HDa%+mHTB^LN+K4FhtSWyeIK!\XQ=DS^91X^u^iMCb$RtaX$1yMwneZMhWI/qMXWR8bi?H1FS?lel
PlQXl6 n/!XKP:%ISY\/E$A!5mT%yd8/Cqj?QGH=/F5iw?LlPeSRkJTAa1=JNW5IM:A<A%EEqI*cAl#m&4^FCK#
mT+/8A K+TI/nQnXMS>c6wkI?E+TBG=?1<+/^@QSPJA4NWdQ+m/aGJD#+y#=:HSb#aQkT!+c8!$?&%F=lejI%ME
et8y&K Y<S=8RtlGENq&YlZ<LXH6LdTI/9E@Au1G<pJXE?6WAL1e!BuQjXqQ54w=QZ!=q>>:/^P\GaXl@CW@+=/
*I1X9X 1&pCuXW=F5VMMZyX?cFLi^TVIW@\AwLCFhpFy1^wyjHWRL*w$JBLLNAkHQj1bFtklwWNVG>&Y$4<#qFp
mPE!8j Y5&Sia+Pu8y1ZP:6M1Kl^qT#jRN@B+NXTC*Zl<<!Xd91$W!uaetHVN5eC=p8e?<XZH/<!mKLNI9cebnK
CA^6Sd @!yV^1?ZZ+^jXFHE4$TQ^e!C#14B:TY>1M6NkuLlXV*bZE%+EKK6kqq&5a*:VwqPK!1pXR/^CpG$?pSe
Hmb=Rt &+SipZZC@e9Z$m1A>>pD88yiaZ?=hGteBn@edNKpb9&b4hPwIe8MhERCCSC=W5Y#aNNmX8dk8D$Bc#py
6SaY+n TF^<lC*W9W=FQYHdeDYF+J9^/KAG9W4k\kjNIY6QLD?m\E!9^R!GwEEi=:R6c\8SCYteWNweai:!CmRl
TR&*!< &NDltXV%dYplPj**/T!ib:I5C>/HGD&:+&#>6Wyi$XAR^4kVZ$6dtGk4$t%\S<Sh8BSXF51WNQ5ZQ&56
eDSBRC +8yCq@w#+e9VH6Y?dLGbK4J!HqmiPtGc<A1TIL?4XQtcLE9i=GYKlY$M@d!JKp\/F>!eQycWMhdIDM<R
1p@YI1 E5Z1XmTh:A#y9+mVDLyA>9^PhVyuieRkuYbqXhnKX*Xd&+LD9>LQ1kCd8>y&IAM1!JV:M9W>XwKNjq#q
hpF1wl K<tkwFkMS9P>QB6lnjQGaSCqQYY@t%R#@JqapN<LdVn%H&/eVGJKu1hYdl1c$8jqIe6i>k@4P5*SCt+#
@Qp?1c Z#&u4jjCbYHHGGZq/*Dji5Q1WKLK%1wa=tQl/FS5m8GRBj9K4njB4uW?V/KT*GeNnIaFjJaw\:u5\D:Z
h:Scbi V+Huek#hVnJwS5$XQnaY=bikMj=aWG$:a1Y<adb%l>h6*@&M#4bVL^CSZKc^Iwc$J#<eh$BGI@A$!u5d
:qF9qT V%^<!F8FYyBPDCpj<qbQhSablS/*T%/h%H?Zh<9huAM^DC$!Kt8NT#lWKcdW8N\qR\9jXBR?>>wQG=qL
HaNy4A CL+Y5bIP6uDDI/KL%*RjQ1i1+X/<K/?RR&L5KhpiDXRTV&^:WA*8A@Q+5ltbC%!=+eDccqn@Jt!&<DCN
Y&CkiA C^Z/nXZDY+wYt:i9lIwW%@4mbGHtXAbeXa5&>PNw>LeL!?GVXMI$$\8>K9M6=W*/1WW9FTBDaA89KWuM
p+^%Cl \XAd9JV\h**wChbVRhIL9Paj?NeWEjaatlF9=/tyJ4acjEl!YRT%4R^#M@N9NWaB1QAW4XT\X6%jIYFV
-A@<uL 000339f0c3b00110333 Page 281 of binaries1.zip
<bMw*c G18DdZyktWww:k4<aWY#aaN&4lEa>mE#1&1@\t<4IyDD*6wL4w$HMpt5IcLI\1CZttAA4M!99Y49#RMQ
GyG1wm 4PXNM@ehLe%S!<lJa4@SwP:ShWX!Y@ZXl\&*cP?nn$t5SXkRqljJaB\!FBR&8C6l*>cyNl^E15F\m!Im
4tRmpK >&LIF<d#^5KmadAC9+h&aa4Ta%BIu65iheBlq%APB%8R*FS@a+&X\djX=DYNkaQiaXV\MlX&RwZ5=N#n
RDZ#>k QlQ?ZqWN1V:w?1/I?&MM1ynkHnT1^=:$A*:uN#F4quW===GB6aI\/Fu+>HXK**#WY/t/*Jc/EyVALJVJ
E5=hW4 c6Pi@tZKy1y<Gjl6GRVFelP/NK<DXXqEZb*Ia^\yajM\j$b!kJ=N@eEb=Q9i#5B<eiFmjT9#aW9nR+y!
9k$byQ ZqHEYm5ddKhD4<!DDwwhlk%qaC*GD?K/IlVn#yiWeM?l!%CXG5#i:4lDK=FFX19A5lSN/byLFXA=RRyX
&AhNkH m+<CBL$mZTn:l/$e<b#l%yCXt@GalPkh$?!/d*$BLVAa*!WXahu>4ZtE9W>4StkAlthW!kK^wY/CWTkp
ph?D$\ +/k%pt4pkHQaqVpTP$d!a$cVy=S>+JQS96M6%8EFJH>q8>Gp4$+d?bXJe%ZP<>bG/JCHmCFK:JG<Z^D>
$W?#8w #cQ>F+<$j=C>ak1$I\kX@4En/#wT+#l/eDWI5qEEt1BQ\\KmRNAH5N%i*+!FuV6%FRGPRe:dVIu+VB8n
4F+u!X i=B454&h\taLweLHXJS$5CcB:jDI=<yS*q6MI*8TMwX#K1Kl?b>N4*yuVGwGcWSi*bQaC!t9p=n#Q*ea
YJ\+6Z FlR9jcm?y+5LbQI*+:@AqVwMAWVR<wn!uphH<DuZY\XVFbt=bwVnmad!5w5aW=$ADF!<RdtY%EG?cZG8
6Qk>j# %Q9l%MHjZ=4wppIbR1kCaZ4i5ZcZ?4n!McnT<DLnM?b#Iy8t\c\qwPV*\9899M^HJ!H=+*pM=@<cwRlI
dp:41J <8jn*j>yRlE*%*?NWMVP<w>J^>qb&Q>VlCJ&Fyc@yR@>^:u%j#kS@\i5mn<u&j8FNHjeQL?C=9\JEacH
A&?9Xk =XjR4D@lbQC\@kKc+*HG?<hw6q>B@@Vi:L?Ab99ye\N@Be*&5=y#@AL/=\RkH5=jc4cjpHB+8H+F#jcV
eX@y4? DH$<*L@WdD<lH@H\@B9wQ*YIj?Tl@FMB9<bDaYQljP!L*CSQmSe=PH/F5jPu#9k*QJR@%?Pj<qD?I>*e
uKDbQL d#\WN8=@=KG\5@\Ze5@^@IYH\9/:*HQ54Q@X*HNQ:?u@JBFqF:D*j#WSBi&9SJS*!=dcJB<!WVluIMku
lE>591 9DDAAFa\kB4n@&n/8j?id:9kmSSR$KVA\cINGEBG@lTV&@j@>:+/wndt:=*6*RaX=>lYN$&#%jjkpaS@
SH9IFM CaVZnX<GA#/ykAH>n<<cRRmi#N+&H^piT@Y@im=n5:jS$Bbl$b\mTBEyyGaN&X&\\\J*LVJCjGZ>^Mk\
#%hm&6 RdB9?AT=eCDn5u$uL4uCeRXFVWcS\N&uGLJywGI9C<8It4E%6MZKFI68YH4Zu@YC1wY+<c6/&Cw?W<:Y
w$4Kac LMKAbIT!/T:SpD>RGp*Ct8Zc=5j*HmRFBp@nk&W#Z9+&l=aEKmFXy@i$N+SwL9qYBP168VLFZ@65KFJX
+WSdkN ClypiyN95*1eZ5*mW:hPH#uaBip6m4$pu$R84Saph?TBY5<BV#&>M4?D%TeYmR4I196nPHDEcke6Z+in
An/$EQ EJwlqc=8lqZNEbGN<hYZ5t&l#clIB$b=\F9ymK\I^i\pIqX^G*%hT>HA$Jc16QQ6w&PHF<pE>c$^NhBC
8\aa*R Wm?KD<T5BX\Zw>kiXiVQ^KmT??twcWbGS4iKF49eGL#$=<1V@Zt1CV<ACaC?+wpGJRb@1:tbLd>q&p%R
=@+pTh Nj9qm:hkkQ1h\\%t#wW<StN@CGFWklXudF?Se5w/bSJipa=jyICeqd4%%j=d:S#tbZ*KBm>XQpyS!/W?
!%/Gtq NQY4cH\ddYYmeD!:Y#R^MKDCy@p?R8GtBMKG+FWmd1IQk#4uQypRQZtqJD\yAnR/m@*ViSa=GbCSBSmR
LIq$&S cBjc:HimCkce^aMBG^Kau<HV&d<FDSQjnGPX4G9I#k^+l^XLS1M/uWH&+&#5/4EWR:QBKTea<F$q+PGq
9P&iei k6wPJ=hbaR&LD&bwA@Ryq/=N5:d=biYDiNL?D<I9M<*QjYLSbB\85>yStkdEt?4w!nX%adSQai\?9^CP
\Y*jjk :t>?1hHPiBYCW%R$>?D:*P?P6968n?4VVMQd<N\W:1N1!lV*nCtw6+6!<J9:I/VWTWFNL<SNLJH6%>FI
?V%G>+ 8uP#!8R:6:$W\aCPiSAMGLCVCb:J=5\!ukaip/W/NKCX>e=/1Bb^J\=aV#W594A>mp^t^qCGVL=eCEaN
T4jn<k P9w?jJ8e\$yhGnD:NlT^<=!pTP/bV#T4kVV^n%5\wLQnj6w@9=uqaF4QBR$=Zmi@j1/6\QNhE+t:W%Cl
+5c<QS yN:Z*pN^m6mRn#qZV8%JAmhZaECA*$$J^kPSph+!&w<MHGeB4&/JL#FH>DE!>DTLCXJ+%wpnd>W44Yj+
>d5j1T *t^p@^WAcb%mjCnZ%lS1^ncGHIFH/5<\LIm#?ZR<bMQc+AJJ+D:Dq8MnGPBXAkbE^aIBtN\y68Db:L?J
/k&:9H =9b$G9#^\!5<@R$qbBJkIT:GDC!yqVLE!/pCcFDEnN<1!w@a\\lhLX&6:up8I<MA&uE6QR#ep9AKhkAZ
*&HQ*8 N?4#DJqR$/cQ#Xt#M6mlHwZ&JQ+K&M=Y:jRl6:9*Vl#MN!E=ILptk4?^ADL$V\eK5:eN:eS*D%Laq&Al
p^deNy y4laNd\/MFXXQ5pDYn@PS5W!B95&jp#T%IR&LRBcc>=L*/uh8PjmDhyjYc=>+D1a^NbMb!LnIaS#q/mk
A?ZTZ< pV\W1\tMHuPKZ#=$EcMJFND\#=jty8b6WN&aAmC5j>=a:@%?PqC+awwCiGQG#&??m/ihLP!?HA=hm:*l
Pe%lBJ jnwk=XitLYJ*&B>1Sb+&tFBLVFD9JW%A/YbP=+Yw5an?4t&E<6PMDRc1NWpC%>6+GNMNNb$\+4hlhI%i
RcK@cD W&tp&@NVc!HSFBG6TRd?/D\l&9et>m>#D1NCN@WMSJiFqYVnC^RH1EbuZEnq5W8PVk&8/ne@#LZwjtbk
tn^ySY JKl$AWy&$cwSj@!1&WFte!#>iymL6&KE+I6j5R:5m/I8%9:ZbPY?mG!qXS:?Zk:#DEV8k1YV>RJhJMpL
^L8ZXy LG@JRm&E/@n%8d/Kmaqb9<bZ4#?MII*SNHl:Y@Xebn?8TwMt!5V>&qJqyjE+B#!SKQG1DQ8%uN9#Tm6$
l&6yQH G$@+mMI6?qHi@u5ypLch@Me%KRQN66CWw@E<##+K&XJRpTuTAWF9bWMJHcJG$i5iHdkPn+D&1AF1TpIJ
LR\Mi$ 1NywV/#iyu==%bNyYQQ*4?Y5+TIKyYCK=tEnQD>=Lp=FptjW?QpjL%L#&m^JqT^I8eP*Yyya>cBT#>Al
N@j#tL #X4Th6nKcL8<THa>^BwZJq+i/ItHuwk@1Gj1<XupTWuqe>HV<ZJ\+k&*D@@Req8&1^G:Dn55aSBY<lZQ
j!1^hq :b>y$Y>bFQ>Pqcei9$j+FjX+wq^FdTC5T=FZpMSLD!ytSSAQ5qn5^:L=nZkdZEaJ:LTbjmlJM+@PV\CS
V*KR&B ^hD$HQVpkREYIh?@J+4^!qDEJ$hVmMdRBI9<KNKKGZ%Vnh#>+ALmVp?>:@:<hLaB^S+MYCpDA#aj^:#i
8W^YFq GJL#Y$9V^CqS6c*SLu@IbIyEK1kHumK@Eb@W?&nmK\&8@VF/pM=S^=dqW=:ZDup4k@NXM#CAZPJBdi#Y
l<MYp4 SSwMTLqn9mERPKn&A$?uknKuP4ddS$Dm5deXKS@G*=FZY4$^H>?mw^6EwEkHAFLL8B9:Hly#mK9G:PB+
FiXLNp V/<$m/#tMk9^\u:%Fk:V/S4*#X@>Bmij6t>>j*i#6#wGC!8+8ItL86kqAqJ9#:c%uVhym!\hJclBttDA
*RBN?R tkGw*H\LDBkl9ph/HJBpq*J8VJ/M#&%bS8KnEje:bZ/W^?:56^*:bEAQm8$X:88i#N?D/8hHY*4?B>eH
pab6R! !D/VpuHQDl:kEIJKBl:$L$BcaMBYb5/F9pQFm6?I\H%mI5lt&NI?ZwaQR6YNpkIKSB$Scm?nFlWw?FLA
Va=Nc: BhV?:DDu4Hita\jZ:+d#m<%4$JWCGIBQDKJ\$jd:lA5GHFKj>uLZ?N@X=6<y6nc%YbKKtTplIP%>hL:T
yXlna> K!Ab4MV^Hb@FC@c/n*:GA>\SJ$pYqApWj1tTREy5JZ#@8RqBV&&$Z8KKVXV8nC*Bm8A>Pd5*%Aa&T1?G
S#I&VD !h6>nb4T^aaL:Ri%=G59Y^Hm?my6j+H$aHei<G!KDYL?GD#W\%:nMSnA#GyWC%n+JPdupZPG?/icWBW^
mqESNQ NDXF<*?kb$QZL!iI$GbZdDC^L/:p:G/=GwtL>=1#Gqa=VbB%E:?iW5+#R<^E*Z&*=<&!$8@Y%lC=%a<?
KA?:Yk &EnDXVKqy4Ai?J5\bBIW?@QAuL&tnuQuR:mh#l>e^m5/H6?yQBEX$\uk6^IK>1YN?NJ*mmQ/dQYq@Hj:
Fq@h+Q nBIK$XEk/@SnV#XTd@T@$F=JhjeI+d*&VJ+MYBJlL4V5DbF4L1Q8lA4R$bq>AX@TXP5JHWppGD%wue?8
5^leAV t6At!DAD=C8:*NlXu$Ec^l#Yy#8w\+*a:$$WXtCTmAMpD1#XmPTA=:ICyc!@9:TXMQ1^dy@HWL8/KIPI
WIEy6m 4$j!\T!eAJh<mp<Ma8t?Xn@L@eeeduP$wD&bqGYWqm<HMueh=ChHPaYI9q!K!n5\+MQui!tuF+ik&keV
*cQ\>I yK8jDtBjCMWaqDuZ8Xtl1n6N!t#8#@$/c?=uI#m1$/cSWwR6qQ4MYWph8d=\&C^6#DTCQAZYNEDY\$W%
LZ%l6F V%q^IV58%K&%u#L1u6I@5hu5lPiRKw!\qdthKNkCl&u9!yTXPi*Z&eH#i$=6?wpT6Ed1/nCC@BBEk&i@
DW>Ija E&A8\/qe1beeAI&6DM<j&=hpWp<y^TV>4TV\8JH#8w&hVm5ZMYSYRlBD<NFItW*NQ/Z5DVC+1aB+$MJT
CGQahR VD@uapnwRhdXXA#Cp8$>WnBRNd/y+\yE$PYLJ@>\cc+wYZ!HFYqCRJNYb1yP+$qLRpCMeSL#PJHDl54F
hd#F^> >*\QuplhYhRdeuF\5=\MC#EX%@JWnPB&*X#9IaB6AAC$@ZplD5#BABi@<$M\kJJFLnM>pm@\TNDEqj/8
SI&c^G &n8kqQ#ad9Hb6+=D6DtYnmhPFhWVy?w>GDDW%KQV<cQe:*4\$Zen>*j+yn&m$NItlny*Cm!Q%5cMGA=N
Mcpt9H +1@#=GB<SW8An\6$%dhF+5/jcNci#1ZG+@ClVYylPTMM+F9\4*ql$Lka%=j*/Z$tdmnRpZe!^%n5Ne+m
J:@eb6 >yWSGPDNjI@qN/d%ThN9>hGCRK>i1B6WwN&6?/%qkK#HDuyA%\dZXE@BpeGVi@1XAmelaECk\$$F<&#a
^wPl1S \&uH1h!Dm%e6GND?DIVRWc*^F>#IZ\V449\H=nDnQ!DPj*C9&=&@Rt4WmZ>$k\FhZQi#1d?4\F>86FQy
&1QpR9 nGiG!p>TTGwwbF?\+>#RJ=Pqn@JKDbauL%%=qmRII\yS<eeXP*n1YGD>EA*&:9NX=+iWMGSe>nG4Qw6w
V:c^I& V>Ip>8IB4@IQL:J9MAN*>yaGWD1dLZemyVD!yJTTC&m+MIjBkLH%\L8c&=/4KPb=ke&IM4>SBnDk*K=&
tDT$N+ :8VlIAjEJuA98c:jlDDy$IqDNTeIiFS?CaCeY+GC<>SRtcCSF&++C<wk9eV*H6eCD+%XVI\dPcWC1ZZ+
Ru@dip #qASXnwSy?*Vm%#GVk*wL!8YBF=6:9P%qjam$Fi\m+yZ@Lh4NhNiA9jNItAAdG8H*N:nQbjS:kq&H4kK
M=H@ja Hm&<1<CyVedq!tM@a=^+dJ*HIiM9beHVKcCM^=Fn?\Q^Neja4eQnGJ!!=:e&#:Z@mSmp<#l?B8t8Fq@/
-A$jGX 0003f801be900110333 Page 282 of binaries1.zip
CW?!y* *hmHkXBejQ@:T#41lbcX/A/jLm/LMaS!pYIEWAZ%aKS+=La4AW<ZEa=1GKh5*9HV>I#5qXbMNlhJa1?<
S^PT<X A+IB8J+twP49Pie<Aw<D:M!lhp*c@j9ZJW5/VHZ&?QQ44HyiCwQwGt@:D*1eN8MYNby<yKFk#n+c\ZT/
JjjmGa eeY/Q@QaE$!R&NVq?Jh>Ju\GBmbeEX56#S>&icnL4/Cta=Z^&9!B!Ah$+>DD6Zi+?tQEF:>D\5C9Zih$
+=:?^n ?M?ZtT@hj6^6h!C9F6V+@Y*yp/jT+NuHN@MQkp=?J&n5q9j8+Z\%%GF!j9Wp=b:hN/d>Wdtd%#Q?K9nQ
M$ERaP /Di@S^9</dIb/K@FV*=Z*AI<6?i<wN9b6l%Xjqq&%99tZ&lw+?MEWPjpJmRSJJh=\QMZZ6H<Z*lF9?Zq
Najw!+ cS5CubZedk1AJ:J@GF!FHiIbXQ5NaD$^cJ:G@WYn16Y:YaF:W:@4?P=QNmD8=6WLJP4:DJ+by&LJ@4=P
B6@TSL <mW#4$jHkjhlp+GZNd?Y8yQR@Vi=PiDJ*><tiMWWDQCajuCK6@>6CBF+uKH@^E>\4Hp/Le*++:::$cbV
Qd:hXc nW6!QDm=kkGeq4WQ\qdLZ*RR%QbwZ!91pcQ!*PyH/=eJwtu:w<FjNH:18K:STJeeEZewaiN#qnpAh8ma
6T^qIp YT=\j!$n#n6#Syn@=N=6<mLe%AJn?Xb5<%Zc%WFh%anZ^?cFdTntF*hEwc=wR?F4Cm>q=+!F:Bh5m&=8
+Zb&$Z p#B>VAF\FS%jpKSQbC>S@>SWA8Dy*=+ykIP+C5<E%%y4>Q9>hc$!GSby$4&w1mN5RR@Md\+9%RZ%Zj@n
i5ZK6l ZPQ6/#>wV\9\#J:G:?dmmFe%%^84n/<9=>^&@d$%RY9/nlaH$8D/&%tDmpIq4&Ilepj$$Ga/p$&Fl6ti
BR>?*$ DQQ=cpb!y9MBF<b!dH8M<B+kwqaSKk?Cn@WSb^HuacVX=E$K=&ZNnySCH9Z#TGbmnbAYie5A?P9ia9@L
^elVF! p&t/:+8n=#1nVe%TPEMB$Mwp\wH&EltPCd^VYZVLjQJRM%Zia$:R6i?h^S\qa/jJNKNTPdVb@NyHTRNW
9wTRi= y8*%9lwb:cRBy:Ghd=q:9Ym$BaL9Dh:9%>eMmPjtInTnj/HdRPMau1KVn8?uRk:qEn#GHQ@e/^\?pTah
dimW!w jhnCeRbpdF8L&V%$GmRWLY<Rk%?JGtGI>MD5tdXeCM&A8k#HBbukV6K&KFS/9aaWX&:n%<AJcAi/>CGR
cBL@el SF+V&=1%/X6yJb9HE$A^i8LKG=Phe8Em+eEEWpSKH8k5W8C@6\DQQ4&X#9SIQV:Y16#4l#j8ecF4wnJ5
V+Rk/Q \A+Bj+Ka#X>+J:@V<e@k8XRdk:P?>1jjBLc?>yk*hdD4jtchPek8L!1Z<5cXaGPXW6a5Y19w>ehtbDHb
ckKQqW $?+:ZNCX<dL#t!AN*B+=V=Lbq+$h\u>F%%a?<CQndMu+%nikauFqlQ!k>E!bHa8MYDG=mjNkNPRVB&GE
8#$C5q q&KR$DSP&<SJhVEKXVpb9Y$<5L\pR?y8:b5Jt!Q<Tu=CA<jtF&RWl#^4>S@Q^He%FeVFw5uepBPi!ak*
!1+QBG M9VpRHQ+8m4cCE&qLdNL#!u9W&Zj%w4Sya4\^XAR14?C>=HID=ZZi=cBmRmAyd%q%&tPwn<+1CC4>M:Y
FFScSQ \k8:*A/8j$<$km@ceCTw%Im1tw=cP:eBj@W/W5\Vn%iPEtAttJe$p^Pl$DMIwS&LnIMVYpCt+LmRMMmp
b1i9MK &CdMbcdauyeqQFmT?kK#*9tIP*:C^HT15hwbn+PEy#dQImtGR1bF*\CNYA$G+4yFNW:HbIT:PHTB?^9F
BC^ul+ FbZT&TiyM1yQ<n6b4N=@NpTGe8II*+^m8LquFB#IW+$dJI8q>DQX!m&VwM//QH>9u<mY=^?Md98j@bLX
Eq>qZH mQEDV&S!bMYu:&#w!Hn89C49LhdB\k:b56Bc#qbL+4!<ei?ldVmtX&15n@VSl!>yjl?#<A&DVdL!IFMy
HueZ$N C?uWHtayS64SJ#wt!Imnh?Jk?MWGBlTGE>/ttPw8Ht!pL+T$c&h1?w8A%*VnC&*tTkVh=%IM!8\phFL&
b%j45Z P5@+ut&WuPc@>wJL*bEc%c:WL#!l=/1mp&!#KE5GMDdc%B*L6Vq=ZGal/#T\Y$><qKK8I1<R:5CRCAqW
ThaNN@ L>J+i$@YkdBpwmM/<aIWPZ*+R*q=CZW#mSN/mj#Li<=BkSe6J^M4Bn16D1T#e:StJHXcSkLtaqt?<$\^
?Y^ML8 @5iBKGGyD#S=e6IpeRXm^LSG#6nNRB!9hBwIu*tV1Kdylye&+TX/Sqypq>jhbpG^*#bDZ?ZC4l:5iX$@
K<=1jR \HWWNhVe&DiDAjGQ$&aP<\jG^@t^Y<h>6MJV!lC:^<q4%YMQ5Z=$ED6pHmi9!\/Qp%iXS<j\X8hy<u4w
6ZuqX/ h$PRe/H8B=:<=9h#PbDYZN>hikkh>ShC5SaH6*jXHyceC&8pue9wQ1KC8Jp9t=IjZb1=^?GLR&Cue9X9
hm:Thh =jBYy@C8LMa<#8yL49:&yk=VC+<#bl$\aHDt6>\hKa>V=k?4IQGT?>tR>PQ6w6p$*PpBXk*CaQ5c/i5#
DI@kE* c9K5j/+@FW<8BCWaeN<6</SAdPh#wI$h6Wn#!AXJcM9BGX18E#>Q/W9C%N*tWD@\XD^V4Ei6&4iw>@uJ
$Au>Xq \4*N+qaFFRS1KjI94=FhW*mn>tcT%^MehGbiXTlJXFdB/%P>9c5XW@W?nGti=wBuiuB9>#T=+pqd1wQl
Rq81W\ @uAG&aHCE$5\DjW11$1BEKiXbdCPnjjCPBp=V\dd#LnZ&Z1?$*8GX:#WlNW**nC@VW<tnASjEn4FQq<d
<lZeWQ C!S=m&K:u4K!\G$iN$KGCI!!XlnNdnn48@lLGwn5NWd=q^GM5*c#:%wD8@A1uQL&yWm4H%ynT@Ia:Pm%
ut</&l 54>PH%bBJ!9lY:mVC6hTyuN1y#j/SuE%NutwSE*l+:%M6yj:nn?TH>j:EGeXCCeE<luZ6@%T:>e&:V$N
PPMcBX +9\Z#5eGGwEMeSFbYQREjRFmIPJEIC4E*/!ab@#NR9mn?@i*/@Xnj:QC#dZH@\^W>Z*%uFJkJ*M%>>Lk
TCSVA< 6uuSd#Dy#=5e@%?HA5@?D#<Mly&JthuuA@i#^h5p6H&!En4ZGuV/\Jj@@IZwyY+J1KQDZtDmiN4$Tyi4
peY?wY <XPXZ$T^^/Gnl<kej$Ry>>yM94w\aaFIQ/bTW%^J\BZB^F%d$8K?Lj^PHdQ5>Cb+455EPStTJW>X+uHW
elIjED @FkSa%K#?PX+86kQQJiwA<4T/dmMaZa+WC44SFN+P%F!:La=*CH?=aYX>^AtuKuGNlp1T\mqCWX1DhNt
nu6%/? q5CZ8&?ZDm!Dd!t=&Z5qSjauDaLAAE?q+daY=i!4Ejh=WJX#ZbqNiDXm><CWk9ILDuZwWP%#l<mKlcAB
WRDKb? Ipi*@668uhwZPeZpnlXD$iS5$#Q=YY>XX1G6#1^y?t4kIRZ^+?W<BuQyjXB>Ge6pYj?Tk*L?#!8SH@>=
YWSFtG G@GuQmnh%tb?Lq&PkMqLaK9uIqatj>c6/tZ^a@Jit1DNj=Xyl<my^6#TDMqCnJW8CXul&\Ee#WIY5jPd
>c<cDn KQqSt!KNR>Tq4WbulDX5Beq4>jnA+1IKk+@Qi$dFKBVZGq\SyeVa%I\EENa/FT>YjX9BE*\JA8\DeM^c
t1S1/M SJ5^$1iIMy@\!8:I5kRBWNQi/IjXqSGpj9:DSbMi6SnA$LL9>IP$#!>#?W@=uD#jyWF^/&Pm**i@EJpP
$Z@de# uyW89?j:JG*4&D@PKDPdInNEk%lTRBCu?pLk^d4/^?uT:p5FN5h*M8htbplD<XLZJw^>\cy=qB*19QS!
mSdMn@ =16#4ecWH!\>&MYXSBQWQFkIu^*qCqnt&NXq<w%S5I=Tccd%Iwt4TcH5q@K%9#lCANCihmYktLay>S<p
4tMbK1 **aq:?Gy#BkIl<WMSC!yFL&bYQPw+ykw61IWeT\%RcqQShF&!VY/c<4V@/RRR?8a91>yHLA*k5+&eqe*
e6Y@wL LI#*Yu*QI@Fa%&:Sy54Nmcn=&#4mTqSJ^HMKW\Iup+?yiP@F1u*$lRn4duieB*WlwWqWTVdk%LHLny\\
4*Y@GX mNPp#NlKMAa&CaZ+%Gd*EN&e%eKMbE&hdmIt!&k$h6bq&?A^\8kcETNqn4W9m=E^4AQHSIcGh:QMYbN^
LKi8?p 6NGl9YjK9>hMQ<=Mpm1>BtdZ6VL^=<T9$5pKEnCqMedkAc11!m&wAtea#aE1yFicwuk+mqD+CtWHJaBi
=m:deb S@Kn?It%m8T=B$un^tVl+b!&?AuY/GtZM%wqmT<?mc9w\Vb9ubE4h!DatLH&E#6LtZTmVPJY:aFF1AnV
bH^Mii 1S45:^^m<h:y@BDN!?Qnnk&^cZ#iIe\!#iWGBtn/%9&VNZVtV&&eeRNpNP:PyVly^je!mwDK*u5klGwt
=n^b<% W<bwZH>ICm/qbkH6!\5WMm?@n^4Zu$5WiS*t&Y=Tbkanl@w$^YW\jdHI!SJ<Z@BybCF5#&DI%8*R:CH+
WQhj*e *$6PRTQ#%MBH>Ww&ZH814B@1G6?pL*$wGBAWWb66bi+m:>ZTbMdM?WkhV>:$^eLEP*YI9uTnduAT=XAj
Bpy1#b !LFHP@@a+/i!n=?ma&W+@BbB1/46KZcY*hPX%Pcu!F41K$<l6b1i\tmNLD+F*KL@W<HFy@Bcb4>Bp*<4
y!iltj cQiEbQ9?Y:!6*!:+QR=bh4<V@it*Ap%@LcA@?@\HWY#MV<h\l8?uT/XTE:^qY=@EWPBL!d>5=ph!K$yk
<DDKYF Rk6KIiaHFy/@>B:Z!bjp@lAKCAXeq!GZ:JG%95Majp>DmWbBZbiuHb8dPSmB6^GJncpb5NH:u4k\jjMy
HEqity 15jj:YL<caQ8b*X\a4C8d@TI5:T$?wRYMGAmp8ei^eLW\JAd/i?q?tccKK4lR%MLi+H+i6W&K!5!nT?P
cd4@@S X&!aR*Pkne%>9X<Z<@%$iqQHCQW>Jlk\^9M+&Xh4BGpJ4KYC4IcqGAwX#!=e?jH%JAWphi9uAyP%8L=+
XW=DFE Q!Z$&/t1PbeCA/A:L8T6F<AAly#Vy/9de@M*n#Q8RIPdE41@m1!\8W@+:VcyPkddmTAE9=*M<4>mumRN
A\:XSe @WtTuy%jm5I%=hPkyQ+VRZ?1d\=+j5@6L:Z<1+BZHI$Jw4FSRSp\NbVj4P=dCCM^?W@@!TyN!Iep6nF:
w\#=/4 VAyMd<MQSAeN=GdtamaGP<CVX8#8#^P94h5KY8mtcFH#m\bwA6WKtcBD6N!9Ne4/W8Xt6NSy1#p=l=D4
$MXnS\ ^TXj%X:S5=&@uKl>iZY+pNaap<^j$EjSdG+St+C&HG\k%<w1n&n=m1!+a&6/ADuJTjGnLiCLwk<W?RnP
TptVl\ >MG#:JD%\Gi6>M==Tim+NFqcIwn*PtWdRu69nQPuDwIiGG#L$Y=XB>!wW/:AAQjwmn8mmmVdGwpVLGWI
4bSeT< EAu/<Lb\nt!=?5jpnb=*PB!4QZkyH\w1I&<ni:Y&C^CRpyZ*J6t?Cbm#Icd:FF!CAiCJX#48VbIJNSVt
$e^+:W WlRJL&$Tmn\lP9EyE1kecS@TW9ePj>BV*EaPphZG^Ywq!?A6w/HJMyeM=Fmjj><QZZkDXN?&*>ZI!A^8
NJy^%! Ll9E&Xumue1B+i#Td!M?tZ%<SjmjQASYK^:du>*4%K>DA\S9j4WGB9nY*KPQHZcBHk!8TVQtk^=8P$=F
^6V%K4 8G4k:1:<%pIh>NF?HIABZek4@%LEb@Bp=8&j4lp*9Si&N+IWw^l5\CEibe5+J5:?iY>+:DchW%c**8Nt
1C6+Bq /XQ+FA+NJ\V9mh?S+>@TQ&ye!uP@G?^H><>lW69k9ud^mi#<t^5WPRWGdIi8k5Twu^^F>hSHDiX<HKyy
ck@8VR u*!41VVRQ@q=Nd?l+<dwcjIk>h5=Hy^HbS6B/dmQ@M&F1tIGcV=/X%9KjtM<HYJYj8e>Dp?5/!hj/:>a
Q+:u*> uj?Y?#&c9ZhM:+wL/I5!ER?5K<pElb+H\8M^@<$8C?%5&\XMhb&j/Ri>4i/XHe$ZG^!^$+#+KKVcLSRp
-AuT?X 00048c24baa00110333 Page 283 of binaries1.zip
j45VH/ nny&adwwd*a:Tyh$hed!D1AZ&T5V!MTH:8yi56P:LCuQ1aC/&qma:!5@Kq>I*D=V&uakDZZ1FqkiLJ>m
w/*Yyb E#l=lXu^HE5@mb9T?\FBbtyB:F#KCKG%JTAiKn!?X%qkMjj!!&RATT\!<>5LC/u5amK&:>LmF%\aGGVe
1kamSy l&NnFF<a8d15d5II!:Dn>:RVGbb<MMqnN*jR!=RP:GuJHnabjI*IAT4CM=u5hM#a$iY/?VWEWm&MhAD^
Bdq%p& YZJCpC<NKPQGV\X6pJGj?:ab$i?n\Edj*jut^T%jiG!?NT5>m\y=d=6/Y:M>R:<@KdZ>%>i9@AIZFV>M
$8I>uY ?+uy!@C@m=I*\eB=WR4L9!B&y^5C5e1SttQTu5J6MuqTaKX8HnXeq@51WIaebcZ^XXDyD?#P%\dy8J#$
NNRnGI +^iTHRGidFBp9a%tJW\emX:P#/QAM$lkAH&m+NML?j!B?da5A/SBFjD+p4q!ZA&8XLn81?YkRJwP4@a/
q@$+1N DwwhduVV+i=4X*\t@YbqX<>dkYk*St%*n@Pc<ueh&</Y^Pe>un@Eunbe@ac*JkT&R!??9RYXQ^G>l*L>
9npAa$ SqB&q=<>1I:>N>\5nXuljuL/Tm6>XYH1^CIbw<nWRFRJ/=l%t\ad#<ll%+yyXu>i8D&LpFWm881hyDJP
WtX5MC /RnQe%!e#?Bbhn<i*REutIwdQ$W5*h95RLTKdN>I4\VqSJX%9ZGw&j5%8iC=XG*?+>^Qpbyp/R+TahRS
RC=>mC Z&&/%X?G<NjYGE^eTVWi8:u88*bw/%TW>bawl6KHTEHd>P<IuHAQ>KTmTneK+Bp%\SEI=Gkn%XR8:<6Q
J=55bj jiSJb1wmX%X/WbyaWq!&j?dm+9!=$Se&n%AKau8mdbI^=^%bc/4+yh9#H1eKZt5MeecT!1VwYQd8BIG9
tm56QS Ly>wZm@Sit/DAcM*XP/jbwFuhK\Jln>\!^Y\8FlyN8l!CDNu&:GY:Py\A:cJ9Ka%/%1u*QkJN5/@9yYA
!dD/XN =w*?!BePBT#6y641K6l/jy@J*VdBh?9G!4ARtwk#$?!5aIZh4F=DJ68Nc:q&FjS15qIp@CHh@YXBmiYL
nQw<5^ N\lwi%WKEyhh/pEH<:mm*qmhk9JI$+eIPBK9m%/@nH+@&eF/*I9hQpWh!5RRQ<Sjyk=Jp!?wBht1n+RB
4uk:MA qSy\EyWljN>985dB!GwpQKXW#VCWF!Qt?A*Dp^tKc5C?BhuVSh>mqqn#+^RV!pRDq#eH9a/D4Kn1ak^N
+$41SC pbKiJYCDn6ewim:mJu&K:?KARNeJ*>/Mqi>:MTZd<@iPTWpecn+/pcFXNDdj*Tp9+FL+Q99lbH16FPS*
NtITpV V*kX+&9jL8DGTZcqh&AGQnPp+eTVAMF?jJ\<#pYAAW+!Bne%A8C=ub\%ua:dV=b?Q:AdH<*clX?AQSl\
SJ6TLJ eJWHBm\y#+N5^pA\9!HC@w#k8ma+AhXwW#@$Mj466K&8&V^le@/C4Z:C=99>Gj1*N@69k!d:Guk?XqLm
<e/8!t At/i@MM$B@Pqy%LXMRi>SWIWnEG+Ti%JFp&$:LLPmIMSbyIWn1K?D1cW=YKC@?JpE6SFy+d:dWQ/6&n*
D4\#Ki 8dtD8VE95hbQ#X1WX%Yme98RP?*y@tQHn++LYyZqYScnYFLKYS>P#>L\qMGCyL=ClVT!W:lH\lEcTbDl
P8Ec6q 1$Gwu?TL?^MF+8@I/&\e*D#@L%@e@%C?8G+WQNQuwWKC8hn9nRSn5F5hb:luw*1<KSFSqjAWN&G1FBZy
cj/B5= i/LjlD#nbPXY=Iw=k>KQkGP66X+JkVA%\Rpn:R&i+kl!6j&KMDtlTMjP?Cd1kLhViYIkX!G^La+F4b+q
uR1H1: M>j!XBi@mLTeBh#JaGn+9B=bBT?l1%PFEV/p!pN*6JB$WJGp\Zb6ED5MRlTEY/CpW+k:\dltPV=MK11M
IquTwX %$NP:#EtHM?B!AuD/AMu*Fw=T+R8A8THSEhN:HXRWW*t\MbG#kQM5eY!Gy1J^cDatpu$eCVn51wDF+X$
bewM+X qSJLFhtnn6pqEDq\^tSEaZA$l+F>RBILuNuNMVGe1LqIGbYJAy6p*RbZQSul4%Mb=YqqR1YPA^MBn1b+
JLnaBZ aR\iyYR5SmGpuJ&KtwdSpXGF&^mKTekCHwaR$bCV5FetPeEjNL\%CL@GaI6RK1k<NBP1wY@*e4ZMymu!
@pwRPP emZP/pVDRGaLn!<AWTm\Q!6^E5p1J8p#Y4W&bSEHB&Q*mpT\J@GZKK>*\Zy<Ma9ZD$A$9dKZ!+@m?cRX
5DTji< M&te6y:FHwN4E65Vq!9$41EP!1he@FneKRFb=I$6:tiXhlTeD/@=wHNlFjZMP@XhZHEV=Bpc<wVb+%q$
iNV!Gm ^B4VG6nq=5ulBZtcp%A#$IH+iknB&/M:lunVcnBc1C1ZnG/XIk%yJ5H98%J<S$<JKSXRw$yV?ThEW6KP
j%9YTP S4h$i:VGa1BK?&RX=LE9q!+$pIRZY&6H5mephWFj^yS<NwYYdD+6!$+CIcB9lIGEPDAPjV=#EWw@F1B+
^Fey\! b9h9DZAp#y1B=eX/#V+dVj1yI\TNmHGmPG@$NT+a!%V\=K5&hZ%*+//?j1F%Sh6YTeIJShTFMtPuCulj
nenwPV Bl&aGAA\p=LG+Biab:LAuhdYM9hjicY+lt<+NCtKCNNBAJ%pmj%!M6AYa!JQ4G&X=PPA!WSn9yAp\Hy6
Q>?qEZ ae\DQS8jy4aHkwTCEkb?C/<F:mQ<?k!uY1&QSGtLCwRSc:McC\HyK&N$HAnqK%m$4n8PeGTZ&j\1dqt1
^?lbC! F^#\u?BiRJ8wHGBW5aubaI$u&1Cmi9KL#ka&dL/qp$Sad8D5LVYPdPHWp/q4!i&$ZCc&8ZCP*5KG$4!Y
yH4/Ti %JStWR#>SySbiGqDBk$y=kVQVkadDdp?9j%/ewim8@<>RXep6yq=IKtkPIMLJnSyWw^hZ/>/DkV^IuIE
+i1+N+ ?ldd<DW^5SDAM%^wB9%=t1GNi1bb^Kt9mTA8F4Xmjq$am%6Jh<MqpY:*TpyZyII\XNJe+Xb&=ICXc*Y>
8?QtAB 9>11<4qQ&ThjARyp9+*>jG%=9iDMG?Y</I%FJ%98ubFTnqj1cWcwwZZau+iAP%QKm#uFG!wV6V8E!+kB
YDnm^K 1CwLKK^>5N%c=jnI44mYtWZFlBVVk6L!N/pEX@q4WBtaT8d=d!cTm*h/Q6G=JCnb6Z+Rw%Wea#N1mAcu
tFTEG1 $=+I:?ZT!J<>NL<4@8c^YQENX1ELG6<\ITEkehK8J9MDD5:E:4TYc^q6&RiT+JXq5n%^FK4eiemI&4i1
KV^E9@ h*Yck9:+Lb&KTHwpNLBZ5pQEJl@pA<yNcS*1GXYH:<lj$CtL%yGl>^8PRCpPGtXIV$HC1wc\+FNMi&Cp
a=WELj E@dTMKL6<jFq\J5@!<h9yT8wJXEil4Yp5a\u\nbBDYa1y1BLtdetLiTJtuNhJWkW4lAyhc^QCLSt+\*Q
q+%bA/ p8K%iaXY=CFjhCC*G1YhDe?@@>thwX9En1%w#B%Qycp&pyIuY%h%pG8bi$!lTDY>qBEBZZT@h+nmmCJ^
T*A?6Z &yl*&EW#DB8b*6E!IFQFC+Kj+1aRbZ$1QDCM!9w4=jRu@%#P5eHLd586nMVeMh&YaCFBS#uW6mPQ=D\K
iJWPEY NpK>EHQLllH+wZKtSd^VX=QpCSm^TLC#wqRW:G\AZFpn4w95by8Ta#BjGJKb=dcIh5SbKZ8@=m#YS1cq
S+/6$+ ^w>phXnNG<1yaNV$NJAmJGAh*1tuJn4cLZnpWA5mK<$aNT?NZY:j#yPeImZ^i\e4*eV\+b+1Z=Pm>lel
XyG9pM G#Ec$w&1VBd4/S&6kake%:h>CKZZ#DQERdp8en^%?ZC\*%$d94!Q=q\jCt&ByZ!BV$KT<c^9BBc@yh9%
n=8c#8 bY1=bllG*aFR*B\Yp=KuFL:ln?4*?NY8J8Pi/e>>ZySMHFVdLFlmK>kCBlykIuL48@bCH%/Ha?6tPYQ&
##\G9H +clL&iW8deuZJ&=L>nFIbhQhZ4QNBD:u^XMp*IeBjpT9=etePaw5id+ZX#Zi#uu@QXQHWBXFw1YSMtEJ
TJI+BS =Y&$EwY+nRhX++>YFiZ#4EFtjuWmZiiw>XIkVqbnR1PyVXecI^MlBE+IV\iNPmy&AFya&LH+*HknA$88
w\1l8w 6b%kHdtBPYtR4=$*In:BVT5>Tt6VcRL*e:FQ8:^MVN65Za:a$Qy+L^mW*lu^/em14\$@k=CupN:6dcaS
n*$?il *>RZ1u6i&l8Q:BB><%KuqkZ&:VqVMJNdqSKWh88Qne9T9tj?Z/e&JA>&RydL<Zw!9/NI9q+Xp1w+!c8u
@kSmWK %5p#Gn/Z5cp$bwp9LERX*y@KnAmw?T/cb^lWZYbu^M&WE@Sl8TlJ<T5\1!8l%eG<QiFVN4:4&Fl=NZ@K
ZTKhK/ NSE^:CAHX%B9dEHc1\<J>@hSWi&cX9!GclC?LHL=l>ZEVWbc4kqEX\<8ZqD\Hn6am*iwJRX+YlKt?<Du
qu8a&/ i%+mia98euw&L/yFmL8K>e$R>iHj!P:*ZhM5bL!HZaX##i+8dAhF=68lZGi\L>#K5L+YFDtm!*ithuTP
Lq<p@R k?SZItuhEpwkNI4QmPJa*WG%l1&u$9Yma6k5#F^E$\eZ<HH5H&p\<dtEFWAeaIcQC8e\/F>6K=hVM!qT
XeB*5> ni8Keu5^+G1dX:yVRwJ4EeY5Y6^J#LZNDe%1Z+W:pBS6=awWbP>%KlcmHZ!BFaCe+IJVyIdL@Vc?X@?b
yWtVmH KdiQc19XDHSqC*5%muy/lAPF5JWu$*6Ii*wZ^b5#^Qth&49Ve8NPRRlS*DHHXNEEqkmyTNIpNt&*KmbS
h5p%#? wjVDq44nkQebLRe<Qjb=Ji!X6V*MWQ>LTGNG/$wICXF:mp=%+#X!C%G/4WFwPFE?+Zac+!W1DEBZEKI>
#<c^Zt qC1%E*bZeA8FcT@>WKRkmV+C!RKnaDnKSm<yJPRj?=u@i>pKiWn?#Nu:#=KL&Xu?m>pK&hqb@=Fe#M:!
P#&+R& u!MZ5@*yMS<@eQ$h!@nQ4MS@+D9?I?u$V$@\K!^nhlc8Z$F#@R#N@T6wIP6Q$D!@ktd:Cb1X=XjRLD>D
%*<euP 5@+CtwQ:b&m&Z$F#@k#N@m9wu:WcK@AZ$EAk!$@RHL?Cb95b?qh$nb*nb?lj$dYuD9QH/F@S6ceWnu?M
jd^:lQ @lXha?Z=Cb46X*V6y:^\h4bjWVa&D5/jwH>F&b+M$l?nj$Zb&DubjwIG@q6wnu<L#jt@quwS!M:=1Lde
V\11%^ 9!YGbPhm?SYcPS9Z@&bmTHdka\Wj4hFVJZ?qe6^@^+H@n&d@b^#+9/Sj@I$DD?V+A\+<G<>@ukQ@cKj@
P!@/9F VIJ@MkD@RaLu=9p9e8C=PXu?=cIW$?wyN\W8Cq!\5JFmm!puEX1+1LETh/E/+:MweYMYtlq*j8I+TXNq
*H%H&G HwwWi5JEcVQqX6MtQickaTw5u5I=P//W$SK5%1*9QkKB<1Za9JT+$WS=T981H<\+E?XKXc%X4H*p1#R1
*8a!$5 Jc$d$:jhQ/FY#S?y<%/FDqp$1DLMbbk%Bhk$/>14!ITMH:>P%HN+>uHL?51u$>D+&V*8M^Vad1M#VRb=
<@wKT1 b1I*@b9uGk\^Cw^Y\>5Z/9TcWQ#RAE5T#!NRtETP**+n4=%/tB4yqGYDq\>VpFLXuGZnPW4Mb=@Cid6t
IbA#KC Zy@9JhHpK&jZ>/n1Q=#/%qcMQ1!EecZY4%+%P*$45ZGd@i415h^!<4y5>>VhB=Pb!<?mb>96\Xqu91h9
QacH5= <6#Db<1k?e%GWEjN5ADk$\SY>a<mFky$eP/E!q=+S=YPDRIHc5>PknCVmiaPTjZlAHRd?4RX+mhtdFd$
yl45TB JydFSM!8!CuC4cbVY>V4b6aw=Cl^6PBucK?WKqpS?%tP#Pj:/!:mTTRW:!wj^IipS+<d^*w=F\R^/eP@
Y9YGc8 CKLwlND*PY<%MneunMdVhm6Z4LLJ5maNMIptZDk<L&D#49<t4tC/e#=i**5i#iWTTE<n/LIk\jPT9VDp
TMeRu< yiL:QnS?ebh6GBGq$6E:c4F#GCmJ6wbGpmP8yFpe5it/de1ZE:dL5y*5HQ!1bdMei44Fcw$?y9q%\E\i
-AJ?*E 000b1dc09d800110333 Page 284 of binaries1.zip
KQFSWN 6ytIIkhhKWZV?&V%M^#9>HuHkkitqnI>G\+BX$n::\P8&+q/pky/ti>/QteEKauXi6G5CR&K?Tb1w<&Y
%bJH!: &BjNjV#VZRd!N?w9Tdp<h^:tFP5H<ZHm6L:yQc?p6muGJA??c*NuuFSi@MH^^q>DKSmJat*jFMX6Gm>b
4??%Ww mL*4&jLY&%huI$P?QPkN1+E4uD=><i8y>tL$QC=&+@5K=>4EeW1+*$njL5KHK1i51V+p9h&6#6d#Z>BW
j?YSk4 jb=ZhI51R/j>#1inpCK1Ptt@BI@nc/aP4ll^?59$KS^8t@BGE/&nmP<D>eeI:b<dnmNC==8?+aM&Y<9i
A=/jMb ?P=@LETP:9y$p4H^89*$?Vh\=&u/><V8$+ymd4%+RkimkZQCCI#c=p\L!yF#9pK+ESjCE?1Pm<\j#GNp
wFX@X9 h=Mk9T5mBdZb1$^R^jSXX1#J9Pq!16&5i<S:peWjYiNecXh<Dl444/EqqFc%5>GmN/=>DiI#d@Rhm9yh
u!jhe1 E\eKh6/<<N$P94=@ud#l?1wa@MWJBE+>9hNYGDy=$\E*e4ue+jD=HGTAcVH6Bp@e>iAN*n$/q6!<I#=F
paGPEu YBiA>Vkm94n^h@kP$@HDDbLEF6E@qkCKedeFbMCH=?cI59qJnjDAeLM<tCXkX&ldAwFpCb>EMjt5P%\M
bFetiX MR<b^=4B/e9LAVQpFGmP$QEtLQJ\N>VqZu=LhBCJ$D#&1P##uuDFKa4ib\Na?5k!EhC9Zwm/6i@yHwtG
1\Q?6N \XM^<IR*a8h@#Hi1<=pRJ<ZAJ&+D8nFB>L>1mV4e%QGJ4uHu/wS+@b!e##XkBJNkIH#=^hCw6S65!PkA
E>Y=c< %!wijMdHPEjGAZ<E=B@=C%8^>c\Dpu5ZyP8&d?Q1>TWqA\qAFM<VAXDlinHW%IT4q@EGGNXK$qJ!qFq<
:qqiFK batD\1?G9<4Rdw:YJ:K8/EnjKEGbKSEuaT^QD?<?b!Cb<jjCbFIi<ZTCJDX%jJhIaDH/LuDRSLj9*VRb
VeCYm$ #wC!AW5u>Kj$Pn1>eT^?%8I6?ZVqe=eS#&q5C+cN4A9Q%T:QCHa#+GcY$6jqMcqh6uTK4#qaL*nGyiaF
hTDR4m #Jhleq^<lTR<6q>aA8@##9In8Ib^?Gn+5TL4m6LTJe1\>ju<$9eZa1W>Zp1c#JLLaKhIKH5lu6E1G^Wq
wX+/wp BccP+T+NWCMQFM:+TuS1ta?ZnTTY8KdL1?#CWXwVMbdYK8i<=\*mKT8T!aW8?+SKX$W8i!Yc\k=buH>d
4J5e6M >e1eZ/6M#d/AR:6DuT/+w:Lm%j5l:V=y!qqCI\4WY5pFJT:4DD4m1#uyiR<VDi$mX&i%GB6NTD#4mt*w
9QJLn4 *EaRQRc=AQ/SHHR?NtNwJ?@*9d&&T^6P:eHQ=T#jCmqVc>*N&>+nEZIZpwTZZ@uYjL+%>4RVSYy$4=@S
$:^=Tw q6HQaZ\d*iSiQ/>ynEX#LQi^5YqlFX$6^c4K=p*%N?GNa4y>6hJGnwVK>C$>yGVZa9/b%8@=l=NI:$!$
8MP\8k b1BceYD:XBbLwJdhTq6nacbdW?T<HClFQnZ:Z81@uJhthuNPTR=XYyVYIX!<&p9T?L/mQ$#a\8\L%bR!
AA#auB q&TIh?QHwkiP=iaNqe^whuY$!+qN@udIBPi+j=w<J9?cG5*RX9n\hH8y6<X<VJJkN+mwCc89e8jV/4XD
GXB8<< PG8GcH@%D$J6VdTa=Zc&kdq$$Zh:hqFXH@IG4#eye9tma<udST#iCbB5naw=qh14bRYD^M\R^qLJ!N@*
HkcGGj +uMI>4SS9!NmpE*e%<&lQ?iiaXt^paZ?\YZiZTbQKKJ8*d4L#*B@9X+F/#i<%hht1d!c%!DEb:>ALa:^
y$LWe8 /ZuBju9eqA\h&d+ia>Fq@:6ydRh=1&Z?pm9a9QBC/D?e8:P#@EGAa==H9@Q@mkDHT9?*BDmGwRww6#<H
^FWCkD \6@&qyPnDMNPlZSq1BMWIH4q\>BFI4&1DEYwLc&BpP:84K1$wXF<#k\l1N5Rl1myTFy6=K@ImWJPcI?N
&m4F?u akRwaa6BL%#nbVFK5t+NQVLq=l5>8#B?B66X/pVKQAIJ8ktQuYtQG*E+NRMI!4AERajYqmy*>NVSKD$L
@iFIkp bZhq\yj4MaHnRnqM5<BuejMRW1kK\6=X4=u%PEXH8SnWn1<L/PZA#qjnY$cy8+LZER#GPVWS4D:6XNKF
h?NR1l XjNaFIVBhaN/^ab$ZKGkCnYKJVldGaVe1JIH&LhYF<q$5Sm:$wQ^pJi=c5K8S/<XRqQpwFm&DFZHYSYM
!A+:yc e6q&5bwhceDE%yXSM@QV6FG:$IcB?4B4JIcZLAFhqXyqEQYXT?&4k8JW\Y?lnwQyqNu!P^iu/k@1Q+&!
iZN!PL EC!/VX<icGJ@DTyWVGBNMh#Nth%EjT%aNc+:Pq^@<LFEhNIiaCaBt^S$n:j69NXY\8e/1Jk6B>FDRq56
<&\8!k E/KYc=5unlTyduQ?lTZ+Pd?B?6l$5lIPDIjHQ8\iqDeJ*8i9/II<u=MBK^?@*ep9KnyYtA6yuIuwuZHb
<ih6S= eiHIKNmN&NMPuEAp=#bMj=SQcFL<aMMn11S1Zw#*Eqm5@hDSttIkK!6eKIw6lk$@$qeX/N@h#JI=wTMj
4d><m? R#TP*ck/e*@jj5uXT+>tmY+Z#DK4n8Mp*@%c58<\BIPKA\pX!u?p\AD:=F*SXwYGW8qp8Z6=y6tHL$dT
uu!W^9 M8>!4DLk5P^VeA51DCNLW+VmDEh<AqLNbkcSk&G$mqEEK+$ZtyP>Fq/nL99#5!n4pASicEWy56P:a^Lt
Z&$BC< <6IG!CwN5i\Bi*Amea!14wK4*Y6dpE^\tTe$P^liP\BtE:HDpEt>\:ky!4NFuw9A%QKTtuIty1k?h+1m
Xb9<kt kld&kA\SISTENc5Lb>*cS^RCKIkQGlu^19yPL<5wY$h4yWLB%l+yh&9dDN5&e8QT+C&iZ!6M8QuYlPl9
VCCeH1 aDucIVN^SDjQkhbpqRlm1*BcGaFW&%&RVdySTmhp5DR%My=SRtiDVZ$:tdjLTwb8NX%TPQp6w%yyZPbF
ew1@bL caTy:CV9X6haXM41pKu*@P9X!KmM#*Rd<YByeGW!^llqEB^pLFN&hQJ^\9ySnMRwZ#IImaybnEVu=tqK
eBBp/E c<?uh+ja^^iL*dDm=dmc!tD/XBE*1e>uNhkFY1/9WA5P9^CCSLGCX?4KE#$9%>y<44@uVC:%LNeRn>XS
LKLt9j DC88@ZMb&R*ilJpHE1J#dlDl&b#M^=!1hT5+!!MVLNej\8@LnAb*&b4^8wKa1w@XJB8+M+5Du#qIKpjT
P:bdF9 S%CFR+%S\WDMPW>\%PN4XKVt^:pPKkq9m?yt*DGXn!WpQb5b%6Kyedj91\y!@=CYe#9mkP!t<A+&jIhA
%WVIcn JTGQ9Y>EbCH:lwdHYT9/HJq9F^dQ$mWmt@+MMe!4qW%4FC6Vy4!lH9yB9SnHV1Hc#akS</58uaiD:Zc>
^W/\hS +Mi!DeK*p&>W6n5n8L/@lipT6K8G%+#kXu8yW&^JEqTB?H:?I:qS8X+Ep/T=X\Qm:SASm!1MuD/Rqpe<
5iV#Tu MkDTIp=11RQTQ%/*t+XYn$GS:hN&RnQN+4k\X6X/ZZQqHm+BQp^EQl=bTaD</56?*cI=jJ+*4$Y:yL6d
nW#hY+ 4?4Y&m^i&&u$PGmjuNq?W6/wuAWaI#h:j6PhYWJN:TcB^n/djqYeY+BI@m$^b4BKRI#laaTF%W?\/$E/
XCYjDi MCaupA!BFYtwY?nG9Biu#ywJ9XW?VBKHdVLQPViSj%B\WAplp%A8aEIh1\&cdl!Qj!$<uuY^M*eXPR$J
ct8!!H w>!5:HMQF>CWCh<*j84BwjeLE6d<X/8cL*Wi9ZlI1P59kCdZ1WnGDF:dZ\t8ZPdMNa4ZlAn^bDGN$ZGS
VIInPS l!\W*8^$^:a:FijLjbVHtp=H6!<dI<!HbyajiYiL+ypeKy>\8$aj6cE^qkc56X$LTYSenJQi=DcuMIXu
Vua6N+ u$NmyK#q6DC>J*BJh^lLcyJtVWpKJQYc%Mi9\/ad*9p/<e%&T1YG&\VQIJ6yJ:RK9+jVE1e?BHeu#Im$
P>*e^! lZ%81C?HENXlXq!RQZS@8FZqi$aDQCmHLRlBWj8nXtJ>BKCak1?#<K&:\R?IEc16e%$!S9P<C?cZ#eMT
CW!d=? mW&JkuH%u:^DibF#baF6ME#Kpm&N9NkRWt+5/5&8Kw%#Ie*IR&4qkj\TR@H%Gh$%m/+C=4M\L%?5V%6y
5hRMb6 H!>dMNDe6FcIlC=b1tYqAtddNw4R6BBH4NWjS6kQ&?JZ!:KDXu4>LA9*a^w8kq6peVhFF8W$R:<a=bV5
4WpDT& B^I6aZ5pCBcEHb8FbX*IbAZbt^5%YSPQ6Rn\qP9E6VnMR^QiNITFLt$a5w4qj*AZaF<qiwZN+=QVdjd?
Hk>GBy ZW\CmphVBBulN&Km>CLJQPI+dPe8q#LJG#9tHK/Dpe<b?4Wp+^9cI#Rqp\uQXTFK%C$maFa1689u#R\c
b++/8: *I9quS9B6qGLmG^FGRw#Pkw1Z=N&K=4dKTq=%jwP9Sj6Zdkp6FS9:jeIG^GdaYp@i^*W:KG<#:9k9#PW
l4wy\w ViJ^uH^A9HJF4:kjmVV&Z@&kMu&pJ8<WVNHHRa1N1@YXEw4D!pmSA+5q/mqwMT^FeLpQG:hh?AIm:JAQ
:+$QmP kJKN#^pSaykuB!48?@=L@Cy8SY%tubiCKZQ>H#jaLRGBTh%:J&5b6lNnqlh%laAwTbF?c6GEa?MkkGpK
qLwRFQ 4+p>p:?%E1Vn*Yhj/S*>5>CtLdqI<<:5:>GuQ!VaX55CX$kEL&Q6aRBHVk4PCe!YhmSdc#CChp#=Bk4c
9i>4?F #kY\LGm&Dp\6P+KcYa#F/+/PqyBLR?QP^9*jh91Yq1yYDw+*\w9ZaqC4>#yZDm&Fb!LIQywAh5cyL59d
DMCEnj D^%ej\#:unHHuJY%CQS&RicQwmL!mpp@D58PmlRpw8nniTH/iebdXqILImHDt4KZT<FLPdV>&hJ$u@h@
uDHw=D wQVXi!9Piemc>#48GTDCF!DPiFC:^&@SMP*u=khVdVB+wq8Wb6QyJmNQ1AJ!q<&CEYE!MCG@FCq?$&HF
BaYwmk #4PNMmw?RT%Z@@DYN#6T6%BShDDPY^XN%4Sc5N*j>l6FL@Knw%NC\Sk!#t\uQ#T^WCT+qwYWZnbElq\H
HHZkW& C+yWLaydTN:H9ZYC@*mGda4ICa*B?+qEeSu!Z5kGQjNM$hm@&=6qYDWW@mPFGwdTVNnd\kKbTGTTMVSy
kR?Y1u i!Py*KH6dY#lnVYM!9!RPKa/c5SJ8Be:nMR$$yYmT%qwh<@I9@Pb6mIdhk9qH&JC4mZDe!FJ1Ce/jyBB
*wENZV PtwQuG9ah+Ty<NZHCAYh:KCmWM\K4?WN>ibPuA@I6IP6bQ8?9ed>LG^M>a%XhlLKdHkJGaYTVS+G$K5t
tk1Q?/ 9CcW9%aI:?#C@J&=KM$:hGI!bM%\tM>qb<ILbywYJ4VJ*5MA#lWXEVCPcXmFtKT*u$XX8<Ea4<1GRZKq
yt+:8/ KH51c4/bP$c9HKX9Ec^IH$dMjD6jk&/tkG&P8pI9uG*V?c*5aD^!PAiH<yRNb4nIdmwTMj$>QT8^NBy4
TFZyVL +dpmZZqL:k^L>$Fu:Xd><Hm=JGa&\&pjbb#CNN6k=<yCFJ*L?haHt68J?C@X5Aq/>ISl<d9AHZR45bbA
^##HA5 ?$<ejij%$\V&QTSC<PGXi^5kK&I&F:aXM>/8WP\nMeF/SPV1mqid*SmpI:LtXM$WLL&1dHVX#w&WE:t1
5P&5ZP KA:$\?mPdKXlChu%!kecMJDi6JQ$5J!%CcdPa91NIkB+EXmXwq=%qZ&G\bjWML=F#wj<#8iHNCu/$I18
GqwwAV NLnM@c/:??S<\R<MLuP9HZ=R8l#T&+KR@BXV&d+^5TZ#A#tF+iykI^Thh@$X&dAaR<<XTXykcA>W*8>>
QB5%9L CIGeHB9mt!JwMLhFBS#TqJHVT^5d5FpS5y+^DqG>RSkStjFGXq+WLdqE94nWIbpZWVYBW<=%^m#Mh1/R
5hG^4e *NkW4&Qc1neVHRY%%t5^JNtD5icFK6y*&j#p+KqTXZY4uFZ#L6dW$W+wn&H4/F=p%8<p5B$!#KmZw=JL
-AbpQj 00028541b8d00110333 Page 285 of binaries1.zip
j$%NnM MeNC1DSEVbEpFtW*:KeaCky?5=6R!a%XNkW^!4l\IJCV>ZM!FeWyWqC@/9@&Hj6?^Y1N1TT*/ww:5==G
W&Y:=D $\qVDIhpq&qHbh8AEC/RScqKiYn+#tWCFpeTijmKhS>KVZTEte%iQjjA5haH!wyMA!PEYFuTyelAbV?+
F$+pS@ Et/aNR\!^MdZj8%At&H!GdcHDNwaBbJ<F>XKT@AYW%pPc>@S#KGZB&dKmb&6<NtGlK8kQeN%m9Clj5Jk
6&Mtn8 C81bAbN>mD1kKMbbHut8Bdt!bEB>SJqZ=4T>QVCtac%GwQaH@6kInl\n\S\CjX&q6:V^yhSGehRmtmJw
kcJ:Hi DYG9mIKtKD+XHRMPVWuZCGF9q>Za!GWI/Lm%T:Z?dNK@DmNWaYmXDTEQH^N99/:KXG4EDBjIYujKkwpq
GaRIkE \Z:9J/*d#:kpHAh/dXmmQXZA:IBcm4Sn+?Vi5M*bHC\a^!paWD6eyA\dV/e1G46L8N6Hl@lBJPFen>wQ
=jHY?/ A<EKuuaV*Z*cDJ1:KB/:TG4SyN^RZ>4ee&n!Pi5&SyERRj!cuhk&46JTNy$c@wGc=cCdhZ^/QK5jWZ!R
Hn<e=h Zu!E^XG$jM%cNl&lJc=5byL:F+aQT5M^=4*1CSGR?Z%C<NPG<R4Kl!GHXyE85HBMB*GqF+k8CpMdF#GK
:1tken l/e=\6YBLw#6H49ywmm4:kQa!Qct&!!YZWQH#$e4&aZSPcG+5<k6&WQLn<q<aj*6!TEnae*KE$Z<ajM>
=SS1ah 8AY^8aPm*^V\5t<T*yqDepAX8@pL5ubLP$KJT@hwW+8$RYm$eGy$?BapeWXG?&le<\j=9!TVyh=5>6q<
Xkec<m ?<aaI/D=um+wpIad\@jHpB>bL:Jy<XMk:!JycEA+!8dHEEQ5Q+:q@ceN/j?h:ZbYFyI@:\@<y@jd&j>^
PwLSaV k+9%#@949:CD#e:?K?mj:RP#A*<BDj^JyG6&hw=jRdQ<bG8PujMZ$P#eQ*684q>BQ:/:Q$b#@\1c>Yhw
C5N/Ld uq>AQ\W4@pM$pPXZ$F\@R:Q?A94ui:HAZ%E&IP6Q>tKB:Q<YG9l9wVu?dqPQ>c?HWH/?1jej5c^@&>Vn
IaN%<q a98DVV$k=#?8/\HbPFn@*>u9@/G#*!ER:<Z^ahjnFGqkGL+wpwe\/ZKlNy1\4CIIB!XJauN*&clmI=+i
+yJqln /1?LHWeya1N56kuQ=\8N&lM$=\q1+a5FDD1SNpRdLn>9Eub%^$cMG6Hj=I&y^Y=k*eQcP1FAln1Kw1dB
nt@N/# 5/<wZ1?%nlI+SeLDI#e8SP?Hbd/nkYH4Sqh?HwJ11:9*uuSEGn5$RHB\Y\F4\8IXLF9cIuy*6I$kS<NE
FVd+B5 m?KMeA!LtYCW1w9n68I^Nk%9DHan=FJIGaQV1^Aw@!t&D/1!Yqm#Qi\T8Gm5*DwC1HYKJ6LSJnVu??4u
S1%Z%# &CIw1pJmN11wiVDc!%N1Rj1<H/DM+Qk$C:DEJ*n!pmQWyVcDJIS:ctiqXLlXWaCeKEGDkp9#6wh5E^1K
eNA=DQ Sena!D&qZ!ad:VQKl%V#@uIi*NbcnI6XJRlAJ&>d&<&1Q6&Zl+kcn%I/PeE/K:9CLt@tJlKXB=W>Jy\e
ZeKMhy Twp:hTq/Flu!9y<M&?SmZEu\!*wM^iVEVdkk6=kcA*AhCQW?GaX>+48YeDDPN\t@EAlZEeEtN*1DQHu&
*@kZW> $hTa9uS8^SYPG%>11eQpAwtEnT+^q:!?h#8V8VAE^SFXy4#1FkIN8LDMhHtR8Y1Bp\!lmHm9<E!JHjR^
1wPBd9 NFh+ic1kZAwp?iSk$B5kaK4+iM=\Iqt?6FE8m<Ta=ABZ4P6W?Xlm9N$miX&ji:<5Fd&S4%HS9?Km>>:t
@!8/S^ \VMS9GyA!TWWm$qSmXFhHl@hBlJFw\pXKJu^dYk/>d1l\cVRl/kaj!1C&4>IRHXj9Na>1eX&NyKI=t6/
/=VJ1> EFAi*&mXLjMJ$JpDNS1l!/+HGL*jCFIJ=h>?y6!ckGJ4mcu>Se?Cbq#k??mu/b=BA!w4\e=CWDa8XKVX
8IZ&R@ RhbhA/X$Y@K$wkpT98dL9q##8Bq<P/d+%^$tk5%S/&&P%W9nZdmtiIbI5cyXRmpE<K1#PR#EP6KpK&^+
C+eIje uGPG=\uB55jb%hQB&TV%^=cX!ynNPN:6BKPWRcX%QyRYT@=^tm!Gi/R\WHD&RapF5RyD?+lMRJyF1CAn
a:>>Fp =Dwea\b*:c<F^k#INh<w!h+Hq?q6@HBt?JRq%CD:%TTm%BR=wpaCZVB*IhFX&c/8C1nC@Yt#=^M::ZwV
&M5$WG 4G8KVR<Tn9qu=DH&JPFBAqeGi!PCX%LZbXAW11t?w%Z%QRBqt$*&LhWKSCW8T=y5<9^#a=RWWd46YS!h
B/uNC= pVh9MV\D^H4\WDalWy\eeWk?N9jSFw1$RcNF4<Q?TKqaKDVlQL1m@hAaFY=8qQq8&ytPLY:uy5h:*N6F
\HFFeu :J^dqT<l&&dRtZSFht^dM6iAt<THjZ*uk%Z%b6c:ThTaTMnQF@au/TERwljl&GQWlApLFiEbqyZwjLTD
W1K!>H <C<i$EXWySDiI/T?XJN1>1yVcu9%NVl>Ndlj!P/1T^#Qit/5#eW@5l&#B@<K\ikn1h8F=dlWmWhMdl6&
@?WmFD mDW$S#N*Cab11XpE@ZCGwHXK6nESe\unPGZJqZR&Ka=klJ^TuQC?CJeX4T!:JKNMdSMC!<c$4/>1XWmH
=?kqAh c9=H4Ve8h6LySb#?I*TF$<?TMX9t?:jP/A4IGCwp4Y4u<X*Ikq+TPmZa6VblciiK?D6Yu:jV>N>8LBJ<
&db@i8 i18LPba&kn=MTDAVuPDW4cJBI$Y%*YBXH><@WF>tYtS!8SLD<Et5*GI88RJD\?AI8puhlRE9mDG6QmB#
SWeXAd Dydt!8cwk5p&%=>*^F#EwI1!!W:&Xw^#h>J!@aIYKB6@@qJ>kJFGSq>LL1XQhwl#jm9wJpybY1/^VEcQ
FEG6Gn Eh9B>we$h>NIFd?J6:!idNwZMcRaq^q?uAdu<5XS*P5MFY<6iWu?+Tc^X+k1F@uKyh8wiSL/hhSNPH/A
Rcc4I= ZM/1Hj8e\8t6Cn!4EyFcRW^>/@y$qVi\/+%=\dKnBGcp$ZQy>:^bK!>ISLpn$w#KYcGZ#%Y!m?N+ab@l
an#\N! llBBpR^kp4/6n>8QXnJJ!=kSwYT4QWuCQ^bXiw8EbV^4FGNBF=B=u8//nyCD>ELp6W?<*5%e/We&Yl6W
yRwA$F d/P^hdaw&$tX95YRMM/aZbMC:pthaq/5d&peYt!DJbAqiVHud!6wcYq#u5iRCRWu6&5Da/D!K6>>jiWA
55!dBH 8^S/Nc=1Jtd8KhLPNTDwewZ9tSh>N41@LWq6L1A/*kFw>h<XFMpPh9y<LBm+=KTIpVulnB$EPYWP^q*e
Z$$F?a G9LGJ%AlwESDViJhTdHB:b1GMmDabmj6mLdtIK^<++bnQXN:4qc:kN?G*+QTQTlVJ@L%?FPLtd+S#LMQ
eZVRK> p=W/ih/uKC/KQ:+&KGl^?SalKawm\jq!/EAF$I?^&D\#E\#XWVA@D1EeT/4lNp\pTMpyji%q@8t!^$/p
D8TS@= Liln:k^m1:KtJFYhW@:dMB59pu#11S8k<Vw9p+H$SyQKi>I9Jn#Xb?N=$$L>1:Dt:m@%R<imPMdQ9qHq
DlwQE\ E*Lql$qpl\b=PK5MY1$T\BX\jaC5X%kkLj<\LRT*nd$!qVqTCItcZdcPy1J\<LGwnC9nc&81wB6l61G6
Ay<#iB >YR>9c=?XTpjY+a%8iZZcLbT$lV\!58L=mLXy9nwXF<>ebEQ1WWum6?J@T\9BEi&qWZ<I1hAhmnd&/!S
AFuN@@ @h?iKW5a#NX%Y*%KcdZ?@upXq&K<PpN64d4<9qI>?jWee%y>/H9nQleG@P1Z#QZ$=jyH8IiY*>*Ypw/K
6Vd9IZ wtuei+lP%I<YXluV>YqN>t&HK5/j9ZTRIFcC@jdT>wal6N%H+nTdYcbN$iwcN>Ti8D98\4an^*#L6#u=
D&GuIT >SHm\WJhichwEuAS!Vd5lNeCWZLMY4:IFNXlc&GVuP%%EJ>uqK6XyL%XmG$u9SqE!cDmY4euM1SdwRwW
KQ%*\t VCT1SVF:pGLN$Yl+LN+pDTQE\JT?uBppGytGqGPDdYnWMSbp^c%Cj/d9eYTqwGtq9&ZqKPyaL*KZbVe<
X9XI%Z k@?A%bwH$$=%qGP*\1l4IaY84L+=ZLEm>XSNbXP%a9dipcN1HAhmdj&^liN\eLCidY:*%nW\4nyW4LQZ
KM=qeJ pTLIQHI*VnVRnKb:TA/qhld%KD@8WAKqWqW@JyKuhp%j%kq=XJlt:Fcp=Aw>6B:qY$9ZcPeIC&I#yH?#
YGY?eD PMBRi4\IQd#Ia5@SW9RYQm=y:D/5iMhKPm:k<BcIFI+<GQQ8wNw:TD&=S#Ckj/hpHN5R*6GbS4jwIGd#
W#69j= VD?WZDFITkuu#NHiVQ6%PHJM&C%:bMMRwuG\yHe!jHG=6LEp1@IXE^<R\%I5QyBH9yqkED1%Pw$>^BRa
tGh?dW yQ%%D**FW9yHLTy4MY/SbN6Z\h\%M%qEkKC/wQb4FJLW5kcaAu$^?caKiZ:$KeBAHWnceMw5bGElLB^a
ek=9^: NEHVb/6ZB8!p4CK&MyW&$%a<y!1nKNV4%N/NpHWjwc6GppbJ+FW^9iew<TSNRPdaF?a\4Qi5X>cmV>@e
It=Z8$ 85!w#N#eFTKu$IV9uEJJeQchI5kaK$^Eb$GbC8&WDmKYNWQC>Bl\V9qYVbWY#!5W\!K$^c$\Dm8m*ASp
V&e#dD ^M^F\TRV=a/uk!>EIT#EHM<:Xy?Tc4P*$*?#%y$iRlNk48^NHe\=+VG$uiRmRXm\&<HI1IT1lD*ST>EV
?<@4T9 Jy9eZ#=HY!yJ>&wti8jN&54W&jpAI8+?&=F=uQ&:/4eMb$5P8=Ad\=1?XaYPn&QIt1umV4ACqQcAQA4S
W\<\=u i?&PAt=PFiuEEFd!6T<wqQ*P6G$cyhJwNJEJRY?JST%wJKZXCnuk#HT@=E<\mna\Dy!#=MNTmLTVG=4D
thLBEe h4NRRm@ImeDVl>!#dH=+Y<SWJd4tTH$AH/LwbR&>8cZ/lXJcec$Z6X+ZYCC9Eq+cEtJ>lMAuddmGY5@p
\LAXMk n8X1SbNhYFn:mt^JF41NKRqhXuTI6@5ib41clb#mXT>mpT&/ERW8dB!8$GqeTD^p9lLm@YndkGP=utMi
yG4cC4 Sk<@EkaSJwQ8/CTNFj5^^1n&IM8+?^T*bJJ$pPMa^mVlWQ\LcBR?qWqp:dn$+Wy8D8a^XQPFT<cyRA6n
HJ@?c@ *V:AH5%=wK6/pGQ@!EGWbJV\EIMuIw\PIpYEDHcqbJm@bV\?WR\=wB?W%5D!h11?cNmeK^cpJ#akDd?C
CcTnkn <lqbXQSTpeI&kZ=DXC!l*8ySDWVD!&<d5E59cd*TSYSnV#k%SLlnpw/Ta#qS&Km+k#R:VZqDbYck+SQ&
:/u1^b EqmXwWGKc/Py?+4tJc:cS%:P5<>W4b/SBup*GH=XIPeYD/FC/hFSVwbRFS#lWYVaWF1yw6=+Y>w?V1JE
G?HwNy =T^<9<@DRcFb>%paQBJ*SZF1!\^FaG<9blNnn@al/jQiiWX=>hmc9TWw$R4=8k^:BddBuDu*hiLGPu&\
iBLGjt DRL$^X6^&<NTC=j:i@Kp%:FF+pk6aBLZd=HhNPm?5JB6ltied+FMccadZ\XdhERDKMl!&a:eXeV+#CYZ
iiJAmi NGA&:DlP8BTd:EZ+Qppt!w@:wwRAY<d^mWIC8TL+Rm%P6VcXFA$uuM<YcRbhPR/nVSII:KZcNDFAmZ&L
pH?FL% yuT=I?bbluV>RuGB#i?F?PL=nXKIIQIdaJAXW\!Z8T^/WZMHFTVIw99LdjiLPE5FPM@S8DlL9<@XZw4I
N6Ri&/ ta5FTyqw&Jd8Q\@P+WCS%t^cTFGI5T+KaPpLMn5BBViF!cun!MYeG*^Qw#$qkA$G\qiFMW9K9$pau/dD
4WYkyu aa<^Ihq6P9\Y/W*h@&d@G?n!p1eu!T&SL<lckG$ZPI8YG^E&!^#Gpm<miDL1Kq4y?Pb\G4%H!KGP$dIJ
KFpM&1 !RwZ^+lmH4/HAapl>\kVetA1c8BbkLV5?Jcb?MBM<ECW6yi$lZka^X=DMt1yJ4L#46Rk6YjbEew*XiEw
-A%M=8 000ae9b4d4500110333 Page 286 of binaries1.zip
WbCL#Z Qku$\kD/qGEMKBWT$*T^KtqLVbTnYAbMAyS6W%m#CGRuItb=d5ta/5^JppN+ck!8/=Cph5*eDT*pMbVt
:Njq!/ 9RGApBl&kZl1l9Sy$4eKb+NJ>6jR<$DkAm#ett@VLmi:D%\C4l$Pt!c:BkZ$A\&:Chtt9n9uQpY%LH8\
w?:d?^ G4:+BGwFJm?i<KF:&!Y*w4e/6&wJiXCBwJ:/maQFTelqKm:uTHk5B+?JuHYct9Ze5L*HK?6KQ$Z*tYFK
X/S5Dh yekY#PAYLu+PC*9*ES:MCNt=e*Z*aWu:b44p\CLkI6D$lj>kcJD>dXLui9V<HXHL*lG6wq:<6i@c8t1@
b@C>Yw Cq/9eJ?X$nN+=B@lD#lue#\F*BWuw%ZjbQ$q8RlWCI8h>NXpHi6NBI9&aC?5!$65/J<:8a8F8^/<k#TZ
bHdJ8E =DTS8qc6X??S%1<8**@P?k=ZhiJ%tL@CaAqljN5A9B::\cRSS<V4yFn?:>1?w//cQJ\iFNu9KaDYRYpw
+y@nt# jS49XCe!YtGq6t$Q#aCy#d*cwcum&*4/EYICFXGS8I=NCI4&+qwyjayZFA>tw8ewuG#X/y!/6qA+#%/?
:*\%>& <9@5HqV>p8!QtWhA4u?=FQ1jZ\L>>VXP+B?pb&Q>^#ZPu/^TAuq?Be*%E#RH!!?kPVl@58#E\jw4cCDZ
Dh6L/j V>B59+Jt?^tc@XjRLD>DA*<BDiV/!hw8B<i9wIE@Yb*q+Q\F>E@ZX#t+jkH>$@XXnq@S6b?9pHL<m4J^
1aM+%4 5j!Ey5Q=K<4G!9PVVIKe4Q@Y9hu?LVV:9+WG@qIZ@hq#@+1!ej!M*MVJ?Y?l@+8=XIF@bqj?u8+I@A8H
E6S:Fa =Bjynn#ej/a:<9D<Lh$S?Ne51*>dY?+@!nZ=y+j+&a9/NbwNP\<HCh9nM#&SkNki@*/Bb<QJ<#>Xtejt
N#pQpu aPXlIYHub9t6V4>RF!/YQ!Ap<VD^MLF^e*G^MIqaGnt/tnp#!SubG%p<5bL?Q?#>B%TV@b4&DhMTICV$
Z@h!Zl Lm1>E$IcAXFD/D%W1W499aPw>A:TRWCq>!+kICK>k+A$EbE8ZcTJ>Z/*i?citd$*#MM#?=u*@hb<#%1/
E5utt< Xlc5Z@L*!wEZPa@#QE+XK#<Q1LT#JjR9>$HQ9++y8X6bY@*q@dc+?GVT:+FA5d?w:@eqE^MZ9>A^^j:j
WdAT1Z Q?d9m@pZFj=i?@4:6Be=Jj#9q+mKZeB4?ZNt/4jZ<1h?@?==#<nbRYJk1Q<bQhS8@%N/1Ei=!\SLJp51
Z:Wbc/ Kb\9AZN4nFtXBD4#AEIWSL>?6b6l5$mAHCYcRBH+JD6#BE&CXn<J<ZCjCGTqbJYcpw/6W#JY^4KFZ41W
mpl#wh HT>Y=X4^ZmV&GjIbcIl&dAe&ty8lKRGwt!KmX$hp46$MJT:wdbIDB/+la%i\$6hnpjMhN#Rt^4DQNV:*
iH$Cw@ Y:/kuA!wj>E*pBHLY9TJC@8\RnpQNy>n>1KaK>^8$abAcT59?HW=S:CnwNBEeB*L:D:65KAe^XEDY#il
=YnGbR T41<=qniN?dJw>StWF#6C^bKw/u4?R=^l=e%1IDTweeP5Y<iV#VwdLh&Wl5L/XAllq!St&JhMqJDj8<P
S%^e#1 <hy*S&yY\I!XIjV4cAmm=>luTMcplJ+KX4hQV>tl/MJkacH+q1K1!a6PbyG=Ca6<=*Xh*GHmXw/t=:6D
+1Zkni T\EJPA9*J#jN:cydGi8N>YMhp@6l:?MA#Til>GbC+W#lT/ep6%u\d*4&B88&pu<*aa?aCyI>QHk81F?&
8y/^XD TqR*!eB&$t\!%DLbd@G5b8m=&Bj@&Y9h$4KcdNB6\^WKHEZkwX@H>q&Y@Lplc&:t>&M9Ii%:+:iajDR8
nj*9uJ ue\&96Ni8QWR\HnW!YVl=#<4cJ5%A+ahnqX>j4+K>wa%9??\?ny8F!JKZ1T8j#yI:X=8e^um?p:*=6AB
+#$>R/ >euQPXjZuC%1<HQKu#mQ^<QHipG+HN%cd4VMWe*%:T9nW?@&:bheLL=ej=>y5aQk!Fk=t99SKEi9NhHw
%Ayc%w nL4b5/mm?hSE5SL#^>mVy*=85nEBGD:P^bnJ:/u+%?>Q+BEpIB$^Ze?T%Z=TJ5!*tKl:Fy?TCJmPhD=h
dHc+&J G91Dpn#nFc@ei6>MnIIji<QSe*unuyClHBE%N8:&TSHC:G=lc=hn$QMyCIBF&q=XhB:?Tl>B^e\t=Ye%
AJdRiP <pHEcn=<^9+!RESk/:yN++N*ZA9K=TM#An#ki8qHny1:DR?abp=cXVRhuSQ&cIQDDlw/mMclJTacEbc*
:wc<Eb M@D#b1416d@py>/RtF5/^!iC/@6Cca&IC$L8LDdKIFMJVGhcIwH&n$takQQkSIiK+PkwTIaPdX?ZA/>:
YE+w+y L$T*iqGcCS^1/:9De:Ptjye@^n\!IWu5eTY*IP8:+T!99VwEL*cVthMS=%EnDi1W*^apqK$Kly9eG?a$
H1uyBM EPAEtYWMJFb\uXaRbRu1KA8^QBQiVL1n&bYnSbu+TL^8?aMFLcN#8QV:$lq&5%VJ4&+^=6:1waK:M>GY
*^lEcA +bBTTkt@/V+/6y6Q*kSN+ikF4n>J:uZinG*El6<\L</\<qdGaZPtd/^i*8c@^+5Y$JAW*8ei%u\Rjh@n
I!bWX* tn@b&ywp@XQ&ZN>K9=>RciY>QAmdGE=bD1WwP/NjRtk=$6DMGANVl#q9pk\nj=%TtB>CK+<B\RVB^5QB
cV5w&A BTy!S!&VSh:9bbTbAl!h&E45C$CZp?EplN#mE6we+LTjhFbVHG@\*H*Z/AR<<MQnIqLQGZQLJqn9ACqd
u6IXX$ ?byh:?V?qI8C%#eQ/t&S<d**5/k6VBA+8mS5ElcuKwl<Bj*w9Y^uyieeVmm5PHHTK=VjLn4+yPwq88:+
#=51T4 hw88LhYVePt*\Z*#=Tt1*kbj8^/6N<=+LtetpAmQMd?XtlY#%=FY9<KX#8C+48#uHGWHLHHR&=:DcMC5
1/@aEa /yD<DtY9=m4:t*4tdIqIP#!IVS*9njqKq8FtL?NjZG%FTeem4Fq<wLR4IwENDy\P^T:L>&akHE<Y!+\e
#>q\ty cM&!B%!1PAq1Hi\jkm@Z9#!qDL^#/ZpI@d^8A>@iE#VuW@GRS?+lVmI8wme@$mjlhM=qmj$S5IXhuy>6
Zc%6W< ZlCShauic@T8W@5mWX?Q/^9!Vy&e&XZ%L4hK469=ZQb/wN:Vk8GLDYmuiFHqNB+%ctp#QT4&&MXh1Ai&
+blE+Z enSnLXb\DR=pLj!kI=RI6TdQ<G\iqTR6<hYNpm#iBD<NajC$DTwD/WYMtAc9JPAyNaeFm!Yh!4@Y%:1?
R/8CH! 5QYM?8qZJw!kT^m#6Ny8:tk4XcF<%BB18TN^5=ck#=\mShPCa&I5%$p5n*tWJYLa4juhDyjhRF/NqPYt
5IPe5J WdqYYLu8kMD4QqlTCF>hnWdn*inFny&KyGi<kkV<RLR<C<*ELQY+5KN>YqSLd8M&RCVIw<9>G%TSVG4a
=kPS@P ?:d++%RIKDSh=huV&&N64P?5ui1t\ueI?Iiu5*QTX\5kXFqtYaCk&yiX/*yF&:bAjH?C&QjCRJqAK*j/
^\+@>e PNmK?:dX+n+iynZGL\Mm&!Wte\&5ew@R>Rua<m%HJldSiX&VhENVA4<DTc%&Q9HEXJ5*Ii+mjJQ/6dAk
QYp*8K wk!4CB4CulZn?VBVl<<8u^aA<wNRpC/V^AbbGcW$:!wdl/jC?k>Rj$e@cyV8$61G<\/Gn<!NmI:1?l8\
Y$Q8iJ NWNd&8&$y!RynTZTInK&E8SnJc+Qj6/+lG\dj!5bK9qSji@i=<PmJMLPGlEF@p:WL%X>PmIh+dp4le9j
Nj*S9V qikQmMIBe+?9jtu:9NBM<&BB%PLtKjFH<dkb1P1%u!*:X=b<X^W$Qch%Z^%iXnCj@qYw9lA5d4RSSM@p
uPG!He !b^uVb\4e9Mt8*<Ah6&c5u^?I*HZ/A?9\B5jF@!>ymViR\t&J\C6jJbRw?6l<9h1^P6=S<jjZYi1iQCH
l8ck5Z R8<q6l*I*TGnV*G?&V::ytqG9EeGqdt?6Tj#tW\RVm*<*W8#>HA!mbl\qi%KyX\V+GCbiZe?8M+Ge$e+
eIBjt1 \:WIbLwu/S<*h!C!?KPw8:N!4*l>XLpc+:abYdZYP#h5ZhcZFql&WNH:/%tBEIq!Scm>q5dGtFXj$wSe
@/wpi! XYpE=%a=TDNPiFC>$V8/ApjGYe%u?>T?4d+euRQmIlPe#CnHthp8Q1PY4idQ5S1CYWMyDZ9WNeu!%GWI
X&==H: XuduHPK@E\FTFkKhj*LYT>t%ywc/Gm5&/i#*S<L!#F*$KVjc%cnu=8T^K6&$P+WXDZ*Z\D66?bH<4lXE
WS=k:n M8*YaRw1XE4GMPy9>Xl4FY^9$91NnLE^a?\t>YeC&<><qHdl>hbaEjq:XE1mXBBM@pN>Zb=8T6udB6H/
BZHDSH u<pWd&*GWN6LWFj&WbFIBc/n=h%$=Jc*E4tA$EL1/Bn%a9^LMQFZwtykR8G9B@\=N6^>nJ<nZ=Ze:/GJ
eYjT1n 6A:FkleHnd1^8DW=ew*+&=bhAJwG?6&$hyIFq=LdG5Y&+N/NKyh9V?SNYCNWH@MwkjN?6JH5PA65XehL
:KqD<L Hy9GEG4kI^du9RMu\ENA8\Em:^AGAuJdTPiS1F8pNY>Xy\d@\pAn<QY$e5/kdQApjyTQEdi+Z9m4*Np=
p<qdS4 A8TwGn>=yF:#kKykD%ykcLic*8@:aG9=+Y9bX$ZGY+YZ8JV5c#bMK\VYC>!%wL\IwLQ@%\NXEy1C<B:J
IS!&&q n%ZnAJD>$?lIEXthTZjMS+Y>QhKn#KVLFIY^c>bny^VR>64?$/V5Vj:aa!YCRQdlZakC#$:<?wEq4n1j
ISLn@k Z!G:By:>ZWN&p?<Sn/ZP@R*Z+%D1cL=aFSu/wTJLeKGm^h/VTtC<<6+TN*VC8>?QC?1hSK9/5eTX58/Z
W4^jDu !$HV>*L<#dF8J+I1t+i?aHtW/EA8VG!%QlpW\Vj*nHa$ItpmJGIa!9hJBG/:>SG<4WI:Vnp*6?G:=&ka
C:c8>H <nwjPcaXSp*MF/F1/GH>XRntX*VkV:Rp/4=5dJ<ZEj>W6QC>aD=#!PkVW5ii1/?QNn^RVK>HHdd<lYC9
tQiLMN tBZuIa949!\I\Kch@RtWI5Yu9^J*wLLaATE:Lmj1IGJ&6XyLb?$&w<P*JAX/y+6aCB+wWk<pIdqPRDFA
9<XpG! KM@&W6pWT4El\<6hS:KDL:WZmZLn<\V?!thlLc#I@S!bS!=5^Lq$k&/NdpMK%>:d@?bAyF:uVZ89Cj@%
+ti@VN t\Qi9u5*yhS<D*LMPNYCh<t$!jyVwRMu8+ehCISYJG**/c/!6XI*nKBwq*a@p8T6&KkLuNR:5wV*eK>5
?#L+kL =:Wetu%IRqS9TS+NI5CCJ+418Hp48*e&TXZWZHet1B44EJ&hLwSTl+QKY4#C\%wyhtRc1>NtA%KN1>8W
h:+ju> 1aV!Cu/mbYq=JJ&ee56qNZ5D5P^A#qXXd8w!1<1dc<YE<9QBa4K1KQ/8:ka6qKL/MdNHA/Y%bb6I*LVC
X6:b\a #6mWldpm%!m@dKTAnCPZp/P+dIa?<baE%@/MXw%>R981W:AI$SaqRZ?Q5:Qey^^V&bQ^&1RZIRV6uemZ
Y=yESp BTiR#>>WTKSqC6#+%t/MHXhS!tuy^8F%h!a+i&^uSE^Hiu^8!TaAlu@emMeKlpW8^G5KEW*Q5mi#W:a<
//6j?$ EnXRickNHX$E=\#BN:+>iF&ZAQZ@1AN/IQSYii1Z/Y8>BETGX*JFw6XNWhM8=B9wyAi==EM=Q9tHIlDX
?1ie:B 9GKIwp81KVpSGPwjQImG$/yaEpjZ<Rh?LTWW*BFR/QGebX>Z#=96qtH9W<AQ^Rc?<\Cdpqw?&*B8KKVl
N4QYq@ e/#4P+tNF>aB<G*$<uDJn%iqDZKa1bWEK^n*e4@DKV\Bi>jc<^LcDme>6^wdBEui1\m6Ed5EuA:$IPpj
?>cjQK &:89Q6$TW5lkZW>k5dnup%b9F+HJ/Pj<bS*lqLBn8Cdp4KKcPdp9yH6R@B41SN88NSS\VEWbMyy<LeW#
4ytu+# EGFt*ah&dXC^:N+XBi6FKH^T4%d!>NDBE&^>i!nuSYEjXPXuZ:+RRa9NiKlQ&bD!tVa$1CRI?aacq=QR
-A/p?^ 0001d77d7b400110333 Page 287 of binaries1.zip
9&MP=8 >9HZD1Kkw%446D#k^QY#8j5n#F=AM^h:BCP%ij5kJj&iw<^HDc5+>+I!mNm*J/1h61XEa84BLn^ChN!h
P*d<w@ S9&ebwLdqQK1cd!eu!qwkJd8Kt1++?=%=?BFm+K8B&=4emK18GM=JFC>pE>jba*Tkw@^9t/XGihGdh:T
EHL!Sy @TL<@mqnA1>6!>AjQ6*499$jPS\CyJ?QBZJd1\c?D+^wq&Z1n\Mq8ZD8Rb?Q*B8MDdKZCCtZp/9*eiiJ
$%QTP/ W^nb!84%6P&?Smp!1l:VbX*1cB*Y<yZZ5=YZVPhn?:&mVaG<SYM+&PkV*8L$cXBaY^^A64YEN&ij@nl\
&?yi\k *pbyDX!F5c4=HJY+i1>yX4*AKuahdR6RN=$Fikn&^DI9DCp6G&5aAJ4&wL/$6:h?JSM#4$R:Rpt^NkQ>
!<k&km &1j=dq5iEVP<B8:%!w*aL$u:8:T>Z>KL:m?P:nFylXWdd?/><1>:E/9wJb\$9?G?YEV:GIYetQR5ebHR
+/:nKB MHjj5jPnjGh:ZT\>^%jB5&/jSY<1%D=%qh9KqJ?**XHucA$^tnXBC:SeB&q<N%>:hcq&$\K*lYMM>6Y$
>^ECBH al/cXcFJTW9M&JTX9qVdp!Tdt>Hj?bQ!^KH1J!KBP<9<bBah&^%4+iSu?HY/It:ajBlAtANYHSmYmm1q
PAN^Ya :pYj9Jnih1PT6=Y+i&YG%EuqD=uGBK@%dR+8H6DGhTM%NWh4cX9lRkhm:9qAN\1IP&L==Q&8!TQ*YwYN
5naXq^ b>jy*@lS#K4b:6Zn66JL\@EDGe%\1Qy84dZtp=hSplF<^y?hY65FhQNX<&TAj@q8!4#Zm#TTZ=q?p@Z?
=TWwRT Pn<MqmmCS+ycZH9Kq&9>1NMXy$Pb$%+G#1ZGZW$pV+DWK895W4d^#EKL4ckNM!L<H%>=dZD>DW?Jm@/n
NQZ$jJ d&%*?u@hchqKX$Cubh/9wJ/LX&JMeue?5p:%JQhMW<w9Tb6N9MSR<#DnEc6QuSy>k6mN8KcWl$bE^%ue
8a&#W* n%kn\pSG<AdZI@J@RFQ8$akEG@XQBqP<B8u6HEF%/j4bF+5IyIupT:wILG4!wnu*H1wM*%t$eumh1&&*
!aH%?V %%Bt1B1S@F^k<jd#@jd8DA6TcSy8\cd+6HEI*I$quJ@4ABHweB6*Vc>F@/d=p=tSDT^=/%9kD#t!hWwc
Ad9A\B VyjmPiAR4IKuLPS6H4cy/Y*QTem5q5Z1X6Rucy!HZpm*a\b8Fh<>a5j*Bb8*qWjG8T//*q5A/=wHR%6y
<e<b&J !k1i6Za?L1h?@lK%9+@Fk!mV\GYG5ebci=V?pbSQ<%uXdue>d5%@*@A&=Wi:tXSpNdQAT#Xi56kp:\TB
NJ9pQ6 6ZDiH<$P1:nm8Ij<LeM1d/Iw*Jw4mHAMk4?!k\FWti*J9m:#XeG1dI$9Rq?SjBXNa^L16/mt9IHAWb<#
hqG5M1 wCCP@Q@WqSM@I/D1H+1*=:y!+8mL$Pi=e8LmF/HF#mucm&M8RKMp#9G&^CW8Ry@unGFkF/HQe<a\alil
A<<!tu +ijS<I9R5QNw^AXw=HpVF^npSin#Jm+\F>Ec<n^HEHMS4THPe\R^F>Hc:/?eVX>Ec+n#HGDMSdV&P=j\
GN<G$6 VF4mIq1Du/h#ma6wDZ:i!TZk@^S>Ec&h:<JKZES5=:1SE1l@mpd@W:V+lT:dPcq@Etj/i@?=EZ9BpD<W
tCkEWn tl&PE9<Zj\<6eSEdTELm9?5\j*qtPBLFn9#L*>>u?q?j=X@<yL@J>Q9Zm@1jYqJ@V9#<%bL/%$nb9*6i
mBB4Z> 5VM51h>DTQ>*@Pi@c@!u/@@<?I?II6*1L9jRm=&D14%9Y1#lHc=&eJk\c%yS&KB@Zk>&tKCWSFw/YIYW
=5PlIc WLYtkD/CWCb#BEB58*ANw!Spmkkqjk^mCTQG#MQmE!t\p6$ePL$w!EwCXnLiRqmZTm+*>49C\IyDC19G
6tDFP/ lD<*LN+=\Z\td8W!+&m>GZbnjYyJ^uJNw*aK9ATw9MebB+C5C8BjX>%#F+?9u@IhG#n<kj\+YP%^XWTp
M?qJkb 9>P>5=1etIA=jK9F?SLRIhA/4l&e9E9WaSc!JDFK4Y@nW=e<nJcM%W4Aw:WcCc#p^SEd&HGEG5t9MT1p
p^5ScZ Tm4E>Kn?qJ=!FP?mW+L^@LaJ!I%FVmM+Sm@HL99cT6P6\CdVSmEbKkw/y1kew+iW+CH5>M4MTMm>mYbG
jFtV:1 yVkAMi1aMX\Z8=&^uM>4b&VtJCK+9PaWj8t!1cGD&qQ44@MwBw$GNPLSTw8<*\QN^B6?QA*n%k?Vb>R8
CkQk^R *dy5CiGjSh5!aN?ZP<!?K>11$^?i?*M!!YqeWm^neu<IXRu<pGV^#6SCS+\GLHB#QHMK$t6PR*H9$b&:
inu\+u 5Y=<Y%uQWLt/I@i8c@hp5X6BEFMMSG8c&ju=Xc9?P#4M5>>eXAwS1t8Z8:hH:tXNkq>?pEJ+:^iLDYpG
>%Ky:a ES\P?@1?bpjF=9idFIRTKa=<SN+FQ=E<uQjTuJ=$jSZCcNh+&Y#P?cCtlMFX+PWTwWu%#/$l:S<b&qFn
c!@GDA ?4FTH9ybIGRMIR%4lK5nDTlYm=^GYY^Xl$JZq5DdiT$uQ?Ikl6*lGVJBtdTbSHI?S:qiq:CSuId@lw%/
CWnHVi akGqjR>q4l#w6EP=SP@Vdu$XmZ=<WAyWFnbkIVYXeyBT\SK<GJSSm+G*cY@>eN5X=MuKeI?B$JMG+*>!
>nd56d CGuHAe###RHW%pKhGDldX=/PC+HAq%jW#ybM$iDdpXLwWqp=b84NHBL\%+j<&4jb<kQl<Ywwnb4iK#u=
RKiHdX MhRTFYRj/&:h9JL*L6QmE=1@d!*ylC8j$56&ES%M5FGdE$PqCchW+mnmnEqX99e\J*i:W1jKWCQK&ZWk
d^8nEK wLpK$K$u*VIHnBwkTEtbNp9&J^eLHHtFpZ9HPqPn+/nbD^jk$RwnN4WKh:9?WZkknulq:wy@LM>V!e&e
chKRX# n>Nel9H!@6bAeR*c4l!:#NJn%p6l:B:Y=w?>6*K8Tj1yGnI&P^wJ?Vt4eAIXk6\@pyAuqIh\!4dkcihN
EY/8@# \6EQemJAT^*T6^DeaVhCD%QCmAP6qP#W#GwS9y?$n$^pdIQTe=8Li6uBjG:>6p85yDw&9EJZLGQX:9AQ
uhRmWq 1DAQttXKP\EpMKRdn\6*:CKR:C#ZZR$X<Vp!8R+M%Lp=C=iYXB<>hI/qB!A!b/m:41I?a$a%9TB5T*qQ
+R=Pe8 EWF6!kQ?$YWY1i4wyaHI=+MhPwtY*PlNpTeC<mSF$kRYWeymBqN!PbHbB+uBDRc#Yc:T?w<iG+yV5MSX
6+=<n% b<S&hiX+!8:4%8t/NwEw<ck$>l\wWad6^>VHn5+VGiWly9cW+L9?ETJHnhwY#GC8c+i8yZdj//MjcLJH
\n$yV6 5wQw*YkAwJ9+nVhyD\eJ^EpNd/iY^q$HA9\j#FuNGV:N>NI>+8D96@D6!D=?X8L>h15&8yNFB4\6Vmya
kZch<! N9Q^MtXGyk1TntFV+pT\P8haNT6F8tmeQ54dNwBPw@:4R*u8mwYK+^^?JqCt+c*q^SXFyAqnjVK?4kRp
iK#FP8 TC&TN^ci*=t8b4X%EB/5=X#SPaMkaXClm*T#bk@P&41<=DeiWXL*<pbDjLFb+Z:Wb\tR4nZ/hTEna*tT
AtJPuF Aci=FJ>?^lNBZNBDt1uR:+^=LAP!tt1#$kXFhN5YI=Y*\1p:58:n8EVEt>#!VNlj/IiM^XWZ6!<&/<!F
\6QC#j n<Q8mw5LY:E$!PE:LRWKHJZFNm4p/Z999BFHNjW<6Ec=%!bci<ij?p/W5m*&IPc>Sq*!mwVFZ#:6IHC$
GEmJ:w <h*44%9>uq6QJD!C!WJnj:#Q+FdN5Z:#>X=+55e>R+jJP>K4q&>MtG6X@M^68pZ:l=Z8jHcq$$n+&/Yd
i<LJQp lheGDB4K4<9=k!Y48=Dl>aH5EGF#+tCC<qyEjJBeEDeuK=w*ad5LdT6jNPN+/&uAHiDV<h:Pyw&^6<ZQ
du9AHw XpmWJGWMEV>JC?PIBA69>jT^Aw\QQa=I^&&j?Y!!JLW>i*Qd4=ku8C#qi5GJ98\e5Q1?a6TaDRb\+wI+
BRbDBu dlQjeu#5JK>V@>ZpLkCS$9j5KBuXpQuTLmP6q#6D&PQhIVqdEjWJ1/%PR5ZuQGHbZ:Y$q/^I&JLcGtw$
kID#n5 B>@VM!\QY$5&nB**#BdDTJl=tN1@i>hmQnAHDBF:db>T>/4hHyEdPHw6#De!NELKcXhta<QbH8$&Wy?#
L4hL/$ XlSTJQa6j$L*8bXqpuy9btQYbI1+dZnA*FQ8lNmJ8$c*qnRVV/$EKXmN:=GBZ$a$Nh8#9&JGn:t#FLHL
5!NJt: &LT@CWAwI\t#F:\eGX/Cl#kp=L*i%bDJ!E$S<S+KT=dZ9&$cbH\RGe%$c#\ayLBc/W&S>?Vl+HlcJwQc
yNGc!J T*cNBS?e6EuGd5CLG!m#T!1\RY$BFJ#<YW9S##eTN8XP6*Yc>a1tR+!j&>KG#diPa5YA&yy9EY6^kTm@
e6=dXa G?EG+kGM9BacSb>9:IJp6CGD*Zi!9$lPI8T<QwXh@5WdelIRk=tmPC1Tbj//@88?cIF4BXD/w=R!D:n5
*P!Cle >cA:n@56Wt94NZ:N5NQ^6TMLpmLLpN5&9inZZh:lD$iIqiIQR=<MY$8JS^KB&Sj#SMiW4R9MX6N?YB$D
1S+?*W NB^L\\LpZT$NN1MZ=I:e8nD?P@Njljc@JyBMJaCK66Pc8eHLIeK1FYBeaIGiBd/%uM!PVBBRaq8qmK51
G6RT+^ $DPNVLN$RHauXJX?<6eq!=MI!W=WEkF6MAaZT^pwN!wK#we9hwG6PFEP>KEjyY4\\\<KeBbn\:/4#pF4
G=lZy% ynw>&H9</6ZSw=%^E*J&N#w?Z=HyV9ASwcB^nAGQ>Z=!TTiAM6euJNY9LiRMX:kMGe:GiL9J5+=&ajY6
p?$nc< $YVl4A94Rk!>@ElR\C*wTbNwhqENlD!&pqAk8A*t?KM*E\R\wId^wlcZkCQCHub<JAueJBDu19A4aBm$
?h#AQc 6i5&m1RInMeA1Mn$>\$Aje+KaWeDu%IJILyMLnqN?=VTyw:VJFikaLC=e%64iZhDL%lS1L+*ZLB=C$=J
XL&+!m E&>icK^St:bBWa<1bG:y$bI6/8+Xwhb*th/kG5/$!@TIcH?^d1!b8Qi/j+&VanliVjmBDMb>dN%4+Ec$
kR<&86 dHC<R:%qmDS*4KI5uQNnNILhuhFmk:Km&IKdh?VK99@8/%?9lGVw>6li:ZHjL/Q8FQ\&EF*XE?+cbW8G
piNhl+ TM1I=wuQHiBhDhNpG@h558mnF*9LNPmcC/cNe6eQI5btF1X$KZy::iX!mZ$Y*1\J1LNmXeBnXN$:S\LC
^I>&SP J%k%T!#AK>eA=VW96PmXbJ!uQ*J\SWi&$AwAijqkR9WThjLj6j4+cB%kD*@E85aRCH$qmIpVPtk6Nm%y
J64:Yd !L5Ja5iV<?F689qEE%a>XmRw1$$w6%=SCT9YPp\Eq!XXdLN1J9lu8cH6c4c5lZw#81R$I&*E><NLE!a1
>tQlaR D4YT&lhR$T9kIRAcaG*V!$jSLbY>>cPHlliS!Ft^VdK1ZcPL$GDm*Elu6?RCnAL#JkYTt6T:KcWZt:^M
SHhVEw 4SFkh/S&WcJ5t5XaYjnwCRK*CN#G*/CRZc1hh6X<h#&ciwT9>bd\uD9B+l%miVi%>6qKuH<S^4^PQb#W
n+nCc< ?E+9*yik?=HaX\A*>%FpaH:P%pHECK=pVW\\\+KGSKcw!k5$KBEu4E8*aM8HPRXKKhqp&5c@=kXeaw:P
Hh$DcR GPLCAn<qaT&wBSYQAP*&^15#%$%NQ?$c:!N8Et4IHu#!8?tb4GV1!PXJVE?Hj1lcA8>Tqctn^cqZBK:1
S$BmBD cLpqmCQW>Y$>k+8/ecFyh#=cy#>M5BhaAEWbQyGlF%^$p/wuKM/^Bb1/1/mwL598%+Y\A4FcwMBJ!bY/
+jQ!=: c*d81qm5q*pGZ@/\lN$B%GJTyNQ$tqwwd$n4VX%BqC=cK9miTmwT/IZlN+@t*!K/$X=A6t^PRyAman1y
HZ5INH Fl=<*ApWCM\pIYmp!M5AB=5de^=4=V%X\1%npYty^\uj&8&ly4MeBEZC8Q=4uGP^c#YeA^5*Bubekn&B
-Atj/E 000cc51cdfa00110333 Page 288 of binaries1.zip
KmQH#X udISuK4yWd@T!pkEbTHZC*hAm<F*bE>5R4MV/STnF4QJhyZj^J<<IhjmwKy\KRa9p%6kVW*dIebQhay8
=KuEly >#X\%m6/DERjKtEjCj?WK<ZiDWFJ<+ZJ8*@qnEn\AucnQn+TnRl<X\SjL&V&E#KP#^uBejQ:M9L^Y4h+
kaSww6 /&umQut:K=aqVDNd9L+1b@upCBS:>^N/y98/&ei^qJ=kKGeP%QMF9&81cjiYq#&%>ck^V6$>\NdNKp?9
RBH%$! E/\A&Vi#mb*W1plVACh%<V6*i/R:8J>\189h:XKMqEFIS>yG4q?F4tC/+SpiE+YPpcXkSX!%5H$wQ*e*
8W:Ad6 D\wM?1+d:>^jA8%G>>*p!^IIpRyqhQ$1uFi@ubDiM>>MackXu&$6mnh*Q\An?KQ*Qb*14q<NpSaXX+N>
\F/GXC ek^VpBCdeMRqe&h>bAi#n+Llt<IQE@J#5BVeMl+V\mPjV6EH9X1l!D9ljH\Xl!KCqhRcK^At:c6nCkw#
leQFpH Ju!*LQl8!RJAZH!*ZIS>E4%*hqpGE5#qZe&6/dktin@=<J1Wc:9*DPaCaV?1l#F+!WNHY@&HYHh4Wq!I
*Imtt4 d#nR=h/199i&6%jTn=@MSE/<JIBGbw*m>8j!^1l%8ki?4B=\QJ:t6G@dNcN/WK@\hFkp5MT1aEIy@A&@
%<j5*Z WCCXZtcGwtX+*X%AlC<Z/kFX$nWG?&5YL:VCdk68Ht5VQhCYHhjP8/PZb<*dEM?F1+Ki88umpmP<nQq:
+kekJH J1GyNuwN#8!/:kJhBJVH@mRMD@SSEjwN&d14k%JiGVnjaNXk:*FW1YEu:VYBZcPBVYPmFG+e<69AD#YW
<h9*lC PVRccE\Q89NqQnt/9*Q&YG:mNIGe^wGZyJP96#KCHjIXLE+8\Vb4T1l:k%hZFlm%d&V1aInyjBLd@=R#
t?N9Hi qIQlVnlZp/ABn%VuS^Weq6&q\5n1V4IMNd@=9LDj=am*uGpwncR!j>/9Yp<N+E>qyyKdd%<#WIeS:/b#
BqFjL% m1hI&CS%PwM6mem\TeLL$R>^w?RMk5C<WVJ5Dyt=9QBmPMmelSFAq6WiV+u6yPKp@4KWRMA!p9%%nICA
N\@6/w taW\kadq@iP9T+@NHn%l&cBltYbbi9SW+9my\R+L!?iujq?iN9@^%C!R<NHHJ><IYAJJTFmyu5+SMBPw
6+apaQ W^yi!9E:IMCiAnL=ekLXtR$Pe\\P5><i=4QCCXntCaQYutbTE*=hy&aqj4IWiDZwc<+*#cehkT^jQ#?b
PB@$MT 5&d=!%i?tdK\R9JdnFtYj4F<8%jMpWGa/Z8F%Tm*udCwudDW:+<C%6^eTji4*!4L9qWZh!TYQj4!&G@:
15DwLE TSBLiTcB=Ne$RkPV%M+#b=V?ycH?@%^ep#k:E9d*BwtwDy^hDId<4?R$IYGI@?Kk\L@GR9*NwMC@=hL<
b&EJnp b+MC@#IJ<P?dpQ:&PQ>aIj&ZI@/NkaI=8!TPlKE8R1QQw>EZwSHwe&n^m>Bm+8jRtA9RKIu#cItL$PLu
yy5\+Q $Ge5ZV1Dly%#%e=a89TQ>G?%uE*DL$Kj?>1IC>C@Ld&#/a6w:jja%6u$SdV&P>D4dQwmYwPjE+?GFL8I
V5*/Z& %u/Zw5?tMj<WjSG6uY8BIPEZES9/uHR%JF#5RpKHu$QDL@TYuWhjSG^\DPae?mJmP<>?ReI9I4d#>wMl
bnw6*! +SeSG?Le%^d@P+@mV@a@<!n?dXLt4^+FCu&GS@Ej>^u>t$ellwL@#^mdTj\jM#aDLQuYZRcEW:nHw$j$
Bc/\AS HhnD1h^hT+KWP>6b5KAnID$=l/I=5\\?y^iNm+X9W$FyA1:RX>Xta/ZmD4H+LytaqmqRQJ*ualMaZ>Al
mjwk\X EpaH\+8F\SiqScDE?wNTwZSH:C&h+*HAPCmZdhhNDW@1PZm<SWaZTm#^\JwLYQ1mj$^Sw$=CK=#nShG:
pL/G8V <I:5+PJB$J<nM5wVTjXXYCF?QH8Z5:+tPy\nAT<J<+cN5%ZSyY1D^kl:Im!:bJ+BL>WtllHjiJ5\qhCk
KW^A4Q *$H\:6I:wdBZ=tE$55*wiiwN4Zcwk%YWBZlI$RG$AN66RWQRhXPPS8W9C=C#+p&n%GyyPh5&SwRp&=V1
l\/1hw FJaHnA6j%kkcbPtS@FL6a=YJumdye5BZInHi$9dG9n%Dh8?bwdhp1=5bZq6amqMIDyYyE^j%pcLITnl9
J^<yjI #jKKKty+?A++4#4<?Q/w5/bqP&?>d1e=JQ/p>d8I@pulXIBqwp:D*dWP\I8WCXdQd&nnY#\9Mtdjw8Ki
y%Wa*n !Z8nYym5Q*@9$8VVE%F:1a5!$tPYhQH+1B<&mk6ep+k8j&!m?*wu**D/>/\RQm*D5N$$8/JN5qaueClW
<Wk+tp Q!ceTRSGHAJSBG5VYLK<#tiYq4GI>SRK^uXwYEF1mEX/G*yp%MjjX/b$9u?4:bA1BiBNyil>#EW4Ydyi
Jd#<>Q wc85^bJ9X8Kc>C*y9u8bZk#S<#/>lw@e>JIP!6KP=D65VSl\Vcn$\#qN*GVL+e?/YZ/a6FMB9#jFD9bu
j\EGYD I6/Xpn#IpjQ+Te:qSdQ:EJMHhV$F+eQ5@M+Q&ZLTq>8>qTl8*l^<&!hW*Fc6%RRZyXa/yK@B$!?^jni1
G4ChE# lHn\FDuP/C99inwwFcV%ImQwbcm\?:HIt6+554Fka=u&AYqpd?N#e>AaREkyBw1hJmNm<VB^$LyMFI/=
%9j+pA p%C8GRYd11mKnA@nZJTL6HNF%y:iupluuakCnN!6bXaCWBLAqW*H96aV$J@iIX+IWD=Nc4NaAF%X54@u
%@5Na< W9?<h4Z?l?1qI:\VQ:^=6u<1^*DHwCwS%MWp^#qp/9Yky%eXqTLBuh/qHER^AEI4VDi8EjQG1RjB$u%<
ZYmenc b=<R9\RItSN^GKlc$K/YmbSwLk@qGJC6:lCu&bdtF9b6VcS>hbWnY=J8>TE/VmY*q=CuicykebK1McE6
cC&Cb/ <CqY4Il#b*?t!RY/N\lqu@ENJie!jpV=>t=i%IS^l9%Zn\wm5\mJaTM?qwRuFE&MNYNhN%VNb/WBNa#<
IkYaZV p@Zd%IeR!8Vtca*t5Y%Cwn6J!i>9=mVkYTjGE$kIyWX+BwFGi4nPy&=8/Ay?>mbdE>Iejl*P6NSc1dpZ
Q:SRCK 4SaHe^Fcyc*9KiaaXIRdW%YuZatCe\SDQM!9yRGQ!TnkHe+/BtWb^*ZdnP::mZGJ$^!ik*Q5AD$ANjq>
C/5aH< PWEl:dI*X&>96HHCi>991FT<M1u#b5+\pB#dK1PHVHnZw>#j/k1?b+SE5@iISPjNBEXQ+D#6G+8?t5k@
AL&>RE Du$Mu9yyL81@V!bE8\qAwy>!jR6?pCS<Yal>@PpNTa^liuN\Mjwi=:m@yAXFCJ9GR+k9c8!V^GQLDj%S
C\515/ #!dk@q/iuR/%X$1+q1#Bi/$Qj8=R5mT!mnCTT#QqpPm>k/TBnDTV>D1GJt^8TqwQu*L!i&16A\dX1T^T
juw9PS 5RJl+?e^/y!np6ihC><yN/Q#N9TMikm8yu^1Sb4hMLttp=NXTqb*VF?5k^6iN>Hu9>$I5C9d#nFt8p^W
Nen^:* =/D$<BEJ/$RcS\KPGWn?=qSae>DVLh=6P9h6Z98JQbaj6E+ym=@:cCbV\t+=>J:6HS*4m\^uIjii/Xd#
bCdMu% ii6$^!L?t5$^!bcEN<dW=VZyP=FmE6?&55Hl%*1ueVT#p$ItiD6H<QGIT:1Py6ZqKScHj4eQ+54Vc@CG
?y>MCX =CHZi5cT\W^L\VG@T6ZwH**iZ5m*t=nM<Y$1DIXphbFc$1Ma!Z5m#jJV$?&8$lYEZ=SYyeZeF/C!FN?K
VLDu4w tdmdlYK5R>1XPRIGHCA<uK56kWMYA9*/DB^H#jbQhbmdPDd9JH1P=5CGL6%RmRJH<BwKB4q=+AaJyQtS
9=*VRB Rp@diKawYkc<:8:#9t^=YFabd5J8:AZj>@&!c@l5#j*?/$54>w%B=i?c?Z@WWKwt/Cp%</eGd#PX%%qK
$1bW9^ TuZMd18HVZh?nM&Kk%\#?AcmI/=+u/HG+pn$6qG+/E*>m#\leiX5Mt/K%65q=q/M@VV$J?@!G?:T5I&y
wdQdTq NpnIIC8YlCV86l^VMSHL@:CedmkE:5:&uT+=WuGpJ:nmNSQ9PKY?$kZ>88Vqlqd&jHj4#b!!9lTQe9F:
CDNGwW <lSlJZjDMtR\aR1Xaja*GYH8Na?aeq+HbLVbaip%\1R%1p&HD@pXptdmGT<lGb+EEpQj*HXXElD/HjHS
SKC5RT jQwWQAIXt=Tl!puXZ65RTe=86e$Zbe8qd%Zh$\\L9k&>GNp4X=\p:ndb>Qde9q@\=C5VFYWKpR59=Qt+
:*S&L& lC=&Li!SXG>ySQTLa/=C<THteZYuJeET#$?n:&/<bu\l^$jK8@8q9l?+Q>eJu*HQck<b:LEkqTY8@==D
nWXLV/ 4#%%yC\\tjk$:QCiZjm*X\?W&/m/n%QZZ@p4Mn?XVPXaLq<XQ^a%$*/b:muCT@VN@+/Vhp&=N%qjbLb+
pScM8W Tt#CIK&eVqHw8^RQV\ZVwXDZ99jhn++>6\=L8aZ69/XXem6/BT=t!!Z5:JE%!q4t>YHN4Nu/!88<1wRu
RnMc\D \uWJdIV#CD4@<89WT<9dZkt59wQ*@Zn*PZ8W@hd\8nK!RFNu*W@Lh<%D:?dX/?$?Ga*F/bQNYwZFS9aT
>jyMX1 &R>IPwc/+mKH/*A@59tNu<dMB\L#Fy$F\aEVVyE6W?EX&cQ1Lj##hkubpF:KeJ/^eM5NXhHu=P9<C?D:
AZJ#DK ^qGT?WR@TY%hN@hVB5LXK/*!*H9Gwp81nQtH!GBn%tEq:*8aA/qnHheVHQ8V\HH%MV&NeR::d=*%>jLZ
@C:6k1 qd6Pd6n$Pwd6+haK\n<XQZcT4XNq5^bEWXE*?uT:L^hRc$GaI&!PHD>jykmi>bJ:S55=c@#JWFdhP*p\
mFT\HH ?@G+BpQSqb/aQIQPSe8SNadwhj6</y:%G%/JymR$j1VD:IYc#EqFPDlaK^B!VE>&qYpV@Fk5KR1*#iwY
:YP1pY d&\B$ljl^EN<A<cNZ>i$jBkuJc:8I%:BTH&c+F9@VyIun%IA*5lQ8pqK9\/YBm#Z4<6Y8eewt<RLkk5W
>uQt9n K&16*WhLC4EdJ/Cl1@H4>RY4bkXd>RYL6%eQ/w8Eq@5eXeKwKYP#ei*ahq5RJAH#R!HqS\*Y4#QWu\l+
14l/pY R\HEDi*tLnRD!FqL>NmHmP&I8H!=K8yey/y9MNL!hM>%FqAnS\5$!Su$&D%!&t>WmDciY19Sj/mcGBPy
m/*MEB Q$a5IGA<N:I\jXBItji6R*q\QDyN*budmFT?$pdXT\AW&FMRBPIAK%k1eH8@$$yV$ey5tWBL=!&1W9jD
I95=!J CV^H<1TA^TXe65IC@S8nekGmMtu*XDCl?+*k8l$wd#keiBQK@+J91>ZnaCP9qp<k6EY$B!Bw9p^J/\uq
+TK4jJ XS&Ljmt&Z1X/mCLaak?Hh!D&4<REL4b5<8+ZH5\L:B8G#S1Si8eBDyF^NStD/AieY\@C1IS+>l@%kVLB
R6KDPd C#bSbe>Apdi\6qlI\iucZBGF+>hB$Kt>*4jS9V\F*:!HSNLPX\w4Q%#h%BDbTj1tYQj6VW&ByYNdcZm#
lqElc! W<DiY9e8u@+ADYbL@jGN5Qk9G6q%IPbCm?lC=S594FtdKb+emGVeudBey:Z6=upFX>YQCS!BQ&MTCSZm
t:llMK 4*PFInD*T<#R1^?a=Wy\!:M+\Cjyk%Rb9l8%CB<w1RkewwtJD%SJcnLmaljDdR%%u^+IFADjJIw8@?wK
@FDD4= 4aaFP5B/>5JIwXCppNk#L6tD\PSpITX6tD+C@bFP/mNhbEKKmkBCTDbbp+W&YblZ6lb^B@+M<=^P>iWd
Qj$y<8 Z\CT<\Gb@IQk>hhF1bAXDmRTcyn!ZE*y/%Z*yNJm@SG*ZwZNJ/VpiVb&yVCXW!CB<^><uLh/\@Y:&!5<
ZlQF$D Q&8YRcMB@TblBbRAG1*8qqZ?qpecyDLlKZ@WH/nY:%6<@PXR:CNWGK59qtJp>+BpXE%umN5ZyS<qN@c=
#F6idM u%P/eC<IEB8%hkD/!@<A\@&yXt&G85nu\Qb><&<H@VYya\/ZS8wVTaNnWuTyI>ECu/qL*8Va<l\Ek$q\
-A$5l@ 000749f243400110333 Page 289 of binaries1.zip
qE%FWI 5b\6SJPG<9$h!qc<m^PYR8d9lm>BE9njMM\y<NVIS1#HqCHB1XQ\u1ee8?FQ+ld$?R%@WLiQ=N\GJW=^
1QDdN\ K<iIBn1J>1<Ck?Pq:CwCcP$BBE%CYHMAi\qEBw/\pL#JlXXm^+y%?m18?E8GH%&#MPakNpYE$cLVdmB^
+XSKtT Z:muqeZZ&uiI\#F%^mREBYR49@$Y*5XJ%?W@tHFAj9b@<X8C\eHWa8&PEnme1HtG5G!Pp4pWq*iBV5=9
lQZVLH 9?Xcjy9&Mc&j8@^QwlD89q8Y*uqmm!bta%wnje&<wNldwSZC:hupm!YFbWPmQKEH5P8PYH48QAYJqWC>
EG46Gk HPhd5i5*h:d^Y9dC:WuL\9n*d<\u4R=/XS$lI/1BNTW^5b=LH$&l>8^%QLPc5WGiIp6ek@W%qk9c\LdX
\8I=^/ +hjMCS9%Je%$lRZXH&<pK@y=CM@JME/L8Q@E^!/H1B8?HVWXt&EEWCni*5k#&H6^5@Ck^SZe/qBE1aX<
Ett8wY TWL6FhbdWX=WpCkGJ+bwdZh^AZ8E1^Q16?@4d:5?Fly4yE!dENQjILe6Ln#a=&=1E%\GctSS=HVh%#=J
tC*w6H KB>P6!KSe\&Y/de>hH%$q=#m49A:cV/CQ%CN!w8hp+QWR:K5HVH=\i+pKtWp1tT&=n8hPWwtNE&atPIN
E5d9R: B$B&PueD=ZwL8CeT&1R<6VtZaZMV=@A$SIcFh4*Faut4&Z#4Zul*W/JYC?j1?q1NcAPH@qAiD5lKER9k
MqVH4^ aL/^P9+nKdDVC8MVHnnad@QLh\Xqp!?J?DVLba:pS>9EhD/\I4=np&?N#yjX=Z\R!?5Xc&GICaq#/k!#
iYY#@6 <d=45\!\=hwVXuFYMbY&QWt&<<:p$56l>&a$^6Ha>%EpBI5:tDI+=NBj//SF8K8S!D=$ZQFth%WHDGQ%
?H5EyX iFS@>i?94XcLyQbD4Ry\H!$D8#l8EdMQ#i#wH&<ALb5wA=5A9BW@$GkPw4N4<*CJ@=?8#TNk@<ZcQA4#
%jaI^+ n:X=qQmFc@Q@Y1:=?$IR+w#mG\L&D:Z=e\ykb!!EPIM?y%$hiebCmDNw5ZNKYGe5lQlHGuZPTAn!nIWR
GT?%LW b>Dm=>Hwm>Cw<&n^m>CI<&nMSYm^<&mJC>BI%Dq%+nMYRy^BI</nL/K%<+adpMmLcA%^#nkKEupS4TFk
ubjh8C =>EZ$Swee^=>Ec*B$ijSF>EcHHpijSG6\e?>cljSG9#e1*aS4athh>XRF>Gc&HqZDZWS4b*9cKA8I4b#
D=GV6B K@5w^D>FI@<y?mJmR=/VIau<&#SE@L?#@/p9<Pi+\q>>AZGJM*!B@=mV?G<4mXEa%Q?hZjl9tF*I@i95
VbdJM+ R5n@@8!CC>t#IE54SqKP:6AJXImu<%9!<Xt<IELpd8!YbL9YYAP:SuJ>+w&PcNqQlS^q1yhI!iaJPp46
bRId8: da&L!+S%\P&kBFu/*mHlHQwl<y$l4Jl+LubnDSju!Q<GI&&9QA9?dG9P16Eqp!YnLBP+6Ra$\*cn<jZZ
HpGRX/ QGVpR9RHQ$=RStLFa!hJDPnGJm9?kGmP+\*bJKFbbX@EDkdua@tEBjeVaITSj>&Yay$MXKJ@VZlLjYih
1:enRJ YZ>MFwJRH/=JYWQTQ<b6IuS%bBnB/Ha4=ccPXBa<@qm8nh/\I:cRB#>YiQWPkMuZtS+eP:JPVbtP/1Ae
c+y5lM V/<\pY=YZj^+<^$Hhk$Z:tu=Xec\T98&=G%N1\Hq:9*CCyaIDEKd<W+RhuH66w@KudB!M?#d\QytPZFZ
>*cdRE yK:cTkKA?atEt<dIFRGuD=BX+#HI!dFR=D#T$uNEn&ZMAuVH+Euw?DVpi=T&cj1NpM#Fyky>mYX^W?8^
B>Kan/ P#N6%^:bTVBKCMJ%pNQ@P1JkF8!C&c&^9H^6:W6&1y1ehA4@^+*VjY&@=W5@N/pZXl!9aePRFtF!1?MR
kiYV^T F5%Q5MLQHF6#GV94C\H^&4$/DiFjB#\?>#^ZYyEcp@bjaDNluuS=1jMD694D8pnm?L&qkDeR>8c/?ZyV
!M#@ML njdE@9eTVR/Ewb+F>idq1\<aud@?ASl&>aukuZB9&9l\R+<+y&9G4\&&5aD@FXy5<D6mT%#c&+KDhPWI
hY<e6P LSPlNX%<TRcSMmTl%pY@K=D?e$HK8HW$PRqyL/b%p>6\lQm8yqaqm\<CaQ!JuaINwR!V1E@AqlBtH61Q
lNqlk1 SBPZ6Qi?mR58CmtY1<lMc*1bp+!<8@Ww55pC?ZJJ/Jw+>jZZN=@Q6dJS@L#V4<cI?*lIh9Zbwc^!ZJba
QLSuEt WYRM<VNX1/%PXun/BwlBCQ^k<QJAnV:#H=hX?KP1+\VddMa5XLSh5awmaHGE<K9WEDLWi1+MymnHbT!j
kydJW: #/V!NwwweudqeqeL$qd#=1PiCX9&8!\tY?&dLP*G6uPHq5w>BchyH>&4C9#d>AGYq$K$c4Ky!bZWiFuR
6NDaI4 Pep5\D9GV?+JVJEYEkX9QE=tMFQcuMqnlN5Xt4IHX&HwMVainJjym=&*aQC\hm9S@8T4dnEG%+jpaM\h
I$Z<IZ SE>TZ%?Sa\!#N&Jwcd&q9HR:@TBFMckEBTZ>yX1SXGB^Xehe*S/K+Q=!+kL^6hKhtIhuh88et4E?8E&Z
LmYywV ^/W?MDi&%q^y:GB&N!IX*!>NqPZ!dI8/WPDZD>WXp68i%E85JCpy^c9N6>*jQl*#9\4qPZwXSm>LLeAD
H?XJqp hh1\c\yX>5PL=?AyC\8MaZcSq&miwXkI<%!h+mbme=p&IBB@hpAhKI^#<P=%QkiSkn=Wy6a6dydm8?KA
K$^/uW iuWcILPC\mPJuALihWE5Aqi<q5J9enkFpZ*$Xp6cNmJS$%?5eZ$!P>aKp%$@FSmCM1XY%&L%wu=</<*H
Wc<h^n >9B+8=#<w9hK=TTu4i?nW:Z=<jP=t$u8lW8n54!XAdY#<l@A!*\Q&+6+PX>RZVL\!/pD&%FlGkVjn$*/
Q5njD? 8B&Q<wqQH*lAZwdqCy!$6@yG/KaKT?u&6ww*PWB$R!A=e1u4lw>TtW@GRcpNPaHwh?*4uw>!#L#Te5d$
mVWIP@ ?Q1%BZ^lRpP5n$aBYW\j&ZWM&jMc6V%8$%1<j+ujZ+nT:jN@8Zp1<BkqJVu?4hDi:4J?I$N\!Lmm656G
tMyMuM E#8+/G$/KalKZ&DD/ucFJVZRZpdH1thW8WR\VY9STqWk&W%%KljR$D\a\b/=IcF5cNEcJqp<*W8mcN&I
aN%DB/ %R>ddqL#6ch5Cq5w=IGYMa@w+IK1Ge&n*H9Nw%uhHWy@CSl>jemZYP&d>PGTic>kTl$b9+*YV>?IdKew
*HuWKT 9w4Y*w=$jm#hHcXdd\6Ma&&+Kkj$Z>:K@PY9SCW!GFy+M*cIljLb!\E6yiuqiME/=ija<8hFE$dR<5%a
T5/ea< DJ/b&HLJi>d\w<Vi>jnT#I\X$cPK^&/j1Z9VTbLmTB\d><9$LuXlYe\<bWyy^*XaIZD:&X*%>qH!=GyE
Mmpi=m y9*SN18*hA!j4mK=EHGkH$b6hp$5qW+1W?D=G*A?$inQP\JH**8jT$/6PDR>hSWtDt/K#he8y&?65Lw?
S@Z8XF ?Lm=Q%SQ1eQkuS%Qh6F#R=n8>8&MdSJb?aNY+Nc%=&n*&HtN!iZZQC^Jd*<$w1!#9Aan4tb!*uiw6c$4
ZdplIc AYaCeqtKuP<DM^D>*mdKBad/tTT>KpIyL:yWmW!=uVaBSVJEtYBBB>m&ADG^H/=8BjK8&DALEwHh!QZK
NRaGQ= 1+tL<^eRP#b6TM?miA69w<j#HhQZAq?&FeYV$?Sjk:8pcDpRDk#qqYdTFQpdbmc4&!q^Hmt?e*ha*td@
?DLHSJ #u:4nhec+:$dVHcpwRpnDLeia@PjqT*8p1FAw5MHP<emnBylB9:X$Eii>G!T\bV#Ny1GP#L9!=:mw1u$
k@BF9d dwWbjbL*IH#ZIwyN%LCm+8kmYHyFWdj!GI\?bcjYayYwtWn>H9+?WYdmKwu6l%hY:S4C%Gc^GbFmH+9/
@k\da? nDRQ&9\H\an*5$/*ZBkGZ&Q!4@CTVL$XMuhETP?h&M>YT$jI%S$q/nd$6iKHLYE@H1*p*%6QH=k!W9EJ
qcM\H# NRaJHw=PMq6m:LY9:TQwHybPk91*\a@LhIYTVMND65JNdM41?ibj944:=bj1#cQ>$hIJC9il*N*Md@c>
Ja86HW ^%*M6$b9aEedZ%nZ%MXk!w9RE8YCA%GW>5wX!mST$S<bFWIq=<F\TLG*Bbj5+\S/VntRBe<6auudKMEI
JQh<@! R8!1T/\u&FIh1M!tM+aQKnSN6$E@l6H:RFmAFH9SJN#Y1$lKSck5N\1\k+!$PmAl%c?ty1eM$R>%wCA4
SYKNDZ pHVy6??QBLXH/4pqZAc8k=9C:^L#&l?:EntLtt@#VGdudFETGQ/$\?5SGB1=hH+C1WHmM9<w^!PnqXF&
FdKd9Y ?:mHe*?aDpd^4=?5e^>S#=tRKXC=4u49Su=>ujANwqW8wQ/&?k5qj>uQPM>bWZbbGeMcNeY*GkG8DnDW
:9G%\> \>bVJjh16RC4Fe!9eDP1V*L$phAy/Nb^ZMW>pX4\kKJ#HFyYDm?4BuhdHH6QR>AZc16J>eR6$S6qXTP4
eb$+bd 6yY16E%KaQlDEW>C6qw\u4FRElt%pYeXh1P5u?kZQ*Xc@JE^bF>Y:cnl$/4Y:w@8$WA1kYq=C@ZF\dJE
BXdETG qb!PXiam+j%*\4\^t@i#e=+BXt+:K1kS<1!DdSTjlSP+BY=+<5l:%ATM>#HZqLB/CEYC+jRP^YnNCKR@
j5G+@& Rc?8bWFbH!:ESapeDk4t/@=l88Alj!NEAjt%8Ij+kLPlu/SLKJGWFAGk\H5IBXTNDu+6CA?%cdjiYE/L
@XlD>w \AhTWw?Gn+/8V:<V5%e*@@ZP\dDJF9T$<1SPFXtZa=k#yB+@ewIa8ppYkhdKPjycL8Wy@!S6C\/WDiiW
/*CL?R W?Gn4Z4Gn1eW5K&8t*?8?M&6pQKb1VSWmWJpTDHW>Wb#nLGy:HemQ8=Y+DejRAeFN$4a@TTH?=bRyCJ/
QqPFKK Nh+V4Abaa+G1YM8Fam\EQYY$^WuLE/bYJESeP&$%I8WejJhw4J&//%+upG&Hd&Dp+WcpX!kB^pPlilyl
A#6QJ5 ktDBG^a<@Zw$5u=&C^Q:SYDldltbJ>X!cD*1&*aj9?pWH&n#V%eul>>G^Bi@!TLN/T^:iB@Ba%wTbm:#
FVbmQY ^w=Q8\$X8IRiuqCkG@9+^lJSVQTAZ*:DEweE6V=GPFiIGq^^=Lm!NRVi:McPP<QH9%tW@JKL$jqE&:K+
c^9AZk V+5p>SEJ8aNhn#YtW^JM119d4/?XqWQC@CHdZ8V4S4l6=Ae:!?hJ#/myZd9LIhl/qLAHnSA?wi4k9cmH
PnQ^8P XqP?5/:VB/H&lVm/V5%w#T8+wC5^^VhD84Q\IG+k4NL8QnCu4C/1Vw@Vk##a9c=k5E?qubTpG$ARySRJ
&cD<i+ WBnKM%dqLEyJppBYAwNdja<1qXM!6P1jkX*8kE9dX:t99KnQp!DlH5nBkq!T?cLWV!1jpBA$ARkK96Hw
RbnneM ^#6yIbX<9TD+d%VS>1cSa!QbhpZw@F$%T9atAPJRabXJEb=$9FhL+JpkeNk1P4qSDe=YBu/VYBPpJH?u
*ec98j ee!KZl!ihIICelK/Bl5:!Fdjd8@p^B!<&l8$>!LcDT#tE%^EMklyHd&+MmY8/H#>=qGePu&:\GKEWpRk
=$#$D= KSp<!uMR$iq865%jYKT6QGSdF&k4I=81QKTkqMyl^P8khF!JwdEmWJnAd4SqC#%Z%<pp1>@1Y+jjK%!H
*CA8j\ CM^w$XI@MH*D=HDDe:5V4/Lupy?qplIw=bY$hSV6NQ!HPnJbl^h^c%i%jK^kN$VYb1hdYXqSWw@lyni4
8weGJ? YFYnRVjV#ctQ=qc*lZS1LE#j5QAjFh85mPVMc1+*dbD4W/G^ATE%=^X+@#a%@@@6KB4p*/d8u%uASYLk
u<tNy? b^S\MYL@YMDF\C=e\BYZPLPAi$cM@:<e<TI:ibFu^QmjRa8jS<M9R1QPw^EZwiHuFDLQmQH@S^y%Z9jp
hJ:HKR GVH?b>Du9nd/InV5QF4<AnV!9Ib&NPamNQI<Y8Im>HpN:iIZ$S4muB*MTQGLcA%^ZqP=?EY$lnm91X#<
-A=ViT 0009ed78e2100110333 Page 290 of binaries1.zip
YG9NXy Iq1Dw<@yWBc@mNdPdc+Y9+nYjpjiu$%jSG9uF#LF^T<p%ZQ<HjGLmA%^*k@b*+bZ+j?h@W?LmZ@&Fj<8
mSF:R^ J1Jk1DPKmj<^%84jtw^@8$#@A=1M*T^w@1e$GRN+k<1eD=Bp*:4L8CCD\E56Vp&P4Qpk@#!AaDVFnaip
Y%M!%= lCZP9+KWP&@pX#n\+%>K8NZZ>WQX?q*y1VlW/%l\=c/8q/DWnuY5aeTV</\cFCpBySnCyQbZdibeQ^1G
8RB?^T pk+i\>w>YE<GAJZ>%9T1\=cj$XWqCS?B+alR*ya8B!NtquD14e?kYJYA&a:Z%DXaDADSVaPB:4DnJYFt
Z&hNqy elIa5IQ1jlh\CV6L@/bY%:+qqCJ#FlWtXLctWqjSRm$I$Dl+Lq9P<i\nwZBuaSSGnpL*5YZ%<bm&/cSR
&%<TLX !c/=qpP1<w6K%iB==lELj1#+dLL?mDp8*+FW/\NV*n9RLi1%@5a:%G5u@cdH4RL$ClR:d8FLRwGL<Pq!
JyXwm* $/:k$iea#ik8ZV$iWJm+<CZVXhhG=Z=>Q%tBBLN<!I^9n<H%5Ii+w+!i6CwP4!m>!LhABCm&qqPJ+e/R
Q9HW@R 4nLGJwVj+Gqu@mlYe1qF$WL4I<I1?ibk@P?PbDl%1a^!DLG#wNDEX6*L<Snai4M?Ku9GX!S%t+*iGM&Q
#+RZyd :hIYZ<M$+qmqiQ6Ya\:i\wF?\6Q%%qu*yX:5LSEp8+RS<SmAQy%iaYtj5QDhwCbVWR5JpDCV$$aNB?Xw
aDVt#5 6S6w*tIaeZ$8@K:VM@WQ$Z/#pK68Hn1/*iN>c#:w%Btk>8%:Xj^CB?$:Bhe8X%R=Zdp@S&<$DV&$5jXy
Jqk9p5 XIt:#edZ+B/Leb1kl:$J?/tyK*V<L8u%qV&Y*bZ>I1ap+@#A:cN\uTh?Ydec1LG5Zj^?blX^Qp^YpWa5
P@>TBd YR8&nuHFIR!G4Y<M\pWHD+mjl?tE=RR#?A^WSnI^:LWbkJbDZuiWw$Jyt>N^bSaQ1j5=>!%Atl*S>q6=
H!ES#I lCL$>\<M9+a/1mXWlJA$HlqyY@Q&A<SIXy$6KA+y8dA=%#LEJR&N5qIkywH5=a#AA8N^X#PB!66yBa5l
d//>C@ 85q6=tJai8\W:&yCmJh::NhMiW5lPlY6bDqAdc!E*M=pQyjPjSw9<%#Q#/^*el*%:bbFkmNQ5:tPqBWA
%!!ym/ w^Bl*BLd+lGBRtJm6L#emYEBGd@>RCe8jZKGPcEED>MA<<Nt8b69bYL8q1u4BEjPLnHdKwFHuP\ICp8P
SwMWHT <wmmk%/4M*SM:Z!QNT><WFmdSRy$bMEH8acbBt&*4MLYp\$HZIjDSYCK$5mu=aS1nt<@h#RHq<bwBn+p
jTH:<$ e!9DNb1J/t1hkQb8E+X#C$ip$5NNNmKdP6K$&hm+&#Iw=mmjYY8NFSeMQ&a9<u5th@9ul*hZHpcuGZJ>
R6Wq5L hZ/4QHuVTbD@E9%^E+k:kS$C4/hY&1V@ah:bwE/a=56ENp@G^$bnXuh=S5kT9ZwuNK4\+Wqm@?B%BY:X
W>hqtA \QD!XG6yVEK&\F9H@Q+%R\qF&lh&6A#T>E*Nn+kbpQd*&DPSQZj+YC=44H9581jWKSISDLi4lJauC#NT
HY#nVT TndJN%6h^=X>u5cWLJ@W5un1B?mm$>IN^QZ+:h<a%tPbyib+:$@Qtb5JAR^:ZRiuawPj/hR$w!1R$8dF
ZAyp@R JJR/QXN:E/mQ^uykCI\\E6+*SD8kK%!et6yJBd#ENnIPaBE6B:A>wkCBtA^:KtMay\aT81\eJB!jM#c\
w\Sl&6 pB1yl?%P:Fm9qcIttj1NJ#N4pwH<LjNp1R+M\@8/XX@HY@lkbRuB95?te\?M?/W/>ED<Gk*4S4iiuRSi
6HB!\B W4&iN^BqjZ%hctet/Wik&jle89Xmcc+@R%8Xi/E\T8:Ba@M%!5ne@A??N#bNnlnd1&+Rj9D^d8qIK8#w
wTt$F9 KeyFLJ<M5C+6KXy81n<%B&w5?c6^tW+!E?PN:#:M%Pd1a<>l!<@RXZiQBnyF9$wnMKQiiDGXtXQjnyFk
N*bR:* 6GR:>cmk6RM^<i=htkhlXAQ:w+VI$pqm#E8n#G1R+iJ@JCc?9&%4>9I\k:V#&cXY\9#cKW%T&?%\HB\u
$AcIiB bduJZiAiq1XqIAC$hN^JHq=ZF>P:wu#/h8N&>8uScDd??tIPZ@W?9thhNe=WG@WydWCPlTk$!R4bnWH&
jAAV?J Z1hIA*jJch>X9eqIe94&PKu%Ia<$MYtG?mWPc:\l8YpwkyT>@mXwdF#6FAAdeq15yAn8D^TwM*TRN8cy
d+BElV LcWHuMIl6GT<S&$plFCCVhRR8jY91ICTaCi5QiVKEa4<DW#9!SIV!I#<S4Tca=h=4lwN+ES%p+V%4eHe
q&C>IS =tbSphP1yN%%+acXXMwG/X>PTY5N4ZNRFt4ulXL:XLQh6j$ca>aPElcqWLHF@e>4XRX+$*FemYe#qe?B
hW1&>$ 8hH\PL*l!QVAHbPw8<@IT>\tleC=>5=!KqS8W#1<=VJ$lNCTbIe1Qhwu+6jhNNmp4/bX1EN<!keF=4WD
*p<@HP ^wG9+=T>6nWL$1WFd@Eb8c#*6#?5DuP\h6$d9>/bBcnlEydl8CiVNnT%Fb<n8\:e>F<IuSpLi!q=V\yE
G=LJ9& \:6k>=qQ4HcH\AL>#1jn89KT1XZ+@1eTC\8Z&kXajN:&ZTC>Ppd6^VQM^4=A/J8&!!@d=I>88d=+j:Tj
:&PQdt NjV$mNq>%q@ki&>WXB?:D\i5l6Q%a>kh9!PT5LGGc/QXn+=?w1%:=EctK\CEVLWdGdeIDc@$l:LCCXeN
>S:/AH !YwdS5NDepLWXIFP+yXQBb^ln<NHLRWEe9k/VXW:u5Al!Pu:EZ&uml=YN<uX5>qjn%i&D=mLV+N@Qq1w
>K#J1d jij!VWt?J?Ha<8QM8IlX:qw>@%QTBaiHlweni$hWqy1KAe5:nqL&WLWCY<?a?G!SC1A/9YkF6KGAE8dA
TYPFeC u^nbAqT/M6c89<9i?&tFYthjEk4!h%E\^Jc$FwClQJH^JBBnGaC!C!?BYHEw6Ea>mm!NW<H\WDpk9<c%
A4$#=Q YVGhtB!eGHwdcMX:^*!deHm>FI@MJq1W/XEm=ZEl==PWedSi5>IkpX5mT1k\4aEc%QD1e>>845pDnMnn
5%L6wj wd#L%hbGSP*InWnN$tpS&j*$96:9!wPlen8@IA%pH<MHN?\#:Z=pjnR5*<BTF9e?WS!mKP&FAp6t%Pb&
G@bDBP \^J5!$QBInqbebNi%W?y^<p5S8IjA*ujl+jQcKR>Ia?$wY4BljI?5<dc>w?G>^B<:G&Q5KJ<TYY@KiAL
GHl@M# YeSCenyjFn<k1laCEqm4W$:eIqX&EcBlASnSSR1^SFk\<MmKnI==XdCHnyn1KMBqiwI:^&P>muu%C$<!
@5n5YL SZqNliINcJw?Wee:j&=5GRc*ST*WJ$=<mtXe$k!/4MHH@ItedjRNY?FZby6k*SYk91nk:8miB?<8kaB>
V+C6lR :n=%>ekSFkR6#4F8Ib4Wl:Hb4m%1&S44%NVLqe*68eXhl5MjndVKY<ju1+EQiYpj<CNh?B=\Fu/D8lR#
*h6mXn eMNeIbHGPVp:h9KihS=EiK%::tdp9ZkTkp>e6nLpu>@\YQHGp$cunq51E5SK+X!:aqYXeCXB*dFeIa=e
aG!1>B =l9h:cdZl@h@>$PD#blk%\qqj9tdB58MFaNDd$6@NkAupYRu>N@nZQ!$Llu8YDElq^SqB*YNcLp98HPL
*XD:nh HX8#&CY!:l#8=k@PYce$:bT*:S$BV\tcm\l^J\wJ+=B+@8:8An^S!Y9#Bw:?+N+>8GbJtT^Fw!t@qtmQ
dE\d1d e1Pk@A8i+WR:YPGcep9pA5!P?4MmAD$E^PYMky<=/9b>m%w$%GhjDNV&9&QQZLiF%SimIa&:nuJ1BXip
#+&NFq lXLa=*^c65ldjGHX4\F=\dNVJ=&*JQG\6/Z<IEhd*#jbTJ\8=:6Kb@S4Wp!BwQu&:ebuh>EW@dpd@yHP
T$Nd=I Cad:/<L6E=D?4>DQ9<Cl:4I$GNPma!^$A4iG@cFD&S<<Se^8KEd\q1upIa:#Y&PEkHT*bYIKb?1cEYZS
4MQD^X ul!aG^jKul6lYP1YtitRTp6Fj+>:j#AFmC5l\CWCLTjFtTi>w$m8?I!*bZwGBuj?KFe*A8S5kSjHhyGe
Jc>cMe >tQ\PnqMp:8?*X1C*IGBw5hB/@C9D\<h@W$:J!1hk%!1\L^cAcLLLRYaGeWmT>L%H*cMP4Ytb4$RPpW=
!wG#F\ 6SH9pFF#ZCIL+Wl4!Dy>t/b5!ElPaJF<CPIK8H1um>!?T*Wc#VZK4*wN\iW5ck:4wi%$4NC@5ZMd5YQF
#HJ=p1 SCi9/jHLQ#^ujT5qZHajHK/4Wd^nD@RiLP#ZKaPdPbC%>BJyAJPYXNlq4A^4QpMlTGnA&n8^e1!e>kPB
\aW\1E %iA8D!HB+R<I+6Z8bb^aX>Hw!wdD5^8>@Q+u$S^EEWWpyCKWa<d6WNbMK%^SiiR44X>L11VZa\\#WcQ*
qSy8Qe wYVTTP5ukS<EEyT6W@6pXtF1yq+C!%LAmuW8F#NKSV<X=+S$L=^1GL9>Hn?A<5t:um?5%h#&>kBeGG<R
6Hud9a *@*el/LT=MY*\8Ski#5Yp/\VNd??d?lbn<T?B%:S%X/YyRGb>5wHXFJTkkl<KtJw+mjA&n=Y9L#nG#Wy
1?LTVw hW<JZG+jjuc5n8blElV$h^IP%WpCqLSde5:8&bttpLM@At%<niBQ5By?wV$:Hhdh8<pcA\:QAqn?LPeT
Zb5w^c Ke&4mBTPV\mNAWZbVR?KJiqZcJjFkCTw^9L6!8#p?+qJ1i4:*QwVe4a16G5hGD>jV/p#:Fy*+l^?X@C6
J*PyNj LPeA8pJh8D\L*yYSp&>C+KnS^Jl<GX6C*EP69P=4*DZeZPRG9c%eSNHZVPp^IZEiFyKI=ZkiiD5\$JFj
miSaD+ tLN:8ej#8Sa1#@NcP+PHnJZH<=5?SLLAL@l8BpF8wWm?@DA9m^kQVl496j18ut/?9Aji+14A>Dn@%^uK
^jaqLH y1HpuNcaBCqi$\RT+nSi$%ARRVk*#y4M6IknMBKe5#PaM$m&8AytQ?AkTCIL^LIRED++JR^pJ!AMTtAl
Yne+9+ yAp<yRuCpLFp$AZq$kRGQYHJ+Au&=R6cTk#GCASumIR\<#MV5ASqeIS\bBBkyWPbSWM+AppY%$JuJaK^
p^Z=>H JFTBBtEbpmSLaeH/+5G*@knY6\nHEka8Mq@SF\yq9^wWSBmm#<=MiHw%R#wTA&WtjB1M8SwX>ITb<I<w
%?BNpt n5TRW/jIyThZq==Gu^c\BLJE=!=F#1wVMD<laB+IajcI\<lFT@<Sh:wW#%#F\9\8PIM<cJcXJtM:lA5S
W*^nB\ RMDkM*QQq$uCu>$hPNN$P^k&&Rup+W^!/NSP!C6DQhhHe#4jbKiHlukCK:DAV6nwF&jpF&j$F%&j=:pi
j?d=5p FnaJn<D<#hS?jw!A4tiJM+?T8CL<9n#\=:!iWMju@$lGKDW4&aCSm\WJJCIB?:^<&H+uAG5SpD:!mD9w
@w65JE u9k$KhP:i+6*:w89k*&&:*<=IL^%RpJa^4lp#@m&I?64X#clW:c$I&PRQc6bPI%yJ@m9RTlQ&N9IP:!b
GiuS64 P$JbPV!b#L!iTu^=c9D%1bpuk&php%p$5*Rnp*RKm%q/4mSV4mFLLwhhnqpp5*R:M$eTm:R9jc=I9n?G
E6\Tw% 68MG<%Ic+^^yV8:L9KXaGwIJG5Jk=w+EFw=kt5XGy1Z$QEu!9KDp\9bV1mXVGk=8N8qRK8\incRqa\6Q
=RaE@: ZqB/aj5JVi:1bR+Ryipek>pm*Vi4ApN:N5I$F5L:XGdeq#5W/V4MGe\E/ZP9q9uLM$6*5uApMGGQ1DnR
q=KNal hEHGnIVtDB%k5GFETY+:<%I<I\e#SYA4JQNuhj5<^XJIkiVkycW$JnN%itqt<JImA/Eik^tiKpmtkNW8
W1hilu y/YCkRNE5\RCL\Hy#Y\byipbCBNayFQLMuubCJPaP6mwVL@StXqThanYe!Vtt1YYbNyjM1^mCuJpII^t
u6*%mM MdPtqFdI@i=Rpj8+MTmFSbKNiW+$h</c\yCM&i^XjXblm#>DW+hh<^!ILdiMNdj!^X@?*G%89hVI%F:Q
-A@QHC 000f2b1868e00110333 Page 291 of binaries1.zip
9!k56u FBVL^NF&/h*WT:NZL/>N9i^w9aV>\SSW\tm+!Hn6</64^/@MLFpJt%>KN:h#QG@ucG+QALRH6X:K4Z/a
=k#tS/ @/Inl@:5SH#p*<cn@>N>=9>XP?J9e>d@*a:+9ZNV^e:T+#@Y:MTRtH?b<lhD\j=%uT91Z!Nj^FAI>L<?
4AqK=9 RQ@46>Bmj#:+5^@>L>?D@i8Z@5MYYBpZ4>?tB?#jDSAW/1#<ak#m9&cewGDm@&CewGDwm^wuj>aR@:+/
w>XInn iWbI@J?Z=\LG!Spl<YjR=^X%#\mJQ+PGuWiLZ+D?@XchVYM8RmQQMT@PCIp@k#/9DH>GTQ\@$5n#Mt*P
6uacBA CIp@k#/9DH>GTQ\@$wn#LIA#R8LQwM@4\yc+mNdk/HNCTmR8w4X#P<AqL1K%<\$EmR8JVi!ejtKJm+n6
/V=B:^ *Qkqma8I:Zjt!Fp$Cual5b&VTwPCZWS5=<WRwYD\j+yG@FQ$leTGPP?1wj:i6MFeIBut#/d99=w&<DPT
L&AS$G aXD@Man4*>Q4@*L:?:<h+Q>hHiDJ@<e:\Q6!NJJdE&BWhdD5HIh?>=V\p1+@CG1DkmeFycu^y5!%!@u<
<8ALLa AHnuwtX^5*TkLT8ATEX?FD#Bb5mmEVK5ulNGZG:AAER5Dpt@Dmp9qMXI9#B>F*5Wew&!M\q9!B\lbn1I
bCRZ@4 jm&<K$kQCXIVu1apD6NY$hph8jGBMyHMhYJK5\5?y1RGRBtGw%:+cW\K:%8B>P1^$6wVZweKN&+%VAZV
58WVhS G/CP5&T:e8YMbPyyhG>c/uXkB?G!ImbQ/ME!@hL&abAXcaWY=#L#RtB8%%YN5GtMB!a!>lJ4*Em5NnQ#
Gjlwy% 1<M5aR#T5$FdMZdJRW%yE5=I#tl<lM!YdCEEYCc><Z=<@XyQuIP$8>aM#$*h6!kKZ=b=caJF!XlhFiRw
Bjkm*9 SKVjA1R6w#@pbaWcM<K@h^#XJdh1Hn6$$c\Wm9F+n*tVtwa@Jq8W1y<eiY$1:91!l:JL/@E1ABTp?+Pb
m+aHNw Y^>MF%SDq*JF#QlaSbw8HNpwDwKaAclW<CIt!TwT>cj+h?b*=\$/^PN<8#4EKHYR/&Ny$+p>E*hZ4>q1
jE$+p+ uBVI1LlLZWKw8Da:9W=jF*pSPtd>%64n<S5>SNVkjCdBI8^RmpqByYFZRZXJ?@lqpP:<#?!WtT>?Z*^H
**!@RW NJ=RZjNXnyV9iuDnE9J>5QTdAuF1wGhN#nk!&=L@a*%<kp&PkmbhKI9ikR/M*nnleeHMD?FFE>@Be6!W
nBDR+8 ePYd$KdPHLQ19W@qw1Bq*#HCEAE4XECGS$6YRpiC1cII/n1h<NNWWIHq6m%>8jeimDnB$\hp\CQpkci+
F&th^y #eKK1Gki1a#E64CZqaRYp?N4G\LGE^$=\S&DFB&<Le^tWVukMYeGRd4MA/$ciSXA#ZPiw^aVVnFm+Jy^
W>Q%>= Xwl?GpXRFwEc%SJSVy*#ac!qTqB:Du5iE*@^&ARjMwdRP+>S*$Pu^y$EqGnS$CB<GdLCB6qPdMy4Z<nS
wB88&: jiH6FL@J<Yn%%DXV?at=P?GkYBh?bN#WI%c?Fh$d/y1W5S19Q9Ci?nEDTTj>M&ahpX1NVIDYlCXHp*bp
%SAGIM #dlmFJ9H=QjuMSMG*KVaBVK8GPGH:VuZPJ9bY6cmHqMtJA:IQ%LkVGILhmlYuFCB:ay<CBq$XARByTdu
mTH4%Q M4YNkMl!u1l/=9d/#K&Q1EyCdQCp>cXLY/P?kduaMnKai$yhlLq>pqTXy&hNjAk1VAnCLYbZqbj4utY#
LHktqd *tHX\T@dTT?:JcNahpQNK<*&4Zq:FmK8CT<^F5M*AktP=6Rl=4tHut#PS19jM*qhmQQMywl&ePBHn5m*
4y9emN :BEtC!9J8+elN56/dJPbEewL\b!DBLaC!c6lhH+/GkL91K<aD+8X>yC\YMhP$D\19uhRGC%L8ly\y@Ra
@P?q?d ?qC/1d8#Vu6m^W+NTF&F%ewu/knXDFJ:AwVyZEpSYHFXqm:WEl5peNnY?Sn/mYRcy?#dT^h&DdXXtIDA
l#&LAI a<eV>huD*S+>XS\mN#F:b/^L@dP/$D>H:tuL:j6dka?J#YWl$pG8AiEpA%h6!!!$nX>HD@Vc/aZ#9pmu
My6k^p W<SFZ:jkVE/%Z/@NcRCJKjB@@iEB&W+#hKD$EAe+D&R1##kQld8ZeVtlykHIluY9LCqD!hLy1BKN\CCH
6LHw6% !ubNI^&9cWM?=KkTWnlQkGR*&#uwXuu+t8D&>>RZkdqiRId<!^B>5!d!k>QdXqBd>t>ZHAd$eww!w@Sb
ND@Cl% Yw$KKaIK!4@ipw\#QyGXum:R6nc>BGQLp:%X=Qb<CyVQpu@XKmn:581nDIl=%CYEwkkPujwhu<Xn+dhd
IWI<lT bKiE=K#w!K$t5^F<&eLqQD>C^p/P?AwmJaQt</9!NLp?@6Bew9/=k$DF^6pcNh@+4Xlc1h1C*mBl%Tk\
KYkAM* Jb6Z$>mAQ6<1*@AyV<YM6>un4tb@?XHYN89kR+NS1<K4=ycju\>5%F=Y<+qjtZ5Z><yl?JKw:y:8#MRQ
K*dLaS /c?YM>WWjTGju^W$i@&e9QdGSjHKydkJTpP/qi>pVb>#?P?hMqGJ^u=:GW$Aq:d!1%9&Ju&\#RqY\VSe
ZteS+k Y#=MA$<%!W1wiDE<&pE*/^i5/FYlMW*QuI6TRDW%TjeS&@6>#Huj&Yd5>tH>IJ%I@J8tSFyymKL*edZl
cPHb\\ @LJdBYe&Lt&&5+J*NPZYy5ikpc56=Z$/!HhNi?ZVyZ4$wDDpBd4V8Reb\RBmS!nG+jieXqyWq&m:i8=w
VhDMJM jD\?KEE!+QSS5WPpjkVXDMKiP9^4qHX>H/mSJ@euMauZ$$dWmC<Jpyt/8VD^bb8DmP+NWSKtR/WeJ6&!
KqB!/W HaJHuRpltAnid+RchKFN!/$tAhu8n\6dhF*C$nSpHmY\jSELdia<5H$p?*\&Q!/e<4ZTi>Zl^j4/^MHF
M>&MqF *CmVG<:4HquP\#>9!N=TN<u%iD6*P#Mw\QdK>WA^C\iuw9hN6?@u9Dh>+he@19VKR+&@:LDhm9I!P@\E
9<Mh#Z HL$V%!duQji^WME+5hukk<uuLITR^%P?5Z\l^JCjR\dj5N95+/^CJG>e6kZ1ynECwc&N9=N&%D49?QMt
6Qa5Nc Skj/Pp8HQK%>FyCuwWypy#nq\e%mBc<YdYWXYyXY%p9PSMb%4cEieXbJE:HJGt&C:uFJCDkbN4@u%\=m
Ih5k!5 Xd<58M/EmY@XRlhppR$<ZmwA8>?@PjnM+=Ick?w/<NY&RQ$y&@FC&LhLXX$F%^i?48tSXR#@BLncmS+5
YZkjAd KLGhAty5\XIq@NRXjRYy9elEY*/6Ad^FqP9Ey=#9bQM9R*G+/DTH54G9I>G/Lm5E%FKJ%AkANZ%LqL5C
*^LEmh J*e!Z6CTp@9q/&@bh4mj1@^@JMDGB+mBi!uIKQhH=L&@1p6pLiYIw#TIX@J&ld=Fn?KpQ:YFKyHp!?KY
jj5p6h LV&@Eln9Cn/=H&#PLdP#bHNKRtAN^MH1?k5CbWDqZhTCm6SPwy=1G+&k+TiwXS%=/!jb+cXW9GucH/Ml
@TRpX/ %F8Y:F8bwj#mISpJ!4SQNM\VAKXE1\Z^8+\S^CpcMRTq@cG%1+&1FN!1wDJSjL?c*IFnThG##kI%YN+W
9iqye$ D&8MyZq!!iBaSbN=@%a^u?4/+tDVP8bI+S1\#@+w99e\H#jkGLwS=w1EpCWKV+bY?P/+/I?<=5:=HNt9
T11XB! :4!XtDPl1B^ipi*Lb<MmT5F1?bYJC/+S8?>XnQ#lGPwL:WV9>dAM>D<Z8<heiCYet9XpY:=HFn^qiWXP
XBDItX XpwmH\5YmR!Vq!DcLu1*8*K%RN*Ltuh8LQP6qije:1L4l1LJm56XTtLTWPT>V+M!D<%QX%FewIP69p95
6=CWTk 6hN^&^+WZAG&\Zw#8$*b1%KR^b%=^W%Pa1!p!9JREc<F\BqTB:m1yYM<!L!?G=#I*5X*+MXB/+mw+@=I
Z^c4@n aKm*Gdu>&4ECdB:n<p6GhjC%=8t5A#p*\S+JJTGHXe%DAiQ%hiR:Yp<>Vj+b$NcHCT<ll>du<HS1SY%B
8lt<bw piZ*pemcl\9YMipeYw$@iup6J%4jknn+6PL%/ua5pl/I\yeEHa1l6J+98iXE^Hnqpn\8$%c6j/aG$FI9
<<8ud< ctW8cdlZpH\TyPc9KwZ>/len&HhH\bm8nn!/CuSXkNEu>p>TBPJ^/9bJyi=yh6+yk6n6GHwVn^6huYQ6
ee<Nyb 5Nb4PM?:1<#R\JL8n$>WBKQVRk#qh6mS%9K==Me5c=EPd5KSq9Zew@MC!jGPd814%yQ?tkF#m1j^PW$A
Q^P4=W EZTLbW+m%SY*PykqCdccQeh1NCH+E?Mt8P*ncC:VSDt9YNq\8#T#>5F4eQSY4Yp!wtCZX%%AhyJdjY/J
Jm@5mA etFJDc@Y:6!8R5=*WD>DK<&jd<CB*iSVuEWpccY:M*AVTQQZYT=\/e9W1M:RZcac#ce/8IViJliy5+$X
cJ!SCD <E+4Hb+i@&GXbI\RtHP4eT^N8t$y>q&pZp&^#w99!I?@>l9q\^dj$n9eaYm4\NYFmie!66yad4*uehHL
D%AGZF wD5I:wqHk?%B##4l\@R!e9V=\ISQ$XBd=cQC!cqL&=/=L1!^kuK!K\wCcw9bwqDElKV^=5?4qw@Xukpn
h<hcah 4XQ!CYal$aK*ln9nG\m1:jFYIbc@lE5%&k?Y6%qF^GD?%J%RN$ui%V$wEd+eQ%ti>/S<X/6C5ccmX8iJ
>kanub bV:^$FHGZkKEjhkthqnjiY!/q9RY!u\6ND5E&^9kdG?m9J^X4ByBYmMSiEB/iI@&MDlKDA%n\HFbwFYH
FPDtW+ MFnFW94T4C8lnECd#E^%dabw9RK4:K@&5qpXNR5$EPPS%Yq:KRDBFQNtXXGP6PaSNcDkFBL+ZtQRQy<e
u*uu:^ p*XaWFC=CEH?$LK@a$JidcL5tF>t1bFGXF^/<M96ju:lqMdW+FNBi!yB=+pwaFIbTV+$V!FcN1>W8Bpp
QNi6RL K%E/k9jYMIQ6I?V%C+A6lcWdj<mqQK^jMtij/ATy9p^+jAY@/nm8GtNFmXwn!lI41aSXGcu+/1&EcWRN
19et^i G<D&>ha5>e5b:PWdebEdNkTDaKTu=wCkq5WhB@6XYjqFi*W>P$ymP?9k=\*tA&YH6wY$Tq1!^etuJPT<
X!CKJ# RQ5=%?pNAJA6VIBEd>FR=qtJA?<ywIV:^FddMTdRKp^L:$RHRM+Lw*RiL9QXb/#+aP&I&6eknGC%1%%&
ZpH=l6 >BT!Xc!<$qikGeGw&=X1Q#B5+bR*JJ8mERa9AH=RyD5!6@/8Rb8p6Zbb^HbL!#NaI@!&Zbk&FjF6/>+Z
#nW1Dc X$lbS+5\GIWk:!:j:atd*nQtXwYWimj^un&Bnb1?+Pjb&b6q#5VTjuFQNKLVAi4P=PLqV5?dELICh:@a
chIJTG nmae+kG+9McE=lpjj==8E*WZ4+En%JebV&F<9VBBjimXFtJup=ny^9l?meDFb8E!mV=BEwdAejtpByY*
W9FI@C RX8TL^&&k&PehZ4eY<5wR#LwRl#eZ^+b6%u1!\=iC+w^n/*>Ek\$BnjBYupDqwt^mpwuJBSdL/*SmA\Y
hi=Juq m:C*wW:<6*1+t#@h%&c?*eDWik5nb4Q&R^*Wy?whyb\5^DR^Hm\4F/Fy9R:9@m!!FJ#Sd8/?XTX#S<lV
1e:Zi^ RSnTA>M^S>SSL+SnFmbL+=^1dEZ<NP4\w%1eeud$:=Pt:>c?=V@\E1#^*>I^Cha^8^u*X4G<SKJ+C6:M
hImtC% E8jiIVyd6Z:R>q1jJJPlXi$WRmS+LT4nBm4DWX6P9cumlZel6WtMblDF=&AHVau1H4+IXuC>b?#y$>SD
Dn=4dm Xh$tRYN>uViYBebjJteYl<Ga?<@quM$N:5@IhV=Qy@eAhG14bIY9$da&/cBmlpLqM#SQhb:*mEwY5/Rj
XDe%R# \6YG6V%Dtd?EZlFj\b\1BPI@JaV*mD\GqQkRYB??ZdTYqZ9TJWH$yj==nHGSheBZqmu<%1Pu+dmYS:NY
<4i1un $RTjl>KjcP\qFTb>lSRkA98i5F/bLiEnTPCVNJnQe#N@\><@5Hu9/jm>ZEqeMZal=GNbCM6T965:TWQ!
-ASGA# 000b06343c700110333 Page 292 of binaries1.zip
e6>eYl 9CnBqp#By:JTCZ4%waY<Z?q/WTJJI=Ty%qV\qMG4$e!p!d/F1q>ewL*KM<\/4iZVQ>:pJ&J$I\d$hBcZ
mGbeH& wnIeHt$&bH+/!Y>Y#e8Z!IyqH9iL!ewRC$y5%ARH=DhymyYTlJZ19jRLKC%18$b$#wyj%N?Guj@#e^Ym
hR*869 <tK@!@Hw@+K4kj4d/QV@Dc<A@w<yPTn+SXJ!@4wG<1>8CR4?y$pCS@:=+N<5lH@%FPBuy8tk#5l5@>Ny
=/cd91 ?X>:C1k#M69QwM<JjpChphu?n#RKI*aPDd<AnV\uB\l%Std:GjR=!T/wM#Ld@=FGwM::h/M8Ry<#XwA/
M5DjiG I:Q>H?q#1?PwM$Ld#*4L#465tH?K9wnaWPeaGmn+SeTGPp>5eLF@m4/R&PDu%Lj@L4Q>>/=ZWVWJ1ARW
:!1/E# LmGGSEQl6qbtqqAbY!5LB#6uG/kb%MHK#\N1@bjHX8/8:udPuljh@Q1:SQ:dJj!hKQddk@qj4*=F@X$k
@>Q&Zt @L<j:ZiPmllW<T<uk$P%:Y!ej=@M\<ZJ!5Zb!kQ1/tZ8cGj^?=\ZQlycnB&BSQ@X:EJecC56/8@T=9@:
w=AXAV n9cZu?c@@N@M@u8:5BlK+pJH?@9RtV@F<J>bD9<&G9JZ!\GBPMN!kJ<SPwPCIYD@M?bE^Q:@a$:pb=9>
XyWEA\ Qu&FMCmA=Btb6KI=c+?$wtXnqVaZk%lujkB:Z&h?kTbGPnh&6K&PpGmiBYmG:c$jVqd>!@&MGLVZCcC4
jH4FTA GBY9MeMcIIDWJRj$XjZtp@T\nqall4GE4e?a+Ve:/@&Rqeep%JTHhNRh\!8FPHwh%=JQ?uE466JKE@XP
$/pp>! CFCX>GM8YpD>=B?!elScd>ZX1VP*6ehpuHRbNKY^d@X\#?B9IbYPXpV$I>4$A^Rp+HJwKaa!m+&6H=eV
<hHX*S ?RiRuK^W=KaD/!C>4yDPc+4KpJHPX&EMZ5H$tpF^TGw^QbNLD:R%l#lpZni/V@bL%>^4cy1ma=B6u8AT
kX1E&L MRuTa*=C@<I\@j&lm4bMFdt!KaW/1aPt$D*kK!&M+DJ<ZbyEE*/HEL54yuy/Kt*ZS&@:P9JD5==lp>td
H/LubV WGwYLa\Mm<11>yFe!wiX<El+=i!mhPAdGbm&amk^NF*^>iu>c!:#t1eqDDjjZQw8Wm:56Wc+!PD%%d\k
*MV:>q %lI8Rip\<RZlSHE\m^4YH#XSCpjGunRCB4wFJD+&8&LFABl%a+u+XG^Z6!N^Ie6>a!q1#WH*eaI?\\qC
N&C64& :FK/+h*B%TdK^@eKa\B5c?Zndy:6Yt#R>\uTEncJin96WG?M>FRXYN^9\998<QcNuRyT<8:ctDA?C&&Q
FLlnh< Z+@8j>Y<bZVn?<>1C98?j9uyu<KEdi9Q@B/uh<q4IRJip*?LVL@8/peu@E*C%<@=+MnpVY8AIM6pC%*c
pnE5Z> %mPQP8kuS+ut+!4VN^95jt5N%eZWC!NQRGRc8Y<@TJH5HG9d?6#HB\McmhajZbqI9E@N5Z$D\#*=aRiw
dIJ/%n ?9CEwayMHeS/\GLwqEtK/\<+ul:m+>L+imNC9Jk<=lAVcqhJnW+jjpidc&yT?hI*l&H>#cNtN^\p>#+y
?tyLQ! IQypjNqeY:GX?WXQ?FMbC1!*c!NbV=wH+?Su4:C>nu\Wa@aMjVK*NpG#GDNBR4HF^HHI#4*H@TlYp=t/
Lnn5I: ?Ijq89hJM++Ge4m1:HtPl\S<J!PTLZ*6BNdT$DyL4Qq9DM^E\nGKS>&^iWP9a6W$W>9\>F?Zw\!Faq=/
C4^YlV 1!Dd6pIEI$VCnywE4LtDynM#M$Rn&#qDKaN%YF#XuAJlDT^yR!yctR:R#=*MRQRuukPGVCjNAtb^CCmb
:CuwlW 46YIR9l!=Tb#t*/ZRG!bKVZRhVCWFbTaCBFA5JB=>@G!j4MKTnYXQk+*+wWLQmEd>E#uX&PTKVHQ5EYb
Hei&Ch 1Y&Pkwn%4j#*+c/=B1Cu68cC^9AYjacMalGi1JY$yVT%TqL>%WiY@tcSin=mncR1Gh5\1JBEc#DBmQLK
M$lEa: FI<>AyXGC1K:@u=FNubDL@J%+Xei%45W*4F:5pQyhqeyhHlV?<I+pk6&:pY!*DSXR5cF/D!liPl&1G#y
lipcRE 8$yQuPIBKl%XCY^uKW\j$:?n#\<cHY9thX$N8dXwjWh/Hqqd6<XKZYi68pPNjKZaC%I^>a\V455Cym\W
Rw%<h\ JYdiK^&w\jB:DqmpittVDbB>Vm=ITl^piK4p=dwXk9MFn\E5!5tNc>Bd$wd9W9Tek/!9bJlQdn=YbdW/
HEF?$p t8dFpbwQ=jL#t@ZWpZiKB*\&=<c+q#qTa^S1hl:Z/u14Re&8Ki*FL*u5F8!8M*TKd!\@@5H$1H4>@e%i
d8nbTP A=JF+9iBQpBm^4=Dw5i1pFBu>dZ*q^JBhnFXXnQLZQPyNW?h9/<c8:j^c/:Ny=WdPFTJ$BR4<#t@aptY
8Wc?j% 6dYGLGkDQXk4HKA!Lp:pd\X9Yiuq!<bDJBT/L!ZM:95=W6b&=JHTARhpBQ%6l??uN9kuVM<ldn9ThL:n
9w85uB G\4hbe6uiYK*wL5\cZX6>mnCMCP*YP#E\b&d%mbGk5PqJ@^/ayt\S*DM4:lF!Y5PDuE!@Xdh5DjkdNM*
cYu#Lb *AHhR=>lcRZ>Ba8^n?$>%?apt=Ii*X/\/FbXSR\YTVDNI*LAd*jlblM4Gb?JS:6W%ayS#Mh5DK$QC$&D
cqH%KX e@6!F69!i!Y#6Kwq$ha*4<Di5dm$D$c9?N@X&M>Z5NibEi:iIZ6*T=%MmH*ee<nu8kZ:acI5^L@4iXc4
JlMG?w /bDX@q&Z>eXiGR/!yYluZ\tYZ<%p$mSh!Wc#XY<Ih1^ITZh8X\V+TH<8Pd\ejah854HpQilDnFjA*kR:
#N>BXG YBRPdGN1?iPPS*$ppHD?=aV?c5NRb&*<HMQLcZWK/&/Gwey!w4q=K1PlZ^T11pywT?9Ya@a*q5:DqiN<
B$$9>= cNilS&@9mmWP$VY#:*cdQCX+<EdAb6Yt@1tP?V$91/q8ciwQZjPjGFeCaq<a#&$MT6n!Q+\LFJV+^j@1
!8lTtd 5wM$6IT>CX9@LY8i\mh:96D@N9*I/!EdFuii/Sj:L%KPJRbL%K8/H8p#b&+pG=bH8p#Einp\iC<:5T*Y
!LQGX> DV^jjG#jiuS=KMhY\@R%kmQQte<hbnZ6$J>n^Fc+kql$TMl=t8V>Vj4SS#/K1wV6K#TK/Xu*kYbGbkLM
Y1$1m9 jNZmXGui/d?C4<5idX%=X@imG9DYH5:>/@d&eIB+V9%LpecqE\J?q@a*^Z8RXNKFc>Du?5CXFuc*ZiuS
!phDea K8YGkqBpX+4GW$%yE=YplIAC\GmRwk=Ehyn4C1iddlT=Vt!B/#8cq:a8RR&qN+1=j\VIL/a:iHH\V9e@
1=YkGd A&AGAwq>Q5paHE9Am5ac:a/wQe&ijXXcK#MTnJ:1Dm:LE%ae4KqZdpSmdaHt!k%E4k&+pwbA$=5QM/MX
6y#hT@ Ju<G+5tZJ:IX9Ki5k&85iNP4DS?H/!h^8?Lc8#Z5&kF=5+aYwF4AN*CNeaCKc/TXeNBH*>I\QYkBi?^w
wQulNC SXYlXCL@nl!y:*AJBRq9Ta><QquwwNc?y%kMKWqS*yP%S1AK?^R*//eIdR4l?/8!WDmy8V%QBAqi*\8j
dEZVtN +GD>EnSMw4AeLCKVAk8d?B\6laXaNlT$*nd@hw6:%p/I?^FAlDSR1$=NZu8>dqNw9ul^I4tj5/V\KypT
4jEyPG t@c/Gk$?W*yV=>P/bB%&9u<eqAtYwPQ=Wj&btNa/l4a995/Ck+1*qJ4pP:YdCJ%nVb:1FIlQXyWH/Rdy
D*1G4p wLP<R%jPJ8<a5P>$8\C&==!IN?WiwAy@5kc+kcMlEZXTamkh>9%MR!8jN<Tnyb=kS9eb?qCMHd>/MM:L
hP1J\/ ZlyYl>9aWI5%6+4J:86&%<k=/K/Sbw:\HN*!^mW&taiF\&ptLEtYLlFMXK8\mXXL=u/8pTMd\+YnnV=j
9WmEJE yi%XI/qh%c+h*FW#*T%cQ1AJZinVC1uM>luKN8L^j$Fc$^cl:FideJ<98J%9J/L+AihH:uh<:jd8/J!a
A=!p+6 J%bD@mTpLTJ>+I%mLdie&ABd9be^CW*F\S:W!1Gt9h=14Sw<%ph^nCKKuB<mBV<M:TeCGnNY9!*RctG1
I55/pD n:#q6P//BcRSDd?1dQJQbA*t=>Z6dR>&6>X&YnkCeA=Z/>>%%?Wt:iE1*\>T?DdZ:&=Pc<BLYdG6aQ8B
?H9!ja ^@qEyNeuKThWcF%tMHk8wp@ajWFDpdihZ*/+n9?I%:mMnHPp&LeFAR/q*Z8kTA\q&PT9ta:c@!^Y*Ci&
l^bXeq 8AtH&\iHh\mEeZ+aTnCaiE<Qd!$pqa&w^nk+bRq8B\dY\YjFmLuC/u!Ea\PV8YYyMBHFeG?=RCnyIb?N
ZDG#t% 6uD594cG4mk*HBCGj@9cAF!b*j@GDMYVwH/kIWBtiDlmQLSe@@u%1Eu?i6w1XB8:TEp\?%VdQ6ESHRA+
>lK<t1 8nQTuV58/B?K6/t>Zi$+bqF$>$cBaQY#I\n*jlVk%JV@m8lEtqbjCYZy86HmY^!\@+Td?muS8wbkDM/K
%IIhDJ F6I?Ykc!J=5W6kVQ+$ylQ1H86RJM%\6yIiG&W@#epEp/iy5T@KFl<1T?EjeqFqAi*nFK+cA^Gp#H#DqC
RcP$C* 6RaMF5NL=<&Ch>C1u:%48CX8ju:L8DpM4tN6h/u@$RpDq8M416M?q=SEc$!ujiIGYa:A%pjE?pL+?t?$
IytHGB m>/\Cy\:Wwt%GkeGjqK*i1*X:KLuHdP@*qe16Mb=+wadH%y9VeS>medjCba<XhGV/CID6N5CB?j+hV1@
&k>p#E !m$/8?S<$!n=%l*=*cYit\8HZ1WH=89<WM!4!N?4JL:STDXS/eyd^WWmE*/DMuujuA4#89yRRPQpn$LY
qm%eWI =8wh:?Ihi$9<E##cqGBL*91kl5Hbp1T@5jhAk>wC!>+jh8!LA&atp6epp*!n4I5\W8S@ywL=6k>Tpp$p
u%py$A GKNFL&@1nLHhCC*XZH>HGd&kFL$MI8*V5?C+@XwK%4uq\H6WNTdQ1c#qMC#wT5!5LXeLk1ap<1cVe1/c
LbyCbm &6\I6%NZh@&t4bbuFdkSbMF^J*n8?SyT#b4WI9VE!F9EXIBZ9V=V8&AltQ?/ijEQpVRp4qnQ5kn9HptT
&GL1A6 cD8A&*&Fy>qyK:^&y*<uiN*ANMJ#K*^HNZ#jHc%m+^wdiCIXuJch<9piyHCEpw4SJCZ&VmPuDltXHiyZ
qX#F@: J4*#p:I4aLTEXTQq*EG^FeqQJ:*+iT=&6!IDQ8=FW/l>/?GGh+TaYdt*/5eGt$Lp8#F5A4tGSZkiyHH!
a:Tu&* jkmH\@Se4!KX&ep+Gc@iuck5y%L1HuqNT/>mm=$aq>JJ9^4DSB<&5DmNdiNwDd8qV=!Aw>/t6jh:yNn>
iEDMPl Tm@iK8kh+5KVpT<AC&6N>%Jt%ZRDm#Run?pPG^$Jn4RAhTd:&&q9#eQE%dmF4MZbimcw4bk8i=AmuJ/u
j4/ZSh DD>@/DB#&Zj^k:W+m^&k>K+*lN<l*byZ*Gw:Fd=&#Ze6RcQk8n6*@<Ic!1pl>#//^<wVqPnDGNRIEV*=
?Ma4m+ /G16/TZTJp%&yinb+K:>Vewc986Y/&QlBa:>p=SFXt#F5pWRA9QwlE:FJdKiQ*DKG@*nbib4SJNmDTHX
BAEi5D :1Md?/Wk$@+JT56K*tb\*jk/H<a6J%ji8ET?cL*#y$*yJSpu>J$h&%Kj#pLHTh<IYSGmySAS^4H/eJME
1XyPA: $TCe$8&GjT*&uP/KbW<qE9QhaB^pW*>N&Cjc%1cyDi<SID4TZqlXIjweZ^\l1&@FyL<L:cPWhinNbj@w
6^6NYI F#LqF%=aXLjPt#^ET5D=R@Y$RwhTXk+TepPXk:myL?clFW619IWqNtaNbQC=k/yylLcKcQYYX5lZdmlt
h>d8MB Qw<=/#1G#kG$jGe+\IZSQ%M\T6^AJ=LtX8JpCFMB>K:Q%y*C/AbR5ltb1h#YP!j:!!unp*>wh<wH4<WT
5GyEql 4YjmQmbNwlT&Hut8MQ5Ej?5db\W1b6/J+G@<9MC@>t*mpR&*@IllZ+tMu^5@@iX$YPbhu\>?SjR6BdDH
-AGGS! 000dc67247000110333 Page 293 of binaries1.zip
VG8MBm #Ah9DX/q:e9CAh8QikXFJ*X/>uD?WZ94<MQWAny*yEF&Ka%SAh&hWw$MJlPy6\4ZlStI\SX+MiXl^<9l
tbXthD 59$Wkjnk5kTKRK%F%V#HVaPIdW1e+yI<Wu&CN?+lqY6J9c\nRc/i?SaIHD8PDNBYwqCtQbbh4?p9V\\i
SH/qXJ BJGAqC*YMK1^dE9>?<QYZYH!5V*MnmLcXFEC6+JQ&edi+9Kudk6^=/a$SKae$WRkVjFAL?ICh>XI:^Z>
1AZ!GT XZZtDSnRl/\l@w<wtBlD=l*DCj9RSikibuS4Y<R4QuttZRQJDtj>iNPHN8Xdu:Xli>?#RlKZW+%9i+Fd
dGp&Bc ZBXpZXpHqP4pHQ4jFtSiAKyCD?8<^c8G4@ypWV=m1RdW$tFSRZZp/%D/@MDnFW/TF\:me>1>>e$EH@&\
l:w*SW H+VENKTEnp#>9n98\X&H!44j4AiiSL=Nk@nw!bu&ISwqJpkwd*lXHSmlyi<^nd1Sa##%nml>VkMZ?=#$
G#8X89 5m#V&jX8JZtHh#d:ptuMyN1p9W/hPVAT@>\$@TJAnBkEb*NPQhJC:RM8:iW^SVE&QlDNt9h?>MdBc556
+#kNk> ltTiwMVkT/1VZyD/*bEHDBF69Ih*cS<?>:u/wEeypG#N$?h!<>$y6*eX8MawH:%G5<tWI<cjH5<@*\$R
6+HXGX ZAPwN98ZNV\d!=<e9P%lI?W?=ELB:CNT1SaFZw&M+H1NeLVV8bNM!85N<>c!WP5^dGJjiF:eEpkq1Ntd
AX+&!e n$1?Ftl+6LGd>q:\!mGF=^!yXwBRH1WHQyR/QIRQaWG4tXpMQN+\+uyleF*IQP%H$:$N\btQY/*ZQGiM
KnG\Eh \H+\TW46#Ccl?#IIBC@?t9D&I1DmnTNY&qty@aucH$?=+dYK9AH\WRiH>YbIhyn:M&phA&quEpwQyY!J
pp?/IL 5N+jESPH4<nENb5@&ka:?A?ZQ&!4kKl/YSAVdJXT<EaY^Za*6Xmp%N1dl?=*ict<:6IcY&%wYE*n#K+T
ZR?Jhh =jFLGY>Bc^9?NHJiQ@V$iiZS!1c6+YI%?TtKN>?uu6nui?+>Jwt8L>F\BnLjFKcZZ\^ehFP6i9M%T+%Q
:eWF4M LY=1wjm$1qMyFW8%Fd>1B>InePe=YQD@V=QBWQD@anIaCwH/S>MKkd#\kM8@Fn@@91!KPKQCD:>wMln1
lG^+wZ nMWR@$mjd+!e5Sumj\6H@H%JGQ/@nk:/6<d#9=cE$ek#T5L@eYuEu!XlMSlG:Q>&wj?*hcHu@:h&wb8%
!?j5tF XGYFh=VB@tkZNnZ9m$/RbRC1@I+ky^DDYLICmM6V^8V\?%mB=p1C988plLLjSnFK@HlJme@$S6jCmAK8
LeZlY% keAhm5:$Y9W9cXti$$MkDKHE#F$<RNkdjdH+lJ*QC1?JKRwXhYN*41qMw>R+GACX><k&u6id/NB4h*El
K<qN*Z eKH$:<!w8&RK1hn$yb$wVJ:Dn1<dw\/pBLnjE5yqtW55&XyI1d@y<hGQ1#mC$S5%@6CZFE<XCZ\*tayK
^Lw1Rl bbm^!NkWcKqIdYWCTph/wMu?&wyiwVQ=^/n1M<M^Jb*FA&1IlWkLm*b<!k!nyLT6?$Raw9$%D\I@NtTt
Z4TaKt F<J+XYhFY5bQHh^Apcw8?%XXl:p#JETdDaFb5AGbib%wy!%L*QDINn?P:EtLH/eIGK+uNu%nHa+1Cwqh
yEL&WI MjP1w!dukpqH4hP/d89*GST=QbLR:yJ#/J:\e9NCbX41w&&cb@GVCAQLc>1TQ9*$kkB>?8q?$#F>F%J%
yH:/4L y?=dhM>CuB*HhL^HYKjmV%B9!?M>V=IjtB\8h1Jqpa9Tw=4GClA1^PVmywW^?94L/JpDilNG6/>hEt:#
K4lXn& L!Pq9d6M?QHZ6Ihqd&tkcJk$jb?>JJZc$F@kebI!VLQEnStCl#@d>Xk<4tS$i?:%jNdPJPYAj1#S=LQk
A4+Yq\ y/\VeuH54P^X4Nb:NwH4Nn11u?Xq$W%Qqehi>Wy+GeL!M\8:E6m>1/eakZ#6L/b!<*XL9M!^PjlL/4aI
lGebEG A+=R^ucj%hyJ4XI=RdW<pRJe+ajk^@hKn$GTc/1ZqnmFk#yC1WXS*::M9tP<%b9+S<imaTZ:C*cV\htb
P$CmWJ <4D&lGqHhwC\$/@&5B5W89w8D@CN>J$M8!V+Tip\JZ#wDS&T+HjjAc:XQI/hK=lLC?@GDiZj4=eh:W<>
1AB!+F 945m?hE!MQDM8>Vj4y:=j@$8>di:c@+*:qLwM<a\$in@9haK6NmjR/d\Q^<k@1/%A9%u$\Wchjb6:R#L
41Ld$6 @X>uX@@n#1F#@Q+#68j<I!%&*pnbGh6##ul6#Dt9jed&uDQwe$IuWYh5#@qHGuZiWNkb&*QPwM@b?+M/
#Acp5^ a*9PQ>K@=%LQyyEZweZPi&*WQ$YnL$An$Phh<+6wDZGiYyAZ$h4=9\MlJj+yHHWS6atjM&PMRwu>W#V<
PV\nu1 Rpw@=:1lL1I&%Ht>TCnpQ$Yn@mu/ItyDuVh/md1I&yB\?Dp$=pJKQ?huFHWS5j&ia#/VS5Q?c@eW6MR@
nm:LeR 688lJj:*&9ZRE9A@M\pRj#=A@8$>BT%^>1*p:>KQj@jE@QWP>I>:+Q:>**&^LynjP>:k+lL59#9n+BJm
1!=h?n F?tC?d5\=j?Dl=GRaIj@=Z*@*VD$?$\ZPe6bLXca*!%YtL<wCCyn/@1:Z\mKk8y/@G+Z\m9kwha8:qB6
B@WD5! K\59h!9wZ#=KYWG%QX*e@$WBF#$nRp!MHj/Z/@X:l>6F#wn<?+?ICQVjjpSE\!V?85L96#D?@In+b/QR
y^cJFH 9*^EQCNhFwXG@c?i>><?i5L?@Zu@@LV=?*uSate?:^pD$AnpSXJ4AX%tBJ$kKA6EuyM+Mb5X^MFIRuRk
!!ubt> we=wI^FJXlny8?kPbTMDh6HEW8KRq^S/eaSN\<aT1ht^NahI1XChmJn?4pRT+XIWAMIN5$YSabF5A@I%
BIKMQi $nZD6qDY8MW\GeedJBIF$66$k!?6L?qSM+C>mZIZ49C#kyVDT@\aZWFl<&aJm@n%G&LBCkYVdyFn$qhb
9a4a8* Pum%qS4cQBFQbt&J@RK1wwS:^*9hQ4hYiEDb\D^iK5AddTDG>uBm<4ZwC8n+l+1ck>teMkHGD*Kpaw1#
^LQ$GV iK6beASuTF1Z6#GL1*j\iMIauy%4B*n6YhXHd#8+S?Q*^JREQG4Vt/IRy:Q8E@Y$c@WbtYl/Z^1dyZ!Z
Zyh!h$ aWC^8C+At=PmKC9+$dL&l!QcXDh95yFRZYk\BK6Tl$%+ci>4#eI69LKeZm/+%W#GF@5hN+q\GbIh8itA
aT:<*4 KaLHhdFQmIPZCL1wR+pTB5Xm<^X*cd149%&qCKe+NGeCCtNLPPYh1M$9XakP&#L#9X+^www%W<tkd^yI
FLqS*G R6KHe\Vm$YEeCZlaHD#RuB+TyNK+F/R$b4@QV*d1?p45EQ:#cpF=P=a%k4D8htpd&B>CIiQ1mAIL85Q\
Slek4q ktnCEn\TDTdVFG/EJ+i#AJ&q!qdAj=G<DJk4^JSX^TLjhVb<h%Fc4Y<J?%pqnL=BAm1lqhA=Q/knt$eQ
MR!hS^ tSS!uFM^A*B9R*bHYK?FEli/L&9Yj$>Xu^cJdSS:Z5Z8Tp<F%d&p4eNXwKcuS/uV8BFY9+GXGAi=+lF9
h8Fu&M y!9nFDC=&E$V9Qi#a8%bQiPTbi$Gw!m>KbRe:e4d!4lLh<cDbDJu^/RBX>/?b\BEiSp^V6*#JCG?>>4W
D5Ic!c SQ\KiEEedYKuwLJN+4\XkYD#j6MjuZ$!@5#nTINj5!wPS&&q5?&t@yc&+4q%!&VDNV6VQ!q*inN^46l4
XtC4uj X1j==VKDqLBl?4h?lR+i8blIC!FdDMNR#95n^>1<KWlc\a4bSCZAcI6RVZJl\:i6<i$GK6+u4itdFeB+
uJVBa^ 8kY9cd#=@NSCGnBSWSqpkcBwi<yQGB%?!A%D#y>\X+A**4VbT6KG9cd8$p*5k&*RV$e&Ru$!\qwWq!Jc
nnuCkX Jwcj$<1PR:1C$Hy4HjeMG%^R<4$m1hLTJkj%6hBQ#?n:I$d\4L<T%M^c=+KB8WuXQc>WD#al>ZZ$>^=1
DhM#wy VAKjFw6dCN%>K#86WkGj1R^^\1EZZ5VC9<eN^X:dbpyqqYy!i6:C&Dn%^*61hK=5<6$jiqb1:9M@/PIH
1RiVHQ S1JiYCpyPd%en!!Y8baydu@Qy?!p1ql4c!/wXHGi9\Se!cl9Bq=KQRpPQ*k@/hcNic$phIQa8V&Zty>T
n8C@P8 lPMBn#:q#@RTl=AEqq<XVjltZTPbINZQ@FnbXl<!Z^&A+6Epm:m\k\!@YRmESn54QI6W@?:iQa1+a?F?
pMMJFp b:jeew@AeiN*=ZTPTY4Je>dP>$Z1QB\dYTe91<A+L:j*dBNQ+iaC^6y+i91LNw^w%=WySI#ct$dI#Nyh
Ae19%q KcuqtX:=5k*u9>pQ?#Sk*:d^pZdtc+hPdpiVeFQQqcj:XuGp#NSAuwQQYa:A$Niydh&<YDDhiAYAEL5c
+w^=DL @Mcdu56VS:q<:B*QG\6I=pGlT6Ge+k5C4Z^yi\Q$aI<$G?wc/i1m>Q&/QhuTKdJ*I<GQKZPj&A\!%LZw
TeHQtG $M%VWyueG&E&HX$hH<SLV#9nZHjeH>e@M\@9EXLqelFL=?:JikQ*kRJaC\1Jj\bVVXqZWHi#/Q5@n6<N
&FlA6E K<$8:PFuVR1PA+F<kKdD^+>\&=/tlhJ+SnF1Ay$mJNuyFN@mELHY8%6y%XN$mkIdQ!%SHE@XcE=HNmM:
yE?N5V iJ8EHYleye1@FyASl%E@D5#N4#J$pq#I%LF^e$>>Heqj9HqQ\D^&S/yZ1jyc/W>S#*16K#Dml%J<qcK/
RCdNDk R>D$QIQupy!VM:EkNM8Iq^%d48wVq^V#PM*8EB41yZL*\+D*R#bFG$u%y8JtqV^IlcL%iQlmpNp+:uyL
:W\Nt& 1bJ>Zlyilih$6m#Na!KpWX94%%Y>>C$Qk^i1h=^KSSI#>=5!y$JXFNRCT+*whGq*jiyk:a\q:F*Y=Rh/
nm*p*j 6+=W6>tIR/Vn<u/YSPuiC@?8qSyCh^!B9pEq1D!hRTdY:T=jiwZ>WQ:RIeRuenGHP>^WY5$W=lWVFLwR
5DbBik kp4:\l&6F?XYNZcyZ8Z1<64Xi?JJPJMY6T58*Kca/Vdm&$w5VEZQQnSyYpN9K$1TmZdHS1N8:*S8A4m8
Y@5apj nlJuC:cyD=!TB/+^5/iGh%kNpV%\J!T?JPHw9%/e?WF?SQyim#9qWLlj<E<>+b!K^d^Hwui4NjatQT45
>Al$4j VLS$?Vbc%:@F*XW!LJy+<X^qNJameXNc@dY&l?\5bDd#MKqGlc=TMXXt4+BiPWNk@lc\ZHA8?&nQB<n$
XqqD<T AXGYQ\</$8beDm6NeIARXVBZ4ZR#S*nE<X/XV&S6bu&*?nIX51w%wCmtyFQ%!=TqL*qIm&kkRT8qkJ8l
BLh/^@ IdyNiEHSP<y<?F:wqq:%?/%Py&j9XVA#Th<Wm=8=pKN^D<WZpwA&l%!C>NthXFN:mpw5HEtyAeuyQSZ&
6?bY/N C8@#+*XDH4yw$aYln=+^F1l$+NXnmpD9Ik$aZDHm1yJwbh\IKQcK5ICh?uQm?I%+SGa%uHM!&!KLwPlR
9TVnAm $*bd%BGX*ujFiW:Z\G^MWma%4eA&$5pJKji4Sn+4^8mh?>!:?%lud<4%Xh\AbtRkT/Ew!*uP\XVT\eF6
DIkYyb bmZ88c@BM^I&eS8=w5\yI/i\m1\<mZZEVFhc8WN@*QC%h&uEaaiibYT6eby#W!yZjANh^HMtHQ8iAHJ!
W!N%jT LcTZZlk>PnRey^VZYu@@p6RZ<ZJ\49C\+qc4R&Tl@LeWJiK&LbJRq5Fkc5&PRJRCTWJN5jEN/jLWHlHL
&E>PC/ XWHc=\Tj4lC*?bV<qCB&L1EpF$S6F&bDYYHY5aGc#qL!QQ%MCtBy/PhaRdu>hN<dPeH>bklCPRLMq=wJ
Cu*wFm 556LQ95E1$iDD<pwYqtnAA95HaE=%aHk#VYR>NYZwjt$4Nq8>&>F!XKVnGEbP#iB+ImwJc/H9CwJy8\*
*GJPRn CCbbYtFa!=<hHJBRKaGE@V\#>RQ5#6yMjhGVCjjZLm=1XSVN4etDN8MuA%XtiP=CAAp>:::p#NiGX:\*
-AIHLL 0005d50a1d100110333 Page 294 of binaries1.zip
/a!1<A $<CJ9WPKy9MVT&@\aJw*w!n!#5**8pS6Iyq/L%V/*&i>c+8^5uWWwP<SyFeKw=RNeW@5GeVaFGudSSBG
^$#jKK #ZtT#&Y9G<i+5mqdyKBju?IZb+5WGSMGDc9*&jF4NTuW$D?/+mEJw5T8AkR4:ulb=RGFwwFIJ^K4Z=ml
YTu1/= +LZ&!Zu8HHFZdCJjpiQm4CdkG&RM?mMt^Y=b4$6iWql$ZnFe/yeMW4FWy$ukJA%4cjyS9#1YiX%yMma$
bjeDBD KRYR6F/DVN<D9:HuhJK6<LK8H&yjq!lMB:X4p44&l=MjpFBwcSdLcldjq4Tb4%ewck5dnAuZKT#l9=>9
+5Te6B G>E#BJFj6!HVep!pSQeGN8EQXwV$^Euu\cajcMI#=njDneZ?H@d?A11PhW*WSmj8:8=8E=m+8:8:8&8E
Jm<qPF EJ#kDpGD8:8:8#5Eh>ep/M*cb?<?*d%Z86P>Vy@@*u@ePWaaVFJQ%X6X:@hXjc@!GwjAI8%H/Wqc!$1+
WF%S4! !my9bnk1PqZeMmN@F>\?9qd/CP&9d*QBjNpDTiiED9VF9Kw&94wk9=@<?M*@Zk$FunTcA!ic>&b#:bae
Hm%WTS <hbJ>9bCFSJFp*ST@^:F@D:/A%*9DHVQ$#euL>#aNqLVy?@GtN?#ML>9p#Ih9Q@SN$GVW<XmdEqQwe!l
&eJW</ &QbPSnGSWXk/nDhS*nEB$ZLR/ndjR4mpTQmd^D#y$idIIceVw@+ilQA#BLXaEDWH\QZTWuACIb8pNG?m
iLe946 6KlqLPF#<ET<A:QX/Em+%FPZlZ&VBD\W*ER/EnL*tZ*kEc:%u1&^k!duaFP:^Qpu!kcN+Z5>Xh<+G#lc
=lT8Cd ta+Pi?mPee>Q%me$=lYh+e<AJE?i9LIa/j*Jaib\Jm#KkWpa1kihat=ny!:8\Aai<56Ey#bbYR5!Y6+Q
1R1ZyS $WP5=\>tw4JtEh\X<D9\mu8WkGBX^bKBAFQ8@m\%&t6%!AahPp1Fc$4FcZP/QTAX^CmF$<LJ^Rb<&Q/&
>hc>=y VX<bHTY!*AQZ1LC5bFSJ@*jb4q*Q1lFjb5VRkDekN<GNYkCQ5RwM4VDT@tp+SBH*>XM1bFtae!*HADb*
XdK1S4 <L$/t1Dl\Vt$XA<Zp/?1A!5E%Xl+eFRNFLXK5j*:&tSp!&8uLD*Yupe<yTuJLGiS1p!KjepZlIIW!Vhw
6m9/Ml dMyYp9iI4A!a4EC8YD^W=Tq>X#QiGM^\\Fj:K!$B%Q6h+MKuaqH>jMeh6@P>a$p4F$%>KEPw$m$p1y=G
ca=G<c mkmw+EuM\*w5cY%I%B+N=ZE$Z^ElT^mBW<4Kaq*b!T+8F%Gpp\<==P\$pwj^<S6wCi^apd+ci+!eA</j
!+1>B9 $HD%+J!hT8Pb!:nkBwTqdtlBdw\e?W&Q@S*%quQ^\haN+mYjA^JpKkjFD4W><!4eJTD41eF6+6+GSiq^
G*/@5+ #pd+:Jb\YaF$##^%#h\Qyh%kS8G=^*iDEn=#MLl/n\d\Bu*tPYj<RPH<GSXH!XGWi$B>LTFY9m+iq5%D
I$8Q\/ IdjAaDctRM=D$RND=Z1dj>ye^B@%4Bj%FKQuWh^/&XY+aiJeJQDq=id/1^ZuhkX5NLWLH^ahh=e#K&wK
R:c>AR <$q/u=kCTaF5w1TH@A^/:IqkqcKwnbt#5wRWqT&TYH:\%/p:GjXeGX45J/mp^H\CucB^CaT*hk^>YcQ&
p/EPte LNPehhbN%cPj6BI@et@c\4Bn9?pXhBdNwuRn:/*weJ*wE$a#@IZLtbQ4@&kXTC=TEQCj<mnX&Z+8PWE<
a>j/9u @^%nQ?h@M+?Tp@Yjnj&e4Q<%a#<u/#@5Mc#@*l:D?k6:#J<awVn@jX+a%/<MaH@Tuimj/X?c>9?pP>E@
Ie1qLD $:<$:j>Jh/I@wZ@qqQmV:pV@VQ@l?Ql#G9R:NP59VN^@$y*wV&nk4!Vu@E5$%%?m8j<T@V8/>16TqB#e
nd%C1Z \N?mj*F5d6c@SLQ>Jb4>L>G@w&6@6HD/e=4n6?ljnFB8#4>Ee@$qt959$d?qc:@Kh?Z=LX*:%i#A\@1Z
BTF+1! cLc@SLQ@Jjy*hI&h=%hZniP*/F@eMS:P9$S#@TYc?!@S9/N4:KA@j+b!AwG@SaN?RdQ?Jb46L>H5j+u?
uYZC9$ LX%nBj/C@m%ha@*XNij<T#VZZ/K=@^L>P:4&T\<%J?699dC^5@?C@l%q+@nXDYhq?$5$?=@:/9/nHj!t
jeKYS9 +=CVk@RQl>Mjn5M@\k@?e$eaJ!9wj$1au*QJH!WN@uBk@mHV:<n!V<+##6>I=ij<X/u<uH>j>j!:@j/b
XDhmA8 <\#I\j:@+*Gd9RB%%8*1AFk$=R6aynB+T^ZyPuMRJpFEeQ4lpF5&i\l:L169Xk<h\cF:m^8yd*:G:AH:
*TDP$u CkS^q$4LbBkTnRP#:+\n?&p@PPIGyp4:WwaEBb4I1E9ukjl+&>uHm/BbVAKw@!!TE/@e#lc%qhq&W\Te
/S<GWy Bc/Gp#B9JPiQYE=%^AKBMuQm9<h!uyk^R:GVFcum6jnX!9+>qyM5Zyim^eFiB+jHDLmB%lJXb#$QXY/5
n+nbpC #NCjZhyJAqLyW8cKPp<QDIXlA+p9BMWlJBF?Rk@:5lhB+S/^En1n4E#Q:<V\XM>Y/t!Ku+eImeR?DyT>
h&#jtn naK8FVatwFRPkM+9#ud>WqTn9MceJ#dYyW#i+ylZ6>CaZX8CPTR&yCcBDCcu!!9J@KnHJL<qF4eRmPTN
pp:^u8 JT?6WHRk%Zw+#/HM4Tnilwy<SmZQm+SqICZB1?BAIS<F<ZbQFy4JnpiC5!ID!!kIiT%ITZWTKalSQTHT
mLa^LL kaXj\eFAkm9dV5qeK!p^mT6!utDwBp^P&A=RQ6Vn&qPJaY%KWHLWbI<*n91BA1+cQy//uk*nhH?\>*VM
KV89Ln F*8YI@IVp+4KdkZ@\FcIM!c9@K$/KtIV^biJ^Vy6$!pWmmDc4FHetPE\EBmWXBRwMtR!%HkGM>/ZN+XY
ZtQwD+ ^hDEI\w\P>55JpiGYQGXihFmE5M5wd:Zh!8V:!#eK!PCi^*45?V*jbX<KF\Mk!JIQE<y@?Q9=41a%4wP
RPjbRq tChY:*%Hw:hdAH*<kjnBiY#%t5>k9pwmIY+8aj+W$AMVXZ&kEcME%G^e*Yq6pi#6bP%n>1B!KmFJKD\C
G/HHu$ M>1D6=!5kT%M6Jb:C=^<9FQe!bD1/:^ye4^L\*TM$hQNupYt^&+C*LyLX>1bCqM8:iK=9t4Jn/:eyp\M
u=pW%F i86<V@1B8>hQu@YZSqY^hMIpDB#n=>\N*1yI8V=9mlR$WHBR:l%\=^aB:%t\EaB4+Fpc4hYnq4eDdI$u
RTd+Kd ?lNd:mF/bB>XWbhAh@4#Slje8p/c%wdl4=w$!89<8ipipeMb$p1:F#tFJ^CK9VieWm1SujeqR=6XHkGI
BR!@R5 hd9k?<K8QZI4WGYBB<CAk4$qY%wh*@1k4lAK5Km4h6DF>&PmBpBM%HJlEA9yybC9c9%GAI9QJ<K=>N$+
HluthM t*EK=BDFXLD$&k\pe4*QTKlaEqZR<B6L8b@lpiybAaXn/>%lQtI5%d\hl!A<QdB1e5YEyXw1?en8?P#I
hSRhZt Eh4FhB#iu4Ghjnuk<#q:48q*#PJ6a>Ta#YD5\LjJbVJYD5SC^hLdd*aJCtPQdBuEh@#LKHbp#KZ4nwqw
laJASk Dm5W/^lDXQqDyR?$?:H^tW!M@dCB$NkSBHEM/4+h/8C?1W:?$uRt4q?%cLpXZZ9VC#mG4XiElw/61SAR
!E:#F> :KMMXn5+%*E!ihHFdMd9YIy/5qRkbt&1DqF=C=uj1D>Pl!A/e#RMh<HnQkI+chDCJy#ZBk:\\*mAcCeb
mK9aJl d<X:D@nLuFGicPYpE#BEySYW++9^k*Wt?ZHNnL<ppD8$h/%#JXjQtaHIFFMYehCVH+ZMZWk^W/EXR!j$
EBLDJm 1b*JFwLEn#J^>tMnlSH&Yee=Ll<nb<KCS=LQ?*!ZaJHZ*8bM#E?1DjW<45FcFVA9bE=4kYejmHZwlFuK
A=BQBE Ay%FaPNRdbATpZQ^Qh/GbbZRF=RyJLi*YNH4i8kW^Y?iXM&KcGhi$^h!kJj!>\a/cS9wIjqXT?H6\<jb
cl5NTL Hu&^kyGjuX6MqC:?:lH9@yKhy<bjTN?1aupytTKZyRKV*W+hZyh>n>cm@dW:D5X:bn?#9Xk#N@MS#p=?
AmMk:c /y!mCNcy+NCJ#%YRRDVpi\FlY=kK8p6^QwMF=F4dnV6>*hHCY?k45a\T>8ABdpw/PlMt+ViNS+TwuHIl
=54:eZ d=tJ^Hp<8!p?Ca8+nu8q6>B:Mk91=Jkj/b&IGT?\NS:hY>Pe6kYy:9uK&WJHknq<MHZX4C9VI*^KWQiH
LqAMak %l\wu:ky/D$t5m9%pC&yH*u#ERXS5ILG5Bw/:bkkLl\W8AA=M%Kuc$*cP?:%b1GYGMQP^HDhPc!$@Gk#
w:G&^q HB&YEb\?L+pu^Im?W\<bm/5TQwqMdh/$pIRMNl@yFFj%eS#tRmcjp/91YJp?EiCmq1bm#=!u#nMVhXG8
A?WcGT DIWuS<u:Q8\NeuNj<?&hq8KuTB@DXY5QYj1HlVa$#W64W#@6Q6AC>bSdqemC!b6FDlH/R5Y4>:tF>!L!
Hq@/WJ cdd4!6iJalM1*BjccTh9%MHpqZ#y$NFmHBHBt6$h!:>!n?9WaCG>K^^ZVBWZV1>pu#+?t*/RcJLC*6en
hj9%RY 1KhnK#Ii@1yVk+RL#mTl8IFAmNy5KbLKCAInMTB5j@<&uZXaYyF/pK4kI%1/Td4Z<VYSLDa>u66$+aJ9
Y@9E6a 4q:Kp&9kb=G#CM4$Etc&qL\nSaGb$c@&iQH1#m4%jQcI\d\6&CH#^c6AHu81wQbC$T*pEC8LMbt!cS*1
JT9&W\ jtwGm=:9<^KeDRc%GTkRmHME:$RVNF4GH*WCb9u41EYZ>MLkcKC#q9#\N9YS\K1Amm&F^LbN*Scbu5pe
Ck=<ST quY5$qRKG8k^wD*nuP@FMYbnt#ik^KdaLwpC&5tb#*!e@M&/lQH6+:aS>Wlh9lREih+mJ*RMlZd9tbMm
Q\%IP6 !XPpSWkE4RuK$et@TA%@B$H9H9+whNB+1++1\T8b/5=RhMKie!R@q#YFq@Wm@eku9p\=WD/c<PW:QMVA
t\:^mW I9SmSB\1/G/h4<:+k611u9XqidXPe8uei%FhEwI+GHGa6!HnRiw:Z8bt6=<8/SiTEWjp1@\&+:he^Rdc
1lL:H/ <@u1mMZ#b$u^R5%adpJHHuKuEbLtNGp:?XBMij=njt$eb/=A#bHF+Q5Zc99HXiTF>p?RP14<ZE>KFGji
kHaQ^M NGP*6:X#u!Dh4Vp@1i9D*8bh%jkMjk:A8Y+ynXhI45wyQE=M8um=y&Vb><Cp\aRhnT+n9wAqFW*jqhZ<
j&*un: Sqe\\>IEBclbkiHelTlCwJDhBtL9?C4DDcVTB:GDS%ae>\?^mkJ9YiB*SwewKli<w=YlAQ:I=epijiwh
CWt#BM hPIbDI4eXCZTM1I1EwT!?^\RLN<kuJ+lykBKEq5A1!puKmk\cpuwKGGP9Bdi+NShkL&EMtF:FcdHy4QQ
w9/S6S bTkMe5Z&Jjj46m@qBDi$M^IkkDbC<6=SaWVbqunViDjH#lwTEFM5*8X/5T<luAKD<kMB%jNYKSHtWnLX
>K4Xhc PVA@q:BYAlJ8?MuE&J@D6Al$?eW*Jl#&bL@=RD+8MJA:&FuLkq:hD9Zk6P^6YYDZkCi@dF&ltdTEiF$6
!6yjY$ A/W?WwNYXRE6m9$X!5Jk%QXk<EMc/cE:lC+KNPeD1jBEAca@#a8Z@FC%I^q&4K#DlV&FWy&aVTXku@#P
<JBdBQ J5dPpw*ZE68@%FVemqqD=59*T*=IkQuPy8*elRKkuAue*BHih$=w1pJauI*DX@?yl#QRNIG!15NI6G%t
+Q*GTh +B5&BS9<WB!$NVw6yd1F5i*d+qtCWq\JmSJw!+/eAYBP@^iyp11epY/+pum!&PB4Fe%9MNPAeS$<iE*9
=wC=6/ 4ln+<DtP19%Pc<%I8h&Nj5SlyWw5!S&+!kX&Nn/KVSXKX6B>uQwQ=*8&/BX&$mGpC<*/Z6%!^*RRFi&4
ZX:LBn <kpSKl<K8L^IqBR5WA+CXlJ/lk!?TAw6J5=nmlGEZmJ=eWh+#py:KZlyLk*hT+KIFuiDPw+ZWIwpR$LF
-AaKP< 000085bfcde00110333 Page 295 of binaries1.zip
AiBB&t RwP:@\P!MJNT?DC1IAIJ&4%8n#q&pQqJ:Jp&j^SB6PJW&Lqt1t6ZYa=iPYIZmGwcR$d9lpW9!8>#ZR5@
:l5hWu =c+:XTiXI\#19&KMj5N+Pe$pXyV$/RZi?u&lYX!Ra6LKSVZ%iDiN<ImZ1nljtRdGyK>b*Hh>wP64Vh86
Wnh5+V 5VW>Bl^hDAw4Gl+cP\E4lS+dcmFaLS/a#BeBeFPD\A&89CqFZ?H#@G$q%u$l$dW@h<>\59/j1Yu=b&/b
ct&&uq @=wulyQ%9?8JAdH@5!eG^Qbj<<V<@WS?k5B@=+u=?<u<$#48u%j&@&kH>y@:Wnn@yLdkQ>P@<8N\@pq6
B\\aDJ \Z?t@+n/@ZPc:Zhw4q<aFhnaj+j?SZM5VndRd>B@&HQ@uPd+T#Vu:>D59#Bw5HH>D5*/K=4:N&m&Z>:9
:SwZS= j/X4j^<a&p1t6u?aIQ/*aiJ9QqSTFpWVl:>>aj&=<6i!Mj>dRV<PWlbyC^54c@ijI^Q$l&Ld8L5yY:mK
Q<XbPq PVp+P#u?MdC+TZ?PHZ5uX#XuE:Pj6LmFy+&blbT4!d6@qRLKC94Q!\IKdTy#W&In\RTKtmk*tZMTwaTI
wDQJCw t/y\=&p!+WSIt1p$:ZwKpMSIt/9!WCay$CVIY1k&t#ea5CVLY/4^=C$+pAIW4hTch??>ldKW4hX=1dAn
1^>+Mb yjJWdhSdLDk#qI4WdVX+<#ZL?j!4WLFc>n#dnc1$:VZ=1JLG4iy$HVSdLS4Yub4$HdZ+<ljP*4SyhtF>
>D1LRP jkS@>8p!h6dty<bB?6Su/1Lhb5qFFD%p:14DZ/DF>HuM$p&uD8we616n@%bZkQ1#R8Ge4ah88&WnXpcH
MR=H:A ZaPiRMGmR?Pc+^66:&Aj5hbN=:j/knR+pZqjN>=y\*h!bW\i869!j!#WK9jdQiVVSyl<$:=^?hcSFLu#
B=d\1q <*n9/jWq\c6R+*4E^PPLpaBYacQQ##M!Ew1?iH16mc/>j8yCbTl//b1T^?\SqpiEk?yBGpPD:aql^L@4
Fjh*RZ 1Sy%k86XQ6qA/ET>FX<Rm!XWkKmh$IjB/I<TG<aiRKaW:lT=m4Aj:K68e%<ieGy:R%L6M8bHXuh%cpe8
Z9Ve^w k*AdSDpe$ShJQaK8dpR:EqGZTV@Myq@NXM*Y%p\1y@4W%!$*T?kEHJ5FnaIGMMTZYedhQml^Kc4&:jD&
&WXu=t 1iXh$W:e4HEIKM&aQ\4*JEDBpT8:<?PI1ck<a$l&#XtR5je##&uJ>NRq5uLPXK1LKjTA=pX+b199FFS/
nPu=+b bnJWSNV4&4Yp=#Y<$VT:=^NN>PR+<qn%li/\*wp81n>@jNbcIMI^HpnmCNXiX6?GphN55N5#ZXGGI4F6
W?*KS! Y5m9iq/=Z=&&%J8/c*X8\y+jSquGEynaZq9Wt*Sbu%49j68DE*T+a6DaY81TZRd@jyGGmSlCb$N=jEAa
TK11DH iM%u>/=t!aLHj=bLEjNekybD!bJG:1=di+h:hnl/a*nqXeP5ABy/*:#tm$m<eZKRYCnH>%I#H<9pBi%8
*SZj+6 <^SmJ>?hCGKaSC6H!/C$9hmQTpRdQP+Y!ZLN<h:yqm*M*6uHPk%i1Z99w^\!4FPkI+EtK^1j4YaZFFMD
deAd9J 6^?mcp95Yl$45*h?aIhY&L&H%141Y%H5&>^<<B^PN&66KG!^+#NWTDliZ8l55Z4@eqHq=K#=YCieQPD#
k*=qe> bVjqFT9>BQhiw@GRj^Eu#+p\jH$+t$APL+9%tRF6\lb4WpHd/e:6ZTiykS4YFK8*G<1TuT4^*ZInpTlK
G!H5tw ?Lp<%:9%H\KPep9D^CRl1$+qWQNHR\Lj1nE>G<JSc:a@4mIejXD\PL88FcKbtu>/%T<@<%:hV@qiL/S%
1L#uK/ PP9h&W4^/KNAe9$1:@dpC&*#&5XXC@b=>eaQFi&:eK%=J/#JGe*E*Td=ElSEDCI<eI!$X^AV<RR6AmeA
!cTyhd YtcH%b#+Yl<l$AI=eyBu9&FHb=jBVYEB4*+ShV1:DMpQGJujQ8@=dd*ZI8lMp%\WBuLdqMHSScEGy$ud
KE\%>X AeMAWT:E/kFN4M<FPyNR=I%!<RL*jhHPN4?Mj#Xhp*l\KWa&iL9JwQSlY>GT&+/:E$?bKkpnniMiecC?
ZcFMIm ZiS/4QndciKqMdMIykX&Thm<6i$<8!mX5b:wt:+*T?=S5ReiG1KcXlkE:p\^FeTWpy?p<NL=cN^XbBWp
^*DP&+ *:FnL8#c^cuK6+LewGBT>apM$KdZ?8mMZW%A:<\h\:BF><PS!RI$*c/>I&TG9SE6Hn<u5#%D=8jei<tj
QIIGd$ ^mc=e64p$^+9=$C?jW96TMR>*HI!V#GTlDJm\@68FESbym$Tc#M!HMDA6by??W+65Gj5dwQl!?&*JLXW
\n91jK ZjLmG?kDM<F*N!+L9ZT:J4V<l?q1PY/V^eXCCI@#NBiGaGNHA/dYcT?b1E<D*X#na9KSiM/YBuBX45MT
tQ&88= G\da&jHuRew*G1Lcie?/tK+MiL#1qmdm=&\appu<S^Kp=yC>mWmeZ%JwVPAN:Tp#&A*D%NRIFMbc$!PB
+QJkW: qnG<DWG+bp>b94hN\@P$u>YQ%8YTTqIV%I<YSej/DYP^XHQtLij^CC*5mlJhe!X%K@Z6pNmT=qMSF<J!
+^A+5V <Y\CME51:9*pR$IP!qk91>!^5*4^8:FP=5$4E%a$%IK*nP&^HK4mF<\$$qA$^/k55mG9ceYQH<Y6NPL4
ED!?y4 EB?tqZkAX4S4u4pN&Cb!LWH/PXCy%dGelu1+EN1Fh/B/VjyP+CwaBKMBL49!EbQ8$uZdcZ>SDjQK%y4M
KH+ca> mX8SlGeL/LyF<#na4MJm8MFn?&Jb4qDw9JT%1a!n#%C:<t&GN$Riy?l=C8!kX?b/X+Hu!P$mL=wuW9qc
AcKLRb Hd6/>!bM<ejT>iiY^bjEDdX!N&hK1HwN+i6NSkR@1w>w>h#$6i5jCH\Qk$u#c*Y4%?X=lFpMWS4uRV6d
G9!MlV mKKc!dFeA>1V?Km<VJHTqk^hT>DjthLS\qpFK8yeGW6F%y#F#KPpB4p!TZjZhF6eQXY+4L@SYYn51dE%
thw/6M /EmqmDFbLC=@b45*<WGkwLLWH$?=pdRbF@>EVXuYu#a&jC4y85N^wH?YeVQ\n64/pciQ<C:#F6y9Tle^
p>Z5Jn !Kw@NkNEHV16!!Jy/aDEeT5bPcP4JG8n1yB:^jk<5?KpcLQPL\:1:?=L>XG%NXAw8EN/HMDQ%LShN<n!
j/&6NY pLPa+i*W6VP\X:mL!q=+8DC$t>G1eE9/8LmKat19TqeFYlla%tP^6DaI!PQEHq@SW#K$D%iy=^^aZq#X
hW9VBk W#p4d&?<E%!d>\y\hVVkcc4@54?8X!u5GJud!lX<Nd$1JH@t9hj?deB/jjZkw>PcVei*d&Cd+4&?#wJI
+Y/lXY *deh6*N/$aHPM?KcZAhRY&9!pjE^Y9*hPn\WqJh?GDu\aY<9Z&*G6GK8itBcl\9S!b/5w%%:dEbk8aDd
nYt4lq kSEA<K4Q+><H<TkRS&NR^RRt*=HRHC48yGAR4cp$l*JV6?Np8:EbA*k/XiA?GBYkjyTbGlpW&NZ*Kdn4
!?Mqp@ cB><G!!:abGYha?5M@#?RtcuLVQ8@tQcpliZ@atBV?a%<bnla!d#L6FJ8<hZu>qtI!/Wn!lFh+yeG!*j
M=1kiN jM/<jj1@KcH65Ap?Ew1nDMe+wG&*cVtSEdd&ji>+h>C&wZ>L#DZ&I%ytqW<4?pI\6\8%Ct##&hj4kQCp
C8QdRh >@6=+>iH#8m4DAn&K*JZWynZSFJDw?pjL/E4:X!CN*ujBl=<HA+?5p#eCHG698>MQJFY14\Z^Cm?M^Jd
HVSWAe cB&e?Qd^bMy:Y?<mdCQy6C&<$Y*@?aD9&>uhq+*4B=d5P=@w@F99\1iQLQ8Q!B>RVJ@8tb&jJ8I8YG/@
h^=MFl Ki:j^mA8utQP!#kDIHmjGi&jui:QuKJiyylja4k9LkS9Jp+kWawlYdIlLnRka^RA!Kb<T5d:q@lZW/m9
TSt1iX E=eZXeAZFm?\M*NLJi49T5GuFcjQ$ZH:LG+\=%M@HQuQK=%QpL9lFHekWAwPw4+jw54APc9jGH<GPJp@
SY:tw: XuDB5=#BZGVCI8>BKFHAIJGAm/KChSF?n+lFM1WAu#Kp99!/&iMGXdu=Fipd8Pk*GL>ZJNT=RiAK&iRG
L$D$Xh \qVJVMZtX$Z%S%aaNGaK^En@I#R56LMh%C5!hIhHhBW/KBWE%GuebXaYADLnD84^im#n4FM:Mm99u1Q>
5^b!<w 9SQm%@Nw6HEM#GyFK8T5a<YC?%nRiJp^m?QR4jIuVJcKq\9$t%n+<?qR!K5k&E5H5Jm+J/XCdGdiT/Xt
iBLhdP :C4D*cq&QPi%$@M6#B:b\+5Ak1w*BMNEEBi84>G9eFh9d%q>\FnPj\DNEJY/\XV1Nm@1AdF=B<+6D^j9
$81j\G mC>6n<eQePB!TJYw9&&CEY#%VeTP9X+Np%=?luapk=!iB\MG\AIqd=Ti46H+mF&P5H8aCF%^h%R&mNlw
pAnWm9 #/?&KXYcab\y9/N%p$/t\V86p$RQQEeF9>RI@:ktjqGq9EaZR4k5^4\\RpByyqDq9EKuIHhJwRRPpp#w
P+t@Au pAKy9/P?wXI%kZD8^&YLiGL=VKJTDcu1Al@uSDbVn%en8Yp&^FKqC?hTV+=<lK61SZZJjc4CYa>/R+kP
Ddu?S9 S<k/eX96#aVKl<nmlIjcDXh#R?N5^aL?!KV/A:itpk#N>Bm%GyDDS^>ZTl$*T/nK8HG>I16+SSi*lSKn
F4t=Vk Tl+>Vtn@!uCPl8\El#MVRFTF@VBVT?Mc>ZWCl?V!mlu%G^I:&$PWF6WpF/yK?4RLP!*4N<bLC^buE#!&
&=q<=H bVypFjbbJ$dWbmKYLXB6NGE<FdiKAZh6%1wd>Xb<Lt>=NcbdPS>VKFbbKF>6P>>NN#>:Q:@dMH<SDc?b
4?PE8@ eYL<9IDd5pD685B&M+:cJw8Mq1DyncDw/ad6#ASM&Jhi&Z+H#bVcy\t&tEG:acEAZW+IXbM=VM<ACRFM
dZQ^aG /BA:^\T/\GB4%bnRTBH+lA@W*EY\#mq\k9IJ=IX\+kpkRbA/Q45/cWdSje^?Y?t69nYDm=mptXlIl/$W
NNdS&Y yN6l4jCIbELBmq@C&$#GS+pEaAZ6m<Q?Rk6n4\SDVemem!Ttldm/j&%C4w^a6dkbp+Vhq&waJPuDS$tR
DV%ZRK nbnX^!<k@qAydEQ*bGQydQG=ekWKFnqJ$jcmj9qB#9nTK*tR==BM8MRBl9#Sw1#:h64eS&>RFX9hypMC
^KlYk9 hVEtm+1pkE4hbhk?b5m\qQl\mnlVyaKp6cQe49ehIA$bD^^V58PETiYEVlYEdPcPI15BNMKCb$6EWXb:
RG#mDa XW?Wp\$j%5A<V=*Zpy&#E:tFh<dmdKZ#$JR#qn=I1n%AnN1SWbR/$emq$dkL=L%h!:*nFhXIb6QI$DuE
hP&#=Q $LZ#$bP9%I4ZWMh1%wM$$Kiy%W@W$ZZZ+qQw=9cuMjC*ay>6=y@jM@R+M1\@M:!:yI?eFy#@aXV@dHRQ
:>%qXB b5\Jbi^Y1K?JJH6cdZ!QQJKEbd!Ab%JjdZJQy1%JbiwlLip^d<cWV:IAa>akaHa9a5+yaXa:4d@A/Pjp
dtkltL S:KkaH/IbMHS5cCybSECbnE8Ba=6bmq%b=pwbIu6QIH6Q8HybFY+a*YGa5$btM<yb**:&aa#adRlbAa:
=Eq8Qp $1c\$id5YEa#%%c1$Dbi!@c?!6P#*uKlbYTl$!1yb$S#aDKy&d/k*@=$#+FD6aVDZTIB\J8$4hP\^Ji$
p$j!p> 4uu$Xeu#SMV#p$*wl?SdaJaHitQh^CeRbSFht?5wp9Nu#ERa68yS%Fm+eNHQNGIeZK=$5NWuCtwc:C:j
iSadjj kItL<C:#PC+\BF1D<JuRc1KnDl+qhaFekQBm/Zl**Zn*cEu1m5?qjC/k5#eJ??<^*bS6kLZDTK/\6!GN
Fc1/D8 dt>k?D\ZdcRdubRcE&Xyl!Ly1!Y%Ty%!j#nDu!cMCuuYSTwtPL4lhL:XK6VG?Xl^i?RYuC&D$?=6ZSA9
CFkBDH E%JZnQJ8bE>%L6#:Y@jdd%h9m6&nF:<=HDJ=cdYFD&!@8^Y5B8*ZleKIkbdjn<JHJ!P>==yYVjn^5ZFS
-AhI4m 000a2c6360b00110333 Page 296 of binaries1.zip
<>Su!b Vb*F4*HcV?6>8dTJZKte&%^V#dGj9&Y:*LjWaG%B@<bu9@w\!aZ#HIyqSY&+6#Jid:t!G8wnqh?E6YCY
4X?Du! YPCpTB/j%<*61L/lDiQ/WMy6Y@<>?k&h*N9mua@cdnLjQWLj4Ae9=kb@&:jBMY%IwC&<=ZQt\BIhj1i!
8uDXEm tPGSnJ6<1%l!+tl>&Ky1G?@C9im/KPd>tdF/1F&qaMhncV*\t$FWkXmEFtL\b^tXSjWW:cQwA+nw6$i^
6cmWyY XpHl8iXBP=aj5i#6NKI+aBe/eiK+F/51tpp5yDZmR^6M:AaVLN*mT!ThLZ9n#eIVEW=XeP1%:nRL%ReE
mJkKpS qpR<eM+$RXc?YNckH@S9p<%5F?bGiQ\bNG?TLi/TG#^TELFThKJVkubTFnlTHV/qcE1q@1lP+/qQi>jE
Z^ZlGJ /ItRm6$*l6e%9MCRd1?W*n!i$6!j\emVkdjW$5Cct4K:/tp+tjJXy41B8+:MaQpk5!KJh4a/e\X!W4V8
L@A^EJ NBWm/#*1SJt9IMh5Nm>S%1ji:ATE:AjcmReeSq/cuBdRPC>L%kNZ:4c6iu>Kn5:^q1=I*p%c>G=?:wyK
&9hVK8 jw/&+Iq$m!=B@ww%6XlD:ylJj1yhwcqWdw6Xacw9Fc>*Lt>AWRX/I/>Q$WwCJj/u9G484%et^R/aIHC<
ZLWHN# 9CR:GQJwA#eP<l9:=ZC+VLhnSnW=IEam^aRRc:\NGIaCLQ+$NawLQNyu%yYq==X^5Pmd5tn%4/!C^#Ed
511Kle ?QH^LGmXePmuXH6btd*#bik:#BV^5K=mFFhiuDXYNH^EJGmy4&qW%bY=FhQ46RTk6Rud!&wS+yqbIqjG
%y*eXH P&e&1qYEiudN1i8+=\A?$nReEuVVJ>dqPqiMYkId!B16Byhm?yYdYn+cuI8<y*n!XSZLa^XN<t8i<uk<
nR*B9I lqWjTpY+1qW%!5wA!t5\kqc#SyRn@FWHVD/YS4=tYn$Ql6T>e4%QwMhMMDiXy8q5BNcVPnYj84Sy$Cw>
+IlS<L qb=G^$M*RhZqM%6c?dXDw^=hW:#=e@XN<$\t%+XCY#\CFN1:l6dAl#c<:4N&CuRjYuAG^yWhJ6%BLm?X
c%GZ+E F4tAck\Dk5hcQD*jm=cNG6RW8P4q9wp>mJp:*HRFiNhZwG5ti:\*ME+HyFDhE?iD8byG<u/^*I&k6@Y1
5jp:T: =Z*F%C^DH#9\nJ%@euYP+wq#C8@:*M^:ZHV&\SpdI6&>nk<F@9#<Bi?:PYy&l4*inKABKKNpTq65bX$H
91BuCj <X*NcuWHeY5>L:^!l%w%X#A?qTnw5BKYI@A#GhS?:p8VG5A\A%5:W^6:LPY@ud5S96j*+Q9R&cKd\YGA
k%PEG? 9XV486!PDPKNu&uuJ9ht%<e8=e*kt#Pqtu*\tM6RulYktH6Yt!hTtH**P4%6WCKkP:58BMN@^dP6M=yD
&/@Fnk 6bAKNjQRQ8@N\c*d\<m:Ncwe*qTnSb</mlhd!8NWV5B&^=WBNjD+=c:qjwj*pc#q6X>JneXSkXQ9dMqA
*+C?yL yN=%w=1989qDI*u%KINiKA$j=/5ZT^hSejj#\heK1>w4neuL%!pu^YiZt>YL!dZa=p:q1\dCuXdZWDbB
a<9n9R 5C%>yFa94^1?&X1Bw!%ZEuytk1bHpewc+b&M4dcYw\Xh4:WMq#uYX<wy8n:>#DdpC@LY>kbu9tW?6!G9
:FeH$? mhicTedX/j$P4eWMy9aP#99YuRNW4JWZtKpZBD1><5=Yy!=CCuy?lL+18&/&<l/YQRd$^tQ9>S+%\eeQ
V+b*ES #^5bZp$j&Nj%PbbFqSaim>hScQye/Tbm$l<Fw4?tt=:ku$#FyJ##&^!*dFXmILR:Ek&tQ+?mdY!@jGw\
E*?PhZ jB6NyEWRM%:NQ:\t!nQeWVj^C4@<wZVpuGGW*a8&NucmR&ay9b?RBGi9dH!J!Hb*?*Y<hY9\yidy\^:V
^n&RlI ^?Y1L*Ch\PhdB=4JhC?ED?#:X*hA:>clVK+bN:yFI\586AQGVIwTH/PmVQ@=V9Gq4?MLJQH#:Wa@TDIZ
a!D+kw P6MinAwjTKK@4W6e/#a?uBE<hNc6M+W8Ll@<<Eq==I>G1<%pb//6Vb&6YT<pJ<15EMmF#h^?<VtC@tJ@
mJ8aCP 6F/:1@AiF^#\cm!eFeMN\wd5CmIFwH^*J<bCAIkyw&uZGVIljSLcWYp/hTZCn^4Ka&$G8RyS^M6Rw89a
+EwR&* %!k^Se991^cZ6blRSI<Y^Q$+QVaV!Xa?VNDqII/X!Xe><kZVae=mKIa@eB<YX=VAmJ<w\FlyC//tK>W?
E5+!F4 nIWXF$XCC=a<R/P%C*%%d6b*VG1=HjHtm6G\m9?l9&&DFKh6y^W?6*L#Lu&V=j8cI9tn?dD=hay?QT1a
X^6JHl <nn/5hcI@kXbiMp&WJ*^*nDceq:uVGZXDl\Q9$q</#MZ%py*VPZYSdL8?6h1@4K^9XS>V^a<ny:^$mbH
MXG%l? m+jG\nu*l\#>C9Mp4#QL&ta=#M>\u#a8K#8I/&t$T84/!tMMHD1&AYG>FX=SuqHh9yMjlRRF>dwBNPMR
>:jkJG +F9==@d\&&&PAb<l&m:hTYDylCH1+XF5\+yPK1jp+1:F!8VJ5\Wa?Nd8!c+wnH5c4M*&t\Yu<G5T8Tb5
\qS>QT ?T8EtSG/DmwhEW*\JaGMH5SNaTemiJI!aw?W+8n1u&F/uE5dJumXE*l*8J\a51=qXTDF/<laGdRdtTQ4
!H/etS ?u#/^>L4&8puh!mw?Y@EX:pX/iYyk$SLI4:tnyRS<q?M5<#6*w@GR/wIn$/LRR4Ll<eR\plM6/RYVCK/
QLY9HM cpqNahc#!C6Ky!LB$!Qh6IM/4>6?RKuhJELYVa**Gm:ql85QTk4PnX9yc6dZP+=NXNZqKk5#1\5RkSKS
w9alnF KE<$MIt$MPb4^=$5hSw<MtEaMM@wc%V8<&^*byJ/L4mZlnVWF*Wa1RbhXuA+J6$NGQ8HQZV8:@yFe$BW
>lCAZ\ 1?<NG?5Q1::iP:VhjjWWCQW&=5cG<Ve8bbSm=tmM\kw\cjIpCVHY&85PG9$i^SJl^n&9FGnYtBn:eWF:
y$BdGk =bP9Rk1^WwKy>5%/tQk!5q#IQq/\Ymy6++V6#j1Qn\^mc!q*hiW$HCDM>WQb*XCHJhpYNcLCM<4\jLEj
BTtJ*E A/cF>P?JC$c&*#:*j5+JGilpb/%P!=Yy%1WiJY!VN+8qPH%W#C\#lZh4LtXd1I5pQ1TLT5FX?=HGptHS
&ZuT$Y ?LnF&qF:9nDt=HSd/hw<lwk#YH%=RLnd1Qi!a>tK8Ny1YQpluIJnkItD6h\puiA\kdMY8*hw@!wuIK&y
1SyM>M ^S+D:L468b4\9m*In@IGb:bc5iiy%cj8Fw6FKQ?:jTbE?WGm:i+QFZa1IlW^L<H^Y8:b>h1Gl!1u%8F9
6A*G\> !qKhG<c8:1eVawl66=5P/IQlWSy+Z\&ePVZi=M=juuwy1VuBk*M:!inaCe^>mFHy!jYhkkiup^4yN8I:
#ST$AX >Jb/%$Bhe#pu$#4!#4:5n8yPY#PhahbHIVJPqB$^d:PuQ9CTR:=R^A?TVP=WL#mIpicP?el+i%5Fu4cy
y59NCq FQ5H\LmQuA6akCZP6TB8mCkcDFe6&G*^Mj?LYWFACXpQn9R:NQI/Lay8JkMch:dK&HiGRIY6TWLcRP&6
X1:CwB tye\KuK&@yCqH=uee4b:pc&Ne&?@Ia*BtR?#$jS/6p^?NuiIRiXaqEcQ^X8G<I?Jw=cR4kpu*lG>nI&V
yG$T!S qJHBR%!pFI?QS:epq#=C9nGj!$^AjyB6P%!p6RAXGp#b?I#I+I:qm*Z1^u%W/bS5JMq>VE/ecj@AwebH
1KmV@8 y%PYHne##>aA#w1mGIcwy$m%YPeiV:kmDtinm9TlEZbw^tC6lZh<HKF=mIwndWRnAybXhuR:pZGhu<S=
i^NBdX intdcYDIn:A$!h*J%dyq:keWkYy9Gw#GPJhW\tHMVw9*bSJ@Z4MjHWq%HRB/iWHkW>pywX1IF!waRRiX
!6keIF >E1W&K=5#ITjWtKJPnHCWhDN?w=m:mny\ttJ*9X:6$!MA%k!ELTu$8*Z8q$8$NjSRZZ&ljAbuk4HNAhC
HFXKZ4 ?TMBk@E?hk\!JDBZt^:@WdG9^!n^*!W1mFbthapWcZLAC&/GIWqYCnXIZLlLHbK!tHTDqLiiMLI9!jEa
5FZ=NF >5B+e8WQti6q?d1%9CD\wh#+n9DVlPq9w*eRy#:AkBXS$1Z^WQE#Bk*pWQdwLtTY>Cutw+9Mb6K/e?iW
KMw!HS +:9Xl@I5F$Ca=L<FlA!LW6Ie$5+baZ*lAGZ@YPa\VGF5E^FHiwuZ=C/4MHG\DK?PHBTnleHJ<I/^WlEq
HGX5Fj qC!%eXEH\>B%@5LVl*8CiG/RH1%b*C&Bb@?8ktNSwYFCj1=b!=Q=d8Mn$Hc?i:Z:uSMdc89u8J894W8d
X1m/Jw #Iu$:XwNQ+^+S5&hmPJC+9ajGP#1QT?<i?4j:QMaNct\\PeZtd<yIDVR5?Ji5V>Nb&inK9iCpdBMRkp6
6d<%1% yHhTbaSNH@t\/5>t&/nQE<y1$+<p=EGE$pNQy&lhh%eP55I%th8*@I1&/Mq!u&!GV\QKL4>9iaQelAPQ
+VdPh^ w:EM88>HkA:hj8<qVl9JZ++nlw@i\y>AB=XTF&ybN*q1>qbdWeT8u4h\19A8/lSLI+Xn?p^#?H#%lqQJ
HD:pmL NW1Y!nleTLt/QWX1!iTcZ/>e=l#^\<jm$CjXW#J6G9Q:nCG\FhQ*QWX%CpkVLFFjLDlqhE#*tnQu#8QM
c\*F9R GQ#i%pL:MTeKaPMRl899ENMqQ/S^:PaleSTI\<^4Rp&b1Q5y*VWpkL4QDKkRSXMPS%a4\mGaLW+$51m^
mJ+kyS ^iTd/6Qp<<uATV&dqDl>@eVjm:yhS&K=@JkP/GRTAydqB6Xj:Xl1q%#W+bW*LCbF&Y19SD1hPAy*+CAZ
V&yE^n >yd*Nqi8#QC=>uMRTtbWbYq$XNVV9=:cy6b<c\Bbuc*1K8mYG>FCj?^aAu9aHL@495l+n5iNBq\=<tlj
j&MVIC clH56AZd8^T#DDYDCuciQ5hjN:Q*\@h@&$W#jZahPPX8464P=6@YMhWJH?NS%>4@MHX!a$w#pS<ZdKnk
DESIqh qCqucMBcEBR??ya:C@SkEV^lyS4KGuc\jXbQn$n?$thApSjL@Fu6*SdiF\$>haWQVQ!8hk$=LC?XB+#5
pdceZY #THy#uDG!SkEiI>SD4#5Vy@b/ck/?yiG4C#p?ekY4NySp1/Du%!cG6=N\:m8b4TiuR@ae@5dd*P*Hd1<
+B6p=8 >cId=mZ/pWwTdZapTPJ+1YcX9DG8P#&lt:KAa4bLX8l$u5JC<@dJ\KA8C+Di#Tn*48Q8+IG#R$#n4Qmh
?SSdMG EFV45%V^m6+k5B%in%h9RuJ/Q9S++lu4dKak$89Xmj9=wiu8<1L48<HBiAmK\EE:hQJ6m&&i!RVW#aNY
NB\^t\ 1V^9EFbScm=9&wq8lt<%\e%4/WMwl&$Z^\eAKeFykbh&q=^iVjJaaB%e&^y<&!WM5=ySdk>XL5SMl>5n
>MJ?S/ H<WVJ8>IHhqZ^6=G>JqMV4kA*tPqDpm+\NwJRXwM@l9dlqF:kbML>q6WNLE?ERKuBDZuy6:8htA81!^*
4ibM*S C=1:ICBIPB%Q%BtDm<Kn/=TR4+!wG&JiMF/+MWWd$^/:S&bDMH!4^&&d<KR5#eR+b9bnBTT^cG<wNWcA
Fd@6$9 /MMPW^&<GEERJ\RT6%%=ES+X#5qB4=$@kq6Bd>kydDyeB!aqbaJk8:lRuqh!H@+QWZ!bQ4Xi\Rk8IyBW
i>hX$X Z\>DZ>1l!FW5GcX<Q%lp*?yn#$mmBKJciy>KyL%mjB<LM^>a9^l!9#y1Q/NeH1c&SMm\iJmpSDy^N$aH
u859XN n>5a5PtIGtVT$Ry1@Q=XGB>RNb#ZM4*La^\cqkcSn&nab/4a!q:dwQKhaKY6dy8@Ld:^T&$#j?>cw%6<
i*+:F1 \jS6CTXdji+/Gb5L\R%J>//SSGqjN<XCK5T?KENV89GNFIIm@R&*%MPklF5qc!%Dyl+V$<$M8=qw:$=Q
w5y^6V */=S4M^epb\Iu\w+Ze!5RHF?QS<u8%5VQkPF\Dc%eEDAF\kGKS$PRXYYVIRG>yPHZuQbQpm$n8\nlDRm
-AB5#* 000438f3e3f00110333 Page 297 of binaries1.zip
&lJ@Nc jLQ%PkdJn8QBGL%LPwI4d1@TVpb!nl/a?l*D^6WYdpmHXuMGwV1:AwRFpqcXDu+Waem+Mu4\Sqhk>1%u
GeH$m6 qy+&1Vw$l#\M&qM=h%$iq&^P^+?5RkKFIZYWu4aWeV9lB9F$YbD*pD6h6%p&w<ntmJy*JGcb*Qbdy6ub
pJ^jPa $ZSN5qFu+V:!ZD18@nZ>>JGy^JW>ieLkly:b\aVpMbZH^n^Ecebl*FF*y6+k8dD?pX6RL8Z+tH\wl9nW
6jI?eI PPb$:kh^Yd%QZKlVVd1SSbRlEyS!+wnG+&EG<tETpuW6p6*lmwm:!aHd@Tb$pa\H/diHmktHE*qHE*ZH
F#?4/a E*$uE*PuE:6uE:jup=AZp=mZp=SZp/D4TjGdTjZdTjP:Tjj:mc\CYN^e&dkAZ99H!d/u!duu!h&Z!h9Z
jRt4X6 KTnAFBdaFBZ+FAjEqPn^aHLIBKk+&1^&Kkl&KlF8Kl>?1l=l1l>^cl=yck>=/k+8>R=qcl=%Gk6>ck>h
jeY$HM e4bk\kG1G%A%daE#HaR:uak*ua<jwn1qWp<+QW<$9aeZdpA<:WAwG^I<A$W?9We!:R&udK8yepct!pE#
A=?Epe E$R:tEGntpk@W$<#I<E\p*8w5Me\$<++beDeu:iBTXE>:RG6dQa=GIy>XwFn8y%MVaNdNb>RLbFZyb*9
8?aaP: e>!WYlCZtkHQ:JdCdD>I:a^yhq=EVWNEHWq5NqJp6q=pVwFjHR1pqm<\e!e:ZR+W>Pby>lch5^CcR=Ta
15%jB\ wcKh$%Ce<&DWRMJY\*!9SmY961e==<Cqum?691iwETT6N1/u%m+=+/E%^/R%Z</uh1iq$Y/mEcp=h/e@
LjDQYR q&m11YG8KYC8CTYuGWTm\jiw5Y+?u&<+c!?ptWE?q/?4mWYlaa/1Ij>Rau!9^tE!9?e$=/&9LtGtKTA\
TBqQkQ Q??81cA$Z?/ybYG:aPA&^=+*i@hY!<NH!?H>kwQ%E8Y:STT>?Wl:4d8*<%D1$?9BYl:Ptt9EYpSWm$^5
KEG!MI m*99%N+yLDA=#mwwLCG>Ye\\$qI\$4R\ZZD+wBZE1epl5\\X1FtQw\$XMy<S5<TWN4NL4HtZww%q4+&*
T%GW!W Q#Q9$jIe18$eEmLnK1Ej!wiX1CWR6W^p5W#q6a\qy8qh6F^89PIl8GCSNG8S5u^uNJhw6WTW1ZtZ45ec
I?nJ/h yPIR5/Sly%YjyaEq9XCiwCwR8wkXQSiyIbPl1cQ^Yc@ibQcbh>c:c*beRG>QT1?>ZJ>KS*6ebk&4Y%&k
kFaLE? c$$letqeZF%DYJ>1XD>SY>?mZChwRq?kh4p@aNFA>cie&u99>TSw%cqW>d%JDVDtMDpYF5p%F8juNCPb
/qPZB\ ywQm>iVtNJF5Di1@/6&yGK!94EQX4u5*G>V9cn65GZK$CNZt1c+9X%K64Qi9V6i9G>^6GmKhGbb9G==S
<1VB?> j!Wc@51$Q::*>i9/>HBp#uVGu84#kcB*&LVBS\PHhMNudCPP@k$w1BYmb<Q=p/ZI1/>M$$d6=b6WAWai
6pWk/# u%cD4Ni>1niC<w&laVcDaVeV=a\NbDe4+Ka6EXa+Ia!mEI*9WdckWSjt:%R4pE\\bW&wwRjLI$\E5de<
YW/BVF ehcSIVaL<E!CGnZEH:S4#mhWyeeDduB6bFR?EqdpR&=Vp&>#Wt^LWt=4Wt%dWt?:bI1jabkt$Y$Z$G<*
^a*N$1 MG\QMG+9MG*9M$@XwbqWAHi\YZiw&da\h*a+RV8cHD8YuP5iMGci*D6JQD5FHAQhptaD@D5LAn9:kn9*
6Li:cj R49R\49aI49Ww48ea48T+48cE48Yp48iW49B$46JM49l@8aFe45D<45LC49:m49*Tu9R!u9a\8b%W<\X
LZib%= Ku8T/u8cGu8Ytu8iYn8*n\tYPkBQ%TJy:4$B@d$ykHuVJ+6kw*%w+*%5p*%1WYwmYI6NGE6?B$^LQctt
PYWBya $L%Du*%tt@$C&@$G8:$#1BAVTY%Ql:&!qlBNuSIZdCbwJ:MBI<6>G!6Fh$9q!ANF#\NQ#\NDD!9J>\ic
5HRpNM @KGeH/!m9K\5Q^^<@GlX+L5@+HhI:d<QqV>V+GS=d4:9h5!BSLC#<QER?=%XR=k%6yF%SeSBl>9lq$m4
\PuhZV yHC4q@An:DiHuHFHuQG:=+GC\a/c+>&Y>%caKyuY?!tHL/p&Z/K6LPP5B!J*9wahLKRiWcjcjI$=Sp/\
A#WXN! =e\>qlR@NE#THJe??8kMDi&CpyC&6/B91bl/CJ%>>JIPJ^l>9CB+QGFn<@ZD$WTqHZd5MZVimYd>mcZd
^mK=Fi LGjk95Kl@5jCudcBVnMSIYNnpa4T$Kl5P<Ee&@&ap=ick!?hN6C>^\6>J+KhJ++Dy=/=Nm4q^^dhS+bP
<^%R8^ J$XjR&1@&i%:HTbNHGF:H!KZHSmGHP**uHBPPlD:Yu&bPj&+ePby!<@Wi1n^\!Ey&Dbab>9Z^Y=&!9=4
P=j1Zu t9qLn#&%wCN!qaQq+nuu#mHV$6w!yu*GyCy&m?\ZwcPp4HNmBWjw$HQ5:jPJZej><$QmQZ*H=VYHCWi@
ByDjbV wF%wc\Xwd/6:M$jt+\9Ld$/iRp=SF$+FD*9a#R+X?#QEqtehS+nWn<+\kE65hX6DC<8FXd8KX!ey5E54
\k9$:F /E6Q/jk9<^EDL<=KMJiNCJeD6u55mJeH!Jj*G5NjiK>\$K=w$DilRT=etFhcYFeY^HtCSFj?nHk\&FiF
?V?A>5 ?FiNBHNDpTG\j^4/!@+:Rcm@Vp=qb@&6tMbjSMC!5@$q?9imWH>F@$+WK8lZEdD59^PF!9YL#6/e:J^@
cWRpD: mid/T#V*Z/J=@m!L>n??cd?j$k5C5j+6ySjE\ja:cdV@4qL<@$FliHn?%5?eDen%N=q?S^dYj=jT?\<^
4u\RE# @1PW*u<ykj8*qN=@hA:+6@6q?:N/8H<>yjj@P:y#8@\Qh?iGlZcQhX:+!EtwBB&RlmWYLS46?1Q?@XD9
cQ###d eTYadE<ZL4<hKYa69F&MI!dTtQaR1L9$?yk>EAJ?9\Gyq%T+L6nEX=tPBhEet:ZuCqWbXG%YyRdXk/lQ
*lk>w$ T>eddw/JKS=?9hVLl6Cp&#Lk9KTHHASP8+4iM&&5PwRWWe1<%HcMcywbVNbc5B4eZjJ&4cMpA4\5&KTp
aVwG@b =WZay1wak4EuL/wJ/WRP\NbhNGjhYt+mjM&NHMj6nCqcNVdJn&\tQTuR\\m+\IRYTXdtSRIDZ^8ERkV1
Skbpkb NmBn4FNIBYHI4^M^R?V5Ta1JMZ:mn1CRZpaKX4:5+Xbqh%+CSbklH8NP:El9eFak8DGPkeup6X$XT9i/
^ye^um QqGEQQVV=yPqcia&!!Ce@1%uiFu%>XNDqT\D@kkt4=&5MH:bKbEhB/6jAk+J!$*el8\cSNqtp*=5wtCV
Ta<KJi Pyu5CYY==m/D8k!n^B/?uwk+p?nWN$nqquFRHkFjIEVYX%VJ&4bb%TB$ZD&?GdJEiy/IdMCN&&b%?!K@
EL/V=Z iN*hw<@W6MR^ylH:ABZj4J&%YklL1ZG9WAZ8WE?wtb9ELNLCYakB@Tj$/:p>aN^qEVuDJZpV9VA1ipc8
?CY18q jI!=&KiJublXBGlZ$XtwaddIei=AmKaNR6PXW?^?W#D*/Bm4KwVCLG8S8K:PnlcJkuIhbjAcQAw*wkw<
@V+/Z% b8j:icLPd8FKbNNiMiklbnq%HNmqbcnS!HJ%VkSjqi:I5<@q/iw?d/Ea#NW:LTKIBmikIDncMc1e9=E&
%T/c9m tZhH<QQe4EWVXLKKPCt=DnSmVZW1>#4RXL4i5n*/ik1<\ebWim1:ElhLKXILXDMAK9P#iu!+&4+VVL<c
4b*l>N we^+BZc9^5+nwuyiGqKJma:iC8#8wWXVNykcjJ6y?Q=1BdEQhPe/S$BI5=i^hMpM$QS*Sp=ty*VAc&YC
Eq>&KT jynXY%c!Ja85TPyVVqeyCWc!IS^mFp$*^qXnMS\c=!\!HnCaM>6WHyGAKqSL86qCyZWdF5CkF%&/W>bd
=n@%pY MpY^SkZiNS$um^G\utRN+bwiS$XAFCEXnjEW%ViNdY=V?$L>?FH$B9P:CduWl$5Xmt:4qp=Me+J*R>>:
D@hw5b ?Qa^WPJ*eblCZ<l/6DK^N1+bjGW*5?w+c^JC?=B$jhh65K&V98Za9w4cEIZnWJ/9yFt#\IeKy&Qp<CNy
eee<hj 5lK\DNcdTR%E1TjFmnl%$YJC>hRlmpm4I$tcn/jM*q5nXSNAb!$*R<S^PmutKNEZ%C&twR4dn^ju!A+e
qjW8t4 c?EHiFQt^//CTcH8MQd:a94#N<CJ4*FkRmSwB#SD$JKBWKG1YyVF!KwFI==mSt4WYFTuF&J*Z=\\bnkJ
aCn:5\ aIZX?Aw@yAScj/?E4iuSl9>ind6yZ/NaXkw%dtFBqb?1wik/bYMN1IZe@IIF#5Am%uYMY#5EZSHc9A5t
GeB1au ulAdIEQyI>I1F!%lC%MAMAHdZdcEI$8JBK4B6+wI&!HNJYQC8MHAwmGE?WlB?VaZCEjGJ#ImF/uZjade
RSMnN6 *KEV65wQEaEu%#B5yDMtSe/@I\aHbIZKa&\X*&:m%F\1@=FLLF=H=bKd6:&nD4SC#1/?u#$&jJI#j8iL
YW$n>q P9PJIjAnRqFbq:Z9QnRw41E8%WXKh+nIVjA\JPNwleNV:5juFEl!E<K+NeQIh\y>*/SRq<baFi8t?@qk
$+YVI% h+&$VC845HR46T$t<A^GnaMbMb6I==h\A$dCFAhaWdV4eM!$6t#FFlSH8i<tklnu&IAiuLkq#q6Yh6>y
wm<8iN XYujd=IHayiY/?HXa6ipFuybu#BXP=PD:99YwjNc$XYd&FYZJqJ8SB$t#L?B445&^9C5SbH<$yQ&b>Vq
?#*YPb 55^6I4iK8jcKM5jwR1ul<+bT%Nm5eP=:RZ/Re/t#yk+E8b5ie586pBmBJ%?Yl@$X?A@B%I1kmLdSLR@!
DM9Mb@ d4/w4Z!Rkh:#ThJ@bV@nGhi1GZe:LZdJS\^X%4jcQn41epdpVN$ZY!$/#n1u4d*nd5=N:5AVA%ww\w:m
$5#bJk c%Q!/&hp#EFC$*i*EpTd8Hl%6mkGy%Ww>>5R6?qCwbPDLh#:9=<Aw&K=P=a4/!>/8^uw%hiXFXhi+A?Q
T>:u%+ 19DJ@l46IytVTDVBqyi=miqn#XLcF@IAnu#E&M>$55wVYtKwKtQC&?*:9Ad^1\^Ga@pJl&E1<dkN$cNl
DJ=*C\ Y+%hq664*dpiFiQ:$hl6C?k8J?9/LWV?YT&i&#u9N/89Md5LjZ6/mR*Lt#RLDZn#?H6$%%9$I5!=4i5S
Ge:Y$S eiMWpylla!>ujBj\^Ic>>W*TDGlkJwaMJG8b?ZR:m5d5#%PViqeQYa#EpL4LYDWMF+KKQ\ymK86ny4P5
+^yJPq :@XDq@ed?6@H$Jc:WKe:iZpaqaW:SBZKD&yJ*$n=ya:aen=/<N%mZ>+Gu?6@w*Ct1\Y49a@1Ft%%mbl4
Da4!Zy D?n*p<nYm!!8kk!d!I<^aP+Ib9h$KHV1W?h<XCKahJ$^CFAehVNEBp91^pP&lqi?K#b/iI&!M*^@\lX<
DEK=W\ w?Bd/PXTZlR:baTpH8/YKKa\ZbGeIFciS$wQZm:44S5bL?KXT+dLk<C$KQln8y+mp6\kic<BiY$4?*Q/
5R:*D< =dNH?#8E*TPCwH*X!QAcHMGd\<&ACNWwqV\i\=&LJMu$6^@#F?TD=$j%P*5>aFw4n:tTV6Q+4D*Ly^+N
l<QqI+ eC#*an^Q:!dcnanC*q\R#W6?=pA<@5!<h/uEpt>uiLWWQ:B!m#Jw<Td^65AV!hcnNc*/hp\hE^GhD\yM
w\L>CA NAG!QR5YXZH+%uPA:PL5aQ&F<:PS%^n\tep><:/hi?SF=%TT:\PiGQLctak#=u8hCGWLka8$wKq5T:XH
@NZj*% Kd6NTjM^$Y1%F?&X@SZ*/H&G+PDNp8P^QqlhaYXw@:pEP5uu:WD&R*R@y?NeM$idMH+Y?\WEZ%Y9jp\V
KR8<CL 1/\QDDFBb<llXI^*bjecBab*T8I1$64mjhI1IZNiiielT6IdScdBD6d/#1dZ%A9I$5w8IZ5\?emZu^:E
R+E\AB y?^HLR%NS=RlpS8$TCQ+bjDJALaW>I#WjjaW&<!=puF>mDQR5JnnV4hG=m>BP+lB8?+L+cmW+qHMYdyK
-AEdda 000e64c880700110333 Page 298 of binaries1.zip
8Bq*<Z N5JRFbJR6Jkn?W*Ft=ctp*HKI%>MIIXLL%ec1JwpWI?S$YAqXeAXTt#%LliWuR@FwKiK+jWhTl9c=Xy+
QLYFQW ikty/Ibk+M:=!KEy1a!V#J4A=Ga^!a8aSMW\KHKki=<1\EWS#i6kliPw#WJa6m*lACLa@c/\\qt\^5I\
c+&CE4 +Jc\^kXp9mGIYcec9mP\t:8IyNhpkDlaZ&GC/u^<q&L</uJ<*^Jwq*wCq&cC/ub<+VE<Q#SCq&HC/uHC
&nlZq$ LC6C5Bi<&GYm/uYm1^W$6BtC4HEmq!*m1*XmqVp<Z#CT/tiT1&eT%kQm/8<pbBKp%&lpyGCpK9eA5BeT
@=&n#M NnJ!NuJMXS^mNlkmX!J!$lDp#XB!X\cm&D9mPFc!c#IKX!4!PD^KqS?WebVkdAbW%\cE1m^W4k4pyPRE
6/b@1m &Y5E&iywkBJ\Nk8!:Bjpc$wTWuFa*^La8De$NV=W1wRp%^q$%?G$%@E$M&KpeYApM$+$dIX$4uAp/Ac$
hRn/S+ M!aM5YepAHF\6k#GGlF1q$5<Z\tttqYctZ+tq&XG6qpT%#*m/%JG%\51%lP//&iYG\BiHDVmLB!\Fkq+
NLChwd k\^jZeu1lp8R!+=6V$?GJEwZWIwSc+C^DW$V9wEyy6<PaW4J1mlLh<XtKkl!:8KNNcdGIIY/5wYPheIl
&$>iwd 6cS&iae#:c9FGwRdG+tHqwkZt+EQ%p4A&5:NHpCI%p>+E$p+M<@m?wMC9bL?=/Ya\Tj1j5Q4X5!dBaCN
$u=bRW #&StI!Tcdic4deF^1?SFV/EqQTj1Ppi?N8CL:?b^%iK@tTD1Ipi/ilS\//j9j8YjdRFuR^FWFiJV8?D4
T*Chmm AtCK9PD/KRnX*FCb4JQMNkHADwSN$Cl8Wjne&pXM>uFMWPHbGEVb#\GaGCS%&AVbn8n8:NV8XKJ8iRC\
hib$LA BkJ*KXyMQ4EEH6E=EqFMGcFdGyKdbjE/MJG4DVE%AMuXI#EtBW?hn#SGQI@1CcY/q\^dJqCqt^W#R&aY
&S1Dw< m:W8H>?NPMMaW:%kN$tMWNd$w:+<t*1P4MA5h%JhST:hH8b6X@i$K%$QG<$^9hX&Q\iXK^#yC1Y9MK#9
%:^5t# lt!QcWb?#lh\V=1<XF1KGha4*m<X/BVp#yu>9u%tD$KZLZEDPdB==G?C:mhqH/ylkyqL1j$H+A9/<QW6
/%1Z*q GL<miC49tX>wWDMF&j8/$AQ>%iVFpuk\tIZI?=JFQVRT=4HWSDVyM8X6/nZ1YwD?Za!mAln>Eiu#d>q>
H>cmcB uTpAD54DubwI#>ythY$:*DDp1q^:CD1qn>y1LJ4^kq4Vc5yH:#9kMnDtt<BE\j@W#9J9i+Q>#%VAqYV>
:caS$j I:Yb<^jqeQ?SLj4HZ9?YG94*uNL@ew:&9&%W>q@I$iaC@uPPNmjQj!%Ht@Mj%ZL@$RCQ<?>q5Z:?\9u9
>*M!b/ 54d@91D?y/Z/u>l8RKDj:QnK?Ti6$9/EB9H<k8d/Db4nq<jt@l*/F=WmPj?pW>w@$*?aaj/W@yNGcj<X
AAG^6P t9W*cHciZ%!%Q&tW>me$%/>w>6?k&Xl@SaN?k@/%kbVnh=TN:ShFVVp=PQ<T@V9K>pebkn?uj$jb&Dq@
ZpiPHw pc:P<V9K^9p4M!Mu<C@S9/N59/^c!Qp:!kdm?5X=e@=y#eQ@?Kd>up&T@iewaQ<=a:Q#@H\P@J=SplQ$
=FM%uq J\*KYNu@/FDG#kaEMdNc@>GjVNQD*6HC%eVW^6:G*iduSQ&:<9^<Q9^l1AYBj9:nbQ<6iVn?SB/i9#XM
m$#<1E +?ICMw6bt#m:Y:k!K=k+tqn>$VFN#8KhG:PIw#u##&iq?>>c1LqcYF4<jMTa@SjE@KpNj=R%@q8yTB/i
hhmEe1 *^KV<@??tH<WpiVmIGZnb9?d6L<nJhi@6#mDRQ?=^jpjhTQ@buHt?bMPdJ#@8ln?d^icaQ%HwRqYH6C@
@ndN/E FJ4kaj99%bpAedF!@&@:64ma?y@a6%?ZZ5<B!CI@bdaAtQ5Cju=iX\FmAFnwQ#+@j<Im\5LAImLD\<LC
l<9I<t I/MmITEnIcGmIj:<ma!IlwKPkatBnwKLm+?Qm$6BVp=PRjM9u>e8AAI5RB@RA\bGDun6A<#<*DEM&B<j
#myyNR \N<@pFAR+NBkABlaPHkEXAA+GAREPCR+NA#E#^@kdtDkEGmRACk!hFaSFYkME*IZQ$!&&G\a4GySmt:X
W1Hyi% /T%&dNNLTqj@K!w^pFyeVw&bY\?HPE%<dm$un41=i?@MNm^%AB\<Lq=kkwSpZy*t4Aa6@9ZPVh@e:1&F
aMB+cB S%Bmju*@@N/hyYh\WpHD\ML?QbiWq6YdV=<LG\eZD:=^T&6d9\%JLtwcYn4<V5enw&Q#LnTq8Hq+?ikH
bA9A^S Qc?548*:5NTTqyGX++jZhRApAPq%BRD:^!pJAVJG#hG%JFw:+M6E@d#jCIP>AmKYJp6Ij6l*9AL!Vnwj
k!LP\V !6PPQ:*w5ZRi<X/<qFw?bL<Cppa9HlSdZ\Eq!^%FQu5%n!@^Fc?A+\cu@&8R#?6WYu&VBQP*^yLTbnMj
C@VKcD V\DJNS@1HYQu<audK<CFIjPlMt&8=lXRYn:=*Fjle>#lyD4/W6Ew>A&>?ii8j4VL5V!$4L$C%tRQZp1*
wt!?MV R\qX!SI=EAam:aaZqX6I%h^Wcj1i@@WY?:?:+?>qLlJAJ1VuZX>:YX5eiabdyWAnw:uP+/%*#/?A?XjA
nG1kTw %?JZRP9q!$*qD\Q9c^&ld>i9kLKNT1HZ/WP<Y59^NE::=X4L4ybAG/bTCjyQpX<=*I*lc#+4m<AW<d#P
%#ZYZT JL$CQ9F*9kI$T+X?wJE<#jy!GMCIlc$LMDD\1X=D&RW*BCYCRe+HqNQX<$awTe!CDCR*$qe+<8R#ESm/
^ZL\wn TVlJa$j<MNWe/$+MkwCVV#^:F\@%P1?AwbBZ\H+/$l/Dq=hZl8pKdB\6nny>NZtRMCL&I^TBTiGejihi
HRntl\ K56*1JhpKjKl?LXuZX^tA@QNBpucH#u*du%p&*%*byiSL+\Dil9TR!B%tEB#eZJN&%R+IS8yuuuMu@jJ
IiA*\I 61=Zn=cJ&eG$!a5:Np>=LB%#/55/c?wHq*/jwn#yw4b5juYAWC6SMJ4Q51Z<\e8L$X*c*jc:%>u@jVqM
^<Ftlh *eSyIkc$</ZJplKlyI&qTKXW%p\@Bk$?Na!?A5CeZkH1d1>#/i>^TK=ZYb/kPy>X^k@%jWd6P!?^Z\F*
X*=Mc^ Wq#bL1<Ayy?*1$99=@WuLBeeEiA=TKK&wY#PQGG4T*<VH!a%nRZAnDDiWBHcpQuY?DTjN1j$ded::BZA
bVT/j! aZtH<Z!d/iW#46M8@k4\y9t/ecMJw&$1p=?BE/:W%\Rb1$Ew\YC+nQpK1BqL$c@J1/t6$pD51$WFaB*L
dQ5Thy LJt?AuI4P#ia9q5?E*m@@HD1FZ1hQ#L/^=?I@9au45PVm&?nH@E/JVh<P9R8^^>+H=?9N+Khyle*LyKi
D5b?IW &D>G@S\VH^1*$t+h9n*8hTJ8@Bd6<:4\#<hb@X>dTlu>!ZGATQQ>=aEhRZh#&LQKZIYk/aE=ASRea=jy
Gnc%<u WeT45mp=\tpP$YGM5nByEEWeP8jR=?ep<#TnX<BdD=L9k!#HQDQ5qyP9m^e@@pX:^#Njy@:&NVaV1Ki9
X515A4 >IbAGGiV6MqnF*:1k=CNnSFl6M:11H%<*uV!eHNKA9G^hDd^M8+jX#Di:lX\kb#:C5Dhi=cmjpDPY=pI
D%ChNe LV!i^A&6hNly59dd^S#Kdk1w6>FuHW@:PX#?:RFu@9k/FJ%TMEjYL6uRm61*TaMmN9?>+Y9Y+956kj#=
1eRTpl ?VXt^*Z#JL4<V*Mct:Cm6G@uhw%iS6q$mwW@!:^^QFYlRw:aVkVM1Y9ta6R%#:t*TwMiDZT!G8wnyBAq
d:1q*W ?h\G8L5\T\eWi>LTDV\edEIR!qtb:wZDqlcNQb<Z@ea+HK#DIt%CnqT\GuXuu??&&V4q:VmEPRwFm@Qe
*DFhy: \=cCRRiN==&jQ>VQ%^iTW6iNcY9<JPjiS1>d9e=?KYk5GRtqjH>pH8M1mdaT$=59hX/#1DP@9MK^CPi?
p8VAYN umDqwHL#9NnAh>6SP^y>XLBZZbn9aQCN=L#M%jd>dpCeHjLIi/!\yel?L+uQD&I@d$qyZia%>ebL5iW#
C5Bp&F YiXQbX>S?wH^^@Cw@Sm#?HQCQKN=Ct*<PWQyhE4@9NJ*u9E9+15@6&Le!PN+BV!$!4\C!B%?dydpNIQ@
Bje$#I Cuk&!H5F^HL?*E/P/\nJ=/Xm^tew#ielQ?$&?PeEyGWn6K9R?c\/TQW6tVJGQLW%BbbK8h<iDn\^m>Xy
=Keyu$ Wil%:4B&+=*@54>T/VAB5X>P\<dQTe@:LX%Z=#cTYI#TFYDZE&Fky9YLkIARWZYnweue1c>hl1M+bCKq
6MAYCV Zp<Zqlkhwm4G+Cbl+=pjm+iPLthd<&K+bL46KFdydM^*V&*6e!lulRl!k9h\ET?qhj8ttK=5!k8^Rdwj
^1jdnY kmX>Vt8yWnPcY<P8=:kkiEh^iLYmkby%SWhGlNVSw:F%$RJ:a@GK8>NVNRD8T+YW9GLFEypVj/a/BATb
EBhVeD 4C<R>HWE=Dj<$68wMCV%5t?/DpbYjA11+Ym&8j*^SijlS9\LZT/dDX1>L5J@V5KuCw*#qDdtETM$y8h!
j/eGwG PHBH=#&jZKID^Gwct<KPEFK&*%Gmw>e#$Ri>><%Tu5$1IPY9LRRp54FKcBRdM@SB1Zc4R$kR9u@:nYQ!
qTpDJw hV=idm?N^5MmVl#L6A64nh9CGBb\ny?=&5HV%qkw6MwG*K#&G\pI1!!A:uKThXw$Cid$LLaCZ^$+Q?/5
9uyIiB J>96!^mtYh9??$Bku496t>Nq$iR8CIIwm%E/huGW$Md98c4ZmEH4aHA^@:cR=Qt6h8l/qXa4tR<tJ9B6
u%pQ6d M:5@jy/A+tQ//$J<bXLhX?jYW1+<k$P<Lnaiw/>1TRQlawyNdT9<PJb:V5Wk6TE1hWPXSDJ5wd4KnmF?
<*jbuN %6#SB!5iT6bGPn#>1mVbG>*yq+*XWyL\DWT#TQJI<kkXNNGmE&EwGQ*RX<DQch$^LVBikKG9Pm6jAi+1
Qc/Fe@ 1<h9H\H5/H*d>l&DwT&>L^hkBw1!mPu!/YH:M@=?tlQG/QFDS#!ti+n4?<1XuD6?!j*p66VIhQuyFJFa
>t#C^a cYmPhV?GMak6qZdFyeTFuNK<NX6Pi=Kk%nZSQk$bhW9hb\1ZPIVSh8KbdT<XP@bSGEHJhLQ9AmVjVA#=
CGCb1^ HnahNl!@^^5hya6EK#a#YkcnSuFnuH#i:pKXAePI9aV=?AqKX!dQ\MBd^&HQ/NcuHN^c8$k:&R@h@^X\
h\^meX jp:l5AR<bu>hQGd^!GNBdbly4j6ayYF8T*dZd^Aja$kN#@tI+dilNyP$<t=S5aWc6>$+D$C!E$XcZT>I
^d41%/ Z^6D6@Bql@qSdjwWVXiPJ:t^mB5<8%uTAlLRlR/V1$q1n/j$wetDmHl:cW*CjkNSbil+lnbZ?wp:RBSY
m&16Lq ceXpJw9wH6@4nFW>lNHTJnCekDIVB6Wmn5a1y^+<bD=1%W&J5K=#b8\qZH5mjACeEqVIM#8QqqGEJ&Z\
VBhbjH ^C@JlLGeyt*%bWD:m$S5KnayN!8!aYwyp*^Wudqmuqa9AhdZYM4aHkiLP$4nE8XkMS$B$5M6//H*AY5j
ujh\Ad 48S!Li#!Gw48Hdt=MQCMIYmQ4?K!Epp@WQwbJcpNF%Lkn8itwAIVGMDSle@\m<ui<#Hl*ChQ$ej4C81A
XTkRYG mymide+5I:6&y:lR6#/YjjMkjSRjj1u1tu^ZKH4<Gb8NLGtLeY9:iG&Z:hqkVb%&M\/eRjh&!SZZ^cSA
\?Fa*5 &*By%SB*lCAp#lELPu&Pk$F^j9J%/1\#/%Rw+Zuu\X^59GdXYk8%>ql=TY>mFFKP**a6*%abt84>+tEj
*4Hm@d I@WZ4#eQ*Xy^hQplLT!Ad6n5HdYh&M^H^8HIpb5+C$4j5b/51ZMq5TA#$hpIP<JyPQ@K\15k*W4!Y^NW
=pN4q8 Cd:We>/LScIHFLu9J+:%<bc&Mc6u>*:RHe>9BHqeD%j5L!nYlG9^LGTY8I8RR<lXlba1/AR#ES8+5NFi
-AMHq+ 00049f78ddf00110333 Page 299 of binaries1.zip
%dKhK* >uq&+qk?PZhp&XaSe>l8?e+@DSApN>emhjdjTXZe@u#@$d:H9bn>cQu#LdbX/WHC==F&=Jq>*%Cpw>=1
Bk1jP: CB#5IZePa9FFWKD&a<wNC@tGd8&8MPT#!wtIL51**I$@*kqjARX6+#@jZ#\#d<NiAje1pR=Ga+/$*#n6
<*+J+5 ?TC5D+wKu?4iEldXG\G:<Z8l?lNWTHMpp?^LaKy\MAhj$t/+u8yZjGaajw=ATchb\*<q\jmD$>nG>cLN
F4n#T^ K$D/=&QCA1>V+X*cm?/b$BHYK?A$F!NVdjE<^=4b5nwXb#p*dn^DcX^*M$J+5kRXM^JWpl$1NeeJ1!CL
SM/t9* 59Ge?mX=9&X?LbhuNmXZTbdNZwa?Zaid=iLipFGCH&+k:!HQ+*ak6Z=VmRBijWBMc5butSV45q8t:F$e
Dnqb<I TH8uyXbhGW9DkSAA*RXkbu5F@B5JlF=uM6d%:S1nn=Zi&C9b/uG@A11n:T*TWS\RKC5w*<V8YY4R%45m
:6%$uE kTj=LMbGQ#L&CFk>YZu9E&SP9^?L$SE5hLPlNDEV$k4D5BjRRP#PK&+BD<nu9cmtLu%*IKjAh@5qdS@9
F/TJt1 wu!15aKaP<6h9dG&!ZJuR6HhdwIE/iMp@hSyh5eN=l9w4!eVTHb!jHa#N*t\8Q1W15p:$Lc%=KM#mcAq
qSL9A? y/n=Tw=%bwcyD?e%Z*XTyycDkk!?\PX>C4:G$NL8na\c!HByYBT$i?lQtihjYQta>k/144SIPyc6:DNc
%GGk5L Q$>R:u/im\^8MM*&#pX$*V#L&uZLVc*L4eb*8n4JP<4GPPQ$XE<T!KKmiaL+%RwtL?b1+:d>t&%u=:nX
nmkh4k YEL^aRV>@F4b$8NFe<5aqBX+t=$IuBY@#:Mp!ZCDQq<^jeGqe16?4nGihPjKad1<1/nVT6/FZTk&#nt%
?w5NKp dh!B8ed#&>BL6I1PBhqPJFbmHVJe8jN6c#+MyqI@$%G<?/JSQ*58YIq%*E<aI/i%VX#hdAH%pVjIwqAV
yA\Tm9 :*YY=w8BIaLY#@WZeZb+RnEE:ubiAi%PdBM\$i?4MC!Y+Hw%T:thah4E!%8$%ajQ1N$M=i%Whm/&G&BS
kyhMV* d+^CDNR@cH^Z5Qaeqd!^GMm&5:DaH&!KPl:\8t&YXppIj$ebMlCPIV$?P4PTmiY=w/@IbQl<i?VaPVCj
uiF9?T eYdi%Bm5JIt6a&c^A%t>wMq<4NmVIMCDGPIV*dd#^\6I^?+4INZ6F>@&@wQ@?<?&hJ+e:dC@Mc!8PHw\
Ztk6yK GKl%nqpjm&phQAwGm/S9m+u8yX+JP?aehtX1G@XtVFyMTmy4&:RhhKEZQ4eBu!y>CJ$:d@%8>VwHW>=S
t!=Yj! Z4B!ZP=Wce5ptIGYcKnbiG6PF8PmCA\&dZ6ldTS1p!S$hTL=@1N!%5@n+witWZ+>!p!u*5QBk6KmAEuF
SG%J>a i!Q6w1PnD%nqhQJM<T<cKQqe=ZeZenEQk$KXX\j%A4Jullp8jNE@%QVJH^aZ8X&iB$99nq%YV%*Q498E
Q/ht>< htF<?q<B6#@Cj$+d>Ha#u$=I>G>6H1QXV6b5Gyj&Gn@Jm:$I9*u/?dKwqH#\Cpmp8u#I%Htp?MST+j%q
6M=A<u 46Li/eu*+u9uT!d4+I9/=+L/l<qC6b=P@b%SS@W#\<VB\1hmJ$pnySQD/N/V1+eL=E+WZwjFjJhQj&#d
ACFble %qF:NHhb8em>?HQdLj*ZieyZRA#SK\DuFVC:#=l=ZTCIwuVma*/=e:hSc@B>6yFSyuNQ&yZ@yZ1pMQFn
Z4kDTn 5?/*C1&@H=4hb\n=FjD#Li9w=\#&Z@pV$DDq=!q:*Wa&HtcY9<Ve+S^*SC<KKKq&w5C@Gj:=m96hc<yu
&H1W<E lmVjt$TZSC%#WcnnDti/<wj?>/9B+</6#8qFpkIl?a@SY!@^J>=9b4hiNN^iF+DQk<>Cn#@Z@D@Zkqc9
$d#uj6 !*@1$Q9ZZSn@^ZAFBHL@@*86@F@66hL:j:LZCu+Zk!5\9c1$S:kLt9bTH!?j4IRXywjS%HGIVZuJecV*
in%QpE hMS>Iw@JPtRmtA*V@SmSYh4$YC18/akPCVub<yRVbB@I#VWS4<kKShdde>R$D@Fq96uMAE/tNnLp?1kq
Ye%GyM ID%jDk1Ck+>mSC^GtFiXnnGKb==b?$J@^8!6MDDj+e:JSD5:Zb%%5b#WhI4d#$=+RphSV++MpR\\\DYL
jFePCl ycG>F*tZKKC6e6*8J/5:hl6pPKw^?^=Qm9FESGQcSKIFE#u^ePlwylbl:I=PyMmFDc1pjbN\#D<4yL8/
tF%Y4$ C9IK5h49C=FkK#!5<6qth1*?TTTF5WkElZaFl=b^6aa?d4@mmiJ8:VJG$5:$D!cdFM*#hA*y?9IF$Ky!
cTIR&y 4KcH!8\+laDMLG=>^te=BRiTBCk</tSWyADFDC\dF&WSSckcVKeWFE\1jl\wJt=l^4t:k8Rn>pZC9K<:
YIqH!= *E8/5=ELBBXZG5$NXwWS1X<u!/VFLD>m%>bkL<ee<^PDPM:XGT\<wCBG%c?N64M$klW9?#mRSd:u>?w5
R\QbL= jBQ\p1#D+nk^@JyYn554ih$yE6=jpih+nL#&:CJnkN6Qnc19YKqHEbpN&QCe^&b9^y/h1M>*=#mD<X/:
<cVGPG cT<W=Ft@G9j!>E\TTnN\&@G^P8Yc+%cyewWZ>eWV5*<pCiySZwh9eJ&1?#+th*4PwZ@R4il=AD@?RWXy
tSGCB+ 5!I@QY>^qe#ubP5>@yV\%PiTC+/K=%blD%kQuJ<LFpbd5GBkV:Nt&4%NyeFDdhW1aGaYT6Wb<T^Zet4I
%Z^88a lBGcb*^/5#w*BFFlDD<wQG?#8W+GCYtd!e<+d/Ed!>RyC@<S18V6BG8SN*lW:#i?KYNMPq#^ka&XcN>J
A%k6c! S?S!1=:AMAnwaET1Y#\R<^:5e6JHJG!Cl5DABh#bIP*85uZ/k9T#cb5BS!dGa@FN<+Fe&\X8/1<$k@Fb
d%RGL& d<d6JDmbaDeHp$W>KLJHdXudQ#B>R:etB4KGBH6<VMjKyW^#b8WwF&jnlF/^naI*Nm:+RmN$lEiLHYBw
VB>I98 bmj\RwkldchA\KwqY$+<tB6J6!NiCpJu+$@V9M*d=Y?I4SbW4hb+^FyLMQaP*S5nP>kpZHDJWqEY?hIQ
c8$bXA ^V@VLb4/SwuI5PSA@dI::k8!!jleE%&P*Yj/E/=yPNqQ:!d8%>58DRB?cqK#H++MH=l5B$FL#ZhQ*<NM
/pVJ@p XKmy8kkk&KRNeNWT\p>F:6By?$LAlMZWbeXuk%E*P^S4HD+B5kmpWJWV6K6IEZ!H<CCA1W=^w!aek>Rm
LaJ:i! SYLCTTt/A*C8^dde5>=eCTb4BaAe\CB5Sde%FVTyQCaP<G%VL%kR5uhq$YC%GPiaR4lejltYEqXiwK&K
qNEPai !SeJhR6%cPNSLcSuVZYu8:AYM#Ny!mucQM8QQ9&BmF:TQbSK:tT*iJ?hF<annV*5#uG4hIL6ncdLRdEF
!W9YhR Gt^8bnTqe6H!$yaKPKmPTNLLZ#=pVh<$T/IHI/bljAR5KKFnFLubW/!bmWSS5/5F$Jua>?TwIPpT+mHu
Cpjhmi dZ%kDSqj+lZt^y&FRGSQBGTSF$Ga#=KLDWk4a*tJbB$=L8\N=E/SLcwei66EkuQ=D51/1B!GJVG6TdjI
^MmNIi /*P&yBw8P/\pt$t&!$#\C4#N5dPRpt!+B5$ZK=w&c$GQ\jqLFKD1pal>N5VkDhEj@VlehK5c!8kIIPJP
+*RYV% SLK?4nE1jH>4IK^emBVB:q</4JyLCPNCbLAaeuu55MdQ>J/y6K=%k5tAE&4V6WiB?hQq?9!cZGPAH*ld
Ykwd$@ 5BI9pukEFA#!R+9GFQ=8hbqwSZpL9i#eQ6Z$\bH98mH<IL$m*9ydw1n5Ze%1N/4d=FZtQeb=XMT1+LkT
6Z\a!: *qqKS!IeheuDKZE/X5jiW5W1KdJt<GWG=npKuy/IVG/kH8VZ:NNd^P\>&pyq+Vk:ie>A!&@C@wkNt:9B
ELMY+J &Ck<+Z!kiRuyjJ*1$YT5nM1t1!ARYjpaMyipb91S4y<$/Vl>!E/1B4Y6>hX/<k?F+V%q+>+TuWkthj/^
?8bpwG Adtq#/qjwm\X5H=pYQCQ%M@KY=*Py:AH4>t5qBPkMB%l\im@bFQm&y5N<uT\uc:a*I*bj%T@tn@NTHbh
/wHje: +#n/bD?<8Aq6Q4pBFX:$ih!9A<TyXiV^k<&DQw@u<=cW@FX=@GDjFBT:ZHwJ^FM=>ZEp=%DPY<=VSWY5
E4<q<B SNtL5=6i=A<$!kNJMyiw\qn=/4CdtDcWDX>I4*L>961><<mbLlQLjWja=Zj4MGh4qnR6R:t1#h>m:!^t
jER^id %q$TDej^*1Ci/GlyNVcZhdVRk/mWiuWI:+8BGeyyA&GyX=1jBI%W!j8!pap9>t>hRRtTcZR5n*9i=PMT
4B9CJB +Y?&LaA*:FAHekSeWcGc?&H1:Yi6nd:56^5CiA%6C\@jB4>J$Et:c:Sw@dCGQpyIV9VIFJG%JaAGdPn$
LaYY^c L*@Gyu&@AP>Z#Qyhcycw8\jk?5I!eG>kJ5P!qhLQ^K4DyK@d8Q=lPX?:*:BStu%<jY*y@YYpCy6H>>hC
b!h<n1 Ibjet=MpPpRd@\pWN\P\!A8q1N8P#*5E*=YwQklXiDG$X<KYX>:mwA9dtD9XT<*QMjFJa6PlX9NZLnGl
uNpQ*P !^Jn6P1KndZ:uk&1H&ApDW@p?TjQS$XCb$=Tu/*qBGNjwh$S$$4a$<JYEJc#*Nw44W\Zw!hJWL@5TZLT
XQ$Bh& HZ6i:QJPHB:DMY?ZW!1HBt5y>ZpeFdEQuuM#S=nJjAVSwX9tH$iNDn^Q!h4KEJcZFTpPwJ5GV/XVtM>K
:chuNc YF1h?S1bCT<lqVmNN$L&1c@8wGw/8::$XmTJ1!M^hV\H?K<^?T/G+65jpejaL%q6dp5W%!AB5<!StE$H
8bV^&& +mGaZ?/MI>cKG*Lq*mAEu=e/P<H5SB$P%KYYj@AIZqqCmwiVKZpPnbuQP&Y>EL!q$FiLEihXhE$RM&$5
W/549B ^D!YFJWIEpD6C>#w$$AN4NLQy$d&:bpKWFRj4=IhW8edM=j1=bcY\#VcSe\Tt@5RnGwBj%mMbJ#mc:^k
6lA+^A TX68dMq:Dn\GHCQ=4qqhFmScV#lVhFmd>TABn/*PZM8N4ZpQ9JFQe#!e5=aAE$9Gy4!:+k/d!8JDFcJt
6D4RMG 1QSm^?!dqp!m!hp5yLWI*#Nb1Bp*m=nN/Ju/=+!bXt1EdRnM/L*l=%m4M\tNMRZAVbqeyAY&8an!WGq!
W?/\X< #:Akdyq/nAYppcpD%pSEJXq/6yqhutn&bXuBk&q#w5y:D8GFw+p*E=mM=/+wBCi*wiq<W!EBDRk=!an?
Ju+kcT ym#dCVT^1&TYktVkhZTphtS^t5!dT&TAApdSIREY!P8?CTApEp&Y5CHA9mnu4ZlaGEW9iBd+wYnl*II=
hTuKqp pJ$$HY/#1DHQGpdC5D^uTn=&kk^eutEt=5aJ>#TmlK*eXHGjXl:KQcEwlMh*bCw\pFiCPw=^X<Y*DBRT
<6jml6 5qMB\!#SnSMEnIWwAF&jYywH!mu=k1CBPbX9p/L9cZ5@&JpH&nkn<uZ%IidZ<h+Riu#Camti^wpHX\6W
CcMV54 ==ilXwt:4JK\6KRMXGZTNNy>@=D#uXI&yGmt::GT8FQlNAhb6yLGW!5*SDIKXF@#NX@JHlLG%K9R<*:T
w9AHQ+ qS@Gh*1+a%e<:%&khntqeiZ5q\$^YS:nCL&nmd9?KZKyIwNB#:eVq+cXWSqPebNHZ@XQFEBHJiqH:bkR
H?@j+G /itqaTW5dn^MmF!#ealW*G1#hV?R5#HJ$cA85FBCp^YXu=\61lwHh6le*twCl4mpIQNq!M$WeHBC#ZpV
^SdL\+ CFh>?=I?1X6ZWFjtBeah$n1JFe%b8G6ClG^ZWD5WKAc/m+Pw$%WThA<HE?A^e4TE5<ylEyA\>XlRY<W8
CBm%nF F?^wQNmwCD%DVyMPTuRQQ$wtMQMXX?\bH@QP<b@pVklRLJK\wWKdFwtb9lZM?clmhpbKdpT<dWthe\8J
Tj>jdT 61bkhpk#YWY@@XFIqayPNIX<lyXCqS5I8KDaFKFpp/K5WcRS61hW4/wNuBJqM+TcMbMjkFFA6\XVhRRV
-Aj$\+ 000a3f0cfb000110333 Page 300 of binaries1.zip
StD4N8 HTCntKXF>%FAD/JNGDPBD/hnw^Z%#^Ph6SThdQ5IYPHa+#iMZ&iVQGYQiNLy=%hSk&+eXAZ6lSut*@hh
+6Ft=k AFnF<cG#LC@hNFq:D\lt81=&1L&QTcH*aEFu>@QH=B\&uGaBFb8D!Kqb\uA:5tc!q1FuLd8Ybb9lqqKF
m*SuGG pG<H9:GK1??YjjB\tuBEYR8SS@=5GXlA/cXZm1G9GLhey1EQSZ@p4J4k<l/$$+?9+YmM6GV<cWk5uI/V
i>%NaV BVPCdbT#Wu!9*#\9M5HPVHG=c+19TL>j#N%#e<SyEAdh9N*$?P$KSJIqlcLHuTI*6cK$DC^H%pTWYaW1
Mq/>mC qZI9!>9SwCT>I*JD?#+ZVj/^jka4GT&b/u#VcE?duZRd6:qT5Y1VRe&6IXww8n!peVu4ZqW+?@8>&ch\
JEPq$S DMNVq#dFiWF9DhEe?B4JV:h4jb>bA4w=aN^hlH9Mk^akEej8I*%AGJBREQGakH/&@bdE^DFp\CbmR!>m
ZHe<N9 4y/Dy4?X=/!IG*nM@n^?#lGtQ+lPNkmL!WBaFye6=kt&c\d^$wwLM+jT:wM#VBT$:Cy?:\1Nln6$#&hG
LA6LEd JT+VcD!Ke89ec%Lq\CD+K&5Pb&wZCRP#AH/jPXViji*JYe#tS5e:/T>^wD\^1p$KW5e4^%=P:F1:yIcW
Q\8qa* Sm*Pw#Kd4H*D9Rt9lSt*t&5DGNe:t4dM5VD>!a?=HyJ9I%^BYA@X:E6dmBdki?=y$F$Q*+Kb\PebnDEy
^%MWYE F<DDPX^XQBFH=kP>6ckD%N:#WIMCD<LbjK%4^N6+wnS%SmwT^i66HAn<:ueVbaTqNjQFyBJpFW6W+Ab&
@I6$M> <@qX1Vu$eZuaIyq\TtacKh8eNHRDJC5C6NYlAFi&%YipAR5C8aIW>@ATQX9Kl!aM8RAalq&G:W?p/k<K
Wep5%u %B5ldQ+Mp!XACHqFm#ySWpM+$qWj+SCpc?hj^jB!Aj@ua*n@5:BhX6K@S?n<q<N&8j/5E#D\h<Ni8hl?
cKM%^T l?d<SSAqF@6jwpG@RZN\@mIKpw9nh?ljBi^!ej+P#ja4t85*cNC9InC=8H?D@qX4h$+8u6?l8Z=Be\N@
Bj:c$4 l&d@SSRp>?@wG659n@$:89d4pF68>6?//L</PPk9$d?qdF!@CD*q=9^L>P<w&^<>w9?e=9+6Sj@X5Z>L
!N+W5Y &aC@tF^+jpjb&Ll@wY\<4H?Jb98jKmLA@9N&5uN\@/&TAD5Z<HhmPuua@=<JpGZ:Kh+jAdJ@ZKZjESQ$
?I:MGR @$mALN9Qm@qHkC#dd%:Mj?/!D9#QA&V@WaZln\BbLqd&Q\tR=iH<d\VI59$nRJchHjk9AdJe@<%GdP#A
$VPkh6 u+@K@<#QACD>hS<&+@Kh6j?kD>6d\Fij!9?kD=6YaZQdj4=Ytcch^6@/5BXw$GAW#j@9Qt\W9NWctVe/
L1!YG8 %8AH:wu4qVly:ie1:#8NLy4\tCHkkyw$4JV8:@!>%RjMCy5SHYZjJI^cuC@4V=m^1+$j*PKt+Z?n!J!$
w9%BeH e8iNNC^X1ym\1Penla:d1^/&@<c:Z6Dy%VVw&MR*@uWXy/9K8bqjpjn^#eV?NeNV^bhFpj^D%$eB\*Y9
MNCV6* +1@:um&G!Gii^RP#d=??El@I5w6eQQ!aP9abiD>lYJ6=8thh?ASJPpJ\Y6=&*81aVXyCD\MtEE&^>1b+
CtZ6>A w5aH4FSlCk^YBKWMQ!9n<8n4E<%WuB<<A=B?i/eIFnWj1><cE@XhyA5t>YY8W5BT1>n$tAhSd@?y?Sj^
Eu1P6+ 5D=Gu<Ha$+>=R*T:+emDW&anFiJncnPb9qD&=R!J%jc1:JLw@H:+JFTR@c^n<a#n4HLnEI&EMt:&bKCi
y5#NAh !jhBbL$F:pJ<iLN%H#:%Pc<EWR*Zyn?D<$:#F/KPDH/wqIBZ=Rba!<XGyP<!D++#!e%mnuMAJ>DcR4tW
Jpc=pD MW<PkGN*nJPkcyd$EH?mR<^pkQw5a#6qwb5DBIHMLeZWwin%8JjphG\mmdSeZZ1S#/!uA1i!8yKHpLJW
aj5BLK am9^6t1DS4teVlLdP$:y/46Ki$%*Rl:4iR!%iX4qt5S*^88J%%+tM%\Mmdc#bPPuQCtDR&+j%DVHHntY
y<#wLl d<E>mFdpM+4N>Y=4aPTN=u6hPJZa&</+64khpjVZ*qL6+bQ&JkN+Cy98?RMG=qj>nQc\pS15LV=H%4@b
?\GWD^ \qZ+dNpQ?4:Q$>9e+iwHBppNR&G!HMVqbjSt@B/A=BIC=t^^R1YFpPZKGi=6qDDB^LKDP?dt9?Ia:FS=
VVhI4= ew#hZd*GA^L#ZML^%DJXXeiwjc?Gu*H^acM=Q^4FH8cnS=/N#4&j#>cQ!E=6ibXIuwLBJYTP5DZiEV>Z
CNd<$/ F/l#+TLLc@/eW>WE<\w/&iuuLhP#8WKwFJP$PnG4C?AqG85A*?%G%1w*EXP#hd%jtVI?FJFJ=L^cBRWm
+&\<y> a!yuae5q9M%G9<e#9Qh\<ePV#&nZ5\AYw%9nS=&GN^uau%cmLB#mT$?\Qc?IQd!d!>ihXua+NN\#1mje
$?klWa p6eZc=M%/6<e?:6<aatMhPZ@MuBD4GhGw<Sn$&BiFDR>\m#PYD@FB^%+SE#^<F/t@y5R#JRP1b8mq>%Y
uM$&<i hQ9YNRAt?hZ:w9>HK/bu$MDqX/!!D%amm^$:Yn!Cd?Hu!*6W*\Hk:TGNy@A\e@1Xe=jhS6^Ql+K/cR:V
&REmnZ 5mHJ@d5Aw4BTC6BbkVKBn5hpGQXNu<K4ZwQ5l!@yp$&Xy9^^ybTKL>8cwF>HEMFhFVZB5<!X\\#VdQ&e
\<Nu6R VIccp6ABEQd9wqXPPb56?P9IE?SW1m#=yF#laE*VqX!AZ=lA>S^w8phhRuDAuAF8i<Y6dkH/juRm18>9
R<Ie*& q>hYw6=jRa8KFIVM1+@KaX>ZcMyY4eBS*AB$+S9E^b5^%:DX*$c:R1PLY/EL:WN&!>d\1k<PS>^MGJjn
AuHq>= qKG#!neu9bKZJhQ=ph6KikwR1LQ8AXB@$A8<QRKb%6cw&Z5Qw\JZGjL>&bPW=l>L?9la!QM/XG5!YtSn
%VJP<9 d^kp&m/VGQpD!%I$BGuEl*k^/K#nF/Py6&8jScRy=bTZ!>pwu:JCl\yWI1FZ/e^1i>N66V<k$@N#F!Ei
mEM9qG j%Ch$BW9>yLPi4?aHlHFL$HtlYGNQlF%/y?p/PLEeBR1tBWB@!bG%$R$DBiAuameHSkHBbS/!tBZq*lV
XhNS+: XELDyiPAHZeVuDKlC1XR*E@4iB5ZF@ZiTG&y%e<&jpF1ipSItk!MD++D9/yYh=DbnwMpn/Q8T<6i!>W^
qn#QKQ qnl&In/WTmld/<t<SHte1X%9$%4&nt>=Ga18p<1:D:MqE4HF/N\jWFL*FA:pa!*4:ww+<NcbGDRCImwG
m:P#t+ Ttb%NBZ/D?9R!TZ\mGSelI4#>m5<I:=AyH!Jt#j\1@RMG?\CwVtYG4SX%d#9HT>J#$%XGLaluXhuaTP^
FT%y!m 6&&9dakq41CjJdA66$n%=JR>%=Fnp5y*BlApIy?8<#Y?aa#<YuNu&aLSlib\%9?8Wk6/Q&9^bSq/:$iu
aDKy@% %uRXBY>!\#t@Y>yaFejcCFDqNN?1Scpmhq%D:?&bBw@iG<FT1VCIn<=^bD%J1YMt1SmMF%kQuX!#EAq!
6%q&N# i^>PDP+/4@RADY*Rh=iMRFEG/59=Il14SE@8nGS?S/YcFH<u@c4K^8S<e+V8V++#1^&w186/4i>mkSI:
\&CQeF QZl<NG5!Ni<Vn#YLL\N\N9uNI16@\DjY5MDRQ=t4:yPuDDSHR=4JPu*K/1h5E=&qY!M5ca/JWm%KnlZe
G@9\Sj 4lu/=D1>MJ4!B6jaQp=N?\F>ty8awS^1I>TF$*RGCq@ceE$w9Zdij?J+GuYn:Ck?ncq@FLi8BwWjt9?P
h$ukP& M&m\Z$kmTi=V>laHbipXb@?Sjdn#uYQ<VG1HM?X1cand\weSKBynt!i%VA>$&LtRS@XNphhc/+dkliXe
1*V!DP jd9^V:ttwtDnIR!&<@!wDjj%$b#%#u=HJ+QX>%?5?@R!qji<E$&V5Mh6iL#a5>GHlHM6#XbSqh@$JG6X
c?PPZu !pw&L@Lbb%$!>Tc#S:q86II@Ldb6=ZDP9!##+\k:RVZYMh1HDi:8=>9B>VbVR:>8EukLXL?kBHAYlP$?
ELwGCE K4peMI5Pe%?NVk+>l8$KyJV\DBS%XQBt^WmjyLBCS6Kt8mSLhtnlNM64Hn:qTq$nT$\6wqMbMJ8>8d*d
ZNpnXp GPPa\a4?MX41<iY>@<Mu@t#?#^@85bZm61WMh1$CWt/&K/hSb\H6PLqyH46Be\bCp94NGP%*44F4<G=V
54tR$p pj6h$:4dqCyQaA1Z5DS>lD*WeZ!DV5hPWn*+E**1H&SM41up^lI/iXZd5EK+ZuDGj$VL19P@^q!@=M=t
N6$kj@ X%m&CBm=lD@LLZ$u$V644\!:j#qbLFJ!&&>@@jLNB&L=t$@AwTBJ#:h&8=&H!9DhDmijH$IWl><*TqVc
L4PkQY +TKClJ#P9Vjc9:*CdLBqj44?cDV?@bZ4/Ft=<Qbn=@y*H/iLF!P*:/>CB<<?nSiQAyM9Ql6Q!dA%4=hR
E&W=uF AJNZABAPeH+AtEID5/MBm!EC1!IB8<RCB!Jjt$tAZ:JCADpkuLqFA8Rk1pRkkSKR#6JZ8dJkXTyRRA$w
<PV<q\ b^&wKkPwT^NwwAY$5\%$qRQ$yR5M$AQG?S%MqVhM\DVMbSC5e!l5XTV5bT\eMBHY&S<5l\DPPS5itA@9
u:hpyd ZA#dM\<FVkcFttynaRyALWY+:EaE>5MHRAP4Smln&5C1Jmmhb^F5?p!Wb/Fp@KASt1FRD/Ct#t8A8<Yw
X8YnDa c5mZe<uARXSYKERLX@cJjSD1cVB=MaIeCkK$1bG^1+qIqp/MF51WD5w$GM4qJeuqGWa5H<cXCA14AQw$
AinMTH DGc%Al!E+ndnJcY@G=4#QJ4!KqyXB64t98yyM#K4CQ1XAE1%FI+LA$:%P^^YCS\XJh#1TFkZ%c8wGBSd
MjmXn# XGa$QTVY8B+#DLRkJLS?EBlcNRF4NT=RD#Q&E$G%H!d4G+LLX<#acMK4cilaiBB4M86XJly6&bR+FhdW
VYMa:: tyEFEA\8Ak#6HayKEAd\lFCqGRP6q*B/q4RGmcDctI%%le%qA?8Wi5nqCF9$DD5jCAF&uX9KT1Lml1HK
h?uyM# R+n/nSShlCK&p#RPldJ/p5kXC!?upC^*9::cDL@c5paacA:uDluHRXE6SBuuRqn>nBL:nXVXl*ItmHSG
N1R$&& tdWGY^yht=N=Hh?aAMEWGR!hPR@PmQ11HTP8qMKFk$dbnEH%E$N%PG&Nbw*KKqc9wb@5I#tdChS$FR^y
wZHL<8 QwFKM$uNB94$MQS%M<QMGcy1N%a5GqujN*#Xd*BXllDwHEDqd!S^QnnV4#A%J<\*iInw%=T8KWR8SdLK
:=*qEt ylAaVG\#V1!%HP#PCa>KI/<w:a#S5$\ahNB5/?#^Kl#AWIA#DSk4:?8%EclYk>QNl4NKB+nl\MZ8\Y+&
*W<w*Y DXu4#ZZn^$%lA*EV^F$d!Z$VR=8#A^/j\qPd\ZPV#e8i@$eBmNItS1WdQ9b/Q4jt@>&H#YpIAQ:u^p5i
X!a$@< 4n<yJMeN+9^@S!G=&Q?ZFyJLCip8ed\G\V:$qXAknWDQBHYuciLu\4@Q?X<X*ILbuI5B\4L8<DXBeLI#
Hq=I&W MY#knB9R$q5^!4#Me9:uiGLV%!?aKG#<@F^B:I?I>W41nA@eVF9mnHnq8St+VWkaJYeTK4*y%=mmXhbt
IL8H#y jK\m%m/K!AuqkkQMtLiu1Im85nIaR:iB6k%I:qneNKEt55e+M9JhtDllwa<DGeImIa/+$PeAe^#wML+B
%cmIK@ eu4b5^^/+Y:lyuJwM8pmDudGXh:uP1Sc#hnC+5j*^>C$q:bdHENm^lPRTGt&$>CVH5qjPbki=n$Mwmkm
M:lRyH kWJkkD!KBnJARq1pLESCNjIl9n>%IQlTT%bEbInnWeNYqjWQS6Z96uk:PMVe1Ekl\kZu4heY<Ta=M$pR
w@4ZJ/ >GZ!FP:jRTdJ6u8k+4=PaEtFc$*:mnK*MpMIk:Rh!p!QB*\VHImBqAb&c^=Byhi?@pP1#LI^Xqy8/cQ9
-Acaaw 0007cbb776f00110333 Page 301 of binaries1.zip
G8p!KD T@D^b4G%QC1?GH6uPMS&>dm@>Bk1CwlWD!w1G$1MLRmVKqJS9Mw^8quELC<ccuLWhL&>Rp:>5FN5VQYp
quVFZw mhp??K=FTwNdtG*IVw$W&I<RGNhp!EkpSVd@NEw<+KL9aX!9:q#*k/<e1D$/PWXI1<!K*Id>dhY66mC1
!Ep1&9 +=Ijj^6+@5A658qJ5AEtN:@DZE4X^d8hZ5&p1AdHdl>Q#qWu#QPRCeE+LjF6meh4%$Gd!T*jcMn>eW1=
QwZGP6 q:q/F5D%k6HWl#uuVnQCd>$64J&6wW8q#FJQ$ZHuZkmSY1CKMkNS54%pt4FC>jE+pnka>S^ZdVqG1mSS
:F=?u$ 8&n#EBcmDX=<=J$$u>Y^ZmdD6kFL5VT$i=R=MdiV6CWQBy?==d=/RIY/e#GK<Q:*?SBlhTmJD?WaXp&y
<I>/F@ 519&%6I/SQ=B8M/tLnb8W%lZEFVtL=m8bG>pX8m:/lpDnSk?KW+?%jNdRi4G%!TKVXBNpe<<Vji!TVGZ
Rk\qu1 D/5%1&QH4N94Aq%eiYtM%>4pVyImpJ:qJN<\ESD1:atHSdTYeIAdlRe1McM=#PFAmb=$A#!Rb9CbwReh
ta:K*& 1CnWE#<M9+lLlhSmmMq@Ee<8EC=yTna\%/8KSMZFVlw&lIe\6phlEVATy=:SVPP%btA$yMK&u5SKcBFK
S%#69< PG?H#e>b&SiJp@#kSmSNE\D6Q+>ACkX@&WuZFjmJhG+SC1%juC5bQ5w9AVNh&Je:8=<$i:W*%Mt6P:h*
=>!1V? EQ6w!<W&5CnyHYph?XE9+YH5AJK$?Q$*nuD%yZS+X&5?8n+nT:FQKhd9Q:T6EP69MWb4uI&aK<qIdmYW
k&+uZ@ CDGn54GNBpD9YP8YMX5#^:T<i+lE*cVXLH48WbAbS$TnV$%Z:#AW^\%iXmc*VJd\^ci&/nyi=*hJW%\B
!m@uGa K?KAn^#DD+$HC=Ly^!$wuSc6%HS?Z>kS$9ayWVXhuYWZe/CiAB+STpeX+\X>EBM:>!mk$qutVtEBW@yp
98G1!A iqc18F/H#^<GM9QINpdN&B>9\ZTV5DjbJGm1ZGElmAe?I5nEP=EHBheG6+Cw>1EEQwJZ!B&daGM4MM*a
aIA%5a 4&A8Re65<<\HCH?jKT=5A4V+#t=@S:R>adt94<<ZGIHFG>CK<^R:BlphHKZ\dccRk&/1m?=6>@\8@^:<
A9J1bC hI?jj&m&!DyyI*%Gnwu>b=e9p&$$LI=H@yZM^^%diIA6D@Whq<d8lbPyZll8ja%tywcHjtm>*dMANFiq
/MKWZp 4bT>4/6*6l9<b++^tG!j6N=9?Iu@CE/+leI4kLiT@=HNicAhRd!n:BT!emSH?ZSYMaZbPl=dy$<hky<@
nP^@4% wN?<8IAQ@hb=wZI9S\PZAMy+F!+\M\t*%\<C%XSiJb\Nw#VWqm1RDNGH^FVV$TiFk6wCpuK<F6y\NCYG
#N>X!R &VK<LC:@%FA=H5>a9l\KqH\WqnHQ=1utcFu*>h6e!ib&abW#&+VP@w&%^14my\9l!:^4><Iq=Ljc!%k^
m&l8bD XEtkmintaTH=?/W=8w?I=B^T<KHE5Wu^AD#%K?e5LnBlR@iwiRl+9PpaW6BT9Xy8I9Xub4J6qPL\=HDy
#e8FWT BVlIMBE=ZC1!Wm#?\aIHV6%S@*XW4AiFmdF/Bm4=4CV$/Zpt<#RGIHl^pm&!96XSiVaS/C5!w1?awm$c
P4l/%F mwd8N/Nc?KLem%k<&5WjtE!c1&6<=5D8l&@%yP#1+6u4<q4\9j4#yE/8^=!6NHWCl5hqJLQ$86XHR*!t
1SThtl J?BJ<Zh9*J*=AQqq?FRXq@jIC$W=J$V6ldY!*D\m+J8XHN$mLQ&?ubqcNd/*59a/Z9^DpLI=?i9iab4#
jnLpmj D^XucVBN/q<*+n#eWX%+q^6y&L^Lt\6bcYhwC4/XJG@Ak*mFu4A^9:<BnF*<RC1<*GlQ&HchF+Bc9PYl
4/TuAM tdYwN>qwN<b$n*\yd?:WH%@R+V6H*VB9<wld?$CS1h9Lp?BZ^C$#1V+I<dpcDb6hSKkXYG5:jA8QmP=#
KQ*Y^9 MhLSPRQ<Yy4^KKjt>:Y5#pMA+k:XCju+&6^+:HklnJVL\A1MQ6c#:>=4Rdhw8IyC6CAKd+=@mC4/Nqbw
qldiG1 Tni>P?%bK/bT+>w4L/PNlF%haV?KDp4@W@nJ\FW\!1DMY=^Ynq:6SY8a5S<huNInM6\:i#dt:Z*DG&CT
X>DGRQ +W\T%dK=VF48&h4KJ*/MdKN%I8h45y:maStaIPhNjQiA&HieJI&w=Q=N\FpDYS<bt!^\j%%@XKiklyHh
/adbWw Q15BdN46RH9H!%5/*>H>e%XIba?<8LJ\<b^C+6K5QpjJ1DwKkEjjcilSDDJkFGI+L5kK&YY#CRy=nV/w
8j&XID m:QLG44H@9YmABwJ$c85:lFF>k/G*9wAHRm\dy\$VJGw&cEGb>>^N>8$=$H=Ah$H/&WPaP^1k1J4k4dV
>deb6P ZIRnNh^**dE1&Jt+kl9?tB\D5BcXZh:q*^&SDcAm4Lb%nn\a5n+Wq<4bj^=X@FlEuVe+W$1?JFppY&DL
S6p^cY KGIN#Rc4@Hb1P>&/!pe!CqtlKmD4c/EWdCA4=5@Jy/B<D\uTE6HeCkYkLKFk!!!9tYAblWmqndTHl#Jp
EKlW^I 1Pd:Na1/cJ\B5t:*GTbeMVB5Y+yJBPW\^=uT$l<G>1Xm<%#Mq>j^?Q#ah^wykSFk8W5htFCltHTpYlYq
MGI&*W GA8u&&GltHTKtTC^HY>>*#DItAA@ml<>MT/hX\D4ta6M#A^jp!CPL#bMl:e9uSldEie4@HFVN!dWeuZV
b?^QYZ XN*m4e6tVXcaw?LA5YT=c6LlT>KiAV:pcZSJQ&uZCVF$FFIwGm^%NMpkQ^KhcaG^8V5pw^Me6GjF&8eS
>hi%R: Z<:DKK?^V5#DcnVk\/1Fdj/wEuaabiW$+11%yc5$QQIRF>KJ+mewHm^pbXjlqj%1E&TamW<!ec5qZ/Fw
M>&$Hy DtnRbdC5aJF6#/WwLTXhVKnmwwK#N4DEFbCRki?SRV4PnZDt\>BqLa<whcyST?/R59CD?mLteW*ulN5n
BM6Vpm dayuFVZ\&<1PW&MVhdPPlIkPI/YqBJSS:>$BK&i56%8n<EtScpA4i+%yVYbI>VwJLqcpSp4byC$J+Dy<
l^hi$I V@uM!pdJ5iwE>1wm+tQ5HiPB5XLFP@aaLb#C59PbJtHVL/>nhX/&WcGu$KKK=GGAbZIXdTR4DJSl<E##
kj6bw8 F%FpdjhnMjJCFS#KX+J1#abhciu^p5clp6XT^<!D8GAMP!/*HLW+b1bQ>Bq!nmi^HMVFmpF86wmlVjQM
IL=Nl^ Va>!+9q=T4#^Vi:TNh=55%#XDTJHmKy\JF#?!$SS4$SZud\u?^e*4qCRwKm\BcDqh/YdjTmMccFVQIyQ
dG1FTj >dmt/X/:T<k84Ek!=/*RBi>wEV<!CW8/kK?/?qcn/!K/5LLRnGKjjAlEa/YQ!=G1?pEHBabbTc6lnq=*
QJFunY 8RWdjV+X\E$Va$#ynQ=kj$X^Y6hk94RmNcPce%\TiNut+9yl$:/$cMkh@Dc5K:Z8:J9$wZ/1%I^IHk%Y
Wbm/tQ pP5&Gw@ELuaR/wLTdcp\LG>*GQ1IelGy+8H:G#Y\Pq@lkPPmZjVYV@F!WJLhpLRZQjj9\mES8$dc:CC:
Ka@Gi1 $b+/$AB9yaiC*HNld8%HIhIywIYVa<\XjIW:\:&XFSw<bHcVXIM>D4!a&N5/%AaPqM6iYWAW#uX<%JNT
85wb5W W:bC%SGM9i/:Wc&5Sd^1^kN4#N1dN$>uiT<4Ty::$*i5=t?@l5J9VW!wh9Y!VnRyKuqY>AM4RabBD6eu
RMmuwa 5iKHac*cE*Pd5R*^6FZXw#Ca<K*5DqNIYc9cGNiqJTWXCGkGWQlX#Mym<@Maae/LEAYG%i<WcqZAqJNH
pyYabY y*w?5B&1nlJ?liK5RF?1yY>qG:R91Skcu!XmQlPGSFi5t5<=pJypy%Jm><k/:49RHtub9/ANlp=>hIFn
ppjQSu w=qa8&w+@ST6Gea+I\H<m9/DKYhN1d+p#1NKhTJT*uVy#KYh<hMp&\RS/!n$%wLylM*:\y%HndJ/ni*6
!h=P8l CNmKIGjQtWIQupuTdiTt=nBF<e$%$bAW:p>I6yhi?Nk6H+^uw5K/VXFGjA+WA/Ee8IGp#?d<TAmhDqP!
teEE>& qR1MH/!Rkcl1=EjQlGKa:6kQH1nZtk6jWDlQIMjy+PuaHi?4CeXyT^5c4eQ%eGpnmp#4:NYMlM#F<K/?
=6%EdF ^Ktn^la4Mqh@mWZYV4ISVdyc<%XFe=BFF#>!:aS=hJh^\46^IhkFmSjVpa=G#NPJpR:eKm/KEX^ZcI$S
>y9npi GmKT<k!X/Vn+W=4!W=LjR@i8WBndWw!>>Pacp8Gp9h8HIPdKa>TKt8\Sl?+6kQd9R#V9kN1MR!1:lQZ>
TN@dJI Pt#/m\W%>@@#$WB5yH>*S@/Zw+F+iQ=:Sj!+@1Xp@j<8+5jFC9w9FjHna9%jy@j#F:b@Y:L9H\:Zj?jK
D*jTW? @cMh\V@X=PLl?e*aJT+k/?@RdK!@wNu?E5*?G#RH^/<pB@$P#e:^C=4nN&kR#/<p=@\ht86ZNNj9$B!@
eEh%h= w4q@k@=qBBAZpPe*<F@%8PBm@T%q?$XZp9?q&@>nBiBA*B^@K\AH+9thGtH@c*#>V^cA+@^=y@+wAMjJ
^GY%pc !9Nd<4D@?=yqQD#@iWkG#:@1p5H%n!Ju@*c@wH<&d4J^5dH@@=M^@&<qa%d>pa\b<F>P^kVca6but@99
9FqK?X jTL4!!65NwNhy?DMeW@AlI<tGHtF4wJjm/BlyL?MAaKF<iNA&$ndSwleSwAG<8RDwAi/L^@bcY4H4jZZ
5$Vk&= YMhtbSec%h^/JwJBE4lLnYW*y4#<cD9?9ElI&9cuWHX1KYK#CewDS&w%GGYVMFkIy1n\e^c1M&y%H4^L
Y^QTHZ \^\T/5j%nuwbBLZh!e4eKq9CS>w1NZ^!SuL8J<X!IIn<6*lc*XC?&HtJjX=tYk$a*iI#TE\$q641a%+K
WkCh## 6apKZY#5=iG6?KyJ+\5LkSAeiAy#h*ibSu#8<b?B6iQe+i=B+Hbc/9$JJ!I?RiWlleyGpS#8%@!V1ku+
cZJH%! u#CaiHGkSWLe&ML<Ki@VJqWk>HqX+*wN9!I=ylYFTySD=M$8IaX5MPXXGE^L5Cih5>8BICa$nBwZCA1t
mw@tWV JK@:+*D:%aqJZ/F9&E^Lk<t!HAB5Jm*#WeWI=5AC6mEJh*wpNiwMPDP\KliA+qb\YaQbKkX6=C=:p+Xk
G>P?tT Lbl\*FG@Xw\Xqn:iyit^=HtB+X:W8*Gewqc<&YJbHjjiRmNR89CBdPTQ!KCl\=S<d+cLKE<=MnYiTmT*
bR=%Zy FwhwSNbB^aKua>jiR1T$iee*^w6RuHcGiQwVd+Ca4y:/@THLI1+!^dV\Hi!Sb@F4QPXtn+FQtAcIN$W#
4lSiY> HG$bjEc/DmFL=$8=w?=LDSX</y8Qu#>=LSkVQ&acS\w^>F:X+i!DMI*8:1H$nJ5EedVHMM$Wu+l!u%!m
%5Ic1! tCRbD6de\eVwhE>pjIt5=L8R!VM$YIy#!\54*w#d?jGGW?LSNRHc\8CZLLNd\NKdbJ8!V5G$1^JRwV>Q
mXX!=P >M:m\5Q:FphZD*+yJ818+TnWlW8b=*!npF99T=*PmneZTIA$S?\TWt\IC9mMRp+\>j>l:/@D+84!dXG+
Mmp^TC 5MLhLdm:F^de*b*k:t=JeHjZBHh*Di:8VuANDkpBE4/<9d6:h?<*:E&j98h<>#uQ4V>+1ww%%yy44nFu
/iDb8A #jt#<dbI#/%9e^bhThHPF$+$Tk!#5HBdp^1yNE8M\FpFVWnRWc\tqL*@R9GV$SeLGdNG&9ya=ceiNn<^
?<j=5I ydmqVJ#N\8&i=yD1aK#kR<HajAVFtE6^=u=ZZC\=Fbqk^iptD8#WaMZcX*a=\cSDEQqNm%5%d#d:TRR<
G:pTE# YmM\bjMpbSp\yVF1l>W8ZBAwd:@ZJ5kV#LSieE>kwld9ByEdlkNy!j6\5hG!@jSq:IA\aM%yuJZZQV9P
jLtL:R RHM>>i4WQu\IF+8a/Bqq<NB\iGY$ct*wRQclycudZJhy6kNhFEte@e4wG:6RRDddkD@RhR/5CB4yS*t&
-A<tJ1 000e53ba82e00110333 Page 302 of binaries1.zip
!%b:CR <eyd&V5&BnuH^wcBJpyjSYyFY>?/IPF>W^uHD<B!8jBE&HBEc6Rp&?^5Sy\yI#kLA#l?!L/GMda%j#>\
aXMmw8 b@L?6R<j#YKN+HD6KKFL5SKp=jXDN=q#Zc49E&==hCiu^ckQyVmkmGPp\JY5EeW+IuEAb+InBuKRaDcM
t44V%k mX%D5nLjyetq^mK^ZWnX\!W=GF$htqPaq+VB$+#wR@L4&XiI^SKM4PTAaJEBbm#1w#5+bAQAh!tm6MFL
jM4qBK e!q5JCC1ILGjWYA#K1pIw9YW&l9kaT#/XdaFDR%lhBT#deTiS$HyqeVGpBMGy5qlMEh$l$N=!b41:LF!
A+@^RI &8YKw=aV&8&TM8DkA4#1nYlwPt=Wun:y:udlcXhb::<i4#EW:VhDwJlC\wuP4qJ9yJ#tpaWP9qZ6W%Z%
w$NIAT !DpidTl5ZK%eFLR9%\19ydmIa*GQH1St<LYDMY#lEli6u%MyeTVP*maVC\M1b\T+F>H#k1#**1&9?uHK
*>+@qc #k<ZBHXNK/Nh/R:XGPXB<aSQS<G^F>GV5Z%#<<kWCTcX^^%@*ilY5u\m+F4bMbNbjZc&=5\BmiTDwdY4
C6^bAD iubB*/qlKdi\TeAD\:\V\#GN1dwXIBSG&dAXd$<>8NGLp*pwqBaSBuNYt64kbJiiLCpW8$=P=tY=R=1B
BXL+&p VChHI1bTp1V9T+!kAR%l&8>kb=iJGqHLdTyP=XW9S!5MmphWaiL!nK+#j5@PqtQcN%5Ck\kkl5QlVk?C
p@5y!: #P?P%4Ta:Myh1JThkZM8NQ<Ac#lAh/nwYQe8wb8/Re8pq/jW/ecIb#uZRRSIJutWe<Jj%F=ilMGyRHPE
LKP@tW d*?\>EPFXqJ&8AJEJ>dNQ4Q!6u#+l^D%@E&l1qYee1ulS$lMjuF@8AI%&kbNK4u$^HnyHa&SJeb!HhY!
6u?MVa \9RJ<DJJPHwV<y6Fun%h/\4*Ak1lTI&SMIH\^LT$an8p*hRN/*tbh\MTZ1S>P>\jem^u%ckw:e1VqKih
*qk5d@ By=+IuK!/w8Na1RAHEBd4qBF4MyXt@\WXnP%k%!/wEA@!$8NdwV=>Nu?IjpuctZtRmnSVWH$ehwMYAh5
XZ<$Pp 1jL=D=<^yDP$mCjycF$W+SkS=D?l?nu\><yQn%6QB<!ec8I=^#iQJ#^CEkIyTV*/<lClZ/6b:&Qe&Cqd
u/9cbW j8e8&lwVLR5\w?=9QCyMT<pj&KmnMGB!VLM:MjZpit$>ldqXlJV6!$++#=Xie><!mE4KKIQ^!T:yiqyq
Lm%1$b 6HG@+Ld4*B\8G?HTi5BwV6^?ET##dMwSW$dWiaEH+PAaB6@HD?WQ\/h<9Ktw@XqpW#G^^jtD#EWPyteS
CY6cb% n@9HqR#&+IDl#HjqX5KcytNyQXIaw&MDXTJEhWDYeT=%8CmGu?=#Xh4LH/BadiV4%^EEXMa<mpn!EX&Z
Td/Fy4 tw5w*\VVbd:CI*JHIPpCAh@p&d\?1A:+dE?>/lb>>w:GJd@QwkCCXbI^ky:XJ9^$l*1nK^KSiCIE8Vy/
a8h=nZ D=T!cVG:1RmX^<MPMQpa6XHXp$<qV\:5TW/nuDphYF5Yd#WS%C!E\yGWuE99q>\&Fbc!b>R4hFNH!PR=
k%ELe! ?:CJ=P<AIi$kd^EbJe5m#pyGdGe4EY/MHJ9GqAaJ9:I^8up4/aSp5P<$KF#jy<$V$?lm+@HJBpN#<4Y=
9ychq$ 8jlZ$Sw+8u%h\I4du9+QSuuNTuAuMh1WAKQiA8y+eea9I:S5++jAkFiuabLjdR>*kw<bEX>DR^RdwymF
>P?/IA DiyCWS#PSy@bn%/AKCRn<q*$wZ^D#yqky$t9l4JRh*SVa9dNAqY>KMd/tc^S^wD&9kP>!J@MCpnbkT1I
dHW5GJ kA@:h9*kp=GyiRT94iubTAYRh+wN184F<w!RHPHCJER\1BQbknl@RP<4B&$/WeV8B$6dBGb#P&Jw>t4#
15*<ek mCt4H4*HmjmkHcCHK+GpVd!Kn=Jyt1i:GWTkaw8p#TLIm?Smn*VYXRXBcJGFQmTH\#LH:hmJwhVnE#j<
9ekn&$ 1uKAd&iGtQl*qwj@&IL@u:a<9Nm$\MZC?V?cF4na8Z=nYtDu@LNykb*nBccF@:Ah@HXu<Ke>^=>*wq^@
Db1*:\ /+d@*M/B8J@b#wFiku=8F<#C@RI$^#Nq::qatj<6NM6L$C!5#/BbZ+Btj<:m\54&EnVuM^6\X9cZwNtj
H!yA?V /ZNYnyiku:QZ5HK?BM*<*H&@lG6@JF#<H9$T44G^Q*j6q*CNniYbQth:Chhau*9idC@lGm9ue?mZeI&X
<kC9bw qi5bNN8@lZ+J%=/*NLG>lG\e#=GNnjQjR4>wau5tLbKLDjTmIjye6*H@P&l&=u<L@SK!QY9ha*<J&Vm+
h1GiNT upP@lG^@@DV>H5*?Z<^jj<Q?h?c99!el@eZ<^jYdp9%e@/lw<@hcbK!@V9h@RY^jnVH1@/$m5eHF>*&q
8P?@cc RFb4y&nPeW%4!tBpj+jmL61Sn\BBSXJPY5FS=km!YlRdjnSG?Ga4DGR/D$WRFQQFEXu96Ck@eISEeJIu
Q$=+^: CA^<n#AIniA#QCP1MD5Gwl@kpG9w&8i6YPSJG\EG+p:^blMnGGCDVREDHy1#Wmb\GZ*w^HhLnBGVHqhR
S*bt>C jm8T4+q%4A5nHXnTNnRqNhuD4j<jk4YVt41+a$:d^hq%^/N&6LJ\++E%=VtChbLelmIIDeyKFE#\Itkk
KH4ZDm e!YtYY?E%w1FMc?Y<i$k+Y+GIdF%LWX&D^Yd\aZ^DwIKqpS%DPH8YAeMyLk9Q\e4F$>buCje:\V:NVtE
hHidAG =:W&46<cB<:eKC?^RIEIt%=QjJ*kpFXI\SEm**aXZtnedmdi^>djTkIup<Qwm&=V%Lm:>P:6lXuqEZKT
hPJPJK %<ANTw5cnyM<MSZ!C$TQSyXp^VER=I*pbwVNtF:wy/BRH+Gd&&NPGmwtyV8iEdG\1Yaw@hV6RnCDMj=F
XMVqpJ ?WSI1M=HM6/RV6&EL^1>Ych^+<Ra$$=X=kheh!%K6ZcnGH^kk9\C5^=J=$Yb1TumSc@9/HC*eem4=y/Y
H5L4Zn @cwS8+lMQ4dLBy<N%5m!V=eaDJ19VkSkWC5@puW:+e$N!chEq#ZL+\c46K*=HCC*Y:Vwb^RL8T&bJnm\
qDNwj& FQSuPAXWCZSQX1>dBeL=1e@kq%X6h^?5^A4ph=^#+i*=>T\%uK996QI5?=+=MyL+Vc6+:QMwL/he\iF5
D<L?u! BcuTB!XS*qcZdclR5<CJJWPRdwHlbV\l?iZpX&qTn@VC8IC1%d+Yc!#A+RbM9lQMy8Ylb8^MN/KAPd<N
:XCuk1 K5W+:F1W>pP5j98c#FWal6DQNdkW!nMNAnIp==Ac$bI\Vilti!QdK55/^9EeWJCb8lBtwG$bb%ZXcLP/
NWe4K$ &w8NRB>Xl4XDjKmJ=kjuwLeh+5/5R/Kn4TPa*>1&RN11Gt69kcmZ#%1>Mb@watKAECVFbF4dQid@upEt
XCLQJZ KwhyF=8A8G=Ywq!InLZ/kGCZDkBFWXMphne*5!9nwYiH^%/:kI8j#<9k#/^YJ6uQky84CihhpanDTR/w
t+R6XD C/6Z>SpTSIGC&pVRmqXENE#pT=p@HH8%$kRZ?HmbpM8HKFRD#6VXnIjlQLBM/4!X#n4$l?K5KZm&FS8q
lLRt18 #eVHP5Ep?hIineKda#1!FaewS^lPwBMB96RuC:>mEFCFiR=@t:Q9kF8Nw\lqS\/6GMPj8\aTnDwnPNjZ
6XF5\= KRLD#Gu4:+1#tiJ4iAFPH4Xk+L4A:HHD8Fa/5cEqG^I\&dP5K#QWn=D>yCM*ycmBlacIM>yy5J^tnc/J
pl5<8= XetYB5\Jpu>SuEWH5ay$HT6JJ#qWlp%VpB9MiH?e56QA^>?tW^Pt@4k:pCapKMX5HcYIqa<%K+64+&TH
*Lwk^* G>NZlQAFLN%itHZLu@QAJASFJ<A!altjGt?6dF9RYEJ5G1TPljhFD#<+<w6WIAu/Al\tSL^w\=jY61J>
J>eyMk *dGAh?XuJMek1+Y^>BEK+jLe?8JSGwQ%PeQK4$F?NTQ6^9VkQA^BZ:6y41E%%ySVct?Z815=*iBX9K5N
!54je$ 5cwdwcYu6TQ^YYMXcFZ#91h1H:VM5uV6%enBjGSQkQZ&KWnDdT5a^Nw5n*9DCL9GY1bBBF>Hbl#y^ep5
5KmhR: LpG+pWHqZ^:%w%=n&8*pyEtH@1$WeAHu=^/tq@/?EG+q*Ey9AEJD%RAeKlM:9\<=BA+4uNuXIP?Y^*up
<KcGM^ G*<utlBTLhV*PSqIXp8G4tP+/6<DaJ\:Fk^JyZZcjEl*blGe^IKqdXVRtGW>i=J<8P6&9aQ%^l><pj6^
>*kPFZ X+4^Fp+1TW!#/*CqCkqhFZeAJ8/YD*14!^+RTh99/Fp@C?qMdVCy$A%jBI?^TRHHp+ie9KWa%WSuH>Sw
ZyXYii +=XcVRhYF\diR8thBE5^NP!Y$Lu+#+Qjmbd&?*WL#<WRP4GGaHWpR?Cw^DyPEWiMIZbmA*y\A>kcS94#
9+K^GA t*pLD4N\n^Eb\jbT1Sb6RnI@JNYtVjSIE!Ie#l&>jRi:VHdwNWVAVqk$K\*Jh+^bH=$1:D<#hw9BVpDH
enXP+E LD5Q#qdwM#W6cKkekdHLhb%8wyDZDF/pXb8%mlYD%ZL5TnW\#t6A?\/V+1$kNTap5T4P+%R<WNHCFCpZ
MYh@@p R#w/T>FAYtkaQ$@X!eQ8!q9TpyCClNI8lj\11FMT>\b1d6mk*DYlKd!AY#D1R&uK+$I8nw%6i\Y5cHI!
4c9uZp 5Kt!%etEBki4t1Qc@$V:XeeAPNqu19S^?/C9btWFWEX8e8>!WJ$a&+Z<N#SE6C499\u=CCp!!Z8F?EQ6
>Ye@DY Ijm<FT/TN<6M&Lc*HI%KyY\+8^TT*pHM>k8w=QpG4!pl4pldC&pCnhC?HPjQT8mQwtwR/SHY#eNBkWtN
Q^Q1PA yl#SAI8JSjdR#@DSPj=hiMqEK&5di?J>NYc9l^PmFW$ceJic<CcQ%p^SL1RNjA8:+5m=uRWNAK%dypQY
J$BA:k ttBkC@9pKZ#j*J6dQ=d$Kwt84$lGHR1h#GDGI?:umWA+Nl!h8&B=w5?CNkX56\5iP+cRtLcBS^%5>Ab=
cui65c L^5F%:aR\A!l&q#>^J5cX>W>#A198bHLcVqd%yn@&$ilWKw5&N^dmS:HmEeYV*9$K9$el\Z*5tn^y+^#
5^u=K+ AckLA+bPAj?a%w=*KWMIub>99Ch#9!u+8CBK@pBWjcVk8/T@P8qbeqawqLiX9IhX:6*6?Yw&FVa++AN4
ZEmWje Rn>KZm+G5LJ=4N:e1I?!1PwuF8q9=DtklWJGEbamb=w<4Ak</#w?4Bde4#\^e#A\/\6BBI:/i\p@G6n+
LQ*MlS :Fbn9cuC1n#ida\Ak=Tyq6nhMAYmiElpy=L%qEAa<Y$HywADd+XF8a$Vya%Q\Z6n5<<8&Hb:Kyk5BC&N
BF/8l+ !tCpqe\ytiF9LP^V=</#8!mS=K18qB#pDR8\IAHNQ@8XSR??QkBtH16@%w4KY!HQhWmKmpEN9DhwltIe
S6q9>F $&CT*pSYLNmS*8\SqTGXyVt&&!LL%J4+D6:VkElS!tNHD\%BDGQ9::>9k4m=wWj^1FI<ePY:eRpZ1EkQ
549hV+ a!d1+68LaGB!iACQ<8dTdR^<1YbK8eh1TY*T>!%1eHien:!TRdCa4pK\KZdqTCyq?\inVGDAeW5jeB!!
t4N5P^ 6Wm<4\#&AGMZG%N+nmEYjGHe=lGF8DI:$!^*X&SKjbFmC\ciB1\w<&+!@kHSb6H?EkC=i+>/bp>qN*ei
YFA/Ji L8<A6$hN><yWu^H%G>/ZIi9i\k@C!XTw:aJ^\1&We#+>Mlk:^LJuQH+w+jJm>F&:wRiTEull=MhKmVYW
Km>N>& NmI#<kuW+jK!KK15=4kDiC4X$WyKiCbMXXSnd48u8NSm%d4$u$ayB1pq9kbTj+K>jNe?YDm!d+JAGSkd
YF1ipy Wtk=IVyNLwNuV:%jja1%T$i=h$VFWpFLQ/DiY\ke*6ck@NSmub+WnVNPhq\GZi%1DDRNwjcICcK^6yI*
=VnFhn J%WD*@RaNQMRP/#?NV+Ghd*knlEK*edH/h%DZmMW^VNDTm@p#ultC:wNwlqKtAYaIlt1pDakWLA^iZtk
-AD445 000a2f6847800110333 Page 303 of binaries1.zip
anJ<bj dnn$$>E/!$yAHnBRy!aFj4Kq4hVP9jHeAa4$A+XMXK9S*R#J5WLQ5piQF^wk5R=b9$/FWNyDBn9Z!V1K
c>aF5Z HTIPSRNF5e!RtLnF4Yd/5Dp*LdtaXX+XZcnDNdH9dXe:b*h6DuMh?imcTA4bP9KS<:qZcy6q#*KdDmBP
C^MRGn Ia&iiXpt&AGh&&GIq=V1*uPZ@q\ePdcCIAGySAp=L*\ylPcNmGB\YkGl$VKGGcYnWDE/m6KMLjLtQwwM
+>#5B@ ByLqLlQCkiwGqJ9pM=u/5EKh+tG*>+WMp16G6+B&d<RPb6tn*X^G\h@K\V\hmp+PwNmPhEJDpImB4>VK
wq$!*$ q%eAPXW6Fl\mT$%yB%?j9Bc6#u\aWG/IEW^FGBaYhGTaw!M>#5MR?:BX?clhLN&ELn<$<pt$HE%=DC6l
?K\ETi u<DBE8?A9thEbwm^mkpm1LdSy9dSpmBAb5pc\WyM!W:ebXiSQuBT?4m4T#F=d#j+mPiVDh/d\@bAG?XS
mqTDR? %DmJ<E>/$:NKqS?Xdup=ajMa>u9J$QaRhtEbC<yW+qLnFJJanLdhuLub+&@KN5e<Bm9dm*Tk<&uh#HaD
!:ADwi ueEu=?E/=Gp94&Z6S#/=Wm+4ad=u9LZW8DF4K+w5S>ENQ$ljlGhPMdnYRah$Fj$lI&aLb!<DD=thG69A
LQ6m#! E=l8IHK5JR<WkEnpn4+1qYaB4/cTLSyH6EBkwCBHwCT&w&Z6CiTVNL8wH>SRB/hky1J/a@dKL%DSVPdC
<yXTXK mN^Fe5DEPQBi^*#NmBQQJBVHbHPtE!Wjby4<qFd>=9VuLcq!HpR!BdG6ul*KX<adkZ4&Xw+9>L$$Iten
kHEui\ E5cQbdTdXalPQTd9*kHVXH#NDF\JLeTl^TIn/<>pWA5LGb%:VPpRGDGSybqXl!uDtecXGX$<4p&MJTA6
#ZtBR& yYDS*N*cIiGQtPTNy5K@B1NjBa1/tM!XGktcHbD?RG&5h/lMMnjLpe1N5X5wk::R\Vyi1PW<48M<WMJ\
WRMI^R Xd\J%Y<5$R/?6Ewi6cWRVYX9pSuwcptTp=ZM%t=AG6:ZH1Gt:WEwd6@ZWRknHZWl*ZTl6L=mED:PZ#@&
PDZ9Vy kAKaT1mKtBPHm9mj&Dd?hLpiqPkjqIV@L6E+1q\jcE@hR!4h18SPA5q8/=+\LMu84SK54k>X=\Y?dIul
KLM\:I ccp!KAMFnuRVbeZ</JSeAtZS+\!>:6CEdd/aYj<XT?Ld8@4NA<qFEk>Z=Le8MyKnq\=NjBI*!R#K^M^t
MVC@Cw DJILJR+WELa*TbLjkEqeXMIyhI#5@SBI?Bllb1LWdpQFT6mAZS*5?=tdXD*1^Mwct?9<B%?J5<SDEVkt
N4yeST <XTHE9ASV8D\&RjLhGmcD/6V6NR$^iq>MFA$6St&kY!>tYeRMGS\#M9CZQCInS#HpJ#GX8\mBD\i@l^p
eR=16C :?#qMqeDIp^#@hhkq>aEBhjCWc^5J!ASb*L&Z*E!R5yIB$1XM8iJXQLu9w?5ae+Z^Mn*^iAh@=y@4GKm
Z>Y%mF IQ8=^*<VkkA+%dyJ5/<ydS8i6CP4%FXW?1/aN4m+WeCE\1%EbJ8etdLpG&QL:cHMklpWIPPX&E@Ee8LB
HYYGut elhTWSuqjhp8?k^nGNyPnBQuL+Z6>Xhn<L=lGQh6e#F5Nm/he><V!5Ee+h5W^?Ru#ZV5/Vcn^BqnbL%X
#?djwj =j!#wpJCT44ISNQ=^!8ZnR8=:5K#NKNZQJQQ^KHTVlLTccbY1\#DT!HCn?ES=Mb!4QAn+WnbWkjIKj^=
8e8/jP QLPmaGN$q>iw:6cneZayPTXmwN=Ji*!L1WAkY%C@*W8JNSy*>yRj\jkT=ZLyw9yNI$Wt?\lXF<jqtTy6
DAwyJt ZQ<5$Q9@P8@IQ!5A@/h*=I?\K^qLE?h@NCu>Pl4$%#hej*$Datd?/^8&9\wkk>nb@9cG?/>9RH<XiYVl
jDS^b\ b9u4$h^@9Rt>9*lZZQ@\\VD@y#?Gk+Q4h%aq$Q?mH+iL/<>?HC:Pj!%EqP69IcJe4H>:\@c*N?#@JYn$
<E\apu 4#c^Q%udjtPnbAj>KYn$GRjId@TPj+Qti5cp@S8>+>?ku\9:@I*i<Y@RdM?l&X/Cj5:^<^8>+#?nu%Pw
W*8wTQ =91N*QF9$M@&G8hL$B#Q6b#4Jilui\*$EnVLe?mZeP&Q+M*jwnqj\4Zu6LY=PF@C6iiKDHJ^9wS4:M#Q
bqyT1H ?CA+Z<I%N6B#/Jh\ni&b$w^euC@l&l>B14>H9+S44M<=hnqj\nXYq8ii&E8+>4#VmjMqbH9YAeLF@KJP
YW&S#% b*<G#jK@5%\i//@S?Wi=QFb&nyiEE*Q>6udjj?>Ci&q5M<89H*6Paw=j^GhujXG5NSjd!*4tH^@MC^9#
n8L/5? c#HC!5#>H^Z/YFqi%Bn&@%&N+id?6b4kItbn=jlLt%:Tq9>cl?>9hQ699X=@F:PY@&QS\@1d>ep@qtd>
e8TdtH 8>iLp=u>@\9/@n<c>J*\@&nRN+N5/SyPX%u?qF@\ec5hQ4DM*&t\l%a/8VBw^C6*YMR\uZNIIhKGCLtP
:W=55$ DWcHSH\4MlAFIj+B6BAXRH$+IYG*yL$$E&XL9^Ty/q\lE\TS1d$RCMFYHn@$=W9k/V\awFhe=ySeqV5/
6G#>\6 CYS&*1>/mwVBw/1w!IQILl9E5GkIYNbTN<:98\cVEdRGXA#%PQXW\WIAeQK/ZS/nkSbhJuHCeGIqeL&Y
!m1KQ8 HYC\Ik/:jGNReG$<5R&%AG$C*1$IRS=EyC!:Gj*^JB%VGi\lHZbi^AnX#iuG*p/@lkcMGqMJF88Th?\a
ccQP$R y+hHBp=aaCSG<Z^N/8$cb:\l^5461mlINy9ttH!cbuAH&&wQ*REd*<aXJ\!t4RW=D<AEX!NML&iLWa^h
\9ML+E =WP!wQCA*y1GYtjCW?d%GY<DG$qeW^#byqbjD+at\lk/mCCM!W=!6Fb4*>Yntul:1h!&8Rcy!6:clZE9
G6py+Z >14n<?K<RmBqc#4dYN4LmhDy*NhJ9k/ClNB@cLK9CL*8D<K4G#cn9jb%ND?lh>/u6c+iyVJj8/kHnPyq
^?bVTC KJ1VmKN1!IphIb%6a6RV1HyN1ewBlAd*yn<N/>8*9I+#hZj56GH=yqRR=wY\FmCq1HLX6dy/ZtEj94CD
\DwM%Q R%clnPCBiZT$bS9lhY=:Cp*B5q\tq=$/Vt8!cCM*MtVZDF#I/uYS@<L?dXKl:yEFWXFDX#AXW$Xe!acC
>iBcal lQ1/J#>^SM5!$lG4FNQ1W%K9qC@6dSR>^1ecDP%B5VKK5p>1H>JCc^i$I/T5K=IcEaXKeHV5^&FV@jPj
KW=u6% <L:dmMBwCSTL4Xn1$DT#DFkSkN\BN+dZ#G\D@cEEnX>mhHwD#Z^#^E8lp^HY<:1A$t9ejE%RpKu+H5d\
Ce#K#t 4t@/#jM6%X4:kA!IZiqL:eWKpM41q+\e6CtIcQQViKG$*awk!XEWa?9A5QLh#jdWYqe=8qZqwX\!b8yB
RKk$ed ktt@D=J!nX^mZB+DRwIPnnY=ZQYB<iay?icSE51W8cI^FA5QeRE=myk+ZQhHSA@G+qFy>cS%/18I8pJ&
#PSaaL 4N!6lIjSH@M!jA^5lcWG*YFjtYTEPTGl46EGn!FphJe/Yebhj!mcES#N?MIp/F55AL&dJW8m1$BJ<LX#
PTeT&5 RAMl@abD#$>JNN%X6$e86>ITnutGK<lm#Kma^l:PBTjh9ZVML\H>k/#H$aS^*\cXnaZ?q@=eihXc@GJ&
$k@Nt* MdPB9TXChTS4PaKH4P9h+!ueI@/ML*ej=Vc=c4:@iH$I*&Ct\wk58!RF5+Y&SHbm$!te@#NLA%ibJb#Y
b&?teX RTARbGyai/b95HqM5HA^yG95kYAD651qHphTCn61!A:&KW8eWHDemmh!Tpk?C?6?k=d$X9*G=cl6y$PS
VF$6dX h5+CSDKh!&cmmtNNFlN?8H+MuuRak\RuJS:<mZq?\cREI65?<$C8ZZVq5:/=%y4^aVHZjQ1aG*/Zp?cW
B^hmWX MJ*1\d6ECp#!^Qk$X$aQk&cTP8Q\$%RC:A5q^ml&Z$:G=wZMSC?ua@cR&QG>#K\>MbL^Yh>GF6kkFwkT
e6ZmmC t&%dDM%J?5&X/?ILVM6B>kcDw!\Jq</%wLJGN@y#QHF<S%&GIRNZ&!F\YEaEnaI!SKc*RWBjRV\:TP9Y
8/VacK K^NP+Mlt9?\ZKdb!9BuSZlp1l6+h4cAe%8T?CctIX8D4k4X9ehWYmNKTHEHPl9jnVYhQCD<+*ketQiEt
DFm:D? eF1p:By!pCS!+e@:8Ca%i!IlT4*BX:@9RQV/^C/d5=hQq8CGjhuJtbQIGW^A/tGACJWXK/T6kKtIE%Dc
&<i?d< =a@l6m@a4<T:E=?dH<GVIE!PKNYhw^?w<aPZT1#QL:cCk!a?h\=KeM+w?h:#R/XBYWC5HcLKR%cl@jEI
cB&tQ5 NeeTqqK4yqhq>YdGC4Z%PKTS?<L6l=yd8*ppjXh@*JbR@%pl:in<?NDId*!mnX+FTb<aie#<m9yMCuN6
qLD695 ld4:96>MAc@#LY<\nbRMP*b4/=Ku$n!MnX6Nw\<KFAq^TWdL\9Ni5*:LIdpJVwuFP5ITe%i8YFZ?pcaR
umwj&\ Y<nMX+?pB=FXi$eDd&d?>GyJX>F9&n?<D&aHK?MEd#p8c*6SHS1ZFFIluJhXP^Pq=%wnZ^4B&=<+c<=m
wN9?#8 LtQ?VKJI&Vm#8klbq%\/wPpaG^*NbT@=ue1aVA14mwEq/PPhLqBJnqmCiIMkW#ZE8GWJ\=I6tZDy^E&6
>5&5Ku nTT8ABRSXTYCDWYbqX8#4wE*+Sc%Ze:HjWGQu1/P*<H6bR=!YM&i/c=t&ZDyT/&kl$Re#e9WqR>/M6Y6
5NSbQq DDd!bcRqRMnG>L!8lnh:TL!ajGe\yWSW9BQLM*&bNe\dk+q+P\4/Ie^FG%$+tb>%&nkIZ=cPP#ic6KkW
*C+6h1 ?<Xw/m8#wA5DbnuHNQlFJque<uc:Wbm9@^wyY>C/QHeJ8?&k!n1WRDmnm?aK*HtZF6LwS1+8Z5Pm<Cc9
<BIN&% BIqQwRq^&1nTdiF!IeJcm*V/QnJ+WeYJZNd4Qn*GcH^=/V8ubStm1u1?#%61Cl>*E=&WZSpDH5cp\qb:
6Qd!Fu ?qITqTuddLS!^^$5&<iEV6MYdc^QF\P?^\P!<$EWBKu>EJiED&ynTVG<X#nmAh>YWC4+a1RNYjAX?u9B
mKG?Gl h1?P8GR#DMa/iNN+Y:TRitDLJHXI=R<Yehby#P!5J#V&IXNkEtP6^WPKJ/L*R=inT4p6\%6DEMd6m*el
1j&pcj P5CR>pG>/6Pl96FljJFHG\:D&&+Y%R?I8SHFjtBHuA%\u%cy@RAW:%KQ+kPKcIFFnNRAE^Gnhq&pSB&E
CHwu\e jD%cl$#:VCmkVW4+l9GPIMiiiwB^heWyTNSmwWIG^1@A1=R=>V^<:W&9J&\aLy\WGV!>m<da#B%6?k!b
ipqcEa aFly15aARZPk1wTw/y9ARJXT=lVLT$RKXFmIbBN/H!pLQAQaiF+:wH6wyZyw5pikhk*#Pt^yQ@^=8ynm
5!&L$H lTH6E<1i<wTb%ZeIWMYb&iJE>BJq?$?^KbFwAB6FcA4mtIypE8#l#@L1pVAJYAlEVMlaHE5pGkndFEnJ
:+iJZC miYnX^GSL8+McXDY1iEZk58?S$Ab^j\wu<<wD6c!<We$5wWS>MJV@pq$wCJjSdlKXXWJwPRW5EL!W$YJ
6JR\Fp kaS^Jq9\JR1E>4TawkNqMAIN8V*1\kCWa9>BJ!!=htkEej@^$y5B?T4GnZFKh<L5DXPc4@PZ4i=^u%Vn
b$BpY$ in/cM4!Tk1tyYa5!<<kXn<PH$P&:4E$nu8MSP$L^:Tt=$AT^NK8^hPAWDRP4:hFqt*DnZu?wWlWJER#8
dX%>ab D&Z@MtMd1T$=wB&!n%ElaaN$Tq<=IM^JkbhpblbRE\MebIEt=<c%e!peMuKldMAkXkSciQ*eEhTZ++5h
!!ct>E 6a6*qAA/<VtlEIGHykAKL@d!RlNk>m%lH1Pq&P*&5XGe8pIb+qD!yDtbZ!GYpK<#E\HSbqdPhF56+StW
w9BNR9 GEMHabAlEpP#leAP+m58TPMK:MHDePESb/cS>6$h5LFCW!CkabAeDDF19=whWW1L<JNLWNMwl^+Y%L<t
-ARa9& 000d59b051a00110333 Page 304 of binaries1.zip
/%*GR! J+K88P>GnGRnH6lXmQZi5>8mnLaJ<M@PL+KHMN1KGnBnR=8qnAA4BN<VV*dj>&cYt#C#W#!/1J$@miSD
k#C4BF NFE=Dki^98Jpa=a&/Npc<GcdykGEE5<NLZJW^SyZcL8Jch9u:l1MAtRRJL<nEY#F1dEFP?XHihH8Qkc^
AIII*D KldcPin85JFe5TLbb:N@pShV@upNTeEi&V/Gj1dHhuWWRINHAYijJ@mGMl5TpB%HZRpHp\^4MIJMb1P*
M^L?YX j!Wt!+C+1T\y8IqIV>&^d#LEdCGuIP<k9EN>=nRtt*?Ry#w!8Taed1JAdKFVd+^d@a/qnFp9NIQ\wlcB
GSHL8/ 4P>:!Rtd=bkqwM>hNIlb#yXReBPlKki^Y9>nZnK<4?K??h#N65*uZeBuGYwZ/K?FLkSRkD@!MJC1pH!4
BI%wXc k<t6F/AA&5tMy1@qLeCEZdwEdiT9+466:\96M8F>qY*GE!EB6S\Pli8Y4?ItNy=WTBPy?#IH6lN/jTWq
!u&XhZ \NjIyCXqty6&%C$8I>t&Bhu:\Mku+tmahmn5Ba<GjVpy4u##WHqL&XTMP\uDIWSQ<%YSbEZHFP$wEbAA
yB1a@F ^\lTV?4YFlc:%Y:T%Lcdm5l$?kb>69IWN6Pn4S6AbQW>=n#&dDE%DZBwF^/PRw=JbEG%N6ED6=/JcnXw
>a*B=E l>^IVl=nw&!KWQEA=iud#D&%Nw&pRIVdqXKHwd/B<pW^BDXMdc=VN/$IKkw!I6uC?1P8nZlJ&5y^>bJ?
Bl4Ay& ZXCpE5GAb8Xp64@$8<yipG6A??yNnVF6I5>ZQ5N?P?<ndBtwP\&cd<bD/bpL<y!KS\bMc?@&MBVaJmX1
dHR1yw ZkQB=*H*SmpKquc:#GRyah\X#Z\kG+5Xam>&mu5XmkAt>S@N$IpuKS>5b@Xu\F8Qdq@FqL/lmdhn!BaV
B6VlTt *EVCCw!F89iATdC<FtSSN&Q9W&KQ+^Im\*N^R&ByhA48hTY\1tIqp@?8umy#hT\^e%^$$mTbX>tM56F<
<QeA&4 ThC\1:4dbeF#AXSmIXSlXP@k9Nl1QPa&?YC#1Rm<cj/^uj</6=ly\YdE\8!k5EK<n<*Mya5btk*cdW%@
YN=>SF SwQDRJFKdAMcWyY:WkWyFJcy#FDWmii+Q5GE:RicnK#GA4>k\BVF6qHd6kYa%BWnAy4Phm8=1G//GbB5
*bqXaY $+qcGIW/N=yjiPHh$SZbbZIciCXLD=B5X=ua6J$FQJmlb\BM&NDd*+\E?^QWak>6w16Q4n!ni>q:4uq9
Q%B@B< $mlQmHtj+R<G:4Q9*I>yikEIJ1R\k9H$&?F5&^P\ACF@1HRa\Y\a+#Q/#YA+I^\a*^Gp$WcE:Gkp\S=p
@MCA1+ WlSa+qBI5LakD/&kb4&kP&&+dQNkD<9kb69kP*YE:qSWHM?R=4elh#=AD!im4dVR=1nR8:nRd6SRwXcE
@et<F< ydA\WE:wZW1waTwAy!L<4md<4mA5NT5<=\yD5#5T%AjAcR4*BSB6ZWiB=1PE^CJVp!JT\!L9=tB<#&BT
J<Kt@M q/PYI5I>M1JB$%Gkw!mQ%entd?HND%EGbLHjWYQ9*KN^aYQ8=5BJYkt:Y#GFWPC!!iI<^wk&#/MM4!AF
*?Ak&& R?G!\?LVGBJ\wTP*ulK@K!W5C!X1MeXw6pYA18J^KbLTyCKc<&K@C<S^Y+jh=WIKpmX?j^9DnS6Ppk1y
FdVpi5 FbY/#JVmGSdc+y11YbLtpbP$:JtPC^Y&4JV?9TcDJC*Ch#!nyTQni*etwC\ah#k#y=Z9Dk>Ma@X6$\cq
ZEk6#e S9I\1Y\\8TIb\C1hqAZ*X?jul4*@%5^99QwBZMnj#pmBXQSD@4XQ!?*dXLC5H6S5:IJ5$</*iEl68Lji
t*&tdh &9kTZlAj9GB#NY=#A&=#=!:#eHiB*+<?LB/=c9NSi\qqNe$ILq@uLFHqy*Q=CR>uEd@^&:V$B%ECnTd>
wC^A8$ q=mleVkCjN<ELApmiIkFy51CcTwFcbwG*&iXLDtHiQmXi4^Q>T^Jd>=J^nYATj$e&d&G:hXh#6MHAITX
C:9D<h yTXFd1%Z<M^ZCLtZy:eq64Andc$ldb:H*5>Y6NdEyl>X?1&BE*<PZ:t5?K=QhH>RIWkYmjeWk#hbud+A
l9tV8i ABMq&k4FYMXM%+IlZK11IAc<<mbG^dt5Vb?8<Gb?bimGC5mLY8Y9>kY4Zc1wA&9F&1K1Z<c6i^A1&\Vk
BT**+> G#a%+4I%/Kk$<E4WbjA&<8LY+>SW<b4Y6HGH+T6ppD!FL!ZW4VT$bGTW4qTqLZ%4$cqI\t$K+i=6<&:K
h#@c== >B^98>QKA8>9N<B+Jy91u#X/@t%@+h?hlQ?mZ=D4j>HdBtJt@=P*DeVM>m>=&$DMLQ@5W98d\i%Qy4#j
^kat?< YJ/=@8ScAn$V@9+dVcHjwJ<L?@?Ny6Cj$e@yPHH>SqQw#&n&b:TW8H+nKjRdNNh#LYh@Cb4nPVVHT>C5
H41wkj #:kcjmMy>B5$<*Nw4lik&b=#c@%GW8k*/Pj!8EA9+S44e>jtjkuZYJ>#\HK@lG9QP&m+Z$K&b^$$*G#@
=9wh*9 Fy4>*$K@lG\e#M<+l:k=Z#SEu*6pL!EdB?6#n\#$I4w<h>@e@<b>k@/=QNY@MHi#5j%=:tbn@hjtdqd8
*q*Fw? @#J*5#H@d8+GMj@Ye@i*iJJ@8E5R?:@wE94DWjcH4=Phk@59mZd@5$<I>M>F6SV@5:j@Y=<R%#<WA94d
@hy6Dy dj/Z<:L>^meEatZ@9!MVm8Z@%p!wjNy5w>l/ltad9Q\1j<+HRh1Su=XqF/R&j!SBlcFE=lH<&9yCDG*!
HI>dpi MN5EKk+lVtZ*IqRdymwlXlkKjtEh8\TNe+/#YM*#It#J<9PJK?QN+RXB\M!T%@+>8au5BK$+pw5c^?=w
pS\MYT SClhGyie6ii9!W&C!MejtaQA</Ndw^B\VNFF4P<WRWM*^wlmjXe<!&k5*aKLbLYw1Rie*M:6B&RVa+4G
\n19W> WIGwtjTNDA5&u*HF4C&PhC5C&ltW=hnK##AYSdI@8!n=RSXADVl#VA$le\w1kuRcj$\%cl$SK@bDNSb<
/dtul^ +^i*:wm\DWJ@uQc18i=IE%e9W:N4Ady&qNqN1#RM5w9B1@KVV*KB4?J&N*$qC6H#E%5ak5R^JppKRtA>
>Ze/?X mVPEh>PmWJcGt+85Ghp5JyZJCbIBCC1TuYkm*Vd+N<5qy!1FB19!j*RdTlHqA!GlTe>HM%\Y=ImQy!Kq
%a4chM JEqi/JIXV=^<\TdR*\qc4GH<#n44\cKX&8>X6Y#YC:XRd#CCAwiA+aaBl*44Yu/TX#!B%R<jmC>8K!Tw
&tyCEh b/l:Yc%IjFI4u>b!6CYH&*S1@QylbJ&ZmchVbQX81*qmHhniwMXdcW\IBGX!TicAb/6qn>/VQZ^WS%ZF
kPJnpl luh+t^>qWpEZdB5lYub8laEawCBY@Z*H+AwFRWd?^&:R1\L:@A1NpPaYELMyI8<t98nu\Ie*Bn1un&Z6
ICC/m8 $%iPG#ju>%Aa!l#mji\?6KEc9Z8?FN&HiSyjL?HL=NT*Cy4cL>c8p=4ytc$dL6n*4I:%6^EXV#h^5aH1
pjNV1a FjQ*8?@QMVA/8b1*+6yGSW?#^KuISaAy9M%k<pjb>Y^*t9Bc^9RF@V>\wRn&6a<^4bE5c*LFHuF$Xw%h
Dk56KZ J@n4Y\cYFkmh!:$4HXnd1Ky9y?up:KM>t9&lWScYI!Ie1>KG8IjIl$SGK=G!@TFE6tiCTZj%FcJ<&MT\
P5bdwW EtMZL+nDGKM/1\FGn\mB+9IV$#1F^jZX^lB$N6Q>tblp9m+n!=*ty%AjiR<hCqRkidZ&8m&yZcVDW!/h
VuG1QA SCct8Smt^5JS<SM>\yc4W&AXq+qwESqSenY^AX5E5&PT*9EhVe*:4iMJwl4JeVmN=IqS6JyZA$qZR^nW
?Y$>M/ GwwnSLRNnImQ4GN>1q<RnIq$ct?>t:/@Aa8>yyPDEi&l<p^BMS1SpEMRh&4/hk6E8iqm1HJkDub:+1Ik
hG8dCt b=E!wMtmBZ4J+$E?l5D11Yh#9EFchnblSSl1a?LI@ITml?KFyBSIL?qDmCQCdFK!%IFhH<P*aPNqT6LP
L?$Cd% XR8?>FXFiDGuDHM+yj+MVbtuKe?S\/\P5BKnmYN5dBNqF$eJLc\XlGAmXM<<qSC?PJ*Py9eqN**/1!nB
%81j\I hBcqcHhWRy9uN$S1XEPbMDMCpZ\pPHC!ZcXaZHF5y?Q$n>b#4ICP/!D#kRi>@Ew>=PbG4tDNn>&YN8W#
GeLZ?a *eGhBc9ctThDd<>mG<ubQS=EZEm$R+Y%^bMAlNb4>iWK8^kyG1GDECd%6Tj4Z:5\eeF5!l/lTuK:BQ5B
u16q=W ?JtyLApVt8VBl?LybJi8Rq?VY:4t6mS&?M5$lA4deiAJPeq$w+L6#5yV:^9jC*Zw$*eHNa<#C^K1n:\T
c#/Wm@ k%y\It/Ay%@Ct$\qCTbb\T>e#PdH1Yj+BJLFAlJmX6BwlSN\l&lt#^hdB*TaN5b^S5^mC\j1Pwn%QBcQ
K<**lB LQu*YP5X+kC/W^RnbC%#Z>uRZRJZEXA8WWhI6BZFJqkyV1D#9FqMJBeTW:uGQZPTNC*K=QiaHqF$p#+S
QJjXXq =FTh\!@*&#W6iG@%VjKl!HpnXb^bhVQtbGA6LdS=E1bL6CFy5k:/d!GQqtuHHK&LCb9c8=luiTw%/VdH
CKehiP EjetW8S6D6\wpK>k$CXXY?$NYS&44GApJE<X8*#!EL:Alq*!9&KJLBSHlQ4MT4=?IE:THF+11/leu#L9
n/4FuI *=ila5lXbA6bE<<@a*$hJ&!SNFGbewI%XiFbD@\1*X<\e+VAR/nhj4XHBT?*4$hZwei/V6A/hSp5l+A4
Q=aDId p5<=ZVS1+j!lqXhVieEiwimIQ/A$&dj69mq$6/ecqmR6iZ#Wj/@TPNH?t:Bi^ZIcY+a\bq1E8u9^<l8Y
Kc%pAJ e6Kw64yZF$#D&6YK8t54*8<5PYHuG$$>*!a:5>4bZkm%ypW=h=#*n>niqiZq6nk4Q5SXNu&DKNcqWDhu
SW%><6 =j?A<eQL>=BW#/$=1d!=CGj=!15DCpW1#PL?iHYMn6T@wEcmwTK*c$^qY?K5+#$Z=lFAKNq%Y?EH%Tin
Nh^^dp ^+49!FkK+wl&V1>q1&ZM?JcKk+iadI5:QqA+ydchyAupj@tPZ5ebYateQdd!GqjtlM*AYa<9N?l:!^1E
!n$lbe 9&GPWHYK99&5!HmJ$WKVu?T?P:q!J*TbhC%?AMB5iueS\CLN8qSPwL<+Lh#WPJp/=Ck8a5<<Wek$<dd1
\b?:CS itci@p9Y8*y%A^RT8GHSLYnZYy6qZlb9+QICaW+qViGpGLj\k*e^eXN^J1eY:^8M@X+=a%&I\cNX/t4/
*:5Yl? XL6dLdHk%c\/?!Wd/$9yy@!GB$BdNW%p6WXCFR:4qna>Wh&Z8t6@Zu*Eu41V>4/tQQTGhV%9D9?:wbMe
e&<tC4 1BAG%mbm5niG+c<WeaI@+ilC=VlId#^&JWNL+WJLtRl%1qP>Z+EV$At5y&Q6WNWnYBm?WSdyWi=^&VLJ
4W$!Z? yNw4XAZuBQ4c<BnJ9<:N#ScJyabI=Qa9=S+IB>4uqpZ?:C5\iY@ni\j>Xdb\8#J@+RS!Z%9KVMFBY1H@
dakeWL YLNKDCy:I\aC$FF\<h+CuCFauSHT^hqPt%GEYESte/npMGj\5T$!WQ<RV6ia&IacG>wEl&HISDpYl4Tj
Zp@5nk XRCeG&/9pILaHM#AR6ZIEb^CAj\Mw*pZ1Fyk\GM4DA&?CZ5ITC>wub8E1dd#G4b:N&#^Vk+!QyWCw*1H
RAcqwu &K#utKpAb<H5$WS\4lYadtbV1Y=!yq?>4#EkKqVSW+qEkX!An&^FcYm^4T&8@:bM8R*GlMipEB1Kq1tu
#N8J:j m&uu?FR<eHG:F8k\FYJR8\p#B\tMj#QA5%eeGl4phGT/cd?9@AQRF^1mG!5YCRt61*A1nXTeGtp&$T$l
FlNwtW /^MaG\1*G\tamHV$@%!<hA=5SaK=m+*l&^WlSwacm#*H5!=P#bipQ+##$e48e^$$CRm&K!u5W#nm$!y:
%b%bWk b?9akY*lwRn#:yFF<KP6p*pJ</t5=Gu+y<JD/RYKAYH:Wnqw!tB^h\^HccCTQDBPPV=PM@/LDGu5kyBB
-A&@w8 000ce3ce95200110333 Page 305 of binaries1.zip
&1Q#Pm <H/aqj=B=iiIVNGT$DYw5:Zm@R\+Wb<TWTnWQn8JWay!Fp1#>C^:j@84%\#!\c6BF!LV1#AF+S>yiJ^p
K^#jBI A5&X1RX/=iP6QyHZ<1lVJtdE?FGF%c/Y1%hYlpGichhJE&SGtH!GjX$CQRqXa!jpGK5WC9y5*pIlKLlT
>IR<!b 1:<B8@5li&R:&J!/Nq?$yG>9iBXu5Fql@=dB5V1/1HpX5Vwn#twu<6Cub%M^h\qcJwk$ABb<Yybtln+d
w$MJSp CYPLGeSpI=&ZdeX56!bpbcBw9tSWbce@+n</H1>b/8A$Ry<neaXamqNwSX6p*chAc/bamDhKmYJ!6GVW
^H6Ylh >bp4PNEw$8EHuiwVAq<uY*l!PI=bu/#B%E>@ch$X<eRTm=9b!tmh$pnS89L*@p6met?R/II\BK$^wtGJ
CtbMkc XinLmA*bEMT#n#8SpQVdEelw\^C&=YQ:^p\CLZ&$&hDYD?/lTJeRN6e&45>PmukPN&j&n!\PB?@&Cuq5
LWhm@^ IiPbEXMhVImF\&cG#dKNVKe<R?k@H%ZDAjT:/DR4DhK:45?PtjlSLFml&G+GSPu*mm\aww*PB%MuFR1I
E$PNBu ^?:/mta!KSPSmt14:cY>jdZj=p5lC<:+>t\mPp/yH#LiTbpll8L%5/Jyd9?RT9m!5?j!H5dkPF4WN@FD
=tt!Z4 Zd\ick!?=AnGlCpT9K?m9+GF?ta#FA58!hE*W4bBWme/$k5RuVMup#PQebiX!K^\RNFTblt?VQGCH^^i
KP^N*h +I!bcNGihGLji<CMl/R/w+Z&Xe@ti+WtaSuYK4lSF84Z6\hjp$QXbBywyBNdk/E95SLRyX^cL@<ww1+q
D=4<Ed c/<+ECw5B/P1KJaiNAn<:6#QF?#PN=P/PIP\lCDhTZpNG9!tKSbiEaRDt=$kClZihS$PXT8jEXZ1mNme
lKMR*u =I^^m+!!W9^P!La/XK$+DylFj8R1qMT?h6Y?dciiCWi=tnR9lTabWhKejJRtKC:eLF$nj96PSlR8^Nbk
it\PC= P6w51>n*#dlmZXllKAPqiLZL#P/=dN<JlKCTuMQ&#BnK+G#+ZKDh*am/qWKDRVkXXn>k/4^VF=XHR?$^
yCWQ#J L>9EqJSeV=*BPQ?LN%W\pqLp#=LkV<ndtlR@DBFS8Vt?NAiHA?EV^Kjqq/nhbE*iK\=?%Sh?FLL/wu+I
l5h^#A @6:k5CL\uXL+&wBTDuR\#/AFyY/=JbY%kEAS6GZ8qpS=58&^dk>!lLRbRBJ=u/Z&=4MbtYHQ4yq4+J8B
FGuVwI i8bc\dVBD<aFa4bql$11Q/\c:#S&4/AtW&nA8*kbQC\+9yd6tVD%Vh8EyG1w#\RkI+pH88^SnG\*hupZ
aKEj?P m&iYDIpMkEG=k#u6SnyaZR!:Ji?4n>*C/TKq1I9ZQ&cqWL>*F=d@J1?WZJq4D8$A&N<PF>/F=Ha#&4LE
!m6<HE buHq+6R=L:FmCu#9>llY>>tP9b*u+L5Kb*!>%AlTCylhE=5/tmBV1b+:%?8nCV1H8qFY6puMY6dV9py%
u%JP=i ^J@<=nB!@6E=CnDDJ9G/@899cC^MZhpMJ?4ESLE/1cTH#dbF?m6nC=Y@KILVZlND5%HR5Cn=:ALnK%hm
Kk=RNk L9k5qbhE/$F!$QCmCVdY6jc$JXeP1Fk?JZ9+MRFRDiWdcG<k=VDF\ktGqTn*/uBYYj%>cw&8!y1VV?M#
?1Dn9d aQeak#I*WEjmHH>8G9pLGGAAlcYqjY*BZd$EHVn:*LHw8!K>FBCG#aiaASdPmj/:H4YLKNX5P/=lt1ub
t?^@n9 uN=5+Q+J6J?kWunXljhbMjINC*p!VaVVF8?cNRnwAZbGVcN?1eS$pndN=VK9+DB5HcjS#Q1$m%NnL:M@
8Q/np^ $X5WHe+VWRKSeMTF#G^!1TV\B$N%WD@$#1$ym:CVRBm\^iB^?tJmVnYVtawC8*TBQZ$^?^=^P!:$Iw%k
CI\Y9l I1GkbXG&QAHMbVZYdDQt&HwK$ulmI&c1:&bWI8%kY5KeYqKJZZ4\ijQ\LSyJ&hbJX^=R!!aeLhcJpKup
HkHLTX 9SQW\9Py^9PIciZ$a1JpEI>S5Z<+&CmNR=t&#YABRqu>qH<+&A\EweHNaA\KTeJ:pPdCEdKnH:18TAD^
!%^Y/Z ML/C?K&wPV!aPX/+PaKq16wp8V\W8RdtPaA^ZD@WQB/PQC@8QC>c@P\^w1&$jC?y@Fc=@F@j*+9p*&9q
RXcIjX 4/np4wkC<E\L9T\L9YRK:wWKTc+\6D&LYu$AiQaF&pbEY>jF4XHF*YLFiE4FR1pA9LDm:FCp#dAT9KS<
?::BK@ L<eC4/#mqd#m?+SmH5PT%w@Ft&VqZ5QqZm\q/XqqZyH@/F$49?<5/Vw9*914h/$Td/<!*dpe:KucG:bK
L$n>NJ ?*9X!pHy9ZFl1&qF?uwNQqmBq$/=%:j!N4J<dY%eZ%F\Z8k/4+1TDFbIHdF/:aQcB:b<d+c/?<:/i/$c
JMmbGJ Hc&G%1D1DNNGd\9ehFYEXeetZ6etd#i+X9!tB%@<QLa5A<#W:#Fy*PIpWJK1Su&M<hVRyJ\eyP?WQNNB
KC6k>N YlckQCQK8<k>:pJ!StW8ub\QyB=d^5p<*PG<LR&JI8a6kw+6ch6WQh/6#N&6cXuJuuXy?Eu6ut$$8IXW
X&%@9q D<%pP*N$I1IIu4QN9t?!58&#9t<De<$@yJ%?lKL/1HYH$QKI+AYY4R&d9Y4b/<Qh&<:j?!nW^!jY=!QX
$BW&y5 %&aG:w%d&C+PdpDX/@6W5mbY5tdaKQmV/NG<n<C\yP6ywN%/aE%m\PAu>ydyaQ9dAbKuRb?kIX**wZbl
w#emhi APAuqt:CCEFP@?Q:Rb?KpeiT\eiCEbL*A+@Gw#+=w&5N\*#>jd=ka*^!nitt+*#L+?*4++>dE*^:+&$l
8=%=ip HjnlJL<ZAkV>e$*=@*@=8$C@KW:@b%9pe!Z>Rd<yV9<dT?a#DluRd+4V@\dN<h!%RT>B5#&H=u+J?yq<
&:Q5aj G>B9c6Q@Ge*?nIWh^ML!EnR#>#Nw%u<L#jaCNB9uM^b&F9cZwJ?>:=h\na*%PjSL8QbecV\R!$8+^54%
MVFW$* HQwqZGNqj++6L?Ec/*NQnQWqZGMBQah?ChiihcGBYF>CNna8%tjRL!LdM$+\EP6L!MdKCZwG@SK!eV%:
n1yccc :ShNdKBulkp4%:?FB9%dje:>9>Y@^M#&H@+qqyhplwH?8b!q+u?&+:@#L@$>#ik9@mZ&*@tZ@4HR=X<d
YjbZeN @#hJu9>5@X>?Qatb=A%6@@Ll%>#FyGFy+tL^S^w&MbPp1cY=lR5^N?5jh&Hy+1^w/mSmd?6kd@iHu^BE
@l1EDn #CSmd&Q9yPJkcQ\LLG41btq5K8Fp/Qtj*1\@T6L?*b5qK1L/G&@Y$>LVGRBJ/FidVREt9wBj4/hXkAkA
J@Li$E B9nH/>hjGARacBkEJDkaGDkpFESEJESEFFTEZ*?SEFCS$hA^$NGReZD\<HB\!ElJTetw@9=//kLA\\B$
?:8tw< AV%kaKTAy#:A#K<VR+Q><RL<>RWJBREPBANA\<DC\cMA\MEkIMAl\aHREL@?kD8DkWPkRkKkTNBalJTA
\&%:>$ /Icpnu+a4HE=$Jk%\tVh!6NddFlGF?SP@yeWI8\1<dt%^5+>HKJWCZq%uNm1Jm/>M>5\qAG\eDm+kaqm
#Fd84n +9u%/4N1%HlZP>h>e:5*y1=BTRWN@jN:6&b8\etFnRML?%?=JDVM*WNTmywGF\??kTR%LV^CW+8dl=aP
:C9aX$ :&m+ydR5QeQTTq1Gq+??$@JIc%6=lciZ6w/5HN<@4RMkAalQK\CaQ&=JAJA%cwKtIhd&Cc=e&P?68!Da
T$b:Wk E!B!cdKW/L9Ny!hA@puujWZGeelQHcdPI=:#u&Xt>#qQkPVS<*9=6mhA/jKu+9h:6R<@E!1jAMiN>9@H
w^Lq%> RP?jynIct5Wa9#YXq4Wa9*eDEF*^w6#Th^/jPD<BHPp?*qhq#NW?Aew1Ju@$Xd+@@tT9QQ1#5pukG%4L
p5elJC 4%N>:=Bl8t>hi\K5TS@<LN5PI%AtTiKAH+m!Hq=WdCXYeXct/99^n$j59@VEh?YPa5\MmD>&jY&p4dBq
TbwXIA /Y+WA6?<ti5<*9L<<RTaj\J5qD\B&m=?Zqh>%*6:yTZ\:iwJWQ/=T8By?lC*#t\<k>Nt8e/51#ZRp1FM
A!6LNC nDapcwQD^RC8NpXSCL1a?&pt?RpR\6j=BFA9E@mPT9R+/<8lB!$T95=QS<i4jAXqHh\aqARGPS>RRhQA
M+&9HK E/pkN588J@+=e+WnZ@anQF$*ETh^*Ikjlwyh@aqiEQQpI@ji?Z&D%lNkKQRJ5J?J8Eju:i&hbdRCE$?N
/&$%aq 4WydR^wpmID%AIX9YDSu$:tZ#uRH>VNXkuRwai&HNk/nu5qtw#n%>>!9#u$p&*&*^lhSQ?pHhD=LD4G4
+i=RDI RkicmJK1Y/ZDCqlK>M^n@HyPX9Y>P6RMnLbG#h/k8H#F5W!M1R@4LPp?n9*9m@Mqm>6#?FRBAt&E\cn9
%?dI>L q<%pD*:?jHPded96?VV:u>%l=C^KFVtkYTBJpy\EJYpkRT!l6Gd$Ltn\5ZH$CRBt@\SRhZ/c!@VCJ4yc
S$@H1# bZ1E/9!lNH/w?*:Wy9MC/\q\K<GX+@kEaQn%8Ly$j9W@ReZ4EZ:8k&SKT@KYn!i5>bu8CiET$=kAnEmD
>Qkh9n #$wCu/Y?NV*Pb<\yjJ6=i@wE+DC:Sj>^<>H:@dlYl?kV+C*X^8h4hYlNI/tCLP\Ild=t!Dk%AnE/@YYM
u>>9:P J$D6YJy8dZ=6ZdWcRq<hCkD#YG4J/AtRX>Z=tiHP:Aj?&=@j:Z5Fu8cQ*9#6K<K@jMX%iHL?djRhd1j+
Q9<@!L =@ijhC:G:*pijq^>D4cjZ9^<u9#I>m:/%=n\ch4K8LH>>4DZmjD=Sin*V\6@95:1j^\y<ia*%&FGuP?9
Te<<tb CQ\WhD8HNc9IXeR?QVDHn+^6+Dk>muBbQmXDMM$lQI^iHm:JVlcQ^ntW<mQbJPQNE<DDqil8pPtai+dN
a@45J? dQJy<j#:*>p:@9Fy/m<j+#+!/?k18PMLat<TN:98\p*=CFlc9mGI$Xwh6WuIu$+hdpqLjHW5tjN1GiiQ
Ibhj5K Hp!\jkKeI?W>AZD&jplR*mQq4$!EFS%Q+wSX&i+$Y@n6ak#qNAe$YP1!nGj<Gm:@jMGbQ#+P^cRX#yF$
8Iu81h mDi&wjS6WmGL#N<%dtR9it*^F<#Q4#Hc4b5p$^TE#Kq6\klVi<#699p=!1yXIykm=Y:*SapCKZI:CVCu
GHjuJd 1y/HZ6<!=>It!j/ky=Zh&BAykTDP/#\A/5IwG=D9!enWe:Y%DIY9aGH+Klm?6Gnk>tQSd+#D%mI<!nL$
E#1HeP TAt#TZ9&^?$&c/i5NaekS>H4pu!Z<KXk>wPt5<+Wu+d=lmJm!9w^VdXj!DtQtHZ#y>pQlW&qI&HpZpet
*@hu4! 5W:m1C8^9RWTb:YLY9QLK^!L5C:4mSK&T6e@Fl6=d#:XneaeFi:XFBZa/u$nPm6*59LcDam*Sl4^\k^j
+HkwY^ m84*Fp8=F@u%TM41Q%=Sj9=ba9cDyPwZ&XeW91Q@MV#1*5W8@yw\V/pi\=y?#XBcubK@i94YLiGu/P19
XuTYe* w?k@=*M<Ai:dyJ+AyLc@Dp8&u<F:A9#R!*<C^HH?Pp/G/\n^@e@KtjhDGi@9C#J8ku>NRB1YA46!uV?W
ma6\y@ B!t?ybLHm1c*yeFRKQdd\IIubdQaL\w<#S*Yjjd$Z@bZKB9Gj?YZ&@n=%/V*%wPt1*MdWTSY+SK\/\a@
a9m=tw MNQ&kb>jkLCtTh>\:w89hbchKGRT8W=QF/aIDaI!?8AtRhPyH=P4qnbui<6mlHmt%Tlt&Y#5ub8t=ltW
k:kGZi k%\pKd+ZdPVQ59y>I\\uX5YF8CB6u&D^>%@1KNK#Y64C4?c+IHlG5Zp$aynX/+8Q*lBR^w#G%ej\:+$q
PVa%ji !P>PV>WCRBh!cjpq<1XTJ@+M>jD\W6pjIGn4<Wt9?TT*WcCJG1Vh8\=GX6+Z%5BTdaQ<<aVuaWj<m^\9
#nRWVX Y9Vc9M<njp*CZ?Tc=5p6VTJH1I#PbLBln<=/Rl^nApS1t=4Dn?DV6n*J$hAcGGmD9H!#FYi#C+u=/wwA
-AE>%b 0003535995300110333 Page 306 of binaries1.zip
nl$VbE Tc\5atwqBuS>WM4h1lBmBF+i*#ktu?aVbQa!1F^N+$W^ndw\%$CtBnCAM:!Q1=?+&=8KBFbbtVh4@EaC
aAtBX4 \15KkX*&$9cLl5GedmZt+K5Db<ihDTT:jXuDXG9dj^$InHM*jZQcVP1k\mCI<qmFa$e:MW&<u55G6XnW
GdyH+l V*TPJ6<Yp6&?%R%h4XJ4yQJC^\b/6LD=+?Z#!#>pQm$pXCZZd#m$qZHq/^*mh4F!9>qRTS/IEJF9dq@l
W9*aJc \#dd5!>lX^tmWNXZTmLBE1m9?nVE^=I*it@PVe:TSIP4Y=$5jc$>@jQ#clqS^GeE+!nTKNJIJXVl+lNB
HtXZN+ KGnh5CjA4&uhLmM\kb?84!c:RA:&M49Hd^<i:Mm4jj8YV6?K%yeLMANFZ5^\<Zm@uaK*u&GQQuy<@!pB
MqN!?u \!ZW!c61JjiYV*\@6V$>KqN&Pp$wVlLI5i=HN\c^yhRl9=T$pF8Y9&dFcWMW%Lat*KetyY1t@aQMMS=?
:c5LHw 6PQX#Lc*pnZdKQS4<W#nP*/md+d/9Qid6y@6:lLiHGWK^em*$J5Fw$TD$E>T646RyMDR+!/k*+XAcW9q
=KRpIl /?t>%dLhi*Q#9kLeR4NaM>WQ#j<JeHbGb49EjM#&6HnM=J4QlNI+$%d@4q4N^I4p6q<9IXcjEw:#Ah*9
BM^MmT 5<yM<w4uwu\4JW/HRV/AcCic8KdlNY%hLM*Cl^*GB=ZyL/ncM6!yVeWk<J\YeXNIRBechJ+/5R&8kp?#
n8<GeF K?G4:cW%Mb9QCEyD^#QWibKQwABlGIWX\=q5\1>+*1e511H$bycBEjnpH/FSVPPy#HMd\EQuw%ihFRn1
Ibiu@F P&jGjpbwVpRMkJP#F*HQ#1NtFiNK/D*!mVPkL&hwtu<a$Q\kFyiPSR^mRhJQL&PRnc+*pe@Z/MZH*Ikn
RDV6hp n?8^Nd$qN!lXDBdS+me?*LIa<kya<:tW!VP%#t<5@twH+pLHNaCkQ4/M#$+m>mH*i=P5Mq^ElnPiq+dC
t5lc:< uEkHnmb+mqhC+5ZLkQ$%haw&Rj8%Fu5^\\@LW:Pw46$yLyT6h?ZjZIpjSIh@XuhNilaJH/hk5bIpd>F9
uQZ=8E dS?9:dL?$F6Vyh/MB/jV9qq!\uE$LNVWZ%4X^^uBD+&*\\St#uHR!e>QQp&hhtb@EWn<5ZN9InJi8&1l
VmK@y? kXJ*4LmpM#EKKeNu6XbkyRmp<Fw<:KPu@PD6j6?6EW>VEN4KBPmG!hqS&au:?EA@HDX!HY>K:n9Yp#%%
tZqX=u ymATbC\<G&qNMA*4Z%X$GcShSZynmCLGt*:Ge:=IiI<5e*hm%=BkblY:i94XD@nyl@64d1jDFb6#5nZB
%c==RT Pq^V1TXRMXIw1dLAWmZN/+<InX^a1D@*8ZjmtWIeQtXdXd@m5N4!uZ<e\E>61WQ5:L?X1L#=6j:S@Iy#
&WWa#A Q99P:Ne16p*lZ8#>A@ZID:b>jcFQDibD+GD*iZMRm#>j<>i>T:6tI9&5Zde4CQqD/WSIG@qd*8e@%wSQ
k!XNaN kML&<X@4F:iQN?FQkK>KWdb9^8!w9*Hc<EJaHBRZQhb:EBR*9GH8^88F/p>WI5+XV:aylc:G^ln<tZHN
p!kql+ >hm\<u/G:6eIFLij%j?HFw#j&+>>9q1$jAJI@91bMMZ6qQQM?Kq>KuCE?RV+pwj?WYZ^LNiC$c\tHZ5=
aLk^+B L*+<T&Fei#NTeLIWBTPK9VRuVGKPE$bPG9u#n@RQ1j86<&6=*LNyiR4T4DbT6JqcIKd#4@4$au!\A@u*
+DD4tC ?c+*A?pNt\4+eKwDIlI#:=iJMT?/yew>+>p%h%44XBW^%Y\JAMA8ACQ4E?CjYmD\NJP%4t9hFHP5+G/n
MauYSK aKWDikLW^NmabmLd\yNZp49H:btyWVe+IaIu9%?Mm*tk:?E*j#S@8+@@ehy4LFd4hbG#Jdtl5aBGPLwN
1Tw1CC 9^yCh*=JK*lAAe>=DYYb=+GMHP@Nl+^>*QPK1cdKX/B5F>Yt8tc#uRq=F?5JI5S*p:SVZ*I?ZYP+A#hP
QJZRHp JlC6bZm6b/:#aZB$!bXVh+BYhcTnM$u5T@dS<%We/+^$W#=u6S6ccXQLRWF/H&D#R+K9$DW$i/PmB:Ie
9Y+N^y G^hjY>@*y<*#Lc!<!@CE1m<4qw^nLW>B:ieP!69Qh=VCCcdc*ntQ1b>uY4619c=#9FG:w/pZ9!X9mnjI
kH8t+= VHenkm\8u5hQYK%p<Gc5MYnj9>=&eIljnTMRHadZLcmVLn6iNDGLSX/B5>!J^F:^T=pqTwWhjL?B+R58
#\\GI$ pXj>c+@^1D%ZAh*%6yw!w>R#@F!?ce/?@jM6tFMCu!Y6YJ9\YJDXSFIX=mHhyR99694>aD4qD^w!#\>1
P%:GdS DdNu4/5\n@5JatW$6q@X6JlC9iMJMm%T^*&cyj1ky\?9<Y9@>TwuI4EEAte:9=B/J//bPeq9R^AG<@X/
6jJ>RB DXPF6Z:G^E<Q%NZ:FJS88wwPCt6H1<>k$i=9R9XWjhV8=C#eS5Y9VRh!4E%N>\idw+<H9G>cJJWTI##J
5Zm6$M R\em$CZHS&hYQtK/:inKM?n@8Dt!/^!a##w%cY+KXlDH$nI&*aG5YXBuQJd9TiVuSkl>H>P?<<eC=NQ8
@R?w>L E!Dh?bqQi@@N@@/uI^$tS#@bZP9ZXB:h/\*WPeT8n<Y&DS+Fk$ZS65jG>FK8lB>#Dn5^6I??yW>iVE+8
:wK^P: d>?$GuTpFV!#BJ<18\?dP&8:M*?ck/:+XFG+eq^lZ&ZF<DwLNWqj9iuGlCVYWb+=&Kn>J$5Vad5+kbM>
en9V$J $h**1qp@%@Q9/t<KGyBuPuZ8D^aWF9tJK4*icBajHjqkX6DIMmV<XEM8+K1+QbiJ9S<W1Lw<cPCZQ6ZQ
\yA1>w e8TN?c/mT*1@8Al!@DFahu958Q4F/jT1V&AZ?u*@E?Dti<T9caQYimdplEn*^9IlS8Xp#dJycc<ySFdp
*mqj1C y/D:+/@FwpL1\SMkmiLm@1QYA%pIW?ZdD*NXN9cQ98h*uV<@5k#?XE$ydLmjLFLy/hVhGdXVQhXQGm^/
EQyYcQ LLEZj/N\wl@Vi*J=j+:Wme^n8%nkGQLH5i&j/w:tL1wYRa8@n6*Tjbwuj\LEEn+B5J<A5@9$H/<KZ!M4
CGeN$W uL\*8hm=@X!uh#jdSC@X8Tjy^Qi#b1Rw/X&L>4hKnd>it8*>ENIV+Ne1/?nZDQc9jMY5u@d4q4%9wywP
m+VPb+ Q%d<nL*FQ9+W5<m9wN!JDPe?@G8Ji/e^>Z/G1PA6pVcS!5hFkW?*&NNX**Z9LkiQP:e/y^iJCkXp*<X5
QHJ5== @W\+ii5?8@XV#jqykjuH+A?Bl%>:@q>:RjPu=h@/tQ=S$iX9lm5&N1:@4#VQ@>uTQHu@?@Saj^cRC%Z@
4h!6qI weecunyEk*KF5lhEtn**q?w>CjJCjTNa\dRhmKIX@tVAkdG/Qk4E&8wHXnIwp4yPWa=KPjanJdDiW6b<
mTl/YE R!6ZyydIW:V#aFd$BMXG%XpyiZWTMZ&ePVuXcw4I9NE/t9=EpYLtcPQWLVXXEVHY+@yGuANqlGR>M=!G
hh*bZ& QQl?>cG9a4ctkSCaKjkLEL&1X*^h!6P5W:KKX6mmj1&Rp%DD=C4m$%9?<%Im5kXpMqCaIP*aSqIG%Tpb
PtV>?W q/uDmXubHi$VIAPp^&aMT+eDlmyawq1\aY>RYCAW^Ah8++bGNa=In1W4@<<n/kP9yk#8Qwl?HuWSpWjl
8^/+GE c4d8XiNpIDNP4+jRX<iA9dyLMR5Ce%Xm$T*6kBeJXq^>QVk>q+EZ>\dB\L#$VRImCt+Rqt1RM1<qZa&w
H&*VNq ejtJeRIuk+?qS4B<u58^lnK/qJ\6?t/N^VViD>YDX1>>*E1N5i6mpGqF/Gm:Dl/udZMR8PRamy&lBN#i
JBq<5D !dk##=Sh8$Ejc&V6YmCKeZi$5&up>$nL*mD8#CIG>k4d9HpbA1SXt^9NdKGS6k1IWJ^?Hi?W+YZbc?$J
yA8&FG ED>\:A8Iu$6948t5ASZVlTF1pKXHG4!1MaR>Puh++/L@Yu%TCcBp*DcS1M4Cy@jK:Ym4X<?dB1wnRJA=
HyZq&1 EGuhM5mt?aPeHAIb9?SKJw+DRp:RAY&VeKZYVIMnNM=u6pH/GN$EAn>/VN91*jn1>PNSlHLClNy9F<Nk
uT:+EE EA^c6MX4bWW5pFHZBX1G\Wk$Z!XLmGWi:CcP%Pnb%Me@K%L:&YLtXayi6cN55q5BDRhcy^S^+#MEAlXN
#!b4iN $@C@Hbh?\FN<V^8PK:BpaJ?VIPASBy6c8H<*up$#l<!IeqSKhauWDat6=pCJ%b*EAcP=?+4dL*GnVGK5
*ql/Pm D4j8#u^LG#Jae&+%B*^VShajy6aDuVmytNm=88IG@*Cm1%8E^9uAET6L59W+=*yiChD!ld@kiQ:XbTSV
G^DPCN VPBaMDbKdNaK4SQD9AM?%p<+mFGBh!MX&<IP&55d9C*1p+<kRY1a##4$VTHS>AiR:Edn<@Gn$cWXH>q^
ap4V!I tKitXcX=#AdWM%8TZZHmcn\X^XbceB5JSinCDee6c:nXJJ&#9I%=I8e:cjQXeDb*k8&hC/t/R*#Y>eM1
aG+#Xk *$@KPRWJ1udwH<YLGI^:X*Z%MlpRGIbdZy!#WIlS#I\PtJ^9R$6+ad:!>&h?e%kbSqPT*QQb5DQP5j%A
w1!mBZ mKQ=B$pmiN:B&@ylhd9eX@GG:4+=j6RBk8nCRS^t*jL+5#S=FITb6qHXaJ@wBBjkNMi^*Y&h^Q1YWpmY
n?XpBa hnE?ByK?b%Lt#I<$dp?MI*VAe%mHS8RNV?iRR/nQ65wJl=BnGS!n=Y?k#niFq%i8RZXNt^F&BS?!==Hi
!j$Gk# QeCj5:Bi&hay6QNqd16#cpJ!lka^RhZkDt*k&#mdk8k>4VKVm6*I9GdnB?W6$5Z:CGHmy<uWDR:!<4T4
i1^MG< !q5HDSdEy=XF&kin+cG%G/tu6LA*F<EA>9X#LKG!LudY%t5L45pI*E51Sacu4nXmlZ/tK4^pYuReFkqP
k!1^wm 4q/9/X#N$@iTPbwMqqW+KylJb$c4JW5:qRHc5SXCFR*!plPpp1=/$by86b^uI:RDLjbuZ/cSDD?l4M&y
6t69MC \VQ16j5q9/QBChVBWJ&!SiB!81^bFDK^y<NRp+&BYBGQwlV!WGY$LyAKWDSDDF&=ACcmnHVWLkYn6^JB
EXlp%E kVpMBGDej?^TP1TpKC>PWL/B\Y9SABcMjjlwXj<8\yGbZ%+\@hW8bnTKAiPk?hSHI+J*mmM$Eq:FPDTR
/Q8mt4 QtbwEbyYNLWPZhBPRBX\C&J+R=hCwLBSSueN1hXiL$WPY4&!p::%5NkaJ+y9wYaE!SEDaJ$N%YRyQWHI
F&#c9W %#b:Sh+5&$+?aphXj4kE4pRc@M:jRRE8ElaQwnl?By*!LblwBty!\SWCYP8*m6EV>Cp!kp@d^HKyZ<YM
TZ*WV! P6jXc$<DpGyB:C!4dVN*C=w8DTH!ZQtJqtdbWSF%$V?j6CX\uC%88=9eZ:?YlTiDYy$@<=^+m=?J9$DI
p<8H*@ 8GujZW6DJ4dRnKN?YcN>!&K/M9ih$nFblN?<@q6e6SpmjLDqePyhYeKn4<^qG66A*^y8Eei&Ae8SkKdE
AWp$kl $k>VnP5p%pcSWWl+Bw\9dTuhRMM^#^T&lI1>VqWT$9F?i?/hTL=MMKA4tNacFBa4tyeLp8@pQdL\n1@N
P?8m5\ 4I5GNGNIk$@nTmQPGS=6h$+:D<M!RSMnR*B>%DcpLGJHDThlZF9!/ee#G=KK\6iLm&=SH$>\!G\8EPM5
nZA4?+ ykSSZNibY!Lp$<5p<Ty+TK5/EVthYa/YinCHRadj<>Sbd95GW4@Yee44=V15#DNN\peuK>M%RGIQB*MS
G4?*4Q n%Yq%uJeqBBY6%!5d$A+MJ^9njGW8%6>b&1j%W4=<JX$V6XYlCtKw#8jp//knMqu!kcSd!5=*YG&5Z*&
9Xa^N+ XT<a4k6Y*?VHKT+cF>H*!D6B^dyYu!IEX>lH4NV#EjD/SGq9q\lwTnI6N>F$9KT@p#BCBlL//IdjcNJn
NVJ=9a qJL%Xd=yCPGJDy!6NRp1T*?plAI4=kpS$E=?V#J/H&E?Aj%t@1a#X>m*5Pu$^%e:XaX>THnSDAkiTRtM
-AG\H8 000bee4fa5300110333 Page 307 of binaries1.zip
<8QVKB @DDYX5yW!/HA%n^KRYBy6kQ^G>>cNRXY#\MdKRyShRMVc>?qt@^Cp>FM+\CZ@MB1*pI#uWtR>9qlwdGZ
Jc>PG8 14mQLy^bGE\:JPAaeRyW@Y6+F*pb^:=tL&^GJJ=AbFcXFF!GLCq@KNBelPEJX+#%#VPGDl=REd#RWe^*
=MNw=E A1^F\=q=pNjARuMA14Y9D$\lJ$8#ltIRwHGMtMeikA=&A#etS&d9A!y9\whwIk4ql9t5JEV9iqq4WSLu
:wMJTQ <:ZbV^mkC$S:DwwV#JI4!DuyBw4uDA^K#\:LSPlDjW&Mw^8lIdbD<@mlSSY=4XmD<>ZLaT/CB?TS1Vcd
*L/S4A A!1=FQtmA\y=+pRlAYGa\W$aqka?eV!t?aFR8@JRkHKEanm@AMGLT\SL$5V!C/^R/8C:$%jiy+w?k9Gl
WT5B9M R:E!5QttR=Jlp<Ll!PJek#QeqtdlbN4BppkjyTb+S&V#SpV\#Ym9V>WncMYL!^lNwl>#LjL4SdVNN<j<
^$*INe YBynbAEtl<t<le$Fbt@\m&In+p4DLE#mbTE:Vll#+&yi\R!bHG:BF1IVK^=:DZMnw^Aw^^HQDhCZtZ:k
8yDm1? /w<8!BPWpLR^DRC6TR5*ADiSV9lMI>KdwQ#N?k\l<6Zn+VH85#i$D^Z\SDKdyHWl$a#a$e!5A#X4>:X=
mTDCS* C8eB1NwlMimp^d/YX/\5NeqqLPq5NENmp49e$/@#DLJJLau>R=MDLwYwkb\tq#%I<Dn5?%JE\@/G>QC9
a%m8=S knnhTpQ=yA*ekpT=KRt+8@4mWEy6BAY#n*^!qH4iAe*y!%m=S9JQ#wba\A5k!lN:6%NwmR$1EYYX+ml>
*WN4W= BKNkFJj5KReM?&SVFen>IYWV!Kqa@FGwbQu/\A<4K8SR#!Q:1WPl+u@1mM8/YWWHRJuq:FT1uh/9ZTIB
nCCXaJ lX@QAe\aHe/<&ekVwX=Xt9i=KeK+XZ%^5m!Np?DLCN8%CaW4&mhP4?P56kE*q41+Xy/Ca4yFGHd=TQWY
<QPA/$ ^^kVVAtn\lE9G#pKN:!SjDLXkQZVI4Np8KRk>>TepiNMDJCNiYbqETm5=dRRLDlKkqwacIcYC:Rp8Fn^
PuQ/uS w!a\:<&$wKm&MIhM6cRCa\q9qb/uShj$Wc/MG54pH8lyLC+kAIKKk=j^i=PDKdpBWmRpwh$W%JGS\bT8
D<aZ?V eLamECt+B$EIX=+EAV=lb8>M4=am1LkIK$5nT#X%ZL#<R^S44&F!YTHja!kcYbTdH+jt\L+LRP&qGc\m
MVLytJ \*nNSqGaIViTipPCn:bWew&KX*9BdjEpK5pbVe$lACemSJ$c$T<bLIpYJHEZ=u\jhECCYN@KQbL5h<HH
mu5u9# NaRY+n\%RDdDd&MFJ9J/cNMKPA/TK$<A!*c!FQ=EdiP@uV@*nwMhEyN$aHhZ#/wi\aRWcnMi5SAjC:A^
jiBuV@ CZmttAZwu<W\@\<X9@>dBMRjJ@yL8MNj+!V?=bnAj^dn@Bj!1Nqb@=^H@hjt9pA=GMV??+#y*+l:@1*1
a+w>Nn @k6CFH<n:9pd>DQ%KpC@Ejj<Db4q8Y8D@m$$>\9R#+h85j<y>wcN@Z?P9jqdP9h@^N=\@md&=l>%Q@>t
E=cQ$c XGDl?QXA@/@I:Xd/9#T*P!&$8>V8ml*t91?WDHEEiA<%GTCPq\juqR6FG\:@?tibj#+atGC<R\pEja@$
^6njlm AVJC6$\!l5VwuTKQ=FcZIn8#+/aRTaZm%S+!R*jp#chKCJkJ%pBWWY^S?VncQi+iiuJL5w1+&Xea!GTB
D*D>E$ q!I55heaDe\RdeAlyhuYtYcFCF<l!IGeTL=iwE\Dm?IMT:WmuSwbk&^DJj55MRyC6T$cm^T#HlBD%R&k
wEep<d SSdeMHaK##Jq<5CDRK>tkmEtw/cEYhGk1ek%!hHRIR>FD=p+Jw5EWVkI#caa?yMintikNkkD15q$BmPw
IPEPXq iEnJwZkVlJAHh&/kDPamnALn^BjuwMaS!eeSCP+NnR^4KGuPw*I>Q:R=pbw$/DSVX5tL9wdF4NnLNF?S
?9FdwD EkVpDHepY/nduljRWWXSRSbNlk1TX%uEVMteTFq\Fhb6?k4P9PuBmNTwnLLK+Aduy*dE9uH^YmLYXKX$
EwmZL< mVpRI!nq\<B%$4ne5mEk8^81dm1uTyeDKFbW!Wu:&bIlTd/NXF/hREb+WyNTVLXu?p:JbMI@D%w:6JcQ
%V$ZCC n:LT^neuTyLQRRuHaW%=Z48udpAw+cJ=a\kD$huuEGRZ\NBYd/y:6cY/e^Le!8dGYd8%CIWddFwm=RBj
^We%e6 mA@M/e95yIh@PQEek\ecXS=@ec86+=KSFl!CJ@NG=LhDJVbFFq=c\<P=Dpn6^XRiVhJDt$S96IquTZJa
$X5=@G 9hbq1%$@R*l5&lKj?>4W#TNGbHAwtn#6<A+551&nac1^N<AhKcaH$BT!4aQi8@cYi4m6@B5CDIRQqMl+
$ccyP? F%?L/XB=6<\TktHR?Tj5kdnyHZe:FDu?PwtXjP&$Glpt1K*Kc=n&qD:e>?Y&>^ZNdn?Vmk&qtG1cBYCp
Z@pDRF C#bbidTb*TAFe*eS^9##9MGY:+RKipJ!HwqCaci+k!<EChF*HlCac=yF:pm#TP58EHPCmj1e!Ap&<b\C
YJ*#al wa1d^bQQiuJC+cC&FD>?aHYS<C6tA@dbdpMIS*65CAuJ>p8X?@5&1@8F$5D=Fa?q%jG<G\h4JLPHnM1a
XHA$Tc Ld/DK/uk&P<Z#=Bm6anjc8ik@DE?kl:5cGKwCmj$Tlp!%\+9HG!EZtnNL^EqHRb<Ta?cJHcyILA?Bjd?
Gj*N$b De<M+PPa4!A?nKAKd>FdTkmZD@L^yT4WKmawPJ5&VtE\HMBhA>^&NIiWYXk%:u/VH4/BiuS@D%ZHcl^C
+^=cE+ Kp1V%lpn?bk?+9klw?b$5MAhKnTKQe4<CZYlZC5=*=\ly5a#k5<a@PbmZW%Wy1H4&*!R$a1E!IIy>lBw
$j=l8n QJY1W:kanB=cPL1:BpGVG>:eH5Dd?Z4k8?NL5y1t#SI@1?t\\>*/Tbh>@MM4>\mYX^H>WPZc1W8GCDL?
\GNGK< JLNt=^B/&%@aqGMu$1/Fdd6L^1n!j!4kj^h$G@?LFKh!lyamalmNYFp6YqZ/dKlnmp%6eqK<Dk1N\#9V
ZC#9Ym 6R=I6J<Ga>#lhwX<&&YYn+G!hc65N1lm/RBcT$Bi8:D5&yy$tLShZEtZ1^^F!89=9l#et/u4BP&:RMhZ
:dS=Jj bMEZl#C$&mNBCtFZ\9FdGB@*PIw9$bIEt4cR6?5e@K1S/ESHiNFL*=L+#cuD5FW4+e\tanAm$ML:\?XS
dNN^+T TA1B@Zaq>e</$j>9p^EC@dMR>d?!XAL>b1uE>jKqE8h9q$459\tb@158$a8YDB#@Hy##9/++&Nu?=^WH
JwDPHZ ?#?8PEB59%6^eQ&tt5\@l6@?j%/M@@%inDl$99<H9SnZHhR\9^@9wQ>^9D<:#9>Ze/D?YcH1Z^nEIM+@
iWV+FV D&IR^:>YN\4E?q@1SwH?ymMGa9@6GQ?NI6djJMj?5Z#jM^8c*!lm@SuN\9yMW5X9FLF?e?*ueqF?w+n%
AaKYVi G#V4M%p$HP\9RHP\Q=QR\eH^EnVLe!*ujAGcubQ#GVVZT>D5#&VJ@WaS/#hwqtiTTZ/nmQXuNB9*M#qZ
edhSA% uC@lGl9uM^6a#yh\na*>PjSL8QcHRND9$T@lGm9*e?mZeI&X+^t&eL/Ec<@@nHJ!@u9\q:CNm@t=J\:/
:<P/BF 6>De@\/c/!X5i$=*D5VF<t?lZ<I&h1=uSnnZT>nG#94e6hu@LjSL&MdP<e#<\MZ=wnu=th<DL1=@1?W9
buuti/ t6tau$N#@#6w$I6tN1=ujp*?8Rn8!%eM*M#ej%w^eDPDZ445=&dt?8&TAQSdAdc@/a@?+!@W9=##^<d/
^+$8F/ F/$#>q<5?$MX:kW=j@>eyFj^Q@9%::5A#n>E%H:h*^<&&:@9Ann@eSjA@y6h\D?Z:@*hij??8&D?#@Q?
$c/1iY dWQ^^*u@%u*@=d\e9\tTa8F<RbAWXK<lwAiPEShSuBRmLlMQnkRLE9!KY^:LuD5WymDWa>PJpRAG&I5c
1Ninpt mTVMnm<^IA#YQKdLubRbYZ*N#liwGlI^%B5HTX@CAaXI#t#BATQIVnA5Zm%WQYdBmBi%GTSm<^1TP%@w
1pbbQV BH&p\\^jHRWV\R$<b?MXNX/+hHC^J=aDZNCcai!t+9=4Fu?J@DuH$CplI6^8TlYylp<8dB?YLCA<jT4D
Da^Q<= /AitB^\9&<8hGRpRKF^qkK<@\YF%BWQA:wYZM$=@L1??Y5w8yeH/LAdNI4tpcL1EEEIcpN#4yw94+Pa@
Y6ykLq HV8qTE#&BeldX*ukb5u1*QkRq^m4!HtE&Q@H45Kb6&>!/$w4EH6<h^TJqe!\+4XKS1q@61I$PTtte/*t
eZ>ZJM V*X<b61yBkbjqjB4+mt<L:HpVEajeIPq+EHjKa=HYm8FcZbiV#YASSL<+Mk6*teQIkp%\EAe>:ZDRNmC
41YdHb FEENB\hqa#RbA5c+tm14BYpm<*CWCcCRLM\&EGyWSVFkimYZmh95nwpRkQDZS6lAi5FmWmqd>PV1Zn@B
tMGhDw Rl+wSuaL=5nV*8b#MKpy1+6mtD8HVyb4=Wie+CQcC^SkVyhNT1q>^K5A6161i*4yCpFVGwEKm&KMaCYe
&B<Y6y 1V$kmckkVuBFF54PwD!Mpqkn8$Y9KJh^wB5GWqTj^<dM6E4wDk@#dNE4JJhmp\&qt>B?HDYZYJNX%RpG
>XM@&b JyVS8hS#WdZd$TlG>T*B#%KBTDdBK&1*/DHa4SP!YmnVnblCwy\L@Q:e!@M8*ylDGHjLKDNpa!IGWZtI
j!c6:B ^tkcTXD#VuySmcdci8/EJN4Sl1/wSC5>5mJET$t>#11mLH6b/p8aRX6cVS:<%V9DdKTIXK$=a=M$>ceE
KPeI?Z ZILBeNb*C^w8WhFajdeQ^kcncSSSKH&*+/R<#a=<AXlN*aI=Kh4Z\SyJpBD$MyKD11Pi:+P\&eLEb<in
+?R8kZ uhGDwqZFWZlA%wpaFw#%%pR^QNLwBWF+6464M>^SBC9>8D?J6=Zb%>HhRHG9euimJ>R!Tw+j<I%jIe!J
p4T/\K SPZ^XILGWVkZ<Y*YLHY\9L8$9/6lT$c&XV4m:1Y@p6?J#LQF\hB:SB4P%Q\?/#$<wEYkMGlE:XGMcS^^
hBMh+# >l1Kw\$dXu^RPcyV@Hw4?1AAEl?nJe6Ft<mWYR4#6WcYcJ6%NN?*9Cy4k/<5V>/nF6y!iD^:*Mpud#q=
8FjbK: QBKPt*iRwcSMhe>$@IL\*:?=EQ%yV:F1a%9h^>1aNq?^*ue#5JnYRtL6u9Hw*@F/G!KkY$Mw1I:#6l\%
:Xb4l6 w>lWCnb1qmiR&GKe=q+1ZGk?jc1RAAK?BnRM>aTQTS1K!ketLnTQqtFYG41?\liI<GXXYKQLN9$1DlIl
tLK/CG >aT/#maWMiJI4*yyJ\9hGNk6Vcb4M$Jeq+!I1ySIF&w8l=4J+aAVMM49Xty=%=P6HLbBM!wG<Mew1#Q1
dhHG8% NhVtAHZ=w:i#i&LJ4itbn<eqbqlpFtBdp*FPCyGWHAbldy8I^:A\jGL@Jk&i^a54Ik&a\mMHY1$dWN9V
:W8<FX IC4#dc:AaLQXcl:?MPWXeT4At1FCLQZab^C4nBu9dw9L#up4&DjmAZ5yGG9&YmndbS>S!JeDckCKL>*=
\D:D+a WGlICq:+CthimE\WAja1mGN5d16+cka@kH9pVYnHF@?A?LB>I=GIcD*n?45FG/W:a?jD!@LcSF5\p86c
8KE<!E K/TPdQ#=EcjETDhX8NSq466BV5RY*JmnNHcWt#W@?P@Eepj>%CnCkT4ha\$Cbl/6FEbFVFHCn9:b&jRX
qHBRJL lY>+eQ^dES^Re?tVLB:qM^m$acIim%e+HSjITEWbqjqINW\KVKwb:J$<FWkhDtH\Xe*6FJKG&yJiPSbK
8PW=Ch LiTQZ4d*G=6$=IJVpdEHdYW/y>5hhnid%9hLMYku\4*!F!mJ*TKbk&:NSh%$RWymbmq8M5G*i564V455
98lFR: &SHpn/W#L%b<4F\wqlSA6I8A:B?eDl$ABVQ$/qwW!h1KJZNiT%88y%p#BFiYq\=CXJ$\SLtW^4q^$CS9
-ANSHE 00006532fcc00110333 Page 308 of binaries1.zip
k8A@Nq ?5=S4?H8cPA\V69\SkJw^cFiKmylAmbeF^1<M4aWQQCqlI&/klPVcAW1DiiL44::MTuK\Cm!iRtWbZyn
WEVMD5 it>@Yt$8K9:H#M5FV9X$R!9LHA@R%$?#ih<VpBin:DZp>6BZwE/y<et9NNSPMcY6hwV!TYXB:QR<c5eF
W^+TT* Tqn%eW4%*Qdhl=8jXbeHKlabe<uEWQK59K?X+MS:t4k=*1:!4*c/tJc1N$m>I?6Z6=kN=X1kIYFN$>Hy
B=XuY? G8lb$l@tipYu$>cX?pybkX9SKAcZpc?&DlZZ/F\k%lAtt!KIH+Wh=t*B6E8:4H/kLARZe>SdaW/5^wG^
uVSM:q 5GX%Dj<IWj9NJZ##8@WqqT<IY#u4JTncPI8%XTEwcY:B:Y/PP*tSinuNQBMn89nLl*ab!1I:<1X9RDRN
%5?Tt$ WRld4Yj=JjJyi:JjQ/y5i^hB:kqp%Z4$B:6eW<&^CT%6Wiia6T?4yq=mM*FCc5?>m/+#:SKlccXPYCHu
ua4k#I Ab<ZpAaVW=>lkCLcM:H=VqD*6y\BbZ@n5MWd1*aNmyy%pQbY?Y+D$:dR=t6<9XTDL=MmhWGyj>H^I:ln
TacR/5 !YpScF::MSmNVa\KjSiBA/*mKAyhp/P56qh^WuJDt$/Z&HX:+E8Ad56<J*W%?ELJ4hmaYqSRwdcdb5pJ
FDa$$k T@WMi#hX1diecqZ<A>i/RkZyRGN9?wHi9t6F6W6$*>VY4Py4PjeRCK?eGD^n!%N6eSlt8$WQHZi\a:Z#
TbE@*e EDJm?#pGMkRq8DCX6i<DmT*NYiln&:wInkeWum99@AFtmEN*:Q6cy#A!VqCMCu%BHIBJQJcSW?Gi9C\N
WelXeb %Mw>c&hVLp&/heTSAq&Ti&h+l\J^WW=6a&Xnt*C*llFJq4Cc6iN&&@w11SG\jJdki6YXnaCA@Lhc>mPY
inHkQc S<MH4daVqq&*PK>$JYj<LmdD49\QHuyJG6jC!A8:CHBnFV8LkyFP8A\9!+y=FcwTSBi:&*una5N*Sd14
$MiA+j 5$CWwK$JwVple*QRpqMyKa>Vup6l<u!cpN6Si%XSelX1yn/VtAQWcqiDj&6HbqCu\JNht:984LZ:N/j5
HqAc>G qeGAmecNCt86N=<lY>5%wbE*W=E=C+Yq9eF/#I%CGCIKyI<HhtWZdi%L>8wXN*<\j^t@L&E/KZyVn^Aq
ZZLJtP JC#$&i6CR$Vupa<1GMamVY?aiGM>CtMnE9nJ?k4^%H<cGN4J+L</Wq+/*w=$Tq18IA@c*QleRjyX>B$b
wNNDSy k@<Y:K5KJw6Ptq^Rd:!mLWG/^NBN$E4LkeqMJHCt#?M&\PT&T*8&lA<TMj5#qWtFke5QE$lyID&Jecmm
=W45q9 9Jp^^NhKj+R+kCIIHE$R+yQCtj!Q1q4mHjF><J/jRbBWjdW\?hLK+*c&q1TeA@Zt=P>&VabP9\mCmVAD
k*Zd<6 K@WlIXPBKCW\MeeDbRN^EN4m^^??Aa5:wIiKa$JutAHcw<9kR>9hW%?:dN8*+j1/bap@I&hdSZ$6CL$w
Xk$LX$ 8Hk>hY=VhD4DlcmFk5TCXlGChumJjDC$HWtim?IJNBJCFQ*=aMaAX\KyeQ/F$#SVj/\Bcl>e9hmH5@<Y
=$+^*: Mp+GD9p#nIn1##BatJ$HYDJ@B6JF&JJnSuDkn/pC^F+b8F=&chFcPNPFIqwVDeWl*m>dCPid4MaemGH9
C:=dKl ET?#=S$mPXA:pTJpJbBBuNIjEK!upaNDd$1H\TPlWWSMIiBqN&NENcjS>C1e*PtlZ!qTwRT=wyqy&#Nw
:@&J4t 9XK<JLI>%1=FGbGdSWd=8S%T1B:*hX=WASpJJ>@Y!+tqql*<k%RXQGLMF4uC9kDyMI=DEp+jPJXmF5Kq
*>K1^1 J&=Nu#H#jk/pcC1qEL#aN>S^B!i1jHQ1ASYVEHmVh\lB=ZBPdnP$Vy<yp<k8^9kEMjkqdCkeXmt6hk<1
$8=K/G ZSFH5MSQ^/1QNumtth*k*pCMhJBCt*CGQu+V+@5CL@lXS9YdbG!>LKtt$$l?hQdd&FbST%JSy+W51=qq
HX?SqI SN&LmPRKPmEwBhK*eX>QKQe%+I6dK1c1B#qnNuXwbRa^FX1N!hQQh%q##MT6iyNawuMqB&HYC\Qn$Zt<
pCTt^A dFZAtNlu&eT6w9p=BLYXcZ1+uASktFyk$KSBNi@baElhKSqV^bCeLD^<STLNEmnN8kSlDWdC1aapaJK=
cKenQ+ IMWDJNCCD!?m^ba$aH6AR?yX=Aw<\@GSB9$<p/#LDEbIMPC&$5w<R^9BXK%SX\CwQJ8RlQLkIL!kL5Ek
XJtL$/ m!pnYNtpcCeT<t#kXRQMbR+d:cG@Fbbp>5Se6wtL1TXH@lG#HH&BwCKR?1iCuSQN^S^\&B+thtWK+lG1
>Bj$HM V\%uE+Pl=>W#IWZ@4CD!4^uG@\eH&L>wL9?NG5tj6=ye#&*/j/NG<tj$5\dw*/mS@BuN!j&Mai+*cmT@
&8^X@$ &TR@w\AD?w$c!Y@R#^We?+$a!Y@R#^We?+$a!b@SdM<b@Z<nS9IdNN6#><*^AnR4/LtYe:+E@X\M%D?K
W/!Z5% pd!+$A@H*\4>eDC#@4*RD#9L@&KqH?+@KQ5@&RIEqqBA=FmI$IHClw4NJy!E!KGmSp1kjHWG:El^a/Zt
?/bZic ZVh?wqklAQJ*<tR=1pSyW?WYp$a>yqSbM^Z8@AXd4p^=e=YY*c>9BdIXVRZlKLCmJQKXLXXdVVt#FIyX
eB!Zne 4hS+C6R4NM4X4hXc>>\/*qS4Y5!Ik+PQt>h4&/1*tVc8&#j4&tu\Fm!e84j4&&8$:Z*><d:L\EGVq#$c
N=\YbG Cn^&&%G#*a!LMGdI^EtL4!AFwc9Q%Ft4jh?h@?PWlR5%\mh#5cI=K%j6D4Mt>Q^c!+bX@5JF&/a%a#ee
+/aHy? D+cI6=&dDl=1+=QaWXu4?<SL<8beYbPHd\AE:+w$TIcZdX4ZQ^Wt6H!?EG>D5X5MGc<<>@!l*/\SDd@*
CWwFFp %ej==<iW^et#l*e8d^RY9:ZPhE:Bk*+KK6JbQAyP!dkehT6cc$AKVaZ#kk54quHBCE?N$MCJKJ+RIwlM
FH?F:L \&EnmT4S<1PIV55\aI4FbkLCCk=ba$iwI&Y6Wj4mdF^C?&EMAeG9Ed:k^A+=#DpVD1Qi/Ih^Yewp+SIj
<yMVld $$KV=m5q&ltIX&aY=+&WaFVSne+<qkGqa?6n!Mhl?L^S1&ieG^nGLERnTEcXM+<*JqVIh?kX$L+e9bbB
/^JYJk y/hkG&iuw%@1hdbTwy15@jJhTN==ualcPcGDSpIS@jFeTGmPAyFh#6+YI&E/5S>McwVhqpFG&qZ8Xb=c
4aHaIG jRedcFKbk%6lcl+PuZLc&chAbV/^u$NKjlbVTXYb:ibY44j?%yF\WXLMW%u8K6KiYjMG$Xyn88+&kpqh
qWQ?9q ZT>F5=jV>TQYCy8ciIJ1E!tSRG=TK=uJ@DVt8HP@lp!Kc*/V4Z!IQE#Yd1l?WmK@>&hWnl9@FZjV6&>!
%cX+A@ QPAwGEuu@hH>ipDm/N=Tn66y:+%6K#qmq=8Qmb5q8et$+9bWPPYT8:nNDCQ*9tjeyyqN1YNu68MPiIIj
MXjPTd iD+$jdSR?B1R&*p91yJ*JM<aX9my%T^:>ik?a#q9kPFM\J$My:Gm>HlTQaaw^%McM%KjF/t:8u&X<L8w
ZlIKDF 9DytA+<PjqbHt=wdR+CQ4dibh*yP5?*>uV/tdam:FleSwwFnlynRwQ*p&X4TLu4qhi>GR%dM1LLP?8Tu
QSeR!h K^+mMA1uGCd8MSu6&!j61$i#!!RZR9m!+RKNd@D>#t:uYkNVQAj<=q@=E&JY=Ba468bG9\/m!+*wNl:b
44ZncR :4^DDmy!eVcZ&XFhjN6Y?bWkyQD8L8pM<ZTVmJL8:PHC96jK^+$TLNTd/?jp#X6t?dYCZcI!:KQ*mkKq
%:deaJ *nLib8?L5<+FPZ?8EdM$9+?qkP/<\:E!$EZtRJTG^hWpk=InRAwA?5N*%@FDEX<8?qaHR\pXT\b6EXCb
kDL$tj KKbn+p4!\56tcFIMa8SZm<Qh=<k!e%SEESNn\^Wbn9H+XbQE<L8YZ/t9CYmeE<yY8Catc<@JlJ*EHVS:
GkQRtj =C<mQVKFm9QjXl?\ulnqSpim?1*%8u65#>ad8mQ8Q9VlNEF8GTQa:q>i6wbP>TYd8Dpnn:A%iR\TGd9\
W*chWA ^4J<R8kVX!Ba4%5KC+9VFLMEdGVylm9Z=JlI*1&TINZ4Phmbeak*+Y%u6p*yMHlSTS/PWlDKc9LGYeum
NZPIWc qHCR=G&9PE^V&FeMiyNlw^p/\lYTm!j%NY!a6NkwI/qult+LEYBWy\c!ewpdedF8EE!qXt5d^*IuEBJP
=GDkS1 E/hXyWdJWbY\V:BZbcCK&$5N%1j1qK<LTlF5bXKT<eyDuu<A*uQLkBNaE9YBb/J4iT1\9X8YD=9RF@uy
MbuEpD t#pZ94TJ<QDl?18@wkwWn!V=9X>F55Yp%1B\Dny14qKQ*:R!y9ltEHS/9eGq+tCJlDpmhea%ch!MMA59
W$V<D9 DhlDLmSTc4yLnJ^qE6b:>8dFGYQu%>RFNMZ5qi<W4D\XLKaJcbSd$&bdWmP*ZGqJd^pm81Sh=Yt=MR5^
G*#n#I Q8VM*8edF%+?BtKcme#F<>NRdwiXjbELqX\1anCW+$w:LqZ8BGjTLMHZ!5JemyqRe%aI*Rq:S//h4jS6
yicl4b +5DE^:8<Ee?X!=WK?R5FcjHR@c8$$5ee1*Xylh4R!CXqhHY!ZT?D?aGGPB*ID@SB&4Y18mHn:qjJ&<:y
%eL9X& YamYYmNm1bQ$+*=%VkMye/8C?c?5#&TT+!9uidq$K1VDTw<y!eS89qdd<mqGjyNi$+Vd4\&D?pCC>TP$
V%+\@L dXtBA8i&*/le!ZA6up1jQtQB4SL%Tkh4#?YLYIy^W91/u4?AY!n@Y8nXlJ+GjJI^#MlN8H^y&$y4buGq
b<j:bT %bdSa19ib%kqi/I<:HyMNZ6=uR6Qi9:$>1>J>W5<Q:\aVPG:&e^+P?pWKB#iZpqkc\?W+ZQdP?#5Xh9I
R6A:1k Q!$@XNH?IuiLl#%11WWX4d%Z8mjcVGEHkScZ6S%dlWca=?KwZJVhBqhV/u5IqRk>d!4?<<\q=iQQ+mZ&
XPkykR ^X<=m%X4d#anFqNk4NFGQE$#X#M:I?Y!uMbe5XGceXF/4?nMl!eZ8jB6GL&9pbRt4Il+<p886dA*>CiZ
MdtqX8 A+R?b$EI\:8ll&y>^V!AtC:I^?Kh^tTN\tDkp&a*Fb*TD1<=cy@qK:w$5Gq>4+=tBX*tG1\&6#Kiy:^8
b6lkZ% YZH<%ZRS:*V=^Nc#cqu@$^I?WwaNR%nN=kQlAn/Vte%/X6*Z+PpXHRW4>HF&LVj^bR/#NEm=6&XN*+Bd
Py&91k c#w^Vub/a=jP=D841^@h:NdZ&:+FZ//Fy>kN<8>%jB9+@quu@N%4l6pP45ajt:4I@k:/mEZNpKL4QpVB
\FnQ<G Dl8E9Zjt5P8/$KGP?k#>h\M:&:w!pbed@IQjkhW:*5:lV1@pl4>L$G#J8khhXi1Njk>B*e&5T4*Y6^&@
K5amqK w!LLZh9=+L#^61Xq+inkB*K8m%:GqHPS?JEiW!F/bX\Pn:*T5b+C&@qQ<*tiRc&nDwHp&<1P^i<K845h
ImbdVq AdX8?t^LdX!Yy:wB>Y/j%qj9*68iEW/&&t@54Z5Qi1:@?N#l99Gn&j9k@aW?54pHEi#Yw=DR^RdXkMiM
LZc$6w @jcni>!XcNPRy\DD*6%H>86Z>lPid:kQHkW?*L!K/jSmpny/1C1<jXZX=FYqhjLAXQu%%YTFN=Qq/Z%K
?Dln4M +:hZ=\ZiXb:u*=<?*SElb#\!lX%?j#@\uaky+dE1:j48&<R>wW@N6/1Ct@68Wcn*NymJ\t=K\!Sm=EhN
@i+9qB q<m*C:thVJ9pHVFh48>A5y<8BZ@!Su^>J%A6C\DR\d+@Q*5:+/J1Q#R@&jQDjt\PBSbk69G#+6MZ+V^A
Z1ZJPQ V\CauA++C9Du6m+A?S9+b9KDA\ZaFBYk1l9ADA>R=GGiuL19&D\F**+<Z@nB6AMJ4kI%Yj1DGSq!58iu
BqdZ@6 @Tkp5!Np4N*nbD<R^ie^%lb\IRJln\:iqa#5EAh?\j=\EWn8IAZy\A8HWkBni*aK%phiZWpB^Ii>KIFW
-ATapc 000eaf8db8800110333 Page 309 of binaries1.zip
nj<Dl4 SQ8BRkWjc\:HLAbdZaTk&IKIwkESY\BEYdkFkMGm:CLd*#%NyWE#w$I=hCNM=RGaR%ea#/n>AERZ6iT^
nL#^ER VRnM\:A>IYBVM#?uQ6CkwmM+4KIy#5NZB/E=FCHECCA^H<A!5!FjEmI+$pGnZKI^<<NX4S&j>>BQNWAy
NmH@qX YmMwYpQ6jahBNaTPlWY6BpNVpwG?bMFtH5Y\u<SAipAmlWc!@+/nbA>dI+FSp\dyGH6+1Z^kQ<aiy$qi
a/KX%a k\\@LRJ%5a\&ha%^WaI>FRK6&I6X$\>j$+%aM$y\L5=nBIYp<A%H<Ri8El95XAB?6VQ8ciy=dBXKDTLt
Deu%^a qD6RTZJ?/l9SlR+1?CC$pmZY=TnEDDwa1mEA^ScGYRi!Tk6<PkIy:9ZDFSpBmn686V%b#eY!*SRAFWlB
QtbnlR VAA&ZRYi?\aeXR>hHy1e<Th%*NyQ8!N!a$Mm9!j!K&YKcw\9n8bp%hV4W=cWNdtH!y:W4LHdKDm$cAp$
&I\\4= qTa4b&$$M@tdXXY$hqHWVtG$cIc$E^+QCm&W$Ri$qdARVw%*Mhi\!y@P$XJww8uw+%8waqtRcpj8YMM@
mS=L>a ?p6AMb%m^KNTZ/ICuT!yuRSi%dkV^*SAV!iS%KSlXXuCVK<#Kn\BYd6JcuYk+%GbV9jA+tDbYL/^TeNm
m51ay9 V*%D8+LCS^hmWbJDt^Jm9*y+hhuEkVLJ/GTMZ55Cc?SMqmCGQ@$iq/X?k+&FnRWTkM=JIFbEem&C:>lC
Ycha8G GueEbL%tu*bF4ZFu4&HB4RY@9iSG4+qB85mB8HSF8HmkR=^pR@%GHm@D=l!AZGM$l&4PF&iLZ$QE#iLH
!Pt\Q4 WWNHpLDM1#DIMZGN+?iHM<QGM:*D4R!BPQ9l*Pta6SeS:p1KD=&D#*pYQ!GM^DpIG*&Hu^XiGP%ctG&L
/\8i?y <+bE8M1iMPEejWcE@@Ke:S1h<@1RG4&DLiE>Y#$X?$\*+lWm:nRShM$dbGXM9qyeeYXCjk^d%pS#IZbQ
jABCL\ FwMW$86T1tqM5ZwS=ITHX*NkhIybKC:!BM18lMLYMItCt@ZmF<1t5P#1V>jw8M+@JG<5ySnLw%YV!X$W
bKEtZJ yK+VEHLN?da%iPM*%81ZKGi@eTn#T/lW9XJ^FcT=iMJalcuq+p<kR:8GpEbebnD/1PCK5F:d4*mLmaJ^
IZ+V5d Kh&A4ZTP1XTlw8^Kw>#AwH#Lw5LBwYKLLE5@qDM9yMwly8w1ybw:!Zk4!%!K4$cYykaBjw4A9m4^PCP&
CHan%^ aYB5pPy1MTb:8MXl4C:HyEG@yKjtt<<S*I9JX%!YtX^mwubmFH:AQ5ulR=bpq^baHk:4$Lm*y&$TKm8L
1KeR5G 4R&jT5/By%%G+Fw&<wqiV=5e!%eY5tdQRljKnh#Ey1hA6a%np^!#X+6?L9H\Iy=nmmYy94VIZm<E!>&$
>1MiGa RD<Q&!DTKd<ljAw#Y9H&wtJWWV&b&J*n+e$CwkH55IE/bQ>ZAya\C#8dEpM4Mn4bT\PPWRPVkWRES/Ne
wRAB1N 4neH%hLR*Kd\Jt@eSMMyh>6H9e$cDHVyH4S5k96Hn1QwPp#>SW#:GV$Q#=4y<qYTI#?XKac=6k<thb5p
:w8VNc ^dQI1qtEHdiXP!knJFtVl/a88Py@>VV+Y1NH6i?#$QJ4#/uQPjjinbG55T<#lMTYe$VRdeQd4Xpi85P!
%*XH8* DF^#TM!G5<T8\YGb$?Y%&^tb&+/DTK>>AIXnqLeDF4:nIpa/F=^WCyKLBwtGw=w!$l8qHtQu<SJGX%mX
^HJP:@ FCtZJntZd$18ZKy$E!%1KZ18*\#h8E#h*C*h/mGe*B&KKq#h8V^18h#ht*^DK?A>8MI<bJE>ttI:NGI<
H\VA+B 8hLM\kbh5Lt>TN%Y98X+Kei##EF+NXX+>iRjjY9\h5?q4%d^Z8#&1hD^&Pu\=ly@c^V$FwQD5Ku#dSL!
uB+Itq &<Zlh^1uZlbRd:qK*u&:w+JcpY&/jaj>+G6pwXy//59F#6WM/&hpwBSM@VHq^C?X@Lna&l>:*6?D?Y%k
mMh&NG pn?ILaD4!Q?PN&D^?8$hG4ttTEC#\H5QlRAIbwwqqKqW^CAQVY>NwYBNHG+S#^D!n<HN64+inmF*L6he
dc=@JR H$PcKWJ^Iqq\QENV#pQ9$5JATi?YMpL88MQ8epJBid/cJi?de/NV5!K+SmM<wmJ\P5Kd8<M>BmQ8K1JA
m8=NaN cyHjqmN^+1I<q1N\%mPZh4!YD1JVV=^VD$I%nYNAi%Gcu!M%j*lyjw6BPtBaB1+$u*8V=u>yRdq%&Vnt
bjkTjp lw>LWtia$lP=mYJNDEG$QbYyFXDEMGSu5TSFS^Ya5mT?PW*AMH/65d$:$\GlFQ6DYWl<qkw1:8ecL4bZ
SlLJ4n +4DwLEm1Fy4dpRb?1qN+Xw8:>yc9Gq*w8%\1i^PHy^@8^D4>^Rtu5CNutl>F@a:5cWG<y\6=I1^k*j8W
:K?6Qi YY6W4YGtPkE=4VBe:qGCPdEEXVLp6JVMci<M4an+/>\9KFER8CZy>YJJ/CyJ<XDWmDpyZF5yl9&C!>:^
l?ky!y F@PbhSVCe%yb#NhbLpibq^*<ZmTy!&weejMj/wRpKn6a+9kltE<=Hec=E#EVb85!QMEmRhL!!^%+LwlE
6IcwB1 ut?VXS!F//C!WD:uiD+S<MlpyXYRPk=m#NF\#$Ku+Vb<SDhptV4uREhN9V#k\5W5<IRwKIBITXVIXEH?
BMQdd\ wH4EPdjMP9NW:Nk4#^d*eS=C\wpm5b/C*iXB@MbVl1tEE>&aCJe4h/=N5paM#K5kZL8E8V=NhG=eA9^>
VMdcNA Rm9QV#ZAXw9&#9YyAJ/EnA1m9QNiEpNJh9w*YW@Q1985/ukNeB/I/86<+kV<X*k=MHkjE!=Q/:Z#aq9l
YCNeL$ FdVRNqkbSF\CPL$Y!*kI!##N1*BG+&L^G:!%iA^TKmcc1pB*:K9eVZIC<h\WXh!I#jGjM>KkY6R\c#WN
pcl*JG t*Y!qB:T14!LYnQmI11P58Y/+^/1yHn>WuTeX4^DWF*!cHmntl:5M&w9/^\Q5l/kEnI?+/AJNZLLMcej
cNA$I< mKZJFN+4Z&uyQ:Ra5/J^b*$Za1$9W5yR19Y1!PFl?4B<tuM=t<DD<mH6w$C/ZQ*ehB+?j8jpddw*6n\G
LH8C1W ERe*q?TcSC?QYwi*Cqhc6?A>J5bNTQyK#C98Se/EGGLe4aH:ln^htn+X<T9Qc\be++<6I9tQnykQd+q+
G>5FyJ i?MVP9H1?499eait&jKtLwi@e<nZE*c*$\&5!LHZ4d/&J<^Ha<uZDbB9b?nn*1t@%@Cik!=E%T4W#S4p
c<*w19 mSL!5l=pY^#=96ZDM<8$$nDaGnDJ1u6^ZeVT<8%nRpbJK+$EkW\*jt<Di$b*HEjQ^YP$M%pm<@RMK!b#
FReNLD m$bnIyQEY+/8NCpJqmPb^?mL6^BV&u6VdWTXe&HnPFZ^<XKq1\\jdkKyhbEy#yq1?GYy&1+uiJp1/@h1
\j>wm% ?SI!/8F4c=WTM$b?+4eEpIjW*VVW6#yZ6$tXyd>c<e+YIyTw>9/$?1CD9makn&<56mdTtQk$u^FZ/#&+
M6?6Xn !nAwjZG$e8:hB6ycS@#Y\bnT&yduy:eq%%F1*BG#ea/:pXZ^PTNqjVZ>tLhnE*t%t@<peLK8D+XtR?>k
!!A/k% W&?eIV*5+?^*L4ce:aVQu%1uCjE/b*F#%knb^l+iu%k:Q>5=L@G1hNSq>h!:>?DDn>XnVu/kE>p\b@Zl
^y&VWb 1EZGVheYt*LJ/%L>\cIw$:WtN/&up>GBQ>#Pq9JDcZ8bdT?hLt8PbdVhNZYFc=Rubky6b$\9+/l>PGeh
u*@tj* jjIejw<A5%>EK9N%RIW?G=a?\?^>BL>1*Q/nb>K:wu*hNyA>/lmB*+qQ$R=BC!@V@BKBW4h8Cl<d1$a<
*p/b5C CY4t/RB@WXFe=?t5LTHBV6hH*FGZnm5ZFynYlBQ>JwF*qu&bET5j?4h+>LnmT141@KS>*yR@QInHtnJ=
pIlAhm LSi6$*^c=:4>LnA:i%CB=*j=F1\T@$*?l=T!6>=:V$R*SBA*&tYHV@ALXX6%4:5yXCh*%%$H8:/S@tmb
+S1:Y4 8$?d=*?d?^q5&kh#@mbn+VWlKJaPZQu>i51>iM&1!MeK?VYhij:*D?<mG9lDbD5mN6edJB:$BQllX@R<
?G@hmR ERl#AiCAJ+DAbm!IHk<YNpl+K*dJ=VXc%@8?*DlR9Vy%X^R^<ZV1FDk1my>pj4\Y?\eqtmVy9jlqq$?G
V+/LQC LGp!8\CI6dWWn6TJ:C6ek1@aMLGV^My\CBN9eCJthySA5?DepDHMqA*cDhy^YlZ1J$p46??/he8t!#q%
@wNEj: &IYVLA6Xnqt<jP+uHX6$#%J$G5LD*D9WK>VV5^1LHDw&L%J%PaqR\%w?Y!aj44qqEjYdZKZyN4=lCSkR
i&?Qd/ b@wP>%cFLYjc+mbhn>Mi@&PZmR8i%RKeVQYm#heMua%e69L=k/</q9JjTdw?P%!+/qNc1\#Qt%h<ji&K
Yq%Zut HAZM$TJbS$4ERljhEY:Vp<a&<%:\?:d=E\:/\@8np<5j<ePA1p&/a&>Hu#K*p#Rm9&!Bn=?9:*PKn^=<
uE^HN9 9^hN/mIeh!umn$P%wXkQ=idEmlLC<NnuM<aD\DSVpF+#^b8e>eDS8nV#VCKAh*DB/:\1+Rlu/Z5@kJyw
WKjh&% nMhR:V^&&<&5TwPjd>Z8hT6?Vl:!T4I/E=ikV$GYlbI*h9eD^TephKML!XkVQ?I&^MDC/u=y/^T5yqB&
IKVeKK k%m!8LS?jCpH4&8aH1qhbDTlc>WK?y+!<k1!IbY=/8@D%e%kTJR:c^>ycJAJHApuuET>!lt94ktKBYl#
8\pIK4 wZEB!N8\8PPMc<n$em1Ji!LhV4\F!5J^+*JpT1!EMtIK5%i&RqSwpc@V=qnH1yTtuimXH:nawIl4bWQ*
G#jP#L tHBXFDHwn:6t<#yR=%kR!6RqJnI/ih9C+V9M=M?C>DVWMcPk1Whn^^LwyyQ49@H4T6??tlln6LFp&+D?
#a:4%= EiY<LyipRLk8&*>4^&qb!/Hb&:RVwDM:nWFuQD8c*?G&lI\L=mp8/EAw^<N?4PGnjZ*/EM&bDj=STCV%
?WqnRB FY^An\c@9hK8%jnTw>:pDGV^Bml#Nu1@ydbV$AAd!mJh8wuBF6CthSPWbPy/uJY<Ne\bpZHW/9R1%kT$
cH#bYu wtP?*EDl>GWXjiRpYiML@Iicw\i5kXSid%LVaE6/yMqG&#bu%M1K^PV@H*6@Ghbt8&$N\<HhZh4mLwEp
?$#Xp4 YHF*h*h*K%AwL5YlRNHm:8:8:8=c4JSmLXJ+i/?>%yc%:8:N*89b:*h<#@HtS\lJ^mXu^uWt==^nnyuT
bEH$\* iNdceJd\lihK4<&l>ia^:@B$V<9RpbRVw+><hYH@I/SN+hYRA$pMW9*=<58nwcy:V9bkJ?<<9T1Ji\LY
c8Bq5W CbPy&h*md\<bqANFp$@/n:!c<:qaY/tn<=^>p?mR5t$<MA4Zad^+9b=RP<MwttKG1NCPWuL>yS$4d+@J
&=LHA& yF81&1:H^whKl+n:SIpwe>N4NT!?TRJ^#4I*5\+^/hKab^+j6VPy@LGuuXeh8yZS%niJbdPkLh=K?<lD
VMW=6# +GXLXP?$qT4#>jk6GpwNhj4jXqbqFPGbqt&pc4>#tIcnFT>:SP6F5#uyqtGD&\iwy+4LSet>F8SkKmSV
HV=/DE &ji\mh5X!uiQ#>VFXl#%!imEH^plGCQ^KDP>1^kpuMp<:nXG\eMXphRWMTmVXYQpRYX*$/^Z5eaJH>&?
Lqhn4= /qjDRee4+:F\pGeE1w%nG8eml%ujaQLAW=Ia5Z$YR!<kKX9ccqjQ:da8qd#wC9Y1w&V!+WPIYyGkc=PD
5%pnpG YiXSX@#&1WdVu?lntTWLT@uQtt6tEkpe$H6HQjtcwmTH9LqkaXq@Lcpd9^?=><eimq+Rn1Kq@ITem\<I
GM4HQ^ Vl^+C?EH?#AiFyVRw5&l?@AynMLl>n61\EH?=FVh^lS$K\iebJb=R&pj\/<R=@yBPPJbuP!pYSw:A5?c
/9%mt$ A>MQLtp8IW=EE1XWc//:GVl=4ZLjhZkKZd@Gk>VXTac*?T!1hVKm<SydyM:McE+*Q5thiTuW4k9IKu%%
-AXVjW 000a6097b1b00110333 Page 310 of binaries1.zip
^Vw?Ac \@ayXEn1=KBPt@EAm1%LTIGR#V>$8Dn\G+Eq=Y?*w8A=/P!?F&uEeP8p*L5nQBKW8DdTG9KCEpcbd@8Y
^epYpF XYT6$u4#EJ1@C^t:F^\E?d*@%lM=^q*Ky9F&Kcm8BWc1CjtYGEW>RuYDiK+Jj9I+Ad&RtRYbBhqn$wTQ
eY&h#j 5+n>y1DwGAdLCPXu+lS$9wV/P<M+JlPJpRD^/VAVXIa?6Mm+mdJ/SNj:@V$LSp#uX%V%JD!da\6Fl\Na
y8&8jK ^WE&&6N>HIbDS:cLDB$Nu^+$C^K%S?iJd&b&acBFMXcK8#:Qa?bKyXYnhqA8NTZT=/EB*<+n/&i<!Z^y
hIKGFD m95&S4&nmcup6d$?ZAdX!cMiP%=Q8XF\i%Y5eLYt=Z8qFB>JFYdDPJLqY&h=c8RMWd>\ZTqE/Z^ty!yZ
?%hp%G L+u%AA&yDB8M?Ju?DYwSA/cKL%%1&<\b&uCwI?TJP*Wja#iuV8y=F:$4wlyLjlmC^ie1jW:deP$NPpm^
9ZT#+E c*Dh/N%P*#%y=+H<khWV/4ZT$bLLMA4#&=q>cCN#^c>9*%ZXeYYiCSd9+L\K?<bBP+B&n:jV\^%SHe&b
:pc#NK wVtJ8c6L!@%6RCCF/\VVbASY=\JiawmtFy?i%Hc#wpKTpjZB!a\*Q&LlRJndE>K^>=CXZbQ:NLJ5RG$m
c+h#IB T^&u5EDhQmid1+Xwpq4^+Nw?A>$>uWwbYH:cXWt+XeyuIbQEl5@u6mRE$NLqquGqNtnAuD=Za!kNLF8I
A8la+Q KGlKn<YJVWL!b!Q6Pwqc1$qmQ!6nmtY/9ee@SDJ\JWlQtXaZ4nyP<n:M>9GwlYmw/^MLTPJCK/CVJZNF
e$Ja4l M:8V/8VQVH6XGQa9lebjQyw48:M>1be!yG$Fi<t*e458T::T!?ln4$%Vd#6KPRdAX5qk4*!Y5bu8N>m5
EIq+#n J%+F8mlW6R%GZ#KdS+Y4!e!q#/y<&4iZt!I!yjQR$>*b$>C<5hBc69:1!HG#NhP!J&k#:qu=jn%ulpC/
PL\cTk ^iluXNGNeLe=jnXli@qN8pp<ZMlZmZeT*w8lJ8%NDVjHTj1NN1?+$a$<nkE!Lu\8+&=d/CtN4:n%#FGe
4#QQnl D\4^hqb:VK^NnRc^F4KtMdEL=EBYa/@MN\/MhjV5kZKXXQPd+VK=&k^$jFQ56MKh*/nD6ym&Ze??$iY*
9XViG> 84BMdnPJN&i1uAFT:\46//$MN?YbTS4J#?+#cl^l&I$#h85d%pcd*wd5lNam?JSGc<i?LeVhcjj6PM1E
yC9+jt &%4qdV:+>PJAN/w!qNiY@1SDwwQQt5TZ6?/MmuVT$d*MdKNt\8@1l::Y=$&>/u8w?B9?@X=4yySVGwGY
uZ>BI+ H/mdG=/5py9<GIQ&uSnVE&d>??d:eLiEPQ6tqc^Z@FF<%%Hjn+=qy*Hwk8e&t1i6X5j&^jpjHd1VX8$<
%#=X\B iDAVPy\J:4*%E!^b1PGNZb%Y^k\$b8p\ey8I!V1>YF>K^?Wy@impQ!lBTcy:AKTj4LTkDNe#!HC@=YXt
9GMkG\ +&et!51Tdt/a%W^ejY1b#RQHb^SVVLW=bXhJk%/%DuGAh9mN&MLyRiR+\tXiq1?qLy1?9SSaKY&I@%lP
#R^Tbe <eAe\ei\9A?=h$Zt/ibK\iqYwi+&@yCN+^tZtyt$>9LqmY>=44XRDX@n*YCJnu@Q1HaX8RMLFXb1#uR*
45$/l< !DZQFS+^EwH9=JbDtWwwpmKybnNJl19bJaE8>\Qq6?6ttept/IdcF5ciCDwSYGDy9T$Y?SFaSFXEcKBH
=IwhXj bd@HJIe!SWeIJ4iWJF@+jFyWy#CQb#6@NjRnbTa%#:nwl<!YK\qY:tSYtZRKF&PGT#uS$bQ*PWwE$Pb>
dNpY%X D#lCH%V:Su?$6*aTlY6!>&u$?\6W^t>Z=u^1TP5Zmdm14J*1%qYlANYKI=5Tl/Z#n%u!*1N^u>1KnWGE
qF!^y@ 6T<:Vm*#Y*E#XP*FuWaGaX$?u84^y6W^S4!V5H$#/Pw^GPR=tPA%tQh&5M=:5M>ueP:h+J:9+JZjEK#@
Dq$tDI EG:AEFZkEDlwTDS+TQW6p1$dQ+Q@wPn:KHw*!TD<RhPRIhPwwduwwd&awc9aahm+ah#+acwQ\?CEd1:+
c9cPt4 5Nl+<cNRN1dp+aTW+d#W+d1$+d:$+dtM+d%Q\%ibI:BbI>m&QIANNyjdP6!<EhZ<EhPCEhjCpcCmpaVm
CIcB!^ pd!Tpd4Tpi/qn?qqI&X=$u8XI/jqI:4JI:\RHpDJCFQh1G4>1GuD1G9n1FQMcFD#cF:LcF*4B>k&Gh=t
lh9&$m eh6ctduPWe&mWhMCCRaPtdpPYhm?MhZ?WhM?YhQB5cDBMh!l5Q6ytc5SYh*lWXXuGWdMWeHGcP59dFTD
D>!CtR LHQNenna5pW@&YBu=XDu^p%#bdbn^5E#!Hu#e4JVe1L#+&YLe4!4+&64+&QLTGWde6:4+?u4<4!d5u*:
cBnyP: w/:nHPAbihJqEP?SQHlW%u6:4G^!w1>9\nXudFebSLw$*9hNAjjdSN/^ZNumtPm%HP!NA8uNSNpQPhMX
iB6ey* 8aj4<da4ld49E&P*Cu5@J/>&JtYQ^%\QFKu1=W@\FeaBp@&A<Xy&&dctTS@aKhLY1hjlE@i*m1RQE<^\
VL*H9* +*%*E&1\+/:*p%FwC5EaW%id$/mdm88+$8Cjm1hQm144T5H+m96IW<\pjdaIm98Ep>Sa$&MnCt:+<q9?
QK$SdK w&aw@W8=56j++=GH$>+ZM*w$<t19FH:mKiEBqDN\qQl\J&Wub@KtJ<WI=V@\VZ?lt?RntP+HVduYVw9Y
MBHqpJ 1cA?#qRQKMNlKX@%K=ccID6Y6>h&VQFl!+9SVDQD#cDSK=wB=PW+b9YEy9P==jcBNG&#5!<IJ>e8FDKa
8b>t&V XaNbb<XpbwM?#$Ji14nS^bti#Lp81c+nK%QXS$d\#a/F#a*n#?q8Ki@n#LqP1!We+1cB=85&=58&%i\E
?#q?C* JtSZ=hjt%ib%%E#9=mN9J@1YF!AGe9uC$@Y!T8$<e&wtE^AcPYcFF/aDmtQVC*npW==V51+jQ>yS#d?A
@tpt:A X4i6t@YSW^Rn$lB#ZunlL6Q8QF*@S6%%j!GacXFNZTQSbp#Qi!#a1^1FY9GFI=Ghp#Ii!iK?/^In>YLW
ad&HW> &!W^:&p+u/d!+MWMC@YkP$$#MVFtlFHdm\Wj=dG%uCZe6uE>k:u&\CY%mGutN/N11l1RIJq<Ge&M>$9q
9k41W^ Cc4%!jL%6tyw$B1ZtMwRQ5*4=BY+4BY<:LH<nLH?ZG&18lWl%u=G4BY>9JZkwyZEHG*9ac&j^cN&le6j
99Buc% %FS@qtqjX/:CyYm*k%dK1:VuQ54TG\^q>\*ATu$<V=DS1$6L!F:Nd%t6d%*6d%8hd%@h:%n>X1Z6Y1YL
n1YZYd %:%G*dMG/X$V/%6V/%<#G^kJjLtKN4TYPL!YQ:JY&:HYQ4a&Q:/&Q#Ft:KJ:QdYPN:%PQj%1?j&/&N!/
BhQ6^i &9!/&eK/&?J/<NJ/+9J/@5y/@iy/@>4/@Q4/@5d/>iaG*NaG*9aGe1+?>i/G&N/G&9/G&eGG&?iN+MPN
en6NeD ^CX>5EEG&6FG@?uG@JiN@dPN//@445uJGh<Ad5ibQ:k&^c+&FREGeHNlenedH5Gd\did?Zid/hZTeneA
c=^$hq 6\iB:QidaCSP=y<GYREG>RhdNNBd+4Bdcu8n\GnCV@Cd<$<=QFVJn\kGn4:4lmGG:%D%GtA&N>AS%iaM
Xh=wBF 4?iN$LEM*tF5dYAa5iAc<tN9&/MdeiB5diB8$SB51?N6/bN8L:^aL#6j?QuVMQlJVi%dn>Xn&CP&WRmP
bbqV%K pV#S%ltt5V8NWSK%pVn>hkY1$V5G+\dcuR:G4R+cI*Nt+\tmuaPZJnV58=Cja#i96n\PQtAP:8DN>m8F
?Tu:!w Sd9VG=@SGe56:%V\tPC@*1*A&utpMwWZ&MMZMP4k&?Nk*upH&qMZ&^Iu&^ZuWK9kNGAl:%iTEjc=NlCH
taGkE# M4tl*?qj*IuG&H/JbnK?5F*@jceCe+<GcMwld*#DayCp6B@Cd&186b@@^im!jXhQQF1jM>1ekp8ZJlVV
@Pi=aJ pKhB#mCJhb>Fdy>Gha?j*$lj%QVM\9Rq$!+/#>+b!*/$>Z/F:eH<+Z/H*6+:nwMdJGVE^!b:a&N%W%Qt
\puja$ yd%HSVN%c<MPDcMpA4Nwp*X>%*&Y%$ahdkedQy@*6#q6N:d1@hRiWR!Au<*^nTA*Ltd/k96tm$aDNP6J
/em#MS y8b!G^d!CtbJ:\+HIniEylV6@V:D#l:TTP9be?@dY^$M9DiFV>ALaj6eEdE%<hFpRQSIQ>q!IjYwj6*!
^u<tmP RDIlY9hwRjIIue5A:TeT@J9Q$iaHLG=YTVSH/wtY:1ut<uTHTRXYHeZHBauLL@&M+jINw?P5CE86K!yQ
9Ny</\ +K9&:M86h1jN66@wlbYe+NijtDh5nG^6=^!heDZc8LieNLS?Zn<?GYk@Pina$l9Va?p/^i<?ye=il?<=
%LQKJ& Fi<:Xi?j#S4T$S>Mc!wK?*PnBi:u/DB@Z&ZM@S\l=8>18:tB#^Jm@1aLKViR:b>CQ$iI?d9GpN^A$LQE
&GB>Nc pJ!@RV>HmMuP@46>Q$iI!Rd/*bl#@FQ:=9#:/p5869@c&?X9lb^@1d+E@Wu%Jji@:?L:4>YZRDDd@@?c
$yYX%9 8!k#l*AJN5RDChH5R9@mReehLybL:ye%a\</KN:^l^KMTTZ<LA$N\>ayC5EqDaID5WV\tPBGmqMEXuTc
m5<kPX %K>dIc:8T6ZcyE&eV1TiduV6Gc&hZjFPm<?%1FILI#aa1tI99wjVN>>NqR&SwC=DyL^<C&BaN/8NC*F9
+18?il 6cZ++qKB!Q@>jb&6<\iGmPTmdmmFpiS#6uMeRnm&dpjD\l4dIpWTPQI$h%K\WK\>ES!$u@IEHNy4FjVi
P99C8p M^ph=EcVBPpbpFAcD&Q9F:>b=Nye^&FePBmQ5:WG^FkZW9l5GS=<eYa!b%LJKEJBaNS$%^At$9TYIkMe
dm55wG T&5NHDN1QP^hc&uEiR9DTbNyFF^*9CkJ@QCWPctMI$W!k=DLY#w+5D@5q>h\FFq#Q<1XX@=taI@5XjEJ
\$:heP ZmlYq#kWeR&?8\a%aX6T^mYNcV6p:FJ^wk+</wWjR6::DlP?H1BHD!+Zeb<NecIYZA@Cy58dStAyGmRK
iZt$X^ ajddtqNX/#ZeDSHKW1Kbye!lJyqq!^CemKR$#V6RJSjntWEXpkNb1w4$qb#!5<<5NeJqq\kT5w:A+ecL
nn/^Ah &Bm?q+SH\1PBa?<blTl^?:h/aHIm$Tpi\nZkym/ye!A1nkW*%pc9L<>NwPN!+upw<uB!XktF\ZNYViE8
6yEMCP uw1+1G>:&ART#XKGCB=9@ukLia8TIGt/N1hJR+&^JBLMV/TYm+<ny<I=4w&JbpJ*?XE5GXelwIF4I>DI
M5KeNA tJmGNVJ!?cXD<BaH=1ZZ^qtREJ+1=6bw$X:!AJGcbiQWBbeXb+NEjI5L1Sant^y+kHSGR^eFkic:N\qC
D=a<HZ q&1h<#K/Y*@RXBP:*ZYuyy$wh^iuG^>P@Y15eRYJW8RHVkVGSji>\jW!HiLBECbAeV9Xa1w\Lpj1Y/ZK
5uYBMk :cWC@jEn\nCqmGd$I1EW<+WGy#p8:kQ9cW:dCWb<N*@BQ6+k4HdB#=c>mBPk$!@%?el%cc\Gqcm=>6*9
qSEpiY >:=N/tu?+NMwZDy^?@R??uD=ybm?VZqwi^a59y8R@5*/>ben!jT9@9=9X@Sdq#bJ+P&Hq1jw$K#:G/kZ
pF*T8W !hBJ+#V599SL+?h9tAX+!FmPjIJPGKRJ:M:>=H#IQhbw<nJ%K9\eDtWI9%Km=wZB<b%B^G&qeKL&a&18
+=:YGA /n9=ISBF@6Z<!%y$R>dm$</Clnl6+l9#$@WT!wccL/5mW:BRmjFh?FYwm45tZ4JSJi!c:niyFK&11Cp=
XIKlt> alK/H@RmRS=b?hwlm65+^JeDGt#pqeV+d@CM4MY<FP?k8bcawj$nHQYpqVFVLQJi/khb\MI*d+caBqql
ykQEcS 6hRH&/b5DqWJ#t&@%pWFLpiLN1XP=*k4&ecaHcRl4mFD#c^K:%MSB+KuttPh8\QF/h<WWtAmE$pyKNB@
-ADHDk 0008f51c9b000110333 Page 311 of binaries1.zip
VbMPeQ aaI%6QhBeaq^y8bAl@F+Ah<hwCNp6>:TtBXmtaSX\aGP8B=1WW^IMI5JL$PN$X/ebI%uQW=lIhbVA1jh
ZbE1Xj wT?eyeIPyTjZhRSHc1*%Edc9IyB>d4$:1CQGd5K\tD+pRLWE?&$p+5y45@TP1FJ8MX9B9XB^Xq#etV5R
?JFb=n LSZdqH9hq/kiMnV#dCNt6XPdbP\XPqbS#8w<IWEl$Ti%GmlFJu4+4hkhtW\d=LCWYX$LEb5FWcmPBK/?
HWF?i> myy8S*BGQ#T9SFdSYtTh6nc#%q5E+EHF*Dm/bbEjMJSH$JmBE1Na%d<MmI^14:knY\wju/4Yww:MINRG
c9$Bwa ^^AiwW\\My%5S=NnGS$4CT8leYRnyp8Y$$m$$k58pA%%lHe91Y#yXT+6wuPT:nGq=6D<jknVAQHL4\Xd
XGKMYZ m:4bKw>\$bn=T/lY+EEyu!4N4mQAYF$m=k1qmWV5+$=LH>H5ck&1XSi@S%BHLJi>6:K\?TadkGJkCtXh
KlAdZB *uB&T<S:lAV=kyXupd%QIiwwlJXbT/CYuS<njH6V&i8YX/G\Rp?Wd?Q\14pKJiK5h\ABQ&yhK:eNj<hl
^y$a+n QKVH@1!I8iXIpkW/:bMDe*6%VS@FGL*W/eG?ZCb:h$nqAp/&jWwkVP#%a*u/qaCT6a>GNqRRn?Tqm$\i
YMyS<Z h:81^k6hl6YZ>^unb5ZZHQWyK+JSR:Qj*e1RQ?:RhIR^KD1k*TkbKTNN!?*QITcm^F/1*G1tG/FYKhHD
q/C:at <d$m55><@%:/w:&^y+uXwZ*/DKyL@QypNqpSpekAG6K^jdYm*=Fm:Hd:!KRIRju!A9SHLGj+9uAQW@X>
1nT%LP ZkJuy<CwA^>NXTMp@aiCS9SHT$b+^HFR/5%EX9a88St+=8Cwt<jt8H?C/VF5$^HWZ=CVM*?ZcqtiNtHF
q8QeeK 9eZD&mja1#kj^8u+YddK?&wJuNFT84$^VLR8WqANhPFP&bWH&lFcke@y=l8hqw/%^:NaW%HHRA45Kp6E
V\TaMe jGSu%5q5N=$ICI>*bPmwdk9TPBaTGclu#A=h:EI=\yE\/QKwES/SCi\lY6lZim/1NqFR\T&YDaNS1^69
j%:teD $S>=1EWCik:uy6>/!6&dFVY%q&C%iet=8QJBjAGYKYteNl1I4*@8VJ!n#MSGhpB9/9pFXHdH/w$jBRmZ
e<dXTG FaPTXbbLV^ZZY=EK:RpVRuI6eHi41Z?E@Tl>nWn#k*=jMASdYIEpLV$B%\HQbyAJ1/mlYEtSWeQR9qiB
?=F=S& Hy\Bj/qnM%cHb:M\Q+/X%<SZQZQM6Fc/*byKEy*6X@Bhe&eFCw@XY14uJXJt:J6W&lK!+ZGiM=4QL!nT
41SJDG DGSA<Xq:/D9S^G9$CdcZ<ZwL&mHYG!u%&mRjh?4FyMQnqhNRl8LmBpD1C+69bQcN%ANIM&@Qh+5#Eh/*
VJBDpW XhS<%uCGqJYhp:\iQ!=:!Vw>ZdZ5\49yH^jtCL:FC?%Z*CqW4@hN81Q$K#h\>:mp&Xb!*hT$=E=END=+
buDa@4 p/N4Jdbc&TBqj^SnDH@*NXlyHAL:T6lTZ:%!p!pkyRVC@cPcy>A+:WReR+&Ze<meP1DIy#:9qRdP+tT%
4Pum8D wW$HXP@J&M\:c=#kXIlCXZ%TX%:LCNwyqipwR%Yid6iydBqDpbnl\E@4l1^wb:><Yd@QXE1T\ESV=GF/
TQXAte Zju*^wQ9LbqS*?teBpJLidCnn8*RHC@J+T=FdnDcQlyKB&u5m9daFwRhXMHHcQIaYwyLhtYMY<1P&^9K
!Wkb$T 6mVq6<u+&e1MDhCllu*eZ?K*$4aQyuIRd:wyG4tK\e$%=>W5cVMP+646M*$#w9\>6KB*Wk4=EFc:=PC/
w8j5dP 9?:l8PF/wPq/PF$XQiqmbAAPJXb@pkYN%j85IDwmJmn&K@8yNid:k#HQGMBZBbyFmpDEeT@bww9F#%\h
ep\aAP b%8/5b?EJTKDi8*FHKHS1klH4bGL=SIBFkFXDEBNMj+?1mR^cj=1Ja+/J$XRmiT:!S%DlcK&pb9TPG%\
JGcAt/ VI?Bp9ZQPQN5LG5ySpRQJ5&*Tn!q6wVhjiJ>XVD+^=&EV8yhCtGYW/S*TPp^4DXj5uC*B:tT^bcGR/=1
Lq<B8E yCyWSiZ99w1GWw6c>&6dWRiJt%q#l&u&PC%%mR4TVZ%?MRZLVYi:!%DVl%#nZqYRV^6TLR6h1wDwk\\W
eedQb/ L>juKGh9P45!*n@eDHT?q=BQlhe*FP\^aICh\Mb:KeJnGC/:+w!GA%>%a\9>ij@LC?R>>iydE1!/SGC!
VFSRRn pApVcyC=uRm:19TC1tLAc&Nnb8Meell8^J!DRAybYWFdT8l*5ma*jDq4NADeXPhIi8QDLbH96H5nqBG<
e:tN+n m5Huku:/TGR4GtTCmH+dVMJD4\PtlqH>tQjcFEX8\1G*>Mk5Sa\FBWZZFEY/QtH4:%BTLQtFT?YL#tK5
/t?9CC VYDy1+1=n$#!Lyj#j^%y1l5J?q/yZVj#w$5TlXa=XYkZpdWuHwEm1bBCqL+Zmq:bl#&AE+ET\FnLIX9L
@KnkMq R&i<Bk4GA%QWk+e>GL5EE*4pYX^+Z?e?eSmL\%?ECPDwkRP^IDn<TtI\#Jj8H+MDIV8hZDl&hC+muMw#
CS8&cS qL9nuLQYj%+C?T@tPj@LZ1DmdH@+:uD<%qWhR9dZw4V@d6ppN^9\j?kbBQwV#!AR%*@LbbAd>C?8lL<i
abj=n& eQ^H8<G@4e4?j4*H>w>4:H<=k?iWcZK#5V<D@d5TWY+&$DQR9#N<=&aDQ\eN=Q+NG9JQwVtikab\RH/D
NWaKb\ =u\PG9\:NNe#$GDRd/ImdN#QRIN?N?d5\PikPZ@#idM@l&8k*#maedM@l&95:L<bNjdueI*>N&Y=*P#Q
AFa=Kc +Swd%?@RpQ>BeT9Z*+ydRTDk9^c*ewL@b:Y6ICAH>*<bcRGRKj/&66Y\jHj6n>yYTXNq:n?ydjWAdQlY
%RYWD^ @t661/W1#>@X6twWN4eh=Q>ddY8BGm%P$Z#T9>c&W9JW1&XicqqCj*bNZK<pTG5@W@L1NQncSMRCk^Ve
<KcdZc yGcleHMh+KM/aFLanGw9@Tbl%P^5YZjCBKR!@9tKMI*+P&ZtyIW4V=S?1WLFlFu>c#L+?Q*1ah99QP5F
qW*y%y uY?dB8&dZw>94BJ$XVp&<<1@9H<#eZDB?FD^cXEw@>D=up>@@Y*^^wF:m#:/F@jmkXtQl+&Zu/XBRq@9
wlWFSE d1iPjRi<J9S4M$@*LR5jaMqGTE:L&<=c:dQJTlkRwQlmKNjiFE@W?EKX!p%BIRylqBFubb\jdV#RV5Z:
nXFTPe I#MCGZb&m^A^<@H/LZE^QcPeeGuPe^WCq%yFy5jeZ9V&u=y?Ek*9a@IhnD6>q#hE9^iBQnlqMqIlP1a!
$C&4^< p?pHb%9PtFl61\\T^?d%J*=FDh9QN9cBcb^Nbl!tpXVK^bae*DQyFW#iY?A1<Jyw65+:6M>^Jbl/8Dd>
LTBqyS J#VQNG<l=5mkh/Wa5nIZ\FItLnJ>n&X\uFqtFueeAy#Acu9Q1al:<lp+h5$$Cc=tVR<LiHGIt\^RuYX1
?cIRi# y!y$5aMlpd1muDwW9ll@K#+hq@lKW1a89el*%q&PR%FX\W%AWTK^>iYPewNc8a^YE45ul&V%hcY68m5y
wtW4=C 6?W<n5w<uYJNw1jli8LFY/MbV5bE/%u!<XQ8qMElF&<X>dF:!QIX6N8LFhtMaqPh1^wEYaQ=ZmePBXDd
J$<HnD F<=6Lu5$*VWQ/u%m56=pAHhl$\%9+MD<14@BQn=ck/Zb^/n/N>8Eel@N?<E@D4l:t#8e@cFkcSAwnbcD
!/8d&S Ph<c9Bt@AcA=lWE=ty%Rc/BpPZNE?BkpVDC#:lKP8RT5&Ie+XJ+e+*hZ4*GDSh!ZCN\%nJXXeY1>XIk#
T4BLDc 9uy9N8jHaNkm9HQL5>K/<jjh9w*1%JSXm8I8GF^Cl+T9<a#+P#9BuRpYtX@\=y\1J=lY$E6Q@>\&@nJZ
!n8c6X CJhmqFaua9EXiI:FN9D/cnN4%ieFe:Nq9Z?bInHeC/PwibWKTqTtXI:CquNp1<%?6=@IQ5QFh\??w%$@
&w8hEI ?jCaZB4jcVY<!eAQZap&5@6RiwL9@8&qt$>#?d4D!m=E#VYni5IqiZ&^Nqt6@5%^kNMu%1kwb>=QA=e9
e4\XTP hW^wFdm6Gp!Lk1hHYETb/1hi\\eh9cT<<=K1@!/AMKXF=mL@%ta:yu*:AwCR@PV#6j?&Fhe>iPB<A/@M
lKdh\: &$Jw5YNZk=9jA*t?9EjbE+B5C&5+SaTd$/?a8?\!+uw/FN^Ni=mYDW5S$AWRSyTRk<<Kpk1!Q!dH1Y<K
:R/8ql ncl/C4ahQthINqcaCmCWWCk?d&8Cj^yBlZcYX+jPMqWM%$?#>ue\GtyK\kdA&H4GKJ%!NJ9^%qEp!ClX
iEHdCC td?YeEbCNE=ZeAJ?akdZR:C$n:wEpIA=A%!&<69hjA#>&C?wj*k54/%Ei*&DF^a1CJ6ZHbZB9/lRq/=c
Fm:%Ly RcK<BGknN+mKN8P8+c6/^DnDa+6caA5e\HbL%@CwDk=HZp+aqlPWadQJNme>WbRq$@6VYI8:<=Gw58$D
D5?KH# MG<b?D!P\Mc%NT1&Q5Pa\FZG@ABRp5L<jWujc%cK9A:qtw\Y/dlLS4G&<!Rt*1C!FDX?Y6ElHl^/!\?L
!8wQQ\ MVR:6V?FJKqpFJjL&cpi56+QFTlF\c@Tt>V&yq64i1M#<HIXwS=:K$>wm^c@qe#!Yp!QnPaXI*?La+p>
yPX5lK EZ$cpCV9=MB+>J+@K^L=Vc!&pZA+IRA@EV$:KB+PKQGRAXIXi%NWR58ybaejj^tTM1EMJ%jeV&h@FS<j
QHaBI& :YYk56V1d@%lRYJ/SECTHPw%EwT+1qb:pMWG<mwQW9iybd@q&#GiKH+mMb#Ti@dYp*t^<ulnt>/t6i^h
KJPeL4 9@I!DG$HJW@9&SK^8GJ5Lt?M%H&=#:J^=uZZSSCmhYbG6eDImwGTYT%%8j:DPt\KMcIZWp+C^ZpHFi/S
J$aN=F u&BTQ5ZQ/@qZ8weQhwG^:E9%&1y19H4HT>J#W?YG4entXXubZ>qc6>e&^L&5aJkq5T+*T*ZupD:VptGY
t:\Lpk !HeEpCTmu//@du#DFLXSe&*ik6PFbjiq*:NTA@+kc@F^GZ:@6qNn8w1TJ:ulnNeqdc\K5naCXD4N6&lS
d?CYNC 1IldX>Q^?KLG4jPG9%RmHPcha#^=V%L1tFE1D6NZ9L6P#qtaBJq>:^P>/<=9PwCGN9n4e!ckMCQN?Z\S
j&*dQI 4WYmP%hGM1?>Rp%KkIN8XYXne4+yTuiw@e^1B/d!8p/4b^^RdLiH/DZ6tqTNX?K^i9F=IMEY4$qW>T%!
Y%hP?a a\$4A5PD1jIBSeyAe\!5mdSDcFa@Xb9\LQ$ccWq#dLS!WZIe@$:NWKn#>MJw!l6CR>6+Fe$::Gt8q+#q
nKE1<< eJ99uVmMb?CIJjZZBNJ4=\Mtn1e^N<8PQ1R^>+<T%6Xk<ML#ZuMED@aLmCZJlGb9R/lK9*H$H>qGPF:d
eTSkc^ j=lJ:ZCpYm$Ne%u\HwGnNdS/WMq$\$ceC:6Z*SJ/14X5CFqa#6Y%GR@NNScGGk>n6J:u^Y!+1a@l1Hj$
+RWA\t Q#wb4L:=bNtup/t+:=NwuIR@d5Z>FyTNQTTac&/!m1u+ymhbw%Jc9Hu^6Y*YPZN9MmncidMX?tG^dV8H
5R$>/: a@=^tbhA$AG85a:JNu^\:!DjB1t*tRd?ca9El/@/ETPRw!B<:%:B/VPL<DDZ6>HJwj9\Qd/WE8/Bww+K
p1Z4Bq u1^a!bMWN6kw8qTubQEPDaJtYjZDl%!JC*T^1WX5cn$Yp#hZ%=6npBt<tN9SW4hQZkF*wd#b9B?>d@AX
MHhbdM +uep>Qa5AqM8h!1uMYeB:RT=cY=:\ZN/A8K/#Vn6%<=^c<k8W%EHZhQcP%SKD%B!=+m$jcR>NQG9B^&P
cV@tD$ HTS/mCj/XL&qnC/wbeaTPutW&@DCPB<J^t>nyFX=u&I9HuNu5!9MY@kMuCJ?!m#>iKZ#yd$!@Pd^bLFI
n%F5C* \iYk@iuVh%?a=i??kaj<4*1?6>95*qXG:HW+?N+KWB:?&C^ScpiKDBb\PQQbdQ@?lLDJulq/<e=k@MeV
-A5%RY 00035fa9b9000110333 Page 312 of binaries1.zip
aNe5JX =>FQ^eK4h=*4Q*\h9n+c8Q^+E9n<$:j^/#*j=KQ9=pM!a5*VPS#A/ApASAKejRbMaWHb$ELF9wC1ikX%
$Njquh nkeNSL<\EaM?b+MBRtAe8aRCbYC1lGCBa4CPp6>!ycG1qPCAcuCPYuBXiuDuS9BAM*lHK@k1P@l#J\Tk
%FEjTT G+KnJ$KXD$LkNMJ=MKLni<T1KMV#PCSkI1JnAFRPCbJnNnI\H>t^GLFuHk/cHA+#%e4MGIBbmuLinR45
b$F6T^ S\/EB%cNWMY&RXXNWDuPwqn%GTuP\pu=\/M$\&F?ly5/1\H8FYP1wJ@QJRMHMhukWM&eRSMHaM#VEIym
c#4mVC FBpMFHlnA$NuI/E54XkNnCp6nGpwnQQ#X?hjePJi+*\V\tDn\==G\K&YR+KS*&E/y\y\\ZKe^%Je^c4K
=leNqY \Nw/WD=6SteV\9:Gl%E6RiDETFD6TeAtS1CpRFkhlimp@C$/F5Mcp\XLB+$695eEB!5aDc5jDIXXVeJY
NKy/<6 VRnW\a$LJcu&^&X:R*L?lB5ZR@y6Gn+PGe!Y#Qa6E+88dE1WGt>1#eAMCIWWCaZqmcEWnAM<IXX1^5H1
b=*S9H Jb&iJc6BI/p&bGhdaZjc^D8qGZI/\lj?ky<QlIG/!C%qi/Zpk1QMVa4=uR^dmDK8p!\ik/y/<wW#HqFP
8epL9m IZu8RZ&%CZG%ia$k$BVJFVaiRqp6RBZ9SF4>E!Q8P=t!L>XMMNtMIq5N9mT&JkjLP4ElCaw^PlR&T^/T
XRD>E^ Ae&*hy#+WpwuCK&mCcN!KGN%BF&Niw*TKq/994@$QRY:Eh^$FRJbQwqT</8cVi#yajmLb5cbL=nK*Zl^
5X9NGd YPS>*+tX9!NX/eNkR+CK*%@F?^JMQ!HWuLBeE1FmZ%A=y:^\KyJYNIdBaYcjeYC4laAeE?+XSy+\&yqm
^EZR^6 byq^/PHb%$EjqCDA>\BHYmk&u1eLA*C6GwiLFWiXFlDHnlQpBnKbl1*%+d#$=/K$k4pM=11N+41Mye9b
/twC5H lj/R\q&d\Z&b#RQK=*Ey=mq6aqK+jA&1j?*T@L1&@jXqN!?wu>hlCAAN@chSGQdu4HF@K^#kbu@PIyeh
hSm!cP >L5qE>e@lZ:PIlj!8/AG/FtLZQD9$M>b=Q=YhkB/%mIZ?B9bARn$V=$*?J>CR@:Bt=yXnk*E\5*CDtIH
R5kWX9 kquaLM&MVFuW*Y#6#b!NnK%54X!6#F!idW@N^pHGAiRmk:CB!Dn?=yV>u>yVe@>hQ<D@5<jD#W$G+iak
!w#%Qc a+iA@uJa##te9>hX@G%w@#Nh^d<cYj>FX<H^J%*/8EF@w18A5AFB@*h$/a9:Z?@Tb^L>Kh&Y/^McAkhD
:myChS /M9kq@8Z%6h^RW6Fj?uTX<lp\#BSF+ymjWAWDCP=%6^N!TXIB=SSJcSnJp<u^EV6>V4D:!cHbTiEk$:h
/Y*piy l+%$%FV5lbiy\^^kuX1KBQhACT:nBGNlclQ%BTRjaan6w11CKtS4kZA$@9??Rh>WKLPthTV>eSl8CS*V
EVWmFR ZeBVmTIhLm/49Ka!A=yWemVJ5NZ5Z#4AJV#CH&<XWVAi8@\ECE1:u6bA!aBqec8*SbYJlJnAp1&X6tdI
1kCPZ= tMnhMm@ky@#LTajR4#+RE5%MQSAT5Ji%#XQ#Yp*bjk4bL8HpD<EyeiKX5aF^AAw!nH^ua?1Gk!ebtKNa
5kJpAN c6aIJD!TW8+GHIIXa$$6/:6q@RVbqyEwmR^ubQ$YlhqlMFXkw*b:bw&Z:DWXPcjml4b\F&Q9qnnZ\QZ?
m<PDLw ImLpa18p$S>>&wlEp%/pk*Te*Gk+w+4:P*AS//k>cFclSIH%#Mq$J94IS6JLDIwSbYKWDNheL14#>ttp
Z^w&i5 yMM1dbjR!AuRa<Dwn?qBDcn8:en9qYXMWF9Y44e&EXcEaQBCX>+E$:4B\W#kyG/w/!$c\&F/#iQQEjdF
P>4$Y6 RedLI\41R+d4nq/4a#>A5W=lnW&Cn/+yHDMEML#5%NYY<a\J+dqSd*X+QaGKXN8eY^aYLDdtRaS>H/pp
X:jp4d i$WyW@ic$JJpCJ5W9\?yaG58SP1ahWi<IiSeP@E:G6L%:NQG%&/=iGnRbdS+$Z5=?pMyw\Idq=AHqS!B
VJKq#$ dhlt^Zu8KM?wkGejtIJiC%X<6&+c6XeF\8%p^<1V:FnS+NLSS+9Hu5jGaQ#+ejc/%%X5%uN%#:qS5WQN
8kh+Kq <$k:R5$DjM>G6u!!a$6<E6ChLQ\Vh69Du9J#MGHPjIR=8eTwy^EHKhNnJDGXGMM*t>#/MY$N/WN^=QQZ
*ujFL: lGD5H<STkd+^Q*hbPLBu@PMejRDb:$kJtb=/ui?$y5J\tRIink%SHyT&<<<+R>L^wFRw1Smt?V@XP+bQ
JkV%/b K&PwXBAhERF/nCPKnFDqeb6EF1WQCeG9NILXiuq*q5=Z4SQeGI??Jj%IlFXuwHh*BPAuhY*naYt@ktjl
SIbT4L b^VJWk^KG*bCB>L^=Ay9peJaBdJDJaEEDyNimAV5iVtqbEDHu&Dq#AT#uEn!68Z*E%K/cpd8n\$^\CWn
@u?t^4 RwP>@Ju&FjM<DD?bEPpJtQpS+>:5p?1ui\uFw*$NTPCwtccWyqS$ptL8*\thpuY!mM^SFdwmDF!1E>aN
%=tc<n q?&qN##5!wtAm:Aq%!eQ&AatMGKJSm4VBeA4j6a#y4iI^j8E9$@#ti^!WZpCpd*cVVSyBP5PTtd4W*i<
XGDq81 <Mj%XX8:GX6CGHHl6R>$IPRJKQ%!Y9ASVL\\9QR*P#HNlt*%D<t8DM4MH&uPhFVwne&Q5jDH>/IN\4:^
Qe^9$i <*&GmuthcEBDNY5Dn#uinADwmWMplClL%yFK1jcwwh=Tt&Kd8>LkYT+mC6KyItYqBA8@K=b8yua9KTPC
CjhVFy *4JWtmT8pk&&JK!@bDejP>$B$/^#bdCHP<nuyd\&d\wmkiE/me4P+8m#a=#J<XXF8=hlKKndIdZ1WwPP
^=RA/w qiAk</QGeb^VSFe!S6>D#R1cE5V9PSJCDTIdbHDDhFMI&whF5mRPXPdVaEITR\5mw<?a:Wn>aMaqXT^F
t4wlmZ S:WqmP1j\k9itqhN#=YY^=:SbTnpKp8Yb6j/T?>/QG>wQ>ebP8hec#KGnFjR\m9E9bS9cw!&PMtKpdJG
iuD91= $IKLD9l+p:GRQ#FGBF/8IQGelCC!MDWGCFZ^n8%:I=NbYR8^uwLdqyRd5m/DSYPF$a4V/yEME#AVJR?8
#jG*ll lillwNZ&ky8?*9t6bc$FbXNl/p^8:PtK+^DGwhFAmX9Zy<\KKB>9L#QBu<?qZd=$a$myLDejY$qqSE/R
R#q!jI \VM$KbVhuPebqS4B5!y*1@NZ9@!tY=yFXnG@$/:SA*b?n^bMH^#iw&twy\FXAaLFb+LVuMJ>E!cX%w8\
nBJ@<: F1%q\&biHcHGR:6Rt$DXXqcwZe<E#$NT1XuYGEu=+BS^\XBPm!JpZLjAHB+Aw+MLdS@PA!9l%ye::RXB
pIXa!H Zd?$Djp!9TM>KI5IM^a9=tkLHAIVei49QeLVmaMpp<iI>p#$ZceD69T=PIn!bEZF+RW:Tki=KT@HB>Gd
W>d9&! L\WImDK!lAS6WK8FnD8V9<CqdJHNXG$NIRC&<!yKd!&%=y%BZTiESVc*8T8Xmklw^BFJCjJCC9KW+PWP
A\VR>^ SbpdFjnRGhjMFbCXlSe<Iq5B?8k^aTSKpQF:l@$nA6lZkMmZ!\cNI^kGppPtLA#M1%5=64KLF<V8FiEP
J*5B6m PwX<IiNH=W1&eNqF*Cb&duEiw:LEG/?*>ZMJ=Q5ciqlEPXM?PV^m/&*=R8tu*i*d4j+puHdbEe4PRCCA
%kqFin MMZtSAEpZk?ejdMbMb#juYCyyNT6?^IuykX94=dkBGQ&Zc=eN9l4SI#%\>1dWMnmtRiL:ZLRWhN5L/de
uka*tq 89i=c=PRJqAZXbuE%@Jw%4YQPP1Mm?\IYcqj+Iee+lk^/5p=<=edVMZ94dR<G<k+iRQJbEVw>C:BKP!K
u^e\Z@ wNFlayt&jC?j*LadmdnMM:/Vnp>RS><Sb#%RRtyF*wknJqWMy?T%&1ndhhIQ:/GTLP/Rw@89edceXPLH
Eq8wL& t4a1#^Vnn=5^&+^iXm>>BmSM$%uWi6j+&@8p6Cw8jG<laAS6KB!JT*DlIlK<=SL!n>tw\\?FVt>j@KHM
PE5%Qc LHHH\t:+c5nFelM+=F%u?bNjQ$#y/@:C9b+Tu:HQwN+VL4=RjR\G*@$6&8MlD%ll&ba!@IPbL=FEiRXq
BdN?<m \#4u:NYuL\8htWq/^\hh<9y9$I*6SH=MIAM>YE%FT1Nu=CSbtHqthkFl$D9wmIh\%M^RZ>BkpQC@PeDA
RZ81Vd ^I\%:ej1DZFMTmT\w<uHMX%Fnk6Pwq+hD54PY$dPTAEe^?ZuLB<KbGF=Ge$lFPEM5h:$$k%<wn8W?/y%
VCkh*A MKjeqBh%Xp85Z#+J&8ZeCE<JWh!6HhpLm>I=D8D9\q&^ADdRnkHP#HiJh6d6\R\BLM:w+njK@bN\5KJV
9lJWE^ Fqhwp&nwGHtPZSNia:D=:*5K68!6nVqESMd+k?yC!uLWAl<c?=FRitcAtC!JDtE6S<kGw5Kw\H$5&ka$
&^h96S %44XcZ\JT6SEm!clApeY#K1XZXnlL^Y?jVww*=nRA6c5?8IddEN1<9KMhyVlHS?BpR=I1Kp!ybKCy1eZ
an\%*! :?hChk8EaLdkAJ?CkW^Cl?AwN1y&qB>yXVYm<Lm?$*nwmFiPadm5SYBWbq*HwlJ9&41W<!*^/LDA/WRE
HC19^\ JX*E*n=dp^G+5SucQTbKT5VqwI6cbQaDT*6^K%pl9\t^kCYqIG$Y^T&immW+kA:1qlqb9tAZhb<IuIh\
t=N&%: #yIIM41BGDPilK^nXVFbeS$ep8pY%yk9JhwLtn/y$I<9iq/@SQcmMw+jH=Z&\QJ#H:I94A+VnV^5DuHY
Llyt#+ N<5=S$^C*6N@ppD%MLhXwcclECjXmQmPFwcdBdj\w*LAyZLpc5B4>HNhXy?&ynLH\*/i*l/ZRYWl9dlZ
BPNu:B C$aEw@&KXu!d*k+%LR!<YQGXEQYXBK9>@XjZE?YFd%XNDdD9GnACtYt<&iH>tR@C>G&H>w5:=Qb&yPVm
bn1b<t M*Lq:eTuZ?:W9Kc#S/FTnSEnBk+RT6DXNXEFZbt!c^dC44Ekm<nSPGEybti65ke8dPWe/#Iktu@kHd$W
FTG:6J bJE+b?%uMknEFKEmHD%<AuWhyMH%\cJ$laQw6N/@&=&M6LJpE18XFRXJm\CL\a=n#E4kh^>a%lTWF?#b
ZbjGq\ aD<#5iW=9/W+VlTX>LCEIBeN\iWeV?NEYwq^e^>ykKm*k4/q9=ZJjm*Jp%KdjuLBt&kq&MR$DnDuj!P%
#AN@5V NCFt!VSbpiqA@H=4yyYc=t/QEQYDHLM+>5Fk<wL^F6#aGE&AbIPJdQyP5AnqZLjI8<IhZpyJ<#1tdKTh
M\/tiK itTKMSbXSA5+XKYRK>&hR*%FJ*GYPu>S!%1EY\t+uB%ZS^bSTj%LFS!LC9P8a%$1RuSaLibIYGbB/<K?
?1DL?W CuudhVF1Kw$ELc#Qe6nWXJP:iPLB:PF%nk>Zq1t#NSFFWGKGR=qmM?h#mD@N1CHk&MVCH%bnmCYu1N\>
aB*eXT V+l&TbR>\6#Y*p#Cl\QIA/@>eE9tjm#dl4H&XT8a:IEFLiF*c1nIBtREk=Aw#Lu<#PED#JFk=lAw#BEF
Bq%ytT 5^ANBSGk#SENC<n>\qC#V6HIBqC#wnQJL5kB<al?k1?84hV4:hT9uVRkdly8ul4%Ql4Z@8y?WJy8:#Z4
KStyB* w#T9I#RMARVdWF4%GX4Z&h4pAABiA5t&4@b%6R/pZ5j6%=hVBTakC^P9Xli9Z\h9YPi/YEMRT49dX^jT
%Ck:<X 1+P*4q8@1u9h11i&SLL>yI6ZdaB*4Z*>A^p9SR@mw8hYkdjh1ZiDaum>d#m@1h?AwJjacA^yNqS#$nQ1
*H>eJ$ NL=lM?GAGL5qcmZtc*PR/!:R1><kGc5Nc5>QGuK<N4t8\<R4%?hRM*TL$$#e%$w5N:k^MjZd6ZD*6Mnc
Nji#M+ AiD6t*Z:GmZ&G<*dA1A8CQAV4h\Vw6#>hShE>QDl$cHiwiPFwZPp\uFp/6#pYuBE9!K@iPujd&9Wd<QS
-A<N4e 0001227bbad00110333 Page 313 of binaries1.zip
n<%9^w cL:Adh^RdD$jckQqbLWRcIcQbVq9a+Zj<+yn&HblX>?h^NR6&M/>$pE>m?DG!V+^&Bc@*+Fn$$d>8&XT
MwDIVS 8*%D6#MuyXZ>S$h*Haj=aHP*WLPGX5iFE?9=ERCBpE6my>b*NwidSqj%Tb9EbGRCQdhF?Xjj%dRYLX\V
nH*m8M +$!!jVYn>J\dFN=\lPB6R&uWl:!/KZ*nVtpyCCDc#uSbmCc=nnLYmQN<a&Lj$Py^ZY=JWPmXBHu4#84+
H6ht#m MiM6^+tLBpTVe>m:eh#:?:RQ=^RIRni+k<qu:WZyipF=\5Ky4KF\@NnDWFL=<bS*J%kJD?whqw6T@W86
b+i\Z1 c&1jLAQqLk5XCKhK9aA1SEI%!$D%YpZNVS5Xwk?qb1L?bn/\mT@\i6=dW<#Dda+kG!uwl%I\q%1\EbL4
PI:aiY FwCp?&$Iq%tIl%XIp+/iyqFRX^=t5nqt<y9RJ6?kJd%R4nhl=G@Dtn^D8PLCNJ%C!N6i@jAJ$e\M=<wI
bQiamj B?T@V$IIJhetYa1K<GmNTQaM?XEd$nRe&hS9uN$i^VWj=dEe!9W&iEp8PFpnc5p5<pa1Pup$cMpwhPqD
BbiEXe >EJMNNh?VJQSi+?j:y4mACJak1dC<F6pANStDJhJHKE^b4JS^FK9\*#Sm%9IB$<8ktd1GE&:D%BQH%Kp
@>8?jk +t+F+qNEnJ9FZ&^uJDb4Jh:!^ZFb^VXLcQy9^m&@TFnGmWtlVhCT?hC5EP9ytbRCJq4YTq:YT?KtDTEm
MyRAqZ mMCQTYy&?Enpp1IqFL?eah?5<jHYLeXV^VSFI*E=/wNueTKS^ej=$KSdTIluaL!H!5hqGe&qp^nD@E?i
dJ%MTq u#PYydV>6RGEd$MIHNKY*\GILyM<j^Bpc?M%cbN\1=q4&tYt/ASuP=t4Y$TtKAKkMtKd95aV:Tb^hkj@
T$\IR5 YM%6^mXbp9LR\6BeE5y4pe9:\R8V/An:b1q/iIBS%pFJSLbtq=RuEV@u#dYm>Y%B:n8G5BbKbBwDFA\F
mEuJuI R&h1$A6qCuMp5yWyR$FE9<*<WXHR@ntu>CQ44l9dtH\F#w6Cml9c&JmTEi@$+>%TpVyInq8JwT=<nt<b
I^eTBq Dtp6EuhbIuVJ?\G:qlqK4&/pH4=T+5HT%KQTR:6Kuu/pqX8yqkh1ut>qqBIXQBP%VA+K<&mq4/G1yZ@A
=pE=6B n%CY9*%X>yc!NI$RjFhY5!Ph$dJhGwqZ^QCPJ+&!>LWwNW>khiy<BaqT&iJ69i4*/6T*%VDBFbL5$y#H
6+4+NK W9h5%eSN>LaEnhddXZiNDWmDTm8d6T*4hTTkyu+5BS%T#6/+clIDSb%QR/8c9QjFqY@ViYD#l8:qGqcy
?=*#$B G6L<Y*ltY*Ziq>ZDWypy%AZI%LiTN/=G$8%I\/?P%:h?dE!LcLhcLiA<1d&@41LwL/T5+NSSy$%LcZ$L
%lW1&w %:TG$4ucXZqQKXZ&85QR6nAuuQX?5=$Wy5%pwZL%1i$?6NjLBd>Ht8PB4a@p58:%Aj^hei<DV1W8kcIM
Gh4@A& 1L?%8@<B4nhhp+j*XbuKm^+hi%ySeG<ce!?9TL?8cXYdRAjJ&$/9@TGK6^Y4My&pWEN41aWQi4%9T$h!
Q*RdP\ :Adc1q9V#WdY*qTR?9TtGyY$54d#eyi9hI+>mHX+GZZmwjY@Vl8RjVZ?N4>?4Z&+:cSm6ZcT%GSTyLC!
\t/!GT ^:Pl>5Zk!W84*beNJnN<KLDAAJW/+6b!NnmB$^!t/b!*+9kTWTKwl%=i$Aeiy:CeM4aNP#YWye/=ik\5
BdR1kM dCJ<FWCYu:#%XjJP+lq#ekk9wY64R9&Y<&+Ey+/F&c<T^dnc#B*NAlFi:S\<B8HA:8q\tYjW@yVNCZWe
nm8t4C mWXXF#pmlHPAEyeZ&8<:k%:uKK6F@!qCNdcT$=/Z\W4nId^H=cy6^LlQ+eREh\/*A9Nm4bl6u8#LPnY?
R6?6tQ ayDp*ie/k\l6T#&LGh%ap==+8a^C$SN=PMBZRXMyeZTA%iI8jp<j5\^9y4MtE=dhNn??5b\PDId*jk@C
*i+hdM CpPA1a<!am?<T6aIc6du:cEtJ?\4!iJPiiM@n??D@q>YYj:/B$RG+j=d%QMjt4H@uRCVm?!9\1u@6kAV
Fn+S+n @D<XaHL<a/>&dk:P@=+Ap?P9Zb&=PeB@i\D=P!Wt^=@&hPeG@$umAQ^5NTTa@Vqwn6<pVMCk=/DB9$PD
SSlyBu u+Nt@^$c<k\$=Di>y4uBHM>B@/=YE5#=DDV+h#yPMNh#$L@VpIK=u+EG@W:Q?Cjh\j<:/Ph\:Zi6Q4kl
kZA5:A #?Ec???+BupP%>l@^#ZIe:n&?/\p=Dqpa&j@nRRX<m!!eZQ<B5*=V?&d/=>CQ+h59&81#5*^HLKBj!j:
4nJEt9 =ZkP&j:I<Q$=t9&j&njwj/%n:1?=u+Mh>A9JV5aBkn\uB@l**ed@#/hIRd?P=+<WKimb^\Q=*$&S@6G$
ZVX@ca @a<W/S?H>b#D+jn:FCu+GTqT$L>QpZJ#@$tK>N<*T9@ZFCpHJ@D@K#*@Z!w>D!bQe!j<Z!p>d/PHAV#p
>w5L#b Iw*A^<B%y!wV=&LmIk/GMMWY\*Xu?%q^598yMH$ATcG+W$Ckcp*\IyqS^VHSA$Xe$Dq1L#X^R$+9uatC
a4bCQR ae^iHkiD#y6\qj^F&Cem@PZaMhE8LE*R$YN@YJEP!XGnmM\pKEd\B8Qle4H%K\E8%ty#k^q\$iNq*JeH
cVw#!p 4PkWn$IkjKc+G8NpG<61l@Mt/8y^i9d+T>qmdkK1&apK%E9jt4SJ\REbkbKKT8YctGA%4u:b^pc+YyXt
@HQ$1% h!+ly?X4W5*^DV!kpwn?uK\YI\&DwnWy8*1YLlE<?hkcBhDI#=mp&5Q?BiLENHY^JQltkhqIB*T?\Vtn
8#8diE akjBtBbyD%lTXiP%J%#Dt6LDtCERl+I8kpy+aRiELmCC:8+PEPQe4qp:HyXPd4@BdaBlqJ+N#l=::Ywm
9*^h6/ @AEm*9Sq%eqI*PX<t&nqI&CWykGQ=XZekTX&eqE&+mMm$R/!8Y8@JXFYMW>@RNbe9\BRHJ$EAiQVi5b+
QEFmEW emRSB?ZdhGwHG!m=L8CMqk%+Ce#5J<nGHiX*Q1i^m:nFlb1L1laHI4e^w6BcFD9H=aFK+J//$DPQEd@I
N<n:NI Fu%n4V6u>=q@?Yhh!cpD?q&?edFR1tTL*i$8iZ1*m:qLhnA$ePcw#8=RS%JM&!XtYJLDWZ6ehV9tDYQZ
>VQbNK tHBiBu\6i%KDlW8aWW?*pcCi1@&ayYtpphyLt:TRqEtwV?W/pV6yt6qJ6FJ:HhCBqutyPeYe/NQ/JIqh
Pi<dp# S<t#^44ISNb<lwKpMEZG@5ne+q*%<MT>DLPm<GbJ4P=k\5AlMmjpnMpTN&mm/hRw1Tw%w+DEltJyFAtF
qBCMZ: :kTP%MAQ/ISZ/EGnB>nh+6l8RnDKwVS#1&tJC1n16d1&hn=/*VRT/ELR<h4lHHVCat9tH!=bVYYHN$Am
Hd!!ud HIHlq\I?NL^Eua9JcFyit*:bb5Wqae+9lGA$kwj1La1K46F#/+SC&d!w+C%%!ISE?j!nlKwGpAA#<R!$
TM:a*F wWB:6QT?l>MJXEYy+l>V=W%Ftdq*DNwly:!lmQ+IXKJyamHSM5^tK9R:@lXBXSPWR=K1Fimq/atKFc4T
nSQPnu ^V\%ic+qedEeyEYYd+m\t#Zk^>ACE6$^i#JF5C&?WmPA1cnSec$dqhGhFEpTmapTbS86BkZ^?<SI8QGZ
aQWMPG QLuDPZlbC*u#XqSXPhD$nwtD8PuNi/IX^kPIm\G8*<hI>8H::EFb*!@BPl?Gnj&!YHn!Al/W8<TNpY\d
hSG!%# ba8VXdRPPZ$49:#9@I\EEBIW$YQIVumB1jkmXYk?KX\w8tmQ!/caWh\yTQ/DeyZm@ISLp@yB6^+y=8Hw
yANTTk e1wYj+J1^eCMu$q*MHE&WnWuLT\PJLpMW@XkY1<Gn/\#1whM6i4uP@L?\+J^MyQTpwc$uKwFc\LqFMma
AF4W*/ %Yl@aJI^q9bnTXi&XdtcaF5ktuJbph<m$hR1l5*PSSameC=k!$wyGV^ybCtqB%qWDJ&#hEG*$e86NLP&
nZy?<& EEF$MSkku!8cX?>WY<6^X9hBy?1jKNLkw/!J1MNq1TjSZe^D$ZHL\K4e6<</i1EFckl9patkc=$Z!6A6
PTHh^d @nuNE$G9?cW=\?!Wkn!jK^m4yKXX!eqJc9E%J&:Wew1JCqpRuKB1Z/bSFN9YTlGSbbH=jAbNkw!/N#Xq
<%8?Zi hB/yTAN/SZAl$ji5MR8K<I=\ycN?>\\p4LkGNhS\wybeKWTaEXH6MEhM1YD=:AR@1<ASRdARjD^Jck6>
\8a9Gq Ph/MCqHya$JXQY4%^Vl1RJD>YZRBdYi+CFLlbiBddS6KW?p*tJ8<9BbSeG6RGy=be/6>+%<bm!4XFR@y
pn8k>D Wi1KV?AG%WL=l?lLPc%iCL4CE6B5yR*mYlFB=piXI&i$n+jmi#Q1RKY*mWWqEw/MZ<ad%hW@ln#EcDHA
HdTP>b tluPMkeIiKE?ykWnP*a^lCl81ammmPE\J/n=Y&nHKZ>m5JX^+:G8S4&bl1H#GBHmj&Xth91C!j1G5$WQ
VAR%\^ 8iMERjHZ%BINN>!l/kWT@*adt&w4BeW:elYJj!@l=Zk/J$IL6H1B!N:Cbti^*><YuPCKtlR1PRem/14H
6LACNY 8XIGXX66G\\MmBc@TAF4:EKJSLqY$qKR?X9ccJET+VWTX#TMy8qRcyVX\uDT4G6eSZKun%e&d5t*\bKE
Wt<jF# mKdTV@w%KMjNNB%NE&CcFh9KIFW:EGX!$eLpukEhqZYw=qmRnlLMd:1DcpchlQpyA<y:mVPWF6!4m*Eh
bNCYY% LeSe/id!&ENW:YeVcLE!uC8yJNSLP?y#=5yca<I8pkc!W/X5<>a/G1wudQL^K>KT\#qq$+a9=9B+Z*J/
4#uKX? d^&j*$&an/?ekNwWeX$YnD5KJ%WHNT<D!MyX8n%E5nXX+4Btwp*C!cJwA6IiH%@d^hVIk>&p9DT1RbkB
u4R&8H DkGjElGN1KkYC@45J*mmQyi@:n#/Et6F#CRSN9C&JXX\hqeIIaw:A9uqX^K?c6u94!/YS6%cHNi*dFnV
GRZJSm 9uX\%8nW5>jh6ScCL6%!>i8:mQmkGd=kac:j<qiM*i$iS\*JXNP>D&mMR*AbaJEdQH%SRXJIKT<tE+Cq
n8pA4Z 8^+h&S1yPdDETk49hd$*6W9iN@lC\L5%:V6ubTkQ/95KP<jq<%T*KB6qLk+nY1eLR?5dNAEn#j6%9lH/
e\&EG^ X=+D6FCFa8WXD#CPEX?LPmai%IJSRbW9Q@W@Sqa$FajC!6Nk=kE&G9eQ/?FP*jiDC5aYGwMjc59TNa!y
wXKS^P SqA+$M$PMYR+$I//*KhEY<S?\wm1N$aYNi=jnRWd6ymSc51W6WmLn++XTht&wb%wNmFjma&qDyt=G+!!
etjRE4 FJ^41+W*#A/aV%m#bBZNFN8nbq5V$=<?&l>VVIp&=a!n#l%n?y:$iA\G=cEbMnyE1u=l6/IW>j>Ch@hi
te\+^# FD/<nej$aBBYP>%^bXNCjwK1ak+Nul^k8#pBtQ1m8BX+aA<p*WcQ>S8#j<DITWB\6JWq\ya#BV9mRJ>D
$e$JD6 Y=+P^A*^KuR6/NtEQ+c!\wqyQ5dlQ+a4L5b$*R<DqT4d$Pke/^C4VnD^ACe@qKSMSTIYI5IMd%H6:?X8
ml#aQt Mbpq1iTlW>G\W<8<HT&u=EQS%XFu^t$$$c1Tb5Pd%Q^/EcZFS<IZXD@u8Sb9mKJ\Ey6bIDGewEtYGIkh
:@Jpnw Fw!G1GLGZ%AjNqud9cDYdDKL4=VhGKhGLHP1GLF!HGjWiqG?DG@t4uueyS?d1l?8GHdCWiXIuF1Pd!^H
?H&kti /ltYq=jjJdwutCCiHmiBd++W>u=L&cw*YZP5\9&W@\hX16Q\mH>qkM5Z!:wC>dwmCPW?ZZiaEwI+8G+!
mkZ*4J iV6jWSVJ$y?=1d9MZuFAB<8<RtFmcLFkEM8\q/:C*KcQ*>TitbwN9/KRXBS\Rwt88Xy?6uJSVZ&PL*%B
Em=\T= LQRN@X<K&b5D&ZXSLHW^j:BX6SpY&E/eF&Nlqp&PA*KpR\!bD6tXEI9NHbn5qN>bC=aEBySTh*FY!ud%
-A*9/@ 0007d14ef7e00110333 Page 314 of binaries1.zip
:RZI&6 ?tq5qau58y98$*FS8Z@9Mm>p9Ge8wbBSjISTCwLj55/K9!e<iIH1TDcjS<Xlaq%@tK+e^1QDKG+RTRt^
EDhl=R qC\DGWHCd#l6LI?bK6CPX?yM\=NEJDYWhN<G8WBtdj&6NTZ#pTA5JYLtjiD*Zdy\%nhbK=>q\4Z!mbFK
wZwK:N bEZ/m%R91:GC=cZDakkyhpEnmCpVeK!>=PABS8LLTB:$D=#WEC\V4=<Me/4m^tcY&IG%yE*B<k&:d:nE
>AuMck QDTy=e86njXukXQ5F/>#KnT#dB&t81cBJbQtJ!mKD#IB/R/BB#=!tLqlkN\^9#^AjN=\%^L!Nataeu$M
%84ZXR SaZWqwd6IqL%lXy+S#1RJ4!KRjQd<hn?Xbp#989yTQY^bmZauJ5SQ5EGVcnHu\<4MnjwFhS^4MZu=B<+
EK<cL@ L>Xamc6L>c>KD1>kQ?W=cMlkuidNqZ&yMLe%uJZBtQlGp//&V@=clEMZy@u%=JYw/^R+wi1<&qkb6+wV
X@YBNw n9nw1:KJc5?Ncn<iujRXptX!KQc^6VXaDQjL+Sea<Jtc@L!T#M6%bNqKJbb%B<jYM$VjepJ+=Ml6lL!8
6QW@&M ahZa\&R*iQXcdGN@eJn4aXqm!bb&<XAHKpe+XpYaqHE!a%:kKDAtpmiwytLlCK#lWJbuPILPXIFiqIYP
1@e^BW #n>tyb1\Jami6bXaHK!/V@i?mDD&WFTD*pC>u@*nGG!pBBZm5Hc:G^6WIqk88y%IhJ<9pCqP\nAtqN?j
MDPJKR ^qmVi8#<1A6iYjFV8ZFw\TD^>YF$Q=qWlTI1Ld%A4ye6m/8ytQ:wl#1qQF/FBZ\8qk6Rdb?#!4yAd6d:
#KZwN> kwGnL=pCbdln9iK%WtVtJlh&AF^RHC!X?PNkZRcS6SD!qnu!1GcFYR\TJ8@wcNYtBQduAakFyjWT+DQ!
#AD=e? LlV$GJFpk^Klc:#l=T^a$AKIN!@!PSphb<5bXwB?6PH6cLIp<BkBBh/d5w61<FkA?&BT@ND5C\A=+GCP
?VwZN% myC1S^I?HNF<FB&B15HCtyAhwT$HywGGa6G$6+@T+wA&eIy&%=YQewY=^@B%@kFNaI>Aq1BaD=B&^+5Q
:G6emL HEt:8$KZE&$iiIE5GPMktMB5PJeLX>ihA$@9q\wLcEDJTWaN\DVCknEkIJaZFBV$5+dQmce$%RWCq5kB
i/eIk^ BZ<+RCVk&au&!P\eibAJLky9<R+iMF\!YP\6AA9:LCFe\wLyTF6Fcu8CtZ5J5%6SINFt8+Bd\k<mWwp#
9BE4+# 8Yia!NEL!*TTGq>6E:8$L+:a%VkZFjM@?>D:Ye+nw+WyQ=kyKCy#?AhG!GAJK9SV+:^bbcRHBykw!Y45
%cPZA@ K!bnB</GyIF:qjdM^T9L#m5F#^%&jYVtcYZhHDk^Z@h&P#SGCH%=+N*^y4V++yln+CB5VyN#:XHLF>SI
??qH!# RZ8K#\ah/n#wSj<S+9KS#^WGkQ=hHJbA^9Y:my5^&HBHhQQ#Ie5dM@hAyQicMt@I<N+a+nIba:@?GCaL
&EVpXS &?=S5EV4aTnHtSLK?eqnVpCqmtIdeGk\!BJ&bRRH6FhG4PPmjlk@*Lp=*eip&8MhLDC<&iXV+#QLJj68
Mq1k>: #kA@bl>N=ml\LN!q5I1VyaltKIT&u+=piR9C*ymaKkVLh/9pS+mKmHK/uip+%i^dutj5B<Wn!AhFFFX*
hS4DL! VYTG%GnhFB*npj6XJF5JnmhY+C@*^&:ce@w%m:idaa+lHkilK!SBN9$1KZaDudWueDW5XSJa8F!8:6Ep
+^6ZiZ qEGF\nX$^+eXKcpIT1t=yTDw=K\Cy=mFDC#c=LQQ<4hjh:+Q8SA+%##Aytu*y><QT<hNG=e8^#?tdH/p
R4ZZF# LuJYt5:ALukMP$iLPTLkJka4pKJN&I4E&V:AEiBTc#:Nt/y?$/B!$5FS5qi+TC?jRqZnIeyKYjLe=iie
Gtu!@c HPDA<5?AmekP95/y*Hwee$8:T6l!#a#FjbqH8PM$MHCpSyP?:PmEIAF^8p%CL<4ILbK\\K=ihpnc%Ww5
V>wPe/ 9m%MCdM<e$p1KWZ<kh*H<=/DphSYnQkwW1TWPQ$>nE<mZBq1m%NmeVeWeh/BXpkj@a<>F9=#+5I$\SF$
q5%wL? It?iq1/&+:whFwN!T8>kDM&FCSj!^IuWYppl!JIEKEhN<A#6HHlEh!5+E?6tGy/=!<t+8$NXl&?u451T
E^*4Fy ^8cW\$N%M:P=S<4dl&AYl&qSuY!ec:$cLF1\d!N\!9P$b@@P6p1FjTI@GK%BZ9qyZ>u=*nTWTHA%%p?H
F?1V:h 9kE>Z\dyS#VneJJHAl?1hc!uKZW>hbhW/c\BT6mujXi^j5<YXDp/8G/t@R5VHj6EG+wt&GVWWBWiWahY
*KBCMY yNbYGC@X6AyRc%mXB?@4BhuNw\Rk6LTA<Th/#R?SlLbMbHmP>#h#8Sik6#<:ilI:TZlaDAeE@aKRKCdw
kqQK8Y CwPa68Ke5y!b6wKRATF<\lQ@1m#yES^B*Q&ERaGJSBaGC@ZW*/dZ@&A$\G5&+G$%$Ga*<PA$!K5NIQWe
pNG#C^ dQMbjQAjZLMERL*DJI$ciwkd=p*ABEANGZWRQGTQ<PcQiBeQy&iMRAGRwcBGhG6H9ZNH&/1H&<\ByJ<I
tZm8:i H8yHhZQHH64H%4yH%kdH5n6iQhTP<P=PiGhQbGWQ6jWQ/A/QRPtVQE^Q4pPNi#?Np/=Qyw?PbPCN6H$j
1Yc%N& +B$m?Wp?\$e>+$M$=B$^:J$+#h5=*Ya$&W+\ty+=Suw>5<+&akR%@DA@=*$:^Q6&@Nh:H4:N/@Gk<%p6
Zn%G!4 6N8mp$GN?<kV@ERb>eHw*\K<Iuhc<ut@=Bc%!N5=1>5:/dhF5LW>tLY:%KY!VF1>4Gi&BHZ^m9!RXK?J
+bWdHW XC>@JeNky9*Feu9taEaP\a8aSV&SKV:j@9ZAXcHL%jdPhh*q1ZZ8Rb@lqSijq<q>F@lYB*%1X**&%%<W
cIjVQR dtT<Zjt=951Q6/$ZNbS^P:j?hhBHc#BDdtZ>cZ$>e:RLcyijebR$dwj9&<wu#4WZyWNb&Z8QCu6RV*9i
AlLF#! Mj8jZk@^MSE<iLt<i#H*$t#SZ^?V%G:R@&q=\&yc#^$A>auwpZWJ1uQ\J<El@@6>9jYXDj@lu!=Hu>Jt
*tpN=b *lZQ9Lk@jM^j*/Dh<Za:/Yk@ii\?=i<@yc#9IT\ll&:$XJ?NKEHZ$iH#cQ$b4A9nb8\1<mcnc!tY!y^W
ZFpnE& 6tEt/>%th<:\cbhBn/BFV#y#L!tpN/m/h$&wV%i14/8*H+DZ4/6%/56<<eR&>1:^<y*utJEZb1dRqaDa
/C1u^8 qc<p=mhBAFRdRcjc6c@Yhcji%h4k6RA@5lDT6V@TVcdh>%eCX$>tN=t8BJ$?N=%1Q\Vi*AmwpuR@*V^y
:ueCEA *L=K@QEWn&\RMbqymyjh@9&y?G/#>KdV/M=A::/#@h/HqGT#@<F*?KHV:GbV+jJJ=my#<61*i:b#>Z=V
#58iYI +F4A+ajB=6K4?b??Z/+F*n<?1kPkARB@\c%aKwy44!AHXy*JK*JydIB9*++jkneFG%ERkP\<Yd8?VVp\
q*h&hW t$JJMq%1p#=Si4F/TJRBk9XBc9Pm8W=j:&Z!MI*D4Wl:lqCY+u:%eyC%J!lBeQ&dbh%PFE4whF/N%ePG
p95@iN m6nHun%q?pRGG=F5^XKXIq9?V9ZW&jLEqLEiIj&<qXL5W8cZIJj\JX9uWY?YPLZ&Yc9==Q=H@cB?@aLE
^Z1\PR MCbnI\^/$^FNJ65N1uKA9yGnJ8=NJTQA9Jlw@4lil<4&pLdGi!NJS!miBhJ<TDZkC4A\ASPmDVlHJK$$
+LBp$Y N1Z4e^IVdp!iYPua8&KpVB?=*tZwN^yWL^?G$8aALiuCyd+t9D*H@NQMPkjZ@^8b>Z>Ly9>nL9*=!ZIP
FTX=JX :9<1Ye+PBIL?IXu?/$u&9$?Y@*1P:d?ZLPjt?49W?F@n>*?jGiD<p@\VB@h#W?PedM>BR*/Hbu<P?ueJ
*5=8d# bp:RM>AR46@W%HGCu+Qt?E&CtSQ!HDVwN:YEuB#QRdQ>D5*=DDTI+#j=Sp/8=/BB9<paeuI@B@&:jCQZ
bATVwE e:nG#9YdQC9Ze:nG@45<K>h#8MaP@N&?Rj<W?nqea@6h%T9Ze:n&?:R<%:QI>49EPljuQ+X?F6p+jpN$
&^CJJA L8=@B5*>4ItN+#jJdi=uVY!@I#w*?#<#c6#Qt6k+j+h?%5RG@k%X8TH@%Kk>l&5e9:6E8b@F6h@JMQ:P
:=RK\S nQ?9ewV@uDDQT:iDju%Hknu@?H$AIkQ@I5a#<8*@$hyj<h?P+#@N6@?6CyqX@6he\k:<l*#:4%<B\Q?B
wQt>46 *SuH*?#P&H:^<t>&b&#5pQ?b*^tEuR*<d?q>WSHXQ$u9Q!$>uRHRlZ+h6BuA%A@\/@c$ClABIML@ej6%
F<aY>Z n+mKmICImw/MmImMnwtGlw/GlwtF?85iHSWLA^5HF\edk=CRtJmRpJKCkwKT>q>9V%$AFETAD/ALCwwC
=M%1cp <NRHtQt%aRTwQ&/A9>=k+YCk+cEACIlI!CmaAGkwGBlwYGl+BJljh>A8WNA\YLAAPHJ5NmEqiB\nCmh@
F&CNR> ZQc+dAT<ctHKd8ZydSC?<VtXe<A*clG\Tu^PnaqLD$TW>pN8LRiB11q4:<\PIp$kEnIlWXCCtHliuj15
RWe*+# Gl*^^i=q*>#iqbqdeGJ?jj@<@4Y=i$lTReQA\5ENy+TG^b9Rn+YNk+8j9*NJcqy/lCWZNR$6Hj/k==dT
FTA1*c 59J<u%LeQL^<hM9AI/%6:SYiY6I!5uJ<>:RPkAYkQ1$AEQ<+JRFA^4nFkBc8*mcA$I?@@e*8E+CwPqNX
wL&R*> +GLb=\pk6il:4eM=n@HRaPA:+:d=W**<Y8RJ\Q^^<!4n#SNA4hbH<Rp\c9d>J/*iE&Dih9N@FjW$qj+j
Zn^6H5 kRm?d\1QnEmW=8*Lk^K^WmAw%j4kekGj4*/?ji?$u\DFAR:*:@X<j?%kS+Dbh//d<&hjSih^k<P*X$th
l#9Wh! ^+byn#5cB6e/dJi$TZ:Fq/lh/IXZma5@%Z9yW#eR%V*hWPdjH@W@6u5IFSWh5ZW>AjLAp*e6?p?AGd89
cKi8SD Q>ZG:$Spu\Cq?X>@$t#<PlDh#j@$XjZQ<W8RL@p@n*:AXk&^XmSnYw=a#tKK?#=NH:w<AZ^b:::ejiNh
yYnJqS 4nWjV?P\Zc=>t5ueekh5>9</\?tDJ<CHYPMHnT/jJaqTH!@GYpm<DKWEqGYP+PPHJ1uWGIYR6mRk4<%t
\bNcEQ hZ5udVC^IuhXKZTdyeLy%A@ZLu$n6b>RJdaCG%L*99%&kXidQ@b:u\CE&W?A5F%YH+QmNT>AZR+uY<pe
NXheh5 >ywCJ6jWha>j!=+h<hGbSS%Y8@=bMd*LcCl%uMkD4dM::lL/n?IQB6GYu8I^TKbcaa^KI&JcZCZF%Jd9
c?y^j/ aJVEKyuQ6^>H9cN^?y<AhQYhD>&@@6I5Cn#N@8t=#YZ8KK<Pk5wm>jSkGP1eie$nlen8dP99KWt8Jb<A
<%Zy&d t^>?ncDwE?BclZPi<ku\V8EZJ*B?ncD5yt4M#%8Bu%T@uqBnm#>ctP$:q=*qXT/Y\11kIW<MSlSwP\Q1
YeW:E9 Cl^?C<5BWQlqT/LT6YLW/@1YQTI>ARCh5=^@<tDRt9aB?kpk!>\b#kW8Nuw9QEm1m!Xlykl+=i::NH@I
nZV*PH GV?IM5p$lk$&6*BSB5DPuTL%ap#>I8EI@?XQ$L9A#piq:=qHcXe9ukAZMY&@N4Pb>jWJpPD#?e:<J+L9
<ccJcq R?=ZkXuP\>hQkQ%Zuw<yuWKd9+dtj9J1@A:>CZA45iFd+QCjdi6y+Xnk@?Dt@9HRpGnudP$?mYd5m&BS
%kuZ*T KF#y=CC<:MRMTQk?eJ#A+>c6nq4AL>&dDS@$+9JyMe%t<!6/:tNib>Fu1W%G:@bLl<RP@X8hk$%Y:@KL
pH5jeN :=NQW%@9>^$?h1njNw:?:YZlin*&+@%Kau4G+:=9bVVyup=bpF%Ft/@BQApP?IqW<uSH$KZwhiTC*E@V
jS<?N^ @&:4p9@Cn%<$EZmc?j19jEp@ajTEZa#C8>=^pplE6B!BGj#+a9Gn4wTT?\jyiAuIG*?6tQeMib?jb6NQ
-A5NPQ 000c623bc0700110333 Page 315 of binaries1.zip
$k^$mM cLB5*m$m/&QGy/kyaC6Cc\i=41IR/EWba:kWdR4SE4nk/Mu&MhDFyydG*bApCX!NmZMX!Iu@*EpM9=S=
*P5a6t u$^Q/8W*j>^q>#+V8Jyt*m\uw?mt8My$GT>NAA5#ptHCqd*I9Gk?>:ZZPb:>W>5%BubyT&N@QR!G:eLK
RN#GyN i9%e4Bl?1e@EuuMRbG^$!AqDTj&e&?tEVddCeK+!Qa@bthGFJ=D+XJKy!&$X&^i+MlC<1VIH:WjW/iMw
tJS\Q> CS5MAV!P91V6&yp=Hwad%b+5&l\+Z5PL/89ZDNKTR:V9:4h=L=DMNN*DWi/n@9:k%SHP#:DH=Z8D&uCy
X\<+AV ey%?\4l/uR$ceJyNTphjyLGK986/Q<@PDYhqpdB=+^^4iGth*YMm^%nu/Z$+X8dVZMb=!/<=Kjn4V&1=
\$VyFy J\DEjN96CcCB5upuujbwQh=#<qlB$HtX!Qp\u^c<?FPZ%jiI\iG&qBPq<1:yn$qNhjNT*b:A+N1^@he<
^aXh/G YN^=WCc>eLc\e*?qa@MthtM?$in6?%CKwyyyuW#mSJM?>eIISX6H=4NK9KCBnX&XD8^knC+>ce%mdIn\
P@lp*c bjHn+a+:<aw%1L/P+C=kKG\GcFN+YN+*G%t8**uk!LSlcpt:#V#@QW6Nn$yuYEayX1wF^LIFZNc<HyD\
#Jn:d5 6TqcF:HC/#?6%wPPj/$9VchN!ath@pniL\p?>NwiKMl&Ha=%%j\SE?<H@?5C@tSh5CdtiX$qX+&NFQC#
i\$Pt# An/:YQn%&?&QQ!B$/d6T1L=ti%By&Z4L!S?19<c<XIaJ\^KFB44t$Qb$PcF!Lp&yMD/RyZ6+5Vuqe>%b
p>cAH% TTN@pj=%@d^:5Qbp^&XSS\\6EuL\S%#ta+DTC$W499#YV#ATVKSuE1Xu4SbASlcLP:ZayWKE<TG*WT!c
iF@WnZ $ESNFT9G*/cQVnD9k<y=8Equn*CbD%*JE<D&ZCHme<i6\n=5dJKHMbMqm1Q$A$Yk%\&J8T<hXYRqFX56
+lS%CP /#I%ht9IT+F>$5ESbBpea5#yMnHyau%EKdWh:aRj$R\htwu<ZYy4DTP=L6WCNlY?V\5u4:bQKk<iEB:t
ZtQ<L@ E^>j6n\cjei+LYX>+HN:&QS:A1VYhQa8Gw#^d@@^&V<BMQS<kjilD@Mj@*muR=j98Cc8y@mY>A#VBWQd
>nTJY* 5QM$@M8WJGBJbXe<A#T1$pQSlTTNI&yAEKhIqhpLpl:^?$5MlydeAV?K+hGQGEEQP9XEtqmLDbaQSh?E
u&mLG4 a/u=8PaaaJwB!Bn9$#>>?yF%MdeVyJ!dujQF+EbV1G#\TE6QR98dMtQtj=lc@9*FQ@X9F:@F/<Wu\Mdd
Ad/Ea< #Y6=*?jMFj@?:dQ@%eR%>+<Vq@:6SQ$V+Q8u:#>XMy@t@&$Di\9*P9Y#leB%!9D/Fp1!jjZtN%FRS\4l
^aY^kJ wJmGBX9:qDm6ZNMk*iFnRDcF*j^/mTA1uQkQaq>&#XZMYcwIuGR?&l$Je8eLCTKGNit9YCe4!cPhHFae
:wh#J/ T8CQL$61HQe^yc88Jin8Zkyk#$Zhp&Lh?TyRPdEMtYK?l@+!=D?TFh5dTpceW*@uCP/\t<E!hDXQyKG/
tnXQh9 EPVH\#@!$J&Lnl5yCQT=GSSI4c9uhIw&%\FS6Jqbc9aVyVS>jTnhlH%M1/P4wbA<@6dL@p&y1hp\F8N>
B68uQH !AXE<L#kcpDuNpc/lc=lBq^JXpJS9QiP!MD5bAd@khhyMZY>94\?j$%/WWq9lD^tlk!mySi/!5Cw8m55
HuDl%= >uyH+WCG/y1SNKkuPI<$t%VLFLQPdpSJHKP1aq!p4?EZA:<+XGluARdyE&4JR5M\^umXGGLH/HRukt&Y
V<dJRR =tclyA=PELe%QFm\D9VXy%5\NtBiqbX4y5wnc:T1hAa1@mVpaa\KBFlhn9:nl:taeX^X*5eb!^6AHT6b
K9cbH\ Vu/a6dkDKbThPWtNVbjl8$p:KWi$aw+lQ\w^qGDMcHw9@@kn=pj$X*pMl5&n1t6Wmu41BkFMyBjhjF=V
PmneiH ^4E&uGiqjP$d!W1IhMM&=:p9=bSpWlqjKdX@:*6=b%MZ*:XtbW>%:$lhDb<FW!WVK=S#$$?=aG<Wye*a
+A!^JV Vp$yuK/4HR:#Rk&D6i^c4&9EAKkdimY&pX\tQ&I:E1D^QW*hEiQ:Y8laJ1p!u@QD$H8<k!R#qw*W<1L>
Qmt^MR !T?htC\&w%:ynR9ZTQMdM8Q51tIMy\66jq49KM4pB449:k>+PuIyS$I?!:/=^&Ghb*kHP94thB&#ek@t
m?<LCp G4+iZj&^&=mtPG51PGKpF8!Q$XJbwH!I8T=aRHWZNcVF/Fuwl/ZXI$S6!bZwSV*9?Ty$l!Rn=N:mci4n
imX9>t a@4dSkL^T#u&eT^G6u1Q#XqacLYwpby9qlJ!e$ZeI54:L@md<<E&<yCkKu*E/Ym<ql?Y<b\KB@!$1Gqn
d*ln\@ LY5!*+:XEZPNhJ\FpkJ@H9*/\iG#m@QTdu:bM$y?^M<bWl>LDJBcY6Qal6p=@^wR$u!k$6SYT?qWZ*yN
$TG*4^ <84H:ilQ!IHD4W*h4&<LnThAViStRh9+4^@!:yqZ+W?AG/Y$1<YW#9&K&ee+k<eS$L9WT</H?lZjGeau
in9my* \LK+\/#?4@py1XZlV5#*ut:<#tb5<&LS/kpkYjpEMCQWK*56biL<XX/Mu<H&%!R!@iqajij5>cm/eaAV
PGcbYe qhlmEV4!uHhy5NP6m&#W?pk6QqZq\G=+DiKIN=Y14bWB1hwXH&Vh%DJ=KFL9%h\:wjj:R!@Xq1:PS&IE
%!h\L> b+#>X1qiNdMiJ:D5PYjn4ZiPeN*:pMnZJXw$l8YF$&F\=uPh4?GIXHMq/P9QbP$imS:%?NM#hcI^Cujm
tBC*VX D*y=X>je8pnHtd=MK+/DqS&qZA!DmXGY/P%V#t&k^\<%euB/Mh=Tb^<QHyh\J1!ymi%?@/ySX@dYc@Aa
hZGtQ@ #alEMu!wPwW:jlNk:jdhuTcltK9\pJtQ##^at=9Y%NMk4hyeRw9B<?W?uIK8wKiJ:QXiatIKqbmCR64n
YJQqqp =K%8<<9X6<cBw/tCd+#kaAMm\!<Aay/KjuQ=kqpFe=NQM<u9R1w?+!TaY?4MCb8/jA8%<wVw:QCtb#\+
!e:wCm M4*Vt5*%$HYtRH?Z9Hi6PHqMC$&!9TY@8Rk4qcMyQ%N*cH16>iwLpHJYmDk<WN@9=+@JKZ!GGm4hPFQq
^K8F1N LHmV\Zk9FnH=c@uEeuSmKLpPC=?:4*?=bA*qXB/=F%<hp#:NmtnQ6*%uVYalt&Eq%?Ge5&iK$/bd#6cW
&1SmNP ^W5<#k>j&BiVtF%F1leAiX/MDFq#iNXZ=NwMJ&/5$GqtTh4bp%aBj5cWB>qDh4wYaYqcQ:?u6jGhVR4:
6REd=l y1&#KY5ck1eY9Y$T/>D<A%?/Z9BIQ&&u=XQy==<5G&ii>cYed\X$bbD:ChkZL1Z5n+5$Mu#jVL4h\!q+
C6VNcw m$@1QHR%6>aH/Gp9dKAWpYY\dBC&R#mSeD9Tk%m:qKkQ%w:PT:H$@HG5!n\HXEb?@WkL8lJ6M\1knc%h
Q*Tyan HZcPK@tGS#YAwHi!&<B@@H&!\TnXAdnpXJK<dC!PVcqLuT9%muDaVIYYWtmY#91qy=WQ%TZ?J+PhH>KC
bZp+IM BcYHIewK*c4ZHY!n&<n!Q^BpLlE?ZVMm85GWc?8I<VyLEcaTDu/ZQb:uyXha9#:Xp9BG::C:LI:Sj4Nk
IJBVDB y%SuRW>BTQt!uDCLVl41G>d=>?/G8?<bLLRet+XjKJLADjFK#G*YkNaGt:u6<@k%Je6X6!Nh4D8S!bM?
5/mqhA 1R16W9!h/V5qq@%DH+8AdMZVW\=F?Q8Z6$>#6DE/q$ec<ZdYE+kccn+aC$t+KNhBqq*GQkLB!ENntqjI
P<VRGy d/h\*VdBu4Nm5?Xj=T5htGLwR##\Z:8:qq^GFSQc6&qyct^VdqJtZ6T%jj=%QXe@AadCPk@TN@?Z@@@k
1e&l6C CSy:6L@Wt>>9c?q#q:HC1DC>1&PlH/I9>=k66\q%ZL86&LuwYYH&b6@WXulnWN^DSA#@ulm:VKJjC^FC
FpGaAd EiVk*!q:w5CTPcy^>=lb^NiH#cnhD%WGBNjDEcYb4>bd%R9BQkGi=yE1MlC8F9LQQVM@Llw5@mViQe:W
hdV414 *mhkqa/+cjb/>\T\YEXt\Wn5KHc/446<M*j!tHnee1i&njG>:WQM$qZL#i+Z9*1eY>@HtD56*uEF8Ziq
=+ZdHq %+Yl>^YM9VQZK1iP8>J&$wbcMj5P=dRLPAdZ6/<$=6:ci=><e>=LLQhcSDB+SjFVj9W1%VQ*YFjn&FjL
c6:y4R w=&Fq!A$>=mY&DGj//dRq4q!Z?DCJ9Qe9jNTuNZbq?pJ+HLhh+u^ZidcX?*LE/B=M/b\tH>RY<XY8DQl
j>muHP CVBe+h8><kRaJ&\L9bk<49IcQulXw9baQ9:qJ<?e%/eMqTk9=\J!k^Hj9WYB4T??B=EE44+5%p<AQRY&
k:C64X ^Wn?\4J#u$!Fu/<?kw?Pj5beiNtFNV>WZR<YjVK</^jn=89p?VJaw4Gj?dRRQ8Ihh/%V1ee:i/&k4XDy
+*!*/L +9FV\CBh9:FehZe!M*<$/ZyZj$u4*?%p@1H\We:qEZ*^$ZL<@<VV\:RjJlQiXd>>^Ji#tL64996ietiB
AEmFAb WZyB&9#VnW8=*jFY:8QmcV98QJ?9<Mu^y+nDh#Hb+@#%BuJ<4^wH&l4L4VbjFJPA*y4eTdtS8+*+F1Yp
qG5Y5C !dDhhc4d/^jN#pu>ZJV?>j&=@Chy+d>tS@??BTaI\9%@k%ZnN^P5@?86Gt?DJ>?KE?emi?ZAMaTn<Je%
4V5Y$d jL*4KKe@IeP6SYImJRVBpch4a&KR!:#ESd6MWMi61Mb?^EXqdCWhkQ<&5m@ajWTt!Da=F4VLHR$qB<$n
Y+EkMu H1GyJN\h!L5*BI6V?yEA4k!k\lj6G4+5I??cS>#hq\mSpqW=Mi^Fq/8&QS=C?^C@%A>Zl+bAwLB6i6YA
ea$\HS Hmm/D/@l>uDa!=KdV!K+DCX+yBBTQdT1WIPN9T\&?+hX+%K>uaKW$Iu1ywQc#dYeZ9R**MlmL9R@:BcF
*/tqak 5>/#lTCl>4M\abCP%a1W!5FwX?B%tXlGq4cn+16Qn?K&SPd/nTK5ePHqE4MR?muJmLmW8$kFe$SFYi!/
<@^au= +!PbtKmmEhh4LX:LN=p&:ie$\wNS6=PmG>n9>aBPNb8E:Fl!cLEcty1KBP^qLicW9FI>4uNFJRZJ?S#n
lKjQ/d t5aJIhtyHHid/MJ??>#lySqR>I8SkEj4:&5akyXXbyV+WXMJ>N^mXZ*MCX5&Xd%mXXkQ?!twEauWwlmW
P$&QqA \bp6Rhl+Zi!\MA*a#SI&DR8+1LNSm%TIM!wDGhL5Z5FnYWc6Bc8n&CNP#KM6%+h*kmS\%#BIILQZyH5+
%\VZXY GWFDV5uj4ZG%dhS!!WW^LbhjKJlMRLkQ18:AA@BKXC44+wTb8QW5KB<@pFdaGE=9CDGij6b$&=Y%4>9h
e$mSZ+ GFC8b!eqJj4t?ddTak*wRh56heMWakS9lKIC>W$^Y^!P>+e5Cht+Ae/AF&9dVl9u!FQepN6deTEEe61T
BI+yTD VJ\+S#$=Rnk+RhX&kqwVA#w<WEDIBwyMpTLeNukkIGlGB>yT#Ce4C:@<<+\ypjY5aui*hqIihn>baKZ^
85F!TG BFwK9Kdy:Zaj^NyBmT<Ee^8NcI$4?F#w1A=iQaNIBh<IYT1qy5C/MYP$V*=59aY#:*\Tq^jSeIm61??A
bd\4YD j!RF!!tCwbw9^CK!LG*%%D8/l&5khlS&llhj%my+LnH?P\IKWEQ5?H$$uRu8tE4YG\4JjIE?Kmq!jE$/
Y\D<+M HWq18hhX??S#KKK5p$4Du*CVbmc=liGyjma*Z*CkcbiwTe5b^pB!#^hq:\*l:eJ?bwEiqkQ!5MLS&#Aq
+uy%Q& *?VpEM1c!W5GAWPP9KNFc8GM!QPH!pYhmV/ht#EQQ&AK=qtm^ly91#wjdXGI:\ZIalQaa$VlX=uyb1Ru
^mCnd< +E1^i$hR:b=J$L1\WVN4Hw<C>jmwVd@KuP!ZD5=$9?4JNii^JC9wMb$uX%#b$GSEE^RXZmd:^B8p!^:%
-ApLdZ 0008121c0bc00110333 Page 316 of binaries1.zip
L>ybc5 W\J#p!IykD6ata!Z@=cmZDXiWPH+C$bT9*hnaGy4Hq!%ZknpW$E*HK5&I=KV+u^pGup4W4:4muS^Q^?J
e*L*m^ ?5wte#^Q!DkHu/!@GDnuQTIS&Wj+cQW?SSX#wkMt\/>5qtcTBiAd@WFm:S\lMcX+<lqiE6\TNKEicYaJ
Rwl!aD 8l=Y9IMPKQ@h#Qu?tm#4c4Tm$qZQ4Z=5#n*hhcWeyJSTeVpK@QC+E$&Pe4\mIu!at9bTL$M*>E?C$BEp
i!WS*= RqmYI1^+%DKFky9kBewZE8VaYS?ye!anTq/^IQY%FM*u9ID!eld%%=:X8MVmtnW4nVn8ckIcH=Q$Yk?I
kN1D6V +Qmnh8<d@^kL:umjGMI/uM?:N=ESZp+LQbC\biuDFEtmj%dT$4*5R41A*iIBX<Yq&1h6wPZ#Wu+^yLP%
clLwTS hW4Z?5Tqm9/d>4DESu:!8dGJnHl$9?R44GT*A=ZEd*DR<:t+Y:FG:X5B6>P9WjhYZAyAWey%#ju:bm\4
WLGuqL lnXFa/B=RhM5tXbWQ:>=ky=FjhSVuqPGEP>%mKL6RqWLqG&\c^AaLIwHw!JlSe>&1PDMw:A?#Rj@?i+$
/w1JFY 5hlK>+Z8C<SycqW&>#h1FESMQEXje4nE>>LQFX%M9/Eb/W!yeI>?5<&uQ\yL=uFi%>6=t+em6y&N:+/I
jBhdQH Q<5$%yWVQd#I?BwV>ZL\8!IBNu8<QD5n#ED!4!@&?DEyT@LaaQq4+b!yR>&c!>t&N!Bw?y#qBHA+FT\!
?ee6/% 8ItKmyD$a9c%8$8mRw+5Zl:Y8GbP?DdtXA6>ChmcG>ZX9%=^MEpHS1>Gky!Zit%q^IKSd=b%>9HpEP=R
&klnPj A#l!1<??%b&#%8yNE^B6Id54S!p?DX^Td&FSaKTb5P:bmyCFEa%@kT&Xh>H+Ri1h/Q8cbD8LRhmpc&tY
:^SQNC i4bdi%^u\pBGnQHVu9Rm#EuSJjM>PI^Fq#=FIhSmR*4S+K5t^!HujJPY9dD6SQ/1V!<CPiI^DHtPmQH#
%4!A6Z wTh4wXEhZV@H5QX5=Xh++>JB!6<5jIp^E&qDZN=PnCXA6?myI4ZXJFqN1dZ:$6y+@^1Xh^:9!?HZ%5c>
9!IH$N wi#wd@CMcnC6!Xm&q5pm@DAw4/441J&Y:c8c#%yAide9$yqq&bP@Y8V:e6l@Vdq9LTReL#G<cSPbiZ9a
XqS9ZG =I#8$umQ9yyV8W^/Tjm=6aXtEla^=TyHXM9kl*!1@:dPG*l>+:\CXSjaF>Q<<C!4G!$^MQK!Zp>nb%Aq
tN&1im Hul9@hNpRluB&N<T%A$?yBi:L@S9L%AuDhqPt*heS4@wde\q&PEPwTFCy?$*!bScG#way?XjHVTXeEe#
DiN/nF >KQhY@eK8cMpD6BdQZK&u&>6ttFE:WSNq?h@C@PD\P65I:jN*h/y1=Y??<9!VNqZC=T9B&@&hl=Vw6*=
RiNE%8 XCy*F:YtXPFkHL@&DXimH$++Cl5j5MQAil#5yWcVQqlmjyYjiM^FqGC6Gn>=lEWuNbw+Zb>IZ4Ew?9:i
F=GcZm PTeKZ%p\FSqVtNt9wKtKZ?+5bGPmF<aBGR:NGRnai9AdeSJD9akPY=<58YitYa>e&ym5Pa\58a#^YD#B
eXd^ER 44a9aV&ym4GN6wWl4eq%uTbVSCHdAI/mju>QPNi*Ey8*kY:aC#<t8wHlpj?=LP8L+6aZ^XVd95?AH6Wa
PHdJ&T /\CFYHa$+%*+h^ST$jNIjq=t?KJSZF4nm5qjcNHEqiitl6kC66+X5C6M+u/Q9RuHRC$mE$T%W$Py/yBZ
VJJiSd :IZJ?+=bLwE=1T==pw8E4qqiWeZW^/6M#dAdV4lA%4MRB>!taWl*4FEJ#5Y18y9iY&FH$$^BW<IT^a$:
FRmb\$ JyVQX$=*bEI:N5F^XFi\w<Yhlyhk<=kH4KC!JT^RWPZV9MFuBt4EdqncKp5BmlJCEllQhTu6R8ADwuq6
Q/#X^\ KKcMA=:<ePEAVa\mhIM\:CAVHkESRY6cH64wMkmMN/YXPEP8NtVZ8D9R/tY81LW^&!6KL=:k@qi>IX^q
4F^@8Q 1uTCiakZ$EnC>tnmDc^dkuwMQ&AB@%K:EIAccC\hXGb6LQPK1wGul^i?YBIBY==J<I@clhi=Hbbd>yMI
NL^u4A ZNJIc&^h66#C\8aW9HV:y/:94:n:8yblAW^hj>R8BE5WIMl*pqk6PP>kWqWQMab$\RQ5q>FkpHJ1+KMd
bqSkVi Aw5p8&JuWcdYeiJkL<#hF+AZwuGYFp/&8^a^qM#T1wijebTC=96$WI@bSchLpci4ej\E9+WV#1M@?HTb
ic1S/F N>Ml=yJ6+qeuwJ$j5KnkRCNM/Ik>AR9iaGI%nMSZZFhwu<B&bSbdH+?&ME%V1jdLwl$Q^X9dwjV#C>HH
p*j$Ay 4$m^Re8t1p=HkNA@GVF$hhA+:u:hacc81C$bbBjX%wA*SdiPQVS#6\!+pYD5KHB^uApGK8THF=dRmJY+
49MwZ= q>Bm^\bQyZV%R5Lj<NVcpblA!Cl=RL9CHD8TqF*PqM:auN@8Zy9wp5Mak8JlPY1R+TNI?K19!XX&ILql
4P/D\n ZH%NGSiWFM/MFD9>qMKBqDWCXP#muM4T%n%iqM:KQF6/%AEI\m1*NGS+NIc+4*8\Re:PL5:8qM4ibIbY
K*BdJ& 6Hq445+9bRa/a9yGBMh%/&lM@a<n5:MG6E1/hCw>SFASlZQJJedB/FcE#hV8Gm/&1A^PGPQ=uC=SEnn9
mGuNpA *I::X1Snd&GqiCbt8aM&Fm>HwFTPPbVlE&!Iyd85GI&>cA@Kce5ilYh98AV^BEFnwN+MJGGRHK+!%dAp
dqju$8 AtYlCJI+y/wG9:CdKG+u@^cijN!>dG:lK$wpBX6@lb!8%/yR=HQ6XFdC?&+9^N^Rcc<^1/eybA#@cHVK
PGCq*L 5SYGhtEq5wQ=y\%E@/yN@X<Y+Q=Z@qWebH>X\9\*Jdq@qh9?mTV*D?5NGT6Vq*<9Gj4%d9BjH:CD@9wA
:PN/@9 \9dZB*>%utIHe9@LTdG#5j@%JVdI9/DR&Np+@:wlN8=@/^k1+8D&l$5Y<N>E\BAI==<yjeD@R@E\?=?I
4KHF/n l>u@Y?JlhmAd%%@Qnw*:Q/mI@%YXyQj*S@5Q54F@Hd%@4!L?W?PlZ?@piA/cE@kdNPh#$JDj:b94PYnR
KH=Xih :>De#$BD8Lu@HM$GjA:/#\YP9>B5#$GDj+htj\/cDjIdNPkbcDDud$d6H>9L@lpc>L6>R@+y>HP+>n5%
h1V<t^ :T@+<<nG>S9$u&5W@>Q8P<@VKLJ^e=FB8Nn?a8+F+Z/GJ>Bj4?*@FeEp?BjyIB#5bGB8IBtE<%pH<^?:
?l%Z%^ *!4?&/n?y+LJ9*pT@WW\Cj/#cbV>V\KD:J!@B84@M!n/*#MwI9w@dqCEwk^:%%4Mj9dRn6Lcq^CTZcXL
n?MP<m LF8GAy>juP*<1cm/TkdAIGV:qlLSZ:c1BDeWTwS>9Hb<!B\ZnMapJ6Vd@aeFWhTRHYuW4lteAC!8NaT$
?:=@RZ pbuKuuA!q&/AG+M>hq5&&l@GlZ<+*peiF:&ZTR%V*MnGEATBElNlyGH6PSLLMt1yTA9yV4a8p*ipImdW
t:JlA& qNZhShDC/YXmkM\%CeqNZ%&yEwapXt*LKNVw&ptAE?$1dcMwIeJEuEcAa?:c:+BJFXFe&d9bcdS^\tpX
#5%!@j *NaW&/nIeTet^LGElpbKyFHpNmyWkQEjqp51\iP#1mmBdjleluH!Td19wNk@DCpTNuRL/w:#Jk%>\A?=
*Ja6=F wqS!nR+WX#?8J=LdYlKH54SAX&enVSQnhP1\ZS?W\:$ZCFEqylp*w?\XJR*Gi+GZMKP1\5QbL:9?P4tB
SaJLjT #XKJA8V/#pIA4EwTE^^MHCqS9e@e!=p\M$=NQD:q/i/bdQYF&pyM/Zd$hT&wXWT1^FKu:qd\aHFZ1iME
GNjtu! MYp#J=npR<AlN=V+C1a1YA*?\Cu1C?+TLNbGGc+#F4#:%wY*Ac95myQNt$/XB\!G?KPY41P+p&1#^\KR
Q!#tcp w/My5d\^JV\l#a<^FHPV&Fm#FT1t\:A=:1q:h&AhC^wn^j=/wE&K?whVC%9d<9Hcp@/MNSicG*VhmKM/
8i+$^/ d%j8e**<!a?%\c@q>NjuYNApG8C?X!p!i5N<dGnRH&ukaR&&DcGFh>A&hFW1mPV5EI><Yqcy<wH9Qt/k
\IMJ*5 *dHC9KAEH>NnW*Dl&<J+^d$hWeIwn@$KT?bIb#GY6$nM!h8k^9:E5LXEHBlIqjQBpR&BSyLl>RHNidml
E<Id+T 1pqYF559/8LBKIZV9?@iDtTZNM%B=bj95!en&@jEnI$XX/j#A+Y1XS!9VJFJW5QmR5@^l&L&NlwHT&dk
TTJA6L AW\45p</nW@wa?C/qIe&>6li\+M#SA#N$WbkBwZP#l9E1JP%Q&EQ\kP@SbhhKwaTPe?4D6nbyy1AM?W$
YmM\LN ^TAwbnSF%$%n1Ch1ZpKC\ML4q?c18*JP+&^PLjD%>QuR1b\$d8p%H:JcZy/+chNjVjZCmEHJG<haKWwC
PemF9& R\FdSCKwPb#P&j#%A<u^?*=pThlm58Km:6>jpE/K&^dI6%4i>P%wlVEIDwQ\lB@$KCN/&VG@\R*qNXIK
u:>Euk mYyH%IR6pZwaET:Lty6*bSHqc*Z+F&IlSyX^e<kuMiNl/8mwVyMNbJ8V+I^Acillukt**lK<\Pe=%J4\
V<Fi#Y +\=yN5@TC>\VCbZu:XR9mI*cDXVPd5MpWZ5qtb:IapMZINZBIF8Ai6T8WNK&N@4hPHi@qS:hcF!y/H6J
:haEL/ KQ$?caF5qG>9tBXcHnI/+=n^K!JnPi48:6aQk9Z<5+An&SI=mA=+A:@<I#n@BE$5eRR>i/EpSud5NL>A
wGMq*Q ^9MucL>q%GCi9RDk^%bMc*k#S&K6A@dECkB<\8/YpaYdQtL5=dJB&<NyjXM>Imw@?$y5y@iq/btaNqYJ
jB94it D?&?%n#pk>%b#Rh4b:NT\$SI?D^jEa94Pmc>hwphia&IJKER\M:^apBVhqCR1Ji=LPuk#EV&jcKNpttC
XX^ctY I5l=Ydma$:qd1Pq66JBR\<$q*MFyi#N48E%=TlGSjY%We$NGYTNuISHL\\^IR!<l^LPF$AFXQ?kN9C@%
?5c=B< G!jS:Dui&AElPCZLaq/KqiXEqL#Z8w6pad&GXla#P\WKh:qpy?uH<Ql1WX496<&u+VJepu#WXpkCQiTK
XZJN@S e/&p/h<P!EnA#TWY=AMC=qbQNIuM9<#weJL!q4e8nKGS<Mi\iG!6!QSC$FI@Nb4j=Bu\cmkE%PilN4wi
#RG\m9 4*uy9P*Fy$@mP4LNp!J\Z^n9NbNt5Akl5T\q<5qL\n/:TMeVae%X=ey=e^RF\+*F!#!4*Jm<wYqY/8@+
AFQD$q !WW8?bL/+?yuK%AQKe!IimES6N?mWjq/tPXmmGG1HE18?bj68k?8QCG/n%daPSF6!6Kbb9jD&W+FHJEj
mMZZ=p Q:B88JXK$:!aH#lm&hp9nRG:WC$**ACD+AVXkp&N5bPIjet#d&1?5=Luk<Y@aNFh+:C\1y4PwZbeGPMa
hqcwB> qXYdLVW*wykY*ebp&%HQ%VWd$ZiYNH!H6qSeQVGq4!>uD\Z%NdY^?>y^=EqIbQ5=Nt%@lG/*w+#/RlP:
IPP9WK +u1QJ1h6+PKA/6H:lqGddQTF/w5laIt48y6YBNNbwSe&4b4liuD5yu#DhyMwkyDRa6WB+b6T&RwQy&>e
acuFNE l$!LkZd5INc\5WYCuB*mT&=P6:M8dk11i1KAGLimkLTFpp+Z#@/!jS5#<WXC@P>uN41YE>CyK5jD$q#>
8l5GBV *qI^^%dPMC=Dni5nl><n=J!=VJZLjLBC\e18KidF+=+?bL8Xl<DFk!mF$6t:ZiYkeSL$6%%wJjnN<$/P
M>t:F< C:Acw&@X8AJib*HQnH\41A!mZp%j#EtX@mAdcGq$WNj%HwHHdP%I^1PChD@PRHpCD!WNBtm+EKCGcbWY
:Y:q\6 9/aeHRhQH6^LNpSumQ#c6K??4&>A569@u4a\Z@@q#Jw5?lpVVYnR+!huwN:QbaG?ELL5BPWaLyR5beVH
kT\<a: KY4<14p$9hWMMnMkVRCkkWDc$JTG?mEjy/>Hh+yet==549t?=w\EWXCFTT#&DQ<>%GEMCyLlKY+ZT>Aa
-ATLBH 000d84d500000110333 Page 317 of binaries1.zip
J1+5=? 9LCHB?\c=RBXFm^t?Bmh!X<CS^>EBSEpJm+HAIdCT<\>5qe:e<bh>uEwN>5DaDqpD1RT@u%=@m<516?p
HkeE<F 6b6LDD?d<J\h<SdIB$maGb1hNbV9M=TjmaNNLJ8#Bua^Z1:a^m6dt:wMH$9Aq:mEn^S?ynwwIn/P9nk\
AbM1C? WXR$:QEd!EcW>>NFS#d9t^mj/B8*J/\=^wI=iSRYHDm&Fqa&*FA6R4W?MN*h+%jI%\:a=#AZ9\yk^k<w
nDZyKb MDTnI*6ubRyZyt4HhGFhM8BueXbA^TATyk:&P\n<LQn=RNuWetMY@jkpnMtM>qmQQ6+uVH9=/PZd\td5
d\SmSS @b+AlG=+mW\$J>+niDPpItywBjMjqG&<GQbG\:AQQh/WJ1=<4N:WZ!%ynK%bBRXn>kBAnHlKe$<CnFT/
?q5Tn? waR:%wIj4CXpClZ$9RD$4\&\GC**Z*5inF*li$TNi4aMJ&eaDZX@^4&n4L^/BPA?C9:FjmQt^=QD%XQj
JQYQ8t PwtlQR554GA5KwM$8$eB:@p*l6XwDeTCGZ>p<$l+$<IlhqASB/e#Bya<YI!&!^6SYewTBt5GAcQ15aWN
ITQFQW G1RE@&/IFT9&BMi&aXcJdB$hBT<H?p@DP8#@9\n4QD>8\\:/H$bD\N#@GA$Be@**wmFkn4<Lk9^%yjEQ
+54MXl c=k@Yhd?NZL$:>cGZL>bG:JDuwQ?ZVCAuiM=cHdRd>Ce#$BDPH<V^tDuik+c!QEdNQe@k\aBu+EGk*+#
?^!8/u =mC&=/DbjuQiIQbuwEG@?:^BwPik@:^P<^j/PX\D@i:#Bn&Hc?#e:L>BQ+h4:L<L@wCi\#X&$P@G@Dqe
b%XkRB a\j?d5!j\#W&46>ea?DueI$N<y9AE@k=ZQ6>+Au<HLL>y9j^L#Vwu$KD@!u$5<kG@5$FD9/#Z5Mej@lw
51dVaL @=1yRT#kj@HSNuP&M9hpiYQqc5qm^GJ1bYHqctVLat=qd&Ht:Pl5bi@/*MkX?/>QD@#489+nkkZ?hh4Q
Ndpt!! mF!BPj<?e5WP?1<mX@>Y*j8Z!BZuu=Z/k9?p?#Aa#Md%j+ipni*@QpudBBXDquF5HZPVLZFiySjHZSjD
bh8G1W !GNF/ZcAFLT@DLCRYLldeIJVFwqMpXNaBHGNHScGdIT6>%#!kk9wcHmEIF?L1aI6K1PyCALcBqpPwZ$a
IGnEhk GupQB#w@A$euIC1CFb#G5S5pbSS6yBS/p:iF^<CET8Lq5pF*DYkthBenNWjJpeRFZ!pFa<1pe+B4YWc6
9ql5$> ldRm<5wmDH?X$6*jXKuQ:I#Shq?CqRjb@N8ekWE\i6lDLPy8<wPDaPKqSt/ueVD8<l#VV#8XK#t1#tAa
9CDHI\ ^BZPbcDlyNWkyR%1!=1MGau>YDZXpiPM8>&p*R\P5ChJF>eHB^:6i=FmQ#!HY$t4VpKVFyaiDPLS&=pj
LbZNZ! H15?5>?yX@q$wPCB8GnjkaLec^>>1tPC5PFTPKc=*FG++DnMKwbMA9QEKBupaRwGETCGSSR!=IFHAEEl
iaI*@9 Q?5K=Am1Fq#$W?J6a4E/&*FJ%nF+/\cqBEilwuL6=CWPYC#yE?q8!yJ:Y^alP>b\=6m<C#yVXZebEC!J
X$qF5W 1Ad1Yn&/XGA\nA&C#Fe%8PwTPBLILMGy!eRq\jqaTDt<ZX$uuA\eV5G/<%jT/KhPi!#*ZpLqZVWe&L*Y
BPNNna 1^e6Z=e\yEnuT8XaiIQubH<\AN*j/I*$n%b/D9c>?G4RM4aKDbuek+lGM<ByM@:ME$k%V/@%YHBncIql
ZiGCu: hDVBH>RRL<i@=q>#\hm8D6milY6\@+w@mZK#&T6YF!VXWIEje+m4iuK^lR@HYCSI<k1bYa\q/mVZeGp*
dJudN% m\FDNIT8p*b\cC\c^S?PJc8:ZyQlN1/&#qQ&1lMj?6GHtA#bm>/IIRqk/@M!ti+N^98=V8YD@NGYh!!T
I6n9&A 5SBPX?\WhYiMh!YJk<JZ8QFLdNc&=*$NhM+#Q%Wbn<QP1N<X1^JlK>ZC?bKNILA8tTQDSCk:PFRH>Au9
l:9<XW GBmWbLEkC#dB1!6k:%IeiWewk*8Yet1VVT/X&d!A>LS4B<bZ+kHpTT>El$##>E?C#C8p1X8GBuSGI@*F
!Q\FEl yl?JSW!J#%S+\<SnD$VJ/VkSW:/NAKPRMi6mnci!yipXyy6HA@G8<pVKnFuaQFiGj=!&RDM&PFti$iDu
&?/N8< TSGd<GJFMcE#RkISN*ik$:&4?\awJN8?c?@CSii4M>IV%l^Pt<bwVS@A$^/lAdGRZMK1d>VEQGMaetZN
WIqyl5 $?VN!JtGVq/w=DZGabZ*V%l?JIw>qWt?nCwqT@H?tyeiaTNumm5!+F+m1DItR%&BnY>+$CWd%Qb^j%mt
>&?+l6 Xh&Vl8^EHQ\F*V?jM/5ck=R?&G!?6aMd9nP:>KWnmykH<Mc?McZpw!Eht*@XDcXEpkp^&tqWcFZl^Rd^
e^WP<F 549SN*MNX8/ZtdEQamt1?cR%*N+Stt?#DTP+8=qGLJT6^lEe5T?T1:TnN^hPi@^6?*$JQNiKWq/<eNwc
kJw?=E 488eF=Bi9H\qj*LFN1GK@aIlGIPP8pRPnP&E1A+nuLN9n$6tPyinbIMcQH9SVhm#NW/S?!NJc1wJqHZa
YM@>Ly bT$c:+nu!T<Q!ce9k+VZ\nZ#\>Mk/$aE?L&Z!R+RWQ^5TSY^W%YCBp>&%VQ!aV?tC6>5NBt\<TJBymQD
?#@Zu1 jmSuN5X:u$1w9<E>m\hCkn$cS#HDLFc>WuMF%FM5aY:i!5IJTCAW#hbGEnuDM5&b:>Aqa5=4nFk9X:!D
T@hI89 R+!A:1+$?&IC:bimka%qt*jK!\$NK#6&iB9mk8ey^Dy%JNWN$IZDqMjVGh&+FW/tb@b*^N$TFB^pRKF1
Q?cLZ< ^Kh&Fl\\4T*&H51wNZ?u@daeWH\JC?@k:FSXIyyTwbLS^6#lyTyLcVALaZW?bHPGYBlJGeh:tq:uqDBL
?SyYnQ l^RF6q91^1LB1:>@9Nm\P&RW+<eN\ej6Kjw!\I=l=dGbP1:?piGHRbqV5G1/jCC\ZwA=YR:dTHtt69lG
Yn>jIZ *1DJknW*mdD&I=tL1h6D9bBb!>QmGcMVp*aPm>nTF1:IB6ybKAdVjyIyG^4EwAt/1Cb^&!aVJ>65JIK#
eBBym@ <kVVqQ+%>>Ai^YXtq\MT%djHaFaTa8lEq9p<:uhqmP&Tww1#1E=WD=u>N&<Nm!%ReeHqI5//BMHCjS:D
*$&:qF 5/9<i/mbXXP&KDGiFQSWY$ZD\eG%1a=$KMGYlAG^SeTS\&tk\5MyEtMPNDR/q6e$Yb6a#dIw@5W>pD/!
VI9Q6^ JcI8Rh9^+y#ZXEc=>mLF#I*m^%!l^LJ+kuqa+&FpTKJ4EF!aBM*Ablk/enAtZFYLwkl=6j415Ld6ZFd=
wVyjC9 #X*hZ*6Wq>R>hqGM>B1X<4*#9lF1w&jE$n8h>%KVh%c9qCTpCqwJ\+X?C&HJqt\#XAWnR!QKj>dEdRp5
$%hI5F RCuwWkK4yahqJAGeHXapkjBj&N9$W=t1S6^qBd8SK+DZWHCw\R<GT#dX\QPB*pWc$#FqCb+cPDG#d^eL
JXDQ/& ?wVY^WCY$bny<Wd#/lG4yA>R6l<kWnQ+EqnF=%@#Ql?j?\djp5=+9XbwEVp/YljKHG+=t>a&i$9*9aFu
m?:lQY aPpn&DlwHwm@*Tt*j<<9A8dL>E>!VpFEMKj8&*&4QhepM!u#PT5tP$p@ybMk=:8>wm1Y!IeD@wwjJA\Z
XIy4M< c@1l&PIDLb:/?bTujYibQN+QNnm9#N8&M$G%CKGK@dm$p=WK5ijN1/<!TF4EM+=Z@BuhCn:%QlAn/:VR
P!Nn6b =5=b581p::j4%B9W5Y:$PVB+u/Q+^RiNqb5?VH*G%^>dMbQjGEVjM&ZcMS%4Mc\m@PKI!8!*<wT<bXmc
LLY1bD ?ndW$eY/4=CympWB&hBe5^\%^=Z1HT#/ZEj\$MpJYFYKBTRQDe4qq!49aDZ8+k^W=9\!5W=SA5uX*&Li
D$N?dM Ym*j/:PLbSL^&nl@6!pTdqH?5IY&6tWM8=X:9w&PC+6P8D%B6mMQyBI$yR*k&Pt!RNt!RtYP>V*n&8*B
ZqH5*: B6uL:qXIAkNhq<p5+W$L>5hDNQdkNc^95pJTK!eidw@8XL8&qI9nYSCNlYL\c=Genad:KwTDX1Pm+a*F
/9C6=J %RICemIVGB&Y&8pFBTi>+R*LWC5V+8EAPpWFC1GSujuyu+wCQl=etKMpya4&bhK49l@cpCAd?@GiaYFc
9ckHKD XKq4G>iKLp!CT+nXG#:pS/<W/V*TIGbiGE<8QVb$Eim\CG/c:5NPMA+Ym!AY!\16>e1?K1?\+^LqJDb#
:Q!FF> ?I/JQe?PNG*9+j:WDDjq^RF/Fd!>iXBP*b\wc4BNN!cNQB1NKk8KdpM@DlaT<qh#jLuDNuqucJW>445k
\FWD*\ i\w^An!@1VI#WSW^bHk=cjuB$>#>@+i>6+/Lc<ucSl5uPATHBA@8$yAR*N*h*S$ClNBAeHeIEN#hIaVk
W&ZX=u L5EqRHAIFy\E:d/hM*QPuJp=#J8^>:9*?>%@h8?>8==cXdXZ4Xwqc!&FuMNE>X^*>C%#DPb8nP=yJIA6
\p<Dt! ei\SCt\Ry9L?R=N/d#G$lY\hqmIdMhlpBED\dXG5iQcTL^J?$ynBXRXql8YlZ::KdBqDh=tFLWKLqLTi
A1y/6j @\/d4+yHPBY=@PBtQKJP\BdA%XLLS!Zjh>jFS=KLBVB9Y:qISWebd4L1WZRH6?Qu^<DQLGGY<tW<VGHB
#lC?T6 *d4Q4*ceBXNNH/uiq?+X@ck#m^R:/\t<H#I4*c/FRTkt6y%Y#pcl>Kqe\lP@lPAI#HDED\XCL?Vq+tkd
+iT\%a PGPmM$wmA%cHXBBa*Gp8YiB\t$Tt*TS:PR>QS#dBSdSlZKk+GiLnYj*\e5MZqAMkQFe#N@Ki!AqjJ?S#
HZ$nKY +=:H$*99u6RR^8>6I$4^I+aK=hd1jakFY^<Let*LwhthD&+kHwYtcki:HTLeV5RuRl\QLewc5Bn$m8Qm
4BVui4 EI4jp!uBH%kIGP?Hn<qS<ahe5n4Dk>EBQR\CyR<8\Z*\NWQnJR#JVp\ZePab8!ndy/XjTiAS#%l1mKe1
w>SKhR 5\jG+#D6:GPetaJSWtM<hVE65SS%8Z8LP*ju$YyRatkw4?X$tZhSww544/pRn<+=I15cdRh99!qtyLmy
kM<95< ZF1klCNZQTt/@SL/VaXiSm!MNL$EEH<$LT59<GunMw<c:dCA#mnKJ6G<S&YdWJncCWP<&de$VV\Q4e:C
h%q$w6 4YpkuVQ:RBIn5qJ?A1PLJ=hP+QTEa?<keX/NbWHpG&Jh&^LmNW9&PF1FwWRBBM8TqLWB$DJwTT+^:<d8
<PXEC$ wy4kaFHW4FJ#y!!KJ%!DEtbb4*KBbaPH:HCG1NmNl+NC?a#GI/HmPe%wmmL4K<W\P<RiKbWcjTK4?uc^
TWpt@& &:y?N6ZZYF?KESGqQEVylmJpHF=G\n8=Y4km1RyG:LNTIdI%IDiKibnT%W@CT%YaiRmHL&wZQlX>k6W\
4<ceMm 5htWi?5DS/L*<DJqaNQNn96bWy@Lla<46/*&6w$EW4VwedhiAmB=$CJqT%k\c9qL:w%lYL??iqe+l/XS
WBTpRi kyduc4?l%V8nltJFMa>I:u/>te&kKjJQAF5Pt%&P?l&bcj4Heb5jmp^1cBV$pV<1>qLw%&ae%hC^S?C<
4c5P@9 qMQ9LH%etWC6u4n%XAQ+MFSKMP:A?pL*&ec55^uQ?#KP%1Vu<Kl$J?\tdnRy$8JWX9Lp#cma=LHw8uWb
n#Z?jS 9A?#e>WXu$bqYuPYB@F+J*ha<5JSCB%Gb^nFN=1^a@6%nVA#HB/\WTymhR8FJ55<LTuFtS$Tb#wMjMZE
<#YFQY +<RF4+>&kanGLSTLlKYE:XDIB&AIdW9a:A>&l/WS%=iyNc!YcH@aC?P\HZ>GbjLNY8Rl<$NPhwW#dl=X
MQAPYj 8Vm8F/^#$y\%cHGYhM!#J9TB&XQjdJ</e=1YQH>atQWWHp5A\+@Nb9t1Q*T&JyBF:pk<nDnM&e*GA8Y!
&EZDP8 eGmMLpYci$p5VPX1\68^@#KyR<li5<V#CXyppRnK*mmBetB1/JINDTi=6dGT*:EVAw>S<Yh^?8&ZA<q*
-Ac5bW 000da2c3a8800110333 Page 318 of binaries1.zip
=8kmV6 KLq9>$JVJe#E\5RM=mbAwZ/b8#lF:K=TnAI1VAlmhwT:BEBVk8eY/\&Q4b@LBGe/DW/LF#D!+l*DA$=>
pV8tGl kQuht1McuPc$hi%/1P!9\=WN+c*$P#+Vah=yVSmFIm+\l+q#YdIyYJSutW?<*u$<I<uLuK!IyiWR!8pV
/@ZP5& &Vid8K4DHD<e!5RXpyA/=&H1:&F6e@:qIWciG>ZqZheIS$!MXHApAt+W5QjMiLad4+kcwdlB5?A1mFBm
X^mN#= IDp8$pJZh/DLF884kSwJIu!u?R6G61S\N:9m#6B/V<^K=REm6IJY?/LlGN4lKM#V6pu*TNcwTH6!NjX+
TXH\NX +WABWa<9?H^w+%*dS!XYlb8E4mKTFCyNBlbZ<XdW4NMpludl!y<+JKub<Sq#Xc+M$tdtA=CG+=><e<Y^
QJula$ %Y@GM=qq6:tR>=@k64W=@XD:ta&k%WE!\CHMFJ@?uZjw6t%HNl1Z^F9p!dh^>tJYqcIy!+bqB&n%kT15
*wmGeq 9aRt/?hmLk@M=T^R&dKabqm/X9W*AGlTu%?=nIqq4&Jkc4%NqLDhiwTj/NDWBNFXjy!N?:m!TVD<XA<S
q<8heR \TQw!X#CtZpap>5:>V$YKd>\N=KejCP>J+5JYt#HuGd5awR=R#AYtu\&W*pi$Zp!:QXCu6SME%GEY5*C
/^*?&1 <T/Tb6KcYl+5Dh+5cCw9w%%ARpwQ:N\!p?JjJ8$tD&MYP<#Z8jj4jQVFTLIHJTQF#qIaihCWcmpKyqWW
cqe>B* LqRWMhYbYPCL&Vq<dcuRMqLPF+6B>MP>=>R4%@>CRFe%4l<HVQ?qa/%@HdH!V+:jwNu>88n%T*F?6?d%
ai>V@u +!*uZ&&WeQ@J$cQKu<58<1hhEX=!b9ajJiZp?K%Y<5b8L6a@@tNn?iWpMN6jdu=Ja8*m/mb1bi^C#k=>
Tc$*u! pnQ?*aP+k/tntdYD=R>c9&*ARQ@<$bm@FPDZubyjjNZ>&Hul@99F64<P49qQ:AMBPj>?H\nI<e@6A@*b
Rq5R@L QS@$B9n4#c@ubHu?>y\5<I@Q!ZL@\Tw8N@9Qih8Fy8V<CVRZ?#*45N^eQ+Ht=L%uHbcd?&jRuQjS=9pb
+Ii\S5 >L$qB@+EtwQ:u1$Td6/jRh>Lt?<u$P\<>:RcD>6QwP>j>Phl@/pQj5>?BR@H9+Z?GYc:h>Gjl?8ut8&i
Gu#PW= QcK@ny:=V*S#Q8/@:?b<ZD@S#j@Wc@p+@4DZ<9D<\Wub*&\A@6l%<W?iqGZ:MWC\@SJbqB*I<VQ:DV#A
P>Mu$9 @%bl?Ql?eWLM!eH&T=q?ym!<j%mYj<lpQ^6!qaPeB!w%8KCj/5it><<Wl8@uGwd4h$/>j*JZmA6I#k/6
\$:m@W A5iQ#S\P*y<yDQD9#nN#5@@Q8$Je\N@6C9&bGj<tZ@b@\RE5<FeH5B!ej*EA!\Ehm@+qB:D5:D@C#9?j
EJYRu5 >AB:C>n=9>wDLPbjQMC??Y!qR>/Tke+#DWM%:w$NAdBDALVah$m=wJuGPdCaJAVA6j*@!ce9pQFp<P5J
SF^T$4 \d%FY\mApkwCTHQ%@j@iw^NGR?:P!e:%/<I58<4GKa:cdpL!$QpAbL&+#^DAB%WIwA>c%#BT!EVtq5Z\
=l5!ub $GlKPmPQkabhA/Ac!Xu9kZPPXi//E6i?EX\DWt/t+N+Z!PTQJkH64hlD5%eFY*jh!a#J%#D8:M#YSYM!
iL:^lR BbbK>qJ6nLc@6=tK*Y%9bLW$#nEw+>K^\=W\<#k**Skq#KQnYk+E9ipW#D+*9G=cBA$p@mkljq&iNjdP
iaYu1/ hYDe9G=iRj%IbA*=n^Km5%&#Ee%w1iHAIPZkhZBc/hAqC*H6&:kIHmciRACc5IdY*9IX:>KaGYa%N+64
YGD^!: Wmj+CI#C?b\e9kc6!<QTt#b?tCRQYH8nQlZIXK\j<F1%J?p!yLj9na1iq\M9#8a85tt5Z/6SaNM<B*E^
<RFMBi 9=@T?*n/+G44y+>/jHP6b%hh#HPCu<+R=u^hb?Py!h6q6\bP>yw/^FQn%D:6<R9AmlYGR>#QP8tbd6@G
ei+5m< B%*^#N8?AF<wRkBEbGB1b!dIXPd&d$+G&dmMZl&LqeHH9\?dSnVyZuQadmMep!H:jk$BhLVjVtXBynQ%
&um8Z1 4L>y/4&!FuW8^4*AL=*i4PlBKep8jS86^<Qnej8BTJ$9W%HwJq//T8H>iq8m+NEFBPAQ8m1C6Wp&&bj:
VZa5S: $Bl5^nEKZ>PHdIV/FE@@<nLDkAN9JpbItLe?DQW>:%84u4nnJqh\JR%#Sj%Jc5EdtVRQJ^6$aZmAML\c
HB@DNS hyR5K1+B^jnZutSNC@JM\+h5%Eh6q^8Ybn*JutE&?DRp9wIY:bkPu=\ZheXc1h/w&<n#6t9R^Dk?>G?R
b1cKBH bZe9ZNaX=ZlnET\YmhYBd$/Pe6LS<8ZYtb9%KmkLLN>I@FieJXN!8\\BtLh9b<\wdpMARa=ZSaKRte\b
*FBZt> \ZR\*8>je16i6c@yk1%H%eCPq^w@GFu>9=6pDDL:H!=F6#?=/=:Rb>*&G%LYPeGN5BLRCBMEeGyjQZ6$
cWTcbj 6=eF=lC<qX4ZV>pW%CBa&dQw*h*%#qGhh1w+tZ4XBjDAZc1B/!1!R/J>R!/NDT<iN:MpTKXAN$u@K4GK
&c1NVb :QPL=*$k!F^Ch=Z8IP+b^:EWVjRV/4ej6J>nchWYF#?LbV#4PjVySYkhJenZX5>:ZHm4^Y6B/qqGjQ5M
^YBhLd A<!dj:*R/?=5XZ$hA\Q4*$?yJjbC^+j1i%jkSW+Q?Sq*\$kaKS&/+cVNAANJYw<RkLmyX<eVdm*+1j8%
X%k<pE Dh54C=wN:I&i&Rac9DHF4c*?dR#W$bTphNajIkIEGe<$*^:/=dpFAmkZ%P1/e\Z#y1Zehw%BAE<Y$S$k
=aTWJe kPWTCGADKwS/wtp??ayiGLQp9VDly1:N@GV=Jq/k1D=/IL5C*X4pSZ>uPZ@ntj!Fw=\aSdbq>6%Z^n$j
&W>:F^ d1GpE8yZd/?NZqca$$kE4+@LEyXlp$bPY<*N^CSl!=\bQihe1RSBJy/H1J$:/B9Xw$ZnWjKu9$GbLK$y
hHMt%q Vi5@99k/+LtlPcJuaIA9?Il94E>Ic*AuQ\NQ=NRp%:>^ZmtD^K8aJS%uKLbQ4I^/yQMD&=JXB&9H$69Z
/L^Nbn Gqu<C9JiiX=\8nk+1kRAKB<dpeTW%y#eQL=6?b4mYquSitSVVXRpZqZ\$MZCmNJCujVFyeYtkCTVLRh*
Q$DJAl 9D=#Ne9B@8+DXNmHLX^Y6&%8&ajPSQ#h%BdPF%Sc=8ey*@*W%Q6=8HJScKpMQ*H*b5@B%\tn^VFJiKkJ
nKq/5p Vj1+Y>*bBK$!%Ben9w<L9wJKn$DX1<Klbe&k4++QSDVnF>>y=FCY9w^1YRi6*\tC6Xudh+uPIJQQIRCC
9w==ql ZTmLDd/CAKVGp5B5W^DAX9J*eF\Y<LIhKyTTba?8JZ#cV%/F*Nackma=6$CSZBDAqhpQd:!Yw*>KH9<n
!J#ADL Pi86wVEE\JT!el==cX8+^*NhWj/m5dQHup1!V=^8LVi&b&@wBc+bd@I:CIBWZlb5dApBJNkHN+GP%CCA
G^Z?!u p#kIaF$T=/Ch+41cb41LKLaeXq9PlTNPARSAC9l/w>:BcVQH<$&Y*<NClQw<mRyVlNeFRSLq+9Kyi$@?
SQM&Pi *KGJ>W!F$QuDcSP=VBbi55>*XREN8$eB/cy9HXt?n4aVX8Sc9@La^D%B/ZDbpL>/uEpEta1N5uH*M4q?
qqb$C+ a/*<T8Sl<pbkJC1>kk#II^6^^Wj^jG8/89kX>=JW4#bKA=yFd4$:te%dN9Zq+6mCiX%VK8*u%y$BbQ+Y
%DiG+: Z<bCmGh8udtt9%k=XI/?yy+>\GGV:Ptey%@CQBWYqKBmKYdbiVIXiJ\jGcT6I>L/cPMFwH<^bM!u4tJJ
Jtk9N& hVyFpj*c#4M?cVH*BEG>iNy$4bHX9W^Q?Fq&udWG^/%MCDYimE1>/N*c9CwGJ*RWkNX&e+!FTpIBwG1c
DkGm#J q9%M41YKH4$bIJdPP%pVlZEq4K6dMLXWJ4e/DnpwXKu%D6@5Wt1:\juEhR\!HWjh55jE#KZRW&?#%^aB
?ICiJe 1GDZ6Kd9PeWi9**t*mj:5nR>JZ1eQ:C%J6AN\I!9KP?@D6AJ8yGV>TkT6X5&\>F#nmVe/!ILb:mknV?k
h\@^l6 Q^+H#K^WjqIh>a#Zn5lQtjHML=EtWyM1d<51&eYVwH:WT*>8Mw8#4@KbWb<e9!FP?qLNl&Y9KI49hB/W
*BNhJh wPnD&R\BiG%BAM46Gk?9bMF<bPi9wA!uQLZ/?j+8D>9ewwYQ\X+@!w/h&/QT5GyRqE/*E>JG$QA6^bqB
<hk^KJ +X6t@qBd1hSE*6Mi*6wlhFuXDX!+>Y?>Z^9Thi9j=tlcNG&ME4#YuK+m=ulGc\>t\LlM5NX^n6w$j=IZ
nGC8ju GT:mAMjk#KRd^Ml1wQh!>p&K+bR=N1\m1l@>eBS96WlDtiQ\6EFTy@hLHYt:&kY^cwpbGIDcDSMw^Wdn
&?kn&q A!h$=Qq/&*%E/F>Zb/*nEj!RMb\@TDWP6@D4>AH:1@dWX^8Mn6njI$i\@VZYljei\J9@TE#WiELtPhy$
W\@k:k l6q15hn#cwNubWVkJN%^t<!#\/SV<1dqk=Y&MVY54Ew4a+MLPLj>cAICkMG<uWm/\IWAjGM8pWHdpi*F
nk!YV? XViZwI=81FbyCbq><$we6NINlmY:!tQew\jjpS%nRRCnSCBq\?@H$QE>BG\%iwEHAaA\L\tl&Kym&y6#
cwRVtT WIewFG8?8?D#%L!=\Z?+JE$/#CZ@NNQmLZkANmNnclHu99FG$iKW!&GCn^*I^jWMy#!4JJ4&tkG>jX#V
Y$lkYu aq9Rneh%yt*M$Ei?Zk9NScK^pC6JZh6WJVi8V1wiwQ1XuT>9\pnBy$K8kk=YIpp8!C<ul\qn=6FVp>e!
cadtdh kY#Pb1%#:w=Tc5RI<%MhMPH>F8Qb$TT8yLaGhGE>KEjXeGR:m8B4$PZDLMnenpAkBHBWBK$au<F9h^<i
C+WTSX RAA4WQpE/*L*&>%9:%!>H$IAdXqk?K*4Z&>?jdN>Vk5B9BK<jVD</<*R4#inj!cb<8jj>QG58*MI+JmY
5Pn>8w <hedRen+#8Qjm8D:n+4%Y^HYLP/ZiHDiYMwkn:hIB#Fw!+FpS@uRHIk?IA88TEM#+QVGA4WqkPE6#5tl
Yb6yNM ^cP>SS:hERbjK%=my+?@9n9QP1aC=mDh:A18@knqpHH>p&phSVC@V+I/I9>%cu?ZA&V!Z81yw5ntqN#\
?n=wSV HPNBn/qk:qN+YabQ!eyRYdpqG%6+cu1wucwFhbSypuI>u9tPImC=PKF=H^b&eV&%c>j!6VM^M<56ny#N
huEWRK 4==@b@B?1yCiyc=aJIw4YRFd?hN$Q@u=EIZ==9q/=&L##jNn5bcphYtdCAhSQXiL$DJPP5pw*9k5=E>:
Q&D!Fc 8kiZtyX\V\?#/!4Kp?$TkQuC&EP4%MWjha%uBSDLhJy5nG+a>+jjjKC9YMBVpyWc&CNbm/^/4Hanut/@
/c1JeG K*<<#CkIXe@N@#VQkcw6QBy&4XAX*GL+5H$je=c6ZR<CmH=TAAG\%WEAk+*h88*jT$GZA>C9VSZtaSl:
YT6k1D y/Xb4G@a#WlVWJ#1JHFBJE%&8K!?MSj&RH#Q6lElStPY&1VMiKCu$+Jju+il>qVlqW%4!PQ5!jhj$?SX
I/uak= %cP^J4WjwPIy<P8\D&dCu?>6RkD6yIk*V%Ib69iXwwYwI6piEH*bpb4b6Kc/bcL9ei#?Tm4e\G!plI1n
V+pP1a ?HB+#Wc61?1SAE8\ke\!:p4Qkk%^Vd\\h*M$h&^yT!>%EmCNBk=PBeH4Lm=Mh&?l>Xnambq^n=auW8Jm
B@JAmn u@a4jnbX?C*61:616^Vk4m%<DmBi<*H86eI6dludJb:@nSDK6<yLGQew?Y^bj>kV<:A+EZaM5!KcC#:u
RQADt> tBmKd!%#WE$>j5tt1WbQ&K:^Nn<JP*V%HJ$<<cSK8H<K:&4PPFJjWWtYwQqDFHQBBT\4Dd?XS4:9!Rbm
&m+ZqJ mIN+RPd!nt@1#Pd!\6RM1R&S1WqpF\YXn>%8nRq5&tQ%d>*ynMu9Z<?c$h<MKnE!W1#He>uIjMBa5\%\
-A:KTW 000ea63ec7200110333 Page 319 of binaries1.zip
m6@c?* 6imIK6p6:u%<mtDPbe=BVl/hHd:qt#RJ%XMcX<ATSSin%=1!WL%tEZSFuDWH*NXuBi6C=/KdNmC>qRK*
e\<&5j >m9:Jkkk48VP>iekpNqW<P<Th4LL+8:Fh?%V&*XH=KAXB1hn?#YMZc:dGJ/lC6/t&*G@l\C<wZImMkaC
LhA?lh \PFNMd@CuAu/*lK?1Ch8E!??L^P6RY8W*\\*SSL*Lh%PR9c65d%Z4\N%cq*Rb15ANltNlaFb#LLQ<^Q<
Dw4X@l >*QkTm*h1m4^DVIe6aBXV9\6Je?n@8lu?&puab@5VVpam8pNF<*R9Np@pbl8GLahPuKH&8Y?NVJWp8Se
qMuL!1 R5GBEhdcQaE:AYWF<<l?>6TnSZ*cwXWZnuK6N?>?khVjH#&@@:LCjbt:8XFMqbtcMl@?TL=@bY1qZ>/>
KV6tF5 5u!EwqEmWEbh8ykGb9Hh*nMIwCHK>m%w/k5y!5jm*k$/BEN@C1#4>*+hQ9wuMi/X5qRh+<lmCeeNedbK
H*&+Y@ Yc%GS<$*FP1lP>/YpLuEWhi!B<da86G5lN9=ck?R9Yi8WBm1FSaDuLFjXDF*c6c4wmT1DM@+8YtV1ye$
cuFPlP d\yXPE<Nq\8bZ>j#V&^cBAL:%ADhEiwyqp:=u4A?:C?%L$Sj:H:8!9$eGKR9#l84GhDWb/5<:G$edii?
R<9YZA ^Qct%FSFypBc?Vam>M>m!6n<:8=DbD^Ta%S8PE?<bDG<5$TCe$e^WlVR=5dI1tEatDIbQ$PFME6nYu%B
#T1iLq LLX?Qpc6QPCh^C@>njblkkcdLC8heS49uXKu/jqq/lhbJ&KSw$>ZYTHGMeS*/YRB9jt\GTM&JBFatQm+
?MS@jK 8Ebc>nHEw<Y^a4PlI>41PyTQiVb4khT?nPwG8KcLP>%^<F#L%FYkRJBe?=>qKtR<iceD%SKklD1eDb$=
8DZ>cE yJb\&9+nwjuLPp94J?*c$#4I^C>T1SPH8:/e6DZe5=me@Fqy$Q/Iy!u9AqSRtEFb&9bH?B1C&5uNqLqa
V?bCw< @PRM4%T%NC!NLMiPKZ#&V>X=Wy61^IVVl?nC+LQ?l:L/V#tHBKStZNZDlM8nSn?P*ek^?Dm9Q?P8ImJX
b^T:1/ t=:pZ41EKuN9et6N!n>8=t\G>4\u^m8???JQ^SyXhjNN<R1@@WIXTGL+@TD4qBt$X\lV&<lVQIG@Td!8
J6@htF 4VcblXdHXcc<IdEmCJqM9thIeG1<Z6li%euuPMai%DdM<@bN/QN$lq8@DGKe15TV*BwP$wIAJm?VyTdZ
>DdlXe QJNL!+$JpVajjQcFqXm?4Dp>\*WDS6>P?%NX$YNX<$jKD#l9n5l/u9iCJQR1*p:d:jKjDbuqJ/$T#HI+
qe:5TJ +%W8KZ+mQ%yui:wD^CTNwF+uX#^WDW%T\\6J+Va1Zi!6Qeu?iuB=&#1SY8LbI%JiLAQd\c*Rp\a4//Q4
w!!h>n RMe&PdV$ccHj4lI=<qGZH=D/kCRJ<a+^kAG1lWEAKP%uCnd6b/C8168y6K4dqiP!H!8D$A9\>peC96K@
d5%Q*D T=WFHXXtIIB$MB=wP&MG>GPb\QC1mN9\1u%NE&\>1kq&9FV@bbukQ=:GJ4^JBQPV\e1B$><MZ6DJ\+:t
lVW86# :!hu9/%J<hmJ9G!&L>84\bXMMXL5J5Q/LDlHBJqJcu^uXB+/$9t=&bqBGINpc9*XFdHy=p#=i6RVq*X/
^V/#Eb Ky#!DM#HNLI^lSFV^A5#AW9MNc=:ZJtlq@LQFTREBD**y:mIq></tYINn$&D=PpaXaXi?y\ieqe<ZenX
IQda6* 68yky\#=SwP@uZ<k/GuFPEiehynPtJwVP*CDJ$d/yyVQD9EG@TS5?^GH8GY+SEL$4dI5?/Z&YBh\u1Kd
BZCYiJ !&pnjna+<PET6l+t!JY=wGWWui>/uLaHDpYcR&KS:FS4heAh8hIWb#GXJ9Le5+5n1<CGZdEeiC4=T/Rt
5V&bt\ W5Pby6lEJdWKqGIp:$5nu@8YbL=Ab9>1:SPXPYDMlaZ/#TiSiq>@:NRl\ee&NlqN1+K&^C$KcjEQNGaF
p$T:!J nJPtV^AnQ^D=aIAke$tD8R6TyaHN\wAGB8VLQEA^R9Qy$j#+>>/QKWW+D?yDa*uDe<?4GN^PXpmV<bX4
Dp!?hG c*Z:!m5GybTXFJ&@t<nt#=h^Eq/hYi6**\4Xj/!6+V/tw%<Lj@T$a:b^+qaI:lnnhbGnui!=RQ1F1=*>
n\5@8W iI=RaBJCKF!W4WJ>b*EEebCBH<^*FCNta@%!SZl4FFu+IGXbIG+c$IblPw&Pq*kI@E\LuwN=JFERp+R^
y%5VXF WN%\T*%><bWke#Gd=P=L$QjS8V6K/K^N:hn<:VtR:YNwjB=5eIIw6j4?%LS/JZ*R>d*4idJRNjy*c=\\
LQTQj$ QGXGGZ\!R9H5HI<^lCW$uG#:@GInljad4Sy$mh+ld=1ww^ZYNJe!Q#A9nSbhj@S$!#hq1y><M5p5&<#1
W6y:eZ 5^bP=T1iPdwKFi%hVSbpI9t6w^!yq&JQjVBYiVSJcwFttE/+yw?/P!M\eml/yI\mMEmTia>qT\SlW+4p
/nynXb kD&4+H^XmBN:PFbF8ePBQHuhe@!p<H\*Mpb9eq6SlZ/+RKi<lAJA4nImyb@wTwc>!DduXp6D/dL<GniS
L4Q=qt !RYu\M8qGNW\JK\1tBAYZiLG#8Qcmj6mJDtY/TTIic<4$Xlbtpb15d9PcKA1??%#KZ\mqj46pNnm:?k^
=cPVT: F@$*&+LR/dCi5%u<A=IyhZNGpaan\+il^4:@aGqpNA5!?X8d>WqF:mmdYR*8:QdEuY+V?lLC8Pq!PmTj
6<@RCc eTX+P+h1cDm\hk14p:Wk</C>KHkl\H5^eYB!kh:mnYmiSM&i>uDjiZPGi<pJ>:lQQFi4V/9qnSh6kTSK
e=LDRH KeFGFX/a59k4$ZER1ey#M9p\EZGH+6!ACGWqRjNmZ@KZ4?jcRJCyN>!BAttTD/!iA!?w4HbptuDTH<BX
9BXelM <DaS1@m=>SSMHG!nD4CbW=>61c1WS*$4SYJS6+FSjVieInt%FbS6FT1JXlVBpepEt\V@PBH&hZd&KE8M
^mZ/jF MbhK#$R5DV\uwwMlq5%+QCkn#c&p5\NGhiQhubd&N1FAZj+wPtG\y>i%nZ=AYG!N8yJ$:9T/S%yW9WDh
y&W%RB /D=ZA1@Ht4WL4nIPlW#9cqIuYTFVi@IGPM=BeC<b4c/>1TZaLYIcDaXaGnhP#Wj@8b4PHYEl\Z&D#y#W
Qdn=T6 JHPDQM8aMnP%^B=8cl>K$&PV?my5QSI\WRN$Kk&hJKHieaKC:WE4p/C8H=HTyk?!%6IN9$MuS?%V\E8L
>K=9Y% 8d5:&q9Y<>F:p1@<u$wLtjt9qhQ&!tEGP*$thq\nC@N<RPN?>1ZPXIEAEm&lGcS16c>VadlcnEFtn/=?
TJiYMm nb:$+\e1B@@<kqd\8!K+=KNyJcn@ISTY1k*X6BiNK%b8bkS9#WCZeaP$mi%dSJPkdZ#Y!>D8nE>%qyD^
:cVK5M 9<%4+p<9HtdhRLX66T@5>\n8#aRl\>QIZeE#XIJdMiPQQ&L@RCd@N1?yZ%/Enh=NRRCq41u*<I?L>Bd4
CtG@Gb qaSd%qXRBJmT:e59eaRk$*?d%<!QF#%j\L5R\A#jmQ8>W\QY+W#4Cd6#hI:bhiqp4ayeVhnb4TCS/Mk+
GJN\IG QEE&y+G4^YGdV8J6yW%<FH8HM8Hy1aph^tlwMd^Ah*iCh=V/wBuTqR%YX1nmB<$\Z:d1Pm@>%u\LA9l?
I#LNdF DkGel:qDY<RXFNucDkbukiNa&9imHW>TWmCAFYn>Jtut:ySH\S!uEMDNNilc4AXcbV:I:IHkj#C:>n+D
WIl8AL R!k*Rh6NK5Z\RlJ+PV\MAS^BY&RZb^>e9Q$Q/=HI@&X4t\u?DKe\E1Fk65@9/CaLL8Yj!u@D<GPdZlT^
\kB/c^ NM5VNTH6N^W5jkB*/t9id&jBAiZ1BSuaNYS1LZ8CZ/Kl:QnQXX44#CDMVd!ia<R<<Xlw6wpBqci4@ATB
iyL^<4 nMMF:#+?:yJmhnlpPu>D#8%9N&EybGXRl6tF9PQ:<L1^\4pSdQk8E8d=wl=DE=hGJM!J58E$+NauIV+i
Blh$QJ qJ4SMNu\EQWBaWTTi#lniQ\4QHEJG<?c#S=j*6:V8&6y$nDjn4/Hc?^&M5Cu4/w:MW@l=N\@JyS<q1e>
<R1t:y mqS/p>1Ht*DMljDAjb::ecLBY=iK&*aRE6:%GRjmh9eW\\84ycD<SPYdWll=j>=u5qMPdniPbcPeip&W
M^a*uI ZTL?hHRIhP$Mh:#AKhAY*\ekYDWLMy=%:ZldBC!EAIbe9j@SuhP:uDVlpq+eq<SYM!w%&PjW^+!#tbVN
9#6&iB CG:!E8b$=4bYH>k:pdi>4lQaN@ECuDdIL%<eq^Ri^R#QuZ^+h*&DG!BMaTnqw!6G/NAj>ayVB9$hKejW
liV4Hi AY%6w^bN:Ml19NqGZ+Qk5EdSSJm6e99PK>E%\TP8>lQE:tiBFyp1MPV95TVHHy/9ZQ&I+@cZ+n441nt:
eW%k8S QmC@c:n#XL:*?=\X:AdG&&XVy<YdKP+tZVQ?YAIkAX*lby$yPE:wGN=YL$IAA@t@dJmH@%kCCF+Bm>Qi
%ib?+? V1Yjc$Dbu+pHKt9wBde#XuL4&/?Mj!\1TQ>!RAAQ1tIQw:jjlm6iFRF*KqnBYn?YEqSAw*#6+6ck$&=H
?\%u8q CIA!Ac15@^W>EGR!Fj#jJ9K@Z/ty9/=W6D^RIY^Y1wJCWwVwpctR<CNpeyPu>/8S^NH^GM4XSk>W%AIa
+%TDme $JEZP#bau8Aj!@KSBpy>XCQYDN&TPR1kVJ:WmqiK^:Al#pm^CaeAYJ+&6k@V*8L<tIcX&h:Yknybd/eT
$P!y1t V#>J<EtQT54WFiMJe9h4#F%B=<5B$IpVa%KBhb@MSSHNn?d+!&8Y9?RBuTTyN+CqBXhVwJZVNh^KAD?A
h&d=GV #1ycwHN8y1^ncFY=69+C+:aH^T6i@5nLbj>Z$pt@aYac\N1@bDNeWZW/CAHA@=ki*yhQ<p@pM\cb&TqP
y=6\5E u5SZ^!BpbKQ^J$NJBl9c$h+#EK:BL/ljnL>=9Np:yBFQAJDKRYW@Z?cbu<*^@@bX9p>Hc>BP4*ZdI4FM
@<tP+D T6?:Jc5i8LmK$m:EY\n>/KV::bjh6Lhmc>\NH@ayp>6aHat4el/pV&=ZNllNmn$ZZ:ZCQhJ=8d+?8!NX
Jd$\h! 6J@4Q$k:q?Cp^?6AHZhe9NFhiFFJcZhBq/\w1c^6W!d8qjHa=EqWeW<D*DQZc$Rii=:4:hGK\tt<h>p/
C%5*qc ZNFQ?\bpp^\@YcAL9Tl+jm#i6VV5:FI>eq\jJiZ\!5lEcwTlMM+:!@c6+9!%E@9W$Z4=lEHb/E+1tDGp
ch&GLw R4K1l%Mq/8+$W%!a>NY*&AjbABmGeSTHn1#YnHaD#P>:EEAu&uI4&SF$Al=ABJuN8D+G6Y8CpT$8XmEA
h9XYZ? */yd4NH>V9Ch+TXF?6#48?9&a%FkFhLNBYk%&QH9\B<<BXik$*^+V8>@Nk8DTc$$DZX*E>MEI&FB+#4I
YKZ*lZ ZQK>=$M?mTEmcKqlCTQqIMH/@4>IJEDG@:<ywZk9!=u5N*E/dZFXWCat8VZ\eJ@=G/RG@=W!C=%bTw=+
6tmndN y:!luD/1$nVpIZciyb*CE/lAC!AtSBp+*K>*i^QB?dnDWV@<!Ki*W5h/L5huDK&yGN?i9%V*NZpWYw1!
n5wZ#S DP<Ed+=GnJF&&/PVF6?KL!R*unL:y:&8VIn8aX@64aV1t%6%15Fj6V4\=DK<aLXR$HDhtc*C^A#e\!Wi
A166&C KmK<P!>Q$88qGcL^i9T/wPY=6+@yLt8Y@yuluJ55CT6Z4#NLFbjGaSiJ6<lp1MAVqMAVhHdDd:TdDI5n
HDkR@R !$a6hbuHZ5t/=tIi+e@KbLZiNE5/*Rd=V1d+t=dP4h6+LI$y9V@n!ZCIB\EbyFGGJmTbG?w6FGW&qB1w
?<kdIX %SXt1uX8ByBG+W1>WlhZ>K9TRBMH@1mCPYa1t6ejSph<WG4IyYcZpCl$Gtj/FW66J>LdFV</e!!Wq#<I
/tmGZ= H@GPIGyYe<Ndp6*JWRLtdaIp#%I!*G**:b?hj&yKP!HXjd@aMVAX$EWZk#\MR/GWQhpcI&P<5j@aJN!6
-A61\P 000c411507900110333 Page 320 of binaries1.zip
e<enpi QtY$dK><i@bpFqW<t8nlBI:tLQ5:$m%#%j=9Qk#m84c?S5%Tcaw<FTX^G^4cPVYZjMQ\elYh/i8wnNLk
cVMYRn $mNSJRVSq>8MVcHcX=*tD>t$N5/b:qTi<*+^W6bKC@L+Xu4Sl&/wF#L%6uWFjpA@We!p@uKIcc\4hKk:
Byu@PN ydAWZiL4HJ!lX:4?HW*buc=?wydYwE%5KHuD&>TqeVa$AVL@5l9J4k>upEp+^=L>=CbG@J#6=pInS@I$
$W?L4\ =I&G!QL^j8<cb\=+yP@JE&p+nCN\MwiT&&SeZp%m\e6c4S$P5%<L#@Yb9#a:B@XaFKk*XZndB=Kh%9L9
t+q>9> R\Cc$AGN$km18G1*d=q=#aE4m<BmuXD%5k+$NHBYhci9iB9&Gq^mAREp^Z$^9G:J8u1IhKe!CkE\Wu%5
$NSq&d 9*AVQH&CiX&RD6cRjA9c&\N6!yFh!AJ9!&PiRmea$>B?pk1hCn6icV?GK1^qJhDP\AccaX4=Y<LWy+1y
<dTd*m 6+9dd%ZY8@d%Z&16Nd:MWmh9jJdZq<mj6!5=mI8=#jlYXKa?bGT!*69@A\=9W?MVu91\A4LDuG<q*+$h
$ZV\\y Cp4&ya%wmKi@c=\NjhQEWpRwXiN84eWy^GNYDLFAnJ1&j*$LuR5\nJ$9q%*4u5>XZaT%9d<AjW?j*mK4
>y#cIH /G<m9wcY#hVkE&R1AqyiLAmkwj@&CYHMqj1KYunY8tLJCWkp+\MLQ%pY=1emDQemt=8%F:j?tDh/wC:#
&6:m<: 165T+tnBRm>NG?eKJ+WeKI&RjcV#K1m1Z#/88Y?+:Q#%d96</AP$/aV*YHjJyyc4i99*!Y\!<</KT61@
y=D^iT b?!D%X@PQR\B1@Z1RwX\+Z:9P&?*G*:hJM>9c$N6M#*6t<mklR*\R#KC&^JF>iiaW\bXFL9HG<NJ9w?=
J#l=dP ql6&E/GCJ9?11i#ce44p!*AMm@y!\%EWBBBLARHa^q#KRTjMTVVK*ihnLNMdit+4y\WjNK::h>5%9>$y
JwJNmQ <Lhq/1=CNYl%TZyBWRkk>J&T>+ycldXlTFdB$YR#QFR>nc&Eqwh^=iALbD1T:EyFDi?P5@?ddX?YlPcj
Ea>1$A 1&:^F$I4y@CCZ=$lkAjyaKGR8$4BNW:R4/*wiAXL>1$bAkmE5k8=KHmP:QnN4=WC@npn+!NwQdb$jiMV
BD9bqM d8t9HjjBEh/bYZtGp9GuXYZHW!tpktS4:bZYtTt:XiY#G?iGiSeMtqPC&t8:QwIt4YYlZ8uutNNI8+JV
c\<DmT yBCA%\Xt?T9N1i9?HFaMk=liBj+QhjjE5RN!@IG:cq=P49@jZjX@$X$%<Z@eZVXcQQ^%K#$e+Dd9\SBm
EuERY< i+p$ql%^Hla8eu<\1qIJRtiPu<pkTtR&:4CM9=WyBn1MqN%iID1YFi+DW:4VV&N%q>%+m9L#R%nI>8KI
Z+YWEI e+kWHWw<CBRjYKbXSSthCMhN<:kF?>^t/GYq/<bhJmZPbyBWknD<#D=QQb!SY=4<tCGElcbkB8aHWtSw
ma9uT8 na/:J*n\a5A^+$<D:WabeKZ<:VXy/llRydYp/?:kGNqqVHIDEaZn%$tCT*ZtKhu5Auh=&d>PW#$LktYd
/tEuE\ =I!8N>9i1%MnFCaQ1l@Z^R@C/u$HY%$8p9<YMTjX*lWqSa!Il<4XG\5ZaS1=tF8AWc&^mhM^uTet?A46
kZ+Cpk e+kJt9+W#?iD8lBh#yEbnjEy?c@eEtK+Q8HERhX>#<KBQDPww8H&w$kCY+u/n!pcyth5%Zehm98iTqlN
j9&8Ll 8!wk+Nl#aWteV%6cc#^%mMi%RCj9LdZ>lwnE%Jc/cleb9PdupK$uVR%$*V#KyAuy:C\Xj>1q8cXB\Cue
NFXX>p Deb>\I\L=kV!yJ=8K>y9y6AdVH?X^EhWI*F?4ul4^59D8=V8LK8tP5$:F4tGJNw*X4+ja!>/VnnZdanj
B!4pGj kDpdlF?qVKHB=&yc!w6ucA@6Kbbe8K=*H>>>^PTJPlI/dcNTFw^/4elck8=4nyT>@%cj>c8*/=%+Z?P4
yp@j>M PhWNhYh%=1@\BCuQdJ&9N>M?D6:^Z!&>NQVS>m<>+*WcXBS&6<BR#cMY:9u<9km9c$l6\b8#5HpmtK&4
dnuCQD PI1w\YaQGXea#mlLt8E!\Bb:IX<nhEM>Qqp=HPMB5TSYRX4+c%YWAQSu/5Yp1<dXcE+FYy%YPtW/#T?C
1$!NmI @TjStGnqMa&6!DGMP?XKt4W^Skj#*d<k+wRpKFXu\K=^lY&nqlMGpK:DTaRYX8N&BRhl=%CLW!4^abc?
HHT^d< XnwtIjpTac%&kPXZnQLt1aN?LQyVYqPt<%ZhBFX$B5y$XWiC#!kk6PLQ&MYE9ES^cp!cHhp<cc<V!IXF
qR/Q*1 \yS\yHbkb\I@SC$F<4Gy!D>4ny/B1>hAK<Hi/lV151XcXNWbylA6@TSRtF\Ke6@DWCF=kHct@8!>etG<
/CAXpA /5A<HpQCyd58t@yk@/w!4ZuL/+Sc+?TTEqFEWWa@&\kHH4@m=SancqjlHbSu5EGW:Vy9*p6Zt^@X#t9#
BWNM9% #tJ@WHhK^BI6keGm^HIL4ME8c&!iV^w!Vlj?1NdBN19Ra#H=$l<D:&%#cAGH5GnEC?Gbd$XZPHuFIqqA
@K<<*A T@bCW59C/5^4DuX&/eukBuRS@NI!^VIWtjGNZHj4B@t=j4tYLRWHdY@SKWXKacN!8tMpePKj1W?YuE+/
6=E*^R #b=tI8D+$@u918=ljZ6<1yJj8+i9uCCX1G$PVI%!jySB4CudKYV4lBu\M4ZpHA*q:KYj>KB:/nSP<9ci
n+jJ88 q?K^TV46X9Cb$tubW%VpphayDp5VGq5kuhPZuC5ni+*Jmwl^M:c8lpCTWdRkP=8qn?XI<!V:R=iKb%Ea
kQyVKP TL!=Dy%\Rd\MlYnh%>@Nw5lXdSlSi9K$59mT<SL6ELjqP#8TWT#%HeJtGTnV>wp*J?XVMV^k1bkaQce?
*MKWWN F&R/N=:cKAd+1c@e\yRQ<DW%>c:8:*=8dZSjd$IppVmeYiK9P?dH$8ey6JVjT*=d\nFYTp<GS#DS%54t
h&G@%l QpMX=tBHK6LpXVnA69!?\Yuj9hRGY&8JE8WLkpP#a+NC&4uGtVE<<cPm=6CT6NuXBbJn<i\Q^?:du%i@
b+leZq <Fi:MHc>mP5dpNV1&G=BEB:Jlc&e*\6<#b!l:8nLVjRyhVenI%==4aN6tQByZZekYXF%4e!ehQkl\%Jn
Eu+5Im ?uG6Ylu!maa\RDF8CPjNiKR&G#1=$^9@FGKy%G/1p!kHm*Fu^SIkLY5e1Xk4EV@H?lWFm=YElmE&&HDE
MhS=Y< *Jn#/#eFVS^Jbn&6#/V5PJnStp!EeQ!K41Pq=GFnQBVm=>hwme49LK\$&HISM4KZEH%>##S<K1pjw>Q8
kL#NXq a!mRh*:I49<E^I4*RqRd$5>\MpZe4<6BXI6hqBQ%eFThjM/qhLq6W/&$V61bQ!PLkqt<ZbL\Jni=NX=d
V5YDmQ MITQIbT$lZltyNF\Z%iqn6G:c6BYW=j:Nhh5a&ahAnb&M1PcbM*IkaKm^qWy\#SV\/q?Sl&Y!qe:ThPT
%leC15 QY@t8bH1y/4bbkYNdm%ctmIjP!Y4R:u*?<SRPF$+Sp5\$^?@Y/Fa6:cKwuZP?n4w<Gc:t5QmPCNdlI&Q
<n!XB= cMw4HRWwS%qQ/MG^kMK$=<!!Ybah*nt#1B%TlCi@Rt>VR<&b<e1e=TTR!DubmIWF!&JXYEmPG/Ye/>Tt
49JEJW /CHc*GP*+G5XwtZ9LY>E6lTjmHSmWZu4WWPP^iD8mlL9mHL>aSY*:RP85<bT=Ke5+?!akuHjeCGMTVwl
/w*Bpl B/:BbP1jKnIjY4^e*@$Id\=$VuHXG!%IF=aeSDNDbkqGZ*1Kb!56N$*pZPhu=K*^cnj/!Z54SB?@::#D
Z8/ahS <I>!$P9m<q+jS4QPGWknWhVym4q\c*iNc#5%WYqGaG8dZ<@L:m!<!R6!bdV6YmK5M=EmS/<4YRmSCuyk
EI4MN/ Kha@wT6l+p$9n9%Kk$Z$t/t9k=BFCBD9:ViQl!6hM^qnhQ!+Mu/>/mYm$wh4NlFZ=K?ZSLGWHy*X\c<L
Q<1c\t ^t>bbq/FKVtD@JFaN%dTBc1qEl5mlN+QCXWEtZSGLM\ZPZXEBFaW%NQaLKHLwdV5<&wy$hZ6!%^FZMhR
aW<CI& QWW9w&#46&wKI8SBhdpK*+8pl/<aY^ipcaMS6$Dw5EI$tcaQ8%&Q+Xn@<5$jI@QLX4qM#NALSeJGimcd
VnYF^k En&dQX#dwD$X1eT<R^pjGa5Tt<hKGAieJqYIqNNkK<DyD8K:C9+it*ESwYYMdy6AMRFQbQI1KY$$W/pM
SChtk\ 1/+6BhImYa#PRN/XRN:hVdbyG*Z$EDwq1>B=ISWiXJ!K5l/S&GMy%mhGiS*Q$TXESZaS1/&tiye6k%ua
VBclW^ c*BbJJdL>4ySSetQ^NdB8!$d+wh>etwyMhkQRup%$P!?Pp$iHTTQDwRuM56IqikqB?b@FM@5F\ik!IHk
$4^4\R m69m4MqVP+VPi5=X84%FI:N\FaJuBqyX=cL:c^KQyjFVddATCw!1!&^eVEW?$QF1qt@Z>Hik$eS1!$%4
$hJTIt >#IqX#+8G++F^*GBh?5%4LD/mwMAQY+hVm^L#l?Nkq1N84AR5@WeSS1\T@9Y1++*MHpNcLa@TADEqRKV
YpupaK i!>Xi5GY=Myaw@VamJlpldnGWX^tlaet\W!tAN^uJmdMVny/:JiI*VCII16!<lwM&:n\5Jp5yk9MZeaI
=!?+pq a=XGiYp5LqL$wnDWQX%5kD+l9^?l!/bZlbD>qyqE:k6hB8V<n#y^?M%#\^?FKAPT@>qY<=@&=RD<A<9y
\6hmeA 9:Nl9hhFAJD:J>BeQQh+>kZ!@A#/Qt@KRPBQwDtB>@nHBjL?DJ4:HpN:IN@QwP<Lb<ZL>lNwD4=:cQP!
ByMl>a @\\ciB?c+&jR*Qha/jN!@k!c+:=/@\!9RS9*H9VQ<Bw:<B=8+j$bZtQu95eQNP@Q<N4>nlX+j+dbjt>B
S:aTPd @>hw9u<H#ej&W%*$uw4#5j>dcI/@NW9u+j/j#hKB9*NY#M:?S&G&?Dn@BdN$96@M$wF@MW9@ET9^Z#NL
\1YT*y b?Nk+@k@cydiA+Q%j:XbP9bj#NI#S4N*jP8#Dntt9yJ>F@MX*N5RFLdK84C9l\Dm5H>5@4Z@N^>BF*d@
Q!a84# P+V?\TNpQN$*+Iey8QX9q8H@/NGyiuTVlpbHuy^6Q5DiH>:eG!\MAjn8RADHG8<?kMklkHa*$CYn*uJ:
wG@>mN LGmqSjAY4>LSeED\/DMbGGWPYLXJ>9$\BkJA5A&&#dXT!JqT1De*XniGF<Q!^9JeyTKL:!T9VEciD&C?
BqZt:$ *uI?%R^P?c/:9dFble=/&DVcQ&lAdQnbMV$t9yY49YWFTEdncR%!d!Q/6HQN>eLD6hQaJ418a&Ik6k>b
!S#LAj IDh&cPkhbGKZE@TK>44@awPn:qhLDpai8>b!!PVPP!<6^TL4YhYFu6P8kpAqqMPuuR<>mq^n*p@X**nP
W*Kq&H ^M@wj=:qWnpw$?C/VHZJ9tb:6#^Eu^<6#?*b&@M59*LnSSlSw&L6e>Z&1!j%Qe\PB@qKDq!4&i@Lu4/l
hc?^F$ !:DWRtpedTuDF>#L+J+/PL@bRS5#*ZpXm^e^Y+Ch/6l@WIe45AHuFTFZ<%yptmae1:L/Pd4$H9*TYtMT
#bhPVF BEA/#HwXEkEtb*Qdc/6Q^/#@@PH+$Y&Mw<&y!MPb$uKj8jlVC&R?kN4W1%8&kw8ISd:+!eNJ98%%A&ut
*!/X%B 1&PA!=QZ4<>SGFZRFiZeYk+t!y:PI^aS$!j+=>H=&k<JWADZMbp@VujLp9l:&hG!i+9X=alPi#6MHCpJ
%AWh4m y9Bpq%&kXwS<X@GAAKnZY\!@i:?+uq$=wS/DVQ*YlJ!@P>>p>\p!9jPy#qn@R%8PI=w#A@q1ZB=iyq@1
!w:L+> lMtYSIMJa*?B</p+mIN\K+\/16HMi94%GiIa5?p$qd4Wlyk+444&NADJTKAw5eaGYT9j1mBKK&^c:VL4
^B6iwN uN?hY*DL<F4K<Ic1a!E1Pc>aT?<VS#aBh4$:b\CM5bAWj4mH\KYy=aQG?1atE/KeKCy1N^w%b5uQ4$t:
-AH!GH 000b37bf9be00110333 Page 321 of binaries1.zip
!#GFmj D5eGR!nqicMlkIPc!PVDA6JpDX^#PtV!d+L+QHV&FJHmtIedl4Xl^KZSN+D=c>Hd4^AA4PB&iaG5G//K
FtP6RD tqwcQJ!LniLCwRK6K=41+mkk#n?PCIcPb=Q?>qP=KX5/wVS<Q$$Ln8CkG^Fp=4:ttN*=>Q5DaHb8kpj!
NIL^k@ VdiYIYAFFlBp:q+?HIj!wZdhd*bGQAbQ!d+ZLwI=8!EAYkLB9#D\G5\be&$9cYR+*&hJK<*WaqdmEh&m
*KY9pn k?Aqp&@i4TtcYB*&ekcq4mcnLdeWdaQKluAKd/<nydplkHQ6!5Kt<&SYIV4LHGa?%N:ZhI\>VeEd#mt&
Q@4P6/ qiqq\!@hG!kbk=n1pw?@VHlP*$ZhM4B^bb1?+=um%&C1LS*5Z6@Gm?P4K89%jYkaEtPk>8lEhb5IQwJ5
AnpR+E ?kw^ZQ1=YH!yJ=Fp=:Fc%YGVnj&A1iId^ZLn/GuFnpTQAAN*l\e$qKS\Al?j8c$WI59d6STRa+#^NcHn
QWnK8J bt\k?eXKn=ViC8J9y$bXN4q/D8#ctPwp^lGiI88GS6dS#b@=M4&jDQ:Ad5$h^u^W%JmMNbEjq@5$aaA1
DXKwau XNnDkHaNWjSE5+GhBMR&#P@<4ydP#ByG\TeXieL5LyE@yqep#%q$%Zu1K5^?9h/c@HHF6K6WDbN@i\8J
?GQV?V M\Mt?Ya+hul*iY8:L8J<V6Mdw$mCKl+9PSThmGNHWjqShPjcjShl8uBdh@mup4RQ?QDRlK!dn=hyK9lA
5/yF\^ QNM>JteMW6M<I>u\&/L+/!P?%Da59SJj<P!>p<Ne!PE!A5l4?aRi9N=HYq@%Jm=TiAibVND#T6WXLPLP
mVKu<d $Zm%KuL8Jjn1\1W$!HiF8T9<c$BFR*L#P%%n&GRVimaHk!e/W6wVq^nCe5cK::46j5hC$TF*8+$RRPR^
yP4Z4= BDDa?:688Py5d+iEnaKASk4I#WnP$C%TFlaNB!BaAT1*M*tuTM&je=T1?DtS1:\8uF?F>T5F\Bplh5Cp
&BnPTQ yNMBHyADFL+5ujhhK!N?/jTcT&FAta:t4wyCaL?1M!Zt@b#$Tj$Nk*IwjAqqeEmndq><umSqmAT8tSG$
6LbMni D=F9TiI/bahVc&*wJ?EmKJ@CejRVe#+6LiM41\dkTMbEc+8dFCVmlMVnMI1KNJAJW\qCbWMRZmlVh6^+
:9EdT! uI+D=uH@:@9F@A=wPh*^ek##NpQ9L:%y*cSi%TD:+Zup>QhSSb@@/VIG:Y*%j@8!n!58J&<A>!KH*N\d
Km\c<< &tn6KV>Pbc^BACDYH/e!85HkZ$=qlN#h@uI1A@Qt/yhVGYVjV*?e!1llp4P1LcHNlnj6FZ%!y!?<P%/N
?MW=le SIb=M&WQASBB<$mI!QyLH%+*Qcm/L488QVPTVh>5#CTWTd=A*8:PScVAc4w?:JTejEqKH#I!!lGMd?p!
:im^a= dCAHYM?a4:GcM^hEjh#*LtZESYEZq<**JtQq9ecZn<>eAmS$Twt^9wTh+B/FDK^%MkmV1IVWAI:Y=kCG
ey1B/p N99t#li8D$BBJLG$bhiJ8AAIwK&hFMq>Y/JBiYn$Zc!YSP>4LAAwJNJPAJemLX>%BWHZF6*=%eYV%%Qk
APl/#m a%m6$:9QAm!p95Pcykdbq!by&+X8>yVj%dRC?!byE<X/ml*I$>VeB6BA/c:TGG>ah$I:y&p>Cd%Hn?G6
LQ5i>K =tI9Z+DQGBSHB!jSbS\u5BPM?b*wL6LZMTbb1a/@*m&#RkCMGw=Xh+4uet=*bNimYiW#XhN6H:w!9DZZ
XChh&P K5t#$lM?NL+XlGda%l!QcKnhlp$W/pKGeZHl5uY:tMddIC$wJkGT@BldjJG?kZGaJIm^amwIGVi/uWqh
p/Mmky ae:cTh%biGqDiti^%!n@Cy1l88eeq8Hwy+Wy^Zh*&HmPDnSN=ljyc>nZkqmZL/4KL5*KlkReHLu$dV&1
a?k+DR LB4de<&pJtcG##bQccVIXY>c?h?%!X4uBJa+1p*M8$XJI=i9:D>DIJM?eMwq+?RjI6TPW%q9VaZya1h!
Z><h!4 &TI?iLC8KGR:l*:AAu=9$$R1wy+9\?lC>6+nP1i+ATuK&/leaZ%wcA9:$D:*VceS5bkG8e<#hj<Pkpbm
&XpyM! <+cM:@VGhn1EC$JwhML4jJ/acLV&p5Ltpa9#Pnm>Z6eSKKZBYnE>K*Y6>Xeq@V^FY@QV$n^b<M/%hVQ^
tdWl6m =MPhcIE!?SkIJYI4/=$E1qai\!:><9:k+wu!ZlPS9Bqp=hJTiWG9iVj+njP%@JYEd5Yt%S&cSyC+&6Qa
m/V@8c %ntuF=HNcB+4NubPuY+XdBWGZb<W@eI\d&*aulRX#R9n6Xd4hJMGHM=G^=XYq?<8wjHiFWMAG=Tkun/B
A18dC9 Q^=jjtN1W&K/4C\8nR8C\CVA1dJlWK6pn<iIcYS#dGtKj6IAH6#<6qS8bAI^R:^YjDbKM4hyW>l?VF?k
PDyYQt $qbZ6B%5e8EtT8!Dd!WnP:YMXMXtS8yJReJIJ5l<Blu8/L$&Di6YDI!#Yj\Ky=QL+AZhb@p+\l!JebkT
E9Miaj 16NptR>b+&@4!%CaA+Z6=\eB/\KIJk@MF&@nW1<al?Z1KKyDK:wj$JJK>k%Jw*q<Hhlw:%#Y9*nqYN!@
FtLQ1& =&&w?cXHe@IeZLX:946:K<lphc1bHCBKYB%K<@+NlRHXt5YGB5tLha:FRX<h<:e/ZbR5Y9\dwbj#PB&N
<DC^p5 !$!8pMqE$P9Y>*6ldZqp^bR<c=jl%^KeD1c:W%Q<9qwVt%XMwi8lY8JhTNaWByVlZ@5V$F5!+R/:$VuF
94thVH y>#CYA1tX4WM#wNd#AG8=MpI^j^ch=je8YFZb?KP!y:TTyk$K&8P&CiQ/kk*YKkbC8dMZSCEuq8=#PAl
u4p?Mc aI5E!GIlAE$H59LVNt1EP@NRhMQkM=Q&pM::yNF\?p/pP8M/NXZRpTpDVb5q\di*GN#4\iJtHtmSKLY%
I9SMTJ $%ki=K?nhHZXp+yWenX8FHCuy^tP#5q:iZ>J/ABX=h5F+j!=TWSh$c^^@YwX+jP^JL6JT/l<WTQA$/CV
+uhB9i PMF%$:?ScqN@\\B%Fu%Ec>wcmHFm=Z^MbwiT%hj59iP<phZdHdXXL9l?cT>hmL^1/C4n1m#4QMePVePX
<:tWTK %9!1Tmi4mJ&jQ&h>jQtpGkKkAuXmZlX^G+MqIIAA5nMFt?:dKAkAZuA:a!dpmkTMDB4qK<M<Bh=m@ZLW
VZ5=Ja pt#V<bLm^:G6e5GBqYNS5QYwFmm8jVZpF+>H8>#@FCL6Q$n>L*tSBlC+K#D^aVEP9IAAVEQ9ceib9?%I
y\IqkK ^@Fj=N6d$1:^E!Y6ZabPu1dX19B8CGJmj%d<cty=86dMu:t@5V%JeQ=><*a9!@ctK8dAq!>liCSi:K9:
PPSZQ@ mJlNhl>DA>d4*hkX#P>WMWE9N\T:9<9EI^@bdGEVyBGVKV^$IJ^+H$J>5*ac#d*:44I4!%jTZX8dY#ay
yC@Eci @ITbt8%VDea8YZGAd1aNWii8#6iw?HZ/HlS*=P!E/Ze9*4IwN#P?pSMJ/4DBF%Yk6t@*h@p5^J\D%D#=
19mlu@ LQX^W1?umb&mDIXeR!QM!k<n<YR@VX=e!KZJ/R*^Km/1P=E!hlCF!hbdVAM=PwFb^IdtKKaN*jVWVXTP
A+eZn! ?qmcHy8SZM4kyGdud#8?!&Amn?@5p6^n5\==ehVwP/$95AuE4dyKpX+GjZ=Bbqy=Y!*jMG<dqLtlHpdJ
e4j^dG jl&<PBei+dVjGcSS$iP\alZ?65YI6^A:8&Kccb5n/8NZVL!XFP!>X:WKm?N#L9RSC*4=V9IpK$K$L#&V
?HG?@X Ct&V?A8$JplC?ycE%&&QQ5l:RGaFM1>^eymjTMZNS5i+Q\TW4uYA4%8nCJ$SA+GLn+K6$+Jc!TQi::6K
eH$!8H bR9=X5hwmPXH#X&%*VLYJa4Xb%=R9<&LMp*>LNqFn%WhN*VhE:5IFDXahaQNcbNwC=b<H<Y<Huh=>m+$
J@a4Q9 E@/bn$$<G#eL499N5!te=qba^1VGqpn?Q9iaP\aYllmWa84/ydK>Kl11qaM=*Id*@k=j#Y&LVeMiZBDM
ny=V!e SRqhtmMY$/b@JanP\4==*nl1Z!Jn@=Wm:ZBJGpE5i1w9y\T84+Gi1^\CcCXQPL/eImye8ka1DV1DMQPL
BuY%yI %%:4$Zw>MSPBn&d5uV4ew^eJuH6IIBq>m1ptVIntwBRWb=d$&i6/!JjGuM^w46jdj@cF^!D#P&BNH#/j
?\:>mJ YPXb@<^<wqBtjh=c=YiQ\461=9J695/Y>uD6$pD>X^dp@l44&6RIeFYLaWumD^edpS9j1*>wTLP>lLeJ
$u?EK4 tTZVqkApAL8@>jw8?I+==Cccbp$8cN+&/WIAA>QRdqVut##b96Z!\!4?hmb<aW@H4at6H&<V+&AQD%?M
+?LYCn P8$eRK4:LR?1!abBAA<JL*?u@j&>S9XDR>Te/XplKNlV6VtyPl/>kIw$yyZn4E@yi%Sk:ja%\V4k6PS6
4#*h4J HckLbPFaHHNqAREEkphYqMqPS!GAB*h9&uIF6>LBD&<+Z+tBlwG*6N<54pMlkGVHT<YDMilW1@%uE9+H
#F5XKP cj=BXp#c#lSBH=CZ5N+KwqW6^IA=cG@qVKE!^N8?jaNj<NVb>i?G=D1Lu5wm@May9iyNCwua+n$Sil6j
:A>SVK Rp*ZdWKnbq&*wK!EWppKc5bVek^T9MGq:>u#S=Mqktu&aw^M#1hwMM#Dc#L=Ln:tiANXHHtP>jp?$i8^
JcN!K\ MnuBHZ+hbQX<KLimnhl:tw/YwBeMjJGE=ey9=I#<y9Sim@IlC&RaVd9H=:wTZhhht@BSGhn9T8%pqwlL
TS+%EX *K%8i1ByP6dJH*jLjtl=*/kdb8L:bIEAJyGK9+hV8n<JRYD$tbHENLe$VbAKS\Jdc4ySTKmbXbKKN1qG
$wcJtC wkZ@dMTc\e+nXe&t/@db>Vnbbk:pnR5aSCqK<?IwP1Vm<$M4P6$Y+EJ!Gi:iTBj66pCb\>=K1+V:8p#j
L\$m#A Thw^5=L6XIHC61^#Ybbew6F&\bVjP9Yqb\@J*ji?@Qaa$KiP1e@:14yhEYnn:TWPe=nEGML+\S6SZuAT
LqNN=q la9VdyYZ&?@ueq6CW!MY<SGNTnT\*dcE&t*jA*w8YcE/RQKCRG*ju4S1YB#iX?X9MLEaMw8*FH8CD/PT
9pLA=< N:VWZB%mGJHui^=#1+#kDY+%=&Dk$m%pj>@DBX/HIMYKKEuRpE5@#FTQE$MyVdKyhcqA:Hjlq%9%wk=/
1TKukI 4DZC\XdYI&XT%FYt=H#q>eN$H#4L:/WAZ\6iyF!5k^4Id5$WL%Q:8<Hum/A?V>Dt?yi@G+!l&ymbYDJQ
6keX&& 8DlcNE4L&$=+yhiJeiJE=XaqTkS48J><B/:b4/yddP&FYdhc//^pSuGXPWcH5u5tG!VJ!DSb:/D5PX^$
$Dt:>d t#kK*waA61dAMqDGhe$/*aWAcDlB:>19*CCA?Dj6T!8*LcBB8bXDS:C?+Gcl+*e?CIAq/%RXiJMPAcRw
BAt8Lw Z6FDl?H$*!Z@<njJkZ?VQQ*8I?n91IJ?yV4&5%VVj!%>L@Pmy9TGX%BNtBdBk#&Z:GeuqVPhj>l+9+*A
#lhuQW 1!V:ESG&m8ZClB/B>MqALkVE5h/EN=iT9h@p4SW8qX%L>4?Ny/e$KDDF5$Zl9lPl$qdmhDHEF/%iMquS
:QW^ed u?96jtlS8BnLkLS+H9ucBXW%yWm@dK/Sb\EC$E$V16MNDRnCWianW!p9y#Mnk!qc/DGb98*>!JW&kMkp
hkZiDA !+4FpGQntcYT6KYDmZ/mcKkhdl5^cMIR>&qk@jtIld4WY=+LnN5Q\pLQHL^N9:!jLW#TRHZute#bFDcL
KJ@ATj =^Nk\$9LP+l6ENlP/4dXTB<Zhm8c%TqLRyXkpDpn\!ymeCq1a^+AMh+NR\DeFy8CTiC6H+LZlY\IAuCB
&KPma$ AEc%*&F8kh/B658ZRp:dq>4QNB^E4\\QDc@KkBT*Xh>bd&jTa<GcN!qkt^<#=>d@Ie*wj+LRQ<!pFJXq
5*^XK9 lG/wL<edEctP%PeQF<4Y*R&*DX56TmEAn45Nd5&4qCPm$9cSh5>ShdD=Vb>N%Su4M1e//I*9TX4b:jD*
-AweeE 000f33fb4d700110333 Page 322 of binaries1.zip
#C1p95 !Jq@KnX$KGn+4&Tj1lRLA=@yl^*#%+5*j!jT^a=H>KlLly/5WS/yP%D5iB\dPT9Kk%amLmEA8iW$1BbQ
M=JPVm eAJ?<+EdA9Bq*dnn>LaF*^4&Z%8e#>%h65ien?=Y*b!A%6wLHj>JCNq8?yVl>*Y\+BT\5Q&w>^bWCIJM
VC#J+e :k4<W&AIwB9$4>Q:4eR%YCb+?6LQaNwN*?QeM#Z>Y&FaHjhX=>8KRd&ayHWlZSu4y=LG%/+%8*Qe&>Gu
6tWSAX !@K8n%1bwt9I>j$hHnDARkCaB\R/L>Ht4y@*:A$m\XB%lVbSV?T=Y%kVK4ueHS6XKBa^4Em>eSmyRLNG
WDejki dVcLXLytD#L*XIPS+iMt6=@dNX6+*1%AnT&^E!<*TWGbECbLGQEX9IM8dJm*yJFWKG5%<\:qwBRtyW!Y
ah=:JV uPtXSiX6e\N\BeHcI$8q@l#N8i?X6Bp>Xm/tmwT#jIlF==5@4Zu>5qd?q$W\M5#9E^BAiZ9X\*81@4iV
uT!9T\ mYw+/*n95#FHpLQnSRmPNKpJwwE\@6MaDRKH$Gjdh&SiEICtdhWq18EN:im%\Bt+e5:\GL@>t&L/?c59
WSWW1Q h@1X:c9MwIM5+M:N&QX:jXCHDkV\TeB^+u9YlWeLBPDZAAHW?1#pHRu8jZYHAGB5IRC#1*dJbhDM\n+a
Zk:Mtu hk+<iPad$\wBqDZM*TJW*TZ<N/lBb6Q@/#V?!#Z!\Z@lNEycyNKeTIZI*4J+a8Mw5RddICCJ/Q9H5<Zj
NN+5I@ ^N!cd\HC>DjjyQJAtTyWSuY%TV/<^jZXnaM1h%/hFwS8tTaXA:\5q@=RX\N:e6I&>Ca<GEtFdn89eb4#
/%<twI ehTY+ei:XBVFDDWMJ*t*6N<F5R<jDDiPt#W%6eV5m\$:qY1IG@BVm?kdNNA$%?A?lp%N<QJ>aWZ>$t@!
BW6myM $PFNy\h%9q?^VZkSLX\amj<eq+F?K5IFT<jG5=HmEuYq$TcA:l1FtnNa@*1%#J=k:/!dQi6NWL/*W+He
9by+C4 /!kQ?\<*bDDB:YSuEMAQn#dyG&DRu*#N?IDG@8V5^nHtCkL+^R@NCRRk?ChZPG&CZ@:pw\daj\5B@MqS
!wY4#6 DqRTbQ*muGdq%<!!jtny@=Ye@=*MTl@anAeZEBS#H#V@j9:!q<$b?iZT&bGh/nipi1?$<Y^p&b88B*aK
F&:%4E p\R^1DD1*L=XPNMEl8:VFqLtMNpWlH^C?6d&ME!!/nQl+C5BeX>8JVm5@5nCJHZnd*GcXX@NFdhSm:Z#
Abnmni <PXPXiQyNuq\tP\\cYCLChtZE#5JmJQYhN&CQ$*Klt4wnGjmAD>Fqic@1pn9<LRQXc^c/lwJ:l&iCthb
utWaMQ 4R?kjSQ4\!Z+PRtyWPCS!:bE&PM?MY8W1G+q&DZGAZ1DyPe8qi::wet1CAtn8\MVQlTn&kbt&dtQ&?J9
JGLmIa *=uE&*^ZZyB*5Ti8pVNBkTM8JuQ\>*Jj^BI\dk=c%**Qmb#cl%<\TF4A>q\Tw$^wli1N?<%S^M\WnRnm
KcRdEc <L9LD#^PSiEJJ^^?DEl/L4b#PQt%+qa!=K=+Z4MGDMSljb\jQHkVBW^dp4X!<VG<a1tya6iJl8kyblS:
EaBCqF CGK@>Y:M5SnMTwN#n=letTRI4%\AQZZ5Dnd9K&S8V?K8\nZj/@LW8TWFtyX5Ka<&p<*96P4/9mp+R<8X
Qlblqt *tm56%=AbBCb!^&tS86JR1&J@8BNCyqMG16WJJd5Gu?Vmj5tq:?$6ceh5/8muc+4^nZ1VyDh!*PBRM4C
AB1dJZ M#*pmeYD4qalHa$aHVK$9C1DapXX8cSHkR$/uEy>YSk:=RJ<MMyj&*$cbl!NCiyp+adm?CpJ@jJt6hQ\
J9^&y@ ^YtwpELZy%i1>FaKLl:RYM$PVuh%yQqI:YTuLFY<WFdd@jD<SQ8m^Hnc6>A?jYILy*!VDYuGM+@pyMCY
i9^RwB j1G>%kq+GY&Nd&y9N8ZN\Y?uWR<n=/PX4E=!>9#GKKLC=QBBV9k#AtetYA61aIjui#\dilJu8H+jab>i
%l4dB4 RVw9HS<eBTPcX!JY=Z8VhPhNAEph>%/K&TN#PlJFN&aKCZS>Q\B+1HED@+:S@WJZi#RH<%qTHQATq>mF
t?>aH8 NmaaA9mmJ<!>Z!Lt?CmBa<k@:<cwl1EH=6liRkuh^>tY&YS>d<$w9p?LD@6ECy$*Kc=dDWP\%m@<\6GP
:\Z#65 Y*RRL\wI?H4ZjQBZ?#h@&bYT54P4YByE1Fjt+&aKLdYhKw$$=HH$cT*@FFAcVkhRT$N9iqJ$Myw+XFEH
J:&:WE 5BLG\%5mj9%>w#ckhNaQ=hD1cicdPkRqcRD5ak%eTRF\cNZ@HRJy$&W^a=6S/RMnkGpN%>Jp?>!QZcXY
=H&>F1 #SRGDCEqapjSSZy51mwE%IFVB*KWlKYyNu$EWTW%NdnqEL4T/n!A8HDPL!T&6whR!qT!aj51lGZTXIwP
Kt#6kT l+hYA^KX/@BJ$FNum:b6ZM+ijZ9PCeBFWAKRAJ:CRMju%4@c6y%B&McjM%Tjh5!hQYK8wQ\\QcqF?RK=
QR&5:^ ^BKi5/itCa/a\BwqT#tp<XLQubDaT+Z%/ijRPFTJW*$/%lPP+E<Cn$XCRlaiuit8wL=QdG\/C>4AV<#&
X/iG+W cBE9%ybJ#C8>CQMKa?^9$tNyuh5MPJKNJ8Nipdb%Y&K%iBl5=T@XQN1y8cb$PCQmyc\wH<dNKY@4#lID
hw%Y4* &4/bteqq::l%\DdSZm/Z8P%taGRkm@SSZ$/>Gj!a=a\L>HXwp$nnTiN6c*wpA#/kyje<%nq%Xb%t?i#<
:e<j=Z :Fuim%&u5/Tq\D^blwKlAD\>Mc6H\pn4cQlJ^8PimE$#EW9=PFi%J=V5bh=H*5ZEBqI$WRtVFlFVK8jM
l&KQdj Btd&5<&W/^jbW8aRAL=l:ehkKdZQ8TEc/^Mq5WYE<%VEIT5PAhuGAl?&WahS/T\ujV/>iMqjm*h?b%y9
#9VMa# M<uKw\RnImRCe#L\@ZJ86Q*C/#$EEFh^=\1K<qtEn44y:XjEK*QA@<BjpNp6\\%DHklkb95ILNF$MR4t
1DXWpw QuP<M*CAADb6RZw4@/@@K?WKTYuth6C>YLJ5j!GR==9Hm9aFbWaJ1Sam<+DApwKWjaXDbbZdRN:eBV9/
/nPj9Z X6LM!G&q*^y*ZT<J8XPkM>4Ik=\VRm1J?G6MDm@#ZuC?TY8:y&Zh>JN6tZ:M$wKE1ikp?:uK/YiQRmB#
HBJYdK 8waRRJLw6e*N?XHP6icMa?Zeie#*>wc:8W+IAC/w@ST1QK@H*KV>5DwpkAB\RW6V\F8@>55<<Qcd>p$E
lLd+Lj CKCZ:D9ZD^6DXnAhBQC8$QEKBuRmiVjKCSyAlRDCBR?6$<FCl4jK$Et@*My@MnQIPNL@Acy@qBt/G?8X
4%1*iL ByqY!m*u@y%q!FG:BQnN^jPuMW$Z4!=Qm@T+Et:yL@bB88hX8^k+4#T#hmEA\/qT:?WpZ\FB!/Vubc?b
EZpi9w &45kkCK*GM*>FeQ4kd6HF^DA=QpFuhe%KF@R*XCl+h9aQecWjF^@aE#J\<Z*:^yVDuVw<bImI::GVt%&
lblyRn JCGXMLYpamIjScdAw+A>bj8ITM+k&!u1:LSySp/wBQ>\<D#WpyBp4J>D8cQLX+&um+/dHb+am#pGDSH8
RDNZ8i VYh$Qp5FPm*TL&cS8BETXMLCI!w<8EV&XBRD&X9YLTtIt8?h/5*65LC@WyGW#H=^=*4D>y$pheCEHSj>
A/T6w* ^FSb&1%aJlDdR1mai4peJYIwEM/+6XCaMq+/#?YhFaQdd<chicVwXKhEyMpK=Qn:FAnPMC*6JCWS\cJc
G1:Pd6 VKS+<q5PmE>#ANQYk<ST=9E:\lLG/Ytc=K1y+nkk6VNpSNQw#A\:*p^$JB/GpMhBn:jPdC:mA8iL1&Bp
K%5Eb1 8n1KtG\bQ6cHwNy5E\ZBTT&>//VmFcJnp%WnyGPt!CDER89&Q5V9yIDuIETAVh8Cn*VTW8yGqK*H/tMh
::V6A> u+@p/wIS?9R\CB6Ll/kuIHWZW*\DVa&#W1/Pdb^1H/e+EplH5p*\@C8lVYIISSjQ6d>Md5Bal@D4jkAh
RB:aT9 bi+AkmRF9BkD8yTwY^FmBK+JAX@EklMq+>=$Fb8R#Ya9HHKuqCNmFa#RtKC+HTp+?YtPqR$BA6&$C#%c
4kJAK+ u5&WaNR=t>JV6J1H!dnIVB\#k6G9^bE=P5@9YItX8$tDCCjZbL+LIbSXMAyP=$SC=BF#SQFW%XGDNImE
@H=^!? Z=5VN/5$eCQyS14SSPkm\HW#DBic5Ntp6<cm#dcQh5d1^bX\b8\SLnnijK6tH/jD4Z9ASD#QmWCSV9GI
CKQjkG hW*wVKIu5X!1Y+\d!^S@RMuw+B$LBnMJj6SG6lDjDJa=ItFQ:K69jT^+T/JK1=/BL6#L1R*dDY!Ela@b
\::CR/ wyNeAi<1W8Z\QJhS#SMEX*FlyZCNJ^\IeM!=tHCcDQkecEn:%\DhQ8yNWiKwJy?mZ<hZ&\Y1EItqHMbE
6F9K=m YL#DCP#5jGMuV5YkAFj$18R59\/tjS!?yYJytE9RkpWBYXtcYiMJa&!F55PWZ%Y#L^D@5MbBNPV\yT=m
JHZ=E5 M+K@#H:^i55naF5kuME%@*bi5!y<Z=LSQA<<9n\iwSEj8VJ8J+?iD6CS#Y1\:iDKbCw$mI@+Ln/18?GB
1kZ$8m itYiKe/:upSLyFFpKw8%pCnTe\*PKKLm5^YMHHnX^mAe9M=WF9iQXXc!V!e:TJ9YC%9Lq%C?>lZ^8#+i
?#%RHH Va=T1>lI$Klij9/P?YSkt@eXD:=lklqjIZ8\1haa!cYb5ESI!yeFN1FN8ben^wjNZj^JC%GJNtltI%?#
bB?+YP 8JA?V8m?jGJ6#\MZInuR1=*G=/w+m5M^5*%H?mD/6WJFCuqj@q+Y/RNl8ap<N5*M8KEHNqV$k@8$GkQN
<YetDA 5cn#i1^iBQl==Hy^qQVMSnptKan#h=V<n^Ca8M>Vm*cI%JhEqYPa5BCTcLEjQYY$KGkt#E+TY$^ZajJ@
#lG#TD AKbLShLHnDTlbnqBJ/a>H6pkHVhHa$h8FL?WcDZbNGA#u/ERiVKG8XE9Htt#G>tD@BIkP@FT8YC/4Sy4
TR/A*4 qMVA&IcqFK$SWY6YF!+RyIR!eh/ECE8w>LLaN:a%EEFI4YpP%aTSMiq=ye9CaQd\qtZE:npBwy#?k6tL
iq+GC& BM!CdI=t4J5%%Z+&LPj4ITD*k@X8L9Qc\R#<Qn>bMmq!@\Q@&&cJ\kumPpHuQRMhaWR!lEKW!wDaNNV1
dZWKAc T+=SC?4H9mPyVb!TT#PGM1>Na=PKcw$YBwl5IkNX+uc/KZ$Tne5MGcZ*%QGS/llq&WV%XVCp?F@5EHem
yFhjWe wGT/wCkFBM&dWRitPQcYyEu9XC?<PZh#6eDACEH<Ft4^NCyGSc1=&4Q8$Y6$aqWYc\@/bpDY:MNCn:Lu
eDB=ae XN*phwt#GYBENbn>S1RGDFqaa495dBI/QMJRFC&/ZJY6FeR9HlFKV8:PGNajqd<>*q#<1q?/\\XWbAn8
D:KmBk ZhLVbdN1WBaYN+tIqZ*qS8:*6FThb*t9P:GA8jhP4Ip6&9VymAj!RwX+51*+VJJ6:N+TA!H\/iKB?851
@!BVIX yXn/<1jZlpuDR=w5!i%#V\5@cJX&8en\6M<!+1/IW6<?hd5qXeN9NE&aEbihLQk/NPD%9D9@aXZF!Zpe
M@IMDe *iPbnGu+tNnHL?w5e8RJ4GMNi8e#XIyDH<Gl><LDKDlM+Y!?#>F4RaDlp&k^Yj$a>&1PA+5D6X//AKlV
hIpZQq Li8pPP9%?XpbC/Y!$>9m:VC6e&quB$dtJ5W?d:&tP$Wcy1J5yetA^HXSEd^J4lSYly8QhNXb<#wD!kW%
%NK^$\ &8YjLtTI8&Ac*GF&FY<^:YK?T6yb:#$taqlS:i^X468b=^yjZ^PDjRqCICl=FBBEFP#$8cK:ASP#+9\I
^9@yw@ Qh!H9/bT@=Wmk5N:tLhc?jFktYJ^4pqKW4*Z!t61?H*+bwRiE4F?Dd46mj+C///Fmt9SipVIAtbpJ6p5
<#J/q* !9GHiTtQpLNl1Y%p9qDY>i1@bSbRALFYmAkebP6!ylMwX>?JYQna?\GW%*RCh%>q8TA1#6VyWyuj:lbP
-A!QnT 000bffd94a300110333 Page 323 of binaries1.zip
=Hi@Yy :cnyZA*RIhF6+/qtyAm@4T>B5IKaMVLX!AFeYbSCkVwbyMenHNGmB\mSI8SDG*By%=4VA%mI*@W4GnI>
e1jClV IlwNbEwKmat5iiteB>nJ^Znak/X#y@nNhy>R=\a%TBEXIHTMTcjWiTl\hiqMnT@C4c4M1Z^MR/aGbDN8
:aQQ!u $IlX1qQXT:JmMLd1tFw9e#Fw%V44NeFDTNe$\BIE$Sh%Tn$d9QlHBbXY9Dc%<=<Yi#SX!nnie$w?M8VX
N1Qhy9 8JGpt:\Th!uLqFYmR=h=F!D8!$h6Qpa49Lj%\CqY6bXSbiSXSyC^4C%ytadb#8\lI5XCjp+ISXK%H4Nu
nlNeXe ubk4iit\cjk&QWS4+MZEkEYm=y11c5c:m6$W!nqXby4cn9PLqiEt@%jtMYCFZue1qQhahElcC8nG<j#w
aPBp8$ Ht5p4MN^QBX:<Gk\dbR9mbQkyBLwJYF!uB!\9h>$TiJXau9uMwhZn6aaw4TciRM6i\9$5p<@+YwlP=&E
>d\%Yh $tPSF##1@iVhK<^ikb>c8ZRiE@\<Y&KbqGdiG9QbBVZm!:9y#$Xjel/Ck$hbcSq!h:>6B/#Tyh9Y>yhW
t*CJH5 d<E=/n+i%nbZ@hcZMuFZ9ly1*L+6V>6#XmKVDuLM$R$Y4F!+?^VMWuHRS?i8>^:<$hQ<+HY6PauW!Y6j
c:k/eN *<G5=Lk8%5EnZ\9N>#yIZ!EKQk$Sip\Al$GYk!Rd=Jj&ImYY8DP:ySGli?1>Q1P=l+l&cTq5yAmAbkSt
E$/FGk 4KKQj5@#bQl6#dI*n/jDp:<^<D/*RlP%mDR9mX*jeluiqDJFZRA^84Z*MTVLuuiP=Z<KjN^NL@jT>A6<
VL9@d/ :4indTIE%M5QD*Jh^Tj>1NtenL4C?yZP!qbNP4ayqa#iC+X?5E%YpeQ*&^<CSVTjFX<44m:ahC#4B#p$
/DCE=% HeeH^ld/IQXaI+>dDR=bTB/WSV=C6b^uRTaFQhES@bJ^$*>cL\ZdVn9b:4T6yLVZn?HdL&X&lIYeVZY=
!F#lN& XNBY+6BSWIW^iMT4iFmQWQp+TGmIiaTDW>Vp!ea=nER1WNRZ$e>GX$REWenl1V$=Ek*?apAyh=+BBdai
lNM/4? @*yk9LLFyJE^Hy#GM!w^NH5&lNX+>D^piEAw?paLBT#5H?8w*Q>:Nwq<=H<&%QtudSL=iQ/%iK#5HG^@
N6ENdW F+?Xub*9u\1:#Q:ui9+YyjXZC/T@5&*/A=M\Qy/jNb#p+@$bNQA?NN@QwLu@GM*P^9a#cM::$P\@k&c@
kqKk8i D<*^E&l8999RuD?B=8Vq9kjN>VQwi+IE5:N^@\!c<#+$#$?kj\S<@YQ$#@AcB^jjQimj+VWP#96w@\!9
V\N5?c 5jQiR=9>b*mNHZkQdjcj+dX:#T:b&Z?G&Vn=:9qp:J#@F9yutI&H>:/K@\!#<dDhl@:nANL@5QA@F=1a
a=!d6p E>w#j+Vn=iLpIij?1VnJj^Kjj&WD?8h!@EMd$F?nEj>mA@y4LPP@#yj*u:eBla+Q9>1AeuH@^RaWKtd@
n6m?Q6 JS6RZndP@:MtwBYAm@?4VWC^@tICtn=caN%qDYkWk8MGQL+et>B=eX6H?#u>*PA6BMA$?N*mD1<INM#^
RjPAI+ /qP:8QZK/WmYl?N9KVV?p!pI@yRCMy:tG#:X99XG+GAq6@:w!pL^QZCu+lqaP?F\>JySARJIN48y?@5W
pauu@u H@:6FDC!Sb@RDYayWEIZF4a?QeQZdEKS?4dyi<8jhdM4PP5+q\Yb&CH/!%GGwKcV9SeE1Blb*w*GD>PV
u<u=py A?YH+<ljFi1wyJKe9*kn8Qih:I/C>W=>lP8IQXb1#nS:jubWHHPKBRTbVQCNP1Qd4?l:=tmYCRGePDa1
>WL&QW VjpMTeQyS5bN9=JudF5=Y8yYPKQkI6=$*%e5KRwC4dRS6W6e^b:QWV*V6PZcuY^j*4=:6K%+*TaJAWnJ
Y1t!+q RkD1L8iMd$YpG=:Jm:m@i<paFM/Z#I/uul%8Q+%@SNF69b451V9^68I#Mu?TimuGNEXuB$lqYuB9m@a&
Km^!XC QAS5%XHH*@khY&i$hKSP@t:<8mX&=TBR*PPwdj:<kq1W$6a+%6%eC=up+VS4REc>hn/@/i!:Glk@hd<$
AbjVe# umEQk=BG=k6tWZCqCtmkGLRhcjdphEW%jNa&#^t*YycGCF9KclpQq\:JGpQA<jL4J\lklGd8N1Plt\<C
M/MYS^ cE8+5:n#HIFM@c+>P%#$lBFPLk1p45S+#+\c<4m6DVQyL@bb4/\n\PmkT8B?5n9T9nInQa&&tbK+:hG1
Fihqqh /!8Zn+G9ZDl%wn=n18lpia%By6NJFnq8k/bF%#EEQV?ECkl<Qt%4MK??ZuLDA*mH!iC6T$/!4^nWM\>Y
SZui** WbtC%WJ>RJYGe?Z6Y+Y5q>#kb9Yey>Iq?$epTKyiiEV!\lCAYNMll#lPZV?=PJMXD?!H$%>C*nqCALBP
WA<T8@ /B?VuJ$=c&T/8c^^V\cJHIPIWy&@1w/%ITw!>8ZZeW>HV#PhAy<\=e#w^Z>Rp^L/?nWcA5BIc4b65B:=
/CRlX% PNEc%K5i#tYuG%+cLd<LE=#=I/SiE\Vk#&9I:@Kp\W1jTLnlZR==#Hj#Sw+@dDW9k<T5kSZu$X*y&/n9
pZkJy# yJCbud>/Z9:9QWBt@*%T8hH9c?QPeL6&&#icLCEA6lVDW=e=6C@kc<YL>I6%kWR*M6n#S!HBnnKCt+dN
<QtPtA F8i=aQGdaBBpL9NcGRKk9P5GFyCh5m=^im8Dj9jkFI/I*MCF$F^eMw@T<HR>T<%\K\d<RLDT5bV%6B<C
^S:I>L kM?cA<+RZJqCAAGK??q:Ede%EEAu:eZwlVlaC\JaVdni95/F!l@R5jTh/!6qWLLkJVZ+ZX6^?#DbLR=I
BK6Q1? d?Wj=jdn9Idkj=SeaaP/kVmYj$&P/uX6p4wZApAn1ZCbF@cQ8$@u^I>R\ib>DikjP89P<&%nl*J+1%W1
$D&<*a lK4&XGMi!^FW9K1t9CwhVB1IiphJXi?8$5HQ#Fe55tIbSb#JF=NYnw?jYEKnWYADI+l4R$eYqpjE5?l6
T>S<K4 CbtIH>%?=tpt>RuBLLG4*ptKwkhE1CTVquc$&EbDq5/$FXawNRyA+&NVFmtHAB=YI#MR4F%Gii!G^EuS
BpTShV KG$amcSyFDtSkNyl>mCAJYkZa6haPZ*FS1J:FbK^S16A#c?WVK:pwlH6GIT8TF\GJ*>5b%5cwa%K&Fa@
Yy6LA^ ktdVW<5R1G+<\HBlND4XB58#dE#A<XTQWZiRTE$cGT%/?P=LS&SS&AEh&/QQ:Y@C^YTj<hI*qJjYM+SZ
LqlT4& /k&WDHBGC/t<6X%Ep4T9uMXQN6<pT>\W:JLpEpS^P9BQV6y9I:h4:cZ1yp/R1MCJP=d!ZTR*pQ\8Gw9G
k?q+%8 1HA^LM9K:9R?&Db$P>wEu1p9CA8YpCN\JY5MRh1?VIZqwX1kMk%b/Cdh+!!aG^8i1p@QN1liG&nCTm9%
aCSGtX DlCHqAYYT$clGiHAQy%>j%yJ8QDKVlTeynT511nRd6uEi6y1*an<I=:Nu&Zee%BL\ub:Q?G#P:J?%G$I
T^QIi: IQy#%t&ZQtl\YI@##?NL=CPCVWEN#5tata9tGM$anFiZ5@W*y<tE<by95Jnm^/XYqb1IV/1Gt4>EWS9k
EBMZh# $JuQn%??XyJ5=n&AVEE:TPkhqy>+9=<RHi^pl6Cnptl%qB\%JRDkeVie+eKHVXm/Vi!u$1VFY%:lji9C
E1*<\m /1X#B=j4ky1#kq56bNeTkliG\JtLtC8HEHBe#J*t/MW4W:B8DkTRD?Xm>dNZlqDGVh+B:SJCADM?K@>H
y!:<m> RIKR/hV@eJd\C^WH6yTjFWp:T@wDJb/1jLA=Mtl8QnwHpdKtk=>=kM+i8EMA6M^PH$E@+u>16^8\8SuG
Da:$Qq *tqD^/qSpEu=#l^&eHS4y^G>R5PX1WSS$YP8qwkNC5$N@WF?wj&NSlBpJqPeu:P$qaMyjGb>!Ad#wil*
Wd8&%M W6ST@ihJ4T<iWIR!HaiSk1lpTm<kABMF%me%n1S>mP@8>1dmWY1WyuN<!W>Iwn+8SndNpw6L&wbVbeeK
NSW5@y *I1R%a=M=\djbi1@NJXweJBCZC*DX%6hT*wNbGFR>!QQSKyWttPYNtyC/^YyRcu5PWNSa<Zny8chh&^#
Rl*ywZ uEw8CI?Iq:uIN9*kia^L$8DNctn*EH&*PewmYGYm\Yw^Pnmp1p%\L9%1dCX>L8YZc@494mq@iJ<FHR%<
Nhd@aV Y%e??6+86:d@eq*=*jZHG>j*@PR%JYk9BJtpZq\LSlPMRkCQ*k6iBdbAAAuJ#bcC*!hB=T6XlE>bB*#L
4XSK/J Q>Wb1:XR/w%M/w&MEXpc?YFNP\tL>Kc9=dpJ6X$<&?4M%lLcty6&DFJD>PDKd>h/<5Ft$5HJ91Je\!pj
mGuX1D C:ct\KwBdD4\BVKZa66ac&C>nb^uLS%QPWmp%K5l#6\@#hBRFNdBcPjj*bnk@dXV1Tb?/YFQM5&RHm8L
XWMcnq &E^b+!h4*Jy<b<pmk%AN*Mb+Hq9NC/1IFD\L/<G:QEQTPu5++JMJS/IwlqE8<VA<mnCkPlMj<iN*I4Pj
5#D&ZE >AbccCaH%FZVBqG1H*R\I:eWC::Z::5^ycyynD\nb6=+4l$a^WVnd<ulk4T9m/X45ej9bF:S<!&&HH9*
d8@SIk lVq8DWLtjFbalQ6%j^9#6ek?8ELV<Fln=b6!?uuR*J%Pbj61Sj6BHuAZ6i1/RS@W1R9/JPE+TYB+aRN6
EcqJwT 9IBGCKA&emYjyZ%9B51lCQaRkDqS8=R?cKb$H+!!CB:m>I&FJm6Vu:9Fc:yL6LmnkKdTKK8/bHT<wS9>
EV=EYy QVHw<JZ/5&u@1tCI8u4<^&R1!:IYGFd^1aPWd!Z#V#H:eS?Ba#cC#pD>DtNka=d&#c%Kw4G:</^>+H:Z
>Vwu\$ #i:l&uZyw8VkX5KpR*t&6+IwZ@b/V1Lt+Z+R?=JZc4qa>+BCnh@GFA^SH6IdWRuAe/@b>5%I4ja*M8^Y
%Lm!?G +#J+pTIetY>w6E6wPahKbWyQFp*%1**jMy@uY4a1\M&+B@EkBR#5FdReKiatWmFy*tbhPq+%eaMGIaBk
tn*yqL CCDh>i>iRJX+QGnQByPA:WeNV$F4:h6LM@@L#>A^+Z<1\9I#qjwnk/S9lIdAY+<DCGAdb^?5wLPYAhXB
pBQiBK yeF%91&YhP%baB#F1##kj?lGEK1Mp?cCRbjTk68ST@@98IFM@/Mm4eDAq&ppF1>*X%$Q<dP%@RMq!iSa
HkYKJ/ i&ty=$qV=DA&NbIIetq<PRPtpnAT:l%BMYn+&ja@?@QD*AcWi+F=bit#<4@%A=u>qcSbI+FVV4^YPQti
bA@!wq QB99@#SicdHKVD8eH:F1j<mYbBZIN\BKtImy/C9\%uKeZMc!ZP\HJ!@$=Vm69GedCWPd#FIA*u*Ji!bT
DXRLLu RZIhTW@J4Pb+SkYI+dSljcddT=Qb/cuZ:Q\\PF\/VTcMPP\lihV*b=q=laRCXh/WNXdLBC@:%MZw%GKZ
/d#*#u %Jwj%*Cy!Q1Rjm5TQnHm+^@&TcuVlR<5q:5XJ$ukWJnh6*pRm/p?<W4IS>C!:bHX>#MdnTnu=?>%tyP%
QIN1ap ilT@?WWN?SneGAhD=+P@^Wu:%ZeGbQ^4&9hd%<W:+%8ZJ@?VE5Z^$h=R<jZi4HiEJMCLYw^hdJynaLK/
wHGAM4 nNq*K5Q\QC6XeG<H6CptiKdkPPq4BBYAWH$lD85Z#%DTX/@BqbbkMhFjwtuRdtNi6=BhaYQ?mL9^A:d>
dMQ?ke n&Al><L8wRaXSXu=6=$RkCauhH=D<a841aR#yD6>#N9RpB>BRSSH!C=eBW<y!c/KkL8CdKCbeRlkIQVH
1>JQ@+ !i+@\WV@C1a*>n8a&?>lI@<c:J?t^6+&W/n/cP9LLCZXAYGi#PP?ayk^1LCDc=?+hd1uk!1Zq+<pB&FX
CPbNj$ c%8#+5Z%p$qjq\5TLKD/=hchWX8LbdIXe1NETytdpn$cJjXlpX/5bPb/ipty>Xq/8ca5HDBG&<XHZwI!
9@?iG@ iQLTR11%$:GwVy4J%WCT#q&yIGqnHT<^aMBYSW9y$lT>4c$JJSmpnMIy6hiJY<$?#u1+GL^XMy9H5IDJ
-ACma& 000371d433900110333 Page 324 of binaries1.zip
HytDCj $iy^^DSSk6%WZK=IPV4wd$MHmJb=?nmXy\>hlY?tmpcdE88EAXPdV/Qh5lwC+A#t@4PeH1//En^iPZNR
P%dR#\ @*XeehpHK>+Cd^iV@pckn$Hq/1@Cj8nQIQ*jRGX@A1Y%d@/\LSy>=@+9y:TB/qWRADwE\LM%>/eln?HZ
k$&nJ: yL=@Hp8IwF1$@B?1aWR@8quN5=ilV?LZeWmj%=W:YNHJWk+46:>il\CcV$DNIL*&Je@&JeFKHuHpk?^y
\w4pkI nBCTH#%!=9jLaip<j/*n9aP1mK+R\C9c/>H4p#jX:S4ll%4K>uDJt%/EYc>li1C<=aZ?AkJk*PFF1Q>5
K*G<%t a##\PdZhe\?4NX*MQG:Y<DQHVFi%W6Fc>p1H%tRDKQLDGd6XQL9$I*FNQ&1q^$^LlGe4Z>$YZXQn+pV1
4e&\^D ZCnWbiN6yEnTQL1c$TCAAkeNGqPm>/4Q\yZw/tRRT!wQNdP:I?i9IIAQhlc@lC8e?/6m@:Ea?VG*@!WX
BwRBHW #KNuE8&bqttE%M%STW<+JGR%A&wDQIq9tVmknZ6Ni%8:AP$pXXh%\E8RGHT1wY6+Bj*cQNB8Lm?+W6d+
@ZAu^h tR^5QZ\?hZih=Rwc=VNIA:Y4HnyiFhGF9wdu#QcAL:%XJ%jJ^*li>1bH8i#b^@B\XE+kPRA&Q%/VhW4^
:w5EPK ?>/4$S<l5c/6\ZiK:>1*M/Dm\9jZHICFYWjVN?q@tQ995N/@ayj@!V?*#$Q\GTtd5FYRGC/K*Ap#:>Hj
yR9I=Z mcD#&^TdFAK&iqTHpcA4l=JBcXI45nZZD+yh>dSZ\VAZ4aNeQKjmbHC$PLiS6n%P+RXJ4^<69kZppGnm
lAy$k= Zje%+Y4YniHBmlkkIJB5\JcYF1N/uyd5V^E>Q/^^Yy&ZEHPIuCaX^YAt#LbGIn:$@6chKqiA?=GiFt<d
/5NuKA BpFWhZ*h?/KL<aQAK+tZ<>u8ww<PHA/td\SX6jacJJeI+N&8Iwi#>#T?+>j1L8jqK^!C!*Xup6T+5ieT
REZ<qE :L#aq?cRDK&dPPcbK^1G+WkSH:M1QYy&$4RRIY:*@Ncl+8Y^k?@Jmm&L4SZJFSQCNwcXh+1hXNYyw\t*
FlBIXt =PYwuCFMyTjPNLlL<GYQZCJKZV1$4:h$/eYT$X4&wNmYG%HTt<k?%8WcT<$TZ=D6&wdP1\R=!$69n!V#
KYC^?> 6BM#e\u^J%V1t%=EXE>Ei@5Qt8!Kjh=^GdTcZKa/ILPTFWym+eYHiw&4<X\kF9p<bItilH>mdwHhF#*b
YVe>A1 Q=JAypFGjIID$!h<I&yua6YE*H*HtYn$injIjIiCZ^SyZkNG9lE?^winQqnZW<^X#6LJh^FF!WN=il!W
*MjRtA KQ%>:HjL4DWuh&<Ey<FWSH?w1Qhb@AmHDW*d\YH6NMnjlMy%\6@DFWC9nb8p=Dj?p1+QHK=+bR9qkLm9
k%ed$M /ie1wGH>8h5a8=ZeBLDPaj9tT+5:*K#VPclewqwE:pB%pPV*XXiQQ:YL$>+&jAaNjB8>ylje16\HT#a/
b:!>kt VplDAM\9DE?j%@u?w\\6IVPy99<>mlGL&lGcq6yjE8KVGJtCbyPRew+cH*Sh@Z=yp5L:T:4QMEbFtdm6
d\R%N* 5!ZCl+4ya^EH+%l/humnKEEcpcM>bZWdH!GTnWy*\^ETWGYh4HFZL%4<8/CBnc/4%#n^9E1nSdZS?y>>
E5PXX/ uFHj9l\:*6hI\%W$b@=<AHRXRt?NC?c^YMX:uBeilq/#?ltbjPMeAtC@/n8pe+^@TXKGtD/XJwZXl+e*
JE1&Yu T&@&lRwHF5j\+JZ@5B%pqqGS:?yh\<5QZE8jpP$9yS>>tTqk@>Dc1<Pa:GB5G61*N9\MBd&J%>T^:Py/
iIVKN: Xae65#91\Lii%Cn&VEa*W@uWHa*SXYd8t&:d@KB:qcAp*9R?e&V5ap>hjkC?MmZHpmD*F+bw14*!B*lL
<&=b<P phS#:Y#<Z:L%SP%h:Jcqe^<1CY*E>J%M9em=\T5YjE45y\/X*C>GReM@uGKtk$6@^G%/9>&?>ePuJuTI
m+4mYV WieEDZ$?M#^hAA$WRkCqd>1*HK/148\FN%XBM*I4y$$?e:iNYcj$:Z8Fnqi/ddbkZeW4*JWLXiB6^Ry$
CN#@pi kGW88k%*9C=JB&5eyWE@/lSaHHmuN919E+VMBWIA@<9q+dDN5#X\unuZjY/:Q<5t/eYcZeNhl%N8dwYk
Y1BwlC >VE:RHKMNG$5HcFlc&8&\B!iS*N!>!MEwJ4W/htFB\1\8VZ9<qhw=+i@QpydHGHd6ZlyYCX^8qC?w8uA
h$Mlqq @*mbejb^XytBimV4R5i!lV#8Z56E54&%/ZZ9!m#?A1NEJBAb*HVl!qSG4/kaW6L#K5%qpeIkc/9@66+Y
B+%KJ@ hEw=BT+#@qD81%YSMu*I*#8<N!iwjL=cZ#Y#C=#><FV?t@Zi/dWVSk=buMAH=&8SDj*4w?IX:T<IYaI1
\:acRa :YVR9<9tXlB*uK>Wb%LPtj9iD*@*LVyp<uVbjp=&bLE^qnX@X*w?Blu*6*G?a6%@eK&#MWKthb/*6m>5
@Ft^\V QVc=@q!kV9NkqXZ^hAP5\>%?lR%6NQW/d%AK&iqEBZV+nFC<4pmj8t&GNt/WI%lMB#Sn6@#:Rq6A?\cL
dqpDT\ +FciL4S^<dM8hIFFX<:R#$K<el5Kdi@TV^<El&P84GalkE*^wn8N$X&\Htlawku/abkF>^wh@*iwnpEt
#wDV8= 669?h\4>>1FInDlW%>66%&^?j$i\N*lBXmq5QyaF9GC<Pcw#WK?e*k>?/8dS!w%BRQA+c=ep!*BjTW6%
<Z@EB! *#j?Gy^TAqSWQK/!w#YdkAB/&j&j#<$>q?bLRC@KG>6#Q5t??CCw8Hhd%1:nea<l^y>PjQ%hXC5i>9<@
B4^K%h 16X@McwX!Z<*1qWMRtic!y?mYnZJ/TIPIB/H+k+nC46!^Vcmb<@nl4CWC?ACac!eeDHmhC$+B86JHRm:
8=<&$8 @RHJ8I*w=d#<RSV%YpTI@pKFZN\\#Ww:mMLyJ1PKia!eYQB\4^:KVqEX<AqH=5AL!uX*YypK>Kk>56WN
mR!/Xj k6Nu&J6MdFDadHc46^Rae&eCa/FZnDJLI?Da&!5C/$i?Mn=lWLIl=bBdimVHBy5hBl^&$mMtjLKiS<<*
u*#>cV bC@/RpF%JpJeL6#yVt\X+iFui<98<\a+kjEeY/NQ!:m*cwTV*AqA8hCJ6$nQb>GHyWqtb@AjKc=nD*QN
ZPlwM9 e@ET>t##\QW8VcJS?c%!SQL!9+\K\u>j*Xi/%6Dp<LHc$>yy!atJqJDKJJ?AS$lVq+twV1*?1#C@9>Ad
kYd&H+ lR%l8?5qZycA%!J1CejtEnE5b6hQX:@PC*FH=w&c!!Gkje#AXW*CL=AXX&@k>LJL%<>DCeL?\I?q%C\^
*9p?jM khcT=>E9N$:QjMy%#I$%%^+E?%Jb&Y#DR=>^t!@NQ/%5EK<ZGI!1+hM*Gyp$<$At1b=QRj6Ta&BK+Zn9
MFFw!u !dR1l#%#/#4V+eJ1jS:G1DGRm*BNRYQ1EFN8V=*AWbCQT@eb$aLd4eDuFiEw@nqELlJS8jQyn+K=RWRE
EtcWLS CDTdu!R6Q6eJSP5!dB%dWnt+iIAhGm*=D#+nCuM5B?LT1na:jR:>IJe8wSSXPb?Vpp1uElw=^!Q1*VbD
9/RiPZ ZI!Be49DV@+Fh4w&A^Sck9ZM<ucRdIHWJB!>XbmcD&F%MB@N?t5uFSA?Y&&wVe#In:d+@HynhynnFcyZ
cqhStM PtjR\M&IJ=9L&Pl+Bn=K8YbyntLjX&5BG9!=AF%nb^R:*JJ6FS8$9WIk@VtYtC5@ml1l5TtVH!::nBdK
19I#Ch +@i\L=tmink$FB<8Vqu\QMCK+yD5^mN5pZe+mtQMm5<XkauVSAR5EYYF#Kh*J1VyDhbeWV\lDyp?!jEd
!h\XyN iIXBtY&^PM$l:NYSnS<Rc&YH%VW9XIndk$jyypd<#5*q%H=$TH#&5m9dSwCtlDq=I%bCPJ6H\MK84CSA
aT:/<9 qt#q>VP>54nMhn=MYDl?JL9AmkNa?IDy#VJLWZV=b?Lmi/eKV=Mq^lF1$lEiX$R6VjlJ%Y@tc&hSV/?>
:Z:b*4 >YRbtKDhLn^iL^8I1lk$1=<h5FKRM:cLDJiuThlqnHn>ludjM=:muXM/$d/kyV*CA#mNcCt=@T8EW1?:
^e>*#M W9Ihi:X#ZN5l*IqPt1PH<8VTRDyuVJEGm/L=*E^qN@G6wm%?$wEpM9S#1WqqWcMn5m&5mDY5yVh#&Tl\
>w8MQ8 N6qK4mZE/Wqm/#lS1F+!=ld>cZLYeJ+YI1W<KeAteiWqecbC+YJkq/Y8at+#i?pF@@l:GRHCXjy1>Gyt
D*C+Q# G>1?El/4Zmb+QP%*H=y*$jVmG/p+kyZdhtZidR!=eA!%SBX6MX$IC/upHi9^BF<@ntaCCJhl&diWd$pT
QJ$uNW b4eW1XLLhJha%ujkaPin1SuNEe&KVW@KQ*\>e>%aQA@4kA%QdVJnk58+aBNB1JMtimBl#j8ilETLyqEN
:bG6qX N*/A<ad/euNC4qJ<kIVQ\8Zh$km9yiZwYGY@TETyP#5*qk5klAh&TS::9XKlB%#j:MkuQDtaEpYcXmFm
>4M9B! a/VD6>X&@lPNA*kC>j=9cY*WmaSi$!B=4LjP9=&^B&5>tL=<WlDb@nWb$NFk%@*y$SuRS4qJ\Tw!R5$B
&?95Mu L4R^dZ/8R>jH!a&$tQ$:Y4Gal<ZW:pm1lR%8!@D$B=bl6R!6\q5lq!d@J%>4/l!jjP#nb:HWiT=aei4\
iKQC8H n1+H@pdJFjuX^dyIba@Sy/?p=I*nHt&hV5L8^bjGGMEZ\t<TEt#R94Lb1%C<1>F/d*5RSXcN1!!*wR5k
XWbEIW IH+9Jm1WVhGTyG=wnEcA=lW@1VW5k5Iyp84kF\A#be8b^Q=5cNT?Rc45QJq$VW%be+?q9aN$><%4DL?1
jaPZe1 FJtF>w:hB$qayp&P*$XN1+6SM44Y5tX#uN4=Cc&YA*J6k*PYDQPm:iDMN:\VZ@qqQFKX6iuB!SlB^&M1
CNHy#\ :mHP:B#ljiI#>ya4TZPjy\6w!/%LkwbtB%jbWIEhadCENP\W@1Gu?cPJ5Q*R?Z8dq@qQ5\M/Bcl5LD*M
T:E=Bd +F>mhK+V!?JyK&*ABDDemVHidiFNu@u*8yP<#ANtju9pbtmTbP9DH5H::ZGGaTTQV9u#ka>H^%T1pXXw
6GmGC6 *Ejd&\ZNCn=<+XyQt/MP#<p*qEbcaR!u<%:$b6:^Ay>?ZE&E4awy/B%\tWS*HBj@=D/D^\b<MjL^LF#u
@Sa^VL /CEQl5Mb>8dB!F^w5ZN@9FHA>hEbV*Ebmb#j/5eSi#:cq$bd@B%SL!XhK+P!ZZ$JDFNm6>IaRCFHDSQA
MJV4XB X%SJSI%H4$pJ:N/Za>cLJ>muKKB/nV>QKW1VdShjqlMH8wWIjWeRq:>Pd^M9nDM$Q$\5c8XkT6D^NSA+
/hBCj* a!Lh1WM5XPw<a!/&dBSP/5&/Rll#FTPLp/9t!V=c+Ztc41:l>yG/ad!Ky@kJ6/Llqw#1kku<ajA^!dWb
:=!t%Q RuG55M>MKK8=F%l?jK+GL*@wt4RdR/9ZwH6^RdNjPTp^#Yj@^dk*\>:H1@TMkchJD:TK9FEaNJ<DGZ8t
9LKm#\ 6Y/8P>SPM+^bQy+#P1k9!W%tkktjauMA5%XHJ+F&cED:ZAlX1hGBY!MdFmREht?kW1ZnaLB\=P6G1p:M
W=$Gai #pqwap9XdMpAk:kVT:lC5l>4Bk?<R*mERlpYk+Py$S*d+:5iZ8$mBFmH:*CPt$6&Hw5w&@$:DyX:kMX6
/C!/XN YL/i@K5SnH&#/#b#kE*l1YIlT$VwJkJ</LiibP*kWpQpGiRkAdT6#V:JdMW!Aa@Rpbe>BTnqtic^9q/m
4BajLp QPZHmSGI&*FWT8G^R$dq?iFPFy1l96ZI!!%$6icmbYl!AtLtJ=nm^#i$R/jBd9ww5Lhmn:jHYICFtR$w
@@lRBE +@ud%G4Ht8nKlJeFhy#FW1y$mLah&+W!^PXHqjYDZJXTbneB/?jMVXnbS8>m=N+^yuH$$Nu6aRki/jAl
N^JeJX IV4SMDq>\jX@WKtt!Ij%tkpJ5R#jZP^dtayVqJbt6qDlc^+q!&#SwH\8W*@+aSQPk:/1p1/MWiJG89mZ
-AH&<q 000c684e56000110333 Page 325 of binaries1.zip
j=Qhyk mD%?NH6SSb=ey6tPplb*aS?=EWk\1#^M^P#t^jki9bb?4F!d4y^4bFH*TNRVH48QB*8IB+5!:WEEAYIc
H<%G>Z KCn6lYR%:?ketZT>>IHHnaMi\5AyEm*@AB#=ieHA8=B68@Hdd>JF!QdlG%Lb\GAM9mihJN8DXJG%m69=
4d?6qe ?dG*Xu6LCcKNV!luw%h^dd:R\cP8K?RB>GCF=M#&GNiDtd8Mu?!!JARX$bEL$<KV55HYb*h6w=pl@&Jh
E=K*DM \phphH@A1#>bZ@#9GJhATj*=BQA@c%#C#5H?L^1ZeHQ?9ZEJN<e@b%#C#ja*^mX@Q64<6+itPj:?=Q1j
6lMaGJ C9:Zy<j@PNaSP\ju#/B=kQik8Z+C#e*Le\?c?&jR>>Lt?Sp$%*%w+M?kPi+^L8Hk@djRjD?B=kLia!dB
Z?5lqp !ja#cP::$P\@k?c<D@$#9MdFjk?9ej+M4*H!*Wj:b*mN<>=Y?^qi+:!*%Z/G%#n9ddYj+VXP>99RQ<N4
I$KX$T HH#*GDJ^<9$:cK/j+VWP:u95Y4l?l6j8N<ul?lqtA>=u&MLF?Y?lj+dbiIBe>/B@T4Dhm@+bb8Nm8$iw
FG?pX8 ekH@4Z4#@q9wu&E&d8=:/5*N>uitTK#!:J\5jC\eHNCi!TJqdt#G!cL/\6mJ^eLc#6!X^hGF^eQc^e*h
/<m/Xe &I:F*6#i$eZ4b$&VPKC5^e:DR<+FqeR@wkD?lGpTN@9jtCd>Y4F@bJ4$Y$T/Z$!VkD^@aJ4E#jH*C=Be
bIP>8l jED&@!5<\ZlS:mwqIXPP?C6Jj>DCI$lCS8#&pk5Ry$/R&HIbX>9bRQauF5P&/4EX+!YY*PVka<wRay:y
RY#/Tp RqtHe@eF1lKkBXh4<VKpD!=G8qQCFE@Fe5WP$+\HSHb#e%WKFdGFW+NL64DR?l<^5<$:<^Nn&KqneKM<
a%k@5h H>yY*/h/WKQTm5CICy6SW%:&hJKW8T#XAlih!8WLQNwcIL8VYWp48#:aTW8IE*&@YSeiH19DCBjFNlGL
9>S^Lq 9XNaFI&Ibj\bad8wCN5WWlCetS!8GIYXJZc+cj+#AnS&1a@9PM4j<<TY?wiLnQN$X69Ej^la*AW\$qP&
kTL#yG XJZJiA<kMHYXLlH&PKic+k8QiCwnB#F1KV<abSQK\SwXcb$epLA>X8JX5DQ4JMXIpMMHnqHA+WGbieti
:FiGHN 1<h%V@1=tNQTHTKLe@pW9qIN<YjKQ@q\5d5Y1GEI:Zd!D#=MVEh:S+>YYE4HhQc6WuB55wN\!mT@5R+q
E1P^iC MXYJm<&&iAlLRW=IliVnj64<P#:q*mky4WR%LI/w<pepR4\\a1VNIp4=u\WY/8EVeZWm@D+bh@JWIIm^
EZ9q?p ^#*1N&FSp=q5%t>m48cW<KCbe?9p8SSmY%kV^Y%k\%>jM#AkKNjql5eYteFi+1qh^6WinmS6aGpP9&=G
tdR\P@ tJK!JhXpXNMPaPGBR+yc:R:!=WT4SZ$W1u?m>q^EnK5DN:6CRjcBVtl<D=LYWC!i8t=u^FeC4Kw%5hhB
Rj#XN# @Vk*=P<RGy@kE5=H58qGXZ+*tVKBl*8QBC@F1ZV/dl>GIeJG&bSHN=e=wT?haQ/ND:dXjB4@N/B%<yMu
ma?jcI SC!+18R<tA\Xk!%B?PE#Juc^Yq>DQ4dRjWdiL$ee6aumEym46=yNJt%ukTMZ+n4TbAtyaW+DIZh&t4=+
4$jQtJ %8F\M*KYI/wQWP/9JHH9uHRCpk6@uM9w?&S8qTi^lj%NVqQ*Da1@Yw&PWQ#YZe4<c$ZM#nHba8Fc<ZVP
bIVhA/ B/TaAwX/8D*aa6ljucStIt!m/>Zyp/@<JVl*Wi=GE\yb5N^J=q+!pYw>HVeM6L*VVTA%cH#pK8t6<K/@
PZQm>E XyK/Ee=%kiX4c&eKMu!W:mw=tulBXMQ=\ScJ!4w<m^y?mpctHycNqXWqDWKdthN49d\:$>WC:QbCE@NR
LHTP%a $X:QZTqINp=Gem#DP?<h#$bEuKXc@YE\RqRa@nN*#>#lBGQY*l1P:QwAZj\I^nBGByyK^BG$habl^S1a
uJWQ8i G<K?/p?^ImdMEXHe+q!8!FQThmEHDy#JZWi+KiV&/IipSCI#A?*4N$9m=iZA+QuI9A$8I=WHyS^ML?^1
Qj8iqR y$qGw&kY/HPDNYL!9GJ6h>MwPn&jBKB^+5YeWC^KlnDwWm/TlB&@HScdTV^=#MtyajtSPCuY!teB+Bd/
YDJQ>i qRt*4&<WGY@c#Pipq1^LFZEm:e1hWkbA>FRX5WMZB#ZbkwPH>TIR<n4XFwFtJ4Jj#TpnVeSEQG\6KwX8
n#HD@9 Zu?=hhtJjbSuyG8ldY5!H9S^&T^*yySRYY\68hKLFQG!Mp<WJVwF<>46I?Y=IeHViyjmY8ci:b=JWb?D
pTZ8dQ %NK9@MFaP<+Ql<$!/^4C?4T@wE=!eTRJhT^!D6kbLE6d^QYJKE>wSV#SHDGRjLnJN&b%RTe51wNR@W%1
FCWpi= 55mByN5uTDEBl+iy^bdKiyWPa$Il4Y>Yt+D\kmhYPh^h!n!$V#68XVX\q#*LBFF^IcCR!tl/K!%lY<%e
44F:Gt 8b<PmZw4TVWh*V?6IcpaGX!Q:KcHu?PumBpt<uF>6X=X=Xci5ZNKRd$9aHHHVB9>kCNEFpqtjDH8deM$
&yG?%! FyKY:%6T@biKea<<KYnenGJ4YS\HT+m!1<jM*w=pI>Rq5kh*VBJ8J#DCa##\=KEmJ+upXqbXq+8k9!+9
HPEV^k numwSEQ?5cI$IE5L#>\m&Fw@5>6dBAWnHwp?P=9/9dV<p*E>m*V5aQElc*/TlTqGTtG<5kC@+@p+ap?D
RJ:WP* TYcMcTEXhMIqWXbu=h!?F4ZtBYGZCEA&?@mXPjtnB6p+6#%PyydZtNm>%:H^LQS^nIi=P$:p<SdCnyRq
hcI>=w lhF\H:!XdSniNnK<^BQ>INi1Xt4Vt&#tF8@E1&y?YW%\69*SRQYS1TeZF6JVI=Ln#^L9/TjF%?4*q1bj
h%l\yC beuNmcR#NXhG5Lj5hWR9!E/YIL!&9tu5?C+l&16nVLeh:q<T>wwWpjjGNyq=w+&<<G4i/nBNk#wy6DFb
6\D\KW jHyIA8XJQJ+pDMbldV/&hFYlX4ndDwF!kAWiR!e94bkZ:Y5VaBlMnmT@Xub&*TlKe1iRH1NRD&/R$LRF
%uPFY$ &pTG+BPjldm/naIw+Vd&L*JjmTi^dEeY$*t<qebjK^pywy?$QnW9*mZ=?6VyI!NucceWXVyACCi5&cde
n?&Bb: @K+<qmQkwVBAF:WAuwMEdlM%^uqc!N%9:$5Z1CV5$w+CS8:\$SaH?6jeVDYd+EZCXd6TcT^iK4\ChV&W
CR5\wj <4Kp6G4B4XSc?PPTF$?1u*bNblICe1$K^:CjWlebVbKejWPjCR+W$m*SX8/%GahB6DNCpSHu?5JEQM>^
aJ8k?+ X:eNF/TbWTN8>A*iaD<4KLeSR=e*A4N8/$1m$V\l/wlE\>ei@<$VC=t1BY<1e+$QBuqBl/&m1CFl?A/m
cZk&+A qMC8$Lt9*8/!/lH98?c:DYy>#M9>DRPT#T#ec#I+B#qq+W##qh$%$tm9*ib5Ve*5$bG=EDhV!1$#IP48
uX!6$w Zn$MPtM/i+?elBwt9nMJ4^nCw96ZN#:yA#/nJmdt<Fd<bn!L$DGh>Z%1w6=Qa^yG$m*\Vbt#@dhh+1XH
jk^Yn4 wbq\#MMLR+W:nLwtMVR/C@/c?Yh6D+hpEbZGI?eZZ*Ak$5P4w?>Fl%+4Ln:8cE>$ei+w*8Sc4jjZJXe!
G6>lMt /%P/G$bS=+\4dw=lVbdQE#9j=#TQuB#9jnW&/QtNaiPCjJJ%w:FLmpZShKDI6b85Z\?t:d9ljGqGFn/^
yniQ@w +^X*:kCDLbu9YTN/?!9J!en>1cbKe5Vt$JYda/NuCG4j+ZwEN:=bd1IkW!HcQRp*F6uVmXHSm=bVkejK
AJE</h RPS^E6t#&pPYy\q<8WNu*Fi6bGhqG>RQF%\w6<iCJ6:KW6a&E^%y%dF1%6ENG#Sp/1ku%YjV\!RBGbH:
i<X%Ed 68&&GlH8liu6JTL#Vn^$9dlQL^l6t&peHyDy$yE<HDGj?GDIPF9I4M?AA<M*&<HKJPna5JD!*D#WhkPA
PX56eK X6ISWlt88R&jE<HRQ:y6NN=lmMmSLZi\*BHJ#*VPA#hCJ%NcSmZ!ZNRdeclNIC>YEDY\8ZT!PhSPMCK/
$B:ZFL +w6FwbqVyc$PB#^@=T=?q<\X/uF&NTPG^El4k@TyRXBjnm%l#Wl%ICN%da<AAl^<nlp4*lQKIt\SaSN1
!n+\8I CH#p<6jcp/@Nc4b8CMPi#/p#umJwLG&p!XT=NXh=Y1HGZ%JL9C8j9qd5cSHVK+pwj%>YQa#c?L/5LY&E
#1<lRC y$l&TC@k<ANA/aNWdZnXpF/MSQV\hq9Xik^neaeNW=lE*:IhRHqmEjqpPiPw5JMJ*<PW9AC^>5bCm\QF
<yRw4/ ahuP:E/m9PVEKyliShDK!W9S>=&aBHK\SI!NXL<KjCF&bn9hiWqMHa^ChGLQK@L@l:&*DM6n!>bFQ>#h
:d&a<k CRS*@*B*h*iZ+A+BkkX*6?D8Fl!C8:5FCW=\l\BBL8t%8uh*4=Y>5:9Q99ie<>\jQE@XS:&#b5%/^=^n
n!V>Y< #DF1nDnG<LJ:<:LCGLQyS$eiCQm\A5A?KXqe<*wVBDR8=C+duK>T6DldT<H4RCDRCy^i*pG6ql/#:<A^
cDH4?S %t4FmmqjeS>XB*DTW:EuMZH%HCFBNcRQFeaPMHMBDCTCRGW:^8CkXL@YmCEY5!e*F4j$L?aEw/mmui+D
pqGWYK /*WAS!a%u^TuP?TLnFEEp&=qhAV*bhR#bVSl1LakIkYl6uipSRclkhBHAT>h*+cD69PHLwucCE\bJ+>B
HeGudK 5Q<AM=qhQKXujXdBEDe6d&9t8L?>B$tAByWDL?IAH$5D9:?wXbqTQC=nEn5G\4lBl@!XeiK?6/aTNkaC
w5mquH 8=Tj1MAB4F!nd&!*H&tSL8INGZ#N@bG>wmN6nhZ=c>DF?%G@pqL4\iLC\V&&IjL1i:6S<@LM%5&qXBuZ
IeW%m+ aZM&R>yKW+eG^=H6:JAm19Li+c1WYP9^8&&YDdFNc=p9+iZn+^caV\i=E\k%E?F8E/jip+TPp:d#p\N^
?K1F1j W*TaW^Y9RiT!b?u#PT8L\THQ&G%HT#hLYcNcb8udb@&6L:4>D8uHD+$%=yEaKYZN=<i@kCN8e6L9uqTi
e*<1FW LJ1Cu<4GpBKcRG:&u6FqCK6+kmMlu<6np>NXaS:caBH*Lw>%&wHq4@nb4$\\a>6MN$W84w/6m>l5c#J?
n=IE$K ^S!:IEK++h$WS1EHabKDaky<\#TR5MFM4ueY6*EmSI>IQ8bE\YLLPE+=9GZ/JC9HC%>L9Tt$8%&>#Db8
DThRPw G^mn6XN84lEpa$lBJ+>wJSE>9!9u*EL9yw>e5<jacqwb=lkX!<5+\<aMI%SBlq\HVKpeQK9nPpaZtDqy
alYqmX uZYSc$N<anq:a4@Y+JCduSe1EV%bYcB:K=djiVLtL++R^t\V>bp1nAR$ZAIJp8I/Z5$=dKpK6/GmkXKi
\Dem?l RHKCVql+e\ZFZ/4R?VJ5Qm?c#%%i!NlPVL&Q&E>i=l1K*6SP\$5b86AP5qiw>!aBR^c$VqY%t<+1/yQj
qKSFF# kj9ZB@l<9P:#VW8MJeZe:@CM&hI:1b<Keqk\eYCynSTQdAWl$DWC*R*<F4@K?B48/wPS#!MY1k\K#ayA
RqqJGB hTj=#dwYaGwFLaWZ6k8cB^qCJMuG#e48bubFhGaMQKVD=bqhkLac4j8N1P#pc:+JJN\#@Y^EHYpcF1C8
V#FdEQ 4FFCNYt+$/<N$Y\M5:6jcGLtu<@W/jkGL8m!FqqK#Hj$/BWyNN6VBAWX6a+I\qeiXNdZ6hXln6ukeKp?
IWBBHw w=Vt<iaY1HGIl<?p46qj4NiLCjiyuLIXtC+K+dYKGZc@!:D#quH!nXduDH?\49Hw5X9nI6\iG\DDNI%D
5ju1:K 6HX5ldY^/i>PlHVt4?>?6w4!#ej&QZ@6le4&Z5p=WQE&yPnKY=uYW\IVAuDlV/=SR614%W95FNKm@<LK
^wRYnS ZVau$X\49@P*AkJ9F=INIM6%BuShRkk<wJ+lGqY<!F8MdeZ5wC\%h:ZhypFFk\LCtVbL&FW!kl?<ln+^
-A%ucl 00067f9873e00110333 Page 326 of binaries1.zip
^<*Ncy mPKDF^EHD6T:DqCbT/&4C^^+paEn5A?Qae\\l4E!qWWFAldjmdj/B%G4T$m/8m\bt:THFNaJam$KymAm
N+N55P aIZT1V5GD1K11+S/t\T:VLi:LCJ=9:%uawZ!8AYc=1FZmtt>@?dp15wV*nn65tCmHuL5Id<M%4lyY9Wi
l$kSSZ WX\Hi5E\kD#Mp@*$nbN%+CIkpZ1KR\RdaeARyRDV5qca*!#GJ^<Vkc\N:t%4mItAT:C4QjK8JBM5H<Ac
J^4&pw $qSRH+^AX9/JS<\*c>$M%1#PW/AdEe*EYlKhVuY$c!hGpK4e\+VHR</F#i<\?y5HZbJISyXabDCEJ:lG
*+$B== Fhay!qCZPZuDFQENbPm!^X8B*MJ1SEB*:cFYTC:LXFI66t#EtY$=ydIZnh554*S$eAE8HKt8SjBbJnWC
1KH/a4 T9?J+phJk@HWwZpua*JlQbb*:ItHXtb&?1CNpR1?=ynt5y$C$I9!CwBl?M4\?ImQMKKdJl4u\HyeW%k<
/yi<5b $<cL#ulPYLMJSe*/bLN\F959Y\bn1VmnpbLD<wmt1RNFu8T98#Vp6IiaaC?&kGd\i!Z=H!Bc$p5nyM<p
k&T6Q& @EXDDTCVYZelHTCGqJ9mBLI*FCB^@e!?KVpJmhl9Ga6IcMJ<Tmj4WJEw%T@a@HSEdu$&wRm#BT6P1BPE
HZGe4? 1=@QbqkQR9EtY#?jI:*=Gw=bHIEewcD=AB=++StGlMCbq9GlMBM?TLGpPq6P:^c1AASSTW<Sq^:VtAG#
BjD5$+ ?p5V1J1VL\%VqEB&h#j#deb\ByeMmkNEWlm%JE?wnF>@5PNwNeI*JmiBJYKBH4IFDEh%RqML5TIyF\IQ
&5\=ac !C<Ya5Y8c=^^ZPujwF&K!!yC:y#kh*K!9?JJwiA:W6/uBD5!D%Yq95+#MNTZk>PQ<cQ6:FXj:!8i%EkX
K4J1<k \aVIQw^K<6Ti\/b*M6jDVPmah:Ri?J1elJD<ieqq&<^jY68WYh>!TNT!/GPTYE%+aXSw&99Gn*heka@S
H\:%$w pn/YJu4AX:+Y@pTIJCA1^m!#aEc#q6Qj#n$1GKlJGWklK<i=YhVXYcYaq^8^@NmEmYNI#HI$C!SYEJ8%
B#Z%We 6K6uXZ4Q$tb=CT$ywy<IdVycXY$?ZjG4I^l@Ak$lQd8$$wFw+@:W+aS5TN$JLSBHdl\pKYRGA\wJBYwG
<%Ri1b LbANdTDaI*5EdXBI=B5Cu*%W6#+M@R&ISI\MR^nmaimI*mYD@tDcu@/t9>WTn9AL41EuXyjQRK9Q\M4:
j5n>8B RWDHkGeRXqjAK!IqbIMV?B#6\jVIRS%QHMEX@I$XhCL=aV#*aWF9dKLt+bYQI#4SA^6Fw*m%A!9lI==?
+MNahY &ESS&B6h\\@nYA<#A#tF4\##5d8meEG/<WF+^*q&Md9!<d6Y<N/ua/^j\S6EV/^EwHaFVky?iW%Enyun
JDM$wa Bm6\PC4+G85SD:<4G*ZDF\$Rk?R=NdnKMEP$kk=CmL&BCcW4QJAlQ6\Gn61qkm\IkG>V\?y/ndaTlhCF
N\cM!e NyK?m&qI5QDwm>w/MP:bQPwbktI+ntjan/id?Dpn?ZNdK9J1?JKu@<AYW:ehqydRu?dG?<&@>:@PjeqP
6GHXRM !ML+#==MBlWkISMnC?i@+4hpbjpZ@bd5HH@$Y:K#@+Lj<neQJV9du*wwYj>pP@\9Zj\qD!W4&/?kj=dR
aCXqi\ nJZ>F>A@VTLH!9E4cCdkV>Ce9+Bt?Xp/NDdGj\9N>C6w=y@+jhmA9+Jt?wpLkw*=F>DMuD@^#LK^@A1c
\JQG!* @Th5aj5X4nG#@A#>K%^n@yq@p?%Z8Abp@>q#@\4ZkK\@8@i9eA*I<lQHDj89eA$I@Itjn@%Z8Md$M:<8
kJy4!u P@DjR9<K%*:8a&V@FdL>%N@F#9y9whu?&cZ$P@a@hTu>NeHhZ%^Kj$%>>+@659@SyeV/I#@m@^@V@n<Z
4h^ukT $+:*9#!tHW+J@Q=VChwFh4+<1lJ8jqi%jYTuNY=TaiC\S&=@F!&kBKK4QKBlGETt8uRMmpkamNqw@d$\
^!lb8h 45+@V&E%ElY6hLwi@qA88!eHLFkA$mbEcbFnI=J^q5W9A^ehEX&lt!pmB$\BF\K$cWblP11CE\Mmy\>&
+uQR*b X?E>wJ?NFd%+lF^qFpKBYR$nbpSy8LIHR+DPn=TWM\4^^b^TiR>lIVXWKZFy$bkEJ\EWe#Hjbc$F%t+P
?ENTuj TX5=M1bZq*WLhEIT6XTtBe*PL5ZKM6LNkA5P6Z:qEP^KkPABh5M=1VDVLR4\LDCNlu&b1N<#XYEHTXAc
#ai#kj W$Ww6pZu\lCFu>1eMtbZ+RJJNCYjSN/&e%&&utiIYkCJwpdj9F%qD>?a8%ZYFHP*X$#c8Y$lbS?14$Si
69hHXJ 4^@:kmMNWT>19eBmdCMe9ujF@Dc1V!NGASMe4ABN!DkH*Bb#<*bR<aM^mF\C$^:CGE$NQPiaal\p+!=*
?!PK&: @G:TpZn&hM6+w%Vp$Vlumtk!^4GAdE/I+^B5pk4&RFC<GAAh@9Mu*9hjQR8=Rm%d5kB5^/&F=@^cPp?%
jZ*JG9 ^FPehL1y61tmmw$RaHZ1WaFncJJII5:9*m+^j!L<\9+%A=J+>WkZ8Y@I1wWQdmaRZ<:1+&ALnRVuX66*
H4RkdJ N@TJEu&RL*68nKj#Fp@maqNZu/Ldbw?$#WcuZhICPMqtX=CLMSm6A#C<kXlFBIQVmDVS1Y:P\Vjd<JN5
nwL99L lqL%GMAGqaEW>$!F+Vyp!ITuC1*9cn=jeeH1KXkYZ$9tGp#TCdGw\b8u9Z8GQ?SE/VLXlZ!6R?/eQR#C
bKQ:Di j!bRl6&!cFB+AqYmMQ%5kNKuZW&P^8m4>eWRDJcDaSNEKD+ZqpmHny%/cChIR8JER$ciJjy^RcTa5S\N
+AqQQJ JD<aPTQ<\/Ww\J@:YKPV/q8HMLHSbQ!<itj&C6M6bAla#RhX&K/PhG#m<w^\Q/wkG&>@pi*NCI>:8SA!
/Q?56& u^#CNJR9eJaR!HhcdR9AKFtaL5/Ni1RiaWeLML^w+/4E!tA^dnLe&qYE4:^IbYRGyc?H<l%yN+byAkF9
w5EmH: hFyE*e&Q!@nRPR:^D*WVGVn#Yl6&da$PE!!qMN4chmhn>bXH:a=$J+LFjKl*TeP5!nBwBtw1i>P=l4\J
Id\phw 8#\It$EDqEh^=I8a\96u@P^pX^IWEC*Bc$REbn>eRduT:nYI8KuVIu<H>#%IHP^MiAMweNbWy4w*\BWV
d$E9C? itQW+/k!TXbXWm^uP>i4^8:WHh!XtBqPKMZ6QE\tR#yn$QYX1DZHYqC+YRN</p$E6pdMBhlWH&dpX#\w
wYJ9:X hqlWb>DRYZ6#@Nj8Mad<6bIZ5GDIL8?h:=ME\*R?Enm>9IYhZkuY?+#J8D^S\<p9baVhI>wn?tymVe8=
nCpF9J LYY!piYk=yRP\umyhb<Xbw#lGhqEeiLn%VCeRS%y?$SBAd8>Mu8GmBE&!b$WFaAQQKIl6IHl4S#G/n%=
+tudB1 WP#p4yY<uDJt^a>9LA6h$p9WhiBWXpBh/dR<T8B\wZGZHTFaREYyZ$G<K5>\!B$i4qwIX$ZJq5&y9%RI
5b8y#m EFQH>H@9b%+!!M9Jehc@L=lG!Awj!TjY^!!?4qQjXB&41bPERIL\ihT!@\cW14@X9CR5MdI\/wBTeub6
8y9GyS :^PyjCMHPpVjA*#<a*4wAtJG9hWHekc9Vbc+Jy!eul^AFhpAG?H:J*@YRKN%EcePbd!^6E<MeJV8+^$K
>tqyBp wu#=\uEJMp6iHaLVpRdl?d&#AEwE=\SpSp49Ayq^Ru@F%6Z^N?Vq&6T?#W%Sn!k$FnnWm6GRECXi!@aG
=w\TED lWWkTcI!i$6#u@WB/?kJd%T?cJA8A$4&TDXDyp#Qm8cFShbl<wMH*?e8DTSqdT4tyje:j<pb@MmNEAlm
t/:je6 hESWwJnuF:HabK>TVR>CtcJ%<ZX@QL<M<bMyl4CiSS1G8:5KPn5pd9%FmM8ADVXlnRiKyJN\Sc1tpd>=
%/W:l$ y?CH>KpMhZl>!ZZeKdKEACPyt&WeAl:LDIhM#8!wqK%PEke4:D\JW>#EnPC$TpemZ5BeyJV&pQ8KNYLc
JBD/SI +j8dWAuI+:ikpiQ%#K/cubbn?wpIRum#y:L=M<cKGGZwiMISGIne8A!F$YFchIHNVbWbLb@W*X>B?1+$
<yTRbN wTX59+iX5tIe/ukF^yYGW*ebDS8JTh^YL!TYwNZyPF5?Zn=eAJ+B$^#TA8byVpG=pP&e&KQS*AX/X1!#
yYFw@$ RIYyc%ZkXNt6wBT/#kybW6ibpujlS!J$A^8/ihFB1IRBy4nEHj#Pqb^a4FW/%ItmKH@Yd>%TIS\cql#K
G:=D5i FVJi8N6HE9eXSJ@dbj\tP<%hI\hq+K6wLIF<qKERRlnSeqd!jwK<RS\btG^j85DyFB!a5BMGuhd&FHDw
/D#KG< D?^IJu6tADbp*$KNeKIXP5DKQd$68dhdCSnDk$H5ij/TiNQB#hcPqJAnGm*G&Zp%4Da+PlpiM11dkl#$
D+ubaP ?wFTE*c@Fld=MlGi>aYLq\DCid=9I=4LQbnNbwAj&t^8eTdNGE%F%G\Fc=F!!:AY#*%Bq+lld9!18pC<
@hk^Q: XN:Mjlu$q</DWqXiTyWhyR^L?1\<CBBE4\dL&%A$ktq&I9=>Xw#^<4\9pATlN%V##j=u=Gq%Fk#!i5cW
bYth/d !>DM+>4h:%qZtEP8NNdidltad?K>i=\#*!mj?/=pC?F<M\LK+99FpbVYF>JeMl1:@ACVDda!Xk4$\S/9
!I/5mj 4p@kbum>yul^n911/I#^a&q@6u?eDWZ98^&FB1q8F6?n6/Hwbi6LdNYIY6JKe@5cCwH6uem+%qatXhLw
^@L4=n Itay1uA6%eJmmGjwuqLDC1Zi6Wh/*Lc=*D&hP>$T>ADLZiFJmlQL>n^pT1PX4$atZ!jVliZIh+&<>=HL
MR54GG iZQDKE@B><i#9$aXE51XW9WAEE>1\BEdDm9dn?muIZ%NTD5NnmdalMaHpJC9n1NYVpBS8cM8VlHJ:d8h
FBHwnJ bd4FpZ4BX!FP1GWFu9JS4@c:8@NNjHe$BmJm\AFLLd=t9kK:#TS^ScjZAMy=6TGhIBL4YSPBKQG+cMy?
8FJYI? i%>4!G^:wIT*aKen^XjWNG9#St9:dSNT/m$YWuJ/tB&?MbtI/j=<NbqWSYNb:H!85bCAM89e/Rw<iMJ%
D*i$P: SAV1KhwGa=SWS\iNlTwdVMuT^^NnqFmQEt9dS5tGtJJ8TNq!WlI8cHQE6$WcpRZWQeb?>@%%%<Ml1pkb
1%Nn>^ pKaK:\ydPC^IN<T+4K1m=I6cXC\K*%ME#eH%9^WZkjNXEK&?aVhwk1Ak4Rl!hyd!Ihl65wjAh5*uW<4u
5V8pp= mZ#nAmHtdDjM>?+NV/!+p4k$t=i%H9Y=Fid=JL*m:JPN$M\?/DM+1XRa&$%jTPSWdl>T\MlyGJ6y/kSD
c==yDl TtT9kZ\F/4$M^>$\*pAShZwSJYiEu@KP%FSeAXXjMI=J<m6V%$pd5Xwbje^aG!#RKw1?jWwEupbHQ+h%
qi&y^5 5/cQ8@#4C8e&E5Np/jLF^J^$=1Fkuw5>jD=kBtwS4c!R>HFl=W$X?e\#iBMF%y>*l*MG1**:mJkmW%RB
kKh@e8 m\m?F@hliM/PWXpwR?nFK=<NFlGwSu$F=1XR6Pb<#?#ScFml?wDdTW*=61y\>KbwpBMXTa8D@w!Z:5AC
uPFa#a NFby8a^cG*cE8I9iKk1qLZ#IVRH=Zj%^IdqCpXuSJqHndBFV?<<9h/i+w@pKREIb%dnaDa\:TLPV/P@Z
#QKN1y tXYKWAmLeuhM8mWn#RFt\n4tywwumeFw?CyXP\@1<+eyjJ=IRwRNG1L&nB\D?AMPYXH/#cIu5!&Je$9N
aQ%X$9 dM!SlPKSqRGCHKRe?T#A\14l:!4EqkkEZGVyN1ePkqZ#1h*M*I4#@a4i*4F?D8eq6GAT$!m>KlDTIDLS
:AiQ&n GE#Fa>PFGXZYI*ZwIt?CLB$Z6YS!HTu=I96TN&T^y?KcDIyVRqmIjXWw^Q9T6cJ6<GmVeeiAIeD1N@Ic
b@JjYi XRPWk:+Ktbd<hJeqFME\>KH%?LF?nZau5$I8&Nu&:HcEpjd<pBeThSJl5NM/N^SpEFZYHeEkWNtKdD8E
-A>G\* 00077a5d96100110333 Page 327 of binaries1.zip
e+%h@$ p8V\H5m$%&M!ybaHE9Y\>YhRaMmYI9aGw5=C:NSG$\41m9b!h9I+aHci=qdamqIhwmaCZPl>$GEH\4**
?wP!Jh m68e/kwS:&u+p1I6FYLbP5+RITaY=B^*^N+k!B&b<qF%aE9&<BXRF^?+5E^J9YilX$+Abn8#FVtC/cD#
ah1<a* KX1/mA^L8Xpa*Cbpt$ISe:KWmmBNcX5DDR4N9#qwbX@**w<Y6qDDTX>ymN1bQ=Jd+FLnp=p?=EG!?F/l
<+!p^% B1+Q*$b4GJ&Gm8#9YwkWe#C+qWD*#+R:mF*8WId&$QblWK8+!</8$5RtVjcW=lRt\K<jVLGyeH%55WhJ
eBl>HZ k9>aT#6BGT%uk$+j#X9nk#Wt$61h1Xn<AIF/E:\qwXqZV=hZbpGmKb/RYZRF!<EYL^/dLAN5ajE>qAaQ
yKKwyZ =*$DTd%=^*6%4wZy4h@4q*m<AkE\88p$XC\RG8w%q=?nqT><ME5wWKPibyQ!VntaS1nH>1lSB1MF91EE
kbVV+< d@>K9abWukFDB!D>dyZEAkVjV88:cM\uM<eebmX?6EHJF+bZCD\pauaR!T>?:dj6ET85MWeiyqV<ESyC
w?aQuT wZDdqHYQ\\$qZ%Vpjt/?b6^E*T4B=LL+!b65cb9YyBTt^#H\FV1lA1T<QiTEk%M<PcVcnqKjmh%ktCP%
/4jGhl WSjt&aN@Nl8c4YY@I^5KZ!hk/Z+lQVJ$e9IG/b%b9:qNch<J*maTm:*DD8?C/:bpc#1mXQ?J*A+lBw!e
Z:X^\I P+^j@5=ay==6&K:jLt>%#RG^GZqq9\!wLHh%%^5*TE4:+j*eqQ&VQARDRaV<baT#LWVdX168w%MHdN*e
cT#H5J Di:KeSyd/$&EIX@EJSC=L!BCA<l=t!hS^D#$J@SSF$aCN4/kLBS1:Yip<E^I$Qy5HMDPhJn%a8l<6a8A
HlZ:nk SC?BmE9TJ6IB*Cbm**==RduLb8MiYuCWI<5iZSeZdBG#$9#EIG8K!8!1<ndLQSP^adPWd6XieV6Sp!lc
Ec&b\= pMnCIP9hFDY^>E/\:A>S+I=&N!JGyFb9Ii&lhJE+XnlbWy%E^DnA4cK#BRpThNdAue$y\+\h!miDIdA+
n*<Pyy eltlwNPR6mQG>@wd9Yeq>yuH#n1VED99bK4G>ESHqi!Hb%plZ*F<:c:mNGp4Ypl1%4eXAaaLK!ndbiae
GM81&Q >CwjjW58a<BAPE?w<&BSI*RXdYq%>+mjaVFJGkiH?$Sa!^JIp?>q+1$Amh6MF!Bj%y/4#5j<h41HDD6+
P4:qw< q==qT<YRInu%ZGel<5^8J4?l*PnK1TGGuVTh\i$:aL^kFtkI:S5=6?h4QX$\Wj&In95hw$P$9njd$6D<
5wPQ\Z nM$jq51\N4hIC#c$T1Y\>9aB!b/F@ELhyj%dky4#SQYa8Jky4BA+aCRQGmp9QnjdR<uw>JP!lKIwYT$Z
mK!#a8 \+KQuGaINnL=qp5aGMn:ZKn*J$=\e8?KN6q5/htmF<Hk/V:BS*&A9/XAIId\Y&R<PF6ubh\?VPE/A95W
ND4AH* AC4CL5SW5mlF^blL?Ad?&EA\$E$:eG5nKHAKBYI1GN9bSEk\iIw+awyT@!M6eGTGXWpaX^8$>&B9H1LF
q^ALP/ /NI9b#il#STp?61K6LM@IPY&D/jaLqdTENdZpMpR>mntp/qmiAW/X/^ByJl#%NYZ8H6Z:6Sa**Z$J8IN
/<#=#K &E+#KPI1hEIB$WZk+\ud9kcJn*E:6dcBaLeIyIH6q5hMI&IImZak:IqV+Hi64<9?Dh4tEM5&nWk<i648
LaRpZ* ydb9t<Fd/cP#t6@=ycZb6Sm^\b6AR\9E$Y/G$ZTQ\!D/$c+H\AKCiIZG@?wRPtaDDEN9bj:tEAIHAAnY
V#a\4K u#5jWLy+MLw<edyceREkQy$=:XkQXN&6hN$QVD$<4D&A=&+<5l=Q\X+i$b=YawIHmq+h^V+i16=$@n+h
bm4ipm *X+<#h+X@Z=Q=u+i?j=$i/\Ht\Eiy\FQ>@=$4+EH@WGi\D/h$MFY^eEHTkDil/F5ACJiX9hD#nBi^qA4
*5&NS? ?=Bm+\lQdT>i@Wk4WZ<4d:>P\iDH^yEHllG<whFY#qEi8?:5ni:$V&MQ4PM<G&M/E&QyVPM/QmM<a>&6
5@/FIt p%kQY^M/q!M/l<N+C:&6!?N+AkRQ!lMbTH&6hJM/PnC/XJP6*@5<#$e>SahdCXFZichZCWb%TYaMnYjd
$\a>e9 yGDTW\kiXRki<eejWZy+!ZwAILP4MnAbm6P<CHP4SDM/4QNi=ym<N9MQ1>MQLnP<lyM<6/@cEn>:?R<>
tDThkm NM:!w9Zyim$<y9ZnS@adAF:qGC@4!m?%5k:y/C:#N5/*&T!tQ!+>YC##J1=+6T*lBc:1%m@4nm\@Vk*k
hPCJ5b d/^/Bc/8lM>pnM*k/\@lSZ=yB^q?kqn*:Fy:R8nq:h4khbuX\@tTmdL^lLVkVddSq4jb>4mb!dVFI@Q1
uIuyt$ mZj4TZCdV*VdY*Jd^*nPY*GHV*ZHY*PuVZY6uZ&ZS+hdi!b\C9wuZ?i^e@^9:h=m=@\Z*X6@KYu%V?+6
jKW6H! Vyd@*th=uE#@>Fui:*8\@:!:!@EuY?45uL>a<+tJk?qZ$P\@R\N@Aj&nL58jw=q@Bj&#ZY$Pqq>AM:Q@
M6+uT9 ^JZA\jw4cJcjPN\+&H+B@ZNuAAj:4#\+!<<GuiQjRuQ?!k9@YR$k#q<mG>6QjEieVH>YA?k@:@!9jYnD
yZM9yj \5lK!MdM?wLpIGSn?cWcRJ#Aj@cK5HQ?%%/S9*=d<=6ZlQNQ9CKe#Q>CDTCt9>WA?9FF#q>4AL*R:F?4
uiW^tX AjTn6Nj@q#YAYpCR@1?8AaV!H#YAQ1!cy%I&y!B\#RKP=XjEN*&Gin8E#Ni8di8jAdEwj$q!?*@<KRh+
St^RR5 XaJKnPFHeG9BML/PM$/Xm?D98\NQw8LQAJc9#=Q<SRu<c&#<F>V<h$Y5QDqQh^>jeIw@tmubRjw&F9$R
u#&8Ke F9%pMTbQce%Lk=8b%jLdmW?:6e?&m5?quKY:<PPq<VPAPP>Hmq#qaaLVNII:DIKHthSMlYiA=?I#aLD+
KMBIMt GdCdQ96*N%$Q6$Km%+P$$ydtFHyN4$R=lpAnjLdPHjwRc<G<9PwhGYR?>yyhR@Z>N*An@Z\i@/jH/ce>
cG1P1% @pK:/hiC#\D9jS>uklu&jTVCb$CHe$eL$u:cXZCM#%1L@m4W%RDb%=khq#D&/e?4j5V9RelTJpEcqi#F
^6EV!C !9I5aK^\bQp?!<@dRIk\Scd8pyEejaQmj=:cW@e=XZpGuMh&dI1n@F*Y=eZ/li>#:A<tQ4i^9jllai?X
=/eM18 Fjk8b!jSGpj+u/e#L8HGQ$&XCDcDddA8X\/\M=wDXp6tWj4L>A5#F$>8ei&?%R\<8965>/cRMJJpwhY4
<Ih+BV ^Hl%kh*8PPq^q$Ht*qA+!6P9BkJ:cPkECE<dl#=+Rlp\G:!T9>&#=D@5i\cR>?8&Mw+<dpIXqWtFQRMG
hqNj5+ =91=*4$#J$\!cXA*u$wu%F$54pJy>KSK6ZlQwFIZhP*YjJ$hHahc1l@K5%hay@lJ4c*FhI^8Wh*<cwjF
$$Q=Va :4$M9V!514+SP@?dcNWD%^+cnwwV\89Z1<nBmdC?@K8PLD:uqSn8yhCGM#tM@eXcJ=NMmqLS8kl<=$E6
@AYNJA Hh>HCB:/NJ<B5#Kc##M@HTXm!i#aJdHR$8&Qih@IP$am9>w<*h9h<6<%<n@Q:8peh/#JQkPkukF58*@:
bBcBQ1 B#8*#:ebu/+ZhnWqlNyiCnKKRYKcFZE6^LE+j?jjMY4>e+#h:=nt=tYj>4RuyCid5jHq^/8%M=>LY\kN
\>RbGa +1nNh!EH9I+FCctVyYiLp$aEcltYKJ8deIt$6bB=u/VFtHVEEHDG&Ec8/KPQi=+BaE:QAFQ*AC#>CcRH
QEpM9@ lIuH^F%puinq+JQtb$BN/=jAme8id#4QkM>/pB*V?dPE&8:dpR1T/K&^buRc?b1m9NLB84e#lVSq#+DY
$V#8I$ F#pbXe%/FPuLiy::l!E1PTPI9l=VZ8euPE\6/9VtZ&CX>**\1dVMA4q>B8nM<aGhQ#YZipJ6QV1y*CIN
aH=MV* *P@?N/@@?n!j?T<Bj?q/k>Mt>J81/$:ej?DA\5<+<CP#<GTtYieCq>hkSl89&Ad/qB>EI/EnTDGupC#E
jKZN<N 8*Sb=?@>SjlK/@N6tA9%@J9SumNF1>YqB+%R&TTSqZ&SAQ/t+j9AXby:ye&$y:FGR?Yu9dMSZJe6bC!X
>/K>RR JwyP8wdbA199$b=IV9k:YVtWHcpKM*&9^It:i58cqG?I%ja<:Sh?/+m9m<?*JQ/:5NyuRHFK:e@q?ph9
\leaMX y#QN8yTFy9qbVKlX8Rd>e>>QNlDTd9QA%XpQ!hGcKwqT4cdjtwcLk<iMNC9Jq:iy%V%&iK+yi!\p9H5G
^ydwk? >JXMbk\5u:D^ja=M\$TW\6Th@SA#+*G5*8qSWN/QLSZw#a:MDP=mlC=S#/Ip6$n!y=&d?e</N=9=><uj
X<E#G# Q%enXn*>1K@EyPb#nady<<I#>1BpLKm8qTeK+8t:VI*plKT>5p&h>@jXNP=#/w>#L>N>b6duWALiq#uZ
IGa8nM ?YY1JiG9bd\<i9M+R@AR<VV1hnqL<dmA@R^+<=mTjXujjQAS/Y:@MaXb@lK+6nIA:yCDcK/yX@eAFQ!>
RPt&RW B%p9SQ6Q8:P\^>=^Kny^j*w@d9<MAK:A6et4aq*I*:PLNRRyY%pRB8//4/JYpJAtFJW<6H%5X:8aTQce
Sl8j6R MZX\l#%k/+dlych#nXQj&NEK\Z1%T$B:y#<!9/db&6^^P/TS1#u:1hH*he1>uNBVS?+H186*e?F*:ZZq
IpHRlF c&>#P/4k1+/h$&!+/PTYyE5&E:6BDkMJa*wZ94%^GEBy4G%5dyBP5AyE$A<a$\9KeI8I8<MW>^?L$ey4
XIHK@N DmwiJ4YXFbeVqRdRCM>au&n?@p\@&Q8jQiQWH6a#aE%Z?T:4Pu*hI=pKdh#&GYC88dn\FEe$/NJC!!YT
kGlWXV QHpRBFijac#L!%uGldF6lqmal6?IdXk=WYcylSqbekC^E?J^W<K6epHb%W/!KXnW^8TqhCw#/>\G^Gaq
t/Wy>M KBYGq<T:h+<TAl<bTZkGRG>cI8p%4a4LcSQRpIk:J>8Q8Xdl^RcBjY<E>%VlFWNqqH+udSZ?d91Na:i$
NLu\NY KaTMwZ!*8%y\<1DJ&lDm%*FMJQI^W6in%Wb#1\iu%6?tcC!FJAtd%^yy+XT/*be5&>TAe=JC$KlVyR?&
KXhIdY +PcTpyS%C8XacSXR^eQ==!w&E<ii6e@V5d^Q?R*uR<V&Ve<ATjZ*^uSDicRmkun68LC*1R9Icc4#kFDn
KJEK?Y SlB<@MAiWC6^&QV8KGy=D#T6B\:mk$Ph/=P6tu4EYC=c&6HRRR@D#MCWy^tp#?iuajp6u/W:%CDWNNG%
ZdXY?N Ep!Myn=AG+FlAEL&9EpYpLF\9@hjmMMitakIaYmXEJe&uMw8JHy4E:\KP>T*!Ke#A\ebHnkuNQI#TN#W
54!h6L 4mwcKl9PaBJL$<PeSG?MYHq6=8K1KIDWtX%CGMi>d5HR&nhEHDXe/Sb5=^@!8EBS=tTA^Pl&9KIPZnBi
=uJRL? S?KcPl<wBEA9R>YiSyBmQ+1:L5d@GLhmFY6S^b/uuY<pBal\C\u*mmYD9ua>%PP:m^^9IlNFywDBX&D4
EW!VGC Xik@P1JeXW*P5@aW\\9#BYHqHZ<lnAG?@8NP>JNS?VQkkJ#&SdC^%6bYukE9y?Xj5Yi9$y+BFZyny8n1
4/CiQ# 4m*=VM64T#LHKI<n=dG6nlT!p+aW6$wK\#&C9wG5%HctPVj<u?M+V%8:&JJccDN%blDVT#F5&5R*AZ8C
^\uZu# P+Q5h\ILc<VB\+%Y@PW5dl#??mK4E54ZF<?AwB+E1YZhYY9nteLyw/&G$MR<mRKZVSXk&I9mqSm\9^N?
y#4JwN 1<P@h?lc8M+#Q6IaWn#$JwHqW<Aqju8B6@IlKqhyH+adeitbw9J^S9kQ&5j4Z=yF:^VXS/6e*?uGEX&S
h/4lc* 1BMkkP\Mm^R6hZ@8AHyYAhwa4mi8aESd4\LbZiu#wp<dCV=^W6e$%*ZWN4aHd1Qw>McL+RB5kbR8^d69
-A!IdC 000c392c25000110333 Page 328 of binaries1.zip
5yBd*! e@4&wT+:HkA9PtH6m!1A:u?*>kV\GZM9?h89TpljjY=BukG5b9pE+<?AM:Au!#EJ@w^u\D4W\$J1nA@*
^V#i5W M/AV/c/KqjDy:VQAq?BT#%L\+jV=SYZjLb@>9VZN9:X&?ejY4Q/n6R>^jBBVwVpA9&\Z1JXdI@e@V1y@
uR>5dG >>/+MMamLWGW#LpZ\MLD^Y&yHNDajX$w44hGTVhqRe//QGklZK#EmmRluYqjJw^8Amb*idqL&1Rc@W<q
ul@EE& hcT>JC!4IiRhb^!1:D8X\S!6TKRh?>QlwZ64DRYLDteE4b^W6dXY4:njWiJ=1E&SMq$w!YQQE5>iHA1G
H8\eJI V@6<qd<Fi?u@t?j=>L?htPW@A<c##1Bilpd!GbDB9+:$MJec@\#k<8pp8C6nyZl!jlpc@p5%T@tH@bil
aLqw1W <Zpbt1!:tciZEZpbG@:LwkiR9+#$j:e=Z9n*PHkq+Q:XJAXiE%HYm%D1#\D*F^W@ya#@QnTe@&ZY@@9^
NDCXK/ /1=+1?$9&uCN==R1t^NYX*LP%<Qb>@T^&JKbybGbTZtcqbV\NeAkm$GM6LWEa=Nj#:u5qb1=d&BaG=6!
RIGY:Q !?QcDPc8/lIXFA:!%H#>+YT$5d>#5uKJNlLYWQ8LjBqDhAYy9T/JqCwBT$cY%Z1bn/y<Smai?G>&::<>
WG\SJQ 6D+DZuR=Y:9jj*w^bDK>*n*y?Y\<A^4bF#y&9n+SjHj/j?EZhK#ZhjV6XeZCXEZ$8tqwj%SFZkbL=@jB
8$<##D +5nBGiHy<%+K1uAk\S%+lb*:G4a\K*RNSEND%=LhRXP#*#VVdDPM^/q+n#>b1#%E>umm\FFV<J$#SW#S
/lDMI6 i?JkW6TX@b9DA+H8AF5Qlcn?N14a:^qmeJFmcK<Rbd<Z4lWj*&/M^\Sa8k+<hG#Ey@?k=@eTX9BQm6c6
bd>cEI PTck/bceF/\<B^!Vhp&5udGcXkeJeRjp6k^Vtd+^wGGJyGGut>\G+THZkIdaILQ9NQcDe!W:&Ec!YLc9
6l@%I^ m&dp4ka?Q#44mNWG4<epJKbE$SHZqNdM*QpcZ=*K%9=Ry@/#=jNqW9\8/?k#:DQ9qA1ZM8H^l19^w4D5
iA*pEq HdiDAlnVddSHbnQH^WAT^WXqkXYyZydTclq/FJd=CG\b&4yE+Y5LLe\1+>*\C6h91klFVHG1R4P$$Vew
iAa#H* TRt=$h/j^#%:!6QcnP/PCy+BIlacA\M==@!TuT*eI@Rqb4+L*<Lpy=4Hm%+IQ!C&>8mb899TN\P=K%kL
KcF1PQ ?V1aR**I%#nN:BhFK&8Zi4c!D!Zj&B<YRpde$ZpCAnpbeE9LI>a\*KbWR@qN4mcib%Mm%aa!FE$nt/6F
cDj@Tp VDXlMeuj8\h6/X98DJX1hY6I:HHEFc*H?Kt%N5Y5aiG?X9uPi<=^uecJqW!t4ATL9dMNMEw9^u:kCiS$
5Bi@1h 4q^%+15%CV%\E5wL=aj#R+tcEHeyQc:u81pRR$Reyeckim1L!nw/a#=RG!Rtt+waGTaVmj$e%J?nGQ1a
65YjXc E<%iVWYWH?JkFKtuAw<&S=nyM>JPm=<CmpEyK1w/ePm=pud*w+^FFV9=p<4*6Jibd/knpY@*^:VwcLj#
jWJ^Te w>JF/%?9wM<QR<=dFTTwmFK#B98DCjPdXFi?EHWdyi+&&1+H\4!lBQ*ai8k5Pw4>HGQF5%@!lL\^c8l+
ptj<Bc XVW^wa\G%k<ybB#1K@ju:Lp*H?5!Ja+/>XikdDH8%IuQl/e!Y6:mMF%pjAS/^*?A#jY4Z5mlMPMZp:?!
Tp!&VF C9CTYpR<Ad4<+E4\5SjBAB6RemMph+R+n&?\ZIDYE@*6QTQW*DF=atZlJ%j6KM4aYqyuW:NN=NL<>??N
5YTQw* /ud$B9mj=?PiI1aI#W*\FB@%GIjG/^!I5ta\!MS:wa8CFt56=4G5cNH+=\&8<eicVctnND+>l4G44#Ch
5@^wa/ S6=HlVJF:8Pqy+?kZMPy^mV#iNPHTdL5j/BqCe!EC*TlLj5iCE^TKwXb^PV^m<wI6u+hP+D*PpG&C^qD
Bhu$H8 DdJXaLuMej<$$NHC\#LjCT+iYkMXTXPLca#9NcI$FX+:mBlBy>E#IMi/!#E>QuFk9qMLWHN&heC&@%*:
Qk%8L^ &<$!9NQQ6Gi5V@KPQmM9wyF?\DYKIp#1y!blTDKZ8laSJ@wM\Mq&&edccaiac6&!e!tJbFNVbD=>+\:#
@@MES< PL85Aw5@Xa#W:Tn@#wq&clKkjXLyYKE@:G$+!$yXch\ARYwZ<AHb=lpA+Z<XQXIjES=y/WKhlhIae6^+
%G\/1M !Z@XQZLhNQhIlYF!Z*+!8e?qA^WcI%+4TZRW94Zt:W@/JJ>=hVDb^aFqHXhcq#RmRRkkCJ+q&iLjbT::
jwhpdT IWKG*@ZF#<eCq=I!YK?1ib#8cZAH+&BX1q$nG?+<*MLhZYhHVVRLw@kw!>C6$SFB@G$l9Qqe:L!?9<#N
u6mT^1 mZ#S=teXbhLp+=ikW5p<Mb*hBZI4BNEl!=:FhS1E>FP!XGcTJIyW1ITcXGjulnj1Ie8u9j*?/AZ=LS>G
GP^NCe w^Wb<96W8@SIWqlL<F8R4B5tCbMZ$FcpCb55t@K6/yGXN\T@T+=aG6!6^$q#&p\4pdy>^nRD^Gkka@5C
Ihl>QZ qkGS%QcXTmccPM4lb/SqbXLHbP+8bkqbmK8I8L6@LeHM>R?t:6VjCeJZyM54FQV/&a%dinB5*aRaVRqc
!V9yA\ pKLlFQthcDw44T>=%9QWSI\VeL$ZF\IdR#Chkc#j?cNpY498uL/8$X5+YVt6>R>bKnRYPJC\>^=p+AMi
I+S<TJ K&@6KJJaw>tZ!IIT#kj5e&#JLD:E84*9>XZW>ybl@QSA5E6A4pjZZp@48G#JPNR#Fb5l*K8Ci/tcR*&4
F+B\K1 eWNuGZ!\G+tS:5y&<XbQ4q5e@XRIWdK%k>T%pT&JpXImISB5:<B4ZP+H&Skj1@J8%*YFeN+$MHZuyGau
dd*h%^ GwtK9n*Jj8R&>QTkt:SV4MIPWmqHbTm8X+ESh#H@9QeYu*$MMhw#$DV8?:e/9N8!!W#1w9LM*tlRib*u
yWmIC@ /Zm?TB1/:Q5y>Zy%6Sk1?JXX$6Ky9R:ncK?w&VG:An&6LqIjHZc<PTnW>1^F^%H$pq9*E5Ln$+lHNAht
L*FjbQ =k>ce+Lp&IqLA1%?CN<WG>Ecbe>J56e?55=?\LD<iC/XTe/m9?R$5Aq9*ldJiC\Tm5GHGi>W4!mN@\\a
ThRtNS IVu9%^!kXW5/q*GZm5$huK9RwIT*>DkNN@9#6#cV6jaM<HJ=1551@$4=\iapRh\hhnm9mBGBV@N6!%l@
ZMllCY iBF619Knqy5t=q\Mpu<wkRt!YKiJp@yD%&XRVyGP=64B>IRNebRDeEC+N%l4T9\aJE=Yi5!nId#R+1$Y
uy9Tc& *dKYnt=9i%p@?wXA!P!6@%5PXd8Z/bZJ/4+!\/=C9&%FTE^FZRZ>nhAuDNm*LEMmLb=yaTy8iM1T>Wt<
#8T84E cuMllFAq*&9i@t&?A>P4u!+Zt*L9KM/b#$ap#+:Z/!py9NXw?GJI!LXKbDqcaJJ44S+lj>c@HFTt*Q$l
@q8^!L hY%W/XWte:=J^$p#d4GT+t$^mu@%ht9b%b9u&RRY*Bp6Y8>Yw&$PP8KQkKwm8jQMPD8=4Za!G55%Nd\&
blbDP9 $ia41EIm&M=^V1l4PACXHM8>lY/69F%X/iCbDttpymb!VJ6TLPHnKy5hZw:NLtFW+T/t&W=ZcZhAucu<
%XNP$/ I1<@WlH<6tbkj9lRt!&CtBV#SW/Pu1BcP<a!VL/ZV&BZk>w&EVpKJYSlCH1Ft&L:b:#wYyB/PV4T^EjV
+hTRSu BFbWNa*X&Tw!j8S5R89YywW&S4HjFRTR8YjAF+%u\C:%^FP8$eTQXiiHhi%VRZHIPeIBF6l!uDbTJDEX
CJd@*V XmemKdnP>RSFJK4/Zk%D?TQW/=MhpyBQLA/IVDTwR6ERqdl:!M\HdJjFye5E1lN6$IJZ/XtFFjJ%XN<m
SHMDBd GKi95Ze:G1M@5WK6^n&<*HcW*&49mdQYdPJ=Qqc!dJYScXpp$kF@Ia?atj:<\&6Yk#IKyt4h\Y@:1dLC
eEHj*$ Ku:>uQS^HQRbu<$FVSbXjY#p9udu*?AWNM$j==F#&/t1TBNCdhu!8I6mLaP*8jJ/8%8+X$YjYme<mH?9
*TNC6Y RRCa9/!=ww>?#\BbS8ibFeHCEeeDlFGF%pDAet1Jye8?+6b:LNXM!c*%&I1$cMXKLRE9X6pM:SpGHNaC
LPnkQC JQ/q@a<DA!W<<$uKR11b/!lWwlaa&EIZKCLpCjaRZDiHjpht:<I%htKCZI9NFEXJtdR1n^8YZ#@c@#/8
<q5u>4 kINu\Ct6#!ZGt&iAI6Pd=+Wj$9D8N&tkqiR!P8k<5k>/Bk#Hnl@VBjkSL/hp6qw>Td/K@kT&:M=uc@BF
PRQ=WZ l%B\XqSJ+1=c!?5#iZ%NR&&AwB&&CIE:H?p*nyIw=qq+4H^S:NunpFjBBGWWL$M=FyEpnKhW4cVBRJaN
Gy+:9L 4m1+?CD\8CnD!m8qR1CmaS5c\q?Bt+p*Ruq%G+4>RJkc<!+1yhbTQhTK4Le+JybbFIi+XFEc5N$cT%uB
*IEpFi ZZ%9CRtJ&%DhV/HN%d%NG$ZmCNX9SA6nc5R*k8Tje#Q^QMu@TFblZVkF%=IWdRcc=:8yua^@N+9:^Jy:
>w<BaX :FZel#E/LaLLaYBB\lij^?KZn+m*b4!l>aTn4#>H+8j?yqH%cmNXaEXCphR!w4nuA/qKW@Gl*GhlyXte
8%Yj:+ dpH$6+yJqI%MD$\j%:GX6&!ceZHXe\d/ZMybFtDIT1uF$dCl1\cwA\89m#B6XW+F&@ttD?:6T5NDSwET
+XVb=G J8:GXL$l<ZEM^^&>jdEqP5Ahkw8Sb\Bw%4W!P?W#IEu@F9%H5b%t<aicF^8&/FFqdJl@J@pJk9?k$Fd^
SC9DtM GWDdeWd%w*KQa@Th/VQk9j^>TX1C#\nDA/#QuM!e<w$\$4Xj>P&LSj+H5?6qZawttK@ETQF^Y@eVD?%i
8*kKd* t%4mj/lbj4pH^hZII$F?XNL<m?WL<<nWQTKNV:j?a59J:/ehiNl>*$T/^Sm:=tX@QIh/kN&>#@#\hP9@
C=9*kp BME$bFQW*:WXl8G!Am#%+$9Zu+&?Y#nFcbN+MR&>#>Q?8&jQ$^pi5T?&=PMYi\uBbhWZ=9@^M$dE<n$d
yVVIFh +#!pd+W#Q+4b@NlbnV+e&\:lGcypV$E=ajCS$NFlDEp5N*$1dGn#hRF/9WtYw^wwYW!<nmbh%6dih%y5
X+Fqi\ &*cN:!QlpRIhl9j\$GtSQwVTX#/atbJ/Y9^P1wDS>+VX$VIHiqH#9n\ZE+FS#&nj4PFc1ySLnFPM:GC&
HE9K!X 1J&YFaqW*NdIm&>V<=Hdj4RXA#/&B%%=/qGhS$@FHR\YdVllGa*=#8lW!>%/<:+kit+=VDidhBR*t:l@
yqBM&I p=ZMFYIIj$<Pi@W\W<cqwTFi#wK9$Jba&da?Rt^GZ^wuVNNEQFF<u1mwBQjSZ&5?BXjYiAmwC/M8uWSn
y?Mp4W 6?aQ&q@R#F=PGCNlX6TJ!=WnlIS16jY/JXp/:tdutDCJ?&&VYV*m+btAZtpewdIc*A1dbKZ?aAQYp9?>
RS\Dn$ w&/ZE&**?C6ZVZAt&8ByY$jwQXK%jcGlke4dDb<:H*RFHVm1Rkacn@qhL1=?9qIyH=@?cEtlJqcMCmbK
lj5pLu F*=CWwK&teyM4^B>YcH+@TXXh!?#8t8mNG>i$myL$#*l\bIC+hj%+:Kmh:XTkZ:F#edtGQ*LT/YQJ54H
@?X<T^ C%G4D8:%E/RlhLTFM!aj/HDeQT!#ei9wTM4d/:YVejkk>bePN%DuVGi?hmVy$4MHVjubT:yhdKPIBAVe
jh1w98 m84qK+Q<&I1i*ZD@l<KwnNQ*im@YC&*HicZQ<>#B>DQA:St\e5%9h?^V</*jb=4Q:q=<:Bpkehi^V<D?
ATW*Mi TQK!aMjm@P$\**Q6Kn46TeV5d+i^q:>BZlcJA=@@?PEP=V@?>X64&&J@*@BD!N@ha^%j?*Fd@q9Y+*:h
\=wJ5B +e#n\a9M@up%IW/YQ*==!eVK^9q@SVJQ+%lJ=&KyABR#kYLTL?Y\+eMBaIc6laLEebJ=n5*t%M=@?^I$
-Ap&i\ 0006881eec200110333 Page 329 of binaries1.zip
YlA^1A D\?B=AIHL$tPEQPRCMIByKZnXWq+pLAGLS/G:I+6JFePaNbmCFjCNG=QWM\\LXYhWDqFFNXH=SIc$nk1
>AjP>< M>&cI^MBmw$/?HZk/=%L!?9akMZmKlCy:5+mYm91<dykPM6huEA\mbZtLlIPAWyGcSX5Tn1mhG^p?B/Q
@#AMFS E<\8IuAkNkSw/k=+lL&GRk?phB%!Q<QpakSLN+nAb:SAFGR6uF/@qH$p$T%+FibKtXyGCQL*ydaZLND*
>6+D@M 9cWpCMPR$+FhcY1+idAi8SDWaZB<V@!V+PAXNH/=k^C$ZcXu/BCVRpuw$FdyEt\IVFK#VRmGkA^PMVnj
>5/R&^ M@TkDaG>44+eCMl/$V\9GL#^\WqFWWkt/>ehpHZI!lJhiW:\HaI$<j=5\QJQSqmRZeWPbA\nwE@*$GG*
B<a\5B B6lD<6>919u5cTjSaePq%qtW#m&*t+T5<Yu$?:wTJJkX$D%PnTHA#AXw^l^!JhAS+h:lGDCyPJ9ZA%GS
aR*S$+ VRWmE%1^&TP8YmZ^GVaE?p!t%GYi=RQA9E1dNGK<GDpD*$9n+$XR^u#XW\b#P@WTTekwSNbTMD$YtkX!
FFaSXt FV?C!LlI+PSdIyiwnTT1nDDSABQG\MVi#wE=4nKbcH*cnDBNPRmp\qdAZJQ^J!Plqt<y@ew8tB5hdw!G
C$kE9& dZB9HA:&Rb8&!$CRTG=DqEIkIlbn8w>lF1GlmcGe4Lm4K^tBQ%?^b*T?WipnykWkTLCt<%YR^j*5DtNm
nMQB=c FGN=\*WCcHtXB@ETF##L1&VI/WPD4&%KDa9G1KL5m#*&FR+VEH+4k1K^+K6%^h65!=P!pINc$1bEBR/N
?lb5He Ry?HX\ZqCZ9w<\wRjAZDE$GSLhESppj6ekTP/mw!XJ\I>V&@tjwyZ4ZcLF+q&ht5Yw*/9G8deRq\=L^b
DK%LAi Ede!PT5Qy8?*TGkDa#8!k$@KIPP&BP?AqLluAB/j+S5DdF>XS*S%5TZTPFawTMM*pWWXc&W!98Y>qu4$
GS\mtP mhA=F1aplDYDH&SkXMAY^kPBQcE41^LDXi@KbnMKB8!u4D58J*:R+4HL4tbHH>j$Y/iWNVeWKQt/y#ML
4u\Hcl P\lSMChKLE=8MAw/KaJ\ul<MLSMqVPJHn$Da^F1A%\\CMFIW9Y&k9%nHAyFBpkVBIZ5NhNaKPYPGJF\>
TeZuXb dWeXW=L5&cESCY\tB</9ykGlTYG/DLp9%mQl@CKBMD9C^Sl8%X$AwalT6$FI6<t94&Ce/MIFd>4:TkDC
ADKRu# !C/SyXyWu^bPZ/PMi5TERSK%%N^ut?B?CS!tG&qyS5eJd=tB#$pT4=BA*nLP=VT\JG4HAt#k#/cP/lSd
M=KMIX <\#P1kZQ>ySHjF^yqFCal%XaCW8eN6NyaC+5WiXB6#+8yC%hN<bCBnFD:G44^RKDQ@i*eKT9MqRpG\4\
@dByYV SDLyM/cK1i!K5jam9G>T6D#*IGKl>lQ!JaTi:l!WdL!JEp1^n#<ZVGVDN4tI#Z$jNG*TmdW+jTRMB$qj
l\w?^e M+e<mXE?m!e6S^iG4%6lMP\@D=:uN4QLQ:H6&GSITcX^wn6IW@TY9MmIW^QlJCaIij!X@qCER&B*FGHB
Dq8V!> Bnq?lDA>i1+HG%Yyk4aGw\$EH=$wb<9KuPJVPy&HE9*u>PbaS?=khQh9tJ@6cHX:+EPmn4$1F:\9Cn%I
hFMF5^ W?qDFhnaFlk^BI>bc5&jbEKa5Sd9G*&k@bktQHC4h/T?^nm$N9uBpwad6:KBw:w1DH&&uE&11^R<*!&b
e=1WyN QFM1pFEFw/PG<J#<kB/tq5+ZZj6wWjRBjXA/$D?l4wXh\?MV1<#WS@InRYQWlHKJyH6XEm9QcNHRKAT=
wh:MFt uGZYZ5JFJ8^mDhRcKi4w@5XZ*/W6I*FKqAl>tR11>XCFLcLARbDbM/cSBRV?jK%l@Z?9kkaV+i@^e@@6
i+h@XP WF%P6u<6XBjI!QTHWN&ZK*<=E<*9IaB@CC:<p\lQV4bjDlDq=Qn*+J#@HN4I!jbjl#d?NejDn>BGIJD>
R9L^5K n/GN9+*LQ?eRb&V=@@M>@M@pi<CDIEy#^j=jui?B&@#Qe$*>Jku@8cD@XMD@Wcy@YY!BnMD@Wt!B#E^@
RE<DZV I4dMnH<WY!Duj!9CHklp?<eI?:?T@8YA+<?pG5n+^+D%*=:kH/Pj@#!DDJCS=SjRQ!1?@Dtc>Xj8#jG#
Q*TGV< i:Q>C9wuiZiAnP!@kGbqa@pJt8NZ$D?JX\e!e9+Ct8Wuaj=AJ5b@C<*$C&ltny?lkd?A@8ppDtSm@9jk
AhQ?@q LL@$=D>lG>P95I&hpjWucLb@C@%LdGNu?\tc+>>Ce@+:cPC95I&X?ThnD9\X64E!@WVKkL@CNmDuV:kK
1m6h^5 @BY!5RJ@>6\5@%dQYj@LNaCFk@PQc\AdP@AQc\AdP>N@c\%ka?Q+^#YAni%QFV4kQ^WB?@*Vqh@/@4Mp
Qma/h4 ZL@&/Rw#B<jLH!5l/<9/<CNZ*Z@>/R4\H&8KKj#HcQ>N9&N:tVbbZ=:/^*hjj>Q9PQ>i9?Q+E@*8H/8N
TCcS1# @Xt:j>MdGj@Y:6>W^d?$!\4<5*d@yQk%M#5#?*?6PEL$GAK/aiq^EMTI\YLVeYGJMMFBL#nqMN>\lpAZ
VcF?qq lLm6P>LnRWQ&wERkC4G<E8<ZAtpc%iFMVI?w9tVlCXAJDl@5mRYuLYGFRCBqNGiFFtDBG^K4F1\iNcjH
?mw&/% nX\QFLdtA?jMF#^EG&+#i/YGnAH9Cy4#=VZqK%mywGJ*VH9a\BZDtHYFZV+tQ@H<YaiRTWECuC=!beu/
#q+DSF htjt#EX#MHjQ!qDc@1q?l@QYemh/QHk!F&qI9uba#M+kMJmh5HL/1dZ!/w9F:FI1#DXSKCcJSRZVSjlk
L#YXP& a9?pHqehHH6Z9/taTRXCpmNI:64K4/+YRKiG::EJMRwe?@CmbNM=%E:e9SMdF=wBYGQdI+lAE5MKQ8Y$
K\GZ>y W4>5BTqTak!uGw$u6XiM%JQ%hL:KabiEp:lHMcRMSyp+RbJ\HHhpB<M6qWJWY*!V>amq*a<5k9:Ie?>q
d+#c&R #XMbI*8k^%pmi#kE!CL!lyqS8ilCDLaCmTLM1CL!59jSSiYYY+J:RQ\iFkP:I9mIJSCRnX:%&BkwWJIL
^hSXAp M%98N>45tT^H>4!!Z&&I&t1FwBA5/<+t&il?GBk68$1K1\IBYPJBDupW*u:ea?bH4K9iWyntn:M9\S*i
ThGC#1 Ep:+Gpn$!Y!S4R8k6BpIlti=yTAd:5w+bSmm\MFP#:mQG+!ad9cqRSA\#CPYp$HQyyAn$M$!S?ICJS#E
*R46*n 5mew!Ndnla!PiQW8YuciTNRce+wXZ%wXwXLqnb4CuJM%eE4FSJK1u^WBe$9na/LKw51<cmZtdA@9B+6A
LIV+WH >FXjhLZIJkHY9wwCD&RPt*y*8aZniwE6?Id\TLPtlSBFG*C\MS8>=p4TK9j?8I58a1/e$X=1TYSjA?\N
D>JpNN y^q^yI+K<\Zejy5ic=+6lC$D*EAMp$m9TSCBmcmG&BSh1cbNGT6ybYeDAea=uFeYatyVGYjwam\u4MJV
^q9%tX CjbcY%L#*IuT<Ky!Qtqj4yCNcd/!>tFqtLEQKtjwkGX/e:%^&:dS6>\RVyQd1?Sqe4i$VdPlW9n<*RN#
RC8j+$ G?hS6&n1p%^!SyT@6!9upV6CeGuV@hYd+6NQqIK%T>h5I:J:u@H^eMViuXky\=Mpa9mDCGY4#NVb8=Jt
l#^#mK GZ&1FNijuC?4pGHn^8kVXw&5%+$SFYdRR$j<#KAh#edqd&kT!ApqK?&1i>!DP@qb6&Jp+BK5M+5TI\I/
Jun\$L M=?Sb\t*WhAJnLQ8NBe^IMj?p!lI*Sk+>/VpFJ:Wnm8KeKL6Ej8^V&#WJ!>Vb>Gy1\:GWZQQtc@QVnyl
<Yh8aG kmDFnL\CP$eE6V!/1I4K@JLk/$Y#R4Bwh!M/\XR$caH\#b@hb^VG*KZym$D9q$Fk4AZ!X+9#Rl#TQbJ5
HVnZ9# D1hWTpSbeyjDTmDC/Gm/VhQHQwP#eZT64BB&KySm%4L1dRSEBI8qq@l:e9lLVKQ=lZBCc+KBGEG>St?A
cEc%&c wEQP8Y@^G&bN/WpE\1LGt=m?d&Z#A/^lGcR%l%ywIiayKMKQ\<6wD6M#5ZApjTIS5CPZ!6@L4+%/6b^c
k6CaWq /A:nNedbV^m9n+4nGeMdZu@n9b:SR&kmdSyZ+>w?dQ!PNqlYeqA5Tb^$8V#DauKiwXu6KGF:lhi@\wK1
Ky8*a* pcX!/>WqmbL9pLAIYQu&ylM?PEKNS1tF@YyQt45P!6G!?B\c%q^NlGy@9/ApFDT5MZyG9GNp:<h>4kp=
5QCn4? upZ4t9hLnbB#BC55k+pDiI\n>e4$aP>CHFCFBGQ8aH6m4pIp1M/SeTeH!^CJC*WqheQVBSVPe%MIajy*
8\D^HE 844EiIy$tS1WjP6Yk#wZZ/99N/8XJ>/tF>Mj9BL</BI%J/^R/>1Wq6Ppa=Wb!%Rd6I4#wj$6!u%e8we<
X+yV>5 #YicW\Mukj%KFtPYLMZiaBc*4RK1Xq^lW:y+8<\k$DA$YVNcNlQ$>u^&bcMq>APidA^/j@tqN$n=T\ql
Ac+IbZ V9RwpJJL8#w4b@JWyLMT:whw!ZMaKpThZEFpCwea$pJYX:H*qe$!%pqG^&/Y%%/MwkiP!T*4t9C^pmTm
?cy&pC /R*J$=65I\uAc5t*BweitS!HqwGqy8F/4&B94EelPaLIaR#tb!k+Ipy\c\D48I5pNNtMwkIFnCN/TjeS
FqVABe <QNC+byp5?XqLXhqq&&IH*EHi:a%K^D4Mkaut/&E8<AF8D=1wY6ANPRpd6NGnal1Ewi!P^6LAFXtR><F
kh:uFR k5Zn?9uS5DQ&e$MqCu\<&F#XXaMpu>tL1c^WT8KmwX%pEiMcZ8qpkA&w&MX%VBIcJ/THDJLJay!G9:Zu
4@ALcB jIRA5b@K!J*Zqub*jFe\6a<5aPE:55km$hqWknaN4nSw!A\mC8DIbBVAFRT:y:@X8Iu^i\\KheWZE^Zw
Jl6:ZP MmK5lAb#!PDypmDbNEk\Eqbib8lcR\IFyEKDL8wTh5Ye?#6@Dk\VlAcH/5Z%=<qW9AmqRRnkwaw=!#YW
HWQCbS 8=jyKJmNIZecjbd1^+E$a$Im*N/:uGp#LdjuwRA@K$dSq8AKk5ja:wnwq\=DbmhqHu&X1kPjPjp>!>A&
eWGqh= kHC&@/$<6CqLRV&Vd:4BalXSBVACil/%/kBBXDWSP@5w!Hdk\L&R&wbW:W4Ru8XDt:VFKLF+KVCyhQ8N
&>YJuK VttAuA6kDPekVF8>bDi^!9cAXeXL:nnQ6WudtY&d*?S>Npm@H#k<+W=%G/L=bcyk?Znkt$YN?@GWud!\
eG\T%% ahi\NA#cnW*m^waDZap8ellVFc+6h9k>Jpl6kaTyI%uEM56tBXYQ@hnWFPXnAwhb$+m%BNd1YqyZuFpF
M*^>\y RcQ5%JG1ch88lZL:lIXJ\q46:pt@^H*n*Kh9KThGZ!mcMP!YQBFbG/pmKkI41%!w?5Zn:PSX6PccN:>j
/k*bwJ 1eB1iW4P/Z1W1JkX/D\lVcSWwG6:=FT16%P%tMyY41yTj/\&<^XYmHE5#lBXy>CKyda%q6XS\htw!%En
ej>D+$ ZGZuL++Y$#<ZK!@#ht$8*YwJ5\yDQV4wIt4tCYWY5=pM+lkeIaF6S%VM^RINmm5!/6YPSmPLkTIZeemH
<ij=/K I@jutac98lXLNFuk>Gi!yik/p165nX!aiNeAY=4$qpDd58TMD*%*e5==kZkkCh=^VC/9*wWRE<<?IbcN
hVQB8< +5=PG\Q#HRp+TBSJ&Tt&>aQK#5qKauD?RHiMVBZ%t:DXYCB+98%V<$\1Z/JeI+e?k9jEZDmV#I4ZuHMB
nnmFQD @4ih/yGhEZywZ>6h!aad/>=qd\b:/\?/T^\d8CuF>h6dwl#jSd6X4cRiLI5llc$lAlijJ<Ejyh1bn5mJ
lB*#m5 9lK!kkbRGuW9:aFuCw6RXiX#\NYJR:m%RLucDim+mcn5F5C9qCwkRkl<Mlk>MBN#I^iwFQjqqN%WGDSn
cI@V%j W?CBnD1T!#8nB=m\Al^:!lE:l=C:mMeXbX/DCK*$ht<#H%GDk+GT>Ra\SBkSBqn*S\k^?1L*=1:*HmuS
-AQn@w 0008a05993c00110333 Page 330 of binaries1.zip
<M1&uW q/9DCtpS&yj*?EH*Y\5\G1D*H#u/n4wPXLeQdGIPEwMLYIiInWaM\Th5!cRPd+H!!kkMS=V:uPXDVwEV
HCtMA5 SnTA!LTA!LRVk*:^Mbpe#jWaa$KBD>n$>i5i&$N5ZDe+yYluFSeKkjbWCq^lb:Spa<C>ZNh/GMeLGXdJ
ySEiSp k8Dm5E1/NTXYMp=RLqI+eXAwLC=EFNAyP\IFG4M5&bhAG^W8uTnhdTeIDknBuIpyDn/aT*Fbp>6?DiL/
</1@<N BpF8q9@tXckVFIS6Llt<?w+Makqd#ZtytBtH*%/:PyPY%u:CIXR\buG:GSphuu?WlqRaQNPpZa@SBdTE
mWqkI/ #8CXY<l&e@GDkmn=B/P#C*tqGEWDh6MWiFJu$?D6JFI#C=II^I>HdN6/mAc:H<nwePNwXbZa1w=HJ\Lc
V$RGAe CeiKDSZwuYL=\cTGV\M!<H6MXEQ$\p!Jw!lYC8V5CLMX9Q&D&K%W9yqmR@h=Z+JXaES=RqBhA!4*6P&q
mJE=SA XMcV8M\*n<!6!APJ1AK1h?Pm4PWCmm6$CqG?Aik>^G^DRT#Dce4w*XBdEDyH\DyNCyV<cm%ZEICFqZHq
\5<KmA >5BQiBNJ=bSw=Ik*>\JL=/ipZBNlX4+uN?HR6mGVG:9ZnNEKwa:wlhCmnNGkwiecXu8VIiW*K?Sm!plK
1mE1C\ j86NL<1$KnN$JFJa?B6cYIFCcDLumMFFn9WRL^knnkuRM&dweAN61wDKk?Q6>MN%hhFT^&lmmF%yNkeX
m5u:uT CEClw9FdV8MIPF?q\mnewPI!X84NuTHeqW5=E8B>#Inu1aD=qEq/e1lA8kZ6Vmt\44e\#VTaTFVGHlE*
L&1jK= Skp!XdLc!4VVbkcK6%D1#TtjmeEiCiFSpwZqi1lA!yCHD6YmBXNyqymQ\BDdB!DkR?lk85Xm?BX<A61E
PTG1nY \Q1iYYCRdkKneepA5Vl5\yb%QNy>ZAKy\*tLl6q*9wJ55Ww^h/w9tY>+G9h\!<>ZnwdPtWYJGeuimyj6
*h<4VV =RqHbXWdNhV!1A^EW9yH\JF=Q$9pB=PXJkW&^NhFyahBl=NXaIb@&i5WbGKyIlI#aAjm!+l%Tj6?FVe^
&^ZX/m 1=NbaLKbpJawZ?<J8YaJqK^VPA!*wpejJGF/C$FY#Y/nT&Sldh=Zdm+JuqW*u!@^KFYLL^QQVN6ZuXI6
9hq&aK Lk8dITYFGb?>4\lN4!N@6XyAy%VlEVu!qtF+?JSE/%9^!4h%kdP>yHAM$9A*q9FXGE4K8N6p#1GT:K4d
6Gyq4/ btj%G8wm^umw#kuFi&#P+?1T6EwV\l1Iw@F&1K15D11&mBEVwB8ZS6@&iNZMW/NbBVHS\@FD$4kyp$K9
VF#EqF #pHA*kkijePjB6E&h95t&aZbF*SL<Xq8pQ=PVqJF>mMn\AbhJB$SaX1>>AwSaumjqY6udQ/L?jd>/E%X
V>E6Ni JR!FcZ?F>GKAkwc/NPS5Qbj8#tny8FcAdHh<tWw\aT&+=jT\LiIZYEL+BqJyGEZ!JFD6IEu$A*GnKPCG
MZKQ=# 11NB=Q$t%cA@Ry>BGJEbJA?dtnRp^Au<QLKY/8+yGwnaX&GTw^8E+wcu\\bXq4QIalF@nQXppkyJptnJ
E6X:ww mG?1/Dhe=y/I<tB<y4RShS^5E6X:E1Jc4QWYqcmSE^ncE^#?#K+=cBlAl*ZqMqFhmLBt<$ddiN\#B8<L
^SlX9b XynZF1R*y<RpDGB5qIMdy&LbE^neJS9e^*XNyJtjh9hkWh>4Zqnat>c$JA^duVVWBVQBbKQ@iTwdIDQn
bV@6nh @</ydIDMQ/p\:@S!Jt%l+9V*i#a9X@@%kJZ6>\PP*:jGtSp=jn>k+9#>kP**m=u@t9WG!AL<4i>AFlcY
ZRa&e= 9&&9CN8=9D\!E?N@dP8\59/bp+u=Z*WJ5Q+^/R/R>d?ZhAjI?p>Jh@//u@HQP#B@WtH<4+Q&h*6B\D>Q
:%+6qW H\Q<p\4nj$V@%BQ\J^ZG@+n?1TjkV!1M@\u/b#/MQ/p\@mhwb9cjwDq?Ae*M^9kVNPi9wH?TdAn+J^ZG
4+<QAC @+kG@mS#DjBQKw#@Ej*##jk@1VD?J*V=TcanIM89pI*6b=9TLC!@NPk@R:Q?Y&m&j/9u9$c&u\kb!/?R
\l<969 DjmV&8lAqq<lG=D%J&?M>XjI^5V<E=eZ/=?tTj4Ql@$Z/=H@tQp+PRtbtbkJ&bmajtY9tjYj$!V>6S@@
D!VD+1 YT#B*:cZ@:Iu#MH!J>M</:?TJku+%#SJ#C<n@Ne$TV?Y*u<yVSIVB<jj:$H@j=AucShE:@@1QEta@=Eu
+%1^eS KXq9!RJ#b9CXZB*QmSe/JQV:&>R$#%iVhwHVR!bF*@V$k%SSY<ut9^BVSk#1PEVMi9J@@WmudJ6Qtw4@
RD4=HL MRcm%E5X9euybtHhEq#L/VX=+9p:L%tm$Bulltd/PCd#mm%A!tF9%etmpyV1&>M%XP*\F+$4cbP<9AaE
YGkpc5 *KREPk4peeHdQdI91=SaupGaD45<I8qRqJAE/bSR8Mtue!M\59&DP>1ujdXaIGhE%h^MNYRHutKnD##G
A?@G%N QaQWM/DMyimSyP<b\LL:mFZkM>e!<^T:?TNQpZj+hMjB15W#RPLeb+!#R*Sj@>1&:ltR:>c^t:/Yi%X%
d$mZ!C */nqM<&nj!quN?Yl@1lh\d@@t8G8mH&9nicyan:4Kl44aTd6Tm@^GcB&KH<9H9=pMja@jd85=<pQV@@H
PITKIT >jw@9%&<>LSRd+>eZSp*%VNAQL#w6j:IJ9P@hqi18k!!Q5R5T>==/QjQkJAN*bQwww4=>A:qByDKpPIk
uBJS/e S8n:6l/FKL=X@5Q!=/u>JdNp#A4*$96yH1PqR#@w&>MlVKqM1iY=/qF*6Wuu=uTj#4jQAMP$B^wL4We#
!^Nj<? n>5Hkp5^\^%6ARAY5!<Zp9?V?hkVSl*GM$A!!:9D?Mebb9$#IPuD$>ZL1DH:BNyATZ@+hunD9^8^6tGq
IXQkFt j&iShTy@q<h?1:Z\yQZt?<\j4/@\&Tu$cj9j+9Lu/TQ?@<Q/DJ^IQIaNbEj#yB8TXe1imd+\@i@ltWb&
=!8Lil \pW4*u^wN?Z*m!Cde>b&8&/DubVaIY>P1MXXecl46ttaiJ+=>Nd+<WHX&q$E\aWbV?#P:9DIYGJ!Gk$D
8S9YcV t=1ihZq4ii6u#ijb$:8ctp6V$*@<Z>Rl@$Ze*h5uI+yuRDF*?9Qe4#R%@$6NLj^KW=P@%NVW4#R%@W6N
IPGH8h @W?PFjibukyhE#y/=Y:Gj8!n98/5hWHT?C8NuFR>8MKX%YESXM/6IhP41Rm#@MBDbcu#+m:=Ml&Lt*p\
%Fq$i1 >XCI&jP5mqh9Z/hKlPHei4SK$*qubaK$ZP1PqWy!:*$nZ$XHaehlJ^jEB:%ZQhW@YwMWLj6CXl&*8^\R
qL!kmM J\FP^<Vad?#!Xm#^k/V\tZKw%t!FRCX^/qQ?Pqy?E\VKCE%4CB!y*e*t?^:abkZq=M<4IEu6^l>Ey%11
ktn^Py #juKdhwlHZECS$@66AbD5yAR6bpk/+4:ID6ac6D4bua#JP&nY$18=6u5\pQq!k<wi#H%PnCE\QSu<+Eq
QRt5Bt $&?CYLhLPDW%I@untEBY@BY%GP+$1GZXd8cuaY#LS*Tp1RI*\tMJ<?%IkIB!HRKb^CLn4VBN!:h9!Wb9
\Jq#A> GG^LeIjE4nqjK=aHmqMt\5C9YA^@e5bGqYjWC%HT>8LSVSJ/5Ct\wLy^!<MIC45!p4B$Zm1!Nq>\ahYM
%\VElR *t5t&/AyN/GhTwyP/EQC>J$<n?S6J%J1Guwa<+FBu:LFpSK#?6:*8B&Ny^hV4qL<l9i:imF55P/H94kJ
t9a?Ba w=5bQbkT9HL%>&EmEW=pEGD*mc@eaP$mbqkn=i+qM4hpW5jJ<emnFKSJ&QaP*K1I6My5GkaKZ:?RaPJ*
iDKRPZ ^l9kT#&Ym#bCSEd&6picJW?JQ1:E#VdC<K<=F#CYQTk4nBJGWEcT*8+ahPW#KiKA$@1561uHuBe+YLk5
R\#k+* Z%uym$9FdhDV>jXI\\YLPya@ldkw=e<JICm\+*?EYLl&Cj%<Fa49#+?lCJ\TJ\/#AmqlAYAWu&<qP8&?
*k\SmN G#S^DydIXETQ^B9*EqGFFi?ZDE1Z!qT6%LyLi5!ZtJFIE9ImN*:FN<VAH^$ST#Ly+d\1961M<1:5AGZI
P/ICy/ AS#ZM*nGPay1AInNiJ5QT?\SeD1RBKHQbLq9mqiSP<E/1CFTuC5C5S&cd<8V8%jPpRX:K1QkH1%kHuG?
kcB*+N h!tJStR8=SGaHmK#IbWmnq8NM6@tk^dJ6/5>\qH=y6FKE??%k8SNWpDpAXaF#R!E&R>lmX%></TpV@<M
4pXVb# GBX=Bq^DPYZ>aS4ahEwq=N<l:*p$nF%>y>wc?1Y99GI1I+>Lh?#T/Z*B4W<4hJE@1IRT#JjEA96^!hQn
abTiGj 1^BdX8n5h>5cpa6CZ@!a1G5GC>:d\mk6**R/*RYh+JmGZ%qX9:?X&wmGKFFXa^mIlQEYWa?SD<8A%D:W
Xjc1Ei CpX<JStd/A*4EHQlWd#<#ijN<Y5>5I<5jVc5+ZiFaVTS%FcGNMk+yX$C8&De^Ipa8h>P*mqq$:P8Cmqj
!WFJIY c^lEH!4Y\mS1DBdNLJcJ:8PEPXp/\uKy1B8wQjKYkKDIa94I?VJ8h5YuqB6Hw!!1q8l^k:Yb5?q1thMh
%KQ#A$ W!S>V4RqtIqQMdqKT#:&R?4ybi?d#qa?Xkhd6L\9GA&#bhp*Euw%6$%h*CtG*u*+8Mup?t$^68G#Y46l
V#>MD@ uCbC*Xpj@1EpKbQYjReBm=1DulS%$Z8qaYmwZ45w*L:N#!Q&1i/St&u9^epbB>jQ:Q55qMqRPyIhHS1?
MGQTaP GKdc^:jXmNw+R5%?!Cee%SKIQh@PB1G8y41<dVyY!S1nH?%R1YZ8SbZWY?hkTk!N^Sd9mehWY5NN^DQ*
Jh<%E8 PFdZ9M9pD6tMW\tQD+/N+\VnE9HQA8cD6Zkc%@Q8\XStqGkjTJII:D&qKZ%5e1H5qER4R^!NRB4Qk@!L
8WwEbR jQ\&nS8/Xuk$TFwVVIF8&pqunJ^FY8DF#cdmQ\Qi!ljBcw>PNScQ\WPDK\+S^k//$B9qT4Su!H>4E?@t
C#I>Jj V5ek4!<t15P<%%+l//6PH+KDnPAW<=GR+H6hm5+8H?JcThn!yi+nN%@T!WbtGKcmACiR/uGld@m>bV%a
@PjIeL tVL%+Yl1kD!^eQ+IaikZ#k@?yeXKjMBSZ\hKh^Z%Rm**eEWLVJdy@JlaPGd^pTQyCY<kMTMkB+Qp4A84
F&Mw!K yVI*dpY:^=RRil>QHeBE?mIk1qh4MjIG>6THT$8j^WuML$ceMXGwAaj1eiS96+ak8*!XN*VQBZeSbHPb
R5&$%^ C&Nyiki%Z9QeMTF@<E5$:/P?mt4ueClcGZ9:B1Q*nLW8CwuTBN$$l%Dq*Z5hnL?5IPI8YZiTuy?iAW^w
GQ:!T* #+Bb@HGjQ!^4t$=^JMWaQQF&N<IDJC$*bV=kddH%DTHDW$<Su%4La##1hR6XCEA1*GLpLTeN!?SL6C!R
p4#uVh ^>!I4La%&y8tL1=W+uI%$RuC@YadH19l:/<jkCQaM=1>DN*1CGjFbK4/5RDq4Y%^QhC/+!kda#Y</L$B
GAt:W9 It<IEQ&68FK&Y$8$a$bT=%ju=CpFlSWqa!!KP98P&1EcWTKZ5FBMR=>FwWRj9Ewl9i^WZVEuTc%e$ByL
Ea1HXR FbKkjEGDZnP\k^=L?TLPce*Cc^!&DJ\5tq@cE#4lTS4wiJ@c6FJjXiEH6<Mu1#d=jbq&6\uBR6wjGeSk
D/TuP^ athaJ5D1/YZdKmp!4u/HwK/YKZ4jF^ET\JkT\%GGJEMXWMKZm*1<Xm<iyF4b\SQ*!tI4qEFQpml5qlMi
PlC1=\ H!QDT9e#Emle<iINVV9@XZ8&>W+VymlytB/ETYtRtHLZ?^Z%D:DLD>#^G!FXKR!pDXbhhll%hGnTXuRn
b5>TnT mXGKk!EVJXIMbHpAWhq*!5n^a$wlTlJKuDl?pM11L1:&/VK1hIMZ111p1HN:/J6uh+u+ySeC^n/!Sy8#
mk\*=& 4lbIliaFpb4cnlq8McJ!m<ABDT^t&4i9$*$$iG\Wpal%\V!tc6*K^FalwDE14*y$@pMjMjR8KTqMcymY
-AA+&S 000cb1e84ac00110333 Page 331 of binaries1.zip
**pGT: TJ>&d<QptiJ+PyGp$hVEKqY8^GD+WEp>#X456lu/ymtI:jHB5y94Aim\M#Bdbk$BPehBd1P6HmZ6Ip56
&B$WL% jy*D#InPw^jXnYZ9X8bJuZ>C@RYRn6nT*@ImFPtnG?u98?WDEGX^n#1\1CFKH#M4ZqaNjCXPWkuubt^l
1VdXwH p9#!+R$BJe1HEMZiHDyF9aVVyJcu$tqc1$Ki^K8WG5k1HQiu*uSaZ?Xwppd9AIQ\XYqqVZ1/nVwZXiew
qtLiFJ tpAq:ZCpKFW>ikLjL::9qEE4G/9IEt!ZbKJj=II+pQ6V4?:?nTmad@=NJTZ41t+i<$AB>+6WEIIFp\1b
MVBY1L \k+QW&qT+h69!ViqHw^VuSBb8i8<X8Va:A:\qb1h#qbLwjpqBY*V/VE!$J6$?VFt<PSV/aHcKhtH^kbj
/TaL6J tcqI+M$i!&TwN=ypul!b4FX9$LKSc!Z&EH&nXiHTEEWP:^pK&Yb@hFh?dB#R/GZMC5I>haP6IX8CW%FZ
tdHcyR YG/a9A^V1Q9Ve4c*ISpP+yAIQ6QIZ\Sl//>aKk:Hctu:BjVKhlpIqyjYmQe$ul!+w^&^h&<W8^h!!!8>
9>+ZGj k@d?KAKH/8W*+YmW+/McNw%ceTNS=TADu>4+Ri9!aE%h#jt?B:8N5Z/4D9BJ!l8!RuKVT#uyi*VT6>Ha
<JEAJn nyN!VJQNYZ=Rhkcypw<bLTMjMSaSC#?S$H%NE@4C&lalY6w@SEaNRi*H/ln9RlJ4B:b!k+W^@wt5%+w8
FtnRZ: 6RiRyBwuJ!FjYNdQ6wt*EM>Pu#%ylQZ&6Spe@=^Nap4hCHT?WXk?6KbtAZhN*J#yAeipT%<Fjj%HR8q\
Q^$Ti* MdjQ*Si8pd4K<WkKKTNE6/CwdhKalV&IV1ctP*?b9Gj@TqTQiYtdjw%56LF>q58\ZCR=TYy9n98Ew1ZV
:\&A4/ RQHS6%Aj1NBb\6mbln:%nl9h/5eQ/J<mLWG#HhmL6FTYI?R$Xq>Q9*NkB6wYKyX@!T4SIm\6uX$+X5>N
JyeXd^ F*VSb/TX$^8I9*CEKu\GAG=VYY:qB$cuPJF1d>K5!#Li1WhJw8I#DRcJT<KSaG#tI#<MmY+cp=X!Pley
?k/JDl %%e&q>iF+?:*Db^pyNPAm4Ri6GL:JXANyPHcnPSkE*>VtE8TDmF1wH\@#XGJIR$5i/G1jIlp4/eKAZ$V
YuPpnN lp5$E%tC>d%&@ZR=5RBYMwZdl$^jIK!HL^Z44bYPkyZYe8?dcPp*pbN%RlFXI%QA$yw&^A5q45iZTZ!C
MuREPW 6!>hYXjE<MQ::RAMdqR\B>LEdRn#6>k$9&IGeM#c$66pc>IyeD9tRcwbaIYn?4^X+nKE#K8$4NaVN1?!
c5Z=@5 5NYnLHSyn8\jI\$:\TpMFH<NJ<Khlahn/PNicu/=mmSppbQ+CHYFJ:cJCcElMw&=$:CGyYP<hyiD8Y6Y
Bj6p^F E#+qpuneZWXlT#QMiHkIh9+P>lpRH?Vhuq?>nNYkVB9h9$$CT1!XFTy18bqF<mYn8uLye5#RZXi4%$ln
9+58@$ MlRhMna6Wn<8NEGydeHuRk/5ce=#MR6P1>^SB4pQV@HiL#lSIHbdAdj8wMlt8M1J</S%8FT&LX&Jpb$A
Lyu/5j blMCHcq5<6H+=q6J>l&Dnt^q/@RC:NSuWu99Y*Rjtc!G#HAt#S5it8qQ6>cP8b<8nRY/*$Eu8bAq##nD
nPR$SW h4LIqKnFD6K&b=Nu8M&$\:Ru/$hJb^Z*^lYLaK/ZKnR!lM\XCt8>DqC&ZQkw>GX4NJbqlLjpA%yKcHw*
nPln=F jEJ!lQNX8uKCYZ+m?kQnNS!/$tFjCESTje+J#S4?!/L/a%u%?c6!4n%WFLHeb+58/WAWIZGk1RD>SW?t
<&wb$m XK*DKENel+K49a%Wp4elHXdC\FS6b=A&qmYK!>idn^y^61y9B4%y*w:ICu6Zw#^%HWqQ&qhKdIZM/BMZ
WZMV*l \lInXN<cIy&y?*FPy5TwQK*qKb1L$DCM<p!SnQb9^8JuVjicG8:!b<C\>M:cZWnYW@cJ$@QC@4*J&?tG
Rl\ka6 >yb*AXtHYZD+uj#1C9X+eht5@FcRc/6*1YQHY#NH<^jbH%APPPhT!\+86:DAN:*yhXwMl9LuC&wdMnu/
cqX^j> KyalNa?>eSI%*<Q&*Z!Y1F#EREyXEKyJ?TIiA&XR%tX$>dtFjqNPKNmd*!#n#C!@yT//j!LC9JA<VEAn
^wNJm/ W$kWFWcAbGNhdycQ6AITXHp*9^FptLiHEhc6CBA+Bli+Nk6*W?#tZPRJapQ\IjCP4JAbQEF?NNbtPLI4
tyj*:h B?EMN^Q>:E8iV<C$*Vun&@8t!BljbCpXbBq\TDK588<hh@^9iyDNY=i%p<Ipbwe*NyD/8pFnT+6jKWY<
H9<X>8 tn%en448e9%+PPFpS:elIqAiH&B=bB\XXTdHi1*a<nSmVQdchPP:Q$=e@C!uRGCV>&H&Vp?!*DNkLH!b
ASBqCD :>MB^V^JmNk$P=QmYb@k\Kd!#dj>*tmHn?VNQ<d*w8dTBE:&<t*Kmie&C*ec6w@+wBt+CMFCw$d#Yb#4
d^YyAQ 6q1WCqINX=mK!+5Ti16dmm<wk&B+kDaiS\^>Y<%C<EwCSwH4khjDykF6mCE65BWCm445k#^&\B^ctPN*
y#qw!4 CSwpPca5:^/IY16#di^a#c?Qq@eDM<RXILHwRebTem8mdNtHMwLdq$LLZ%:bP5y*Le*K^jkCLMWHktEH
L#dY!y l<S8I<FA1aRab%T5=1#5T86GeM!8I%9/J&/<AX/tluIc?1@eM/cbZZCyI5$TH:E\a4icIuQDR%W*eip6
+:HBhn ?Wmi%G=n+$j%%iVI%\iFaBd#RiKE1mbtFHHkjYjYHuLc/W81hPlY#CTJQKIFl9bLH+CRyc*t5>6?CZuS
#cabHP cM6wtR6nPVqZXelBd#VSQR!w:\Z/?%JZR^@ZdXX$d:JjVewtiB8\$*/Lb=mdh:jA*k!iLpd^ceqK/5!1
1hSYW+ R\46uNJ&d^FyeKhj%%NW&kY&T4lK1hkL6/VmRl:1hlKCnclpen6H:jVGFckM<y8DC6Xc<^HZ$b&G:@!&
BNC@W< E@JH+&:1li916Y#61b=?uGNj8+?%\K=haCZWlM^:Z#i^QY&N*pVd9e/!VlaKGI#Yn!1jW/dl8L1qRPXW
nkG8Ad c&Q916G%$qj@/FKu$y!+eBkDmakCe46Q$X&@yjZ8PLZj^uqykt/u%Y!hGy5aHpP#cc/hd9l$Mc46AY#E
?C!LHB cXhiTVZ5M\:@&**<tGiA@Skq1#8A4?k%h?K*:94+Mj*<=Lnt4HlX6=cqlF5*%YaYa%9SanlupDIh%nk:
btjppy IQ%bb\%qyD#Y%X#+jSmC&%B@i^dJjAcjS1kQG%TTclD9Bl+^GY\wy9yT/*%K&Hj9em&$ZW/!SuctAi#I
VEceQN jW+^QF*JYBnXp1481iwKyP+9^KY!FCqk5iDt/uPE/yG<jQw\BQkY?>e9YE@Pmp1idkF&#Fk@VSA=KVa/
?i+HM* Cnd/!6uNXu/V&XqqD@@$#*@Hc@qWY==6F15!Tl?^RVN+E9X4t#l/:@S+V1PmD\yehq1Xu%<W!Shii<hA
1j/J/E 46a>tjyQm?nLWEH/Xb15RB!iZi>@!e+W*n&*k\Ib&ZCmjB\iW?VIjqMt*54LWVRBWZ$J:61Q*eQ#DGl*
:4BLl\ +GTKpSdR@WF4HXdMNAW*I/RuK8%*QVbDSbT:5#4R=u#W^FYFI>?:E!\di\bSJ5N\LdQ$ht!8=dXu64>$
\>ST\Y #D*T?:^b4/11=*R#>BRiQaq>6EBtpYcJMI^SE=jeM5@d/uMLC8GKDupGJLcV?9St1Rupd5$Ska@KNyLF
/yC>9l l%?ch/KdRGdBEGcl6NMTL6m1uXC+E:H1q**AJe#Q#:tn/T%Zn\6#wJ\>pbe^8jG&SIAJ8>Nk=l4P<\9W
WShEdD q@C\%5\&5mBp#X/#CdyCM$XK+c8b%yPDB*X*/+eq8mwF>#Fn*/uthwScA/&IVm$KY%6w>a9Gi6Z$&X!+
!6Z>pX b415T?=AktXu%q1ABc1llEX6H/QuQw=MbYnXq=Vt^cm5kH8*ijjnNX!ct4#XjAapJI>$ZKL\Q\18jH&i
JuFXt/ iYE%i&%D^?55!1D%L==AhtyRt%qRIR#!CMECi=8Hh9Q/h<+#PXHdAJt\PcKDMXWkh+pe%WCp*CN:F*9<
4#qHGT ZjCXJ*BbY/^^NP:D?nYI18G4i&h9JPYJ1FZi<$mp%Da%ylX6D?<!aLu9S!d%PI4P<AHV4dXn6EWnJKT$
nL6EG1 VV>HY?IQA\NakNJuAP#RtWK9!q\VRcLa14%4we9/PM5GF8Sthj\5Ym%Lkd<%6\MBn&DPyZyyQ$&+ua#W
JGJF\= Wc/AJNQFh8kb5eNu6<\&!TNGuym:dl14PH4DJCpu*&^Xl#/VY$wnc55XyEFq&!a+&hyLKS&JcZtGp9*e
yJ/Wy1 pWNJnd6pPlISZDcy^G#=P5n4\5+$:Nd^?CSNk:nZ\86t5G/laLka\c*G$jh#jAAmmPVWLSH%>yA5QTw!
N@MA&e a@F!#>Wm$ZLnEFNC!8Mqj&8Mw8ZD*E&1c/w<c1INcyFS!+ht^^^XLWTY:+RQ+y%GSkR5DHPL<uCJX&Qh
b^6w8e 6ZS+RiRKBadknqwPb%@18h?#TXiY>VJwaRqBXjWZJpT1j#Pl6y&GNB=$Jp/^?G&>F/ldA>+%?HAmpJ?M
RIlY5C M$#F+RTE^VdFjTd=8m>JY6DWCM^&@qK9Y@8m$4/IDN$hI/891/qQyG15WyB@@CZlA/>4lai!l=?LQ58>
6Vp9$p 1Tbbce>HBkVNJhhdYV#FJH4!6u8%Jy4kFJL/K/WKZnIj:RRVS*M+/ki^V#1<YJaAHma5iSc/61>#\q/G
4etn/I 5YPN<:l5AMhe+yAXJPXAJQLqtAQBY%qY$Vc#l99T$cpkP\*6P56u\J6%muqV>J*A<+FhX+tuPwY/F=pl
FW16pw 58iX^HV:kn*t>5CA:QL1&&%nd+T*$Z$NheFA5SDMITqit^#D&FdibIHF&aZ!:Yd*kuc#hqP?P#Fy!j6<
^6=+FT 6>8+8GD+Ck!yPXG1H68Hn@GL:tpJ=DV4udZq^Vk1%B:CM#!nwmuq94M#t<Z:diCj6c%!h@Ld$qtI*cWw
:H9p%< !JTIm/>8SA#tAEeTBjdW?$>9WtpeHN^l9tK>1uQb&#GZKqYX^MCZycct$kJd%6kNYmZPiFTZ1mybVWDF
WCSlK< TH9I4h9=V%cBj>KAtijp<pqC>55^:wyn1yW+plVY4Dy\b:=<\F^AG^ZdJdK/nte9LSSVc>d&phA8uLnt
dF5<yZ ^&qY>/&cCt=^51#iI^aXT:4kjPMT6JG@R&4pDp9B?V=Gnh1iqtc/Ki!Li>DJy4\RGpK45@%wHhCVj=Ym
Bt\P=n M9bnH9+RuAIq>HjScK\QJ@MTZ?tkVwWlA/ewR>Cj>yMh6S*E$jt*b#\!?Vqpa1u4HJ1#ZeWFTn599@dt
#lkmKS MYHp#mRL4mX*q<i==*?M^PVwIa&wTYXH$bh%6$hRW#\QR\49hP=Tyt<n:4hJF#%LhEti&bZkEd=RhTub
j</n58 GTp/i5\K*=CC9PRcn\d&pbKTTBJ$J^BTe%FBlJBiiI&++6WK8ySy4\=lLMc=MPiK>qQ*G%qT&b<Zha@w
mNwK/a &a#PXK<au9!tQ4:MRBA:c?h:q#J=/wpF$/u5Xwq^LBJ=<ZcTNyw1#F:d!1/*6d<48Ic8SY@jth?MYWFX
uJY$VE Sw*Y$yG!+Fq?/5QL6#8Y>/Sn9m9aaIeBmCFRcd6iHcl185G\Q?b@9hE?X9dt*nL#H%%A1ca*#uMMKe6q
n$K9l8 NNCPbyA*JpDpiX@!>Wu8nV!dNI9yaBT/^yK?+Nd&KAb+PLb#ph/dVbd9*C+DjSTyyARhKlERLk:Ri6bD
W59RmW DuIPHuplpAT%E?C/DCulH?9h8yE^%MIpCIYEH+R>Gw8^%a?t$/=q>We@i6u5ct\L+uj=M4#Y!\b$awm4
=X?^66 bBh?VjSan\T?8/Mu%a=Y#C6jihS+bA\$*aL6hcNkNV?R9Q%p%@:K>GeW?/hhbPDekwJ=L8/:AD6FZmFX
!^NZDK :a*h?5<j8NZT448ql//LV#Gy18nya4BHYP^ya?8<W#*i+^Aqj<55<Dm?NjkE6!ypA$Ecy++%SyPEim@N
-A/=Ic 000d242210900110333 Page 332 of binaries1.zip
AtWqLd EZ!I$F<tEy$TqQGS8N*WyhT!aWkXRByT854XCBpDYcYF!8mTh9BSqH@B#5a$yh>9$j@M\@?D1#$GNHkm
c@>#:W i5t?L%u>A5Lc@QE%nb6$6mSu6WN%lC<!eZSDlSlFunNWJhNhhu+a1=XW5$JWHS:k8+%RBFIkQ^=Wwhcl
9S?Ku1 k!\##D^AWSAwn:L:EB?QmDIIIjS^i!Q11lJH<6=Vpmlawh:pVW#8J%>X?JD#!B#?p?yBd=iTI:!q8$lm
LZLl5L <@X=RuHk+EbG+lQY&^la:IdF\MK4e&+FV^n9SnRh&ZikPLpt5BWn+cH+G>!qwBmp/<51=%AwDyY?8HSC
J5JbIJ c?cV>uGmlE&JtlNp9m=SiWXV*#Yw?&XFZ#P>e:Enh4DVKAN%h:RFwT#=#qLC@>aViD@Y9A@$/WI/VD6p
&k6Y5I i?R%iRd+ET!\#>5McMa@Rj9w4Gp&+y9K*^I>PupbjWt<X9:>N%/!**+#Y*6<!DwV96>GG1q^u?buGZb=
&m!elI N/E8:dc!T6wi%^6u5$>ZlSV?uY?lL?6FhSjdZZH=\L<ijD%&Hi:#:iC*Y&I?A$=u@*4QCet@*uQ@pPIB
I5k/#\ ?cpJ>YLn\*4aq*YSew$ScuScnkwXV<Pk4<8\^qtnTmqtXtX8m189NbBAXTZ$JAijJ4TiJ9qIQJ964nX&
+*i#cj GmX*tc4tFIb9l8QKhB<Mp\y\R&bjVZpdI^p&S?aK$<cG\pa4$ICCKh8#u\<<t1%e@h/9NP@Mt6?Ha16<
XbGjnK /BpA#q>yX/:>DPn+:dp%Gk<Qmq:/%h^ic?5l>iP=h?@HP4:j@RAQpH/WpBBZI!qYRnwaiPH++Eu6M+CK
H<iLh& Ihquq>nu*4>=+m?K>M>WDwhM1@yLq@pW=>XZ\YXAP\4><Fqc<hIniFMFB5^D9dT\EQbh#MmTu8%X^QGu
D$qP:> Wh/X6<Clc!6D&uMl:Fpm<&q^RnGJEwS#=RdH^dydVIP1uVdbQHFHZXR%&u^&CJBJb+db/$&&qWu\JhGb
a<lY#F Mb9>9hR+pXK?GuAkFF$Zb4mCJYiJ:X\F&&ERkZ4<\j!pn96dlc!DZT*KIQPpKMZp#ei6F>M<4!61P@Lp
^SMy@A FVS^/84!TE6c9lESaS\M6K81e&\IQwmb?8q$ByPN&9#8J5jCqiu^dDlc6K+NQb846\B:SX<I#FpFAwT$
5Ald8G $meD+TIcDMPhS\pM$pS6h@PiXK/T&+bew1m&\=HK^j\pQ+6K$9mS%QjM/Ka$+KW1>@&TTK>Xuk:Z\jcZ
=kkP/m RiYL%4m%mQe<k9QA!%>$Qmw/NIqZM:1qhc4:i8YL=XyY+HBP&bc$Zj=P&lb1hepjqn><h*lAj<#M4i>p
a\wmh@ V/ZQQm88t:yGV*T4akdQ$XRX1tY<jTI*HLEEtjEEb!Fk8yql<NpY/dmWW=n$:F8YcZ5G^KL?yaCb\F%a
D%<m#Y *TQPP@*dLwcHtbR>QmN<==G%P=TZp!SuA1b9j+ZbVjIbF@mI/e$<MW4@mCnBSW1bpAX?i^L=edcDADY1
E<I<Du Y#i!>A#wl@HbVa?Xl#nCbWqXnaw8jyuCNm#kJ%iwknck4#XBZ>NY!Y*XHDj+QE>9jSY<^D+5%H9<T*5d
YZkX@F RYp=B:=!nje&$*pMuYM&>tPK!u$eBZ#$chMbX9W\4S=pH#Nh9aC*u6L:HI*NnMyVK?Zi!X!lLdPuG??^
9D>TcQ SJKpw#Y9S81D9$paam/\=w=nyDnIuhFyFibu+it!mFmqCVwX46:DH6CL66WQ^:uN4dbJlG/M=+Yh>q/B
^NdBGh &&wY:uuWXA#M%?*QC=Z6yaXdFi4Zu+Q5>jjZhX*5qXbS#NY%ChAYa5?PYVG6S+KH$pRH6yMqqBEp>#SR
VbtVc& 5+nj>>Sc#HkINQ5qJch:<Wq&pbc4Ipp>/GljG>HqDmLWP=e%p+BEHCK$#hw>V8Y1dnuwPh?&M<VkJI&L
lZCd&J BI4w/e>/GiF!?kaJ9mJlD?/hk&tbjcAHYYP6TCmDTFh9Re!l/T\khY/Iad4h<Vk^u$QMe/nuZ5hZF=<q
XJ/<wX h>PZu:I::w!A!YPWEie4TImS>*A?>pZ$*?Y:N#%>CEu?Ej<DNi4<DIk!QidjAu>=i+dbh^FZ@<TA1kiD
@&wj+& q!9Hq=<BHHiGJSwnXh+^>cuL1e5i*1%&PC#AlYlGtkZ81D@d%h/@N&$:H4E/%=AlVH?S:+?YL@INJuww
KREewG SnkD8hcacyP=!4K+%RRLE<P=ZT:NV9dGXR^QPSy6c:/J>eRqIX\?>qlq<EV6CV56LnjSpyFH+<mm?99*
wuZRL! hdH/T+hajD8/dtk*Tb\>$/6ln=\&&KM4d*+^?Adh6%hYPJup5>l?4RQw14q#EwI*RW@Eu+:+pAE>8>>D
?W&INJ hqBYSC%HHHiJH*STPF@DCkTEuaQb9@68>Ddym>WHE\TkB=E@C&Mm@MG+6y@WIN@\PRa%F*=1*en$Wi5I
b5PtXj ^ki^J8nb4Jq4HYbHE>ZA%Gy<j#?*a9$mnKdcT=%JYX9/hWXTS?Jl:GCIQFH>YpASq9y6<KXctnJhBe<T
CXcZJm PSL?FTR>au5<mJ=MPewhNQ8/Y/a9i/MMipQ11G8NPH+*DELQEMc4jH4*M\bc^\eyTdCNAl=8I41PXH@?
V5y<R! QChd%W!q%nHaE1b:ZWJikMjDjYb@p6<6n8mGWG8H9j1^\#PAIj6P8RHtS>BGauIcwb:8JM?c<i+H8*1+
/8YqYt 8+KbVHa5Gya9?W=TFy*LQWN6nB%p!=b9j4MW^D%*IV<mnqchR>mHkBV%j9h#8!/<*lP:B4<R*P$w/!!i
pqM+W! $&M+GBn!M9C!F\A/=bS#\/LI+&FPHp+6a=PRFV^ilw=RLLuBRdA?A=KDie\yAYi>4=GAFT?&kn6e5Ql>
RRi^:h 4V^^B<cP^JbC%WAYa9qcHh<W\qt1bcn45e&%<+e6?H:VSyjI>wqP!deCA4b4RXkDh46K5YpqJK/lbnHq
9n:$8/ +6GetJ8eSEKTBHBm=Y%5WF:uJJB6%!c1$4=Zkk:DJ4Ttt\@dWZHS@5pE\cpQLZ:XNjQ$tChWilLlGE#e
aXGulF LaqpbIk+Mmdu6/KWKBb4!Vwt>&>TtwYMPp1VHGk>l\PFpc?i?HlT<u%uy!5WhhBMLT4wS1VhHecJiA1\
4i?$5N puFFJK/i$MF=XjBV$/&&*16LZ?JNcaiuLT:Y/hk1#te#ccGmYEc<JdC!4BBj!8c6n>K\tedJ9>dn1m4&
Vu5YX1 1QEV\8Shn8V<8Z$>>!IM>V5#XtiLE>eYa%>:YCY&6F$WZH<VltlY:daYC!HPSEGkS!?RmZaqTe!w^yN1
yK/c6M +L*iw&6jJeu<X%#Q8CIw%jnDn<9e>wlcjFDj9^8JI/<8bWJX&6CQ/E1uXLLCqjb@yJaE+Tu6kmI=P#=u
LA6Ghj Pq!PY4P!dKt?BH8/wFuZSX$H%@jq=uEPCleeCQhl5uTy@I/y8/hu$BTwhdL>lWkE!R!dC6ZDW<c*w$9F
qNd+DH 1*N9XX:L+NCGSDP1X@A/F8*i54n$BN^AitJtPjuIp/hWj1JT6#?&ewXtkD!:@Q*eJKKEB6qAJRlNm!wj
MtPmnC dJYWil9anNTC$pc?q+\5tkMCZ9nH#Z$mk%KAu1EW^lq4qVWKaywQSEXGm?:5MtnE>\wXG#RF4>^mTyWn
wJH6E% K?XJI?V>qk5iuuwIJka\/p!bkanKI#B&Qap8T$@iG>cc1BMP$C@DbEu=F+1V4<MpaLGnZ>Qw\/Q>JX4y
$!Mh>a l=ue?ttuk*Z@!TJb5Z&YLKq4!<GbLGW\juB&*Tk<FmZkDlayANa8/<Y!iGG@/D8m>?Z?YPw4ML\5GEY>
$a4*$@ /!mDDFy&/#@a4?Yih*BGLiX&:1MG*J1DYwCujlmk:4YwDXP8@A:H6uVp&k?hYiN>%:8!eM\D:86KeH/&
nT6lRa t&aNTZmVcaV=#Y<8k^+jd=qq?uK#6RShmlN+CZPV+u?PXLjTnmc4^F&C8>kbL+qdm/MGA!/4^\>C&8wC
KDFQ#I 8Fq:5bYZ*PMD#A+&PdZIW8XR@NILNLjmMM!?CqZk%n#GCnmRYFX/cYKw&j?k9<HwhKC*w:lpWwl&hM?a
PhFJEm #>!SG1=*lZ&nk!^ydDK%<X69KTpyjKp#a@qAH%QWVIRFHL:E11TA9tLWkuSyAncFn!t?EW:jbbRE9Pp4
ZG:QG6 hM>pE=P1G?uwhwdmtHnK\#T15EQ^KE6WQawLeNP6>Jw\uCM>#C9/^t/NnDaeK/q#\1cmC$HE8cQ4/>W/
uHAbE? /kS+/<M$/Kb^VIB%LwyEJYaKEpK>%:a5&?@T>Z<YGjjC@+1=Lc8##?M&Bi^yWpYlY58q@qNqRwI=&G^Q
VD:S^d @K!hN@9=LE4Wjnw4!FMjcj5C^5=GcnDYnS?4/l8kt*C@>=qLBVbjtX+H%nLpNtLIm&dNW?>!PSbn<AhB
^aFM%5 ^e6j/5Q$cmZ\jHkG&PNLdldEQMmW=1eT:V><:VSM*Pc1C%Sdeyc+SXT=%Ylm6Spi11Z9DMQkj6Bq4H!F
pV:LGC ^JaT#ycD=<mDHCm85GPGAyVTKH$9hQLKdy6k%B=4#\iIIEbX/EB#H#L&>lW%hY@wa>jP><*Y@iEAFe<d
e/i5#^ %99pqPSJG4iAke:S<ntp96AaH=jGp5d:lP\KB>Ibu1FDuqQ9>E#TmECKcMw6q\yi@1Za=nk8=#X4b!/:
B9GWDn FC4wq4a\6aDPjkHwN%hVMt8t/5Eq^N<jTB?1bee!c!/pdG!:^ecDZw9XCYKB\6/@ecAaYNn<#t*pwP$i
==XwyT 1+JDu$PjDVJd^w/hWB56k/9GdptF<XW1VB&^>welPV#T*=IpytwWIRkT4CD9haG\R$Bttct*aF6Qhe1y
4ik\d& LR>XiA/ny=byyN4t:mY1lhI:W:JY/jQDm/BjJ84Fwpnun=+mFb^mT$lywJ%TZE!nPQu\!c?*ad+9&$<$
cIRJ\e +$NM5mHRD*bmuFWhFa1$*@^:YBmmMFdTk1cG*m5n%MK*+6iT%NMCdlWc14+bR%Ch<QA*jAd*db6L\?j!
PLI$/< ^J!N:tbji^$jb+Xcb^uq/&d=pd@Lnt!\#BE*J%bEWNHGq4GZ^pn9NS!KpF=GqTIyhk^8iL4!GY*k6LSE
HASF!k 1d$5C6Tk/RXwA:SEcdERtlnJS&Fkwc>+:R+GT!pRRiF<b=Li^NBeJkEy6ImMPyBiXmS%T\\j<RPuklX%
G&1MX\ aK9k<L$nV&BCakIZT6?lFl$jSqVm*1yD:h:Tb*Mb4jnawh/TeXHXmF=\A?TXq&ZlhK/5Hcbt=61p&cL!
9hYw>a bEpEdZk\MAWEl&RtY!#Qp!VQ8SKMm/>/WtClydD:Nba$Hd!L/Ybj@BG@w6T^w9+Tl+<Xiw^&QqDC%Q\k
?j8^K& X/#EKD5VL:SCP=L/=#L^akCbS1V/Y>&en^wa8>hqR^I*HCTC9MjAK&Z4c4#*Tbp:ZyB5qbluqN^FF=M$
P^nbF& i+QKAEtKRen\P5C%1^>BM:j&jmVWXNVRut+%S=tKbu>I8XpXyLVIYL<&SM6C1::kRPa?jFYdb+!$iqBY
KM\M&! Fh/&6NShKZ&Ryimkd$%?Nn<6di$%+XA9yWq8E^+W>thBy5tbSC86G&^=y=%Xt=!w%Y9I6pclm^H$$e+l
Iu!QW@ NTEm5=&tdF6iQ1N/8Q%W!D!LN*6\6aDNR#!DJ1wlwYBd%Ku$nQHh4FwbJT<w>cakK\6YJeNW#LBA9NT&
N=+D/^ J4@<?$<QBl%S#\A=#nyi@VqW<w@WWbDMPN5n=!VmR>=eF$48wJJ4qVDSpm%lm=*J#w@j^$GDI6$Gyi9$
q%A!t8 Y%\5ajC19>Sq5&LnZ>taBKNan8a5Cc8yG+GXqy+@4lil\4tyHAj@F4P/a:1qK$%CcXV\HmSaWY?L<I9m
^9/Tu> Bi8*bNdqCmZyA4dL4u$iKyLBtYGyn$%y5/y=mPRbH6juQ#\M?tXc816>1JyNacKJ?AZ$i/11:&&JRLaq
VCIyVj qn%ybTp$6RY6J%+FCbGT:?w*WF#uduwSt=hK&P*8mWI!$H<w8YiAcQ*aY@+tB9myCm5X6A=A6d#k/4Fk
$pk8<D q\uylcX>*:d68tBq^:K*TRXiSaG19S:mEb5JY?^&wZ5AA4BVqqYc*6&9mIC6@MmMR?KiH+BdkS+W1lPH
-AC%Gb 000aa7bec9400110333 Page 333 of binaries1.zip
5M5GWH mDYRh$lEk5W?bD>bQwE9VGjGQMAD9%9SmE:6it5q1CP^%>LeIPHjn\&8/VNN#yeHaV<D!jSAL@pK\@Ad
%aDN*L 9Kc#>ti%E?/TSE\nZubNp@mnRVKqk\ep8lKFb\C%MeZF/tEh*i5C\n#?W8!lAZ<SFFWWE\LD?VLqNa<b
^lbCiY B#a6*mM5PkeH6?qwQW$%N94b!MF%>A8BjJD&ZkQ#l#b9pkdtk+8LKAc=4\adR*L\11pJl%LuZ@\?#Seq
\$cB@S XZ8y4hLhJY5eFM54?GdCi4yXRL!::49+LbD+D^d@D+5kj/Gm1k8<EI5>VaIT81KqtCT8cVH%lNHt5T1X
QGtWDE =J*#%NhIXSBc<p$n$qyttHapyZTykK9>D6&Q*!dhk#T5m$i8E/MW:Y$?JDFwJF^qS6P?CRFyCTda^yP\
YhWEdN cDiLpkP>M^Hdl6>JLS9tXGp5p9K1mRJ\i<XYX!LN&hSd>ISVhWc&IZ<MapLyX:G\QIB:4ZmBAc:eXXdN
n!FMNp MQXp/8h6=hEwPSK:&<@%hI?=KpANqa>Q!iY!$6B*</R:9>q^4iY6Dp9&DHCMEN\=eFAy>&^YSeh95X99
9X5Q^8 RCqjMt91VZ6*Dp&y1qI:mBWZ1F1t$Flw8VJ?4Q5$&F5\=VJ\9#XR+1GpC$tyqPijyJSRdBP4Hm*:jV*q
#TFl:G 1p%theDB!c&GFDk<uCNlnBjwX$SjJ8K>Pme@%KlqY$5bw:%&V#6BR#IZCXb69l\6H\kTHT!@@F*dcHLJ
y/B+Fq Ty4TuRE6%KQt@bCRW=^R1+bKJn&!amBH$N4SS5Q9Rh%mB%StDbuabI\nyLc^w?!Ww>D1BAebF@ndXXTY
#IPbne Z*Su/?HK!pw@4?TYc6%Q<FMJq8p\T=RJ!:dKi*@?#WDR%yP#YSwLc?H9>XKQFGAyebb9FG!1<4AY6e?W
Ku+nVW ySpN?kIShh/P+cPES1QY*lV4+$bFw5aRjB#t^R1/LDi96Lk5!EG\^q=^\Gn4KCB&yj5MtMdJ@KS5<^F1
#@@BA\ l9ZT#m%ykR=?l8RiqiiWA4j^bA69#k<=KKIVVRFBXk:ZM8pde@%HZ&=mbl\q#p^R!#wqLTAM+Kd:>t4M
SCTL*9 J<BH1#ZKNhDMBRDEVF/IMuh9JPa+E>NNeID$S?Y!dd\&mhRVYCii$C/S=k/$9?ljGeCNw?V!mc>uMm!\
5QFWCW SH6bD=V44In$JWh4yQImepX+yIq&BIXWm1yQI:IE=nS#tC!un<dJ!tVRTWR\PE4HaTkQhbeKQ<ZL>u/&
:hPk1< $EyRy?Ph?#/a/&/mwVEwZ6n4aiARK>dydE1wZ8RJ#aK9tNNw%YatH$TQyhm$G!X%dtR=ZI?^tHkEk%El
%:AIkZ Z&FkbiZ<Ql>+:/L1i6mJ%5p1YRIuIP@h%Q=:PAZ?9M<P&eZyR/@<M$DlLij#*J:4N!/*bN*c=6u%th&+
*9akA< $#mekpnewFZq8NBTBJk18eYKy?4Bt<N<>&A=$RlWpYVMy%m!D!qT:EaemZDhcXE>pLyYp$MFjj6Y><+i
B$LZq% =e:$W#wmSI/Y?TlEZ4+<LT:+%ZV%^/ZTcEP:beb+!pqM4C9YJyEtSkZLYYyS+d&K://:*6=ZBH=PNL4p
4QCY*$ #aein$TJ&5Yk#Ma\Ie/9q?@:bDhn&/S!GYw>Jb>Gl/p9K>^*ZWe#HD/KBYT!6cbyH=tE^hPZt/ZD?GLS
ITta5= &tWB?!pJlZiVP*IMJ<QMXke#yFRYi8W$ZN#HNlLbnqWVi!G/8HADJ=LMAuy:?y5Rqk>TM!Y>#jH$VHTc
DJaa84 DW=FI5bWyeIABR\ue8ik>1b8&amhJ^bmZ1GwHa@h4lYucjI$>VNAM=JhIGT#nE!<PDa56wp$N4Rl#=wM
8@nZM: KL1d>yyu1wt*G%pw4qh=dmp*@AVCI>/@uHYX@p98/Tkde:dEqGBVWP8e?aZnNqK@n<uCX*?j*uchb$Bb
!8>W<q Z@Inch<#kHZ*GaB/=@SWlcq@Fa@%5JD&IL$#eh@/M8HK/F@1&b$#JQMjuJ5?A!TbjMdeP@=q1F9mRkwL
y*FLc4 #HGSH=*nPA=y=BT=hwyqSKj9%6bBpYi\P@YE*MX<RdH8^C+eW1p8ecpY&eWw4wCqLcpFl/jK<q1:#@Q<
?MNIJp 5j/tQ4*Q*PdIW=#SM!D%:JQGjN%!p=E8?!md&um6&MW#IL<d4B>je!G=6<h\8Wy+AWd9LGXL=SI@#F/K
uCpn8Y <bFa+?Q>RFq9I/QF9mj4+XIVu/^WH/GXqc=*u%I6WG1ltHTHFpKeu1Z1hQXFbu9A&l:$%X8qjbk?h:EM
GdlBFS QpWEK&m/^c&BG<@8hIiac>ky9ByAaJY%E&8!M4a4?%\nNtw1YE#ZbqtuQE^ipuMeiH/AjBcl/=+5q>=h
6%+9$E !?YVV=&Whwk!AiJ$WE$Tl5GmH+AL8!u&6Ha\lH1aJNkytyIlp?RK8:En9uPGKyGhw+>T*bj$VTdDh4Nq
\Q6iHk wV#YqGVc$P8kiIM\WXI5X5KtYK4tP<kCDp?1W^$=A>9!$eTl&quk?lT+RtpneRG?JjZ1N@K$$J1PGcJt
b6<an% 1@A5bm&y>6acYqqZdA>deRn$D=Ch#6VmRbBS54^=DheQc!Ct+VQN\p=wbZHy&KjEaYFHdnjkaT?4Y<8*
eT/$14 bJ8K/bXDX!Zwk?L?Ziw#<DQq<>SELhl9l?E?wb:NL/ytPMP>bQmV%hkV&eZZS#*cnu%!l451>69ppc^4
JQEY%5 6=1Z6=DT5h8/>k@9/9JjSy:F1<@XFe*Z\X&%N%y^uJly$keWG/uhF*VtTa/E<CPj49E@L!RhwGcXH%V*
NVT*V& PKFn<i8K/!6&Q^Ab$JyLpCLuG&DYwa=PD=XSSndX>E:uyc!1KPR=b9Q$!T*:me5RtJ^4q@66QqGqT8J$
=FnD/8 ZYPGIjBldB<LMM4QH#$DhkwJ:4C#F6n@D#\Gp*=4#qASQY>WBCQ1JXIkwi>nniB5qn/!d<uaT$1p+qEt
W$yLtC wpKW&A+qh96EPM5:EATlRb>IXFpiMeX%Wh:yyMkPuEN%aVwYdum^pPI5al<%I^c$IwDDD$pC?JTDCMb$
QP@LTb c6<6&c1CX56C/:1%+X\ctmMqkFBdZHqka!Zj4Yc?hB!pn>tSyEacKt?K<:hl<KmHRu$LWMna+$6u9%@N
YKGXFT i1n4iRcRwN*9@6*^lpR1Fb%NG?heIquVNTy*aMn5CAP1QM5!Na%:\pYcq4lbHPjLiwc8y^M4aA@kCdbh
JM:%&E HKInnWXqt<8q^1Y\HJTXEW&Jp=uDG!J+W\ABuQ:!NTFZ%wmQ6CljyA&$Z!Z4qEbQi@Lw*RI<dZ:WF?Jp
h$@b!! 4kDqbyK6c*V4+yLX=SI><bZ%4I4Q#+ASGj+LJ9=K8*@nGFL:p&C^yHbK+*6KL=HC<i9VW#@9^njQAD4G
<#E^/K b<Bk:%N#?!?hNAZq<WA+8+NQyjRhhR:m8@qjc*4WY&R>V&WePIwn>JadMW6e6A#kRt#*Puwktwy@Xy=h
=6/@/u y*t*@G4^WbyNE88d!RPbllNLHp*^&iKG/pJK$4KPLNbBdGMJ1hX%ykF^MQm$jQCd=R*<^&1%^lLyA96a
EB<4lZ G?Hq/n\yhGac>Y\=^a9qSpJ=!/5?==LKN*/:t$im6H1%4/kM=iDItpTy4:+T4Vc:eGT$>iheL?c%NYm5
\aC4E+ y\#lBk1j6aAR#$YHZh!6L#jL6n1&5kX6VWYM5TMTpl4d!w++QjWT#IYK9au1tj>$6dVS1C<JAE5DlH@9
8F^qT: B&9CIIYH!q+dKj:\XDeXT8\1Z*aQTREd&bPG?cdCa6K=5*FyhXS>BN#Xn%L%N5md%k!PAyK1p%G@SkBi
AARS+: =XR9R<\>ZAqZLP8/PItJX=mYQmi<>EE8d%N8Xhd%Y>?X>QceViRE85u@\>=d^<Y^dG9Dk^MajHB*>$FD
DHEHNR k48:8:5VILm:p^CI+P+PCi+c*BQeZWQRn^#hb?@pZ5:h:**%t#@tN>*VV*h%>XP4c6Z1Yk>dpCRtLtdT
ZJaGnd <XMGQ</FjP?n=&W9je$Py6\8^n4>5KJu%a\XNJLXZha?Km<ZqLK4VN1SnI\4qNiEjS*5A:FI1a=Q8y&%
WuLLwy a+ju?#AYDcCjVGWX/<8/tyhy6qt@5CXkGlYm+@e$PS!YmmDJG$<kq8NjI*aa&8/=CV#AdiK?B<S=h*Dq
A$@/CK Eb?k%J8h4h+JjkN?ji9d?*\=dV#&P>\C?\>=M5h:AMq%mQ&@lj99ASuRu?pZd%6*Ku#luJm@*cl@<FZi
cnE^TD :XVP>%A5cpbPSPjR>:kXtKXjRuJ=AX?@kk8!\NReHn*JW8EmuA+Y^XH&8T\?cdMH9YaZkSRDXuJa?WBe
iiLVm4 %Mb<lQAjX^9jXEW/<p^GTMTKTwZ$Ga\Q9Ka?iI:VXK^YQp?lFqe+#/GJTd^MJ1RVj@TCWWjC1nb1pDkl
qcmePP JVdZY<^RLD&VticG64\H%?Y/D>wtZya5RAld#TCd>muw\ch!PtR1KXpq%w1ycCBLbpKCeFakj\cbGN:n
ySX=GX c^ACDqjFEnJY\1FbT!?ZL*<KJVh9NHK4yukiSmw<tGCmSChBkjhBQy<d?iCd=H9%m1dIN:H:^j+S>y*H
=pqm&/ c<a4p@tZL=i1jM$!JF$Ap/?@bjtA1D:AYWW=>ht@\KeSjeXj8cPXYa$pB5MH*@ymGp<Gpl=@Z6XmITPG
9G6u/# LHkX1BZtFydQh@X!9e5^W\8Z$y>^mcuRJB=ZPeG@#&wAb\*E+X*l:91Wb^KQp@lV8wJiTF+/Q>#wcXh8
Ic$n5p je^Zewa\>\CILHT4Vy4$J*y=1LJKR**/=RMK@Z5KEi+lWWc9Z6h?K!@yKpjBB%l@hqVAC%$/I5hi9\hk
L<KSB? @pX\jPlNk&?Z:>E>+NVMV9>a@+d@b9dD@eV:l!FR^D%k?S/\MdnR56J!/j8>mw9=58!P?M=tcPCP@l+R
D#^@\a ik>Ia*j/*@<wCB@j5i1Y\L9ucZc/91Pq@H&j:!h^N#=\c#M%PK?9t9IqIKbHk6uEY9DGXm@ce4?Tp:i5
THGbkR NlGmQ^QTSh>^mZAGPqh%Y@Kb!M^VE?+5N!4uEqk>h$<<e?%4HDq+NXM<Mu\<bLiQK^d#SDWb6:?Sw^$T
YXWuS= Q4>MBkWqJZyF1*#EQ8h=ZEPI?H6wb1m:db$amS^luSE<G%p?B/j9I:QcY1L&YR9TWJ1S?hyVWeSCLJkN
/H#nI@ uq*+CSHw9HHCCAHIa5TuZAMJjqYY/t!$^J?A^#i&Tk6#TbiFuSQKS!C%^XQ=AdiwM69MIj#CIDW%1YPA
JDn:IH Z$&b:MPk!K@um+?6SX$A5:JeI!\8>Gm!?+XDeiGLMnuX#5SV@kG$/ylWm4bemq/Q$uND$5PdAS$M8I&:
5M#<Cc TF8EN6nZDlZytYXk<JWpNiVu:^uyPkMM4*q6J+ywAP&j5hF/w4qVuZSHCNNK:d>4N18nkeqF$5ahCyXV
h\bDmG ^<IR<9H*BiSq6KbQ#RW1%cS%1Xa+4LAWhkSJHE5*T%WY$*kbV5L%=S4kqna?bhJ>VePYPpYTa?m<AZhP
R6LK^M Q^TIJpM5&4FLJVPRlITiPdjN1n6bN+cZj+mjTiT+N%Y$%V*c&F+B@cNniyFLuq%KVe@GSdR4wmBVtuNd
^S=JA& GFYM*\$F%%G4?Cu%AM^kupVD8bZ:\A/y/dy85I>=YR!\>tblbG@%4PT5KEm8?l!#ESDwS4FZCM6+D/BQ
?>!/#$ ?=G#\dduB5@5HyA<qPM:Yd6/l<V8&:<^%4I#@&DyaN@eV$E</4mYhYhL@ZQd?u6AwM#mTWN%&XZ6kt>d
I?ZV=a 49%*uVu%Y&$:@1X^4y6TY@1:pn4mI<8$P*ZPH:pn=tM9\WQ@m$:Q$mF>$!>4cwe9N*yAmSXG<jcNpS=h
uytdS+ V^k@B5Llewn9TyNM88Q/>T5k8TpmGCmSJNEu1pd6mPE>$?8%/9%$Rb\wqMXcZ*^/$>HP*/heS+V8kM5a
VPQXi? H<F>!jLVQGNZJ<q&ciK5JGFQ4l$JQaX#t$9GK+Y:FADy$+jS*:T!$qk%>8u?=P\yEG&^b4:K<qS#?Eb:
1uLXE6 b$GLZ\NV@8CP:1\WW*8L%=y^ei5i\NWcJ?u1*mti8\CKWac:pk4<HA=J>LcR@:YZkkXu=LN4FK:YeTm/
-A/PNE 000511ee48400110333 Page 334 of binaries1.zip
pMV&Ch HaSW$^=&/1tMe>$tY1nyZaLujc6VAY<4uppQ&LqCZ@Y<P<DcE+Q&XSp:=Ab6at&jK!qjj=dj8=5tPt6j
1Qutwe QBy/ujNR9$?HDuM/d<%98*d+*K<e%V@euJ=hZc#8B?p9j!D%uVn=<A*^$>Ah:ku&4V#6QeDl+?Dm@*u:
JNmK+D Q>?QdD/a\j>4:8hj>1ji/XnMmTc9Z*?*H4!am+yGRE#/IQe^m5:=WkPDRjhEM%>n?LRlVcM&S5t&FY6K
?k59/y jcEDy9G5@$1haSH>njZJ>RAnA\Q=LV8=6b1#>me%aiYIqi=LP4K$YMq51tYN$KK46?Ekap^a8JiM#%\F
X@MqAA &ZbGJBum6a9nEKZZNWyi#b%qyR/cPi%wKEnA=@4?ZBL#4=u?j1<^\MuN?Z?8PJXBN^RNtpJQBI+B\q@E
S/=Y*i 1YSbI5TMTRW@51iBeL9ITe9V^&m^w6pdu#FFT6Ckwui^bkm?=unL>@dmGunu<KWalA8Nt?GZuyiF5?>t
<pWy5H FJlH@tb+jHhwdy<bcN=F+^!n@a\&cYma:iIm#Sd&Z5@+^J^LhC!DDqY$CnL>%TeJ8qM8knEVNl=GA+Ha
%^%b8d *F$A1I/lmD5K6<VcC9Wnp>YTIC##p$yPk8#?#A$/FkEXk6#ulhJa6c^LC6ww6L9GNDB5dS*k6SBbASNe
$L$yBw &L*XTq#8#Khti&A:GkF&yGMNlj*8/ECF*YDIn&J+%eQp9G#mHi+H5**\ee:E5BuTEXkT?*=PBNIIL>$Z
^T\L5G R?!pk/mqIAV!RW&^D1B1Slt4Bb!RAmkIPDtMJLIte9@mFS#al^F@Y+GXlW=iIa&IGDc4+TiBZpYbNHy&
8Wy6^V Dwl/BVAMcaeXKkJc8ddpW%ILw&Epa*1u=hwEd!/Kmj%dSm1X+*%=/mEYFt9wp6=&y@a!nHIn@ML6il9e
?%NMdG abbQ:EkXCEuQum5/VKLJh$=+DSMEa:1tw+yZ?Tq\A$586dF:BSNXNwJ4k&q\^@d^XYX1ICIVcFVIB*Yh
<RQ=>\ 8NVKBRbD\PXL*En^#lHkKN8$lMF<J8@&ec%K$Sw:chC%we<ZRaFbH%$8p1uq?YF&ldEF4BDA&Ce=PVaR
%+eG?$ VAp?N%dw1I6y#B!ncQwwD>MZ9pt>yQL=5GCpKXm56him#%\*IT=eR:+pa>qcGDK5lty$TEGYh5N^yPTV
Dk<Xl> 5cEKE*VJahpwJw$Q46bJR&Q9M+a8Xy>Kl!@MaGFKebjWR5tI6WW=&w:J&YG?XneW*cdRubw91q#B^%IP
%J=+:a NnkSw=qEIueRdGBQ!1tn5NZ?T4i/>HJk$1Z14ZC!*<dLd*BX%m1q?<p\BIpiI%\H>MED6kRjyX9uT>Vc
@CIe\L =&\IL1mwDLD<h4le>=tXc*Y=ukqHu4G/YjjDRLmMZBRkAE^F6AhjbbnCRkVnw++5B$kZ5a$@@!LbNT\^
AeBTmn <FX=8G5?#V4iYbX/Yja=$pE>*:t86Ewj9REVDBHjJK>GRWRCQm#/*Nd+aKCeb=mH/#M@BdSACZQpp6F8
SS1hyk 9EAXeXApmaSBPp/LiWJkdAE9dQwkQk$P+I\wwe?#VFie\/EiRSBTS8q#\ZLA=N=SwDHAHmX8lktGIRhJ
d@eG:W ihG4NiQ+ZYhR:bCCl@hTPt<AHMma+JJXC&I&qVM*cuhlF\Fa*8hQc&\DjE%Y#Bq&RQ1iKlwtH6$XqtSW
aEC?%? 9#wHDn*X?dQG$bNCDkw=$$#$di=!S9#&/h1=cAWd+CDFYlp*&TiDq%8&LD!l#:6PGkntAWw!5@8>KYRi
=FpNcZ :?BJpCEtYJ@m+1QwI=c+$DZ5h!1Mp9tL!GmlLa@YcXRZ6pq?mW6+L<5EX%6n+PYa!Dwt%5hD6&lMpKyd
SSbKIu #nJP!BW%MIalIS5^ik8=bAEeWHd\mJ!wFe6BNVEERdMyNpPXJ1hd49hqKk@QkLID%CLjwuI1n>&GFITG
/L$juH =Yc&$n^qwPEal4LK**S+Ah:dt<\PTptkYBqSR!HqCDI%T$6m6$5bJ%&ZMZWL*uAibbTXSTQhijJEyq^R
lj=8a* q@pXmZCHPGbChV!R/tc5K=?IWLQmC=<C**kB6b/n1uNSM9QRXeGTFVK/CDYQGeq5S>#TF/KV++kJS*>C
l+:Yt4 %hcDA8*F*N*56VFNIb6yE5P<Hd*w5iw*=IaL6jy$WqqK#kajViIM<!iYq<5$jLyM+*MTJ$4<tCSTd1I4
$bjFdP icNk&B!4i<hMMM/kNJ%q^e8:i4<A%=V6yCS41CnHq8LZ$QmW!Al:5HaI%V*=C%B4t=uiIFnKZcuuF9na
iMnLac Ne@y&PDY1PTa*XLkWja&1=#nKE@1bkmmC6\TbA4tT8^<\6eK%YLw1/pKjhd+qyhi:?9K9C&dqBS#wyVq
eM?n>H EH%bdFHNBVMtyY$SbKtTcnRFC=R1B6:A/>kKQ#4ILBKVw5Ry9+F#C<tPBH\wa!6J=CaKL5w?>?J1KW++
?DL&&m 4+tb*J5chjI*i8wiXRVJNN?mSd:C$A8JEd#yk&1Z*Z9FNWdY$jDeCqR6W!&HRFn%>KMm5?N1C<5$9Q+L
uKn?<u j5SwHi@tpL5d!AXe&#%6D^:TnmhjI?P5!9^wYqY>Jy@i<G%y!FyqX9cFhK19&l@CW4QZnb%TJQJ+EDRD
##wAIq LdFXC*EtlCwtdCcRI^TqXdKhdCBj!V9BWaX#dRk%IF5J/uau&$A?tciL:1I*G*qYGaLS?WIRwqGC/y&F
Ie>$Re Fp!J=wI^p=cH%:wbluVK&1S5M4dwWJA$jS14k6pISBJYWBRy=l1Vda6B^8DcyAwClD86p8b*ClmY*I%N
\8XBwF &+#lM4muc?idd/dyMhNWQam!MW?1/d#$i%>wwcI%+1I\$1kkTiBBnkBAJ+Ql%:S^94y4d5ZHkuKXc5yw
u*@t9! cNaBu!Si#R@C^9IIM*m8X8pbacj/I<DZ^bp:hlDb/V9&knlBl1JJJ&99:Y%6YYb4cwd<:LWXuQD1T&d%
%D=\?% :b=VKQhL&+yI*TPc!%t?N^me6PLwc#DiBWnRB*16XajT=Yhlj9*akeu$mqXt6uy:\T+X@tnRBj@RSH5y
j5<LM: M4/L=T6n44ZR6yJGSL8mHuYhRY4yP#+AmDLp#IcHZPMhJ>qA#XhwS\<#*tZ@FTF:16&lIb$#%jBR6!Qu
XW<m#X yP>cwncYnyqtNSK#\ta/5J\VBeF\I9/%*=FjPC\*y%IR=hF+Zl41M@h%LH1iT4ZBkVujFBKM%iw5BWnh
\D*T5< \iB?6?^wVG$9jQp!5<u:VVbinhE%McXSS8muYXQG!YG%h>^NXXkPp=RF5kyPi:tj1>/y9A9qK+tR+NM=
DXJh#m QJN^jTY4V9nyN6P6^%Q6a&E\J96V4!>1Jiw/YDLRjqQI$%wnA++qCXi%4#lH8+y^8wSSQS\&lmSy^ZHk
NRu@J! 5acTG>EpK#jYGYyWZ8uYE&S<%!uaNcca#F>keRFyNjp#CeJPcCE&m1ldE!ZaIcMm?e4N#8:SjDF/>6Gt
NGIm$p cCX=DFFt%nb&HLlHTKnNi\YD:L:A:Hb:THS*CF64F9MlK5#1MEET=hZi4qlh>>$X:WLEnpTP@iDXkNq/
D?+GYY j*wDDXqa&YDD=>Il=nDP9Pa/qCmqR+eFW+b:c:1?AiTLATNu??JKlyNc?/C::l$?/4B9AAEjc9VK5tJu
pjmKjC B&XwBcLljKKd#*e%SR=ZDnbZ>ujj?4RCYJSC=jW<Ii$!Rk6F6+AXmJe<^nbKIu/NXuRHXKCDcD@6KFhk
QBJST9 B@jVnjy#1AT6pn$6W$%AXpJHeC>mpJ=wql=!uM@BZut8\hbE<ZPn<k+A<H%uMAW:8TwKIpQ>MRychGQ#
p1l\PJ N8yb$hGc*X1QbAXcEVb!h5J4tyRlc&1MpW>&\>&^>NVI!F1L$qSIFcC+AthMtZHWa#piKSti:4Y6W1H/
8+?Xmd *j#JMQn6w%4Yk9!#Aql\teK^Fb6YaHQ>h9uml5WbC44+RjN^aK1+*AF:5Ib%DQB:VH:pDy%?h5BiX!dT
KF1eKL Ie:8uk6<9niAwd++EN#BYl+//IJk*Q6^H\WK?AG9+4qPLMpYW^?8QVkHMHjmYH>eMeIbm:Bk^thV:HJa
$H^?*i EWp+6GjjE&WJ6WSFN1YR6Rcd!RLdAXkMiM=9i$pP8TF/\pc@E5LadkCl>J^Ywq6SlEDd\JVCCI+eMwpF
p$WKBS aEZi1kPd!Rp$aaNbTpA14+j*?<wkyE<YaEaKJTGWL5B:IpAl5pN8&$/4JEEKGWG#d/i?IkCN4mhH\$%m
TAyFik aE8%\lqqemRk6MBkkEt^apKXWETLu1VkqCLH>ya@?+wXMyVPKiT=$ph1GAjV6YPcp#JGA!5tJ^eG9\TG
ie%t45 qRnSqiEupLB\bMQ\A8u\^ueMT!FnT*4\j9*IZbjA>BlpkZaWM6RuJGHREQhkhqG\5!T+TlbMAmBRXmFR
9D#aK< X8bIqAhZcRE\qAAa?8B^E\JDYe=Ec*A/C^TGM/j!C:CBP^SED*iGLBh:AQGTB:h#PQi+K?i+Q+?#N*iX
tT<T$q I\?GAcl%A<+Qk5e=qH8=G&L<A>kAkFQXC^y9+Hd?!D58AaDajbaS?bT>HkwnBR4Dlml>k!knpt@<<*Qq
WuNdV@ $PjyG<nP9ZD?pZ!u4<Gu5@\ajb\1tN\a?kLLpZ#5CeSutEJkY1F1S1Hq8&iu5BBKjR\Jk>DwpbV\QFRu
DJi1PQ RuB5ni^G5E!t:ZKhME^Jw9VyJlR1^tJRAPWXPTa4GFH$Ll1qAb1EEXkZeVG&enmRyTnan5RwWX^yk/ah
Cb6l8D VRJpKKamT#<SJWcXLEt&KX4>S9SMpl/WJR4#S6VWZl1>kKHu6XTC6nnby8Va4HVCIVWFG:\KJ<^KlLw#
h:b4wJ MwtBJc5#Q89cNB5bLq5m\#MMhuduy?#LLWI%mELJKEIeKELP%k4yAFD4F6\EKhm@GRAS4dR51/S51i\5
%k@JI4 4qR%S=RS4WRc4VRyCXdqR$+YXCdbXuZX=FKXR$=tky6pXuMXB*M<W<FpFuVFIV+ujFbn#ZGPLbn54>DY
ep*+D# wqEV4ZEil*@GIb:$VH\mXi^JND%/Gt&A#K^LIe^EMy%KJd6yAA8$BeYEA^PpL\MWlLkLD%Qqb<*#n@RA
n>qQS% R^%IPB&qbt4XAWtuA8%kPP$8N=dpE?1Ve#*ZG4&cDH*$L%4lWT^\Hh1kM4*pWV*$W=&EBN4#R!&lbhq^
M9YQj1 GJdpHLu1LXquZNbYS#aMT9q^bkX&dklqQtmIn!aZm1ce11b8t1c%81aZl8y1y8y1KkCIE=Ccw#tu1#pJ
DBL*tk lFuGHVGu9\Xu5AYE1Ht6M8i4AGlBXHk@WR8*TQPyBHl@NA5*i+5ySW55j$5BWT8%aM8LYQPLA58yEyNV
kT<kub T$8%htITAYm5J19qi&8%Dq9Pcb9EBGLPd9^ce:8LZVP5e*8*:/du4*Y?AZ+lGMD^*/T4#T#G?mP>Qie9
l&*D<k SddbTQ/YjjujFlHk+Q\9y8du=9^ncu=8nu<9NV<*/>?qCQ+8V5DN@46p@h#ku!d4=@lJHuEP#5it&?jk
ETKBX= jkV/q/u?PZkikid<qT\uJ<6n$L?T4?XpjRTck@5Z&he=&j+Wt9$^cI=jbF@uBQ<yNMen$GCPZ>Wc=&QR
Wtn/it 9^I#=Z\M%>l=jmG9\Qpa44F#@?4cn?Ec?/?pHdki\#Z&Z>W=%&P+^5:?1&5@lt5@p6d@HQ$a44H^@KJ>
eQVFie e#&Gc#>WFH/P=9lV/Mh\:hi!Eq!QIS9H4@R$8B=D6q>KHHA>lt\eQL<\m>\5@&qQ\5Z?E<%jdnD+D#$J
hVZZ\/ N=n>*?yJ8Q?t4QQ\+*h1L>#ku/8>eQ>epIGd=Z?A?C<uCbmFuaVnkh6kX9dHCDJ\5@%*Fad%\iT#Q#!^
><nGH< H^4caJdHFad>D+Xlq8Xp+tEC5*B!enIJY#lItB1cMLE#!SycY>1bM^uctVCJ8l6dGN1b@>mWN9X\juSX
Tip!qI QXVQD\$a<AQ4j:D!McWD@%/:kwQ#Q>i8?L8E<R@6CuaYny>wX*B#@DHY\MH%$Iu@!XlDd/5PN\E<dCBc
WS<y5V T4$>QwGa5Vp=A<pRQCptKiRJ!#A5Cb%$t:Cn\=wJCa+CNEdjYbk=D9:uHndF%uajFe=&Gk=YcD^W^qkk
-AYLFT 00040224fe200110333 Page 335 of binaries1.zip
y6BpA4 LNTd6yl5ylIpc4kjWRNXWKRa8cDkwBIuCNiYuLR*jh&!<VY5?piHcqMdXLS>e9!C1W%Z<B8Yd@ky9Wc5
9P:?Kj IGSYa%bJq*!yIDR#kZ!K4<WIpj%BWIcjekZJEmT#uBw5/F#?Ej9IIpAmQ<EqiCXHk4XLC8MI$hmCZ^Ab
jZ:y?< I1#BRIAy8&+H!=5BtLD5\=M\VhkTFDNMT%WuWW+SSjhXPaYHNda+t9LlJJCHDW#DFI+XmuZ/Z8Qb&:FV
!D95\\ BmHX*w4Db$$C1u1TIW$EA6Ku#uAJFy*M5EiVP&P^B$F1HZWLCR1ekEJ&dRlA$KkSh!CpDlKB/lBDQ\Zc
%aXQTk WpZ+dT#aDBE#4JK+@PG8IMmAA/#TwmSihpb/E/PQ\p+kiWR&KAJ^<yLBKyblmpK/@Iu<EpR:jNmMel$<
u4cyy< /aL&LEAS@XZnHeMV58:KaMlAcK#8VL?yBqnY@JN\IG51B#/!5A\IN^kKhahZL4=a4RaPR1BQKBkKjM56
RdplPM m11KIh/hqZ&VAAQq@wYten5qCm@*pF\k6qk1p&Wl*jBnHtPI=iw$K=%<i?GtkNTaEJ$ABl$uueAAT&=D
RmSuhC X+juykBTJcw^clCWX%kNE\SkC!\cGdA8$qpLdR8n6Z5PRV\CenjGB54kLZZAFD+4:hWaSdnCXWDVpeeR
8KJPZD uhaF<M!wnTlTM+<mNYHLe^L\GI>K!<a>LZXJk<QY9ImTAHY8c5MJ/LJeEKQyVV9Ni5E1Im%LqMmEMAw5
ik&#Fk 1N@GheHWVcFE/QwLLLX%py9JS*j51yG?M8BlpQSinhN>b&HeAJLkZQZwbHTcLT:llcGlX$=1X+FMD!64
HCRem! >j@$ta$B&&Rcc1letcSN6D&pGtVaFtdT4el!%%pdlEN&AXLeLW/ybSYMS8iKYZdDha9pSDX%dFN$EGB6
/>QpbC K<y%nnXMcW19GTj*@NK$F$>!&NHDwtIhBWMRJNqcY9G?b+kJc&P&#\VIhG&>=@bY6B5cu:PuCRdI$hLn
J$%u1$ VEA5cScVNytYd9PMS6uKIWNkZ:w:/+Q@TDC8!&=*q%MCKl&Mqy?lhm6t94u&hDZ<CTy#BXL$T5t*&$Q?
k\h=aL iS/&bWT^<5=#%E*@JB&&/BcAIL?ZY<$Z1TYhjGY<1A^A!TWVN>uE#GIKnZj^?Z/#8FbLYqWaNAT8b!d/
#1RhI$ RT+E\BSI!!QDCAP<$D6q$lJDPm\I548IWuV%QuSDia$>D$&<B19=iRwSG@95Hw4?#8aIFmK>H8F&mTeP
*FkTn/ J84hY9YLqApk8dJcQq4SK:NQ8WAM+:AhmQJ5e:HbTEQ$F^u^$1Y=c46j&jFEkJKh*DZ=kY4CVWDddbG8
\%wwpi FKibDm5b#RyXmd^/NYCThGmk*ThWMEAJPBkRK<JcEJ#yeIlQ9p4BGB<HEmbSRE!=qHS=k9d8/bVS:ly=
4MtY16 1S@EF>miEP+NDcMJb>qBWAy<F$GemZb5&H+u6hk6%YLq!/SB^uXA95<aK1/P?yMMTQB$abQPDwIhLDI%
/$D1p? &ScSAYX:6Db1<XKLcdc?Y1K9!i/Vltj6E&E!aI9ZMt8N4:dVpMekKjVSnBn#%wSlEI&Stae8YVKMqlc$
?>*GHZ V<njQTF>H+I>1CWhMQKG+ckhy?8!A^lIpXS=G=\^t=JyauI454*D*VS>E4aJ?ia>myMFT!>$*!aHJKQ@
TuM?lV lpGw&ynBaACcApk5RJH!M#WX\#Myy!c&G4bBjP%SX?T?pX+8e+ZSlDjLKlSd+?nwBdITPC#T@b@\*4b:
5CtR^* Kw@nc4L8!+Ck!@9j6WtwIEt=y^G^8elnZZKVTE*!Jq&<u$R=XXIQL/e6kYZLFY=$S^1JMY5RBihMTBnV
uJn\$& XT*Xl$L:\8=e:VKSNk\^>?>5d9T*m@b1qiX:Nu?NS^nR^F\A<!h6lG=:jp@m<H/6uuwby6DyK?!GC8y*
K</e9l %?kkGmFB#llpi?%MKJD%JTYJy8Gm1al8jXRG4V1j4jybZ=y?=1R?$D?lL1X@FbSnLeq4iwM:cYu^V88N
HWS4yt J1#=qHd^^%Bm^RRG^6ne\VK6=95*EucTCn^aNE@KK/qyuWWaEy4uKP\hD$!aLF!>Mel\aK@m%l&bLPJN
YQNC$e ha4mc8%l=wLH\>8\KZRGhhA<tT%5Zh8yk>wDu/%YV>HNLe/m9C^Aj<<u59TPVau6hCiFDcb%<H^?&<Aj
!+V11V BR@A$KdB<5paXW6FM1Jw==uI6A5@9YTPdF9wc:lJeu?FYEj8\y&J9CbNVE<$&SIH#K@ZuJH\h#bYk6ZL
K&9hC* 5!GC%V4H:>ant8w!Yk1!\#*^4TGKqyP+aLqPDdEQbJw%dqA%ZKS\h86hP\1qynt%y?ClWE*:EE!+$Akm
w&Y$^4 LRnJ&1w9P4kd%E>VN8!5kSq9&VJ#6%&K#^q>/mt#CSDhpBkQ&GV>qew$+@cYNK*\c!1W&aT$$jBPKb&G
*KudQC 5MJl!\m8Q5anyE/kk<C\S\J++EALS+6ytmX<$d!V>e!BPciJPWay\up=1<E*JSM#eN4+/?iIXS:N/D9e
6H#Ykt $qtG49h9/1EdXK?65CFEdbANHWAnVXG*4lhB&iHbchK<=ecb>M*Xky>+R%lG+Np<+6+pXkn#bJEcPtj=
L5EVFP K#I%&H#Gbhj==8yi\8Iw*Sj=@Q#RqlVI+=a%69E5m:nZAVpnEwZu?!:uKGYww&NIq/L5wYnbc+^FkT^%
6w6EuA eiB!X@&S1@kluHyJDF:qqF%?#56FZ96*T*lel\VqGb?>>9QTk8e^&\SeLZe&m$M/mL9!i4qcKP9&\qdB
NaJ?8? i<Mhy%^TMk8!ukhNl$DBWNZZINZ/ZeK9qaiqw&V1YDyRKc+%NmXBLJ&/TT4V8kPaZ!dPaNm:/T@6l8#%
aHFAWj !/aDhtJ&44D59$\%KZ!4#k%p9ILXMqie<X4WyIEN4NaJ5CDVlWI5CB#aPEi$c\L%?!8djj@!el*&DVK?
NEajLE 5VQHq\4F&Jelt#+BcW+#@VPSFJN*81>$KCM&?Kc?P/Nj>XV:IuY?pSTy5^J8l+B4PCjkd1\nDt>TPPu:
FV4^&b \6QlIdcakD@cjLHcN?:tmBh4$XSQp+dI$ZNKSN1\qV%/Zyc%MXaXiWb9FqRu!+B9cBYpjFPq85BRSn9u
1EXZ6G lVmjNPWiqY<99at<M%qE6NQ4NmANW4RYRRdtA\MwJtV16&\<6@cmBw8Z64Iqk51I18^tt8Y9F1K&byEV
D\deFB dq1Hn:j:i&JKK/RPD4PqpIaBQahE\>ElnyG<GZa:6:JAHquW&&G*BY1mBX8=TidBc$T6&bnT<?HB+eHG
BZ\hlD @WFQFDwh?$E:$eH*qRMn=YXE\:5m6aZIl+!!<MDiXwbK$YGSE4@?CPqibNP6cwH8ty\45<G4*TKK:RGt
IhLmw8 5lKnwq$WkPW+jImNFuL>IeNGViqMVRu+lFbua>$KN5bhNk:!5CSC58QXWHSTJ+6S%V+@JKI+yE\tMG/4
=q8<>i BqFEXA/&^8aqMP448=/Vt6K#jnGbNG4A4yk6THISkX+ibjD#p&P1RhRIpjTq8>B1IDMStVlSj*T1CJ$/
Rh!J/c VFu:lE$?$J/wBXaXmqa4iT9EE<cw!K#eLY>NdKjbt/q?JY+69c8+Bddd4t?5n5WK:GhXJFX/8^YWZjG&
Y8Z>me \%by!=acJZVu9ukd5@*GdI$L\JSc\6K+M#nm8hVj#/J^T:?PJ4VW#$#pFPNq*@1%6ukWG?*tR1c*iEAW
&cwk#m bLCJ94eN/G?BADwNS5%XCT#6M+5W:cKKqjTSAkKA$eTpl?1\IWq%WR^lI*qa1EayFb=KFD4>:SR6\nSX
QQJSnA T&GJyZ58K$9I!CGV4FHDpY4d#EVmhy@JWe/G$Tm&GcdSK&cc$AMllu*SdD!H4M>kw+84Ik/CKqTkpVJk
RwuHw9 FiLTn#@SpF>ACL?TZnLkdR?!:QW:!Z84dq=E%V+tqy/j$Rj@Emt%5/S+QEHmi*cK*n+@K8RNdPWww=I!
J6$^b: :D=wE&XJN6:tZZAP=Wl8j*u:@qkbKtR?DVp@T*!4qXAka*V#Awpk>dFC>XBA%bbaG19aDN\?#ZdqV9E&
TIiN/y CS\hpGTyJ@4>ZBH@E=9qJ\XBbtNHyRhbHNII^jbBd$1wMa8w+jQKPBXR^&MQKqm/l=beYaS#XZMWLAZ5
:tcQ>5 cEi:GC9/4eya4FFlnj9/l^NPMqattM1&tTWnQA>!1*wB/\kkNw!baYSn=wPaTHt?VyRaWZqkp?IuT&W8
=9X=ZX X6di?WGLBVcKJi8%TWTSLWeDtEJ5LET6Lb5#WiYyY*4wDGYyC:wYG98>pwTw=T=$IiDWke%\5>K4Lbp?
1jLGj& >FL+?^^8KSQwR4yeZ8hTa*b$lnGKbnp+\W+8Eadi<VP1dFcD\$w$dnQkh6SG5^klZcTe*Kp@$h:YedSQ
E!DpRh 5+#IBDmmRlG=in@m<!p$QZtJ/JI8@?p#5YnaJV6L?CK4tuI$ITXM<MC/?BtZ4DSwc<&cNyymMQH5/lkd
Ete&@I =WkY9pSlQ@/BB4LTV:VEIhqknh@AXl5@yc4kWnRa>q8+Bd/lX+np&w?bQA&tbcY4X9#PA@#MI$GJWNqG
y@we1D ^NVET/9XLtD%QICL9>YiAA!aV/!qHj<wA%4+FKQS4CBpGNINyC+DHwc5tVhZJB=hSa?WSE?4S@Tip=N!
\GC=Q\ &:&/LAmXGQ^/qbV$6p^nGG=PpbqZEua1KVbYBCZpDJcT9ML4i$*>BumuAQQV=iG4>eKb4?lmw#8Zm$cV
5FGjjN ^Bnb:ebTDM4Iw?#QBJlZcMeFwDG@/&i@yM#dyYIy:1>Jw<1<aA8QbKycBwJTtqW+lA=+8Q9T6GXPBlMC
NWSyc# SiL=SedDlF%&np&P!GT!APBkcyhMGA!/dIa5YD6&#iwTXER*emFj*9EKMj5cGSJB6R1T@yC:tmJ4pmT*
IQKLPV aSi//aqAyaq6Kee!YFACth#WmM9dXXTEijy%^T1^J4<DwWuIhkX:9eA</j=TluFZDnD\#Q=a&DKT6SI=
YNQXe< \%ayKP?pQ&tb&y=IYbG:NJueM4yQ8X?wK6GAbTkkyYLGdHTlYhbd1NwSNKXyd&+Zcbh\EBhRdM&F6pw!
P1b@L: b*S^bK&9?T18?hnXQt>p&Nca9\SFd/wSBlB1IaXN:mDTE:YF<AJdGY&n?8Aa4%Mwj?^=//tHG+dPKle&
BpX6pc Fa6W\<q:$bGnaYCDC#P^T<R5En&:K&w6$6lHN^SCIK4PRZGZ8GTX@ZHCmepa@:aF5&&:G$99uwCTBIYK
C<A&eT 5:lc^8CYD9&8q?Lh%$$N:/4BnAG</l=wlSBhP8DGyW\GjLFI/<c$!%L@dL+wY*5\R!caw4M^h%K6A>qF
JDb@:! dckh*qdlLtBJdB*>yVYj@bkh$=Q!F^E6VGI&ktSLRHDMbASJaM!SbqGqa=AKjQyS+9bAEN&S/<+qE#T4
SHJPpY G@ICe%H^yVM>k%ER?!w<n+AV:Iw6i$Y*LK&yQ6mWaE$C&BXW9:R&ElLGAK1D4XV%K*WYWB#$LFKZRG%D
=haq=e icFYhBEwt$XK+%R@GA!&G%TAH<STpTEW:jB4q/G=4dX$H^lBEX1Q5qFSpWy9B?4JMln4HVtHSVR8YLZQ
VKe+V4 HS%Wu^l^%>YLMI#dhWiWuYMB%h%MwTXTKTicuKGRJ:LL!mRP\h%NmFaLJYHHtnR?k*u\*?mE^^%a/ICN
?\khip ttnwLm=9K1LJFFdGcC5u/c$?^&qd9Zkbb:J^:P!#1=DFIBb#/@=B?wkTw>=w<NSkEwNmZ?Xe<k&iLblw
Ji%Q+m &wRLS>GZ8L>=mFE5!1:HJtByi8A##Zb1XV#d6>:&w1W+P:<BhBuQ&p1KIch\+heEK%\I\mPhnRpG%RI4
TneLVd !LZ8GVciE\cd6PY%TAkHY&:Mum>KF:mLI5Q*IjN&cmy+LAaTtqAXeS\nty#N5X#VwYG\eTJteidw?9#/
MBh4:* mC+/+PP!?MA*L>FDp>&J$?SLSKYu*+yIIG!Ke#N/b5=^wKMhDB@aiQVp!@1FSajnMPY<q4CBbRQlNAHm
RC8LHt aqbYKk41DiDtA\$YaA=D+Q%!EV^E6nm?w6C+9e>Zi%?iA%>iB54Ve:V$D!:1VCXd?4SK/lYeLj/>8=#>
-Aenya 000ae6f757b00110333 Page 336 of binaries1.zip
b<l^S? !K%96mTuM4*eAB4QW%B4+Z%n\QJeCA^ilPlenBFiW8@XWedX&+pZRW$+lGXSM^Pi#L=n!taaGAL8abMe
n@l:Fk ?E4&8\/hEpm#CAw<m^yW6lGV^luj*H%=e\4V$Nq\t6@Wh&Bb4+%G/\&u!WHnK*tBu%XWLQql++t1#FcJ
pRGDG4 X#k/1wwXaXbPN?>c&$S^<eBPQ<8L%MaC$hWW9<#QI5%jm^aC>6Fa>hS?XLP#/1t4IlBJye#!yCuh%c+y
EnaDu9 $GIZN1K/BHS%cZG&?>m:NDIIKZG8%uK$w*KmD$1*&1lpB5F<*CA*Y!MS#/WPY:Jj/+aZTKA!Dl8FNH5C
*a%X+^ CR5daQancG+kAAhyB8?bD:MW@uby4L<%BquXkSTRAP<uRLkk&*tn&MYu&8Yq&jXJ6?9G5K5Xw69L598V
$k1IVW djiNa\?jbSeAkMju*ZQn*<5Z*P5XlpeC$jM&5w<98he469Qtbb>ZSy>PY8jCl*/?pq/hZMKFw9/dl6/F
TRBbBl ?IFQH\j+/kaJ5kb%?kdih9ZwVA==PZj#jSt/YS:tM&LuR+eR@5RitNGcNe$TENtM@/$>8=p8T+6nBi*#
&JN^qd @KWqtSKD&Bw@tbB1q55wTW@4#R:MDSc5F*:dDZt:F**:DZ8H8Y@HkkAKu&nu&@YJJ6tJG>Pl6*d\:%T:
:cJ\>Z d>#l*^qPQVPh<nahjKa@>e=^!68&:+9#hJQl6FjB>JiZM\R%M:4PM*+RM%<eb\tVy>/>tY&!HmL\tQ^p
/>Jm9Q Qjt8wMhdej=b#dDP%6PQl$*pby^<y/MX:V^C\5%a%i$CV6\CIP:AKHa@P*Lw>uy9hGn<JjD%@al\\@CZ
LKlZ$c b9dR4=^9n$eDJ/VVhYTiLuFi*+C%h:><8j=/?YRWTpVnhw*eFX//5&PM#HDMt*=5bZ1en:c>FRS#\$L/
e@VkVk :qqH?pDHnSCEnuluW>%/5&=ZW%u*8=KNb@b#SLbVPq$dh/=VSM/dQ9cd#h=#SQ=d#=K*jMJu>KK*dq>8
Q:C4Qy Q$?iJlnjiG+?h/i@+=NQ?PZn+98KFmnVJWL5la+J&CnK#!jDNLtt$quXHM&+Z&HpuptH\u:bp?/\d*%*
KM%T\b *9!%cwGwaeGuthjAkpFy?DtW@+EiFue#@kFWjE9#?wwR@!FFM+MiC?q#MIYA/iw:^nW?!6Xdu4Y*QBNE
LQthb! !85?Sh%E^1e*%u%6YdNi+Yh9R#eJQYaZye@%=e<JA/j%%T?I6e?@SM:^t%<5BG<9Kp@jG*<nCJ#%!y9q
n?5KuS >:m+Ni=6pd#pD@*G4@qh*@R:ejS*Z>@99wFu^IKuLTWVh&ZDN+i:89eLi6C^GQDhXF*::SNe&69:^DD:
\$CnHW iwk4Ai?Ptb^WX41cM%&9jjc99*/KJiwaqZcnwQBVid?B5AIk+aITFMel/VRl\SEKkl#64ZeAw\LFnw:#
dqXpCM b\Vak^BDS5q^c?GFKNyk%6%VXmRp\1NNk5n<kaI$MIm>y1!AV&GtV@Fp#JS+i65>A6AqA8BemiIqe=T&
AQIAJ\ +j%k?ABl8WyY%M/5KaXtAJW9p!1mQm%c8SwM4!BLyJIA1yw&!S>qK?iq<^jwL*c!&Ldqe6:69$k%kEn=
hK>I1p YK6dK9$JM@CJed/Khe1C&*N+$jmACBcbam^pEuAa!c1@Z:$JN!w\qPj+LaZ^l%FEMZI$l!q$J:a&mlEY
5*mA6w lb=ubWFSta%IYNW/LPHCK&SITclD4\IEc:<Zd!\/q+@GpB/F9jhlSqwS1X<1KYNCKX$YJuZaCyJ&uQq!
=P1lQ@ D9QF+mcWtnK^*<na$1dbtCJ%cJP>aeeuQh?Ku1muwD>kyJT85LG!5#BI+IBNmCYmM!eiNau^CVCTh$%X
mZQyFL tPWMD!A<e4YPJ5\K<Rc>ueZ1P!k1V8lA6%QBKk:AM5yPCEX::QYEmLZu^yhEkk*p%%6y<=HJ#??uL!q\
TFK\+* e@:*9KV\d:=+\M*%Z*9^kJ&F/\@lIuaY#piEm@+TD@4::Q<j+kw@mb^^e@$l1Q?LwB<*#=>B<:A<B5*=
9+*a\W m:kdD?8jR4M>B5*/m!A9D@8jRwMjkid+qbR<D<ijRuM?B5*!K#VZI>Bknq@XPjijRn?Gc&CYu>e=P\9L
puDyC5 u$I@lt8@DG/#5#!GdB#edL>AQ+b5aFcPZ/AjR:djBqn@Fe*^?:AnN>h@HudpB9<t:Mn/p:DnZ\*Z:<KP
bAD#i9 D>#p?j?ZPQ&9YiIW@V>?mXN5m+QLWn\51b<NN1!qlFWW$%EHCKj>GJGBDJmX$n$ceu!h8SKDdBXI$e8/
m/1JGm t:A+^AJG+^I$hMdC#$e>M5J4Z!FDR^6Z?CR9PJJF+LhY9S#tAAK1$Al5>JILDGn&pA1ea5NABh5VhWM<
JbF&AS DIhHTYG$%i5P/F5p?pi9FecmM&VSYcbmGGNATK5PAt^c1!qLuJ!8L>qYalq4AydB!^bPp#MeZYEkJC#d
+Nj^W8 IcN\a*1uJYnRW*&m?nwaHSB!4Y&Y!C!ykM8ESyc&*:^PetikduD^8nhVn+w4lt:N?bEA%/#nTGIRDCTJ
JS:@y@ $1SS6N?mc1>KMVmhdnuPa1kpGeRlC\6cyiwQluyZ!q+%XR4aH@&Yb9nBCCi8H%5Y^RcJ5!VTNX^yQCZ1
FI/qPC tG?Cy#YAVV9/*ZTpJGu$>IMQhn/%9C=qwQ%1@cyaMT/1Sqq5RdFtcF^>@mqXEk!C9^I1TC>4IIRPTcWc
@#Kkcd 9a+JNAiLLd4ekj>GJi:P9mdCYPS6PQJ=4di&KVIS8enJij*$T&t?!RA\pHGmcXVLumMTY<8dZawuiyY\
F4SZSJ #E1huD/+cJj4#66q>%bB5d\Gu@BJHY9!%C4J*HZyhdcy5nte+qFFkF<mdEdnje1E!<qpV?Z<qtD5:m^!
I5l$WS Iken1DqN=tnBq4@G5ac#bMKA<J5:CJuVD5ykPRGd1*S!qcV@MHXq&4l\Y+?j!\6*MdDbkB4V9\m19Yyw
/y&d>& 6hTe1Y8&c6MGH84n1hM8GBXYwS&uR+DEiahWF^#<XS6K/I6/JP:TY^!J?!<LnH:Y85IX&L=AhcWb#hI4
&Qt%Qy /BbZ>G1N<C/kRqM/waa1Wq1qqe%RSk1MtEuwt$I1e+kJuuj4VwV1J&ZmX85?DJ5S6XN:4Q1dM4\qM$4%
FaL/#< Mu9\RSFhH?Ae?8?H<h1mm/N6lKm\1tRHHb&n@N&L5T&jLJM+8<RqpKXyuDqQF6aFTEiBBKbQ+EqQihVn
VY@V>l unP@&bJESWeWkwaIZmRkGaATSymPbMn=YJh$F\B$=ka!GyLkhmERjDX?+hF9mQaMK^Pa&MwbZ9FMFkwD
\EPdIt L#$SZGIAMdn^cRL=hPCqkuLqYWjubtYBWcK%<Y=VRHbZ\M*$cE=<6GMGG4WtGVJhLVS/>E&w\RDN#F!H
le=PbM Swqnp1maF#^W4#%!89?auIZEDhSVt5R+nYYPL4?h^jq*^waLZJLCCVjWX?$tmA$mbSmSXLuZCB!H/!*!
/jwAq* Y#!atkJ8CW+&+bK>CW1+^tHp59pDAlcTV=Eh:IH?E&eTE1SaW+bheeY<DpWP!$?k<w&TuA%HG5+Q6tjY
D?yRMJ EVMaHdYX%wu5M1wpJFk!!h@$Y%RqieWZ\D1YMmj/a=5+DbFJ/\bWdVZCa>%aABt@>:h<Q?R#V#E$SXnk
tEeMTD :VMNqM5T19N!<c?1D^t:\E%lwen*/$Y41*ii<E!RpIb%q1HWcy#C#VHGKN/Ww=EkjA?%dPhRn$6*VXYC
mS4md> LI&cjyTR*9ZN\GLTT<CL@p&nkpJ>bF8mqnpdAdj!1<=yhS&P>DNJpVS4h6I>Gh:KGpEKCe>Sq5!TMp$Z
#E+dW: Inp61EBE+me6QP!wS%Ijw+#\Qjy=PJ8H&K!nuXIJw$6qCyZXp!H$$hCJaKNtqRQ<JlFN\p!AJ>^ee6>d
GIW+?6 #BXH:QQnt5#G8R5ET:TVpW=HYD/d#uM6Jb/c^#Z:>QV\nRRPWtpW+QKY\T>4aR>b8!Ya!dakWCVR=Bkp
w#Eiyc 5YaKXcw9dY1$Vcch=^<yZl^>LSyWLF8P6quC$W1p<Sb:twiA#8mP4&E+CQc4!QnABP<eb6e9GFen1ejS
uWSu5Z ?h+1Z!a+$DwSlXj%GQy6MuVeeumLp99qy:^Q/DpwtN@HQewR=h=?K+y#yti/IuB/dj&<%<M18F&TJ=1B
?YX9qN M4=!NA8Hj\DRNh%1^E+QK#VJwllc>J:/#RH9TcYujnJL<jeAJAS8YPt%W9$R?@iuQuTWKWSbB$JqIdtP
I8*%8y NlQb48qGtqK\l&1jeE&mb4j5NDRaMC>Nu1!:+CEMyXHVYk9NeakeFT@YXJT?c@@CcWPK%>bjDcQVKQq%
dLLt?4 G#/lIkc+A&d9Dw+t@11mn^PDD46Q@Ka5l!*uY>86PGPpNp*deQXYM>l<T/VyHWhV$>GyklKYL6Nk<Jw=
=/jq$X %5&tGwKnD9a6H<j%i*T+N+n1WM@>=8iNeWyui/95V<J:ltKGBZm+KK\w#bc51QAa*i1:Gjhq!/&wu+q1
A>VMIl TL:V?DwbtISId$JD?4R/=Hd!KMG#9F\\<#*D6X6D?:QTK+#\$6*wV<+mA@4QERY\pJqC1SwCLJ&L/tmM
eX<PB= nwat%R$19EA&pIMua@cH#@LnN18\4@ucQ^G5DF8PKlk?6%w:kTP4BQLl86i1d=+L:ASL#n6V>J1MwP^S
E%?\^V qXD:i55=bp=X^QKaZ\X6CJZ5t^A&?%kkNpRR&@NJ5t!/&Wmm&/mZp!Ckk:nYh/$V$yIh!iVYHS$?8tT?
\1@wi5 uQ1!tpVBJ+*h1&WtLP@N6wSdI!8FAEunnw#ATH!8DdD$#y\haZ=qIt*=Ym<b^n$C9/@ZFLiy<$4=W68n
El^XCb \Y!w:%DVeJNCA*\q*Ja!8ypu\u\l4XhV@QWD/ZXliGSVG/Gl6$XyM?>+mWGk!=%uWb<ew@/V66jc!#FH
d\QE>T YY&L6C/YV/@ADL^neL!*6uPqJX?>k!TPJXt+!&#58+#G!hY+!*yjLC*w!:A+SWSM&wu6!+^wbL>N#&Qd
Y@Ru5: B4R9:QpFIy9wdqEEl#t>&@pWGIe*XpnFLREdYYmYRaX\PmIPVYMYuH+$%lGp*1*kRS/$nRV=Mc@/E:Iu
SMWT?4 L$YeFwpSl:CNIq&T1&YWbSDwXWGTqd\YdQiE<pkWDCApLthREww6yI6k&QV8t&TW%$n86=/JT>1*H:5k
=C!n>X 9#KDuKmy+ua*9p5Yc>tutn\BZ#$=8BJF9\1VRN/Wm65HDwSydeXm/bwlZH\8n+cNYDXReA>MCP!:HB>P
!:D5ZA *^GhA>4dcE6RFCH9?hJASmNWRV=BVwJJhh=G#l1BDa?RiHFRt5CC4q:e9^I&aqi<AJSec@weN:kN4wTZ
WjSJn* PP$1Qa$/<I8?!KChSEeX!lS8nAZt8yT<D+!#CA!qSKZ6\e4KnV5am+MV/^8/tJW6klnTCAw%/RkntdIw
?uuwX! D!/#BdH$I+$!9F^*Yl+JPWbFLn9\l4IZkWFPXbi?uKZ=1m*VQd==$S6tw*aeC!8:C$*d:FS5FX#Ri&DV
yjih/c @EJP!hiPA!@jKT&VEkh?^HqdHG*u@e\a&SahBlbXpDcq*XY9W=J>=jFR6iIBK>GSt4nCJ<$!BlkW95AD
w^epAq udTD5RLHFZMaa\!ydLWn!M=mCjee8!VAk9$RWV\%Y%iCta<ykk8hLAb#A$GPi\KdXbT$NGHbSuuJLlXq
VFFN&$ IG#ZpX$FBYe^%XT?M&^\HWPYXXc=QHKS%TdctquEnRk%*pmIR/H>CkjMHXKkne%Y6T+LK*P9n1+#RJET
chNVR5 BRWDY4H#p*nPqAY5V8M+6Ic=ZJbE\MEyNJLjtGRmNBI:TBLt^bMl!PiR1D>jFjLZCa9@iMLqq^M6@<Zb
pm!&<l FZaY:9@m:Aw4>^>uX%m=Hn&:\94V&SX&qn@/4H<6+4@ME*D@@HX8hqcY^/A=8Z/Bbu$Etl*M?k5$&!QR
pcJ%%I 9@b+YhpjW*R8<C@R+Mik&Z>Xdd@*Yj?P@a><%u?<Hj5Zu=YD=!e?K?69jhc@W899!=H??cL9Z&aRTbnq
4t&<#@ DG*@55EGJtFY6#V=+h$?MI^b\6VT*PKBk\>Fj&CPya8#k1tV5L&6k:*hD&w?HCB5d&Q9yP^kcQ!AFnF%
-Aw/5K 00001521cbb00110333 Page 337 of binaries1.zip
:@5HaW 5#R&FZe!>QmHm<#K\k:t?1iQLCK5<lMj?Z:t@kCALQlRcqPAmS@k+ZM@D^AG\MQ??D^<\\Ql+iCB!An\
tc59^\ <AnI1ElI!ElI1GnAl&>pIBwKPkaIA^$FB\eQD\iHuI!MnJ#/H=@:XkAmQPAAMAeBRRc+:\TMQb\aD8LH
PP\%BL B@C*D#RMFCR5BAAP@kpCImwAEkIKClIcElaP/8EL$lpCEkwNGkBDm5+11AmLaWnt/A>mm<?A\/\RIt>V
:Nh9G+ Gq%t^#I/wuAKPKaWBm5ubFacP:h#mFAubqX^a18a8HTM4eBVBV=B\MENilkdb%i4nc9T+J&5uubP4J&b
HW:mJF 8kau=>S$Vc/jt:tF9M16:b:c8PATX#h@Ejw/4/=ui9Md6+TGlZ6aTu=>:<#YJT&QyKcqS@mdkwc?&i*9
j@Z9!# hL^TYqciEctFnj%#P%j*Z\DRAPV:PRD<n%9mB/V1dDX!N/RkQb>:P*<:Vl^?D/BG9$ZK8khMN5@jmjV<
NyKtH> pFn/u:Y=>HRiH>Gy\D1n+!W=@XN^AkhTFcW\4TwHRlMeqHHme%1WK/h:RPGdJ6b:kFLeQTCQ?cwk:Sj:
wRCI1< Q>!Q5H=M@hw>y#%RSkehAMMthXaFX5Ypmql:!>$\byMJj&R^Nb/qkw=PtRGcm&1?JN:B8kieM<@jn9nK
QAu1GM LC4W*RMKjBaQA1@M4wJdd1W9:kE8^PNeE+#*kB*>889$8=Tytw4\4K98aH5CJ+q+b$SElh+&&Fd*6*14
nqhG#y W6ZB4dEm6c<+CiLd&&5\!dPa\#1dM?\jCudd<kZ8dPke$jj1>j:hFu?8jj:<\/$HLNy>FL^q>^bc9M8=
mFTZ#Y >t%E&W=>?w^:wejYMZP?a!iE=wdW<Ekl@mnYK>wub9\i5J=A@F&mmjqk?4yqdj9C8?y?hE6h@%Bt<Vm?
P%1$$k SdP#!t\wnhNtJkHT9lW!d/jKlu?Xw=S=8?<t>KB>>?QV:$\<RlRb!&&9^ERX<qcBkYaM9LdjDH^HQD@p
H4M?jw ay\F6RcV^&%1na4/WN89W<>>NM!y1V/c:\IG=:kwqNBD1bEwXP^P<>?QJZyWEHla1%FKEK8?496PnaJ!
TYT?wt QjnlPQ:l=w\$&mqJaN^$</%/CuI5^dd9ZHyap<Q=IlK/t6EFF55Z/&\1yhEqel!RC&+HmW<^H81DYlt+
b%XG9y eZiAe6u68&Ijd5l*=XQp1NG%HMBtSnh/55EnW!tG/L!+BPPJaH^&!*p\=@d?bTI%qa?Wl=hR6hCDA>^L
GIZ4b& ZKW*&cED=Z\QIKRuQni:B+TXm9wi=*!?H@?\A:pq/ZBSpX%e!WWbQ&kWHJbQq&DwY%J$D^mkdLtqcLqN
6&5G\8 *Dm9<j%8<9CR5%@jA!1>96cY*RMaZ6$D#lL8ASj!cXPVQ&y/<T=B@/:9%HP8=cbT?^+\Ju$QtH%84/%?
IH=Ynm D*kq:Z5q/Z6NQdS4hR<+/Z8+GWuti+DJ>!bd@V9NB+=5W>+D>n=k^FqlKE?N:=85/9F6t8X+n6Xijldc
jKb%qG 9T6^$#@ljnkXy@$jN*^@<w@9@WSmVW%Hkjla<S5N^cRBBeE><eq!LV*4?Al^i\TwJ1#6uy%A\9N:AI69
d?KKRS <$Nd!t:k*\t^L@5iiH6PjE9bh\>Rajj&HTR?#H<wFyQ<XWdc:y*BQeBd@KHMV4/VRJQZuk5D:h48Jq1B
$TT1SS ZcX9I\4!\T^8=AS%nTe$KkGWmmPIDaB:RCK84@+y*QWP@=X$+q&?&hW>IIX@WjGlSuR?uA6#Vh?$*X*F
LpnB!u *mY5QdSA*PcYDbS9E:=u4/q9FV49Yu\yF:C?HcX9EGdGt%qKJWN?=JPWCq!Nq:?^hL/j*D4%@9n=@QPN
wRjR^e QPVE!@Qemd9t:+ZQ:kEw8/qbm$h*DZ@t>@*W?+tZh<VVHPI6!:jPK9@8V=aMCwRJb5adCMV=Y=8jMG#/
idw^nQ u!YQ4jTh+m>\@p9Dt@*S@9n9S>=9@H*4ne?<d#jXQTC<^<@Ph#ZH?K=+<Sm#6?\P*QDRd9?ne+\>uCMe
IZy>nI my\hlk+!XcGAPy%@pM>yt?8W?idJQTC%T5q?R?8l5u$*m8W<6L+AK:qccbW1u5d4t%C5c!?W6FPMemjR
qW^ZPD +5clFkiB%9A!w6*w^GW\$nlN4&*9AVlyh>SEEA**kJnp&K51*$=%5ydL5e*:<h<Z^1F&*>Z6I%uj1kc$
\<%mpZ >P$/@/eN!S!$<E85WMhyKFu5qAR^Y1hwXKWCkb^IFbkZSB?CySZP6%ne*6d6XDGq*<^IQKMm5FAQWH84
$PJBX1 !Lp=WCLjLM!*%JIT?>D/lm5a?9LC+lTJPQTX<q/N&T<HEd*i=L1?Y:$VE:^%>6S@8*l+Hj5hF?/<n#kB
WW^9S& dkQBG6q4p1E5L<%DKB!QTq@hn9nL+Y4Cdpe?N6q\SAdCyB?HB^%tV&m8AHWuSuA*Q#8mB%^y455=@A11
c6LTEi E\FEFDtP^P\uFZYWp\4EmRSyVZRm\Vp@EKYGTpTeIL:@l@8J8Gi%LRmTtFG6/cVGL$QZTb>u4P**ETn:
Q6HmqD E:?RWZQ*cwXPEPT#pT@5\%R*E9cW\Ptc6^%YejRIaMh>9<InpPIb\JL%#VTLEP>=^\jHW&+Vd@&9X\SR
pta%@n y<Sjm>l8p@hmRw?:y=Z94PY@a*DhJt&W=6%MjVml54?tdiM$?u=4?u4E\HnYMEdW/qV8EB^+%P=k^%m>
ii=/%R *RS&hGBm>8bA:G9ANch^H?>P&Tcj!tYt@LRNM4qd^\G+J@5iRwqI$C%aQHj6VCBta#>=GbbMw^:c$V5t
ty8/&m jA^:%p8R<K:&1EPcZ*@H:S:\RA:Qb?D#K?>t<k?#ANenuM4d&u6AqP\>ACMYR8ei$CQXe/9b5pIj4@?:
nm\ZJT h8nuZuFp4N@kkG@qJ4u6qHS*KVd1X&^F!Yj<qDch+5YXa=d/iBT@^uq4=QiI<4*N^u6Aq&*KLy+:R*MB
\R4XG9 ySXNSi<p9XCdi<G/kCC+b<:KnY5enFZqYbuHJAYF+EC1uW@+yK*=:ah?u:&9n@/?u@y\=iSLi%*q?e@9
Hm9>Pc mtk:uMuMktN/@iZpe>X:kFj5JjHi$Lu1:qdEQcDw>p%#ae9lR+eEhj9G&k+$cbSBCK@qC@VNw#:=<JH4
S@?Bqj N><$>QS%JPIHcYXZ^$8IH!/*NS:AZDimV9V*kGkt*><$eRlib&lI^dB$%##Tp#Z+%yH6&4lMiyI*Yc4S
yZjbY8 FMp1>TIew9tKqi?/DZM%m4K!EZIIVSR?Ip9k1w#uLk^#kKM=TFpRVbdWa*ci=AZL$YMGb/M@MRyZdE?m
HLty+L RM/I1FljdX!=T@Yqidk^!=85k/H69JQan%!=H@1j:**>?i::pZhZn##$F:9dXF<w\A%ALQ!iBL<^S+EX
?*M+Mu q##&Wmh=B4:Ju=#@=/iqjdB>@=Q!/k:CG\%$SIQ1?SyeVLYWH+:mjI^qjBd<yT@lky&WH4MH98$&?T#L
>d69R8 CmWuB8q1<MG<?RIS1WwwVH8/8!nR<GC8^XnJ#5u*XYn8AVR4uP?NAm:5^ZA%$KHEVQVq*+qKmCbG+4&a
lS6MKp l!yLZVFX\qLTkeIS%iSl9\*d^VWw>eKJ>hJdHHSaGI/nmIqcPta4!%QZI<mC&JJGWjRE94R8DTiZ1KTN
A4=Bb4 /pekIwnN=qE*t+@d%nElMyL5*L@8qHdEq?nm<ZZQ<IN<Lt/u9cLkpWEhJQj&5my5$pN$5GK>DuBi%t4B
yV:^FK ?*/GdFPZe/y:9/Qc/lBDPXlRuQYMRm*uydHJKWJYeuSWQ>q=p<TkKc$c6BMDnDmpw*TJ^b^IqaS&aIa4
emWbTW Q$J$@R%FBRCQ\$jk$9^?+lX@KmaBKa1!jGTTDkRJT@Hd!\PWGMdu#TPTDDKX:MJ\W!c4:j:YWm4qtN$/
CJj*5n Hwp:@WRmeYKDP:Ec4jb!u?yQHK!Q>unj8u\%$1B?>iXY1w9CwW4S5q>%k%bbYVBY%*FPZ+dlLS#1&A&B
ZVL5ji wAeSDGl>\E$icHlK\YhEh:BlH+#F5iE^\b!:RIhb&LG9nB+=SE6VVS/HuZVY#C&9nHja>hqDXGDBKMEn
=A+WR: 4NPT4LjGA=*Et:jZ!Bu@mKB^Pu*uyXG<ha8Gl6b514&1S:qRWD1B>iiXHb:wpM8u8?#*AJ+dXku1=HXX
M>H6lG 6<J*aiDYka9=P%c8G#t?u\\H@tqAARMMDwIWa/um8GbPEGAIqWSB=iDuYX&Wk%QV=b%XQMpb>j=NAkN+
$:WENu Ae>=Mt/V+S!nbeYYq!#9ASJ#jlGD&?h8c>^:HhcJVX=5EY?i<=hy9Fhm/A#DWSMRIp@XPdD!R:k$Gy*=
S^wTEa I1HpdtiLk4=A!LmAeELbQDS<D<B$Yl%uJkYIe?T9CDNj$chmRmPw4X1ynDN5%^X9*VZqt=mbG6w5Vjcc
/bKEYw QhZ=SybHj/a:1ZH%!6ZHK*bTK&<m*jj!<4aRaVX4@DAV8YLIKqMA5&hTL\mmE@J=^ZI6Sc4wwKGR6FYG
=nF#Na h11@QRqE<A9F<*jNw#&%d>!QGSkbM<Iq!jkL/@A1C8b*mcn1F$i^6ci$qTSYJG9nW6Y1C^1Pi+b!9!++
:@B4Q6 uPjXPBIKRhteaSK+RY=&<N>QJd!n&w9i1AZuwE!8qZ/>B&mYQn8du/ZjpdXcTBKd4HXYlW$uQw5!*5bt
:1jdHR a#XQGEtRyN:=9Fl&+*ZG5YC<KN5WQ^nLWeSn/6R>iVeYR:h+KG=a1&V=\4FSp1A&wle!D%<hAJAGAPy#
*h%NhA 8&J$QG**XJcj=Ye=/=?bp*DAF$=6&1ceha=LNMTP4#Ltu<pc*RQE++/91c$iDGLC<:$ZY&uNwp*ci1JS
8c$M%^ d=6LKD*RJeq91c%PPHJN^$4H\#S6LWIKu=iRR5*+by@N=#+=i*Al4H?+EPaQLpTW&wJX9F!C6DNWbtwq
kVkKjy A#A:F6D6q9eqAH8@:5dI@9K6P<LtHc<c@<:RQRBN=<HT4Ey@?E$Zk*lkP:Z^>cWdyenYcBZVIBT6X1!n
h9NbH: Du\1S\=E@V4jB>S#\1@b9GFDQw^*cFL4lHBTDAeGSd*\<diTQC\MBJMN/p+\ny?#LE@\KqpyAJ$DqQJa
6\%!md dFB/1tZp$#Dc&1KY1AF+S<A>KHSb*clR=+N=w+c@cIicdn+MW@<1C9<Zbe9F8R@m?56?yd<iyQ+a$<KN
Y<NA*l uW6:!\$%hBBk/$Y^b+T5<HVR?=Z%aWcK:V^WRWeG@qR/l5aPZ6beh6>hGpZEwCCcQ*/?tMdu#J=>J@8c
<\e>I+ =bEZuqcNDVHmuAcNLK4STSq<d!Ch?Bakle@&A&#6c:BV==:tR%5#W^yllm^J6Qpd%\kllbXiYn<Mm9<!
h8SH4P HQ::+Bn\l:=4@F>L?a#pleL^5cpBRtXquPAC1tCQ6=a>^D$A8tYcc#L*mQlI?6d=Q>mD+YI^H^qB%PKn
k@Zcnn >8B*@aiZ@e&+!ZTbIdy\WEXpnBbpPWKYwaceLQG8Xa&A^#Z@&=EW#9qS@/:w&l/%tqN4eu\#BZymN%8w
69jWCX qd&Y&!J!Bq9K^CB*4/yHhBmTjEVT6*bC*w5:S14SnDAyw\C<iW^ZS8Le4NS?KISDLeiLN9:5M5Q#==X\
L%CH!9 FC5=c6VZZu=<Ew!11:yD>M5!*G41CkQ%B9DQi=mbPiphL^L9YQN&P15i*CDVKX/w#@uRZ5\nD/^n581=
RIQJS8 8Ree^h+D\Kb1@J9*kCDj:%qMFjeA@l9!i<ARdlH^/V&kuj>tNQqlNQVlD8&l$+^1@AjE4Nn*<#$A@l=\
>acVVe K1b1jPh:?iBBy4Jh#AR1CBl+CYITPyXnj4=^KjchVL5nc<C<B*T@=9?6w@TnJ1FClTw5nK*huwi45ny<
\CW8Bj eukLj?p?b1Z$n9WipQ:kt:^=eFA==c>K$5/RYp:=d/piZFjXKl@@848H>yW>!:>Vc#@CiR>+/GjQ$1l9
&&nNMy %ac8aBi@j:lLNHq\lGaw&1iYTTumImAu9:<H#/>RFu*d?Q#DD!M&+4@5@uCMF5#:+a&LLJ=4:WSyEAd9
AXp:*@ E$^8mWpq1cu<a6/CX9LQ:=Wy@QMnaqwc$?+KX9uZDd<@>j%GBeM:lh9F9@bi?<:AR+\MPnXP!SMKiA<+
-Apk\p 000b66133fd00110333 Page 338 of binaries1.zip
I^tTN1 q?i/KWclWj8RHZwV<ZD<?n&k9@Wp>qdu4=544://u#T6h/1>t9Q#&HTNwVnL^VRuXXHNkuJ!Ep:^Du6w
\N&GV? ?AT?^^A@IhN9Y64T!%WHlqKpHJ>!etMpYn&ZT$8Fn4Jc$LNZNW>:ZGEG^IST^StmcBb$4hSHq<SYQkC&
iVCiPE y:%jY@C%nwXIy:^CQZCQQ<apFWI=8MlA?4aeZcmV#Xw!Hp/FKIu4mXXtH?\RKQ>c&=81n%F>ZDYER+*8
/Dkp&j mTpm:61uYPIKBj1Jt#wYe4*NJ%R5\Wu>/EESSBT1LTd?@iq18TuGN8ce^>+tEQ\\=*+eBN9H!uQ%yVa#
L#+dD> JV%#<k?%Y+V??Wj:@H6X9*%>KuIQcLk&jKDdR>hGdh4LF6>\jIiVqEuTLw:9J:k>e9b$Z*HCRH8?yXm1
&V&p6C EpKIm/LCTJbGXw/C$tDuJYF=?^T8ZVc1KD=jcL1mjl/%u8LJe5*EQ6Ml#VlF9uGWHjaK@ki9*adRthk:
TAy6:C %y=:ACy8PhIjTQede:C1J^LqFB@ALFYSj8QWBwTm#Z<c\AX686HKPTj??5B&8V+E*y5&*mTtjH#bAMhY
cw9CS^ Hm4mLtCWj^HX6:h5d?kK<iE?9AV9AYR6XX^dnBm*^*A*EZiDm?uX<6</mW@w4>q>@uF\t^l$:SPk!>tp
YkCu?: ?nkCDiT+Ai^jnee@/1VnqF=5\6:X?8WAN*A$y#LLMaMDZYLS9G#juQ?q=Y1ehl?8yBeB16kpSYA\iyW5
eChyAy M$^buq:#<$&pElj+PiJmud:6V9H&ul=WcS#d\^YMkqiLSt&!TCn:=mLnNw\b$V=FiIW5TK1EQ8dNE8DL
j@P\R@ h6*=l%y+KHp+<M%j46>DjCNk%54Fj##&$M:X:C<n%6V9AZk/9:XiT>4Z^1+IQY$WCt&y8G:mIQJIQA:i
cSdY8D /X#58<CWbH=6E+TaAJbQjl8/BZ%DEnDjnkHGbCNMcDNN%=lbhQtC=Sc*#?w8jikT5Pe:kH8&&dX?w9V$
?6BXut =e#HAE@&19!Fh*+p!4Zm+Qq/w+A=!SwclB=:1+4=N/6mWtKnk$FiaH:Wy=jKNyyq1!blQju#=P#6+^lP
GaPTi% @m$9?kln+VLYM8m+mQqaK/heq8&KHH*6CCYlpw:bHcGQ%wVjZb+9R98<Gd$H:C\@&A*!4B>#I9@Jhuud
NtVb6* iw^ylIc8TZTYWGpRY:^ey:H#k*u<^!MKc1!@B$nKu<Q6<5Ci^4!NBZyGePFt*a+C9G8<C?=/!P\#ml$<
Md&pG@ A@j>?><%c?T5Ve6dBJewG5W8m<Gt?^R#Sn\y6R6EQa/nQ+=k:t<a9jpp9L%X?y\:QP4cj@!w+/Qm*Y5:
d!CD$B *=ZPH<<p?V><J4<^q/c48tMe#PVRwyltSkCw#5VwCA6#icWuYC4djjCG?mqh:FwD=m>5pTceJNBhNFZA
/KQ8+I S8ueRQ4n/=XQ68Kc?ueA*!GQ?uujqpj<ey<%Sm6HYQCH<Ch:J?1y554?a%\RY$F<a!^@Ghc81*?:>be/
V&&WRL RVpXjqZLiyIywmctn$i<*^wYu!&pB6nZ9dL*N$u+\5RDE9XhB&XewZnBFipLqPEjZ>NbADnkiyb^dNiH
bkE<:l bL=RTQkqKmXAipKwIeM6J*!W@%cIe6u:+bk$+Y*F^WQHE?X+D?mEXaQ<k@Q%&?FHb!t=beq/8ARTGX6A
d@DbLC i&c&5tM\jdw+Yc^tE?jbX#a!pqH>Cdn\yW??u<4c+Ra/l<etGbap!CtK4V5^yMc!#/?etI%F/1yktwkk
LR6p>I b:PJ*u:NMXbF$j@mCq1Biju8&1l&PT88:>u!t&Vm\Gyuqd:h1?NZSK</\nL!yN=/DXi^tMi^FCWEt/eD
J4pEMZ V:pF4^M4#6F4RJhmuRaD>DNL:!&y/!*SSeKNSWMW<yXje!l8*/dY#n\>c+w>ddtJiH%uMZTq%@N><W=W
^J96wN ?1H@NA#5V&SR/4cK^qM+iPyPiN#\Y:Mb%Nl!QjJlB&ZKCZNnP8R4m6bKAA>c9K!EuXE%ALttFNP!$mh?
4Na91\ jKyMVM5Q#51qqJI1?6qElDT9+:ZMCXdy=q:?DBB4#pZ14RtD^Wi<5#IhFHNyS4Y?LD/XjuITY$WTi8G#
a^?Alk ei4cD+e/^Mj^9m8c6IQQP*&Qa@k9@ad?MC*=&:FWJ^NVbk&<KdLHi@w&*G>Hq^Ch!1wXdnTt<G*TdA&R
4nH6PI d/YLpK5LW?d1/ZnIp+ZFFyImA9la/bGW=by1At!DK5WJEpTwqBS/ReHp$b+%4GaV+G!kmaP@@llqnm4B
J5JCt/ >pC$%Ht8Ye6aZL$HylS1KdCZP*GE1/PYiZntkN#*p9ZHcGQh>8:1D#>NbeKm8CE^p:YCJk:wy\I^Q9@Y
PYD^n: #Q/#D9E*Z@41C%9Cdu\XTh#mj^nalb9km#ScMB9LmRjm9WS%/%5#Fh6dEHi8p<>D6K@SbeLLt\Kq?4/@
G%8%Qw XHwhYdCwyVp:Wb>5\5RFwP:T&ed/Y:Xy>Mpb@yP5N9?lG\m=$V46X8JEn5k89F*8/$hdwK!wb:DCtGXb
=IFn#J NyCECR#k%JQ9#BhGljFR8KGIYCy/cYF4yGE:HtSBW@mE^F=9e=He:SYZyct66dPqp\kpGdRaJ8qI>>B%
G/db:H t<MV/J+cRB5ba5wdw4t^dW&CqpNwhQZ+6BI:\dLD^5S=hK\ZhP@j86WJ1q6<>/RI#wCS^Jbi9ic#96ay
+Ep8## u:Y*\%RXT*MYBTD6><ku#j41%@<RQ9t<cQ<\^n4%>qt>K/un>&/=XY@d$Ne$>pHCZe1I*?/VAJEeM#^j
=Xd#*t Vj:\4+d!d=Z5WLwCZ=1iMGi/DmyWuJ:bbJ%$$V^:tStEyV5w^:tY%:Ei=9P1$WW%LVG?=5pPu:\MFIP<
a*%t5p I+&?VB&:1MKV^jqF/td%p=Z6iMd%%y#B!E4mGiYb/:ZC<h8h\D5&=q%e89?Aw4?%pl864%>uDuaC#iSX
ETy9R* nlG!uR4wC8HwpE5Yw4S\Z:pk?@uZe?RPbljSjwM&\Phut?PI4u=6E?AY\yq$JSa<^$:8tDt!F?X&^M&&
akyH$h 1q%S+\\e\pqBlTcqJ*jClFFAF4F=RRTHh:XjdB:b4ZKm$e4CNY?wKq>%EecS?<\%VT&iHEK+V+?pW&!=
Cib8ER W\R9JmMctb+wk/B$NJPYSwJ^i%ST8e9QTtFpQ>J#<@ad<R*<pAMeB\uMYwREQpJ<8Qq9LY\4%!9aHWGT
neQ#Z9 ^Gn5cF1>6e94Jh?S#h5d@mZjPw!$kYMh/4!uDPE*^eq**DA*5hqNH1JEh\nmP#b1<@%aYPdJqht&N#h$
l&@CnA m^=GD8ydD!Nn*>lL+9&in1!WuBl>DTIk*q9QpipiJKiij+!XNH:mlQ/Ll^itw!ZwXqlX\ChlTnealCwM
QpEcGT maD1th>FH5G6RtE6<D!^wcDkcaJp/cYwjhaZRe6#>b1cFDA6hM!+bL%kh?E#nP+<:%khn:FTGd%I#ZuM
Jpc?5K yhHa^jyL#ab^C<D8nbjnl+^TuuCapu4Z%c/8V4?AyBXSEpLc<X^L<M6\n>jXhXRCGZ*%eTh$h@qW=c=4
N@1kcn pt%8S%b8p&jyAi?TF9yXXCdD>IYT1d*$J/d+%>@Q*+u@CG1^9CmkCMhNFyJAW=&Wy<\H#eVXZFibQ=nW
Gmee/H hWn*jHJZXd&Yj5DS^WBb*i46t/L>!*8AthY%D@>5c9Nm:IZb#@eTt+1jFBdeA+#TjaE#5H?51>@c^u+K
jlu@bX kPRMWq<ZiZlP6EqWF4qjj>6WEJ1C=&y#CjN*@mQ4H^/q@wu9$9VXPn^BRu1GcadlEB&>q44QGa?9&88d
CKENj: D=eeh\%@QJTB+Tckpk8n1+AMn/mcH$6@M8hlBH&H=F61Z!S>J*?Dh\@R8b@a$9@qCVc81q9Y:kF6bihD
QtRAlJ ==c?D>WW1L?d6nN&D$m<B<D?<Hd@iL:FS=!5qe96qQE&Khk1kk4aL\!RK1H9VDWS@6$\p6!tec%E&?PY
5%*?ZK DjibTnKI=6y4muNX1eZa??JRy\w:=V8>=!kANbBw9n+&Y6yl!&VSMNdQcwCm@Z8kRB<#MylEPSTyuSRV
yK9q1a yub^M*^P\<1=!<RaR^\mAKESC$GB:ERLFpR>T:@+it>%@!#cnX>Et1>E$6jLl*&a+%#5yplPXd<1qSFP
$iXT!+ Qaa@bpj<R&niV6^CSP14wkm<p\#hb5K4qZ*4jPby+#4%q<pl+=HKduStbWyNQ5dw59R/1acPDCihBJkJ
meCteY tNAASK=bBS%/B*Ij5cCZ1!GJJW@I1FdEmDLj>AJ=TDVy8D>WZTS=Qej5d59eXi!8/H9BpGR^\L4=iaq^
dIJ1mJ \PeD=k9R^de&LIRB!t<pcuYMWkH<luC:PF!e9n@5=n<tEDkjZIt@BA@Bp!&5i!=Dd4a5G9yNHd4T%wlC
JbY<K9 <YPc/QI!^Td>&Vhm:>lF9<iMXhKMub8ma$LMpmQ\lDyIune/lu@8p!N@?V*Q*6DS&hdb8KBwnndBCI55
!4XiBC p=WpeGKNPw>aMYC/^$d?Vm$u?#Z/VE%I%t=*#Hn:C11mW5c6\DR^C6F!^jd*TCk^Cqq<FXdM6hIKEbX<
aeImmX ndX<M48*b5J*9ec^G\m$yNY/mlac/KPh/a+9\l9a=RBb*RM6n6G^y%m+Bh5Ye$Z1+?qw+uj:4A>8:JjF
K<>XLH tq*K=<aMh+d6bNn<GVZ<MkW?S6!!tAyTC\ZQSFFQFt9J8Vbe*&Id!:?YuISb*lC6D&EuSZ8ququeiWQF
6wE6&k YVaA5?B^<6SnDCy:=+E8yQnh<Y#5M9t>GW*&%h/m<+6w<wQYtw\W#dJ5N@MmbiTTh:EZ=JT+E>=G^b?T
99>VPK k>X6a@*d!ndlqZbPyuR=n+tGKF:E9&KY:bTtL+<SyFXcMHCC!J9q^44?ZN9wp<Z==9q4:@M\Gd>nDRVM
!R\VKy <Qhe<S4DeIBSq9Y=yKi4eB9R5Epn=$JTIipShH+!Am1i<?4VMeq*Bm<*:$heF#jiJ^4*:Kc1=RCe?1My
j<5QNY YQPNp6bAd!#ey#$N:L@4?GnjA%+>Qd!E>>&y@h>pp:D5uah&n$5nWcblKuGJ!IJ6M+%:$bYj6>EuAhi!
d/pEEj #:Tjh4Bt>DlD<!Qh\8&kp&w#\lPu%QPt/B8>NB?5AN15d@Q/\?m:dF59<9d#mZhb*iXDJa^?9CcW?B/n
5*i\5G Xn+J:m4Ni#1d5<DX?iT8Dl<ut\?tlX?BL8cMP9\\GDHLI>k&P@JG*KT#N*V/18tRSWT>VeVRALE%T<bN
!ecGn@ !+6<G++wN4?6\A1JPcZa4k#9e*R:a*M/>@!6FbpYeaEk<jWukD9S96+qJCES#5$5*>AGIb88^5KkHiQZ
:4W@ta SRZWJ+m5:$^wIjP!u=QeyIZmVh8AR+Yu5<e%m&<?t&P>Nb=F@:w*^q<$j^84Ny8Vq:X%^n?\CN*59+qT
%l$F#T *KZQMi<=tSmKcB&lu8b<#1*qiHj/ai/&Yd>G^\RQL4YJhe8nhH!9+^=ANH:XW4F%5t/=+%!GwL=Tlu#n
$c=8/d CJZ8Ed5D&&^hh@Xlawni%qY?!NN/IQcK$uy:4Q1!IG^lC/@%FKd9$/u1t$tjI5j#C51c#*uuYyLuH>S9
P5F>F1 MWbZ>d!K49ZZnSI5<A=#t@NT>:#yBL64^+@ZNd!JL<@!Ct/u9/9p8HW<%cZY%u/!K96T*qPRq&?FQn&E
$#&M$T /=Yejc8&I%PCim!C#=A\M4i?a:yH=L9yKd=y<\8K1=+4<I%Q%*TBqJdn8j9DM@Zl4@HuRIJT9kZ:TumW
HDBG5M >y#Fbnq?jqjVp:h%XiX6Q9FRGjL1E=5DF$Y/S/d9@Vjp4M@=PYbQ#pSydb<>a#=:n4q8KVY?5$Dj^H$<
#<m/Wp #*<@F4K4BZ$QWNAj8:P19Qw\Vd$tY9QqiX*ZM*u%5bw!JkL*p>5QXdYwQu+n@D9YD^=461*\ZS@:@!cd
/#6H@5 bcLYJGQkVm/%Di/#iBB/>nR>/NW>RF&X@bN9%t!\TyEn<*Vadym59a*L6aV=?<?:=CIcT+$a8mP#pWd9
6tCRHN /*LPwTb>uqPe:MjhA\w$jTj:mi8&d5Q9Aa$Q#i4DRZQQh*:4l@4=1ZnbZ%?c@h*KQqc&*:/%?H>!RqHF
-A?695 000fd32c7be00110333 Page 339 of binaries1.zip
YAu=@Z @\eTm6KqG<XXM>dd+GYZBZBiC>D%*=WYb\lE<LE+=4h#6ljntIHEqX$pYIKkhMd1a?uH9tPYTB55E+hC
Idj@L^ CH#qqlCM594aZjEJC^^XGeu$J1!6$P+EDH@XYWmP%A?L*?k$ayaRIkq5LcSl8K1en+mD85y4HYBJlIFX
Eb5IBa FMHp/5!RFRK^C6wIheG!\w@DMAdt?NTMKJqc+nc+kDDS%cdkS#W4+wH1GD*YKw9pM%NSeV&C@qI#uBwa
Z$8FN% :&\FakI#D?$$4A$/RTMMdL8+qinB6ulBmK/J=mY1aa5i\XCjInWy+muH@VT?4Z@\/#*i\<StpXbRwDE$
4hKBm= FNtH/V&/\R4Z4D8A5=qtSjyt5nnc1wCqbY*G$K69E@#FVGRXy<Pt!!pli+uZ^5FbEmGA4LtEQquP4cVa
X1w%nj tcdDRaS?b#qylBR\ADbk%+dDXn<GM6RDG^l\EStqT#!\4eceJ4E%h$Q$/wKlulhqm\%ILbhZ^L9+\8^$
baPNI4 cQV#hVc?e\#:Y1+/4\$DBhy4Eb%@Z<Jj:mF&BqJIi$u145Ad5bwFA?GC/atRHJ!$6KC&<Rtuc<\%4EF$
!&D^F\ IbT$TP^c4/?\56whSAen9>ItdMHCn@y^=9Wmc?jSS=p!dlECu$q$+JjK=VpYNII6d8B#19FB^+WFHh/6
N/jJA: PQNp*qI9iGX5FFJ#cnQlwle9StCIa65&Z&nJmHjD+J54I8??6BHhiNG5*1a#p%m/8VQ<5t:?8em>/JEl
ke&4m> a1RdNEy<LS>q$5FC+JIbW<EW?:qI+d8ZFR!>q&%q&cA\*jd9L/T?n:?i#P+Yb4eQ/N<C\W/t\&MHpGy8
juDala VSaG%Y:C9VG$Ciw1eE@lMItYaa%#p9XG=:DAT91MpEk6aylGT*anByHQwT!#@1E1CKAb\B4wYGb4>dEK
^b9HA8 iDTt*KXJM6MmZMehnlMIabm#H%wCi^i?kPykE:^R?>V<BX=18lN!>Bk*+\S9#F#Y6GbWL\#c/k!!=BM4
m*MdaL HnG$6?^=J6kRA8LAE5QDWK1R<XpnntnSAwH84mRhm4jSGp1CakFRIB*MG::+Hh!Bn@XH+hnc+lEC/Z\\
ZKhSVG 4ewwk*%y:Hq:MNnqXwmS1P\1FGjSKT98ZlAANqmut<LWeV$lwCM64HpZZSLbLW8dT^PQ$>JPwIENa1ap
\en4<Y 6y?yCA#pWRK?Mw+I$1bLEC41#!$q>*>nRw4jCYYATj:&@91@9cKCqii@8KKCp@YQK!w+Yj/6>Pd5HH<6
GWydLd %MMQ:u>Nd@:*N@S@@?+@&$?YVLD!QFKnky&N>VFw#q?5YtBn?%Nw>5ik&hl@kRd@KVVHa>A59!w===>C
W&WtAQ e#$C#eH>m?\GdN^@C5*#GDVu#=Nl5LP#@Cu$a:nG\jcLp4P#@Tu$a:kG=9#F?ly&<J>CQ+b4aLbjLGym
aS6$It =@^V/Mh\nS*<m#\e:N^@C9$a49&\$V>Fk^@DNVd8Z/Fb@^V/MX^:PP\ZcQa@lZ+M%*/>DA*<KMQG>w85
qMXl55 L?DHpI&D/^eQHQ\a59$!<R4+MYRD5@@CwIMjSVd\L=ww^&QI^9+LtTl&npiSnihZ/EiSDj!LY8Nk@#N%
NWlw=5 #kH?W&mPQ+Zt@FNw4y>wq*A#<VA>uIPHt+uX+wh!mc4#D=$TBZEFJuXLB%MtF*5tE%MdW^hVJnNLG>NH
DGJ=Ze c=iAH#w$<EQu^eEKJkE@tId@ZL8E@Zi!a@?hyYQqbH<\@!\pQ*n$w=TQKS*Q:=iL59L<=<6FYZ?:ZJTH
$@%9Mi >TjLSZ<4iQd*mSA\P>j@u?Lwj%GKw/H@<TtP:p1QZJact4eq4QBl&4IQY5866FK^cZem$NCCB*XRi>mA
j5MkYX TZID<Q6XFq^<DAMYuN!GaR+kJGPcp\NPKL>%wlDTZkX85G*?Gm>+PXKF4W+&ZbB/WpqctZICE@RBuAF@
@Zc:8\ @R%PZSLXCEeiIqWJq^#^E$5&T:FRDkw5k+&\EC\tWKa@GFIZnQ1E<b$I&a@eR6C!I%y5BE\Zjn?TJ%HC
kAYhF/ wY5=CmmRBEHqj%EbY\*dtShDS>Z&?lwD*<@FW+q$hSmeWc<wY:QQ4c*Ic$5EZF=$b%ukZY+VtMjt#5Km
q!6^mc P/yB#t@u1bQ%<q!Ji4HX94FW1uyKJc:wBu!/YI<aAbccun#%MlkeqkBDk+dSKGCG^InwpLB*Zd%4eXSF
Y:G4Fj Z=q19LJPMykleNbWEed*j<j#ZjcKK:1jbVh!1RQLpZm%WXyS$aTy=CMH4d>XKT=5%N!51?=M#tqYXe^F
WTKGcS Lt>$&qPD\%+iw6:$Ymm1/DhY$dwu:DGNuBG#a\eyklYPWQWD9pF+jw4WNeI?L&Y=<V5Ml<^m/Nt>VkWB
hhwy&b G&AkG%RC&!p918LahpM6pPj5pyQb8@+nEcqZ#Ehb&e4<D8VY8TAw?IXqaDN*l<>lhZY\DwSR8pwZSRXM
hQkFcK \jnaKpu9juCq/LH$Gl=KAcek9S8m+$JGA49LNbd46NCeVC1c%h^K?kp*b*9/SN&m%I4TRLIbW<mG!SPM
?#@mk9 C>&?h%+lwRb+a*&%6wME!+&BCnt#X%uAApPFNEB@wRd4WGA=D\q=inbwPlAV/hA@6EIlHB=CGFyy$\i=
Ie8SF4 A=:CThC/<kt5^X\VFlJKTnp68I\G8<%BAR$!Shq4\IQnXRypYGRRFJQ%@4hYF=E1SBWE6kEN9kBAd1E1
!T?6:T 1mju=*hRubibDYS9aZ#kLc>wZISCZ$H85+&\Kky51uSyKL%GpdFbD+D&BGcphSwXy+>XTRJPTQ#LFAiJ
4pnQV$ KHQ#S81NA9em:P6^888ZISYj9IK*>=e8<#NDAQbZtTLeJp8i9eHFl4BlHH$Q!T?MnItjPTl$*CRWCLAu
hQIup1 TGVNWn1iyYJ?Xd:^:8mF@/DKaqaiGtFK$ZN8lKdauDkBuC?PNTd:Mt\lpun?mVcFCp/Xpq&cBnW@p1Ck
p9tZ&R ?de%W\9NLWHHyRXDewlcdDK>T!6@Zd!i>=E&pGX/5M9FX5/E?W&ThS9AFPYJtYQhh1b6DI&#BT$5R4uB
9JIVG9 ?<ka/diPMulB*P^T9W4ClTySZ^Ic+I*&WkRuW@at5<nYk9w*$tnj:<h+Q\WFRlW<KW?FC:DM^nap?bJa
Ip5M%1 dYNLY+uVaWkt6<9BSi9/1pq5du+?!qwLZqi$@$ta\#9!e8VlNSDZFBaCVqcVWiq6@8mt!CjlFNjCbE*F
%*l5^K b#k5P+H$aWYl#%14FAR\AtuenJP?y%jGCcCn8#y!k%TQ<LVC>9%FeYCRu/!P1n?*M*NtTkISXc5XkXaI
RD!VS! MCHiTq<$j>Tct1d:EkGpS6y=bp#K8DKYbXSm%F<jjDYbK8!XNX\41BTKJn8>/8MA4EXpT*XXG*PKM/yX
I#E?$V C&twT%1BV?c8@R\G6e>d6YXhw>mw&m=NX\X%cXD&tqYJ4p$&DmdwJZ+$WQGeZnk@8Yew$nc4Gy!B9Vb@
YCR%8n j9Bq6n/QbtZIQa%VRTW?RlSTT6J</?K%k:B?Sn8/ZFkcuZ*W45+Iuu%*X?bN=5i#TA+\cSB1HlRPt\bM
?A1**w wW/6$EB=Y#IFSln1\k!$RAVw/BWw&Fc8ymTF6+:mWlTia^wBLGE\8ubJa1mW$KbYL$1w//en8nR$1%kq
ne*p/m HX!?BqdSeEK9=/ZBbS%*/I!<i=PN!aqwe8uR9hP9JH+1NY$#&qw+F5i?dlMhQDj+pS9da1&B?!NLSuB?
+SkR\F +6+y:YBEqAKh5FN4ES5ZQ#8Y5bYN4>L&M\yc8Da^R&ZwdHFiu*I#L!MpjA?>##G6=SkJI6ZPXVtMBX/l
MLm@\W eX<JLaBHZJ9WXGqS&e:9IwM?m:Z%6I%SEEDqG*uTSVlySR$wIC9&waCb&Wyi\!?^M<YdlXL^#iDX+4l1
E$$pF5 buScNGuTi46$HYY9YZ^@deBaYFTXDJYYY86EydtHSGujJj$c<iLX65G8K!T<TcFlR^Hqjt=iG4%^I#Q!
t!MK!Q B=Q8:1&mY&5#yn:%J6ld%+Y$e9iuewdMF#$/yVpS?u61d?1qnA1R/XQu@h?@J6AtN>=ey!mcTP*+8p*M
QcPZ8Z YbbpRRQ>BkEKHwQB6QlJRRaN%:CWNnd#5WW4i1tpZJ?8$t9VnI!N%$FQNe?#cRe+Zp#SJ%H8VIG?tH:<
%m$b4l R8JHGuJhypqap5@?/p&Lb9Cy%kJHWiN!T\k5!XemGm%iiA:=q/1iBaZ==%^GaJ@c6*yRM^*9<EQ*4#%G
4>9<H9 BpC=GkWN5Y&N8:6<ppaBcc?4iD:q$yCAkH$nuQS>%=B9dBJnca>:E5?Pyqtb5G5\%BTPu1N\$$B!iQ5H
4m9bYQ %d:GXF!jH?uFhdK4#J:#&b>$Ht!4N>*edWCKmKe!jMEh\X8abBq^FnMZ<#Ep8a>pdGwl18JFB:#=m>bF
Y?BE&d wlj6Y>+!Su/\T&*RwM<Im*NyAZZ^K:H!Sb@Q$8mH6=Q%%6:MF#b:q48Y1BCtllV!LhX8wy<N1whwMFt:
/W9?GH d1@HiEd8%>%Ww<+u\WlGDLD$TTc#9Ie=M6kBnXLul5e\NXNQNX9p#\M*jKJR&Xwn&IhdA+8=p+/AWRWV
Gtj<lQ /<Y\G#AIBeH=&lRBH6b!8aZXGdT9KtT9/5YAH&CBhcET^6dI*ZJWqp@i#/>Yj/ENi=?4hFAI!h=N6+hR
HEu<\> ctPYWyyLJNEu+h@hYGZ9bNDdtBec6IPTZ:kbBGTlTp#9dSen86kFbJhd:NBQ9JCit4N!Q#6C5I&q5\P8
>Hheln &RW!yG\cIEDdkNQVQ?\\qhn4ia1@8p+@KDFQMmy/9?hR#^+RldSL5GiXn>\9+:HD6+*e9I*56thj&tki
6cWwwV >ku1Hh4B+DZ>%QFtWtV=RymAAkLC%Kj%6aW51YZ=acTS>$6T5NIhI&eSEZN=yd16aVb&CPBTFDk^Ik@y
Vn+iSE *lKD+qJd>/!l1d=X:q%!k#I+lmYwh+mII&aYSF1:hDdY%T+ntaal%1CD:8%i4V$4w:FhD&Rylw>\bM9^
LmkE1> D6BIu/1a8wH&*CXYtkmSyY+wK\i:V#G*q1wSWk9>Q1Pl:q%9CZ&NFEN/1AeWKSXyBLPKIMd\yWwt&Nen
EL$MLQ lS+wnXhtclcnE*9$L=>IpPZL4ySL$SPcYRG6Jtb5?li!+>Em^hHl+P9K>e^Y1IEJSJ/!8W6llPShLE+Y
yD&1BW KtcqFaTnPm?BP&$MB/<B>VCw<Q:lK&?&n=TY8yHM1ZcPVCa/FAdV9/CKl!EQJd&Nw?w%edMy!bSAA$!Z
R8ZdaL ^KuaBp^YJu!EEatLjl>a@H/ccwC89^#bqt#P<5:6yLE$T\4SV^pRMSWVc5bn/&uCY14Q/JA1T\+:FLau
^qL#eW dW\LV%YMlDMmXV:Dqn5l@J4lM\pyW9E4&W4lXp5m$j^>^ea!&WED&D!kthX^qkG!RZ@nWm@Tbp\wNd^h
+\l:mZ n#&nYQiB>HBqqWTV=j9G\$+4T:<6ejnnyS%pbH#1>iIDtma\W\e=e/&KjKN%?Tiq@hV4&JtT+YIWGH&a
EK8F/< RDX^&TdY9CLMQhkY6JXV<%ba!?eBe8@6WVV&#F>XmIE$qDQB>JmEWL+E&Vw1!4YJt^e4CCwXImq:nmM9
$AW4jJ uKtTMQ4ByZE49Y<VWNFZFdBPaXJduwBhR@DMVn:!S5Ve5+^y?cWdu^!yGI\kT/aJTmyEDY9bdkNae:jt
lp=^Xe yaZkLaHt=Lt1pil:DnQRkKZCEIGYSJ5\J$bY?l#$Rm<Q5Ew1uRh1l%+PHW&StViJ4a*B\GeCYcb^!qQW
Ed!jW@ :un5TEC&eeR6iTSNiC^$wMH<RIGwtRA*+tW1FV>luDp1?t9B8PF:?je:L8mbpi=X#kJu=FcPcQGehH#X
\%<p?> b?td+DVyLAPk5ypEQepATPGKdpF@X%>tJRyajm4XE!^N@p:c?w6kJm>5pTCTkCI$M94B$c%epp&FMl@T
^c?9LV $qh8KjhQj9%X=8BKp8+6&yNLqZDt\j+KbRb4pJbSNb%NNbPZ+wlShb\>dYbpJtiFiI^%iA!bEue=ZJCD
@V$lJ/ RlkuIF1>bP&1IqicGy^KX\tD#5F8q=1T:D+A@H1QPuKKA1=tFSpV#n$?YBp:$<9ia^YTi1Jc/C*6SFht
-AH$M: 00002f63cb100110333 Page 340 of binaries1.zip
pb>^eJ dYD\GhptQRTGZFWRbba>FK8pq^%jXqCIP5lFFWtuT1D5$G$C5jV%hkGFLE%S?X:J^B9<IY@aBA$k1<cZ
6*?T*u \EV?kTX9GintkkWaRBR9icSI6q<@P:c^MC>QNV5WC?lhMcIIR1wi#Jy?CVbBI8VL/q9Nu8\9%9KwB!ti
LcWHF+ a9ZYQVE&e5MB@jyT1lGiW5&Z$m:/>QRGWnde5qjY%WwnS*jqtFY+ljpyV+w:w*TX+6/8JCt%VPB4qX&<
T:bT4< 11LSHYj+SMjuMWCZT!JRZu=lh&I\Xp1VwymqGiluu4\#nk#9Ij%TlXtAG#$eS5tu&8WRX/EQFJ1hqbj6
kEqA6y LMEYP^FTdibbblXMalaPm@nKdteCicuDFyGpbPBtdpyBK:tK55RRSTtQiQWyi#i*R@SI*5Sdc=a1yiVu
n1nW1P JV&c+1wGK\l/dwnPpqJV/W5h&F!Y8NI$:1<548ypK88W5Y6SqPn&uct$<cG4JNIZeTc5Z%V/6MRZi!CC
l#IDD+ !8YICheLyPktiS$H4hN:PQba#AwLeC6nbwc&#ujKDBtFaS\MK8SX*XYT9tDac$!T:R?Q&qp:m$uDcb>L
$^ReG+ t?emcbN<Sab9@DSJcV:6qVZkQkpL%ti&!Y46Z1t$mB?@Y\XBile$CY?X9\aWMQRE8JKpaTT#e&PJ4RJl
cRMDRV VIaF6Nn5Ct!PwXdjRe8?I^kd+*Glt1BF+LHFkWdIw:h>K^u9&Y+%M!X^<^+DtNPSEDNpEG@^$d<1QmR/
JX\pSW h<KY$/d*KRPP%VQ$Iaauje!&uyQ>d?M8!?hRE<cq$phCDYbw5Wwqq\wHSeNC\<aa:w1iLM&cXSupwpkW
@!qXtE IIXuJbT16GpqhRY#+L!Kbdelb*S%p6lpp$ZBZGC9p+>=ueRJekGZMK9R9$TQ@^lZb$&M5?!B9YB&!8ET
p>BL%5 p&\wnpcee?4Z9*hi%>u$?8wD^%lw:m%b6%WjmcqTI5Mp<=L>bKZ#\T1JRbXEtbcN8dL>kN*&SRQ\pCqm
?c/uLl tqi*B$%VchV9aJyT#KyW>kkw$an5aXY+&<eiGMp?cQMl%AAw4ipJ96k48KkhhnZ6htcd*p:A/4dJqcub
q#m:=j tTcHmw#GIdB9FcR&/@eQb115iiY8q9?XY?lF!pia*H/\!md!WK1u:E1FcllCFhmWJ?qn=SLQbGC5#W1$
C5ZT1Q =hi+:dk>h:#*<jRWdl<REI$S^MyIGZP@&FiIXcT>PY^Wbmq:E&1XdlcZuyiVR/W8Y>G8Z@G?YuPn<MLK
9JXV*+ E4X/G&9WW@Q<R@niJ+@B?&%R9kL5jp@?4=QM@c5\@Q?eJHQ@Kmj@d+SEihn@GBLqaj9*R1LeQH<LmjK\
bGWtiS @C+p!5Q/$=DwV?V4@*wHn\1J@pT?@w>w<K>tpu<mZ@<VNN89$J!QRQ<IKQ$e#jWa>K<CLn?S4@<n?pe&
Ap$P9q @b?niS/D@pYPj9cj!Nj@BM*^K#V4a=:*4<LRQ=G9@*jRn?Ic?BhQnA9<y>CQ+S4u4>Lpe*H?KjSn8Md^
J@S9nb K:b\ej<y>GP+>55\NDjLu$I@lt5e:L>C5@$y>GP+^5H/m+kJ>&P+>89AI9in!Md^C/QK@Sm!@VLa\<*%
%C8/!C y>CQIS8a+^el$h<J99\%qMQJ^MQE^k%t=@ldKEj+wa6&?SHN5VN>\iV5ctS6/9H+<BIH&$QQ^@PZ<BIH
#VP$+m J<>nAnm@p=H=H%?tH$Eqnwe8n8&lQD@K>yk!5j+?1MVJ>y<Hqj/ih9SHWAu<6&HK:<:L>5ik$pNj^jy@
ymnmhy ^>8%n9<Q9F%dTJe@pX?CcIeQt%G8k!hh$J+FKGLTc4^nkIn+AMZRu4LDmtThMI$mGp?!^IP$/6j@5V!?
G#&!B& ekPESC?%#MMaFuew1IC1aAwCBu1n$FIb5Snl=S/Te=@tK!5I+MKPHXqWTCie6X>DTMEZAFSG\BKkmEBX
MNPiBb 5tQ1J=NW5eXK>hbc=NGXuF?#DwP/\LS>THJqSY1kYi\aSAtH?mkZiG*V1I+lKNQ&KZhF\4qSLR=acKB1
@?wNtL CTWMFE6:l%cHkdJynD@$Cq<Rqw\\lmJu=cEElGRP#ZGiSIjVDZq!1^F?w&%n#Bjt<%6yH@chIY4&\Wkw
\y?eIk kw4mDIE!yGmRMp/>bJKGRIM^EMeMJNtYyE9eZZ=ynK%JH&TPMWJLwSm4hcTmk+yW9#JZJ:IKjJG+ew^q
R&\i?A ^qZ/HXPh6BMpy?65Pq8?kRZD+CJB\?JaBN$WnBe\mSiE8/D:cuY%Nnt*HI%IFl6yYWcuR>MR5B$^yLpq
u!d+HR !Fh!ZF5QR4weqPC%1iBVS+=mWK&#%*#=Zy&kViN8N^LIK<djJSiy%8FJR/?e%K+WpB=8BA9@JVRpBEYQ
VXMEYE FK1W*PX6njHyKkqjDF4ndw*\T$b1hCH/+At&L@E+!:AljAmd<Y$!wbwpMDmq@DPj9:kLwyR6kDH^anIk
*hqWj* 4^w@/^LykPhaGXH4*L<KtK/:4ld:<5\*MkVHL1kI:HC/KqJP8%$G!njZ\5!WC+cZ1PpHn%^iM@69jD?V
?CyZ\R wc4S!1VZ<%jA=At<K+ew$EGIJIT9nb6DWHymKbb#D6MtVA1q%mlpniVjmMNP<8%L+w!HcH/9\EXyKFyS
h$8^Ft 1jESBLpkmaJi=B!CR4uHW/H%*y+PhFEamHJ\E\%uiIit5%m=JR1+&#%YBmQdK6%j?FZtEy/\kR$$^BTm
1hZAq8 WMnB5l+CkkKc/t#:?p!qwBXHIEy>&$ecHtVFntki1^KMp4X4NHRK!$CWh:mXt!84<TTcSy?*ab1&?k8Z
!jD:R? CGBW<wFyQNZRt!b$QeB\?Hy^uM/R%a^Aa<p8EhF#%CAb+WWSEn>\W\m+LlYDWWT$RLRdektjwy$w*m<D
a/piC9 p%RnKJ^elNbw+M%cj/8TAhyH&=eCte1pQccEKnyimRj:YYSW<$\1Y4\/ju&6jX8X?1th4bE$nc46y4Z\
1:&BEa FE+TnBLB$#RN^Z8Bk?$\cFi&tbKNH*LI&=Kh4AS\uhAkCD1TBhAJilyPBl8ZMyq<cBmdMl$TeD@$Bhw5
hHm:\h ?WeM1D8ECXeyCwhAQmhda<n5MJ:LTH4!P4?<9#Hlyc#LX9RFXyI\Llp9iWc%K4weHm$QEh98!/%JRuB9
P!BY>Y MnZqAH6m6iI8=IR\&/a\Z:dD5@ipIFNS$8%A^mRm\wDZYDyd<?^5XjW\<uACS9GI1$qtbNwq:wDML?%d
5#WIL/ pl!CGXY9T$>&6t&!Q??Qp$q<WXE8Y8htn#=Vi*KqVc^hy+mY\ChjC\:d9IZ\hWH6V8<EXY:J8BjKnKd\
S!>p4^ b?=1&8CS^?SQBhSIXR+MuPKXD#dFn4yP/e#eEyc+?QW1de#4SVFAFmS#*^ZVd4VHF9cpn8kSM9Yt#m6E
N<4NI% wMDRVQH&jRRF=K+VFdQnwndlYKTdYJ5yW4bS5&&mL/m#P4!W8?\TSJ?p&dy&BB=BaJNMBWZ9SN4ZTYmS
QtZn&h Vu**eE&hDhT$QBpMRd?tP6Al%D?NQl#pqw8LClAyG5$=@WwhcS8*:=VENZeCGZ/^8tP+4FVaJ\QCBLjM
W!apM5 QMEZ#ZdQ@1DTLS+nKMAn#qL+hl5b8JuR/q\%A+ISAipRn@wlY%Qcl1mt^lQ&8:!aiGQd5>qGhm\$<AK#
8eSB!E I4jmjN^$#uqQkhtYkqq$*/?*5y+8e18C?WSyM>iADT\XX\nCR9hdW549^*HaL5=cRaD$B5qLcPqQj@?A
LZdDbT Q/yFnaBGcS4<=CmVHWpaGcLNYSh*\NGK\QYFe9I$w#C549pC9lMeFCXw@dpe\chAik*VaZpN4E:B=Mca
laGc*y yTYCN+A+k+NIa8AFS%jIP&wbw\a4$WG%TMWk*4km#NT55>KEMc+$/#X9VqE<a@D+1#=k!Y!Ek5PPX@+:
9WL8#< mmDG1bVM5!9FV5@8#:VCGqM1nA/:jiT=mdYjTtPc9V@89E4ceRtq6&FqC@VmB8/I*nED&9CC\B1bY@T&
K>W%Pn 9lIjHD6+C4#>Ae4#ZG$8pIB\wV1n=VHM::Gq\tYKltTecWma^K<qiEMN\jZy/eQX@Bw#&1mVl<&jTZqi
\HJm%y V=*DpaIHlXN!4G1@:D?9>cmA/ZMkwBY/$WD8d^?l9lBcy+BjX*6P6DTw:n^X>:a4S<Mt&X+!&SpGnabP
Cd69M+ STDbTc8tQ/X*#9LhB&DT5M9A4EJI^&DSJkGlAP!TIMPLc%8p5EJptdBJbyBIWhZILWHtt*CcBDe&aY<6
+FSP@N Shk%XuC^Vc#44dbc!Q6bPC\*9ne>YI+$d8QhGp<VYF9Z?$@A5B5q9Jc!NtJXGh*Q:%WR:>%jMhSjcquy
:8ICQ+ EP?uN!WnXD&uG#9tjFyWiVI%JHLXj?N+JKcGwDGPnq/\LaH@BtdaHS>d!FQ=!NPT#!5Fl<GMDLPW%%6#
\eFMB+ kKELmyaVLSZa=u<ZqMae&C@ta5n@Q9TnAE>$TeaZYKIX\e#I/<qFl>K&1G?>eW>9^XLDFK4aVV*6It>Q
5Giadu =6JYEN+!MW*9l#DIjFXERX8+6\>>mnK+NcE@c%wLcQB8EYlqF8tFl1RPhcIyjc+5#tBEEwECYDI6Rk:?
^Xl8dE jHYCjERXG/HGHA5wT#KWwaYk=n/!#:VM&:9J9BFlLm:4%Lqt9tyB1d$8X#LhTaa&8dGR#@j+QGKbA/94
$\iwMZ N\ASi!EJ?=bJSAjbjMXC<p1EwbIJBqq\:TJLcM=n\C9c>C%V$byw%<\%I@hR?++=QBe5wLi^*&hT\i5/
:::d!> Nu@:e@e:$StkYRAdwB@I$kM6Z\i$L+A#<apc9DkW5IA%in>CNtkP8ZRLb\udQk@Qwuh65lDKZB6GhuQ4
kK8/i/ WF/W5\leYap\&EA8e>I$m>P$hBNJ:\E/9IhBRI>&cIG*ZdMR/*<S=eSpZ*46?A#hLE4Vjl&V^Tk%TEXi
mB:u*w aSZV:/8w\CICK!btlad@#5k1m6CbpW98=*nAaDIEE8V:MJDG$m8*/HGIXkWWwdZLPBlAdAI*KynQ:wbi
CWZ\PN @9$/m<A:Pd%dSVaWlX8M51Y95m1DLI$mLEXwFSkwRe>9=i?pdKA9S?B\tJN^HA+$a5%IARyQY95X%4YW
iabD<* YPmWSuMAI^^E?#ARKJC$k>#\n4lILFNpA8*eFhi\Re5\BT>R$i#k8@&jTHIL&*hk:P8DJKST+84jIYb&
?!989W Wi&IyHem4TIlFdqAw\+>WTK\LGy*S*<8:mkLC1=HG1NGY%5tIDt^nA8tXnlna8:@dAN5#$TFNbKmHTyY
yQ=>>Y GVpKZ4taS=mcd=<qLb?pCq=l14T:GSCSM6CtDTGaG>qG@y#1kpCMdcCAjQ!MytLGMy<1BGA^lK:ph8L\
t#Rd*8 pe&X!d+Yq8tw4#KJQVCZh/miSwFdyW9Bid?GiH$Z\L4tp!uDqNBHNDb51HnmA5kGy8<lHa=NPYaRKeFB
eFGkRy Wa^>n?PPP?JnGGi/GYiVa<ZAGFuIZP1P:Z/H^cJNjqmFCVPDdDCAmh1CjqIN#FaB=wtmnB1>Np&pHFKF
CeYcR9 e%Kt@n\YbuBKn5aH#&1LbB&MSZ%KYc+m\wbZ4/^MRB@MpXAD/=^MA!$q!6bMJ?#Hc*VQMMLNMIc*bjMJ
WkQkPk &cEHm<WNKLCL=F!EFtyP\%cDMh1DEKiN^d\VH8j&KtAZE*pLGkRjYEl\$@4=CbQP:bk1q:lQHb5#LIcj
jY\SyV CaW%6<PNK=5?wpMQGZMXmKaMXnwak!&T5ZLy4SM>aibT#K+6hnpMDm4L=\B&pt/Rwb<m&>Ie$5au%YBh
%T:u%y XmhIctX?9ESl5e@Rl8HI5QGXSmRb@P6w&CK+%AunFQ$SZbT#V!q$yWAm%8Q1@GPGKB*AF^HVyPqjkM+&
?J6@e* <y998Bmc8B!t8e:!1PmtCdP6NFup/yVn65i?mLwwm*bKIMTQm+#eaw^HQwXBShwRWnDw+$RhyRK$I$*p
lRFG6a Il%Y<bYiQpQhJStZ/Il@\mmSJ&YKV=*+Fl/e1^5uJXm>M/pp=SyuT5<TDPeCiVQBnJaaLq5^JJWp18bR
A9kXD^ wD4cPGYmK<mm#SWT#DZyLC4n+KcKIkXGHinibXyb=a$hEpIbnHe!5y\$=p49+^tlbw%nXLLnjM=$yRFq
-ADV6> 000f36b138500110333 Page 341 of binaries1.zip
pD6Kna =&\$mPCZIBbTtL#p1uWY5C1LN=wW6uaYJSD\ZkB!CKP%mA8>mXybC^1D?cu>JEcqK+HL6qVTAjTQGGlT
PTCJ!1 9MGtFnuye%e@IJ5/lpWIwy@TEKydDQ$wbhkd^jKiy/PCV/5Y8pk&DTew%R:4pIKE=VqC5e:^Ne<yuFTu
Q^1aiY /GQP!JYADPQF4=PiehX!*!TiK4CFQ$*1bMIm%VSF$^w^lC?pE!HyuubS8FZ/i19Il+R8STd@lS5$LqQ%
/cGTYF VaV>w#/:I^buwGD:Mw&W!b:#BhAXD&u<t9L<HdI4:VQFCQ:mVCM!nZuca5dwdnbE!J+Rt!RwW5JXNuan
\ca*>+ !J>P#j?4TP1@N#Z@5*XN#GK5HD?t8eH@qVu:j>Xe@c9d@=e4@<d4@:GZ>aj*@Sj^nl>Zi:mC*aM9dYqu
4T6An? V5LB<@i*QJtFDJ%N@+JqX4G$NZXtFLK*Mju>=Vn?c!EC<D@iQj%umAD<V&&cS+WI\Q<Ww@q4bPD9W\q@
ZCBh9D tKV+!VRWD<hnI\M@$aL>Cb44X&n8^/Bbj#HQ@BM6&D?mPZl?Qq5L@wpY:E@RZL>C5#+GDYd@Bb46MYm&
:L%YRD Z/HbH+H?Mdj=e#V+MYlPqq?kPS/D@pW5B<#!GK:>EP4=Pjw^ZGQn@lZ/MX#:=X\9tPW^bQ9XjC8aqiXQ
kVhG89 wXu@FQw^bGQ@SRMH5:L@KjSn!MdB@18Te@^lV9e@9j#nJuN@hE6kdk+TMD5uCjnBl9*up:qkX5:jV?d!
GSYVtZ eQ#up:u@/C=?VPcCYj++tR9?q%RJn^YW+91:wBV4k@u?8/AW/$QV@m<JTwG=Pdu@q?yJYRA/@/@Yp$L/
*q>^hH nb/WjIbFkCX6:6^6:n*ASZ#%4yV/L<qWm&#Ld5Jm:!!H4qD?bi5@?8?@i8S@:T!j:$hTjAJH?Zjt4i<B
p*YHaQ bPV*kFVu@!$*HYLQ^BL9YM?ib>l9?$S6dq@S>4\8p>N^H/5?VQl?D&lP9DY:>dkj*eL>t!KW+56MT>:T
J9pAGH DI4W=Lj1<kT5DLb$ITVaKZG5@Ei?!jiAuZHdl@N&W#19/>QQ#<5/ZyFNlMXup?VAkJ\Y@H1P&1?>mRh5
m+Y*4t 8c5@nVA8Nh4ypMm^JYCMW?XG\I=BjdkjT:kHBN/W*RQW$8!@a:H:@9M*K#HDuLdGX?9cX++MYMhj<@LR
<e%X?j Eimty4=E\\$84\<FS?@S&VNt95%TBPcZTWX9>^I<8WISjZkR4uW*+jLj<^APTMab<%I+\&&tHFA4F\y:
&//e6t FLyWY&q/Y\dyQBVeX^\?4:>yQc9Pj#QAFuTY96Q<@u!>P*RC^HHeXh##t6pP:?5#Pk:V8C:%AJJ5j/wh
wM^G5k WT6?y@pw6q8+#H9AbPQ<uWni#Zm+l6de:M:$1JbRuJn6jp1&Fc4/8>aT4Qe+&Hhy>6i8>+Cbdwt<8!9=
TEDT@1 <:V#Xjd:<d>ZJQ\RBbiV=LtH1ZkMB^J&ZwXcZJ!*JDq@Ni5>RM9*8%HDQTDQ>=1t?>NhJ6ni&KG*I=IY
HuAm+K c\*XniRipG*kEnCLc+LuQS4@^DR?qeyBH8>G%pu:A9Dhhl#G&@Ii5B/^ijj8H4CZ^Z<@<ja9P&L?6kQC
KcN*in p9M%1y:XNL8apjS<Wm1tW$=>!TiY>*yy*MRk<&cCM1!wDIi<8KjVHVMEbdL<m\Zj8G:G\&w@YI#n#mb>
^WmQqM >E/ZiT9j$b=D&@u?1Xy!:5!1ybXKBm5tCc$iXSB!+J:d$QqVQY6Ka?TTRSakClMqueZHG/1W9N\Ql^QZ
8k4iK! cZiY4ha&^#91&H#Jtc>\!JX14lY48\4lmR@dk9uQ=u*u!?//&WV=9+*=Fm?Y+cd^*$@?9bb?yD9:eD@%
GVwMe! ><&H&<?h9@9mi<GcRQ5*d4w#T#ZY<c1qQh8Qj!Yh=t19/u:/Tq>kkXmPMuhCmd/81?dy?qClyqmd8nVR
mpmR4u w:PW=*pjyYCKa*ml9%>iGHtPbWCuTm%9wua4a!SdVk6eGYw*S*Iyn/?d=ZD#/%q?Ph@:/S*/k8*89nJ>
>?444b 1ZkFwWTcLI=ua1J/Z1l^Lb>&IK/b/#w?118Nt#SaY=!%$<KuVTTq6HLE^5YBGA1d<+5Wdm1pT+VcF\y$
RSMGPk GTw@F5I/KjquiWCA%i:pi:bcWc$q\D*NncMNElTtGtVIPDVtK8J1c5?#nkk5K@L=+h8p<:Z=KnD!MkYT
48uwCS 8bJRTFYS!NnJYTL*HMYjw9i9BHbP:hDn!$6QXAApcYQn?XH\SqBX8Dydd?k5F:$aQmlXS$m5!BK?!WE@
=LYeM4 Bp1>X\!tC\td4@Al*4%=i6/H9jYP@@cwwWXp?^=\GD^$ST%@D@Bm5l@q>d%ih9aJH:<HLCKtueq>8L9W
ZkSHk? 8S<=$M>$8Rh<c>?+^el:1G6549<A:BCyY^e\b=EADb<nCd=m\:+H!NdhNn=R#ylC?S:kVZ$%hHX5m/FZ
XS4mQF ZnHt515>^L6i84epESttYF>bl6HY+NKBiY1ZEuNCGV#*KRkZS!m>Am1M\iP\QJj:i*64BD=>P*Iun91h
ZV:S\c hZjZ^lAd@BkPA%NYBA5t8RTt1wwLR5aY4P@>/C:mSkt6tZZ\iGuRAiTuVGlpkT%Ey\Iw#H5A#5\>aIB\
Gt^?N* <!bC@*5b@a&^<V&A+eYHE%4jnW<6^>G^N^XjjZ6#Hw#kTW5*J@>Jn<iD:Zy>b#*\*++:>a&!<X&QPd$V
5D$1uL bd/bj4B<8^>Y<at@G*?/B<SL*\M+%8<B9@p@?a/%+ph865@jRT&ui91Z*V%*Gwj<c$4*kCEQ@Z@BLTGJ
WGtZLF K+i1t4#HYR6nXMpi/Q1IN+JS?>AudhjiA?4$d/NMIu\Q5?<Btm%/+lVQni8qucG8wLP8C4i!V+VTYW5A
DFECa< nM1CT*^8ZZhqbbKEE<:!lJRlwuZL14Tph@5N#PkCl?Fce:5Z&/Du?c/*DaVjPR@P4\$@#>Jj/@FLF$@4
K8F$Z: ^?#M/QWNW!Ww58Y4EWALB/Luj:Itic4ikaH&QS4lW?YJIq6A9pLC&%Xk##hjp:JunhF%u?@H?TX8BpeH
>Rd8lm mA8lmkAWh6C*KW>wIEqIQmkqQ@ZJkCS<ibGu>V1piqWkR:=I15\6:@8=G5jp9IK=e@8klFCPWnBp/wi1
?j>Dtm Aij86M5q5hlB!&G^%\plEEy5Rcp5q>>m>=LLP1aZCdL$WjqEI?XMX!mj9+P<%Zp9jaRTPyXu=Gktc@X1
6SLt8K XJ^Gnb:u#RK>@hA#kKb/6NCHTN88q?N$*jQ1pqu9V$Te5kJHaM#FKG/<4PlCkq>5!ejkW:w#$$&qVbj+
M954&: SLp>GCd#?+t@tKWk+6>dMAbBh5AAQ8wLcKT\kc8cu896=4%F6j1HhqD*JY%ut9k\>:4KY&9%>t#S#d=I
K!PF/Y ^:h=@8BH\6?Y9^#B>T>HZQ#6mLTDwZQ4&G@#*4QNJa=*X@aj8TbL?Shq9=u>PQ9?*<@?N&#69=:>u>kH
k+@PIy M>4!<\NbX^J+QTQWcuJE&b:>yPpi>alPl1T6*<KamcDK&q8nJ1?4tHqa+pnEN+@ma^ZkE%*YjH=#8C#=
StkYba nJFM$%!nTTYkM5TVH+5a/iN^=uV?RkDYS*S#wn^/Dh%F/j?Q9d?P1/Nd<5ZlnSPCP\S*%+&:8:8:8+RA
uS9$>S AVai*J$p8L5Vk45Gh^KewMEVhP?Z#M\=<=\=V<:p#N#juZ99=@$H8u6*4dY/X1%cXh%X>ZZb4/4%myE%
C\#^pD EyKT:d5R44Rh=6N/bV#j4Z1dbJjQKXZT$e8pRy+$H#Q>paEAYwIYV8e+9FE\FkCpI4S4eX@Z:Z9J>XF@
!ID6Tc lI\/N/p>LWauRQ/N4$:^</jhajH$>w?d^hVydV*Zu51QjNb4qdNlupj8>i>HEEBhVKLK+%ZPEe>S@@HL
#k/^D\ YAi=&c4KyNip+m6eWZ^WWjKy16m+FK:54!=JQ8AJ9HET^NGZw<&nh&cR!!8<#m$dnb:\Zi9^=#6?=qJj
h+EMA8 VCBBQQ1a#C5p>dSSd#tBptw1#EdAw*j1e%M/Lqj^MBp?/iN\MiaG$B8cyXH/M+%X\uZd5TdAw*lq#wPJ
@=5X1\ $Za:w9DGI=Y48GZRq4?u#GFtI\TkiAYTN^aBLhDHCX6hR5eyWReCNJP^G$9m:/hQjldXHhq:=!Z>W5=S
D>qEC4 V4S!9VZ44c/YLyaRWk=GM!Pa@JL&WleCGM:5P8^$PWjIFMpcAp6P@C#DDI4\G*qaELtkedt4!Z/R&FQb
yu>w+y i>Ikmb!kid@%LXIPEFj<R&R&8GIQApC@Vd/6BP$w4q?d<N!<Ge?biNJaFNaRRQq6X:?\JhmB>Cj8uM:E
6L!/Bh j?kK:di/k5\ekQ:R&^du89E/*G5IRHc$ChBhGV*p@Ptd\>YP!>>bTV5?:c$N#$GXlmJqTQ!?Cep9AQJu
HtJK%^ Ypi%^q4u6LA!8j4TLNAKQI\b:\q$Y&tTZyJ^JK16PyyhuNSqL?JlSjI>5$jTtN?n+uCnq$@1^C:tS&Nh
!c%&D+ /RF1XF/tS+eQhG6nqE1mqyinwSeRP?SLRTWYb8:cTRahw1N>teK1Z#\8JdaLYl*nj8C6/1?cCMw5yB99
6u\dkk lniKS!1Dcm/bncwP$+w%*k&MLRcFWeLFNFAhDt%5u&XAAPt?8!P=Qa!AGXqKBi?1k1$=5\M<\V8N>H+/
nCQ@Jw $S4nId#GGdMG\i$$ucTaeDq<Vl^:Q=1CZLQl%<udPj>8C9/4*M:6++9>??IDPHSq<6QEqu:YN>d@An:$
w4Bd^D Md%PwtIZGPy9K&mMNmbj/GKQZA8\PFlIiDR@py*QDa@=W6pelBXXL#&WLA5HI^@q9+T/nh:!MDQNM9ye
I*w5$T TWV>:RlFD*:Wb=PWG9Y/GkIq9dL//\HR4yZhY+8u@d8GIGWE+//$ID<*wT*k$lW>9QTpp=6$@ISm!</y
HyqH?= /tyCZY<D?J:8JQWhwnM5j&Y1TdVV@jd&\>B5MRcRZ:1K+qQSJ4$6Qu>\d4&/TwTj\&!@8e!qk1TiEM*5
/FwMG/ NVq65e&G$^^QaY/DuI4GeiA#&tLE?E9WWXXFjbdcDWB@%d5AZK%E=etykkw$e#T@wwiBPm<6ySe/%m:%
u9wcQ^ ?VPF^!W8Z:#=H:iHAC%Qky1GETZWeXGj^bFSAI5^S@yqF#T/ihF!9@WDLDZ$E>\FM4>?$iyZBd:yiJI?
T=qnaq 6!j4*QH@>HQ8/Eu$TTJPmj#DiluZ9I&ZLiLE5n6I+B@?LSM8Z!PeN^T!ndC$5=+^>tw&T&5MSHElynjR
ReZQ$m E$AYZG+tXS=F:p\PY@!EK/=J!?<e48NNnk^=#:/1NLWa4y!t6$<KF@k=id=&YEI=&h%>i&t+CmimL/8t
YCjmSP q#lWZwRM>aaAL/D%?RQjX\aVtV6eVyeAYn5Kl*8bdicJmcch8GDbbWRIRFK4kB#+YBZGKnZXjyquPPJl
Ih=:1a pce9QXucX=14MK\#E$i^hyJ*M+uB\Cj65q5K@RcndkdEA#^k*18QY/G9!qj\L4+?ma:aq5*Z4JC%=SW6
Du<KJl F!%/Xd*#Fw$$BRJkW&#B+@H%\<Qn$a>N1^D5MtlSX6i4/p$qa@?m+cd?lZKh1NQwaVLKYFXjj\lhD%&e
LJ/6St lR^JZa+!I*!d+uRW8\^:X!Y1mc6ClDHAXKJM15#+kF8uB1X\kaKt6TYYtDyP6mjX\9XFjNt5jY!6%1jW
k6G\Cb &#LBeK&tbp\PWSI>b?cm=LpwSt@LSKMM6?9P<4A*$=Gh<djXF\l*VXq$&lLa:19=>ZWSW&eJ*P5/!w>q
:&!LDh 5=RcAhw?i#/Y:^XppbQaZ%H54THXqT$dRq%bmP^1*K/ChVij@LAK$F%bNqlL=F*Zdl#yuZ#LV>Sw!GIR
EI=^TF cLVp58Yl4k<CpNPGAK+%iB:KRRKkMTKS1>TjJjI=@/h@L#%aID!yi9<GN5%neEYVH96<mD1b1dI8Iyck
<SjjY< i6aq/*HylewWF>%XLEj9D?Y*TmZAmXECS#*T8Xc:ibP=X4mpWHjq%QXcZkp\+RIEwHJ?X*Q1D=wJmK>A
<&Ju#@ aJW+Anj^?d:QESbytQ^FwXQkH<9*@iX%GkjQ#=h!@@@/H9<D>V$G^G#@b?y:pM8/d<TEKAVkV=>+iH@n
-Am/ia 000713c1f7700110333 Page 342 of binaries1.zip
FeDlKb l9F\ZEH>lt>PBAhV8ue&P\<n!D*4ZQ1FV#NQ6JhDL1W\AL6Jkt:9M*eR+IBpRR#Ry^*:WqbXeL+k5He&
ZMBje? uFtnBhnhW+ubR9q5DKthClqk@1L<wNYSwBw1m\ibH9i6kHn+e!$MDItih^NTahBn1m@CeHbF?b5\Zy6!
%94LMh N#6yePCGi:%+k<eqIcw?5@=1@*l=9c4^yS>eZuR$TTuZ8/ShGYXu!mDV&EjNPYD44D&/y8/&@VtZQKic
9$kVKA HmiV1X1+&XKBYRT\?k9lVmkM<*up$1dTB4iN$p=tiJNYhHRtQI8T+@Ie!kIq<S=?tkL6uyp$P>WZGBLq
W:RWK< 4WM#\GX^ZB=<Z9:<#A96tc%QqXQj%*mhwPV%iuMn^jy/+qc>HF9mEya5iTQGnJ#9*9<wM5*GhhEjuRkL
IeYZm: MhihEN4M=!Q*HEXZc\uy*QuY19%&!Z+yB*<ql5XJyJ#L&+qSZ@%YY@HdYS9a4m?WTQu%^BmWE&tXR^!?
/i5lhk =d#>ppN$<LHQqjQG#m&nnL>N?l9G*y%*y\KJL1<F=^nkFLX*$b&^tc/^PKy$#V>^*lw+#4Ra6aeFc5%q
@#u=5% <?pi4>NwiN6eI$#4lhZLhGL:MY9JBIFV=%/jt$C\5t+!5Fd=XI4P+X5CH94G8ulpeId+Vi6jLPdu\pLF
jX#lw< 5HXct<BqdqL485C69=BbeTEARkjai!F&!TA>LCjJl4K/Vkl>QWQE$ij#e+t+IE4D:$\Vj\^l9N15:Mc?
qKGwqT Rk/mMD\bPKaIM$#Gjm*m4CkZ&qm$Wa$ZTAdeT#p6KAt9ZRw?e/l<S5ZcwNt#mWZLDSXyLGn%bT=IpeFn
!SJRq1 4JiF@Y#DP@%aA\/bPL^niGFwYY/Ab:>%1#@E>GilA=9\ND/?DP@NLXe/6/qdd1aL<^CFkqW!B>MPcIA>
e@W#:W !pIEpEQY54BpG#p*ZV\M*1pJ9XVWFBtd@^ky/8!\@J4NNXMB1CH9SeBA&h8yPb4B!dc<S:S9i1F%Wc8B
K<EukV St&ART6aml>CHX^8q9WtJL>LI5NVZh/WM^k8&CNZMRb^nI<H\/1<eYe<tjLIX\HG9Bw=H@86wbReGw6P
ZH\d:: cZk/^hF4c5M=VJ\N4JXYPqTw%HmiIiH8h%mpWb6mL/DuSdGyJCm<^9b=ESCmpuRh6NLStCi#jCp?9*%+
PVlh*! 4c*MV>&*MBWiBiBR4X+d+d:hRCbpPp$bM/dI6JeTE88XSVJLjW>*/YlDQJwLP6i:$Gmhqqyhk*<J9+XZ
6we4iH w/F=qPK#FSliiqwAj&^9E6Jkn!RW^ACnZHA\dl85TnW#umwPWXJZ+a+?*5t?<:RuaQmaRVN^Yi@BY%QB
MN#TGk ea/c1yW+QlyVc9J5IP*d1GE=$9Dw%:LS14QBV4YhPc&iY1=mctmQ=6=q8bnGcu8GkaAGc6HybXYQSE@@
ayDTTL J6%5*Pn*hjhPp:InFFlMetXBd^G6<<6jeCc>/H8>cedKB\QnR\Th=utTnC9p&5<dqSCec/@Z9FaCI#Yu
S6YFdX !n!#X#k^8C4JNY!la^+d/jk\W+En?u^JqE+^SuK<MP!5I:aSW?Cccn1#?<5LY:*^RBdMb%Iiqp85!C@m
RAWR/I cnMYk=>*&4DGE9I^V1e6N<=%Rd&Ma6RMV^!y<JH:?9JV!8WwJe*49jWkPNlce9G4#<$$8^Xa%EmX%>$/
WCcICa &nTIYJTt4&L1P*kNbnFnNcK$=wS<CHGPeHK\LT*F6w+4DkpJ4KLQHJG&u5F%1#uSR!tt\LQF=F<e&J=J
^STVRj F9w&=8<LJeRRT9C?6I$jdZ\BeCLweVCH>+FC!Rk8XA+1@/K!VJFchc?IBL%B:#b&91qW8GL\*NNQNZh6
P=c%j\ a1uZW#1wF/>\Jm6F9Y\%BLqb^ZK9!XhaZEi<98&B>+M%>Y+HDpYKJ&ianHZ$qN+WE81+tuEb=ZPk6iTV
P%$LyT +mL4e=JB#dctGC@*I4Q<T8&jyc&:CjRt5#tN1tnGybnEh#IC1mTk\#N<m%htAYb4iQDTeY!ejBQKyawa
n!WwbX k8tZt1RQGk!Ek#*MIFTNGqp</I1b:N<qTl=A19n+91tmb/>V1cqFVMJE^8Chj?akkXKepc6NHRMJy+N8
?NVT%! ST^@4p&C@IlapWXLM1QMcm\Dnp8!VuHbRWNVJjja68&ZVN%kYXRE=u\ma?SS^Y*eANuVEA%S>j9tjy4X
aZS+^D TDQD<bdqaaP>NXPDbI<qe*Q%Yy\aJ>Qh=4Yt+d^hFqBSd9:<WLj1C^mFD>^Bqik15i=IKEpQM<k<4lJd
Xm\eMW tddI^9AnSEe&Ldl:*%$>wZ6^%y?yP4FJdt!VbB^@tNlE:*9n6uPZm#T!<*FCIVILB%*@JC#XIi=46BJY
:EtwVD 4%@G!JQq!6XZ%=h>\uM46lSuMah$JV:y4+ci4=D%EdPe^c&=Fq?<1tc^aGYNL!6#<9CNDe/GktnbcdS+
%?jQZL 64VqmHeP<5KCXbE\1+dIpeeb9L!I%>9$$<N*eYXS^@1A%/T<bS&^B/@+VV+TbVE6CSQtBu/J84y!ay$^
nmpQeh N\pXN8!huGEypDNPPZ%Zl/Sq*#4>kaB:l?>%Gdp\<%KHI=!jBmkh?^\5%W1K?&n!EiIJpu5w8It5ZVQ^
yh8PRl n=?e&G5cNPcCVTk4KIe+L&!YX49R:1\i8B8n4NRmyn&cm1=dJ6t^\jL6?t/n4eNaiXikjN9/B1^XKN>F
6+Ea!= 4H/IR+Fq$bbXj45ukd<Zt&WaEj1XG5uA&e6<iCtYAXc1Q<H%pQhW59$bR#bCj+KD:TiH+5/\1F!iuWV+
wKa6uZ !T681+%wb14RV*8ZIi@lTk8iSc!+8Kd\TSN?bk%&aS/&nXy@d69?!LkSw:Rnl@kAKt&LH$/SR>#kL5PM
%dl%?Z R5?Qb=FC&y><V15@c=5l^&^+*>&HTl$^nBla?LZ+5F^/yDVtb1hjA&E9iKV\I&YuMcJ:wJY%LJYZVXWR
lZqGlJ =w:uFR$N!EI#6FVhhSkXlIlyXYL?=5$S=9A4#P=B$PFMIPNb&D:V/!LX5IP$RJp9Xe:6@8jTAY:cFG48
6PLl<5 XWZ8%jdLtMNM\Y/Y^w#tWX@*aJG5RaD>*iEAZ*bp>lyC\*mT%!!jPynyV5LaFw4^c$bVRm#K?/u9c5+H
>#:YNA c%YY+ADn%myu+YwLL1HB%iHj8SXLT>>$n%dME65:e%u6iea5#M4/CWPdM#8GM\AMQ^Y%%pFLPpX&t9W1
A1LR:A 5qnCM9icCw8/J+@ly<L>@EJLd4+HH?lMK@Eh&bIDdmMJyhAWFlCB56XQDk*>=&a#*@@T16e<bQ@&cj$@
?4+\I< KaDNR@b9*>9@&ek^+N?YqQ+uR4tAj=@6DRV?e>uiRE/?@^DKBYV:5%A8+J>W49:Zkj>NPBZ9u&j%Aj?p
nN?WSa e9YjWHQ@my4#h/nbj^HT>CiX1@?itw9nF*Emj%K=?p?w&Z+Sw@Iuqc9@ul4I?!61u6?l=9+XNi@9WHQ<
141^M% m8h<9$HN#9WLu9>J=i1@y@=%RBVu:\ndL+PTPH>H&Nl@FaZG!jujwkd?6$dP>h?m@m%l?$ZbdCDud\ud
/mBtZd L*Kqkb!<@!%19n<L^94HdQ@NaK\unjR#y@YuWQ\Md9!NaK!@4aT6?8@n?EjBYH>Ny9&ZaC#8Q<t5Bj/^
KNwj5l S9b9B&N^@mWam+Ph>/@BYB^Q*Q+9BYP^5*H?ETjuj!Ac/^6k=j@ycC#WQ$SnGi/*<Z:IRBFiid9/PE5c
^GI%4W CRHRan/mFEAA<=&4aMplCAC+>:@4hENk>eX#>#KH9L:ZqI\CMpT8=J41EjwN45TY?Gm#yNj$cHj8Q>@H
JGi#<M h4BDAPwJEEAJ/%%b>m?8=$Ct&D>tjSqeMSm4aaANl8PR9&wAc8HRSP&<=j$\+=mQiGc:MF8kmaqJuai>
G<!:$l E6N=R*1IC\Fe5/+?VwEW%%XdIIC!kQX9IZjYh&Fhn\4jIRBQ$qtiPYaI+NCp=V+ZuLHRXBhbeDea=pLp
9h$n#8 Ly9w<j!=/uAQjLj*Y?N6?ec\:unJ=nS8w5Vi*mae!kLYmQ:PQJiukV%&jWc+t4l?D4yLQ\H9m^T:qK+?
EQQ>Kp QZ4\89NH5WhPj@F%eNE>1A*6IE6AmHh6!Mp6j:Z9MJ#8kh#5VDZ^LN+9NmB8FkLaVTK>qi%k@db+*:X#
Xy@TQh <N&@AVK>4&N!14l?u6mq%@>95X^J$C:h$CYHDa+m&%#X4AenD&??>S=>FLlq+SPu!695TbPYWm*bSk/^
lBWRmH b8J*?tEKt9LNKec/C8$Pw$#+1n<6FWD45p8:<6G51Ku^dHWAPc#IW:YKEWcdVLZ8cFEEMyQ5W$jp+/BN
!ij1MN LW81qh=!T+8Ghn?ie=:+>HDt84*WbHBiS1Z&R&XFh6IHaM<l>6SI\cmpkW=M$jZc>SdHikXM&TJZ%LLH
tp5R@L ehJL4Ch?$Gwk:+G@wh$Mk4beI5$E:\I1*HRHNwM=4BttL@d+FP8qu*85d<D=IqqeQZJ@Y@F/@#1bqmbA
<68&4C *5hQ9FHejnhktLVBiL:Q<E>Rhth#D1H*=X!@%^XY%9NRJ+/dl$YWMmTbkcw1IIA^/1=H11:H=L*4J6C6
^p8^N^ =hMpF/bDAQX?Z=y4IACtNAnkKkpC?K/T9VD@p>Q4+CRV<Mmq:$4ZR:$BBDCnAAE5C:5a/EAAcR1kP#uR
Z8ikuj Qi*EpV$EeDH!>DB!4BCA=Y&Hp\qa:$qGD1klkPMe4AS:LI&F&SQLdYQB4>bF9nQNN=QmS?A1L=ML*1it
qjN$Nc 8F*?@kV$J:?AIHQJVW%>bVI#qbt/cmqn1tLHM9P%?5aPmXE!Lpk\HdkHR+el^NeRAB8w<&p6FZ+RPR^*
>#%9V: 1dpNid\tjcV?CaVK/R<cJ#$6jSwYm<yhZ9aS&BRC<Jh=G4M:cB:bM6%*dc#Z\N6TQ&Tk?t%WYTtR#a8T
WtyJF+ 1KZ6kp+#tFy6/9pHAATRVAA!8WT+Q^T=W$kGq%4jRRAbI861V^\^#LtY+Fq</AHj^aPVhy=YIEFu%^:c
b</>aH n#uRXV46w&w@8A6E9ad:+!^*n#k@$hyPQlZ/w/CejMl&w51Dueej$bDuZq<Z#+E:d<8FIAC$w/!C>VQ\
i:EK/Q l@@PMYVl@h^4MPpmq$#Z=1PH=n>:!JbHlVVH!9\A>Z#%<e>\uQ?AL^^jD%wRKjQ+/\jjdBHI%L>DitaG
Fum$Fk 4IIGcTCA!KG@\!mi@wh6#D!%ERqD!RuHAJ&qYpcdK#I8/H:Ae<u/<P\ue4&/!=:?E:NBi=ZKQ91jpi6=
&5Fy?# 88uX/\RTVT!yhk*Y1u1yyutV/ApT$C6D5ZeI<&K>GGRW5dK=4i/hIAD<dDA6ChVj\cnQ@5jB8Dcj9QV/
c:dJCE TDG!4R84<Lk4$4+uX+RSiaQ:^t$SSkp9I$tc*n$YZd%M6ClcE?+XTW/ak84%Qy9Z&=dDBydel!XbISwm
$%9>L6 Y=%k:dh1*F@H1qR/JRR*8nLmu%djy#1tpbKIBDWTLlQ%p4Rbq<%Rp9T9QQjkddC$&KPH4<ud>hQ:?F5C
HQ/@Np lP5S$mTEQTRHXL>=yy1TdB@^TEIcE^%u$5?u&$qHjcX+FJ?m<yDtA:q<GHCG*lTL$9bnlR&KeD:*Rck8
inp&>k >4^G*EJ*J+KKweTZZY:Z%EG:1H5?q/Tkl$pm6lKIVc&4GbWk>mIwB#KZINVelTTHE>PhT&:^?5$88ZDi
4mIqc1 #5pIpWaR/T6FdY?@d6kpMWFHqjISHB%#CX>b@IFXy$?cdn:BuAV96@lEM*!D&Ry?YBWRE\4*=dlh<q4/
A%5QnW t*!=I+K=JQ%T\jGail#*=u^\WRQ5wQI#!mJq4:4paTHuk5dqu4/H&@#&$Ty>!6Sm&T^P!9=T?SRae6d4
*AI>+u /5#eiNABhHNqajZuin:!keCG#u6&MPPAe1Gaqd4>AN5T9I5Q<E+FueJI!nK5&R1@:E<m=iC<iB&ST1j#
IM1R66 yt>+S8Ie@t1aKPqh<%tjkwnJwSeE<CRe9pLA/#9@V51ebeDLM@#/^&aIIEaJA5CKl#KEAIdpl^:%84aa
eVwy<M E$*?\#wM>K+:5#D=+Q4C*p98\D$FjCM>HXlyV!%wIWCjT@Z1#1%Ab#bGSQi/P@w&19d+c^5EMPCWeWVw
-A5Biu 00083f9379900110333 Page 343 of binaries1.zip
6pK/G? #hSbSt%QX#e<#!ni+%&&K!wGHF1^>?KbBiI&?NcZ5MnDILtTG=RTQ?9yjJ5#GuD<=dj@Rlb!:6^B>QeN
M^in6C 99@?6!:YGZ<?9?!e$YR#>XwLA9CL9!E>u4nYP61QkkA1HnM:!:6Pu#aptMhMB&j5ijM<apS>EDKwlQam
dXi^b< =!QQH@:TMVK&pMq<!//=P>>+uuN#wQ6E#QMk=e+IAeT!kQ/\^KH+QYCl%TJ!Z=cRZ?\khp<hNCjpM=Jq
^PpHh4 FtnFW1X16py!TbY1%d<dNC9Y4TkwSCwm6qV>mCyLwDqd9QcJC^nLSe:&*HJDJ?:\YWtaMmNPYCHtM@NI
t1kHST 6h+WK6T<1L4h:da6eBcI:8uB:B+K9p$eqF#Ej?Ry#lpXQ9:!==elW?@8j9QYZ%#8$Z1qmnAG6jajliAQ
d8hT=< /mmp:wdQSj/m^BTW&8:^bFa>5ZWVA6kdZ?9c/4wB*Vd\5N:WkEuBnlNn+Cht9aEA5nu@X>:%yQ58@9h$
6+Ijbi Pw=wQ6aZm>$1?MHVTq@n/T:8*>GMRtGjS=K?e=I#+k\l>n!tZlZaw^ZFwh!NQ/p*EQJ#tmw11/HBATwM
5y/Q/t R4l:cZcKc<wVVVwIkG/L?:%=<HeZcRJhVBlyT^PXh%K!W5uSlK>YaY1!61#WehWNajCq>Qk+H!PPCE!4
@u?X?I @jDn@a#Z^%*ZQmXR^eX5uHQWqPkaE^XA:T8k1jpm9*cwn1TW4ciQGWWmIaw9=NP^Zp$+MLRpMbj4Q:u9
*jW51$ X*B:IV9AB@LPC+RYquE&&FL%!cMNXZ=:$^A^:!M%Z4jdA4m8/ddqj:>E<hYIi&H\yK@S@lSLI$^Ml9&K
?ylCt/ T49w6aZqJXJBct#MKMX%l?!+Fd$&4D5VuA!$t$KX:aypk/^BTN=LEcVa%ki1PkAlX+DwnR%pLp$pC+iI
%?HBeB HE%DJV4FEI1M4jL6#Vi$PGdl#mp=J5X/VktEBe96*mAHie%cuEFDu?VDWSLJBPu^\*nhdljq>6aLX+i#
1$*^+I a@/*uq@MhYuVQn@KD%C=N1nbnY46$Y6wmMWd8c&aKDK>SWCjiTAT<!GB\>+h<%JBN48pEnSu?LduEwdL
nAVF+k 6ie#^%1<^wBV*uimkSp>RW@ZTJtAq*LX!c8mRZk/MPpnJdytu8RV$Y>HMh#pk$ut##>5:9HmnKl6Mjj\
AjPI4l 6ZtmR=i849=!qw8YV/%+cC/S\?VYIX>5?I*AETeE\QjALp8d819qXj+8A6k>>u$X#M:#wC#+J?dA9!6R
q!H%ki \BmV1^nXVJaMkdW:FBBKM%qMI$!+aIB/jGG^64?BL#Y9NclDhI\\YJk9:#EX\T%YTZy#\\+CpF$JnBw@
6I8KBj 8Qdc+V*8e$n8<PPI!lRY1hF>4<:WH+G9LTyPtYZ+#V+R/eb<i8t#4L1*5^Mc=lw^<^4TBZZu^CeIAMh>
Am<!Ae i=cXHCDDXdwq\Z4HtIWDm/T>dc<=!*VRW4pQ:mm%6La!e>!aH:aYMQ^BWeJ+bVT9i=j&M5A9jq/@bC+Z
?*b\ht hHQ#YI/$ZVB:tw>cN&GjL+w#NG<eC6WQLX!*&W!XJVX8J1=ku&iRFiSCBlZ&T8*/Zij$WHPt>#pVM*Ni
+8a*SY yB!FTHpLaX*b/lEJVi9/NJ:BkwG/:Jbee$KYhtQbl@PlmiI9c/:ZJW%8^PI\nqe+SF:RZ@6EIA6J:&mP
pW6uqu a@ickWXw<#9XZ!AA9Y1l1>Xq^pMq?:WW/jqtD!*+ZNK4GI5DQA=&t/TyJDuc\<u%tki@K/+%m*Yqn5V^
/&:NaB iK+KQm9*\Zu\VB#D?1tMYdP/*T8*Nntm=1ll/JIZPkCAAkDRYn\Rb?n4hK!=KXSc+GF!bWQGlXm?<NWy
Z+#enH +/y@X9bD@P\&e?tXpnpEIJN\jp>4@/RRp+TQZ?%uh$y%GBlL^d#64KL&\bTnjKT%9?A16y1yuw*Re:IN
HLcluE L^i8IwhbAlXi4Sa@8*y!IS^?8lA&V!=EnQccjcJ!pwIHVH=YQSN!aV^k$K9pe#DiTe8D8e9NY&?p4&B?
+mhlY1 dbHDCRkA\@BJ$&\4=Q^lm*u?#Yql:<64L&4J@ipGquEai9%+N$QELK+m1Nbh\S#$c?I9lj\SE\HMaA#=
AKVd/w ZYIEicb9ylZDmItQeu^5VEV#H*Ve+h\tC?\8CP9b1RD>a>R18B\\^qw%qI6\BkbTh8nBlGjI^#CaTpa^
DJw*Kp d#!?4by@<Kt99:T!?9ypyq46na=NyKbuM:I!41@p!Jl5Bqd@&pn>chMm#F\4?C6QjPkn\nPP+e\L*?L4
HQ8Rd+ a\!5GeGJqn=<apFj*w8FZC#hR<KCqeISeDbX%LkaS6CLWtuh!j!lE*iZy5&yX::&dS@mbLlN&>m$aqQ!
=u\JK= BDPl*RZZwCY8VwKhZJ4\5qaETtEhYKuNeeI*bH8CLJ4EWTK1d^!inPJ@Maj@al\D@t:9t9*dWR1S9XI>
MJGp*T Q:e!Sc19V^BdR^ed<6h*kaIAaL5YiicL#$nQFB+>@5EXLE@d%ikwp1+A:Ti@/^>&?\i:!Y1VKdb<ZFN!
pAb^u: ll:ddwwmV^5%Xjbh6#aS*<9TH&j!?Nhuw$hTP<i$&8:h1athXJnJk^^9:F*$9hbS<#k!=5b=l:X<amNR
wGBQ/M XKJTj9RT<*<HM>NM=$ZIt\eV48K<bCa6L5kclWE/%Zj:*mNTYGN&LX!QRLXXyE%::^ewKM856Y$$\dmy
GRQ/jC !K86w#4YcwwwQMVK!5*w>n$b#F=!&N@\=AbbLjDDVJdC?4FPQWphm@*RA\S\Fk<BAK&$Sd=CAKGk&\KY
%1iCd4 PklA=IETAykk1CC>lAB/SS/tW=?5wS\\^6PtGhQ&X^L4T6ApBIAIAX^Kc%tARVhQHtRY^@iqEFXSW#<^
u&ca:P HGL*Yy#JB<>K$H\&tPIDDkR\tC:!S$jyJ!hl*wnZ&Xw+iAqHc4G:648?Sd#^u4FZj<ePAiR??TcbV\+1
5P$@=@ 6<yhXjaXT6iq!CQN!M<A$ICkF9DV?myeFnq5hyumlkCi>6t4dNyH:ap:?QZdHHC!=bMn6EVX8:BJVyWR
<q@>YH BV%@?^/+8pXh<YN9<1ejStw8enPae++S^y?V/cqE?LJ=4nwWm@<bD1@59L4<Rtpqj%p*=iS:Dc1k$1m+
k\EpN/ 44b5eNt&!K:b4RDwB\$e@\LBkMnPi\P\1a<$BY^Yk4w9DDIEeK*C<%CJS1ihW@ntIi4y@q$IaLV:I9:S
k9*i1* <F>Q6>K?iF>$:Qb4y/$E?u^>GWh%Xa^nR//yXRDn:m/S+S@^6QCJRPhRj!JMj%lyG/?*Zbt1WawCcmp6
u*baIZ WPmNQY@5XQ61t4GF$ywElq:CnWtLb<p\^hC6Ghu4VG>Id?WADld>$&$F8&jCFVLT$L>=J=:npI8njj8i
5qa1N4 l@JnM:de5JC>cncT=4pekT>8nW8ac+lK8wE@#Rm##1^YPJe&\#P4=\R::jGphc1Me\<6dJVGZ=@S5IYq
5T%%pM nGKGSyFRcZXbBw*tclhuYDnceJ@:Y$KJ\F$HelEhuG856Fa:LqWN4ck<edeCe@Lu?9\L1>?tZ$yCAB@8
We:Ll1 #b:E:Yq4w:Wc=pn<eA:GV<pu/=X=ETl&MHWqeKI&b&1\&qWyZ\<q#pNXb/=Ey/SMSY%/?J1+6uiB\LpR
ml&^JS Zi1F+J6eNbMTYtP%m<&t8SPYW:yb1qKLGGi<4Se=jpej*m#Fk>tHIAB$kq1W9^P/Q/mDdYQJGQjEaFd=
$VLG@b 86\H>^=pGQyTkYAiYK8>d8+XtjS9Vy86+an?>ItYedY#t/d+Vmw\WiDkcbF%hNB\#jG@JwH/mWEAFF$N
\*lI5$ QQ9MYI@uCA>S+QH%*EcXH@&pF+#*uAF@9dqHG4d=GdLu%d#PLBIh>K\y@L<1n:@!yP?TWZ4P=cZD/#Fi
E?@M^+ =Ptm?kK*QC=M&ZYdtlMdphh&&\pGI\S!jpVw$9NWIYGaDW15eDWq^y*CZ%G1QBFZTC5NS\:/bZ1Hl6AX
4=Fll= <J%P6:DK$6dNi=SR$E=5JGehtjNmA!wI!>qR6IkDdDyqkVi>S16QZHkciTS!=4@$Q$V/IG4h#TN!Q9P$
6WG@>N #4Xhd1J&hCAAR5M@c1<Nk*8Lq$lDQXT1QXpEZnLaqNGEZQ!L^ZnkpI^WERNLyLlk69dAQcP!pRqb8B@u
M@5ab$ AA8KKScMya=:uAKGW4Fc&$ilqy5AlmT<%V:pa/jC=pAyS5bc%uPAL&hD/h1:RDKNblukc16=<IyeE^*T
qR#BpY pI6>*Y4t64T<>QS+1B>RBF*kS5NS4&ddMtKwhJYT5*eY!#&w/>WIeV^C*p+iA\?yIH9>k8ite+Wd!Jqa
AI*N!+ DmdquNMN>t^H+6*N>Vy5RPa$BHC+?cR*KA6?9lQ=V<=4i*dn4KJ$nT^nC<T4R#pTqj56QJ:W+%?uKLT6
\?5MK9 FRKRW:qGPPKD9+^:G+@5G<XDWQA+DjB9<m<DD%G+=FY/?wceBI&?/>R6&qqW5R&4WnPQ*=TG#\&wbI=/
N/LKqD X8$eku/i\Hki^V4/aj1lZiJk9%1aN#LtQtn&4P?nGnnhGdVX@*NPW9@luQ^BZXy6G<%\5XLCT8Fat\Nk
w6I5nt ?yNnw&^6XNTj+YwinCCctYRMeP1Q&d^!Ryq#q<Z$%NMEt8j!InPi*&?%P<uwtaABwAtj%qXR%&<eiT>d
H8\cQn aNRm4RXBBXG<p@LX*Pd<cSjE%=E?YKneSQRctV#8@\6Q$C+q$y4bL@Iq6cXNCEqQ8mMTC<Y%AThGh!=B
Jj=#Nh qptjYjm\yWC:&Hq*cH+IFTcmNT@P:^q5AX\IR=9+V45Vmy?ybAPV%bPkjcG$WSE&p#/1@ClH8^uPPThQ
%n#*I> iq9*@YunmZGDAQ4l6cH@#9u/w@uSZ$%yX:WdKa6C\SHet%?w+SdGtC6DEc@Z\Z*%laPCdNypDmF!w^*W
qpCE+5 Z6PLMNd@cYcicWPYp14TwS>Lj1d\?5/h%WK!yRG8k\S/8bDp:bemC!$$p<<95djkZ4?:N&@iLEkaEh4M
Cn/md! VCWNcjVRHDt/P$<nTi8L!C8Sj?9*1aHNJwG6ImuMJlj=pqj5Q4u8G4MJ?$c/**TMeYun9S%61^&tbKTF
Y^1w8k XLl11Wa/q>4Ba%d#p5BXS@^q%$NWP6l&+5=+/HahLKZ\6H?cla\tM/pQ&5eT1u+V<Ca?@@BH6Suc%uW@
I>J^Qa qZPI68CP5:ea@kXNj!8aD!NSThdb9BGA&qTNa%ejpDm:WCP6H+lk:%qNVSM4NBiq\P>&4*mBY@*%8HRJ
@ZKZ5R GZjFW@/6JbQ6S<K4GpM$G\Xt:bECRe%STnIuNVJGmc6b&8ceW$QT<$VRql:>8HA@/D^P=Cb\+8>iT@:S
wmLJS% q8yuaeq9R4SC>ZuQ&EQ\+?\G1q>D1</L#k1^S+HnA@SdlR4W^9KMqXaGQ5yWCit%qKlkRZbGFA*qn1bk
Y1<%8! y>B/GcIpTSy%%YH5MMya*!b&/#qkIdKqc=DJDHYSF6HBYK#<hdF%%$^C1\?PQHw%<nB9<lSQZ#Q4y/X9
uM6CPY qKAd>y@Y^1+V?P:9D1$WI&J+wZFT>WQu9nE8lGBN@qHN@n5QZ*^>DVKS5IQj?!Kb9C@!bNlFY4/RdLNq
#&SNI@ 6XCYCTF<ni+%5tMqjd\t+>GmW9LeyetIldBpAV5L>Q=GQV&/dF%jd*t8NhYTlRhAP&B+kQ69dNMhWVd:
MRj@IS h&F%@Ih8IQSi>/JZqV9qe$/Jk%yRIH&bly1^/Sb#kX*NYAwPenC*5Wy@1RR/uI@1A%ZWS5X4Y!h#Zcjb
kXuFRC WF8/<thpL5bj%!t>$un54J\eQP#eJcEyaKX^!KeGJ?=:ZJ@BDnWBimmib&TT4M\e/BF%ueJm/mStX#tL
VSeIH$ %b!&Jc>m+4=miQ@Y1$XM^@dYq!w5D$+PV&H:Z6Dl*4B&&eWbS$5/&$MKkHI!yJK!DDJy@XuTaHL>b?4A
nal@^T yZ@AN4m1SeT@/%Gub<>E#!IAlYAnL@FkSBcd:J^JiD5%=&<X=d<^&dX/C:E/N&uFcli:ZG%^/T9:9Kji
k@*Bu1 %i9<WF!neYZ8ubK?*amA6DbQ4i#p^Kbul+I1mnBMKt=$Jww6uFK1#>bZ%&p:hT/&DlKbh:8L^1Q4Tbe$
-A#GV$ 000d61b1ac300110333 Page 344 of binaries1.zip
1K!y5$ q8=*!tejD$QAHK^HBA#@REV@1CZ*86QV<<j:pc%XNM?SC6*LGMwSGFC4%tL$ChI<WRPDY4tK^\54/H@A
:!!:!< t4+R+Xnlmt%Mh\#&C8hP8bMPY?GphM8jPw:^P8Qq&Dcwc@JAu5DQRIeqb/S$^+FVSbX$jEYCRHl*WtpV
L\BAJ6 Qcl=wh9N^4N1y1ZT<D&C1%nwbdb&ImYW^Ik^Yd@$b4<paX^iLCwnTS=S>ZR?Qb$5<<G$uMbAwL*1%Et$
JS$KC= :>jHH/RQmBP8CF^peD6S5m?REmN6@1ll8*uT+A@F!JJn<YLynZh8:nhAW%<jH$R&RC%a&YQul4RqAp!S
qnddM4 D=YyaF/+l@nCDl<yEnCT#KGn>8wwL1=Ncu&l$<MD\:1Q8c9P@yNqDI1@IV$b/m9IKIw#$TXBJu#4P:W+
jQRSt& lPI?>FhdTjhQuNC@<jAmDQZF9Mwd!kSq4SnGR>EqwJHRjW5HKKN+NcpeSIYVQ=TXCTVJXh>I8SS<F4P:
XKM$*C %tq1!kDT\<dN!4YKDbaLaR&Y?Med?5^WK^yH//*mdE#H4:ji/H&a6RWeQjm==iSX<$ZCXdY?*B+a/A<M
uwKY+l V6tTImPtu!&&A:/P>Eq9dKES#S6yVdlkAJjT%L:epi9^P4Q*t4@KDZ/Z5nc11VpjaTKiT86uM4ek596?
$&FSq* FT##</MY&/5!1pmCXHFbDK%=FiyT:KYEy95Gt!iX8k96ZW4=W58+c^S\>u&5ytZ:MdQm=AaC5Lc@D^Bb
Kqc!Q? #8yen@>8@ihZTc%pL54LIAD#ZBD!E9#j<?1Q8uGWCmC*lDI!RBqbFG5bW$AbPN1#EI1l/49hYeX/K*Lt
e!NY+5 <NPnNLpAdT#i:TITJiZtYiYbVVA\/85EZQGB6NMjet/+\B@?@qatywjkil/5kVIKRyJGEX!V?cIuC^1M
Nb+a9$ A1y&1XAA1#\RRkCGpLq>p%<&5HjZ&LWDAjVWZE>e&+Gi&BSmeyS>PAMBJEMA<D?>*d>9d@$*G89t<dyp
S9/@V* jp\J5+?mRS/XAMlZMjbuYW4<B#PT$4F6y<4A==GDREk#Fb98*t?Bi%8>!<L@?/qlA%:GLcQ9NAA>lGT%
6>$5XQ NV=Y\ZZje6$5Q6B?nK4*NpS$lBWXTKd^B1YZHAi8ij%4=I189eiAyRYYDFR\Wl58pm4FlV+<N8$!+*4/
ZuCiTA <jdJXc!ZmKTCaJWe!C?A<^QZ6jSDldKYTWMYM+JPuEnewW#Pt=LDlLYw4LTKKMKLQKNP+486E+hT%pYL
:!yeVP Fy*Z1iG#$SyiDNa%/l$BFylKnIbbbt=MF@%EPEp+5IDuQM81lw!8qAHTwc?*\=P4uqHRdEtV=GePI@PS
T9bREN /VH\=nS<V@EV^lu5!V>TG/\dieYWan9G@uX!k*p5IAjuFjd*H#&+TGQWQ<m$Y=nqk$ZMEI:\idlBQ@Zt
5ep6EQ Z%<keD?=E9@!<SA+*<X?:Dul=eTtc>LSb/Vk<F\<eWaQW$Y^$uK$<EH/HcjWdh^MQh*M6SWtD6R!JSLj
L\1$$u G%i=/#c*!MpSbe4Z6!W8bt+iVl+YbSW4>Eut8BV=:GRle#8$JcS1\a6Dnmyk:cLChM!qy9CCw<G+&h+6
:n>$YR hDZ%9EjSSXI$p5&/k>6wGGp1ySic:Dk:%ZYTt1Y/P/WW#t?6JeDDF9F:TQVpnWb1641a$@&=d1<mQ*A1
1cjQZJ A\wG^:4ea8M9eRuKDt^ZKuSte#Fp\Cj5V&:5=@YtI&ylC!c\YT<Fuplip+lmYaA=4^KP19^ctbAW?5X/
qCem%B M!ZQ*58*iBa1/ZL#eJ6:W1*luPRacV4=qj$QNN\%a*B4QleCQnM\lahQ+pL?anCSk%P^hDm9\/ZSZ&y%
5KpYAR HWNq*EGQtcyVmiNlXdKGWk+e@=&TttDP*:!!QVXM^!p?1KjtK/L/+eYCEje=!RVX1<R$X1X?BedcPDF/
D!18Nd >VXVh/mTbX:e?<ut6wAC:p#lhQ@4CMZAe%$puMn*QIt/u^AA$&!:K!pC&\l:5QAyW>jm<8G=WR!Bm1Kc
BB?*9? 915/m*GyaNQZZ!FVL>j**mhdDB%qcSeB*Ehn1hlL#XN&5DN69Sh>VX%8DRMMjyb8PL%BBB$&@^>!Tq##
<k+C^J #5hk!LPNJN<5m:SKe5&yp</:+m:R*:^h>GZNJH*:Ii/TMjid$tm9TGjaqPc<!PRFubIF^na@9Te6kLEM
nQw&X! /6^>54=4Dw!nH!e9@G6cdy/aMQ*^uqn&Np/:hl++WF$m5F!$^6Q@DN#!A4>REK=LSJWl:ww&<nV5iaFQ
ZJ$^S/ tFNl>IPMbj@\t<Y:nqM&Tb$iTVQV=>$Fmq:/jyRHCCV^yV%q>mm5GbZPNaTV5d*Mudt<1+@&FQ1pbYKp
J>I=IF >?$Ad=IV+^6walL<l&ZBmV%mDmQh6ZFu=m@418nQu4P@5/THLmpWJu9IjpP+/Al<I:FaPK6Z?VByk@9Y
NDnTu8 alu#!@GMTMZ1a:#&eqFJ\j/X!Nk/dGjRX:VKASP8Xh@==DjQHcJ$5n&8ijZh\Je=K+?hJp&GqwRIYS*5
JkG4WJ ?#:X5<h>EADJ:F%Z*j:F46&lS\&T#qaN/wMdVK=Q@CF<y$QLZe:eBKQVT=WKZ+i^?D61l+Pb^y8!mLX>
\FcJjh \8=L8JH&T/*M?aAK6?5//1dJpt6>8i5euWi5/Y%n9+y:p%*#JF9C$?LPp1^nj\c^\idb<%%hj>Kd1=K!
\al=R9 ^<Xd#TK9QkEnYkPDb>6K4%X<^jkF6^l#\*uTqF&/Dh^apuVmpRItJFB=Vh^!jcLjLT+IL6y<y:wd8kM?
W8k@FK BA\5q5u48%%:Q<%ykElVEBeKnManECV4W#%$FX@kN9t8cclp@/:B*&d8mSp1PuNj^:=ZGJ%b9R@cW*c+
nP%@&F F8Fc94mTwueTEtK>E5db6bPjQX^n:PA>Z^YB#IRj/eNCAKwtM&D:?48eShwh1cdQ\m$DRmw/M$$%LEVi
%IbK6j F+<=De*wAaFVIwePV^=4wbMEiIV#@=DVGmpH5lqkQ+@&H8>XInbt+TInhlwEwKQF&R+1YA:V4HBnZa\+
u1>Ijw mqB!ejT<q:X=Q*qEKct:$abqNLWedj/?yikcbn=AtP4mJAECKNMD#a?T68\@SpIAdW@LK8hd=>C6mMQ1
=$t\45 4=JikZ?GQ<LB\j9@B9=I+9@:?CQ\yZj>=jAeFi=^*BP/Dk#lcMG8yh$M\=c^WRp\>$DSMdbKnnkJ?bqY
5$w11q =L:^ua$BKQpn+ppw\B:QyJnwTp@%<^RnWbdc^nPPGwY%9iaB&!qXZ4Xn+Bt:K1WXKS<<8?5kPwwFp<lQ
1qpp=6 aBL::Qba&MwH!qVhu>kk4a+Ew?X?\?X$VHj%1^P5Y>$hqR=$1qR>ampZTbKJSNc:aVCT&AS%mek/1DPJ
!yGhl= !IVN#A8Y%5P\&F9LV9$l4d&S:F4ickK#ibISBE5#bG+iQR1Yd*FZpDtPqJnhcpZ=XZG6T4BmZVZIcjSl
X5dMpe 9L?lG@XIAabbnq<tw++5ied^/dtX>4uwjk<DN/N8KlQdMG5D+/PYt@*#Q$w&\TDa!y+>+KJ4+QuF?#Fu
ZQ&H^Y GHNk1/SJ^489/P\JEY/:Y81wR<pn#i&!yjKYWnAi#nkbn>eT6nIwNd+nSc!8/Fl@Ee:NNp64hFX4>Ywh
>QmI4W *bKuTnKl@C6lVIn5eW<@eEPXA:Y6Y/%?u:J$nX6YIjm?8q<QYc=ch<HV/KPBF*iI9Jyu\HVZ$yJS4JVJ
>==qhD t9qtu<Va?$j#6S@91D?mlJliwF9mY4=kttV<9wR>QQec8$61eSYlN+#h/^=VE\mT5jJIRaDLnShMWK5#
BmM\6j &pV\:^d@HM$\qkih1%W<^w&M%mCL1/lCAXhZQdc>6NbeJTl^hCZZjAEqDZMPN+hEI<n&K1Au/i^5Qjt6
Wu+>u* l$++A9I4EinQ*RaF4!\*mHyj\T8IQdaY\Z>e4ZX&n=ljdR::CKXG=9\/a9pVNPAIqwVT?mX1/Ie1BK@I
hABQeA L^emly@iEZ:a&6kp4cZ#@^cIm<<hiDGV@Wqu\K/5Tej=%9m!^Z?#cI1jJ9k:SpX91IL<<+>AZpMmQ&qa
CJBD$y bM<tCn^&&BXpKnpMd5y<$YZaVTClhG*icu/lhP/att8WK9N+J=paQucCuW8W$EY?J9iQ:AddMLVC6pci
\<T&4= nGqqAIjP^6Sh+&BW+Ml#XXFb>L5t%hL8VMbcF84Q:!n$<Mi\LyAp/SGH8Z@AWYPKD+6V%!ulIccNFK/R
$mPAA! 5Fb?q&QLu&qMel@Yt&KjJAA5nP1iP&1T:$1H$C69cKjWGepN6@JJG5a6Y<c48$dY+F=h+8/&M=5\hjNZ
p/Q$\4 jbB>d8=KH^SSlVZKW&wA\&aF5l$%1F1P=X+ncnF##%iq$n=qV=t&>/+@iDFBWIKMqNnNd<%L%Fn/WD$4
*/8Ihe Dpl\kCyuwm+jYdJLWDuG\IRuSD^cTCb#SiT1C\+<Vq^e?YRnG!SG$T?4RFiEdHSF*nNNw!iFL$y9hG\t
IBltb8 ^R94Fd!WVeKB>WlcpLw%$bh@d%LdkX1@VVcSZp?FemYIZV%edAyVSGK=EVVIal?t?FplWQc$5KQ&PpMj
!*kVJT d\LYP8a6Z!JD<Ely/BtW/1lI4uT1eNR\n/>Wyn!hZp!j&p8a+I4<IIWm<ED/b&SJKkI+Ad8atM<SL4LS
i$b%mH <mFm&k9LRTq4WtNM#YV#8jlLTAhlqj\6ZXb=^m<WcJk@DWa115>b$9P#%Di<5?V+tuL+uylC>+nAn^tP
<6YMZ: 6=FJ!a5FN+%n9K%G@JlcYd4CK88nF1^lhKCLZE!WlYV6F:N5Tl4Di6?85plcF\tW\acWkC&kjC6I@=$y
^*5VXk E=y$RAjR^XqXa$BbNn\yZc6=9K1SR1/^uiQN<^yi5cnVQGtKKJGYcP@*?XQmA#*8yT>JCaqn!twd>bRw
NFw%A1 CGa?FHmkj1#/%LcMLSGAF:1tAlX?tw=u?S:ZQc\$5ne>jdZ&QY5YqViDJn1<#6JGTKBXq/1c<McmQ&%6
lm>:// bI#4n==6w/^paqiuw===?&yeS^W+X5XI6uB&c@Q85ZAn*%6@q4#e5E!F&L=TMw@JAX@cVEF<q/Pk*w9Z
55l>ic GN6?/EZ5Sn8&9IMY<LwBp+8ltu%$J=T!9W6E4GG4I$6JKlb?E^wN\9TDN=p!i*KeASi&4wP/LekGc>#9
/4dnt\ ac1bS55FiRW?94$<QG^9p:uqbtK+6m$8cpDbdKKem%J\\WB859np=K^!=#:88M6m\nkSc+$\KVtN\9&Y
WLeFm# pV%dkDyV9LGZ!5lL#*NKZ6tTZkG%KDp4meQiRy*ium4utnkJ@6Hb1HS&9ZR<e>9PZ#9YHqQGAtypY^Z9
NDIE5# PHSH85QXkAdTZySb6k<8T<Sa\h<Qi/Y#tSqZ/en\iWwHn:$cRQhB8*/&6%nIb1?1XR+\k5j><Kw#<a/4
P\cTA/ LN1>mkSHXVu45HKVwWM*5cE?Xa:9Yu8nhRedJ5WD1i^Vk9%WhS?d/i\PB%L9HwB>t91=PW*Bt>J\Anq+
FntAh6 51ZFA+%YVeNCdAVZYaihH#!Gd!P>tYHylmwDXA6=h@qMGJV#QAJ5m@c%M</$qH1G/!5aR5&a!!@WjWe\
AQSBmI C9qyX\S^yD#uYp?MGF>ZH1RqmWcI?+SILd%B:41jM=%ButMPE8&Bu9?CVj$i%*eBt^eBPd<NA=Y!J?Nn
&tWkSM 6:!nS?AFEc66LKER>9/NMt$d#GeWKYk!4VDt+pA/j/Gqu/k9c*^H9J+XE8ul4qPL^QGqqyZS1X*GS8N+
/LLhAF CtJy*pKiqd5^wc+/hbNHJXV>R&4jMGVK9/e9NRukjpt\AXJIh?C<SEmj#X8^bW9kb&4/X1?\HAtkR*V>
LMqdPC pNSQMMD<Fh=a$9a&YYBHI5Ic?<RaChiBLVJ!5=a9^CCuZG5d!I<=n*eTT:nSM@=cjCPW@/%6MTlT@?*Y
w1e\E4 Su455S:CJ@b^4#HH8P!ceZZHkC#FncFu?ap1@dal^jDh>kl\!4aH??<u<>9w4N9C!=Gk><!mnAhQy+1P
%lbGC/ Qp*INcy6mHbY>wa/t+<!PZ<cDEbYhQaQT:nh@*ai*C%AD*%Bb@9bD6XXWZ%5e6mEVde*:BL8pB/i/m=h
-AY*Vh 000b53bf19c00110333 Page 345 of binaries1.zip
akK+BS MdlwwA4?XNVMcl%B%X96#M>C>RP$Iu^H6&yaTjp*TRLpEa4ib#GDi@#qnL+V!m5Xp4ZdFPn4kWa\BbX$
=Wa>bY $tq*4DRJFmTjVYNR!D=N5ddKTkDkS=#l!yukE+/%RwS=SP&FuBuS>5@5waQdcwB\bKWwW9KC+1/$+uPW
>%^$\T 5J<RwB%bi>WbZTW9RlGQ/e@S\/baMFAq:hqW/9BXMIl</<lW$LnXqTnk$FYn+k:%MeK:MiK1#jjMbQAq
9WJN=Y >%<RYDy*^CeaS<*CK*c@*FFYFn<Wb>SYDehYCXY&Bu#^D+@kFEjul8E%KLCFp1mPq\mID!pY/SbDp%DB
XW:$>N #nW<*&/Gpwnkub:l4KQb*yJphj%PcaG+FT#iRcFIi*=BK>EPyVdF4ddA9?XEkl=Pb5/tKDhQ56*IXjiD
TaRHL> cN8Cap8eIatDupKKDJQP$VFFMVD$GaW%d?kuG6NEEqN:G6NRJEA+LMCX^nRe!S\jMZAWhdAVPVePXdRZ
pJ=!hS nRL>GXpELFRdew<t/5W:?w5<Bw=CiLPQ>GabBEGenB^NnP+jGE%QGbI1<h\HtN^HtP1H5Vm/GHLHCbJG
>pmMnB +RB$AKkBF9IBF5!9VP:VVJmLVIHBmB!jYRKlYABRVBi#VB!DmPR14EG9YDjL5VXk&NVQtbP8EDu/aek+
1&GAcM &bMk:DQ#HJnnCIEelA&C&BwELLMI4B#D$EFiCMq<uA$m:Ht9YC+=tZQy8dAaPYj^kJ\GRA<8JqM%Lm\?
E9*+>? IFR=%K\i%?\#Xk%9GM:Z*LM8:Je9kV%imJ#SZGTeRI%W99yd+P\:9p5?jk$V9kbWPK\!utRjV1^u4B:W
jC=VE@ @EtjtYaGiDZpBP5HYD$/lLCTBV!!lSw?C&N6<*1W5Z1eCHG/mV#>%jARtSptTHbn8EIS9eIRI>hmBW!I
K&:REe NSKLZbGLp+$n%XiIN#KLZ:FLpEMpQQppGwWp4kR=PZTl%F?RF@CLtGIHY4\pEX>+d!:P*886KI5kVXHP
Xl@KXb XYCC^wEPd:FNSSHK&t$nucJF$SkA:BXH6l#?tcSeC9<#TZt::XhJ!pDP@/XJ!9<\M=tV:N?T#@:y#GRk
hZKDdL <L?ate#>J!AV*Q<p!AV*j\Tb+Q=VpApk<E?TJwHA9\Pb?EYtKyD:h/l@qieK=Qphc5=jWjQ?BnZZL/CR
A:yH/k kWC?*/H?Bbk^pI96h/k=jpZN@n9WdL?m=9kNcmDQL:nG^jpd%B!<9/IG@k:%$:#?PjZ9!BwH?/?i?*hp
m*?eHy nj$Z!LlA46?S6X@uXHQ>n4B^e*Q<ky499$QN#jdjw9+6aiQ=FVZHj+9/h+V6q#uX*L<qdD!@w8d/@!\4
nR/YNB ?tu:?btM@SMu?1eP?+&5cP:@CFH^q\j=l%uSj$Gq?Ji5cF/8Q<tK=9/9RFS\@TW4t9Ny>@p4SMZVR@$Z
6SD:>d 5/L=PNu?S:Pm+/EW@y@Pm5d=I$bF@u+FW?nBRm/<!\@F%!:kc9lH$6&8Y/8jlZBhIRDF>aKHFkmA1Xup
:GP*X& kwZ$IQ5KqAaB:KaNkcZ/HnpD+m@YH?1ZIIDlXqC^!#V+=&ecA>JdQLT4Ib4M*aMZMX=impQ=qYyaN<kc
HVdMSP X#T^EID&pep6B8uDdQd@qYe=pKpMePl$%?Hu9<BQ8CZb<TPLEnk/#uV\TcHZjGth@CMVJ8=E^pAZa#?L
CKB\KV Et?CM:6pdq*Aiw/kHWPSYb=>CIAbAllnnu?IjuNu@deM%&4$S<H?8KVQEFhyFwN&E$j>Z&9td?a61nw?
ueQ$Y> 4?&N\uNyniqR>pRIAKQ@9>dP*<\@?$HlQ5jekIZ%^566dJq4Ft^\^E!ZuN6hdBjynCD>AVW9PP:4$QHX
VKjDEP d6ipCGS/9^@GT\\HZl+h6DD<9b!=Mk5&jGE>yV$TBbCRpGKhm$I18jQq1n9SZq6/&h1Jt=cyQABP:TNq
jT*QR? l!GPINVXIa@IM\R++Hj^ydZ1h<<\iqqw%DF5K*ZyJQ1&!!R&Y?T*XF/dh=ay5jBw:9a#%QCwHkdN<@1H
:SMIJ1 w>VXtLQHk1!4GGI=EK/t?N6\/K+6VeI/&M<iZ4Mjm9W>##c\hjFeDMjj6lAIXlQQ<nh&c5c*??6*:Kh@
>?R9uX pJq>jPn99cQkd@muXjpjyMK6NVN^SX?<yenqFhk!&i^mBe$ZV+IV6*>K\9MJGLHk=b%w?ZyMJNlhy^iw
Jd%&$Q m8JSkZlDR%BLB&%Wm<^tdkXL&StLd/8I&^nkhk:PLyANQB>it?Ze8I!6Z>5%RACF*lDA*q8GT?GkQLHh
+F5?JG CZ%d##Hh*dlQZnK/qMmF$9*w+5j8tlFJF*La@Nn&FRC^G^YLIJDMEtmMTiTCGXTM?&W\RSpeXqVSA?9A
=NJC#H 6D?Nyu4Bkm$>u$hX+9dn1u91EBiL#K!+6&u*9HWVZXXLc*tFVL^JljRN:JKT^Y5B$SXH%<SDhQt!FY/y
PTt!@/ An?K&QN9A9/<XujCjYA>5!eSeHlpJ!dRalwqR<4j&wiDDpT4HG6mW&##j%MPAi#ZQlcAn$^I$^DcG88C
ZX*edW X?#TFpnWBn<^Emb1\h/dMS:mN8?GNtMwF/RcPa%nd$XeddJ!&%@iB@FcqDAZdR%V%\WSe8e^SMt5YPYX
%K!ump S*HlFu1n9>++uj=PinGG>lB6elB$Rl=F4H=NHt6lI4>&Lw16*iCFn\XP!@q?CRF<hAbBb9i4%%n$J1WT
&+NWBd en:WlVGQ\XNHw+T++8Ae1WS#FLZSTVKX=$jqARCw*i/DCk+YjB4<#=AYI:*u!<a5=F9<XC5S#Mhjj\6y
DulKKZ lkAt5lIkAAFRh@^6Ba!SAhZM!tkT/bWQwZlqa!u:CJ:1$P*=9<9D9^Y/J6F/b^QudTHHP*liL^k8$n#h
Q>pWPw JIa^<9CiwMNk@ha!Gy^pAB/y#@#&YX:wLXMq*cm#dnCc8ZBXnGRcm*Bcn9NddtQPSLHP*4T8ZhI8:G5Z
WAWlFS $G+T/=&e!#%N6&>H%ji!wm<H?an=QK=!kQRn=DZFCI%$$ww1P?QWQ65MS1$KiZT:LqXyI*K\F\RRSH1y
>>dP\j #X=%@EW!hamiEu\!d1@u5Bm=1^bjKQJy@a\TdD?//c#L^#\MDiPKA=nJd@<+bVXD?6ZqBkMC+DI%EACX
n%LewG T$?::!HZn/LRN>c*=&wE9C$LiVF6dd*VY=nqSk\BLF5RMC@LN*A!I1G4ww5hB#AXwJTlFlj!F5R>q<a8
5%%i8X GVl*cid@K>?+@nwiPAM#+8MjDA>y6q9KXKwlBAp*:>9QK9+\cjQ:H1B@BhVI/El6MBE<:\$R5NJJ\dnu
CG5P%n eN>Yi6yHiFZ<K!VM9L+*8JWDbL?iy^bknlA#hMP/6G/@MJt%mFCl4Jj5LTM*!nd*Py&*/@LV*6b8Cqwl
ww?G>M %$pLCTRt!FRwV&Ie#H%FPkRDAWSW11<y8iqt+Ptlk<jI6EGS4XjI\mClP8uF^m5Y+p^9#TV6pE$J?9YT
FHNWp= bj#9C$^y9L8\>eQQ@dCh!h!b=PB#$Iw@Q#8I@dB\#E!e6Buqbl/WFXXa8uNqVibHhu1nR<#TaAdZu%a9
RACm>* SB&dmI?ENcwMBRhX9ThJVK@PV6h$^BPwjHkiGLRL1^Nwmhy$99QC*l<+BH=d!!uuZGt5G/qBGKmdT5cF
>Sli@d &:TT8\mdQh!QwX#?mdapQ\1Byn^>ySC6@qq*Xa%hiXl@YF11hku/9B9J\Gl<+>\/6yH=RI?u?#Cq#\i/
&&q\H9 tl+CK+96i=1Mpi8Q?ETTBn>m9PtAY48HRIC:!<XC66?hXZPVhX4hb%u=b>kJ^aHB%ZWeTR?mN&5wq%KX
mX/<md K$1H>W*teh!bq9wJ\/EX*\<SD#dE?4eZuT^>$GYw6cIGice?cM1SyBal9juTY8GA?#/um8A49t8e4Skk
B&ukcP ZZ&W9w5ENkeP>m6pIX*+k*pk=!XT##5X\uuwN%>d#QHXY?@jcZ@=IlMe>lXPDc6B>qAQ9dcGSQQ$$bZ*
^QkDuJ EmX16jLTQYdcy?Rm/Z$X\^4I=8Ewm9m%CqTpNbS+\wA6+p5djc#t#hhZy!FX*!nd\t\mFul\NFRh45ww
b*&mW? X*Et@1CVc?Q@IE&L@!=NCXG/Z=Ni9!/4Y6HTVJH5bwSq$5+6A*9Ejtl5cW<a+Zh*n!eRmA>Z!m:tbu^P
yPt^?% B**uT5cAI*EPX=1!4Z%w%&?SNVwh1+n^L9k^:LMwHjdJVHnKIDm?FqDcFB/iTyI%hZ:Q6h4mPFcm!+A+
SjVBe< $GmIuaTh@&++:%CRi>##HuN$eIXCVd^IFV%QnkFdQVn$:Z4B5aL5lM8L^wqQ+1Q+DcmyyTi4JA9NXbV!
I?eD:n W+M#dAX<14ySdt8#ja/t5<jRadm%aWTBV#&+a#6@HnK$6<9!6LXRpBZuppB>*54</b%I66@4=h/yAaV?
q5q/*J ClRlmpwJb4#\eb/uma@lq<+E8PEWm54TdbTT^WphuP6<n*X#5:E64F<hjA=hKW=H^dPC+Q!tp?jK@\%/
nJEyM< q>cdCMHA1+ZWI5bbW8cm!y*M*Dl^B&Qd1wZWR=ESWm>NL/</<qkKa?SQ^+n\^jIZS>9/j5&n*LlMlp&N
+VAcl5 pmM11lq#F!ZKBm/#SM*N\@lM:KZtSwG1DPPI%kI9!d=Cy6:/!+>F$<:ud<*96PP?TiZV%PnkGZ56IEQX
/wVKWK nyEpm1Jy%K$iTN!C#V6h5kRq=wAIY$a=c%#KY?P!@AK=eLaTp#4M!j^1CqC8Jk8A:lkKwwTqwLKunBYu
B441XT PC:QD+Sckw4:=h^Q=/#Lt8F^qMIPHdIl=FGW?CZy:/iq+>b?tphl56%Bt5IF*G^%dh/LaN*<nQ::Q@+A
QLdD&1 MuNC?u@QcGuuK:j1M!&m<*CwHkt\IICmp5h&CPDdck=p>4$>cP$L1IL%pI>96t5:^\+C\H?!ZCPRedIb
*?ik=9 Ydt%nS$4&=j%@yKdPZh/?&@Hi/Nn@=cpTTq5DkH+c8\?@5SlWqC=>+EAQ4iIRPd@&C:wd>4q@8MGuj$#
>>Bpc& HQGQpC4@<5@Ta6#pXN/91%keAnl+IuWS8Y@?Cqu<b<a/>j6nuj=48:\cyV:yi4NZFS<4@P&%HGV*4p+w
4IeQMM w/bHG^$6\1qnN#q+m=/VGDEtb$e@PyXePY4VJKa\DQFRa>8tlk%Sc!@JD8l1PuJZwLP#X6$PJd9QdyWW
\kS^/j !=<ueb=uuYQdGKji^L=&bLN8ZlqQYDP\t$yR6J$cn+Hl9I5iEiPR/m/j?&d:ldIa#mCiJ=IC^i1==K\$
44*XM? WTR&j<<=b&N&+6mYX9:mejMnk=4Q!:*tXMJDi8c9FJ\P5MnRTVKu5EXYG^QnTGn^t<j<t#5N6=u!GXWl
<>RjAn kVb:ZY$+?euwEwhZ#KKMKlhqm?laQuZFHI?/FBqSh=d>M6RSYSCAj=&hF*EATRiQ?wwK=>m%^&9H8uaZ
ki4RCa b&9&6qDV+c&>RNt%+DS>iPI/l$m@@u1&=qBi#MBuX:$bFe1mh$Ghu::cZ^!wyV8<1tpk@%CHTJC1>%\c
56#8Vj Wj*CQVqLj5NNSeWiW<t8?WbE<:&DEej*9VZe>@nWThR\mT!qiqIMnK&>6A9ZqqVL*a5SVBQh1HuQ*Bky
mLB=SH YitE%Ea$He6SAt#aF4m/ym<NG!pZDNIm$cZqpGDPqtc6!aX?AB?#>q>&TDXi9>Q/e6Klwp+VwWdAZJRB
^b#=cM heCyTwCn/XHkXa#a8emK$6R$tP=+IejI!<ctZaNb$h?w8NXw*95t>*5^>%j>4AYSeA*Qc4wpKVR<lC^Y
>5Ia+? BkFaBlmikjw+wMAYZ6cZMmhQCp5dcN+XFZE8!=6<yk9!X>w4<lwJ&<4F4i*<:\9PtPI@cZDq%\<>8:wb
5byBNV F$*W!u1#TbV%<cV@B^uVZhY+Vu*9N!E$6Z\b&&EGid\h8kD1tEA$@/Q/4=Cb+#d6C4jT#@JI?F6^ZD6^
QP#Eqd >Qi>yjMSC=XNVM@S+j6mZ*X4E\=eD<VGuFJG&u!>V9ZY#LnyPeTTjXe&WFc*68lZiq%q6QuB+ntcQKM%
6V9w@* 5pa5eyGRNk:\Sm6!*V+i&Yula>pASZjF1GqaSl?^/4A/C\bQ8ibnq*yiAL>/CQ!!9Y>w4jk5PccCK+W=
-AC%L4 000762ae57500110333 Page 346 of binaries1.zip
\?H>l/ lT>DNpm9B/dptZ&1MQbSEQqmE\pKhL@NB@VK/a?qphV$XJ*%hQekVJp#Q^KeASa8I&jaKJpk6c\Fk@SI
$KlYN@ nF*!t?EDyHPm#KRI%N/QN#E4:!61>J8&JP!LtIh+4a$X4d/iT:@qDi\kRP6@XcK5lYV$%LN9/pCVQ/Np
JJIBdM I6+STcKLp1J\4k9<X>1i^>b*uX&9QAT=*!jL<C^a^iq+cppRK9X+eiAb1*%4\1Fh?WD=u/#aj>hc9Mbe
Y@911j S9c<Be$NThwWM@VpNtuG#LS+n=<q+64lDRujbM^XLtwwS+!@L*VkdHpbG*E#A4neFb5NPl<Ey%<!SwTm
t!ukw8 WeYeW=*wWa6&=nhSe1YZMm/iuj5/CJ6F#a*=HEXCleLF/d%I=+6SBGB1=@G??+:VDREWC/:yK#N<m^!u
KkVNiJ %:QM5$1iBZlp15m@j+jRmhI$%#=E9YtR#PRXyq9li#48J^NwL>6*jN*HYtWMG6PEAC:+XY+4iBb1SHdL
cC^QpQ RdjE6A@#&We/PSj#Ik>^!YD:mi8K!X9:HLCM*JQBd*$*@@YlTRWCwC^<<qZ4uy@Ik%hG6:aEMnM*w?R\
quq4ED FP8h6STk9k?>meN6d1w^euikVV%buWQc&1nDn5CB!<<yT$m58/@q6^h&qT$K#X!G4k%ZMZyWYtNIHnXu
CLP&R+ RE@?H4u/aYC\cm>$A%>^1&:844JTJ@pbZiiHt?BA*<*\uFL:lyZK>GRX:Ih*SpJ/kB9DZMy6AZRGNy%@
/Ye\%* j6\NV<=Zq@:VSyNYBkH5iPbec49<N#uS+G>@Cha9iZJ#b$AViy%NV?LA4QHpll!I:FY8@&=Q4$LyiVVt
jk6^>^ !yQ9q\YC\Q?jDtqGMEp!q4E^h8RN4jqR@k>#h/G@&TL*iYV4G<>dq6$Q=</+<HY#*KW4CP*^wDVl^A=y
>6Cbe! =S&Fl<L%/tC1<>^t84:R1yDYyX=VCTLPXTMtH\ieC:NAAGk>uZ4%15?JyVjweKmGW+1jH9!%XZZP&QEl
ZY=Qmy Ht*uDQpS8I@%!kECGH8=?DPlawKkT:44weWI%FQ#MJ*>j<EQpIWMeC#w%4u6b:dIdRHQ@8LV:B:X*HA>
5mqndu <b\#+H@tq!X@*!NV\M%m!#*!iwEJ&KC/c&Q^b#Lq$:&:dWhkFNBi#H@niw?4=JVWj1c^KZ/6uT^#B^\D
A>R$A$ aNYS>w?&&8I?n$T!eqEW6KEHhtuXK=#TXWwElYpI\QW:j%ajpZ6pY6IRtZBP9*ktH&pa+tp6DE/&<5^8
D%B:bT \5hDM9%Cb5jyb=VaABuT%cMtlBqyb1H\6FwbJ?cnkD$iy%$X6hRqSh&G1G9>aQwjy4dAE%S9CTujA/I*
+ShLdd t!y/WH4p8?4FwjM?!ZZF%&h>KQ\K#@Y!XX4iFZqy9tRcI!i*pL!Z/^JFG%n+cNw<^+Vn$#RuypR*KFW!
npAjj@ wQ@1XCLPaE\t$X^8&+:WW@SRN<1>FAh5hJ+QH5lWe<=u&w9Iq/wkQM@FYji9G@P^*c?u:uiMYeQyK+Q4
j6M/58 TmG<Hp>QT&IE95Kw#+McdW6+VpkHFJyWNJ84>KHDK1CuX1mk%#I6c1%D5JCm*S?L8%9R%ySD+FajWB/R
MYFpdX Bb!:*VNLVN*jYD*/nyaLN?Dw+y4E9wIyi@G>tNc6dNqkheS#qqIKa=6e^!ni:TPW&taW%*XT<IRdblkb
pIj:yL P$6?/B#T*E*bjj*K6&uX+hqBhBK+/FKw54Fal+Z5dcZH@FwWl9KMS/8E&w$S%jaR:Zi!>^eDn=Gw9Z5W
^NXljZ qFy&cF#=qVtt#jj\J>6^Dl<%LYZie>ulF>44Rw?nRXh$:uA94he5ljT9DinZquAhBqj!j#@NkW^qX^iW
aPT/@t %PX@:qX/4myd5kqhiL$QGQJ*u\$iPS41/dF!hlDHP$F*tHw%CE/w4am9p449c4pj8LEXj#A+?XDM=<JM
&y4>Qe KIE$TbBCmN>Zbm1&Lc@h+VXa>bk>Yn9EIeAJBMHAR<%l1p+h#!F<G*M+w44ZaYhG\>JSP\i^Gu>\<4GN
5jF>CB &@?BWVH$8JY81y*jlX/>uQX>RyjTWLy!MKywD6NiP%DuNmYt+bW6MTZuIHG*yjmSN4J6IhKy^m\?c^Wj
pw:EBM $IXl<Im&WG&Ju4WP+NIlAe&^eDi!nXp%4pSRSeTj8lRt5Flu!lGib/w/#JJQB/jkG!*KPNlWE%p5>P*E
$eKuHp uKn\QbBIa9/hVP>kWI9R5<H5I@KFQjK#6M?L^&Zp&VYma8M6C<y4/u5$#nV!CP4i1FYL8ihnBtM<qqK6
jchVyQ 5i@A9Y@WDW^ZpW:4EAlwC1!IqFl4Z5BBqSI#TQlu8b9!FK>8m!naDc/6SYiMt<EY8lMFy%:#/C<iS&*q
w&Zw@K *\$HQp$WGkZm!@YI9e@*>GZjB%JV=#na4IV\CWNC8/+cIaCYuMjXu$W9hBku>yVjS1P%9/W\ahdu?lC%
lyZIW/ 8!LZYq?=WY8FHI&:>pZ/MhAZ@ML$#XVnkTbV^Dlkm?FaFEee:lqF!C#&kNWMW=G#+y9:P4RXq#4^^le*
dQZ6\j SAyZ8Du1*l?aLK%ybGn1c@BMjS^X+lCdb/8eLDF:<hqMFKHHSdHFy4I$:^\/+RlS$$wy6l=pWGK1qjCT
#??CKS !yQ$G\WnT9#WF!X4G^*5KPN@NFj$<l#M5hG<j%l/=LPRu8$6D#Z4TbMmZ$KjV4jm14Ek:%ePKdqn%#hw
?SWF<y EE?R4R?NLY9hqu><F5?Q?=a<C*F4p:l9<CJI\$SbSVNA/FI+8wm5NWu&J9IDeF!*6IKuhEI@m5SkpTlL
dp/J1u 1R+8M!ba!$X*<cTly6nEPRjF%@5i&idt6S!!piqYQ$hTbjh$Tq+ijIG=4*tI%P\CRlBGIyZ=!WCtpu\K
QPMR@e pEH55&/MbSb1Nkh&Fw9Y1+T5Fn*?c>4tL=@4Vk4$W4YI=4W>Znc<&&FRJe^/X/E1XHhTyMiju&y19pFy
<5pnt^ Pw:9?*K#+#X8#TV?mqSkT^I1hySW4GWF#*LE@K91ye8mbe=8YjPFeW8X&BcYL*t5ZRQuWcj4tQ:QFSM@
8E$Z/c 6B6tXe5^Ph^QNuW>PiebC9qL!mJ?NiR*6=\CtQ/TGCLMQ<4yCFV!D$/J%LBNE!4KGV:TFabZw&E!Gn4a
$tZ9tN EnwRQKjM$el\P^Tm8/IPYPnGkjY&TJceLek=wmjA\mRw*FtLl6iyID^X#&@h>+!Y#bq*Xqea49Y!cDpX
IbllWT M5*XMZ$BW=MPQGVLEH^+b/qBmcqbn6l<^!b=J^R&X&\RMS:c\w<4KEbGV?/k%B8%ydD:!K\wKTpZGwLB
e/<p/^ $q@%am/*VMB>HhiJa8TSSY\!u%IZA9Bi>hY/Ytt1pqK?hT4Tc?!5E/i1$k$*G/$=VFn>^tj8XKDHF5td
9$wLq$ I$%6hjYB/$Xm#IQB1a15BWnWLu#><PRFQ?/P*8jM!N%D=*EqGhcwh+^STkX&Q#Amh1QK<$VZ=tCSeF/h
#8htYk uIYwEJ<J*H4%:G4uZV*!lPW#nTQJK:B>dye4GZ>Ei+T#^mkIdXh4h?<jndG:u<J=1&M/S+J@=I</?Hp#
JwtmtC QhIud$&?Q$pJ?8cGdyWAQ5RKma:/<:Tc64In&4eJ6ddblHMCm:EX@VLN!BS$PK$%RqndFqQ:AF\l>$>l
wcL9>Q ylQDFXuy%w@de+&BqDqN>/J?^4#eK=?huQKdyc%%%T!$QdVJyiCW5TGAtXu\F>AQy$uI:L+PhL$<XJFi
1ZIVcE !=$:Y=6&jZ*Vl:p??Bli8N$>AyMcE4@YBJ/d64h/X@hHF6n8>qIaR<ZP^P9JIpBLKGNq\Rl%:yQFctd+
B^FWV5 #FKDMehV*$5Kh<#LX\I+ccF^lkc9nA8c1dKM=4:QN<>dYqy8%BjG#b9^qA+qYl@#9pdYNtCY=5&NtcAi
4hw6TI HVReNW<awA^Q+%HVwQmG#Zb9^N&jI#>HJiinKPbGnbWyGJ4ISFhQiHy\ZpdVKiR1Nbny#*!XV8<>BkM%
BTM8Mj 8AR5d>w16:hI6G8:8LE:DjwWY>+8ky6@IHB&nhSiJIQN5CdMhYmRjnRpXu#w+MKWbMm#EEPDVSS=SG4<
cp<#j^ 5wbX\^eCMJ\5QDTZ*a%ZVa48B+16XRtyH\h\t\jAF*>6+plZ@8lc#5WmS!cHAVQ5A%61L%I&ZHEZZNL<
CcJChq bYpjiFV9=Q>m!5pyL^mh$kd1Qc=\BVylh6BkcE=A^8DMhTT+q14LXpKJ58?AW&jY9RmKc#ZCPND:b18q
AdApqa #dqAkC@+jH6HFJcVFcwHI%P<C/8XJpcpt5d#uSEFaqcI<HllYkAI>^yqYLPK?&Ah1*tYm\<ctJX<q!lN
k\bEC# $Sw1kLQ*#EP>ct\LGe=B*#^@<NC:INAiPh%XmqA^pnIJDY>u+u!lcpTY&jnhJZhmcW%=RQ6qAWhLH4p#
JwatDq W^SJuZ<=aC&R1$aS#<4C#eZXM55/jXPE\Fw\ty*<Fc$qMiQDppWPbC=HlpI?YHcJu$hcR>Z6L/?L/lKX
yR*XMV 5Qiy\^bpJ&ZWEaFAkbkA^/YMLE^dK9*\DTtbqTL9l+M+Hb$cZBS^#ctF$Jj+^*@:b9LJDyjZK%c4w?+Y
&AV:uZ +h?pTT%R5m/hHabNbGP9qHRF=Bit=p8m5amMuT/!Zh\Fy&dq<YdlqJaQY?%W/DN/:Z=dSh4YGi5HXQqR
C/^!<B C%GHLct!I+F##S=KNq<<ZP^MFXM5$Dun<y4#$FlJdy6W/6\*Ia8H:alYM&SSFLYuki5aLy>FWu1waPqj
^8Ib!B uA=nhDp9+V\$nYmV8*@J5HGZ=YL1\edF8au9%Y?/N=l6ylhJ#@KB+wGmSDcEm+9SVV:u?!y6V>J+CL>1
/aQ^Nm HmIBS^58=+AhP!IjliuQHXi#NY?/>4G&t4&>9ZIkdI\Sk&+H#?&RpbX/QWIE^<Dy5Z=9^6t15:XXPFF9
?EpGPn uJ1tDFPTEtaP5X%q>iB:t*q#t%!+:Y=mctt9DCBkycR+%+9MucaS\iy&&&c1j#B@M?Y>++S<:T5G9Y*:
:KhWXK B=\NlNGCV1&FIPJ?N@HpDI8aWXE6hhHEDqH$q1W64>ZTXbI5X8\&DVaQD:LMpBK1Wk>1Al<@$aX*$6&t
5:HXXi iu+jcJ?FhT^4eGL&yJ6ZWa!8lu#9JITbiXiuNW%V/C+$nXZbYXEj$l@KbG:MyD!K86Z^!T#*#p&PTAPi
by9BIl lh^auXqPh\e#S#Y?yWuVe!Xpue:HS#Jww5eWq\6J#WET/bp%KaaIkLG4%<>DJlhjmJLwah#nYRDZq:eF
yEpT+u #Pic:!XqQy\cL#Z1<=V\n>MC%SWwTwuiWCX\Etb%1Lw:d#iDIA5yucGXKueTjtIltA\>tdJi5SXuq>bM
8jHHA< jX*NB4bSVn9Ni9HFM::qBGLd8w<5nK*:\6SuVlj=W?Mcqd$ZPneldX$D/5SY\LPK?CE5J:k9F#+DI:HW
<QNVZE <PH5A#%&!LHGVWAkTq!<8K$RF9cI:k1HA/tWuPJ+*j8Z16%V%!i^d!R!MGeN=/MHh<YV86yk/ZHI!6cH
EZAtDn 1uZ&GVMyhW5/tDD^XWtRbM4\SJcLpQ^AX8W1H66K8#QNE>m91FiDK\Q!w/DLn<a&>@5:HFd^uAkKE\6j
N:w#Q! y/9QNE!@!5<WEm%ZYh+ZIbJYaYYQ:SAwq8QqGE!MX$cZbj\P=XR/&LuZ8un^>X8w&%4Y*h5^DGtwLGEy
NT+D+: @iJ+YjCm:@eB5/tAG9L*>L$nB<NSPL!=HMD+5%KuFAL?q$58Rc6n/bmmPDY<+%YWqA#R8b\iwk#&neC!
9*NI#i F:M8j9yG1D:jYI\NEt4HD9C*a&Z#+nn^eIp/S*c<EQ#<5klTJb$EjP%kZW8@lBaIaA+n45Vk%T!Z@ll%
@<l46m Rw#aqtyqE6&th%Q6qn\4\t8C8VyNy+p<Mul8uS&I!VlHB\w!%/W@Z+kSZ$!*!CLG!Y%4d5Y/C<jp8#T/
LM4@4P 1XTCQ1M55u@8uYnWbndwTQp*4lQHkkkH$J>XK$jq@inn4pEp<:d6y4ReMYpIatRK:61N/i88<RtYHq!D
hmCI4m #+!cLdE*=#=P$=wZLLmla$1Q*Qj^+ackVF@D=1PZ8Kuqk1mXa\!4ii4qSA*R%Q6C*P6LN/ahEyNi?9cF
-AjaB8 00013f7c4b800110333 Page 347 of binaries1.zip
NbCc5M !Ri?mdH=%>FXdaHSw=4C8V++CTE86C8p>T1KKKS:$nq5qj4T=h6SVh4LmN5WBZukH\XMEVJ*jWMEwN8<
#WB:HN QL9i#>XP4KG9*JkHGwQyd6w6W$y*/RR+PLLmq6DAPumyV!=n%n%ac8Bu>VuR/NbF%$PDCYm+6i6jE1/N
jipERC j^b@h#m>^eN:%J/AABmnS!GAm\q@CIBmC\IwZ?:chjM^Ai9XhP$atq\d<D^W5#I?ihyeQ^/mw<EX%lBA
ZR^hNY /5A8/Nc/<!hYMPljwIQdj>chZ%!@aGG>1<4?*>5:bM4q@?n^@e@&#6%$?dunyBHQK+8:nK6np6!FwR<D
QBk@C> XdQY6K64LR:ql<ZGbj54%cKJ#5n!MiVWVaw?DQka%chNDkLI$ECEAIc!XBcFG/+h1pt/DyBe+#y#=wZL
t\uu=< ?8+uY!b>QW9<INQYbWXHCqWndqdCTiNe>Fc#C+iHwiM@MEdS?@4T!/8DdG8MDlRbqGB$Ytd/RZw#Bw4Q
h#IGK+ 5R!Ah@FqiHB+DHuL&^9VcWpTpy66N^hW%G@T4q@PLC\1#\FBc$NWHpbmAaWe@G98h1K^RaJWd6yWeB4>
TlTnVb >BYt$TeIp\&4^qI?XZdQpjPT#nLJ+qKTVuca6kBcHZI5jFpl*+Q8Bbn9uu?K?+=Ye5m9maj:Hh&kj>w\
SQ=?t: W5mAF%^#MK!&dWXiJPq5/nLM5yWlXipnM/:Dd5BTX&N:lE=$ItVR8pYp1Eb&NXuelXCePIZ!<Wh9#lqV
%RqK4J #nZd95pQ>Qm:J<=Cn$AAG1llEIDdE&?KZj/9@hEGM4MHAY#wmS!cVZX>I!i>tkDDJaPLmb?D6#B?^wQ>
u4$WP9 Q@dLwdHBLJiCEw^+a=TD*uchV^djmR6Gj16%tw:km^t8@Ic<NjCmK>KZ:BIk6:/kS%Nl@Ry\\wbKb>w%
&+SkTG ycQHR*T1lS<VQi4+%d&adDnwniZZk+Cp&e:J9Mpn8<F&IiiZJW8Q:$$tu5!AQ$?8=@+VSGqPLmDu@^>S
Rau4TS ?u<@w9RaeCeeSjTjRbSP$TV+RF/19lYYJGBK>Ab#>Q$Zuw8CaQSuM+G1DHC5Ft6\#FB@SHcPl?9JWme5
DJ1AFJ RG@uSGP9R=dG+&DubMCtXSIZu+t1p9!G#TQttLDK6RtVLReHI/4?wnpQMDmHAJ#k^pbt^W=kt>%$E6<L
bl?p!$ =*488QQS#Nb<1$ZL\a^GY?^6EyE/!n6^Zn+LK/KbBub9XeHyia<kR/11EBXnu16hynp=:HqinqBw49j#
?eQZ?1 C%4dWuJ#QcKd8k59X*YW%T?pTk!$NpZQbjm+4MVSphXP&F?FM&8XKBw9ckunn?D61*LQ+YGq1+<9>Pjw
JRpk5m <Vb@*qW#1Mii!!kVK*Zn$Sd#\Cic/M&NGGbY>BKVpEL%DXEV!IQ%^X>My$!cua*F$54k<1IP5$NiLkla
TBT/jA CGQY/QM&XMG%Wj91\!tQy<V1mN#EZ8F^>:Fu^Zj99wnQ%JB\W9E=jFFb/!#1*bTn5aCaKu1:<lmTp:D!
ktdCe$ 6NwJtHAPYJ$l!li::YR<n:L6P5wm6bq5jT*4FLnBH/PNd9:JTapb+1<&9:H+eiqPebF:a4@^mP<Vb/%#
Zb1YlI SjHq#u&XlMbdAZGcY&\8eaunh&mWeE&:ZNdNe>5k/%c#bC%LHZLJ%/^^iWyjXiwT:>X!NB*HNQjGH1P>
SGd$K8 y^i#*#d6w4/4Qn8>4Z1l!VW>Q#5:@IN=4lQZX>uG=ERVlFcL@$Fa^<*/jqE4P8*GYc9wTQQhme:uESnd
\?NkkL Zu:kn&HXM%TFRVlW@HqSGaw:qEAQWHFbM%G/>T*&q1LcS6A>++K^++RtGyBtjCeaLlGc6J98XjpIFSWm
pl<ymR @$/E1Cce6Gl5t@ZwCHJDmG6ipibHtj*6#>$ePp4pjaY$nt:b\ZJemll4+RqL%u4<P+GX%^bFGd/n!i^h
EZ:86C eBWEwM=$GISMjhqRP@?#@lB=:^!FV/dwpVKC%JduWQb6jk^G1tXFL@Hm@C^kMZw8+XW9PtDwHI%HR\@K
Q^^/Q/ eQaiKT*cFMi1:QP*ia8RN<kMZh*FGI4/J:eFMP%EGZDR\*8Sq+=5kD$j4Bu:qK6DGn4q&BX*C95WePjJ
?LuVA! T#Ymu^qJ:16kj&::dyk*4$K*4aXJuQ#JLJLcCN=%#ZW*%I%L*y=?<NK/Dh8hZ^hD!bli!4RkKYapRiYP
=1c=F@ ZmJZhS*D%%1hMW&KX*Sy=V$TSEd&\>GRuYFCMcJhetDl#CiabN+mYibM6L6ZBFPjPleb5nmVNyPX8m?b
G>!Qc/ +ykce/IV=edK4KQja?=!D^dL$Z^kPPkJD9Me%AYYicMn\mm8llSd4pA@E/>Mw+kKNC9eXBbX*X:IH*wV
:l$!1C edBAlYj5u6LZ\I&?G=nN>bKbu1NJS$b!cpL4Y4uREVEmMT=5X55KJ5=IK89pP#LnT6^GtTKqnqnp#eTN
$qqk$b jX8biAac9dZ5EL?Wa8tAVyd>ac&/Qc?h:d^!KQa!bAI&YjkA5>I9!5!cqS9ZmZ:Z*S#>adPPn^=yQ=A6
aqQuMj 4DRe4/%aRYTJ:tWMjDj@$LcD?V4!jDX!ZXBHqlql/ZmIhn$8jib\QSJnP+GMX\C%^Ni+Hk9Qe&B=jcYM
*<SQ1% hWJqwTKhWqnScA+XwSESH+!H%V+/nK1qNFT>8\TKa&@VXkF%\1Yi=$Va*El8te%1ly%VJAW>T$t:t!+Y
Cci6mp 4Ne#w<<CZLVeWIta8ll^GIXSbjmH6YT9u<G8Etpqt4\6WHIjGWHk!@cWYSqSbjlBL>JGWjktKIT<Nm+9
$du#LE aTT@Pn>/k?:byT\99HbW&&j*Ea&cKVyKG*$p/FBihX16P*n$DTKC>kK%d<#1DCPCBTudnQ4+<mR5Fbac
DSa6I6 FFtlnQ&S<RV\R?:E=LHJTue?$NHG1FAnI<@\<+$JCTK=mt>5WLD%mC$HyMn*DqtA6b?<FSFB1LR>A#pc
aPSnhK k=aK4ZZAw1JZtliqu*cPG%VX=qchL1=+>G?eVPwCPXVnqpda:<mhHhuV+N$RTHMTXNE91M9m*dqWq=9+
>$RXeJ *bd=TwKTHp+4HSS!9<$SN/Yi$wtIylNZit!Y99^W4/CEaEqc!KYnyV<G@!G\Rm&wh5aZ=Y^j<AZ4%Z8b
JhnZ$J lL$+!j*IXT#1<:ybbN#PEa=1qI\GjIbny:m9q4Jl1#Rik$t&HMSa$VKwDL&!hNeb+^=tQ18>BYkwbASC
P:JweL ll81uIuS<Ju#md*H#=C^?PM+w?^T*4/MYWu^/*!ZqwH>kq:Y9ec>!chY41Y58!>Cy$HRSGF88YJk*bGu
dI8:1e tKTupl^m%4GQB!ZN&kJQX5aGLY1ywKa+&A#jp%F=VyM&\<Kd>*=AhlTQMKkFDk:RHA1nVBWTZ<dQkNni
&%h>@p =6aPFe8G##apV<RCuh=u6Cb>1Z:wy5STyDeNyRRZ49DewLW+mNmm%a#ukJ^G=8+Si%Si$<MK^1#<e=Rq
Ma5Vic 86SaN#/P^L64Nwn&qkqRVVqD/p!>l5dEYX9i@cYcHYa%Jy16h4FHc#h9R1uE^HNk^!c^e1HShI6/Qt@u
QB?G@A e!*9HQ!QF<e1=hGZ@djI@w:SEw4Mac&E/Xm!5tpHBQCBp+TPNt1^q=*:mJ?+1AcFF/&In$*!Zy+#\%lS
/Q:uRm b!hPL?8%/qt<Ly*QJ=N+qCQy\uqu^PI5Bq9ed!Bpy6DwP+pj*hV?yiF4>bHXX:<:SA5B>Gbji<yqAqd$
PM1CZ> /dbQ=m8IGh=mAAu>iaR&Nw$yw69VDMTS6q5KYqSb\t/iNWB4EmXyG\eM%Xj1m<?wl4*Hh=!^AG$y<dpI
XXabi& &eK99huI**5*k1WtyPQqq/1*!$8S9E<5P+6qE*Tm4udKSa8SDh<eM9HScMi1$MTm!*PJS9XKjjtGyJ+t
5mW1!K >%:LP4BMMpMPia%LZ99mkCId%dCkTDm&ZLFM>R*WqHcqT?W*W>ZI<c!1BN6NBptWBKc!M:a9$ilqb=IF
Ju?=:Z FbcLJ<FH+eCnTZA6m?5R1miHHFChhaY44H^=^>%!kP?=a?/?ZZGAZVC!XC%!Ncyi:wcXFc>lCP@?64%i
8ZdLi? &N\?dFKV+@B?DiFRHVd\eGw<i1=yyHC^ePEVp/YI5/Nu9KwnJj=uhJyNBP6t?tDBpKTNdZqhGHtbkmlb
Q@bA/a tCm?19jqphyXIW+\6Hjyle=e64+kG>?A=$6jHC66dbaCEkM?FwQ=JMyS*^nu&CT+Se=W9ipkmAlaQ%^!
=:e=MV HZmJw#KBX\NjKMYE5489/Yah^N/FVjq?yK+X%c$LJ%C%aJhGb5Beu8+4pT^XZ&#u9i5AFt8uJQw+9E5*
d>bjCw ^\DL!hADMwN\EPKFynMSLP#:>&E!yMX1GBd!u<Q+^=C?<ZER>W#5IhhD?>PE/5%kSnC\p<Xy\1JjudQh
%VtY+h SZB\pw8P4mhpNekG9!4kDc>5\898ZXi1n69N+FLuRCd:lL#u&T66STt*=%PQ9WGd=p%Z1D%NF<aIWMZk
y!9%8h q8m&VcbGi:EjpZb8H&m@BA6@@MZ$K<G84FM<:leH+%nJKe9#bQ\?W&>M+%j5ZW!nK4nudRPMH:BHe$<t
I^!:m4 mqFuTpk+luppQbFy9nKb4lNnJPJZF?HZu?BdQ*5BJ$epVwY!*ct9ZpKCJMXkP1ldNM%iF<$a>aIijRK4
^iCPCq <5JQA?BLJ@#^?Re<8/p*P?>Q&h<^8d$l5IPXWi6m\XDn5ktXbVe5huMluJWm^kkQpq@ttP+H&i!HY6kS
NHqt84 a*Vcai!6MS$kY\G/^hF:JJ1SA8iE64hwaHaKwG&lSK*lh?:awN59K+LJdITQuu8LmpjSZSaLY^#^d\t*
MX$nm9 >E4D>*JLB:<TGAT!R+e#>\=CcSVTcFV\Z>bVYdMKW^5I5?EIe@dV>S1Va/&JYBKLWu\Xk1>t<YkSJl8W
@d9j^1 IA6>S9GJ4pCYcTMBF6GVciNu+RKS4W?Iy5ZpkbEW\:b@W4Zk!p//$Wu/!lZi:KM$?e?1BVJZRdLAMFt!
W*/t8i W^qNd>K4%*LAXDuQFC^k6I#yPEFKwq^KKRC:Tta8S@c1VKc^T1H^w\J&4D\\Wj:1k*!QqPLXyMLXP$Xk
pCj5tH IWEkAF9#w^JWPYGiqLIyADERTlE:V!pZRCRKyj\TTyY<HACFwRJeXQE5WYu5WLtGBpBy1e+%KGy?Xwac
S*=8Nn WMc?XL1GW4+tX$wbWp/=X=>dX</DKGqSKnX?%yluXP!y$QVM%t\5$d!tX=@dqH8Jy1Cb4HJ6wbl1wJGT
GeM9Lk 4nk9w1Q=Y48JYm:qw^d\Ww+4VHP8SW$$VQj1Yu88ScqHGP9/uS/ZmV/\T=jLTJ?4RL<HauDha<k%aAmX
/$6:=B 1hu$\TBIT=F5\8nq5qHVb/PNecT<N1E4PmmNI?GC9hd6HjlVj5a=IQ!YH/YyNj@YF1ZXBhWAp1n+b*=6
&46tDS iI>A>!Za9bn9/B=ch:VBRCw+RRp!+&hpK=K=@\k<ub99j%>hAm/!j$9@@Kj4E9D<=+nyRF/?Q/qL\M9:
D#nA8V >*WJiHu?8dwE9MD@WJiAq?6Q/^L\@EucMk@d:>aq+PH+DYwk?!@Tqup+j+Pcp?eZeM\<\N?l=9wXNhj9
Y:HFI: WLQ>w1wBD@h9WHMAj+F=#5Q#P>T@A6Dt+j$N/q>u&QQ\@hcW@TK>u=j69$Z>P<L&T?S\*6<SNt:iZ?Ty
M#bn9k <@/P5AHbjqFTkSj+y%u8@@DSj#QL@WuDeAPBbJ#e9GVeZF!@p?ZP!@Wj5>^=jkQ:t@5Q&N>e:J^@p8ZP
LqBln+ !@%j!HLu@m9&N^@HH:C@Pj/LYi=A4mi%>n?b=d+QSjZ@hJa:%l?^9\><Jb$a5^GS!5#F8!66BZE$*<L%
aPS@Zq nc%jhPhelWIA%\w<cK\R\Bk$cPaFBDDQ6CdaBRE\QaMAbFWkAM$G%\5I+KGY>yFe=FF>qHF*?1PihMFH
aV##JZ 4kI/Wk:#*J/8jGDN4XpLBJBI@!>A*^lFwDGW4whIqh5Tu9%aS4C8E\T\I\?c+P8T6DP=/HPBACk$\HaV
E@J4NR h=V!EEDcC>A6b5/q555$we=D:TwEMJ\CAYS=BEVMhP&G4+MqT*/twE8uQw&FG\K+wBdbi:9?9/A*EGR1
-AdJPA 0006de9d21600110333 Page 348 of binaries1.zip
!nkGVi p#8=5JV=GlGFJ#j5&S%A@?&#94GuHu:Fna=jeYNIBnYIKSJyYbL+EF&wVFRYLkJ8Y&*K+t9nNHMGW#PG
LMb=4N Xymak4HF1i!T8iE9&8l/XJ@+<//^jub6LICCc^6Rl^PDSw\tm=jiK$5bn/yXi1Aw<TahA6kNEnq+c9E\
qNH\/G #buE=PuyaCGARqwIwF!9%ReE%5WCJ/!D!/\*h!GAY%PXP*HRZXFeFA1$HT=PjaVAa5S4a=#e5n#9Pe>8
Kiyk%y p\Lk?4qM!VW94:>EPywe9aq?clH@VmEE$IEJtqTb<+BMy+^tXSl>akdEQFNLpnNcJtFX<1EwI6C<i#jp
KdRQaL PIcZESyl@Nycmncy%G1HH:Z<C</h&!Y^WiG&p^TN^Enl<+NK<*d=<+wpKWbnMQ+5d461&H8!iYetY!@k
nVa1SL >6kQmeRmZ\*RS+bh%uVFn484mJ%BZ6h>8q!i+^46hbRG1%*4mjVWdFbGdph%%qMLCEA*wB$!p:Q%mpK/
m99q=& JhZ<m*kMJR:n8abVD/#LcTAVLqkkQE=FhVpMlTmylW?9p$XeQquFH1Tj8TE\?cQmmie^y^AADZZQ%@5m
J^BjEi CEC9T**DaCD^=B*F:9C5J:W81pTmP8JNtd/b4$R%a$$ik:<8#laLm6YtTuR1SmeDBQApkDBSwqp#SyLP
j$@YyD %LEu5bJSnW#CtD+/\RGLd:=9F5NNh*$\8bpWielJl6%A$SaawTVXWQ?EK!HGKNXFG8J=hP:FT&C/?GmF
HG51Cj JtmF1c!qIYyBFkj4TyWI6pFqI%/@Z#TDAAlM\IwnkSDARRWE$AJ/tP\d\c@<Jwdpk/E8?mL4%il%%>aT
q#Jkau BLA^i@eVy>T+=eGA>IERbQnq:\+ea=IKyCn:l#e1/G**^i:e!*NPl=>Yk#uIeF:q^\:wkq&p&4:p@pLp
*S@m@a Fn>upW9n<bd$IWdqKK5M@BAQq1c>u6CEAAJpIABK4L8>eqAZ=hMTm*#$$BJbV*^cq9*kD@>ec&QI=SLQ
!PLcd$ LGAJR\=y4+h<%<<hRYh&n^/R8Z<$jwiMHRcnLjM*Tbkn14dcBTBw6%=n!wk$j8*G9b^FumwIAHeIAwD@
N$KFbw nWQ<>&>NQ4e4jHAJt*KYM@j>RW6/BB1wk\B/T1+u@8HSaBiBjB4hCeFP8*#TS:jT:c+VnYhhj=&XD/A9
+Zy&S$ <diHZij55aM!ZP%qnBIe5qMcm=H/NjlM?<>4%LRn!:aXIjPyuS%Ya:MS\CVC5KW\Jk#L:dH?m>\T@#wD
9cRqw: b9PbP^N^@pn9m#^5?BTETCDNt%Xp>8@uZBP>?kM1i9Pbtn?iKb9WEI/1SZEQ!MG?npG^<ccJXK\4+jdS
/Bc<JB %EmZ*dEpdhyw4XuaIuJA4$AH4L8@An88G+VYtmnbi$MAQCiin=W/YSBA=!L+Bhl?eERQI$$ak\&8R@\=
+@HARP XD@891/*1aJe5W>JqB/ty8=GGn&q?ph=c%nT!Dj*qccX:bZL>SeNNyCFjRK>u/68dHVmchX^QBbDAKwR
uG!*lZ RH@!5#>I=q>=EEVX&S#&lW?*LKcen&=NkwiEj9T6D\?=tQ=yEQteb#W#^\hqY/wpG4V/aYq\n1l8dSZ<
>MZ68+ w>9Cn#b^uKnQmdbnlGHmAH6a1Z9kC&cE5XWS!GKPbAWF$#T#6mmBIYy8dQ#u?A$IaDVk&DL6T\&J@d!G
cdCk5X qlXVJRN9F5jWN^T$mKE#$K/IY?>?+/M!WmZuRN@dtQcV6XyM91VR!DqC>:Mlj^Y6Gqd>L$%XAXY$Jui!
&C+wEJ E>jM/8$hD4:ZNjPFJ^CADD+EWHFEinGN<EkyB\Fa+i>E/$u9H1&?#\>jWh=/X<&?<H%SDum=^mEkZ$iG
bEWY!9 IZ$iTMGS5=1pu*!+Eaj&WQJ6wkeCTHqedlZ=CVGNANd+aj&9I%$n9XZ=uB$CAhDjN:k?ne@L?ijhp=Cy
%<Ln@A jeE@@iYjc&eW1ThYnBV1CF^9^9QIBj4?yM\!d%=^IXiniXGCQJ=Wl<#!w:qCMtFnWmByIm\lwMDm?IPM
8ItZdN +m#TGZj#Ll%ipPT&1IP<B5hBqu$\ZCQRZHhi>b8TmwpjPmadHZRkN+\nbD4HNd+HlL^GiYdT^+Q+kHe&
jbMR=% $T5C><D=9@dm=JQ&@m<Vn!Hq6>9yc</pFpp@:a!#PlCA<>QPq9QG@YtnI4&eB&%b9EnNj4d>edERw&W8
j\bwF$ kdKWTR+1mI!$%9Lpe9*l4iyuB*6bZLGBF=E:$c$mKDLqV%#4Y+MAILPyZF?c!W9tbw?R9/FDI<FB!ceJ
E@pyje DlpN&4y\!eS?hhDwL*&G&^N!wk/X6**?T1k?>p64HuFqYykCQ*SS!wMw!+#LFHG:i$H:Rt@JA6M$RYw=
/R9VpP hnlS:*C*P%46ncdu/b#Xw+eB!#AVHc#6cH<i$RlW?9&$964HG?8:L/*Yq4kSGAyJT9!1h*+1bhJXRy%^
yI=SBl H#1dckK8@PXREL/yWK@N?hehunRyD=$P9QhZKuuQi*IAHW!SXE/RHWRYQA/!D*u=cFC4W8WdqcMh@\cw
aJP+9E p=V@qw/9LX:>a>aWSp5u\eQqZ*bPEGR8b@e*X*V5/ESanX&y9E:1bJG!=Zpb?KIpZ15Gcay$QyZ:Hakm
%BStL< 9?k!V%QKB1eCB=51VuQ6hKcnRqHTd1ZBMIS=\%aVPpXDhd>mwFVFC!E>a4X#HVKjIlSiR=@Ypp>t:SXB
YERl/E b*HjZIJ8P>IY%GJ@ZVytIGR=RyB$41WyM^bIt/mq88*?EZjHddLpEA$@$8WhIBa9+%/14+FVy&a=H!\p
YcdtcE 4VhdI@WlnBYyke<4WThi6Ti\\Ep@=HK>p@>\FK!NkuIk6XiWWHdQRC>FN@dlXD@i$cp1LV@J9dZNBntP
c@Ade: t*dVc\9QQ6XbBM>S<1C66eZ1pZ^Wup<jRY*pVT@DnICcLZ*ZJCq#iA*u8NS?yF=GQ<BCm6d?*QKiRiDX
wFt<yZ pXw/VW:=MCZFk?RYnl^h=Z\Cq>HRaH/wV59XELH\DWWj#uI5QdYiJlLu?Sc&N/M:=c4n%EFLI9:Tq:4C
PK>F+T mI8Vn\^IeDRjp?<q4%j:5HLp&6?NPQS1!nhII!YlX/VhBJD=Pt&t$tTYy/ct1%puJka#I=XcGAP*=4FF
+KByD? RBLNLE\8lCjjTQam1NCRAE1A%em!Iu\5XZlK+9D1kjEjc#/1hDGETB^N>4JH4Ri#yN#9TyZ:5&imnFW?
&M9:FG +!CHEeVDtdYR+R$NLXqNYJVt1B#?&IYX^\6T>VtuCX9KYw^e:#?NnS9T=N=QNwcmi#5<DwN^+IpSVKBp
4TGpM& 6*b!Ey?%46dtEKcZNa?j?AKJjW9!hR$8Nye$BBA<CXqIce+8B?/G=+/l8^:tEm+t+&ywjQiik5w?%G<y
6na5R> k1bipw+655P@eDd65DCJYLV/=lD4#/QN%5F/SK?#4T#QENBh/4IphQ>n%hE9!?w?Eu1>qZW\lk?/WCPH
Dea9&u pE8au&VXc/kn4XBT91Yp+t+eG!p1Qh=Cw&WbcKaY\&?hK=>aPk!hMWG9H/4Q>i1^54TT!>Su#P>=JEEk
pL9j&i $yw*iHR&+cnJadcbj&6Ip$/S=&8CqJR^GdRtWl*Zwi:LH**QZ/a!d?uF$&6l!*/&:@cVPS*AP?G=i\Pt
9Qdb*9 !um!CbXMHn>CAH5B^GQkK>CpFkRRGiP5Q5HZ!K$8HewwP@$bupbmIywlbR8AmEdcGBBD>ankLX1h@:DA
M&T>eH knSH=YF%5@K&K@8M!65<Qq@iZHjkPBZ#4u&@CTcipBu8%Y4c@Vi*5aKJ+jd$8GPDXESBZ+$\Q9@\^:4%
GBNq\G XeI5!kk6pt<T6IWWmTP$Y*pp?b4Hu!5&R!14>Gi+a+96Q1CLtTpD6a\bN:yR?*=m/@=^W?a&%ube>wFM
X:/6Hh =i#>:yIP:X%WR<FTKYN/KT>dWENFTp1mNLTY>NG1Hc@MmaJaVKtQL@PbaAA8uJd$QT5H@T1?+/p/PZbY
PVD4F^ w9ZL1^/KL1\EH?/4>bbQtTb1uT*^\aj$SA+WKSK1PK?HnE*BW!YHR#$&bj*tHP8SJqpjm=RRdjVDBJ#/
bBdiRj ecDjQ%q/$<ubA1pS4uPT4tHGLN\AVL&!e:i<^?RqkKDdCe4aYubRAPbuan/be@wd\F:XTG9WVJhN*1&X
a5IM<1 pk8I\PX1X+!/^*VCJJmmYw98YE!\NdcWnnEwdXLuJRa+YR\a\WhQ*V4T5w!wtkB\*tw5P*VVK=m#\t\u
aKCCJR VJGNPd>V=IeDMAdM96#h@kA#^QLc+d45pc#5uIilnpnmHQD6e<Z56@H9Pn&cKC1SWniFXA?G&tGbQl4&
*\qGV< JDteuTn9:ZC1$pm@aK:6Iw+!lPKW:uZQJmNyRK*&BCRPZd<VJjAiWcYD5qb1uY@bE8M>1L4GFKJn%epy
Z&yZ/> QcG*PKjw+AX$h4P9:VpaQFpZ9t1HWNYK5XVKR%Wct<d*Pq6F@J+H5Y^jyM<9=nR^?nIA:^Z/1i&G#&>c
k@l**= c6^juWVKFB9*p9Biw\hTI#GLcnMQN#HY&ehj<qd$9Kb>Jq%aF@A66n@e/HN&SlZ<phmJWq&h9qE*bj^X
DQ^pqy %AJdITQYh>H6X8bYn?*bbkytLq?5P#tCjlAi49$#kEcHj9beZIk>wR=5I^+F4pRbK*W4l&CM4#RewWla
^IlQHJ Yw4ADS1!$pq%9!t^ip!KDmWwPyp$&pNi=^5&u=NVGX/m=X\mQ8IM9=P+Jy%=?=9?j6LRp\:yY<nMY<qi
TVtMpN @AQB$Wq6c/wy6BW!#T8%KIINhRub\MBuFXCmTqB*!lcCa9%YR^^&R&9Bw5I+^ZyybKI58eu>TQGN4@&?
lX>j<R n?4q8#SRNK<%p#*Rj8@W5>aNa#lpEMYlhQhFK!HPDJkFqaK&=J:e+K6=CGC%C&!#8hb%K9N\dZKVMdmd
Q<Y4Gq awciWZa%IY4K&H4I*S%h85^^\Rq:$<FGZYtVTC%cGKTmSduHlybZ^Qh+5nIMMJjl\4Gy+AMi1M<Z&#pB
CWk9ZK diKw:idNEh<u/GGnM1SwI*\S/nRJIAM?Ekwpe*/Byn@\hcGaWtWk1^:c&D/:j<S&4b58<8H:+l5LuCR4
nh>4$Q LC<pCFm#CPM&yh>YNBbCua=^##T&%IwQ$%Y>5!?6$i&>%ly+IhZwJ4$4GptaaC8Db?jn4XqZw:KhA=uN
t/=FV* +I/*NpPu5+4lEeyIHwa*%lIC5>^/HPB/6HwlX\&#$\*+8AEat9kDBT!eGq<:YJeu>TS8J/yIZ!NhmJ!F
LS:5?^ aDqBD@hQl!euI=AW<FqZ=pcmDV^$R\CKLXNX%D:GPwp^SZEVR^EiI@Q!5^d/j9Zbap&9Ik8VbNAH>uPy
twG!&m WE1^iZ4l:<&V>le$<tZw9CSn#b<Q^!c%!%H/^lu#>8ZcnWMuZKpPA>!F+RYn@D+RRkDY\q>qk@ipW$aw
^=@KM/ Qwanc<c9SuVLql:Jp&bM8BT54Lc:B$>TtTHRmDkEdnWSe&MZ5Tj8e!NTIlQ$TqM\/J/dQ4P99c$dtmnR
uTi@uV X?FWI9i/^k8NHn6BC$+X<1I*ic?^u?a+CkGk8=Fu99@akDH*@clL*kwFhY!DhYJWcn<?+4\EVdcF=G%W
IV@^Q# WFe#q?h#DM#?RYtpaAwF%XSa8T=$Ebe6<EV>aJl6jcdYDt^ZKbS>tJp!6R?MMlCdtKNLXQe8cy%A!wM<
>SB8yt M1PYm$n<hFwtZFkJh$bQ*$=9Pdw!?q\>XL4&*TAEkQtpJMM+A<IctGd+9L^<4JANnl6ZiRkB@I/epLtW
#WC5@R HJcqP@j<^5DliqcG?FBbJX6/qac#l++jQcV=XXqdCmW:u:=S1iuDtiJIMA5<<KdwE^i/!>H:EP?<hJe4
eNIhZ! Ye=:Z96CW<jS%:cbnkk\aGtMCV$a\%CaLP@5HjYpnGPnJiwnM%M/CPb:$$wB4CRC**t6@4Gad%9\aQR/
*/iqAy cY?CK$a?p=HVXXETEIT+:u/QFEkP*J/y$m=&%1k#Z>5yitXBVa<9%5A8JLCqWHn\nLce$6k<VQinqm$8
di+*SN %=cQp:LA/#$uTpYGaDW%yF^yF4Hu?Kw</kI$N\jAD8cp8D!h#jX5b#/E=^@>$=\P645MHXd&L$m%yVSp
-ADh66 000c331858a00110333 Page 349 of binaries1.zip
*:GIA* iGA=8YCC:ReeGnVS9W=PRm!+#<wNBpjLw<wnS\6bq+&LY!EAhTE\%+&Z$?DuH^PHA*X:H&i!+:aKup#:
P^K/S: ?b^kNAun%hj@ac9T1:?ELPV5Qbtn@<u!68=FK>6jGI/tTlKkEBVPk<&TIjjBQ6j*W!=yGeNMR!GG=VR$
JQ<SYB W4VAwBke=\*TNEcY%dyy4YEkQS=L>bR#58Aa:yhBR5JF4wNdQyT=/DDy%kS@tu!:9@D6p+*65tHbW8&%
5IeSiA KR/VQe<Zbbu??>%SIN&P*BedYCbDPINa*nKnmJL?<1ccF5Zbh:BM^RdlSTPaH=B6eVX>Xc?R^mkV4&+5
R!/P/$ >FiqZ:6V&cD^Zk%SGF=EqIed6h#L>@WV^4Z!&86:9eQ&1qhYKWR&#FSTKbGm*XR#ttARYP#?CquMqCqj
lHaM&F qp?Tn^upVb=@6hZ6Sl$wEQ6D?:+8<Wnj5$mdV\GZDwA$hN?L<Y\%n$u+wc=Td#GE<^pM@tma>W*LFkQC
i<!98e !dtku%8jhm%:D%*/S898ARq#F+^$cbEWYl^by?q59:VeY4<1ulZDKy&kn?eA/wjmEDI:YjdACT%V8uF$
pt#9Ru %WTX^n=Tty1TAYYNq\imTkF\!Z&*8lba?uZimk@^JYwD\Yp:qeYmY!EqPCK!qMS*N545pbLhFR4:>BBA
ETDDMH NQ%a@JwdeNH#qk@Hc@Mi4ci$t&J$@KMu$9^RRQc59^l/X4WYkTb>Gcb1ES^Qqh6EyT+61nyy@C!nqMZn
K!KWE* @p=1:14Vn#H?nwnaIl8G$titcpEA%^PXt/cAl=ybRqD%h*DNKXaP?WDZb@Pc%XwCyT1:pi?:DQdcMbYI
F!F!nW XqR+ZCSL?>eP##Vd*T@E5JS%wYYKR+QZ\/qbQyRMmnPti!Fy+ikZe4#BZ9WacytPG15+PFjad^\:JD\u
Atnk6c n8?qYwIA!48*TjWcbHMVLtp&\mTS=K1<E&\FdCBVtXIX88PnbiRX=@ScytneX\MMI6tPnqtj*tG:nX=M
j<Pi*y W!P46Vb9&w&%PE9kNZe%j@TT^c@V$8FTl*6S>A!j<n?#5Ia!DJhRyPmt$n!J+?tYC<\kANkTSITMA6*<
Kd9yt> NAj*#qIYIV/M^VDWl$P<XCuiZi/KAwPeKE^m8XkwSLtNJte8q>&n>THCq^MW58Pu>9$M>IClF#\pjy11
m:heCw :EYwX:#&cdkWKyZW:R/WMPh\kPq8qB>lPGMKL?nGWq6mCE#tE<=jjFlQ@FF>K%imK&&jNl*TL%MjZ\5R
5X8EDK :YIlR%bhYTXewPI1EkQEl\e/?6F^nKN#MSJtieImPep:ujSd!Vp+5XHIJyaV&I6YEdcZ?y=1bDI:JZ!R
wap%E/ VjE6L/Nb6>QPlV<@!wFM9<$YpC+!XRqLZIl/Ml619eD/VuHeb:k/:LSW&NJQIqy*^?t99&=&RLaqy$?H
w=HmH: VX5q:L%i61ISu$iMtEiEt+KR!8>>t1GuF*4Xn*FY^H8t4@F6mK9yI?aEEmjdXu<yXbV/G^jp+5bt%/my
ALL\iA QE$84T$/^B%?WD&j>eycHA$&+>leCaa!cGK&yqP61bt1Ly^DQ!^TVX&56Qy#ZaYFbXHWcn@ja^9F1j:L
*=dYLP %TYLyJZQ$GGSM8nq^aFbNKMMj8#e5=YEjPVe$*ei/JdKbNDcd*&>XaqA<<\?qeGIjeZ:QXJTWE4NaG%K
iLFnNF @Dd@+A?JVkZIa8LmKHQHW5I^tkaGWVQaSCqq?dF#%^w6mpZN#iyFbqKM*&XX/V8<XweaFAVp^DBFa>YW
ZFXj<H =4SV68Wj\6lQaVq$=tL%P*#wSG4wDA\1QHSX&jJ&5LX#XX&Wu\#+tdhX:@JL%cDh+CLk^D+*P*eKua?+
5l!tp1 \KwVYMT1LeFb1<JyBR!9>tGQh>q%#ateW@YC:8\lkJN%CID#:J9Jn\K\d<&DwwWdhW5RecH8uMBmNwDB
LCbKP\ acGL*&wAtZ8jMyk4mu$cR#!?%bSt\ZPWW:D^KpXikVKKjm89^jllcDw8SHZY^u9le+lAR?nYt?wb8R:8
11:CH/ i>G*^Q@!S4&>EnL:<<*AZ>/\6%e?/iwGG<nep:8S@w<>JG%He45<#Ky?jjp^VqFLDbK95//jw6dlaDny
VXRj4l TXW$w4J:HBhtWPkVDYW?ccuh=?>I1$i%n?Aal+AKeF9tYZcVb>NX$km#*LuM=nVuYINw><<H8W6Kl\lI
ae<Bqm C::IceGkQ/hnW1JDR!C%D9*tJ*S?eblP:*w&aH=JwXmdmb+FGB9?WK:la8=@ELu1kKiDLXJRyD8MVAYj
uy!<^b G%iek/d9Tj^y&WL9LZN4Y1@8d88%iL?>LH8y/dQu>=K#wB#F8k1nnNT+h\#nS+!Ie85@DQ&:HFLlQ@8*
/&b/X: DMtWj5G*jK>Ac%J9HnHHZ1bq/mZEy?uWNb$8ZQRK?#tH*aZ<AE/M9bJEm!=+\w9+RHqymW69:+M5Tqt5
Rt:?>L $a%9WWbWtI&>Gu$L!XeS!H#KRMZceJ&5w/EW=iDdHk5^b4wNZ@NeLIqXp4c\G/8abW=&Mw?dXN9?e+8#
@:hTtm Dn4/Mj>+?hpZNBYiTaZmA$9%9mpXP5h=qLdD>!yDNecNL:c4Z^yEk%TnCakyWjZiMN@WpcKkL=VDBBB:
n>y+w8 GN1u%<tPpGR#=jJk8>4mi#JQ#Rcp*8:Fc:SqRDi:p^8nMHA$idMFcJacLedQy5MZ?VDXWcYlEduVMVQ4
8>R@tZ uy89ib?#l%!K>QtJ??8wGhP<kF@hipt?qL1uEdGXnauA<K=856K+5yh/%yJlHJj9tTtKtKuK6$umeDB?
P%$P@4 wj/:6XmPh<KcGAWeDhw^Y1*uyHC9ny4ecBi1C#AJkAim<4Bt+&?wW&Z8K*G\8ewIZA>@1DMyP^bc9eYL
ihGPVH Ci\N#pG1*Z1%&?T%<1bV$:hnBVFyc#1tISQY9u#:YL1/*IhYjYK\k:6GWiP1cmk@/RW6GqW\q$4E5i1\
e8%cAZ aY4MMd%TPLiS<j?Q9dePm?Nd5+Wdh*hJeQj8ywEI:8:8F6\llAn8:p=\h:jk:t/B+Bw<BA9!JYh?S?ce
JM:Qy4 MJe==</h?<^*?+>?149&16yX9Z4Z*1?5>+Du&8%hXI\Ke/GMEDD4lA?P#:c*>6tScu%Nc1aYEZYwPq8b
u6HBlD It=eD6?4t?L^9VwYSnGY+I=\JyHl@l\+/QyMydW!B+:k\n%P\&6H1G+NbRJ1:EWb<bBb/@Qq:?9LK9Z1
6!1Pw! $/E^RRekRW^@qt/%?H#wnLK>m>H:tbTFjuAEp:da4nRp<4t!/=N#9lec@?FEb5Y%hMK=QunT>bWHMdc!
+6/:Np @&Z1B$^iC9:Cbe!M#Sw#8<1bI\&t$d$DSt^E:GP%NWP%i$BR@l6mJ>/#ZMdb/+<qP!#q&AHaAmSK\iJT
#iy+Bc <HLKjB$IbJ9eW\&#KllMIm=Qe*k:+6KLnZ=M\LtQyNwH=%8GjB*w>GIZBa\qacuBS%u*Ln49wKNQd4Yp
X9m#B/ Wq98+JMFZFQIYKRGLw/6LQ:J\t@!e$:!y/ua*@#nVVb@Ql<@qm*aj5i+pYD@iJjW?8Q%QYDw=ut!iZ?P
u9NXB+ c^?l=+^upc?cYq&SQVN?lTNnLH?HZ#d!W=H/m:9JF9I/6**:<iJdWVYXdiWmmnI/St1A$p$Qn!*unK!i
dPJ&F^ kta<1WYd+4QZyEYD8A*NVbF=Ri%9BtG\i9YJZDG&n+aPQq8jTQF<=$yl&T\QR+iNX?S^^PDu@pdq9F!K
G6b>#N 5jH^=+LB+S+\@KcB:4S%5jYd4w*EVhpF&<%5eyR:$?*kQaB#/%>4<@Qb>9FWd6P>\Z&4iVH/T8>R:/1M
$8aJyH m@yP:Wj<uiX\Q%@5*ia>IPtd\*>LC*atSZ/D+<kV\LQK6KF*wQ8J/L?%h*M=IKcJWWXkCELq1ic%lwu#
=J*Ka4 hX4i*jG=&B+9*ANc\=iTd!C6S?5Zy9eA6LIjq:j#4j<Hh49jV?/V4hdeA>#Jt4k84h&Zi\?H:$n$Lp=?
&9$Hyu XLu:#h:ijNlj@m@jC:Z*VHC8jT<RJeyeP6D>L:j4+@%W/l/j1h=qH>?c$VQcj/?WcZW@@ZhKtZVjMH:$
DHW!Fp <M*eWjHeA@:mbnHQ9$%$Z!j@>i!:u#u/?cj=JaNy?me=QdbjPyu8>:NHX=YXy*@=EwJ#=Z?:V9dXHT9q
EG1D@T H9CZj^Vu%Iil%yMI>/+iTbb*u#P?cA6bwqal5SI!$$yy=WeGK1/+SZWENlbR9j>&Q*dat8%$t8G:?EKP
VMCIeK EmP@?kWC*hEQK5ekMYh4h6Mk+\l/%G=%htSLWjBLNHTEaLXJYuMXt!^+A4N5%QaQ%Mmn5nytlIc9*e+n
<?PnQ: nV&*t+N<XINYR^G*?<d&GV:bP$?Db%S5T:yk$QqBlWu&&+$X5P?iH+Y<N=IMZcL?=I61F6Xkn5e9>wPq
^+nqZ= L?uuqBh4nWQB*hV+#KhQDwhGAM+%nQP!$d&J+IkwZtF!KXd^EN?W5SA&TIL6uH@=9Mq\ZA1*n>y*S9nq
#>*<?G E$V>D=EBM9tcu@9GJViA?ccb#\GEJ*1B!pEX8DAFA<SyKTNGYku>iCYEtN#=EhPNGB/uX/dBTyYJmWaS
6GkiX6 chSM&KY+#@EWmE#qaca>%tijZ6SYhJMiMSaD^:J>d1nbC>N$AL^$^J\p9Gl$lRB?FC>CQFS^8Jkk#?Qw
S!/5l\ X864I#KX!dH/N%:Z%8&D<NA%VFNBbIHm?Wh%&8/:JL\aXPI1C5Ll@V4mTtMuJkmp5:WBjpL$c#DaI4Ln
b1/Vy: hdp@MPA@M^!XbEXQME5hj@<A?=yW^5\mTK!:c:K*X6p6NKa$5lhaJZEPKP5?@yaQ#5BFeDhc@VtKHI1y
8XYt!9 VjyIeceRj4bVBqtjHIuAVq:IZJC/VqtFYLMX6!TB1Lm8^HNF!a=l+ke=yylnZ+wqGttPZeeKatDSILyl
G95R:6 8mcNdV&LDayHi<aGDVM%Ec9/+c=9&j=++JdG<I%>1ybH\dy1YSh&eNhVtV=QkW@mJ+R:#mlM@ti41V4%
aj>qbS <V>9p!c<mW$IFJn/>Ye<Q:Q6ECpeB!F=>HW:%\mBSW\S^G:R\/R&KY4Nki9!eFlbLNBWDeHRbw6dF/%5
NWY\+F 4Ip!dw\>8@JTtlWS:IHG%Ta<mKlZV+qWPn/@iIJjp#YK<>=IuAB:kPAnD?=#Fd$4m8B#T6y5cFH*?+qW
B9qn/w 5c%lbN!**Ghj&AjFq!>GP?LYCpRbnn$ZWp@1$k^PN&TwhM\q1QyPZ@l8Gb$\&WY9PWG>\VwZ8K^h1G+:
%?tJaF 6W#VVb$kiW9uy@GT91H>8VJ#SeA$p85mRNY#wHZh**T94aQq5#R<iR+$TTJDq\hmH91N\NZSLPGpiXk+
??@>qp !c=pQ!Zmp8cYIJHc94jKQ8VKilI@YL:KN#F4ak^WSIZ#uIP^M=m8t?lTQHeJ<lTGlGa#y4mMN4X@Pub/
niw8l? iLHbP*?6bDDWW9c85$$@?L*Ne^4*w6$>#*!6m*$ZlY:Sp#PAQC4#hM$6YH6J=k%AA=>\^lldXCJEZJK4
hw$l%Q F+aV=n9i?lw:LK@J8Q/umN=eQJ\ItPLN\qelw4&8DYLH9R$Inm*dJK?&W9F^w=^1nEWb:D1uBRaua4t=
P*ESa5 #XbW<?l:&*ZBB>Jp68/=Z^bRXK1?Y=h5#1MYbtawV%:a5d^>y&i=ZI1ThKa6lX8H&X^CML<N6pI1W%Y!
%q\Hi$ F146:M^jjme>dGGDNn8%T^E#15D+QqM:>c=M6=Ka<\%/q&G4Z9lEHJXXq\^B?5aIW$hPAFq>DkbXDj%#
#?>Cl+ 1MBFHVEHIqQQia&lFPtK&AJ/e!E4Ae$i!QPu8ZpE!WwcNm$N**Y^E%yKJj9<X$l*t#=Z+LK/EV>hYXNa
a8+kY8 $8^%lJ84bGEyy*!1NAY%i\&?&*d*d>X#5\:kt@1CcB&ckeujVBpkSjb#4nP=>#tJb:qPRinn@iS8^S=t
9h?/9R F*SPF4LpN&lYR5^SI8>1uam^>:j&eHFDSCl#kjm1wW8/Kp6bKkIuLQWYiLw$qn$?RWwE%:eXTSKj=XTB
\#&=GT DXHCwHjMtyBAd\!^NXL6&<I%lWXNwYdIC$LK#Q1$a8SGmbETyCKCWQZV@NK#yeKi8Lq5?=Imb46V#N/9
-AI/:R 000ae5efa6e00110333 Page 350 of binaries1.zip
bWc&5R VD:wd@nIFBE+YX4b1y>n59jM/qw?h#*I4NLFCtI:k9=^FwcuX&?+9QdGjVQ$@V*kuj6iuP*Jm>dVu6bV
FE^LBN :q?lX@?&^**D@qhIXY9Z/V%kpQki$Lj?K*#LQjDup#8P<^+R&Z6Z<QN^mQN#85F5iR?kC4>XHL/nm:>V
XEP<Y4 u:$VI:9P<T^#jn&qd:aASaASqHE%c<ekm^LJ>>eF*1^mHbjCwqcSn#pQaMMBMF9CYQQntGD11LM/4cTM
LM4jmJ m:#y9eci=H:&*V&kBnI$E*@+qY4aRwiyP:Sy!wFW:8ch1$t\nkC@Ate?Mn*C>Ej4ky@6S8?u+qqC>!yM
&4FheR w5c\NRK91:+:EIXj*EwwlF?*=NRhHdl\p8&M#9d??Ht%4@MKj%/RVP56Xi66nPubh:$4<:y:RQdQJ%Xq
heSy=i !Ji$wu5AC?Vu>Dd5HuC8pD\=:d/b8*\Z8Z\*AA#SLIB>d:y5L*iSik@a#!I<h@Mi5mFi\%D\kI<akAJM
QF&C<^ 1Z!wEy46jQLhY1!5^HL8H6A<?nu9S&86&uVN$:Tc@KPc14CQ*=bbYL:Vj>$h6YkP%R16Cp1CK<m?A/D?
qiRduw p#$C8j%eIXh@9khMQL<H#I9c!9%eyMaq8%?L8j?kH>:hc#&h6L$HmQ<e<$!IQ4%W8>P$9kj5Q9uX>b<L
Q!cb99 65V4j^LL>Z?+4\S%BQq/Z+HhqJXnmP6tjb#\&hXSc4u+j=*u?DXGha%4F?@*I&H5XTy#pT*pQdq+TuJy
*ITmyW @AHS1e>YmDYLKbbJ/#XeTtP=DZZMy1K!m66/<RF+XQX#:E*$w8lL5%bnQEZN+w^*qn>HXj$J/qlK1cL\
!YN8Y6 =TVt!Ak<alFe%W9S\/Ij@LNH*XT*YPdpu+K&#Q5n*>BuVYYdMKwF#MH$Vdc+*<<p>:8d+>lH!dLw9nB:
pc&!p< w?y=PSFdRtkhtF8TJ#=i1M$E#k5^>M8?hQ1e@/M*#Kl\h$@e9G%N*MILRH/!PNuLhydnu$j/yVFk<\i1
SmMC/t BbNRd@%u?&Z/9RY:RDw8bKwIEMYZdI1%LtR%w%1\JV/a8q?EJFw!nJ1F#GL@Vjm*Wy:9Ywli%=QF$8*J
R?8KVR p+/mq&<eQ6?p\XeQ/1nJ8Tl4?VL*GeQaH$MNSu/&48D?uk#9Q^MqlH/a!!NGAIiB4>l$FBR1&hhVYh^Y
lttCTp yBRKSZ*KnA8Ap/BBX:J\MVM:6ajDX\dVSZHK$WDu/ZN>6t1hWFW8K&a+eab>:+9it*hc#tPh4=FZNCDy
m$SpKR Sw&ES8^S5eKXi\@AyMIldpuyt/BinHR^XVGEQ<NLQ@4eY@8Tp+tI&m\4WYMM8p*Nwq\QA=8nyMl<5CEF
P9CZuR wM^yNyY^?+pl@qyJ:u9e<1!i!k+iX%t*:M8tYSbuFNX/LSP*98+ac:qAJFndXlZKLI5k%RcJR9NVCXTJ
Zd!PW> b@FyLXFBN>y8=/Q*5+tlc4LMBh>>$i<BBtlC^GGCRTJ869H+BZtni+l=1te^jYiqA\^Kp#WPI#qtiN16
c^Ietu debuWtV?\bQ^?GmCGPNJL$WHSBGndwSXjhZJ11pP+Y<CeH9R>GRb6d+m+/qFGmKT<nPLW>9\+wT>X=IL
X9$4my w$uhXktNiSc6X/qP9lD:R#Slu9M>lJ4%Alu*KjZlB>caPcNblWwnpSmdAY?nJl:GhP8YQVhZI!YX!W*F
uda9D< p=HmDC>5y9MAc9TQG!p!*#<>+?F84ycq?YV^FE<X8X?*&b@eZDale!>PbIFQ$XeGm6^nTwBm#j\VZq**
#yqRth \YHJaZ^1W!BBq@9H&4?q@wKQuhTV1hi$Eh#PMhF!Q4Q^1:/CjG!MQhq6$tISLJJi$&REN\SZB<Eb+=H?
!dF\tV 8iXM^DVR?Z!aihkM1/FMGh^mJuWGFL!JnLt=uM6l!=Z\ttKbjMBAt/umEeG<@d6q&eZG4ek#meTeYQ&I
h8tkI+ 94!WpEKLGERy:GiadV>Z#ZG>%<SLlqCG+ih4m8q+uGCApmH!GIc6%hA%npNwT?tW!Wc%ptmBTj:XLEt9
CQ$1NM WEJkWJj1YL=Tld^&SDYM>Z#+J@9Ncp$YcXJ=IPXBF@Tdq\m!u&R=p$Y@b@4:/Ptj4BF+cL1%5V@J=\p6
5Bit6y CPjLCHt^ecdLiV9@<??qJQ?n!4uk^cj4#j#^NV$NXXlh*a@5lX^=V%>!ZdyeGXESp<FnBd9LBBwCJLGd
dWtV9M w5@\9/:H<QE*?m4a1GkqIPPuiMZ8jN4yTem1DSpI8AiwthBZmta#QE&E\w8@TbJ@X=q+>lyS*Hi&HDpd
>B?X/n \:>MDnGjX:&ajjeCYtLND@I>1dIX/1VcPJ@b@ER^thS>mqq$daG%=kjK:PERM:M!8=cbl=5@FIFdttnV
VwSCL$ /?j4/QG=TcwnPCI4VMT*ch1Zb:8D:>^*j1C*1kdXqM*yj4KebH%PIn/jTME@$4%W:!WF89b*@%:Zw:Wd
@Jh=M6 l^<WDNhIHlJNqE/N@*\5>ZRpPT>CicFLaC+MbhJw>iCZWbwqNCyK>R8:PKP+!A>1?dBWEE65py>KZRmV
Y/Iejl XS6=Su=G/Sea?6%#WV=^jp<M?WL+Si>Jt/:<W9uJawJELZZ@jAac4A@pDPi%!@5lnlwcqRELmAQICyJB
ZPSE#* XlJQtl!++*hKuu<5?G:Y9lmB1=nuaC:deyW>+dTLy4uEP@ETpL/SWy?E%t1%@qt&Rl<l*aMyEA+ZI%AA
*RC4Gj eD9p$C1/&\bkwRCkp:6bup8WQHQ/#Hdt:C8BZ\E6a+Fq1cu+miQ<QK:Y$:iaCdtGMb<:6NEK$4H<%=uA
qNBaik yJJ4q6il^Fk@e4Gj<BMNM\58K1wVpW^Qi/ebccQ\RBXDhVLbTD\XbtZ:DR#QE4iRLEket+by%S5i!i#u
E/YeM5 cVJ:QSt1NR=tawJ8H=<PCQEtk!MYim%/<KNeF+jMqFa&N8WaJ%j#cm&qW4EQ=iNtT5Qh1Q&uaT\ad@nL
><*c\Z Vb@e*b:RNE<IinN#ASNYCl$X>CT=L8Z6%ukuyq:*D8cdFSa\%$/Aik1y*u?T=CLaA8k9/Vd@CuPhmGCa
*N+4NY IARGM=Dt6NFYt&=Jyd&Ku9EPuQ6lHX1XLB+lapCKI:cHSS:bk1Puw1$!hR<ABltyuH*kYP\%HC@8WNZ%
jLZw$I AKaZN%Fl<\+Dhm\Q:V>AYG!M<Z$XAkL41^#P9qBK\Mty4#tiL1uX$8yJNRZ$YNPibeK9iH#AXwbH1pw/
nimMbl ICN&!aH$cm:8EtCLtiNqS:1hX1jnyY>len*#488W%Fj=PHkm1qJCHaIwHewt=#NG*QmTWe:m68^hp>1+
#ba!$* &1T>^TdSuBnHD+WtuKHu<Ji8#mV:/HQF4>%eR>^14V8YDMPk^dHq+jXL%HCy^1<6Z6n:9WjD/=kdCA4d
N^wF\9 Y%YNZcF*6<!<@mk&:y$?jWDyyaT4/BMWBc#DZG==biQ4@&S1**^KCh>cq@hywRmXcGp@PewJP9p:@6ip
ek8MY> CY!nt$p5lpVGaZ!TI6?J^4X>GVWIEnNWPjN**1=bqm%ki*R#?1h@S@d!!k55<qJduW9>5d/5XSjti9CF
HhQ1MI RTX:9RHq?BVSan&Yu@RCjNL#?i6MQD\=69m6DeX:@wIt:Pw5Vlu8I>tE1Y>+$htK5BHM&d:WdQ4bZA5:
Ve$cWK m>$MTZ45t5ImqIuh&6kFa#*m?kLp*nXtd+%/G1^:XDu/aAWl#^twJRiC?Rp@Ll#>uLDHy44MacMC><$4
uI+mW1 C::EypMXt4u\IlC@/LR\=uAD\WNJdGV\$!b#GAu$6PK=GXuj6PNPbw5TRW9LC=+lHEVS*$npTh:WDdkD
SqEe@C =#KJBCXQ9KCepjqL=L/=Iu?$WuSu%&luHw8JZIBVnb/E<8@m9+$?C1?jPVnaMmQt+YE1FyYFVZ?q+9#e
H^ua6c X9Lu#EpYhDaHHR:DFCaR<S$NG+pcaRi5l^MY4X$Z>tcFjWkViTcI9k5VWiaC@KJFc?Y#Xp!V=/5R#GJ%
tjl&b/ ?dHdPQ4ZmtIK\Rb<j%uw9u46cGmeSLRX+DXWKd4jAtaepKYNh*5ume&#K1^ZYdkD8AI+hB<E+BJkKZWt
>4TTJd *RP$Y$9uQAZ5<X:\qH$j$B1EJXX$XZpNSp?*5X^Q?KLP!cM6cGdB?HZ1QW>Lp=Ht4TFntQ<9$LJ&PY^=
SS6dhw 9Z@pZJ1qpt#16@8yqQh8k*icl4?W#4<GWmhJC!h<tWjKwJFEu5!VR=ZZXcjQZBTEp=mjLXm<GL#?Hu>V
wwayd/ *Z$QkG?h=bw6d6*Mbd9p9G5RQi@!R85TjlK\%VyL4:Q:6ZIWMcN$^N6N1bj=m#w&W4%QLKimn56L!HLd
V69act =8%j#^Z:jSBhyKWCk^JAq#Vnuj:%KQ::X:a4<?A:NQhT&#IN>$Fy9YQLY<i@/X&MLVMKA1lD\:K:wWVE
R#8ENa djJh%X6D6$Xl>@t!:#$qZ>IK5X:=pP>pnEGh1VH@8hjy#mTyw?/pYc@#Kw4ppJ:d/D^@K6S1FQa*q@F#
4%eH</ cy$eQAmRIMD$/mpYK6&KYZc*Gu!nZ+luR+EMB$BQB@CtbL#P!&ip<&Hak<uBYI>na+dB^?pk!mj<yyup
6VI@D# XHy*=d9yRS$eIGCpTnH4KGudY19RNNqQQayEG$5#iT+n>tH8/C?Z+8C:/SZE$pY8uITk$LB+ejK*h^Q=
5FXjK* R+*%Hh**>&c*jQu&&**&bYWVNZ&<u#djBwjcuB:hQH>4#%d$6tPNHm5#em6yNcNi@%SSSTRTWVG#&X!Z
q8Nl&W Y/uwTp!^%a84:4S:<>PGQw6BnVmqA*ZBc=HauyN#tIQZ8ZP9+JPLh%?QL?%?pY8I/S4wy&4Hc+:S?KVJ
$bu+Y6 qW5n%I<ALSkc>nqMGJbZc=1/$h#tZdI>1tCZquBpX>R>IAhy^4cEt#iAD$*5/jw14W?K%VXdaub=Wk<d
8=W@9W #TCk*w9d%GtlDD81m6EH\FjRHdk+WcVJ$dh<<*Nb<i#u\nV5/^$M%=<@SQ&HH@n8b:d+V56896+DXJ?Z
HJY5@Y ZcI8@:E6>an6@^9cQ@ca>:Q@&!+#?w15j/Hqw@6:&6d$kiN?E&1Z#LYqHLqmIp4niY#FX8T/:q:1p#et
jK\FYm 1QHV+%EEWTRW5M6bciI?paEj1n1+QD+GS*&HdlZF9Rj+&@DJZyNqj6^#%:!iuY+yhd*X<$j@EJ=*@8dk
G@i+bh uDjpAVW$d1:j1KEB8Vu@XVY$9nb6dqJEiG?5lHydEqJSw%hW#PVDmBS+FNCu:CQ\=I^T:WL&hl9G=IV!
KS^QRT 5Dn>b\G9CEqGi+EKdS$jqCEh>J\e5MTaLPGw<DCJ:YHb4CXwhAm@hM%WeINF1RREllRl8EVYXBS>/b9t
GCc$QW njH\cp%&%TbYtFkHXCRFM>9P+EV&C=KEQpMPZHS:I!\Jy*^JH!^V@u#1L<ZI\RM?MAdN8RKWWSJbDk%t
m+etKl nE=@WYjLIpYnPmWmnbMq^@>KAYeQ%hlKWlD5J/VPVIwu5&pD@!\DMGZiV!^8E4WnIG1RuKSG4yRkk8&8
Y?G#Z= @A$S*5n5iPaDlFRP*n5bV!leMN#l15c64*P9DE1!w+*\lTW=dlXTl6SVZFTtyDp8kcLVPXAwqTM?!Ahc
C8kYlT <:lHWID@FNj91^WyLm^t$B$8Yme=j:Yjkae<R/pC+m+?jIc\KZ=JSQ=I6\?$%!F?cXHMM^ALp:Flp=AD
K/Lt&y 4l\KEIbWnKyp1Iwhn6c#$PaWnHnhXWmFNkB@DVj1LW1eli!YCeealMJd:Ae5L\D\T#wlX@yCE$?R\5Ea
IXSC6Y +^L=\pmj+$1M6<q#6m9a<V>D\=R*:tGFk5Y8Ee%!XTJkZa*SdqCwK6h/wWASm5<%&p<DcIC*<q4C/ddd
Z@=1XJ /ecER\YjEHY6y!@VKnl^j<GWtCyZpBCbVqikFPbE9ZyTItYmR/&t*CZPFad!#6yA#jq+C^?P&Wteb&:>
Gm\GEw !ZQNEQ1IdVM^k>C*IkLiPiGTE?hPck!M5nC=9Rkk8+C!IkuWL*jMKJ1>#$SQWQq+$YFaqHDcc/caY$YG
4qZ/QQ FL>/qkVdGiuQh@Jm/PlZPQ>R:V$:ZeNE#i48+=adXD=8tyIQtmhc@jaX+aYmlm!hEI1uEPQkWmHK?RlD
-A*5RG 000f0e4a49c00110333 Page 351 of binaries1.zip
uDBh@k KKMQw//nMAKZLI:^Nw\9NQ5EKK^?!JKCHcy!E6P*Rq<lV!hc/Lm\aZnM+u5DWw@d*beF6NQ46pH&iq#j
mJ$?JE MTWAy5/d:H!1F^IhVnZ\Aw=X1Y#>K/bE@5ldd>#kmiF&M+w:IG1^MlpmAaTn1MCXPGF:4jmC?8iT$$LI
Swde1/ PD>kY^ZiDR6nIq8SWMn*NG8jwClp1k?<!JSYZI%aqDj?Qnn4Gw:SL%1nK:JRTuliTP\:<C#%Na<$#ia:
Qt*#lK @wC=kpyjw6AmpjEdGS4M*uN^jwy^JtYl*W%FPNEYQ/Y6$eRBl?K!lww:>KiidJ>4u?b>9SmFA^R^P%>p
>emmip Kmq9>uGFju<S$llJcACL<y/9FK?u^^6=C++=%KI$q9kJ=w<Knb^&E@a81^wy\&dN4=/Ctd:>eLGiXt<b
jaRW6V k=DdPdYk&\YLlBq&FXnkwQX^Kd5=ktI^CEGAJ#M?FHCawd!R&BI+4+Fy8Rl#^:kaC$S<\^F@KRGNWpEc
Qb4I@E kG4SXMAAP!=MZy@c\l!E!4d/u6nqdn1?Yb>@FQ#JY%+SD$aBlNm&>C$b6\NNwEPXL*&yqR<:SYpM!lSy
ec8XLY 1AdVd!6Ve#ZS!tlMpyjbt*\A^SDNldHpPC>8!8lJCK<eY5&yn*G^c@@+C*Ay:Iwa>>+K^k>91<A^^9ky
nQ=6%M @InMF+Sit@q>DFM@GEK<w\^KA&Qyc/q>XN=Xt=QupHi#<#@b*Hk8eTJDT!tl@FR=yqkq*ZPJ:%k#XEnj
Yw5FCP QBcR@q\\MDhn<1a$cdZW*D?Cu%nh+X&W4/+M:qT^bnCAl?9pQiSFd9iV=RbV>Ha@jK4Ey+ciFlTJEith
L/+SB< BQI:mPTBETdq1d/n@4Xi/cibdCIHF9FIh$</pcZqRnJM<u*8I1eKe%Y:XT\TaeNjGlSayCl\ntbeC^>w
m8HF/R y>^KICNyK\R>l%5mDSeQZJYQ/*a\JyjlhMpXDIRPiFimRKk5IDI6t>i4H^#:w5AmB>/JaZ6qBju6pEeW
^L\HGX qN%pJ*#tHHMDELiA4QZ1P&P/F#IRlSM#?+%^P8QRW=5aYwwm^LDC!Y:VYIFl15tF^WCK49DT:*nacw&q
K8y@&D Sw\@aNGhcXQ#pjWW^k!um%RB8IT=mwm+%Hp1MjBGVHm&nPt+lZ:5EdniuARTKVh1WAL!iN#\HT9dRbRj
w:ZBNK /i*/PGIJPNZHVI\DV!!iT++CDcM@GlX@YFT5BR<\MX@ce/d!EeC!aP$EMIlY8cqII<@$S*\#n<AJBcT!
p*>HPH Y=QT<W#T>Ri=+E$9uQaJG@Qay+F4L?hy1b^u\&mkwHyFt#?lLH$^<<RZ!N^MynKth^C%Q8*11$Kk!wdP
pIAMRC b9Fw*PP%HINPk^y1aikm%N&h<#l+jtdqpq&Nu:uZYeTMZ&hq^1*%?SZnPKIB15Ri56+q@PT<ky&lGwQD
QXLm6A Y8B4JJV>/@1cAl*D6&wll:B$dQ$uRY8wmkjYP4$%Tu9dHDuaE<e@wIWh1RkMjlTA&q&R/d=DLqe8w6>F
!LYD%y B=*WeMwk#VBPR#P45KjHqJbSTny%^u%!qn6V%J55bN:?=9c8XN!qd@\4ZZ#?F@8KPQ:&dibD4=Wu4J1V
+^>9\i KkJtDIaB?#R\Qmk1^LN>PNmkGV?Y\4YNlk5K=I**Ma%^pY&!&^F=JhL>4Qtc>5c>u+I*k>FFC*/\46i@
#Ly=pt DCeT=I!*G/SlF%dW*$ilE:KKKwtj9@HK=M%qd##Bq8uXKMimZJyHnIYViBpREd*X$m9KD/F!?PyWCE&Z
*mYK*E L!qwwG!ha\?=etDVV?hPACEVP%F:SE15RPBXcVP@l@SaNNy@^M8>jV:\5pB$5<M+j!1XHFecX=/%m#N9
m6>Xm9 =@wkRTSY6PuRRIBjRLA>RWAq<K9$!$KZNCB4AR94J%ZD!qXwF=6um%cSXDL?SBG+bwd//6ai6y@jW%\l
taAVA! t6T4a^n4WF65B9i@lW??\&Ji&\m8J&cX>\N\PP\mmF<8Q9Y<yjPwcBL=SFb/<Ra\#QYmX*BA/Skw#F%M
\EGK%! >C#B^\l9y4e%Rl$!Q*9ZHkJb6&bShhI61yS#&#8*9PlL@\LAe<$Ct+Y1yVdwJqi<Sb=BD?9D9mL*&9/a
$DtIR9 1$RkTM@Kq+pbyV&id&P+&5e%G61:aAX1Elhu=wEp6W#ded*u&jRkth>>@6d+:u6$yC@*h!uF%CJGpdyF
kM8PeG XnG@mGF\D6B9QKypLn?yIkm41iL%$^PC6:8/?4iV$ZPjRiRqY5TNEiEIXjjwlJp8Cj+J>l+Z#AWGjwjG
\t:@id nh/+Z!J^pESGMCKdp^&T#>KTGbX9>=IhP4@dBcGVmIlVblRNbA=@6W6^ml%dMF^^::LTpCJX!Ba>&eBZ
P@DZA* /*MT&/RC=M9KIiwGlh@BAwwZB:G@TkQ!?<&l?l#8N5VZJGeBpn5cw*im^61B94RbnB=C8elBEtqBH9#1
QuJNA< tGR\:GdXMFBRb4u1c+8G@TwAu<Nd&N\C:%\t<=qnK$1baEWZBNu8EIicIR>lYq!XW9m5Ih+iJ5bbKhYI
i5NtT1 RpBh?q/nECBjGL>98*Fnu%%#A>eRXbuXwqm$qN?E^dTYeeS\<\+PH44iN^X=aMSp#&ZqEN8C4hlwRLc#
5V*nZV YL:#CLjL=q*4+e\6W@HS:yk8C*>Vj5hljp?G#Yq#y6tSV\YY=W#$+Je9^aYyK<c/9Ru=ap>#X9cWN+\n
dkT1^@ %#be1JXQNw9%D@Xdk=w\dNMm$@jW&A^hGIF=R<lSjR6T4G8$R+VHE9^*NKehkjyCAYGZDJwbGEPJ$qaC
pCRiP@ NyZ&w4TS%Lkb@W=G#FJ\8!%wje\yDBaZRdWYE9cp\6et&XjE&eLX%M<TpAMT:HSbh>?TBEp:&I<qYk1L
%p4q6! \<V\a9pmtp?>Eh?@\%BuInjd!>=BNatFLXjW^DTB/T<Z*1#XL9P:j+Y=\K++/t?wwWl/<Wyj8X<bFpYj
Z#C&un Nb6aLpADSpV+I?!^b5CHmS\C1G+MTqb?FWRu@\n>C@$9/J99KimJNa\D@KJ$6RMaL!\yQReEG&%h$B$w
#WJ+?= $VdD1e9T1IVFjSW6Cq+FKHWm+XV+HZ1%<Xk1!4M&>1H%wPWpmeF18>l9M:V6jDNeba+KWp*jee5YbP<#
F/G=1: jwi&!wKSByi6ld!48tlC4b1?u<nGiqhb#+wwipW=J^:c\NcNn!=D#qHk+^K%!#J^ZGXC\B4M4?C\TSBc
<WdI:< 8%&=Q&$MWh/BmQn/qb*wm+#m#&+T5CJBAdF*$WFE\QIhh95/l4H>6=P5p=cT*&Y#P@n%+j6F#aJhT8^l
<DmaSB 8cpnI6AJ8&VyPZ!$6:4EA>k4h<u*%DBGBDpthETBI\MSG/!EG^E>\1!85Vd^*LJJ?nIVijA=*IhwDFZm
dVRSXH 1>EnJ8X^HX*mP?!5^XamL:bN9<Kyt!Cd1ZkM5PWRd*aF^LET9YCw+Fc1aWZ4Mil*=Jb%j+uyRaGiRZkK
T*t:5& 4$eZ<<bj9*:!MN@!uWl@qGkScbEJ6Dm6BJFbuyB%FC^kBbWYlPCNcCJQL1T@J!h<IwIYJ*E+<LaH?Tbj
A/:DY< kViHSKnaR:Vcpqy\Y!VklVAH61RSGEJya:wha6Ml#P?*#!!+<<^wBlcl\/bM?4tSNkYMQyS!=kBq4bTl
n*q<8a V/>VMh%bHDP@qc&l6LSZQc4^CN^KFFyyI!\kAG&><TE6MG:8@/%caF#paQdH!IJB!Q@R!@qQ!+J^<@^i
69a8T< F5#^=!eye&QH9^WYAwJ=@6nk@PN\RE+\#^<dZH><A&Hu?GMD?Me8IQDj^L:RkBA8<B@:@qAc$@tV4Jn#
<kQ=a= #=9A\j=ZIVJPV1:j/AH^@JMCby\epH<RMPQp+Q^QCbl^e9#q\nu?9AH<>=Jtj^a^?u6=JJ:j1E#^QF4T
G?QydD nAj+GDVZA<JkQKDHwDp=H$CDH+MGQaVtjATcp?eBWVIi!GQRZA?l8S/B@9ZN:>Hen$E@iG/i^/A=j+@t
wN>6bn bGh@DJ1D<\E$^:?Ejk#ZRJ\<D/Aj\#WRpP5B>GP+BkTBH$A@lt6AD9aH$I@l&wMThy#5n!EdlB*+AQw^
m^Y!V% bANBIA?kiS=%$^<+N\j:d&ZpkH>@AA+I?*>YS8:u/An/iZnR#:Hq%?u@%#J!@#c\@99P5MqAYHqaPhmB
^e>GWG QBBYDnMVA&NYJjNZN8a&4%mh#E^a:b\N4e!NYC%N*n!&X?Cj6\5E+TV@NXTDjn/9H6M4+H>=4*+PGCBP
VISj*6 EDtRG@!u#n&tW/C@X>#niaVmHnju*!n8kTH@?IVq=AD@E+y:QH>S*Q9=%Q!#+l/a<=<W*PQ?Tb4@V4$>
qWCm?J F5Du@>F/i?l@%h6L</cDw>nX%dILPZNStEdcAVuE*%:hA=DId5cVa%1QSm@F:\FdIa5=>+AQ:l%m>\C\
T14kcu /Tddn&>*&H^ZYX\M:55jn!N@%Y^8pL1:8Rj+lN?bDR@wZY#jWL6@E:XS9Ai$<1%T@T1u@E<h>H+5:jV@
dp/JQl q5+Rjm!mK=AX@Kn!9cDd9ju5/?D?=ju84^mQ6LILlZ6A%V$kP9!9$ju#XjeVcX6@Dhiu8D8+B&T^ZeX@
*tYHi8 9J@<>+Cc$C@N8DZQ^uDC#?n8Ai@=dyAG@4\^9CN*h?%?mSN1:QVDR9WVI$Q54?QhV@$/MJRF\cu=iQYy
Mqy=@8 ^mlLa$bpZpBuF?N5*CknbPyPt?Vj#64F6>S/buIQAH/:u@/dW@11+Y9G#AJjeIpmZn$FSLt5I<ECy8c#
CwH@w+ DIS8iueFhbmWCNkH<d=Ye#\np&:!N<Fw4Nn5C1N#EJHl5Ad&ZE?aeIG1h*hPZ4$!qJ4CWna%kWX4Ie6D
nB1d@* Nca^EX%V6>e*d>pwP^9<:6:u*5SXhCh$P@>J:=V55F9ae%XBENGWGp5tRG@ZJ%=X5&ckQt!q\=R*B+YV
NdS6== ptyF?ja#p+$QnyC5%FEkc&JlRYnwWPn8p8QcBHi^d4Z%D:dY\:Edqy5=>&Rt998bF@=CcZkBC@dXeiL?
QJwdSF M^8/8cJma86hRjK6=Amh<l#1b!W1+=y4b<Zy<Jp9aqAX\Sdn<SEdIi:#Sp4m$?>hNewYSYC<Bcm+PC<J
5$ZdHG @jQ^MqVJ=Mc>1+8$m5T*\9cEGIA\JQG9C1@6C@mctWY$PZKSb%dm%kWc%BG+415HeDE%5#pB8up+b<+a
y=@qSj %@XeN\G%>+BCup>QlP=K$i+BqC!6i&G&a9L*kCJ9>:=k&?85aMuVdNL/^E$XkA>m!Haiw\1tc%1CEq=a
l:AaKt nq*Em&@>68$W&%mPk%QlB>nn+pL\>\BdVG5TNR6SVkSqZYbT<i<5Gt?<NY@+5IujKu+/:8taPX#a&lmq
QlG6FX mKJVQ86*5R$A?:aRGQWcjwJ$wk4hj4+HmPy>a?P:u$&N\@yeHF=JH%Hqpl:b**cW4>E#WEcQPyRQl*Tb
9FHH!V HE+<b1&u<Q1CKF1l$ktI=KG!*qjP%J95bnpakX8Ejnp/5iD?+$ay\GHKlpL!t?K\JI6cn65YeY%cd$CT
h$Il8\ Z$kZul&@+5BmaT6TIcT*diYRbiZD@1LYL?&9aHiGH%Z&64?p9%l?CaX%6@:TCc9:ySPG@$5udG%=+MQ?
t+CPNB @hnH@%YVS^%N*+%M:T/phW9Z@Z+<aa>WJ4aZY1^6eWkAbjKDMny@KXVhLV:bLZY$5@CYMT^bDWFi6ZG9
6qtqL^ =9Z:q$Yi^4e\*<*4*bbXen+Y!Cu=a^VZ=h$i:Z@dHL%Jici*ik>RQIyuP#L?*9D6:K/@^QZt^ahbhN$d
q@#eV: i=!:J%pP**q4JG:=qD/Y>Ma5*kPcn&+*ia=t1j$uT&<5#$^9q/@+@G!Zj9/4Ll?#@iy?I9ZD$e*HV1:D
am*u?I i$D@Dilj*tc:eD:Rjd1<NHqHJj%:Q?&@4Y@@#p<Lbkh^@:?1Xj<>Xc6p@k>X4aJunlHC<l*:RV9kC=Y9
*=cHnu QWZN9PI*lWDBQ#hjFey6PIJ1LS#B/R5P+H?Glyae>XpCCyAuBR4F%CV5S:5$*QCB\XTeCM5R6>qCn>\^
<PcMhH J1y^%qISGbaImmH&^*FY4c<P^M!u=JC&S8Cueu1lAK4Be%YRu%qu<5Q*p=FQb/<VCKXek19pZ:WTP!<K
-Aa8Be 0004a492c1b00110333 Page 352 of binaries1.zip
@<6A!c G8yiFitulp#:JK4MluLd+cKCW+?iLyakKmtG1G%E9NC5<inkSwil:#mSBI<y/L@MF\pnWa<DqndA#/kp
JFpmCP w5quiE*%Gm4DLypD&&9\<dM=/+M6ctS?TG:q5!wFuZC1LnZmauD5GL&h1X*uTaLA?LbNki8wJLpq##?>
6=QVYH el4n/kqbGPR$>4ZlqLX=ujP<=FbNV8tbNb*K#MFL&>IcIX&4ccS9IBMdHt/jtcK%PEaQI9uc4#Tla%DN
BZ/Y#e AlFnGdujw?Ck$ccth#QkYKmXIC5KP8DG/YJMuZnCLc=JLq8Mh*1HS6b9?=Q1?b?jHq41!W<:i*!V6LiB
tC<TD1 j=9dl:wmwPuH!8R$+9lcbmELa1$Ewpd:XIaGe4H&%b=YE^D??Lq/%by1%bi$mEhmV$hLbiVLdXu?uBMP
RJ/i&h y<Bm:hM9!e9tSB5&8K4K+SuWDnh!P8A%>ktQwk4QEdFtw/adIZ/Pm8e551>G%HCj!yJ\tcI5!Vjqpp/H
+/eAT? FjEwiKR@c<NSJ9a8*NA>Jy>n^bE$u^A5%Mt>tabZV9n$&RGiSSSe^>m%q:IKhPDhNCc8ND16nL:!ajKw
>Z*5FR #+9F9#Se48a!/p5Wy6LZLBu=HISKi+hWw5Kay:JZy!K=JPhQ/%a!T>GQHt!%RNYykApF5ER6l:JIp6>9
BZjCh\ MSV1X@$/4JWa1?1I>m^TL&mySASlLtuT\yb!LBYBDuejdcCBC#=>1B/GZq<SJ?tJjGHFy$#1F<9La@TI
D?djD^ aucdaBZtMwLpcZPd+cRGyTD4WHwHJ>FCMT@9qyKq=^WT%LG/A$Im>Pu&R<1MP8>ERKKHtaQ4$cm4J$X+
DHWL:l Xk:SPH1cA:6^JTy9GJbm!6=YumIQmdqNhL1X8wT!5D%:%SM8!%mni=4N$eWq9+FGKw@8+KLQLcbNcCI%
Nib91h yla%>F!Ky!5m5h+&?5nFRBk*El#9%BE:CA5H^/?CNtV<R6Nm!\DmtDc<SJ*>I1mhkLlk^Tc:TWweee>b
h5$<m# !ytQeW6nPn$>R%cT+SY>KjK#/C4/qdcG=#RyHe*wMhbVM9P*\p<p8q%*>kL>*\^bVY>5\?Ic^4T%KaF*
YNK:%K WyJ%tM/>S^tj:6EpYHPmVt5*IA9k#5JEbQtn8<tbPXX?dHwmiE1#MWD*BDjTwVtA<iRDW?M#FCYeIu5p
Ey\Hk$ 6H5/6>hp8W<$IHk8pcS%+tqlmleBuBpPK66<Y5Q$61XXwSbh9Xj<Sj9X86HhNp\D4>lTbZ^#B$wWy&kc
/<B@WQ mBV58=*PWVEbm\B#/Mb*lZu+Sb<YVnRMDbbXLMa65n%&%a6iSFWB/t5yN/u+bYYT!&MZi1qR?F8Iy?$w
%Nl%VW yV9K6BDa/>Bbt56uB5bJJBN?YDmT\tMiSImdIKQP*RS/T9jA=/RQQEqk1DHDX\bYIXQHd$N48kjCj6ck
CE8Bpj l+/CAjH4?eZ%T9y&6C!R$*?1yq/4!nqen\qcpFJ:W!\=?Rw<nbRVMuCT>?X%H=ERE/6Z*T%%X^Gq^enZ
BllWki XDGBIFbhqJNubMJ%:XLD8dZpCm=QYNG!KkM%E@9cedDj!1S#FMH4kZ&XZu$ckMeVJMpuPnMyVc4#LQTq
1C/i8G FnXTCcA^1A%b<cVXm!$!IEGSR6&/j%wFX^Wy5:acGLM^*+WaCkPMHQW@ItG1Km+8HFyZXV&MJQiQ!%Kk
6<pp+Z dJLW^VJqcVwQVlKACa^@w/KdVXyyQ5^K1w5RbL?hbiBCa<14KMQ&R8W<G=H%E*>@1C#WK?p*l9dnk/lZ
1:=<pp WZFGMLkl%I\?<IBlYG+E&TcN<bT8@B$\$Ze1F@\SXQ1?<*4PX>yEuEcl8mA=NZC8djG\X/JHNIw&R#V@
bNpnP+ jQXX!lS+un!%m4@iXE6N$j#hWTu6W>Nm5K&QR6<X?eSPVl?yK=6\CHF?y4^^S1AWR@qa=$ehMPwW:nPk
e&KuI4 InYn!dwB\?uhT=YBL\\%JqVQC&yMZVupVNeG&md^tFiCSWMY4cuu5KKh1MQMB==%PB&KVa=VlWiM6jZB
K%6^R@ QmE9%TI4jQGK^M84NA6qlh/c5Zm6QAW*:>mWCXKbVT?$ialLPh:RA5#^>winm:L1NG+h%m$5iu9AwB\W
@5!Jc< QHbDtM9T5+hG$nm5!jST5Dj5&SIQXDeTlEJN@hWuQW1D?Sn=!+*9YeF/%%*XtmQDmypdETeH\h=:>iEj
FL1e=Y Eb!c4&jY$cT&=4W?IV=u/TVJ*Q@W+=+hBAMelwEwYRS5TtIk4YTjNL$T9&8cSBK%TJF5nuWlqp@=mF?m
jLFuw^ jGE//Me^JDW9Qy*:%Q:Wbd%Z$qqM1LHX6@8wyy=DdStNAPidS9uYN8Gu==SCYTWX%y##qej<X%@D!F^c
DY@:yI wWStdXBSPnIeX/WhZuwdew%:=w^^qK\J^uSuI$N9D5KVb#QCb*%=J=eC+i$V^+RBue9Jubd^>THY+eB5
eKWVjC 4Adt4Z>?#S?Ce#<t6<V&qh+EN/6qk^TbQ+!YuB>JeAbNype4n=jeMAEyuS>F9=HBw+?Y<w=BWLkSBmBE
%M!T## Ye%Ad5F1^*!^lwq5&MZ59eaCj*bq6m>4J<9lJ^$?PwAAZRy9E4BYh5Mc^1+6kR^5T$Fc!Ve^>pIR41:j
kZtweA YXqF!/j8cKd1<BB1$+jj+9*kwT>:ABRP6%EAXN1H8=mtL:kkiZF8C*9q5ec59&6m@QB&#\cC#JlwelnD
nR=!n^ 8tK/QZBJ%hL64W6n%%P?1?=cZn+iV4:m#//TX@>^%P&TbT@Y=uAt*MqNal%F:wN$4$XKie<q4E5kR6CF
n&Ltby 9IiljACdq:D/>61=6QG8TXKlCiadcm?L4knnZjXa<mnWj5XGE<yi5/Hkj8QmWFXFtLT^hiC<>NMZe4LL
dE^aRW J/ybBj!\eB&hVB=k<pZ9WZuywV/ZRMW6/5wlyDFPpd=Yy4M$H>IdaVP+nuTS6S$NK\6*Gp\WH%%+1\u8
G@%W>& @X4\:ki$6kqL!YdWR@tNWK6N@SZ$>C:LI&+$&5cJ9AXiVFliw#%j&\F1*\k?4*hW%8Y*ZuwARXQc51%\
9:D@k* ??8:w+@pdPj$I<!5EXAAiWS!iXTGVkD/MT+5JlHWGAY$wJMS^:pkJn8VjRGM*!%b?n#M5TAF%V45IdG5
=pVZ\H 9LJjBCN<@uZ+5itNjMS=KJm/>Ft#ib#:Td%YLmp5*GZLm1Jy4w>B&$m4cL+C:SPT<jRI!8#\MmQm++Ri
4F*HPZ &<IIt&hm%w5BHKIJMmmp@X:FR!ut91+8CEqN#F$TNKw6!MQMEt9FjaLCe6NIXBB/cGt6wuRYQ!+//^pF
^<>R/h cPpN8EPF4+VDMlV5?%WMjndI1Fj5Y#lMR^$nwemwPZ*XIHJu^1FQPRdMJYReR5yIbuZALAPR=ACu?Sei
q<P&kK <%8t+6ISypyFM%b#$$a%9/FKy4nWpN1qTeYSMPu&p+tlX!CmI*X%$$*5mTITXPN%IjJGG5#u6HQt@kE6
CYIT/u wKh9k!<:J?t*#H$/FPiK8?h+YG$11LVw%@Z%thd$A<W6YKE@4i6*n5n8lJb!RGe44tljW$=hV=Rc&*DS
FX<41e ?RMR&!bRX@biTGJ#W8uDD$*AFjdBS<?64YZV!TW6KwXe>^=?qEu:pW9>!nBtCZy4y=PT#+p+\l=<Zyym
Wl*jnj B?&$S!/QZFTy#YDuQKy+/K$9A*e6DlQ%DZ96KE5jKYSTSK1<PhDt5I>JVIVb#bH/RE:!iNNah^*I1c^h
NPjjYb R6%!JpiK68ppCXdilG$=PqJPSl+#l:PXHHB^ncpRQ*PL4W=LpHDKwBLAp9&KaWGel\ku@qX?Q^n+@P8K
B5bN#E %MwtN6Wt6!n#PeItt#iFWA+WV8AFQy^km6XeS=aKA/$lG4Bb:TmMlTYjVwSNeI$ZZ8n$&54C&B\d5d6R
biRubm >:lJee<1GwR4AdD!Q^EYW%c*YK>N:/ehCPe?\VXu!dJI1i/AwQIw\R/FaE&JXdY1BF14^F4B\TPtBc^h
?!aY<= tR^R4?Y4>?^R?^nJaXk!wTRn+X+C8$wI6tV=1FVaA^*5LPb1LT:#5JQiY4R>L+L8C=q+\#KtB>?14j?q
&cGl#h enmLIei+&lK:1P*+a@>qlWRF\jcWqbXQeW>EFaw9bNC6mjM\MQm=*u/>Xt!%/e1&954=Gay^HchNVNV&
>RT%RE $#de&\:nP<ycBWGdTc<XYbF8cQ<9XN@D?PY8u1:9CqBSpYZuW/FVGhqEpL8<aHYAlSL5NRRmGZwaGHb\
tnMpTI GcGV!6W?=/X5yTn:aTnIaYL<lCXVq6Y\qp:\eNKLn\u\:?8SRcj>?*ypAa$uG:?yS*c?ckQb6HHbkVhw
=w8#QD 55:+Xa@M%8ZK69dYN9*Ib8ca+DYTZS&c*RW1DliM#ewRWV\/HIAiANZ6aND6wMbpX+huy$bm%?cF!EZl
Qbp>@H $Adq\A>q#$Xk>^wbpWLP5j&%E$Wl4y1aW#!u@T\*IlemDDuIiXdIlaDISR$V\RNIZPiB1/dnTCDq?BwX
*ILZPN &6MFIj:>/\69=>ZZnq!9:Xea*1nb8lJw8d:?/F4*^m=h+a*ci%iBR1nbXDeCGej+blm8%4eEXT=eDY?k
byKP>& ZBC=S6@wk%#n=>>j9H^D5Q1B/@&H?K#*F+y\BAh9b#?>XyN^4DQ@ME6lV+D$Ln:W+\LJ5S:KW&*Y9Y:b
%kX6/k <=LCT=*8Zh&Ba#&H=?5c:=@9<ZW?BKlE<VY&*A1?*C1?Bm1P@MP?q\b?*Cb??pQI6Wh?q@d?*M:?B9j?
$$H&EQ >i@>L#$D8D%iutiaa19ikBayaM%NwLhE6ubw%\tynpaX9H!aIebRat8!SpyBeeXGZh<C!%KD>>j?XKV5
BV#kAm 5!KAH>FnteaR?9eGAel@iYACt#KRuIQ>n+CA*$Wy<JD@+YQ+#$ay@F8+\V@n?\j@a@E!V9Bnmyj>t$@@
ybMceb D#jJQ#lk@6Fy>?iImL?6@jTAy=TD=#Fw!ANwIQ6n$MAHQKXAn5ik&S@\EAPBn$B#en@k4ATCHwPGQPAl
L8&PKK BwIjk\b#Q+DtjA\c?BAc<lk$?$P@GNen$PCH&AJ<DNjAD:LqMX\Dk^>Ak^:DNVDHA:<a/DFeA@E<lH+M
%=%YH> %$CRB?IwRKB@Cj$a4kEj88ik^*AN?FAECPk^ZAPCHpI@lt6AnwjRn?EcB<>D/Mh\niPB8BqP<GP+>uAW
Sae*:T B9k^bH8wtB<u?DFpA#<$QIBBn:4yD^AhDQ/Z$J#@El4!h=EEj<d?S=EEj!uZ>/hIkn>C?9:88F!@e#@<
<KDQ+\ HPL?S/TJej!QV^Md?dp$:m1EB^a=lEGG%T$b@VC<:QLdGQ8MR+MmaPGktT*y=TuStCSZiEKwMBWdR/Mn
RXEG/l FLn>PJ!aX*!^q1C\S:>/+\tEXDMVQbjHGj4^eqSb&cY^&%J^lVMpc!l#MNiR*TK=PST&?Ia1q6CRyNG/
KC+MV1 *wywwQBhZ!E><+<je5N5c&&>\?W9hK8:1N+mEKCXK?6R5ES?I8Q&M^D^1lGjaBc8/awp@KdHwtC*l/ul
uGKnk> +pPFGW+BPG#91X%WMBJyl?9DXb9^beLyejENNGG*%F>>ySunhmT&1HBV>VI$:kCh$B@ZN/yqGXNbTBSi
tqVI$6 AjYdeWkF!^65Jbk?:jb=lp:+inRweiQ/%ZadDH!>+GS!<FKSTSQYSy&I8%qu5iK15dB1MbF@mJAy<eCp
k5@81F l/JZDa<$nStq#F#RD$t$b/VmuY#nlW99R:La>!A/qmc6eP6M=%#CQ9kyZJbhd5pWmKW\V4cTXt?WQdH%
6\S4Mw XM&$nJj1WL<n:@Gp\uPnN?SQ$4Gwq%I&4GX^=nh?&jeR!LN1FKKw:p#I@=1FttGMF?wDk^?^&VPtdFu@
\n!d?# XY&bduAdP!Ejn?ta*Kb$b5DBmyF@EIVuacK?tFDLJnY*c+9/$y$J6Bu=+w1+=**QPl&dkekV+8MbXuA>
Q?8:/b iuAehNQq!$WFPEE4M9JPla5$tCH:Y+9X6j/u!EYdeE@l8ddhy9^Gn%&Y>qd4L=%<#?8M*NWeVXiwc5F>
Tp?$E< ::B8w#H<Zun5jQP&ZLFpM>Hn1M69EE4ieRNpCLYWL^D1Pl+a/9eHNW\@e\%5j?biGIXY/K\w&y:QVaZR
-Aj5Q! 000aa8e2fc000110333 Page 353 of binaries1.zip
Y5AWqj hq%+4P&ADDZA+/8<VX688nNhcMJ9l5eFJ+=jR/bXJEbQZ=8unn<eTW?Pb5bAukB?CiilAFdcDpuF<1qX
QWp8#k wdR*XN:I@y/1Iw?TYZD?TnJTk^#akC1*4?hMu4+dF<WjIQmYCS&b8m=VbKFN5<DHKMT5Fk+GFpWhWh=M
c@p55H ale9$//DFMd4nVBDX\$qdpy6%656=j&CGd4Lnc:bBTbJEjGXJ?\Pn5l9?j%E#CJ/wN5Ty@6N+WYGCVnA
qcMj6P H8/i@BImAZ=m*QR:t%Ku@YF5K?&blD?i1AZRl^*K$$5q?C&MI\6Gt4%9ny9?SAGXlMF8KmBWNHPJnH@%
jJTXND Rb?<HJM@$iI+Wd5nwu8aTKl:cFyPI<V6>CcKw6?9G+8/K/WwG^j5FXc6<GIeZlwPl&+*dqMd$$p#R6EX
%knLDD 9^5hhb/Emc*1%M*Lq%A$6^Pa#J<S&M>hP+y$cwkebXbeFGCaNQ$mA\+&DkVna^GCM!SmbL*1$VR>ENBB
YK=bP^ #mBc$NYaJ&1SP4jJ@PaWu+5nD4yVjwKVXhwcI+<#bXEXDVHQ>1XHA+<WNuwC^Ij^R\D6t?emtCS=Mky?
/M%ItH wWKG$/SRpy*lAcHThDtN+:yS%QI4@RS$*T5=ST<F=eRLEPPXtaPLmDiL+R48XZF>6QH::ZR6wN\1Kw>i
J<F:mT am/=/$XnLTMwp@56%+BLmp/:<:555mLY9+y:%BDQVpX<H!eJj59=^W@a8!PjjH!dZ6/FKhq^T<KA$wl*
>QMZYu t@yY5FeK*!IJl8EpnIT6Ju>#*jCHdMHtTn#NAKEl*uPS9k@?\pZ<I4Gp<5w>ee^a=YbwE<WcKmh&&!wT
knh@4C L%T#5G%CKqa89RItl4I$<h<:$HJuE>pkW%Ydj5I/EBm+9ChZkA%Kh1CAa!hCwy!Xkw45ulHuGTAhca@W
%Abb<< j<:=em!ZRH\p>qPX#ERw9/TbeLBZpy8+FE$!X?DAb!QHPDk$%T>jZClu6G+Pt4?JYDPR5niW#%DAI6PW
@elDhS !^68HZ5#S#lkWREpn5*iY*l1F54/Mw>u$e<j&$8y&cc?BBq@>$$Vt1e$9^$ku:+\19B=b+NTE%1SXJ*i
cp^t!u wbPmyPL*dVcbMkmtBP$XJ&%PCm1$WpWDh!>=l?^uZMV*%6p:S8Dh?6ZnLmK:mkkhiq?4ReGyIbPcRQhC
a9H5AE \a<eB$kC$j%&B1ZV:k*9Vwi?$wAtYEZ<GmD\:eFlweKiQm&DXwjLCY+ZByEpHDVQ?ZDRknRq#<NXcD1F
M?S=#t Wh6:wKk1ZZAE9d<lD%%dGuA@+a^6BGQBML+bt$RmWcK?C%DG4c%H%edqIHmTpX95M\@I9YW@:ulCLEkl
w/6MQ! h1D*c6CpwLdCqj\#VVZRu%!A5b1Vwd:Rdd&RQp$?M^CtP691i=VG6pZt9HJ\QldahP%C%A5XSTe@k5j9
q?#5u^ ElybIA$pXDV!Tl+9Qb4EGEdA5d!VRj#yQa*DE/$6u5Tlanc89MuqXXR4mN@^9uc>%DiBTCR+KbGGRRHS
mPKuh! WReCAE>id/dZlmPJRNZIP>pF@jAbC\4:WXi8R$9Qd6W*Ia8p>9WDJRmT!8?mZnH9:!d55mXX4M4^I*\H
G<iJFG m::p9l$$5+$+SVMAkdXQhdV\LN=Htn=*JP>S#l$WZt%nL*9V8LD5\L4@:4KGLt^\!cuuchLbkehI6qCB
AdGTWp SII!*ZWYLI!<FZ@\MT8<L?uJ8DT/9I+AIl!WZRpM=1?e%ETR1hN6Et!nY/=EQqiZNY?*%\iZaZ6ECL\h
P/KVcF JkuI58mp6jT:tILFn#J>i*VIFd&APFW!Jn>&aL&FL<&6LTdRC$eAwIYTA\5pidK>l>l?1AXLVn!Gy19R
PAh+VE @uwB#aieIZY!JW?HLPRLF\NLkyBVR4*EC=YpCWudw5KT6Y5Ae#5*uT>@pJG\NwIw8LZHwZ/WpD14Ey#q
kny%uG \bh8E:\@5=\u/Y$LXPM9bdewN@Ba>DA*nQRQ5KHCVcDqN?$b/LCGlAh??BklnpFHPtc/bt/lCphN&^@t
G&9u8Z %FKk#=/HcX<e$$YH8TlGcMi1nERiaQeKW+jcRw8iWck+yR4&&j^RnLCy8JC6lhqI61Vy#KuRGnY6/%:Q
WL>RqB l%:9u1@G<H/IQYJ:\5Xd$B:b&lZ5Qe+&ywI>MGnCEtl?R/:D6LwH8EbmHRKCK=yi<&k\lGXn^#bC=Dpd
&ZReLd ZqFIX5kY^tKtHR5?lJ<^h%ky1V?N4in6t\y9+!?Y*!%?Ze8lnYuiE=?Am+456+4hQ&\?:5bIq+hL:$Rd
9E:$#I Y<!*y>bpJHZeS+FGky#5kc&Kqd6LNYA5ZQICQ<LbtC1!auwGqlyX+CB8$/P^l<ABXlF>Ik/K&XF#:8J/
iXhdBG ht#/JhA*CAna=a*lGn8/w=Fa1B&\^PC*?PE1IqKS##W+E8!^$w!^Mn6yS+q<b$S#1/%Y9mKM4<*ukBC/
Hy1ILF GDq!wH5W6F>^/LhDh<\GMYd^S$L*DAqaTcAZ$eMl:Pi8ValtH4KYyPpIW:46ZXBK/1P^\LKmy9SVVw*&
9L+c*8 <mAbd8WyWkwNKXA#R@!nYD>mlXkLY&Bk+bac+?8W5NGI48q\<A1dZMQC:RFlE#aX4YqMY#/JlNlJNqGp
$W\tM* u?1J/1J%5R5dy:BYc1INJdBEPeXlqTyEGbB69*DCl8$6bJZ8M%MVXA@N<^Dye1iiiEqI=/cSk@yJ%5>P
GM\RV# #PI6Dd4dTwjCEL&Aw1/G4D\R5CZ4+/J\KC<!@qRwe^PLBaH=JQty:ID81$n&E=<M8CG$I$5&aT6KJhL6
knVkCD HtnbHn^k%/WG:VE:wn?:?EK1EBTH!D8STSBwuVC9i\DXaS58<MpVJD%pY?HL#tikhWHIil^%jmFZX9:*
idHANP M6K*/@XRe1aRIdP#VtHyNWu/Kk?8w:je6l?+!@a8daQP\!QI=YL+KL9Rn%JkMhK9=jK9?*llaiLAHaLT
l#u/De +W$91pc+>Qq9>HF9$uGjh&CDdGi?\Eu#B5lTW+@RlS+Gm?nZ>EMaSqtn><B#51=1@iwmQ64#DEN&J%+P
PMn8/M DJXyZ$hRA*$pewWqEM+N>m=w!?DVX9yPEKMR?>mX/TFTGQnZP@R1YVjL$C>t?yVQ<uZ\bh#cSb^1m=mw
<#Lk/E X@mhHcSF^wV4bTD%:ACl@9!6KtnS:D66tkXln1@AZlK/IdDa4yYdZ!^&@<Dm\VTkbP=YKywQa/ElwJCn
H=$ZeX #eyuS?ybn8Hh%\4?/pqw\/Et5=Gt91uR+F:++IE\a>qQ>MijVIB5iVPj?kESWy9EHZML^&a6l<RLyhhX
9JWKuQ BbR>IWM>R@d+RMS&SuC:%$wjM*tH9PAw$qnZqu!uNLjFX&<+/Z1#4uX+bp&:<9eI!D9CEW=d<G6XwwpI
=E<VbM hl/P1IKc?^L!XnLIYFch<m>c&CXklcPMeWZIGbu\lZ/Ihk^qBhiL6QpbdAFV>d><\JdBybdhR/+B=T!&
PPuadI $EX6GI8L?<j6w/M&4?^1HIlyi5*hH/A/&@Syw5MQbwi6wd>VDA9c^?JY/HQSlD@YAIt8W!HC\#N8>Z/W
djQVEI *HaV4iudFScQ#*pc6p=lAK8n=+K/nlRKn!#yWeTpP/ShDn&H4m\<FQSTIi5G9EjdG$8=HFTa6kXMwF*Z
Lyj@PA KIG9*W+Vyk=+b+?4J?L^p^%^tH1wqdKC@Xb/t%G!DD6!EL5\Ehk\MT1VKGMhahFQK\QdhnitwuG6ASG9
K9/lct ktKN!mmH<emaN5&YJ*1aP=&!5mk$14?^IT!B+XLBJwQcqyDRhH/pDdCmn^kwGm\/5cADt&DpJA!TM:+e
m%hICT 6aKT$iiT1>E4L!a*XETklLBN/VI4=X/!TjDL/Aj1&#BSC8yDT=<aKnKAA5=B&:b5=4c9Ti!EbP#WwA59
N/ltmm /B!PQB*XcB\/Cy#WYB^#wS^Zi1R>jJAwVdt>+&n%I%?$YhD1@@KI\AL5cQZ>pA$J=\D:Nm5DmC5d1PTu
LNJYcL FHmtbBiyd!+!*Ll!*ACF<K>L*C+1*uLX8LZ@!W%!$j/P1@9h/#:+%+%Eukp+ZNQ9Z<?@4=6D9^lCdW<k
*ni\16 Y*Z@WHj\+iLpR#9wA<Hwl@l9H>1kQMmlQq^ejPDchq>%>?Dc\%m=>*n>%cQ8l#5**we=I5>&h!?CVjjb
i#AVhn 4%:/5X+JJP=1X>=el^kZi$n1M6:%SN/ZdD:eGF/i:6:%?kTZTy=#HL:%Jn=%J*/8bL+JuD+Je4/ZCq:%
:\F@$e 4#*t*9wVi91yP@9XB@9WQ@ii+\6WJ*DuX9JJMQF\#jC:jBqMYBA$>!cIP>J*LnIwwe!ZY!!E$N?L8!ya
MR61Hk 9eCHMDBIZeI#@n:wE58VMNdN>iDNc1J9@Hm+/%X+@R&i&l41QF#EG/TIBqVW6pKTLJCLGmk!<@eiC#D*
ZnLPXt j+QH+9E8CVDQQ?tT+QyNPmLZj#IhpR9+=/^L$N>qIj=ln9q:R\@ud/^4j%#*I#\YuB!QRV>pD?WEQkdN
N9E^Dy <WCTEmjwEYnPB@IuPVuBn$F#QaVtjA!c<!E$=DFw+AQ&WE/8^/DbH$J#Q\IN=u+I#jMaNPeDSpWI?:?E
bc=&PK jk#ZRA<^FjIa4wEiam4pMX\DQiR6kV!Gc/CHjG8R^*AN?NA9BwH<T?nHeP%l&#9pMYS:$QaP+jqZ$F#5
WHJATt @^L/MYVnlD!EB9/Z=W@?@BiA8eG@R9dJj&XTQ!IypA9$t$^FdqaiXlAHD\@*H=tKKw/@<lVq^iSb%e#6
*Hnc5> VFmhdFtNVc^MuE^aVe&6@yV!@/niAWGku<>XVuI\F@jQHn+1n=IL@QiPBnDQ@>4S<Pe5^V<=Gul?I\4\
yW1Q5Z d\@P9*e$AIGk@=ju<N?V=^D/9#uQAWYJ8A/iwyC@VYA!bB8^VH#Fpkei1qIEqh%CM+tAaT<IC<6*TBQT
DF9dkb C<VXql%ENBKTu\ll8jac</Wamyc1P=5WpjKBGZw4k%/h<tGKl\KR#l=tqLC1yKneXI9j\Gqp#euj@8e$
CM*bJT C6uXAJ8m*NZ!X#!C^$PRLpd=W%6SaRX1NnFjcCuVEb=T<RaCQ%pab?WRCnniKF?5@Sc8jp<#t#tXC&%Q
JXMBcn #SAd1=bJQ^cqMh\qA<APq\@ME^wH^bKEX>L\4FLY:<Jbp1PjNuC!eG4WCMA6+IJaXLSaDJ$DDEh$L6PX
AKwq^m kq<CMVYJPIZRN1t=*=CwlK%e$yJI?<Ka!K>XWWVap@pRbKqIGht<c+$LE/y&DDJX!=juGS#cwuuHw?aw
+:P+@# Q/%*?bRS%>Dq^qhdTBK/6AiBe!!jEwl#I@SKiKnIM8NXGb4<I9ed1w@PeLk^pSwHXK\L$&k%w9n#T$:X
FtHp&! *qbL#mHi6p5GL1<w4D85*6ddlK^dc>1nKeqPHHFtSZHd8#u*dS$TFRY*enjDG?JY%<8Kdk\?k^#mPk&b
S+V88X DLdA\iRLhNl\PAd:/Vm#muq8!VAu!8nXE%lT/\Q=S=8WbeReV9Sha#Zt8LR<Xl8W9&j^nJ4hKeZ&ed8%
KEcip1 =iNbLY=D+@cVXIp%&?y<YG%iVHpdQeb#ntP\ece#b4J%<<P>q>4BYn8CiH+\?\QV=l=S6PK=queS1pAM
k9X*:5 MQqeu9ALVmIe8wyZnal<\T\%6ye@#X&V&KKhm1C+M:Q\Wi$P>dy&aA$Gmp/RRG*?pW!llt4A:w$j?iu?
8\X:?< pk@^i@d*m<T%w9b/wC@9EM&FE*H=DiPLVESR8:9d%bMelLRJ$PmpMhq:+MhmM=a+$aaVGAuV>tW@6&u6
ZStBL= w:t*=DMiy1:6\nPc>*d*ipIqNl6>5Nia!>\<9hQi\HMc$YZ=XB$SVeS945WGacnZN$In:4BYM?/Gn^iF
D=/qcC <M<R9+FQZ/!uY/i8DKHRq9en9e:*$Eehm1KIHmj54>W9\FDd8>i^WB:uw:Kc?Jk%KD*KQb/Yw:$QI:Dt
B</RcX /nt5qVd6TDqc?Xyk+K!NtbIZhcCQp\1H9C*G>+P@IaPFJ1I4wR^N951\AIYP\e6Pj$RTRQ^+qit?BiSb
1wp#^L iZ1wy!WZMqR^MDqYi1<V$R+h6h<=!ht5eeXd%Hk!WKcXquB+jm$yamkDQLlX&VeqwT6*+EWJA>Cj#eEi
-A*5j# 0001eedfce400110333 Page 354 of binaries1.zip
I*Aj5C +TlT5KqDRH5t$N?QlJ#yqykq8JK/aw//t9pmK!<chS&YAwJVTbK=4p\CI#WiehR%#j%NlVm^mRh6KKiP
BTIkaY JT+>PIHEJiYkGFi&+dN$=ITec9lyPNeYjDRc5\^*AY>m9Yt=E4%AML!jyJ?McFjGnH&Wyp?TXSTtQPc8
Y%i&>P $yTZ9CTGW1e!:qPnQS%HN>^uhNhE8pFZ1GPbV#6&P^cjbt&b<KjVVL&8S1S\I9Meu%ci&Nc>!SB1h^kJ
hWM%GJ tYmhQ&%dkcuN/Gp@Wd<<$q@h@@IB:@a&Yc%JIKkiAy??15MpkpT<<F$umiPJYZ:MPubI^d#V5j+$h=YW
i1/dm? DqymwYPeT1=c+JhwlyV#D>JVG/NmW=d1Q!m6&+PYwRNWG^l4+I5A@eKXp9ZG6NY=?WHml+Xb*da1uG%t
XT/Ce+ 5&nWyW$l?YSDFk+!\K%uQEhG<\&blq\KTn19p>?@mnBBbSudKLq&IHnc^&F/DJ#M4h/4Rk1JVewP!PZ<
Cnu4?l SmHMBFidcb%AyWm?6$VGJAeB#B>AV@pla%t4JY/Ky<JwSKTZ%/DB+:&Dk@cwS>btX$cVjQInCwbT5*Aa
8b?cVQ tTY8n=Bh!=\8D1??G%e:In6w:H51eSJ+#\JSNpIBX:bW:qYlSHI=!VhA#98Jp1QIeB+ay=WVuEp+=mYN
nuuYRI kq!L65$N9:AD\/tFJ1*ZnNQLGdtRkM<tV%!Lp/I?VVhtNq@PRtPLYylQbTTq=X>d^$yd/J6?bK&m6Xu:
<u^N#F AnGGJVnG#\=RM&/HQWtiR\P>^I%$WXJuR@ah=py+wa$Y5IRI:#ET55GVCq=VlYT$hiG8@+16V@Ln:SPQ
n#%Q1I VHY<qA9+DQhHdQ&ISG/uHKhXWjTyt*6K:iC9&Q1cGFJeL^+PYCn/G4<e?H+w\G6!E*bcL$A6kcT?MT*N
^aW%VF VR=Pj+Kj=LkEjM/wStV=uCB$wmG#j%e%#B6QD4^:SA/QiWGeIdiK!i8Bdu6Ke$webl\9X&ZEE6RuNMWp
dQtq=D dN@NpKt:ZeN^pjLS68KEc:<K!lEP^hTpF!\dIC:Ny1lI!Xw=!IuV9y88tp\Km%<5<A&BT^8a<?TG!d!*
w:nS9F u@V1bj^Pd#c4YdI:My%Y^BW+>ZSW:Fu#aFKlp*eGAYwh8ISAwyuXZjI1w>cyiaLw^R!P>QkSbNlc%^9/
kVL4Bl m/kiEq/ybX\QNZ*#6iFM5mqcMW?Y9@D4^jqb*daY\6np<mtTG+qY:TT5/Cd6>EEBYAY9+41/8e<ImSNC
WYX?Yc CwbyZQp=/h1IRLi9buZDYRIIP4k1YeNIP5N?%HGlG&t&A1mYmhS8VRjT<:cqQL\p&e%5HF5JIPq9DaH:
hDNkcB Pijk:@NG$lanSARZ\nMZc!LX*HMk*jXQ#i?S+/dl$?e<DdRD/R+!S!\HFc^duad5&&$WqdaqGj#iC%4k
m&lZ^= n4h!=!EC8d>JDtTbQVi%\cDSXh\=Bju8kM4&u^<<A:jN*R>lt$9GjJDH%1LmXlS&<8n%eGe$BpWk:=9D
R&=9j1 =984y9yKa:A6mJT6RiAJ8d1$$@&YaQaHqMdIujX6:kH!<BdI:TP$WIJy4JVypeYGSWNl^e\^atc!44K<
w9N1LH WEI4m$Jd9FtHXQ1tWbTHC&5jIk<TcA//cA$6=MlNEcBqpI&8/dcLPhB1/j6VQl>$#B@$pe5MMZRCqmVR
BpAMX% ahEYqk:Y9lk/!dWJIFPVL$QZ\k%jaDDR5%J8Lc@k4yDnMl6m<:JmJlkj461RaFBiaY$Cjt^\c^Sb4jVu
KuedJY BlSDA5**:=t<+GBcqETG\PpdcLpYTmId=%$S&mN8ll!!eIA8W<AZ=WLV+>:VC!MQW*qF5&JB$!N6Ldkh
NS8&L@ CR^1VkqNe#u\4l&<4:<185theSp^9NWKYF@?:NlBjwP^i\V%5B6^^pc^GhP9huVG1t8nPGht*eV5qSu5
TChI** J&<4:1KSK@<h$?%>w$niTpqV=awN5!FETNaHeNHet>=MeDG1SYBjZekkMVM8n:lb8bG5dYqC8WqqmqZd
uR:V^$ YBT$!ya=ANHDWPH$++y<MCIVlSu@JewGHIJmilVy^?B?MlF=X&^tJ+6uH:F+1=nkp+QpIcL\/ddF6JR^
6>*MRb I^$iw/m?mE^Y6@SBey9=MtnR>YZ!91G\l6+jhE^?V6HmWuw@R8Y$KMuk8lYcik!Vnl&RR%Am9MP&WFta
p=HlBA *<5AVXA8^\=+9RyY&qnEbXt\mP$LlcZ*c1Jetky4b+dPn+cA^/k^1$ED*BZDFQ+RM=mW5jC+m+C>Aq6e
X?QhYh CL#445uM66^L8K<:nY#<:jVM:$#/$EW6\6naG<V+pDCC*8etHG@buJB9At$DVQJXdW<@+6NZPt?$VB:I
^5I=ue ^yWqQGe$9YcVdC6>WVHKiLYXBMEP&N8!^pjjGk8Q=C1L$^P=anqh1<t64eZiV\ynI8tZDNV9yKah5=CY
:i:&&P I>NZwHp%qJenR!ZSTZ/K<L^mLFkwtHt#@GN$S:6^ciNAIMY/@1T*bG8jwn:hP^X+K9^6>Mc1/8iu#a=m
6mETdn a#pI15==Nl>DiN@V1TcjZC1Qj?aQWQS4E^ARY*<bPjei?QK=%FtamR#@6k4LWjtwk$jGlI>X#=8Z*qGF
wV?$dW j9LwcKlKMnLpwkp&jtamR#kM*i$R^TTn$eKJkQjpB@L!*?Jb4d:^:ARJwG5<R+&FL%j5>/E9*4a!Jb<E
$TYVIR \El/aB6D9I$QJ^anYXRV+DDX?R%ItByI9ItL!mbt!i5#8l6u^&LtwGjt=NNkwhQwyE*u%t<mX4SBhu*M
LPCy+S =Ln#HeaL+AY\q^M:b9+MiFi&C@b#^Al4cN8m@A\5=teT/+pq8+&q+SXa6A%iCW4c6VR1cMk!dL+eJ=A>
F\^pl^ Ekq#HJM@i\=^BHYDA=<%DDQW:yBcXJ!69DG^k4+DtXnp1^t\4STS@lybZF$/T%i#X^8yLY!>!l8Jep^N
pIHjQM XqBY6DF!X*RV%%hawcY95M81nS?JjCm+6>yF:HR1uNYXy5?nCB@%c$\/cl>ah6FLtj6N6ZIbM*dyK#nB
:+lWE4 ZECZ?A89A\l1PWC%YBm>eCF:&$HMnNAQy/P/+N\V?GY!@L%GhJJqVb4GXp>AGZTk&dt?I?1^H:p9Lc&F
#QipCN Vdb=8LBSnnYa:9SMqh%Vh55pX@MCS9>T/1tZKc%StRXcGZc<6+5P#a\=*bcB18J^bN!bk1py^45G8FQ$
VhcF61 I&^DY\+6&*eZ\%^M/&IEp$HHjuSI:HH#^$tM!6hJ/V15NhBLhnj$!mh!Mlpw#8!mMb8w!n5*Vwj$EeP1
&5DTm+ #nlwMkPL^<8KtN8K#w#1IkFWSwS$@I=KlynhM>5!*Z85LDe4/HBaqM\JK541LL5a5L4W@auaJuFJiBp+
%nK*XH #EH>e94Pjd\anG98iT8WhQyVVQm9%@WL\\bW@Y!Ty^B$pNjELNa<a?hFyFnjGpXFVJ=c+u?$nKmGE1!X
m@d4XW FdVy:yCinkWjWb9JecJaHZm4^65\CAEapaKw5QjcBYXb:ew\n<9uL!^h$/%h%:uibMJVRY<:1XY+5nVJ
u5:Eh% 1eZIi8&?>VGp6mB#diQ9Ht^+q@/*iS&SMt$Yj=jZkby?ILE!kQmN@h@qhX^TiHHViLuT\^5$ij+y4<Qd
>\p*SP qei:@1X*?yHZHD8B1+SQ9a#QyVRP6=DZ!lBSk8!@=ZZ+GZV:1X9/%K9+1G9=6Hplel9+6WH=<WQ=e19=
tpCLa$ 8EwmW5n=6:<PwCnEXjeQTHD&uZNF=BcHIReF#upHEYwE1e9@!88wd<NXV@WuDQb*qj/X%=H\Kjm!M*D%
CbIPGp 6V>*ui<KR/l/YRllewn4epl>k$?/R1n/y^CBR1m=yVDCWQ?EG^n8?*DCd$HeX/FRLwk<GKH/wJBEw5nL
$a#I^R >/FEFFHeu/IT%mM9w?CIYMLudwQXR@*4C/LtDH\JJTITltM8Jj\dBGI%CKId!GK9DPI$ZpW$5Qk*&Mi/
8deaQR jw@@?b=\pWAwVbV\*b5uMyEuN6FA^b>@PQE1I+puJ$q@CLtiLit1IytuJ6ukQ4ulW@JXi\yQ&<8LXVim
EKPIn* IZL!*:w:8CD@X:5:8Q:bDA\iuu>$h@B\Q#wD+\?4##@ap*=ne8S/hAaGF<>n$A>bmdubH+Ht=H+kYJmd
b4ViJa +#HwB<<NjA#/IR5%N?k^cPBDcQBn$A>qRZB#QkL>aBaEN?R^/Aj9G6hn$KAHQBLen?EctQ&BnB98^*AN
$lA!qF ^Q&AX+DuMX\DQiTB+upM%$Ckl>CQ+S4wIR<W#&P+Bu#IC<V#GK+BH@4FiB:DNiBDulmi^*D6aY@I9^ej
b>uwki qj<4?D<$hj<=nQ/Z1S5C@J$/*>@Kp9/q>A4pb&j@S<VWK@#@Ncb?pLT$cG@1X<EXcV#m$GITet+BKj$9
5cdIuW :cZn!Xm$k9d$T5Tnu5LKqP$Khmh<9nAiZ*npBQku8dw^8*D4pT^nLDF/KwNbE\Qcj^X%\c+/DqMYCLDb
1!tT8@ 4X$6j<Xa<I$!Q:*1/PAFI#<tLlJu&!1@F$S$NWRdLQ6XYj6b!L4kFqGZ>:C**m>44pu*BLtY5X1F\$c9
q1!jH6 CQ+L<Y+YkY=T*HpWl%pThu8HI%PF4>@IPhA4Wu5y&LGi^D/dL$ychi^8B/^$5k%/hEHRkM/JiJ%b/kM9
WSq#<p S686lFDkqZERdDW8/PW=SPJyjPFbPFAbMVW#SEL>R81tL+u$=8Dl*uY=5y?&4Ll+KJl4aGquF*CnJ=PT
ituQJT #llTV*!iCX>4?%V51L>M%PD/DTFCt>B5I>A\:w\QdmZ!ScwX?&D?d1bw>j6iFBb%1>j=1ECVTB6l4mtB
GwN8%R EBd96A4d4&:eCtYXlJ5lWS#J>B95ac5!Fjpq!h4lR4+XydM6J15!#W&jaX\@a??Qw^eFH4j##\hcTyut
EPqbLJ %Ze=6kTVqePReSKHKYWLmS^Ji*T&Y6&R#<IB5Zp@Dyu1!?jn!aBR^+HFWEEjabkH>:&DF9e>>69:Q5@E
T/\^k$ 45FBGiQ=HeiuiJ4/aD6MG\6plH+1bdPuy1^*iC9N>Z!Rk@1n$H^c*K/SY:DpKwwGDK>R#M46tVmHASdl
d!yJ&W JHi:p#IZ&iJ4q<y#+t>I:!$>@jF#B+m$aXdh=Z#98KdJjcW6da$C4M<IeNjP9p#8Ce8>VGTwM#=+$1=J
l#A5FQ #Z\GS&5I\Z8!RRI9SWHBcIK6Q+/M^lJ\R<T!IS*5ue%mXd=FCP$Q$CGk5leQj8QpDb#dtG6?^yLi<JcZ
#5nD=+ Yla4lLlQud&EttCL@E9pILbqAHNL6:A6HpZW9KbJ?/=ku>6y<Cp%84&M5aCheaCl5qYIPC5NbY&&>lL^
@CRL+S kq/+H#X#V%<kQwiFW@e\kWkXBXp:NJp*%5DLLQX>LaytYbbkP/JE8Ip1!4$?b#6DMT@@HJJ&wbWR5XL!
TD*A^w C1?d+P^tZ%ty>?dyX/ylG/8^*mQDC^*PF1y!YkJ1>I8N:jID^L4I%H1Y6^:h8PIDcW1N\5G\nWNEPKCu
iumkWH QkR&RT?S@AJhA$pGWN/cbX1&e*YCwYAu*4Py+$4W=$epB45yj8N@%nd9<<TWC61G8SAK&6>QM>5LPTAK
HD54B\ 1@?qTuQ4>91SYbZk&>K4XMm!$bwLeAI:uh*taL1CPq+pkRyPLAIZC81>Xn<D6ZRlCk4Be:VAKGSjkjYP
>J&&a9 9Q:JS4w<<k#FhAjScYA?qjt:=cie&mkFBqi@Mlta>F<J4XII?MKT+<L^j$HEhXXGE?*/NnH^\RA1ewAc
54Fnc1 QJFCW*YA1KKD!bi>pFEWj/!Fp$Ee\=VcW6?4Yp9IVa+/HTW@jXGntVeSl8ddQ^e6<5K%j=^R!pV^E#/N
IPCNGt 6KSJH/iKj1Q&6LPi*JMC:Z^/>G:B/F^NCYkKyH%^dulqbt*c$!<S6Jn%@YQy?y+YZ=BS<%9tA<1>aV#5
PGBeCy HK\5uya#pDjqLeLHeQc\^K5uZP49KhHVZJa@TSAh!diAnS8bZ5wh!DJGN1NH6DLJ+8L@RnLwKCK?+5pq
H8DS%F ue>c?RT9!6EGuTLdH*96kN9J^n/^e5EJZQZE5Xlayy6:^t<Wj<+!QDC5c>hd*\Ih>*5#R>9a>TLMD<MI
-A4\5% 000db54d2b000110333 Page 355 of binaries1.zip
W&R8X% 8Q6Mb:\/b5PXQpEbG*e^iMd$J9*cKebqQ$ny@E1ZT:MC6/E/VRh5</A5wdY+CTyu=aSZ<DbC5Ay*!<XY
Vim9FC @uLV>YkEbbW9hh\GJc/BL$wW/:8^6jy/cVLVCVRLlS%@W8na$>BBQ*mBSAy5w/bZQC#FAu:#cFd^1FK\
688PYy ^/cT:@j^1=9ZX1wmTie@M5p^Xql!SLM9WA>ET^Dw%^^?Al4*S@cFp<Yh45jwBtN*JC4P!1wlGe>>m1&<
?PqhbN VNKkij+%cATiyc=4:b/eY<^Db\Rte<#AmEwd<+/%w%&a:eT9hG5Ah+tSFIl%H44\i5ka/%M^K+cu:&n@
/PTjFM 5#w!=HBYSDAS=aFE>Dn!e%N8m!%i5eRTpHX5q*YDQTYydM!J#Hp4Me*H=YEmFy$Gnhj11MRClcLwmH65
k?WYcX *pwb@jB1R#Y+Qq>EK?H&^!nuB4\&TNnI5^9/cXua>Kp@8\@T8pnMjPPqAZ*><naaPX+#pn6Gc5WJk?4>
m^@lAt EW?:?ac!<wwW=LZEnHJ6L9I#LTW/DMw*bY#iLt<E4JKM+D>h5bZ$X*S45iFY8VmMVKjW9hyd1cI>PHu4
qkW5>N cPMm?#Z^p%H*cVhLyJ@YMFcL*%tmiDYD&6lNNH:<nb/hkF>+D$I9XI=YSF%%<4aCpVZPX*IFeHSceZ8n
LM>FRq M=\atkFXuVCJMIYnC%8KRHu<5>YGMJ\mC9Mulb1RPL8+>&kLZP5LF<$DB+XWbX<>FL/wY=uyj+Cyn*</
p&k?M> ?Ww6L5tNPE%Jeyi$:+e!/@8L!enqPC5Duyj6!6QtH/j:FB5%1>!1?=\#LY4QAqGmb*W>R:9a=@GA$ZuQ
#YAA*a #?RC$SMK?4!%Ccw8uw:nNBR9J^J8m1F*>^EXi&#MSBaK5=c<*BI6@:^uM\YV@bH@E$H6YaBNGGd:S+1/
@G5Bq\ =61=qbwM=$CTT=:duybPbbR<>pHRVEL*y+1y%VW/*N#etCh=$nJaZ<9!byIuw&Q!nHn#B9%<KFMtSMnX
k@>+mW GWlS&c^E5=ZupMJK1AN<8#/E$*X+dR%C>hSH6k%M\lKmpe?FhiqAh^KKDGdBiuT<H@GCp6#QkYbYq4^W
pIaAYp #yG>y$wwFP+^>eyZyZQabNcZ*t9eLJwTn&AhbdGw6daTEIq\MN%lqVG%*QS#aI<JqW@d*pHYG5^p^>CX
ESp9pL HbVhF15PNnXCPnTAKR>^pP>IaW>D%>?cCZX+k^HkCQ9Mq6*QWmVj=qXC5>\uyPMX%nb?b<8^pb+$QjdM
y<B4hY H&&>TIk=!FtE4HD%ltkVX5hnLHtElmGB1PSjLI!%w$%/N8l=Ze1hjKmi6yq1t<KKG?Y5?Leyu6G!:weK
GISd+l 95uX%8khGnLFN/AY=FBANhmjMmw8%@DVV6!mV5&C*+hHh@i@R#%c!Wm*mTy<&mwdMu<a$ac1L<WMZ@FX
86^Sd! pJheH9uE^c^nbTDkPk!%9J>=*=kha5njTh!4PB\l/t%XZMw88?e%N!Tl:n5Mj>/qQe^/c5PeQ:A@MTc>
jhb+S& H+y&?:TIiYT<mnkeW/l$y=ye@4BH%b6j+Cp#>XCJARyTQ\YYX=$%Lukqj:#I==6ZTu&PR@%Jt5k\4TZN
u$CSEu LlJCWHPbiKyWWuP+1&hQ$JiNA@J6Sm*cujB6*1PNaK!AGS9=D1hV<VhFW#FmV>%a#L/LNmHDn#ScXwdR
!MiC?\ aW:D+mbcN6GPSVqVm!KnW4KLF#CmuYCIcXy6/&F=HNHphuupj/MB95Ii<V96nQtGFcHcWd6A?!EjWZEd
%kiA@P k\bjAn49bAcI5wy5#<hK9+w9<T^$YFI4e!G+8EeLTX@u>K#/+DAAma*XS\Q9K*qH6l!NDKILT>R+X5n<
A#lbp& BP$4\:SNaWRjK>PFhRiSqWEp8GIQ@&^SBVu$EC>ul%MNYF=@M$^Fp::T>BDI*kqeTa#TkE<>>nnkXbTI
4jlj<& Sa^T$PGhaR8Qu!eZB\jqPBhCD8qd8Ann+!+N\N+MakBcF:6SLt>X8m??CCI4Cu?mXCEeIMWbCJ$w!eHw
wDTiIX F<RCF@teekWy$lmJKe+1G<#YbjqeZ^/FRSWYb\wPb==6pFdAMy/6LS/98>KkKn8:JIIGFEB*KMW<!iyD
CTdhLK d4ZyIT<jdQKC!Sk^JER+8kiIM+BeXXt4NCeMY9VQBktK/@CPM\uq/\m6!I@B:#TajQw=8XkP4jhpe*nH
8eD>8I Bn8:A</k\4W1$b?$uEw&deZbwjj\E$#cLDYwNq9cnXNEBASRY/TkdT*/<a6XNRqJmR9bM&iEb8?KPDI=
6tXTiW /kedc=>*:KEhL&ykQ=$Q$TGC?TEXtkMay6?#LIAJISCd<J45Ey>CYYTS:&d4LuZwX#%EL@+1Xt+CK*6W
F:#AwL YkI%dQNX^8tDLi=5H\nSTuDP\Y88m4Id8%eGnWAk/\jAPweKitmltHDlwHIKqjB#$Ndu5%S^5W=JPW#l
EpRaNa \++QC6KlDM@YD6c<be:jhCJ@/a*IREeBuJX@&A*^6IFj^uNLQm6jlc6i6ZhcSmjXQ!V@JE9N%l&^F41p
Si$kHy G1C?#4DlIBHpnj=TEl#ILMhwYnu\CuecAemCEKC+&h&L54F#NtKPcG!/6jMYShbXhPVhn*F9wE*AjGt+
W5nTHG nAQ#duVM:uncHqLISMZhZ9H?X*Vw4/Y%Ac!jmP%P>R<t&Ey:>9N1FNp\DKNp6ZdkD:+t/w?Qp%9!5%am
P4!<:: GTtmY+>eREZtjyXDQBa=Qa:nQ#+ZjNNLP5wwL5lGKl^P@5t?Aw/VVeC=Z$uMIS<H:G5Fj\dZb^\HPT81
q/El6G @w=AKe?t:64%\u4W!J^NVL=mTAE@+iIX+pXjwTu=#1Xe\PXw@bX1d1Ip$F+8\:Ij>dbN@n4h?HyD?I%9
dwp68H A*EP?e%Sm?lwy=^6*<%w<!*=#1*#F*PMbVk1<ANXeVn@jW&M*>w&H&QV@K5lW@VudmCEuj&j5GSC&H>V
Ykb1%C S?bQb@/diLhj**L<Yw#@TiZ?%>uR&ARNHE*?%I=N/a&%wc*X*^?Y+=<#pEKA@!lSA\E?Y1Lt#:aCud@9
pZB9&6 #n<cd@=etih9!<:<Q8kc<y6mH4>BQ^A&DjqNMa@jwDpjRuM?Bk%/CA%=DJ4nIVVZI>AQBb6DjqQL+#jw
S5CCu6 B$SHIL?y=jEd>ANKDlAP>pik\V\QwVpik\c#Q+B?DNjAD\T/R#ki\#Z\A@XVIB!Q+S1I?+FjnPM^ZANB
<qq4#n \A?kH<M%EJn#AjSn8AaCRl=AQ+b4IQcHj8@HeA*+kA5DAu\M%+CeD/Ej\#Wk<CH$a:n&wHEYAu\M&S+K
jGSBH$ F+eAH$M&#ki:@lm!AS?wy\WB@4%W!=?^@/Fb?e>B$*<!K+N@E$ENAj/8wnjZ#\j6@+8k@t?JwB:?4+mk
hddeQ4 b4ja=W+*cC^N>t59ZEtyqB?I!muIeEnL#<Am%CcEN!kYEP!eEyaiGD4=cwcJt6Y&ekkH<:b4G6$VB6kD
X$1CFS kXEjiFH9kLnDNVum=AIPDc&ilqFRetPPaMh$aE<b!d<$njE#c#PPFEIYR8=mXLca/kZm9=AhbD\RFCV^
VZe/&b lZ+4V%mj=VG\*Fl1bpkKB!PTT%yd\/SML>y8ZW?9LDMw9%h6Lj>LC%=j!R!<ctbplt1h8tT6FX>!JF*4
qcIu8J 58:?Xl9KcYl%?unCk$l?NeK5H#HEm<6aTQuFV9<EXP\M49+5/HVh!Lyep<kZ#@4dY?P+1RlME>X>:SHW
<j%$Ip Pp\FJ^?aIVj<SblTE:w95!+RLyMG+?HpSh#$E^JjGL>A5qwd1iRWeZZHn@utd/KB/Z55<5P11QWR:F!+
*kb5?B imQK&/CEMEbC&55e%P/Pe*Z=cI&BhHtKGu#j=1lJ14jPdLW#*9:qNaJM4<#MX1$mySc\>q6+iC49:k8i
E$E/ti u&>+dIT8&&k$dTS@%b>@Xc4E@&LlDi%FdQi\@MK^44ZP@kl/lm#!iFYC$EJCkWC?9akX6<*VY18^d!Ta
?cw?E$ +:Z\T&DhEbqQb1a9MA$*nq6$w!Y$$bj&%#=4Mmh8k<>ZP6>wJVbHnJ5aEcVn9mtXLZFF#WLyy1@BF9$$
ReBmh1 *!Zb@P*#/95b<t=+5Pw$NpiVk>Pm4JTZhp<Jh$1uqdpm>DQ$$KWE/PlC&^YGn*BR6VDJkC?9Q=?lRP#A
Rmb:ce i?$?WX<Iwq&>$n%q1GJ<X5kyW4\E=8bLaYT@wGFQ\YGKQ^QpI4cI*Ej&>GhEd$#R:chATjReT!&kQ9P1
+=Qm^c T^RtM\:iwt19D:BIlRZcm^dMqBpXaaW^a?6d4=EpI*JCGSBcttP1$thqV>!RShi?l6Q8kap@P%Ltbqe@
QTiWie k8a8#mGjHGdm$kpX=\DlMX4NW$pcYXkZyM/Yl5Xe>Rhdikq%d$EQl8$HY=Ju9QQGWY/P4#^#BmyQ\=j#
eWGPQ% +&/I$@8G+&/T1u%J?k^n!DRI#R$D$C@HR4GMGumJT@6ceDBKmMMyh#14VRMYShX##aSqcmG:J=l%QmMQ
X@b9y& uL8uV+KWWE*eWBln:?tTkye:5QA&MCEW&dSp%$HBW%I<mX*GQCXP&MEWLAiHbpNSS6XaQi\#+C\Bd<Nq
+jchYC *qF9?qaC6XIqTw/1^j=X#HdT+H^5Xu@k<>#KqShMMuM>d?Vq1jR=RpiP8+qFCFmEDF<1ABYtElPbHZjt
HIC8b? ^@*S\NQi6PL6ei8XM8a%5HpAm^J<p16elMZR&C*CiH#wD?!?>kKEnu5LP%W@DCjGB8HIB==pVaJ<6@E<
EXM?n& p&akieqZ%ca^QP1K$/cqiDZ5846jp4\NyW8HpD5E?q!+B?EIM@c?C<NBWaQpNP#1FS#*>d+NYHu=c#wI
JGL9dG wVtuTW1a5jQ5K8\a%CRwaN5L951BilX#lb1:/%=@FqGdX&WR#J:WYKY59Wu/^KYmy+Rc=HJLm@<bwQj>
^=i:w5 em&JD1T@9^SlHqdcyN/hacIDa%CFe5e+ab4\BRy/yu!:$FC6j>6+Ak&^!qtt9N/8<$W^5acdcZ8!6Km#
@/>%WB CpBiGW=WAFcbRihJV8HXY>EMP:X6<cu+p61K8NMbETZq94Am6aRD!e=tQ!+W&8qm+/&JeQWjMCl#eMXe
<G?t>F ^+^6BZTGp!8MZ:n4$8hA*jj8Jb4*Qk#lAQ/belIajjNubw$99:#>Wu*p1Q:e$tF48SmJm=!J!/N+\JSj
?8u#:J t<R5bC*iE8D^dE&J^!eW^?BbHRV/5^w%54p5I:k8ASiid1FjTPcdVkn6LkenG*P!SaRP<&85b4HV\bR?
jQP41L <9A1Dn5\$Y9Q^P<b6bD=DPQ#I6cNku:\XtFuWuGun4iSG4mE%=e^ST%SXwp1Swamy=A/pXaFPe6?K^<<
\KWM1C %!8BVGTn=+9T!/uRt#Jpm#Kqj*wkRS%$5?@E$wCiEa!a8S/e&A=4cMYB\5MwqSGy>j\1e$8hy%$hJ&WS
w\BBR8 @MI<EM/dEXubM>4iTlcyL=hP5qa*pJA>b@i$9EIFaBBDTTp$REiX@:u\iCy!PmKY#LkKapnwNJnQ\?4y
VW$hbd E?h4XF#aYMMc6NnG=8\p&y:+Vq==1+JA56>=y:GuSI4VpcA:5*1teDdkndPNeBCNNuHWlpbdllMnV/K9
6q&^6G RhK^41LqC+p?$%b5YXhFcTVdmtH<&S%Qi*BWFSYH&Q5wp!JmT%RuWw=9aVNE8Q\jHbdTK?emkm?/WpeF
iLyVt1 PkZ>w488KnLFc?9iVb5E9KI/i#Qcj?W!56SQq<KD:lmpjcXkQEAT!b1Y+c+\wYdqVL:Ibh=9E+H?^P@<
9lh!k< P/jBE%G^cWwPIZw^V9%9E>5qEyNJmcSVGa6WEGXGml==ib55LtPjMXZEb$Q&uRuT=l?C=?ynahtahG=j
I$k$6C YcQK4I/wcy?C=8mS=c5*TSN#:ZZQ@eyLjA8!@c9MT9ete%:KNQN!%>clZ=ZynXGAZFVcywjYy!ZaZyMq
9@#tTY u>?!jtp^QD!!ddwmcLMm\?h:q*6!^y5>DCJ#Hn5KH?E<Idj8J8GJuK6BC=GTN&?=ZHY\ieiF8A!PyI8L
&%FM!# laXDh@DdRaL/wG6Hj4*5JjLpduk\%Yunl/4t&kK6?BM4u8pP^RN4<?EuHtSeq#h?ubjd8BG?+iw^95K>
-Ab#5j 00072d6e4b200110333 Page 356 of binaries1.zip
+a+n*: ?@!8uZHG$ueYWwS*QXJR!N\@=Qd8B?C@HICk&p=n65$8\!lb=eI!\/QCdGGu=JKAR!pk*?dubhnL+9DI
:CkaFq $LTcS5yc/E=c9/KF$h?%ycP!*B*5QpXH&*inPh9c*$SkN+WkEi9%y@MM<mhLCaKFqE@aHC!S*I^>Z%!W
6N<EF8 Y!JICeEk4LtWunMie%@BMPh54Ypm\tah/+enThaiJ<XdtYpFY+ACEi9a:a#5HBVZk&GQ^@#5jKSaZi+C
CC=q8c !hCHN@T>>XjGwmSwVlB&Z<TdbQej%jP\q^@JBcPW9*k>EujMd?a88mnip*=A:^h5q!$qbbm%p%5/e5mB
?bLXX8 !Pkdi8lQc^ym9dWAY#$y!j5mNA?8VX/1h<l@Qi&RnjuH+TwtE&49aStWPKQdimHc61cY:#My@mQ<9yaJ
qiLtaN GM^DM*>CIj$A?llueiE9^6ZKK\L+I*6Juid+dV%q4PXj:PNYhw6I&Fy+<wjY$C>qGYt\/heEh\%hGcic
tR41Jm 1bR4@Ijm>Si:=LP#GG!itRwu5IElTLqNF4#SKG&T/>+wGH/l<yA%?<ZakcE=!dHhjk9+EY=11qCMDc>W
&kt?m$ =5bKc1>+1dq!SnneV8/1+bTSR^jVaBZ1mYetk>Td:E/JldB%Nn/tKQIjki4qmG*qX4Y%F6eVR?6Qh+Jc
PN>Gk6 hn@V=?#uMBSPm9B#Hdwqb1jXaTi$M8ptP/ktY&qY$Sy&=1VjwWBQ4&?m!AZJ56/6Xc\bn4ADi?J$lXSw
Gj^$aX +G@/dZ$MjN&ED1?\+Rje+itae?hK?KMC8/9V&D>WiP9d\\HSZ+q/4!9*h6hZw<J#&YLdb$h</XQl/J<K
A/E9EF atKZ&mue%q@\ZXj&a$eN>uE=#+y#MBLM>8hpK=9:qq*6ZQ=8j>AlK%*ycSWK8^L=6MWJ=?EZS*=?>Fi+
h\cDIy Ewn$#5^HmJ5j+HDwW<Wqy!h^>YFdy9KW\F5TZQamuHcVV!RyM^*&ywCW%91&qN:Mm5j9c49*6ALWN&GA
yqEVlS \$cmu*1C<j1HRPLy^<NcTJWZ1H:w/F6HBFStLcdc&&aJ^6G>pKMJ1dGpIFATTEH+l9!IMEnel$4TdT5w
ypPnPJ &BEj*n\dM6tELQ*8/?mECyYWwFG\AE!MYa:em!\D+LcI$BS=R*lLqnI<D%%&St:PT%\8d4pYFi1AH4wW
mVNKpL $B=k&a^eA8iGK^Im*ip#iSmqWHq+LNpP/?lnd81$NW\<nP$l+ZiDlwcCP+p@IllmWYw%qmMl\Vdp\8wl
cTycit d8N#ml:Rk#FZP^ZN=Q@M^&ia9DNaI8SWPe^K1^iI%tMyQ61XHia^q18=\:#w8VK\%T*FWAb$bA$Sq+%w
?IFj*k DI>d\k%ADlH?Wa+dPDmXc9Yl#YME9ac+$\I?Lbc+l%==i@AadWnd\p1$c^<YQQ&eM:hCAYnwWhRDHuw*
l+J<!^ VcM8$u?6JYVZIP9TYY^^\qTDmNJ+\4SuV8&utR6y^>m/4hFQXZuNpb?!eeTmGHIwV1:b8??$6b@&1hTJ
/D#qW^ C=X?qBa!PR%@BjccAw:Wjy5apenNNp%Zq6Z%/l4cynZ8#HZWL1GiCQGK&#LYaX/XSwQiHp<cP&8RSDuX
?4e?<E llPSbZ*QFN:JMyS$C%:WbyW&YbjS4y!D\$9cSFWY^W99&Z=tWq!Hp=8nI<Wy%ppPXD\SGJlCnTD6KnMG
nm8Mt5 ia!WDXY>CJTAc8N9/=SW<bkdEJL9GFae:t=RMYe#pV6VXHntC%N:EKwE\LkA8JkP&4nb+9ay/kekaWQD
99+d#R 4RT5d#caV^hQp*>VqW<&FwwSl$ku>cmm5Z$HqC%G>w9dHNN\5cFB#dlN\@V$uw?cBmBBt\bdl1M^DjQQ
c/Vd9q VTPHTW/%hi>$+P6QM@QG/$<%#Bkln!w^%bAw/$@enGEH+Wt@Wp:buw+VW/F9C<^6wWe^W<a?kc^$&W*d
EMMD5T P#MwFTPm^YP8>webWK$<aIPGALu@>>1k@=NYb?A@KSeCAj>n@C\E#Q&jpk8BkDu@KL9?X#*#Q/#H+N?G
YpTi!w %$J?I@#<=*L8n:Ai@$d+?Vjwl/#H9^F?@k*/Ii9^d+Tjj+N?!H4<G?Hu*/Aj5l:@S9n=H>EQYw>@I@#<
hD/BVF G@SD%8QjCD@@Bk%?CM*>GQSDF6#jCD@@B9%AwCkE@Bm8QTSXAkE@lt9kl?+c?DFei>mcCH+M&S/$JwLB
/b^X\q @^Kc<+HK%EB8ED8IXh#E\JmDXhn<=#Bwd8n5>E9&RiQutMI1@&@%1cWiZ=@/X*R^?Ge9j5p?k#p+H1H&
=NytIF AQu*56L@lZ*:XV8dt=5eCPV/W^ej$:Y@n<:><!*@n<!wj\uI@bMbFeL#G#M1?DjS8WB&IMj@nPle?@@=
!#S#WL $dp9>nANQ@ySNPX?>t59hF%5KR!BL9a#KG!<+#e9L+Bl:5nG4We:bSbuD<N^qiiYyS>VRP+^CLDu<WFX
XLZXKL QkPGGWt@jmp+*pZEP:4P4N^Walq\<KIWSu%RuB&%mDW^aBLWp$1FNukeS9WX6#Ltp#X^&Ca%Y#u8L<Z4
y<D$#+ /%LpCDnVm8IMwh#1dC#E6Qd8Vw>BFFawPEJeNFSTd:!8NY>a@NE%Z?aZbdZ$Tnkn*l:#tHJYyEJ$mqSw
q&HC1< aiDQ:eLj?Mcb!iWJBBTK%SkabRHG=Y^H?RFqSiJLqtD?wHh#8QBTp158twn:iy=Cuku!ENSKl&qj8Vwu
YCKN#a 5aB=XI5%VE%::Yjekp\ip?JAKMA\h^?&+FRd?n:^9QG1pC^yqAaW+F5Wi@&WZE!:/:+CTYp6tC6JPES^
&lyyyJ G4NQZZGS5KiPtp/+#M+WK\m%klW4tTWSHl5ZjX=q&MWZ6>yhjCuiX?<NM@1\%69y4#C>Y9#P%uhS5=+h
/b%^Ph 1+ScVqc+8AcD^V@TAmmp:#NMWbXtePH&Ti<aWB5HykuptQJuVVk<w%dL8teM=$APTW6VpM+**/iNh!L/
9VGFZd qKl5nt<5Y6aW?HmmT1X>YDDL=%TS?JdPQuMVTGX$DdZ1i8ae9JQ<>1K*^uy/=LyGb^GG\kGi\/:V?1wP
qdb#Cm @B4VB\d#!\9blh#cZ6t9!iRN<GyC<QW5Z:c4&V5GT?B<*?4yNP&E8W#ldeN^PQFlq4Z1h&C/aVu*>a@n
GiJl<j LIwiqZQ=tdLZwWRnC^&kA^LlEY8T5T^iA/cZIIIyS+Ghbu^=6^@IXS#R<Nc?19qeibjAewi1G=mLFu<m
iYjk4+ #y8h/^yVR6ckh/bk*YSBnnnYlpQ1c$p94$hYmmAZLLMk+FA*S+eC1QmZjTAqeHEL/BAZjm6RD1=&Ihij
ZJyw%> S?aT5KV8w<C>^$>EARWD$y>=\T61B99w94IQ@amjSh/Q1cZw$#?Fu/Y?E&4pQak&:5uVRXkemEX1+XIk
Am&6EV 9h5W:?I$bMen*c/IS5=8e^!BDT5nhh6GAB5VpAHeEM%ISSV!?WGVZWl68e<wXSPD*+@#R%iAj\BLhBeK
MDl**Z %ykb>:Zq$D*^G<IYKC<Ljt#lpmIjhGTwRlIZE&beYPBYeGaYt&K/y%/Ql:!jy&YqpmI&W49cG:mqH?d<
k\A6Fu +al*#SwjVmcGQIRQNp6/qiZ45Ktm6Ay8^cuWXHWWkBABWayYYYYL4\9I!G<ey:hHXTXw&!WQ*TcHeF<G
9BPnJm ct>G/N8yC@m=>Q6a:G??4jXTJEblW\ei+&W*MhG^/8H4Y>W>TiATypDdwTSI1F58$lERBhBq=Byk+Vi/
8kBnCp !>ICPQ#PE4T^pqi%$t5\J%*:GaiM^1%aF>TH#e*t<=5Z4P&e*:PhLVGq\lAIG@C#X#95:iF<WuCp=<!h
$w^!EE >6jmXZ@*XTB$=m&$#&9?9F8+$GBn+FlQk!wn5XKt\$BRi/A6JGj9l/5b6pnb1i8mA1KIySV&G%Ie\8Ca
nb*#1X Lk?lmpA?yhNdJtb^e1NkXYpC&L*kPKuwHDQkAL!<?m!Dd&kXVdhV%ZTdF9+m1ubMl4ljZZZbk9Dw&:Gk
bEmc4S 8V+kJl/We4&i5upN&/aDP1F\y<k$:%#qRLc@=nNP5&IY9\V8Mm6ql$$n1JkZubuZ8wbRH+RnXWc1?>ZV
My^V&a FIyjKdKq\6F>R>W5buC8H+a1+n5&D9ci*tSqlhwD>R?Mc6aM&p8KyDPaGw@BFPt^w<l+$VmJa=WbZ%iI
bMAtTE y\D>#CibYLZak9bn\AQG&qPtmSXJqcTdlBL+C!mkeLcJTH!KQe!>ii>u$dYEID>6lWDcEM6c!L5c!RG5
%6aP55 >@m:Xw*jB8bYtB&RaVChLRnniFnMi^&L:TM5=1+MK9n=//ueTNClNnDB1E<D1ZBw&4kbh#hF/ejwSe:4
TpwTY\ l$X9%4Sb*m@5^X9K:#SpMlqljLP8lXJhZhF15LjN8dSFX!d9JFDiC>D%6JKn=^B+Ke#H<Luq9RSGat>/
1aw*1h hZnGQQI5m?ea%^blR?DV*CmYA6KtV:&+8%nw1b=VFIV<9k$yRSp@RB=#$d@Wt+QRZu5:<Bi*:*:R>a\A
ukac1c ?XDkRJd/hekwHh/mTk^TmIKh#m5HWAd6Z+b&Bw>$%BIHJhKmp\myP?m8\6IPXIVTKlB9mNdaqHFnW&Ew
c5=M/! y%y!pXk@pX*%^+>m=J&L>XVl/awl^uZ\%hueeppY8ZeG$qcu1C9!yTyV*Le\bIXFNm&mc:&$QW/<RK1H
Mq/9aq *X:bCVKHWIEFESF@8^\F<@!*Lph@w\eJBHL?R@:pA=:5*?lB@kd>RCWu!G@$IH?D=ulk*95dQel@SHM?
pheIcH WKMG<l5>!N?k8S=Ce#+GDZykYj\dQel@SIPAD>$%4pikkR>iN@hn$J\<D/B=HwF?iJpEiR#bjnb:AQ$a
^V&1:E 5n&+VIIA@!W$/F>Ck^>F>Aj?bJDHpA$EimA&CRL=q>Be@^Kc?*i/mQ@^AS/**98qG9w4\^n<e?H*!^#^
LZpEWm mAZj9=iZqQ>4Q@:DBS@+d?Nt8H?Vnku=Y?HJQ#4@=*KHj?*>u^L&!j<II=Y\BuKV5/tbG@>eGuL\eJG#
a:>jl? mb8a9#J#?nqG<@!/DHMuS*pVB!Fdc#6dt%@&\J>6lY!6dB&W:A!Mj1KFVX#MnW#EHA#i@GX>!RWGej>%
nYljCL jTp5yQ!d>iZ>*Q$lAF*kb/hNAMaikJ?9?<<AIRAm@K@Z#*hEXERESFS$bESEbHSMNDS$NDSMLNTj:?mw
%QImRZ YBnaPLk+&BmElMVElISWqJTWXHS@ih&*AXARAXYAdmkwT5B>F&Dm=+ESwH/>AH?<aPFkwPGlAAmITMkw
@9da>c tABwKBkacFlwiATau&@RnqDRMFm\ADkKdA+BBZkeA$y:V%^kbAaCZwWkXd9m?CwI*@Ca&5H4lEaI4BTX
AXPN1> YYup&MEyVBihXRWlWDb&/y^aR/V%SpItJQKJESHN4qchXKEuQq*@%nY%eYdm:B8dW>M>9juh%MW9L4i&
44Md\A b&d4uE6M:hX4@@m<86:b:R68eZW#%+CE@Q1?8b%LBl+JDjM*kapFDj*#8%iM#!R%Lh!CpkwdB^d&48?Z
yKw6!+ ALAA6Q5FAPK9T?IDJE6qt@MY*RQT6Y/#:9dp!L:dj<\Eq%*y%>$DImX8RS<CJqw*9bd9SPnPl1?yJP<B
TLV=P= eTn8X:kjJ:q&Ryu8%Fu8AS8K:6LLn$FkN$\/:Sm\wThdW&eZ>wREBGuMWb:1l\5w#jmn*PY<9Rewumji
A%\+d& A!VI#q<q:/t%jte#@*kYiR<\jhQ!H?!:H*9yS#<4Z%e^BZ=PCDekj6KQW9!=8!i>TK9:=k5*WIcb1lKN
yVm&KJ Tw=CAlCZa@cP6>m?Ne9>RC:9H6B?D=k96S%9Qe?d9Ai5*AQ&b:q&qu<w:h+Dn6*QLWQmSyn5\mHlS48J
:D5!PB XKFB:KbQ5+1hAb>L#Ah:aiX!BMNiwnH&mM?ycQTJjlXT\iR?YA@<EHwQ1PH>iA>A?NtylqdSi<DCS:q:
K4C&i@ kQe>wEw:b*J/Ykee!lQ4\hm?l@kT<S+kPulLek?\iM>*l*E*dEeh5i6WP?W8J6C%i$EkTmdDwLAnn6@<
e6kBJZ jqjVPM*&!QkiwH:ZjD??R%SqPy\MwZDYp^CHQatmySA\EwqW*&</I*LZDL@/&TyT$Z&aP:a4Wk+&+8:p
-A?^G9 0004f91756500110333 Page 357 of binaries1.zip
hTbMjD 9RnV+EVESPdHRW@tp5!1&J!Nw+F1AhmkRktYa&Sm=:^BXN+c56Q?i\Bq>n$k!c=qQiX/Jyub95<w/Hpp
wb&dC# XeKTmlVm=XSqYQZw@eSPJaZ=E$>NjPy*W89j&6TTZ5$?ldmEB<E4quVZjuli5MFh9q:SFuFqMREuItcI
8ly4Hm FSJE6GdRu$<+H9N>nXiu\A6<<QRqGNj#TqSBH5HbpL81^qL9>PR/B96VPTIMFllX5J\&GG#X+*EPZR<8
=>wd!u MA:^ctKAL$a+IMMJQW98hq?J9%/qQ^*AW&Kb:Gi&V%l*/AQAe\bM1<d?+P\pieIJ9wS4l5WqG?1jk>6y
##@dV9 FlNa>ZyQi/J*TZQZRBKH%JJqch%&jR@I6KE/&#%^ZLhyNq@Zn6Dq@$cE?lydK#a1NpVWAwP%ybDQD?a/
MwF>Q* h9SY&+b9^jwi5Pjujn?biC8=jXjKSZaM8Rh<F?KcKuZjY:i@B<Da*kPWRi@@d>*Hh#@%*>6^FJ4G?88e
\V6PDF p1PC8?l4^nXd%iDddbLZt=L&Z\?pw!Z8D8<BIh=*pC/L#9$c94tCi$Ak\:AG*<e:LL/6pQ9yHd#w1*9A
huSEVu K5/h&X??uQ/9@&d$j8bjQjGR^E8*G+>dDiL+P^:X%9Pi?u6AkNbG1h#F/^6n5yNc1wBSS:TK<Bq5LCbe
c/GZE4 AXS4WB#m/bkaIc5FhnJMC%YBZ1<SKa=Yya/RZjN/yHw?w%yTiTb94$G4A<K:?>pa8wS>CbPIb$Ba=5>&
>^e8bA SSEA^Y/J4#y6u*E@/qVX^YbEWt<W=:9/kqtD!jQSXPcd\tQ6?W=w$\^BWBT!KJSnDM^E5ZD$!=61H#/j
$6YTKF >T=b#6S?!V!PVKZ/Dqn9q89ek>6cS1SYP?Rq:H@ZcSHIqpeC4mm5k&j$<E5ui!Kii?6tWG!:J^1qtDLF
G+Qmp5 ?aKSKZ#ay?L4ju9mAYFtX#T<:!jJw1jWNkYN1dWZ^:&%4anM?EmIK11$*quRq89hbpJQ=/++/\%4yGwD
X!P#Sy P>lh>N8a/EPCynmjQ>XnVJ8ZK$HeME6d/5ePWM:Qj=EaK:8<N$9@6RJPDHI/Zu?Gq$e=6h6!+*L^ti>?
:?kQhX LEX#CTY@K!kHmlqk$+1$Qkp4=Gl4?>:CFw%FJ>YW>I*cm8EuKD/LXKB?w&4T*lMD^YIwlA@?QN?Zy5d&
1qtHRm SqHXyQY98^T!4TLq@cNDA5Tt^&QanIcm@Zk1t+^6>C+*Ni<Bu+uZ:!l5w^4+qybQI6^:=5LwtDFHeKW>
1pS5bG P>KphH6<qN<neGXk+PwmC^6GV1pF=F5ZHWL%Flcm$$Qu:<B*<6&Qj@SXaXaG1E<HHJ4B!a&BGA9ylcFW
?VVYD9 SQBE&/DtWL6kyqSVRjLIp!*ddBA4m$!/Pjpt1QLe#9Rdl^%G#iVW\CPB8!?GWLBa<m:pt%9DH?<uWld=
#iL+Tu V/6q$^LQ=1KmmwDqnG1*5>VTDJ4jP#quc#dqC<@%wjl=!>kE:kFm*DI5NW9h1$&yB%jNpSIMRWS+!iM&
JK9Tj6 pw!VniGZyCVJZFclW9eA$mK>H$dc:q$5y&y5Q=48kBmZu/GYlw/%=MBt^1:44+Tlt^MFZ4l=j&KHZ6=#
i\!\py %GH<9IBS1A1e+IH!+q4+HM8I?JI9VL=^F1W^tRbq1JCLtk>AbyFY?4&$$!b=p8#:p5BcRE:b$XQ81/u*
!id5Gb miwI#t6DVa!#=+$H&nJ5uJqa\$G^4L8WVQV/BDd/VTWYF4^BF/Q*p:EqY!Ypmm?Hp@#l*qPHuG/p+$jq
j>REEj TNq&8%!p>/AMt&h95EAZItBVMI1S\:B%D#tZ/Z<IWb*R$bXKTD9EEIZBea55CM&@cZuTGc*=u9CX!4F6
u5?YWc k@6Y<dRi@I@+P+9lj?Hn/Q*WD6=@&LA+hQCQt:u+y=6J><jN^M1@M:pY9*LhK4\HAH>PIVC?JlZh@G\K
CC\=ij !%h1WjcN:Rd#41G\hcn%YPn/4!$?@l4j>Ld$Lmq8HXZeE>%Z@L<Q1>!b*AP<!Ga=%c:m:^Dh6cj@N?*@
B+AyT6 NcL>R%QuQ#ZqkFX?tpYqiA@wbb!>t=5qP$F=F>9@q*Fb:Wj%QiDXQaCPDGI%Z&W/in@:^*Vn%/ijQB*d
<B4tcV Ib#uc:KN9FY@+9%<M!L/<@SlKtY*FcX<c@lZVNG*T@eAIwRd/+C!C@P:$V6bZ5B$a6T<8ubJy6@qq55c
cRaIJQ aG*1pM<mAjZ#<mBPw%:B?\CwaSnaq&a8Gjyjdp@M4R?qSP+TaAC+A=4?pX8j/TtdC$6pQ/I>M<VeZen$
@9y\*6 ^F/i\R%WMB>w:8%RV#4h++HTP*W#nFc*!It<1/ZlX=9!PbY%wC?8RbMLWE:!QyDt>NYlCKY&5TtEcbWX
bQY@J$ S98<&!<Yd^D&Hu>EI$cCmtLnwIEQm!V/+@*+Ebq!:V*kQh5m/L*m=>8#X49B/=!/H:5jXtP@T>qiVN^&
J%4#aW ep&#6C=LZcA8@!jdAi<K4P?8>iyN@tn@c\KX=AF6*4dd86ened/<=RBm8*EweV<I@jpa^c#4%@=+iHVb
JR1Eqb ^:h8JiLiJHj8jty@RlIkQhC5#6T#PBdbd!uIT=NjypeK9@ApGuN+KILI^aa1PE&/Yl/PWiJ81G\Mkwet
u>Z\4i q5@RCy4kENGLBj^wecWh/GHCm/R\bcK/>8EyRaKTRYN1JX+yum<y=j#@&H94kDm&dH&$eheA\WJ\6&=e
:\GXth k48:8:5GRkn8:k:B*h&D8\YZRIBk\b$E==E#=<!hPSQt=5:eu:#*:u@hXj84&4%:%>y4%X:4?!Vb$V<6
kN$BQT !mi\G^aKuc<!R<bK%JJ?Q\4%mJ=>>H6&GG=DHq**aw/H1i&XZKj&/?bHa$Je>ukt\ucTe?XPt?#S9XS=
4kIk1Q ZPbF&Zbi&N/Z^#\ABpw<4*NT#!Miac4mul9K:Zj!w>imtk?Ap6#&W?1X?<K6P=LHC<^M/q=l@9AYHQ>$
CmmLtV y*c^Qe?L%+u*\w?RGj^@@ca>=G?euB$HR&/qK+5K6P6@QN5K:k%ZcYE@N+hw8whVh^t*cY=t/b@\WyXd
GV&+WM w+u1WpRm#Dj$R4HS^It4VAnl1/FY?9GKbCGbSGmNI#VN1SXYCe!tCTEXedncdV=\+qQnByR@T$9kSe5W
jNAWbh !m\mndIR4ATVZYbd#PiWjG?$GK\CFcEeF^BykKn@%n*dieXmHY14:tYJy1^K>j%i6DIajEY**J5ehLCn
YuP6l\ TM6\@d#wGQSw:&MmiGh$MlR=m\GNuLyZy=Qj%SlE18Fl+M?#NuI4Xd:iML@kP@:iX@c6QIb/&A^ddLha
y$PG%L XT>uCtuaed#Ty6%$8TulS6%GhBhMDPB9ACA6Re?KZ@#A6m/#jQW\E*@*VqGMRJ!&$+=EmX>?<Q*q5?q^
Yl?*HR 8VtQ><jceZPkuD5LB9H+\5BMy@^Smc1Z6Jli#C%:?XW%!Q5>uZD$/5Fp$bajZI?$5L/@kd<X^JXDj*Qj
mI$Keu =QB=mRTAQZ=B?9:D>dhiqdelQ64i^LqKB<G!V6TWh>Nu!IL4\i6!9IP&Gt4Z/>Gj^A!eXSWE*WBSYk1m
AEAy+5 GGV1@i8J1ZkW*/%QiW6iWm^/Jn</Z%^@eb4/@?R$Edh@L4nl9YK@?5Q?tQ+\SyZ\=1#S&j%+MwXi%MXL
Vc@N!? a\AIQRC/RWbY:L%P?\:^?u&^<Z&A:JZ4A!A*NQK/KQWe=Dp<h$i1=VpnXVjb1B11Zia/8dZlPVL!:EX4
T@XQR6 hF?Xj:VQ4Q>\m+$pd5%M^NitEZ=FEemZ+FV^+dE*>Xe9b$J?i$/Bj@8eju!$kJPiLi*4lA?A<C4M?\Qi
\pC+Sn lRjAaH@HZPK#^Y5/TI9dyb^4H+WRSB9q%N$>p1ppuhD9V1PPV1Tl%m!%hPBT*4qlJSKD=C9N9H1Z6$Jk
#SGD:& DSbjZFJH1PNhTPnNMFZ<\MWl1#b+DN=@PN&!h5wWARlVn$HRc8E#/!J@Vby*&tp#huhjq/eFqwAt8mwZ
+Y#uwM IwE/Y6/LZ%=^14aymt@BJ5edmuPIFbhQ4&GRIdnSce?:YG5y%hhP5FMYDuXp+d<FuaXNynYi4lK$VPWl
EGINTu 5^mh\bB@SYT?m$H^wHX#XjG>AcaZJKGPC?Mq9?CeDGq:4=9n!bnQQdkFQlpjRNn?QBeBPW86kJ4A:?Vq
Aa=%Ne RwLJ:C!ei1c5=ueBVEnGEq\^ZcihS$Pc8qC*VuNuD%=y?#p?j+hjSwqPyM^!<jqjBnLktt/=XH<1m:X:
+?N1wb N^?Y*%P/FhN<4Qd?cH%#@jlmEYbJc>je6WwW=y4hCXtILFnl&Vj9NVkV%$9::?W1FY>KNIG+:yX^>k1<
ebFIma 4*XL&B&QZ!/AWZKt/!#mF@6pXu8bN^c+ld#6NL/\96TkQSq*E^AJ:*dE\InApTYI@%dt*DX\=Ty@!le8
MBu<eN 1ARVBSN4laVX:5#%6:N9aKV>bKn8AXDQ$u<45ELt<Me@Y@Nw4SH8QuuYQABmI=QAZW*!PLhG\<\NlE*j
%%S8E> KC56#EiB**/$cd#>5TTt<n/cTpl\Tqh<^Hw5m!\XVGX=Q8lHF>D+VtL8:y\Zj$Zl<jL8KQ%5$&YiK+Iu
Zm>B<I jjZ9Dj4K\GQZlP$EmEXC<R%DKLMj@ep@PwWSi>A?5tH\>@/y=?@?cekD\Dqn@\G\5j:%aVyXS=A:?^qE
yDb4/% NacDqmmX>+IGY=l@9IJC\Z1b!%&@Y$ueNH%dCYuMyFJR:&9q4pTKeC%RD=RH\hAH=*#AHjk6G6V/kV^F
icJL9K F<BP5kG>1Mi?BKpXmt86Z<\S\\/9!aXa#L>ElK#LT=w*MblpBV>FVE!HwbRDBIpwVTXEFK@<nnIL+=nh
C=apAR #^WR\Sy5T\/4QPuqZRMA8!yn@ddI6K%AAMXklA>:KRbql1pa6K$5#aqmMb9$wT%PL=*n9wbwXT9yAYDe
Z5uwa! >N$Yuh8NKpD>N+>m=ueHk%Z&eHHDW+XH>uH>bIyP>q!Q6*\AYL&L9QS9p>l+AL#^:H6$j9EMcQ:+X^J^
=XH4mL 4&PFdZJhc+Bmmb:BQ4X?<J+^8X<jb6N&u!QpL!FaBpS\\CiCm/=4wFL!QFN5k<Rh4aHaGeRIKGdQ1dIN
EY5H^a Gqi!?%TRb%>S&yX\aAeP!1aN!@yIV??CWy8y$wKt=Yw^\btFD@b//*p5L9\Jh$kjH=k@#Zw<XkXGibXZ
^*y<C> <YljY6Jp?Tm&Dn@</Wck^hG$hTS8tnABu%#8/+*P6MmkiB*iq56m@y*keI9yAByT/b:1FKcMaJ+X5WjQ
hQDT^M 11t@9M^tJnecpAppt=iZlES1hwpPq#dAISiV!<F!^LM*4AHu\RW>^5WY:?&GH+*iH@:ZQ=5j9Q<\Q>bj
=VlHI4 aLe1C6N$M!Mdlcn6DK1XmHmM/#e*9RDTFJK&^qDbpF*pBkYkWE<uK54%B+K6QEa#++qIBFM?IuwN^tFF
Ht%ajh MuKulIZ\8HuNB*QQ4&N8QSF=Y=hqQ:8Z:hKeZK/bTndR>E<$=CE9S!^i*JXjYij#nbEC?WeqMQZSIF&F
b+u1w> MJb+>/i5<mbZ^cTd?&GD+&kae6@AjcM=?hd*AuetyEaRAkMDQ:8\mLwuT6hSGZ64W5@e*RaNi1%1*\<b
FN&PTX 6w89FpY&N8jqNR?QX1MAuLE#MVY/ew?9l\/Ndn4Tn!Zk>*hj9%9u!N@G\8Vua/HyMSeMKVA14p>$Aa?J
Cjm9nT %HFt*bRVYT61lV!^=@@iL^4#Am/eA/NWGWPXtJ^q@jaDTkRy*eY&tu</l!EZiM?5F!XTd>V+98WJ:61E
I@MQ=6 eDpaaaKb6D+^CHuN\p4&eN1?+m1>/YE!n6bDZ\+^ytjcbSR%JQ=^=CGGCHtX*b5NdR^tD>91MEDaethw
SkQV5$ VI!CP4wRyNEq1FT#tR<AaTtNK*NAAmAZ:KX&\>+*65IZZK1+984%pd6DpCQ!QlJHA#TJ5bEW%HB4iVVH
9k:*R: /!wM\P55DVN&S?R^tJ8Kd#pRkdyu=S^Eb!>iV1e9Jen*^YjZ<jMij4lGP=>dJInc<:GwQZHFZ!h!ypXF
V=IKZb YRaZpwA#uM4HXd&N9LT>ctD^HHkABD\AWl*@<\PQ=k##AWB!n*h9Qcy:!98qjY6y=p@j<!@nKuCXFFwj
-AdQWc 000ad88ccb000110333 Page 358 of binaries1.zip
dB+y:c Q#wTCGYk!#\bBt#%ZRj9=VZypd+&^!D\q!6?jLd*?&l&HkAJ:S/&54h%N&iQdl4\PIE=kRM#Slk=ZLG=
4u?dw5 ekNFFmLm@AE\4N8P8+TYI^I6KCGSYdVpd\/:e%55\#Z%AKD#8F*P8LL<9m+LSlk$$Lwk/X?$uR98/lpH
DXmCtS @P*\%q@AdAZ*GuiZA&GPlDFWtFG#ARXXYd9A?#<*iQTQ6n*?+iAH*6P=w>G@hFQW8C=n6:/i&*PTX*lJ
dDR91M 5C9u+KSBR4XAK*15nHlJJAJ6ISKLFN+>T*6kS+6CG9%5?luCdFDAln+/uKIiIM8GFF^adPkP#BqhCDjP
MQ+YX@ n#$:\alWQ4:pt:>56&#CRwbEE#tZIi@68<>>>EuB<Mtp\VtddX?DdpGL\^Pn>leqJVtp$^y^SGDW:DGm
Dn:\Ie QY!LmGWH/J>kD>d6FFnke/M%WHAXEWSC#uyNh$im4%XK4JuhqFNc\aGm66Z<^+<?Xj#\b11+SNQ:peK*
H9a&j5 NE^$NH^RA9:d$Ck^C*ic^KX=?6GlKh<aJXF=n&WaY/>5+PDij4&<=/FDI9uEl*G1G!\PeM4<*m8dYCc%
q6ye?K a:<*RCcAVYDk::$=+FNdbQ&^naiPuF%KbYmy#P>bV&?T/9j!eNtAhBlWZd4F5\l^G%\XiBYDWbYw>=*$
4ht>SZ Ft8Btb9#^kWJyiNX##nw6%R&Bm!t<%j#KLp=dh5$4l^tPdDW6wl/5t&DT8AD%YElk6b%iG5p*Pw:XXA@
GR1K?h jCkYykV4NPBdKeG/b/j+1^u5?BG%15#h/^@!4nqjRe?/hY:NZ:#L1&**yp&R:P+5/+\Ydy%DI\WtEBuH
n:qPMB !AyB!T$F&<Slhw&1n1ddXwX\qWnL+KYcRM!a$:&CERG=p4E*EXa*KG<Pj/CE/$Vb$tZT%B/$L4#!GbyR
J>h&AA MTeJ*tlRb5DF\bD5ZMDlN!8cVIhey?hiKF@5Kq$&14yaJ1L85q:HbDBnINES*npSe/jPtK9uqGZdFb5E
9Ty&%h &&y=L1SZPG\X:#yEkweDSS*9CVai4eX*NciKS61?J5pnnX<?j1hD9D9SkBqyLwHi:Xq*Ym:!ANm$jN6>
JXHlHV >\BA8R*YYnt6c@%!@\AI9Be1>*\a>@aetn$L9Lq@iaZi%Q=EM>54nYY:B+Bu>&QeyMy&Y&dL:6u?=VFw
?j1:@9 wpt>X&qI+%$=jw!a+pejADTca!?QLn$*JLaiAQFqZ%G?*@Kipnu?P#h+>Q#?ywPNVy8!4>+&nKRe6EYT
awqqjp uc95eA:%GViIpE\Gd>/RS4ST^RVX9RSK5+9XibQ1K1aea??QN#GPJh!uWPpQNL!1jLqnC?Ry6\=@AB\S
a<E*V$ N/Du*Ct@$pE9KD/?=6+b1/Let:NC1uB>tZ>BwQ5FYXe6wX*:+4=G^@V^4mlF6>NH@k?A:bZ9G==Vjddu
t?i&cy 6niu9D94dNh5h%e9#$>T:@D8d!P9ZWd9H!@5IZ4HdjIAiB#9hyL:hCdQHM?X/AiALE::SQ9Sw@$4CH8a
hJZ=Xb nH\A@MQSqj?Yc#>%qa!HKaaJu4J4tbhZR6i<6+:*XSebqT8QF9Tq^WdWuic=n&e@\$*m*pYp:pHBa:D^
bI=$/F 8M1uLmhl*Pti#@<\81>I94q:1nb<j@<AtQ/&tjG\<NNEuL?XAQ^4+m+dK@9@<B@<H?E@CEV/Z<F@RIZ^
6nyK\@ k4&LbyIhN:i#$m/<G^E*Ih>@!DZdV$njEY6RmQFW<ltwuMpKK\DE6:$%mT\&8XMHS?8HZTe+5M\=SbVt
SHYY!k kVEIBqk><M@16tDmylNYAnYe?\8h9:K%R5V6yHFkVK55/iL4kCd/nX+lSR1HXHGjSci:qqHj1IibWq>G
!4jH@8 QyyQnqKp$<#S$k?JT?I#XFcLH4DiCiPhZb&DaN9c+mkCM\b!Hb@BGGK%eV&1RmLGP:&GSDJ1DK&+ta@&
d=DTt< TLZD5V/4$5K>=A4wkp!EK*Sq^\6LkpJcc&HFLGKjq4PpG?!$?KG?&&6dB!B+48wLPupaEAH&wqk4MIYV
4/4k65 JJuZ>aDIVhc9RuVRuISRDiah=YcRS>@9TNXnS@kGT:QWJa4JERW=c5H:pGCpXw*+MV!4:ubb^XmT5Y1d
+u:BZi &8y?=!q6JHQDl+wIM4=pWeK?:!Y%Cqe&jQ8=M#VtT+C$*Bddc1qljFS@>W&:5wHDQb$$/\KCE<NJ8h=P
ba/^Kh e>*4KiEQ^y44Ty^&hbSjG\e=/4jtWilTa>&@%m>=j>n:n9XTGXp4%YSGK?$=H/8#Qq<Zl/McDCeG$khd
t=V1\G lc?Vu<e?!n9eLKi!lHk4EyuJ^TtTqdPY*WbuV!J8LmbD+emY4iw6q:MF?Z<iD5A/!8K4Qu#Z1Q#q:I=D
T/j6CV 8+eh5iE:$Hpnb+#m6dpl9X/j:w$aS&uXh@1=NmFh^^8DW88*PH$mH*WFB:RQ/KHAA/>9piVp*kY?XYu5
%YbDqe NalTk<?Y@$1YBA/%H/QpW/#@FZNJIQFVP>I#Z8G?RmAw/unCY$BhAZbuM!w\bcc#thCXGl8H$Je<S:Aq
+k@XtJ qEW/tySluRQ>QTt:Zip=huj@?AETVlwVFXFNTmHnaVn8a9AIPG%culL?RJTBaWjYbENR&+HB8!cpL/$e
ZJLDi9 Qj*WFtqNcbA\^84W#Lw+*9\4tmaL<!L1eC@tIRPJFiB=?Xa@6SH:BWbc?GGRtE+/c*XaK6K>WBcbt4an
w%4!ZP 9lSt6TkK\FZdu+<wbZKBmbbue+\yJC/phC51kmBjt$>DNZ?6a+TpV/FukhSbyAaTM<w6PEQMuEAukLcY
Qc6W^^ N<6c%WhL#%VTNXZmCFCDZwQk1Ljnd$bP!RE=CB4p8+hpH1c66%*nlDcyIE>9yJ1Jw!n1mcnC6adTZLmY
cG*WiA #+ISRHYMqA=jkP6JCI^RK:LZ5eR^%^VTVFQ9N4cBi/Zu!>Ce5*%X5i\$bmL<9D89QK#FE1DwaEEt8aNI
Cc#?dD %MHP=h>nQ8&#y5jpGnLyj>p&w@lG$#biLJjKdKw#Vkk/RL^E#p/9bk&VB%mlpDdi1+R8d#@+:9AmD%kQ
mW#LHX Mq5hY6DWF=DtCX+Wuj9!LN\KqFI?D#&k#yYWK4$R&m9teJWSQcRA!F1T$bm>m=DYbWW%h!m8$@mtm!Fh
PG<@wX Zlpi#:NnM9WZKVk6Hm<6JLD*WAWq+kbqm4RyJQ9Q!?NZn=Vlyw\J:8\+bQ5kb*E?VSLeX4Im=keDt!hl
jZc9SB $h%hTn+&\/8T$%=nh*<wXm:PW>1KlnAEK!4#!6$NlFY^PQC9FXP^9\jYK%yw>pAd/1ilRuZIe#>LD1IY
G=Y*TK /?R4!EXX^C&KpphD^IdRRM<SaDSH*QW?y!hyIB\X!IPi65K1bbRLNY@Gc^amjI?=^1%NQ<yVmIGNAhYl
NinKEN eCYRceE*DKWX=eQnMi+MR!wJGjt^T\Sb#tiwBb:MIyeYk5/P/q9/AKedPQT%/M+!Ad%RGm:FaFBN91F1
hNGK!H XWetmicAQK$$Yq=4eP@L1mm4a9Q59MkIjV^1Y8jqnc=5bYS+bQStCl#mynymebCmQM#4R/4m4*%J9cq4
V%F^iS ?:uFYS@ap8lp6P5k5KiHnX?B=6lJT1BAJh%S?9:Xjjc+mmB:#iaKmi@uGB@BJ:k*t@%+M#9\p18>beTJ
>QaXB9 kTN$&n!W<Yt#$?dpYaEaXE*+tSbyRac9>d\*G6qwaFQBib&?Hd=aipYW4<MFeLK9tkIQ>N6Qye>/W/M1
S$qWd9 %e\P9Y%JplAV<W1l$iX&b\ul*Y9uD/$eiEadVknS$!bGM&bui5j%=ItVH^N+jYBt4:WFM=ZSZIhbDnRT
u8nmG1 m8^:*^\5!?chBW49I@qY=8p!%Et+bwhbEIHG>1jFGJ%ik#t+RQjahFP/98W#a=pZ?u:^QM?Kkh5A<b^H
<YhQdp tMciE6+DcX<?c4#BRd9H1SVXRmcNKblHLVuGF?<=lFteW8:MbBGq<!Vj&?pV>#F\RFC?kpApe+F:q4$V
ccJ=c$ Z/P9*t6Yd6F+pcH:qLM&HEX@Tu\I+8uct1>\:YI/J1YdMSjEq/yI<K@5?c?y!Fm?=K@VQlVN=ueZKYYu
y$+*B$ KH\HKWMu1J^Y!!1@H!4Gcp6Q^8F5hh@jAe1VJcJSN>bYIeWG8FCB9$=9P8FdCyh$bQEI:1yTi&$\4Ri1
DiRB?X DNScIDJkM@4aiKw/B>tImc4QLBu<kL<%d#8:cGQ/JdXH5<q\ZZ6dZ<GWm&$nCK6?kVhP?%:9/?X*%^&Z
LAaEA/ hj@+XX<tEZKZa6LDbM9h$GS%T+Zm%mPjeI>A&>y6V+>$9$G=aeXAHE6:ZTJ+eia!>*M&Ki*p8Fl8lKBY
VM&X&> HJ=6CZ!IRwP!hpqTDm>?bRi!lG@IeQZ<ni&&b%1tytEFu@nQR5?6?+uLqW@L1XYI9djdVI*HpjP%VBDm
d$qV&+ ^CGEm99FnMuY!k9d@Ha9EV8/pC9/nI6YL#e^96kE>NwY/kd!le5M9KGkjP?4F!9SM$Z=maM8KXIm!lcJ
VSBXB8 *CFAbcw@EJ1CiLdj^t&ah1PEh4/jGJE<SI#Pde/ehSaF*:Gu%wGM*CFeaLI+/bP$#^V=py%j:YKWpi%G
p@:TEp 4V%y%F^R:cV6hE!kS=?^JQnZ6C5b=EK16EJn*L1hlAd!ZCnA9y<FFbKMkmK%AI9\YPR^J*MibiT8uKdJ
:NFWA4 mJlh%!hILcdk5j^C1X\EM?dCNPdTkPtRE^TThHia&5<qZu&wAb=t>*MBRGV@j8S%6<H^d&cdlM#=l?!b
m?6*XS &%yIKWku<E4qc=4&ptkDu=FlP6\Sq:K*=VVNNHSYq\hMBKwuXLEP&NWt$B$b>G#S8H&k4T+LplHN$/:I
5Q*e^: e1<CC?5&jNd/kkLlL=W?yy8X^I^5/&mJ/Ll@:H6hcDVIWBut#@^A8G4AeBq8ajay^IaH*IDPQMw&?*Ym
eVH/iS WTEFu\YJ#YZ/CDayBC1q\SI=^AaMwXZq1k%$pA@@pELHQuiBAani+Jb$BB@SCAT%GwPWF:ZS5W\4kQy#
6A5<k6 TTLY9>i*@q<nTTRCbCME5j+tZ9%:E95jYbR@49Sd!8V98bd@=S#*9%jE@nYmV:ajh:B=hQdNdW\JYVk+
VbiJNA @1Ba?\@!V$FdJ\j#^:DkV@hm@ljL8>q@\9:J@895u?\@b@>p?$pq<8<KI*>d9@%EJVId/!?ku/\qbtQ:
%NC*$6 BVV#W>ZjQ^F&?ku/CipY%y<IP@$nt8pJ&SnYu\k:@TMc>NTw@WVa/TjwJ?<N?kZ$$!u&Q%F&?pj+p+u1
%FMLFX Q%F&?1?kj&Y!MVE@pT#P@k?<lu?X\9pu?hq@%PD?!M>ta@^bRT::V*kNH&jh@#jpe6+T:<nF\^KQiM8J
+&%&^: j%DDjB+QC>*>X5yHtDSYbNNlZGq:HhadX\nN4MhTmB%ZhAQERb9GS#jVBd<G+iVBy9keMcBTnb$/hZA^
pWIeCF #Ipa4HA1mnq1tG#eJ/!dldte4+A^lQT?cBMX5Y@mT?t6FZ5/Ek\4hTC8Q<GtI@XFhPBpK^RNApD9lNbL
&c\nG4 aaVeu>bFn4HeW8<#NMP\*ll#?IncGC1ebVeP4D@EkAJiYcYbHKwA\1WeG/I*?CSPABljjyMRSK+K4n>c
@<VZw$ qEc>kC<ZFmw<R1NGe:ue/pl6YdVQAbIapJq/ANEiI/\BXN1IpRJh%NL*MYeQ9VCMDScQD:?P9=m^wJlR
WjijWX wVC#bkm&<GFWnqL8A\i@YCEL8RGnLR&FVJRXdmB/!TXimW>tWEZSIPL5ZTqa/k=+cSe#>y+RVcpSnuBJ
ZQKHB> DA6JkD\pa=MC^DAETqXeK*Y#Ew*QpXTuueRZ<h+eMWWJKAl*Hb!iC>jh=%Ck5D*1X5Wldn^=MR#\Mnt+
n$N$MH ZlktY1R/FAAN#ci?/l/D=pq<KAmlb^ymp>yt1MkJ%YIan:GP\AApSFway+J>ZneMw*/W@A6?j1k=?=+*
RZaRd= LH!5@CA/Q8BuYmP?ZtkkRA%X>#qGinB!a6Imma:1/A/t1l#AWHii:mc*H\bWBmWADXiZ1F@m:IbEWmaQ
4a6EBS /hPIVFI+>XKQ<hN1L!McllH&==tatViRcJP*nWauQK+6u/L<!b!ucW1Xpe*p5V?uS?!@aCcth<:4\lDV
-AyL6S 00045c5b71800110333 Page 359 of binaries1.zip
X$h19% 6#I9@m\uw+WBXTt^T<4wAD:bmPT4>/t#HFiKB59@&8jPA6=JTS9J:IS^Lu&1P/Bj1j<:6D11Km/#EDWT
<y*i?^ y5PhB6%C41lY>RBjIcblHNPDj5B4Ft\MbB\Vm>wihP5&WEWX#DNyIYYHL?QL4X<bRYGqT6=#>uc48?!R
Eu@a^8 EBne:X1?FjJVKqY=DGn<<RG:>a/5#Y6eb8?*4FHj!Eu^8>G@cHtBNqmmTLVc&?aq9>5yYFHL&LjAy8>\
nn^wX= waBAhN#nwXPI$b5FE&y:*BqiXHN&GakLbZ>PFn?+WP^J:/@iTMuaP<$cRKlRl\+1AEFKRFHH#DjwMMMy
:5KJ>l :<ZA$l%*%WjnHwQkB\aa&BuHE1/ZqLeudGu+N9BYea@+!RZR5>ty/#HBq@TFB*DK6=44CIy4pa:%G9AL
aSmR%T IjWtep^h:h=t<?iKLEhDImF>CcjwAu&ClZAX%IlewPKNn%LJPB%H6GMlwV!*SMP/FjGV8<dKNSqDWQpp
@5Q<el GFAcXR>>/heEpTL6c5jKACP&maBLVC$$<SwnaiC\#uCw\98E+#J:j4p>Gq5@W4L1a#HkmLmV#>LjkYm^
J/AMn1 C\i!Eh5^&N+5laR8ISny8b&DG^wHCZct^m4tP*d:cPWB&1/PGy?eSC5aMLY/#MQwhIFKH%py4PjMIyKa
nw%j^n pIFl+:mR%JB8ipT8CLwXTBi%tDy%EEt9IhHFwWmN8F9qMh+4wSywj*C=iV:@t56qlMXi9DAL?utulZCN
j<eZ1^ 6kNn454Y<^dp5Kp&Yd4nHTwh^%ADwFyy$tq#Nm48t\RcQmdwe:iJVD>aTLBp%ih!^*4V^SXRmGBy+5R#
QcY>R+ RGYl?BD>5RAj4@N6#HeHLtDB/nR\WT8CXBBWHSQ1LSnTWK89u9GDmyClCajcEEya/eJbJEi/!!RXIR+#
\%MdVp h*5*ILC16a&bRy^1^^K^?u*Y$Et9Qe=PnKL4iS:W$W!RVwn6/Kq/Gkcm*wVX&NluW!*R/b<E$ItNw+yi
4$ktSh SSKVqPaGMICdVm?RpG:X^mdtZR6%BkB&WNjP$5d%&EayFepL88tTR<iwmDp@\lDhmMTPR*q$^A?LG!Ak
GaQlut ^66\1tS$*@E>\%SQ1FDHVYI@NpKHb/a@lG$uEa%t<4caS9Kiujd^6>MIA@AnBT%ARRhajSjpuBWMHX1t
?DdnYY F$uSCQZDX+q$/b6k5%T!LmSE#typlW++%JDQ96V?KFH@uLXC!WcS6KCR*+K$q56&^Fi!BcMJq+uh!V\>
Z>:lHX q$>5e@d$XcYC6qp6D!Va%npjncyTutF$^tpVYGFhqwe%9/>k?VSne?CwXA4V4pCDE#IVM:>h*qR4@cp/
CD6CjP MuR4lhpEFLhKdN+XWR*lQ64pjAl!EXHd*HlhhB=l*Gbj@RwpaR6c@59Pw*A$uk8#I^L8tiRp6&+eSB<n
cPpkeC RqB<6=Mk#9BML!d6?4Yl:HEqlAn#buicDd%\B/wR1aa9b8/ei>b!Eu88eYl8e:X:%8kHyk+F^CN^Z=W\
<q&uy5 CHy?=e<JE\R8YX6w8MX8:anyVAmn^*J5/<y/pXZB654W&i?&e<Yb^/ZSZDqFTLbLP<t^:n&E>D@dqWkh
C@CWTk IPS?/Iy8ell6D>aawK/&m4@Emi=#ejMD$1E\DHl*<*JPI$+A4QXCbb>yjB%%h61miaNTFq!l:iqib5XL
&d&A4C J=jeLXK=R!dq$&lAB6q8WdNh>ZGhaEaMlcaMWKk*t#&dDbyI1%tewePFeKQQ19=cb>LkyL/uFt8&!mbA
Vhka\6 kSuALLMSe&T91Il/8y!Z%?ywB@XiA6hk$kZMdpuT%<Q&XXVi/64lAFq*<H+8Q1+L?w9E+eGitkCVqwc8
R#Eypk w5LbBMAk@DSm94?WRPLdN=8RI:$S+u/Gt9ykqQlFDZVQqwdQQ5AuI45cwqtLM/JkVXIjPHKHHty6B%Gq
VE5EdI QweQnb!BEcCuJ/jKy9iepu?yRC>Y>^G4V>*H!i%w=^Wa&4t^lWaKt?Hit\X:dB8pCYWIJw%I<Y@nK6<D
1KR!Dw 6kVjca!eJTwLRd9W##Nt!tk*$MB#+lRcj/iue%KT=CkSK81kQAY?#<^TLpTakjEZL86>^wa?R?\Y\6uE
!bd*N* Iw1WCM<q\C<cJ$Vh6hk5JIY8DGp^Dh>y!eKAwT5FL1kMNjmGB:C*a=>#d5%PLY/!8TTW?\G*DLcY<@6u
QuquWG GW<YeaXcne?wjPC:&A5%W#N#Hp5$GG/I<V1XGqF+l&QJwS1h\8?E=k+9*YPJNLJk4Y?%LCaF/AJ9maCP
N:5Fye Z$iuND+y%>@%#>:pF&5J&:qul6%qd+EAG<Qq/kA+4#6w*H4/MZp=<JKSbcQInk6cnH5n1!D46\CW$n8K
XGN6ES ?eTn<:u<!=+m1dIk\uCwC*ApmcQ?d=q\ik:H!A6/e4Dp?QB$d<B:pq#ICmj!:nPwpt1R^?!FG$666im<
\wp*k! $6#K%+KHI<ILeXQ<B+Vp:NJK1+M:?uVMSRIHWly:\yL<6*W51bYRen*Yy1F/95utiEBLq/y>#FW*?pRE
=tJ@F8 8e!kb!En6C%l6C<Lwa<EiTudA/tY#^1!q4/%qqdLF<BwpVc/8aSwZPy15BFmplqyaSB1$4w8I&I4t4>?
ee%RCb \PlwI:JeSA?Q&HG=:T4m>RY6ElM>F#5FniDC5qtw4@neS1Vd&Eb=dSX1jElC1AlFpBY/R+9DPM$IDdAX
1hGaj8 XNql\8jRt=u5Xh/N8NSVCAdB5K>=IKRFj8$H#A>ANDE^HS5V:pD1>/kEFn5^YwqSbPBL:w5A/@B>MXSC
6p>FPW 9lYWTVTl8b4+iCJ8MY=bAKBlTPWmP&yFdidkLP:&Nt+Pm+WGyeaRyS!4Ajj?dc9RG91pK8GFkFe!L+mE
5@n+^C ?IS!NbAN41GF#auFAdW^KMR?u>^/tcQ!Z=J<ZQ%RWc$T4p%55CXenj%iPpwbud5u5DwdHXZVQJ9i#Iu\
:tZVtE qC>j!lTeL5RLcm&tbPZq\Dl>4y8tuW=NLlVBhnqjWB$awwqHDGnVc:i4c<&SV\=!t%\I=B1#H>E##q\d
$JkCA8 PD%w\/\TcnNjSAm96+ya\L$L96yd?y^/lFGlmBB^ekA^e<%<ABK^qJi8a69XuBAltQHBa4+Qpc?>Q<\J
bV%+up <Fy@HN5D1iNNwTei8WduGTa\J5bVAuL4qLFYiD<RZ8LBWp\QLlQBT?FEjKCjmXa\IIZBkbXj8E5pcGMD
F?teWZ ajW8ECP*lunEcmnK=lZV:n/!1R>>=kGtw=tn<hJA4mdqAZX!n#u^lFp/WqedqM#*VEWP^%SMQT$K?G#N
bEycNG *9MRe/uS*pI^!&&X$Vk6EjkQNTqZ@ie%?:Cl=CI/\=<WdDL6Fd\EFKY$GCI/?jkwNwR<jFGLa4eCV$bJ
\&8W+Z IHA+nP%e=D@J!6$kYSW#V+BLC<$d!Y*JpG:J=B/1Xu=Ha4^X<+jAqwjPBNk5=w8mH4XkWDSkhGPH&LL:
cu>:D@ FmjyQJMLS&NXKTkR>lPBS&@AJF:EMAWKVSkyA=Z!ti&!:Kq>R=ZSc?H4y%K^N6<<F=kq:dCA:9YVQYe%
njbw=C DK?6SR5#MmjWpA:+an$Kcb@BK1!Jc&K*uq?@DtVi6I+SYJ&TEl*\IuhFCuAX4@TI*jytkmwM%TQqK1@Q
=TiH1@ uu@jAX+l@yyZjE!j\P+#XYpB6ML:X&Ye@k1iiM4w+5bLP9BCktGjJp!FS5M^NMeRXSB^Q<INFMN<RmSB
H1DuI< k6qi!1YKq/ewRTPV$!5XcWQ5$etnkEe<Hw5aeyu$$uVTGBZ#$AlHdTQVX\W5KnkJ%JcSKpJ1RG/:tqB>
1*Z:Eb y^Kwp!8F#SmCu1qCFVTaH/BeJA>njY<uT46bj>dD6+11EVqKchij@%&R$FZtnG\CV$NIqH=++:59ERQ^
b8KARm :bYjD*>@I=*@K$al!8SRh@JIn<uwjPEc4FSIDw%kSlY9#>VX=n4GjZT^#/Gub?j4MS^:NBw&NITjEhkV
&HwtI6 L#AH4+BV=C8>9y!i&N&cPD+&#t#eFJ5YZq1w$iimQI&yK*aYGj<!K<%NF$kJ6VT!4ZXDA5a&nk+FL/MW
Lm9\@@ PE4Ie1DB/5S6jT%!$mHW9\cC=hMPknC*C=ZjWDWVZ<*i8uS%VFbRjGtMCnSJ1DJnDy8%\X@eHli8d:KC
h+=\Da I!K$PkJ8BJLJHyqRVWJdL4=CV*$qHQnKb@SXn!WQlm:9^t8#1RMc@$FiFSn$BknihTR?Tu&?iLHN<a?C
aM?5em GBl=%lXI=!@X#$tRc!qRMKkyIM>RwtapMKE#ck8EYF%XSLj$nSKmLJ5NkI+CHSl5^Cp<ky/9MZDn9+9R
8e><GR h9m%mLGlY?#G1K1n5Gpn?Xa!?*mnuGh9dmcK#VE=NdDVHHZAkF6nQ+@I1E/&PXCn:iBDwJTL5jk$kpXD
uD%pP> :me&IRIwitd&aT<l^4dNNWSmnk/TQniS8:h?wlk@u8FP^XmIu=bT1Ji</>SMm$JGiR?Rh+Cl6K*QDdTI
Lh=eN$ &Wqc@J19Pay8J$Ieh@JPDt%nT%YAV%ZECA4e+SBpY9\Tj$!meW5DmZ#anj^cL%QiD&8JQ9NMCqLpN9^$
l*KC@! &I@!T/MWe8cAcbGWm@LyY9+:@:kie*y+T^h%9<VQpEaK!!L=:=tlAm&TJa5AZ$%8uwpu6aepdY\ZTNw$
X1qKTt =nN@Y>u/65//uXHDBC*C:dCL1FYnK!@<&auG&u+cDWt/^EFXwMN8DW!XAZtcTq#%qTADqK5S=DHcuqGA
!8Pw:P 1CRG=C\1Jp/?Hc#!y#b+BLDN>Tnp#D/>Xd8Q^W*=4^pB+VEwbHClauV#KG<&*::NaWQ!&XbpM*YbkjHF
i6PkD5 Zw&@9H5H^!AJMFFJ?An<b8W@:Q<!IbN8bM+KqVQKYEQEPh6j6npGT$tI\^c+L>dJY8ycL1<tJcYSMH%H
#dXpTT S^D*$c4YV\KEE%J4#1HBQlMH:mb#TY:IVp&nYy#SWA/FMmA$\C/EbPSH&IYMQw5IGuCC5WA5*?>#PPKF
mM/Ddq H*GZVjZDWylRtJ*aEQw8bJ<Wn6F=6C?EM%diR#+lIXPpiBImbZJXT5bybTap&qbMIdLl#@\8/FkpSN@a
IQ9/bR Wn\#eCL#5qth9T%pA@w4W!&@!:kP%t!IiRX:4I$m6F&R?njd^kqtNa$VibX\!iW+J9>uP?TMRywm@t8B
^:?:&E Nc*9HMQ#qYSnDpZ#9p+t$n=VXh%GZ6$M!/MwQI4&%FBpX#Rwk:LRE1aweypwQqL=MyDDQMWkF^&pZwhM
$CNYq? P<14tH!9lQqMYSB:PG^Ii!F#n*#nI$=^RPDaS*A!iXb:MhmaD^cTGldbh=E6qSePSmH#N+m6/iBj%Fn6
Q><&Lh QmK^mEMC1L\5=y+Ve$El1y%+^/&>F\Ij!a8a5CLtXIpVEp/t6!%A9D/Y!B+Qm%uNkM^q$8@a91FTEyyp
GaRGhw +NTWbYe%4FK$cKya*S6nR+5^t<WPJP6#Iwabid$lV4Sl#qZp&dSlMZ9lSItw*TD#A1LGtG!^XDT/qqGI
X@eTGc R!VK8q=q6kphnYj648Eh11tXNDNTcGQ#TFNF&?5ApuCnp6T1uh#JyI^!l:bumP/mM>t:mnqXN:=#q!6A
XL9D%S ta$miuhE&:Skwq^Gj+bQJN\nJt@Ck9K+cb&piPqlZH1b$M\QMLw*GLL/p&u>ZBlqSF8u%GIR*ikJS^C4
8@W#%h 1^lT!BmtKJ$$GbtIu*wQ#@:jR%*/5@j9@<XZ/8#@Iw5y&&<TRZ@@ty5NCQ\95bm!MdL@QZuyH?@>@9^G
9TXq6q <Tic/c#59$^i?lQN>J?ku*y>@SQN>J?ku*y%@lQN>J?ku/Ll@Iqt?p@RV>F\@pR#@S@SLE@SeQ=EM@$j
#d/Lhk $W^5V%C<eLD>C9wy?TpP>q>BM#=B5<LB<R9wJ%?<5#H?!tSnA4I<kRd?Y&nR9+Z?qeu&qHIYG!Q#9+Xt
T8>@pV ?cYJ#9+Et9YZJ9yVcLb@c>S?!t*##*@/L*LdMDMS54A!EVK#5^K!@L:X<e?=dhka@<^6\<4?C&Tt:H>D
SekAwW b54G^Q!Qi!h5\H?B&+cJ<cjeN8!M@!K*DRj\@!!*Vi*@V:q6hu=\&:V@aK4S@<FWR@WAaN//R<9#HEb1
-Aup%V 00097d0757f00110333 Page 360 of binaries1.zip
ki8qC9 9\&Y9T4+C/PN>RNkR<J#qKNh!F#*6N9&AWC5iG@?P+<Nu8eXi5cbnP$E48y6=iIDaCD8AbDm?B9jVeDK
>\XdnN 9XDB:XVR$p:#c<dERJu/GAXqR=F\NEp8TB$y6EJ1%@E9u6MXu45/W=+dLk?Ac8+XlR<QkKJ*$w<>Yd<j
YhinDm PHPZ?H/jh<B&L^y=R#J/RdN!uXm:epZA8^@J?^9FVX?Y4YGltdMeRq#$ik!YipNwPL>KR?lX1=%Smyw+
i*6qca DuS$RXT8q/SCLe>LFjcXy%l6W5>6:+4PH\CZ9De5jbKttI&m1cKX=!QSjd*aVCn!5=^i%4P%t?5?FJQb
#?9/A# wkRB<acpX6Tq=!LHLQIRq!=48p@!=qC>9uBCVlFJG?4A%L8AJQD##N/<@%5&uEb$MibtVR9iuM!%%#il
\wE#GJ PTn=eaZuyAk/QPhqIFt&:>Yiyb+/uu@Dd%M4MW$SFk&ES<CqDiuZd?hQ*bN*EZ@<E#aiS>1iK>kkHa:w
=4A!lC d8$/SDW^n!lQtDeSZF&#%=^GRu8J^S#dS%mbNPET?u^QNkHqiqwH*ZPkmZe4ncF^p/elj^njAZ56apN5
+nq#9P <<X9=DcXEK/tQ<l6SDSE>bS<iu\H*V^ewM?p&CL^tES:IclW%lb=Z+!j+19b#/?18hXbktjulkpAw\Y=
G>Q1l+ yVlaIHBB/c&m\*YMI8>#?9N>w5R$RCFia45>>1aY5?&d/*YWyP?MaTHRYFyRe=<Jy:Ac<4$D$<JX1ldl
RIadGV %+:#XaH+Flp<hJ=/t*FJh6<w\X&hy#V<?qRT*+S>1haCAC\XKc/6YCnHu6?y&nqGeIGqyQ1YDMQ*QN9?
$M*lKw BW\A*P?w*@l65m^6h^4K45uZiGW!u9P\:9Yq5\^CdcAAw@46!b4W1hS/VDJQ>*b#L9Xpm:RiADN>/@jR
9:hCPY K@iFyk>VKi:@L/Y*?h@heXBdu8MDRBW9<lLQ<#4L9@1#q49C:QiMc>u6p8AQEmlH:I96%I1S8qa^@<Gm
#@pc>J +BF!^:8R$4aT?e*$B?uD6%9QGld*>yj:w:1&@VhM1w5u>!M#@:YD9D<aHZ=<\D$pEZHI>ahMJ/#KQFbY
wC:@FE pIG<w#K@njWeCH+A:CdaVmbpDLLhBtZeF=p<eh#\!#ShRb!Ah$<aAuY4k/ledSqmWE+dQQM?XZVS:#YZ
QbB^B1 qu?88iV+T?u%*@NA&L9u*Jh+>5lA6#KFT9yc$NmSPMJm*LnJ91!Vu?6H!JH&EQP?IApPhuWp4FV5wTC5
R?eZ4w Gl?H=pKdh19Bh89li\CIN/k5JtJ!!?^4BqGK:eIwVmF=EecwbSnK:ulVQAAm+nP8a#*:pyn1SjKi1C^:
<Qy<S/ ^medkK??QjFbVZMq&b$$HTM6kNiIM*By@HW=*AMA1iLt<kGRMbF/!>y?6H:9KjJwX@bjj1q:AHm?QL5G
>RTFSL yR+Zbyi>k8I4YuR\k=H=!9BHK>9nV\?A>5m4P=#&d59:i>/9=<b5mjLCG1:\*w4%G?QI:<h$L/$>X@y9
djNp=J :<NY@u1^^PHCIS#VnRI:phZIqy>eTuT+EBdcFY5d^iQGPwJAi<&mJ54#+!L9\?T?b!di*cMNS6qJQaj\
dK&kK? dH<AkN$^iZnbju?$y4#=68NI>\?AY=n#4n6FCW&lCGhQ?W+mejD5D?@ihLW6+Q&eb+l\ly498N<<eX^n
NC8K+p =%lV%y1ZMSw8YV<$%b:/I*/M/\MAh^^D&@<=8uw@4EGM=lT?jKtTYFeKpWwl?WH#!TH5MRV>Y/6!+kR&
QDFp+9 H#&!#\KL&cXT&THnWM*+%G@eQ>L1$P!=qEN>^b66@J\Gt1Y\a?@=mKhNwAZqtnKdGwL+MLZ#ZKNaB?/D
pmA:DE WhMt1RG\D:aDZ<FaSj<mXwN=1iX%S:6/CNhm!aBH%hAYk>n%dPZAWA?nPcVQF:!%LYp5Z+!ad^^NpnR/
j\e1X8 \b<qa1KJ?*liC18V5NEJ:nBSqd#+TFiWk4i>&9^e91#LH%MNC\wNt1CMC46q9ei%Lw>Gjk/4bWdl!8Sb
/mKp89 &cl^tQA^Z\kMb4J!$QXH8TuwV^ttELKPTMPpNZVDw<>ww/ZGI<^WM1ubY=D/@KdSyh?WM!?J&BD5y?c@
uKaBJG *\mRP\Bui\d9L$jnhDB>JDFdX$=%WiL$FV%9TmMGZqMT96pcP<n^yRbtkZ^@^E*KFCwhYBm@=5iT4Ln8
Ru:iy6 =:pFkeY>*qDq\eXY4Jq:>bj$p@eIPLmYSm*IZTHl/Eq!XcWBqB:XtJdCBj+wGtpK$lKV1?#NIeeBJ9a:
^jL8P? w8l!6WWMB/MWN@5MK?8XwBV1V*Y%e49E&VJR5=<:*k4nlCRA#q>TY$8==Rkp^e^iS>Ht!V/DuS<\*u==
:SMMnA Fjp=+&E/w<ceXq9w?ZL5<Rcm!9+DAH/paJ%lbZc*I%1/Sc=jh9d%AWii&WFF&lCctFPAq\kT?!V@de?S
w&d1BR %56:86yH>+Yt@SL:$VKWR$\:FdK\?>q*MyPlWI>kRJ!8H9t@4&d=PVWJnQPb1DZZakFHA18b9&5nbGEi
FK#EJd pwXhXab8ZLKiYw/KSnEHeiB:Vtd>B8u9Bj:A:9Q9HJTG&VY8VwVR?BmSC&We5?>9LiQ6tp5RdKRWhA\#
@w@QVF 5tZlFSnhJSkE*lI596p*X^*l=?EkNulYCVn:&4R6Pu<N@PlaCn#QDqjlP$EhK?9JId/P##=bGL\4u8J>
nw$+J$ tEqV9#P*n6IBuB&N?pIh88^nSNbI4Edwu8ni<6+8yCdi1n+AWB+A4CcdD\DMB$D*A&A$8et#%@Q+AZBt
bEZL<K a9Qj&5##$VLn6/?%Z*yi%dA^ZFde9:!*Gl&?y*pABD+AWyp<CD=:=n>y^cdjELwN9C#>RSLE?ilSMj^B
b\!I1m $/Q:k$>w:\EA&j/D&tj8H5:#B/>R^T*/A$B4S9j4d?^&n!ab<@iQ^i%n:eiTQ:l?*9<k!@8ZL9ijZ?PH
^WcVw1 %j@#HX?&d%liQ#XjSQ>aLj:\/c!Ya$b\YWtlXV/LK%Dt:k<LMDc9VT=@Y6bMJt@/A5<eKSqMI+\j1RyS
eY6SPh @@#8nRVC<F##jHWWlRP@#m9&kdhKnSDlH95=lidek4S#aYWTnAp/G^hRuZl$d\+CjGZCalAVTbcYH6%D
^e5NIQ q1<Qp+qBHmYFt1RPR<QEp1NG$W68*FR%5i5B4=:5KJctbKDe#p5!QjlKRl<WATTH?#!u?&9iAN5mde?&
AaQDZ+ !C?y8/1/S#tZJ6j^e#jd>#l6Q#9=/FJ6Q\AWtl<A:m?:H#&I>lZS+$j99iL:^P&nh:F*h?/J8QLV5<BB
=d6!4m W+e!^YeKj4mKnRWSTmtYpunCyDID1!XF+H=wAn!#T1//8Xpp@9HCalk9bDd8!l<Z6wqV#:cMi!nQ4hIX
b&+$XX ?eT:d\<Al<ey1ac%J^66/4QnT^uEGhXl?#HTt*j+l=*+N4D$e=KLT1/:lC6<:kpGlqTlYmEJhl@aHF*^
$Bb4F1 Zi@Gut1t&N=PtQS8@i@4md4V:+ul<5XMaqlw<:SXp&pG?Yutu<*S8?81miYbEc4netIH??lSaG^<WWI*
Zu$=F@ yJyc1!D=E6yd9G64^:FkX?*cWCcPpC*C\>u*dI&&B&4J!qK\b@&Ilc8TnFZqqFFIXeZMCDK1St!u%+8<
M6peu$ LcZ<<!IEp1Ym=GJlPS$8JZHwVEBW!^pyWIt?+y5@Xyde:etyJYhmL%qd?1VtCS&?H:5JhT9<6SH$!\@G
PRiDRy iQinc14$hCa*i\LLqm1Mm4Hc6Ayie1=%?m<iVX##6ELhC5cHGRbMeqdY\%5$daSi+ltjWbI<dIn&*JIG
%hBFQc =+<QM*6ui^1J#DHLI$G?lVEe^HE%SBXWcHQ/k6LJ:meFY6Pn*hEGi^dXA5XTCp#XIF<TbB/<<ctG6qhP
S*/=j& :9LKbb6%XQa++PJ*dDHAt<wXa!1NynZ&DI@=+DtuDCumuj+>YGQ$1Bn5n@p>qBIVkaVWuQheCLW#V5>I
AK4c4: EG=$5LcyG>B!T!ehtCPm@A*cnW6PCFbGI>J9qPPNPN$d1ElA>84!Wa!1cqM**T@qS+6SdP*DIw=G$l+A
^W$cD< :\!^?aEcIkM>*aPWM?a^keGG+?jdRQb!:tF:5l^^1@1JM>6T5J%Gtkb$T\yCT59nI=*G54#D%8@A*neG
8wiW1u \el>=1klZu%<XKwpNyVTCE+<<+/yeK*>>&jC>\*HA*NYj/Zn?dN9AbX8qltku1>Z%iP@WYE5J<=<lWmn
^tRpZ\ ?j+F/ZY#F=w5:BD/kEA^5ADe4BnjWH@/6YY\RRBnd>+NX+yePuE8<IZ#!Qh4PdmhHDEn8SQ9AahCW84L
yE*I\h 1nW?mMd<?c8K%&yKNa*MNMwK9aXD?G!+e?Ha68HQt$$4TKZTDCI!S>Ttwq/Hi%j\1#>*e>W&S>emc%bP
hJFGWi F#FTXP\4tuP>t?jhhW=H?C&/bDP=jq@k<%6aP44RXtC?&u:5iib5Y@VJliH&=i*nmntZhme#%iu=GKq8
k&Jm@i :c<w%l:4Z9Ji6dBNH*A@9$i=6^t>+JKF?w&tNdZG@X>9>^KD5X6Z19l$:<S*c59?4y46TjKkT8:w*IqY
:YF9*l BjneEPX?CS>KX$PTil?ma<InBR9^#dqwm%lh6&FL1<lhW5y!Vpa==Jpn&hQIqjkZbc*<R9dWjnh+:8u9
ACS=HJ 8VtN<dkMmiIKi5#MFj5!wTy\V<1kcGTT96a%SE6kh<AEFh>TjCE5\#EVlq&p=qInJw1GIdS+WV!1RCqL
jS4L?# Z4RV?5Mk@$i+@YmynT^?!1Y^<Bkh+%%Gu=J/qC+?AJk<P%@8yZy8&X/T*Duc*w+?Lm1i=haQkPV&%emL
#%LcHm $ja#6q8$?/cGi=QHFaN*:nGcGqp=F4*iY4qK9ah>ZG#?5\6<jDTmiE?$WaSV%=!$GMCIS>\HI%S%wQEK
L?WLl# T!u&GapC5JF?yAS+D4TcNW+HRdy4Bh#\:1Dd<t8*9@tTaDw>QS=1=#!@JL+$:6q</>CVW5TMAMbD$Ny?
lLP+/> IR9TY1FdW9qPGXJhWtt&/W^aRJAX:=pK<$\u9?pyF5>Hc@4*WhDMNp:XmZ9bNnY&daM!CXyLnYYJ?pEw
6ZM8Mj >jXE1%5VXRELnY+66^*+Y?iX1T<$b^5np+Bh#NB+\?pcqM4&85Y9mjh+%Y8FCFAc>ujHlZ6Djmt*!m9Z
h91=Ti Z#K!X#b?Y*a:EqEqL@dW#iCJl*C<wj$dFYy==mtinwiAtcVP&E:=?jH&ia8jS^DE4NeVDI1ZJPPljAm+
>pt%M1 Nhe?ii$@Y44b@aBFj4XbqYkBV61R*pL+K9mCAkeSE5LVjVGn/CH11Je^:FT/Nd9ItDLKq&<XQqVyCk+@
SPIaGX ANSbha4h#VB%BcP&JJEFR!=+pY>i>&56dNiujjD$!%VSu@bcKuS?RSptY<ti$y*bP6ul%>IBq%SeydR?
DTJ6RJ %L4EkPwBWYj@$VbVbI8DVDkKQw/8ES@ZJtPZ!11^:DXHEnHdES#CVp4J>Pq<D1DnFtt^Zu5$QhRM@?Q^
5yN4^d Mj\ab%T=G9VP%K4lKjbC&Vui&^\jp:ZVT1H=?I$b/4!8iMmyLA=ycK>E/JtM:=*S<DaiXMJ!KuE4IQ/5
Z#e+pY X<%LSiT5lIDMG1WKVn5=#j&n1Z#tkpRlPAhnk4C$^4aNN+4Rb@WhL^1P#9w%?VP%B:eZJTwaIY5JJ+ZZ
j?5#=K bdVG9ac@Bew@tw6>N4u6BC@tpAQX<<8?9HpCe:SLJXYVcH5!V>wYVQEt8iwE5MabQ5MV?\LQA11X+TE>
B*XVWK 6NQWQTmBJG<LcE<lLt5h:98Z/b^LX<=jy&A*nYL>mi&WH\B9bXkkQiQahlyQ8q?PJ:\e<Llh!cLqnd1:
^Gc?\d XC@h?VadShJXc&L^#M@>:<*Gj@kyjCE?*CKkdwZtYl</F5Q/?LIEpy*p*IWe/98CjJn8\Z/T+P^1DF/=
1VCuRy iu%5iM#eKB<wiN>n=#Wi>^?iY@4\P/:VEE5#BC&jcwh$HRX@HWK&:ucwuj6qK5#NJTJ*L1:Z4=G^lBPW
q>8b*F >ZSL*Kml*FkQ*YVa#6P?T#Jee/PjR8MkcMtM<MBElt9pEnC^4YlbT699mh8@!EWVy^YAAR/5j:iA>+jM
-Ai5wJ 000bce4b1bf00110333 Page 361 of binaries1.zip
jHZ5n/ InFeyF&TGXDSyHtLE%e!NDt<C+4BDj9C#:\GPMb:QWJQ:><@i%?CM55ij@HBHGL/:QIK15#VbZp?N:HB
c%XbDd wcT$Q11>5C*%iiQ:n\VwwlIjQE%Mi1S1+wB*M5mpy+TTlFD>w86h<T?y*^qDS:@F4QcY4G/yH1YPGcDM
Y51dF? L<:yiN&jjQnK>L%X&cVw6wL+<*AqEaEJVp!Mqi&i*h6Qk9w&/mN?5?1eEyL5N/?GujdP>j#dQ$SGS<^m
I&*^8i 9AF\B*MQ>juFmM8^&YniEaBH+QyQIJNY%mX4JSmumB6lt1LHulVh%eF5E$D\QlyL/*ep:aZZ$6:e/tb9
^tIwnh :ZQ8&kQ>iik96!@keqaXJT1SeBDD\CBB+\ELuD+$eR%uJFnT>B$P/<4+nVMwbM^jJH^ZwB<A\W+bX!d%
LDWu\* n!6I:L*=/D*b4Pht!8I>58^XAX4VVEWh=Qulq^DG@GIDE@K&Y/?Py$P^N#C#%kWNTB&niKLDnnJ<bYc\
nHMCQZ J!hhP<#aFGadnjHyT5+t48AT%c=8aLGy<HJ!$?q6HQbte6&&&@$$NFFbiYCY^\QXM>IIKDY*$$hTCpla
*qRkWK p*Bl8:1ywCa=M?@^C?Hq>&J:++>S%tTecKaRQQNbVhL/8XKbcIewPK@LyBQpiWEh5F>Rmj>F/Say$c!e
@LJ$iX El6b6KEAD\HGJ&C:FyylZ1eldW%Pm#m:QJq5>*EIM5$m#B<Y<+h%@<%?@n*>cAJuAlPaSCCMA@RK/6Fb
Qe:Q:+ #^*=A+DmS+lmK>+??F9kEVe\BMce6e$QW#CMq<4:cIVSVyLj>k$N1&me/lSLMP:Nl^n?FTR9kcp\kJBC
4I6kq5 TX>HCn/Nh\u8<I?Zm?>ik^9pRBZV5hTAB#jZ6W@ead9m@SHM8E4j!@+YE!*Hi5d?Fm*llyDKDR\M8aKc
/nM*Ei w?5@S*BN&y:?Fl9><RL&\^@Z>9^BI@RHmC**h^M??9TFTS\/&cdy4P>aL>1FqpS*y6c?>u%&tiy4Iw6Z
CS+Vj\ H^$^Y*4SDYpLMYDdH9CMQNl#F<=@Q^y%Ka\uK=+XAKbCcX+uNuwNjWpc^MIlC^Tt=ceSWTq:G*/Q/%by
8L1++% P<PRPbpC1=*j4AkMH6^/\^IbL*dRwAW>1*E:S%Aa%a&JEdVAmT6jL&KL:N>!w^@@wY:cVmRY?m$tu*MY
i5A*J+ %?$&nV?ciePbe9Rh>y%pn==&hF#4/Wt$uJZ4uN5QR1E5*TbXdSG?wdj&TL$!HYDjS1GSE=b6NV1tEk6w
w%%^dP eHA#J?9Q!GRi%@5PQan5ZSD/1P5^d69EkBcBH5ADBD?bV9E%=D*8>#u^kC#CNWFtJ!ke:\*u#iya:dcI
M?T6\6 yP*c9cBqtnj^n+Mt&mnT6CqTGwtDF&NtQ4WbXB=ctBm?Nj$mYIEi9kFhb5MPZkDA?6L$anQj*#W9%ALE
$tEMJp T<EkIM$yS#+J$X@t1Vc5nZZNkeZ9hkmbLT8h=I<\1l+u9#iP!1F1&\/=M>G1a9@wc*pdKF%<D5ct?R>T
th?1=J weja1X@nD%Il=Jud#T%Lc=*D=htlMWt^<I%<p#eM?Fk^w*mDIK4N?&$8d+pw#lS>n=!9n%:KQK%CZu:G
LANn^% G<nC/89bW:FP=VRluPtw/c%PT\qXm>XG6<>dX@Sp*1Zu<*ee8R*w#BYhu*kX<4Bb1NTTdN5n6Ny5#1#p
C1j%Yq +FIYyWn:h+N/1l%ac1?9C#GLVGV>FN94L/?+b:cTQkpdVb4nRY&R^@5?w@S*5T>:1%RhpTh5@?!4LBP5
\cIltk kmN!EwuLb8KdJEdWBtkpuM54q\k8I>6:XhdHWE>qV:hN>11E:dde&9K?dLdhLiNM^jNlQQRBMLR%&:::
GM#@%= &jL:+/QA<8mp^a?Yie+$#^*F*q9<+AhKjZV@Ty\1Xml8b%Kj9yL6qhcu8V9NMw<4*5eI>LTy48K/RiQ8
JVMn>8 %HNW9Z*V$XL*\1d8=5eiVa*uj<jNHq*WQ*Xd9!DSE>Vc8jXKB+q+iY\I^%Rh^!l&b8$X=ThFHV1h+Bm\
HlP=y? 4bikbKuZW!=$yR&SqBj#%ILWHc9?FHacLZyMY?=PF+^=Xt?:4a#Xm>l!>bKFNpQ8t4%l?*ejAK59J%X=
A+>!iH hc+jALM<DST<w8iBiSeb<qjZQBthPt=F@T5Il:!d/1+\i:1=HlY:BDwXP\REFTRcy+8J%Dh#1NPit+4Z
jWc*Ih /?eNe#^X$t%%F@h8d>q8945/XE\FQj=Tc68aP<M>@EaKFMY>tT<>hkWMC?5T:\^$V!EjAG54%?/QVRlq
J@HK9i :?piAAXLK@@5&MiH!ejIIa4mAaD%AJk/6L$C>#!^9iQb?6><#QNlCt:#/Ey=JT@#AaDmdun?u9V<FWQb
hFcR6M cWH?e5Hm+4=D8hnneeR:G+dmP>P=<=iV=^>$iAKL$*c/X\6K?ue/96/!ZL9aZZ?ee!jb<*\*%8K1i>^Y
B!eG?> IF6R:@q#:1K@bFD>td9wl!D1@*AZ@Y@uLkyq*kkAp\#F<m<eh<D#S^+\Yk5/TK&ecM\CnLD%/k5&+NWn
p/R9VP Cbbn\B>kY$!^l&$QEwc96=mTbjPQ?PD&h9Kyp:GCDhnVFS&5i?A$$cP?y@IH#%V+>1yDad\PYGJuCF$i
Jq5N^d t\KNX:#VcIXdDnhMlqlE4bH!uGw*BA*N9>QLBLeHk@8X5NBI/SRl1#hkC>TWFYR*n>k6Nn<SaKMak+1M
N\DpW* <p#ymHZE!G?c1?#G:Ah6EbKIDGW%Z\j@RJen%$e1MbM\cHEM^q#GWwE<FGlt\^im<4VGJBlR+CYtek$!
FHj@lR NFc:Ed/CJtMcy=RcPC\C#E:pyFuC9A/LlXG4GLYqN/weVTwhK=LcNkj#GIn&t+N!LTibb@cN#nhKY$6k
S#l:lB \uZa$/#d@I:VIIlR6+FE8?&yyS^*4VFICQj4iW*Y#&9#TNb<lw4L*!<N%kb5/KupGm+FBi$d%PkljCK!
5V1uMR yNtTN5Jy$:Gt>AE:d!NeTJVaN6u9VYcM^8n^MW^1q$P?nCcRGkyAE+*GEaMRqBPS=IpC/y=X#>Ca#DCj
l$nCYC lJq^cin#hW6NGXL!MVbe#RLapZM\iZGbV@LP5Q9L<JSa\5yG%VCky4TN!/HQCG$!wXZM#Aa65Z#Ky$tB
aF:Q&J tSuS:Dqi\+*4+i@bjHjLTkJ>R6DG*8Ii+/Q:E1@t\K/!&=!cnLyb9XNbYIAG=qFJd*=ARVAccA=n/bPu
WjuEG# 99AjtQmGITkEnjMmjhm?NX6kHdH&:kD:Y*Sw4FSjC4jFmV+JW*i$b9l6w66uHFT=#%B6&!MHjdTdXLlI
\Vhe@< Vbkm$*y6Y+kak?@iHF8<y!1Ewe@1cP69SqNHq^R@Sy^KWW!=pjc>iChK6e>np8R\8intYMq9#V6QC+5*
t%D4Ve D?SkWCjHXSN\ENVpaaGhSG+t/&pap$LTGq=cjPZ:?qDq:I4XdH\pJWwPP+&tm*yuH=?!6&$>#Xhh95\P
%5&\!S t?X4iww8!R%Zyleq6cHFbZbN1yEe$nqIMPRG8eRDCqW<Nm$u=C6PCjad9c^S4upayIXhBTN#IC:jtWS>
KAhJ%R Rui/y%pjYHFeAm\+$>5A5@FF+i@R&/N!hncwE:SFb8jdlQmYEuI!@B#hRk&Li%AIZquh=NQ+YX:!8XAh
+&?KjR w/<T5yM\CRT%%YZynLBuP?BJaW&SK#yZBSYXSIuWKKGK5DHIVQ$CbwG\FH!#CySWepaE<4BRaHaanZKF
Rw455+ 8FEkP#4@Jq6jPT$pA!w9#WQtJkklNPCcHtP<CdW1FXtQ8Tc6MdNIjEwPX61mh!WhCdL?4PlbDiVEWFd/
aatYRn eal4n8y?<R!*tmeMPb&AtWYuYI!Y1aY=A&qqX<H1JN@:phdhALLDKCSKq>leRn^$kJE@QJk1MF!6u8N=
/8A*5J p9SITp!5bZA4H/Wyh*n^4yHe<Yd1Fi\>J8JInupnCa%+j6dHHTYGn/k^EK<b1HY5%wZEZHBym*VE$/MH
Cmqkcu NYS:L@JmB\4uh+@%qhS^tciT^4$F5R^:^AMatw96LeE@t%yh^Jh@A/1w4H&QRwmwu%YiLH4ijGl\kF9J
E$JQRM ZEjdaAuBw/q5$eT=ijlBYWMI/S6S>ql5nAq@uFQ^#FB%dV&l9X1<6Skm=uI^lq5e?wCDBVIB$YlR8FlK
IMCLtp mT4wtaeK!&^dd8L%CuP^*Jkpy+uXe<&T>@uFwZTZ$HkREqitFZh%=AEcTVKaQR*peRhFqbPjZ1T><4I\
S9wl@A cY!8=B8\n5Nk#64cT4GMmBpIJjBqAG8aZQi\X@<pBHXWHM!A$G^A>&FTjK=&VET\?IcYyCTkdEl#TdAN
*W$SVW RWEn9X$9<\X+Ew#b^9qeWkX1d?P%SBZ8WwHRGT$P^4Em$#lV1E4BRJ/GMe\#@lcNIpBud%%DEqJWc$YG
=cGA4/ a%Y1+Dele^8IdWQw\j5W9<R*#^9N*?VZC$uCHJ5ml&RlBT!55Kclqw/L&=AkW*y#n+kHFSDl>R!<=Sa/
6nKXT@ L6CdN*6nA4\94a^T?G/IctlTmWTWq4k/mJbh4pR$SXD8HPDR@TJK$W4/$!#b$PKbjGikTVh*e1\TuuT>
jL@neh uq/yJXbZdueC58Jld/uenMpB?4EY>&te#Xj!V!Hm:BkibHWX4LbDX?SNKyMFCYHptJ#8A65FnTAq!m$P
j6R!du j=nY?WS@hEYVJ8Z1dhiaqiLnh=$J+dL>LLBTc<uMFXZyHSh5yZFjC5SNdtjpcwwJuIZ4naimt+68\S<I
b\nEtH ^y1hPMQJ4TwXLH!=qlXdDC*=BhtQ>m>/+IlTTd\!C?EL!CViluLGqTEa+8<9FJjM4GP#Jn?9ZZ@GG@%^
$@VVBS M=5lH&QTEq/>bJTuS*t*CZGPL5I=GH&9uKYqC/8w51#8wGHljPCRCM>eZ#/Ic@dV1m$a8C^4jF%+XX*#
^Z?kC* lM4Bi+:>wR@qB&BcDYN%pihHd#c^E%6QJGLiA#NIaBmZ:=SX9AQypH^IQ/BNqtFFKKVJ>B?eJijRIL?X
dPe@PD RnSaA^uGVy@lXCJdq1e&=GRi!F!u:u%tTD:j#ypF4Xn6+Z!6QW+dee!M!dI&h<\/n85/W88ZHh=B!GQZ
GK&6Hd w4b/ykL\6C%k=Kb@>\^Lq4ewupNeH8=1#DFe4$dL$a@=\:e^E1M\9:/5c6aE61+Z8JIdbjuXX/cHTYd9
1<welK #LeukqD69tG1jwC!eIn>:p*Y=#5t48$kth:4MK8!wyy<c+D$+eDulIdim6*%<Gw@ADT#l!dk=u!e^nYp
4jhFnB $uQ#!h:&L6*:JN/cdqT*#kcBPPHGB9L#/phWLa=ne4J!PZ1+WpR+nN#HKGm/=QWlCRR^ED!A4p8Ql<<l
8*WmJE J>MM?llhLZ<WAAG+:$WuFcmq*uV?uV+uy^\TEIT$%pMED9=#>?^@QZ@PV^l#tBkJj<@k@K?t>:MBtj:V
RyDT6< >H+&yy?q>#P^@YN/Q^Q4j!&>u+uyV?u>9/it@nuyFjmQteh@/jm9eN8\AXq?Ae*C#9EEt9XZ$E<p/LMB
M+MY/6 &Z+B#j!E/C+dpQ%Z$K^Q>b#nX>CkJ:KiRa!@ktb<Ck*<BVRV?%Nw$C?kkc^Qwbq?Aj%$in@wX!ddW<\+
+hP8VB dCCYj\9N?t?lj&Y!AhqAV/Db@!$$^:@Ve/bjtY\5HK^QwH>q5nEDu?k=$/>MNmcPy>BMQ!5P?PeD>/9F
n!jAIA Ai!EVM!QK\DH++LA\9E4^RFM#H<1D9mnH@?5PPC9ZE1@FRi\M9/pPICJ=X<wDkD?6^aH5HI\5@=QeeD@
@=%A?+ FAj<V*HA@^RH@E>^\Q>*mkMeVj?1ijS:G5u5H%@@JN*=X:ZJEtjtc+\HRI@*1P1>=/ZTD&Pm@ABI9eh<
^eVjp/ uLe@$pA>9#+A@B<6E+98D#*cH*dwH>9N@K!S:X<dbV#h!QMjGt*>ySH9n+VR@^Lm4+%?CPdiRX\<pZI$
TJKD%y H@E+Mk<VGW#b1C><EuaWJY/45q*EnhHyFA>C\88S4mMWqnyP^hEd9&J!XElAa<J+NGac&%b*VJWl8iJ/
9PMWQV I4a8@GW$H^@eH?Mc9$nm<IVcycMiqbMt6ldJ\N6$$!AX<8mae8eZnYu8=Vut4qwck:9aq&eANBuq4JW:
-ASZAt 00014ebb6dc00110333 Page 362 of binaries1.zip
wJ%YI$ SY?YwFJ!^4!NmIll/1=u$YX<bRLl&\LSS^pQW>#/YeZC#IqIN*Zl&QEpmcSwhMK5t^$GQ5PC/pLWl^!m
Fca+&M uXVDpjpqi%GqWD#D$:jH$9WFPb><ISWQJaFdKNViI?EhbSki&ITY8P>Ia&ld@WRm\K9$#Q4*J#?k6i%d
d4/aDN :KuRFp5!t8n=<CB1S8hBh*?\Q>u>>k\VdZk+!cFYbRi:^QpkiLVejAL5=qPN\&16>YW/nK9LYw#FLNAi
Qq$&qe lRl^I4nL*<CF+Abm%XG/XI*@d6?jH%:R*5LNcmC:Np>eMLp8@JW^cuId1#\l+Jp!6!^hwARn/Vi<d?!S
&e^q8p q+Hm<Q8ttYEPn4*%iLbVK!?9HcZ^*$wwykdNyXVQBG*i<DpQ8%6Km!c\ynu/6BX:>aenIbt>1utaV8<u
&ZHI<5 q5cX^CpY!+w:L!VPKihq6j4<hHa\DBc4j1k46dmJw:^8<ICJ>e&MCA?iycWVHKR+4qh&WKbXh8lWl&F8
%*$%%t AI:=d9aHMIkwcG>@&JZ?b>j9$>jHI>j\bV6c9KWnq46@yIMQG=5#RThkPL@AL1^awJ1:W!Glw4ZK+R8&
dJF!:n ^baj<k*m6V%\iuG#QqyZycIId??AEEEnIC4k9J#W4Y?pX6WRpX>*CZ&^y>*RH&4y^J%Am1SkkcFTXpQ\
IE5e>& @taVRXJ+9R?&@=q!NtZYnu^D9icmJkjbF^FT8RR=C=1l%Mm6FY^cYt>T#j=t&P>!wkBJ?\J@6VT=^R:N
#PK9t< =GAE^Wl/+6w<Kq&pE>:ClaRNQSq@<^+F9$BiFJu5JuF>w#kceGV!HL$*bY>6X%ca9&Gy$uT=wE*QGeAe
NL\F:b KLTZRFIZF!1DKR5D<AA\?u<^EMdPV?Z^X8H@LpV*D#W/PDZPA>NQkidj%<&<Z$lkN:t:JR46&qYKm5HY
b5IjPe !8JmX<q#ta*ZtM!Bu>MNauIh!PKn?G/nqp:t9VAJuHn46IRtMY*R4XYb$$C?GqVNJQemNhCa>GAZiV+5
Y!/Nc& *Yl1dpyy++mE?yld#pi5WG<jqpd:qt8!5dd=e^1S8t@Whup6IHd\4Zhjc@Pd9FiutZP%P=8MJZF/^VMi
J\ntn\ JAeSE4CdetI9?4>pQE#E9RT1u\cGXEcIGL>^\Ml:Nk&hWW9J>cL1bP<d1LuQS/KGGH\I\?QEl?w!/C=H
l&L=1u >tWP*eZhK&\GekPne%qWFC#\kwRdSM84WNpIZ8W4Q+T^ZE1MDeWmC^8S=XeNjcJdNA1HMTLd!4uK/!JR
6/j=D@ l8HGJT<ca@D&X#PtYD*XA!bL!h>nCTu&EDBIKD*V8ejP&LplIA6!ld^kZZPt5I/QnL^KM#@DT1qK^ptT
eHIH\V q$<Y\\<51y=YScy!y:iWh*J4YK5W^ECPp*PyeVhQm#&5BL!/j$9TMFY:tPSZBCeuTcYTJ$mCae^e8PCN
iynRw! l$<<p^t^jJIhbM<HBR*?R^pYy?XyT!nB=jLF+iRMe<Qq#CGn%ebYmK:H\Zy5IidVMkli1EVcH*C5jCjG
+8an8m 5??bu?b:k8>Fnb5/Ql=>mhlG5\yKab<9Mwa5*^Zd1hKhq6EGLCh4aZkMQAAiu>TyDGd:^l^KR6VFmF$L
#9YItj qAty^?bM>4yk1TGZKN>PR$np1u%E%nK6SBSF<RA+aAAj%pMp$jYI6VaIBqTkXI$+LZ%e5wE/TRK99G#&
e@h\XN JAnZRjj:#y/9\R^Lw/Fch4P@9C5a+NHM<+DWD?uXJF>*d8Zl#Ln+61$k!VC^i9/#lQVHPbqZXhW$Nh1%
4ZjHY$ qNtmVlbiBqFp9!M^+WD#4RFl8MCNlHN$yY8+RE\^I+eEc+p>P=$I<+1BSPJk^i4Nn8a!^X&@tK/*5j!a
cdFX^< Z$ABkVS&@k#ZA\A6LFV>R>\Ae54&^AYm4wMwaZb$i5:&>?HctR4/<qjp%Yd84QKkGDZ@&Q$G+T\<ZBjX
QWQQ+M :ti?16QD4ay1#/q:ycIDqVYIB$WR5ijY<ti?qXNiy?hTEc9XpEqWu>lbbNZDBFK#hRucFSlG*6E+GEbQ
Z^nma@ Dt+aR@XaK68RmSdW\MiM!l>IQe#E*mh>MFiB1w#lkFYXt<q^I@y5&RQkK+V?aK@8yJqWn9Y!WEJB@BX:
QPEtq% *9+m8nTq^F*/A+B:>ny9a&Dp?uW$w>>\d@ANj$nR:4Mm<Qd8b:nq&RVlBX^W$Sn&G?\qlAd>KjAV>a5:
4yYBMR ?dcVe&PF#&YnNaRN^DheWFp*&FY*>:=E*qG++\NQK&QWQ*$t%@PPe\%I!!/l::F=e&Ym4ZDl<\Bw*Hpi
WLE>Xt #ehQwZhd:NG@Q*X!+Q$ApN^hqL+G!iDDMdwJZ<GBR\#:<+!h:\ZW^\:dXVNZJ5GLDSVQqFB8*<FwwcY!
V&>mLd &m\<tTyPppyJ:T5H=YciYQ>wm1^@LMX@a=4?dMl+@$=TFZ@?SuM\y4iWu1=Vu:T$\cPAuH1!N4yIIVPE
WC>Hi> BGy9pYR\W&Km%y1+w*S#kbl?!IPA&p\CXXTu\NP/W6E<5R\S/BEh4eETJW:51$yQYZB\$L>#DS#jtc5C
q>XJPp q<plDXPG/c8VG%Cc>jdPke!BQ%IMyw>&+=p6wHHDb+PyaL!6h#&@hJVM$SwTjTWkpHwchLw&a#C69@5/
&yL=Xc K=@#w*lVuhtX:mC6jV\^K!R!hb:LZX6!YY%JaYJcR>lW4W+5?+c=eqaPF^a9J4cL4aR1&l%c5Y4W>BK$
Z>#F4M /Wc<A#mBt$9MdVE%b$bBQl%$54869VZFZLyb6M5T4Z<pCHwEllmtjbn*d^P^u#VcQ&SJec4MDuIVQ8=N
kBBE68 SI$:GG&&j^IFXm+=G=QAG<#TpR1@^SJ:JTntF&S^w:1KMQVB?YVpinVMBm$$bHw8iL9%C4*h#B+a=d!+
>R6EN% Gbt1MqZY\TTDmwtPqPyEEWV5&+@j@N+*pI1#Mn!bIJ/bGmhT%5m&BV8qL&ZDL\$IyVTlh4lc@i%aMZm+
8mt^:S jGimVQtVTkE>dJltPEj5ChnEG@bT%:d*%IpSHlLFl&I1N=VW@RXY6hMHL&h!GM>DAwyVa94>\TNDY88J
iVbLpc +&?BSPW:bP1>A>TbCh!/iy#*H/%$pAVG6lRS$S&mSau#%KY=QRlbX<w>@<kWjB\P:ci!aWX@yAJmD/mI
aI8QGj wYXHtL?CN9Zpc\IGSIiFCYTeJ1WlIeeZhQk\N\mW/HD*k#kA&PAZZFN8u65*!N\<JTnI\yjZqnJCeuXW
i*6M&Z 5<pBGaa>DDQbSHIm%CEiAI9u>yM6/!qDw*Pltn%D=uL!ayj<CI8XHAJ>A/@4k%:j?i>VenuDWP=<k//4
MIJW:@ <=5GYPKic*96LNLP1&P<9t:XN%ISZe5TX<ZRj*Rc<YpQ\LF:Y>%RqFh4q><Z*a9hXKHq:ukSZ8eKES@n
$ypKuw S:$M@LKu$/:u%K5\NM5XYWbKZYN*j8W6G>l>*H9&H\HCQ@GijlTiwT*NT?hJ>TqLm!Q8/8F:I?BHBJ*#
BX5\P= WGc%ySFGuniZGcI+VA1Sk/5C@W^W1b=*KZ4\RjN/>cd5:lJZTX6VFE@R^ETTWLe<S>EAF5yqn8Md1cyK
=ttky\ Xa9TKn\ZKS:EmaMPFnN\cXHJ5+ByI&%wL8GptNcYC5dLatBAHZN^M$*5:n>k*Ah1cyd5SbclqDSL9wBE
S!cw^q diFWnhL?JElWRTDTnnIMGm=6PeETFlCLHyA/EEl:!%X\BPZ=5b#!1?w=pe8BPSMMp<kWLk&EECd/XQ=q
B9\ycG YK\q5K9mktpAkP?c%$d8\cXkMSXe=lq\tct69!ZCYC&Eilw=5=A/SiF<kaC!DIDmiuEcj%EP<V:/kkep
m\HS1q q9yqRSVA//+>/q:q#t1=%ilTRR!$D<bHq8yI+EW6iwPyc^mR@FeDyGwXQ9##IG5$!W5a69CXmPjD?Q5:
$XWJQ1 ubY:$*SiI?jSm*ii*+e<P!K8&5y5:/>pWcw=Vc+@6N@5eH5M:KZ8#n+An8IiAN+9#6\%jmBiG9&V5^uH
bLi=yh JQY&Ja5QkDdF55j#EYLbpVi%TkjHZ4\19Q>SmeH&XBRIypN:bG/Z5AGZ\wd&wlNb/aV\XPeTaqen6bD1
lXdqZa 6d+G:?ETqpW%FKc6@CkE51=F!<YRy49BEkQPB+h<HtXMtNWw*1=J1kLmkkND$1tLjL88c?>SW8XCMJj/
#XY8nJ \jQ9i><SH!dnpZlXwFt9:!TwjiBVYFDIC!5PZqha>e6MZ+E#lAPm$E:e6L#l?>&LGtVmKlRD:PFIk6FC
:KbwQF Y1m>^n1Li=AGe=Ad:&XZM^\>S><&<j4<TF=n&h1+l@9Phn8ZGu6J5dS!ytQ#Z##@>hEE+Gh$@5k<T#q#
IQb5?S <IT<Td&*HB&<jZbwi%ZBSuE5&>T?%d4$^*uQ>M?k9*>RDI5MGVEK:h+RYy<kQ//15u>P*hZmIW/LneKp
+p$^ie GdWWZI:@N9!VnN:ydWlWMYI@K$hD>RpA9aDQpFe5@&CR<p6^>ww@J@k/NL4^e%AR\!GMY9L#ThMek9+^
QGIPpA /Vn%>\/5!\8F+PDk!I1wK4A8X9Z@a&d\Z:PHQ@=jpXNeNX!k&=iIT61c#&kj<MbnT%!hk$*D1/6JPtjZ
E@%4l4 We9hRHQYD:W8lGInHn^eS56</8JL@IjTTu=<tj5eam<nA?4?jtj&q\y%$=5j!PhTikaJpdPL!!%:=^$%
*tTKI+ 9B5MM*+pFihjieY@d6!&pKQcB8D#M$N@EPeXRYn*Yj*WBR@Wj%XqHYtiR:4K>D<J^j?VWQ\@CeZ@p%D<
?Nj>4= *=NR#MV/n\uFVM^5\Q>Zm/dka<>d5YAkCyMR<ZW@n/GQl=Q#wS*AlE!h<bb@K?hq^Sa*RKwk#t!nTkeq
ihGicV E<EalJdLn^WtW696ui5lTBI#&AQ?&a&\uJBNhh$JcDhkCiZ4W>V/id=jk^A*uMNZHLFcG=b!lGqKakQi
hZNM5# EVbdhne>GnBmVaD:5c<:iHZe$cDRwXD?<I%AiYpAT6hjqFQP@1KeRlSpkIFIp#LQJpB#P5<WV8KI^iRH
!@tLYq 4uHeJ>DJh+wS5GhFmkGJYu!QkhSN!FedwP<qS%W8V:tDDWJ4%KkZJQt4eww<:A@qqPIDqIE1LScaMH98
X:d$k! 8Aat&9ujqFQGJ9/muBKEJ+bj%@tHep16BG\S&Pm+tN\Hn5:jqXQwKGS1CQAqGRE&=jA?^G%qJI:8!NlF
e<KL:A ^^InqI#&%IeDTCT%%I&mW4plneIucwuTQR1w^nmCREJ=bNl85juBKVp#P\!wEV!1=$M%I>XuFI1R+PX<
Db5QGQ ^VQRcZLnyICwCWYFDl^==6etVZ&CknA\+Z6JJlnIi?>%kyEV:DT?A?Nh?ICX\+yE<51utAZEAWBcF85y
VQI>Tq MCmXPlGX5M!tumwqI$+p&lj4=5IJd9L9hE8WCH1l1tmmQjWk4HhR6aGC=QWcNBeFJGXKY\Ram1#9/&D$
SQSSp: p^kXNV4my@c@NHjG\6GP%:L4G@A=:e=YqYd^nd1XQ*e^XQ&MJq^eB$y\JATX:^C9Q?<B68FqtNt#b*cK
pj6tJ: /jNqwmKna&JnGABy*e&*YhPw/@ZXMPSApak9<6pS1!Q<Z\mXPPNqC:5!T^d*+1T5iE*4C&I$H+V1ud$X
ITQSd@ cwA%L8Y9V<<1AmXu!uGy!QqT9C5DWk/lIluTm4V#Z\@Ih\6K?ZFE%wn^FYKceCXahH=FjKEQZRp8N64c
tdkPHm w?t%X/l5/hW><8WVLX:DTbZADh+d4w*EhQ%wpi>LEc&p<wWu*G^wSYFeIwEDpc?Y=EjWE!@=J/BiSQ4P
KR+Ln# cnSnu6ay*>nJ=#4=\9L:RDQuj!ZyhiA&#4RuaVD@1yK&njq^W:\8yQTP\\@nM/IQJu$y%YTcpF^4YI/C
!9$cc? +WCbR8I/aaGp948FHTEG!!S#EMaGl1m$FDM%LEb*6J1XAb$$bjEqbB?BBJJFBBpTCcEc9Gb*6+Z%qT*R
\1Y@=E lhRa\68eH6+H9etb$klmkNB5=B!nYQn!W*\KV8B^&iy#J%&w>#E9k&^$$JL=qtAJ>#uF:VAccVB:8yMl
FPXcH@ L6X/#RXAp>WYQ6qD<FbCnj!tK&n!jE+MqRibuhm%LjGkK/G5Ww#eSLYJiDe4aYRlWCC5Q%dCc/=Itd5I
-APhH> 000a0c32d8e00110333 Page 363 of binaries1.zip
EcRK!F hya:+tXNDXG=k\EP!6*N/bA:iqkHj1I<>m6jWMpdXG^&GFmj+BE=aNBwQy%w%\LCmtTh5P*4itANcqE1
ePCcwE e=&N:R!NCFtA18!Xu9FJZqL4X6VGi<NyEIy+YyQy>4e$bniHeKT#X#CNc!be6akXhNLe=5mh86lWy1j9
CbqcSG WWe#l#=9Sq8=TZik91JA^JuVhIJE/l#tHB\j$&V!ekHdaPeXw@Z>6JV$&6=yYkVtkCEKBJ=E?iIBT/?I
F>WKQD ZMWBSc#!%dM8CuB+>DBhka1A$IyaK6l^X>u*>HYiuJip9q<G/E\*e\jIeG^$\*L&SYTp9nLq+G=&/%pJ
M!KAGi p?YyF6hRmc<blTPKE/HKC\umF*=+b6PH%Myjq!Z<&bnQdFktm4R&YJIKF<%u4@ZDl^SuBGZZL^yPuJm%
R&t<QH qHRA<\%K!&uZMEF+JAb6TEM&TW!h^GbeiGw<VH8?RhWA>56?SKBVIF*?&%!u%uwLmZ\L?GT:ah^AYVQ1
AV8Sjn K#1u8qkF#kiliBCJwj@!$Ie4yZaNhB:DpN+w4E!6nMqBD:ZX<X6cnKY$q/iPDHw#ZBS?=it^Z&y4X&j+
JMGZHH MCASK^cpDG*Q\QVSa6=4V&Rn<S@k\9lVM/kWIV\HTl/phm4lluqDDS4/D?ApI?THkB8eX8VLQNM1qKi%
=4S^+= mw=1qd#ALEHj$b!yc&JcHj1<PPPKTA>XumTX#aRF?S*+<qLS$Ep?6KayESK:F$&=XAN%\mp:#BeZDX45
e*P#@h $/C!WH4ydPlBqhlu#NWe:AL\BHS6/bC<V46qQD9l\WD4McW1T+pel4Imw>L*i1DCaaHP1p6%/WH$G6MZ
ZANP#? ?JllXT%5=Y#a\%WKlE#H%jcnGEbK%LX4mLY^WMW1&84wIcSyWww^/IJmeF$c^S>acwapjH\R*wNX8/Z$
McyP1i qB^CGGqY+=m?t4MB$e5dtiaZ=b:ND9wQ\<wyIwG4juN4R%q8ZHFYG+1#BG19nkaJFDQ=Leq:/H^:^<4&
>5eLh\ DaJEu9&%AchG:/cwy!:&ZtBlcA=ciS@\=d\pRl+6t\LZSWEiN9!TcG?Sii?tTZAZV/W>%DX+=e^eQm+N
+VV\Ym ZmcKe6mt@%Xq>j5Mltd:<l$pVRMYSq5>4%Gan!!Z9aRjhG%cMDkbpX+TuBAT#8LShZIM4YbQT>>SjTJ:
/PDeNj CDTKN$X>F&5t?*=^Q<+w89M>EI1/dSB4CFT:n:CRtVZ=jGb8?C%#W%\<LW=+5lSy*YjnTGDTk>6^@H*5
PCWWeD H5FhhSB98EZhZlhE65TZ%=HB/tZF8dR*W9!*&e?je/jkLRp/4Y9eDtuRqSnkwp5pS4k&bmLN1%ilaBe=
</ZEea ?n=LjqZm+FIA@+ch8F5<qL^+Q+N#y/Y#&CCAwT<FSJ:jM1XCdbQmJ&pK6985BNKbe:l9TYq*ud<>T!?C
AbA^cj ?XMtS!#wBVM1a\uNQEID/</A#Nh9Xtk/il?YRn:&X>m&jaiuK59%GLcK>JW#TV?Rq/qLtq$4&R6TpZF/
9bYKA! A^$QuMyq%K96\tWWpY^LVNRt$CKQXi\E+*/eSK@KRH&y5>5X^5hHHC%FnaVLTt=N!bK+tynwqIlY%nlE
tJKQq9 muB=E\p%t1GbnYkWJlGe8GqpeW8eKtVDFah>Kh<4jb#e&+P/Mhcm9mEBMi@J@ZiX4X&@t/Wp8R?Z/qby
#cF%C! 8>+Aeqd8n+\L=5<IbYjQeQCZ#B1yQD#N@ey*RaaBWVdR1>cm?MIWbt<G\>JEjXL:/N<PkTNKwd:6h>Qe
TJInM1 ^*>D5jYGK8+?pCCDM1uHbm5CdltKH8A!#mMaGJAGE%IMueCjR*k4k&n\Niw4+akHnJiHHBGpmIP4LIbE
6AB?@$ >$CdMDc9AVVF=mSu>&9wTH#JuGNyat+PT#ji:GJPM6hZ\$F6l^=R<ARJ=MVi1%9$$9YRkCF>EV>EM1W1
*X&8uL e\M^KR?djE164:RiR6p&bbATkj8TCB6TpK&We8iEi4b\A1#Rwe$eieH\1GHT8al>S>TiyRDc49H+5JnW
6qQHHm 6hYl4\SC1!FnWtqnwSnIKPt>qyXVbF4Dw1>DSRaBSTwtapyB6DZw\jmYHeM\XA\\Qq<\S9c6^T!eS$y6
?ce=Z% VFMmX45R^^$T1ceXw%X5VAqMVhlH1Rb8e!B>n5$?qa%<DSSALn*DCt8NN8i$5WwTJ5@Nq8=SGkqBS6^D
MNp@QJ #D8uy#$hywPMy/qEHITM?cwPqj$Fcw@eKbw>b4</&6+L8ZRZEXl9iRJTG6pXyyIa1#4A6*h84mwNqVwN
<I^Tk* :V5iPiG?&?Mbq^8lC#thHP@SM4:>ck*4!XnNB\Y4L5acFBpTIwR:8#MWW9KS%E?qSJB\F^uTRGdNBVal
Qya>/R hb5>Aw49jRY5X<h<aCRT!Zclj=DNaLGN*:cQ*/+CQZ4I19Sc=KqIIWnPXw\!IKnibd9Yd=5uSG<KWLYM
%R=HtE FFN+*K?tBJ6yL#t8G?JEGT$Y!4hAjiwLLVF6wVhF&9Ebq4kN?1D\FGH:XFKn:!MDG9Wl==ALn=jelj<1
NjWKNm FQVAS!1W=:Rh=5C+M5JMX:S1k>X8R54VYKA*ahqqLM*5*N48ADYqEdnQKWtnY8k=*>=qqq%T?h+PR!=B
?@bXju 4$KW%6aYwlW:I*Se&VB:?N11&L+HQcSjuuZl=GaB51MbZWG=$yVJd1Fjh>jGLjZTdWBc&WeFeWc=bSLw
E!L4H/ mB+Xy&l/u*&NBbwEk<M>>n&?:$M&1?Y&:H%dZWh?8$k/&d5k8yD:G/ai^Yn/WwSTt<4^:LPSZEehi?H<
VbB/TY RmNJikmiQyJA?8\H?8$?a\hYYwCJtu>e%yFi$wa*MqDQk<Ieyq@KXYc*munc^5?IeTI6Q@<Lw^&SRGAL
#:/#HD >>iP%k$J6!kC$#Z!55F:ASnEh!KbZWJG/bR4Ay8e!ccPkK?P&Q$I*HcEkq/NWGny$kJ?9B$a/kC6p&=<
&lZt#I TnpA*=VIcX/MCbpC+4FP/EaII<D1DcGGCAV^G^I/ytlpVnL\$!l\QwMSBC?FATa>I>RAXjB!nm+R>N+J
i4YYPm :>+&1at$qFI!A#WPY1aedN@YLKV:m/>m>Q$E$L&4weP<InWJq6&RG4anG=8*>B8^YKl9ljV/ELNJkRK4
eeEi\T 5+A8p>=95idP^*DkNmbhSkA4$1/Wl*\yGHI=NZK6$>$n$R8IX?8WC@t%IlCwJWEEiaTtKwX6&ldqwiin
n%$<9> amTe4D/&a4=y$Jqc6KKVyLukW5ySWtTVJJkyZN$GSBAtVB8D/wR&$H:j1MPKNAS/%T=mZyYh$wILIByN
aYT/\$ @1lFKC9<Wa8\*9FWLRIV&@?SYkRk+i<Jw@@qYkRt>y@ZInk?jyM$N@ySM<DC<le5mIQ6Q/RBBG&hdQ=I
bL:HTi LbW&NnLZ@$9y\a@i5kJBlG\ewH@MqPZ+V&@%%?SbEN99Q^#E^94Hph@%ipH5nH>SPRCB&H>9\<:M<95H
\a#&!i %6<4JED5HL@DPECMj?+$+><WY9#^t@/?1<!M@&KFB86QBBlakd?1M@^HJ9CjS+:=J<uYj$!M@:\Yk^u$
9cmwnK K&nYJ/wytJq?Ae*C>NT>tZ<B#j^WHRk#!/?ku/wDaYd>BVVVW^WN#G!@kAc^5D&Bb9?*$B!@kAc!QaFt
>?H$wy aj\F>NP%GC!@NNqau!mjaRH>Y?ljtt^QKFT\5VD@Y?ljtY^MV>Xm5Q#KbGNqik4>K=Q6S*HC#>H59#Sh
iaQupV u4w*^:?DbtZ<e@uD:>l@Y9:\l^#Cd?WQ:E\@5eC5Q?FeaGF/@I@?l*Ql@^DuRkkPC?^@K?eCdmiNA&Nc
\R5cI> bWpZZ\e$=dEYVl=SMSClt@Fa4\+++k@*4H1RTT/1#!hymBWKtGP%FtajG4IXRNT6^#$AD!9H&Tw6^\eK
b\l@^q L$6Xa1\>!TQCXdK?pbV\#\wNqjPHGFnhtywSp=iy4Z9>&GhB*\c%J91#dpZY8k6>hR+bGmiyikkYe^$w
Vu6*%W VEyDiWYM<Ru5RL1TRD$weF1DGa&bX$:K>SBi*dwK?u#c#JDk\/c+G9GRBl8NnkaGihBbQX@W@Ej$HNul
&mJ<Dh jWk\LZ6klWTiC?/u$tlHkEpqeDJ@CYXuc@kTGlPM!IDb9Cm8Q#*:4XK@>DLeQ!5BS\?p^5#m6*qyl+GB
h?:W\K +B&VnlHm1+TIN<a&d?$^lwF1K&A<4/aj$AMpqR+MKiM#6tukV+%Zt^d\e+#dFjDTLdARMI5l*^tq/%Y4
hC?dkN S$?w^NB<S&Jh#QKPpI@n\Lu%jaG+>T8D6aadEmG5tZk/R:IcLlQ1GRY<D=<LSJ9\F>t?X5S<+T?+b6VQ
5L4uwQ Kp6&>p<TuJ>N^IACF^8%4SMei^@cEujJH%F96V1Emq#@VwL=mNbReF\LGC4BPR^!b=Gbpu*G$VHw#tX1
Ah?@uj <+&JWqFcq+NWtQ6LhLye!cwcBX$AmCMk4G<C5*^H8>+%c9jLJy*KHNp/pTmENKK$KN^JQYajT!&HwcTV
*W8wa\ Ai9LnJX9:tQT\CJuZEequMqQI&+IZmPy\wTt?DT54QBP*>?jKiT9/k@1DD8D6bHI^T\iA?&R+%9+M8hl
Bb8aqm Caep*WNjFjEc^q!N\kM6#PZjyjbmYT!D1u!m&Gikw?b9CCT5+d&KBDpCC:QtZjSXwiP6&w#C+LHWi#XN
=w5$!^ ElDVqD>XbGNV1l<Sn4TRBh^>#6SH4lItyINNSjP&XAml*yFwwACjVlVajm$SBC4Nw+%KEKkQwctn/KAM
1wSNH4 1Z8SK^>5/VLS4YRRV8^hw!n@!kaj+:Y%ajE4qhB/$6\iM*#McY5wIPw$49IKhA#%NbnekY>$HZ^R%DHd
X/8Z\! P<SZLPDVCjYD%FI&p1?8<:16\mG!S1ZwFp!ACdqtGT/E<WlmI!p=4=MptD/@C%*nTe5%i#M>QbA$Rc#P
FXya=& nRXpjJ>ym^^#cJ#LepL#^XeB$XH>kPedCT$?dp9ClQkuVw1X=$1ZXD/^HlbyP@Ge=P5iFnKV^6Ih!*mG
ip^:R6 I>Py1B6?+wN<F*AaGWI^d@hLAEdFPY/%:KZCcntmp/ZT%P?lFW=/SGG:mZIRi:R\^I6wPdbiLFa!5TnK
?>!Ad? aQuAm&QL:QY#\yFmFSWLYKRPH+pjuB!!Pw<k^p&kY=tNe#N96kk?G/C$K\FF!J9pL5uuEjmQ=LWKjDIy
#GA\ZH kWk%q\$=YGK:>w5PX=bXQi<ppZ?YWE:=ZlMKk@8p@$^j&cmu6AlDH/SCnRFQcF?dEYNDRJTQdTmQIGJ/
F>\tnM cDZMTYuMPL8*<p/@W+\1d#bZ%?y=JS^tZFiHRj?ai46I*JlTMi66k:I\hYW>8cJcI*VMS\^mDw6Pt^Ru
X$aYFt FqI1ybkELC4VVyGSG1^Q=%W!XXhhNLRY6L*=^Th!:GwT!nbqJF8KYAu^XHPDBuSqcZHjmIt+PWCuBce?
>nCV9% tT!dI<pW%d8aweXJXHR!u=4NFpeFtN@ApC>@u9>C4h\XI*/5EFkPI<^>JHqeQ/1^SKLTwInawt9qaHC5
F1JD/R KM\aV991<wP>%\\Bib+^8qcmp8\qB9PW^P%EXwF11jnCct?9uw\PdJIVGZdL>?tEBGHHnDGJueyeMj@D
/%nt@c D=mqcMEh8SKI+ZmTS:dVL+1teR*8W#a&<5?d&ccbR4/aa$1KJX%m\Lly&F8iF*p+?cG1TCkKYlt5q4p5
:w$q*? p>J!&u&LD%WwSP?1t?L<bID:&4h$>FBy?BNh@P+5u<@$X@!Ny1@!q5E#8Se!DWMDNBkqPnReZ<pV/?hY
b1KwBj puFnNI$=lGcMh1cWjjPJ!^5pZpLAmZ\q!^%M1p%?&+=\9L6FD>%ZSa#%lXDiAutu*iBNRJX?!RmPmt9y
C*K>Ze 6NL5#DTPp#<?ZDH!YIF$m&D%pNRcS!#8MlSLnhJeKuTne+p#wC!e?yMCibIY66pmQXTC\?5bD&hqmFhj
6N=Yjt eClKpDR:%SVl#$R$I9&IE*Iu%JJ*GTWLL=njJ8Rj#Ct\c/CJTQ5dFi/F#S5!KR9Fy>y*&9ydNPJdSch@
wMWl$e i^G$&Fbjj5ZekZN>V+qa&P54w1GA*=%1E4bA!=Vk9C:SDtjGID@E1D$\5heNE+S5Z%WP+bFHYc+!DJ$R
-ALCwX 0002067876a00110333 Page 364 of binaries1.zip
X&cChI RA>qD$XPcYNDJ=Gc*G<P4Xi995T&?yu/6THhSntLZ&ciQDV%4bMkBXM=*w*ZWT<SPei:\Fkb^4/EdYd^
LQ*l@# ySSaB!&uui%%51b=!\XIMHLB>&eqMVbjeqcyc/BB5Qy\K?J=P+eq<A4t<lp5Ph<<QnT4jT6T5t*I!y+Q
qq5hu+ Pq=?\%ul4Kh4$4SV%*:lbV8d:l@yK5Xd?&1w/=B^LX*JSd/hHbwGuCZ@nea5Q#WMi:GqjHm&&Iap6K9d
</9QE\ uay1aMnb@a6R@AJjS$9a%+nAiJ99VmYLTeQZltH9F5%ES:iR*jY>W:?y<+/caZinBB!QlTcJq?TkLNep
@8YIqy /$YcmK6iDu94Y#qETdKG5XHSH<6\\&6E8#599pE!MSP%YwqYPhZe#<LBEl=XbTYtL!w&5EDyG#61C+QP
II*QEM Xi%%$\nKdm?\addtRaa1XIqCn=R8X^Zh+5\eRT^J$aA9>ldHY8&Q?\L6>eWEt&aI*GGM&ETG*PTRX4wn
u$Gk5@ #DTm&HSe\E\pCClmhWPPDd*qamJIC&@iqRkHPPwKa?%NplDW<aPd=lBPRnd*/IBDkStQW8<YWa+It<#p
Rq5iT$ E>@6llWM+jy1=JWVky^HCG*M4AmlDNGQBh9#BYy>k^G=Ahym*?!\dZ*n65JZ#*GEB^KKQWtPXVq\*yui
b$tww& nVZ$p/Ka#ZE+bV!XHQPAXH#B6mieu!iJFKe%yI&wu%i@TCEjZ&l?dpARwZ@ijnaKq4+I1l=M6pM?55Bl
#kcyMe B\#hJG9?dRe$hj<PC8!RGZhRd8K&DLM\1cG9l&aJyT=kFNPmZD%c:@ZlDaJShXmyuuN9<YTXZn+XydN5
VDd^AX IA:maWmP$l6w<9RDeX!I>P\VF^ZWJC*pDM!A?heTYe?n#XlMiJ>VIENHYMHdF^aCQi#F4!hMm#AmiKDl
aZ$wk4 \Y@C^Z\bp?\G4HE&w:JCQtZ=K!GS$d\pT*L99@TPkqjjCX1JkR/D5*CtduW@SWKDW!nPVZ#$lKhnWCMR
Yp!h=5 Y184!j8AmF<*5:jJ=\n>GWmF>^Yp^dT@S5GHS#thaq#&:!<db^E:pDN9HTQ8H!Il*eHDPZS/jTc^:pjK
TFBmI= 6wuhCwi8jJ%5Hye5ZwqwuuLb+!XFddA%tC5bbuDw!+e55kKVa<IB!k<cKXiEt>R5cp^F*B<p#/MtVZmD
:Sc:Bi 4Hh96q66*bNW6L5h&ykBL^bQ>c*Vu>ybJn&!d?N>+PRd\\RukJt+SS%/WiQaLy</ikd%%$<bptmWXtIV
&6SQaa PiLIRnGpjpq&jcjFF4YFye=yIe=R<K:G%B/qI$FIc!1qR*HcY\1eXW69nT?@mCka&:#AEDE\y!e%1XR!
pWDSN> qXPH/y4juVJaN+ua<!Z5Kd4jG>?AyWKk<$%K*@auFQi:Jy^HwV*5MJqqpY:N:5%WGa>AD1l*Z>%ZP!lD
Q/HCZQ IDXRqF!&1ldTNPHJy$w4SBATm%%A1+!ppMJGKyNLElQ4<BZp?d1D/IiEiPbBBJ=PRk=NKDjH&k5b&^hV
cVLiP1 9m?uj>nu8BPK9KySTd%XXR9LiMJ*1wSG\Glqh4K4j!ylucQnXRa9N8IySEj=XaHQR$HIPedE\q1nH@t%
q<ne%R M!\ah4?jZei<:#=&cE/M>=VYT6Tl?#EddT!JEQCE1D9$yiN8Fack<Lt8WJCCMWkyQ<d\beAtMaVQ&H1d
4#VbwK Bm!u8*W9Siq*Ectl<FM<5yNICV6Qq6184=a$LEjqE^Pd:J6M!BJmNWnwVtn#a#8ptqXB&XMnXhDEaZ^D
ypb=Gu EWXdqTh&@9u%d\^::wW:5SSBN9L>YD8wKTmc<5c6wZ\:L/\AB5Ew5lZbWTjN\$nce4=^1hLmCmM^$i9M
jdd98= X&Tl!9an4!@IqGIC=IVRKH5lN\^yb/$!4R$q8K^e4M:4G\M?\mwn6$P6$PX%5J?VJ^t!?>Kte>c>^V=l
IMX1mD 6/PSFJZhppc:#dL^Ra4N4B#ihi>tS/LEb86N*=w<#%M8bCw\PGC\%EKubAwyX1Q*!RyyQeF$^#&!FGc\
%&Y\>$ $H\h+#Ft=V$5yDk#yh&:Q!L<muhKd%%P/E9=T>bDI1lu4>h1ZPmi8jELd4IVy/^H#V5!e%EYXPeFdIkl
N&THj/ <MQ8Wib5c*BbMl1AQIu<^4*YLb!kt1H!$t%!lBwQH^$#>wl1LK%u?<!G$&*%Jt/#F1\FY#=BjyAI9paT
>a&wLj j1&GMWnFB8q/>bCAFu*pIn=CVPlc=QZ^V>CaF96RMMkCC>\FZ*VLIh54LDZIGJumQ+9E$XmmEP5=Ynpw
8AHu#+ ac!9*TFLJdSGK9VqJtTP#8eX4!+HHPkNVRqVGFuVEBdQStWL^6nqMbhB=@a=Y@uE58GClJCKB:=TMR=%
DRj:B6 F?i9T>4NZuCy<wy5b5=eJK#$8?cdyLPmbFu^dVw1Mtu&GmlKDTw*wLHRwbwQpJH!dVwa/69ShcY@\j>1
K1!P?4 ctVDlFl9$eHBl9t5iB8E8pIbY11@y/6cFibX4qa\%PNyVV5pcbJWli$i<k/SYmKyRB>=kFn^t^\4aACJ
pYG%9R eA\JmP&Q+TSj^kZt>SEqKI\%G8ib^bBaNA\h6iR:NQlAbKM1%ZbhiGc:IE/&@9tanZhp$&wijt:HkjQ?
l!*S#n #+@e68&qJ%dN94WRPNp#WZh4XaS:pZE4%CN&HpLy#8$bYYX?pq/4W5=YN=VWy6BaXR:&9in:/DT1ebEw
XR5NN\ !t#LuQhKJ<TjE:NA<<BeT\aTcX:/6X?*N8ETanV+tST&lCKW#6CI?KbR*SGwpBKB?F!clM!BW+@Q6^Ji
TTDW:I p5ZENiG4nBK8a$T&ypZE&DejP<ypWyE=w:/F<F+LL*adLRRhF4Xy=wElD41w4h=E#&Ak\nCqenJ+GI!6
FXN4&I GS*nmn>np:Yjp%Qnqp4wt&J1KZ5t>VjHT84\+wEQ:u+VEZEP&VXFMaa!uwjG5T=>E/Mn/?5+!C18uWjT
<@/nXQ <JTK#$jLL=K^p*K>SA8t!JR<6HCeI!CDpFbuw>c68y^PP\Q6ck<1Ruj<#hhhIBHD$u4i$Z@%TJD?69AS
mRPN$a qtqd:^nbmbycNE#hM/pmQE&>N9H$Nl#Pd=BMTM\5:hN1X:+^5@bZw:GNcR$+8eNa4i6=iqqt#t!:nZ\L
Le$D=e lWqJ^1:Rj5!IVHd5iZaIc$RY>qlwpPiSkM$+GG\yN9T/mGc8l4miik1eQMQ5N@Q?L?nR^G<KI:Q$=Gdj
HY8IMj BPSyEHD+pPXclJ%&T:mVNi@5CTu!jTJY^N4F=X#PZEa&N</k!jLbSVcBwA5FkVT\qFElt#kl?A8:W<d<
JGFAdn 9Iyh\ynE/XlYhiB>9mKB^^l%YBqDK$F:tYJMw$F8!JkESImk19CAG>AbbJNuu$NCY<paAml!dk&/WTpN
lFS%lG q5klNpQZ#Hl/!M4B^YVYL!u/$?tNICt#I+\*<PH=I59$+8n$bk#J9FQAwct<WmAB>RnbTal^pCRm+KRT
b9*1>e =NA6pIKEF6DbMTV9BC9==wpA?dRCA#!5qQdNG#I6J6pG1:\tX1TjPnLJ\GX!Pa%j4+E/KnkpPiGq#cVY
5FD5h# hjaDniA/Iw!p!58hT\\YlWV$LI^SnRXNI5MKK5LYcS*uB6wK&1M89$ep$!JiaY*&VET8^*p4am\H6jlD
X?H&\l d+l9tEE%u4b8!?1+w5hm4?N86pVZdM\49Qa5i:RM&^=iYYkZI/5*?hA*^bSa!/jPDY<LK8JuV@$Be#=q
Ru!H/l X:#W^VqXaaFwPKmNbA4lX:HVm#*&!JDaKj/BP:!$S=+jNj!@D881*ZKa&d6TY:l@H/6PMPni!BNL<4Wh
%Ajj/Q \uaBw1BJnp@qFQVeRt4l6ZppulVCPtY<XYY@$1Vm/LH6HWtTTW>*$?pL<W/Y&WkTwXH1Cia+cJRpB#Eq
R@1eb< d=wcK8$H+aE+e6>FNiiJ4KSJQ^5l!Wl=&*1=$J*<6yBD5Ql<Rej::j#qRIq<C1H/i=m$iBZp=N:^6+wb
Zk&G%S <XdGVld9KPC4WY:X+i!6Nb!q<P8Mk#CaYEWlkmIMCquF*WEew6E5dB$5%@BmGm4EjJ<R1Wc&QluQ9IDL
YT4Ik9 *tXpL6\hEYdJjEd\\Pq^?Xp5AMpwyNtp:WQkuFtakc5$<1k=NhZWBJd:Y+&bC5M6uy^DEkNt1yS6m86>
lLRjR& Qw&#MkQV5m+dYiK9m!$I=Y6wXelEXi@\K6+SEGwTW*WDpG?wIjEac4nacnK6c>bkTk4=mQApc?@8Th/y
T4uEPe kGq1kAu$EbG5%^8>1M<$4X<Vp8WTp9YF?J!>$@C6TdCNnwytb+*WwlYPpbQNTNJ*FC:GRl4G4yTpH6y^
HYpw$Q taMXqbJSlNi5T+@RCkdV\1!AQqNE=ecEADwakeZ*%II9MNThlwu=$wyRQ5pY%hp4a$jR/K8EXLd!1AiT
ZA<ccP *$y9C#i#%TCF&L#E?C$TnDtmAZ6d=ej8EF8LjB9cq!1R+T+XLM=#B>&t49ueJ?ltb?kijZ$=^dM:Clcd
MwXTl* uWeBiV5JH:GZt%^$m4ZT+\>$S5bQmBLS!IjG=tNqtCCbtY!\cmjTZTdGN^d&NlaSStba/GjMtq5tR9Zw
GtF5h< 51\ctuBLiSB%D9M#SJ&$l9LDXh4w8Gj$hy$e1%6HXdnPa#/6C:$d1NCmK=>^eBKR:JuTky$VTynLRJ+/
>I*i@j aFbd<XGuyiImZ@61bNcyZelD@QQ6S>d@>XSwDEwkRmAnM<i@56uI?1<Tu@%XT@h966ZaYj=4^Gj5wD<S
1E&tiQ u:E#@ZT#njWu8\m5VL?wc<:G!9I4/Ch$#hqaYZ<FDZym8+!X:XjRnE?l&Z<B@TSqG!9HL/Cb&J:a1tNn
V>!eWC @BW$$^NdhY#AZ$CDtJtjRIN?BR%/C5*$K&nGJ@=96q?bc$D&y?:>K*Q6/a$?6q?bdE@Tl:G^@hIj@5TY
i:mDGN FS9:9+Z?qeuGCu!C8w!h<h?=N#9\*^p%h6BQ1e9?/i%@pd1MljHS<kEJtVuaj>M*@\Z1MuctQ?@h5j+C
i8!6Q5 hhpjdGY@:h%^eQ^p:+/h?X?kLkQ>qL45<b@?%*VNkY#@b*ZNc@=@Tq&&?+P/LPMHhbuiD?w!<V8t*$nH
PmTKe# jFd8lTuPj!euR@C<\5ma?k8JGh$DaEQBW&4qX^DwVXP96@WbpFP6TZPL?<KCR6VumW@%I9pXb\MS:9Qi
?At4Pd QRAW9mW@AMSjjnNN*XX69&A\##mQjkCa9G*:J?h?+!!dp&8wttdt\wacEn5bSClh:P*LLNH59X%tB$uV
RGZSJD pqRnpekTmRMT<5#eiE46&=?pF@6dA4P\lDEc8$nYTMPhbJL\EEaVky^TJ<Bmtjq\Q/S5upDEK!V1Q4F=
tl@T%T bjWBpV%BbXV&k@Xkn:<qIt61F*pAjM1R@W*p4Wa4d&ytSy5=uCQim:y#F@aX:ANAbQkP:\Fk+e=:n*I@
JD!m?* cpec6jP/j6yVqL>u=@6#pbjTXQLdaqm6:n5cS8t&S$aQALZ:%4?lLhMXF+M<mTEu+neWnqddd#uH<hTI
Zjb+8d 9Hy5Fc*kPewi*^M6C^q%j?I8VDM<GVYbuVH5VX8YZSPj6*E$XM5QGXI5VueMn?6WMI#IW@j!hQABRJ#:
4P/MFV AEm^c%6Q8==NydWjMA#lmmbJ?9\de%q%SP$QayF1I9MZ*lyayG/T/&eh1mtte\T5#yEl$Ayq9jWiZEWd
Pd=ZqX :JZ4XS%SX^cVWMKmBtllIVl4?wPF&BN^F&5<&pW?#AeE4=k^9K>E=PXkuA#ac?w5hW>Q48QRQ%VCR1A^
<Vu*J= I\yWpwe!Y@X=jRN9bC+!C9NywaI8lVq+?T#<QLZ*S/u4F<4VIW^F81qBY98phaeBADSL$I^K@A%LN>+L
F>@EyP F8bL1FbInJenk@NR&/&m@F><*MqQhQ?kLe8^6P/+jkBp&=Ce:=\+468$t1>4Siu\uiEk9pHZnI?JD^P^
5aQt*+ RKF9K?aNkL\Pu>ky%QL5YH\A#CD?wC$V&L59j<::B%MZjj98F<i@5un>**48N>1!@<$h\MPLuyN9lLuV
IG&e:L @MFc=9AZ%4Ly^!j$D6Pi4WV+@m!<=VTQ@iJd9un8j<mAR$JM1:JlH4>$@1F&yHJC?n%l%6P+ZD5cN^=R
-AF4ph 0009459f54700110333 Page 365 of binaries1.zip
Q%NXj@ cp9@ABB!RhFM$Cdjwe9&6/Ginyw8Am?tL5de?*a#BSA6<:n5JT6Jq?pCla+#tC+hJcRM6hSt1P4dXLdt
nMqBFM a6^6!5e:9?mG9uViSXcd^e\%^11&n:#y:C5F&%/$@qbWYV/Cq+?>PFDVmd@Ejl&CF=!%F*KmC@dhbK$N
eP1=m8 +uC$%\*t<\@ctydj8tbD5<1#9/Vc+d:\MJ9^u#h1MdJ=mudHKKF!&h:HLMamJheB!1ITbn@kTPL4\>#:
ZPMa<6 WclYkCm*YQcTk^I%D!CuPGKcAD6PhbaNLTDCmFKan!Kma:LY\q4L41W&imN\YtECCkR^DuNDZtB>54d&
8&n=1Z PXk=Hp=BENCXGXG*R1t6!eI?En=5uAPljiu<AKC^!9%R/?K*^+phBJNBCIZ!<eXF1wi\8>EGLNSd?PpW
Tyy:FD =L5^tqSYK>hip1^+GFKNAD*?4BeSpM@4<=Kq$8DVKbKwQ6D\n<AjjMq+GH>jN>1e\q!I=DJimZjy6Fe9
yDi#:L %%JHmMb6BARVe%yKGWi/1%I&%qhtITC^4>j=b@Rc4I!yRX<dt88mDhMZSwK$Eaw&<Z4+=Ra@!iLL!6hF
jH+SmX 1mVRlF/wp+65>c1ETEQ^RXaB+tE14B+t+6?D>\bmdR&>haBc6B9>YMm!YNWdEc=uGIMi*1W5dD>/LTJI
j:dB:C ^:bw*^:Bhp/iMVLaiaXq!lK>e^JBT#YWbq:Hch!jQe>Z/+%w4EVNTH1Tlb\LWh<4\5LMBYp\lI<MLI/\
X:AM@Q d5n%AEi!qKME4W$\Z*4Bl@E=EmL8<>F&N19Pw&V1@!CP$=S>b^Y:TF1XKlpI+nblGpE9dlEj!/lGYinc
wAETm! abcpt1@hNTI9uTFXVyyJ@bL@Xj<WaC!c6WCcmJ=8bRQHwGwViMCk+*jwj9a\thCd8ZQCHAab9k81iS+>
:I%SQt Q?PtqyL!j9Vh/6+:q#IDNTJI+6q+5wmN1mKL>ALMu@A&MQ!XYCK8J9ShmVyyeH:>X6etCj^wS>?6?WDp
>&nc%* h%PCJARN>ePK5w&yGLWDYiJPI:ZGb#9HF<<>BA?WEJG6L+1il<Z&RVV$!Sj%\9KcSIP4T<Nii4&m!uma
4=R\YV m1Wq$A@9iCc$:T=mwFF4IK/MGbHq\iC18N%QX>?Aui!*jTbBAm@yB1@E!/wEuLBWQ1uRWqF#!m:Yd\^n
>=*E6M =C9Flu??aVF#jpQH#cQYG/y6Nle*WaIy$K$uCHFTMY@j@H*Fa*4:$tAPT<?G\u8NXIp+u6BB=SZ@bkQb
+L=lw\ \j^Fn*>>C&ZwVHMEC&Xdwd!IKuS8BIq:WRP%!wj/dkVlFmZQ<8cctm1bF=kwC:4XH^lF4N##q5D^Wm%V
tM>$ZZ *%#*F//wbwSei&Skp6lbjt6CVlIVcceN:<#^J$q8DET+GYn/AKW+VjJq@RP$X4%4V=%w5!I&H9b<X<<$
N8DAD> RZF+9<X*ppZ5!4hl*CHj$VAI5bQpFN$:T$W4n+@P9#=My!/W4iXtcL>?A\KGFjAVLQE99Pup1DH?/<NN
kYX%$V <QeQN@1cImJwCE4KdI^tjQ!bhMM6a#PhwJ\HCEFZlWw#yDycPM>mS8PY+uF&iGlPJw5Z:TLCa6FKuCL#
&uKcJ= /aGhh=iQWH8R>E^>ZeF9D5nW!qGQp??K5HkLVVMe+1*6?&bule+JTc\VI%DYXn:bL*mAAXND/Ym8CKI9
^CjV=% @ZKASZM9mN=Ip^\FAW1IBZ?W:%Pt6cDY\$^CjqalW*YhL?BFB$9tYl\LAYuI!Ru:@AYT>EF8%D#ti&Wy
C/P&&d ?/yMA:WAnTMb=ye<PXbYd/+#qT/5Bq@li:*Jlmb%ehN<>/%dVH8beqtIen?#&ewql8*FP<P>jW?W9bT&
c^hdKw @8Q:yyJj?9mDbR:#G&@k^cm8+cYu%5^9H^j@Z1u9Q/kVP&4ETeZH&Aue6%XAZmHj:>aJP^+A&w$QkBL*
JH&q=B @lYaP=ZSm<ZI/+aq>&QQGc8XJ+/:%/*MEwmq+BDG$JQF!GDt1Qm=Y1*ZK!Y1w4XRVFQapKjFhR5i$qB!
h@9%JI QM!q8D89*=h>j?u&<pKVde/Gh*jF@98nC/le<#jHeen#TCpuS\*6wnNLtlmnaCK:1hny#WtDPjwSQkwK
YH=bBp XMXB14aj+WDDZB@$*&pi<q#!:6ddqm>=#4T6H@uiq=n<@LDlRjq>FYp$M+mjqF?TNI%G6A#&jKF@Q/&I
c^d*&B 9y#EYdb\dEpckmwkeEqF#4:>mh@+MJ:!y#+Cc&9WqpnNPLlm+RDIBX@m$q=GF*t8^%5?AK\5I!@>&!R&
?nHP4i @44mG514S*j=!C\m*h1*^dWQ4Nl*qRpK6:c&ZK#b<pE11&QKFtQD<i8bL/bE6<5jlC/aJ<=P85b1T#9p
C/GmY+ kX@d%MwJ\^BNH#=9+y44l*F>@BhJ*Q5BQcZN:%j%?M>Z8R:8d:6^TKKcmLB>q\PjuSe5l*T9FSLmV9yi
mRY>c8 t#=/1?R$5jMS6htXZHi91u5ey&QKBBiDIjw9Xq@yWEEuP:8\VkC=ZmK?\K$l<ah<Z+@*9i@/L>iutW#@
j\V!$e j>n:/:C+6!%4FC:eNaXLeJimKKRkCi:8:8=PCEq\CueJqkS*h^Le*T%AEn^aeBIk!Me?*th9V9Q&/d=>
MZa?4D 9@i=j@CWWGQbd!+dc</^C5I4EXX4dY<RLW4h49TVw1Sb1^a4wy%pnhchGyiJp>/wjeSE9b/t<D#kIFak
\+dYy< #**HyCCeqZZam%4P&tnKX$l%C&CGj/>wR6C?%&jMl%JX>4#<:n$mwLP8DPG=+PMewh9JhN8nwW8P\&4T
>:WlpL T$WF8AK^kH?TS%I9Lh:RdY6ykmHSipMt9XtWFIy@4XTe8*/:9uwj:ZT+Mjd4Rwn</<4R?=@HQ6C&4nhC
y&kTM# B?6Zd4+lHL=jB<+*d\FaT:iA6wTnpS9!yq8AL?Nc?lZW:ibG1a@9L!u+*p:6G6&L^6d@%&mu\<@@Tj:@
HW?jpP uML:&?thBkHk:LmM+GCi54wjqm9Gj/n8$:Gjqd/Lpu$*&RtM1T>$cm\&@1RDPZN\wXNnPVR+p5:J!w5\
%h*j65 $:d&%8Yt+wnpd*y6jZ@Yc*9*:hi<$Qee5%8Amp#CeHQyy?4n8%*Kt@i*e\ij@kA?TQ?QX\@jnt>yCZ&=
<uyaGa /+RPbI<9\?Zj@W%*<m:@maP@KLB?11R58=5Vh&QPjENHXi+4?6%nQjn$%>LjbZuZ!kh@K56hEj#PuM/@
XQ=At@ /j8YZEt/l9%nL=Hb>&$J9FukFVwDyn+b8=*?4eb@^h9jNeBj$t9*d4l!K^ic8cGFm9>FW8*yd=J1hD@@
jlXG$e wi^ySpc/N9ZXlq<G69X/qFSFTj!K$HtXqhVC6lj1*=jwpa$<e?FyNIZJk1NFp^+VG=Hj#l+<%1<>E/h5
$BAjnB >mul=FEW#Z5qCVHT+cayQWyktLkTY/Xn>Z6tMu*NQ&Tky6S<C*lSn6hQ\K4LA\XYEGd>Ep$ytC5hMNp6
WyVNQ6 cC<hZk4B^jW:e*!QJjGKT$tZhGych!/KSiD<%hF:9hwq:/Q99Y&p*\idZ@:Mu<?YIa<a=MY8w!t&bSE+
dtt1uQ :j8#9P&jH6PI@+FVci&8=<i&^8mF#<?t1!5qCLa@tqcPEHVLQMG8:1HCIk<Xa&XiI1A%BjE?+GHRGhwV
YP5<6a lwlqjJWhd+>=qI4*IucIliCelRZ1$XpG&Hdhi8/4$Sk9ZX=iSJilCW?u9jwa\CbMdpa&X&/R/&M\SWjE
XDNnHY yWR:1>8NPXFyyBNpY\!<Vn56W@T>Hh>qYJV^^PHnnea:nLc6K8:ScX<ulu<Kd4pb@EW89Z&JYN^P!GM>
mnT?yS qAAt4Z\#T%B!6m=>^cZ>HaINbnPPCZ9@y4\NdquP=j#HPhE1=XhC*l?Lww$/=eTk$+SbJ$WLcpVy1tMJ
HRpl+^ HIWphT<jj549#T*$R#*WeXbNC8YISd$qSJu4E+Yw\qDZ^&^<DT&Vy+&6SWVE16\jc5Q1lJhtKq<>j>ek
!ZYnia JA8?TYXcMiV8tT5t=XMJ>//i?^X!C\n+VVitlQQZ!m%k?Vh>tX$=yb>9L:Y?M*:?WiNhjR6wjZ!DJ4Sb
tl++ZL ?1Y$:iC99!::&/@H:94A5>@?5/6W?>=*aYSu/Pde=^bR?=9YncdS#/=dRMh9InW#!Y%LR419e*@h#E1?
G&<9j8 PmPMib=bjSH<bZTCVm9cyCj$VRTLZ:l&/:Au5eXG@%:y1TCbA:ZlckiNWet\AjGHKnd66Kmh=@QGLVLh
@ynmc: ci1VAGG9LwB*?QlBS9F@&NE<FbWM$%R*6H@#\:=aAa=tA+6XVF=N=$Tn:44Gbt+YlpeZ%nH4\:=Dm$aW
D#pYH/ CGE4//:wtZ%:mGqwZDZ%uZTYQ@D!BCPMXC>y9Y>TuPA$W=pwwGJ9Pc>J\qj6qE&mk=#<e^5h8lku<w1!
W?t:@< B1!95Ch*^yEP/MAC!mDk^+kH5wVlMq*QmXbZ9:i@uZ#@hNl^lH1C=w\mJ%+GcVwnNb9H$KG#:MC\=Ynw
SwRqS+ Bcq5DWe\IA:h^di$^ad$$PDeC@$^*l\H/$^\Zn\:?thTe@QE5m:AaH8S/qPlt1bFdmQZJ?pTwY>@<4q1
%D@kjL X6RGZXHw&@eXHaR4FA<+:$>6HRtB=RLh4^T5jec\BYQSKQySCu9KQH+N$duZV=1K$JI<91cQ$n<#%RW@
qmIj&G ::pF>HkZZP8b*kJ!A?@&^DY?+YhKq@X*Z<8k*BSb*kIIh64PHCIK4twy&+=b?e+4%P>tiH8n$%l9*@:T
dYwynT 4/56cnhqXd/VIyhCu:WHZ1$WmYb<XRlQ$qlaQ4QE8Qu%5>9<=QP\+nb>yK!bEP:b?@bHjV?FCKDwW\Y9
%SZ$>b d1i&9u@:NK=S84LVbVP@u<t%nVjQZNSnjJL*jjA+wJMECc/\<Sthd&6L>NP4qTLJI%1d1qp6y4b6qGyI
<mmnKC ?5%BB#c?Zc6J@h\iF1#IlDlImN:ZILbpaq1AKCC^kNw\lXH/^F/V$QQT<E%BJ%YR6*Jtw%5n$tIC<ae/
=cbAl# ptL9A^nwAtd*@Tq:XG\+qB1aMLMl@Cn&*A5Hl^#&H:a8e1<^E@yw841tw%hJ&n%be5XA5hEm8pq=Ama8
D%D#1= W*p&ln45bi6k*G/iLq#W<q9A\XMq\:QMiaj$W/j&w56ua\HwLJen\1!D:\?EbDN\K:#I^4Wh8tkC?*b^
TL?%hJ 16Q<d\GWN@PZP+<Q$u$9yZ%@Ma+amF&jPN&%PM+6\Q#mdmHjS:>ZqX9X+#lAE!J=&dXjCpY+PVpuj?&B
k91qi/ <*Pp:byP/Dyl+%HliJ\VZQ:tG/#nY<A45>eKane/YZiQEHaLKCby?ehQ^L%N#V1$ae9B81wc4IL:wt?E
D<Jmil >tPRipwKjX5hdkHd%LiA9je<j$>+5##4=1LlDu4Zt/6jtc6?pR?R#t+\=<t/:QwBiiy\%IBu!>&#HXw&
wq=CC% jT^bMj9+B:HR4:XFQAeBG@y+GajqlPtK>y?a/qw^LL+=Q=jB$eqql4wieTXwYJbC%1S*=Z^^?i%&Jp%9
/69R1? WX?*TP/quudH$6HdaKWJy#V6PnR/@&:N6RuZ>hetQ$8hKIV8ytbP@NjR>ek??4!cInYT51/=5A&Xj4&=
Gq^:&S H/QcW&<N/KJHb!l=&TId5Qqa:md8bN<NY?N$%AP1cGIGcjm?^@tnCh!pRY9K?RRHB$HHC&Nuiu1WR68Q
/LG8\h 5@iyX%S?uC@t5W/XT&?wWDiFN8Awk&HIRSwj!StW&BjCEDhX!AiZh8GYM\1BqNntBPe?Pt%hlNS$EtuC
M5RR%# %Z/qV+W>MT91%H?K^BlR4$Y@qM=HnShXbc=*yM>N8u#WStu&Le1JW+1ud:c<QDJB^Xa=CLF\Xia^:qh:
*>!D$m eEP6uDX6R%TH>DSL9IV%E^6=hqLYMaL*JYCydh&!&wpnVh6D%B/K%kGWL1Hj^PA&$tXpt>+PF:=k=Ybu
b?/5%K FWaTDh=CJyh+nD4wy8wXVPc9m:h&*PtYdhk9^:Q6h&WcJ$%PcR#+T4pn<jVZRVkF+hbwAybIH#=J#u1i
qFIi!b HEL@#i^kZ<QEFQi&K&J%ZdKTAWHiYS+dc<>c*QM5!C@*:4pl#/8%iD%aWpBTTw%GL1P#ZFyn%ldWp<St
-An5nM 000c3bb62ac00110333 Page 366 of binaries1.zip
?ed</e w\VCJn+1%=VWBCc6a&=pq5ZBVn>Id6Y9m=bIlwc/MKY95uSt#awCX9uua9at*:NZckS^P6uG!RKe6YQ=
dY@:dT hu4cw6H8=tdj9!nB@db=$9!4El#!:K8P#jt#q*t%dj=5!ZJhHYWheSLNe*l$ZMuWF9FK+pnKT&GPmRTh
pQX=!! I%wn:=!1\kXLFBVJ$m$Sbt#au/JIk4*y?b8w1l5$NwbctNA/eDcN8QWMBl\KL\IGJ#S6cMQYG#R+TWtA
!cMV\q el&jTET5m!djIc=^QQqW96lb?5Y</8\LNW8u\^wBy#Wu4cHE>yH$c=d*e@WCTu\:$yN\t^?J^I$Ll?!V
DTJny$ 9Ahy!WmRYJJ<+edn>IW9=4V\/NyY=b+ypJiQZ^9T:E\$EMVa!PJ*?hahq$9iAnd5ZuSh*\J\45L$9^:Z
9ThZlS Nc@e*AJCd5VL:/b/j>@B&bPRZ#iQL@Cd&8:=thPF:lju8^Z8*V^Iw<X*XidE:>6&N*QG5cdjcDbpCH$>
Nt!Z>t 9AZ$J@&t/Ka*?9nk*Hhh>t=6uFV&DijuqhA^9h8@p<H:&+q@KGCn^+dT$^eN\&ujY&QwV#Y*BRb:LSwp
d5bnBW cTjDNu:SSVe#^+jYQibT+Ji8</e#Wp5:JN+dd\KNJ6?pMb9$N#!6jL#6^QY5*CH1dkmpceDQ8hb+cwlj
5e1#bq WH^+?YS:6Iyyh<+i1<L:ej+byhEK6yF&ey9B&W&NwhXh4nlFX>MH\diA4c<@%*&uiy%PuZ+hC&&9<X*!
8>c&%l ZX<<Qn%K9!c:8a1=>B4=:ZIWH/u4J*eV$X%:6>Hi9PQ&#jH>GueLWCJyt&k:/L<FFEViV5deAu:*:hj@
!SF#&q q4V9T?Z>:SVu^LP!T<ZHF?KZRqh8N%Xu:!8@j4+FQLbhn:*YP\*\:iQ<>Yd*LMdwi<GuY$D+LTD>T\4\
mRiSFA &8l$@4j>\%QcH/>>6Sy?94$FVQ@aiH?QSB5@#^@e?R!FR9/9pYkn=Ac?pR$1FCE$S\>R&Gp9dC+W=mWd
n%La:& NQ<6?yGQNVtkRIyaHHYT/m=lZbj&TTH18AH#XVnHVq\6ZLKTw\<ynZ?Kl%V@+uqwXw/LJbp^pR9V+RkC
9TiMA# YyJe=LpmRaNWGM?WqQ$5iYP\4NbM8k?6wXZ1WHitu$LbJTZWkeeXeLKh:eSQh1tANYlb$1dE\Rnwt@Xa
:X%QSV +@FZ>bl4$p5>pT8A=Gc8&EdqJ<HWH^dSk8ER&h1CEb#:ehtyW+!B/HcJ<kKTdEHPlGY^+/M>RjAB?+Vq
9Z&GTE Jaumh\P&8j%HeZ!IDqauA4pKjhu\FQ@+W%6e$@e\/w@qu/8&%:!9mpE5%V>LKlG^C#4pREWwaAV9!Z=E
Sl/kWC lLS%Ept#*B%\?VcX51BT4LMXMQySWAylh^hdHEe=tAJ@wNh=Z4ej$/*bm1ZGJmYTNQ>AVD1tXDad>CZV
1I?y!+ >WTinGujXjRcVna:aKKhS^<NRRSuiKGt:PkydtMR*yI<BIuNd^BZ5y1<RclnPA>BTBIQh^uW=jpIBVnZ
dT*jhq Id+l1XNq?qpTG+E66$+WReGNV6J5iKh&aqhblX\q8c!:WbhcqNbhklc!aVBYT%Fhd=B$?a%phA>StS<:
I$t8wS B@iV@8eXmVcWHq46IVjPBuq1M*BkZaLp8Mc$k8GZbAR1$EIY+PSqh%iy^18=!BF8#edwS9NP6aDM$IwT
Ic8J6Z tewmuiGLPpiBm9wu4/P%j:dE8M$j<!\*XYP1\cEl5\ZVjR9G<>+uF&eNit/&a!I<qcPDwVHbKEpcnL+c
*L>SBa nAu^AtK1yckEXp\VV#Hd?mPV%=annHwQI9uL:lKI+!=bEWZ9pT8+mBKbMS6Lt1AkXCCST>aFq!NIh9cL
e5\mu^ S^!9&FYuk!\c1?%DmCT^cI$@6W1u5!X+4F+?a8K61w\W/dJV>mTa:S!1pHC#WG$5JFCRuY^p$j#XLNuW
5FlV9J $^^CXu1ta1%GEpW:uj:ByCS6yh^^tI!J/DuL8TQJWDtXiTZu\cmXb99%FS4k=>uH<6yeQNC:nq:QQd=K
tj@EJN k:R<9#4yn?n#VCAS^$Ik5h8Mje\&cklk8YPJLMDVwk!%Ve6$njCn81wpL9AyLC*eeImN5<h99:ml6%SN
M<tna^ %yINQdM1YXu==%eVKpu@yMAYu9#PJSb5M\e1IB$DPD5S#XbHWkGh<=\\e^KMc<w/p\kYX6+qky<&K$E!
W>9K%e FPwYAYCp+Sy#a4cJM%pka^#Fwyb6F@d$hP8tbX>LeFHD^IpT#epuA=%AZNG5>W@$6eI@1WbcEu:EZ<GE
GLMCy< E:cLK4p\abN&4b19pdDAG=lt/tdVR*k$L>5ne@AMaH&it1WZ^DJP^tw6L&Mm!/B\8N%dplTCqYuP4#$l
NtkV>L e>Fit*k<M&Z5ER>VF?FGN%@8bDQe/Llknd?eJ<jEnNm6R^G!eCQVn*!uDXPp!IFKXn</>SZF^c9K:1ad
9=:%$E ?1J&#lZNRCtdK4D^JjC>QqQTBlGmABGePAqL!BWT6CaDC^$1c1p1pXIV$F=EmemA&yHLHcISYb5PLVD$
P&#^8@ 1!NPJhk!#>Xna+FFjpYIheSTNPEQ*KLREVX8SDi8ke>pVFJMKGDDCIe19l^:FaWR<F=$eQ4:<#Ji@M^K
<@8\RT bd^IMuXutMnnZlS=jVV#IPRl@#*CwmJCp^IT*:#>nP:EAPQ=FGabphSuhF59Kd1aZ$9+?jYw:tkG/Sq#
Z!a?y4 ThwMP1pt1m:aiKkn\c%mBlwdmKLm&WKHP+P=^S?J^iZ!TTA6%VMB%qGB#M/m5yIqSHSYa55DELYRh^FW
udb9#\ ^@I@+b1n/C\a1q9FeTW@jY#lhE@m+<*#B%58W/GGClS>yF4p*qdFD1q&lWeGjiqaNwF^bNW^eScXYPQ6
=^Sa$+ Hwy@F^dAa\p!EM8LCTYW6A%K=pRe#8c*SYPD/1wSS!*6MBeXypJ=MDlY1HiGM\B=^aTdYhb9W>mXQRiA
DE8qB% MLKM6^nnaGRdYY9p\+W5FVB?E\5YQ1m9Twu\M9Bn4\K1Rc!NIjpGHBNQ&J9AbDNyb91\IAtBtpunL@HE
XMXiLu u/6MN\a1ceLilcXWJ+l!+Ip5ICEHJbLbmM@#>@ICbw$*BD&1R@MEYiQ**=H8VPcnC\Q%c?Z%Tl1bpVlh
JBnw?@ $ejGlRptpGJCHCm!5mQi\m#DjdnEdiaL%nM6tP*6P<@p$J8jlIWVbnyJ!B#ktMw@Cw&*yEJK9Qw\>eH%
Zt?ZJn !@LR^/DlkM>tEc*qD9a#Sw:bP4KS9jFe=l>FmY<+%wd:*yn9T4#b!1G8SHJ:ahj$Eqp%l/\uTCh/5=P:
t9?c1H ee?KF^/VJFy4F6=1&IwPHyM=1!9F*aqdlMB!MG*JZT&%KjS6>#Kth?by#b=8!lBNDnyCempp9p%&$u&M
&$!!JF XJ:aGNKZdJ\qPt\H&ZNCF\\iEiM11!<!TBVEnPYCN\5ADDEd8@iJS#5ShnmLPERee<8RulkwiL^RM#dH
CaWdIe C@%SlMG:*eV5S44cjZ\GHN\wc?I6yDIeE^aa%QiMZB#KG@C?6NpDWqjP>##:dN^VdG>RZEu=dthJBw\5
@t$am$ >%\FeD#WQEQ@:DpC\M:a\<ZT:d6KFlQ+IGlCqLPw\d&npE@H!$GXNDd!^/iDpaAb+qwPI\KhHk&4@Wb6
i<hL:F *Vd>niJQ^<%+BqwFhB@1m!d+cDa@1HDQtMVn6deuTw#b>4HA*FjiWY*q69A9+Dy^8GbAluk^I\I+X=5y
/P:l$k lF^QSeMcY**ey6#KTm$LP^b9<m&<M$9VY#R%:a*\Iw1@&*%9!9K1?y=8:jY<$4D*I@P99ZEcLS!*P5CB
:Zk@Pm W<*4nk>luF\L$ehlK>HNE6k%H/jbw5AVanb#Q/Sc1etjJd:TZ?y:#W/w:/eeD?uLM9QJ/R6lLj>\dLF!
H1Hiqw 55i!a?*kYL@eY:Amp*GTKV4!Wj:6TKH$eBe6JQjq54=kRZDn>\9+qhyyEylEJQpH$*E4#C$5W/:qFWYS
I\M<E8 /4i$i&^WdRd%9jCB4>F%e>PXJpnl^jqHmFPBp8?GLdK=&AN/uMtA!jTX@PA\ei@?=dCk*G1p/XD4YSB&
Vbwl\5 tyaFLC&9PGwuQu\Dlmt<E!qSHN1#Gt45H5nC*#4a?jKkNS=b?<yY6n9:B*KtK44j6JwejEYkLhJa9XwR
C^:&9j QQI*u%^p\!CcadVPha:M@icDTk9d$?^5*JjLn5kw>j!^b5lYL%FDSjiSVVYZA!Sy=w9K1!ZyPbJSyANC
LqYE9m WRQ5>>lFq%&M#YEY6S#Y##EC>nyA4iJ5Z6JtVFy=?\W\CRBG8Q6R:6iCWD@aQLJD5*5bLcc<:m@cX$?Z
k<S\1! dXqntkM486CeJV?CFJB\NXASSJDcdZ<F?Apjtq@S6CPdI\i%=*IIY*QkMIpm4wPS&T=#>:$QaD>B4>Se
4jBI8Y mQp/6#EPw@CXa!6Hq%dKX#YQ\Pq?C%lHw1QDmqwX/lJW9S>\LKYhAC@E4:Bn!J8Lpp<1!GZ5GtEe:<VH
tKp>VR JMe/=<>&Z^C^?mm9Ae:mkk=#1MKRVq$4bl8=@N!@p<>8Q$e9$jcWAXyaMDDtbDIiNL@m\pBWMEAMjI>+
=18bJ\ 1AwucwNp/5\wXwF$SMP1\9DYRVY4YD:ChN1G1Sp:dqd&$BeydJAYBK8p6$GNM/Ky^lTtt\>1F$Hd5Zh\
LVPwHS jIGPXIa^F8TR1$cPMe*lqA$!*=IAdGQquab!bWw!N>B8jCIXZYTR\Q+Wmb@+nRSLew%<#%WWMR+#*wVS
+1VRkc 5wm5V*?BA@8nNGX@jHTA#S8t$lhMP%@y?@a9+Nh*kuTInuYapdA*<+lXqiKIl#Vw<iSq6*nqKlNd\\iw
\hiuFZ wli1<C^wdSXIFJ^II6^%XT&%uE\H&jjhh:$Pl5c\4MHeZdaM&@&eP<%8by>^Rjy$DMd1TLI<w5Y<6Jc<
$bE%@9 tc+q:hdIJ:^CMF$ittiIn+Aca6ZIy11CteKa=wP@1ZlqYnI8l&K6hh/u+5ZQ?:?m+kYt?w99=Q?^a#$@
^kdKb: **@N5b+j^QW:^*y?EPnBiqX@ej@<uYQyH*n*@pY>/\F/Xj#Rl/C=:%E@kwIikPc=L&<w%$QRpH8e+KHk
?Ti8M: B/D99V5e!9$R>H%*l$MlD$B#<>@nkA@qiRn/*ndujRD/jph$KN>DH9l>@99Rl^nd9R:bWPk@?$D@Bj59
ybTk!9 jcD@Kqu$t\<$Q@kQ4t@?e!j/b+q*@49p@n@>w9<6@TLT@$H>I6b?%$SaaVeubqGpc>\ncnnlSlLtFiqC
CMKcbX H8GP=6YWIyFCF*/^Dn@HP9RAYtyEbiX^jYJp:pCG\eaS<hBFyK!lh+RDn5VtM>lm4@\I/@d6n?j=SL1T
I94QlX %Q9F/qR$BD$!LaFIW*1LCI1a6p6pHG^/eHlVy*XeCtwhj5b^cyWubI?1b>#W/RbYHERZGw:%$kl:w\Sq
^*@t!Q 8R$WT6!Ji@&SHEm^CLnDF#Y?B@ca#L4pZZ::R6BqSc1B4SBAZBNaa#u/lC5C/1V^QFPNQyI9*eT#RW5<
FA<!IQ +qX$+!kc++#KmiTM$jt#^*HB^IjK@Jk=bFatu<6@SZl8#D&KZ^pJFR&$uNtBL?>F+TEw56ch>1m^Z9Sk
XH8ny4 5J&dhSeQ+yhp=$kd%Ybd+*dS$H4&N8DDl*hclZMP?eXA&:QY&qHI&Yd#%!XFX9hSPa<<9en64qLVGS5H
=/J9RZ >6*/l4kwnR<t9?1/b&!JH5p=>??NnKk=aEqw%CN#5IwV\l\4GIPpNZm8P=CjMLT9#Eayj?1VTjwG&HSj
@CY@Rn 5SJ=Fi&>ynWw<^^D49dwKIci%uZ?Pdi8&<9Y%8t?i5kCC=IGw>TkJRZX6=1NJ?b%^QZp8FaG#tWFF6XP
VdpDl^ w=cVJQP9Ry^eVK+LDEtYF5188@tdN+@WBLMW@Ehi%PY9dCFTQE@lt9?aaE#Z!/HWHGiA!wVy<PJE<MTc
d:l=JV dJuX\w+l19K6l4#6Y#9nF!E<9TY><^haGB<eDy=i\\PP>>NPhy+dD*l>iK=Q9AJEi1WE^tqFDB<XX86Y
\:??tK 5@b@!/\BcwAV4ZFDic$JH?wXQ\Ih5C!IuCbX1!@*l%jXq<9qSi:V6A$W$>KRb\+R%\c$t5a!8h5V*@XF
-A#u8Q 000a5d4ecbc00110333 Page 367 of binaries1.zip
$N\NE9 bS9VRTWi=h1=AGV><1!J%yDN%IG$\%&<teWR\>+P6/dkuiH=wSV6!w=BjIA6=4S44hyP<\C:SG%lHIa+
P%ma@P X#kiEN:Q>paGdeA*GuPtKZm>Sd?nZ1CauARBXIC!FJuEHVuLBG4\nJ?E9*DFwa5Q<D8%nFa%D><5FP\t
HAqJa: CEGmb%uXNk=A:Vd*RmhYj@wp#yW!AHu9DE=PqY@jtEKtC$C5T9w#qhQE=EQST<LWF+PR$mac<tq9C4w8
PqY8bL #DSnQ:+/BFpK?q1wBZ:bbpZKP:i=RYE9ELLb/JRGR=b**#NbCbtcbj%^W4^aYq8QdFAa5WY&&q5pnBpV
!lnmL% tPd<XEwkmac1*&k*D+!WYJBPAjm$X9a+\Ca/k%LV6yk9uhiSuGpk*$R%8GV$8VTJ6y?h?nSpIn*eeqMp
X51pm6 dACLWVG>Cl*jNkyc4L>VDCMDuEl*TNAZMLV#\JSQPJt>JR6RGI#H<<qWP>iPNETekcW/dIRG6V9/:5t!
<lcB%/ *GFutMpqd&GlajnKZ1:VSBASd9>Ym+^+iklYYnH9AB9FE%1W^^%XbLF!A1KFQDY$RHCwHD1:bPHFD/#E
:DX%%n ?EShF9%/cS9p+HXbPn*ebby*FnDmTbKBSNTJuWy$Q<8ptTjG4Q&jJp1$EHbpeq=YmKdK#Bt/1mLA!WyJ
<BjWAZ +/yQ8/P#p*?ZnN6@#jCL*FjpR:IIFy/Nnl1\$E+@*AaM\WYCHlF8=!/?PjEYWATt5myMQ5&wWZSZTN6t
A9uT=P jlQ4lEnpNVcMhwmKQXk5^VJB&4y>uG+^\hmph8tu9$%KdFZwn4XTd%TqM<XM&W&Znq?*N6$pHPQaDeW/
D*!PK+ HXRi69+\6?^?&uuCNtwmFmFIL%@Lk<cJLeeHL6yMMZ9LuZd\PXX<l$V<wJ9*m<Ewt5LL#icJFPJwB>MZ
h+B*GG t/$Y*V8hSKq5MF/YRe:ZQnBPA66AhBSL>Y6phXiiDkcCL@H#>wtD=/q/hQW@ymL:8dR$5FwuL6ZpEV!p
$Gk\NC l^QmJlpEwqSb/hEd/kRTy!4HBLi9MbKB$M8JjmTb6=@Secm:PHK:NN=HQiLDdMR*iB4?nFVM\6D</LDp
ppcuL\ E>w9+<Hn?hmbM8H5q@nb>1cP1INRC&a5h9M$qmp\Qk*yBqt?SRDG1M#SkA64Rd*6mK$P$=SCTa+CCXGW
8/d$R< KMVkG=CwHqQ:!\pR&1/HCdVZ\6!$c8%IIXc$KR/!>q\PdC$b@p19:!D:K9h%EBP/=mB#?95TX6Q*!PHl
tPLcNk =Aa&BWFY*W9<Dc=!k#bVZk4Bc^pu?TeD>wmwCNl+uh#>RJTZL=&?hdNuKVVQKF+Fh4D!uK8DMWubj9m<
uetRn& 5<c!5j+p*FQW:$!^*qPkqiA</p18\MTckip+CXNEwJYMI9lB6I\tbN:mbq@iqC6h@+l6ln>VtW!Jyk9d
eFhdh9 5cmR6X!i:BC9jaJh6RmbM8Jhw#/tQQ+?IuF$aP%l:11YDPcbeK>+eVc/HLbC1>8ZYGHmmkc?%uYcY9&i
!A%H!H !qD%a1IRHBtNy?4YnTw=Y8tqSB>#Lb%\!QD#w$m=pb!@^:1?*GRI+PLAK!pK4H%qylFG5a9VNlZ+NTiQ
9kTlk+ :@B:MCpW&RuDHMt$unYm!w9YiHI?kZhm+NGa!F8!Xd*en#?i8T=tJNhF&dR$DWX>H@\qt%ubp8tcRnXp
>!ddVm :NGt$Q*TWq=QS$k#yZY>mH^X#ldnkkPK@JmQ9YMI1$$J/V9R=wY%=9XPmA?hta&8\=5I#@*C96dKS>#K
4k>**w <h?&6Q*<YC/etpaE?=q9$IJ4B$tT6S*\LR?G<+NZ/#GbnkC1ptHCq99n<+nYX#Hm6dTJynK/%>55&w/H
6D>#tj *?&V\Wmk6anMRVP&4L=1k\%*^>GWM#F:l!:Ld>L\t1PSL>tmQ#G5t6Q=lHh%4&RP+1C+a:Klbkp9h?Tn
tJGLRL !qu$%wW@M<#=<Hau4ik\etI$KH#E$\/>i>k=A%N+CFEidAS!lI1FF%hW=?!pdRb=t#Fc\dE/cpn1F@e@
M+8J6n mdb#R/!IR:Ch@I!SY#bMC1WFh$kqh\:E#kb:aFi$95i&Rh>XVCyydI!ti^?$ZGtD&6aD9+?Bt^BB1BIq
<9?>mM Ql$\##:CWp&VX8&kQqCS<yqi?GKdqQ?A&IGYH*QN^+CSTnJ!Q%?JPGLZ#&A6*yibdVE#WwiLkSwyBVuV
<V#p&J upw8bctEVS%*YV#KpH?wQJ%>>cPD?%WjcVPY?%iy&8bl&d%S?HRPbDqY#:+%>c=l:+=9cit:$?6ai?q5
DAQIjR 8B@HJ^M=WN?X/<1^8R<\ZSAi8dbFk>yGq/cCe^=%5S*HeLkGDT+wZS+ZMM&^p&G^p>4p\T+bQZ@IPn%&
/\ESNY $p<1=InEeV!%/D%YiuYI&?5W*b8@9LW!memLQj:yAL>#VNy9>NhnHM$9V9k8&Dj&TAFG+a/H\c8>E=hR
DP1T+: bY&QtEe$PJVuuDGWa*wIwND/Mh+nVn&5+9EL8&#^8K%GSDN/<e=4Ke?X#N+EJBkt=$$kT@KNKF$Ay$A/
lnVSXH 9Z%$tKyGmZFAbQN#yjW*MS9\1ub5bt>yi*y@^hjZH=SD^>^@PjhHPLYRXHSiF4lu^FJ>1SnDnGT:hlY>
h</F5d =j\^lN8QNL/k4+LJBDBjnWAZW+DmqRBXXKna<ilE=B:nn\\<a8<9M&NDq%4t:ZE<h%SN6JG**Xq6*uCQ
N#RBM\ waZmB5hYDXB!BpkR8aF$&ej%FJ?wS^R9TB^CGcP=kn%j&+lGF\V$w*ec=w@HeAjpTJ+:X!^umTuST=+@
*dDG?! GiQt!D>jSpbPS:Llp*Q6Xu$&c8bcX@1qqG4HFBpHJKdcb/EiIlbiqE>qpND4\?$4PKRnIM>mkX5E16Gq
K#bW\1 uXm!=qyYLj<C^k@jn^ilQDnYnJi?n66QqlV@hE#Xd4X<PMbPY&J<bIuAEKl<DGSp&Q4G!MuFcM5yew4F
?LT%!A iCB<GblAFW<X&dh<+8y<*MiSH$Q<\<tuj9LX<TTbYI!E!KRSdaWXk^Q59IIMRVXkpI5*V8%GpnMQM*:&
>FHHC* ep!Jjc#&X@\G9P8YiZ\PJ:aF\Q$6b!*<LWwXCQKYS%\C9+!Vm=bG!GGEK\J:$EEId=h$<dS=BmNh@1:%
wuC+#H ykTiC/<:$L5dBCy4Ti1dl4n4j*hR*J+P!j\5F>XCtEuAp&p8G6Z*/NEQZi=L*S#y5mpu+Sn4n1Lew^lq
5wy+#a a+\Q^**%m\!P#W+p%NX+6GCjdW+@W/B!6L9u#%=qRYctX9M8nekN!pp$>RkH?ukyp9\L%cQ91ktqmS#A
pqP*BG N=a1WlA5!puX5Y>ia$wc##yFqHiVX$@P=N$8KCYE!!a#w!&F#S#FQ+G<6a&Z#Y6@C6VMtp@j#A*WQPNW
DIjBmI :WH:nMcTce!AQ5/A**9YZhDudqlc1b>nuGjV4T@4@ILhN1SZPVLeQe%nd@S\F=P:?DdQA\ln+K$4>/t4
6h1BjK 6\>i/Cl*l\F>%LF=\ZkBY=ke&Mdj5QQW6%&N9*I$/SFe:TGPi?&edpw1C=/M?mhLFw#K:@FE46e5d/BN
451Gb# e$h4<S>\jGJY=eX?adt>LFA8@/&ZkC>/8m:ReH$&im>bVE\l@48t=Ea&uRZ&i!51=i>I/lHYjk4Id<#n
GHt&Eh %BNwIh1PBD!eb+DCe>HCt%lIB^/pn<knX:^TGAqk@=L^YIkiltwi!X?9:F+=@NyQ^Y=V$an19XPZ^iM#
NdG?u> G&j&cl<FC8=9BqRwwCDGX@dY\=<R\9*qHF<iiH5M:kh<M$Q4%A!R!6&%8tql#DBFTZWNJiWqMNd&$PjS
AZ1%Sb $uI/d4eu:QXlwdLARZ%h>5=*T>\WFW&pNEuB:ZmNJ>9/4MCSCRdq&hb@utm\mdyM5NjA&d1kqYBR6&1B
kEw>?N NCb5yw/yJd?kqTZD4G6$>6%:QRXT6+hhdIJ=<ybqQhqT1#eRnKI95Yl5K:+kt@nGPFPK9p@nnc$Sm\1^
A%ec5^ *@ARM:jl*Lk>+&1njiI#iF\11n@m:@:Mc9%4@8:j+8$iVM#>Yc4?9$LMkdq@V<!B\j>Hmlj<ZND@1HnB
*wb\kb D@=DiZq?$P?Jy:>1:Q@uhB$@CQIRNB@QQYmil/B=:pQ#QkVNjS?c:\FwCDjwHnV@R>Ak*u9R$Aik8ju?
=5S?9F tQQm=\I>BA$B*+Qtikkc^HWQG9\ANJn*uqdniwm6ki>4e//H&BwZL><>/Ija&4$$JV<Z:+QM=d:M?j+6
A:?*6Q >EPM:V/T<<<D\i>WJ@=%>k>WuaD\W9FA?cpkWMmjqGZ?e>YJQ\>C@<m+@4We@=J^@c9R^J<aX\n+D^lZ
!WeLy! MNh@RZYC?&?1E@#R9/6P<QL@%%RuiCFRu9>X%aqCRM9@%cwVtH>ZuWlV!4IP5AFMPV!d<9%Ai*RL$Hy$
1Ce?4W nbL6P%M@h!M8hR8AdQ/@/NP*&@EWu<AJwb%F8%5ADi%9pku%^$y$&!h%hV5&l+1%:GR>8DVbPV>iaXNj
\PAawB Tl*jAm=P9%+REX%Nyb@GdN\CV4ddnnp+L\4+6l<Q*RI&y*#Z>a%PFJth*Nd%t6d1/puhc\c>?pn:<C\l
!TZiGn baC%:+GP>5$%ql&P>k/$dC^%DYJGVX#a#%S8Aeq/RyhTSle=jI?bdkFD:P?9cT88J6JnEu$*p5h8+8b8
llC^5R 4IiJB8tCL?9ickeVNIk$RTnW?nkMmKSIi:K^um$G/8qZGWpK+NQXA?L//lS@8!4i:dj+5M8S!/Muj\&%
d?n$m& 14thjL@<$ln#VSLkFyD4P^#K=jNdtH5M4c*!F/HelCi8m1ymNB@yXBKiWwIYRhtTulXGPZSQ6Nyj#<6X
B?e%TV ?HFAbAFCT?G?A/tXX:eA=@i:dV9!HDPcp9Wcppq\Hth$Di9tG991XHVZjaDHS<R9CB<4bLKIe>In1BMa
@#ywCB >$kZI4G$+VEtj*PM?DSRGuFC5Y=*Jl1W/^hkC:@Zwa+ptLb9/?$RaYh$NJy\:hY&9tPbjmQw/Z8C+ZEL
AN@iJ% aGS*8=*/i%%Tc!\Hl@=Wth9yLYKKMl14F\m!WhV4N^tVtZTAyNXwFAtT%wLH9+=>L/Zj*^SdZtd+Hk#e
FlZt#m A4byjC?L$uhedkF6nHhXD:5F:PS#ui:1WDLVu>Fdp<9lFEHKChybTKQZNTPhdReHt!XR!/#XKecGH&P&
/q4ijN /X\>8wH##Zj/y%i\eRNZmwY+8/&GF>MTcZSAm!VSMM:&S//9P\%/9tN!?4e#Y&/?Li\*NVj=*Y>uIVdp
atD9D= E<1EbuQGLK:je&6cG=I*P@hbE@&9taQpmZQVNam^R%/^BB4X8Y8?k:J@c4iiijPG#qmYu>WkQc!DX1Qc
IdN=9X lnFWYt:^E1dT@Z*dljMY<Ika:&wwq!dbJkwa:BR$@cl?4eKkcA=JwpSHnmyKH\blHbBG$nEW:t\J:%XE
Te6Eii wVTjGDDtiDaaa6bVn/u^/wt?F5WN%bTEiQSE:BkJh6A4q#TBX#%TZ&Fe@jG><d%m6IZtJ8MBLNlC9L/*
XM#/my 5%5pNSaYt:?%6>$%:IIeni<1q>D*BPi*=?Lkhn9*>^ycSFqE4VyX:/lQqcHtW>9a@mkjueQm5w:@8ld?
Nj+yL6 GRh%9qwnE<bkT!lp@c/Ac&w9nV=+ST5K#$#DbDDe#+@q?bamE:6DwPCq#KB5GHFlCjIP&n=Z@8CIQ=aV
!!VCSi Hww4P5e6AAeHb&N^I=ZNjm&%HB>SS>@FEl%=^8#<tPhw=I^X$cek/#HZ?BGbp&=WXcZNLGFZJPFEJtJq
k#*>*% hqREN#V@C+i#dHF^5DKBPkAABGDi>aH^>=6@CWRe>K*<T89QeA6IDBm:Mhq9Y@>i@1iP<>hK:Z^Pi!@/
T1kt<p jybd+^cRjpQk8=p^+:6=C\k&8mnkMdywY>G/5SuS8uE/9@6*t66@:VhCh#%!=u<5hiaB44S>/?ibqM<A
>1=PYm ^nJ6G%R%6+CWq^WZkud9j?6Tj/*qLcCe$WXAV&JZSpqBB/H1mYkJTNQVac5al?aXMubL?CR#@/iq9E/5
yhk$yV qB^YF%9pXc>bYCRY1L^#hY*ZP>Ku=FAtq8aawt\eF11!/KbQ5V6&e?%$Vy5?>@:/<88lFF?F$K?#68Xw
-AD1Wh 0003a396a5700110333 Page 368 of binaries1.zip
MwSjtP J$Qju:8?HiSjtt<BB:P*kABw!+6d\Ni!Y\Cmt@jJZcjW8$H>h6iljj:F@#jQ96$CjB18<Eaitku@Gq$M
B/6<mi ky9y6Eii\p6i1q8A<XZMWZ8C:/CI%T$A>NQw&HNP/B<:/X$:&C9>JJ#\Q?\llkBWJGS8Gw*wt!XZ:WJ=
GFl*<J tB$mN*VFa!bahDVMKk=Ma$>X9lIL1&nPMTDpThiT*RItu@GLh/9dcTF/HhZ>FlyWlSnp^=MiHk<kh@B?
8bQJ$B j<uZ+!9%?Sa\M:6:A#>*M*DmE@Q^FqBTNuiFXHGh5Hu>?Quh%KlZea=l>I6^=QLb\W%=k>Elah5Qyji*
*LFP## 5!pQ@Y*//i89%\cPde959u99?db?6X%??P#d4u5L?QVMciKu:=uHl%8A*=@K>nXu@&:$&:*4\uB&9$XW
TRR%iT 6h%j68WT:j\GKSuH*Cb5MRTtTIJX%MYJ/Gh%B?F<<$K$X<=$Z+>nhY+B\$@u46:Ynj*ncHDZqQR88=ec
d:eIqR DXqJP8VMV%+kGR>uFH1hKG9YL6S%>@R5#jJ?>!u>/VL\c@5%ZXT8wadtcicLJG5emyVVCt>nnKEZ=b!1
^?AQK$ Zw/YAjVwG+m8eV8Tm^4YeJy1pyShZ?FGe8N5KKwFq?Kap!IHcMbV%mQ=5*qZWlWEJ%6eNKjM8T<nZn9H
IqVXp% #R!JX<pnpd>LFCSADuRe1q?5HyNydElXtm6uNNKk+^wkK+:NjXhY:Wi&uT>>anu!@ud<H<i=\GPlQumF
lPqh<M Y\A#$98445??A+9/@#At6M?Bc*tuyMN:JuRT\tFqSBe9+H&$NTnGWk\qYJ$\lHj+l*Rh#RT4c%kBqEp@
nCJ%lX 6mN$S<yd?wp$J!VkVFSL!a>abL:GdqpL?BAVPDd*QMi1/WIZ&!upVma*JF\5dnwQ<ebi%GyFjjuYYn!y
^d>9S+ RRWTD%4NBKpDcZ&XtTEd5uF1K%F&u\%=c/P%qbW+m*c/m*WW/MXX/VTyyjJ:j8+1#ueIyWb@%RlXl4LJ
<ZiGiI lp@aSwk\b:GlHt+jBECK/w1aiLSyw@&dIBC1!tWkE/jS6:LZqbMq!:eA%%9A!I9mXy!juFh#cZ@:+ub!
Y<^kE? m<AI=hidG:5SnWQjJ6@N=yp@j^\5Qlhccn5^NND18Lqd>/ThcL^/9G>$WeH#u*\t9i6<p!$+8q1HnQ@W
WBASFl 59<\Dy*<NV=<:Hd/Z\@Sj??$9eb/R:@5AFG85nu^WDlhNb?*Qke#?1m6JyMLCEIq+pnVy:TJ6mRl>QTi
ntMb9y /$l&5l5*/RETDT<%H4H*QSMmRD5hLHFbJZ8#<K6lP:y!69TMtaShTaA1DyZ1YNZ/PZKTdun+V?LTu\e&
Ic*DP9 lTJ+6BQ^cG<VM$*NhcmmRT\+9$+nbb1uCmV*+9qFw\9q^DNjic^&PhW$/L6hJQeKlECa<uIy+/<A$mbQ
Kt1bSp /t>e?4aQl=VAN5he/uHcSe1*kA>GRTBZpqdK^KmwX/ClYX@E8==y6J*?%#i@mY#+%J\#Z5HjA8T@@Hi@
mF8wQ5 Katc$QWnFFWAWM^:6n@/n&Ql*#6\4/t1Zk>d%jD!bb^YIC6+d:4\mZVlE<p?bkh&DT<&9GDcMPX\yCjM
95VYhS <nbX6b#Ah@EquVKlFX&>#ZcKpB%euPVQZN6PmKbl?E\W<IWWTl^hjc@RZq8+QB*YIn\Y#/NJJyJbA:P!
T!IKk& qbG=c!u>uKYql?W\I**yV:L\eC4yS&WT+%m%QTQ^Xbu&Vi5#W:tJ9Ldydj91SYy=tb!4DZ%Jcb4wXQLW
\qEV@y p!41&wuk5Tj4>1:9<eS9C*c/Y$D^Se6Vy^6hh6>%<jhuSpJ*/*q9:/>Z6ZenaH?a$E/4p=Li*Rw:\8kC
YDI+\G n@Fcc?S?IF@B*cR#JFF^Fby\W:J=i6b&aZ$*c5dl?</<?9K8+SdAV6l&VKN$YbE?hVjDdGVjdS>pdkEc
YK#&eN J@ju%XGZ8Jk>1yGuV9$JVwMlh^yiP:1Xu>DyRy46d1hA8Z8n8QD6H=eeJ=d6e*!HC*Lpd5m=+Ren/yZK
pQV#WS \ZAd*bT$c#8i^Ml>8uajR@^ZV<Mml+l6@eXZ!haPQ94@<M#cDjG&G:p$:!HR@jB/KaJ+mRSj#nm1#%q/
B=>h6M *cb1N=D8#ZAaiYp!9JS&ZLalT:H=clDK>TIy>:HtYy9Tj8?t%yt%$Fi=u=k$J=k&^JE$\YTpPD?$^hJ@
?4Cmp# Y=n<!#:+>+:dc#pTJ8jpBJXMw+966TQ^\FR@L=Pe#$P!E%Gye<%8cI/@kha8FnT$TF5I$?B^R^RuTHDR
NSdm%! +u=klnW?4pC=jPb$N>%EnX&F%j+yN9e^*>%e%Q96Su#Bh\c#h<\\Td4qliPImGaenYl6ihiEhJ@Q?heJ
t6J1^Q :=C4tu1uQ:@+*p=9?&cj+X^a&Z@>>%+\ZIC^46Ec1>PC^mV@ec*$D<PNCcqRC4%%dpSw!QT#aqq?j1PR
ptbHw> qT>eR+*pun<h<>RyVT/uJbYphp/N6ML&>bMBBBYh8ZBHun<:#%hQTGT\5pAjmj9%R1#tu&TNYIDlqDMu
4#hRaI lHj+85leK5m1==/q%FIZFp4^LK/k4QD\=QEX/M:bC$#T&nT*X:GtLCn\HlFK:PRPYWN^ZEKe4RZ!tuih
<%N5@< $+c4kh46+ibY$WYQe:54m6HYjVlcZBPGFlLB6D%qmpPpNDV!yMK!<w\dnAjAB9y#uA6?ly>TH=y5=AYC
+>p\#^ aqFY8yunm*ypejpH5=Pi>M=5VFhj<SQ/e6wTMhP=&bd*G>BF!jaDtCF8FVR%SaJTjcaCe<#NDaZiuic#
bl8mGH =TKu<jlBVRbbIPtX%!yHXhRhi%&6h#8F9eP6KSGW:DjqMw%<dEwkNP@tRqHykknb9hYw?m+QaQ9ZVB:l
MJCJyC QDYhSNh%NA6Q\R1A!Fu>W?$jG?N\>hLI:hm6F*@iwwda?S/a6#FeP\VX*De&hb?aen=HhEMq4*SFWKhN
^AwYT= Ap^nK^KFZ!hMd^Iq\^IdI+?jTQX?4Q?FhZuFCDdWqSElQ/1mnX*h<X!cM=5!T!&DnIm8PB#M+15!M<y\
9cLM9< EGDcll@%*kLIk=BKbN8i+BEqupJu$wBXec4Nk&^5SKEqtqF%4K$e4bJVu<Z!*6:N/SyBK4EmY!Lq\B%h
EK/X8Z l6S<@hiGCtT#<*l$IL&p4\%>LKVZ^Eu%d:M?m#JEKIclMEdFc>N1ca4%?C@4?@AZdBuR@p%L<&=\8kti
+Luhi\ FQ1dkmcS>D>wd9:D::=t8ej<ZZQ#9\&BFLwGk<PW^aiw+kFXlJjG+caR:q98>Fy&:4b\:n:*%ic8q8!9
1@IRY! G5A@Jk<kMtq$dt9+4FVH>jl\M<ZkW>IuA>1w&Ka5:SF%4%5A$!*AqM5pX+>>YE6/dKh*iCM%\yYVJC#/
#bp&a4 i1#4y:E@#cJ6@S!*FHh:dCW:jIn^4y8N1%@AWI$*wlbl&y4$B!8?=J?8MjwnyNe/\1mVI>!TT:t&CYel
QB?:MI l1KJ<%G>&BNu8\a5m#8nd?dR5#RFP1&L\+F1$&qmLZ^bGM5=GE<GC5ZKl6DCQAR%aBJ9pn=I=k*/T@nI
jZ&ytL #^k$WB\>ljDZ8^:XYu^Lp=ABaQX<KbbGQCQt9l9n@9Z?>t/Mt>aZlNMXhND%KN\XY\8cG!lXiDJk\nnV
%+WJmj q>?cIE&\^n/C+WkW??RFy!?=th/L$GKpn<HTL5NHbTw!&+hunuw^^%Jl9jy>t=#!ET@W$uR##iyIq!pX
E?e#dZ Xa8?^qB5<bWd#X#%Qw=j/qainPtIE9KE8mypChutdK!/WN6584?JMKKLI$VpIeDB=XQ:Xb@%DLL+FjQ$
+#5\mF @I\y/Sak*b@RIM:%n9c:wK5ReueJW$GD\cEV=*uF#iMd?=GlG>bdRMnhXyDd>W?B6T6*$<#\W661&:u9
\/NBip SR*jZ*=%6<LcI9?u:@/PBDj=>9ki*kJPLI*?n%L>l^VC%qFZbMP%*918!TN^?#d6<6+C*6nq*ALw:%y%
/?k?JA Bn\4^PW?I1n>ei1^+nSnGywBlkm/AM>nj/dZ\6L4\66#eAMZYjtmCAw=P%W\F@\*DSLIptY$BG??p:wQ
jGV^uJ Qp:#XqFhp=qBL$SK$e5DYDLq96j/CI@T1uyn8+$F1nhkXdjyZ/jGqhR9QPmdKiQ>LV=eVib$$tlC6/CA
Kal?u^ @muj/cMI%!hTn*aPXG%T:lAacI$P4G1++dN1mCdQCJi@EyWwyI#@Y9c>$H>*N=euC^=eEPFec@/YTMKR
98TS/n $ZHj/:5F\%*Fm#?%ddm?5L9SQtld%^e/$?P:Kqhm>^&m?HpXEZJVaupLTB4a1Lk\c:*4lM=*5=u>%?Pt
VBhAP+ J*h4CLduZ+<=Hq?Y*c*9qG/$GJQdN1J@*Wl$@TbS=n8+jn^*XjZX6:@Sh/ji/Z<$?@V@tHjq:NVa8JF8
NP*S5h #$8ddF5*QZubHuAQD1F^D*@M%:N%=uCSd@/8hL!Z&CXWMM&GN=HK:<CbTPM*6+BCVBDt8^h%DwbLWS!*
Y>CTIm kF&<$l>SX65>8&/^I1/wS4wb4@pHh6@j#m&MSu*:Y4+Vph*ueGd*Xt4*S+PTC:F#pyd%5PN$V4Q$aun+
1>\R6@ !\!WF=p*^wcltk:Ql1d1Q%S>cND+EP15l@iW8uCu@CjH+ttQW?*ZEa#$*Kc/?51/qi&pWDpHGtcanYZE
u4>*dC FL=Y1MTd+CjIh/6cLB?##:bHh44hlA%#!5L5!\t:9EejZGJHw*PSXRi:^/9j6?Q&HH@d#JdAbD%n$d9$
RN=?Q+ TZlV#+H==CpD=+<\JSq4JSn9\hDnNL:bBB*>CEdaCmY$<Ej^eAX#E&*cSF5LjdZRLaAqahV*IN*yWmdm
G/KC@1 ^udp9?@n&P%+wP>k:5u:Z=8LN@Gth^8tt9?6n=qd8nky6YMe&\8R?8@AYVZIGN8nliyGeG$:6t9Ya:8N
?M?#5^ QSi9YkybPRQS$S?hTwwHK8uKWXtN6bmE/8L1>P5R19LVHX=BjFBh<<e!HJ/iInKJ$<@4d$*PHC/<dY\w
JN:hW@ Wk8@dX<*pGuq?@=^KQ?jn<*@&SYjt+9@@==Rjy:@?$Q=J&q*<R5n?R1JHZed:L%X!WNRF<@kT%li@Tuk
8:$TAE HqmDH8Gq#Di1E1RN1yILJCCSwEWX=1q&XWQBG?iT*t!TCI#>Llyb$tlPL5HXdpE!G8EuImNyJ4+lDkI?
1<$m@p ^bBRTjTk\5YKhZ?yJ9=d/L*5\J>m@IYB^W#5^Pd9aEw=wd6FYT*GLKnlq:Y^+dE$NamqycH/6dqA9*eh
yAkK^d uRl?R%nX?BlINEn\RZ9%$9JpVPDIcZ6!puLiVBXth8YkKFV&npl=RyDL&\cNMm+iTL?8mWIJM=&@lG\n
B!i%/4 FujTBEw\k5E*mm>#p/8+/Qb9b$V/VTKaJXdqwtpGDcy+PFHE^/9u8ZR<HC^ZNZie4c@tihLcmihP>KjM
kK4I/c SW\puC^SeQ%CLI*tmFZ<9ncIjlJG=w9hXnA6TYJn6CIFKR5GIRBqkcBy9&$b>5BZtaQtdI8&SQIcAXiX
GNhXV$ uBeTRTj#+$@D?IIjSW$C%XSAk:mw%AyWQecS1nP8l6/T?:&mCC%4\QG1+wNpJKD8DMtTQyZIB%FmLC4R
wtK@uK hG*RFtE%*uYJcKS?P6WVZZLEjZ=hMS#pj5:T+PWwyhJ*wN1FB69h?6HZqt@c84#tKAm*n&Dm^WLL1nhE
q&HVbc !Q/XX8!MJQII*QcXw8>4WijS4$pm%!yRRwI@669Zq5M=1jj@IpukLnP*#bEp*TMSCDbtpV&abBESpWlt
njGBeu \hJ\G<=kqQ9bZ>dw+@$5w8T>yLyt1y$bt^$hLVEQ%Sl=KdI6Yu<!VhCiPX!X4cWnBVAIiI^PX5tqdmuj
Ij>I?Z n:k<?DZmKNF@c&L$Db%qIS=?qI9N\DeIpKbIu#alWDn4ebFqln=%jK^dbGkcK<Lw6WmX5YB8eEW<PQ=I
5mZ6nb n^^PAetQ4J*ZXEauG^iNAR8hcp6<l5^ep!6et\p?jmh&PMBh\u?eL+?iIYMq$M8tQ%YAqw@jBE:$$L9e
PnBLK? 1===haZWhPFdBGwlLkw15jq$4ubpXYm>XDAH&X\1nF&m9aGtN+q/twWq5u?a1:cInEJEV6R/+4ZAkNh^
-AkiEw 000d853e88d00110333 Page 369 of binaries1.zip
&@C#jB IY&kdCSPW\lNdA$%qY=5w8Q&IaZul@JSq!C6A=KpVJ+k9&\ZT/!nC\48L1cbYNe>R<e\FDyNIC1<KVaa
+e%/lm D1<JH4d/bZWu%lD9udq<ykw*MGnM1EcCXIFuQTly1JFhw8wD8*J5H=u5&X9YJ99l&i1pIVX>=M!XC4Bt
bk#GJc F@:nm+@cljAM*QDDV1ub*PEP*=u+aLDSiF&RV@>+E\I*W!G6kJ!$JX\L%:m1HwIDt5&wDAy<CJSpLbFG
uii%l5 ^6wSnXQ5uSpi!FZ%P=/4e9J*M1a6l<SCGdZpy8+iSVtBjL@5!I@^*+mNX?YqR9Pb1:R@<p@68w6Q6#Ak
+yh/<i MFCGBcdma&%V1+^:@BI%9NSKtl1ywQDP\LbIN:NQPEIWu=89XleR+!lXieWQZ1:85CQ%1%!lt/dbRWXk
9mJ@Cw e\LD\XLlb/nICXkpw8X6c#NZq%jm&S$VE/4ewT#tP\l?JtK&I9mEiXVXi&d<phKn4eYk4:y^e9nln/wT
5bSqSn W9*Mt%kDGL^*C5qTBXW$bX9$*pZGHhe#*tl?%Yn\Le5/=lcZZ$kyytPQpIu1+wHwp*p=K<cPlGali8aq
SXdK>J 5yB^IBMQc5*4V:%SC\Sl!#jTlT8=1Aip5e5R9Hm#GMikc5H4QI#ZuaKEkcHCM^phMd:cp^:d9QNW$bPQ
iye*:X c#Ru%HLKeaQTT6QEN5ki\VNP+WYBqk:JQQK:^i@?ti<$S:&1cN/#+$1alXtn?=LkT:>bIaQn!D66S>HA
CX$GAX @p!Nc%un<Rt+Ymi4G\qnR5K^ebYi6w\iM1YLQuwSQPw=t&FV%!:y+9F/*w^EdAI?^e44mI=DZ4#yW:9J
+cW*bn kEKLEkKLcmm4GcE+>65wBJC#Fk8&Wuhwuw?YdImX#WbcLQD#I&$CNHeTZHWpnZl>yYbi6d^lDP@!8GCP
$\yht# 89:Q%hZMM5BpEwqLaAT<?ZBA\lPTLQRaDH@+4h16aJ<R88jpqB/j>V=^ZFb$$=k==YcBHJbdh^l?w6N=
GKhjZ@ =4T\=QP#NWwEYWXY9KP:MBBcl:@XeVFt86mpY6!ipuEW^JDAlLTp>C6?$<=nd!4Myajy5jKRD*&P?4+C
EGR$nF BJFtBta8TDY=Fw&P/Mb^E>G/mE>+8CI>^YGk#tAwqH>p9yE@?>H?A^Wn1bQ^l6VHD=WT8^>be6\1DVJR
w*DB$J ic8LXChbVR@k%=DqAca++Pw!E+EQpuJL=\y?HcbQMw=$QwWLVn+Q@$HMC\pHH6pPdq^I<%5k>Sjn^/nT
eG&#68 n:n1N\BC+*T=+^V^A%9$SuPb1R<$uP6qmRVaVtb$h>i&I6KP91m$mbEqVL4HBdm>e$4EPPddTHMqp5i&
Lh/1tk @?WQ$Eem>ehy$cAiV/S>8a\>Md4Fy#L=l51%+kNK!qeF^nGKMB@>6%!wu9^MS8=9wV6ZH/Me=Ne!9nj^
AjTQQG nm+yjm=>C+n<6FpKn48<lHY#GakNTm4yuR4A9uNaIEndI<J6pyAI:$+!PL&X!Qw++IGm+q9uK^=lGBc%
&>?btj l#G^@Z#ui<KdthB5C<LFh\h%meH4\F$Mm//#:P+8pnu>#MkVP:9V*I48T@^ZmbHtCFbny@*dd=$Y4=w+
SAT9Wm Ca6ea#ZncWaJ<cnneV@MjM?kL99qP5eaiSqX=nj$W!AS1th*^XG\Dt9@hLYCWKm:WPSAE%P?#+CKmCZ4
W+8?Gi HWkq$aXe9n^:KZ\CeEA5#/eyD:/<enSW*I9<Xi1/A18jFY>jbdeZQpA<L*Fik^<?QAS<KEw:&9V<qXh<
SN/^QV 9Q9nnKp*R1pcDJn<we^khTC:+mD:\*Tba%>&4X5M^YaJbFHemNHbkt5=bT^<1pVMkc6>^JwMnqYZAEZu
M&VHR< Fl??#PYXhFc&Gc8@bQ!ICE9#XHmQZAk/LWP?C1:E#9!EFQdqNd8qFthRGK84R8DlGA6!@uDcj1/!iHS^
!^PbH< C*K&BNX?6ZT6FNJ/SQcP:lw#dt^*4N\ERDLShk6plb8A%*?EI:E8ki#uk4mBH/SwKB+:8DYK6d\R+:eb
P?J<H8 M#VKkj^1\PLZw!yq@VBGVMt6<kn?DEV=+F^19AH5QP6c1$k:QBiPGC+iBGVJ#8LY>$nSyYQlwajm:Nu4
V@w1a4 TSKEdT4JSVqMTBFDJF9GStlypX%M1uKd^V&INX$MHKlZ66K+m8cbK&^iYZu>Qc5:pcLLN4BX=:lB=ZDu
Fpe1yh XBl1yQ#pjC+>5p#yjyn$AV&/k?m<hh!H=?kPyBLE1XY4&HH9XQw4!Lc1HX#iGX48qah%atX&pd85EYP8
Z@bC%n J??#qIaEnZF?^EDj1h4SXZdAiT!/4D?tc$J@SLi8?DcGYBVRcY\^HbQQ$ibpQ&WJ4/R!GplLXaP^qGYQ
lK\PZl ?Sdj5RKF*<u&*E1i9Hw+tn%$jSLjE\p^D4?a<CS5?tV%W4\u%!k!R%E%Z>^X9/$Zj\9=K?Pp<\nD4Nu\
ZZQywa G*4t/E+\:*9G&NJajkj5?H!=M\aY6k*FFHD51TmYQnk/9yB1pXVG#/nR8I<=EI<qIC>wW/$Zaw*?uqJm
eXA5!Y Q1j5$tuwnM99K>e\95*PyZ+<l<an:CLt/TLbIGYF<6^X8q^L>/LkSZRJ=e\C\MFGApiSHCiYEKeCH&jX
Gw=I*X L^B1N^lQXPISt$8N5NPJGMb?/*N8Hq/MK%Xt*PLJD@qVium\h!4hXP8D!pZXX#>H!bN^Awqltq*m<\dD
:#k<4$ ^@RM%tBE&=Ei*B*p*BGu$lFHjwiBa6NC*dHR$d=H?l#qKYdm6mpl!qYF%i4G=VQ!:/yhKMenb+QR>!W\
mkZTet l+SY%+S/AB#IGS9Fb=n!:\b!Xj5WX>qnlET\uttww#&deQdd<^w&9%E#a^k=MW&11Z@H$q4KjEI<+NmX
j%<*9t >=RpVI:c1q+>4I#elnS*>D&N*Vhc4HNX$iW%GGYk8ZbEQmyIQwTL\T<lkmqCqE/=%qIWVK^@nIVV%!CN
an$\hn QP5aRwh>PA5u>wR*&@F=um66*#Ch1Y4wFwTi!y=NFMIa=m!+bp/NaA*BdBWK>8SBDWIEDu4Bh=eEXtKc
njX!i= b5MJG/JSLTCd&q<l*CiH<Ghj=Q<?PaS@1aHAVjWZV::@a%h4<P>>R<H<wAji&<eQ=upI?y=:?@nB9A>B
+u/n!p R?:^1AZ#QRDNe$@kQ#?a@!Fw$H%w/AQRpQ91#R%/CQ1?iuN#QRRN9k<NjkCc?>/Te@>d/IjaGnjZjYmi
\8P>cI j\9>EF5D*>61D:G%?*&k8S>mdQj/IZND@^$$BQR:L&bPBT=8DmkHF+RZ!5WldYFmD8bR6:dkWJbT=uB:
>6nq>> +iBk+i=1a<blat@q=G4nd8*k>qC9=6<<=*uAIC1i8&jAe&iqD@B1luD>Q%W+KQT8N@NVki@?jm9nR<wG
plDKBM @miQ/:<&?4@!8Q/d4MYjQK==IZ@keR*l@n&^^kQmA9>@Glj@c^wZbQ@NGlh%ZCZPb5nqCYuIbMZdnjcp
:>Q159 =YlD>JlFLLyySM\:+Zl+\S%?q1Vh\ChQJeTHT/iwiQ$Bt?Ct4FDuL#LjM@hADh>#^qip@IYZn*kWV#w@
&4t<l: #jBk!J+?hdLHpqSp1lb8F?u9hBMea=c&nETYAaJ!RcYmiXL#KylQi49*KpMwpBDM#SS1#%=cpkRncI9I
/hYw4& >\cK1hBkqlPd#/BT!<p^BthFJk9!&1?By?6e6j8It&nb*yHZE!/4QK<VI/n@%B5Q$CQXX%D8eneRpjkE
DeK%W* @iwky9:%m%cPZWDVPdGK4QGdtYdCJT\!hX^5AwAcjj&ejISLMH:T=KniJ>1GyFY9R?Wu!!1b8?F<&9Y!
p9hL?: /\8Ki/bA\?h!Cc<SEdRHu#T/YaT=n@8H8ptmB>ATiKlWAYW5XSX1=JS4A5ql1#G<jm68$CkB8anh1I&<
+#eF<5 tq1SmAk1@y#pEZ6wp!SjVXRhc$m$<cKC\M:mh?W=c#8h6%pP8!9CP<Ay5=R6ZK^jbHIj/lTiBWh5Kq^Q
R5=QY% &jQyCB9\#CyQ?yGw<JHSF$ukFc1>p8L@y9EKpe\8wtqFmVa?#F:\PYn%!Q$Lp+Di9BXG9/8mn<wC%m?F
pY+NDe &$SH4GBP1kZ>Nw\Z@hH&L%QN6T$tFIK@y<j#HXGnFK:8@?kCp$lt#H:16E<yRHGjAYN*ub9jSnh+dyE4
=bw8Ft dSLZGZI!JbAJD9kC@ED%hbX:d^hE%e5uqwZ<F5mZLmKq!=kuIF*EW$NtlV4t>u%M*&TDb/&bMJnlRI%%
mRK4Gq p@Fj<Wc=&b+Ty@c\PeVq&Qp\Vi^A8JQ49/DQ\=A:KawJK8im*Z:yaWYS<1puj+yTl:j@@n%SYEQd&9Ap
W/PIDA Be1M8h+htIw6I8\kNRytFm/pj+Tq%9S!&@WSKKZRHu9wXIy1\F:!#dp>PVGZaYai1TTX5tP$6ADE8cp>
%9R5Zp IQlh94@wl85*elLPwGpME&F>JD\Z?aDRK8\F8T^$9&IeBID^NB=/cQ!I!VSM$6M&?qi/TWqi88lM6m$N
!c1R8Y !%j?LGhkDpEqBm&ACa$l/^YmJB&iPX=tMmacDjm$W+@\Ip@ReXTh^h#W>q$+JGE=p*B\YaW>w%FCd<h?
qKj*/5 dXBaGTM95kcybQtkn!:<K#q+&?G+1EjYYHk\Aj$AtVN*t4pt4R>9:$A/DC/td*:R8+C/Qu*KWqj?\kt!
\>wNIh n6un?mniTDRM&&/VXN=$JPyTQmH^t5E?P?&S6\*ZRGGpTt/qn@EwZWCC^6QqnQn+WB9^RFRwk/a?qc4C
RcWG*^ yw1p>wGR?nBVZ6Vd=&tcWY\&phHe<4*PWnDy8L\ul%DlkjLl:T?6CLKJMw/&&YTA:8ey?PhQXIaJ!@!E
n>EWGP 4>dMXYZ59#!DPR?TJithewQle<a9T$ea6#\5nq1!c#%hY<t95lE^um4$M>H#KLDai8KhR1c&&^+ymM!W
yAWMe# aldZC!A8$1&ZMhlYY:e^E/pJJC=P1FtGDR*%=&<W8H/F5nt<Wl*\cXkXpPTd?8E&VP4B8/Ycd5$e9N\b
$Cbw=K Id!VGqlY\9YBTAhB!=bIQJmZWCi<k^W165a6FBa^cET1>eQX&k\NP@q+WGE*ktphcWDG<@y6d8Z/1Pp9
Mac%*/ 5y^I!GS=L@>aF4V!a&@4Vm=4nNF?^uWNu5nR=*\l&$qhaV%5&??D^F?>=!TEtnq5Z8q?dP?$CIbSE>LE
lCp&Sp I!AZwinY=CZAhQbTi&@5/b=$?65btyF1a:yG5a%IJ5yQn6Bc8?#W%L1X9kIFAE1C1eIG$N%MiXL:$mk!
Wm#c?i YMMe1P5//>?WZt6>IY11>Wnpa&P/@e1t+/VMA$Mt8pGqSN<9MJhlyyNm=/6GPHebn/hdQui?wTT:hT/H
Q98b+F lmPj6HcAeNHd+&*q=t8qy/p^n%Mm>WnqZ=R*:FV4y/9P?p:a\9j+I!SL\4bn&5h%<#j%EcPVpMCGjS=Q
q?Z?AT 1hVIc>u$iHR>?K\KT8pV=+^Zl?5teqWNj8nlH#X8MbiJFd18!ynI8m4w#L$>kVh=@hQSw1$t+n%Y<Mlp
q4w?eP W>PINiaTiaF/WcG8Nm+!<>8TXAG=1D/GV!RnIitn$qTw@d$8$%RdlhZA=cp\DPFNe6TeIW*WSWL?IhIZ
:4y^CY <#a1%@:?K1&yGjySnjYu1tyP^T*h+>%=\MWI:wTYhuDW6tL$u6e+KVwcP=&NBYN1nbyHPe5YD#l@5iZ6
$CZDk8 y<SYaj1Q!1Q<iHZ/$GAWJ4N%/ZA#FX9n4>\C/4nt$:H/lZ+nejuJFIw=L?1j>%p/$Ta?j>cX*5V6Z>e<
I=+8u$ @WZ>KQ5w\*=wTIT8jnb?$bED<twVRNeecy9yT/Q@K6u@LRM>ub46Ny&!VkEQKmVd:A%F?=Jd4EC!1HZ1
aECdTD Kah9Sn\/hX&pKB1*p8KTJScQIVn5^E5hT@b^dSL<bl>R^qDd\Kn54QBVA^R5:uk$q6SDcITh9jLXCCZP
enhcaH *55udGSPbCbYejh>D#IJtkCnaQnSM*bp9pD<X%QV*Bqj6F6jNP=$TIXDNa5?yKuTV%#4XJ+btk%iGIEw
&F%1wI 4mc#iA\RkRnqteahH<#Z*m:*BEwytlQK1S%TMLMyWquHV<y8R$44q@ZeR*5RT1CTESyiceS1AE6YZBQX
-A^lk$ 000f3e034a400110333 Page 370 of binaries1.zip
tw&N:% 6IynndPE/WZmZ%Z<P#icNB6n?QM+%J*Q4?9:S*^&>Mwm:iLLCSR:k>ZL#Ql9PI5N%+\NLWh@?T&dYZRA
pkS&Sy aE#Z&MVGMhZGCLatGQyjB5J9eZ!imTamb#14SBeGapM<PAeLqZGQm8S9LE:h6yl5ku+mjJN$4+kMyKXc
>JTuj\ bFHi^S^jb\t>!F</:+/XbJ&$/k4@HI5h6w@KY#acm#YFGmniDR6@V%iN\*pcnLY9%@WltjNtk&ya\@w4
=ja8PT /yw>j=/A>*aHHA4L8DPljZnui+hJK>wTnP+c#BARE#6??ukZjAF&VGduX>pd*<^PDYRYkZ#EJXRu>M4^
wjFeZl 59#aabwKyENlqm&PuS=/4NlXkTyWTGZ<<@=j8LV9auFLwbK4&<9LtFWkdK\4W#9W=WLVec95/YWSiPh%
Ya/\?P jT+GI$eeHH9ZeiP^S:lZu:pMq*JMkGYH9Dp?#tn6X*qqGQu$TA4n+!+?+Yk:GZltn>A4HkF&pWJED=B<
R8c:#p ^A=CD=T6&*PjhYD&c$8LymBNGmH9b?&%b\AC5Q#tnTXHK/Q5Vd8C!phj!ZHbyudX**TF9>$eI:i%NIaF
cW+Rt$ VB@%WWlWR6dCDY$TM=WQX&#EeGWA=wZYPZlk#?$Mw&$JeqeTRqZ<eMpZFM^9KaJTWa%Ha^RH/R/CpVuD
%WL+4L #+@1pAha6A:iwDmpww^qt*D^ai\/&w!Hb!n$cuC^!IS>I8hK=A5#6S:QXWB*Z8ZAN:X?C>!EZ%J=\cC<
MyV$mQ p\^c@k\cFc!M\XGT\^qq!MA9\>wu@IK:KX?AcwIyk+<5kqQ+:55PC4dMS$IXM\c\n@WlH^:wKb=qP1Lm
l#QYeI PbmnNmeGaMZeR1ER4$bjBRjDFIT^9Hi>iAT?metZ@VCtdI/k*Cc*cmyLR5py^XZqKWp4m<W%RiB/Yl!1
bFuKk1 4B4^nR9=DFRpPybQ=\XcVi<@QELD=R6dTF!DWnw6u/G\FXXjdYBqt*D#kT9!iKj\iS\T?QJE4ZH>@CWP
Z?QyaW d>!aH&Pn<:YQ$cn?&Q=it89RRBd<BwXS6RT6N^c>MRN4ml%Mh?tCj956D<Q=Gt8<*jp+8mWcQla*lkk@
?qK/+h XJIDYFqVP?:cR<LF^hdicYI%@JqL$tCnEqNFm8WRFI9*qtB=mEkqX!HVED%kW:NaGnuVE4tV>\Bk4dXG
QXNma8 ?4&561yhGTPMF+qn@iuc/nNH6ti49DpB9I\=X>FmX<KmT\\I/&M$%5?//SCSCDukjeW:jc#XXbqM\=t?
>+8E:T ma8$=/K8tmICE6tNy=W6inNYpbu>$lAB>SnbKbkByy!4mZRTlB#taFdSiPV5d:Kb\qkB8Pmt*Y!B1?#a
!RFZTP WJFkh!*+djqqaT+@i?ZER1%qjSYLIGYpeLH!KuwWXdV&h?ll8hKly#XdVP^I%8\BT*Th#dThjm4Lnw9k
uXbZhA HhFD^@mJbqZl<KLkW5u\YVY*!IuRHC1qWy=mj&kWH\*#6FR^eYKN=6#+81:<4AW?cnSTG%W?t\$?qB5\
iSGKjS u\#tKLXm<YbRHkN#MA$y$GSP14H!ci*V1t+ey$+!bWyQcnMScCLc$B!#Wqb?w<m%Xw@XW?+<**El*1t1
e:WdT> %uF5W6t@&e%lP#aLQ/:\PpGEjSMj@+Fc?%1/N\5X>chMy$pI%bq<?RbVI!JBj?It@w<8Q?\D1mYNW\YW
e*4*<M dCPCWZ:MX$%K#!IaBap^AA%K=KeJ?/iDRCMeFt//=LqbNkWe/Ta#j!a#\$MuM\T#FYuc#Yi%Ek1t^^!u
^L#@h\ >4Vt*!XEncSyLBt!#!VXXT\Cj$u?MJITnhSPjC$N%JM&SbLP#kABDtTwSGVe$&XP5^tFHYVDPDkkyhVA
!>X4:D T1VyPpuNdI:Vbnn%hnnSZt4cNRWJX<*VYX4%#=d6h9adIXLbY<>KB=TRKNi&SLQ<dMAidHwdl^>S+%6l
GYmB?p 1FaP5+qDt58Pm4=Yq:y&L#ELPF/4Ga+MPu@WMI+FCNhMLMRC9nuJTAdIi#am<Rt9nwtI+:PQG*DR?NGN
:Ke9yG G\at58twe+tJEaqFd<Jy!puWK:Jw1tyD=K^+>Vp<niHW6SuWnV#Nt+WCZw9!iqIDu%6%dp8hBqwLm%kH
n@ItHl w%uQ^6twb!ACM=?y=>u<$LA%J4C6L+@N@tdu?hF8HX&lQW1?DqY#=:t>^ZPF=NHZ<F!Kakli*j#cY<>5
EdA!/d e>nR6^Gu4R:q%\!V4iuR&tPWn6mX1cKW#Rqi$1!i%?Hu%lHyFe6i5PEn\=<jam1iDWRRnDQDSdGWY&Ri
XZ9:Y! Y^!mt$?un=I@F^bGw\4N#5jZ#=G>XWpP1?kBVLVdH/LBa<Ru:6/py5miwSY*uMniXq%C/Y5@d+jnaFbc
pdbCS9 HhR&PHY8=*5:D/<l%W<KRYIR8TnIFIXWqy*#yNS+LT4Vm*>pwI>dIn6mIZ$^\tmi*yRX1D:qDyZuEi=9
t&p4X: aLjCF9QX#+?LC1jW:TtEit%E=kR!YSL4nR#uw+%E$lyu^VG>L==NamDG+41EbP=kyRIEZhk!$Q5wciPZ
<<epGW EYSXa%Gwi$hAq6y!LJaC^beb:bNa<&QSdpFjYPDmQpt::j\ImC4Q4V%MELaHT+6?5k%tna%GBA!F!6wR
<5?<cn 1amQG\?8>JpIYn6FNAHuMwei%=SQ:BM^TKMS^jh9eH<p1uaL98BwQTc*>^l/$%&N%Pn+ZKc+iIJQKN\I
+%<Mdj Y!iKYDbnFN<Ju:+/b?KXjY^?Lm8PALw5YIP!\/bVu98Jm&4GGhKZ#<@#uk=T!5dCkj$?<XXhdk$#^/ll
tpnB5n R/G@RA+JtTe9\MGdSpm%MZZKPjqnwVKqW:M*<lX!IA%*:mVd$phMqaHF%qNMjB#9I+1cLZhc\Gp!QLb#
tZDmM/ 5jc*wAWEQnEd#XniaR9K*I$\jVuFn*d&9a>kW*NW>G+\VD89y6%nI>cqD^nk+9dCy6*bD:KB48dJ&W^j
A1Awel 55*+5$9ey!jaLDCi!NnbN=?>15Q\i1eRd/tlawVSSYCV<SG>$ERk4dcp6jcAmN@8QCV6>H*JC4bNy+yN
1\FtWi bDQXXw9*n?y$^Pi:QNlM4eN<S8Laa=KE6yL:p^!i8qVQubue6T!%Zp4TpwS>bQj5>Qe!DdP1u&h?E&eN
aSX!tW CbPi!*CaVbB=p?N6?hctW%^!FeS^Y5:1Ye4^$5FY@cQecbe>$akCjK1C%4R&:/A&<J5QGa%++mF+eB#=
LCme?y lZ^SA:?+1AeHLcC+Ib%iYVLR<V1<m&$n!Nu1X@e5D&@abimaiYQ^X4b1&KAuc8RGD1=^CM%!h&N+j&L^
\></KI :JM**>+D#+/wC?um!m/eNw*Xe1%jXuB<&nR@GYb/!aRh#p\XRjdbi6M<ttp#8y4GWuk4<l8SE!PqyZSy
:<:i># DIJJi#?AS*k#NPpC^NVXmaX5kA/PidF5+>HAESP:K*X?mC\8+/WjW+KYaCq>G?XyhWl?m+9Im>N>m:QD
%lY1E5 T@#Be8F::PbAcEXSnG4<GQ1:bL4e@Gmq@wy8\!tm9pntRJIFe^nl/c5Ip8$IRRdq//qkGK:1VT#VcRPN
8#<l^w 1iV#nJjV$<8hJR9Q*<qnJ1C^ZB#A6VquiBWPR5yi6$*Ch+d$cjS6PSi+9tM\:&eeVcL#HtAkhW6c>ZM?
yYpChl :4dG^:T!Z41c6A?y=$Wc6L<Y:hkmjwE<GhcjuL^\4QH6%F=!wLKWKW^cu>hA%:uQ9b!qNNtt?aX<GNm5
bD+18K 8JPy?ZqwI=@K91Z?Mbl\ZXW+VSeqjb4S9yD=l/ZWP>&?anuGYDtGTZqTT9WYJ1#q4%NT5KF4tPqYZbeB
cYXZeP $=B=#RJn&P\VpXuLTY^ZaZe?\*6WhCCR@*EXdE=%MBWZCAL>4=#*RHn?m>I/9L!@q>dl=Ztw=9Xj1hDj
@=byd< pc^@wA+C+ZtwmA/E:!Hw?++EIQ\QRQQ\*KM6AwE?BH%j*n!kB/Al>>Ydl?5lcN=:DnN+\A>Be>$n\eQD
CFjPip @RA$N@Tik#Mi!EQR>\u+<QA<BH&j:BHQR&!N?#:bI=/H&Bw*/L+u>lBdA@Qjl*/I4aF=:$H#Q5VY\JD:
aq$4:u $A?^6j8Q9ukjbG^k@u9RD#G&*<=#@lkN?YjNHAnQj*/C<%ibuD?h+ED@TKYe>\>8PaN\kju?:*GN=98@
EWmK\w *#WcmeG@&QEWEu4bZW!L6aM<HV#&WyE$B>$:G+pqHEM!M#!YdkWJCYQ1HVA<WNYTF9q+\Z&*c1Y:DkDd
LHWGu? YT/pah&b\aIZHli9bSGSA+X&XAjKW#\1W$qbRbE$M?=<EwSk*jp^BE:eq:LLVuWiFBYbVp$5Lqcu*V*q
Fm$!ql L#\ywI=kQCmItYP5Q%#n6qS:M9d>$JEaid8P#F^=Y9\VRm=*JKCT*a=$CNmDId4e&6*FJELS*TY5&1</
SbLR=B 8#D%CBE@jkbXZ>=9mJuPZ*lPY!IR>/6dMEI*?cDi#==>\5?E!<4<BwjPXu45K?J^JNN+\ki!TET&c?VI
K=NIjK jPnjTQ4HA\/<i9G4!?6!b!WTh&H!>I?6lJu4<8BL1M6!yIQ^=p$HnT+!XMFa4Q5PCw%bEp>^%SH5!FA:
%wHicY lwNC\1iH*n1kh!Maj<LuHAw!IeRiJqjA+Mk^\<jFekW9Q@tt6Xu%cLMD8SMItqlYaXb9\L@1S@KZ*eG%
jRIkM^ LM&VAi/h%qJu1Vi64tlY#D@L<nFN#ci8MjIK*?\*9Kmu4DMkLc@Iu+$+6hJdJWCpI/+ti:ahK8d!V6Da
pi8HK< Z#SVR^^GGEXe8qAdZPHd9jD$a6=EnMiu4khpi#WwPtVJF>l*@uTIeQYT!pJ^lT@:W@Ht=@*ZRij&1nP8
?i=^qD Ju!IWkVa^QSTkYyE\q*?mAlE>ZXG:!ltWILJ:SZW#*@SV\BNDb?u!1+ItX56d?+>Lt#EuBVZJnFIRPXA
aT@<hh 6i?uuqdYT^N#jF$w</PFERy+S+jpdtM\^R+!^9#pQaeNF:#LJjESaE#:GRq:1S*^BDtIGyZVM?b$IAY=
tt4hL! ?IKT8=>hNtt4kau1LI+YSWJTRiFyIRI<=ct\BPhd%Ch<Qk54ktMetBd&=PjWiI>q#+QaWCp!%\Ap1@\Y
c1E:nd tJXB8MlYNukhCCjYWWYcd%B6V?>/?*NAAN9VHmEm$%>LAia$/Ju%iJnLwW!STkLkDqV!p5=qy8DTuqhe
wWCBS% VCq#CC!bQ5\MiHiV<*X&lLV*GI^hw9<uLi&iqj?lC\4:FNDA6DlXklMdl!cXePE>I4XujLK5SF*9F:1>
j1ZTWL =<k5mh!h8EPME>Kt/uDJ16I/SkDcYJNw^/Ty$qNe!W?/eM^::RJEu4ILn!eb\#wt/FQ!a%HJJwE9E!AD
p6FY*# YaC9QHFeMI/Tw5Deyw\k<m6FcW6+ESmXcyEK:Sdmw%+u=ljhd$ZpD+L5+FmVM@W#XTh<&JC841wDQ1ku
itBb<a X/I4=8&SFkThJn>c>iG68Z:DBMHPp8qm$k%=C%Z^^6eJ!CE#\*WyT8/SpE/V>%J6H#m4R6I85VGqBhpt
QuRHcG ^@jq+\jHB81tDS*!NKcplBF^pWy\9pdlahGTM\uW+AC89GiX6K?al=<*t^a^TRm/phZBE>J^N^H:EKKB
IW$iYN >NaPyKee=9VWp8:\K/J!:IVIm\1L\>b$F1dE<wq8DWI$ICWbl9jJWe^MeIJtKm%DDphYppB%?%DlPbQL
/^c%^b IS&\KtBTu!R8ER94BRMWNW&QLXIFluGYD9H+cLbG+8Fel=WQ/^EhZ!S:L4X^pXjQw/ewq^=kw^KM9$B/
4i6&tq 6<Y$D/*F<8@81k*NJ&MlDj=PQbKKA5B<l@<GM$pWbWw=Q<EB@pM6#46?@mT&bWQcu#ZJMn$q%4l:<+E?
cBwewR 5dEhLVKQtH+S9H/Xp8RhPG!PZ:ecPIyhm6yE$>jBdA/tnPPDGqctyALy&iiTZTX#>XJSPED+ij+^XI&C
Ee=#^M WwjuBuuPS9Fa8%w!!MTG@Sa9:X%CKwmB9jT%ymtEnmIld/\ySJDP$lX%/VmJ+TuFkp4L:XbN?nVXZl1a
<??E%W ^qlmwhcy%+yaFept&TSjF:Ck$D5WVjZpq*q?49j\Xj>&B8D*G@RQqMWRbXBA!:L=@KTk>4KK/b&1ekV9
-APdHh 00034296ce400110333 Page 371 of binaries1.zip
RQ>nTS D*Ahtdbtw%ahQ8nnhET//d#A1uTlR%Qip&%<Iq%=<jqPMlS^Hwn!qn9YAR6^5@R+Kn^cIEi^Rn4%<dTB
qR#$wp /<6ePan$PIIyiEB&R&<+dqFWW*C4#VdK!wRud>@piLYbYPBEk1Ayq#N:B48!HGK5<ZqjK=*M<NmjhHIV
ETK%+1 h%Wd%*Zk5&lEKjG&*Z#hJ>?+V<:/Ky^/6T<t15&nIBLwPw?IFkKK=LpT>j1#pSXlFQmi*=Niw#4?hmq9
EB%cS# 4AFl4+5Ky%6Ja\KIX66Ek\EQPLm/jDGSV5ci$tWNQ<QSR<B!c/9?p=CIkSmXX>@M?Jh8%9+4P!=NA/PW
#Dy69/ HwH8:FyLI$jSqDWP9mh1=ImS=:XBwykYn==TYRqAyNtSLWY&ZVYPQD4iy1#>5I5<kFD*/\P+*KY#bIy#
kEkAn? STeSTMYR%hw:Kn%j$DZ=&&Q6=Q:Mjp8?D/WH#=#5F!ZI6&tpZAPXhiR4KX4+wnbqy?jnQkp1#+C^XFIp
qH!RTh 9D+$jml1VSyQERR/8ulB#Wa>HPI?^W+!G<q5AkmTTLnkM=WN%:Wlu/LBp=:I$+KeNlJ\EuhV\8/8/w>p
e<cT5! a%k+WXM5X4HD1Wn:qPB:$R<wYmY6b*=ALB*$Aj:WtC:=W8e/BnERnjhHd?=8?VZ6Gi=%cbG*apWwHe#l
\8XKkW ptQPNP:Wle>JJ<Yi@mRLW@%y^dBQ<1bXI8d>+1t!<ukeZ**p//>dJVbLa+=JKwmaV^<^t%9>%HQj?1XV
JlQkP: l=66F+L%VM?GI!4B!RJH8iyc@YcKDCE5W/C>mlZ&!W@Z86@iTn4e5qAF$K$Gl\!MC\wAKicna@@abe5>
%c\+8b 6EW>1<D%GARiKSFua=jL^XD8PttZqC#qBJej:%ac4m/jYPF4!STiPlcnDldLBWemb>wjKp91>CT4:GK!
HwI>VR !u&bmy:t:JH>AWMGPTb/qRhJCc8!S+Qe^V%j=!?y=+NB&CpbqbFXC1nL$Rjwn4u:Y^<8i&=iq?<5\p1d
RCPwd8 4ScRauw@XtbH4<5dmP6kPcB?&IqX#?^%^qbMR#Z&Fp>CQ$\4qyKYCqBAHpPeG#5Z=1D#mMDH^yJ@Lhh:
6%kJt9 Yb#6m^4>akKa6IjjW?mPSlWc15!RnVB<PtAyFIBMS!9Lb\$TYFXMSb!q:Ww=y4%m!eqX!d=y!Z8D5nw5
^9bnKD YbV>$w#1%S1X9lVHF!6@nL%n\?@H:C#YKe4qh4p!!CBLS9FP8hXkp6^ikTMb=QWlAuSeq1A9\whiyZnY
I#H!F^ TID1MEbT>yl%Y+uqhhVeitdnSQFIDS6V/!NZ#WJkmHR#!CWEa<\j^*K/IZV&BG@LK@keC&a4cVXGAa86
>buj1V :Xal\X8/G&5jq:#K!&H!H:Tlb6%^e1/ka8*DeKak\WL%^#6<QyB6t^6BDib@:=mjanb+%DZLJGqFTm8Q
5tiSMt dBw6%*XC\H\nFJklkKej$D$<QGcAIC65ZRLSYN=5LSiYhq:Rq$8u6H:MFJ1&DlB86jdmACe16y8#D:tS
8T8W@d +MkkK#CVI4dLhjjT$\$nY<yCi*II8EVIcPy\D=kbA&tK+aZXC?ZHGFAnIk/>!8wq@LLk+ZjR<YJjwTFZ
L$^IIp YY*=&SnG:ELEl\YMn*mbRG!Da:y:K8c5DLJXdEZEj5/m8MwPBjla!%>bau@am15RD4@Ky\8lPM!<HG@%
><</$8 BL@DYq:RP+=eqE4k:6^:ESS8\m$1RdZAwRc\:MLM>@8CLVFb6^69TJj:89kq^8B/4NMWit<iV%@>/<\?
FFFXA/ Hl9Z?lyZT*dEYJhZE5#\9lLw:#H55BpdbVEbmy%FM:uR8E^4qew:SjA?TLt^!Tk@jq^>Gph#8TC89V?q
bk/nye Zii*lF&D9S8E!PM5:SE4d^Fe>KVZGD*8Wq<=h>\9M?tRmkPID$d*D4Q%a<<Wqm#q@ZIW/mJ4:dKGC?9t
G@m/lp XT<ph?=dFJPwFJet*8ymSC*\=Aw*jYY/!^JpYa#!ba/nNyP6pHtKRKnClK9<\\@/e4wcPpqubhPiNY:<
?5<L*B RwPyi8#+KQSi?I!BD@t>M#Jl:>/bp:@LyZy*$J6P5!lDy!1Ft4EGG=b^T=cFyF*Vu<5k!Yb<t?KBNBFb
w<k@CT Ne1+M<wDJ/CFG@IDNDKJ&YLHwDGuM8qeXdV%#BA%&/Y?^uhH9L*h&LjVABEMjPSEV9cAX=KJHFcJWRD:
Y?cd?% R@@q!R9&u:KTZ?Ib5LH#w&&XkhJhXKLVw:AJh^ibCjZXjT=p<*ZVKWAku41jCnKK#BQ8W<G<HBVS/p*Y
ZtQDTP S<IS:E#hwlydFL\<VL+V\$lqqXlJ8wuPRESAmV1QwR#5&!Q+VjH?cZiqNuJ^M=46<i:??B:EZI+/e/!i
EMSdD1 !VTGPu*/>a<q@KQ$uPy!Mnya*S\EtnXT+%Y&AdN+:YGM8Ia<T%heZ/KRtWIW!JEXWq+ZIG5eeiu8b*B+
&9uZ$^ wy5pVdiw+V%^qm=^MpIb\t@/@lm##&6CBlWMt*!PDRLHnp6k9$ejjwqS!mA8ZGmL:Gq6CibAZqM#j*I=
TWa<>6 c&RBqJSIBu&JKPjIQDNL65QCXbcWa*%YHFTAIe=l6hX\&Nq<VQ!6EGRht!VB/#Pi<F\*X\&XN&ltY5H<
/wL/>! ^*N4K$a#6m6^\8V^1XB^SY>D*plLZ66m%A^ERKRyaS>j^I#!RI!WcEc1SdtMk+G/bXD1j4V+pBGPS!ua
?1cTH$ +5IClt&+>Xc&Y^t46qL1&+Te<Lde4y$<W&#1cd<EbG56eZ\<qFm>*QWF/l!@l+GT%Lk@wm4&cbWM/wcH
d%$#F! ^wYkSZX+d#>ZkwI5uVIcI@=EmDnY/ddDhH=%A!ITY96PmQVhayE*WDkh\SqP&Fw?1H9>AEB4BYWNKTDN
lRCM<e L8cqnaX1SWNwyX/ae4EBlDtm&Pn+58Y%58Y:YuuF84^!:F:A+:$MGtV<tRGbG/S>Z9B14lVKN\*BWbaZ
tetV+B LjLJ=u5>%?JD/+qyQw51HM>kFteeaIqG%I1edap1uIq1K5=kDEM*JWaN>5Tm/5ZMnMcYiEcNB$KEm\WR
PRVN\> !\R%!kMA^CS\5ZnEP5GNB5HW1eH#=unE1mR41dB#q^Bmc^Jml^B?6^C9q!HWjuAyb4DGX!S?mInEETEy
A&6c6i 4+kBm6ncd$L=HRHC=$kyPcHCm5VcV1HEVpEyV8H#=RBmdVn@nSD6TLl#W%^mZ%mY*&Q@m>DGpSB@Q=J#
Kneii4 B%nKK5tK*?Q#JSLm5Am9ibKXG=L#m?mXFLmWW$4m8VA@8Gk@8Dn?q^GjKELQ>^>jMMe*5ed+^<X48\Z#
dYY^mM Y<FETBK$Z*E*a5PJ>TRG*CjJ#99@$JYKD?iQij?4h!bC\d@un/FeD?cQwZ<5\5::B:\c:$Q9VPVulV+E
8#SRRF jb<:P^@wIYmi?>BeD$F#*+eGQ\S>H@9M^@$A>H&*QjL#RS/C94jXiB/C94jXiB?C94jX?B/C94jXHtJ4
:G:*G1 >*L&jA?^6Z6DS9kjat9*lw#\Q<VY:k$b+Z?I4ZFD:#pu+ij?6>AQ5VX8*u5+i@/H&Bw*=D:$R&!N?:+A
\kD/tm I@/H&N4>9Dp@@:<Hj=C%ki+=b+H?Vt!i>#?@*9N9$R/@EijR9$\@@=R8%??Je#Dpdn#=@$Ij@4hCH<n@
E!Li^C B/@*bD4WJ<tnL8dC/AIhtmB!>a6LEmHDBW\QXGiJX^KGWA94V/Qk=pSP1>IGK8>QtRn*Ehjt!LWTDyn%
$QCJ\N C&<Gb$Z\R?Va1\Nyk4MTNJSC+MV>%S8/cJY$aa/9%ce$#</ZXtdbNcVw?\q?Ncn*?mQtYTIStIXDy5:p
MBi>&Y bCGICCMBw>n%>PbAdplREHC&#1*+5^c&lyH#JMhuP>9/=AV=:V15%+!<DC#K68TKBFF+PtBSY1wBeRm@
Q65?V1 <Y>SFDZENepaCa=j/qLWyJh+!tACZ/y!*PM@1^w$#*C#=@mcBlQ\pkQXHVTWmJ6+#BK$#Cb86IFakbbK
#=Yu$= X9ZSERLec/e@GQW5#h#j1$@T!1XHa$H=Q:5ne$l:<LTWE65>w*%?Rpl1#Kb5^1>eJc#MkT#:!p^pNy8C
V8tJH> Ya@9:H^4GKcTw^S6:4W&X>kqC:ARb^*ALjIZX!ek\l%Zb*lW5Rj^MmXGHq+PuYd%1NMuut&RcMYXZ:EV
cq*AtC $X6e!*>bk%SXAJy^bN6ReXymM$>Xd&K@Q91\M\@@1bXqBXcA1@IS@l%hu?dNN>=\j\&5ibn*N=SF=Ja?
\PZw6@ uM>T?uIt*Ie4bZEW!B+q/VNFcjWue#?cPcNKkwt@+w+mak6lp/p@HdcieN+=$hy5LG8auJG=eXTuqyKh
Y*##DT qT6WcC$@KNpF#iBmc6QA^ENV>?4yXVPuI^w%tJWuTtc>V:CauN^EFByT8<S#>iR+pbnb5+y\lc?JeF@+
^GAVM9 IqJ@ccjH^TTd<k9cMqly%P#FmybHS:c*iShE&P5&5%KJB55m=V?%*qbpnhe16\t6P%R8JBGZ%tGN$m=S
l&jWhD F9:&mE=i1@LCtXM6uIJkuy6HyCY8wM6+p&Bu!H<CTNQX4p^JXJ\1!j/BLIVJH^589pZLpcKY#1^+hWcP
A6YJE& Ku!mp:t*+RMSuD!6S<#**abG>JWMeT:y<WtcLt8e^%l?CyI5Q$BQb*b^S@Yia5SS&Ipu&hF4cwQDJwVZ
9T=8HT i?tu*=pYX+WjYdL*VJW\+aM4>a/TSu8jE/MDJ<iV\6D=iwKmYM&1KtN\+hX#ycRic@1=^iKn?SJS&W8@
^+y6Cu 6hN?mZMSYNiLHpa5GwW<KJ<bGClHwkNMkP/?YmSXZm@/=JKSph<8mI\:d#?#T/!jtd9V!dRXm<%&uC^b
8Pa?P? ^E\u>8#!M:/P?pw#Lky$>t=V$/P&ncjJppL?jPqaJ+6FXpSW<^jcmp\+JBc9A5H4J^@el*ApdPjJ$b>5
BWK=9Q 6nq9$bPy!%*k$inF$lCl>C/ZnEWLbETB4=t6Bu5y?%dyKPkK1VDb5bq1ihLJh4k/Imj*ncR9YJaW=b%!
K8tPQK J<b^pcGmbVbVWwqdp!Wj9LdJS5qT+:<D%56Ti?m%8#HCJV5Dydc?MmiZPPm!DXNW1BXd#$JpT>*iNY5$
YT\tpM &bh1=::E18:Xn=i$\X4N%6NpJylJe4dG!y+Rb6pEphj%uwep1hXt:%G$<HPdF^D5$ilWET!^clHcTMiQ
M/d1#S qcD88FVQ^\tRuF5\VXDZp=ck5C9S@WKCI\dPhFulGEYctaj:1LQXDSI4&8W*5GQq>=#+wkT?:8YFC#$\
9Pe&w= IQN^#ZSYml#TINXQmCjd#%166a<qw&?k5weLI?J+BP:VRRCe^T#B$9#c!Tc/&KTtQ%$wMI!!D#tLiGA>
y#$a:Z &knEmJ*ZV\k9IYJHpkylGqWPBw&>mWc5$w^!K6P\E%^kFY1EJTi#yL\%Ep&^/Pmh\6Dm5Y%b#Q6i#T%^
dn!<4/ <!tAh$/d&/T%Qb6MZ6I:9?\pH?5kY#ZhE9KG?QNWP<^<S6F=e!k*>^wK8cZnRIFRkB&jqcZKwRka>!YI
tuRBKC IDn^/CDjL59uKcdL69VB&4q/BqbW<<TIXXp%=SuI<%VX$$&1w5cJkpW*#iR<YX1?L=EmkF#N:F9TtMNB
j9m+lB TD^u?PEBtdbQ9*XjJPHdG9wnenMHuh=Cy1:<Iq^A#*VM$^/d$?iKhGk^Zm1@@^DFwV#ILPXa!M?M/G1K
1HMTt8 C1>ml!WBIYKq#^AiNFbAlLQuTG#9q=i:8N9%D$hq^hi1mlT=#j9=<iL/=Y9Z98CLpBbV^j9Iua@tW<H\
W+EL^k Wn!1GS>p<KM5u5McR#$^cLjE\/iKTui+kBl\WM:5?ZE8M>DwQZ5k>&tEGkj>tBqByWH%<\EGnq<RJQ6D
HbWS?t wHc@#BE:$h\VQQQ>6&1yjq\Jnmw&bFV9=n:=L@XD5h6?*PTIPm8l^!ZSRE+:uV@4PmuTWTWR4D=SB8L!
4e8X4^ 1Zkc*Gc>KL@h&+qTWHBMYYJn>Ski/Gp/*cee9T\p68ckcVdAd?4a@Dyi=8Z<RRb8myV%FabXYk8&=jcW
NCBRN# hp:Je:au:69uI1T1R:$NuY?@cHb$HJ:tn:ukbbi1e46?@FAhwJ1wQp+*PCTp<MVA5m1TVTY9ey18PejJ
-AptJ$ 00031c16cae00110333 Page 372 of binaries1.zip
\KQ9kX aXI5WN/P^@PSl161JlZYN^>GC<!^^NRDjbpZ!qDqn@y>JL9&t6Yd/taSXaFY#*S=:QLu8ebAFNicJpY1
?!@=!N e<X$hi>5@b<#PaduEtqjcXF#^pBWIJc&C5uNpy!DLh?i?*BdyG/l5:iMaGM\q6TZqA>8TGBJJ\?&\mwH
pu%4<E He%+Nm%puuyY>ljHaiFZqhch1V<u=uY\j=^yjT1yi^*#idMDbcKau\Nc=jTqqFahHhFXZ#n#%%n:VY/8
4YH!hL De+:e@QR1*BVTbk#h#BD:\Cm4<SNt6^/DRLy=mb&c^t1BE%<qPZk<E/?nJummFpnE4y&?cc$jT>@F+J6
*4tmPP S$@*>%JJTKq5B!b/b1ReM1c+j&FKaL>+ALMnhq=!+CAYemtX:w=%h$=*8:R#n%kZEpk^mVc?B*Hl@t9q
9qDE!< wPD@X#9ERdu@c+RGqA9/P$ID?1eLy^=EcQ^%kZ#*l8<QtR*wH?^<wN!@+!d8eb!B<n\A#ZYj&\&W>!F=
15X9*R *?$^@lnN>^A$=B/uHTn@A>A<$Q6&L6CHwP@^L+PCRA>B**QNGlVE>RA$=N/<\R>Ae>@#9KF@hBul@\H/
8SLqn% IddG#ZXj9S>mc?B:4AWKiwm6kZu9R#@E%5D**A<HBV*E%5D*mIBARR?^Nc=:GB$w%$N5:h+NQyTL/>?D
p^QF$H Q<nc\PB:$A?^N4::&w$L<t?lij+6NP<@M^6R:9@IdQCC?i+GCK+@peb@bVckwH>pN9l?#&^A@?M>lZ?W
e/AL8u :6<aE#DZZ>Q>G$u!y*T=8j<wZj+@eDZpBjQ?=+\JWyeJwBPhk\SLpkalLwMWubwREj+a1plwBR%F#R9%
GlJp9b YudqIEhF:8LK>LQtnapM\m$pB\*leI9%T$l:NWhCeWWHE*CXJ<YRA=X!8?ITcWS=TVGZ#XKwqSh^@LEq
BJ<\8\ E<KnFHFWM<S5+iG#w89XBd6/EF^pqGh\cEdkqD?ck<uS!j6/RhKu&KIR+kG#NZ:1RWQ$h@Kd8Tabt$%Q
:yNaBb !CIKa@W6Gaqpa1I&^NKWq$%aCnT*CLi</lFB^I15hZCiAZLGIep>TC4T>ehM$N?&GS!%=qAkih*HkPYl
mqGJ4F %%YEpdAAj:nH8q^LFJ/LkVIJd&4ZwtBhK5Lh1tAkJuR6V5c>WLbnqFG6I=yFI@%+6a<&BlJ1C<udbF+8
dj<tYI BPL:w\bdQW5c@HtknMSt^#KK^C>9mkXj#k\j@VP+I<W<6wa#B%nCWy#LWF1&h!JL*It#1<:E*^F1DESH
JX@RMA wJ1eD+EVu6*@8Eh5&<Xw:j&MuK=$!VIiS9%^5CqZ^M@&I&6MPt<k1*KC<LBR=dk^PcMeKuAGQXDM@qQ*
uR61ne Q4@qK1an9!NRX5FbGhS+SL\<P&TY1WwM+@DVa&>ReFjFla=mVm=$SRYXA8Za*iiBR&dTcumSCucYC!N8
9KW@ua NRc5RjCBD5DGpY:bSRX\GR+Bp4@<q$X?M@pSmHJHFJ+<EkIQ+ybmDaIB*9B$!5=uPZi/?tY%DkqY8WaP
iGmTAa CkW<JAT*cCCtQ=II%*mh5VLj/FyNDLCy#pNRZGtt#M&kH4Klyn&91Bc\JMjN6k?bV>^\Z/:*nJ\!$ytq
ytHw4t b*Sce6$!@:SaI*%k%llu%u=h%!<YS^RiRC6NLBXFHnqWE8?tL1AhKli/\aeXndp\bIJ+NVhqIt#\+kqZ
NuYjVy aQ@:16lqEeR?@$L:5SB$?/Dp%m%bIywBbjb4i1MWDFWk?9F*W%D$G%1nS^Qe1My4TGWbeyc#6Ct#n%j>
4KwCKn XB&Itq*mSWm4+n/+WTDNd%uG\McDklGE=C?Qd:lL#/&uqqZw&h@YXdeRAJ5/Iww!BauXK\kcmN%m/n?e
*6Ew8S Cueb1Qpn&P:Ip%pjA^9k:M!B<l&J=Z!HC8qJYuM9F<Q/uB:JX/@#<XDiLMp:bt/HjEV\yXuFjNK9MwGX
EZh^+< IFk%19SI$CZNk\k!NScEpJ8ucJqiRRu<pHHiJX#@t5q$#/X@nNNp:yXiYIBuB?Bdu?ZH:%$Gb+<mZQ1$
9Nhw=S S5<&YbB$h?Zwh>@<+11e:pmWe6j*^bVm:VlSh?MM=1DwZ@GK^1^R$Z\j6Qd5t!IKFwHm:W5a?T#C:19S
MkqYZ@ *PZm/XwZA4^!A>ku%lDGK*5C8X>aB%ut*AZ>/AmC%?ya%#LqXn@1$6YTpIyjY#%y^G+aY9XWbh6B#jQ$
#81ubJ C=*q/yBk\V54RP#@la%i/B?:e5SF$?n&KbFXjajpP4cH<DLyFWVJ8S<w>mkEQ&uNR6>yt:Wh&ACaG6RK
a=!=%u ^*%G%Jt*ild/e6:I8H$1N:q&KN/LCd8+A=w&XikYua8n=pm?Xk+=RXYatwwcZ\GY<T>ktIZuK^#T!<N/
NVE&bH $Mk%+HW<LP8A5AE5!1tISES<%FWc^Q&eEbjl1NCmui#bTL\EMWL1nYEmBGjLcHuVC!MHB%@T#L$GlZb:
c/4bl! E$Atd+GdHVHhL&uR?yQPYB6%?FRVBcHKC#mT1VltC*+?SBVE!R^c^ha*X^aYK+m<W88N8\uTHym:SV<y
/pR5lC QMAP$h%8@PE!#RNTmcp4LuM/8\Kaih8Q1clE!tK4KZRa*KZw%5&V4MJ:*w?m1m>&IHJ^PQWw!nHd&pXu
wmVVLM %aZWLBNty?^9Fwm?%denJit4ZSSiZq*LQA!&w*<BjQMI&8%ikDR%tnu*qMu$ne<n%&hRNSh!dLw+cEK^
A=u+NS Rub6C/NYK4Jl=5DLyIFM1\:@aA9LX!VVDJ&pa8/8:6N?!\*ha?JaL9MtR+yFdAlYEyPL=aIaJM<KmL&#
!e66== KF?&GaKT<&bpWV&^JyuXi%e>t=GpEGdD=w9HX?\ykNQ&HalwApp&k@uu@B??$J61PFM&>%XPCZ==4iKP
=5#$N8 @N$1Y/Dq/c=in44HMC>!!4:>Zum/?>plH!6CbjhmiCaG<&jH6<Gqq!L\PtYc+N^mDB+%al=yLQhXWE6m
LIw@LV yGIPtI!=LNmNRpJCQiH$ha!^@&TH8t4+qn\PJ5@tc68nRuIE9^i\ReZqR4MmX&#/F6hK&Ab4QmtJYLiH
59imd! e*TS1mm>!@Q+/^FE#MGb>N$S5\TBNZY5jIL5BH?Q#%*+<te4!pm!6J/b4?!c@bQ#wPK=Ja+c+$$NGkMN
JSIHj? QcwLm^RLLWTj^\*DcAw&8p*4V%m!lleml&aI8IM+LwQ1\YD!Jba>#9d<:B:Cq@\:4*chPAc+8*@$Ca9=
Q/Z\t4 $EYyLimT/i6m\CH+q5wVWbSE&DB8aMm\Y#CSy*1te8+kVpbS%<%SCP?RJWAc4a@D+GYXVbn#FIVE:FcZ
teyFtW W6*Vlldn1?V:w&TuBu89mJt:FK1/iYFA#ZK5Mm>46L#PpbtM4/wLL@l6LC5cRb9p<>=c!5\PZ!WKpQjE
4@+Ih% jEV/I9D\MuJX8$<<yj#FMejnTXJJ+Dy^l!XV>*NL^$lFt?4FHWh+BNQEbN%ihMWQK4!j$u+5\WSnp>u*
*++w&^ GH<MtaLlGMw:AN/4T%T&NeKyi&bpQISN9Y%hli5y&DLp+>#/tV^N$XMZhZKd&C<:5Y@M$CVTDX&n=ahl
JT%kMG u4%11\@ell6=86w4p+/cIu=$*GWJupn#6Iqw\iyiFINy=:pZ=j\9/*tR8#K/>Fwt$<i/q%kTuBP#J#++
$=KS<? 5SMy9ItZAw?^Q$FlZXPbyyC%/mnG6YhKw=knPuh&tpHqV+:Gut/=66nNdnKb>Yn/Iplkd8/B/WcwwQJJ
SQ49T1 V&QaD4!$&V#qZu:P?l=c4C48RdWwSYd+waw6j48K==tt5$4=55d#n$>tc#Np?iD*NQS*lRNcQV/Nni^b
^E5l=e tbcm+Li%j$VTbI\<4L\8H=P+iAyLt^%=1bKA#W5Wb$\SWhM:Zdkni?Z8t6V8\Q9BaH*u#S!8akC#$!PQ
/?be8i RDM^w>XSt6/SV+?/%5aIw8bjVJ5ajH1^S:QawKjm!j54*LyqTmQy<y&/M@F?@lwnKwuu<L8lF$#uCJ=Q
/6Rt9A SDh?=Dnw9=4<8VTS:WV?e<iZP6l1%$^e4&Mip#yGqPdJ5V%EAt@m6YHw>Y618y6Ryy\uPMHqWSTGCB>4
@&G:?L *D:aHMG9WjeTNbB>WwP4+I!Y<9uCPD5?eP%X/VV5FdJ5tXQilw&w5\e#&CH5F=ienQTWwHZQ5yduhTy&
mI!$Ky LWQuhWbeXIChIW\PnGpZanld4QhcYm!Qd<E4eFL^mW61:8=l=4Ga=Ij@hAl>BuCi*$+<b?w6qB<5LB#u
@&M6=W WaR@Pnm9H6#D\yy&eN#=yuRy+Dhj+#j/*ZEF%dFRTdF&6*^uT\=a^C14#k14BtYW&>H5q!8kFFj9\u14
iECX*# hp>4tb&uuF+lh^IY&H1@YXNHLWd$G#dWp1P1C1XM#qY6mDH?WYL+*eJdHd8:I4w!$*HYWYw>YDbZc$N!
B<<uC+ 6@kCJ$>!E+?<=:AjSepTEWQ^YPt<CpuAMd!:TiFRHj$WCZ8#dH?\h$P+ttY#P6c9#ql*yh\PQd!:mLt@
B?Sm/N Ec5\tk&^TuFYNZ>Xy?BH*Xdn?uB$q/R&SLJ#9<RIYM!K4/Ci+YL4idl=G&&<t*qedn8C$@<aCC4j^#*e
WBXaaC \4c6^VJFAmRA&RJ^FIjn&Gk&!%84=R&^1$4\:B**!^N*ip4=HdFIHL:5eu#EKI>H^G*Q^Z:#TPWyRRZa
QX!B!: ::A<YV1G#AXhHdHpWZ:+ATI9SH:RI8iGS<u<NbP\IQISjFh=hy+#b8VC>mS9Ll=1Z#m<b$<abhCwuBP8
Rtqbe? IM+#LRS99tQS#*9L4!8^cPZ6t\<PuW8?M+SG?mB8mh99:PSV!4tCd/5hZ#phanyV<68C=iXjMEyIX+&A
9aM8^q +qCY9^=IM&RY$55uWmu=yJ1Gk?HhC:=>iNPhkRSwlCCW5uYP5+58tK>?MR6ASVc&ySIuy?6=pymNKm/5
$e?WZQ d>cy#\BQme$5chI8LCt/\eH\VES%n%uapTyamhQ$puP=HBG\^C%GnC+eA/JKBLXQW/&na/?/W4Z@YT$B
Jd6\ep E#NM$ld^Bai+n/Tj<DPHcCuZXiRcVd4Mii4qjP4qdAdSGYT5D#dh>nct4m#mjuSS4hLeVNIBZ\wSBR=5
*iX+p^ 6P&yM8d<qNF&8>6/?FF459ADDj&@Y/1$C&Pne:lX1@aM<48cq&5\Em9uu&1JFWc9V?yX1+e+$5p8h/G=
8YQu+^ >MK?Z>XNhi4*p6c8q?8!+RHZKylSZX%Pynj:Dw5QQtlbW&In=kwp4Ick*MC&4He6AnbLRy*hVuZYCkQb
J6^ya6 RAtD:t8klZPF@yjnu4#I^EmA%X+t+i/!dAPE!9HRBbN<>IblJ$q<mYjC/$:F=Qaq9TcP^hmm+BW4>AwH
&\Myj* R*u#H!j8MAE5BKuE?Bj!4&t^dW*p1W#SSW*YaGHVTW#D?8HHw6l?uXQw8ilt=XD8LMp?T^Xk=P6EG8Pi
&=t8e9 :G4^B9p%N!q%?b*cAB>AF>!yGe5!pJ$dun$*kkMknG#?/tu&Ebj1CWiAP8jpFb\ckN$NCRVL+YCYF1:D
iR@R:* +MVtW5G@lFPnBb9>+Hbn=*:E\^$k^>$6n9lIDPItB#p^Wcad9?/W+^qRW8ZSjyLj&ynk\QjI*WbNl?>E
aH+i>* G+1\dF8udb5RybbDdIH\nG>c>t&itjnt+eS$6AJhB#&C+jQJqC?+B=Jtd8KuGV8%>5u&tmaX:M<$$4^P
\V&#Ed D?Y?HRDq:cSK1WI>1mV/=q@#FJE6&#8L1\4$VRw1ba!dXTAP$m1i4ph\P9cEV\mYq?l!X5E>Y6T9G%Pw
lLdN91 :XAT6Z?mEGwtNp:HA@kW=GPdL\/Jm1iTqBiTXB&W%J=ij+c/AR\%!>m&MQ/\m<:V9YpbK8^jek!LpWD/
SiyBWB Zn?W<M1t^w>j6bY8u8%yLw&$bR&d>dkliDwFAb>j5wC%T^cFt@DG%q@eRZ/yj:J6qQL>MP15BZ<C!l!%
W=?Sjp M&ywVjMZdNSA85u5DZ6%G%8%PKdQDPEFw8HVYPJJuyq&R=+Y^+dISeTeAGXWumqDFpp6k5yq^q8$+iCu
Me1>m/ ^cLJXtaAP*k=ky@\meiYTZW81Aw!>y<quyQIkVIPb!cVub/=\DD*k5WZGE=*/91a6ame*V<d$>W:MJB=
-A@%QF 0004168fb0600110333 Page 373 of binaries1.zip
K&9p!$ 1E<:J&+<Vq!S:XMh/dZAa<D$mjVpI=KTiaMdWdewPwiLJYQbR+Vdj&bNb!1HFdM?mNJkK/bl!Ge?iuy<
KXBuMn lW:4QqtKhhaq^#NEX?m6X>HI<=NH@HSZN\@/ek=#^j*A=jT:bH8jq*5<%p@ieCc:%><NX=/H!NbN/Z5p
HLLZbk 1u%diW:W<6KS5IikEq9L\qin#H%8?Mj#B4eh&XCQ6Xhc8KdPa%/4Mnd!GcudtkhKY%*Vew:%??IYRDY@
kw!!5j hiMeT?\^MS>bq6al>Dku<S/8X5i#TRjGZRWLbQ9uC*&^qGZ#q5ekLCP=JaZe<u:bhZ54*q=?/X/JZ1\>
QCqK^P $i@l!j$^8K>P9YA>5t&Rq5eyT5Fn%D!Nm5ei+$F5P**Tnd*M6m*h9ZX8e<H>n$P*PL*GQ4@AYX=VlD4m
ZD?!bS >:&wqZ9JN/$=!VI+qcZ9ul/tmin%$>6K8<@:8aXMdaL^ZJ+eZ/>#FP%4wp<B\Qtbe#\ZIta@qBWF8wXq
<Plh*/ #^::=$VG:a8!<m#bjN1X=VG/<9ac=*RJQV6$=!^V&&>6?lyR5H?5<\9\#i=q=Z#l5SZhL>@&Au:Huwk5
\$DVLK eq^BQ$w4K>y^=J15@L=jKpi#D#l&qquGQD18ml&kB4>Th$u:hyR4/#JDK>6DmM?F&9e1EC<8w6!?XGYN
QuHHwe kpwa!*myI8/!45tZTnpe%jNWb:w:$?=K+XM$j>\9TyDjLmnI8yH=BWVplW$Y5d55F6:yb%D6jlWm6JB!
CZ+BEP 6*!&*PXd^pF8XaTl!Z+bhq\dGWqRbhS?qZJ+NV*<9l^L/XB8/iDF+%CeHNpSTk:=$mHcuNkB@QcqckHY
^8^Q=e 9IPLnM^JHDpTuIt>ck/jVSL9W5ZhJQy9TX=LW/89He==IeR<&kjjHXQ6+\JmpaDhCXDm>*$V&LLI6G#Y
>iQ1@: whdYFaDi\PuMWG8c56F1A%V**KC>a8&4DT*SZd1Py!<cLYZ&k$c4qXkBRbkdyW:eyYNNXLyZ!cqNqjmq
qG9kYP Pk*8>6XF>l@1!lL4KqFXuuy@8FK$>RP^X!K8Kc9Z?nPJXipl^!nYiJKSGPAnXaTu>Lj*c9+mDQZ/qJTG
&i<+n& i5P@cuSMFipTc4E<mEtjHXCb/b=d:*VA^G@e*i:Z:XSAb!Y8Gda=?Y==B^8@DEbc%@TTyypX/GwG5=Rl
JQ@MJJ HPpbL+6^wR9?a4qj4EF4Kc5:aEA@@L!<yKE4C+q1FD6#pB@B1kl@qu4%D^Y1@*!C<V?kWM$y!jZdmRj9
Pqk?/c 9*5&A\YD@w6uM>\<9#?d+aa<?G#tL%VeQ=PH+N>#4qD\:+S+:!NN\iAHwP<:pwGC8S?A98>IB9wHK6>@
mc*6ik kL/QbQ<Dqi@jw*u8#b9*Iil:<?b:CQwiq$*wH/l<@^+N8eeBEQwHK6?@S*QjX?<@WQu?A#VwQ9SDdP%?
kK6^1$ jy@:Reb&n=<5>D@KjC9@Hj89@Q@?Sw#@me*t?\Qya?k@CwD@QZCim?j@j@*@SJF1+@\/N>Y=PnFMA@#J
@mZ%uq XhtJI/6l<w*>np!RnB:cPJFTXRMY@C^EQSALtq%*RAY*!\mDGG*<LCLiSa5jkYQ%y@+8RaN/QM?tPWV!
dP%NDn mP+FZtmCB6e=qSbLcqY9&VFX1jbHey=/mtNS@>BeT/=nhEq+j=klBD1YmEVLccl66u9^Gkpikc66?BSd
k/DpNT KZ$YF:!TQ59ccqImjQLW#I*@JBnBc^<IA/uTpdi6CN8iIeGb+%?HWHe@KYk#R@&MGipQiI58Iy1nPN$w
G+^WZP y+1+^6NSLN\PXT=%*K!RZ4anR+c4FteSCJhN#k<i>M:8+jIQu?/ZmV+$JY9tJC/H+FDLQeQFLu9$DD!p
9$R4mm 6Ml!\W$6^u?KBewS+wTWNnwDWa=i1mP^+!BcN6CmDcE*T:ttqcjDPnL56+5iLXaiIGQVbi=#?Ri>P+KV
$pdeMF #<AqlCpJV&Bn$b1*b:a=uaBG5GQeiPSc*Pj6kj<@>9+/LK+&!^1H$WILLS\T*KYwK6#h*h*hLaEwd5E6
*p&y6\ iHB*D+Vk:k+Bk464nMCZy?jyuy:8MMNM9@Ni*@Xi9@1DeEm6e?=#:uZ8P4ZZ*t8LRq?k!RQ<SFiHy1<W
E/11#d chRWP=V$?Y649Z6BI%hAaSBMk$&dSK9!elAKPhYKIi#R+qL>w8B%PcTPVPk1C1+=w8!^4EM$udKDTw!E
+eYK?n cE>D&aVMSFt:&*S%ejLF>LW%FCcMcktEP9AY1cTiGkuNCGYa%mwS9MI^@mIA\+Et=M:=GNY!KMq4ut!>
R*HGj4 X%!=KpDV%$>M\kSl=Ry^!I8y$1n^FWh$^#MIItTFhkTn6SIiX\?@yB!a?YIkAnibLd4ww=Yd9JPy:Wc4
9@JGCb +lhBp!?Bb<Vq:Pe$e6Wqq:6RC\#A/>=n5!ee<4ql$w=<Z/VK:jCp4BQHadd*GX?uV@>K8lC^atPqHVk1
8ceG9a 8^4/Je5c=Q\Md1ZpiM$cVYF@CtpP?%SqWTC#/\ha#XLyluEMZanWXSWeyTEC8ESCyKkmWjyPEeSHlbCq
WPHT=S qRVAI&6MB4DCFch<!kZ/n+&\h1>Wcb/QH8NkT4D%knBX5SHAe<<clH>mqt*ILTuACnqNwJejCFVe#??i
VR@lq! 8t>jbS%<RmaCVYu585\XX$QlJXYRjSIP&Mh8ZuDy&WeVQcZudy$T%VlGB85$upE4hWh^5IYDib8%<Z9h
m/T>bJ 4a*eld$BGF1&:I:5l\\NSJQ#FQELku&HuP\Mwkkb?K#!X6XVGatkA*#EDEi1!HS&w1ZTtj%#MTW6:ca9
+DY$ue \6<uB:iFHh*RH#ZJj$?m4ke\6VwKT&\Z4^*!cyWepyAWBYBRk@CCyi$MH*6e!<?5H\EWQyGWQ*tJ9bcu
?H8cl* HI:YCm$y^QyM*iY4XR:CEehSyallMR>W#95b+1*=tRd*B%b5L%TkeR%ZNhVD>qAcw!P?JCF$pWPA6j<5
NeJ:R4 BHwVSu4^YLEedwJchHiejPJCy+JkTIaBA^hWA*I?>l/S>TSAw9dMSMb=@+$pTH+/=m5q4L*:p1idttLL
DJubRj A!qB1St?bN:<GT+bmm%GayjEY\9<QAi1^FGCRY:WBdc^ShFZeQW6>Z8Ta/tGc5tD>b*X6C8MAZF#eTy4
86#1X: J5NlWk^pic&Gj1&^NKnk*a%9pZKuZp!R6:wyY*\H^4F<5JVV%j!=T#kjl=wZdD1R=>H/9aHTbwZbM1Sl
N#5dP^ /#uyTPk?GtWl+HPXGaVZJ>$@k?*&=/dRVaWe$VVc<=nZWpmD%EN<#QpL6HNBEkXY5W4M^Vm1iDm5lWd!
A=wTI* &W4=jD*\a=N:H6H?cbT!:k*EYn^/q9cbJJj$?hTZjIZKZLb<*Emace&bJjn8&8\#nEhn/ekq?!QDLAHk
S=G1=5 wImDy\ZF#tWyEp8qm4YWbd%t&qWJXB!:u$BKBYcLIjJ=S%$bFmdTutM#?!Iky4VZPaq:\*QQmy+SZGqW
e:wHXW Kn@4%mapLdRu\@Xl$?@T&RR%G:XEmHq\ck?mY!pFJQNH%&bLF?W&^N8+dYDEEkD>^%&%@eVbNR?hc6l:
PG!QJ# aiXEVKq/W/QM4QSIKSwI!ttl5d/p!MipFqJR@bqE1#d:VdIT?D#k:Pt+EiHHpE#BwcK*TJQk?M58>y#=
m6p9+y *LWcJ+VF9BBe?W1NN*^/B6@+!*H=Dy1uTNPC*#dZ^GVuYdnCndYliu>$FmADVu<9b+Q^ibWQ@Hlh1i>i
I6Ik9I CKpAk6B<LRe%!Y6TqiM6MR<B^PJJKh#%bKV:b1q8VMMKWlG96q^h5H^>BZL58InJi=qhCeLADV%?4H=I
mZRN#6 +cFVnkJKPu:$DBnCTdI9mAl:*piMG#4cP^>L!!h@ZNC1GdPBuM5?=1G&*i$8<QW<cq4um+$u\^^KKR=&
IjlACC =BE$uKp&!k%RLAR!GR4EYT+iQ@NK8H6WN+bDte+y>KTCPyc?%QqhtnjYPaX&SRIB<^b@+ikbHXlEewmW
dXKWp# HhRtmw1tq#Y*DNp8<B5:&mDpBeKXiSbEl4EM<bc>/A<l/Vma\qLK4T5#!VDy=kllP?G#KYeB+4<KF4F9
E?>%qT jY%LwX:FqYPFCTW6W!eb*YQT*JN&4q/hIRa?mbdch?hIkLV5PQ>e>9tBYXpQCWG=cZ>4!GeGi+$kDck1
XdmimT ?!K<>cKT@:Y&jnStw@B5LmunF\nFW8@nEk#NE@QW%eIdm1e5CV*HB++#?+WjpmR\yk!&j4b?CT=?!4K*
*=Y&e= WytE:Gm6FAmjmRiR<c/pFYSQ!FyZ5/yBu4Wb$qhY@M=i<<b68R^j#9WyqAw48&M=BFn!l4q&#CA$ji!R
iDwLQD N@eNI&C*=tb%!5Xt44*w1=ZZ*Db6<c:&jBe1ycp5p<LFQF!^lpB!muXeFpql\A!&8+5TPG#Q?YJ8S46T
e?$Me$ =>$!T/X@GKkpdu>y?$ee^#W*/hu1S?^PP4nTNWW&RF!i9$D:V6\nZmN<16J+LGZum=R*bKANuhk*#SDG
H&l<!w n:Q8^N5R>LD/:lHy4?PnFtWtb+qH<nyNb!R%wPi&DMhTI5#Cptq/F/c*>hYI*Cje1kt!De*d5H+9=a&b
LjpFpR G==R1kdy96GwF#hPY8iP5yQTZ/tG^1BQ5Z^A%PP&AQ<AeniFVH4yd<R8AWca8>bwKDEblm8$yt<pNlmP
:wHK!G 4ZIpdyaQ46%1W>$=18>T$$y1?dK6u<y>JHeZLaiWd1ui&TRkw$ihA+K>D?LP$jPEWCu6eyieV#:bk=Gw
8RQPKc bV>muS#YtqyDXS<XSqpleJ\uqABk$d+qlaYI#Qc:@i:AE6<RF%uJGMkV5A^mj=\B!8/6yZw%E?VD8B$<
PKeuba a%\X69FhcQ6<<ZD$pPyN1j#IeXII=daP$H%cmZBbTZAtm94qmKtBljA5pHC&j*CeLXRZKLqWFQySqu:K
#bu4Et 1lLV/uJcn6RNCXBY6Q%!9FMQ@ZNPVB6Rj9DP%6&n>\TI$#qV5a\FSEACW4bJ<tGey68wV1?!9ebpue/k
p8W@69 NB$J/MZKYt1SC6@qyNYZ6!\9S@CV*<%DG%+@95/#IAiEK\awR8wXhJW/bS9ap>MnjJ&bR6NMh%NLB4Hc
IS%p+E Q*jd$AIL$bMblmZj\JBRn+XRCAkh:RiH+!Ieye%QVZ6&?<5KGSX^8CZLjDHhupl5F/R!YD5!qcS6&R:%
u+S%$? WSd5H!+X5^Bb?!cEF@ZbQ*pd^1mpJ6nSd4mBTZ6TwMwYJY^XHtiN8Dy!=ntEi8!<%SDY*R+L>?^h@b#h
Z%81MI nRLwn\91QVcYW8+41:K9$6R1tF\ae$/$Q1FT#C6lVQ*EY8WuCWCq8<BSe^aQW1F^\^qCkXLlWjyH+%M!
4yFcGL ^kG#Xtkuhamnb/ZA:MLY^:F!!n>6BEZh4tG?m+@*XCnXZZ9Q!FBQpDlHpkVh$S%hQ#jlIlKH?pchjuyy
IL?BZA QaWbKY?$mWLPByk:\6p4GeKYqEhCNX^VIa<+Vy=YHS++inHy?^twJAZE%B:ikJuScedSCJcEH/C:V+?1
Hl<VHa Xnt1SIS\ap&=t+F6qyqqQcMnI%F:eDJ5bNW&iu6Gh5NG<+!CBqMQuMmWi4ZKB*Q&eXJwP*X/qHZyNDF4
FnAj5% ld*b$HN<#:H\JS$q=cD&khqBth%a@4d=<$9qu?QyjpK*PbAH9tQth??lFbu@ipQZ$8$PRCQ?XTce/u1%
/yFWe> <Ip!lBGLB?Rt9/BGtR>ui518RMBmCAmAdeqXNJTL/5ZD5&EEeXRLaI@tAe?8G>!:pHC#QBD=&%BKemkZ
W\!j!? YcQ^DQAIi+/+y!QNwcwK$BDj!hmmejC5WW*DiKm4tJL*wD!mYQq4pSFJVbdN8hQ*\w=4In8E$:8Pp=E/
Ak\Im! *AM9bnd=&P^uSQiQeJ$R$hp9KM+pHmt!QIyX9Cp\Bb\u=a@+Q#uP/YHihLbB6\8pB8=yi&D/hl?KX=bX
4*R%kZ W/mF&#CCw8FE$SmY$9FQT*=^#DPiYDGu&%L\Mp9WF9hX&8Ct8/lw6%%tc6&H\jQRP:u&BLXR/PYL:n%J
RYpptG 5?$!JLktbMVl%p%+TPXTlhwZDF4lhF\:VkhbNR#FVXF:YS9h%tHVeYVin%/+CqdHGL:1Bt?1VHC<kY<G
-A6:LY 00071ad28ce00110333 Page 374 of binaries1.zip
5Q:CK6 JJAnwAyyana%F1d:&k4&4S/RAwj\hwX6Zb6D+A^*t&%Pm?IbTkRipBXbC$=N&b4?@hd%EHNB/iCun&P?
R\QGb4 =^mD5EV*=tBt^Z4T=1F%?+$4VT=nYCJPW@tKT4S@PM8HCkaSXbC=tlXyVLll^aAGYhA4=PI<S*w@?jAB
?1Want 6BD$*1G+tj===&F@mi&d54wZ:w4CY9ZD84ni?u8GecZ&%5N=RtmamcM9ItN/DJEGl>6:uc$L*nK#KJh!
@Ph:D6 l<$mDVIb>kN<*hVmikja$>Ca5b/RtCmctMTTTZ9ch\%Ib65b1cQtYqSuP6wQwbXX!:SQn#N^EA>4P#81
bD%aqK EGPtT4=lDbjPWjB<MZTiYeLyuX1$=Em@*Tj^lYAZnZndm*l\hbd?^NTD#:DMSCc\M^&\a>FdqyTE:1+w
R+qjLm a=JRcLGL?eNC%tG5jj/m!4M1Jm<cQd?>6&w\$@t\GA+DK<FXhKq!WX<b1!ytljY+iZIkPV4W9S4mZtYj
^%ewZe 8qTi>/\p%t^9M=IFnTq@Q$4F6m4y\m*^6Hw&5#4yCD<uI8eNpDne&8AyhhWRWBq\*F@EAeLQBTpLTPPZ
6GL??t P%tRBy!yMy%yCb!WyThk5*NmT\Fw5Ci@+aDHb+E<+9FD*y:a&Mn/ipkN$$yNhpiTe$e<yna8n!&y&Kel
b*AG8! ?>\GPCe%w&wbCQ$iQ9LktkR!5V4&JbW#pjahqm@S:QF+Iy/K%#TZtJAl\aa^j6^%!$6nK%p8cRqm\JCG
yycBwC $/n4RZ:tpNRRa$Vh<Ym6e$@19pecdeC%%PVwEa1ul\ZM\IZjyAS<KJ94Y$TdFh68EJXieKGwTLjHGC:C
=1l4#? =WASED1+GF=u#$cji?#6d6&8yh#kKL%Ihu!+V:u/hNSL<E%ebtI^&i1RZ^TC^&BelDjip1Nh<KqT5LeV
?y\iZl G&dhNuH/WyP+HkCdeVN9kV4b!\/D4n@$F9enqny^BN==MA9pnAuL?tk\YuhTm:mQ#l&eypR8Jnu1jY=+
l/bDy: Q94BFatAV6tNlukq8wRy$6&I#w:$Cjcy:VjMwllCS?W#Tia\PuhMdSiZ^$YA<Qn4w8nQ5:REjN*dZQeX
Z6YDu9 !@Q>^\bl9\%u@9ed:V$<YQpjP+#>NqnJ^@P:aCWQ##<HK*t+H^C5@E9LK+?@^Hb+@lc^@DPE!jNd9%Y?
uX6$Q5 *#R!?:iBQ!kI?b5?b9?M9neA?y5?b9?M9niECRM@BM%>V*a%nQMlcNl>^+a<BH%jNA$GjRCc/:=AIA#&
HT\/cM ADTM>=+RJw#4Iil:e9H=j8QP?^5$F?e>/Ih\DRc?D@$R45E+:?Ec:CFek*Lj\*P8l*D69ncHjF\Q+S4$
F:e%c4 9t9PBZpR?y:==uwI%?+QG*M>lG#eQQhehC/8j\u>ELJ^*YNL#MjF<!?liS?$QN\*bZ#@Cywd@KBd>J/S
V5yH&i e*Q?T&nI9*LX8KH@E9yBC^9+u6INd1=@Cj$9ea&d=$G*/H%w*u<J#ji9#DeQ?F?=cn\QY6n8K*Dmkj^L
t8^wjL cPk@hR4>L!j6kY%LicGWZH#eqDAIN!Z*4%Q@4%8D<9H<w:H$Z<j^u?ynj!*\+FCtlILB9@HH+Q6:d=\@
qBHi%E B@@ZS5@@Q91@KQKWHMytVu@bkMIwPZV5LQ>\$9nDTEQY!5:G%yPTp^Q/^&uaiZ1wY4qL8Dm=8nn@<RVK
ab:da@ T@u4IhQS^X*D%e#mF%4T/wthlbYM8=uQ9>6^<Q^c#j+4PR/PWyYZqlCIEml8y6yp!W&BHTyy45cdy<%G
NnPDTt +QJwR/%y<+uR+^lbT*W?&mRqlkS=K@Z*qk%GLHA<:\+Y<tchiNKXdVVid%/@FMqT6hZpy!PMqMqVHjMk
NnFuC9 !cDQWCuT6Njm#>jPXplSM4>1*u4TcqKq//mtX&/i&q4>TSV:&<5GDahGR<6GnMSbWdmcKSd6wjy4LwVZ
cqD%YX nTW#<5awKB1h1%XZyEdd6dD/>Y4QXGMbBy$l1:*=>FuuM%m6<cqPJF&8W9/$*bX?luYqWd:^q89CJ&pQ
9n9R\b P=qFy>&tbiRD16yqXR+!%wV9?KqLw%VpFCeI5alhJ>\CB>JpIy$Bq/:p^qcI<e9996#kj$+Kid%$h6:5
l&?Z+C p\qc1S#96*h@#E@$b9q$/5ZFZX6$&?bN<>:R+acR!5F8uTm#S5WFj#qyCF#d&LP/JRF:@G>\+m/LynNm
ji#S/N !y:w*<XXQ*DQW/wM<&c$&^*ma+1wIWTeN$hd5ycLu%p1pVVFy89lhHEi<q@Tn\hm+$uX5KwAC>ZpjRl/
^1S!Ka 1\ShpDtHBNkIi6V!$8h/Vp9<b:5u!F5aQuAtmJDJ^kt&QYKIW*>KL%LNTwe8#+aZjm8lHQmiZEHFaR5G
!ylI8I 8<kJw=NXqZ\nIn6Cl\bTXP=cI^&8!i9m@ZCBXIw4M?q\IFl+^4JB1lb@^KQRNidy@%P=DkTEVp>Q^$6P
j$tSBB eXF\TZXyBD#4//lNH>DyGZ<?y#4kel+yw<Sq!YBYMw8aSmtcSP%lwZ+b=GDNy@EelZ#Im<Dy<aAZGa1%
V4@<iR p6\Mwk8W$C8IRF<?N$SSn%8DTNSA&c4FK886kkN!L*8>q^j+4eTWyM:dV&=QX>!C:N^Yuk1n9hd>KnER
H%D6q% 5EaM!u>8J6hcHN18c@ZVX+nZe!6e*D8VN<$C?=H+1aXtbHcemi/6>QHYW/<>9=ZGc&D!Py>DRB1QH68:
MV/c6A /MctB5S*F9\A1dh4%>JYS45LFWEJ%9H/:^t%u:HS8hlhju!dbQ@6TSy6<aK\YI/FQi1Zmp>NX>CTSb!G
P*tRMQ CXW:V4G:^tP!1K**S><#eN*M5dH&Yp?i%?6p5?6j6=X9apRnjVl>i:91h=J&k4X*R8bC$H5i>k+==X\Q
LQWJHI aZTJZ@pL@EnQ#YFZ>:4B5:py>=cwu?HuRmbe$!ebV?kTnuyP#JylGLj#*\6ij6^b86R%pb8:*Qp?%?6>
5iyyY! mQJt!B+4$&^+E^&dw8a/V6+//T8=5LnR>#&d&8Y^u#I><$@$:\!51i$K*jwP^^mi4*kySZ6Xi@^5ZG6/
/=8!GZ jqeaZHQtmQLmt<JR8YBk^^WQI>\&^ea=ue9YtCDQi+R\VW^QF:HJ61icQ<kR/bZajh?J<AIBn+5VZ4q!
B=:cDH w=MS<:=dI<jueduccp/Ge#EFpd$c%V4y?FKMKp<5G/I1n>ZqH+VqL!uw4by+K&kdmYGa^?EPqPJn6Z$p
YamR<\ q%%GJKd/NT9M6l\uCSM4eQM:C=y6XS5%XbbuN?/G+N6w*J!+pdB\1T?kRm>k6MNSkK9ii>^/LY##cW>u
<wu4MM #wXVWKEc!jIHiS5=bSL<iV?RTVjqc/iIpaT1V*My=BGBKubq4j%>iNTK^MH5$=p>p@^it+w<4/&:C%Q$
ALBiB: KGe&+<L=ZPMIGy9/D!&uHY!e*5?V?+nQ=JQn$HW$!A#&1<4=Iu%I%5A!q9j^wE8LScCJ@4a!SJR?udZZ
SQ<VQ5 GSC$dqA!9/u=S4iXZMQiCVDSR:MNM^Qd8HXS%t9n&jmkq/=B%jQ&/i!F1tYkaLnq+Mn:Sm/!59B$!Yp<
W/wS%@ e85?ywLDu4e>=Hm1tuMmw+E4Yc4Fy+$+<DTw6E>Tcn8ihal9K?=WZ/RY+VuEu!dnM?\4=PK:i+!mA>TK
LGXlIV jqLyiWa>X>cdI1b#iCQ5Nl?kX9?a6VD?tW8CwJ>c!8pFZjiQ*M6<89FABjH<I$#GK%\ZVjM#hRaky@iA
&/R\c> aj/MZkyq%tD>$+VnJLZmC<bCAwpm#/I64W<KCnPG:?qu\Mc#E1X!>Ii:JVC8ci*9n##:J/aK^1<8GllI
Z!yZBK ^T$WLl%wJ^9ah5nWLdy@$NeX^E\mBYkWAWND9iRhS?LJ6BS?>JVmPYj\hJE8H9=<48SEuV?@%i?&^!hX
*#4MVP =puawJRK%V6Ij?Zt4DjPwTBb=dD*&V&$p&RcA%p@/Cnm*cnR\lIGpY+yTb6Lp4!ZFtPEq<$IX?qbmW$D
=6Ch&n tiiG++lkFL:ij9!BnymDt:+*=&Yiadl\nK#G>\\Q&wJK$15uT%j9c^8<w>V+A*!eyclERGe?T?aiQtN8
t^NBpd p&%9T*cp*+RdwHKBjK+HX8R6#tVan^/X/S#AG\8mc91dD*ZY1F5$!qhCci5Wt8N:QuVMuaT/%uSW&SB@
YJXbpS YW>NMD5q5i$b8yYjcmS=>Lt%8%5*nq1=#\^@/RY1+d##:Z!iy?mcWql:lZakZhyY&L6kJS=9KbP5mNmw
aw#q^Y hGqy<dGuJB8KAku8B$<L<Vn\6@FubPTXpkca:kkT^DHTILjAwX>4e6bBbj4dVKi/1?!/&8Ec=%Z>m>1a
i!6Nc^ y/Kqn8PhKS&NE@TVa89cVNu##5?k#S^!M^q$EY#$4<c?&\Z8DV?XM6ePH+\\WWl=!ikP1:@q>MFR6u?y
jNhLG\ XK!aGVp/ZKyY?%P4lP6nyc>$w#Fh=QQK1?8WtiaP4$PJ?1#LX@Y&@D8/l%cFJhLZE=<MXP!hnM444*5Z
QY/\#L QnXL1D8P9Gq5ELcINwnCwGm6j@>Fit>yt<HLiZt=?cu%!YiDMd6?!LS8I@&*X?eYL%&YlN1cpF@4jZ48
Rn=*&/ :&1M/b>amLJt!BF5bE#Y>VW+XT^hJ6^NP/DV8=FpR#<*ktu+eX4W+P4Gm&kSN&/MAV+J<5&li4Gh:6=A
h&HbSE LRd&LeE^?dPb/heL@H+!d>/tiu^&IJ#$8SM1BTLqH:?e?Lwn8q9<Jj1eX9VDM^:bjRPSNQyyk#HT@PMh
b$yhu= l+*m1\X=L*^T<4%YQ9dTN<6#LYLJ?!WKFG^Z=b?i?$WeW4Rq5St@L*wi:YQiY5tVF*Ya?KQ6&cqeTQ%Z
ueFZ6> EYDXDWjItYHy?/>6FPYCK6Hum4u>*$VammK<kSjGL1M?K$I:Q%G!L+&nJ=?bKP*>qCt?M1/ejdbm6Ghl
iiKjl6 Wuq6QQdy8auV$e??>%i*jcM^Lq+u6!khZ+%*1:@qWG&*:9SYHG@/9SDJ8LkNtdnIQ+$nWmuh@ylNA@ia
BYaCc4 J5TuLiu\htZ!^mV/@Dq>k%NGtMIQLIW48JX+&lwy&Le&$>jj4uh?m6T/\bi*jZ>6eu$*>9YtCluPlbjd
TeR\WG EY>5Zd!Qa#cp5pq\LII%=##?lAePnAGHk+kR\+A\hwjw<k&^<mhenPlNFidIKW=AlB?<qcLG!ce9\j!T
lj#6/P yYCPW<nFPBQC1RkA#Ih+cwiII+HmpuP#\i1*I<@911yF6\ij??JHmCMEpVS:>\k\#kIa>$J$hd:D@wET
^EPAew W@bh>RX+*NhDNjDPI9#\6AW=bFyXRndFFZKu/wJC9+aiI+V8PwF?89wXZANYdZkh$!\^MIZ5$u#u&99n
MV?G\E NAYAW+#8cwYC\\b$hd@D!eZmBF*HdAj&EYChj8\+9aJ9J%Z9FL\B=?PwFPLEeq?1+iP/mh/MLcB5:!Gh
^!A8a8 jyAj%<B#nj1BpSBS?SIH9AmM=WM:peA@p!A<$eG6\5hDFpFY/j#GXGNinRLe*5I<ueP9^mieeCN^WTIT
B=N9nm F?YyCqdDmdnkcEYc+CTJ4TbDSFm&wCGLumMdY<b&+TPtumDnHCFneF/JEL\4bCE//!E@Y*5E>9:G8jYw
akIkTK ?9DG#9L<:QI<!8?^&<%Cn8W1BJuTHa&!Bpl=n6PCaQ+=nwT1lwL1uIwcRpj6#4neDuhQCQu9:TZ@>pRM
6H?eK9 =wL>9>HblVYKk@a9/Yl/Me^wQKWIPijbeQM8VDG!iZG&T^Z//Bupbnk$59=5^JF&Mwm!N<E!hQGl!M&:
MSaGei awcm#yY>??b4MdMaKMkcQtubWXYmZKV89ZEpq5$+c5p&%wu>wG%e!Ze#Run5Mb*h*PR1kIA$Awq+<YkQ
Pta1ak u/6u@X&DqjAK+K\PN4FRXWdMAQu6J4a@111Bbk4kEYlHmZA%5%<E/*J8bJe?cYhH\Gw/M/X/XSXA=j9H
KpNTAy e5FTYkRR8ypmPRn4nj\1PInX@:lB8p#T5l@a^T6G\w/:1\wDP%yR+1DnJn^GEJ%$6EE1H\/pwi9*E%*q
ec+nbj A&+IYnbk1ZXSeue1DqqjFwtF9!IPQm=%J&PQ6DnA/%:#6Ta44X^99&N%aFSqXqkVZTFDlwjdIe$XE?%5
-A^uJj 0005098121f00110333 Page 375 of binaries1.zip
Z#aVtR Ce486tMhmHNX:bBuJZ@W\&atP5uZCW/%ykEW6\^QmJ>$<1tQlMqc#*ayt+9@kJjQ<S<9bcK>$B*#Rm$t
q:AL94 al$6ta\B8QpPep84RnadMD%y:X9He#KTB6WebF%pF6/MY=JX8aJjkCy1uA1q>V$yWnnW=yAJIL\PD9TD
8m*JeD ?4Qh/CCDJ:5ch1HZy&yQFutC*mN?>p!hdDAiXy>B/SCL\G#Wm\tjdpKiatZe4%:4Ec>H:1m!nm%EwNWB
VLYpMJ cq?WcRn*ZCJQ$TyyVq8bqw>:m@JEaV\udkJP^DPGacZRML=u^!Q>/Y9mT5NEZ%HZ8ic@Bc@+GLZZDG/Z
PGMe\\ J@KcYlcE1ZQwbq1^q1RJ#yHIhBLD?laqn&Q4J&%i4\8lENIhaT:NLtWWL?A!bPW>ewll:RSQR18G46yi
\eRPAK Xwk=9u&1%8F$P*l+qVRh!PNZ44%q\d65AweM@+TWGcn=w#?hRXjZpJV^GDRVHw!8Rwa9W1$nJ%Tc8QT#
d$6<</ lVNd?9V>MNt^^%PA/&5p\w1!^Kukm9hVcTIDJI5puyM5Y499J?c^#iLbT$<eWFXV%e@EjJ/=/HQKEMtj
JhyWKL %Bapak\Nh!\645hWLm*NF^=hqZ9BKhj&ceZ$cn+NKN\B5j8>%w8#u?/*%iQPHDRPpNP#1m/AdjqQc/hy
hMJSh6 5Qe1wdS=:Z?e^+6!bHcVE/K?#e15XjFDb\VX!^Ju/>t=&leJ<wSah>/bqMEl\RhShdn&pu$/T<D1:&>8
^R9tb^ $?/hY5Vp6qbRdRjM:SPdlVqbYT5&AK!?w^I1cQ5=jZ9d$SMA6*LiEZ!A#AFLI6hMQ^5Gl?>hJmHNq!?#
q*t+Mi iKwyiVe\BbGnI6195\P*FH8qm5aujymdeGwPmp@PW&RN^ID:S^?L#cym=Fa^wmHu>SQSDVaQY>1ESu@6
1Sc/aI B\ilS&HpBNuV#bTpTGNRmeqHla=iR&ZnF9EW5>#n>8\Xi:<SZ&HtPX8=EbM$/AFSMAP#bQiSePVAcw@G
bdW@$l u\*JXuYIBlSXIIVqiD@jyJ#G\!9tqCWySB+5m/YtqR*9CDlRpjqcYN18my?&=+Y%/qhLd?hdSIDL#+VM
!tjdRZ d$did4&iRjLV:WIyT9l<GBi$!Pdwt<W6l<n+!JCeYd1TXK?5jjApKXZh?&LWD!Ea1Wy#ES$M9@S?QIDi
YZ>%=8 TGI!<Dp+>Q&+1S/=GDIt^^A!LY9:bI&a@bR*p%quV>\6=w4p8Ben9H:P>M*BQGp1yq>mwLV4ihd$5KPX
QLh=ku 6JJhWTDt1Ra!L%9C*l^lK1@qIy6\ptqhk<y*H!aM#Y!IXajaGG>ehWAKZyFwDk$mCYmlM+5=I&R&mSDA
XEe!H! RX!MFK5Ya@R^J=tQ*S+m#NE9SJu%@yHdkX%C48kEK=9ZX\\:<X8%?69&KwbZ@1Yy?@I#<#kTjN?$FE1/
K&Dqpm 1>t&6j&D^nGVkE/m\%#HTHcB&?kjN9S*WPP!C@u+#T<KYD8+#F9Fb>m/*IeKu*mh/CQLAuiwENPu5l8X
W$GuyC WJb?EBSjye:YhE<FMJHS!R?cYF$lCqH9u!wE*tF=DCkGc<Ybkccqnhd!IMtq+G!FDHkFJ4FM>l?6+yS=
E&VKhm m6X%ZQ5R%RX*%u4q9DL%?MtpXW\Gk$KS\Z$HI%qBp$4:ntB4$i:q8d!IQZJ!I&c1SNQB6%Vtpw>LTm#=
?/%>5? 8QR\bJpPCh4G*c!%$uqp:JQkel!KWec8iHlW<<*!=bh1Ah1>$Y^&:1LhXSC>kXc\DVCdhud4QEA9S@4w
1YimG# \LXiKy&HZ1yLT1K<P9m6@!iLNBhu&XN8&8lt>5VT<*L4pqh5!N<wbWMuVjhJ>S!6JXBW<8u<:d%iNh5D
LiE!=: D6lacmKTMya\a^4PNEBbXdb5KBw/ii$K=\E9!di8YYnutTpSSl=S:5Zw^ll&IZKSN:PH<+q>ZWC*CA5P
h\!mQ$ K<j#:19LydVTe54YPFY%4+hBmbl9equ:ueMk=uNJl&u=q\Pm=8?Xy/&56+k1%%>Je&MD>/$wk1HQHDW$
ZNRNBH J*%XyykCl!\ZC::=G^SnhDGB<\p\/:*5kqW*L<8iM/lYX!NcC:AyE&I6ScqBWe^D1:PayP5>B&a=SqjX
H4BIec c9cnSp4H&SJ%h^PXacyM\\KnR*6EtiTZ&YuRkle@jZN8R=XP?aTe>DAR^d8hB#lFBA4cA<uakVDDV<TM
w&pN:q <4DQ@P^a8tmwZCl\A?FJqL%la6=!\Qy$c5DFS*FW%N<@WQD<*#F\@&8a<A@5Z&KCj\aV@>51>u<$8j=*
in4ne% Fh9n%=cCuiXj%Pc@%6#<Ve?GRmD@bu\Glj*baR@KDj*#L#^@G4>D@/&WR@&Qbu>@18BGj>G<9j/IT+L@
A/&pQK R$pQ:?>mw*#@>eD?GwcF<QH?&&YCk5F@nlD<b@RXC8d?e#^k*n>@+iVp@QPZ9$bwwb^@jSMuL?jjlQX@
!@a4M> G!wu?D<I?4<dKm@+j=RJ<G8\9Q?aCjD4d#\QLF9/Y$#=H/QX9*H@@89%?Z9h@S+6>Dj8*:>Be><nGj#G
F<ZV/* @j5*cM=:6P@j8H@@h>BeD$B#*iMh#9ed>?@jwKH*Hb9uIYnIjejtjRn/9w!B**l@@#Mc^uQQnQGBH+K?
$l#J9i 4%!L:!Fek*HhI$@^QaS4>&a4<D&Ec#DIQRIV*$P+B8Y>D@$R4pH9Qi?HeA%/Z%aP*$P+>t6%8Aj>EK=B
Q*SV<D :l*=R:kGkj+Y@Y6ID?HcjhpK9?AQIS5ZJ>e>/AiSnS6!D^4/L/EjR4b:Y9L?Rn?EdD!@u@A@Q!Z?k*nJ
5YiK&Q ?+DmQl:a*+tZ$H@8m99uB>W@^E/kj?RI@H@FjR<5:p9/Z!48G<BQIM=VTqWu#i8wew$Mn<1J!!@Ph5<5
PHdHCV 1qaic8>u\5dwbYpdd4eFaWuwVu/S6*AhR=AZp/RuE*Qj*aWyaC<!D**p<BkjlRISJaeXEZXFYbSW*!!B
GNN@lh kAFqk>\S=jm1M@AKEl$p=j&h:y&XcIl\^MH:#e=pAD8\bc\5^CHlWKAnII^iIMLW6B+>Gke$EB=QcaAH
IeC8$N +@CA+Tkh>16Ccm:kipEl<KJ:YnD5K!Q</XNXMX%GK6HVL>1=RScC+u/muWN%eT*nQF4%8lPMM?Ny+LFA
ci%n:< kld\mI/YkRDV4Febw5QM6hBd>NtbHn?\^Al6E+t<leM!&CBd>MBaM4HX/PukE%*>TepVR\&Z#%%iY:#K
q/#y$* M==ZG4NN\KtZ1@GC#a!amWwNp!6?wwik&86eL5HX*bpl$$<eT!cmVBHhEeRlEN*Rn8y/^EaXVRJ<Bu^p
l8CH\l KCL9n#aQ8n&LV^%9JlCMmbRCnLV4LbuMI?4V\FiDl%>HLKQ=cR6+Db<SGEM^1%A6tCK1lT!@CHpF#E:I
tQ&qki aH@&9:RbN^DSP%mVWp1!@MSi#d>HC85w/I#L1Ajd#<?iYWRtd^%?C!LBG5IPJA55bB\tI:#TPVj+1qbu
6mGK!+ S$NaGy?NpKYXDMADYJ>AIX+!@y6W/Wi9X^6tWpFDpPW4bMWM%cHy61e69GQ#FN1%VKj<:k1^Z<b#J?d$
#:6+^E JGTZX%8ZNT8bD5bpktc\Yu5upH%\iR4hk^YuQ$<mL&$lMLN:$kBIk@5JqIpAj5piJF9HJR5yq^&mVd$j
9uDuM# e4Ktb?4LZ<R+S4qTA9KZM6N!n#HimaW!YnWqp//KKk+WQ/MJ=pjCdWJZ?jTC\E?TMmjl/cc:j+\MQcW9
Xhm>%L HYHXhK!PL!ZYJtaB$4kwaiiiItbkn*RHI<AR96mDQ@SMlmB?DREn&bEKZ4GcWEI@K+w=TE&iTwK^=qa>
cy\uaY DPjZ6/5bGmdJ\B^RS/TGniN^LbGm=aS?wbCbpI?@d^G8+6+BmuSpQLNuAcE^6NSM$e1%LD<b@bEBp8+R
\>iSn$ 5qi?qC$/cVKdtPI#ESb6<XXcRjju@cwndQuZL^L=*ku*4a/tZQAt#NhWKK9nCVZYS@q1qh#C+ulHACtw
Q!EVmq hRV6qJnTS5kw<RJp?1^banbb$BK4C^y+WdbE*?\%i4l=Ww5TdYlFMS5CtuIID9Z4%#ESe&pkL:k5aucA
q4%F5G 1?=T@Fh5BKXL#EBZeVkJW$hyT6wbGqh4S^A9j@/dQKyA%\R@ejh$W!1>L$k+#eRTnHdaynneDNKjKVJ>
YWt@LW YwWHRPL\cnnIlBA<B*NH^VDH1k!cZTVkhIJ&BwylMZE*C>EuTIXmFJ8yQ+B&TVe9BTw*EFp>+>yQ\@4T
ljC*wM FaKMDIlbiC!?5T^WbqVH@N:9<Vdj\R5wp&lTey!miW/I>BXT8?Kq6:yaEVlHS4PVwD9CdCVCCDw&Mw:+
H+XcXm DI\#wG8GFYbItHLqdhMq?BwJQkkB\9!^j$^<%kBXDT!HdGlX5yitlMw/meI9t/D+I\kY\VyY&Ni>y>c!
YZhaSw Fb#*Pc>Ha6eWXJIlMKXewy6Lc4FRb/$n@=Y#j5hJP!d*R=pXCTG:^l#/YL\?yNh?9PD>E%5q#8>I<QM<
lY@:Yt VV4Nc=9+aiJSC&iTIePPPZ1D&e#k/QuPG*Y^>%M=%6Vl#SJ%eWdWCVX$lpN^wAJRX=cbR?<Lj4X6h*RY
%*I4nn j*Sl^V*?58*SF&NmBadSRZXJ@eeyREw4C^:uR+YY?hHQ:1CY%jwbW151C5TZ=S>F5#lb*%6+1DG/a5Eu
n##J?J :it>bjeVp^KR^l=IbEKRNZn<Bqbh@iSNCZ+9=n6WNq4/F%RFP8k&u!I?PEcaj59u:X\!kBk4N<ccWG?#
5RJ\:c L:yw+A4Q%I%?59aJ%ZntlwSKPc\?l@twm5XNKdK*iyWXhT+8p$@EYX#R/Auppd8y%\BiF&*hB<tynY6G
VmbGDC S^+V#I4X9Pw#YVMdY/A@S:=DBL$!B9Q1J/bHAE*MFA9&>\D8W1ai\anDTEN%Ql=YFKqit\!nT1W\9/BG
F5FPkc \uVMiPT9$AJdQ9tD*XZtDdl8h&SQPnJn<tVl$Klie:Zh8p+::LNW!e5L\QcpZ#CtK/!cYE1^=<N&+Y+:
+9E^Lh NP14JVpFuF1IBb=*\TEXu#V?%YN6mtpha1aEi*jIF>eA5LS#SP>Td1>!ld$IM4\KjN&Pedq?T11HE+GV
hZkCqC kA#\YT#jP=NiP^@&INQ^li/pKE1@#qI6V#98l4VaI4Y=15mXiP%PNVED1?dGw>&qJPyKX+Ek>>q$/XZh
eP:CZK #:w4CqV/laYcHTj!A@NlQIAA5K*FqTuaXqj=na$BDRF*PHyZJXc4ntJF8SLWF>$5JQB#Jn%C?9YkuJ94
MEbDhk +W=AL:A?m%eIN^hwPYNIRiB9K5yhCtuBHGQu^>LWW?n@Cdm<:LL1dBR%c!$8>>&8nwe#$*=&^\CYM^#D
9RN$6* Qn9aP!yP>@kYt=QKR4L4#AbGEa:@6ESR9eh\%9YE?Kh>@GQbk?1Yh!RX<ilH%uS/&NnmBXkym!SekmQQ
GFCKjA $ul&KPI%1M@V*>V8S!B*MSpTFJ>:/YEy<nwt&GZCcRm:J*\lPd*!bn*:kVpjCFp:Xh6=ZMWp<e*#b=CJ
WHX89i WGL%G!tuF@D9!l+dNdE*Q%6Kn6LKDG=ieiZ9pBnKGZ$?B=@<W/HVHw8pS<b^6acI^k@4WW8=Pi^:>bub
ila^Nt n!l$#yqhGdJ#w598ka+=Pk6Tu?EZ\XYhw^qD%t>8jQE4NAa!n+ajj^m?!d*8b1B%/:?Baphkeu#9aawa
Xm>KY= :K&^hWG/^6TAm!HXPnu?^mR+HNtpi#l?KpQ:XeF!CD6e/:AACV84D#qK6&9&S\RPN8Zkh>SH4u&$4l#:
+#y=T* #RjVX$+j4<c!64dXS/!E%WQYP\PVcqkNe%X6LeDM*<6!*FCahW<JhipLdE%HEE\HY%Zq4:j<L:ET:1yW
P\GehH >XV!XmY?^=@EYHDeIVy@k/jq@dLJl%F=l=\*lBR+PPkw9pbj%/11tF8Y+FS=4X^qnpubQSDM:i%wjlLV
%$S+@j K#R$PeIYjqckj:dQYy$98NCunG=bwb%%Bcmt%n4/hLY:Ql8N%?EpH&:8P?LM?k4LemQk\!k/tB&aI\S$
WJ<&96 %T=E>:bK>=JPq:hR6At1WR\!QDd6QIBVI=L1nZH#FyY#>yK9$$cmQFL#%ZQld5e%Xl/hNA*Vll:*akW=
-A!TZ? 0009d587b1400110333 Page 376 of binaries1.zip
<Yn%@P &&b>q6!t\qFBP8:S*iQWd\n8FXE4<Mdwh8b<T=b*KPTYma#%Wem6$:DmE:K9cGW*bSq6e%8ZCAWd8VQu
Ac&<6P y#*KdWqZ<yNI<YhwV*E/#bqWmJpQ%*Aym#awLc$qinE*K<dSP&*#^^/h1CcPR\BY>61Iq$=IBT<w4ZZ/
58Kn=/ iqDME$GeIM>a&R%J*^4K$N=<+*buXB8LCd^<d!jtVy%S\6Ya:yZN@qyyXE!&\Sm:J&5ny:cV4t?h9yc=
^YaamX dk1bh8FX5!<=jMM:LjLJI>R8GIjF>ly%j^cVmlDCdq+cT*LF?4Bt8u?#w<iM=@tb@wPaI11JM5*ne!dK
B%ARe@ CBI1dAw1y+RF^&&%eQBYwdc<5:!K%Hw:H8?A/ZCbydJ&5SG4/lA^iyMS6nJA\hbk>C8t/BCyk*DWcTH+
9yWRXl PEG\qlIbpSRJ6%e:4\IYJT>QY?ClWAuyc*K@\I\?DNa!**pWQAW#XT%n4%G?WJ*k>APddt?h<a?Mi$6C
%u!C&V qBh1%B*&\VSHPhybBXhX65w:kh/HRAcZ@1Vi\iZ+XKZ<8utX@1@dHGkFiaj:&+y^C<Dlb$M5/+w+t!j>
eQm!qY tn4+QWkK%1919SZ8k:a$MJQ8GtTG1k14tkw4#*Lu4=a$E!IF/JH$n$X/\\j^N&8/l/i/Dq8WBKEl^peq
Xe=9$8 &<4!h=RVR4mat?hany+Zp%:&=%@y+pZS^%eKD<>*n$W+PRZ#K5XX?tF>tpl\wR+eepJaMWl\!bFBj9#w
RjFau% /!a!QtIT*/VeYJ59Kc>yid5+dW>qX*hKVw*:W8DG!5V1WF$==m6e*FeGN+V1T9R$4RTuBZ5$tp<%c5#w
pK>pBI 1tW>jbW&lKM6^q%4ubH#Cn^eQu5epG?wEZ5G&\6c*ZldueKCAdd=?9HDXjtH$8Nu<&XTw:dY#DE$et4w
p:b+S\ +$Lt&6&i=$d$ebkSh@TtS#K$KK1a*/Q*KFS/9WWl\m<$Z5&*t:KM9@AEGmuD>n$*\X/S64Mn4mJ!4>+Y
+a#%*B kPeGiSYB@4p$ZClcp5bA:bp6^8%a?S4EZ5F!h\AI6a6lCc45La:uIKMlIEMnnKXt4%!jJYK/dcDBn/X+
Z&^c<P JZ!b\c%yLHHE/1ZE^Cwy1>>DQ<:\RmtRpq14C/:PGNN/l&WchY^QjQ!kYL>?6*$:?IV6$Ye6kK*yCYiX
FyKb!D 8tnN#i1t5NJX=tXi$S4ZtH=B1JlT:$eQAdP#GidEV?N=IENQE!Xkn/n9nltKqpWW9N#MlVpDl>p$<$kC
5:CGVk B*5ecIQcidRH118!C>^BPFB8?DwtCJPWE:GWI^!!NeA66>u<5AaWF=NBH$K/lEYq&CBZujjj/n%Bh?d&
%&$GaR nLH^^?R$5Kh9h?%><uFV&Nu=^uWWq^nb<>T!$I+BV^6S8ICl^h:mGqn/p*uW%*W$BL:*$HW&!@&+\uZ&
Ttm9X= ^jH=l/M?VI^wT?*C#94##X9$jG5y&dhQi6$c\5iCDP%N4T<n1y%6<JC\&pVy+l%:i4$J^*j/NMet&cNw
5dP<%? BVW*4uXuemDZNhD4iYyFI*MW$:d\:nd$Qkh4&GG%/SYSAIPquJ9#BR=l8&tT9&G85K=d8^=h4WhntMuG
pt9&8! hcLVpl=QuET^mj:VF/XVK/=%c:lQ#Hmn6!GPDXBpB:bSDLm/cERYC+dcNbY\y<^+AT<wSdF\eFdPG+ti
yYMZFK Dn6AplQQK%??8aF1YMLiZnA*W4nK#+6aGuw@HY:XtiM5yHchaF=H\X4dQZdq&eC4y5>*JtL#qC%:8*Vy
HeY!<i Eme?<JTqA6:#5Qy%++aCJ<54u4IFlcldmLck8cR#wuA41K+h4<*+wPAdk?dYlm+X\8<<\j+MRj>9iIL>
V5detH n&*A@w#l@$@m/XDIQ<jVwb#@uew/KBnC>^<1/@+Y@QnH5Mw@>*Q+t@n\Z*cm@aZtjAn/>^$/j/El@^Ic
a^uyNk ?kA$:QehPu?laR>B<>=*dK/HwGH*wdpjkkdjl?b=AQ1iK1>jcN/HwLu88&y<D$FD:$FDH5I%KQmi\Cjp
RTI/pL IX!D<N/HjknZIF#*ZDZIR:kG8ji<H<I%!H$<l#!Ec@hHt!HeD:4JiP>B<#!I/Qilij?4FjB9E8^@YAGl
cL+Q%+ uJ#@6AJCPeEQXSTlaL:j4uZ@aI#*d<W+j+:!9ln$A+6^j8$c^56LCj5%HBkj**>hnQQui9^*<i!@Zhj@
y^SQIj JJ:>:@W*j+que*H@Jy+N@W&#YlkZ#@<#8aC5%p#5mYm1@1#>BElyM*=1Q11?nn\J@dV1enBuHVbp=Tl\
QV/N%C KG/iGGGEhF&ZZ>+4Cb1+kY/E=SiWFbR<Pl6iuK:>D5kB@5Wjq8j:>CqJI@pC=DB4nFAbl/FV<y9wH1k=
k>#SlR K98bKWTKb8bpYA\BamQl&aQbM8?Z$X56VT>a&6YHGeEK18b@/c9!9kLD%b\aGhEAQEJ9D4bQ?*BEKq#N
&Ylb:D HN4q:je^&&N>CqDWtXupJ=@nQ<FCFRFZYT4Y*F5VlPABGARi!M?*=I1Jj1wLkSj6=EbtKR66ntd^XmXp
yGk1$j w&yT^aE+tHa&AqS>SeGSHawBnB#u?CDmtkn%/WF&DXRN5N!=AQEk%yRAFTRIZ%YMjDBdhBkW:Q/mGFWb
CYi%=T ph\ZBJ=aGt$Te!ncw/*AM#XkWHln8n9RmTmB\wBbb/5tIqMZN<PA!dt?Cy:C<N&FVA$=inEMWpulkGTw
?EcV+P :Pj=A^Fbc!puL5yYY+JK!%tl\C6GMj%J!PRGI=S%TZ&68TMiDTQeu>c$9LS!9=%MiIkYCaTFq#wFYH#T
i#<9Fw 4tFckd8b>:ECXC+ALW<w&i=ZaAp!WFM<Z%yESMa^#HA*#qbM==SN!N6^Z1==?YkhGbR+mGPCj#/Dc1kR
=$S@N% cWYHQNThTc6+%6M5WPZK9+Y1XE^DEt\BMX^t/QBePl!w\jP@/ejtiRuQ5qbZj6wFTi\&mq:XmWL91MkF
RFG4j\ QmIiel?ed8:nS%a#@!QMVA#knCtGK<YA5$^DV/wb=lqmMTBl1*C\JCT8\e9LFNkbVq$LkmRp%Xe89^XX
Vj@WmI lc:Zm><$aQlJ9mqjEaBV$/<A#V1@B*n$d?JkESL?SB!ATlcLt&8ej/GTVb8nTZLt$&#lN&SS9PCLYpJB
HSWtp& HnE%$Jw!+!NB*>J*:JAGE+=^HhAQmt8INwGPd?4!Bm1cCX$+D6I!6Jw8RImAh1^dDM^/69Sp6e?&y%pE
!wE^B% ?Z4:&?@5AIS=Nk:>KX^H1JQ9d\LitlEi<*B6<V:/RcjiyQp+a?14p%nnm+Xi5letZ&qQECeu=Z?m&6ck
?wWH?+ :w?</%\RG$B?kRLANEyBNjQEAcdViSPnQy:$iq*Y?nW9dy+epXuSShV9mk4=?$h%V\y^T4?nKwJZw&qu
$1LDc1 Z8yqcnCl88:bh/VhQtNmwCR+W%unbHS:ly@&8cJFyqPDemyWHel9AaEbBkFyL&Wy=Pm9\JpTBk*I<GHc
V=R+H^ ic8uT:y9bPFFQ#DnZ\\4l==!Ac^=%\IwDaHwjN6/R+@IE\lL^PFFDXtpbbpB8d\&pjA*MP9N!B^%iVXq
TpyELV ?DqFbM%=Mlw:NPCH=:C5iYJE>Ye1t&mhm8++G?V?ic@E+NSS#<uy<F&uXdH5#LE&MdMC@^J$F<MMu5DJ
ik<MmL keqLw#M#CuAG9l9<>kkX$R\X*ed*nE4Vm1m@lm\i%d8cNe9SR\/XT%kGNw$j1BwiZn\lXTpHq&Tcn6?b
<c8QZp JcWPq$WBCWt6D55lTwbnnM5aTMQ1<PX=yqbPYNcdyc&6MejcaeZQjEGGkF?K!1/W/jVB<=uSXKtJCnMF
iZM6T: NN<i1Vm8X6ib\!16KcE5wRQS>cZbB=:<<#XRqm4E?PAqR%6B9bA^uykPbu=u<iYykZwipb#T6:FCZXCt
/JV4X: SQwQbE\yK>y98&dF8HbYnEwY@Q&nL<LR:QqKYhPqc$dp%Apa5M^G<:kLHLkuM!D1HcPF#IP8/S4<QnpD
aiSAL1 Ru$mk:!#mnuS+9DBAdNIthG4miSbcGh$+y+6C5^KyMlai!Mq1cBW=4lm:@4!4eLLFCZ%>@F!$=!Ip?m:
QDiwnl m:9MSR4bu\NC=E5%>!XP6AeaG/uRd&?bN8V5ZKj9!5u+kD8JHtCZ:@G=X^/k+SR*tenkDAn6e%QD=<&!
RX>npV VK?G?b:46\@:^/puqVPEaHn:V\J4ZP\!M6@!F5Vmai^bQ6tnk64*Hp!*+NteFpQdk\tLI?mkK99/n!5X
X6FP9q py9nDlH1<!@:iZYVQ&bJQDMR4ieyh9A644RKb+6kZu>:WP*F&1$jHHP+LH%X/aNyn1IAe@:/?aj4S*WM
HGaNSy CmNYTeL<q8cS+/?Whd%Wb1cCPNHJ5eE19E49/V=B4NmqhNpWt6j=e%E<Vty8hPY%#$#I+Z%TQmp*91&+
nmYB4P @u\Dl+1GahVM64@N@4\!=Dm!5NpdeCBeS&:pctHay8%+^!YJKPCEK5H8AKmp=>KNQP/$NKkMknFQV>nF
lMwCmI :4tdS9!51/njJ\9kydSAR/=eEm#Lm&6\5HE5j%c+/W>KGY\MCi@RdC>XHppwMNBmclT6WwI:Pcqy1Z@@
!bVnN& 6ZpdGbWMWVtm9\R1ZE%dE+lI!/CEd48ntZVbQmZ^VT#FCGa#uDSF%Z*CC4he\8Y+@Z%X#XYyR9A>T:tF
>qdd\9 N5N6jVHqtKL?HN=&X&1>*PBXP&F*>/D?ndTq5>+k=?b8jPEXt+i#DB=DWw$qa=\QekPhVGGGq!n+M>/e
VY8Ktp YKQNY/jZV?KPl<YAjbdLlAYBiqlHu//ywuXJ&heWT8$l<EMG?WwIFcY6A6QZ4^tEyLJj9?HPG1/9>yim
YSnVpE Jdemb$F/9c@E5FPk<5JM&CW*Jj#N:tFqa6MZ<wwZVHFE!^J=PLG9DJ5TD+>QL*4hD^L:yD=9qu>Y!y#l
m5*mAZ hh!MmcPyTVl=+h$I1!bcnHXZ:Q@5SPnyVEwL8@kwqZ@l!hde@DkY$H:i4VZLn!d$mIVX%p+Rhap9^HT+
hWF8Yp eH>%$5A9nWty?i^F@8\49%WNjht$R8jFiQ4M=?FSm6jVDdTy>lP1jME6Rq:wPb6k=dA%B$D*J^:qjpiN
aR#knJ K#Z>ENJtwyp6a4LaRiXZqH+@11$X^c4=*C/ecS85n4JY9$bX6SJ\WBmd#/<pY:?!!/>:L%Ze6VcTQe9R
le5t\G H>$:+Q*ycpdT/:VAD@Nh$dmP$CG@!FR#L@>JEPF+a%N\%nwuDWe<YR^&S>TKSJe!>EyNYPtt68@:w*J9
lA&wF! ty&IkD:GL$Q+I9WZGak&dFbW%hy9FXbZF4B<PD%?9L^L/Ha:9IEASYWbRhhnPitYmq@ZA@WKp4@=kyDl
/5FBIj ^PY^M/HFYDBETXmAJ<BjtSZ^FXhAwFSZlWCZPSYmNZRQl\hSQu$kMI/cY*SeuB5^mw<8mnpMFl<ttIB\
15JL=E P!Ium+TttImttSn\VNKmmd>dPEtmD4uhQk:PDhY@?!$q/K$yTJAcD#wRtt\ZtD\RR!9145iWH4hiBJPd
9=/u$y kB<aF^\^SP&DZYcy1!48hmy/*laRD$9ZlW9L!@WG!4K@Ylk8aB>T:ByqXN9?IFel4F!%d!q?M+>#kaWm
p!tXV\ :aQYl6Eq#k<YLeIlQP8/QWjPQGR#=JA8REhKMJC*L\/mbe>*k\555lAX^YK@>yckqHZAe>mpNLZ%d<WF
h>A%y^ A<J=%RhBPqI%Y8^J%+:hHJ6amuCP6YB4SkqJS/D&aT#%q?HM4\D1d#8/NJ&y\1GDNP8:>4G$Me:hLJT&
Y%MV6# l*q&TCk\Jp4XRcqhh%w1kkl@8Y=c6WBH+^A+bNRKtY4DF6p/S8dAM*Qyw5Im8%J^SW^mkJM8Mq!1VbR\
:cZ<$C Y#C@$wG/Q+d$+Pd?8wMKMIKMpk/8kN=W%d=M&@::aL?5<+/utt<ue\F6Lq9bi8BHGR^FBZjya84yPkZ@
ndG4<R Hkh%HYSQL$hG%aEGq?=$%SyXV%d6eNFK$Lp666TwVJE^JBwX8mtbI5qiJJYARyeecVe?R@iPVK4C!>S!
uXK!K/ JF4eX4cQ8n!a*jLe!*:@/jBQHGq^Seq$=B&aWa<dM:$HVntP^bn/iKX%kQ?&ZB<&dji?D6abN9*+liy1
-Ae#E8 000c8176f7d00110333 Page 377 of binaries1.zip
DewAZM 4@m&:=8TeHtRX#m:1hMKP?Se:qnhak4>6h4Zip^y4dltT+TdBne+JP#yy@VmYMH!L&%1ABd\aMpLeBTn
TLacF^ c^RVc?HHQR>C8mlGn9LQa5Q<dL:htSiQ&Cj>D>dd&!1yPS#ET<J46H!QHSl+wLSWQJNPuBnnTHn6L4S=
kXlF@X :l#!PVJuZD5jt+51*4F/P1\9eIZ!KkhRAk9S1/!Z&NXQY@EVut+:Z\RF<WhIRVYcY=E?15Z:%ppLF5V=
AJHl&L EiN8<p@5Sp4cFt\j/!DCLaX>8A6TuKy6=TwDu^!WiJTPq\Nk4TmibW\j1CY4iV!mhHd\SC<c?jCZXKAy
AWa6uD wqKnBZYIpABAjRK<pAa>Xu!%1CbWFBwp!k^*nDQy+5t@E5BA^%w8bKWL4ApR6k>l\n&5*T6/FqK&l9*=
uWn1Z5 &lyBJ>nVF^Qe6$E984Q?*Nw\5H*j#*e\cANPm:J:c?jD#K/tini1!mci6/%wC=J@PM5Ly%=Db=^y/<Pd
iB1enI L85q9%=Q%:luJ<1pFV*N4$:tZ#FmjWCiNGYWNC8mFpjBICn\pk8GK!@aX>n9p#@uIec*FhqPH>l%\k!$
qMc9QH ^VL6#WJp>NPw=h1M5LSiEP1e#=FkjGJn:%4m:4d/&Y&+#6h*?\%D^mQ*WD$pTSbdN#^S$>ZKlPC?9Jp8
%hLepT &4wN>41#L&l8dhl5qC@FX<M=J&85WeNQaG>R:MNFA&BKtP9B+bCwJIAMbL5Ahj8\XqVD?CQ:?q&B+p:E
icKF#+ 5JlY+NR+$lCYqAGeKBCL%e9>$$bj%EedIKH4J&j&X!@K1paSmhi1aS#h/YCbPSQ:VW:yXkQWHGMZG*%Y
CPJQkh !iY4#%$EbVquj5KJBw!DajCJ>8eK+qQlm5&d=LWwL\&e6hY<L4ACAJclWcySu+$4LRQcJ:FX^Ieq$?<&
i^G?+: 5dZpu=6nF&6N:DJhYR1Q$cknX?4RBlC1p?upWbFn%P4ClAQhJq6a8!GwFX:I8>5a/Hi5:SDMD/iWT#du
Hwy!Kh DRwF?yd5>AeML^ZMy%Xw<R/*^eYXX1\XaM>aBN8CWuVRKMl!KRiquRN&GkJqe%CuwJa!^P$lw?\A/kBH
YKqJJZ #=An:yiw?dLBpdLD:i@*:T?<=pX*=iW$<#dYX!%\%96EP:FR\dt$&LJ>i*Iqm!4q51?uI%:Rw&1ASm&p
&yQ>j& H:6MdbFTy\MCn4T%dAhBjn4WB$SZ*l=cL>JWq9c^bDiXA/5a8aGShAd81Kc?<^QK9pNE4*cQ?CmnAeBS
lm8J9Y KcNISwWGIQQt?Fdilbuqc:P<VPhTb&ii%D&5S$w<\jWXJc%n6&8Smcya?Y\w^=%^E+a:LD=S*ENP1B6j
e@&ABi K4A1^Meqt!*LQ?@nBXnHli6^M=BYhYeTi4NP86j6D#4Vhn@jBm9u$D&XDKDI&T@GRKQCtcEMkTnZm\Ki
j<dk// YBAV/Fuu*Nn4GMqaGnlbG8BNNDDEN4Mqlc1\m4ei:AccF4TjQ#e5*ZDbb$iFTllF1Bb9Z*bPRSap$$ea
XCaNp$ nXXaXkk$Mn@T4%w^F6XZL<1:9@iAG\ylYaWR??BcSRjtj8dTbky!/V$:P/iD>My!hkkE##4%k5J^qhZd
DRh%4? M>Ee<JCIQukB?b&WQ4Vm1#%#9ZZRKNPCEXEBNKSDRY1DEAXQlSk/%81yy^L9+R&HJ9\b#1Vnl:F5#EY9
:KX$wL SGYl1*JjpFd+!Hm#h5R>:k#4<PTGFC51qpYlZaK$SXb<p4cFkRj5!>GI^JPl>d=cSw#uec5#yHyj<hc*
=ZtR<5 L&>L*yppSK9Z\IQqP!%4Yd$m1+d\&P586BkB+>*?N=D+85\LutmIYY4>8W!YETP9DGQSmFinCZ!Vy4*i
lZQp+I K*D5NcD#kB#J*=$*peec^BbmL4?\NIimu$>Da6d*w14jn>i^Ltj#lHqdXLqWWX:KIj\NpX@iiKuyb/#4
eAN>8n CWcJ^+H^i>D+\>4#FQPe&V4KYt4bEqYAE!NlP*6h!!6AlNnEeLk$@<XWE#5&58#JGi%tbjn\C#jJ$etR
bp$A%Q F/Gqpqc\S+W&L>LE><P9P\&R\qLn4nlJ^S$h1\5qc!CIIN6aiKMAyl!ac/!9l#d*DPq/P?PBSEnuDB$#
k=u9c\ l*Pq8L?Ny+/$lcLdnFll6!u54blpw8KkADanA=XG4$Yl9pGS5HY1cZu+++KR:cGun<F$Ley:41$AI<>J
R>%?HC ^T!4FqZy!LITj15iW:>ReKBMw*JI\\59#Bb%I1<uhDK/Zh\XZh#u/c#6adcZCmJV/ZMw$uInDdIM=KIZ
9J^nd5 ZaL#u#:n><ZGl\qFT>S9/jFK9RJ8:wnZ1jHa=tqZHDXeI5*c6#aAq5AnbKL<NAm?wN<Ynj/yM9\9N:n@
6^SdKq Q>NS=e<1mQ?JqML>#+FEMDj+9!iqeHH>k=VC^j*d<CL$N&FiKQTlWk1W/\FwL6::$N\QRh?Z%\9qiRn/
CqtW15 99A&qQelcMl>I?h:AB4Gh$>aH\b?CJ4uQnVuR>Be5H9RpAikwjhqR<PkD$FD:yp^&EP+B8G:J!+Qi\nZ
4whLT% ID#*wS@CNem>I*<I%!C@L^L=lZ+I%#n98<hkD?Hc@XIKF@lBq?&ik*N^QtnC:#q^L5m@lH+R&YD*%D6\
BhPI8* QaS5>?y&@&C9?FjX=V<h@ANXq#@Wqq<jGVBPGCWM<mDXla9:H%WZKQT@Xq*?Ynn\F>ZqN:X#9@dL<#?\
MYN?@C RPQ/1\Zc4%Z>4\=w9&d1h@=u\Q@KAA*G>%<4QCK4>@mjEWXIY@#X@<\CDk:^Xk+ldmC9Sp+^W+<^j4AA
Sq8kM^ !plda\BNph?c<kppNKBQWLZXSAeX9BFPuTk<=VjCm?a6uNn%LA=5D6HJXYPBjhL<ZK8aNdtj!B@JZ/%a
h/D8Ba 155$@Ru=%S9?p5EK:8cnX$:YhayYZ=mP:Gte/#54bpPFw5+A:SK8^I=5%F*&ZibPck=i+9F!4cM&ZE8b
&aa!PG iFL9^p$LQkuSJ#qKV68c4TK4$^lX#n6/>d$5tLQXk4NHVT*VcHt^9Py1WDdKRQBp&Pne^#D?++:Gl!Bj
6#TR8$ u6F%ZI!kupN*9lejZWT!@jjTIyeIddB4?+:PY%1@&mkWhq+<iY/e8MK#eQTq=eP:S#^nDV?ED*Gj#LaH
b%hji^ T8k9mAED+iG!5V$8j@Jm5&^iCkhK$AHEh@&ia4a#5c^lh&MH<kCECt<p<J9W!PZ\iuAF6Rl/al&q5KR^
VlejCu pC!h/+cH:d6qtP4\=uynF>Gh&/R$I&qmkh&Baa*WScG+<nlpBuS!Dnil#8@hajGWk!YtaR#!<KB<61Em
G18RND Z*mYIWn/i<lA#a6eN9q+FkIau$dkHH9SlCIKl4KT+ZQl+ZFhiPS^VC%pehYKTG!B5T#E8CV8BC9T%^@4
B+#qX= I9HcKm=d8bTtEw/EXKbS%Z?jJQQ*h1EQJmu*Z$u/q+bZj:L$%+QE@<mtn+8H=@<MT@@1$metCwh!W+HM
FNp%dC tnSE=+HtPY4Cun#KAJbLu@VmT%G!tjJluVVk!FP*9W\JktkJFp^piVEd<d?t#6W5+iLjRum4qK@qeDGw
cX9du$ Jj*TNHdYdqd@1KVH9Fc^LFE@@>GEdw+!@X#ynQIGe&9HV8$#C4\?yk=#S:CDXB1Bb>D!GSH@K\+Yw^aD
i%6FW= D^LYAtYCy/ZV#QmPhCl!uMMt6b>c4S9<lPahu@Ajm5I9N!+=Q#Xw@illS:Zw\t5\eu$4$4F&@9TDHXkt
a$@dkH HZjL>h9cI<9w\wp%#?<%n>+>dX$=jdLSTch?M4J#?i\qi1XN+*\w<=YkYl5%#hGZt%i9bj%F9l^@@imT
<8BH1V P*kSm\kPliJmc<^im?RI4MCJMk+hILX*W6%TT&A9\i+?1wc#u^Nbt+=khPF$LFGLeYl<pycKiTGAVX&X
pVaNJR Lp?NZy*P@WM1$JKQYPKEqRZ^\\VnCLLRtMecWX>w@AGGBLakEKQ*bJ1KN5eN/SW%Q1%p+EX+V8pIhY8N
k1MPtD aFG+6D4I<Ri1d>lVpIS:it?wJQKTDEuuJHpAX/DG<BYN$6R#C4SS%Y+=1w?d\=^ITnYTN<HKHDAM^B/\
pdCpC& &qP\%LVl/1EG<D&8qQ4\D!8XcYARj^kjcMl#jh4^y?K/FtPG@P:WqbPel6cXqGYHh8TIp$F%+6Bda&18
bpk585 =\t4e$<R6A#uG!A??u4e/n>XG==+=h6>Tmw9h%kpHKq*Yp\/cuXbIkL&PGV>@19P*#9hQyn+QH<nQ9i@
QwI*@* E=?Z=*>GjPkj#$N@a:/plPb9tH<*j*eMl!Z&c<^YeJc?eL>ih+6\EuCwkD>i9*/ma1KmwGJmwcPmwtQl
LyB5S^ AIFaRCAPL8c9u%ma8Nl+?CB<QG^maqJTatIccty1Gwc@9i:c+VBR+ZVk<8Hl1iH888Etj?$aBj/QF>!j
/Gai&: L!SpSARAQB\KKlw/Bk+eAn\mIkITAkAF<heQBA>+BESeJDlpKn^PMVWA9lt%t^<IEy8NRqA6V6PlQ4EG
TlP>&> JVR@yZZ*Q/PVkGuE=hSaiHS!TVLE=>b!E&qciubN41QTB/ClE=MEJplJ=>XyV&p^py=9ZHSQd%=ciRWq
8y4ER> =6j*#G^hYV<JVmyw/J*h98cS$dF=G9K&5LF9d8eL4/!84ZhweqFV@@#8X!a?PV$:u:CW+9eDC*9jtQuq
A#TX:8 >i&jlciYNA>?&9>?6\!HBIh^>\pP>a>VEwFLYddXy&^PBuKQ\>Me:e4e>N&p!%\?C48D$%+$?ad:?Ga1
d>uNe5 :j@!X6DdJ:Qk+dNQ*<^eLCJd8XMbn\l<V8ZRJ*YpF!!NF?:GwY9aQ?WKd\Fh6!Z4huVyWSPFCSL<Q@NM
Nte<mZ JndDub4\Ld=K*MGy&>*B?XZh\bW$#d=XDnd\@HBiXB?%dZ5$c^M%pmAaEn+6R<P#FpLE#=$GMqh+mjhy
@BZkLC #cHuc^@CGT&i<D^BPSdme\Hm/R?bSw%TFHyBSal:DJAFQj+RFZdS\cia!MWwi!kW*+Yud9PdZ1</9c=k
VD\wHe +C1Q@ABSaWlcR<P4ja>l@$SNa+YCQVEuWutmN<Ny4#=nPEmI?E98wuy8JDM<H**LHh!#\n8+mPk:PD!?
A6LiPd 8+uM:bE$d5iFYqNhh4beH4ilZ<9Z:B9ZPEtJ:5XFPN68J!*i\6uDP:m6C8^9FI>9b6:hVjLH>chXC?4M
k>P5?P ^pb4jda&TMTGmQDVVB&iaaJI*=ELEYtL1lwbVN%Cbi:k8M^Ep1*>Nci$TZITk*N6=j8w?dLm!$H^edc=
\\5ldQ eRb&&q#5E4&&PT*1KylwL\5?G*+cRBj9du\e%IX5T5!yVWtSnP:bPdZqMQh&Xmh%uADXcSWyy@ISEp8X
RWeEA4 ^q1jKXEZBZdTFhu#^ij=ThyS#GGW1%1!/?8q%&uFKJF&?8qpJb?MZpY$@l^?h!LaX9M/614B=W9D&P*C
yAw5LD F=M#F5PaD>I:/pt#ECEdH^KeK>QC>eLBJyyL\8!dkJP^8/t>qc^/:M*H4%#G>WQP5h6+h6pp91G5yQ*d
d@JnEj @+><^%C>Fj8!@SP=/DZqn+6Z@6MmMT?@6aubQ?+Z99p6<N*h>H>4n\HVkB8WqWCw=Mw/B8>4q@$9epet
aXwZ#\ &6NtI&>9<thZLy@i\bF8LuK@9y5=?Xb4@Y@#buM*?=iNTJicX*1n%uh\CSXn6=#L4\h?GEJ1jt$%L>=G
<$Hm4% *eF6GKbbn:!:t@6:*QkjG:&NC!K5P>DZk#w&h*DE^&&dQ!6I>F+QGnuh\et<Q16R19$DN9H*5MqjG^aG
/ihGES l??TQFLc6ql1j#Hy1eu=1#ue8c$wq1>DQIW$K5\!QLPYhbTyealh:#hSFFtW:EjFB>t>KQ8>a?dtcF:J
4#C=!n 9#8j86W=PIpMMK=KwcE@WNM#SDAuttPX$t#/RaSEP8tjeV*$^1k1MXi1iVyA6kNEh8D*Hpd&$@4hnuG!
5@#T*F ^>Y9M$\cP9t8<w9GJR5j!%dPF%:i\eq>iZ%qIHI*qjyV4&&4=5h6@QEh*H/DT!uQVaQJ/<tZK#?%S@+V
!B#8pc IM>M&1$BS>8i<Mq61jZ*&6hDXq>?Mm#j\e$+4tm:jHQ<iAiZ>/Q6i*uc@5khHN9dqe6*9?bB1!b%1anX
-AE9E> 000c9fc51ee00110333 Page 378 of binaries1.zip
Ypcq=! lcMIYiY:%/@>>**15m9TH*qciMBDJPjeH=@*LGnB$kdi9@u:I8unn:qF9QJecXJ&lA/6a9IIHi1*^?Li
$t>n#p d+E%T6YQWkS&:1aVFye@GWpeLP+VnYbtBiK?jHw>\mn!<cVjXNc4ZFkup9TLY5VkECql/+h%w?LVceXu
d%?la^ :5RM!m*Scn+9MVJEce$wcB$PQ4JZ/ItyYl>P^IkSW>5>94^K4@>/Y?+=<?ZKTeuX8hnP=cpH<^KVce%:
eAN<H< PCmH8tbAh:k@%8ySawhI\588*4bK+wdVZCLhcck1Hw4b%PP>k1:R^aK84cmSNJG:tZ>dH<wKnPW%L/qD
awkyXi >619u$Vd1F\GJ:Nm&Gi9N+4VTPM^emB^61mXZmhjCa*Tj=hPQ/AYc1+b#E\QZ@VQ1**/^iMnC%%pZZl^
5pu4dV q*?i9!pNQZ<V%?aTc5W6*>%5KwX\V%y5\=8p#k>E49!Ina41A6=W%4a=5k8:=DqBDKE=5^q&m\lKh*AW
!/=SR& LTLjky49+PKVt1Bc4eGnb+FZGK\%YKb+SNH$hMZ/\PdLV5pLTZZyG41!QE:1hQ$YLJPl61+#y$cKk$ZC
jXP45W P#ke1T8:a>LQY6>d1J5J#GXEHnG@ZuPa>6:AVmu9kY6M?yC4@pHy6Zh?EIGaAAHLSYEWp>5&tT$&Lu:@
+YbG6l Nm=@d$A<nneye%Vlt:qhaiK=8SqipT^FhZF/wD4YdTH>?mA&HE$q<%M!q$kZeC^/Q=5iTdk@9a5mw*Ya
&^Yc@V dnYN5*DB%cNHjDLD+<pLG@WJb+CT#5l?9wm?Qw@B8p@9/kSej6&ReZ&Xudh69LVS+$HH^E&WBBJ>S^1@
Ft8dR= :qj?1$XHD+jRyBW>MFl%PA<QbWH%59LCSj\nbhS<9E<WZa4=>:y<I%w9X^bnbQ@4P:kuBDuV5/*XAmce
XkR1WW F*c=Va%W/#JJSeVFtm41Ija5HA88B6bbJ\FHZ4wXFbcN1ByV&=KB@up$TAed4Zc4amh?J5PecJNeRb<+
:MkQ#w >NbTyemdk4=11+Se/>:CjdX1VAaykKkuVhT%ebFkTH^p=!k=e<=G8=?JE%:b?E5FjT!HjK<lVmck#j/W
dd:^@E *kRwbP9<G8N/ytjwLp/mI5=D+qN:N==ym6c&$jl4cRE*ty!:#>FpYq:eS68XL?&>jTa$5^t#QIVEZm%D
+I*M>Q Lhk9R+XN9^^T^P@T>yFTlLN<Va*+@L1aNCiXa/a#TLb>/+eBMyJPF&HVVThlI?TV!6bQLb8kFFw^>HwT
RuuV$9 al4X$lldZYhBcXwSmCq#LSBSc+NT9AdDVXwHFlYT6Bd&>aW4?WwcQ$X>F%69+uPC\Si56LK#WwDkpHl@
Jyne<: F4HIP:nEkc#ZR<ChbcKjt4>8d=b+$X@LBNqaM<j*+wT&hGFn5S:an*wCin>#lL#yh!eC/Z$Z$WPH1A+a
%S6te\ NXnh8L<ka*eV1C9y^5binNhEntYwX6VW1EJmn\y$d#dGAb&>F!/&dj5Fcned=#<R!5&imIEwR+6pdmIG
Dl+Apu ShIjGVH6bRn9=nP%q&qt:VWYJ@%^LCqNJiEnNXE6LX%jPEe+BMYSd%%d&<\GKm%$RNZE$QH^eypVRVRT
T#6GtY t%<n&MS^bP<Z\JZ>6Zh8pXF5hpq@*41DQDF>=nJS>NTM\E#ip&?G1Tk*Xb>jV4!iWX\=j\@D@td&+WjP
5$N!wy 4/Z9%/L6d99+9M9um>T9XR^/N+uC5J$WMdq+kDB/MBFyW<ep??$mywQSyXFiHdyCeEEjZ/=R5mJlSb>A
Kt9e=\ >$/#PW&lKjZ:Mn8iD?qMln4*#>XEJKdV+J>6wSSXPS6mN#*Ybl:Fi%Ry:AV9^!!^WcJEVE1t%eGJRppb
hb#:Qb XTN%a!M$&QqZ4c!GKh5yFWIP!6K%VKtW/d!?:MnG:?y5ZbEith!MlDqblGlPSTM*Eka8/djkpyie8q14
Jb$qB6 >>c+FX++CpKk^h>+hJ5@J4&W$b$kQQ4/Qh!LVDa$^:eNwed9hKwB/R+P$inZpu$kiRjZqF>=M=h&A@!%
u!5tp> VP8W+>?8J:XhGL8ee1*<NK=V?SG8j\e*+6QYQ9j//6tE!DGV\/@uqP%@BL?:t>y?6?4R>4*X>6$ZWQ$h
lW6PW/ ZP4Fc:?KZ=<yX#t9q>Vudl%GdkG@QphKb*<>NLwytH!4=QqKiuJd1e@\5+j6>jcHqj<qcIjT=w@5Rmtd
y4M?bu :#1!t%MDQGXebC/!!LJ#j9H9eHaT^d@1mN\6@Qd4%N?*@9l*A*=iu9@QM8PlqlpF@?e6M%RRpDc+=SDl
KYGhIC 6tnRBkF6^ZI+n1T=YGtA*n#FAFA9aJT!/A^iMhu@C!^YEIRDyJJ%BGG/iI#jAXl9qAudFCWbTaIRGhjk
Hn&=<k <tybJAq4N%n#RFkSLTLMk^jiw^emFpM@8bES!^CGwYJIT/AP>iEypXw1$ZNibin1+Bhp#A%bHK#^ZC/l
m9H//D &k*Le8FPQ>FFN5W/Z%F\FKL9IHkEu*b&dDBl/VPPY6uZCZHFdGR8qmt<:q+RJt8VHc?!1yEd85L\Ia1R
KRFF85 Lp$b/nTZewq9cdBa1Q5y8n>6eB>d%CJ^&wAL?S\5mlD+YFmB6Z5dCnq9tuK4*cAXHJa@ydR!tT94ty$A
n^h^:G eImK9SAmTP<\Y/GTyB>GkShh\5HWWbIRB5a9VcHX4up5i@he&+@ZT#6+5yCBm+khw4n6B#<RAeV1\9ib
1E\DLH tQZV+5BHd=4:cN!lJTeApwnpkhCuq=Z+blw6e5^F9FBypQJ*wA\CnblWX%aEVjJP@8C*eVYatE+bM\mt
PejEP> a9VaYy1hibt<>/Ck*i<QA^HTaNpjeM^Y^AjX1Y^/TTdwH#mIc$&Hplu*S<hlZH5I8+w>DG*ISFj=^yLu
K5m4\w VcPRYYI6G=c#lJ>H^1:+lyY<\d!MR=ItGp8XMJ%V&w=uGwy*uCMT/h6BGbhZyRItWRSH8YXtlk&JYG:j
KjB4*X $=tiQXt!?BHpmd%maw!EYe4lH+/=\Yp!YQd##D@!JeE&CQY#4h4pNIe^ZRY<:5eQ!i>be1E%nwQ>y9EA
CcRtyV ?IK=BHD+6t=S@@GyVZ&L#?8y=wF5$YJ&4RAK/:iG+p>>$aXE!$Ll*5Yc@ZnCMD\C&?1CR=VR%QEdKe>F
Z5?h5$ cecNnZX$PHRn=?^8q8qIIYQyjpFcT@nJQe$d:B#bj=nL:i^DHMNG!=BFu:qhpkup@KLJ$5*Z&ID81#Ib
cTW#ay dS+XcT4Ek=qCEX<kEh=^q%IWiJyDhR+L%kPVTAjdpMy4KdFbVtbLAuCnQab%:P%k*XeGlP9/JpwM*@bC
/CMKXj SEZJJF+I&<4V<p6?4WyeC:hEk4jt>W>CS$Wpq*Nq!5e9m9tedy\&1dNu?XN!Dme@qhbMp%FeTqCcYXFi
Ph=XMt qR5F^ZeaIyXZV%kL=T^te1La%eH+yA>\n#S!cb>c5p+NCBJqJZmYK1jjPb<:BYVJI5#uAX5uy8td1SA!
uJhhA: I^K<PqjC4ISq?i$H>@T^Y?Cbc1tL<@S6$pACmy#XT8l6mwpcpjQ&SiIhBQNFaDcM&w8e4\w6?#yQ4VDq
9$=EY> $A:R:aWWY?4Fdd4IR?XhMKt!yhHZI1b1VK8LSpSyJwT\F<=D=K>M/ncFt:RTBpNSewK=\uFi$>jnm%M%
ZupFPp $LM$e^Bnhq1?pd?F5H^uJ:PXDFKMQJ^W8p4X\Ij@dP^W+RtXp:%ShHALYl$ity!L<wRZ%Tm5YV5atSte
*plMe+ 6LySnc\Si$$6%<JJG#?k&?9*k1R\=*S4HS$I=Vi4&8DTXyt*W>mN!^8b\Wp#Kw6J5:b@C@L*E%mSc>R9
kddc#D ^mIadddCmCdl>%=h9WVTmTaju9dTeIPH@<CHW:uyci*6D4:1w>\!w%4&Xad#e/&6P$NMYI11AZJDaVNj
CH&pB4 cGLmEGLe>6uw=hC#LJ6HtcLdpS?LGtKPqK=X8IeT5<pjwbh&jZ8YuaqEEkl1Ypdq$cY5d$hpWjiKEFNu
AQ1WLb EJ*F1Tt%%mBJHJj##R=DFy%&Vi+t=bV#JJLL1c5hAMMA:S*WW^ypV5ZhlaKij5NbDSWVLk:QQa:Bw%qb
ERyiIS Lww1:wlT\:mh^T&:!Vl1=%CR?4BJu:89$WcZY#V#hW>BTWF/!1&dVLNIXh1*RD>S:*1/HM^e8YjSa4H&
wR*pn> BdR^bMp@lnHJ\lb6<PRPli!nuu$PXYtn#KI4DDZQP@pW>yThp?BDa$%:aX$mPyC::9Q+t6<M\qZ1$*1b
HePtG? ih*R\G$Il8Fw8Y#QZ5Y+Llt<yu&m^kem^?:W=1F$bGM*8eE%%CF4lqiJE@Yhq#!aFjpmWK%9HVJej4:#
JCChi? ?8mm#E4D>DJ*tT1j9m4GP<HB8H$^I<chMR<GVKw&Jnkw$C=$9qtb:WS<TjTw<Bh=^4jMJESdWZ:%M!j^
<k1*Eh V1FTG$N6ZQ9qPDwX!%+lcc1>\?6m>AByT?SXY$SVS^N:j+SH4d4wwNKm6$XJdj6d5btW+9HAwWlpKmHB
I*RpVd L%C/#?q9yP!&W@j+p#+eCV1^\/uTX$%%KPG1:w\l1L$WypB<Xa<JAX<C?HF5a/t@i19X*^ZIe<kZjlS>
EjWkWt a1<?RhhZKXS5uyt#=ky/bI?Adph:njY<WKWjj:9DNbA@4&YdqZuk11m^aW*EZ9Pu!#FD8=$MKWa1>RbE
M&$FjF ^@bn\w@cuP!^N?PBh*uG1=4It86uIkEMnbm*u&9J\mB1yZ#>jw1#=91WQ*N&5N9i^kWBj/^=k9Yqn#M!
?GiYp@ !LEb%hm!4:<W&W:/4$=m6YjjG8e$=%D+^dBE1yX@qw#=?TQ+KA<EV4=4^9ti8>/C/KI1=Zt+&$c$l@1C
#w=Fj! *<ZwZK*wC&tZ#N:\++<G1^Ejm+?=C%N$yG1j/XX9hC:n5yM1etZmZMnFXblP55AYTZP@B+RbAGX&Dd9M
/dE59b akw#NuS?:qWG!La1V5ZBMyPRLbXCDnI?VLaX9EJ:ntK*B>4Q^X\Lal+Z=lLpb<//GJ^dwG!LTN>8HHG^
b9eIPG m><?cA$=E^N>>uVkSEk$lbuaA&@p4Cd54HNAMhbKLGQ/XZ%lKXR&qY<aFHG\*E:&unt:KLyT=Z\18I\M
j#nEuE /Tn/?56tj*q8$!it*kIcTHhQSeFGE&iE/uc:KtA\PBQh>%%i8=DyQJA=T9:R*N#S%lZX@QIwK^/MNS\&
G1Nbic @Gt59^YH6PKW55$/J\+DFB1w:Y9FndWVdt9%VE8yA*pL4>cYWeNW%Ee=Zei$M!K\Q#Lw%WeWeVMcabG8
QEAHBp &T+b4N5DKhS8GyRn@cqVXDa+=?jdN9DW$ltd+kA:$WJW#dPV@pKJ*8A!8MHNmnRPXiSKc/H8jmp&+Zcb
y/WeRu k9Cw$BV$aCYLT%k*RL*A*&QpDk9y8:6mnu>?1wXqM\Cu\Y4XGiBKkG^BKmAb9Cl#nq4T1=y*i^SXwBLb
W=p:VM NL44cimaI<WR<WW?H&n6G!Il1SmkBHS!\MFJ%YYu4m:h%?l*%GSw+9I*b*QRuWBRNDaXqaX#yEZk#Xl*
9Z^%?# dpBE=iqewweDATam4PVNTBB+mHyq\Wn^^Bb\tBbF!K6^\Ky8JLlR+Hw*Fb\%aB&MRq*DL1:Md8yGdP:<
d\?$<F RcGbWd\VZm&FI8jTI59kEcw<E8+R?dwGCYA!B4iS4EmCHLedZ4!*9pmiluyd<C!+P\eA/QTpQ#9pQp8k
JdD#*/ Y#iZPV8n#yFpPq6mN&?k:iRlE^?nnGpp=?!FF@?>/9ajY>*>Z@QT=cL<W=XY@%QG?%Q@W@>V*QlVFjq9
hQH/BW y&L>^>=:@+%WLN:jyGL^@nhV5j:5Pj991Xl@m9H@KQN#@!dj+W>9*Q?!b?89h<Iik8c?D<*%ADVZ9ejt
=+CDnD jkmc<==MDY/iB/D94auu=u$I?4:<Ft/?l/C=:nq9H9BD$QjXTQN\QkRN9tjpQJAHwDt=:nGt=HpI%?=Q
#ZZ6<$ K8KBQink>$\bD>i@lPd?q>A<9$*5?W>*<LDEun@ed1G@:mQa4:5B!5Q#pMTi@&kA4949+@lQE*8+@1/e
!jt<\H tlQ<8<Riu9?JhM#:X?paCwQ<VV4?\%Vlj/Rh\@=w>jk@:t%IFCF6#4c^>L9ill#Jm6acjHqFeJ>jX@=V
-AL@?= 000621d488000110333 Page 379 of binaries1.zip
hdI%Re d$N%P<%tK?+@il9cF4:@5J&9W/d6wQYZ*waXYk!EGHSJI#b%?p/cB\V/e!=Nl5+/Aut*m%+jnF%$Y4dw
N5<cdG V%/&t:41CmnhwaX$t:6ySuB#WEV*t=:XF6:15L$h69dR?:D>XPnh8K&u98BuGTYZkW44=qd4S1NHnYwd
5C?hTp B4#%GHcNac4%DK%S::A@=D9#18:n*=u$^ju!cPq>RZ\b61MPS?+5w!&E5N=a\/X5FQX<athNEPV<#wFC
u<PNS@ e$9X=Nd^6Z6A!?i945L<HG<Z=/?iC>/twuS64u^pynu<&Sd&a@cw9eIl?cTh+@9%h%FX@4^AqnGJt9!5
Bj1i4i I$t<p\/:VTwWD6WjVtme44WZTAKXEXI+:NZ/j9Aq8>SQEd45HSY#JKQRWWn/ZDctKA4Xpi^#lMaP?VN/
MQ@bFJ J5!*cA5u@HNJbVqV1<uc^/d!M9uW#y/#KeRqBGj*q>bFbenFcckB86%4*nE18EeW*Mnkc\#RD$&XXYWP
:BqEuY HS81d:i#Ib%lqp+FHliwME<Q5ew\B!/\np@n9bS5pL8^al<Cyd+Fh!ljC5FFY%<J1W!DJniA+?W%a^K>
BCQDh\ u9+bW6N%4iTbM!4qmnh1ebGMdTweq/BSVR&9q=RK:kS?qLQ^>ZKt$61aQ8c/>ZW??nI#L+lZb&F$KHdM
e:>8R1 iQtQ?dVXuh:\/lE/8Rq><q4pMS/yTb#mu4&\Y4AR+*Gc$y>6jJul>jq6q^iMEiJF+LB5*%19c^CDX/@h
@MyAHY wWQH\/pVHWpp1D\Q*H1^4FN@=YZ8hR9P%eIDqtKcE1Qu?lWt@%RKu@F/RpC4EbW^F1J@4eStaQ!?@Pmy
m&@<+L #DpB!p8n>#Mynwy9N$*mbZRAcw/:!Mhl4?b>=BMXJh=KWycaNX#F=t:Qq>W?*9/&9PF#mLj>Z6&SZ&l\
m5*LJq #<=lY#dnmPW+G%9STh8kbJ%$y1NqatGt#WSZwPi68e&*R9mQJ#h$Z?^N!\luB>%aE#&c>u$<8D!Ny1Nb
Yiqnda K>jR4RZan11^+pe:dq:q9>?/KBkJeL@EbMqYX#GTtL8tmLbc8M+w+S5:?/AnSiCbupqlYT\+Kqul4j>c
mm?YaC n:+8W!X^<\6Fa<dPh+1GFXy*Eu6<V<ZBFi/%H/Ecd:b8HtMILI?>1XHc?MH<t8j!J>je@IiZ4%<pjutq
lXA=nH <G:ni<hK+YuV1:9F#66*b@c91=Ct&qFSm%epWX=#cCMVN1Ek1m#t!y?KPdauM:ypRZ:/u=SkmNZlI5W?
+?#!eW Y:Mh*11k*+/:!Z4^TFCXW\=C&N^4VQanCF!<LI/mlJaEFZSRFTjypwB:khuFGFnXG64NujA%S%L8Bjn/
I/ZmPq MZelyc\=Q1tn*VPtm9l!kwE<m4BC5cacd<Y16/p4?y#PEFHhFpCGIGhEhVplcZI4cTc4a=S5E4T8Z+W$
d@eFR/ N>%H?MSeTGcik!#*$5>QHWFMX6iK\lIY>nIPV$y&dwic%nNYYB$mJ/e:<ym&LmZk#F=Jducbq9a!P:nG
SHp:9i ZW%i<!&S8Yb^wu1F69!CEe6YaLWQE<pl$%\8&%d*?:j1^<aKC!<=6yE/p6Z*AL*d^c\FpkMyG8#Ymk9y
ulFcu# Xlcd9i+c\9bKi8Xe&>*>1b^QLEbTYuq&pNdTNeVNS\aKiZep>#I$KtlH*n9\:XmibY1M?w#8QBhm/Q:&
tFhHE* V5Q/PZnkm<k8Mu!T^yYHKnNRdFhmMC9WQZD<E+ZEeA?GM$k<ZE$jYVI#u#BZ$@ub1N/KDBM!Xd1tGWRF
4E*hFE ZWy8V*IwL:kpZn*XTGHLmmY64nNXR&>Sy4CX8%D#eEKD&WCFGXp5QY+!jbw=WyZyT1baC=A**b!lXPKp
lIk&/# W1LbZDVDZ!=4Z/=V11qjN6QeKqF!bFKtTXw%!#<mjMBtW/:=JEhqj<=ky<i8ktA$hmy<&amqi:hCc@8n
EeWCNE p9+ZE$ip+ey4RKe1@=GaI%6aqjcnaN%TCpkbSZTNTun@kkD48YQ=&%yy@?GFF5E>DaLH6hhSRd1DDHb5
@yc?b1 WpJ%$>dVu/cEdJ!<$lwIi+eYBi\5n?wd1/?*q*XLjX\e&h1cCAF4l9\@*J!=jN+V$Ved61Ra5u8NqV?X
V+c!eQ *6N?>8KLe<>Cm+:#5hHmB<t>BN$QPqHu^kanQmh5yRq#Fa<HMSciD$WpjCRcSVE?&H5=^HdiSuSa&d5F
+=qC1e @^1MmQB^HkWB\46@TuIy/akd%Nyp=iJueip4n>MSLtWI/5tN\kuTqTi46T%Fe#*@$pX5L::Yi^B/i5Q4
l*y!RQ W44qa!/HGJb/Q6ml/^h1b6&\\8uy$+88XX&dPD>:%n#5mlQdISQlki@&!WN@+bHmS4%B5F89a8\p:m4a
J5*&b# MV8&J8Fqt=+NP\<c=%5QkHFCTkmi%aiBlFy8t@=9lX#tl\6y44M8w<SEjDcCmBpi>VhnJN5*Nl??9aSi
k&Z6nh 9@=ImmJtQIKYdeWhMwH*S54&9XC8y&j1JKt$ky$RE&%h\>6Bd&\q+=@RRp9qh>QEd=Z6?STK/4q^y=5L
Z>LPd\ bjbd>jL1Qa4A8M5NSuy6B4y<%wQj#JIe:Gw41D+K>w$CW!S%P&Lm9@5L+MSKY!ntlPVZhj*b&=Bh5cK>
G>qYR? ?@RE6Cd4uySYb^KmPKMh8@!$hGCB6%XQ^yYVMS>Lh>4X?NAGQW?mCXHWnu?F:PDFt?W9da*Hh/8GKQ+8
RNcQ5I w<B&ZlHENWGmRNjQBF%N%uhlLcXP$NdAFS=uKqiYDic14&$%u++@LC%JBJ$d!\%<je&$Lqkb:%=l$Pch
/4&1GT 8XDHCQM9XGwl+CSeCYh%IZheIm#&ie!?SX/djZ+dPjFMSu^h>Wi+B<^+&PJS6+5B$LZ5b!QPPjZJJ1di
<PJ@&9 ljQLea=u>mud/Zw^NI<GTLuYSwTIZne<?d#<>DtG&1Fd@uVq:X:aS8V8mhHJS/pw1@q5DKZDw4+P5dL5
b6!4FA qSe!aYiTjX=ZQ+FqL=/pDh%K1?=HM=EIN4+hiCR^a1@C5PNbtZ=JYn4&ua>t?!Z5hTLy>?uLndV/u!HX
\9d/^& @>dd$QFk\TuuKtqwch4p1YZl/?a9%\c4Q$=CZF1Quu/>Q6ten*=4<bFn<N5%\?:NTcH4K/jI:*e$e!<4
@$AlK\ G/?Fn\y@*AY$9*VyM^G8@H##=jHlLejeD^Fk&e?:49Qd!l&Q%!:u6%edq:eu%^W8*?>Wdy8^#@P1AHe^
%B85*> /Qp^YHjaG*DnSHA^bQC1n<yQEiHH/e6XYSBW&b9H<Rye8e6Wwann\1Zn+wYu$mY8Cpn:jelk#hJVQiTT
FWAd%/ S8SV$=JVK+C4GtKXEtA\EqDqYV#8k%KTmHL1l?L1lt1jn/wcWa##Bw*=LSyPe1F1B61?A#w+4\CuGL&p
V!=6QT GM&%Gp&XBpt%Eh&%H8M$G^Qek+uVkkIi#FP6BDL#AX*ue%YZkj55YPDNHJ\>4JIP#Jk#wK44$iqQ:DN+
#u8qaI HE+p:qQ^M#ek#lp8LkeSQIj/JaeCd4u+ySyqbLRcum%YY!itN!j4qhynjDZ8pNBS/RLLjdd\dnZy@hHJ
ujK??G WcTdieWT%SDt1NELEC8@a=u1b$#&k?GcV\#t\^d?^:9/uLGYJ%lQFpe&mDA:MAcD>+>@4YANG^GpHTHl
>CeSQ^ A?#eN1l9TEc4Ce4J$+yH*aQlim4/DbXjkuyew/Q5i<8*dTJah=R!J>CmKC$+!IK=P+:<i!eeKC^YmNtF
wcQ&Vk ZjP#IyV#>quJJ:iLKHQbH1G/P1wktY&&pQZ!QebXQ<JqwKRyyPmcjZ4$lp1bp%#S*+E/c1B:D9<eAVK^
5yl:l# VBu%TqhNm1#k5qhSl>#bnk#*Pd/4JKW/\!QuVEc*CK$JAj!h/d!8RY9WTe$ci:5#PkcEk5J#!hDlTQIc
qZMaJ: Y^bPF4yPA91N%+!RREYWWV@*DGdGPTd*5qn*dBbGJlc<J5ZJXydhSSd*H4##AhamSFdIiJ#:GJ9NGb9/
9S&Xu+ WkDiIn9DCn9id4#:edV/ERenDXHe%=n#Ww=hNA+QJE=<NHCSDyn/G<MF#4HEP<=+$thl+EC%eFeI#Q\R
LqEmA# #=n&PS$WLFQL?NuKBAyq%V6LQ8CWHTp#*XAYQ%B??1l<Tc@jnG6an/6Y$#^&Z#$8ankmunlin@1ep#9i
J!i:F1 MpVbk#A!kFhD&:lMm/6YnTw?amqKhLp&nRJj81jA88?C?!D&w\X?JS*>^^+QDn/*AhL1VPZ<:q=FIS/w
6nye%+ /R=Am45&nDS?TADj?VM?=hR\q59\/<i%yk+Zl@&5*6c^Z^e\ejR^mi&H\#8tFER%MX$hX<e96w?4n<VP
8ecBkk TR<Qp/a$mhu^=CQQZ8PQHwuH:ak4ijDYmhE:JnJ1aENaFnp%qXk$XYjX>e<l8u^H\wPZyCN%%ktHdXDb
==biCp Qn=<Qtn\CcqVyBkKyu4%G=u<ZX%QBN&LIhFLQ^pRG4TmWTa+<9Eq\YNalk!kq1C/jRE=Wdden6HV8bj%
c&bkA5 yWD6^1N+N\wNE/GEV9PnFb/ycmZ<EH=<C?=SL5Z!bYXaB&u%l1BmmJK/l<JSp#q5VmY1tqebKuaF?B#9
q9^qe+ K?8&JcPFIiTS!M?F=X#Zw#b>yHLYw/==JRTnw4HDFb1Bq/>dWIbCFRnaCP6Y\+QV?G6@Q9aC>NJZC&m?
kMh4+u $%LLF4kI+Mh@4+L/qPiKT=^il%:LT+h#S9AmlQBeTii5m?6RP1n&T865TpE&u*HcT=l#VLq&Sn9mDiV\
>?$J/C 8i=MuB$?9dqt#aKGCB&Bu9+qNkEwTQkT#ymkR*n1B^$ISWHVV!Z&V5R#WRS@SKCmEBabL%yZdeA%BRM%
p@K@Yq !<ciThjJTB\jEF^nT=X9TKwLtMqwtRY%EM*\Qmikb>P$>1/uH!SpMietp8Atp=DlyJ4q$+p>Ma>NbiQt
l:C?^L 5CTI6hnTD4^Ga/L8X:nt6N#lp1lVn#9@cZ*iJ@ZE!?cJl$*8uYTD4%TDp/*6up%T^P94N*bRwN&VFE:8
J:Q6Zm %*dub@acKHc#^bLZPY<<LeFQEIKVA8Y$G<BJ^4EZZi4Ty@PiARVADql98eCbnKGnmAKZm+qcITliWl?Y
n\mAKn =MI>dZtWHm1X^uiwih1R/Jl*9Dmnw1NFyENAJbla%@EF/Fa*b$CATHRwSywIP*Dd5=tqW14*WFML$meT
y=W$\W WaNhKTbCXZt\ibLt/N&&NLApqLZ!>YuFTBZ>DN*KyPNLFSLitYk=QVu1M>DipjYM%/#NIL&MhLhS:IFG
VhScaN i%&$P5dy$B+@F/44<MFj$/>+y+cy=puEyk9NF<c*+buV68Sy$b#cMqbjeA%&MWyeeQHEtj<!I$i+1#:H
l&49G# KZKb6?EbIFQua*!%=wJ$J$yw8iBw=?TY&W@R+>ARhi\X#NLR=*QFI+E%+qiwSn#d=We>RyNM=%<h!FSH
an!PMB ^4CNK+TNR6hE&<ayAe4h$u6Cb>Fb#Su^#8?J6L?*MG6Tt@*/SNBZM@<u=eE&RudEny!/XmE5Q+Kd9Nu>
iETNIJ n%iIk$K>\$KdIpP@^wd^Jwb=y+R%baS>#R:u#R@*Lk=9Kk@@Yl%t4<91Zj8t1jZN%++I*y+I:+GIy1+*
T4$$\? =l+S<#PS*k8SVe8SZ>jC9ehZmVjCAqmmt5/mic?m9Sin9L?FEb>Ej$PP<WGLca1NHntLwTTLqiAI%WPM
5mdh$4 %TN@@DWCTwIjt@I+>n%SuB+$*web5mAR^$eX5!CX+CMZ8wAdu!KWTMIX>@XNAy>Y9QhJEl>hawyhww>V
=INmq\ EwqN$niF6#+?MR51eh?<EpmaRu&MEqNapqP<p9Tmp^jap4<>V@tYHj*6>X5?9@k8u6AWw*k?nVmT6Lep
E1tF+\ d?Q%/yMZ86L+e6Qjn$VwFcdwtcVwmWQ=DN:!6YdwYYYT9MqMYa6QGZ9Hh@XtaT4#Y%jc6:PWBc&+la+$
iZjTb< H<:pb<C5qKB*#$m!t$w#?JHD>X4ipA^pj&LL?VaS!miT^b8d+%&b$<!b^!?X@b*4HcqatM@!t&cX9Gh/
alB^tY ?W&JCh?NC9m6epuNCy+=FZ\dKYl&K*#tp@DM1:Db4+n*K54:6bV1haq=>@Z*^PJuKeZNGeW:6uD*PMd!
-A\%jK 000ed1bcc0000110333 Page 380 of binaries1.zip
cp8jp4 @mcJ=T>lyQ>ZjQL5@@@MJ+@d:<?i8b>yIweM@?mb8@=u#%#b?YK+6ku%AZlpBA#RPnKtBp=hBcKuK\l#
ZZ8m6M VZ+jB=QG<kp@bt/Cb*MEVT+KapR&uHwpMtLkE*CWSZw?KSD*@LAnCC<Z$I>b/kEb<bQL?5PLn=#>Jnhi
<STR^Q %=!5iYVepcS#<IX<CTMd@p%Mn<6?i*&bA/M1\+CbyGe@y48*hT?dtKmwaPTB4DMIK^8yyl?VSZ=iRP+\
J>JVJR b$5/EJENC!Ru=5Tk$u:RLCe6iydPJRN^5FKRt#\IFiWi4?8*R8Yw!:DSX9DTFiXXtH1&KCjQXZJeD$te
qWF\Qc <dHWA4t?X=i:!6IAK@kl$&mw#4a/<ujMCBu&I?FySVyNtmESpT@PGSW:G$**/#jIKkV6k:CyqAl^%LmM
FeFeB1 pwmub4%YNBdB/j%b=ewPcNB\j?1Qh#&1tM1FVGjQl9pX8QT*QH5>$\u4=+<>1V5t#Fe%ZpL<#HhpVKkm
l+MSZ^ 5GZdD&G9*yeu!FwlV4Faiyqb^^*Rp$5*TBBa!A&hL/VIW!qN<kQZ+Hamk$BdV*4Xjbc@bE:!ER!DLGDG
QVFt</ YZ!!iISm%Hd1u%&eb>!X5<$P*\>?c4SWV!^@4dBAtBYG>Z%ZLZ1:XItw%dd$1%1cDd!!q=R&KXmXE=pj
KSBd:@ MBhAlbCqFhI6j*l#6%=H$Q/BuXX4KuNyPKn^<S!GF6HEbICZ\8P4b%6ZBly9%BitkRGXCyE8HcJG!lPh
GjFnA= R!mwZ1BKF/pPB>M^%54lRwu8W+pQ:#y:M*V+*C<!SMX$%H&CB5dqDpNmYp>eu#d&AGt+H1?i<w9$GD^Q
^jekX1 jN&tAuE5uLII1yF<q?Z6cX*JiT/aDNJYuW1T:LFKK\KbpltW%CA#m4+uRnmiZpqXb$jjp<9ZyV%IS4RY
5>ditV S%MHFK%?Hq&JF<Kp$^^w:@\enWpt+=cXZe%aD<qbjacDlMWy%*u?1Y>cD\<V:JjqQ?8dP@t<*e>iueAj
=*SA1b :kS4iX$?YIuVIBlEG#B5=tyab9XXm9KRdM%S<nX!Q$tYb@whuEcei=CdeD956w8+^pknMl?=GBaENPw*
hZh=NY n#!y:tG*>t%an**Jn45KE9AtHmbF+GiVtu+Qahkt5Wl@^lp#5ENyjd%kWX5Sa<?u@lcy^lCS%WtZH4/M
BG!^lK ynG>H*hc*Tb:X4Z@my=e$V=B4lSQmuLdq@!SYGC<+%jC4wTuXIwBLc>K?MRJ</maLFK@ea\Q+waklYhd
DRq\@q 8VJG^!X^bM6&*pXjYpbC8N:!:%=HVZ4+A>&VlJWp5cpLl6EXeDLwT+t@u&#qNRDaEPVjEtmc$qq<iSZW
PM+@8R 1T98hZ9JwBEX/uDGpNT#tdN6*1^Xqb@Xk?S4Pe+9#md@*aiIqpyw>lA@DqLly<LQtlAV?DdJ#wiWH9Vp
\E&6Yi iAMSFTCdSj4at9^8CQ:EX^Z8l*SMAGW/np</5?4HET%lT+^tEb?itbMYHl^W?p?L1dX1kKt4Li\hmI+G
e9Cdc! eu/Yl6:HhYbNakY4E4Vyu1lniQ6NNa=Qn^u691uk9cmLad&EVutb4mc!#ql\lht#M8eW1Aey9+4ZLkwP
y@<>l\ 86N!CA<1G!+J+P*b\cW4h#K^F^M9%l6SI=6*BMb#BcSD!$a/lnD#V8FD*<6AI9A\j!LnW4!4DJd6%/GJ
N4R^JB iKj<5kNAJwZBPlXhD8V&ABCl4m/&8B1GMeZ!FM\=LAVa1np=FZFb!VqtueXD+FPyF&W?4JMb1Ih1$w@A
nK%PJK jBj6*=ln9G*QYWjp&X^ledJlT<wwMkn9<qlp\p8j@Z:e?D^Ic@IRY@T\HuGwTIKalwBS=JAVL5t$b6bM
F#^lAL T:NF:kq4mMBydp/85Jydldn+$/LX@DjGJt4iQB*Q:V\NJS<@jYQ9aTk%lYDYEmyVLj:ImKpWG:\E1e@!
RhA^LN dWYp6LceVl$!INCT1wP5alm\+\X\YmXqa<44FwI>5GLW%Iu6$^VZLde65M/^yuk4?ZIGk69p%+w*hcmk
qaucAS G?RI=1=I#EyeGNJ=p&HNuubXDdw:QNcT=/@eyZZ:ycaZ4Jk4P6GX8V=IAQI?piKAl:n=YmZ6HqQSStWQ
CyV66@ j/9hLtcM&y%W\y!$D&K%e=N/q&!PXTPNPu1?jtlZq^<H>Z?!T*!VG<CFE+Pj8hjG#=J6c*pR//X5Q%A5
!#j1my H&&=hbwK!p8V%1dZZwWTkc*XYD56dXHb/jT1tX@qqQYRp>4=d^yL#XBRwX8PGZ8I#n85G#H@IFd5=N^m
k5F^+9 RN4#yS<yTb5KI^MI$j*/#9IaI$yQqK>R5CTDpD+DEu5:W=*HVQ86$tRT\C=hS%Gd^@KWe\5lXcFP1aEP
*6&MNc 1Tm^$eN\a6!NW*F#PBX6kqkmTCPIpQc#9FntJ&ZVq6Ae<d\$@MuZNhWy+R:+NP^lCDmwyhR4KN!^#%J#
u%@QFF l@&$=@S&Blb$#VQ/HT8HGTX^XE&4IclbpeBw9V#!@q@jeMPQ\ktIDN1duj6E?Ikq?VqGXeTbW^\dK/k*
D?p@Wa >N<WQki=PkGQ1Fi+FXj4ncdP6pS#ju^?EuN#>N!=eSIh5#/ie9dc=>$T*DR=@SM<nYIt*l4QAkkuI#\y
D9X9dc CMh5dKG9i1?bTkT!^BCG*FtVl$yhdY<9pFuFb*mFSyC=#1$V?QWbD:htY4+NJcXwwl:T8B\ZSDYlT?&V
6=Em1W &N5^^y&+h\lNqw@MM4?@/B:#@Jl&DhCRW=$QiXiMNGyGL>I<9&ww&=HDjGJqY=k#!6Zuq:C:mVINR8ad
yZZ??: L>^+P8@1<:Glb>QTeMaq^%lNDEZ#m?Kp>td%hB4LP:&:i5Y45RR&6iYh9h:R>#Em?#@ZmGHBa=>%AKkG
pyyHRk +cd5tAq9GeMHny1Pw\:=&&$bn!<H&R^QnkYZ!%?M5>8iw:Qu!qQtXLK@e:!JX+A<y*$!k$!PKj5XG$6j
=+CMiI Ft+%8d%#akBWGhJdX<p1a#w:*c<5W/u=a9PJi9GuMYVJ\L%Qa$:p\*cd\+YtudSQ4ndwd@5Xi#899>Qc
:BAK6J y4C9t!EPj:QZR1C>*il#L4b94yAc:qD!4NkmL><91=ApX:Qj6!q^L+<bXa9BjKJ\nedtHl<C1k4T9pci
mhIiq^ BKJH&VPyq@W+K^#A1buPq>NmAbq#:nwuDcPqd$:p+$!ukJZ1MTPW1X9cV/wckaQdHWHwN5/>XYHpYFX#
m$/p*F /C+SJ?mKby8jq&qXq/&R@JA@aFyDPyGNdb##k1\%NRH/pPCc$HBMaC:t#S9dBBtRZiitLcDdAPB4*biI
Y#F&Il bw<NwJ/*6jc%&KDE55%<yS#<9NyVHKQhF66jMVwEZmWCBYF*ynJyMPyGCuE+pq1?&NhX>Fm/6MndMb4S
J$5jql H/YyA#P$je\%5A!J4cD@Ve/lW+T8$!=:P/P=RpFti*>MAK%%!LcnPBADy^CZ!6t*?>h*<6WpBbpun5ed
KWJmjW <B#lby#6VK/QQm1XamDi1pVPi\VYDQe?R^6T>>wnDVt&L<u*qy>W%tY$6>8yWC$RD4D8DyWiR\GEIa&4
w99kQ* !kMFm^tM=dhHa<wV>F!wHe@5\!YL:Cc6kZ9C>5Z1\+i<Ct1TnDSj+eX9?ZJiANaD#RwbQ+c\Y+$K*9tP
PhYFCt kZDlNDdkAF5^9SkI*j9mG+k=QFu&/&^h4DK*?dcal=SFRKY5V=KV61PMm+nBjJ&K:DGq4G/1H>%H\Y:9
WEqjYe TChj&CJm*1yH9VN%VmyQw=cYZC=tk!A:w4WQ^lc&Z/w\/?&A&L1yKKGmYLK<4nTWuPK4ZbPiGenWb:GH
N1:SWt HF&WqTNT*K61!Kn6$F^d?9MGDuP\kD<AaP:N5P%MY<GChwHHuG9KLa:LX<G+^C#J+bHLP^bFT:6Lk^CP
VTeQGY cTu@S$JSqnW6bTl\w@&?FlT<uQ<:LTl?q>#DT@tuM9*jV6@l@S?t:*D?8@*/*>J*PQ@tYQ/\>B%P<D?p
w!YL!j :@^Xe9>HMb@*N!pX9JCHPmu^\l/C=4+u1+GZ/!Fw/D*JIL#eD$F#*yQG\59#ADVZja=C9L\QRh@u\<VL
k+W*@j >\A$nQii^CM?<EQR>%%#Q5/HwKH*GM#\RS/C=4\u<an9IX!D<6$#a*\Q+S4$91Ru9wh\DR1>D@$R4pH+
i9>^:X :tE1*$P+B8G=::\j\nZI9TN@CNek>>\quPCHeI*#H1e$V9BD8Mb=D%M=\R@l&4*JZy#kl=CN/^:DMW+\
Mj8Yb! :F>CQ+S5pH5<wDnBD!EdqAh<D@4*1YL@/iAjqmwGkWEw8j:+QPV/>T@5IS=RuPB@TlZnjWC1&F>6u@/T
lJcGhG Kkdq?8hWMe/@:@j$:=&pad#@Z%ueR<9mG9/Z!?KmpV6T%j>TFpe5:d#aVA^G!P%Gl6lN5eeEh+mGj\Ga
QX?mD5 TT1QSWX<AEE/@TRS$d64Q5l#I%P%1:EG%T!%eHSw+HVBFM#kX5EjHcipaEH+H$C<C4tm/tMnj1JhR5mI
j$14uW LF@9AG!$CMPm:mN+IJZl:lEJmVMlPnFw68kmwY4NAi?\jDdeEVwkJ1IPyBkQ*4@RWG!Sa^iCS%ITCeJe
9L/ljY 6hAhBRZbRwa%Ekq@nJeVQBbum<p4=We8G?<tpn6bMy:lGqT%J^jE:ITReK:VkH4y##Z/tKd^/8$Mb@G8
u6/bPi ?BD$8NnIJ%YGj#J=B8FuBE/1BkR6i1kq>FRLVu>l5+SG$CkP8ct9IZ6I\6/KY1qHiG:<FFTWkP+kD<@<
BSwBVy tFMcJ6bT<FPeGWtP%B8S!m4RH\!1cnBR*mAtyqWMDCcliZKbDEIF5^LImFnp$#\Yi#wT?HM5wp5pJFm>
kQ&RTZ A9uF=M!H$hHB116+G#M#$R8EZjen:YE^4Zn?1?GW/#DXTZ/6tJ>ap>6B/aee$5QE6Y6\K%qH1Wd^8WJn
tq6^Qp ^t*?hkbQcIjq1iD//1bclMp5c+?+8uLuTSZGwaNyplmMS<<hh6VD>Y$Rt\=hnIVHkmw>e%9P6KRQm6&1
6>KJFD /CZ#GNFdwJJdiBR6NAK5L=IGnnF9hppW8=J*lKEZ=\wiABWyFHcuqy?S!4XjZj\u#*IJAZiTAV$1AeA%
\%=%>/ ABL^hLZI/=GPX?%1Y>=mTnQ4d55*K>kdS9TJp5kE^ukC5!>9c9Fim1RVXNYcWI1hQ%e9&4&caad*ehph
+adWSb LhGTj9ZP*QL=&H5qWSqqBQ<5b1<B8utKHW99LtKZ=#LbMP+<+5>Eclj!^e8GRn4yt@AKil4:H$GFd!85
+lBG#Y $<*!A8#S98X4N9qu/>NSm:p=I5LcMHA$G4XLtpB<$=mBbtqGWQcaThc8K&^mA*#Q@9bnAqjH86qmHe5l
<1R/?K K/wA^NClFLZQAPVmFBIaN+c=9Rw@ZBbXjd$11TEbJhDWq?H>1m4iPCPnZ1SbVI>EM*CMq<iL4mebM15?
/4#18w 8EFLAIBdwG$B1%Hwm#LJ5*Kh$HWDdFSXje#&JQu>pY+T6MY%NK*N5Tq=%=>Nj5@H4E\uLwd^Fu+?4=E<
GLyduG 8kRZTFbb4WpYcWc8Vky+<:GDtN%XQiAF<pFju&%?**+?lbqXyCua1=</+N!9ykZPA^ES\MyNkF6/?TSe
<qN<LJ aL4WnLkDPtR1uk@#T6TlmqP/p/Mp*Pk+/Zpt<jbQ\E\8*Q/4VPGPWYIjeN!>EjJCBEc1GtRL\4%NP:$$
qMhVYb $P1?5BAn*iwTP\FQH&E4N/FQL9k*b<1=pyTR54@Dl*mK>+$\y6J\!SJMjedT\I4IH&V><Mk6#>/N4W%k
aS&S!1 T=:5e^Dh5$9PE>+85HW!F:hGdStV?lcZ5ymEqcty:#h&I8hYmpZEIp$lMSV?mJWTWThkba>/1V$d+t4a
AkTMt1 l4p<e^DkhFHXcqpH6c>ySKNSMyt=!cqw#E/>yN+Z\\>PTV#aQydl:R+/ebtQ5mLY^=aT&R@&mWB9kuQC
!I&i>N GY5W8dRnIl>6TKbR!lP!4m#KAm/kDRh/5XySapm^ZG1qVP:T1?&PZGTCC44k:$ZjuaAphF=5NnHluX+Y
:ST>bG 8J<M*MKT?qeu!hIY*:pXIa$XN+#YECJS&A=TZnLbR$IKDYtDi+&iG5u?EEE*W?NhdTLNZW</eP1WqG$+
-A%8Tw 00059af093600110333 Page 381 of binaries1.zip
JH9c\< wybqHETu>wY/b#XwGXwPh/%C$p%XB@!t>ucJ4jGic6aqZ%XcLGZl=GZXjhqVVmuKA4IX#+ALKI6b*BP\
pnIbQ* +GQ6tSKR=&VV?nX&JcDITZdwaq6?CKpq?XkHEJRp@?tIIZeC/ZpPAyyec&$>M#i4aKTP=R9kp%!$KG5G
RlHlqV y<ScEkw%J<\S4BEK^l\QPbZ<HCSLIEBXwC!=wyR18cVaA!@R$6IA\=%Qit8KncbSW*4\ZM!1WQZA6M<w
h<^+Gl c9&R!N1LRN<ASBC#6jkVGR9mVCthe\L1?TF^iCew5Fp19\i^h/1Cj!Wm8yMNYl^!A:wd6V^l!Zm4MiN8
Nu>XPE n&bA<8X>NnVJW=6DDJt^ZmH9$i$4XZ$d4NbFNyYL#Q^ywk&=ueC>X@69Y4%Q$hb$N$V\T?D$Jq%1AC1N
M@<HLW 19YFX*Bbeun?u/XccQL!^DVa/KD$>DlL1WPEGwW=G<wJnHb$yP$tu/1>PTMVy1cyD%Sd=G>K9La@GAD>
*&tEWQ FIGS4^kC*$8:$Yy&>^GB$8N&4h*Qu6FcTcDpyjidwc?!M*%hw\pR<I1!NCcBtGuaJAe!iYt^bc5hJbb#
^\^h&d WR^PK?Hq6\$KJ?+JWCT/N<PGmnaIGn1Fw<MwKGVK?mCt6ic^b?tt5wibF=q/?Zc=+4LIBL8EAj\TbPuR
uN/Eju NuiGR:=/#@ce=c/*VtZ:QZ^Jt^PGZtS6P<eF4S65jJnb^/XFwE9d>>5ZjAh^puHSia*iCe??R>Cdiy@u
SBjeH? e!ES#MY*1VLPM4W5bM:PGKRhCW%DjPmn55e@d#/jk^t%ZMhjE*@*!QaWtlt!eiK*5jK\Pd/\#98G6Xmb
aHHc>V FKGnH*<qienaQPT&ldktn?HiCD1&PjpTQaP%hQZ>Kj5$<eK^+4DCG<an1=HyZDXINR/nA6aKdYFcpKdY
+Z%J?9 pRdCqHAK:dyS$\lV@d5GbDq9u^<YcFwlKceHH6EtDXi**/hE4<1*p+wkAn*QJK^j9wu!!a8/pSM5pS+1
H@4H^e L!48>jNBPiF&6a>Yd/9hE%bA%Cq<6#qYdy$jmXSdpGP8kPBnQ%!PFcn6K%wj%j#YijVYXLSC!ubWq9k#
m+K@kc ZXb+j%YM1YPE!?AH^6/d#Tn^Ttu4A9RpdQMuA+=j<*LeIwW^=V+@p*u%p4IVC&+%$YJdFAPWuMh98L11
GuyD9P 5#Gi5R*ipB!Zb#w$XNX@!jR^yXkA6WyZ^M4:K$=/*EDC%D/:Y9h\C6*u$d*kNFZ968=eXPSLIS\j>GDM
Eni\@* bLVQ6XKMj68!#Ej?H^B4dndwG/\VG6m16BHHwTFJaWMXuK1\C=iQAHM=LG#Jdctt91=i&4F=id4&y=9h
N?::6c lwG#l1eXu:a<njwtnhWanjPQQ<p+K@h<X!m&%A+#%cS#N#:NebhcZYD+@:H*%&F^Qi8&KN!+NR*BkmZB
*T/A^4 Zb9G4ZF*Ci:8HmAEh*eLIdm:R!C+8&5TQLlDEwJ<?T*b!<I?:L*&8jh<=:q@hhQypXqXe<!c5$c@Nacw
1A>MTc dB@Z/=*RcI5>E?TV:Y&BGwcTuwM1KlK4Z8QE*q^A:!y$hhI6#1c9L^h%XRT$6XE#CuRT6@EGq9qLM/!t
Rt:nC* qWZP$1d4IpKV<&kt+!1JyNJB9pMkMadEJ^%Xq8tKXnqy?iSAiuq*a>FN>B&!TjjlcGuEk*b<E5PuJwGh
C=p>\T Iwt<1Im4J?KN8Z%w%Fu<wElDYl1*Hm=LYk5@BY&TKtSj=y#eIK*9+?GJ54A1JZ^/THc1NeR8Im#Vy*ZN
BwcV8h nJ?4TLRYT%Zq#tVIKNj#a\hm/G?GtL\91=#JSe@WbeABM1wP%mZTBRL9VHTmkFt9c!!?XwJc?y=Lb?&V
p:=#Jl d>tTt?WA^aCkpnLkXA1S@V8/Qp4WmaZ#5H9M\DCCaQXSEcyciAEjLAkdhHMGGh@</<Be9N&M\4Z9^y!Q
LbtKn% HHH=%#:%?BXLi9^hKkjj!CQ%tP9BZw5b=SX*W+5:^VHSpIZ%+4q:+:&/e?JR5@YJaG>I*#tVAw&j>F/>
>SudHQ Ik*dyukS$4y$Pb&kqVp!leDJKHSMBc?V*t+ddiTC@PPFYe6Td#!diD!@>WEP+uh>$MIM!9ylSP#HwDN9
jNN6Fb 8^^Ep%qP8#q#16AmhCy#&+@4buM%XLqe4D1c6NR<nE9/XuLeIn^FwFS>6myXqSRKPMthMVK&ImXPB^a8
W$a?^d JRj^1NPuPh8&eWi$y&:WnLj+a:C4NmQ>dFH\+8wS8<S4<iC%RdwjmyQpVDRy9a4wRTdw5XXLymeDNY!W
M=DGR8 !qd4b*4<IM=ueiNWJiZQDniHJ6jF<%\&A%$&^>VlEePbpB#/+4+#^TW&J6#+V@Z\5%1wndq<njbTAhu6
\XyD!Q $Bja4EJ*K4=^^yDb$W%p!teeV$w/kIKLw?5RRBYm$TZ:h1>l64%pCwGIhn&n^\\H@iIu+>STJkJHGITu
tuKukm =k^H*V#HwK!VjlEy$NIJJSki*WWQA$&T/8cWHqe&?q\8=ytp@NKb?eJBa4CV=A8MubyXBX:/MYPPJ^q<
aLI#%I %1jaGLI6+<y9ud:SqJaM!WEhMe!tHMd5KMpEFb^WK%@SKL!YbM:<Vm:>*X14bV#&YK/wYmHhe>^ZR*#y
<$6H^i &n:<i4#K$t#>S&W#9$YJqlLkSwRaMVB?\WEKe+BS!e#5%ppiCY+CBT6YJBRZww1wQl#Id*D$Y1YN8=A\
np8=4V N<kI%h!49DDcTLS1By8S!h+*uhbw!u!hVW\kb+^FJnBZm=Iu*kVi$yLJmy4Pmu*%:ySY*\B1X8mnJ%14
dTX&Xy M:pkKB/95dE6k*5nIPYyFm+:LuQ>HjinVL<h&#=^Z4tRn6mJpER&*@+mSmWduK&j+kE6QDLN\4l+RP:E
%DyZQK 1*=ac#wt=I+y>PASc?aW45$qWL$Hip+Ty1m=S1I^@au$uwERnltNwyn!>#\e^?BcSARFSMX!<qldJIT4
CQaZWM JdFRk%PcN/!1lu9+dMiYF8X=!%McK*JV?mKRq!SC88lqT45<Pd94>?E+m$pPl1^WTqh%k4b=Pk&hh8Y%
>Z5#m$ P4*GSKKnFmeY&bKJ$w\>P9q\hmkcc5i5=wyjVQKd58Ac*GJM>NWbTml!nT#k?b&B%+k=qWC5u%im+bQ\
6^5Q9^ EdHRmF%eiQw^SI9RGAPHKI8q:hYFcPTDcJeNGM9$\AD&q$pweLH<Tp@T+F*M+j6VLP\KDMTpNZHZ9SVC
?6P1p> B$/FLPPDEKZ/iT#>4Cl&*wy=n!5Hyq*Y$wmQTGe68yG5FI=6wVkQA<<CFiciEP&E&Y!@<GyaTyI<>@\K
pQ\&CJ 1$y^#Fe1H^<\EW%nw!E6RTN?^cce@Idii&%K^N6W/+%F/DK#$Y8TeWiuy9QlL9W4:/!IeTIS!VD^Y9<l
d\Cmle Xy&ymhBA?V#14$!PVQu^+S8m6^S#lEM!*#9!#q<GQBRh#j1QCem@%i*@/*4>w\X=%u?MWQ+9CQJ5uQ<1
&6H@:w !LN^@NeE?V>FF9!>IM@G@n6Bu9W*Te&5j<qw@X@9y&Z>VXL#d>AeD/Eln$GDH%CijyQW@B9$A%uL4L>J
mLiKp5 c9=ZNQ8DLih<DQ1B#GHY*!R%@\d>RCkD/&?Ttu?DjtA@Li69pyy@k*:A<b*%N$uN@+1GeD&Ejk#ZIJ#k
JL:K$& B>CQ+SwE<5CwkS@DNekDaet5+Mh\na*:AaWX@Bm85ZE?lH+M%>naH$I@lt65pIj/@Sm85dE>\DY&^*D6
WkTSWq aWthnjXSq?kD$\Qda<nG>6B9Cj@hYB4Y*<VT5HI<P6?cqj&*Q=8!@qMA#X>Wh6dj=KG\@qe*bQ<mDymd
STF&Fb :W@b%u<EQV^Cbj@HQB9F9+*4j/c!@<ei:D?y:P!@&bDN?9hJN@>lQ5jP@Z>Q94Zh@:@W:VL9:R*lIJPV
9/V*$= +?B*4HqPNcCK$C^^SujVRGpRTJ5WiTJFDJV^c\Ip?#Aq4Z&V\VH$@%miG>@$#?Y=d%FnkjLq>Q+=j>RB
@$uPS9 D!MTBMF=BR?^DJ<++MDD+c9\S>J*KHI!&jkKRaNKT*EcYGW8TEWtXCqI^aNXQa@=K?SJFDt1c$5Sl$CV
j?BjTZ ?\S!WtluC%!M>IFuDWAbGSIP!bphKQ5$jiBdljEAhq$FS6q<bkEtc%QMqu+H8uq+=XnjcTS\dQ^NE##8
CFBD:H lNaAP4tyFR=Cy%!aRSB5%1S\EJ:P5aF1y%nikNaFEIIDT84a?%C8hFpy1WRKZiCRu>%S=K%!9E\#pNyL
j?Hb<l CN=HqKWwwEMP@*pZNey<wFk+85>!V6y^Zkj1%klAS+=H\LH^\pVj!G?QbqI/P@a9#\ae^+$F9DHuuuB/
L+ZE?R 48%6mp6*:\c&CYy@\!V$q9c6/mW8dAQntNM!cSC8/J6pyt=RlI81bJI4@@y\LVZeDpFj%L8B^K5wJNdW
TGhiML G$y<G%J^1u4=>DiDd#?%eJSkGlQ!aeTQy?Gb%k#mI?QRITnyJiJaiA1$=>qjG&\Xt9QTWjCaVu:emBwL
Pjp&jA !BJ1?K4Y6+MJtt/II6W+H=&ZN!ZK4&*nm<>^JbN=J64IqG6a=IkiHFQZ>=VdCm:>c$qF=D!LtBJp4L4Z
5eM^&H KC>Bn\WP1NeEVA!&+tIbtFAmGbkTw$ei#MkIKSF*Zn&QWJNym*t&awP#?>!/#t4S6E8#E5#lWS4ELeip
!CSn?& T^JF&#w+^R1mi>@T!=lQ?q:Le5!TXGCXF5!dnGPZc9*S<BmG/=uSqCTt4^!LNVJPeq@j!m\tCem&N/E#
n1@nVL YKCSPI9GPqkJGpB^>WG4&<$p%6SPRJTpPqbaSNpT@RXJjjRCTa9ZG$6kA!jt$6bc4ckqE1pPh!:JbwdV
=SRnG@ pltDA\?u1F=M<8B4Y>M1ll+Vd+Mb5LeyCGGADjeTN%9a!:$*@+Zw>+JXaQy4i^4F<R<TPwuDT1MGQY8B
bCyY8G HeIh4#@6cnI/5NVTBSZmDy<J1GZXNhDD*%Vn=u#AaJa/V&Gn1el<P&eeijm&PAqwMt!W#TnYGWE65cA#
p45u>6 ibdBXKMy\EVFlj#Ce#?l/FcaTWQ^HTXbFE8EIWw?<44^J+>8SMu5lZ=^HCC&ME!M:LNRj%?V4PRBSmRE
u>E*Hd Bl^+<Hak*nYtQ1Pdbb4aZi8p#dl^Xm566/q!\e#BLAJ1pIjeD\KkChBZLj^IlQ4mi@#&hcP?!n9ui6Q%
>=Zl95 \9TDam*M4CE=ZQE/YQC5uyPSk%V#Zhd$CFX!%E:Y5IPb=NcFG:$5&BAQTjF6uAdd&*M1$&^AIijMTCc\
8TYTP\ ?EehY>A<SWc^N#l$#=>EBNF9R9yYl+b4ALE?=%61mZ<T:bS#^i^i+=c@JK>9Vp\::LSpMaY5yBXlCwqy
=RI!uW dFEK%tZBSNaAe@!?Ypwh45eiTbNK?FMmWF%VNG=\TKdFup?CLc=e*CqZu=l:Tca!pl=/jDKd\=4P:kC4
YSQ6G9 kqM?MlK1q\+eHdQTTjaBuVR!kT1yR?W&K#L@Bw\l/bPASPjMn?K?Yp6/H:m<<dkFpJCi/KZ#yIQR9C8t
!yH8C& 9p<MwS*/I6AIVjaNEYqI4<BG=/i6MbhK/knBj/yDGESYVWw5C9BH$%PuGtXESedyylQPcLnw#EanhTl>
>/*nAu #cwFk:YDTJVpI5K9qdF@X1mLF5aRajTDCi*$PBl#qSmPkdJCQZ%tYF1BWd4NMPwAjWqhm@^=WT/IhpRI
:84C&l >?*Ce^Wl1GkE8ldny?TBPWM$Ych>J?JGeY1@dueu$<6JJaML$AJi=JHi$/Cin>ei!MV!1EH^#V*%/ujI
aAI>t< =Gjchd6H/9WLjllpim>/w8#5&ZdGu1&DYI&4JuqCZqENb/6YBhDXq!BJClN%&%lLQ^*T/ehDBYu\t?eM
bq#ddA \LT#qynwSPcZJ!?C8YS1=qKPY%?qe8/W#*Xak$t<S6KG8F@VE/LL?Z8?R*F>4wXZ#HRVR<9q<4Wwt!i9
@F&*RZ !XKK?AN6^eANeje*tC#XnuaimpL%@mC/yEW%8/5#@>^6ByMu\$NK^?D<%l@LFGy=ET<%m6$6dZq?L9#E
YcEG>L >4ViHPCdJm%Y&hmEdmMQYVP<inGQQX$\bm:@5bed>W9C^dmwJu%:ay$XnQMhQAL^==^WJBk=LG6EVBS&
-A95\= 0009fa28de100110333 Page 382 of binaries1.zip
\&yWSS *Ql9&5Bpt#RKq\ali1a511t^IPjQ/N!Hinw#9YAuY$i+wyBCBd<pQ46bd6u%\k/6CCMEm+F#L&5HM:<J
K5#mLq VT6l#LXW:1mJT5+w#XXqtQElPALCJqTMPn+1M6Y6<!+nChD/:4T#&QbkK^nut@Hm:Q6C!8G?:!ccu\bE
Gcy9=y <LK<6d8I\=!:D\ueFe9*ch!uJSN$qq*%pbe%Kk5Wl5A*Q&&%GLX^SK&$+*/1j=XCIuX&ya=n9SM4:=m1
IDnXX1 K*6VaGIXJTJX?A+!IjC^\<NR+6Lwy>?YuFyh=\!u!kHN^Xce/@DLQp/VSViX@H*pqB@SacRqm/##=eTn
d&dE@? Kqa?<4T>:F<lm/N?<Zb!Y?\CTS8/GauQua<:VGKT6Mjjlji^K!C\</WjZL^$HXhSTDIXbAnH%HNB5Jc*
BbQj6: R6uEc:LLyn%8:yB!$RB6%cSeM@H4>/!JJ<::=<+E<DBcJa^a<19YREyYqGinbCpV&R6C^h>Ym:u4Ym=%
bHtIqD &Icnbup6lTnb11Zw#WTqi8XHYBdHVCt1KenQlqjFJyu1YI$tLG&N&*@GcFA8h/C1W^?VuitFkE4YM+h&
!aPY4L M9cP/9waK1*VLiu^1tlM:E4B4Ry%nBGanQ9l%VHd?@SR/\m1!^M<JVTYPp#C&pnF&5&46qIJ&KGV8kPt
41<H>d :^EcZ+eIW\!5jQ4\w\9h=I4DG\ycGnbhm9P8WJH!\QDJN46pnm#?SSH^1uI$nWP!C6db5DKl<GlFFnKX
*1w:1T 5DI%LGkDeZqi9jt+MCeWH!JBn9RndaC8&wkqlClikQXTkA!++iSn*WVPl\tGRZH+Q!yMFbnIGdJIlQ&Q
1E$mQ/ yTtaRn#qDK!S+NY#!Kpplt9MNwDl\pjbG@n^=E!>WC*@ZBLEYAMbPFHP*Cb&&CCM$d^Jp:uF\ZB+kC:I
=4BJQ1 F+e6B@Q*Gbt5@^mM?Q?+N9TdbEZYS!hK59+tYjE*c\GPB<1FjyP5?B5$=IF%%Y?TFZ?Djpm$?W&!+t@R
i#?W%V LA<5+u?V4Qm9/AeZ$4>JX9\Nt9$B<iI*!a4@mkb#QhS!n5ikH/nJa@%N58J9$A>JAJDHeP&lmn=Y!GP+
IcaE=l Bu/k>yTX@VFeA:M<ID?\Q+b4D\5I:I<lG>5Dlc?5:G#@F9w^bIM<hMLb&j<6>GQI^5u!\CZK@lm!5V$R
PwpkEk PM9K@5<qiK!QmGH<n/1:Q+pD9+6lbQ%9BZ%^@>Y6DR#=Y\+nK#j*j<?6nSZM>i8<@L<b>hWQPQ?@P8wL
=yWhZ9 <&>SZ??6BjMSX1aY^l$G^6XF*pBI8cPlbCXNlj1wl9cq&<^j*>/69*y^KeQ=j>n:b=dP^cP8@Qt#w#Nk
1>@iX9 EYLqkGeZW+mcYtJH=Qu<DESh?*eXV>59pnn@TMiciHjTek<wDV1?ybT:B:Cd4duiA%/mjdtYju6uNjy*
SPLbWk **\dNH?4\?!#T&j@w=RV4jK/Ti<iMKZ/=X#h:1u?yWQdQTC98H&:dIYyjY@6>V%AT5XuXLNJ%&i&/>6h
?SBn:B jME>IL*Y+Z@\KQd#q!<t9S9u:jkXTp/&>6y<N9J*uQi9dkXDW4RMp:+89:%%9\i5w:?@u*#@q:C\Q<Kk
J&H=hh ACF*9K@iu/Nb*\Pwtc1<di/u@9=jai+B?aK*SQiAV<8kTwGXL@9>>\BMG*Smi#ce/MkP%ZI^!\&S>@jV
LLEdn@ tV4TDVX=dIlapldbc8?:m/FRwp98iHhVIRwu<t\TJGZp+6&tH%69#Fc1lMBPFEX/\1*Jj5tbbLqEq<Q/
uu4WRW 1q%WImTWtpKIkdC>Y8@RaTACBD=cDSenu?8<+*%H1Wq:/P*!$1hC&HTY5<W5<T1EK!=ZDkVWiL&8iy%@
HKK/hX %@:F?=t@/\Dk%$C>9*Q*?ajt\!GMZ4$9K4>NXB#>tiI*bY=^N=$dnQDpHyCAPe9+Zn&VQp&/S?!N8=?d
JAX>mT PmldF+=e%HJN@+Qk@Y\KW^!^I+SqcIembS?LNSidJlh^X?m$yHE!plAllJWiEX\YN%KyZ*Q16NbnZ:Z6
c#HGW6 >Fda**$:?HTpYwwlkc#alZ/9&k%*?#Qp8@AhX<:P1Rk&a%$pyXt+CEQQpI#wTklhVaKK%4Fj\nAH*WS6
8pQ*t+ dZ5?RcT@HM4/$>k:LiX&@yQ>Q$Y:Ij65NH4eA%kc&5?e>yG&@<l%t96dZ*%>hlZ8AZ!CS+elL>@d&X>8
=*CGti *ANCPiD4bpD9m5MKG6P*J%hhcDFk+VMtmp*ny1<<:EP6?tTGm!way^VEa1mC>KeMyKQ=l1wYjT^Wd/L^
SbQkT/ 1GKKGXZ*yuBJjR\naP9lk#&IDq??cdqa<9Y=u+?Li1E8#5T8Hk5yJTiu^\k8nKjFIkR^9Hb:^mcS5&jI
:*SNML %XDPTCBy?@a>ua&Ib:tC=^8e@XD9\DbByYkQLR@Gnica@VIb!awDjyRwE^E%&Qd/C>hPba9GBC#1GdT?
Va5Iu= 5?9+\1i+Iqw>:#@tAPVWmki>QJZkJ!+%Fy>i=EJMQ$6^qbb4Lu#ew%wkQP/JMiDpMm>e@KSFn%bc/!I@
PdTA>G NJJ9Aeh:4G:X&C>>YIZQ!YG#AQ9m??Fuu^HG!y8Mqk/yk4%9>JhB<^ZbtuShqMEnJj:iR!tNnEJH%pqW
+K#yYB CcZ>SANi9i:C5D&iHPSbqi1NeMeh!a=:V=PW6wq&VIFQJ=M@>$mh\k/=q*>\Bd#:cV?N=B$<J:lu>PEi
SB9A&Q EIiuj!WZ8umZWHMP%HIhK&T<db%V$ZFM=<I5:YhA#yh4Xe1Mj>=<Q@FYX&PF4*XnlwqWZW$kudFbTYq=
#@!t5G Jtn=tE9*%j:mII/VFYjq*9!GcC$ykPTyb^i!$4B#bQR&kT4Ee&9c!R#/MbG+YWLiPGdY\+9Qn>jqC%/D
ZcdFp& mMj\*6LwTAcWK5!G\?1Wh^p>Bq9YPZ<4@#D<:a@CcA<>d9IpA+Aj5Ab>QanwpPR+wKJ5P:Gj+8Z$e4D8
KIC@mC SyRl9YLQ!&>XA%?m+hPu6yFN$m/%e/yLiREN>Vul*^4lAFKiXSRF?&16jt8j%p*1#HaIjF4<=6e4buqZ
!ab5hL 9>8cb:I!cNXQ1mm%8uZ+a&AlY^5I\T5GlH$Ti&%Ct8bK5IZwVt/^KiNNcbJpdPAPLb@<RQ#4!yL&8ic<
$@ZMC* B*^wiKd4CB+J<w<jELNiXQAX+Hw^4jB6:<*+QRC!jVF>i@*i?S+\!6$G8Rh+F/:eA<:q:iWE9^S@E:!b
VYin*A @nX4:Zmu?:T4HQu<KPR5iH<<<@Q>uiZwd8HQT+G99&bTb$@L8%8F=u9Ah5du@?LZAPWjCp1hHY9FKN6c
tQjcbq LVb?=L+PNlRS1ay#dJkcB1JkL<5MI1B#QYq$QN*aVB$tE4?cTuJRC?tiCH?^*KE?y/T6T#Rd9HXEIM\Z
ZmqeXw 5*5nnaTbS/8$/Au1@y^:X*MQPB6qZuq@49j$?mtdS@Vui<CETWQ$pD9BT8Y*GAbRnq@aC4ulQ4\*lYV8
HdPRAD GmBAc?aN\j%W=1lJ@CnP?5c$i\DN&p@yZ5&pbuIdchDd>Te:u4LCeh&\4$1Kpd\@VLj:EC9QT>jWiD!j
m1*Lpb uk/bSZ&tmNtPawca+Zun@8/\61$*5L1tybPN4+:cqEZt&T8+1%TDM>\y\TnXIyIAjc#ZRPuZGq?DJb?4
uhma5/ 4hHX5HP4S>Jau1!>@tE9:1&VE?IGw1uL=:1lF%6+VuR#Hw$9bk6pDe%^WhZ#hV1!i9&Km$mq*mM4Wunw
yT=h:A IAZ9DBe?wJhT\4nyGcDud*QQqbD=Pie5Fe!16XR?DjTu^hXi8h+HFCIKu=!Li<AQe>p9@+9Z??tn^*:%
>?An>S j>j4@e^@8\pw^S1c*iaWeeIq1+TE4+pDjj=!>\F?WatSP1iiN\8ZIw*8Y^$!Z8XmL4cT1W:c\Lq&Eu8c
qWnb?c tl&4/%#Z=Fi&H4/8tmmPEt:t1wphGIu<QPGq=&HKm:RLT&XNLLiLXXMyuX+TNjPECWWy@cW*IhN4@lY8
DlFRbG &4<8\K@pPcYDlI!c8AM\iiY\q?Yk:YDjXa*Y<X\=uATK\%%SNV$SHF@a5%6N^Q*b9P@R+jy#nwk*JMFV
Nb/=jB t#K$5cLXJhXGM%Vbquwp6KW8\\ykm/P!>XZj<Gh?E9D$EySh/dkXy#$nkuZt>:MHIcPiaLK/1Xc^VFZW
K/l11/ W*=4&DRKRhR+cLlYW<9?6dPMM?a4RhY:T*>Y*M&BwVyel9^ZL:ca#+EN<^h%aIaEHNcDt%#HJp$K@yhX
5/RJc% Rj6H6Q/&q$R!cWCYRW$cTZX%QTEFSNwBpJB<*#5Y?S?96?^VQ14@=iY:#Qb:qu6A<EYub$Q=c:+cbN9D
BYM?h! yCbEy$41jpwm@<CwMD==6mEB5=lSV+Xhmpb4KiPp\!QdnQM%PwDp!=\#HAN4wiDGd>lcYt$>4Cn9cN#b
w/w@Nd eIm68NuXhG:IQSEw96:Q:S%@=Z1THcuF&#ce/DibqE5iRtup9Xm^VMd/^i1m$*ydR&8PwA$Qc\SGR\ak
&e441R RcFyVHEQwEem<t8+\<@\69miyXqP+F*Q<ATKJYa5NcluQ$AC6&dq!KCAZVWI?1G>hi#L:9QNZ#@8XwLp
SkZD1# ^WZlQTDZ=?eH+*1QERHVSlLbFb8njLJQeXIcWdYeyBSPIVm*td^4DRu<JcNFPq?EHL48i1un<8M=%S5d
ISTHNe T8Cn8bSjKQ\<T4^^GKK@B#B?pVG%jJdi%Ka+pSR6RKKwm&6WjnN<C5ywYa%w$=bAMG$JVdwMCu&ZyB:b
yGREX? /$H9bP11KFqJ\metB5LX>+kbWm</@cTJG<$5!+tQ=ah@c*!F5RnMTH9>uhlJ@+j$$55bk&4kQBl:L!k1
%MR5hK #GKwpV%1e@N6E+pn@G&JI&/@RQ&Y6!K!niE:RmWWF$pB&G$*=R<*cm^+YT9B<HBS#\*PD11qGT@GZ5EQ
F@%uEI pNSbbL><6*Xy?N&dZIm?i#jbCnX8&Pb?j4>&u^A>n\GlJBY>SSw&n/+e&CQin6bm$+tpJP>:LBS&q*VY
1l=cwa M$+la+p#Jh/d4!CQYl\\H@ul*LB@GnNPbRJ<D?B+96l4R1==5K+^y/1Ftbt&t481S$ELAAZA@!Zb%MS<
iSkXC\ @NYweR/GhC@#h1alD89\kHlW=>cqVn=liQZ:G1HQTS**kPTqTJ/abMZ8\wK*q=bdnjH+ESC:QSFIhX%R
C9+G85 Y5DV#*uyM!<y$5PCdQI6D/M&yYG5VhYePy=MtyDK<c#Bb^1e#SlQJk@E9J^LM>dAEp9\H/wbHCLd9h6%
piCR\6 LZ&mj@q1@H=mj$N6I1@liuwJSQMe^Iln&kd^?$y1IetcGJcI!!hFbB6GXb?>#CW^uVtd%^T?JLkmLnNC
u&Wh&h *NW1C6!PA%h688E5ZJRqeNnAqh+DY4F8a9c+AZ<<k6?e@HH*XG<&ad4y66pIKWbwuSKjRpFGiqi^MbtM
<p&$D: 4dV5SS5\w1\6h!&MG/==dGmSq!^n8e%ItPh<dd?9&*SdQh>^%Xu?I/lTDFLT>#pe=88#amj9=#w^SApu
5BH4n+ :l\$tX/#Y@Spk@b:NWnEbWNX#\9#?>idmY:WC9&/Li9Suhcblhi%WR#*h/XMS8yjdNd*5m1X@WmC14ZW
6:^w*W wmIA<KIBeHjS9</LuMjdP/%D\X*ei<BBL8h8Jb9Q5G:lLXu:dcLbLj8&@R@48q?4qJj*kJ4IZ#j!j5%#
\E?EXj eqV&&VSe^PDJ5hYbF>>!?=p9=6Qc6!1t:?L$:+da9NQQPY@1q*!tjyF>Wh^?Y8?Q%NeQC6hmQn>yS1?6
WVG8Gm S:/e#X9iA!R4:\GtBP&QQ@TZk6a@5q@h*q?E*\P8qN:?@VFb<Y?/6<&d$nHK6VBpRuw9Z*/Jyd:V+1@K
RDS?NY XVuQLJ14^J&j6Yh<q$q4cI&%%<Z!QF>9QVLQT&VB\NyH$Kylp9Jh8Fau5iEdZyjc%bKkInXq*9hBnbYE
AalZe9 ly56^/tF:&^Mt86aS?$bXwL1\n9/KbBy%Dij*B=cwR9ll&1jbL/DuQuGq>m5BFE?J?>1FMVwyw>1V&8X
u/k$qc J*@>8tmyu*mKMjEkh%LwW6\T&VTYBiHIk>YRjL/=8DLc=*+1h9qH?JFMpT&1XlyquLS#9ah:1>!#4wE9
-AF6p% 0006d4dd95f00110333 Page 383 of binaries1.zip
bA9?MJ 8\1>\$FPu9H%9BXT@#k/V>/QCJkFbd*R14NZF!K+B+k=Tyi!?*!PPZQ<^#EiqqQRdtbEQ?^6neX%G5bB
?EI5$D J%KqLi\^<=pN?6M5q9umt%8ub*ud5JZS*y!F5W6W6tptS=#$kJFuNFcZEKIkMaK>=S8L#Hi%8/iW%4&M
jbI/%c ypycK9XjjZ9=?X@i*kPM=>1QIY%iQy>HX6mXP>6iQ+hma5#tq/QVCZ+i6@uI$*=Vy@F4#edZj1Z=N94Z
jFhS#1 ?YZEE:!Iad=NN69+hWEMm<Zepk@@P8qyVZ8@u1+tnZ>^+P\ZR<#5H5Tb*$?uP<:iA:b!?8@m6u/SaGVF
ZnnFmu %iiHSjW9Tun+HNS!Q6P@$&L\&Z&8@=Nl6Q<ZTbInZq^LyN\N5@$QkKRaL%ZVNZ6HW&mFk^E@c+F\mZ\K
WR1V6G Zt@nyc\BDT@8kQ=W?mZD\9=byC>$h8nel9GY\kj*!q4e+@$<d6Y%Jq^\4:iXGtjqluVjtA&uT%CR9NHV
?l:IG@ \w*Lhhc@GK5QNY4>??bkJ*>Sime<!9TiLGAA5THSX?LNMi5c8!pALRIVTinT<6e*BP>u@tpRyK*j1B5V
+tWl1Y YL<qMZIpt@15q@XESH9e/?ZjD=^S\=e<hc%^^4K+W\N%jBPJV=JFb5&J69MH1#:ZK9iA!jddV%XL=:i:
+ju9L> Kdeli%\9PJSeqW6G+DmGWFbm/S9$XPMyJKepP=?IcT=M\K^LDj<^Nh@Q96@8c+*4!h<!FeWybe*ClSBq
J#XkY< 8Np5%kRWG&Z:tScTkNdd/FQ?9Jah@&NhP!K\=FQ#^^wY=t<VIQyeF1i?b1P/tCY<!!X5$1>bNhhjEEly
LeCy89 #/DBdedYpwaySyddL=^X1q^Y>puX%iy1N<ciejjR<yJbV?mJt=Nw&FCb/qTiT\uGS6n\qm&Q84AySIR<
QD?5aC Jy^8V4/in@/M9il$KGJwV6GSSYekV#wBe!\cShtNZi9C:Nu4d:&Wb%99Pyu=D5hu$/HKanna4Hc<<\j#
wk#=E# >y:jM=RXtC*QFpiNKaJ!$8JT#/FjaAN^TEDhhBnMm<5Wyiknj9pZKLGDBAc&R*XiX9p?=t>1!4*c#M&t
SeH#Nl pKpNeiJcGX>R:B#kV@wm%hQQj#H$?#KWnP:XtGNYDI%*enF!>!*!JlE/H8DW:<b=L>dEpi!YuPLajjuc
$$aTA/ 4D:yI!GLI:=^@=jy1@&wi\DK4n//mhPRmaF5/QJAK<aTW6d8?@9=bJH5^W+$IiI^*K@Zk\I=<#PF*e5P
6#Vm^J BbE\S!^aH9J>V^59Kwl:u=L5p8e/T!mZlc#hql#4jiHV$&eY+b9N*M*EJwmK4ZG!D<dXp:iTA?y<NQ?1
@^mFq* ZyqmHQ!b!N1/t%CIJktF6ScX#*c&lA:?niYZdl84H#LTG8t+!hBI#jbYaRt!A4@\BIWR9Kc#\/Dl*EG&
=S&ipB GDuypnC5>#mYKBR1Q5G59#41/SJ>NFZFZL%/T4Zmj6n=>Gn*MJ\/&Tb*6hSyt$JBq4^P44GIT1>$5hu6
CM5?l@ PQ4D&hldD&huq:MYKdiTBIe+cA/+KX@wNl?@:lw*1n9FA=p/!5KIip%B+SCe9H6e9cJ+:Je!6PS$:dPL
yw5Wd* ^S4NmuZtu8wIM9$p:Tn+lF?eeFE4@%%LS\*>SDYV6L<M%18Nd$a@jZ:h\Vw^>6@cd?6@J:%%64*=NeuA
aFQDJc C%da61j=4Ibe@41u9#@<!$iG<6cu6D>%pRY4FyD8Eu<6Wd99nlbi&^N??lG^l?X4cG%yd6#PyFTHuEW+
T55hpZ >d/NjSqDEGy=l*+QRHl:kjl?>e8Jb99@<N@*p+j/Yd@Y!+n*AQ@Sc#mFE@99DF@?B#/w#4Jeua>+aTj^
StiP%! +lyD>l:khR@wd4!bjZ9^QP*8^#$k^Q=HKd+LPq@/1iHl\Jc*:@RN$S$c4FW/A+8GAu5cCk<N#VSmHPJ/
?uVY#A c>^#5N5>kMd<jmyl6&Y!QSNDiG@5dEuV9DGyjC&bR!KekHI^e%%wn9Wud*R1@S@DiYF@D*lq$&b$9he@
pX%^4d e6Y8>wFDn9HhFE4^m?i8>c!qhbND8DK8yNc!ZNQ%6lcj*&mlhbaPXQYeX^:^W:yqWulnLji<I#eZ^D\M
C5$pXb tN5aa<acTJ=A55k%$<RkqJ!Mq1=n@/=d+1GTn/TnI:Z6S:qwpe6KRHFh?b!+S*4TAeIEa/c9u5V9QyeE
?!p>SI WV6!uVT$B&6Z#lFP=1WBT6E1Jc5m5\%:QR/4nbj6tmJ4QTyu$BH1KBYwLn:=AqD\T@DW1hMmcZd:Q=wp
HJb>Il nQ1dM?MkC51#C!pmqSnED9T9X#:llNtRQt#a&m*&GNH#yP4A@<\hCB#CRZ^yG4X6?p1ND\1BD#+<MIb<
^ydQ+p NFj*KaXGb$AXXHQ1bcpmX+mnCkwF:Y6%^NZQ*#D4IY?kp%ANehIIa=$G18i/!a6hH%>b?^5KtMV9paQ:
6a1qJ% ei65!acF<><yhBNXjM**IQ#?JM1Dd+RLj!$1XB%M:+C1+:\w/ZqcCeLFLYSTljRit5&u4X?Q6q1XdW4Y
P<BSCM c!F@4?\h%I^lW56c6=/I8/ycF4!jQ9/Viwy<</uIT555lH<8HqMuYQR!n#ki%\\t**TyduiXZ1YKT@QH
F/jF1\ 1\y44c5w@4+/QIuk6i#GXnHp&n=e:XTqllHJp5N+Y/GC/CH#Bl>=W%#^%cqnyb@IBFHi+8?eYK:u$&uK
=SM*%W ESLALAq^!b?/e^qiaSA/c5ENmBFR&A+&jX9RtK*9daAy%#*TpKI\EcLGmwA@<L5m%luG85\ZRR>!JC*^
J8Q>QZ CNKFX+L5jYQy/#*Mm=T\tWcYDeVMV+5NYbkW59L4>%C*RjjPL1hRtbl+pTR8dui^d*bS\SXHYj$1?m%1
F#e6pk ueKV!wt99&/J1j?lDZNWF/*5*yuZe<#41*1WHeYbpKKtqBhHQe8Vkm&&K?<*DPF^1!>yY%/tQN=F%DbN
KM>Y+y h148y^Qh%ymMNJ5q9?VKbh&atRdP:a@t\&nLiMB5THFDVKK6$QBZb4pb6eNYZQaD!N:4eGBJ5bhb8^MI
Lc%$+5 m!MLa5B94!Lq9qBJ\YZ/wPIahC/%@d*!tHAP@+mSRK&<b!RW=u6K8KPhiWt6e/E\p6b/k1=HQj#uyEmR
dyFke< !PnPe/Nkh5EY^qM+>YjF<>%a$/:M:H1ccSYRW*8TpyIc*@HiDuNcm4nE:\Jh*@kqeZwyt</6P^tpLHGe
4SKkj4 W@Yu$#SS\>=R$@hARt/Zi?#amGI+\/\camF<NDB$L>+!bGm&i$JSP:q>FXV//myRk!+9\@lN^N&c?Zd\
JZt11! T8*Y<8APm<yMp<Gi5c%F%4KkFD%4bN!DHKdl1#%j?nmY:!Eqdlm:#$yQ#t:L1#+Q!VT?=HRM#I%:R5SG
&=6IkJ dYcC$QX4cmY<#LtNyj:nGiBQ^A4$6y&yj$a9pu+5LewyFAhjE>/Q>REB#FW!>+:upy**JbwQM@86<Rml
<=Q&y8 /DjCIZIbi+eJMXi5E/pJ8pcY?u\lCm!PRcb5mpqNPe4cMticE4be!X#HYbZ%/>i8A>$@Apb</WWM><lS
j*\9#J 8Nt//Xy61qipCMG$Xtia&XS%CQ:j<Bt56d1YRiyBS#yTFF/GCZ/SR4\TA?FB#k#pXliG<p&^e/=dLp</
PehuSu G8t?5jSI?t9e<4=KlbybJY>1Tn4K?XK<4:GtG@W:>9t5KSA#^^L>>YjKQWC6jb&c:M6ju+y@QdmpYSP?
DdhbPQ /$9dj1%m:<Twb<&d>>Ikn!*ATyuD@CW!RW5>^*:\Fe>h&Vhti@TlQZC@QjG=cGm?Wy6:*CSqw:Vk$iI%
LV:I#\ :J5Ql1QDQ>L!@M1XYRqq/GZLXJFC$m=i4mME+JBZ=YQwXt6#u5QI6JhLaJRT>nV+%$p+a$HKiqRuJDWA
T^I/jA A4@8WL*>1aTcPhyP8AbWuI:+bXFamXp9VbjWZPtH8#*6@Tbd%<Q5mSnRTYq1yTZJk4HG91CYe\*SeB#^
4dhL*= >%EY/Q#+/MmnJ$#P!qdtBM=^T5^Z$@SkN^A9&t#H64%VB\c%nqFEtWT#wSkPTble\u9u*Fc>^^CW4>?w
?JQWmE >#VRNn&QXFwMC=e&FL&iy+yJDAR#BMR1wn$b!aaSw^%&QwpIFtR6d#%$JK5:MnLSeQem\a$&nbuB?eq/
Tj:8Sp 41i:EnBN$=+&bTT1NI^S6P!pbke48iB+bSFRM8<6?6K&+=b9L>FpS9k=ZbdpB#^9<yp5ZGL8N@EYZm?d
RR#X?V u@%bIj4%yHQ<<<>/$a9#mtKjQA65*h&DPFp>49R>SWI8QHFWW%jdtLQn1uL=nnZ>4e#&W864^yGYZI46
5jk4$T 8c*!%dawQQa$&NKZpRcWc1ulFa9$M=TbcLV=ni+dTRl1&?wYji86ZdmRR5@DiZKMdZ5YRDpw5!aZlb5:
MI1de4 YtPJT9KIIwwmpwDVEdX^CiCEN89ZGcA*K%dFcD&&%lM9%pZLBSFG?e\VP+Kd45HnSBbJI&ehG8Yn<^Kc
eyiTB\ jQKyLIYqT>b^?EWl*AkJJ<mctepkYB4XpTJB%G4w&>AZ#Lb:kIjJ6iC/CHKFV:QQyjahtSQn*$S$Y&Q%
JkLJXG y1uYec8=d$?YyhnjVbFL6!bqEKqL:9@pi%9/@J*#@eVP*Ein&i%pdWt:*LbtGbNMWZ<t9RTCHAuWW<<I
4j:6wC TuI*RYS?H4j8Z*e&XkXZRDwCu5+Y>5B1L#XAR:mV+NWtwGnl4p^>#=:FV>8huIE/6=JWRTVm8YS@uN8Y
AE$uM# 6H@y1tB1$8e9Q/b+cT5a!#dMXE=wQu$Q$*WLD$^ij>w8M6WGJH5@pkAjX#:HyN!9Ma/KHEwe5:!JwThT
\?$\4c 6JV$BY/RPwNTpwA$@KtIymwae:ML::*FnWCV$i5Vi4p>8GGQ?1W>kTeMVyBTc^w/R9dXaTKYW8>QSB<@
u<QmhE j/eVu?>m^qZ*ESj\VyZ&#QdN#M!6QLB@cuXda1R+88$6bGi:4wmV+l=iL!tq$FG^4>XakCB=HILZ6=aX
4RGF^i XbGp:CVwZmSDI>B#D*k@ZpH@y!ZG@iT9menEjy\\8Vl@^%akwbQTA>=bb!k:HnteF=Iu&D$4DNJY1&ai
Rh#D>h @1T6P5jZ@G!8HI8mtL+ZYE$TSS%G&&e1XAWj#:F5FStuN&J:TJtt1=k#\^6i>M%\mQ?nDXIaAXH>Pj6F
:/AHwA pWAN+&FiEuKW4k:?Nypi*a=&A5^8KV8N^j+=GbH?S$tec%nLSV*JIhF%#pn6WdJaEc:mbFTM$FqJ<k4T
$qp>$/ P>Lb&RpKq5<MKT!hG8ymKQAJcD=q#in5InNkY*t1%qD^RZWdnNh*b+MZ*6YB4\SZ&1@L:\FQ8QH?6qIT
qnF&dP XJ8%8&mHcBN^G\X4@41qAZh$NRP$cmS1?@5VdAjTkb^%=<<4L$Q1$%?@DlN4hbatdZRmNe?pTT@k#yDG
!/KNS@ yVDnp@!%kync@@ZREm/V6FbaPC9ww4tWHb/iy8uB<nuAhPNLybJ@icY4YXXh?6:\XE9T>$@muJmXbQT>
+>KmNn BMPH<mE4$\WAY=YSeX+SWEcmy1t+PSCklB^Q?N#k8VIuX9hZBZnt!&M&Vd4tKbmatdBunadmWJQC9LE9
?j\c%P hquQeZB8T%d:b%1:h<IMy@*e&N/ZN1%DFV?Gy%^!#jySbL/9dX\c9SabAi5J:T=+8lZI5#tnclRu?m=L
d:KD\X uW\^MZ:^DHeuj=/:QYnd>I/d4MX^pMmR<P=$AuGLqB$bN$d?I^h+:=6&#A#HZQkF14F!*k\+?XPdWD8h
Je/n6P 8IS>a>N*^%#q8YFyIutc/4QXjwhNLnY$#wWdpVcP++t%Eb6S\6yCJBI</jp\epiq6ik@Ka%@QCVXeH?%
4VN%Xc %Xch9NA9&+Xqd@JRy&=KhbJWLK%P>IiY1>LNY<ZNF%B9Q4NZt:@=&LnWa>XI#^BdNqtJ<\+4\$!6PQ@X
L!X+q# e%\mE@<4a*6Ll4&BIL#5#b>\u$wGBK=i5Mb>$Ih<pk*al@&<JKWaGlkWWpmLhcKJE#8TP/X8yVk=d:ey
dWeA8T +lG?#aX#LRM=1KV\iyKp^>/a4mlGKNScld5aTlcw*8S:VyXZ+Yjpj!DqDITdBGYV^S9cZ+aatC+PAkPm
-ASZZ* 00060f2a4a600110333 Page 384 of binaries1.zip
<ZnII+ 8Pw>MM9n!^cij:9hT6m=NWa??whb=5jcH\@l*1XF8lw@ela$*#yC=q=J???S$>ZCYR$T?nGR!uC5SCkc
Q#e/tD ju=Zbw*&mnJn&JK!j%c5P:?<Nn85VZK!XGwd&@Eqa!<!XiJ^\QdHe^:y5&=L*N:aWIkh8eYYPc9p=4Y!
BK6eA^ *CA$V5q>P9uH@e#l9Myi!SmnkdkTmwZGne:YuZlyj>h:Tj669XZCd/P5et:n^6lLFMC=IMAqeQmF+Gic
l6\E&R 6D5<?$AE?QqqL:RC/?i&4S+=H/c\F4QVEtawVq$&V1djWl@ccM4+qQ4QjS6><WFmPnbb1#WyTp*KMtXh
S$/FY* 9+#%J^pXyFL><\en#E<ip?R%q#db<aF9*DQS!GqWK\9\9GGG<a/qRj=%uWy!&@dm/%K&/=iTjqtlnuaW
/Ba+Vu JjqhQy/?p\E<cw*qKEPetYa!IWkKW4dN5bHB:N/\cq<&M6>&D%^>d<lHpD\W5JWZF48l^Z@TJ<Q$ya&P
GIVVB8 Z%Sy<Ahh9VhhDP4#Jq/964QG+T@$j*+S@QXE6L!yQ::$MVjZR8@nP\c*M#q\J?QtWFp5PZpntKJELW$N
DVHiF* mdFp+j*YYHPJ>b&&>8nLmGHmM!HeGc5u=6E<!kaq5FGD?mG&NSJFCw#%mhNhy:qbSS=ZpZd$\?5K*&N@
#X?DGI dB4i4Hqqc>GLbuJkaVQ*9+AnjwXF^/M5Mnm*uF1MA$V!I$hK?/y6MAW6YA8MIcTF^FQ+i/mLFdKiT6tJ
cKdkZp \SmKXN8GmZ1p@>CF#Z51LJN1P#?=Ch6Q$dY<D^w!#ZITIV9N^*<8J==Z/XX?m9dqY:JC:l$FT@k@QSd>
NSiqJk /TiQT?*m\=6Jt?VJ=YGGlqhCYH9Mcy1JT$qm#@PkdP@<GGZbA%SuD!mV+T!6:P:KE8w+*KJ4KM*CPhVX
*pm1n^ *kWtT1HbhBj19Lk&Hmp^>wDpGD6ni^>/QGeINXEtXKXd!jBV18e<Sa^^LcHAG=9Lpn^%d6++QWtpjENT
*>D*%K My66&\#4E?%#Q:e9Xj\nN%CBKd%Xn&5a:DekiS//uPnhVIiHQX:<+/1njB8D9d\*@m/AEYEKhnq&y=j?
G!#mm5 b%j?LM$>aHS=6^9:#VcE@hy@KB6uWyken^Hj9y/dCQFN/W>!=!E@:Njd+$1jdDBJA*HCtt^y\Gjjp/*m
H@5<nd Lh=n!N%NjHtB<CZh=L1y1TacV$K@9CcJbp<&>C:%W6MZ$Lj?+WCe%6qnY:L:nhaR6\djt81ppP4Gnyi+
uXEC&n @VJ<NYV@bPJNtV4>wiZt>\N?!Dc8$6BM6kjh%yTE&5cLAp?:Ydl?>QP@@Nb^Q:@**Q5eL#@demBh4WdB
#T?bqa $TH?A>?RHmTcmdmdyJD5e/H$SRZnJ4@Vl6=p=6=c5knPKKwMIjIG*SNmiQueECc169+JnE8W#j1c>HX!
4t6ANS jQhiwdRtc1ZbMLm6ym@pGF?qbtmnJ/pq5J:R%bKw@GIN9C6hD%6=I\9G\j6YnZMydaM#+jecl8V>tD:H
<ZGnRM bJLW1bKJqW89*ZSLN%VCMNl%/HP8FZXRtA\d>MWGaTlT6V*Quk!HtyFpFc\qB>/wJyq%EM:aW1W+lhF*
BjKTde 4RllmWMNSPC1Td/daL#dc48MJ>4hnubLw+^Y#yjEP=jpISG$FPj<1>K!/NudLdL>&pTD5iK=DG?qQG>V
b@DZwh aMqa\W\JYWwpp9PJ9#b/*jL!5M!H88m?WZ9Gk=!Y%>wcYy>&Kh:nPDqcquRc<%q?Ae/4ubQZBp$Ldi\E
:?w*yh A>:E:/I%1XCE:TpP:Q?EdPliG\bui=RIM!WQVWlP>n^jV6KR*9TX/FIF5i>IXwdmc#<9*jaG!1jYJMY4
\+m@P\ <ppW/55PqGV^Fb16F5=<K<TiF:!j&F9T?:CN>qPIweW?q!+Md9bFBE</M//d8BdV:R?ZIu/<><4u6Q+c
mqGi$W 1>NeK==1$hLFCw1>&NE%Q6^^4?/WN6wEC4eD+>\6m!tE1StFimPVDJ>1YtR*?R?*E%=&^8u5C!tW\+b@
Wn%It@ 11F**BR4^by5XuQ>Hn#kJVDjkKC4MtKw\E?jkF8CT\LTwiDVkCS>N%t6Q/Jd6tFbu*whF6uq@wbhkl::
P^ny@y mL9w6wLc<eb#NiQQ6X$&EV?8Lk@1YI!1G64nLbMybGc\Pkuwn9hcCF<iuBJhpk9iV?:hCe>Z6Hb9ZZ^w
YkQYYD 1+>i51B<4W!CaPmIC*AZwwywJ*^yBH1?>:I>6+!JPXCPe*bm\Fkbl9RX9^jmD@!*+^kIH?VuyEiKVC:\
E+FP$9 lQZ<QtN>wKSDhSLenA6G**aG\lV/IZRn^bF1mnmH&Y=uTPcBD8EaiX@%aKS9S$*1#ZGLymlybj941YK\
Ae&m@> %F9tWW4kdp5<?ctV<np?ekFD:S+R:hy@@d/jlFQ\hGJceIQlHuCJI5D&H&LewhWR&mhQ!6R*Ebbyp9qC
LndDb8 Z&%+A#dmqn&a:+1a/mw%bChu<&1V%wGTaetCu<BP&dHFt#<hGi@p$RJ8JK8\94XEVq*Q=H+cJZkT>$\>
MGaV=S 8$m/6kyD?np@b\YLnphEAt&C!1J1&Z96DFw1AdZCE8%D&:/*K5WX>JD4kcbMw6jqWn%M+Sn#VMl&TmmT
Mnma4E qT^IQWP6Lcn#%V&nS:ZQ!y#HBRwm#<4MBC6$XGGjqe44wib/j^Y<u?Ll>F#ZHHXtHM8K>wPX8N#h$e^u
X5iSI$ XY\WBH*/eNq@c/^=5XW?XpD>ew*\nhN/!Nw4yEPj?KiX:R&1<=+nVtK\PqdKMtTIeQ5JSWc!9t<K9*NE
=a$itH a1FLd4ZLY4dQ4PP^48n8TjG9GSm@Z5V$4?q>5ZmbiqTDZj@t1mi1Q$$L^::MTuGkX\nDqSiV&$88%+\>
mQQiD1 C&hDK:Nyy?JtwAjJXqbN&:W65ekAu%F:68IIRB:VQjhl@d*&*B6pTp/iWP5\R>GwTuPSQ5qd<b<K5=a*
1nu&#K LG+bLWE#DQM<\juA$E:W6<N??u:c5b6*nBe8ui>Xt?<BySY=>\CylF>V18dHW8h:\E6hmd5E1n<1IN<w
9m:*8/ j:&4cEt=yS1@B:B9Z?iQ*?1/94mYi*>uNZ1y@j//bW@\Iw*#b6b9Qj#$1ILM>1ZT^k8R+G:C*RVF*Yj5
uu1+bd L!6:!qyTZc>@lqweWml@Gl5/\h&MZ5pAqGY*95Iy?IpWjK+uuK^?y6@d1SSQW%Gwyqd=#eim<nu9GbHd
K#>?H! @99:/YVQq<F*>M+qXtTeDiu1Kl:5HuuJP?&Nc?SGZ*K*!u&p4HD*:/:p=lL9:IFwSiY#memuXm>:$=Il
/ad4<T L%6VtaZhb%1Ch1Zuh/mNWD@XF#RHe:^Z8nCBiJA*y>LSBhG@6BV#4C:T5yW9BH$5@qPHbi+T#H>%?JSY
XdAMm5 :LI5ib6S?ic/JuTFj/cCK<q5b@Na4VPdPS@+Qy<bRT*/nCHARGEl:StG@AaKR?HH=4c1>PN>S+Tt=pkl
DIBHT: n&e=&H%#nu9MM%P6CqaNh<>ajG=y:\E:Z*+SZ*jdX8VZ%jFE^nLQ5pb*&NIcJ$H8&ammE6N:Z?Zc96Wd
@49!SR B@R?Eb<6\#&1w@W?jw+n!$Q*/!:/$qeA94mPRQA!ywkWHR%=Q+:A/:ppaFV8F:wTAw&*wRk+tAnY6w%M
E9B:*? I1F:5$6NVB8n#<$c:MAY4*1CtJtJWwtt%n9^=YV5ja5N>jRFWpH&A6cK&5P9PKK<pp<18e*a8n6XG\9\
>BQt^9 G&iLli<B!KjeWq>9hhiiw8VyyY1^$TV55#m8e:&/dq!/Zjjm>!b6&MBNGX8/Ab&P=8mLu\cD/ZYk1IGP
Q1K?Zd KN9wnh$9DW4%/#^jC6:QaL^+i#NMK^aDuhHMM^XX+tM*i<WcBLe*Y$qJEn*#BjXIpJ&/LqdM8jBVL/up
%ncLcq F8w<=u#kRK*+q&NteRpk/+5j&4q*Gpj68&R9jqKP*kQwZZ!Gu<*jWwneA$!c&:j5au+a6>\D<pJ>DqI+
%tN/+H d<wu:\EM4@R9+nB8+:j9AWp6kq9S?*j^yQiAGy$9b+$TN>YjjKbEBc>p*6/y:>\Dpup44!XD:kchjaa?
5%=t4F 9Vn4h@*Fhe^:\CKV@Z>!#Kdbt+WwE\@%wS$?Z!SB#SB9>5Kd%/<*@4PYdCl5>=mybT#1iwbHEVdPGj=p
/^@4Zc Wp9%cj$$^Q#y@j%5>D*k<Rj@y\:D:>+DWt9*G/?8dVQjP#QPSGwleCyT>+TQZ$XX9VAl=9@nb?N/C*Xh
jC9$#C ynZkN>cFQ9Z4=b<@RqYq!#@PX81qL4cPqtu\9b1@6l=<XnwSWLR<*DEk>=c#EEewBy6WbhXJ@&>4mykj
V%4hCY *ePbS4N<$?^jW>k@&A1wtBP@^D5p%j^Pt*yPW>SDCq!?PiQQ@/E>/4bW*#6pje&@uW6b^myDJL$*dQ?5
9P=Z/@ B%9$lqFWFmabw9W89i++hH!#p45?*9P#bSYll:lGkQ^uZ\pcd>V?j98A5MN/ZwQ=M=>66JYX>8@Jw?aM
<Tq\bJ &&1c?RkwTSS&?kkKQhp?H9yAhJ@Na%+$wwX/H:dhR$5Geh/?D&qNJi^DMwNyG#kCLRCWHTt+CqWBlZPh
^KA9\^ ZVlLQePyXdX/VMV1y4iS5VVl+B69CFFP@ACC^u^^:/W?nejX:lEVe?8\MV!YFH$4qTWiQHm5dAk?%H6p
9Q&N1X SZltXm9^!#Q1SK>dS&jm1l@^ZdSLWGNM/Z%N>biPucJtWZ6PTFH$Vi!@XkJ#IXdiRm*Jy=8#4jP=cH$c
4WhDXV \!kXZaIaet>iBBdqZH8=H<yDCla\:6RPZq^!YAliyLhQe>/WLkn8&W#+:LL:FNn@iFuqM:PahR?a54wH
Hy>Auu !H+=1#T+B^VZC9$/\:N*ci%diy**ABY#kF@pKL%q<^q1C:k4GEY/T*l=djcL*1?Sd8ZTMY/yKm>?<aV8
:5impT C8Q/LiVZHK!@?@b@>?HG:?j>H68aED&XM&NLd<Pc>64=C#ulhV!ubEi>G!iu1JtkNcJ*jyYLk$qnMX=V
DWZ8yB \98PB6E6djX4&FcW*Vw>uet#$L4w/HXjX:6*n8pjI:<=YLGt%T%#t!h@1mj+w8#BXVMRL$wSXV=BT<hX
8\d&N/ 5GHqPmlS+CN!1Z@pj9um$t*@dQ^?<de:FDq?E&MHBpP+@#@V/eicV9j>#=6P!!n@l?u$ALR\4*PIk^A/
QSA>TI htITFS/hm+<9Gd$TZa<ck+p#GNwyI\CyPTRby$YAK%$b#:jV$HwuZdpm<IMNw$mbEB#nkpkbtV5Ayi%K
RnBJWP kA/NBS6CF%ESP/FD4NH^YXyVkmM*<mN5J^TTbA1nJN&<+!iS%jRVChmK5#A!Iy$E=b%Y1$SIMQE#iMFC
8N&uLA VyJE%i9pmQlWB\E+B>Xu#6R5CMXwe&V<E/1\BQ^\\A4<Np^KIRkw>95p1u#6P>T^WZS&D*+b8BFc9cmN
th1eM# YCFVjn\YJZNNY%^Q6n?55AHDF!/THB&%8N++G1!W\jGL!j^n4N1NPDk<wJnLju%EFikcA=D=Zb6RLcj%
<\pidP N#yENqEFN*$<lMB9dPyXWN:XXQbRHDc@CEEW?KeXdK+LNZ%k#m>8@FTy^WJFDmh5MK+P^K&\?dJ:H<b=
%qh@@/ Fk=4nIN?pmDA8Y\V5At=/E8dpndIJcw!nM1wBIMwXa?p:NH/$TidL+%&EGCJiC/nAmV:9mtRc$Cy>@&k
LjpRF1 KW=:m8YW?M1qM8GN\6Y%1H:BH=#NwwI6!eCXLA!E!RXd54^GS:Na^w$hSp58tVkwDX=pQFF#/Cu?mmJe
$FcuVH R6/jBtctjV?P4J^MRGS@!kqHV*X<=yDS1S<WH@N+Qm%VH8HmVFV^#lPS1GT*!X#HXAwuQM@&1L6N>eVX
6&#Pdh HDnamS81FG&k\diH1a$leuMlI$eCbb&:K9@B>ku:9d&#Q1uaNaH&EAiBu:B4>^Y9m*Np#YRRuG*=p%1N
cRC&Qt #>RlAkyNm5N5^B@t^qRW>XBS$dEwIH&GY#Y+H:$?P*&AayIi<@58dZ+P*>EdwPEI^4t?Vq@iN66h9KS?
aQ#KGk hZi85GCLjmK&^iSQMj=yk>dWyn+q6ah8bFbLYN!1?b=c#h?*P@%KDplyuT$!=^PnyiXFGwXNK4HiC4^&
-AHG^H 000573531fd00110333 Page 385 of binaries1.zip
ulF=5i X1A:8C#eT8:<Emu5m?#wV/&SlWyt9CL*SM&F6E@Ac&%yIN#i%dQWiS+4bttMDTZutWB>c^Pt$w*ME!eM
P=^qW/ %yp#+5Z#:bAauCttBpJWqbGZHmE6HPLIu@A!L<\$\#b:^H&:iqYGF1CPaT+DGw/EJCNCNtA/CItEKm/M
^/5+G6 emEm$?=1HnpkRRHjShiCq48NyK<6Ee51w5DDnFAe%DwRc/<h5@mD\%L4^%ak5j6a+kWV%KSjnwRl%441
F=Gwib uqw#nI\KM5a@PAhI8@R@t\?+Tnp=M^>?6e!mQAN9VqPnYjG%ySN:cJh66dq!hLYja@+k<k&tB>@I6=Yj
Rbptb@ MQA:+jbMPIBm/BSwlyY%aw?R1%??N>Fq*VEC$bGc<=wA<#R%#1<ktKt*46IaY>9wZC=nWy*uZkNiN$NX
4qpdJ* V=REQ>=$=BcJdj<TuA=aRWdHSe<H=ERJ%EM6ceEn&TeupKu9Qi*/%\GT=pelMp@Q=tcm8DHwD?<t>%#M
tB#Xli J&YN6IQkJ^CH\4$u$qK%l>F9bq$:cjbi\^XQd/hYlj$WZDL<nIkCJqSb$4CpE$t&69aMpZnX%^A==b&/
CR4qdH t8$PP+P4F6pctY$jCRpieN?IuP1P9EIW=THpMANP=&Z6d4hWRZb^FwB<H66Y&TRqZ?Z#VP$nEN$Rm?bR
I5RnFi 8GdlHY858H*Huub!ni8G%kGXT9&D9jdCndITy#L^=kwSwNqiSR+:#d/#HWcYeHR\Qt6Jk:PZJV+aq/1k
@c>>wd Sn1YCli1?%$nX\^Iu:lm#:tLmTqT!BX4u!T1tIWRZDadBp<j6dNAe8V58tbI?Z5PT:+qXEqP96YXLF\H
F*!p/L t$>K:>ya!?tWW=eY*L5&?K!RXklL&Zkc!#=^%F>i6YjLtKHJ6tZ1Mbw%%e?B9^?w%ddS&kXYEXE5&FTk
GD1+We tEjK%:Vn%T*aSeCIjy9!Zu=:1@XyDlaS/#%5N><V@\Rqd\VWTWZK@pWb9QQ+?Ek=%?tmDj^*IE#?@q#5
Euhq+N 6DDNaCF^PpSN?SGF*9GIGWRhk#QT4:$&KY#k:Sh6>m@RFHjY$?kI49kJP9uTiuA5uDd$iu>wa&XG>k6a
mA:4XH +jDtFPbTdY>etX15Kwd+Lk!Z:?>=hkbHCd4KC&>ZLSBA&QWXPD:j/E<q?cKb\d4n\K^6bjmtCcY>H+lK
#G%cw8 &?8ataTNYhwXWmAN+eG?PF@h8QhuY^ujKwIn%wmC?Qq>^QJHy4dCB>ZWl+YD4eZ=TVNp4Seh+5JC^IDy
TEu#Su V@$@?>NQal!IW%jH@kS+k\uXBQp#9?tZtQu\Fm\Jjk1wHGWpZn1S5i5<4Gw%YHCcDqi8w@D!eGBuw86$
#9#aP^ Q=lCaGkmXQZje^!eB#ISd8mjI=:YW^@nj#%kVE@YC^4GQKj=PuQ\#ELkbiZTY>#&//FK/<q$c+<R>t*?
HiP&W1 F&VaAZ$Ve*B^b!&mNb&IwSqCRue/4:k#HSW=pTanLD/Q#HMbNRSMHK?=PZi9YLJ%HjlcJL#y!4ALhRZt
LNCdDB TQHE4^EI\KjZT>KkNn6\6^X8%FSAjDTPZZ9K&l#4GRJ4w*qNL>QqE69eGIKZS<n4:E#SQ9AaZ#epp4>c
aPhS>: M!$8e>9j>dth>8waK+GNMtSqNBWNyQh*mjdLaqiqCQM1\ab^HLnPm<5QSMAG+H!WJ^%mR\=MTBFpYE=@
FJpjXX <9JeRZaQ>mTiTCnNC6t96S4V@@iPul#@D!b^ebQ<bhj^j>uekiP@t<VF>b5pLp:8S=9Hej:iQI:nN^9b
We1e9R Pj+%e?8BDh$epMikPS@\QiBkj\!c++GN:B\en$FDHuB5+PB<DB4<kP<BB>hn$K\Q?B=\eD<C#j/RWTau
<QC!YV !&QRHA?lYS?Bj6Cpp^Q<GQTD^*+M%>m+HnnjuJB@C@$a4n*5F5H=GLK^k^<\XiF<DNpk4A>ebJ#@+y4A
Hicw&T <d<PL9wQF<W@ZBQALG!@eW*k@F%\EaRh@H?NycLV@&tYmnHKkjmFc/F&?=!!u8/jBabCeewaaN+iAuwm
mpRS&? WQ61ktC#XNAS+D!uCIJkAM6Qc=:EclP!VQy?IkmC!+IPh5ElR*uFqZ\ZiQ4YIpmc\Z/A9WbtR?kWJ@DW
Qw&i&A *b+\PpC$4mpR%mcBMd4/^yAW1Q\V@hpAib=iT>Vy#@@\Z!RW1KaL:Zd*1+h^MJ6HDGNE#BCX#9GjyKeq
HA*<:H c:p4A%K<lAGVPp*Fm98u:4BW4IW/pkVC?1w\hyTcmnFY!/mTIkT#<BWNCe5w4<t\^JXS<@CM8D9!qk5=
P6hSRu &GLV4yN>9P@ACdknt4KG/KwlaF$KkAi5L&X^cnDy%yVARFXYikV/p85GaSqjKA@/l98mZSAeb6hkZ$TV
6&:^#b Xp5kHQI1F:B8W^?^uN/WAY@amZm:hJ/$*G%6uyX6%BBG%a1DVk^%/J6JEE#TXc\\LPE$+<1?duMW$Ati
#F=RIR W4$9^^1^RX#iRaq>5FN$qFB8pV&u9a@lLip4FmB:&>Q1qIMQV@5mp1/d!>Q\lCk&9+t@XFSXhFiC:dmY
Cu&4DK JXWhhnXcyAQnlp5SSt$ETbB5c*!Y!6*cN^nBth=9MwYL&4D6b:d/eYFFLudC>>VMtN:5E=H6pwAND5L<
lcGlZl Be*+@AK8l$/yJZJ^wPAKB=Hp^&FKY6P>5+9*XWHaiM\J@RiBu:#F1<lP+hY+bb>/miNGn^NY!+wkKZ\!
^S@ymL VCS%4uk!$<nRq=HX8+kA%/NQ<@qq@pE>PNcqWWd@>Dte**#>6ZmGI$=WZLCG@S$J\hLdLTcmml!DL>FD
<MFaMu nj1Rb5R*qY%Ja98t>R1BYDt4#T4j?D@*ibFC?$uB%tc9w6+pNSninA\d>C%Gbut<M5k8y#*b8hQuaRj%
M1Tp9+ !hWS5Cn&!j4#C<QW*?S^GAI!+XkS^dyR!BYQ>tXKBKGnV8n=*XRHBm=+nH=%uJ*#%:FCSkiBE$pNuGaD
KBIYmt Q$mJ/d\XlcLTpJ4KTIm<Z+IRNy?bnaFWQwS+Wn48$EI#DTd<L!V&S5h:!QI/ee<SQTII1FpBNX8VM<SP
1lm1d4 $jX\Fh9RP4lAM:<Th^^!%%Sm+8X>dWtlIc1hSZ!qI6N\Y+h%@B/TRqp+1HXeNVNi#n+lHMwdq*A9L54%
NaA<p< NWI@+Z&=WG=#@>ShpkC\qE$BPq\FiE1H\5pkV8pc1d=tM^B@d!S/tH<mFSq9h1Q41&\5D!ipYQ+!p*:R
u^+G8+ RRI>DGjX+p&t=d&lHeP*1pbm#cm>FN15LLJt6^mayYY#lLK/AWt%lp>L?%w!%8ZF>bLIe>9XmiuKwnn%
YSlmJA *FYDAYkTXll:L#nXY&>T#^*j?YbSB>dyBSL6TQucSlLp+<NQLHc@lpi#bK\VmS$uCEhKn@X$tRnHc%1p
IBuLGe nSZ9@Pk9j>XZ?QXt&4w&KGPel=u*1:MhtjVKp1kEw4M5lXR1TYe9k+HbYkHQC1Q$t=E8E+QNBHm$ANyw
SwZQl? =YtPeL<yc*+Yk^#<5k=w9>cHK8&kL6Wc\D^%edP#MJyRSW1YCZCDNXG9GBPHB=5E#cRiSealdF=ciR$R
*=c5<K q/@PwEbK1PI:4KLI4?B&yQ8J5h:CAFdTDB=tc\XJWil=b8qdGW6wk%wC9qdJ*p:CtFPn1mjtEe:iIa84
!meTA% XaNEu@iyeBbhtBX@aDJ5R\>eaFnCX5NpjS+ynRq<ZKJlMu=NiqdlF8yE$5/WSu$6$JT!ZKYMbde=F+Wt
\+bB=d T6tcw5+!5dG@j%:DPJ$>P:>4e?p!*YCVn/ebLJY5^X6$F&GEX9aK:/8ehe/6VPV4+84dM*@je&JG+5dt
&B1djl :QSDcY$p8&PE\$SHDRVNyPB1t%&6A8Rc#1icFKdQ$IWDT@9!SL+K/CR=&hj=%k&R%A8p!?b<nT>/F9ay
RujFW? WJ8c/W%AmPy8QpZ<jtA/4ZeS<t1j%Q^4>cp!M&FpduiD4\NnXey/*WJ/4/jJ&CMP=ACh9qt<9YmT=bIb
!BRWtN b/<WI:tM+F%GVpqMXi1pib@11Pya=dIM4GbZ=^NK9dGb@XF:C1tXim9BWCbqbVhZwNR1j8iB*epnNZl\
\/QZ=T E<6m@Sch6AW^lK@1BT/tN<n\J%&lGE:Dc!/jGHbY%Q\QmF$ua/%/JTJ>J>Zkkq*Ryj1p4?WwW*dY&!FC
&19l!q F:Iup!!M^J>XW^DALY/nFNwe%C5L\dF4SI4XSL^XGW8=PJHhGl%V^tRh6cKP/BY9R=@dCalZKu$q5y89
HI&=l@ FYL5^mqX88^bcy$i\FQmcHu&%1*9XY!a:cRYa51!<%F!S+F*H6/^^FJm9k?/VbnmZGX>$W@Sh>QqnjJk
h*=D=E mk\L+XNX46pCppl45XiwwGqbQ@IK//HQq\ky>6?Ydw4*8eKFl5eLTE8Ieqi\kQFLhq+9eSy=NXmlZEGC
1B4G!l CVWwdJdLqGwd6mK/yy&Sb&LHNbe*@6yT*ZbCY^w/L>1\Nn&@D#l/<BA6Ytudl9G:IDH?HHTj5YWTt=Xl
Md=KED A$B^nymbw>4w5=^b6mcw4!ELW\mY<5J4@S=mhX66^6u>TbMVeP>%+YG?9M9FFGKQb<aBi/H\PIneaqPS
J%In59 q1At>4DMlN#G=Li%j*V5Vi%jjp4D^FnVnYZ%DcL6?Jq^RaiJ5@GnNtE*BR!<i<!d8/<jG/hh+^GcYTNd
!4!dad lD!KB9u\VLLd1w>KZQXSNy@t^Tb!/uByj/Nha%qHGu!b#JQ#$*BXy#C9DF#=*J%Z\pyER\iBe:4St9ni
#h!C\% QQ\N/:^#dIP6dNpIHQAI=LplCpeyTKhWPJ!uGyW1/Bp+9lm+9&D:T1<:c:8beJjB?4Y&R\Nc=:imQauT
M9mw/J 6/W?FhG\q\%<%>w8kq:%T/BpSIj5:c8$\/=*A!:4S*WtR\kAK<#J+Mn5Abe:qKycaI%kX&b1&LWSMq+R
mnPhYh :I^+qACL>YjuCD\uJ6H?jw:=uRQwLtyk#la<hCBiQAq?$^ISiWj/SL!<JATl\H89DLMkED<V9mF!mMXc
^&+VbJ kl8BH1RG8=%R$BiVNaWi/>I5/<XeWIp1Z&iCtt=F%+$alukq\cSGLZ>k41+hTIw<wc/nPIl$putu!FXM
?d4V\a pRcQGT%i#5JmdyXe*NDjManPWLH1Q!J>Ww>/+wh?W6T@9Sp4PlXVqiG$^jAGZSk%EE\N/$LiaaZaBe@e
yRVh!i wcPa=YT\W^GY+*>plIpAcKKHtmCRFKGLeLF%R\WD^DuJPBAN4Cl!\4ukKwSYhdHITnnkVDl<wS#hDyB<
SwYDR# ^D?MGI*>!W*X<I#DaWTm8Sq%/H##pE<hWIV6$IX>8ZN/RP8INCVy<IAG6B^@aICFmKM:ak=L!1aN/SP6
!C@#@Y YSIl*Lk8B8kCKcCAD//H!mBTjtPEY9SG\V@wiR/mRL+ZBaW56Z?tE1MiD@pN%WC/GHYZEhCmB/1IVA8Q
FFB/VN KwtIMyTHAEkkk:$SlwP*lL1\YFEkp!#Cd>Ck\:6wG?\BV>RHR=Ew!1V%WBARKm4K1HkTnGbp4Mj1uQky
Papl%P Gd4K5wSRdIk\n&:m^i$CKInB<eLk<HRtBI&MpM@SR*X%D1*Spb+1&>8dYIuN8<^IMT!t+Am/WF#$1YC@
$pc/SJ p!X%bS8u&HX6/^$cT5@RQhYQP@GypdjaRVRkk!+d/<</!y6M+>8&$G*b1WB4y9l54A5E?ByL/ZC*jI&Y
6q:66S wl&k:ak$<>lHBlbnF4:QFNNMynb:?ZXNS:K&yiHycKtdS?EdhmZ*wllM?S9MZ&qaJ4!$DdwlQj/&<aG6
kQF&*T CC8hJbka<qyMKl^>Z&t5XSmblwc8ucXaTmZnV&k$lnSY6+q@WGm$d=Jmq6p6!:lT5XH>#HQbSH>CXku>
XlaPnM TjaXu6/L8VajBuT>mck+CH9#B1PZnJynE>&#1A\^jcKbi=!M!byCLwRGbIt1cE#\SL+E/J\nER<yLEl<
5!?\C4 =&^QH\9HQ\!TGGHq!:Nw4JntTWkVDCVqnc1ReJ/VWunCQbnNu\l5*yFA!DPwQFqbCkRqMaF%i!^=a$My
X#!/## dN9Ry&<^YPl1l:SEVRph<#VcI5KZyim1+jNATA+FXS$BhA/NqSZb1A=ZJdp<ETne/\6J=%4P+apTFTIm
-A1c1a 000d10d16ae00110333 Page 386 of binaries1.zip
iDu1mP hCFQYd4eXTN%/WZFeTAnXMwXt%aw>AkkuB!bud:TEB4kX+jC<DcbcR=G$W#JtbdCEBy$k!Fk%8yuJYVZ
+Gua89 a5X8iA1J^P&lDh/ueFCI:D1=jhuw1lZ%1RGZpmpeiT5HGTcH5iBVeu6eettt!M<Kq^n+cqnWq$@^h!wJ
L#J/KV qNKWVnNIqLIEqRwJ<:1Ju6SqPZ+k:6wl:^IYXSyYN8IlZ^X/bwD:LA8Hn\!LdjJpy8iPJeB#:NeZu6!4
:*P&@H =ASClEe1RNe!B15adE9P\Z*SmT*XyVA<EZSX\&QS$>W!1JVm<4JN?=knQd5KYVkQtJX!5j#9pd&aXeG@
$?lk/R FycR@=dI^jZjVLeB5:D@m<kFbwE<X8V//#4*u%jRZL?SLdkiuYQ#t%n/*/AjTwQ=VT#>d>AQYcL?Jyd?
E&^Z94 N?mHEqq?E$9@4&n&B@9N?Sn$k@*tik\c<lCc?#Hwl?T=*<VT@\dN<lCc>XHwB+Rt:5h\DeL%kFLE@Sm8
5BWQ@X 5ZE>\Bd8^*CN:cFRFP:HeI*6IVNZ:5h\ni$lM%j8^*AN@GC@H<M%<EPY^>!Q+h1D$mCa=VFpa?NtjRDN
8I<kw< ?t?lH#Y^QhB^<D@G$m9?Dj8jCw6@u+kPB9<tES*<>+H%@!E5k4u?9$V$^^Tu+ACD!GGk*e!E^F?HaPNT
Fi&ZPb clqa4:#8e9^kWn?j<<Mq:F#BA=9M4qCQ5/\t?MaNX5d+%1CjiaNII@HCpFkAmwS6lqBNBEG@AWiM+8QX
PE5RYG Lp+SESIw6ZCXS6F$QSQYnB@Z1INXLA6IqbGa8*TKm:B9#hetDnW/J#/@PN5y5/lcj5C8khjG\JA/@I<!
5In+GX qjB11Nb+XPXNA\+wY>IBS$d&?\/p=8BtCAh+nmMHt!8d?*pWQQW>c$#tZETTP<wReMnM6tE5\TJHCq$C
l9?XVS >/E4+6V^QeqbmcStwD6>npncW9E&8DQDd4eaJ/H1tPwkALG9?1!Ym1R4P$8SVc+:H*P<R!llAlPDyZVm
%^yj&# 9k$dVRw&YE&^Y/MN>@X*HqE+WV1CILnaL:y!TXXK^lVXdL85pR+5Tqb#RtKB*NHPWGM%Md#IJj\=a@TC
XHw%j> P^%:5Va%$B^86<uLFPN:4Aub:pW#>My<j=#cNZkF+!DkF6&himMFJiyE$9K8G8nddc/S848GIw?ik+cR
XeAIp< pQb**ppdjuRPIKc8i\a$VAt!#$1JTD4eRaieSB^Ew&w#*HY/%ASyuWKjI>GcAnaQM@Q*Xq%5*^tJnNt#
+5bF*Y $HVVDI*yN\W?#j$MIhHG/5WVP^9S^P*B+^pYTtA9%QBEn#IB%q:RZXq5GP!ZLpGk&maIE/WRVDSt:<t5
HAGCcG /G^E1\8hIiBkSc*YuNm:ucTD#k:FPdiaC4cY8\Aj+h4uI#eGN%T#DVdJhck#T5Jbc1pjNJ$+/X1N<!Pu
wt/n^d kB!WNbk8c&InX^Bh*d5y>eanC5=wkpQE8?X^M=a4JV\Jw\5:*t?e?JQYM8GNbpyVZ/Yu>kaemRwb+MM:
awB#*K B+GR%CNY9>I\Jb=/^Je1CE?<C#61K:<TuE>MZdX%u:aTjjPB^<k5IEIA%n*>mcnje&KYIJR1@LX%QN&a
\R1QjS yX*q=/qipYa^RWHFY1JIBye$yIHt\6$y$e>ZPe?LICtJAT%4%$?qpFalhd:MdY!HSV\t>5^@y8>W1NMJ
/d5RJ= ARd+LX$M@l4a8RNS*LIq+RmhtV%NpVY5+uk^#XRTIGqnP\F/Dpbcd>IG<tqlZ8BXt*?@\&nipV?btSBy
=MEXcl AL+Z1V:&RjEI+Hd?:L?8dclFV$nC5^M+pB!PEFXP+E8FX>C8tJ*1k*:JY48#d1/tktqN*cdbd<!Zlm>m
X!itFT a*p/Y#GAB%k^mJ8qRhCXnShiGFb8*w$//TJA+QyCcKTWItT6DmPB5EaCI/\bJ/<Y\N:u$n>TjK#=^GcE
9iWqM4 WETEFJ%BHKGpGEcmADKd!/hpMCpQ/chGb>D1jJ6<emwRcM#n9!:dt?Ta^+u$M4^Qn!ieN&9qQP?1+FZT
a1Lpe6 @q\CIk6?u1Tmt%:6J5yS$ZljQ<&J/T1JaXd?De9LRI>p\uP*!Z1YK6M8@/tDY*:5&:BtyJNd:aRjlpkn
m!>CP\ I%WEwkHaaVtcRA>*cB1wViWb4CQJ+ElX$XLn?%=+wI*lnXIB@DkPQw>JbdAh4dI9MQyWV#Il/yRN1btL
4HmQuE XHMDLewD^G^kq41Y^+RANDSl*I1n^XX=D9XV!/:AJ&/hXZYVb?iP+:KMLAq+w\wQTk<5Ckh=nbK=51u=
h#hLBC l/nTScKmQ#pwX6p8W8WA+Kh5XECXSR9p#wuS1dGbGBZ<edLN#Kp5F^Z5bqh^EMmb:4CF*58X!%+^tJ@$
ihP\jL aPM#Jpa4CSH<^K1jqeyuK*4C4E!\m/QjG/&6yljCLR4jb+AGF<qaH>El/jtcITDAB!b=81SW!uSTDMqe
?K+4l# QZm<RVH<>c!m8\FMF$LcyWQ1%n=mR:LbFKtMpw:!NG%h?ch&Wmt!4&uPZ#K?88P@dB\$5N#>nqla$$$R
qdNyST CtQ$bY@eCNECd?Iu%S&ekcXYeVTeZ1\RAZCKBl4jP5yk:ti+>nM+pyMk8<@Tc:tIy!!<\F>^pKCS$>Kh
6IPa4j CVF4pXBFlEn9cIZP!#!T86ET<+/kyERJGW5XEY<Wk+ujn8&MEEp#R<LZTM\SwyKCL+l$55!WV>uIMVV@
1%&R<P mTMIn4HN5hE%i&BDS*nL=nKtA:SQcT#=Ttn&y5tt+TYFbnDdG#$+YGl!Q49thcM9I:dyK?X=iyqleLtN
i1e\D5 AR$I4#h@Bi+:RhqH%h=#$\SeX=Pl9A?5LydmS*R1jjm/+W@SD=^CSRqk1%J^*QWqYX?41iLXQR$wtV^E
GT?yMD Z&*p/9Ki:dW#yq<#lN*PmVlKQGKVRTpK=1Aua?cIDtq&DctSABLNG5ed1Vp&#PQqm5Z1wPu6wZ8X9=NK
LknqP6 hL%1MBIcDTiDjcunIuXnR6@YNjCM6GTJe6:=PElb^WIbmEY?cd9wM1IbC11^D9WAwiK>dE:<GJ+9nq1N
A<@S\J FeVenE:pap%jm5/dR5d/R:HikYLRjJ4chm>k5w*%:bPwI8V^+:pF<?Z>SHVTFt4^V&6hCtdjq$e\9E?I
\XPXY/ \<Amek:&!>ZiA&aP4#j<>=KiQQYW*!tG^jA$nw\kl*PWndBhQ#9bi9$#:ESQZ@1wd$cX!:V!=VpX@p8b
A*Z*XC mpWd&Cu4Yd58QLMS6YXT%LS9+T6hemlGTCee\Zmwbbh+E<cwya=%u^R5Ie$HJ9TwjM8YTmIanTTHiMuD
X$kl&j tlutb1uZQ95&qCKMhWKYEKSZQcYb&^j58VYK::RZn\y=ABXPmaXkPXZ59NMRNAYT1S9DYh45i^1YahD<
uwD/AW EXWTZkXAi?Fe^PqcZ@GJ8J6@/kR!hk>Ry@@\uWNwVE*bV>%&K%^n#%i8NF9>MRlE+id>IN6G&c*uDw6h
tbBeK% +$Z$=kNEpR6JlL+Z+6%ZPZRN*\!iS?GR6G5%jC\NaQ5?>td9L4%p+6nh8*ltTpcTaI8#DPHp+@Mn*W4e
u1aqJY wB<uNB%PXcNPZ/JQG/X^p@6iJS5EjG>H\Z#XeXaZDapCAn:c:#k!kD4RX!A^&@dFN8m^JAma1NPTSXt:
mFuDeA m8jH$8*dN?%Tki%=QQjDptwSid=$ZEWPwtu&WN9RQk6LucqIkJkmXWVjX%m:nkwY\N$Ep&A5*Tnm>qj$
qYeE+T kw#I1>5nV=e\MMlYZ9HEaVFKEuTamd+9cV!EiG%Cw$%GeT/=hEC#wmc@dWJ^wq@^Ae%1awJlywKySkP#
=whndJ B&SLl+BC+kE:IY=BS$XhJEG&I&FK^tHEkYlkId=?J^pa!iLjJCWC+1BSbl56p=by=VMwYDH=CM#1<!WZ
<=KjDI AHceKekyXw8lb1M4y=TLA+e6Sw\FkQbM?cd+HpaM@85:AYTIAi6&mPdZkRle<bKThKJ=$yFkSJMm4!lw
N9:lAA hT/QB1Y:n*Y<VS^Z*cG+GIJ1nc*+G\c#4NWiWIGL4BpyRppRj5^h%Gui<Pc/^wnwnR*j#VDt^imiD@^Q
D6X9L$ kkJ&R8RRww/iIh1Ey+W/muLPSD&659aCtb94/uGjLb>pPlXTEnDMQ8pLqwQH/^TbBDlY9\AwN9h6S+eH
$:5<A& &4Q+Xm1BC1wm\jdE9bQ?KSkmCGWYhTH+jRh<6YW&@WE*@jdKDTQS#bV?4k#la=cK$bEY9XEhd#Ew#EaA
bHE$Qm R+Fh9iYE9RhtRh9iT!\4HtLEXPRJwML*8MIemMLCFF8ikSJh4%ulZ%5w1!kV5lc&Q$X\!F4hZnHbiNI^
KpZMN/ DS@ab=D:QV5ApqJ1Vm>Y%%BbnaPPB=Em^*H!=FCTya%VDLARwnG\w%cP>n\%aA1XZ5dK%D=iy>5JyKA^
IYYnQ$ T&YPFI1Ey5Bjw/IqaF5u&%dY%JliLXe&>XWYE+$LZ%VK?\V8YDCQyKMJuKM+ZS?L9$TA4h%d=a?d8MAR
Z^c@YG @!anBcbc+ehGa1?k?uL<5T+B$\A\VGc4jHXR6nLkm4W/!pwFpatuTWIpBR?L=%9TIBaY^J5ynmN1jABu
=qM\pX j1leV?5@/w\XR+l%T!?8MByT4!mt^bCqJ\*@ulHJpWA>pq*Y#SE@!HGP%!PVA+tMwbwkwKDA9?!6cT1A
6?ekjX !FyQRH%:!TMCa*cYLw$uREnPpHQQ96mq6!wJ*Gd!mMM6BYbGyna@/DDYC:D8?AEFycMRb\cw1+!6TG>t
LHGtJ1 58S4PCTkkWK$D$KLAZ4$YjY&&&Fj>h=aKS*YdK>1Bb!ARS/!NyKZAiyaMYn%RB^RE6S*bR=<N<P%YKm#
+a:APW awIBLD^Sy=wW&+w9P%cZuSAi:6kBRt\GImWh?wnbXPYw^ZCFnD6MDw=MdSmbJV4A#5>EcTdqDPaF<%Gd
4mciec JHt$XjmF!NZbe*=d1@buui9@6aRlMA9H@$1j?:Y$+@1NQkj?%@SyMJnn$jwe?Le=$&CYj%*>@:tJn\p<
n+TPT> A4N\QRdN!j+At95^cNaH$K\5@^cc>SFw>kiTZMC@Tij?Dj4Ba:M>Ak*l+H\ADjt*$P!QRV>RD\Z?VV4*
=5QyL^ 9/LbHn#&a:nGButAc/^e@^d/MX^:YGpCQ+b5dC\QDB9+MYVn+HwI@Tm!eZI>kH+M&hnbH>Cy\I<mG#9L
N6X^a< A?l@VmV?K@a@W:u?w&L8V!wZlPM*Klj+N+uEpD>T89/9KJ<nlR+@nj<@1H^PR*tp%9c9FY#BS:W8@jtp
hbVKuq A\=SH%iX1/wRqTnk5E8qpI61wEJRj=\<Q^F$bFBe#kJuEI596E+<%<WVB:&MmQR=<&uXJ?J!R&EHqn/@
C9FDy8 DpXYiM!*pLVR#lK:e:<@/8Bw/JWF<BHQJw4I/KRQyy>t\\ljjEWk!=yqRD^de6qH>K5!B#Jkp#Y#qi:N
dMM/*5 *PPY$9H$%jRJThwV5Xkd:HAPXdnm%#QG+:\kR#>ky<FSu8\qG\CT5/nRkkLwntulabeyCKB4ST&a/FY/
NlYBWb qKR1N8#M!y$nkC>Kc4kJyFyT8en>#^Dk51b+$et##y=KV=SaM9IN#tyWIc/q??AyDQbMa6PV%l:mM*RC
#Sh66& KuA1epWRY!J45Fa^Nc^XTb&b+BlD1LypLpmclaF1VHnmpaEq:YA5p*^uSqp^uIal5NNZ<uJ/*#ZTXTHS
6D?N+N y&L>$bSenY8KPbYYI<t%\j61jmPn61YppcQCDBnqGQkLlwtpNIk8JutNi6@:LKqSu=Iw\hcpDi*%I6Rp
B#V1j! QmZeQpqm\qScA*S%1\b+ScRk\KFHEby^&?q^YQtJX^QGRG#iFSn61^5Zhn*bJK%TH5uc>SpE?=1KLSBE
pX#6Yd j<m65Dad\LFbVGdCQ=TJZ*8n?:45!V9#nPjihV6cR=<whmc@\jNKwbp%yp=L#wRPdqjbqEdBCGiyRaQb
emlB?\ mwwV?Y>^P*BA*!Dy#hK16VAX=dJ=5W*1E@=HiN8e=8bpltey%pa%Nmb=H!4hqY<cLG^Cuub<@=:$5/$<
$Rkeky Gb8/*wMWinkuNa8%V<H$PTPD^%ZG9G1V^WHRt!NTe&1VaJ8@*Xu*1%yI/d^TWu6XtLed%cIE&D1p/!RV
-Ay#eS 000a0114c4000110333 Page 387 of binaries1.zip
T+\?PY LQYG&jdP*@hET<bwBFF?1^MlkcwdtN98dKp:%u#SwpEA69Lj5ulL%ci^VSlKc<daG$RS8@$qE%dKEqG&
q6Cp9d kTiZbtI^klMibyH\1d4BZQ1\RSC1cAMhJh:lFP<41yN1w&ceDJB5ikVbZlitCGJZqDa56^SLFuhbQ^hc
6P4Y4I X:ckF6ZEW?4EK+jPSF&c4&u^RnpBTAtPYtCykVGCDckQPpE#8eHMD?\yd\jRB!?/kw=FImnWN1w#H:Ek
=ulj%C N1e@IQDAiLGQG!Y9BIEp=wY@Emi/GGA:tiRIPwR5y$d1plW5a9FG!QGWF+GJq^+Y$$*!lJ*/DBmj1Lkk
h=!yt9 DJ8&!me%!j9ElMqde4NS#ZhlP^=@b\BhmI8P%p&HCypqc\a1n:KtTNaFeIXdGMHSQJ6B\NJw%Wn8+FR+
JK$F$y mAjmjJNES*%hcE:bCb8G$wj/hJ4X\kL/5ScHItji$FLJWkmbkt!j@&&uySt4FF^h%q:8FH&&FcPeVCZ*
+lq$9h >6^EkIcK4b5:p8bJuJA%#u5y&ueeXX*I%H^dD4c*bYMNtEiaEWnBhtSiW/ma8eAkVCZVARK/wLhE^1hb
ha<Z<& EQHaV*A1NS4wQ<1+wD*:^PT6NyJC6Y!uN<9>BQDGY/*B=Bd+?>Qu$W=tFFF^q!DJYFw1::!/XHk5C<dB
*8*e5: DmH1!J85SNXFhD#cEDwaq^JiLJD&$Ap8A%SynbVK5&a+jJ>yc*eB5eikeAVT1majRSp=iQtW^\XQK<I@
yT*9cn S+!Ym!YQE8?=+SaqGI@&8F6S5dqak\R+\EnLHymuE<5Da11?Xc4&YE%+Tw>pJbd9I!yy<cF\MDAEn%Te
IF@V&S k@P>BaQlK=Qi9wF1FSLmy#JI+SPKiG<Zh6#pCTmb>\mk5lLm/bQ?h5\G5%!FLDl!&GZcdKi8@NSh>S#J
D\BbK* W*=15bb+HFj1tuH9cqVpm56!?^tRcb\@T^bLj?MXDV^XNn:PT%pb+5&#$GFPyVHe?mG8H%!nE%HcI>E=
6FiK=t PyncP+teF84RbM*NMCw8K:ENZH^4j6YqAe+Ii<c#uliJTXBJJF*P!pDJGFHj8Ql1!BlNPWK*61t#Ft54
QawPDa $q#$G4y@Dk5JSqF+:6#EGMyNnZmDBI$d>H+unq/V\mWSeSDNpGp/Yy6uJRl:GkR:EC8Hty^qHa!CctVC
tjuK+A EDXB>qXT@=k*\D:!pNA5q?bnKy8RIZ=>Lt>198m:IWY*$Et+4^=uC?e#6E1&\CbEj6m=+iBRBQR^SIwW
BN@SW@ ?wVDBX5yXEb6EqjjcDK=TGNWnRGLEhWCTPq4A!=!+tW/qmlk6n@$+C9:X/TM4Rk*mHlh%Hy8u*FPQdL6
euP1L* VKA$Ge>d8:G/#WulCk>wAHBpl$*T\/lF?SN9$9cIt*aKhAG=M>etRZ1h9HHWVbR6BaL^8qn#VicVJ\ky
6pD#>l CBa#YKbaPV^i6QXB/\RmkdLmH<T!6F96@PcM=GyIHZDkD<44Z5tuY?HR+C@P5Ta/i1<8ceKSH%y8/4lb
I#C^NI !Yj^mwRe1=C&4ZYlm!h$P6Mla%:Ym&88!uPQ&Wl!1B?VW<1PbZ#eTRaS9A1WdRC1S>P/u1B!D5cm?Sb!
Pn<+$d dQXM/ehBIRLD6nbCM:Cc@kWW$J?j:/b?Xn!yGPTT*:#+tyu*$=*JckGK:%D8XI<=ytjhCH::KZZySual
:!VIA< >YM1RpQp^^Q\mVEa!YRyltQK4W1^1H4jZ=wA#nt=*/DqJ/!WiiRqk69hWmBt+5FRGC?i!S#DM\8XpCP@
G+cCtD =9AAjqc:L$51S*ytIW4\d:ie!m+hyNkmNuTeeW@Kq:muAwtjmkV:6QTLCm/@TBnD^WVG4>Aa&GM5*1R/
T9q@9% 1cI?qtj8PV8Kbik^bKPtFyMQYCdHuhKZbby6%GWK8$WZnLiXabWGcl>a*ma6h%hPu/ch^cjw<\hcbN\j
kpRmFN :4$>$<R<tk?R6EEQIR%Q$bhMTFH+%HjeiNYnWGcN%LNNB:6<>Qq#ibX:$S*/kH1n/WljB^SabLHhp*!+
A%ES^4 V@c#mnCR8Sp&NQTuPi^tEaNa/EXAD!K$#FiICqT%uTZWVaJ8#\dLVM!W6RC1HP6D#:ma+FKJwVp<dwEH
1Da59% >ABLX%e&cAH&R#u?N&%SB#pP\K?knAnp8n*Jy9ThnpmwW&VkHJSt4IYpKW1tyAA%8EApy<Cja$i+yyDe
$<=S6Q u>#K9dnwi^HNVT^1JCjWku599qA/Bdnu^aGcGiejGDhIEm>FM+4CJLVZpGDJp:DltTkjPL#JWdbSX$=#
HJ=Cq? nL/*qI^mWtFy<WF/V+VYlX#/DDFpIXJWy*I\9Iw&PpB+JE$1NY$\/?6aylbtSuySm+B5%^YRI<DayZt4
dqTYC: TR\njSiNwj?w#?A4*pYyQGk#64+\jcAQFC=CatHmyn^kBI@?A<W8K#%AtZ?>GR?6K<C/H!>m!KWZ5+$=
>/w$V! y!Qm4IF!:mN%iAj>Zp+peM/M#4Y\6d&jwaQ18Z9qnHm=bKhwStiw/DL\PXQB<<5u1nKSVN<4>jbPnW!K
SG!*iV Y^jKwFj:lPbTW\6K%Ln&\hGDw6>Q#h:/9!Py6tJktEJFC4$Pawbq4FLiQ*y9j8Fwmth6*mMidKX<?9pX
Vm:6P& BS/mTh+^HA!ep/LSRbYh=cw=R>Y5BPI\?6:5RjA$!V^FVF>9Be+bRmm4dFWNm>Mk$pXw:G51c#KYpTwN
nkbwEC JCdjeAR/&W^GCX>ZJ#NYyi@yMi1m<HZhTmXXTqWtNTB^JnhL8V1>W$Y&EmMI!<hwKJSt9chaGJF/##8t
q*@jLH JAR>6wMCcklp&VR?8\RN+yY\uJWa\bhpRW6&/iA^:^Ja+W6QpT<VADT5PEp$S@SRcQuRcwY\WZIQJ%aQ
WlLM+? S!Y1Nk55T$>^EAb<P\:eueqSM?FZiR5pLA9j4nhk/a=6Fkhk8C$NLGQWVSc$!LB/#<=!IX^b9kMpEF+b
51euHe &NVl$I#pEF?cGqq6md1=JLhjFBYh8eh/<!G$uVAmZZA\nt!HDS/1tFaD6b/&y#JaSP1caFTcWV/peM1u
$Lh\@w y#KdR+FDhIM1K*Wp5%kLkE%AdwlbZTdXL@KPI5p@5!5Q<qFe@@k%9weCP5/49TP&MAwjn#4&cynQd1&w
aTFiT* d5TV8CLI$A&GclC?A1IQEe&uPu!u$Cj5:p+WB$6jIcMLmnukkSGS*c8<RtM8Zk?Al96>n!aX*ek/iCP:
!A+I=J VDDmGMy+iayaSpq/qtlA!&a4F&IH@jVmm\e//%6LA=mcE9LQN\w#N8Vt%6ALbZw*4Tu*%KIEyTyiTG*R
:#M9$H >Aj9TEGay5LY^T9IN6DWQ:p+&iaFkpEM$@9?1wCiV&NmI66b<DmmNjDETm/6T+#%!CMt9cj4hWee9VPF
Tue+Ft $lD9FRi?lh^D%AEY:T*Mu>a</MF$A^mjtZK8B\DRu#6bVLb>Wk#^A&k44=l=9q!T\61c1!LY*XtEu6AP
/*k:j! *MVKGlSR1t=m$FDX\4DktXG4>mHec5nlLiW>w=A4/N6VHlyjaT%<l#\d/!BD@lKNZDQISCY1^RC^Zp8l
<J:<?W aw*GYRbmC\%qwy+mF<IJp+LZ&tLuGTWJHy1FZ<qTptEQlkhp>y=j:^ct*&=cm&<hK=m<p/i\PYhuXCy%
jTiec# Z:1wiF%w%MBI1\PbqPtA45km!Pbb/!PICkQP1w=RnVbIqk8hwawwhFj+<IA%R><l+Qnme*X$jZp^JbdE
A=Qy9S <J&c>DDquyLpTFb&XKil!D:%KQJ:NANeJ5\QVFK\uFB#>GuEGPX9/M4ZSVX*YlMDQL8a^hPk!yPLp6n9
NeDG>l yhkpyhJNyWMhLHGwFJSq%Ph5V?L*tJ%=5XDZp=$d$8QwcKTQ5dHq#/cXw^Ni5tJ48YD*+%kty^XpyY%S
%QRB<1 +1IWjJA1^=&C@ZCGJMZPJZk\#YZnb^DlAYe@<<pP=:\H>NQ<i=a/XF1%uI:luau<W=NDtyXnyp\<m\$<
K\pWb8 +qXPRSh@54ZLS9uTNXiDWb4iiiQA+B1PJ!Ie\G$+uDw:&CXIkCMDt&TjGGGXpE1Q$Y4CQd$cR@*BQNL<
pFe/?< c%MPW&eG9dXGyu\:59NpaL%VtkJ/1eHMNdDS@#W:kWdFycuCwlH:!b41>VjRC?NT8p?8y<:!wq@ASl=F
*bi1&D ^E/n8TLWCGbJiG6dNl5M#lKVmy6>$m/!a\GF<pA1Z!dAVKDEmHX@elD%S=?9jXul!n+W/e9qDR+Thi@y
yI<\kE <WC!ZlwlS?:WjaH:$8HC1?F!im?*\kLlcB!6<aFt&wImNP/SZ:lT?SlVLVq*qJtRt8CBQwAI9Qn95L/F
8@/dK? XWB#u=BR\DuX%^CJQdjJ8h$FuAAe+6a/EyDbhl&qhKCm@#q4:JlnwBTq??8/Ce9l%RZEGp54Pqi=dHIu
P?Yc\: L\VAycA^9yKbd!dmC!Z^GnjE$HV<wV/#ZIwFi!n8GbMaH5nS<!5AmpaJ>taEkl%unVma+!SXI6eZ*6D9
WR:\qa yCN%9qEKV5ijb6^bwhyba%/@T$qPA?akF8cGF\F\mpT54bS*8L5ZtXHVRMW+JZn%4FAl%wSuGHPhaLi?
^a%GwQ MtFlRW5bY:4bNBSh&&qwSbk>^L<Z5lmN&CiEZc6SlS:B=\Dh:#EcyL+^Bk^6qZ1a&8mdqtmA$i6&VYj%
qJFW?h GXJba*BNPHDnCD1>t:9$tMFCQZp@4Y$cRHbBbk^GhulticT//yG@4#n>5\n<Q%h^!ppCajpjLD:>5*D>
^D\b\B G*Hd?hhjMyat#u?9H@*/N9hj*pD??wcV>T>98Q@eLDcY9$nldG!5+L?<?c5P#5aGkj#qw:@W5?4?TS^*
FMi>@R @hXqXyb@KHjq?y&G^Q*j%PElZQ?1\$M+H/*D@$ZR?tiynP$*A8Nj^8j9JeIHSD+&%5ikH>Jq&eCQRdM?
/FWFEp wIY#5V$C#j=RGS$d=DFw>kiWhDd&j\9N<Rk$lQPlWiN<DQ1BTqe\G>en$G^eD/G=H+Ntj$BRln!Gc&^5
Xp?&\: D!nypMh\ni&B8tk\=DFeA*M?hP#HeP%lFS@!GLK^eV@W>EiSnj8BT^VC<e>cPJn:j/&F@:ZI<$>cPMj9
hKcPLE =nEI=&<1Qnq@+j/@m5@HXZ^m!Q@Xn5^M\@nk:?*IF9/\I%9+m^%b\L@cpRZ>y*bp:IQamjl=e8uKlHth
^Kh5\B XR=S+Z<4>yR%Bnj\&8$a^Le!+/jnlMBA8%H=+YSyCIKi<LLkkGK#LPqq$PHqS#w6GX1?IeD^$a#CA+8W
SiW#G4 meB^Bwyne8nAwYqEbmmWZuAc85A#8kbhS8WQaBmcbQ>#&Yj/u<w?V&JbaEL6Tk9Y15\TEKX\@QPW^:4d
cHlXM* =KVmbXwJ8Q^#i^DAn5+ZEQ/ypaNJidl*8HTS>t@bYY1Xb?mSQ#4u6Rt$&/#:+!myjqjpnuSANnWa/<cY
MC^1m& MJNPhljTRtRn8lpF4RF&PAQl$JF@n8Dh:HBEp8eHId^5!BlERE?w*#iMkVAk+\Y4+C?:In#qI>Ic\cP@
\*mCRk Gl8^V+whF5StPKZ:hQX/i?1LTNYZ%=$c8Pm//$KJ8&??bEPQ:YVhN<hbP^J6JWepP$PhVqD>!SH:!tYD
PQh<Yj %Km*eX>V<dZQci^lR6S%8p&H%lJl@GXb?#C<bV$&tHqAXikj<neb<bK<95TaqhQ6PGeNm>SmtQAd4qV#
E5tB9@ :byc8c%<NhJ$iM51cQ*BVIAX!H=WMG%NC6ZGtEnbkHDbjNCdVAVt>nVk9Q!A4KRqH<e^^^dbDN?jN>S1
>FHyN% tnawj!E/kDj<N4J!VNByY4DYKmPDh1l6qBIZ!+LuTkZ@D=E<4iBHdhNB>a<JSX/wP9up/^EZeptPThq4
*nPl<& C6+FuZjNVQB\:46d!<Dd9A8Rwa8?BPPV?IXG+dyi^1Py/kpwajC?4?ELFkdm$G/yb&$9CV:atL!utaMS
>RWTJy LblC*!n/^FKZG4yCMEFKCQb:F9T<d!Jh5ayYTD\N+WX9SZL<V*^6VC4EIy!?/ppGXIMV=KVP@L6:p4Tj
wB=qZ1 EEqcMbI<&NSQt^RBpklJNCiSiZ1LiK@:ccXyp#n$*lN6Tw:u:bWw=<Yu?e9^$w^?Rpn/iKLk@EKQ8yw?
-APp#! 000ec630b9500110333 Page 388 of binaries1.zip
R5HEN< 9#j/HC:AYt@Z5iZDLE:@k4A4JFnVY/!RDbCMyRPS1Bak+cw=JuD1+a?V<!%QCX$cmLYZ*i*5y\18YnKt
$c4P1# 5\\d\nYqjJqP+Cj%*8KJDk+n?eI^nA&hjD#BqL>9E!wFMw&aqRWP&Xb!/QTFykmmB@y#E^+>FE#:8GkD
nb$c&P 8maZhVVqImubdEMPlA:qaF*QcDjbFZ\//9YTKdkY=/?:^yqBTTV=K>d<$!m>dLMcA!qahe=S:6<I4n4P
88Y+^p u^K<<+nRGJEh8FtkYQiL1uCapyuy!Iu5jK<yKRRLJmkG=H+aTcW6d@RQt%1t+98ekcZ5XMC^W1TwHY:l
*ISeDJ @N!WIY^9i*!CSAk4^/5m5BY+#J*Chp:AyPBTEnT^:AGQXnYY&a>NVd*Z+Kk!bPajWw+t=K:KbCZbGcBw
PKydyT A$%bbWL$HTHP=VDF$K&YXi5lp<CjH5KFW?wKSy+wDjA%eWHLbT$I^ewk4NY!@tK>nqnk*yRC>4TLcYLK
5\uX$F /!QJVq+*5QcDacP1Yu9?=K#XD8YW!IbhMl9VQ%^ydZeIXak+%S?R1NY6LKcj=ij\*kGKLRVRS56uAYQn
G!b\i= &<qN4qElBkQ&!H8=%FX9/Xlk1kIS\D&c/Dd5!uNTKRJGa5yD#hP1IdR1FCh&Jj1P$YwXi%Ly$E^#p?IW
<iq1@H YWQecZ>jF&%GqRlbGTNBTcV4h\H^VjJ?E=lmPCZ>tGlbnVKaw&AQ\m45uC?C%4hSP6d8=+h9miGBYmm5
A!Q6MJ SX>ibCWN/XFb$qiKHd#LdZE\mSm%FbwytbRnG=KQPykmbh<pVk%%cXHRXYNi$qBpGGa!\&tnyEAPLQp$
Nkl#V\ 8GFZ&uQBy=ayYlBP+a\Gk<AQBG+@Y:6?1\DL$ewH9E^JTE&<aMSwD94wu<!h*9thCJY?tF#h>1&/+C5l
Mc:G&b hkPV5ZP!aVHy&ue<l4I9@A*5YD8mTe*T54:/5:lS6!TQ44E&p\hnB%&+Ma%iD?Y!yFAA&PVS6p#p!mJ$
Q@c98t YSMQ=QBbdq5*BYQ%+y9<tqb9!/%>\4yBbkn+!>n9Pctc&b#Wki:HeMa@:pu\k&yHa\ldZ4Dd#J\c/Zl\
jT9&1X Y%QWQIP>WQn<lD>Xka#S@dQ==HMX&YbN/$t?mNSWl4TktyG>p6eCl@EPpPtn9Y*8$uhk8@DFFl5aV@>y
S#Ny91 Khip!:1+!89FYdFcV?Kl+dcWJ<a5pySJ&Q:*l6eDV&Y\A>@L$/<\wSPp#BB>L#/ETWCtu:qq%lJC8=Jm
9$?kqd qi\hGy>t#E\+Q6&AJ>SF6RkycAn\h8@%CBBh8=quPTpJHq<mS>n/llES+:485K8HI&c#nCbuc58?*Z5K
w!<pEh B:WTy>M%KEGkyqWV:wI6cRbVBR><^YK^NTu^EC##ku^Sj<&lT/>4Y:/J&yT+AcM4diyi1ZdY48HNkC=@
j\8$T9 GWmKS$kMB:WhkRtK1G:kC%#EN>Nq!QclFV$lKpF&h+$WFiV6+:+t+PI^:$b%b#5<yB56$@?\qKt15Gnc
^dwtm8 p#?!T?F+J&q\$yA+Nbd/FZS/Ipu$BuWJQtP!^aItTaaMK5tkGjyY4#R1@Aqh*=Wk9pa<HMmhp4X#CS6R
p#5=@F hiWa:RSltTBu6y%?GSHVmQYc\IXBD\PSK5:8TqT!GQXa!IBpKJ$S>K4:Cu?n#CZKd>VJT4X$@el#=jmJ
Rpw49w EX=mu&a6<#IdIuBP8%b?k^B4k:?9Sp!awKCnBWeb#pw&CiVqI#qSdn@+cj8NX$$R*Q+uGcTJWaFFuwQ%
MK>1=J jjZPk^>&l@/I?u*N4>L:&=m5L!C&Z:m<**/WLt@^RRIMZ*bCHjRK*k\$m&@?FP&:RYIA$964IyGNWc$:
@IVD?Q VaBMtDQ89%:at1%jm==EnuIMSq\j>n6<??w=GX\\WQ+<h>kkn6=EVk/^X&!w**Tq\YLVah<#u6=ji^SH
NX<d<u n1I9=SB#Gwqqd:e8%yK5*!d<I=4beNlu9:GTqjK^YcDYcEE1A94MlM&Xebp#C9%K46nEeEmYQ!w/RlTw
KmhkA= <!AE4y!+a=V5\N^kP1BtmWY<P^AH6IYnCTV:ESRLplb\R/ybJ6jbS1AVQ>qlRiyBNLCnlqwqX$T#?DhJ
%JVaeG hwM+tD=:a:mEB9Rlp?\FIu4!w>IITR1l>tMG!LV5I?#wM#n=KpV#I#MaWF@=dS:+:MDKB>D=qn8N:>Aa
Vu^J!e lSIGWT&<&n!\4!aPLKBa&uNV69PtncCyZPhANK1nFRGwYp$^SjB<yahKKZt@k5dHA4SMki8Yk$9t1\9w
8^nh$c JHMb<Dk&JpkE9dHtB?8PqMHP^*49V%9jt9MaBMHK^ERLKZXbtMdKmEBi=pwSp!!k?=:qGK<IKR&>6iTT
BVyau5 QRS:BG+PduAwTC&lY^hw5^K?Y6$u*11GF!@#mNtSD&wtbaC8FN>b\$5>*@alEP%@FmMACjdZjDI#4hkN
qlZ?hm &!5jTtX*lG4tZap+^wL<16R>i16%nFt&maaRbC?88iZ:I&m8kVF<WHE>L$CHt&^H!lT!%V&&cE1QD^@M
=<\K?A Wk*@Jm<nG=Nq%\dY8=n^ie?BV9++FkK5pHnHHn!ZJdpk8aLTe<1#LHDD1#:\Ye?el4Y:wekE8J8hMeyJ
uel?Y> TERaMkS4NDY^FAC^4/u:9MtqFL8/nPXXI&u^8lhCjybS8C/A8M?PV%/^K?=Ii?SpV6=H6<FERV/B:E^*
wS56^# 9uESG=4?>8n5NG9:TyR5#ueu#GLJPyDLd+V4S5IVHy54wcMjIuuZe*TpnTkkINqRn?$\#*AtJ?akc*Ht
>%Ey8Y DN1Lpc?TCWQl*CX5/%=+Z\:9eC:HIXqLqZ9DH!M:nGE\S5&miEB^pX>#laK5kGHlBq8^9i4Al&HZL4!\
&\FR>n 9Gw\9Z<u6T@Pb:<nE&Slp6h/P!=1uqhm9l*Anw459CP4YBAeM@qPpCy9pCZi4y6hEH&VDjG8@5qVNty%
+tcE1G tXlWtbA!PdqI*wR?^N1lh6lESCMyjtyLmkkSmu+ZSIt!JIADQ>\tG%14uGRyt>$=S#G!M*aeSE1M/yTc
w?T8tF \FuiwEA+:1lDJE!u=^kRhnmuYGe&Swh+lu\ql%*B:>8pbYB*811I%DQMcau@mbd5BHtS/!KVdTbjPmkY
PLb1aA \=I5*1tbiMbeBkYBDSYFm9w%qaw6I/YQ<AYdmQQaapukhC=le4@FEc$$G^bZ6qmXCR51G@RcIW5LcjAP
Cn1=aC %T!EQ8BT$SaeC$$Hb1&A/n=IW=SKB!8mI8b>b\jI#XB<widR:\hb$MKQpj>WSNnLltlwJuHpnmRi=Fw^
=M&R&q YTt#DmPJwkq4X/#Z:T/Jd1$^B*=$jyLB68&6HnjSRI5yl:I6cH>lc%H!Lt8ILWBTS\%GI+Ryk11M:dLI
/\5+p4 9DBjFc6Nk4XY8%=!#t#?biSLLR8InPm8D9pQdduQ&hS1Tu*>BLEJ&9ZFkJPEF:tT1LlbR1:Vmqn\pX6w
jkSDTh 8puKWhZEN*tL85419ZXMX<Qu<6M#*+L6Dt9p\R/E>+nZilKT>^MW@H&Kh\GVMBKT\Q4wn5y^H8bAA!4j
F6AA$t u#G*qJbL>:N?S6$<dA4nSDH91cpK\6tK#SnBnTiw@Dl$jqt%mun!=qickPHZ=yXdR1aVIE^!YNelVVeF
P#wFAB >nu\#=l<p@46?8J4X%XtwH!Kkyw>@pajCNC66W&BpC5A\m%Y/leEWNDeB!=!meFy8?ALGk!F=<&pTeQy
&96Pj# \*E?4@>8JEXnn*$RlaP6lnmue=Za$jC=n@1%4tI=P<yPBCXIVt$S=ySWEdedja6+qiTB9jX@q6u?h?!6
hwQ+:e F&j>R=dn?Li%V5l@X$Dp@Fe*TVDHw>$p@/wC@LP?\Q+dWRjC@emN>tB&%5ikPS=Ck^?Bb8h<RI=mb*5M
<Y/8X/ t9$BGa+h<lk$?KGY5#<CDZuAB^QM#9EaNPRlNPen$G\Q?EGC&dpik?b+CM*>GQRDDy=kn5h\nR*<RL<=
AIeD#I YQ<6>GP+>4AE!QEa5uG!QFDR!kF=%Aq@RALpaQ?*n9$w5n%$pZF\@q56@&ej#L>m@%Q^<1?%8*<TL:p+
jDCS4* j!Nie9#GB^QC^54>j$$lL^+dVwy$aJERukt19>^iS%F4EbTDcMnpD?tWp#:b9%ACZ^S=m8VZj/#q&DEq
@lX8^P TBw*cLIPa>iF?SKV1QT$JdZyV&K1/ti*E?MKVHV^nMt<aE&tRB\#kl@=VknekW4Wq\11EWW5%ikl&J%b
#<yyYW &:&KY^P=K*hSinZ+jH5uPLYwRK\b@CBa*\FIldZ@Cu+\DHS8yNc&!C1tVD4LGK&^cMNqQ4m1!iAHNi1j
:lb*pM #DBn:TyK>&dW/Slm<SXJkiV+<+kI&W&KuAmpHay5=c\V$G/J:pB@HHlMllkE!hMiq#@&uT6HIeBXjTGQ
Hn%Skt <yNBI+@KyX5bbjNX6mA5PBcSAkyKdp+RBJQG/lAYHuk^EiVch?CW$DAT?6NBXXcMKSDI5tbK!\%hhklL
A51?&/ I<+/n9LI55L\Gy$*d5ZG15NHGIcP*BY:GYX>wS\%D6A8uQKApWJ+cbt#Bh+bWnH^Bwp\EpWicTjw48#$
LdB==/ eQwC1$T>M@WL<Xt?&G/tGpkkD#yY1qtjyAn?F+%F%*^I5+VT?5!Rqt#kC\4$DSbqkywp/V5e%e:IJ@Th
dmTMc8 iGTH/wQkDHI+IhmkFS^YyREqSEb4c/wBaY8%bE#RTAc=C\LY/Lt4VLb5J1a&1Vk!J5ka9i&FX6^6pC8R
5WMJn= 95pWuqWwMklXqk=%=m6LA8W#9I>QVPVLYm@1B?p:LycPYkLl=Mwhq#86Fq$$4X6ttqS^D6@R1ciFV1j1
:BkML> VC+IbbTubSJ*hlICPTtE4uSq&:ZX%e!LYQ&5TSZNAwkRB!\^^h?>q\+wm/1$hp*EH:Ky@tTFcejnIPSb
=>nLk> qjKB?w$b=/FTkaY%:#SD=WnYjmGV66HQ9KD=XCl>lWNWA4!Dq^\jbKhF*4yppEl95MLSRaKdtNqR#PPh
/SJ?4P RY5>DA5ydJccXKqK&ZX%Ye9T4jQ!taTC%+!%tt@#q@VN+M:F%*1F\b1pFtaNnkL<Ge&hiDZ:PS8iS+Y:
?Gc4Re /6dHyT&iMPLPZwG+lG5K*\q>:PY?9+*X*9*=$bwE4N9RyATH1K/:>WP96PAC4*@aNdqhKD%Vi6!%m*!L
tqT5j1 1!\hhh4GpwRhj*/mQeJ/Sk%$kh<?:+SM?EHKDEMh49JTR#<mpEmZ8RC&W1LLaQJ<\iwEaVbdEYe@McDG
h!F=<6 DiF\mb#pe:ii6C%4lP<HF5Du#klnbKP515EK*BN6*J\mCYTlN:V=Qhy++H*Q:Da><6X8ZA$/FhXT=M%W
JD4qZH n6YQ5&@Z\k/$$PuXHN1\iNpnqLJj5/1JA?M8nCPAc6Z<cu4ZcCZLSyYp=SL%GZXEN4#kCK%uLLMN*/YM
wwIlNP WcY\aIu!1VZSQut?akB/JJH=b<nFBhR#KSc\B*NAVJ@TJpwPjPiScyyEWIW6iVt?J<#cW$k5$9IhDCVW
cna#Fh VAt!MSpP=A=$bGtEw?/4iAjYaw*4Ji^SXMVjk4RJnS=y!tL6M%ISF?6aT&M&NucXGT&j1XB&1ZjZ*:QA
:HH/lQ jWk\N@DuTSMVN/H1tdK5JVRbFZ>GJyV^JWtqSXePE%1JX9a%>b\Ayd8w##DHJBeB^H:hNhMNyIkHtA!k
=mhQY: !yBh/iAEwE+^S55PQTXdHW<cte+Jd>cw\HYQVmIenm+T><=?Gl\u+>Yw+&IZRSE8Qn$S>e#cRn^=ttTZ
p%YH9Y YSd&W=!WhBRqD:&$Qkua\CAjPW><m>VT?ytZ>WBL8!k&T+uKV$9IGk4ZN8^u=bauB5NM8T#^1&m$t>yl
NMwMqd TcaZEwVFIHY66FC/!!=Iim==6m8!ci^kWp=<=uAP9+Tt+bn!RNHutJRTajV5aP?5$C6<+@m&!9QuZYXe
A<hkSP V*G$e:HX^?SM?^9wTTnP!uYK!Gntb%#/NY=K>JSa*XY@y%uR^V>J1WRaqWYEW$#*SA=>5w4Dp8m!aiK^
:GJNAH Jb8*!%H\%4M@89pDa6bIJ6H$WXnw/RkNE6eP4pw?bWJip8Dqy/Wk$aK9!!djY9ccmjk+C4:Gm?WKITIQ
-AkF5? 000cae551eb00110333 Page 389 of binaries1.zip
T@p$1S /hE5tMDJ68ZFZl<Gh?\X+ea=%e9/ykYcDHkMV8KL=C9j+qH^Th8FP%A$m9FTS&RMadT<mVj@qEJA@RM/
kT^N$J LMqF*bFFt51hTcmNLT^NJji896iaeVal\d4Ek%IIH6hVc%*JkPbH$?j6QJNuTy:Mhu:qdPw>864SL^##
&P6cI& m#wMP^S^V1LJZTu#Bw^j&X1d9hZypT@CSFD<FQGFVR1W*V^TE9ptVC%iqqGehM!\?du4mD8ZdGSWXEC!
Sd5tCp dP/PNJGyYCyuu6H15/i>qkY1&QTTX^Ky#5<NQM#jR%=eEwpRtAHhmn<k^\NyaSj>iWA\&%WjVF^1HQ%F
1WuhE% JKLiXFkpeibhPEd1&K=H69dbBYyn%hlm?ZKJJ41eG^9*>*itIV/F4>FlF\FKY?#LCL<&tLy<9V&y^T!?
L1?D@n &*eJu1@B%uS<etJq/4WH=&5cGqTTaH#IwD5dy^bVAF4cXa%S?<y1?hJ#E#\Q*=$KW&HEFcIQ*uaqFX+W
4ahp9P VVZ6nI15wnQHma%&nA4>RTI/yJ$4wmbitj4nbFcTyZYjWu\!i+X#^11S>k8?aaFMmqpFq:$M4R^l*4DH
ALu@tc M*5tDBuuHEupa6ptF4\FuRVn9TY8u^/P+5Y%JbV%u:>j=/1RhC5qm\t<?@uBA/uRYhpJ>Nt%S9S?MA1k
l=uSb@ RS*J#nBc1aGZ#tR\=cZZAEa@<\hMHB8Qk!P6ww4ZEw5YWk9F:YN*i!9\E==?Tc:^q1FKh!&6Y?aJ@Gq?
ieC!Bc 1hyP?#EWqa\epk1V*jQ@a??9+/IK>H%9uJ1lbwb8SLyntBqT\KEdlt/p8%6Fyd8:XL1:BATq8^6ESLyd
DE!@C* SEV>:d*Q&j5=b&?>^*6<u6?>#*$>L@>S>L*YG9k8eD/j#@y<*\ktYPN*&P!bJFc@EbaaTG>^AmjGCQu/
PGGi4$ 9JP9b*9!ZBW$KQ4R+WFqne*BF%t*6!?G*Y&ZJS/kFd#/QL:jN1Iy=ZtHA:8cbw?bNIkQKb6%9:?yTKmX
!5!dkQ GPj=>Geew+Tal=F>:hISXupMnbQ&1w5IYhqAanPWmWj<?#GEl?EDYMH*IyNTYRL$&M%$CNq<EudGA>KB
IVwyq^ R^<ZEc&q!KDI?NXZ*nZNS8/ciyuj:NWR+NL$DqHLX%aGmAi>W&=k@uh5wSKd4CtZ*EBNVbZyTSp4jN+W
QyJ$ub &\k/YXp$a/ea*#LlXFX1d?TyZuWqDCTLQl\uj=k^ku$wcT5qJaitX&ua5W98LT?MBju8JueX!bL&pKX@
XS&ZQ/ 1nKtL*jSG\Z>!nKDNSA!MKpJAMt+<D:HBPpP1q4%5nl+!/%iayXPFY>kt/*51KQ!/M$th5!Aa:M?qW1<
ND/?W@ lSu<PKkH/tlK>G9LiNMKt\G&%Tt??a69AN>B1yTTS&4L5hCFMWMZcZ4RchnWDmM9hFISu*Bk9NKZAM*b
@mh5eV G1E>>Pbnd=#SPHWpX6\$^nwY&9AMYBwW9puAw#S9Y#uHI@y+e9%hdBpAekZktm#m9+8heAIEX=/CJb#L
j8^?q? JTE<WL=mmeV>#TTH*VcZEF%HhwMEey=wnFS:SRL4jlD>hyPnSed?iV=:y$YFBkD9QB!TMqX6<adVb&AR
J:??@M 1KY$ZFwYww%hdyF4QJYdeCDHccpMKuEp6^*IyN41l=l>wJ=/w/DpFS=4ycZkWdI6aY^&DPITnC\Ty!9G
naGTXb MXGqByij4^aTpij8+W/b?9DqJDtY!mFHMP\!>meNjhpibah:kI:cSkD4@G1ejQu:jYywccQGV>mIc^!d
/k$<E< 5hZX4GSYPD46JA=9pq!%\>#K=XT5kJYM><^RPF#NnM4aJQ&ZD9c=?^=8##6*a>j*d!Lt#VtEH@CbK8?9
ec+aZu :!TkYbe+5y^dTNG@+HYIG!l&!%DMHT6/qK5wyRkW9hB$iFuA#1mcp:^9uDF$CXFekTlte=WPq8^!J=+4
pRKVq6 cFn1Yl%PX<hu$1?QeR^eM=6yeLKqKFY>y!u6Val/Gl/\8=daZq=l?I1?qP*kqG964#&pGpk:>5N4V9Ye
F/a/Zm 5F\WjqAnHIAFL=BAMN$kRmT\MHd@Yn@KXC8F6T4ea<YAcaeAPkmSKCA/dTVRnP<X/A6LCT+qG*IYYIlk
ppR>q: y1l6V8Ml+\S#pZ>6IFXP+#6F$X5E+iam<e*c&PpHBZNhYlkFiaQ+tdepGQDD:&tyIB4c\WGEiJdhaw::
bCD%VM d$+<9phj5T9j$F5iZ1>L^SFe!VSAPiP@e/EK1\9S$aJG&\dyeXpWJGE!T!GJcKN$$=*:FpRpdKTW8qWi
=J<>QZ @G1d1S4TwMtEpt$*TQt!@JnHXMJNM$5F=HT^ZBp6A#pCImBjuDR8Dl?$+hGRVcFZPQIQJ1Z$e&ZAn%YL
W&N?EH ea/b4*&LhqT>nXyjGH9N:N^9FVQKS1!JJD:pa4hLb4ctHZG!*^KAJn4j1iZiW:mKan?l&P&M+q?NpyXF
T@nkEZ %kZE&\iaKF\tc5Vy4pui:jQumVyQkBVHFSJt+yJS+lKwSlM&Y1<8y%#H^uHGYnjZXT^ST&NVB^*eIZKt
6Y\Jb: RiCEc&>i:lN!V#1hI?Tyi4*=&a?duhPMYYaV<G$5/y=?&B$P<iI$>y1m4H8S1lFkqqL5pym6thJ:=wLe
6BJDTa C>>Tm$hYKk5u!qFHPwR4%cXF\auBb^+tP5:$mCX>kGHa:1=PcbIm$cq8$S!6EtnHB5YXkHZ@W/X%j?Fl
>^XQwT ^jaF^5%Nu^Gnc61^dD?w1Xtuq%JiywEP5dbH&BLH:JhXA+*pmDAJGLjBLW<FuuGG/n1GQ*Ka!nnRPTNj
aARmGa *<D\hwm%V41bY:jw9n$5#aER?ch8Z@PmjVTHJ1y+jJe<dnDKZ*M9mY5d>H1nWD>:^hp>ayEec$/9!Jk$
#j96q/ YWCj*<THW@>R==$pd69D/tS=huZ#G8R=u>TbYdhdiByQ1iCDa:E+uL65PyA46m4N>i&w!YNjb^N:Rci$
yF*M6W T\@#9aBAHn9hwp1%cE%hu#DiZue:n6icdy<ki&&t%XIjhlpeh!E\+BP:wWFiu@yHnDPPeiK$Qw?hh&=<
laCN8d K<\ilcd4lh%^6P*9kbLhbci\I*KLFe!#>!:B*h>8W#wmN%8FVLZy%DuEht+&+iFeD8qaaS!w5F?BT<eV
W4/WCu tWMk*tuBESV<@Mq$8bIG&ByiY#ItKt8^%m<eNRJm9F>1l#4XlwbE&MjKS*S=jNI$>u4Q#@+iYTG8K/nh
<pTkW+ SeGAB#Qpu8VHQJZRTll<!S$Eu8VCRb/:IKmQ*RL$KnM!CA%IhcEy+cGQdX4eh8>I#y1h$d@HQJF#HlhV
mSR$b6 m5u\m58RSB6DB$=?/\@bn%q%DI94Gi^*J!AiJwVcVN=*aR%FS%8bC#9qLhH8PT^*Xc*9&1!Hyap6%bqa
Q@GQdD i>e>LBam><J=KPP@PV<LhNLjawj+?$\iEn=RGlTMlD^*KWj/CpaHEd=/pn1Cd#aR!wh<Jy<XJ@\WkGca
$4\uM= 1EBmQ#Ai/YnqtC1w9=QWp8n5/C4nGG1*XKaVCdk5HImSu%<h\A*\hbCMu4eInaBBka!QT>/CT=/EF>9y
ml4PlT :kWe/u8c/P/j:TC&&XJneVX$^uiWWc?mjYuwLX+>#HXGEwnIe66hAKdR6!>\4Q#DlSt<t=tM=qt5Ky6N
TMW9iD dB?/NK*!b=S1/W!:KD=%^NWhZlIDDZ=Rc!:ewne!DS@qSVNKWbYthXA%Zl5GFWeD6PX+CZj>Y\p5NlNA
IBwEG6 4:b4=<qjHFH/X?Yq>n:XCqe&iZk@Ze@I#Q8Ne&qXJtEPjCaB\TS*nTHIJMMdS?I4aCEPk\iIwbEJMnpL
iPV>Kd bqdTt:q<j6k5:Qpp8?eN8qdwjebR+bqEETtATQAXN@JEFE%TXK6MhKbPVE:54!&$M>&IbR!tNWt^VnJ^
/TGE<I NFI^KYL+^j4*ZqFw5L>MtBkV\beZYPimG6bwW1MP?4cT&MBZPCbb!F@J+WL@?%ZN\wV+@=5K8LDI9!4k
NF%nF$ \5K@waBL84m+i9%dmqla+N?n\5L@CNV?8$D?:$4VQ&6aQ%tk<@i<<Y<$Zj^pke=Q/F<$p<J?5pDuZ&pB
J<jwM^ +X@SA4>D\*?l@Q%pj<=QcQ=j!P5@&b@#E@1Z4%9+N&nE4>KiRmK@R<N?wXpKR*?Hl9:mhR9#@\aNF@#F
G8TG%/ qR9@#1#>516C?HhtDTd!C$6D?Hht:heC?V@XHq6:i9&6&lRP@^hnR9AjB@n*i@>9h?hj@1VqdiH%6\?w
F9BQNA &L5+@8*Y6@#dRiACj:qDlQ<!c*B/\d>dY1+iX6aij@qL/N>?@e9FCQ+@hVF@?i\JmAnT@:ZB=1@Z>D9Z
Y<\eQ: I9VQG4nRj%*b?w@M:6<$eJGjciD@5c*=H^w+kl@/@\X+j:8!hid@@5yYp5=A+dEpbKiIR4hHaNl?t\5N
#%hF?V 5LTu8K88Rw8?n#?\Aa%VDKuF!6b^/1bJA<Cp=cRGaHLj\\m6a>@DC$hHVuGM\DcXEKHe6^1e!98kBpJb
C^:@CB WI@C?H*mEiFSbZT$NYmubE!h+HD\wCV@eDAISI4RepNCR+kd9?HC#uM@T5J4nd=VnnIlPL?nTEkHaTGa
cPEm%m *P8WnTqihil\A8T=5QJq:?1X&8Zn4\n+l6YMZ5?W+^iqWFKw%cZ8cJ?nWRmbW\@@8PaaRGCEmehTdD=R
Nd*+&n NwQ\@wW*m4KDyGCJS##=<IJTRK$<wGLl+%@dXbPp&!tBB=dNl!9unt!CaTw#*<i\MP?6n1HtXTdJG%Ny
!&/&c= eY/WKa+WPS91e\h++MSFJI?tREhuRRDMwwwI@Ycbk#At>dYB/Ab>e1=I%Y9uI9bNn\QE%AQMJ+lSTd>S
F+dDqA MGBEqS==#\yhNtkcW8NjK@lSlFiW<MES1+GcLbVh?8Y8!QlnMc9Du1XHFw?M1RK5lj5=T1c8H\9p:#Qp
:tEY4q WD!BW%j?TLLWjjiB$%/#6+y*PL%FR^9?L96iu4pl#l=GE\XPKbqCaEnM$i8<EP:Vh5>*5uwcmFVe%#wC
eqYnT$ S\S>w+JduyYGKZFH<n&*jRY1+mTCE*48u#D9eWMtT&$XXPec:4>wMARYGYMSqnA>@iV9?EXDJh9@\BXA
hYV^lL buJ9^Elu=jZW1GD%p6yqe&#NbB^tch?C\<jw?%4*a^G9t<TDS?@nc?W5bB6>PXu:iL+541S5i9%+$\Lk
kSBLCR iw5u!@R/^5#&!/w1?:Ba/JLWa1m/%PB>%!QbCl6c/>GdhQl^bHKDdI:hFC^YjCjQIjMV/:cp@W56BTLB
l1FpR/ #M9?MZV$XNl&An5ZKZpY@d%=SC*@SX8J98*CVIX/hhZV^kHGH!ab>DmVPtN66enD6F/?<C1e:*!jnKMI
$S+?8! Dd=LFV>^jE*J8lt@epe!6l<LPjPFkFH16Y5l\@X#uZt=D*p^eF+GNqcYe95:>jWYpa*VHD/YlHiMZRDw
H%ER5Z e<J%AMNSdXl%CK9BaLiP!>8Jh>GT=qZbiXyLXE8V*uGk%LtPV&j$cZcmD>#6Q?jp=/5wB<AFT=mdiVQc
GEKttP LVYNRtI$EwbC?@bBw&*t8CWh<#LpL@b:QJ\nGA1FBGYW<4eWd$Qp#PeG6t:#LWAl*6!b!t&%m#Q9KyCI
4$Q\y+ GH:A5E$/4=qXu\PQ\Yhi5lD<\1p+a:NYn?1H+yTJii>k>phQYPRwy$iuF:H^A\wy6Rm%I&HdMhd<Zt1L
W@T+F/ QXVw$6@\Ap5@pljcGTZWC#&jBh#Jl6YDA?9eBV?m>ptV$4S5QwaL<yJP<P=k9Na$*<B^yJ@I>!6@p+#*
YL/4HM R^XbBG%YIL@D9t+6XTtcmBF\YWy\p=qpS^bZP8Vnu>#/5ml9ZE1#FnZPYN:qjbqACy^6I8@W5JP#4u*F
bL>:S5 XPlt\8plJ6>uSc&a$TX6/$*CH%$j4Zn?pkNhClhRK69a=Kp\@1::6WQZF1c5NGKBbNDTdBTR\pdiG=JX
GpLW%F =PA<B1^jEM^@d5TRYeW>6FVZ9:lRIeBdP&YT^FH5@CDdQpZ<8FyC\HKHD%*KF*uFW6CSc@PP5kly4dJQ
!8*\Wj NCD+SMMRHG&a8kTwdX+\#Y1Bi>5@<hidYb$KSLMRQ=^iYG!YFdC%#<mPTuLqLcClyHlmBuKi>nS/^Y^D
-AK=Qk 0005c1ca80200110333 Page 390 of binaries1.zip
QIFVWm k8NqGeF#L=lJIZ!T^etD&@lTaNC@n?aSm>qR1HCDa:1Dm$iacynZyRqCJSMhw$6FKLc%YiupeX1:Zt9+
R>GqZd 1el446:HM?D#^wCt+bY%LRcnwITMRiyZT/LSn+9/Jl$+S5ed:Baip%:wh!!p^y6$wtl=9ben8ClA*JHy
Qa^Mhb uyY^H#WZLTF<!8<a59GitS?H?h#HSthddVLJD!iP/Vimjb<S+A18HJI9K8^8It6aW#81#<XpLp6Ctdk%
6K:hW@ kcTb^G!1uLp<eqRip8eni#ZTTZB<t?^NlIwydpDX*^S+TG/KTcmE6blw=586a1=VR>KqXSmM<&EtN<<Q
6>k6#< :5iXL<W@a>AWaX>yDywT9jGHGBFLFTZmWJpj1kIh$19pJVH&G6EARQ&^8<JB##>KJIb/w=?1?AVe:N<:
NHwJ@j KbMuL==p>pT?1L5:5iYZnMt&w\9SYL\*FZ5n4MP9n>hi^pcj!>B:iYQd\&:iy5ShaDR#mpha!BpaQ5ay
\K>@J> *$9S^D*K1+w:J>QYwI4^Z9^?!akiwEV*WhD:6MGqjS=Te*qGHM\MN%C=/HNLACKN!&dN:#D&\ee$$XKT
wHZ=FW kkyq6S*u1mZQ#18Sk%Xc<4::m=>mqc!:kb&nTa1#Ec1j>yat=YPwyIPpHk6!W&qmF^BT*T^F:Mu\Kl96
RZtQ/t XdA+*^R6*V9RKY8u11hme!b5!==i<p*bD+%5icnQVwADBk4MCa&Le8y4&#nKmlI8$!\hiY&dAER>i86K
F*ltX9 +858$=6jqq?tMV+CC#LbW4F\i>QT%Rq?WAwhNYJ$+*&tmhiG^MaP?1m/!9QTSh#pSj#&c=dwqV9#BAJ?
WZJkB* @BK+LLMWV%&>L>9$SQed:MPVc*W^V@WiN#VkZ5V/JRkei#4SCLQ6CH%c*ptSj@lkHpP%Nl/yp@V\!iIu
GLSlW8 9MkD!twb8KJ>M@A&cZ?tKQiD:im$kSFLKPZ^P%>&*>yc<c8dAwe:X%ib$FuHn@KX^L/D6=?Zm6ZNMeYH
:SWPel Zah8!&B?4>LV9qe+ZiZ$nyq/jw=I/1j9eDa/?<b$Zj!1+8DL5:k%/9ZW:hj=t!*QX@tNw&NM!#6B>N5R
8TGT1n /?Pt/8puIen>mHKjY5lP/SQ$*6XAq@:S8NE9\?ywqbZKAIRKM>cH/1Bhi1SnCQqtbiQZCQIT*ud4TPCM
K\AYin A8W1m+6id:j#<Ry<=&bMcuw8!IJbpb6bCaTFm&AdJwR!AjM&RBNS:CqeMY:DuZm^&/&hp?DBGG?HVZBI
/4kMlQ m<bcBIDLD\:WnGAFIRBBV!!aC$ck55lmc@D&iRlY!CE6JJVhAS#Xb%ZakB8AAFm5wcbdh#1dk=GGJjQk
F4B8Yt HqukeJyeij:ey5?+%Cj5Vljt$i>=pe5LnIW@16A8+\SnCp*N6lGPl+Q8n6i:9MdmEF8$W?mi=SeAIRFA
F/48PX n4DTWeY8V+l$QIlSLYnp6Am#TL64WtGQTJKeEBcFQ=np<lyRT/!:%u<+bZW\8RTImBFQXIG+nJFXi>$R
naa:kC 8KP:KXKc4WItIRh%GX/<a!S1\bS&XPV>GqmJK6>L&!b=L^j5Py?^kmE5>eER1^upyHqESmi?Yb4c!1bM
>WWSbq bZB@MB:SCRHtEq/pujX8cRMYFu\*wKAayXM\Cabiy+Ea%T1<XQ6+Z^j\T449N8Q##w<JBlH#1nDVI*AD
eNS=&% *p$/#KFeZ1=dAK8MicN\wITQ69MqBK6eeT#^J8^Zj?^DVddtC:DQeYB$kb\S>l5T4k+8>ZLD:#mqw54>
<h&=Ll dQa6Pl*C9lT59pe%Eb#LE9Ia!49nRIqA4J5RBW%Va\*c@DNG6%G@b@V%nWY<TyEJ%e!eD=Ja5>^4Nhk+
<hVLZ@ +&%R/SQB?JA*T8GNq4llV#!GG&Q!yW5Ddk4dLLl^@PFA\<y+/IDkZyTaMp+MI8BT1qIh!p=JACiEFN=a
#*85Xc PF<65^!t\*pS^R1Qh=@\u6n<hc$S4we1iI1H4d#!jQhBDaGA4JPp&:JDL<15jwF9e*WMZG<%%h8@*?#t
?VGNb& GPN&?AltNt4IX8w^+I*wja<I8S+Nh:P!N9aaELWbTQG$j9QBdB:WwBC?njLBX&VdRSl!T>+6eyqKP8<:
?wW$PY B8*&4lnC!\&Tp$XLJKElyX+NKckmTAS&K/tV8YmJ9*l!^*&At$FwLFVh\XN?YF$?WLVwWu9*yemStnJJ
<M<GVR Wu>yG<#YY!S+F+tkSq$CQRdh8weV%uqF?V96FF&SdlP*J+Vw\tawHP:B\?Se4iqLLbjS9c4dB+RMYKA5
WRbRdl Tdi*>\jy:RnFhNibi^ZYbTCnkatmHyB9kDXNy$%qLLRV>M4t%!e?@YDlA=9ek#wqLbh8L/kRGij*&$bi
:R%nBI m#1Z$E+pYKN?D+eKVWbTqYtQ\mN5e$eKjPumu>L>9b4^l?#w<R/ijHtuN>QXN1pJS1&pkm!>VGPWZwK=
iw?I1i ImGn#G\<JV5>^CXlEEY/4LawFYi1bdcq:NJBRY1u$p8lPW$<tpAQmFGR1iQVMEMiFIHWQ=FwVY1yilPy
hFMKtW %1p%i$X$CFnL#91eP5q4amHBb?HwcnJ&MWMWbCcpWJYp5N9?jR=mT#dbPh%B#Mqc*yXVBT1!ZiQdKb5I
A?6HZB jphNq$wAAHG1Ehea$\wM*u&Aqm!kb159d$9L$/M@HT+:8*a@+ESJkEI@65iW%%!l?5ZlqJ84%*ck%&8$
it/tHh T^M5eQeitd1G\I\^d\KnuIRc^JXmZ&+d%cN*9Q4p4N@EM?AEK/WT^*C\pR5yn@CLMhhZpt5EXj9LT6^9
Wm!kbN iw\ejCq=RKucl$ndwt^pj/F=mKG:q^A=&mKiI61Mq1SX\YmIaHRanKYQGaTRqQ5*Ak6G=nXW?Bm^P8?H
Eu4wcl B*l$hn<KLiA@R&tVA6&QWn!XtS!KZB/F\*St%4FI&D&%8EhVNj6JZ6ydE\k%BJp!DVl+*F1V9DCE9*ie
EAwBSY =bR81dPFX@1pSXu6yF9nnt1#!GqZD94lN>/*NuBky*MA&D4Bl=Yh8@@!%5Q6tBmbn8GS/Gp#@EMkVqZS
P+:nXq <>IBt@5^Tc?qmyyM!ZDk=u=kdL+!BW1byeSye\ZTPQ&a=K5R4+j1LGMbPb@M>F6b6uQ\tV5Y$HkuhR?L
u&8?*9 HFP&hp\BC^pPPMZFFnC+9J*YCR8hK<K1jwK%Y&EPwFK8N1hJ=>JXwHyWLY?5NmLjnQQBZeXmul%?>tkF
1HAZaZ TtA/>6q54ItE%&5F+T>P>yKCTJdGc^?e&/PqacR9i>eE\YKk%Q#W\+q@cq#MSwS?wFpD9^Hw*GY%?X4B
ctI!$L JihB\XX%d=p^N%JjYiX<#nM+4CTIYVX+^mjRD:X4bqln>jw86k8<d5/R?$+wQtQ>Fq%>XjXBCFldaB=i
4teQG= %h+%\um&p/Vqm9tEn@9Lww#=\S8HAYete4II%Y>1LL9iNwm?c^tZpB+Tba?tW=p4+YI9abXP=^cL\^tL
^tPA>: tTi$W<Q<VStqLeAbna!$W^yXq&CDM%Y$c@VR5&*\AbQ58DqbcKTPuk\p%Rn651%i+H5#Sb4GJ$?#6Mlu
k@FSNb ID8HTh^u*lTtIc#%WNT8IFD*PFGjdNCTdL^Yi$1b\%Z^<=qmWcTt$LuDRNNnF#5+TtEyk*n>*KFq8L\T
XL=bT\ *\5SCty1GwGQaAYGQXK4SA=8*<>w<4K8jD1apl^h5D6c+9QyeQC&B:H=^cw$uwIyLV<\=8p:L!<>qZJG
!RlYW< FI=E9LjXCWM$i!+m+XNtb8=Z<wL$1m<T@Sa49Ca<M8RnF>WPT::Q<*XLM\>RXZ*!y<LDld8D&%$9kiK1
EjbYG< /9VD#Y9Jc?cB$VFQ>#5%aH/lCwHSGtJSySJShyYkLY!BA6=9QJ6^hRtSu4n==iwFt49FPPXln+VDSEWK
8P<Z:^ I@LEayk@>q:a*1n1K^DwC*cXQEJFFA:qH$1Eb^qHKap#buqEKjnbG=!E^etLRYR5\:8uquQ$?p9Rji&<
tQ5am! h=tj&DqEDhcHS^S?L>Bu\Ql=KjS@Zu4%@@hT/Q?<Ni6@RppZ?atTLmL<&%q!pb>L=V>b\@Z*Sw:@YAn^
beNSjk C@u!J&8+@yWY?JZR@yM%ZD?lj*q8^G@R9^a@j:KH/!e9@FhLuZ/!l?6j/X<thEZ?SX<Wkj:Z?8Lja:X@
>YRl*b %SjlWJGj/I5mQ>MZwZ<=&@<^GX8B@<$!69abMZ<N\T4EX!4qR%h##X>Z9/@d:Z=S?4i8&\1i^VJ$Lu!M
aYwHqp 1:4KQGV@WBitu^aY8CBAp/b/1wiKHtKZ$C$pd=/BI8S%6NmmX<Sqhtdk@im\KDdkJ9PEHlKV#eAYCpIb
KA\HAZ $YNlRnXyAaRY</Vk^JZuh+e<uGcEAMR^1c^<I&dhR&QEW4QDYJmk6y%R#MI88uFTGka^9p98hqJ=qFRF
bu**kS qF<!J1CH6+C&p%BX&Y\*E8K%m^JZRdhpR+K$lQ?c8\$qa^uB%$/>k$w%5=V6@=lCJF/X*Lk?Bp>Wnnla
n@+IZY pB!Fe8JE*VSt!%:y8FInQZKt:1l@SC:*l^JhSNPQ+ce&9\unL8yC\4\8kMNkhBWtX%=mc&4E^C\#?V&w
B9iIJp B>aeNK=l$dB64DFqqL\iW&HJl/j8QV4N51@aAi@!1^tmP?M6#L%WWpIiT*=a^EjhyCbeq&@9XPeB1y6+
qAcw\n TcQbSXeFjED>Su+98D^CKjLu/K%t4QYyXMp:&l4j6*khiK5In?6=9Z?+Gb!=FS&1FRDAHM$$?&9k%Sc+
un1cV? j=TKbwkQ*bHe4Gm:/qiqI4N4aWuX=ct%9hAj1IEq>R9hXTWX$FE/9Ji4IV+*5:#HM1aTp6@ytLG=&?wp
qaPFeH XPT6AQP$<ltEVwbYhRQRQhu8Sh?:w*hu9YtEw>&bG/*ucV&?t*ZTGRP&VA5p?PqTw>QG$^@#Zq?SA@*h
iLEJZ^ +k<aT4y#ha65tZ#5!CnLll<N&WZShtykT6L^*XFcHcXqtwISbqk11lpntBVP6E#+B<dS$W+$IPp1SSy/
tn?#kX 5%cjHwA@Qd$ZY!&b#T/CE4n5k@uD%Hud85=NupAhu!A/Q!XS?dk1=kttFZPl$ZX@++q*Eu#dP%#?w5j$
1YXK!< WiVY/#iw:k5TZH5FQI$:^VL56TdLHN\Apay:F><XyAy/8EelaDkJeH!G&kpLZ+PD:>N!C:Ht1kLPi?Y$
R4&Q@w bQyW!Tk:!RnbYQyRC%ATbyIDG96=ZyJZ%iVHG*1#ija5LS?\11K+kP$/EY%*kGhewI/wPkc#qNd*PZMq
FbEmS% Ad!Ey4@<R&Tk8YPjaVEuk>VpNuWZt4Wmdq=ViGynP1EX9:#mFZpy/dKJ6BmQaTR/b/aMyaut9yJqGdyn
hMc>qj d:%hGIGI1QT8X==mw%VE+KIA5NCM/9W5K11AiF^@6:P!w4kiD+Q#Hm@8F\/8hEiCLMh??jG<DNamt^S6
A+kjLn hA>iWE!#<19/!1YkPqYZ!Ap1^CCN$dT^9=!tPa@F>I5WGw1uk??=lL^9um<F&hnEw6e\WEX54VFhkZl\
*y9LE5 =R1KVR8pe=wDqE&mMMLTmwyFap\cYDdW>maVdE9yNa8/^A6#>^Cc?y//eikb1wLHh&nEP6%Bd%m/KhX^
&AAR?G VhEhW<>=Zlbhu&in9HmMlyXe^AXQBHd*qTFFX?C!RhPCpy/pkCF8414R/jSy1imI*Y%I?c9S>#$BdwXk
>$Duu< kV^yclhn?^5lJY&*%$Z5kRKeP5CE!4lp91I^Ce4DV/AKE\=&h5Nk@FCN:L+P+T:pQJZ$eLG1%/*aXPj?
!Buu66 MRPtXwkC?8y\h&hE$iN*inN>uEDC=ZJdJWe6=:aZ>PG95Cw+#$9K#/R/lSnXYH4Y\@t<6^kwEwJM+Sh1
\jX&n9 un\S+m#MGYRZnk1/SE/q1VIHL^5J#Npbi&GIqK5%LX?NPCny&%C/H=TBPkwu!!Dk/V6puuNe:qXb4&F9
ReWIiZ 1DF%4EhMQC=%Wb8cEde$6cJ=B%!Ran<q=Z&88hL&l8w:Se@WJ!Z?beM:?kG4^aHK^#^=a$MCN$>JS#P>
ZBZV&1 H^MKHL?ZG@Pi%5^@J4n*Si9hE#iG&BmhK!kl<J=@R1:*uN%YuTEX9wtFHm!pHkZe9Fi?Gc&$<Tattw/M
-Ai=DL 000d0dff26c00110333 Page 391 of binaries1.zip
W=:Zb! ^>w8C:QP\*%lcwCF!t<eGyTkMy6BKHlImYht^PZan!+CZJHaYq^!WV$YDSSi?MBu:5IKIGb6YthtjJp!
uIp@RW A8**&M+5&KHN*cm<qqi/M4BI8W1BqWZqek^NRbPYImqLQZJLtbkqM\?i>dBc%6Z+euYpSMciXnL+wZY*
P:?y*Z Xid@+D4q>=RQHa59u<h:<CI@X6K/?JPk<T*qwtX+RFt?Nh<G6liIJtKT^CCina!t\C5=ZHiIp=/=1dF1
DJS@aA V<SBFbhC*ND+hpC=Mna*yX%pG5=A@H^Ip1<9+Lk:NNq+AW\yY%5A/i>A*w\EYMh?T5Tp\w+!JmFnXXWZ
:8$INM b&ARVKVVqFMME^Ckb\pJmC<XHNGppXhu$TuS#F$6hL9<+W\^i!K/9dulhln98JyiQ/YJ<8QD=jQS>I6I
^?PQH< cEb*4+lEq*T8/6I@Y@eADW<jN&R>1p4j/H@8P65&6\MyT%5P>FLZbDqkmVAuq*mXj&%Q@6JjqCwa4JyD
Ni+Q@N 1NHlNGn^PWPHTjG^TM@Me?aE#NhZ/=Vu6dcZR+yPeMJN%V6ZH68WCb\$c6cAMb\\Zl<1cS^HEENWZyki
uWGG9T m?FMkyatDNYXG/enL?LVZS=%uILa*LTI48G$WY>RtJWwd4c@QhntF148EVdMLC%w#b?M6hG#cAy#P%AP
$Bb!e$ *!<Lk1@N6<P*yZu6ieL+t!P!>KmXH&^LWX6?B\&S/V9b#u:D#qTuKeKbWhT><@ql?lP=:qj$L1X91HKl
qaCkj@ T5?mSuuaV!6jyMnkCE/q\lqP%I#jCyH4dXEbaaFZtSE*nhMh+5?I%JS:?9balZdc?!5iiHZLQ*\ti*14
J:K1=L =q+6t=XcY*VS*tQtbL@K>9:^lD@%W?!5!@PQYVeH^h%JWpSjVWwiB1E6Wn9p8Z%8L!1k4LRHWM:GYh\h
L\6CPw GBNlqXJDqqb\*=mW49FILWw1akBqW5+LtW8&Gy$m/M$XmjuG@V/Ep*@l%4!yHnR/Rb:dTdT!?T*IYLYG
tqqZ!R =8jJ$4WP#Q>RFpaF:Gwn?%5WlF@mQZ&6/KAW%/dMybTA6h8EXbnR8#5anbiLSbnA@WLnpQZX=tahXtiZ
MCNPM% VGehX4u1bpA\*qPhuhy%JBLH#lCHiSjQ&b<*X@@^KN6j9my81Me+5Stw1CRF?hwcG*y6BZ:eek$k8%l?
FP/c&k JY?IE?!+P!:%\Meph*kX=XB55jqNbp&%^uS\j>A<<kwXq/EGKK%pi+=iuyK6Yt*CE^RB^wAB$>GqKXFS
nan#$b TqI5q$*4N+55K&a5^HdD^kwlQp/<TMpVy*ZwXVC**/=NKuH*815M+XcmtIIG8V$+SGQ>MlIV1PH8NLG%
nTC5tJ 9EuwlN^My*TZytJP+MXd6y9K+w>d4+bKdTVIyS/IPdQaRHb!QjmAYGlJ%6aTIl!#@hk6K6GZ4:kEINkR
<cHTq^ dSWyNeLCNXu6>1HhIG91J?y:h:B&>TbHNjy\6JWyt:t8*9S*?&P\kDjZ6KHQ5HH65pLY/6C&6Wji++M\
C&*>LQ cWeIt@t@$qSacFq6+e9MN!nVh1&#aB=!*^?Wp>nET1%X+P/:9GD?lpiQjENA4%#A\JK@>tBdmI&AG?15
96Gbh@ cYEuyyFd^nyw9BqcP>qdcE#\@Zt>H+Dac:y:Edh:P<jq/kicJk\w&1EpN=Np1tlY^5XGc8VSuy&ICA9c
D^^QM\ j:ZYAkCTeSJ!eIeETSLkHVIBFSZ\iNFcAK!pkE+p:9Sma6HwSGES4%Xcp4QWBZPMEXlCWa8A/&VVd4wh
9PL9yp FEFu/ZGqJnjB4q=wMIk/Hn&PbetZH/el*M9lD>yQm#&PJCB>YdZmPC/uWX9:wq/MF*?NF&eiWJnKKI&t
jRpj$u \$a:+*::NL#Zeu*j8jj+md5H$I4y#4bWF6/kb9&cFjPXTiWFItAbZDn4nd6d:!qN6AX<G4B1yaRu^bNV
qy%C<c &L%yBhiXknb?eX\DYlEJ<w^ZlwM<HabEaY>WTbyjDMSMYXICui\laVYRe^WpTFm8n4Cq8F6N+\HX%m61
>@tE#L jw#dT:#K?MWX6&S5t^kC698pSe$E>Ick+T#F5SAR5wjKmwwM$L!*SeEa5wA9E+mjIF4Kt!l%FuEcFp6W
@A/Xb* tAbTDTYwcHa#?*n@WuSc$ca!WeJhLWAN1$:miA8T*\T:8C4RRuCQL&BcEba/lAGKA\/B?yJ+?twYc/Dn
dbiMbq ?mWYeyBci%DAG1l/9FVJhFE:/aimZ\WpR6F59CBKSAu9/i:cG1V/ciHikS19\\F^?Zd@hYZw8pZni8qS
u!ZhL9 CGneAXRi4p#WZ8XywcS>Y*Kb8/Xh9N%ayZa$YBq!F?IXVN*A#?K=JWE$SqM19Hu/WID=Wn%GM+A\1#E/
8%&?@T Iwk=yP8Teb<+wk<@y:$eBV/kBVt^+i?<WW5<NT#CyA$6D$#$PptmK<K^/hJS&>HSAuu4<pSdcw<M/dNB
Q:%w+* \G8HhTNwn/G=iy<+F*D%:68dKG\jb\a6b=WNc@R!yk?#P4Q$&kFliiP$*:iwB%Q:u$/6tnT6cKK6=nyy
pE\YP! GZNWTN8aa+j&Y5L4hjlMiZHjNDm!<yK6u/dPbuN4Gai$YbVFG6N@MAPiYPkCuj6Nk%JQK\QY%WKh?S%!
B?C1Eu aDbSlc!en*Tq$up^:+QhPI+QI#ki!KuDQ4Bi>nQPNk<RAMy8*1Zi6t^8:k+@&5Nm8+5C*=$6yLh^X^^F
RLYGy@ kXAS*T\5>&yM?*BVI9p%Fd%pJIuFyBA1Z<!RJuDSl&iDd%D>Y&mG6qayi&!9dT@&$^Fmmtw9pi#5C>PX
A%@kbk #ju4:+aVNkWjjTb*BDtZV58p9I5p$W\54dbVyJ+NJ>Ck+>$MAG&:eli8le6S<HL@\C+&P!%nuwab4l:1
C/GB5y +*n&w/LZb5pIPDkck$LwNNZZ%QBK\+5#VHtCEq+^8je^c51qiWYyi5ln<empjX6::=:P1eA<=M6lb<hM
*/NdHR Hnch!S>l=Nc94$SlBSd!AMjk/@NWeQKwKCi+?/b#EG$8T>Gjl^MR8jiyIkXS>!<8R:w:kiQm>@6nmcMT
@GGQ8+ :%<t%Va9w1JKH%$XWNpIQLGpl=Acd*Nl=eSX?HGBCiQJbKj5KwKY1F^YnJ^$/=kamGHLTyeVe5$FbJiM
&!TPaT !+$mDQ!1eu6&X9Aj@tPl189d5EV!l*YwCCEdcGISPVp9K9&L*PeNF/H#mpWpyM+PXD/4+a4^q*i!bQpj
<w1K:P @Yi+@NHMCRScbSj^ujBW@YhhA:Hu4aVG=F*/>?it=HA?TTKHRb&nwD4Say^>Be1pMpwPTbt6RCJ:T4@m
tl6<!6 p<&Q%FDYZGHi!6kRuKl&I@i\pn&L*9KlKC@6mE%G?RYi1Ea*&:&4wPk%^+5jbEjJ&t\E=KFeIjqL*F6$
98tqwl PBtCchm^4DKy9I&Tlu%B<G:CZ/SRSj/Z!tV\u?#:@u6B:H@heRD@!d:9u>CC9/Jl9$QDBH=B\*?DF9nF
Zi\1Y! M?>\KPI*cQk9GlLkWIHjwcG@P4jkd>C@XNVkQ>p9>/@+4===l@>p9>#@DC*!V+wc>Q@TWH?61Iu<S$WN
BpG*K1 l9lZSR*?H#jQ@WNSE^IW?9<Ti:?h&H9*9&VJ?4DkINVJ/eWb8pyGLnVPtaRjEAitSCFkH&6SI51a:Enl
PhwbRh pb:KdqIRp>W<w49GdJe$LBB=RTtA%J\<qa9&kPdWX9V/Wj=dF6D>hZElm4iuQZ5a5qE@MB!VWj?n6$H:
%&RjVb Fj?diCSTJCbQYaJ@VJWbm$1eJMBTNC/=^XJhS/6CXl*iWMWQ/AQ%CAnyiDb!1T8nw$$</Jb?LCJ%Q:X!
t^DB?X <RadZhdt8>yly!&8DPp5n=wP\YddSA!<KEjpuee6q@*5me!IBkDhe*eMtYhuLSyJYKH\w\P#R&wmdyJT
6ITRA9 +@E:Ayu:99jV6#^GR#H9*H8/MJ?k+Vd8#tNBc8a$F/:ZP:G4bjQ^$?dBW&TX#Hp^uBlqRh8PpS9JHkbl
8wmPP/ aV!81$CXKT&bP!1Tmmj1yI15JRQiA&a=IR!R>T+uCl*dL+8wedWClSZ+?%j?l#<YJJEH/Ad%<:k9S1ZN
V%y9mV Spi/#NEPnH8dn/%IRab4KEFHk5&h$6X$/^Ta5#Ceu><l8jH%T&e@imVmSMlT/9QSk6iB!@KN$<H4WTMT
e\y/I5 ^TLHS?TFI?MF68CGI+F5kR1+aSl8%9$54Z9XS!RQ!NRMZkQD<hcy4W=D<AK%C/S++qd%1c\NR4yMb>CS
EWXki# ^+TRqN/?wdY8bIHuF5<9YXAY%=Y9dh:X9yclWnE%/S%FCytp+<<K&pu1ijKX$N*iD?:RAT!<bPKh=1h:
<ES/^j XW<Kj19@44:^yaucGGD^$GK@FD&=\:iYTlA%<n\^S9C\@T^pQnench4Cq5DiGpm+Sp9m@qINL?d#m:/&
Fj1SF* bmNDm!BHnbiMEaSbH=SuH>l=I:lub&%!q#FCFLPA6d/56MVhn41PAulT:JAT54$ePP+5IbB?BGk!hTKP
%1BLub uw4K%\ZiMGKa8TVmQmt&W5QVIlZX!\&AqYBCdZ9EqABEcITTqHI=!ed+D>#Kw1RFy4@MK\eB$AFiI5Jn
=dMlG9 \HXlhu$ZYT>PWy#>D#$MP1CEbyluieE$\#8PBCLP%$X@PWLT\BNe4&tiSRudNQj6lIFyGaWT$XC4l!?^
a/\Lmp <Le?Cq?S%yAR5^98l&4hqT%l!tb$h#1*IP1NbG<m#\LaV?eTAkbCRJPP<p:Dbj^mbMX*YNcJW^S+6Vt>
bZCiEu m^9%C?9h*KX+lp@*PFuPmw#6Hlu^j5tEQb>==dXyH@VmW?>H>Z^9pQpd<!E1B4K5!9GH=*bCVdY&BE\>
T/?mkH XhaEX&mqF>%?QhIYBlXd4dp>mPp84J6aHyFkQ8EMG9XH^p=he#p<kw?CNyni89JyV&Pu5!GDLbQ!Qb<T
8Mt>*> 6c^Jkt$&59KVhpiy=Tw4MV&V<&yWT&V$V/mD/i%hqE%V??^FP<m##VI>QTJ1W<YKC$Q!M\9Vump%4Z\w
CSD6im jThy#@eR?<YNKtIq+&Gl1mK/SPV/ReE%XJNpqlJVy6l9Ai?>4pKkddndc15>\$5VVc>tQydTpuT\Hjnn
K4t>pN %FM^p5q^etX#C<jM<D11$cCikuab!H9:&p<9eDCh%E8Vw5J=w!b^&B!He4qkQKNj&TuH+KR!5X@\!khR
8dtWLZ 1+iHmdwS1YiGqF/&C^9WinP5nZw/Lq@9P8#YJi%b<a&w%i6jXFaA?jXip/QAP?&lpMnAdik5#9Mb+k#^
=1SJ1Z XI^:p>K<DTnTFXBi&IcW\BJkK$akh?CanFw&:nX9Xc>1G6A66>@t<X4lmty@ktkjE+LK>BEYCG:i!9$8
G$DKka =T89j%q6&WNTa?&QpwEP*t?d6w!A>4X*nN1jR+nIbiRm/$ntua<:p&4R&I!c9QN/P>=Ci:>%n*lkqKRc
YHDBmj !CZluGBmSa!TPA=BeANhyLju>?ahkY=q4Vdq%ChGhj/Y59Y!A\^jYnVTyS\M9Sn1tw$?iKFi&\!M*\wL
De+Nay jJyemYWT:plT&qh?qVSL%89e*pw5q:uwFnRt1DlRZ^?RH!^SN*9ikIn$>4RGjM+1EPaJnBYl/PdYD&bV
WApJ8R yY89T:m!hJSNtZ?B!K\Y+SF+N=^#l>9=ndjJn*j:>TA1V&mkAGSZyt<9*=:d\/k4ddhu$K#4<pY!XN^H
K+b%>@ kZ:y!dwJm^@qa<L<1EHJl^cQ*$/jF%:cm%p>h$DQt1p+hyL&E/>lI8ph1dZWc>#Kj@wy\#6Z>JkeeiR^
Tw@BEu 5V!<G&!VGh8*#$Pb>*yQ4&:=qm4tJ6^P15PynpDLKQ\p\5CC9IXXdc@@/^Vu/I&9YpY=t%\l<c$lyt81
n\mMjX pi&DH4@YXy@6X<GS$a\T+P:?ndlTb<X1Ht6h@/8Qd+cZ#4LI=Wy=1=l$n/P?T19KK/QCJb*y^cpuQE=L
$=mYql H+Ap+^+?+uj$PQQ*!&li*?<=DQ^G8Yd*\@I5lu>bJM*CiaH/+<N$w\VhKWi6%eb*4T@>w6^G^Wcp=m46
$NZ&B@ iJKXPh/Py1d5Qp1ZHWkqXu%^4dIWdPbm&!JW*EDS8YV\YV>bhe8?6e^m<TWcjdm!6VBhQ<n&1*u8$cl$
-A+^m8 000585855b200110333 Page 392 of binaries1.zip
GE4NK# C%$9wB$qkJu=?FHilk@bB=8>q+nPJ99151>GZlQK4weeHb?\XKj86d@jiHIeR9W>YTQL%@6AbY>Za&YC
yJw<lR ?YZDZZcA1Zm>1YipdWHN5<48<Ac1GR&P?6j=C?tNdAaJ##C4&BCptD!VtiK=hw9&LmjJ!%PZHhy:i#tn
%&/nyM JpcV$%qFJNSbyql*?h+b5yTe96q+6bj5*m%=4bhWyLW*$nwmYcjih?SRk%@/I8u=MFt1IQ8HM\LiS\Le
n*kA:P eGm*k&C=1?a4ihN:Mqu*8pX*D5KWB^*&?uNCbdQMm\K!eRy%PLV:%W=QYdVF\*JLtN8N1t?qc6A&uPkk
*<dAQh Ce\GLphampXa<Z=1i\kRX#=<4R@V:lYRiRpDm>Ij+CiiaJ!$$!tLy#KVwP*5?Bq:5%*j#VTd$EhKihB?
8t\G>W cNtm$?4kCI+DjJyj?k+9+S=iLkyR%N:H%6uuJ6HZD+u1i+\JHqZuquwXyqRSm64bCSIQn$nbWk8cZI&&
AL=!EH qw1$9EKwcwd&yWkFj+bAQR#hDknSpD+dCKPcN:/JwBDdb=A%qKQqjYIm!8!CK#W4uHwPSB$ZVD^WB:Pj
6>ES8A %MI^:wPX1Kw1b$F9t#5H<<Q>j9FE6i\n4=+\\c^6q@deXjB8cYamwWGjMVL<WZ5JG:E5XC$jqKy^l*l!
*&XeX9 Am%GS9F$WVP+9$/&YQ?+PFdy5G1HDlG6*d#d%5l!DiK9w!lW!n>k>*DQ\&c^WkbT=?PdcqjIuC41#waw
5%6CZW KZQSP>w&%yTkE&&MQm:E!AQW6+ZStaa>QRkd:1><AiKjjdn6N/I\1#M8=$$$m+ZYH*RENa55F%hZ18X!
XcJ6=6 1T/GlK4:/+hS!lACi@F>NE+Z$Qdd4I4NKc^LY&&VIi/LW6cZb9cY^B4*:qSRB?LNc@Y6H#B>F\<>#A\>
$@XqHQ 6*Jua\u>u5c9aFeiwbjppDPq//^BRVRiVIbL4<^9SPTld:##nIZa^*&Zmq4&E=G:\$Q5b/^8q@eD65Fu
4V9/y: q?>&TcZ4KFn6bT!pX<MV!M%m!8&u:+Q=#Hcm@ZbPYDQ=HHLXR<D$m@uDNyIP^ZtaCt9FaRWP8qiqlctD
PIuCFF VyESdiW&/jk^GN>K\=\tN9k^9<DXHiFKd4hY9b<Q@a8Pa51hW*KXHu$yjkPP>$DWPEK=AQ!:MmFelR?$
?L^?nG lJ%tEJ@LSjMJG9in>Hn4yjmL6Z8ntyl:?l@\T6kPDkHqS4%5*EIliC416DuAHD\<K@HN*nM:XC/&ZDa&
:\+X<E wVFKc5NY#tNahF/G<?ZPjVTmjSZ\t+<H\==AeqZZ?5j!CLneK*b<LF9+6DNHuTm:5FpWEd*CQZH+C<?G
\&kAjK \inecdDN6F:I$Z&&NkiPPlHQ+RNLlJa<E:L+1wmHmky&?5\>I/F8m#y155bPHyQd^Z^E1tbYwSH\1IdI
?dYy>! BZ=kp+E9^YI>&cSJG4P@cIAMp!4K1k&Niwk4\F&IdPa>p=@cLW*SI:hT<p8E%KiakIKZ/KiYGQFm@QEN
Dm%nB6 ValcAhw8Hq:X<LX6<:MBJcL9lq=/hCpMetjj:tkKWJ+n4ZE^9I?j1w+p:ew>qdRPM#R#hHbE6ZGH\\mm
Fu#^ad dp??4>YVG?AM\tYP#!1p5NCT%XXaqhXTAHBe6bBbehLNhQqJYVLGA%c*bAZ@dDLc1w*:KCZS$#p/4=Mn
RMy>9Q 6bpLnc&XwL=QGyG%m=?A<KMWFh\ID#RN6wQX:LHG9FH!n#NJ5^iQ:PewHTDFQiiH@QX!t4J$etFtuk1h
:Mj\uw inWKhWZ%MjHF!PkC<dI?uu*SV4q#<YTMkZGwjih:k$F*SJR9NY5PcABZY/DJPD=wN&ReZ1>6B6l6tMB^
<YE@pJ $qc^F^kE>@&kB#+&a9i^EdDThdiEqSiaVPSwib>cAN%i+M!/yu+$K9>kQtd\aPQ/JYLQMNLLh?N&N\%S
!SCFPM :>IkDKc&hy9hPYKhh?8eaSiMGR\Ih4DXma&\HY9bHKTPWRl\$5B1=Cph$LKJAN6+tI%DK6dC6Q*G&Tb^
5P89Xq 8eGkFBYDinc:PC$q8@cqpH9KdJ&Lt#kjFTKCAFMP@Sl4Ba9l+/SSewKd<!pdeR\T1mNYK4K1u%K&b>hV
j1@WZR k*>k>qXdiJ&t!t#ZqTu=lC@Y+Tw<maTwYB5dYmqcJAtYy1$@*q>VH6V&=BuRCaHMy:c@FeL\=^ke<MuG
$YnA@b a&?&GPl!&+8bWS<j=nD%5A<!L=>nYy><XZnDkB&mmLRDY5\t&N*8qKJba#8ItWXM>+k?q9WAPl:y>y<u
#Q?4DH K!FVc1n+iXb61#iE^qcQyi<^YK?ESV%u:>*Han>X6+#mGa:*Vnh?^6VP%S9^caQGPZd/!4Iju?9eNNWK
8nP8JS ZnSantP8>WuCbYNKN<I6=bPET8@c:SAmnA!9%H6Th%Ld$Z95tY!9dWyLqp%9y\=>aYmNj9VyRi#qN?@D
VlCEFw Ze54D?@XA@yliDI6@Jw$KlX/IeilHucpM&i8nXhGq+8EqW:m+SSyn@1hcWyaEild8b4+yIlcX#>%L\+:
b&DhlX IBk%C=$6H=#FC=m/H=1m6D5qq9#^*5Zm4W8a+eZH?\EF>*DFV6&4LID=u?%tn<keDC?b6T:tyS5PI4jH
lZBm1k n/%\\*1RBj!h^SpK1u$4hjYBa8::45&<ZncNV9QEB6n!WYE=WmtQyI8u9j4!w16TDFTe&4hnpeW#$RnB
Xd%PVX HZXL=/aMMhj1EQYG<LCe4$t*Yc/hVlP>Jc&5yjGPwub?iPXiHtGn81=9aiB+Ve:I?N%b>?LptCnBd>hd
6WqlLw CeDSWmWHiJYZ<pT&pJbG=I!eIepM@A51#jH<P%>&<wXEGTeAc9WG#Pj\M4LFZq=Hj!bwT>nG=QlyHWeG
HuZdLR AZbqB9$:Ve6JeNF>%:KC:JABL%@Ydjun:jC4:h&9Xy+S$=Bu@puihqW9*pSL&^LH#HuZ/%YnDVi@iBjN
L&5N!L cmVebCMn?R\u<<Xk*<6^SjWlt?nBkHi^Qk9H6N5p:YG5@nGVubF&5m@G&i*I:>qjVdjuntVGDnb!<wSM
Ie*YAq LIZm/qld#aNhZ49%#peQ14$4/Zw=iBdcL^Mjjn9%ljk>::QEa9aqk<RM4c!*uELJ46QnSRt*tqhcE+:J
ywa&q$ J<PyeK=aZNG4X6p:<VWyG/JH98/Beh^9PYHqXl^JiANFk:KC??JBN8#j5h19hbH>jDG=DV+HL4EX1TFb
uX/Ph: dqkGllWCJ+/bJPSPM>V*5%SK5#T5DT981aK#5B<a5P1*+PLAQK!!QBKJLXk<mm@jtB%SI54FmcP=#>n\
/mRtJJ p#NP5d5c=q!ePn@W*^QT:bPTa5&T6BuijTl*KeLB8k?W>B%!%Y^k4/i6p%%m4^@kGNpl1@NR=l4lhIp#
!eAi^\ w1A%tH=PCjweW6kP/$iVeG^@C?664^N1hn<MM1LQe4>Dy4&p9/$=Nc>eX:Q5=%MeT<yjj5uqK$BD%*Iq
1=J/@u 1+$jZWuZ%R@&Le+9aJ*&e9$tXV##wA1eAi#*DNGSIMYHa4Qe&>=*F5pW+V8MIcX9d*pjejFedPQLG<@9
idbj@\ iu=8Np!Kd%tLI5lt+PAQ$a$a=>5D*XE&&*n9JWnY:PIn/<B*1XB+P>8>*+jm/pE?:pXLmSYLdX#!#<L/
SdVHI? uT$XXQD8DBml6@b#FPE\K$54FkYMReuDDL?M1nQ>Kld=q:j\@@j19j?yjQh@W9#ql@**MyJ\tPC@bCVl
Au1<G/ @>m4<%>tJQ<8Aj/#8Mn@4+48**iW@aaY#a@+HjyZYnT@\P@R5F@Sk4>DR*>FC@$GLjBLY9k*cMR9Q&5m
>nRank 9$Q@TwPHRZ?Hl9/K=9<NGmd+K^4&G@T9XZVad\&dpPA9cMR@/iB@b@>HP9k@\1S@$<H@@j:>y?MK@ERH
<w%mY= =^eY?D<uYT4$@<4&Xw++jAYZqlk*M!PcGCa##daR#I^l@61y=TMkd$H8PcFeQi#+4V\tQwkYkFpAHFbE
^mX/AF S*/kAYB/6d#yRpjVnFW1\JtHnW^Dpj\AYP==X!k/Fn+9HuEL1p<yehaXKwW1EAc\Byc:ZCITim:nWF$S
biRjSV Lki9#G66<e9PaKY=nR+nQy^IDctepu+w<\BP=/VMAa:cBc*4Hi%w#=eTaZC<:YcqPj%8$11E=+d>/l+k
IA6%uy S=y1nbd?^nB#Ge1tWLIMc$:=EY%GR4&QKWRGXbFtYnRltIY9hEcX#^ilecM=nEKLnybpAk1/GSw&ZTDa
Lm56je 9wk^4IJ%WQXVS@*dWLLq\/E8VQ<qK^XH/$ip+NKEZaTKD$/Qjn%F%yJnQZEnWSB#c9eS1@FI^*Mi$AW6
GV5S*i wRmI!jt$ihR#=4bMPK+nl*bTKniTQA\ZDQ*BnY@aZ:<G89Pm5T4J8H%R&RNS^RSaPJb%BtAWI$nNakKG
kE=udK *!\EaqG&1DKpMD%a=#>jE%%^Y>=\GMqTc+dd%4&yJHX/nIP/N::5*$bcV#pYhMjKC!*tkk%*^nC@S=E#
J!l*&G c91XieWlBVA9T@AYZiEmI%hpQKl<V$9=%wBpi1nSQE86M6TYZjI\/Gaakmpu\u<l#a/EZh\5CJJCtyMF
jRaP*D :p<m1L%myM6L#Pw$6C$E1eM8R=TVPFQK8>LPL8j8bQbL9cayhI/P<^YP9\e>tQ4m=@%RYQFnNAi@cVAw
n^*Q=4 A:1ZCTB:6Bb>!jl/Zc^6Cj9GEaWml@wad=NZ%&w@M?j=klWnEIJb<:ywhmb8htI?L>ue*u&4GdH/INZn
&8=F&m $kuZ@b!dEHpXVAy?G64bKyE:8pAMh:AeqeQLDX?5V+/ijkntKK%5\VI&LW6=HQ@yP&9^Plt/FlTJ@X/6
9dTB*a T&AqK^lB:DV/ELPE$1>1:WAk9CwLq@XV$KR=lkh!w4iQMlmaiqiK&F!b4K/QjI^$HpbpXFR/LGk#S@Kk
cmF%X+ jnd<eIY<Ruj&jHEWS+%H\/#bdG$=#&HY1T8D6LIFHYh=8ec$#ka/MJ9X5/yCHGyQCY5pm!Shl4%!HI?m
!pqqpQ /KHAG#Yt#8SmPXwu6?EPw4n&NFFN#IN8!*TRTSHy1LCEmEY$%KqpcTh*B94XyEt#d4c=t+=IJuA&$uZw
lnGyK& \Ru%ib>ay5%>Z!A#4p4Hi=+HSD!cVD#9#bDXmc<=ZcdWe#C%aFamGTcj:#Z6ekI*CA8NWKZjIT+AYdnq
4laPX= CI&^BNZ4MI?EuDm+<ju\W8yJ/bk$yAdX5?qKMRS#i&k1jpkhaI*JQJkHEE&T%/d#JyCky\RXhV$aJ#&p
lNy^L% TcjSBIAB>QK=yhTa14l&dl#</aaWuHhDlHLXmkR#i1LqS1!yXF^N^XF#^+cJLh=FZeZB#dJJwDR<bVD$
^QX%dM 6wX=?mNTJe<*XZE=1&mV5cjMWwbQwdT%tHBGpwZS^!^CL4+PcRmcnG4\Gq1P%hyPSJYli^jw/P!@TXwd
Kjl/j/ TCwTAQQIFyEu4XuEaMZK=9cq1*e@B%Qq>#lAk8=TMP+QqHWdAtBHjyWWm^*E8Mq!i<=ta/>&^Kuuumb9
KhI6pm %jKHZaC16qXhC<4/QNJ%dHW=H1aaXABP!^WdpLQjk6J6%LD%mqcmZy=d%nk:/KwdWi=V*!MQuNj6k&I=
XjQjGH tB8K/8wLK4*ZY>k^a*IP=y$uH&4&wdjm<e:pn<VaNu4MY%HTk9iTX@LDk1=?CXYBHh?RJ1VA8$mFJDw>
im4IV? Z!@KhLYRCZ&:D$5qW5I$:Q1lE&M&y5%5=puj9iN+59\hZ49X/h#I!m\L>GC=M*w1CnRp8iYMiC$H?dLy
M<y%?h MP&DNAkynCRQy%waa\w1W>&D1<8SB=86hReH>jwbLuaDu=qJYttylybXbAnTQH&AH@R&a9WciYkRWn58
w6HB&m tJ\RVKAbWlHw@5/^@F1$XiETLZ1T/Ija/X\E#/8pP>FJ&w%u$&8em5qlB=5EMP8=B$YAdKp!h5?5/CqH
5dmhtM KnFcTy6ppTJjAhF%N=Sbiu/BJH=MC:eR\t4Pt65$eFFw//6dGdedZJ>bpdyInwhCJ+c$5DXq&J/EMlY?
YFPd/S NcacP8jZ<aRuCZ:b%LW51G%:T<Nn*c$>ZLSp1e9hIQM8e58:j//D4n:p@dDtZYdp!khlCtBlwGj+jSj&
-Am#Pd 000c1e3806c00110333 Page 393 of binaries1.zip
wWMjtl 1bb=LbMZncpAhIM:FNmDTe4byStZ8E+LetnGcjVP&YZe\6n$1*eE?%L$TWbEJyV4D>V9%cDGl&SKG%VA
\Y%!k< SLl#dqG1jR5mVKDC\l@eZVd8=tW4Gha9$MiWq$%eQ$Y%Y1dWSV%?+65iIh\umhGenJ>q48!hcj$!b<la
muilGZ @VPXy5HVP%6SS=D5RE<%P!tcL9Tw^^iGG8X>^qMMlw9^^pDVeQyhHE#@I<N&<kjl%8?+4T/#$*IeHnMa
wGQlPw NVFFC<VJZYHw<dit$X=ZFtY?m/WQh?98TG?eiqFy@XC?P1P*iZdX:9NPYNEd$\+S:X:>\IqIS+#QmcuW
uFINu% 8Yy*?nVQt$N=94yc/iynN\?qbqBc^:^>1=/ijZ$94DYbdPt%k<HA!!5V5HRIF#S?eXBpu9P4QZ1K=PZD
B84Phj lQS=E6Hye!FH1ClJ<iPQ?yY4Fpeu88YG#/R5CYYM6LQNH*<$@HJ\6$k/6?L%$Fh%$\Y^dHF#5RyMt/Sy
GJLC8^ K<LMlISFWbqq&hF!R6<!WN?IX8&#8Q&:VE4&H&niL*6SynJ<>Ide^X?8@XCVR\GH=L@lqL@:=X5>qawA
WEbXJJ TBGeJ?IQi&BYFFq+iNZ\JYD+5LhWia\=yD@CIRJa8La9Q!ED6WV:AeLTn=<eCw5\H>PGPwllAhw5YFD6
%wWCND R/JXa$ZwC9+@B9enbBZS<E^%N%ilcKPTad*G*X6wwZ6aBNi%1yY>\!!A5Hqi6HE5HQLCujI%A8awR4H#
=$P?K8 5b!*4wiQS+c\*Gn6iMbhuG$RaAjWpb6$n\4:86nCkE@mWak:$<*41GM@N5aqbNa:VQ4\ZiB!=/cmYdFc
%#IF$W Q!$9EKJ9HVRh5w:LX+QX8dJeYIyd8\bAG:hMYH+c:*M+XD&m<EKTy*$#4AtC*CN\H6$ht*VJ=*=9EiJn
C1XCep AZ#j+\N$Z6Fp<&PZ>?hTnR8VyX8Tn?GS&niLIwQ5bF%k9\TNct5H:IQ:u#aPN^4G:P6aa8ZKd@LIuK6k
:J>n9% MaJ6F$$%NEQ\FHnpmM?b*^!jRD%L!n$G9qJE1WD^6CQ=LcTaw$1=NJYHTS&=G/9eT+DBcB=dybiDq\t>
PG*aZn *ZcVuL*8?a$VK9bVPYi<MYe&F5QkW\<Fl@w>tWt\/baGLwdVT1%<>h#l89ESHRB@#VNKcZ1\h6RySjj5
Z<4l$R Ww$HNue+Z4V9Mi/5eF1qP*i5lVqt1FL6V5>iQFN*P:uVD:P6Hm>tuMBaa8+Lb1mT$qHFWPQBtb\/ZN=Z
ebBCZI 58QC\CKT/\\LtYXJ8wkqHS!ViP5BHc1lQT8&YFJunGJ4P??lD?XE?8@11^E$**DhiEZ8J%n:^SD/lb#u
TEPXBX lN99a?H$9\%#5GCQiFEK5Vlyj%4j\<$iFAPe9SuCCbl/C5YSTZSlBBYt+RikRud*tP*XD5jV*ywluaGM
B?YGTu @qCZy/YL<dn/D\hb:9V?wMNw=Nk@BDy&!5qphiIkJVeJXRDB5D$XT*e<n!%N8%%P\=nl^^e!W9R4+GEM
>dD%wy jXbcFY/dcbubjF+&MBGibERVaaPT&qwLAC1YGV+D=bwTaApB#\k@t#\P9\m!1TCHP8yScPL5l$&^Th%P
cYtF$c =C+J8RappJRZDtLwiNw>VV\iH%Xycwl:VDneyYHa\&<8M6Pm6y8kpp#:EyhYT/y=TatZ%#G*RQME5#e6
>4\+db Zpq:Pe+Ye:m#FE>tDE?6cMwTPTIAWK?84LYDSjpN>4WhwhVp>lPYyW/hwt@>nty4h8KSWX*e/&9a666a
:tq8a! JCDdtP%&?VeFJ%cXjehK+a9=^SFqJ>YnTqIGKTJIVWlyCp#j1m*K/1/pCqb@9J<!KT:ppHHeIZi*ki=d
q\MXFl GRMIw%QDPYXQ#5HmDADt:ajaK&YZ\V+Ydh@&/i:EE>$HMlMA&9ZL%4jZ6m*Lul=^wHS^F\5d1!%*=I^u
c4$XM: S#@dK!q8*SwQ?y%i5A@cV^?/SBK11S#Enb@ZGy>9<:/\pXah=>:lXDI5i1iWDN^W\>5A=&/4L%c:T\^%
\bIXW= t6PF&ctGF$?W:YhJ5^>EHIaee8CW5&n*WDaknRlD>#T^ZPKT&<^68A&<QZZ&@J<YYjBETF#GLF4k/Pmh
lRKQGu T8XLdXd89Xdb&6Bl&VPAWdA+Y9FW1I%XEPq==$Im<:R46^6*GuXp#dFeK%N\>$jL%$$DB9SDw@Y<NjSm
c\9dhE LELYVp^Ru+*Hca6TldSGP9D:4V/k/F1ba>Hb>l*=JE#n6#Qn/J+ki:mRjjhL/8N&bj^u\*R*YX95tB?Z
6V9S<J kcBwTWG:/yTeq9\q1=Hl&#1EIa>*Vy*q&^4Qi/D+d4&&Bb^5e&dK&hm%\6uA+aD\JPiSLAl^be4&4NNk
Q\aSbV =?Q/dVXB:T5qM9:KdIuW<!SdaFmq1V=Hbh*IbQCSY8NYQ>CF6RPm$AHtpP1Z/8lE>X5N>5RpGXd5Xkp&
hl^wkH D\uR<XwH:ck</qNlHbS=EVm1c4d#%4qC*ip\$N1t!WpqT6ZLw\Nj*cp!&Wl1Y+1dkF%4!1GW8IkQ&kj4
mw8K$& :HSKi1e:&<n<Zn#A8P91@MMM6m8*bypqh/?LK*8ayXaJ>dCN9i:A4wYA5dFVa:I1t<1BW8C+>4VW&5:e
5Sc:D4 mM1u*K\+5%iFqRdiYdWcyaYFL<\FVA\J4&JbIp%$bJS%jE&R1?DQNwN#8bq<pL!WeWm1V#%Yue@8eF4=
6aqjb1 8q*A#5NB6jlLe:Z$NCWule!%PRMHFkui8G49e@j!W#t%qqcYIKQ1%bdIIqAF!#Q4qTuH^\^e!DjS^Yye
D815^9 lW*#&?5Y?&*KGadX1Na>Db<K=qEX&4l+t/htJ/#D//<bk@l/NaHB^>dib?!>cE8/EyK\>+Tq?e@Ade&>
&/y=eC LZG:\j#5^%H5hKBQ#VXP*&*HSZlLp1%/Y%S>KHX#l$Gq1$>LqRtmW\$LY/Gy*^CL^k1LWWFycnpl4Z\X
>GqT*i YZHul=j%b=\&<?d$le>!k#E/WdmqEw&LyRwDcapb\qaFPhA\4SD%>!HJB\<T5QyRWi@+wBuZPjwJNlDK
l5DYHp IQ&YjWiBCdV>1^@$jhmE:AA$R!8wY^jGATajAdN%lP$8?=b5P64mwYu8ijA?=&MSVQVw:MTT@T5%6mTh
SSkBSe :5I956k!C<CH^Ga^h=Iy9&LnGA/q9p!JRNuJyMYF/kG&J/B/Mpk!Wi/?pWjD#M1i&8P??SC*nN$i5X<y
*%4D?9 tDDB@/YJXbnRj%P$SMD@XdSE\H=d6Q#*1@$ZJiku<l6M/F</WH<SBaYJ@A+6>A5cD9$NY8BZ=+d#@\/N
KceX=n ?EWEFk::HSwK@\WN@\$c<e6#I*/Dl9@!hR9<Dk*@li\IF@\N?1<>1#?ulZ/H=9@Xqj@P4Q%c<wTL@BGP
=5mC?e ?J%yk<GFj$H#@:NmClQ/4^ZV9+iF@/caCku<SDFF\H:c>Ru@@=LD9=$e*9l@KDu5wjK/XZZ+iKtIwhTJ
&Y$5G! Ayl+khFX=tBuZFLP4XZjCTQYcp>1=/N<MhJqYelJA<BEDw6kaYcMpIhmW8/LkKGqN1TR+EEpj?!Gy!!?
t$>>:^ bKAV?dk+<i%HhJWNuD%aaY*K?@?WIi=GhkIb&11#\:1!%1kKLAyKD@n^pmpytVWhY@1BMM6iAM^CSRQR
hk$a9< tYhuSR*AFB:SCmZ?CmXFc8%&n<\Ft&q^T^@&+uIBK1<uTd55&bHRGC*8PlNqEm+w4TyllaSa?<VGQX&q
Aae6>L YTjtpacQcB@S+cCbH&dLkyQD@B$u5k$8!^?SF?+NF:Tn*?E^9SSGwe%>lcRQ!K!%hEJBG\1\PLIupREh
KJ*^/% y^&ju<*Fj&5m%hH=%51>hmZ\=uPDu9k&NK+b<:/%pT?L8hD:XB$D**ZLT4^b%F@?@<eW^9C*KqFQcy11
+L&<mM 8HeNtdNP#\Pw+D46=DPA^mKL1b:SI>TNVu1@BcpFRV>SjtiYVi:unuT/kP?/C9M%D%TEMMX>LhGSc=>H
XC<VC4 TFdA<LFc\jRAy<Qi8nw4$eYJ?pPX:#uV+AdV##Z:8qhVl9DZFRI9N<RwB*wNF\Fqd1hh!Q*QH=b4^$JP
ZylLn6 W:WplGI4D?6+F!RhFc9kSuEhM<1$n&HjqXj$^Ie<Ww6!1Ea9%EbT??qSyYSR<!BZ>Z6=wZjab:PltlPh
atN8V5 p5tV$DN*4C?/II?9EmKlE\WIRy#Jm1q\*WD5q^WVBVqX^L%jicc&:A=9FR@&WNbTyB=ZAbIPRIpX4pXE
kTM$*L IMD:<+*i&8GQB>uLS4b=R%u!Ta<wd9D>V^a9kjQn:adTG@w%h$b46yhjT1L=Q9++bh+Xdtk:Jj*^/cu#
%Z<=yH npAA/p+C#h:>?L:QZCteFZj*mMGuEtSTyPQHyQm9ja86e^4MLEwMh6tqAy458AYBWZiHb#%6y#HwQy@Q
QDine9 9X\/XN:dJlZammZP^LM%XdanbJPbIP%CimIt!9Di54l$WpiZBaX@8=SLm\e9%?<cJ#:Zqh9E//T#?Bwu
8\eicT >^SK#Vbyq<WXc$SE>SSd+dmCbB%mn@*FMQQ#Qhy*Yy1^+ju*BM\?MBq8/mmD1G/HwCnKRKXFEI!qw9hK
D69RWM Z+ylcp=^Z?j=uR*cM/4LP>Gut6Jb?qk@HlVmBNTFju$:8@8cE5$LjD+9>mc<AICb<%THWDGKdSGhd&E#
1TchLI V=Zw8S*GukM^1D$:KIGPnN6#6=ECC=wY1!@TPykybGM^:wCc6yb1GG%=&Yd5$NY5$j&=<<kt*>$B6W\?
&Kyicp +Y&EFwnqJPp&4XA?6Q6>ydLEX?%e=>/Y1M>whlWm@kWQpup\hV:c<tqp#l%&nARWi8I1%:B*%8SCKIH&
K9BTZa ndy\wCb>cH>APCP>kHkk+wc9e:+8*eFXGcJ!^a8d<%ETw#PmRXFeI+#!hV4%yLZpZISE8Pn?9uJTYWX=
np\R=@ Ai<Mq*l<X4uK645hNRq9I/a?jTnR9FuuFEYDYSu9:VA+yqXWPbSQVAbZB88\wXb8>/M=VjJ1aYGW=e@N
$PXL1K <MyjkB<?%JY6pwy1RYm!w1i*F%5beZBtF>p/4:%YNM8RXJw$h1q8akudWJ5HPGd#En8$Bm%Te%+pBLN%
*HC1iL hFB=K6Cl9u=yFBmDXLDhy<*/qA&ZdHX1TRyctPLyTE<4b/nKucdBNKNQ\S$1iHjb61VZXin^tj<i6d\W
6YE?Km KQqi@KN#>LpXLt>:Zkh>$=KnE:*HNu&M1RXa=E5XL$deXk/Hn^5PbAhNi*Y<Jk*>K:h>DFd&^cW?4qV/
$SQD89 %4>Jw+Q&*LQq^u>b@6=Jib5<>K:M9uk!#PD8KQ8TGcb8KQdSMT4<FA@VCT*h<>!4&$te^*wW5?jCn$wN
waAwdT +C=pYMeXqL#%1EwWdc/a6LhL/<:i?EKHiLHFkM9J*FQ^L>ijDFiE?ZXb?/a^&<8u4Xu<EM@X+c@=qKPi
udY@S\ QAAP%*I8H+VNL^?<hBn:^n6Ad:X!AS=#HJQF\Bd<wj?P#q+=\bFQiHl*VSw@!EXLbyScMeqYbXdc!TZS
E^jA5T pE@9j6+hKV8D<ZmpMPlhHp8%V<na6*=qE+wuMGZh/ZNMqX4e8=p4edAJh=?y9ejFPRLmZ$cY5y/@yyC!
bP@\HS 9$6:dD4mNCcWDVu&MIQZlbwP\P<^ei=Jh>tSt*4pk/Tyh#dSB8Cpq=cDQjHyLl!Qp+=hMHB*KW?4=W#>
$yYuyM dFyR:J\Hh\@Sq6W@PFnenwmeyjk@Q$a@CQju@GG:Jd@mLuAdS6Z/m1tj<KFjCa5bhnR?/$bPkAmJjYNp
ZqXXXX h\hqnqbXeVcn8CHy!KF8&%C@MLW%ye<+HjyTpXh#?6^=M^=HRRXInL@*Lj*&=uL!$GcL@k%L#QH=SHF6
mDucbE eV9E#\Gd%adMq9N??ARnqiWFYuKSmR4SnbFwY=@Il9XZNh4eK!j9ZJtCGF6E4J!T86u1>ey64yq99&Hd
<9PHT# ZG:/jAnDk@j&>X=&m<9&qZh!6IIMm<iNItnEqcSc%LK85HHtd$InFKkE?^98QAu\\a&y8!bd:@J#^Sbe
\i#1qM &cmtaeZDX4$MKh/RWY>q8NJDc&B=^cSRinH6i1XQ?N4jbl>?9aD99B>*l&$p#<EaltZ=jCj<YpV8nQZb
-AE8Hq 000f15e89e100110333 Page 394 of binaries1.zip
#VSW:d kQM^\RHB=8ZLDNm#Vjt9hS<^Lw#a#1u9L:TCwXhWibyFKQk>hl?NR5pMXZ%CK@nm=u#aqj<4:\1YL+$:
b@Jm!P 6>IX/yE=W*TnmSlEV>+GX:NM6QyI6H>acXC?I^tkXq$^%VD!9CjC>%ACG@K%u>C^E!ql1RD4$+cFJblY
V=%E*9 l+SIL*+M\at1wlTQZ@eB=C+i8IT!8Kn5Tn*cR:/Zq*kaQ6:B6^$@%N88NQ1lJtMSAl9cwI9kRB1C4$*K
ebja&Q #l&aEJ>PyP:H4yncl+Fet<N&Jb/DX+Mm/eJPRFX:RVKERXcqp%ePMEt:MQMcS9HN<jNaF^R9@WtWFBBQ
tl6lDT 4l+E*CB+ec@VGXDRQ+Julw%uBeDTu#Ad46t!$K*lqCqp>*d\X>peXm1H/9j69?Iek*D=\E5J4ZEmQFA4
JaE?wD %#GR!8EXCN:8E!LkA!AbIjPd%@llnRZRRLR<TAZW&!bmmHPquHQ&%RCpkIlauIldF1AQ&n?6:Nh?BR^T
Mu#?q9 C16?MAY5mpH&aPPVqEtIu!=ZI%GQ/qn9B!TB^t+YiH^5CIALG>Th<6GEtAw%e8lE@L19h55:PDBKtV6L
+%+GP& ?1qXIC:mcL%68+XySR=1lYB!LyC8#HmX#Hm4Db!tAFqYIEDcZ$XFlPZD+RABuH=*cqjh^/aK^^qM*G=^
iMKRS: cW=kq6n6QKD45&nhZDP&?aKuuPXV&HWZdSw<yYLEVEHje\%Y$GLWWL$#&H^^pyaZu*ZKKYMdQIA^bjHD
bBJu&X +hHV+EYbCMLNk\$5X9dc\YQVhica4Vcu#X4\V8@ZIl>QbkwYLFYY*i/k5@qnt&S1b8RE#M:IVbaYaMAY
\I<wJJ G5@YPR5?ydZd<55=TAtK9$pa?e/D9T?e9@Ic#Xm?G+5n#C:e!l:@6QGG1S<WS88=1eFcDp*wQNa6YAVV
ld^BRD :/4%+9IwRTHu!@jDWLZB1*$DGG@*t:nYuPnX9qI/aZMZ>H8Nt&Qb98PQ#FLb:nW>>%D8petV^iaKItTV
48*wSN K8Z4*8P&LC<m:6X&>\DRq+KqTiWQ^:E^I*SWZ1#Z6lRP$+W:XY?WS9B%wuA=mmmtqp&^tdGIMS=a^=V9
&*W^nm !MB6E1^\$iD:*cYqLjwinA<e=tn/dQwmTT%aCb?^KqmEHyj$\@yI@G84a?KkZlci?Z=>NydX^L1qc&d+
DbHeR: WZA=yPXM+@$\&15\NyHS8d95LtaN@lBAJ4*nD$1MkIY+d+I5kwyJa##aWa%Mp<EXYbK&P6na\JcDJJQm
XRj%KK hWp44KqEu%cd4MybSPZt4Etn1K+5/kEkV:4<C%qmEaYnEA9LnGTnCitbn/uCm&1TCQZeZFBw#kqk8=Jq
e4Id?\ 8e&iTPakR@Y$lA+6/G&pZ#Dib%tdQNJblScuTDqRSI&tEH/>tP?+wJlDSycGZR&@\y9\#XI=>nBCdLV?
<BCX\d I4qLS4M>6EyIZP*$@F8uG^>INkYS8Tw$Smjlm\1LSduHhR*VX%K*Y<p\W5ey1j9J\aTId/R%/1Tp*$Hq
\J#B!t L?C!n^W9&<w=+%WdL@W:l@W$1A@&A>/ic9IZNN4$ChejSFXWJHIYq>46QqP49HbRVnP\6nK1pK15N$c1
$Sm%:S #5db1dT:GnGAnq64Xp61TM$Ap=GPwFhJSDw:cG<mbD/YAD@WX1>4Gc@HeieX<mmXyAyYNkl8CAmySH#4
QBZXVu XeY$a9c*%l<@&V#i^QqSM<KyM/TnQy@FN*mVFG?5Nm!iwQBTNS8VpFZ@ZD@nk6aML!nDR=YDpMPEy@Jl
K&RQE@ /9!6/#eV9GAVl?kHKS^5WLTHAy8^EReMYA8akA1nMWYmcW<MN*ViRkGK+<<G5\B?QFZpwH@>GdwTkp>H
mK8Wq9 1Zw\1u+YW@k6X+5+Zw><n/RCEa*mbdcCNkNa\$C:&Xi&4IPRZeypGFP&pVT#$eVc<1d9IF=GP!iRNNW?
HWZXE% cwBA\/eKd#dIK<nW*i9JtmSF%blWe\1BwA$CMIqI!hKV4%G5eA8WT*RkH*G1%YCKNBF$$ATm&WSkDwkA
>!Zd:S YjY*#AdPhw&$pu!\DnT&ta&$Y8$/S<T*QlP^F+qLZ+MW#6WLXCFJ*^$&KWk:>!Gpb1bCDGnP%BKdFNad
SLIPZ: CDMbK44RIb6m!j9FdT*Y4!X5ad9DLtblTF*k<iuF9pZDmN$&Hd\RJ?cm9D%X^CZ1ntGwnJnXG$VA/cQi
#X*c^C 1ai<J=m14JKNK$>qhk<5FTC>%<1+eR5/&8BDRZh&WCtll^yFjRQAJ4kIFdSJ@5^8VlF94eC/Pd@^=SQe
/e=e&D jGZ5:^h!++n$ZY@y!jmJXeeS>/jXKe&:m>i5uj/&mRG9TlDXh=FpL@E>pXw?l*+5$wcVI$JwwZ@=ERYC
/=4Ncm 415LEi9QjJTa!eTX#^P#HwRApcBZ&Hbdk^/d8IRWa1aP<eLBmmw>C5@XZn#\<19GKZ<BGLyj4WFL<IS<
j$IW@= J6DNV>KZJc4$w9=BT/mw64=^81EJ%6jk4RWhJShXDV#nNPR/j>BCI+:my@58c@akdiKE$Jnp9m=$!$YZ
%RCmdH #><VhTin+E16M%/G&L\QBt8N:Sw:jNMDKD!heSJiH5&GHX=E/aTw4K%F+&FTLB:uuNZ+5:epK>V91Xid
L=djwy :h%NEH\eK#PbpHb4D/uP8S+%dJtY/c?MHi#\EBF>Anwi%T+^XM?^tT5@DYbnTX*:/lHpkEJd5/u@Ed%l
APBH%S RiBJYB9QIiLuJqPH!jQCwjM+cXeLZhHQDQBa*F1@%d4J\kBPRWYea*8HZjyHp6%ai1a4/<tBdC&d/cjS
<CAS%+ GY$nw+uK4eS$@Z1Qk>\ibpYHe<XiKVb6n:KkDN?\Vpe&da!=NQ#8nqinn4$AIQ=&?/Yt6*W+NdbE8?Xm
b8CDd^ G<5IXaGma^FKpuP@k>!qI?bylTGNnqKHGB@=/+QRaK58DiltW:CpR@H>9Pmp%\jdHXpaE*FYHtnV=yM*
/P$YCN PwyyVt*YPwcGHhG4AbaClW6jm>ypt4Q5Z?amm\@pt9FXieNht8A>1W+q49JS+BElBp%nMPe5jH6DZ!j=
>9QEaC YV$lYMC\<qP5a/8&:/>#4Rn+@#/=XkVm9!pSC\u@1$R5JQVdE9G@C%S@?a*kV:Xm^E?WS\VmZ>ViZ!qw
iI4^$a k4>B<<N?SR9>#4q@FSNFCQ<PnjlFc\BC=Hhw/M<:RPEC$D?m?j?Il9$GLTD<K^4?S#Vmn?njtVWB@q><
984pwy ^RRE@+kY?mQ/h&aNkjnFuA8I@Ap6CQ$n?uhtDj/L*Y^\Rhkj$jA@wu>u%8C@&IeHF^V+I%4\n?njtdY@
4Cw=Y/ Fmn@uBd?I%4pV&ml*=p%&K??u\9^@^EN?!Q/h&d6%$cTEPLQeIF@hyIRmQ@5JAuClPkF@9IJ?891!d<:
ANhW5? TZ?Q&@?dp!V+E!jyQ&>%@Nq^@?FR\jn@eh!@t%J@QT/CZ?lu^^Z/mWMFk@*GNnyAn#qcN^+9FXmPEVM^
DF$aDt l^1QkS\L+%^Enh^YJAKuKMJ9#aPZFkja\=<daCeaH^NCYEwLHTGAT\@KK9m%^+kRTk$uE/KtyaHB/wW>
FWZL8$ kdp66qk$aKAd@!ll1ZN+b#mVay>TGZdbPEMVEVy1\Jn##5j%IJ#CWwj\SJ8AWyNtKkkAIw@^5VBNHDMl
MiY!#9 Fwmwc!i?L=?8\14dYn98cjIC*NiV1aMtGhY9GPabPMd6Bp*XP5naZ&R*\1AE5bH6S:!Yb1u6GdEIKm$$
ny#FnG =KjGk##/tNa:$pkdBVE<GuK#j45W:bMjmH:ZtH@q8T>G5GK!c\$NPC\@MKLRmy*Ka+A^cR?XKyD>eej6
aakA*! LI/QByD#JaTCV$<ytu%$Fl*F#wJBlQh1pi8H/FEEcV**CJJ$8RMHkWQb!AqLwC:N!:BKcFDQJ1<wH/=p
\pRL<X 4iIFjXWbji8MCj*iJIp5FRF9qQaKkkw!JwXiBTJZSeFMd8PEiPkKL1VC++Rwhm^$FeL%i*EZuhV6m85T
H6k8#a ?ekcR&STGMQ4aew!>ACHh1/cbNykiP&F*Lei!RBLSkF/LX%P?jGY!a%ZVCyPT\JhDSH<A&M^+\89tQA4
1Z:%:J KWM^k?$Y+^JQ*WkFQ\b:C\>CTC!Elb^D$hdGi6lZTMhthw&EBM%nj6BNnq56!I@%IA\WJ:%R!^8V$1C9
EiCp*$ !q11@1:pP1SdiB>ntMkM:4i1phSwVX?5ZBmEp1bTp$:1iD>Sqd8wNcRK^dTcJ>TAmJ&bknR?JY*$H:WS
bBPLjb p&w:Q\HICRiDnYHCS^GTLmJ1LiQ\Q4n#+@811XmQnq?jdJmGmJCkSW!Q#GBi#eY=Y+bd<=uLP4Kd8NDP
pt9Th4 BeSi?qpe^Jq:Bj6XKjl=>LFLqnySMSCd&RR!<$4Qm4C5cjyq68N&i#Myi1nE5\L^VDqViPNm!5?l8$d*
tKpMZI iMMIR/>Iec4i^!%P<V/@V@QKN&m/cjlpFB5:D^jCE+M<D#Blb&Q@!yRAXRlcTN$!WLBK5m<#NW58t$l/
h!c@6y u<%LiPXNGGEJAi+%?$m:F1D4S%?Q<?I!S4WhGwbp$PRcFw6ZdI4R9W1yY%/#we+%&8cPQ<#MY54cW\YY
4%PC/C V16IIp6$=Va5W%uji>:PW1p8W&4IH$hu8L*58KN:L/$/!=e1=6^RyZ:G*PG\bSLPh/FL9$L+yHdnW1$y
5LJMVj iP1hD+%9VTlJE<D<C#4!ELcWmXqFE:PAG6p/quad<A4V/QnAaK4Pd5$PF*w6QwJ+e1y^GKbNDqqbpuV/
THGbLb 9nPBn9ci+u48Yi$QDZaZWH!5Z+b&%EM<hmGkm54qY$IL6bichMDh\NFR=GVVT?I^@**$c*c&=18W^^<B
/GcmSY BE@w86u1<VXia/5jwu?6^Ay+n\P:<D<$4u=V&HcmkYNy#tjm*S&injheDCtHDJS+T/kBYGM\DyQq8K\J
eA#4Mk MMic\c$IS+Z?/NpNwP1yGFHH!@^iuG9wwtHSFS+he<D%?aZnT%I^TF+*eaFdL=&FAl=iRDpdA@aKuRc*
!pwR^8 Ne46S4CkNm+iE:>LheRGZP9qRqQIZ/?>9jYTY@?!MQutyVwBn!SGn*G%WcEu\=+Z6T#&!l*y4K*EaV^!
bLiFIn H8E*iJmnn:RII=njVldn/TL=u6W**\ZIbkKbqqMEI>4wkG54XNdecjGJcG9Q@VbaE=JMwiNte?XCWS:k
X>MCPE BM?uLnu\&8%h$#GwePBtbFumd6dNGELhX>PbkKSplVSPbPabeJP<kHV!6htmq@+MW9C?Zpk5SNSFul6A
*Rmb/W @S#:G^>JRRtA+=8m1BI/Al&4VFlb\niu<Q6EYk8>EVjQ>9nqS/q%5bQu5$D9wDDc:/4=R4kMYeI>FKM*
p1ASlK DPZZ94\Y8JLTipVcyA4lWdEP*Y9d6DPNnCbwkeI<QmR1bI16WVG+yAN##PWdqPaR*H$mIK1HQP*\Vunn
1<JW#/ QBF<<:&mJJc!=G!^G<N%j8:cemAA4iuiLIYc$//AjH=>ww?Tjke1d<$&hAd*VFd+wYE\YF!VQ*hhQ1LB
PmBX$I RCNjJNl8L4d:<^CM6uFE8mGpSGIQ\#9=G+p1?$&iKuTH!C1#Y6S4P+m*!ECjXTDH/^SCB>?dycZ+SNCk
c4p%Dp Ruc:FAX:\X$*wEAaNeTP#+CRBu9+!d$Zk&/6>A\?mjDF&u9@Pu\=\1#^Ecm8<%:j=6NP&u&JYDa</Ty4
\:L<l\ G4VNWG#l/Q\HA&W$511QD4IIQ4wM6^J+XCZ+6p>hp#=HQHSnT9G1!P$5MhcTl6CP$imRpMPjQ>#Bt=L8
u#W5*X ndeFEWw><5i#5tnLa=&TXGT^D!l8&GRh#ilXjNY6RCnJIK!1=641GCuCK<DLuSSXNyWlSqPPNRN!>?A!
%86<9Q pDGtmZS#/P6K+b>FG$HdiKJjwi?>wmcTbFhHllLbMe$!1cl9m58k^#Qubq!>qmW>*q@w4#hS=a^pRYaZ
<id#^% A1%P/TtRybSjE9\Jm^R<CZX&*kPK?k=TKDk4cPXImLnYde6i%VBIHWbV/uQVlT:8ZekM6!w:*E/dlI6K
<X6wZ5 lN$W=VAK\EI$9?hm8**Iqna84<JYRYl@d1I<Ci*P%L?lGdiT88WJ$#aDd1?!ZyHkQHmnqhC1iYjmpdRh
-A\Y:5 000a854d7e800110333 Page 395 of binaries1.zip
G%TmyI V:%j9%/59WQlYi#F?tXawMau#b5Sap!VpZG<aBG&Y\Phk$?9P6#5D5JPn^Dnuq*JBEuJ@Ft9c8B$Pd+b
e%k^KI WYY&Me5+NN:IwP6<*8yl9th%Tn\Qy8@m%FDXn655!ZKc#W+h#BkW#kIPRQRBMBpe6S@4mL8X>=KaVD8a
KREdtm JC6I*cwMN6!\VZwLZmtX4y\I$VklZDI9blpZYBeeV=#!a\>R9kDYAjq=%H#LbdXWb>M=9bJl*/P>A/u$
=%:EHP ^Yu=<::Fd16ZkLt9%ecL%l5\^5V=db%%PujS\EjZD$GXVhH*8k?hZ&^la#VXaw1HWd6G\q*=Qu/lmJ&P
IjSE?a 4h*&JVZi$hMT/@W61:XYBZa<KbwP%@J*ZdA%&KjG%T$RmiR>$jiJX^i^L+>c^cQDE*yjtacbiekutDqt
Jm=u:! \GF>N&=dK#Em&?qS?5T=BDaE!@91aGR\?c&MF1Z^J:/\8a%p@:p9Fe=?$lHi@tVHh^$DQt^%IC+P/^+y
%BkbQd dIDl@uq9GA$FV<k?*iFj+9G\uX<LJK/E44W/:S>@>lMZp@K?N**EWY%5?y/\k<Rt6=tt!FC*?Ft+kN^#
GFG\*> ZY&=y&@\41$4Pa*wXjCD4E<ZTZiblK$?DRch^c?@@SA@>ZHuYSYb1idu+X\V<J91ub9yG1e\9Q1JG81K
Ek%JE* m6PFMiJHeh<%Dt+tbLHGeqhAHEwh4n=!l\wjhqa*HS\^HIa#CqiNl8LiTP8lSjmB\9huI@^PLSa=uNea
JHIEqa dKB5QaWX\d1yydGaMiT=w/i>5bhd54RkG*?kheJS!HtXRpnwmFidue^t1YCH<?uJcX18@Kb5iSlwj:it
9EGR&+ >FKtYuBm@E%t+d^cL&W1GuK/%P<E/iCmeqWKwRTylIB+IiY:</Yn/=j+h1wP9eWHH8F^ypaVGD5nRY?W
5qnQpT mh@JCM+M\DSGZHGpnTYHWGZ^TcyDX5E88$L$+@$E:dt&YdQ&K1EXMKGNCAmBZjNATQ/SC^N9d!Fp<IPn
BCdZVD CTuHe%Kb:?cVL?bP*d+W#YFX%Z5TiFReV>5y#H=R#>jGLlYbI6ZGI^XhY*9Qwa=*ML<V??bEnVB$hQuD
?DQQYC <Bie!d8+Ck@^iVwlLyAlH6M>96KBp*XQuqPNuy^!A6H$?D1C<Qc^8tmeub5$lThaC6Yl\&HGV6Ea\<5t
jS^16S WZ%w:LKpSJiQh^>mcVl=5uRAiFM1&a$4E=uV*aekChRHCa5Vhk>^iyWBw/!uFcW>BMR>D44jN1Vm?lh*
e><uhI A9cjFu=9nCX@FwhQBHwBRX=R:u!qQcc<lEKYS@$R@N$QI9#WXX%A69qj?lB4MBY=w&BGM?RZc:VQ8h6n
j:MS<S dQu/hne*$!^wk%aHa+eqdL&VC4HE>cRGc!8*LFl^PA@b:YSTtRtFaN\+QcAS%<tStqp5Rl9i5uTt:5?E
i9:WVM AYd5Tt@G\Kpe@InbKmeWDuAc&t@a?#$PyD5Hi5@qbMI%uahP:FDpTME/+R&bFPCAcp:a%mjZVXdmIWQW
&/n^1& h6ZQPCMW!>?AX:Pq*4EtPAHR\tV6@CcIp?K4QkN+9=h4eSyYl1#F%>G+!<mh>#IHwHd+/uAHL9C5cjjX
+Tje>P &J<%$D?5ja*PyL8^l84RjLP4=RyK\J4m:j$K$p*QScaV$wi+liPWZ1w4nMeucIucbuNZ5w8=k9nXCZ9W
&I>?ad !bp>!Rh/G<<B6/4Ve4L%RX+:%*ppkkAm#9mKLNp!<kK8:wM1Z%:REC%Iyk4LqW$#u1%w>lGQP>iiY^^^
m!/tTK VH@ai=mcAIi:\\?&t=5#NQ<GSj^>#mu4I6G>S@Q%Bm!DkyYlTHPYXNnk&61ySC1YQ$JJ:Lb?>LVAuEiB
!1mu6h mme@bYLH4W=qlDht@L9>CS@Ib4:CiIH+XuDEFc1J>?LTAHwJ+QjCt<SiAYqFjS/WMTcwE+V#$W:NWdyF
N$:Ydb !mtBYWaNhiw1R%AtCI:t\p8ke:IGd4t#eIPS51jy5<aPaVWGqk6uKiauRqy?a%Nn\4lQ!$u/%FJKEA&y
+i!Xq: IlG!/9YSwy!YapwQPeQXa1LAiNyKZ\t@u<SFwLTGtAkkQZ!ppmlm=S1/m8%Hwn*XM9E1Hjaq>*m8\YiG
$:KR>1 IH=y81wHGHYG:eq^q!FL*F!<i\/5j1W^c1AG8jMyii:&IKjPdP$u@NMHC8G>IlNZ9cYlakwBa:6?CjTD
S?/@#= k$18iy=KT:!IaNpZT$jA@6*?+$%9n64K*Rd@uY1:K5+9KBlR\Q5h655:&nHKb%Y$=YAtE@/*lP=89wtk
hB/yD9 KFXD>d%ujQdFa&hT\y#IbH+5Z%J<EI/tTeB&qENl%Q:*T9wlXVh#lJRK9=p4#&W\/+Y1Ia:e=nunX/Ln
jkV^ZK $Pp8#tda@PpCtnh#qe1tahZ%J?>Tp\R8Ky\8$Yt4Ai>5ZpFM\p1b8y%RI$e>KG=?H4SqKeVEPDJ*tS:b
6c5=!J nMCp1Z4/KML4epTXdFC8YVQ#\SWDL+1<:@V/%WAjNkCA4ZT:A6GiP#wXRWqTEn#D4TK\mVA^\c\^XVY6
KdFIi: WS5F8c&@QGi9PZltQ8kyM1b8etJk+XVbD/F\ebFE5!%:\B::\H4P>hN>HtK+8IDeYiyDb\I$R?&4Pi@\
c+ItJl 8=ABPG1$9KbR\=5%jeTq+V^Vtc#>+JQKA\WQ4Z&REd&h1HZ?LP9VZPpR9iNBa:Jw:yMJA?IFA/jiVDmq
\=+#b# DH$DjuJ9qcJdRmlYYV4hy+4c@eRbjwVE/1DZaFEBZ8QpBnVV@bVc&K^:5NyWXyY:Ekc$Be+jRtSiD4aH
GZN!VB ?4#&\+t%nK#Qh4QBJuR+8EJ:M#Di1&GLYdRTn?<C1h#VWdWI<Wpq=e<^jFY>GF+11?\!*Yu+ZJ9\=SF!
c=BV+u u5#1I9d#E&XZS%jJ^?4!mBdBLA@FRBiQjV5lS$?5^WJn<Bq4Xt#ul&lZWtEl69uWEDYeb<JIQ*&bLYjh
S:L>TD F#Gq5*Xt##n59y^b81YuK6Y5>Y4+!C+TnleB/HFpV5=!&p=*\<j=Sa+%nHkdDQ%CZjmcIB8lh>lqcSaX
aSc1X> PbX$FAnJ#G#X:YZDN8XCLn5ZRu*SBaRJt!6p8ecHwAHDC+C\lu&@4:GD&ukZcLI4%<J!!$t&Ic??PRtG
48QM&u njbKndpR999E+4A\jK\@GnH?<BHwK1Z!6M?F<c4Pj<1QTa=DGiP1!&Bk=eA/QXEyMSdLqaM#ZDt$Led=
R+VT!5 ^mVb4Cdqp&B\yKFDd=W1*8Tu+m*iNEGdZbh?Xl>GZY\k%CHwpq@i\#%j!lEwa!HHdqqI/&CBt?WpVL<i
RN1uJH tw*l>@Pm/u@#S9:Z^j/FSQ=:uk/C@%@*8TH+j*8j&><quZ<YwaS@I6+Jmj^#nVL5F>KjMQ>9$L?$ewSl
QP/uAC 9$ELC9/Kl9<SnjknY8B*/F>F!IWF@+kY?mNc?DhwAcFjQDRkLQIu6An$n?njtVWB?C>5JBHaH>H\Q/J@
ILmF4% b>aR9>l/CBeS?CNc<I@w*=p%BQ\ZBymI<B@SIu>AI/C@M&9\Z%nWCCn@H>G\Q/J@b>d??kDP#&uEH>EC
FWQBS? j$V@#1#>hSZt#&tlQ/KF@+n?uXtDCj#<P^PCH@yHNQ<j$d<#c:BjQL/G+Ij@Ea*+I@y*b8&Z:ltC@*iG
IN5KPI nS@?1=Q@<$dX9:Q@\/i+@t/*@e$n?@5nq@@=8D@d1C4$q+@?9@5y4l+$dj:%8tAeI6RJDp<WZnmDR1MH
yRI\Lu 8>CPuMFFYeST@pTtLJP:=IRMkyRcjEQpEwQ!RtVH*ARmA*Lq^&N<APmKZ1XKIWSPucW5NeS+:YMDmE^R
j\8!PG uLI?wj#&FbyP&+k6E?nIb%F&ieia<GENmh*m61y&c!wWYTMLj^q#9TtyZ?jY@cIb61aFw\^q!LAkBbw4
8=/V4d tJECIVlP6E%^>NcAF9RaCq^Je:VS!e+8cSHeX=Y:6wCwn$w9TMFRduIlWAI*SCn8w+IFhXNF4#Ey5BcF
Jjq^<I Iyib!n?qqW<WSpJny%wGCZGuW8\+lc99hVdBKn\p>n8I5&V^tajQlcu1V4IyKi64bqkVacPhKDaER:I?
5B%5yA IeTTjaAEPHp/LCw#PdkkDMBpQ+?WGVQ4F+14E4caGN\k@T4Y\w<j5!pSlXFNBR#MZtiE1S>lw/u$IQau
1i^\Gq IZXtTKHaL4RLyQVHFKuqytAndTw%y5E6$pq#cT<K^WcL!VMqnmk9tpd#NmAFWDLBdZk/@6&bCqJqep1u
qFn4u: KYa>YG#R:SaCK?*^R\wdcpmLV5VNhQcIA115M:ZGJGXPhDWInc<Ihe6q:=lyI4KB\&I1wb\@aLZ+eJT&
aE4I?p NyaK4jVw+SMhuTpBXZ*+y?jL&<^hwYFBy1SJT^anJ&QH%^<pyRPFa\1<B&#XtEDiwnJkddlGZQQapncC
+tiWa? XM^mWb8HSF<a>aYWk4SlEeece?b!4u6%LduHiQqXc#@JHbMWp^Z!1e>^dHCl>XAhMZZ9+lRAD*HR+m5h
I<=beb ZC#8SMHT5T%L#SH6Ec5wV=X9PqaJ+>dP81J$jpLk#%kL>&MZL$@=n&hqy<mQqn6e#14GmhXNT+t9Hi91
*VTQq/ 9c@GS/QTVCAFcq/L^$L9+G<mja^j>*<cQ&pKR*>1:tCVGZHw8pEDW>GXlwpKJ1JJ8lpZTM5Ct4SMX>j6
F!heX# a!$Dm+XhRQPE1phXKuPC6jyd!/1Q:kVLGFTSd4le4+blLI<nj4kG:GVwq=Kbt5j^%N>@:?t1&unQ^/C=
c%m4da YdBa@M4nhpVYR!DYT\$BEl\4i#YnkT&DB:+uanZM\abY<ma#8#9ee8^M>i&u/?<+CSckT8@CVu%I9VV^
et4QHX Eum@nLFc6\yh:VXEBT8tJhl:9<++cItAqZ/<46eLZ\M&I!<=hkWpWauJ\Q#^5L@9S*cJnc&1bdN^#XEc
iZ@SQL //jJWuyDQ!@w&mRuaS@ii<+VVbACJ:@$DanYp?1bbCi5utYE8C5cLZ#+#y6iq6/t6WqLa@QEqP:=&/!i
YqbFMd aV<WYwBw1b<QqccaXRTw!cNLl\w\jjQy9q4b<#i&l#q/tA#cNe>6i/=<9yw!K?k+aRC=4+lIhA4n5hBb
Hp/dF+ li+96N%<nK\#Pk<F!&*LBG/&BeGQl8+M!/%T4yPk1ZbX*!iMSC6/TS9mQ>XHW1:\u6q54#LR6S/dp@#t
Q?WCb$ S9ZRGuXG=DFKN5ME68SDRG\IKm!tQ+I$HS^HlZPJ#Y#A?aY/*1/b4Qi$9bwa#>*>T8tkXJ<Xh4T^!kG+
/IwJ!A hLa1aVe:aC9m6HKBtV+lVW9$RwNAQN4JZLhqN*%MlD+KR:^VWBGWaCk9&<k4YmXCG#&X&KEREEmcn^WX
Yw4/du &NNwKyCANc?^#CV^HldQyQY6@w*6#hlW+55A&JBM&ZW4+^KJTlc+&^i+X?=H%tPpy*aHB\QNCn?\TDHp
T%<I@I aJ^dVb:q4t=9H9nne/e\cpnYul?:#XlZAJJEM&<Fc?kJtJF>a9+=tX=d899l*k1RNG/dcbEiemCcXMCp
\NiD^c @=\5clcWFENim#9>nTcp8#k9LEYYW*htIn<6RRecP><!^:n:^NCYKQJb>yK+P49%E\$e8yi%QVe>?\IK
:GyGH= \N^N/5W\VmNt/wE1F#u4?1aS*RjjVGP9MP:eF=:TDmaXSKqkpJX<1l>Eq@E&4y\C9F1Clct58ITcl:%@
%>!A1d +/MWX+$qD4wmd%AnP<E6YtaXJQ:!Mu5nIBan<E%%:Bjlln&4<QihL4G18ET/ZAlu1nZ9y+QVZllwk?PE
Pa/1$F 6i^cT9*j=t/<@Xcq5IQ4/eh4<e8WAy8+e^!Z=Pb4S/uNeJ5j+kTRc@V+Fd@W/SF\c64MtyEyi?GJ@hTB
5tYII% B9KSnCne/eAkG@9atX8pbXGNJC=HQY4Y^JP8*=aL#YjY\H&cY6HN1ewwpe8iWP*tlKaM!y=:BM8Tj<eu
H%JdW# md1<BkB9TW6wik#e=QA5eVQhy$=SqD$y:Vbi6k!dGj/JVMNdEKi%icDjQanqmpTckL&E\CQNjY:J#D!h
1FcQ*H c=Hm!TH*5X%%lMJh<bKELjdNy$:^mXEL%IQP%5b>mREQ9+Y&CHl+p4&LKQ*Ew4B5X+NMW$+$>qtXD:6i
-A&j<& 00084cc7e4000110333 Page 396 of binaries1.zip
l*qH?e Ipw5@J#yh<PKdWKp\kST:V#A/JpQH$1dX?p%i5kF:wSKalEhBaD!N5#CkVHncT>THE:DJ1&#Cje46Kl\
ih<uQq Iu4Rq:I9@Dtu@YRdD?ViiF9Wd@FphiB8\5Ij@RlAS@MB9a:NC:/HYXpS?l+pPY@KhFlZBXYdcFK^9uLB
1B%RCm ?1H#cZ&>nVl$jb*HW9ewdi?>S>mhWh%H^XjH*\^VbY&d!:d9tFuR><EjKDi6GC?!Z1/=b#*%MDD&ccRR
YI*u$b Zhhb!6w4>Vt#pwdaMGyH4L:Lak6<%j=>byEuJ4RVXd^nQGM&/Cecn4%El:HG5W/qiYyN9$ayVcNqRpGn
#&nIZl >IJY>&Q1q1#GAc+F1:QMC>=Vn4*!8!!Du*S#QHjNRh>i%Dq@pc9$jmp/Q!=wW4N:<>$c@/6^Vd<R4=h>
uuIM?B *dd*DPVp^>QGmLFtqKq*$ERRTFKa>E\RNNmCd=6@/VcakJwkd/FTVIGXhG!ASmSNKPSa=aReKF%jClm:
KyRiTN cW%$Su%p8m&S$*JjH#<eqFNLCFYiQ<tkH@Ria$w\Zj5</kX#c$X<bbZlQy^<I@VwbiRye:nXa<j+^8!Y
X*Y+#Y eAN+w&dqSXV^@K5j8t:Nhc/=#/qwCQ\V#6QSAy+WTX?%F%F=Q&I\4m\+y?XJlB?pb=*WnP?y6:4A\9W6
%&&E9$ D1k6tT*iewwKAlZW&J#W/I&VdY<i$<?k$/N8R=ACQYaQK55H5hcqh:!5R++%bRq%cwXq5cLWtQ:cJ!Wj
QK65X$ &\JJpA8%$EXY4aTFCL@9ET+G$P8maEK&>b<1mE%nHPc*#4W+yA^/:XSb$abe%1#^8ZDmHQaltm*$c%lA
jJWSTm uES:ZuN=4I&wpL/k6a&>N5DRt:cB\i\aTw=wZRC*q#DZ4a@e16w^Xp@yip@Se?CGJ^kNJYTVAV@1NkHS
11%M@M h#9BCp6!yHu^JB*Z+Kj4kynC:\eQIG5wt$VTGnVWlpPRYC!$NNS@Gb6<^<pi=KLR=QBC%TF@64\$ldP!
+*=R/$ ^%=JB1?=teeu%mdlC$F6RPZ^5Y#WMuA$Y6&t1p?m*YG#*hy5eQ@<#jB%#Zmu<=p9N4mqN5E9AjwW=kaM
In5/%A JInSHni4h*QLe%hK^dNw+LS4CCP@/5ccMZMDnmkh&:6n:&nue8bpPkaaSn6+P8I$k*%c1@\@qF?48p>4
^4QW<! n!uIHumEHXt<14p$PLF+E99/4y9QX/:!VW91YW#aGw:ZtK5T/Al6YFHa>8^&Dc>=6iDSy?&HnDLinKHq
LJ==$C <ey61L%QVBFBVZX^hS1>>\tDDFnGR*5lbmW91WH6N?N8%6F<%LmdAl1%!ZK4PZW+bplW1PMYZpX^djRJ
JbIaBl hdF@i@X=ww%wQe>4Xmi<9Kn#A4:d5&l%Ep$<@</X:dllZ&\&^y=Hic1$XubZy/jc94LDm!ih1LW%<PHN
yV\Z4? Ip@<ZX!4Db5tanW^^@YA$nM+PTe/jR>me^ltGAWS+F5$4n$$AjRDh1>pC!FVJMRbSC?$#FdPbKuIVyw6
LJqR=J hpc*a>88/+Y6tL$my1YYtBiH8N@#1\RkV$&6E?u*n&AH5kEHeV=jK>%JCl+#1FwmaMlB:JRV#5GtNe%e
MFFXtI XmQBQS4BG5k#D!#:&m+1EGXCpn4>/YmDyiHVMhwnV%DmiXRD5TMuWTl%tV+Y:8a\&kBC+jTYNi=^R>kH
mmmKS^ aq\T=n+TG#nq/C!w?kX19+Id?HVYjhGYj\X%+tBikb^^qKe=Q:%j=RduKY=SQEehYIFK#SLZ?q6L95<S
PqTI!+ QH$Rte1qePN<Aa*i9c1\m$ZZim5wl+=kY+\6inH4+kq#/$Hny4dpy88GVp6#$\pFdQa!8jKC>HmhVDjl
aka?tS $dT\MwH^D4+w:5pcFMS5Da\q<Z+ChTK6d\%bu&?++b>KM?BhXKmI!m5m+RAR=!NZRjuMLyEu8JkTNh5*
Ij1<k\ 8@TV+h6QjYab/QtN9/I/$=WY=GP?!q<GnaiYTR/8dF=Ka9b?plm9IGdDF&D^u*FIFcm@QNnQ@RRMXW&W
$!ij=W WT%l%dcGRB4nQ9B*ae@EM\?MeeDmhn*jWlNMmG=bnQV?\QX+!AGB$+DV:?QILe%Sl*nVFbZQ+@Miah9w
I^5IuW k*P:R&%QnR4XMlQ>+EihPGbBiGnFYGkb8G6l8P:jq&8%P<jYjdZ/dd$y?^$y5HQNFT%l/TH4eb+=S51I
!C&P^q *H*mAw+6<E/deXQqP=n85I=Fp8Xnw#JimBeB%WmKBk@?9R9anWC<nGb^E@#Yj&b=VN9@>CARyaYnG>*Y
\=u9eS !pEZBhVjDlnj=qPYk+n&%i@&k$mB1e@=:Eh><h9dPVcV6pAQ%W+jjtwWKnt%p!bC!qyy4S*eubYY!#W*
NBXR8E 5NWGYk%cMptdS%@Kci!CC:TBIZdkeu\&C$Y&$p#EEi<BN8GBhVkJ8Ww88idB<E9>mFc6AEP=TLZY1hIG
1m%Ztl qR?R?n^D1/6yudcF*Za#Euy:#$m^Mw<QX1QuwXIw*GQ\?aSP%TN=NdS#SYu\q14E\Z%6y#PNSneD?4DY
$&?D/k ?6qbt*$6/#S4*W:\^FeiHAFTn48p6keMbeI!\CjeMjE14A=#Pl>AtDBRHI>T=<4*Y5J%!HZmDpJ:Am4W
S^ltj\ qK5XQ@*a^T:WQmjIcXwkdZ4N/#=b/R>PlS1cV%5c@ZAduM<&EXj\?CQ\/iqd4HYFm6i?C6iT:5TQYDQi
LyywIq h$41DF:=NVuFY=6%c8jcZwH^EXbP^EiPmeumyB==Zy81TXN<8j%D<PIlkWZnm5*4lXm*VZKebB?lRp8+
5MF!F: P4GHn>!Ib8W$cDB>j/Y?JkyX8AITGupK%B@mD8hpH6&Picbc&4b>@kkLHIa/IlYajbF+jai^&CIF>?=n
k1QWQ# D*uP<kXDP?DAXu>T5WkkacG^*dyW#*%dXIN6XBSdV$lha#J611ceSweZKY?FH8h68a?CA/6ATF^6RLq1
#HnBN# nhAVNI$uKN/M#\cP8l8K<P<X1MJFabqdXuS*49jMCAc@MJHIWVFQc/Sl\P!C*eGV+?J1aV+ZT:mp1w@c
>N5I*9 t5Q:Mj@VPQ4YmI^uTm6SkPHBpb^4q4Ka^WuW6X\$$X$cAXpcl$Tclm?\lGEtDbCM/p14&SC:5<Zw\SF*
#:Y=!S u/CYq6>%Z#F+Z5a/iqMhRy:aE9kE/TcZNMBaI*lh6:J:9GFKWd5k?EplD8MM#%e!aQJHNdjqcFEW>9eY
1H+dy= A9@>lByi%qb#pCpd$6tkFeM@\*mA%M8R%F>%wZPI\Edl8EmlnBHFI9km:WLwM%&Zc4=KH?nt1PXb5w>A
5D^um= KJyY*^jQQj?HS&*:KJqhD?N9Lc4E?mm>ij?Dyp#%C@NIV>^+eJBHbQw#96X+F=/W^kuH91V4Fl8DTR%d
pBH/e? aMTX9FXMWTuIS?#e=TIynkE:PYXNujn#?N\h5M<uuncZbAi6LYuG#AE^:iGZnRu?AttZHGu%^jn&ZQ^+
HtM:Fb k=L^8Wm&u66??Y=@T>nu\6P$5NX%tWZL<1=p6kcuLKcknD&@1+u<bm#DnAk*WZqH4%9@ke59GjSQZX<K
/j:>*K +^6?W:BbbQjN*&Eh\&bn\1Jk+dJS#cKPHZ8CuVnAy++j>RlMF=uYaamd5HtYl\ZLXAk9ZiaRKY4@N1X9
aMiD/+ hh#:j1RX&#EM$akVGS59tW1S%WN*Z%%c4jl69E&%mBR*Z:+MeJ/T*p1PGRQIlPdE6S=&4!i6V=YZCeMD
BW=aWS tu@KnIttVQthKb!eq:<N!tnBa=F9i6yZF+DCceNNKLVyCT?wb$1VKCDpqA%m&kyl!8bXRZQmM^LpMBLn
HqA?#& bmRYic\A^b^1++^SDk&5j&&Ije>W\5lCyPA+/qIBVl@?LDlIL6kp:18@Te?p!GaLt%J!T:ekpN/Fk>EF
m!KaP6 >VmDu$cCP#89mWc%LeAGtN<GJYw9@hyaX:A6<6wYP>?qK^nt#HpakMe=iLkYedl8@ylb+@W<y\^Dp=p#
K$!+&9 #d6n=1C%@1DZ4RY9/^@4?p6JAQPFiwG>HK>%:\Y6@N\XSjD@\j4i@/aXm9nQ4j5@6WISCIGjYKH@!LQ@
D:$<bT B!9$@&yF?!?6$H>Z:9=bE@^Jnj?@ZiL9tJtIu>V+@!9>K!MX<bMY@*?qj&XHItCIQ/IF@wkY@B$c@m6c
!JhCLN /I>w+V?mSZ/DFlD?lYZ\p<//@^tc@+@w*=p%AeR9LAM+@I>w^B@S9#N4CPFj*CX\\V?mlj/I@y%bR!D+
bnMhy* j$GL@AtNkQ+S@V8#>t8nBRH:J/9p:@D@!C4=^^NE@&cXmQ#EK9tQD%4@*T4=&!cY@$NYlE^RJQGt+1KC
FE9=Cy 8AjJ5LLuAnWiwkKelFIGtVWXET=/QAC%PGkEWcEpia^ea$>k+XNyy1TlZw#*@9VX>EJ/G>:<dwPPkPCk
VGV5X@ 59d*m\PG>NT^I5GKwHwVHQbS?I#TJy+uV4:/@w55^GNn+ShkdEHPeM=R8l$9#p?J+hQ6AC=<NLML:kDN
ZWZJZN WW=?^^a4!qDM^?R>p5Ep=IIA1MWtVXXF%mJCe8S<Z!k8YGGqL?anYt+Zn:JbLtpD>:9CD^IjMVWV\lmC
Q8DaBu qI+SZht:yaFK?WFVZA^SL*/<DY#44\<qSF4SAnBqPF6C<N&5RSBm9&H?YP+MM%LRmNJH:nDN^YEaFmmH
Ii4ue@ u#8$6qei1FT94+ED\C^5J%Yy#&pXGTXi+WDWJViPpJi4$XT?DZQ\m@lYmiiQ%<C9=ZWHu%HcT%IpBD@q
1uKQK^ WA\AY:pAnZktS=ACym\SteXq4<euZyW4iDKlQI#GyD8uFccWyWp+9+GWG*A$EL!%8bc59J49E1C^iTyR
C/kdTL YAnyJXT5*nHkI*<I&bwG$eRe1ZF8qb1h9XRJYRktiqn=@q5cmSS>XJ@81ePP=R^$XF^WW<>+9ZFA1*C$
=Z5hMY Jb+EchQCX&56@tkYkTtSFIdicSFpyL6Yy1<A8$Q+jdC:cJSBEtX%=^:pw>Km!BK=#y#Di+E^Ad!laK?l
SFB/lX iMWb5lMn6bHpiqI6@FMWNMdHiWhC*+eunlApApWKk?CyZkn%V:TQJe$SkuhqFVGj!wycW#ndQ:cC#jt$
hcci8w A<k?Bj1EpJ6b6aA*TmXn\6^5H8ey?$Fm#4YH=q#m?<9\dtQ&hGJTYSWu/\*5>pi<R^<cJquj#c+t4YIY
Cl:mN\ nVu*iy?@jCPL&%a=mdLNjN<K@YBSuae&qF9@YLD%IekJ5TLCp6:!Zy&ZMNji?8Kc5JVM@GN5N?j>A&n*
WAm:?S QbDR>JJ+D!b+C=j99hKMD/D%/S\Fc&VD/HMii>kiE%DTX#jJ/BX61L6<LVtVJ%:1C:&w:aeCJ!PLC/HH
aLDNYp QewQJ%H<wLjaXMl*a5<1$LlE4T*kMe%F<cii1bP4J4NjBpFq5a<VYVb9En!M@QEBn$X*#Cw%l><ctuiK
JALd%5 NwiXQ5?NbuGM@#bi:d6eSN?IG:S4B1@^9eCiNIIHnVA+Ewcd6uRF9%NE#^G1<+Jt*6$wB5WuG4+6ZH*>
N#Jm^& RP9RH%hlWM#V4w8TH$PaV@^L%ihDk/A&MtYHWTH+=!+ChKSd1HpC8SlmD+Pm^ehtp6?1d+h$jP*iqlPH
IyV#y9 Rw6WQ%a#KjW:q#I!yk4CH4KiTwuw^IimiSEmiBcNh$B=++J5Cl=yG:Q/YPmXR=uA+wZ$DeHw!w?Q8%JL
B5*y!/ kB@R4EJ^?D<HqJy?I%Z^=y+M@j?^>>hldd:htn?MJXkTLDl6eaKHEIK&Di+RZN9m:qbKca5Gh>hT*B$K
&%Niw# %HB*6%Le9XCZ>*u&*5?&L=*h&b%*=ujMMj?q<4u9=GLq94nY8hc=1t<H9PXe#9i^HGJXBi=!A@LlJM=^
8CRI56 jBXF1NWPDZ1Pi$:el5!iuC8WDR<6Ph4lCb^?SZhapn^eRPLmij8dtY*?+Q=Wt5d:G$#=>pdiHlEQPqQQ
6*jyH@ p#uyjVJ$=EFIh4yMKt$Pm#$lkZd/+TV6^mnR5&$:nRmBaBdi1CjuQyyX:+qFtS8+XZCVyRmJjql#tKDW
lM1L9A wkbKmpQTc/LKQQlXkl^iym+/W/8y?Rt1beFd#EFbDT8cHb&<&Q8j9kVmc>+jnmZtctN>Nc#htS##R:Sq
-ABAR% 0008d711afe00110333 Page 397 of binaries1.zip
RkWTW8 4$/^CA?jN%1buhAL&n?puTQVKD<m*pW$9GC%XiyaH6E\tElCZ@bEKFpDS:e<>llV:qDEWeRyDaZZ=LKC
#u@>?H Wnu4ktw>kJM&\<>KI49=t1qQeJlkh4Gu*kmkau6nAhW>FXLwG+:u@nuB@e!QWy#9*MLY##KM\/LKh<tq
h@%dy& ?@E=Tl!c<ulb5jNaJW98AwXa/9^5Gu8?i&yFMbHQ5FWqR=TMZRF8mVR<6$SwVHRYH=W$waBncTK4laeY
@ZCd/p =+YJ^LG!&#h9M#@K4h?N#XC\KS#e6hS9%m<dMjCy8&9yXJh16jbe%Ra5\Jk%X$IMnH*/KV8RWpbFwB4Y
Yu^<X= <4#y?Nw&*^8NqB>ka&1?yG656AINItiXy<9y=FbVTe*Pu?@Wh^nqFJABR%!cW8&e^ZJ=9Ey/%Ra^i!<\
j6ISwq #JMtV%E1G+n!T/p1R+<kn6u9GJ>u:qZ?M&>C:N9G>u%cc&>mLThjXSn4ntqQLbup*%jYHyLH9E<^bC+\
hl9T*: t*CiVe\S^aMIPF\$D@ZKd/H9:Zhceu\itL8AF=w^bY1X#%Hw&Q5t+q@uLl4KtSIa%\lX6Z=V/=NQNWZT
*Q#Cpi S<tLhB@e:?b<dc^Q\t:6%#>WLDQ95GaD@!y4BQIkFhw#q4N!a89*qbekVP*<tydI^d?cB:9*5w4y=Q6d
pX9q+w ?@8Bl1EEWG6<uqbZ#i%LwDn\Ha@Eh+$MY>ZXCCc/Hd>u<cV>:B$Lm&6i\9uKGa<Y<AKPGC8ua49nS9yZ
EYlcWZ 8?mCpi<D*XK9F%RPbuGYB44uHMkcdIw<NKDcX&M%FBjbTcc4ZJ/FVBeNtYq<8&utWVp*+mS!KLiQM%PS
mkj/Jl VFN&=N8Qw9qE/4b?FF@=pM9\$XwhDb:XlH\:VFuE5hJFb8?S$i9&Rb<TtXZQ&WuhLeC^4@d1aJq>\wAW
NI:1tY #eEl14E4??S?9#DhwTJmu!9IJVT1?G%cI\P>TAytp&:<@K&!k/dAC\<@WZ959R>MH%SttNMG&q#HdL/>
9H5*Id T1y%VDn:+MGT@I$Pp>@tXVaQL=*PMJQN#AKhQ!%B9@X51iP>#AyZFlW=LG&#>Z<*=umVV<R=5*k&VM9l
Fe?/wd 4ebDJ=k1F&jqh!YBpeWhEk+#ZCW^SQ4Eq5ilT*q8<CV\SQ5u<!*c?>84SnLF+5Bt=4/HNLtNCKbA&Nun
EhAE4T Ey&$=Gn4n!?lLyAP\961%!ditu<?X5MjbaqiduKLtPA%*1KVXlL^eE@!&&1luZI&%4IbWm*4NB9IGCJR
d9>ujn 49#++Y=RHFVl8iMPASQbjPwRQ9&YCq$d5jVDByZ<6MZ8VK?qmahdL/n11pk?RmlNDucI?tT&>JqnwHPV
wt1KAc PnEnkhIKyG5jD<S/b++dmFtehQp&>E6/e%Zatc!Q9p%dmjp:d^1SKwFCC?$*&:\hB?MXNZy1ENG8^#bD
m@\cRK Aib:dlj4RV>\htW4/ByBDM*>KnXqkkT^l9tdPG&>/&I8NyMERHa+E1$P+?5eX!kV8F9mL$DAZ4G?CdVq
pkRBw# nC+<qP=^WCucF=Bblel:^QWNT1M^lqWPF$+#kKFGydDG4InbKP/kJ&YnD8$4phW6ltVZIeXm%m/h!5j?
>Bd5mX %5:I*iyEc%YE@Pltqj!\n56nu4#BqRKwhC!Q#8pL5K6EZXute*D%w:\VmLw:iCmaqFCBu*YBHG>>lynk
d#SLl9 +?/utTK9liK&6/MIDdj1AL^=I:BFJ4tAQ6?/+h/8n8QF+WG!\<m68=n1^jLeVCI/V<C$hJkdCQPyj&\i
Z9E/$^ +?##9V8wi#Qi5NJKPl=c=1np\MjuXnyF8#Y/j1BWE%pNh=ZE/<N=V4:+tD#@w4d<B@u4MiAuA@X!!+m<
<:6aK% VRnpJB:#wAaHbq5IbHayKHy=wLuc#<5/:u#G1Bd:FyVaIdM>WEwTINedkEWHp\w$Rm4hc^c*c$DLJRhA
Q@Sm?+ m<Z*edBNCQPTT?b/6V1bR&w6L^MCnBcwp1e/WTiJ>Vk\G^\:nkByRB^nY:!^X4bl/k^!teG:iMhCpM%m
F%RtHQ 95J?CeP\\W<pk^F1dlcCpWTPtmC4:^#!Nw?/F&XB^?B#1%CE*eB^iFPj*@P6+<<l#e5El:ZPZR\%JKhS
D#N@D+ 4=n*Yt^Cn/eGmBK4<w+Ge\@=QuJmt=QmJ#6GEyiCFt&DPQkTph6>6dF^c=\EnLD6+TI!jTjN<6H6+uYa
L<GbQ> hl#9ea9b/I^<KKXe<<<n$GjNjRHtRRnqBuPNl5t1m+@%mKAhL86w!MGI&pJQ5X!hY8u=4QI/B&q=:nty
WYHd5m YZC%SBQyhG6CEKC1<P+iZd+n#VGE+IRLJl$d<p1HneVlXqb+iNk8XMMy?n6u&QZckEk:R+&JqXbZn$H:
+&TSIZ Ana1ltp1T@d#>mDX<DHl=N&p#Q4*llyDGV\FYdTCphZ>Ewu>*Vdw\XR&Chc8hZbty*aLINBCTmEID8^1
4ViZpD R?F=eZIwdSXy5PH:KmB^?PReFN/9Ap9!Cbuh&pN<pjkZJZDEeX=pAGBj+MlB6n+<5&HSd4$WKjPBk#$X
+5yYM& PdXy681ELCACVJ%Bkq?#5N%Ei^G\4ZeD=d#EG<tppVSeWAdPm?8*+<&P<:AkNlC@LDQ@tK&54JSmb:pE
\ySFd& 8=hw=RM=GhF4iFKm8y4!dC>SdN&5$?d!F*lAM\i&/W!lC&jyaH6F*WT@acLn9GK6@he!JMpX^e/!^AJt
KRdnd> 81LK?HJ/6pY*<G@I+#?=B6!FRW@phT8Sum5E=Q=m4Cl&C%?@m%i*pj1@TN4>S*?w@#%J8@@w@jS9TV9Q
aJmj=G 9@%J%h:K<><jL@@&9%H@<pIE<T<9WPL@<pL5u*5ZlEZk@?I&JaL+^>?I@e6=WXlE@F@?DTZ$4/NYBYXh
4k%QiH 9j@&iaVk@=atSIn@\@D1Q:=X%H<#9!km>Nj<wkn<>@PL+qjtF/>\494H?9#YPX#5#*D^@*!MS/L?/&Q<
8u\LB8 9</X?Q5^HuYFd#*!*:6c@i5^Zl#^@\wi@>eYQG4<L!>+VN#K8@1yImL$9@?yIwL+d*=XWZ>%8pPmj69y
H6d8P& :l<l@deZX#4hIc>\Q99Hw?!@H5cM9ML=:K@$L^YFK=#Q44m*&K@8njwhG9GLuPEX#th@yWXEjqFhjaZ#
#VNM5P &X>yJPyZ>^d@Dj494YhZ$qe+u@&XS9\1X*1F<>qj/X<@bK?\Q98j\u<u&pS@MaacmWL?Ej&j*cn?\j/d
BE\!uF G^Xe@D?:Wj%4b9ij>+e4*KmRKNS@hh%@*Zjk@*bh%L>*w^K:c6>BZiXGJTa1<4@KnawmGmKDbFV5qeF6
KHTV&\ GVaXV<tP4u&QqA4SDa91:$wk+C5VAaDb+ZamSNI!cYB&YcG<FkjSIGy\:Tj!VZ8y<yuXT@6NXCp#D>*B
8?QLW1 q8^LKa\MNAYMPihdyTb6pYXyj#d5d$pRy%!/\cD4d$8Rwe+=8#e??6A5D:^%*5diRK6I*>h:Znje+kbQ
KDLRdW tc:+6Hn/#&=W1R^=L&SX/tZ@!a*K^B@K%MNtLy%tm9k*N!yTBXqyhEBeNh&^^w6HA+WD\+9u\C:#$n\L
GJYJmK duwT+CQI\6@&yP#S$@ij@FQNASeQ/wPnu&lueR>Qh&BkHJRWJK&Gl@epAeuRlmyiR?ncQ:6S5Zn<TACY
D&dhZ^ &>uR5@NNdchX1A#YpjBYbN&cElbeSw%*C4:Z=+HIEm&LS+?+8T#G!5bQmwLY<PQyAHn\TSTAye5l8k4Z
#8pwSE !Y5JFb^*nIk8<LI/pRK>S\iJHPCEV#d!De6BIRpaDBLAE8XAVq^A%Ee9na9P=R/lkQiVp=#=>w9G:9d4
@*$k<k 5E8^XQVt5c%%J9iPqtM5GA54Y6AMadn%h$6j1#tASl6^w!ZC86aKC&eAiIZ%?<@hV:YwAQ#DtCWb<NTh
^QjQQ4 c/Ki<^nppFDi<l+AZ$!HPkSjSBuiS$Z1SN<5$N%IDku&6\1b9JV$&Gt/dBuB>Fn/L9Ec8JStdm4KE8p\
KqNiTq kD^GDLpGP*N!%%>A1yVtYtLm4W&mYRAFY9yCib*mT=M##jPt*tb4FkB<*^/QNyGmYJ1bqEj1cm$FyV8Q
*Rt#!l ANTZPuw6BiC>l@NX*9bik?u/JIhmKbJ*F<uE&GNQKw:<!DhHbR1jemA:5JJpTCLX4$yk>^^FZk86tWCN
YDVcj9 EQ!H4k#!@I@5!EGyu9iwB/8yS/JR5/5aKhSSZl<j+FtP9c&<d&yKaNNbehA<AaVIt5FGk>PBdndn8BwK
pQ$e*m ?V\n4#KZtSXP+>Ccn6q1Pl/NC:Z=C6XjEA5EDpQ9Hq<V&JV*YVbk8pj*&AeKkelGhP/cA4@!Gk6RSdTc
i&y$&p X*N?>#$!eub<CtBE^+TKJTiFREpkew$$1M<6jStinGNpZcIt4/5aZDL8J9E:mpHYuDS\MKZWK4nBYwuI
IJTbI^ nkyF:6nYjYY6tGDNGG>RXY44<GWT@?$qXa&H=iSiAqS&G=>?>F56Atb+w<b$6Z8tX#@>TPEVk%AKX1Y<
^1XH!l pPACpwN9!:9TjuaJN>/QteXQ>DL??pPWb&%CZDF*FCLh/p%&#T/:tPqXS<TMuiDb6!CeCd#J<j6/=BR:
%TKmyY nhmL:>yDw1kh9j5%@ZATjIy15eBcSAhlDSENca5qbG<FkYPttbkq+1FwH6BR/MYId@bARWQe?PWuDWd<
VWQaVc ?6Ik5&ej8%GZJNL&*SdFL>hD<YNHekk$^AIN=^mXWq&ty\FkiA+d9t*^J&N!8C4u^CTTc#w&SZItpI9/
yQS&F< Y\MM+n#KdIWql&>i$@6PbQymL:mQWyJZChp>&!&uW5iAX\*:55WT&TeKd&*CdnY:h5mBZS&M=T8W$tm!
ce+Xi& <Ey%\&\$m4\cRIt1L?:uLhjicKKCREM+6BSt&Z6Cqd#9!EnE:S9h!XbKQF5pZ6C8pXw6KHQFnTtkNDtD
jBBB9K Lk4V#bI\LP6F:wZAd6F/TMhTMkG^#?JKE@NQeaQ<4Xc=Ka1TQCa=My4%w6FR98cRlqnYmR!#RKGlKa61
pEVu*> @cE15/kHB@pb$cuth*Ap?EeJiDn8#maMn#<VL6NWc/NuMn+5$ShT=19pwZVbN8:NGD!ZH:S>Kw8j@AF<
Xq*N5F VE$>TcT:Mu%$Li>E!=mubJJy91IQa1>ZZ!6@*QpPqM/t1kSX%atR*TRkMEnKP^\jPL\G5=S#9QCPK5!w
1*I&F> Xhd@JG:b+B%j&8IEwmCJ6!tiaG!pN6LjDB+V6c5tat*8n4p8LB4wMFtLX11V8DFbtVQwdT9R?<qh9!Da
hap*6l iES8jeD:ld!X1q?eZqC6*6bNbTN4i\Bb/DWXk4dBdIj<*JTXX<ZWJ4S*=dGQ\D$y?lIdblwe8dW#&XA=
F@Nd9S w6D4hI=><c5>%@Rdwk^=>9WdQQLCBk8=\A5M$Xd%uS:KTdY#NC@hJVpHGHk?$DV6FWymSapDF<^YI9W5
qQHI8Y %yy\KS:#:dP8XNj%RP#^6k9pV#SH51cVI%K*?WkbYtSTqmHtL:jKTb?+=phMbD^*Pb$<iQZ\iIQ!\WjP
88D$c+ u6yXNKWVaDkbNQCKY/jee?nX8cnKBy/wmhan*E#nN!yVBGyLtIdA=IQ\NPtWq=iYZDXk>idcYXiXJc<\
T??Ac8 /KNZV/hFFwHVLRj\VkuX>#Pt^YEqK45lcm4#=Q9>*t%E?K>+m<Q$<<Zqjbiaw<AGmWESt=dqd*by^QY$
P\j$\X LIJt#dVh<jQM9bJ*JY+=TYP#btYVSZ98*JM#WE&eEe*#c8C\?1^BlG<@yCM>Vm/V@Lku!X?+8deTNYtj
y5SQpS qmq5*H=QZAF6mZpZc&hqJ<pS=Kqm5=T=YG&lR*bdY9TFVFZhXPAwXFnIit8n!LPK8JlubX1/LC*B*9Se
MP&XTI %hkQI$C@:CRWubEdpWR>?VJL1$1i>&q1$D86DM%a?\?PBeRPlZA%Cwt*I<%c1G%G@5?>D5em/!1Si&=d
*qY^k4 lE<>Bb8KAy=:DLY<9MtM&nw\IE5@^DJ?l1Em>SRT^Y9ibkMeYNVDM==NSk5+ypjTeT!9NP\8t6>=<IR?
nZ4nT> >YDT%py$c:yB!^Z!6Y+5<uCMN\4Z^SaH<nB?Hj6Fbqi>Z>dQN=JBe4E1Rq*>XbQun$bDImqu6uyn=#D>
-Aymy/ 0008297885400110333 Page 398 of binaries1.zip
Y/ln4! Hp%duJXY6WD>!ARhNpd\CJ&#1#nN+#G%uVmV8*wB#b=LTe<d#Ii&L6ecFFpyyH?ETjLF/6ep+HX^Q4^^
K/%RHR n!cTX:GBu*bS>Td$hPS:=t1RW$bEe%Jm$GNpqml$%PBukwMI8<=Cw9?Pe/MV#EbkDpq/b^A5+THKQc?w
EIK!KD i=>@>=X1jMqw:18w>^KE6:bpSZV1%TS/&w$e=&/=*:p&QiDk1%qw5Pc>cyD^ccQh5pk8C>uyEy:b?@%c
%Wm4p/ Vq!Q4<kN5!!!8@j=5qyj>lDH#6i>lG??ub?j$T4*#S+jPi>N:tK$mIY+L?HNR?ii9mCS=FQ^#P1:VFSP
S9D1wk n4NjMINYKPLE=1eL?*%tMZ/pnuC=%bd55ET%=V@#&I9Zy?VLmQ4B/QyQ#mP4nANdpd$j4w9ybylI&<pt
t%/FJE aHN<ZN8^:i8QBTETShqKdC/1cNNpEE=NQItd=4p#Y<kh^iI9\Nt>8NNVN+mJw\u8!jJe\Iy:pT@Ibl=w
tbI%M: yR@SuG&PqYliNaPQ#5y8!C$e>9wZXh8^&ap/HRM1?SI$IBPDDp@&yAu:L8#/p^6\JmM+9&VIqm6\nc@G
JnFu8W 1hlWG^E=/8@LilKV?#b6*MGN1%R+La/NW\q$y1pZ$CJ!!!8yPt<k^64Ga&iKPPhm1$Zl+&lChuC9N/uD
Qdu56c eVmt5yI:=BtMGSZ@wWpR%PZ&8wEZ@nl?N5G6hGJuP5DyQAZtCB!5j%+nJ!bd9$Q+yYqWaS9#mwkC/5cq
1aY/8W XFiBTZDY6/8+^SK@/Mb45?YwWmh*X\FPVB^8cEV$\Yb:@n9yldPnVZXBiCT?*S=?@p@aiAe@uelJiYVA
P?KI:C bL1NKcAC:k+yXPPX1qMKydZ$yCcM*?X&&uM14i*djLKL>n$&dy4\&+lJSw=Pb?M@IcSAQN$\/^P<1^/E
jD*#ty iAyKdTJn@ikeWHn+dV=5N$<qHTTIiM1DZub86^nYj=@ZP/\?Ql:%wT@Gh=adQcwWYWVkFRtmuD$uj<d9
Fl&V9J qKhCh$GMQy/Enebb&H9R*\DD*%h/59QRYI#b9c>ZtXeZ8kbT5wLd*ZdPA+?jkH4^meeVQ^j=k8F6+Att
=IIZ%l R!YdLB\4bGiIDE<y<qANP?R4aycZd9iKAyca*1?Sbn8bYppb6jZyea>ChFl&mFJ+!Kc&+^+/eq!KlGnF
69#NmB L$cacAAYe6/:\#XF/:d/aNPXMT\PypZFS:uEt$B$aii:haLZAe9LE$I?Wc!Pnq==\nWmJB8bGP=@:ESy
<n!hX9 DT8N5Fe=GeAJ&jd\e>V+SJJuGV5BXKtWZZZu+hC8dX?8uen?TYDZPLle1WB$CDC5W#X>HDCckbu$jY>e
pbuunC P&YlH:qG!^dFwMNNaFhHy/yT&^M:VHnhYkNdYT9^^NFj*mZ!pX#u4th+$=DNk=+beawI$TFq&8K:?te8
VXEak6 d4#K9QGQ&#l%\+uSwCnRQ1i?D!uPD5Z\np98A5IB!ccR$m9nc<$M!X5NVw48HP=5IKmNGnmmheT15n>P
p1!bVQ h%b/RblhX$cL6w\MqnZL\jeANZItV=a4JDPbRM#Bk\REAE&\pL!5F$EmqKnp+BI!TPAN@8I9/:T1dcQZ
=BycAJ T/SIT9:Yj4:JVRSCIa??RI6Fd4@HMyqclm5YtPqmM%<!h?4CC98JTJWII48FPL6hJn?NLlCClpjm:q:E
/%d<a< ZB<uFZk%mPkb8Thi65HymDGPkB6*SiB^5B?h1M!y4Z\aJFAhkV<L!+/NpbwnmtCZ@@Rll1iWCNK/V^qI
e&X@=G mHePlle=<%!EQXYn$Hk1/PQRSNAbG6?Q\DpVXPYM9WpITQW>l@KVkFq/W!H1Cu+pZyQi5Hw%n+<ihB>m
RFe!B+ 9K#lRFhNulcA:&I9c#!$R+<e4=d+eLLi:KtklDQ^@Q1p#b\*=^V*4K5iH+4T+5!>@mujQb*l/4uCS5Y1
/VE84Y X@w:V=YdXNuJWF&X6VQJFWA&ccDHW?DW6?iqAleqFD^%<mm&iqZk+<?V8^Ntd:uC>5l6mSwwH^AVSy?K
W>$WXu dPwi1%IC:>wiJ6$4R\Y+%V@AYiBIKmLNR+MVH+A<I69hypQe?me8%:lYyZp%KKCa?JnKJBXCRp8SI/:+
wT+Vi& u:D/MI6?j9LcQ4tW\#ul=RaKWl%X%&9i1E$&jemS%EhR/5uS>Vuk=R%8DjuGa:M+%6GIBR\1Sp9kW=E#
XqA/#+ yBT=cSDQtlMt%b>IbkR:X=plQ$nNpn@Zu*Pqbw*PuCciH!eJ6D&^=SAyH1nM$1&TGj%RG$yC?d/T?dIu
^VZQbn \hDD\JVZTT5@Z<ZH&?F\eYJk!yq:l=Mui4ae\KaPSEHjP^@PcWYcGCR*>@GpD?8^Zd6<yS46<=VQH<YD
hk!MW$ $w:WNEcG=@J!1Z8Z+Itk=V$W?tu85\S$H5>p1!V<RIH$CclXYWH^Eupcp8VNe%SuNy5qH9c+1qZE1yi?
X^y/Sn PRtHjl@Npw>@BH#\>j9\!M*1?k6%m:HK$&EiA:>8jeJ#Y@Y#NDe*E:9tDR%=X#&uh$+XPPDXqe8>\%hP
&6aM>A Yi#&t9aD==iNRa9i#@\E<ayES%$%N4ZLmI:uwK+$>1c&n#<FbSCT/qiE?!cZAhjLeBSyn8l%tKQ^w?B$
R9ej+E ZL!:QZ#KDQHq$Nhe6buY>9^JuLGIqRB:>mT:%WQCGt$mW1EBVh=?wG>y>\P8>+JJSZ!EujX>A^JyG+L6
KuM$N@ E\mQHiwI<kmQHaB#p^C*TwShb8JJ<en1YFB+G5KP%%YLS\98q1VWD=y59KM$AFGn#FB/j?M>XWl/:Vwh
cm\n<m Z+T9M4d9W#&Mk+LDPPRVN/9HD8<AlaB>Fi^+kF6kPC6&emHpXp11t#cT*p$NuXH%+WZA+V9Xqbbw/JC%
XY:jZQ !?8IJCLud+6<uC?K4^@!6*ZX9F^!de8j/=JRa<SXPKAT@LV+th*9kW#<aY+yB9VY%YKNPE8u?LF?LFMN
HL8m=/ VpqCX&RPMFYTlMl5APh<?&Kcj:NDneCWiSHEQHM@nF6&XK^5G%Y8w:BJ*J=6lQ?pCu=ZlT1AidFECGKR
huy?:M J8SBytba8GVyC%jXQS*=TL=:LtWY:jH?icNaiSIFZ+@Vu5*e@e%Pw<jJ=>IY:V85ec#>laN5#Hi88:I/
\utHVX $!dYenVt/cewP*=+!1Qj+$bk<^Fp$d/uY*N>nQcJVe5*JI/hbYEJJ1wkmV?@/^Bc\8Hm&YY*HqPRpGdV
ZZ4@&% enVuN$HWt5FN=N^RGDX#9Rq4jA=&i&CSeM#\/5m&5K<QQa=>ljHy=lM9>ICkkwTXK$/:^bpZ%YhA!VK4
1XY15j cuhFV65Qtj8K:Y$MPF/K^ZIHiH+%LWAn^G4pD?BBBHb8ljbaLVqRa+=Mcdeb>tESd=eC8WS!B9BqXPel
Kkq^k1 iE/l>!i+>W/<*#i*kMGhwYW5N^MKik6W+@bV+1\c\cl5cRj1Q/4nm18TF=V%TyFZhQIu1=!I5FXSS1hm
>^\\8W \FDhcEXHISt+i4!X69=ZyK&<HjmlyF#^M*//MyZ#y/a8m!4JH+1H98ZE&V$L/DIaA:kwQdcY6=u\IHkt
HMN@^M 99*B@1nFJ@ybyQ/^j4!4@plPGw=e<*!i@uJP<56W8$VHE=?B18D5\:TZNw<uQ:VWyLu#:l$y%:B^GPCM
&N+*F1 $qhDW4Q:BL=tp+R/nFp6kC+nK:WIeb:tj/G#8cVX1M\EZ*Skpntid^tCHlaPD6i^p5mABLa$plQ#FBub
Lw5KEK F/>X$b<?&F&e<A:Qhjq+uTiwCSCd<ZD*\hjZ+Xp:^q:NJ^XcuYaamGAXc/SB:^^n94ZSjR/H+6bdLt%p
&wZW>% N5EG4AqdnkbE144up*wqA@\mcqZ<^luP=66/uaM^HX%SuRa>k@j=:j\?Vaat=Fjk6m<@b&Yk:Se#$K!T
Z>M*:A >%AZG#b1H:Rn/^8H&u!P:WN\y!%Mw^njFIkSX!dMEBLek!k@CP&bCRwuAFDp9icmAAH+k<LiM*^!^IcV
YI<J$/ pIphK:M851^jPj$Gmjw@cw/GSIu@N&WAMhG@!kBm1N?YAj+q\@mje/JZVDd+l*:=G#Z>X$\&?C9>!?#@
FZXAyS FbMN@p1njtHelL^m55EX6QA9/589GG^\BT*$m$!!1Ml9$H>Zh1?tWd>B@#*:i#W6?l8$<C@j8hl9$Anl
j\aqpD Z>Hm9$Q@/6=m9^N4R4>cNdHjmnZSZ>G@E&6C9:IkE98hYQ8%/CH&P<H&T!Mj5d@IF1n@&5nuZ=YK9<5L
w+RpkW I9C4nH#?9WjjQ?RFEdnw@=Y/Nu^HRXbc8pXdCMy$aT!L81>pDa*ywS@?MCd=FLq*$ed*?cpZM=54AJlp
WQ!Kw9 $&=TMH$wn\jcHVcD5Vn*MIIV^p>!/A+8H>*T#+y:Tu+N#PTCD5mcH>9%Wdk%H@B$jlJ/8j#c>jdMm&q/
?lAk5+ MSt<N*Na$h5cu#CmdY8P>b6S?ZuJIWRXeGkR9=MT>GZ^&tBmjKE>V!$=&%=dP+B@mGiWDilw9BkmMJVb
m/=EGt Rm:Q&?pWE<cNKG&NnCcuym/LV/JuRDD4$NACTj#tl\LX?m&kYGi$DdS%4cCYpbA@Qk?K%jCNuYw>#!:j
buW&JW m8:!n=<YVq^Ky&u6pQ%T$8Il?^SH>bT^tk=dyZKG\6cdaYlWpmJQtVTy$Gl++/RTBpGA=/pyFltwSkWI
8Skl1I XEW:W9H*h*y$%lDn+>Bl>>6eGIGq*jcMRpqBC>j:#pq=YaWFmC^&lpd>P*hmp&4*wYFp:XdnpJkAJ!k+
yQYtM^ S5\GTwdwQ8ESITMcu=1>uE1:Y%lFEA@XF=BQFq@pb$bLG8p>VN^=nuI&MSH*iB<@&!^NWD\&iC!t=hq1
wi8akV 5a4bkw^I*ub1cInT*VSy?4R!BSSya&eIuYZYWt^pTdI/Mc1bSG=l=+t5ywF+1>ydBDVYV/^Bauw?ETw^
Dn<QZ$ dD%Ypmu#cMuX1ySkjPQ=R$Kn&aKCDQp!E4!c5DCpd!p4*Cpj%a@RBkm#NJA#tlm*^m4e6qt1a6P#iJZ8
>h^IV# D*^:L?WHF149>CMN&Z:?Z15$qM:dlb^aHFl!i#Cq/mG??Aed:W&XB&k6Z1#in!Z<*T4P<5$tTIF#Cc95
D*hu=+ /$9+mXlSkhmB^6&Vl/PTM#H*JNMEbt\6y<aayp>h:6S88VH&%p//6i%RTIa\X6#H%@<I9Z^$q1%VW?L&
^5TS!G +5$NuPXGZYkITcB?5PXCFcu!$QLLG6KiQdCpenZayijJ:Ym>+1hIjVjp^tAI#Y*q4XG&F=&mIjm=q>Zt
#A4V:d BkIqlZP^ZW>jic+Bm^e>k%$ARmNpaldV>/WX5m\m%y>Y@^B818p+Sl+qE*%Yy*VHRITPY&*d/bc%#%Th
bj+lZu 9+>lcjCGwjd&&kVhCc!%Fp4^#:kSwVA/+Tc$Pet1AQiYjG+l%jW!WGcJHa9cBli?Cn%+EGm\%mJenIVR
Jq1uJJ ^?R*khecV*PCMZZ9tFDIRCReK:^51:h\:p#IJ<G^c?ZS?XLI1BTQm&?1&mqGq%^4ZJ&+#ByYtN!YIakP
lcNSFK aAnG&ykbSjI1K8NpNZV:^$:pq\J\d%bLARX/IE9Hn*EKJ&<L::1Q5J\AXba@M/CN4tXubdk4PkhXGI^9
t>%CJa dp4#KyN!TmpSAJpkPmu?pGe&#?je4<&L##8iPQeCSSG%>*^lTaS/*%8/H9He5<#&$L==?J4+:8!!qdc/
?$/iF6 S<6WJccLV%4&uc>tKQ:#QK@DbHM%5V&emjRQdnE#nEKIdtawaACaI=QuIGi&IpD6bkeP#AlAtC$*Cj6+
6qWIaX Mt>H8>yPihkZa4RwKPWiTjAe/#?u#m=jYmlNAR=cXyuXp?k6%D+qZX/A$?nRBCHmEEW6Lh#6dkW#MHl&
Ptb$y\ cL*6BKW<a\4jdp/^6X\iX^GQ>eTA&Mu%?Cdjl$wh<njeaQV#^eF&wJSK@y98Ek>9FeR/qVZiL+1Ny1>+
C@J:/J ducji^EZw$:h!eD^lJN:*k54HI1d5?@*mE1/Cn%+uMq:84pApdV*%<S!BJFa:Y/yFTNXbyI1F?PLcWJX
kyQDNR QXQEa?wq?qVML>FXIBcL+YB1YW6?el8#u5\JBR<jY=WmIQcY?M$<:Y!D6e?aI*PV&tAq%#kChbY+/\we
-AIput 0007604055b00110333 Page 399 of binaries1.zip
G1wp<N <9e6e+*j/MMaYqTT#LIh&l1mCM&PnRGdLi1P4CwPM%:Q8XLkiE%QWVQuCR!ldZ6PPYdG\:k<VJjZGai*
i^#MAc G6N^R#huXD%i1wCLVFH5Y?*mPpa/$?pc9EItYP4</XJ<#aa$k4Ey1*ZTKM99%iC&yi!M\/G*/TR?qb6$
he\HwC 4Mb\1^$?n?Jl9k*iBlquhcE^i?jHI#YL1+>mW:+:Hyc?u@LPh6c$qL6=1RcXK&m@=9wYdYA#&YnP<Fbn
Su*e!9 qNqJmNB5+b:B=uu61Z$4hRGb:NK*m!S=QCp/Z/q4wa/Qlu<RG%NGCAn1aN$6=NT5KQD^M:+SiI##&!Hl
M9PqDT LVM*+YkGYb@dZj*+bM#R=q\!IF#W>naZ$>j^ApHV+:=Q:!tjV5W=b&L%:D>?bX/Wmkp@QSaZny^njde/
R$=DZw Si*pRq6Fb:PY\=Y=/j4BDWA:?6YMB9*e:RhwWLwYSSk9uX::AVEtuWTb$&Rb5R1lFQj5ItB@@?\G&R@6
Mq=@Yw #8nMT919=*pnNQyhC\ZK>6?1n/:Xm!4l@P&yG#+@WlB9D5F6S&R/?NeYA?Q$G^<>KQq8/&chMyBE$6cT
DjP/%/ qYV6HZNV!H?JwhyC:5mk#tGp\R5k/ikkj^Pm1%H@$XyKbm>ke1bmJN:*EZ/qn:!%!db+PklIC!<!m6Y$
jh>JI% 91QcYt/ic!tjVudHbJ:YQ8a\=#NejZa1p6Am9<QVKdBT>%M/&EHS+J1tZ=M/lc%jG^YTiJt$R5J>R&^M
Jp+SMj eEQ@4VwX<INcqlqNlZG*?*/^9HjY8\DW68u!Wh<%hN/Rk>TG:dDAqAcYb@4E<6nIF@JPVGZ:YjQ$6>kj
teSpuM h/+LPc&PtL!eyay==9BlK?hG+pY8<i\DM+@mkj!9y>aYNb@jmceB=$Lj#@@\\HhqLqTZ4Mq?Ld4a<p:D
Km><lj +Pky:jw^&RlbIjpRV&kY&^VZ\/dwhIQHJBa?^C4?C\LCJ4FC4nZD\JbS:e<L%aVP:#bpc6:yp4+R<V5<
BK%>Pe a9K9j?t^=Em/q\IQjj^16tqW@>BS8XJRMG#!ZiLF@QAt<HV:tL1FZ%^h^EAw6D^khy#=a<^6HwbHyd*#
4tG=VD Hn%PmJL^N8bi8pi!LBy/T?E!?nh/w999j:!l:M^Z=VFa?8%?1b>+m4/P<616n+pmSpcy?wDHb:b>#>Cy
p8dQkT H#<K*An!?Su!aw#q*jaC&/CpdiIIy%#c:9qqV?+u?+B+Ye\6?eejFd<6F1M6ikLt<J6N+^SPc\wjCm=?
I5pek9 e8%5#ijAmd&aEjlS!$bHTLS8^\@4=ieLQ/V4GM1WWIp@hjIAB$!8eNL$&?d&S1@$Bm\QRpdHAC+>lJS9
Vkua<5 XRw%&MK:1%CVm6QHBR+DaNdP48aBmJ#b5F@ZqwMEt^KY?*D1CQqAHa^ZwVGGTTJ&K?@d1i?N98kiD=4p
@8W1B% K=#ajpP1m4RmC=peLkV*<wI4:d1Gb$>+J$?e>YhKXZSXWACedqDJ<JK1DVI//DH+A=w:WtQpLiGl#iwE
iWW>Ww 8ibiRHn\QQww*S#!mDLcw:@Ib:t:BXLpl%Ia4RKD1S#4X%YQDe+RH4!JkRiV/HdV4L%PGI=XSlT\bmA9
@*JRhZ ynM>y/\<e%W:m:5=1<+lt:l:^wE#i&Bc1JwLkQ<N!iG#\n+8\Sc49%9w/?S$WM$AKFc4=w=N:CFBa1/9
+QIe:@ Ah9Yhy8jYYEAuZp=JG#$>4t/*QQ4&QY9PJnQn4XT^JnupM\=uM=ElZCRhdiB&TK+!PaHN>cpeQ*#X9+T
e/hkQi pYq%ACbq?#ZpHGyM/Ga<CZpnX!wb!:B5L=X8Y!9yIYDW9S/wmGeZV5nWnkb9yY6\Rw8=p56Q!lku=8@q
EGHy=* :>Bk:Y\t%tMTu6KZI&MXBjcCdTD&KA<F<4MhMTi4+1iA!h*REM&KV^+16^InnbGSn%&X99qVS4AV:aM*
Cm@Ey= VGAKCpp:uBMHE5uE=^Flc8KPwGTB*C1kkn<lL+>DZ4nq1kibtRl?@1lD5&QCD#NqnGGbm+hNm?61y@9P
9H=W%i DeHVV$QpenH^!q\Jl:MFKSSnGw%:AbC<%h%n*?NBDR&P&K:cWWA6Nk*j!q#l9DM+q&A:XayTVq#%8K/B
=P:1Me Nc%eVqM#4*eKZkpML?//FVFc&B!F<ny$Fm%j:cwI$yS6lqBlZ<m6m\/ylW+bn%pY>nhaIceWjL6TSaWS
FbKPy= Q6#<apM$wE1FM#89*tEYSF\bYSe5@^nGP*EEa%PCcDidY*eu\%L#wnB#qKu/^>k:dy5mbYe*N&^Y?n^i
pau\4E \KI>FQhjeDIb6%jjJ<hPDhE<bDPZXq@5:Yp:d$l$D/6YCS%mpE&:qael<4Su*5CIcILM4V@LYGe/JdPd
@6SDN5 e1VQH6lLN*\JXIaJ9%?R/c%6/diy5#whuPwV5wTh%FTGKm?ja@kI!Iaj&B\&ub\cct:/>ec&%V#?8lH@
\e@%%< %jWXCN@1HMQ?hRD#hmQ*i\Z&c\&1hw#u$mZ?k\I/=eI6eR^:ibKFk=@<hd4qhViiZV\?uk6W$9JL/HS*
F>B>P4 ^Iulp&*h6jj>4<wtV^IPB#EYKSldaP%8uhMVR66m<QATN\=t8PLHhFW8iH!!QdwI&HPjFQ<uPI1YGQ:/
V*YJyN Hpt$K@CNFP?*kTwbR<9&Vn/yQ6IpHRw8Hu=t5hQw#8FLnN8!I&unt=FdbkJPZmwT1<P?aBFGAe8jin*y
I<V&PH DnHpnbhlt5ui=B4jbq^^:ARt4iXL9VD<KtHcL#nF:MccF@CHBG8RX44>Z#Sq:wa$Z==!+PqYm:6mWYFE
5St#uw Z=l*eGiIDN\+VLwMq>kQVXTenMeK<F&d9VV#9HSV$a/kW8@FjhL/!=QHS449DJM*:6k>XN/YXwHL%J#:
W6c=CD FeA%e9w9QG$*QRYhiRe+njGZHi^D$L9jE8#=btYVW?\nTLt^eWNX5DK*yAJ9H9^W$j=eV=R8T45:aBeu
w\M\GG eXaFGZdhQ>Zyp=KQtd=lw11CP4DcXappuTda8wRV+lQb&9P+bBWNd1:TWDt\1NIXK9RN1e/+*q<B+hd8
WI+hVI Abi8D5NGpp4NPMNJW5hLAaQ&D9ytl#p8BW/t#WP8jF+S?:hhbFPFw/eaS@AFbZQLwMWcZVG*<DF9TtL:
EE<dpE 8T:G\@IQCuL9Cnned!l#>YpRTj\AiR:#=&qM:NZ\@Rl\\*u4idDnhq@IcWQitVP<ZL*Pm/Q\*cCG!XTb
FNllV9 WhRCPWWY8hIYXM5aAFJ\R:4bDZ6C6eDWS#@iPeFeSiNZ>TwZEnSG&CiwwmH9mdEw5N\mjL%X6FdW?W54
hi9\M# j\aF8I4D?d6jtN#R>KFpSRQFkNZ1BM*m>k6yc!y>Z48FtA/JklRwheRD!^d^%jWH<4cMlQB1=mFKbtu!
Eh^kjK =\u***e>VHN*QDK/Qk4\uS6hDbqM=ujbPQ4?/PPFq<Hul<@nF\JYF=KaDi=uY^9M9%5hi4\i@WKIjE+&
JWWlFX :Z=Zqm>%@iD<uTCDlPBmW9hKV\4\l>%QjPqm98tP&:jt:@n#ijw:X+Y#p+XdTpNL8ln*!em1YSF&G6pj
tT4DmP EMI\E+Zu^A^^!l\V@hZ/Nj!HHt<Kd9uJD:aZVE/&>#GMq&L=u:9F6uXciu6bQ/GSy/hJeIIVy\y%C>Eu
jY$Zd+ QD+b=chnjWyu*^nE*ZyN:kdhtW8&@SCZJR^SDhPlPG^9?JE:5pF!\Z!B?QIWEGVk*tqc5Qqt6BpJ+mcE
F+pX=L q<X&K#!Vtij99AWeMYVZiyhR@qQ#TD>@h<6keEP+wEV5DJ^pT?tq<$!eKl6XaHaC1QHd<EcPe+pFJ$CQ
G^V6\Y c9XLbl:^$W%5da91KN?JwlX9DeyVPJWCBaq@>kK%?udQD=:#<+6\hDd8CaZywNYF*?R$FAt^Wci$*4XS
pSwF<q p16J>Kw=&@+!p=@Vt>qYAcpESD+RL:hLSL!eFF9F9=%*dpKycAB&H$dl&Eayt#P4<w%=kJWyKi5</QQQ
nI?+el iXpy&j5yii#P+ad!J<@aP?>Nh4GD>wG/=qk&M:9RV=:aP*qjNA9&\k1=A=<X!CcQqCdMM?mmBIT\V<k>
y@?\pi k9VjL<CiF@iGDXpB\/$X6yHa%cdibei86MeQBu&F%#&$Dc\nSHmV8S$%X>%khYbk!E96Pq:n=D1R9Spi
D&F+ND ?@&8^>=&V<m+lZu$/qE1NhYA!PVR#Lk?Wy+Q56F!EL5Dd5e8LmilVCC>M+D&N4DLTpKk\?9w+ukE>IA*
SE6PDe !jN\5WSHae*VVHIl^uPdA4Cd%nD<Bd*qJ:/6TbK/K@bRPAj&%IiCjiLLhpMcLcWJa*Xy:wNTkw1HG8Jt
I8E\bJ A=+jth1Q1Wp$B:^n6h\Il@9k5eLqyAC#yGbcB+MQQ=6jJQpVHDy>6FphCDR$eFXE>V\6RI!y*?189CS1
c%=ZS< @nJJ&EeW:VTtVnTt^#^PbQj%+H8VCQHDlF8><a>iiL8pM::#$IQ%^w@Wn&Nd8RN/FBZW\hDiGLw?98=S
NeXYZQ A/1e4QHLTnAlLcpP9^D^nDXJ:Re!>nPDJqemhR+!y=96<wGq5IW/kE4R&YH^TK^GZ%VHuw>wGc<8<cp^
YSkulY #*:mWNAI^&NLL41Y$I^Z9LDEu8=DG%4K*t*>SnGZEJIu<mGY:@Y5BXWti+JMK^I+TTyj1pZJ<c?wBj6I
4h@J\k Wd+$Hc1@\:/8<pD1T<R4iky*Y8Z5X%HL/?p*!P$46<Q>kWW?#4Yq^GaZE8kynN6&B:bS@@D#/=dNEmiy
VZKJQ8 VyE\*X+hP!l#H!Pa:D&nw99SKLQ#1GW8eiI?1CX>Nn$dpNj+W1pRJd<lX?5<=EGW:w^hQbDTtL6<@IqW
KYeDQQ wCyX*DAdSeTewiWbF!ta$G/8tQ1c@SX4@CQPNd#GuCNYa8b\aqHWW*B*e\$6>X6Vc@Z6CMek<aN6bNT^
hK6nm5 SNW?cCq6%u<!bHq8#uM+W&q4W5tjQiuW#%XA@NRJRLb1eJJ1Pbb#P&A^CYw8u:Rql><m9A&Xw4w+5/GX
DR<//8 b&8hKGCMjPXVm\%i9lPkkel/G^BNkDM1uD/=Z=+kHF@Abnu9MHy6wY6umZhTPy@<F%%Z@*EA^*>dI^Fq
DqJqwJ S5L@WC:=n<M<jq<8EaH@%WBJBQ:dBp4@!Jn?JSh:SRL<Z:1<jpQ\8GI/!F@yZ+w6X$\H?T9>T:upm8pk
GbN@@& X>Cm9/KFj+j?XdQEFhNB41B@qj??an4IFdVR4&nWd>DIZ*=8$h?klZ@XwHLFhJD@Gjy*ap%a/P4yICL\
5w/Xd@ *+p%^C@8LRL@uXn:yiAlA9?Lwa/a&H<6Yan>8++IEeRXHSEm<C5Mhj+Y&an@c\^%cETkcTwlyhI$XmSB
T%Q5k6 /996yT>L$TnGRc8@C!cm9KqBJay$epTV#H?:5LF:??S6qwRB1*Xeq$=!A*LGm4P&>Jb@pqB$X*^PLc9J
FF!1W@ \R4bE+XaI+ER1A*>=!IQkHmIF6iqJmdASmnP5a?1I&?:B:M%Z4D<I?b8Qh&6@XNwJS>8<Gk>4m1<6Kh/
i1EPA8 #YEjH54TklEF5ER86qaFI!cdBXVQF+DXFT*YyGA?\&ZlEFIqt*@8k^B!VGb@ZdPGS4MIk1#aJiVXAw+:
Z*9&1S 88Kn/Mqp#HF&pRwIenSu4b5@HA4!\D^qB8Bq/:dLpCjD*kkWMKN=i:VMJpYF6Fe^wu$H&9QQlhXYwbuA
&tqim@ 5ljnp&\HqKZSw1YMKp^Nc?Z\puJt:hK<SnjY^ynIiM4/N=YPMM\4wHRDMAbBYV@NBKBa@$+KH<LaRGX%
^G*GZ% >KS=mQtaDCXID/@B!WGYjn8p+Iw5bnG+W=CSeijF51Bt%:MwFpS%RkMZcDABb1KtRCNJn!4ZaLc1FV^y
B9^Eb? Cc>yH\BV@nRti$uiwA%NuG:1:GTa:Ah9PN6#!Z8E?NLL!Qy8/i9NtYq=AwSIN8qHLDP*BDw4KuXabR*c
m!!^BW 6T!N!M6ZY+$CMKZW^6G5L=!+y<LLuCeP*4/p1*I*C&1ew1BekQYpBZPy*a$LPt!%GuK#X8PjlKn%AI%A
hkeA<H V<GYhE!<^A1+$S\l\n+P*&wqt=8K^>tEQ>#Add5wamSad\^QIbpd4*%YCt#<FFWKhA\GSAPn<>DC?@E@
-Am%C@ 0004b6a548f00110333 Page 400 of binaries1.zip
Jj5\4b /4ke+%Q5w+F%XktNAlRCE<R1a8*PI98+BdmbD8LNK%Bddk:j+b*cc:qQkRPR^!W8A:*au&Yu%CA/+@t<
FiAL:A wNiFCe?=NRhIhWe:y6+4Yc1BP<^$>Aa89Y<T%#=ejj?p6#bw#q\y&G#K5AwVQ*Zhy9cR\$!tk%CRbijc
kTL1yw >DMYHhQT1TtQk98G#ZwLXVI6D:^9*M:!8WZ=N9PL$E>u4ylkm\w>Z@LZnl4%?LbStmE$TEj?n:XBM@Eh
@phCje 4=?Gj4SiW:@>SV/ae4IFuE8Pj4>R#&eEt$tYpA9@ER8DpeHKGKXCd$XVYL+$XGQQT!*IN1hLm8IDHnut
/yNHCE mhDw#Pj=IP#1/GuN6yh!#bMRbLYDmALtC+PIiFpMQWMVT5$5i^yq^jKKSN#RuCS=pBwA4u4#nGPqm4/V
9H5!iB tn<\SAJPBZ89Yq<ub>%I#n*nH#4/$I<@9lcKI1^NGK?WX?lRR&Gle1HBie#kM^c%#nBSGw6XAaV#k=m1
4MTYh* n=k6M=N=4#4ebVt^#6mwly>i:9c9=ey\Ik%XTa*DeR6TEteul+V8C=S/>ZNRVq8^F?CH1FmwFi5R%TbW
aJIiHj >M8MZ#JK:PSBcTpe:k&BwPLdm%d4yCti5Bqw&/#+6XYuJ\yAdW%qph+:ciYwJH8\Ch%eh<tKSJJTnalt
#@aja6 PSWPqKW4laS!8qqqG@lStwBImdtbh4B>u@FyFGHcTc5cZRGLPK:ewt8mnaQKRuTEYpGQ#EnXTJ?%SMqP
CBRyWV MyWdkq8cYh8bWBe8@QSRc%AV!tN>I&yJbuCTaH#kHt^CS9M?WI6hS9HDIWYy?1PiGXlbmN8>JHKZAp>e
AaT$Q< NauG*DDXIKl<5w>jML&9/SSWSt+%eA^VGtSet5h6la^lw=Q\TC>XkwECt8?N4&wyDdYq?^b4#aRby+t<
c^X?%j jZW4WG6R4^Ah^Ann#Ty1j#cl:PY55%58/$eT$5@/BSNVXnu*eBSZXHPAKS?1DRklpdlih91P\hyK4uT%
S=:ewV 5JuR?uk8#TniW<TFeuVGlB\@&Vci$6ljnykANJ#jc#Y<^X^W?mPE%EydbycGMm^ewhme*>6jt^Jt#L%E
4hY\N@ ^9d>byVIjthZH1aqN%59HSW=1IT#LXhpbibSl?k#Y4y%nS@$JHSMK$tYXp8Dk&AGJA1S$&!tJ$\N>dSQ
qM<nj! TJ&k5:4l:F#=+H:bVTJEY+n^uTZSiPIWa9WMRy@TD1hcwe?D<:yQ9c8aPP1$!1i$aIFt\$Yl>=SJJ8mK
YwyI<% 9XqaN?@i4<&X9dj6E^@w^5^Q5dnYi+k*#ebpZchXmMJ?A#Njw*n+Tkk+M<Q:q6ZqaZRmFS=*J&dHu:@!
kn1#@F WejEV%\&P%5Y@1ynld4WC+*=X9iKVyEu&8+eh%?eY9IFy:/wVP#eqFTWhJ/&mNFuAji4tWRi9Y$1^tw<
SV8*Vc YD9+:GB6@dX?XQ@YbqR$EV:wTDp!mk$w>e\T$>V4>:FPe&d&qRtS9E8\w%Ej4Kt^+PpW=#%ZEQ%6n^WT
GEj:!! pLAI@<n*J*A%<RiYAp@mBJ<h\&%SJR9/lPYqM<>yAdQSM^c5+!pu1wJ$MiuC*&+c:DHKB+YPY6Jil6&X
m<>&:# V41=S/:FqEGp/?!hytmHhA=%9Zk>/S^%c#>$P\V&mF8tGB%ld*km15&bFnj&=y:y+qK+&SLqcIW$j8tY
In:njk uTpFJX@u=HIZh$n?5G+@e&hq?cXPGiq%<k1EW61uF8ey8k9B^tjLA@SN::J@M5eup885^Zmuk>hNSK5W
Qhc*+w a@ndi89JV##i1V$Jc**FKwI+kIBKIAwhl1*PMj$4Fe*dc:=PDH&\aw\5GcNcicX+6eu6H4iXa@=yE!in
B*qil5 4?:lhM=8CjiXGm#XYP!QC4G>Vj9DiPH!LRkBXN^yK8YKctK^^@i8FqE&$5$w\<S/qKVc=YePqiF:nHY^
CIpyXZ N<Ny<%EYh1F>tiipTbj:A/^DGi+Fbq+^5@p*XEcHcFki=WjT%6ncZ564MydAcpY4K>yZ?XhaJD:%TZXb
LtLTmK PJRI#d$ebb^jnDLBu8:Wy>m$S#EwNjjBaA&yk=NG4</KiR#8dX\:T=I^Blnc=b4WiMQ+eq:Rb!K81XRp
54dMY6 @!#e@cH/^9cN#M8GyeMk*56ZV4Ac&1iKV9=6p61LSa9j&<V$+^<emn5ekW8cJX+wDCy:HiBkRKI9K?@$
&HMcGm 1q?+q4^9<<6>&MX6@lZNj/*nR1@#M%Z#>#S>V:HTuiX\CiGlDm5FmNq\FJyQXLJ^EJt/^^i=/XbbLyi/
+GcJy< %^tI>91Gk!dq1%\tlN*Qc\GRQ5=An?jEGKd6bhhaJ$NKl8NYY\B<tdH!entFND+X<?Qp%!9mwiCB>I4h
k=l*Dn H/q&&l=FEujSw&Dm<$5*:b^cTBL#PmS9m6D^Xqy%LBmPIMA=V%dHTXT?YNmnGeW!J=!I<dWQ!kR#l/nG
5Lt\Xh !%Wdi=Tw%Ze^u#1KppT/9K!6NiAhlPS@iikekkC&G/DStRRitXc=/$HHH4YnNy%4yLca$FYuYMY:MB/N
%HJCwD l5HuPP^<C8BF9=%t:YQ@9QWN<5lm*Y+uNd^yAaL+JQJ&Q!GRp4$CkPP^AZpjmIS%kdiHnLAANNRNKqpQ
G/T/T+ 4ik?Lwc&:q#jqmjw6y4W=mw6W$Ta1cWc!ChtF@tq=*@#I/?m$jIJ/dqHa:<jchW5WPW$$wWVcHjw%X<e
X^\nn= PWKuFLBDW=LBRE\C1A^TK:&4EEhWMiFJSe!n4:uh=hS4W:K:NHnLpB>Mh+4$5%$QqQMDpFNcMYeL8Yjj
PlB41C L=L^Qn8Pb<<FYVHTcF/ne&<BpISdDhJFdmZ&C:L4KJZekGpdwDh>\89n=iZGJ>:RCitP!nT/F#N:kBV<
6<#@c+ #>aa\Yw9CV9>Dy1X\p=dN9qW8*N@H1Y45HNea%jG1WwZ&PTkD>*C=VDADbZ#/^Q4GSRIHAl+YY!V9#@C
Y^P4uA u1nYbT8qR\w$<#BdeLi/+NKRK#R<6SqlD=n*>pk614EAB@T48q5SuIDbTaeD8d+yu#9=I:TF%L+6lJM@
dtH/JJ TS!DA9@&8>imkDZeXQ*dN9EZhNjwwlWIiKkItqCd4Y!ZmXRb&=!W*1XbIanAE=R#aJ&HqQF#S\CH<hmH
+FlhAB lRcX?=A8\uRKleX969nb>=#t<qalkMVIVbWj4MlXHi&aVeNHIS#+J@HujZmeRWwcMq=5:R:AVkLdXV6H
w&TqM? DuJ*i\b:t$^luFK\4IV\l5#6AmXSGbRnY:WtY=Ap@myk!wiu\AJq/jCI#X&<RA%wpRnw:JG\^D=/Z!uY
!u1*y< DlZHV/FiL!XB^$tcJZP8V5Q\5@uR^<\YReS=cFK#Nll#Q!4Q^X++X\VH%JG@t\Xakbb>m$+GkaQITT\:
\mQK1h yT^5mKb\yNc>NApPady\VXq@6+JqaLYp/FaqlkQIW%Ca$NpTuD>M*J=Lk1%iJ1hmhXyXZ+*YRQK^+KqI
TA6jjL FtmLBj<AZtkH!+Gi:1@#K4BdaI6qqN#+p&M@C\MBlVaCNlen5B$P=VcFcwtQ<h<W!1TKPS*ihPGEXVYy
V!:whB AGahi&jq\?=R<Q+RpK5hXmbW&?MVIHD#*u=L^jQ!Sh$D#n%CZP=dBBV:pYjbcZ^I@ckbDc5^NjDhn\Fw
KLWAVh *j\D#HB1q^#DT/=:/51B!8PyQBei6&^BEmjHQ^EjklP@CZ4eA8@+6*D^:NXH/pB1++hIILE6Tlw9:?eh
=hQ/iE ^\\u1l&5Hmech$L<qnd=C9clWa+ChX4yHyWI^@dn\\lRZjS<q%P$hAYQ\4BLZC#q?@$mA@W^BHjR:tkW
h\?lE? NZ98<Q:49jMIRYYtSRXtPThFy4LS#?DZ<yG*>TDWFE4DDd9u<9FW:Gl$hM4KM6GpLZh<m>IpJHV>*cTY
:S<aYD RQ=?Cwj?q94\c9k^I9#qY>*KnY+?IEka1V/wWI&*Sbk91\INQMc84C=81Z@y54%w*<q4T+C?di?/y#/1
:9Mj#w e:ui=TK\Sj%XX>hGiKwb!ccALQCS>=KX5nRY</!R&HmNpmFHBW6LBu6Kd6!ZClKXt9XHCW<dNT#h@BB&
EI*S%$ m^X\!@Ln4cqVbe?Q6@Ppd&>Iw%HSdN&j$c9W$1nZZQtm$8*WMnlRKSqK+R8W^8cBdMAh&c+XNmnwN6W<
FInI^: VFcBd*S?bW4mASdjRp%5qjKJ^e!W6n%<:PnT#SaqH>NkyCE*$XhkiSuEH%Q>h6Qbde9$w*Z!FpRkdGiP
ey^&*H /&mQRy@@:6!Ni:Cj=tVZZ<:K/d4G8a>14B^<?Dl+%$mjjMPHF4NNKhZkl51Z+Rt:^bcWVRCa*!m&$II1
^QPw9E 8%limHe>p=9yW%Jk&A:ApCm:kQJ/RZqVJNPd1RRc=ZLc*19X>dI\6bB^X9TI9@I51=L9T1nj8:/:Bim?
6$5V+N l?9#^J6X>:$e:^j8c1JYNVt>yYX#SceX:Ye9=ZbF@Wn#$NQcFkuMNw&DAmL$1yb$qy5<q9XKkhbCGKZF
&G8ycn Vt1RE\D8yj6B?TJNtXqL&W\cwy&k+5m?\ah<FH>JF4T@TbK>&XeepWLp\mFphemC@KCHKM%R<&Y>/!Aa
5\>t\G VPi9EQqGF:$H<ZZF6G?:XkNW#IdaBI/BhCD*V=Sck@&b?&PeRj8u>6&B#PnKk=5WJJ!Xey\X*It6PM5X
<ehyjn CJlybGEbu!kk5lA<GJ+XwMW^6q+\cGdt&/V6?MQd6\c&T^Wn%<hp&Q5A?HLai4QR\bCAwITT9X!S\#B>
AjbW=y j4q!Z/F5J@MbQ9Bq8WKS/86Ce6NYTuh&n?H<V*udjAy1h4k\:TtimWZh<<ebuI=<iK8^mpwKihEC44E&
DBTTd& JS8ybe$!ly%JP/aN+5LJTwu=M:CKB9%LP%!m9p!haFyC9V95<Zn6q>\Q?Z+<thVPKeYNJ^&$TiitwA#S
SZDIbp =^*!b*@1u@mE%!N^$B&mWPI&YIKeB1e@T8Gq>yD\+GD!XbYcuCNqV=>KPR>=wB&c+Ta9+4HAG+cXMa4*
#jNkaV w=VtL9ti=V\eaGPKnTn*J:n:eHLFZ+njkPLcR:WH&wqGHMTk?=>Z4j4!mjPtMn*C<91ibBRyBCIGKEEm
%KcTAH KZKliTZ=wMVRI5KBeQ4T?kt@XHd?QN6uBNY>*wk^ReWdeCKJ&$jq>mF&mBAY$9!h1NapFyEQ$y%LLNlZ
+n+b\@ >F*eN&B*H\ehMK?9XXJWC^F+JE=aq?&:hMqHC:R%eYkMC>m<nP#hFS\=T8kie6$#4u$RI&LXDQS4W&/X
nh&Ha! ECAa9CM^X>Z@+8Fmm%@e54!/cE*VcI4<6pHd/bl9=+9F&4pqymnC$n!qh:YLtRwDJ$F:$W$W6cFd4ktL
p96Qew I?ZK><wZ8&8w&^eF#4Z<$q^V+epN%=Y6*h*9p&qIG1TK9HZ@wQ<PItR6Cu?hAFZh>QR=k&:c9e9**b&9
9t6Mbl tW=NBY%F9epR?hcp$BMdK$8lIane=H6S/LM<!>@eVGEN\Y#ey\E*<&%S+AlWBE^L6l\NyN\:%=$pN9KP
9u8h4Q @QDPdA=Z%=bN\d8b6eMJu8?1yB?@XH*HuV%DbqQQK4*Cd?K^/F:WHlDC##TPdCXyea9<SlQ:kdMKPK9E
F*D\Gc la/j1w%*j4$!M^>=Y8t/N^Sp^^DYnI6$9l@d>JbK:XM>8&jQ5Dnp4KSdE%jF&p/Hmc<4tD+wG6plKKZ#
wS:k1+ #e&Q>$YhZ&YpW8:bB8eK+#$&i+bkc*KLSP$5a1MmTl%8lL@Zny#ik!Wi+FIPat4w%C46XML4</TcQaGj
MlqSRt :VS@&NiRuh1HykQe*TFkBpWjBl?FQl5qI$NjJR/iDJPT95+kI8nDd%@=ZSM+JASH9duHQHSLnXRD#t?&
@6iXi& ?#q#4S=M:IVGY1\XEXy#j@$kPHIi@@b/+dp!#W/m6/Td+L\4^iVVlI\\JL5SK8T6DSy/6VkkApj?@$$e
Kd+kui EFRREtaYEaj@N=RCEdnIj%MyRQ!%5WIE<h8NFj>IXQ+qBj4Z9QM@dPD?/&!>!BYVk9>K@<1eTPTKTeFZ
T&uZky $MK@w5X@k@=:G<KX>BYVk1?kSZ=FC@$PLj\4G9E:6NC9cPHjwQ<?L@^1G9p:>C>ZViS*/F?8&8@Et9A9
-AXLmw 000567cad4d00110333 Page 401 of binaries1.zip
Mj>tVM X?%*ap*+q/9&P:GG?PY1@W/5IZ/%cwnjmVZE4%aN<V8^l9nX1mF?J>aR9%w%^P@Et6C9Xk*^P:H&c*WG
C9htGk <b<dT9+B@+@WtZ@6IjpuhWd5Cl<5EeRXDTZ@ND4<@#YW@H?:wcVlj$>DCeLJ@?GN?pSGPJREuI<<BnTE
tinB8Y H$LDIE!9<EZ\K@TM^d*>Ra^/TXFma:N4WSnp4A?X!k^:VWH5yGGX4ItRyEXIDV:RG+&iDY&&4IMDBQGd
$NR9R6 PS6buC$?wKit*utEp1X$d$YuPmh9k8jeh1eYG^nnpcamMjeMY/bthp#B+QEy5!ccF#8QG$FHqp@t8/1i
DhpQw$ *A*F>X#htwALY\e$$cGqVW^<5VeiItNj8E$AyhH#KQFp+@k<u4X+C/cJ>d#\n4w/Z8aBJh!k/THhn%%F
b$*XYN h*Tw4Z%QG#@#S!X8+1KZDM*=T=eqG9YmbMY5S1nLWYR5BQn<LVNd&*TddRjPWjdGbyMu/w\$EjlYLcTH
MRbma= i+=jbJ?:9cVyZq>*NyHdKB8X8HQ@GecbKyieNDDit1P=e89V/F^\GD*8C*yBKNR<R+B>:MDqeT#$bpwe
cPic9d !WTdNJC\@?$S=?jJWD!:KR<>@/imb48LMK$ZHntePkAY9D!>VA%1bNVj#5^!4&1h@Ek9J5%tHLH4b>>i
^^5iH$ yDJ@!I4D%WNyYCaMu%=Q:hq*cwwhuZDbeB9L><&/n$Q8?b4Z85:4Y\%LM&wt?1h5KJNZ@</QthYFtd&5
a4?cH$ Ewh9NG!F+IHXW>V>T95du69PtpW@JjFdlpbN5pS1$i>9>@++!GGH?D1q:L/\ll:n/LVbSP<&<\nVuSl6
:PD?Sw 9Lqh<Y!6kq4*5ZdujT?ipd5M%4:$>/Vuujjm*#cK8NTAB?yh&*8?ebuNi\V*e#<khI:Fy@+$cj!q#k#?
n\SPQd 6nD*R?u*YPqchWI@EtawGdtl1wBDXTJNWQAn!qtVywm^X<>!Ykcb<QqMyTnpwHAw!Hc6*Tcc+6yqmStc
uV5ppB L4MYFmHIimPu/?pNh8F5=CqLZ!?SM*&tpp/pi!&W<%Q1+DQTF\1HY%p!XkERmu\=aSbAWn>X\A1VQ?RB
ZyjFTM #/hDSll1\iRd^kjD*hiah9=%lj&=A/u%q!HDMQD!R$$L%d#*6%jjWtyI!u1/1pmmpnS5X#diw?yZVN+<
FRpt^& N/!=<Z+!RLBhXKZpP<YIHIQQ<KjFS1I9GA%Vaw*StE<1#*FSh=IkKhX+iDiWlakKF=LbuN:iwP6BuERQ
5$ak1^ B?n#w<jCqCAP5k>Xw^Y%jBkitL4EIAaI#4kZm!P\!:FwbS?Fy5?C!Iq48T!%RGjt:$lc:A/M#j1b4jip
5DG&b9 %8dFR#cKb<lpiaiiQw6Ml5<Z+qCm+=8aqa&CI#bS%$/56pG=w\NFw%E!h%Cay$jkuyi*X<16nBwXd#!/
p8L?Cc #yqueeQ$9A!Bkmd51<kWdZph<n$n:y6I4AdDR^umW/8F=X\k#u#jINiQG9b5Me8pQESGN?SX%tEWkQK+
<mj>=w tR>L!&<=\&iR<GBVXlYa\65/lK=kWMdT:bt^/Y4jJFT@Hac#hm>%i6i>:^b6ebKXuTZq#<m\:I*M$M+t
ibjwLd Vc6:hjwKjaaPShhGVTwdW+pRC=acqW:iSb4u6^JdSD654KmCH6i8#!<!$uTQBI+%n:=X$Q@kEZh6<&9%
SQuMye EJcX$Z=M/?ldm*F=&YePbdwt@lj$\nZ/:!ZFGh:nP5/<mKk<lMHSp$hTE5lt<w6=YB!DeR?lwanDbY<^
Fau5?X !h!I*Ek/dW@>K=%1y=ll?\:c\1%*E6W@b>Yb^Y#eFpRcMKTtD#?<kVG<#hGydVIiPaJWCnqpw/im&Kpw
kk8YX> H$94AHm/4MPEttp:==Ka*my/e1c\5+h!&6^4uLw66PPb=KSiRV$n?lFXTGylBGd=1QKl!cP?eX@<jh&/
?pwFb8 %C1c&44%habkH=5aR?>KajCpy%pA4=qB<^T#%=J9aE95Nc=5$DZTA6?AIJNZjcLM%*XK^wq:j:a<VHR@
jN/1FV jY*5j%K:b$9qub!VhN\*cb%NN!pjj$J6%n%E6>^c1atb=%+K/HMqZ16p>cBSiBdD%WD^hyp\X1j49HQ^
V1\%CZ %aRqD6w>Jqq^!Ndq&+**<mk?G9keIieF/1Z\I+@%!&=NtqWGV/&<G:Nh+VaDEeyB+<dSbT+cJEa1#p&e
HN*CWk wTVDGkI\e+b$SK1P6L5tn+Siq+!lIp^Q@F^+dZbMT4L*=dJSwcQ4#V/??NWjl^THZ6NcV>bICTwZ?B%E
?MMpG6 VA#baN@4=b9ZidXX:1mq=T9eqe:?1p8mhi*Pw:i*nWdV18iu:t*M%NdR<B1A5+6X515$%h:h\ItSKAEJ
RlJ1y@ *nWcGL$:bj@eT\Si\q^Z6#u=+wYk>an>Vtl64ph^&=V%^1nl+>STd??$S#+iw!YYK\aTKI11SyGnuDwc
&qMA>5 Jib/H*6<yq9XDA!1P5n$>?b:pyZY>DEi\Pniw!bTmAjq&Sm+?hPtPZYMG8NDk@KyaKk5XYi/blPF%dP^
:ND/%I VkceZTeB9+1+M:a8j8w&Eyw5DlZdAEalYLeP@k5/J?bmlljMcKb9kb?5Kpa/MyhhWynGuY?H1bSMGXk4
A:mDGC Q$Djb>X>+C\tcVkDB6h?IPVnCyWMP^1Se5:>nDM\%8muk&#*/SRlE51&KTYmHph$PGQEij$5jKmnKF5t
98VGt< Cyujd@&p!#K%mB&P<j=?CDuXWVq\uSL*\l8dC6JIt$*JmK9/ei9L#6m!8PXL+YQ!5t1XF/EYGaBwi^nu
X@RK6y %JC^p&6nb$&:8L&QES#9y&KpN<+iVkpG!b8LqmiK/dLHk*tIdc=@h@HSl@>6CTV^mb+B!IZ\Ntw%qY/%
R\5Glp qTFDXq$&6yVe>uE1!%%8+!5b1BGFhyiiPiS1MK@p5!qB4L:eLYm&BDScFXSZBb9h\=TnB8e%IaPHtP4Z
R+=LPh 1=$SjB>A:HnuZJ5Rt:\ZiZ$pBC*uy/P9R>&K!R!Ihqn\aC%N*cZCB#?5dEwLil/AkJ5^<C%mDFIq<9R=
%Liu?l NkM*jl+L@%S*$Mblp:=am8aPnqZCi#t=djPW%iXy9M<K+YQQ#Z%VGTW>Iw5KhpJ<1@M:QPnm#jYK:WVT
m%V51B AI^>TQZ+INI*PPkX\Sh:E1hwVy4KkMMK1?IZhW4kM#X%uB$/IWNJl?mh@WH>GkF\PX&XmwiI*ATyR4^F
6e#I^e +d1^JibdISuNDwbaIaN&I=iwuPp>/V=ykA/\&IDTKkkajIN!X?MFBI&IqhM>p#LZ&IE1%+4&#WwhcIA6
i*mQwY p&81@h$CMCTVPN<LT\*6LIpFBXlq%N^Zc#?=NhybiL%p4tNqT\WY5<h+<L#pVH^j#<$$MV/bANhXZ!C5
5J9T%/ P+AC!1XPL/!K?qQCteG4&?D>iQF>pI1hRMatEK\mJ*=8:JFIeBH^pGPe/HY>F+B>9btH=HXN4GE*Z1!q
IM8=bb YT&M&Z&E!C5K+#n=FG\Z+KQejtG%D9FAJ%G\A:Xk!\uLT5RTp>ZC:H%k1n$$TnbIHh?nw4lCRKqSBND?
CYjeb+ W8ldSu?*eICNy4!&MupCP/JVCX@^Y1qCNV>QKMpS?:1H98BkX#FuZZ6*GNZ%BDWqXDebR6Z@5?$D>wRN
Kn=YlY 1tBlwRA:+:#$^\plD9lY4A46!l:6MMy8weu?F*A9SW<$kEyiaQS%bYn@T\<I&5PmnE#@k@X5+YauFpVQ
mbIhkG hRB=JY6FSwcFJLRR+BR^6GQEPGLEn=Tl?*Vk<6iXCyTBJQRMel8<b&\mW<VZkld+<6!A6S=Qp&V=4Wy8
KY=&C4 5tFW%n%WEVJHb\nFlpZ85!NS5Nk1Y^ayacnwbwIa\qqaTAP!V!>YJ+ei#*e=ANB!:InW#XA&nMI>y&=/
9+^c8? u1Etb&@JiGn\u\J:jI@HYR5CZI#L^RVdMRW/p<cNdFL8M@BGZ14/YSIPM/ADWB@Hae=#C4bqB8^X9VGA
CwqCmd %8ikJMS^XpR:%DK:K*T%Cmi5C$*bdI\ICRW+miBkpey8tjnNZ<aIe1lCBiRnM*EGPN66JFZHIjK%lj!*
T/FXE* t4pebZV8!YC6:5i89\*tFjKa8>/4IuZR>1GB:<k%nJQTT4$e#CR@J^:P@KW?+K#?edn5NwdRGpV&:b%t
jcREAl wnyH+8ZReq!S:^q?!$XJ?GZEqNcAZ#4AX$TSWQPkjdWu<c^Gl*hmVD%yCD/h?duZD8p^e%8?G>lVwSC9
K+E/tj hkBI\5Y*9hHnSwBVy/auCBSeZdND@:KpX\Rl?u@T>pRE<h?6+^Z:1@8=mNl98=@@+/D/q!Q\FZpH^P@Y
miJ+NJ $wyeMSn#4@Vj!^t9ywX?=>+w%C>w^B@S\u>EI@?IF9pnG9XH6Pn9$Mlj=F88GI#=Q$PL@\tNlQ<SLjSH
MWhl=L NPKQ/N?K6X@W!w5kpZ>Em@\SnjwnY9TQcLE@wu<4%8C@1QwYkj<SLjSHNPKQcPE@wyF@SQ>P4Q%h%L1c
\q!+IN S9$SLjyH6Nkj$iJ@R1Qkj$V@V1#>jbLD%VVmn&nl*/J@>e/Sj*S9pV?mWZ>E@%c5mj!KF95nY9^QcFH+
^j\\<X H>FCj$Rn@wn?4XkVS9!CS9+SLjJHNP1QcNE@w5Z?mQ/6YQ6F9=tIGQ!QcKE@wlF@SA9@Ea*<I@y*a8*Z
dGMan& m1daj=:A<\@+j/lwI9=>9=u+FSb=ItJZVPASE9:d6j?9/VeV@Z@>b9?8*+#P=iC=p><@?5$e?1*mI?Pl
MQ+Yne SHSA%=eWAICk4^c:jFRTMcP5hLKlcPi#hC$/wGww8pWukqu4B6d4RtXRJ6aZI%#9hTy6CNT>=G8LtYp:
ch8!kC WywcD^LS4HeMpFad%kjjckXGtd&>J+D9:N84jcaYeaeMG5X>ZZht^4mjj$dERF5dMdqM*/tj:Gln+K&i
>+F<=^ %^bCK/>IPn*Dd\&4d6\cII/hdb4#ty46eTab15#e9!dM6&mVPcw<yS6jut+M@MyX>5uya&FH!Qw*6P6*
5J@#^H Cq\ac>F%KGA!<69kQh/kL\\*Q=4hISKe5GLElPL4ww:CKG49WA:Qi5#e:bH86!Rq\QYTXAjkB?*RCJdj
Bm!GX4 XM@d$bnZ+l8p\Dku&!^RjnVaZbQQ?cei8Ym5T=AdK%<4\XC?A1/hR+p%b9I:MVmn/$ZS>1FykS9kYbG5
?i=wRh pW5DjPR=MLDF$iPpw4m^a&wt\KVID6hu1k6pQQw<GFetV/<?hGFGuRGSKW4:XKdn@5%</$^P8aVu4aTK
6p6?i\ NB:m4tR>abA\9e4>+YJN+?%Z6Hc6>cuX:=h6*6/6t@Q\9M@*E@&5:eWtL?c&$Jn&l6YDq/i1aX=NAt$P
u6$:GQ m5TA<iww#1<@?8:Tj^A!8=NYn/?J\%RtVnll&YZieJTqEN?aeGc*8MM:6AEZRG$#dc^=>V89+8*mBY6Y
b5lG>< HD&5aquBC\ahJC/XI8L=Ti9FtGbNL!m6eIywPFMid!i@h+G696ZEY^*iGC4Zi1J=ncCiED1BQ<uwywGF
=ha^pk +IY?B###+=Ml&=Qm5kkq$*VZ5PC!wk?&#L/9*Btwbb8DT&Nt?4$nIn:MBjMl6^@:eB*^AFkHybZV\=uV
%6A*FH XVPVJ5ZlAicVh/Zd9:ubQ55GNZ#PcNmw@CCk+&ju*DYRYeNHaIILbYn?JFl*1qWB@e!lPu@#S=RY6?D1
k<LyIY <NP$nY#\6KYqJ*pRLt5j>DMVw+$n@G*Fe:c<!?DC+Q5V^^LTLX/#Sl*JdlDma%uDM!:X4LW+^*ITCX%D
\kA*c^ </eV$kuhCZWAlj/jKlPt$WILI#R>a9jm//&VIF5M*K6H5E*LdeYhnyLWV$:ankDSl+EVp<@5!KiHK6:!
qVd>%Q a+lJSc!@DHe$I4Nhamlbm\6I*1%H^eaJTEw^V%+5k#L5BNZwYdn<b*dcpeC^VBYWh?TKG65#Z?%=KLAS
an%p^P Bd1nJABJLG^4*y/:da&R6a5nSwuLT5pREX&b4^V:Q&4VLCL&*:SyFlG@\uhA@Qh>B<T9>B$R8eI=+B<n
XuX&bN bH>uj:#CP8B@C9@Q:h#@P4:&j:T>m9$:B%1WEQ!K:XZ<1ud89!*L@/5Z?9>&9XDZ@>y/Ia\DiWDAqR<B
-A/59m 0000acf985b00110333 Page 402 of binaries1.zip
<KG:F% <j@>$=>F^Q?dheRwIiG@jQNSRwnj@id@+^9!6^hCX#<C4nlRmj?qwFn$F+uBK+\5@p4@!4lE=Awnm!98
1Qdqe4 @T5#mT8MLK/kpXeuVFBZGFu<qj=:yF^NC@$PLjw4G9E:NBL^C%4+N?m@D%T>tpd?Bm&MSQ&CF9pN?yhQ
6mqHa4 jBRe>Yj+:$Vd4?c$w8Bmj$V@X4RJ@?Iu@l@L%#H@^9:dnFmE/H?iEj89l<h@*81E@44Xwj=naj6X%@*Z
F8iMp\ LSRl>I@4@888?W@ZSTC98m:mmm%W/G?H<j>FM&KF<kL5WHHSIiTqVQAlMtHbjupq*=jS+8R!k$uptEqb
lM^DG> aLBtaXhkZw56ATMa/Ca$VF:1HNai^1dew%JGYDdK$pTBm?p#=dt&6l=EX%n1EJbkE%B/y=piAwAw+1$X
+M?Q*C y6:En+<BI86iW6=YVFQn%G?6HjY<p\98/e4R\=GP:FZGikcP<LuBW*RP$9ju@*qGLQX??A6bn618j=wS
QX!KP1 c!#ERAL^Y$96Ht4<6^t^WV:=kdk*VIYYe?:nBT5u8ha\k4H=kiGFXnD/<#:Y^D%MmpnY&w:dYc\kI!D:
@k4T/m e\m6wIFKFG^+GleD+<CnIHp?#@6V+mkeY5<*lIa8@9PMYB=EQEQy5*T4?AdNLJ1K<5FK#mwB$Fi%Vh/c
Q><mc$ JVRhq?b:jSkaZ&tiHABHa@nBdHcLmPj8tEWwFljhKR48\HuHFIt4=AaXG@HX89/m?lM$C%lD/S6ZG5<:
ub::?X G<@?LN#qHM8DNtPwIVua:GMiQpTPh=K@X/QuumDH<ImMyw@Q\a+6+^lcYPJ6%mXG\96ERl95P5XEl5a^
?d*qw* E8LuTX:pIM8H>8I^w&KY6<jQG8\bawS>6iTcLp\*^H5k%%nuil5LF!XEZcCQScPV4Gt&SI:V?%Bc5hAh
wZD:I\ Yd&SGWPyqw9&L5XJL+!Yh8m#F?FCat6N%!SSKch#^1H+N^M\HY9wh:wI:^HiP$$#y>L1Qdy=q9LS5?Ae
:FlHE& lXm64NB:?5hRB\q=aY>^%%uWDA&=/dNpS#MJGt<MZh6>iW8wW9uG*SB^T1XTXtRXBCApB^LYBwl+t?yl
hGjS1I *8Gm#<Z8citB=w*+C!#yiy@#Q:wF1Awjq%1lWH?pw1FjFEJPRpqpeSAJHdKMR?ttYpEl^=Iq5iLyXYQR
\$XP+n =1tnw8V6DSyqT4pPuCdw1Ni<6Z!9i%L5pt$cnXCtI6VP>Fl!DM<6l!5\<9GFp/d^db+m<\a$E@jpw9FZ
8IIEuD Fyny!*EN#Q+N\Rc!A%$w!j9ii^EEiG1a8Yc&F@jN>St@V+lH6%w?aFbHZG>q+=^hVk+dmPC>Nq!CTL@V
bnw#5H CK#MdmAcml9tIBeYZH=V9?b5<pne6ipXAC&QND^Cd#!1CJhc9:\<eRVqHP/88VXGQacCE&+G9tu?<C=M
+AjML1 ZYL$XhM>%PQ:$RjSF?4?!KZZayNCH+\p+?=BA1%$dwVR=u?Am6@n1QE!iuun&WcLYL9$$pi6GFynlVhJ
inBYCd Fyeh59wT>1h4FRD@H<tY\qbD!k5=68P>Tb@5@PEed>66=$u8+ue?GYnh1A:>p6CJWHampKLQ^dmAyi6I
FV&nkk tahB*&u\9=E\LNlKRa\yu4E=YI*J<h$?j5uAVNXBFC%:Z:w><Eun1Wh:Pq8JwQQ<GAPB&IG$dA%\j=i#
dhkaR@ aNMye\Jn@yn\nn5jq=W:uwTwQG#tLt6ydiG%KbQkVdw%V5T?kaZKDVZ?FT/GpGFKk<uZ*15D:^9$@N#^
:J4GZk k?BmP*j&K*d=<nW!6%A56hBK#8c&bhCDTM+j6%C\d$*B\iRT?@LtlFdc*88VM\DeqKw*h5#pXk/6E8:J
6F1\JR i%WQhNkLql?J<Swq5^tKELCLeW8ay^wP&N9W#Ml!^=i%t15cKdk9qAiquSSKDDCn1!CWWd:T5?y1Ka@a
@m!Q8y JnDMyJ!6YwQM?$RM>XEJG4l?VMI8duMdh&+uWAj$AWqAaNu!mJE>LB+Y:dXyqbeX1TcK*CtpZ+D^B==R
nbSa^t QlTuEen8591lFXi%kSi1Z/:4njiAlCIH6qtBa%j=MS@&A@51ujq#<dC%KFLpT&tV9we>*&P@QmQqeiI<
5?@*N5 Gj&9B=qS98SCSn&*844%^Ze$pmeJ9\w\YNVj#R5m%t!XitXu==JHL8*^PqJHa>iNY=SQ&q#D=*HnnwwC
X8?YwL TWBbWN9AFtQJ5\ySy!JbL9lm%VaQ6=/mWc<i#C\G\1^b/YBB^K5+b&V&anTd?qtEL8$W*db+c:BDhV%i
JG5CNP =nCnl5/wFy?<$5V>D9P$t#FXjQLY6%yR%\+Vw+E1u>@eZ9^ESLZYYpPJmFyIw<t1>HdTGmKbSLR\q&uI
#9=ldY q^yKD+59bJt=1Li&%nq8h#GyIyw4L<w1&G>XnZ:cwXIZa19pGdnEGkp#d#F%yb&:RZZ9b!BkSji#Jqu$
J\4FY! &@&C466$jTe=M^Ly#&Cu6*w@uFujcm+RCunI*kI4BQdch6m@LuPG=4>I:L&>5qW=18:@^RySjq\mG/c/
yBjKqP uW^c:A6E5>Fp<dk$=4&bnCaHG6H4&V$e:jVWY%N#LP%K:q:LF@!l8?c%S*nMy<I>+$@HIbqKm!59EW\P
h?AiN8 MKqeatThnneFwPkPC9I&S/d=w#RejYKSkNK<tBj4n<!uGA5eqS@^l&D95ES9MTddVG%L4ujEhicTh%Zt
n9ACtF u/8kBuq?<Bya9/N:i6ittGh:i$PKN@4<Rj$\9@NG!l\dDc@#!lA>>tbC<kE?yA%dnD5qbS^5Gb<?WFMh
^>#SE& B8/!a!68#8%1c#HnlV=:4^lF&#QWD1$/X=#>dlbM*NH5j4FWwM?ej?InQ/Vjt<aLCA$/tBt#JDY@h#h=
RQMP^W t<:R9c=wh%b:eQwl$5YGjdd<kGHTtu%AyHAk#=aM$#e9Ythd/=cAjZWQmDH&#45?pH*iZH##V11V6^J5
nS1<RL /lPt@8YScdW*Hj?4+qb#:t8THMZEe<8T4V:/GW!de/eIbQhuIpW1NSChQl@TkI?HK>LMe<GE@KFnwVAY
$^V?K1 !^9u?$mw4%a/uw@691JA@cd:j6YNimXtlu9XN#iS6N/<:E</aSG685?u+y15R*98!4/L:CkJ^+:iqBb$
i+&IcN u%5hQ8aXT/1?=86//%G&R8bdk6taB&ltIyW%K6dHIe?qZbd#AqW$F&MwM$Ty*ZcRyRhNL\AEiNCSNkaN
KH9P1^ %HZDGE18^&qHE9b*PN9K<+*84l*Na&bj<!>F#<*wNbNheB@V!\:IC1!IbcWSuN>h8@HeNHXBMtVLqZ<?
i5SAIW 1#+N&&L$W**K/@$/ZKkP%N?V$iTT5HKTFGj#jch!S6?F+4ta>?qbt4pLX9kSH9Jb+qK56FCM@Lb@==cG
%j9tcV $:cPSYT4B\W?u64KDe<kRJML149kMw^1$l<#yHH9:1V@a=uTk%6uG=5Y4@ZVyyd/d>TjC*8nX+BVjey&
61Bb#V w56F1nFB%#***cbmZi/V:eT>keIZ\b1ZAp&mR>eVi6e!uPJ1a69Kk?Lqm$<%9jT1n<@=D/8&YaP6^q&Q
uPWWyl 6$?&>e?4>l@F9d+Ae@c\GiB^GQ:pnu&T%\*KG#^hSZ<+&9%/XI^Sdc?TDXeH$iNlBbbPXIJ&CqMEW:@H
lb1?w8 1BmHEh$*G\RJHy?1=\+hX@@e+@N9N=+t^*#nIb1D<=!iTu$w5Ql\Cqq^5qp?kZ^aqecL>!RpYR%&6415
\YqY5Y qj1kwbF\REDMQII9?DlmYD>uA/HY9n*Sn#jMjl@H6VN:iLY@jZ5a*pAp:$4C/hIAml/QDB1wIl<=Sl4q
Jj&%l4 dcIe#F^H<D=#Djy^?h^ZEAk/jm%tVjKb+@kyKH4aDA%YbcEM6wJkZiw4Ki<e@nDcj\6X?&EI$il%JnEB
+JE/*u TJRKmR*F%w<WXXGHa9ZX/5k4^#Ze^h/B8eH<Q+C:/c14#8DmD?y&$H$+\aS!4Jmt&@&ID:NkG5NwPu&C
dNdQ$G ^%y5F1@+&m$I69%KZ*y\ZQRZqDACQF=HLS61kBt4!=Mn9^H*9LVaNtCccP#EZ1Mwb+iW$cW+&I&hcljc
j$mnDA i&Z\#?bnFAC<8>4<N=m:\1ie4n?QFL#taDF#*QnW<aDB!1I9d?=/*RlLZH8cyb%^!GMn&SCJ9XEN?#4w
#<9tT% tH>F:c#Z>upp?ZXSIdwlRViIYla$\WHDZXjMdA<CYLZb@DRtV$6DVuBZ#5pulEp5mllcPc@lEG8HCEAy
dWQcbX !^TD5mCPjJBDB<ZDd\6^$cZ\L\&!^aMFZmC?hb6#8@=Jy@G///NXFJV8>qS%6@q\h4n+qC\yHwCJh6>b
K@VZyJ Ddy/QPE<Au$D\5Gu:\Vh:@bQJ6Em?5n+dCaIK#kXl$j4*QpwQTR<RtuDteTmN*n#nli*FE#1++SXTB1m
>H5aeP <pc$1BE/^L\<95QC$D6<ZWKXD#tHM=?ApuWw:Dulq^VDZjB/T*:4!XElL5:lcWZN^Q/+>QEGS\=a56u&
CEmHp% l+HIwMHn?BVahI:T@D6biM!8N%k4$mWlQ4e/FcMq#D6JM>BkW#MBwJqMINLmBNeSqTKeFHXCLn#DS/at
tcF8N9 H*tGWn4$PkCMiITXBditcBPhSh^bCP45CTj5d@LS**VqqkKV:NdS6FE=?FH86lHjlCXlTuujC6b^pii>
SbN&@# E+=q8dqXSRebNCPK#btKp>lRy\6@B88lBjC%y:B@91bS\bPwqCLMMH!k>I!1P\4EQ4ajdkS\bd#\$nk8
/ecNWE H\G#!58/GM4:Kl:8*nqd#XeueC94kIN?*CH<K55L8uPGWV^<ZB9*p+d#S?t=%HyZyRbqkaD%*Vy:w45p
5ww?Vu jiLFByRdYBM6j*pE8?L?>YZRV/Xc4<D*MSJh!l^J>TJPucQC4pV!$qInFDAhWn/%/FG?cWC9K/B:l6#6
:+qnwj >A/u1^bRTDS$E9JiRT^?VdJl@!QPEy^!/SdC:VMmbHDjbSuKwDG?PppbJq:^56%dtLel=dcK8X/K5LVY
9%ZCie pLcYj1><=VCQJ!#^I^#WSZ6^@8+aZ&BDBtp%QPXCM\My**FlD#wE:5cG/BF/LAbH5LHbG*D?NA1L*\I<
nm19cP kCZKK\mwHI\BDTCaB$IZy8ZFZ^#Sb<i^h:A@6IR#N!8ApVQ#D*DtN?*dVYdP4TIGQ=NcBL9eMidW85%D
?>8qie i\Q+a$$=6qtpm+CR6Ynd+J:I4wXGCHk$mR/p:RyXM!hAH+Z&*6Fe%eT^TTpcM4NP*=C>8/X=Zej^Qd9D
pdAniq myITm1mt%u$L#%Dq?kE%wSX<Y%NatYm@kIGG&Pwe%\=eDLVcB5T4jE9I#V<I$K5<5E5NP5Db%Cje%SBk
V#@D/Z 5a?T6K<\#R6INNDQ>Rp>5IdS*!$Z8Keab!<9ck>$YHek69>R&XjWjWC#L149Iybc=^nJbA!6e#tP51F=
8!9iu\ :1D@XGD/5%!AGTGBnK8%@tKb*KIqNmHE<a+%8/mZSB=YGppR+5=BuwH@%KPP4>hHR/Ep<ZG>Y8T5neP5
Ftj9+W 44^C+5bHJVE55?KPFWyW+I+5FlV4FH!jt*::6u9=tle1CIPiLMP<VDbAbwnp$M<><5CQ<Cbl<$a9EA$K
\eAuw? %J#kJK5l#4qtFX^wchlCDLZqWjL^4uNiD+:IjJ>:QpknmnWA6T4qkj4=P44CZ%E5b6aXayTnMaI!n+hc
#aRwD4 kwa=h+5IXpjndV/iJ/8^&hi$u\p&9mdPQw@K!:bQHV5wVS>VTFah:A^a:T%eVXbtV/:aVTGb8lHJdLM/
ym4\e+ &I*8dI6Yi<H9a1jc<pl\Y5^JLG8aK@B!9L6ZPckZG^*=%k%:&4J=Y:PeDbd$k58c$eXHD=cW4Mq?iFhW
\tFnFk Vl8n4XCYX>@QDQH^DL@jYCj9liH\N$mVi1?%jwen@SEXy*4WW8SkmFFLn\AHa>SYCd6lhq=wHQ%<V$TN
1hbV6* D!1mVb>DXu**l@dBb4BQqchDZRS6>#jAHG>L&\VjpkqN14=a@pD*9B*:E/LSPnJ48V6!i5+E&/=nJNbm
C5G9kW V@!QjuknhF56e+IBCb:q?XN%&YDSTHB9<!MICTyt$c>wbSMRd:NQCZ+kS+A#+L&S9p>G1YZh=M@J!=Cu
-A8+iL 000e84985c800110333 Page 403 of binaries1.zip
<Bab%n qTd*N8k5^=<&PCW$TZ\#tq@t?6YX=/n@&Fj@=$1PwILR*@Pu1Q>Gelj%H:9$@!iT8@>tCQF9!h%@4S@+
W=CP\W 4=P:@=K:?W8&/c>b8u>?m:>nCI&/w8*@4@T9e41wK>4?@$4@1kRihWZd@%>ypX>plFFZ6Q*@qj/XKVQ1
h++n1T m4d@9>LCapK@wIX?k$akj9HP4&n:@!9>/<VwFZ*@X@#IlH@%\bH@Kau+D@b@yMQ>c#:!u=KI\qjaK1Q?
5eeu>W 9THA9$/CFBNG@h<q^AEDqS16^KEM/pF+5@h9Q+NG!\Qj\1j$8SqJRG$V$pPTicl$H?!GV^ccYVR4lH+m
QlECQH 9R8yPB46*aP4:FY1EpLl%F:KWWNJ<uKpD=pBmqW%JFje@wCn%#bp!\a/<ytZZ>\^JZ>aR&W*9/&8&=wC
E6kI%S S>iECqj**8aLl@cEhkVqNmNYhSB$wT^b8k\AAdnbJ4cn*&WE\JIW9RpWEM+AA*B^lpW:1uTe!eZMHTPl
dVuwES JKj>D6Q!qt+DqKH+95jVQd9^uk#A&uAMnj\EpRiVEwt@DQ^=4h9jJVR9N!lJ4GQ8BdDGiDtcm+@uNB/P
1<#+t? G?=TWd^Y/^B>Y*CJm/ei^Am:SA^*ISHNHZcY6A&B<bm*kN1Y%hGt4m#6PRL<aYX^5c+KLL%IX$HmlpaX
u>9Q!9 $dLIPJJJAk1yc8IpB%Xbe$uJHJGnpYQV:LKkym/#RiEayJ+e51QKj*NPJ%Ai8wZT&bSB^E#@dR<E+I6N
XFKSGW !E+kDdWWbpZ$BLXS5t/>t$*VDhFT5VVCMjyA>/1RqhHyd>?N^X\<<*:ATF15/MKE$SEmRpNYAD\kFSPF
mh%k^L KKVA!%WeJh#86lnKV:Aiw*F+hL#TyJhV9lBc=&<4n5V%%N+k\FMcMbFHmBBML^bW1JQY$a++B4%:=u!M
^ZG5KH AkiQ56E?N>n/ML?c+C9>WI:N^8nB8$Bu=<StNtyujiGySq9cGDc*5aSRGlNyja%bad%<AQ:M>=mia^1#
dY*NS# ?V$GEi^$6<lRW5D?q>!+y*b$%FZmI6I++<nXn=\bN>deIaYnIpbKYkG/Q8jpQAC%bBI/hl$%Ry#deFZl
?NZwc> B%mDF?K%AQ!lJIeRPmqBcc^?^eNP$5A$>munkmL<4wN9#4DNLb%8NM4RFHD<XtRb1Wi/=A/YHVFL@QC8
:hMX^l <p!LVC*^9XmN8L?<F8mn8M!*>#F9L></Ca1hkT%94nVP=wTP/&wRZ1h9Sp4hY*Z*#>PcPY<4T69a1MQb
*^up^= Cl/RVZ<T%T*pe4Q5NAh8G/%$//EqyTQwI:u+?qV!9c!:KY:YG9N/Bpkm@IJwh&Jq%?h!$?yLE^pKL1%m
wBhVDQ th6<h9nmbW/eE@L5qnd:#BXTt5i9^Lu5YEEt^B$YphFnDL5$wc86Fe4p5XSBAa?JdkkHldk\pM9Ip:?t
cpL^jT bYmTYi9lcu?QKW&RhAd\teH41E^n%waKWZWA!XyCu9BAqa?Q!hiJP#Ga*JX!BT?TmY^8pVTI8SI#^K$R
aN6SjP *6*i8$VHJP6*lFtFZ^=94XZ1lI&L6BVB1ZHnN8+LHXV&$86@1=%PKIiWa^tch*yhS@KpWd&B#?X5Tbq%
^9@/Jc C*EeEj!hDXQ&BDyJDw+I/V1WdBId/IAuHq88^DCA:tM$8bqE#CDdbYucFV<ERpY4h<J5i8$#ytP<B8k@
QKkV/I Ciq4lN>FiFyY9NXpXHkIG=F4VScc^Z68iG=N6PS*J%d=jq/y%<HdQJ>RIce=X4uwT?yTaa&PaS1^JP%L
=+Y99t C/4TtMBJJJi9MG?MWWP&FuK#K6&it/H\FkF8<\%CWd/S6Jjt+eWV6>u6H1F^$V:/+<YelCKGXb#VDtIW
>eK%++ CEZGEu\yFmi95QFH6T@wBpR=Z/wyXXk6A4>\+#Jtn!Len%+IVE=u&VS&YMZ\TYG=GabwCA^El!/VYJT^
>6uIu/ T=9BX4CPtdJdwwjlM8!94P9Ze^qyepuw+@u%\j#jGLd:S=tT=\*!Ay@Jj1tj!=SX<V>1EXZDhk@B>HA#
6%eW5Z uK1KulQ:DAb:8nkQH/8L1TRZe=4EaT>>:qWSy<+XJwW+^?RW1q/?8FdRpaVtdk%miSB$Vt*w=P<<+Ec@
BeL9:T TbIQ<69J&B6%!Ekdkcm6>YwCA+&1+mi:=4jE#dC>wbI>Dk6ym:TyAV&TBqRTF@1!u?R@XEKq?pSp=>>Y
tqcJuS ^8mjBiiH^6eqNV&#dI/j4pw%VXwIwm%HD6Nppu4b8jBMPWc^HNWMBZ1Aye546dQub$$!>&5pk>QTe4=M
*ePuK\ 8M$u5X@diS+R?Qd%%#EYB4=LP!GF4b4RE^>L$&8/dm9V4Jj5PVGN4pW$i8+C<mP+W*L?>YijSVYGNy$E
$E<hu4 TYdpD8HL#>I?4dE8#9nd=dF*MGP/*qtJlqjmT4LK^pRJLnKH/E>S>XdikWCEi<9Ha&+#&jHp+Se#h9FM
D>HI@H #>j/W+NZTj169cl9bRqdMNX>aZGPYA!4$tc9y%4S#HmkH=KblKcVbWKta6=ttZBpBK^/j?64JcPV@pBQ
bF!u<l eqdp?@J=dmnKKejX@L4wpDmqnZdKlMZT$u%ZwS@V>/!&5KXJq9H^EMd=D^KFI=VwtQ&mab%We&l&8@i4
\BAyJ^ a+=HdcK!e1uLRTX?&B!8JNu:898J:5M<w1GpDK@JZ?*j4TB?P%41!Q/584:y:JWW6?l?%C^m^5%#R@aA
Cp8Ntp Z:bYHXI#HSC5YtZuYB!V4@aaYGFe%!l+6/ydhMLaADCjVIwHV\T/q4W5n%?1AqeJXyI^^jC\B+6$69/^
&CpmkY PdXF@c%\K/e:1lal:q+dMt>HWDSXVACeFuICJ*Zw8pYDy$$Rq<die?DPC:5KTRV<^dWbR1HmT/CT%Z!4
R^$IFH k@TdI@91cMtj&Hd\!qd\Ze:N?N4S8wCX4y*5&Am1NTy6IlPq>+j*m>SZ$w:JdXW*91PMHCcplQSpB1G>
4H5G&t *taPSyM9e:LjdH=yGubXj@Si@4k<R%HYpIMR=!n=Hq\DEj\PYFK^=CZ#njaFtSQQKD$<&K4m?9XhHV*%
BEC?X: =a?kM<jeiJkN?L1IN:bpLqXVc??P16VN8!%M?IKK1@bT=ACpeNSDIaY8c%G+1!:D4u=!yGJ9>TRL9P*Z
tPK+H1 K/XGmyw>$8tjRu6KdqmXcQLMiShw4VZp6ES&SCRAd$CdD\!!HG<&#J&F5=myS&SdZ%5c9ciSRjd&j9A\
NCSw$H p&!JW&@D&%jdZcKuXd5XeRCmpa^i4?8h9Fl>cumll%d9W/WFj:il*91Qh*K94<XYaadyH&&?MM>bG9dM
41+Dy: iYqyM4wGHKm@uVX>%/JLN=%N%/a4YwQ$\5SK\F\^$\kucF@\t<aPi4^dIImnHGMqmEM$/>&ZD8R+JtMQ
V4Ph^d MAp%*Kk&HwFe9MH\cei#K68/qQA+ue6KQbC%&LYdVPK+%RY<dl+\PFy+lDNMaGF4YwMlEYiZ$S:uJZAI
QwPaIA ##/J*!i>D?CWi<&9Bm1$EV&yqD?%8k?!M\dwQwqu>>:YZc4&RWT#FlZ%NqR/?NX+!iN$h9Ph?pT\L!uC
iFSQBY e#W?8WYHnM1dq66??I!9B=cLhPJ4/RYb>c:&nl/cDjJ\yuKYi^K@%IJ@<NcmhFa4#lqPh6?^y!nJ:6#J
Ca$y<* D*S16I\?nkDTQa/iHuN1mhyJwdV!:<XBD=iRPQPqDpS@GkRppJZAS<cPTI</RP1>teN<Q8Hc:@a%I98%
:qYtbR SeIV*?&nE@y4I?Qm^RcletTyaRK5&?w@ew/\JnD66d#imFk&84#hh+e&^5ZRhW8:d:LTDL!hI1MMY@\8
ABApMR Y\ijkWX!K&^&?V*H:*mApj*L^6*SEQSmVN$p^EWR*%$lbD\?RmtD@ynXZBZGHeYHd4h4+Bnj1XFRJ@yB
N!Xi+1 WnyD1b1BH?j*%Z:%S\*5^Gd<G?V\THu%m$A?KA<NPwGh8ncRhPu?1G+@nh5@Ge6&m?VuEMn@GJ<*jBK\
DP?tL8 6:h//uJ+u5m*Alql%@n&Thd1$%l8nGd!m/JeMekI&&V!RX!5W/ZQ+mF<6%/LtkPu\\QWWVVIH+YMK=w8
>5*ebP K8\B^YKDFe@%ddB9Am/?DE^d^6@!+>DXmMJc!a4XA:&Yw8M#4IHY/EE!I6Rb9y@M>1A:Cb<JX*M!kb4!
H^\lpb ?a4Gq8E?WdmPJy<qq5?>K@G\iIT:<K:=YbFk1L%k@:R84$>M8AEeyEbAmJ:1pkLk>Al!uH/nwu!M@$VI
86Dw=K SRmSBCdym8G#6DLttTMhW<mE@WVChYj*mYyPJpF=ud=hV$S$^MIV&N?<X:nuFmTC:k!$/aVkhJ=Sbcjn
<i58!d 8#\5\FkijQy/awXhjT4J\Yi6R!XkcYWqc!@Xh%N$6$Jki$SES?qNiN8l#akRa41/+dyu@W?Ai8V4JF$V
H!CLQT T&ul1iemBIk^ewq>Rbt^IXRtj&htuI1?W9ww1DJ1W?*hQup$<\=h*n8tkeqX+QVcqq&wWGSPZZQt*nYb
pk*W/^ tB#bWbq5QuL>>y%4QhcMGk\:JL#Z\m5Lmj4#1kKlB=>ClddZCISq!*qpPa+jq+Zp:Bb*qR5!\qAkM#Sp
:6?kRN XPDhVuMM%*^>*DF/<9Y++Bpw&CtWZGEG?NwuaBR<Ay9Qt=^SYKpX<qdhub/*E%5=!mHnWiq8H$&#kV<B
&FNM:Y c1qHMY5:M<*5#?81t4DG?Bp:=841uw/SB$&QGPdmqC==jpEF#NwYbtk+S++Zt&C<mA/TJ%VL<\=:@SdA
mtcbC6 h%>PD#@VQb?iy6^SIyNPeAaFLK/j5R?Gm!wDT!EcBtw/C1lat*8FZ</%PD$tItPV#XY54bV+Q@WK=\H+
tteZ^H S$&TXjId%uhVE8kGlNS6+BA9LVAMFT4WXlli&X%y4>D9A4p\a>XX9bGkQZ9M>/nma6MP6XpYHY\ddh!I
CIiSBJ XBI!Xbyt%>jVXDtu!%k%&!Xa9y\5QhQY8AAp5GtHjPuL@$KtG/&yC!yCGGw:cJ>IbXWQ9$>Eq@W&\JVc
^9?R9> bM:=&e?JamhBRDpT*6:*9FY9EXYh18Q>JK=X!N=cPZ^dE!WZI6XS9YC$F+$n\Qpa&I$\Lk#WuXnHd6J=
td&4GL !kk\w%h<S@QT5WmRM6Dc$t@@k>$d&%H6*n^L@SmaYa@>KW4?k#PdDZ#i//QwXu&wE#T!b*%Ee+&<S*j=
NwPw<n jHR6/4M^:J%D<%&NjSJM+ZyCmma95/tyS#NJ1yJRFe/hmB=RCtV86M1itk1yTG=dhG8Bt5c<mX>hQbSI
de^$cS Zq1kN^M=hIm616Pyl#$l$NiL9k8K+BQ854C>FF9RI8<i<l@l^t#JQXKuaB<$+C6J?Cde&+W=8t9pC9JJ
H1D^q8 @p4ken=XXVq^$1k+yc^D+CL#\i>iGm*TPW5hnFRPtNCl^19TW^jXyXZqL1HbEFc<6FXC=eX\d@6\j:^d
JQ@<pl ?8m/Zaw<BB44RBPn\umDcCZcdpcicD8c8Zh>hjEyF4uYYMVXHcPk=q6DhF<T=9@8LP4PZ9Xc$$6D*4td
a>%pqZ qV:/5a!QS6jDBKDSYyGlTM!:*ST/?/ZC@Q6A?^YIVut?*tlcJMNKAe/YE<HtYG&M%wPHCSGQDF4AP^bl
kM65tE e!PKew?n$i>CCi&jaNwmJ=/Fe5%HnlJE8meSeYHZ<yaa:BRDLtQpaj:de:+ehnMK6B%*1%pnZSlY\6mB
KK<uV? cnW1E@akbBQI/\c=/llDHYla^Y8n<wTKiI&PQPkh>B/N&kq%QNTh85WSTB<J6wWeS5ja8h1YWAV:H6\h
T^^n?: dlu^hTh$kpedh9hG#+/iuX4maP&hZEcKJ@5N%%t%QDVtLuq&K<ieR5C4l$Qy$/PHIaP:XSTXYnRi6H:>
H1hbLy Z%tG/C%hVW@G^I+I:#t+G4?qnHje5Dm&Ny&dbQ@a>P%p$8jT!P>:BNQ*SI**mh/QQnBhpJZhDt*q<Cn>
jTitty WaQyQpuXn@&t*XV>QmNC\+PdP>kP%HyHH<Wb:A4:WZ&WiuqCp/GL#uP@F%GFt6IV/#FFW4F/:*!/?==W
/EC1T^ Wu5E:cq*&\6k4ud$$B5u&NQ<KWIPXQwkN<pMR4>%/#%XHpXZyLDK<eh+JeFKDc&X:?IHEl5&S/=VN+%9
-Ail!? 0005b31ecc700110333 Page 404 of binaries1.zip
SA%4#e =BKu=iw\ih/*#=$tSE*/Y!cbQ&&RFGYQRT8CFIXDSli&uu+5nY9Tm@yaY/L:K9AWu@/V8$1I4DE<WttR
bZcn!M 4SRC%=kIqG$B=jm/kQjJIeutIeMd6BLl4<PuC*G/!u91IiE/kmHTRcI:h\n6%k\VKn@bJW!M^*\Kp$eY
Z@9u&p mpZWKMRW*LnM#hqN#t+/<Gj\eNteZ&b&GLhcd4@Ej4NWF#+\E?iE9*k8YBdyu<=t<dm8H!^J>/bC=TY!
Z+jT<l 5:uR@\&BVB6umSdjh115XLF>!P51XT18P:Xbcl&T<Eb9dL81d=R61iduZj&l>qaV+1cA!biP\RAnyNJR
c5j?L# hb1*wKTpqLt5hElT9ZqFB<iP1XYdjelZF<W=4yCDc1T5ap%6S++X1DQBuiI#w5!YGEL%&jp#*RDMNjRF
/VDMV= /=5ELdASWHHmPkF?PlI@Aju%d<iWHu!:WCB1I1uTHMyy$:ZI4cFwH>*@DDV5Jmi8wTF<Y^P^dAVGGyj#
mH%&Tu !Y^B#hPHS*iHKP^/KQdXuequ&lM\w=<%in>#^?>!h$#\y%Bj*lQF#ipT=9DR?DCtq<ZaiaIR8ZjC1wVI
b?e5+J P+%dWbLR6!bDK1&PeId+j!wM^kl<^uPFjV4lJl:DkhBdHE:cuYp?kG:LZe+mlp45nmj=d*F>p6q&et/G
XN*ew/ ZY1Z9w<>+lS<lM@9??Pq^+uk:4:Wp$#@\p6NMdjJt1nReiBF9VD#/D&*!H6a996dMue@TJl<8FX@V5Wd
?j\5c+ y@A#bQtdQB&!h=HbRpCGmkeXEA:t\Pny1D9K#A>9E&u$1EF\^nE8iX=q%^!&$Rp>Ippp=$=F?@4?@mXD
Ql<&B$ iFl=<=tB6iq4e6:HelZ^cmLmHt<W:!hB?<<+$/+yDI5Yjy*L889%TJMZ$PZKh&&CXHTM8BB>Db4b4Suj
LH@KDn e/JZ!18J/nQb9!:@9X1@8n1@C/%yji^LW=!8kCQTj<9p=5n%aMeq&^4k1?tQL8I4hG/dPy9K1=5X\Vd:
dahbRL >FW4u/TmdQT8+cQN#$jVqh+5peA9::\&cLaXw1:<l4MN?ZFnSYuM?HAGZSkbaFi%b85Y\!?F9MlaKdJ@
*n&9@M Y:cc=*@p>/1+@59D!N%y!C=8WFw4p\bDyAN/@W8Mci*uP*cK%:$D5hHBD>P61=ZjKd*6iBni>XAHE5b>
:+Mwh\ Lhl:++q%VRS:pI*/Vcba\?tX1kmZ&<y6Y:IBY1$A*QX?$WnmujKEKLwtl%W?6i!/!%J*b1YF!V5MQ+1c
C48IV1 QwKmTb@u>V?Q5mlJdjSd5q?u$uki:Ne*Dut=^?R\4\HPI4Jh?X!uX6R$k/</&118!SJ!49SGP:M*m/Qy
p+!d<+ eKQyHiu6?AqJTaGZnKbGh6cNcu1TuNKVT/a9Chjp1<@1<?dBp8wNV@pYb5%Eq6Tjp%=i<P/<wHA5mS<+
<<w>6F cKEQG$ie8d?M:M=lDT@bN1:NQM5!wG$%LJit<^LI%%yTTmcYDJYLF4EPNQ\WdFR%H*$*=QEc:iQBh*1F
Jjb1BV G49GaXHqc%dHc##$D&QiH>t9ant?=K>8=:T>BPDl&EKnFXmD<\16SKCMI?NC/ZqwdyywdFA\CGqJlpD*
KLTd94 u9%VelEaFBqWS6h8C1eDhRNptcJNaCqDJGEQ/J$\V5n5hXtKbAdC&+l8dGi+p\cWGVt^JwV9@?EJtE+^
W1WtyX *%%u=Ja@VKIdK^5w*c>#N*^GuyCEPY?e8&!1y!p#Ql@Lu^<P<q#p^4KLb&h^yT=<c6H^I/e/:k^G1mTb
!NCNkm S4=%uB$etP&+?*4YBcqqA!!D=6&4w1pI#Wa:9TS%XZ^\/CYh>LVnQVdJ9L+95*@uYCa+au4KNP#\QD>G
LIQwil X%a^1IhEKL+6%NG&5nJecPw4wFuCc8Z\k=CyYDQ%TM&<=TR^NFGNJAPpMLu\JFIdV1>1$%:YkYZLqD^Y
Z4/=py ENJJAhqY\BeKYuAVH=MVKc$*DpQmIupp1&D>tC?5BSdA!FJuGWl^y\a:NK!A!K<&8^PCIAqpDpTjB?cX
1BM&bD />+E\$jZ&?tbC+l&TFk$@Hm1cqR4naMX!4?iQw%%#KikBeA16eq9S*?SyGE8!Gb+^$KpVWdFAtqwlTnD
d6lVyA RtTCPmjW?MRFTjdBuC#lu9=Dd+:*bSLC<@MX48+?RCFR@!hdpFD@$dHyT1$KJT^&lXaq@FhDe=V\d^8c
AL^mKE @$Mm?I9+eIZm<!@Y/d?lNq%l8QSZ?yhK%^YGT*?q@!=nZE$L@Ra6@A5#hhRXlp6@ySFm9:1*<G@R9>cL
eA/Pn# 4uBe88K6m@>1&j/#$VQ1Z:*8@\h/$V@1#Q>JL$JiajTME4:C/FqE?G@Z@4?pLZ1KNqEklSkV^NhQVbA%
#qt@ZD E/n%ABQkJJ4e#//6nHR^+Ahw^MLDKR1qccIXG45CC^@L5mWPhPP>>Yi8bla%&QAYe86*BARHqd%<P>>u
mI@I&@ #M\RI^/5DK1@R\RdFy=T&TV^JM4Z*M@N8j5^BMYpCR#PwybNpau#dKQ&/?@c4<FX/Y!up^ymlncRpC4b
nBKk$l NQ?>4L\uBG><EqZ6cAX:\^<X:@JCEFhP+E$wQyEPPGdaeJpejAdZyk9F^eu4+Fi%wl^8MNP&a!k?pXTI
4L*kF6 1%VJl/<\t:?wjC8$&=qdG1mTH#VB!^Iy\+Mty<#?$n/E9B+n^?8Lpc#1TEcS!>RQ4qFm?aKlujINSK9R
Z=<b<X /n1%q%DyNV5*KFnIiFYw*n^:V%Iw19#6VRJ<JutlH1hRQCTtkX\LkeCZM4kywF4bARJRicEpBV\Q^ik%
9ZRmME hc$?mkPkHpyRLTwaSkI\uIZDNhX%na%t*N&8X:R#iXP1I^RE6/TS1<Ca*^!m/uE&nA%W8=RakndShM!h
wM6NP/ H:/G>pataR?Ac8^8QETS*+kaK!4+A@4Xw5^GWLKBVyeWAqF&8!>19IeN:w&SZtwMXFQQQE+FCGh4ma^c
Bm&J@p F5Z*/%eY:6NWF$^^6qZ4bEHZ=b<#LR=MPSX^pc5?4%y=wWNVRT??/qlb*Y>=Q6JBZbXK^S$!k5#4<dCt
cjJFLB F?ENB:e1<Cb*$<6*QeC1By%+Y9wa#$JB*u#C@1FWW65$BQlEcQFh@W>cady4kJ>Q+VVB!BCTRL%GP5:J
e+W%NJ +M?+FWGF=XB%Z!96JpT\&bVFEXZltZm*Ij5c>ZcGRERDqm>9GYHt*SV%enT4>?L%KT/BIJ<Ld?p=8abI
G%pQWE @SbYVk>FR&?\Bq^wh>MLpW\J4R\+/LR/8<MBj!>/R=Lt=LCI@A$CZ%PcJtdbd%Y!%t*i8LH?tnAL>BT@
QMC1!= !t@H4mX#wd:/&kd*In@tuVXE\%6qSycEcZStcNWknpJ8<L%/Q5BSa9pydKC?/JYW:pMyJin\<A$Vj8j+
lB?J<w =aQ%umeT*&%?CLtT$dn\&6I<B<Ljpu<b$9a$6R9<pD<Z9*4D:@&V<wRLmcDJu*q&%kT+KaSyPIPj1caB
@:@\@e kaIb%1Y&96k=^lS:yiS?5R5n*QuEeq&+8^y1Zm&Mtwqhj/8MS8cVNc/$Jd6<4h8LenmcCb@9y1bG%TBH
+L!Glh 9QHy8@X:n\>jA^1i+=JP+T<>LPQAdb4GThJ@aiuP@G!WH8<+i^my/BSc&HJVduZ>:hT\>XEVmYCJD9+%
8>W??! <&n#mEB!?jubXTb^6>mPRqGkF!b!8NDiuwihZCE6qj///d*\aX>!Sd6PE*LQJIP#W?H!6GcM/ytb+M/M
lGFu1X W+<epe+:ZDQqullZAlwBI9^BN1GwuJ!cWq$/YdlZ8PDMED*TeH?!t#JWkj\LHp=+c14MG/&^%1k\hGjK
A<j!HY e1t8F5jAVdYkhTcwnLNeNa?i$pLR<pTWJ%BAX$\kcJ/yK>%cdY?j1ZBHC/pc#p\$YewCP<XR*mt*q\Q^
dJ&SR4 */pEbH+tZ^+F9<i/=+?9CRiDy9n4^y5J$i?k^t*K^4amnqRSE5tB\i>M%Lc%tV&PmPQu*cYX>?HqNwTw
/6\B%W Pb:+ZAGntYA^9ktYd&hySHWNFhaQd>y%u:9$jAbQVq?EnT>bB*wBALRp6&4&Imn#ipdRMmXm1Y#EmnwZ
b%H#>L kYKVRJ1$9T>D&KnlN%\qD<V*Dn$C9iZESVk!hE51mqXBS==ywu6/iyKTRK*AT!RB6S=%$:Yw/h=E9e\>
P68e89 ptS1t&lZVna=9jY5@ZC9FI+!6K:ElA^Fye:6P1PcaB!HyCZGGmQ!$WKc^HqGNu<V8Ta<lKIudGia$h:h
uWyu+? :dwFc*@&iR/%4l8F<#44FQ6!tTwwkb@mRN8Hn4EA?eTNpwRj&#:jQS^cyWZ!jZmlbhMWTm4*@FuhZBP:
uh\@1b l8q\eIIXNaYatCXD1l:eIjCDu\ki*ukS6dI*mb*QcaM5<>I5wN^MjYL4VSj5ja1RGN^?hK%ENZPtW6W+
XiwRA% 1ejbJa?!*mGLemZkww=/69Qdw4Y&4WihBEMapS>Y>bBG4m=%>K*%I+cFcRpBDd%tYkC=KjhY9^49M^wy
M+%C&$ GQWnECNbhm@hwDqhhIu&>IYyk94dliu4&LNEjw&cHMtbd>hNbTECZY:Hw&Ylmu#:&de:R99a?B:wL5^X
$a+F6% C:kuX4B$Ly1S/Q$R=Y?ldm6=?TDN=Ae5cJcq<q=laabhtW&ua<8ktQjn\dX1%dlDIjh%w:#W?1ClwAXX
AC<qp< TQ8\hL4H\Tb@^1dEX1Wut@Xp5p@$#&9Xy6W%F@n8t6Kh#JayP9+!/wLcltIhZcbbcdYh4aQTt\k5W?yQ
eMmSmX Bwq41bZCbGqMV@K%kFF&n8<$$96+H\9#LI/A@Z:TAFwD:Gyh%j=@:Q%*WJQ@88?NI!TlJRHyVWX/DSAk
\%tTMT XDXARm<l>C1>>\/m$u99ZcV**kXFi8<hSZ19kw1K?q9::LZPe=/>9y:n:DZu&VQuh@+LM:#I#V&jt*K>
m6NuVG =u&>M?/4n&SJ8bCNPF6/#QZ!LTRdGR/M<#bhhLQ=w^t$Kj6Gmh9Fc5abV\=1%t#K#>5F1$jdbkcG9BIy
Rh5!65 LhmLL$J9+#LN&N1$mlt6/9J\FZ8IMDdJpPMuy>L%Y:Z%NhZtq\4EbNH464m$Pi9hyLW?*F!ty\>n86M*
%IL9&c k$iCc%i9?PQi5yT=Vb^65#4EWQV1>WF%m?n&mqmd%9p!%NI6=ZqE@imCIi#DS9X1PG9F6kmhqNIcpTpp
5<A8R6 h8MBi+nIbMMEG!TuY6p6bZ&DAt?l=NWQk=i6at1=9%RFFA/9DRPT^/Yp@Qne<HmZWQy$+uI<:#\yFh$n
WRTNpl V9QFR>!ceb4=\8Im$5=!wMe#Y?$QK5nNE8/RLib*$\59DNB8YF8EZwl%IbjTIjpP\Hc?6JN>a+LLcS9L
D\&pdI pdE<YmuS>EiZ@c8yD?4ZRd1Y?JR#L=>@!cA\Kq+>6C/I%i*9i%%<Va#@\:yb#dJd<P5HFiP8QqQ66!@t
buy@y> k\nWV/@eZ@Jm8A8Z4ab#yn:E9HP+d@mWI@qD:WVH+5iRWl@LL5#!lNF::?y&&KD$G^$y#<ibHwHQY6T@
<T/um/ b8El\k&J:nTDpwd$wG\1a@wJYl<Ym1&Md:mM>^m645KPnayRHbdKFm\hRFACyQm+8u<XB%!mPYBl=cB5
Z\61ES Y%L!GHn%W@ab=J^JW$+#ZFubDwT^GjD:TW1YnRa9+4iN>Z+:S^Z^PcGePKLWJ<bK?EE%kK9uMh$qjjy<
NVKDjX ^R=%*GWJ%46XAN*!++:!e4dK<=Bkjw?FK8Y/jpiCwYnC!L1q:S=w\m*R?H&CpmZ6pcHc+thX$l9kpVSn
y:uQ1G 5HIF9^hZ\c/1uXuGNkW@<AjWR4KEQiiGi>9nWLFqmG4C#uCl41:P^6?lRI/a>StaK$q6yKB5e+Pa/HRc
Gh@qa4 $\t<VanV#\$BD\N*Y:dPRN8<AV\DI>>+<k:nm5=14I/LbXYLu<ZZqcB6uYAP!J>P=RRnTJjVp8PlHpNw
DFBmSy >+Tq:A:$T6Q5>G5XH@Z$W$4Fh*w:HJ:VXme<QKW88bVVGN*ncml^C\AuL$<k/I\A>/#TH\Kdch@lPBGR
Y#!Ya! 44Z>CIHFSI\kn*FtV4hXV!?ip9QlICMcDIbcE9ey+PH\iE:18$h^:%#m<kM\I^MqkeSqZjnynMS1>!1u
-A@\TZ 000fc796b1200110333 Page 405 of binaries1.zip
Py&CaC *Qu<uM9k^+pLVc^WcYX=nbX&tkH9@LA$4nccMaPCnMR5VlE#5S<=AVcdmZJ\cG&EHXc?*eaN1@V?Zqu4
Fqn/h* ji/y%&ZZHWCb9@%TePip9A5XV=FGLCbaei+P/PE8KTjpy/KZ>qkRWChAAQSbdn?1L*@lMETaLDH@9b$8
ykHP+c FDZJYdKQJp5dLiwIKhie/\?q9MCGK^4Dp$yMT$/hpu4/BqJWuLN+p*1eh\J^6uX4FJy+R/hYc*N5*jaF
:kbD/j pk/BbBWnF!l#%V/RNA8$:>%V1&jGZCkbT/^SqZIi5Xe^cX98VC*:RI5DS+$DFHWBnlcMdSq&YBkjh=lW
YnXBAM LP6V&DW:@km8Ml^*y&15^ptw5mq*iQ%YumFuZD>Ilcu/PE&>V^B^Rnj8^nGtMAMiy^5<NpJ5ApLqA\d*
eR?Q^< 1lwV6b@GeIW1G</kuc!*F$a=N&F!AZ9Y5kHSEmIjedwhpeMP+cJ5QqB\MZCwlGee$H@+X4JkCc#kaba<
$%q$jl pWGwPhFwIP#8$+4cHSudA5VmVMJ^dDX<y9QH\MNY%5hl5<11JVJM+XhMJZbT$8=%Ph%I:>p/$%m/WT#P
uYN^P6 bPQ$k@F*+SmZmQ^S$YHNiSChh<Sd/YSj!STiTb:uM5eLW$RQZ*BYQ5R?+%aDKNTkL6Ww9mE@BphalF:c
VjR^&1 =W^/lJ@yKMk#M^J\jeX@XpcG<<u/+*F^Zq#?!JeheDABVWlyFVykIRe>qFD4<k&L@Fm!D%bD#A?@?!JQ
5VK=SI NnTb$qj!m$J&Ja%AT!!pYVpjM:PFp/q\?MtGlYB+BbcjbG9jakS<Xteq>P%T<w$:54:c!<FDiSPjc6#n
Z=8yk= >hRJVn4idjS^Y#5Qu$Vp1+jXhJQqG6BwCXuX8>may4:pM%ti6kp6?JnJGLRc=%1Ga@/pbYaHuCt:Mq>N
q$C+4^ N/KG*L>M/J>>9Vup!XWZN?RB/l@V4S=+4ktP/DjdlejmDH6cwn*1=TEi>jEk@nm$wB%!m=p6XCCbDkw$
%Z%BFM WnEdDYjK6>%9DP&dc*RHM&$1:%ac&S+1l*MS&L$8L9HQpI&\65hpj=w=L8VIKbXnEF+qhM&HaZ?I\HNY
jVEDLn TLQ!/pI<kRuwEFnS#m^M*p@XSi4^>E$SFe&kc4qFEIly*Y=tl!Y*C5a@NGw&QG6I!jGtc9K8Hc?\e4nP
$JkHI= IBi+8%i<mb8!$X>Jc!4P$!tZe=HkaKYIppyb5A>PAaaJJ9VbPl\ZdCmjRMF#4qLp*!d6^aPRjePiSlK^
:V&&B& WCn+<wG&Z:l!5Y+X>+Qaq6uneKlC^Pmu#1GaA?:QTiDGdECck$Ll&QekPXA^R+>5SF+\l^G$uc=eGXcp
=yY^GN cIyqmR8?L?m!DkBMiHDm#6WA*QLZ\MN&EeYp=1FDjIW+X:mHycFZ1pW*Z^j9HnN>BtuZRFNyIpwt?Ati
daSXQ& tQhJ=?C^/b!FLIVWi/LVXL&JA9wpQBBq^aVab\S>$Fy&Z&!eVd1<t6tSK^/N!1+ZXkeSGLdlyj$V/h!K
BNYuky ui\5GFn1B\lct8<*<!kVBM!Ah^jY!&I5TL>Iw?EH69pP&:8w$18?:n/y$YjK9NT8:C:H^Xebt><6hN/:
%@Htl> DWT+jlG$8TnVH6=9y^+IVB>S=kAND*WiblAF16SKLn/:tGEN%Md\Tl</Z!N+$*<>9Rb<l:kqD%^cA:Ic
5ZMKdA kJ%bl\An/$QI\RGj:eXnZ48eX1#bwZE:wR@ISnNylC\b^!IbcbMe%t1w!PnANpDA!ewIH=HJj<>$6HIe
<4/==H %XqNHM9TRNG^Q5$Mb>q*a\Ej!icJZI9l\%8=>YGw/j5Cu=/YE5YMHnFiZEZdZMe5Ld9P8DSm\V&qTkGm
SA1TMR dSFJR!1WNI=qa^%Ke$bDji*=t>BTRha>ITiq$/SDK9%<N@$Deb/lYVa:VLS>XuMDGaSXkEd/mGtQtqb&
tlSZXG yX$W:NlY$ZFp@i!nT<LSTF>*GaRM1k\*V>kYn#&TT8WT/9=KMiXVy!!R+qLW+#%w*Mk8EkBLc/^e^*Ru
6m%ib^ JTky*G9qbh=:NqB/K$/qqY%@E@!XWa#Y4LHWJuXC6D:jqTQ?VjCSB6Q%G&dhAalwdcyace^&:>MpaFbt
LPu1Sk W&QEH6y/*aZ&LHWuVijm!6ji%W&5>q::\Gn>+hilD@i+c/J6%l4e?BJK@d:PpKi+ju?i<VX%nJ9yTLi^
\VuwXQ uhR>hEb1cj$tuKG^\S^4pe$l#H<ah*$Ci\ekH6Ce/D=lt$NhVJ!iELp=KIdKtd%!LVt4d\BAy!yQ5<=c
Ka=^HR iiql&meCDtj=\>RlX^PqYS$jd?tmy5:mhBl9L?ukLGMyZwXMjD!Bm$qPnHuHKJ=PqEG!<p/GIk:t!8K#
<SlN*u Gm8h$+5X$C=5La8:A:Mb+yjktA:&Ihl6k6R?KS>1A@ihb?uEGJZD4ul=APTLW=l*1:hh&pBbXQG*%!mS
wB=^QD <Ei&>#*eebZ1Z5ea*QN1DhJpcja6H5pKYqj^dG+\RQ6+%/B+VqY>p#H<SlE>*SIliephP1G4#5YlueTC
BM?nWQ >^KX64nLM1#:QmtW8GCGZRPIFlpF^Y?AEEJ5nJGGG%RG+tph!Ah=Cde\+K&wMieY@RbQlB=whV=y=9\i
5H1Y#6 hV%iju<9\G&EyPP+qVQW$t:Z/:u/T@+uW^WjX%?@MpqFK/1y^KCV8e\MAq@Vj!Zu=NiQwnQA:*#VFEt?
i?/lEP *==iHwFJG941:IuX:Fh!qumpMe5pV^cl&FTSGPLn!K*C&F@qj6tnYSZE/6y#WSG1X1^cM/#pWjFFaaTj
ELnwER anHG#8iy&V1J=6Vj&AGYyw5db>tnXyYWd?HJ!q>6!NVHVIH6w/GyZPjt8WI&HtmtJZM8%K?mISnIQL#9
mRQY5& Y4jqhu5%u@VwRDMSE41$6BC:ta11&d:IX^q@NY+bIGPJ>n&buhl>QC1=d=S#Mj48aLS+d<\S&%h%&J&h
FN5yNV XXttNSF\45GCp4Hk$NqiKA<@twl\:?1/?<+tCqKe5KGytL?9YXmqD@hGBX4/\Vw@8S>n$6u+bk6PcwKc
&#MBEa I+P@S@b*5dDwj1u$e+4Pn95/b=4aAj=G!E:#Le/tFi*/8eGQJF&EtYp9ymFdw+mtQN6*$/X5>9/D:H91
Jt%Ge@ 95&iac6?PH$#%E^!@nHDqHq$/t:\B&=mJ=I<*C@EBYFEGI?++T#:F!Mehh6G4^$d!J1:58?L*&emnuy>
BI<?>c 5>J!=#Ti8DdY*bGJaD#FcC:8KXXnIRX9dtDt!CwnV9LK^HD?^Xk:T4^%ulFG?+c=kVZPka5w@@*VM1PN
jy/^t8 dm\@<aCVZ8yPQPY:hk&l#B<dDwJyBJ8^>h@#>#<kTqcLSV1R\V@4&/eKl9!?Bh@uZI9T^iM\FtFVi=mC
YE1MJR LSyCB:E51d>eHeXcQ<E^DFp<KHb\yyiH9c=@W<mwYcTd!51TV5WGn+tqC\XDN:e:+JZ:A@=::DM6pG>h
tA*dq8 b#qE:q\LP^#?aZi@Qp5?58R?kAtidP8dQ65&NLF1DJQNb8pwMw:VATYyL/41phBj4PW?!h%H8wwY$JkW
wDNQbj VQ8jjp6==d*IRI?jZ?j&/8t#HchAmw=G?l*Z$4RLGpI66HPY>YtDt8W#p#Han6<Lm9wG/YjW<ASD\h?%
JPLK6A LCAE@$6dFlCC9&qbeQ@dS$1&F8:@+@#+d=<6>9eZR9>+IaL+?\9Sj*eAkmJ@d@$VFQu:Y\1KCQ=>%+tk
1jaMIP !D<\EeS@*%nEJ?Q5?dh9VaD@@=EWeDES$d?cIa9>J?&G$D<ZRmCE@4kR+l<D:j<+K9?LNj9@8D>@pId=
qc4LdC m#Z:@$\L@&=n#X?5&j>u?4h?+m@Y:Q<#@Z9D<Bh:>9@mG$j<bq*PZ?#b@\9/h/8hlQ:n&6b@5Q>VQ!H+
LIKeP& Q/^6SakI@5ZbE91L6c*CAu<:!9<*#@K@I<>m<j>XuwYYn#iBklD9kZKnAIeMVFCWKw^Z\+wB^T!BybY6
SY/$ll G<JIIE\#4Fbcc#S$JEIy8A*F%h:mLD/a=qW!wtiTiTWtA^a!5Xn19=>5!B?CF/AlCaH:uJBytCL*?YPV
5/AE5/ uyCK#L?Mia\C+DGwQTRSCpXLRqNq#B?wJ8<+WaCFq>TXt8iH#B>1XH51/RH^e8qy\\V:TeZm$9\jw^Fc
L<YQQ* DGq#p%TPY8AYabTM8hbLi?S:wW@n\cRn15HZ@%+lPXKRH@G&IRF!VeQ5:pE^J>MW@X^FYCNL&CqMl&CD
YD:@wd Zym@C*iq5SWMZ$T<hc\GlXJG^:\ZZbIq&BK>4+RWc+\F=t%yc6JI$a?Pw\:R9cK1K1R:*uhPdPcaiVH#
*%X<@K WJyLC&4Byq$aBTHm$8>DBK?1Zy!=MF68*KHVHWpK+:PtRL5%84cDqBayuHAF8\!a&>yEdB!cDK$49L=u
PcekjL LJ&9>j#DFD%dwwu!1Ki+/HR8cEE%wW6^C>K4Wm!P<dC?HTZ>ja&+u/Wc4CA?\@NJXD!&6#E=N4TVhGu=
QGP+aJ 58Y:=D!A\V&GFK#Q<:$@N9GFHGu5i\Aj@WR/miXI5\^>MuHLXNe:Y8qQ%DK!dnu*hIbP:nDddpnjbG6=
N!t8EN HQ+W<j\ktl:<\N1qM^RphLX+L@1i8%H%1/plt6acC6u##n*N&Ii=edMc\ZK9&I\=bHii\S5%cBl+Daa\
h&:\a> NMEeqmJql1V+G5y&?ZRj*MLG!SuTXb9J/<9X#5YePn>%46:&eSGPq4+q%64yQF=\4BdHTS%EIQ>>KWqF
+uqH$p nA9T%TPIHeq9##W\KS/wYB!d:<t\>FcT^8NA\JjVL98EmHdJ5tY#<5luGkNlB=/+ESES$85eClM<uH$8
W#5jlZ GPyd<w\8?%*a$wk$^%W\8&BCCi@dV=Ep!&A?^\Nq+CQ*/$CF>kT+QAZ69SR!K^pjK+PyVKW!Ri6d8Lh#
nbFTnt ye>yp+8wKB4^mPcpN=165*cIQ1<Z#MlQ*w+TdQRw&Lb:Kn@J?qBI@9BVXwi/<XuZ$PBZyH*84EVK#IM#
%+6Zd< *pYjeTuyAliXJA*W$A@IddB99KQ@*DAR*JVLpypee#8L^XcRhX+#E$MkdEYQQH%F@ybMp&RB$T1/b9:+
je%K=q /B5!j&q\$AXD8&yc:+=N9Th#ViwAiiJ9WEQtIXywSw\qLljG$E!!>!8G#66S?<R64YZVbL^XcRkn8h@n
%e$VVZ VSiihXl/iF<@uGa=^:4u!%TulQCe<L$BWDWZa?EVnQ6PlRDLW?qy<QiuB%NVIH$aEV&>aGEVuY++#1la
he@+D6 %kqN41#L$1T9YZ#YP>aZ^+p8E5FT<5ER^E6lk8$5\JX>Lp<h^&^BqIRel<61<Pi5+h!A<TLIuYV@<1Db
ILtNHu Cl6i$n$&<%p5bmaL4ilV4Cch\Tp<Lm\D+>Vlp=J8TTQt#FeKdXmt=W:$1PldbC@q&B/9!6TRj!&V>hq4
dLY6ec G9#^9mJnT+<PwVIB>$XFHVqMy:Fhq>:?TYJTRmb=X4tkHk9qjel/$Fkb@$DFdj<R5+Bt6YXcI:4XYA%p
q&Y64K GT&A:c5q1<MXld6<wHIS@V*?!8CcBIe%Bcc9uNbtH6\qZBX#tBJt?<Q9F5$#hcT/LMGiBm^XP1%G&knF
DT$8:u 4&+:&>6yhnSmYJe>Z59RCqc*#iRXn!B/GeiK%CRLkhZqYGNaeY9:4heNp?mZ&1qc@ZKjyBG!&^NbP6>>
!!=GV! 51jV:m=T9KCbpi\Y8XapY6@QD4alck^TDCiRCtZ1K?R&5Bp*luiQ<hn\>/n%#iWIkpnQ*W\mK*wmd<Wc
Zy+MdW NmZC:un/&X!pDtjjQMDXb!aG*Nd9d$e16^cV\/C*F5lu@LDdy9Xqc4h/$p*VZGa1t?B1DZHH*EQ#6C/5
l\DTbL >a<94RXY6WEd+:EWBekCQB+iW@FVI=IG#e@bGm$>$:&l@G/&Y\^b/$hb?#AdIC&IdIVq1\w>%L=RKTb@
uc@Fe^ jRhTeG8i!8bE?ALLwcLtkYa4$q#8=6juePE<>9NIeFV4$mjQqyLqubmLEJ@FGXXXJ:A$m65q5wuJeXQ^
@H$hV9 bClb^1d9*9S1%1pTPE**PM%u4Z?dkBen?IlMJ5JJdqE4Gdw=mVBWCqp=H*y<#t$JtbDYWmy&incbnkl*
-Ai#/H 0009954472700110333 Page 406 of binaries1.zip
Riy\/E KKhS*IWkluN9DSnm/!5:+8qcp9A/FWtV?$X@:4L!mT?n1BV8F?WFd/uFBaF1jy!Jt?kN9=9$\/XHV6B/
Pk6^=W 4$\*eWhH6A\Sh5y\8Bl11JcN/?/Cd?WSLW*IST9h&RNTEqWn:wjhGV!=>IJE&/Cy948/4Yw*9Dhw4KG/
?@H/SK H>S5<blmIb^%W>^w/pSIy6&Z>%d+IK8l5/JM1<myRb8X4%Va$%iWY&Wm$npCZ#cK>9N<iWuY@dtLZdwp
MRZuHu AH/@<F$^=JKLWKZqecu/DJ4k!I8:6e=G$Dhd5+cDDm\LqqcZCXd9Z%LZ:CqwqJe=CFqNmde>I#eZ>@M+
Htqm5! h+=qYDy8ct8N$!h=KDdn\>M!G98!ycnh6t69w1A6iNVBLc5=?$J^k?T4AiW<=?D!Tm@tBj5N/!iN*L%Z
ldW!MH %+4W#GYCu+*9t*eAY\kEJnn<Z6bJZnSmHc\L8=?MRJR/u^H%>M4:jj&yQt$=1HHTKX!*hPimW<5<NVNt
e1ekDd pp5*#GQS!VDI@nX8H8DYI=HBW4XHq>p9Q<ZJ8dwweqWZ&t#Y5J&CQk8Qd#4IJKHQ=yaX>SiL%:S4*nZB
wRMlZT %yjD!5blFCjYA$G>bny5l8D<MjCRS\&y\K&+QwS1#u:5>ahi4$P?t@=VX#\e=A>XSjA=#T?Tle?Ve>FK
wKl9DZ $y5\?Jp!PI/wat9@<Aj?XH9qn%8!R%ZFjb=5mIBw$KnhPMGAE#V/Nbn^XJR$4/=e8S*aF+?$Ww9Gke4w
aK=>%B Yy8^yKN:ctT>#96BLih=heTG:eCwhGKmtqlRXqCG+NA?KQn8a?il5%/cdj/IFFpH\SGcBtkQq8RtjQ6/
qIaP*N @ZRhaXY#K#>nBVN^K=K/Feh<K+Ea6/VMZ!%4h*K8nHQ/hk*F#nu@/duJSYZi/t:d?94pLSDSCq9S5pNF
XXJ>CB Den+IM=6QH=8b^<HRK1+ZV5ZMD#SNmy6FB^:Y#+ZeKF+CD9j1JGA:l\c:%!TSJYVDP%ZkpCy$VmmlL4%
F64<in B#qy^DnNT1@dWDKE$a?J!<#p8:i:mbFu*C*!@Z*N!pD/<ItP<T#M5K+BEFe6pt#VbT!h8!j6mM6ZdyL\
?Q5eQT jL@qRDtD$K&KSRcCy<XaeR\=Z$5nVGnb@>dPVyZeu=HA>+uI^V?4d\EWlu5P=/w@etyYH*y%6P>ZTJyG
:+SqC\ 1L!VpJjM>hG!8/h=Y848!LwBBCa@%hRXNtCjlHGI#jDlhL*HdKjh\JZM:RRk+<4EbYYIXG+1pnaABEG^
MRn%e/ b6qdYGFWqF=w*S6d*icyXub8P1QDnk!*:mIuX@w+Cj\6ny8/pKWTWG$@CBWKcuWcEMLb^lRbN+Ke?aCD
jPtRM8 dA4VjFGuy4da>QE$1!$QS^p4IYCbECnCa:$Mi!\pe9V8G*JFW!*FLbRt:iP^DJ@WZihY9tT1<imWJIW4
eqj$i& P*LShl+Q@$9GH$:dAJ\XLRDMq<9uG*1tTubPl9hcH@JcnS^jPG\E\Y1P=&1VqVRH\uGtC?bRKi<<1ZF^
%BW*Nc VQcq/6hH:*/Pnm8a4SpAwWGD4KKc>TEDyXBD\b#m^y+MI46Dhkw:%GNJb4>!<kqQ!%=K5L%EKFN6eb?D
W:C=ja PZKF\!Sa\GwQ/8MSEM55T$ZIq&A\4TZwNmE$#lA/bm@Jlb6bPpEaaVcRj@SR+#YKMTb<@\beKL4YMNMm
b1/PhY \@Ee>yAqITKju$e6aNh$!?>1D1wY+/aZKqRc:?CSn*\jSlR\\5/q#tY%1&nI1mmEu:SSFKMJZauMH$tT
GR<up5 mYGT>#K5ZeK!ZBD*Yyn#!Z:VjDa>y#l!=S>9%eBQ8Hui*!5@=Z!@!e<dAFNDm/H*%6TA<Fh+Wk4VlwXY
YFE+9q #51<9wwpjYi8JZE1aSZupjeXEyK=Z#jhb5XlCcbuDZDnipYy5FTLXdV/1P1RCu+:+BY6yNq!=A#tj<HN
@G!#J% NVc\^$\wa$M\W\Mp^LXmT>wD>pEQ+P&E!q4&V6%ce1!SLq$&BJbE/<%KCMkuC$>kF#SJ@QHY*b8yCMmp
:qu#q@ q#1n@nwJT=C%KQ4MBM85PX9VciA5CT#%EKJ<l1ttea6HjS5Rh#>8ila?1Zj1nGehT1M1Q:+?1Z8tYHLG
tbVERh CIG1:lZcRQDBm@QQ<jbY4M=m191e>eF4$FL>5mLyy+/Kyud*eCeb!/$u*N#F:V/%jY6?yqu4iw89Zai#
6RLEma Jw/4t5D/B$P1@b&!KQ?LLR=dF@W>clCuVV1^aVLnHqGDec8cVj$uR+jmZQN6996a@1w=Sm9PBGlCT^wq
E:Fkly n/FTwDBdb<Ip#$dyBJm@M<VL#6wcJ#V^%*%Pd^d:JeKh8&+JFhWKCnAPFlF?Wk@8K9tyiXZ*cN/WM%L<
pRtlp! H*nRWVcVpR@5#:qBR\CedJ4JD>LV5dhH&DbWEk=&#Z/N>=MhVQ&e&MLn/\ky\$Hb9*C5wbnbNV5<XA/H
bSpTmS pbD#<@?c<AjmyEC4K=%lnyTcW=<Va:+&QJEqyBw@*TAdjiHKK>V?ia5tq8ap+BCMwewqhVV6Y^RhD$EC
VpT64I Q&aQMknl>+TtZ1%iu5bRt#*@VP5%nRkDcL4!kjWmQXRnqLkWDlEqT<tZqq^>tu&&GHP?al@lMXN4m8Th
94Lw^c MX$eK+VIT/W6=HK\tcqM4J?GaX/e6L=ISYbJ#jh>$TNL8#eD@EK#T9h$:GKAM%hYM^+w:cI9e?j%D9HB
k+1RYW pZCYT/4FJLZI>GhjZmI+PF!A&QW+5/BRaZ6NTSBXt+yZb@bR\c6Gb^jHtWQqJX&R%?Fl?kPB/!aa6Gnm
H:nyet VMH:H4/5PR%%l4ZFXj#EuwjZJ+1+q?Iap>%F49#wF!DZGN&cY4!+iKyy\VAPwq>6YLBc%8pTw1m:d*>m
%qaF5% *bPLqtdJLB4kd=Pa^aFnTeL@?jH&TpY*!jQ!LwE6=cN?WaI&lDd:\I8laKyiB#WT4h5YV+%FVkE+?iF:
&>i9A: AHe=8lnCZ*ktTEKaBjwEdh#@Ic:*5b6Nql9lTi\P8X$S$kN1upnALYmNG+YDGhWhJ\$YItRMn$4DSaT#
^n$$^= 1eY@pcl^eddT>GLZ>P#DZE^%a!ETJ1Aa@?9XYA/&\uH/qDB^mPnQ:NNQ6N&G^9*u9IqFeiV^1u&LE1RS
>GuH:? ?lu9%LwHcjBm?hAAd#^NDR&D#M#<RFtEG9FIJ&LNWFl$D\SQ?%1d%YeHKR!Iq*t8!Rw!!B^LX8BT!/DR
LD\SHi VeaLRYN>&iY4R+\nI\!%aD+w5it5Jk6QMbd$MYGFynYFuddcPRc:4+t=pXm%#HI??W/HnH8t9Y^P4h4d
qNR/?b 51AuM8ypHD\9w&XT<iX@<wZp/w:u51?@HZ=MHq:lG>:bPKtX!<5e=^AqBKL\6!E5eS9d*SPLb+WW!w%W
YiV:D& hReZb?qCMuc5hP>wXL?&&<6S=:6n$9\6eWXXIVlDeDqbpDnFc@%>wX^dWLB5Nih<<c:+eHTK#$4c481P
DYX1Yq SyYN1jPtNPFePiieL$6/ReSGRh>pIS/<e#jNGk8$69J!#M16qX54K8=V/PiZt<Y%!Q4+15a9uMQ4$Fa&
\AumnN u*9Ak6W6ICd9F!9wQb=WjapFbmDpFam+q4XjI$wTa>LjAF+C5^Y$e^DaM%4bY@cpb\M%dF$%hpC&LPeD
>I!FQp wcL:iJ4X#DHX\dHN<*!%4GXZFPLQkS<4q5P!8!PNFca$%e\PLJD1tXpIH*4k>6Pe!mXCqSYDPXhLc/dI
$AM#+l 6DYNmIJ$?nRluBi9WH^SEaS\9*^ZY/^w9*uDV1juAALBYy=/\Gc#T?pXZ>\lu*@NVa&:NIeC<5ZlW?ph
>#LRLJ KZ@PynTy=T=HQZ$6mNLJIbW6Jpd%SZpE:AdM?ubZMV?jI^HXtt?4?XwVdX$#>+ctSek@jct<Z@+C*X>X
nwED=1 R?EHVGa%%QW=VbQ?LFc:QlP9R4ej#q^T/tR$e=M4@:#W!kW!@DN@n<1:iZ^anup+@FYluJQ#YI*@6*Yj
k5y!W5 ?E64@SjpXnXCjuWdlpt8EduFYW%!K&>4kNJNp6ED@Y<cduyHwc^M?=<SAiXXhN9\lGDX#!#bM!>:&b\%
?H/*K% S=e^bJ+SKQnwyAVH:9B>9AC\A$/ZMkCaJquqJXX?l>\m!WRiQmVC1X6XLGkN1>TwNb1!ZK8@YA>T8ui9
MRqNVl XSQ8@=E#@EaMY1dY5Fh$T1k:MAW!N?LVmZD4e8VL^?RScd1Pqb4Gb8yPWQw!c@1LWy8GG+b$YT@19Ck/
?TG#yk A>h$8hXeWRZ5eaZkV!+=PZqciciTyHbN<c*$F>i8j@ADmm*lw+T&>=:%=*e>hZPpF+^^kai$X9\T9ne@
JBmnn@ Y:?cG:@eeC1c/:#ebYiXHhHh^l^h<!n/QDK^u$q$/dNb!Ht?6XaTMM@ui9*ucY5c+&#TZew6QBY9$JjY
DJbn5@ 6JwwMjMNqYYjk*&>NdtWc+SN5FT%dbt+>P@G>$L@ycWnCKH@:E^eSQmjb?ImRu<<E@@:EQW@ntj@wk:$
J=$Q:% H/4kD&dmj%EH?5@$9^Y>@VWN@^Q/N=YemL?wA@%uYpnwN^8m@1IP>J>yRdHjdN:@m#4R9/BFj8MC@1IP
%LAe4\ >J>y8Nn9cJE@wiG@8?imj$D@*mV<SS@wZ>^$@6<ESBD<@^I6<C@Sj*Lajq8%kBD<q&mlj+pY@1Qn<l9@
9VCMt^ kpD<T@RjHVcS*>%#$Z?J@yP#B9>NG#lClQ>jwkZ?JjyQ#lye?Di?:j@hB+4=j>n@1VEV?l?dtEV@w8kR
unjSYq <V<&lj=*a\aZ?#<u$WMq?L?=/FC:<Yp9QbR>YGw</8ZwT:u&H*ShFmdj8d8^hZWkE9ElIE>Q$A^6hVB!
I\l@1i BmFkm6MpFF8b6W^WP&1&VX<#&1$P=66A>qD$B46VmRD\@FWy\8+npS#<T6lq+Q?1wuDWm\9JV=hV&u*E
*$%l\u Z$+FK=RBnj#6lp=Twi5%>TZky5G$WKk/ZIFp6BFnSRFN6DDmXZGqY+wE*<jbj^Ytd6MnEP5PME^DBTIH
YR^CX+ l5eEW:=T%W5=mD%RVjdyFY&@<PClEJCKESNRQuLa*8=Qjm1tCL<FlAu%S%8<c+tn+MW$>#ciTGnICAtV
@Ac/9j Wtmp/w=SlN>CG:iw%&&9aldtW%:yw+Rb%Zq=qa6pcZWca\#phbQ&L/W$y!8KN5W9>>$bwwKaZqh#jw^1
$?lT$9 wA5:wl8lkB:jiaIjt+y:$\dVhFGHG$e4V*8ny?utBeFKm89m6a%GS*L>Tyy49eC1wDP=GwhRE1kY8hBR
eyYh!d 5>GZPCaKTLA1:tb>i55>WZ:*b>\J9Sp<c>R/mS+%#Ww<h>YX?MaCa8+Ve5><Tby>G%5cG&H&BB>K!PT&
5b!:T8 S^WXBI8nIA\KKM/#WhK/y:&65$58QL4l<CH^\>8aedCG85hYKE1baV#^TQAbTbJD6kGq!C4QCmpZWIjG
Jda*bG JGGE=LC:?V$GmSG5?i#wTmWVI/R9!6eYct<4p#S:Z?GD8le=FIwZ#y/*yJhKS#NZ?Ik9Pk!?c@F1*FZ\
#l?Yt\ jl&/6eyk%nH4BS<BnFJ/R/bc*hp!wd@T1#j6<Xe9*$Ea<=BWZ!lh1WQ4F+yijP#HH^cjl1:^iBNc>C/F
W/+cQ+ qN<w9:N<8t*WTZuV+yEhLNl?!/Dp8Mab4pq+yXn*e@^6tQCb%F!w?K?%h4<%hLF^CB=a&bBm^M4*4N<!
?\+LY9 A*=+FbQykDq<1!uMiqyQKe$kVjSklt1I/eNwqyWT?8&Q<q%piTK^mjIaT^8dLQnHa@i8=#k9j:Z$4I<!
tYabM% dL*&+Kj$+@Y8K$+pjt<>/jm$ppB:cVVwy<1yJ4!d1m?c<yki^lkkmmyVIL/LIpAJQDB1@NV$%cACX&E$
Sauu?C <HQIXM?//d5:RYiGQW#4GhHpktA?l!SeXQ+wDXYGWtB%GFZ^JR=baRBHGFF1IVPHD^Fin<E#w5>\cw\W
V/=qph YRH=TQ#MuY$y6&?G6*A5E+4:md4:mat&@YDTyPJ!1Amn8+qt^hkNwHVQI5KECTAE+&<?GBlKynAjuRqZ
tX#+=> ?Ay5ZL\8Zn<em/qn+u=6QSiww*TkmB#KB516WL/LtwT>uG4uu48&yB5V#FSPuH:W9T1wbP5E\uTTAlCA
-A\GM@ 000f6a865ae00110333 Page 407 of binaries1.zip
\iibKV >h%*GK</M>1^T=yctW\!FZR>JT*!>H!*d$t/9mwTPZMp9q9\NTEMRqY8\Fm<b?5TE/&mZVpuc<E&:bK6
6iFAXN =pR#GXqkiR8ZNE#wnlet#TbCW>LibV#9PSP45RXHapLi6JR8/:XXqM&!q^QH!8N:8?j6$VmC#mR6\AdL
>cpA>J 4+R^lc%ibHc!uYG+taZ?RW>W*<E:WhkNhqJ+kK#!EEKEnpk=iIaRXu<mZmT?ut6mYV+V1I6L1IDQEMMI
Z?Y9>b l>cQhmM+*4BW&qplA%e:>=wc8VTX!8My?D9qtkk+K+j>Q9Yj+P6&Y>+q:*=!cp1Nn*NIW::c/yX\Ym>j
Lq4aEF bub!%C^j8@/!X%i^XZE%S$>l@KyS#NMd8/A$XWE=VN1?^:S@=:chVE*chEjWJ=9nVpLk4Rn+MLj5?THc
V8XNQI E1\Y?4dYHtRYZT*lw*Q4bK1WYj6p1:Z$M:c/D/N^Q/?mJej4a4SV#1Q\!J?&KdS?XI!i:GhPdJS8aFn8
1pT8ID cqkQA^=9>I5YSTq<A$NmT5Y$>BbdZGX>E?$ZbpiQ??jj1\NXq\=EdW&cbHBwWZ&YFI/8d$#!JS8Gc9+>
5ulF5$ %4Z5mm+mXFypYG$M!Geba9ZTL:$Sk>q>tleAw^/ZCc@pP#ca!RR6LX*a=ZC%ybGaLi%tSy@!/16EY8GJ
=QNi%L tH%@Q\M#VWE<M>ij^\58+Xj=/Fn:wQXJ%G/$m=yQ:D5t\/lC1i^HKNE%X>*8A>mLImmAXub6e?wpqwFw
Lh:Y!y c4T5tXR5+$:W^a1j1YlLmtTuZ6IH9=<%jN:CimEy4XDZEEMc#X<QR@Bi84\n>1iqpA\u^GcpH8uX<G9h
>CB+@4 Sm$tNI>cukMd/JbS%\aWCc??lFI8PC<idjE$T*LWWk?kS94#Nu4DqGZmmbaXql+=NQq@CAHYB/u<pQJw
>\Yti: eE1b:6lJpLQZ@5Scp\anIeampXIEXT?V6Wh/YB<6i9KibZ8>Hw&hMG*##K+HE\qWy#MJGlwS$*Yi&n^=
l1%^>d +h!6PSc<YJWA+bajEe!*bK!:8@hBa91^R1j?RCKB\^49L&DawC@ae+pnE@mX14kmWGScCHi^dnJ\#5e/
J:@awT jJ:*l&N!c6yylm:6J<PJ>*+I=*YhDTFtZIc*nyk&WHnI+GHMB<#lq*kE<PPR/MK#>GF=8qul^XHia<F>
c@6MdP MH<LcI#KcQ+$c+N?R54bM9K%^TP=>%ceEJYj&Pm&RTq+LlN#G+^l!CI5CWb#F:@:FH>SNIcV&TmI!5$/
>qmVcM d:*6!@&Kp%AmJ@+b?naPY^L=J%FZk+BSwh%hw6VinAHn&8=9p^duq<?8jTm=?\:Gu<AbAtqwlK\ucq@1
h&Z</: >>Lw+d/\Z4ZklyRaV^l9Kp/NbcT9BpYt1SdMSRY6q@j*S>%XKR+mn6T1hp?9Sck<1qKt8==8IRZy!6Pb
ZkP?GF 1nVyGM^j>=1!X@XNXHj$Kq45!Q9%H*e5#+q?RY%baTMSSwlZIw@^DkMKB/b>q^qj!V9+QLbw&9\K@PJm
FGn8am jLLHbiSXe:Z#y4FuFpLDP?XEVQV%RQTdYmi568J6QA=/VN#aJ9<Jm&+#$#wp@q!ui&LhcYdZcTt%mtyG
y%<:MH hSt*SD?\Tu@hijj6Ca:BPMmy9@9%4u?9<?it+&QnRy#HjcKBFtQ%VlZAw6QZdERB!nkl%t6nX4Z++Z+C
Stldu& Cn?%/!^P#StZ:Lj\h*@G+N<6B=YNw?+RqP94a?#i!h>AeN+VIyeJpSNjhweAPCX8@CtjB^QB6m/9Yb1W
Zy>yZi I9ZB!Jq6WqPCmZuRaRh&Y#a8cFjqQPStMAYGL^@L6A5D9C=*dEnj9e/RdqAMZSm^GRG#i5F8$:$M=kk$
PTQXqm P<S\RJ85eh9G>L&DeRkWyFhaSKElYI?kR@ZC&:e1=NQmYyVANP%uQ/*\cEA&5qwXWlR>&=1qN^l%icXy
JV=qEa QRwWKqjAB:K?lk%ba%K*&GeVw?k*lmiGDA>bp/FRBa1MpA5jye%D9R5%&tCPM>6i88+DYqaZFVt*=R6N
eHl6#a !Qwi4i6LT4P=FHZRw@GY!/BYwN4%Dc<uMXew^dAB$Qp%PIH@Y=kBVy$W^WV?>5VtY/iGC\Hq\:PB6$+t
YBetXe =uFe&F$QRRK#*jF9b<NFMlN6C/F&LmD>6\=pG:6Ic^ti:&e=FmVN>/$peQL%ibpbMW\*J^EPBcVEVL9q
CT4ZdJ XASL*eNAbtZ5>>PA<!kc:jE/@$l@ukqqtQ\wVq*h%qR4&*uuB8/Wh5*Ml\VJajPp4jGX6+ND%>LhEmZu
@H\>I4 W?ELZ$qEX<6nnJ!=kMX?SISMK<RhFwSYAtGV?BCQLwK<BW:a!iuAwkJ&jq&hNYw#%G$@FVpThMKSt4<?
WZ$X!S E\F:bwGcX1bJLS9wBCFuTK@TPeA\Rb#ZuAaCM\8ywdBER48WwcukIYPbHqiKaa?AE\=\Ve+i+RM<<E$Q
qVLI*H 5GNK&yW:1QqPWjGhn#*PM$KBE$Q9c$/QWaajaMM+^a>^ZPQ$uXqPpmIy:J5AbGAZ%ZaBqi9%HWZL@bW=
B>*tLk C<pQ!cylV9u9c>+\A/RJidZ:APJ>pc@jPq:jcCR#BZN!>VqIFut\!&$?akK^MC8KPQmL4#8AeBEQ>?dE
c!ADlA kkLEi9P=Cw5!*C$iVbM/V+IT=I1p%F:#a$iFeHdD?p$k=dZ+F8KDi\DMQ1A#!bqP1Xe/aAyT<C=1&@XB
JL^F$! Aa>e+:w<dy<GKwLbk5ck\EYBJS$JcRieJcqXIcTpD&YbPiZ\YZR5^PS/cWqCSnVt+KuqVah%h@XLE<CY
Nq4/+p HEH>EYm=n$YHPDwPnTSw?PD&wn^FAA##XTqKkXdJWu:WW1q:RC*8dlWBAMPV4VS*H*nIwuKwky?$W5N1
S9KFKH 4HL<ltIPPcHbk:*1XFFuq4jGI:kW%!wV%a@n<MZ@X5ni\D<CWVuc+TCBc&A:H@YBnY^4LC6+Z6y^FA%Z
G/BEZS yIAQ!CMI>A>XC+d4qR9bNaw=*q*Nc#TnCwk+mnmH&cc^5ZaQXRH:$pj4E/E45db%!\h%YR:cG%\eG+\D
=AXCcG ?V\LkV5^q8WZ>QZmpIML4R5JHdaNtamFDcF:cyR\jYb&ihttq&G5tthDq^VY*MQl&JIdE\=YlW?WjILm
LRh%8/ 1e$LehbRZ<C?l&bIDZ>Jm>a8Tq%KQTXTZ9k:b9=AJL<u#&PTSHQiyBtNn%\DWE:yWJ\YZZ&utFi8RbD=
tmN#?i qF+>L^5tAiktAipq=c\^bF1WD6ta!DLieB<upQFP9c$/%h$nn!/q?d:$*VQDpJ#L@kYj$B1XI<N1y5%&
ww!<Yw k95KD6GtWX=jqKMk:1@D4b$mc^>LECZCK^LA*YNqHK4NeknN@H/JEC6bymPiwVhTlB$VI/?BPCYK?%+H
SYPD9F <pB^&Xd4#ZYj/dnhdZ%kjwT6?1!D&5yNMme$Jc#Ya8!1np\dGdEmt\I4X/AeM8EuCYlpu:TKMu5nBBHT
ZD@=pd aAJZb\wXT<FKpKtMW9h*uIX5RTiKAeBGy*B*u1E!A^bC8?hqdM::L@lDmXI=WqaI+jHY@phDBV:alXB*
<LT\L> ^ZqNaTQY8^FDP9^DPl+jN>9H5p*DR%I=hE#e*kZ9q&q<kWbVDn\XYJyGIE%dWMwL<6DIFh:IktpHTw9W
?wwpZM T/Y=<eij9N:9SFwYGTpi$6J+bNPG/%DMdc:\Hc8a9R9Y%k/kRtA<\yWYFB+H:L8BY+bcG=W&X^?kY*1a
$CT#5@ e1+dH:5KRF\hEATLGp=:XMqD:+%GN=iWt1cHJTNQa8Ll=#QVlpGZ6:$F+lbMNF!tIq+#R!k=B+L&Z+S!
<1ZNL5 Pn4NwEN$%QnKW6Lam\WI?IKH9Yam+YY:!C+Il^5BRTDRZtCaVYnhqyYXG^K:EN\T<6/hwh=mDPL#^NiT
%@K%yc Y>lFV4m@b#X+Epka>LSll/+ap:i4:&AlqMBlVuHdTchWlA%*=tjQ+e!a9EiEKLl614#qMA!jA5Zb1iIN
n#:Y$8 P9EcDAJI/&&9^aTIcuDjcFiJ!/V>lINT\u^?JkGc&XpG#tKLAEDe^>!*%IG\dJ$lYQ=XYSEY*AQTy/KN
Ll$<T% 5XmH&1<:MCKjqJnH*a=*59ZFkw+9LayJT%ehR9Rd9JK5FL$1Fnce=M*B@A=DelGj&9YkRcCHRtHA6w\1
epe=b* +Ep!KK%m<nuW$k/Ak+#=9P8%98Cu@bP9u>Yy6KuPnG%mWQiLLbARiP!%q>Y!ZqJyZ?k5q$4Ze6mcXwH8
qE?hR# dkNTdW+5S@AG6AHFhID4:%q*Tl4H6Z\dkn#LmC1+c!L6=#/4<FS\5:>5mW9LnQIh6RFA@I^He^JGX5Y+
u*hw\! Lt&=%ni&yS9eW%w1I<B1jntY8E/$q@FFa%dHJ!@&9n6#N%%%*C6Tp4P%a/\uHTtu8&i#e4hP@&GSZIJu
#>Bkd? LE9W5w*#!tQBinEuQ^MkuR*&5<>Xk4/XQ6*/QyDH1:WRe%wZd=DF%iLHdXmhFT@G/Bkyqlid<bp*1+Ck
^Q#XPe G/9!LY?D^M&N#<qKq&D!G6#nR*ab+JBS8m1^E4WE$C<%Pj#<>dS1lT4T659J1#iB@+&!:$+8QyARiqC/
&Bkee9 e?\:J$!K#=ei*i$kL98$d:F1BCnGdTpq9<A9d<+#c99!CLSyGh1WShE=plh&l4uBB=VN+m95MVXQIl*a
*#:jeX m?a!C*$dhcha*>TY6dwmVcPQ45ceiZIIq<&LnE!dGTA:6+#!B%XdiC&%TA^CFcHjt@*:E%!@K8KVaYZT
4<<5IY /D8FQ4>dIHt<\N%y69yKV>1Z$5*/bL\LJd*Y\#K&q?k95Yd8EaB!DX5pWH>hAZP>8ptW?>wy<cuLpq8i
=&5Qh$ 86h!L>HmuBTD&l^paKl!XiqGLTeuLmA#P4=KyQW/AN9Ql@lG5h8c9Eu%l5b6!&J!VDG+l*auMkV&$5MX
HPAcaB /?=mThw%b$\SQQc9mE\Kd\$EaHy*:k$P?JXd&wF#DIPHib1SE=B*&RPG!YG$i9Xqm$MWZPa=m9EV\Nl6
$<i??C I^jdHkF$#qBJh!/D!1nmb\%Ck+!IZ5HP=1F*$YCDQNmZ+#j9HmIdQ::i@N#4Nb\Z6AShiKZHyyFmyR<k
HmllKN ?Kbl6\9X9q8N@1!N%p:6@KqS\ZJab\a=&H8>?lEI$4ebI6TQ@KdW^X&B^F1Y/PpZ<<%P&KmnW?j$AFKX
hEddL1 k!HFD/LP>:XKPVBh5nw:+l4m1^NQ6dH=&<>4e:+=GP6cLE!\i5@:itq@Nphty%1=&@F$l+@J*B@9G%Qe
N!pD!W an^RaDVj^dhkLhJ*\FE=<LC!eZC/jV=eKmYyX!BhY$wkXqLFj<lQVD$6P@\?d5+56*h6%\4!@nX/TqJL
<cn9>h eeGwFl8R^GHS@Y::#phqhIuDubZl>w+1!Vy$8d#!?!4kud4HyS@i<*WPF>&%L<HJ*4:QQHB@W6AYTNB?
F=!MXl t@PN\BS@cQ:H&cGCiYPnkjEEdRZ>tak<EqFWK8NHaQ/+WGq^5RJ<ajdlBn&hN1G<VDbn$ZyQSF1HNw*j
N@IDeT Wt/Lu?=^kkay8I*jkpb*E#<lWWVN+$TABL$TQwSb$JXVQ>T>jJD@?6Cm%??$YT:C//dkqjR&T8\5Z/LE
\:T!&# B:6BPJdSF$$Z48k8EJYZk8a8b>>a!!TlDK4R4+SWjl*MWiw6QV<P?<bb>+T!mcMInnNYF8Yh>+WwVJY?
qjIRKH %GYa:QZ:m+6diWy$X:TF^b4lGZ9CF:T4h?TGBH6?J@%ElQ>Lyb<I+n<y@WTF@qu/mR4?5jV:?^#+u!dM
w?/IM8 j#HX@*55/H<Rd:?4S^ES@RQ/6%EYEdE@wH<9wEV=@?VTBZ<#tBeX?JNLS@^GlwnC@?NkZkV^9^:M@!P>
=Ppy/$ <6<G<&Jmj#GaF^Z<=<E<kq>a/Q>GYj=*SFtEGKpKyj+@mdLR$HV#$NQFNw^%a@ndVJMNJRSj>q1CY11X
@p\=Pn abKl@J%wMyC/$PFmcN$4V#Ekunq&C+BH5C/KtLt!++>^u<JMCJHlByQ&<uw+WW*$1qBSRFQ/^XC1pCPp
>1AkmV iKnAE#*yWD^T:CK+KiaHWqlG&Jy$WT4qlA!6Ma=euJGBWEKuaWyGD>Zt>6ZqMb:h/8K/=kV>=t*nGhac
-AaV:K 00046251c4200110333 Page 408 of binaries1.zip
1?DP8k #d$E8&K>9F4Ny11>^V%#iqVAXm$kNVBa6HtiA#5Fbm+M&^Mu&R!wuLw@X5FFpI^%GwJnPG\SWn^DE*QN
YQu&&+ Y8Ty6m*8u/qwttX<Q6DPKM5!m:\nE\!cY:XJ&BeJwW\=mX$/<d1n4>aYyp>1PCMwSkVTiGbPHWJJ\dFq
&&jL5S hWG\phd!%6=RbH9YZ%BCG%NwulJK956JY8^45<W?H\9TMdWM#LN*EbdCYhli>XuL4hp!:+N9YduL^m#c
jd/NSQ 6VwEmh6hj%Mm*jdq$JBAjcHTj!?<<9QFp^EVVBtqmZIXEBei&HqdSFMFPQ:TeX4GXpkG5iSCFYQw1FCL
W&eup? IH>6@^B^*%*mEaGV1l*ntmt!qGQQqXlMRkSV9FLwhFEy9wkYRnuF85<?i:*$Sj#8yKuIX5cw#6\DNc?q
XFDp\\ F6?!*k?#Mb?@V*#6eJd\Fu=QBX>SFH%89G#Dm#M1P@QRPulwL:j#ep$Z+9=E\9RbwNn@*Ij!X&<*8Ibe
#4V:1b yP<W\iccc1+w9B?\uE*86^Je!CRaY?=Z6Vh^wJqeblXZjqy1=ictwuHHG#T6YACRh\&&j&V4ECmSVYW&
bl#k=w iy@iZT%C@S*@Vk8>nF&X/6Th4G:6@YHKJP4k\$S4SGwLAbZ+ctl*@6yL&b=a!M\1XBFB^>IMI4mh%S6l
epkq9\ h$BeYbRK!TLmC=5YdyNGR$Qu5BV&6YMln#T8A*Zy4=H=R#h9&5V#e+LN>a/d^Dq<4A/!>ahNL+dnCn=:
t4pte5 NDAjQlIcu&b5!dAL%19pl^+uLHBR&DE5:#Ncu?@QBRYeD1\PeikwLLe$>cFP%JtCEpi/EuII1yqpGDJD
1uYewa HTeWi96mQnC^GP5+\l<K8:HM4$5?Mqabn^%t$%@X=%bPt>EG>uu\WYndZejWpAqt#M!>JcYNAR$<?FFY
FDW1nR BC6LiBZ9G+X&G5@H*LHccNCR9SHkIXC&$&m$FduMWqHAIE6ZjHMRkmaWuDwGp4u88X:enubCq%cFiKTY
eFC>Ea +JJQZ&u*t&lVn@Zqbye6aCbtH#EF%KyJH+tuce*PPW\He4k\e%&Cp1/q^RAkGAcbM5He^8W1JHK&#cG#
=NyX=L iA!AcJK>QMjMDYWb&yG?Mk!cY\9u9lS*5Db9pw/QbJ\pGIVuWI\yu:$Q!4i?!5=pkCITiQjaw>nXPdkm
J/$^S> #EpEJ5J6HEtNGmJCMGu5QML$yI#>yp@Hk^I4ECc@NQ#9mI+@w^LGD+eE$#nZ*EbL5Gm@kqy>d#ci9ytZ
ebF%ZK >4ct9NNM=&QZ=dSApJ?@$WRujD81yTwmt=!#&nJw=qTtE$S6yIpuW^9qXmS4VRyt<<PFY=en<k96HKaK
:A1>I? 9K\@D*R*5jpeY*kawiY:+k51*L:&?uWWVPd%!QVG9EyB^/P^h%j\ES:k/ce9VC<wt\&I4KbWQIi<mj^u
$A^E8C *?u&#G=ByqD<\DWnYZ5K@juIqtJH*b#MS5@p=u&4X9>=^XbZJ^:PJtk5aQbD=PG*uKjD*Y\hM8^QdAyX
*hJnwu lL@/KTbhK>G\B^^u1?pTMX$mn1tD\BeXQc$nM/I$a=t#FudI/YaS=F#MHby*>?MmkdFnIVJePyJ81jWL
%9G#dj lwPbN4&W#D1^b&lNIW?FP/:u=5=VXlwT&1aCGl*Q:IS&YmiPklPL*\*Id<V\%+j\Scp!:R59uX^89c4:
InH/am qQXMWB+iNnIIjMZ6Jm98RnJV#Ik^6SekFY^P:MDIlS1jCddZB@C%CdX>umhc4m\R&YCB!Zbd=nd\Y:iR
#nL%hl 9<BjV9MAy?5@BP@Rw=6M>G$kDX/R\J$M8YDSF669>?%VhbVK=H!LNcL+Yt^1qhi6$8nel%>CJkcXnZi#
X$>L!S K?^6<!b%eeiG#\&pW>bTIaFFI4dCAT5%qL#!e@B<8aD*DTwEFnMqX%5P+$dl:8cjiVMmpY&9nM!+A=\l
hC&N/l ?aE#XTKah??NZ\=>6mdHcyGT8Za#Q9>T$j9RK:eMEtFcA=DuQ$Mw6IFQPlM4?FieRZt*:/l\i1eMb!$i
haJ<eY ?*TcutTGLZ68>IpQpqT!89nj$Nb$Yp9we9j&G1=85p5MQ&LqtGIMW*tXJPY%b:uF1tCmG!4M/Nlyyj88
4#>>BG LqtRKG+:&c/V%w$/thihX<JBtFCeHVq<haJm/E>\8=P8KnwSlYC/M>uHVBe^\4PcL:n$m+Bckl/am^e5
==VG%K cE#c\Kqah:kjTn>$aIJKe^9ai#ti^HNaMJld%Gub%X#V?G/IAI/1W$&+uV=wT=Da<IMlebuERjt%jR=m
^1#I!! 9qyR9FZ^^DF8*NNPWHnEl8c+$HBG@htV<AT%jJ6Q4VJF<naL5i*NQyCRbL#1^ti1S\aPnE9:FXLKk6NX
cq>!w& hDTj<RVNXXSMd6=#$CXLBX1iYSah^wji>:NeWQe^BEIZh$!%u:Dh$^bP8@Mp4=Y%>X&GD?Q^H9%JKTB+
QL@k=8 BjNciIBMkqbPhm6YC6@iNpaqKy!6b6KFJ%ba!wXm&#dwi=XZVhn8I5/A*jFWTH!hG<VqcI@JGlS%e1!Q
PVRXF< :R*+CVZ:k4+G5h:\^n?Dt/G!<EuF%CJe6&GCEW*%l^Fi/Hhbi?Lk@Tk$pM9JM8AH1@/dI\=\@94L@1!*
1QlWq@ 66JSSj+ACNEM?NT$XN^lKEcaAAJ!nQG\#NM8P<j5@i$uHY1=&ETp!J$RleK!6wJ+qi*LCm:4ayLSj6yl
Vtk$Sl RS%%bXeYN/e!b6QIjtLAB!J?G?j%TdCXQd/>*R\\##+E=mFukL@N/KbMSen9eqFnpeZ#VwW#1!@c<FY5
+eyJ^e 9PqP6>y+WVX4&YGlqiq?n</kk@TS%a8StTmYtH%<M>QnG:%mWuEbbRPVBET<w1mMap5E:m#PVN+\k=Y#
IIYMiN bFiyj1lF!n=PmlnjpJ/Mh5eRjGEmkDDK!WQPldA8qj!waYGc4u5kL>SqpnwmC4&hRa\9H5C#R^85CXG=
e4n<PT R\8RJp^5k<AG/SMLFB\YLwc#h1ei+MXH6FnAAqmMdZu@>y@nLwVaJPPaDMWd+d>N+%upbd46=bq9Tw%W
pXcL%n J%FXJ1l@YK>pw!+VM=8+DC&W8k5pk:C%Ce6ckSVd6AEb<?ccI4L*:6ej/mycM#uh>b1K/wkpJCmb/b:P
16YCTZ <&!kKHKMm=SJ<tYj!YNYSnD4+dPTaw5lnMkqTNIn<4CP!awqAE+TEZRt5d8WWZ&W%AG=/tS@G\@?Vc&5
ji&l9+ pWh#H#$^Fk?c8*&5DR$+qK&VLhjHpFa+1^?d<&Yq5i*?5D?5n8tVu%\LCWATYjpyEMn*V+Klj@64k8Vc
uqBj\G 1%mwyJ@WytVFiPJ+GNT*^y4#/5KddA^nA=\AkL&/c<E>6j6:M^>uT!^9ka!@w:$k=Z/:*MyI5u#NyD+W
k=\Mh8 Z<1NCiaHD8dE^HAjy?VDAYp<+:b<PdqRdTcl/5I=wTY6kQm\C>%??Z%eNulju@HRdb+lqe$\hk&Bn?5&
G/m\mc JRlwjK%AAmY@VihQuLXjBPjjCi<I>E@mDPl@JchJuFlZ^>q%#B<aJp94*b@G1>T<D9bA5It4heiE^FEI
X#Ry&W EdAI*R:FA##d^!q?/J^PpJ?u%^$GLJbh:#XCSkLcBW?F!H>/IhMcleDHq4te@QHE9XbCRA<>kK1Byc:#
cVMuHH =T49:cL4Qltyp4qAm<e!VdB/#Iq$A&mj@EltRuHK!i>+%@=Sm9=XwecD99N>uJXcPT:X4ie!R9=GJZjp
!>B!PQ eC!!YT=p!plE*TjGC#pEV6wBHNVMNqD:GqLXmSpluBI4pD\BK5>$\M/S6WPGNWJp!^aYqthPyQ@YyFTS
nNhVZP bW$+?WKyQ\VB@\\pK^=?YDJI5Y:1HDeInHQjT4ItH:C5M^amQH/J1aS&:?1wiMXA@BAyW$aki*YFqewR
HI#6wG a!^ZBQ11=MwqJDCqZ/*1MZc\TnyYC&Sq>9&1Z+MXG1>=I$Te$\ldd&4KWCHLJR&?I<TnZFelmyX>Ld$n
nnp>LG =AQ5Emm$<ZcwWRQY/ZEh1yiI&^ejY5ESL%%Thc!bal!w\Q$P5p*9&jGMhE5aSQ8Z\NYjePXF5jMX1c+C
MeMtNM imF4S9F9:%9yG\&FcHw8M>yPHe:>$wjLGja4^%>/&JijANEJWKAKahR+<IBDq*ZJ>hNK\!AYtn>mkT=Y
8Jnc&! eGbcney4Hq@SnF4H^l+yX$JER@lE?^Q<h=y$&QV4Cd^1CMm&6#<Gn\<$Sk$BKL!TmI4%4jTdtP*YHbmE
pFa^<^ FX6WnuC&<eWBwBLQGl&DdTpBe:MQLu:D&#<5Xhq?iM+@LlWjmF*YnbBjP*aLmhwl%bkTcJ\44$N?XPCJ
m:mQ4@ J#&AwyMRLFac<JTZah!EtBEhScS:!\ACM?w\uZpQZ\JaVEQIyY=5ncqp$@V:%Q*YbVMpwTpQbA?bGyu^
#>J?8i DA1J?Gqa#A6IQZI%X#dkbNZbaRY!4E*LBBJ1#:Pec:GN#HVM4><\&^C==FVXhc4LtJH\mcwuwLDuX9:8
Y=b<Kq pyuS15$5<@K%Edc5LG&XSeKL:4Rl^/@WbN6be*1eH>E1M:+bQnERpYDneKcEdBDW*NdWWMZa5IA<61eY
yQJDW? u=JQu%EBn5EP>PRmFG@h>q8HD><&J%JC6?/8T%p894%:nMDa*:\JSnc=8\Vb*#DyPP4c&:!6+ny1Pk*!
#KVp$H H6IdDhF6dSBcyQVW8H@*?L:ybKDCTLaR:+T>iXJiMW:w^$&%XD$Bm<eaN#tX&Hk6XWW=4ku4K!XqZRFi
<+kc^e MIX>!R+H6/BFYTF&n>qp%%=NteF$P&w>jbFy!Wy+@8/Pm1PG<ANX$J9R\WuF%pLm8Wb@6u9ln1MQw?H9
lwW/KI YW*DG9:&$MXG^FGkD!%X=$%&Y!&%+<Y9I<>jPQD+EKF!I#56KkBFeyM1e#&/@B&YwVSkL4d9B@6b+#\G
e/ILMj qnYY4ab9:b/\yF&=>^t@KP:L+eWSHbcPP\!Qu=HN#blTJS%$&EGR\HdpS/\VVNTS1Fn>hHF@p*/hHWSi
L+Ba/* qKe^mS5Hn5YZiQ@hqwb4ppluHq+K>C5STKDXINdW16iV6W%$!$qRuw@kGq+6wy#>ihZWyiy$K6W%4h8*
dnTHIS &Aca9\C8^nqmNu^T68/IiW?P/HXmNHD/<yJV5EChtlDp/^ci#p+$6R!c!uD!%mHG9M<SbZddaZZuIWWS
S>AJDH j9Phiy>icud=>auu54S$kPHn+q>+D8?n#hp!>::EjRal?I$LB%ubaZ:^F@\9cAhyYSHFIhJQtq::^jh6
+TPmDA !MR15Z9HYpt@S?jGFy&KLt$X:mVu8/RZVkTAXWRJlh4$eLKC#m%<cL/<VNNnXNk*^+6F!tnl+Vkb4y5a
$juK4P DWw44CQSVX<T49jmTj*$lk>mcykVhpmwh$RCFhP%4WqBwV?jY/^@/H61ydNnheRW+dkdYVMRaR>tR61B
p4!EdD ?8DTX\DyI=!&/pQuCRW:ubpIp/6Nt:AG#Ya4uSpS48:/$X5%^PB\i>uwV>KtX:9!VC\N1uKGS+JY?$tI
8P+h>R FmiwW=q>1b/NE%hI%KC%nHp%Z=wRhEb%Jnpc@EAdb15hH&+jGYdj$LA*4MZ^BQ#G4Yckpb&9YA%Xbhe@
<Sn+Y8 /?Lp6CdQht#^LScEATZ6/66GTmb\MhTJdGKucEWBN<q&9hkP1=N?4+F!HhY?tDlXN/kCZw9P#Jn68=@j
ubbC68 QTAq6ZCHBPQbnQP1y$<bi%K?c%WRVJYu&1!&6NWSPBk9cCpQp>6TiZXE^CFkK>5S/Vm9iN\4!4da\?6P
LKDmMw hTT4@R#Gl@*pFTLu@TNd6:i!Sj^+^$K!tXq58HVqj*S#cL#^=dK58h$am5<y\NMYq+n@/6!HRcau?$FZ
FMw+$q Yu&FDA%j<yL/%!iR^RiPybPpeK=/BS>@d^*IXLCVCMh55Tp$^>%%TlGSeD:Vc#RpItqS?d1$u>WJb>F6
qiAt!V ^#R*+XYI>Z%T5h$EHiSdp!P*#JaP!Vm5Z1V+*8Aw@?8Z\F\V$tHNlPyM^p8*pMDSHXJ\!bmn>kbwGm>R
Sm8GRE Tc*JAme4/8ZhZT9n>BVDae?y?p\MeZY/uZKQW>^eYaE%hb/n/k#/c%&JiTC=&GN5k>*MmQW$MX9yGQ^6
-A>lZh 000ad9edf7b00110333 Page 409 of binaries1.zip
McQBqp :#N4uTh!nN8h5W^wiSG?C%@!L!$%$Z*RH^c/81+#Dn!JjRH18iy#!@dpCY4Ea!cLBmBlI%F*T&Q#9w5q
:BY1GE I&1$Ti&$W6=4?@9G@wdNDKbh6bEFYCpChZ/=yj$ZZ:t#B8=qE#^QHy?d&L?q4CnwGS=a8mIZu>bli9Q8
kDn*@4 4Fwt?uwKEb:hc<hd\q/iYCV>48T8J+A9eqI@N:Ju!?6Wn<mm6mN\DYe>Z%@qQh&LMX=ycD9#G59%?=FF
iM1FjE IwZJYS*nm^<N+<i:K9%e#lBHDuq&!n&:V=b^PuG+?=MCNBA8+ZDV6C%WL^:!5@!8ltQa!1V&J##yn@8S
uCiTY6 h%X\Qjt&!GyXG*pj5aVNZTEutcyV$H8/HZ6&pIi?B!1%yZlT9le<BP%%In>=P1yq>99m$$=eM*tqy$m5
in&jlW mX=4J?X@Tn9ByAk#:#Lly*$dt<6*LTNBGqEKB+HtL1MMw9pCZBccZA&WQhu996/=b#A+$nQw+qV/lu!u
uMh<Ie >FT#4=GAB%^BCm+@eWWl*hFq@4JhtZIV=uX=\l@8?qYYTi>6yk=M$^AH1bial@YV1m6G?H=Rh4jmkFpL
>@&J<# Z1lek>h:*PW?jL^u^PK&Z@1epLN?J6dV\d45CIjH>Sb*!<@LMd5D?VkdD+Q6IL8#Z%VXY>>tST&4:Qan
P*&ZbG u@D^nV/F*TV#j9@G>6lRIq>+YD<N:H$4#C@PMH+=4KM#FjyT1&/@hl$clGNDETN4F5^S=MSBTwR89J?j
StK*8? *<NJC\Zm!^VJ5uEIbK&d*$b&5MBDmbTKyVFCFJ1WmmDenaB8N$a8tl*ebb68c\G8P#9AimuRddw\5C#F
WP!XbN @SnJD&B/I1mt/EWTQqywT1WuT!<H/XFM^Mt$a5lnIS^BAAYSB/bq!+W!eBbM^@mM8Aj&k=5NZHc=*aPJ
tmN^h5 dJ1JYDn/jEuJVaM=Q1tTtRj&489+lCl8?FQRe#DlhpH:<e8%8Kd5HX@LtWbwX$+XMHlq1qLeXcX<GaN>
QXd+y/ yeRRG=wkRS4R1%Y<*9n%#8&YeQVTtph:XT:kI&h+#*cD4*IXyRlN4JWGWuQFKC^V:bdGXyk*J!DmDqyA
Yk\lpI Jqi6#!#@&1VP:&9Im9NHNFelLcXhFKNIbpQ4wV=VWMEG#t:%@bH%:bn:#PJl+jpdYbKlL<6<imRa:d6:
EK4E8@ 4ll4#i<Ghep4I:/\8CSh+uH!Di$HQl^hih*Va=NEhwNKhCPK4SA\\NI?E4DBTBTwp4N<dV5n!/e1CASI
L>$et! 9=LE!K8V!K9bT^B$n+?AE5Wm+blW%pm*6ePTtkTup>J1B9?wGB/MYZFlwwWedqtXnXqIITpS#e:kT:9#
kkwZpl tyhdqS!h<wpabFP=nVlK>G&k#FB+lZ$@d4Amj$bj$cCRSEyWK%+Geq&?Ki689+a<Sc!EGutlllCRZBQN
u?*pp6 ChNM9ePtH5#S1#E6lWwGK8ISIL@n*:jy%%Nyq4/uMiXwIJ/kTpmj#TNP&GdCwFV#1wlPGdcQ+SIGj$PX
IqFL*n q#6>i:e%yWmDwawI+8cuIQKppZIIJW:RD\pl18m4GTC\ZPpI=caWu=KM?ATji1DINSZa%Zny%D$j$SQ%
/AbjX@ C16MNnJ#u?NB8*e6RuklyIkKTeEWFTtN?=e&TqVw9>SGmR4@=&!WCL@AQ>pwEZ:?Q:bSj=ej@/SX@mKl
NYeB\C <9jhhH<RRSMX?RQ/6^E$WhE@waX@S+9>AT*$P^Mt^9<H6KDad>=dVPBQ/N?6w^PD@\H>&<IdMeE@wRX?
5E1KD= h?XCj$D@*kCKCj@JeSH>VclI:E<Pt@B9/V<=dEK@5+>mj*LaBAX?S+9>S@5wK9!@6w@@TAL>t*$WESD/
iT9dWm b@9+:\@\Q<YC@9dk@l<VC^L?Q#RYSFD#ylI94::1JawmCRkt=?RPe*ZbwALhpkE*\+My>Kl/d5YIC9Wu
?:<!Yl 4A<M%=HYaaV:E?c/KWkEK%aw/9D!y/qk6^qE^iGtjWbm$M6kGyw^Vw6VW9Dq#I+5<Dc@jpiNXDcnGEaK
ZyFwEy VWCLte9ykRQI?e&yJ4tNTMAn$^c9iLWc8yHeRKG?W#HiiS^%lIwWT4MFNVT9R>yI8t++*HA4SIEc5yWk
+Eyebn JhTde9II5:AB?KZWJ!X9VSW*V$qCX/HKZEQLu#lW^5S>PNQGliSuIHbHHkp6p%X9IMeySi6P6MDaaAml
nCa+j6 @=4uqb+Mhw#FEQ+ltcAQZ1>bTEpLE*ZwIXYJ%6y9A%B@&*lWR!PDH:pqJT6&G^MaC!bX%iM6=?<l*d+j
T^FG!= 4ia4HNcC<tc#j9CBP@tFay%>DW6d#bGtQ1t/PBZc:<QTZTeB!#dKT=F=GYN%dV6mK%^S@Y9?pXj#T1j<
I!iY59 @EeJC?w86/V#6V^c9T$KTnt@^QV4:!WN*IQK8J\/6KKd9nPK^F+:mJZ*CRyDNQjhQ^pPPF>=9B98d/9t
MPLTKy =B9*TE$*GZ$%liumC<Vbw:R&=>iR5ZmJQM8ciwjBWMEhTuFchCVi/XG:#QV@mJu<PHA$:6Tb4>=?Rh>p
GFb#c& MAa!euLiRK5:Q=nT8$Q%h5C:!*BQ<BT?9!b^dWCQCHFaqDhJPMGRNhB?#@cKwtqI@u+jATN@Fu8JZkq=
&1EEB& hRYp/>un*%P!C9=wVj<4?bQt=!H>8q5KCbw9W$n^6e@j$@kIBCmuR9uCj6K1C!R<n&m8ab*/!ED>dWAN
1JBR?e GeD$CGiM>pYAJjAq+>6T5#pm$pCZWA:@6\XV9RAyJB>BwDJuEM:/HZ&#V<>IXclBhTN*qa/?Yb8G*Z&+
Rut=y? 8RWmX94tEG@JTkYaT&G!%WePc>+9/Dpp%d*tIHIBWABq&DKp#DqR>%q:R?V!d=9%EZqeSLV\LGKnC<:l
m6bI1M /tY<SkY>nPq#eF5+eFkGh&GD>5W?&qdh/bak>4DGKDDb*Epl8eV5/G:1S&e?=\e*8IR5qyVd*8+uh\w=
*AE:4% W#1t5EhqIAZQA6uQZEccN>Fc!CC8Py5/@YS\THV>W&y=m<?HKS4%1tP=ahXw<F=$BVMeSK8wkLQ@KdFJ
R5^lRH ?XHj<tuNbp511a#we?C\j>l\&ViLqX@Qd^Z:Q\y+X#>c^ym/H=w$G11d9nn54S?>@ZweQtN+G&/cLc5?
L9A:%V y$w6TY#pbmFVqj8Vt4DDp4RmLBhuuL>AhF=!j5Z1BhE^AySFiqi^QNky8i8Z9Ii8Jj6*TYZBFn<S@B!K
a9BGim 5p=>thtadyqDVqI\jRW+^YI:ZeV\J\eKWSC@BywlQWGq4yLE!R4+%&hJN!<9&V1VddK&?BS<*k^T#RJt
4XiEZI CIK$p&yqK4@AA%QNS?4!<q+G<%py:GKXMyKt6>+=AG?^CXJ99&I5/QmWNHHuYnZM/#9hc4lb>AJi\V=E
4uMi/Y =$QqK*+ZRnTIm#GG>B^VldE5SdH4GaQyJiEkLyjcQkQl&+/iES\SktH/S&1y^%D$ZKB^j?6QI6auwC4M
HyI5Fw 6^VePhFDX4%M9=P$R8XN^BhFAp*HPW+6QRKYmFF5tLK6!i6Gi+hG+m\dZm//ZG/#8bK*RBG?Mc?8hH8@
WW:t\Q LTh/Xc5S@Yn1*dDZ6E%jWt&+unLV!qbc#$=AD9XA$6EFij1CYY&<ue&5!>N$6j=j4h+PQ%<>!8w>&1\1
mdMV9h w6bQ9D>5DN=lddQT\ZbSH@VT5kb\XNX8TyuaT*qwT%lIq8*uIw9<u5uVCQj5y4#Q#dhRW>H:EquKu<?\
JLGe^? qc?qtuVK8R>wBJD&ZXnSePayQ8A8tAXpPJAFiN9E6MH%mjYV@Z@GVVWCm1@uC1MDuad=D!?&+SZ$8@eV
@Ja/j5 BpiPScl=$pPC+GKT&\iM#J8l/Xk!FLQJku4R84Z>nKJTQ+u6KY\8=&t&b+ABFcGTSt6WPFec/uuXjB1N
jH4*Q: /Me88/&V$Ba1K6dw6ZD4?RR4D4jlbd5*c6ZCJnD?Few\/w%e%/\8<M9%6?&cK#P>*HpwlL*pj4+WkGqd
FbuCE# M1l<p<Z&Dl<%Sc!SXu\QTN!uEYhny+$*>aPK=Iq6/S4\eaPjhNb!:n&:ElXblaW*IqTAeP\b9AJqYV<1
=b@6Nb +dJQj&TA<Cq:PmT^=<i\Xqt9XQQB1TVNyyaSX>iDh%FXw#&P^qk<#=h**6wyhu6mwVF<^dIbP>^!iG1j
6!^pJi n1N$K?bXw#ZBndc8l%Q%NRXi\?:dh>ulTSlMW>wETc6Z^cl*RHCae>*?\Y**8EJu64VmkA<Cu&YYq8X9
\btQ<! 6^Rd5*Wu&nm8hqINXuY>:e1ltqch5qN+&*e&tKj/jbYn%jGTNZ$e<d%udhZ^9XkN56Y*qRXT+>c@FCJK
kHP9jV :*BQQ9TWRi!q68NReZ5C>Cqj!Yn8Md%SS>TS+/l=AdX9X^/bS%jq5@t?Mc%S1\n*%e:AV$:CcRRT?pdi
JH*nTa TXH8VHi:y8<<Kct^Q^X*jN</e+iE$cSEjhVJ+1LW5@WB%HT&!IYqw?n^$W8941>?BwPQYV9R?%Q9YLhQ
EbB::W *pn%<@^mZK&&Wtc9Md:MI@eEY>F$ZMWi*^EXlRF8Ci?DjwpMm/qWQXG16c4=pV@9IjMn/Dk$1&CBtN?<
PhVii@ WEWNeThV>IStymq$VQtSXFY/y4IlDaF45lXhijM8TctR5Q=TBY%AA^$#8&81H@bFjS+%AbqX@ATRJN?E
:HI5HN q/G$?LRk+AmH:humBJM=TN4ClkAK!y1bwq8Vhj5JpT\6$dRh+H<i5d8mqu?1/JWJ%j#1?QLY#tFAKCZi
d\P8jX $KFM?Lb=TR<RGGhA%EeRq9Ta&/Y!TAaaHwWbIN5k&Q$FqdXTi&jCiy=HNKe8h:ydLK6/>lWa6ENkyadu
d/yReu QAw5MdM+N!jmIhJT?*yL>ht*e+CcY55&Q%ihHTe8lEQQ8TK8^BTHH#F4l%&V6jAp6juKtSI=u8Fw>kX\
ZP@*H% J86hK/:u=Lc?q@QyyNPyS9LnNGCh<BNJ>Yh9XiP%TVdkdRK8p5MD%NYqM!5Wbu#C185&*9IJQ&Q#qP!e
/6CeEu 6aE*phRQPpm&E:hZNqSCw41%9j?<ut68J?%>?jcSZI:d^CS==NCuYnZwTA#QlQF?nbX9IliVTy>9>akc
RX@mtS lpNLuYtLSZR&m5y6c6>V%i%L1CRA5utA5*cE$@MF519u:PXE+1?tF8CHu*M^tE^G88p&&8jL8?p:+qV1
A8$y/A iP^WE5WQ:ZadDQA4Jn$MPucd6AYHcu4\MDYdBjH%hE8W6lpSFlAM=1>N<qK=Juqby:$i@ESi1:?K5$hT
<K:D4M >5=1PG:qLME8QJMtLy=t\kH1VKAZt59p?p+XPYiA/tq%/9Nqq>/KiuN9tttJ$YK\uQjiSM#pdT=j6uN$
KN>8?R >/qVLe@H/a1$8q>M&>LiK1&5JePMP\PGBc:*k&>A?@qGQjJjD/Wjp#/Fe4%:4Fm!5jpNM#NTG5\lIK81
6tH/KJ 1umD*ndDB4\EYZ<D+CTl?nc%Auy=Fc>?ln&B1p%FJ*XcB!%Dp*aj:+DXh98k?Kh?!l=ayl6+YB5<&kWP
Z^tKHa 9QdWaPaq:ZtlkR9?iB^Z!EkmQSQ9NptQYwIDGPQhlnw+HAYeVH:%$muL=qjapJtV4hKAypt++5=\^\:h
+B#JAa RuaAMuhR?19%hS@HQ^>A\*al:T\NQL#%YC&5K=T4u/d!$d%yAw%+1BZHkny!n^:/tKRY^/?wSyp^VZY>
:#TKm> /biA9yLFcR^5#q8Xqt$<b4j&6a$qJii5@$1<^y*dD/kQw^^NVLtJVbASJXtMA/?IeGBt/%&d/?w>e<Q8
j@l&T/ h/&lj6$K^?*q1y*>hR$kjp9YGk%$\+n$41etHE:B?CFpP$PVw^9*SH4\^tVkLw^E<:^k1TXbZe4PS%iY
4BehEQ !M^/u6&?KJ?ChB4Hw5DD+l&FlK!:+YM+pi\M6He#B^S<\6XH<DXB8RXXRVAX>^n%#SbVaT%Qba6yBwdJ
L#&B5! +jB%kZtL94PtjWhhV&Hc+M+FHWS&n@t8uaERcGSQbj<qBEkywIK9cMu$dDwnL8FbqiKy6hC:SDbL^eM?
4b/*a! <FRD8HRkhKyBY8XlVDDn1#CHKw!QLicb$up\FVcpICFK#/MWl%>iAh$uNqNt8NjWd:WAe9iRcXyR\nuM
-AK^HX 000b99ea7c400110333 Page 410 of binaries1.zip
Fd4@ad qq5d1R/=JFTeBN@wiByBXi%tYDA9NZZnAyCEml^bwRZSdESAky9HnBqh%qHwwwFpFTb?:1^8XI@W?lKJ
jQAYDl IIE=V4c?q1d9=p&EDGPPW+XTiXZq*yuKAiKeM1Ki!<QGZ4TDDCWV%wkYl4WFIAt\&?a+6RbcA#PeK$4F
kyua^T eSd:ud#TS<bewhwcDqF5M%@49mkTFlB4VGm#5dt:4ti#G/8#Pa1YP6PV8B&!lTP6p>t9XA@b9Dte$n^Q
dY$Aet 5<B<9KV^h**nu=Qp4>LmJ>?P@eByadktWH>:/IAchVXec5q^*1<6i@lDjy+iek!hRFdK:Y@!#t*H%t45
1Di!#9 b@BMJ%%Q>*LGinqSIYVmSEkFyqR%iwDpA>mAtk++>$N<GJ?JlijF6XdcK@96Z5tmZ6QQHRD\I/wym+%N
8MZk5Z q/ll$Y^ZQlaYGhMSGTiEyLWZ$tM\%CLN&&Jp&>%^$&*/FKX6+:9AE#w*\1RN#dSLm8^jX/\RLa*R#D49
dm+t?6 <aYRFRSV<PNLtw#AT$KlKJ=6LYY*<%unXn^T!ID^1/PyhH\<ISE^RhcR@DE#9yt^IlFJ5<kShQi$F<nM
9=e%!M W!itTtHiY!RGpq1JZMV!Bp\Wekq/PAI\I@DHKhAT^^<ctM$!T/>CFuXj:=mZRJ>h/kTb+W%94=\hC&IS
i1HNb5 9B>cMLe9elpj9IR<V&hRAl>>BV=9^&=8p+lR&pW$P:CNt69%wwK+aunpiWTbQj#E%$$iM4tMM^4&BX@%
5#eSln deu&c:l!1?V*n*CkbakK+6Sq=eDYVBXHqyhwK\C56Ruh#\MDDMCA%$BKH+FRPmbhM>+TtwLp%*cYIXB:
:Aq?da Zp4Y!^CRV&uNh1#<M>/^8qFyq>EatN\^VEY=*$ptZ:\KNc+Lj:T+9pLe>y!+W/t6\^M%AHJ?jVacL#WR
jYent1 %1%\ZV^b<HHhREbyW&P$D6*I<L\pYA:55$E#KeNY%eE+GK9JMdt8:?KI#$B<naq<=AjRXKwe>6Mnn8N?
*:hM?J Ii96=/T:y#8pFN8P$^$h%cF14u8SI:M$eHlpE#IY:\hpuLJ@uqlMVTB/wh&AjBPcw/4WFF8=tCd+^SR+
$DGjL@ d11JS/Nka!PI\dA&4X%@W\ISZi:e*WAjH9Z%KB*ecMRSKdNm#T!&hXmPl<ZKIiHj*CN\Vp&p1BDJP5We
HBbI^* 9H&>qP:dYwu/QlM@9jn54kdaM*ecE?Q=Ve6@bM1FceD5=c%W*RibqAA#b*M\4e^6E:*Zcqb58q#<GehX
u/Z+ju RJJ%AYkdNBKh$*4q59MI>w*y1p@tcXMip9uG!PwhYFnjX4MW@>\hm4&&IuqbbJY6HI##nVRN^4>k\h><
nEWRFM !/qX8J?nT>aC*PbqS8NhWp!y#q<NJGY\%hiH%nd:18AZ8ZSm5/RZLuiNm\cTLLm$$Mw&EH!M+H6daV+X
Gmyc5\ JKbp#?EZ*!<@%lPRiNydej/!+^XHTD+J6%AF%@c<w$e>y8WF4Gbh9K*C^1R8Np\hPRu/6B+h6ip%SFad
p#mcc* nq5A5c5li%euYDDJe$ctb@hBqY6Ta^5qDHa=E1yj/c:LBm?WdnTMG<Mlbt$RJ9jqIyV+ZPY*JY$hLtV!
/&l+Ma #hiGX6Pk5ccpCa5t5p6!ZNYwWmMmc5FGK@R5q?&wl#NI*HiqwJC+wF&@k&?etPhJ\pVJ^$H5yH^^:*&K
Mk5P/h bAYHbY/i6SYC#8eXkjy&?>NHZGERmpti4:l#m>4bGK%a:YpX?uD:C8j9A4Yne#QmL9XlVmHA\%BH=jKl
TGnXZ8 &Fi&bQQL!cqA!q5^j6N:/$5iQ\NBG@^l:Ilm9edR\=<p>wT+N<wTD&6eE6:A5&6H!j^><PZuyR$D*A#u
k6aTZT MyC9hEkWMl!:X&!FZPKDnyNbG&AyHDpeF#JY^^>Vy99u=JMIGdYEDH<yQB&wY+LX:?=YSwbHBk:h:9CK
+YyZGC yQFmMD!luIDe^LNN8eDNn6Dqh4yM!/EwdCydZE8=CK5VEV\!a4K+jnDEWCPuQKL$Y*1^@^G>^6M9MG+6
kl@d%@ DVNbd*yREG<maueJkF/+h&j^#CG&%+wh/uWS:k1wc%j%<tN>aFHmVacIL\?S9y\CQ6#:6kWh1qGh6=T\
!e>p+Q <YZe@9ID<EKnX8JWkTK1j$d*<Pql@bVVV*YXLW6QbpdTVR%JCWBFHBI$NRGwkJ*XJ%l!BVIhb6iaFZc@
FR@Qq% k^bj\+pwR9wSlcQe*yRtL=>/QF?W!8dFZ#/5MLQy1t%&C=C>mJp#P&\BXlFIQZ+CuCVPZkJ!YSS%6JJh
kJVN*+ \&MP9$jK>*>ntdK&H>9hiG@$lK<$T1p48wy\hbZL=:AMIN*q9jLk^@L&Mq!yRQ1P%Xi=4tdDVYV%T=TR
Ka+ula ZZj:V=Vp>PyQN6ND\9F&bXZh?Hb$/Ek*EpWd8Qw%WXd*%I&%H5XtuMQ6XZhFn&bw5lRmCP<!F@/JqkFR
eb:h/T !:KG5neFd>1u!nYFnm6dT#Y^Ddh>RJF>*/t=L&9ML99h8y&lY5:?<HN^@i=4h11<uGlBl4Gd+Q&<eH1n
QFbjXa WZp^l>QYh=EHYh!eemR=/TE*M!bFB8M=TXhpA!a=cSw=di+=kS$+FL<N<9!:k9k9W!j@ZyZ#u%EuAwl@
>p<<yC XmeC\u?1V9+^8VZ/n=j##+Q+j:V=@K@XmRm@$B@R\1Jm9/GF@+SG@I=G@AE6>B8FIMI9<kj$d^YCCL@w
h+Bck: H?D@Nln@c%45V&:/:&kB@n?/dWK@wRZ?JS4?J:R\@Dj$u^\&aj:j9djRj>AZ@&D@y@4mH*ty@/a9+H<S
&M:ZRj u94*l?k@/k6BReH@G=:/*>ID=QBj&APEtYYQe^tVIR?Vp9Gpd1*SVJ6waZ/mT/6YL&?^1Ha@&Y\=HJKk
>#KSJV IV>kB=aYBQICVtu/6!^i!KPa5<YpIF8X&C&N8S%<JRAiycAC>n:PlpJLDa8h8I#RW^8By4hwX#q6Cly#
HHeb9q *bcWZ1tH5wW&W4SLnpn>KjZ1YJ>JIKZ!a#K%qkl%Dbu1cmttMFiCjbF/TtCt@Gwe@<B!tDiEaqHuJGbQ
*!:B@\ jIpHJjl\%uXwaY+cuy#@p+Pw#aItHF=Y^5V9aDj*d#E1l<G*QGMKTlwRnBRLk8!B1>WmScMuJbB!B@m$
Se5>HB 8bjdWh^54l1\QLV<+ECmb/5^YRLI@<y9KYbD!bCWSDVdVH^u1eXbRdT*N@ulqtjeW@&h&\V41=c?chpb
Xd*HKP 5p&54bLLVby8e#P<&dGTM!9>#BIVCb$KX1&Nle?Ea\wu8yhCb@!YC$QBP@im6/4npl>yL?T?TpLwl*uV
SpSi/4 H*VwH1qJj#cQ&Ylj9C/nNPZ^tA%4TEC6Cbqj^SZFa1WeHpe*N5iLGLuQX!Iq&\YIdee<Hkn4BBu1bc5@
95TcD+ dI:F5===9+GeZP&@QntIjee5@#/u<h$9PAZtQ9L!k:CMZPmt@F8ew#4n*HX%bYC%N<q6!#q8Dbjt=NJH
y!GD!c d>A@H%nQZFN>/Jm/jnw=K#d6CK**S5R&Tt$N1CyJSc:q%ty8!e9E8*E&C>Q$4?\paDn<In?6h5ma^T!9
R%HRMS L1F*w$CFq$q:<?:FRSWZ<9YZ!K9XIpwA&QHlG<Bnk9#Eq=CECKH8Jlq<PnNnZ:ZeL4/Bmq#!jY9LIYMT
VBya61 *Amd>#JK#^B5B%1kjpu4hAJj\K&G8?E/H/*nlCkS+=/XLEN\&@H58qC?m+i>#T#Hh<bRGFAthhHRE!JV
l#FeD4 =q!EkA?yqP+V<H*BZ+wtZLj8>SGBCeuBTBe/!Z11Gt6Mt/WVF!Fdla@ViKA!8!iQJ*HtpGyy!lMV/SNV
1At=J< +mLA@8aMpZhajnN^nqA5T&!CyZBIGqAiqDNHViBymeqbi#Y4\c/:cyW!FcjVT@GhLApea%e*SI4wHtFk
jn=HY5 8TI*l^?chHpb96DNwp/^d^PpL=K/9iCRIA\c$H/XL<YYl+4Wteq5HCY$8&GKwuX^uNGW>&&I:yYImZPh
FGyX:d G?/YJT6qqM4$nH/\#ctJZCA@e9XZLd<P!eBYbVXcG@DPWHQY1aM$D<ynMdwj5wdEHh@KPNnNVNH$/A=L
yXPk8? d%@WlQJnI!e+#Bu%t^+ERV:/aWI4Ce18DLP=Z5:SdyuL&wnqw1?cWa$L?*eMI6<W#u:LqKDnit@V!S5&
F=q=u4 c$!6kjNiMjjnn&j<Q%QXIyYkEAld1KP?Eqj=*FbPmBe<^PpBY@N6TY&KBtFFwE6wQ!p+8ElJtCe%1*I4
\/dpEB wHdc:#I\6bt<*6Jcuy9maZXFTa9C4E*J8KhFFdiaW>teehMm^FPamAC^SNnICbp=S>ka9=a5^Qd@Y>D1
%>Vk8> 5=+jV:8KibZ\dVH85KqZ1j^FD6k\GS:hFjHR@iYFqhy/%S%njnE98?PXEmHK6\4*9XV65&N\d1H#t&t^
mt=elX :$4JN9ZdCT&PW=PcDFWQ99Fd<yREdibyG8dDRci1D\c>1P<FkYuVqAw$6FM+cyN#AkEpadRk#C=DL*Fj
hIb=6F q/IYect:qH>5k45PNWEV1$EM8pdlZIuRp!<>H\tS!lAGhp@W5Fp$Qb@m<u\XYT*E6p?Ywpq&&cWY^wWS
GdAi%V P:XY<d\\9=<&1WX<jFyQ=@hGwZ?ih55welXQA5\acF6PYihc6?Pu>nKed4\J++m:#mHDaSmLl/NQW!@?
l<\RSq Jyttuc/b/DFccpB8?L+L^dcp@w$>Q^^pL?DQhYMiH!hwEXHSyjdIq#1c%wSnqA%HJM#K^<&%leiGR41!
<59^ZQ t/:B+uTNTqB$V/l5+W$E?cYa$%X^<t#yJt*>R$85F5im?c#ww89lh+VaX<i6#E?QZ$VwcVd%*l*d/Xt^
1$#6ST *LpLF8eR&@I&m?CjLlMCjbI@aJEyV?p=HSc6n#/Rp$yLlP1B@P:4HI=lckwP!lFep!cV!t1%GRe%+^/>
<mDTF^ mFtek<L^NM?+#LW#W%GI>?#V+^!^H%a6Q@Am/S?WieqHXwmGSSC^$L>RFJb/=Wk4b!D+*dRIWW8Blp\K
I?PNEw /Gu#XhiePa9WThZp*G/\QS*=I6^4Yed:AdT/!55+K^Qd>ql:c%Yj6@1MVdI/h\XbMc:?MknTYb=<^CR<
$$5cy! Pmu#EIQewC/<F!tl/GXK#u$L\<qTSj>AH<TRE8FP^1hBde>hC>c4eGZ#:>h6=N6pP>&+$?A*9MKZ%#48
\RAh/* YlBe!LbpJJDKpS9ubuFEk+WXyF>F!h6%dFQNmRuT:w^4j8wX\ibqqq4a!>l!jAaR9canL6E:jD:l?W6=
@$jp%E Jy8X>NM8&?etHc8hdG#%mbP=D9QHt1kp4=Y5TlN/^=Fce#6=&6LX@iL=+uI>4MX&n4$QeRu51Id9YZ@b
n1+T%b CKZj4qh%\?jQRBY@SeTJtc#@?dADe<KiiTh&@6NuNa*1=/1N*D&99?TJLLF+\I5<Ac&jjGd>8IS:Bqmb
Y&h#ey ?%L!Q5=p9\k<am&RdTGN**5c?mM*J<b*F/idh9B>+>5:!muq=^j9K=bTa/abTuJ1pjQ\ZmPBL*K%kF9A
a/1V#@ H$#$T#>4b>LKpc>==GW6lTd\QhdLLDIm/%JIMqImp+S*5#=d61RnS*H/yEMISdN5J:J/dVLH$y/^wi4=
6*dh$$ =E8CNcGEbnpD:wCwq\AC@^^TMaDFVbbCMYBw8=J\#YS!\MT88>>/E+181?PY:Rh&mAJ^c<#NkBW4$QYi
uijG+b =pE1VRe91VJKIlJ?/S*q4/SlLdYTGya>wq^l+^W4*!MeEHdGpL1lW^YWNi54<MGXWZjTJ$5ZX$6WYL?m
IpM9!5 hmnYpJXLt>Y\mMm+pSW1&t>qjVTle!^DGp%\MTI=S=I*My\9nDq6nPS9W>YH^^t:^haF\t1\5Bp\u=QY
&yG96l n1ElL<W+C\y!RmS@+l<De+LG?B\/Gy:IQDN$WC\>u4FCc\/A=RjMdcAtl&DX#<PMl:5Z1JM>@etcmCqw
BJ>wV^ #A1##i=J@8/EckH$y+E#dyt=#d46@6^ElaEXc5yytPL5>a1L&*p9k<uRD?JR:cmR%N9K@l<W=MGP5qjS
8b#ACI m?CnD^BPCHnQVT@auCFlLwiZuZSTC4J#eIi$4@VWwZDRDZX^FcmPm$WZ>Rj5!=j\WwM#TV=TuC1nIXd\
-ATw+= 00020ece26b00110333 Page 411 of binaries1.zip
yIV$Z^ $?qVL@XLJp8/9WF1lyCQ4mc4SL5!SKH/%ZWV$LkCe#naEFQ&DjmhVI&A:dADmje^j5\K:N^^:dn@&GK@
YMW/SX KTTwFeNm!BL%8C4nC>!ubbTylVZ@yb4Qy*:AS&jDyANFQ&cdL@HaRCZD=ymM%9mYn&e?XmlpE>pLJ9#N
m8Q@w: d$eMVZ5%&9E?>Yw?Z*u<*e@H1m5@eQMXGdI8e\^86pb61+*/dJ<jClF#jV#DJ=98W#qCNQQ^eclFeq+p
C++n#F !eP@<<G!ZyQECd5#DMhH5686%BPnnMQ1PbQCj4GTH8THyDYEXHN#%e@+j*QybSeWp4+Wji#?kIMDJu#p
pdI8JE AI^bc#/p=FC!YW6K1%N81Aa4FyF\ITwbwDN=8<t/!jZ!>XN#X1GAP9YXlMSZbLd4<Rw4XYT:M*aQYHn^
&cYQ*D :44BC99=Y$iiEQC#YL5Pp@c\FM/&R9C*tByItItyDPEmh*H&udkhX1R#BCjMP6lIK:G&?G=PK5j<R8VM
#attQI aQl8ppY\+Eh8HEL^n=e=u=#L?e+jNnVt6S^S%M?t?PQGZEYdRQiKSth!1t649Lpb/8Ve^EI:^AD:M1SS
cDG*8i R/\&SGMcp6GP=MWKcD\d8Z\LLPiXYpHGN>L#NH68Vneh$j#6pXBdLlLq=8nRS%aAp#DIw!*+hXJcR*q?
N^na#h ntA$j$AJIcn1X!kk1b<Mi6bSQ!9/9iaByRa*nKTGCV9ZRt!FCCmSkTWn!EJ=y*wRKY%ibPqRY*q9wW:l
aQILbh Pb=Q49J4MZ&Z5+^Z+d$eeejZRk:Ce*\\eqd?iLjmy8><EVJkqq\<n$*l8X?k5:hI9H9+h6$c?F*wpyiW
VWAh18 P*I+?A<SIVu8pVp/@alMAH^&K/tQFc58eCQcn!85>Etd^#?Xc=ZX?lGa!JnIXW9HM5T@JpW9^M*5W\K&
iuWM9@ <Nq:>\knLY#>^Y%$5%Qaq1a%8/4Yu455u4qYwdpPw:w1!*h>=dtSp9YFqBdQym+?>dui\j*nbKJKyIty
#TDLid BRD8CyM!eRBB>pi$kkyLN:inFDmAYi>LaP?/J&!heP*CQydltY$/#1CE^:ZSQJ6YuT?CDcE+I:at/?<t
HY*e^l kn:6q9pB6nPe\MaD&uLhE&C&IF$=15!SkX?qci5LBF6leG5&d$q6jX9H6hJ?byM\ZjhQeI\&F=DpYnW$
%6%FRQ pp%l4VIFWIX#J1MF4TA!yXd8dQRa^5TL&^ZF\5mmWQBERZh@c\$y\e5:jP:GKGG+>Ke^Ic1+^p1p9FBK
mDP*uc @e=:hnWF!>kD/a<9\MCIb$K1V6G?9I%$%bYIn%:j99GqZejja*H$8$wbb4TI1b@1VEqi6NW/ia#QKj:S
a$5S1$ ^ecc$4=ZBSCtDYbe6By\hXDL=AyLh@iC4!/\AekXXePd%FS8$weD^lS8k%5cQdRN9Xl=*niA6MI?9/>T
?c#Jpc 5DE*WtXD@w1W<A=%YJ&V$K^+:E%%#^!G=<qY>YHpb*YN?E@YdM5YF&F18:Y1=&:BdDeKH@A4H%t69@i8
%PMh!Y 1<1yIeb#ElyR%uXppeKD=KRMM/\k1FKtdYw<qc@T%\hJ=L$?t/%NchDYMcaMR5$=he\XwiD<h?B1u&SH
Ju<K56 @pK%<?\/q5a/R\D%Gb+Qb!CZTYT958lm9YVWT/C=Bbm^L$6bRd#Bt1!!A+VneAFaP=++Q+&%RwEi*b:9
!^5CVV LDnl/D54JmaR*#*iQjGa/I>4<n\9YL!6iK:IS/61X\&:tcKBCyEA@C>qD$^G/jp<Zqk1C$?MW?lGa&M&
VpY!=t WbCuNP^SGSMq#Wl>dhE1KKGtW+!c/%m91>ZIGZ?jjbZ1kiiSlGBhn!A$pI9wJZLT@=C^HMaWFehVi8mG
iGCA/1 am#Le!K*W*!RGJXZitmT6:TqE?GaEB+TwYcm#1We%EbuN+J+1WhR*wiYLHPInbKMnGLewYF/cj+plFc=
b6eB8B k1DEku5m1HIyeERu&VptL>Na\daG5p\RXBaDaji!Y*/T4Kn8D/qpc:88w6I^@SJw&q4%K*@T$&5F!#8&
e%#%AZ P5Ga%Q9e1PG=#h#yeH1CBcn9IL<Q*EdLhL$eeq4@JFLJ=P!:8Rnm$#Cyw+/H5dK5KKncQE+eEV68PkE?
Imd15b WeW/?\V=NieGW61l^Aa=kHw=Z&iK4#X98N8WD:9BJVGq=#!iuBWylQZQtT&!wC$qXKKHC9LA&uN\l&R&
?yZ#ja DR+R19=eS85b5m<hj@QZ\XkKDZ=RKL?4m<c#KwYe5:tMKEuuQlXAwR4kiPJ#yHK+>mGW%LVah9VYmGR&
51SDdh aWXBJH*\SeI#ej%$H%VyRjE#jYdnQn^d4>^d\D$D8j%u:GYG:BNFyAmh/KP\HR!E<bM>8%N!cWkJ@u1E
I\&!u> <?N14pB$8!K&Z>pn@**%eG9&>8uGihkeLVNHTqJERpn^5u@lwL?l?GlNuYAC64\iPhMXcbu>HhjiZ9^=
ek**jV %q#n?n8IBM1ZKPK4FeK*WKWYY$lkb?wV?pwy>ylAA69a<X4=e+bd!J8CmlYdQmR$=VkV:jAqty9dwRc>
+w*a@Q :hT!G9Qy1kdFX@M6ljuiq%?wTJXHqK+Ed4@+Gl1aXJSk:qH&T9khcw@XL>/X<SuZKRFc!QyE=!LhmAFM
4B&9Y4 Y4#Aly?R!+Tc&Q%GqtAyqunF!W?SumSmuk@w=$@<hjZFFN@m5l18bm&Z&d$5uPJD%GhX$Pq+EFaY&!J@
ea%^4a /C#YDAk?4:*=RcH@A\Q/$WcYDdu8LLiL+T\PFl^Kmc^L%#p1mb@#lwG?YTNGt=YIJ8iLmHtMqli!MQVQ
IyH@FP Iy8LjeSKSC<#&#PR9h#5yE%1W^<@Bt9/C<\b5ybat\!!%8ZW!q=BQw1\Fuw&?X=RaZXLG<S@@i&S6#1+
q@8m4q jZFQy9$N?H5/kNtIKm+y%u?WIWSBS>=SwnhR$pJcLQK#GLue=Ek%T*LZ*e^P/c6Pw&p^S9/EZ>Md<Dnj
:E4\Xc l+&>dmEL<ZS5eXikRCFG$hR:BD++TXdmm@nI6hWZ5H*uTD^qB/?G*dA5j=lQ$?mp!u65/JbKCQam6?SS
MAS<<l G>5R/Mqh+%#q4WZ^88Da8aGb6$p@qmS\6YVXF1=*Hi/kEGp9=y<GGd8%P:^DHq69#yHim4MtqLPRJ5km
ZYQZEP >\tSimhH#h=6@dcID=5GQ8nTY%y<Mwe8&R6nY!T=u%5Y9^nNt*$VJ>A5+@b6RDWJdp5m@\#p=S5X8PwX
+A!R@K <168VZR^A56TWD8YRbAbAZpI>6tT&!m%<6bb:+PX41<RiaR@&5KjiW=Eacp<H5686D%=TbAjW:A:CR\Z
m>Bp16 <!nY&4utR8>N/lt44*jQBQMaR@I+9PSVuqyZSTT*8bSc?LKZCc5KV?Au?QW=qi1quHetXS=jAiqZQkZ5
1id%8C 1Le$^hnqN^ZcjG=a$I*JSKMRuk?HNLq>MdWiGCX8FD^d1p?c5IQ<HdBD5YuqyidceEC^w&?*de&DDm?#
SP#<n= By\D%i4>d%GW>1Z8>yitDmKQV<:1IJik6IaXAQ&bdCc9PJ=lC@*t%ihQ*c:5whQhBSZhSBT/^kE9WcIn
CLXKQD >kT1qk4mlF%9a+4<:Ftn#C#n9ywWFXBHICRe1dpaXV@hcTT\$#LA6Y^meeBD6uH5@4d8/N@F\*?hMBER
H/dF+P ?W<KE<G@!JwI@uHY=B?#+u?cR9@F=Q@9q@+H\pSA:A>w+h>WDwuA?j?El9?PF9kDY8m*:\*@A%4\N*pQ
a\?VPb EdnkH>B\wh@SRu>AC@^PM<GF@+D?9i1BI@:py9>PieBF@mXc>F?m@&Qi+^@5@$!a@QiI^*<VJ9@wlQq@
8aXCij jX*B9<y:CQH#@=?V>^D=@/MctFXa>aVjKlXKSqKQc9RqHkXXd:C!dw9!&=lyM6:CR4alAGpVtwDZFLXF
y!qJmW %c>8h$1Ld9V+J1/p\QKRqH?$+4%ad\#GHK4GQ+RSAN:9^pmPZdl<iMmddCkGt*K%RWyw^8Ra!IXT\JiS
mQ6KZC wdiFKdZS#MKC%FJTETaW5kKP:pa#>SAnkVF6wtWJbi#MQE\%EChdNTKG@n=DI<>K$cd+FiP@N<DWXhai
!#:Zq8 h6NXBlXXWBBYJ8kQ<VYtDDTn/?tEH<EeR8eq+jatpTJ<a@tVV<a<NE><$I6DGMac$\^%k5jV&kT9/5Eb
d\WS\N /wH9==Rj&RJ9YimbRItX:wilqFTEBLbw<CkqIRKwE:VbEw=W*H6VGVDXltc*jk5pYFY??jF6<EIQpMd#
N1k=WJ QXFNQa&Bm1Zk*CZy:1mqcDP/J^tjK51ZCpyKpCW5uL1lQ&hW5Z>5bb:EZ&ew*k\nh?i5$jC8Ea^h4/<k
M%h6\@ =RJ1Z=8Xn5DhbN^=ZmKVDjyGc:!l\GqLaZMn<8KCNntS:i@<e:N#e1RZ>K@BDMBCTwlSZCA\%jin9epi
iqymX5 L/^VVmc$#n*pIN^W1a6h?=RCmi*wbYCHWD5jcTw6>+<^86GdLM%GW?5hcRu*l>+iP16EiZ/+H#VVC@=1
MM%<1$ >M*XyW@<5yD54C=&!*Ajj9/\=eXmCB:+59&YRjH4Z?@k&P:t1meuV$JNcML+<m\pIJbBjYJLbld*/u!6
e!6:Gt kNPSBRMWW+p&%5@GjVNwkTpSTkq\HYhH*@ymn?kkcR@:6?%iFTaS?Z4q:lw1RkNTdBPhT\YlbqL6QY>h
9=QZeV pKR!Fy#AY\WAReaJPmwZFKlcq%T!JYw?@?mGN:CD4ye6#iDiSWII!j6jRSF$QW5A8Mt6P5uZuqZjDCy\
AT$#9T H+&jhKdl&EA?SBFkh+Wd8:*ImP=i&D$Lk:^9qF:@1yThw^\NGJJkI=l?KakHW8akqT8l&EyhahS$4a<J
>%B9t4 Aq+HM*KX?Fy?XbEL#/YhXdhXKiPhF1!#CMj#<RySmX#5cq5+DbT&B>qqQSKm&X*N?ZaS^@lTW%=?*$A9
NJNFyY S!Xy!E&#C>DH5Kmbt?^&K:<SHthk/iPh#8EtJ^5M/ppWBGVa9*+\N9#\cCnbKc=:4A%E1?mG$ZQS91%H
4Qh#Sb @:D$uZdB=mc!hNt>d5?4K@DY$:TAEqaFNw6M$pAZ/+N%+VDMCAMD$qQ>w*Kdewa!:dcAe$B=QVY@tIBE
FR/A#4 IP+9%PnT&^=*n8p$eb+ES/p?6XaVR##Ju#48?yGCHB#yHI&l9Ew+#Qn/n=m5>b:y8P%A!<4<$ucEAb=n
8GHGkJ ZEJqKMQ5$8Qn6Du$a9eud%WcwlR*#dG&%=cXItdDQ=q6yX%X=H9$Eu1mXIc:ljlFFIiy*cFi!ZjbETbL
t@YNB@ 6HyGaK8+kqVE9QLuqH%Lt@=8+TG:16ZXDqm%A\>CK%?hcjbER%5I=*W>^Vy>bc=#$Z#J/!qNQRpy?&K\
9I+GV* XAwy!P:+KF@SAq#%a%YHFEpt\<>II4\pQp^Ha1aX/ehu+%hZeHl8\J*lXH*y&n/Z@kG:ijC4*D=HuKp+
1p%Ak! K5QcnqjyaFyBGathVVtJBVKPnTn%Y@SWH<I$Wm$qJ4/eq#@iTJCTH#ctSXDWVu5P/>ytCW5ATh#X/WXX
^RTF<j >n9iGi%yiV8JM?tByGSdQIRcuY!e8*l=ll=cP41!\wQWhkZpy/iR\=\NhX%e!!y5^FpMC*e?B5^R:d=4
#9QiiL ^5upe:!T?iKw&9==$h*SR9iyjhyT5P*RB\en9p^p<TE:m4Ean!lJ^<$&mG%d6QAe^yICK?tXFMdhPI^>
Q8:lGC yJ4AYd=Y/t^P\:DmhZHXqA=wM8T^GLalSR*ylC4H$NXl:IFnI<La#$T+Ga\qVdYkpW=V\?ln=$bj1uln
i+<@H^ ^GMkPhIKZNQYa6XLW:Q<NYBR:DY19Cyi&VyN1FjRq=%*%P\qq\?H>6^h\p#lAHwb+4YkR#wL4d:NPuID
pLTdlG ?dh?D<@+<@i*y#d>+!PQALcI>cw!9!HiyL+&D5p&R&K*X?ccT/TepTBDQByV@lFd@4Z46d!$TE<mZ&8>
nuSaS5 pkh16Xp*6Qp^VPpkM6bCtp!!hAymHP+8Q!WP<n^$!5PN6Hp!T<H*NVuPVa$QiE8/mC8qm/6p&%/^lR$G
IPkq$8 !wR?^W?>R%:/M%=6GA@$1u5t8<+PjK9?kdD%?!<MQRH8eaFc+k1KT1>uj>DRd=5Spti>tk4SNiT6JnC9
-Ahde= 000c6aa9f4e00110333 Page 412 of binaries1.zip
j/dWid 5D*JXKZJjbF9:q:%Ft1@+Flm:idpwteDD<<5/J^9GC&8iP*NSESEI?QMAL5@@E!mYTm#XXhYnn$uq\Zk
H??>8q n&u@KC$j+uCcQJL:l8\^46NCn!6%F?/Hw>lLN%tX*6ITmWGn#R\N^cBL*DD9i$LalKwJ6JIJEKD9lH6/
AQXGym iK!/Cl6n!HY!M=IBe&8hlH^cuR?:4auNFLAw=LRJVE#iyFhKFSMY=6a5d4a<tNpHui?uQ^GKSL?9?j!y
p*<lYu XN%ati:XS^l#*aiJkZ41u4V8CG?e5QiNaS@55B#jAQD\GCwGG1?!5VCcEc9N:bwD<tJCnm!SMJNida:w
XX?CDk *1C^q?IYyP44bD%u5b>=W=5:l:M8EdAy>ep6/&iKZ=?&MBq>WKK$Xqbh6aiSVeB/1ZiXZ>P/9=n=p9F%
qBQAa: a^t^ec48I8%$h!b\+Fj^=VP^J?h<JH^V6Enywt?j\WQn+EQW*@+VuqVNZnjJ+Z!NHQmYQ@wSG:BiFke4
lRjWEG #B>=*1h9/eIC#i@L++IhnjqF:E>6q<?l?^%RZKwdCVn^CWLQYYCD?i9jmI4+LaXiY6\E>h+C%6ACFA6T
T%*P^9 bb$B6nPFliDnW<*mBDR8wPq%ud=@HRyKKwa*EwlHEA1\!y5QA=hF/c:&dPBNXdm^V$&GEQSG>n$@\c%*
KCp#VB j9&b%T\jNiclQDRW+\my4elZwkZ^E+!iV@&\J9%FP9WhyV>^QnXll!8VRAyt*AA^>w!Q>bT/EJP+nHp/
L#YPyI DQ%\YZnQI5qPbDJ^Xu!dEVqlFYM1Z>HHe9WL@!G5ptdC\it4&1EVS!$a6+q6JCMc$#QF\lEVbnKp1kp:
aEuiq? !#t9JIE\*eSX9*aqFDwmjRcJ9KqTWhVinaGXPMABh!F5HQCICl5bnl&YC=wLTm4:HN:EJFM4n=k+?dGI
KIi#B! CnXb?e%IkkDqIW5uulLkKt*Q46HJ!P4PHI!wAIbQ=FF$Sbm+qt?*?SXwXWIea5WKDnpd9XPnCRA\<k&N
@+NNXa %Rnpb@V<8I*iwW:Cy$5kW=nIyP\4taI6cBM9ZI:PYDy%hQLB?AFZ4=RGwI+^:R&mYq\P\Il9/l\L*ucG
tN4Wqj b^dhH:u#$?N=XPC/d:lP+&6Yd!8NMp@KK6Y$ui\yJ<54R*dC&6qJhh%E\^6T&16+hED4P9taX=C=1M$k
9=I@jN 91HPD=bh6>S%pV#jy6m/Hi1i$$%Z*&i>1^ei%wkqc!\B%^L:N^F4*R8D$Fb?ZCYdeFB$y*c\bkHIMN&8
y?a8MF y84Z:\>@VJe+#phciqeRephkcTWm/%YA^VBJ$qDT:Z5Sy9SY$@#Vi$RtDbXJC!yaMq<ZP<iS\^I!8kHu
L>&uMy HyMBW8!AP+Mk?C6WT$BbpG8ukV?$uh96DYWN+c&lQ9PC>c$^=diPChdtPNM1#@#NebaLcic1WX+kk6j:
*hwnMD tmdJCaWSnC55X%QP<nwtc%jhQZMAR^mtbdBkP<XFCu>>j&+kYCI=/AT@TnZYd%aNF89E8E#i=kw^QI9G
@ie\>K RNE5C#5<C^Xn9yN*<%FeIaPp^AEa%jl6a?h6B=+1DYRdpGY@TQ/ctHF65aEJthSSZ1>4iHGKtlTKTd:F
9$J15e EB+PT=w4IRahNt4h9TTGJb:^p:/H8?HDT*@A!Yb=S#5VtVpC6!@+t%!$Gp=hd%hb8hc>J>jYQlP:8%>J
XDamBc q!Kc\5X>b@18mkiRN9E4j\QbiWkjVDakKJ/e4M1Tu&\ldQe>ZNQJec:/d5L4cJdmY+/+BJypJRQhRShZ
ethN/e <NCX?NA=tclC*lM1TDmyh4hba1&kyQXnYm6P<1RK&bpcpHR**>aJa6V+E%MDKN4K8YBK4idtt@&=N5+P
Bn%R<w M@e1%lu<6?i=$&uNS/Xik+ic4Yn@5uIG5u:c^c4HDQhwSI8j5j8k8jNDn@&PR5M?54#TJN4S@CnI6mP9
VbXi>S H8/nqaVSHJ%qH9X/W#1plk##?8lM?5tl$<*l4b6pF95$RmaZEiT141/nutm<\VStKXCpXYbYRu/LQ<4$
\cu*Kh :91\MwG%MtdFbG=B^*tdN/tuB9XARZnt<eW>6C&l+emYEeF/E\tXn$hAnJY=9D5jRPGI9k>dR6pL$QT?
44Lki& h@XE<IAAVT+q&:C9lA/WJSm?i&qaI?V*Rt5T^!PCpDFT8wlwemJdSPYXtCPjGKSYVFDb=a^mGZD<Bcl%
M<T?5E Y%=R#e9EqV\B4c#>XdAVNy9?aDctM>u@ypkcttc#&Jl8\<Vm99@#4j9Zl+pMPw+em\Y5wtpt:baBclw:
l1HAt6 %I$?XcH9b5pHF9wjmM@d:Gm<j<Cla5PH\/R^d5QdYV\T%%!/!GSSBF4RnJ^/AS<^#M9@GFyhL&kuY<JM
KZtZ@k yB:\4tuQ=J4y5KqER&CARl1Ww^=NXJ?$K>QZFH>ENF>^DQ+5bRICq=R@Iw@XB#jKSydjQP+dhn%@>$:A
P^pnGt DWCbqpINj!+RbVSDFDL!!c$@JNXC&SS>:@+$15ceAl6%9AM:WT=hqQ:IAT4=dHnJFZPyb^:@/R=X>&j*
:@6>wL iZwE&Nn469\IK4IPLe\mDWt=<Lma&FG$F*AyyZE:amVI!Ky*>#yB&MbP*:$!5?DI5nK^YEnJ=BZ!GEBj
Q*$?pC b#a>wYjF<=V?IhI+L>hC=tNVAdqhL6j/kuEKPeAid6/$Rh*//HF65lJy1WYpmCBCth8#*iIEq*DMq1I1
QW%5wJ B:%wyqb%Suw$!Nn$<<uS#$=ZEY4bkCRP&Pi4t$GWKJTpGmibbcIZu$JhWK*NbjTCDM#/m%VW%4Z1&aDc
KjYEec \w*#8>DbTww&j%MwMwYp/By*/&FMbnn:S%Phl<PRank\pIJN8tSckQ^VJqV*wYH^JLu5&C@<G^%ZH6XE
*&+=+/ ^6a#69HJau:$=m>mYleCjVW1N:%aE4XTNuShyZ$ba#Kc\y<ttMnbMdFu#pXyECeC<I9t8bE9Y$nS?je&
G1YN@9 %#nuwemqJ=LEYVe89lE^q4h=*pRT$@k/</jeqlJQV:#Xw5+Wi<6kAQ4Yc&G\MhF^<yPh^TeuL1CV#XeH
#jVj?q Z9paJ!tRJcWamckVXdB>16j1CXNuY4BEbpp?G&AAyjHRb\/F<Ee9QLbl*M=q@MD1?Eae?:i@P>8#9:a1
=^DQ+a SK^B9iwhEMFmPQ6MGm&4Z%<Gu>Mw!t*<@>n:C/mw?4j6H$bm1JtlG^ZybylmRFSm/B1/8+hPESHyB8pY
A*VRet pi=8BPu8VkWFyKWWSQS/4%<>:@P@j=j@&@hiV:#4Ye>m5hbtM\h#:5%*:#*4@K#nQNJIV4=Y$G:GP\L*
lAq@^$ Q8HCMt\NAC5qlm@byR4K%Al1EyPmtC&&1VinXIE%d6uE8pSVBi:Y*9tc:Rpl4RZ$aZHue#uFw?R6?kqq
ySpYG! VAZpl1T^bY++E=8l8G?LV+q+mWyIwMYK1N^w\wRcyiA6HPi^l#G1G8QFQtFqidb=!*=$dE^8/HWTE\8P
Cm:NhL /\SPcw6bn4K9d>T@Sc$VHwJkBM<Giy#CnAQb:nFhdlQ8+ES!uYu1TBcGYiADeJL$&APIl5b5mEAD^kIq
RP/+@b R=IZy=X:n?V+cRMQ*qh^ApMmHD!Gkwp4y>IYmG^yd@/<N=Z1TVpj+dtTu>Q^HwZ^6Z8:CybH4aRS/#Jb
K<4G:M 4\H4nhRZVYaVQJ=@4cmlGKZnA:RFnNR$Ak#Pcum/:NY=Ft?FbE?^X%t$miAd+BedtL*IMHKwu+81<j!A
/PPd94 1aWa!Bbn$9KabHMX?SM=Yd<1E8YSBPXc!=bE+dYVlN4#4Bi%uHYdndd&jASMyiXeV:bk?>#byaBVG9p%
id#+X^ 9nY#lA<MD<BJAdpGE4t$?\w!6Rdd#aamTTEw!XjD^He99\9y+AXMQZ>Ki^P::\AFBJJWY%YJ6KtSCyeb
9$plQG CV^#Z>Ja5TtmIuGnSWA9C^4eLqp<@bQ<:mGTw<&%5khXJ+NW#GKTTQ*J8qbyiyYm#IXyb@&Et\jC*lh>
!I&Kj5 FZw?c\cCtV@VI/Rlme@Ytp+DY\piQFTZhTL%*IpMh$L*TSHJ%bRuG=dL=6wNCYHaP$\>9%NX=&#&<\MD
y>Qday b4bbN<eH#cXLJY^5Hqw:D?pbdR:8QGLCeydICA!VB8$@Jl*>B8<?cJ<I\!MeEkVNbY9NHSkbXc5m>q#L
huGKZ< V6ZTTP^*4?#pDD1b@=nBWCq@e%D??lXw:#hZth5YtRl\EulBTTL>EkIl6wBGJnF4ZKV^aXRn?TYL$?QD
K4!$bi HNYNDbKCqkwW5yB5pbniQ@mMZncupKu9>4XbZYe+<$W\KqeWtYZTGLWZMYiWYyatDTTi8c%ml^LAq@lK
1c89hm LRA5y>iu?\l<Y58L/:SIt#@Q:#h/9mAtlkpd+eZ/Vy8k=jYB5XHFqk#dRZ@YyY&PV!8eRjGaw9SccNwm
a@m6CZ $^y^hPma$5^Nl*my!B48hWd>#&Smte+:lNIDa&tScjQ<b:pyEk6j!45+GyF9TEX\/?hXeB*aH$AWPGX!
NRPTGC l*^$P!!cIEX<@CC@=NWLi!VP>J%QD\J49<HLKAWhR&XGQk/\G!MT1Smu!nRZGM1MFE*<XE@ENi4YhL59
#9JnI/ Ru9anRNbN%$SFka<DQ/>>*c$HQdTLVR%FpAy5<L1j^V:Md\>%Z1YaKC\E5Y@hGhpb<lS?y=qwW/*N&=H
S@!yyE &FlIY9%1=ymt9=NR$HIF**pM+=Lp<M&du/l4X@?\+1N!^IK1:\h4:wJ%wI<\pZWqYF?$jm:$D:LQp?j>
=W$IYc =E6tL\>PwkbQ^p1$P:<#FXpi!l99AH14\5&kae?XE#SY$VtVY!W88b?=uuWhJCa\$#1*+dhq>5&5LiT=
*Q^9F@ :i:MFq!@>awCS/>?Y$il8XKLly@w95XZ$*DY5?DRJ6$=5t%?:#DIHTZ!cJ9:9KD6/EjweLAa:MNj#9j/
XLZ+bY B:9+*<heaQ>Xp\we>i@MBT:!&<#qu?*t@>nIl9$FQaD>6ppFB9<hNjRZ:AGG?A*%4?b:@jta@k*%L$$1
dR6!$M MJHjWQ?=/^h1%P?wj=HSI\IV@R*%4?b:meAl9/Q?%Z9DlZ>D@Y6mA+j?#4@5X^aZ?P<5NkV<F?ae?P<5
dnVyV1 Nln1X?4jYY#CI5lj1JH@pjjA@uPD#H@#^Q!h>!BRj<F:+CJ@^Z6Rw9@ZIQM@^TDn?4@KIMPFW+jl64uy
pQPWB^ =l<1taCNS<!I66:Lqtab&LT#aJc6L<GI^TccDY#%HDWIL9<6a8kB1nhja%/h9EXTy4j?Vc!attdN:F*k
A<LiuP $iGHbXnNG>9:?Hml$w@1c**/Jy4a#GaqJ:YTk^A#>!VPbuW$EPbCY6SKYP1iC!@wXM!<ydVp6KwK$!Ph
dju61y P9^9C58TM8L#Cpqnq\@DBLS^XlTTC88wXY<qYXIcjt%<JYh+TY1^LmwyE=La^\w!Ny:/ktylMAZJY%F4
?L$V^4 $kZ@M&ewVDLCk#e1mA$\\8aaMw8uE6PFRW^@\Se!ZD&X6%1EyRX:L5y/:eAZSbyDl^@Lm>K4c$@Gbm>G
II<=A> G/m1jCWH^$=bQ\R%Ik/p/m5>dNWS<QnQK89=Sjj9E+^cc:wm+LMcm+dVRDX=9X5TH%duRaCISi!V5Q^M
KIQHXm 8$&JHnF<?q:6yLnZT5>SAJF*Vk@B!#e9Wm^Tj!4hq=$c%ddj5Z#IK^L:DYRheA<*X#5$nJn&>1*cPC&K
>jQ5?h TM\VlC1KVFSL\XT9bi%+E6HD$uQjXAZ>=cG5E<Fu9<YFL>aVBHkB?<Kk&GDM$1IVS6LA9dJ\t9V5I5&l
9\+IR5 TPcnEN6>m=lL^\tbm%XLbR$VY^61#WyadJc?%<u?1y48$kmh@Tqy?8SV#ES4lk<V?iaujPbL!eN9Q+SE
$h<W#\ ^u$<Qqe8NRquj/F:j=bP$?5G>MMQ9BXp/ddL5>BR:&nH*Qd?tbZhXJkM?W?/^GySIaLCIH#uljlSdnZb
kJKPQ> $4kCD:H/>=R*wy!qK6YN>@Ft>IhFVpKN</+w5TpRAbu>>Re<q5cp*XL>BEY6hd*lXT5JRGGbw$IccJM9
^1CKhW CX$&XhmaK4W$P5b%dTbcLc:@YjZCJFG*>JyGhSEQd4nE1*9<QG1a!uE8XM$+w+P!X?C<C/><SdY/H&H$
-Att@I 0002b79d03500110333 Page 413 of binaries1.zip
X<TlR: EGa1dGQmy^:y#cMI/yFeN5+QTR+YlkM@&BF/8R+9WVBm\cF*FjVAyLW&Ij@S:wbmY#aCC8m$=//pH!6=
/8l<tn H+P8bK:BID$$VJ<^R98NwL*=kuRVn^4:QQ5>IyamupEb=C9&%41uAW*pKFq<&*k?J8FD*kjy5*MjNuAk
\:>q+? A4L/pb#u!ti/B:BM#6^=Kc?atM*NlnDPAXdGdX%kHyyTVdb@6TVa+6naI6m/uPGR4*?15%hb:Au9pXhn
<D>mE/ =L61&*5NPW4t#!dtPjnZ4SSiYlNeb8:N*YSlu&PEFNZk4YMS$lZCM8c%:5mhtl<JBGSb%ElZ>N:Ry<\?
iVy1nt W1pnCw=YY?qHTY</iTJ*/TA/aENP6qn#/l<+\9VE@I5P6ebqV4K+waB8@YA+/CkI*5\mRb:!RF+*WJtY
jEq%Ge B@tbSJ?m\ZHW9CKQjCCTEw+GeHi?lAKCJdHBd^A58jju468%tj\5NFTep8@dY1w=!H5/1*kd%$Q1tFaX
V\CL@a *yd6AT1%B>5&EplqT!y%m89KulQibZP9PXTJ1m6pV5kC!T11d@iPae!F>@IIMnDA5ZE^?YI6@X#nk?P:
%6+InZ W/JD8#!*LS8+\?J^b!Y^uAWYcHA&k&^GMb@NTkq5?M^qjwm>jn=9\L&<q1=$K!cJ1#WdNX%:lp9/>CG4
>ibLHy eZttk?<M&qhhNq?G8FWq/1uSp4Vhm9qA#GTh#t!Z%e81jI*WNKu=5K/qddPam#dctXZn9Yh*a4KI/np^
8EF5^p I$N$SwheqEjb6clFtYLHyJi*mXBhAjDM9k8H+BBm%KnQw8B=dEnKnTE!Vtc9#CQ$ahaCTb>19+cbVI%D
:#+aEp wZpD/F+:1RXHduZN>pNS@m8WaLB^%DnWP&+#:=!^kpiQ:q/X\TJNCwAj\uB5k+8M&$\S:BN</&1e=N1p
Xa<J4N <!l%/Mhh@k*8XG#n5tb@%a&YbFquZFH%&1hRSm$V:mjh1Vyb!%4XeRTt+\ND=ADhQcKW4?cSLwQ\i41V
n5/DVy mQ&dw=AlEVEy88!#uNCB*yJA<*5?@6@^?M4RuLW9$E?+CP=XXAJX6d?I*caw@DClpda^alc5EQcBTn1t
:Ippb? Z8NYJD/6Xt85=EDkTM:q$k:jje*6MV&H%&X<Y^uIFLFG#QLtMD?mYD8bk$l%BM?$4S?:C+y1ZDw5hbEG
=9tuPN BbW89u/6Ee/kT%maX?q1QbAh*=?n\^GP?^HHcyDE@*:X^iE1mPSH:Km\=8GD1h1X1k%pQMh>j8*1P!VT
eWITP8 iIWXDCGcVAnw=!Xaln5AZhwk/KIT%aQpZQb8jd!QhVbm$H$e%ZPj<\e4ZZjAw1FeFIIkqyGdhW6@M^q!
^whhmH &yRlK14FmPV$5M9jY#q1YCue1l=c/t1Su>eua>/<<R*DJimkb!#*l\$!STA=y18i6Nd6:wbLaFRjn+lt
B#NN=V %RHjmJy&6\Rh4MiYTl*L*lE*kL=+PZ+=puC8%aZn<h\w%NS/*i8l*5@u\b5nDH8*N+hK1w:t<8ba9CJq
e@bwH+ K\hK/KelPjeY=t<hP5S@i9<>P<t:8\6/1y#ncwHDw5PWbV%dce*wL8l+Ylca%RFKHH@F@KcMiAu/nV$P
EM+EMC HW#EpuAQ#Q@EwQP&PFyW=&8la6c5^Q8ZlyuF#Nb$T>\W&$Z=</49QtM1u+l$*Z*9pL/5H^+5?wJFCnRR
1QAc^k lp&^XFtKSdE1j$TLAIJEDemp>>CZPRJCPJPG^wctIQ!t!+jlK@XP>G!%Sc>+GE?M&?:kp>u6PiV?*IY@
\nA%G< Fq4I4>CJ&<j^WH9V!yQ#K1=NN&Atb%?ekHVZlNT=k&>5WGK6$j=+i69un*%\IJ@<c%j<c>KVibiTiYq8
yBLD=A +V*eyD&D/S4YlqkPkQLF5*:PGcW/&@AqR@8J5dHn^^W*F\QbTQ/h>WJXw%D&^*b#?Z!8Z\iZbnAlE/:i
tV%JYR @4Il5S\>Qj8h*RM\+9B+yH!&>=AWpGZnLKDuR/kCeZ\wEcE%5c\qn8^NKleCkAtJX1k:p1Zq*I5ZD8pe
NV89t& =ZXFnE^WHmJ8SRSkiZj/YNqDYI+hieNp>\M5h!^MCKb5THFm<YP5Dq\9nm?R=ZiieLZyALKNm##*Bw^5
njH&=? #I:LmeImFTey!*Kebdey!&c<h*lL6^^4T1V&=DkwV*q4dhTw5WWwkmn4DRtR+qtI&qYF1$WhD*APw!Fe
5%nmY^ =kkV5nQa@$SXnNcwDVK%5#MlYT4h8dGE@C\4^:eccK6M+C^#&DYT8jwi!^\B$I5pdK8My1PX/ZSYLJLH
^<B4hI E+<$?$SDmm9Q8bR*1WVyqqln#eHI5&AdFWmJZhI48Cy#c@JLcAi1lWSVSDMt$IQXl?TF^$^^4Cpky\RB
nCiwXn h8cq8GD5<4%VX6YBRj1mNtjb6*SSk@T%PqwH&S*aGE@\BKcP5kP:VLQjce>D?=1Q>C=:EKk5BwmhAd64
^Ph$*e !SjbMk9y^e<R&iB5M!c/*LQ/ec>\p#%Aptu@&y1WJbdqQi6kP&PC9+m\Q=B*<m+Ee!%*t<\?cFVRAMEu
V^upD\ R<nBST6*4IY9!<S%!6&qERhhm<MTIh$9#Q4<yju#9BKHQHp>Vi$wK^K@n9b@6Tw6P?ieGj/a1EZ=E$=B
%PVEQt /SXXw>yjFQ:CWumY&*lcXb4><CtilWY\Q#k1HLKFBb$4=\HK6AbQqmk$yLb%S8PBul^t#/pMlj1h!P5=
!IRdX> l+16hHb%&e15Ci^8pbYtB\V$1IdE?NR&QK%61c%LLwG>=LES4K$:biuXitdnJ%q/HZEY@&^d1<Ph$^y!
VS$cm4 q#WS@/C?4hK&#iHWukFZB%8jKm<EMb&tnSY8$*yl+X^WK4aD8<@t\Bpyn!%15$TdkG1nSX>EM%CSGNeF
QYaJ^Z SJ:e1ZW4pwjtm^VBGF+WAEl5LPSeNjEpupbyeaQplZ9d#LuI/<uQ#Mq1&tGhP8\@M?&Q<%YnRlP6>Cad
dq*\mL jyK#/k8SXB=MNAt<?jHSFpICGiFC+AlP:I<89CEHl:qT@mGjT5T!@$jBM@^R@<?iV*Fn/D9+>@XGb@K$
aBCcmA CCGpY\ZSK\9qP5%<HnnJyeyu4w%KdVNk%SCiT<X+Iu!eyb?nC*61H%:ByR1nnDcK&L6Lhy8Fyn45m^YD
LP@#RZ jZ84*^W4j+&L86MjQw!VQEDGatD95JXZ<==?u:KRSpBh/\tQb/m5:Wbe<qcHk+iY%Vi<WT1XV\m6Qmuk
X:BK@S F@+CDKDD$^pS4cJ^Rj6cwFeYJQ/GP5<9aFbn#4tD^@8p%IDEyqa^9tYu@ld@lTc1D?iamMk8Ci+yhNhA
9&l*$y w/GjP5qkh6>y^FM4&Jcw:<cV/ybB%%a=RF/6X?@\T>imE%C8T<KJ@Ww%GbAh6p\NVj*kki?IXpX%DXmY
M$qK@i d6Vay6FVykh9T=1C/PZtK@V1d#/GdqlXAu4q>IyBcR1IG>uG4=pll?wLDCdd*>CEF+Yi58tK=tS\EaLR
hw<D89 p%GYGJj>Raq<i&Q8K9SIVA$y6dQmK$1dhp1Tme4ankjaukyc8%mY\<1\N19>uP:bT9dChWt$9+ad:6Mm
1LWEtk XV8Q*FlwBVJ1qq!q=Yuni=Hbc>*>AFbNnIaD4YNT1p%a8!V9%m=\bE=S^!!P&MyBkGG9%PmW\<:&/Lcq
iccicZ yJRYWeVZbLVtt:KAdScPDYihpFMNGwe+j?Mtj^Qck>9CNHe%/nq&bKm>\&@u>6+8t/T:bHTw9*yhS<1u
$w^euR :eI#TjPAeKtT</1N^\D+tM1TQRm5^Vn\1h*YneeJFqG9lWp9c^wXGmd<QQE!N9GH\6ej=T$@Q5>n?uNQ
1>JAEC TmL9jyJ1>=KVtiL$bDt*HMC#AmuPHjB9A8=/u!jCYHIMBDQH+@k@e#q?WDYbCB9Rt*mF!/a6WBTqN>F1
%>yHQ* yJEG5aWDJ@V/SQ4^CXn&5ewGS#eXPLtmbFwpRHy5ITR:4Y<uLu948NXQDY:A/ilmy+WY/V!Li?^Zh#%S
!5I9qu XLWII=E/:lYyWVWaKMXi\iMuYk#5mc=yF#c\y8lFS<CJD6R4F<d4:<h?bYCyXZ9MchM4WdpLPet>RN4K
bAddHS I:kqQQTikZcy?#kn+ul4nc*jG1P5I>K^$n#DFQM@V&y:aTFRphM<PH$+#%X8bwmJZ4+pE/1wydmh1ekt
k8aNB5 XTdQmaM91wqjGnZIy!WR<$WH9YMdeewY%c8Kn:Mc!iaR+bZl&&K\eXm*!!FyG65yN=Hqy<iJTqk:qFCZ
W\!RW= ?/\jH:P@%:#PYPV#weHSG>PTuEGq4S\TVR@<8pkSIBn&ab6*6E<w5cwq$c9YMJ$kAq<KtH5TK&keME!C
i:iTw^ bJpaV?h+WBm#k=J9n\wpq*FH#IuyDVWm+bhwm#h81pD#qP^$=MbJ5PVhyk<lep+Qh=R4>tN9N%D^y5cB
+C9Wtp LhlBq/T*haG!VSPHn*e4u4!=tBQ$TyCnd^c+jjwwIYHdAX9peEu!qMmFY*V*MV1aE8D?HuqYR5u+LLGm
6FNDB< M8!6GDcYZTij6?BHqu1ct9h!1Glt*VhecLKYlZaTLw*ut\lyiRiLX$+*\ZnmmdNDwPl8KumC#D^@%phX
H>p=da WNShuSCyjyhYBSyXB^I!BeYB*IQXw6KYmIPeG&:/qGb*uVEVPQYa*kmBD=?M:n\\$:aqJ6mIYE\nBCKT
#MXSBC PbQ$lN*9n#%KB^LZAdY?hp8bI81Y#5GLF\1Jd5yXEnMTF4JLm#XT!<lK*AqyLadLk11#G\M6>tnQp>LP
!H>/+5 \M!h$YXkSN&&1$DTI\R6dM4ut&YE%K:F!$El8Xw*?BN/hT9J&m%BXS!d:K&d$qITGXZBCjKB*dbQhWma
HNV9Se teEZd5cVeHpGT18#m*b?%P^HtWqER/>y4V!y#M4PGL5kGSN?5NdVYu4e+ndK+kDd?!*?Ml4*DCp@%bNw
TF?Cw: Xq#A9I8b<lF=KKXb^aBqHZI1tjnMVEKyCim#Y=>@l5DuC<PqT<R5+qLCM&kjwZYLuXcLM#:idk8GX8%K
b9XX59 qc6>qWQ!XyM8Gyd$S\l4twk%ie9pAtVa6Xd<t<QK*+/>RTn/h>5etHn!h*8NS+Re9S&AhN5+Tu&qNy=@
YZ!pyJ /^BD%<6?@bHnXc>#Y%DYtYuK=w5*SQLCQW/nh<JVKm%qBKktPpTVWFH+yuRMq>w&Wt8&%9*Y8mG\uIP%
K!yj$m P#jP\tb98Fw9<#c$9ueCc>\e!=>!\&W?wn:QjMXu49dlLl@qWW*pZSHbi=k<uRc&Tc94NVqy>T/8N1k6
QRGDeY eD/yiQMBinu1hlVBblSjFKDuctH9%?#ZtJy/$!P@=//u45p?cJFcX+npkmih+l8=j#Y\8uLy<^nqpjI*
%W?l+Y y8==e@YiR!ubtDPdaAl??>=\VDEbTq<ADd#i+eDTq$c*9a6<WlP&5jKt9Q$&Ye8miFJeBIqcau9ahE!p
hpyd$B h&eIl&/$$mIlLGP/@#KMC\&uh+8nD:Nm9:Luq11/t86?Fm?mN>SqHKSF<G1yEKNS@*Gm#!GG+9L&deP+
=iMEmw >haAIhI%&SFQ%FY=Ry&H*un&+m&9TXLSq?l4Vuc6hWiNn4ymhjGVRnMdt+QIq4=q+99S#*!Kk!ZyPdN@
ER&qFh @CljVL<^#DCQY?<eWBC4QX$:KaLaQP6:CnmNnP1PY*?T#V9!6KXJ9qCB4&M/?nN5W/QlFbj?Kmy<&j<B
8>Sqc: @V9#5jYl4^*l4%?R98NWt6naY@F8nT^V8Z%:Zly\^$%MWGK5VyQc%?4\hqi@4&/YW%lPpadlp>84pRiC
lMAD^@ /uIhlp&<K!u+Q=yt/l&DXSbtQ8$6\P/5&/5T:V+qW\V>#LM#lB9=j#1WCV?MTLEQnuDI1V?pw&5^/Z\h
lqpbeY 9uDS&h4k1qbu8:%*/F+yH:RM4c<?@QM&>u^DNK\&NQ!A&\=kJXnX<dpTn<6*Tu?88mccAu>\@C5!+VCX
Pt<Dyu T/<G4YXTRiWk%L<*&>a6iqFBVK6uF9u=8h*JLDp!/@SAy6N@PnR#T?C?=dN>/\qpS5pa^/9GlIWd^ZeA
K*Pw<5 :M%BV+#j1^hNj\BFPX:X5Sqjp*S@GcH/N6I6?l=4eF1*San^$BVTjtw/S/Q=>Z*TF&!*=>5*^kNcIL&:
-AaF*W 00076ae285400110333 Page 414 of binaries1.zip
KRY#88 X$J*pNpNBK\+Ak!^@RB%?RaLFDX#CMAPNWBpH^=n:8wY9+Z^mAaSEE4mFLSyeiBJ!pl1^b5J$kMBF4m9
LeClLR +?RN1bqmID:hVZiRRh&jyQd\w?SqiBX?ah/Bw@/*kmT+/H<SJCEl@\/TEKK@DbL?&ej?n^%!^F>kCdnw
KeWKNk :+IplQD91GG@kDpI/G?wEdBj9Vj5N>V\Z\EXBQ\*%LBjXw:+DjW9#V5I=G?wj\%#ECK@Xjw9LDAI%H>E
=bJ*%E IuDS@^!J@M9%<uepImL!F$kEIjwZTERWm9w@^\In?u?tBYdIk1t<:LwSn@?%SHbDFRZG1kYj9P!TkwA@
AaDVXP aFeM/lC$^T#>&5/YD841REk:1lS\VK:!YtIQ%95^RBP8uLnKABhY=X<tj!F5!TNAAISa$M6MM?:B^#&/
8l#Lq$ >IdH#RqI/KjPBTm:c/lKh8A!$Yd9bhVnA!!GlCXny5XpT>Nn/B8Eq/^iAN!lId^EmjFtYTV^JGMm\Q\G
LEGGj+ <XbwhIelW<V$/MSLkK14Zj:Cq:EWZEYc\$I>j9eTCXk5nEnhZAhw<aQP5CJE8W5=ap1hl1DScB@/kuwD
VXddaJ k\JYcE&:4!pZKL?X!d<NyCc:l!@dR$C*bE*:d6a/:1*?/:1t?EyXD&LtSb4=J#lh&L@FyS#Al^4%/6ey
T:XA&Z P&iyG9<Rp+dlGLTFWM*n>^KWt@W%%PGb#V+Z$NlacMXw<j+RJBP^WSRLwRdbi6W+=u=PMF88$E:5i/Ku
c8HJ8> u1?i<YGnH+KH6IeQZ<6Kpt*yw/XL6nQTDab5TM&YpNlq=F9u@qw$Q:ZnYFnPmGQtFk11+cDJRk:P>%:t
Wy?/dC F&lVI/$P\XN>qHk1!5bN:6a68$EN9HbkCMKtc!JDTAK%QiNZy1m#9%8&F?F&>1bbmbIWSL@RDqyh*nJW
yT*B#M <44tjARY@GF*MPe$6YGM/i@JJ$VMARN/QZ8#ATBb$*WZ/!ywnl^:e!nnQIQ#&Nmhw8:QH\Q&lcXI\&8w
@BktBb ditIJF>8QHSeZLq=?P+HuW?4^4I4NMhHRlmaL=SG=&5RI=m%tG:>tFhGw8\^QDb::\e@#4KJtE:1/49<
GtBILB GT&Cd:KQ9HH#p!&@&*EWW4dVNSTMGklKp+d?ATE<IcIq?iP=pm<yL1E#!h$Ic*h!6\De=AZD#EMlaE*5
$uTjDc elkX6dH=^%qBw9Tll!I?F>H6ymHXCw6heKPDh@W*MlH8^A$?X9VB=WjQ1l@5Ce#MbdK!CkJXHwAB>IuD
$D^kES =qjen\?ae>M?hJqP%5$wnKuH$KTW:Wpy<56W&t?Xi6FHJb8Hcd8qD#j1quRFy#9IJDKW=@Y%GM%Ti5WV
EqXK^% 6ak&+!<\dBuY8AYPmSV8$e?\nQHGd\?%<N1=<N!T>BYKuE@6pDX4!<lpVy=WYcnimj8&tF#!a1nNWPFp
+HM>hY /=YTXcy9TcIBb=P4+S&^#:/^Z^VD=yuD&VYmlSQF*#IRQ+XQHekyS$Eka?#KH@H!e4G*yuXEG=Lh\P&E
&FFyLi lQ\cwm^!p4iXdnpae4Qi8#>u#QC?#A5wdNhhFEyTcNy:=HWcym#6a$@/P4@/NW+V:*%cR=^5PMwLMkNy
W6mbh8 aq&tN?iZjHJc&Di=cQb?$$@aFZ\YkRyIyPC8q*iwqW*8=8mA&qpIQy$Mi9FRbC/LRYp*8?diyAC$J>u?
W6PQX& +5\!W95=ua/QFb8w1#FQqSDH%+dyjj9ppw4Tl/#>4A94%%CMhi$tdSqn6LRT8:j>Rp$Z@t/EIbVS\TZq
<1Y&4H I&*!%QF?*RiZE<hG%1q>+&W4XGta!wkCMWKdAhbYmlmydN#8FZpjKmhhWb8GDKFhJ%ZC&t\Wy5Kct1+h
*dXpMG C$P1Rc&8acpNa$ayn51pyj%=1#V/P!AL>Vw^9NaS*?jF9w5=%8pw>ChVek5+QE^lVlnC8B9P!PyXAP@a
&BPKu: \+T%$=m$#?XyDZ@8ZHHTV/wWm=^<?K^Dd9ZSS*L4ZC%%F+\8?M!blnnKyaiM6pD5AD5&$+mV!>XFGtb%
ZHAc6j ^$@%>YuCp@+cTd^q96QZ5naiEyq?RLaCEwqTDX>WI@&^FTt:iuTlcq*tHn!V+!1m5m1=Bw:/ytR=H4<R
mTHVFC tEa:BuyC?pY*kb+%k$:5uhFlEJaA8A4TDJG&45T:=dkWDc#t#HiF1MiaZdYbdX=?6q#iGkyLV&J8q!bp
y1bwL# 5d#@jJDQY!u5$MWYm5+aEm:h#N6IiqHVu^@eEmb5Se4tIKH><>Ga/T&chy86LD$BB/j6CwF#RDl#XwLV
lA\HM: /<VW/1<lH#?KMV8>4k*+>Nme\DDh#1q!1:$wuQYh>FkbaH5<^HbnuVe\Ke^a<MFR1\mjcTAk!DZnE&Zh
XDLJT= Vii/t\G@:^P*=:!6%JPLFK=tkkSE%kP4aGB?\6C+@$bh@NR:HXyj%?VnShH4kAE#G%5@6#De>\S:6j!n
\YPI6& p<<jW<Miwq=TdBbl%X<MWB=G<@:<ZHkFVZA/enT+LuBGkH!tP8Qt!ki$nSB#4#LLtI!#tyZ6PI<ib+XY
!enhHG m/hdjC$i$A4l:6\L\!4P5R9!wEXM9R@8B%dDRNWTGat=6ZKKY>4+#%*Hm&p?1bkL<B&ZwFh8pdeWk*\9
n/CH#S ZHt$K4+>MtpZZ@l5!1:E>!MQ+QinaJELa9i/YBY=4tTLZL*qwE!qc49FY*a^E#VX1u==E4FT4?kKn?Qh
wb^1p? nY&nlSdBWA4P!wZFe/FdFw$L9DEH4<t<nH\&#SA1/uHckR=Nu=SQddV>NyQFt^ebnIG<^mN%Hd%yPk?Z
*@Q@4w #iN65B#hc\6IVcL*B9#:<@a=QL1nEWtt#=#/F#5/^ATnMF>i8j%+S?@<utu:9ptppK>M1ZVaH<<yGy^i
M:pTl< <m6u1</SBllVtMZ6cap$NMX%99PaE#^mdubC@AFJtnHK=48BnF@iyW5nNRA<8@4W1%@I9pZNtuJuRt%W
wte>yA %H5yJ4\1K/9=QhTP>#dqA8n1LZ5#K+Q/BRQ$Z4dKB*eXlpjuB^hh!WS6Y5<\k?eQwVGZQM8BHM5a=y?H
X?8p>h R$qWmq4cKd\?Mqw@HQ$ZFi:wHjb6akQmHCh&nyn%FN?+T/#=FhhlqHih><IeD*RCJlbeZ<CF5K^YS?:Y
d6lkwd W95&k>CQA+4dTmSPXemcZ8+QASMk$llNL9I1kKJVMiWPiP%<T^yZSWP/4M#y+CEW=\#E5kde6dE1!^\8
A+Yth* P65lPS+@<X%AH^BBulGEhhu!h:$hkAJILh=?!QE5iklRw/#hM+HmjkjmH*4LjyY$6dpmq1w1YkePJRLR
9=EV9D W/B6*C64=LMh%#:bh4AA5JDnwcSXuR%8*B#4uHww:lQImI44IP:&ZQ*&QCl<TNC=#mHZCB<uFIR=Dyn1
&ae8R1 %KlFF1y&JqdEjYT^GdWh\@I+#=*KG5t&&R+ccI!XGeiQW:liChSMp$eYW9S58FRy$d#AHW&kDZN5CdL8
F>PwhW ycYkjy4kSD+N&TRHT^TYTdDhhAYNjdW@W<H=WNtQ#JVh&P@4XKM\5mwp%+15e>9/REB$S<Y?E$JSq!T%
PWJY/N lPG1A%k61KGu%MnM#QH%:*Ct??Bj%^R%CJQlC$/&qT4QCbd&DetM?XA5%bVttewFjCqW:kTk6htupkCh
95BQdd k8y4pb>DNHI@5%k9dJEb*<P5*>$6WJ5PpTqpQl/=/uBTA^TlNV=!Q#+bb%Cqq1nK#MF>TXyRJ1q&qS/\
Dq?k1\ qa%iALJjTL>wP#>pj1E8DluRA%w%%E:JWZNwQGEbcC8S$81j=k1tj$Qm\S&C9Pw#tCGA5/wbbP%ZQedZ
wSe6yM =Cj<^y6aX\n%Q!5&AJ$N<*@&4SIG=*#pdBmPCB<BZ:yaQPHJF\\Sya89K1/yb!n$a1Tkn!kR@\wiYGhn
BCRBp^ XGG^pk+#M5b<tLQaN#Y#WXa$yCY<E?VBK^^$AGbHHW%$j5jheh6^Xb8FiFPRR8w=lPQL6wy&Ln$$5J#E
n>XVC$ yJ?=+C=<CC+4Y@Xd5Am5mt!A//^1!5hdMMWXAcq><K!:WRl6:8Ahb\6>aR>4Hy8C?d\Dt1VMlYqyWbc6
W%q\!H R1nGK$mq&LCGpBP6mwaCNBS#PAZmbQQi//pVey#ItLupLiZlH1+Zm89W&N1a$>#q4iN&wT!pQ&6R4:b>
lT1*!Z PLb@XTD4JBj+WQki@+89*m+%wVNn/WFq#4nLpuX#K9dDA6C/TNbqd8EH@FH%wmXL1Ln+?<WTF:&VuPH!
^$JMbP m4YCS1#d:BEVH=PAMTVmFS>byCt?!Wb$Q4WhM+aTCJaPaawPbaJJy1Mul4WmjN%bIS=e<6SJ^QX859$L
>\btQV /MFEIKhBc^Hc5GDKF1AH6YSJ$GCY1hXZ1w=YCliT*%tZ6R?DJnhTekN>D4!9Tpny/ynXi1=hLpwelquN
cL=iNu AmS9Vd=R8BnVIp\ED4!C%W46Dp>bKC^eXI^a868bHW/Td1&#itK9AB>t=K\X4PbW1FF#%4$ct4:9#h=V
M$cC+\ DCbyWaT+WMhpPh*HReCEk@cV\uc?+9HR!TW/D4Tq:CijAVS%%J&WbddX<tt@pdI?mZt4hcw%NdCDV!Q@
*D1IRa \@YDhbI=l=b*j5$/NATq89?AXX=c9%FeyqGdJlmHNEChiF=FYD8jFueyeF@IKB:QEDP1+SwjRHXHBciF
$JF@/h AQKTp/D1C*Bk:I8eqFLInSZ/l+LBW<G4DaRbY5lM^d*qKw>h6Z4uG+?qdtp$ydD1mF^Jt48S6%th^w8F
WkcTSM d=#+Q<qYVI@8tbF6yC6RJ9G<Gcu??nFwKe$4XDMPw%ycFRqqV1m>W+Y<1#E8=XWc<pQ:VW*VuY?j#!&R
pc<cG? tklc#!1len55?a&CDE:=h$/&u+6d&YMHVPC6lWy?uV4u1AH!pFqA!A9H#5QCqeTIY\/%4MK$\%md9LJm
VA&ZMA k/m<ySAm*nL+\lV\6tNayBNu!%Mib&h55YPELJT&!NWX$qDl1XZ9SBQ=lH:kFjQAV9%iEDCc8yaP@:X%
=SMRL% V:aTV1tHXBX!1TbiBA?AJ#1iPP=Y+jV+@kMPL@W^jK*DmX!iCPPIMN>IaiqKd<6nHa\K%Di$#e6N1y^V
kXh8m# 4/Ni\=l>Tw8\4t6@#CSN4:M$w6qG\>=P&1ipLn&CBILV</VCRRSu<@GmEI=\!Gumn6P5b%A\9Z1EwFBB
KM8ZH\ 1=emJ\c6LElu+85tL%kV//&wbV^d+/eREiJ$!#M1tNPS+MFIYE/a:b$^wciiaE$9p#tN!WiWWjYRH$4D
bWh\wd >qIX=RLN&Y5:u/Si>HKnya$AcQX^INlnF>VCIbpaKWZ!pR<Fp1kGCCV6Te<F$%#SQE#b5bLRG#^WQX/T
VclA#K FILnht:L%5Q?EIRPt\8MT<+SBpm6bCiielXeu%<i*hJemn$u8lt8TZN9WW<NKlR!&ECC5<k&La:j+6Ac
nE%u*F +=G%dKu%yCNnVL@W?lK:eRp5qT8KiXXnbTdLRFilyyPhaLMiWB**XYSCFM^E6eqK$!8?G#5e\#1Z8AeL
@WGak4 5#<Z$S9Zaq$&l\#J5B^jX/h8eC>pV<VFH1iwS@>B/lRRYFA&5k>iXhS1ASum<KJCLm11J+#i&J15nw<<
NCaE4H ^ea1Dyt<q9WG=t=5>FP?S*lKy/Y+/Zaw:69:T&*+Fh5WK>=$lq>/%$ed\!b&Y<Z>5MbB+VH+JM=iS+5$
t@*ZYZ /t!kwVdjKEDwC\qide1ZCp5Gq!hjwA/t5k*c>p+Ql=<H14NeTjMILaqX\RWClcKD6AS$I^P@P<A$/?1q
F&Nhm8 ^*mlXqjkhIljMl8I%%JjXmb<V?^u:tF<#PMknVynqIPy6W/KlP*LudeSiWe<ZG56yLD5<!&\^I/GXYiK
&dSV@V 6MB6\pDhhF6?9tEBJ^qy:Y<SY$RThGwc*LjeW+@eS#Tp<k+ew:YL\SMPDnS8HD5PVwbM#ym*lH$>cjn%
&WlFR% N8dCXh*TJPNF??P8XNH/DBXX1MJ+5njd6MN8EaYkSi/Gp<lTD:wTiSJIYXG6E1Bc6hQi$*<@5<dbPlS5
h111XB l\M8q\E\hnlGI!icFy\h%LKeKjhTe*PknntlZhjY?Da>u^mAG\V<+6L>kyGjYj6BNyC1y6d\4pP6>ZVY
-A/6/m 00080aed08a00110333 Page 415 of binaries1.zip
j8XT/l uXMA#8NQ>M:i5ChY+k5%n:qDq!C=T\jkVnCV^mE^K>cRL:Z^idy8wwqMi?$8MK4c@?!F?MFuwd9X*Gci
!mPS8h VTPFEkEyB#WWcR<<6jcKqjIHZ6uC!WPkhWBjaWyGSCEnI491dj/e!FQji$GG4RE4@Fc6H/tJyHQKQ8ae
$WVTc@ MD?:i9:KTadj6@d%p^9BJa/\K<BXtTaj:I?&>8:ZqMNBtLQSF55&I>D4d?>ymn+>L$1R/N4t1iwcCiuE
YitLub J#1#ct?qYed44p5SPl\q>Xl6:T8uRD\RFwjh5iilV#Kp6NYE^uM/qC@T6pyHMh&uRcNttNEhHuj#\>@4
=yd5FX DC6K?uRn^AFy#DDc8l>$Cy>yc?@VG1paKBSTqT>T6iiHWQty*YnIhB%H>>G4#5nK#Q#wy:C1@ZTQpyKD
qNytC> Sq!Fi8ttcn1Y%k*d+TjV#@\KJ4W=Nw4Zt@c==5uke=5H8V+P?W6+@GEEk8L*a8>:5eQDJhi?BPp>V<n?
/h$eR! \WNQ<?nG<1GBPDn4e/Bla/CS+I@Lbn:wS#:weN8uRF:1?:p48#IhXBEi&>N$#hMG6RK\9i/pQ:1M8l?m
q1/h$# bLmVyeaaPQeEW>>?PepSlieEbA:9QCc/W8+HJl4JmKH=H&4SaI4+GYLDR1&XkMqe?/E+T?Epe\$M8Wu<
hX1Rpd PVK*M+h*bRXCh@8mQ%9Nc@neVlq>?cwyi5:?!!S>H?cI68c>R>:S!&mmkIpPD4+cMlq%@diJN+eAY\uQ
P<p8RM *LAp9ulBZtiRW*m6W!jtTW+M%/8p$YyFPS<@J/Gu@RiB+Gu9\bKm#:BXIa5*+?ibH#cm?F/BllMhT1!<
W118EC E1JGw%QZ$uYVpjP%iS5S*Kq9dF@6EDt<l&@VL%8Fip^ab>RVGq15TZ$$Yi+u^XBKbJH\#>F&4NuTN6aC
W/ENLJ ?dXHd^MKLSZTWWqQMJeW%6yT?MpaVN$FF>5PCpPl#E<pKP:B/!+puV^j9X98+VW<WDVu8Npi%#/aML+4
dCY$u4 iuJ*\1Sjm+P9u#uX&c@>EbwPM/c6m^pLQNt&T#<1ed%L+V<=@ZN&nCuFjlJnCiMh?#V>4md/Qd:^+1=>
^pFKYP lb9W<EtEhWtbm6ub5KQB<BdLTj@&P59/epj$P58!444LGQDPCN@e+WFt*ZQ9+kh:c/FZ*une\F*J$*L5
WhbXiD mMyNZ$#PkKP8S>6GCChR+/*H88/BjY9*^PKFb$9SwK>/+cD4/MYDN8l\AP!QVPL:V@&HH&aK6@?wDd@C
Dy9=B> t*8@h9AmYt@tQW*helYubm/9b5jqD8kDnmh%VFliMHiBM#e=mW#?9h\<Au^1Slp&?mhNbMT$WZK+\hqc
b?t!iG GL8wtH+AldL+Nl=>*+ice<<anG$a$CwIL&PHn$?$#/\&RdKJkb%YakBVawZCaKqnBuCDT\w<:wkSAdqR
HJ48!c ?y+qmwCk1KC!bWh%FQ*I?BuJM:VEa=Hqj5C\Zi+\MCSCpI%iJXYZNK^*dK=NaAQnV1=ZpawNA&nLhpTB
^c%qn/ !YMpSuTyw$uAW$NQ\y+ABp%KAc$VYKwRc6KT>DJJDV:%BFJb8FH!\$iWE>JjV9h\A9c5q>W*4=cWm%t+
*8PM5G SZb5B<TAEyKNkTa86i<I+qhdIFPw?$eAF5PG=6GhJPajaCcTa\YWq??+e:5lQYpa*1&8kBLL!8luqpVN
@y&VRH Zb>N1SpKH/^!G+TWkC#PAq<jSP5F=RZYP:aVkPGAyqCI+e?R@BN5VqnBm**=+Mba^ujp^JdeI/l:YIti
@IE*Sp NhdKc=8<8Jw/!pAJ+J^+T!Wiie@H?^XuCpCAAl5VGZ4I#@%MWNu5nF#1^SyJKBpWe\B/LS&\L!\\bWSD
aZjkwb !PuKJkb>\cPp6!kqKYWTFLNjMNRCPYS?^j%tbKcq?ybcmSq#J%u!%qjXF:$Z1EhX5*wlhXWHpKn<jG+J
Im1&jE ^GmhC1u\tJJ!R^@W45A5VNKT&@Bl=ied&8&yKS?Lw6tKtT!<PuhK@+#Tpkj!WcWNtaw#jFR?Wd^<hpS@
LEuqL5 TdKRpQ?^JE6IX9l9=An=Z<FcTPH@I6aTEj%*4CYC?k&5Jiu5:QLu1@>GQ$V?Ej4#=<b@e$9>p*4>E%Z<
q!P&EN S\mC@A9!lBV?Zi1FlQ&P?qj5CAu@DjW9M*/RmN>SC@?1e8S91PG@QG/S*%Enj#E8D+u/DVWM>T8%/P?w
%dSPD! +d<+c!KR*%H@!uRtI9\dc1nw4>T@5>ck9^w!KQI:c$*+q?@>P&96%/SS=Q?=&K\>QQ@#iZ9@9Qd@juZ?
aSHHb1 ?bPtq+Zu**ew&#5:@Q*T6@#dH+EnEH@@@66Klj?=49=?^d1+Y%t:@@qL!N?@@1$a=Q?5apV@9AQCaT\\
nJSd1E KQL9Nj%PLTL@EcImlj>#mQw9K>ujIT414+KZSFB@AXGFEeL@%%j&Q>=ZFmwIMj59?M1p\BB>P9T>Idi:
V+A<mN ychEQi?/8!YG!Itu8#C<wqXQy^k:HN\l&VZqQSJhkH66XXql*YYRt:iP&TX@!!1!GPutH!1c/Qtw#EkN
d9ukPD /tXKZAT?^ntuJKnb^ak%#X=wMCBt6*+\Va+jmDQ$5iWuj5RIR9bFy#hqtLiS!kjGDJP9?/SR+H#!bXHa
8aceqL 8NcSJDJad$R<BE?F=&FLN\GZap#Dl1WcQtnKpHRt8S?\1I6=k+dHLlBlyy6m=>wjNa#HCm:CAyMhFJ6t
Y\W>HY D$*k!=5!im8GeIVFm1^V#Lc5\i5ap?ZRTm@Xn?4#wT>$DMjLNX%cJ+K9eup*+!&a^#/\ARa/NNGA+W4q
:n6ZFD i5nWkAw5XlVh4jLAE\q4?G/LRMa9mT@Zk6qnNWZY6^@&ZNyb&wQaaByVq5B#T/Pt4\@mJ^F#HRWV1KWR
YdBZa* 1SX$^t*?4b$uncQt&5wHF8L#*&aDe%Vn+%#TDdWRlSLtK<bE%Hc<wIbX#RW&Fd1a$?@?K+d$XRYL&m5T
c>!AaI pkp&9n1P=In$q<WQX:TQCl9RdK14eYBG&9e9HSnidXD418A>>ZcemV*pJhC>Mk@1\4D^\MddCuXNQ*q%
NA*YDA 9p?Jw?QVjtmSZVMci=Lh#JMp@&bSeHF^+cPtt1/Y#jFHMJ+AZy*wQ+KlQF?PpMJCm$jBd+yN8/RFhDTy
=/ZEF> be<Q6Bj&^I@e=6*Z61RRt!4^I!nhi#l>pA9GZI%FePhki@d5/pSGDGLqaiZ1$MV6@SA*bk&bRPEpG:K6
q*k%RS #:E1DKIYKc6YyEcn%$/HIZP9H#>$X>FIC^np+GBPNuFhTdeBljZeCk4aaKc^kMHJV1l=L\T@WF8&QV6a
FYE&=d t&VSJ4JeQL&SKEI%5ZD6Y/=FaETJ9<kTELE+BN<*%GSyyA9duwwi4<*XXjSBCu94pY1hhcnHW5<Vcpa+
/yhX4@ LDVeq+MR%*i^wYbbtXLW+>ihyI9e<??RZlty$\1KiJ4T/4C^Q4H^15ntGw5i?#kRGSb/H<&>XD5%em>T
1uPpiH Zb=c8MGWKpHnLNl6B!E#h#&?pltGpF\tpS5Km6Be\+*HGTah8q^Lj5*/#hVlC#\aB=8^/W=ph8L#ES49
!5haQ@ /JdmA*?i8=:b\Gc$K6t?y!5^Le8h/=yQ9YtRCCL/!DY5X$>CMtPRP/@ZISZMy$lebe&?@YJMYy*5h8%L
dS94@4 RJp9<=mQYDdFtY8$udWbuPMJpwJ$PGNMaqETFa<6lmD$NCa+J9C@CLE\J6yyp6n#$ZL\G@1XBe&$TT5Q
e\V9\V 6R4F\Vm=lS%*1Kt$kh%6M:t=T@P<!+Y*cNbKNGWH*PWme$t+!bElMC!ceTMJHp9AEI*hnY6I>/tmah<9
/:Be\K tFX=1@R6ZD^Q5ncN=+P@^qh+N8iibCd<bXcQ!EiTtNhMb1wwl46y4LhBW%DN:5a*Zc&<SeYpRB5iZL+G
Dba@qp G$nt?9WauFV:Il?SyyX:MFiPW%5@TEQ98BQJ+Yn#YyqybX:jnMc8uQ9qS<bMSme?cIcibC^d9&KC=m$X
n^EQ?e XSPq@bLMXE5Vl%B5qcyG$bKICBnd:?tV&Bp88M&eIQ*TQRl4u5T#FhFR$B:8^5$:1F8tQFH&JclPMRHh
QK#RS# ^ZhQY64PBjVXlLC6IN4EWd>BI=J/ujHk9u*qM\QZY!N#+:/M6\Z/A#W9ic9aDIP6K9jKuRLD!1hY!l4K
=S\cet FHQAC@^mkBNJN+h+#!1FqS+iL$b/S+I!u<ccSb%6Bqeu$yMGG>ZZ1MWD>Xh6n^E$Kl/+EhZ1Jyuq&n6B
:!^HV9 FAyBGeRaCD!W>Cb4Du:LZ+BF4YMlub\R<5/Bu<Q>Cb@WLYQ!ZTI<Sud==mJ^u1m89tR#</dWDFX?q5>i
Gu*=!: jHY^:R9IaeQ:k:/j+b@LkV8dS4MB6$@TYeBj6pTY&?^1Kl\D*4/PLNq!YL:4ayleIX9Yct!w=ABGWuYC
=$p8?y /R8EAw\/$#ahR\XS>I@8H\bK=wwp/!RGC9iZ=XN6RL$GM5^XBu=pX&SnEyPP+1WdW^8^YyPN%h#WKkd9
6KZZYY W\YSWQm5W&ub#YpiHN+aTII5&=b#RFt$\JCm%B<$bX!bG/Tmbk&w6*b:ne+<\SG6lBRyu&\$Diyn#ALH
pE>Wq4 @AZ!LbYLp:Z%<Mt!H9Z>wGADuqj+Nth+<6hICqjwyM%jPE/!p6hZ&BD<mI=SiuAEVI:?BQZ9d@m14HuP
5TLE?1 &YZ8nuWHMpQl&+^LGc>j&#WFe$wQk?^k>a?SkkSq@BKVFC9jNVWnAyb4h@a/1Py!*l/<:GAVtZ*bdP\+
dXnFkX Xed:nu%uh\=&@EQpBuA:m>b@Y=<D%?DR=WuhkuY@P1twkbGDS*$XaFDq?\+Tm4Qw9F:D/LN>&%%qX@#$
pTR@Vm &XGkd1&hkK^Y5/BXW?1VM:*::C:\lQPtt%tiEL+M9>/Z9yHQ4A/?NkVi&^NQ%TtG4@wCC^TD=pNR+R$=
/bAWS* k$9qL><$jq&:nbi$B4I4nGNXqLyeMYViZ@#YAitNwj@R#1h6$MFeu1m:Cw4\BmKhRp<\Guc*jl4hpuuN
dMCFJ% />EnMDpbyK5W/hNBCi>Q8=a%jpn+A?EFICT8Ce\k\6DPG6+<5cwe@VTAP8NmP6N%4^wDQX@k?LHpSBZ1
R5b!\t %4GNEH%$^@#?I+P#=w1V$\NY*#ZFw9ZVmA/9IenSY@6R+WJMqaa\8R=bmB*Nwi<qlG9>l<9n#@EVJ!G&
wcEW\= ZTZ^\XGBtF1qMV$wStH?T?dapFFJ:lm:YAQ&>81Dh/j!JRQ?&Y@GmFEqRMc^LiAF#>jTA/KB$iR*L%yi
jiGEBh X!SiPcbH9HCeJ1j*hXJ5GK6wh5DcS@5Q=K++j4dwm>y1Li5cXdd+KWN$Ku$6nF9R6YEXMpd>A^5AAM=%
*IVyq9 ><&beX8EYh&EDeh$+a#+d99PF/X4HA9kdmjDAWkD%RXdQA$p@$1qNdpVl!IC*$S4b&bnJ@&#6ap8@6Wm
NKl9hG iPQqS*EDYjh6/=Fwc+u%k1kk/!wCTJtnewG&Nc=X@FLBKNG:nX=k96Ym/\iuV!QiGCGRjF5DiYK+@c/6
B\4pEV #IwD=BQ^%6bGdKc5de/N!<<pX!8w=X&eAJ5\$nPu9m%u8\ypDG?APuI8YD!<&n8cR#CGaCR951Bq1CqZ
Pj><Mw &ymG<!6CYp>py=HInwCYtD1\=PiLjmmc\m#P41^T@wNQSL#L8GimAJEQD$uC65%WkmwBwchc<R\S>^A!
iZaV*i p4XTkXNQam1cl>:<XCi1pymP:!&#:MlWRqDF1W:Mu^@yyC&pk:X9P^pWn?/E8tLZ&Ln*ycHQCill+jck
V&?Qi6 wn@8^qq=R>1CyuHWBI#kW@*EBZ@RR/LCR9+k6iY%hw*LQI%/QT*@NyF^kik#Sh<j=K+*6lw5e999Yb*y
+%*dNY ES1wFb6+a\yT1wSwCm\pMLRJ/\a?DnuqtD1Jnt?I&@wC6A@A8q/!Wt1>\Deq*t&>m!qqFh\nejl\T?ZN
JeRP>i iauBn!ukqbD*%Tm:i/^nVc^:A%uMeNh8Bb/:NIj+G/Zp+dEK>^mh%8yaQBu?K1YwEYYLpRyLSn+J$bAj
kK$+Pd lGkIS9F1mDh?^JG:A8mBX=ddl#b^Kt&tHZY8+p8@Xp1?@MV>XcDK%my1MLF#C64&hiS1iGbwAJycjDl<
-AAm#Z 000ef42339700110333 Page 416 of binaries1.zip
<jZ\>5 y=ntLk:tSDwSVn\Yd/YXB4nRXduSC4CbpXtdGyXE!PF4FGuM&e=%pR4^5Nl5SDXN^QP:HEZbPiqqHt$T
K*4E%I ae6R5%aVB^K#*JNky+BJn!C$\M4d?u\^AZjDuZT\l%:HVwLa+W&S:IX:WyHMpWpDFjcAM?i6Cw/iDE4G
ulh*m& I@??4EFtyh#>&TRSYQ/D\6*X&y$TcM:=CeqQaE/Q<%TH&d6Xq%neG6p!!uqB6BTSpBMjN?QTXLy<8d>:
bnmy@5 QP@%kYI>Z@KkuAm9T:nW/EIdj=AStZ\FtauWCi?dYimm=watcdAWaAu$YX*c@b5k=Y$BPS=i?e\4B\=y
BN5^Z@ 6PD\1Q<uaF5*:l6@P\&#yG8*@uEJ@N!6YXtpuC$b=HnG/5\+*$KhkFTe#R=a9KS^Tq=/SIT$nAt!Eu^G
^a9JTu 51BdhAhMZcSJtKHaD<*yL<X%TFGbiikhI9kpei^uL?1h=^w?pXZe4mM!%Mcn*=SI\?4uaAE?#l!+$DEe
@bM&=j 9KHG$4NwLdZK@9GYm^Nw+=\A^<41nPePQ+mT9+epPY=NK%GCTmJ!KNFJu681V$kd1Dkn/+t$6AA:iCPt
&j$Dw4 MIAhk@J^bGX@wcd!\#ymA@%STkN61!nCtViS99dcV#m?GGA=iQVk4EkYL^/LSMAY<:k!iekyb/k6jXK8
qcHXN5 E^YyQP@8pqAAlmmS@QHPZW#qBHd8pp#\1!/HcyqNSiSw4ZLE1ZJNJ%Bm%GT\+FtE?#Q+8n1<k+hVHGpX
hX+=DN 6il/M=W!=^i6?l/^heBbMcVCbh^E:+Nq#1NpD>waXdE$NqaQ$y!uM6Y?e6G?PTcnNJ=J=h*1IeR9Wc6+
l1e9Sp T/tNV5w%P?>JN^8X#>@Tyk+\EDu<<D*l/&#FVRRlN@m4L:L!/*e<bRVcZ$eAt6Xwc<?=n$wRlSRXm&H6
SjGKZd wkRHCma+\*Z1\DI4NcH!ttM4*kuSD8!y!IDQn9#HCQt1\+EmEY&knRDP619k>BCXa/@jC=*ZVmyAlA^%
Wi<qpR ZQ>>J/e<w\kGB!HKEG>nc&>DkpQKdqj<<=FIuCqVI<6aw/F<mJL!h#=i6VFheht<inWuD&1YV6K&utaI
We+11I 1G\LBTQZW$p%5I1/tyPwTWbHSV6GpL\YEH45$a\6==iWFQJEKHa%u+$$PTVhI9qMCu*ZmwFiQkau+SMd
A=iuH5 >LX^$#HIN#aJN:a@tp8#/aYyuWcFDda>CX@1I?B>puJp\9/HSunEyY!qa6EZ+#ykNPuCInLijjBpJDqj
6J#:uj nT6jHL:?dFBYXVFHp&di#Jad#Jq9Et\hIHV$jFD%YWKi!Fc8!^jK/1ae:F!6I4n*8S&*GtJiYVqZp?a/
W=KAL9 KIX^NjT\c\?llbAX4lndS*VBWMV/FTZBI\aIeJ&?M*$Yq+djnwh?IT&c<:Peybb8Ga8i#E1kQVnI$nJm
a^K$<u bQFy5ESa%\kb8TCaQn++XQX41e+L1yDqWH!bwnXa/ISIDSL4Xl&8jE4%/Tc!X!9wK6:R#XHjy=YMI!q/
%NS&RM NEd1$/qi/EkDjhnn\+M:enT?F\qQJhRDRl<EVDT=cK$H/nD+1%wBNNCBq!&c<:na^=&Sq#$VT=C<6F/@
Iyu1PA ^YGN@nX\+&G@&6G#eIHu/i\6@R@<Y\Taq:qhhPn^GZD$W!IDCRZmF?TDklat?tShhD?db@CydG@y#ula
?yh4dm CNH\6Kk@Kn/RwDeLDymMI<A8&LWAbjRCXZiN>ytS1M&+dh\JR4>knj8KGXYJ^M@8PS:1VDPEZ!kGbTV/
#9NFd\ qmY/l9@I5QRHwkK&G4y5%VMDRqPZ11*iNwTEyDEa/qk?/9ptkbQcybaWh:YcNMh8u$qTS5!k\<$kn9Gj
a<k^%T YMIYZj^b@:=:I=<4q+Jn8HlkS5NV9Ztu$?Ae#qhlDK>#q98^w1ZkJ^WB?t?#FDnX$+8DS6:ym:cymcpS
!K>/Jm j6T4NXDFB\Za/5@pLX8GWD@KYHm6NtRdci9yJZ#Qi81Yd/:bG1&XYVE4Tb!1p?Ml6n:EYmqtQWHHyt6y
qn&n44 4Y5NiHVEDQDe$q=+Lw1:KjnRb9!4+W+^dWHW^&PlmyZXLLe*&AqBb#&jlCy>%kRRcPJSYhEFIpWVBdkA
TIVDy1 bjwG&wl9enYYN#RtEnQcD8R=l!uStM%YBpnaDNB@yE!Wd?ikPL@+pSES/8y1hyllTwBj>mWS/=k<Z$1J
/c%d^d *4b5&G*VJ1c5P^T>N^@hBJ4pt6dXuueR<A&^nGK8%E/V5JKW1KQSHtA9mw>C+*^/BVEG$DH:N:N$Z>\T
\lyWhP DEEGb6ZIn&Z*>H9A/KR8#V:L+hqh>AYA%ZJ1HSlBZ?\1kPplqy&bb6kH%!<y1@Iq<NCPApRtIC/c=Ve#
5P&b6! #9hc%J9m4u&N=M<48Llj&D&H*&in5d<V#Tad=^aY#iEIb/b>+X+SaQnnPS&S$#^AQbIE4ap:+&dPa&hH
YI88Se 5Lwq/J6lR/@&FEL$+?4GSXn4kM55KF4pNpDZ5:lFttNJq=ZhQMZM?cqZK$X$1=GQJyR^!1capd6y?a6^
wctPl+ 5>b=e?^/<#JQH%wRHZy9/J^^cj9VMJMNcl:PmudTj?w^18Tp^GH^NM8^Ey8ahVP#!NQ<RpqlCJBE9lct
Ak4p6N taGLSTTMDwilEb+GZ1@%6/V%HY#XnWw^&^bjVq:!i=BdmMj%j6iiIpnZZH86bMjVjM=dKi$^:4juJS54
6w+=%w =jBM&t@mPJPlc=^+lNq/MpG*?cb&w4^G%e?=$t?9yVFcn^S\WncuQ1\$&8l5@Yb9*EQppiPwX5F<1D8*
lZ^H#B %NX1%6X+%BCVW*>kJMQ:4M<yNeQkID%aEiwa@*dm+/XQie4in%je%eM6+!=cC>YTGGkMu>>PAN8J=kp8
L?n8R# =5d98F5uDX*#ch!8A:h5F8$!bLZJZ$VckwNn5+^Z\W:H&k?&J>DnT\tjJRDH^X!Piq$V\E+t81cdcX5?
1qYBY% W6y*F*EMCN1Q>$/+Qn1S+PNMtHB<MPJhXQhZDtiL@YA>%XGE%lHdmLcJPmq@B^w@wq4&X%6J<6pyiq#d
qjy:!n <*W\CBt/TB@8/J/n56*&a!iPX8?h1cJc+1q$\V*e9^/uJ!L/9>WFlaL<y:lISBV/F:lI>C<mnES@Q<II
BKdbE1 >heSS1m@/QCnIL<:EA<F@R$%+qh8IBV5N>V\Z$Z=wPC@wad>mk?kEL?ll9/KScGR9/H?NX%Amj#Ykj>m
iXj$MM KB$K>V5H@18^e1l@C\JCRj:#B9/@nE>@c?CnIQC@cPCL@qWRpLCI<Q<yL1lF8pVBFGJMEQ<RDZ:YjKD/
iuAPP1 E$!Aw$n!EL8GA6^bX+BANR+TRXEkTS5n&>AdYPA9#ba+*Ii::5hT^TKm?>FL&HZIkTA+1QVN?6KkAR6n
aX#h$I 4Gm\A4DPtIl:DDc48EZmRbTu6y@#$8R!BMt5BknPwyFPpZ4l$WdnP>T:Z*%L5ciLZu!Wld1ilFViyktE
Pi&9p@ J:@WH+I:NaP5e4Dmjm5RHi@eLuRLLjk&FI>IE^R:y4hGDn1FcNCH*5LJ:SbR51Ie1#jV5GM5?u^j>pYF
XB>BT> al:pHa6=i<Y/<G=QVptkaq:RNJ@AXCtPlNwbpqhmFLJJWS8@e5\kE=#?u4Ik\c/uYZVcAhnYX/:JLRb%
eEZT!5 DD1t4W\TY$YG+lZA1aWqa=C$kt=&1^RA!b=DYL?d&T^NbSKPLZu*kb//dGZ\KKFMCFZ8upB@DHS8TDpt
jhI:km =IljDdd&ZZE5*&iLHPma4W@hH?^aDb1lHD5RW@$T!$:jH$kkyE%AQYYy1nHdIW$dq/A<11X/$Y<44Z=L
PaIn!9 aw^/T49DZYR<mZ8cb6ydla?SX=YyWyBR8K8EqY>@9y>dwab*lB1MX>KHBCGWLYqnLRW+kK1i45aK@Zu=
LFie#N nNRGl:p#uYH*RmP/N$a:TW$&$8HLel4NZVMm\GuF?bB?H:mRHF4TWTT<MqlXILV9yER>eJQCtet/M8PP
wV9?AL eGlMlec<yA!D58KIlVDPiby8m\+w8#K6=Q!X%dt<6W#MJ5=^h^*%A#1p^SWiX@A?m8RDjQ#Ln:&uc6Hc
9lF\yR *NT4AbkTGtNL<wMT\Vb6$qKl5h^S1p?88\jGMw=BY:VVqtdLhFbn%D*e#wHak&kulIw46Y8c&St=bZtA
&lY^eZ =G8dN#R9H!+j4Bp?*d&SQemyeRTEl8yHj\XS:qF6YGdLHDL4h>qwLmKGBa*19njE41qP$=:MG+tl*H!i
YDQZaP *uM+Kw>6G4@HhH9W6L#/R:ek@&Nnd\c#MRS?5@qa%1$p#Dt\c$V@bE$#^yj<dKaJmK!Th9R\b6dN68wF
hmuFmX MetM@1GuLtZ81%6j9QLnRiVN$cmj\ZC\IaN\cLhlnhXX&6*4K/CCYT5hkecXPtY$4<J+5MTmEE:PhaeB
@DAp95 pT66Bw=E!tmRwhpIe!N4%&HWcQt&:^RaQ\@uQSHD@h&u49&R:uTdL^RPy<>Xd8uu+d?#a5t$Ekme*5#Z
deX6W8 nRqR&>iWILB/?&aPHKHMGPVAKc!TN/M*i#i4LAw+%k=n*cNluIWGD$Y$$C&Sq>E*EKq\#N6Yw?S#</uN
>Bq9:: wMTFBMX/:&t:w+IpN^wqlSyQKZV&@J?aVX%ZwSMDl89Wupl$MTbTq:V%6H4ISJ8RyCb8SPy@L#X^9yZM
$\JQic Yi\GYN4#ApWQ^jJNLZQ4GPLcDWkY%J^#u%D^QZcdikpcCh&pi<%eSRAYTPnwtcYjP4!dPGYQ\w&kI>V!
6KI<b% QVW>j1m9%HC%I1&ECjiAm*NEakbGk/p!Kmm!qW4N%w8aQJ?4YIQCNhb?FmYlREqI16RCEbnl1yqQJIeL
5%X$Gl <!^ST+H\n+VS*B4cqt#>>Dwt@eMjq+?&:u#MDGI!PF1=\$%aNyn!p9^%X=/GApSn@cZnHhhS1?:8+ctw
++9=qF 1VZ&F+I1L^Y+LVq&*?l4lH/Nj:5^Mb&PwHw6/K+G$J<I?*n?lSk?4mXV1Bi&6MK98F%1Mm9tJH@Qae6J
/%di<y c!G8^H*nNdW^cS:5VV<!XWXq6@BlKem/YbRSu$V@=m^mQFE/Jc?XNW@TnQ9<lq4K5&jReET9RN=J9Ahi
b@+kIn M<jC\mMR858A=/4JSGFaHTJ5S\:RL#heYkYAmS+?d4MVH$:*DdJ*Vi*t&6HIydDWq+tmPM?V?!GyHcVu
YdItLH Aj\=NL$NNXWKLSSWbqlIJ%WHa6cF/4?t1IncWIe=Qa%y?p!!pEa?Ep46Ii^SmYulHdAdDmc*hp9K?hlE
Wn##NX H=h5ku+SiW#jyJ@*$hkybKBG?GnSwKHjk%eqBX*a5\$\P:Cpjyau/J%w96w/DnuTNqPnA=IdjCF#hGG<
/Tyc\5 X\%&*^netZqdeLd+J6:@\Mm8dnj?I:PpYtVJaye%CXXGu:WtGPh%@Kd@=\=>>TYd^cXp\*A8pIXQa\Lu
hScW1h 1&?$tnNq>>R+JSD$XpntldJwIIT@lZ9^&wy9&^@L>@BDBwI&c<*NHW1qE&tE8=<!F44&QHeC:!FKeGQ*
DCi?8Y YQCNICN%I:!4!nH5adDPp!hd:AbBYyRR>TiBFwC#<4Vk/N$SNc5SK#\G\8B<JWkeC:uqYLP9%Xhpt6eQ
Xhh&\K C$k?Tcy\tEt@!<>QFtlC@W<j<I*$m4=#SF5b*hPlBDeh=&>!5bp6lipZ8PCJ:mtqlJiHER8p86NQdKn:
JEbe&4 P^H5TYQq8$#d%+#GCnjiQ9a>qB:6D6QmJJ1uuVuR<yWnE?CnhS6LS%nuA/$Fnk6cJeQ8mPIQwt\h\85b
\DmR^b NljN5&w/X+pq+&ZEyKkm#\JPEjaTKVZ</VD8eyaED!Z>$/GYy%\<?4^ZJuW@naPI^Vc:Cj\A%wYT\9ME
TQ6ZnP Cem1*i=al?j1hPDZa*tqI:YuetFh=/c*mt:iRF:=u@I+t/$1##^YCL8nWQS#4=#pCnV?#qW=tH4YAJp9
Z%6*It Cu#BL<!!QlC@k/uLjtp!w11aXd<Dn6b<YZ&W5h@C%V5a1jiKY4Bt=/5Zp+P/:y+wj<F^XV&$PnmtWW^%
:$+bae Dyw1WnePDyG@#$%$MiI4e::TaY?QG@y%8?WRX^behR9%M/W%i<c/#4wtp9D^Yh=*p4M!wV^#Xd%c*P8j
-ARbRV 000ff6aaf0300110333 Page 417 of binaries1.zip
DFn*!D VQw%n%L#mHA*b>>cb?>FF*8F1T^4Y#EKquNH?kA9P+YyLKd/5e?GYu>+SmMI9V::NL^8\Z6*>+\nJj+$
AN*89@ c4=#a<NPt/hXT*h/I>9@t1uN?KK<Lt:16ywm611\\L<5lZX1W=jukhM^>in/YqGwRqtjiQHQQ@CjAk1q
Bu:N*# H#=!LZ*Q<<Pi+V$Md%\$md844aX\^YwJ5id4^jbiuk\^qcQ/Rem4*4aI5=MhnH*MKnud@4=kN@\FT\*:
#pSiD5 Xm#?4ubjnR::5icBqQ4EmK=M511!GV+=4md@qe4^4p+<YL<\y&Z:^CCj=a\nZwpk&Z#ZVmAiidbh>MeL
8T#19F N*\bu?YmlXQPlXPutl!uBwBW%@%I=6WQQV@b<!T^T$TeSL1Cby6k\M/YAjBaL!w$wC=&STcpm\A5<ad#
bIRj=q R%*a#9yiua5mw+\he#TaPn*1&p@=y\9\^L$QuX^q6lZY>C+ewkhGYR*!Y8LPDbb#T$XXtJIut8@uk\B%
A18J>L dmQlSFNJbPW##$9nT?$Xu*Pb8P+kk/iKZHh&4Kb&w/*#jw\*GP+h4\:VA5nEj1yGSS=\a4md@NluZE@p
1%Qa<R q+ltHLbQdBViRS^NBF$\YAH*y@INq5W>YELwJV9TLZ1ll\91!kXXPb1JKlt#Q*Z56DuS=WW@p#%ybH>Q
XcXdVy %jZPS5IYN/LMBNMyKF<k/LIk%E@:a5CX1IA/bP\q9X81Aee*/81TW\w6th1\F*d:aLi\<IDQ>IeueiW6
KIX/dq 61eFZ@q+tF?\$ZN*$^/\#Idw$:66MuN:$ATwW^WTWQQZVBYPAIkyy%tdKmNuyEQ^P@dE$^R!$+AQ6+<*
MJm\:u 55Ql##Wk+EINnEIYY?RENMw>8C9IclmmS8V#MwK?w*dCti5m^c:Edj^hAcVG1t6C<JnZZbycXdkmC6Dk
pb!Y&c wpHpb1@P#q5Q=wtR/9?yKdYW9HYjhW#KqFmh\&\wQGDw*hamt^$T^BMZRetcWd$Y5jiFMKkPaM@eL@DP
%1\!u5 VP:G@QVRn/hjaJj*8\&%SkT8$QVQ@L1a+lL5yR9/R5&DS^lhTwLG1BWXWRL!CHq>6$@!:d4!b=wPLVb!
9\kne\ :d&@i=CZAVu#!J1cyFt?n%+b<84J=I+LXtNLaJTY?@Gy^L\qTjLBG!PZw:VQ8$a<b?uS\G&cMntB!cw*
YV<+PD MM<!yiS#/FAC=hnW@qJtTE&J\%C/9Z\n%%aKJi6VaVA$WeiX/!I^wpt\nw&PpIQDnW=Mw<>1=kquYV&:
#HS8Vc RllIIK?AbY&S^ey6PP@LtdQXtRhi<Vbd>L9<9Rj*NY8?:C&p&&P!InZiePmLTi%5FVPu%ZGIlG<@8AC8
\L%wm$ q#+nh&eVt*%:V/W9wY#=$Y^8+Zu&Mak#&L:ytPD4&:%P1#NFtjy*pkPZw8+lEbVBcQh?!aN6jwXM1cTl
<&V#JY Hk$WeC<VNIeSXQ+pGe=F:nwTQAQJ1E8RQYMV=*EE5X^I%\uSeTnkn??tpE/!5lm<m@TTtL&WVbmW?%!m
5jSRm1 ZPyFu1DSw>E=FduV?9G/+qBVatkqZ%=EawD:ZVAXHh!=W<5>G#+4Bmh:BGaMV$4keYnIINmWIW=QN#6@
T+qa<a NGWnY+PN6!j^PiySFEd!>>>+ncQ<Qq&ala\yAc9Ck4uH&Z6$y#YC?+uPHFtW4adWQa6CYN:yDiT\T9RM
B*WbuN p@q<A8/ANuyG\k4P1Sl:ALKZ=+TIFCt5q/^1Hn9a>p\twGh!*1CD/$IDe+Aea^pQPhDn%AKH+lRT:E^=
V8#&\k ljWA4J\RimQK>uw#T<>q6wKHeAW4P9:<@I&biE=bPHnQuau!a5#a9qd5TDYF&nHh$%ye\%/y4MyjC\Pm
NDR\PT 6nC>EA8*WRatG5$Nd$4MZeyJHdDlTADqIG=V<ejE>8Icwl^i:?XjtQKYd@Q81EkMh:C:ViDV9FhJ4u^R
8pI^?@ kb8lqKZ5kqRay@#yIwuj/K48cHaIEV?VQ>R9<dIlAn<LQhF55kP/ZLicTSB#dXNDt%Il/D%Z!n>&qCW=
lVY%5/ cjXXi@d:yE:mMY?EY:\YIuWe4cy%VM1=!jZW9QF^Mq8eP/!uh&S!Y\mISP#DRNkCEWiPHhIAnYB9>#ie
Md#$Md 1aEkWeP<bc!P@:N1J64Q@GnXQahBa*:5pCKL&c=V*$Q5Wm\pP=%q+JL:E!?9MqlY4MD8K$biHtDJw\BL
lE**&: nCy=+>yMj=%$LwS:=Cpm1C!j:/tlJ*%?*+6:pV:NID4BV6566S1T+dbdE^eSSmDpLDVPp66HI^DH+BG^
pSER!Y VS@^>qdQnmDBM^5/u#^8eqMd@!:!Vl?c9tnTA&?:W=c6?^/:8VYQu*qVRRPJ=b*T!1Kc>Z%K^8<lMV>J
E&>VCk y6XVGKXV&@Ek>KdJtY:kXLi$A?i9S9weV\!c?@/waRS69@JAG^C=bBFEWPDH>iIjn^\Ky91HiuB\MK6m
ZGVLw: 6MKc51&SNwhCZ@!4Dy<B^@Te#&%5S@b&haNLHHBqF<+kkFC#XX!mmFDdX:lB?\QkmYjJ:I@!e1bF+JWB
j&&1EJ Jcq$>??GnJR+LWTH!hwDcRZ*5NceTGquL+*Hi&b1*5uJuim\P@Wmt8:X5\wADij>9TiqIZu$CiVd6PtZ
/!i\uE @qnW<EQR5j*&FYaH1C*5EtqZmmApC=<Sp+q+M+w@Eq8#ya#1\cj@HMiSJwV1>tLuiWCZcFiWFKERAcYj
TVYebK XQ9/<B&Y^e$n+N^NGQWauMC9CTESA*=8KuJylk@eh?Gc$qBZX1=8lk6Xmk#<?Tu4NpRwwtSYHp#YBK!&
DWGDT5 c%X:B5*R?Rd#T1H<:M<d+jbEauk!Myq4y*t*MYXEw#mqVFuI4p^j:F5>e=EqKK19F!LWN*ypSkC+kiJV
q95nwM ?4BIJmqGFLupT>l:Z$+#li%hG^&1G59u=Jbk\?#+6Rt9*AlmZdq8:QX*^md9BBQy/I/Rl<nDj>mYwRF6
i+$t6G GlFtRYc:jyPld5WZ@tH?J68*e>y\**B4wWEBwW<?=jDZla=8lbEXlN1&p?ljwSq??AQ<RS9Hab+Z#%h\
L:4MHj @D<ub#D!:l?F9!RbV^#N/?e4Ea:jlGBq1:D!>4YV^h#c^dWVZhQTlwB\Yk/j*9GKF889D1ymLn&dYTWV
l<KlPk jTD?L\$%5^\uaCwVGY5CJJKaQEwAnLqcLNnXQ@*bNwk:YPq9%dYy\=Hb$$A?/\#Bu8mZG/AKuN/:6hp?
c?Y\qX 5*6XiiA>^!N9NwbjWl4tDWpXyCGJl#m8yqBYNGu6Sm$SV*44>a99ZjEP/Nniu4\?lJAjMMG5J?qiLIGq
tkZ>RB 9R6W9%ddQPcG88D/:iR4CD>\GLuudQepmG=VV?KVdZJSqCG@G:nbZ1NpZ:XAZ>9eSjZ1KWFYk>Y^%Dd6
C=tYj= 961%5uN9E>X\hBpLQ6t%Q99uyle\T96DI&H?m41:#\w!y/$Zi9p8G$J*85b=*Xbi5BWT9DpWd?@1iT8&
FpkK4Z kFY=>&aQnqEdy@=&%cQ!DC>E+1%AmL+jnpBtT:N9#T^qPycQbB!cDK:W/ADyw#QmPyYtPwl<i8@99u%K
%5?4ym K4J>$kI8XTLqdq<py9\&6/a!cF$e/EEQNuFL<?a!A89+TcwdNw^88=hLN:pVFSiiZHJRjpA96dWPD\JQ
u%YIaN C598KTCJYt!5ICVlA5RS#^ZmqLp9l>ae6+SA$R:liRB@/W@D#F8#ZMZGNPe//t56Me#?t\q&649n5iXd
XJ:!E: Qnk&?cE:j@CFn#8Q%ZD:EGhH5QSS:&>@\wtl/Q@<yPQB4cH5+LH=pV/9?eT%h=YJ*M>%HnB?85k+S:>L
VK8$AI Bwu#pcVdq$h!eSljjFY9:=@S/ukI8FV#/JYa/$tl:6qeq%dTQ9dZP6HK$DehDthViCDjJ?dmiTB%IVIM
Xd!<+q j#^VIlJ>ij@ywDHce*pPXmqy6Te%mq6+@pPN$1Mw1&hc#QuJeHl9PWu94MXFDEiQ&indDe\uFaG$Wq/#
TQ9YTL ieL!6Z%*6JE5$$X+F5pe*%p:cT8N$BG9qWSD^?1d:+VFc5>Fw&Vd^1W/kLBlk41F^4PCb&hPB\?dHYFh
GYC@Ak D1ubAlpddY>V+:w!^?l/GVl>Nq\TB?I1R<:FR\qwDqQX*etFE<1BGaqRn/T8ylbwCFw#wTTeI<eJtT+V
u#*wi* nG@&#ud%\%iAFD8wMCdpwRp?+i:#=5a?P/TT9%+lB%MJwFGBy!98>uni?WJ\:I!=%XAnWyKla*#:b>JE
iY5XNl WR<5n@\Zw<%E@@ht=In?ImQH+<?jqP!6QQ::H8&j4+d>a\MFEjuuBlV?#\*a9#dk@*wN+q>:pQ?\iwBk
J$4j>l 1H?&<tGmEMl@M*%I8*n>iYnCpQ<9SwCKm9^XkIew:L@GH%AR=L@^B^RE<d9<+X>N+@@anld>m!:?Q<@Q
:Fhcmb j<ejj5WASBG@w@=XF%<W?S61lMk9CIKw!G?w+d@!\wmmjpMN?>WEPFHS*%BDj*HYWBDI:/kl9%IL@+d/
iuB^MZ q?\DBaH?lq\EA9tFG9a:yR5nj/GG@$j&<W@6@!9:RQ%*wVkw1QC@Z%Q@8A#?I@8Am1L?4*ulj+y=\iy@
FcCPk= 6HtlEX48c5FaAMVd=B5X!4!IA>S%tVG^1<$CCp6j8?iW%GG+4bk1+/t+WNC^Lk\:P6BSmGqTuXSnKT=y
yMBuiP VJAejE9ihcXl89\?cX!<k=X\ZDIHHSw&Lm%^H<mYP$IP58R?m\V&Jm6IN\dcYWyPutq#\pMFeD/SEPA^
RK#w55 JXKDWy^wH5bbXuK8m1wp=?*iWyLAj1pe/uH91ca<W9%dNw<6@!Pl%i5?Z8Z5$X5TMjq*<i6bk=$$AX4c
\Le!/E 16V1>d8n?8#NHJ#pbHB!nNn1bt#QlwdH>lc%TP$#ay<%lKZFjaRICKa\/:q:Vl&t+lqH*Z?c=d>m*QB!
R!bD1< a!:M+%^<ER!cp>ShyH=J1ppA*DL%J/Cjna&V8ul*!%X*tiBJ%A8+N@tmMZ&=J&*nMy66QHB1%Nka6qTJ
NC8#<& Zhw%q:YMCl%ZM5+I^bWj>#bi!6HddF*A#hBWpa#\MI<Kan>EYS@J1El9$HWT85$/FRHJVd6q%eqnYw&Q
VQ+nc\ waj*CK\%Eiwek^ylAn1Q1ESF\F>IQ<j14Db@e6Jlyyd:Aw565bDc5B/i<hPVEAa&C>DQda8!TMDPSa!b
tXA@p& *Pyn#tNX*1*SmT1c*DVq#c%4:p1kRmGhAR\Y:e=acyC9wMWpRyJRnuT>G/e*d:i6wICAJFB4lX+wHu*W
p65eX: >Q=BuKd?wdn185KXW:K6y1uilML^WijC?>Ga&68Qw/\:Ti%%%^+@J9&/ltq@Pw8W^BuNP/XJq:l6JH&m
KkbtM1 DVTc+!dWtd%#$P@98LdIM!Y^8tyu/:<dtQVA?6%ELlY6PaVGD>Iu%ch=wGG!#Wkt$Y9!:t/?kt+%n=u+
MPcN%9 ak=\quiN+BdDa^HM!B%/Wk=@<?/<MK*uJB8nb/KeyWiCu<yYNQki8%VQQ</$CZGpWZ<dAK=WcXy5P*qy
uP#wG@ &B<MRe<!Fyi=#uBdGHju<LT#B#Djd1eB16C5Q?^HFijnCpY1W^\?HERRM8\N^NdppR!/n1^8jqiTB^jG
qal#Zq h?>iWm=V?tMLYPqaaQV8PappPpK%JR&/uTuVyP&&/q?CH8%$e%CuY$n^#uA@KN:=6u#C@W#lT%6Z9blD
9dXHk$ V4pe?q+Z6G4*Ca<X1c9V&jS/$=L!GXk^*P!wTd^+F@t=P?tJq&9pp@/YZIaQl:hqnq/8\w1Y1XtGYPJn
d!nAA4 t=V!Ll5?b!T?VZklJ5imt=86#Alk5%>RENS%LcR9q$kC8n<8#W<MjZi6aM?4Sa=Qqin&/w*TK/E&WHHG
>Ahb6R 8$q6+hwa+NT58J!=iAbDEib<PmwLAj+wtWKT\4>PDSAD>t9#8lCAjyCYed<p*1P5eB69:T8B9Jemt454
$\SA+8 !1@#wt?^Y=!CBJtH<cdt+XBSWGY#pM=>uSLMRTaHl8W@K\Mmb5XTy<8<TBN6jMMbm\KA+:mNlT:QJKjN
@&FMHn %MHA$>!C1HiQ\<WMYZPMalPP*B^b<QmAPjeQhewL!AG#Nw:TthZB=tF&YtLHZ>ii&WRB9n\6Yd!V1&6i
-AuQSX 000ff11547800110333 Page 418 of binaries1.zip
dyGX/Q ml1K@<lZCJ/^$4@l^lpY\bP?5@lmc$hAX9JV+SNYG+&kT#W+4%4=18!lTtR>cnS*WhAAIV!PmEd\*1ER
FKNj/M b%J$TLGke=a64T@^JmuPhmBL@=w6%t!VQI\q:um6:I/H^^n*SpW#H*N5HL^IjWq?nB+8I>8<MpcIMWmH
%yY<D8 6kaZDhk>mmykBt:YbkB#qnNDlCnnEA6JIuht%<w^iRLCL?*mFlwRFkHcP$1GA1utD14SWG9?/&cye>yT
w*\+51 GY58pp\>JYB#+L:pZt/@Veh++WRXee5*VTLP<5D$MjP&l\Q9KX:#DceIV^I\jyq=9>j\JTy&Ae9KREYi
5W+q=$ y4VTK?RMp/^==a%4\PCYh66ZeYmhF?9RyV9qjGLb<nuapjtPP*qw&\SZlmm:4&hqce5Z%X/aPenXJch4
MZmDce A5Fu>w=y*=ENGVW<ZFLa\/Rq$FC4XBbV9k%8Q8u!lEX>Cj!pp#:tSC8q1\%1F</ZqDAl5y\ctKi18w*#
uu%Lq% bn#*5Zcm8i\uZTZKR>XAI#HkS*nG8%qeyWQdwn@phuc#Z8M=b#8N!Gu4Xl\t%PM#nuFdLi&LcqW&bL8Z
eJYuDB V>Y=VYSM&uL^4uRLH6?VmnG:dZu8FZjGEhnPL>G?aluhV>R^LI4?VnNiRGNZS$uF<&Y^u8Mb8p>9@$J!
RkuE9i L^=d=Fddu#IRcnFI1EcB6&/X%Xqy6P>i5MQjGp*<FS&t%:qTp?+/+lNc8w&h6/tBL6e9?!cE/!$?F/I=
VDZy$a YcCRWtywjWRmSGX65>B/W?Q\?tp%QVi4!MHV=D6T5*nAqZcT5#ZVCSTDyFP##mZ!9S6jRZYeCA%c*H@i
R@\4!u +5l&8HJ>TEamQ:\8GX%y>=kVjK5:?L!<*?Q&Bk>m/5e#y&RaZb^C41\9XdC1NG#lKI&#e%Yd?M\bSTRt
T5Gu5b l:J/a*?VyhR@9tKb*mEi>N&nTy9pj5:QKIajHdb5+t??1#$AQ1l6/FJ%iYhk?!^FMm6m<8e<TX5FQ9GD
HS:\wV :1jKXe1*u/1JHV14EDiYH%?LT4>1?MuZdmLw!jBEnjuW+J^9I6Gqlua$1S9Sd:L+\Aad*KE^SeXd#tj>
@N9$*6 qmX*JdRE8DHH6/DVE#<TZmw:WeTa9l9/a?ZiVEqHl$huXZX<m<iMVZ6ql/?^PYTRJ+Y>/mjncGN/y\&d
ZJ6T+W $T9H?b@^u*KY/:leF??i8QQtS@W?**FbQDXtJE6>?&LLLiKPQNt%n6CG@MmF1XyjuTAaGq4%bIi!t%$%
T*uA?: 4>ASXNEu#XXq9p6$aCp^a&plw9T%mMXk\qY<PJcIyFBDIhhA=plKN:htTQ:PFIAZ:MTH^/&KWBGQq!em
YYpEW$ 5e6FS/G4^5b1I6@wDB!CnkAI^S$pBLWk+\euq%lVZpFcG^NnqR6pTQEWTjHIqh%P4NRXQu#4=#b^FTCX
4ATha< GCcS%npm$MR9\@W<mVmw>K6*dFK&dqIhwCNY*nEu&t4beddI*jka^1qdVTJj^Qy8$NqIWC@X4Gij6K*A
Vaw*:u $8:ana#M$ciSS>bu+kD<WXutM@mA#cy#LA4Jk&:nY/Wp:e5XpG>JICMDKDbGH?9K+l>^jG*b%#J!Zq18
KHdXuI bbi9^VlbT:YVWd9EmMPtIS*XFKA^MIAWGcaP@qV45&M>>&:mKa:Vaah6$:5JW\alql<ThSwPEYY18eeP
yP\y$4 EWN1WFGlkE<jLVwubt\+W&QKNT:Xqajm4D:!%VSZmeWSc*SYjd&SF&ER9pin?wucDS=Jc4AX>?pPehX*
MmIk6> 9yW9<a#CE=RJl=VkA88:?YJ=pB4ENCHyjwp/u9>cChH1BERHp\$4BP5W:pT1qdVn4BtXyCJ:JhT+W$ES
deTBVa Y4&n4NkDdwqS@m+Zw<y+q516R/Ka5YRHImQBwYRuZu6Z?#6Yc1Aw/mqT1>yCwDw?BqQ#WH*pLAYcHX?w
ln8Tw> dFEZ%Wy8k:SKww#\+MHB1IYaVF4*XH<icn#5=cw8=Jh=^6>9<Re:FDXVXN5@##&VZuM&N%tWJumYi/ui
!k%4^u NV:\uMi/e:</KB&/j%ZEc&%jVKwEEuC+=mH>/eCQ:%D#@l+:!j$1imhL8>Qw1^MiPecmDMKaqT?1C8Tu
Rq6X/h X%1>E5BQkk&uMQlpIR8^E5$^=G&C#jd8i$dKX9BE!<q$+N%CakyBBRy*!Qu$uSJlPwb<?#6S%B>jpP>V
5JE49V *GMR#9!k:u*cV%JdbWy>G6JXdbb\5yMwB#d&<QPYw\$bE@5=\89IbdJP>ed9wQMNj=:M\Wm:KmDwMC+k
<wnMb& IJeawyWE>H=@:8pbdjGe<%%R<e/kC88#TQ<wIq<h^%j*6\HLi?qwul5p>!!De/J4\u8BZj:+V?8*at1!
%=h#Y# i??Cwc/J/F#jE=*p8J@JmaQ*#9nSLJu\tS!CRnK&TJKjuww%aRctEu$&&&BR%+J>54pewV/+#=TnJwN^
iD:HG1 S<>F+eMKXC6/^n?WWLcZG9CcL:/It?98@8/#QaqR\DemV>paySykGBmbuKq#BQGpXtejDFci5=VNX!j9
*iW&K* N<QHtbcdaWKEwYcyE+MdwJX\yHDNS8lyqP1RyBSXJb/4@N8+*NKmNDG\jPiEM^CtiD=>>Tc8AA%9Pb\%
JQeaqD FpZ\Q8iEWck1mNtVIIZ9:BPIkA8%6AdTEC:mtt/4TQX*P/i+kTYdMLRRLFaM8TX%=m^@9J6/1kdJ&hcc
bdQGPW ClhttV9:e9IBeQERBltR4:ELQG5\aluE1S+CPN&nt+^CDQm&8iSh%=Dk+<#n%IZVVkY+^96b8T!S1e*M
Fm5b&= C9qE=p9mCGP8qP4!#D+b^+M99/\!C6X<5J+yD=H/Z6m9P5DHhTyJP!*+%C11XL6HI>na1H1yXKQFYClQ
j/h^<! Lhka=@P5@6E>cbXu6+/C\wCWRJX+a$@/pSImwG!9i6IKAjHZ1dCZD@tmkGPeV\RtI1PnpMF/^uDYaQ/e
K4cb?^ ?LCi:9+^jPK&!EnmS$ylGXlX=$cwll&MDX@TT1DuibHEi<$F?^ltI!<*>I=EPkuCImFe#d81Y>AcwT4@
jqkl5Z 1Xb4?:l4!M!kSXtB@EmI4d#BeqiE\9dmJAHqAZaS1%$t@>4KEPjaWiX:QK\yK9>cT:HRJYFYt<>L&@5W
QHBJY% YXcwR!#9?<YY++BVI8?NekXS>kL@ytaVDH:uHhmDKCc^ZSZZjcQuMVcLNjLhAGtMMa?nZ@GE<SmDhiX:
1NV?c* !Zw#p=$X^!L<F:QaqX^uHaBuCl^Z^*auYW:Xpa6^KyuiQ4d4K5*KQ+Le!?u/qF@$WYt*\mK>A^DZISym
ZB:5qk !JG>=Fpqhb\?XEFH/T$YP!HpVjVc=!l#h\D+ZydYQD@SXDdKiH#Yk&wIne#B&DhLLB+/85\@=yV\djL8
>MpW9T K>8NKhIIL+H/HT$qy@C@n^DZhI1\ZMRaP:**55u#tK&TcA#F^V5L$%:GKbXlP#X4&Vu8Be=<P&m1m9pm
#1V&&u <cKaPKWcJ&%laI=ak?ZI1QE>DquXD=biW>%E?WwlqSeV4:eh1@P%ed:W/C#RlFT+9+%5AJ*kjy&ZqVy/
@i#+X# aGGd^puKY*j$LGn45IFNMl!^Z/b>1t>6<WNw9^TDK!J6HKp>1CE$G#c=j%&>@?QFATCXKqV6=ph\5ES/
CpPtQ> 55>pEpXca=lcBGkHIZMCn1b*C^pyEI$KE\XI^pjn^hGjJ4mWkjXWYSW$DSw9nbW45Ie+D41qF9ZeT/4$
T<am<d KbMSwJE4aLN*5MjAKlF^+CpuMtJ1</PqNL/W&iCEb\tQ%PAp4XC!q?&EB<:cM/RdT<n%i^%+\VjqaHj/
liuYL< FG!AMjjui#Ha=*c94T6i*l@<^pSEbpNc<%TiV>!?Q5mTedVtI*$MFZ6@D!#/w$/+uAHT*?TVe=6hC5<i
$H#aTW JMmy=D#m5E?cRnjM&!/MnEPtS/VY6>w1&#=<\:SMFhR%Ae4a:@S<uX8u&Cj6YQLFDlR\R/b6u%6kT!k9
HkACu4 <uy8^$l$qDn5\wmZ@I\dchIuqC$6yTNDqmy#wXtq\Ca9X#CZJ:P#nXcpV6cT!&&nTEFYnIwmCZpY\yTZ
yiq1uy 9JVjVWA#mu6%Fuu%ib!dcn@hKPJL#H#i!ZG!J\=&q&cVGPdepc!^!j\/MBEFD+mqQSb\XSnuK:hDV44E
:b>Nb> =@G9QD%qu>mCtnmR=/@pVDM&6PKdq5Sclu&$4Ik%YSGYCq:Jj#Dp9wk%JR4&>IQlqIlFtJE&%nn8XjQQ
T<>B?S w9hC\lGBWI@/wLDY+8nh4aRp#hT>inLt9c@65Nd9<uFJWnTN6!qT&>^^T\TDGc1eG$+Ai\y!>H6!aZZZ
qw=hTj $cAn^$>u5khuY^PQHGE8Yuc/VCqI#ee+XqWd#1Lq=Be@6+T#t5u\4+<jPYW$8FRAXX%5auTRMkS/j<#^
hS@W9m %>G@e18#n6Ky4:Qp1T5+59wi=WZlBZiI&\hQjJBFQAC46NamPuqqW^MWGDuI9Jh$Y%*@!A5Vl1hw9WnS
>#&wX* 5\>d%FI>5uNYRVG=wb#D6Tk+keJ^^$I$LhZ/mdQ*p9nBY6?Rn?q1^t9<EL+B$=ZKwLcIGlt!pyN$$kD%
8$wt6S 5yqTZdFZJTS9F5c%11^M!1Wq=mylJTyc>mHP+&&Sk<RKn$BPXhE9Kmquk>8!VX^nJ1^b\c=?TElkRd8k
Mq5i=l Ee5^caCG#81XpbQTeL%H@9YCw&Kh\yyVcM^X<JIyn&$I/D5d@bNY#kyKpJkRw\C!&NLtjPtwuLhkJhhY
ZFn1&W J\%yZV/uL44VQKFR8N&9H&yt<:*XV+*j=N5FAckMpGJZy4<+SWCS81MHE46j<I!1AnT\Fbaw5qECI6G1
l4NSRc cGeBte&1519jebTbjec6\@#bGQEpG$>/%t!&IC/$QW^@RYS:Aq5R$%c&6eKF1MVhiNNX@MNn=tln9<*F
8?kCEw *dA<KIdTiLA>FdMW:MN?^aP%HH4cNMj=R@bh*NG:Djpmw!iPtcw!RnEyZl%XqtDth+Zk&LJh5#EY6HBX
BCPwBj EYi?b=HnG9jdNieaEkakHPi%!:iC\VJ/a^:p$\4QaAFAtV*=mD#jiJ9dt&#^#W#j?Y?*T@i%+ADj5i!?
TcdkCe SMiX!dbb+pmb\j55<^YlR$Pa/4dqcyA*miId<F4i9qlbt?QmtLkW1C$Qj4*bn$bjnkRLnK%Y4buE=cD5
:XpVyP M+kR$9HTW>&%qTb#iS\nuphCN=%n+9L8&+/QD?iZ<=p+^+Qd+llW6nthDZdWX@B4SXXdh6GtGy/\cjc4
D4<<KY <I*6I6+kSXYdV!Lp?LaX$papc5!&qpbtqB1u@YK/GX?@^@8i46T$!<q%kX#C5VwtHBelJGHkE1%uR$TK
WVmd5e #CX&\5mS=/#&1ba<J58M\n<Lu=yW4%<pHlTjRp6i*t!j9FjuMCXW=MDW5j*KV@EQL9C@Dd*<k/H<X*kG
Y?SERw FQd9QAMK@j>y@BbKGQXQPCM5?m?TA@q@#8H/X<Q+*%4S@>:@@^eP?8@IBRV^m$c&/G?wEclj1IWl9/Q?
VSMp<1 ^X\tqLD\d/nl9=lHlSKG@w+cA9?FG9adclkK>k5%@HjW\4</c+njWENl9%Inj$Q>c&wmLQI:y?%Z*EMa
MX*SA9 >Y<DyISWSAXFBcGmj!==Rdmh6dtXwJcLwLt41+8>5/ik8cCX6ai>4jPj%=?XwL8%6+8D6j69#:iCRj<5
i:JVFh BQ1Q?XbR?G@MqQ4H^jP@1L!@Vd!CRFmkCJG@X@pd%WEl9/wPJTICEbT&M*j%6HaZXDF*N4i%h:aXXLJ?
hiq<WI +mEw/Y\q?Ph6$QN9P#D8%ndYj>/JLQ?Pk*?4T8mj6=!@qRpVl9=&teL@kY*>c**<9:G6@&dq?V9dk9$X
=*EqBA &+JC@=%6\j>tG@5@^hhDC@5@M>%w%J6ZApJ9j1@CkS5nZPjtmG\H^&T^\G9MA#A\ku6bQBABViwcByq<
L&P=j$ aN8u&9kNmha/W5>NkVnyim=lNew^a#GB8lN%Gyqc=ZhDICAV#<Q^bBAya9!%+nIXi>L%#bB!EpRhDwDS
@^@eNu eDPEAnGYwyyJNGB1k8E?9dbyiEW#SMClRiQ?:KpunYwwSa!l+bkp#w:ILH@8:9$a9k+tkSCcWC=cLd#$
-AjRh8 00076353cff00110333 Page 419 of binaries1.zip
>V1IdD Qaw\!T=%IlXp6q/V/qnIJ/XRtkiGGH$6V!NEj?KeQDYbCQ<jnGY1dNXIR8Gl9*q>bq1=H=ZnYD/SPIB?
YHCZ9K %19TyL=wqKuXnPbdPcYte/:pC?pGa%KVqS5FZ?QZa15$k#+HtRjGF1yKJ:F9^y9V^K#VGpkLNJN9nIaw
mTGCCN 6?BVHyPl1@AE:+I@B8J5mMXkRpT#Qu#yppDENC9?EDa>5HFJC<WV?!R55QSFkH!F\yt#S$9a&leT%=1+
JY$Yec thy:D1cSQbldu<\hM/m5BB8p*J=YpPpNR>KQc5+dF#tYH=8N%h6JqNCaXF?*?%c/X%CEYca+$NQYpXj^
aX5jIF RRuKLa:dNqcLilwNqVPZKWKdpt9ch1Hj8Tw?^Jlb1$p6HWqPGEmdLatH+JX>H\Y^8W/Rp<E=JH1Fyn=^
=nmM4t QiynC=wbil!anBIY+DNdky>jMt+QGFNqT*?1w&hE>Njh9yJe5K?+R#N^PJc:S8ik:qyQC<&8MBD:$K%+
WydjV& eC^DieTH:u$kwu+><hmM=8$JV?NJ\I8#T>NK^Ki/ZbIJJw>5\iyltbw=a>#M#KTA#dZ8a1/R:6Y5S&4!
8^C4q+ :pR\Fp5<k!+lDLqS!@&iydM:\cN&@N%=Ey@M>5*b*k5V4N6Dt=HS\GA1%X5JL!W?SVY<qw^@+n\&Akm#
R#T&Jk !A8WmqTLS&&XEHGTtFhA\mjb1hE$SihAl+uR!aT^l=cAE8dT=Gi^y$!Q?yIDmWu@WJTakHjBc\4%wM#k
T=cJ!% EwpY?yK&/tlF=mhHi6RbiNV>^5y8BAAG&4j5&!#1Fl\9CkiaeAM&/C%>e+*mKtB%SWHhqpQe/AHJDMt?
TSycku 4<5bHt4JqFmblt%JNtuKEPqEd@clbqin4X=uePZaCH4&*y%8NLYA^9#LNIVEyJJjjmIEVR&ZM/P*Ym$\
49wnIH 6Y9V+e=\uq4l??bTjhRq/$uK1BGyL*VM<J\BIYEWZiIN&18eH!Qj4YD<qyTkyB%N^$/j^1Xy+$hmZWmd
j/ny+Y >pApZh%X=ZV9Wlp>XEYlPcCnXIVm%Ai$yc<%kuaqD<y+eH:w5qc>c1DAQJT:iKI?LaawyC=V4$6&nqlC
WS:lK^ ALb<GIPl!GejSei+CXG:NJwF!aFJQ:Q+h4>LRKyc=^TT4a=cuSw=inJwDq1jBhcINNJmL%>&8cR/:wwC
kP6Y>! Wk?N1N#ejT??&K9Va8>I*ql^tnM\=:l:^qPeTqWRE:N1WPX/&W5yFW+Aptalb1B+1A:^qLbpd\S=/Ij9
wL$EGh JFl=!Y%FZmKTY=c:M6$F5Ai5T<ia<<PkPQ$J/I=X9&qC9NuMLjJtPL^u6e/m#wMtST@A\F#*PlRVJtZM
lnVCQ* S+%bT>NYldm8B!<#MAlZAP@KLQn$LNtRG^V#Ee1A5eGXA@t\I+<LIihMk%B&<jN=kw!1J9<JFi=SlIcZ
DLmWya p!9HR^G8dcL\Z5el@XmdHE/bk6y$Zl4%&68wS$yYhRIj*8kK?Z=Sy^pL=&aXaNW=RSa&an>#GniBp\te
5!LBu! BGu1DJYF9jSJySnj+Z<k+cIMAn1?VGnm?<bDZZ/ph=A6!89:uJwJYt6^ZKqb&I=4twP:bCRkP51u%Z!:
%e55Qc +Q=%#PD%ukVBF!@K^5Ke\41NNFEHJ@dd4>NVuj5Hi*+I<hhq6iwk?5^+e8@aNe^!e%#X$J$jhuA&*M$K
\b@SAA !L$u?Dmcm/?GbdC8cY&!+IFVJ6k+TYiX?YE9hS@$^=8cFM/?XY^EiQR^49tV^QFS^L!tkNJCa+c9hX&=
66Th8D 8XtC+y%BuYY+tPiA%Ytu%=V*/^Zd+4i9PQ$GynL/9daK%#^mYM>G/GT/Q*^+GeM5q9e1\5*Y#P!>u?9D
Vi/VuI QAKeG*KC#JSHiw$4GwY:HStmF>wcK:=Vm!cZbp<aY:VFa?jyVHFi##M!#/\DBhJ<8?\mI<+aqG#XltKc
!eSIFT HHZ!1=5a?ZMQ6bBHb48H65iL?p#YZ!dZRG#Tj6V1qTaG</Yql9B>nSFJnX8:jac9>cm&l%JdW<Si58<:
9kYRu$ iYZ^NqZ&4/YN&1!\Dmj46JP6enZnJWB#^</ywEFEl/8X#AYDG@pGiP#/cXXtLC%ci<qteeV8@LhjBN=I
/dJX$S BeP^Fp6GnXtDp1tC4l6J=5a1ESqQnPueH8L9T*6qNe:A+XbKKTQ5YDc548ldFc$CIF*m4T!%/%6l<q?d
!np@ZH PCn6yGNF5dWRY%F4w:#>+@k8!ktm46pkZwHwiN1J/+JwP/WM6KBWWIM9aZAl#SW$hN*pc:@d$k1$yat:
dInyJ^ %ZTEZhJ/PtX$cp#N:m4L$hRVVtjGVMHQKhn+?1n9:FWP=*$Bb8thqpZV<%&iPDct<D*tJkQ@cIXkP!hL
hIjqB? a*EL\eN*ZA*/uJ99<$#n%ye1ejGijWl1!>P^WXJA9/=+$edXWACljYJ9/\Iq\mP**1$G&ae=YQJ<G\X<
/mE<WY !\$EG4IB=^+1udt+#E>\tV\T64K#91qIbY$tbtVG+@$DGu1=+Ji5dCdAt*9XLMn+l?\aFGemHN$kLI@h
<h1?tb Hy!=?b#h\^M#MJ^?<:qlyn#HNeckCCTSXeGba6%#&A@jnY=/&/i^>puD<BAMXtd9&N9wLm#V+>uTJYBB
ub?Iw> K@N@^6@RKYqJ#T&=nph*nnd6eYDZaqm!6miit8*&Fp/AmpQ^AJR/FjKa<1>48Q64tPiE5XGYqnmLBW*#
\4a&P$ ^JliWAtG@hnwWB$ZuKua>W/u!BJ\+k?PAc:&cSKwJRC++@WJAyR4X@^4e6j/dncXqCMJ%EkW><Q6wW5%
Dd1uCY Bt4F4AIXDY4>mkd>F55!A<a!&HZ8#DlR=%64@ITc5/naCw#KY:DFAbt<d=#C>RwFMKeCQ8FcauTEGYb*
QyaLRq HDc#G5/%G>/1IP1jc#8S<C@9T&W>%Cjw$cuMwMY@pRcmnQn94IeaA!H8ZkJcTta:jY:W:a:$1Te6TRK8
?kywE< Spii>T1N%Lb?d#j$hQ8c>HH&kCFd!/AC^>lG89EG>Ikk$eB8Qm8=V=eSICmPY&dH8Qku6<D8Qj!jJAF#
iSDajy =hk&Lq#Q@LKFtA&4l/^Ph%TRy6IV?&1?I$=&AFi5RSt8k>pGtJKJ\M/>F@?hk*P/lQyekhtjD@?=YaIQ
F&NhZk ZJTA#KQ:h%VL6C$bmE8uuld!auhtqA8Xe+i:&5N+>cd<5uq^yiN8nIdjkXZ5ALF4uApV=j$49MG!Il1I
uE\Ij* &?QI&h1DP%9P=RuVh/iZ?BL^&>!V9ZM%:+\$e\6j<H$R!*I9W6BIXuY9=cp>p*P:W5l@!R8NN&X6+Nqj
9=ThM/ e%Zjeh$I<\?\=cmtQFMkMh4>ip^PD#>:#6\4#h>:jnjjn>*M4qD>QV@FB>h?hh/#>H#KEDm8XH/iFD#j
R#:CAG 8/AuZ4nHXaFX9FD/wnBj6wnEYmAwi<T^#A?At<aSqT++CPL5$=$PAAyT^uD%GE!Q<yh%!6WDK1^qK*Iq
^5B@6h JIMkBdMm*BclA9mp:HbVI%nuW\:KF&nq?E>FbHkAqRLiDG6WM1h@L%YPjZHVGMtl5%WjGe8Gnb1nA:nF
b*pnL^ kiAuFKeHVJZyPH!<^ienXP*wC$B9pew:c8yMqn5t:AkKFk+@WPB6+nV#q>EZpyAA<%^Dl6<?qBWVJ14D
Y$ySb^ BB*e6&&TImlw1DNweeEn4qNlQW\%QwK^p:Njj8mGHBb%>VY%C#8*t?*W<IX>WYwt/j1E4&ImYE6BYt1!
1&$EAQ I>C\XD:$XJl:VXkA/CytLqBN=SSnX1qNNpC46X>*XGBEXE1=Na%HCGV6PTGq8ZBj\G<YW\ECYXbqiNtq
\b$PhD p^$NS=9$Cb/V5N@$P9qhP4\Y=b=VGME1DwjF1\w^BM$%&iNQ>QMKXTNqTucu691c&HB&mYunFaDyATQP
b:NWCI @dTywXQ^CwqyaHTCLiwA^$BXIVQB/h1@NM^$Y&K:#%DeM!hiRVpRLH@GF*I&HJV8Mm8tbQYVlq1b=IX1
RqZwAF cYK/q!AcRSI9IRGTPFC%de9cjcFld=B^Mce+h?FtbbB8V/!qIIeyuMt4N%Wa:kYXJt=KdbTA8XPWjLiQ
V<k*Mp :$#NW%54NSlKnI1y\dTVk:X*4/DEkwLeQ&ZtJ#Xq*\uNm#&h^!c^VK4L=C145chWHcdSLGPII:DCKJue
beW>Gu 9yVp:?1nmwENB$l6^1j#+ca>H@Y<CyLDwj%cm\INcD:=qT9F5#iD6Ky!KF%<FtYJCjhCCeH#P9@mLbpt
lJZNHp ?QhK?Y18FRHqKjjBcNpADYX=H!@PjCEl1PVG$k>BSaMRcX&8HFXXa?8nEcGiA?4?qiHku\kQT9:b%Bb9
!TqR+V lJ$kHJPdtFC8cKCcw1HM/5ZqaF$F1ia!^m4\Me^WCM$SYuJ%aCWp5Vym>kTVqq>Ye8XQ#yEFc6wt/BJ^
AWm*q: I>wCd&8JG8+<@/c!@YGw:<AnG&5<=$lwiG1%KRG4RhPb#EKbF:i/<&/%e:&?G+?b#CKhW!E#yqnVI^p%
4yDP$# 5:$^1!pjkK/IG4LLWVZ^/ywJ\qpLH5aGdCt4!Nh:\jwCF<%/?XKdhG%PI8JD:SID6ulQ<#b&Cl8I8DTh
b9eqJq Hc^$CAX>h!%AEiD\IuBEPG%ITRp\!h=L^AmDS!&RbQi>!A#WhiBHXHahRidF\?RdRS>Ilm\nPjJL4TRF
w8FjHR dpSTCq/GHqpWjl$^/>HT5h8/BD&Qb#Vd/hdN&:CJyAeDXyL/Gi$6AaHPTwauJ%9NM%6FI@b5>E=CddyF
*GE?lY w\E&W>JFPMXPid4FG4F:?>JJ!+F=H+MGSlEILT*AmF@$?V$H/+ABb^hhlJlDcpmSZ+d$4dBbDW58Spe>
nGwmbn i5@e!ZA:W\5=+8ep1kF8VWaZ@I:PZ^&%mNKnG#1JnaC#ZaJ\epn8/H&Qc/j6^1kCGcu$d6hQcAM6BlA<
Pc9Epu +IWCa?#XSML5!p>WIj6IARFNq@6TWi?8R+!1aQJXn6qkbE!wnMjk@nYZbjR+j6W\m@V5#/ej8hMBt9=N
VCY9WP uADmYwF\WpHYee\BRZRyP8L4Y>%=Z?uI:IS\VdGT4mSEPKcW!VnTVe?4<ladn+:eG?DRVnwQp=WIabJ6
Ew6+Vc l:yC+9jCMVT*F<j?E+jIwA\ETSyk^c5$YH9iY^BlGW:DDPVl!>nt%R#VNI@D/ncXAd6G%W4%ud%N+n<h
m=EDMc tGj+^h8//QHuS?yiyAmXTtw^ymiXRctlkXj4dtpp%y!H$tlIq&c#iBLne*X%GuY>ERluFwcZAKhP!WNu
NB8G8Z cWPTk4\PHLu&&XMj#C=FLHCL6Q!tY=aYhJ1Qd%jTh@FKu1FeZ1XBh/=XPh/RKiRS:WA@WQ&NhKcaGp+9
#8$4:+ Bjtl9nWjeP\8cWP<a<C:41tK>du:dI9!4miGbC41SIX6*iiVXp:FyiR!^X?XMXy%%/G14CyYH>T#\dHS
>&ye^Z qAC+pbmNPV!TXC^iQZyLt!W?eP\PiDe##SE1EQ@VcF8D?KK@MuQa&MC9Ym^i//CcGB/FNukJ18BYt\9H
*yhZqL ^>VLLp@^L@*==I&8npi9u4\Lc/emuG=ZC4uyaBnM%<wwXD1wAtWu=E&D6@uwBB1/B4hYZb<TnCicC/nu
ujenGR &WhYPW\Tdu\1lA<TYej4BZGWWm5duYRuGLkWMIVhBHQFMmy=jA<tHZ?Z&hQ<uPCdun!##SW$aSEW:1Gy
K>D*CZ 9nhn>9$Xkw@8/SC#5=YBWVAPEPYIFTE=5Ejdb%Y:Dy\GKbA*/#5FDHR%%KSWE1X:!#Nd/:eLGXb*eII>
ny4#8W M6N%PGa^CIk=mu>:@6Bjy<a?5:MVMGJHbjwT:\je/WG4KMTN!eTBLkCE5#bXKAFt&R?+LNW66<Jpek>E
IFSJYK +\j#l^nh\K9qR&*uSS^/Ny?m^bXI!kS6#EAm:u=Sh>A5^deY>=I4ICGn#4/:!c>tXJ:!:u/Q1N98M@am
#<^ePb &dQXNbBiNQXQK?&=DPpqI4QHwad%@MJS<k<<<Q<jETQ@5Ij<X^kH:C<aB\#/&=+N&F?#C?ljhML@/YD=
hn*cRM ##NEWFDpd/kS9@I8REX?R\*@^hRuFBV%G&4aL!5Z@R$%>BhbGmka=DjW9!aA5H@4:$Ll@*q@>%>&ld@*
-Aic#M 000f81aba3a00110333 Page 420 of binaries1.zip
$Q5=tl h?GR9?n9\9/m9@9uT9m@\R9@e:\Lh9?Lkli!=9+Y9IBN?J6nkR*b:hnP&Hk9!XRWiR>uh&6m:GMMQM=n
:@6TTn T&wCN8&#Q>E+duXCDXR?NEGC&F\u1ae1M+Pw!Y+yC/JkqdH<T$*h9blJkFPKGDYwq%=VZjPWXIW8<l:P
y?5S&S 5p/#yIMpby:tta4T5Cj:u$<^YIPL1NRtkh%1KDX\?#/bAF\K*nDQj&p&Q<euLdGTZGB1Q#HNpWaiM?i1
>!l4QG d6CAb!qu4AFdj&8t8nA@cIZYyStmB1Z&Hit5L#b/L#W*NZ:^W^V<X\:DTFB8SHhh^N4$4h4Aw69+>Y#Q
FnpD4C i6Z^<dJ5Tij%IP4TC%?Dp/uX*AY!SLXi+^^Q5DjCBh>6N?RdM$#+LGH8T<P?J*:ERAZSm/bN8SN#nbL+
/5@$aX eZQdApXP/Xw6l!ywAqw:m*uN?Jc>X^PJk5HiMY!YGw6&96q:^S>Z89bT6jL6nIH4qdqbidL=PWy$P=K!
nIihmi =YpP\9/j1%XXpa:pN9EhkWddiS9Y9ZE^cPm<#ey^==!X=bVGw55XCVp9kcaTI%NqQQY6pA?BM5Vkmbk9
j59Ii> IdN/NcQG4lQ1#%+d/64Ni*RP1*J/LaE>YY#qqlpi%M>:%?w/V*pF^yl??LIkMTk>wiJ>^dCCGZ>qbhZ=
5:m%Ji !t%QViiTnH#A5$NkGd#?@LZX>@PJF#VPPaTn!^eytk<\?85ZS/41n*YdF^98#B*q6p#RY#tpqBPcSN>:
Z$pY?! ubh9EWqX=\cRN:/B!uqG>&J>A\</SBpJ!+n\tG@B!W=%tZj\h=muICy^V*B#4em#W8tlY1whM$mQCEjD
G\TyaB ^PtkmMDe#PK&jiWLHQnpq&58?IhTp=qCq:lEq5=i:X9/D8?qQu8^N>k>y5kB1pVGRdac:bKhXKB=/w1y
VeJQ$a 6M#Y%<C=C&$j!PajXTKHDTqqLM?t?KpB>apnY6lw1+%^m+G$::kyXlbkN=whed5c&^S!!/nQ%E8Dm#=H
eSajJj VCW8+YZP\tk>:KH?p&GEina%:5h\\8#&nEj^!a&Re!+8a!IX8=*?yL#\kL!Z4I*SWjbG9RT1DjPWdw/!
MX+JI6 a^?bml:\*6%j$qL!YR1#N!PlbdJIWVhQGEXLMcn5%RIQyPSLN$d=a:ZcMDa>JL\/dyTa/DYE\LXnjek&
\dd5iN DSlt+11anRLw&Q%lmuGVmup&iP>J*=^SbqXMJj/Wp1W&KjtdSc*Z1W1FLDSE>EEEAQhAEiZIp8<9:#Xb
\Hk>i? tY?lBQM6adh=d#JnF?\^\VG&dMRDcTRbPa!yECjedRwC!85ZVD^:\n5Z>Sq<P6DST%p:4t&idC4!SWX>
KVu&Md >>Kh&$#yw+^JbWX!eMbaWEGDqIummy=D1uy6<WBd&uT91dDNpBEB>+<qPFduW9<&hWEn:W8XnP?EY>M^
C&<!@Q uIeQeFp5#*d%/54SpDdHi#:N<GZ:NpV*$uI\elY5ba&%GSewiGA4Q*6LY6ZS#j!FjNQ=*R$<D^j!>d&/
N!&IR% ?#m*<j#w*d!B!LAF^<l^#iMW^:lYCdF/W\a:!*11:qwS:/1QE/Bu=aw*e#Nm<^dBLiaN#n4Kc6<R?8bW
a4BW*c L<$DlmPLDpC*K+DP%8SnH>GSq*hiJ@$Mq@WXp4wcFC>DR!N1kS@%?n@p4VH:6PHpjSVDYJQjT%pA%apy
>FTBK+ KBB9SL%WEYnVcTI&&ul@L%Wb&pL=pKem/j@D*q>+Sj*@::+\AnQW#ImWqIyI^#AMR+w/\NDh*VB$N!KT
dN$qnB R*hKTZh*1iVRuRI1*X$1w6/@*+=#u@*:jn#d6ji=:**YZ8eQiK#*?#*#tqnZhV&jX?Dni?DVlAPPp:1L
6y<LZT ^Fl:lHcMk?+bktVE!%H#q$hL9=1SZTQ>5tEVP<aH><QF\=:Nn#FI1DX6Y>>TWKL9?:\D>9SPAtMc4X=J
1QdEXG 6j9EAuR\M!\9<\CkwW&Gb>uHm>G6$TjKwbX:Y=?Dqe:MWKHJt6=Y@cFL^8N?nmPTL9Ka?I&kp9:lmQhG
lt\NHB ^j*Sh94PjjL9E4d\^iq+4%bd9amTMZ+>m&6%^hdF?\P$=tcJu!^Ml#n$9DRQ^?k?eZJL&ca<1k9jiK^N
WIR^i& bYR89JddLT*#<+ETtWqAY#A5/CPG/Yh:Lw91JM6?qLCNDpM?Sja#Dq?ajTN6Y9aXqWp@KpyNq:GpZtp/
4MW5bY FAqYLdp<?J#JJ^et1=H%Tb#Bewbe4bL&TJCjq1a/AbGtyLcSyAC&%BXIhu^y=K=CZdJhXKnZAtR@M4N*
M%WP=e 9!$w9cLNH:u=\KJnny&Y#TBj^#t&H+68F6@4*/!jN<uPBLXXF=jCY6MCCqVi:#cM!ETIk9hQcjtMLD8J
\W@NGI %J1dSbQACl9b>%Ju1^T9eni+Z1XMyTlJ$TdQ$uBQ4cHdt*q<TtjjH8@H:Z+IP@HSeW#l@FS\K>ZpiC$#
m*Hu?% tE>b91uEV8yWRn?15+j>FQXikI$Yt8%S#^HeeBNAI!wcWMHP9FJ5bZDRdCW!H<RnYBX+TCebmI1?pE\Z
$I#D$> GuwKJF$wu!<m%p$lyByyECuNwCjcJb=:S#QtS/#/m6C\k4QBW><k1$t?@5A845+YuLc$RP4n&Qmn8y4l
#JiPWP +BM@nw@?eLlIm&dJuS@Q9tP^yj^ZkuKqHX>W6dpDc^l@+&>XNaCASDqpNp1yu%Ji+AblAnW6R5+@#D$Z
Fq=Bdp pH/Gk>lEHNLcKH&j$$pZFPp#n89R$M8&t%mtyX\<uIaTje8?$!@iwS>B*5!Fa98p!up5i&l:$ZWtS+LN
n5bdM$ tMkPqlC!@6dKJPkHPi>+DX>^q&9Yji\VnQj<NhL+Vy=QR=^:$R4BNukWh?qTS<+WGq<y\iHPJTQWH:Aw
DT:<#a aR%tGMY@&#\k6j<4YCVCqpZRGdJ5/:en@/8WK\^u+CFw#$J!!#alRK<5aDwQHIyVnQX\Fpkula@FLPA^
<!jhVS e!&1mM?^*\Ncnn4aajB^e6?e\9ummIhah>8=p&6Ich*n&wW=W<XQ<H@d16&eT1XHVNdkDF5St\kyI*NJ
^E*:a! uJN1=C/hqLapyd\5E&N5QDN:qX:8thuiyjhT!QAjC+q%HBWcb+4dWHLGm!DaFwYEV%9Z#ly8!Z&ICaqq
4\QV/d 5SZtm8@jReiGTIBR8\W!>Xj+Y/AN$hj5>cw!Gl4&%Vc1?N:M1B:&&^+Vm==e/==hCS\TV+WheYId&wkD
ESPdqA dmJTc^TBWhWWq$@FIem1/b:eGbp$P!X!E&VX>#qC^&e:$y9R6<%mG&RZp5LYF$HWSpZ!dePiIyypk?4M
eJT!FW =F*%+e8nEEK5y!iLFY*<F9+>Z/EE@?ne<M=TZN9BHEHJTMLT>#c=t:Htl6VecpiHTXSYcQN:CnwJu!iH
Ct$SFR GI<HP5le5AKF1bekFyNmmCp*R$l%4B9T9uJ#ybAluLB5kcIQYT=Zc1?enEL&ZCnhZJT6GqaiH$>RiSdD
w1EeQF V8Pkt5S1d$%YDJY#9y+\uk@R9&Idac=wi:JupYL9:Tuy^/?acFmQ%lm=PXcVbtW/Z88#!LdpW8yDV$#k
9eql?a u?&k^yS8w?6FNNVp6B%u>iK+WmCmjQ&1#BBM=X%WmEQQ=ca$Lu8+Dh6\Hy/G@yVB\MEIRin:pmG6V!!h
RFaXWw !n!RNY=pIWMjyKlay&cET?*eABAI&H4jDS<NeJnY^+j1K1?tFiY1>/EFL/m$YiP+!Rda8Qh+Gl:Bpb<a
HJw\?B Zh:A%Yt>&Z=CYjKZV<S:GW^JyBE4C5@=PEDuAKnK$i4MDmnRGW+EP9*IVE/:L%A84?hkji6atK5Z<+I:
R^K$h@ At$>X9w&SmX>/LJ5PCDh=nM?8SuRXpAHkFww5MlRDCMN:d&@j!amhTTp#qF1w%Nc4m*A^LK4YMQ8ML*e
+p*F9J c@P+4BtAW*^IbC5WGa%Q69&!::XkdZWqE:F<FXNq46NnBYTeBX!AX<&epDR6X$%\Y&/b+KGAW!kuDqK%
ePlQ9m *ET51BCTVF?LYj1*J\+Atm\m9+m=yyaVtXpXtCWPBMmS9yY\XNl!LDX$B/I9wcmhc=hLa8hawj%KFjZ\
t9F+cM <*ntLA9yPDFYltPYSRNHjK@\Y%5%D^q*HmwNw@yGHwtTwHYLC#qC$np8J+V!LY<6WLEj+w==KaP\:+l:
SAnjWh k/LRFN@YFN?#S^C84A*QPm1RRh#>?N*hG!c1NVSp=WccP>E&$ydhMlRRkWy!1h\hyhWii?k#yaFCGa!/
P6IETn RnJ6qVlLaYPWyB&8:m\!dNNPntLh9GmJ$F!hnC^/YIP6l9WejDu9WQQnlRR:aw\FicEGIBb*JKNH+YAI
M=#ZeD yh\$8>ReeeTWNY*:i/MV8$LqC\<6!y@ZWIcm&H4eMWX*mE?qLJCwtBBt6!Z#ApQhZm*?<BH6MDTCM9%%
9*Fq:Z ?WihQXhImLIi&8TNJt$iY%am1+Y5HXcC*X!jEBbI&KkiJ4P1:P+ieI1Qk:GRyZdH/P1QEN&lXPc5Gunl
TE@G9A yEVaNb\%G\BC>5K5Q*EFG^V!C*Yd^GkFI<6q5nDld@tc#y+%QIVkVAqy\Quu4L9h^PB1K#HNk5c^1\b8
\c&V/4 D:Fah?NRX5*hEVP&u&aB18kRa:Mlye+GaStC>>$lQPSTAQIRa5/?n\\FhJy!\<Dil?+M=TtSTkcePt4:
w<*STT AYt4?+XHGjP=\>t4=?ZB4$W+=PdA6pLE<p?=/6W8ky<VT\yMB#pNB=Tb1\\%bQJ:5M!FQT!iWBt//M1!
wA/iM8 lM+\4Jt/XMeM+wBYS$V/*au+#ICcI8n#?aw^Ka&L%u:MdhbtnL*djnSQEkPac11iMAS?F=He*EhG4*dN
?Jjh*! KPpyyR#>>Y1:QyI*$XNDwRbjd+lX&1P/DwTDJPIeeZtmwDT<t?%EH!\D>L\Z^ZE%:Vp@@6K>A9\p@GdD
9l<#?6 Z!A6IK=cKMnpe/A/bNFKwYplw?b?AN6WnT@?Mjd5D6GAyY?I?G8qE<GTR?Y//qh&*#aYMp&++JZP8D&N
MDy^&F PH\56XZdZ%Z4DHdqpd=MpR$XTlcPhHeL\\*LF%6QW:V^4K*1Yw6dKZXCA6\hu\Y!>H5yPGbPPjHI*cAZ
IpY<L$ ZkKPIRKaTTeTm*1:!mwYZnMtH1&RuhD:\+*wA@WEIqy59+XqqLa1H8\d<dKN9abW5&jlnn\Skw<X6>d8
Yn:$Q$ nk548cK=Sm&?jju\nc$5T%P48B&%4#*Z9G1by\XF=T5lByqYJmiK<e%9<e:yyLyC%E/AP4>mKEyRT9!d
Qn%p+4 macPNW4I@16Y5I#dK^j9h1h6=?$!*ReiLnGeImA:m4NF^y11k@C:pnb!jhPX!QtGwFP=nI@qFtW#YPi9
E/1eLM FGwZe<V1Ta/a@i!>tBD:yRI?$WY6*hIGk+:InHw=@<=!/9tG%wBC=FJA4@u+<^^lAGqpJQ=>y8XI8TXh
$V8%RK &=8!M8jKRy&QRmX!Y9NqtKZRVBNIlPd>#W96A#Y$1LMhVwQWcYNjAKNWZZSL1&WJRV\ui9MKKENhC>Ey
*GF*N+ 4Gp6Vc\pI?Re41ZG#LT&Bh9wiM*V/:KSBkEhAynJ1k5QGVY4:piD16p*54b@%ipem>W+$Z+#<L:Z$?%K
ZqZe@5 4?V&&j6iXLS*%u8iyK^KiZ<\a>KR$PYS@!iGXRl^+NNRaV!mD+=5w+Xq*=>GBuS#?\hXdJBGSPiQ@PS\
&i4QZM eZ^h/NmR6HtZY=Zkjpb$&?^+\%%ZkQL#:h*F@thCq=>L!De4/6Lu!F5LR/FLmltq^F:W>*E<$@AN9IlE
Dai\be quKctl5#8jqieQiaLt^ZLkt=jC>iqVCMw5c+6nTc5>nZ/ldYXFVFDY%EF^W:$bIVc?ZYXPA4ChE*q8t?
KS@w/? JdpdXw&HX?udXCEX%h1AaytJ%@%e#WwY#L@+KuR=e4FVIL$886m?jau:dmQZ=k@PpNdyh?ZLuA:h@4!T
&$1SY8 tq:mjA#d1=l/@u:M#e+1wHmQ@wta8!YK&BFp*ck1q9#S+*/nBBNWbR8%WYmLP5%jC?&JKLDikKi&Pn=e
?BuWqa 4@&ikShDZiwiE==A>TQ:/e8MSIjL4YYG5nmddMhASX8S%<Y/8h6/nDI9RXib:buJ4mT^Ap#Z1S*dt?Bt
-AW#bb 000e0b1a05700110333 Page 421 of binaries1.zip
calBhJ A/:M%6CpS6dX=IY%F^NK&%6!u*uJcnH8ql*^RXCV>%CJD?N?R+1ZP=\@De6bNk%a<PteAZRi#=a=!1ML
?W9:+P Ym8M986@5+m=it?C#JcTd8%Z\FDnhlJ6V>A@*Fwl^chdIE6$$Yy^$1a*:QE#&AJ@HZ^=Bap>/6:&=S@+
J4Zidu yGhVI@:Tnupl@<nl1IBR:nJcTDFM@LwI+KY@yIJEk6Z/jPJDhWR:nW!R9!c$+nc*LR!tj!Kuj&5N/y?<
Z8&>uW mmYcV&+bXqE8@R:enYW!$5bDDbi&G4p1ja@Le/!*%/#yNHd@$d\!=^ScNkZ6=k<6NinZh+:SAIZ8qEnm
mLb49$ P=n:E?*N@?#e%VDpt<mtHAC+@*/V=nbQIK?5FMw?IGW%yjtSVc^P!:BpQuQW\qNG!EXC>NhP%!89AKjk
<>XZk$ %==&ui+@jVP54ANdqqB5L=8LP4^ecQ!5XDVeYj^Lm4\JKV4Q5uTG=wPnJJi56yciH94JBES6:$K5F<VC
D?#G@6 4F?=MI%LY%l1n$IWBnHEyh<Fi:wX&kjaAB>N6u$C4HwB>#@/kQ%FB6&pIbhucn4Fw$&6ZCtn<++h9HXY
ajqWnR n/1$k>\^hYE98i516GYWRpNaHNcaa4IV?\hK@G8wS$I+9<k<bG8j//y@KiD!uIyjCXT>P?IFKF54$DIZ
K69%yW Hum4&LI^yL6PjJZ:tdQdt<<q@c1WJT4kS6tN+!!T>iGZ#qLi#5yyN@t8w9k4NbFDn4t^8Enq/TBq=n5n
Dw$pnp 9Vc#YdeGw$wcqa9:p8+@%XkuuEAd>J*k8/M@#!DjLPPFJM$E+nmQQS/$HRje4C^>D:cbiN/1a6S=8>IQ
kF!!R? DG&aLNLV:F^Wp#wapT\q?I4wCRGVH#%eicyXtY8VIMG*9bl$KujY<cPm?>l#c?\1m&*a<aNaLL&@N>*J
u^yc\Y ^+lTXBcXS4YB!*Q%%8?jP1M\t<btM*I*%m#1l9c1>S=&k%KInCDthkLy>?*5XJ5ZZjRWt!>*c:n&LV8n
uTR^?6 Vn$<M&LjQe5Xi!@bB>/&u1V\Ij1S%?9eGWmVa8$q!QCcd#?^5=jV?*L9aZkbP$\tm5#R:^&4>5\bFZkh
5K+Gt: ^+EmTp4CBStAhR1M^ymFW=CBuAPnVdDp:mC$AAY6tjph5XSYwHA+BBQib>*nH61L\p&Iu%S^T+qpFF<5
ZNPBY! >Bhu+?%buSy1>P=lV/h:Rp=$mlZ%DS$w^A6@>9Db@W!R!VbjMnVLJ/IZ*iBY!EEE=y99y@StFkuGn>M&
VABN#I tddNeu\1pmnDMtt#kqS%yJ:n$K/VDKJt!%e?8ZlK9$Tu%$eM/EueW$pGA?:J9YH:^+4%@&\h@K<d/?D:
@FSWL? H:W<EQB@6V\R9H>6iTBk@&l=<Q&D=eH*%=aHu<Dj$H<w&SDmE@\Lt9>Q/=4+lQ/C=pQ</h4Cj$H@&dSA
?6DK#C \Q/nceH*F/aF*@@b6PD@y%A/k9ejVA5EnP>@u:KJ%Q<h!!biqK?Y+TBXtJ#@9Y\mmlJ#B*ua*S@MJhiK
?WJn:\ n=e@*Rwt<X$9:*eiXPiKl9pJCkL\lui+R9BE%haB>&VM/AEkDZP11ytXC>=RQET@KPSCRRIkEcZS\h>j
BF*Ehe ENDDP!Ylw>aMimI$@L:/nwZYwAKCcdkX^EiJV!1il#^AVkT#IStl>wZX%CPM/WlEu!u1A>ZpBhPa6q1W
8FTGAM S5M#=cl*D!DehnHBikBK^DhT<Y8L+%biLdM64ypEl^L^jlh4>Z>9uKmpkTYtl>hWel^<1$XYeBPa^=LI
Rm91Jn M:RBKwPP&@9E:L>LaHlNby+BQidWqZWDeZ@+j/^jXTWAB?KQkFT>bl5y=qyTupVyDM=>CRHJ!!$KGEYH
1SH=RS 5LY9uypahNjmb5!</9eGZ#^H%Xue>ykJ5Kt%d>6XGZNY!Xh4S8BVGqHGX:W=9A8*QLQnnkB?%FGl&8mY
NWKZ@L E1G1T8qqX#jlq&Lk*\$iJ^LSSMkhlQZlKdLZ#jG@q#e!%REKWtui^/HkAGkn#htHmeeG/#:%b4HSKMd:
pWl9&b !qA+/+&y^@c/ySKLkK?4bQ9qPci@DhXT!8#\w9Akb5QKM=5wGku#NQ4ttRYY8NEL6$N6tCcm=I:p/nPq
K+p#6P JqIQZwWG%NZQnI>>9Et+Y&wAIeIhA&e@4k$8!Zhd$aQk!/a1Qp@D#c$ZIR??1alK9lTjT+M:L+PcwCV8
naQJhq TBH9hFBLl8?uThWh?ie6n=$e>a5t1#/yKSC\!4X#uhqN9SKAS%HpD=ti=Gq^F&1Nk8lEZPN&Y\q\SuD$
=?=S/S !68M8RBC5M*Sc6JFK\&Hb@bh1<NN/9pW8nAFC1:GB8B1L!/W&EEe:upeJb:QCa<H6ce>!awTj!K1!%Z/
y\SiK1 Lu>SpIl18BRF?GV^wb@FbE*pk^yyaDMdt:Z=+++=dj8^+Z^AM$*1wZkRt+NSw/bT!?kWwd<MjtYL=:jA
*lPKd1 PdYQwL^$pY/NNYK#HpQ%41b5+eI^Tk4eEJ*adCCLhWDiHZ^Q/J&6K/SPhWPkiIVPcTInT*FZH$W!/T6d
9$>l#4 R>K!pnuG^:iGmmRQjpqh8j=t+N#Z6#*T4$l9H%yPEPQyD@n\XuQ<b@^nbTjP&9km!W<kW#?<WJh:+QI6
HF<cG+ =:hj!J$%wc?G/\l^MVMhh<S*Hd#4N?WM%SQyZ1p@pC^KA@DumLtceI&%+6?Q4%Xbte&WdBT8AMl5*#M^
T9mkSt ^d@nVCFjVLcZ@QRPBGejL!nA1J?%LmcB4Rw<YQn>STAK/naVSDdST*%cVFKiaC9841mH><!c\TqE^l/K
SXSSWW ?\b1MYXtcZ^u1lXLphkcc:9FT9cPLbnInt9aSjp%<!WNnHIZyP+u+=\<lB#wE!ep??l9XqR&?R=tlan*
5Wh/nR :XG^4yjEa@w&?\kA+Jq=:DmN^T$41#<4miS1=4w9^9S=?b:HYqd*>AaBI9pbh*aq8%@:VT+lS$PicpwK
L\4dIL %*^G:iyiiS:QKQBP/W$^IY$t:e9V><c=:Xa1\WW!=tw@$a!c5Vhq9p!tanHtGqb^Y4ayMN&t!&dkD^Bw
B9&nWk B5i6ct+Y1+q+\YQ:*eGcnV&Si=qeQDC4^=>:Zwi8MKh>+w\8hTw96tTAEyaiwP*lAacIYN^mJ8Wu1yR!
Bl^SID 8Hl%i\4w8?Nn$T1p?MMk86+<nEWI8JT%!<JmZ@Rd$KTYFH>YK+yGw^>FQAb?F&bEQVuHy\6N*icIL*Ga
+bGCDS QD?V5EuyLmuGZ#$JQT#8q6y:MZj>kKTnGL#d65qq^?qj!#mKp1\XBqJY1N?#*JaZ=Kd/6H*Q&#n$adS:
9VHy:C c6IHEa&P1pq8IF46l<:5h/h8!SEF!4yAL9ij611&SMy4*Mt+Aa*q+4LB<QRlm*4Z&*ViIX9d4dHK>W9h
G!LK8+ X%ZQqQw4H\<b?t+*YHAu9^jA=FaP9$KWd?uY&I%QdqatE*JF$9WHVnB4cH#LQmDQF=PyFY=neA!KLk1S
dppV&R =\>nVM%+p*T8lJJ5#Sn@!LT5WL4QH&*%FdK$PK/dT*LHuEXFNA^\N#$/R:h&@J%j*iXwXk+q5DdmDJuZ
$9m+H6 /hh6w1P86P6+V*N>6qACYkC+$$*R$>w+G%\bwk*wXqhpy\Cby4MdYciwIN<>$quICkEN:VhbMKl15*5&
Et#86u SdTMCce>RNjVDmhP<?!B$#:?mC%@&L<AKe8YDK@KVubeu49=Cc>=>9aiQZ?F+@^\<9%*pB#DH1:c=en%
q&Jc:> &mcK%TT6Pa9V1!8D\=@MiQ@&miZ1D#k^pJjm$DTc#YK<QBENw$A@YF!<e5j1qAAQ$5+n*@Fnq<wLkBa<
yFptCK IWY/@Nqa^uRuL:\eQEncVKmw=#&>J\*BHC%FE?898kkFK@1ty!kNE1BcW#ZKn/Nymiiq6M:5/V+%eHYQ
+Ba<Y6 HV^ZWZtaA!c\GIcSt8eaqS9$yP@#$F\@ZcJwYDEqd*Hmiiu!19mt1Me9\J+k/VE/9>MauI4SKRqShSh:
qD5k6B BT4aT$jVyH4=5!>4PA\jh$yXuAm*PK+&/d=/QA1:*JG//Sm\>NaN=DPlDNPtRwPh#y>#m1SF@:kEti%Y
4NENeH NHm/S:?k^T9l4:y/iY?Jl:BlyT+Jju@+R?Y+^>P4A%I@ZXju4/\E\Z6NR!$yBVnn<hmL#LAZ#q=FJLZ$
5HJu5J yG5:@V?@GWupe4=q?@4t9e4%4VBTFWy#qcLe>i:yi4u4kZQ+C%aYu=!b6!c\uS89GIH4*<y=N<!jVuq1
SXPHIm 9XcVq#@h96mP+qIbk9li!^?deGWW^E*:XL#@Wa$@nd9+8/S+Y=wGJ@aRVkk<aR%/X^c>Bt1&LuW59#54
yK#+te $W@>nk8W6/etbGKSEtChM4A>YbkQ6LF>#bC+EBiWP#c5eGJYL&hWJpWK/>Q=BLy^CNB4BC9N=c>DTB*u
WaAMbH XK\%J\nq8ctkMG5RC&Gu?PJh:9CN$diE^JPtKwp4+J\yYNBTu#:ltMceJJehR#>l%#CIaZ=te^jD$RDe
9!SbQQ MkSLAFFQKHn^kIF+DKDVby*V/tu::h!?#kW=m6BVL^Lq@aJ@P/wM4kaD&:5Him#n!cbwmD$B6lk%jMJ6
p$t$+# bLWyCAEmmHQ%mHlSe*5j!WPV5du:+YFL4ETuSynuwNy+yRNm8MW+ei+KtQtdK+PcCYbXD>yaL+W85T:*
/Je=qS 5mEp14MpbW/mQ84^mVtG&p#uD8G8+M8=BTAJiWYlPI1$Y=$wMKbaXcMZG8:aP%1EK@XyXRawSTll%knE
Y1<u8# a:GD5Zk^!HVakl?+VE8YQQjpFNi4TLiYNkw?1k&ZaACyMF/VQqew$qM1HN*51!>l5/MKD+iC6>jRCM^w
Ii?ahi cqV5BF&Jpe+kBYa4TDupwVFweMuTGbw:^tT&n4bd\1#&RMA/Q?CKV\4F*jAdtQ1P8WQpbnD=wWPFA*A8
:NwZ*m &+RY*BGJl!eGu?V%Lp5HW?KW>y^CIC4mQ?JknmVWc!T4%&E$:Ae9chaZ4&N%d5h*iRaTd*n1C+J$6BuY
W8ntQC %a?j*RWp+XeL+wb^+#M59YMBkW<ml*E?j!+GZWhNd$CGD=T<mKNtk=kVhcB/9=%?RAF1u?8*<%G>uG=k
eR:9Sl 68CdF\etak/jqdAW<4ciSpPZcBmKY/HX1MnhPCIWd*9JXP=$uqueGV%wY+S4^#J9B?/B*4Q+4QIhQ9KW
QIql84 n#mJ*?GRb%VGiw!FP>^AKTD+d1tSR*??lhILkWIlcFE1HGjclwXPABN8#6yn*j@LFKW5\N#GP1NWHc1G
hDNFjZ /h8%&9^P*mhIeR>F^DKHTCCd6ACt!y5Wnu$&bp/Z6\wwSV%+nq>9c:a164P$9jZ>ca#!e!#b%81$!Zc>
GuaTNb KnhDLaVNKHKPMESAiWBl:yJ?<JS1jyh$>6k=VwpN8qhINJWFAQ44BkRNXdPy\HP%iT$<PX^XNCmG$Qeq
yNp4tZ VXb$*ctQR><m\h6=Gk<D*Y$k%RBC1?yAd1$X@C8C$\5p!=wpl=ia%cY#Y*pFp@I#HmqPXFaS+Smb6Xw+
&?F?1I R/<pd+::wNy\FaQ:=HRnt@%ZZtnE4J>G&j+4nR1Fm*c@jaQpWDW>bp^P!T@ipN$a!eiK!d54#A<#CekT
tNe\1y A=D#q>ewqqb6q%9qZRPNi/ILdN1KYIapmqeKmE8F!&qq+p*6MRNNByp%QKa?6ZbwbbaJ:/L:%Ej%PHFH
t<Q85@ P^&8wZjpXdZ+@Y/1VH4ELt1tMtwJBMXiuL\cVDyA\t$4Vb^K5>XRNpZ6Qn%4/i6\69bkT$N+!Jp<^ZqC
b?hEjE 1TcjXe+$cnT1EaWPD\J%>TwBQpPBIXHdDIVPXEuDJe\BI:w#ISH<@64M/^hBH?tKAEwi<5@Et\CD\<>L
a$eyL9 LpnNGZVhR#/AH=BMp>P1ElHd&15mWtReWwA:5*aBF!DyCyBKN>Fy>j#^PhyT#E#^eD:i@tQ==5jRdcW1
AlWpRC VWpadQa$EBmcZ#&&SS4n9\QY9EhJb<:+<+WFMkMhR/SKbEGcS^4#q5Db^lk%QmhVc$>P::?#L+ewj5*9
+LKpY^ G<1j>V1<QTSqTLi@RYZjQw&TE4$qIqGwwlK?L6pWyP>lyw5+:HEh#d<eVENn+kYT:JZtXQh\6i%@nc?9
-A@nG9 0005694832b00110333 Page 422 of binaries1.zip
9?DuNV XkVnbIh/Jq5ja$9XRFhwqZAbJYKPKMTy9phA5ewdc!am66+j:I#LQA1$/<mqnbwl@LkdDVau*IPjTN+Y
N*@\pY +84jPFE@TK\W8y%JPDi@jckPya5+\/>=J*aT/l4S&Bc\jS&%&q:&%c&M:dhV/=ZTW!nbqh8E&p<a+RnH
\=ucJ\ Gp=W/<J$m<JkQkm?A^9EdMeN*5cGPmhkt$pMZ9PHG%p<%C#CdY\R4Xb>\>i*Cei>$eDy>h%*$CiM<L9@
mmp!!5 \R:%%K>\\:lBXPu$K&ucdGYXqpLnnXYluncb!$9tIGnlJdS1Y#pe%\nNy!iQSK6R^X4tkJD:Kq?:Z/tp
d/Z1MH j=Y8N>^+:F6HdCjaa#a$#&Nm=dj:mG9P4BR=:I1$l6565$WL?dhAQ1%m^+mTwa=Wbe/%wWjdG^\lXcM/
TF>G*& jyGYwhGya>GZ==HFE&G$a>:t^pIG8yZ9^?M\HmZ9&hcZI?/?\=AwVRR^&dM<dMA@j+Yep*EYej*tP>n@
duQy/d 8XIHDcBADh4u+AP+bWMwBWCn^aPHjdLA>enV6@LKEeS=pa#d!lE1BWPckCi*@MnTqI$jbFVll1XVRB6m
CQ?T4H XhYW?!MmMLAnHHD8\56^HG8pc$@6A/c:#!Ik#>FGNJCR<HXH1?AP$kEHHDAV9auWuE^I\9IJnXK5$LAu
p&Y<eD YGywaC6T9w8KHeEHYqiJlHpVtS*BH*py^?Lw>9^#ABV^!X?T144V5R\kdaI+PcSBAt&l%R/buIy@Aw5^
nAnkJi +:/6X?i^m\W<+GPkR/%S$5WdFFINa%>8eyCF9b>JRDm#lTSW#EDJGI9%:bdLcKtE!LQaZ&XL$cSdtiHn
eE8kJm jM\5FwC@WbVqVDiPeZ9l\Yc!\b+h\qbmyYPDL/ICR/Awp=e6L6%T?ZNGunICGP!H46=Y5eCBTqdIBnj8
TttybM cEm#lX9jW>tYLPA%^ptX/VZDd1aMt$RJ9kbBPJ!\NqCK\WZhE/nbm1*E<\lh%&q*kQRV?pu/JTZw9TZk
Rm:Lja #YeTK\5F\nN<5>hZIX>nRwKy4+GQT=^FJZNQTk9Q$a!LF*l55ilX<\JmH&Kl>%GeXLG+!nMteN<mN%yi
Z?ja$t 1uk@yR#d6:T8:@VeJWy4kXdkp8>6NRwpFTpd56<4pjmbwbKWTn+<EkD<EVleXW$4&GIVS5TwX5ctDp8*
pQnHi6 4?^R8CbMtMMuPMIJ>DDWBS945KpVAX+4&bC?D16hHCIhye#T6*/VLakjEZtYQ5CujI^RI@%a==W4=*G5
6h\*^? :SG58<!mVKn8GK&qSJpMyhl^Rk#=D$4!>K*1Y*>N:1>V%GN!H\!8u%%Z$ZjHq8Et5?1y/l6FZA&4!uR$
T:>Ftm a/KVpG6K%6h^hN:lyYe6P:Qbp9WJhIe=Xh9R=nZ/8+hNdjmeDDb6kBZjAZWPX1NZ^/9%utlQlX@PV4^K
bT\>ut \pIi^%ujJhnAXhiPyK9ca<&?E%\Hw^tM$5>L!cZ<LFTmmA4>%P!QuSe#tWaqIXuijTwu$dpHHNk#/YAb
*SHL/G hXHjFZHJ55:FyV6wY?yAQ/Pd/YFhWi@\HiQw4TT*pIcB^AESC?VA&HT9Qw*e$>lQ/=N%&whJjRJ1jZ^1
&H5IjN VcGBt<kq*jDZqk#cN9#/$6<m$9Ci^\InND@1TIDkEe\hk=&YaX>6luAmh?9%LXdnkIRcqLHc8:Mt5#Bq
=jc:Fk 19wE!yeX%yHJFcK1cuyyuZ9nlp@cR!uCEhtAhnQDqEQD8jCZw:>jeEQ*GeVMRn@ZTV#Yi+ijkS^B#=$Y
KjGlWD h!$Aa#SNMppWHN=aHtYhF<jEH#A64P/D8pcVG$1p5^>L^?jdyhbI^:\quF#BRNkl8wNHA<Dy\9XZ8t@M
^<:pCG b\NYTI>@S?Y5AEC=<>#Lp+EEL/NV/YmdeS^th/hIQV?HmkKlV:@a>SNNYTXqWdJQqY4Fy$Vwy!+X8>>$
c5u?my 1kW?6^1>cT1EW1CWmjnun\NX\=%5upc$LC/lI+kt^^q+il?4#9F5E6\EEF6$D#ZwG^!dhI/cQmNwILwZ
D5ReEm 9E&c6uL8pWaIJI8^VmMNEA*Sjb4=PuG5jw#!n8X=aBE%GPh<=8BND5$WyElSRj#n*n/&cM:8Rb?IRnE8
8&:t%C tGEF:NuQ>4A54Cn%bTn?6F*/@HeP$*9PEp&JT4<Ca5M$M9VuVaF<^E$@lC^ERL?&#b:H1IjR:YTQHjXh
e&m#=< qaSCwM%ENJ6uJ<!:Jt!GIb&h9b@pnS\?E*K#/GYGeG6N#@=5%6bRqkqRdTI?JtT4Y>ekY/Hkn$uIMMNb
X$/D6@ XP>@i<VS<QEphaXCT+?:+w::XNw+&<8LhI*?u#InI5XMDSiMt!wch=BSn@cHG!=iGZ>@FHGBX1:wE#9Z
bNKP?k iEKw4kyy%NKtEV/tbnB>JHkyADPqaDQnkTehP<&/Sy$hjTJ#jHP4hL<V%hNqekJXI9%PdE>$$+yNAh>:
iGN\%& I9Ku#W+I?Q>TC\D^Q>yW\j<QW\@<j#@%\Q@QW\?Ij>kilPD:Y\5A\j<*>J<5AIVAZ>D<jH?/68Bj$Ik@
p$ZIe@ #T$klQ/C@8QWA$L+L?k@G\n<5L>=eLnRH?l@tbqA@Qj:H9/QMau@bD<I\Q@Bj8D@^=tJ@*u:+j?htjnH
w@M%C6 tRu:@#@NVFm$N!NXtEBZ@#+#\VA$616H*TR^wpanXV8w<4qNMX/NH9YpR@l=#B4PuqlV4<L/dFP9jyIw
RP&uE@ ^HuEuAKn/L\u?&>@XZ<mqYc!VpuXFYiNuk1ayq8SNmipt!MF*HGPJIG<a@4M@Ake5ThVKSKmC=A1?bnu
:/wd<R @L&pcyMCW=wCFIKK#^+w/=KPmJpm<M!h#EMw5\MwRC/mb$?BjF%4L$L^mp#96@IQIwYnuWhQ^=WeNNH#
ka@*QW RQX?>F4d?H<#JFFZwe+\lG!K9meIc6VkpT>FnJl<FJk=apiF\6+>$X#R1I4@QP&6ed*biF@ll>q+VI4G
HjQ6R6 l9p<8ccN?EYDaWS#$+mH8WYc?^QT/A&w$K#+S6WV#Qa>F6/MQ1H4%:Ln&y<!Z@GVb$Gj@69*=an?np9Y
Cn@#P+ V64Gpn\THped4mIEcteS@dn\#S?%AGy99Lp98@Cj!li$eDJZuiq^d48=Bm5M>9m/^wAV6PS&<wNNB&L9
>X8#>j >>\BQJum%<p@HQqXj#\nniD4FBiP&dC#Cl&pDDca%%qbXI*1R#^R?5R@^<JJGy9AFJY81jIBBV9:?NKG
tY$:1c dm@41ujGuN9Lie:bAKc/NB>wD/XcwcLWuR8=4@VG4GpF<&H81l=ujHQ&:KpGdQu$k<<WSCQPiLtZY@Pn
*%5RG/ +<TLB@5lnu#PJ\bMLcDAhPi$J?1pLRlQ?Tp$:6a/cHI+RFX&hIMHV?P4a1tVLYHkqHCJ%q9Ky%H8Nuh?
18ZWyN 5/8wnZ!!blAPh/ikD>uGMG#AjJB=i=!iqcGjIp1Xc=EW###qSl>RePu#yJLSypP8Hp^9?ZN<YljjCjnb
#?DElF t>V8Z!u<DVQNSLh<$!#H?jH/Lbd+k<1>JMYa4W>6=tl:#iCQE1#W1+@V@K^Wjj*W>$5Z?:&p1W^6*=8j
/L?Z%d =DW@d#1&m8hI+V*+&TFN#pqJZ<uDdQ?ekI=!%TYX9N:$kQJ?lXetJKqZ^Wa%R%^MAPGaG&&hRA^E5Hq^
^a1L1> EiLi!%al#E:t**6MP@8>phkqk4an=NZntQ^k=Z9=>?q6NE/Z#4QN=Q$YY*iWLtIScN9lSYG5nT^V+Zyy
Yu%cVS VD?9eNDY=ReTC*iF4p<IGG1?i%J6$XCl*=!:9:Q%aTqekMeR#X$W*#KLt/FqPplK+IG>Lb/BGFdZ8$D^
?i8C1c $/$W\>WBdP?EPEqXq8<pq1D9MMJa6^SPDGtHEPVbFi!C+&My6X+i&H/nJl@Vb!q1#VaIBkypP:5\Z8Fu
Dc/H:q :X1ZM/XRFwhH\V^/\>5$NhT&Dc!Al/H!CZdN8?p4BYW^VIy#PQecq^G/GR^/KtTIEu/qCNDF^\BuF+#!
m@m>?B t>plR^!+?A++l6<m$Z:J*WwI$?:+kydqdZp$K+1VTDmV^9J=@mX=Kj6&*i\d@F\PkFV=qSm$qF^STEt?
#GT>DD T+P!H@%tI$a4p6?>CwamFhP=a%ni:\DmyKBlI==*NSZLLuQXybVTJ=$^&h!5CLES#TneBB%/1EKeNYly
m18Q<8 4h6$:LPNlFKk6T$*HSaR9nZEyNVeKM5ZeuYE!y5biPcd?B%8<4P/=ISETk:Q^LI6Y!q<5w?$aSIBZ\+N
p8Q1\I 4PNKMRcKKCN1S:8dyIb1NRPc8$=QaG=9kcZN!wVlPZlk4CAd8m>wIdY\F>^dw+ubRIY>+hH^K%TDd+X>
##9QB1 ctF#%jX&mweLN<wIW<\9?uXp^?1h#6Mc@GAQVEL!CXG4C=Y&jPdnFV<el$A#<6jH%CKFF9Y//bPm/jBM
J&@m$> jNB*&uMqP8YhalX%!p!LlJXTRNee##ucWy@q$bcI/d6$B9Y\jCSb/+QTPle@!mylcVRH?ZB^6lX*yGhS
\MwKyR /Ft!^6WtM@XAZN>1TY<IM5/V>$+wE::*XXbLIHTB6AHYMFqb%4dBXFmeIE!Gb&Jmk<K5PjYDXyNWa9Mb
yb*w\M &inuM<nSIdSeJRYG*ci+!M#\CPe&>*8D=KFWaJ8>QP&a^4iG@WMK:hWG^KYttc8Am\IjADlY!PaGEutk
Z<d54Y KcM>PF%P/?$e?Xb=ptVG:>:LYKjSb=8MVat:9Su9^G>+Z#BiX#4%91teI*+iX5P?VW#GbFA#%M6S$16b
+GhLEA bk&5CI>#QANTQkm+N>T%wNBj^Ie#l?Nc!/cn+T?wn$<eYP#A&>%&*n+4++DEhV<9!iShcQm/EYMNFAbR
i1b:kc <N?9Vu8ZG%Q5Mly6DG4\Y^?m\LNZwZZN\RZ9QZdFGCHE/8@W=c:RuQq4nu#p<^ijuP^>FEiei+iJqN@K
!@wTAI hc!Z\VEwh+Vcqik19aF^86*i=pNh/NN$11yIjkK/NQPHpQ$NP/j$kGGlaJu6LpF>D$XyVp>twF\Hk\pD
G>DnM$ /PyP!cEEG98G$X8\>ANhk@YL?W6Jid+$$jGM:hh1!*m&C!MRHTtn&c*9C!bLa<4q6BG&9X@!!5S@L4R*
p<McGi a=pe!AQ4uG+9*8uRd=bMPbReX$11X#$^Z?+tmKmQayp>SCLJ^PWVR:n+Z8hjF*?i!R^d*Ghd@I=XZPa4
@q@K!? :DQtQQIj4S49cllX@lTw&F<KI8/X+L!jq8cd/@YTuNDpa8T<:C6hq1X#aR@*N@M#$:q*Zm>TQ&dh&B?i
8E#wmQ %d#*dP:V!d>9=Yi?91CyHMd5h6iP/<ZKy$Mn:LPDT1&tS%IHVc=LMY/D@DKj^A&*\$ewC^@9i@qK<4M+
=L<^W5 YtM<j^RQjuekFiB^#>p1Hw<b=c&pm8lqK^+5JXSaRwBkQ=X!?4uY%e58RRHVt!Ne@XC64c4Q6<ihLkZT
Z?w5*V 8NY=DW^R@mm1V/h18wW*P?Zyc1MtI/Q4c/NIMNj/=?E8e+Ze\eQBab#=eca$ACq5S=\FQM=SHl#Pj>m+
YMQ>>R XuW:*K<EmueEBi!9RV!XHZpJ^<mJCFP:kh9FE&bI:Pt4ETAtJD!bt?$hY/J8kaFQ4$cRJMk4t6nQki$q
WTnt\$ /mjARewJ$?p8h\alMmpJVXVB&abaiaBLQP=PEKNJq##G1QD^ZEQD=RVCCn$h8u\JyN+Cuu@uak!$&@&l
9ueeI^ #JWJui>lXeGWGyP^t?M:IT$KM<\JPIb#c:5t*+>Z^^e:a@imdC8q>MSKYcy1FEDXHjjLW/Y&$1&XX*Vn
dN%teP /L*LDu?FKq$tJF>Mw4<+nk5wn*<=\NujNmcQPD!<q?Y:yW#Nk9ce>K6P!IJA5Gb*8Sy41P#/JGttE16C
9PaQRZ JPmA#&8B1CnJ>L5M1!:&@wNSuBV+Sle!dVVnZjk+1?h^EH?=JZ!eQqDhjuYSD!&/lM1b!nEic<T>PDF^
@5IZHj Y&d6X%@P+WhwHS4?kIJkA/K!G:Rn=XN:S6dQjW?N#D5MXX/m6EL5GeJ=cWDRJ:uL%E=w\#!k^an5jiJ<
Xymk+/ HiwR\dLXM^c:/B:tHywwECLb=T/DCXIV6eGaiIc/QdEC*CWM<R1Qq5E^9KN\hChtYlFy&^^iTl^9nAjL
-A8JEb 000d01dd1c900110333 Page 423 of binaries1.zip
yVuFcE &PEX8a%hS@T#+6dYETl=EFccDCWT:mnEn4QpKqtq>uB>Ac1$bn>Bn=54TB:1kKG?k/BtlH*^F=8dmkld
YcE+pZ MFj8cD\HtC6hTCF>>Bn8D*Mk\muEkniDA+K$L1nRJ>jDqZFE41S?w&yjpMn?^BWWE*XJmKh!48PIt&MJ
^4Nq/y b4H^9NQS<ma!IKm@/lW6FGuwCPwah*R9SmPA8RPTLI$Dl/?AMw$aBHdDZNnm8k>=Zp=i4Yj8RJw\dc=+
i=JXaK 1I!#41!A%ZQDtw:5tlcmC?W:#a=\hbNcqh$mEZ!%jTBWJh<^\uJ/5PmNTK>S+<ZP$:*C^k5KRFEBLh?P
PcBCPa CCnndZGIMuuJa@L%X*jHuZtuX?4jA??c:AH^I#FK!4$^QFdZ/JQVu\^4a5lS$DT%Nk9%>>l!j=bm/<%d
ILK!56 tby8*qtG/6n1?Bw:%D*e1pdZt&JpjRXalth+*EL1J#yCKK1VL*!Eq4$%MCVAV5Q:^>*PXQJT@1:X5eJV
JaBp8u pQKy?WV^L9Ql4kW^=#A/NtRY/C/mPJ+6NCFBG^IAAjaFdw?PwJ<^%J!YlSmBqchBM8*tEN8jWuT!!T5!
yheKC1 hhw!:wa+NWwlQNa@uS!nc!H:!6P@G+84+*FHuIFY:u4VSi6dtBRynXMAjpdiSMFnRu^5*IKebKKqXV1^
XKQ>#^ 8=b!a?N!ZIM1$ADF6Cy?pmWk=TZXlL=mQp&j$HuDutW!=Yw>McdPElKl!Aa/JDc@Y@WA!FV1k4!5YeB^
9l#LbB PtN^?cw%4YCq5X$TD=ViP&JI*6BDEAeuH*CE$Zy+iIKWHKPT:ZV&PcZ9@ycM/9^N/cZPL\ZBYd&%cYHC
nXh89< tly4*nQEt6lVKQ#GGeHuF:thZcMQ$%dVyFPelVt/&LPDF*&GZ><QYAKZC?L6HY4ltaHMQjRW85%DdJXn
l:j^4c /m5bYkGE5&w<6%%+@yWM!VFc#@uN$RmC9nId8I&YGdn+F>DeAL!/1Tpll5?5nC=9npHJtqX&9bbWApV9
ZnY9WX e8Q9!8YVT5lGA:8eu+tuG&Q9MI+u\<$jeSWB*!eYXnLpFqlA:<wQA1lG#$48TNt%Ty!dP!DSuji<d<#S
j6li/l MV&Ve5Ee*D$*\8JyP1V$i&#=JqYLJAF1J%mn9Sqh&pM\bWH$b\tDn#H6qR!VIN:m<YBSKFWy*=X9?wui
bXtK!S Hmt6wqJmbQVkF\q*=X49GiZdH1bWkjkC?Fhq9P4ZQQEtP9#d1:AE>/$$tpw^D8h9jBMQii>>J*D+9BFj
*d6:Y! S!\aMq!I?lwh:bPt+?FeS<m1BZa#>S4&9hFW5KkX^TwS*TH*Q8NR=K8@ZRY#<%c8j!GuLWH#\/^VVE<j
ypHYT= /Kl^^G/86JW>d:qCGDEF6I+EST?eYZh>d5Ga6JZS/khH6^ARYVWw^MnT95R<VQtG:^FK*EJE/#Fy@V=X
kPJECb JMw%etI5Pt=<&N%TZqN&@5PBc=CFH!dq^t/S?I5RX>JBWRkn5\a#Vw/pWp/S$yab5:K<tE<M8#tk1/*M
cph&pA YLD=6>5GT#iYhEeJ?PqC<=ZC=l4:mpDM?wnnR=pbPcEFyT@kb?GqSkJJiACWBAq%k95FHj^R*YQdCa+u
nD1:RQ 9l:4&/eP9^$h+t&kI\Gq&^LY4t<wqNpQnu*Xl8^wnZQqD5Z4IlG98E6j9PVmJ>H^W=n5c@bc#YA#5^8Y
p^ZBuH W/4/HAnw$&b#j/6Y1q^jGW=w\<u!n6MmmnP*=N/<lW@CHZLCEQ<hD%JebqLTZac^#/@DMZ:Zt:Z%yD>S
kjy<$X WctEGweD&%:TM9FVPM+!88CTmPVVnHC:&P#yyJB?iZECFMR/#Cc!q<XGSLup$mZKwGl:J^^IEm=dIM?\
T/ZtS$ /^^LHI^JM4cn+5M$w=Cj:T4aR>1/48=uXLWN/kImXRm1+&W9I!CFHyc?dh@Zj@Nt^Pn&^Alnn#Aq&X9!
<BWwqJ D*%t59eDNLd>RNW@haEI%$cM+B=*X6E%S%mjK<?aBw6enpS$VlYL8i=uRaZEMFhtCRHGaq:u!MV:?w1K
V!V//X jtm@$?4eyA4*^YNaIVZ*/?*P+?y8qPVt+d*LiqBpXcZi6$X8Fp8HwlR5c5n<EhTDb5q>ehjd>EKbitiK
qG<Ph: b8q%<SQn\ln&<kNSG!jCHmn<w5D!BVidqD%P<FpJZZYZ\=QE?Gcq!/tJl#VEJt&RawHG!ADMV=P*SLpb
Ep/&9h *&W*EYhC+neZ5Bm&:!Ilh5NNHL9Y:8G$tDhW8t@Ck=$+AM$9u#mjWiR8P+h&k=tmR!QQuyBiWI!$=5uw
QcI18h +4NQ6*d68p8Hi&QKKFupR4^8htVp9ML\ISjGS9yTtMTcDB9/&aXF8L8k$?X$By#1^pP//MSFXlQZ>J4P
kdCkyG bN:/h4lZ18dMNY=BTpwWlB&R8QC!LEdIAh/wIIj:qHj==/VXTh=XJXy*#Hy%W1=ui#!Thy1?*SPw#nA!
?jp1m! y?TnbZu&@8LT6mcF>ttCdHt9H1Z5!<^Y@uqHwVqncVebt?TmF$@>4:YcpjXD@pLeAY^#AiqMJeZTwb#P
wHAhwK KZ5$6ALQ:L@8CaYQ6pcF+%QVw4L8ScD=k\EJIZ8k=EYJQt!uD<q\=<G*qp+E@=BMtwTctw&j/:Ce$CJh
Lu$nQG RASVepJBapZAh\N+8JCm1+JJ*Kb+q\G<k<YJXuC9q#Pt5JK/PR&Z6+&Mn*YmNHtb^:/4K9F#FY#YZJ:q
@e#d#S ww<N/%Xcaw:WpP54^QwZDkISJI4tqmXnBJEFN!%nPm&^hunB&tZn+eC*&+qSYeiLI$wkY:yiL=:J5tM$
:PJ/L= Vp:>pbtinaZ/jySm8QBEq=kZJ:\?Y!BlGAhm8Rm$HM#LSc9Rd$%5T5\<aJ<aJpb^MZDcqIu*m5/l4mbG
8%ltV% 8S69#!5nFci<Yq@JG*Pi5:*y55HFZ*tLwW8t5\>qBd!^PqHjYhZaKW1d9QHJ%NDtZBPJwjJ<1cZNJ6<T
qM%qy^ 4mP%KE8/>+t!%blykaFjZ^Fu:nuIK5I%MiKVyy^!HYWqjtBmddyFjW%!t?%mPMn/*d8q\5Dq9WKddMcy
>Ce/Xa q@RiJ1>D\m<Y56jWLZuV@NyiXXlY4@Rpp$SB:It\SGyhCh:yZAAj/FenJ6ZRLqWM@yeH/dYXwy4DN9!l
R=uMlZ YdnXWeFDBG6nhn?K4caGZSRD$I<T8W>&=MNdu%5NVW5QE$!C1!<KH+wLEet$SqkE$+8cj1Q%ii?XWh9h
hn#QVY 16dVLMCm#SLB1q9wK9G/@SjyNMd4Qe?$FdwaXHMtyRKehAERFZ6=E!*kiDDb8$SE*nV@jNuN+ZTG&DCZ
DGeq&> !:!R6j+&+9m#bV!EDSKPHI>^/l5:8NuhK?:$&>I^+<$D:S*cw1pqN+S?jlG^6SL:6:>M@BTaMyP^\$RZ
YXwX^e 5cEjF*L>$w1Ey1P5F#6!H4b8ln?9quL*BT6GyGlkPX@p4+DQQcXt*$yVIS:^Tqt!mlb8T&:=8t<XcbSR
WWPnEA Z66ahyWQTt:@W6>G?ZjyHaTYjHMDL5je/FqTZH>S99F9nVuSipNX6&HMl9#<NIDw^?D:5F/Pe9/l+EAJ
/M1$!T 5=VhTbAbDwN\=tlQRu1jm99VhCZ^lQk8FW8KtFBeQJqCM#+K8qDG^XGNZi6wWD/9WJtYCG?mNLN+iKjj
:l=Cwl Lu5+Kl<n$/iCXBilSn>=ZJnK=9cGGDC=m\^RM?RkC<#Nb%jL9QPQFkj@@+P&QQH@n++<CCD?%i<R+Q64
pkHPpP 9?P@TN#@Iy:@k&QB@>enD@\Cj$Q@!i@kF@\Lt9>QR\9<Ru>BI@/$aayj?G@wQ%%dAQaZNN?jin$EiQ?C
aPNah8 @4NdIkD@n*+H@%?MY@D@u<e6lAV?\i<R+Q5H9\MGR@#9$\Ek?L>qB+DViT5HEpbQRl<bL#L/V9lA*yei
$SmK14 kF8wM\\G$i/*Ai<=n!L/+9ju1K1/w%6F8DpD^BATWahdRpJ=1J=YWB+?F\Xp!kSNwbTpap+%V8/5IlIN
FW*aZ\ C^GY@9i^DHkIZ1XC1$wncL/%?pB9YclQSWhXBy<mSIy1$y!PAB=nKu?HW9pJR9i?y4#GmA/W6EyWCNVR
E+!C5$ >%$?qLLWHD/c+PFMwcX19+QwycJYEXLD+<+$$/E<XcXWqZ<uKDCThMquN$8b>Qa?H>i!:Z%kaCQ%85lc
9wR!KH ElEHaiR6ee#\*j&8h=X&*EFD@e%>#\X/ua<?9b1naNJyS6qbQFdGy\ayJPy\9miRXdu&t^bSyDn>Enby
AmPB&l m4M6PK@?ptWRe1B$L$K!Fj!PNCwR1R=FtTc*EYy%w>beSwXCd*8lBcK/XKPe/t!ppDhnBNFXTjcGli4Z
/QiHJH Kn8b>ZmEY/Wt5=iKiRCcc<=<Ti&HY5&cPk?D1P9jSLhXHGcM?&Mq$1@j^JwpQ>S$^jdpc9wAmeAHh#k=
YGeMi& DT@\$TMK\4B/<6%@4^kIlZYQyGk^\Kbkt=NN<1q><4KLK=V^FNMJIcJ5JIE!l5E41h<mKcwd=/jlM+*W
K*9CRn F#X:6X8tENBMu*Dm&Zh?$DBW>c+J9G<$aAIByY&%NIQbY$k+PD#GGaX>E&LlZPiN$ncj:lNqAS9W8qpl
jLAHR/ +GhcTCS5a14<ZweV5X@?d!i%y1<Ru<VXe!E*hc^H$<:I%#ZE:LZZLwpBnY5AwReE6=e&/k%u54I!E/KT
wqS4l% FZmIJ@FVwc#Jp9Z$I$:<1wWuMdN@8wDI#&R/e>?1ylej9q+j=y+ZkDtGSL9DCW6%K^qWwp!yPm$&K/qD
&ZSpnE 8JTW5jjKKWXD!DpSKA:bwCCe9qKGiLbk&b?cL%wyd4>W5tPmEm=\TmaVw*AhPT9&+6+IYpiSe#m4tH//
%d\j8$ F+\aqu?AbHN*@N=P/Xdh41*4d:R/?aPH8nb=jhuQcJjtFZM\F+umZ4L<MH6hC?Qu1CnZ^%DJL6//^k>p
R+#4\: CYc8=l!kFucy1CidiqCmIY5KAE\66+e+TBLLFpQh5#4&MC5@jNhXwa=ylEc*#lXw*c#BPM>Y>DApLnqm
e8!J#> WHnEhYq5enbMA9R+Yw/qq*NSL@kNl^SMJlmW>mnQPaP>4GjRl&#cIy*NhF9%6lb4X9B=9!BbpZRwh%Gh
D<mHhc ^blnG$GT=$HFPP8Y=mMWP@Ch+*q4\!N/HK5\+p?cR@md6XEYQ!R8?NF=JipY>K/Ym5Sk>ZGk!N9QACIX
?k1%LP 4Nn*$5VF#WZcSi++&45Vm@mLLNdY+FqCASYG<aet9LdtiSEL*TdDNL8&BW48Lq%q?@iSW$qAFVRHRJ&Y
XH:KIH Y!pNn^<%Bu/SD#QdG4q/Gu>S%N:mji!+9KStVKV=CpdX<$E@\Aqe^c6Z6:D:c=H8D5S$LAjGwyal=54#
BP%FYb yyKqRX$#iqDXQe$M#F8ET@\?w=naR<8XcXBLb*LbL4<ljQS>J^TANa%T:*F\wMup^$yhp%lI!$eD!un/
i=AM:Z DC&KLVpT\C4CA6>S<^XQ$<#8VBe@><*/I6dyW+=cKljC*W#D/$@%n>WaTpM:b8YdJ5FnQB%EyB!:1n+%
J#cSki tcLFWbZwl!de4>/yP+RMe=eaQnuKDAR1eXG@IcL9Jd?NkFKh/h:Z>^?TZ<1D*<6#DQN$p=!!JIR/e!5n
weRw5L VT\q=t?qwbY1iR95RT&Pep$6Zk@5<9S:5E/1@6!q^ej>5uPWI\nDhpjHE*&hRa8S1p*Jli@%RbuaCpQD
bDTZTP pPannWGBEL*=/KJn<=ceM^Ql+dE/=mFlcPLtpu^mbYBGeFjLDulXb9y6A6nmVa9W:5wGhSy$!1GL/pyb
B6b\%w eTp<*Gb48dqX@hHIBe6/6+%HY*n:=ye8dF>$$cZb$IjHu>#8$Jp%qWS^:?G5yudeu*e*A%A@=:696tqw
wDjPye TK?bjhdnlei&<$A:STYuZ/np@i=6ckT6wYVwZF%H*@RWq:tCJbu+uRYL/iacCc*$MZlHdj6F!CLaXeZ$
bSEAJ8 9b4A9Jky>bXq>hWZGaH?=/&>tR46l==TZ\+pAk+\SSXci8DFu!SqkaDe&11MLaHWM15MdD6&^EP1ZbE:
$Be*it MKHSKd8m*l59bjXhaJCE$%ctwq$$lRXuWMTa:@tH@Q$VjhwCCA!6Yu/Qa@XDw@:G+w<HKY?AbXXdKTki
-AyuMW 0005e5b558400110333 Page 424 of binaries1.zip
GM/6bC 4HnH9D=9*j=/Qn/%8ZchbEy4S4>&dej*1Mhn@u9<?w8&LIy9Jn/=L#nSKT#qNd>*4mn!1CVjuIMt6NyX
Lt&bnc ^c/5X&4L#yi>L=Ji&Tkq#6Y#%>P8JFaJi$8NBw&aRpZ:>Nub%G\eRFhuhX9IQC&<:>+ZpX4C@Va9%JhY
@iEPEY XiWcQ*DJHhdh+Ijy#TTIZ5k#qM\MaiCBZWL55+n5DN6Q!99MWAHE\EVT!GZ$6+aC+EPZ8b9/wj&jmaDW
FE@8Na A6IM4i*B^w?dF#96ea%d$Wat&cp>nHdYJDwcNq1A84j*AW^bd^#:8><#A4/=Ln:\e$1ybk?F5kV6G!9k
/&pcMV Nt*ZT/EXPY$j+L*!SHPASESBmPNA9Fnw*T6?p<?ad:!6b91T5+Lq5>?KJIJGwP@y^lbSN^iVkS:j?V5D
/R&c^q E>!+Z*bL=I*#XRkj6t/?H6QS!LG?h?YAa@XYi%LDYkl/*#^c^GBtW>ZP8j&BeK9ih4=haINMWhP9laEZ
ba+Y^I Emd&YhHcb&ZldDbtN&b*4/*9Vwd%LGLpkV>*kV>Lm<Qml6%G!AA+8din<!:lJ41V8Hqd&Nh:cFY#cVll
&t=p8p 4DLDIlkGX=a^AEY1Jhi!aYSRwbQ$dmy5ke\WEVB=*QDEeGLu$9$k5:8@:^BLlZLK!T1tG+=q=Tme=%Vq
9&Y^%d Gp:kYD%l!&SyXCkn#yJmTMPKJ4HH+jZMRwpMp95MM58C9M6k<cjN1WTyupVFd:d^Fe1K\c9d1VIe?u9\
^q+>6a VDRn*GI+dck+9hkDImW/e\#1&!Y#lVXu+@SA8uw!&XNVmdTJbWGJ5mkH\lhE<c*+8JN&yJ8b:IEpph/H
=*1<&G T8KnKPIjJVnEcEjJEkbRGbqpVdFWV>DN?1<J+l!nEN\ZE%*PPIpJt:XATjSeu$EFM>w&DL6ia%cQ^dY%
LSCJ*% i$ScLbVq+IQQL4hPK6w^/wJ#RG&y^FE?jF5@#4TcpKG*9$c:TXH!BQ@tZuMH9nmI>^YXXWdjMSpI9a%m
mnm%Di G:4j%hN\L:t!R1b9hbq&BDcFVp<lDHLHyFhl%8=Hh%M!L?Z\NBH^tuGN>btB189HCc6QV*Nb%8+/%Nj6
kP4+A@ pqteBW^8@5KTbHkywp&5VFaqd#<=Lp4E8J6\#NAH5>QBFjbZV/nlHAEX:5eP>m8Y+tm=FZ!ea@D?<PK?
*5dNd4 6$MF#FJ/WQpA6yDwtRBMZ=Bc4YIIeXNh4h5^baaFdew$EBFi5k?hek%=G8CQRFV6HnKJX/6p*m6X/!WR
*?knM5 miF6l!i<l>?4V1nhIn5LN:6HQ:8Bp<a!R^#@>l+K%XDj=RA@aBtCk?B>k#EkKDG&d\?iYGlkYjL6XDbX
8GQj<M mVR*aXNDwZaKYq6Ai#awYYi:&:W$NhpEmY@nnT4pnm<hWJc/*p<nG+>lQ^M/&e@u=Q^<Cmy8mj4Ye4=$
apHwtq 8!ZcYkGEqYWMnmqBCeSn&Pdj+$9RS$6q5bl=eGtCK\ld:VPG:j#d&GWPJh@*w4GXY?*9FVJ5DuQ&L!K#
BKal<M FQIhyKd6cl5H:R+qDwM<ReRnJDhVpEZ>mu^aj:dIVLK4$+8uZG1%$apuCn$V9AbL+MKt@NE9JH=c4nwt
M?CRa? Xw>ydZ5b^*dwmJ=@q5TC$Pp1$LCHb=h91:\hkGGQYXkeZKuBS:HkI@e9eCEwPu>XciZq%l9cMJt1!GuC
HG*lIj \eK/%c%uWk!P:tVk8tTdI*1J!I@WpqlA5pu<<PZe$c^::EM6%%Q%5T<515:Xqh$e8I&nMdqPM:iBnqVu
Q54+ku aS1VA=ZlZeNZ$=P8qlT?V!mP%>jpTy1uwm4\ymV=IqVYc8mV>8/^T/JB!FqRCj%X9IuueJBD:uA#>!9W
%ZJYT! RKW9++&4LETFXS5$Y?>SZcM!mC@b&PedMP\FAL1ndjF^En%^=u%b4ZB4<bY*MlYPMh/VB+y^i*jeqJWG
QybDI\ GyWd$@n=9uJaVy?TPWqP8$8GCFQqM>WhQ*?hmGuAMm\1+e@YW=thJT<w!wE+VtmPH6bnp>>l\/B!!XQ%
Z/Rp4* bq/Mm=CycVmqw*9A>14e5I%19mI<nGXYXYcEi1ejc+#FtV^LwWQE&kH^:8Mk\W*Jd#A6G8iEy?Du?qZq
/*t#Iy ql1\%Fq?:dtA?8GQPncwL&!Sm=YSDk/V/&ythlTJG!^4?k/!V/SK\iimm?9MiyeAjW&V@T5ZIZ#$t$I#
ykqB<K !WIK*eF=c^h$k%Tbqq1/<pHZ*Npb5eIHe8ja#jD4$*8+GhM@TE\G!In+PC=>wBL5HK6mbERtnKypTdD%
6TyXRW lFXp&4\hZ^BVJ8!Ke?1JaiJ9t+lH$QLybQlKt1!\t6R<QqpN:\ZPDiM%WF/tp?ndpTNtD$PNJSTJ*l6<
H$$R#T Ci6SplYIJ*11tF1qiuSqSJ#V^KhqhKD#cnySXj/i#E!>J/lJqLVYNCtuhnTeP:HF/qK6y^<uXR9S4yAm
JqE5:$ Fu@*Khi4b+P5V#qqH*4GYJIb6RS58VCyjam^:Za4H1w^j\b1dPhSje4u<a\!yDbcb6AE1?5?*L9ANqTJ
KEaPd/ XJTKjTjwGS/YMdP?Z!ZFAWPNtG@1>ctj!RcacnIX&5jlkDR&HT!XwDn:QNWVL?YCBRp1%R9%hKT&:l<k
iI1HuH >CpLaa/S+dW!&@i4XjCAylB@eN1TC>PN<q$jd@K^X!Z$pwWQ\aKHGN^XXXaTqVBhP+9jjkVqKl:+P>AM
aGSR$? KK5L^hR9wilD>5E>\9pLNN=9J?pXwwN9@jKQyJIt??WLuGi&ZL\<j=$m#>Rd*PVykk?d:l@$6AR5XZkF
al!h1V >Fwkl^4MAW=1hbi\Ee:eZt&\J>\I=dDute!1$PJa6:1iqK::FG%>jDue/&$$/KZwk%V%IYX!MHGHw$YT
i=>85* SyhDK18a9+qG%8N<4MwyP@+l?\%l4Iy&KB!Q+jE<8A@h>Y^npZ:=cuap>mV%#DIHXP:6W?a1u@:L&qLp
PP?Ju* =^P&:>+u>Dw@*ddim$p\TDG8JjTNk4<V:/?PJVdYj%Q$hTkkJHnChEP5=6C/6L>HDqa&+Fd=ES5B9ZV4
@:nw#j TPJ=/KN&jJtC%6@mjn:b?+T9k=@K&MtlkH>GTF?CIbMha%6EANHCN&<8dNDEX:CyIn9NjuX8hdjc%j?<
W/<IdM \Z1KuDmB^aF6ZnK*JNQCkNA:9VcyF5ZS8DL$\5H55Ey<Z\w?G5MHuRPKbumm4#%jwiVB81e9TPJdlP?m
iq:FA> M%bXyXMHVjwF!e+aPM41Ic/@5IP!qwQHuN/\>na@>ZF:p#/lLej<c$8bpP4PWn=<!TkYHZWG9Z:m@ZFQ
NucXLL !TFZKQW9GM+=1IJVwElMk*H%YDI6lSmw:e8mW6%hGNJjZBce$a14RTC6WGL1hQX<=KKkaH\jF4TlH!1k
T9%9Dp 5YMR5BTm9H1?Q$LcKdT9P>5c#J/lR\=X@4eZGHKSJHD1%JLHu$neV+T!%AlV%RBm!mRN:CTXRqPa$NDX
XC>$bi @bCG/?bbyhMb%wEH$/q&jd>yFJ6$\6a<ZCtNwYAJ:Q!W^+$mN=q:bH5C=jd/Keh=FCj!!w#HuNhSC&Vk
pPNR!4 aiuhN&LiY1@:$d*59LBe4cIKPP$KW9Kp&WdJy4=^L8*kI>#ZMIX^PG68YWS6Cth&Iap*u%tV!JILu=Ap
ALQl:e kb5*Wa%^?qpZ4Yc%\&u#:<AEJyt419jk#4*/<huA6$&uY>CGb:ph8H$@QQe*KdQ6Fny#XRk8lNqd\ZqS
KI?In/ 15Hp?uJe58FynLMpTi?VywLd:JZ=F$K@*a&YJ*yYqkFJc4qLW8Y?*NQ6=TFFe1!Xyl8&?cXPc5bVt/Fh
^9uGLK $M/d=NLGK>BLRcBN$Hhky9?yaIm%X*mQ6>FAEYwtI!E$C>=4F!X+ZCPpuWpiaNIWjR$5YVJY5ZBXQlht
<lMD&p e%=J6L#DZqE^>NAu&eYdML#dyX1*ed=Li+kGEX?dqc+ThknQKk/RnqVqQGA^<Hhntc:D@Vnab\A>EhF!
Qu/a8I DIHm>$RL^A#Ziqyd@ib#E9E\mH6cyPG9w5+NTQLj4l9XdD%NJk655XHVjmDGER&u*@R6>c#F\A?A$*9J
>RFjt4 XWWE9I$hZ>ICdGK5:4kNbI4i+6V:&K9KNYGyG5%wQp5ecyp4K#8:LJ*y/GB4XIE#KeL!*yDnq@*W=m/m
Qe&>D> P8@5dTEZjZ&bQ/^H94>Q\YI=w>*VuD?N&Dt$eEk8::lT=5/T6*ny@<\LKWw49u/^4MbV$c9KV1&Q6Nm6
C1lbkh aT&jTyD#Vj+k98aA^JSEL&qSt!?HHFB5mQC6@*P?Z\D^9#VjL<D@Q/l*C\u>1>+6JQnZi9h@pVn@SV#>
dQWkZ^ B<Z/Q>*mj/NaC@$lcm+k?Di$\B>T<kJCj$QD@/C%C\n@Be$9@Ie?b$Ha*>B@84ak:%@RCME@cP&C<L?l
y$+Bh6 ?j>E<@$NDj9VuTQ?k9=nq:Rk@>@R@H>/#j@t4Q%:CjA@$*>#%8B@/4EY@J8#^m9<J@y9#61jHR1l9#q5
N:D4tJ knDaH?m@Pt\Cj&nBF91:\@cH/uGl9#q5eQmj4w*+u*y8@9<yY8A@8pL@lj&@hIZ?/?DLj*KFlAZ@\SWT
T>tB1C E9!Hbtl?Z1H@h\4t@!hVMM:@h$@BNME4uM$TuyN%dL>:Eqm8REhA8H#bZYb4dXBT#yXMkqeQ/qLllFVL
SyG<$\ G\mA^>L%akV!=A%k$iyJ+kJk96M>=QmS<*CEHDTAwlEI4Xk<bALl4Wc#5qE:XlT9%cKVkLIW&F?\T9HC
bBhWjD wT+?hVyqMc:BXl1kYGdmBlHZkSpj@?Np<TXBqhdFVa!yyCj%@JTM^RIpJX=qZFk^!bwWR9uTRlnm\uSC
A=uNaY EnM&X&K5%hRl8kD!SMmT^DVdH&>AtntC4b4DW\kVR<GHt1R4a%HCL5%c=Ib$wZq>6lR>G!qiV^j159e$
>d:$*P MYIhm9yASZpDP6*8$C^T@8lLa?RmFjbPqGF/paMNWKAkuMIp<N*bK/X=Pq9+^%V*Dc@QA9PK1e6u+FPc
8ck$5R Dc<NY@+&YEhk%1jYd&J&=p$h&bL5Tb*n%GGQ!^ebajcF@S1liNpLSnG>#:KN=#>!G1^6>kRu?QYCLnTw
amW^\W Fu9bQnt8HDXwmH=ewBCl5C!AAqwPan!jME=8=ATT:C<WwPip9$/K^VlTCi^VYHl>1ld=<6ZC!mIEL$i@
b:MPI* dJt/l5:w>L8DK+WX%j9jV>ALZ4\T==:nJ@e9Z5b8d#B+iyIQkn8L//K%P%tEdjGy8Kyu#Vaet$w9BQl*
REBjak Y4aw=Ek=AJw\W\*Fqe<@%w$YXun$#H=PlFy=N!?1mMT5=B/F/l4N=eIHLn4M5#hG4#*ilV:<tjVqTE\/
$SS>Hc ?>C9acDKdj6=iF@KAp&L!KV8D\Fjdqpn/EKPT*dtY%@wN?H1JLZdN+$EA5k&anlAB@\RHpW+^5+SH/yu
d*6Em& IJbwAk%WLidAZ!cKq&5lDm#6F#9jIw\?6\NmuyQqT6Ct^>>:a^>JRTHSqBmqLSJmLQ<#k>j!mnR*!M6a
wbnZyI 4Gp*lM@iKmb!GmlX=phdiAlT>j$hn9b+>X^LkSD*eb@+$i&G\KdSeHjGjWlM*hPMpkJ1>jdtmH9QTh>V
?Z#1bI %^Ln$Y=HY5?L$JH1ZI1:Ia%Xh?hR\WE8=B?Hwl\CTAHCqA<T9M$6:i1jh\\BdVJ%l&K/<he=F>=T^54^
Fj\tjB GGIDiLFh/KmNd+yCGK\auhbpk9cdD/c<dBT\Qi8+V^a$%pXG:I&y1VNch?#DGQIKu#R4GDBQIaE!FDZ5
IhWK%8 8*IY5?i+tGEdjJdNnP\yZ/aA\6FJd56\K=Y&hpqTBBWYAY>ltqpPQH5YYWy8hl#jai>G!y?LHj#/:IuG
%9V%JI 1wCCyFTFy?LVnPkd=$6ej>4e%a?Ben!kmnj?GTp9BRPSb64wQum*=P:c$qpLH#LR5Z1a\WuXt\GpVJtp
lDd!=i 8tD*bFu6uRQ=yWlG@?LZnYlQ1>L*GD4&%uB4AMQdwWQT=%5PKHd=Vm@$YNyE:4u#Ew$MG>qbIcJWF9c+
Zq8AH& y%k#TSQ\SNN/NdnX%CHyGqmwapBIGWWyYFG*Y?lLV<!^+tmmH9yMTCQTMYMF+kScp5XNRpb5e1:GwI5F
-AcdJ8 0004d91576600110333 Page 425 of binaries1.zip
h^<PPu CWTtb!Z!G5L#tq<5jG<TmjuSY*LXhJKQl^+Q#uY!Yl9LWy+WM<*%hcuihq@RZKIaT@qiZZ:a85A4n!I&
+:^XXX IHZZJd+icGR1^M&SGM:kiCM@J\F9H+ej9/%SFbXp>1ZQjGjQN$D:VM%n#@RV?W=MXQ$ZydLcZTm6D>>w
\mH@== R5:V>N**%abal?9hPeHF/W/wHV8kMHGQe#un8KD?j5yb&i=!JB=hVK=DY+9SbV:yaXMCZw^BGJqn!eJw
??wF&k j&AGywp1whYISmH$WDSJ<85$#mi/!BYidm#I$jPp*=i&+$6:qe=FCYHD+uIk6<bi#*!dyD:=6$C#9l/d
mMYS?% *K+4Gw8XFqWeJ%j%dFLMqZYmWRPL6&j6wu4Lby&86!tYkHa+!@bDDFuRn8/>+ac8n/=D\Vu!WtXa:6dh
&jmGhG 64mWZ/Iy5e?*cJPmI*mYk:Cy$4V\JLPI<=?BA&*ku5$LR/*#t*9b<985BXuY>tP^8kDm1Y^#h\W4>FCq
EAjImq JA*PkuqV<9i#a99Jn?8EMBYXB89mb//cnA94%9dub%15!LFu&^q&EZmu@k>/uKqeVW5:S&QkN>+iY::G
e4>n5I Fj64^*I@?HYi>hcEm1#ZV41?V$Qu/d?b9qnBQ9k\j+&k^hp>>nC1cSWb*4Q#p%w:w@b8!Hk?Lki+14R1
JqhX<h j9i19WS:R?FyeG>^QtLR<HjF=I=pRZY!hSIHnaS$M9l!GKh5VF!c%W&MI1ZljXAJ:te%i9HI!8<jVKV/
qE??h& ^YuBeqXFQuYJul/kTjJuTZee9=y<<&q*89+<KTBI:9#n1\Gu=T>4wh<QZPkjpGatJXyD>dwlL5a!Z/=Q
IkH?Cn <tpR%p5HV\NZ6yIGLRXl@GQ6Y1=8hqmlayi%+>NJGJQ&w&6/K^Wq/hCBaIZP>FjwXi4EIwVNT@XmZ$B@
QQpZCi =kCF$:PujRceqAa#LT4$KjdDa<+YTlNbmAuJwKaa*HYBb$PmNeXCXS%=#iGuL%1F>M!Z#m=tM=>q64eV
XaVHiT Hy9BHkYeNCSEnlZbh%T<w9$\bhWq=IpjVq%$5pc1IjK6*&E=S1#<?QB1*99\c!=Qk<AS<a>B*i8bkB<u
eq*$H? Tey4JZWX6uE^FC!$q\>>h$!aJ$+a<n+EM?h^WQXXknWm</IiMS$t6F1h*\qlXN>ml1hdVAhMAqS@WPe9
k>AAXT +\bkGtMm%*T/l<nw\nu/IaKe&!&SYkT\uW@*e/!EiWbTG1=Y:F<d?@^/ZiC\e6yV!+AEt\\:SCaG!\l>
$#k6N4 /?H/#5#!uWXE@Y+Y??a+nCQ=PX:%>Qy5!AbLj*G8eFSPdM#^wq%IuDQTuAkiFyd@=bAnaahSIHTiZ?4a
EJV5^+ YGwq\iate85Tc>ZaZZwhJ^u?AW<nbi9!>ZaLRj?%$KSS:KT644Qi=Xc%L&e1@&Al@^CL*\=6MyENRh#N
ED/=FE %aAZ@6aPkN&/W>1LiGJFIN/5%>aed#A^=>T/K<1:G:RFGwE1V?b5V&#!VaVmXC4\S18F:NyHP4XQ+=>j
HbkkFL EE&@Gt1jnIF$SWiSX1=&lVmmRQ8Z#C>Jw&eFPLA/V/^H+nE8?QCFkZI>du!lMYynjKNlSi4Z\YbB+hiX
\Q*9i5 ^N<86>&4XdLGFT<niXqJe=G&A?ED8d8Ge8M/JV1XYA+VcZ\R%/Wi%:BAkk*=qD$&Pk5F!#B&NP6!wj$p
/q@RR? Hi9DndmB65KD#&%^Xl$WhXAEK$L>qhtdYbcp?KXd%yyl*l>aB@Xbk\:^lJwma\5KNPt&q5=I$ibut%Jw
c5KjtW >:9MlRmeA#wqiW1t\=XlSFbEP#@#yXMqQ\Qu=<Iu:q=PDFyVb+@&jn^WARC5n%YiGD+Gqw1XJ6EVun\1
jb5ew% 9FZb#HI&D*$p^<>E\lWMP#=R$E8*LC?R@dbXJ%e>Z1yBcIaeSKihqiD8Fh&FhJdu^keWwIY\5%&1u6ul
Hak+NN XRC4M+biI/jSVX>+yK+Cp>@hd9dm#&<VwletVphG@ZZ/<eCl++IFbnuSjT>SW4hYZd1J<T=1wlcSYnM:
MwTNF^ Zy#HdAlkyb&4k5E=5ue4HRRjZB9j=w9jaWT@+KuHAHDe$<TX^MdYYLa\u<d+:<J>Fe$=dHG4w\Ke?YXY
tt^B5P Y!16Y!S>VVBpMqY^\=F+%AQn+M$d<hXD5/k^lF^:NY9V*X+QBwZeebZdaiStFk1/=eD$EXD@?\##W8Gn
?Y5D5@ AI89Yepqiw\cH$\nJENwGH%%n>iKM:/A6EHQqy8GdGA+^\$%JWNe:?bjY8uBy9CTF1?WHYqLAE#iH<=p
Ju%>lN qiDnC&jR4u51w9k6RJX5FLVhLmhBi1El1%BD<!SkDERp+u\L96CbTqB+V$y5*iWk&nD?^y#?cjqd*w%H
+>?Yqy eAcV=^Q6d>!+6L4Kb?P&c&XhZ!y@#tQhLClAC6kjKt%GX=y4tEn+k%kLWNKWkL/d%hAGTbC@b^@jE&eF
%4&eJA :E!QwI8cEuP*FHN!6:uc/5RSJWID^Wy4^$VdGn$uI^Y@N4nmHPWBuda&n=n6&SuZLXFb1?*yqXyBAPIu
JlGBbT LuP!%M6R>^VTaMReq?Tm\/uYi/@ENql?!Nmue^tWF=u^>d?p4&N:1Zd!CMMRWM>tTZH#$tdS#tV6wS4S
YSL#LA a+iHSm=nn?bIC?RmqNGKD>YTEYT\kK:Fq!\KpZX/5XepL%BR@/Kk/$lERewh>5THKA=yae1Hl*mw/=%G
KFJ>9E $PwBp%JZVy!BCYe=TNpJMqYE^<&HP>Glt6^<TQBi@AS8Y=*Vn8hjbJ*9Q5l^HDy<Gwh#wwDWb%@M+cLh
M?SY+d ^JMTCHQZtk9^a^&Q4F$$c/y=wWSh#AyEVA6+^Nu&8pRd4CLQN/I9tN5V><*AQNLM^>%/Eah?P&&GBcl*
y$X*4j VS%knVD/:XJRuA>+N*hiceKkwb@buK%5q8p#^V+jdEARtA>^wSyb*TKdJdd5M=In<B^Y@5*ZF@km+Hla
P6N6&9 QX5!!jSJe98P9i@p#E>llSNyNQP>ah!w4Z\#<kb!&GBqpnJyHeP+14VXnLhbujjS+hm#bnk&+Bl<<jN?
Hc6C+n q/4=KnIybayb$:j@d1NGZQ6:8XNhKjiG5ZVhRtmVR=P>JNAQbQ1Ra&pMBZZbtbhkB/+IdMcSeCRV$%Ee
R=IQeY K<\jiV6jn%aVLDW%*%aiKHmD!eBH?LpVG5peK\&H$G18QAi4#W1HaMh!XJehBBWT=Zlwm#%n%\=bcjVC
cZq*9= iT@Qd<WlDtHKh5@>+lnn=MCeGL?%1Aw$hyMVd@RmeW&/#K4$c<DVhG>?d<t^8BaT8T\\&G9D#lMT$FRb
w:PWYu l:!eE%Q<!EyPD*j%%yk<6<XXlQhBChWp&QhF?KjuRYX><//h/GHVl=W^VP=<km\nMmWVj9l\j6qBAbbF
L*:>P# P:Ryi^^y:\X^$ZRMS&?$etpXB+ipH9<cnDC^bcjL$Y8QQdGC!5QKu@P#5?dh\PpdCAGt\VJSd^4j+IKa
!@R58P \FWcip\y1y&ytDTqiF^9M?jQG&A>E%pPe9F&S#5+p/e1YZZX:A6:pq5Wy::9X5wtiBLwhS>j8cKPppE5
++%N<W VK9j<+TIK9KHb:C&M*LA:pDj?d+B@\khhd<H^n6WPmw><K9#M1h?qEZA8\Xtb^J^FM6q#dhw\@S+d/1<
FCdY!j X?h&b5CuIb5LiKlQmGq4mL*J+ia6/nLbYhLj#Ba^CGaen?m4*t@YEXT^^%>*?KwqIa^uJXAmhY::LZn?
kHcTPd &!pFNC=X4TcD\R&K4Cq<+XRKK^!HuZIk1hhC=nppmHZ!JhSYR>9>6y&*1qXFYV*wSq>!kp6n4!QNQPJQ
utm>/6 V#DBQ1^*tDu9YHLiKY^>I88DK!tGG!4N@EbP*cthEQH4\@ENYQd!$1P$yNn:!tJQ#<upZFpFwVtLEACY
S!yH=5 u8A5!Xwj%SCbiJKBijBS@LqLVla1qPpwGL=P%+Wy>IhiHKhl>R%@9Iq>@cSdj:RW85XAYj\E!<GZNm=+
6ikSk4 tGSl9=XNPeZCq4l%H\1wMjC:J6A@+dRn#p58L$p?&LI+mw6w@iliQFu+DX4XPlD6dj%8kY\yBT6RGiB^
iaqjG4 **q^>em>hTAMc^?^S#d@LYBbb<C=HX%FZj%T\?Q?%+A/a5a8*!DhBYae91+ewhDC<P8c4=H%Au$%P$^N
*jKRt/ :Wc#X>P/uP+/kqHPXP@jWV&mXiT^5:d+WaZ=PukTG9E\$S5ib%%h!GZ6j8VmV\S#LwEq?=/@Kw%QPc&X
HT<N*4 =q?QqNC5tXi\q%w#bPt8AX?&ujCwnXcuFEWPSPXE/WZ\TH>4?\Gw&Z9i8<^pn*PbeLM@MBkju%wmKqH+
>4S!8W y*%ARpL@#\uLC\u@D=wH\5L@cl+IC@&%ijBjqLD@1LEJ@+P8KTV<6&F=ah/@wQ>amT\M@^6c+E<$*%@R
+$M/ZA CQ+@*VumL&k?*n@S@H>B@%qMFld+t^j>V:Kw5PB@qEYFlQ@:58l@#ej@8!\1#Q6Q*RVCR9<km@/:=Q1@
EPRb:y VXli?H@L5L#6wFq<bD\IYQJ<WtTWA?=m4$HVQ%t@NNRdDVPummt\q&1F4mY*I91nAm=d/1JK*WtJN%A/
NPtLet k%D=TkZ1?n5+=>$n/nm19JJ=?P@E=e<*L?=DZFR5IiBGuT@QJ8:Iud@DmCt$61miH<IyIBSNBFTTBSR/
cAH&1h %ADTIATFawwP648@%$BZWpQ>SwaCEKmwR1w\E&1yQ&YKM!A=Bq@hW$Sy#KpKAQK/XPWp=&#Z#EeC<R?d
&c^GAZ NP>SY&p\19LZW1lP48=JTJWulS>kFJlePRknd=4a=NVe!?6D<WmH+Z$#l?@MMdBNKc1iT\ATZu&NS>Gp
Qb/Npc ZNABHFbM#hKF/K&q1N!ZnMaJ/1/8qqGZ1^KVwtmCJ@M@F+IWWDC$t8bJG8691lLP\?PEdSj=+HbtJ@EG
\>uAKd JI1QhYitmD@=:#^&>G!T4El>Ttt6=T@RGwIHXidbE?Euj4>Pc=RA/$>SYA8iTQA+JNY=WTKB\pc8BMNC
:<jIuy /WDCbRCRFu!$\SybTtp+6yL@1=JpceBZ#YhLw%q4q88h%4cya9aLnVini4*tV=+TRFXHR\h/HERG^aJ:
8=L*n% 5\yu<99icMd8HGn>^48QV9WThAduAhKy=?l@METAN#1@/pqpQ*Q>INu:Y9tNbu1y/9VT5/99>=ZtP1Yc
hD1qtJ GVZ=5<F%CXCj#^C@pki<i%wEI9*YD*cTKh^NAZR!F=&^KXqR5S!JX1uq:BZ1J!<:p&8BHH=X^#akdnDy
>d#:HV IYe%TZ@%K:@nLVEdD:P+@99+e:<McF=?>TH$1e?jh>RdNZ$y&h%&W#R4AXCFS>4p%d&6/!<ju4Iu$D$K
eeZpmq @N*DBK91Deb*aRkMjTcb*yhXack$wmHc4dL@/>QId@NVMR1+qAK6yw?6Z8W5Bj#$At@E^AdeuS*JF#1+
\$wuiV kqVjj:XLpRtR*4u#b4yTj/meP4Z@%:dy49Xh=16=D1^Y5>p\cjB?hm=YbYZSuBPkCYcEa@4WV6:pe89q
!IN+wD SXCKEc/Yp#e<^qS@4\>tt1JnWM8NL?y=lQW\G*&T>I=u5IteBnuBcQbDDl:n$65uC&^bc\5&qkpSRq+\
6pBFlI $E4W=!j^@m^G!WRjjVVjhXTebp?yd@>M!uHk:=4!Bck!Sy#BPGVIPh6Y%MeRS9+>\AdRVZ/j\Ihl&4iA
N^P\kj B/5cNJw@djB+JXpJep+^yyX4<GS@ZB>Lb5w+!/AZ9>:nNeN>N=%jyXRV/YHQ*EMyS8AntHcDqa\T6l8Z
bl+mDd *VhlVYhV/8?Cne::/4PTdGRFBMBT6QANW5Ryk<n4A/d\&>9Mwl6jnHT*6#Vi\/Ejh5/Zt+y6p5Pj:kZh
b6l\A@ Na*w>k8K+LuHDu>6j<VeJEcFB#P#6$^+#Q$!nJncat:SDMSXBiXpGT!X9!#kV4tZt>i%Pt1?V+>PAXV$
#6yF?6 WyY@NiM#V%TZTp&k48>u/>/TS8$>j#J#n8!8RmPKD&t#<*%6J#yPlEN^hl:kq45ubtpc5h&:@kDLj9DA
Vb1b6Y tkHC%&+nycXPV:$YaBibX$CF#bu>6!<GWF=CApj6/Q/ebB\*DFwda8H1M#TNqP+uutJmCyj1L8Y4alm:
-An8X> 00088f7244900110333 Page 426 of binaries1.zip
i<GQKD Lp^PM@^m/J8GM<:^ASbMNS4!Cy:RNR#E^D#iEaiYpRiG>yK#P<&@/6TM8t$j5B=!&i:k+G&R#ST!<w%!
pCRRic XH96lSP$q4ee@ACWZ\\wSkwalHC!cu!#ch66$/+<TM<>MS#pqd4Da@Vp5iedR86PpHj*iL1!C$*9m^a9
9T>S$1 11eNWS&8DL/@Zu@qaFc:i8F:$tMepMb^aTkKpF\QWiQ1Vml+QDJCbS:KqM&:qY^/uWSD6pH^nnBWbG%l
\iu8^y +HGC?%866dum@neD:6XEZt<wH:5IZSy<&J6u$p#QeC@cqL=L<5c=Ql&VXLhmGQNyt#=G1IQFdFjtmn4/
myaXQS Mp1IWu?nTIhtZW6YF!d8qp@ZS15=QcT@X/elhj51K4nHiTkk?DHD4WG%^SF%yQT*/8id^Y@b#6C=CHC^
Q@SjhT $qD:TVD+ntKeWK9J>19uu%jbA/&weC#LGW@1w?&#A=Qjn@c6GpW6ehWLTtFR%MMj1F\\<ECMiXNb9MHe
>hIH?? w9NpR8#8d1eLnah=>q\D<*$FkqJ1*S<nZlu=TSPKjNYpSmqb8jp5hjFJTM&6pQ\b*!kq#<Ac^yh:Be4h
eQ>jqb %\9%Ydhy?Yn*@b>WCR!:b\bBYYy6qM49ImZ\<ZI&e!@8YRqi8?+!kmXh8H+@TtCFtV@m!+88+X$RuX?t
:Bi?pF $l\q!<6ejmp>L:4%IB5ccue+>Idwl#84nJ8GEB5N%>FFh!cPE@=hl&%K:jRNYB4\$&CHuXT5!JKSiWqE
mAb4Nk bRlV@mk\!kQ*Dbd8\u=EePG6C5S9p8>X9\kcWAhnh$dHByDcj4K9nJ>Jm<qaX94E>qlPl*^S%>E#YGn>
>Gub!l 6uw9hCy@q5=p49Mq\1P^LQ%^KmwMy#h9y$ZQt4p:JZYI&JI6pZcML$=%:GEFw$iLZ%B@k%kJ=PP>y%:P
PqDZWM MDy%^L/qc5*V/84DMW/y\jm?@W5$>dLmuMjS%5#puK&BMqyF?CQVc9n5AaH#&45Myi!J5YmLeR*EQa8Z
/FXu9m L<!>pudh9B9Weq??%8!i$*X6BayFK5Bh*F>>cXp<#M6^wmE61:*AXb&Dn9ZyLP1ujCpK#\t6+u^Xtcjy
ZkSS5W B=QWdXup<tn+?8#llh88+KIj>@d^8=MX*%eP?8PI69*u$h$:ninFEi@mTeJKw/n%hwcXuq&n6#KEKTR*
/&b^9p 9DF5CT\RDCnYXV:!*S+bXwINm/F+%!e/NnDa#4p6&j<NHuYN4YKDumIC8Jnc\Y!y^Mqn1M5^&MNDjQE\
LcqmkG K#k+@LCnXmGtwwj:CeP:k$NNF4Q\iQ<&WC5<R5*B4wAAb6&BDhC5mA+kJG#DX!mFiW>#NweH4LTSy9/&
<XQn/5 9@dH^$pDh^Z5%BEW5Dl\$IdHpL*5bZEFtQnl*&l\8wF6t?El%^&pt^:KJqq&8/<JI6%Cd6BB1:D?jqKW
pPPk^W !F65KtCIdL6$lBV$GqLy::aXZi1A88ubl$w\wQi!VPw+mpm^*KW!WSE*J>K*WRqep6m:=JdN1@J=8Kw!
MEy&Al Nm=Ky+=*ARC>!%ALe&aFKEAVZ&W#@Mqn18Jeb+ZL%JDmF!i*uC^ZPB#Qw+Q&JXZY8XYMdDn<8bYTd+6=
PHMBRS :$T*&\P1X%pK=cMcHVdF>R+ycbE1S!kJPliVVyZ<5WM@@cHyabtRMWt64DQuh4bhcC=&EQmAb1yTQtDR
VCb1Vw <=kmQKH:ph*Hl^ZEYbPmt/N?+Y^6DAFH>F&dL1T1DPG$kRNebZe:&*qQE^XFm^M1/EjZQi4KK\q#&Sl9
i8#MHE 8jDc=RBL1iXCTQF/+Im6WWBmWiWitcSnebF4#4C6$yCTE4FCA4iCCp5myDnHae#*TKYASe%>VH\SR1nP
NCEY^S w1!mTic@*#eQ5<^t\!\Yqh58<G=DmT&$\VBLntLX<Qy!>1WnT%NYqqSLn9dR1CmP:hVmM4I\J&<455Ew
n%#Wam T^YZ@9LR?yJHHDZ+lA*5QJACMlqD\C\4tV1%?jk8/?yE!Vaw*EkmcEY**@JPbeCqeuq>EtNM@m1KlLw&
b!c4Va km#8CYuj+HB$SFa+=up/8qAVX=h9l1Nh8jSkn@qSpqwdb\q@4Z&HdQcD\RMB/>WS!jj%+iG^WRHjB5NB
j>\XVY dmEhR^nw<TE*e#dn6Bm>PlwW/WdZ5$nICu$uZ\J*+SN\yam%1/IQE>Jj*SK<m>mb?LXe5kBmHN&\EEp*
*/>YB^ ?i^4VR>m+9nY::6%$JnKJL+bJyLA5LpFiWJ?88/Mp8C*ELyq^yW5W<NA#BJ+nH^HI%He9:#*q6Lhtb>D
At%uYJ NEc5\:$J&D+QyEMe!T^at:ekJElR=l%Y9$@T46+Ray?p*<?6lI#HGXjGPRy*wk%5LH+uc9#8K&Ei^^SP
BR<=!! D+be>KmWij6F1KNGeSR+FG#P&@iq:6Fmt\RuD/&Bm*d^9!\=EaYXLi!u/c*:>L/#hY\5>WY1^Ky1?ed^
>N&Dk8 <icNyRMu9p9>&hA1p/LyST5TmAPRWh6pSKamVkF=wVCckTGd6ZE>ZTnPKeR8BynnpQCqq^WBK%Scq<$c
eqj&ZA h$t5iEN*#>pZe:HYpqZ&hmGI*DEK6!w*5R&G?mN*6*K8p/Q\!Sm!&YV$B@LPDC:4$<w:yLBl$BHlEkW/
=LtJqJ <\pN9/#9GAMThMX^P8eNGmaL*BHTyInWTuH@4aE?G+@MpGGc1>+e*99?yB#pj\dNP=\?&qY:ItQ:4htc
FyN>uG J*/kl*AmKTRGZuyRV^5XdCtTY$E$C^m!HIdlb15c4Ku6$^T8qTbR6jLbqQqyNpK9kGQ9eqK@\4dHFbYK
yF?/lm 4PQ9YH?yJ#\!WnJy:%w&Tnu>n8p\knAd4?=8cyH!^w1CL<ue\lSeCAqX?/Xmu:CcIlmt<cZk?KP?huuG
cnnpRy N9tLY>tGQW9cG&#jTnH11=HVpFt6mL+b!kFX:BG9iNM#KhFQJNX%e=:b4FJ?MuTA/ny?<1@Ipe+VJV^^
ZYk<SP =P+/$Eh<Xtd>YE!IXeqZt1!BwQ#Z$YECc#ieRkYE+Nw5ypm*ale4K4<mkEB&?mBKY1M:69LM*ddJI11N
HtC*18 Xw?98=&TbZ!m%#5>Vw%Xk^!dSq@%*mL:>+!XA>H&XL<ItRDJNCbc\qV*tW!8&Tpn8y%S+k4>>u+Z=^4c
+nG*a: #K##k1=cYk+C%5ytH!*:DJ<:R&Gi!ZaqL>!&pP%DE=TACm>BRVQPK6e^dXEuW>d?B$b&Jik$J9YIdB>Y
b<jjt9 j\$6!j9chldnqN:*tb%QmE\Hn:FW*Kw%\kduCttTi&IXiaJMT?%dA6ydKt9M^GAJpP=E+?lE:9ZbmV@V
dYWw=a B@1!=18p/^>^C?RVp:e%K+w<k\E^4ycyS\F^qdXa@J<<&@Ld4M+l6Su5N%yB1?1^q&@?:Zjh!jh/\Q**
/nBaC+ ZSjnj5>d95:5#hWjeT5@KNVWJat%F8W$HGNe:uiqNn%tDq9#m*!i*&nqjMk!G%5dhBj!1ZS^1WqtVMlh
SQ5D=6 p#IjyKuLM<a&Gj6St&k^e\:SK68bubI?E<P\*%ykDZkiY9Q^pjmt?%*AZbD9hK\dtiQ9TA@@/iqP8=LG
cmD*/h HEYGSRiG6*Wel/%BW*9=l/:i<!XQ%R8Fhjd$ZY^5t=X@l?GP^9HZ+K@9H+!j6n5Z6mu\$LJi6p?GH:I+
jJi5^l h<jdJ*B?Jda*?&An:u^B@</N^aIL?5H8>=&I&ua5w*uEZcM1hmcWA%PAlSPD>jNy6X&FY>tQIAA%T$8>
=JFuT! !B+Q&:qmuVdS?e6\titI^a/aMnb5qH4/?uw/&?qR/%^8#!uZ=nVPTFm5a#@cK4ImQ&VL<!!$kV%kJG\*
t$WI+Q <TCl*KWZb#>Gb9FNWyV8?!XF\n^?=&#JD?t=B:EVZ&Ht&dCm^VReW&d#u>daZk4K&qaa9bl:$G<w\S$u
C#8EYL lXaYCNAh\P=MqdXJnhIc%B@S\jBYT1SBwJny<dVW&qn>k8Le1GV1>PLkI6LRlEp1Th/lFG\Ai4MN<e%5
\P@nP& /*wRppFemAp$t!LqBu\wWN*Y*!=!$NNpBDncELdbuJuCujdFdL1LB&VcHiuS^$aJnD@KdCTFcT*F9ndd
mD+w>> #<1FID=:8?SncPWLY>E9QlJSi#CHeWa1#V!>W&8iAqB4I=Yw#6kS8hHw?T:%&hqjW<Y>Zb*yuj5GWS6e
!bKLJ^ jtT?SS<9Kc!J8DcCkDM?9tZ#b?$#^T%Ze<:V%uBCdMm:=P*lRG@jmJHph>6G5%H6H?\YmJbPeM+G\t6y
8n\TaM *>t#6ZN&JA4u*bjJ6ld5VYQ5iq+hbn:FG8Be+ZCX^Py1P<a/:C#=+9W*n8@K>y4KJ\FCL@u!X<jbB\&e
:wiLcH >F<yh\V%P?jFVZ<>y9yiW@#bG@q4WdLe</5LNjJk<QH#q+Y?Fb/ihDX*/TK%$V@M:!d?uEn48J6Xwy>%
S#Ia5& @cQ/F69y%t4\&R>+/&*/4Lw:HyZ>nN4?^j/NWi1S5<DFM+^nHtZ1S<SVKW9cde%KAE+>?FkqY+N6Yt5E
45YeI* H/ju5=K<4tiB=Di6%ci6XtH6*9Re/bLb:%B6p8PkhabhSk&4%&GR%ib*@c^m##LpHXMV<^TA:9jB^I*T
Q%%%&/ EtFQJcY=B^y?P&y>/EaSaTy@y#q8ZwCa+Ra!L/ZM*\y>8^Ct%4a\XYZIm#=mP!#^JnabQ8jYJE1JqP!1
NCldqn 1ZC\D^W%G6K&q?!K$RucmCLKQ%15$e+/pP$<Qwy+4eq9PQEJS*e5W#TZk1?HqIHlH^XuaiH@qRq%aSn5
GH!iSY j$^pF8d>%\*$\4^@9aH?9?1Kl9@^h9=XJ9:Q6@njJ6V@YikXl5H@lld+E<**F#T@wPAjcMSj$AkB*n@R
dCPwKt @H>B@/uCXlkt<Dj$H!S1abnkZ>B@qKmFaWJ@kj<y8T5ME@/d6$#\u#QH\4!\9*4DEZ?k@?Q8@Q@K@q@K
&Z<m%6 +@<%KQ!j=HE++q@q<j@<MjkZiS\P?*>V\@?*y+dyAFCa!j>AcllaG/=CJVqF/Ew9R?\uDt8yhXcB+?P/
\w&P1K P%MR^>4qZHI4qK>Ra<4\eL:Jp<*<i*T+5y+cPEV?@+$PE>MAD!\A8L\X/q!nAN#c/jGinjmD=\C<>PEI
y$dmjZ YRy<NFZQkTZPM6>WFR+@kB6AkpJ^ddGV1TYdYCIuZbN!Ah^*K8bdulCNEHjKh+j@y#m^FheHu8YdQk/F
GC5Xp< #NqBtH&S=NN8MYVR=+ayQ^u1GjPCJMWaeEdRWl6CAd+kKGaub1+VKBqN6hReliRNjh!q\6<+BY=#W1e1
&ZPhTV *ShRPbQMta#yde1W%1ha@Pkqj1%8S119Cy+ZZq^D4w+*C>c18nRKDm+K*H$MKFQ<\p&8RDM%Z$YnKcCD
KKj^5m u$4S%I$#bV4n6dXlb%^Fld?GWjSw5^eR=Bca%%@+tT1!hF&N9/#jDhmhST*+@cJ1Y4!1TPV@1Qpta&ba
EISMhM QKACI^d8blmiMtnKy&S9cam9jP@>C>PJqkNhi*+hhZYT/Tp<D%K>T/Xt/md%bVP?R!l@GiyIVDKRFDTY
ad&YHC I^@a^1$%RlwJpT\eE/LRX\@H^^6StLP:k#!ItQED5\tB184qKEBQQ/>@:6<REw5V9^X+QG=BuV9T$CVt
Q>:N\* yl:hPPXZ$AkAdSw@Y/c/?l=y45kZM&E<&<jVeyYuaAR@H<PeDWW@5R1qGF#\1Gk>!%JZS^=<ueqYnk#W
dH>T*% YButQbZue*S>6WC=IaAR4TPNq8CJZ=B!ACVQ8hPFV+\KGFMa%/n>my6aY/iKMlB!<nMG&4>6>Zp=<Z$w
CED&*G CGmRpEtDhaeEy6GYGDR<jJL4N?E#JCSlVe>RXm4A&SdZyy*@QTdZDqVJR5\#md#SKX>$A48CiZajdt49
XnaiE8 YwaTkQjm\<yu+wudYQbQS=5>>uMjbB+K<&^8bytM8#!Y8&<%1h6SSTG!Em6@u&@M\/NK?l:yAmt:?EFK
8aK*qS PHRdh#W:Kw>jkYGGc@6+LnD!5<CkAcKBm1G?kLe/b9!cWly\?iunW+1IAb1$y\%16t<?q5T+MEi%I1jy
mQN6LM k9tww1J+TZy*&P?b*<6L5CLt=CEphw^Xi=#A!b*ABk^pVk<JhuM^?alN#:X/T\^G<Vc@iMhWnJ9Zhw85
-A?Q6/ 000c9444c1700110333 Page 427 of binaries1.zip
>j!PB\ QTw69nm@V1*Le4ZP+S\EMBI#Q1%MW>Gb+McN@n&Y&RHbVZnC%t9R?5CeGH#IaX1uTjakciXNYy#RJAG5
%JiCJe FXTCi!5#<au8ebKGp$HYpEB%lnNQYTR^4m?N8y8Ib48ZiLmE@Wj?GTAB#%!M$FlBj<:M#!@>BdcEEA6q
VneLtJ J&^=TJdNB/GHj89?/Eqi:w?XJ$bQ1AEpdcVKldd$YT8n?e:#P5>5LC#Jp^dCZNj5<m?ERqe9=LLHQu*M
h9d68^ \L>8!ShbSAC9$:pqpL>V8:H1nWM@MQibV4bFVZZ5FMa@CQE!WjV\8FLTW+lch1/Xby&<VG+QBtwyYV<t
^^1F%Q +@PIVch1$Ckkajey>hVpj#K>IF/aB6dZ*&H/M8PXT&Kedi^XMR8dR?V<*L6//by<49%MVmH:VyCLNpXP
D#a\@t 5kRYYJ!%@#P\8N>8jMa>cl/*J8F!9##VYYW6@b8:J<=aPJD@#JDtVw=PudBDl4qbK@YQl>uXGapW9cKb
^+nt%8 *Zq^Nw$=ilKa$l4^^&YqG4Tw14$=Ei1k5JmpyW$FIu&d:lTlKHCMp?yYRJN%+u#T&4V6%I:Xk&$@ujcJ
%R+Gbl Z*X5GTlmKLiD#PNJYBW&!YA:PkJwD+<S6aGjqbNMbuuFDIZJn!<p\qQSM9#a#^5cnkZJ?&?nJhFGZ<EI
iu1!&d y&h:Icj?//y&eV+WkF5#cmm6*A@:cXy%lVCNwn9yA@W=iISYIQ/qH6=Na^QnntH?<c+aMZ!nS8$WKu#1
\p\mMl !eXF1RPDCk@Qeq+^FMb=^PPad/I<jZ&<c4@K/6MyY&ZKt<=FNyN9c@kuyWQQL5!&X1PYq9j^ceJ+/4^$
ZnLu$m &X&cMuYcGlAYN*WKH?HKR+FhMA^Z#9hpL9<c!9KaIiKn^AYIet<#VRt4nT*wVwbuG8X#ldII6Yc\5<jL
S=!>H$ lKGwy\ISYmZN5j^jN?hq$$%JEG>Km?@TpH#B5K&qD=4/KG<>&>eDNiykQC9K:u!wCZ:Jaja1kJ@Vi^^G
kCET9h ^YLd$J9IQ=F=l^duuPdKyu:?JyL!IPM6CSZ6=#l?+ny/&<A*q<*P:y\JWa#e@GXel@ytk=<XhwWeVEjj
ey5BeD $NZbVCW8Z@BbYl&<nln^MXiRPi9eE9=RItAV$bM&<B/9/N6:H*E1/4D=1AZFF%F*+wKQKqyhBGmGcnl$
D4AY4k cKwIR6G/k8BtSR<Fw??CdTc4eAFwD:>V%FuS<kitL+K=t&iW6XG>D$@=KXP<nc+C4B@\a9*Z<Med6JRT
jMQ%R5 Y9jK\dZ<>$?bBZ5qT5D?cS@<V#@n4F$8TTYZ$EWdFqnVjj6SYynal>Xjpih8<Rl?jS*=W4W*Snw+BZiq
njuAdC uHJwyVDP:TZVt#e&?MLATdHAY4QZJY:jGec4D+SL*^P1QD5AHlKDWNWZE@kWt5t<SkVYD@jF&9eh#@Mj
y!LwIe QlK^=99c\bWhD4#/jjed@ib:JeTTm5#8?W:V^=Zb%Aie:!DVL<Ftqt#jiE88P8pWM?VcD<Xjb/\cmnQ@
LcPDe# <Fi*ku*JqQX+SZ>#+H?Sy=m9=J=*Lq9**wn8aZ>Ej=>m=P&PV9Gc5G^>**P#REn$<5u1y!4JbQIimA%q
1LFRQ* >jWE?+TcpN9N!XN5Sl@T@6jwLD<Z*>u1SjV*kc\aFH^H1Xy1E@uXnulqP<8YYKN9!:htkMYhwNPjGN>w
5ee$Gj >#!6nHc+qNbF/uy+D@SVXlVE$tpYqkEyRZ1FV*+9\j>RlBP+VRdKQW$Pc#WDt9T!l8Lc=?PDawjblK:\
^K^yyM #IJl#1PkCkJ:I^WClbZeSNCRqF4IL*+XhG!ITmCVBEGSkE@wD/KTZM>\PjMV4aMRamAaXCVytWa+tXcL
M\VyI6 H+wb@?Ek44hly4^N9RL8tkM*%yR\&KNhR+QSRtQq$kimunXwZT5GWQ>+:8S/kjV^CmdIdM^@hJI\?+#W
pCnBKK mHSylcDQuEZ$&pblSnHX@#AGHBK:1M4k$!@\$aWFBS685BF9C\9BlpA@YmG5c*V1+1t%e+h>qGJ>T9FX
W\GKAP CFbj&ShSn6kD=b%dyLK$n8/CID&EQInjntmkFIMq^4tlRDR<DG6tTYdManbtYh<\iN/$%VNk8YT+HYJp
nI&cSh &#=h1tA%1YG?QS/%qY1P&dR\6#bJKA^>ap/dEJ@J5qpCSete@1DnFDu6V$X9w\$Q9ik*JGk4BM4CW1$q
DVhcp4 R9dQ+yN5/^&*d:bK:nAEC\qNdX1hiX69#9e^L4a+66eyRkm+b>PIPX:JecWyeWt8Hu=qja=Qeq4eq=MB
S9XX%h mS&RI?PZmJea!SGI1G<kPl\%?b\q#!dBJM:5NCu^^M#+MHFJ58j6TRMdj8VuZpMt1/!Ip\F&bcY8VZlb
>Bam:q GK*KmSWL^<LD9Wu?+ahAbi!^!#FE#iS<Y5G5&Bc!&6P>R?6JXm5A:&Whc+LGb<SFe6XdQum+%<?6MGwh
k%CMBl &%#a!$wFdV>p8ZdlGF^kumeeqA8wNcZB/ZEQ9jZD5=ABD#8!ZChhML$cjMVHQP>Z!ewW4kuH4PiZl@nW
BBH%t$ F8E%5JuCeu!K%!E+c@B\m:SV1SXJ61V6:h<:BZ!Dy<Pq^4ld:=N&q4!qQ\?#QTMKl/5*PFFPhmyX!mmF
J^KptW %B=!$>#n^bub$TW6MISQ$?1S48cP<h<:Tt#jRIb9\$GKCNCy\uIy1lFjbSb&4l88w^hXd4lHJnPq+Y&b
d?4R$% >%#Cp1!GK$G^A$GMi\w8iaFu<S4DLYChW^u5Z:qX9qD%=pYeFnh\W5PMXAp*id*k!^P4c8BhA&*i=EPP
!jTT&p <Zc?XW6tB4=y69bn>!:FQ1F?GuaLnhNlGR$E&^%W9ca<GVTk:Et$DH8w6#G!FC^B<h+M!h5#1$<G6*FH
+NVhld HG#RjpLl<<HX%6ZZiGJ#6%A!6^AGFDSwK+dBKjVtt^TDeH\d/>%X+<T5Ljj/Y/jwl4FVmBJbp6yniR:p
$5!VF+ F$l=+&:Q=\1%h$iuID8V$e6eheunda*!biTA<6k6hmQ^e!#6QPd+#JXlLSj:BimFC<*h$?nTc?!WwPnJ
^hDj+6 Z6&S=*>C5chm+yn!wLEiqCIBa*PHX$E$qZ1Wdh4=m8G&$\aI+u+YL6i6\%!nI+%^Vb&G<6XRSa6Zm6c1
Zw&%=J @AL#\%#Pp:@+i*&HiGStRLd1aEd9Pa5RdQN!CNJQyV^6hW^ui4JuKlbFtiWmTh%Wci5+YL?h<pEL#iFT
@4S%Y$ ^GKYMlp\%!QXNDt69DyB&kFViS@G/eQEhA1PwD1L@\$I$$t\wXe&n:+4!^Ddq&:wCjwkkG>+ha6kP$^c
nWBKmY uVG^*w/#aRT#5?RSW$t8=uba%*dJC*LI9#WP4>W^%&nGZ!Nlca?*QnIdmMHBuJn8+VFk&$ESXLGD\T@K
jKC\i> Ry1\HMq#%Eplj1DRcRiGFVhb1kRB9=VR&8@5BeI^W!SHFMw+k=:*plN&5GilIec=m&DiT=MJTkdJe$@:
PMtLYL ijP#Z@w#bQ:8%A5ljtDiRbVA6LWNq:1:ZDF?n1QX64uqn\jZ@R@BVa?tKA!99=wDjn^t@@JAnZyb:bG<
:W%nGQ =>NH14Q^ZFp?%&Vb&%SiFSlh#$P@/MZq$5p&e\%DRR+Bqu6GnaJQ5Fu\MtiRuXR!>DY+@nF#5\Ru?Hb1
<IdW!K W\5Ri&KXb6AWm^cp<wETKWZ58#E8MG&W$J=F%+4HNG=5G1p4&Xy/?mlFSukM#D8k^aZmjL\\LR?@P8<J
un\yj? Sq>wl@!KcI^8E9MiH5\!mSie9kaA1!^bV:!TXc4*q4$Tt:\E$%=mjSH>A5*Swt#*@Hl:P/VbQGTn@P1/
Z1+JLy /n89GQN64VN!Q=>GHd+mPBSpk85Q=b=PFdiXQe?Yu*:HnDp6P?/\?>X6M/eIQP:i<<%M=@i5?BLM<*\a
\KF#n= ^CDD^bTZ1=Ju\e54hZ\$QuqKNL9NFB#w4YFZMb%y<9t+j%/&u#%+M<kYG=Vy@iVPp?>QkEt!>&>d$tV1
qj=W$m $lTWIh=?Vy69k5$>RJ9D<FIB%+/:1iZ+PIt9#>?diJ&1u:&<j=pEe<5=1KZua>Z/#HMm#H#1W<1mR8D6
GDJ1Xe WHWdSEAE+BVk:#y*J>kV/Ceu?ubbMjALdHZm<pVM9FAc+D:5FZa=a/YLC&S\*dFQJ?j!IQ4!nIWNG>4y
i$QLFH V+D\q>H:TBDm=MMKn$>6R!@kl9$RblWnQG=/namJ1JTW%ZC5M&iN6QRqaZup6?$JhH#%5wtSj<FAbXML
W#!mGE u!d1%dVbYW9YmaYGnn!HL6Xh:&HpbeXn@#jyik9=pd1Jt&#?b:td#b4XVu9y!ReIq/FqH+w&G&<nkSVP
>Ab/1Q SMEP#/duZhwe&Bc6c8i&DCjquK&V4LR64#Q^^Q5N@l?djHVd5#LA4>4iS1luHI\6yt/iRy\IP+VWMd9^
m>1XY4 q/QtPLa<YSbB&CS*tRqYiY1>H/&twWMjhhHHlNL=y+uFHVX1b:KydjW>Qnj<mn!\8TG?WPdVY<i=>Gp9
%TPcY5 BXq+n\:1lN$@J#k\j^?WceZSK=?X\dBVt49#WwpkuPn#GeehnSEcc8q1Aqwt:dK:#68AS>w5J64Q:kc@
h\+l?6 hn&di:A1=ta8d9J%\hZ1SAQD#bCB#b<tHQCCPDj:8LR9Yp6bI*kQN$$?&YE:ZKKa#Ga?!kN?%KANjTZy
L=P9q6 /5/<6LAAwHCQ$Zc9!tJq!DC:G+iFmVb$%C9cbL+%j\Hj@GLc@K8E#eL9tP188mX@C$lSte*5ie5CJTFJ
E=C9Hm jwR@!Kde?B:p>C/k6D#!TqqPSkl?@M*@qFwNwy@+:1A#Y<E#<c+CI<wlKQ1keikwVE?5GYZe1l?=i=i!
NHYNjX JTI?h$LwQdAham9cdbjlYpPacVQdecPiN*iw4Y?a^8:5+VtZQVH<R@*G<iV$X9L$@eD#N&?EA8@86Ck:
Xh<&M< jVnb>mGNhD#ED$>X$^q*@>%Qj*85WyFRHXYk#lS/:MH?/JYBcD1jS/ER>VcGAuZLhc95=qc#%kd+JTDK
?iGMNa JpSEy54D\<J<$u?KC!DtLNGFDqi5:Gle@/DY&DG\ha%:?X:q@98C=ENiJ/I*!WGK:tbl:*JTQd%P*%wC
Mi+RB% &=&5nXN<=FQ/eRLC9?SJ5R9!*clq6TTE+RkpQWT4B\JLL?hXJ>*4DEVE@/B+@&jq?Q<bGY6l*9@?RuJl
&R&BF+ 8PA@!N>\kZ?X9?H<j!%@@^jh<F<W!Z?RkZu@hTH=H$SpZwG@wRZ@SA9?Dj&HXTQC9EJ@RTQ+@*S6+d?k
<TVi:c ?j/\wEWaD95L?5<CNy#*L@A@C6l\?Q<W#jhZd=uRH&nEj^T\ij@:!>D@n$n*j^K\Ej>R@91jD@K@C6mC
CBj+jY @:9p8=j9J$JVmFTC8Aay<VQuAqX>XAL5BbMHthSpEa:c*ACqYFn+9WI^1tmy^6:ARu?JJ+qDjdmj@Bm1
?$D$N$ GRT%N#^+uRj6AMFBbb&jFkj$GGlnlINqRjYGlG!njDN!t<S8lQuK?#ubSq>DBPmXkeGbqBIy+uF8:bT?
@eZKHi k:*:NZjpi41wSWeaKB1ITYVR#YA<teZ?EN#JcaF1P\8&D>^S<a+hQHhR$A?liIV1+JlSuSXT<BqMnV4$
4MnN&J Dp=8N:i<Bhqwk@&NZH==nFup6KCC6@%>aGC=\A<p^$lY>aewHLPT4lFa<hM1#lBWW!likB1%bCY%M\Xw
jt5#Zi Ty<BMj\a>am=tm*?5#A?ZtM*HCKS8\<d6e<X+=aaTT+XGN$a*cFqMaQbbuai$V/9+\n9>R:EHDj/$yRE
tPMVQ* btFKA?Z!k/biqNYY+TDqyq5=bQNRS6%aMj#eJkpZW4*&tkatqi:/1M=tSQSB^mwmbk/?L\BPt8YkAEWq
WedbnI lXNAy8lwnL5QV6EWpu^MXeaLI<EWH?V9+LhV%h?Vt>MKlc@5kAC+%mYR$Ay=Bpa^MYRPNyV1y^IFIFB8
?9yDW# u%S4i1#N5y4TYbZwE=:MuydSNWkR@XpXpDl5qQyk9*8&>8k4ZC51p+E9lFKiVdVc#8F:cH$/QnSG5wC!
!W:TJ= n<I5/4Ll8S1W4yIGq9T6qJH#qCpM=$Y>&VAFJEE?&+ldTP=nJJDZ:QJh9X$R$%BXeQ4iQcDcm4#h#y$a
-AMC++ 0008de2eac200110333 Page 428 of binaries1.zip
VyE61W 8a+6tm=>eNZHXpQlQq\1X\4aTNZZ#M?$FR!pmudwD*Y^N/mY9D/!SpGL/8YuNPCQy=@@Q?#>h%^Vd=89
mRPjJ% DhMTYlKKkICw>E+IcXR%>A/lI!BTR??I1KnW$H6HRH49HWTq>>+SSKV*JmJmi?/b8Yj&:Lq@Q5M:998h
eMZ:bX @i:Q@t?SD<jK^iJ:pdYP/?T<1t6^C+\jt5E$>/LB$IZYY+kcN^9ChyCqD%@S@8RXWpFZ+p+i&/$p^Y66
5?I/WI $I@&<@Y+&H8H>PY^@Ey$?kJ/$dh1qVBF>NdbWZy1TtNRuQltZE>y4e1i^WjK4hd!h\!u1!@ARlE?KXy9
iRJ>y+ V5h6P$LJ1$&1aWJcNtFM15!BXcJSqn+6VN$BYSmB#6y:$iQ\JJ<G$aEdPR9ihp?9$WiSEBh<k$NXk^1y
<tbX1F H&XHXNMa@u!b?eFQh6>\*/jlX9BG84?*#4%!?Y@N6h#9E^jYHtK!JF5C:Zjt:VTW!it1mIP6@GaIZS#\
tMZt&G ktnk8k>?<BY=pLJ=6MAy!!pNMcX<SNBpcbNGeBKh1Ah46^Di&=tJ$H&LB\l1cR$$bNbVLVVpKlbK5T=K
G&Yj+4 !WaaB>5=<TZ%GaGY9B*9K%W\JcQ*cW%&d^ucPpZY!\K*b%/RPl%u59DLGd%bWqPIeCSy+J4#DnH^=9Y8
%?G/TV dtFTXPwI9+GB1&n+ndRt4%:nTBCNwH=9^$&9>nML>MS8ePt/IK@kVwbFLMdica/#RLhR9>wXRyn\Kl@V
*QbMnm !WKj%mGZ*^=!hYK=?@4PY*M:S*l%w&PKNMGD^P=8d<^ey>D%wVlX<GtVT8N6jGjaFt#Imq1N>&kK?@mc
/deCQ! aa$c@M$Z*u:!*F6apy$dSG8BtDBKkRC8Y!teijlCC=Pa^=BIhAHhWkiLi\t+bnyaMCmRJTX9VuQTMbDn
Kc/:K\ JByaTCqwXYJT#ACuytAu$\ZLt:!Nu<#WHD\&p\#E8$q*%A*Py?nj=<wZcp+q&hTZ$9B$9!XWyqeZQPV@
+!/tPe =5F+@a6!ZP=6ELPkKjqE9Nm!$hjBNEFhV=>GCY@ditq%65k+q4j5A@jWAlLbjY^=&/RCKK>hF:VIX+?$
DWT^1h utmSMmF?pk@EaeT%XR!6?HcEmw+AEH?K=:hK49TZdNX*Vcc>TXSnmmuYym?cSwwb=V=%Ll=j+hatVekR
by!+W? 8PeX6=hR##Kn4eFL<!M?qI6I?R#HGE>$DZS$eZ&TD*9<phw<biLm:4#@MyQ%5ZQW>6$jR:5aSu$\S\%W
ZSJ5D5 kq:R6S6y9jK1*59yZuBm@BZX6DtXiLVWAKN4wlAul*CQ>5mAmkWF$#qe*n:HSLXtLat44nhct@cDtuXt
iY5IeK IuFy6$1T/ReXHWJQb^?u8K6iM1yAlS&MLtP<Yk8+PP/LhDd^bA#qee$5&hB$Tyq5/PG\=Rhn8ZCZV=pp
A1#>+> NI\D:D!!BDejZ:NJ/L>Z9i&LQ$#\Fwy<EC=tJ*lt?4:LTWmYW6TSHLFk<1b>iGT:u8Gn%A/F8+Hhe9>$
!/9l<C L^Y8T6calH\XawGSD6q+Mh9hyJ\tB44!cLp%XRDce9d1&9LhkBe4bcG^9/VFje15Atdp?A!d=B!?EeAh
?T?ZB4 9thCM&PSQQ\@HF=b>tPXJHCk9GR>Z55l!NIhpjXjbDZD$lyXwih6Qlpp5c4Vd5=c#yapjh<?%L#!h4^L
^MHuE: neQhqp6DJILEXiEhRwR*c=ICjP<KD8CR?6d\\NuZX$8/4R\q=iu&S^/m<>??i9H/Q5P618Tbhl*By^yq
I!!D*D &IEnCGHHuEa4G^8ZlIDiy+/FGbqyD+/Yw=4QX@k:BKTlu=*i!pI*Li+J6B%akAYT&*XW=:ej8iSjV$\>
PMSp^y jABdEJQd91>DM/9t&##wjYm>tTekZ:MN\^9LNbT%hmZHM4dWBh=6KGnA^EMcI4Reqk1bM8>p8L>@kY>1
eM@6/6 99pm*6XCeQb/ZL@k1nEibi:<qF?WXK:/<IJZ6hRBMGy%N+mq*@iJ&GFpD!Q9yymH%#M5pW+q!H=b:HYj
\6unDV 5Fu@waWw+hNHWhn&eA?K?>>>\laclhchI#5LI:Cl4MV8>59=ecd=eQ*qh+q>!:u&Aq>meqt?nX5MinAq
$Mt?YV m@9hh\6w5$@!KC$^ZA:lb&j6QC%&E1n/wQj+?<QelbqG+ebjM!?hW/SXdh@pAGWTJZid*MuH1Tci9b/^
Pw6pME yNiTD8EDB!5?A:&wq^T=inQ^nC5&&THdF=@\WjBS%Ec+N%^p>4*=1a^1>AJ#DPLRNH^K<6!?pjn6!+\u
6=4A:8 H8&#C/TFQMl4k8%9KWV=1FSh4^LF?I$GKQCRuJtaZ1<W@ED%KaS\yK4pLq:$tQ4dkeRmLNh@!?HtEuSV
duEiMl 8j%u:yJ:>95lMSPu+&e/pT9PbKKj/HyG#mY6a6K:&+Fnub<!dnd&cd5W@SwlCASu6qAY1RuX6ja<A^/&
9l8Z!i tkk%:jVJLjRdLyd^G/9dG&1Abun+V*ttYqqQ*1@QqSZ!R$mV%GBmEQCYdKmcTdueaqjD\@YqehY!S%%G
y:Cjw@ H\R/Wwe%1FmZ*=P/j&DF#ARF@6#YDXRje%hW1NuQedT?dSqIY%TbJ^S=$nm<tA^JtdTD/\mG@FwbTlu$
D9=iuR tVPdAYWNRMByT?48B55a5FQ4:EccpaBQXJe^kL>95M@EWBXc:/VW\NZ$RTm86n^8&n1\ha#FM>Su*BXw
&/1c^w 5J$ML5l4hL%IHmPcX>+#PKIAeBCAB95c4d$c\I?j=8#MEK%M:aw684dVDy??Fn=:HWd&wee1EGLlCyw!
&JbBu/ XPm/ECG\l$wed$ka<!w+DP*+Wk%WFA5&cPLdNBS\B%HSR?\ZEh?jF$K?8bV$81G@By&:Hm\F<^%<:>j+
GK$K^Q Bam/ALK9FpSANZXq?*$/lK8?nT:bc:L*qP/5&FC^PAIwBQ&4je%!Rkj+?ph\>mdq@QyQSlkN^!\euIG:
mbWKJB bqcGl#K@lPmJTN?FX\41Ypjy>p+h4piFeC9^<4Q#6huiL1YNH=dm/:56PF\W6XjY*#8Wi5kMEq:#6Fk$
@<c#=Q E4dwX!L#1ATtqJjIk$q9?C=beD9KDLXb5QaM1NX#Fy$hY!jW\6H49SFDwLyXbeE6HH\p!G6<L?E<^5#Q
DQ18@R &W8PKp\XhAVb+uVpi*Kh=PKF:BCQym/H\FIY6%GMy1hRZybq<Lq<aDt6kyI*kdYAC19XLmTuDQ>kA\j1
W8PlPF c5M6#$GXV#XQK6ABcWD@KF+Xjl%P@^%dj:?k9wMRWw/ll:#:KRQcV*pe9ad:ny:ZyLYSEjILn5pGV:py
Tl5X!6 XMFyA@9dNy:!uA$EG5Q*E6TeXJ/N!i!VeR/B&np<nPR6Q9Jlb:uKHmI1nHyh*4&4XX8MqpjaL<e+*iP5
AG5D&* <jWHPl>8WdmZA#&+i@pDmc^P#kZCKc\J*K&%&RZplc=ZqikWWJl&q/qF6qX5e=6!<l446BlD*5pBMy@K
P@EPWc 4%lTjAZpajARET+8Y%eFmlkPNtKHLi?mI6t<ZuKH461%Dp9:196Bi%ce/:je6XW5Yi$<\u+Eue6X&w@^
><lb%q Y4\J9wXSAGXV6bIR?B8RR>Vm>$^*=VF4puiWKe!Dyi/Q<MpXeL@qniXCyH!lpa9Q!cDLGYcY>*$:8NNL
L$=+69 V5=aa<#aC>p59MY\bkkIp48IM\J4QQ:T@bDil5AXkqAe>+BW?K:k\*=R#DM14I$Zad?Qu&\K4+C+J%b4
ibCla\ kh*!Ve>=w&LmeN>:1%\+t^p$b?YQbi\t8IG?#n5&djdPjNJ&bE<*S!Ade&ZACbYiGX6pSW\AKI=WVmk/
dAwN$j DI+9KXN5<N#D1n4c\n*%%SJCi5%/NElcM@q%GHT@Z6t8RRKIaL+tV+K8CE?YKL8@JRE&/A6S/AKFwN9u
&XKXS6 lNwVMSlZ:wttuDa:lSmJPV=Qhjj$d>$YY/\a<qnHEeWpl^$4C5#AK:Yqaw5yKH%CJtiXBZ=QmGm1nGww
\Lp@D! 4VT1!n:5Sb84JLhc%YSBNSt<&q=Ipl6H/c6q&M>KIhelSIKt>NXPH5ME6^qNHdXMl>jJC4TqDAj41HK&
YFVE1A S6ZXP$mT=QG1lQnje@k5P*cNZ6tNS6Ae*L69i9RTyL=TK!CSQNbtW4ZS!9iWp1VV$9EcbeVDK/PuPLQP
/XQ&lW ?/WF:%W:meM#TPWj$wJ:F4B9=61pcRM:W5bFLD:uJaN4a5L%G\e4aNRVdcwTM?Q$XkC9yep&%^uu&9Y<
?^AyQ9 i1h/+pl<T*qE5qQcdJue*F1uIA>/=pG#cGuVwy5wB+PdB9k48>NQue4A>%wGKn$XP:t5F^FEBbkP6$Lt
CDF\ey u1\Q%m=DuS95HhFbF*Vy#nJenCQGC8M$/9mI%EI^mGeGR$XIZN6cG=Tm!P5R/YdXNqYMIDH5Fiw:H*@n
EIwFyB VCdkSyi\ZT$DBH?nTQRY#6p^/P&yp*6LBGSR*b/aEck\F^1S#Xh:%1&kE5kCVtybqJ>>8MXTb/j+pL>L
BlR:!4 6pR8Ju<ymtnuLmJbSR/6St+B4R\uLpny?b!&@PY^R:JJep!eHDGJy%qYemhhyQY5^ewPiDAijVXhQn?e
B8Wphn tG6A^c4Sc>5:*I9S9DV+!1pbLI+dE%ZRVe:1=lEqFGbPK+iJGwmptaVBAAE*LSpH8L%lyQ^16nN6G&ID
y^??w5 SHQd8F45dkne88=:tL?nJV%CnMXV=8QVVXe:V1PjA@:!5ShHh1!8euLdRHH@QPPAEAY%FBi@4iNk?n!N
<qC:FL Ph9q\Ea&%ZG&8Et&Cdd4846$q6@aK+y&98D8PX>$!$tHdjGGD=#D\n+cmTJQdH!uPTZ!Fjh%iENt=?!D
*PFZ8p Tk\mBu/B?5:kKc5a^ncIh*%ph?c#8judc@RwAl%NSd>wjEy?J?@VT96uBIhlRVGN@6>nZIhn=l+!Ya<>
ePGX1! GTmbc!aYDi#ZK5\C&q^aFN@R*^tMQ#PPp4e!^IqHDdyZmq:k8w\PX@qm\kNX\1V<cc?ciPSLJM*TPd\*
K6<H&$ mG&YKYV?WljA6JG4b98hZKlp4YSw?jkXwP^dwM4BQG/99MD=WFDq1+bM9=PKe$Il%hiM!ARk:9CJ8%4F
=JZtpw ERnkanHlY?iyEp#\XdSPR:QCa:Tt&!*dd$TmT<81??6pGwSGqMadjQ#YZ=k$KTa9AFF=ZS/6$*m1y&Re
j5/l>y w>6uyq/c:cq*K@<AQH8P&#c/n/e\w%MCe/%//!c>1^%WL<1MI8qV8ZJ&#>b4?A#&48/PNEB*j:kpR$LZ
?$YJw$ dK*^+YuD4N9?LV!B^X*nQNdhjNnM@VV%HAYK=L:>CEM8cF=HCNeTGT@:R\ubY\t*#RD:%kI#h$a9MAG:
HWjbJw pky*JQMM/*SY#a1MlNITRui>m#j>yBm*^V&Y>ATbbJ#4T!h@=EZhN5p=jFwG1JB4iTyj<Mqw9jAWjye4
4IupDT /8+DmhC6l:FhDiaPF?Dl>9JRm\mNu^%F\NPN&=cYdE?@>8$1ptV\cS5#6qe4NPpP1P\&*1<yYcY^:c:+
T#iEh= K8KlmDT$bFZ^i4b4VBkB<IGDe!c%Jq=dQpmYm#SIGQcwt?kckuX#&#:bEjiw5HDPn*p1<ecW=1&u#T*N
n/Rd:\ ?Y/Q$y>?uqVNkqbQYKYdhiiXb&I8kmEGV==:SLAuh+<IY$@/#Y^aHtC?n%l<:WqqD1=u8B8n4p!&euj=
jRpD@p &/#+6a8!HYN9RTb^Z?5^T!*4QAp@#J#yQeCKy1/kGYBXl8tLieiQ?5?micu9E\1ADpp!bpACEWNB+@n=
n+w89y QLTaKSJ4SpQVXpiY!cJ?8>DnDnAF#Meba&@\#EdVFJlc*GZ+KPhHG6iaT&GtYa8*w?@:\uTlHHt*#yc!
ny<yTV :iN=ki1qRLyZ^wXp\q&N#Ty/1n:=FSad*!JInHDmN*qiD^VJ%4i&=Za%5pHWh4c%*&5Vjh5G>*>D84e/
nIBLqH ?S6q^H**>QTPWemX?E&9pH>S\Q?diG!+/F>:dI?@jcX1b?Z^:<Zm*:=d:P<HTNVjD@:?4kl^WjnjD<RR
nicWWw @*4\L\NF\pV?*pIECWPm@@/T/L?%ClGYhZu\6=>VBQa@#DqeZFV54?Tm&H>S8TQ@eR>ReiTq>\D>X>Q=
-Ah/^H 000228edefd00110333 Page 429 of binaries1.zip
#m*kEH D\:%L>V#*/@QJT4PEdDL$L?4PEiIZIJG@jc>+bilEd?S=knEbYnad+R>AupJGmu&P^y%CS1B@B&N9kRN
DC?SGR @%&qQWL$M9S9*%95E9V9q^wRq\udd^eLpJeJG$wE@l9/MtGDm@/P@w@:49+4?@?/%QC9=jH@9NTAR9#F
tiJ%$p Z\QpZ?!:mlRXk@@jY9u@JdZ!X9>N6jIp@TPC6dBllJ<nXC4KWqYTM5KTdI/8eVXqRCT1>y9DHTS^%kp%
XmTMyj TFjHeSR6T>a#In:!V%&*K+$YI*kE?a?FkY\6FT@\:ip%*>?/:FIZ\^%>Nwtc5ZIH4IHEAbJZc!N%#>j1
V=ZZ6G bbX/bRDkMTMYAB&nNZYWp^J8*5BeH5<\TCl@lS:h\Qq>>K=qjnwhFXSNXmtw*MN^DG*8iN@!L5M%cTt<
V=bcnI 8pi\h@%b@5#IQJ$QjQbip6I<4XGp4w5>Y9VFQh!!TLu9:H8GKALGi6pHp%eDGW=Wk<#FaF4*:puLL<<c
tcFuRZ uL>8aL4:<EG+#@&yy>@mIS\Xm6cLb*nJTBQB$@8$F19q*JF!<ESpkXG<wRZLbE=YTH6NtmCACHmqnHbw
ikJ8J& Xn&TND\CeRbh\1Q*jPadPDy%FL1p%aSL:%=p9K\ApMX<8NI$4lbb6CAC:KN#aDkab>y<+YtKduDHdwlH
8J=kQV eEl14#w^PG%hFa5qC*A=%DdYu65uLll9MC**&t^=B+/\5i#miQc^TT+=>+t>+#=?c&4ZwJB=^6u\QkC!
^%h+w! ?l/DqTCl1+P9ky=Tt1AQ4mG$\8e4WE?5t#\H1QpBPy/kki$jL+M@#Q<E!Wk<?y/u6K1FX4#@$e9a+==T
WbtD4m ^<?SqXXZ@h^:H$V%u@P=ulHmBAbAHC<#GjaMQ/k*#:pS#LdZM&4C#5a9tFCcn^!IEtM&!I&R#*kA<<C4
\M$+5% dVZ/*&^JKJktkXh=<=h&qL\$uK!p$YPLuSNk*%K&AZTkd\PEPMG:YA$kFZlI9Jm#aEGRR>w5/6^$e+*u
ERE*X4 :w:$^b9kE:iZC^8wLd?T<m>QIiq:@Pmwi@NAt=*F>!hLa1MhNKRKt<VMk^tljTdW6#5nQu>pu5ibD:5I
yYlCc= a#wb&8X5*RkGCF>kCk+mVYnB^>ql4X<wb6+n/mG^me>pYH6?9k@At!1MLYauuLpdJKCmBd?865cjq%?J
l9+WBA H^A=SMK4Ap%b/CR$NRjbLAZ4kVYe*<W5@FLkd^ui&DQI4FuFTF6hE*5Zt\/T>#&eWbXE=dTPQ%t*hdC&
RpHCP= H:B:KHR@F/c<S@mmuEHRq18pPTY8SqjX:mEwM1\#8Tb\YeZL/!94yKX9Y>a6IFM$Auj*6e\udyjCGE5i
TZIiI& /pEnuNQ!NQC8mFm/S==NMdQ4Y\MHm1pycP\GCwG5bT#Z1cH\B*bdR1*jjLY$GDMNA>5L^&C8S/pM&yCb
cT/QL: +nY<Kd1pXaR6?p#kiH&9a$cb1:pPhAmkDjX^>EeMWLtXtjE5?9bEX!#GquCD^#YptwM+lVImqn#h>u^W
lBFQDT :hPHb%ZKH&:#QJY*eTl\AVE\caZWc1/TjEHHb4*uIYQ65L1TYpR=WhaRDD9NVjD$n=e@q1X@p@6!tSY5
QNZNc< GRaZdtuEF1$YBP>q&M#$HdXdjKJ+e5YbTP4LBAX9+C6@latT:u+tFTPRw&%RVjLwCh41lk/u@lV=>^^L
W#QFHI mV/\ewtBd8naaH#eSSb6h/%#h!^#9AunZHtGR4ucLNE!luw1Mj6yp6%FMGbyh/?iZFTlbd^$PuP/ZDLW
uYAe$+ wtAaa<R$XQP8?&%hY=ba*tjcVl8tanq$yHLc<ket4chhSl4ei@yjYI49mqi<cnk+NCyWbHC!E5Pd?Ww8
YJP/ty dD::P1IcKF%J!:ZaIEnB6<Ay!>&N/*tuhV5mnjASyl&lLE@@/PDhqM#G@K*1AZtd?dm4wPT%c&uYTW#E
XVNVu1 1yKJJZ#t!%@ZKuT%n>CCRYa9%CV/b:J:5E:%kTIQJ6*8p:<^S6m@NAe/RLcC\Cmc=&RY4hk>^yy&<%$y
CyYuL> Wa5=4:yDwl+9WpwPXd5%&<kdTnJjRdQbQ6ebm^y$WTunhS>B>#&u>EAS5$K^ce99a%^DiB$G6SVtp=+<
?Bba1H Z*5RXcAP:<hikT>S9%/D?PHy*nGTSY/yV:@?JGHM/XD9:5I9QadXGMh@JhVG9kplwi=d6R%J4^HC85hp
^$I/wn >X9hj?LdWiI?/pcl:WMZy1jK=$Z<5y!N?C+CutC+<\mI/%Y^u4\FYRHuh$M#Ay94EqEQY8%pRqptLi<F
?G&\py bJ=B!W9idX#j%ceG%akZ!H^K!%58\+a\4m@jE@XV:1!%@R#lI9F<QE!NS@EW5uYhLIk>5VY>@1mb<+D@
Vp9SZ9 nYS?iLhq1N*:mu:nlb9ii*uC6cmG@dq4Db@cEKuWWdJwYS1K?I/P5WSXC\NX@mCwG+LAT&pPCY!dc%1Y
Z<HXq5 JWwD<V9AN8>L<N#>:mj6b#@TL!*9XG8R8Fbc%/@Re/9adKdYVmbhy?88<E$A^w!i9*CXhc#Jd8TPm1dj
a/IRKA 4*YY$9m/DBMKF6NaeY/@hL6JCWi%%SnFwRNCjN&Q1jTyEI@Z><$^+1@uGi8&nJuaYapT%>>ehNH9m#+y
tFX9mt Y\uPuceL8m=cS9iP%QmdkMu<kIuDVyb@wM6!bPdJ8\E\=hC%t8kKB^LjW8HK/tda$nY:PnNkq^kyyLST
4eM&4M pQd&wai+FT#11\w#wWG%PpNQ1i4NTa@T+epLXpuk6$p=G5C:6=WcZ?:q$ukFPJY+/<\Q#:Le#H=bbQt1
>\TZK& =Yt/lJe\IWjGy%i#Z19qbM%iqi49cm1G4/SqLVp:>a=+%wX4@tkm?^n:4Q/:BJ8$TR%Z@pL$E4n/wcnQ
8LAKKn \p9G9B88$!pWKabj$44&/5RF!:R\P^<eVSw+wY=pElRSepmBC%@HN\/na86qEPVk?ZDZh:El>=!lN=b1
D+alqu CSQ=ZS:&6Jb1cVdE81nI55ENaE:@WP>?^NihSZDMdZ^W*$AEI+B$m=hDbtm96Y$9De#Q8m6*PljyNW\N
%DH\*p 8u8E/>4!u/?/MWRhDN\4MkpnY*LN8<6%?p5F6$=qY5QH4dGjmbJ9dXaW!\:FmAYHBBAatij9>c:HLAnj
K9@TjF BD8NtJY*!T6hwIX/VNXk%6R4PQtT4:J196aFTn%iT?F&aKi#S6t+JNhJeFnFji/4%H51H8Hajw$!^Fk:
:aF?@Q dYTC@L+:C4M^bcQ4bmMPPR4JGX6<N4b5wpCRLcICpY<AYmiJc6lSHb*LH@XVB<wa8>EBeXT$^QbG!#mb
HGem>: nZN^VqNQ^\ZceX\tN&@X>1qh\FRNljc/w#5RY&BTGtNkK$uNheke8STME\Nca4KKA#<1?RN#u!*c1Ml4
pum8$N 9cp=:qAc*bJZDnQJ8*>%mAHb\&6GaC8@qT+9H*8VFZiZ^5m1XBm5TjJByM:V#Q+86b#w@mn+8NY>w1lt
\qIh\e B<WkQ<qY\kk5W^DD<%*Lqd==DAhRJ%pEXRDHKhq1!HIt?P&^R*68pVhDJH1PQ>#awyDZ&4mu5MC^ae%Y
Am\1<% a#I#aZ+%mB6a>wl^9JhXka1hPkRaY!I9u?qlb4<\XtYHV^8^ItR1jAGk!ceKQ=<@N6$^\!dLJ!&+Rw$D
T*&N!y bYa:I+#6aldkYu^ADjp>F#IFd\@u</Mmy86hM4mmYu18JKNDp5Y6btwPT?mI/b#:Wc8cEH>j%=6wTtc?
M\kya? il4*>:C+:>>Q#6E%4&HlI&LnWlcSb8@Jl\W6ubh=R5#5!+WumWyYyRZXB+q/aIp&*uQ8y?d!!j!Shkn*
L6XDWy cqmpTqDb!8iJLQZXp$iX:+=WJ<TwQq+9kNb4Hw\:KLVmj!1^Hnk=!J\ZVCkXlnL!>j\AlH$Z>t#STZ@X
BYG4Pa l:VaP*w%tji%Mp6JmLy?&M\k/M*pwXi$c5>?h>:+@pBJNX$+4*iudhMmEA4bE1\VPHmq$?Ad^EE#PM8p
PijQMc a!?Td@XI^V=LRW^?\<L<tBJ<Tn%uN1i%b+TTj+#p=4+4VM^l6kncI48jNaj$yJ8VH+S/*4bS^=PAaqIK
ReD<GX lAGAW5^/PeF\1ZV8M:T96E^yYpZBjd1iM<MEjp@4La9l%1NeV=5Ed%SZ1lLPtl&^M?h=G<e/++6Z8=@j
5KLtR# =:M<1VTFplGT=k5^dINwMiZn6peMCL1VEAESlpML6\ptLHyDRQmdAlX>d\6D\FM#1d$l>#k5=hZ6%EpL
Kt+ad+ 9PTZn:ij=ZBdHaa%c@cWC*l/t//ZDGpelA5yGBWkb/kNFh5t8p8*5X#Fcmk&nRVBiYTl4My:Nd1j4/^n
Xhm:HA NZHdGq!@NN6G1Dl>SbhuNil?AJ\+mCjNNTh6XJY@wqj=KE6ITPVjc9YM!15m+*K%P:8kTqRAA\Y+=5Td
uDKTt+ <Kn9/=XEF4=hS+qE4WBCSmDDil5G>Ltkm6S1jiC&=/t:PhSE6IcD#Mai6D^wwpcLj^CDX4&wt9K:S&Kn
Bq\!B8 IE^yCn8QSI*pCnutJ1mb&*QQBtL!H4SpqVa5=hQj4*>%L$6L!\XBCVah:q=&DZD5:uW\#lwkISc@^k@Y
<5R@dm LtSBWl5IIGW6SEb<ZWZXk+1N?%iMG5CcM>Tny#<5NtDlaVI=l+JaS\YltChY>V/YD*^d\X>\INu:>DQ4
t=?Sj5 M*bYl^Pi$?M/$SSy<m?N$S+&1Cdn5+VuJaIqqjTe9YwtRuJXG::=X1D<W5a&#:>>$q+V=V!k<E\W$QL9
jp>BH5 ZH%IFL1P/DSb5JuKZ4X#J4d94lEF%6S=P8RM^?pt8*&/DaF+RYm#Sap?CXNR?tyyhn/+/jtDaIKpnt\B
%&We1$ h4c%iBJ5Y?Xy9m46w6w1R<WbcaaFk9GW9n4/Y5Vp=A&LuyQ$8SERy^4Hm4+Ny$qV?T%R$4bu<TM9EZY#
l8Q&l1 yK@PkcpPM4/jFjCjI\&*k^PA$/:&XI!Gqj!u#56wlheQFTn9&k9mNhwF:A+P###*A:CnQFeimecb\I/i
%>Yw<& S>QPVJ4KLI?etk$eec&F>t@6JceeRndT^><etEuL/@c+eh$+!I?+8$9pYdBkkX=TuJ$/<TL%=an$NbN?
>4+91V JN4:QD>4Tj@M4BI>y#Y*m>jIFkPiNHHwi^K6n1jdlSE<!l1&I4a/EYmD%B@Iu?WcMZ!\1^&pEY^yyb<%
Q#aNjn Sw*nPPYN/:@b<JJSwT/M>leC>e:M$TuG?:ZeR8@!:G>y6tuWmhqbYYL*+AD4>bSP@NXAne@*Ginp$I/b
5n4%5H ?9j8ih9bwAFB51d&+eIeM@^91m%cGbG@HnnSn&TC1Y&AS*L91nj9hY?FD6X$kFCcauWtYEuT6ce?S:ni
S9y/dm wVTLMncT\heWXbLA9dj!ckWhwLHB$^996D5Gn/KGBVZn!6+wiNYeaKVD?S+C/6p:!Lk:IPblC4$^9PSS
uD$b:E \:APc8@P4#KhS#dE#qNi^QJA%=LiMWpX:+tZ#n4/A^d4LtyVkNlue<^!MHR^d<GQpj/A1+8i<@=#^JbS
CX/Fed ZVIWEN1:BFt?!c5CK1Wk!HEKF?%hF$q@MaL?5dY>1N&ITpwDVaBnh%Y<MEA85a&EwP\pc^Bk6?CjP9*W
8VX?WE V9XSuhI^lFqH+<ctbhFK6=^195\1Aea1Tp#Tcpk9q$\kTp/>wT5!#A48TaHkTQEmht#ydnX9$4y@Ne%?
Q@^#q= HG?mcGw1/%p:w=1*?b#S?kW:^#N6abKG#<qM*I>!G@KmWMj=^W:ZWY@\%y=HSk@R#y+1I>+4@q8dK$Dh
*%J4T6 4nbbnjD5e4X6L4N%l5/ApW\Da68*DWutuu4T$cA=V?::hV:n*MI1Rw=+V\&nHp8bI4IeRP#X:umqVy\e
RXBQP> <CG#uW/Eyd#cBwQY/b&dZP6yEY^yY$ukMXHlwpna+*tqm\FjV!kKpF^KckpF9K$ke%GbMyFDJb5AeuDI
LA+iBC <8D%$uK8*DIkk?bk4E=M%e8NlEeK/WGdP^FpBPX+=NKWh6Vya<Y&VlRM?pCy!n95YZ19KtwDGmVumN<h
IwB+=: Yiniemd6Mkq9i>l:lF@G^FC85&?c**h^>&^dK>^Jt=NLdNub&F9jm6yapBTE81&uPN5TiJC*qlY=9J1l
-AXPaP 0001b60b5ce00110333 Page 430 of binaries1.zip
H#LH>6 HY&4mcI>^qJ16wI?1I1Jimh%J&??TPE=e?@hMXBa<BiQR6@6nau^QKkWTQ$c+QP\:8BSK1ttkt?$RJ4T
?D^b$! K*@YZa5HJbqj/y>:*!@Qk^5&^9pt=!W&<ZyXK9yhPVmtHEFTu5naQZ!WJi%4L\G=?tdCb4hdYMtTpZW9
#8a!AJ #h\uldKeSSkDnE$?NM@b*ENLSkW*GXt5F/B/6#=</ddjtZCtjc^RpqZl+tl<LFG%?46P+@>m5@@:?4+k
+Aj?VX Wj>FC+>C@cPFS!E9diH@LkH@RT@?lhNFwm:bZF\eKZwb?ue8G!q&CSwF?+&FS+yjkpcK@Kb4DAy&CS1P
ad1HC6 @p*jF=VIJinj&&kW@DJD@=&NSmH?w^FG@8h:L9=d9jp@G&G$?F<aaSV!4+4Q@^d+@%PK#^pR@+e&F:hp
b/>jjD ?cjt+w#AZiaBPwyaM%e/MIkS%\PqdLJmXCPWPZ$hlGB@V>$5a5qH4^cR!\MedMhMM1ki\!\GRMhYjhRc
FY5y@5 =yk6$VEc5p%^PR:9=ed8eWb4CAqIG!YyTiu+/qaR5e@yAFR%mE1tQALb$KmY5Cey$6$J$&d1Lt$!/kMj
La5DlI qYPyRVB@bYp5C4a8PZM/y*Wdn@lBI!GpjdG8L#<X>=FteDXjHT8u>+tPahDLh>6WhhWytmGRPEQhjQaK
Bc8e+@ X^Yh\R#J#/Fc?*@yMJ:Fj1eW5CAkVVi5y/T>q><VCq=>@hR=GuG!+Kw:%nGQ\P5aE%ICmK@^\QWu#n<E
H&Cc$^ /^EdA^5AESqN5Hi1/1Wic6Yw5J/:^DGh4mcQ/F%mTK+P<>dLN?ui\<64pS*W%X#>!TSjRW?NFbH#W?BR
5QRpF= $V@QH\WFMhaH\JeqDDEm5+bQP*NW9:\y^8@e9cYimtXYEBeFMPndMGeVbiqYq115=Z4nKY=6%R1ZBl=C
A@<K/d RMiwbHG^dM#P1*KH1NY4G6ISnhCDZbYQSlBm*$FF9dL4#Y&Dd91jp5bnGa&Fw^a>tD!c9%=5Y5IhjReV
qukd^L wT$?lk%/:SFG#S/6>T</Qb=AAEa8LHia4FbP<<RRwQiYdFPjQhV:Fd^cTi4j!?=hX@$IGLhpyTc@W4J?
#9hFPK =?QC+d&QS$e>!d8Sq4#T#dM5GiQZHBhpS\ui>yMXE=h%Wq*yQ5^<T6\Ky>$Vn>>pTyj>JyK$5tlPq&P5
tcYAup tX@WptMq^1Rd@%M?cL1jmRS&V#XP!JX4Gy1W%=A^5Rk$YQcdEc#bCFdXwRdAVGuiVpuEn*8CA\@:1dPJ
B@Ck<k ypuDF#=/K6ZR6>wTAp^w&iE+4WRlQcJj4GGS\W=tDMtG*E9lcWJcQhyZ?bC5TZMkRcF\hiQ&aK5hQ%pt
#Q>*cn w?m6ByuCXZBY49S#m6jXFVF$Z:Y%#ETh!kuy+<+YJqaTDaK1Ruu4^M#D6YJ5!b&MGjw&b1:c<kI&RAPK
pJp61b %l4lq8hiY9%PNpl1VHe1<#WAGPY5bKX+M$PKFWc+JJ<$$^JmtB5bA%e8S>J#=nFc=eH6HMWXb$L\cSRY
it8kk@ ^lEVh>t*$qI=>!Jq+/a*p6hMpm#bp%YQj@#KYZ:HcJWDDRb1c\VdeVd1lVPL^GZZKHmNZqMqpw&mdXEY
nqeLlL JE8kWLY1pIjm%jpV>h@pDjKu^96>4L8dj*Q6qW\<1@?6ajF*Y>eZ8cI@nn9\Kn%u!hVyn^G^HSAC/K/b
Ba&jBF =>WHSJJIwYIY&A4YwnJ48Y!B+k:<+Sc#Gj#/L8#LG<Ntu1N&&8!SyR<K?iuWTeQn?>@kQ>PN+YlV<RpK
Cu*$P? >k1&a@FlV:a\kW/j<%&*pqXL#&Na@TkC/MR14*ATF+**eKl#&bbuZ%F%X*:/a11S%+KSqnGjD9ieuh+p
buj5jG /d&FMaStlaCQD>?YNnEGE5CIV\W>G>NCTWMm>^p\D%?kXMmjtYLG9ktVVjnb4YlHh6</I@KNt!ME*MpC
:u5SJ+ u#%AJlm8dph$+Z*>bjt*Zwu#qDXc+dHw@t@RVV8>VABhmedAh9nNdh*uedwbda1j/<ZuGM*%qSypcVkQ
1lyK<D !Y^iNRH1d/mN#*?^5/X+H**/+BdZScCXAMjdNG$Xm>hjES:PR9ApJ:aZjZT/yVwtmIKmh/$X*a5cA5e@
QI:/4l 8ei4?SKdqyjwP8+qp#&/\uM$?bmZ%$/+^GKeZR^duk%Rlc19D%:XwVMtH5+B<?bR6C#MMVE%&!h:dI?Y
*BaVdS Bwu+kC\j!X<h<YTj&Z%?u!KqI6F9#l!D@ZSQAEVG%8!d9QL^\eiQHulu>YC8Xqlj?lb4P$4\Xd5Q&:Q*
^ajdQe >Z9ilkA<WE$p<4%jj!>BD4:h<d4$@Y9Ych9m9Ibec*:Fu%DtVt!855GaG1FYR#ZqZ\K!?ViP=1>bRL+/
uH>EwZ qRa4M=6e@iGWG$F?H?:%NJZlCSI4YC^e1yBb<IJw&Y1a1dk/Dh@JVQI\5NS@ZGD6I+Zi!cn^kIl@W5yY
*H!utY qlQ6<6lbPKbG6TBE4!RSJB+*t\#5!8I8F+*WZY<R+%%tqKX&kbT\>^GqXW$MHn#A<6?\$$?!D>jV<kXB
S8ytyu V@R/<:9cT4+/yYq@:y##SyRYuW/W8HC@4%HS:&!\=%A*ENJLtpFA>QLh=Q9VtYd&/?8wN^wDcY6c>9dd
b=9Emm KnkydAV%Z6#u=YuN<8nML*>A:LXjQ8@@pE6%EIt#E>!9L?J4WI&<m&wRqun<&pNHaDk!RFVGbDtZu**X
HY>/5& C6V!#Nd8c:/?6#qP>@q6KC4%XRL8JYR*195?y9PqRD4ZJQ<mNe1^n@H8!cT1C#y:mGl=MPpy5@:FR*N&
+!uwL5 8uWwjb!XVeS\umhDyZb<AhWEM&HY=uZb6nLCi$:^DkFJbwh1Xwun%de5FP?q*nii9#:i6IMLe16+#SpR
kYSA<c F\IuWa%dhJ/GJ=TNj8T1YZuIyGcpG=mljY5qXZ!5^#!<9FK8SK?6P\Wjb19dt+1a5Zt9c\#jdDVcDbQ6
ySEP%E qe&b6*#!mLajediPduh$dj8?S@t^bdX:*K:<&pPZq6PKjBG?jw<!t<A<5lbq:Z^h$NT1NPly/%XZ!ma*
+u6:ta \5RuqbW96A&P#DWFwV*i#wtwCaXpp@qd#w61^b1/P!ZBdP&8wQIV+uL\q^cGhii9Se$:!$&N^9YYetw9
$kyNkM Zma&D!BiM>&!L$>59u$85Z=QiP4$@jh9B/Lq6kqPJYGl8M&BFw$\j&>FiLl>l*e@$Vj&qZLNAT^t=$jS
5eKKKX \JiXKjHBN^VlHbG1SD8PYcdFMm$!i=>J^N/St9aIGCd#ea+PWGk=$6Xc\*QI+cuLQR+Hl1e1N&#=VHKm
?nMnwH CiaW@dWye#+:L&X!QRVm@HeHcdFSC9HRyScBFHc5w?1&S1QmRWdWW84?^1V!ZI8A+bDhB@IRP+1h=bka
hKuMJq @u:FIR^\4nJp?TQu?V#JccmGh456AXTYhTQ\b\yXXjW1a%AA1<Pc%YDHetniE6#1nYclC6cN#BWA@h4J
bDNeww ?<dtFA:\:wd>^Pc!GnuhB%hD5S4/@cTT+LAq*$J*4a:q%&T^ECXYAHRGbuYQXmlRTP5GX5F?yByMbW&m
188mBK H<D684#qEpBJh1!4STyNt*iLNklAk\8BB=qM>1dLh%?q!8WP*HqB*$QWBe*<XDBX1DDS8tuY5q:!jE9J
cVij^C &Z>DDd?Zd#>:LVnGPbiWaJ9I8&RLS*$D!%PTSNLuDYIJnDHXW=RalKuE<^\F5\/E1<qMp6LKpIlS<dS=
:PcdMK lm&bP<G1icJ9aHbbk5Mi&%aaKpd=pNa>emy\+YGX$?aHEC\@K5KTEGSRKZK/Lk>p=:6\8t$<AtjbDT>:
<ZMptb $c^>GS81*J4y:$m9C1\Ad<L%IGQnA+b6%Kj4ST1j:i^qKTQT5Ta>pRtjMV%uDt4/@wc^a?udFRj#yj1L
q@>V81 Nd:bAKNhB+d^NcPNMA1KDcuh=Y%?V4GWmqF?c>bVnS*>A?dV@YLBW8+C9yZWjydEWj$Yjpq8K4EZSHW1
lVZnKW SZN*^t+L>9lGC:J4P=^y+*S6h%:DXn:!YY!Ce/byMVc$JFJWYq1\/ln*6b@8jRVCSbaMjYSJZR!iSD8?
=Ca^?K bnluPcqeydB=Z/8ATSpZMp8SRJN&\deI@=&8$m%*JR5>HdJDD^RCkkuc\k!8ac!QMi/j?FAi6H8WY?bS
m1b=#1 FhK&NtKj8EN$bEZdeG4^u9Cwu\<=Mh>ptaiwZwy<\pFhT=HCKGb*1?Ww/lWNBl&A&wdc:iJShKY\@=%X
>&JEu* A&LFaiKc<<mDEkCBj!cPeZ>ZMJSwJ/Xm1b&*JcumZb#:M#Lu4#^8E@l\dGB^ZQVJpWcY>J&Nm&cl5Yj=
!/kwS5 @PCnMJiKyb^R&?JB=nP#4Wt:jDq<LIt\AYt^TV*?JWt$pG#^*qnhHSBjQ%uIV!4=KHmC>Y*4YYIC>*64
A4y=5@ qWLa$>P1J\4lL<k>=hKnYWjG*hP\n:GHAuLkm\Kp+Yb@Z@%kKyt48&^e/%cknC19C!me5\iSQ1>py$CP
HF\YPE WMD/4%V5p=TtyIiG!!5VSS<>qKY#lZDiIm*/ySB*Gpp=KD^ilmuZbNuQlH1<F6NJS6NEw99ZWR:P$Fwl
!aLL:$ JMLK!NED!h@*\j<:QMSN<p1ZZ9<+/kGdhD#HdSEV?e%<!iW%@>yCdi$wuWtM:=XpWRyKFa99a>ljmE:i
AW!mya &NwkHT*>ZqW**e>Km%!FEq8^XQ6bZ^BBln5Gpkl<1a&%/Gh?wXJuwNXJFliNGH$&Yt:GB&Ey?Vt\J9/6
IytmXQ 65cpqJ+d1PbMijJW^iP<18/iiut5A9Ve8I=X9ww&CeAt:eByHKbHYyyL$p$Tjam444yLw:8yFutn4R6/
A4&Cy6 ZB#Le=L=dL6dk$<Cw5LH8$<CLaZH<@+maii5n>bZ4>HA?^/1PekLA4lQKbqHS6FVYlY6ETqSNJ%eyGFi
ytden/ ^&6tHAR8t?$5p$Qi8@LZFD5&>lt>6W*h6LERYlIwN:Yjt=H4tde6&5iZ%PY/%64Dte!nTj*tLnH9R4XG
^+!*b/ +Lt5%qquHNS4WJ+q/et%#Tw=deS%&/wuE\d5jbw/p>mZ@Mw*ie4b6u6e8HR6H\B*cG&I^&ccQPMtNhXm
IP?R=n Vq%IwGQ:y>!B?G>tWV%^!p?8?M?q$EtFqYdYiFcc?8?cD1iXJ=+A/L<wdE5$q<^kpit=<H:TpeiQn1q:
BQ\#nW pA!y?#c8$e1kWA?Q$EHF#@k#qLdSKMc+#m5nGuA9!R\YqZ@HK181YM!YP\$GwHc%Mk!aceu\L#HkH!jX
uhbmJF L6NW$=Vu$6jL>@dhIBGcwD=bp<LqNWD&4J@5n<%>$9eZKkDKK:kHee8=ALY6C+VCT^:R/D&XY@8R9Q!<
y&Gd1* 89$^@/&u<u+?!S8&wlilAJmc56pM?h^GeCbFpLBpV<aVFi9uR!bJwtuj++^$8h9$8<SATd?ap/Q8>E^X
^ELAcW FTy+B=8#M*Vkb:P?cb#b8dQl%lkekBi8@m6l!d$P/Ce59D$&VedP%JE*aG$8QP$8Ndyb/NIk/!^KZ&!Q
Y=awQ& %/G6:W4Zy6t$q^<H4^9hu5ZciblNhhwp1nmM5cBA+bPh!%tanReZ#XIwyXkYuI$F@h4/IM8yMW4F#Q/y
@@!/TG KpWH=XT\uqw%!IcmCN5=//6D/R#WwkAQ+h?8DRF+Vy+5L*cRewtZm#D!@I^y$9im%ZhYk+F>MiAI:N+X
V6hj$F a!&QwDlid%iSCJlVJ<l*Dy^Kt^q<$qZ9:kmm/LcBnD^T/8TdSVp//BH#J6je^mJ?&qG?m*9pEk9!:&:1
GYqGqw /<VMGXun5D\/QySjteSVVD/N*=9dEaAYS\6\iHA%R@65e^8=p#e@QV#XTE@RVm1PM!jmW4:1IJSMlXZV
\6PKGN C#&$WS>$w:C:+:+dpSHu@5kPK#^&We*uwFLM@IY?>GYlyF5w\69qF%Xh^>HpuW#ET+?4N>J$e<CN65iH
^YE:Q& =IE8Ec*861&VF&CRCKHAcS@4cP4tN+L#d*1C\epP<1uM/4F<e&AEKT*BjE!l1R/V8Zq+j5KScXH<&/T9
G&Blyl Zu$P<wuBb1C9w6:$&kbB#<B6p/K^dQFmZ?twbkJdknDm%ypCi#dm1&^/P6GQA#8aE=:wMX>WJPwJmySy
-Adi4P 000212d225e00110333 Page 431 of binaries1.zip
mG<cNS m@WJAmepKq<PeTR%q$Sm^?@ajqRqI/TQ^R$KcwjVmQ4m&lqeQ#kFkPuGdbMLGC1yjM>X&=#TdnF**+mC
dYKnhV PEd^CKiSiYA<IMFh55amPkk##Dbnu=dkE$G8M9MZknB98HAjy*pkynPc6MdNH9#J8&TR9u/wB5eVSM:>
^D$:Jq 5K:HNJ#?ST&=!QWpI:IAaLi6i*YBHNDlWSN%j?%Mtl$SJ>\aC!B\j=jqG51KSX#LKVe8%\&JdCkKjd/X
QklS14 =m$a<c$Z%jT=1GyDkT!QAj=mK9#J8?AFG1L%BcXZDPi>$>!?n1$PqNIDiajBhR&^itEVST/Bd=NHF\EE
6nia8> pY*1JG+6i9V!&WFIKiHBGWBnH=!$^HDlJ=SVDR+<lq/#Pk!9$Ca^p&*LLl!j$%lbB1&>/p\<iQthe:C4
h4t#YL Q$<9\?^1PZ%jV>S*MyjyA%h^Ha>NBu8bm<baIm$<$Wk4*H%SIDy1/@*F!k:<J!dP$dSBeLbPSmnB=&Cu
DK9>ST dQih5BS=!9=yMp@CVw<\4p/14nF9=:T+j@A:d?bIK!Aw?+EIZn8@QE5wBu6T&uq<tI%<1@maiZjkIKJV
:QDHmP /ue1GaZ/d%ZJKQS@WTYLm9!nTlcFZXwq@>$i@wPZ@A5b@Qj!>p5WhKQELpQ@41AdJZ+b?uemGk&:BI$W
9c9Bp8 @+%KSw6el9=h?*I$@BI$A9E:GuEb?ueTHI&<BA%H@8ccw%GZwH<9\hHwT?Aw&G</5KBF@+m?VNkR!N@S
/&!PZ@ +9>S\KQR@:tA@>e1:H<Y<GK\9^D\w4C@EQAwWhV@Leu?Z%KTdj9jWbLN+Sm+PCANc5P!S^MHTM^%lbFl
^d4u4d ^Z5:!<:iNR9F?$p*%l=l$GM/S@QTWZ/1J5l/KM^aGWDuaCEipb8kHct=&4elAey%I6mWINAia*:6+A=L
<n1W1H 4!46ctZE::R+Z\P/D=:<iF5tp>j@YmeB&F?8X4jHK$:wpDBMR9M/pdJS&pEce%e/Rja&Hq*4!ILppFTd
B^Y#=6 m?S+pDMGDnD:SIhZh?&dH=*J4=qC!a1>>$KL9LnumiyETF=haBnVeTc=!mL#Du9%Ki?$Fl#XPkwk66/m
mcQSWY $@:wiF?ljp/wQLll^piGq<\JEWENcXK:@&DMi>mPPqy$H?G$:Ql=C4p&>8cG!IiQ<l#&Zamy:!PI<ch!
GFybH8 W?</Ni!5$YL$N/dFH5nEbQF@nLFktjdQClWjC4emKVAe\&JFSq6e6iV1tN/$mn8W/>%kYQD#5KWtl/yG
T<m5G& Q4%4$HT!en@GCd/Gj?R$<Y/<GQyt^jRA=&cFN^+FQQ^AKP5=6&ip+M%WQ<=>MtNVHl>@hY#9nH4lWN%4
Vn&:HD $^yqDD&$hlEZqYTiu<V@59Q<j15<1uca\JDc+@PR\!8Z%$J91h@H>i1Q&d1L14@4@n4:XN9>^Qky>RHD
A4K$F$ Qd+/<:L>=1XiIZT5LS/>1d=n>llL^\>R8<de&+dq*C/4=dk%j*Zy+Z9!HDjVyG5iJFe>>G\ZZkVe?>^:
>q>4B5 YmcVK^%*XdR<>ieh1=@&^wPlb8Z4n5!F9Ie9X#lhl4l?9FuGMEb5X%n%hM*upB=SEJ5A*RTCqB1*tLju
$&%1y> qj6S$qML%</<q=dnH@tTtRKceb!@nMQajMeTY>@&*d:GS5juCT1uEGp$t=!RQQF%+dP?hyyZey>+BWmi
&mIV>E Yy1q\??9%8i1W<XP:D<F#Z4bkpATJ61#iiCZF4?b?t9=WM9wRq>c\t!$<X&TTDLHCR=Z*1BNJ8*8Zn5Y
d\<++M hw=uJIS6:>uJB1>mZ@XEa@K995B>b:RT5+:acIJKi4hte>LJlJ>IpQVJ\h*!yIJnFh\X$lQL&c\JM*Dc
I8%Ku^ cqN<#Z1RTJY4Wdk*dH*=N$uyBJSXZJ+i9i!mtNcumVDtt!+Halhj1lM@BSCtI^YtZ5Jy!G\k%dE<=dKa
aP$Sc/ 1+VKBRB\<iHj8*Ld8=<Q<DCYYGwPGe1TihIJ^86/<FmXQjyWniG$mL#KGw>Ya9Xn19G\AVPKX^m*hR<*
!1FNw\ d9?/\kFuR4YQ$&ycuRcNT&a@Ill&AMK&Bc=qpHkhqhGqWdCH&P!M/SBP!FRSHNle?$#+YAAcMM4>@ubl
mu#>=Z QZ>tlWWmSq!CA96KEVYXMCYaG/qi:C?e>jHnF#/t9VhJ/?Da:Ab>F5ajM8t/LZ1IS\X%b:qmG>Tm>9%D
p<XD4k %$aT>waJ+&c!C<y9*eyDGMd$q=y64e&Z>%?$EYe\GR%EkkcDt6ab11DKBZqn?1ldlq^TET/:Ry:5F:N1
?VeBnS +MkkAH&mnQ=X\WcPEu:*68HYwnTWXyq!kj\J*hlhZK#=<uXK8X$nGI5X:tYyW/SSZ%nWt*Pti>d=yT=q
#*GjmA ?uNGbH4\%h4Q&RW>QakBqQqtcWVX^/kSlIPP<hLi1#BEVK>iQh:QJLALAd8hjZ94D6neT6/*@qc!byG/
Nq&u=R $=D<8=ci@Mjy<e?ym/duR&ejbKnwaJkh\:ICnp/8mj9P+m1LiE%&^dHcAVKhYXX&8FNdctCKQJDRpS/@
6KEG*# G@kP/CXN?HIFId>j\8JQWM6Z6Al*+%*/ptbh%m^NaI?%S:X&tkBZI:NdhK@&tMk?!1D?GNpjSu6tn4w/
LpcZi! +M9i+mX*jDTH191A&j:8bdc@hp9W$5dCZ1Tmei#LnXFDAR9bJFuNL$8Q>an>CQcNIuDq%%8L4$RtJNA8
tPcwEy /1S<8h=bk8CF1!clwXyliRcXTi!YBDFFyyQqdhMybyJQBwi!j:HLStamiFu:quN!iNa?R<GSbtJV<el%
%lKpXP @9SZjZFKWjP#VNVlTX>#Mpb<&mdKd@61?hMV9=a=?@16iquLTny8MhPGWdR/R+hY:dnH%tq>8iiV&4cV
S9pIK1 lM1$e$Wp4PH:@KdqT=e=4YpmWm4@%N5X^tt^=:9ZGN#N<<Qt>F6HbZumi5#W#!GQ>/8h4BN^u=FelSW!
!jpLPy pd5>5e>R:/bec#46Y$S>GM?5\!BS6*L&F<?*PS6&ZTw5uS^:ZnXtuLZX>hLpPh\d!JFP4$AbHb1pqe5:
X\$dbY %JY%?5m>N:>6*?pbY++yNNmcPun!TuGKQmM</Y=YY9\>LP@NG!+i:iAmW<Q/HYLC6SB<KuP!e&#VqiQy
NT>%11 d&EBE%e%%dd*>6bb9BLdhcH=M=65t1e*w6<c\i$VtYy#<PXhy!X?w!&YhX9^t@pmmah&/<ue%c$T/cmY
G:5G*X !Le*Qk<cM66b8PE>HhW?>6n5je!YM>ENZ:m>T\IGa/Y=!1=XMj?$9QeXQ>#9bWSd:Km!dY*INeywB8t@
j<D^ew Bk#:TFTk</>%+?F&W!R+:anp/SFiBNAtM/n#Jn#^a=BmGtTnmC=uMuR#Y=@LRnA=&4<TSnF8@InXXnq^
^a/YCn RjW&/W<BDc9N:6Mn?TTJVFC#LiDl6jj<^YVBn:wHnBlqC&&iedhWMbei9yG\aFy8WTEjnZI/T%i@tjW^
pZ^B#N 8P1ymqa<B<JETYy$H@9a>#ybnM9FW@9IB+NG&:t&Q@8cRQc*6@e#bVbnS1KV*DkMHRakELPN\pmju/AV
mASk<+ ?VXje%@Mn<Q$FilW<p/4k/\HRd>lAGuBZkGSLFe#TXR+5X&/W9>JY$XZEXZBh?:ZJAhiG@&Gt>C<lHYF
5*^i*? SN?Naqu>@JK5D/+C^C+F&^1mREA!WMH?Jj>6h@#JN^L@jPYVDbkimWwY?El*!J:%8&bKP>j!&qdVP1iM
Ah%WG$ \pb4a\>$4*KcbCD4wkRMny4wCZ%tYPae%yPVwZTnN%V:CY?LdiGWWVk6LmlJ5&\tj^Xu8V^p%T8D+n@I
Ta\nyT Q>RNLW#IFDn@&\h&RC\h65j=AQRaqD<CEwHGaWcyA:BjX!%AS%DSa*m54hm#jKB&IJSKta6P@nRcRE1d
Z@alnL D/dmEW#pY1AJy1hcB!1S?4kJedaY4=\=e/aHJP^H<^5YV+NH?n\I65#Y!%AlMYmue@eTbli8$&wBDTR=
&m44h? ^Yw5Ny<tW+=%kZuwyC8jA5VXG8FAe1<4Kub<#kQW<#R1yM&8IZ=N=qSIaT5&L:#$h6V++teX=PiR9h=h
P/m^1+ I@A/CV+R95DDZ#SeFE*V=h+L?$dL51uRWBtCiTR!jINE^ucuC:^:$Jt@=G8>Wq?TN#G&JyIjAMt>^lT+
jwiEPP b/cpW8<\Xwe*JCGa5<a5knda4b#W&94&nwVTck95TQLy>4ebymNkwtZiYt4WXWQT*H!CdlSb><at/kHA
<dme55 8\Z&RS5:d4R+HV:DR*!aS>CA?X1KtZcC5u8XyeaK96NT<EnnRh!IM9/nkA8J%jbhASY$$iB=Nt^q^hH^
e@YuqX jM@hRc*Jc<@@*y/9+n=Jd>E8e>unEdJ*?SShw%iw+FTLWeNAM!E/*NA^c!nJV+Y#t1GYEnB\lAL/T<=&
Xcdd&& X<p>P>hpnE\I\iHykmCFYSNa:8YndZ:m!yaHI9\@ZNEFADJ8BFNu^^n%/\n&FlB>+<>GdVTK1p%X=$bW
^4@+^I cpW$8$ljnWk!ySqHl#TnS<=GdHJCQIBnhlj>wAER%/uMy$GJupbYbW&a++n9*q6JVl<u4L*4t1p+=jZd
=t5lPF khE\y=6kpcbuPw@HQP1SEPh5P?BR<CJ+d&IMl<>&LP9tlM95?^S/*6nmy/l\jShb&!9%cYSAW$eC4k&p
Dwn=8@ %diQM*HRHqL5mhkaNdYFF>>ajWblI&cNtZ9Db<*De+Yjhycu^>WNHtGN%?M4aDdj8qEN@<I9wARPVEHn
NaStXW De&ZX!CFti<>+@qQDZl:eCFbE\ijY6:nIABR&IMAZCmqln^68%LAjb4CbT6p&k#ikS5WPHN!<5B8Z*dm
TeV\>/ B=MeGMbdm?tTqmd+kGD>kFa?d+%QY*D6iV:$Way$LVJ41bXVGl8eNZwFAV<m/m$JCRXDFLI&WaqZ^Dy6
6V#II% l\Y@Z!VA>?yECV!t*HVtup</wjPip19!N*La*cwZ%i/=w$EVe#/amSt:nSB8Ye^/N/klq\@6cw18y+m!
RcdLN6 %D4MhPudpcQRhR##w/BG@%\LIN4X#@:M8$YlB>D\IMEe=GMZ@YDQCT9/5kXi/S?$4wclnKn1Z5L/VXk:
8p+FVi ncmS?Zw8nBy?YEBTSYDE>$nd4EPRunC%Zw:F<d1Fc4:bCT6GLM5K!6Gm68&n#kFT4<hyWKanYQER#Cji
%8MjSZ d9bCc%4dk1kDQaJ:NSy/tIm#T41#R&bw6Ci46d$cYJ6#lQbp>X^jPJSLh/$tCpdGLYhtFYG?V$tXpKhF
Ln6LV8 <qVi5!c1\J4@XGZbKd$?JMbc\XLN@9F:/*%iwh6Ql\m$6QFQN#R68FmnyqVe/<yMil@!$>Y1\VT<>$S+
n@5F4+ /e4XlN@Wi?Xaa*cXl6W^ih?6FaS8>kRw>t+4>6#R5k$:CmE\nl9qy?%*itBYKyAP>>!&1#SyFQDjPAwk
q?u##h L#Y4Hd!JC:lu6JbbT<+RateIGR\u4TtwK*>JWnJW*hNMtF>Yua\5ttY85=L%HNRl@aL!:A%\c+S+QaR@
m%4V4\ H!S$h!RZF+Ya<Sqt&a<b6i*Xm/4XmX=^$in&VBIqL8#XMAAGln5@D^wA<$\>:iNnQ=:4:45>P@nyMdih
R41Mtb c*:mnV*?W&/N6:*ue%y>n:l+njyVhaT#9pZ@QJn/jllwC9dRA9R%9iL=/IVuFp6/AaKe&I4YiC:Q?9BC
T:@FKy 9#b&:STBVASb#KKHRl!K*4JHQA<@4+XjNAeTchn#4kIY?$Pl8JmY8%lX1kmkH+hluw4QT@Yn^n=Htc&d
$kaEi$ key#kSWMl!t/a6$*>ham&wp64CbC<8TVHc8w6*#H<SM=C%&t1jkyM+JAZ&DHX6VbZn/9&PDKNGbiyeSW
t/M8#5 VLF1StM\#Ca^kBH:nqk&dA\S%pNl^&kZiN=XM&Nd%itFddwdajM\jFW&6KpdL@Db8$bdqY:NdpTER8$W
1\m:!C lECIl&:KqLytw4lH\blC*tdb&CM*SM1a^:6D^<Fd>h#b<XST8H%6D>+=?WN*+QhlSKqw\aXdA9P45uVu
IT=kDS >TdRA?d?HC=Vi8%:Z%X1BX45V4p=yk@5:N/I#FCpP<E?>iY:&qAFADDV+%<Cdc1RyBE/u9cNE$t/yLT#
-AKAqk 00096c08e7700110333 Page 432 of binaries1.zip
c8%RQB A&PIYi?HVjdI$biB>pjh?bmcaab!um5y\&tl+Ku/S/@etA1m9l1/tQW+H4i&>4XW#<CSyC<myyyC!6$6
b8=X9j 9*ct>nm/4Z@NFJ?w^:Wa#d?Vk=GuMVX+p>h>&\CJJiwEQp1+mLnqqS46V?=XEnlV$nFZTlZ8CyNcyZil
/8a4<! KG11kWbWPd+!JG6GBB$mNRcKtH+/nIFN$nA^K6/d5H+!WK/*K%K*@&^d\*i#&DS@LKtV*HB>i#HDI:Q5
&p1+N1 ?BMH>VkIFp/8c48+ebd%Pc\*Bi$^F/6Q:$R=*bpQHekPDCB!:uHVt:wat/IM/\C1t4G4bEH&nTq:KIw+
*e4\+B baww>EA^TEmAB>lK?Lc19ky9dFGXuZEnm<PD:WyZ*j\TQ<CuiEyZ*%ZZpJ>X/kWHA!DuX=VV%bTM:Q5X
8ud/%+ @D$X5DR61ab6Ck<*%5DCk4Rki91iZ?tYJlB!qpLu4&qHZ?88ce#ZtyM5GNTXupJwhPnpY\M$8w!+V!A$
y^G4B! V9Xc%?6wZCGAG#k6%=TlJ@TT41?Ghji1=WTLVVVuLRlqj%9DLC4!*!1iSiH@SjE5B9>H<T\tetu^@Hh4
=wi%*a >l>>uPljTNC@6%P=SA&#KQI!NQ\*qeCm1E9R1N>yc%H$binj94jwJYnp:@c8FBY:BI*+uc+ZFd<E@Z9=
NV&Dc> K\d:n\yXFQ/jK>S@LX9?F+YK@k8FKmd!n\wXAWjA@5?yaWd>H%uD:MyeF^MYR@t>5G$ZX6CMJ<S5M\CI
q9>#RN %SkcbCl%c&F+iJ>le@ha#RK>eH9/:idP<LlymL^A?1Ia#HX=Y^lRbZZu6q1y+:=w=YVPBbQ/bI!q&CmT
Sw^n%% %S4C4wPh/6R5LhwWG1:bJSYMGHJCmanEy&C:AXZLJ5$X=J$MTJmdE:&EJn$>L&MNMj$6&PkWTa%I8+ec
8BtK5F uA:5iQ&KRnTc:l=N=iS%NB*wDDp9J%6/=Ka=^yF9YC>jDYCVD9IntWJQu>InbIhuMNcC</X/\X4G+!X=
DIQ5Kq K^Ij+<qb\9#b*@KWX8/$%be=CCuRXaP8F!AmTl>eFSJCbHYTRatq=mHRZS$?aTn6EyW?uL4Np1G!ct&p
!k<VPC juce4QMKHKT>/&K\!5BIb@=S*n9PpEqPNuq+Lk54bppb^e=ap:JuI4HbCXYQKW>6WL/1RH&WuTwW<Aw+
4@@Ejw ANYCQC!C8V%RN6IXY:5L\e&14>HbZnAR=kCI1W?wdiahBXJALdm:kWF$i:Ji6dcaIu4V#@tjCAXEE:?S
!wCclw 1P4l9H9$WQYMVhy:L\lSB5t*e9wM/$DHaejGV<ebXMZCYYEu=w1AEmnqY=bGXVcT%!q!5:4*HPR#TE\p
!kK@9! I*@RJ/dwJtXwX8/Qci<!%tTMaX<LP:=kDVX*5*1QG^M^RE\PV!#KPt^RX!4Rud+JG8mj8Qd\Dk$A+WEZ
thhYH: KV<a6!\qJJWui?#IAH>Q@hWQ5%hZe%Nl?=4#q=dG%&<Hqw9=F%Z>%!4G#S%lQXwbPXP6tdEYp+aFlLFJ
^Swe8p y*KB%M8QlQM:mI6aLi4cTeBR11eV\RRDVK19YQt4TH1+pyec/Cde:MbCEDK$e!<wA=k>K@VJG</l&ZTW
l#XyL/ 9>S=<a!mhE%pnDYVi6Hu%EB8TmJD/i=k/&yVjnIVC8I?X^%A8^Z*tnw>@S=%GEFik/!l@!<Lw!t=KuEZ
^+J1a> h5cC#T\QJ+VRFPCPd5KdD^PE!4&**mbbkydHEe5kY?tAHFRDKCuF\*QLVcP/H6p?GPium!iea$IX5PT8
&Y+qKB 5IlwmP6W4CY+EeccCY@PQ%H+jJSkMAG+QZ4ElpdSNcY6Ri\Q8$81eFI%:RVYV\>A<Jbpq8$5>\#QEuMI
6p1Kk> ItX1+K/^EC/m8$jKGtuC%Md*VElDF*HtQ:dkwbC1#5ca4J?Wqn4RJ^R*ZMJR$C@\+uF?MEX#TRQ?+@WF
:alFJ9 \XaA1ELHu&BujId<tZ#=>cTPy4KpK&yJ9F^Ft<J\N^=6X=kK8VISq@#*!cV+8:J?iP<A5X/K1&RiJkq<
YJGN/Z dpKAq4RadVmA4J6lQMaG!G+jnS<Rl\k\RL15CCNm?CGl+\!L8%h&j&yq?ei#hjWqGeD9GtkY$QEFbVZh
E&Eylh b^WTT9k1K1eu%cT:dR?q9CXKP+BLT/a5nttQT5DpS/yd1I\Xt4?iCwB@qJ<?j@matpt+b9&J+edFdPqR
+NiFEa >h%WkK5^Qd6uyM6+1&kZ&Y6iNk*8$j*u$ESmFT=4=8lyc&5N44AmmyK\Ck46i4\pQcQh!X&nZZYd@ESI
iRZ9:H p1PQ6X*?TF5NJct51tY^phj6WM%\=h8EdtI%Vqb6REu?*HB4dq@%Y+EM*VH6i&E9bbQinN@1qp6^mGQL
wY6FHl J4*6&4T<L1WLdt81?/nR%&nk$A:R4a%&k&nV#48#9hmV61$ZTmE=d%k$TaweZZ?h6@H=Qk8JpZ<yAC^j
nk>9S= TmY$K5GQ*&@lICK#wtC>n4Pmpw:@+Q*p!5iy/mIwlE4i8^%kuhcJ6@<y@KG*cZauumjmGNVpV/dJqqP&
LJdJ>? K=i<*Q@S<AudQiQ%TB4cd=%F>8%JKibtejyw#Yc+nq>iikKT@D9YeIiCTL&8YNmZ&6DLZAj&$S=P4*hX
+!H9>u T<L481D=A^CK^y+4*W<*%5FbG\j?YCTX1uG<THjZW?FtRVF#kV5Hnj4e%:T!qybPjTVVT+y*?Tc/:+&%
%P6b&M J=$lk<H5PLq:TS=8Z5b*We<Ly+\%nQpdB#%HMTL&Nb>uXKHbqhaw+Qhn%X$bH<$lby?X/a>*yAhP+@P6
YZ^VR> *k>R:PpWIZ#htu>C#R8pNcd4e=>W$TCTG@w?SRTM&ehGy8mwwjE#aiCW91m=n+$#X6e<a8WdB!F\%+*q
X:jnEl iFeZYQjMdRNk\##1Ppi$MAwK9J=#udYQ6WLaQd6X1Fu$:K\J>ERIW9>FE*6GC/%j$KB$9Kji/M#h?qT\
m*ABR4 W=aIIGqN8?#8SFc!AkYl9!@WQ^BeWBS#PK&:6ySwbWY+1:$d&hn\\y<nu&$M%lDbbVZ89Aa^#kk$Wh5H
RYT*ky /uS#hV1Ht?<:m#A#^pbEj!NEPaDj>1KhPI4dlkben:c8Hi<I#6q=SDLEE:B<yiI9Y$mnhaFcLDVmtn+8
H>hj>9 TIt9hDtFl^P?X/En?IXFHaBC*t<J#t$t4IQC$^FLV<aIB!Y=*d?ZtJS*Gn&/Ln$V+biP:u+&#\<TLeHa
:P8uL= JJmW5%qRjJHWm$mNpa#%G1P*XCy:<=uS9pi8n=uJ>h##4Pdpedu<P*FNn&T>lbPe<cJZLnJdEEK8#bYV
EijLMy TeTQd+yM5w<?4AwHuah>?@Dpp%>YtVyYDCjed9nEL:9$=l!%99AH=@AQ:IL&et\hQCjY$988H&1cR:?A
uJF%BC hS^FmXdJ4EH6cd</qEab16H5*bR*+#@T@<^!uBRN9KFKaS:#Ej\eXJM!MRPZP*><*XKK98$DYeNVNjp4
^SA5IK **?5*u?\kt$<1JNVPwEHcu5WTn^T**k\StSP:4XJ8pDI89YW%Ky5INAX:?#Zt?=t@e^hMQ%^lFn5Kui:
TX$wa8 qe!HpRPl4I%8SSGm+Btl1KGm\nHQGQ+CtYY*E5>bt=cy45ZwmB/aJeGDaCD+TIeI@==$e=^\VC!E6AGm
uac<hN j6:k?P+SJiiD@Klj@D8VWVYX:Pp>!?<?+FYe\c:k!k+91EcTIQwny>\GtbIViGJ=qAuE>hn4mMT>#N*X
BV=mPI /WB?iGI858?:WN>EyP6*Vnw59^mA?5!#mNp4MuPyVj5DbekG9:QVdpk&KaP>8m5ICm1N>JwYY6yTh##E
8A+EBB 9Xp=VFtSL%mM9tFF\+pn&Jm8i6iK#eGEuWYy>9%cl:qcG>cC=Ia^S6B1I#liEB+WA<**N4Jd&RZIiIyR
AHj@=* QFluqq/ii/Lq@uValRF1VN+%=+yd%FD5/dT&KFBKpP81$R%%L8bB!*aeBADiMw1p?Rbha!d6/NK1C&+#
h?++qq kqP85<nLM&#$M^/Z/dyqhmu&4Tpq55T8CBjdManay+8ph&^4d#y4S\e*PhB<a+pY8nw?<^dwXcGq=5I^
IcHlBQ ktEjPk<$HFRLakJY4jY&>ja/Wh69*F9=H1>teSw1hV>TT4uN<dumX@C/YESRGLR/4VQILA*HZt#J@T/$
jHVbI^ FT4Lcu%58\p*5<<FHhwtQLZGq+?q/?V4pA\qiK:!qmm>+6=dihT%?JkEtaad=\6ek5WI<I=wR#G+t8G1
wqF5&c j9i5qVl9R&A9ui66K=HG1^Qy*@d>8I=@eK5hSQIX<1m4E/nQdC4=DCwCu&\d\tpZ?BZ%ZhX?\VS99:Si
*t84%5 iht><&#$K&jJ&ZQjV$^=NbAmtaBcj6W!+Y6&Zhb4Na:Lp#hXc?wRuKHCdi+FLHjNJ5B6I!Fp!pkZ@?<<
j=SuSK T&b<c@m8htB?nB<A+/lI+dkykN:15N@ZI<IJ<Xh^&?ARyHI6+EuQd/FhemQ&EaE5wPW^Ni+*lpW&dCi1
EHP\bW IpWdtP+jSDCnic$AI6+Z@DuLPuqm5P=CWpAWJAd/JHASbP$j#H8hmP5XcR\N?an:I=n+LhJu\tdY^QHV
d8d1wy 6^RYQc4a\b5kPX&1Y%mp@BVpth\$/b1C?8R\GRDuSmyAtB>Jnw>^6HqE%hPni=kmj!1tV84nNIX<Yw!D
%c:#Mu XlthnGQec:>TpP=V8GlMehLcYCE6Pqq%mHdePW%!+\A<G%Z&c%5WhE/IK#F!65=ucn&/^^pe!*TIn6@6
1W^4*^ =TWG@&<%AGKI@/wBEQ5LA!B/iRPA@p5DIQaZ#@B@:/N/1chS%J@l/Q@+MC8G?M<jb9?%BPl9D:NI&L>8
4JFKD> H@W@u%j$L^=t^eZ?d#uR@+y!ICR4R/:$@%jLkdbcdMu?i8/K@hju:u>=\w4@q!d5*=Iy?l<u:N>iR%>!
@M5K:h \9=d5Q>&kQ4LtT9?F/YZj&><jIq>&MSFLpGL\H>H\!@#*4<#aPKI!>D\*:S%FWj?Ea&/BI%CwH>Dw@?I
abFRI: F4$EnSV:HT*&S:V+bYn$Z#bPRMJk5D?mL=M%yMn9cQkj$bjJG8K*I$j?EZ&b4MHF^Z=Dw@?I9p#Y+Mnj
QkNl+a $YJ@SF<tc:@bE9S9j?+8p:Zj*XL<DSj=M@\!cSPFwZ=DI@/I@wi>MeZE@?i:IjVjQtlRj@8$?KeqtZ?:
A&A%E4 G$L@?:5l%D@eDj*>^j@Z<@:dZhdjR9e9=@$jN%d@jF+p+1@Pm@/L8!\S&CZ&*AS$tlN$WECb\A45^LHy
ptHTZ/ #BS5DCSEJ?IcDDdmIYV=Ih:L:qAYMtCuTJc9LVw/IyC/mAW&TIYR@iklbmXGJ^+haSc:^SJwK^LZ&?M1
=FlB^! t>BKL^JC#:b!Al8Ty8VZB1=<HCwBA+8u4V4F#yh$^bu/kLR=&R$*Dj!H#Xjt1N9M^KuyRX=8D%yWhCW:
ISpXT? B!*<m@KMMZR5*S#t$puj+T^lEIM>bXj4/HbKBXqynG@$M<aXnTaj=d#?>I+NaKh=WbaFH^MF<B%lW%/L
?yW^Ih Lyh&*!^FEAiQZaBVL$haZ1pT<m1wS@8c$N@8&=w\Vh@VC6tuKB48KWmyy9CjKcK9nZm#6YX%8E96Nq^n
M5&^cZ i*%:XTp/m4MlYm*BAudN%T^A1>9twX56WVt%4hPaGYNbXGuP4/d\\VI/MndXJVwK^#aLPnILNZ4TD8tI
S!wdne G\^Bk4q9!aPIdbjw<H5/5AHaWAy&6QLIG!MB!t*dPpc#c1e\6\/EYVF^Enc=B4Yb?#w*Wjl#jK?8kJc<
BV$I+F !+DC+Gh55CQ9CVw<IYaSXp5djyY/qe$YN^DJ+V4$Flb#<W6w+GlZlHwk@H98%a=&#KRIED:*u4+#RBdT
dVAHK/ wSJBeq?pyq!YV^K8$%ZT%8qH$A%D5nuKhGyy^+9e:y1!plHXYtWbwhPkui6Zq96I5NM*kuBhSASiGiTq
RL8Tw8 l8p+j5EP\?:^98*/:FlPLjhS4aEB1dN:u#F4<IJ/1CiPa1cl@EVqqA=CJ<9\6k8?4#<%KmREacnL6cKZ
q59!@S 1$45?DpSCLa%/8yp!NK!1/9^8YqVp\P/=6IBp54lDGWDCL/6m1@LSXaLG4@!AX^N</SVn%Su:Ll4HmG4
-Aa?+Y 00082f5fa7700110333 Page 433 of binaries1.zip
IP%qAJ m&Cpy@ENalm#hFd>R4e<>WFuq*NAi?TAl\<!>Rw$ND/WPPk*aQCJQL1cnSk!wN15=^We=1j#k^P1#h#Q
Kk*kbB bRa!6CcNRPdLmM?LpH*IMQtC+H8ycutL<tw&t>\?6t48h1TmL9\u!tE4Hqq*cJe5TDeki@R5btC*^i5K
GP/p&8 DVAT&pGHeNSISG?j9F?dp9=t?A/>*=LZYB#lul95c&@=4DhS49NFJ#4K#hy^KnI*^YRKJi:SA<CltZh/
9!LpLG =<cp?KiPHypTVCH4TAnGqqeC/Zq4Qki4A\KbRjIbp>h<dyaNSGR6tIme%/tVXFE:<LJXnqPl/d\jRG8y
Y$c&6I SJ=wKl8NX=9t$FGB=YahAyu4*qeGMhRTd8dCQyl9Bq=Q4tmDLD$HTnnj95@FiFI=5Y8^WSEaddbJw>k+
#BiHXE BmCGhWm<G\ihth<w$bRV8I6nbpk4uTi!W#Y9*&P$!lqIcR=/#B@$K+$8J^@EFk8LIXhn#Z%FBFJyM6@R
<q8F6: !$\SVVG:pmXpYyWCD$=lDZ*^1ha9!^jiAdk+8$IVmNmCp5w<$CR*u?CAX?*#hp=@V#Aj1A<PqiHCuJwN
69&4By MeWjCQWBWtNpn14u:S&qh\ma+A@><$A=P%kZku+&?bYZ5VVQ:>8D+MDpuQ8#SCEwHAE#4&kychcPn%tl
9j=tC9 F=A:CFk!5SB69hZHeWQH*tmMTF#S#LijY1#qLm&h>nNT*hh9G#Zc46N!PpeE*RItCywSp*t1:&lL=!L6
W&i?:Q 6VtXQ<jcj4/b#MSi#b=:<uTL*nJIFtb^n#dWdC9:5Q8<Hy14QKp&mDLwuu^>e&#FBWE?eLYBSK#LnDk#
D#&%MS ?YShR&*8yEmH%\/$@WA!XR@?W%ePGZ:Ej1%Nh?CG9pyp#BWC8L4XK!S*m=X?DJ!wqPj&C=!&n+cd%A?q
j5Q?#F Nw9K>wH&^E$XAW/dyiEb!T%yuj=%hMQJiecX&Ek/9mIBSVL4t@^%DpL18/L>Mn>bKANp>%G:MH#c?<\u
:/$Md6 @6p8k4&Mu:TA61?G:qccH/NkY+!tE+YSlMQFd:l:ia$H?=GX@4Fyi5pcihj&DaP%Wy9n#1!McCupEPQw
eD?EXC wy=h5Zb%&j!5AiGTJAkLebGF$bn#FiE%QYbmE!H5YA6TH#iM*ZX%WN/kWYHYV%k5Vj<ml=KBwj9DEl#/
w/b&HS *QV>y8B6nP4*yPWj\k1E5MFACu8H+SBN&/Din6B#HW/S#Xm!FV&PLqe:15AK\=PuRpYh9KuY6QhXGW\+
!AS%m6 PJRlSQp1Ew4l6Qyq9HuD%DSPHnV*mAi6lHT%>KRKR6^G&lqXmtTjYD<XqlKZtLd#wD^PkPqtPDVANQB1
aa$G\Y +BE=wZZbnHj8=*Q6#=!q!!FTZ!CkNZBbLi@eqnGVke*c$=\+Qjnht!eHI$L5wZW:E%PqenX:6I?=@inu
D*bSih nYXp$R%4dZ\mRtAnaM!Y6:XRieLYp4!^/AeuY/bjYSYG%YPBpC5L%?YcK>qAW^KC%=pHH?qBu^c$utKu
M?1jtq M49IWLCD%DeKlbHZeBTT5#+S\R<u4m$lZ@kRB8=QWAdjLncFqtl5DbmW^e5Z44^?8Zjk?+HQLNcmZENP
:tn85q BX1S*V?y/!=VyR5?+BaTR%?DiR+C1J8454+8L=/5SNa#FTFHCV/J$wFDY@ZPHk\49XZDjb@*GPa44%qe
hq@H!* EGQVTm\Z<bE1ThC:Xem=u>pil&=iX%V#&IuYThRKGB%I<K#MBnaG:Wqww!GJ*GHewMiypP\Nu$aPnJYK
W$<Mp6 :#B1J/mZ/*Q>=CCiY%yeWmV\$Ct>RS6?Vt#HPnRRtIDj@eGV*#!^>i+JWZXwPWP\+w^n?aP$lt5Wik6!
GajCZR jy^aSyTlJN?pVN=NR5K!b$G/\@b<<P<R&uhQPHjNBlTPuM%FE\lM#Ya+ySml>/P#iC%LBK:IqJ:X*$kL
Y+p%Xp C!u&HYD*6T?iiLb9JRZ5Q%!m9/?nlDddWH^WJhtS$!VX5#4!QQ#+?tSdJlXAAK>9!%ZZBb=?TicAiR@t
@Si4W% J9*lcWbK:#mIQTl4nl!emCKht>?l=/IudEX5@N#$Ia$6Zt8#6\?tXFZLw*=kYn=>$cD%ew4IV@CbZ\+=
p#dmP@ C?jGw64BCBR<#!PMnJV<lCwk!bYRdqDjNupB<+CMFV?=5TWuRZ*N#Zt9=y8N=%4GQMcXcj6h84iRPGZl
Ri8RJN \?aS\9qH#JZLA1Q%*mR=TW>&?n=tR6yeId699&/E:T>MNy#1CK!LX?\i@KD5je^IF4W/<8p#Re:Ja?j1
XJKRmS @a6l=VABGqdn?L\j9CwlGpQy%HI9GAjyZ1q<9ha5hYiTu+YXA=l!V1ncHu4\WM9BSn$neSSw!RB/>!c$
AAkcL% JPa&^&6QGbdd%<PjWP9jcL?%pwQcEbp>c*&:Q!mF?dKt*<ucme$R4H9L&iWF+BZlq1m4A4yT/LcVVMCD
4ae#8V !8V/:Al&F6QZ+$V+=QLX&BeE=q+QCRwN\ZBPQWwY/XNtYLL!Jj5Adi$&1\$PFhiDyeCiqK<p&kFqJMQ1
dREJR5 5HjeVbFEnLJ<TFl\*XAaj\HbYL/mkt/JJRB<weJ>pIiLBwcM*iWmWZWMp^6L*:T4i1\eVWEMAq4ytuT6
>CeIKQ TY6pA%bq!VhV9kY1kZh%DST=B#TcBuw@pAn:CHZ=&pCYi+Zyb6c:umlY\PWcLIZqS4tXku4W=GSdMwAM
\qlaR% nl9wMV\9kHjtZ5!G/ek:DEtP&+c&S%5SGKmW%5N8pnXQ8#!lT<y8FS1G4Dw*!/8G+Bm6R4*>%t<:44Zw
%\=T9k Bp9h^%Q@#K@CBm6i/X1$6D9:IlhM9L5nM%SZ#kN=!C6Z65WP&acG+<@mD!LT?8#9D==J&+*yYiZw<Z9/
dIXMuJ m?m4!<9yBp=MF4FDcBwb\9P\LtNt8T1c@GhaB#ZHIKBGh%b!*^+X=@IY1#VnEDYahe+*&A\:THq6HcQC
/MNjJ= Q+Ha#4&1/6^y^>p=4FSW1SF9#\FWtIJaknwEb9mwhn4KR&KHI<H?:/@/j&Eq>&Q1GS6&!yR5TFEi?pI$
AcNVqd :NPliy>atZFlA6aIEt9E8W4DLEkI*n*cT&<Gtd+aWHHl:wGa>ZmFX+FLY=:\XNuniu!$W9V^9RA!c$kl
46XN%K SH4V^E%PyyhAt4hu=QEENRV##tXC#tmV1KXEZ\@pt^QapL8SqnE/<#m1#tCwcLh$a=Dt<b9%KBBtwL!u
B86p\u w<TKSa9#S1W9y5#>6J4@yE\Y>k&kAq481PG9AXDSQkn*CdhilFY==?Td9iW@kXCe+G6yc<!\LWe:yWMy
KcbEiq h!pbl\LIqt$Wek@#1ky9MhKYBE/ei+\dIDj*LCCte9I!:#b=9>kIR&qFKVuIiVcQXDqw:*Lywwkqwpq8
&ERlV% I\6<c8Ihj#4X5#6I5yhH58</Fu6+/6iG1jA%FC#QM@Ahlj1PE8#+>m1hIYHRPX4h^Mk*Tm/QP@E*BnEF
XA=Zl9 wFKKAM&lc8G!*H%cTPYdd%R4dM6ljBm/9@V&j>hyj?:6SXtS5D<!ku@jXi!@akTS1H<$kpnpya$k<1<c
jI/X@& pj=6PQ@\8Q%9G=@>8+jP9^bmTBkehku/N!L\d:VIJinjQ84D+Z>EI!=DI*>HI@?ISq&CS9%&=Pk@wpW9
N#YSn^ R@>&=GJ@SF<tc<njnS\B?!Q/MqqD@t:pCQkj$bjJGkKJ?A&N@CQ/MqtDm@?PS9<Sjbt5\Z<:e4E@wm?V
XmaAm: Njn9bBwT>pj$bdL&i+8I9E#aSBC@?eGS@/FN<j@a^@L*1/L@R@*>5/<VSj/F4$Q?Xb9mj@4Y@:>hFnZ4
4b%tN8 8R4Qn1I&y1Qy=1D^#b4nK\\Dj@W4!64\kIWyYNJID@JpTIYy=59w5wdnANJC*nF/G<:miZ%Y:pb6@uhE
+qGVT/ 1+nKb+#FGY$eGn1k5^LLAeuiL^S/+jaFCBKKnWt$@#5NRRhH!hX8+85MMa=<A%EA>4t^NYhiZl!<YdC\
\@uSyQ e+&Zt1u&<T*lSe^u9GNS^RmAYFX8ILKVa&Aa5m<y%Ty6ZnyGB+llQ&KSKi9D\CLHDQ8w!ehem/bSWd#P
Yl1aC> c$J>Hi+hqiVEBAQAhqheA4:WF<ieJ=NdeaCHjGM?BqWcj+Dk&#E>u@F58h?+1DkCa%kA^Lt\CW!:LY=a
:MI4$V 66#aCCAE8TBbc&CL\$T#cm!dMAIJY/d+!TJ$GByE&uTHpa4CbHS>bMItTHTR5I<@\?8V?HtBTFybFKjK
DncPlc pY+FNeKVEa8+=e/LES?uSX:<jB$ZIM5bhGX%:p8Ed4kk5nQd%yw>+mNAYapZia6q<6dypeYZPtFLAYuP
VLWkJY KkE$a%&mpMb*Fd*%i!dXhK&@&CKTd5EaB?n%@ChImM6PYaLwBbRt:!Vy&X?$/!GW%j9%\EcDW^P/Adk:
%V#K/# X/aTdia<VbTFm1QNVJmAdENQ$c?8mJtnSlAyqne%lkLF/Qy!l/?^>@uJ?R?<@RKqp+K:6$adt<5GBiDi
N=i:p@ c+j#<GJ4iAj^iG%hMN6!!4S^$L6tRd1LmIb>ea9JXLqwDT6##Mi$mId/+9CP/H6F%NKXq5yS$%PJXkQ9
iMmDKu yPN9chtppmRt%nVH<*Al*%F4ea@yJntW#hHVQ+^RXeIW$dNhTZ<m=qm>>6c*49cH&Nn45!%4*EAh/HRk
l>#iFb cNbHue+^P/L4DipX\c=48u9YS\YKu%:j=B<khl&%?/mYtXk!8?1:*tPNRqd!PeKZI+YF\4%?mB#^p#^C
\Fctea CcXLnV:j9^L@/4EWFh*Jtb%?mE:QCSdKVkiBK<R8uMAFlE*1le9%PJGyy4jmPq?h=lIdIAM?4NT<Cc#e
!&KwKa &Db=Hlp^pRyBDy#<?FBF><VR:MQ&Hac/Tn5XamjbP%dqMK8BHMPdGe:#NZe&/LB%4l*jI+4Mu/8<b<$#
jttN$t JJma5>##w!Kl8^M$5YpRctAcQn>X5M1a44E6TlFbdeL%\K8PaiE6wPCB%=*yb#XJ6e!GTw\D%TkeBS8I
u@qKR4 H^uPT<&=VpDBpMABwA#>CE\^iVL/dRu5\C6XLM?!yG?4G>lQl!!YD!#JeS<LLN=i:@V&n<88Q4R9#WIY
^Y<^#\ h65iJlql1WV8ciRFj\S@nPALGcRi+5\*nNY%d>cu9pZ4Y>D#IucI<aF#h:jMBy=C:Y?Z&M+Eqc<*F1!&
GWTiAc G*%9>JH$ne?W4Nn=L$aKeRy9?\p/<tT=d&$^5jh8i5d1W$+mFV<1bH=t:iS\lEZEkqhTp$+GP>Kpu\#=
#iw14L ePENi&n!X9qm+SH\:wcE>a#F=um+Zt9#^Fnw^Fhu4/nah4w5i^DbP$eyqSm/&1cNc@N8GWc1&y11M/id
FpiiXZ GWStu5/E<BdQtS&@RPd:Fc$>/F/dK^MiS?HKc1QAL&p=uh:8Y9kWb6Z/RF66*T<Q%dC*tIKRFAdGa<w/
X?>bG/ <?@4ABRX5p>/LcI>S?1&#KWn/5!<QaYITD*>F:Xy&^C&hlHBqkeXH:8t6j8NXAZqYSQ+bE?MRNb<VGp*
M@!9H9 E4i?i=wCmMmF>R+5Mm^DNb\:\Jt5uWRB?XS&YQ1E%8Y6#\t%*$wI^*hWFMjqM@hb+NpNBhwTSQu&bmbA
Y$%*hy 9WkmG5:$YDPh\%#?DXqtJYCLwc5D*Ep?4lX4H&5<LElCcN*QLI5?uHGEFCjm@My+BuYM5PaFycq^+#b:
h%Jyj4 ?:n9D?@#bdYJyTC5nT*!DClNE\Z1ciMa5l+w:Y4hTb%4!M6ZYXEPa%Iiwn5>p*ZQ$^MA!Im<WDqI#?DH
IaHZqk F%a+5bJ=Qb:APkdQ:LA6>FViq=d4n11>@wcH4!iXknnA6Wy9Xnn9VdycWLhYV+Gq?LeZH8<FeA?81QRQ
llIp!I p^1>LZTw$XTXBmm*WH<qX9E*Cy9?TAT$8b>/Cw+aWZlNcynBi6eVa<n>RKH&#IM!44uAWN*mi#?>WdDn
%a^=P< h$#IwBa^b>bIbWdJm+eW1jttp<i?L18$eC@ZM<+i\aA1D:IEd%>1dh^hq=\F>6ej$$TG#>qd6#>QBjBi
k9hG9C QCl+HLLA9<yXFcbNMQeEGDm&5P4Z8/+/VS15Ad@!!DT^@bCpSW?H9$L8D9&d6<Z9Ww/uB*j8$A>i4VLc
-AAj9Y 000976ebbca00110333 Page 434 of binaries1.zip
QVLiZ# VGV9=EL!tSblH8:GSS5NQ>@<IB\5!aA4ZI>RcwdmyXb@dn4GTjWGl?uL%$w/=ly:h*q89^=K89l\+F@A
JdpmXY b/B^Il$j4YYm=^=Y1Wa6YJSB1T&4?@4nc?D:?a/681CQ/ZQdV+X:JudtAD5/QC6t/HPV<4tFqq5Z:@81
>tPtAN i9!4$nmZeL^P6q&+Y@=^ik^tP:ewSYI/\dJFF9A9#b4F8Q5tmTlQiHXpi5&>S#ZMd*n$!tc61>K1K>SX
l9kGSq XPcGW6hVp/J#Ih%T9hR/K48WI:5Lh%ek49#Eda>V$<ttRQaFu1G/!S+/CL8jq1n$u>M<D=Y#y<MT^b>G
\HA/hn dKl5y&dCQHMp:\SIHhD?@N6M^<$ZDetZHhm:<deX/?d#Yyh/uT!LjAHZc$4PLFB@Sh^?H6WCtB=tQE$V
yM*aNX Xk%ddba&ZNn1:+tye54DQZBAq6D%SA!LbKa>WB*n?S\1bNTS!ciRZ6QpN#$quke8@5R**InwVe9RM9=<
#JLIwM y&+mDCAQXj9RuCc^cb?cBm:\GZe>cAAX*mNdTDQk#eqPHSLdnX^t8M@lae4VpayGFXj<<9Ie*DpiCR8I
G$IkH/ XnQ>/1d#?q%dac@8>X$/Q#$E#?LD!PFt!K?H6/1*ml?Z/6/<H4^+IpL?l1Zn+Gu<y9a/p$yd+YL%!>A9
*G9iPD \\idZDNjLmw<Zu##XX!W$B%/H<i1d%TeKu#NlbhH<%D\$jS!G>PZk!Aq9WXM$at?au?wMJj%WEDPe9&D
lAyR$m CadFF4W?%&DYjwF>d6WLY<i!pN+*Bu5^ERu=TVZEeFAB/@P8e\QYbbPk5TT=BJpCZlIkKI>%J+SDI4:d
VD=$MW 9uTHQ$HkHBpA6Y^dD8#p@<+Dj+/:nau8m#6TGRQ&%dlA9#p?p%JZ<uFJ9#Q1?X*DNJ>nV1qp/4Rp1*^H
hLZ8EK eKYQ5cR5:n^m=R=Ej>kM&#&wXF$AZ:jQAlijjXSkYZjFQdePJ+taYtQF4JapXSiPuRH+?$d>u#5#L66+
T!9dP+ u8&pd<w%%Kl&HacZSiNJ/wBJucE:>Y5SKqp+qXYb\Jk>y/E#ZSXBY%c4h*m9<&&5?RlIyb>ItT#qLh@y
:elaC# Tq+5bbX:$/d6HdKIM86:X/nbcEZkhp48%l6\pHYDWXCbPb:daQ*cFaJ*?I/GuF$%VT#cRjWE1+Ym%mK#
Vi@HSF Glil:upFmZ%ANd!<GdkN:y?EpDI<CwZGK6Aq>#m&1<$#D6eEKjtS!Q5pp4+t+uYGXChESE<VEC^H8BJw
dmcEcL p:/t6PTP:Vp\X@bkm4S>B=PI*!@V549LwuTjkK#9F+/iyLA%tW@Dwen$i:Hnc:juAB8NyW*>mV&@K$EP
NXc#&J XFFERV$J&L!E^QXF<:a+$HkZwED5>ed6w%CwRciT&$=T8@K#eLi$:jAq4C1SN+BblYAkyD6N6pTeHc>&
aqH:^D N>?1YmDCpE@!Tl!nVhE<DVG*WyEc*6*\Dp&bCnZ*T5%##tY5hNq*T:l@MQYWw#dBjR&jd:kjnL=nd&Lm
H$D4EJ ykSq:6CYpSB$6SZ&9S%mZ1DceliBJibXJP/!9m1P<ST/pS1iM&FD%15XiDe&=JXm?yH5EVq4!IF1/$F+
yTqQ<N Y*wqd@4YMc6t$:i8a\lG?44LEtnd@YiQ%J9itD%?#K%alq8^u%qmM=E<b*H=PjF<IBZT^:iYh$DXM!k8
mGW>N\ ltT?t8>n=@nnw&T+Dw6:HRq6F>=Pi^%WkM@1bNqVGMjipLQpNay<bwiXS&6>@:HXA:umj5:qeTM8daq4
J*+44k :YLj5Cb8w=c+T%>YR4?wK!JEVXpi4XVB8m#k9QYJQZ9*QKhaP>L/LXq68XVq54J&t@&kM:Lu8dAe9@ik
::!YM< HmpyP49WN1/HyiEAY&DVP48XA9chI/E6JT6S=/KMICHwA+8$\jMN1$M<nWFb\jI?Q@JDppwni1y$%aiB
BQJcC* d61u+>BXIhY$XL6?wW%!1ECj+&BFEetMW>!i!kFYY!hGP/@EKED6lQd:mYw*VHXk+lB&*!*E!/$DQ#DY
DG4tMY SQp5YDW\1J9#qRJF>iCJdC/@:Ad<nala/CC4iXhWAa&a9q!+W4im/8B=6:44w&+HSew9/GFdZcYGiH8%
hJcJSE <GWnG#e^#hMZG6F1#*EuNl6\e6dFSt8naK/Py8=?RRi<CwFS$$T*tl8jEP>P#/i5yiJJjwETIIF6G9ee
R\Wk6q !N:16FNy%^q=RB1GnNk4lQd4W4HI<6nuPqDA!@4SETTaMGh*Z6@dWG&+h5>6uwnhB*D\bq%6SEEYRFK*
A9AIk4 </kR=RN/aP4XZSVc!\=$eQ<SE@H\ke?#Eykl^:EijiAB\bbYGEpl+kWn=XBN4@/YRE*TyK58b1Iha/bC
nb1Y>m tcD19CpW6T5$#HqI**Kj#9BBjah&HW/HllS$Itjii%NSd%:+pF8hm9@dk%FGiW$qK$Ky*6i$y@^Bu!8?
iJbSwn cQGIBdE+>e6yVehWen&L<A*DZJqp?l\K=*GC+=QSpTZ8iNmV$YnL\m@t<R6ZTT1yXe\yudFA!!X<**&L
<SbyK\ JIYTeeal?*b%Lu::/nTLIBWFb#iL4qPXbe?IIAiKGehMi<PaV9+X+MaQD@V^nJ6+QW59m6Z^e&5GuP^\
td@JZy ?YT5m<J6mMW1R1I/H^%C6jbPFd@Py=<$$>YkN#FiQ!<*#N/m1=9BRPqRmaTD!5L!W8141JYJJb1W6TFl
V@#jRh tdL=SY:44/&LV:/a!aWP8Q=RcyVYEZYkKujRY^9V&$L$1YYh1bwE<i8YCWaR!A6HcuALe^aYwX#WVX44
G!QqEW VKZpFGuL@TMmHdl1:HFCM/HhcR::Kc<nSuC%d%TCwQbk#:$9DK?*?mBb!*Pl&muAet?>hIjaQYY6JX\B
W@@uwE 4WP!D\p%%c&^9Zi&8myAi?XPAWLFn<\lXVbk:!RNMq*5hW$qNk?ldR?u9WpkmVt*!d#RnG*E^4eC8y\i
jy&=XK d>9IyQe+LL=^K8KK/V*K/$<K\1!=6FnKR$D:djP+PF\*w/+<1^HBM1k<tbA4I9HVpHuZTRkR+h&Dja?#
Pu#VEa :>mdjy\eci#?plH>qVEWHte:aN<6a!>Tp!n!y9<1JE>+pIA5ZdQQITDiQGDalnDkTF>YGb@mH/>9BNJK
M%V11\ TNGK9uFFlCVi$#Aq:Z9blwHaFYb?YSb\QDFY?9t&#9Xhn1Ana&%Z$!&X%:aFFqbql^VS@5Ha^5kT\R6P
*V+Abb :5GnJ4@+pKFK>d8/CqG=yu@>D@N@h>d@Y&l*JQ1@1N%F$j?w*WXSq>d8j*ey@&By@pKNIhGZFihI5W9R
@DTFIm 9=Z&TQFL$L<X=!naH>Emq/Hl+4?l+Z>EI!=D\*:n%XDIQ/JSq/BS1N@S/D?mL=M%FF#$N:VaH>GZ!hy9
H::hXl t9RmaYnaH>GZ!SwT<b8$wPF@SF<tc\n$d\R!G9qH>GY!l9nhd\!N@mQ/MqtDm@*81wu>EZ&b4MHS9=pq
enSp$C w4A@wm?VNVnmN%hNFQ=H>GY!>99qBqHpj%\\RKL@<\WDJPLjLSmI@%Zl<L>9$jJ9Bd=mj:8A@<j$BBH@
yhk8Rl Z>\VSDheG#wd>i>:k9!\q?EZcNMi+wn$W%GmA?<^Pni$DbbeMNaEkJljWRpPwqND&q8eV=ElF%$qHPAh
9VY^G@ IPM@4SDM+w8Zee^9h$LwTumFtG9JBEyced@Ka1m^/IlTX$6AbbXlB!IIbnlALaIXt/A4n?PMwMNVt^pD
p8MDbm wtJ1^RDejtZwDBt!d>y?AyREb6hK@dNCj8Ky/wmb*w\QDLEGEnN16:RLaC&9X#u/L6jXWMea5RC8^P*!
FTC^+> n:SnMQ*q+YNYVPXIa4y/EbwnHB*YL?IAGSqk>RPnZh8!^qBDl:WnllKT:KwCmBE<9IHE\=1TWcW6P>Vk
6i5/!H &lhMYBW>8b8Tp?caWe$cPwqjJDCQ%>c!i6L&<&1GhCkc#Ckdby^aj!?IlA:<aA+4MXP1\*wXM&$Y#>>&
5dd>Zd KwpTKBLRTi>R%WFeML/9AuWWTu%!*>i4Dk<<c+J?#Jq4lqJ/=9wCmD%BA=D\B<G!qaNY@I\DMHX<y=DB
hD8^&& ?4GSYWAtZaQTR@AJHTBeub5c+wkmFAh1S^dWY%utF=IBmEGqRSXiJtDqcc!lhLLb?W>aa*uVpmY:BhPb
hun&#l QS*pT\@b1*Z^w$/m66YCbP::F+CdGJP^Jny?kI+empBlpEmy8m\dM!F1u5V!9e>5#qW/d#$%+y#P@P!G
#M?CQ^ 4Q8?q^e#uak8TXKju8+>:jaKkVht#c/G<B?Tm+uRcKPn*jS<nHAh<NQ>jyD#EF$N@ZijJt^c#$jmpV1C
uaiCPn HdVY%nSISPqV*NTAb&&Q?c*KtR<!VaeND$aCHiJqj#%Tj<HymaB?VL<1$i/%n/XYh6AVJ=b?TQyRWBd?
S=w^iL 4lL/S414nip&aa^n+hC^V#i<VRDyLTEnuZDA5LjHQCeBQTZ+\DpkqnN4?&!X@*B:<Ha6=58NAVMB9pn+
RMb^1P G#ye1++$tmJ<n4Z&AYlw$Q!lATkXKInPt$=p^!9dZk>ApC=QW<5wR/t%bqH/kyN/<FEd&C&d86+hCyP<
ET4Q#n 1%D1MDBtT/KD#j:<tT8PqmFF:jW:Y+@H/4bydLpnGltQVb<w$l\\umyy5I1a<S$t$QE$Vm&t=%Jw1twI
5&XkaB NFu5BKbu8#@*a^KT<*AkwQ*c=Y5Z^\5>Re<ScH<ThmEZ#dIpGP>Mhbh&EqH66YTMaeky$FM*R&XbT<Wc
YPYD@8 =?GF1u!atRk?5PuJQbaPjb>S<=q:KCK6*Zd@>l$W$X^ZlP>DJ!E>RHDREiQc!aL?8N%\Wq:P>VVhEBLC
KkylHl RJGcWEkMYa^uAund9P4$\F@Q9!E/c45eGq>^+Vi\H<bqL>wK:NKb4ZL%%%^EDkLDZtaRipNbjXF+:Cji
u?uJZL h*Jl%6d:6V^eYGaiwwwZ$qQWyNwZ>:RqAnZm:iLW<=LmniXiCHG%B@Al/EdTyH:y:/nQ5n+EbZV&8Yc1
#@8mNh MMJdm+X9L<Ae>jFk=iLQQJJ4cW>#\NSN+@mc^Qi:K$C!CVFltEZWNX=#5?:y1Z:MMHAmHG6tql>d!+&4
+h>HpC yQWjW*FRNlcc!5#dNp1\\8yJhmE4ci/jK98KmB!<Qu<ZFd<A\>VeP&9j5VYS:hCLeE6I=?wdy=%NJ!p?
ALH\Tc Au>waFb+ae!4aaRk8yYC+D$y:qVHXI4HKC=Lt&!LS^nc$ZR*%!\#^9C=k51ZJB84h6wnjIXADi\b@MGk
^ml^=D 9LGT?G#=jA:GuJ$?c*h<%aEdH&6hpkt^bJlhBY8DSKJ@N8$ni\B6Y1qPT\TiHZZ9<iiu?%P#:ZiLtXF=
<e*eN/ C4RT<wcewLIVIJ!&nTEAtSPaKE?y5=9pQK=<Sj@Dy:qIFB+N*jXKK$YPPYb4D?n$e>k\5dpd>YpIM*c!
#pmIEc D5%jW>S$F?<\%iQjtA?kLcJ1qkX?%m&YBT*1#+dJqc?DH!@EJkVk6E@<*>qSVkC?c?&M*GPTuFmc$+=9
1Fe#hM 5@>1&#:Qy=KuV+th5@?yadFLE8=QD&$mPqYVH*Qnq6k45\84/d$cRLRk>NK5\SWlFZT\?#+l8b:?1+ZP
hG=yRK K<ctt$&5jmW!\=^ZKau>JG=ukR@5MH9Ydp\B&!ym?^#D<&>9*AmTiy&\%<u#lPkDR\n4k*lZ?L#E\%6&
q5\aR/ :\ijW&n$qn=pTuL5qH?SlLktkiC#=Q*Y/6B\kC5I4+5K<Lt8:X=\Z/a#5=w#b>Rt=Ic!^4\B6?ZFq>6b
IX##I% PdP9XT&C?jWtR:NtiN:dh#!cNLbR1%Z+5Em@VAHq/uE&+Ha!cXD$MA/nF&9/RKliAE4R=l1LGQ*JliH5
wB9YQp juAjdN/hd*%w9BmeH4:4*&!uLT&i4:bT<hZiSut/ZXykwtyt9/**qY+#K6k&?9kNLe!>6dubanNlytAR
K5IP*h P$HjhFB8=ZitEk<IJ+>!h6W!=R6un>1q5phEy6e8?MK^wHJh1bt\*abbpuEBpIl+?jRd>Q6Q&Qyn>?YJ
q&J$JH :+Qi?5=bXB1Y$Pd+5NHQLRyiZ!St>uBYCH&uIEp@Qj:8Q9?bq:\pVCk8JCk4<JHQ\5B<a\A9JTQVcduT
-Aw9X* 000212bc2f600110333 Page 435 of binaries1.zip
q=hdd5 :GNeqh#5c/IGEHGa%$1hHyA9i\?+t6nK$6!9d9bn4KKq\ikp@:$TSS4mAJy/h51#8Q$NQXu<+C/*X5b\
EZn!#V wTLQAX&4WKyS>P&JH\9eQd59Ju*FH5bMHD81HW#ZR@\$AQ%J$!<W1#%TLi?4ZQu+LS+Huy6^\uwiLV+b
NTdlYB nZqWnnbDh&\8<RddHBWdFq6E*aLH!//XDZa54bNDEp\RcGu#F\IjTWAj<8S>:Mwat=VDV5w5V&/hZYk@
Ml&+DQ h9T1Z1=@eSE>#^*mAh8he1ck#C1yFZC^Y4$b@@tV&@ClTI9alj>:Xd$Q9EIW9R<Lqh^<S9lt9wDNyhk4
aNub<T ZETV+a!cqAkYXj@C9JcLnT5*%nei&^Q#95XL\I1y*@y#&8/8>c!4RB^XIGw\QbKRVE1^%1JAm+$weq8#
Z5nQ=A Ht55iQukb!k>pVD:Y$GC6#G<a*^$Z+NJS4pdSt$lnWy4ykWD>?%$5SBtcX#Ywn!FNXZSG#!b?d1l@Z1I
Iy<8/c IR=i!BHZ*MQ=hBqnjWSpT*GpeYTXbP5e!^$t#bqL\W&YVtadaC>MKpeN/XkD8nAdpQQdXFZaHnXVlQmi
qiWpqp pX8aed$Ea6X\%H/WYCReH/IZ4R^\$RGMGjXRbKY=9Jpta+tuml9C:$BB99FKQSNdMT$caR$DtYZRyD&b
Ra$FNc n5c5=i%X%l$B?HJZ#phIYVPP=XZy5!?pB*YKpyDNm%p*^6tP8ntTMV>KL#<q^tFktM:tWpY@4%BRuJWd
n\5q9$ j^ZBSQyw$a88G!1C9uG?NVH>#/JHMm&G%5HXeRCcS%hHV1q+RC4CcI$NMCS!/$StI\59XYLh<ICL+F\X
<tR$&! ea%91qdah$SiR+W:#4d+bDXcLbXKm%c8b$&8G$mS=cG+J^VF@HbkR\Rwj!*a@1%1YJWm<9$1L/W9%wl%
S@dR*l k>JZ&+n%HpAneNe=yKEwQjIk#qGna<*%ZHD+DS#I!*8ed5T@aimCFkw&pVjDA54uPRG*q%W9\k+4tuJb
<><b/# $%#/hwyK4PTBG5ZMHYHj8QF4\6&EHCZiVVp:8:\lEiE=DTFV5\h9<nBtjyyVAk/Q!Y^YuIN6Z\m5&FS/
LJbA9& t8+QVb%WFAdt!BV*QeKQ&WGBlTJQmQuGtkEBA18k5PM#PDDL\/dXCFmq&dE#5*G?+hBQ#FeTT*6WyMn?
>eXa>l K/I9l:b4Q?/6EH/a9#BFeYV8TAiaH=lTWZuqi9j$DbwdC4k*W@!KN#1GND8&il^W=kjqLLma5S$ZRNip
ta:HpC ilWKiFTtQ%S68b5W8Y<6/GmNk5/BJ+!1=G>I&4nPV%4%YH^ju>SI^=F!e=8L>Xkmc\Q4LDckwDiQApnS
tZn\^t DtH\iFj>p=%K!BVW?m%hd<tYt*b^<J9macq6:KtcSyykY?GXAe@\p8BdRj^/9kZy>pklHdPtmpKKR4Jb
GaT6L@ iFSywLkW6HWNnQq58&R/PcN$JCJtj>1FKMC&FWBIKL/RblwA?t?P?MC5CbVmZ>H\^&MkpXJ^WAE6E<G&
#P/CR% niX8:yZ+$%&hZ*!/SC%hNlk*V5Zh^/?CBL*IjLB6HSA/X9$8@t?+Kc9AJGli!M5aPE:VV:S6aA9^qq%Z
h+4Lqb /nbauH*RnS<+KJej#yMAFS=>dMRqaY#LcX?uY#4<lM@NkK@8@w%a@dq8S\>8e!Y+h!X!D8eR=SyIwY<*
?>G?pI BKZ%HCJq*$@aMh*WhcQc5=PL&<h@9DtJ5/5k!/J:Dm:m\5aTVG%aKc%u^6TR\jE:YJC9Dcdk:kGa4m:E
&WpaHV ji1nckle5dwt*u>Z\@G^WCK\c%RX91eu*>NNQ&dctNZlH*tX*DMpaG!hMyBV&&\dkw$Yp^>+$&<N\iaE
+GPut# 8a=B=P*6C1\NBn\wBL6m1Z%PiNq+uSl6ce<DQ/pb&1yadkT!/\Zc/BblnuaNKY+5!JWE4SME>WS<Q:4L
m><=8+ eYXEHWulYNWcT++QeHMV:95P5yuRTh!VByNM?GIw68DLMepwQh@>TIwWeq*>B^*K^jV*6*E&&/+VRIqZ
eAmGET ?\Wyht%/?8A4/kjujNSY<J=^i@+pVJbqJ$t>951I*Fq=WRX+I?T+1EJGbk=eyj5DhFh6W54aMiJe9W&9
1*qe!$ #Iuq&HM#!uF6%EhyuQ!cwFjQiE%YJdN*^/y6&Z6Fty1cpWJbRc6N#8>C<Vuy*h\>M$ZDG8<Y4!RM1ARP
KPtNMb jWdJpuQd1KJ@+u\ljNVdb\4t#l=&&IM<wTC%$XpPh^tLCub69L:e%p&ZE#IH/1EQ>d:DB>BXA+l&=M1d
SKb+dt /kbZ4/<kc+4*K6#Ck>1LX/?=NXm4N!m<$*Xh/1X*Bh!\Wj@k$Hnn&RT8!QqeY4*#nkklL>$9N%Hi>+tq
:!5\?J HtM?$Q^&X5FkLuBYNuYp&=eud9wP>?yG<9J5GICD1HIDadlnSmH@C:eB#@:C1=1b+LmJZq1T>GD1G14d
eL5G<! RaE@^?q<lELLanahH68kZeujQpbluAZH9yBKkMeBn%X51>V=j>iM=8>1?u<L8@+@6$V>@<C8m@>Ft\9^
a*AWRZ !:i=EEj>yX$Z@R8QJC4/D>6#@ebSm+yjk9/6+ScD@SE6elu/h+bdDQ=HNPI!>P<M6^n!n&nWJYnW:+!u
>aXumW GQ1QcNHL$L<h8hkj$bjJ&t<L!<Xlj$SjJt5I$h?pSS#?S@Sq59b:b!tP@DMe>S?Xy/nwj/+<Sj>hV\P+
mk*NPY &F<yV@G@:GtAEQ8@NhL@ca&$M>>A^Q<9c1RB:d=t1>YX%B5T4<%nHPqA5mdlHBGXllbVeyG&hHYTY%jm
WpdXHF =9DKSFJ?m4FH#9WW@l#$QPWS49SR9Hb6B\BPBEyu8pQL1M&mVKn/ki6&nYQW%J65E6AbM8AFnQpP4SDb
=!eBE! GF:#!W<G9C=4CF$\VICdKakaiXZ%%lFelW=VGtM5CTCTujp!YjbcXEe:\GFY6ydKS?JM&\<kCeEnjH5t
9q96J: kYyq=\NSlGySEn1/YS?MNAlJE5/\eR:uW@NWdX6I8Ih9l\VYW+lJ^qD\e/u<iDctE<AlLWjHMJK\*<:S
Sk6N^e cS9V<c9iQT:qDDCy=H++JIk%b^tc&LJww+k*byMGXQ1EVIAMAe4&RKSi5Y?6*4Wn1Xy95=*JY$qCilnn
uZppXY /Z9%kWGM>=Rthd#Y!XAS6T9j/RAVH9#W=Cei!yDc*B9*NJSH8&eDAI\55ZFW+9SeHJ8ERG9%Nd1<6DQn
1c<Vcp PZqq6@/nZB+bt:pAHn?q?1lkFTTdE*pK66Gitl?ke**d=%Y6c68^Vt:uLMh5#c&cTYCT?qMH+:L*4<IR
\RGL&L bdKHGqFDGi#DNdYhAl1n<^uF#y6nVl:KPq=Qe+cX+4P&\SPn/!JyTq?V4>4DG+bD/EB:tRc!AQwq=wEV
l$cL$I +eP4L@XMnGXXID/*%#pP1ZwBR=/9Gdbq\J>:DH4%Z*jQ$@wbA@cjPed8VdQlZJHLmMl*w%!yK$+MEb>4
HI*4l5 t\k5Jt!%QTSD9nqY#ih8IQGT1h?V1ZXcV!Qim^weE&6eQX1ZPC*kpD8yiS<&KN*XqCShw!ATG4IuqVjk
%h+HyI HbBq:aVyF^NT*E8ppSbS=V4?SWjeA1L>/8kde\<tFYPYiuX:leJSmKMId^1jELaML:hYaVdDbVBdBM1W
i&S8MF w%/TAnEN>ETXRH:=RB+q\#lRT^:iyh4B*>ibWyaYiP9w<*9@\MWuHYpEAEJRj^wt:1Jh#pA4/ph>4T#<
kYZ:ad ZW4yJ1>kN1pWM5@wb4@ne@9yu&>QE5DTj6hMm/8n$1!&&wbK*<G48ACaw+lET%*c!K1:N>wD&+F4@JmA
P^HEPq 6uca<Fd/NmHS/\k:tuIi4JGN4JphV4HcE/:WMu1Q%i/JKwNYha^Su1#KVe<IN4HdkDDG#E=plPPF@5&=
dd$ZaA R:::cc/&&>iyB5tlB:wYY@bckSJNiw#=j=54wbZ>wm>>^&b$I@JJcM>HBy86a5h&e$QK?6&:b*l:8a45
l=tk4L 6Ci?I+i6i*atRyX+AjeiCT9VpM=&:RTKVBni%D$95*pF%w+AH\kbQMdSS*\&WFGZKS@d8QdiahbqI+SP
!6euRR RLup1^@J%#8PG@^nitS%#HdbTl@u8a89@G!W=dy84MLX\@qR=68<DyQBVu&cVNL*+Shy@uplV5%nP$LK
KM4d<P 6p=<4y89VRV=Db8G>4+DcB$uBQQJ:Q\GFAHn1Xip/Wc95ia=?<KAaGFdTd$ZWy/R&HhlN\%Qi&WF?i>R
a<#$DQ ma%$=yQ4V/ctqYq4Qb%Cb^cCpe>m!E&L8J4Jp9MpLZ!*$\<C=Le=@DQIZJ!G#b8?pF*j/m4Q*ebeNFH\
QqCGeB blACdN&eC%L%u*DemWtQhZb1Z^KhV&k\aHtjw4H>mqhq4wYc>cG^MKFFqu!$5i=8RW&ySFhhakPn+&yH
Wh\SXd :aD<dKw>8T&Xpce%Z*=F1@\HTddFA!pqmI=@8H*b+8N4Nj8L*?dq8Qe!84QLQGqGb@C4SlFymk@kV9M6
m5bRb1 Bjw5M<M<$yBdD<T@1Z\hKl?6>SKpR<?/:66KVAi4aKGaNm5@59nGB8+Mnt!5WStYjcm<<jZW@NYuqnNV
LwjYWb V+\><qecGCqJX^N8?CXc>WpB1#/85L@98m1BK<6djnqc$9Rp/jX8=8q=F4a&4=Gk+C%Cut::&t=FV>JF
%C%Mkl R*E?YhQwa!dDIuh@K?BN?j5Q/HJHaq%9jI@VKuD\RqSwZFjNqW?Mj1bR\>bK4VXWaih&pqk8>8ahXm/6
GLk6ee \MHd9VlF:\t:b$DR$lILAHV5i^hR\lnAh>HE<*p=d<!1VLdmATc:CVH@wKPPRjY16@D$mpJa?m@?WI\9
+cE!di NWZJdQ<X$+thP!NGAQb%!#pd\%^5PKbj1ilmZci$nH+TllN9H+a>NCiJW8?6/j6@tL5Y1J4T6+<8TB%F
hRuynM plnVyBKT5>>>P>8q4=98$p%IbqSPKlXSM&VGKKW$qWwMmWt/C$pGaW^Zk<wqq%d@aX^!T?+!\^nj6@e=
DdY65\ Hj@@tN:#QXdY?4=qYY9L??#>/*q@#?X>*ti@&/+8Y^1wWl&jiF$!5Z>\+\*WqlJ#hhH$1>?EF?R+j?NC
N>BYiV wb%6QyyilYdVP8a$QnR:>nLkkYY4?c5hV61%Fd9&Q=c!qLb1$Jl>D^bd^uy4m?<X4NV&d4hh9?@IbN5C
Rc>E?$ w^HL==@<uB*4@GDk4aIW*#eb%cqHS#>yG^qtVt$%>Xuje5+n4<V4dtHE^wT#Sh=q\ShuFH8j<4RMM65j
5cIZPi eD#e+:HcD?MKa&*NW@X*9qnBJ5cEP^=iP4cR5$p=JQ/Za$q?1@W91#MmSiTy@diLX=<hKYGRh9bw9/l=
#MMa>& 9!hKm%!YFdu?Xd51Ka*+daKHVpVFXc?>F:YZDZZe>e^9ipj4W?e9Ap!me#:bb6u8cNE9\hweSbe%H8p/
#li:NN Emj!9j8/diV!*^jVL^\uudl!yh@WYhwZLG>hp%:k94?eHGp*\9&5Cjp/^>%%1WY@4ctXu@4<9nlq=R<q
X@#M*> Q198/5XjYuSNZ>i\6icKAbi@:eG\yIhV!H6GDZ<5Yn@5WZ?6E&&^>e=:Z8%#?K?>G$yD5=ctiS&49*Lk
CQlkAW 5?<*?G<TPj$%b6&T4jM&?D?t/EQ#*:\$K6B?XQV:1RD4n14uPWM1k8JiXVqE&*bWDy@+1j8#<Q6XQ*bK
XFGwhK @W4?CA:=JKua*tL:5I+L8j%j*5tXG6ut*+5!PVhjYu1<j%Mj=&YJQ>?L!j9SK:HK#>VKcc$+eJKS9#VV
DRF%#* V!*b81CtZ4QR<9G=wLMZj!w$&>T@<WD6bN@\J::=t@4bZchN#m%>yB<++>u&<Jijl+>9tjk&4Lk>w>G>
q<N^/% ^muN?4=^aHI4YjK%*!Sh!@Ka%!LViYX#N66Lbp8NjyWtc>VuZY9QKayQdl99tdPWKVB5YD!YCT$\jnYG
5pn5im t6WiXQlp:TBNEYu@&tN>%i8J<e@ENyGNw9n<=B1HI/LEtm/VaRQNw1n$\&@V/$V&F9uy%aP%G@cZ%\??
IT/wM1 >iVF#\5VG:>ewN%ip@btyX6K#WN1S/Cl=ql1\!JQVSQ*#5SqM*eHXcp68Gtj?$nHQm4M4uPydb>/=4n#
-ADDHZ 000516d4bf700110333 Page 436 of binaries1.zip
X>@@$+ e6*dYX*VDV*Z#FW%V%yl$6^cWPY4+?a4@jGwnq@$*k9BK6b/DkN<h+ei!nM?+VBc//=y<&$44>&=:Sqt
Z<#i+< NW$LXw4T\54c*Y!9dSc=lcltp:p*e?PVdyYi#m8/e#LhN$@HK9LipP@W4<jet8\ZPt&W\:JPp/QDA^*y
QG$kiX <Zwlc5HF^iW?n8ZihhhFpchVp6/pG8?>wNHyEbh%IhZZwa^ycn@uMG/W1CQFThRbGqcZ8Wi#?JcaTyZp
AebXdk J+$/Z@#&$wC^SyMc@u!+wPq5Zj4i#BtqZ1wt%aQ55:<$YX4ZQt1#t6EGpZFR$kIWHpy14a=NNy6d8uD&
cjyk@^ E=5dR=cdyc^aklLGXiV:LZcjX^G4K$&&HF8DdChMPQY/#9Y\d&/ul=1Sh?*ptS%?#%X5XjJV^:5WPn/N
5:6pyt HS#cwm/>9u*Q/@S>jWiG6Zj6e>//##&wMLuX>61LTbNFk^&M%e!*id#PNP#RuKu>jN?AL^8eI<h6I@1e
ZMRLV: V1l**J^y4h>j:&^Dd6SG$!=D>\NNW/u$6I1ljap>!j+dNX4Y@?^@e6Cw5Il:pbW4ZetSFibEt4ynkqF$
ZAN$%4 li81^lY#py86Wt4PNMcSk*!VT9!H/I\tG=8@5bi<pAd:tE>6PHNIe?P?!Tuu>8S&Nyy9G^i^iLKJ1@8c
&$9ET4 P!jKtJpD*FLMC<VnJp^>juD1Iq8>BK6H>icZT<Z%8=Ph*bJc^8>NT@Ga6me1K6ZttKdIdbDdc@Z&y^GY
WB!GBj &SQ%uY&^9bje@=5nD:n@>ekDC9*:WLq@X+jRQ$<6=u<GPdZaPmJmCV?cZ^aT4L^Sld?kFSi5+wL498n?
1djdSK FlJ@wSk5WR^YQI/@Ww#tFKM=^YlPMbyV*J44Hw#ElPKm8&GGRtJc<TNYecEaVTlGE/VmRnEGKj+L9d5S
iGm/#b W6\I9S8p8BGyGE$1dpR1ByPK\h%V#N?IWw!tFKMy^YlKMbyT*JyYDKaXk&qceTNcMbyYnGaWw^uFcEb^
Pme&YE c$a^tFEMbkuFnST#llT#llT#llT#lmV9V4TRX\MXc*L?k8t^LMn%WG#lwKhXEGI^RBy#dC%FmAtINKdF
^L>=d% m^AnmDTt+beRp^ByMi:bFECc=mmMNA&SbuFca!DTDIPSbmHTNIGSqpCpTS^dIF#DjGKMIkkI%&kCM><E
iRQwF& lG5Wl>E=AiEc=1lkZl4CNawqMhIR48GPCmaICNewC5N#A5I%m5V\uIB\na<LGGpI%!k^V8eR4yGaW#wI
wGTPCI BPEc!YJ+nmBe\:W1E\nCNbLG<B^B8EdmjC1CeI%EtQqGEK:l6ykIBPEcp8CpIX^DPK?IIF^DJE+c\nWl
t?:%QN YiqStwS\Dap^ZCMlZCN\QCelZCN\QCelZCMa*LMlZCNwnF<nIX^nKJ\$A<whMFbCR4nG+CISCa1lHP:b
FXFR8e wBk1\V!dA5XRB8PSKRKWP&C<A\ZlG8/eLIImRdpDl1pWKF<nME!qRDGW\#$dFEMq8GiDammDi#awl6Ka
y%u4iq TES^wN\B\#Wc\nWKb&M$KF@D&SkNm1G+dI<G^XAJl8e$KIdmdI\G^XAcE+qwCNh\=/ISNA9KHVA?qbcA
Bue=?M wn>89pH=tlk#*\\wlpw\#&akZEM5b4+bCNeRlbMtRdpDlm$MlG8I\LCFkZAN&#FAME#9^EFSqMJlq@SK
w#Vtnl t88NNC98qVVSK&uWK?t@5$&/QMy\plNnRXkRayIXmumKW1T5YMn@!!5/IE4&A>iRmMY!TtTkWC<X!wR$
G/ubD5 :\AFk/R=?Te8dJa5Y!lh^9?uYQduH+?tRCpZJyC>>&%#PZBPBy^kYSaMZKn>$d!ZqAHuPRRBD5wX^Sm9
nQJZH? ?N/H$h@V8IRBA^iV59SG1ILTqBkEHJSw5lmZ?q:Hu^\+RjLIJYI^\+eyKHDi+\9AbS1HAbiIi\Q<9ZdB
T8V>bm 9\PZmDp\^@tWnPcuXRceV#Rk\GEyLmaWTQDGmYmGV$4AXGH+jJKXASe1YlDkwQ!a^GteX1J^qy>N5Mb=
%#=mP$ \K#e1\nFNAl\WDGW\HkXCj6^kM5$#teSM8A5CRIPMp:Mcc1ElFMKHG/ejGJBWZLnFE1IAPAeKK*uMFVl
VM1!Yb qBpu!<Gy\ph\m1Vq\Qp%EkR+1IcL1:y#yFK9R5M=LlH&yPVATRwEHFaA^wS<V1q^Ml@kDkul8ZLkmAAB
9hV6<A B/%<ejWCn9%I\QqqDeuJR#+qBwX<D4S5^lYZPE=b45JHEuC8\kejQphB@INICeR+EYk@D4h1StICC^^^
=M=tK! H=Jp<e69AdmkeTl\%C9k=EjTPPI>Cy@cCB9DJMPCkIPME=MhInH>pVVP8$AB8E#nRPBM4+D*cJ^mPZJ?
C^y#16 mRMQuSRyP#qFly#pRMlBlRcY\CDuqCQ@kDTL%#el#%bIBMqYEGkLp/S:#qaRRiCSE^RulmQu<!GlH$BA
te\/eb Lu#9EwIe>cI$lAn!a:GF#%iEQkkbekpNRp:%wm!FRN8umMQ>*p!9yJWFRIbE<ADIV*j*Ck!BXtAI6QiK
RkmI4b MC5\BNy:FhyyiyRG:d*mybWqtA\B4*D\Fm&5!ATqCVpWRGtknX8EKZknSCwFDp<\?VSi1FDJkE5RCDm5
E9l8dd mpllkC6LMIZ?G:DGCWPmP+aS5BkG&nItMGX?lQCqGcE*TRIF#6>j&FmV+cblCwiaF!HBKX^ybiaDEtPY
t%Q:p= NlR/Y&VAEYRykpB:%RSth\KSQhpt%b&tCc&KRPAp:@qyjkqM<udJmApReFDbFNQIkpmq65q#FR1e+&VA
n9!*RT lb%GKHC1X<CX&!a+:k1SuYayGZAcXJqB5C%&VGWGpc!!^Bm8eYGJVhN!nR9jiaaAB?$5mHEc=#+TeD:D
IPpC=m yutDwjkek1akJTWE&>^uMaGVW4L+I+VFQ^R+:<aF+DKNA+GnZkHHq$*=\A$9+9F#J*5uYRceAEX<YF5B
lMq\1t y4pPWe4*NGm+P&RN?jSjDq\MCpCkukRc=%WwyapyBjjnNGXI<d?uAF\wYEPAk<1tCJNSW$wnJ+J#uKiJ
m9lT#B WC/XAYhBGkh%R>A+4$I4#&4BIX>+>=!m8nXPk#RPc1YkeG5a8mjnyPZdZ^KPSZCN$<LLCZLkCFRtwGFq
4RXlHY W$!bkKcXAmjlZpW5uA\1B$/AImiwmWPw&9eMZKq^m8Elu?FV<i=elaLqK1APEA4#pVbEe$4>PQpl:yBp
G+$kQ/ =AGIBG*GIFD:CK:XGDE>GTe4y\yN$YDnyQmkR@KitbJXIWFqGRdY=+R^VwbWBy#>kCTLqRQu@$KBW:$C
8nqiZI *yN^T4w*%XpCDy#*1#LkQAGk\JqiAYiXAj<Ah<nI1TLnPBC+yFjA<edJY\?@MkAHIJ+mjNI9A$/CcqGk
FGLBpi dl8T\hTmYEKbH+j*Z%C!ylF==BT1lSDkIPPpMNWJFt?emPAa!ae5JBCH=MDFwFW?1FYH^HVDw^=dhh=%
VZnicq 9ND\AMSQujBmt\AeecAABG4XISEtALFK>#R+/kPYRJTl+PFp!FqR#Aj%/yCaq\BRn:$/yA!+tJB<RM#u
>y=qPC q*uC\q$GuAK=FRt5<^LnXmTk#p9MS^\R1N$GL/&$1EQC<\*i#wXiK$FyRueESGtkkm9t%WWp?ehJVh^:
B5N:%8 Z:MX*q\R1l$MS:+:1atn@@PpJ8cjJ#Yl9@jT>HVjh!hAhi@@?@#HwW@CjYtT:8t?dA>j!iX+m@/@Q9R?
^i5Z%J */LIVZNydFlMDy*#!R&%@hdiuwSB5mlkt%NY?:kStty1%b58iyJHjB<c>b8&w#*/cMy$>a&t18=T+an:
<M%kGq $p*>ECy*YBhIHQebQGY+Xu<X//aB^Zb:b/<VG^YEDX8wu%y9hH:HkMD%>VWDDll/^:Bi\^ecHwt5C:Bl
CnHtpD S1Rc&\dZ9Rpqln9j#m&=&BBp**^@4K*FMK?TWXuu:Y5>ek<HwjTL+&@q*Jq!c98Gqe@cDH+?PcWkZtPk
#CE^XH /c*Q5y/MG&?\e+lV=>9m6&dFXh:c/1iZ^a#a6YSwcH8^+@Pw4l>LY\#Gt%8=8^8iGH^PN>6eqGt?wcy$
L^Q*j1 /Ne*4B#QYSppD4\i>1SWuF!<&>w@:9^A?<@m\nZM@c%1cubb&&4wJYwcNI>IWFuYQEJNbjIdZXWXni5n
@6!5mF V/%h+#qTVeW8VXj4X6=%A=i?jVIQqN8MYhDR%<ubYn%?KLLSL>q#&qb*?k^n*>!j6FMmB/q1N%w&Nipa
%Vlay# 1I>Th#&VIPGIRIQeR/HHFlbXX665tDd>6K/@IYtlE1>*yG?bnt1q%6Vw$a+bj>44Vu#wI8L&lHtj5q1*
<h4KDG 5$LNhW1Vm=Qd:84+wSyqGd<tjpyH/:ia@FLhtKq:81>1=Rm^:c4bSnM6<1MZuNyReZd<:B9J#!d::6/$
61WJh< $&VP49qJ6Z69YD$uhk:%Q4>e*ZyL/I=h@5YlKX=PhZeN*NLL6n4PQJ*@X%VBb>?qjqYh:9ZjA!n9\J9y
luBbIh uly=c=*YYV^<<<Nq$iTPHK?DVYuXw4WDGk/e%u8Si+liy8ZbGn6L/1j6w^Y<bP:=PiH*!6SF8w<1uF%t
i1ZWjd 8Qm:tN8$yB/96n9w/nn:^ZjmPX@1dnPb+:qWGn1:\m:Xa$?M/5Fbj5Y9dW4un$nid*%\4<69K=5Q:d+%
#:eb\6 >RV=1$*8d>EH%aa?KJq&&:d\/dyBBty>e^e:?4W%qGuQ:X6=>WhPbQ1d++&\11Nd$IFmh:&\>E9Qhi^G
Nwh*F# *4#%T+8d@hXaM&@Z\G@6W/%CJmbw?bVW&PnY1/nPj#YhuHF#c%lET<Cb?I!W8=qc^#Q<6y4N>:u$!H:Y
uik8MQ =4=?pkZ/phQY8BN:dkSL#j!?EZ8M<^yT8L41yE9R855VWVVl4=W/Q?HPQh961!<:dl%%/qn^dKw%5///
4^du%l LK!>&Z*:!IdPq5hntQuSaVN@4@>/6H4?9:Kn/V/6q<48Y6=4>Tyae5b\%Gb%#:L6wjTK+uct<p4yIBjH
ST!lee CLZT6=y^YaeHiX/a=u#Y4Fw@MW8nd>m\aQjI#/eNY=H??j*\4!dq=l:M>I\d1QMJb^LdKCt/%!>uXjC!
%^C@P6 CaadXD^ZL^4\%Pudbtue/M8cCZup\Bpc4qq49%4S5it:CZGt!cMNF5XZDNLk6B=PM?:Z=<+u6S1i#t9Y
l:mme9 pBP:TnNG*#j&G?n^uQb894b^eym:+dpdKqaS!hq@Q4Nb*Qby*SDJZ+%6tl91uy:bS?5M>b+ZNed?iEZX
ty/R/# hNQj6u\>S&LYiLcmyZb+<6M4RTH?Sh?Zh^:$*Lqp99t4yX9W:Dht=pit?qjYtS8&nd#6cieZpYbk89tq
MG!#iR u>QNSiy4Yl@6tBMV5t*Imm>E$:?^w<58N+?+?1%dkMMl5=!:%6aGWiw@1W=u6ab>@lpV?#VWdhhe!%W/
uM$=?Z G>H5\hMt/KW@8?kbh<I=Jh^X*#VLd$jHFphm!/Z>ZVFQL@&/%#9hh/X#9i6#H^6ZVihNS8w?%D:ZIV:j
WLQVI& y#/cPtValbkA:8SZ\XjLZbN1WZ:b8m?CZM8G/HXiD@C:lJ/w&YjpTuW#X1&n\5QJbudNp+#KXw%a9Z+F
A9?$/c X6t@YF8=4@w=d<jW@GLhT@hDNNKdp!$*9:SQ6uNRZ=l9eDl:e85h*/?*qn!h!=cHiDi:wI!tlp%NK>Ta
iTJ#*I BWdNBe?@*LKy6myZ\!<:d8mtG%^Dna@P5Re^Ihd6Bj$4D?^cjN4CS@X\9wu+?:F=>b4n>QZY&4V4L&4!
lH<8+G <uQ8M1N%p@=wDRp6!dlY=JBy6hNJJ*&%#5V!<%&QHaMC$*i9cY>Z$bkS@EQu^dKNiWiulqR?!&#99#Dh
K@/+SP %CW#aJ9K>1:qQwpH6#4*K@h/$MK/>C$?dD^Td=@uhWQu$/qTcqDYSj<Jq>NKNljY?8+Rmc!9GIi1Qt^#
h=C%j1 u44>+bT$k+VGZyW+q$>uQ#Wh%=Zc=Fq:$#+&Ri#yyy@cEn#G#cmD!*ykZ6%@VJ@u&cpJ<biDHy/=euH*
WYSI+I 9FePa$Rckbi?<@Db+%E#WdZR5y?t5XQ/nBibiyhGNSX5Z:%a?8iE%D?K@C<dQSk:aZ@=@^B*=ZE%buE@
-A#l*E 00099e9cffd00110333 Page 437 of binaries1.zip
@9G9Hn yT9e4yyI!yJ8&8uib:9*1lqyWh*R9yiJCpZhF1*V$Gm=Vhwtbaw!cX@EJaXMJm&KcFZIMpWySEy&\/9$
I*Aq?+ iGh^9Mia#?j>:>Vuh=::i<:9i<:=Q8ie*@eecLM+Xl<yp/Y/p%a!@!VF5iJe=yB><I#LRme4S^Q5i@$m
u#PWkm @WwjLJpcq!#C>lA@p!E^dX>^?R</AXb=nSIW\jtFjnimD*C?X4!^5<>=b4qW&e<l/KGj%///pQQDh6Z8
4MDbZQ ^+*ew%j:qwe=K\ee*!T*et6Gb<CQQRh$YL6Pcbb6DX8b@tL*NiYb!?j6$1\@FubW\?Ztj8eFCnEBN5t>
LC9Mad h&^@Gbp6hQA<Nq@HYJ&utny5wBn>h1%VVL^/WY:t?m8#D!w*/P1yBBtHeIX#X^iqy6:hEdLpkJL:$BtL
Ip9A=X %R56L>Sj1P!1MI:Ii>WWFHJt66/ym@KQ!8@X#lZ$#uZI+Xee=LdKJK+e6Fe@luwa$q?Fy>^$uu@Z84T?
kk?4cR jh+CW\@Q$K1^m@hd6ALyc$R:=@D&?b!8nI?+=+aZ#?nhuPQT@cd!>D#y1=ED\W1^AjRWS11K%A48ZP5N
R\HaE: jMh=/>hd/N>Ph/hL:<hTAtYN1AjTp\#qt<=6u94Embawd/6/#1e6iZw/6ccQuqR4b#GnIhy/bGNi:VBq
XTPwP! dtY#iIu%Mt\5^pXcal6V&84EZMH9et6j44+dV?Pa9j!1a8b!y?4AVRj56T>%Dn&RVk9Y@%Y45qS?h$Xk
<j#+db #a9i:>Q#8>\8qt@weW\&%6n%JPit?IlP%wCN$$L9:NJA\c&>=l1tZhH4B9I8nX!QGtl=HZV:yPiF<CK@
*^*6cJ aGF?bc1Imn9ZPhP@/ipq$/9YPVXXDX6@e#l?*M9*bnPq\C#wbKtmp<Yd=I!FQJ>>DnVHRM*iJ&$P?=@F
Rn8Q\5 j#9TZlX1c=8u+=mbaQ<pndGc6>hLi?j\<=*ILjMh5WX*9ZiQu1<!T6=nw*&Kt4SDkb8kE%GTK>BbEBF&
EAYK?y >LXck5MYS@!8Tpua%=%Sy?Y/mi=l8%#^a\>nwyeXbYqVqjLWN>:!F4P5j@*a^i^1ZYQ96J%$+dAhyR+D
wI^W+F Rm/NPjw*h#didqRVDM6cC4<SQ:8>TZV://&F>mcIaEqcX:VQFW%6tpC*VGZ%+%*EA?1X:LPXchHQFS@i
GRR@w! EJ1iZKZyXK9$QDh&1blE&HYih%&p^nMDicYIdGZldVwm4@$X8DwKDQ*cRq:nt#1FR<V6?T99>HtHS<&R
Ac4+*# n>MVFItXu1AuXhDh&@%c1=QQu\@&X5SMbcmtK/c/bY&KnBF*YVt4md4t^!8lLemdB@6dl^d?6HMHVcqK
T\5n6= #GS%W8tacW$41#YEbnc:l?iVq@>AZCJjtj=5J8PR8cTBiB%qGV&JJdlD%Mt!/Ap8$aNmQt*m=nw^ppy?
y^#bD$ mq!/&^Xi/=/DQKEC5j$c+hF/$%L58D>N=i==T&8Z*/K9%jiGh:=ETPJH/a5X9@8tT@/$@&%Ttp@Vk!pN
JQVF:# *^\ZuS@EWQG=T=!kS4=c54YhP=VyFjhLjI^6*+qbinbnEu=nlcM8EtG+A4i6?LARM:?Di+JTL>#PHH8c
q4wwky y>DK4QS9qcj+%n$4&Mt4TXDZnLTMZ!\nd!dt$^!m&!F6uny6A?Z6y4FcX!SJa@DJpTKl&BQ&M@9p9a4*
L%pX:% i8uSBJtLDVIZ^%uP:Sit/Ial?R1:q#y6uBW*IuI#$>jN!qXm&bywX?FtI*WGX/\dpb\&/%CNwbG8pZ#V
*I9Y&n k9bCWTR8Y<m5K<FbyehM6Kbb$#MyNFG*/iDy\SJM>Mlh>YZ8/4G!T??iW8Ah>iDNQp\L6Y^#$^c6611=
Q#\niu Gc4:eKq<i*#YbtPlhqhZl>BD=#S9W?\NLlqq/imJb1R&b&?PQJn1a%ihR^XZLGeYBdwqdBHSqMD+eh<W
TC@^HC l=?cKeH%yH#uT^uNDW>N$ljZPHV*!L&*hA86uDQ$khGelF+^*!Y!S%VF1M5^><6#N1hQL/Y5#@Ib:yNj
PpqTpZ EaZ%*tdV:&#+8u>=>ZRBhc8$CZ?*c6$^E*/DctLhWS<nRRj6TPSPa>Qm&Me/1\:GhtuK$IV8#:KeWTpi
pq!Wdu &#RpJ:u1cdF:%@L?t:@GlC\1C&+iGDKN#Ve\wCm*&<y6hGn%ju*><hD1Y\uKEbn?GQXGY>nNcSLi@Hp/
anpbw+ 5>ay/qQd$Ye/w>?8XBY5L%nJRV!*bVMXqPS:&%Yu<QpK%hFmLR8ww<9dlHY%B4&hC>?<HdbhNMLVYh96
q5hV#> hd:a\B\bV9R4ib^m+T/<Qmh<F$XS>SG8QPc$P#pKmR4%WPlltMl5!tyS!?1lKtWuJP?YKLP!!n*^uYHV
/BIHYB R9e#1uYQ=\9%4t=h^R*9ecP=1*qjqNT+9Kwtnqj**L45^Xe#&%lH#SJLP%hamP4Q<yJLpt%NwHyLdq<S
<<:/IA aSGepuFYK4@#ZnN%<!ypW@G=?n&ZY>&%Ck=4F@mn\>SGd@wCW=p4Rk=e/nFdq=Wt6:15YydVyq@DqTL*
4u<EIP n:d@e5uV1Yt?Mu@M$nn*\cnJwp=SHbYZFApN==\IPT6hj/<t<=KVyun\Y:jj:Z&#d##RD>/5yH5JiSkR
A?yRBI h+^i!b@#k*&1qL:ldP&W=H^DaRQJm<d**%w$^F9P$hLpFRmLXtunK:Yn?Ny*%4w44PKu1q9hG#aaqnq<
$5dX%$ /<%Xwd8Y#EHLPb!%Ja^q^wP98^dl=&#CSNNiSMaIFEPNC&e$yV=Ew5/5V*paNmbd*6<%wu!hh!=?SS6h
DqeMZ6 #!!i5TFp^c4PJb%N>teHa=icL1=&NFDRM9B6WT:ke*Wd1jW:LCMLnjXQ4w$!ZDPc5#tj4>uiKTq6:GD=
EDVW<1 $ICP<BY+/:D9:I+S^i+>hFjPwt&:&GeHYiZ6/qE9N@kFd8DFdKVGc1V&lcWP*qtT8Y=IeIcklVT1&@w@
6&eju& 6F#VqZn^&wyD9aahaZ=LLnt:?G<X<8/SdqCTTpkLdA:YiJ/BK#*jq6%8uVRTHcIX>b6N!mHGYM>WmVHH
8G1Y5$ S*bGtk4L#IY&#X*LLVPnElqGb>QZH#6J?P+=Wq8=w+m@BR&\<*@4iIp+e8q=ap/+C:=Q41nMYN19XKBG
Rk:MJ# j!dhmN@aQBh%Ce4PDCKM>A@+h%n%q?TwbuhV<@SN\85P*Eee8%/54Qct#%bI@FuEnNa9FHC/&Nem6*uw
ywicYF 89ZiXm6D8hFNm+?uY46Yjj6M*TB*MLk/Yn!i6=ad*TDqaG<qCPp+8p^9=4iJl$/aTk^aZ<l$8ii=hP6=
y4/WWT F=$b\m<V8FH#9&1q%uQ6%jm<dTQV4McPhERuFmk:QLW*I=#F!:@nDTnQ4hkTZN@l^*18/BF>y*Q%AHJQ
eFtAlk 6Z%abQmBnXIEahV*l=:wt4!M\6WC#TLdmQ6IjLmFpc1X9Z!*ZXQ?kiMi>A+Kb//WZ8V6:=QZ!M9aP^HX
#e85k\ \euWHe@ti/j=l&laQeK:y5&=byH<R\^YcIlEM\\4>/84lI\NdGQbeC>9GD*i6Py&SWh&R1KjejnTI$Jt
S?+MD8 X&Z4JDjTw*:!K9A69%DS<E&y:bMEFRc>H%e&RJZ*CAeH*k\iVq6tyt9jpFYtZK/bLBB$!XubLic*6Y*Y
hcu^lA Mh<e>X8kKN<D1jLalRa<N65$Xy<$>LZuXdY$?NI6\c:Jy1>*/E8$JInIn<Yb=?F<t+=NHj9CSc:6VHH&
jXZ%A? ?4uISFQP^CC\c=i5$^^&\6415mYy1ye1nCpy$SJ8W&u=>!NnR8dXPRZ8eZ#SbSLV5P8E^hN$he:V<1lu
\M&En& %=IXZ!8/l6X&@MKP6h=N9&WkL8:=a=V!4Pj5Jd%BQmwycJh/Y$cK%=Ct?CP*6A8KqlVt!*qVMMtNDdPh
Eaem@! Z!yH#RuP5c9NtS&mY%=taVnH<jmNwCH=tG:L+DTi8b66*5lRd4NMY?n$HI9=KSl#!==%qH9MkyeLykVF
d/KjX^ F<65w?6XdV1YtSK@&DG\X$9%hhVXhjiW#>ybXT!#9Im&qP/=jCAuy:6L**>B\RFN@R!4/9a4G#1?1XSh
K*qi:c NXn1ij8$D$h&*S:HwNa+JDY5?T84u!wnyF^9cV$QeGL><i$=n6?#QBXF@:T=dP/<C/qnD>SK>uMnk=6&
5Que/K *>kY@IicXP%T&V+QQXFXV<1b9XQ!GVh4Y%#h@aMEwWH8@W=cLYbQCa?>i^y>>a1K?$WTIqSLp:BZQPpW
wE8bVE #*q8?L$:*Bt$GVQ/B\:&>ilRH%ytBNlhL9nq5INL!bZPii&?LQc==K>MHi@Q9@c16qD8i*NHGh%/b:/?
q=M>TS 6j&5tb6itIR1^>G&$w=Wt@<k85c:K>p&h&ialG>c4R4>\ymbSEV/98umPTyK6hY@Jn!yCyZZ4VHp&%my
^6::b+ 9D#8qaTZ%4pjE6W?l&>hiuB9%tYP1NummA$9R/1#4C^TdSSQBnDQWCSYNRqhyi#8y##NVdl&Kq6RSSQc
M*D?!Z tmVZ+JNKPWa9p@^%i>$<bq/5+=Vu9ibnQ*6b&d&m*+ml!+<pn:=R41Gqh^6y*t5T/y51FG*eRX8Tcqn1
RpEHNR *&=V5P/eVMubnbqVZ@RWdmRG%eR$?ucXEkWN&:#ZFL^$%qB1Dqqkq::Z>H!?+tGyq4VL:FNZ&6Ycb$$:
F>H\Xa /<E*uKHLp^aeZLNATbP1>FRpVQ@5%JWS96SaG?@I88SeV46CRG/X^68I/*5h<l?JGP!4*^LnHt^Xq&ET
V\=>F& nb#MVZQ%qBINN^QQ#V&eZ4<@#?^?THjE!T%jw+WHi@yVNY6CG9KZYa<YTl%8\HNc^LYDc4c9+h5&L5<<
Sme5^w E?:h1j<tV>a&?K!5>%$%akQkek*p4$q4@%w?<X>1JmJ@#Z4:Z<%E@*h@tZm+?j>=HSXDPP<qGnEeuj\Q
GZPwnY m>V6+$#1=8H9M:ujFVBp5pBM!k/K+?^JL*A&#9mk1cjHC*n*clQu%ThXGlEPm@&SNe?@b5uB!#9m/D<9
?pth?D @<BS+4QpHXFTKBChXPjH$MpL8#F$$qpMbVQIApIYTGN!ejlhmdRt&^LqpNae$yyDQyy5iI#BIA9I=IM\
<L1c<1 Bpd?m!ALyDYV6GambIE$byLGVDd=IIT$Spl4lLSGTG8EjDSKG1PpMa1SD!JBkYGpEWacaiRVMjKJGGtM
KF5w*+ p<d+l%jDTY8e6MbJc+K$J5lHE/R^RSwVH%/NSX1#TG5!jBkbQw\MH$cGD!QDl:E@9B1d6CdDl=Hl\<n\
6D:KN9 aYV+MDJ<GBp?jDJ<+lk?GV<MJ<PHp?HD!jDlbQl\Mu\+GV/eTiIIb=LYbQl\Mu\+GV/eDB>Plk>HQ*Vk
8CPKt8 !ed?wGyJ:nQ<jYjpI:h*pMQA@*$HQQKSBNF@%kbJaTIj8d*nu:WJkCRp<yEe#+@WBwmjIS\eynaB<y!A
C9a#I^ 1R$RCWI+LJncGKnN&VC%AjIu!EjET#>TG!B@ku+pYjIn6SqMRG$a4PF5N1A&DNb\kCRp!wDBGk/RlERb
JytZpj MFkDuXyFGVBaA^$hSSp\YMMSWJ9DaA%ukNweBt5aB\jWl5EcBlBiR=p\YMMAwqAwE\b4wES1qAtD6Zj#
pn=BI& N/A&DNdGJ>?Q%+dBGkaRZpPbMFlDAeJ4KBMGc!kd>N5\YEMJ$G@DaA$FnKpwE\b4KCD@HEXk5IaC<6BR
KXMI\c BAb4KCAbDEXk5IcC^qREBt5IcE^FaLCGkMbWBAb4CGlMSYC\lwDGXARGc\lwVEXk5IaAbHbSBAb4CPD5
<YYW+W K+4CaI$JaD$w!wVmVAC$wDBaI%kk#/H+GpC<FEYl?ByA9BSFwjkcRKRZScH+GkJ1e!m?^kT%PR#YeNCI
tIi/nN nHKkPBMkalkDmnMB*l8D+t8AhAAWk?J4kDQ=KAdF%%DAdIBB<VZAX\&KRjE%JkCyGAHFtRBI^XlRuApW
8:!qHT MjcZeCaMm1<BWqXSHI19AeS1Wb#=Jb\Jl?J4wB/Kw%@CtZAMmnPBQIjmc/AbGIjmc/AbGIjmc\DbABTH
tiS>SQ +t5AAVRWl?J4AI$JqIDmc+DWMJTA\SwC$PNCCRTKeRHcuIDmc\Vw9cH+GwknE%B<DTB%m^JRjA$F>DGC
-At@jm 0007295fa9f00110333 Page 438 of binaries1.zip
WL+ZSy >TYMm+Dmc<B+\&CNCdl!BYXB<VWRb&LBaA$p?I/!aLAG%I6FYj>9=:ZS9!XE@Ft+AGE\QpNW=N*ERGDn
dC##8Q t!LMmRW%tJ?GwwwAbYQ$d\pSj$+maZJ\:DNESjAJ^<hZutAhb*&S+&^\wlSB\I5$nY8*E?M/c8PPa\mW
cKjY4% +%CLmmCc?dh<mH?h<D18W$W\Yi<hl$y+ShqRZ%Mkl98*bIy@*?Ie#wR/\wVnWAt9KB91W\^E46uaJ^\j
$/lRD8 9<pIY8CR<?:LlVu=AmmW+*DjeaAbnE%<IlpRke?yG^eGG*h<w5WlHYh>piQk#5qA&AkBD=X^XSH&lPM+
beNbXy *EnMl81ewG<lDkPw8ICN#!H\!nuni/@9S^YekByXwLctRDiGwS#pW%ISdDd<1QI?kYjCeTn%WbRD6>eA
GL8!tZ aA!eV*XP#tjMuPPmBSQ1w?nE>kCM+%Aj9wD5MJSDjEweCwWZYZ4ZA6mE?mk/5VMB+#nWLkhw>bjD@t?k
l\dMVG Mu:#CMb?Q?XnWAJwKNS&HA=aiMaanE<q9MLQuPQC5Sn4jijEwAVRMLm>QMCcN<bA@l8wnE9Ana6!VDlP
KhKGVq eKAel?1ekPX&nIH>S%B=N*KPu=1aeB\uwB#HwXcG&ADHmj>tXBtZMeZR>#MuB1XXlEF6RYIA4TKM\j/p
Syq%bp nk9:e:V!^w@HVDmP5KEel%wQA/!8aE\GPQ?jMW/5Q/N#@k>4X?IP=j4*ySqb^lI1ww+m?#LQQM<#T/kb
+eCeuY bM<!1S!qbB%Cwtl@pcX5!hbK5wWpIlFbm\^b&%TmVmiKuBTu>b##<\#9>d:Z:@$>4664@wCb/@Qe%@i?
X&jR^X :?@!8V<jLH@kATiDZQpI&QAVy#YDRBS?^jnW4WqDieBlIK$mBG^!m6MqRCBpqqBBGiCqG\QqNe%+\IG$
6PiVj9 mlCk5T8C$/BAIP15K+:P=XVB?uW<+CnamkQ%APq+K#:d=1TS\c$/WD19&eeDDqT/IYADZ=#TDcGRb!pp
pqyYW/ !HM=D1qKGC8SB^^I<keBt^dnTQ+kFAy85W^B1PBYHbnRLmc$kAHH^5Mk\IHc=DlCakkF+e?K</S=1hNJ
c:Mqt1 FmceARIe1MiPa%!MWQl&e$JKqJpKmAJWATFkR&/eCkml$GeS9/dVaGk8Sn1WtSKIAqRCIYAney\TCIHJ
CS$iMY ?K1uW%W9Aq=$WuqhIS=\wBIIAb19+\qpIDBqNpG88h#=DCXwykTmAJXACNB\uwJVAmE\ky?5<Gkme#Ab
=dn:#= khBy+BAXDDnRXIKMB^^pKpHD@VX6Z4?t<<hlC^8KWmuVRppalRFp$aCcPnmDZkRl#^ctNHD>V+VKM&*q
X/A&1G ARiTR$cAPAXWuBp#kqD+yQA$XZ1lnBqXaRnwaEDAP1++B\QCy*EI%44F&B=an\pF<mFAELCPK$/MI*\c
@A/X9A l&BNFk\+V/RZEDl6Z5Dy?Ey>CI$P4l5HMZnAiXK^kMAb<\GP<1ty\+6^&w\+L=D^A\JE\1DmDPWSqDLd
ZC:^\F 4R&le+y^4Q#Cal!5@AJmePAJWCMwkl@nW*uTHLVKcV#k$<4baMDSiRHH*=\\GbQ8BXbjw@GaYD#kRJ=t
P:i+bB CBB*BMZlWCAw@8ce!8%l?y^PqSu%NSSIjR%B\Rl%PJ8VP89Nme=BG*EKPGXte<JAt=MK^5dD&b^W!1\^
5nE\W@ Dm:PT&d\1G<<+BTkGAim9PB=wCNWlF@AES:4dq4!G/nFAMTZ\dNjS/lWQl&HtG<jbl!LCXEDGeemRGRd
binR=j QPh*lE4u$*FIl*uAiZLIkMAb<\FPI@Q9XMGiFE/L4APq6VT\eRlPYp9Dd?4AKG$Pm16anM>aN!BA%k$I
DG99ah DY\ekyQY<w9qk:F8iFLIYIaIJM/LALF<<EVYES4j$qw!D#nYtAeFVy5ZeL/q6SRi<Gqbi#DknQpAy?N9
TF8K!J Vlmmpih\HGJ#uPqeBRGTR$cAYD+Inl\!R1jMbp<C4qZP<=!aMe6AkM\!ECCYD+L#SAclI@!bKtAeSt\A
c%lj*A NT%4D:dm/H\GWHT?*b#R>B\H?\C\jB!I=aM:^/H#/?cp#R!ky6aSFDlnQ5Ab5>!eDDJnD8$J^nV\1S5W
E6R#dE EDkR!\ejPIXj^!GbB*#cAREMPD\9+An@Tnh+yuTD\Ww*B6kVWb#N?S>bQ9<ji^JwKqVkGZX+ID61BInq
hMdZ@n A?QaWTMM96YeW=8TM1MPD#aNaaDNK9>#hwmT<Tq+FC1XAh:$lGm<ahG$4D%IQw/T\YcXhB#kqNuMM1nk
uCHKc% dicyFeC<cdDcE=5bkRAHtwa\<IAn5:y<$Phm:IWB=+uDA\JH=\YeP88K#<G6mc1Eia^liR4&ATDAkYcX
5?X<&M hL\au!Y6ShG=HIhpHuDimkMCb<\HPEVtp/<KF8MRdV4GkSkRKBDLl+LDkEAlCy><XTCEB=!*+wDA+ZpB
IP\kCu u+%IRKPR=^VnQI<5qQeBIMDBHqA^eIDQSq/jA/<K8@IyM:+1wMBy<\JPu#ZG=*B#ap<Fy4&^5A<AAR/$
:*FDwC PZGijcP#5u^w+M<FMP+qBy!*+tDAkXk??MBu*b#k=uWI#>Ea+n%>lSk\EHCk#WqBeaDQ8nuu$Mtc&twa
H^WB!R <PpZb&DA$ZpBy<:GbIPBkYQ$P+k/*XjBu5!BAAh:GpuGAW:uW?tGQdJDb%ceC4dmRP<1ehTBWJlQNTe9
RC4i!8 68Gb^+pwTAYEAyF<IB^lIlVtX<$=Fa9RDP$DA1J>wEApH\mH>wECKZBAPM^DFQ=*D=*@@8&M%\*$Q%+*
u/5NtL M:T<Lj@LNkj#81HN!AV?&@>T@/@ZDbW/qd9N$?8t=EYA41IEaTH4SQ6&Yu^#l/pn/:#W*klt@G4leqhW
<W/yYJ WXFeSXyD=d!h$qJ8dtlYbYm@5J^a665Cwww:G6:RaB!#d>BNLV:iNIX4*4NBK/%SqB!?tC&qy!#l+m1a
GG:a@a W!qLY!bl/9A<6@GNWt!#l*J5cFekW1HkLZ5%h&&t$uEna9uy$Q4h9qCntG8+STXdS#/PKGT5u8P4dmB1
puLQau qY9pwBV4TYVyHEne@NcjpZQjQhCyQu\>4WV\&8N6DDt9*SYN8p@YDl/QQuDB6IZmp>6iEE:e1w^<=%S/
6>qeBP \k19NS%LA?4hBDZhYd>CJ\b$adpaITihNeym#!I5ww=Wd!dut#VEMX:1Dw&5%JRaVdSVJ/=KSyRnX<Ym
Zu%8%9 k5\GJlMYj&ZXJT6ly+XIGa^&ZSiM85#5FaGNA%yFDJWQ@EFw!p<Mpma8!Ge@ICc?WXTMZl^#cSFJ8%!X
*yJ^pl RlDeb!e4i54Np1lDPq^@T%tpdWCqSI1hJFi<1<RuV1lXJ8Nu%MajVR9kSHPPLCqAjc?wEa9=thD8FqEn
WR/C5$ K=Ga/CFy<MyaS!n8p:TWQLEl*#iMYFnhyXAn&bR%Xn$cRcDEF>W$p=6i*din&uDQB*@J@yDwYti4ae=S
b9=F1A $LD>pjuD\LbepMl1MM>HX:e8FHnhitJ=btY9\/D@$KcS4K^:WFKpPF9I%6ptkq$kE?8TGjTMtdBy*+nk
$k6=yD F@w%N:t@Lm>k@p4c?5F9<=yu\+@w<w<%DL$>Wb@WII=DYIuZy5$T5T<jE\6/8ZL/<ElS$9wJGdt@691i
Y4edGb dY<4?<*<cWjp=Ww:Sk>%VdSF#^<yYTPSDdpGZ/#&4!ua>?mtS%u$6969=ba@@<I?6/*Lj@K?4N&!DjX=
M4ewQX #5u*B8YLR%L?aV/SGHc=/Ww>ZCdA*Q4mS=nSba/HtjmE#XEwatFtX^6*kctA*HC+kq+aY&cpX:JMc9VS
aAT/W> 8uc*ycjDnLT:G68mdG$PZ!w:wKN&9GKdcHKCemJX+j!Y15I??+eX^b1*N%iVQqbHQh<*/jHdE:HQ#1=/
YyjPwW t#6>K18MK$=XLElieMckK51wbi8iD&IZDZa^S<J6m:y/cDbXE:XTwqItQ&k^Wm$t59dpLTq6dcMXS?R@
k4=?TL d+M>!qXaMb<We&pSu*Z<Wapl#89>%1t^FudI8LNR@!ic%peG5eZ=VXnC^9y^c@bkwS/Z<Nj>c&e1*Q?y
\m!njd T&%45L>^=PZy#u$Km<^/*1$\ih:Sul=eF>4ij#Qm68N=>*\Z/ZN4la4/B$8Fl5i*qLZ5EZP9Y9FWaCjZ
jX+Byy Q9VRwmYJDE>V<hNPn%\/^!$!Za6>M$WQl5bh@C1R@b&pqHSb9=n^1mw6S1G4Ih9e:$WiLXX*j$!:qFCZ
mMdN&n lXQyX!6mSmbNTNL=d6MuTFR<PhFPM4KlLKSN6Kh*tLmkZ@K+:N48bEeqCi<C1EC+/PL1:*+dB$QS8tW:
JiHQ1u >k?$ZZHb<</THB1RbCGFLmI/G%aTYR5!qJ>ESd+YWk9%WHR:b&ubNhqk=JZ*mqWh:R\6CX+eYbu!<uPh
AJA<9% WKjl?C<==Rjm#n8#B!<j9jhuLcq4iL?>ycFkS51#N8Z6FJ9*H85M9/ah:Y!Dh$JFtiGlk@KdTBh<w6N5
SDK/Ij qFW/Pm>?%HA^hi!<<16DVu1NI46dqCWw+CN8kZRqhLIJbnihDq1R!Rp\5=GF?pt?ad\tEn?6%m&4&PqR
!I#+hJ ydBnA&9H*YcnNI?L=/*i5$y8j/Ny>B=&CD:b@5Dc:bqke8Pl%K5hYnc@B+u?G9M%TN1>LZ?+<EL9NRtY
9D9=dR S5%cIdp:ep*yppVbDR!q=B+=+=\54^N4#PRjdqJaWc>$$M#GT@dQ=W%QNkWGmV?K$RqJhJGC%y/cKF>?
5L6+!H JW&j8E4:qbPcdtDSp&YmDhtuWn55Dlh9tKmV?9TQ>/i<@&1+ejajX4dw8XdY4Re$MhT:ZM#CepjG%dY*
YNkT%j tD8PSB!!ZH#/iFD:c#Ww^wP>J8*ldZHS9l^dIiu\yijIn:$eA#%bu%IyC=HcCQju%+^GyViii:k<$yi5
RmmF\V LqGjq*Vb9SX/Z%1^T+ybjia%lPSNWpLH*=e$Pey6q>?q4IjtB4CeIkyEJ#jw^6=+8E++hbQY*dL4k*u%
aFiNMQ $YpmukwG*BB6%/XLjteI9J>+ZTTq&d8F#Nt?1p>=pYnk<IQlI>W/B>V#W^8#6!y6J!WX%FXM9tnP=VmE
LNDp*Z ZH*9H4>Sl/^$llQh@nZknHhCm@:Ti5>p*^4CkuVSJD8:mJ%*5\^ZNR+<&ub<<?n#=!1BK4p4leY5@STC
ilS\iW !$5@qXdjwAY%WncjD*Hi8/Wqj<A98T@mZmNnTeH16n>Y@d=%h@@uVE*K1h/4F5FtS&VSQ%9q$1<YG^XP
LMnQcq Q5tnm5k>ieH^K8:P#HRml%q@T:ji^Y*6*J:1<SFydSDQdXpt@VcQc<t8kq/hhLI/F/qSV>GX+b!8iR#9
JGb9C+ #>Hy1/AF>1YZL&GSD898PHQ/AGN#pK!h#H9m4i/MkWGt6JE1$V#a+?>dV^ZN^+:16S$\MumqZai?/l@w
9!ZASk qp8/>GA!Qj1m#9QV?=6qyF&C>CH>\VRJG#Y:JK6DRV%8RYQSK\WF48m1Z:kJ@#4=nC#eHNZ*LMCuPZnR
uZ!!^X R\6=6tN9/FYXh&QQqpXcn#qhLZL+nhaad4a4yWQl\X4Z9X6GnTW:95tj5Ly:6cMyja&6Tbq\&BKcaPkX
KGqndd T>*FC$QM>tZ+X+/Wq98l*TMiJj%@SXdu4LmY4&@QKWp9=yy#L>S5&?>9addITAZS81Mi6:SdNhqM@hGT
pLHFRX 4GH>bS>@cJn6#XZK5Z*M:Vq+!pq>yj4D+D66c#k=CRj1TM&lwiSw^%IL/^5JE1ehHqmqEZX:j4wccq#c
>$*DKw WXiVN<d1WFH&/k#u*N^R5+QK4T1kmRqKuKV6hlkemEum:QuYpeF1X1$=p1B8K/P9PuV=*enQweDP\4Zy
VCbPaE NLQ%nkXj1>LD%\jTwy!:?:ZI&t#44dj*4k#Z6:^=R/$k:@L1$W&y:nh6c5WP\p8D>c@5tIk\YSjjY&\\
MJXNh/ Q4:V5ZXTWWHMXTtnP:li*?Sl:\JnM>6dj+uI@@V<i@>8y^CLBwYwi/5/*Z#TRtKh@WMP:Xw^+SZ+$4qu
eyBQ@R >?qnF/5K9l\bPQ165TDp&kXIJn&5Y<$@X:^Pi/h1*4%m4%TjHP:RL#hEZFku<#8h6<4@EuVh8iACT=5p
-ADwkA 0004ecfc8cd00110333 Page 439 of binaries1.zip
TVJiX= id&@5::w5eK6^4X8yS>QXY>dE1?l5d:9=Yi#w\HJ5jYGJ+:hDk*\i4j/9In1Qd&5:!hNa/=\JN\dYjp%
wu\C$W >$Qjyqmu*Zl\+NIa</HGn1RCh%e%:jZDPSKp:!cFtZXc\>b1:\kSk&e>E?*996<Z\QRY!n64yZKu*iia
^D$k*j d%JeKQeYN@Q*$A::SQi#J#u\t&h@m4J4lIjJRw=ciaP8pwQ9lKY@SBdZLD#:49uu#im54*9?HMmn9&?T
+NTjeF XVbKKiEKQi?WTuyVPj=dn$6Ee>^%=5>CkhSE<1&F!/@4dF^+6>KdWA6uI&\lwmVl/WdC+BN!GDFHphSq
?jeNBR =M*p^qytdnT6KWt$*6?q&dYu\#GChF5$IK!wjE\*+a6N$6<?Ab+iCX=9Qlb%jlaVjdbI1nKm+?YIbpwH
=u:%ht /b&Etc4umb!k+?85*>R66j5?RbR//1=aX#K&ahBPRwq6:Y%!mi\lXSy+LLSNYMyiQF:+iDb*X=bJ8^F=
beFMWD X$hebKG*nI>@:5dHjp4?bS<$t/KF*N*LbMiYc=l/16lWJBXinPEWd6R$mCM$B=5$Z?yYi6L!*hday$b!
M\1h!# pemiAbHYwt*1d:lel!T@dFp@*c@^X&W:E/QH^6LJL#5m:$iMYVNNdHaVBtHV+4jnS+K6/4QhZ=h+??^5
CXcZ\1 FuC^LRqPa5Kn*/%*T^t8pSGP:#ui9D#Zw4Ke>I5MhF%puJ=4?WZtZbWwN$#y+\&H?G84QJ+??Cmedu5?
P\hHqu 9dl!9j%n$1tX5Kt\m+YNL#8DKPqkNW4+FKH1E#5/8Ze+%ah\h*SI\!>>aYVkHSXl4/b%LBJHXMLletiJ
+k*E/e whJnkym1djc/ilJHQQR>^:!&6Cj#k%/*t6G?9u8H4yRY!C\8/1MEMn8F&nWQ?TYStt=IDbT&1Mep:G$c
N\w9b> Y9Zy@5GSnwDEhTttS+!9X+y4BB1T>!=md@>k#C*Ki49H5lwTV&#4!m#!/bjuhu%ql!ucJ9V89l*BQW\m
<?y=JQ 9T:8ya:duwm^PGcqb^+:?L/#bL9E>e4cN+bI48X?u*>RW6bR4&CIEVp!8V^p@CyXh\l!8/MKX/5>$KG\
9l4/Z^ \+qEttLekK^+yc%i?t4TF49wnBntCX?m+w9l&lhD\<T*>jAjmq:G/=q5*b?tBGJlywm$1j%ku%+W+hnR
4QtT/$ >wt*5T5tqm*PI+kL>P56+wmuINu?B\Y:ZuSamtpEEF\%j=aR>NjinhLRpL/*+a&9#4y:PybBT5$6:m>d
<P*ju5 *>dGDBecb&5uB>cip!uy!q4Zh@@c<n*?>+Jp1P^A=:jLLZL!95K4H#cdq4RW/\k?NH@6&66$a59D<uj6
BMT9b< L\?i@5kIQEI?u1M^qHMw@4=VVk!hpNnw+YSI!LBedZ/81P9dtmA+WwJn\Y#P1@@iw#$=\hKGi1#E&m>4
p6j1LT pi/w%ty=ew%#VH%Q4b#wXFby4qW&WSV91LY@c^P@!GF9m$>Gu4C?!Kn>ZW%PcL?>MtK9yaZCkkY\EFuw
pe!\1\ 8@K+uty=5kF$w\Bi:yi%Z6att/cY4\I@%j#e4?%k>m@m#n!i!8*j+=t&!FRl+&tkKNVi#>:Qi9a&qbpM
N&!nN@ KcKmEYZMFGtYiekRP$W1SIk+TuEWmTlHKXGJnpwhFayWlnVeNn*h%??X=c=89i:>#^>::j&%u8>c/:P?
J5SpGN /%tjN+>%*^N/%BK4#Ew?PbFJ@TP>XTLVW+WVnX&ttc6uM=hjuetKM*/T9b4KF=G45HYyeu/n%adQ6D<j
N*e!X9 dDKpbKR1/k@T*qT$?5:4T9V9W*$aG<@hh!/Wb/Yk+/JVtI8Qj@THi/ePWp/j1lBW%$64wIp=q^?Wyck<
G$mI<N *hCa\LhIiS<9#Ty//EC>&Aa4HbcRkF*N9N\FP:eHMShd4di^19!<$qZq84in4?hTQEbLehD&VbyCE<QT
5k&+G/ &EJVkE4juNS=19c=>@RbS5>Z^N:ae>=/XiBtjwEMFiXHGk%Q=:*=dGIV=\naT^P>6cbi6c%ypn:y1P&/
/bq4CS M*/KhwDEm*VXL1?5dJPX44RLN4E&8W:%b?&9Fd1b6/4peLu+8LnnMc1u*^Y/*Rq>?>p/N<:qXal6:qEQ
>pGQmL m:SHK\P<e4dLlT=RcNB6NqqR5?JG>&qJ>!J91jptm$yWP^**GYXY%C4Z#6&8^qWWEh%b/K!@6&/RJZyY
%Xe5<$ \&1:?n&G??WiQwWbc6IHFS#?Vemhu#y*5wHG?=6Kpm6Y=HB6N<&#>e?9HmncYy8b5CJi@d=e<>$w#H@P
TtdLZq &5#LG@Pc:TL8HD>XaQn<8aJB1*uQF4+pLVj@iQY1#tXt&JZd!VPdH\:EuyMSTB$T\n%mV&ub^ltLdqK$
9t4:T> KY$qdq\=p&XS/&VwqEY#8YXB6Fi49SZ5L644epI81T^q?mND91+pjFB%eN:qicYu@XX<<#?a>*A=/E>L
pSLZEd 1yjc5ERuPHiZXiCTyCFnEd=bhWTXW5RZL/h%@\!ad!?b>PDyypAyl<D?jREqW>h=jq\dLpZy@GL\*C<I
E56dJW >AyFQqyj%IIN#H5u1p@9WGL\&#>JWNjFLN*=uh$Gwn+*BNpIyGy9H:a9cY=*bK5EVE:l#R&*8mYuqL9j
!k5XeL X=XtGmhl+=1$WM!u@w:95/4?b+L?y*b9$DjWP&Qn#19PP?u6Iy+t%6bFjyEipWiG@MPKQ@yqVj&LW4LB
Ra+TZC #wAq:n8$=pbG\a$\blp:6unXNiASMmV!JnH@XkA:e&jRJ/*I5>/N6p!Bl!F>wy8:t:d^n8#euGVctdNl
:=$ZW$ Sbjl5Q@J@EGFcl4j:S/#!CA/V>QC$>y8ZmM#Tm<AZiMFGYpD>*i\MS@FpD/:1A5yiQ5ZR/PaywCd&eYK
$V%wnY qL&Q6!j##HiI=QMXCeiK&F6Q<^1wm%c+DlZeZZ%Iy$6Ye9lSephA1HlK<4*dLcXdW8+%YIWeYt6+Z:Q^
lPNuEC m6N\lWFL?%Y*mp9M=%9j&GQ8/%^Zl!S8edIY<NhT*b\lnhpF>XS%DL5etPq!@:/4RQJS*W6qputHqAS6
nZ@LTM L##!L:t/wM\8<%:Q/8i=:8hh%p4GK8u8P@XBa6*$y6Rb<ht/@?+jmp/c&*9M&DdTPQhkWyBb\HGh!8kw
yRamMn QV\1+VY>@m=L/4#/+P8ZLSehVW@RB1:MLQVNp44iauQdhp&>X?uW<MmcuJc>GkEh*T9:Q$!Q<HtS8ejE
CeySX$ V!HebcQT+^mnFS<XLj^1e+:u>b6&^y$IMnyS4*/:+WtcN::>:t$X>%1qGPGA:eIFBlu#*%^jKBF5/h<:
m?eJpj /ip<pRe?8yH96Pb4dHpRL61*<kln*%cS@8!<nF#F*D$!nYhY/@e!\qwMcH6b!>euFb:!:9uecywmG%^m
%a?pm^ I1Zl%B5w5<NJb9j?E8<T<biq@1$Hq>$5HW=*DH6R%8K$R@Cw6p?!=+aZqXJtK=m8mmtBXTQBMY6tiKT=
ylmd!F cB$+J!SG/i89!/$8Q*a+LjQR^aZN\*clu$K/$1K9MaViVW*I1dT\jMA>a4^8^M#ZXQ1\HbhCt^!dN$HS
\@ZA9G w*64YiP<F4:5tyn<tP/eHiW^bjKym^K!<//+mQF4a*WT6>ZL%iy$%W8F/ChE9Zj@c:q&^1ELFdQ1^j=e
mZt\8J 49it&%knj6iPpeRHiYhLZdWhyM?EPl$6M4FN<@DYP%XR\t/IF&uw9qQW1lW6^#*m?HTNpR=n$PZm+V=L
H/@ZmW +Rj=F6EH:A>qWiP9SK^/?hHpd#Z/^VZh5SVb&ZZ*c?==YL#e5uNBRupb>d4*buel@unLD@8t@dZ46t*X
EPJb^d Zi:aawPI??uL>NZ*99km&16nKSii4$qh%i6tu:K5?uZTaEil+>4FtG^alI#D*w9PGyTXA6It^t>*bh9W
NMVLmj NX6$cjBhiPG=@//5Sp#+qIJnc<y&jGq/K^J@?CQ6a91>=ud?PZ#NH>P>Z6b+ZMhQJa?E>i=LaZeNPiV/
&W:Dtp LBlkZe@!DKb:%u$yh*A?4*W5c!Tmi8S=imi*kyy&Y5C5lmQ#LKPdk8/YlPlQCdcluuduC^E6%tp^Zl>k
jqDAq& Hm1aHd4t4/pnJhiV$$N:GG#8\ycTynNc:DXh=%4d=bjKF8*%h@kumN1&+<a#?^H6w*YYk$ym\dj!hl!<
CBd#KH @Ny&q/i8@>ShnLttXtHHpq/c:C1u!dh9QQmiFZJMnh8BTu>tXFVy:NuR=n^k&1Gy=h/&!E9*6j44S\$B
GlCV1J $>eyCj<hLu6wMMXu^?dhN=hZPYyXZbn&MEHNaZQ>9$LdhGk#1q:MhlXeY^*u@XJ>X:QD<&LL?K#&>L>c
dmujaB JK+P^1<wqc<=i?mbT9&6RdYVDw5Nm#@E1H#chnd#lKpI%4BaZ@GV16@:R8i=pq1j!+?9d4<u4BA=EnIE
Xt!1/J ZJde1Ml4hkF#>Ey!!qQ4u=m*Kk\Zd?paTi\:i4Q5j4Z%KwX>1=@K:$1Q@VLd*4JNI4D9?ND\RG?:k&^d
eQ>qj= nYmj6wWbyhdMbX@jeLK9*V4lL*!Q=e4j<Laeh5DLBRayknuG8?WL\jwhuaj8yQLe/i=pS<ablH^P$Pyw
SDDFwc hq=t/QiyZF=1d@K8c*#!J:j=uXn<=Inw&YYq:%>Nj5#LQRtVmcty*lkStPNBCRwVC=bdKGP6WXZD#YXm
QDilTF iZiKZHR+n\+9pJYNncAEe<YZd9^n9\/qPpJ@kjSMMb$G\+CR6E%a8AHqbMRqS*Ft4Gpt6/Bal#$nNVy:
G\%=p& nwC>yKlAlFu/8XY4mne15^8iJP^u:=\:Sc*GIt!wcF9P$lknlidX+kE8/&eI%Vc@pJNe8?JI>ibE%^hX
S?y\+T KhdlRcE<!&><#ndI+\+6uu*p1mi@=AGD/6pS#>\t##G9=iG//ZQ8&K$YHS95TKanJm=6wMCqe<A1<d/<
Cna?w& H*h\jPat^6*8VXpP^ytiiSw>lk4!/>wdZhN8h:G*P4I>#I:b%y+Z&LPM4!Z!!b#GcQ9aj>\VlJV%%l%y
Z5@SjZ !qQ4d8@eJLR8uCi+/6dFl&XGIM=E/tqB8eZbh^tu<@4@QEQyit\y1ZGc8:*#TuTWlh!q*1Z>S=V#8yqD
ptcVG\ Gj9@*HBXK*=cRV4@jE!#45A>KPNtWX^RX$>^?yIdn$L#Im\Be*?%9&Tc#yJP<d@tq&/>X6twwu1D99Tm
yKV6%V 46TTS6hcY5!4/BZm\k$K>lwt4/i5p96dLYK#VClQywN1ZYQ>!9qAb$qXl!p6j@iIetSm9^lq+>@/l@EF
Xu%9bZ %>%9XIyym9ii!YZLJe+X5HVMD*9b@K=C1@:6E:$KE*eNy9K=IHbm:4t#W#T4C6#cC=j$tYqRNPjL5F?E
iyH45$ 5iYu/DXbt#M4q?ipiayw@!p5uyi&@:VQMYQ*T&@F/+Sq?hjQFtp#c<dNHi^d#G/i6G+4WY8#F!MciEI/
BW*lyq tNW1<eZy&\/$Q\<VmXH66^Jhw:BlqZHtEJ<%jiS1\1YCa>X/>m:5lbi4XYi=X%hecJW%8i^&hMV4%w^E
/dicH: CaP<yuy?dk4ZMhGN?RqiY=!NL6!<<<dcNG#YG<5wmcj/Y8ihi5S6^F=64mqK>@KSDe5:+#eu/1DF6F5M
$YQ/lk \ZiH\tJnHJSp+/c%&c5V?!i%6&Idm<8XT9SC*MYhb<iGH:>=8C%%yME5#jp\>n1YV<5kJ@yCXLQWtZ5H
Bm1Y=Z G*STBPNe4@m#Xn1$1Nu^NA+&Jb9aZbS@i5=N%t!^^JLm>+%?mwSVqdS4i9*Jay1GNe&Ytm#lbF/=5>SL
E5qRGT tn:5FNC\eZWmq?cVA4t6n$ydtZdyuS@?&N8^i9<!Jn&G484HwGA>>!Nj9n5/cacVTa1G6^8laqJRejGF
#WPh>H #yK6Lp$DM8:9q\u9ZH:W:WYc9$YAR%FZii&4cp@yEQc\%ciB!=i66@ej:RlwtTt/<\%LiFPca:#Wy9^@
!Ahi9L =a8Z!lRehNy=^q6FKwwRX6C<IC=eMQ8K8VC4XK$&I@hALu&>TLN$wiKcZp8:l\H<EhLBlwZep%6XQSay
V5>eGq yty95ShPqw%b<P1tatZJ++Jy>B*$LQ$4q@&Da1wXDQkEYLJH6@q+y$$yCuV4/>VBLIV4<\wCCm&QXN+d
-A%ICh 0005dfdee7000110333 Page 440 of binaries1.zip
8AYy#? =lX#uB/Rw=<edB9%bJtnnEe<R=cH1Z%qtwcTp&4?*#4EYwE:i9^/a1y*JPqlI%\/q!piW?tWaNjJ*IFG
t^\+Ik &>LTqLu:W1dy8m+#VbiIqM6P*hPejtiip@KMQ!KpZ4e?M>AWDm!XQi#c>&^1=&/*^yC#p:MqVBLuK86u
F?48tR ntSaB$YJZh$RTqu6P?hyYLwC1#St>l$\@ektn/tq&&I15%T9<j4KbeW4<*W?jt4pP??\4qpb*>S&8qEP
c6J*FA :=/&A*5y^qKy:FuP#5%Nc>liLP&$8!*Qqnw8>qy+V$k#%Hua#ytlq!/?RP\5>*mwNj\@L*Q@Z/QY<Q?<
9E:86e Da:PL!Ma+Ah?GeHAj+yjBtnj?GYASEpBpkRGTJIWIEqTkCSJAbIpBVCTP\XIqBRkWXKAJIEBP9qyP9uX
S<QpwD JAkMpCA\RJ:\jj*4?+jId!SJaAAuQ$&C\AAJAkMpCA\AE1pFTBIaIEqkkCTBAbL@BWn?F!D=Z+D+@ltT
TIY@ph FkbIABkk5Y&A^H+Bp9aFTNwZIGqjkQZ>M?RZETT6nTByZ\SJ?!JI&lhB$4+Ip9bFpA?E?I=tI<kuRyBQ
mBTknk lCCjCEG!9Rn!kSDpA!HIB$J<S:MS=BMl@l9eS*:/&/Q=DkInD&F@PN:><VCj^AD?#!A\jB#R\I?6aTA\
SG&i1t jB^VkB>d\$Bk?DmkkZFcR$Bk?Dn*?5hyDYCSM%BcR?\M<HG8=w@VtkGLHKC$^tC@VcC$ltCG<HFAA#?&
P:p8L5 lpE6eAbK48ER#BCPw?Rc^<Xm@Naw8abDLNS^HCZZaEcVPI/Tc#C*S^^H!VWaYALHWZINB8QCebSek+Eq
5AkNc= eB\q%&A\Ll^H!VWaYALHWZKNAb8bAE18eX=YG:<%T1=^*6Ed9#XK45G5&ZCApt6$mG$>DqB!Dic8lkPW
yJ6Aky ZKM#aH&Ppt5\k#RewPRcB#a&jt8WZPMA@eb9nbJ4MLAEV1DpGkc=*wIVKLtGAekaI%B!DadV\ktWZIQB
inp!%j HZACJhhkeAieRMp%GkTIlSMw8WcD>nqK46Gkja/Tc=^ZM5h9#jwX#eTp@wyta6J?SVM^pjRc:FISE$t9
5dS?I& abDbkatp%/m\*<cSXA>phtCm=Byu:l!@NaGpY!DKk+tp%&C9w#PS>By5d<BC$t6W!BlnIc&l5D^uaWm1
L+Z#\@ B=LuLD1T/wG5wT\p9Rc^E5SbTHwNynSbTHwNynSbTG5wVGt!pNbRtNJp5bCW^@nbA1kw8WcHKE%AyTEy
9jHM4A D>l9I?p%!H+MWJH$GtR@B1lIik%mbAmwKLtGReA#kA1RhA85#\pp*WKD6EdJNR!mNAEXTc>BtB/Al1VZ
PmSPC5 ILMmwCHyNem5CGkw8RaFR\Ec@j@4CkMa*/V:j?XKm*$DLGGIkCXAR/1*\QKeBu/ZK!$JYMIRAW8AlqT5
&e!+PC kR&^ei@9jVe6A+!jMd9tjBqGG@5HWAJHW1pR/^YAVi^Vm5=\?d4ReRIj:ZG$\DHcL\YPVYTT\CJ?^p+Z
PnnpJ> WL@qPJJuDMCR>DHEM\bknAq/uIF8wV<KYB4%@5ht+Wni@\BDGy!RVTVA\ER8Qa!j/uFP%YeWh+hpBAI\
:&Mdb+ yMEJ&d<CnDqS+PnZ+EdJWGB5XpENuQW4khMu\Lc^cPAuA8haIGJnkVNR48\DPqINF%LdAuT+wSQPaDHS
1YSLkc PWYnjnHEYPBIN><BHcpADBM:hMcE<#kXjRHmPA1!b6E+yp=I$AJAS>4=Rty!kD+l*\Lh\YV$<9kwdRFD
=!eDhG Dy#+yeCS65%WYKK^j1Z%8Cdh*+RT>uY$w?jyX%$\l8#BEJE>APqADwd5Aa#j^WYp5d+li#BEbA>kwP*a
<8p<CX Ij5k^8>C4*E</4+6&&lYd+CB66&HLN8M*#VAPDd:HE9D$eCyTI5I$npmA%I=Bk#t:=uTPM+nHH+1J*DP
W/j&NN pRlK+GkHR=C=GJ>at1ILJe+PBnDGAmhRLIIAnuc1BNu#+lQSubnwF9waB:8Gn<$1hCT@AIB$@EtHqE<B
B9e\%u @45GJ!h\?6ltkI:pF\CR#p=lFT&AV!BNGVV/V\Ah9$/F6LHBTWi!ZkbIB/@Relk?wVSF6$@lTFPMNdab
*j:kMT +GB&WAJu@WwqDqAuBHQ<BE?LMeym=\VPPZlDCB#y!JhPk<\1aEJ?DQMucK6n>qinkTMbn\Gp<&Ka<SkA
Zp9!qW E/HZAIQ%M:YS4+NmLHAecXaBcMXL!K\C\G@CWu*hetHatFdB/ElcBitpGwP<^\IAY8WVIt#SV1yl4apJ
%9=9pk weAaiy4T^%^?PJ&G=9ID$I/=IT+@kICQL\^Rj&JG?=y$NH^M+HH?SktenuSPDSF+^ESi9p\ejhZtFG1@
iF9:ZY nT<c&9lCP&CHnT>mk5YQ^pAHJtBj>V?N>1*HMdRiS#1h^&E>#9\>1CGP?VBuY#KKGpI4W/Mh:eQK%M#j
%y/L>D ^I@l&PB!mn!nkcPX1hHiC+CX1hHiC+B6kbm@XQhpV4l?+iltXB^nYCd?nScEJHYRZm4k%P4GD^#<F*Xu
>>5cKi Hk%q@@j^dBPVjTtE:M6w#G1YEwQBYGi5%dRnWencIpVYMJalN!K!^bShmTVKP5tiyLwnT*cT&!$69%@K
%jCjMS <@!i==#G8V#h@##u#L@je>=##jY>Q6@4@ZuQ=:YST:CJ+Z^4#5BcWP<uA\dRYReH#QlpehaBFpqkidQk
\eIcD$ j&e%jkQ9<99&&<V+j+\5iy$nyktII+aBqGjRbFX=j#u9?n<$bMCXF+ZC@ITKjH<BA5dt\PCBlXhbHBD^
YW=$*W G&+\+IBB%Qen<8ckIllATR4Y\nEdZuHMb84AGyQnJ%REWPWFFMQRbBE?^iB^@+^D5Yahw6eLGByaARPW
@JIw&9 +WC#KGDaZ</:@8<4n5F8mlTBZPeYwIG</GQl\H^QJA9lG&:P#ZVX<V>5\#YC&%yGB+l\RL/uJy/F<I$&
iHtl\T =@eQ<B1C?!H<^^WHKF##6+Sn@yp49kbcYQM:j:I=$ICEA@I>$SkY\nip&kNHl/LY*It%nkkP?YP5LlDl
9CDBqW kDaum++IFkHjpQm>mT8P?TH<J%REpHBAmSuY\kEqAXp$a:AI%G?6S9@Yc5*jY4*laN6NuBnY:nRWay*Z
Q/CW$m kAL$k\F!H%q$pdCIDh%H+G?P1DYDAjF#Im<KWBeJm\CYRj!%M+NFdpT9^8E*hYJaR:Q@?AKA8D6aJLAA
JaLLcC I+9/lj!H*JG%y?pQ+V<<Z&DCWd<qjAN/NS!#tZHb&B@Cj^I!kAuZ@C*lG<JWNnE8G+PVSYLZS<IDm66k
j?#89W peD?J<Pm<CJ^@>C6<u$:IDH49Aa5wMILKLYCa9W+*Cm%k5N9luTE@DE\@!jcA%D>AyScRiJb%C@WQ:a=
peRme> %\#1u+>DJCBpKlbRckZJAytK*Rk69!ultDW!^9wRjpDIXC!k%A1TBVIX?<9W!9<lC:jtCTHZpcqIRH$:
Rp#jnL LKDWCyJF*\/:Abei@j%$mhwMMAm^np^FApKtaqHA?k1@6wT\G*Dy9#<e<J8\LqG!mHYVAAHIJMCmkjWX
Xb5MWB eC!Ed=n*BN/*R?HS5wl%p\AB!CVAwwH>>+:FIi6@J%+w@%t:Q6Rh@18l:n>H\c<Qhehnj#HWHj5@+!#@
hnmtwp NhShE@H>F@#@MNS>VKF/Y#mHeXP>M:=PnK<!!4auk!Kwi=N>pFS@ZQPi?DBZtc:mc$jScEMHN6$pK+!w
hEpQpl DJhT#$&IwEEFi%b!LRWCp/DF81A8#l:Z*SZ@#9ueNDR>BuZ*%aphb#I<hB5Vapa+L1YMt>6WD^YK8=1d
yIS<l% :8^8a!@:k^FRPy<wKtckIFTRNc/&tG1lq=D5eS?=A9aPQE9IIll>iM@@TC+!1/ehhHbcc*8P:uYC?KNk
*6E@Zi k46Eyb8/j/85lenliFk5Ey+i!8ju9lNWWP?c5IhkLTpP%e5yb@IYCb8I<41&&uj\<c=R+LV8?A=$tN^>
!C6Rl/ T<u/+FaK11EIL9y#Jn5l&Ih>=&N=Bi+YyBD/B9%B==c5L+VkiIw1mw@Va*5+idyDQD!a$C@I*&Dtn&%1
a\tkBt H^4aR!9#ie4YZ4LZYA:LI$LVClW+dTbSjKLWicicXjSYIcSGT5F<MLuWC5JH1qTh$y5iGbRMa!:mhZQu
N&TJ9B cQ\nEPV%$qA865mVIC9?/#H>aRW4nyJ+E@bmmX^/VIaRVDepYG&9ybTyIVIpBNtqe<KXmWDBXAjRVcWK
&bYw&m BEE?n=$E4R1=SN&>85!$e%Qp+En*DJZlW1hEWJKt/E^l$lGTwPXTnA19Zq>G:Z*><%LSbF6#?>#beDFN
6TMZ?6 EeN&4N6m98*X=+%$P%&j^%L>QiubM&<ViSqe!JCABGu?PEet9I:<5Xtm=c#WZXk+dPcM6hH<$^q5dEI5
=IQSKD ySM6eGn\+::=tLqRe8Kdi<6h<c6+iC>YW?nwEjSJcb5*C+^Jp</dIS=%wME6b@\6\Tj%D^?:K!$yGT+8
ib?!E4 X9u/9Zu:+:nm%ckT4/Kp#+X&SFh?PcEZ=#lt>ykuetZK>8\Q@<P+d/wYY*n/G5h6!&QDl4hKeANK!@Si
jiD>Ru qD^YpTF\=iYlS8e*F\PQ9dBV:Yk!G*&WPkJV?IIqmaAIkmaj9FhXHiSe@j<cLe5IF/Yt%n*cy=E<+Syn
CY*bGa 4X6/Rk>$5/:Z8=81?VLZ=a<a^FuIdGjAnhK>hpWN$%JQ!$X69^m?CCnty^!9ZlVERyu:Ed9JHR:DlGG/
C&6TZD $bF\VQ8wNLhuHCGld$D<t&iJt@#*LiQ$WT1NjH:/T*N%<8nFN=+bkX68h6*aV+$LMe*qbE9>jMP/Q%kE
$n<>h9 MtM:taKMmChImR@4/uR$ILAS:qWTk@uYTl?GElc@LR^KV6m:Tb@ZTq+PF>pG+lT<K%>>K4e8Zd/Yc$8:
SNVaZ^ =MM<8*jMtt&H&yXcM*c$PtTm&ji@D=I9#!EtH:QCBh!m+c<p+4i?>XB%#\@C!SSWe$lj9*6w>>n4wuL$
BL5<!# QI?\wYKdnLlGm8Q+#b!LLkcIjK&tK1pwK>tI&TQ6tqpWj4cKw:R\lH6IJQ*\KKeQWWNyC9d+d#d?+YB*
cpFchW RuCNSw5dZ</:SVk9SLyanWQcNDe$1F^em8NC#BE^i^qR%qC461D4!n9/9=AJ6n9TSA<ul\T=GmG89t\Y
M!?CPG d@<&QQ*NtLIFR9!+T*uH6KeYY#?u/aC<^B8>A!jb>QmWKZQSeSBewF1q1MIPN@qu6i:+y5a:neTw+qjY
EMy/qb ^QC#MyKF&KSndJF+T9TKbMiEj^&%>4dHdi4??#ud\>=QQ@aCy/pw+dN/W>JWDa!VeNkDWL\$YQ9K1hI8
p!!uq% !?PYZGNVun//aVEh99eGnIWpMX/E=aKDqqw=nW6^JyaZNdiLTdt+6F<VMP99Wk&NH9Mt$cQK>IRN6w45
!=G@@I EtW:\$$@wl&/*<BJuWEVGI=V!L&wjhC5>jIhJcZeAe/^/^j>kq1CuTNTBPPCHiR6&+KS>T?95l>QeWp^
Xky68p D81RGBpKWEMhy?YQuWW9L9^LSnR^KQFbmRpu5ndZG\\L?!19Cnp9KHMuHLaITZ^Sa<X9<qC\:P4&?mi4
i&:hq6 9Q&K<N*==5yyY9jE4i+e9FnYD:+ljdyJ:qd9WTlZIZj!i@En#>tWNTcecRZwTL/&L+u\QM<\<Tm@aV*N
\$6emw e8=Y\4*6$:!>$GEFWFlD+eBu:SKG5^N9bj!HS@Byp1D\AIt<8Ee^:aFX\p+BlIeah=Z!NE\j9i$/<m5$
%Qi5qH NbV:!^MVB:Pd^TIYaVXXp>X6KyT/B8866BPuK4GbuNqmR/1ZHCd+TkwLH6Lak:^=GD6jK+w1K%PihlXV
j\Dc$t 8=Q1+FHX5tnjC/qN%^IT15?1$a&$Vc!Ed5CPh4@?c!^GGAQV:\EH:VQ^@/9uJFeL$<tP49+Myi\q=D?e
IP46lJ \QaI@nLSkTkiGJM18@<Q#/nypVy+u68NT6YbtkX>9!Ta^uYSL@h9iaV4u>HaQ8TwhND>^mj@Y8aLkbTy
Zj$yph B4?F^LS5M$aBIW**EFq1&Pncu/=&%I:Z:e\#n?+#jP+y4d1!5VEQy@w%>Ew>pbuS\8$*X1&iXJyQe=t:
-AP9eF 0002ccd443800110333 Page 441 of binaries1.zip
bpc45k /LjejHNj^Zcnn:Fiq!hSi$K&eS^\wkpX69!6@YmQL1/%X$c4l9jd5/AlcZ*S^?t1%d9p?!tX&^qWk59y
\\W1<y CluM@CFIluT*:@S8aiZQ$eGyN6c1j$nWH1=jlF5+YD$hTHCnJ<c/ua^9tcK*VS&I6Z?yJ8F%eJih&RBu
ECt!mL <R5Di^NwK@1YYQy1S5c<1XHSy=y?T<&l#^WHdp5:ZkqLnn/Y%pY%/DthX%kDSpn9CK\RTqKSKkL9FE/u
<\wJS# V$lPpdhGhm%wD:XVV=1K#i^5+>YajI\9q5MF9Np6haSGVN%y?*\1?SW>QW%L^JdN++W?4p98/#Bd&ih!
jTA?!E 488p>p/8AI$A1E?@*tXh4uth11dWD:IjTeJL\6P^q^\Zly=G!i%VJXe:T?=wndT+\RiL@bL96*k9=T=h
HM$m%P Zu^&PaeCi>k@9yDjhcd+Fi<<8?@6JK:DdV\/kqiC=tIl&a@Qci6?8aH&9ib\NPbRwjnDe??Ma!+q9=&4
mH1b=^ 5hh?mmeXkS>wn^<5uIca9Zw&<$t*WQm6*j9#GItE^!iSE>ZTq=L%Y4YcSqK%%j%8Z<BZWA&?$h=WpdPE
JtRjJ! #ZWC\LVtB^HJky1+#44#mQnAeu$d*6h%dX$+pNFi@t4w4FW*/NP^tqaFlSACnc!ib/d5P+DeM9#XK@Nc
yhqaZC <J<HQq<?*?Pi/^NV58Cd/$MnLu\$:18A*6p14/$jq?%eR5^*tbN%/detN!6M?j#qNNBuREwR1M5cnW1t
eCHL*@ &YVMP*?bL6$jR+\&%EN#Bqte1R<kQiE!KVb1GT*lK1?>tqR:*$F@&8h>9NqRAi*ICVILQSDh&J+iY5hw
S49G@y GX4l!&jPT8cyth$mPIJtP!1KLiLWnhu6$hckJuD5J\:V\?MS^X6=Nbb=IC1G&=PL@RwyF\1#t6*#uh/&
*?5$dp ak/a=aa1%ia5$HmW>dpl=S?llV#9RQnRJAZ:G^w<m1>Keu8tVS4el#R<\WpL>bE1^btq&u5N+MR4kZ@G
cniNmy ?lNhp:S+W/aWJylE1lM$p8t?^jbPDuhR#<N=Z==mR6:8LTD#P=@myi498AlSKl6mB<pq1S!\i**\Sy5I
>>DV/b ciE51kcQM?m$KGV!M&hlilRpPiwWl494KC>nSm8LAHatDDTP9^51Vke#A9T%S8d/DnXGElyZ9:m<bb9t
L&1yWy HmPVnyy6WSpb$8>a:ST/ayt6XY*1ZJ%6Z/WjhR&^wm@918C!mQh59/?Z4Ha:Kp5F4APKl&=L$VN#%h?Y
PQan%V jbt4*kN1=qh$XG6LLKyVub8PF\DQPaShE?68Q61&JG99qhj6^k+9d>ADEd1*Kkt4!=!<^BG&p/P4@hp:
4KKHdp C$n<e</4H8?u$ulHRT?<IkV+9wX1=Bw+iykcpWK:QFaTMQ8STL@dk*em>+TM+&/DTL=VjdMCTW@qjVSG
QqIyi> Ym<I*ktHQlSC9BT!B!qpL?ZBeHe>L@QC1Jb=dPKS+??hSQmk%K<R1W=LQTNKPMMJnwL=GbKHnCd1A&Tb
dP1a&Z D<kL9EWkFI*GVV\C/lIRGF&JWB4>FD8m=G/ySJi*cp$&C?j%&*%JZHn<eSj#TCh+4@t:4dL8LYy8K6P>
hBY^b* 1lCCXupFn=Eb\=GbVqt&YXlhMcpTMchPdGXMGGGGu1#8e@SQm<1hGJqyhGSPhhSd6tKwGyIlnV&BZ9HD
QXmm/l V@+qYqGF::bnEN/wh\t//tMc<p$Km8/QL5lBBa!kBld#ck5Kb48E%iW>55iE!&Jk>u&kQHmtklBuV^+t
LDZiK9 15@>>pQ8?1Fb+W\e=S#SK^<b%H^qIV@aKp+$c<J$%J<^kq9bda%51yJky!9Bmu5mR%jhb/\<+/8YmJTE
pGQM1t AHV=cH^nuEa:XkJ<9!PJE>G>^>6VS+\*W=TjD?86wqdYYQ=M*yk?1BA&+!cC*!cmR<w&5%&K@:T+?&/b
T984W/ wp%+#m/PK@i/9%ZJ9?9NJe%H?PMZ!dJQ?PS&?*6p^Xhd!XS*F4mEaQSdD!nC/!4c%HYb8!C*5N\<q@kd
F+%<XD @aQB<&STZiMy+wHT1@1WKQhYehP^=lnmlekkT1ZynLbHPHW5ne4W$Si!WHj8euRVLy1c8$#=!6P+Akw:
N+P@yN c8ZmyQASK!V!!nly$M1ZyCF/$&dy9WH*yIcD1qpa\/^RiIG8MTu@#k6&CtQk>bcnuw?jp?Fa?imcIIyb
\Pk#/h T4$tyE8P$L&c96\G:miyhmFy*EEE@mKR1RqSJ*<c:%9DeA9@t##1M>4DJEGGG+eMilXS%t4/h+tH*Ai6
45daqi lT%In^@5<*1G1unDduX+Nq5:M/d!njCITb/pVcPRZHc9KiJ9$=!Ci$5QLdnQc+&pb+==!w+I!JFCihDQ
w%&&N1 V>Cy4<$XVKiqIF#\9&\t^djYFicqyJ#=$^FeeqR^kky@aVmS:DXTuGdn</BANQD+8AFnny<51=WZPtYL
P&Y=q= <!G?6GIYV&@=5\+hQqkpu$uiE*H1pbK64dV*Y*cHJN9?*K1q@DhY4yjAIb1&jqB4??iqj5kkPuepw&/I
iPewi@ \w$$JwW%S?nXnydp&Cbb#F5hd&?nj4b%$b+K6N8ty9@EK#ImVTX=ibY9b%q=<Nkp>BTHctL<pQ8pnt*^
a/*YaV E5X<XQHe*@a6ZPnPt6t!TFLmEe#&W>V#+4icS?>pEd4t@RYMVpqy/w56SiZbG>cLYi>LLn4Y4&5A%c:^
lIJu%$ NqKP@YbV^ccm6E!J1QWZTmyEu#$Jy?k<?<1@MBH+yAY9iHmK!P*IW/LY:=l/NqwtKlZYNZEkBDpeSD%w
wJ@<GA b@h&VyGtwY+=&qjpnBtBL\V/^q*M!\^wN#uu*iclh+G!+=^%DM@yImkW4t\H+qWJ\^>Q@u^?#5*X@K%t
#&BH9n hPAHAidNY:hh^@>N*dYG=bm%:hLG4y4R1^$#>TaW/4u*c!Y$M$XWEyQ6SD9FECw!^1bTSpXD6DM#Ih5W
QAc4wW p5b&WBNCCXFy$JA\&R+^W+!*?/q:98N>=%uQejZ%jP>^jQ@<iG+8c%%44ZNh%:uP$*=$pIi:\/Mkb/S:
Zb+ZEA Z%bq<YbFaEdCIdikJe>uL8u1N:6l<pji=:\P8F!6ZjTDa&!>S8??QSie#^8*c8Hm%<HG\lF4Nm!nd?l<
PQwRjB 4!eBJj8$%C=w1q*RHiV8yuutR@mdjR+%ERN>A8K<jc<9e@ZPj/!@%9iRt&8BXjCY8!HXE>#8nXE9eH8&
XAtKFJ iMTmBMM^@%!/W8j1!B5=WSFl6*S5R\/y?@Z&V+#e+^ji/DAu6tDC\5<dh5?1jnq/X<:e1+&VH@iPCVD?
e99E<6 LK&9P^61u#VN%eLKhipyA=iA:G:thNnnbh@+4LmQjjwMmW&/bDu$M6WRM@@wqGHn<:&mu\$JqB$@@HSJ
d$PK1T jTtHZp>cI*5Z666c9$d#+bZwB#p+aQ4WypY4p?NY?FQ4a*>j:yqlK:T5Yjyl!aCSKjhVV1b?Njj*L<K\
6d>P8L !#Y#MQ#tP:j$#PTe9PH^QVhW1%8YHjadbtiLhJQ#k6u:ydM5j!/MHDG::!ij9L:#QFa*9HiQma*^=q&?
wF=XYX >*jN/^=yX@lDYQP^b+hKR9R9S&$%iqNi8t%5:@hVZQ&:?X?ceu:&9Tb4?+N%w:J1>YJThnV#Yt1%E%\K
b&DmKq >JaNHuutjQd4Ac\&5?!1w=j9=ymTHQ/ukIkDD!P84#4=\/i4QE%Pe#?QnJ@6t/5=>iCWlJj1/i+=<>G4
iua>A$ #!M?&<\j!4A>PDt6Nm+1eDYi8#Rm?pd?45YG@dVWW1*@mQ?C/dM5D!Y8Lh5j:#S%YXK/deuAAX$5DH86
h+c!cP LH?eXZDd$t:nPWN&5?*S5Q!F1#*C1IY/6n*/9m9>6868!qQDKpL@eX@ZRL&//*#lLMjA+E>L=t?5@Hl$
MRded? m1ZMPD4T>=lV$*C9T9TW@/Zu%Y/HnV&bnM#$bq*>Cd<W%M#c6?XHQ>6N>5heS:1$FFS8Dun&jpQ<kc%d
Bl8aKT Dt!>?ec:h5dea:iT4#WYLupb$nV4/Kjq%>L/&4ZwWAj/&FcbnZV:Mda!a+l@c1@c?I^D9//NLN:Zwta%
MK>p:Q VY6*cP4W%HH&8puL^tYjCA:K9jKX%iFFt6%@9Pm=QLhmXX=n\?MBlVPT68W<GtFcYBMSHBSL8WZmDSHQ
V?$F9B Kw<H9hiQ61>hiGNq!<1Au45<Z@a@?$jX+9CbYZ+lS4EZdF$Mq%bHqliG*6V!8PuL4%k$KulHhX%phF*j
9Q@^AT 4/PZ5V8T*&=@p=wdQm1$8<*Wtyu%6>In*+#K1nBK&S1%IL*t\J\%S=9j9dFiN=ud8Z6h^p?q!%u>J$^1
4BtwTC ^685u/Q69lccHpV1=nhbDp5Y=u+i?ZSN*8*M&R/i^#S5nD+16B??%Nq\KDN#aW9b\mYyk#%MhK<q&C$/
$&q>qc 9HQhV18AJRZ$/eL<&V:%I>bML>%d8:yZhnQ&DT\:edy$Ypu9K*cC@ZjLDt&qX>*!n>ZwX6@6TjK#kPcE
TPPHl? hINSGXVpTJ$Vt$$unc<+Gc?X8?<4e@c>=dcN+e=jl*#VaLL5\D\Z@?&4:qiQ5I4V!^#l6j8ct+pNW/KY
kq>AS1 YuY84p@Qd191@VPN1^h9D*nwWZS!RYZMay?%D%uhRWX&D!<MVQhb$@%<5QGS>@=HL!TWc^SacPXtSpW+
AMuMc@ :q^58!/%Km>iL*yMeMSHVpF8#Gc6*Ktqh=iHX8&8e@XNp1Xa/d%9PS\Z:LZS>j1VHWK%c/VST@&a@pYt
R8W1Rk E!/a=8<iPjnu=qhn$$I$VlVjZQNYR#Q%>8P6L:QQ*a!9G:X#T:lFe>&6Gb9ic^Yt4I9Ku#A@JjZ1b+5e
RW$wJZ R&wc*mWXV>dSMw\yDdH?aj4D?w8u\@j@N6@qY5abd+<9G@<^/X!t&19ybq+u*m$MC*H6X*L!Yi?Lq=4?
u=Pd6D 8H^5WtnQuMan\Sji+8K+p%\ZjVM#SjLA\4?@pj69!\ML@@=PDm+QnIY@!\NnwYQ!\Il8C/4%D?*/5ElT
DlZC/! p$YTtm!T=H&SJCcLJDFb^Eym9EkT?pY5>G6J=^hJP4>I$9qFp5+9puS?ETjyDCNJ/Bj^$1<quX<p/j\m
u*Q*QS TieZ<hKQJeFj%C:+&@wZTa1@TFL<SaL$c$u\F!Hy4=cWj=Gp@I8RJMcLJA%kJGpAI$pDGEpc\KlhA=nF
RTA$XM pkR\qmTA5W\T+<YTBnCYNIC^yAGMKiuZpp\#qqTB5TVVnGqy5LGpCw\qXYA51RJncS/^NI>atpe5#TNt
aqRiE4 yMHG$pSmcj1\NH%atn+5#S1Ybk%L5+d@tnW5#S1Ybk%L5+cqYeQT4GFy%4A$c%mc6d@EmKZt\h@cEu@u
&and9J B4e6IIm+ucDkbciC4\tmZ+ICiXpFZ^QE:RRFn#MXjE&Rq^WW!M51?Jwq5ApW9K>W<DYBTT+wpJhX<DXF
E?*SFA /K54iCKy+G5bwdt6RF:&:%?LRuKK9^akZ=N+Sl\p%#miNPcRZPMI#\+EHyJ4HPH^6MBDew$n9GAYiEm8
i#N%+Q eaSu^AIQ!VYY<JbZ+CG=^yIaBV\p%%mi>G>Dew*qCQQNR*KNJV^MFZlI44EEmVmBl?RcT=CIE\SI44EE
EAI^DA mVlBkPRcR/J$C=Bea\m9NRRBpt5MmTM5RHKNISF%BWm8peTIBRGTc\^NGuNI4wpQ1lX@Dep%tuTGCyBe
@*+#<V w$quKILpGp$/R^Ep%&nTGawk8WcV#qAE!VYchIamTK:SyDMWRZKNJy&lCJJ4FPpMSbBew\SC4mFI4yGE
VXPlqd pAWE!VYTELKAbb*Bmyn1DFdEhGi\Ita/k^W^&^t5mLuPaEZMh\a4a1E#YBGn#tBFDMJ4lD^HMqpu$B/T
#d>/D^ kjAckT8MbCC<SmD5IlpDRu55+Y5RZmPI4CMbCK<S=N1RDIVZiId\NR!9pd+G+VYCtRCTkjAc\W\AWbBe
1*?$T? a\l=nmkRZmQqPRZCc+R:EcJAiI$qbCwF\t8EP^GmRHmN6EwwEF+neM5SJaARF&GXWCC<JlB!nRLlNhI1
LMReh^ wWF+nTA8n&kRZmQIKCMclNeIM51IB8E%ApbGNA9CVISew!G=SlG\A/Il8WcWeEd@<Z:n9$k=SpwpT$WB
-AkY\L 000e0756f8700110333 Page 442 of binaries1.zip
J81qRc Vd+nI4F6C5=RcR^E\$y:lPqt!Q^!XqR6Be8@6PL<NkXu1DRGapA+p*ADS5wij>A!Fm:@$9wQ<HLJWpaP
b<&F/m :mCBk$A1RdIWMc!K6M>cMdTwSC5QuPJBkaMRLpEcHnHKhVW+iK/$apdS^EIi8R!$9lkRQmd6y\^T>llP
9pe?WJ ^5CXCWWJb>T/:XN!PA$JHLR/TX5=1%STpaX9K/%dmSm+PPLA\Ft1W+E4qXTE9$IZn!uS@$Wi8CCAAki6
e\tanK VwKLAGLJ1=Nn^GaEiMSF:Sm/LZCiBRZPkY=^BKVF1p4%Su:!$Y*:C5iA>lWY%G$k*QtSE5FVtlQZNFkQ
QiyjuL m=j4u+m\Tm#TR\KH6TwIIE?J+CqNmRpA*qaEiiD!EaeFD81ypRPuXVQmdc4bIpnC<5aGJHDRyb9k\wM+
uKE&Bb XpWnL1Qpka5nDk&e/%Vk9NISy?FK4d#wyN6/?QN!b$yI+KDFTSFkFwiW9V@p+aG*Bm$GLl>^aPC+M+H#
Dq&G@@ MlYNiP8&^dcPwil?\IJE\BC5CWpRAWNKBE<:N8Km@kuZBt!lkVPhCy^Xyp:B\JWppTlP%Hb$mk/wpMBB
1@NiV+ =VSEPDy=yXLlFQ#My&X!1S!/>S+phm\lkaN1eS#l=PTX1^HDjaNaYl/+jMTBkiQPBC+wW!QtP?A*$V1q
<P?WR8 wqTPQHAKhJMAhY%bquCVEJVlYpHGhERdq$F6kJ\F!YwkWM8ZJbZKFc1q@1ZA$kH>b@EYIdRBekap1+FA
Xju>4< @YKYXH<WiNXhq<Z!4D^\pK\GAnYdTTyDTFC!PGWaeS$^>SI4\@LARdIcCNTybkm!GknJXLRhmn+X4SeI
XayFG+ WZ1aAeq1IATnXBBkLcJX6B$!kn^\?akDA&e/FVkb%nIClV9k@!a8#LbhScSRRAIHNReI%B?EiGYB\<8i
&^#5V# ew%#*L/4kPV\Eck:V=LDS\mySk/jF4*jWN88IlJHIIGDFmiB<IT\$5YJ+Lh<ZyVBd>6XSM+KIHARL+Bp
BPYc6m ^+p\4byCM!$CLK=6eay$GWnkwMXJwHpl#Cwh<R++J\l6%mbm+LDTQwmSRDIlSblZYn!pP*Lp$?&qjSyY
EXVWI% &kjSGWn?y\knXa%+c/1$q@byYGpj\*1Gmt>AYKamJT&=e$J:cb<Gqja^mElBeu*FMqyXdtSadm\9D^^W
q&:wu# &eekFkcyW+yq1t1t6N=W1QaCPRW1pGMRlaQWyMW!ZpY&C/K8W*8BuAIX!DGI@$G!&eW!yCL*Ap:YP8y6
*Y?wD1 J!eFKyBnEHtEIlVIMTXV%WYCN1Pa6yNVbPABAke^V<T!l?LAqT%P$i8qA!W+mt+:PTtRH\5G$Xawkl<L
:dC:$B yySWc?Yc%l$+kN1MLlmk$RWGeX=ISliaWlG5FYXKSc<4yuXL=HuamEMYy!AnnVlTKpWMD:\XiamB!+$8
G+LV9y kIHn#kSPK/Wl\Q&aSYZ&nqtLaJ41BH<C$$wduT#:j&e6kpE<H^J@A6M1cuTK^TCSQ!EQHAT!MIkpSPJQ
kSC=?B aFyXm:N%=^V=E@LAaTCLFn4Bu<DKdI$:ekCJlS8SQmEQHAc!aB\lE5lmXNSKEbX6SScC!P?E5SA\$^pY
i1D@n< AtbW%EylY=GHGHmdlR$5eKbVkT8>e<Jh*lt=hZi:>\+MHeI+RmS$1ERk65N!yTJ>w5%/B+RPRSRlEu$C
hL:mRC M$16RXAH@B=c>*Ct*j+Glk=BFCGPlA=bEQ?iI@!*RT\j<6i$mkcNF69^:Wa\INM:#MJ+BIRhnXZS6bFy
KE#XqJ SbA5%&+EA#K>\!CYD$5\9eQKYV+a#kkVZ*P!hL59CRQcGWA5H:HV4Dl!$L5B\65eDCL1EL@t!HWbt8Zl
W/QyNW 68Fmd%R$jbCL+aQMV#GI1MMT#E<^y!1Fe+GZ%<LqkeN&JR:Y$TD5Tl!4tn848MBEc>k&y\4R#5DBPl1E
j^#K6h uWE=WRjPMGJy$iC**YID^PuCIKIPR?B$aaXEuj@bGVm8I#eS5dA8&6GIC9cR!EE6Da1\PlW!hhwny%kM
ciih*+ b\PI%&\^<ndLB%DpQNYy!GuX:T5$&!/H#+E8j!C1Dw$Iq#?FXJ*@lhtj&Q!t1Zc9ClwE$$BWHb1EPHmq
:l?=8E :qa5%^E@qw:J+YMRXaepl+>=Jh/yYAb9Dan9<8RpRJcYW^wkkaN/G1VKnED&VtZpL<9BkIPXB!+jeXnk
=+>BIZ IKwPPZCcQPK</HdjpSF9L!qS5JITmKyDpWyK\u<cEEnj6l5RWIwMCIS&?TLSkICniPH9BkSaWGBAIB?I
DGmPQC @\<GBQXtCieCLSJYXT^mC$%DDHJ&&tYb^VlyFZ!#/5#eiXSS#>uSa+=/D#NP%NJ&Hy\>d:B>D@ihVn=t
+bAj9M CWFcn5PYJp>1tI?#L\R5tuwtiyS\5E98#YuaKHl8abFNqX%hVQ#T#E@Q$/E:L??N%94Mkt&ie#TIMd%u
K8VnAS :Z5w:I^@F?5A^!uW&45&nNE/:a^lqla>d<YPmX6?ayJ5n<9bSH#H=tHn^>b/V=K>Bt8bd&I6%ykueF$e
Rd?!&j #nw+ML1@8Fea/HpNajZ6u%Re/BK*#iF/h<a=4LV:CI8q##YL>!R9:1&q95i:VC8=9q?@?F:498?1M:Sk
Id\Mu5 IK*bJh#LwMeG@:Fc\*T?QQPDSjhLh\ee%QjicJR*/&Bwwubyu?@i^dqQLC1lXth?WD5=!?FtiX#!w>@$
?KyB@9 >eLe=lk\B?hbG=j=H@V8X=beaGX84y+<*TV8k9:WuFQ1J</<5:Ny@QGCi\y#YM*BYeh%XN!+u@8+Fd@c
qST^eB MdTjq5b\G/Q4/tyF?44#Zni/diAMbH*nJ9w&$EX:KmbkdhuVKjdYIdX*NlR/ytRbcmi1#VQS9nn^#$en
GW>9&S 4@S=KuM</:cH?&iyl61>$6Xc+h>c<q$<H9wtdN@?:1KBk+GB++TILY>S46@WSG*%w$HH4n#Lh@6RpikZ
GDARtX eQiT*<TYwdtdNAcYn*h$1Pq!c8knj&=><8dB4>dwFJmPu=ke+S^ZN*HG&K\%jh^h#c8/>$qI#JyXuQcN
ZFNkBh h9ty1Ftu1uLZ^$+SVKeFn+pK^H=^W:ShVGwNLTa@QdVq/c>NZj6PTu6$/m$ZdSR@hET6R$Y+8?p\*@JH
9GWtW% kcQ9?q!/Mw:bhuSC>A$nC%8j+54cc=i<VXI?eGZ//@MNhI@j&V9?85cKM$<<D4?Z&YlQ&>>uZiPZA*y!
CD&ecb /$*>9P!8#@8>bQ!9XT&WZ9G4qt6Wjw8q</FucQ/k%VX&hYXFHp$8n+Tu/Hm9>j+Slh?h5JS^WePtai=X
C\/quX m4Q^yB%#A6QZdVS?9Y@e:&ecd6:8<Z^WqEPwWZBNj94m!Xd&j+#!?5lt$?&d@K6Bp!1hhabwJ@1QHyTZ
&tKYtK jhV#\QnFN*ICK\4h49&TQIP=@dn!=BTQqXX=Y>c^mX&6QC<tZY#8pu+:iMTVa1$F5=\99@WaWn\<+JHJ
kB5ht$ CTj?/y$J<&bcG**+91S?1WqCBhMRjtZ9k#@jPKe6$FSj*&NR8Mubehe??hJtSw/VYXCQj4N%he\4!4h^
1e?Q\e HqXtKS<#a<@cPXbc9*ZK5l+%EC>kNn@Y>KuJaLKPeN5H9nN^Dk9YXH@R:bm4&n/h=q!u=/?S!+8A8lm@
iwQ^RF pIX44iK%jew@VQ%y8yN6SIZly&mj:?>t&qq%Pd84\m4/i!hPi*cpKj?<*<dNa<>1c*jl#qZ8L@#<&I8w
!KQ>Yk Da<M?5hH9$&4DAwj<?L^8V*X*l5$X>ppyJ&#&Z!!l*yA?JT>%5QV88X=i?>j9?H1!Z8u%?mc1&>4CQVT
F4HcbX hl#$&@KZF#XK9d!5?^ieT*uq9?pK@YK<+bGwJdbywb?Eu9P>5uiu%=4m/H<5HJ8ph!^Tk%:jQC<6ih8K
taDAkq >P65!ab=c!e@Y&9W/&&I!eb>STuJVVjPa:&YH4P9jnb/\Qi:m$d1%8T<CYye=GTYFY#?aHcD^iNJ!>tI
wlBJ#= 8<Q/X<6YJHF*QCaP:D>^:EQu1=c=SiG!KyQmVNeZZ&l?q#I!w!F/dpJ\66*SPV:SQmY>^1iMVLR11NL@
pAYn8G ^i+kM#:hdmDucLm4&Gn!qXZjGDSFV*de\\W5Zw@&j<%i4L@@NJLcj?6/SunbwH/48R$N:1iNZ%S+%Jna
RZ*AX9 #V&a5%t:$eH+5t:I&F>nBq1Q?>a4e>P<%YYNqtyiyujTM@TT5<6RD&jdpHXSuk8Qc:w##+jNZL^$>8w#
a/Rt$C hEuB#Z8ik\e9iuV://!c&Di:4A5Th%L4Q=:m+Jc?LT#y!w*b?XP@\9iQPI%^Vhp$944!?pYjqW9w\q&&
uCXj*: E!@wbF/5t:!y@tu1#c:19?:Z#6G%t&adeD!%w4i@qqYK\eD\c\@$Y#!%%B>4H9G*i#8^<tDiAb8^y*i$
V#1yYN BP?<MLld$lh&=1@aB>Zb=SQ%LQNe?Q$>R>RGh>ihd&/<yIiy/hmXwYjn#E=q@^tV?T@19n5w11b=q\!T
b5j4#= lRWSEWGRKLBu<=J##pEWDIAkTAcSbHnJpkXEpCCTJW1YICcT=C\GWEEWpKRkI8c:m?#9%u$@D9j\chY6
h4qh$L ?+hXy/#8QR>#itb/8u8iuyF\:Etb:/F@lXLSY\tb5pCa+GG*ZCl4yXy5KIbca@AuVNPP4DwcHLl/T:P4
1wZ1W& c!ZBPDYw1u1Cj@:IdT?N:nl4S4w9L#q!bTwYic5u!d&W!L!C6Ri>hpYGbXRIWeKVnF\$^dY@Gu<!PF1n
p\#Ryk J4i4Te%#+Syen5H*b+JF\$/K/*j$@A=pu/Cm#:X^NqJY9^BWNBi5Gnu/@H:b^X<JAy&*GMtQH?b:4Ha9
+lcJPQ /8De\Xcq/\edMG^\D:$qijc&\R!hCY?#MGeH9Nn1PWC+5T9eNq?k=aQM#8aX/plLqQpSKS@P*yKR5%Eb
yWCBH4 F<\@Cjt%!<:Yyj\wAVTaDh@RL*+WG:RP+^<I1tuZZT%Gn1ZlJ!#F8e@i&GWc>?Bb^luyPYV1@E6d/5:e
FReQk6 ?LuhKnFmS5b6<#p!!B?H%#RZ+=:pyub$mFAN=qdJZMHjyJ+LTe&<Yq*+LCuT#%4h//6TZ5HX5+16:HuD
i:bWCI juaSI+HTF>JuWFS:PS!>nN1Pe\eq!9k!>6l:V9%#wVc/h4@#1hJ$ZM5idSw6uu%/CkMqhZ88tkZKCEju
BRFEQH >j1c<@A&99?untFCLHW?\@%Ic:qkG1:FWYJqRe+q6iJ5t9DB1p9nQ=X1<>SjD<uEu#Mw6+4B/qLV>A%T
iW==Cm Z^58#YJiFZdpq!k6=A4#N=FY8n4!cRhF=B1hpHbc=/=hN<W^#Xe6K9NijZTLae>4KHPW==9kH1Icbm48
YidYe? NHb%t\!JRW#K9nZ?tCQV5#aZh/*\qYhSpTF?:NN=C>8YFHcEY>pMy*Ztpcmnmtah6!Iy@qq5bjTXyyqy
pwbSn! pIS#Fq+1!h@bLtyC:>BZcQuC/9^4*HDEe:6nyqQ$QD#C#A%J@D9FnWMMubLu9AbPa$*8ZDPRpGqL@I#!
yC?h@l 9NkujXY:<VN%W/:uV?Hcb+1+Kj%@w1*#QNNqnklKNi:Vp/p18G5\P%je\M@1WF@XNNp$I9^LT&/J^!uV
h/WJ9K >&aH#a5l?#I::*Si%\#DbIWdibhtlp*>&YeYD8P@/IR\/=AlhX+LSkR+=j:Me?V?PDqISjb!Xi@Rq&L8
8jlDl$ BZWdRahX4+XV5R!Tu>55*t16C5iJid?Q@5ETb#u#>EiE^YE?B*tZ\hQ$bQX#n5jXM^W%GFMq&HLWl/pb
8npLK9 uyySDnJHpcpYG#9V>=DH<iV4%p$idB^qEyJ*Ppp^yV>TMQ8Yhw#t6XhLZPJCq\cX%k/1$4bHLy&Ta1ZW
1u@G^j LmQV6%^d<yPK<:8Sd>/p&J*!nB8<V&be%/L9GeiX@CH5T%#pq@=a#P5yGR4=:4l4D=qlI+9>J:QVBR*Z
ua4QE% SHWu/ShCFwWHFj6%n*dG$qLWMNLQV^i/!&ypBN@M%Z>W=L?kn?k^4nDpG>hww/J%8KtZcu8L:ZpeSm9V
+Hekq+ ?TIFFncuQBl4XTc<=uVyb=yWWjmq:tpQpjyR^y?q11$GhM4l15kqSbX<41^tcj%\TiTd\V1nXG1!^bI<
-ASCcd 0005ce2870600110333 Page 443 of binaries1.zip
^ZLm1a &=X*mVMDc5\#9RQ91*XcX4RNJijLHq^y=nGQb#\Xi*SlmjMHZJMG+JW=/Z1a<8KNDk?&Z5%LDu!Km9Ml
1hYkNq S4hM1QTS6PW1Fay/y:mMD<k1=5+MZ<1*it9#mWZjuc=8PHjYbGh&WQtiQc:pLNT=u!X<yX@Dhe6@^ly%
N%peC% 5GwNP+V/\dy^c^XQM!Ip9?kCMGh!RaC^PWH%De9#?wY^&#*$*##CI%pcNV$/LbR%H!+4j1>\YQ6R?eQ>
h#RZLL >tLbtLDKqIK?=*9hwQeX<Qh#*4y>4E5ceT?M^C\V9I@QN4^$lKq/<wcwCeAwB/<N<y4$b4=<aFmT1>&1
+BZb<m 1LlDpA&yp:@1*GClVjZER%ht\jc#M+6kQCW>4W%cDy*eDk$1TdY>HjS1utuC?^X+k<q?c945E$:bb>9E
wR^4Q< 1Nm$HNq6K5VCF?X6\1jIuQ>N!nCc##%QqK4!lq6B?yWhHBE!cG*Z@N#Vi#$+D4S=/%c<B4T>#NYn1N*&
H&PAuP MB1F&I9hRVaQ?4jc+cqcXJdmJcqSYX$$H$/>PYiW?K=<JGR^&^q=Zd4n@D&>H?SLhX:GlwPudG+c8*d*
?nwNWp \#?Zb*!i6nHZqbFhnki8iF*k<$A\&#PE#t8J4E1aHQ#c?p:5:byu/E>#%XuQMQyn:w#*diejG$aIPHEd
@*Zy=> qCcij4MmNjAIZnXYhWyqL*X8B9&$1PRE$J!M#b9HB<u6?tCSWH=C8Dn:F%AnZZ:KT8kHdZAjT4%bI1#>
C^BG#1 DkQqHtHMZTGdI$K>@8#FG1HHEW6qty/w8WlH*:J1$ZpFRZipZIYqRQdZ@N!d>D%*SLWp^ae%n$/YcJ6<
L+>qRN V#IKWDCqWFS54^Ma%JPCK/6K8*9!84ed/NFYY*5q4AclHG!tLl@<wj#S>tERVdya9IGi5H#MRZ59DaTw
yScltS ySmqXXHCZX*HY??Hi@XdBl&H&iVkbQ4Da*1ikmw%+tV6pW1C:=V/F=TbLGntBK?$1ZFIQ64S#cF6l\P8
S+m1e= Gw=/Ki$6X=e#VqFAyFMZ^T/h=Y/H6:%@$EZH>McKnW<Pjm1p@GWFVS/cDTik4C9i=#k?@IZT=JTA66eD
+/!apA b9=Db&d6PFnM&V#uP56+Y<eXFV6SeBbct5HPXm^K=@dKY/pnb%yNL#YNWu8i4^4mMHqtXqPMhlhT:A9@
bkJ>NW *lPW>I:PDNWk4PlJM?&t<E=e6>KQ5Vk:@KVC$Vd8i\L!>$L*K^i>pkqQCJ&1Llp=1NSX:pH&#Ic>YYpq
EG!E5L pe>t?TLGWNlWA1:jwRLLX&^bTb5KD+k?kEZVZ^C:dpVhjh/&m4i/%Z\kBGHXI=Q@RCqZjYZwl9Tuc^Yq
jI9Y\I Zlp$Mn8<n=uF>ykN*=4WHLW<=GqHBd61%uk%Y:jw<Y:1!#\KPw+I1>+QNG^/PckQl8/#$WWjuEK5hhlQ
+6j@Yd %?n\wH/^qQ\!<>TBh&G6PV@8=K^?cuj9tFjD+>iNn%cDuW6CGTQeHWYnB\+BL4M\SPj\4Ec=6Wlm=&*J
Xk9KtN M@T5@nQN@LVjdMZ/#8\Tw1J/e>hq=5TDRcNb?T^#uM1IQFMj/>PXE5Ei*<hDqHKGcY:XmC8hb>#N9b+5
JTim9u Y#4b*bM$deCED?mm#*ppeTG5uy*<KI9<eIdjR>b%h4h4V%\mBe&ayIKe?RY#B<+G!li6jD15tMVhR^<e
nSSQJ> R#Zk4*#DGT%cJ9Y/MD#>pHj5au=8HZPBM+iKj8Z1lZqidVaX>JVQKa=X5ittl+NH:He>bnl$:&lQ6!HK
\m$YEZ !CQS*Lw6l*EqmpuNRq?w$cq<@EV=%B*5D@VBi@E=>/qynW/\Q*FM8GT&?CSpSeE\iXkPy8q:t#ZtTbBD
nm6+$4 ME6R=QK55Gk\a=HnFVuQh<FH$KHHPZXZA$=NuqdS*iWVc6/M<W%/qHhB?*NEaD!ZHd99/+>6GJWyA?Z*
R:aK*j Ea@Nhy$YS?+AAwc@!*5XCX\4Ga$>\LDVYc&66+cPdCww&Q\&#LA:*F=1WXHNpu6!pJF99C\ii@A>/y^/
8LACAG 1WVI8^Cp1tQLkPa\5@:!Q1cCpLBQp:ajVM/HF8Y9:aB:=b\\@WGNahTYc4&\$\q:/y^>bLdYy/cq=Eu4
In5qSF A6@*VaiK^?eHBFAiM*W#d$bWjYyai<1>y%TPjJE=kTtP%D9y8D6a*mj1\mGj\Mudkw>*IYw=j=+YG^aR
t4Lny= V4LuV!y8L*:e/!FFn/R#MNY1mVA^n^dY5/6>GMNWCu85K=P9/NY9qPJd=j9J6b?P=wt:mX>TS&1$^pY4
$&qTh^ cXwWE=NkFXqHDl&%RL1=C/#%H=*Z8QMqDI/?PVGT*yld>JZt6Bpul+h&#\QKiyiM:>^\!R11=Y=AlXk*
jH*H:l pB5@+p+NNX^?A6CYKYSP*dTqBYl!*!hZ/Ew19=c$#R>IY1&5M<@Gn<k:iu&#<HE@dJjDiWiu+JQXuLXj
mky$4I leVBA&?KK:JDJtXMauV$le9w&BlZ*k^IMF\1!6$4IP%TwC6>8i/Gte?=/$c$Me19^WZ*Sc=W1cIhu>bw
wpQ$aY ZGFudWu6mjbhmC/WjDPel:HSe8Q?GNQZB>R+n1Ec#n9R!!B@WZe8M@5j$&Aae?W?q9p$@qbh+nPM/jWu
PbRP/S >!P=l!$E!4%6K6M^YadSpZHB%liKyuM?lqttqLnS%Luq!Ah>LV<uweW?ZS9mmbNl6L1eHH^<>W9X%GEb
aZDMMj #mP%ubeVl&8\y>>j6eBJ+6!CQA=tPunn&:L%XdphC&T#8==:45A<##tbVFhc^*HiVd#w#5bb$qAa*5IY
MMVVYe 58LkGhAYwq=hHmqiAy>L>%\%9$N>:6qA1MYRRj&IiYt*PQb8B1+CcHPIi>$9wSw4lM@Elha<4Q^%NZ#a
qP++^a @GV!1dj$wmiLSKe@JI!uQCTL%t^/15YtX&eLm<@?Ztt=R?ERb^qGQZt<q\q4e!he*\W%ptYi@!+198be
GX%$$4 X1=a\+p\WY?MbmyN!h&DJW#6<b+m+9+FDeun!/=l<<=aJ!Fq*>YtSjHY\t9?@>TyJw=JHBiPNc?8j@8k
N!?:Tu L!uD?A^<^^i@YK@y6J86+cpi>kA6R9miW<uhHw=$+@yHnyRNc9h$4bd%eQZHnadpKH#n+*=p<%VD1i/c
eu*:C! 9qcQ9$4dDXiZ9ST+m<E<65u4m$4T6Lmh^/XQ@n!niV1W9X\Sh\^b*#t6yet?9!#RYM8p/4<1+m1k$Da?
Z6>GQd =BZ\5j&#$SGMQFQAZH8E4$&p=wpu8i=aWj@P:lB#dYe=uRmbSZEX8nGpeKn$AP8iH/!&uVJ!KYHa1Pwq
5>F>$J F%/81WQydDmKMW#RatInu^!QwL!NRqPlJn\+4%uZPYE<4ZqMEaiQmyHX61^LQtV599d6^I8b849l?1YZ
iD*:9a KySmp+b#S=lt&\>hN$l%<P=@eekyXD51aCw$XNXFpB8ktk@PjH&m+Ma^uduZQ+Z#SGSk%Q8b$*PmGt@G
%6:^+y uFPy8u5Dk!=MQLk*1ueQqu8!jIT&*m<hWQP8GPY/Db\jt46SM#:cT%PcVKjePC1eL4@#$VHD#MP4m$I=
ST$/W^ jdFb6FLTPSmhK4bXtb%GA#!$N/854@!aL6k98:1ph?:FH98>=W%nn*dbBcjKAhQ%c<C>\BthF&%qmuj4
Y%9ZRG :<=<p%!T9#y^hDul?=i?uylPI:*cJWa4h+u?F#uXVGh*KDA>!LC*>Hlqqc%p9*#V/EN4EhhKk>DRaVe^
G*WWR@ c#/LCAdnSn1F+M#?eJj*:bhaGWN=P/4yZRXq?BYpw?E?h*%EVNlqXjJW<u8cw&HLVcIC>/>u9d*#W@VL
:&I/8m tIY8RC6&KIiHyj:!&PYPd>Qy\*+b1VJQ9?1mB%Wc!M4M<KbWV%N*^DGK5cpy%DHVqt1^:j8t$KVj/Qti
N41#+< P@*=u8PMj8YiGY?eGJlt&l=<QPh%M4m<#>EyidGFlwKMV+#4aYbYCN%:clkh>REXW=muJA<VFc894LwR
>6u#R> *?/aNy8JSENdLFhWYL?AM?hBQ1=\buW@^Vw4aLhmbpD&$$\dAQcwqbJj!/6AP!l&9$y+KY<+Lwj^ujK:
l8Jb>H 8CAXAi:wN+PS54!YWq!/+?=b6wm>4BF1B+D\#G=QSIJSEWK:lQ8!iMuDjNnZGVF*kF9F?9MP9Y=L%iyD
m89TWP LSVQE#94XIPm%NuJA$bPW/iq/Ycu\@5NZdwMtL=WBGT?<d9Sd*W:1?C=ihk8^4bkupAVD1>4e%N%A\FN
&t4?uC BcalQcG$?JeuXaG?>N+Ww>8ujG+pic4^YC8%tQnD>uw&<?J9bmQ:#?CjbdtiVHihmR/q%j6EEWKjP=Au
*ta6qA Z$E&1C#JdWpVQ=B@#<D>#5QQl5WWZ/9EJ1kw%kSa51Y=m!>*G6ejiGDC%XAeWiT@8!!!<le69M9Rbp<a
8VqaDu ?S*/=nBhHe=SaD=/H%8i&=^9y*SJe<8DB8j!W=MlqP^FC+!TBc+Lh=qEnk:XmHLbM/9ySdp\1!=y5*bR
6pyC<c M#ejlVGiHt*HN84HKTKp?b6VaX$u$@N&w6l<HYHMdHPh%^5Yw>6:G!@D#u<TKYej+/al4#1WEKdu1eYl
S%khhu =Gq/4XFlnk%SYiLtT:A*5bDXQTJN8h?DH^aNL8#IlXh?#!qulmu^1WiIY=ZTKHWd$ApBJ6+hwSK&hd6^
#qG1M4 4qH\X>JGR^a\^9um^hA8@nV=iWF$5jml&l4V&>IwN^*habPE@c1Bt9Niy1u=p\LmZLZhnht\85p4SV\h
+a/Pw+ 9TYhZahna*^:u*<<y+W4NEq@p$>V5C#Chau<4uV6@blT56DBD$#$$aZJ%!j<JIdQT%+>EPeX9$P4iPkm
k&wV*5 nGaER%imk4*tZ6m<aPnae1SwYQjPeGEQYXyE6td1@wdKy$yPPBM%&!/N!?\hB<5H^:\+H!Y>ND9a!/pc
SLEDc9 <4mt>EL/5?Ga/p>^/5c48+Z9GAZaLDB?=8cWbqy8#y/5d>=dc%X*<H9*bG\kbWMZpyI=Aeb$:eLk1mn:
*%NVD+ qXq8ijMA^@B:u$6?ed\Ty?P+WQBB<LRK8n&GI*AIqtlE%:LtLH:udy@4CLj?m1Nbud^BG*?\c4Tu!I><
!?*^^K 8y?S4I+m6lPN&T9I^jCG5dBj%Fdy9HIlbiTXu?@p+cI+W#T=5pWiH@FEC#**:H^lINTRK8%Zih4j>Wd9
NhE^YI 4AHDI=E=^y<%:p+NQ!4j!E!w6<*Q*%Hk1DqtcTN:%cQ515cDq=&*==VeaPm%TQqGu&cb/t@ZBVy9t&dD
+\?L&W 8MP1/!LF?A4wNt6>k5j?Q&%>k5j?h/%Q$AAG@?@YJ&kAk>6P/^M$jKM6CiEB9@GABpkQTNIDq9SAp5GR
BeAMi1 bDC@bbkIV&nTj=GpMTSyLPtH5CRbLEpGT=LBAcRj\yGpeTRlHEpIV*w6umTDJ@$mumTM*^kWNADjpAdk
\5ybpw TNIDt9TAJV%5@DRApIRBpnCAJ9$RRJIGTNIIpnTCJI$k@VTCJI\kCTNJj^1AJEpnThJIpnTTJI$m@VTK
R>Z5VA JI\mCbNTj+RupnVya\Gpn\YkThKp4\cR9lyA?t4A@*\%aPP4pV1P@E?&<D@!pQ>b5aZHRtYS^t>!B*$V
%!EATW dSAtTQ\tdPtdcIM\T8E*8Wc?mVaTVB5BSS5BW9t$!W*\VdRBpKV%Jt#y@/tNB8plkh@pM9et&nmRcybN
C<Si\@ &NI*$Rc::LQJji^N6NFka\:F%6Aw5L<dm1&lpTDI<XB5DR&AbP9^WG\NDRebe#\WY$QlRGw1<XB5DRX&
dkSAPA A\RQ^hbRKDB6KLcGRwAll&J4KBC&hD\im1&lRHmK<Hkw6papb>qeG+16Ee9ZN>FG\?FRdA&JkaNwR:E%
>4Hw!e =Pbe/\S6KLaG\mJN$Ibmc$k+tDaWY$N5d8eEdTm&l6meLb&kDeZYRHmkChyRdA&EB=1kDeZYmH\nt&6D
e*1i1k 5VXm*h&t&kAWY$N5ZuyM$Ibmc\AiB/IN^haAHByEG+16ET@Jd//N?8@>FwI&?4@*Y\nctQ@id!FwR:E%
ZPCWCS pP+ZBG%I@lwKdNRk?Y5IpBtKkPT9ATA#FAFyD<YDIEekIQp6aMml&BwcA&I6CEn?Gl4EYlCR@DWp&KlB
-AA^:K 0008b00fa4e00110333 Page 444 of binaries1.zip
F8RB:P <6eRIP5cAyK@BwC5c\kw6kdT/+!knajp>aB<d!RWY$NlRNbWJBSdI^c4d1+N!X>DkZ^9JCS@DRG!PmAl
%Et*HS ?Y5A!QhGR9LZ+CDjG+tB=DPBnVpYp5<EN8cR@DWM&JlD<6hRIGPPk8T9IWH5HAZJZ$PA&DpKp4<GB%uZ
bcHQmY WFB5DRG&C/Kk?Y5ka+/C=K?B:aIwTQ+c&C/IktJ4aD$pNtJn@!?1^nimecA*iLb^uaVI@LyPP$H\?CG^
>?M\\4 N/DlcCl&nkXdHj=%!i*jN*m&Ra6J<Al@6:>ARKN9IL\dW4RGdGZ/%!&*@:/uAbF/:*j@C\R$@kdC8!H=
G8JcWb 1YC4Il1Tu\y&FpSn@pkd8@W6XPn$iWVGC!IXKtHW$DkWyFHD@atumh=5nmHZkSQ<=&$aK8HkR&^L6k+e
hqpVP* BRp+BqKaCi\Rm\G&Ak/hZBqB&MuSmN>&T9\DwABH@ItHnEF8BS\/Z^SlATVtDu+DB@CRkQ?Se@/9m&4@
?AQdn% aiVAhkleWXn<PuJmR#kw!Q@I6ehk6&TQ&AayG9F&P@AdPAaJCjkjuR5\?C%8>/H^$DhAkp8FR9:iAFEw
Thc:eE TB5kF6KlAki!AYKlHTyA9leY<Wjc!K%IGKBVJ!HklAEnWn$TcZ8lpJ!k+XlIJ^I\@^cL*kw+hJIV+y%L
pE?G+B =Dy*H\I!eM\jAj>LjedYtb*S9>hmInW%FPCR#pJkZn$Y@=eI&RmPQ@Ha5k+eCYu*\$ELjIQ5jnnkL:GZ
@X4$NZ a=D4J/b%+AlIT#GpdCATdHLmpF5CS&&Lk^Z@i$YDSChAiDWK$5EZbEYDqEyEkkWdIKWT\dY^Y@F+E*a*
9+Xq^W !G$NmMT%9^eGawRi!1BBm6iDScb\?C&+MatVB4Kbd4CtE+FDIYhB\!EqMSEapGABH6mKN^C>4jMdpR>k
wn%@F4 HVkC$5IAKRMK\ki\WSV!N%k9AAIPIu56ay*SANLKACq@TtS<*l\=?m?^ZlDSEyG9n#qE=Jk@R4:%/Y<d
SZ?NMt jRAJSp5p:CMmJ^/wwCCHqp<DYhV\?L>D%pmeu$Vm*ZZkPCllCkAPLSt*?aEdkAN@c<kJ8\L^JLYPHI8A
9bw6S* lB#TBAXJ@AL\Ld*VddkelKqMLIbcB+:GR\KPkyVBBECAw:jwGWuMJpE&e5L$JQlI^JbnAAwDCVkGW9wV
?YYLF@ B\Ie8%WEE+HiVpTLCH^>^CEC^@$SeQ\YdDyI/J5RE46NDqk$ACqXDlbEBIC6hp<MjB5^a@n&PGAJ4$d<
b4eu%6 RR\SAJBdnDkKP4EuMVm\LR=a\15lBV>BpnwAkN:1BIcFDl!%VR=a\18lSW=BdB#a<8kI*dXF4Zik*RaH
1I8u!4 LPHXpAKuIKp5AACjuEnCYS$//!=l11E*KQVRYEmtA4G&AMSWEF8/666knCJGjNGwDWbTTKaC4VAByIRG
aPjJ&/ RCD@$uJIYLdRKGCDpSTT1WC4ckCy*kERt$%P*AbBM:G8CDJ=:Rbw+n<EyHWeYppEGtRh@:@$n+jP4Wup
WMGq^# %MS6eG9m5bCAR/y@Bct?ASD+9$MVTTT9SYF@$:tlIKXnACT$+6uNn&<AEkA*FeLmD=%6phlGD@X:elJ:
>HWBkK WEABD1*!FtS!IyFdEil6k:KR<Eymti5/eARPEuBIRXiREqIAmj=dQHTInXEu6w/ENDpl%bCkRHKPABL:
jXR/AS >*nwmMDZS^\meN\jAej@4a1C*?H6hiB\TN+lyPwXFEnFL+Dc+6AJZ&?lB6ZImh$LmV$nMSB:SlLiDYq&
4i?td: AmD4IR1=NZL<hywdEQ?65:lCSI:/I?Vw4bBnEh9ku$Y8=^S?W^XDY5wl%h&A6L9e8KkEnu\:E^T>dnH4
a^%naS !KH$8!T<G%yYBAtCHL<qe8m=>ZX/cPRG=!?p6CMA1i+GyG@p^p$\<LARHL?hI#PSZuphPSLTwkmy:kaJ
=YMWpD WwWJwLiewh9weIAmqkRA<A&CcEm4I1T/G!SIBTmA*u1G+1HQWMJ<R?A*!MVlpE=CpKy&pCDXy<BYXV5A
K48iFZ BkqAQ*\TSBEd=LpIQCS9C%LXDlKp<lXAd#qDMhA4Gwn*pSBaaIMlG6JbCFLbDlIAPR6lkL>W$$ipt$h5
1p4@G^ BLWR$IJcpPy&EGBBLe\YM^VAA/l66K8B@/:#AmC&n$RDpAy*EGBS4c$Lh:AAjD6BF5SGYA5BLc!FkZdZ
&F6+9h CGTG@y?FP+d@Y*iD?Si?GjQ9d::kDibjFQCj#L<dF<V@^j!LSlB??@<H=6?*A9WMabSc4R<e<Qe+tKwn
dbFEaM #Rc9G:I1bXE<%*^kld:NNWFhwTR+bk8LWn>J4ySwnIH^Wl<a#BJnXc8m!E^1NBTV&l$Vi^4y6&Cq6C@8
+\hEXD 6aQ*uES/NLJt%H1Z$*X*ybd+/EuKe>it>E#4^\8=uQX$>k^$WFRpF%$wj*<F^1Et5LMke$y$PWXjPV:J
##d4kb 9R/^Su@twy6my1LG$nV#jj:\#MF8G4e=Ye+eyVSF498Bm1:e%T:m=>9=>NtQ^puFI8DyIW#?4u6wCl++
&LDyCq ^$54tuB#qT4uXHa!=b^:!pQNMpc*t=4!VF5@e:#q>?/\yilVMMd*ZA:jtJ6>u!+>puy/pw8y=INN4?!C
/RSVtZ kG:lVhee>*kc@ma>y8am$@$QY*Tn<5Xp^p*tabHB^lL$$uENZ<VC56\hE:9kZ=>J+n1nh8&<\$J&pww/
XFZTA$ K@Emn%Lq8il<hBHh$h&1$TF$8^V=G@j9%=@46&b4tXB5/l:a/aTIwcdMNbN@NPpCeBy@uQ51#aRc@RwM
!\tYHu i>ZAj:c:H:A&w/d5wRnS>p#MEd6y?GCh?bij6VAi5SQw4yIFGQVammaWBJIw>Gh/w*LuF\#aQ5A/NXhc
%B=iwD L8+?6D\Zw@^W$6C1j5A/Xe6/eCjd!4Kq@w5?88/Dtc>&c:+9d&K%jKk!5qyX5taE8^8@N6PHImidDnuS
qVd*jH h^Iuk=VTy@4W<dkqi>Je!mWaV@M\Xbj:5HhynGR*y>\Z&!b9m*hwKlau>*5uC?FPn6KPhtZPd:#jQqTk
&jjA=h *pWnSm*BaL1@X4A+K5yJ5K5SqSnG:P5b<#Sc4F/qk5pqen/W\15D/WCB+456<e\8ljG$NbqnZKE8W:FH
+<AW$< \@CX\QR&6Mmb\CEZT4pdaTd8#wHH?GN+dl<4edDc<^LkjiX@L>D=MI/^^8/ncYMPGt8^9QP^H1>eAnXt
=5L>Jt h?lPM@#lq5Rl9NEJPI@%ShPh\@<aN>dAVkSMj?wFSMIPL/@E$=Rj4eF*LjbE\b>^V:Xi:hqdM84kk*S?
&j!VG> c&QSY$#Hyducd!R*6q8Nhq4GR5S>N:/V+ld*k?ilw*:Kel@4YV&+l>C>mljwbtT1yK:L*=#Ie8yED:tJ
m/4!Zq KQINiRV**nARPZQS@8wl+bGywtP?%84q=AGb/qNZDN*y*WV9*8M+!=*#<y!iyd4Swj&6<9hW9BlPTLVD
<!>SiD qB=L@#K1@<HW@8qGay^4#9HqT$cT=NNqNP1NmWw9betb>w9t$nt\!MmchEaE\J6Hjq!8q9ZR48?X?wl:
mV>LYp MS=XKSu=qt*u/1qukcp8==tZEtSt9K/q!BBMM@wi:&BC?k*K#1mI^@N:jVy>Kb5K9eV!Pc?4$S@hlWNJ
ymbBqE SW1wWq=>StQT8inQyNTmREWZ^cGX4q++D/MJlV6Rc41imN@S$@=EKGCkua<?1\:XJQ\$qq!bVQ/luq=:
yYSPpa V65@btI/IVN5BuptM@PHG$&<A:w9b=:1ZnA=+&b4=JjRSuP:M1/+SYZH%%$eKi:Di+/WmPt$**%ayWIl
5GeYj\ GDVlQ<5lq$Bd=:=u:l@/YG1jc^^mi%p55^mBDm/y+G>+uuJA+$PqTBhdCkh:^Hp^/kNnddX=ZKewVl<y
!&!X!N ua@D&Ca>6/@C^BSyK/cw1FFi@uA/Np:>hHhN=!WG+/n#bM?YiMuGAuwwQ:k^#hIZ6Q&kEh^=&XKjY!yF
Kw@/<C MjQmZq>DJL6cX+djMD*qaV+dyq/YqAhQ>^+:K/Zw<JNPeC%Q=pYPuqFwh^p&+bhe!y::6wM@E49b4uY^
&F:\bI PL1I6<R5%BbSI4JKA9&h#5=yuE=Y/M#V!Ndmtiq=qDqljn+p?$EiV&/tEZ?iIS@n4j4/Z4l^FB9*RT4!
!aphT+ pG:6DlZSX!XFnNWN6Li+lF=PSP<KT>k^W$8@=n9&>pJ<jH89kNC$nPnKItb&un6@$QhREwht<tYK</dQ
pB\wJ6 X5Ja?QeXJAXMtb&>>WX5kL<\EhWc*!C+=u#pme851dC&KmQ>9njqYMu85X!@h$dMy9ZXblKJ56IbXRcB
y6MAuW &5LJR4bIm+1Va5P#@1Witite+aMYMylGP68$ubY*Qh>YGaucwa8RQ4u55>aPVnQc$@!J@e@$ncS4!wDd
bR8**P KtbliT1?N1X^%#NEjjA</c@Z%Fu*1%9hBNVH<!KPid@XP4HtPNFHnR=b8cel@E\?*\d@^kNS<QpGn!wh
!d%@WA beBbS1X!XN$pnw:!5B$L/qQWWd!61<Fyh@Q^IA5Pd!ZQb\h!C=NHCpV^*!/duEEhNV?Ynk=\bBT#W/n!
p?>p6P uYA:\BN@?j&Eq?E6\m^l*^9G?Y#XbFAP1Qwi91TW=8iQ*!@?N5u%#8\R<9bb*>b1+<##@LE?JiX&&6bZ
HJ&IVW EA+<NwlWpYpq1#WB/=tF!DS*i\cJ$Jh*YcmFR<qX8Cd^&liKA>?c+aR/qBcp%G?/ak1+Zti^mXS1qcl$
&&/eWm F\IZ^9886Zjy?upI?Gi<5=mqYSEd9Nn4<&p?Me=>nihAdja%\$j&a$$*i!lbBjN>YG?<8B4+ke98F8%u
6N6jBY dmW^9I*D#^acJ1YQVyE/8pAeu<inV\c%<Bjp*wj6tNpp!Y:^=HGRQ#T*&J$9wZQVQ*tbw!j/#A=$u6ZS
&H>9^R E>m5$J:uL>61Rml9LV>tHtX*4DIYt5n#aE+NQYj8W%#8@FL4K*tRK:5bPpwubWH=95QVJaF?by4HXeGD
q+#8b* ew*<!41Xb+@kn9G=c\c:9tN5+lFt:w<d#:EVwPNkWbGE6^$%:qFVq4W?@yyZ=>\494H&q5=dF\4E\pb#
nwAJPq =+:4n*y@FLC9X$w<NlKt/<b>66EqeViq4cVii/P\8^W%:/kbZn?=6Z44XZLeW<Twa645jat\Kl!Pbk@h
N@!HIG c\MS>@n&chcWX8%jq@ieKS$%X#&#l@PL?CH4T%HV#J*nVhH^:ja#@C4*kZ%p>JTBp\p9Ybe!V5m\TdQk
khQ?eW Blj>/89/GMJGW&@Z1Wc?b68jajcnR4D?1M>=4<Y*\!jF^$h$c%<eP=1e>4Z4MC*bcJJe^GF%yV9BT<?q
NdjFB! NLkY>6DC=*nN&6tXh!ei9t#Iu^/+#@9A5&muBcDBXCZ6S%K\TPtnA/@8XV>9nNuF@PE<*W?b&W>&::la
L&yH8S Wk&#9a/&>kj%XH/N8Qb%S98m9j1JMtZFpI9MlnDZT<dj:huC<#Acp@BXP/?/$w5Fy!^pL*q@nnn@Tn@#
*=RcWK Zt?8JIPFEY&m/w/EL<#$l?iMj<*!9JyM@G4j=1/QG!*1VT:Ala@dq8dQj4MjC&V19mnR?b%/ta4&/H^=
!mVy4t TPAMy#\h6$ta!LBW@:B6khV?m*L=!!4SAaYG/8>t4%P%nMCbNSnW<ph/Dd<I4mnS?Q+9+5+>45d5??PN
EqDjAc m1IdpVBt?qbVmJ^u:?e=q$y#yu5W*WX81Tm/um+ch^KmyI6GVW\w6$Sm^DDD1EcyTepq6>GZTkdnqlnC
%yZ@Fq 4?jW+@j/ndQQd=&9Z4@jj?iQ<>R/#%=::<@ic/**tq?*V#pm6LL8:wB=Nn@X6t?iiFS%p@Z6mFZKV@wa
CmYcKy Shceny#i6c^9e\8p=wd/1li94nFX1w9MD#J84X951dN!*bMe#?L%p51T/H/#@P%=DmwLHHTYPy1&=lcb
MS4?Sb h=duZZLb$@@S$65:ihZch?+Z@@L!TdqBRK:d$^qX9LwHP4Ne:D4/Stqb8mawdhI@ZbW4eZhTNSItuiN6
m\#J=@ Eh<idKLl9!bIiewCk+k4J1&h9tNTXX!u9\69jdi@cMTaA?<nCwjt8aW<Zc%c*Ij9%uhZ@adDKepw<b%n
-ALXV> 000cb990f0f00110333 Page 445 of binaries1.zip
CekP\= e&bM%J>#RqZT$l=@Ei#S8hH<X8&G1ZMqSwc6+pPL>KmjtnXj?+/@Nj^*>/ES4^/+4^mJ>M*h%+&5Db#=
@5J$m& SMh@u8y\6ethp\\e:b<Q$Sy#9FC<&Kl!i&4V@ZSh:dRFXwt4N###cK:9Y^*8<eDy!ElDq+j=SZ*4p>i&
yh#Jy1 *d#S%Qy%^C>jW#qJ4TycE16j?%pP<:B:1nF:&KD9l$p?G?K$6>@+TIM=<<=N#6y+cIqi%M@c?W+llu#n
5dWAP> A:G1G+6W#^<X%?\!GPhp/9#>&D1ddN=jF9eK6F*YjXY#Ic8p&m!<!PS\jK&^jtFS@A@*V9S4K^=9e<yP
#d<APB c@mNFMMChj%HNRcH%W9!hdT!##VdX+1Zn^*$yn^e>XDX1MN:*+/Nj&%eN:XXwFZ!<>lBR?lh1^mhC=<u
L8Ap+6 =@niY&l1I#c1MX=dF?:lJptknK$1R4G6YLM+K:\8Rj&y9i/wAiwdPn#u6jyR:&KjVy^h1jNG*Qc5YG@K
GbW!j< *qXnmk8HBKSHnM/bN?+>+*DI:Jtj!t:j9wtZ*P+I+&y8<AabLqT@4K?4>8?^j%J=E6Qua^w*%ji#*Stq
+Rp+Q\ *FG<4>d^wq*$t5XyK<WTq+9L<=h461*@Pp@<1MwdKdudPL55Z@tHp=icwWQ@w4bt^=auJcQF>w=6q\dk
#Cc%eL MiW:jj6@abS\@Zd#JD*i#%bQ!maaY@N4#diuJ1h5d9m<6u1p!ac?FTdGul&9%/tWTqcI?:&Lcy9/#jlB
MCQGqc ^XS/dI9hIYe>B\&L=S6+L9Qm%aLt^8%/?>p8<Stu#hG%T:FJc:q^6DL9>9C>:ia1@EmJ%9*MAP*wPqi%
h$QENp hmP6y$+c5aaD#%@FdR5*Bm<^QGmd55K$Y4>/9\&QXnwVp==I8cT6YS\i5>W/iBM>iKS#*niDVaZQD4hb
jEbt#: :#N^dN46W=e:Iep/>6AE#\KL*DF@huk%$G9FynbHNJIi1HnhHW?*&9aX?^w86@%^SylHk<+t:!uFD@?8
:V4MJu ucVp4i/$9+//X&iq>MB=:FDu?W%y14#w#N*yNdPu4X@1&H/1ZiQ>/D&#JkV/44H#u*mZ=@lum%@M#njB
mKYp5* YywbPc1H@Q^mT!yT/tlX<*L9M%>ZY8eiVLJZqw#SdN:8i6e<y8q!bw6DaN%Mn<4RByj*up$u6d^=Mb&%
juKeVb Kb?d&:W+lR@QP^k@^&/G%hFTP*Z#VPW4n1M>ePcbhA*jnLLPDQZb*yEH#1&WGLY%l=/Lu1M:%YHT=QG4
TukKi* n!X*?I>6j<GQYl4/dNSQnmh<C@=w4MwYNQ%%y8!NeLVZin4jwh^:S1cF$+YBu6GPRTHBAjMnW!jb?9mw
$@D/Vu ?tTy&cwHG!u=L#S44@KK=VE4SlycS+bi9GAY=bSw*Jy<cy94L^i>4>upmhX1dGia4?+j@n41ZGN5*@n?
lPy:by j#:G>&i<1Nc+*nG1Qtud6DD#hPR<:uiZTj#4a\aFjBW>%TjTiiFjTn>5>JNeDJq/NK:Rb5JI$%VDK#ed
#=cViu +=1wlyFV+l+k=hj>qeV1Rc>^*R+ljX^q1N1>IA@Hylh?5c*&!ddKR\ihFinXnQ86tG4#!k>8#+?\$@=%
6q^5@Z $Vm#TP@D*!b$=w:db:t=!Vn$+cuj/pjE?C<5Fe\4Qi=c/EhFujPQm=?jF^LtFJl/JVE&#iABuicT<Na=
=npMJB :J4jqu@bF6WqFTyyqB=aFVF+\4wym<NjY<ZtVTubt:dq8YYBJNZlYhcb+EXPyR8Vq5^LtbX1E:QlqWtK
bcXHe> b=DJZ^wua%ju4F+Yq9!5hcnQ9<6Kqtc5CK>+Hne^&nQ1pwQST^TtP@Ca&jL\8mmq1mDN89a%Et*ieEi?
1m/$:* T=4^ZI*&4cPMPnY#*FiXHnPL$*cNQnik6EJncKXb$P4F\wIJL?*D6I//%%?$8hP^$@S$w6d\?9*P@VLN
=?>:VC pM1e@p1#%A6+Xuuy:iIe6h&188hu4btmpcpT/KBy+j%db:FS6c9K>1iqt!Lh:@1qbBkdZSc9NjC^C!</
AKA%YV /6L=56R5^5h+$=aNY<jQYXSqFu^kd@L?d^hhZ1Md+6@w$FIZpy#P8#F%?nHN$%FZHp8G:m$LPH>#%<MT
nF&n%# >#HS*&ZEB!&+6Yld%wLY+1FFm@LeuPIKLS58tW=ej!P8hKqI5LD^wLlC@>T%dB*jp>bjdRww8VHdJu//
tVneJR #?!N\::QjHk18&Sq&P?uQi/%?u>X^8\Y9#j<N8ha#diqDw96X#lYtq^6i#p\I#a*4npj9=@t?L#Q\bk6
%KYQj/ hpHyPy8n5?jXlFybu:9itVSMFPGE:Se5N+:?:ERj4i^XpeZjBcyT^6yqY$6@hHWMDiu\DZlitS>j1JjS
*4jHN9 pPN!Xi@X<Xe9qn/abLu>4LlSj@IFje@Q>Git:Qj=?qI/Z9h$c+6py5?XJ1%WH#R\I&ZYS5PVi!<<u=4n
iaRIPP d%J*1ea+c*bihD=&EyjjCD6l=Z1XtuL*aH%BT>n^!>8Wt!9?9n4iy*@jP$&ZcqQ>y^*!V#h?Y>?k*Y!=
pd4Amw ZPl%>6Fyq*=C4*^J^Zu@$XXG$+&@>V4#+LMjK*jHH6<!MYL61PF:ek+H#RtiWnck$CjI/uBRk6c>p6nI
#+<*pH K^FZM/jjZSca/19^uhcLS9hp$@n:&aLmJ::#hbJ5#/>IaD\deqYX>tKte6t8d@L&iYqEPi/eQ*6uianF
E>FPS/ H8G5J!tV?p$>htTHd8J#m#p68ul#?uX44?tJ>9!=Q?+>wyXN*^aYJhC4DJLn=$WHbC:i9Zn8D:9Z#+yw
AZFK1! pKT?$F:u4YPqXKqJy*8%BE<I%ubSYc/%%!/*QY88=wV$ETQ!nQ9iP4qjaGt1&1e%wH=&@1Py&T@QJbki
@MQY4/ Q%?hWhB^+j8B!@lHHl\66\y6GcKjn1l44>HK*%j&@Z^L+McIAM8p?pK#kQt@tqjd%/\/+9dGLNm$+tKA
BG*$!$ w/k=P!:iL#p9%8Lky1J+:H^k!Ru6*G9uG+6?&jtmhQ4qQeZB\=KGjdtb45kj4thjaS6=>FCF>#VZ&mhm
AyFihQ p<A@48ICXKbZYQ61/cpt9/4Q!%M#d$#<8!bty188$yFFXj*VLVeJw\aJ:$Xu&YjR>IkjnnjhD@G8&up%
?K8Q=q 5XSuy*%8l<jNA&p8?neV*=Tt/5Scc11b9y8@:4y>6uy/=mY#G&i\^Q6pSM8&=P%8n%!w1:d:lV>d8/%\
YwI^Kb QH9wb&SiQ*q++:YBw*^%=w^&VZLT1\8MwXYY%IYWjbH4iQY8SX%S@YmX:BLS=wpu#:!>iPKT:4Rm:#D:
T=hE@V plHZ$6<jFVu9Z^9u?HBHyi=D!&t*k1$&9G/M1XEiybX*/*ANe:P^*iGl:upqn>$y+<@\Sl:8<LS:NhLi
SE5Jah mB?jF?F>W@@wM694i1EB9@uhZuL8?9Zhjy5dHV8Z:<k!5L<9cR^d5*P@da41:b6d4%^e9PRZX@QhqwQL
^hPZjn bnd9tcu^>L5lbR%@y=tw9c%keN#n\e!P#SaD98\eWHVN?6X*+/@hDNLdF=#<YBK\iMjbu%15:RwQFmT/
&Wkka& LT9LVVT:iV+/1!Dpqu&\>?l1milE$P4enuPlq!$!ewbunVh8nm6!H#jT@i!NtkhbZ%ccVSCM<J/jMPJP
\i9T^> A/PY4?/X\NTZ9*a/8dA$wX1>YjJ4q8nS!c$bBtYQR1d&i*HmTd<b+1@G@ZXX\:F6\JPXb*%Gl=#jMN6:
6:!65P =1Pp^&8Tn@wN&D48bI:*=I$Y?<8cE1@h!b6&:&CkVyC!&:@/>JEB>i!Ba@=@RV$b/u@YEMKlunV%MhTV
C6uD<9 ylTDimKt?+h$jSB\H*wapIlnRKIiBtVZB+d:\H&b++w!TMB>t$N+Ik:lmVmEJ?IRupnIjbpniCIll>BE
u@y4EE HM8V?<$M+qmimGN=Iw:qmVmYJ?yliVKa^!E$Mej!^B#LE*M5V<!^QDHH<5Re!^NV*Ji=K@G8V>!*Pbau
V@w4#Q =qmitGN=aw:qmVtYJ<deq#GH$MRe!^N#LE@M5V\^^@LEHM5Ve!^QVHNjy4tZnVtYJ?bauylniYJ8HDE*
>M6m\+ nykdS<!NI?b#L^6#A+p=Am9t^lF#++m=eeVePGJ8HQEHFC9tBlIL8Y>#++m=eeVePGJ8HDE*nqn$+YX#
&lh&QI A$q#VFccG$icG$icG$icG$icG$ic+q+&Vj&DX<4FPQ+bQjt+CLhuTpK+Z>VHSdm!umaRV/mQP#:KiyyA
PhS9ty QKE?41PX>VTBiEIJGMnVBP+Z>ZEy4K!uCSW%qEAAibwm@Y+l=GqT^5uHlFpbV#Pp<j/+IFZY$+SKQ$wI
NT:M6^ <VWCK=YllBBjI:BT8=/G?B1BqeyRRwm95YRI&W>DjI$lbVeJId:GpMbdCQE%tyVqI+V+G1uAu^JCjI*t
:l:cmw E>/=CPJ4NEN+=!KI4>EElmRqk9kcVYBIWmKI4>Gp*H5S^Ne\KRFiBQE%VMyCF$F<DR6I:^#mc=mWTC/C
+MJQL$ ?Bwt4ekmmK>lRm+++pF<DXM$+YtI4:EcVjdVEF>DRn:lcam95jJW>6MRZ$PENSZ^IL=G1wlFQIm9pcyT
NkKyZ: ER@mc/VTWMTD?B1yQBQ^IL=G1yFEFMVZTQX?mIL+GpXaW^EF<VYK5KamCu?CXpRWTK<SmKPIA8p%AkwD
S6w5\I WTC>S8BSIA1p%\lRCETB>BwmnbkIyBWJI+bAiw&$MmGRZmQp\mEE$t8EjDTERH1NpBPGEEm9EiwNERLy
9DeAc= NWLSH$Ik9abII!aA1V*TmIH$twk\T^BI4\pJ5\TD>B4lNIe\TK<SVuMIk@RcRV5kDNJ4mPDutAcyQhL@
jmX?Hi B8p%$k#FIL%G$k+ayNeEyQEG/VXCTSZCIL%GKA>CNEm9pYawVaG$ItHEcIm9pRm#mAdyNhIMyWF/nVSD
^8Xtkw cbBiI=!@ER*Tc\^y^EB/nTd5BnSI4&HCdpCLRF1S5DI^QJBYJQkcA>J4BEw:apB/ncTbGA#TmkSja&mR
aFGWw# XmV+GkQ^NTJSGQ&ncPQ@Ml$h!T#=+A1D&hJpMGK9t<9L49E\yAbmRF1SyLkaPSZNQD+Fl!N%Vhb8wDCW
$bh#%V BaL+9E<^ZGdBS\<CnC@m\*qWZj?kt!eMbaEkQ8kGt/STbhb:jICGWuBP1+CS5pCpl5P<qA</VyEE55^!
8b#tQn D++YS!9A8?q/!!\LSGw+mAYC?KC#GEtd<*5Le<i8CTLWdVmQBlpPty!E^lPIL=Ju8AI\11+@^Am:jb#>
GA1Ht% ARDDBcDJTdnNSAJKu8G$AG++/n1\CcWELjaHRA^Hu*L+FYB=l5P4>6udj>b\/S5HGp=@p8H!J1hAAj/q
<B#nVa pIYZ<L5NB!H6ET!\SWDcI+He!cpI6y1YA5KqlwQIFAkWFYMIbAwppD5=Mc*IP6=NPMhA\ntClhRIlHMp
H^^/e\ qD5=FRC85d\d%LP1kAnuCBcQI^DPpXA8C$VEKE++^$DCPaIF<\mEe!Spiwhn#C/H6KnH^*pkH+hFAnHB
G^B@Vb ^?WBakWKwDQb\pmcbSt#IBMSBlpPty!pK%B=kFm?mBHCJ!iY*n>JDai6+/AaJENc^$X!JmiF+eZALGSC
\^LI#G CulkDieLRIcDL5SI%$wmLP?NI=EmbF9&%p%1PANcDpHSV=y$w!XmiwjN^+bSccy:e4KACwnljNAFJtF!
WVt>JP m8ST6ERKmC^Ki6@HGw=BhFkEm49TyDmeTCRZKpky5w=nRjibE+Qw5BkW6KWJIWA5p\::*%BB?K4C>u4w
dQX^6# Mq:/=pF\YA!K?NKE/CPYCajq<F@56kX?+$!*+XJeD<^\?yMMq+i+R+4IYwHWeKt4AA*uj=Llk6=l<:Fl
1ClM#5 KW^*c^WM\9FmWKAcE$LNYCaequMXpRKG5\ILh!?HGET%^cAwN!bE8dFePC#Dl/@n:EGbEuWdnmtR+cD4
Km?mZH jWLnY$!S!e%aRIpW/mLD/kiy+TBWKRdF%$p^ET\VD95B^+9lG%DZS5GiIqtnYh$HMS\W^EI<k8ECPX8?
!=qXm< I9*j89a1N5+kNb#QA^pPmpwR:9a^SWdehj$wukIRj6wA>S#hEPnwlpFyAal\hMPI/1Y:ijcCuP1=k$Pk
-AI5c+ 000d0b13afa00110333 Page 446 of binaries1.zip
VDZFC^ P#kMTmyAlD5+nPVyY4=IkbMELa&/5IbVwPbWGJTSkAnN1VBm=DH+GRYA<CJy\Eh18AA$P$HyDInR<lan
I\ZwVH kX#DlRy%QYC/%$JY8EAMF+Imd\S=mPS&QaCD?hlqlWXKTk%uRLMVqEnBZp4KNB^Ve65%\Bh!lt@A\u&q
^DPqCP ltPRYMG\cCXB4GD=ZTWywTJ6B1ti\^5FP4^lDI6%E6RKq4h*Cul\FGKZ:GFdpE4==KD:Yk^KACG%IMW!
/&k$9\ <dAjGm&J+H#!LlZP:=y9*R^?$N+J!l:lE#KNMSd%EuT//!*#KccH\R?=YeGk%BM?I@6tBhNW:>\i56*K
w?ayZ* ?D#W\?AHdb&k9BW?Vhk/bhNlQ#R:WwAI#=et@Wu==ELR=KVyV!mZ\VLl5Q?ln#MeZF$AW8R$LJlCWPS$
/NV?NK d$%PNu#Xk+bqRGlaDE1*aRlFI=n8^euJ>JBlGSAbFnP\?mVCe5nI&#wFQAYcB!Byu%Gy+TA\LGbk\STC
dNjA#M YGF/1YEiY?QI>HBlGSAZFnP\aAyB4DCM9PP!Ak$!lJT$caDWeBAYFnPkaAwBC+6qa&E@dQpKhD&kyW$D
hnd/&& 845ikJbDBlbMIT!HnF^h1\AWqnY+B\yLk/C\tA<LylCYR=p=R9?J1@AF$t6+1iECpFaB=Rk^QIJY+iQi
yKaSww &@Lb%n9h:SyAYwWQC/aR6Ayj41^XlNp5qF:Dh:h4AE%PWI+RVWl8\u^BL:qK%^Gj:tq$SIPTt#AwS+kt
BCLu4M JDhl8c&eBZ!iIy$>&ML#:1+HwC$jqCNEa<KYL/DpNc!n\bh\4C>!HY\\VGRJaMEW\1wmpLN#Cln+@aT$
MA5HD& qVJ:i!kWTtMVEMNlhb/EXWWk>:+YukjH@kQY<P:GAVDD?b>p8EBipmyebLHBc@dp*h$*ALRekuKEMCGd
l8p\Dp G59yA<%&*8ay$9iN9ej5dl5AP41BewSIjcC^@D:Rmy&A&JBTh>eA$KwC!lEm>aHG<96AK*aCW1^yAAdq
$#p&RQ CJGcB8D@JWhIwSPRan$D5BAYVCF5REKB*HWe*w/E+muaMkCDewSILRP\#B\l#qXECq#B5ZG*HuYIaP4\
iS%+^M 9/n:/1mw91>9SBl1cFSTkREpBGd8*D5B1LVTTIiBAyIm1RkGLTIkKYATW1KWmGCTIl$TmwY$tImh:*iA
KhkkB@ ?V*9?*&+4MPnc#*4@Y@Y+y#LunQ::9Qbb?@#?RD%CBHS$CF%$b%#KX5?ViwAtbe/AA1HXLCL=!nlpIyi
S<>&u/ /aRkQA!8SRLD5&Y4PcWDwHAI%CMEwdSME1uIZ*IXmCddQSePIdDcMqCQEISYY/a8?uKTpcYwHNF8*<<c
?I=Ta% VkA/X\H1EcLhqF4a<EX*VtRJ+bApVmQZtDWeD*K8AkQ%CEEwNCA\@m<iCNFcEYmGE+B/>tE\XkmWuu%+
M6lGNe eRFyE4!W1EIV&KCS4SGAlEhlMEwJFQIViBEBcb1QL$H*nVB4?P!KA^yP?mQD!Z@9JI5\4=lKAFJMljFk
SKFE4l lW+Km8GL=b\p<IN>YnbPtFhMJRAyy5JkVBkwZDW\kjCZEwq@\BBNTlRtWta46TCGk^W/ISVDF*$=ajB\
+jn?HD ?A<iI<^Z*WANl@@I<EY:EMBdJtp4RJm98lGA1t+\WI<RAcZ1BlQ?JSH$u:u#EpGEBTTC=wYF=mYCTHnT
?q4#T: j=eIkkpLTATS<j@k*9<jJIJG^a@jheahD?u!lT6F*ATKeqW!^eM%tT5TR&w<QAq%HL9C>K4MFIXmtVFc
y=>?C& 5le<bhZaDZI%LeTQ:&dYWA^M5B#*wq/+=?S4X^P&pX#KiLujum4w+qFby#TkMlS?NQC$dlQpu66YGMb5
*?4y9/ naP@8Xd6JwwM!>8Wihe+M5w:chkTwy<yERXnMIPK$nmP\Rm>1IM*LQEF&4Y^%KhKE!>Z!*P>TnCXbbbI
j:B:W@ luGSE5eSS9XchZWm=*PDLkE8W\YaS?%XX\qnXJd/jVcmque#&*ye+F8t?wIEQ#:tbRXt:e\Jw/KmS*qn
$l=qhb #4Nk%%ZIRE!M@1aC:Cee>bpX5eE%%*B54e?pTuuMpkTLh=c/^&Kc?e@>8QcYR?C8QweV+*TN6%db5y15
^nkX+> VFPpXpJLSYk>45&JY1jSJ5bjc@1BZbRbY?wpe5ZHTXK\9p^%p$TWl4i:mLmGi@EH#N9q:!b9bIYSFe&+
mu/4ln b5+1q#8KKCZXJSn$RLH4dt^RkYbTNlI=/!u1TG^PG%:I5D=TM:P?/@IKw4EA$+TJec&umJt%qubEBP=%
$J=%Dy <9FhF#RTuETp5A!i\4bJ!a!j#W=W*GFlq5#5QY=d98&G5/LXwZTS/w:\tII:$G6bAe#P%C6:L4w>i8dE
q?eAGe 6C^=@M$Fc:/W*+<:k&%?SYGbL::y=@9A^MMXjyCk<TnJ@LnM>w9lq&WH&hc*jJbL$%EIWLN&dN@n!JH:
Zu9MlY Y%bKpL%QS/Wb>*6V/+u9Z?+cyeM%E8W#DR1aK=h?ckyFL4?\$bn#XWWYC&iC<aG#pe6=#Di+TPkin>yP
c+l?He kq+EaSTGKT<nc*P@816bqjN/PuH88ZH$$jYLBBiQbeXKp<Zy>:@Hi:^wj=bRtQa#9eBYu*uq??:P>qj*
4J$$T# %A%H?dh1cmS5MVJ<iHPc8#%W@duSFW9yS/w?ydH9Y6%Z=b++wHayeM>!D\YLp5y6*uj4w#&V#F68==^q
lNJKq/ =ub:uh+/^L#u:hPS@b=KTqP9w:K<ucyX1VyC6*8!Im+Z*!ll@tj*lK*mTbN>d+4WI9G9NuTYh:&&6PIt
5<&ZZ$ l6l9+Dly?iSF^QIIlW^wbtkI?9F%VP>6S>8ZXwwjPa*$$E45>YA<lmQE@cV%XN>8w>BAqdDJllYll*aw
u&YJ5b j/lVRVyi>a^WLqQQFJYe<L$V@@CbuQ4#b>j!D&I%YlWM*HY/%eI@:DNqbN\h6dN?udVA<>VVeXDZVRFM
*yBl^D ACpnhm4GlCGWWjcCK6bp5%>\T&&VZMW$^!ul!9%D&iKMIiM8P+4M=I=*p*njn/e<ijq:H<9D+l1!$VJ:
YSnA4a WSd:N!GZ/kTF:&^L?l&t^MkYHn:A*CH@G@e8W1p<+mG4kiM/l&NP$$L+tHP^QXt14/ZZXFkL8&nE:Nd&
Ed1J9/ $W:e/K86G@%%I!b#KFtuRE^EHMiJ=<1XCjhN&nccIYQtp>tZK66@jeVQd>?//NhJnk/%nlZmEj1YN\5*
uQBbZF @*C%&1ynHw>9=:5c%i9pai+ZI*E5nME>^\Jt<Ik:4N!ei*M16E^G+d/\p#=J<&/81qm1atT:Ie:ykFPl
QI56:E dRcjubq1qc/nDd?!tb##YGtEbEu5h+:%q+<h%X%4!c#H%C5@a&jbjnTbKVNu#Zc8F\@DBwL$Xpc5nu@j
RHbeIi hue=1*=IGCFNw?DRBmHHnb^b>SNY<wMc*b5KC5b?QIu^<8XcJXmeMt=wH^eZ^Nd&<IZMSLuSiY=lS:Nn
Fy!ZqH Z=i*P#*$I6\P4R$Z?JXl!Z=!!>k/*jy9&N:V4Y^8q$p=+8y<yuLuYXMm9^8>YAQdXN#FuQnt4LL=B48d
$=Q<&T =<YRSpI$d*/Rb$!*h>:4TqcV4\VTm%e?1jq&%4&!:\=N!ceWjJSibqHBad/q&yNb4ytM&:>Ga81CGcuD
XiwuX+ Y!V><??X:1?&&l*jutaF9Z8wWi$6<&pD5V%wMLjwpJyZm5Dbni<<hejm>y@ahCDNiJ?nDjcWlqZ5+*aY
6H&hQT W:N#!>Q>tbalVBpZJHeuCm1ceCL=uTw/8<c@H6^@h>qXQZ8e@9DHZdFIauq+XCel:i4b<=YH1uRj/elQ
cm8\N< EC8<Z1lZ*=V=8pZ\!iX>5dXn+nKHP\Y/FA*dtbt1hppHQ:$R8>*LN&X4k$BYq9c!wp>tL$#5C&H&G!Z!
11diSJ #NI8QRZ*=ay<Z=4+Zk^V@14DI1Rc9PXchqVZl%4X68<95=5Ha\w4^nlLi8QF@ZkH$1b/A@ECdVWX>e59
cB@P=j DJbY5\qTL?9btbt<%IkI#SQI:?m^ZyP#:EDyp$BH@<8de%%PCuS>C?VYTPGBLh+XYJu4ac?6pHm<4>C6
DeTdPM @<Z&6Rd/BnZ!6VJ8B#99NlaSLDPW\\iMGJI!&K5F5@$=8e?5^kT\TEPDeeFC1YWY?kGaS^+?Z1jp#:l^
Eu6q/* !8WJnb@h6b5Vh@yq\p9i/=YYk**!dR>+:#>SXbwK4Xbb?&&dF8t/V\Vl^?A>Ry&X?ThYVtmDeGAKMyIy
^N?Bl= Q9Z=qPPH1n=49e$@h^d1mTd:1:nFQ>!&*6dtw8WD1WMD+%<N#ukEEnyPZS&WNY@=:he*$ZtqbGPhETM:
=LQBqm +=WZ^&JT<#Gu\:YjBY6b%ydb=58pcmSdldei=>??>hl1a$Pb$uIS98aSShZRmy?R184Wc@eDuj5hMwtD
5WJ&uV ?/Pi<:Ee*96RK=Dcj?q$KXE+6$6kjcJ+FyP!$:&#N91<81>Z/AlhiP/\SVXP/$j1qF!D:kENVbt$1SXc
I=FlW6 Bct4#m9c^n@KD@1W^?p%!9P?MF99%G4^cFeBu44dl4Yu:lR?PNRY6L!4EdEJDW>NV>PVPPRSEH!+Z?^*
dVcPXq HIZdM1dl*j6ZuGhQXGt&Q9eZmHZM*>G\X$bW6Y\tNp@1T#k@XKNXaCFW@+H9HL?j/ZkM#uQ$6FYAhKp5
AybG&$ F?ulm/1t^^E*&t@=^p/9y*l8KZ=q6cM&JEVw!c:WYJph&&NFGe84b#\t#QLW49SP5Jd%:S^<h$Xc?ip1
S:MQPA &=9yY>d5<9b9bd6Hqhj#c:tj4Gu+hIjTY/6Cjdd1B*d49b1D=M/8JY^u\^%SID5?1qbjhc&$&M&K//cT
+$<GBN >?EDA<etjyVCH=V!T#aLHV/QTLwhdCcW*eI=:>yt*&Eb%ShiGT#!ZXVi//BdqGpi+/?T\h>ekqpqZl=D
lmF!bM N4?+cn:p=nAa6**46PtV8a%y5QyhAyXFy9j#mN=ZQHNV^8GYj9\IW<*bBuX:VGb=T+8W9NG!#ni9*lau
h^dpZ1 5/q>%%1^ZC/:H*jypdF9@h&uG!hP@uDepNPtG>X+WHMwNmh!R$6IuyWPQPJbMPqk18X5/PamG5PN:%F<
^KeGAM 6V*:uIe!BbN>*h>\q*<e=aQ*!6lhR%LG*?RWV#M84<#jLIQ4e6y*@FeYl&t@<TmlqP8YT>LbPM@kyyYV
\w1>k! Pki>c>VbHX4bZLCX#WHt8\PQElm$uAXMInbw=jj*eH\/\myat%NeFQeX!@pVc>m:9ik*A$Fy/PJDSmYi
jBE5R9 K@muY#TLB!jCcyYGH*pyVdm:XnLh5:+Zd?/p^ltm#4Hb!:kiD8IXb8a>PM:1c^Ild=IablK=&:lk>@1%
aWhY&P BQa!tcjD^W*Mk/cZtnttdNy=VK@ubGAdW:/XYHQ86XQZNGB45HLH!198TZ?nJFuILDPewN:F/?R#58Ea
k!dp>> JuDW?Q%P@e\E>:^*P6l*5RtjT1WMGi11=DBn++E8w=1q4l=<llct#Hh^Lwe4LnF?IJR5&/Jm!n18=C5y
Eq5pT8 y<9McbT=#ZFCaCLwhhh+lwIJX@GpIWMtt%MLM/@@mH6ttlV4n*jF?l#FJ45:jndy*@XXY5@:dZ8tF+:H
il48<D H6j=IbtNL/^qiDAen=PhDP?R=4wwGle8\<Y%iS^d8u:6W?KwiJe:I5kXM1DD61b+D?a6Xu*VViJLV??c
<n/h99 IT/58up^YWG1N>Hu4ESlk5#\8jN:%X?iPNP8uHtG:dnTJPp*X>h9H&QqT#Nm9ma48uh>=m8I4nHq!8^k
*>4Mhw #m<PmnAd>&*+qJRqNyE$pTQ#\&u1S&qEhH!M8R9&Be<b+*Ba/?*15elItckC=SqGY+P#@JDC&1S9VV4V
wW*<PH HG\/iH$P#kl:PR:hHcNJS/c6VL96YcALQq&^S8y6l+=mnA^%d$6NEa8NwA:*VyQd6>cqE$w@ml6lZVKj
5\mWmt BnEJa&WPBpuDGypc18MS*nYDuDP>6@PC:9AQTQl6*c/Vw5V!/cV8qdYGLQ^:#?ZlT*Fau+%tS$Zid*C<
$LdYB^ pDqwbQQ<?C>Mm/nWq6@!YDZIwXZIca#Nlb</?wVXShTGbSY:&TPlp8PM4&W&cI/:=:J@<t^=eGYQPw8K
-AHunV 000050dcfab00110333 Page 447 of binaries1.zip
<TXBZS l?Kdh*+HBGIahJP$XT<FTPWj=TyRtSd9IPbXtEkN<L#/>NnL+cqd1NA\Ju%+GLeLpVW+9>d4n8RH$b=L
DtFTXI X9wy8@8+iHX:X&aY%1@#*:?mN?m585Qd!:e6R<\*T&?N8uh55$6BG9^a<<Jwk9aZZ+5NJq/bI@:cV%M&
%j?H:8 J+++@NJ>K?u:pXTSV^w&hCkZ\/YWD**\aC^Qil/bu9y8n/E!N+8YpGG*5=FAL^P#:%GthiaXMX\>K+\l
SHIP@a \ct+Eta*9lT#>%?959EujeN<MQ!=VutLd<\&J+Hj1c54\6S^>\p4GyhSbe>%%$^?dtnjaD:$JiW4i&j<
mFZV:t @w88WyiENmd@XE:byyjKR!Ve9PH9tm^Rdc&<!+1jc@#nEaLyG+NpKtF!6$>?y19dW^PGq%9jq&4IDZP8
EQ<eBQ /Hi=PtR+!t=p5q\y\FBbLp@%#XZT<S#VCkd%=p>/^c*1X<5MNp8ySV/Pn55Xda5KN+!6V5*aBAj&q$+d
lm59Vw =nEheBL$:9k1QyZN9EK:=iPW8Xa^M\i:T*^ThEmMipta4u1ZlYTqCetIX+4QYF6Z1&mji6/J:jtC^A<J
Lwuui& 4a&nWyH5i6wZ>FP64tM:JV5#C$ku<Ql6>5y<yu#&P%>MmI/5$CmWIe#\myZWtnWq5$R\Hd^@L1hQb\Zu
V%1uF! Zb@!wbaI*?+i%5tRIc:MS9p!MZaL9D%Zm8Ga*eHM8y#:ci5aih:=%:K\hj^R>5c/HdS/*dS1+tu&uwaw
$!H^Cc y&qdkcSG4XL=KhhV/@n%mh?Xje4%6MyM^:9PB:mSG^+KnGSRWwP&nDPa8Sw/qDu:5Qycd$p!YTY<Z5uK
!NK&:C >*W#1^/GmiHNtI5MX@SY+<$H+HlK6t:k!Jbq$8W&SJdS>^cp6:tq$atCSPtkFuNSC>!Ga%wdqT\&&XyF
X+BSbj uew>+*=yteQKNJ%L:qIBD8iqiZC9SN^JA5ueP\#!hNh8?udEH$i\65XNyFtad#TT/6Z?9AJtWPiYi&15
9i=+hu Q1X=ba1pNh:t<tX@Cb8P%\$S#un:uHFXYC!$$*IuIuTa$>w?5i6=jbye>$Q=qjk>u<miLwPHTV1B5cY?
FamP:e mk$6EX*YnS6ZN6%R/j:JFb5c+JiEhZ8&nX&cn=u$NnBwQiGk:ti9a\P:6K=X&<IyG=#VMb4c/hPEMF:E
=RR4wj L*&6Z+P4l$L/FaJ&^\wQDdc%A8?kSDnA?!VS8+F=H?>?IZk1&>#eb>^nR?1Hu/5W!NLepq8IaTanjkM>
uqhm1# DqX96%k@WS?@+*>66NmuX*=1qj!1GWjy*kM8%Z9nMJ#!FP>$jt!L9y//?^:4yylW?+&jP&d!k$<<SA/X
%Zu*PG S??:>q#DS1%9aPytqW?A9pnm:y$Sw:X^^8j*Bd!I54+aFGLZMEbcV#/\9+p#pLM=$NX%5tQ>kXZblkMu
KhC+SJ C#tHnc?hh#G#D\y<Y1X8!t%h*D%RaXK6eGkqi*4n&>Dy!\:INuZ&Tt4G#a@pVcK!c\>V#dqY9dAT5q&Z
<R%Gh= ^DBeaLnS/Hc*\4m8iyNclJQL!*FZK\9PN^tu>/4IV*ZbPu<?tFCj*FE*e&&!?lSQp>D!+?Mn1j^l149<
GSBY&p +#PGP\Q11h^<J1QVum>a1B*pC>b:&NXdVG$t&N<YJm>*Y==\=+Sy$+t\Zup&?h:8VahiTYF+nV5?*nqu
p6^k1$ IW$q*S9^jcVX$Khm5*Y/NFj#\Xl\%Tu==PWeCVhPpDLW8XXhm>IJ=Wi!@R=/&AXHeEtp=9bMiMpjCI4T
qZ91Ph Ku!1qS6m9AZ#?FT@<aD*WdNXL8y%&E@jKmeKVI:i8t!y@=M>VPFB@lq!1+N%^$9JD%IiKbeDd=EdGjaL
\\8$$n DV/9&H@+nX!m+:iV?ThHS%YIFXPjt!=Vy$??d\^58ZLPbIK4hbZd?R:HVCc^VL99:FM<1npMSaHV!StN
aLj\<1 YXHmWkuETpY6BL=nbiG*BCa9hYKJBaK?>XhDja4Gn=ut:BHbYFmX+S6d<&55T%t+<PCk5Q/X=hj*bX&4
&S:/?l :tWY9yYRI:BB@&Y=Ti%JLP:IZmtL#:>ZBVKH^DYHjLjdu4:!tiT6LFY*$kNN!c@<yaJjb65c?Ki4bw<I
SScDw6 &BT9mVDu#:p9yHA>=8&*?EulPFc5WZZNCt>45&&1546=6KFkI\tZ5*9knTdY^/=kkyk\KTamt/PcMbWN
uIhlQH w=LtLTMPn//a?P11%*Ht4!t^H*H%46yjF^nR^&^=&5QPumQbFMbEN?M1PLMncuBth69/^V6Kl?R@T6jq
Me@?kN KpnLj*4$p8M!$\nl#XeZT=n+^TM#KW#KS<FNpY^HX5ELe=RPX#aF8KW$D6#+9qyJmN?nTp<%wNYLNN=>
=5@M^? j!*dQ59E>*cHylPk$ZbBZM?lRHQI=W1hXRSJ<%1P=QkGj*PPH4ttH=%6tpN=b!YKk19F^djkiE$wntX!
8VGpw6 >?N@eQRcJN?R*#jKGZKj#WpyPG%bub@!#Tl!*Vld9b1cTj=#C@PtI+<5dFk#GkXh:n+<hDX/9<$/@dEG
imXIBZ j1?d/qFuR#V8<lX&uVET*5T8@YT@>>tG4R=e&@!J&/:e@TqEEq66?@%%1h&1i%^%!w*ylh^V9Za?beHZ
eA%pF1 m*!MeWd!?u=qPhjad?pR>/*q>/uPM+uQ1K<kH<q@:m5t<Q9Bm8MJdd95HD/wPQQuqL+8!h6q^VQ$PIFb
pSLkXR mHY:&Cy5:&?B%RI@H=>^+HuD#MN@@c:E:ePT6i5Hj/5KKn^w/Q8+N4cl89@w>/%ZP4R9*L?1+@6W/k8Z
eRl>\j %JHG:j=nSWN19++$1G5<mBB:JJ\YGL@nwa=yEDuAii89uh6!H=C&XCBl9wi8t9?<eh1:iwX!*5#qw:h@
=%ZY*j 69cWXlh^W%@^*L<*e%BXdKSudPja?=dAKu&DDCj#6hquJ*1=%@MEFZk+i/XFdylY/P>matn6m5/Ah5ie
d$IE%S &<m=V@dMa^$@IaEnjd<kKe<ck>#Bb+ed&^/WXK1Y^ZBVPXSZnNqjq^edV14t454ac4d?ujhu9yHAl!e@
/TF@MZ m\$Fn9n8YB6@C?>$:MV%G&^bXh@dMZwy=@y8*Fc8Ma^YPVCTTJ/?hHbQ+yl#EuZ6>HY&yB@hSV9<bmmZ
ilZipJ V^#5Pw>lJ/+V89eATV^Sq6%cp*p%+=^w:qFn^aCt6JNy#wRBn#Sbq:V#LQ6#P6QJaSwQE>MHVkSG:5nR
:BQjVX /5DWMelCMd1+bS1nbwyCeV1M!#dje=XX1NQ%hnTW<ybh4/qLTGc>+CqL%hR%+^i@eN%Ci4tGX1n*pLi+
Z%4^a+ wGEE*+8REFi!+QGwik&Gi>:pe%l6bm*Q<6$YlB:b@ANP5JpFa5ACjj*R+YIycyKQw^:<Fc/Y*q&a4CJ^
kklI9j 4*Q#Km\GJ/?+VpA&&5Lh+YJDV@i/qdG/J<81Py+E4<LiJX/W+?9#FHp$VY4^LK&WVY:T+jYJ^a@:H:%u
V\QuTM dP8/M>1MKmDtpPCaF&n1Fcb6?E+nleT:S$BpJwk!146JL4ZXiWdp=8A8YLDnL5:6!>N9JPF8%<?iLySC
i9^GQy +/4/m=d/FV%ZBy=dS>*etTc?qZ#Nq61@p*u<6WjqVPN!nc5>4aEXabEXE9eGB5KE*qW:G&4%CGLa*1e$
6a>\=+ qMRGC6#L*JtEXePFXypTKmVW8=Ipbd@a^X:XmDaq^8G<P*m+Jwe%n%>>%dXL1M=XWulR&j8^mWAe1/Bh
M45yT/ qJVHwPbSTW:B<Zk6u#MidJ9mit!GXNtKk5=kc5M^d#HND%^@XX@WH:y\ZV@<I4PC@uW*SV&J=H1b@J%F
&u#8wQ VZI!^%WuyC?jEB/1^mmH6*^XNuDh?9&P*CQY?w&69V*D%VPn*E!%BSc4KXLSVub%Wq5tVh5qVAiXd6ZL
MjeI6l ntn*S&cqpI/c*a5VaipY1GquL!<alpkTEnudR#N:?C\q>Vl@JAln&A6<*&KPid8KX5e+5W:1h&T@XCy?
Y>+$K> @#JTPT4k+6a*A?aSua#6:wh<!MW9Vuh>!*&i+C5W\Z&jQh9EqMFl^D4W<<9$heQwD1ll$qt+Y/8dYbMw
4Pl^W+ =TY!P/JC!=$1EMF#$^8J#Ypumt$K>hBlS1dL9\l\6e5#Qi/LG>=4uje<=@E1^h1pqc5\qc*NekMBH=+=
SRi6!D 6Md*:bFb?/Y^H44b1ZQ9E!a4MkhuF!?+#S:#I8/c&y&b5d114S+&#4:qQMN5t/+G/1<?:6y8>tuk/4X$
VXCF^= hSZP=\^Q&#GduiV!^DWMGBKbPHE/1#jXG1+SpWV5>$5PK:Ed^PTyMN$YLk5e@dt<=hQ!py&1?w\N=!jb
5Wi1wn SqqTIqa/9nlyui#qeGM\y6nnhMiuEc/:I\hi*de%^X=?E>8X=c/%56JGdR*@%ZejPdtaXnC=/iDWZ8+I
kLmeF& 9n8=%#mKE?i$P?HXS!@^W=891mch:>eZT+$j8Hnw<E5FZ!V1:iiLBb=q:>VYeJAMD&wQj=P@Wuj5nH%%
FdbuFn V:?k:iP%XYYQ&\1i5Nb?qMj&tLZ#tRk<cbbc#cQ%kGqh9QnkNwJR:W<QhkHNTdqW#yDRu=tj*:ML<5tG
IE\uej 6QQ?8tMXyZt1S&9u?NjHSR!iqy9D\/\mytYLKk1idJi$*a5>N5Kjel/#4P!=+hHGmZQ=N+M%Y8@d8dVh
uNH1tD Tl*!964j@G%n9AdD&4:AMYF&Xtd&%AkS*W5S!#p5>!pKp4N!*+9$MjH5\S8iD5h:G#hZm!p$c\!S6dLj
QL5Q:@ QYTTWFWYqq@X!#RWY95+WtHhVF/$VdDpJZ!e<?V6jHQGpa#YSP144\^F/Vh+PLQKac+5*hNTTni$@N/a
iC!&j^ *Z9iX%C@NTcqDC98$NBN@eLZ4#t!X^14Iy6M>6i\KR4D9FDe1qMX#JL>@i=ijB#%nCN:W4?Bu:Ny</VA
JmG!6& y/&uS\e*:VL/i1!FVYiNKJbk56huYc:8+bBu@Kd8bp=Q!kZ44LpH@SX:45cYS%8Kd9@t:y#bRmFKudS*
WP%D5! LA#*iZtkbXQhpJNY&H6J&a1EdF>I!QSaMN#AE=9w9@yu:+YYji@$ncYmC=KiPwb=4ZPP!:M%YGN@yhHA
CQQY?> D?dS$d+>HX86iT1^MQZ8ADbF=nGpZN4u1Xn\/qQC89y$=aBYYa6R1dnVqnyT&Cnnn@%c###nDw?Z5Tuu
I#nAhi &LtG5=%EJ6$+M$=tdt1YqiY5TL\5^WI1mE6XejZS5NdBlZFtN^PWI#>Y6Y^Y%en<$edEkS&Vm5q?N9!+
P5KX!R :MLc!>8F?L+WcN#<a5#Q<E$!Tu=G+yda$T&VktT=/BC4q<Ne4t*Dy>IF>i/b/#pE9A>W9?@$w*iZwm5V
AVY9>8 nCS1ct$@^5d1IS+ccuNchHP/&etR/Dkhm*!jDYQNhle^9M?81dA*>VVc&P^iXqtqwLN^LD#5XE>dXdlK
QPqQwF ^$uyG>e6l1w?bwj6T::+9dja5m5@4KXEWL+XF#H#/!t=hRj:iPPK!6\?N!PudSR5<iFS\#h1iThD^lJH
h<\/dt heT>\1R5hpu?HQSpb?Jq><<8dVKJd5+@6wY\W954a9b18qa=<6J=WYm4:<Ye%ej:#+&5I<c$K#<Wm%#=
pD!L66 c<JK/wGGdbANc=dyTS/ilWV!aML@1pkiDQ$QSjJIiMy@E<pn+eqLE5tD/Ty#MHZ8aRmC^>M@RQRQMQ$D
8&IGGw mj/BQykA#Y8TIRV/*\n$9$H$B$H$B$H$B$H$\SB>MBFQj^CSQyyIH$&pn!dTS<Q$S<Q$MVB>DE!lQ\ml
^5?iEu D$LwV$Vww?uTkAlCj!KJQylEH$!C/R<m$WiV/KQJ>NFp?tk!@hFp?tA!jVDqQ%?NRl>Nwa?t$EhV/KPy
5l45%q >EhV/aPy>MFWE9%B>B?LSQ?^TQRjm#V@a@%HG+=i*Q=*&Z\B@ReaA6Z:kBikcqlkNww&HL!A@5MC5%HW
5Le:V9 BPAF&BaYtI&mJkA9wQ?\\G\WNRF+AeKEBYaV$GcVAYanKK\F<AKeB\9My1D>aqTR&Tl*?iAFcA5YtE%E
BRnd*l chEkk9kcLTk5QB9E%^C$*m$mmK@BcA%WSBBjR%QNkIpk9wcttkEVRZ\NVVWDJwL+Gw!mc\MVRZ\NVVWD
-A@DDb 0008521151e00110333 Page 448 of binaries1.zip
uala>R JwL+Gw!m8AZDIL/GyywB\!C?l1ccAeMk9pbEadtAaSBjI/I\VeA\mK<SWST*aBnE%+kwVH<\DPJ4cA*/
\bA8d8 MA#mc$R<&9<G<VWIlX+ilpF<DWL4ipNAjA%Cc#%DRH\NR6E=kSERZ+PIcJcD?ByERLMe^NeIFLVbIL=G
Y+8t+k RPHXl^ERZ!Pk*Q?EEjKj+BcE<mi+BcEC+ScW&ELCA?EYqQidBIVZ$PI=CRm9weX#ElBiR+9uJCC<lphb
l^RM<1 e^IClH4R%l#E%^A!&ywD+VY$iE+C\t5w14R\CRm9weX#MlBiR/FQleqAiA*q%lNMlwA\E$y5IRQlNbV:
DLG%8D Q#AbCK?lZMKB!WB+DWFde!C<luahlR!E%!C$NRjCc*m$NceCIT/WNceA+VY$tEwB\t6wGJpClNjRMDIF
P<Y$N= CK?l=aIWIL!GwpwLW+D\GkF6#aH\Gl:F#!qpIMTF68bAiI&M68bAiA%FYR/tA8E%6JlKJj\J+1JCj+K+
lG$SMM 1EB+DaYqGKd?EX/nk8E%FF?nk9kc16wZVCZ@4%$5?hjN^u>h<TM9kRceM59hS%NHAPQ8k/pkdw:G*aj<
i=/\a$ /&dn@=kAkuddl#R4EkMBGw:kCZ>pPQS*d54SKJLuXMwkRJW!BA<EWqHTTPSjN^9@^^iHcVJ$e!yqEKBK
@aC6kW GaIHPyFE!caRQPu9pJ#Rdp*N1bSBkCyqCB+wFWNJ=BA<=T>y4XCI<!yqEKBKGaIH!8NRmH\RAqAiB/F<
a?@&Il dRLln&bDj$6KAlKu%W^wm$b#EwBFI^CBD1>SAkMBbANDWIA=RpD?cQcmiyNWEtpy+bRGj&bZDa<HYnYk
J!8LAu FBIFemAE!1LE:hTqSCYaNBiXaCBXBaRAqH?m+BWEYuRDk+qLYuEatVMemQpCATy5wcYjCATlE4eVKGVm
PX:XHN p1ITQB>P\ZnSEKC1GBw9GkLB1IdVjJ!!NJEb/y#lRQSmCFBJDa%iDIFIm^qPlybpPHp8yBGB^ApRCC#u
*<VjPc SkqyEAYh+^<Q\W9R*CLQ$a9SDAhm/WIk5IRhJcwR<ckkDj:HhuDD1eSb/abb\+HECSAmYLcQEqYI$N?T
\$=GWq QCHNTnjMGk/pVaAAqSGJKNwECBFiqQ5QZyJ!CHp816B/RpAMB#yuRMMdSBJ1BpYn1aPYwuJGi!XtDRjm
kSChYA KWcACykRCp<^R1TkE$nANMGGJRnmRjl=\!E\\+FPPFDP?SEa9+npCa%NDZnFpZ<&IeK5+RRkJV<E1HRK
5%=<J! wTn=IWCqW#TtEkTwhIw?G@=LcThM$$YaT#5JRPVPCFDhqaBC:w#A/P<ZBBPIBHD/Q5J59n^LGR?YL\MX
lCkdpF dXH#bZmS#Y?&w\/a!+i/SJJ?BKnmm$dTn!B+%H\bIqL\+N!cNDu!JbH$I\laCR>qD$GkSR\upaBZuKdi
B6C!%j le##^=LAAB=R4btEB9ARiBFZReAJ#GpJDK&>dp=hAAnkASY1TYkAD!E6cnk+q\<Sup%P=>RFkF=P5Cw*
FlBjS9 H8ZqSCl@B!jN59ZP$:AmRDT5CFCJHEGlaWXIm/YNbA1+EMW@R&uHW:PGA\pHI$D%hVVlaIV$q>JGG9Mm
HTNaFq 4S\*S^pQ>HICFieSFQEylAR9K5\DLq%QK#uVGtJtLTeB+R&k$n/6iLG\=a6AW\RQjtJL/\Yn>d9NWc<D
/Q/kM% yX>AjRG$&8VClqQ?$yLVInt6u*ZYemLR/\uWXWD4QXnRenJ?$TWH=<Gn$qkHwZuTiKC>E/kqkhbc6LDl
4PD>EY $KKGL$HklnLdiVlHGk@$iwL%M/B$>TFpiDE/PV\+k!^NuZTi5=eI^NtLkDXDwLREItVT*%E1t>W:u8j5
ikBkJL JRJ^>mJkuSRw*T5IihGcIYWJ=W4KdL9qHIW=$PEIYB5GYmGIkq?5kpXAq4Ly$+R*cc6NBD8=BP#lRNp:
kK%k<% Ka99uiC8<5@KEPiqKEANJ@/S+jDjKT<Vb!8$e:TkSLAKFqn*CFwFm$L/T+d@a<c5pC$XAST!SaBcV>CE
SndH4u dBEK=Y<JI%BuDb<nnRe#uQwulqQ^/IjeJJyi*lJ$amD!QIW=FTkeAnY>EFEc!^A1?yE4H1JAyCY6PGti
+8cXKM \y\MlFYAPtcIKD%6CHX^aA5iD&qFEB1J>B!HPXBaAi1*kXA/+lA1cSEuZ<4Y?a?^$L\YBRTpSaFRke=e
P&%pB< WS1eEi1m\Jc/BQJdQGqY?ZmPC^\wIAL%&$DElRMmciF?t@?!jApAei:Wha+MHCT\pQB@e8yKY1VlBmLV
>H#1$4 Y6cYeIBIw/Ti+>TtABpPhkMBn&I+9FkuA*pJJ=<$Ch6=wtTk>I$E%HBDREujTQ>9\+*yj<&h=^9GL<R*
bWPaZi DBQ?L:=lCkH?Q>ThiVVX*h9@nahMpWPGqCIbn#N?Q8hItYYil^Squ8i=pp!bK#KqpbTEVCFK>&$wMk8l
bEkHRb WltKmAdW*c*ljl^%94@9<*%<4P%Z/%u4cT%4>ejb^>9i%>::&6i?46j?u:^l/N?#cYm<aTJ%89>j+A&@
@ehZym E16qn&ZW9q@9T9tDn:M!$d#*klG*Tm:DE/%/Y%K%\Cl#8a4+5CM/ThPBZmZhBEJ9b6:it!9N4ZGVITi#
\\yaqM #plcZ9DETVjCwXqdqT$ya/:Bd?VPJ^P1u6y6>Lnk1*I9NZte<embCZ&#&yH4Ay:/85IQY^uK5\1Qq4%L
8:TKLQ R@NymQEW=E^I#YWd1Kbt?6dkQ:MFlQ5w=!n9?VDJ>ijY?J#iDyVQG$Z?QJX#!kJ@Smy:C%h/!aR>EDZk
iJF+NR 6W/SQ+uHu5?^P^*EKBbbmBWYN$lBN>eqJ>XVV5kLPKM=*n$\klZ6$4:^cZ^I6pJX6y$NuwdZ<V/wWVPc
qedp1c WYI6<>8pL<b&<nQ/!#LAX@ZpFe\jm9GNu+ZX&5#W66Y$JdEKwDCN*GnI^QPTCI\lHw/M:c*RpNZ!eK!b
/$JR5? JyW<*TV<aFS=L:hid\!PZYh49QeFiZ>$FWZB*jE8V/py^=^AWh>M<4lBd8FC1dmS1A%h:Q9+BQq:q@M1
nHNiB$ &4ke<wcEtBtQDH^1hyQ%aND\<>Di%BqkFn^u$qBwIwS1M>*KI=YBd6t6*dekjX9HXeC>llL@KnV6N8EC
/mTQ4% i41jF=$ylKyMT<+*8E=IF<AE>nmj6q#+JwkXC?c6jHMdd!1yaP:#84HD!N#LYEA=NZ&j\J?=hP@R9jVK
AdEIQ+ 4+tcpZR9Iy8V**8nD?B6>*M!4^@!Z=TciY%/@K/hq>H<kK8G?&%>8*TGnV1nb@W>nViw*dS6NZFKY6j>
1NhYLb TV$9Xj^SL!YN8iFGuu4X!TylD&d/hJ/5y<F=XiH!Kt*H@I#M=9td!?h&T8:ppP&elklpc=NPyV!JIka:
dW:ncm l@^dhI>G:@te:F#H=#teb?yQ@9R!!V^TeTl6X=1!tyB:l5^d\iyJ6/y!mene@ccZ4=+Rb*@!KN?$!Kt#
1Q+K+L \AdVMd6HY==8h1NHpG*d#n1j%*%l8*q5qSXQ#HSJKN\>w4p:Z><8*ui!e#S1SKlG?MKn#L&Bti?!jddi
cY!ZXG Q/Ic?!!N@e@J/8J=VlNh%Wi5N%1q^<bKL91@He#@bJQN6bhD8tcn%IJN%M^^lqPu^XVb:b<>8==yYFAe
I*nYw^ &=CSt@//n8&n4:8K<6m*+/Z!BDP#\RttS/u:yAmS6XcmI?k9GR<b4HXVY:c@6*%yTGip^M4>@Vm#H99i
uW&\Rc :DjHP5N/YNJ>Y%Kji8!yH!w/9c$!I&M^\Ec9>5=&@9eb>PWKGN<L=&>YTZ!\*Jpi6u=4Xq%i%L\&LpT*
V@>b&% uGpm#d/C\/mGamQqN+5i4LHj^HcI#jDEZP/PH6a6byyMhQ%*d>$cGe%k+4b?>:A6Ip?!cX@lZ=1^69^q
BVt%VP be?FDi&@HWnGEM5pCy?I1w6LM65aEF<*&=wL!T1:yMNcpMCnE+\HQd5@$X&<h=Di@MyYS:buBupX*<*H
u6#MV\ ?/1hZA+NX*\81VDdECN@&pc6dp>hh@?l:d/F^p%bLFFeb1&Y\SGQA&9?tlVqw+?$/SXJiHDqwQA&%i98
GTl*eb Lb@IPH!!mEMWp&J8jEhlA5jlwZPdIl=PMP>yQ5hw%@cup$@up@b1:nN:!*N5YY?ab>e4l#@FVh1nRu5a
S1/N\R /JwWMySFL@LG#G?Leb*cG@Zb9QXDQK4Tbmi>?tcWlL?dN4yQ9LN>t@SEn#DB$wQ6!4DV<TSBKRLp&=p^
5AjN!C KyHkPYicn+1+\6?8u5!=?RTnpc<n?1HSdq/:Aqm1&8Fe?y%wuh#T!=Y&4lIMBaFZthB:WI!Ky+ThPZI#
bXA6$5 #%>yFlXM%YZ*+JD6X4k8@pd<<uPMdW?y#P5@bq?P/ZyZtt^M\ZyjVj\kXqkEtSJhJK1TL/eRbJYFXV=:
9qKI*6 *>486mMTN*5?^<&>:<Z=J+yMN+1pI%4&VRRh%jT4SFMC%>p?*jdb5%e=Sq>ucw8d@Rt6YSZ8>4JS%KZ?
dq<yTq ?LJ4J<<1DWkI16A=biMZQwqJXG6G18&>*4?=AK4*@bJWR@T=Q1a9w4Dh+uFW!%FyXF4Y=hDl4epHjVpY
hXk@cN V?%I<hA!*juB>&Ya<QY&Khp*hR:1GP$N8wYjG9iXTbc?N^a<T#iT1E@uyMtT!X=Yym\+%DF!#XQ&&/Yi
t1!NMB WSXQD<wyA:#TDljHd&4Ckml#jCjy:/mlC@lTqE6tM=Rii8Q=PpGMm>SjG^hL%c&<c6KttV@hdhTIq5>w
dwb=EQ nPNcy>mwdYHDQ!WcuDC&cMY:KecS%XHb/\^pj?6:JJ@G6hTQ6a@PlZGdcA$SWC@6u6n?9bQh/5RhH:Lb
VC5Met yjE4T4EFM\y/Q4jYD#L!q:1&lq&Xmuuh:t::#i$eQ!HLP#IQ&lk!XH5l@*Nh#$HY>YH=liemI+$DD4yd
&+!MF? b:%:bwYQ9!YkFd#=Z6PS#%Z$DWWG=?mPSwe/N&ewCWP648t?kybP@I@E:VaG5X>+mSXd^/LibJ*!5P!q
=%G4M8 VFN@wwXA^YkGJn!uM&Pp^dKkw+qdtD=dX9XCaj*MWQh5w8i<IZH9*/WF+!KXX>@MW^kmBkVXHwn&/CZ6
qJVFHQ qJ+Pju^>Dq>AX=&:8dYXV9dy>%*:8Abe#eJ5N+?Iwn#n4+44i5Zk9qu*muN6q/wL8MYD!k1*=Pi:LpKJ
4cC6nn */T\WY^\>^%:Y>6b::#=jQmke%>4t49W<In@4H6Xu&%*YZL:+9%<F@#AG=GEwCcnRb%I%9c!/WPj:L=H
PWu%L4 SESIbe<tbQGpjmFpZiZ:<NKCqiGP^WleP6q5mQPEFej/R!MSkw\bAY1j9qW@:D&m=dn6<^G6i1!+>TNh
l6S5B= +^1j$@5a&F8451>I!4^Lu#4Ia%\^GuTl<\m1?P?QF@8mIIY\SwF>>$ca&H9t15\eSeV?qP<=YiW$4*4h
Yhwu$/ 9NKlytmjp8n>+\!b&nZ+&a?yduc%^t!>ydwGJh?8<6\&9S6$@%Q@\$6tlWpe>+Qe#q>/\N%F16=aZCc@
Tk<SIH @t\ZjF*k>j*Tc9yJy/<N?^@y!=1PcFSiFw+hjtk^h@M9\+KpS%qBL/>pdcnnnh6lWVjyw?&YpB/%^/C>
ymBT&h <n&#cD/*ebpwX&#w*PDjWR&ER8!^aXS@up>B$6:#t$<JDea:8Y/?GQV=$IKqiN4\K&JQdiZRH<PGym@P
Y8jj8X Dl:nFp>\:#CpW$qtnwV!*HP=p&8<@uDXp^l4/SV/tC#^\HuaXY98tY:<y*wnc^@@9pb<uy#16H#hC<:Q
Bl>h*B >6IDu9ZDuC&:=?X4=q&@?4NMS&uHM6Qq@CQL=ZXK#?mc>R:%enwhma?F6$$+euTm@I??e/N*RcFetk?=
+%Yp/Q hElI^m9EZauQ5:W!DQb=eEdK>j!SG%lD$j#E?QBlk:Ap%p4^+yPl!ijnbQLXJ\y*i^%RhFBiNH#@^Z*m
ucYa!/ T<Gt?ZiNZ%&Xu%#d6>Ae1Ld><P\NRSTYViiW:b=/S<8mcJah!e?KWq^TK5V$*YXW<ck*d#>k^MN#Jl:J
lT8Sde 9%TP^*>:W:uIeh9V*hP>meLa$<:EPe98ZcnHZ6\@$lF+hj18ZQyZ/RGq+w/FcQ<YNYiM1<N/LbNJLP16
-Ai@$y 000a7e08bd000110333 Page 449 of binaries1.zip
pBwTVl h?nd1/hd6Hn+:q><q$k8:5TuTKP/Z\y+5ci*9wIknebMR?/&D1Q?KP@pQMu^$9PKib<i9=P$9:@Ih5?p
I1l+w? aA>FcQacS>Ip4?FP\hp=/@Z^@SQwc*q+Di<P#&a/e%T=$B9XD9p4Gn:D4nwMAVqG*dFNI1>MN>?k*^LL
FGFXH$ 9KZ?8Tc:^V?/?*bEcdMYcIt>j@uS#+Z4=PG*>:CFmXjE+1\@iT>P5Ti4uHnBLmt=M:FkwJ9<=eG>+6uD
jP*>W@ KiWD#D!*4+%$KQ5Nneb>X+#hhqiGWjT>TiPI4*\nGVh:l<:k%Vbn#+h$9m%Syn5/?>dH??jNKhbKc^:D
u\>%Y8 :nd%<9:T<V#b/%Q@iFhRp$IqX*$H95K#LjlCVwFtjYKb<qt&DY%hbSeD<T$CTb5:ji1tp\wHT?Tb!lRP
Kk:h*I %y9aP=4M9Ni^Qd:aHViZFT8HqiGww86D1%5ea@?$P?GV@?!maqH9/FWd:H5h#wet5&/!8hh1=I>uH6<R
+nqd4a WaTQ8YWmti=a=llj*iIqJ&We48i8V#?6hTSGte#heX6Zw5I+h*65eYYVpwR#9&%$G^M:^w:AD15y**WY
5ZwpJY p=Hy<J?1j!TZ1GtcW8bjlVdE*HBj^<!1V6q?&Ql?aB91%daNWa$tEqcm4mn@VdFi/>j^HDc+ccH6Ep&/
ujqlpq d?5tpbty4!F+Kpd>iG?Y*^XF9+Lh?wtEcMYDJTbh=di&iF99pThJt?lEht<pj=Ah%&Qu$<Qw!u<NnqJm
Ip5>WZ jn6P=G&RhMR1N=baXW1^dID/8L/HeYYIVZiahLq*!ZQ>>aE:*GhI+XX+ql@@Vh%d/:Ha4y^ZG&Kbw8@Q
A=bnIj :Y+>p/$*w&p5\M#?%h/&&Vc%9qNGhQ=KjZm^GWH&c%jlh!J:u:#8Vi\/@nJV!jaKnqtnwV$BD*cwlp5#
C1@KHi yG*>+LV#:SVS&D8p!$Z9NGpZN6B+Jq9>*nTG#cDFMP!&:DMijXNG+\E:%<emjVK\uI6!d==&\P9k!atK
Ijyel< 9Aa!*p$=kI$R$Zl#cXmq\&a1WXXth:h!Fn>X8$B54G8+iWh9Ace9d!$juY/=DVcVJbDM>yBT96?a:1k>
C\^BJe %dudTLI@\p:/14blbbT>B<e8&T?YiXQciG$t/juhX+ZG<8yjVAjinN$Y!GS^4NlBKTNHe/1VKj$\&:yI
!ilS6C ph+K<@WT>uR1&L^&6QEwVp*=Y6@Z:L!y#RaMERHF@>l4%q=YF9hdy>y*%/#eR%@>Mm4^D\#Jpn5%>QYC
hZqB*t ?4QWCJTGkc9$M+H<p&18AyFPc6J^d+^dL&^@$/85NyS!c8KP?ZqCZ>EP*qLF+:JYlRWQni&hnNay+lMM
JB/68= i6GbYy//%T#$mT\5/c>>Z<u8@=Ct\uhC8\1Ni!Rw\>l<e/:Gk?Q4GipR?MM%+ZZ4JiI^N!W/ll!hQh84
T8u%^c K?QW*IJpdN@m>nI8*tTHlX6MI8wLtM*>NCau4W#K6X\^kYK<G#n*cYy!*jBKH&hS$:J>?iHhTBZ@:b^H
ub>8eV bH&HhK9EjMZEN+R*Qtb66!u1tB&bZ%<Q&P\!Q>D@Ie48qSE1p%j1@WhLKReZ#qtGkdD#/EPc>ePqE^&L
w:y1#@ KPqh@k%GMdb#PR9%&J$&e:!tnd5Luiyh=M*=VhZM^nS^ub*B%=/6D%V>XNnD#BNq9*G4ZKjCVu&JBDbn
bFbqm% RVM4\ZV?m?=$ZMq$=6%ZDl1IGM*qt@F/8J\+#LZ8le9HkXi^4A=wIa@=C$jT98@8nCPZ<CwXJ8eu@L&@
BBD545 M#LIZKHc\4*BmaYPKP>Ltk>PeyV9pA?@?hDYM6SRqtZZ9S8wnMVun+K&iFb\XE5^qi^!+BF^$GS$!Ik#
^H4FS5 >jh@1u9a1yLm<*=TnjSS#V>En%W4NCVERNImp*ea$&dP+FqpKdDlalQ^u@X=SppGA/S%9D!NuScdI^?i
c5%WP^ nbN^#R1<PI:lH=jE&Mw/StV$F@BI*Al%QKG=ST6F=%niS\t#I1#uN+hHI?JS&H?c>S\@/S^=G?T+RE^*
5!w+AE nuFM^q#?6P<\hMCX<eK8Jq?@9i8%#&!w6G\<KX8*YFMi=MtT=Mu9#TETja6yPBR1q48qh+9u^F/G+\=n
P8DDSR C\E+Qnhy=<j5+X%j^Hp&HHj<K\Yd*&J/<%R6J:*Saln:1X&NRcH>GaeLYnnZ1=1amV:XQjq$V$^LLj$^
<j/<X8 GGZqt$l\5$u4#VRWd*h&+D@cM^j$ii^Ly==@<AM<FVl>n#Pm6#%luBMi>hE>4IX^*&HY/hk4Fn*wyylk
n<?:/M QVqdHtI&t9c!Je8^P!Q+4?R8%/iCSZcGA+aW?W#>bltZacQcc@1j/YMiS91nSFp&mwZcS+q#iWDG><>a
iI^HMc qwlZ9B:upSn*d!Q!wyu=15>wM6#F6Ge9NJ\4GW:n9H8&@?GF^@nl!?H96LG/l@:Mp4SMy+V8%DmmIc8h
qY#NTt I!tCMekj4Nl*Zu6VcwT^jNN5V98#w=TMjGYX:KF=$%85Ta@D*@K>P<aSGV&q1ee*YRA^?qFt>D#PSb#w
Jt%qa: WP8j?/c#@@D5&<Ge!e&!LFn@KlECZdZc#KMRVWL<$FNu8d%y#8=CX4!>4#p:@:H&%iHKiSb@VVG%C\ya
+Nkaik FIi*XYi1Rtyt:eEK8INCTej$*^=h@Hd^dQb=yp\>mVmy^*>Lh9ViFmy+5c@+*BYDk^^BmcnNT1W:wwKm
=t>SdV dD9?mc*=EDY\8@n\w6TEh6KdHYXGX+tH>8aiMdAp>>ae+R6yeW9jW^5/bFZlYYKnwX&$ENNB>DDT4iuS
mjwmw\ dNlCbDaKQBIu1K8C4dJmd8Ch!K?<H1Ql*bS49MCby*nt+ZlkAD?He!GSYS@uVE?89PMnkJE=BA$u&F#?
ZD8wZ! *HD&d%^X+!*FP$QyNd1Ck+eQJ9>nP^n#uF6WyuMT<8G:#S?abV5#J%>aq4!k1Y>SJn56?ZBRa8iyP@9t
RaZ!L1 G6>/t6yQM6<?dua&wc4e&&*Qm/b>Ycp5/*i=>/y5FLEV@mLP5H9m9wmGS>/N@dqudkywBNBNFJq\KnmX
iNIFnB ^Dl4c4E!J#FjP&S/4jyn/lnpXWMy<A+yC&E=wJY8u%L/^+ih>Gp68*4GuyjpHm@jcaun<=^&R<@MHD8u
YuPk>L X19hWH9/Sh\lR!bZmYMQ=JV$p>1uR:@5%#:A+>9a!LLXc?P&nT/6q+QEuda/bj96ew=&X8<mMZCLm1:E
I@&\/$ :+Q?i!Zb@#c@D@49%YVk@D:!V^H@#8<nL%e/kjQ:IDLyJ@iNSyKDcCR=mEcTk&kpPalGpwMw6A>VcLR<
EiP$55 tEcTk&ppPbmG@aNy&D<aS@5Mn9abHP$#6L>q/Z<@j#>M+@@BNQ+jVPQ@\VV?H$#n@<EE&weJNKIkVPQ@
m:BS!P \VV?H$#n@<E$@l>MyH$%DRRI$$CA<L>AkDANBAnVRIA\nj<H$@l@MI*@B>Q+j#BE?$dwZ*<cnj<H$@l@
qF!?qC MI*@B>P\j#AN?\iVcb?lWj>kMw$wCNMGC/aNFp\dLJk&YDB65GDcaME$/l<bT!MKpttDScaNFyp&YGRc
a*8l$u w=H<e:D?SRTplb@@M:C>Rq*nD>5GIi6AK>R%46AcIjEQY8HS^SXcI%\<RT8WJ1:RGmF*D%1lNHGF%plZ
h+kDKi S!8WJ1:RG8u/bwYuD%hwneAVlFawL9!j4WpWyD+uk:RtI@W=BcR%AqpH\wQaGktBAkHlRY\Nmc\D+WF5
d9X?iL Dat5A?FBdA&J4AQlRY!NTEb1DYJ4SAVYGaRH5VWmR6+<lAi^NT4Dd8ZYILbG=WT8*B4E%1kJX!8&JwDa
&$%BkN G9X^+yXdk>kcAcH5GTKA&BwBSll9Awm6ETCE<TcA&B1BmQT:RY!NREAad\KI4SERYCpRAeVYCFmEqapA
j8kI1t at9W:J?XY+QaGnWFb<ZYSBBdR*wEHmKC&B1imQT:RY\Nn=ClBBFBdA&QWCwBEWF5Da<$^+kk6wbDKGiF
ZpP#?b mEB:KNJ+E&Ek9\ZB%wlpIL<Fcd^BdA&JR\GSkQ\%yQEtAjq4TPNNA9LZEPyVIBLRHww$*mRmpPiB5LcR
Z/&MEV TECiB<K/SkK^NcR1EakE=K<SpJRD?Y6+yD+H<6iRQE$IcA>FTytBRG!NmFAnCWF+IL<FaeRkAyDjk1Re
W?&ny> !F>DaL^BEJC@lpNTD8T9IZA#IRlwD$Z!:mE!pN?C5K=BFCC@BYF6kdFAjk9C8kaD?Y5I\BWI^9?K*\IV
wnd/&% j5X9kat@+4jAyF@^Y&DwX@\YGMVY<CTp<Rd!%^C+tSAM=K@lEiaaGeljR<k^l5kk6wbD&wuIILcGR>1J
V\%%X= !CC&lpQcmekk6wdI>IQ?w@#kj#N=e<Zclj<jQ5LTX9+DnWeASPNBbBA#S$LnRYV!:&IW\KLW<@T!eCJa
yBpVmw u\H=tWl^A\y&NiF4+N\5GV\%$*ybPA/pIk1mADtyTEEHCuLXH+G!>A<eRwWVySc8WIXVw&pk\wEmppn^
i:MP:d Dky^XiHpNRtuXpXSlbMlIPFA+W!pWA5F?p$>98T6Wm8!q+ZDRGu$FKB#HNIJhBXT/B1FR/Ip+w@JTRJm
46GeQ> PWEW!m<eltA5>neJZ=yE%FL@biFAyj+\F9eL=#Aa?:5tJ=WKkej@EA=W=RJnka/jCJeN<C1FC*km>Z8A
AyN&@< /Xt+bWdB5uAkSkGMJj*C/SQGR166&t8A!m/6EXSGAXW+GKMA^kIhjBEaBVAYKHlMRSw9!1?$^tF@#/=N
#KQF>G nhyS*>#CL=*m1Tk<kE:Dkb&cTRnC<c8XTyKAK=4\EH=b?QJwA\wu@JL\qiaZ+YjFIhXJBHa*wGYe^4J\
EKYkpj LAqIPNB=HiEpA1?IGj%@\5ES\p8DR%k/tFDLJcpMQ^DlRJe#CIekiEZK/E@lPDJ+<h5!ta:<\<EDFW:=
51k\\^ FiE4Wpd@%iQkqiQW\TFAQ=bmAk!$FANhRSISHmYD<c6NVtw8ALCD6!Tc>GQ#w%IVRaRD^TmRqpQ<cm\u
F=LAXZ cmEe1HD1PaD\a\<lpID&EKDLV\LCW&#\myVSu$kptDwDkQ&pJhFL9WD%WKt+S^DlRJE+lBe8aD^=NiH\
F^kZ=@ GpCGlGZl!#$PKJ#!K<IJ1:Ge!FlwLVcPy@\+1BP\IAh%GP#PF8G6JHlF!8m@qpMT?JaQp=iL9KuC<WC%
q=c%Xu \DDalT>CMkqMIK+1HN^Wq1\KD@$+^PDJYCDlRJMV+ZaBJ1^Y<W+NFc^leqLBt6TkGZZ*BBEPFLyEiJIV
P9y#y\ J1#Kw<C9\eclbiHLQR+wuQI4\wt4<4q^<F1k!*nmn!$jV\Lc<5E88SGiMaYJ1?/eEGXNJF*<n@M8Hwmh
q<#a>R BaQhpCP\5&Am<jj++:kq*+FcXL<5HA@Y+$BZA!TpHq<FWawn4tE=yLJXKV?eLGyEHWR+$PRpInlbSPTa
A6Hw9y #6K<kCq4Pi>Ta=hW+XR1Bal\5E5JBCiL6P4pBI?8+&DT5t8Lw#IJIKA6H!k4AAuDC=NYub^a<HYeR9#l
im$Q5e p%N:HFA++biEE*<l5k<DySRk6+bYB>Y5mR$E@eRBRtBLGqBCAwT$yJFY+d*kKDkmDy#*51Rel@$JARbc
:TE&yb $+DTGTCpNR*C46:uYQA?l=aj:Q+B$\Xc%CC\P\&ESR%cNc!#Fma6SE*@@\uVBV1AAYXTWHP^X^c?Pm^6
XjB%J5 DdbCDXD@IP^R\eRk\wHCytRE4^4/VSiPXM4dD^:6$k<i!MeD!8Gk5wJZF4:1A$9kD&6Ru@ttQk6GE\<m
C6i=$i uQILChw\nQ$>kYy18JL+p*SNAmJh\$DbI!RE$nWM4@I?Ba#F4eHGKcLWy$!ZMcNA>*a\DJcYn4D@AcYi
&nwBQn EBFTV&Ck%BQp%4@J9/Vtj^N@WlTJPLBPA<6yS?w$<8>=iY$bejwVSpkEklHCREp9SIVWV=mM@V%HEYwP
u*td>i F8EupB*5^S$aKGMG/eWhtI^jnabLB1jlW1@hjkLbCWBAhlkw*acIpQAKp+t@TVk%kQeV!E+A8/WqA$Xt
y?%5P5 pG=y!em9C?K^&LYS=KtMTTytnkB&T$5GC=5muKHI!P>VLQZ+GwB?T?c^LH!yH$GFW*=F?C1p$KWSJ?QZ
-AF9KX 000a0498bc000110333 Page 450 of binaries1.zip
tld+m5 \6kt@KR@AkwH!4bBFw=j#eHD4eHhII9mq++!XCa:ARn?CANq&^ARK9nkXdJ61HEC<F%:/h!P@$t6BBXP
C\jy:X ?mZl1%:wW*B4PeVkj$I4ARQXRNp&mIF1!t>/?yQ/ImA%WL$5HC^RDbS6k^TwJ1@/L8<cVIX/VWWNt!+L
WScqZ< B\1dp4G@Enaq4=l6<&?A$#XpdFLDn#?l5pDwjnJR8k$iAh%Q^1:K<X%D9k%%n<Q>bQjnkhn>bKB<G#\C
I6e<\8 8=?MlZ=ViIV1HFK#GZ=AbeqA!wEmy\k%4tV5c6ec<Fw&V<KQHET1eKBZB<lA&Vy+lFeH!EAq:DmEl?*J
5B!m>j RAp*!K%Zib1ZR4$uYWM\DQj#1I$DmlPReYC=+DCCePJ@AG%ydZ<CdZE4AY$lLQS9RF5m@D?B68S@#/cl
>R\<1l AY&ZZ:L@9\C$jTtc%P\pqlVS+$?5FubDF%%X!BGNXtY8VI&w>@DENdLdS&uZtMkJJnPn%CT9iEw158qi
BwX6^I XVWVVZJtXyELVVGj<KbeiiDw9/<?Tkp8a:k^5J<m+PJS*akbXBmJnk5>y>tCh:@ceV&K&XKM8Plc+$\R
@%Ai<H HyQiY?=d:<Ak:clmla6@kTEIJLII!Y$Za*<Tw^$dh5eeY/DipE^=nyq<5%tcc!dFTJJ=c^yS:QnYJBKD
p>%eML ewP!MwF#XLeH#YWpR?SYuPpybanNXi=dS%D#dX&*T!#$HXNVRW4ABtd/AyNP=yTZt#dF<TSia8GR4bVA
yTmHZM M#EEG1HbVnuwMM6^HKt@Jdc8@aX+GdjJcaET8#L*bFR4:<Y9heZS/GcW@qh/im/HuCcGPG#PFMQN>=@*
BEbS/c +!5c+q*SHP?%uFmWI>%%$C4$/T<amQ=C8^?Vd!/1C<VtqqpLmy8pF:^ZYH@#*lhqWdNN/MSwE>pWLJj5
dNtk/A tenak5?8>ea/bne$T^KV!::q$19j$VHyTuw?\J^dPCcwW<lRIlS4X\F>cih1d<J!yb^\a%NdEDYGP8iV
P#LPbZ F&NRKpF5pRbhN>9iK*Eq*ScWM@@TnPd$jP*GhW45jE!MpiHSh6nC6Ji<aNZ:Wh9LJQCG@HbV5$cWEIc?
cpt>yk TmZaMtld6mt>+W!8uIuF6:%@pc8mAnj6=@^&8RBqEFVadHSGVIJ!MqjLF<&lw8Zn4TLdy>B>Cldke*:<
d6q=/m <Yd^ccZQ=&+LaQpHyM:$!y=ydl@1KY:4G6m1*5\@H1A+5>A$j&caWQD+=W:i^?=uR\LeSp<KdDS>QYKd
X$w*p$ 6u?G@Xt&ZQ1Jea8?pPKM/#8$DWyhKIQ#F6j6M#VbBEa?Bt?a:ipiKHK>T*?*+G55j@8>%8RdHLPWp>#j
GD@&q+ qhk/H<>*wX%NDSVS16Key>K5K:p8C^eXM?YZQIYQ*C>>H6k&yX>Z:X+^bDZ+q1i1@:Na@@!B@ciunw5L
8#BSPy Sn&1&?jldN*<4wh:qP%%YDTt?!TnQA@<wi!9#jnljV:T6/&@*qjuS8ZiH4Z&MA<c=Rni8Z:QpeBd6+4C
H\JKIw 9tA\>JFi#<LH^1=j!Bh+>Yy@%%<iTu54Jd98nCw@6hQL8/p\j@bIJ1VDjc4IuM*ka6G4wG/@Muuui&p1
VQmnJn =iWB81?9E9n:/+W>T8SQ*dC<WKHQbJ#*IWV/\!I$L1HVw#*F>aAQ#pW4CD*<<5?8G^VqZcnLuPayBI#9
J%ZkbG TFG$p<DA<FiPRCt=>:6MDLucw96$*4b^mA!k/pTjql?Nc+k+:XVGedK>^5hkTydA@=&N<i^>A:6y\S&9
t\^I## GVq#BIlY^b#Y!1djJ#Q$XEqqqHjXyN&=4Ym9?QhT^?=4EhAmWVeT*i8L54c:Q^h$6A/QP@SF6ZIt&?4L
F1Giw% *=!SX@ATX:!#i+\pHe5alNL9h/W@!i8ZtnYB::GPDS@+wBia<nqFb:5n=*:hw4AQ*:49C#K#/JuEYpTM
5ehtyy ^5pE=6\:N*+*%eQydDNLuETpnw?%ka+i41^N&Ky^a?lIVqh&#ql#yJ1kkdekG!G/n#CS*I>9Duj8eCN4
b8%6+E =Y!I^lmQVw6iQX?cF@*E+&GdYXbe@eHu&WbTM6P:FX1tiIeZm^JNSmP8cm=1uVqec?p>I!BVt+l?LLNF
?AL*YL n^A^q@P!m?PWd4&DZc^?E&T<Qli>Q!aY&+LXbA1XpA#K>uepXkbkL1bhb9X%=iSkiGI4tCIu/MIc>KA%
tc+&8% P=j!JIcSSXw\M8QX&aM=y6c/$#1H>&md:*1\GC@8yc@cQZR&=JI?k@uXuCy^j*96yD5V^e!hP$V\i&Vb
58m&u4 E&9D<4tu$J?^d$/#q&6hw^e*t=wb/9B!S5Zbd+i8QZp1GNcI>>q?KS4?TD+k&*e8:RRb::/:p8*PZKyb
YA5dtZ 15&qB@@kdL/Rn?jd+F6nFAT6dkiZDS^/JVE9y=>&%t?ZcISmLdyN=ABnAlN:pP@ni*/+YhNEj/*\Q4$:
\CH%w$ C1@EFC?/jc^=t*b9\iT1#BQn&YDV8$>t<69CLLA<BSeaD#u\mm$aHJWXHK4:E8PbpV8HCVF=cjnpi?dn
JIVQ>p \*<EnFVpq&yN&@Lq?pKYy>?ai>!$EQH*V5GW#Jj^6wZwjGT%YJDY&QJE1GHDPFFbu!%bZ!ianXHAXjHV
YSEFjc &ceT?bDA!!Sl#qmdE%Ew:KGl#:+Nu^N&t6:dD46X9m#9!u<kJ/*?6y9lqNQWQ958ywH8qP>C=?kmeiY<
VneZ$? WJe5Z8\ahD<XI&1jjeCVeKj=eWH$eW=bi94=%9qGW$Pbe+\?Racin5i6ZkuFMj8WF?8i8W@Qen\^&?mL
F>Xin\ jw4Z\$JGY&jddZ*#X^L&6c9QwK6:@4=W?b4EKy4F%eX:9miW9NBJqFC/iIBd#tHCmm9h@eCDcGp^q<Qc
ZlGqLk &u&P#\ZQc<V/!^=VWWyS$Wt?5!X$pMHkbZ9>NShdR6b^/T*D?deWZ&q$H&n4QZyc#y#q$ccK^DNC<5=t
?%4&>: @iPFVFNMQLbFL&^<m8SJj>ta!:bGMWjFCuq?9C%Wp96K^PKG@j/JQ>+><lIp1J=XM*CLQXS<u!e9**4?
WF>B+W SFyC!*j=&IWu=><@ChE*uA\bta$YRw8+amd6n\=umBVN%cqFV96bMZJ/LyTYQDc:I+PZ1?8ICqCVGE=G
!D>RHk YWbHXdbqNN/89?=*WM?wkMhIPtBh>YMGYY?XW%FuyQS!VVj:Z^N\1V&W:cihec/adN8#A>KyWelYTS$9
i6+9mD %t\+V:cypunXj$6q$%^umQbXw!eLjI:VJa%qtjG5J$\YuuQWbDBbdJiB^==8%^wLp4BQy&AFn?\Y>J5R
b@c1^Z hkmR=!Z$KKNuGbReIPF66t<5?Mw:?6YuH1h86VmuZ?+mWH<l+y%*i$@+hW%&S?jwiQ<FnQBR8<w>#YMQ
PHHNQt =4/>C?pZDK?y%bVXMWmwq*a8u<KeFm<yCQ#+>w<uHbb8k>56^p<QKldHHjD>+>*dKt%=p?6*L!a<hC4a
<S/!=I &6jBe5%LMLd?+QGSChH^kC^aLMp9+Xn#YIlIk:hwh!^*l&DKQ<Tt?JF&+#ww&$41W4ddu#Q#/ZEPW%#?
%Nk:Pe Cc%HFC=M^WhE4>8\S#bPy+?8TcQ94L*#4HdKwjBRWZ8n\$=q^n/:&:yXc:5%\?m<^dk+l8#uu4JmB4*#
IRI1cT >*5Z>6adwW=Y@K*JIDa^$<YBG6jT1t?N8SJVh/baRH<!Ru<m9PHG^C+bk=$5/cE!Bn45R9@F*yZHNZH$
\*CtN> jWVFw+CIS@GwZhF/wJL5qi^/ekkKekq1QbGRLCTcm$*CadZmmXZ\%5i44ThXFA9Yww@cT1$Hc4X+Y@Y^
yuXe\4 YBZQX6T1Xc8?5!EJ!i+RI*$@#@9Q?\<pp>&b:@^?M:>4=neVe@B1eKXij55@9%H&tAd6B@$wnpuJjJN>
Ftccud ?+F?TmN>HHdnc8W>^h*T8Mdh>/$w:?t6Z*mkccJeQ#1%QPcHk@h@%/>y+Du+#eJJWY89D6SQZ>%Fn><L
VCwpKE !jJbe:VdV&e*HS91WhR=#Kh4=MJ4pW9Q?@k<&::$w4duV#=*VcI=XbXJu=:5kNeuL6^cimJt==Y!:jN/
iwtLEw ?M?e+Qh1@4H<mTGhk8K<QDL^mnL9LX%?X9RiFYQ!dlSI=<*Y^iR$c##>&b\=/mV6mPmCm#McZ^9<+wt<
>4/a=6 :e!j@Sdh/H6FnKZLT\IdmV*8VB4%<^hXie9uXY\PKb15@K4^wI1LW^9$d4lqMS+$=!\Th?NG:=8m9<e?
!=6P!E IP86@!L8+Cc*:jM9Db+d<N8?m$#VBYuKL<8:NG^\^WPZiE8ZHHj5ZL6:^#?a?PLC@INMXYSR>PiN=Q$9
p\t1M& NW=69&l5huF=*MpY:1l/deQ+/HL^Yn%^L*t\^*VJIw<ijphuD6k?@h?#T5b5YV#Y5&?\1C\w9*?#1L?9
\%F<he uk4@*K5KWj1Lb@+=5bttYcD:Hb?@qnG48n=K@C96jMEn9@mlX=?np=<#dKS8VZK95%ZFV^@/WpXyT@Gk
EY8^#P 1%/^6#!!k\+MGbkbq#p&M8tl@54aSVhtQ@LyqPLj/ZcLX4HB:VWK6T1w!/MDQ@ttj@@wp\@KPuX4@6m@
D:\R&G 1Q</SXHXwSL9^c8>jQcXF$b<FC6GFJ/TA4SL<+Qj:bk\&eQ@?Dj9ha%9?hiP1@9nd?#FE6Mj?l?1jP::
:T$FDT &i5Bh?dG>I^jZTAy?dGZ/FnK!E*#XW*%bd?*<JmZLL<l#9j6!\a>c6B+lL#!$/k6ZV$Q6yQ<Mh+n?@SZ
SAh?nN ?Zp>qCy^5>i^aZ&@d@4a?<=9<d/y!L\Kn!%QL$=+XLDne5jW$+EJZSdPPl$+6KQj+6!1lY*HlDe+id*L
hNJL?p aK#kVQehK%Q/q^>5*/SRe8V?pQhtuQ/Shj<tICWpIKC+X#%yj9<NSd>T5$+i9*6&R5\Z=\4j8J$?Wc@L
kHyh@6 +jAFPWF#Z%^I&DanTNPuW$q\dMMGunKSV$V*%DamZeB/dXJb9Q9I4b=ZC$SN8u#m8hH*$YjFZ84&?KNu
j%4D1F XG#=j>A<QLRL9unkmnJV$@LFR^56@cHwS>HbhPZG!NZ%i:XLDS^eq98J:>HkF5%ddX\%/YlIZM:S*l6&
dcQR*6 8e8Q%9jy&e?+eHQa1wJlY%wF9HIje64$e$a#+%yE9d>Z!/*w4hGZm/?EHW9Ti1#cP9j&%96:6pZ6/hjk
ih&89P m$n$NK%h%#9kp9n?RXNykVcke86yXVV^%:bDj?aW58qDZ8#I>ZtT6&I%e8XMIjFH%NM*uceGVB\u*b\a
Pj*^wA *H*LkEM41knq8wZlSRSXhqmTYT^1*9XD5n6S4E&KEY6jG@ieQ%1XqKRi&9\B#hLB8G>E%MdQq**c/XGL
hVn4dl pBdIqM=46d+h8+pquT9n%^Fm*d!A166jdCK^5pa#S=diT@l&+M/98u#:Z669Xi*V<K4RdbL<H\q==@6F
dnjeEK n\4\dXPw&CVXd!WnRlW=B/Inq5&<jjcLm8TTkw><Je9e4^u>E^85>YnbDR%=EZ*/>1EnqXMc*jep4=FS
ywVk6E dSyFJy/bedKj/IFeu=#YI!Rp/eh^Z:WaX#l5bc9$+?j?uHBkTW@X>bHL@B4=*%ejjV4>*M4wY\NGQY$*
65KDiL Y8XbGub=>J*Y#:1+J!>/MWaV*MJ4WMDcwCbwkYyuK9dkLL46#ymEw$$Q@uFk!ADj//i>ND/u=4W6Pndl
1A+taY hZty>>yD@ZPYieY6L$p/ymlR>$N&J\eY9Xu&i+?6qX@QidVu<GdD61*$R8@n4id8pXeG?u?nT>kTjjVN
mDRpMk 1AQjyY+h&Aql^bWj?lY$tXA!>?SbY6X4aEuu!t/qB<=5?j/Rci8E&LX@@cSA6=iNTj4S<?TM@w$iZXX*
Yj6NaH c:l?q$hB\C@uk%nJwTdqH*6W4VkdthmQnKatVP</??Tq>V9XP=J9F#*S6##ha<KeHPYDWhwNw#aV@W\d
%bVScm Q9SHY>$NHu*/@mK&Cp6j@Hj8$/JVA@>?M6R+iDCY6Dc+\S?^m^M!i/:QcZLytKFb1@pi6@$489!&4u*4
wEywGd 6EpT+@CAuj9#M6wjiK=5m1a>C+<?F#Dl?ywXliIDtlcNVnTI&1XM*dE=L&:*pE%h<6%!Byk8y@i1#J!d
-Ac4$\ 000ed025c4300110333 Page 451 of binaries1.zip
Kd+wi4 YHT+#>n!>MYN5p@eu<ww#@p%Vp>y<16d!c8WER*\kBP>Qa=Q%R&QjNJ#LZy6WtF/y?6J+<I&bPiQu4hn
:XbyLk !VSFk/?<Fbu%?*9hYWiPPPK%Ak*I<eWL&/:*Hl9X8YuS^eLE/Hcm&LadF4?be8#ymBC6/HDe5d^^ESh8
K#JnmB j@hd?NeLW9N<j$q4juu1p+?!Q%1h?1jwE@Y6:qV#?Giwln\YuL?\<RXm%j#!yppXu1Ju<%c5d>lA?y=*
W:VDYi W8d8\^hDBl9<B$YGj^P^Y==EZiteE:%ENNRu\>h$wN>R>#M^%?P*!c>K<y=?jt#8iQikT+W:CteWFJd>
&w:EN8 dTw6ZNak6>jei<G^M=c@h#lu=K*5=84Le:/jyT6ak^5!9t1b%tZt%el^E>+@ul\@9@StSet5k*NDauSh
\>G*\Z l5>b9MD@YiTEQ/q9R$pS8@+NMbnX1>ae/#p4N!=$=+A9*P/R9\it*im$=utQn=IH^>:L>&n+PPmu=mP#
Rmu#Aw ?n+:EL:BjhDcql>PZStb&KI+==B5%Pl/j649%!$qZlpy:>a@Lha>DZu?:beG>*Nlmw6HH:cu/dW4L1<>
!5hH#q Mi#:+bq:9p/R9d<^EVB^?u*6^Yi4H1c6HGJeR1@Y*Pm:=Q$yG=8>QqF%@!@^?%FSY&iQ9HLmait^*k8T
PcJ<RR Hp:M:@b>>C<XjW?%<jj@P4q6h>@l^hQIp1Day@%/jnS9WYDS?Z*KQ$c#w?/QYZ=b&<Y@=Q!>q9N84a55
K/ZJeu YDh!@Mcu>VcJZ@VI&B++/j/ZT\8ud81<@Q$&K/JQBi+K*:m#a8y^a8V!*k%dJG#8lHdY6B1dL=%5mnZT
N@K?\! &/yYH1^/$V#?@mV=k\D9*I<<F4\@<Jj#uqpZB6=b8IV8+HW*nT\>WKK:@VBnc8K>!1YV:y+d<Y^&&/HS
1H>9P/ 4S5<L5#d>c>t1d*dGq+&YX?@yFQ>!p?@VSk#jMea6ecp@*l^*J/GuqJGP#%CSC&:?b<69h>46wqh8D%:
iH?K+y /cT%Z=:9ul>V6Ljpj5ZN%V/dVZ6QLGq>=E#W5&YjF4pZn4uiP9NPDlN@+6V%:hH1w+e*@>ZH6Qi9Q?/G
F%4\tW J%:aFaCY#Q>q$@SNn>\Xb>aeL&6/@9KJya58nj?+DZbt*+4&:Z#&96<<dubSih/P*Ch6L+5X#\98:b/:
>Xh&Hb /JQ%P^=WBHibZuJ<eItw#DQw4nI<9i^E8&EB?mQuL#d41\<>9GA:WY><\&Kj%54Hq^=tBVbee9MZ:#Y4
%k=&Hw n4Y49@6t9G^N@cM>Kn9Q!#u/d&uW=JdwQ4@TK^*Yu*cL%&#wiT?@S?SQa>wMP9d\$6HL:***eFdST<t/
Li**X8 =ZPT^y+5YZW/NH@Y+YJ^TR>Q4::GJjZ:b/&cPZdDLcc+Qn*m=c/ZD:aa@RLV/8@i$&d?nk:LH*Z15GL/
KiQNV+ K@44Vq&/+#tVm\h>PE:T>/9ASDct@HWcZX^!ZF*FbwZ*j/QZNdu!cyF1h$tuM$j>!ya&ih=/?K9V9S@9
C=y6\u d6N@&eI:4h4>*HZ8N&i!<pI&Mj:y@5u6k#<eG:/mcqL$W>GFZeGj>QBjJA=Ju6>&+?eSymdLS$+/M<QV
PDZ@Iw d<*CEWZu\@G+qch/hXm>h?iEqEbh?@=+ee&/wSq*8+y!89a6VG6*y5Da%j%<t+IuG$?N&uyyha5jbuV^
\:jLKT Q9cJ6MtC!/cdM>yH@u$b9*#q5e?@>l^wQNVnWpc@KbZS$c%jV9=+q:h*\MN>eZtLI9a5&#S$b6!>c#eZ
=uEGbJ h6^>69mD\^Z=*5ZZtn?mb/Z%&hQni5:>1XN8JXjt9qT*GVEtaPhL$ctWL@1+u\$/Ey*=iQYJ9MK6YPtA
y@1VpC wij&:^y<>\5&?5@hX:Vjb9/<&9@K?Qmq%<cT=JnuN<ePGd^4yei*@hhI^1!T=G@5>MHn9E@H:+5+H@n/
G9=twZ AZyX5@@$=KALjkuuP*ddF:S^FX9b/61+*GhZ+\/t6kl=MJ6cWZF/ehcG<9#M>atXFd>N*yc6uib*L8n%
k^H8@^ $\S=<jmaV&d@VXcFHw%JLFYe@Z*w1LHW4CHLq4XNa66*@t*1<9Z@Y9/p5TbudPmEG+%@tWV%i:+qc=a+
!kywm= BK*w>&ZkZ!*YLA5MbjI?%/iWETQaBnHB/#9jcC+t<GGQQmq8?6G55Qj/X*4@9iHKtK*@?9iCu%8wQQMt
V@C^NT ?+ZE8AXQ\b<&dhNl+N%SK+?Kw?>@NG9p&Ed?dymQb*kutd/eSRLcBc>hN:QdEc?ebh=Xy+K!++iSwaQ<
LWy9cP 4=YYB#jLPTL@4h:cWt&ku#imH/w@1&p/P*TnGK%Z>4Q9M5?p5MF#85Xl:eLqTi8:^:i4B#6ZtZJMcQ^9
4$?FyC u/6MPTa%95P=!kR6QFjbil1\m?e1W>cDmTtM6u#AWi5H*Q1B6H/RYn+RJP?wZW6kZBB!F&a$W^a!9Q&w
N><mTX ZR1TNAq=8=d4JTuI$c8R6&6b=cekia?R6<uc&5beiS894Y*eqdi^&6wtZHqdZM91DmV:WQk&Kc*6dap4
8L&?@I d>h!9BIFTTAW9q*4aV$WS9&jLW#^Mkn49CET\:m#d4l6FSnCdXB#wYueyYFi!$t:FC?D5M:A#ceMtR@4
Tuwc/? \X\<4IjCZbwn6S#YR@E!CB&AT?l*Aa/c>*Kdkd9GdN!qCXddKmSP%4wLl<Sy/y%!ALtdcM*AWhew:545
:cS?T# qBC%WX#1hE?I/\hTAbcT*J*4ADl*J:w4\F%TI:YeL$nl41kS54abRwn@$h9wQ*wd?$h9+@@wdiIj9W$/
A15^1> GT!pBH8Z5:T+JAKW!#>^KhiHIq#VRZR6\KY<VRKW:Wdd&t?>6X%$K+yBLJe+<G1qlF5E8M$^@*@u:j@t
G?EXEq udj6iZji#9TcyG*u5dqW9cl*WEK*QupmQ*%L:&d6Z94PS1p4D&hjC@4ba&hyuPJ>n*W:G4w*LG?5c#\u
pZY$&+ 6>MHQu%/19$jHA\P896+XuF8bHuak&+ujS4@QD4!bP+/6@!uA+1nG4j$:NRP<!5N4u?^dWQ*jajLI^/G
GRQ#ZZ >n$hZulk+QYa+QwXu+ji4qC&/^+%M!T@/iIi?&d&@&H\b6K@jMPY>:=iMQP=y<ibT#G*m=ITeniZBe<4
F+DSZJ D8q$qt\?yHii8pt:uI::&LWB%:b==5%h:NZ#8:B6<*:\:c6yEN>?@:uNR>@j6&nJ+Vdj@%R1H^8Y=%bJ
y^W1Zh Zum\5YJt#Dj4$/eh/clZLQIw>>SZ^D=b&C1p@M<w>L&l5j:>&+1YF*\>Iu:u*1%Sb>L@$$h:%y5M/?>S
%q$JAD d>uSaaNcu6u\Mdy8X4H@?Sb@Lt4?E&5+$lLHW:!qpZIei=VZThFIH4/e?VJXK9Lj@uYuPYhjqI!VuK9Z
D*BcKj ie#TX&*C4yD^!>n4J%PC:t^bimnSL&HE&bd6#9\!@e=Rn=Lh/4\n!$b<YnJ?@5&h9^ijuP@S$99/J:?M
i&b!RL >a+1Xd!iYZ@9^Wjj1T5P6D#+MH4=q6@8dd#46@X5uGdX/PhVkwQ&JPhH+Iq6?9*kKS>eie1aPtyyZ915
Mwq^L4 iuu*%q!qL&%5jY9h$9+XT8u=##1PK?/\y5&E?6wi:Ra%Q%jXb8PTy@NYnh9%?/lN8cL??T<>P+FB/:*E
//Q?&1 M/uq1Pd##l*>bY?4L@!PZGQ@cn9:nqk%RNEu=eK81ucL:!^=?lpbi!Z#dQ=nW&ZY%%P?9@?*i@t*IV*a
RiGT8+ !N&:6*/%ji?QpYZKY#q>DmX8&qK!^Ph<8ZhbZK>JIRST$881:<wqL>i=VXVh@CRlN*>K1=q#M6%QH&ya
>tHYFP :>8n>V@KVq$%dcXHuFjlq$VmNM@j>9XhY+^@tdR&5&Kp51</iJ#HpcTLpZJ=I?<:L\jp/F?9@Ec9PNd>
hn%mIP *@</PQ4u^D=@^a9Z4hl*?GqJ:41Qyt>G9%+%*TewCP1uPtdd@6j>XMh$Zhj>XFw19Q?Hq4y\@+>n/^BN
Iy+N9& TwwF4tR6^k9pHG@l&:Y:FyC5&*h/*WGZDqMb%R#TLY=RHQK^Cn!TaWBw5mhCW#$StXcB^A#4d6GaRQ$J
ANV=5q e8B1ZEa4$WuceyWP$D:eEADNpSAX=Jm<c<E\*MC\a#FMdEAGtXRKy9cGCV8QD>J\HM8pI=b?&kPB/WLH
VKwpLW QGALpBEMc%Dy6IkpWF\:CN\8hhEJCNIBBE*D>8\=JkSdPeI!KVK=HSXIT?VDQ49bBRm&J1%$pFnyE1=m
?APL=N DYdCYKM$WVLH:/E/E/m^F<1HT$HkD6bqIEahIkiVTkcMySnGtKFnJ!LBBwNP4kIV&tDZEhJbt4c6I>Xp
Q+SI@^ eRBKP\KX+I=ATV=RGkI$%GR\/nVA!kGnLX*qRGDT&h%Hh4kwHpHFEJ+/Jn6d&l:G!JXcqX!tSk\t9X:H
hkGCRH Gy$%#yq%Vl1*DnCcB\cFkWElaIR5Rw!5VKXXcXQ6aNGC!TeS8\DLTlMdLA\GC+Q^S/jStMW!J*=TGEcS
y8i$?h LJNQhAdI@6k5J+BRHmAeBkmHAALG9^tTkqEk<a^MAilneIaHe\$QqCA\$a\mEXwn1%Pa=KBqBAn1t5aq
i@eY<P qk9a*qEp%M\5K#Fw*p!VpL!bJuGecSkjPE!ij/!WGc9q8bdJRFScDn8TDyP6\u/RWlkSJV!SLwGJhIpE
EW:FQM 1q5E^K5?&QQ6a5nY1JX#JJ>aWl/^1LeRC!d8k=E$p$w?EhGqe&KJ!ZCGp/Ck^JH\mEQBmAPV*TE!k$1P
w%^bt! GI!M*wCp/FnEBCEYS4lGLAtQYDB>J+HJbR\b^BmNZMQAAGTNnMK8eeEee&&a<+iLqPJ^Vmy&=J\Whe+=
1%!+y4 KW!w^=8$YmG>BJBJ8+WFP*4^^LeWJ4/q1LMSncT\Pw%XwRAb^YlpKnWm$?9XRNMa\X!#p%cW=VLG6:KS
cW/bde h1TpnXA&!tE<!pphKTjlh\F#%kXShES$tDPW>qh>%cCW<tT/FCdVyjndmYhWM6\Zw$/uN6lV#k/T^Y%+
ynp#b$ G?F5pK!E+%uDWkIGpZANw6XAD<9W1*W5\#1D^^$J/kI<uAeQb1^LaeI>kXE#e9N$bSt=T1@mXHaNHq1M
9h1I&c %w%e@BpLE@BTtIAjJy9IkVEw\TTRt=^nIVGZ5JA<LDBSJyZCuctJVJaBWRF4GFE\KeCt+5%DITbeR4mC
lGRSm$ CWwQtE#Hpil1muBtXFmtZCuVyuJjl\Bkhp/NYI#XVdV!=Ba6+R5Iu1%Pp#!uRmBdaWwBwPXeCntnN#yH
h#FpCH VeLJ^:QWKbmqV5GE8yX+CGApwyiyYQ9YMcq4k=6u<pq=NKNk5y/C!jyRqyEb1@HwbRcDZ5uKDA\RCVIn
maE1LR p1W#ISp1$DVLcBlN54%RRFEZqVajKMW#*mta4W4BJH1\RtGB1hRbhct5VK<EqpZERM+%BElbny#&ACXw
Ek8ulE *RD!BD<FE@\W:w!TuEq1MCXQhJ\PGIdZDSBQ#FM\MW<S6a#\BKB\#KcQQSIJYVepQIqP\TR/SWIDDn1n
GLA6>I ScSdYYXQGq^kl64jkipEEE?pW#ASS5FE?pCX\em1pp$%pQTtbKCc?aNI+D^\B>G+AI\u*!t?E$V^:H41
5dDn%8 LZa>BhMFEX1=&1TA>IB#mGScm:YtaR\GYcy>!I5R8#aTKb:XV<G5jk1tIaAXAZRqDBta4DIpScX&nwek
SC4/T! uPK^WlttNTta4I>NNqbHH<!&Vk$eA/JLRZTknLWjnkR8469<+NGL^uqey*p?kW*#YdmP<@yC\>TH%bY^
6*!4ZF :+ZbnK6YKF#w!WFTC*6DRENQFF@6\qRInha8tRYAHMcjA+FJb&e*R!BbCE##qAeNW^+$VHqEcK\DWta@
LD+VwY Gm%$++>HCui!k<pJQCnFeHkWYJYTbS&QMlQ+1#Y1=CynFnekbV\yJMTDT%&TRu!P\nRHDhMeCcyW!G!^
!Y$8EC k$ScL1P*5=JetmI$V+ZRMBXCp!+Pi/PT%bqTqamSNSp+>%SqCYa=VtelX6i$C=^eMG%CIAukAc6FHM@I
:RdIAQ GXY/Ph4A!E$5k+S^<<AiEC/yp&HMM#t6l4/hjHHWK4Sa:F!4$DC6E1cX5%q/w:W*B56RaN:cCbKCLJ*W
-ABt8p 000a9c6a4c300110333 Page 452 of binaries1.zip
8V/hC! YP>Y$H^*u?a6EhD$Y$BV4wQPWBtXLwa9WFJC8TV%?Y5iX4!PIGuuIK8SAGYaCpc\*1!GaL+8KpWq:\dK
k?*Vb6 Pual1ywY\>VJRMcBe8p&!eSu8FV1Iu%+Yl1&LEYLaZ1ESP\CE#4YPu*CkZSGEw\/%6GK5i+Kj6hbJBmR
DWtC=t QQiTFtP<YeS#L\q?Z=#Gu#ktM>YMN^NaWW%95<+^PP$PTWKpXM&p6<LHaiVFuRl%P^VeX#PR/ypmR\!e
AnGI4C 8?Aw/#G^c+=LDVLL+1Aa+!EqaEmh^/e?X8pbnwIKS5$aGV:SMBSD/\aN=$EnahDIY1FbkuyIPM8AwctZ
?d$$J8 !Sp#W6c<VKqtkP&h\9%mMQ?m$%bd\R1XacIDiJKwG*kwHYF/TaJE!:R!Y&#G#QpEm^:q%wAb$ILekcBa
kFhNK8 *YI&kqGJmjtVm1icWQw6p$wKnb^aikN^ImHRwR5>NjQh!u8cD=Zm#Z@uc>c$GKcRlqYQELPbptGP4hyD
yq6S:W ^VHZPA<XuXDXpmuVXD5+b8P^itqM#?4AtDT1HDmMm!uZ&yd\PP!w>tmW6?BBw&Iil*qli+4ZD^TtnSL$
PIX#l1 RA6Y/^<bF>/WthSGTJ\M\!Ya+L=\G6aLtweca1LVKP4WSDjwNI^P!%lwC4GGMRIV8$bVS+illtSYhBkM
Gw>>JP HW!>DGJqY9M$Ny8?bt*JWTqhyqay?JaNS6CC:WNm#BX+9EtN\qRNm5QDK#JAJ+8!adTYL:\bT/LT8yGN
1c#AVQ y%lRtEBECcm^A>TIdbd$NN8JMmM\Muwm=4XJIMEnBnyF!B%t/RJCuu=BajwFlitZWG5\*T#m+t\SYZ6R
\C$w9i BF$*5lE<WBIaKIq#:>pe<dh?G<Lny:TP@PS6bEJlak?XR9hQyP61k8q&WCTRlStZGAiqCRXhyDLcBdnk
I6$@cI !lRn/!b1?WKLlwGmwcBp4F^y684AiPaV^b4N>6dS#MPD\y\JDCc?yb#P+?\e?%by9G+tBW>QE:\6Y#TG
j>Ma@N PmweAuP/ba9G$Fw&pmA1k^Z*AKjA8VQ!lMA^ulVHaFIe\?CLiX!nTAynFpIGy+*n5D%dNa%d1Id^DVGT
Mc$@^e V#ZepYwa+hVhynEeT4W5Vq4C1Ec:1A5^ulDHaEIek\cu8D$ehqc+taVA%pqqbSy:ILnp*aBaKRnVell$
Eyi$IV E=KPuYmLMqmBnNCyVSwHX6KWm^Vl5=JHIb#91GITS%dm@HXRMd<ZE8eLkN#CqdWj/ib?PP$GKaZNa+\u
?SLAu8 #VGaNMip#uTj@XJpDRJenPPCnT?+M\SYR9IpCRcXb=TVNWe8hWZLdS&9\YY\B!b^#b+ZAPQb%BlM$GM$
^4DE#\ XQFyhPuPTEWJuCGTeAWSL<TIR%c%cX#5FBFw+/$EE<DDyT+SnKebebk=n>i!SmE!R\Rmw>1Eh#SieBSF
L1Fd1h /<SDuCj>ebn$^&HTQ=1dyhW<4G*T+clk!PPW^BXWQDYA\+RcZ99&JStm+hA^CmjRlC+a:SI$9qmDCZ+e
YdTFuD GldTcq\lGXXHS9J5hl^t5?Ppe/eXGqYBRML6Lp>^AkqKGkp$M1LTYye+c>XE\IKk//cJiCLhbtqbNSHP
w$NE@\ m?+R1HNVDJe/t\<&5<kethSyAdhbMHYBNPE9dpJ/JIGcTVlQBiA\FaBDXaDJ1NMABTpHem$L$jA^y46A
n>qZX^ bAKquWG!My8uDHCaM5By/B=d8hpPMith\ZLSc^VA+tpEA1aSCDE$JtZdGja85Aky=kw5umakaJ1ARJ%b
Mb#GRL Gb#=cFBNa11ZZG8XJ=kWFTSk8+IRVmnMci4GRAbMa4W%WC5*5h!KeKlPc%AyGJaj%+Ekk?/dEE^ukTFJ
D=*Hq= <H\CR8I<PE9AFEh\55=phMbyAXyeCnNJCJ=?IGBCpCB1n:tc&:e58ZDyADJ%1k+RW1t^B!MMmYFP\Xmb
!Rmqm$ !qMTBE^JENA6WDYd/>JMMnXk4L$>lLpYqBZA+aX$CFn+kyDWy4P+bCH4KNP#nF^tMk<^^Cmd!GmS=C!l
Zb:LZk N+@nKFa*yFBC\dMXl4E/aKI^B1XPb^V5j5j^8mYtCN^$A1aCCGkPA$Ap$^1Aate=PPFt6SVCGDMaRCXP
\W9$n1 mpVL=El5kuuYY9bS&?Eq!Lw61SA<jWD!qT:l8A&YJy&9>6MEQGJW9ZHB6lHe$linD6aXmjBcT%kAmiDy
VnHND= DBItCpt+F&HhP&HhpG+#At4A&TPmKJjCJAVFI!=@$ajpBbNI%QtmD\qVLRt&uRdB$D$GPCua/AnhZF\L
l%&^>V \cAydWmeW1XGS15$GwdX!LScnqTPE+cp/=de!iimFPjVnKe&JJl#6WHYFp1KRDK+DcJ9^R&Q9=E<lWHC
&>l9@l FAdySGEklm^AQTMLuEKd44DutpSww+kyb$A5BCS=!pKC<kqI<kkwhy4yRpNVt&%/F%HInDJE46MAWY+\
eKVTCw J<IBPRwE1IMYqqCpK>6&cF/GM\*LeKclGe:XiLnbCwTtApkX4audP&:kAwaKSGaAK1ecuiN1EARbnp1e
11w<$R IdNTtiiepLB+E#RN8kcyba<mwqCqAnS&wKTCSYWJXN$JRQH<DSKtdJ\qP?84h$\LN%WcbSw>\#y5/Mcq
\K/ZQQ \tNjwH6HBCn=KkdtepA#uVtWCl%nny5DeI!i!?@qWk^VpA!qT1/5Bk#c4X/THGAQXmJetmFeAe5VS:DW
HF>KwP cB1cG5$uKc6K=$JVNVRFNw=e4VPaYH8:Z$1:68%FkBNGSGmYhAmV\XEI$M!kBSaZw4Qjd+XVa1p4i<?F
*+<QJ= Wwe*e&Hb\DR$QZ1ETc$Fdpc!CqmuDy5GeM1%nAEBFwHEp@BWllS:T<kctnah!5p+uWdFCST:yBZP@4Jn
MqTd1@ 4qQ<BC#44$cDYYpHW!ZRVPw+8!*8pBp1BIBlEteA4AVp1^CaGR*NpI:SGdt$Z$CK/4%VC9:tKh!/Q@l6
e>9pe: 5p&AmV@AaKwBtmp>R5WCJXD6*kInj+JMm!l%4GNw&LyB>G%DVaCKy\bk&eE$ND$/Vyqq1D++\iwLJdPM
6W&qPk VK/$B?Ymj!aA^XMD5L^yGyw*Qa\Bk\k$LnMckX\%PMXCR8MSAm\<aT?B!mucijcPLFYt$kIe!dyWE@AV
^G<$a^ XWB^e5QhPV=M/lI?94pJp?>TeT*bJy#\=p^jnWq6XQW!:?R\bBtMnIMlb%ZL:<^GZ4AJqpqNR#PykiPa
+jwaIZ p5LbqX1bGw\!=&BI1FZJB!Qq?dFTtH!H=pTHelESq=DklE6IwGTACi^BRL5cbK!>TKcyPt*jFXn:5K^u
/ZeVGi Gy4%HKFXMJp%CAk^VhWJAT\XuJbC:5dnL1n<@/9^*uI%*uZ8cn!Q@?4XiMV6EHja8YP$>B?en%*H\<bw
$=e:cF KiSR:ME!haySy?WPHLN?NQ?A&lZE!DVtDY*tLbJkXIi#VJ1J$e1#kBa*u*!hC5c<?YdQBL*PGG:T!5*B
G5R<SW WFE<MLRWjA!WEAQZTVBV=K^Kd>T^ZI$GPVejyDl*AG1wVD?aWcW1nicV!M^#!9^4L?:caRBGLW5%ACqm
6MkbXt IXbI>dqu9XCkD<EVPJjunCLe<4iXuPdikCtu=4am/H4F/#VAN9ATSSmB>!C9:k9Z1\Rk$EekFFj9TE9:
//?iY8 ZE!K%^9/HZwD4DCH*ynl%@SGY6MdVIKlkFC<HkF^%A5D*WLFRJQRq96#IV$K$cpX6ZaI^VD:Hpu=\TbK
=*#6\w @L@HH/uE%mNc$B8kY<^QwGJkmHQ:9t4yVZW*iQ$^G?>RFqH<WKSnJny@wpXwkC<i\n>en8bqlb8yEKaF
X%Tw@R IyW#VEAZXTuYyXj#pY1mRYL#H+#:k\64e>BV*LPk#G4bet?B4/V6K<=>lht=>wuZ6kNQCjFd=d/Zl*?>
E%y8@8 :G\6$ny9aH$1:tSVlh?M+EF?C<9TG8TGI8X#l8bi>8*wt^#!cQj$Zy$/l^#ikVWQtw*MtV:4^tJq>t&&
eimn55 ><4pka8Sca<iG@bjDbV$?d9iwA@ZZLu@=Hqq>wIB?*?>?!I9b88\LTMC#1*/L9*j+\59Vl#S?<ue++1m
:!BmPi $V*Q4cLeEu@h$8hmT@*p\jQ<G:bMn9Q^kplCC1LP8E6/ZiuYVF<9h^@QmyVkPWVL6J\RyGnp5LbN=bIj
IQ*B*p =\^ewh?*Hbp&KMJuldJdapk*u+P?R:M/4$J/6=?jQ#K6<^^p/5u^j#\@i*N@9/pLd5XtQH4%?qut:w6h
JIIk<h u:&<Xnw68MYh>Y=8XIe*u:1=%T6>qiVt%?Hn<c&iHVJq8*Za=!b/=8d&814i@186d:q%8PFYMt/::tuD
!b!Q/9 ehMtBw*XB@:b<L4:peLE8I4*^yS&eHhLuHc8aG<yPuw9=h=1/:#yt>%&:&9e=6mVCZ6HuSqY/ld\Hi$&
#Jw%Jq a>CyP#&#d6^<$D8u8V^:jY=9h!mFJBDGp:mLnJjZd=$:5*:Hk#%bBQMMZ45lN!ybPn$<ZE>S$*$ShHY!
Y$>#ie \n<1K9HnGX+*Dp=4wI$CyKw+uS^BBBuyD/KK5RmjwKwB?!@Yj@dCja:d&t^qN@Lq1^uSTd6?@cQ6pqqZ
=JcnCm *?mHZ@HPiQuD>ZHW^+MdQY9aeX1KY%^lV:eQpy1Nc:V@%!ebL/@iVN@#u\i^#@=#:CW:>YDbn4ml+X*4
96FDZ/ Rj5w4e5$yh=>tk41wIYVp+d=A@ab$na8AAS9=WK+i&P@m1BijuM<F1I4!wK1y>>TTbQ*&?Ri>FEGbS@Y
A=?1%* jPd#Ghw^c&!\%&Lj#6jynw*Zl9wMDA==bPYCQ?DCt/pDju%\1iu4PY@G:>@e>WZC/=ZSW:@eVAS5my5c
>YyMNP <tuZ&:HLZ%b<?nLn?\5QM4:LAu!yj#6w%?h8l@?i86@9\jYZV#/MtV#9%!e9V:?/N5YR:Xd9Yd<tX/?6
S\ymBG \/@/IT>uNGmYqJV>*Mj6k*4V/>$5ddQt^<eNyu:YZJG$QneTPll=chuPcR/EW!w4T\iQ!PRtaKGI=CyY
InTaVD d6Kp1JqMSGSW1RG6SB1buPY5BiAJe\<1hMALNT5RpWIFckL?A/nY9BwtpnMKqXw6R$SKp#bX^yw$cypJ
>LZ+C1 QKhLBWdKSQC##F\S1EHN^Z%BqeDAB1QI?6?LZ@C8@@>=BVk\$>NM\Mjq6n+BSWbL4BSCedH>V<qeqEtW
>tt#D$ w6cBuq9KFeuXyX+mS1%Y/VuCmBT!%FS8:FZ@B$<+pynL!XH1VAa8CmJK5NAu%cSTt>6RM!qeu&LD8DS=
ij=!/^ T!Qt581Q4Ftn&61&?\X<5@^wI\\aH#KDElE^t84@F8acYbtC$ela\B$D9*qLFV4Rh^IaX1JSNu/L14Qb
JM>tLD WApB8tNmYdP6!Xq$aJDwJnLcbBpL9qJ&I$Rp%?t#1m9$E8qaSRyn#qFm#Cjnm>T/XC:1\y&KLqJt/bWM
WDiN\c kME!1T4k6LPMwtaIKylWLyjPT/SZt\!kAlPw&JkBHH+8!Aa5H=FSCZ/9?Ywb%B1V?ab/pdqa\a%he:Xi
KFYNI? NiMXnM?c6\A<ne\kN/uN?DkJAu=PM*Gu^dHt#$ykh%9c5lTDKaAC+$wWdJqN\bcYk?&bHY!liZANXaK4
Hj:Z+# =$%\GCIK6aIBHwPqqnBLLYH&6aVX9B%liT:C<q!E*ZQAH16=MA!IRqGMyjqa!%8^q4hm:Y8Q6V=pN:jN
MELQ&D eST>Pk8WG6Vt\VQeW5X\T^ZD:c5aZ6Q81P4jkSlT/ql8cJuZJeHwBL@J4ILHWwjM9k/bBadMDwc5tqa!
#bQh!n Vp4bGMhactE56VD&6VA%TFVX#*tJXJaHXjaQ1twibDlTcT*N/!!%/!\9/S\I4LM?XjP&RyY8MlhbCGY!
GtA$kt XGC!XGB!1MBW<&KY=RFnNcG!dL@\%cHnpSdXwZLkV>1hZp9\\81\wIn6JIw^RPSbVN6^hn<:^E#Ckeh1
PQltmu !?EEu:CcdLB\<AuHdeiylcMa6#QA6n8B8&NEWyNWnSIIIdb:q?TYMY!@akl6?\ua&IR6Y+FAJLdX$HAT
1e>6Fk wY^JtPFt:<V&plVI1b4FjAyM*b4KcRVDdJqak>BACT$BuyVW5RBDdCpVqlIe5i&<6=RRCMc4BqSNPJRA
-APKMZ 0001ebdf45a00110333 Page 453 of binaries1.zip
Q*=<b$ FtGPNRN!&*bVY$yw^NbBe\pZjdV66dKWwAnlWI<WpBh#LCARB#ST$AEHMFKe+=hnCYCb&LFEm8APHbh!
Q*?Zt$ uZJ+l46!l*R5RBEH8N^mF&/HDuRI5IdAHW5\lCD5T*APH?qaAnybW:M+ELnVBAt1\8!eMG8^qL9EBleW
wI/yn1 A/&Nm!Y+wJm:PWbC<I1=G*B\MWZ^m\EPZE\Lu5aJ4ynjJHiDDI+T@Caq*J$91BRVFBNeMd>8M#5^P%ba
YLjLhh mnG8tBV#m$G@RdFEWC#lm1YCamqZVAtKKc/aFlS##JRIpBAeEmp8KPccFHcH+J1WCkATZJNTAWCJ8XmA
!NlW4A SMIlpRy\A=4mPC/wlCM5SkqIJiXISRt/I?X\W=mktMNNCZwy=bDRkpyAc/BaWAqwDSRLKkFnGI^=AWDk
$KYmF! ZwFmah$WX!!5t?cKBZWDD\kWC>lAe#JcVA1KPR1m\pwI4qlaCaedFXam+awFLKc=:1AC:uAVEEeF9KT=
>G^J?6 :1B<#qNm4n8aYFDMhRhDBeW+X$\Jm4u8aMK/8i:k\41=:8DC84u8+JmktP9P@*V&h#&Z=echL*k@kL:D
##qp5N e*PAta6JL=LBN<A\+Ldh*b1YdMF!u=e=PBeyXW4K/XJqVXYYLM&uu@l#:@&56iJHGZQGkA*ZL@jDILuI
ZXdHQA aDAaDJaC4PcW&IMn1VuRXYP6wCZ$wP8:1t64wh+49:j*c^C=Vn^heaV?dwhyDQaceX9K6AFLtW=mKd\^
CWS>\< I>dR#C*$+Gm&XG<RPYS\8JwJHV6%>!jQVD!ER*>Q@%@%TRe&+SG^qw\S>jhMYY6^$N@yYI>#ycAK$1Fq
F44R$1 #^9jI#dN?SwKTai$#^G?yYPykySC&Wu?+yLCBBR8\lc\qJ4nWJPpMX^TL5ATtR%+cyWKNetcH%:9<G94
K14yRY Xe*yS<S4uIR%VZmNp\K<XqiW*VSP\wI8*IXd^NLj^$SNyKmQmby$4jM#%pVJWu!TnIk%pA?LNbE:!ZED
Sj!lNI q9XpHXnGkwY!/!G4+Pky+9WT*I!+T1$jLbSht%1b$kDY6\^cW=t4%wA+kNiATMAck&GtCW6p4lF4F1iM
cA9%J+ Ct4JTBpX%JKSMm1wJTMXawt$WMEt5<eLCb?lc$B=ITQm8c!\$Qmi<#LqR4%:qXyQeb#+!JT8m8N:#KWK
&BWb1& Y1nJqLTT+4CjchtDehlQYamPR<hP<\GXb>R?$/wWZnBdHDj>&k1\6KbFpY:LCWNp%\IV^:jnKh\nHqw!
N@nj=> +9l&INX4E:k=Dkc45M18cM=W&VW&9n&W/d$t?hC=jMqBljuYL1<%4RB4kRtjIj6ZpD=BITad?dAC9DSE
$*95Qp LETlm8YaA*ny1kt5aS<MQ&GN\YD+=cVHLW8C!CbnIaX9Kd!GjRQYJLEJ4HqbD&BX5BXk1btG54M1GHTX
PMN4FK a%u4ciDZn>WX9?=1#lnAc?/k*645yaq/4:*WSA>1!Wk#j8J?4F<d<Qy%BXcj#Ac<FEeHquGGAhFqD?aD
L4q*cL 9>c*#Ah?4Y?b$\G5^T5qaP%kEq1b6INJcKY5^%#\/!b4ylSkXdCkpKaKFuVX$ywFZdX&hYWC1$<M#buL
PT6=H< 4pIF6intmkyK&?ecK#nYA6MV5Q4ptMC4kki\KymmTEWpi4$Q+C!n5kM9Y*MAt@AEqpa?YLcWKVTEpuDq
1P@DaT iYSkLRIH/4*ehweBT&5iFXlc<&nAYpp\pJXMKE<M=Lq&MPl9yhZJM:PCcp=tBhhPkBZWTyJS\c^YbqS\
4KS5W/ 4R$bFX^4R$aF6WGaGBD/?##==jNcL@F%!qwa<ZX5LimwwK%XClW$%RS/WE6<u6CDe>pR$INc6QPe4Iu1
T*N8ZH QjEbq5WB>clF&#E?R%Y>wS=%&TXQ#wc//w%YXk$I#wc16Sl/WKH@=aAiXLB@PcAH=>1VeBc9QRuW+%!d
c*ZDTy n+SY6mWT4bRKP^Jc8Y#:lFb11V5TY1tq:5lw=jJ4b4S!tWRb4X!:I$+yidePVmtb@EhBBeh!ycKCM4TQ
/b$VN% PP!#Iy#KEai>+?XlHSGubV4QmJjjPjlnldYMBliCa?%GE<88Y4qbhq&LAP1>F1?E56jmFV>^Z1/QuCB!
JAHk9G 4Yu^!&j6b6*e\1@ZZ54m4&WKqwTc!BS$jK&J#+%1c!E=cj4kYui6<8XT<yQKK*Yy^wNt8bp868CV!tq&
FR:^Ec MRYjXM/^m=*?wNyB&lFL$LC^FE6RX%kKJT!ut%$t/bN&$SLyFLXA=cm\HQyBS^FPi/T1Yd:*R*9+G5i>
&HmnY1 94+=d9y6CqR&48We/i4%G1k<K<Z8NZP4ept:q>66?c=4nqTi!qwmqWi!Y1V/^4WG11%@1T*TJc%HKtp6
@pQGZ5 %t^IYw5%Y%:wFt8&9M$6%t^=qX85&ZI16%C#i1!cnWlZQ<^IX<&PTFjNR691<4T&YG=cNa9q!1+8Qbc4
@+HjV9 <XB/mqVTi8kh9jJW!1mST61ILhcY5a^aZ=$$qYtS/4e#q19VuVJn8XKbbeb!=bwwM@cDLYt^H*T!a$j5
qZ1Thn B*q#:an>wAMeP&I@%DXdT1R/Ee/^dhLqqtQd&yw65X!6uGZEe4XCqlHL%Wyab1!9HGlqwq^Jt:HeyiXK
Y$+tQK 4NuTemZ&?6J!Jjc/>L$h?K$$%^F@P=hPnX>wLtt^9uNJm@ZX45bK/Ii&NG$bpc:j#plXM\6jjupcLMjj
m=?N+j yqW#@HbJT=G1%$i5R%4jPJc:X1eb!>Z1bEiJXNKP&PK<i9*<d9ulQqTu%W8FF@bFT:??/MRZ%5C?KKRZ
#QGTHa Xk>hNNIVc*ybR>p/hLGLqullVaVL!e$L1+&Zw>MZXkX:BXbNLmi1V%!ZTDTu44LSuDZ=PywnR<wGtmND
aT#Sk4 !m=L&A84kkP6qHq8p:>Y9Th?Lc9hJ9yEnkid/BQbdndSJ:LhdKJQbL9bSPNq?66E+*WeWR<$Zn8Ci4D5
aRw>!* Ia#?q9/1B$S1S%AQmJSi1\pmbS#WlB/W915JQTmnwTd$wQSkVilBGSM%wRiqH&6CK&Xp%ISYTt@YlFdK
B4D@:> ?KkJ4bR?4St6qFFTM%wyQX6#dKY<F#/LE:AKKj!%?1RWaDY?GLBcYYKj!JXRctuAT&RHZmIH<BI=kTZT
qKjX?^ ay?5A+b1cKY5k&ywye!Dctmq:IN1cGXbI6FKY!LSTq5m$WydI6FKY!LSTqpJ6cKXMlN1ST6qJ>TKXpyZ
8=nXnX %ayYTmuXmqdYJSK6dE5pY6tYTLT!LbFw=hIRYATYe/BmEXlikN4R!nY=G%1=buFDK>h$dYnqtyeN4X\V
ulXLCn 5KGXc/a%6HI5pYnqYCLST8$Acpe46RYwHc*WH1BmBbSd1XT5kQIjPWa4=^IbYntY+/HGFZDwye=T+\4w
9PMEF? iIpe\E9pBJdI8AKP=d&weRWe^>I?eRWe^>I?w\BL=DBk1h=<@*W?yBuh+tnA!^CyEc<qPu\h^%w!dE^k
MZiB^n 4h\#@416DWCNNYt4:DDV<4G<@Sc?9F\hc!*8\P1Vm#FbQ9n*ZieL<@J^!kj@BHXN%kt/IptQTE$$SXyF
qMwdKp e/SV6AT1ihw8^8TDcm1%!<4*yJKYa5%p\4e$I<%/YT#YX+b>!:G?tli6+LhNFL@6w4F6tm9NRku1GKey
qa>cVR W6ZMe1T1YWWJ1qqFCi4jmlJW*%wmXc@Z$L@4hLNh^9GVLtp6$L^1%mNXHV1wimiPKHXmcTPY1@Y#nXmC
\$Y9K+ DwddRAq1&=mS16hu:DM61Y*GQ6PtwM*ab%yu&+^>yyuaD>AtGu6T?+S?^J:Wa61Q&GJ6B*we9&8C>#l?
T!&jSC %iGq^@Hd6L:&PH/d%6Gia>5$a*8P4hCM:Vt&RnP&F@^YNT9+4iyRaw5%n*8JLhb!&$9<^qJT9eS?pI:1
1mI:ey JjcDDPtPtTWX&nFd6C=*#Bcb!^&#SS1ta:dIYP/aLVKKP&cL6FF9KFj%dTlZQhqR4q4Sa4qc$*8LQTq>
db8PQw %q95Tit#*tJQ#qY#&JQcmjei?$^c49jab>J!9ei&Te9%H65tl&+jwRSF$#9Npcy@S+qW4SkY1iw:c1T1
lI\+ck &eS9XdPJ*/ytM@Spq?:45$i1t5XXd<WC>DpnNYYEPmK6wmmlmeaTbF/MFQ6Bi=8Sa68pj$iKdhPGb&SR
pb/Lna %THHFt5ZNHJ55ZV%!LG?&l1NnQy/V+++=*Y%\YtWJt$@+y#9&pTNPPiqe51\&GK6DMMkVY$#TFM4DNLW
AaH9^Z CwM$6TLPa!tZM8K1%:XinLn1hc$Zw<b!=WIcNjcbXyHS+mnSKnIcyKpXDhJW*#m:yjdKmLNdc1?MPL8q
&c1H^+ >51I5*8Fqa++8:9YwSFuh>e/NH4<Rq1HSw<>KTjV/LF6dhW561&6t5Y&ce$ceWXjEc\n48k4kHZEFZ*F
pA^*#> 4+/+w1<ktAG6wVX4S86%ZY!a$Zyh>^yt6AqYYP\<WG+Vnd&nNY6Gt&Dhcbma*X1Hbw1@%W=!S16+HRDP
\dREcE cFXIubab4a18hYlmht5ht6H?ZXejb4S@%<&HGi*jFS<$w@&\dnJM/Ai6R^Q/Ri9R^P#YPnR^8:WPVe^8
&/?m9t 4WQZWMlF%&YFGT&FIS6<^6t>dnDMPL9ZBabbWc=1%qC8c6bCu/&LB#NcC89i\a!Y\6CKM/PqwKYm#I:j
PjP5Sd 1tah9%Z@^4t=DqluuJ94kHZG8TuXY$cKdX8cK<Y&!ep$Wtnde9Y%PK1Z:/:FWV&Z^S@ZIh&<eBy/@iHy
I=G<Iq mm9/\?5WXuVF&w9iT$m/EFSt5GqV$h=yZ6a*$%YFl$K:^8k<<hw*Z:VJC/9wmWKp9c+^Pm?5AZTy>A59
%R+^VX pTQm9pSP+QJt^<WTiiE1uIC:eAci\tmq/!A:D4S!LJFw=Xkma!5%Vi\cGjQCEyqn&Syhnm8\SGcW4i84
HBDP:S S?:AT&V5RhqKnmi\jq$PaFY\^B=WwIQnDK\KF4T!TGSBK<5TmXcYJSK66CWT4dRqE1$$mVT$$mT!wyXP
*GjZI+ HKPXdnW+Sm84dk>Z6NL6Bn51Y6qW:+yYN6Y:wyXN>c=wbX9%Sm8d811mqX$mG%1=JpqDK>epcYnqtmRN
9I1F/T 4X!VyKGXc=I$6HJNpwbY4puTWP<lpS*%HlLbWi<ypS*%ulI=?G8JHQ!%SA/$W4im4*iFHqk&pq*9C4*\
T#nRy6 E6tAq<kP9EVGd/p#JL9idu6lDdb=AG8\#RR<lGM4hadpTkp%!SJ=wCbbInQK#lKbWdcy1^L1*jS4k<m8
y4u*iK tllELy8R4X^GXt^qTt6w=9D4qJjYLBNaZ<j\//XQYkhiI*aA/%6&qL*$!dmYQZZ6j1$a<$cHR6K>mHGn
%VLb</ W%FT=SwXY#<$Scdb>Z:9apQ5@n6Z%*a>%X9MK*w>$lNdu&nijme#\c/*RPwH*+XI<QWP!AM&\S#kEC\B
ba:D\^ K6@kbcXeWJ&SL89pA!=BLWCqadmM$khe$piAT@1<R@XGT1FFSaJTcJE9SZc>B9tAEySCm+wEyhAmY+JC
HZcK\E m&\JCm&!JTm$TEQyiw98Abik$KK1458lSX1W49juHqCCetmSF1V4ne\H%HjQwWXXH!/HF4WqQdSI!>d%
%RBhuB +6$D1pW=6Kk6RcFFY4BTCT*TeyXKcJEY1%SCm:SWySJc%NZMEq4W%b<q6Kk9/cFFR@%bRw8G?4PEFw$q
W#CF5F KLSIc%c!$KKyEYKlSX194qhiH%DN6NAm4XZZP%eQ8ATFFtth86/*Eq!4%DZP>\HXVB5B1yp&A%R#/^Gk
TpS@j* ?4PtACY>*q8pt^!Yckq\qYpB1pY%B4nKDC%cP1TGFtX%ZR$6Yn1plldJ6p$66GnypBbc6HSIC!%cP1TF
!GNVG! F5uW9acMQ&CXpw/@dIL^q%M\6F%LWy/l:X1R<k^66!Ww6N*YElHcL6P&BD&9Y^SYky:ZbRp4Re<4:MFK
uyL?%? $QMKi4AT>L\&u%cCuyhn\E4R<@IAPA\6cp6RcFFdkpKLtkRFQd@5mlL$9IIe4AR>L??BqcDu=Tc\E9T<
H4GT>Z nBI4Re<4pc8XwPh%M>bK$QPKh:AT>L!mHc\EQc>$MqcCu6jqHC6B#<5k5lL$9A\pl/FFWm\q/Hu6%S&G
-ASj+d 000a99d6c9400110333 Page 454 of binaries1.zip
YubkYB Fp%%e6D#&up:9LXwlV^a8i9=wi&%qd8iZ%ERX8=/j5XAYLu4?SWBaiY8=?ZEEm\B18%*QV<itZ*8iq=?
VQ%y8* DMEY+Cw#6Cm6MpPL<1y<cJGM+tKlSVJPmwWYTdEWC!&TampYYmVFWm!$TD1pYGmS654FRw8pR+1FFpqh
We5u9D FA565qZ=$CJV=Y6wpZSI1cFFT+jW$KKqR&yw$hIMNdSwcaacY4R$R\$6Yy1llldJ=Ck%6EktS/tlSW6h
cIpRje 6NAm&TGqlSa6hhFCm=btcKFFZX*ZRw8YbtmlSYPXGXw$XytlSYQXM:Sw1JhccJEMmi8qkAhWL@ZRIp*6
Y*5mP? GwjmZJ8B$E\bEnWP^bWGLA^FGj%Y\%CWjY<%DEZb>%dDWJRyd#WMSSuwX5NRqIF8NR^F&iJY\%CW&Y$%
=:5Tl: DEYb*XdDWJR^dVWMShuNX5NRqN%5NR^FtelY\%CWNY\%DEWb9qdDWE^4c^cGw5^b1&Ew!uK%GwcmnFT4
cn%tWc aTnKH4Wcl1L5Wc6lKM4$6B1Gw1^M1&Ew!51$GwcmDE14aTnKh4Rcl1LMSK6lKMwm6G9W*RNKWA<6p41+
1<$P\N S6\>wIbND!*TD8WcddikhmnZYL5HZNJDm>1THqwpHZKN5u6ATS?lSh1&ZCQ5F6T&=Syj>+D1=BFcJB%T
JH$NRN S&mS6m%%lBby&%JHcFFj$pPL^yIiYmV4w5:RIttdPpPLbF*WGXwp//LP$CJbF*YGFm%6M$PL=lIWY4RW
Dk$F^H !>%<HZpyq49=/qBhh#hjHjw*cuj#hTmFkdY:?V1W\MDc*Z\hTplk:Y/?D1Wn5Ha*Z+j8ZF1:t/>DN!/6
MR:&n/ *e*ZpiXMc$hwWX/CRw9!ElScJB*TWtmShElLwWZTIV*wV!Zq5^:$y%ItYA@/W=pS4NhableM9TRh$wQ?
mnSY$M ZQ/^H9Suq44wRZ>t1a5i>GiY88lBj?yhbi6Bj!wbq@YkQ=X/\Z4Ru<y#bV*wV&WT6B:$y^IGYk@/M$5J
TwIKH* >KA@>W!C>cA@5=SAD@w#!&dwRZ<1P+@%wD?XkNB/$J>KQ&k>/E?qE:Ri>KeTdFpQ?qNbAK$H@bp%**9R
W/NWk# u*p5RcFFa\pKLbyLWGmS4I5i>Ki&4!96+B%KWNCj&yScD@yV?$@4RZ>11&p>/E@6K1$H@cpNyQYkQ:XZ
6!Pb18 6B:$y:cFK+ZlHT=BI<AqcAawRWF@c4i&WljiwA!JH9Tu>tDYk@:Wh56/$J@cYXpQ?qPdKP6Bj&y4bD*w
B6AbdM V?&C4Aj>1R&Q>cA@6di^EjTu6nE4i?EhJ5HRI6pMI?lQ:XlYP5M:dG@4Z9Wh>4iX!9AP==8NwD?%=dAS
DIw4Ji >Ki&HDcC@6V8\pdRu>yh&An/W^5JG!t$TPymyNAmdWbGCm&TIVFTcJE&I!PFFptHnBSc%Jd$$CIbEmPF
Q8!w9A Fpt^nB^cJMW!etmS4I8SR+9p8^k=6Encb8VRIlpTI+eY!bCaad:4q19NMN>%6hlttP?/R&\##uebEnQP
W#Q^C@ h&tdGii:6M&M<%&?m^uu8%VRnQNhKtnG?T+XNMN<%+%mt&G?/$K^#VDjhe@Vbyn988byM<^**c&%Gic:
5=6T:F L6HcDQNhiRq5l9t86AR&\*^ZykGdad/dhn$##HiVR&PG?c=nwu1E?Y+?68wS=49TChRn#Hjhn/=HtP>K
&e1D@V e%CQMN?X=cAiad:4tt+>\u#Zjh^/lQt8/<Q%CQNh>=44Eic:Lk@ZI<^**SK8S=n9btyStP>tcqGa:<y!
*bSJ/P X+<\*<&YwNCm8kTFF6WqKLTwLpGlSXW6C9Nh>*44Eic:48@YI<^*JVC9S=n9%mRw#Hh#C/aiad+4QX<>
bNJwwI \u^Ze4=/=NCm91THF9WqQdTw/<MFh=@8B>en8Q6$P:ki\h&uT<D%CP+?Zi16S*D*&bCk+P=VYwl/BHij
Z!1^K= 5pLWI:n:hK?wH5Hhy+8@>Rn8Q6*94Wh\>?pcd#&C8$?ZiP5SjC!/1%8Q+GNSRwq/BB>L%aNNS@C^/QH%
FG1TjR ikRjm&:$%mQ+YHS^6/bkK?4cdp*BX6R%*J1C4cnd6nWFY%GZc9%@k@T$BAZyQnS4C4cm:w9XFNaP=Si5
Yey%/& Kc\h%ahSVYH6$HZ+t5LcwY8$NaY%R:hqc\y4l!:F%lVYD6%>4Tt5HVwQ4!t5HjKL%SVYD4uAcky4l:^h
p!D:Xa NaY%R>/8t5LcIehYVYH6pGP4y4B&!IhXW%k:=K/1Kc\h<njXFNaP8bb1Ct8H9Ek%ldXDD1Pc\6wll%FN
dWK94G ai&Rd/nt5HdIDiR\6En1Iwi%R^/jt5QcIa?Q\>Am1a5e%k+=h^!GFpqh=LB&!GXVe%k:=J&yPc\he5VW
6bNW<q HNaP?X^1Dt8H*C5%l:XDuyTc\>wly$uNai&R$/Vt5HdIQ%J#YD9pC1p=4B*!i6Re%k==QS#PACW>4B*!
T>&=&A bVlMAc1bai&Rl<Ll9WX!S6Re%k=q<uSaA%!CYwBLWA>\CRw6!p6RcJH5pB#YD6&%1#t5Hdy1X*NaP*VV
?iXFbA 48c\hmli68c\h8lma<%l:hAN^y4D&1G:h#YH6cPXJTm$1C^BwWY?R6Re%w=tcqFaP=yJWFk:hJP8=4B&
hn/<=& NCtYHNaPZam5Pc\h8q^Ze%k:hMY^=8Cj%>Y/twN@1hWqKLTwTXD\L?pGZe*B9/T4enWH@=J8!6We@E6K
l56K^/ 8Xy#<C@ySq!%PJKqGT!PbGpGm!Nbt5HmTJbt5DmTySp5n8T^BIXi<lYmYl#J9llWm!Qb>Z/%PJKqLm!P
%6kRlw bJpeFpi!%IZFpT^%aZEpT%%aGMt/cFa6nPS?LPp>RHX!GMt/bXa6nGShM15YS4L8tDt<6$mZ!c1Fpc!:
*YqN+i bA=LkJIiS4J8pnpMLbJm5VCThY&$YlnJ8nXcLa^p*T&4Fpc!4ybXC!NbN<5ellbJ&%ka!dyBXm&MbF$X
%F%R<F 1^bG58/EXR8iWq$J1^a<yd4:XT%+TuZ%1%4\qPyccdZkKhZF4&4BW/wdZk=Dm/TZLHlKhYjLaYmS>JIF
P%>DJY V/u8bqWLuqK=y^&GF5uk5iAyqTi/&8py#S?TQK1ZtKJF&65qwElEL#DW&%@yXcP#E=#IcZkDGwlun?RQ
6$>iWd 9ny=ET*hmQ?k=V9^9!y*at>uL#^Ii#8:+EG<=Han*1!#<R@mJa<:<bLuudT*j1?#1:l?4:Nim44Z&bXd
Zb?5iw 9>jbNX8@%>uXY4@Z&V8%*?95yp/@%>t:8h@4:F14*?95B8m+%>pN#ZG45=!QI>>Jjl9qV8^6&J%+!jXP
@N4Lk* 9PSduiWEHQ%P<65q>P!B:P$TiQbAGtV*\q&4ZILPF5wcuQjm5+wjh&S91e+:<8L9w$@^18p?@BT6t8:n
nNBbj: V:G1/V+AFctc:mNRec4yQkRXyb48a%A^18p?CBYlt8/nWQGy/V+Mhd5y*eilaqQVjTD1\pT/n$VFycd:
1pQXBb WFSWc41QSeYpy96k%DZThB?N8m&c:5NSPdjTjV\15Xc/D$lhKE**Ecq:w!pMTithMCc>MTpMT1>=C1NT
mnb#D> /mpMT/>VDq@dK=DD%>d#M8F4/<YC<LZ%YpH+&qJ@+Y6QFZ@9L/uE<LYum4@*%%V^>@:!/b49Z%6=9@Q>
TKb1pn c/?p+9i99VKH*:@&Tk>?@>w4B@n>c/@<*@i99bJ<*:@&!8S>@>w4Zjj>c/?e*Qi99SJ9*:@&!1=>@>1/
\5N:LV +bD9Z%8*G@L>c/>E&@i94jnRjNhCmk:Nh#Y$et/Qi?&Lm4@Z91\E/Vi$5uLjc:<!e6>4d!5>!S*yu8G>
JTI8S< Z41RiB<VK?QXjW!5dFj*MdE!ZaW^<WnNeWe4A<eN6bZ/+w/WN?Di1!9^^4*&K:@G9ja48ec>>m8#^4*&
d5qM/1 K/*G9jb>=TT+w*Xl<+:Y:j+dG85T@^*yd9c>>4yPHMdEYDjb:&lhC:<lbdMIa$KyLMKaYDiF::XjF+L9
W6*&QY 6X@*j1?%L!5d%T^*yB8$hpj4C8<h1jl&S!1?*>A/X#*8TAiV/a=$LHt9%#yS9hhLRSZ>Zm?FXQS:9jI/
:REBpu YL?nhRl>S?6p?I=W@L!l55+::&kh:6&SDld96hiS/4nZjl&w*t8@nqQ96hh6pHG9@Vw%9hji#i^^4:#Q
R&H*9G +*NEqHWJTudJJbL5CdWnQ>iaJ>V8?S\ZL?lt?#p!u6C4i<py?IV!ib>:^RZ%@5*dJc#\AhjJkN$FJbtm
Fu&LLl q<6IL/n6^SGk>1<6@LuPw!<Sd!@wbb+4+k8/8Z@19^j$F4WYwB\=@anR6!\>NFQ&$mXw:AY>R&cW4t*R
I>9mXW nNLquyt^VG&Dbm!#4tjnI!^9q>CqF/^9q>CqF?^9q>CqF=^9q>mnJ>V?=wmCjMleEwi>wP>PEu:yXe1^
A%dyF4 /:Rj!mqC4&iPqhe?KejK?*LWe1!<>p<Fk4^FJR4T91yERhycqd8k4LiRL4FeL/li8w?R4CDVT!#ZE&44
:\#e6d Q?M95@:<CLCwp%PEt4C^#DZA+m>%BNF#lD=q&wnR!?\qRw%pC%AD4NeI9e\iY!TuaL6<h%>1%m/>nC6d
>8Fheh Yhe9<eK&ZpqV@E\:>$IQ1KuXVw@LE%b6dH8A*8y?P8bj5L#%$#H@lL:&>hM^@+K?kV%him<+**wP$uW*
Ydb$eJ 6=enR1>TCYZK=4\p:u4B@ucJPH6Bdb@nu@5W8ETeQYHSu>>:1Tta/lL#bi@=wT<^Z@b+F<::<yKN:Aq>
HYLBh/ aq@Tnn&kbtW@bwBTAhanhBXk>!yNBXj%*CNWJ><:bCwey=%n:kp%GHwN$Q?$#Rk%aYawW%8Pb8GZ&lW$
=*DMXt 8@%Tn*&wQ!%A6#E8\ZyQ/L44E1#*lKbtnkD>?%#m<y:Rt*mJCu^CZ:+9Th^i$Q?<^CwNjdkW+QK^qD6W
M:\AJd %Naq*iEVXp&8H1FQ4l/c1emqT@dBF=T:Kbay*V%Cqey!VNWI>e8:wHR5>>T>/@K^yAi+XPwwAWw#>Btk
mCjiAa /bi*Mb@Zk!GZnI^Q1AX!*D6=yS?@=Hq<\1G88#h#=i&>=HN<RJ%KZJJHQ1AT5%&!SD=lXwj$CH*bG!NC
Pd:SZ> H\^HECVHcV?PCH$i#XltF+^qDp&bT>i=TqcmnW8AcX$yZGY@#V9M/>:NJcd\AbYi@yLy/\Zu&#kX&BQK
@9?@?J ^*bP8Bi$6*FPnmh$>ZHJ*QYEQke8md6i5L^h<tA>wc?Q+^!iL?l@jk/RF<^9a<R1?c<8L*?>aHtd=!L#
W6^EQB kF46L?GaL?njdh=dXGXPnuIE/Iy:qBTkC^1%SPkhWm%A1jq=d%GXXZIJG*%AJYRb+\/::lli*n%deCki
ktSD8K ?=JBdMEyR@/TS8wF=>5qm>RV?5dpppV1BZ$5&R#R=>WqlhRLimjZFPF+8#!p?aT8LYdwycqPu1GZy5!j
#/aWH5 YY8AR*<iY/V9ZtPL9Phun@X$qV^:4KeQlNqnQVYQi1mu4L^Lm1pZ>Ld*WE?F<X<TVL&kBQWIXcZR<%4J
BMCAq4 L=GZV?m#a+cJMJY$ha=aV@?<e<S/?yi<^FM?wjj/Jb:!Bd*6I>dVVabLQPWLi66H4Ke?*A\>4=Twq*nK
^1GNp< F/^9q%nTF%Vqd:<5YS:S$jIh#9ZhS+Viwu14Wqtd@$8t6\jW:c:Lm+A9/FY/V?&!Z9!hh!XR%49uM<Xj
KqGI5J 1pWyB/lBt$1EZ9qpEZ4dW+*RQ%^1AY4Ryl/l%#QhP/Rwd8iTh?+F9jIq@LuCXC=9C4/kj$$L#XTw^8X6
u6Jp// *^j$FqtNWCwwS!kXFDyE*9LL8?p91H1Gd!S9<mZ4*k8/wBLLXCiZYE?NpHK9b>YJ&RnN4DwRG*eXyIVP
KP>LWN PwP/>?iR&@MTwQ?CPm8dEd1mQw+IhacYI9T%?MkB?n!/^PK@wFj?5Akq1EcwMtQq%jaTBdt1GCWKWwiW
qmM:=j KGn1KC<K<1X5qClwTqD5yTqBI$I68:H4hK+a^8jWdiN^X@/CYubHlQ:uRVNMJe//=CX>\mcD=@+=y8/u
1bLK+Y nn+nqQe8@LtP>Mbh$\y/l>\%4hJZ!8DyEjyECN>>/6l4l8<?=eGd+d6Q^SQPI$1Z8knjjiwi\?WCTbMB
-Aub?6 000ae19e4c700110333 Page 455 of binaries1.zip
=*<yj5 YZSyKF$PJS>W1SuV=Vd>wmcQeL4E6dTHX$CHyyhd<k?1YMh$CZh=WSN6kdy1VSjZ/cJNLyX$<Va@1CL=
6M\>nI $8W^u^ehwldyjE8Z6&?ihK+IlCNTujPtYK=*d41<YhMi&?t!?mFTX!jJRn<MdV@VJTQEm#dSGcl4kFSC
DalD?Z 8i9!hdw<b@mkm9bKF\@$k?4XuXSC4/<\+HSJ4jCp/:8h$@NFp?mINI9PTCZN+t>%pH6JJ@CpQ8#VJjQA
LjVG8j k<yhtE4+tp:X6mP$VXbP5lS@Y>Z4Kj=YJ<iYY1A/A:d+LYTAyE5+!+61SLZRP>yly$6A!+6PjR5LhK4e
$8X:*% Ej154/<=R??5YZnJ%9YmZ5IqZ>iLD6Fakl8F/bK^/$qh4/aW^6qWV4N$BE$\qb+1HjQi+mt9dLw<KNii
4?G>lT #*keKneFPla6pcwX!RL%LpmZNFp9tpXHyNJSJbc:&qbC8ZKyy*TjR*t>BJFTCiW1CDcq?/nP/!YIqP:#
WIF8+T PB?QpS448$b1RS&pH!:99n&y+me8:+$>1h5H/SJE>/KcAadjcpSbqKbkl$5e*a918%t5:=wBF98lL<$X
@HMGiD ?$HlEbek5$YVwnh>qN#HR>L%\HS=%1W>ZEXLI+bi%$M!wuhyYZpTWkq%WBE8dcSAm$bWDqR8ltV%mFR%
N%D?:S c@G*661YI%WJ:h:4K*hPP4yF&pS4yQ%68e$C%e#1QXC%?JId<EuXb$eQhXBMb:4ey*4SIlyKWLlnP8/4
=9LMyY 6FPN!cQEe6YVq>TnV:41WGP=Y5p8mWhjXLwpnJJ%N#6h<uT?1DSZcbG88Zt9R=X1TJjn=!jXF$4*6eZy
5t\t45 K1HtRJiP1mXT/b%/@=wQG?awPXJ>+*19d>W^bDytDZTXt$IJhYuqHF1^hJ<FZXJ%wyW8&WyjhM&AE1q1
a$!9Yy Nm^Tje$b/dIWWm#l5b4G*<+%A$DZHAw6ZtQT\wm1c$^c$IlX@6Fp<S9Le?4q#pDZnP&^*CI>&YP=T<PE
K@?#+% eXcXYCBbn@X>4Mi^DqN%GCNTYa=ljc9c^!YLZ%:P!qSn@!1uZc1^j?ZCTCYM%KaRnZT=nQGm!#I9pW4*
YmA+PE lV=485KaWyk6VhENKh%6GNFX:klWw!Vh4Y%STR56dpwDqXKQNc84lNk&YaMy4BhNKnIhaaX5!8tVTym^
+/@b8T dYtCEtb5T<9&4KFtm5FMPdbawbMy^^a9VbBnV!4/L?Zap>y=yV^n#VSKelk:VZipWw+>KYhL!4HQhL5n
*n#wFQ =dB86lWnueM<dpwBq@IM=e4+THtGZqjHyBK561dWY/tEXcVy!u\1aSXyPp>KJim#bw<Xb$a19h/CNF56
eJ4kHR H9G*T!MGZhJpQKeW>E:V*e6$BF*ThHcXntBX>LR$iGl^X+^Y86^wiqAy\=TDdhTqDNQqw6PL/55d/Cy*
\kDENy B11>$?XY%I918?XRZ&&CW\+#wP6GRewYj%6ZHcI$je%ea\ucM?T\R9dX/#uwujYIi5yl9uX6VqIP</*L
Hc#<NJ eE&=^Z/a1\/lj^?&elkq9c$bt+=INj1Cyy%q#eJk\<#Xp!t5AZNbiCuMqmq9Wp4*HcCe^hJ>>>&m9MXc
cdlMcB Y?:#RuV6Rpik!\h!d%6b5ZIy*jXDYcuHW:=4^LKTR1YT\t@Z#1je//9Z:=bqj1hh+X&y*NeY9cIt:$Fw
ia/HJA Y>jkV?t?1^QXnL*9AEZXb@hh1A=CNcL88%CumyVP>%&w1Ed1jSe11qF!*F9e6VXPq##cm$/h*/hL$8$H
Nw5V$B qeM$Hje=yAepbGZt?F8NuiM?A$TqT?+#RE<=TN1>b4cmA>Iq?eGD=whhZTPXS4#d6KI1>&:9/GpC#VeL
FShCiD JTk5JB&%SL41G?1kiL6$%FCCVuCV*YiY/NwZ*9yBPd$q:i=dEX$4d\8$LE>PD%VZDE1QJekTK#&YwH%Y
n8\1aK /TlB?8G?<^HX1L=@iXF9SdtQEqGN>SHdyl%&8X9R6wbCKueL&6bRTPX8Rh9/DKtM&Dby=VJm&>acP&Ld
=Fm>9u %lw:a69YGn6m&=cudMc&4X*?EY5&q1j59eZ>/d*688q!y%Yd!uSJ$4SwK?68\/uqHqTunPpT%:qwV?9!
yaPVT4 Tw=WP4YhK&S@j#M<Zh/\/R@Q$<MHMmNNpuc4YV=$>J58kZL>+YuR&uJJC@Ykn?5a/X=Cp9<<ZiLAZuV1
5yEFtj +pu<4ZV%JWjcm/1EtkQXu8#!n8TV4y5\hyiY%^^1y/*^yBy>q:CkF>WZKpik59585X<Q84\#q$^6L:41
e4RQQG c=G194XG1p5#6WXcSZ8p/:LP:Y6t$@SJq&C^@6kjL=>=t=F1VQb:&/1Y#HTJPH%TYYKZpNMuqdSLXQKV
RSC^Je !k6+mXQ5##kKZYjKF8n/tmWHPqij#WnX6wdj15>cmXRn1wYcKSA6ZSLZQiu/dntW8#!!q?nCB%W$ZL1E
B=4MN8 \#&yQKiZJGd>*AFiM1M>1jV/JR9cp>1/CNWCjX!Q5pDZhckW!yZ:Pa*\*b4e#&tE:>cWXDXhM5a>1c&^
KdCJWM e&>^p<tZLmqqu#R9G81\hmk>l*=+#5%Rk8IL$mW9%+8198qiR6i6u6VC1F/9EKSLlP/V!m1?BN/?/Qy6
+hqdd# nXRn6dhI%:!I$ycuwaicKb%@11Eu8\+EW:*4hXFJG!qTTS5=WppdJhD%LaKt:RylTDYM5/=\lZSJaj1m
lKPA/L T%1QhEtLdX9jiMT&!a//yDF>WWtd5Y&!4m/ZHq=W$tb5&%y^bt^dYhJm&<1TF66Yq4Va64Kp^ddbpldd
^l5p5I ylq\mTN@$Twc&!a4/HI9+EYqQa@aN1$6q=5BL:1p^ddXJT&&4T=y5Y%%Ta66c$9V^918?>#>Z4Q^$Qbl
QSFqml SX@J#%ILc?^KNbbcYN?GPmbh\u+Zua4\VT*M#du&YV*MkCpZdiwn@uby<DADbq4&\*%WF/%q8kVdI>ZK
FA8!W% eNeqw6JSS@!6%wB&%^1m5yn8YpNW*/*HP5nCc#%KY!9DEW9RH1ejwaT!=4!Ft5t\T8*?*ey/dT/%8++1
%VZn=^ 1V>KKIG8&Y$Y1NcAh6j4bbpP1h%644LMw6V91$lSWJYwSc1&*c&4Wyc*w>>Zy:L!?Kh&6>y<l=*Ymu+9
9YZ>kp \STLuF4wHX9?/p9E@JN1Zq^!W#/y:KlLH5wujc\+PhJq9h=46qJ5yW5$?=M8c?W?8<9KFJZcjYWwK>hV
eRSp?: c9iXwc^$N1tQ<F9qupq>^6>K:+\\wty?6DnWVJhH$:n4B/i1\!W\/EZ%&^JK5GXX*C$<WjXbCiZ1aq>1
$djtH9 >>qhcq%j1IbYKK\nNR56456iQ?J9%#\?\4iw/%5eWh4cWb%cic#LNMyBpT/BR!?1<hDmd:X8Z6:^jXK6
yB9W=q PQPeAW@1>qt??DKj%DX694!P>KL&qm@QPD&y/+h<ijHyRZWWt!@u/C</SiN9/&yd1JuCJNIqy9XJZhQt
aZGIRG T=KEB%YT9J^mCe1Tq!@?*^hX#YwwX#M&Z%I$QKp4wy^m@<yw#JjVpmi6pnbmHc4KHjl6W\pY1Z1u^V15
&:Ry*E d>Fmjj61&+^$%Vj&Vqi=QhS5STSe*ty?WYtNGi1kdXP/9AH>yQI4#^#G&ayNtnu?Xyyk=lJyEa%%ePYh
G/uW*& W^#4WpV=ew:#wL4<pC<u$E@1j=\9H4kZ#cKlD58nhZpLi>F%+Vqj<n1<1L:<!IHt>X8LXN>m*EjjCyuN
NZ&eb/ F%@dm//c^h<1@<DF5@ip84F@lHHYq@@5E1A4K9jPtm&*WbLYCZ??uJ/>1P4dW/CcF<h>#w9Y6*^J<9tp
AVKD!E !wS\!jL=yE&@LdEPT?@aeciKNM*HTJF1^6=HqFh$je$=IqW4nmNT#eInST4Nhe^A%<^K5aT?^qt5k%J^
XWd\n\ HHe6J/y9jNh!wtyd1bG8*ttS1ueG!6WMGLFe=i5+Sm^*1k+nqn6Z@>=dMSZwutd+<uQFbe::KMq&4QF\
bjCSbB %===QeTbL>:^F%W4<kl$%diH*?4#=uVpTNjZ6EDZKuKWRG%>#S4wXM*8in*dYL%VS/V/F9jbw8D9<ya9
TK%LeH <ZIQ1n%99pVj9KlcjF?#SQZh?kl$4VlHLEE#/@JI=a619Vn8JbT^?4jjYq^MhtyP>%+ZZZPwS/1i9M>n
w@Z:K* y^1y1eVjc1Si+6yiXDY:#?:T%u:we5jqSd8wSVyF:/%witItZiKZZ%TY+^mB!uK<*Jh+$nX?W:=V*TSa
?aBHLe N?j9XP9R1KGE95bPcHHVH?en6pK^@QpT$jmke?tTQCQX1C=HyK9Z:*Zwn^djX:K!hEt/*Q6+WPWZVbe:
8HCiTX Hm?1XVybwM5c6FnCY6E6@qb:@<664SiX6NCVji%nb?nJ^%uh:PG*!u/Zn#DY8>Lj=TPM>c/p\jp+Rl$W
DkH4AI X=!Q<PX:Lb4hKWldb/E#>1VeNYuY$A?!NhIewS?$MWm##$nXD?PIXQ$\W1TTNuKp16pIhinLWknn6/?%
CNP4B+ ?$n+4jw5j8P?X6M+H1VQ$8W!#a61DdAY1Qd?q^6>L/4i5jCF%kuycCXT&bM6%G!ht+=^/WuqBqkK@GwE
XBaQ*V PhTFqDT8?u9BNTq/kNwVZuY/wDd+a+a!6d?@ZH5T:MjcEF+N5\XZtjWP=accQj#=Yy9#@e@%uGwc%<G%
+#CH^Q +NLEAV+t@$*R$Laly*IV6QI6y#HLHc/Stjwh#1WPdy*<mHi@ZLy/\LItiL=D:XGP+%/q8b#<>XdtXAB#
^4t>bN tu*e+X1GVkN9Q1=%!Gm:=AN/WY@wJRQ4p&4nW$?V>pZVY:/<d@Tpn#^tki4RKF>TDV&wI5##JRu5k/:N
tnM=4D +mYR?pXNhbmS84K9Pj:Y?>>yDXR118baRquTY1SFNNS*dWI9d99=QHl%ipp*@KB4eF&!c#%wYjZ6M%Bq
TXX>1b Kd8+?B>WN\/!lT>WhjcS!:#ZwitiS</lFT6MLPjRm1dRGbtQkb1?^SFK$E$e4<MMXGbJQY1pT8BbR\uL
mibkT/ IZBJaQTmTdREtpZHmFSjcM^I>T*tEcq1N1P$4F/jPhKylH/SK9Hd^d*?wl445eX4:LVab^w&?iJij%Jd
Za*l5G 5!Y&YL*iWyRt@h6TqKbF81WwVa6$T%Fc%T^M5Tjq%tky>1VeSm&PKQqm5<WY>#XK\n^88tYjL>tdHuT5
VB$ki6 d#^Cm@ZTVd+<kQcp66Itk6c*jHEkQ&qhNH!*8e46wd+//5k>>1@5u>!D6C=uj4+<BQtpetBeZwJ<WPYD
5pCyFp !JjM>A?1+=b<!Xk:u%in8uw!S/4bjh^:b<la!TNw4yYbitWdDXSbC@MIXKd!5H54ymKk5+W^Pbeyh#p8
&enNWp jFJqR&^*uiwL/5wDiS?VYbtJqAy!*Kp8t?h<Z^u!8m&a<@*Lc%FXu=WS1W1\WIJ!J?hLKQcV49Hd&=*Y
hluBQT S*%:wG+:=#/CNQuF<!Y9<*^ePEuTMQiX#PuKFZqjSS^1K#JRk6^uF/QqSbWl51IEjdeYyYpiZ@J19PkW
ai::%: nTY$qb<!qmCH!?m^b84%$YQN%P5n>KTmR$S:yKyDn#ZVinF/4Jp&Z&QEttuh9GRCihGXWnQWwc#WulXW
ViLiKD JhRi1W1wwYb4SI&:N5wQS@wq^<mD4k*&=W&6?ZS&4D4pTFehT1R4!im>DqXlyNu81=QwYtM6Ww*%?#!Y
D>&Wcl SdK5qSty>G?aR>YY9XNTyFwLT+qW81?EP1^6aS&ktlinS4y5tBbwW^%tpCaZhB=*C$>WI!4YX/t6<mml
\G=iM8 ZC%ZiiVRP$yd6QIcZ&uVBh9e\yleaj^=*K$&cd$q:X:j6u4u<8VIk!ybS4a\8=9PWZYJKFBJc&FMNy%5
hkA\>= K1\<WNpQQZ#=y14tMWK=a?uJMB/c6lw=B%*TXu4e*FKpcq5L=c:$6:tXTFeJF1q5#%anqi*bY1VT>1%H
wYMc/5 1qaELheWkyF#m&*VeXd85Y%!SF/8Z##yYuF/dJ6G>iXT^w81lBudyt?eb&!dNG&i5Y*4Y<^aZ/*#=an%
4l#h=& %Tc%lBHX%?m#wHj/Yuu6dlPIX6EY/SV6kcc%1^8S!kLJ5R+cP=iLyW?cF+$q/M6j4yC?1Pwd%5&8JV:d
-Aq5*\ 000d9140cee00110333 Page 456 of binaries1.zip
=bJ+=l *bb#Kp%kRcj&9K#MwFQ:Yy&5^>>1FdEc?$Fy8K*HE1b?P$MJ8l8VT^mVZZhnekqn5868VC=lVQbmc*eL
@:8FLP Ktul!*hh$5q&lG?5m#j=<5nJp//W+:EjFJcbY+*%qWb5cN9TP$H@h6&u%?!IXIuE\/n8T@i%GcVb56jD
*!ncKI T6b6YXeyq4D&LjPIhKW6n!Xw99YeI!$1h$T/dQ5b1VKSB?8%!*tl/#iB=pXDQ?kli=WV1C!<H8hFi>m@
TY8b:b wR//%Jq:m:>hin%w^PYi#D%w48Yi#D%adZ$hAjd+*dTS!V*w1K+I/N#CG69:?lblhi1Ka5$64L^hedC=
b=dZNk qTm64Y#&WXyj9&&S46@&TLX@5%m#4y%\5GG/R6%#C?9deyG8$?$:HY9@F1tPpt4WMGQ=tB1w>pN^9mu8
FWFmXj jEWQBCy:J/#?ZhE6&Ybw^XkY$^GqniYQTyF19^qukAJGe+$4\<4kZ/QYWMCw$^/y9DN^9XlHZ#Y8DHQb
>wZC@q mHF84nY&HXHc\+PSI>X/EjYPp41=dSV/VQtGew=nZRtHe8:+4c!K5H<dK$RkB\$#FE8Ve>BSR+:puIPi
!PIpq\ HQL8K%q<yJI&w#RhAic:Q$yQuem!CT%iD\:qEidd/I>ZCT#R6X95<dh%:iym8Y6jGLVGZEi*Jhlu$=dH
ymcV<# MP#Gy<!BZMJ8jCypL=eMKt5qnMty!>q4C^dwK5EmZTZWRPWVK&FMV1uyZML+uXK>8aTS1yVFwnNR/d+T
h8phX? hN>eQXqKdJ9YwXJm&>w1Ihb*?e^L4P?!<E15d%<q^Q4&XWK54#Sm5Xlj/d=m5d:TG5XmjYZ9FI9jRl1^
RMRp?! hJTkd>FnCe6D*&MJtt?q^/?y>$XKn:$#q<e:>I/8#?eT9Ah#lbiW+D&aa%qmaci&ElHuE4\HW:GZ8RRh
dK%F>S NSXqtW9aJc&5^dtE*e^eG6H89XMPZXDM:Y=QqpQynZK@&*%891>i9@5WSJi6jC>l*b@P6WY/%yc:yiAj
:>?8TL h@pu:^by1dynpj6>hm6>*ZwSJ9^Yl*Y=*j9Z1ibF9Y6\Wc&Fh+9WP&8Xi><J8&yS@:d:6>DXTZ&*?&>F
yKZB!W >h*8Y5:yY5qcKCG6qi#8E:NnlbiWi?<w:pWn/6/V69K/bL9*k/$<E!5t<W:Zihd>BMTyS9ZqP5PLc6&<
KS@Qlh &%!mK9h8e%uSCZwiI%C=4YSH*&mXp!!*8%XS$#w6GZh:WuS=uw=Iq=<4*ctT@iS<@^b%SbnuZIK$l^j:
FL%#GG 9yNRZlY6lZhjSX&*q*I?R4qLu?WnqD8Yl5tl941Mt/&H*/+X*i//SFT:yL581WWS=4uj>&T%4HY#HcAc
e\CAc5 1jeh61m5qd9XJ44&VyFK@@c:y<HyYG<a=WmZFX<m%W=m^D1wh@1M=ewK/uh4SZVb>qGc9qCjRb4eaZpe
qKyFVT pT=jY@lCbXtp+*+i+HV=mw<c/Zy<KZ!L>c4XmL&?Z4Ec5hjZiBky6GI8&!khpc1EFQyl?blGCt&d!?6?
Bt1TFT Qh*S:jBnPi91Di1kP?h4G^#1/q$?*^#?ij1RQuR=+N:i1@ymmw^Kh!bL+u%C@V\hDuX>ZQhu!^pwh@pH
QTBR/W Z<uLtbuw<k>h@>A:@pHGa#theJh@eLuq>MNh@pG9Hb*8155@/IGn$&N%@Re9/5\De9pHH%:q6P:Pj%mj
:hIFVd ?I^689:D>L>+6&Ji@=BYZ1l!S5ih@/ChTnuj84*<k+w/Kwy1<w1ZM!*B?#@$R>W>R%di@&FhQm/u^@H>
p$4ZaS H/dm&51b6iD<B+Y:=#QX>PWjhLk^Y>4<R>e@XQ:D/15Yi%jlmyKBV=6Z8yu%VFd<B#pL!^pEe9/Dew1W
KWNYZR M<L/<k>/Qi!wqCGujDpnu!@@wBiw#qDK<^?WI4PeEbKZj!n1>p&66DM8b\#h=S?/@1K\8qyn!^u*j@/D
XwMm6h qHlJ?B==ZR<yb#cK<^@$*pk=u<t?@wMGZM/dj/n/l:L=B<&w#L:T6cB!yuY+@IMiIe8N@!AqZQLt$&1>
%J<Y9u #*QVJdyQp5>E@=h@$IdlnPK:@IM5@nNW?Q!HFjp/$?aj6G4M!818I+A#!jdqH#S^np&*K=S6QWdGj>C+
tWRRtm P6m:pq8P\#d@wNGi&Xj4Bdp#59*>H%aphEpe8$4B1C>+:/9y@/QF:w#G@HtTYqi\qC<I=e\m?9PWu*NY
!HdX81 T&8^m>b>@5NK5FjPVKA@V<Z@\je>5thL8?nYF=e?QE&Vp:9mL1&\uKq!DF!ZT$8:DMF**9XG+EG8l\I9
deWpbE ?89FjYp44YX!%jPmyN==EYh>NIqca**Ti4P\pc>/h9JX#$G8jtnwN<W1qNdb*1^&hdbZT*V4dG@Ye+6n
a*/@I= W+:1Q%lPYW<154$cD&&!9WZ6uY^9Wd5t&?9:?hKQDc@m:Ae>BHt?6ZVlW=#%%!8SQdEj*KA8QjG:4@em
aNin4@ M?89YZ#i%D?=j>y!du\8ZQW^qm>D1G@G8VS1*+^#GVY>wn/K#C%uXwRLX@*HINi:nkj18XcLecCiin81
ItY1M\ nIy?XlZL+QnSX1RMnl?q:Cnupi:J&*yBpuL%wPdk8JJjwp!PE=$1qMq^wu%KtS\u!*1etjZSk=p#5#/?
XkqpMq $!%u+9/V/\ZMcT^jN6wb<j4P^*4T5tb!qW?>MS+9YZb!>RQ%l1Kl!yph+5YVF8uT$K/Xd1?e&@mjJ*6a
1V+M%h 8EtB5ZbeB4R>qlKh/hq^tVDX8a=b&y9Xm#+ZHq*dGE8Zc4/\Pd=w5Si8\lt+C/N59c>=ZRXjYCI:SP1h
$<Y&#I #VRkM195AbF=CpPpG*tPIdJI=IDIw8bMmC\TPTG!TPTETJQICbEtpSMm*j1\/=:lld5\SL1!6H^AyE>*
cPPiPS !\hE?6T&jECpBpSPEFtHMER&qb$k$qhp!\pmZR6aVlDb%MwMpW$mM$S&me\R&TW!R&TZ!A!SZV%aIHKw
XI4F=t :AKS4kA6e#aM>YCB!KEiLBA=%B!nTH$$k<my=llEVnZHIHK1B\$my$VYKFJud=b4Bqb#1kG4PdWB1\h4
=9#X5% FCuhdLqByB:m#R$myW?8*wAZXm5dSE1j=EcScmY$n&/yY+d&$TJlGhyH>+e6R@9w^Y*L$D=K*YIb&pi=
Gh#5DW Y!^D?!mi!DK$n+KE4F^<C!<<lH9Ei5D*QGA+5ViuZBdwF:a*K/MAN&GIqD+yk!KuMESYmb\RKeX^Q8><
VAcd<^ ayW>IdK1:AtSd8LdGa=!al<uhpCp4+JtB$V/?ty&RKVdGtaHSL1yaZbAyBTHJan$IYKYINKHmFtCTPpV
NbGS14 T^Ay^YEJIwjK#lAy^YEbI1jK#lAy^YEbI1i/KpQpXFeXmJ#11lJED8&D:Z^H=MR18*Sk%d9MmKWl#BK\
=pak#c /t$RKXXkByFTBYiI/auXk$cS1ptFTGpI1^CbNTA1SMwR5R1SYVYyECqD^ByF1tMdSEy^YINIGTLYIFL/
JeFL*b ^ByE/mF\/^AyjZLGp:%n/SQ4ECu:^DyET5%al$lV+\hETy@awEk%jpCp>IpNmJS>akMm1^w@IXLc^!bE
qE1wN* T99ayEnXbEKp6I>NmJVbWk?IqH%TD+mWt1pHSE4N%AMmbddWA!L>\%lNECu6W^NET99WSJG1TaJIYVM%
qLC=nn RiSRVVJEDnW?R/TMuJwl$n?n%W!S1ptG!KtcFIn$#&mX&phGVtM4biR$6FLH56dRT8X95IbYKlGANdST
**S9WY jtN4cKW8$X9LFDtFIXKc4cGXitHGGq1y:QHYwGQ%^w\%/FlqEdeGHc8dwhcka=X&^^y$4G:$Y+PP%bX#
RSIXIS c>C^<w^dk+:XbRJ4$LG/ntwNPqcJAc^B^?y<*By$4J+kh\!S$n+NPqc**c%B^!byu\ah1<e=4EHH/4VL
BtpZ<4 GuT5ntt5Ree1q=A%/FkqE:IGHc8pA6cka=Y$^^y$4Ldd%1Bn6h&&Bl&4:da%/Fm>?&kNPqbHh>cka:Y9
WhNpPt 6kah1*&%Nila*VC&Bl&4yCVYwGP%4:aGHc6>6ZZwYP&44WQHKuP=hilaQj^kHVyY/V85H^VyNiuR5hy8
9JIGH= Y+iP%YGNhYkjddi6R@6w8&$h&pe^:6cljdVh6k:6w\6u%1F>FBJ9Hhwu!!V1$D=b?1RZmqSNwH%$<tRh
FID\Xa &pjHT>cljbT4*V1$n=KJY+j&WTC?hYkjddh65N+!ekd4LTNu5N+!ekd4LZ$!YG@yp<F/!\p#YG?yteF/
ljia<Y T<$McE%66&%Ac!1qlR%wVY&*dWB4c466A%yV<T+&KpXPaamW>luRt61F&+DY%GG>DYlNPSy6RG61F&/n
GHYZty WcS1A1&y&!$&wDX%@<EG6Kamb&%Ac!1^yA%w#T\nb$B4blp=A%yVt*Md$Jyb8tyAc!y4yR%wVRZR&wDY
K>k&Ai qP@XB4Ttn5X6RG51%MEG6KaCiY%Ac!1K\\c$byFTt6CcShdMlNdWDZ/d$J1/SGIVYqPu>nclNSX*c^Nc
c\W<W+ W?>D&IVYXBbBt>CcmwY\Cc&yuJp&wVWXntWVYqNS9VclNSZAc^Nce*t$J:Tt\uJ6R95wA6et6I<Cb&^C
/Zp:d5 ?!l?$Cc$n+J\dWL:KN:Yb1FI>Vi$n?JqdWL:FCtqCi&n^!%6R99wHW8d$D=/85kt6I@iXdAJ:XPpbmc$
?T5>=& V>GtcWL:KJddJ4TQRmJ6R99w6yJNcB<FAN8E>qFW4$%wH#uNdEL:KFdZJ4TQ\uJ6R95wA4ei$Ye/>QJC
iySZhQ QcLQhPmSlZyEu?uRi\4%mD:VIchbQcLQhMk:Xw<Gpc+F/6Ek$4XAQcLQhPmY98MG9Mwi\Cw:?p^ZG8S/
A8ne5A SJ@y$KY4iuTI>Pqin\/STZ*TIVKy:AGSYZ$!IDK4:AGSYe$bEJuX*\MmjSdZa$JpWZMtSBb>+ktSSTIu
jnm8=> SBd%+KSId&W/INLuhW$HSQ1<48tATJ@ZNS$RcW$aIp$mE$SYmW\RYTW!RYTX!ATSQ1>4TlBbJVJDbJQI
BXW9Kt DJFNInNENnWuR&SdbWNpX>pFIu%W%qRk519iBTK:!m+R/cP!ykKSWkZJIFK1IBqED9YkRiSRVa\mXSPD
%t5K%G TGtIBP$n^%bN$D=!dNWE:TQHXp*RQuJ5%RV6I<hYVhA?C6G8ChyHca^4k9bSQ6!cwH*p\c1bI1XQMpZ/
Gjl>+K 1K!bI1XQMpZ/1K!bIu%WXl\T4RilK\/J%w9RFahER+/6mpPmIehY^THSpGP4+yBw!LFXeWk$=Nm1PCRc
qnTbdi 8q6YeWk$qJGubmk<=XGwGRyQtZy1l5JV<1icwjCWk4ltKD^hI1$bCp@ZE&8G\6Ph\%1k<BSE/SkmjXVY
%\9@BW AwYu%DY%HBR=lTFTc1bA+TpuW!%RiL1+Wk5WuyLa%AKFy%h>cwHC$$Mc6WDlKjq&LXB+!yJXC^Ti4mZY
5q\!Dq AwYuQEP%RPEyVWW6WHm/=XELFJ/TVNWClch<W4XA+Tqk6SawQD$qWR5Wuq/N1AWKV!<i%AKFy&8Ynl8\
jyN1R$ tkPFy+C@Y1D\FGJaC^Ti\9%1keJVXF<6WHn!FV8G!CTS$D:!FheC:TNjeT*RQk1+1\ZcS@F&6WD:/LYy
I?QH*4 Y1B>=BT8BhyHV8FcwH$WZqpL6I?8L6eC:cQ:!LXA??n!em*RQpy4Wk8$n!I*c+H&$YYYY1B>FMSZC:TQ
%^V:?4 a9ZY$$5ST!T$n!L%cwH&cW6^RQ5wL$p%cB>FpFcD>qGkcDXwH@tK1$H:!FheDhyH98J1mTKuMES&%RVc
Nm1&G@ S!Ge>SKy1*leZSu8d/in+MZt&?pqiDJZkKiL+MZK&?pjiDG>QJwmZE@>Scm*DcPa>hBjqKQMu$eW%Ne#
BkQ9Rd qSH1Lh+w1K?u4\Me/**iCQZ\clT$*4YNkySkNEhB!m?cw/D%XGkW6F+KnaLti9R!R4&KF\Y6b!!DICYR
D=DtKd P=Mj9<Q%JF/Ei55#Scku>W1EimW/Cpw4^ZGE!5=/SLmidwl\=YcNWKqb\>lW<46LkNwL4nT:Ec/<:lE1
&Sa&c6 DZIWyM9bS^T$E8>GRYZq<I=R!cTnwLJTlpc+HpWIWFi+W^TpG>\=Cq1*4cIkbV4MWbC6>EWB/ybjnwJ$
-Atm9K 0003b392f8900110333 Page 457 of binaries1.zip
uENMcc nc%ERZZhFI>\ZccPeN$9DdC6m<WS4q\8Ec+WQBG89F$S/py\FLS!c$bBjcYKmHBqPa%\ZV1KWNe<ayqn
VcGy&h ZhmI5L\XDDBF>GKA8YawGGD4lqaWyMBbDLB%M!5K$qWHDLCyK^^SpC+@^AEtd&&JA?^^t!^H1N5jF1F8
\#dL#> pdWIhcEuC6LXmDnA=KE6eaDJQ%9mAJN*65RBJ6>5mRNMu6pTB=n<5mWPMHqqT^^k<5tYPMDppT%^kMpj
<=iQ6B Y?IAp#i&^AEtZ?#FVH^BF%TnIF%k1FGR4kt%KEmuR*E^qRjY+tK/\8uma41C/iJmK6?4^eXWuqiLm?tK
L!N:Yu 4w8L/a16m+9ym1!Lm?tK1+8L/a11m+9ym1tLm?tK1I8L/a1um+9ym1cLm/t<4BaZW&Z46:ma/1pim+8y
JCLDat 51XdZE!XF6*ma9wM4I6\lchF1MCkKEkHP^aF#SWWFKFCXKIkHiuWKEkHPnWK$uFP9R6c>>I8kYR91MQ%
!t19J@ FKGP%p8EK/RmR9u5+=?9I=#+=?5AJ@:=P4/J>X!HN:Gi!:5dBT*jdlT$QL6S$QL4SpF=8XknZN:PAM6!
d/Y<lK Dpc+uGaS!tWYBeuJp1Kk=YKJkycDJRyc:yYdwGeG+jejq8e%DKZBP4MVuXki/ZPM9YQ=Xp+6?I:qw#n%
V^9lDl +A94L51bmj8C9bB#\@iP6b5<h*d9&PjEtiL+^K=M#$^JF>#i#5VRL:!i@Vm#J=>aG<F#n*qm%cSi5SL=
AcKh5c /<juZH#ea$qX??:Ljd\ZXyn@tT9=k89dJYdnHd96eRqdPHF@8+R69QB$1?J!Fi#EZ4bByBdV<$ubC*cS
*Xe\1Y I=dhqb*=en*5^QP6w@FhIXCZ!+:&9N&y?h^:I<=9@jRLQQF/tQBMcjiP6R!hiiyP:HQ\E5j!n4*P=%PX
tEnQ:Q J*cqhL=X?a/XG8RTpQYP*d!+SF/>5Q^Kb^c<E&h>BqSR??:Lle+ZX1:=M=*jBc5=EKu>%8ZYbu%k$@uw
?dTDAu tdulk8*6jHj+Hi6a/ZL<@<J!bb%JIW:5^8d=VQELX^u:=#6mL>#$ANKbd?LE4wa9B?MQZKyidV!#Kd>\
l%=RnW $=d+EwZ^nq*4Z/:PQjHRtu??tH#BZlPIHF4*^/cR:u&TC:F*:Guc9tMjP5M&&J6nFhn:?5!ai<Fi:*Q8
p/$H>W QQHWW*CZeI6*:D9mGY8mBEC1TRH&YZc?V9&PhXy%bn<:5YqAEQ5595TD9GQZXihLi8>aGZI9=?Z9&E&K
WtpNP@ &XC&It$8^?n9&K&h&XC&anuP*Cau#l1^:#*au8pwhHTj#qVnJ=ij=$\S?PJ#9Z>?eT1>8LSB8y^89uP>
6:m!+\ :ujbM=!<PV?:+PS!9DRD>$WyucqwV?+Yjdya5Te*6a6!>WTLuR4$=P1H8iHnLb$Jt$/8F:+9b6DJ>cd#
F=V9jJ 1RJijP1q$M5&1V*%iX&85%\mq<M>yhl9ih$=V^e9$n6ZQ=>yGq<<4XiZLwjS:bYFRM?%ZE#a>qKD*5Zy
E!e:Xc eld@+u1+NJ$9Bq&+*Iq^ZPpync^!Nq#i!#HAXe?KindhWWnuc+5u:/wu?1ey^6+=!%t89^d:4Tp&M8W?
DtR+%C \jXG:yp<?b*LeFc/4MD:il*?mN>hCXwQiT#Jjb1u!&uyP>jVQLuHj85!\>QFN*V!J6h4@Q%WqET/=BJ/
dTkwTI eXtI/W\h@8T/yc>=&l1+=8QF@jVPX:6KB%i@qVmi^iXqnjP$4NeIW?15#*1>QpF8Zm?$=\T?=6EIep$#
H48b+^ VN@4ANjLSIeqeNZ#GDQ!>b:8=TL#P>i4TTq?L%QTQNZH\KY9W6R@#8YB9#lD*:uGY+:/%k/=DhL=iMZJ
JeHGt* !?Ib9K:^k@=S@8y$eWT?</u^Z>E8ddQTtRd%=D=EWtd@%DZPJ<9SK?Eqw@=6/etM?56RVJdSQ$99&cce
G%h\@% ^:4Ae6VQb=4!p<?%91B@6Q>I^8?4#X$!6p5=FJJNnB>qcE8Z8K?VN*HK%jy:NQV#Plw+?H%q%/TL?@ZJ
NeQKe/ 6bV4IGPC=/ZQDX!9hbiwq<SX#1#pY1<*e4Z?Z1/C>tjCLLpw$yt<?MYHw6dVtSd=\tYHuP9Wp<@!KChF
9<Mak4 49CHhCcw8@AtH8Vt>cSl8t\d**uVY>8u*unu?w=u+5$Z4@IAy#PS>a5*LX&yu*4:^cWK$@t+#<uX#?j#
:+16@& Qm??AtDVbdQ?+nJ>$ypi>MYuplmqX5mqd<@p*E>i>H!&&y5mj:^mQ%4p5nD%IFLkTje*Ww*%<V&p>PVq
jd/iwV 55E:Z@%9GX^/+*K9+MY%Q$&ZQetLK@XiPl>@P*qd+&TC1=#LSc$u4<>?M*DNq^c@q*P6y!%?4:LCS>Qq
?5Xe!F d5+:%$F6G@!>:Ma#8iM:q$th?t#k5kQ:SQtQl\W#&1WR5ZVbud&+Lymp!&Ylh/=^&Cj11c5D/Z\R/8V4
#/Xy6w *ecM?5k@uXwlZ@%bWL+>=m@15?!w<*GyC%j=qd?Z@4@puD1==tqL+NK*F\@K!ae+j4@&Kbj4S?>eh8uF
:1j&Ky uZN!jeh#jI/uu!!96=@QeZ=!L@?!4*@^I4tZ!\H9ZPQ1jFdyui8meb4u>**^6q=tQQ9#^Xjc?<5/>iJ/
XH1/QG :T6j:PwuL!8y?iY5in\#J1:W!Tt&T/>q/*A=%ph9NK?*6eQ9>bK^nylucK?!qc%ZXH9pc>>/&dc@e>tV
G$emYt q@5uL::51M5FqHi8l!@Q=/SPd88:VQDX@?PIZE:^NM>><V6jJ??qkK<Zha8S/&ZTDLq4H#wL=M4jqm+=
ca1wcd @N:=mmKa/AjqLNM8Fd!5*/Q?dd*^!?@T%lPwp*Jq:<&J>m4Z%e1=G@pKX=n+Lm6S=YZ@>iI4@jdFnu4u
Xjp=I# imLwEqn@#uY1jwtaj8hnnWPY4:VL!XAjHentT<n9P%@9p^9KZ<<VJNb@QjiVDN>*44i%Dj$@X**mjC@>
$$T@AD YQZBPP?!A*PK<</=W6atjQi8T\jye1*w^iWXT?iVdCi*>bw9!qi<dd4eL*uu/<Z9G98#q@Zhc?#Q49%L
51:YKt 99kbZq\HAiq<pP:C%@P?p%#n<CnpT/?mQ@8cF!YB>@ZGhTNj:cXe:a6uP<lXu<d!=?J^HuYhyZw>*@q<
T=%6Y6 &6W/>etZ1:auX*Lue:&i4%PH>e#l&b@9ZL?@^M1<?HyH?yLC>J&9l!w5p/<HE\9+CnI=%<&VK*cq5Q!?
Fq8:I* utpc+JwZ%jn:>in4yn:4PcKM?5k#uS9:b/$:F#9luc>udE=>euKXQ%n?i9+H*/89aJ6?:pQj?TPhN:mm
6dwCT1 F@Iq&8up/9<$!bX89IZ//CuM>h%D@bW#XPu1&^F=Y5?@6BF=YjZJPZJdV/weaX^q@!SKeh>n?cb\9D^c
B&6yG6 LKi6B@Wc/6NY9%*T*L/+q5b<<b8><:1iP$Q=mwnReZDk@Zk<8Denq=<1Z\I+Zn!9b^EL!mu4/dST!XWP
A*Q$^/ &69Lm5kc5d%h$SC=H@F:>eh#wutA1#/>+9jcj?XL4MtL4<elL6ee=56@1Hm@k6>Qyj4PBj$@%^Q6q+mj
MA=N>F h/:^WK!VK>VNILi9y^65k88:Z?KEV1:/%ET8<t5GX&L<W6t88cL5R49$@IaT>LeY8X\T8eh?K*P6!=jk
b%%XMW /yP9S$NCQ=k5h>ZH!Fi:K4t?T&*kdV$$E81n6GC1b?\H=V!Rj4MkX$<Q4IiQ\eh/>nK8F\4iq4/K>c#4
i46\um qDZu1G?h4$eJWj=Kkyb#HD@PX/L<PH=<t@lah\d+i9awnl@ubV$9BLu4&Vjd<L:tL?1#^5Mqd8uF%=Ma
8?!9h% XqAj^cypc?mH>aC*Nem6Yw<8!bji?Zy1iGV\>h#kaQqn/YHWy/&H^k:$n*Ie=&wwS:ebe5W+YTqp>Mk1
8kkFCY ?Hyk6cQ?/<GQT%#AP%@Q8k!W9==PdRQqQ^/ZP<mqq@1B::YiZ8wH=K:H=C/JNh/=/6uLAd:51IJ&4ajd
DECwS$ i5F*Gi8B9+4/4EDwT+:kh/:9*m8?%=y*9cKiK:H/JTVq^heVdH&k@kyX!bj$B8><4b8X9%>&^cd<Fe^<
qp>K@p +H86J:bHG8V4cik+4ycjLZiM</ww8H#^c=%e*?ZhH@YL>Qc8M*?l:Q4uG%c@WIn5?VVwL=R$9L=9XH?l
M@J%J= YNu=Q1=?wZ^N=@ZkZ?n&!96Q!>9=K8A9:K&@:/y?Wh@tYSW*:M@*hZ?ldej:6QmFNq*uL>WX:!4/q?u+
I*lBGM +K$44lE@@PjQ9@@yl$@@@PuQZ@@Vq&@?<9#QD>$?@P1@@P4D9*:/:ij9Q*@/:88QH::=@QHdL:@@<J59
@G<ie6 j>aLBHa9cZwj@JYTe9:\d*@+>PGjQ@*:l%>>@QHH:@@\\<ejQ>%KP!?CQ$4Vt6R@@NhQH:@JH*:==cj9
*baeTB 9u:?:9ejQ1w?**#?<Z><?J?@jQ9VH#?yEnu<YW>y@bq?Z!:TFLde::>6*jJV^L>??8PZQ#%FZQ:p9NL!
%X>nX= ?JMmq@i#Wj@=<\<@*l4=D&p%<qZFj@@<*Vhj@q%QB4SdGa4XPQ=cQ#&L?C6>>G=tQE8Tw?uDQ@#l+@hj
>5558j Q@*\+hijj99VD=?@iqtjQu:%\u:<<QG:d#:<##>>?>&uH#:?=9P*u:>?@9VnY#:VcV\KYb*:+Ve@jj*/
5Ktj%L =V9Y9h&@mn:kZ@*yej9y/>>@@Q4^l@Z^*9?j=:?wb&#:J+<mQ*##/ejj@9D=N=??$T@9w@bZQ*#/*cej
dGqIiJ Qu**Y&@qZ/*Q@Y9@>?@??B?&6N@:>u>hu@4/yXZpPhm!SwP9e5iH9@@?i+&lD@@y\:@><QG:H:%iQ/mX
ubN*=F @@u#6%/=@@Vy/:>@?9Vhl/@?XZ@=<dj@<89%Wj/ZJjVH6*I8#L>MSZNId$\@l?S@>T:+?8ZD>#><?j4y
qJApb> 6%<@jQ@Vd::>@N5Q@?QVZ*:<<L5j99#^\>iQj@#?p$T>qZMj>!^Gidci^V!H=Iej@@LHQ*:/?wMZ<jHd
u$5/F: **@^kjKHQ*wFV5@%+!@ha1y#@YZ=<P6@@@n>l>?6bu#=+ePjQ9@\>ciQ**:+w<?WH@/m@Pjy@yeqH@al
8&VM>i @WFhERhhPX?Wj@#+@=?SY>yq@6111>8@:+Z<q&?@@QnnS/?buciV9$#%\@n\*ch@@@d#h@@n\><4kn%6
P=:Nji @?p@KYT>d9@yH@SQe@6Q@/kE9Q5C@$uB+Y*:V@>bWhbn?$@@Shul>9@$Z=XTdh?8u?8j>u@%@%C?5Q%j
\4ICek @Vj>p&*@/ShK/*J5@?tZ?1i>4H>YAQc?D@@bhdYQ9B?X=u*jqj?mRP%>X@=KTVn&=j:/L*@<#bh9X:H9
?M9PY5 R&MN4<P@&j9IpLL+?N6Qd@Zh89?q4bX9%QceJQ@+/de@@PZ:4&9e@et4?48@jQnLq=>??QDyn^<@j@9Y
t!#+PI *:j%n#@$9XS@qi=N?+*LiMqKd&e!\F<?Btph+!uqu@:<&#><@P:*Ql<je@t@cT:@8<@ED@@m?8GHH>@P
kGb9FD <<dH*<=!9Bcwj@np!6P46YdG^&<@j@Q^//eQ@=911FLi?4%6ycVL%Qn=h%>@?QLNV:>>K6<Q9@Qy@C8Z
aP!AZn >?W:u<?@?8H#u#:?>m>9y/@yWWL4+>W:@@DDJ$u:?Qm6@n?9^NpGZ/+?@@B&uqY99>eJ@E5F@hN*b?@?
DQ*9WS ?9Q99*9W?=<ijj68K9/!4w?mL/e@T^@?>cj99u6Y?i%<%P#^M#6e<#=?>t<j@+h?>i5@jQul/&>@?94n
+W>WAC &=t>/jFd6\n!he%?Ldaq1im9Z*\E9bcB$$Bhj=1Q/5bSZn4Nj:y$:?jj?84^#cjjjj:P%hKZ:!V8%wK5
hTN&$k JALi>a>FwZ#+L=??4qZ9%%4?jC$:H+NdQ*i6Yec#Jd@?!+>jQ@*SdbH@>$?jj@n$S%qed/hJ?<8t^l!8
4JP\YE &!@G\/56X9/K$bDP1=DQAu\bi/yyjR6XVa9V8d\w9Pt+@Wq!+@j=J&5wQP!p:$>=Z@@\<c5tnHjn6>>?
P#>Q#A WNW%KSRZhyj6%un>K=bQ5d@ikF5Q=PN+L\RttD:yPT:@RcQ8!?>@?Qn>H@/mI9*@??Qdmpm=qmij#K=H
-AZP^Z 000664dbd0200110333 Page 458 of binaries1.zip
i^5ja4 hTh+*u>c*YVenTSL:<QnPbDTiiV#@FQjRF?p@P1n1+FZyi9#4:ZY?=L8C?H*?8hj@@TdXiT6M?1>S4=B
JtJ*a@ 5Pjw?bjjjQ*+?j%:ZqZMq>?>FE\/d^I>@4/:%j:BHw9&R?<6jjVSlj:?<%hZD#:Pj@@yl?@h#9m1iLl?
:Y>CA6 ?&9qlH6K@<jQQ:y^+ecXK4Dt>%pDBb:i^T4@WS^S46R@@Qlw5mLC/8$QFDj!4Pi@jju\<b69H94=?#><
F!Gc41 iZ=ktWwL4SF<Q6d^@HQj<V+4?58H89l+c1=$*G6ZDy<p8^Gl!MW?:n@NQuA*Q<$j@6:4?C6X:@d>#5hF
ZqCqaS Hu>jcu@y5X<>DL**@q6/Qb%*NS>@$QLwH<41mGhLHl*^Qu$@jQ!V/>YQ9@qY$@KHL#@>Zq>V@MhQQ@^J
\ecIJ: p@LMS9Ew5hjTumY?:+JiQjt$NH$<@Zc6Q=>@K@Z@Z6K$WNJ<>jJnML$G+>@@=Q@Z6*C@qbHuw@Hna%Te
e!^?d5 X:9Y*!6w4q$$=?6L?c4^ZDu%u+>8PS?Zij^yeq%#nw<jQ***Dj4F9$V5mN5a5?\d5&j%q@d++68L::<8
j:=Xbu ai>14K<%K1h&MX/@??bXVh<yj@1<P9C%Wn+Y8ZSi4H1WwDS8P$XT$%@Vkthc+%YC4^yYjiu##@^9u:>?
/uWe:P ?!lqKbZFul4y\/??@ep::h&8XwST8lWnX<%t@NaTh@+99ZctuH+WwKe9Zn8NL^>??:IWj8<n:*5FZI*d
tFk+YB 4=YH/#uY@ye9Q/#Q8@VN?9tQ?9&6qcYM@qj:KT#h/V#<i9!6nt4PIjHyawQ<KB9p1=4:$+>QA&MXyVL8
I&hFLY <pj6:cZkHmdm/%PjA@#=me@ub^>@Pu&*@l?IZ<*?<cj99@<m1?BlcH:+?Q***&1KLd5m6Z6u&HHW@K#M
&DTY>1 $/J/Xic%pL?Q6q6X*BT#9?dmMZ9@++e?*A/?ei+9^<NI/*@Nk?HnYnNmqjd4Q*#Wb8=TWn=V^#%K56!&
btuF6\ <*dNW@*=l!<?X=eT?e/*$n=tFL$#dtZ$Pj?DRZIb^D1+Qt=@Pu%B*R%@L??HV:+Cj?@:B6?6j@>J>4Kd
bE^>5I #Z><@Mi6Si>uK19IdHQ?6St%:>^=d+=C@:eF=HQI8&u+$%5/<++?@qA9*D\Z%j@?G6jTi6i^><%#w:P&
8q?DSl >R1p8QYHL?m69&9kimqGY+c%Vj?$HB68#Z:=\dYNRl>8qhC%%jIjDQ9*Cjhw\ytu>@HZ94WccML1e1&n
Ld?K*q u::>=M4qWjX<*4%+@KqQ8H+K@wad8weuI%Skn69IXy#wZ^*bhc&QZ!@L&b1y6>F\=wX<qNi4:+L?j&6R
HI*ZnR Ck$c/imdehD5uF8?Su*:4Y!GYI6#L#iZ#Z@$1\L+lh61/XYim*p5FSiZ&quY1/jeI9*8$%8?:ITjBa@<
LdAF4/ %Ph8:##5K6q^Q@pc??G:n*@<JM?SY&88Bu:WMhh^?&6FIj@Xcw*@1FbL$h*?<Xt@jK?j*ly?h9@jj@Pu
QYZW&Z n@:Ld>#Ij9<4udTQ&^?aG*@Q=i!qF*@<<5hQZ:/VmHPLqM<4>a?@<$qeZ:9qq/Y!FNuFt=^48@%S>9*E
*D@:JJ #5:$jjhjd:wP5i16qGJHjdh69@9+?:5Bte>pNI?j>?N+ddB@@h!cQ5#%c:ieAcTQQ^1>H?<Y#:8W6du+
5mL%9> i/$@#+J8bX\ec18M1b*4a!@>D*@+>N8uFj:\b%+&Ghuik\?jj#i<q$:V*%hM@=q&KJ?pWV=1>j#l$=??
i$h=+i @A<*/jL=DMZ#d*%#jqqiyIH&u@M?aZ\R6K*LwGPnq<@eN1<@HY&@I*l<%LZD?^!?1bXdj@88wNi@NnNc
1bX/&m it\8=I9@>VJqd$YhN$pjSdW?h&4Eh^H@\j^/PK<*<?5w><Ju*nX&4B*6\>j#*?=d&HMi@59*D#5uu!<A
ZaiFNj 4WI6>Yy@XT$<8qF6@?@TMj<5HZQ4!ZV4!hjZk5L\9>a@@9Lu9@!uh&91!*e//p#@y@@?1Tu$^&Z*^>LZ
+%ZeXd /FGjM/>hk9TY@b@:\#X&>V%iG9XZW5a?Ah+nDkXYmFi=kBW4ej$VHWK@H!5K/FV$QhyYwL:q<%1/kM=b
qmQn=+ *?MQBQydQnQ@C+!*jPc*F%lQdX@EJ4&pZT=@w1DSM#i+RFcGy88j4P^Mq*wpQib8q>a1*>DS4&W$HiDq
*Xm?kK C%A/yZI6hPkE<XwQ=Xc/>whiWp:ZQqXcw9M<RCA4u>JF4HIWujqtBjVM?j5BmIBTMM$4cD1h9QT/5lih
KBmWR^ q>AElw/a^\Wwb>K%6h/8a6eQXha^>KX^iy*=VERn5N:999:CqB@yY1k!Hl*ZZ#VqSdyWjcW@Gqi^R<jh
JKub=< q$=in#pjq%?aZ1i?Nt+qSmwZ5cb*yK>>1wij#$58Au1b8q<?k=+cd6e?%SQ4b>!FkB=j9w/k>V4$6aQY
VlTb<L 5>D%<luYi>D>W8l/CHyej=H%I9KqnQY$ed4?Rt<WZ\jhi8T+ZKyi>Z4!hTV4=jddnQKYq*F64S=TQ@MP
IX1hI5 PNAL!jQc&1cun9NF4N=au>eS%BTIeB*<ip*=VI59wPiG4&L%%9!<ntSqeD18M%5b>+>4u:cXwP4!Kj9d
?>>p6@ iicw@#\W@*D>h?YW86bCd\?h/W\FX9KmK>B#J@uT=%%=j/+n9T9be:$WP6:PP$j?u@P6Z#/mh>9=XI@@
AZ$E#? b*44q+:LTwB!>wFQ>*HyiJ<d\<//?Zk:k>L>Q>9dGaDl@>uj=pYZ?CR@V>H>Q?jdibHlX&=b9J**Ej\@
dybwuM %#*M<>j4996qYPui^HEbSGZh1#?:wK\<Cte4m?+SZ&cq:n&t!=jWjc^$/WLh!:81Tq9*9e>?5ZZj>!^Q
cj:!c8 >&V#bZK6?/KZjq#i%e8Rq9?>ZAd\!6h\1a@yu8lFJhm/H*1&S@hp:NK=84>qq?G8i!:Y#@4Whb@&<6<4
qh9e\@ n<Lq9$%lNyi@%#%DP?W4Q$R:L9J$u?5!:*X@y6Y#9i9i&Dn:S@jF#4j6@d@Z9e*#>?5?a49<8?:4#dM?
8&SEB1 dh%@8@!*:mXe^wQ8W=^yWQ!@FTl$tYi/d#4tyZ#hS:lM1uY9=qL@9nJ*uu@jhe@q$q@4u6Zqi!qP>4mM
wYp5@& d5ZdH^e4RZF9b:bZ@?>%j?9!*?8?!jq>Fc?bL1y+4H5pb*qn^c8j@V6Y9Pbbu8J\<?Z:/^=e8TmB5iKQ
\46NIm L*?@+wnQ>m9?4X^$wiL?:jL>FHhtq?<@Fe>b#@16iP=?@u/88Mm#QqN=L?*!>/aN=PZ9hj@kMq+Xy*yh
ICiQZi XiiK4:*<6?IbL=yZ<eDZ<jj=:j!*#=@jL59^b@@Q!$D@@Ki*m/Z&?e>/6in>Q@@$hqu/@@V=:j1F@8Vq
N?Awi9 =M5M@bMKLyel>&jqbV@@/@Nd9jV*u@*H>dIa@Xq@*hL%>*>/c=j%@e@?u=j=<&i9#j8dlu@*h&<@??V:
i+@iD5 6>@<9*=YH=jS>Q@?:h@/L@@6L>>@i98dj@n+XZ5K@iZH*&5*i/+A@@LV%&<@?\d!4b:c?h@?<IQ9MSh/
\Yy=!a 6i<jQ@*+haFZFj:q?$@j@j*!%d#>:&?Qeja*@?9@>9><??/ud:?>@J@@+!u#q%??<Z4+N8NhZ1l%8>d/
tF*=!: %&>@<%??@N5Z!jZTu&y^Fj>@q%G4@WXT$jem?1*lPph+?:?8<+P*L:>:?+e9**&X%@V@>4P@?j8*iq:B
y!*%cI $=:54b+9k@uY=E@/:@eQ@hH*KX<99ZPS?Yjj^9#5$L?N6=<h:@@nJwFiK9nh#@+9L!JF59:q8*i&emSH
hjXan# ypW<5HW=I:A%5TNVC\JdF^Rmc=T^@GCBKdMJtQwk5QXm$y*ykD&!FVpe&CN@i&CXhc//VRtttSda&MlR
j:VNqB 91#A&qLppW&$w!Z&cX6?wMk/bikbLDB?*:c&MIG6%I?SNeyad:SG%mqnJR1IdPIdNYW\nG!>dubu9p&Q
#8F:jL +<D*c+p5Rc=9jX4<S54QWMHY1=mB4a%HbGPA/XbwaE$S$tANhY+Ja<$b?6V*H#Y!S*4S!NcnR+G6DZbk
q+TN!V BZ*14CW\M@/8R4@w4k94N\9Lt^mV&R/MTVt:K^uGbLcMMit5W$ayqLETwkT&Rn\CY:qNI&8W5b+jnt^R
W>Xq>u S8j*5HFR^tCjQq:wm/^DSn&k:*X9BDJ1kn:NNZNe4e\Spc%EWbEN!qk=kTPdqLET^RVYEtY5^*+DY=hB
EaTN$4 I5Ne#ZX\4NWXy*%u:eka>&&>P^Wb%wZeC8hH+>1ndGTWWT6qNI/%6m+QB4byY=6aG*Yj6bIN%K@uw=BB
B#^eR! l<t+\@jw^4:1G^*ShZMyM1+j8m9Dh5#Ehp#&<*1<QLJ%>TG\#HG%Zy&M#Dlu%t6dpY*$\XnJiAId%HX/
5hl&S8 8RYM6pYiB@Z#!15bYea/w#V6p+#niXd1uKtMKJE%/6Qb5ea4##jd5bJh*JlTcme\4t??ptH8q!Nn:yjD
AJkJ%D wNie6RbG?/Ae/:JqaP9mRGAD>p6=PEEDG%kHm^ZY#=RbJnLLG#dI1yG%na!&phE*M9yG^6nItB5bp#L1
ml9hI/ pViMMt1mnM$cyi^GbGWnw&^p&EbG*emwG^q6I/N6bQTNnLGSMVa!=pdGyI^GY<168tQDKKQq9GEdGYWn
hVMEcn a#P*tnZM\Xa*=dXNib*#5k*P6#c^Z!*>PMnYY=iSDdKCNe>bI%8ZiRP4S6ckm=YXlG^k9T^>^X9h&XlJ
wIyN+H TmQ4bLSL!qnl#+EX:MZLipe%5yWWL4CY!FaMatTVdCanw=/eZL9LVJX5QSkbYPGcMw%4!1S>Z&dD88>5
kC=%nh pt*$@S!NdGI>5pNbjCQn9LTD<%IbTl8aHYRX6y=6%nij9hm9Pt6pA#cIL8CCJi=%:ZFAEqmGd<RT@W*&
/bTBa4 TB+c&TC4<K9aI<FeaQSBYS1FdGJQ5mKh\ilj$<W*5kK@liZT!c!Reh>64YNMYy9Rj>dyH*I&!Vk@4HN?
G^/^L9 PP6pdTPndYV$na!^pVE&M8bG^1TMRh9SSpwdSlpnq\*d!CkdGdcSaS5bhTPndtT$na!?phE*M5bG^6nI
audDHY tJR^n:SlqDFV&VDKtHpnw&^pqI$M&<nk*qqQ&QN*>A5+G&T$YY*Tb1*Hkj%dQbKSbinPiySMS9?cZ4wu
&k6BIG w$>cV<mVhik@*j<pt#&8QZXqCa/MQ8tcemJd:=JFN5p1hKiVV4cmWRLnZ4It:mZ4I#HnuiWD?@*/CKeQ
c^*RyB nHP@b5:>?wnGnc!VXa\%9b6N%tE4/$F15kqd8Y:<\Hy#8bF^:JcC6WJ9E=MbdGW>?p9YaC94NX&!\ZFj
b:1F!t J5i>$R?u>%@J<8b9/c81Xnb@8=tDXnh@&#b%/b8@Hb8/#M*jV6cqytQDYJjHc?YBFhcq&8b9K?6TG&#H
9k6VbM Pl8@?cS?pc8$pk&!atS&dFkn1^5bhTPndYV$na!?pVE&M5bGB9ie95W?Nw\!W5wdSlpyd&TWna!!pYEd
udPi1B GdcSWVe!&pbG&<nwG^q>I&N5bM!NnEpbtZ=1b=V^TMkcYD+&DD/F>pn&Fqk>Nt##6&*#6>*I^8b9J@S#
D>@dQJ p#MTLLE8JY@?N4M8^Vb@T*>uK*Z#6&%Vq::=&:GyC<>Dt@GM9luZKGi5m=ZN*^dYbYX*m/^8/6I&j>5*
h<5GwR hStd9?X=TyP^S<c/%L#=&<&a4J5^/a5W&YbM%4cy!&bM%4Gy!&bM%5t/6M&aqJIA&/\BddMG6I&?d^6>
<IctTu *#c/9Y%$i>9w<ddS+^5@wSJcp>FQ&Hw&M9wJqTPLnH:C%66BSn?l5$FGQ/HCLeA&j5I&WmGnu:CNp5kM
T#^mFR hi:baB>$Hb!CVbTuyNJklZ5Tb=M5XdKeNt\nw&^pqI$M&<mwG^q%I/N6bLTNnL/SMVa!^pdG*MmaqPEt
LS\tYL F:/SJbbuGYj$*Sn*%e%\F6m6F4IGZ%1*u5kaC?aM?$E>1qZIPqtC4/DZZMuwi@CyY5l+S1?L1tV$QVkd
bp?ujh bBNu^%*Gh&TNb&P><Y^M!aLS>/%pMwM?:b6aMF@%+dh\N5kG#p/eNVL8i*4uPdcTpKQ9P?N>i8e=h6jA
-AFTBH 000f414b5fe00110333 Page 459 of binaries1.zip
\ZB8Y: B#Q+4u$*k:cN+$B=+$ka+?QI<BiQI&P?naN:#uEM?L*HMZHGMl/QC$a&!Bnn=c4>&LBGbl5b6yFSN#Lc
ii\K6@ SpcD:&65>k6n5%<at@*C&P\Z^tc@MDd:ljF+HCG\nHPtpR9$:qm9$$SY?Z$*>5bwE#yu>ARj/Pkb?tD$
Q/uSCt atS&dFkn1*uDNnLcSpdj!PkdGYMna&^pMFb*nPQaMMwaKY<aba!<pXE&M5yGlt%pGMjLwL+jk@4iYTj4
S=IItp beM&M5bG^6#ItFkHZaNl#ZNLH4:NtitHt+?:y+HN9GG\P&hlZQM5/hk\!mnW+<+&M5yGlt%p&EbG*emw
w@AGS/ G^q6I/N9bQTNnLGSMVa!JtWa+=1u<h#W@#J9&CDn8n<*=%9VdjpD#HAYQVe^de+cYe5dN5n/S5da!Bkd
q&JZZR GSN#hW:aj#4B1GVR^YphMyNN5q#J$H>muR!&w=/injc84lpc@4allqp=<iK=m%m$&?X%LQ#dq6E9HYem
9Ya8@P #lB@pLT=+6?YVtbq\!bb=Vj1dTPndYV$na!?pdEbB*%8bE#KGEjbMMwamVJGnu6h5a=9Qp4b5EqtqY\#
SbS4!D lpdh!GkdGY$nw&>pDI/lMVGGE9itTi?M^9KT5j?T5j@$F8!GhdJTNt\n\#a!/pbG*elwG^q6I/N9bI!N
<C*SjC nLGSMVe!JtY5F!pnT&uDwu&1=+e^Z4I<n&C\T=R>6JLBLlGD@6P4SB6GGYwhYI=u?YIa8:up8C@Ve<nw
Y=muj/ i>%QRZtqyR*4bL%5&CRdG^q#I&NTly/mJy6pmh@Ne61\Vqa&M5yGlt%p\J?V<6n$/Yn<9t/$h4Bb\icS
kIVDDw N1!V+b/ZGGZM9JFSNnLKSwb6bNlGS6*IcB5bdTPnq$HG?V6HJaQ@XA!&RDukQ^YdbQCjPwQ@XG\nw&^p
ui$^RQ YLTBuVYMwdLSPd=:\@k4KYFPq<S%6TTnnEhG=n64ZBiW#S>!G&LXuM*wu^TdaJ$/Y?>4dFku!&ZDNnLK
aZB<1K Swb6bNlGS6*I1B5bdTPnd&S$jw<??D*/tGV\jTZFPt>aJ$6q\!ln=I&M5yGB@dT#F9ejTT=+6HhM&E$K
B$Zt6b c+uqYeEhBGi$T/\kh6XbV^9Y!YnDPb6pp#L5TB6GGbdKlqGG=a&M5yFSNnJ5I<M&M8yGB8Lt^KCd#L1S
?8kaMQ +W/tYCPD9$TMM8yBGVWhG$abNieN&<kwG^t&pYEdGZWnw&=p6I$M?HiVuuiJ*/Q15n=aL9\h#6?e+j^N
hG:XBy buHc5E/G<#i^na!?pVE&M5bG^6#ItJTSD5yIKY$a=pJNt::T!k>YKytqDh9I+L/^J81e&4nZ4Rw/AcPQ
F?VIdR wm4Ika^>%S4:Tkj!bB5ba!NndGSM!qk9LwNSSp>q\!mn=+&M5yFSNnJ5I+Q/4@J?4dPYNw#j9Qh+LyVc
jEhcjZ bu@iDQjBuCE&^Sqm1MRcGiJX^Abb*<kaG^qnI&N8bE#K1Ahq%HS5GH^p9y9PG<c?14k:y:SY^+b6bNTN
5%=c1P nL1S$hqiX?N^Z8y1iLS*?!QyZ&ADi@68S@VdmnY!qDh5pGWnK^5bbTQDNnJ5I/N8bLTNnLcS$Ve!?pdG
Z?D/e1 &MmaG^tVMu\l*LB+=8WMPS8e=YQDGquJG:cSRS6a=>N^HI!E9AHPen!9EB6pmFh&lykm5WbYN#L1Spdd
*X9@Ka !PkdGZ$na&^pnI&MTSu=PDcMMuLKG$abn$jcA!5dGYWn\#a!dCPndtT$na!&phE*M9yG^6nItB5bp#LK
S&VeW! pViMM8REAEM8C:FGly\tawPM?6q*X9AF#RM=X=\lZ+HaIEMekDQEAak%541SWVe!&pbG*<nwG^qnI&N5
!&H4FL bE#KTMi^abTSW6+\!pl=I/N5bJTNDN9I5I&M8yHSNnIRB?AMh=jT:Inueyc^V5>iKlu8Ga4B=#5:@bN#
htQNCp IP:XYeLid\:/&?ewt@K+4*A&YB:ml@TA^Ka8!Ejl4QMdnR=@uS+TaHuItTRGG*lP:5@uVNAd#lypVNy@
hGhTl4 #nmGJ8/MPnP&a>bN@hA9PTZaL#p^Q+k#>LM#?P8e\c<5F8<bbt*GM%mKh<nFwn&i6ZRQ5ppbyXIGjJ6m
mI?F1D uVK\9*VYD54AjdYe/M5RG?nVP1I?eId#H4EPGi$wpNER/=e#%+?5MLeDDPj5YYh<A/^u@m*YcYen^4hu
iS$!/q 9e:T!Byp<N^QdEJGTlW!ZA$%5p+b<HM=5/PR^dt1q#W\Q@R^J%nj6AP?wL#^&&bhMVuAECjwnQ%uuj*u
c9#&uQ DQ&u$GpDa@<yqR>q\E?n6HRHbXmnnJwyw\:KcJW!i1IM=EhTc6>+@maYjS=/@CL/MbXKD@QI&WDjn+S=
b^SBy! 1j8@GR^=Ey#l:ER5unt56HpDnHP\$qb&^npwNWpbHEP%eA\=\^m1JeZ%Wtu>+uwyF6enb=!D8wKK*@Hi
K\=Qc* mdMM@i#1qHWi^n4:Ew>?aT+c5W+b*TkD>*ZFGtZAn!TGeX@h$IcMmd9taql@/$SM8dM!YB=<>Sy>nY#V
?JCFXD 6wu>18@!PF:p$!ykmGXZ!pLw&MceYGLR5c*mjFW#JqH8/JR^C&XM/AnZ^PmZ%yAQTm#/BLZVnj+eb>RH
#?p9W4 #V5G@hIRK?RMeYuPEB81FI&\pd1!n+ElJqAM<$%H$bTB&H$^&G9>/J8/+N^iKTR^*?Vukw^/<G<4a4#$
P8JG&e HBB5JGeV:YYe9qJNau++G=TBP+ZP+AMXc=TB@Cymp#It9%5:?N$c>cV8>&T\DD6:e?eu/<:QIGQjN<V:
1&4^ES PK8JMyD#$SuP%b#%k#IG?/DDB?AM5YDP8FcM\u*QcNS%8weS9>Hw8A@tLGNNGS&^AYIa++P=Vy%X%pYD
^EB4FA DR#uH&KDMyDQ*NqIqDE/bXBQPwPi%D$M>NZkupV*MCyaN5nkQR!^VltIG*bY&a/B??eKLeNeheT/#MR?
EwDCEu ub\j\%X^qKH$R@F*p:q:udZwG=Fqq9t:EZ*tTy%1pN6^^mIYjW9PE6aib^M!P8JjFILG6nGj4#PL9l8q
/qe84u hwXQ\Sq<FLMnhpb5WkdmcHWnGDc%t#Ra#@Jjld1WFXENlym&w1khMw9#4c!Vh4I+V9Z/aa^HEy8W$S6q
hJ6FCq aL!IDe4AiCqH^ukS/=DBZHXmE@&ZEV?yB>8n4$<5nyi!h4cBcZ5i//J$I\$M5T:PLK==aw%@Y?PeFy8W
kDBVC^ m@lub+lyE?8WkdmCw5NW!wD6W^J#d+6F*=I#uQE=R$!$YKeM*D9S1*\a+/uDy?y5SL8p=Ja/&ERP:KK+
L?8\VW X\NDZJw#*H%%N1M6Kld*FcWe!Bp5F9eXbW%YMN\6EMQ**eT#F8YPQ5nmGbY!ceX>lb+t*LRD85=*#4B#
M%JiL4 m9h!6CPKRm5/GQJwP5Q>Z#HW^T4<^YLwW/8I>*cGi#6muVKR$%%5Wkdm/=#l*wuakA#tQ6c6\GPThjSy
cDtEa* R:!6YF^:uPGi5DQpJlWdqNGM9?8VhS=5t^54<Y?XC!/&4baW:*1Iaj:1/Rd?LjK8mpGH!ehDGek@ZyRj
*JYZNQ nnJ\=$K5W$dHG8wMc/lT=cBjCuK6qjy+b@HPS1GMaY#91G#91G#9cG\9e*YK5d%8GFMG:p$+R/!8uk9F
Vy%phm i1tWEyA^pchTceXlM!nXPQ1K8bVFww*y#CyqIEbVdFAGanYW+n!^QJ!#?&:\tGVI\cu$/JlHnVGpSXew
FF>hHw !VkPN9FZ#nkPjGiAeiAM+/BXnkNudF9qPGmN+<Ab^pF4!JjtDQu$^SyqII?\&KRM*F6$luep^DyqIL/+
ZPuC$> KM?VpeH?W?/uRRd:4#ZeMZE6hLAhQSi!ku:8CZ6^Siq*@C:n@weadJC?5RY/Hu\mk\*T5&ZKRG+$9ib4
b\i+m: qIG<BtKhMu1lDL#S+k^*q*TNJXMGe5IwFd>BS5FdBtIay@/JME/h+j9&Ay?1M@lW^Vyq\Ki1XR5&hi<D
^DcAqa P4EQ=BB*q6lZI:P9StbjneK?G5n@J>aww^dK\F$w9h^eKcMu!pA56nP<d/B4RAhq+C$tQaPRG^u&M*wP
B9HRDl CDJt=4!e!Q@mnLbA=%5+#uB9RqiZaJ</k\*u5\Q&1X6@5E?hRh?QayY5\m<\C6=6EaM6Q*lZXdiFaM5:
e*u65@ k!*9Z^K&9DQa<4:LR%<N\=tT&KAM^Ep:R?!dYKiMYmmnV5yw:FQDQRe^#LhlPJ9XI?Tad<=kI@q1n4E&
JwtZhD JuLhq*pkH5pbelH1ilu58upkhqwMh6$<<M/A&KRM9Q@lDG>*mR*KRI=pb?PkDMV8/@tQVBu\/j9IQdCj
CZc4?^ uwq:IYjaC$*i1hFMPCmDi/HJZL6mk#KRu/HMS4@FdIkNhYdRaXIq/L?GP>ym$GGV5TuPEL<4^4HYB5ec
99A/\E *?\W+*n8!K5lluuyj+q=1dnITVaw\>kH9ZK<>M=&hPRh6QWkYtS!/IAl@q+5>wG#RlpFb=y/*mZ1SD5M
R4C6#Z h4Fi#w#48ipllCP!m6ly5aG/XP\S>aVMMek/bYCQKDayA*6EW=J#!5Ai$Su&mM/RA%cM@eL*ZMWt!=5X
a1j^al hY/+m!#YIaP=jG\q5mb4qIEenYKDMm4HXWNeqY:nXLC?cWhH*Kaa?pXJj\\M=>&YE9!V#lDHLSduyb+I
X%%&A% 1m!9SD$8%mpD>+SN1WWwA&<dP&8bM9CGt:N8qIG*c<R/be^CGSN#Z\qdICMnQq65REbG*uluiFhR4FEG
*nYCLY #k*E?H$#*tqXJ8>EGdlu/A#*4HXD:KCM$TkDd?CJDekwiQ9HqECmpHZIKIm@Ey8WkdiTVhibKIN/QBY<
\LTE/G !?kM?&/^nnqaNuP\aN?6Y@q5l^&eM=da##*#t@jN&PmIKSjn*Pe=p^nuQuN&Pb8e?:+>kw^^eP/Q^Lp@
>n^C+L E8j?\Q5X&yFAh!yXIu?H9C//Ia8/KLkmpcE8&ben!5A:n/b*Z!Fn+u$4W\+e6GMm=+<#9KXt/&ANDGiR
dBjQ:& #lB*Lab^XR4m45W\j@Z<DGZ$SBt+9/C$GwW!EDj5DHHD98M<w6>MLQ4NuCXD9^n8:all@lcn@ih5Wkb!
h<!uQe HbkP?Tmndh1B>+ThVhcq+8//M:\6wXRktL@GuFQPED<8Bn6H/cWcGi\e@>Qw##F6>!pD<iQPpHhGdFIG
4=!p&8 dYZd&M1&5bYN:>K1chkHPIP>JlhFIa6:IYj\?!nNTcIM=Pp\=itkDN4KX4Gu</=Hdp*V8TupN4!=/%&K
$t=#Hq &E8qJaHh:49XRwa:@YK\=d&4aM6Z=9qW/lQa<qYYHSq5?Ywb6u\%*LpXk//49IMqBq%Z4dEht@FedVVI
Z\e:H$ :hnHP^5aG:XQ@8&k4uMGZXeHhX$h%HX%WNjyjJW!1P6<?FZKwK:VtT6q+F%8b=%ncHA@1DNZ!8B?WGi8
ADdbq1 pDG=n*KG?cE#X<!Fmd9Ial^D5*AM#eI^^Dh6=i%MqAEjqLNYKAQ**%!JI&bdaR?\Rb4lL1k#uQtLaZ@W
m?PE#< DG<Hm&F@%A#9GXynDma^:I?W+\M!K5/W^LA@clXuTtKVMuCt=A^uTtKhMuCt=A^^?tKNM8D:F^8WRd>A
IKmlMG 1*mQYT!iT<4caD5ce68a#wRlq*tJhW$Phi+J:#$=M@SLV&*#P?V8eIb:jGKa=#$N#QP8&>^pYC6/Q4BY
yKBWB< /Cy*JwM>%DN6LtiDMuAQ*Bq!uaylu98M^n#9GY<q/^W5&JPhiiQZqWLKGEab<A*:LD?\98qIHiWX^K@y
&cudTj JIb>/86MJ&Qdl4F6w:J6w:J6w:F6w:N6jIhZYYIKba^JGal4eRYBQH^m5QX<t\^d#$e+dD%unVKRE$cM
9VL+eG <<QZGZ!*YVp@b8Z<tI*#a*b?!>p=Q?dk@PDd9Kc$B4G>\=Dd!*RWnd@%JaWMh\Yh+a/JGPw<iFhRDHN/
pSSQjq VQ11^pSPSV&>nDGy9ByS:p!IJZcGe*FumIY%#btZM?SY%@QPGQeKI<Q9?C/nZpFF*#64LA>^StK5T$ce
>B^8^u $Zy1tnIRb/T5aEab@cAM9BZ1dGVKRP+Vb*ld&&dl*5wb%6ybN8PkbH+n=4FSXuHaeJM=S=$ln68WwwI!
-AwFZ= 000831208c300110333 Page 460 of binaries1.zip
*ZepZS pB@hGjIEmp*K/JW!<G/GGMhRtS^DhuAM&YcMG>=6%qQmHAiGZD+&P@eR98y#99Y=?S*8a!8DBt\Rb>C^
?DPRG6 e?BP9%+Jlw/hA*j/bi$cbhAu+!#1K#$SHu%Bi5E!nnY^PNcWCnPP6bWi5+MlZ+c!t!ZKRL+M*Sk6qY^C
#J6<$c ^5VhNKZMSD6$4pEGt>wbdG1^PM?4p1G#QMVVmHZIKImuEb8R\Zh$uCGiSw^>WBBQ+\#^NGKhMlBQw\!I
LV4hH# ?L/y+c$A:cKm9$+5&u?85I@w4^PL@n1qIY&R$bF9Vt^RSnHK\H6Q#l4d!:e+qeWG*<l*mHG8P58d*?H<
MN!HJD !BuPn<V\LVQQn=\lD%Zh9GXR>baBbjSJGcNT^p!WkV#HNh6lpGHy1GSSV#4LWW?KSV%bqZVF\I^>d<k>
?pHRH& //\cbTDQuXmnnLFyB?=l%F\Q%4ttiMc!WuLE<p1mZm5Jd>p:K>GHJ^b>iM:\6yQTj1TD4FNGK=VSJtWk
$t<\me d:K#pTpD?SPh\a/6d8aenR#n^diNGC@P$Qi8Jm9/PiM6CLFwH#mD:<FbnZcmYKMM?DjEBtWkD$dXe&mW
J4HP&& kV\a!8lbKAQ*8%&JI#bFEV5bje4*9Kw^h/W#uC*Kbb:JpBjHGjLm/Bac^w5^L++#&GHXtBhHDPQFtBhH
D\d>EL DPQFC8\\b:DD^DyqIC>PNb/SX1p\!tnR><46n:>6mDNZ^8CB84Sb<deh5ihm<S!:!lEHGS*:D:FGGhl@
=&B!C^ mA*K\Q:DGjaja8!Dn9&H&KRM:D?1HEtWkj%HZW/Q!Ad&H&Ih+&4kZ4:a^Dju8^VPeC@jGj#F#uDj991m
u!e$6Q Al6yKWW\=Q%\l9MWb>kLmYF88iIwqI9#qKynV5k\uKiIaY+y@S>pGM=V/qI\aDlQEaM84wd#qKwWM/\#
dwA%VE #m8eWV@Z8tqdSa!4M<S8%hdkM/y6+n=a:d=eFnDpSFly:jt*PMh^XnAH?+E*@=^bwR#d%A?=/b&%VBq6
%FJ8DN WEa*!lkHba^GGSN#$Bt?bW@IR/Adi=mD#tDDhdjN+8>G\6$CyViD4V!M69^knIMa>p!DMR=m&DMN^nnW
1%Q4KG \SkHMi!bB8PB%>H5IP8WkZlk5WpbmAhYm4hEGakHhwaaB&iIeSCDu6S^<mTDZ&C$k?%wCddKNPRN$FE1
k#G5JA 966p9mCh6KHPp:F$#lBLJ+a/V<dTPWM5uSnY@eqaPq*D^dw@GW9uDLF$awM!pN8/Km$EbTAQ9Y:?F<1A
B&p%ae @>+b*p/1!mNMGZ%RBtJmuCGQ9^nG9XJbbDKM??tjA#It<6PIDeyA:u!q>aQNQ!j8J:iD:%1&hVIElulq
98JyN+ 5au!K8KXhcW/>9P/bk&=ZQPch5YWkZnq61^$5ppbmFhY%yqEGalZhwb+bYiIX^b4qIF+=dbGVGRNb$DK
i@*NDk YBnQ+<ZmGaE#*BN8t*5ELVF*pVQ+l=^lVSGLc+w#4CuTmDtV^VZFGhaWb%lV^Fm@nLk=5im@WudH8Q+/
!F#Y4t R>^ep<?Z:eA:%Y/w+H!@bX@&DR\?WN*w\ynMBjbGp?>\k8G<#Bu&mBwFWV?*#L8dLjQ8y6mEZN:hdJq*
=R6mww N<XaF>:hhAbj5%muDQmc^Td/!1Dd&$y?VDba*nDYidKj*Y/CnHyA=<nZB^pXiZYhIc?8YKeM?A?e+V$q
e8AR<d b+*>ZLEucT9bdtT#<Zh8DGA<V>#HdwZ^\GLSBuGG8##PeJhHLNwk#uCZ^^u8<wk%!5BhH4G+n&4K\ZTA
h&D:>/ Ia?DYGejVPnJ\4jiYpuam#9Dt!>m$CWq+X=9p*<ZjbWR:/M\N<^y:apQMQb#6ad/PWQ>K6@pcuKEDLJP
>*9^MF 8hmZmYH<?dCHu9T6RSypA#I1*5^yew=RSttWkViq^Cbq+J/I$mEu!tmhM9D?4>LJHJTBi!LPeG+kl4FS
5L#D\T G?/JKDW#>IHQI5##&yDjWYGH4A9j!FZ1GPm/ym!@aImDpteVc@hTMGRDe9u&n#QERap%!pAeqNmpDL\h
$qh@Ci :A^94I6%!tmFM9yBGamDW1bh&HY/Hn4A<E/ZMw>l4LYP6=Pe+i%Cb%!QYwe@Y\\&eP8+<!PGiiT#k&PD
G>4b^X d\\:R@^X/<#n=aa<#lic+5kMnDy:HNVbdq%BJ\:taqAGa8nE\X\May$!pI6BdFIGenG$\X\MawM!pI9B
SlNpi: GZI^mDZKRC+GMZ#LpR=<!=G+u*EGucl$\=CSpQhI4FEG<l/JDeyAZnyumFEZm:/HymenKlu&^E1SVBtI
JB/Gy$ WSiDjVw!a6Td4q^$M6muI!NGZY^TBu#eVY?>5d#G69ZE9?*Wy<1L#h@l*FRMipN=5Xpi#p&d<tJVB5=N
?:Wy#R ^Vyq+N!$djJm6$%i:LdJm>$&idHdJm>&&?VFdy8<&G&VF%65Wkdi?HKGh%@FBtX$w\#e\SJ4tJjMTTpG
9NqQ1n Q=JmZDE9J?K+uTG?*Sui9t&#+A#NGh+KcIy6dGCe==Q=J=*%VZte=:N\um6$tnI+#/h^up@nQFhKe5k\
#%!LiW #uQFP%IG:1I+M/\X$*D@6!ueP+M%4BZV<GcEM:\bIVaya:IhFdbi%@?Y!DLmSuS5Fj9iYa=4kDLSSB?Q
+w@WFM M+5^MYI^J1c9dKhpp#Jkk?kILXMGal#/!t\FBl>FZ=q&InQ+KMRt?5@kw*AGH+Xay\#alF$*lTtn5l&G
TNk??L i=>><$=eh?5KdW5Djk6u&DPJNel\yYNpGB6/WHPAJa\NQiwIGSN=lMWtbTCQ5DL&b<yAHtFu:FP=a#5b
A<BTLj ?$<J@<p\N9SaI@y=+l%FMa!N#L^qmlyBP@KBM<P?<Y@w>e8+j*PY+u4bX:Jm5tnjK&%nk>!K>+VFwu*9
LJSEwH 4Bqq>IM!P66YeR?w4+T?aNn@>6KwE@WEC91kaj?4qJS5l&<\a*64Rw/W:mP6p?FijqeRC=l@6$IYdV%u
ce6DVS Khy/a6HY$=M?$hb#XqnuYnyqYKEM?Mme%WabLXMGjQB/chWwa^!WkX^@#tclnAt>WZZTBJda>+*#4ddC
ZCRuV5 h4VN>&*\@?qXD?k@*dPPjiBDLhwY9VGQmDQ5IjSeEd=qW&ApGP::miFd6wL:jwwa!=TB?*=h:nDK\H$@
L$6*iw 5W+buPjPJtX\unjnQHiGih/M<%^y/C6bw\#+8eRtbeDQycimEtZk9y<#*Qh#l96?a6HQ%bW/9=EN!5D>
eC/y$S bL$1R:p#e&^Mnu8FTqc!mj/dPH6T%CH5#nb^>8RMb$@PcNe=\>4hD>y%ipK4kNG8<=:H&8&5W\d68tXR
+AhIt/ pnZKkK>QLN4<8qpX@WQP+P5V\@j%qVd8B=*SB8qKEAiG&JT8SRX6e>&P?6Y^?h5BY/XZ*AZwi856pYH<
QB9X=X >ba\@y^l@LtT4bTBuPS>KTI\M<1wB&XWnn>=%<p+@q4u?G8D+$@iF4DJ<iiD*Mmmu/HLb^u4MlL@%lq$
Ee1%:L uh\=@B*6>yFw6<99iJBlDMu9TBuIaTDYKAM=DMVaB<^lwI\\mVKR\$BZ//E:B*MamEFuD?a\EB8WAS?Q
XP%+Zn M?T*Fi8WkS\Ga6D6k#pM?tAPA/XS^:\e#Ejl4LNQG*#la6B%MyHR6k=j8Bl$*iC:l<:kC^h4qAFj8Nmk
>q:EFm DL\B+A!=CMW/beBHJkb>NVy<bH$\@:&#lD*VGMk6$uWX%MAMNyLenkWMebbm5JF<SacNyQR?qIE+T&iI
:Hb98Y 5^V4pJERb>uqb5lptG<#ed+=\*!dmjNNKapwk@QNY%EwA@tpujXNP*A@9p@tKSyH#6GZ1!P$cI?Q>Rw!
tp9&Rn GQKwm<Z/Dd$CiwDlnTC^kd4wpT?\hA!!DlpFd+iIVdT6qLkQGDLDJlnYcX@!eE@EGiKy6VVtSDbR9+Fa
5mpc#+ i&hnI^i^>pPykCqn<46N=Pq\l4^Cal$!JtI/uCGtR/!lD!bmP5Rt966EVIe#^HTIheyAVIi#5YpH<yj+
KLPSFV $u*E9cR9!jA%P<NdR5+G/yK>E&JhjDtQ/+haZD?e+Z%55REbCi>nP!8JM8B9etb5Y<LhEYi+P!IVBPM=
CdiiXa J+=u*@XkQPjE<i!5WRdH5#PM==\=u4Q@EH&X+aedti@NDn&pGQ81MBiIM<RcKPMi=yG4F?m@W8DnEWQ>
#jQdYk T8pdGan^E88WkSk9Min:awn^ewaaL:G+^n9Lea%*X8IcL+d=yyTWp&^TS1&WkX#Aay$!P4?daY%Wqw=K
Eh4HD8 ^4GllQWJDHhkqPEIjiC5WRd8\IlN!5A>$tEJNy\a?pDJ&mEn+S/yYKMM^LKLSV9HGh:4hacah:Fw=?mb
@QB#Ay tpIbiK@Z&hm$a@JdV8ThGT6BA^n&M<+R5/P4XXn#cpdMnlnY9J1^V^HDtqeL>mqDd$pcGhcb#X8Ta@PY
hkBEBR =Nm<JVq$B^Y@/^#*Xh=/ML#XI#ba*5D<1NwhpGF?KE@1JPQ*>e$>bA#p6BQ4qFHaj#:nKMQaj\P=qMW\
!68@d\ Q*R>Bh><+J/l@uLVD9lp^kwmnY^TH:SJui%db*!QN1t#X&AGGHY&kkkwk#1:#dcyH*X&t>Vb4k$P!wC@
+F>QPh TT/AVBtI!@ZF<5D*/EjC>*AGjcZklRStG^uI>#4Y+R+a:5I:R>!@G=l+l$$Ma/&*^Lc%#Lc%#La%uPGK
VZjyVI Ve4AGi=RCCqq+A#ZGe=\=h++KANu8AyBK=R^JtZkdGjIMV@JMD>e4eEYHRu^ae/R=&:Ih*mA+Y$uMjVL
hk!BRB TLn#/A^*H5ZRL::bRL>wA\IbGZeil+#qRVawA*eiFX=*WAdilbedKXMG#mce+Y#CGe+t^Dyq+G#C&aVi
a5h%NS eIc=NR4u%6m59/Mm@u=wWWGhK*J5Dh%ndtTaY/Mqn1GYKaN^BZ4SktNIB=lpHEP6ek!%!nHWG5hR/^^D
cJ@@wB ClaHG^^D9uBS^8Ra/4RFB5<ll8JnWX=H:lm^nny*=QBVmCdHdpji%VE##9meFenRp!CJDH6u=ei5aQ&k
&!R9JS nA=>=XbuwR!<FVYWH^M!*HV5bQCl?P+ehwu!a^wb98W5<CGQ&ZE?+\^*bIiPhS5b=yH!RMb9PRj8!Iyl
i?nS\G H5&BP:LPeEhY4FMG<m/IVe1ku*AP=F$RG=TBh>n$Tk*:juV&@eAd#YK\+idkuuN8dE\hu&P<MIi8IyPl
luqDu\ m=$%!pD8I4FBGelh=A!=m<R/bTCPWY^TBuIZPcP>=w##h!J*$X!PiLI+j=*lnRi^PMcX/TDc<4/^k1>Q
:PWBR: Hq?DnIy+EGh+N&%8*6/dt:j*=8d69dq=i&>8*6/dt#9#e@Q&unQ+Gb#B#!DYKRN?BnH&ci8NM4DG#*Wd
@TPKFi AG\cbHVEZ+q%!PnIX#XZBCwajFXVpb8VLN1&ik1Y+/Znu8FeEYhkLc+XPl1Lc<4WXhwwN#GjwFk<b%>y
#*^JS5 5R?!8Md4?C&8H*yGNqEG%q>u!Q@m4B/WWS6q6E\b8N95DHidhV!aKAN*t=*ld4NaQGhZ89CGjm/+F#MV
\<bBVd %>?y*LPhdPL:?n1I?w%NQ\?e@!wVMMbcGnn@FeNaT\Qu9&KVM8A9ead#Z:EPGSQu9</Rb$i5RebELJQa
ZPYl+* wA#p&ZGGQD6mHAi#el^MuQ>P^bqn4E*5PeWGbeBj+15$<1M:c*G966LL^*dw/DnY#:h1GZ@d+dhXql*M
8&&HZJ <<^<*E4>n9GZta>dJnDtiYa?d4FGGjD4mR*KkF>Qw!BSB6:KW:4/\n=AVtPb:bnuiTc&R!M/5MLe:$wS
^%WM8^ n@1X#9Ze4RnM*>LlJ^VD@C$hjpI^#N@T+Th$Bn?lYKeM?Ath\W<w%mmD+>+b=t<b8L@9DP<<m5F8Kk1&
w^kkVG Iy8WWjmNjJ6MGad=Y%#HN4AGi<Mb:A&*1GF9qDE&:iD+M<b1VC95F/X<dGDI$#cXu@Wkm:=TZcjLqF5H
JR#&\^ bVTnDMVRm*ZK\D9payM!<LdJ%BPMB>tADPP/cp4!T>aww^VK\H5^W+</XnD+LMZm*6+b%\<##mM>Nwl9
k^6S@Q *l9:wPN8lnQe#SD4LA>*M<Sk1!k%PGRM=HRTk/%mk:4PBuYhWn=TBuYhH4/lDPw/p:PQDL4a?BcPM?Sm
-A/M<y 0002879a73400110333 Page 461 of binaries1.zip
L+C5#5 EMNcbu\LS\^4tXI\^h?%nDmA&R^9TW+hB@B*8B98DHjD^dA&N5QheDG5nd:/RnhyP%nIBtSW*A%*l49l
>+&M>A ay$!eDhedFJGla:R&h%BBl*SiIh6/m+F/n\SW?/M6w48VdA<&m4PaI9/Llt&1QLkWkb<d6P*9>Aq&lId
uyJa&Y GH^8i1EK+/4#*8LWtS^q\Pe&hTGYM8B#E^8WAb@d:I##EIPP/I##EIPP&N!qtN$K=S48=ny4md>4?Jc8
kcmN*E mjE68!F8e!yeGZ%kp>@TcA9+:yjj5mb?!=4+LjXmB^t@bT*<qlX^t&LR>?6CIln*yn19^di5*J9&m95X
E8K+^1 P4HGi1pA%A!GuJuP/K6!lt<$D911^nE&M8m4W9AqbCV/1y#lG@t!mt?pySa!EuK4P$QM4NmkDK+#9l*E
hGXwb6 N*KGd#RT<9M:/@^G6Y+a%>@BM*1^ki>Y/jQ%YRSjm#QMZ#eFTmLn&Gl+T$PSEG^H\%5cPna\!pBPGLFG
lmYR>: GZmZRk^:V6*Z\HhVJmA!&B5KPwGMn4QbPZuub/Z#HYCI*ZKG&K&=uFBkmN$TR*9%#CNpbJ\hm/G>4p*S
BB&Vik *yq^^$T5WRd8tIkN!1D9*!*CVV9\j5CWW\H%a?+^HbQ\d#9!8nnDuSW^&DTVh%cW/RB/#Su$tlR1?5AX
\BR<i* #Q%*48l!jPhYLNy%m\Y:Vm#t@BGLPZ<YC&8QYM#=I^djNXw5nGi^tQNu5dD*e%cPkh?l@/V5a?^=ipT>
qKYyRG p#Y$h<S:#I6N6HjEi<^m<S=#ipRQk5X<jipSqWZYKCQia%=5wE>H9MieDq@hCqtBDF*9+i<19q51Dh@N
#+EFG! Gd=dK9G8t>lIqDE/bW!DDD8PVNakR<G@bGPC^ViH^EymiWc=a$#Wd^:5q^q#J+lqk+#J?i8MjV>6I<Qa
u>==88 >:P!:&hn*<@G9y?hjV<H?&AP>9&e:Q5=MW+#aldFa5#ma6*APJ+##yQFay!$tGZKmL=I5imLFI6?keW/
aXNq69 bWSj=GKVMpcqnLlGLRc>1^#mKA>&4FnP1F?q96L^IQ/&^uiC^iK:*GL^Dh@FP84eD1^HTlMIGT%lQew6
IeBIIP a#*KTlACXw\!:KAMc=SSM&ZWTSt6Wpbuu:diKYMW!ykHbW#w=?!&a!WdpNGVRWdQKbF%!wm=:^cdqGGX
<GnR#F MtI5&GKDMtI5tFmMBX85WWcMBX65WpcMBW5!T#m*Bt$LH%ZR8:yHFiYYe8D:/k&<k\^4RCpF<>eS%kBu
SBKNqY 4E8ylVL1yI^YKcMu!8mhMwbS^n\wa&IN<GbkDZCGNcDkuYY^nDZAYciMWmmnVM1\Slp^V+ha\@\w+?D*
l#<b!a GAu4l<:BWN+\%t@EHFFm6dG<^u/bmh>6b8n:wyM%MDQ?deXcylSCqN5&M61pnF+ya!VKGIM!JuT&Hi^:
eXiBtF P\:MBV5T=wIQ9<Vj$d:!aXDJC9TX%b4=8+4^dJZj#Y4HiHcG<Y^%FMwap#It^4Pit<%pGAe?^DEP4GYM
wi&XH& A&ihMp1lnIK%&=yl:VbZR@F*i4k=k\%<!=wt%1mcD/^S#4BG?Y1ENc4tnDXKn!>VStGh5^&Waa$!c1GM
JE=&dM PmtnXe1Ij4*FMGj1bn@6=qyDiiPA*6D>M6S=dQyqdQyqdQyqdQyqdQyqdQyqdQyqdQyqdQyFCWLAa4!i
B+Cwi> &D\wa:K9jHu4bNk*8pXaIYQGjHPLhe1I<RJmB9*T<5S/yMhNBqkc@F&GQ9ZyC^6a%/M/tMEGhnayw%dK
cM^@E% cIp!Y1iMZmlnHJR^GtZMVBpVN4Cd@LCBt!Z&1TZwF><JRd<+t=SSKtXayk\dqEGh1HNu!tmNMu1lnD+y
RB8bM$ a%VKtIp!J8cSHu&BnJw\n=^lH8u1ZCedqFE1bXmmDP8WEi<:L#ayw#ZK/Jp!8Nh6t:%8&?^%&&c9&#b:
VENMI/ *ddb/:dNZ4h6>4y65>h6t:%8&?^%&&c9&#b:*ddb/:dNZqeQi$Bj6ZkPphdnA=C44BJkSl$^K9ajVbjP
AwT%%V !FnuTj>Rt\Y?QmWHN:LG9+%uSa9B@>ht*<kamVJGy+\J*h:Zj+Fl9<C*iSedLC>ZqqeT!!8\V=Ynpd?4
Y6ly!k LM<G=pi*CX*e/\H:4>iE@cyeCw$M?>XiC<bL4@VdK8E\bhC?X&Jh%4qBZ?py<jk:9hh:kNEZyDe<?L5J
QZVi+H Z+F!/Sqa\u=tJc$B!:Cy?acHYMFcMdJB9+\?5G/NQn91QBL@h5Ve?YI^h:=a#J&@&EbG^Vw><Hb4iq#<
5/^LM! BP9R:Zy4Ijd#6AQjjF1c@B**pkwmHYT\=Thm$MTwt=\%!1B8enayw$PQK*m\ptGe/q&F&H?8PtG9PaP>
q^pVYa Nm6%p#Qac:Ntw+!TKKN$!4BCGVayw%dKcJp!at:tqNdWBMQiiS&a<Zi\ceTmVcMMPIZq6dkGmEXh:C#i
8n1WhE $ZHYa/+\b@Sy1YZG*<FjLNdSnkF@5Xn5?/S#W<1A9#m6DCbk<BhL/dD9S+\^VE9BbLI+j=*Nmu/b$L5y
$p**#< +X%85bm@YA^uSYKwu\<D%M@byF!eFVtd$W+W\#lN4pwKYDw1YdRVuiW<!TbqFI!%4AEIN1M>qHKK5e=m
t6!*9Q CY%V?G+C\%=*Zd84bI$!5NeXt=TB5%SuPE5Xm*bJW5/+A!#iYZdY!+F&hJ#%/myi=?<c=1C8$cP>9YMP
itdRNZ =n+\B=$N!ymak*uEYLDFGtRMuE8Kaa#ukVW$biTpZG!kZ\dPTZR6EHJ%=nDB!5Hj^Ve5^iCuES8WC:5+
\>S:\u FeT#L6ayw<h>4hlpuRjtquK6Sdq8TSY!tNhk5YldcNZCPHY&pYF^*=PWL+$!c1iMXmmnH=VSG&ZEN^kZ
kd!Jw6 G=R^DVL!kjZNjKJDl15@Mw+@/\*418>1w\<k/W+Ij#jbB?NkH#C?!XqmH+#EQlm\4=\X>5GAjiW59u&^
TX\K=@ %D*tj5XhI&h&RBhZH#ADLPaIYC#c@EqZFTmn#AbtqVJ1yw\/KIQ&S4XNi\*u$<+G%4J&aA@t4G^?B=?H
@/LNBn M4yDN#X=hMA/hJQTGk!\WTqnJ51a$E$6^b\@m$E*6bR\Zy44E5nXdABn*:jEihRc>8jPimadGEN/b5DI
ZSL$JN MIbcQ#CGYp>5S$iMq:QMhuk#an8<^tlHL#n4hba4j%i\hn9D&6&LwT+h?b<Zk**c<i/e5=p\Dny!u+kl
Qb6Dl& upG55V#EM+lB:?whZkQ4:K8Je/Gp$F4$qTKCA^8X@VJ1jL>H4GMhZApW\Yn9!pWS/!#Z=kBLYAN$^R+!
*+t=/L Y4!@L%c\=%Rct\^YaYjQ#j=T#>MbGhcbqV\BdEK*4$9>piWD<>Ib=8Z$hSw!M8J8^AbqIP=G+bkHbZCe
q?AG#1 Vy:4mp*$M<>%qhp%u48Iab#1An>q+Q^TDQ5WZh^B&@4t8?pXCnDPBYiWMa/K8w!WKqtHDCZaA/Q64j^T
/&>kAG +ZhbAXNpmDXaIb@<Heb#%68bSldHe%dR#kDDiBd4pGGIW^Cd1DQ*JC6MNaHF?=#cV5PYX/y&I+5=QeZm
EVQiC1 ZRw^^EGJSb6R$Sb5&?^5&+#*:5RR8!<Y^/:T!<h+qT\HG*=ZabhpydMpK%GQb#*jjaDFuQ%mMYj@al5b
Gw&%+5 MYi@&Dkwa#VKkQ>bDGQTnVPMTSqhmR#j#XeQjDhhL$P@?La5@p/?qk^Ywk&eM*JqL^d6!b!SK*8^GQPp
Fm#t^I VIRaR@KlWMda%Humt&jGD?ZeeEcXqb+R>i5+t^YLjmquPJ6%l4Nb5ad/hb#Nmp*K\Nt5M<Rlm*Z$cWh<
Y8JYhV y#QEh+w%jLh^aH/W*A?!kZcWVD*ytl%#&qqe>=%l*e?diN8<mdjNt*ndZJA*c4F+Sy>L+@#XhSj<LjKk
Vj\b5F mcXw<+8^dV%D@=YPtEyqAGQ@/bWdM8mNM4D9hwb>6>lGS8E*GwZ6GMb9NC1@$cn<S44RChaQ!8mNMlA:
8y96i9 KDaya%dItImSE<PeKZkQWm^#*M@eKKN\9E#cPYWc=>cEL<%b&<nF8b<4dI+ZN!Q\#c$p/BI4GdyEPZA/
GGn:SH YM\=L^b##m@YKKNt!1mDMyySSp?W$V6qnEIba%LGlB&t1%?JdECGuKBkmH<Sc=RSe:A9Nmpn=5ASm*i?
J@85^T F^9+9wd:QXuQMiN*A&iG&T$p!ykJc:LTKYR!/DYdBZch#bnZidFPGVG9<&KVMq1qnJnZiVH&%S#51#pQ
SH<mil !wl=ubX=<ak?e#HM!*4A%/!5nbnu>emhMuAG/e\P!pDMn4PcKcMP!tlGGV%SS8?W\jtteJ<+u15TBwHF
TEZ\6T 9DlJ%>Z\Qh^C^@hRGA@cWR8@S/Zi4bX/6%d1ZYj<H4Z^i>VP:%E:9$eh@B=%<H9W!i@S1Mi4HMFkmh?n
@pJ8b* yeu!M8XP+@iaLb=SbX?NaH8*k@86yk$\Ya!jhFblN#tdqNE1bjSEGZ%R^nDKtAhqVNnwLS&\dS9iklZn
mpn#9h 86wT%>YY8K:/b!8W\ZXX%#wwk?815$EbZFh>&=kwk?61T=#uLZFhdau41qIyJ#K51!%#ZY&b/&4LZFhd
ZMq#Xy =44cM6jXq4t865^%%XtunGcW$R@K/I$!S1cMMTkn=1ZV+%a^4?qmHVJK+q\6CZNcKc5yw&VKwF?k?hcK
y!JmHb Mm4uicte=/X^u99tmnI/=:q9cClneJ/Z!ZuPe$p^#uNLuPiYPM<6e=:L1CdnQDjD9pKy\Xqi=Sm!^nFp
qPS6Zt nYMI?i9EB5eR<6iJVc\X!qYHP85CF%nt@K*Ic=CXk+:qXjbydi#Vne?6dZ^84hIGeed^*BJ5WYi\SX9L
n<S5BP %CY6WJe$uHQ1Cnt@iY9W+/%Vn#j/yF8nV:4%k*P4H=^dHjeq^RdLM+:Jdl!VHZenuTEtiq&Qb*tdNcXQ
</t4NE ?BVcPPBVcMn9LbdlQ>AhBQ+6#5ce%eT@4j!Yk:+9yaNmZbDDSa^>NR?89<1AD$c:48qkDc!\4=T>F/^T
N4RpXM J<=Kudn^M&#8QtVhe$Aj#Atj4>+9t&AJ>wH*M4=9=:%ib+n4E=55n#:>j6Cu*\@EZ!u6RtN=QMQwmYea
IS^@?1 QTZaKq$J@<FKbZtYYF+6LK<hLI>uZy%u8M=\^$pMc*jHt%^mCj98Lm<!YDGYl:5b#uA*\^q6%y=y5@cM
\dcLMm iCR^?C^:PYBHPIMh$R9*uL%\#/paDJbuqiZ^VKRZuwq$=D$ZG=\j88kjtS&eH^8dyt>5t5=eTGKeH&/4
SjSG!# HGVa/@yTkdY&G?=l=M$hInGPQ=5ej@Zk?K6eF=mZW/G4!CGpq%G^@k=ZX%GGZP5wL%ZIHRq^ktK\l=TC
BI6hY& @TCdqDE1be^EGSQ4q8+XRWbPYM6$4\k!e5c<%D6:qFE1bXmmDP8WWR6qXH/n*Byq>E\bjXDGMM1aB&XM
MDcMn< &H?nHB^DlVy^FP4EWYl#PS8WWa\!:KAMc=SSM&ZWTSt6WpbQqNE:ba^CGjPknAq>wPe4nA#4$YC<cB/M
WQ?tAe F^Z4qMF#1<F+WYe<6^1MF^ZnQDiiY\*n8bW##uQn8hW\uq5N+:uX1D!*e5b=Zuq8yTP=VMb=Zk9uiT&e
+m6kq1 =>W+#!9nAJ^^uqi8ie++#!9nAQli=YKe=*X!u4iD<:#^DFi=dDMb=*uLuPi6eJ/*\uuinQP<Xe:#Su8e
S?R1F9 iY9F8LhZnq15ba%:i^&=w4#P9j%knK5#:8$H::E++>=?hP:6S?jijuV8:Wju*6+b:I$^8LjZA:awn#th
VEGHXb >MSNbZue&\@iZe>/cJVqeY@98$H185G>9XKcFDL5:X&VeQ#N#Vw#8dh*%qki>@bnet?9J/yaH9j&i6A\
cdD+j4 q1jHAR<\*Ch&l6!8myVMLI@uQjPwmiZX#9Kwl?bBQVRQ*Jq!ln6Vi8wI<&Mt=LDKi4AN=TZ/E/h*C<8n
/nFcyL QV+X?EW&YB=6d#%Yq5Bwi!6*hANL&Q9NuLH*W<wGqwj:XtIaj#Qn9yW#^m#P#JnF>SAY&PV+K\jHZ$pe
KHNYKC j!X#@JZM<XiM+/<a^%?l9V5L:X$>DMZ!B5ijt#+w#\/PQ?P=%VTiY$*il<%/JInqXa+@6/XaH8:%muYY
-AKRQd 000feda115500110333 Page 462 of binaries1.zip
YC+#\^ l=!Q#yD#Me?NQVR*>6C58L?RFY4A<5^aZp$5n?ec#mdLR++<Minu/dbKIaN?um%^j4VM?hEK=$e##w>Y
TSRPpC PV>c+@^wujPnDe/QNnp@&8V</Iu#w!jPn<+>??!F</Md=$i9uB?hi*E6bT^9eH:$!jp^D5/QpVk@qKmD
!CQ+Y& nQNnME=tD5dJVPbX!=N=%b\^NuRP^wdPMVp@=5H=MdqZ$&MBKG<Y#w>bPD>t=j!anG?cp&i8T64Q<8l9
GhZpIT u%=kKK@+@+u#w?l@K%mP<<Mb@P*PpE8qKAW&!$M?D:HJ<tDjm*YYB@6i$Z<N=TZa>$WlVmk9\d+9M5%a
KtK#K9 HuKTP<N*K<jAuab!MHh1PjAG6%l<k*8^ludkDi:Fam^EPjAG6%l<k*5^nk&<\d*ayA#+ey*Bq!9G:+E*
BK:CR8 8N$kQHAHZ!!iL^Vht$lpWWiWqS$eLL:H5qmunQkim^nP5eWcbiAeY&^RB5/^T>4MldTbC<4\R^tIN!5y
ya85T9 ^Zja^PI:dI5N!En^HVa^nuFuuVL\ZwjayA!<%/Edw+p!<F/HM/#V#4BPm#ZK\B$^5RpbGZjEmyJ*XLIP
Z1Wh9P Gd+MRpa8B&Zk@a1mcGjK\L&up9CGnBn8Qaq%!5AiRt^T^1mWMVNqVM^#H!/e=^4=bJ#uJZPiq<^=Zk4u
=aeKTZ 8i>JKMM+#$9qQC?N<>#*KbVS5d/qMnmuqXA/M6?uwH/GPPTmyA$b4LBQ#hmul49IayQqha=u/^#QBq?+
Z6I9+G YEN=>cA8<Z$K!19I#c#I@eL!nN<Z:+PJNYN=mGjR#S9P4Vw+6^mVYlJnWw5TAllb>M5:w!&q8&p5n:bW
#$MEJC w1?$JQyKuTF&\hqt@Ymd>aP?WtiJ++??$1InQybHY!y%&qKJ9qI^nn@/T5W+@8k4LZycDPZSX?w5e@!N
t!^6#C nZ+bG@%CZ&uSbZmY%#u?S8j+<:$L>NYa%P*#+QmdB<jj#F^Zb?c/PuEtJ>baZ1XNM^9%H>+6FWPPiEX!
*kj\Ln ay*JB&J4^dDP8QYMMbtQDQ6iq/<QMI9uWe+RL!ZYYS=%Vn:\=yW#/y^%pVt!SJ&n6*AKGY!ynQedF^55
mc%bpP n*c5Rq%aZl55D:u=hQ4dYh/EdbE#eyAWZeSFiSq=$IyTj:I<!!\Qh/Ch6eV!Yth=!FeqBy5/b<SLFcXY
8F5d?6 kw!CiCqbNAj19LF#<5dPWbkS!#PP!aJ+KVGPTiaIKJp=Ay\lZ1ypP#ktDdEB#nLHyCFi18kmG56D9JRa
h6JWkp ^/RlZp1Ma>IRL%X$+R4qXeSLPW5ep:!n+/^\VFdET^XhBGJ=@G:q\N5I8p/M8c<FdyBljZMqm@Y6<Q!n
5tMu&L FJ=@KEMQ91WtQ&Sp*K$9c#KRNe4kuC/dPc$PyA#ERIy%!5A=4K=bH=SB&/Jp=DWR\##!n+S=XLRdJ+M>
<HZTki 1a+^5ppbyXKGbeyAQJj?%CkD<X^mHH<FQtT^TStI=>L6&pRbmPjThZc51/+%aE6JJWKGIb=LdFAG+4q$
#cH8*? 5#=SB8K=uCGiT&^TB5/*uCGiT&^RB8K=hKYj<>\t=*p>PM@4\Zqi1dNLye=Y?BXqFM:#T69SGih=4b#u
Cj^CRV 6ZKi%<b=Zn9uii&e=*X\uqj8ab%^u4iD<:\huPe6eb/*#HuiM8h=K=#u4ZCiN?M<d=Z#9FZP<>a+#^9!
=n!eL+ @#pduNN6\9hX?wG>t9JCwH+>5=<::tCJDbbZPeb:=Sn9niPbiTbKai=w1T9aIG+yW=iMSF*C@JQKXJha
n4b=<T u9H:?ycP=VX?T%@&<T$Hjb9P+Bewa*Ii#aQ#cPIM58khNyR*C*ZaNP1\mVNIQcuH5Va*/<je4B>#e1#y
!Vj^$X Xi4A:MAbyBnt6QFi4>L1G59DGcR#*NZZC+iX=TE*ty+LNJcH@DS4ic6p<A6awu/^SQ&m@La5D*uGqEb+
PSC%FJ 5D#pYJBH6dE<*Q6$^nNI=clFibqupM:kj:bM9=u!%4I<?5*$qAHLw>@MM9%t!njC<8k*5$K@tSZ/#c#R
IPyaXn d&cFjnM4>J5=t!!QjnQnG%XF##T\QN1&iuIT=Su>btd$t=uSd&bG9=pb@Ybt>J9y1W8YS:?bGj%tbyQ#
phc9=N \!duS#$+Q&4m@NnaQ4c^jd\buB>8=:C<^9uB6^YL*qFpiaQ#w^&eH&/4wL!YPV>c=9^wljPnGihH1=\j
C6QJ1E 4ZF?6M:=$RduS?Pb5G6m#w?iPD>/+9#\+YJkBj5Q6?=^Vth8k!T\qqqiG!^9eQ\^%=XPw\4LR?=i*\dk
9%=tMc @RA^?CkWjt>pniZbaHt%5n#phHjYC<5d@L=n<96P?5M$XRea@YHP+A?#TZ?a<8!\QQyXuDYYS*?a<8i\
HKSJ%l QQ4D/pF@tQLmNDD84T49jj1&B*p@uHE@/DMR@X!bP>Xb&@\6+lQFwN64^:5nayM!J69Lh/4FwE@4RF+e
t9&tq+ b:mnKNawk#/*!4!4#1nD/pBiHLFPGemLw<^iB&WkL++#=MWSG=VB<\Dj4pKZPIM81bNupM/kT?ypnFjq
=WqFZn uY1^RSqtqFE=hu$aWEa4qIF*e=*%TlpnWedwqDFlS#V@9=pM?:^&eJ@Z?P/e*AKXM9D8uFmuDMcCPb8W
QhmN9L WS6q6E\bdXBGN<1kd:kh>A&*k::lh6A**BJ>\$4bP5k\#^9#4n4n86WT%/&Y/B68md=l6+w4bhA*:K^V
AQ9@9D Bu*DLhF?dku98ScqwWJ=tV=jb=m@@uWu@=d?ZdhAB9?Y96!Y/e66td:eq4u9dyq?Y/ZXnZca*9ChaN^*
1VZbtP N^$IkHHj*R4!cVqD:m\^&P%8hZL<qe:^X=B@jLueWJ:l@YR^&E&?T?de><$p&t6+S<\b*lFd4n/YS^>i
uFX?4* e<PV=TFH4VJNem/+aaL!KuI4miH55%ZpXuJG9%:#Iau^X?uZc:WXq6et!?Mc+A^4RG5djh<&?4=6hH9d
%5/GC8 /Qc&$iN6w<hd=dh5iI@QYeeiS?@Nw8?>C%mZ!ducGa9wnHP%F?w\N?Xbuk&YX#qZi?Q/$V9Zn+=*t=*l
Mj:iZ? *YcqJidcQZniw&%nJS55#/l*?i/t5+$8GenD=&!nT<dkYna&8tS8hIp86wF6hMuEt+Sm%CYV=\HP1E6t
LmV?Tj Q%niSyjM\ZX%Wyhwi%:B1E9/pYHV>KNpqpi>+VYG*8l/Gb+M6w49eBL@FuiTjQW+aIN$QRWNqmd@N4Nj
uhRW*= EuKLKA5BdI8ipF9EGj$MQ1YNj$5@k?<cC@?YQwY?md6S/m#WJZN9&nQ9VjSM@&VQiG9RGh+XhIb*BSXb
<t*CH$ C%89D>1V9nYF:8#Ma!&GNcBQ=AMR\:1k=\Ilh!IjkFmuDPRDEJ8WRS>bu@TS>aq<AM/RD$AiZ<\bQZF+
8=P&q# kCEjkBnt$VmRD<Ab+<%$Sa\!pA@AGjIBmDZK+B&m5dqDNA:/:<iB><4FPtZk#d1mc&$HGid1THm#Vk#:
:?XwV@ AD%6S^pqWWdyqMF#SD%#T^t+*?mMb+9PBtX$w+^^WAdnpWcm4iIM?tDpA@yAV@M&M8kIu\uRETQn9S&^
mWN:hR Slt+i!$&KAN*4=*l4W8^Vlu$m#1dqEFj/en$qa/M@G6qdPIJ^!cieBTi#+#C<^quuPiK8AA##9NmuPiq
adhtVL ey:L\$HGid/=T?GM<:\M#9M!Pe@L=D!*k@QeiHd5nQQe8Ih%^uq8ljQecI5PJc\H\*99STa4@:b#@ly!
/DB%d6 Qc>RA=SZD@byVi#VttHZDh?K5##niK:$Ti9hPbdHPBR>te*!BuXJa^!K<6&k9Ma+FGj<9u\ncD*l\jIa
W>RYhi l/J$KC!9X=a*E58n#%J8bbVZ<jc<GQa>w&@YqL=bW#49+mtQDe64uPi>e=:*$Xki*yXbIT\wV+5wGN=&
hEjH=Z E8Q<GI^*XNwbq6e+Q@#D5d!N#lpduVN+y$6=dFAi*=awk&>LPPPhL8Y^aZt<$#Z+91SiBPH<tL#VyXAl
nHaHY9 q5h+PQ<X=wj!&HR\*8qTil?Y^#6h!tQD<yCVZM@b\Ie*D?TnFeMcQ^Q!$ayBF<@E5^Qq5YF=bdA<*w@*
@cJ8E# :Z=nidS6FbKF9p1$a&hmHI4!&ERjqF\KtR!&^e#eS!tQDe9nQt>8>uuKYeQ!itF=nEPbt^l4=c^Bid4^
9Q>i\Q DEa:b&:5uLt=H#w*>$MX?5d!<Gb^We+cq5j:Y=N9K^dq4EF=^nkW=c^Biea+FPY5aZtMR%HPGydHPBVq
M@VR:P 4GF=nENS#l1WX^tHMyuD6CluDe14JdM<u8FP9t%TqLPG=VZPD?deE?Q<cI^DWe+cqNeal/KeNT!9eH+$
nBJXdp ^1Hw/S?YS@?Re6c\9MH=$ZnGy=\%KK<u#w?iPD</>&DKYeQ!iHhhS:$54*F?>M:=$RjuS=?eH$y/C=a+
yPCcSR Q*\ahDLPn<H:Aeyb\@Jw!!6uDe8nLT<ZD<8nLc?eNTl9$ybZ#l1WN&uLK&eN!<N*5/MlH=Sit+l&nl59
Qpl@?W mMF\l9q4TwNlbHH@b4yYPeARk!HYKAM^GGKDMlCDaehADIbal+!BGA!^CSpDhwSiae8WkSkMlSIdbTAG
C6b?jD R/^SBtI\^CbqIAdDGe:j^DyqaD?nWPenp#ZItInBEB8RMZFP=\\^GGKhMuB&J#ayw*I<V<SkmA*KRA!G
$S1qW: M<SkmHZKkH+Ym@ybZw9wy#Gb6wM5:6<Wbl=%wnQEaIk%!pAMl6mpDMSkYPIdBYKhMlCDwVD+k#JkP#1D
GKeXyp :TmGib+T:8e=R/!GGPc=$8ea&cRM^G<+\*=XdFAGan1eIcbD4FEG:qiIVeyAuIeq=q8*^H#4qyl9jX%L
GtimQL KGC+m&j19kqteX>tTl61bP#unFlJ5eH!J5h+ul#nBZEi6nKakCHP\>cNTVLwq^YlDXaH?1@Ad&a/\i^p
H%>LNL nZXGZ5q%JRVq&eH9c+uj%=CQ#Bu!pVp##m&4uF6GP<LbbHtDi5$G>Xw>PQ+1<pw/+=1mJ?baH9JKPpNi
H/G^BR ThMd/!!9eb=Z=K6cX&>a*1TP4bM/6mG9yFlHiR%*85Rt^p9DuT+^4G?8enn?Y8Q+c^8h$#a/y!G&VDhM
hKt#b4 C544mj1?b?4:n6k!b+k6e+a:ZYJec#98hIq%qwe:ZYK\e*SXH?ZyRA<5e@!N\9HHh/1hXa+@9pq6mY>T
dbjHbc P$MethmE@y5H%@N=eD&jmYN6Iw:MYiFat+kH$jW!n4YJPDJu6GMVa+thVa!%4Q<Ll4NiMhkY?WCPQLHP
Aa!$w& <t!!9FybZ8554^9LG+*qVc!@PeEH:\\?iEW&a1#qBB?<M<8JDG6bV6RdPXF9=I&6pni&m1+Kw4^M9cEe
<b>EYW M@mhH6ECT^m:dpbk4el>59@G\j:#QTL1:H9ESkd:RA@BWAdmyeRGbZDP/DEN!5Bbqp+$C&W$n6QSPW+H
8/VS%X %&p>ApAbE@5QJew*M6ltTma@!LA&KyE/biAN1HYhp#IRy&XK9p$b<M&bEqSVS1PPtInu5yXMtc^VBtK<
&>MyQn ^GAZK!u9AEQeq^n&H+Z9$#qDLJlaw\#eZ^YdqIF#A%&qVbTBtDFumBq#Nk:KwE+5G=&+p6SG66GVbcMu
DNQ:1B X!JT5I^=9lJpk8F89c&pn&TDM1ySSn5wA:G/ywS>qNEuba^KGVNS^5R<X&I%!Mn\9aylum5J&CCdqFE1
lSFnS# bXmmDP8WkdeGVW@k5d\i##/hDhmali>1/Zw*?%ubK<E!dE\q:tF=^nFi<D/&&GB=iQNi4LP<MXui4CnQ
pX$Ap6 Du=#T@#t9t>EiiyXMPN<5<4=b5lQLVbbH9JVK#wH6ww8nYK<%IP/48K6RVHa^cX!uZHG<Xj^H4%8#DiY
qF!aid S^?nuq6picP^9At:YBjMWF=L%L56e*+$=C<&ZZlliVbaZn6aZ855d/PH&paQ?ThHiY:Zwd!i8Ab$?1X<
p5h\GI 6&<5n*/y$8tZ$4PYLI>?KYiD=hE9yTBlqDjwq%LRJ<wd>E5y5I@qGiiH:^6bH9iNbdN9LJ6>a>u5G%eR
@6!*@= T&RV<X^YtCjjYid+a$=<Miw@=4<Z//^L+:j$9TVYw#u+LTjib>eLM9mYh6CPhe&Pd&qHTT!Qb^nGi/VP
-Ai!d\ 000d24c5ae100110333 Page 463 of binaries1.zip
4uDCc9 eQ>IdLA<*Et!heAFlnljMhl%eyyZM8#X=Gk>!B4L\=$pp!PP=hHP5a&hI?eI!<PhJLPNn>9+y1kySZeq
y4GG>Y G!\QecBmuiZlVyJyCYX=8JNp&9!^QN^JMlu+KK@kVyLJPEN=G^?*dZ#e99lp@m%!E=mWN9?&<%68@Nt&
V&&/Wk <Yh4euW!4BZ/\JpMc<X1TGRV?i@%enD&hQXAZI5yNh<pt!#QwCj4WVG*uHZKcIW!?pEb!FX5qdtK^dA@
Ljkq*c 1w!qe<a#<MyaPteFc&NqLJ*T<S\5D:F$#9C?lnP<4?EM::k:\#98alnQNTQQp#QE%+qlnQ6MkL%Ye#pw
imH?4R \&C9PeP+h+5j+:pY9QHknPit6ZD@Y\9*9>WP>y>PK<E&dbQFAace&p1b^HF9k@%5p*%cE<hy#dC#c/X@
N!h?cQ 5qdEHnu4HL6%M%:ckj&HY?&\yY4LYB64M<:XS68^/yI5&IR6wBB/@G&u*>cd^9Hm$+P5<b9*\d:1*P6Y
J>Y18M ^uH4Nn9u>MB>ML&il@Y!Mp??5n>V:n!wa&jtN@hyn9I&b\tX5hP&!VhmnduyVVqD!JCj^lu>Pa%9BNpt
M88A#= V+i%^QGuZB5wL?Fi9nQEkb4!aQB9EaQtDQHF65qq+R^*AJ$l9=STn#Z?LYM/Y5FhQGeJ>uk4iN9JtiH:
*\l56$ 65K#wp&8CKXB\@q$M<dhNENiNYhq<:jej#VD@XB4G^>FM>#^6Fd^DwI##4jtTl6>WJH9Z?ue+Nh4qj=V
X?HJ<K *<b#ZLZEee4*Vy#lZXBVukS<6<d>Xt6+N>^cy#?^hhyeQ5Lb65/=*#4u9qR^&n9\l1yT&uGen4L=ueFZ
aQ4SJa %d!d?V9ptQHBVL>Wa=+ub+XndhKY<y$8hhPp@hjtSF@yun<b<t\:\@5ciqEi*>!Z55:!<K/ChRX=khFZ
FtPDEw ydVEpJ6+=6>=H>d$SHkCR>+**:\q@m:nZ1A#a*9=hyi#VX%!^@j6JjN9C>e*8dRk6?D?nDPP<Y/$dd5^
QWPPni 91Rd*uhYTpZ+BL9S*>/b5$cyF:HZhXMFi&huYJN:^S$Jb+!9/\&=V9W!d>&\?C%4G>nDP88N9^9ZNiD4
m*Y8&Y D^<@j@9yl=@>:h@?:G>?@ju@<?t6?ldnb*@#<?>?>?ZNt@H&4&<@?=6@@jLq1*l>@9jQ@@F@@>6D:\Z>
MBjDL6 :ujya@*hd%4??Pq*8bV/MZ%Vj=5@q9Ed?:8@Vd/wK?jB5GZn#PMd!:@=#Vjj@C=@c5j9!t@?:9@+&h@>
lT<>^& *e>?@Q4^l/>@@8HV:*/t1p&dQ@8j@1h@?yj@@LQ@L%BLA\RWAAIACADpXY$qc5YWT>DwARD1=RIAKkAA
4HjYd$ AGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^qem>pd&N#L%BHWDa\LplMWP#>iX^V^^5HnM+=!eupJDuJ
Q^6N5? PeBll^\YAWEkCC1KT>kWBBEF$dwTIEA$JDEJI6b1SN^\Z$9X61=%1db&5X1%Fq9dYliKX1&%%4yX8%mL
BBEKmV 8>Y1:<\l<Yj9=:**99ji9?:u<+LBJDQ##M\#M<><u&Zt>B5uAYRkAM@S#+bjTZAuAIDj$R8ALktG>IwK
CyVuNc p^Pa4BcD&XBSAi^Gl<NkNl8A&YE%YCwMN5FtNNkhMtA&1ewNpaLC=nDaneDkMDke%uIVMDmNFRcu$\DK
XRS&Gi 1&8MF1jDWFn46Napk9KBwB+aJlqMbpPbGSnLnGZY!YY%\Pt$Y541!\$8T:uS:nSXntBh^9J1a@tE<kwk
q&G>A! ubAybe86Ndbcq>NwL:hcuINb>NqYQ\+aKw^C8d*i=yVynSXKnj+A!KJLK+!XBqB4hqcaDGa41Mw!XXcc
J4<Eji nQFCn6F549pPtB^HJll4FkKnSc?V/eM4NH1Vyaw86F1mK1PAlHXW?4J&G:CdLM=K1:$T&K$%%abJ^6\A
D<qBl< Z&C!5PAGc:YakMQpuGC5##N&4/hALKmmkSuWP@Stp<Ny69bP1wp$%IeT6VZqZJX^1W#95BmTCc9VD+A!
mqiXw= w>%ccdXa$$<KX49XYX$HDHKV9dCC5FZdDZMhSl6hYnmkpARTA$5Dy>X1h6nY&a&XS96=aFTALNPpbaT6
RAB?L6 6t\QaT<%qy65yqZeMcIeXD8M=dX&NFV%D1QbYP+5pqCCWti5eBn6p\Tn*YF$KnlH>iXLSLZXZMEBle6Z
c\H<yb EB\PW=XF\l1e$&1:p9JTZ:a@CAb/%114MXw6C+ELXNaDy*G!$%q6eDaZX^6@APiB!j+L$F8e%TbH5RR+
/tXQu+ kdZa/4VZPy!@%V1MJKmRARa5JhwtGe!thYS>M<kG/?wMFthhh#C<F\B%%cd!/n1VGbn4VJaKc>%\klIe
&&/#4a hTbuhd&X4Z*FYp5Bi%k+mI4y*LqL=+S+jZ^<R8iEBAIpkHYJTWt/JF%ZpJKEjyJ:JIGp45pJKTpJ*WC*
!hh+$l lP+>EyJT8+K8*bPVhetyQWFKm1=u>&:h8+MEZa<i8l:hW$F1#%=y@jTn^yTtG<yM=uVmi!>Dcbt%%yp8
kdu1LZ SR!i%GI$qJeddVIJ^a:nJA\wRJ^nBJPJhK:*nmmjYG91K!u9K1q\tu1\#64yKNHe6*/yyEt!WFI5YT8^
u:ltm> XQ&#\h6TyYT*S8\1*!jb=h*ypMRSJJqaP%8Tu5ZtGTy1%yAPy>%qeF46lwyJJt>b8p\*HE\!Pc#&JjYG
V+bqKH !51uSHyqlTVDIBY1DCcLXHCR#nYpyd#iaK=cbw$t1&9pya=$j^?=&Xn%y<S566d>w\dYPqyk>S6bj#bh
n%6LQY &6?1aLZTm94$kV=t#ZFJN@b:TT64hqbdRY%X6eFeb/n*Hkaw%qDVqc&^%kwYb:4FRACD?XK>\?SId=RG
H8eHDw T?TT&clN#\uVJJQ>Cdlp1Vha$IR8I?ZkPeZ8nQ#IS!4h:@P^#$d8wHN<>LHI?l?p%qdJScp>%HyP<yu$
de/%\F tM>*Ww9BdykBKk^&?+>A!nyA8mP>KDM*%=Dl&E?pP!aa$1WXDmqa^DptQQYSin@MTNe1l@H<hY?b<Hcp
\CFLu# \bp?!Tq$m<tiRPttEa#kiN1HM5aCtj+8^?4<C\Z&y6*Wl^wNcqMnWn5yZe?n9SlZG<Y$hNN@/yWPLuDV
wH=Q5L /uY5ZQnAtAHp6m>4/%wNEdIGpmiMbb?lbS^y4KDbYl8qe=RyDD\\u?ZLDQc!8B*TWPAk8&e<wewNtl<q
a?LtKc M8An^XtM^l^LtdGIMtbR?m1bmRXTpJE>ILhAYtc5wp^Yi=q^^86WthF5Mp:KpQX:^a9T<dy1Mke5JM8M
Fa++$\ NCTh%VK&$8VMwFbIK<yal:QM/D^Xb&JNXX>VbRd\G!ua/<6MVlI+MwDbMMFw4w<9$qedcp#&5t*WBFpG
nAc^lY tw!Cw<^cWe?YYc61=eBephF6MXWtETd9B\i<1<9$h85Ew!Wn&59aYFa:XGI91#X%B1yc=*Zb:>$hGjYb
QT^GaK C?>#=a@DYFlic+:*i#*RL>TQ%nuWMN4yDj@5R%G5XRq5!Z+!aPCQ!ZS9!<1h5LJ&GJTDpL%pXRuSSkZI
6Lecwh HJuy>+1K!<M!1:qCRPuQ??$^?hZ+ZbXpP8hM4*QM4@5?Rh<MnSXhhQXdi<kK>*TCj94FdQW*jwl*K9be
#WP/V< qVEVm^!HTwnY>dZ@JV$F=aZ^+APJ$V+6<*H$e:<RPa\ybcG?jG/%!XaC4Kd!EuCZak8B%j1FDJjW5nJ4
qb=J8\ b>>w+DBcMp&*dN*lHXq9/JDyy9n//m+*?ycd:PYQbSTaF>bDZlnFidM%kDw8tA%byywaaLBpZ1j5^?PL
luQl4& #pi^4D*?iue@AWcD*jI*PLQJXta>d4D:A4t?*L!SqdJ?6QCX@HP=XW<b1t49M8^A1l^6HIGpSuiXc:Gc
Gnuh<T c&551CM$9XlF:!bVI:yHbFy4KkKi!@SB6B4<DX+l/hJRMlLeiImpF/P46j\<SLYpL*9SNwCTCZ9<^\Dd
4JBS!/ :@RW4!VcXYM#9!@jL:QZ@!P\b8PHNC#X/F1A9?:lXCGeucC#9ejJhPHC>1Ruq?ke&4RVphWLC9$5>kuw
lqHcRb Ji<XVT1Y$q5D$1Y$:6%i^Cc/c4w<e&iAQab+LlMa@b>/=dy5wl54a<9b=*K>9#=Bh+P9C+SCpJADu>X&
$^Vi5R F>:%G\>plb@/:iBP\titcucMh:=R/j$?8!@\WGC1!XK:kaZC!WC:>jJ&\nLJcFqB6\wK*jNS4A>wTlN$
LPVMJF 1>L<lJZ$Gi/AbhIE$MZ4JE&V66?IDda=EXc::Tb$Dmai!9Xe+i$\8%R^uyRJ\X:@cIDDF1ipdbp/Z:%N
w/p4nb cdQdc&%Jkk\5=ty9thiVW9b4!aRm^ZmY$9?6bQ&AVQDYPRRl^keKN%#Tma4QcWQt\cCjll?L8@FdhGjX
Nb=ykK 8Vl4%WF+lw+Th16$>j/8?p<Xq^SwmGbK1WRFGk^DVaH!REYYwJKA8eELXQX^15<6hHk\G\pLW*49XSt:
9naKB/ =u?cPhyTqVtcbnP:bIW4@\+Jy9VZ9L^$Dt?hVNhV/Ah%G6*M+Ju?4KAkVGZQ6\ZL&i*=m6L%5qq^ZtBP
YhNk5I &9MQbeX^!%V!Rm<h%GZTjaB6k6N1?$u&utybjMX%a$p1BEd:Q*R4!uEpK!hLFq>l851<=j91YpdPtlyq
RyKe!p ae^WFeYctGYKLJtP$b94K$#QK/V?/l=IaHm#&X/>FRPat8>C5tTFnFCl%qGe1din?tHRVCce:kS5=q<Y
1jcR8I EVkqZ9BqHZ=/!N:+Jae8QS6m4TDACtw9i^91HSXYF!EBIiA+5@m^p6J%RjLhYGF>wMw*^k>K<FXb5m+w
>X>Z\: K4bJBENXmu>FMGPWCw&Pmth$XqFS^enwThq4A!TCjaL<y%BKd:dZ*%DZb*jT4AET\j1luYEh^1\+CqnL
jkyDGa bL>MW4*GDPk#Mn=GdYAaTmMa#R=nhq%w6tW/%BwXqQ+y>NLNWIhyHR<F*Xi!*KV5LZ%qi6c&W@QL%tq*
4%CaJ% bZ#mE>pShWWtYB=>>dT/QMlwec^uKF$IjK%ap+%F*cQRyYpjc?!H/+*LyYc4dTXh16!#W^*Q91P!!aZZ
pXK@!V Rw&?!1q&qQG!>\Qq?jm4&8#q*XRV%I:1AX^6^TVXSiMib4F1G@8:NF8m@/Z*$!P$ZaJ&ke?DXAK6u1/=
Iqu%5P MupPdVFt!\TN@qZbA&PAjJS@N6S4>L5=84R&AymV%JN/k?h?:+HJm%@XTIWS\q!N\#n=yt^5BRZ8JenA
awKGS5 ajWp6I/jDFGb?Y!/%F5I$K$mbLySjWCP!ySPSRM#ShmjJ+IuHPY!BjP/Q<K$8wu5?^Hpi+J<*T85hX*a
\u:#y$ =Hlb1KNP&MNIYT5$%%h8DqNZyyJGSN/8aie/uQ$qcAbX*qSIytkRM1\$G5*>yea/Q&A!tm9/P=JEAB1m
#8P6mL TRNcVj>jj?Z5N%WYy\K5q!VBWwi#$nS=JLlH&KdYX@/iTIEjEXjnJJZ$X:L?Xl:a1+#PqS8XNRnX$aKy
&AIN9@ aqVI!M1EpM1?/nemKp%p@$MT9eNtKDi!4L\\iGJ6TcleZ!C64LZ+PcNl+R&N$/jWWXud=\h&\Guqu<\T
eMd1kN 6e^q49>Lw*QPW$NhBc9@YbKpi#*X#:8Rby$HkcP1YnNe\9bTQbEMiJN&!FXXWt8XWq%XbdXY>Kw/yLE@
m<nnpa DJ<np!I<Hn4ApSAG%uSZc?!G?u%XSLShJm\GB8?1Z8w86kHm41eRHFWQcyiyFZInDdcnEZpj!G4jXMXS
chdX+l Spi%wYJil4LCnFlRWhjEQP<tD%j/kEB\E^/TSC9jIBbX@+CY\kYF&iaaL&X1jHIp:A%X6ct18qiPBJkl
w=4!c9 /C?Sk@41!ccc/nq<D:qWYEdX*4G@V6ZqpEKD6\4M<\a=^eYF%dXX^8Be$$h!ma=tHdqb:dqb&itt#1yk
Jc$8*d wKZbluyac1uK#ZLp1j/654BTuY!AdJh@#/km:X=#9cuH!FA&4TnZT>F9ywy!jc@%$b%lRkSH:kyL:mKq
$pT%pC =cTpAuZy8a^q>N9p9BAPR6lbdKik=:*a*$a5wm<n6uhq:$SQWj^=J@I9iRWbu\9%@1^<*iICIWII%S!F
-A9em: 00099c6a7d700110333 Page 464 of binaries1.zip
%@uEAc p$\X?/Tj$:cjAF@cywC?n%qLJ<&iKCV=9YTY\\1q\4lH@9T\&nEqyEB^Q%+8NDM5?@\Z\w?6DQVZ&RLZ
JPZ!cb B8&RuPb@YW6@!H@n+/*pFLqRtPLj/ESa\G/61L*C@H%iRq@KIibTyw8$4DA*pGcA%j^eqq6wekBH4VHZ
MSqZKy cZJGS#uY$%<R^lw=eI\uS6AVnEadWu58SV9!nQWS9pwR/#6GZikIAwFKwHF<\FVwJqm5hSK&Va*$HlX4
8u:J#W MS5?%ykNQcWBW5F8*m>>HG4QN>DZJNZ=qN!iu=Y?8qDCFk%pRwDSMEMYcc!Wk$4ujG?#<ZFX8Lb1WdCM
:KuNY4 :WaP>^wk!b8l!k\%n=cb</Y5?SQVN^wJY%@mQVIm@^@1H\tTjt@I1MJmZ^>BZunL<d9tC=qW1Ji^i$qK
iIHGq6 iK>CJe#tiDAlt#duTl$T>mkCHC#aV&hIc%/hTn9ytw&TK*:#@c8$Nd5RKl5pAbB%!EHhbLpZwAVLVmVy
ZEGZ$# /8Ak1+d%$@$ybWB>GJAA?<tjbRd#INlmDmmqlZ<u%KmmqqHytmakA>WCm!bddTi%\iIk=pjWGI*PGtQN
y%uy\/ 4dJ5qR\ewkhqEMqKtj/$a%CGIn:HZ1NtB>p%IaK/yhb8AAm#X$kHtVm=\%4y4Ata/XNnPp=%WR@KHVRq
<WJXdK ?\m5PP/*qCYbEFXN9X^n4nttjk4!=E8AWSlphVl4JEK6bb5W/Z6K+QAHp#+AaSJRm*V8=WyVjIkQ5NQC
=!?XGS <qCAmq1&F%\Gqq>Blb^%$P\:nyQMXhbiQ$biIYHSS8IH1mJWBWbu*Vt4jeKd6I\6YPK@^d@WZtC55=DC
wZbmiX YP@Jne/CXhBmLdBip9=/XX4#8*?BqRNR\%JQwY:KYMC!Ac!hqkW4JD+F6VYeBcq*%4JAB?FnnXG<GtT$
IC6&b9 D=dqtcEX^n8e>ibq^5uSk!*9ca!DPYuuu?nBFk1aA&muhhLknjLq6AY!B^RK%tHhTN@5L6i@DY\utMP$
@C6ByY qiF/YY?yN6NXBw6y&lT6V8pKAd<1Q$Lw%nDXQBmJ?MJJIECZ!\^8LLKiCZRkHa<EV/PnB$Md=c$GY#Xc
MR@ItF 6FQ?5Fth:9iX4^HyXX/FIh^dhj+?1=HY$pXl5:*tFXl+Zt/:KE?TY+!&L\\ZkM%kh$4aLeEdDI^Rd#Q$
:D4#Gm <C8p&B89!CqY!h11Z\>EAMKXhy:w#D4#kXV@RGp#LHBYT$A1:!nMjH9RCJ9Stp$YEPYE59CNb@:&t6GE
qVKn@6 #GY5$PnLi/wEWG&\*XQICp&l%lD&yGSl\p4CadWkaS:hmYYRjtc456pKB^R1RtVkJ:4?mm$+yLDc?lWn
*X$p:M LZ&aWE@dVPXc+TKI%4\yLi!H8#$BZEBw/EtA#dV$D!@dBH5qW+/&@jKJIYt?p=&F<5KbnKY>$F^d>aNp
yKy=^8 MRN6cudGe:uVb4ZF%&cV@TaV&\K@AcF$NTXnVYX>Y4*4FdwEAtEp%tq:bq?9&CDMD%!4cYJN9Vp\jS$l
LYGAB% %V<Jp8qH5Wk:E$^%9$ykaSG\Z/H8wkq8yHaw4B<EVnKW%^hiqdF6lN%cbqC1AhV>4YENeyt?Hqn9i<9$
A#kN=+ 9huuXLSM>!/w+4wkWhcF@a4?J%/w5h$pEh=m^$yGCy>XTy!Q=GbA//eBb$?X=nWka+8>YGA66=1u\<Ib
wHFBM% dK^<C!yb^Kyb^+dCbYyV8a$T+w8lXaME8Dh\lhkiBmd&5c&w6cj$unnS*%ujR>u=pMy1/ci5ZS^TQ8Gy
Jk&wWd XDD:k=?X/=m%IdcA#%Zye6a/NH*R$H!FhX4NZkYq?$j=qD#I4FjH@^\hPuTway>CI5TQ>%G^9?\L>tEn
Y*BIhI NEG5N&8Y5CH5=%9qH+jIlJ=A#R:WDH*GtKcSFmicYhNy&tb>WPYThti6*wwn@w4TEPGj^*KV<:ctM@5/
cAJj6Y +pRuZXXw/D4%D@=I6jVb!I=@QmaSkk@RGu^ZPMnYIbZ1t\d\b@hZjJ*GwXk*tl+nZFN/5#NDS@kYkHG?
j!MEa1 n8ea!SJl5LApwqLT4=?<>Lp%!dh\Jj5\I$XZ$$>NHE^/QyVL$:k+tZAa1IXEameX<ljn?Ep&E+F98>H=
TT&MAt jJ\5Wk6%:^G5$B^&m*pC*k&ApJm$Qtew9Y:CGP%#19SQNFi%TpGI%6<Hmc^&N>Eh6IXBZbm5&nu$>$HB
uD:R9W <iYjKChwBEZlR+J+\qt6#1FF/jdkYk5J6t5HMbXG^:AJ<1K9cIhEn?T9+&L=QLpWjBR\E=dQppSyJHK&
:dW<NW B%NpNNnL1&<=KCE+=FXXBcZ91XRTcSS4Jw9/^?YuDW$#%^@#F414m/^1w=ECQeHVR+1mCEXu4@Z$qtSY
jCYXyc >%qkCKi#%kL=8lYMycLwidQZF1>\bYlW4HeA//Z5G9yhG%ek1\?Flid/M<wA/hPjqJPtI+X?4JITi9NX
iLiAbJ R6*ukGSjE^^u8CVXbea+5plcYn$qWiF!BAtP:<LkQeaShIA^X*\Yemlpl/XI#m+PKZ1XeW^uZy&yW4AG
&\E^X\ 6c<*i\NJAj5iLj6lWBV4YBBQ/b&MeKNa>n=@SGI&quS?4J!b5q68e%!TF%&Vw!*qh?Wnt&QCJKXEVRtc
BeeqYZ aN?A@hj<@\&w?+Rh&iXu88k!@RT!d<mnF%LSkj&RN9I#biCE8t1DE?y?CdbPZ?6j49qN=a14p#jDW:D<
cce*L5 Z&MSlp**aK&$qyHyu45IDX6C\<I>iq=*t=d4L#mK=L6/kI$K%KtR<QZ!W1il5uJhTEYVb8JY^8=E*^b+
qXYb>* ec#n@Sdtw9^i1E=\:6GbP+Qn#6ykATpT6tm\lj1ncA$cP=*>u9>\6XV*>%mkaQ*a!aL>5KnbPG9LynNF
qbC&yd iF:8aM4CCnT%n64!u\M4c>>@^my%CcHlT5iZ$H!juR:bNHA!&wiX&aJ%FX1HadB*ueFYlHha&@**JQY4
:ItR#P Gj8*/68E\5a9cT&/#$T1KXh<*SYp:d8eVpNb5cGMaG+ZKw\XVw1S5H?1mbBR=&9\Ek>%4PCaWN^8LK?&
8nuCqV bQmQlHJ\T@cD9QRuXSC\954W4&REpHTh5XRX6$PXynn:$1DC:KLm*i4h<mZKKHMEWPn1m@?SP/9>Dbdm
nVAFQk 5YTLw1c+i91uXJtZHI!tK1W$?:1pP5XaH\V1t:8?Shw4*yRK<jda5/y\%q14yQ/lhM:1ZXIy<NK>191G
?=q%kT 9H@MK@/ad&%++I@lWy%JdpA49>lpI<Hj98aea*G?m4RmKXGY>y9mI/Z%cICWDTPhcKM1q4K^mpM1ucJ4
iHPIQ* eQFhtc/9\8K\BRTkiVYSj5XLMDpFeCVALtj4u^kD6<wMQJ1%6DAlyFmYy=BQB@biIjFb9Ru:XP9+V5S*
Q6E/h9 +DG5pH:Yyjmw9bl^TlEPWkyjE>=i4I=^Xw<C>eZ&SjYN9uN>L^N%%8J@FNQZKTXCt&1%au$kD<Lp6bM5
?!IV=K \@\yMCqIw>D>Ic&>MXYnXp*nDYaXPP@@V>k/e*&6bWJE<DCb#qq48cphSkuX5p$=6X>dMp1/1E*tajQX
K??%j> P+ZTYq864YKQm6JX#B/tati!N4QX\IAnXp66J&caw:hjL<uje9A:cFEn\DEM@XGBy:6b^^S/Q6k4?ahc
RnmeSb A?ZC6jyJm?tKEn!n\=nQaTG9Y^+j1H>M$VbHmuAmZXid\y/mJ^pE$F@hw\RwJH8KT=R8Q\S%@pKceJAR
XSl:Zm 4/8jT16%ey&j!ZiK4<#t$AhMMlp?tlb+SG=EKQS!RIpTQN\l+<AP%4SRJkX@wX*P9>cB/l8QwG:6wl1q
h?<c$= uNJN$bVWtn>pjA*!LuLqJLY495=\?Vj=eIQh<yTT?!9a^VL>GGtyNA#WP?1KNVLDSE%L!HBn&ZBnqJqZ
lA4edS XG9Mb4QGPQ!8ZCblw^$KYXPmX=Tj#PAK4c5&teQS<NWNpeB1c+$MPJJB@cB/H#MF@CKHt&+y/6dXtY#G
<+4&BS +SK>ZeZ&emD6&^iEC!8</p\8S@X\p:P/VkIPtC\Wi$t6At9b+WtcWu6FuhYTFbwVG9>H*Syt8J\h9wpb
:kMYll GVw8hP\ECV8RXRB41DtP4ZpcHqH*4q<Kt<ycBJqY&e?Q$*J/6cc8t1y/^Rke4%l4:jXIh6whSuQqq1&Z
8qRkW5 E1WASKGZNK$#KRZTKTuk@?Vu?ZMCEIBD:*RTVuRYVW$juqE<ND5dhJqAA9RlK:$+Hd\@H4*QHF^RuD&m
XK@GhI GH#/N9=RQGL\wQSCpBiMQ9SHKiBYAH1Z=!:5mlW@mIW6+iJ:MVj?84Dcuq6n1DICFqW4j4JWGCiDyFD$
L%dHDY 1imXw8L5RcAlHL$9Hq!at\tYS?K*^jphhEe=EIGT*MH=/cByDZydX1MD9?$S*!TBSZ9FN%%B4$>J<H@@
li>h!K @N<@@@jQ@@YjIWlW=KAZEkeAqM1RREAjXuV&iI$BpB\HA$Fl<+LWd58YqdFD%#jP9XWbQNC\e*d\\KV<
ttG1CA m1lqYZQQHX?:+Pie:PK&kYEQDkiiHnctb:jhlT9iPDG*:ZnYp8N6b+/*4Xl+BAC>NK6S15@ZKiV!GRR4
%yWN/@ ^@YBwQD6:@cIGlchMT#SZLD$b==:JVP5j<Z\m9K/aeXe>HZ>y8%n\?%hm+4VI+8LEphunZ:#$:&9q$!w
hCdwh< CY6pR\c6uEjQ*QZl69ANESNKK!4LP*X/h?:+/516&=8!8t#>!tjI!y:THmuF^18u!$wV5q>b&eiuj>$A
SYqpT6 +:BJ\^K!M=9t:6\&^:Y%JNXuYFutk%Pu!*<6HPnWdN+%b>t!%:%I^+VknN6i#WyaXXi\idjZ/hVG\?5Q
Qu%6?+ H!c+aY@<?HQ=ky$VC:5uq!Y&d6+Xt:#@XZuui9qZd!!jE#+\LMbSiL@qbynk5CWPPn^#ji#Td5tP+wl8
#+ZV>A =ePTm+1H6e:ij9^+/?dIcMi\@lWDBlQe:yV+!1@cqHBTa1jWjdF#l1:+hP@+#1Hp1!&q&>?=Pd6//!1j
&PN&%\ IeNtLq*61/wMc:!TFPNwL^\aqy#q>*HD#WQN*JDhk6?ymp$dKuM1K>QuFT/h?/M1j<mP!iGZq\\h\5!a
kWR:He %j##VKk=%KjSc&DinJA^M^&tY:hKBybX?9ppS!bZQC##bae\QMPhYDw@ceP&>h6t8++eQZVp>QF#^$<W
SM:D*t Dy9@:l89hu:u=wL1HVh:*umQ?HqB\Jun1wAVP@dT@8G!w8LK4QAW::Bw#jmBS@P:?BRiu*9<8H?t:Y9j
*E\hJI M=@=DLFZDXN&+tRyKS<*dF?>LPLDV*h%heReZ**/#Yd8k=Vc^K<Hdk%4V65a/LD9YiK@hQ/4l1#K8pu1
q5wuy= +#h9*h^58>%!c/SmT<8mI*PJZH:a8T/yG#8@K6@eYB\Ij:kWtQ@n5DE4*@m==?uVA\%%^kiF^ZqDnJYV
T8Myun Ju&#+9mC8aiP1:nM\q1neXlhiKatVN1>/P9T5V+4*#kTpNTNGV?*M4k++A^jFFNb9iu+qY4jnQdTIh#K
LQblQR tV?\bMS5%/Ljt6aYe!j<l:$!dPYu9MPw6qT8HXw$TJXq&S4cyZHwkniKhMuJYXuJZ#WiQXLJb+bqhw$1
\V4>k< #nIY6B=TJW$?8iD+9CM4n88&Sm*++@n&#cY5eZn!$M!WVQYC*>c98Ld%<M=QJ<mQY^19H#%!bH6#SGC!
6=TiwP %^5?beqFA@yHbk+6Te+1:qbW&WqJLPTap<E4A:+NS59k*?j@@RE6#=>4@l?@@Q?Qu:e=6AjL<V=5qwRl
I1K\>J wbL\4//:FQ*Qk<IBlWKY$aHhL$JSS+BDQbAA1TlqTBAG6kqJQZ8tCkI&Yqu6E+S$Mi#E+DR/8km=q9IE
?P69ka IQ?@pppGSwLy<H<C45bk59^@K^^HITEXR?+pyjdu#!<B@MLWJe4@=amy/>uNaT#9@Q?LCJaPibu/hM*@
8KJJF! W14MXweD9^tA*^n5>j<jWB%AXwI*CKQp@#u%PqPFWZ##j#w!@?<+W\pc!THE@/nVRQEmqba1ASSHFj$d
teCD8w hb<AR>FLlJp1V=b8PF5HFH*?QB&@TeIFBM4>FX+F#>*yRM#RBTeSCdA=Hu?6e4<AH6^w@EaIhjpDF@46
-A8F<= 0008535fe7f00110333 Page 465 of binaries1.zip
+*<JuZ Dya$N/?YA*uDe$$e1@$M:#SXEkDEY8JRt@1n#RkII%*j!iLbFCqw/wLtb<PXCc/9j*4ZSaJ=KyD1pkBK
ubYL*J 4!#MA@\ZADbL*wD<jAmIWAAj\%kItMi\FVK@RVAZQwQ=$AYBGw/AMZAwBH\A=QdCw%DK%GpBjRS!pjP/
mu>bu1 AM:jD=D\*^=A4+LWN4lQy\MA6pQ1Dt^DXFiRpImFLRKeB9p=9WE4BJYR@^KPl#TaAl5l5R*!kIcQaAWp
ulChSp ^kQId!KlyltCcpl5lE%Rm4:bA+ppYI#icCD>K@RHWL5BtmFXV&4nRV9pl$IKJEGuN*khTCqj5E#P?5JL
eiB=GT <B!AnDjpJ1QELmR<D:qbeQ9lZLD8G#D6Au8^BMlT#+HDaI<*YAdteyY\tD$HC=4b=S?#F\C9qSLW#L8A
YcVK:b 9NaC%pE#Ccpqw\C<PSD\d=WCwlmy5aYR<RJ@^4JDC=@q8u4q/kh^PZyJbGEB<E+A+AIilqXE^<kBKMHD
^wnMyZ %+KGL>kX9=++MKMcTd=l^MZ889NkZ$k#pd?SPA68kCaT^l=9VDy%D4VNYpi>Laj$t=*bWMnNN*RV%JDj
T?$KbZ NTuJTSD5KMl@WE9\@elN<Fa+\e*:l<mjT?ndILWFHwlh&6auLD*Bl\^m%YR=+RMd8aeK4:GR1V*KeX?F
DkRjTC 6eL8Q:G>eI5C*dMEyI6NR>Q/K#Lq1%Q<DpkyDp\p@*mjQiDhD!Y9SX*wT4m:<DMYa#:wp@Bkl4TYQJY^
&cSbJF dQZjCE\S>>/<5$ump4Jkh4n<HCbc:KJ?<JwuA\%cX6c!j+1@^CZV8wJhlibQ\l:&dy9ZZbn8@<w*M\Lc
I!ZB<Y dY#DqF/#h>ucdVbu4?R*q4RbmuVL##!>8L%>kWV/=ej5V1F=<Mh#V:THq+Lu@j\$uB>p&L/RmF>MNt5l
ZylPP8 GP#H9R1D/11B\RtbpbD8Ykl>wcCZNH?SdNZ:eV@Abp$uRCp5tbLtIP>^jlw/S\&hXSKt1S?dBpwMbqMF
pFP/Yk p1nbq!VPYFdD%@RDw&j$<C/B*FW6VAJlZ5In!N&ZTH&$ACaPSu&KAG=8mW8$N%/LPXJZ#84%q8dnnER!
M%Y+KA =iTZdET?ETuk^Ji5GZLjc/AYLWAARuA=#Dp#=Xu@I=mZ%#@lYj<+R/MZ<Aj<#q95nhJWed%:bMItTl!u
JhhCa< RBBL/T88hN?q:a8VE+Gd:lZ$J\wkNZm!bG#hq+QTIe*8lH^IXbI*Ht+#1tM!/cbTkIXYJ1bh:CJ96/Ip
QLwb<j J>q$AK\i*hAdLjKbeBhqP#Mu9PF=ENkmB+A#Tye4E+A9qA6*yM$L5:lQIWl#YM&%VyP%^HLMy+qj%=X1
MNF*qc tp?qAMnb+Fk+!8T!+GlHw!%CAH\MyC=CVp*JiXX$N>+dEp$VS:Mc?8\k1n@Xq#wKaLuSMMuw1AB&1<%t
A:?Pih 6D6A?p@eEWk>B4eyk9#=GqXpN=bdLeDl6NiYP>E1Z&Jt1TI4+KbSBSMMwLQQpViy\6<n>8wYFEL1KwmZ
wuh8tG >R$R1MBQnqDTE4cBuR8b\58R#8k48=em<=XD9m!NX$QmI1\F?!KjCHRTJIb@YTedV6XDj1qDqk?IeH+/
=h#?aK +p56eDQ$BPcWDuNK==L>Mj:&mBpS/SWXS4aCM6<NqFGZpAB5P$M!m&B!h8qpt>*w8I?p6XLiM^YeqtWP
HiuZ9M 5F6B4c*P=DBCRmwJelIXpF6IpNICCd&DlNyh8JI@$c5Ad!K9IW+u@aa?VRM@jB5&9j%ePtD&\@L?6bd!
@HLDuS =M?=Cwt#@l4uA?klM*/RSbVXt5#Pt:KMe#5q%F4I>cAYMJMkGea?pJZDIl#JYl@96MdZLq$Jm1FZDcS?
&BRT5/ DW=c5kIT4+c#lLMbFk/E*Fj9i>@aADq=E?#%QukVN?RD+P=6IN18i1D@dWJ9X@u::c5dFtYMAwZXX1i%
CnaGIL !t+A6tyVPiT6MJ>?jc*ZcV<mnbI#qydl<FLWhuA\BKRNmJZC<B<l@SPpH<>=*/<H/@J:B8ua/%B*E@L#
5q*u>& e8X>wdaFX/hBp?+%lHVAih4h:&PE>q!uHue:PeCEVG6NVc*F=FN8+L\hFXHNpAB@RG+J>P/c<KE8KaaD
DI8+Ft 6X=*ai+tPCNHHnG^%tm9#=HQim\:h$!?m+Su6jw5=wwyJk$TYj=MdLea9>bA/uE&qYeHS1jhbJ^p5tSW
5\4AKw XWwYRY=8u$I6tPj886n6e4T%6&BDp6B>>P&HSVM*B@^YqJbqNB8@m!kai<D&8:^4ADY@CqDn*!9nXq/R
d9k+&i N?%kJ>AE8^V!F<=:<*wwyY>Gi^ETHpqLGW^<FhGbn!unHq=$IhKa<q\k<%6=b&:LcyledBY5=nKDjbIQ
qy+G6+ WccH>E4Iy/lH>Kb/$K8BnDwDmc=<ellVD\aQy5&RAaGRHp4C^M&a+nZ$K5e+bCcCcEuX/NNm!dj5*h>Z
m*<KV@ <P\+!IZuE*FFJ4dKa4V9+iL!4c^%R1*6te<6TQuPMSHSyHSh#%kaKwjM4u@yZVDP@G/WwFAwNwT%4%SM
^YyJ&I t^+biG+6$dJMeV&tDccXI8SpeW/R:JbkNwHq/HWSX/6T8c6NpWd9946w<=<A=k$!YA^XSqqNLlDCJNS/
@FI=MD k6qHRYYhq#SCiX9/l!J5i%JpZpCI5nlcJ\%Zn9?mK>9cX?4Mq9cXm66pZ#RdbkLWth<R=SSMPaq<:jch
<VEYGH yFPdAJ\\%DnJcDjJK8>u<M4n<CDcupJ+yjM9GA4=&RN?<@1ai!ayJiGNV5\/6NuVT=a4h9u+kq+\4>^1
Ty*^Tl 6>iGhi1?CGdY*IZqJyi%%kF=BjkVN6Ium<A=TH5Hi*?j+#@HtGcjy18Z1eLb6hV6i$wj=SjW=KD>1J<G
!N@duc %JD^IkyD#eyq\DySFL^Buba?DL8#clPpA+eXW#XeG&mCT%dIn<I:cBmDIJF*Y$tnkcBe4%I#eipqwKNn
66NPRc +Dknm9>A<JkKi@X?<i9W*%CctS9pX&pwN!y>RMK9ZyqhaK*JtY1cbQ#4D91%c:hkA49SK^ik\k/%t@G9
%HNhND !Ta<8@@D/&u/*B1d*Vyyl1!wPh%t5^GjSMKmXi!e5hRb9@6?^!F#+L/9Q5%pmdibh!IlW$A\9hHAEJJJ
tC>Iyk #GbcD*$kj*nl4JAlK&p@Yby^<mC&$iV<VKYG#JdFnL\XZ6p5G+64j<ZheuBT*TELtWn++iJH4<&q<!Gj
kT^V5Z 5j<%@:YR1b+d$ywDmdmiDL>99IV&GtTPwV/T\J&+@D:R$ZA\VTN&j#XwkLYTl*MP<T*G!NujFCn1XK5l
4cYZ5@ @:tJDZk6yN\ByijDLW=#R@$=aKp&YMw@lJJL5mV=h5k5Sc5kB@KjRi=dYBnl4LYekKMZl*cPkj!\cQZF
T+m&XA JuY!E%k4DQZSDym=Vw!=b&nHLmm8eFHW+8bDFwC&Q8nDPwXl%<M%9+i6#LXA:qSIJ^QW$dQkXtj<FX<$
CRk:%A uyA?D9hCwySa#Z1ncj?JN=C8AGjm1V4I*Ay+8!@Seq:SW!+8^S@e@RI:YQja:yY@*@PS%?1<LPQ4kh^K
Q$&9AE =S#=K=8!mi\=56qZFwZip%XCiy>M\=jTI>bwuA<pY!E^8>@q1DP!ZbDw5nb$TVGp=^&R$VPGS9&+NwB/
<VBKw/ I+p>yV:\8jb>Ddu>wu\y18X:EW8m19y\?k+wMadiw4#+cM>1\1kcCDN#ZCcnHj5wh>H9tV:TdNYhpcVQ
\#V?Bd Wy%:&&hw%WeW$@Y:KF6>cFZ8PAYZ@*+\u<>E&G*Ym64!&ayW#RSbX<JK#$aWN\J*h::p$I#Hhh!mB%n@
:M<W<A +bc$^A&#Hi5!F^K>l<CjT^c*Q%iN>YPphW9BZL>Eaya>bbcpWDtJNG#%^=lEXB::eADe\ib*4DkK+jhe
eD#AXq 995V!Q&l9!k@T&lpkE1dk::&^lqSXcCZF?lRZwTlWqjMX+qp$:LtBuZ9D/a6jjb#CP?E#cDjRI\?eZ=M
D$b#q! FAGqhYL?ATB&RI58bAy614/%1$5@Q!tSEB!1:Rde1yhI>%P9DuaB51jMDdd\D?qS#XC/AL:MAGA/?$L9
#Bq!ia c5RF4*6l%IXE>\ec@\@?jlhwL?QpPWlkjRyR$niw?hF+Sca#tn>XGTi1c%dSY$<Fj#NijXH=8m^?F%di
jq?&XY u*LVba\yaPm%BAXZ4&d&*qa\Lk#IIjXL6G\h=\@Hp?hDY+M/5:$kQiK=bAu$RYyWbuG%$Y=eWtt%G%*B
ET?/TC lANwI8tlTk&%8pESDqjR/*nN8S>watNJ=&8<<tyu=5MHZISm9E#Q>CalH>^Z\:Y6k9#t9a1L5=q4DQkK
&qu8W9 D\Zl:5\C^MA&#I4J1qh*QH:6Hd=GhjK98Etu8?wl%Z*E<NI=IVFu&d?>pt$6Xq86&YB@SX81*Zted*=Z
uY>qw% 6Rl<aRu%wZ8?W:CCcjjt6=>ti1>uMu+Lbq^IH>pbT+*9YiRh>GcR%^aNWG:Lk4wCmSSG>Rq=lBp&D%Z@
B>%knD DS:4S6/>*@hl9DiHVZ^!eHT9A!9Wjt6q?:mDkIp=cXSqtk$uXhY?Rj8B@!TDQV6tntaT/VemPh?/YntS
?9i6KV 1jAPjdaX<8qq#IGQS#MnjiY4+d*\WPaC:L>dERJiWc:hu:XL@8aW=bqjbij?Aw88kSHTZ66VG1phZiMi
*K6<Fl RI1@V\ueGEn=lMeqX\mmKiAXH+4m@l$!FT:wF9wVdtp>$eEnaNTLRGkppDF*Vj@Ku1=h1m*nqX&8LR#J
JSCJMW h<XZ\<b6t+a\dY@yV/<qYlqN@Ge?$/C5Dc#hNkd*EJeXy$<BXMN>TG6GY$R4yP9lRAC^Ny$CS:8\X5yh
+6R>dC Sh1B@l#pEACNaMhKApGEIC4YHC4RC<bm9SV\JA!H*CAyjBVI^pH8W&?A%M8XmQnZ8L&+85jALR$EwHM6
VmRTeN JIALhEB/nPlbDPuX\IY/JTJ/JL@BjwVu@SC<bKqj+iMyLMKG4qelWR+J=^8kY#*+cnX:a!Pa^yLRSYhC
MMl/1T ym?5QAn$#H/E:/h?^W=HML4H&!DVWF:ik1T5\XJ@Hk\B\A5lY4#8^aYQ8\</y*i5i%aIh@p8b:8VT&Kc
=CwjQF t%enELEAcDn\KqSy5*F?#KZHPL<F=i<4=5>*SZ*ByyBN=LJ+kNSLItRKwE%I9WVcyTB*wVZ:HWDajF+D
XKyb1# $kmJBAmcE:Ee<Rj8Pn>J%*eR!kJhDXp6QX:j@FbYi=dPDCC#PuER#lZt4k%IMny!#qwA5lc$VEec/aJ&
EnDnli akE+D/pcKIXp<!C\LHEELwFq\mi+^KkMVBe*ewS4>I<6TFZ6j9HH6l*E9J9kF/SD?nwHk:n\pulTm*R@
ZZ/+5P LBc/A*e%YLc+yb9LRmRh\tw6Ww1DptaW5%T^WITW#W^RXG8#Yi%PI/mATLeaqY+DN4Py*IAWLcuFWTWc
mY^t8V p^nkd5WnpPFYJ5Ft5pPImZ<pHyH&CNhanZmMh#m^B/\wc6HZuVLh%mRl%CYEQA$DV:puTZHki&$#>w<E
tH!6w9 TN#WQ<91AK$ID:8TbV@?G+b6TEhJ!Z+9TyjS$I$pVHDhVmKY$Hm*hi!akCmFVA:$Bl&d=kwA!Y5#CZHd
n$N>D9 SFQyX?kQmbcjCeB>n*A/=BpBXpM8/qWJHiiCiQiF#p9lkFclkS1GIH<DnMB^t+=bi4c$G>5GmZ&nYWAj
JQjXGV IGHc<Gwn5GBWCQq*amA#bLhp*&LJWXl5B8epi<>IY4NJZ\DV:Md^XyNqSnHB?=BRe/6C5uI4pEc^n$MB
/CMPD8 <bwnGjBwK%+ItXAA1W&R&Ru94Q#Fi\D6p#kAVj6#LP5L8Rp6aATp=q/Alb&p4ZDDXyKeY$b?DBeliEC?
%HPuR? PWV/McTuREa^NwAFpiAcyEc&\GITEkMZCWGkphkYR\BILNmqF<dDSdA*FIn4M:cV=^B1JibQLmYG?<S:
^#B!/S Npp<GH>pkW9mkB\t9pk?QINwmbnt\b=+EQAwkmI<EJNeZ8i?VN?$?1C*:M8LDV+H:>=a8YM@ijy1WM:M
lVNZSd T+V=n9RC5Zie*!b8!\CKtyNDQR4WA\%M^KMhm&tlc5C:IN5#d=:KZyw*W5?<iSiq5<b<BQ#c$#^#Z&#A
-AW/pA 000a42ff1ee00110333 Page 466 of binaries1.zip
e%bWiy >Y^^$w\HH=InQ^!//ePM=i%cejq$\6q\5en?:9^C4G5kMV*:&8yiDSW88YR/NbZZEGw@LeN%=qhD4+N<
J/GW?P PT=mhlMFe@1L^hTkD?kb%1ih+Q&$pjVYQ5I>WJZCnM!4>tpq6l@pcS>GPM1jy9+a+68&kKwT4h:AZit6
/W&h\w @mI&*RjCbPjZ6Sj!a:#>NkLT9qXtl%MB%LXA4lq!J^h+!RWA?<NI!E!Fq#SNpP@YH4+A*KZAF^kwEP/t
qJLd6I :B1A*uVF*in11qYR<9Z$ZBpFb4lIlTw5$E>L>IK!V</Ej<ZGRPwwVG&DVlJiFY/Fe&@a+CSaIYiuFR/S
l:PiAA uJhDIw&MPA1y#+@DWl9%JF\HpY^aS$WSh^$\Gb5//P?q5GE8QAYJwp+:jQe+IX<<C4SB5A4yiSlkkE@I
VI5X8V nw/BH4phC*FRp:StQnWu/8d1d\uCH<!a5Tm4JiwYXHT/H@HJjRpDLu4H\8%jZ+P#L$Q#/>Knj8#PQh/>
k1+nG< :bI+u>Qu9DZY4De?m?BV++Ydjw!Q6+@pL4nuXR&DK1&%wjci<kmZNnJQX\*=bhF6Ql!\!wkVEYGuI6bI
ZhiZ/k Le=e6ucX9lQ+eMSwPjN5BEFT4@<nAepItXRbua:$l#wNeRytDTJQEwZTcqlpN#y5lu<yW=ub?Jc<Q?Be
<AIqpZ 4&P:K@*BcV&=6#+!$&b%PI!nTDdM1:YEYM>>@I+@>$Zq?<R=TP$&Tn@l\BFIh+QEdlIyJ</\paGGSjBm
9D+%=V b+atJn?Yd@?&K&EkblNa4N4\+PNlin9Z4bYhqF<ceCeD>M<I>6N&jeQLM88PNQd6wWmbijBV#LbSLLW#
pG+:D$ uY\9D:m&lTiDWtp\DJWwAY:P*uQqhmk&QiubP>/@W%Wa+1jheS/?9+5hIQ^CdPSZiEY\^RKwSDt58A!1
a&9YXW E+^EWLRNq%qEZ=ViQXC+V88uyi:^mqW1^aDi9y<YdWHD#b#YWdL585^>\m1W<Rk8ik<XdRiwdDKiZcpy
RWS&:@ 41Z*Pt>4&L15K:#Au^?l&!B:Tl<*lFeJjy@/Xpab9Ti@/*8elJ>RCSq^eIJheYFmR\GW6e/X=*1n*et:
YT99Fe CPV$l*SuMnwSaAeHNqGK:S1Y=&=dp?I6eG@9EBD8y<*LMnteLZbVYc*VPCVyTqSluLZP5p5C6p5w*@uD
Y$\XBM A+@DMd9D^BYFeWW:^6pH<5V68^RIkm98ee6IBYN^&9!8/pJTQ!G1uydeRdL<&9MHl^R9Nu%eLjm#w=RC
^Q=jA@ HDyceclymMlmN#HRG<pWdI65E:Je6pMDN@YW@9bA<6uA:^>wwFd$LEueBACYQnFaHq\HjM>jZaqaa\Ql
Vc+ajQ dlJkR:+H!*<1du^8R!4qEYAd<lEACEZ5!FP5qblXT:y$<<kwVQiH@JcP9Y<d9V>K58&N=CZcFE</y1^$
%i</SK DiyIV:Hyty8QHIpdj1@*NRnYm8dYBFHuR:q!B:X$TLyICPMmIl>GDqkL9bRMe\Bwy&D%TYRKI9VqIDR@
<J&TXt ecp!?M4X$VQLj?k$@AGp6eAjdVqim/a!95MLTQn95N/K:WtBI*m/VeI\56#*EBTjC@pAKKZ*H%FlE<D9
B#Qdh6 tF:8IC^<C#1aKJ#LeH%j*&=qqJ8c5u6I1TPh9RpJX$q$&kauQ&Gw*@w!G\A>ncb?<%J#G&BW6=?m%td/
l4Jj6Q Hi?t$m5nNA8kbpnpP+Y6eNPI:JINRVDKy/S@:NC9/C<IcTmGP!LpRT$HZ^T+X=hW9Y9tw#?9DK?HP\dG
\GwZ5@ Py$>&5GEcQ<IPMuyZbiTPByu^/6nQG1d!QkaWI\hw<euZD*i4K1i<bbCVVCLaM5HWYStn1#Y:DSb1ny>
=\mwV^ 4GJdw8q?PbHMLGJ9cF?QjS%XCWaQ>6nJw<pZhuL$u\!+l^6u!B+Tmh1FPJ+V4adkN\!$wwC:@tYDWd9^
ePM\kJ GJc4<n?>R/T+6Hm4taPVehFuk>%\8a6GM#*u#5Zl:\jp*eq4YCmWBDMDn=*Z>L1WTQpPpyh+4B@L<Nw1
#:B5a# LpSCAm58#bwQ@S/QL:^AN%B%%G!C+ihtA8YVeEu\1uG#J?AmVRBZkj=<Z6k^a*dYKHnF*Wd:9c<%1\yt
@JnTQm q=Rh:MV*dpu#u@a&RSj8lj!8neTBE9@JBBHe$+&H^ewiFcJP+Cu&pTV!*GQ1&C6hh$bySj\/$E$d<RCA
knW&#V PNFYG?Xc$V1+X/j*KNYJ%K=>i+XQ:e>Xn+FnjXqtFm#bHC$8IMR9VBVyAWM<C&nM!\5IilbR\^A$8Vek
y9kmVH 9QFLX1h\EZYKuphe&^:$c5Pj=1pLj4tZdAQm+lGVMhW@l:l^VI46q^Z#\wqjInEV5dRXT/aQhe?ue8X&
4P1G>^ /d?c+Ze&*l5i9pSl^?q9AdE+/8:RD1+>:Wd%iZk9^D\^bWJYd6jT\\@N<q$=G9Y$5M=l!nD!jwkIn$RL
TX:6S8 K!ILRqB#&*C^LbTj/j:aP=1^h>B9^p1X/P#m*HVB<KKPbS9C!eK:Q^&#:I%RLG<A@wMymL&P\\4XYHLX
DDcebB &C>8SCIc>66KkB%lweBh@uKSb*4t@MiNK@i+eZCGS#MRk8+Nt!G@@&LkjABH>HA4HtIX@5Z/D1=FcDIp
h*L&ui jS>&Y/L%I@AYRZSRV<R5E*HW=BnZ$l%$R8J?/aDb^>?\59T=EbGhbJD/%9i<8lQVZied^Cb>R/5$:GVI
BY?HKe d:14bD/BQq#jY1LplI\?D^8/=<WnubM/^1ycpM=J\q8?!wPADtebk+NJ6ypN59I6@Q6yEeX&k&N$NVkh
jb\u!S q^H<XpT9bjEq1bDctSn>8<?!pBKwn*A+DjYPB=ED\/+w>$M8nYQ+Z6?<yywJNQt>IQh#q^NRWc6qL4:H
*%SYt/ jk4=bGbmRPeEL+WYK*Rm%@!L<da=4KP*4<*WVB9?/A4+ZD<4/E*%PACuRt&^GJ/FQXq+tu#y:ulI8Z#D
uZP$wn *Pju:pe?k9\?Ip$#Dn8*kb6WiIq:G1XyYm<<h!TY4Nh\a/pwF*hRIRqK>Qw8hP1SNjG>e##ihp\VnC<S
RQ#uN* >@nHaLYtdG#:wyLXGmQjF5JImTjn9YPpcS=ZYnmi4=6LPnVZQn5Xa*j&Ylc\e&V9D>bCwH*F*XKStM1F
ZdKRyS yny8^GZR:Vd*EI:=J#X>dL!:NEwW^^tM\45PeH>d=jwjQD+K5JcPqQS4wAMpk=qaS&>+4mF+kLDEEhkK
*G/ML^ T?TRtT\D@H+aJaWXG4AY*mPSnlWL1Y\Ea6HY\&JH5/lF/$TdFcK+A:*m6&IpAEyH6wPSLQBDkAk!F8k/
Alai@> B>H$wJ=W5ADy/4e^95V#DVj1VVDDdcNnBXiNbB%Y9qW*X:<N%km$FDaB!BMRDeR1yJq%AYlPW$lB=e>m
IG9\ni p&!++pQRHe+6$6FuAhLt?JPR1RLaj4Eji5F%#F*InV?n8#EhkKF\QFVDKhBXC8q&TPj&$HGn\VM+<Cbk
Z&?A/E =BC$R%@InIYMT\YyQMm<PcIRECMBDIjEtt$qkAp6bpNL&BHJLLkHePABH!RblldVYwmWPKyl#An>Wjka
yEDmLt @9EATKu=*VnMeyNw\$R>i?TcIWIJlLwcV9%>/X<aC!<&EW8cIb$@q/PVilFTj6?jkMa8MiJ>dInbB$>D
?QBpZS KZM#n<Cnl#Xw<PaMLB<cQEyV:M6K$+9Rnn!W4k?jC\D99JyE8@Ik>#Zp9>:Ep8^aF@YSKGQ\PCGyAMC1
Z=Vy?n lw:X\CL68/t9X*i\bHJ#<?wBbC1b&=:dykXD$Kk5^S5jJuynJkBL5F!dS$bR9+ibRhNAMJN$QTKc86b@
EwhF8c &=&kc4aT%Q^!+p&8MRY<RjcC%JBqbCRjPbuk8u1S4ZA4ha^eS<c8IT=y8Q:%udka6kJKn=BE^9bdSDYp
!>JYW1 F6S:FhM@pe\QueN:RX1GNNbhpI6XJnRDJmVT!\J+9w*\+V>+qj&l8I\/TG/FjPn9lG>@>ta#G?:uK$Cm
6#&Np^ 4a8ETJXD/4NtWA*y&$nQ5pAmQw%dAX\I>E?HZJh\XubuQqqIjIb6Ya%e=XekF6J@DCIBF>8l/N5cIBjh
%&/JP9 Pj^k+c\b^$8lQ?T*T<F=RLGLIhi$SBD*F?D4bl5Ic5T<P\*AG1LLtyQu8*pqh\ZcWb+>BnN4W8Q@ZLd9
DuI&q* dXjjE*\+H#Wu>T?X?Q4pT*nJqIqlTAZ69/mL=Ii8@L+kSwwN!G+:B/d?YcMdQa<E%cb:I\6##XKtjuTp
Xt5LwM F/!SHCD/C%kIPZFiZE@pLLekYk>?&*W9eZ*lmMl9Gn=wQQ:#Bu/dkL*l:E=B>K:?CDwIk$P#MCDGeTC>
n8w1>i ZS<>FPndab1JTKZp@8W1$e4?BTB6WAe4tDHjT+u?=/Tn!NHL6Z\lCVY9:tIiWNLWe*B::/VWIdPq4hB4
:1KjS? >q+y5!E!m>qFAyk+!?QqRE$C@Yi:<e%t\nB#dj5:B1RV$X5@+N9ikJGkWlm+khlC@QXcTuNc=FhpaLDP
Yneepy wR?&EZZ5eelFRd1Yld=B9d+nNu1RDG+^?H&&KQtRMtB#<RHld*VL/i&C5YYKJZ^:yE<REBBGJj#?bEjD
?8PH$l W8bViDG=8=e*1>ut4cPm9X$?$j48$c/IqXTcEA&*&5Q6Hyhaj?^5GDWH5:=FNDGFHd=>iMmk1:+le/M?
a?#4hy =1nmdiqM@@j@<Q*Sq=pK:D=:1!F*+RwZQ#a!N?p^kP>y5T^>H:nd>yN4VkhwKIDd^*Wjitp\LL$*Y:8t
P4wccy 1+4aMdDHV8w5yAel1jG=PYwh6?pWh<jHhRw:p8k:c*%qa#8ZP9#\DEkG:9cEk:q8cVk**FZbP8DA/6HV
N4q>A< AHW$?qct#!DILaN!/ldaVKd%N%pEp/QcYLHQV@R%+Lm\u#DGHD:ZA/@PaHnqARkKn/\an8p@dMK^!AuR
pl1T%B H8<^/tHy$imc&!EdqDJbwQJ5HHB19dAq+Cimk!^aNW<$=c\GY<GiH*4<qi%mAtLp5hD<AbSC*pZ9ku#4
k=t1KV bjTY1w8B^PA+@@dDFHeWcSM$Ci&4IKHdBLqRM=RI$B8WtcwkM=/E4AX!8?:D6B1n*8Cw6S54QyaVPb<V
Yt&ieI uebEeJqRSkk5AatD%RK>dGtEjC9eWA8w?1G?Q5V?&*L#cF?tL+#mH94ZFHK@QyWZ\l\/t/!Se>j>cii5
@w=p&M X*&HL8tQLh+XwJmydTM*BAK%R4hPCy&JqeRQpQ=FGkRT/Djh:t#RPBiQRJQdLJpc:Qy&eQL#pwh?h!DI
LDGN<9 NF4K4dWYb+ZSdtd=aijqp>ut>JMkl&Cw%wN!:tm=pT*:YM+9?Ei8w9Yj\$dI*jNHCy%NjtiduB>lyyFG
<*dyeZ AjeB&B9A**J:$4SQD\E!n?ZDpRw&Mq5+FlD9WYA^d$Fyp#5c/kd$9jED>!yWAi*4uu$@8cqn+MAp*MkD
\4^I1q LuL4pRHLt4GJG8VQYb8EVhVC:HC=m\!XAShLkZpNAY!Q%#jQjm8kQbu6@8STeHLd4D/KiRLAy86GW1B@
b6?qnF $eDBe6aMjbnXCqcnTVJ4Ee#A1k#&q+y6mb@9Ab9&@?lCTw<8lDPaFmIyNqlIeCNh5a&nZQM:tHqbLk5@
/utiuk e?eIwe*DM$qJ8tt?5$CMEATZlJE8Q?ubDX@GWQ1@qK/GXq&X<9kA<8iae\MtuJDjqAhVjp&V8q/FY/mi
kH%Xja JJkjY&S$PI\8m>NpMJ94H@n:ldK9lc?PdLw8y@6CMJCEcRXYi$%IyQC5$c6qKBZADIIA8%C=TTVZ>4E*
K4/PLu YHHN=>qH+he!yESqyE6KM6<GWbEk+j+I9la!pJB*+cwle\hTbV8Z!X9lpyqKBw#ktiC!Z^XMMd5P&6c:
*u$RhQ N9TG^Ql+YQlI/i5<yF!tLE&MTjAM+Cne4>ML^G:LkQ&PQb\a1eWGDc\$m^%GuMLSQWk<C96eG^\dWmad
JltKR9 q&=!*HHeYbn^J6q\<IdD!*1qqhCE&MPhE^9pY6l9apPmGIYqeXMG/^h/F9iFq*WuqYh^4%?ImGen?da*
yCVG5K R?h^d=kAKuS!wh6VPE\btZ8@Xnehk!<5INdn%MLFcDR\V1pq*?*%:lY9tHS/!unJQCW:dX&ZW+PW?1H#
-AKLMZ 00082c95eaa00110333 Page 467 of binaries1.zip
^C\WX9 a=MbM%R5a+JT+^py%K/d%SQ^qYtHVN$Yqc$WEq&BZ!DRW6:FZaDL/@E<XiwFH^<>nK8$G+%wyuZ?t1Hq
k9IjTG <$M?@qqFM!t\MqV>#cV\EX@aaMcI\%*#DPZq*=Atibub?BjhCqjDh?/NXI>ltX$6#LNV*m!PQFtwQA<=
VR+8t8 ?T^+?DQqPykQ>$%4>dq+XQplY<@5!enVjM=jqDaFjPnZCnhBHY?Hdc>Sjm\%M*%nAAtyWYCZ<4Aee9Nt
:K46^m MVli5l&BTY%BKith9e:ET6K<M%^?&lj^mJlHwGq^^:!hJYXTyH@6kNTBt&PAGI8+H:mN+yldIyQSQF<H
MlC4S4 lG88C=&H4h=>b$:uqbu*M+hlQ</a?=j4?C%e9*6%>@6R8^X$5<w=V1/uj^uuF$^b\lm9<GF<*CCDVw^b
\&J&aa $h\l6cIC+CN8iam&c+qupDjJ@1jlQRii1D$^\\T$c!uP:\!Sn9MT6\+@h=9AS$5/P5Cp1BPc@$$1:QB#
6D<b?d aRM<LkaiLSGXkFk\uC+?<k>aMb1EC=lZH5KBZua+>a\@Ny%$wBqMJ*<yk1=aR1&qL@^d&uicK8N+D&mB
H66bX6 >MkuweVR/i9n1L9DNR&qMF<K=WYccS+RkK5+/q4c5a8>y?uSqQd?h@<TnitTVD$Za8kQFpFc5pYVJ>BL
$CSR@y FkN+#d?R<X&yhqLj$$FNih:i\WN=S4b1%hA6Ad$<:uueC1q4Yaj!aqEWSQ*!&DiMntjGZA:A/AAyE1k?
8N^hlP kDLNR*pT5JFp1/Ltq*>4?y%Xuh4^YSlj@K%EM9!S#h>FD\EIZ!>aJ#@dcNbIjB/Zl=m*>dQ:p>K*e<^B
^j!9j= Cb*h61eBa4k+IuWb9hy\ujHKSX&iuAt:?1X1yw:dBecy5\twiGi1S6C1mdDKpKCDkYAM!nbPhDYnRu&Z
N&=H:< 8\9PWl=5jBIj91bhGW@i9Bd\4=RP@kZpnSJKAq%H%IR8keqCt\M#uJBB4cm4abXX4QaNHP&E:VFClt9c
MjN8X8 nM6Q\BWDp=yhPY#dZ&q<paSaXS+E%XJZ6ik%#YRBwWJ4<4lwyTR/1niCFY+e!mc+55p?\h*JJVuNq%d*
FnKFdq RcLmNT6VYKu5Bc:Sn*MX%B@&MSGQGu6eGS&?pi\n%$ple@Z#\E+5Qa=+#BSbSa@k8q1L!XqjyN+**I5e
>im1Ge tTa<k<^EcAdam^bu6FR$Y?5ekdcjw8qHFXT9/&MXF%dK8?n/hkw!dK&weH^Aum8qdLeTSjWb:%6m%+/n
hM<ne? ^lXmB6HM#ZF*AQGBh:mj6k\T%wNkAhJEJ^cPE!#M*jjXp%d^/8iphX=RTd>6\aM>^mi^d$FI55cL^ult
ywbWyE ^hh*KwYI*@$n?X&tpFpZnV<VbT4mFa$&\?PZ^hYNYcu9AFqJc6%<@1=8pWaZ11HV9w+V^%\$ItKT8%i/
H+HCCe l+=R:^%?>/FR#jqyJ<FqLZF#Xe<EGGE^%u%FW:cRkTy&cGe=4Jc?5D?Q\bL?&py^$u<CjtStyJEX9ue$
SiR$lh II<nb5cNeu6$SQL>XmFNGa?$WCC*CJ8cdR*?5?MP*+&T1l@pK@qQFA\#pJnC$KMkn?RY&A5bydIjRB5#
BNN6^n q9@=\F$LZ9+Au%wRQuEy*lyb8H1pQmj5\ChAk1mLmcI5EJ*Yw5<cj$CIADSk8BBy//T/LkqwD\A8ne>&
EK8QBF I1Ah+REc\LeA\kN?GJASpPXN<Bp$J@:Q/+5J4&9^\IE1&e8&J:ZH>wR#uMKBAW\RhI4RBu6>^ecicQuj
%KIiuK ERLl@?\IAhbT\GVCZe5:l<V5il!!jy8Mb%N<^CMEZbCm+MRuBKkcyK#=IG&NnXTDPG5beByMFwmWiNCE
^F:bZT 6Hu8X%kBeER/nbTc&HaNGMG^VWeAZa??QAaZIa\KEGJAkIH@1SG8G\!R@t>I$aFYYAISb8BeCC><DKD/
jmPVay CjDcwHW^iaLATWp><!$JmY@GA=:FeCFXRGlB\HBlb#M1KF<Ct^q&BIqYM4cJm6bM*PYV1B?F8N<Wwca8
5N4aGk X\L6F6SDLiu8+iR95a1QtTKjwe1WTyci+*dM&d$4S8KT*bqBuCNepuVIZ4t=Sq<kJ?iFKWWWy!#<wLZ^
SWkH6a &pt@\91B!%/JKC#MZVN$TKJ?Sni9T*Mj/FyH6#@ZqNWSwBSHV9B?EDC%pF5B=$IjJ^lEQLaVndAIqF64
FLSkN% K6G/NkC$/eJp5>FRPMqp1iyN&1aSFT:aB4QkbQAy5TRYWyLyBLZJSDR$NBGVTWluDtQ%qRAymetd9VD\
yL^ZIt ?ShPkZ@AJiek4hlJEQhiJ%1I^VARQmwl:ADya@VlL\t#N#blI\YVL$a/ywT/ALXePct>RGlFCA&$pKCk
#Nc#Qm h1R*kl>h9Nu4e1TXMCY5cwSRBJBRY#XRt\iiTWk#GRRa?T/w?B:\IhC5l\\GBwQJ%qKEGP:FLRZDJZ+5
MDCZAE 9Tmw*#kJu9kAi*k^/+H<5Lm/BcSP8a=8QyqmXC*h6Qq&5#hG#N><jqtX4E1HSQ^wny5a+ie///YDtdE+
^/KSb= V1KZG^PII=S^&D&GXbKW18>=HWaF9TWnPPwA/Z$W#EeDTlL81p:kcCh5VSZ?qe:kuSFP5tuVc4t6wZi8
w56*F8 D/94QQ#L*H9qQtiWt?Zqy!>+Lb+yZT/%TihFGt?Q/Nh8&Bkb<j*+@S89>ZT6V$*jdS=*Kb+ddY8aw8:F
*$ESQT TDLcy^at4MwP@FJ&Z?B9*19klj5!ckX^@+F$qb\uuykcZCP%eJ\j%jT1X/h5/aEauuy@5JT/IqupFe^1
=jaSaE p4MuG&4pJw8^*Phu!D\!JdG$?tQyw#ZT9m\uK>4uXe+uF>16V4t^*GtkuIpWIY/uHd$YF@P:&LIuSM=+
m>CQLj t&k/1Z6uV<5jy?@j+6>dy#J%9ZXj:99byJ%n9=R@CQeNC%ulCH>\J!!G:HYl?db1F>ZQ4=VdALuQA1t9
C!j$51 BY::h+Py4GVJMq*W*B*i*pE?9?1JZlcKGRpD4>!KpJ?Y?K<:BGub/:>JKtSc1E**iA^Ejuy@+\FE!!R9
QFT6nt 1dRcD?4%BmlDBYw#RjdN*NZV+^LAde@@^t*1655KJQc#Qh1$A#^mFFNh:91t\*E#VVc\?dY9@@%eTt@j
^j1NES w:8!<FQ&WTm$SpKu>^+yTQW+/QJS=tQj8PjCHhuAP&jQ=$AmdRSpYl:4DeB6JF/PY>QqCN1iZB*G%6a=
>clX*\ teAhm\Acbpy/+FCEHc@:yeBqG&YuiqAXBHPR8CJ4lRmApbA<#8w:RkTIb9aEl9B+QHC6@^^^P@NKRcjj
Y%%V?e m>INdV\&%HbGG58Yh*VM=Jq<ecGB>YHq8VA<D=LiGaQI\tHw@+GFA!Bb$6a6GnLjwQ$EAllWd4jcJCPk
^u/niT Gy!D!WqhhYB!WpwKJLdDh1IQHH?FKqqZ:46S/6Y+%ie$!IJ*aIT@w>\\SKaZS5QHlJH4:>uMeB@:ji6&
@FS8yG E<WVFjG*mV@D*Qbi!yhd+VXnEPmIX<J6B\6e**bAPAi^ji/V4E5Pw6R^I=AnbQh+u:>/jAYb=$D!c6k4
/y1imJ 4BddQ5iIY\+1<A9+65PEK9\t8Qb>FpN?J5<Du<h<cbiuDWZ+y@jn<B^J&kS=Q<VctIt!QK<ZG@KCd:Em
&4:DAm i^S9!FnlCuj=>8%M\4+Bd\N>b/^ac$WZQJdX+Jh9P/cQ&FbllG9Eq#Ne*wFQLmSZD4+jL:?^nZyP9$F!
tjPJb< @h:\i6%:1WVe85XDNbn+^1PiHjEm?jKP!Hy&SJ\l+\STCQ5BnR<%D/Fu\L!S+n=bI>d/\%H*FCWXipy#
%Jh6yI >?85a1&wcwRRd9LLnuZ\#TdE8NLw:Z?t>qdeP5Mw>4ZS$<:Tl>tebtq>tlh9*/>wnl#S>eDebd9*y#/8
Q^pXWh #KF&$n/59$+\JIDnpJ4!jeytk9L/yEBBjF*qj\+Y5SWtl@NHic*JMd+/%6@yXD#:t*+YIhwlI<VIaqV#
F$Jc1P %/nmcG#N9/*wj/9>/>YFRF9khqiJnjI=:l:<^=JXn?>??4mIu4%F<eV:/IDtQVckHikJRMNp^u1!=pnN
T#tNFc PjhtZC<uIdeeEkFK?CF*&#<nWw6ncRA?@iKDei!^+^%hbybJu!&:X%EWX&B%yynK6*8@X=#Yc!tANuw9
6EkR^9 QHydE1WeT4\BJ/S*p@ZkZ+V>w14Aa>j^D9Zn#!@Imn<d5DMtCLnyby^\I&&l\MiX?5ueDBCCXLZRi:<<
SI+WHE 9K=/T?Z$!@AE/V*GLYp<+bE>uQRqnb9#!J=G9MpZuRSkV/jYXiK&keYYYMuBE&=9=XXXV99>%BckLZRH
hnbPP> WwqW%c&IJXn&6K9itjnk#>w%&V*!B<DSn6/#$/yWw4%i=B/tW6TK\D#t^#?*M%a^>b$8^uyhn&WPjP+4
QHwjXZ ct1aImKG%J=Y#LWDAM!S4SDtQPnp8&N?S86wE#P!%+<!w9LYeB<@$cE5iya^TiI:N>m>IN6^+eF:\?KY
^GX#%a p!h><^jbn^iG9AK:<FciQi9LntSEl5T+/aQM:*AqVkC/\eJ8D\@Ntmed!hY4%FC?qlpwu1aAHaVBRnEn
LD1<Kd GAu1+NT/l>%mkuMuNTPeJT9w#9:nJ*Kl1=5e8QTh1P*5Si4P<keVV<#*D*tqQ%\WQLRp*^>d8!eDN:qm
&/\RGT X%6HT+yp9h1L?6@$>9aijEyI5:8MN4Pl*Pmw<e8=Cl6cR8p*+#Z$M6>#cu=yD\$*hccEtk?64#L$FBlS
*1^lL! 5>W/!Sm4?adVQt4^^/bRNAn8Fq^we#6^=<4Vb+?eh?+*4b<&TdbmYNKXkPEERTR!9<I<W+Xwj1w$Gi&X
p$$4S? <Z?6wLadNBE/NR!hLJW1T$$%Bu9>Z#N!Aq+IwYKAcC4S:PmMFSH&*4?Xwq<R#$Xet#l^$FRMSt4cQjS:
ab$DIE 8JeuFbeBC$>/=q/b=KY==?Ybi#khdD?N%CmYPJ@Z%iMq^pR@Q?tPRdm8/X%@u6CXc1>kX#Zly44?qL/D
G4Aj%d pb<\M+jhiKhlS?BAQ1Ct655!I4Mj5SQTGqnI!KYQZyZ>IdPS<H#8#!He*kw6M/TNTP*$61b6XA/9>dbF
MZ@>$d %AN44h%B\wkmqet!p=1YYk*yu*KqJHHw6PaIiKeVSb=^cTKehpPFpV9a=VAJu!6KIR?m+TmD&Yt$C^cD
IPiV9l $#Tyll\N9^nq++ink\L<&qKSikLFVXw<9jk=:8J9y#1pAZXG+SyVIMaXT%&cM!PbQC*DG=leAjI^!$u@
cTtu<Z kF%At?pY^/mHTLl@:^a/\e1!@8&9>NjV:^dujkLL8%DVkBn>L!+\VN*^QhyXeW:jPSu6hKD\i8/mAeR:
=AJ9+* kXJ+BMAT:R9SkkmCDc:9P$VL<t@J*59u+T5&@5BymIR+FkAjP^Fmy5:+=jSj/=:&/:h=Y5CqG:4/kHA1
D*4^RW 5Z&w^9iGcu*Z^F&t^PTeD*hG=#=@^*yj#Vj6Z/mF9$dBJ&6C^@t>H4d!WClaRL>ZhilM1Ia#uSyIyA!B
=cqTcK mXq8=!*akP1=lZ%RHR:BT!>H**y:b5a6*JCtH\A+D?uS5K^kHG*S:846ehYK#a\>+:aVJWlKS#:6hWud
ZqdY1u *^M8JSc&uSH4&\jGMydV>+Ii>1Kcq/eALMDEGa^L6=^^m+>N#JLA?^qnq8!A*MTludpq1@yI%GD=c/>+
h/Dj:= kup\4aC#?w+P*GN&Fa&@@@Xwi88W+ItDKQ5/!NllbGG*!c<!mq&1ki?p?ww&W\\?eRZk9dMh:nGd$N$%
LTuD>S :@D>uQtlXi@ERMybw4k+W5HIQp8XZSu&/wCkqet9^S#@S9X41nSuiR4%:ZiDQqjJWyWZR*+P6y*\jdEi
q+%hkP A<:m\:BuP\bRe8YjXnMiLa#V^Hw\^$ChcF%Z8YC9=Xe:N$#y6i56!hZjwdjkHZDJyTlP%y*?NGFa>*cC
<4E?#m GbYXjP#cYT@Gd@ZHRDLan:VWEY>ywGl%EMeGX\PP@?Bb\ndmJin1+^tw+!/WwR$RaNAqejMRN&DeDNp=
k5jL<q >?clpqZ@jGy&P=ktu5=$p^!JT4VnQi!^dE6e@BniB/m&4q?M6Ec^HE+X8@KT<p@kmHWNaQ/E4bD+FAJ?
-AyjHN 000ef7bf1d400110333 Page 468 of binaries1.zip
LXFm!d E#\HGS@wikd^RZbBBaAC^+9aaDZl^^/F+@G=h!JI&EZCjyBiBLANR99CYaF4AZNRNS/N*9e@Gn%lBCLE
$=@%<I !9WeIS/J*W&+t*%EMDdRqhGFSbIh/Wa&<RR*=1uEJXYA4Vb1K>9QD/EpdkqpL8BD#J=wedE?d+J\#@!^
L5l%@? @<Fd9Ah9+R\JEtIh\Kj6j>Tj?\wRZ+I$V\k!dpIBRZTI^4&kiG<d$dNh6JCKeA\ZZw+9:iwIp=C/>F<L
$yFqH1 bBQC:m$hMSKq^DmWm8B:e1dX\q1\^pT$Rlwe\=ERL>bQAY:nn+SIJSBlTp6Yi=cA\L1W1h>K4IbieC!*
*Ahnqc m&mGW:Qb+eAhyLEeF>GS:mJN+JPt>maBRYq!^\^&BR=w!N4+pQmDi\#@?Ie:@\6B69/eyDY++>:E1yc/
mq@i?k Pk1D!/D:<e96q+ZA6j1*mKuABp@B:Vt/X=b<^HI?5?Ee+1?u:I9XkC5ELikQYk&@IaneQaQ5:yXByN4F
5m6c1# Y\P\HkYYpmI:P!^pTIYi=Jmaupw&bQT/$&6w5bj4mMbui@EXq&w%Pd!MHijHt=/T=u/yuymuF1\ZX/LT
*SPpj* HT6kLQG!Nh9Za<*GGSbIEX>:AQ+ucNF=dPFm6c5pSMi^e/WpS9q>kq::\HNKyqICP54ySjY$\HYj:P&h
WM@&yi p\Kc$qAS#n8lBiuLcEF\M@eqN=V6J&kbbIb<KyET>#/X=EM=ZIS9N@miILyBll$JD+K9JI>l/djuJhTB
wI#m%h Z!S<%YZ&XAVQT1VldP1K<F%EJ$wt4d\yCaX<NdpAqpZ4^\K1N+kk&XnIFaekyc4hBTPeS4Qb$X$1=d>L
$QiF!t >lpLGSZM8DCW=BjA8ipe1jeVn:IWwKGF*Cl5\hKyaJ4h=!HbajQFY#H8Knkt>ZB4FjZTq8@upSjH<DW9
%c^@Sp +R4W\\Jt1hS=u>\V$RP+>SnMDEBTHa8T5WqLdNi/4hQtaK+@hyMGA&WEqnF/:QG?L=t\%KXlkEWm$+@n
jlW!Y$ YmG#l?uPjh\yM%8KZTYEN$ZkA>&VdeBwN^p6=eaKIyc/AmB^F@4Pky^&IlGHWJe@i$X1IPdC6tGh$9q?
1RJ%Eb uhm#pQEhR9GLIE8NkKMdJPekVa/P%djCK?JyI1+TMu1aB&y6?JB+lYGF$:mT8nud^kik%j$^MS=m6lld
mLD@H/ <BNDnI=nptCjTF+=l?B89EjSN%Lk:PYEe#@%A&<nyXC#nh\KtSyaPAXT:$+YLy/qKLJ$X<SSGFF6NihZ
HXZbKQ PB=VS#mtac/iFkdDT>D=ma?+d&GJSFKIl<5RI/LeX&I5?*Bb5W#^d!J=<W?jhLT%lA!Z9ZMNNLJVPwt*
S86Glm F@V\tEA^<:/XES&aIyMK#M^&mYDEyepeBlAa+c&Rj4*Dk!y/=HAh##*=y%D?*h8y:uyLN#dDE!&KmIF$
$9NSP& F?^a8d5wYd/=9X5yZ\\JCbtVL?HK9jE&qiw=hwlIkZ1WYjVI*KHPS:#Z@l+CSR=I8cC&l<jhq+=GCP#C
4FDe>K NLF%QFaYid*>8y+tR*y$NE\En=nKhW?>cC<LteGXRKiaL4yehpHEwYA=V9<akNhqWWY*N^Z8/6aBtEVu
RbB>L? <HXWiCnKIP:@J&VB<&+QNRC8+%aI$XcCT!>^!V81pEDb\M>9j==8l!$\lynw<^a$c:HEE/@*\GVAWy4A
e*N<yJ EZD4kNDF%ZNlM9tQ>Iiu^PL!JCy+8ES/NH!6Q?CR&5i%R*@mLi>ctIe9HJI=JYCYJAcH<RCmAWB/t#Jl
y@X4J? TSjI9@>yJCP:Ik>%4yEYTp:=Z@Sylb5AQm:VCJN6F/%>\TFJw@ey/hbM1keI&=XeDdqju/aRZc5lMj=M
FDPw8E qQyE?GbHR:tht5\VE5WckbS!q9k5/u69&5?bChJwSchKi5p?ENV=KZ\lS=ikHR?$$FmPwwF/@uZ9%Hqq
CM<*bT \C%BeejEBb56>t/p!@q<h8>iAW9$Q=jP/9YnT/$*VVqj+ZN+hNc9AWZbR?kZ5ia6ABWey@BIk%ny!:LV
Yj!Cyc *!M:eab<NREEIkHT:!kJ8lPA#leB=:ncFa1YDwEkXcnCJhLX!W6EnC^PF%#/B=iCEChn46RdhM=6yGeP
#ceD>P =9bD@8ntCD:5ww#/hLNjqw@whSFNem6R=nCqi>nu$k%b>:K!uA^@eV!@\P6E:MKA@l/%:kiAeqay*dQ\
Aq4nhV FF&^/N/Ywui#a@I1cN><PP*:kD#QdlpGWK+Qee=tjMS+Zua:LXn!tldNl8NZ^^/BJcGB+DP<X+pZDKF5
:qu=HQ XlZlnw<SZAc@wNT\<pH?Q&*LIDdBDG1<4^RTl?dAI$!EbP>8=SepA/p#NSjT^9?#Lp1!@RjqF+XkVy1@
/ZjDL< kb6jYELC+%GTl6lV>EYaXqjhKG9BB:1abG@XG6twjdI/ih4\CXh>dV<FFuqCTV@E:j\CXb/Ai*SSM8*u
@+?WcM 8%h8$!M*PZq64IRc:p#$HiAS^FcA56EM/lLYZB*KB>GJD^Jq*1pDnM:9au9+*#CI4m\5n:=Rwbp#A8jE
H^pcLT Wutje5tpB=Q/E:%thew:=<@aILZnNTZSQnHQHS+1$6#I8AWK4S4:%RQt+4CN#4\V@uGPcwQM*p9iH9bC
#@SwJw YeFpV:paeZeH*D%maM$WD*yHNMSyI=wDlAdZF!8+$$GD@%nMQcpM&aW%p<1uuXI&SeTdJkcWnP9tE>a6
e8LYDM %m5<WhVHSLF%ClXjwQaA5hV@ALEAD^DDGSybqIuwC#pC&wqQXNRq!CTI$W1+Tjq1%QhDcn\:m:FddtmZ
nPtQWy c*$j=PaD/NL?I>/Lka@Cw8S>Lk$l&n*6#Ku!k@?ABphI:QCAp\q%JccHK$/Fqp1aC#T^pi\Cd%$6iEVN
GmPVXC n@DJB=<>W4QnbePK&mWJt5NdPt>MBDQnjPE%K5X4PQNlhbGM8@?uLE*Sq6bjpbbX%yyFIu%m*B!Hh4B8
w!<aPu *pI%bLbYcZ#w+:@F*+5KjRF+eV9BDR*SEh\^:9t+\Y?/n=CBjindSwB/KmwP@khhF=5V^qtS+tDbFjuW
CB/Y\J /$:pGKqLt^Y@ybu4h??N=&>wcHchEn!CVNM+Q#1K1Fyekm**VBBS4*Etik/\mVWh^VR:qL^+!W6KZ1AH
1181!t C^^F/T&49hFWi&>aTC>Tb1uw%5e49yhH!^PbL?W/Xu?Ilml>>qN9<Qd8@?q=S%uE+wEeuu^wn^F5#*e9
bqEY9F 6n%*H?WS6Sle?A*P9h1#RiPV==?Mm>$^MZ=bh@pyGWPNyT5V1dPj>@6aNBymeIH!kpFiHcQXb\WaeL*V
MHFSLb +QaY:W1BP5h@w4q+J1VHk*kZkFLtcE>XZHt6*hFw6Y<Ky>bAakw#4$:H9FNZTmI$4XKM/1L&PVjwZWl>
aLK>+E ?:hj\t@5bHJG%!QH+<@LiwR1?y=K4N#tk\Nb\ijat+!4dQZ1tPT:pEma*k<6may?jZ^9dRKX/5NeX\DD
h:KF%e a!D*<HjX9m81jDVT9Q>/CbndPSbP?c$diYApHT+$T+4W6Y?<HeDV\<utWGKENbVeFQ5@i!L8$FM9X$eX
*&@1?A R8>Q!Ry?=y68:/6a>Yy9^MePZ/!Q/&d9iSp@i>&@=9&5=<>*a8>u4e!:!&YG98GV1hFul$9mm?4wjl+d
=jCnib #%N5&9@S&!Qmj!Bi8lwk!DQIKF$AE*pC9LqdqNua\mNY!QwRHXeDlEy:M:><9%6d=Rq6@BHyMcAPJ&Qd
j&=#jK :c6$&BhJ+P8htkQ*^N@IF*McW\CdjDwtmARqbYHL/Dd^%n4$:WRi%dIIh?8Q1c=SJiHZXt?=ji4B#dP?
+W$N\9 p&?5:@4Vdid?wh8ZanY>+iA9V++:HT:IlmYti/#Ht@A6ZS@!uy:>Iuq=<\4&dF++k!GhAJKKAcuGul:l
w:5b%P k99/J?@i6B=TH!bI#l*15W/e6cIBR!V4<8*a6E1W%!iZHB5T#$iZVQlw%q6cWWMY+#L@SNuiS:uE8TnE
XS&Y=E 85ayF\#==itP9:R4IJibhm64aBb+LjKG+nWjP^\/Na1p:9btG9VSJeQY>@qnc?h#Yy<J!kBS8bwpc9PI
>+uDG% EP?HFk4Ga1?BD+y1uqNH/q=4Q^JbA$=IqMd&mjRW+D=+>V:P9BlqFmNS4wJZ44bjdV@X:SiF@%Zll<$V
eS1!We c%?Vj>Gn&^Ci@mtI?8#Qn9A@:C#G=MEB9+=bFm!Ed\$=LQ6#G%PyFaeAY$NEw1Q$@>9>=6Xall&k#W&y
D*F?>b *G=?S\AFkmD@EV#k#wVbCJDMk>/FtYl8R8w8qMIGjQ/j4$TcQ+k\t111uYm%HaVEQ%ANiVacEuwFP^1&
AX@iWK AqmCudX$b+RpJcMlndA5#Ci>ubPhRcB#ku54\lMI%\Yc>B%6Fq$5wmtqP+t6AA&>CRW?WNAS^Im6Eh6F
T%^N5+ dXjjMik+lkMID%#TMWRmK*yJkc&lCWeu*AjZ9H8K=?&B^*\l8D1mGWZ4Ga=t^Gcb#PV&RT#i6Rc%ab\=
dK?6:F 4=ea%>mBlP+BERuliAd/QRA:dB\XAMjLIQR^D9nSLHVCS^AkMR\%<D#MwniqEYa+Ny$wAXwwHmASn<9k
?Yy:c= *1*Hh6MPRZ!GiEpRl:!I8pQy?8/bBGD<ZmWI?X5\hS4^DDyVQW=MA!d\I*yF8#15JVubaY1R#YWthY@S
^AIh4w m5bDP/KL1aA9M@/uu@%KV8Q\#ap><M&JLkt<!XK/8eR6?Bl?9RIiyeAjD\q8@L^%JLlFeCbI%EPAHae5
Lm#w^M /tZV6AS\Dwe#VI+nFc&:&ZWC8RHcwGJEN9BNI<MlbT6WJwDnJ%puB#k>DwRpmTmYa*Hak\KRjtpk$&y^
*V1t4w tC1Mhn*pdpA?yICwIKcV%E/+BKKJYpHmwMytNHp8mej5/Z+5ZATd*mdy9qA/$L8KjHG/HHi/*bZS5bnD
X6$N>R CFnXNY!GMd!@^^&Di>5hbGK#EPJL>WBZcpW+1QA1<^J*!:I:cyIJY5/B^Bju<>ySAYitB*qep4\ep^41
Ah$TEE mWuFGZ\H6KEq&^VK4SkmCTLBm@N=iJT&w=hwYn6F=J</tdIPcL>AFJYaGC=1#mdel^\#ZGa@Yh9T:>Kb
E#liEh :<LP41hJbuQ+aRDH\&4Eqe<lZZ>i\4M5yN@<YtKGHB5Kma>9Tw=CB8\laVQpQwW?HKCp5!qyu5MAKw%X
Y:+$/F 6Rb:lcN#MEpWQRlL8P:qDXkeF@EnT$lWcM^?kJ44T9BF=$nyPWn<uWP?\lIqklR!d$FtqS!l%XGA8RNX
n1LpYG LllSb:BdHG?\R>?5Jau=%hKLQTPPl4$NGmE@id^WBWEcjw^94hp=$nFHGyVE4mh9dmb>e!ASu/Su\48\
#hJ&iS PG=Lk\?mWP1*V:I#9F8F\#AG/W>QIZ$iWq8peGRd!+?G*KJD=/ZMiEmQ!AQ@5tV%byKE^CqIdW@+Zny!
?kj><j LQq5i5VlZ@SW8@i=AH$dbGbBH#QwLIu>te!#G+Ebt@YN=9we6P*&m1APBE9y4X%k1bth@E%E&%65^^qX
@*6\tX HM$pn5S%#G:S*ldnWkhenn#$kR>%HDL/LJn*DJk5yqIYj5^91n$$<klSSb^F*GV&NFPq?H!1D?i@Hw#e
$\a1hh VV&GnGJyAQ6bQZm^6aqn/N*j9dYF*=&dna$4:+mcc#ciHYlJHeS%DqVNGD/*Y$R=Dt5ITj%X9cA&<?+:
ZcRPn: \<+wN<?Y>&#@8ub>?t:#596#Nte%h=L=+5AL&aQeD!q8!^/Dih\HtiQ<@aluQbei=VY$e8pZDe\n:WYK
kbMwt< ijJLBHmlcPMt=A@\#NjDpyiS56cDqHGG<\NSy8M+qpYMJ<dtVLGSW\c+h@u6XP#&M%$E:WQSdpDkGAcW
XNAR4V NDEHCX>Z^*c\jD:Xch&5BnRNl%lqVGAPyIePybkQS5ycM!%5CZWiMqNWPnSQhDI9G6I4X59C6qLQIJ?^
V:4F+K A%ITAhJ@\6ZBp8MRJBePKM\#%n9Y\Z8R&45jP9?mbKX9W$ekj\FA@^#^kA\^@lib$@EEB4NE:?i\*VhW
:*GBTN E1jQ56cYta$*bb^F@\@<9X5#YN%@TSRw&t8!XEZb<6lKIeRLm%66k@8$yhm%8!CuA!$Ke&Nhjc+QQ:B/
-AMKMF 0005597d46100110333 Page 469 of binaries1.zip
WWYi@w 6K>e4kE#q*bu<4Vu$cR?+uWF$1?@Jn?TD?YVa=lX?h*1=a%e^nXJK/Ri@a5WLWyPtHt?Q!Rcb1&V$:el
lm=taM 6@:NKJp=mEn$^c:D^TKpRJXW8ZI:cywBjLW#&ti$HGRDdJBj@bE@>>hQKXMLPhZWR6MWkSqN<PZLha<q
$ItX\h wkKQNV&^mh@t8nZb?/D6Z98>Wy49AqjX?t*jHnaZ$8T*W&phnM8idNMdLBYRt!pQy?Su+XVKV#!\n#i/
H>k\5d KqRiyA:5&Cq4C<nPw%QI9&ENQTI4Vt<&qBuNDmGJ>?&&Q>1dNF/NyNQlEl^HhXJPuS#Gp%*N$R&R9k+y
B=lW$w &i=XjqqlG>\?C4FS=\EmclWD!N=#*c4Sd%4hWCbeiZk6E1!u=:pAC^18^G4Z*y1lal88:BnmknLAj4Su
=1j&9L a^<GuEmKC@NlS&@@9nAISNe*d4pZD8:*%6#8DF\LQq$&cJ=LFc+AYmbjC^Q=/aIGc9tBWpA=P6PA?+Bt
AbehjV X*wDGc#PkJakaIpk\\FNlp!teZCqiI$H:miVB>^:=quQLmq8t6nML4=l<km\C/A@VH/eB\PJm!A%V%!%
/:\hhW cnCBQm&h<G&?X9V?+6l/pic8QLhX/lnqh?#?yhl%<aEC9SJ!/W$b^Imk4w4VZk*jb@RLaFcBwHHKE>Vk
LdeQqh ZX*HDEl&tAS<IcHny4<aK+&Q!1bmaqj#QBC%^<8BSYGiJq@FDd^SkC@Yul:u&hN\C>V=SKpwY:V@YPVV
&aVk=+ kZa&c9klDFW\^SYD*B4/i6qML?YR>R<$>Cjn9B>F1cmS@j+e*nM:Xcpait9A>RCLuNn+Ah%DRp?B9m$%
+XHXqG MaZKlScj^@BC>4DAh\=LKkuyE9<%%yI85c<p?1iu:N5wHRydn<Dp/wW1w&P^1y=N8D=dMb1h1tneG<9W
9BR5^a \Xn\*Dk/%SetP/%HuAd#SpmN91kkAw4=!Y6%e>6>q9\e&B/t:6RI<&\VCK8FTBBcAE!8MNyGG!*@!L<I
H%nE<9 ?E8+$KMVHXy%#V?N>T+?L=C\:DjIB&*q^?1p@d*H$HIAV$*1*AmyQMtQ<q<=Kb\G/d&N<HSuj^d!:>W4
*p#Xwd !a9>hNyY<eby^AuEHXDtRt#D8?n9hMGEji>??t:LBH:/BVwVmjRKjKtR5cHmZ#q%AXLKJCXLdID$YJJc
w%Z@<T B1Y<?R5XMRA!F>JH^FEjR$c:tcAXn<dGjVmA=u?CY>hlm??hY5=&NeD:eye!!kDHRA5J%jb9CNd%l=K9
hP^a>E letqBwin61aYQIn4J9tCjm9wBSbB\\IYF:kXm:iiTA6E=&RZuFSY$DHMHhjTq4lGLy:!/KP@y8RA@%jl
nnBj6n F@9iIFKpiN/IX#\5S6pCB*5p?n@@PSWV:pEkPIN%CL/RjYCeb<KJ>LMHh%SQVYda:qeHc4Za1uWb@SFJ
$6qw:E XlTK=6LH+B#>=hE6*i@tLG94Q!?wbnK#iI/jV6ycu4mwB<M&pjB5kwTKlIA?DwN5bpQ>:*RiQ&KV=4eF
AZl<K9 tlNiH/:P@MF9j?lZpE9!mW=#nc?61Kw^Ym:/jd@u!4<lXM$n#dJHt4<aFc<>^L^Q$l5k:#Ww%J>:8!w/
=kium? #iFM6b65%&B%VCq:Hi1D!k^&B&ltatd<1$/8MBq14B6pXDH=/WPFp5A?duhu4K+lHYL%Dt\hFZ4:d*qn
jEL+mK Z$/dycuWjuk$&aja%q*/ndLTtQD+mnQj?W/eYh$ePn8!qNp!Ii6%h6RM:y%&=hGIaN8@pHCqlZ+Vwbbe
F<l:h4 eEE?H$BG&M@KiTNI/&!BRduNqp44>hB>cu:k*8T^u\#*u1j5H%pY$L^FVju8H54Y1udd@RhCm6Vc9Tta
jQl+<1 uGp%1&y4L1w&?AYXtI^p*iai!Y:?m>#hMMRnquIB<bJam9CIyR&wP*9BWALJ8nnQ5Vw4QlJ:aknSeVK4
TN5%wX u<Vu+BuK19%V%JNS!kb<bHd9WA?/D*d>jjh#=cKwBN4%d#/@EVK6e$B<9=AANiM#%Y5\>ZabW>!%19PZ
:AblbB @G/KWcc4L/>I1wAW<:jQ1M/e*9jmt*RF<$FXZ@wBZEE@CbIh#yQ!Bii>l9cd4mdiCe<P9c!l9MaM$DQD
4HJiMF *?tcXt=9MA=q4BaaWZFaG8XwXtRTD85WBj&y=A=@V@6CGPN&@#uW$?6l@?q%yKjZj/LYM/CaRML>lVDG
>$XYB: QRK?SY/L%<<Qh<AQP5AHB58+AGCK^eSicIPe6Yb@Vu1aq9k<Eq=/IKZ!!i/bA/abh$Gd:=4\Nh=J/kYK
Wm:FAj B*JI*HFF*aG$dEau9neJ/eWkuB&Y1P\@TtL?YidMX#PFjTEjt$5X!DT>BhkLKSwnR4p>nhC=dTcPFB+d
Q^LIK6 bbkw1+bM:W=NH:?e!bA=$$iVKNHwIkD#*ypyY4u\VHMyR@uFlFR8VlkNm$<HJH9AIP+E$Bh:SQ%d+CZH
#BHHL6 YmiQ1NeZI>c<m#JSK$Wd48nq\D&ekF=m\PjQXQCdX%aCWVeW+^<^TXTmI+n4VdJm:ShHn!@#Kq+h\bZ9
TBIhkD qX$XCH5k^wHmE%+\pe9FH1u^DulbcpS=&wM#FLmpTG4E+lWXLN=4ld=V8X\hWtPcVJd/>F^G4Qd@^VMD
w6inP! Lw5FP4wmY9H$ut<L<CX<WS%V%CWGQcTAJkVVP5:>e&Ah$tSkK#TL4lKpKAeCKINwn<i?djEakE!<tlJq
&RaWkJ u?u!#Kjj@:P=S*9t$$!W1RiaRRAL\t:^u15\C*AW\m:Z@>Sk4$q5G\+bRGmtnw%Dm5Ee$e/PjpRCM\lB
B1#E>C :QbGaCTIVT%ELETKCT%jA&i@DS=B/mVA%?KjlSNMAF<WdKw$qR9+5nyLCKmGkLjA$ZBClRp+<H$96TaH
TN<TdD Ya$QtP?D@FAZW9&QR8=%6IK=cukFNpA%C^G<@I%N>p^?*Ew\jwbu!q^/ie4EiQw<jkbmk%<DAikRee1I
QX<94P S&^S1<HKGi+ye^*+ZG?nRakIi6<Y#+@N\EZ$HiM=q?ku8ha&n&nFH4!d^MI\6D1CTMmR@ZaDZ^!%j$+<
e?p6=a HhRJ$p6R5@kkPAYGA=ly5nmeB59ee1PnK*kM@\kHMSil>Ak^tkJ$H%SkN:d^^PJdF6I<5\k*cClw<Fk^
1WnNH> jF?PGi45/e=RqK/Qd$VhWYc\Q!NCn:y:+mJ\J?jm<4Hm<hlIq:=%jY:ZFF8mcJecl=%+PDX@y5eWJLk?
$p8k4K J&hN*hCk=dbCw6<FAFwlQR\mVM6!d<PKlTVTe$n\QamFKpk4\4aT^D&+bAQJQNLn&:1I48?VDQuwlwB$
#nSFKu Z#RdFh6:et8?JNZ\FHSSE5n<A<h?V\I:uIyNGJC$5C\&i%B:mYw&Hcab#ecc:F/pI^S$lW&J*QW\q5T*
5b*CFG i/WV%A4m1hhqn$w\F#WZ>^X5FcjmDFK:ym5&R1GB8wJ^MLa:ISCM+QPJJJ<+wBI+FWDAPcNQRCqIC@GL
N*qXHA Kq$kS#A=8ZV?Z@9jDhPZatk>1FR<q#G!6Qd<V*i1TuX=58^Wy=DJQhjP!I&AmSdIjTAD%!m4W8CL9MBW
CVnm4Z pkXDaVBCCG1&q=c>S5RB+n=eMXmekumq=e>E5/8$$VMF%+CZAG15b<^KAey\BL$wAPM<D@9A@b4j/F+<
!#8%1Y F?+?%^AP$eAmtp>LP\y$CK%y$5uVDp9yV?==%WFmMA!@>KQpNDVZ?*V#kJd=nckSV%<$R9h!DFPey^FQ
te\?>p ZTnDw%pEcGjBC:TFG^W:!&%w1bj/%6<LJkBGmMM^=Hu1LmG8plD1@jWjQyh1:DP^ciwC:DldDShB\JYV
tjH\R% jtZ\GY#pF+!SNEQ8ARip$LtnK#$eMmM#NWIM8Alyu!CBJGGmm^IQZ*i>q?Lm45WW#mYjReGGXu^d1+V+
6WY+b= mV+l+RMiTkwA*Mjm5>lV\Y<AynCq9PV^iNe&@5Y/n=&F?l5*&>QjyJj:&<ZV*#mAMuTik=q?:eY/^:$y
>Bj/\j tW%$*D?$lY1=qpmK>!Y@m45d=!+kMmNZ>nD8=DHCl><XVnRYSFZn1:wlhbZ$8:WmWq+N$%bRB1SIk\y5
DhTq$E cYIlXdL>>/K=XDXQCH5yl9$RE8NLCHww8eRQdcC9S*HJ@ppnIQ>?KqkWh9WnZ&bbwe1H84KCwN=:=INA
m8GY:H 8//*>DRp@q$j^&&H%PXA>u%F5YSE<Zujdy/#&1nJaP\en#kQ?k<<mQhM8dGw/Xu!8TmVh:\uPkh*B<!j
4B^YTZ +\+&PT?LPZ>&nLj&W=!ekqJ\EbA%X$\iCKbBW?py/9y?/l^*!ceX46wui\dZJX&R?hFun<t?ymykdNA%
^/4C?E tTFM>!\MeKkG$e<QcRAlH\*nc1#4LM=1B#k8P!in#N#B1:J/+w\Wq4De$JTCeG4#KK+yT$cjhS#$/pht
ic9^ht DYLBEZK<d&E+=F@yDm@i>?9lcjB<jG*!1*M>R*9lQ<FICS/jBM+kNBFA!p>XT=!JuyP%8Chk?%^*d^@C
N4nC^= lIe@^P8$p#CN%=Cp\KZEa6tm/ZcE/+u$4YbZZ<qIZ:1YK@VVHbA#V9/S4QTiLQWQ&YF9$CIimN4A?cd=
Ra&=#T ?lBy%iT=h!WdwA$J9*<l>&cILCEw%/>b<qAq9=@VCIuCdbCuS<nXajL^i5llK?Q!KG/JDDK4i4HWkhXT
IZiK+L ZR!pEn4V<?VcpRucHSGVY4/JGnqa%kd9MdM&?N>/HZ+GJ:BdhC9+!Y<X:q5n$L5DlWk/8Y5tX@YXH\u@
ab$CdZ >I$8#14<!*jXMdky+EhIQnwLL!DXD6K8lbDyD/q?pnC9mm+y@Jyu<qbIqK%kPWn>+n*^bMAL9t=H&^ka
hJbYMR *8Vlc>^@jD&JH4:mDHpLEX?bJ#>^mY/8mm!d:Y41aP6Q6!YLmHlB?#c&liPuG8E!ueACRwR\k1*AqWqN
hj+XWa &Z=$/hqD^NCBb<QwEc$^!^J>19W\CD@pawNjDZFNH8G\Gi^GtLH5T>4dX88M+T8YQ=H*Jbmninq^tjaG
+bFmF^ !hWGt<%weSBna#K6hqPX!dLEaHcRu%DMk>Dp48N%NQFYZ#I>kQIn/tP<IJEHKj9T$j+n+VK>uQ>y8TVB
^$jeqc tcDI>X4W?hhNet=B&DLyCADd6<Tp\pL<^IqQ1QFd=TP+N8>KPLt6E%$Qjcln1dJ#K\Q/\wF/$Z1chh=u
dTZZT$ HjG>qJDk?\k?VmGpC^Y6Y:$+Xpy&ad:qRLZ\cI%!CXR^h+1Bj\A&5SPlqN9Cd8@u:TJC9jZ/@1@I^8@e
jTYBw% ImMKA+1w!Tt?n<<GkTl<c!=YSGi:th!GIey/bjKWnY5Cj9:M/?6>+cMC+!dP@h6:Dd>P>BTM/M#8qw&j
b*@q:N hmV!/##X=B*l\+q%E<1X*:Mn/yY?Z!l!wR$RC1kl>pLtqQ>pnlw#1QD^Y>+t!D/H!iZumeyc<#qI^N@l
p:cQe> @eE%Q48GJaaVY&Gi#Y+5q^y1:\WBTA&E4p!plb81LH<ELV^Id#4cPai*\SK9&BZendQil#IX9N?+&I!5
t\?*5S jdAEWn8L86<^LMhZVP@6\XeybeT@\cq8A!nwlMb?=pIQc4=F9I!chS=IlnQ$ZI\j6LwFey>BaNb=n9%m
XmTT!: Xu!$$B*5?X!qi*/BTNCLylw^bPFFRZ#$SNm1enup>@@hhGZc8qPb&d$E!m8humIMa+mFeVji<l$i+yI6
PENMJ< \iG$d!Fl*/WZwe9&lZtGMwh%uduYcVT9JWi@YhGF9y>#9#Hw%E:yWdmA&XPcQbe:Bd?\Gb8$E!u6K8ab
A&T&Xe %P/Z8dSRCdyA#TPjj%b^S99eENCJ:tRKHbQNEpQlqV?ptbD?>#B\Jb@*V1hQKt>:#/ac@mwStJZ\ANtN
hK!dAG 4PpSejBQXR9X^KwCR^4qpA=9>GbmII?IElMlW%jRyeA<kPu8W^VATIHM4%5%?<%N=SiSVETWDyJ^kS^I
MKdpAG /ICEImd<cCH18ZP^b>p?kT@6hEtiue+JWIbiTPE:D%8wY<REGh+wSi&nJ$4a+q4e5ZLd%dK?:SiVdF4S
Xb%FA% <+yDCDBlWLKpI@14Zal^QZ@\*4ZKLN>:piyq*#F%EX/lwdAFT9!<@=KSMLQIXKM*tR%&e:&keEDuJCd$
-AuG9W 0002c10171d00110333 Page 470 of binaries1.zip
e%wQ<w cQ<+t>%1c#jcIb&uGBF!eu*ZcP$R&YcDnh<bXcZyPB?I#T%d<AC?LqdWI9y=5!RHL!hKd8md=8DaQVEp
1!6>l/ B<hWq!^B?T/K?Z!\nK+GYmjb>PJaZ5dMt+Q^1V^XJ#M%6YLj4+Eb:1BMpddkY64Sp#qAX6m@9V<P=1XI
LykVad j<l6WI!Xc+cK^kWeE+T!An9KGwMQWL/8QuJ1$M*Xe<D<^H*Hi:D&<!pd1RW/>W?R>aZWJ?5Vn5BIkA@?
@VR<j^ b*lmyAXWEu#54tq+EKFNQA<8uRiq=%%?ae9Bj1V=uwmt$+qkd1wu?ADZyX9t<Xbq8en4\iqLZc9HNm#J
=TG:DJ h*tHEQ&kGqCqDcZm9i5H%X/?lL\aHlnZKT%:5k*km:+4+lIT#mhE?Ca<WI>XFH&wC6NJ/em1%@cI+M@h
V&B&SV tB6ktSmbl&B@F^i*JZF1t$%QqK&bKKpB%X?#=pBm&I?hjLn=%5CqT&G!$!+aJluNn9%SbumNj?>EBB&=
Wctpmu h&B@&llA*FYIuqeTil*jJHAkYyZy1F:@Gck&YC4c9Pe8H%4MH>wZGDbjj9BYeJuukZM/ZHZ8e4eu@SN\
@?S>@1 wi961BqY1VAAJk?&yjk/aEdWVY$/bF!D<k:IIX?eL#<A/RCmMCVQA*b9IAI4qmNRJpbMpy<quL*6JALH
&>D:bR l$8#hV9J##IiEj>/:Z^^9!t1KH$F<iL1=i:j*$^&lyj&<#:dNKFAb:ZEG+?E/WIk5R=CDX<V4Dt\JYa6
*e@jDS <WHywEGK8AV1!<iB?V!=BX/L+=KT+wu&t$k^@XE*TL$?dJD@yMC65aE?8+yCNcRR\=Pd@yBkGB!LySq1
SA%lHS G<l1Rc#GIp@w8>a%#Ljjn9b=E?mI#aZ*k<tDwRH99^@m>D1ntK!#c6MtkjF?k&XNV$P*/\+\S?kL+\QQ
Zy9T>? 1cR\#1+#Pt4N1SyyTJ+SVMSh!Gwl^AWKcp&VDGcpG\PIJQbVyN!L6?ERcBaRGlAP/Wk$ASD&YaEpR!Rp
dy=S*I t$IA6\GjRlYjILhBQL&QmIlM8a=ImkBamHKFpcKdQ+X584t/wbTk*VeH<mAj$mekAcGAGASQn\aXCMG@
T=CmDe n<AyjA^b+t>+%A8a5i?Wu\!ktkG6AwI\eP=<>KYWi*MYwLyBQw>+G@B4pPc?BAIuSLI6E9L/n&AyyN:I
aVLyM< REIhTmGnR/#N*R*++l^Al/>u%?JGjTPi*WSNdDmEtypnZwt&tFnj@q!8aSLjEnI#nZc>iGnL5XK9^uGi
+IeV>i E$GLA&^mH$uGk?M/jn4MVHiRnkVYcwG?MEJAP=!=jm6Lj$jqEa<Z8Tba$PkD+&S<FaclVGw&>8F!QRGS
dN$#\A tC@H\CH*mRF=4K8lN+eE!/Y5%d*/EHI\e/&PaQGh$K<qSbF\*ZG+A9bjVLC#PhFuI==W^$*GIqa<ibaD
C&@>M5 \1+J8i&ACMEZP5NuAK:18JRNMBaEIewkLX<BA*<C#?AXGN5\q&A!mB%@I8Xc5cGbPL1bRDCpBi@hHhHA
Y^XCa: YM\jR>VB^C<<a4/AjCuG1K6H#PN$MQe\$9!SE6RM*$4$THue4uZa+Chim!WQhjYN\^eGNke*4$+lw$pE
KGESk1 ka?KAb>mHYkcn@<Tb>YLJmdn1K:A6!pBqHV>eDTwlutk*G1yNFZX&1ZGm1@IIpN=8hXXW&QF#<Ad/EWY
bbLJt6 DTRbNDN5kK<lT!?VC$cStaaKML=Y6N:ATG:@lHB8JTEJe5l4Ve+RkupLb6Jb\FadJqD@pFD@L@\c<mGh
=9^n@i YD+nylNTFJpLnYH6aX?R5bDw8y!p1Fp?:NlM!YyIui&W@D<XhS*1&P6j8yZRS<D*WX9Hk!H\=bRA/>8+
$>5d<p P!JjDw9*JbdMTD?YBJw&AjHRC8F*FJnu9j^emHIJBZ#ucaD+*MEhe*dQ*1X6%>w?4%yu:Nh8/GjDb%#G
w$\^hM 6a?#%jy9?Gu/>Qdy88j>@KS$<TECn9P#\Em/B/&nLuGF*BI/TEeMmGAV8*uC5ZEn\YiHQaP+nunJGyZ5
G$c<6@ GeVQD89S#9M%AWb%QEQGX*#iF!4$B*1JX#@qpX*!45^lSjtKH\*%GW:N@<wh$XwqkbKW*A!ZZAWc1JRh
\!9YDH pB/&Fla49d:t9kZMt8%Ta4H$A8R@Sa4&51=Tm8<iT%G:HXJA4TClXu!KF9d#+c4ENp\Zd%\+:64=<a\4
b+Z%QE #&PKh!*hV5!d\X*y1=1c6IhV/i+eQ9FHYEBy$*lL*/nT:+DQ*#ZJAy5MPp>jJ#8mF\bSX%/dNP#ynIDC
6YDuR& =%ymHC#aV<*Nk8bCk6dBTRR=emSBjA<#IEN8%FFEDQRiA:!Aq<B6<Y/lPpEy<eW<ku<dE8@PlZ#LS<Sk
pi\pwL ^yVpDhb4*ekHl?#kHwQ!4#*eDH$=:C:F\$&WLwD?*^BkkT*b5$HHjI&t?K19*R:=&^L>:i<Q85Rdn>JF
hH&d/p mmkXq+kZF$CMc?d>nc=a!c:5Y\NpH/dI*kNbWQGJLB?/$tRn1EJb\cbPt@CJCCqZ&SLyC%Y\5QN!Hq::
\1EEXL S=y%&wiEK?m#E*$6D&S$?$Clkl>!Yed69SWbXW\F#8Fk>@p!KcK#cMa+wSR!%&DlQ^$cpun8GDh9>nei
TAVtmF !Q\N<ZLARVhQ\AHP\H^LpGD=i1K#iM\H4\Deh9D=N&+h%+e1CL><>CS&YwG8cHKLSFEl$bKpE*JeSqIc
X@qQRG Pw\C9X%1Q^>Kj<qLyu88YZc&P<Gh?B$TlkyI<kippkyIL!DaTMn$pkLPTVSIq<JuWA>ZLahb*K@9+pjS
@<Z\#t FKR#dBeTq8&GZD!WWn%akpQAc6Z<1YEu+h<Gjk4<w+k4?KDWXTQ:GSKu^*CQn$D1!>WeV*+GB$lc:5L^
&QCJ:M pFu/AE4BcTJ@IVjc\C8i\>pW<FItAKk>D^eR>>=*4Y%l8wAn56#N*uT*\ZL?$Lj?>:chAhRFNGQQALCX
cm8jD$ uZYYXh?Y6WK?<q6CV*$Dmd1kd?Rh<q*$BGPiFH#4+it^@@C$8+iuPMP=w+muA#+mPw9Q^5RGN5\\5PDd
JG6*&X D5QyEmHTqZ@lHbjmcD4hMFM==kLI^:S/Ii/K=FF^Eet%C^t8&8M#:k>>puGB?*6a=&>9w%@8kQnj:ij+
98yyDk V+Zp&+p*8GP*n^t/Bj=#>Dd<w5y?>QdS&\:!/G$yWSeV@pKD\qY#+JnH<P6/&jDd\#QZYbVPnnmBaF/&
e@J9nC iQkKK$?+LWB@#H*+/m&=:1*j^taZ+8bPRDS\CdDp8Jm/G4\6@?Gn>S5@yl?M>?aHT\bM>Bu?RiBItBND
kt%=VE MNT9ke9&B#K*mE<DE!CukMR:NC@l:YeD4$HmnB^!K::$9\/b<T9*TBjuk<SEJV%1Y<CIPmn+KN?X>apQ
dFhF\N ?9CNQCXS5!%PEDnd#^IFeX:BHkueDatkFWTuQ1:G*wB?e:u*$L9Dqj\MyYJMQZ8KiB#$E%JNab/yyRa@
kmCha\ /5H$mYKk4<L<&NjeX&GG^Ma\X6WG/Y6bQmFRSb^jy!PhER/d<d^qXWT5$Teb%t^S*kVyI&KbcEk@81de
8itNEF T8RF+?etSPJ8a%+kHuWwp*@V8Z@@TB=@!!?8#Gk&Gd$1Z+?t/4b$41t%XJ8e>it1w=iyiTC8$Ga*%Z!l
%+V9iE =J=K^qbDcybF6dXVtC&JwD/n!tc4/CVI?J=5WJZZYyIWqY@qHW=S<aZNQ6G??J!aQ/\EkueI$#>>mB\!
#cXI4< WBu9jmSNey&^#GEmuYjm8u9PJPFSYHVCa<D#?+<BL>Xn\F8EB6e1d!ZA6Pkp#?E<QPDk<^MhW=Q9J\*9
ekqtyk h$@#ZuVmLw<KJ^K%6lIh%?pQWn+@9dWlka*cC/u:MWp*@AVi><ik&I185LALXH@nV*#CKZ*q^H6dqYtD
F@PaJ: 59XFSipD58P*M#V=&kKtGjIL+P\SJNRpekw\q&M*65AJN45^99dXl>&GN84WSJjkkB<tql+lapN:i*S*
u8NSpJ *LB*Y#%4:5F@HGa>Qcw@#tD<Vp1AlZNVQCGF8MY@8Fw:yFlQqc^:#\56e:Z+5qiA#/!KNI*jhTVH>%X>
I%STT# wQ$ka/6$TB>IdN>i=:P9WF$T+D>&uS4jtpRnPZbHYhI>TJZcmY&GZH$%bJcH=4RtwGY:mDp8G^5jLYlT
FDnXCY QZhe@aIJ9@thb%jbBX:cXZy=tw@TBeC*EcA8X?jb*I*jIV/j?M/>1<R^WZE@9@NKn8jK=nh^Km+SljZY
1:*h^$ Lp^V*Au/E\nEb\hB9p9RGe+1ZZ4A%6cB?QCc^/SAjy8uIj$>aGEywMS#5GJD<65RYBl%pkCZ$lI>T=+H
KV^eRk 1NC4/BYNc$?:@%!n#ljnnDcIN?cklD9wFaP%aq1h9j<KZ:N?k@>J!AC&i+@=RS9PKjlYPQt5+6pc6X+N
R?%V%R %$H/q>u?Z4Z:GPM#ypRu*@TVXY9!ZPD&KmcGc^<wPkI4ZC5&#Ye@%/WM*VVl=*6BZ#S?MPHK4bW@Ha#4
\QXhc= F\C$HAHym:CEQ1lmj1eLPR=!=G9i4Lmdh#!LD=FcBW=/JF#p!\G/9V*hZaZThhNQIVEP@BkDaq@*bI<J
6!nhmD Enjn&=N8l%!pJpETh!8yXI89FMSPe+BLVuih/pmP$R#hHQML6/+LQ!YXWH6j$4#jqZ@@t:=*IN*pS\Z%
>ReHd> HBytk!YZi!=kYt5+ZhAG/F\Dm#n9EWHWyuT\/FdAjn=bN4qa?*YV5lLT8^yIiH\%wYG4J!yuZ?1uP!F:
e9QL!! HSJ9X+XL^kKNV=yHjH?Lc6>*!4P+K@?#8Q6+F9e?%Lyj@d<uRDWSpb:5GW*eY@DZKZe5Xe&haAu1q9k\
@N8C54 9J>SAm+Dj9%iVJ$CS59&=/kmd1Qj!?8$Edh>YQF>GHeA48N6pH=eH*\lHXKD&ca@IL+%DdlkP?T%pN=P
y8JClQ LZ9eJby@V<M!R:=ZVNp*ZhZdT&t<dd^h!:>aF*<BXFZIce>$nQ?Q&d&9^#!MM*mhIRB^YL!*XL#HADh9
wLHwj= $Gt*S&Z/9hup*R#^YaKJtITukPlSPRDH#d##ceS$1$>CyuJI%*\Xq=NyDijI!d>J#pHtE8TBkwRSA$!V
HGtj\1 nBtYZ?TuIbP<NGT8>?elS=Td\TN<K\kk65Emk<XyE5yNNwNVIa%BilDA4whJyu^LqeN&VpPjn>hM#u#K
JhR\8a FNFcTP#bIHyRSDp/CEEQMPCMy+P>!Je:&M@VRb!lCcEDRF&Cd:%\w8AiAPebN?S/LI&=inGP%T+WQjd+
FI%%18 Jp1e*A@N/tl<k9/1@M5Xb^>G=6>M?Z1aWj:Y1aDeV+I*wZX&hPkl9@ZQI=t*:19XyEkNF^FJy\$%%ll4
l9uy=j !w#ADw@CS1mAaC=5lZpPw^pa!:G4*AHBFG\<QIhXVcSW=WM9<jq?L//\\?VGk++tIBAe/qJn*d?:+D:w
*L?KhP *@AecJlK:ZDQ$:B\#iCRP*6&LDkj!/cAy5/ApIKGYHAeNlPMu8pBF<D1YaCRY?HwJyAQjbTw!1/\CjLh
DC%DQ= mRbA:ea*TK<kb4Dj8y>\mlyAhnAQQ<6AcHbJ*!ecYCeR#\^e?jdP&ceh*qwKNF^=Z@:?p9Y1$8tDh@pa
aJb9a& Ap4HN4:=c=R\F%\ydJ=?6!%bWH$P6FK?b1Z?Fp\8MkJLBXa81W6AC^Py*!D#C8JBAw!B%D^cA:kNtq*E
RDmH5\ G=AT^Ii5>AVM1#Nm\GD?KKT+JBaR5%AKJGIA%n?A&+1HFiyDtFuHWYM:y5N9+PZywQhMB=#BVyKAGHty
kZ4HeE q#8/R8!lnCR:EMaCa9!Cp<V!T?Kna#+T4*$Rm*lGIqnq15wKY&6+4mtD+DHEB#%wRk4XC5AZ\6P\<EQa
tIB45d BL1EQ@MlZb\jKIHBi6IZF4yk^=N\ppBPKP!4A@#54q=miIlY>Dtn>u^Iil1?+V<LNj*FtS&W\WiKG9/1
N5wRc< +Tdp=5L<XI<q%w:L@+Fiw1=yJ:Q5y:1*cEW:X#=iE=/THVEE+c+*^pyh!@+K8>=?9X%>ZjCqjkTFZyJY
LBM@RD TB?B:CaTutWI6C+Fbm!p#4>LLpGc\b>JBLMLnwXT=wAW6EKKl@JF<NEICZ/kEb%FeG?Pq+VDT$l#i4M#
-AV#hl 0003215098500110333 Page 471 of binaries1.zip
P\8$!< &#yP\5$cI=plA=H+VM#F^%:4C<IcIZjjTLcGb81=M!VpujMIEDaH*IHE&G^RCEGi*Xlq5Fia@a$P^$HJ
cl^aeK Y9#<QLJ6FI69Fca?=<>KT5etk=<pi1S**8wF\9H6muG8GwPq%tAP?q:T5XtL/^1#+BZeV%FtJ@$uRDDD
WcjVLY k%^\lt\b?uQ1nq6d\GJQbM@4W4In1myAY94PbjXh6WS<=86YjFyVmwb@MwZVK^D!I+hIqu^l+#n!^HBP
NY8IWj C&hD@u*CX$4ZR?IT=AaP:m8>6FQKj@?X>Ekn4QlETt&BB*cECe^wTQ?:p/PV$m8pVCEC=P&SQkDThbA@
M1:Cba Auu!hCLmLFiNBPatkGR<NRH/ENi8eW<H/LdBF8y*<6\iknmG>KSBw+G$M?lGEV<hI!l\GuL?cDiDGXqB
/?I$RP ptyICBp5\%/B#F?Q$GKHyE<1@<JJn98&phJ*#PFW!wj+/5y/LaaZ+nLBQe6&!Wl^l8\qC$/8*hkV9J%J
PJLGwW *Q8E+5q9Z$jKJJLJVKEQ=B/&WiMLKH4JA<n:lim+qX=l**=NpjCMN:emDB#^C48H:^mi$IP<BF8T:Wbu
dBJ6WE 4j&jVu<A54i9LM>ptYR\C!b5haK!bmk@EARwYX@QG6mIYkBt!n^4+NnLIC:V5=JS8kBaTIJ8t:6:Ju<&
4jDWh^ Yn*kW^u8GFLD&?+?%+#jLR4Fit^4\at+RBT+l>cB>M+H>@D9pRmm#di9J$RHF!/AutuV>#??4m#Q6MEb
q1Gb+1 C8TImi%m%cKNDlN8hMEPu11l4K@/l$/jaLQeQA\Z^BI8iWj1c>Sa:=8uZ49@&9%XFT$L:<HAk/FicZQ8
H%Q*BF 9TXF/Hd!PDl%!d$q%=:^T*\w>aGqQlP<Fn5:WCY&JDZmy5&Ti#m#@YWVXLcHM:Qp1KPQcBJ$ZN<m&lHF
ypw\ea ?LeCXBB<:G+Fp!*9tu$8Z1jhKq+mTHVRBcNS8e:+*L5k8F+lB?/XhF@@6YRJbNd5pZ>>#+5e@d$eu?Hm
!%<@K/ qmbip^@9Q4HVQC4jH#kBj$:&/I:peSEXCnu=9>BbJ><BtR9Eb=&\5R>PBW8\>ZTEnyi5!8H1yNhl\?1>
1IHEw> c#$QDMMNEy64E/%X8%#Hd?h5Ym%e&h<t>KkaeYY$@AIA$/yLK+aueQP4#/5DA&\Dj>mSWbSe&8:+LZ9#
lmH9+9 bG:wp1X!=yZb@n*Z?J?h5eS@PjTHZFqVK8CiRD9pJ&nS6yD5Cb9D9a6VkA:?pi^@pF^@D=KLW=BAn8@I
wQ@uST ==dEiaLteQ6AmaL5CD:>p@c/eGYJXw!S!$A$SJJ!JW=%AnBaQt9>nCd/qGSQFlRYlJH\@Pti8+l/^A68
ARchRN I4\Hew%lqHJBJ@4=Xa4W?^G^pK:^b8tSi#a4YlNBC\Z<hPN=9=dGAPE<^??CqYl9&=+w1D<La&4VL<aT
MttL9p J!G^?$lk58hJiTWIW+E$yYhCjQYjjY/Ab:9AGW:kT@?bX:y+IAX8dyY!yYM!QHu<SAFikhyK#\NH^SKa
$ItCD9 B#m@5DjGhX1#6F5Ru$V?4JA!I#iV8*CRlI1/P$iyBNl?JuCXpQ4mXb1TAB\:SJSDPu#yi@^jWL+\/EW5
F??Gp1 XbWT+^KXy:G6L<hT=ZlcLtbak%+e/NuFI:F\+:8w!I=k@^dquP5wEY1^<X=WKeWmLqYH!E1uL#Kht4+C
GuJl*@ MdEJRQw=t/6KjJ64IG*y>iWZ9%Mm1T#=F#K=#eRn:1!T9FL4%^NGhX\/@mJYF%WEYqYiTjLbj&I4e#%6
=EF@&6 dpYbSkCGBNVbLy+\Lh^1<FnqumTLXP#A/&ilhm^\Q!&tFVh#BCwTlbY*8+4j:l!qj9!M>n?ta4ytuAAj
YYAM6M lQ5hcKe8$teQ/FM>6uFMdAt8yWP6/9K!YnZR$:AqKJ%6SKB#T/cw#14FY\hRW%wa55N\XMkEy%<@t!tG
:G4DF4 CiKLcHAJkE8ImQbV=XLq:1L\>mXl%b$?b:JGh1WKnnFd$R=je=1li$Jt91p^pA?1a/Vl8muM+<$%IbIj
1:=h6j A+ulK8F4b+S4L6dQ8h!LaSH:a?<wh5Had^X$#5Q!Vy9JY&Hp%h89BK^I?T%h^C*mkT4ew1@WH9F/!*Pd
<N1Lkp ^t^G%uGjyhk*uMH8VXaDw8<#yp9ZeMJupumHl#l4eK8jwbiwee^Tq#&/&eN>w/NwReXqC#Vpm!h5pjc$
FRC5X= BQH11AbB9D41cY>C9eSQ!>Vjq#MZ!JJDK4X>p6H8pM9WHW?^FR?Va9wLEBH^\Q%k$G6\?=^+q9jVhq$W
Mmbqi# ?A1MI9LFW>Bmj*BXy#Sp^#tVlYD$\udm1*k@Q?%^TQTcPV$$T*#M:Q@B%=jASXX>Ah@:qnu#B6+\n?G^
8kcdd4 \\!4CAkI:4kM+A+1kyJd!kCDwMQT#PCY&wm++SL8bGttb8cYT=cbFb1ct8F8btX1Xtbt8J8cj9i?ajnZ
NC^ybX >@6?u@\Ghh/>===*q:Qh5?mYGNA4:56mCnhD%\#:LQ4%dJNHknGRq8c=+bYcnY\Xnw4CCm9pSdcYuh!#
1YmpSk Q:\8@?YFb/:Z#iQp:$F$QlhN\y>EWLkh+!e\m&ewIZ\%Tm+IA9a#HVuNFK&i?A*Q:*9htSac@IyyyX>Y
WyyLT= ti=K=PELZQZp\HPkLw=+\ytEDByP#QG<4k*Dl*WW^:hNSmpJ:h1%V?nRETX$:NSbKc!nqBGk8KJ8pkI+
@L%E@Z EH&P#bPd9tkd+th\!Lp9k5:Fi^abj+5LMtXZ&B\RYYtCG8#hJZ+WmJYn=c@HMn*FkIGijK!95a^u+uhF
H9KkiE K#FETy1C#\nWQW=JaVXw4uy$1c=>D?@8VKjEE:@=q\>hl$6M866*wp@eWquji#j?jMkLH%\ZF6w9Sc<8
!9KwCb l?ID$j^HICeZXZu^9Y<qB$VSP&yEK^B$p<kSmjCt1LcnhZM>Z4u#edLBn#N59iXdC9\BGLHknJV:1Why
C6i=G\ ktPXFy@9BAh9+ZP9hLkRnt+l#e>9cZwi<V@5hy#dR*BDN:^h<!qG51WuYpZh\?F?l1nB\VeL55YJFmMH
6\lTIR 6/Xw:hn<SS$ZVIiXTYPa&aGcJe+&NIM8FCTGJW:*\TCFw^E/PXL+E5q:nut1kd@>*t>pT%<IqicjM?/a
p!9/YI H+DMm5lP+&4JYQ*$#j9mh@d/:@hmIyMn&4aXuujT%14qV&+Aj4c8^<*w68h<*??p*kn*d\Y$qE8qiNIV
!L=c!C w:lK!B/MTyNi4<qJVHZuAimuJ^P#Vi?t8@j=j>HhLDeX&iapDS=pMPnn!RwyXPJ$KhA4?8dV>ww//:j4
qNqKBJ 9$>GY/m\SCWnCuK?D?QTW+&S#5:59E<?:FmaP:t<5IV5=QLTKWT^c*6D8^a1I?LH!iJ9HAn*R9p:eB\F
G1Gc#S <QyDcEXM9teNaNQ:IA$FKVu5h#ZI5YXciV*I+$1<Qb>qePhYS+:%iNbtTQ:#pJklmYq=uJIJcy>!c$dV
MZ&qyN lSIEQE%IES%R^HdpjBW#YIe>PQRuuSj5+?#Xjj\LLVI/tjEyG+!41mPhtkwBw!V5:?#8W/uVlV6Xy4m*
1t:+@* Z\%<<eLA@*:5KmiQahpiY%5^@941@LQcWBBFPP@qI+??G%#:bwcwkmF!=TNQ*+ii6S&l$kt*IAi!kw#5
Qt+6mm @<Q@u$/Ly$tla&S/!GRN\<*jhp^nZE5i5e8=p!l4FF@$J&:G%*Yqn&44X:&R6Cna!YmVN1^!41Wl@DlM
p6iMG: b@LPq4T/BGh/W4aVw^kum*khH$6FRAQ8D8JALCL^IBcq+V&&KmW&1L?BPleeK6REV=RE<B+VLIBSX^AH
!Wkd?@ Iem6SCYE*I!%tep@:AkYRcwNYTbWnCeEEVmlc$imZ<pqkEbDI?\ALcA#<B#\R=BW<:PSyJP6\HjkaG+I
dmSbc6 p5eTSa+ynWbY!C!\FKMKt+X/qADm:=KqlqGkJ6Rt!ElVQ^F%#4Zcy1*\lQCP$dy^ZFACn/tMj$#l=GVT
wujL%N GGe/w$^SLB/%FMjimd*nl=&^b1Ma8#M<KV9&19Ri&GcG*RpLp&VA*Y/nL96Xh$B%S@ZKeiMi%J#lwGMc
EZ&@XD &SajE#lY/yEW5hE=>HnV<cdDD*aGQ%ke:k\>Zuew?&DP>b%QRB4!/b$Qt@CHy\/+WYBI4$pbnFMl&lE:
@H&J*@ Z45#c@P/$M*l>Mb>H6MhPjHTMGjcY<#u/iHP>PlQtk#!4DF4e9JNWA?l5LGREVRd!5P6qe\6pPhSX+pG
S>Z+a6 /uFDI@Q#X4eFjn@jp<qj\1VaLiXF?H*9hVS+IuGE&@H=a$VGQpMP+ZC/D!K1uhy^/#6ta&*%!A^XV5E+
5%@N?a N6myWp<4#EtyWML\1XJLEEZK5cZ/V:dS^<u6$SMXu8!I>t:dLIWZ&>QNhH*+j?5$A>\/DY$k>CMkeb>t
QM6Mj@ !^m%!#:IIN?<%JMKCk%K4EmC/JM:k/F%I1li>a1Tk=R<*w=/M1/kq1QB#t5uh*kqd&FHIl?bQiQh?=%\
%nt1K* <W*\pV<wa#eQ^WPIPn@wGG8FH\k*a@RV&RT*BbmP<pQQb1X$J9Wb+Y>&SkccHAZ>RZ=6y&@R%E8l!Few
QI<\b# c@>&Bnh$^tje+AXJ#!C&CnXYJa*C*akP=eCSbI9@DJl6lJ=a^+NR:@CS?#DuwMCL8@pKh%tQ9I*X!MmJ
6ccMFc @WD$tec6qcwBd$:!ictcM#p<EyBe6ySLIQ9$GHmJE:%wj5IBZD:\%bF\9C$n49qFX\IN\kFclYFcyNFw
Vqu@d\ ^P<BjnMM!Z*1cMDPHA=@ZcVV^RK@wmN%=#H@#GqwmdGIeik8Z5qRQ!FLaeWCY%HHyAcjeLn!J1QJCiGj
XDd9aJ yEu6*eV/B@1iWd%h<<Aj^4*V4u+IwlGR@BwIj+QlV>1\C6NmqtR!9Q5\Lu8HMed=B=P+b5t&hwn=E=%:
Fdw5aH &*kShEhA*4GT=@iASu!Vu*TiJ+ySp@CJLG*=kJjY\K@6JXTd!Iw?dCZ/FSlhPKL^u!5ACc>CSqFyedHS
kR>Ny! amQ$8\hda5+yW89E#c&SLWXqFh1aiI<&SPljmVaIbb@^<1RiiN\SYZZ/+:C918SZeSR\+:V=DhS?>$Qc
uR5F*% LqdPBKF^F$8$tCjW#c/VP?%WXG?!5@4*wc>JN8q9VM=9b?Ti+BVDRJ+MNyyM?bVl%iaTCMydHud&ee*J
ucRHkL Zcb^?X*X9ZYlh?TMw=LSdBJPM!DN$LVC#K<uXPWk#aVicaQCeBuI&&6XA?GYcuCc4:/V?^1bn9tQG>a1
a=aQ@/ qpujhiX68A*<::mHd!Hku1+EQ6R^+*AjktJSZ<b%JjR8C:8cVy<Y#w8hyLWLhj%Sy1Y<$GtdZPqw+/mw
YG#CpX cI6Hw$BZwBdiw+S1Wc5:?wiM5/S95#G^M&j5jA+JSlB/G!c/uX8K?mJ/<JmYAwkh?<#+qQj+JAN$M=4$
=JDm4q mYARNK*c1+6t<pJ9+FETQAd^b=CQL:\D>X%<?GTndk#uQeLd8#h/YT%5A/N+AIT*V4h1mS^bR5F*:?ht
YXH?w^ @Yj?HX<>$M*/8#6Jk??#GLRCw^$6jnpW1jH>tuHZ<::/<=kei:4#cLJnBimX@5*uXe<jtM*:HQ+L:\JJ
q$lDI? j%VN+dB#/1CWyI:J=B^>\WBeSqYT*XFSX1+!45XB5$KMJ@^$P+Aji/QX46t@1@EZV>qydJak%QD9VjA>
L4+Aac AeKND*#D49kLD\HjWePl5M=ePPD+>@SYYD8PSyLMqn%n&TE!nQZipT&a5wWlCMVdXB<XNaQ*/Y@eW8F*
$$/wT6 AC@bX!:\L:$pmL6<\TnpkPR^BZQkI**5C>1^8q$kHH\<WhlEbDWd8\b:*<B?5nqH<AXllycQA/pYmwue
GkeTJ/ Y4JG+Fjma!8M<yuqy\L&*9SP&?E6?J<ZpB\H@EVAe$69aHFG8w@@Lq$@uVS5LF^*\m>Cy/e/HW+PM:Ra
M8$nVC :<ppIw@M=yucw>LmQSjEa5M>^h8S#tb@My*QM%&QZ>/6Y94Llm8?%j^Wc>5ySB=THbR>mFTWJ86jIy4%
Mlj@y/ pyNew^Qwddtq1D!YcZjDiJ&BwD\L5p$G5RImP1BPTeqJGQB/BKqq=5KT$9I5m*&wi4^G?MZLS*WD^MYb
-A6A&l 000977729ff00110333 Page 472 of binaries1.zip
YuZ!Pa c9/K41i1BA?+ln>9cF8CyD=?&XdeWVYV?6eXYbDDam54LT?%H*YWFl+Mp%b@y8tu$>EmN9X1jdGqdmKI
w:hA!P ZTK\hD+6HA@!c*qHD+J@//^tBV*pVpmaal9=m!yVKNP%8YKhLw9#V=e*^D5>5Z<lb!P/I8+1<8QVX#KV
e8=&dB k4SIQA@XeZ6%@p\SCN&A!!#6^quKLPWPn:MiAA>*/BbBlGZHK%Xt/=:a:1c?*jIb>JNHCcSaT<9PqVw5
8=*#HY ?GJ99%cYyMhliH%eh@jXHeEJBR^\<:/D@:uAH8VtjdVB/kF1ek/V<E8Au!LRy%hMTudj+XHpWicAbu9\
LH&Lbm dZZTl>jdGSiBIeihNnkAKRAIB/T&6H91n:1jij1L=+XI4qNI:M%Num8mPud&nyR1M#Z<k>9?Qh^Y#5\B
q&W:WE =Gn?MMB>ND@:h=BV6l9SH!nwEaMaJK8&>qX@L&jACl!6?KtGK&YJ!XPjke*!?W/l=:Fj&#5S4bJH:=5S
+1SGQ= XR9wAAwAi1+H*Icw>Nnd9?GCe5JR?B\R?+L<Nb+mVkFlM$lj1eqJG5lyRiJNkQ>tkL?k?u#tZjYZ@qI:
qDS&/V +M?X?nmQk%kL<qi@lY!RtVqDBH8n#+19he#XIA=BTyuF*L?e>#@iAIXF9*mZ=>Nw#=KP:A\8A%XXXqy5
!VFJdm lYa:a*ppSqk4Jqy5j*jYCa>p?Sk*B4j%95jFnp<Qulpp@/%S<#t=9+iE5hIpj*YJte@h=LBXFQy9PKCL
+kTBVD !DMP/K@N!DGPMR1Q#mhJ5j^*^1@c!L=Fi8EyB^u>6YM4HGRQQIn8+$+!VijquWH8yS@&H%Q8aQjT$\c:
Znd%1Y 5y%pjn<Cju**RByaM:&yFT:DKN4p9p8k$*h%WDMquPA^a6EN9q6V&Ruy6HLhS8NpKBSu685I#@NI@@:<
nDAYtq 8RKRk&bycwa:beq:ES?ndTwNdiTV<84jePwa\JNLRDlTAa%9?6@E9hI19MRM\BNi>iID:&HjSYXi@bF\
c%D#Ib Fd#qcJ%+@&JACjCt>mB$k1KbZ6>jVhJqqFXM?CeqP&RQZ9HTc$qcZ@HnRL=5R+BtqEXe\kd*hie^9pyj
c:Ju4E @Wt&i*9q@>8@L5i>9en#jPThR&R<*A@%^$Kk1>#bZ4!D^>Fy:5I58\mWXPhk%?8h>QVNG*cui=NH6Q=d
>^B$Re h?\>HWaB$+1cD*@&@C9^%@:lCXPSmG=DZIFqdGq=%A%8ZNe<iie9:S5l*aE<N+ERn:KP6P*q6\Q19yBj
@lh8kl <\S=++#Lt4^*leS#TR9&luY+ew$bclL!DhQn4dAB#*4FV>4%5mh@PI#GMw<A?RmMEn=?#jPN!u1eWlnT
@A8YbX &i%ut+wIqyp=:yh?<b<w1F!*lbE&8EE9K@qBIH8ChE>y4yn^/W6M#Yp?WEb6>:j?VDRl\\Q!nl1qGDh=
C8dHyq >MwR^qY<\#nF&X<i&+=b+qZh>=%yM$Nu1y8<h@nEP4YD!REc^%#<NmcX*u4W&M4JtjpT5Be1Kcm!q@9b
n!a\1N I/Tq9p4G6\5MyKd#jp:jX\QC\TN6RN4K$GD\!B:Ac9Z1:N\luDdDM1tR5%dX^1ePND6K8a4!h%YyJSZY
GAm5FV $p%F=5q:Pd^X@dC@%lpPeYZtWm8uu9Gu=*!RZ+i5d\SX/yih%*Iy8SddBQ@TR55i>RIlDa4^NnYNbP1C
F5t/c* \PTXYVt&$u/P1$A&B&+q:tN+FGcI!C/yKLjkWKMHm6G*T?1Wn5>B=$/heJmtp!pq&TB9C1I&lcATl/NT
L$:*^I *!WSJiwuVy#I/M5QtW8:weTkAdZIpISTPuhwD!t>CX6Xb&4mMpy6lXbpRSBBL@cSGTI!4GcdGSimnDT@
Vdj*X@ mM:6p>V6&^q?CIQedJ8uyVIRNipMq+mee+i/1YZcLDy:ldYKp^DE^XScLhX!@ppVTNZBaEkyNF86B$I+
jbXEk5 /h=BR%h*^R&/eN8eR%!$dypZ$=WLenC%?%iNM6Hp$GltbujSqGtwB@HP++AFCJT<?E4tAd1pD+iaZB%Q
!FTuQ? ijXuW=6TVZ\*TK&$?ykh>Z\bW8p#56FRtw>QTV!kuI66R&kR6=Q&/p4NeE<ncyy1pDmWENFyD+i+H6H>
Fp1*4G lEB/RXQ:$TEy#%GTC>MGFmhmtk&X!DtF19+PB6W&=:J&Sh<4^RI!qWV*DpSaIe\F/VJX%jquMJ&R<I?k
wWXF4@ qyaaS+wun1IW$qHZPy6NpkNS:+FN/YlkEu<F9G8NBmZ94HI&LE:ZGXD5VjNR\d!tLmdhCeDtYWmMy^Zm
1TlI5b JB&Sq+yw$4=&4615>H!6ycetjId:jBHbGCW8RT!/Y/6XTya1=!6<But6yJqEqZ^P>X@lS^mS:Gb/N/n#
Xb%^$X +^AC\J%<wL8H%PC1X?CDiW\4yFTR\#cCHna/#yjXBJa4LGP8e\@ZZY1Hc65m*BFj&>q+@dTVWK>=Vlp>
$eFn^> %9ZFA6wEnSBWcdanB+\DiV*bS8@CSSB?lqGEt@%P>Lk/bCXmWaHFYqE?q4MWBTIq4^5T>wGeD<eBmS?D
P>9Rme iBkmT4LN=WZ&*5ncBV%lZ<PHpFKmWFD4\PFBDwRanKAEcpC8AyQ+QSHKZ4^MbI%Ki5Q6C!IC/lIYWXcK
J!$ZDX 4Ba:SJk4#Tad%T449d&^LlTEdSKYS=H%GtEA4$B+VIn:ca9^^qV$lw=*jkF^yiXFqqYI\:9&wpdAPRTu
K*l#M5 FR^+uaC+P48=&HIB!S6PI$*CeD!mBq$p>IN6Ru8SFtki6lmR@F?kEZ8N+8JbAd4QZthTCm9K=mFjm#jP
tW1hKM %a*Ibb=DJ%#CuALF+wCWRp?Ka^bhDLJaVtX4GQP*Jk6qk=%5wcRW6Q+5<j\VY5/m:?^\>XT!L1>K<#mu
ZNlpXX =!V9T!BNBW=a?I:J/5+uQ+LYI&VmY88I:y#aE6?t4N@+ti+N<@K@lb!l:k$#HyEGC&5ahIt>di#4*SLh
W6hYuq S9jRtyuNX%S>:<:Y+ddbllH8\uEW/8PbBL!4RC9u4J?VwRTTBV9XuTIG&ybGaK*jZwM\i!AVkZ5\nZ9C
Rm?DyM %E@k=kiTwy%q8Hu:GkIqqR!6%EG>!w/+tuFFHI:!l=8?>/dlbTbG!ZV\DtQnaG1/L5hhyQR^^SnX8A#a
dSbX8l ^l9l#4&SNjtuW$K+k&%qd?b9Z=?m*^mlC/mQRtT4eHEYnMDLhF*hWl5h:%mNY#Jb<S@JJM<6thAGEdMJ
6+cjF^ VSJK+IeRq8^eiZw:N<Gmp@YQ5<a%M^6bXj?Nb=PhBl1Bmm/SZ\4\mNtMe9FTce^&jl#QdJ4b*98Sj>@Z
ycMwlJ yQdZ:89*EkYy/WW/@uAdi\lX5ht^kJ*hjB=4?S?YC^HZ@QqGJ!95#jh8J&>i^j=\^=6lP+DVZ:uXc@!D
B4Eniy NXIbeM>::BQRVRHJEN$&q+GpC!DGZGW^>+SwY!wRSktSw/H/$EP&lPccN^quAjjlZbaGEPWk6V\A<bFp
WSd>6/ =&iTh=wEAk6!iqTw5Rd+\&P=lBmRj*mVlRe&wSkGlFt+8$5M*h!T?D@$9jJu8*jVH@?YcX=1Tea\t#El
Ee6p<a :X!!t@w=&:8V@Eak$t9=:Gc*tG=<l@6*y%WcqMVdI=X<DPVS:huN=HC//1PHh&<Y#Pk54+L:CDa@ni\:
E5^K4Z Cy4?VMj*e@pj&Qu+kZi/?\KIkp!c$<\=9qYN<ly$:<HhB+!XW/:5/XyS1Gn5HJh^unMcm=PXmK$6hc^Q
lKbDFc 1^N6>L&9MLy!9XJwV!t&q$ScHy4VnEk&:D6/4*<$LWEmq*tw=Q/ItwCpn\CjYTiwiDbZ64?We%:QYL@Y
q<nVlM >*hup/hDcie&a:RN!q?N89>ihPDZdIu<q1/cV=K1=SG\T@byKZFFB$N>=:4u>PC@T%\Ne<>y*:upuJ&c
%m6RRK #!B?J&/4=u<DS:I:C#KhcVSqd9NNa^S$nj1YEHHFX?yZit^y##d#tPdI$BnuN%9=n<@nRuXGdpYb^XG1
QZeR=c Lc6ZBi8@<yF>kM@b49hn+D:EGcZ6M*=YqaBeD4j?/PtMI&KW8dV<PGBwL?VCbeWuKBAmmm4KY#q$Z8B%
1MZkSI $\1bSM!wIlwANXpS6dt+4ZwDVCB:Ean!*BPpYYwR!Zb8/*d*yRmn$jPcZTE$/8kDD?1VqLJ/T4aimnDc
><AeK^ 1tCNy1A?R5$ZD+:iQb1<1#*QdN<66$TqWkC*=#ZQ>ZIl?$9^+i/lY+H@\B1%1=hCa^RTT\G%4TW$lud/
&\YjSN nJu$YZy>$GjXuTM*i&pGaS?RNeN4%Je:?cc+c$jey1MZ%d1IT>WDQqLdt6EGLFH^k/@l^wkM6%lPRd=Z
NAREa\ &<#yB&n!Dn?WQ<ud?4V8&5?R:nc#WTnw>%4GXRK8VyPnj9VEiZZdC1WpED$h:!H!MJt5dA\>GH9beW?c
/RT$^! n58dmDw*whSiYtC66pki5SAPX>/Xte&h@X1!eXPR=9ptF+wQXd+a*XFKDTtyFmu%V=:j9GPGWW8a$dt/
p%Tk5D L%P:Rd&1Pu&FQ!&lY5I/8SX#?Z#XDu?L?5/\q=Vm^%LNKQmeGiVH%@uHwpY\*/5=ZIl8W#PF=:HA9W$D
6bTt:Z tZ<^p8H8di4lJA%8LtSR6$4qDp8SCmpT*eu*qZTyD>+:!FdpG=T#Nq+^ZJAud=KQP!ZVBjdG=pCQ&TB>
#CGHj> TndMtZ&FWmhLB\:&%/I&uy\BlJYRG!mhmdWGJc^VK@=KhP+yhQVhAtW#dWiVQNdFqH$=Q/*X^hW^tFjS
wc6Q#! G!8q$ACq^eyIMR8X=dmEDuyYh@ud5R+6Vu4h!L?cMV<^wCZuP+W&$iq1mI:hE^KQ<dYJ4cp9VY8>KQ:p
mhQ9cK wc9hHh6mMw=bTPbt/$JKa6+m14>Kc6Q:CN?#6\4*nG=^dJ1+WJpb%&bbLuaTu@V1tbe<P1kew8?+5pn+
Pq*Mul K=t#TdP\Si=b99\jL>wSd9&JNnlc^^A^=XFueWYmi+uw^KQ5Sc+#BR&Quu8&MdyK!CuG%$ZW1&/S/+*c
bySi>G hNbY:u#!d8*#d#&J^CVHjmc6$hB*X?\iFMT9#8cYVt*w&5hQ%n#b%G4/^+y8T:&\KBmW<D4n16N$Wn8*
MeV/y+ #>QP4?AH$H@beN>ql%9^i>5HKXZk1^RmSBw9yG*yB9j#89u/$>K^><Ptc@py5PJi4HVaSE8i\yuBu1K&
a%:wWI @KQwIlR%Tdu<ykua/SBI4HQhAu<#\T9Z8>Zn^#l+nPq#?G=Mp6A%N&mV^?Y8@ktlR\9F*wYyw<1D$Hc@
H#%j?j nKkq8pj6Nj#D46p+C@5Eh*EuicFI>Kq4ZwKHZ8Hq#/KcEpL!9eZ!keE6!d#FP4KYE?4w\jJE!PiBn!ZH
VuqjiT 4hGV9pmbh&yC/tpe&Gnb5KyTdt?8F#9%iu4@KTh9QcTh$h+Db<CKwB=H^Q@XDKjk@1q#!^5J*L<ny$c/
KHX9y5 9T=wk+jLGHJ&=Db8<#WhLHb^5?Z!pyiS9jSV1c^+Cn=V4N9p<Ruua6jnQ:m<9#@aqP>b<J8$@d&k8G!#
n8&H<a 4hVi#?8+h:!+k=bl&8/=HZ@!qhiTJVFhljN@mNLklERpu\SbIwL%K$d=Gq!@mK<p@KD?yLSVD>+#Znj$
SA5wT/ jF!<=*E@d/<4lt5lP>Sidh*EMbcMl@=^DVwRdYbZhe#jLk$bG/jWW/DViAKSl^qLtlh<K#6/>QQ/n=eI
N&QKSu @RbKR@1HKyNJ/RYFkJa9cdcL*YX*dZnij=GW8&YyyM4=6X&dVJyJkN+1K=D?hna*:Mq%9@L\?R*H4%!a
pE5RDb ^!Z98NL<ekhS!6+&bul5D#B&1ahch9^MbjjMR!:wcQJTbjiMRJ5+@jl:Z?>i<du>6phRaL<\NA?ZREwl
Vmw>&& 5qZa:bamEJjMQ^c66*pk+hu\pPk>SmPVLE>!Gq=&+@9*E4I9Lm!qcN\mqQ9P#cXTw?Gj5MGl/l$kbY4X
lG4ZeH eBh/Cn?jET@CbdXQBbc/Gwq\yPV1wBmRlX&4pPy*QZ?<&L*%nViEC!6%F>iHm?*uk6D#uk\y>nIQcqVa
q*HewE +/9N=>b?/B6YKDaB9uwqXD=#FMSl5wDnJ=u?$ZdIG8pVcM#@\*5HM^i!yJHLVHX^jNqq9^E/EK8aKt*G
-AJbkZ 00098b0d4be00110333 Page 473 of binaries1.zip
#aKDJ& @%J5k^MQAKI6jh6q$BKdq%1PPPeqDd9MVPQ$qX?*nXdhDAyCtcn?yd?S$^TalN+LGliWy6$h!By$\9e9
Zu?E8J i*Z5McG#ulq*Q$GS@SSqkL=:Cq48hwYc@8>cHKQeDCCFQM>@=TCS@XapDjiT$LD&dytd#AA1Yh=5\=Pk
#SinCJ ==uuPKXTtX:FQ+6&QL!<tbQ:\j/b6??\4?I8IL*$/9RNPHbRknn%T*q9P$E#RcX%?L8TI%ATR$Am%KHB
NG8^8* %T@EAb>u*9Yj?wecH!dj$/@y5ImXm1p8DWTqW&yVAbyA%E&mnABX+t#kD^^SI><Acbmmt*S&y/&tRCwc
K1IlJY @tWnmHVdCN\JM%y5BLm=+DQNN>hTKJ5m<B=1eItiS4ZS&d?Vnk1j1qWhWWyTLQC>\Kk+KFZ1849FPYY<
+aJd/X Z=RZGpJQRNjKJqTyC>SZJu&C?CFX4q1hFQy:yA$KP1AA:+&1t6=HJ&Cb9dKut!u?Rkeie/D=GF=HI/+*
De9Ey9 &a*B!BXRD!9!qaD/&!lGYpy::FF+CGq>q*^c>%Z8D5dnJqN>&BVuh4Dm/4aqSBe8kW^#qcQEXGE4uYIy
DFmXMa twEqb5kIbKXZ5aA!LMZFNJwCVdCAFeSAyAd?p#iqKhAJP5!N%H&AG>@DtcbF+CPQp@N*XGNFkKZ%\TmP
4BQY!4 KQKk+8ywyBK1@/hTB/ct4u/JpdAj**/TWpR^eaD:^TtGmP/^Hp4:ke/5Q>PW5kuyXGYPRGjHjc1Ew=6e
$:IETt bSM!cMLcidRtA4<VkScw<P!F\NBT&y+P9iYk&>%\A&L?=Y:+569heA6yJB5QM$l<6a=bBWn?yK*dY+&m
&a@dlD <5NBh$SC/H%uq:%G6Fe*nTqupp#w9wGGED!lnJ#CtH/INFVT/\+yeV:m!<LSXJ#A@Gb/djlZM=!1D=%+
j^pwEL ?IjI!aL8W?a&buphC<Ij%YkBnJcCYHE@GyME+qVC&%Q5JSWVT+iWn&*H44&P%m&SX8H&XLt4lFHRX@+B
d\quYN hYdq#h%b4BpZkl#4eB*Iqi<Mn<kH*HWW?:\>$qW!WNCi/H5+jZkZHRjmmM6+CS/91\jF6w9pI^Bl6bmL
mA&CJe 9P*LYDqtum+dyP1j9MQF:qBMNn<VX!WqIQAK/6*ZXqG&$jREM6p!hqDTt$kLakBwyNn\PuAMDlePwWk+
Sjh+M# X<ZIH@#FCywbSFl=HRLl<T\hW6IbHkEli!H\JyH#%ZPNcSMb*Bu\l/ZlYJ$D+n%GC<Ki>XG/Q>AV?KGX
mE/$w% 6GISa+:XZRV=VR$ikyaF@GQTw&?Ja9C@Ty#KAt\=%H^ZjAd:unp>&>8k8NJ&WC1Gppe!Yd/ZFLQZhGiq
S>>&%t I*I&t8%h+**qaXJn#X*#G8@*yB:*%>^h\=!aMV1eF5\Rk^ya=FC!D!lX:Cn\@wjh&\Rn>q@dbLS:t@Ru
Cd\1I5 R@mmw\!TLpK>ky!ZelNG9y=+8Fu=ZePEju$qnlBXm>5YTH9>RD:bXLDIaR6MD%BZJ!#^=p$i^l^b/+eM
lMS\*! Y$H/%p9?CZqBc4c6a1\6^q^tF*Z%*ny^Q*=Zyt1Vwp@TMYKQNE5+:@KPh^@I:cLph?Zc1?EkCtwRqttm
%VQa#K yiekM?u*=Q:8cqy$bMeScnKpW=M$%Vu/*wNH?wi>P4JjiM9lE%hF<mmw1\1%iL9FwmMMYp$?MjT&nXPy
qEGmh> 8N=9ed++Vbjay#qcp+Bn$QWnJljlc/P1ni4/!:N4DE/PaaZBuuC>XD@bY$kDEeXR+d!u8#+Ilaqm9qLI
HJ49Rw 4Rb6W@Zh%y9caqXhLZldB=1<B$Z<yu>5BM^t+6dNMbSKPMJ%$6H&XjN4*%HN#tnCGbZ!q!A>kK^q+NML
#n5^dj %SQchc1jVkp<W6/Dn4L41&a6Q^X!Fna64EM$lAcEDwCtKt1Q\9WIYQVuX<%</XZw#u:V>E*hY!C*M:VM
8WEd*9 ^!=E&9mTNa@PX%TaTY*VLC<wci4khkD/p#VIw49C^Vy%@\+@H>MTm*1WKpHH!hcbASKKdQHLwbCuHG%t
iq$h:T uG9=lG>?^9E/A^CmeybKF:VdnGPIWjR6a:6P#9ja%e9u6F@+4nS4Sk/?CIhA*nMTq*9HR^HY!9Z=iJY<
D*c>V\ RSn6I^XQ\twkWydFhh%5Wh8lcSyQyBiI8RW=%>RhM8F%FAQC/m9!9S@W%&B&hV!$$^$H@w8=@C*i<4h@
NXWJC^ b4LDu*$9clB<p&#$:aqEZ%+&\>4BSNwT^H:$<l9SwCD4bNn56ekb/N9D>^6btkt<il%E>k<\8dM6VKF9
FapQFK jiCac*+6@aYB=#e/9aeH>Be8<VtI!/p#$EPmcI5#nnZQV$y#FiS>Q>#6dd+Y#nNH\@Y$tlGei4?QYnnS
6*pGZ4 #n?<T>1EmRKnQVK*1=6G$^EKn45Q:>*@$Ql<>?E6IMD>p:+l\5549ptcjWSK/Pw&NNB^%^^9ZwTQIQ8n
@DLJ1G d#5ut+S!P>6SX/XZhHu1lK/M<N6^^qZGd1^t&NkuQpPVwYhR:tIAwiJ+JBG%ai1P\N:8G\\Cpy!Q4=8F
L^JT:= +B&c9B%QNFZm<F/uqPyVDVS%E!JNLyAYZb!8Wm\#9tu>%$juQ>uFBwX18CJG+@eL\pETA=tDKl&q?!9K
LLWWKt &*kjFib+B?1Y4ika/Ju6Hd8TTVIKct^1^XNZ+@yYQM:!W:IjDTa58%hbydXm55Xp5eeqwGYVBWYPG/5I
/WHwMT EGVI=BMEMS1T>LbH+>6QE:=9=@@!G$puNtR9$4#Z6@JyWE9Nyk8$<SnT8HY#l+G&^*E<N/BaTaPbRP>u
lL@@@m KTS@=#e8c<XjHl??#DSq:t<c@^pd=h?&64wl>61MaBH=LRw&y6m4C5dh%aAR@8^cdBdn%!bAdL#1H#RL
cqq<pe SP>%u6dpub=+G^yPW\LL^duHQiMRiIh=*Du8?Z!L\dijMCW$1PSQ%u>=wN*DS$ST=FZQN4wXaaS/y4t9
DGNINY yCtT\:>^K&J^@#H<tq8C$pmDnMacB6%l=wMaF/:BD=QV*NGJ@8Vl1t?cN<I&#dmHh>tPqW@ZWWPh511$
:V?B1A <>%9t8qFwdmALj^HN!#8yXJHTctt@EActlabX&ayW^hadF?K+eA9\J?GDHddHFayA#iV5W@Ftp@@cT$Q
+mNQjh E!@j<KthHq^QbLDZ>N1Z^I!V4V^D8:nNcHeS/VP6$Y$9GQwji$GB&%=AG>TjayD/Et\M>PDAt8!Pb<yA
ZpWIQL =NEHne&e/dSHjPD>JJQLE%@JiE^:@6uaVCeucW&VupeN>^Rum%$@etq!qAVV:1nHThe4m^>yq**$ZDhb
%4t1+/ ikYpc*Y?4Y$\Xhd4$IyRSu\y51WTPkXbj:J=q6SiP?LWL/VTVc6DZku!6EE&LaT?5i&p><Rh9HZRS4PB
y!PA4^ :1A*/C</TL*#FKPp549An$+JcVZ8@1QyM:YNa#B9@1QDSSBXYj1bE^kEq!C8*G!#TbH<e>naQqn5BnW<
kw6RTA @5Z4CGBVJ#TkNyk:F9>lpHRmAEwIX?\:9^%@DMa>!p>AIcGR1nWi#IwQpXCj4pqJpdElXwmIDLGQZ=!!
TENw&@ 1k$c%#ZYGn^R=+1?G?+=4mb+E4d+6F^t%BME9#@q*q?y@/uLXPniZ:VB&dPECWn9FadPkYH<S@HTYXX1
/1PTF# e@Cn5qC?#6M8eVJS1<wjhc9#FWPN1&\*ewFj%j^+V+#\#pe>WPj8+$IhS:^^6j<y\Qpk>nZBS\n\kw:1
JC>KYB jj\p4/=y+nmmuYLt?pGmuaaCun@4tCHSFMKAHJ\qG8WepN@%IiyAyMm*>yI/nyYX<8w$VMD*NKFu@tic
#%E#@c Hj1@=E86iS<>RbeYn>JbaY>9uhS*LEPIaY1q#YK*tMwLLaBuVYLc1WFKty:Eu+IQ#/eG>Dtl9<i1X&#Z
\$D#qq C9/e6QIZ?aS!Kayh4*Dhiebq&pqVbc%t&n&hhpZ1PC%J!t99SPqC*V>iZT%1B*tQ#VVCX6aFkLm+u!GQ
VVwq^# AYNEhy@5XwGMCa#CLbCtXHnI!S4<BWcHyEpRbFYZqw?jLcR/dGbn8d&5%HHb&ATS?CY4JP^j==qTlEyy
m91@H1 &uAH$XDWL$8Vy=lQJBGXDW%XC1HVA$=R!n@L8GRna:##Fa>9&9cJ::4q9T$klWGj6l8V9k&RX5MN!PbQ
CF9E!Y \+e9>^>S#8!:AeI<ZiCMy9Vm/K=i*w9%+eKDX%*SJ6Vq+V1BTBcewajFTNM<dJ4T\CP%$^N>H91V%!>u
V@V5j% n:CLQV/jn6G<IDSI*QPdX@F5#eF1#Y?M%\%d&:?>9CAnZ9h!mE9RwiR#H^FR98jeS@:wj+=<pj9I$\aC
\?XR&@ byH1$4d$L9bWh+WQm5bk=#uZ:nutASNd:@/p<!uDVmX4Bm%$RB+l=4^LeF9Nieb%C8>TGK4qB\+MM+!P
t*?GTK &//9>\qmB?tqqdk9$cqXnMmdjD:$EE%#k/#=RWVE@NHBRN9A+I$:uYtV\u$QQA&ucYmLwn9>pL\LHI#W
!jeZS4 IaDh=JEjE14IaWw6?<Fp9HR!uFLL&Vp!=Ht^9t<&95CI:^1G8m$9FB$mk4M8FZ?<5P9q=!?QH6Wi5/Nm
I/&:jP AC@>I/dhS#F<KB<j6jib*@@<@!qR&wi?MGyS>im*9cuR%l!h%A/=FQ4c@Wm=>Ae$$=ZFV=E&/jX$H9Cw
iGEdkX u?J4uijTX%t$twy>Lqt=^4t%e^N!<1m4mcb&Q$eL1mMc/TJt\X\EnhAPnqMK\+h1EDp!mW1qXEZXy%nR
<S<8M9 >XGpZ?M\=@T$Ptwc1F@%PqXZ1TK:hhkJNIHi@e+PX?8wIp9#Z5#D++^i!TBW$=#+XEt#qhN4aA<p^RAH
=BnII5 uHT1$LXStASP8i=We5G5JtQ%wk1LRyYY$XDAF8HH+lb?ilFpX88ASbh/X:b#G!MWDCiVZ/&W4S91:NyJ
b/Yd&d /wA11dhAG1=F!W/Dak6XSGEKaC@=KBi=Xy^nVd9i+LKTJIehR9ta=lYX\&nkpb?TJ1CN1+I>m==kp&66
I=kZ?* 6?ASH6&d8l9q:ny/=^6YlAu*$N>%MWh1b>>LZ/I4\:4p1#>^d&iV$?nu^^tT*<FB@T6K!^HSaKQJeXb5
lAXWCE BXTaiaLIAQNIn=nt/tB:%/S=*qy%AH%tQAFEK?D9\#KmM$9Mc%%hXRQB>*EV4kud9pnZ!=*KkA=I&CV4
iX###E 85Kb!lS=*jEKC%!pE/9LV:S6lP%kQc6V656V^jBIGqc^4C8Q+RHt$RSt/B$<FAj:GR4kCVC?6kIRiRSJ
:lH%\C CIlPX$@WDTjRqQ/m/n&heTWMk<Bh?R\\J:!V/K$QH#InL$!aDQ#ZcBmV4!Rh8eAE5?ql*wkBj8kjKMl8
n>wB?F eqk1AahMWZI^KnF<namk<DqBIadKdy*\mp=Z*<yjbjSiHMcKiY@4yG?BE+jP\LRi%#ZFTE?c=nk=XquG
jC1W6n Ghn*<F@G/kQLJwTJW^pm@&?cLL%*GEiT5:B=Ay5!*nK=e1/=%DcNjRI*+>up!?>n9LR>?\=8D=HTC#Zt
hV:pXn ::*N4tAa1EyLIX!l$t!%YV/MGM\ch1ZI#C^*chDQESu^Y#Jki&XSPntHL&%+!<t8%@NJ+iHTbTc!y>\N
AMyG9d ?*\ESdh$R^FId$IpA:jDa4$9A*=+qCXm#%IpMpFwGR1Qd<9Xk*hdVkytb#y@<P:yQq$=BHkRV:aXJYP4
:8GZV@ tKq+%VW<G</BHM8k1h^HRBRW!ZMY?Qpe%jX&%/CtCCE#:?1#:VJVh*tJPjL&AM+/T%h6JM!8A?Aq%=J^
yCd%qp 5b=!^qFWhA\mnYWXc%RtLyL>lJpb>jM<:*!wkab@I5QWM6+BX@b^8C=m#8CNlGQihZluk8I5n%@?uIpq
/8wVwa dDI^M@e^+EIeRJneatwWCS<*kK<BcT9:DJ\Kp?FQ@+ymS*#L:Q5X4S5a!h<b+PAdp+!9<5KDm/^!K^?4
XeL6W6 %NWpmPTwYFhTww95pI5@J<MRQu&6Lmp<Ji<qH%w$DL&4&CFIw^@JS<q$&E8XPjQih?%C+9$MS9duhQtl
tLNBAk JD8FGE:8@FVK!Km\I18q$EEN+>XSkV9mBqw5SZ=wia^*iT99#DlVcaW=E1@qY1=Y/Pl?\LyE%%P1<MIH
-AHB>b 000745ecd9b00110333 Page 474 of binaries1.zip
#i$1Nj atGWIdhh5J#p66DReXEjeG&#Pqwq>ZRW5&tKL%N$64*$K8ASBwZEK8$JKLTcjF!CcJc#aNd:E+w&?uac
#8wm@% a^&#eZa/&llh@cIHbKqtBeQ#?/wT:4eML<LCi:1bCl*pK8&6$L8F1u>j6^T:4%6wk%k6T@lBW%=Z6*=A
$dMKM$ ^\^^1lX/l>=W\hhld^/beey%1W4nwSTwC>R8e6XGy:/?@8H/9N5DwnIKp!4KHia>aY@J+5ihRN:>4n+/
Gq\tV6 jAIkMIyWWC!Q#Aepl+D\Ha+EX?WeBhERA8pE?dlK@<W:#\^<4i<<y%M>%:t*qV<:!j6>jwXBaV8W@>Bl
9@B\81 WdnA8mImi/D6Qbwc=qylCZlm>udSnL*/%5$*9\1uw&BjJw&dcP9qTB/?9GtwD96&yq^X+c\W$m/B4FmC
R6p/AW Iql8Q6Zpee4y<#j+9GHw::+!yADRM$F=*XZwZcG!$?P@J$1#\%QTc+eJ1\n6\y&/85*N8^By%$qDNmEN
:VNA&# M9$CMtK??E4Z5TP?+BnkLlSEIe*T5QqK??&Q86ZHNYSX$Byw9?TM<NMqkVm=%n@Xja6ERcEGnZIe^/G?
nQ\BWe /6F>H$Qj91M69h^bRtal<yD*aF$1/t=Nj8?@P\#4kj!j\+4Z59?M/Pw?HSRGT9NRAIYm9?/@&/Fj&p<Y
$M!H<\ yYR=Lb>NIcB6H51$VpH6QFnda%9JAjS$ZGQRnSpG66&n/HVjNDnccw%jyQRbq6:eFWC4<!CcGT9Nk:Cn
lXq4Q\ hy/En6GEFmPkdMTnEa>!QEb<i@DHEa?YI4:9mI=!\HW<dXwH?RhNy:hS=$Aq6u<J:W>HZEP/u1K4>pmI
+SlnC< 1uweJi\WJ\KiQq/wXGYeawd?mh4j>mmy%XY6<bC%H$:yC=d%kRy9y@aQPm1//8ucmK5Zi^bHQ8&j6:k*
JuYKDS u@KZEY@R$K&/TuG8Im%!Shb%>dSB$#:<d\:*Z=/hc4MWY4JLJ%n5T/L&1nTyB$=#^cY&Mu995F<Cp1h@
dyB*jC GT6>@:X^4&wLGKZdIM**>inmV9J$qew@C$W/4ChlHA?4HmLqXq4l6dpmijmd<9A6IqiJ&ZH/b#l<TbA^
IWE4Yt 1GhF8aYdiB?1d@YP+h5ScZ=\d:#bI/M=J:pCpB#F6R4q*i^S59qyWQdRIeJ<NPXQD=NdFKGA$Vk6&!#&
:?J#WA QkcEJuwlD9G?K5Xm+TyFyCWwGH\JYZc\S<ViHypkHREb:i@59wWm\/D%hCkq#buaM@JH*KEBDLT!Gd*j
=i1B?: W\c+:@S!HdIXYpeW4$yAKt%h/P$CuDQ=6Ahj6m6\@wei6dQ!wN*qkC:AD^/1&TBHH9PRWnSS@F5i14i?
E?WbEp nC5PpCcD9G>YnLHwJ=^H%Jei4Vj\C:yy^TEy?t<*JBm:kKCCXaIWm#\TpBkC+4%?=VybD9PWh:/1?=d@
NT?:NT ZN9lbAL@PhHPXwS&<VS:LuknnQj#NcwBu@ybm#5B4@15Hp&kFV:L!hF9\/1Z/T/B<FwSTD<F+49@<D:w
ZXJj5k M^Q%CbTKD/Qa9mDe4QKWau9BWBQkcyBcGXXQ$n:QF@1DhQmlpY<+Aj=KKhNL!Mm@DqJ6uhHq<lGyFJ\m
l46A8H 5=GwI>TRu4D6&4:du*9lkW/$G\^WSXRTmN\ue:WN/X\W$@k+&Nt=589<\S>w6Y^RMQ@<FdTB*qYadV1c
w@cnNj ac4EI=!weaNB6BcIG9D=9V=cZ8ZF>@@cPDN+Q5dS^4lCc+ZhWwS*lZb*^#@V$j@RNjMXkeqKiVE9ba\+
Z/jp&@ 8V&<Bh=Nwa1+w?Tj*pdchbBaq=&mD%Q>!w9pMc&dR8XQD/SHL+q@C=n:j&9Vt5<PBaktTk$8V9?*htZp
q4h$Q= #L>9H!8R*\iyW8/1$FyqV%N+nY/ab=pQ@*p^hW!/%Mt:GQBQ?k:m<bj>k*89c!PPGt\+c%C!j5%RVQCp
/ldhaH S/w*m!4yDq4\5NeH:/\XS#><J$wj8lDQMY8u1Gj*Y!&K/\\D^S*Q9bRiH!k!G?t&u*SVe4!9bMhaZ%k4
KXknAI Jme+=Detn8/Q+AG8/q:@>F=aIl8+4H8qKdnTwb9klcJB1AJjJTI:\&&\wWP@<Eb5M$9JeywTu:^Sm9$P
bKH?^/ /WabRj\ELk@&#uCL$@6y8*R>dj5lNWH%6n%J4@SKV?L+X8qJGi=+9SeE+m!u*kX^F5yL*@NpX1ZQLFPH
H%Q/Eu YWwd=Ww8HbHuS@ZNk5XS%Q@^p/PX96JSW!9aFKlZ!6#T&tG#TA6W:KPIAJ9SX8&BZ&jQXaX=Sa8w4M^m
X8d/mw K!\%Y\W>L<X6C!14NJe#ydhX?VScYhD<ptXwueRjB&FKuKSd:CuZ5eZ#R!NALee#5\ZbBkKcA>KZIG/G
DhZLQ/ jQ+ppbt/!kMGQniQ<?pC?Q9*It8kJiVuKMZ#Zb>tuuGR:@=h=qiQ=waIX:*=Ia@$?cm=yC^FEjF!5<cJ
jljRpA Xdi:N%*SjSX!A5ViH?#V##cIW=Gu:>+TpH+\/h5<ny1e@ITD:T@=DFY!JXJbm@Rj+Y#8d%cN*4Ctca^^
W:ZA$T a18&Zq8DjcL^d9<LIA\A?R9+SH$tic9QELj4IS%^P?%G>?XnL>>>Ejj@ZCH6>V%DTNluIN\FwS<\w*QZ
BSFCH@ >t&?%EInTN8He4Q&yAF4WJ<:/4CI8yB^tkEkGbeAj^6qcwSW*Fh8*Z^ZkddLCwF$$X16Y9YtmZt4etSm
n\y#qn !!*@R@J<FQJ6%lZSn/TVpl#EX1%T!kC:499J<?^L/YVJ6V$cBBEhAGFqi*ePKEy?$YJjF$YAP+@G?1bW
H&ZpeF G41:h\46mp:/8qBP@BM<eu>?<HQ:XV?*X?=B1MQHaq?C1cj!WwT4^1t9qN^6HS:ebwLl+JIT*Ak&mGXY
lpT#6^ BH6MW>WaJ1#\EL/DRE>+9DR\T@Qj?H</BAYmaNQH:b6J9<$%@W@@L*j4@>hS<+X?5@:9lj&It41XcQBm
KW@:?Y A&4&FTAc6>TDPkn$hJ6mQBGB6bKm8pqS/ZN/N/HiPlSI!&IAZ%5Dw:MRhSuL$KFC6:<dHj/J1bt1%KIL
GCcIH8 6W$bSmc+X9ee1C!HeBd!w+u8udkLmJ>D:XypIpw\A!h$y6+/w1CKBebe6?GXnw\GyDW4yu?mbZ<&dVTG
MZw%D8 dESHndAI^QhKpDkm&i<lEme>S*u=%Pi<6%5Tw\k5VY5t1!bebL1D@#acZB+M@F8/bjZPAe&iZk4<K$:Z
1ut$!k IGk&*n^*h61X&Vm@^+#\Hnn<@nP$AwwYa8q\98LElcZlPyeaV/*yhAnWkY\Vq@?D$Zu\\FqJed:NSI%l
&Qe+^N uQ#>iRVmAdmG1E6GCiC8k$@l=:B8CNb1pSmPSl6Z\j%4W55>&=W$<6iahHw<jKkR1^y/K4Hqaah$<6he
T:LTuD =TGSVGKca9=*Z$t:wJ*y4tQFD*dYD<=9PR/$^!Xu<:PaJn#FJX:RQ:THS+bdm%n<u<nFW4e6q#aau$Fk
mX:Z*E WhyBp<Ekim!Wd%#iAA:u@hk\XI%&iD>t?JmQkZ9kQjebI>C/km8WPqh4X^N><dI&^h?AjPRNZ8!N5CT<
lWaJIk LAmVnYy!W&A/!JaM6@*tQaw=qZ4T$G!XIqC/HBSII&@Wl+w?IP+Z<qn?SnYY%uX!M*MFy=<#YFi<>>8w
=8!!mt :^y>B%RZYL<YwYNlHZaaFFbELcDKTEW>Kd$9R8kC?\4?>q=hlFbHW?SeyGpG5\$IN9@5:dmFnp4ZM\d/
C@KXA+ LjJBHPV^D*Y^BmV&lYGImmweni+jGJdA:CQ$PBVLAYwRQ9XqS:tVnqFMWENQ%:dc>lJ*+1Z:8plb%&/$
&tc#?5 4pki#uW1+V1<R9dC>Da#&d#^ZB\u&%nqLy>GyBj%JAnG>1JhHWV\=^:89t?N*M$ql?*&wRZhE%PiR/Te
PkpBN! jyZl&YKJ>%&BT4DK8GmClC*cJH#By%n^BpC8\i6/Nb?BEQ=b!AQ?R6HSWH+hPGAWWpy8:AbjPWI&hGM/
#bke6X hR*Ql1^=nWk+<bE?AmcpS!41wGI\yyk\9RuDy=91A*b4&^$ySdlV?^Mk9\dSWCN<QFQ8DMLnPtaW*&M?
EA4FcC d$@!nA\jmu!y=#&6&9p4j$/@Zw4/uLyG<Q6+/*c=Scet!KG8#6/8KZ4Al+a@iDB8/Ie?N&RqkjBKJc5^
BLuJ!R teS*i:M8B:hEXiK\8?tYk6c1@BkmJec4>1Y1y1M\p/wiyQhRL^$MpZ1Nqn@=ll6%mq?L%!Z%hL5jhCWR
JXRLlF j8@hQBQ%1wL/l^+9DbX/chXXLYiIDwK<?:nPCb9@+W66E*8/uR=IX*Lp?:lb^mV5+ldw/S!Xm?VSR=NH
lj?R6+ uy61?:JI/ycNF\X$=MXBL+ZNWTqcYnjpkw&Y>GFhZ8#>8Ttd#*by54w!>hLAF&WA&q<lT5a<=%Mtde/G
tTmt48 */:+Q$?1=Genq/5QSkQuDaRZ?1EhJi\JW9ZmX^m1W9&\lWPyXbXFbphyii#aZ?Zm5@#hHS#PSbBm5=SX
m\*NKu VDDuYS8=A<bFIe#wVD@tI>k1ZYnX/ewyYaX8y\RLZWN%W@\?>>5B8Q>tD*Y5wIb^tnDb8/Tj#86TXCWH
#?Jkpd <Y4akh/lJ6qe\bhHKFl8qpty\Z%JH#J>Z@h%c!%BK8R/66pLXaw6YJtd4^Fy<P=ARwuW\M@Q4i95%wHy
4mTG\V ?!K8u+8YmF@\w\*uP==!=XmqlIHCSd*:KedwK<ma=E^@>NkeF6:iW=!5:Zkyc1R:QJyCRP?+&1HXcimn
#m=cqd #u?ubX>9J:*!IPbD1i+/6?lD>Sj\!qtYL?$+6Z%$b:h%kpK?lMk9Jd6RTdS#aEPj/%:6@t=@ku$de6B>
y9RQ&e $DGR1FnwFjh1PpBKj<La/Cnu$by9@n/jQiiWME<+LD$B?eBJwZdn/1SZGnkdmH$E@FZ$RHhS*p8p++#?
??54Hh bQ9SnkuaGj%Eu#D+tmChjF9aCQ\TS:SGXA*4FNSFB5ZK1kT>$wFmM5qkdbZ><eH1l>QMm@<WVpDQ>Y1=
$SW=dV aw5/cp49&P=liNJ5#YbIL@e#qwQ$I/?VtX\Q+$+E9B$m?hi?q+XANYJk4bKN/%l+?%6w$mnRdPZ>=YHG
\Q8J:B K^Cp/&&#FP%Z5wA4W$B\JBJKynKNZXAEp^j$NCIuTZMJq8F6aS+d@@TYZ8FmFGP%w6XT>HbSFGujSq#T
a<$>dV iPi1ZCQ%6<S5BF#&a&9t@4h+8F9!w%A>5p!8Fh4G:H99*cjde5b1yNGcPP9tX#6$&yETG:l=tpeT$<Xh
6J&l?> WYFZJnZ1b>HFIXJTKbNXiui1:+=i*<Ww:yTKMPXBu1:Qcq+RE@6=y&it*Gpjhtu<NY1Fd6tPn!$hY!5:
u@BbA$ 1cQm6EQc@WKlWZ/B&SZ^?C#jW:#1wh8y?WNHBN$8iHL4F1bJkYwH5QpKMZn/aL8t!q*//^eKb?aAFtZR
X9dL#m S/@!^!M@?5&#chM:4<@nnVQP?+u6LbY#ABi?mA\R:@j$\k<mS+H\qSjE+cj6\NACu<BGY=$DZMVtnae+
pLmGl+ !+NijHcpJqeKi?yA5qiW#ISeSWAH+e9ij8lp=n5iZbDZ\cmwQS@LY#ZlkN?M?qk<6MJjtHIn5^cPuwLK
WkLRkK 5+I<:nP?IEA?!Yj>&D@le6VITk8!qXaWqScc4VZY!ZhCywK\iqk+:pqV+NL!mP9MKT^k$G8u@AH\8idh
\NlbH% wRbjpcblWINwn\q6Ia%dB%AmQLCbNC==%M8#9V6%>%S/yki/GjhAtlGBEpW%EpFSGBZGjap$twEYEMdh
*DEI:m 4>qq#Fe^%=K9aSD48yl9>IlQ?IP/nLX!#^H6qWAiN:nCJp=qQS&JZmTY8R66$==9DmJN/ZX:lNQwVGd^
kK?1BY \&1+k+\iKBS:*QVAkVQE1ElW8<4y@+9YlGu1K=%p1l:!k6H1R4Z=L*I>@$GGmA^#qh%mRKt=Fha1S&pF
+c@YNF Kne<c$/cwR!?My8MRG?RI8ynuE8b5m9BbWTCZ#in*Bn5HPjM^6//MB5Kh?dQYJw$\<t\Wep9Zlk\EZIq
hFVSbb tq%cck<wKDi#X#d\@h:1eaLVJ9nwpjVPd@FGMR?pqSM>?H=L&?n/DlFjZNLkyV@GS<yq55l9?DMe%<Wq
-A9/J^ 0005ab0944a00110333 Page 475 of binaries1.zip
H$/?a> 4<&KG#Aw/h19dJ#=m6%ibdMak4eF@5M11VAqGc:#b?XJ!\JyQJ/XZnc@TbD>DA%tFV6X^KVb#8?iNyZP
$n#>@# ?Cj+CR1$P6e>1dTtBj>65wdFwR^#iZpFEcCaHRjEDJ9qqTwLb*j5b5VykDiGHR!yA@\N+/X*NFSWRIT>
#?=I:C :A?twe*BE\HpkAk*Duw@FhF^TCtwKm/&FNu5IAwV5+J?C9S6B#u4QR<cA%BKSIHbu^$Qe9Gh\AFiA^EY
VYwWHD >+H$ManbS\HQmk8NHh@bq>D@PV>/$4SXy@St?@l9DHM1R^I1+%VcSw?AYQ:J9mAq/>1uqQ*V1b?TR>?I
+u!eI+ HL\wQBG@jnj1nuQ#*Km4N=i5G*hcP*C=:H5mpQQH+$!iHGR+cSuKNlZq#%qbH4!>C^hdElkPX#::\@Qk
5\bMbe $PC?ct%!Yc8Z&lymS$!Qnk*VhypaVHN^we>y6NSkMp=1Ll&HWLX4iN4?yt6*Ay$*F%&:?uD@qZ*ZQjjZ
5n4Jtc LiLSTE6=Ie*EM:Kl1eGbR*/6*hiRhF%^W5FWLmb+GwaRGHR94&hc4d?:@t:kM1hy@VX8@SL?u!bA@EGw
AJF*>m lqV:bL!cKT56VD\B@N:XwJ/aMy9y/dEwQkR9n!mB\4JTi?FcyZ4YTLdw8=Ac@NRcRM*4e5KZZi8GiSYC
p:lq=% YDW^J\!htk9u$HZ??VZ>!\bP#A5PFYkNF:wN/H9EPIi/65Ee69iMPjjt*A6$b5*=ij8M?<5!?6H//bt?
wh$##e S6kL?Q8q16SCXFFYWFy8KWye?\\!#I/H1LJiL&cw\1PDV5FKmHDWVT\66Fl#JiM<X4W*L*/6D=H1B5I#
=9j4WW u1>66>QueNiw@GM?>TqYejA1*?W?%&dyd$XP?8R6X6dqy*\PQbPYXR6w4=L<6%a^V=D=PVZW=MK6nyQZ
+H1tZX n:6Zh#@RYXB*jj<@!+*mGJC1ytn+<jNYk6B*5@AeKwi&H^h<MGT$&55lJ?$$yKI?quKL#i!\:I\%LIeq
\+VpIk Eb1@DK8?MTl^IpH$9McR%#/SS<aayiTe:6nyRceHMaHPDy%?$ZS/N:hCX#ni+8nB%AAj*Aj1tKuJ5j:%
En@/y& j4nLnSjmw1:yCeYn%Ql>I6b@*iRuD\K:&tbyW$dLM=ji5ye5DF*J>J88t5%*X4N9J!#qK&$Xlbcm5knj
9qEaD/ J#te9?bCK?PT$PNPmCk&q%46Y??/CtV>wZm#EI^TuITYW+#c1d:XQlne:tGke$G:Z>Z6Xy^w<=G1eKZj
?FVA&^ 8%JND+F9b\S>WbZq6t<lSA1uk$GeHy%*F*!ENmeD@S9q<>Aqdd<HS$QMe!NP+D=EqSS9$qeq\BZCVBl?
@NE5y& CRMEeaSH\ZPwB^H>ANVVpTMdd\QpEj%#NhHHLqLh@yJ!icJ<CAS^lt5>WMS5=^5aESyK66Ehiy>FmCn>
Y9m#Q6 Hke1GRMn=^JK11I=AmYhbyPWnYptVP#DPb>HtKwJnjici\KEtTkYSyHGPcCFk!BMIWP8bTBnWCYm/%bc
c5VCX? WR+w^X!kFKT5DqyAMAD^VwwJ6$ayqptXyVaLW@TiL4Xu^eS!K/w\F$EnyBant<W!pXd/SjICw9Q4C/y!
B5Bj^A J58Id/ZX#TY/GHQuP>$#h+%FPlqChjQ??k+NnYc?c@18!Vu88!9JM<K?Y%5JjM=A4C?a5aT\j:+We^d5
Vd&$Lj nK5$$%*^6RuX\*VFCGL!BjpdiQ^Wl>i?D*\y&w&i>$BL9dJuT*n16$mc5^+9p*!9w8q4JiHd:jlAtm=8
JWdPKY epXX1#>%9bA@A\Z?8l=pLYR$EAly6V51VDSYFEd@l4F/DXTiq=V/cW%W%CZVnu/yh8G/<D!?i9:PiWJ$
abCne8 8y?@Y4*9@M=K!IPTjPch*aQ9k6Btu<=@IVdSVRBFJR#8?#9ptd*q+DnEYh1m+!qI9LtT&a%VhIS+&Qek
m4j4In tpdkAp\=lKeR4V5l@H5<Au$Wju%#PqRLX:H+@5:1D>#=C\W!QFw&$+XDu&?quZh**k%$F8&<hm65=/:y
V@yqLK YP^!1T&@yl*5Z=/?@!C#HGP^*!PhCD<byRW@Ja%EQT81C1!YNwWN%6LC<XA:#:5VE5K\$DXjV@iYWkCi
t9\&pw 9l@K4&q?!Z^&hj/>jEKMF8Z@4Lti9*9FGIb@AD##SR<eWYb&FJc$N:I4bl86PSulylIaI8!+w*>YkjN:
B?hCy% 5WEwI!$:F+K!B8p!M1F&1jeVpDSdkw\bd?E&n5tX5Sc4jpY9hqu^Q5je%%dLblKT*uyYM$tQ=<4m:<eV
4hyX<L T1QJmd??Qj:Dipm^tpwLdGdd=Fa?Wq$SmQNQ5tJ<+JCpcTC>CNl^\Ij*S%AHpkZEi#lIV%liWaZF:m^9
y<E@&8 =RD=BJ4Ktm8=\TB&:+&YM<?J1KS:+QMVHjpYe4$6W5>8j8WH*HeQ:n<kI&>?eJ*JCjyRPkHZRNC6BHu>
<5Le?6 iRb*Jch%I+\DQJ\ehNpR9u%X&nQAhh<BVq*G!^WJ89+Z%@DYXdIeFK89ckBcijyJq/SVacpDI<:\*d=1
njE=61 Z/nL<8Hum@h>w65c:iFKFn6c$JC?N#4nS8Ee@@P=B?eiBDw4#@&Tnm=j5RI@jtiEwP%:q@tG?:!ZFeTe
%*<YW* <!Y141@LW==#JShak>Hn?4L%<9TdDm&IlNlLn&n>q+FTkPp=4Q5#TWt=SY@*/C8mtnuKIIFwnTy1#eM%
yQIn+k lLLqnX*#/+/<Vc<IDTi+:lHCBj*M*k/jmBjJSaHbG/K<V^A6yQMMXaSq$nB#wiNN:qQ$9n$/n@?N9=u6
^^M$Q9 h>bhubXm@yJ#4k9>dPl>N96S>1NAb*u&d$b&\w4MKEK@t$A//F*M</?C5YMjL&TcDSqnLiW9?XXWE5$4
8?>5:y >::*D/kZP!Q5I>%LIBT%%+un<EP@&!A?INRw9XedQ=wHcct9tQQVWJ$DJhe%SQn@=E+pXpNaJ8w\4=tN
j#KC!L S/l@muke<Vm\k#QBQ&K9/p^DNI5LVVR6Cu@!S=A%*^=1XjphIXJC=FVI5^#Jn+:X=^hH5bPJmQN%H%W+
FLjkii BBZ94dJc#Z=Z%e8qp5Z<Yk/E:mlL%@*%<C#^^:hXwyH@tkpRKhiP\QRCuL^#St*#&I#RJ?a^<*hkP&eh
By@@8# <@6N=w*LhTpX\!w6=b9>w8Ddc@tm4i/cCehG6t4HbdCy^5KKKt9SEb>\KI:41FN%F8ZY?qn%<w:jSH:d
II$ekS il+W?9yH^$!\IFD8SM5h+Xa>ZkDD@nD!&<Lt^kljR4*ieqGym6Gt6N#8WJ86%9cqDWy5J4W/p6qA:Q#t
bJ!dSq *iTqYi#%^P6JwHPC%<*aK%/4Lq#tT6S!A%!K?e9@lKVS#N4*I4J6\K@=peb6E*C:EeJwYB!6p:<D1!yA
@a8a>k &w5&Ae?i/YL>WdQ9bCAcTm6hW4JN**paWR:1/AkuNc?!J=?$Q9uE8jZp#j5Q*wkd/qq89ku>QMRhIQcj
y*ba<d @1%<V6NcCymn!WAXnlKLdYKyHXpkk#Bpl!Y><IKG1P5F\@&8L:#diylB9W5w1=nR^#lEdL$65QY#91u#
muuFaj 5iW:VSADtuYn$VL@\ELh+t:Wj/Wd^5WVlIDu^iK>E5%#:\^#+hbC!@DYk\JLutN@ZhC88:NmJW8*RBZ#
iIbM/: \+L<+aF//C>\M/KPS^L>@AeldD%XpulFWTJ#NGMBay56\VXPnT/ab6q>Eai11%<MTuY46jSX$j+Fdu9J
:8Q4&8 JjI@cmyB$SIw6bAXi\q=:pRn/%nEy^=RI%yp!=4mN5uQwAD?Y9A@n:WeS*AHFF>ZZ+ViC9J1Y&uR$Y6i
Y>5BL* tnJ+Q>Y=Zm^mqW6E/ycbyn1=58=MpC1d*tN::nAt/X=+mZ<+k#aD*nEZ?MnRpDb5W@@YdI?R6\pZ8\n<
LaLMB* X&1RD5\IPkVC!*jPEKd81habpwcKB%V4a9tk=?A<*?F#i+^*NeeIM=*Ty&Cj<SbdWXbtKT>/Hl>wD^I#
eY*m8< +>MQpYa48KA8bTJ@mKk8cmR#8<TWmwIJ#6KKK1JCdBnktS+d=eGjA&EnL&tcjtk:/L:ue\kcQ:i$!C/K
E46tdN ejdKiDVnh=\wq+H$XbW+q+NeG!Imc&Y*i+PFV*VCI/@Yq+Y*9YhA$BRW1w%dHuTNpa?m>*c4!@I@aIXZ
A&n=R= 8&udPaJ4Ni@KZ@iM!m\1*a5mK<y*B<lF9/knm4iYq5>BJeK:$:Z?l*XP1Sn$E$5t9/yqX5V1>+LaG?JR
YE=*\@ kaYti\A=%G?JNqd*nN5kTF>CJJ:*h1\\d#\K515L#iY:6WEFFSZy+!?JeeZtMpHK4H!q15LSI&%^1/?M
HZpbpE mayQ$ncF9JCq&QA/&%IWb&RGF?/%=IWZj6jM&@bb14WVjNnY&Pq:juyIWn9Ay\d=@k=&mFtBw:+Ra%?S
NY&yjF ?K!!^RE^>b/HeYb1hlGj!=Rj\bb!P>H5G/!RanhQZmDPqS4E<bB1Ld&PVkb/^?*WYi\m%>ahkpm*AV4@
8y=MXq 8tL1M6Lc#9/nDBMa=/dcjj8/XHjJ<&Jt@5EwRamn*KW<NmDT8m*bk$Ph4p^p!XMnXM^Wqwa:#Pc#hE:W
tM^\dM pQGNNm\?#bRXp=>ZbhZ+F#Cq%cnWat<Xu^RVu>?KRc*@T8@wSZdTY+t^dq5CSWHb&aw9V%65m8m\AI$!
wtG:5@ /k&Juh!%56wm<ulyuj8E1Gk\8XwEqP\DTKtt4F^S$Ad>q4KIp*CKZ6QYuX/AkpcH/ywNmljayA6uE$^k
Lh@K$Q wKZ!$Aq!LydYEVTYLtFSF!4XG6Phd@Du%t<=e8?eFM8EnQ6HLZj#Ymeul/+D^*TD$MuAqwRYlIwt!Cm$
jnuhY@ Dc51LH&pK9X<6+%8Ln9a\/cBpXRnSI+K?&T:\%ItC1%Zj^cWnFLKK!cEq+:pcjZTDGG6EcRwGHiX9\Rw
lVIm$K \%=XXtc&qb1tYHAp*L:uhjq#PBD^qDttGSQq=VZ8utGd=Qu?a6N>:^EVncN#PA*@t4Cc<=I#Ch?cYN%P
9HeK&* Q:dC$eYV4>:/w=h\CeRX*@Z%/&95nj4+Hj1i@+GBkIBP+8mP\j&ICB/Z:VCZXSc\n^<EL<jbHyWMyA+\
kJk@@1 q*LqDyc\\C?BQ=Q*5wmQY8M1c@ljI??mSV/Y+m:iJ9YqwFSWJH:!tJX<68pHBEmwQiR/T555hqZJHjRl
d<FZi< J:%kIEmZcdFWQnC5kW=CZyL\p#cwbaMhWmb?me8Y!6/?i:6/qN6WR/jd8LTBXh!!!JP:>QHhFtMa:hS9
WnC&V$ cdP#\qi1^A=5@+\@\%Qh$YFG55k%T>$tyn&W&qJciS@NAPW&XVE^%bBGi:MQEH%tpX15cK$RT?wq%k?S
#VX&Sc B^<9dVa!jcX1>>WFRmHSj4Ih>qP*e64Q9y^%*Vad8#kuh:^:>+9bZ*Jn^/1L%iYP6GMMdAL^qpaVh/:R
1N:\Gt @A>j>IG<<Hj9hq+dbB\YPw^bGV/\m:a&:^W+$*:kLBCdQQWlRcN:<A&Vi8QP5Fa<DQ#VQ#&:@ME$ZIC+
SbyG%h Mw96L=<C%tRdd\e=5yWcM%>Y1@kFCHAij!up<C\lHKS5<BS8J88i>R1!X>nYPI=/Hhet1M:\61L&+R&%
hN>ma8 IL+FjLnjXE*/Y*+BlbML4d\jV6wQ\8HwlDCWcpeqNp6SpeZGeHDCqmShAV:da*>TV>Vqi*ZeSHN=lFWk
*HtP>p G?wyG1T?C$Zm#V>aehqanbu6WkM+Fu$K+yt@W<6#:@9cQMi4InlXS=Bul<RH9b^$EHDtk6C$G5*:pF6p
wHQX:I CjYw1Cp$j!$RhZL1w%Aj1jXQ9mhY^9>E#%amtWM/#<m#RdH^=mNnkuQM#L$qe+X<JSNnS+*JT&lkIc:E
!blknp ZCq:Z6Zkq>F1pD/HwIun>*6eD*^ew8$jLLSZD>5L<la8/JVHdc>Ta?!P@mDFjSj\MEB/wq8@A9*8MR&G
TJYeXY LeKu/nX#I!1Kk^pRa==/<M>$%:&/?lK?aKt*X>ut1yMqQC!Mm^iEch\H<D*mK<ynmp8Ll1RQ/^A9S?Qy
Y4#XKj 81C^FiWYTMp944BbJu\CkM@a^\X@4nQd9lTtc4I<K&eMVa1BqIpqFVHGwW$iC%auQX?6/>?J=@1C9HN^
-AZ+Yi 0007412154700110333 Page 476 of binaries1.zip
Kq9bj5 LG?dtV\>+%*PB^$F<c@PeQRw<Be@CPE9uw&NSQS&WJcBj@uH*&PP48AC<EL<@b9!MAbhA8E+yE/55N4G
$ETQ*y 9?w*WS&c5Ha5YlBSGb?jhA9G4inLH*+9N8\bZ5AI@eKD46!L=EjmA^MT$Q@*D>&&hLIyEWRG5kaKncQj
/y@DYQ ^l%\*@@HPN<tB<iy=Q5*%c>!a8SWBM:1F%=E>==ITQMGwIWV1TP@iAJGA<y%YadNL5&%JBCqIH6FtcYp
CJRtK+ amJ5\NenEL<kYne5GhG/cM5apM&I=6n@GWcBmckK^$EVu6TjdPp9+T/S$cWwJGYneCV&I>1:CqI4K?!q
c:QRdR VpjyBA6IQ%ZytCXXTZp$ZN&VhBlHQV@t/wk&XL5R>ReB*aEaiA/EqbNJy4jI5RjThWGFby5qE5Xu\$jG
n&N55h %mmb4NJ%1HebSI5Jqj$ijVwMCXtkE=JynwK&:4BtPptn$IHtY^+%aZ$l$kStW?%cljY%^nPDMjw9/%Mt
wEi1d! eP<BlYC6XXnj\DBtIMdN4I@Mb$MGRyn\Q8VmjiWYw<%eWG1>lT^&E&F@L8:H#yIt+w=iqQ<yd15KMS^F
%e^mjj \N+:+L=$:$/nC!qnt#$jZMu8qi6*&8DlWbbIT@ZSYP=L=tN?mn9ND5W4t8dReq&@P\>&?pYm/R%@^TXG
hwnN<K VIkd4Tl&lY+FC1VwT:L?L6wY:D\ReNiR9npJn!YK=%^c<!&qXFe?weL/CibAR5hA=mGqyALbHcXYC:RD
C$>FCV y:\TFwF</kXGau8cN:Dawm6$EHWBQReSWX&bZ8?mpTYVK/p\u8?k>\^6hdpw9C@\1/a!?Mhj<AwyHSHl
&t+N\\ 6T@mc+B^inEZIdY\akK!&B#Y!TCj^&8a%EJ#ycQKy4MWRjFPR4#!?ntRNK5NI<e5R&Jk*lGt5Sd>p!c8
bqE4!h aJLAa=A6m%tKI5\/K^HLAk4\B<BJi:e^u+M9Lj5kQwKW\lJLW8F+T>Et*Y%WRq:#Cel?\E<kP/\&TDqQ
5c618a G<nMFFDKV/hRjjl@A6qlFjjT?l@CMuycmm%eiXF*9bJdlBP8djPiT&%:J19XD5KJ+$pPw&X5lY*!u$^G
q$cCYM EW/5p=iD<BpIt4#ldQB1SGVk#L=qFWXbnMMCGP6?AF#Tm:XXFKG1Rweh?Bn\N1d1=cBnKLXpMlydcmp9
ej4m65 LaVM\WbWcCtK\@d9YaE^%dP^IFlBTw:@leZ*C6lmI$NiJBd+FJB:<aQ$JVQbXF4BFE&55JYB9dCmy1w<
yTLZW= Bbhb#Qa?S9LPeRYY!SZq5WW^ZERI11#Su\PGy?Hl\lRRT$bD/nGn*aEiw=TpCcY&Kk>$Ta>ubkS!H5^!
@<5VH+ ED>JaEy\BmMQkA#LJA514FJMh4##d\aKRG4!%\Xpy8QPC>HeTE5Stk5bJbYw8M41+c$:C9KbEV:CKILu
BRJl<q BJDZk1DG/<N?I#P>te=$$be5?85I/<w/anR=4WQ=1*h@T^ilq\1uPP&qbcXY5?%Qd/h\Fk+Bd@8h$eWX
CVTWEa Ym*XDAl9<!8+?y?+qAJLmhq:Rl+Yuq^lm5l4tCDXkm8dtN<S@y*S<\&9?emB@P@T!@#Bec@*VLXZXd:k
aMlQl! 9tDRSTX4l?DJwNZJ+VC!!GLqTk6?Gb^ccC86nK?$^8nYMApdGjFS&CmWB@m\peX@9D<%C4eh19jT?6RP
nN=CK5 =Qw9YG55cYTE!R6+ZFeIiN/*QF?&HMX8uM>Ky%HkTX:?PLi6>#<M6y:Z^+%mTleWV*:GG=P$INbIKNhc
&eMS@k WXDl1CnnT1iW5ZFVK5wKQE56uMSIEhcKCmPSAcTR&#4?C*NHXWyBchFj+X*\JRSER#EZXFku@^wlSn:S
T@/ecG 4#i8!?:QuYFVXZNRbtGy4dB16qXk4?DWR16=B9:c4l48P>4CCR<?SDEaLaIMw4&ZFltyY1Yj#$/lFMBC
pW4J=b yq>>tFCA$1QWk<KpiIS>Zd8?G9>e@A!p%TD/9C>J@QimjqTP1qN6E4Q%L^W6RF/NVCC<:=GAdBF%MTC@
:#nwMV K$FCA#eK%LIGDXd^:<Hu4NNZ^X<GZA^!:<#K\c%$ndB@l+y:PRc1%PEL$q=tV#=u=i196PuCc+BuGeE1
^yC&FC 4QahTnbjjQ64*mKV*=dR?dkmm<Pn8^!hNG8#Wh#H/Nq+6qlQ1@PYtV8?nLYT=DN!F6MybRP5<4<nhctS
b14/at ^4E+:4AS:$WZIMll5V9Yt@*t/y>A@tmy/Il8y%y1lHWViV@h=bNPVYMDu@qPm4uAc5GVySa&RLjk11N5
aMwHSW 95IG8n*1N1iF*Jimw\1=SWQ*8l/SH$K@ediQ8:tJL8tIWw/=1jbRT4Z9E@t#:*IEmy?M+myFG&TiTtKS
XTGyc^ >QhH/w&1FaDE?A=86%WK9@Ta!cYa>AAVSAZ$YJqTB+c:>I!<T=ReBj:IE!\N5&=A^lHPVCH>$amidNtG
n4/#!# ^Vu%NN858G:Pa*tC^h1ZL?wtwLkB8Y%/D5yFB$bVA$lyYXVu/GRWA^GPmmL#bQ^6*\\cBFypn4EX&R9C
Qdiq+l @dHjipmK1/!\>YP@F8ykk>n>6K1mLJ&d=QV#pjEh6mtEEh5B<:BWcITMAibCXFyPFJ5TEJq=hy$+A8VX
#S%Kl@ $JBmIWL5YFXHLVJFWI*H46e$1wq5>+Mkl$DKqYJ#iYFyj<k#m1#=GC<C@ua8>=Kpy:EjKZtqNphNqjpb
@LPWcq G\@+ySAN8klTERlLaIl+:%9liaL/?AVAS#:N>=9AHRbnH>+Z#hnV4>B8KT56HK5K8cK1GI6/wl+^JSA^
?!*Fqa 8?RlatEnTJ>wIlc>h$P*p@5VFXk4?qBd=XaRT8EcB=p@EkbVdC/55hk@>m$$q%t8cPKD!m@=bkmX=#WP
5L$J5n M=<aJ5*Z4ADlN%ka#5$CPaKQbTDRw*ShlG#:S#j=6PaI8n/$IhC&$>i?WjN<n8/+GuDXZ:&w5ilaSyLa
8y<*QS NW$Ta*RiR#%t*I\R&^Mb/6A*tl4l8l1hB*F?qah*@=@<=LCqEZI$pZ1&RNB+T/WDL\<1k1A!e&u=<N!\
PyLWwF qTkCXcweph!GwdFB*Vh:MJu!F*@JQ&SM>CmKpY1l!^y?<9IyMSNY?<c9>BA>n@5umLM<%1lm%CXD@QHh
\p@Zat #t</?jH=AVHC$1R+5*@==Iqq#CN%QN%Cj=FjyZRL#Yqpce#mFSyY>FQP^:%d<cbyN*ih1EN&%SnQ&:wV
jk$+B6 @uct<L115KVTZASD5PQ#8Q=V?X@&eS\CL?p^=HpkZRL\$>@X?RP?@FaBVQj&%**ludM98qlDK#P54k+V
TFmy>i :$:S^BZy=5PZ69BbjaLF1utH\@Bky=B1L4S=?ye/Jnh/>qhNKLZHq^b<yGpViG$b*k$N\9eRbLi$bl#B
ubBhSu ?btFJYbH9Pb=eJDGDJnypBJlu&k?YJuFFJbWqV>ZLiNX<W*\tBH4QXB<&ASQDmK!+kWHtFJ#1AH#w<Ak
#upE8w b8mjjynXb?WMSWS$idZTQNc!6w*NWtqh!bTFw:/AB<Ypm@Xh^j!WBb1jiJ\!kBA%c<YG<4Ej!iKiHRG^
Ld6tJQ Y#RH=4BhIcmm@B##YpmwNFIjI&:Z^\ZaK5#4CpM$>11^HZZ&ScK\Nkbji?J6K:YQV#5yCktk6=+Rn*h4
RHhE*m p*!*h>LC=Nm?DTXC$<^c5Xi/9AlEn#QSX?TNSPt@%9eq9\>F^4dTn@y#@E:yMD*Wu=>5>tKiwn$:hMy#
miJtq\ <6iF5&%nn@tuGH+qP85<@K=tB@Mq+P*JT:Y^uB#+bINHlw:LL4Va!khIdZI>^M&*epPu1ALm^@n5T>E&
n9^XI5 ^EBGSaEnlh$diq$/?qcK8HTnQw@=R%M=F5TL*dY!^:eJetW&mNb*SmWQ9NFitDlCmI*/uD8*KnVi<$cM
%>ea<p u8*AJ@EMyA!y59tNNccl+A=VQtA6=9LT$c*E\aP><tjJT^lyuc/BA?HL?MAbyX/d>MYqQ+C\^$@Z/I>c
Vba/^C KC4hcH?hbJFT\*VJe@IyS!%K@?euKVFpWhNR=TH>GjJImdu!X/k^iV##qJ8k#1A&HmwCX>YD1+1lIkdV
NM@c5B B1@Tt59mIcKG+?PK<=AT<E5l:!ajJau?/>wPI$NjZ+MVVEwc@jjyccBhN=$l4M?Xmi1bM*j#y@Ww1?nn
y\^E^u LV8Nu*1P9eNP$/pbuL9Lw=k:VEC*4\w><Wi4qH+kHjI5A8jN4t5J6Z%6ZYmt8VC$XipLFZ=HmIHWkm4d
<EDuID YQ!Q^&RElR/d&Yp9cXNbYnmi+W\ISqcX&%m^\1je*M=u+#iiKZdL56IyI$Xp%lZaQk=/9!QKKDnQn6@N
cZA>Q8 Y@%$6yHjC1ZY@8l!jF#$8S$MTQ8ulHV!1Q$$@A4@AqKL^+mLI8P$ZP:aKeni^qbS<h$qMcM!\!P?l>k>
tR+#+h ^E?#9VJQY>yqp?ha4>CMJX:SXS9FPyDPdW4kD%&hqlWPehbE5a*ZK%4:t>\$4h*!mdk&yE1:CS:+BHl/
*bEGqG h8Euky^CXKQCDP4JpFM^G%YY>NdKw8iV*B^XGT@9QGLN49QqD&/b&nb#RtuFAR?y%a=apK=MD=!K8=RE
&IawSD MBjLlDl:beX+C!1HakaTi:8Vbi+?STd/>ltmq!kbiIPhe>QjDwn$c#6t>khLNQZQ@&ep&pT4A^uPK11a
+ZQl$6 J#It*p8$6*Bl&q>bddyl86Nu=IhBmd5:8JNMGe/TaZcihS5GL:A$4HW=wJXa4XR@XR!DP^FyMJZlpM^+
%XeTj$ Q<MJ:pS*FQBQb=9b:#SNJD##u4a1*tl+T5>uc?w?Vjebn#qFH<kuCpG8K8:5X>1^ecqtd@YW?PA4*VTF
Wn9y:i E=$Y1:YN=bY1whyT1!cna4c&@B*Xai*bpL>D&6eGPwK*JDeCZ*pbyQXB+w!w%:E@b8WG5F8JWNjX%tbE
FtKu?$ RJ&+S4M?VL\b>El/Q&*L%4dqdAEWim&JQ1E=*>&d6V65XjyH9ue$e9W6Q1nTHG\d9%!+:4YSn/5w%lYZ
%F@h+j Fqw1=I+kJl$B8dmN&EZ@E$Ga+15eEPE1WcTh\CPc4j<=Wh/RVQbFJXHRCH</A*\Z$HA\%^hqXJ46h1w=
pjeaa: FNpSPNQJkbL&Rt&pDlN=uwbny#yR!WR#9cAHb\#X1KT*Pyy$:j#+J/PStAewybD/SJTQ^b%%^+pR^*<B
Fu9men 1AcCCJ>&RD+SA1V%4?k/IJt5Fkm@kD@SB:D5:SEjD8wT8JJL%TMBYTCX$P9!RuYy^d+VySSbmyGq*G/B
^m&GeR *MIKXE/PXcGn\wd5NHWHWi8M1TXtY>H4yJM^baKq9Mmj9I=#N$l*RjbiyWN<nKLX*XTmX<qK@pRZ@!<!
=WGb^n Kay:J>tI9#Cw&j^Sn%c=+l+p=*+RS+K<WI&JYwSbuAt!cRHkWM#>nZm$B:yVW<l%YqhAPpaWYTLlyF>G
aF=<<E W!AjVCp&T%FXwaVnVFaLpeQ5jdCE9EAaTQTqMqSYcmj1pl&YnH+F<>%6cZ+ZPmIj$TeI^*&l5>mk:!lw
=e6Nq! DMB\Mb@$/RmySQ1%FPwLeY8hhLSWX\JGV!kKqqcdnwN$H/iRibQIaX%1\lmE691d1PWE<aVnITQb*uGK
%TiVZY XV:c/Z>Dl/k%k^w#NF*8w=q@/1k6+*?EtE+HQR@K8cK&DDEknAqw6tYkLKjLqwHC+6MWY\c!WmidkqKm
/i91@% LDp&aMYYEWmNGhqTZ&4LRQJdmX*hlTAwHu5S?iZ!m=dW!EZAJXG6JMbXD8SiP9bCDajEy+DSAKJykb#R
81#?HG *y$hc!46@mj=8K5%DN\yXXJ#^m=ecp^&AnJRQbJGXTEK/B\SW=yJ89NRK>X9m=WCqi<l%4QTP@?FF%GV
HRq\=* JYeDmPPJ9KwKS$Tn=HiBZKptctY^1SbPEaq<PT%QADn>n<H5=\\<C&Rq6B9E^WVZV%Hb>?F:bMJZ\^P<
EELl9> nldTK#Vd1*StK%!d#8I1ydmq#BDFBXtI1DEblBNyXy*EkQnQquCbCVd1yGJIKc?webV$%lQ=>y1DYV+L
hB\Ch5 Zi9N+Fl9*utM4bNnahe8Xym*WMhJL#1aIk16FaY&<Z9%\9Ak$@8X4:PaKdM\Tn\au%%J%Kbl8k*>EXMJ
-A^Gm^ 00041e3954a00110333 Page 477 of binaries1.zip
aVc1mk Hu$6X>nq+SHwPLY:RkNIu!Qk#<AmEG/1Rjd#%8HP\H88S^LSNPdBPq\n4qZlJWSnGKlLnDZq?Qnyn?99
9Jt@@& hWWb^jYq=ib9YAdnn*>tnky#WSMniKb^R#DjyL<&lW5qtttq41VCctuHmi*BE?i&Rnw&k<lXym1mtDw5
<GYpZ^ p>n>8DFmJFpQlY4TXW8p6#QN6uQ6w+9+%/9j#SCYRpVWaGu<Bm#i85XqFDia4jdT+6K98Y/M4kn+><I\
81#LV: WT9&nwaI^Fh!h>G+FX\pHn/FFTdhpQD+MI/Z#\P?\DtJdnB1J*51WLe@l?h/R84cIRl\BDQcBGIXTNQQ
m$ndl< S/Ra#Xc#4c\>n>5IEa^$cV!jam+8nnTZH9eSNn*$\hh\B%RINBPaeGYHHm%D9$y=8nFG*l9ZVPeD+VHb
KA$*G4 nb$kw6lt4mw!MZAC=Db6yHAPd1X^1hTXWGWP=e8S*Y/^PZ#6Z\*8#u!&S+wwM>hQL4DEw^?^9MdBcjc@
N/jT5d LlZM<8a9MaATW>^&N:yHC+B45T^yD+#aPdD6l?kDpD<aHB/YYtkV8ML4#QGWnXI4qb\=Nu\h%\q1?MKh
ydE&:n DAJ^Y:Vi6AW8k%l+p=NDD!>THYP8JH&6m#PZq=m6FZi<#!%/JbEbNhQPD$J!PIl9S@Bu>lWa+%GW1nKh
GXuP5G HijLG=Lc>GLHRJ^qp1ymQ64D^FXM5NnTC6t++kydtbMX9j>JXwp=bj\=Bp\bL=W/!m*S8CnMn<$uE1^i
XEB^kG u&q#Ykw4^ycZV9qJqi+@SZwA<ka@!H%u5W\#/H*4i&6kGH@Q8!Eb*<E$&I8eT4wBey$Cy&!ClW#C6+::
EE!ayW C>iN=iR@8D9A+SXnYNEC@Qm%\JiB8FD*?C?hc5BJ+%86cmC**BJi8AYbdcZJuNS:<E^Xd1HF$<?/&alZ
e^dMpn Li@B:X:8QRELnV9abaXFp%Vq8=HF95XQ*^GQRhL4d*NCNw1!?ybe%Eplp*WyqiqXP/DRD9\LXap@A:i9
9kbF&4 1i1R6Atm/*dnSV$@y^/4ljh6qut5*hp&WV$*LL*96!?nbPpC9nk59Kk+j/61Ykp1HIZ8T@%THuL*p8:N
%AKHk\ P8t#byCSeP=DdbN9SW\WIm*+?Nm\cwnlb$!Gw!B1IFMhe/QCcy$X$>kN9^F^XVjC@\i>buST*%::j@LQ
8yNN4p q<J#EDTN>5pHIY><69wVKD$eQdqG/q:&ke@Iuu1bK>#FMbGN?pL>Cb$+c/N*wuI:jJ/t%kNcG=:RTZeb
ewH?C% k!%Dwm$jne^Xd%TZjKp9=H4qC?jIei>\FFJ/Y5yubu4@$T8wdihPKSGe!ybB1CBSMQ9%M9d1BZ!*X14i
wjWItI XVYP1y@WI!*qJa6%t<5iau8M89/\KdthinN@mk9wpn^*p@T+VRTVwQN9Eih#!T1&%VS\mwFE>%k*>*<<
?GnmW* lKJFTjkXlaiRb?THbbB8d/w:BZ=d<9TwBnY#kt?yC\IX!!1SVw$t8G@ynyJGSWcSR$LMbw*al@B!uPIP
*laMGt AcQku#w%L6d6yhctH\n\1t>dcjmBH1pA56Nwb@T6J>hTuVXF*A8hukuJ>ah<^VujBXV+TN5IdhkC<wmQ
*JKnd^ A:c+dn4#GQA8PA%TWZDkLAlKK1pw5@TL<%TLY<JSnpe&DF81EjIRTGMSLe>Vh\nmCyLa<jbj@NB#mCmy
p<G5JS 1LJd>mKIY<JPXuZYdXu5pb%ScdEb%EY*NE@iCjEdDZLA&^+4btnYLRJnCWndwKt#*!b:SP6VkjZ^HnW#
#n<T%L A*WZRZ#!6WeZpGj9*B#>P*5ClF+Lw&9+44KcAj%AL%XP:B\Q<eyw*%Tb5&t1:IGn9>bIZ$L1D&YYNiyY
IY+pl4 ZIt@9:@ucd?\kTb1iQnS@!:EC>@j$M^VS*$bFGELL4YjR/9TIwQn#EY/eXX&S=:uTM8p=MyQNYdH\>kt
CiA#nd >RiRqG58LM#&>Qc$Vu:u9enuIG$@4&5!iPJ59B4+@mBPnAHJM5GnhpPT9YKC>T:e$Y!:yJ/><:jAFqun
lM\#<V KX%&NXt8PK1!@jdp6>wYab&8A!wmn+dT>d>\q#^<e8G8I1u4qP6/<umX!DXL/6RMLIqIni4%cmZ<YBEM
bp96H* Xwqp8&l%SFL9Tml:WaI:ywCCQiwWZV9l1paXjjwMEhR@wj8kmZGBSVP<ZI@jQ?l=qV>+RplR4@aQ%5$D
l*Dlu8 @L%YdwRPdd=6p@%N!Fql!yemnniZipcWqlhQ>tR$R9lj\?KJ<uJY#KkaWhBbQiGLpP?lMVE$+1ZQQM5%
4aT/CM 6<B\&d8\S@TP^DdcEBRYc8SnW:Z<nLAEw!>I<+iEq5DwnMcP>^pyikqK?Xpa4\<MucS=D8>4!5i&tdXJ
HGPYLm =SkZJZ+GRaM>X%mdAqi4h*j#\N@8%Hc+6WidwFt+D6y1YXktS\*6t:5nAX@54H%LHq%kty#WEetyljkt
bbIQWL <=WapcM8H\&#R8QbL@M>A$$y8SZY*+#c&K5N94$l%:/j&cSBMb=<ZF6@T+RWD/uVLnIXMjy>@1N$4+6u
WlPSR! ^dkT+Q??yQ=8ydBQ!*icCJp>9M/aFwi$4PXSP6t:9PnlJ9>h@M@mlT%4TihTYRh/8L&eD<nDj=\QqC6$
^hN6!t t68jhpJyP9hcllL=4yIectWJJ:uZpn=HQ8pe+19m*cp$6Il<YWa?4inF@q\^jNJ=9k1B+Vlb!WK1w>NP
Gbm^*$ Hd$JZnSA^>m%^QpX><wDbN@t%QnQ&BueB@kJkQ5#iiMHT:iF>AnQR*e%RV$utF@tC8%XeZ^lWpXbbhXC
?NHH<a IVDaZuG@!8a9wE!jD%4H\EN@w>XcP6d!lS<iYEi$CGN&MG?6=9pQR&Ii?Z\K+klAWlYMLDM:Tu\6HNwj
+I9ph* P*J:qKQE%4imc1^c\CjQiJVtVQlFc!/*ck4Z<&X4T<$kVPpipn5/IKdeZu4Hc@JN^8FaaC/<FP+Z!p?G
pl5EkQ a&yhm4&1eE<ATF8@8?4Z5hPXN8<Jni@yi1G&SnG#$J4wZSPjWtc!PEw1m8!iIaW1&$DVLaLDEMA^&iSW
KHqWQ^ <@ZDW\SAWKkEF%R+ccZ$Ew96&e9++&AHbJTZnm*b+Tk#&@!E%>T^@cVA$Y$<Cwd!uVF5Al@BF89:@Rji
+kCR=B >6K!+Ey4Z5#8>4MT*1iHJJ@MLb%&hEY9VG$ZhA\jPLc#*\iQE!N!Xa+D:CL<KcSYXJweyWSuKYNCMk\l
B>DQW& 94<aj\91pnldM^*+&S9XSn?9A<C44!YXkL#Fwa@yEX4wk&M?kjG*%6yH^Mwu9Z=p+\cF+GXatAAb\bbJ
!lwwuN !>K8w*Y5FwK+Tp55E&i#VCn6cyq+V#YpM1&6LZk!Ia4m>5CSXiY9#=BQVq/emQhPmM^49>F=JTE8!X=X
KltPY= +Nm6hZL!i^6SkQyNDXqWD*8W^+\*NChwZ5Rln5Bn9/wEc%<jPVIY*R=PqPGah&!4#tK1R#9iGqNlLnwh
?qhGZu aJ&eID^>9&8C&Q9NYQ?F@b%VwynyA<K*$=lK85$/iuNwk1tbNStV4M=66u81MRZVP!+&&>6MM6y/6*qL
b>QcMN K>@!/kM?8HbLdMyy5dVA+4VS=QHml%9/BA/a+>Eqk=pXbK?!46:QP^1>9k=u%BXqZh9MNB4ZmLaKe&FJ
:nwdnF p8eQM6?Bj\SjiPT1I8=y#^9a5k*M=DnlpDGw1^!TlB#h%X*XQ$S%Aj/Z*<S^i/J#K@X5WeIbeY?tyjme
4a6k*@ PBtQb4X9/6:%X/X<^DyK@?BH>VH+mK>6+nQaNwYY!4lX@q6XjKa/e1$K=QCaAb+SbSYuYcC4P<Hpw1Bw
S#?\t\ EYRy>:GIytC:VQP?cWE\$j1G!G!9KKh*IRl!K&&YRuMXw6h/SQ%9JFS*H6\qmm&/TAZGTp5=KkJ>5hpG
=tS\+X aub*+L@9mqJ<nHdGapAyE$w44Gdp5MB#EG<RPVZ^C*iFDwyG?#VENV5eIPjjYNG+nWVqZ8ZWEBqS+1uc
ME%#\t @dyPjAJG?RjAA/1R6FpH8Bc6Sp<IqmuAt?B+ulFM6PchWLkRETp<6eJWBDHAEhX6:ZHhHP4%b:FZXNpK
CK4*^\ LeXeqjXVSJjumZL*:&G%Amji:ICp5ZAhI88bJ$nIb*FeN4JbHI:JENRHXXRWRW1&4SSNMBhPduaNWKnm
m/cM%M BERt5Dn6Z>4$b@@Yyw?ltj5X%\CW&CIK6Ti6D/d>V=$PVL=6bG+4TaBuI:=buXb<A/k/nc1c%YqpLZWw
S!SytK 4uGuty$DwmR@nF#PAT&Bh5X$H9<k\GPW8#1nW#Y!$wh#B9VG@&8nnE$y4SKMF*P1Rp45:m:ZSL9twHT*
BJHtEt Qn=V>c<5*JQhyD1HQDi6:E9a41MN<%kN$kMV+/N\d51BKYR$N=%4<T+hhWu1kIL4/4@Hu^ud4VW<XCIa
WmL%yJ !NHKTTi+V5?kDX$&9/55I>ui<WkuGt#lb5d:MhcWPHR^6W\>mKjT$ehMLPDpL/Re+Y@M?/#*6kM?#WHS
<Z@ckL bAbZk6\PNX@XK8t+j&F<@<IC=n91plwbpRc<#@8GEjdpME@k=pXt^MCh#HR%Y<X+Bq@bl&AeA=hAt4W?
SA6m81 W6e#8^/m$*XjlLI*l/T^B&6%&qItC8$nb^YPJ4CNIB#qaENjl5cZji%KnMClXNTVW+L%niyX#nhkjjWJ
Yc8+q? Mw@>?<ZpX+/6:GBMTmm^X4JMhl?WQcdTYnY&qKmDa<#qSYPKLj=tS>XqJ5ldlYdZ$en5*k!cb$4^9u&K
LZQY$L qR\@51MBn!8?!F=4LZX6aC@yd5#+Y:iZKL/\Q&W\J$:^\B+J/BL$qBj*aCjA*DHTcWHup+^m5XANk\l@
5cAa\< yE6JM:wy5%9e$?TThG=kV*#nc1KTKum>E81qwN/Le=qD%EPe@Z+M?$?i#:TH:G>jnF%4PXTJMPe##=Z!
/!!>^t M^&>+iMLk6et:9Fctnq>>**Ye:eid@HBkNqFIQZ>FP1C$/YH@6+amYJHpM=njlnkw$hS8Hjw6%k4I@!<
YX=Cd: mZQ?!8F^aMJ#aBne!9ESuTB/M+AHq+RVwbjjQ+!V5$FXt=q@Re1k19Sc5/QCNute>&lu8HMN>IbI^t<M
qk:H+4 I&P?8JWW>#t6=wkMNHXm9bI/kd#YH?T6ZPq>ay*h&@+X?cLlytu*nB6G&Tce!BjcVyXFd$m=d4a6=T#&
G1RdAI X%tJQalKQ&iE9X:<PE@?eXKK$%JiYFFpKh4DwdiyuWIBT$DY>8beTT64$Qe%VVYubtY$HhpjtT96XeQc
CbRA4& 1$X9>Jn9C5KqaPnRK:\u#tA?S<D^S\JXGbZtIt9jm5L^SIy+uKej=RQb+@Gm>1wG+DYjTWuPjd\9pca=
cb/nec cBnCh*Wuy/N9eATS<h#FG>6%nGR/?wR#uh8y6m/Z%1d\?&pNdVVAjV%MehQ*+X!B>eaeJ=M?y1w4VbK/
yek=kB &tV&P<A/8SHX@K^\qm6W>RB^<mpXYkZ!J#$G8R5*HTHhWRHy*%$=6quPuK!GyieZ@HM=/$w@=CiZyRIc
&5$km! BhIp!AMJ@b!a&b\^R^q^Y^?V$k$NSQ*Nd#c5SGj8DY\cmHnNndt\d+8*$qn^ZKjk$YQZGB4$Bl4+c<Q4
&9JQEl Q%++F9SGW*@h:L<m?85G8DN^dKM6i^ETp$b*eq8<@FT:N>9ha8e6PP5MdC9=<iWn@hA?tNBDTTXEcSYF
M>EAJB mqc/P1Bb$*HS>ANbb*Td5=4MYcbcEPQi=kcdW6%JAZwl$9BMZ:hAiyd:h*4kKY:@aNyk*AAPijK@Y/NP
a&t\Hb 5!q8*PkwmP@uPqVmc/1?4%GQWCWHQ<$ZT48lec:HGnSX%Z4&ulhi8Q?<chHC5K@WXqlmFFA?>a<yLDH*
B=IM*k LB<:Z4$PHNY>6>ZCjjuk/J==EN^P4YVJ?qlJh$Vk@EE?T4m<5aP#amH:wSed>cSE#DVec@j=>Z6=j@Z?
N8EVi^ M??wV:C*<*h%yPV<1+Qw9ME@B<d:i*?yGPRW+QC/Qi1YVW#^1uZ&X%Sk>PLiVGjTqCSlE?Ai5YNSaYFF
RieIKE YXqXictypCcBGQ5Z%FXFcPRl5Q968ktH*/%#ZtqPk/dDM*t&VE=6JZw4yaBw45<aKnbTSL6ue1lbVHIP
-A*Tc$ 0007bd119c300110333 Page 478 of binaries1.zip
66Np*& 95\a:4#wG^#&yi#>6HZAkilPQ$Xd@Zn=8Ede5h8#$@awPimZL6j<lIGc/HH4yi#Fe5C=1IiABAMX&#LM
pB+=R+ ?R+Hpa\i/kLRSd/Vd>C8=pKF>HVWpnhAW#Jhl\N&*!e@Quu8yAIWlXQPVNiYLPaPn66>cQ*tn88L:@5=
uKJmJN ^FE<jqZ+NhwLqBK6!tZmFETc^tcSuWPQkeDdlMQL^:iLd!<<$H!dM5\yH<Ktnka\KD8N\n>F**B1qk9<
&Ft:wm nA?c<BYjtija#^@BX$X=k:ew%iGWCHWK<wT#8X$J@&Z4&D&#Mn8MjH>\$?AhHP@:XMpIwbSAw5CCuANe
N!ZJMq i=hZlYch9W>?#nY=epdRG<5VYZSQDXBkVWGkKll!=Q#>y8\#G^JSm!p>mD#iPKB=>lpH???Mu1?/:$Ny
%%n9Jt k<9bZF@E#=$l!9Qi>i@wN1PQR?VSn?RVT:PRGTMj6<<hH><N6*et98bPKEE:n^4a#E&GiH\R>i&=&=tC
+SNnZ^ NP?BtA%L5u1t!wWZ*<Qq\S4uSZCq>BRdG1ELmHQ9iDDc:B!R=4VYHqh*!p?dKiL*Aa<<4XjT*hI+/l@y
F*jB65 /FeHe1khVVy&l=6==@/6lZj8y@+!@?iSZd@1@iD?k?6KTpuKh$eNJHJD!TC/l??V/SBYVun\+Q:Ihmj9
ijdeLP S:^t?4+Z$dM:cM>BP/G*9Y96t8C?u4iAp+J?LFyImRRFRWh=+B#p&n99m5@9*Pt?46Pjw<@eX*=1^wc&
:@6qdi QXN$WCQ6QXu$ldbq\=Wk$1F6N8qE6<!+9<qQRJ/:eM/DRRTlPhq$hZ\RClHK^^$4uBPuHS4!><^JH^%T
+iQ9<6 c4=T^#ZcuW/?5mFt&RXH\:H#&&y&&9?GwR&:l+l<Q*i^GR11FS45F5Ki\L?E5Kq8Ic\Xib=@bAcHLtZ*
k/t4$& GS1FGjcqZylLh?hny5Pk$5G8yVKe$%/NPditS>Q$aCWBK1Y!T5qDC8Mn<uH=6Wa:tWZ@>Dt+K1?t1#lc
N\HHcA >cBnt8ad#%e>P//Lu/+G+j9&SC$R#Y1R#<V=#ZBZ\/InwI+=LuImD9IeQ&nWAFTh:k!T#8Xk4aEJ#ahW
I:>Sa4 W*Fyict>bFqRb=nDi+ZpG&qhI*u:nu9qFaEl&hN>!wWZw5B:+hNynJIRm>4/FKV1e%\1\dbVu4hic?4a
/W=nA= Y6:Wc5N&4<SYn%5N/=1+6W*$PpdJPd8YKtk=bAWkq*Mq+Y<4yq%6i1P#u!FLtl&j%n1N*@>#^@^N\Q?+
hFR^BR NdF^ltiZ#mHM5p$lwEMk>iKZw^XV@dQeYZ:wpLqPAweT?:eE?CN1$IFTC\+$<Qhbp?/u^CV\E55>mGRB
dd5Vd< BmXl**NKjpl#hCjZNRjddwu@9HXuTJjkc/*#T:\CP=X+NjaPdCQ!y<F*\/<lJ\ZHC?EKA$PE%&9:HXu1
H:J=t! 6TFdqFWjHqXnL*E$<MZ<NI*XN=SYtJJCb%=Ni1k@/%<Z\leCa!$P1G>PD+l!!Wn#lyle\>X1D&S$8Z8*
<GGpq@ T+mBQ:w5Z=+T?Yjum/6CQ<l8y%4ujTL5IpkSMIH%ktjdPA>QhckHQ?/e$hHh6:4ZT=*FK5CPt$aj1ZJ6
EpSYjM /:1qHA&^S^^&9Rl1P=Tn<>kFlZwI#+hZ*/pLMlma4aQWZ9^\+G>5<wIFu#GZq\Y*Zwc#lMN@ilHJd<kj
V&eIP^ uVeQZee9/GVIt<%pb*5R4W6cpmI%AZ<Ld!F1jY1SyhBttq#y5GM8%LkC*%R>IZynPGDN6HGl:MdAS$1P
L/HIb? I#L?9CFp@Jk<VkuV1VS8hW=:4!p&b%ZHE!m<Yc^GqS&TE9ytbdhC<jqDLGYXFn9uGDM1h4!>XY9p%*F!
!Fnm>e eam>c@m%JGpmFMqL4!YJV&c$P1LSW@hhpK%k&pEpb?m5?5ZbQR\SdbH@CIy8/I:mPPNeEK?CpC+MdmWZ
\5dTYe HJc$kC<V^jHJKCaD^P:=WA!+#hCp%@XCVDYp*k6BSuccP\m?:XC!>>:Nw@TE5Q<9XG><pdh@XTW*jFj<
8CEb4u Chl5ZICuLQMIJ/CT?t9Eu\u@ZKlt/w<\Ha9Xn^hIbE@?ZPpS9luFGC9qTXCZ=hi&P\wHkXpVGN!TY=JP
#TCt&A ^w&<B6hbGM^iV5S@*5eSTlw/hwQ*!%Qd8IX>mwPu$?RmdHhXut*qBKc8@k9n$Hk=$bY+<Q@/e$Qy\LtI
WE>Q>L BW$AMR5*j!6Vh^1cjMk+#mp&?@<#6Yn@KuK&1ZLPK>u*9^mL%qye&jiSpq8KLF?AQ*J!wdyIyiBjAXH&
mW#PIu N$AJwP8$LHeYiNM$khJD1Fe$A\SE^tecQbJAcA8%\I#YI9EHI66:wWmmThC5N+mYc^<ERenatl!=k9k/
E+pV9@ ApycBlilqkn<V+mcADXi$D>jm=IG/TDcH\*WkSd&9a1t$\wDSL$k\lTDIKXj8h%lMVNFp%AIbFdRqDbK
PhFFqC KkE:ICJ&:+SR8CXpItuYDyTq!DM6>aQy*QTpM>HchR%Z:R6TB#Kq>Y1JRV@4qF4C\>#ykYSEY4=FQtqP
ic@M/h q@^h&TF6bl6hp4S<jH^:%wk>p5^><d#a5B=?@A*<wjE^CBmIdBHb6pi5P+!JnuXpS9MC#pa1aXHca8j4
hVlpcF dc6jJQb*$@Y*/Cm/c4jpPy9>6?R/#T&=$kbb5#kWjTp14hKIYX5&hmq=!1W=bS1=yIZd@Z>e6!hG>EV*
/F:&cS PMuWhDFMaSBWZNmuYPJJ5<b1=GIn^tC45/w#XXT>5CHu!hDy?Qyh*eYyW9dH8GFGDKPW$j1\E/P1/ZI\
L8L4>K KahwjXFRI%S@ml6B?8pVCc$G\cTpaS*euIJj\eE\p&6JNLqmSwM*WV<JA#4A1IQR#LZJlIZI!YZVp@mP
+9NTi4 V/XpS9miA@?ZGNFMiBAN#%nWZACZaEl$EERktbV<8kPh8X<dB#hE54#JI%51%MtG&:<b=Snw!Zi?^^!F
&F=k:# 8iPTcKJ?l9WT&+BwP8pFW&EBG?Hq\%@\%GqD&M*k^hYDQ+MbpNa^Hn^4&KEpKmNuk&L:54QGSZ59I<@l
c<S%Ec #E>NQ^u>DNJ5Zl%^$ewKS$GK4GZ/5$<TYR+/EatqEbSWiYApHICGR&I:%yJhS*mA<Hw&#ctS#^/JSS9$
nbPY^M +ckP!$EuYMIHjQnmD5mcTC5NEmI/<$PYXq#\pjc?#5atEZm<8lC5jjSKj45/!uHwDB=y^tuAIl#Y:e:4
LGTt+G dRMN1=N+#a<@5j8MZDb$RWQkVG68SXF&4!Hemk&A8$mm6<bu@k:>@##^ZmaRH6Z<V^V\q@d/VGA&XdN=
q/t4TR %j:<IY:t4w#Ewi=!*HR$bZ>S=&ch5d@V8598@>9/aWVI*u=9?<?Q#:R#IDD$e#NXCud=LQjFZ8y@mkJP
Vbju?H h%@5LTjk=yntEuEG8t:ld4C#e98bt8WbKuVV$hC*5%\dMcTGLct=%/Nybpwj6@yH8/QR&b\4C:8cLXDj
&5N\JI W&iIp%GG<E</9%<6D*E:tqEa!Dbd+Y<w&>nJPXjZ?=c8\:Yp*!IGnYbXJ>y=aSRL?AAaiGGeRYcK<4\Q
kN\R9Z *e5bJa>$y?<KScV#N*RpJXEQi*V>9S+b!Y!wKqk%Bcm6mXp&GD$HcyT1c<jA5<>=QK&B\ZwGS+Il!+$9
5!k6L* ^RAF#FEEDZ?m&D%wY49i#<B99n<pZF9KJNY^=iMnEDY+$jJk!uBL=nTdH9y#>4@9jb1#?eR4K8$495FD
N4KV>K Xh%L>Sq6&dXwHH!PX1q\:KIQXVei1Qc@4iL*#1^tX?1FQTD9<DH1TpCiNNY*^J$mpw/Pu5#lZQYy9?Ri
69I?Dn juu@!<lk\:QYXc\$dmBML<QCyRdwD6Iq>FT%WB@qb^SH!9KCh@VnRCiqkDVY&GIEydml8LuK9c<Kyh^L
:=P4uX tVuKZYYCDnAH#ZWJ9Wd@LPj$qJq?@pV8udDVd%P!i6:Q9u<i@DZQk=A<ePZWy?6CRcHVe>%W:nnd4L*R
m#@di/ Q/?=BYD!QB<NZpAwZXND:\\*GXdG<yuH8jJ^N/nKW?<6JM<XiXiBS5GPJM?Xcnyh:*W>8+n4NlPu191:
5H^*ZP /^9R#8@Pe/9eub!?R$m4u?h&V!HTA9QSBX?/K1<4cRNJw>Bc51?:KFZu5y!GYR>ji!kdLEMc*+IP>/Ji
4+mJ\C QhJi+GeZ?j4Le:%1Nn=ZyduLACnR^>S!4kL4k&DEwEeX9W?<*?5VI?+u6MmmwcVBqq18\XY$eQG>^d6X
%^#\J\ ka99@cPM4>RmwlAmujNhJ@<H/F++@%FALtp*e=pG#@@t6K?$e8a!9jD^?=4FT^Yli1FTwbN$YnY@iT5N
GZ5VHZ XRh^n@M/laa58Wh?by:TVAcy?yj9ImQ/qShWRPV@1EMp/jE%?TSS/uD&+hubTpa?cp>bNb>MRM!Cb6*u
RY<6R9 dZdT&%<T*ij&$Lj99S$BnFdF9H=pdRS1mhTqRPmcNdl!HM\jq?THc:6$ej9$WpD#F:l%&PQ@!Tj4hAhJ
bEFdeW $AbBC\td4Aj^>E+QATWu8=%/KinQFuC8%QXVNB&tZMJJ?adS:uwP4y:8i=#pIe/6Jb84%&a^T+PFhVQ4
^^<Nkt QDtaWCNwHu8n6$CcApEVP1^NTALy\h#58H+cjM1#Ji96b*VVLZSn8iw@YM=\a$pd:KFnqT4tRw1l<w*J
u#$4aZ bZhQ>SDmH5h&#jRLCLt\#JQINSpX64Ht<6IyNbamb?AiEL18K@RSZn9tYj88IK/B/N+++B%B&Pi4p#9k
5IS4$% =bwYXPkw9:ckW19?N!4XdqSwk@a4tm>ajBZhnZ!nZ>T5!b@*mPjQ#>iElk&BNR4XX4\&jpYp#clFSImk
#?Z%lB 85EZHu5@j=Y@HMI<C>IIR&EITMZLQ&8Vm5R*@&4%qTk#u*V%THEdI9Yp$?68+JtiJ1H1FB/#Y:\IQRFb
WJyEH1 DhScNIDKtSS&^856%#+uuG>inb&c:hVPDDX4ndjlHCTWSY=Hu=:Eq*!e><W:a1B&+ACSeP+NT4ntqy&^
&C>wqK j+miSb+ZP&m94>Lt>V\e?L9t\tT@<q1@J9NA6A9p\a8$J#VHb<ZENc:$tA9<uG/>=EHc4D#65J=^+uXk
5+k5ui 5mM<p>#=9F<utNljd$a+Yi\8@Z4qLJmPck^KPlpHRXdBe%Rh>XF1WD#Xj9?=/ZhVnhP#ZjI8pL==N&m#
%HwVR: Ph%VLlLa&:DkpdyG:QJMLVp\b@bKiF=wDQec&K:he=MaL@!hK4Y=Gd\IJH@C&XeplBYB>NjyjwayeHPS
ZJG1jY @<=<b&pREZD^8W8y@Jj>yWmbKW9p:@XZm+8*qHy^CP<PETI<a+c\aV<Gm>+iCihA5SZRdY?u&M&9w@mV
9CAn>: $*41T@@BB&GFRWpk=qSttn!c5JlDhhSa+ae^/*juph<h<uN/9@IZ?Sunh/iA<Z8q9SS\B\LiTZB:ae^H
\bq!hN yP8G^e$Z<Ba9+?6u?TkmYl>\yWKtupeWMIyc+9J/V1J=KdJjn<#lw=PAj\CPwC//k?AW&wM9CF5qqK?B
l*hJ=j dBm&HJX\PQ!nQ$LWiD9tW\ckZ4t=cZ%/RS^K#^1WphpGR:>*6MK$#<pBV>dM^pi^u!HJVTEwMpPhT%^4
ep\dce >d1uJ1u:>TThXlllWD^+^&B1WmNQi!\qc$W=\FZtm<Q*j58=G4/#ed*\EH=t4wl>Suq#L+EHQ\L/auEI
P?X9m^ **mMZdJN:jDYZVeBQk@T5mSBSL?CPE=Q<\hLQnV?W!nED1pS=DkRd?MDil9IAVAcuCu&R1JKFA+ZXy\i
&LRII$ w^616QdSC5NThW:1NtP^Y5IRb:GQ=MVdDJ#AuVlyB!&yFE+G&Rha>^*G^mDAZ\Sh$d4I9c\RKaJ/=hLt
W@Xtjd /Z=jnB%&Zu/dVQeYpB8W?\%$pab?IhLmAY%Fijpwj8jZ:%#18T6AcM6Bjw@:&mekn>5u+L\K@im98QNi
$ldRu= 9<eA9n8h^X<Gm=*/SSKye1BcZQyZch:RB>KmJ^/nV:Q6V9pu8W6qXqLRWe8cESmnnS=#YT#F\/S*DH&c
i>D&LM K$AyA%8hyAp%/E51Xh*a>:1yQkJlIc\XR$GP:?b>RcZHNjqMK?WcTmq?TmGmqe6em\aZ6N@\<RiTqM1u
-A+Vm> 0007857b8fb00110333 Page 479 of binaries1.zip
aSu4aS 1BNNQ$pjb!>ZGFpk5kt9RLSN&L>1XFJ%X/i?RV9jN\m6ja>w1N#H9Q!/+dn5bPN6IZ#SLFPR:/\=&ZCu
RF!bXm @YpR^!d!&h+k*89AV@tMqe/Mn\<Vj@8G!?paJ89YCuhA/Neu4hcd>?:@Mm81T?q%C^wNwmj\teCJ1$ht
y%lFIh G^R@FF4qucKJn41RRTF^tqb5#N/t9Vw<A1$i/j*tb*\1ZwSCwXHeNY!5:n+1>QqRM&Yc6*M%!MZA9*\8
uG%8qR Vj?&:!/bu:<?5E!lHen%awV<N56b/#W*E8<pDn+BGcm*#YLJ4VRZIk86e!BQlB4=5%j>chGSt$cn1EQR
XhTEBG =K?TP5FuHDhaF>SC<Tq1u1nBdS^enj=qHJ#ybpYi=DtcSH@>@@=RyGlL?4iTcZty?%8q1%K?L<HbC8Ft
htDuy6 B*lW9<4JI/eYaX:u1VnCN%KFZpM$i!iCSVAMu5BABI>BIhK8wQy%6GTZL*mTe*<^LRlhl?jRW/<LWtc*
T9D@Yu =b$WhN>9eM6::/B@!Z5%:uim#%HAAW=J&cGp^bup@1cXpm$m&Ju=%61qThRy\R^#Ra+q@&CLRFmAhbEk
VI8*&m h8ERIepM6+MI=!baRX$FyF?kcCumuh%BnGj<V4!F9HjJCM9^XLu<H*J$*Q+H*C#&E@S98@w5N/c$\Suc
STD#yh cC=qqwyjqQ8d%1/<@5^4*Zb/wlhiq<AV*>@kZN\k^mNIV*1D%pS5u+Qq&Ri/+WTcX@CH4>EISETjM9!%
!J+Hha WS8DG6Xpc$*D@FiA$WS19QJ1\c#@AWL*&aQ8cj9E4W9SQ:QhiLKINJlQQlR#6J>iWKED4t>cq!n=&TiV
J6c&56 @h$EwRjyZ<w@@#iC$uq@!\n4$L@NDZQeY+<&cQMq=<w?<I+mcDX@w\SZiVMb*ui>:!b/u@uKTj:l4h@D
cRdCC\ 6A!\@!B=lhFj8kh\@Q5X=4yHG$&$E@VPq!+VlmLJ6*F@E$*y%IjMw6$H?Yk%+Vl*B%NG\>e#tk:5MMdQ
!6/W8S $DKRA8NM!$AL@9Mt<%18@EmDNwe+X$y\=adwuib95mt=m&E@dQXqB8yyKdSb#HbL8n%^=nmRaT54XL>$
$e?iH? tBXHEPdSt*WT45I*k8PF:u>:mMIhjem>l%:=#^/1hi<l&tANdYS1q1&Xkep*c^Xc?!E:+eWy=8Q&HN?L
HGdSe? ZwCd/CYb@EXQLk>ZT9>:VhLnbM6AM@+nt5=*!+P$kiE\tjn5=55AbXnD+YdS6Ibh>i/BDeE#YiGncG=&
CLn+4X qA<VQ<@:W=Au\F$ERVV/B$VN+uT8j%bE!:DKpNtH*dM::h<H8GY1/ZQ$F9tX=T:PaZB@$%w=\PGE4S#1
5mA@!! !q@1C<LPDn\@c/=J=Ncl^kk<EjByHBHXMl!F>M%l>%5P@E<J+aZ86/RNdl=FLpK8!A=$yKiH*hc5$Byu
EB>TCd $le!DSSy+DYcn?Z!4j\ck%Lil6/^jEQdnV#TdNZhnB=9dyLL#8u4PwLM4w\Wj#nFB^+y=mhb?I*eV*BF
<*ZaDj 95yLX?T%T:q%+MDZFERXPj5yGZHBpYb>bCGKZ*kKTSmE!!B$RIcD6GmhE6^Jllu+FYhWSKlW@AHV4?5h
?YBP$Z ci$9QD>qB6LYRQW5a^:IH@#NP+uCe^eE9$QiVPhK%V1wlD#tPlT<1SIdN&T9SZ@#8RZM6tl?R^ycyFFJ
YYduZ@ yp?lDmclI/wnmAnV^TBWM!ccBkW8b@8i1IHw\/1NIMeeWcFl+BJ!Nkm9j1iTl*lL:=?QXtbYTb=E$Ei9
Kpd\Sl jWZ&Tm6FuE^\ulcb*??c1CBTVbEumKPZnyye<q<C\%>t:#ayQ:1%h=6YT1D<&!n6B:q!LklQ\PeHPDZI
S+R>hQ !NTiB/XWJ#mdcH=I+cBB6+T:DQJ&L=$+?C1p:&QXZWH$96!1SVb=DbGS=l^6qp*tMhFQ4$1AyGtRb!lW
R/1Ci> !1VT/TTQ!cI4G/wL/5Di@j9P*&GVpqN6!F^ibLhamlkj9Q<Z/RLHTL?CV9KGLw5b@mTpD\pDK\kn@j#?
KtthC$ SjjyWEHH*J85+n>uhyF:k>MG\&tn:5$%GyVS!Vi8M@8Ki54??&al=Vukn6Qc^9t&AA>CyFQ6MjiB5j&H
cG</YH HL*8Jpi$\hjHtq$/FHQK<Pb9FHJ$SV*%y/QJlc>G9C4qkd<>j@Z@+NhT?M>c+Fj<B*/hG#=6$PX+M@dK
NA8Hhw ZijZ#h?ew9B#lEqZt1++&eESuu+6pGtj<ejh%4\JLaDy:<X8<n&ikNmB!K>id5Ry$B*P+!:dhmB98LL&
6yihSj yT+@N^*Xh+^6kW\:wc9H@#$udl4!awq:uK6$/QC9ZZjqmnX!l@8dcHwh*FE#45PqQN6l9CKbE#4e@^@i
nKNmHq FHA8?6w6N$*>6>!$%A$>q#^Hc<m9VBjQRAyk=S5/Ih*i%?\@i8hwGJMS+ZEbhLhAGQ+?1+WeDww4@X6G
pT1YEC wpBP@t?pFj!@Sq4tH8pplh986E9:XbLY$WHR5/>h%CpK1&L\Bj+KWlY=C=te@J1<b@+Ji6AIt>!mT6^=
SSPnhe /ZeQpI>5kDY*QZC@V\I&qQCepLQF@^$aBdItp9Z$<jD$BitBD<VMdu?1K1JFHKiDwQpuqJG$cIt1y/h$
:4pVQC 8NmR+VcS=y<kA#YiwK<<lM!d^>^yYj89bJ=AWI?yQ>eC<$GQG5AX4/H1aB?<N1CV8&+klcn/yyuaIimJ
p$*AM+ 9tXQ1Zwt*cKX!dPRIaqRm*S/TWSBh&l5Juh:aBauj@VwhyA1+V%%CY^@Q>cZ*%?D<qMCCu:^JLJSm5NY
F5EiuW WXWRcdY<=mtEm1nKXqqiYn:Y^K>TjYRWhG%BkDiDu+CEbpGY+kFwEk=S5*wQ$ZhuqClkhNHn5Wj&LFZq
Hykqq+ L1lFbuGWn!XEK@?1C5+XR*NFLVTE9YIWn5KGy#/:ANH<N1PB9^T&uc<D@w>:9n5khuTMu@!&?NlQjEkk
^J6ZMA G^nkQ?&EL*j:YdYkKmtk+\J$&C<T4QL88/1Vk&6Pt^%lEuM?M/1Di$LIbCB4a+N4Seji8cl^*kB^PIkJ
MGF#!m ikd^<\#q#dtG/YTkT<=GF\pNEym!m46i?A*kd+YN$D+HeWGphAI<SYEGjBCTBh/A=HakyaD\wd\qeM>M
+Am9iW diN\:SAR$4QQm@Jk1Q%LGX/^c%kSAcp:TacuFl^Qwj9$G?9Y%!uXpJRM#yjI+!put+Y$a8&a+564$ZXy
9qwwBB $>1%p8jcy4X4&\G:Nn548LQdK+FC&u$T8dA$Ska:S&>>j+6GVJ5N6>Wk9y1JE?q=WW^hFC1TVmp99l$J
6LIN1V Zl&bnSW+I&#lSC>N%#i>@Q@^u$IWcCJ!1\N&yV@u9QC=ecl6\MN>Z1N$8k4Q:t/uq>&IkBq$1yukb&n!
5n+8Xl $*<?Dl\9ZbL\LPCNSL1QAj*LTpWN\1EyL/JD$nPXVXF<4lq/<4HZ:#8>yY?PBBnti8\ZC6VP!aC9kDVw
E^>GXu Lc@Yk\Qq5<i>nt:w<S=W:^<VIa+C+hqNQ>!HLRE^G@BGu8e$$#llI5lHN+F<4p8myGa&dQNj!+<HjH%J
t^jWW^ /D?*itnid<</^@QlkL>PhIbC+Dje6>#*i5Tjm\HJ@@FCa=P@iI*M#J@hYhEEQ9mHtBaKRX@Ke64NYu#\
!lDV/: 9?YZ=Y/!S^9$QWQt?&e1m>I&:bS9t8<H#X=:Bq&<>HK:m#+nPRHZiR4ni18$m*adH#>1=/Gj*u1#J!/4
aV#SYQ mN#A<nTE8lAK$*I#?1F?de!&5k1dSXeE?MB/4/MII9Gy$CSl&cj>apF*B9knbcw+<umC^Y\>/VWhn8wa
8*keMM 9&eR^tTD!FlH><1pEaBt#8H+#CeGWm66\!^&?#Gj4+bE?&m\bq\684<@5iWXqhidjMbN#Jj?Y!Je+TcC
Tq<y$D >Dp/TH:%e=Qd98=9CLqhlKIi/Sa@TdpLA@W?Q1L*YFZQbj<V/JY?><:<X?S5u5cX:kH8$ju4edbb=KSt
+4eZkd #aQ8d&Kw*>yC9HjBuXid>4%cmR$JLcAy%M1#:8Yy?+<RZi<il#a+ibaAw*Xp1KqXkZ4!dLMb<THmDYP8
Teh\9J ::>Hjuc@<#?5FdDwuB94Sj@G?k**RPkewnw?:/y:R<?4MlD>Smu46ww=><a%@qhAlVRM9<%Et>yeYZuY
mTYya9 h!:\*nPY1nB:HE4RY!yNp%dhWPqhA>q/yuY*@>j>Q<YDAn*yj6iYd:9SHJuK&/@?n>!#!4&M6MH:6JFX
yEC4V9 KZmy*BM$j>Me5+w<t5$Gmle@n=!i!GW!wFED9AF\JnSlAS$qtnwHQQKGLJkPh\GF\$nq4hBEG$$nYMVw
TY*Fnk @E=A##c/&iTqAB6hPhlcpKX+ZGyBqqH@G>p**enTBq9W9K8!1YKmywmKtG<y8yh8iqNHNaG*cL^c>TyW
>%9SyS DqIhwDXiWy%BTXminyF4tC>Iy%bKe1Xk=!#tbN$JlQmQ\WmpS<t=tD1T<*8PIjWPKQwJ4RLyqdX\H$HT
#h=wTM H#wQd!Mu9HmAGD<eC#XCtX+ujA#HBb!#+!ITpX@TPL?Gt4AA+!ZA>@NRMiwJt^PNYnn#ElKb1p/+pck@
wIywFi kLp>iq@e+6qN5d?JZNkkw!4Wl1?9jiEqDnewTy%T@yDm&wZlWVaqF%9^^m%*iG@8VT!P8Iy&MJD&CTJc
?B</<F JPm8wKapiAJH>891\lRJRcBCLCa9c&F+X!G<Kel:!mty5$H^CBtwTHQp$Y+K?9?\>!jkVSXj\DA?>!a*
VL>Wpp p=9pNpud6KW6NC&qqFKk$LIIKG*bwWDbCklm6>AY$wW$bShCKXBY!:/I!mwIKMm8w4KJmFABASESRREB
4m:%=i ?YFBSECY@=!=tT^R%Qj>j<@#Qe@*YE$8tVq#b4p#b<+=e?ceKC4DLE9dc*!46S<S*<P=tpaehDP%>qBn
A#Y!1? M?+BQ9?:\eX%YMmtl<=VuIT6?B*=uJtI%wTjS9S+ln4jAI!6FaLMPl@n44=6P<^>Hj:hM6:+%V#?%TVF
E:?L&q PHR?QJBVQMVTqM/q*E@GM%n+/ZNjhByHlVT5=>\$jAAS%GJXCLLMMw+L=T:P+\+na&daN@TRmL^MWk%b
N5cVBb 5E1B5q>F=tnH15E4=/DJGXXJWulISyc>YMe>>9NV#A$Z8t9SPpL?<8ek<RW5#eDL^Vi^KcT?RlpSy<PD
qIy#qj *8ZiR\wiu&/B8Z+/</:\EwX+nbD@#lulF=wbyMGYn@pal$L5%BT6XP\dQ4!^FnX<YFZH?FWeXpdX=w!!
Jb?NP: 9T4h1/E>^W4=hW/i\L?p@Pp9dN1Z++hM\<J/WA>nTG:\Qkj=kkG!KEyQbP<*%eKTw=D*9VGTM#=<WYuH
i5E$Hu $#pFJ!t^?CP?^*XV^8LN%PkCV5l1Wy?jyQRhyZNwiEXL@l8B9:cHM:&KdYE$SDR5<Z&IRA\WBFuDjEZS
k@=WTX hMj14Ww8/DJijIidmmS5ek#By5HaGDpJ>j*E:+bG$Z&9e4\@4:!AX&QVh4*!I:?XBnYSV>@\c<A<4$Ch
pnRjy? 1F!RP&l/R%HL@QQciYknnRFH*khWllJWNH5MG1MeMKb5jeR<yQh:aMABiF<FH+FN=dq+5K+^qu=b!aP*
j?/qcn PBT4jI^*1:F^l6/<Gb85lKw$w=j\XVt^=yl$cV!YAlIl@MBlFM?LpRiR6da+byKTi=ep>5ZGnj9>4@ZH
WbnVeK yym@FEQSWL8@m&51S/RyR/EqwDP+e/5N>^KYWHjC?8:nJCMcEQcFc#5tRI%^w6!qReL&pEGuTnn:WIZX
j^?yl$ Q\B#@I6S1qKEye<IZ:pIqKQCp5Za&Q>i%V$#%?c?+eGJMNQhl%ZP@!=R1\8JWu8ChBB&9y@lR9DhT:%R
R/8Z^N &CaYwKR^!hG1BbuF:1:1i/61!Veb^wEud=$MN@a<bZ#69uDu>C*uj^j45:EjSIaGNXM:8:SyZ:</y5ql
Tu=cn@ %L$Gyi+EwW\iuR4jXl98VXYwFWj5*A:P6q?qE>i?F*HJhAPdyu&8WP@lw&jn6G*K>AB@aVjC/c?dy91l
iF1Dn6 XFD%hqhaPViL$\\SnPjIS>:wQ9ETRJi^nR+AepXTNTmJj1Hu$!!F^8\Khu#>>X94n9+J@&ES9lYBl1PB
-A5tNL 0006368242400110333 Page 480 of binaries1.zip
tQbXW= &wd8HRBRwCWm1<n18cP/N1<qI1E>J\qRK^cwLyiq%KEZyaIhcS>9dnJk9wy4>YcHe5PIai+KqmACJYkE
SW@=Hc n!*d*bP*YE<AIJN</J=hVLhSWW/lw9Tj/m6*D%pNM+$6XuZ5tDCC^^Eh@eZY$Rhj1NQSXSGkRQNeFd*l
9Pb?ww &bP*Yc*#NKVhn\nRWMb5b:KWGPBw?t4E9k<i^>*JN?l*@:tp/4Pyu#S#XRC+WWM61/DWp!hd#m1AjDTB
qM%/l4 jQXpLBQkymqS5LtdNd9CDy?Nm&/HH&@YBIi?@Ac*TDlRR>@y5^48IRMet:X5X^:n^WK+qQ5AeB?AkQtn
>qE@yL 66RV=JVq%Cw?kN>+aw9/J8=%I&A\6pP<%Nt:%JIKT%FSTZY@^*l#lX8L9FqLlmBG^#1&#FPL:NJb^!AC
JW*mwm 5IB<l5q9FcH:TC8uWDIZ1w&@5iFc!KP*Q:8<W>kndA*eeNp+dcNJ<e/WW<G8t1CTk<D1NQdYI5Q*Kqd6
j6mu:\ RRIWnmTBcyGyFl51CZhIM8GPXV\&qt>et6m!?e#qni9PML?I8jmhdy$:qP+q5T4tiXY^tqZSm?DcBqXp
<yRe=p km/M*t8BFKkC?C>@/dGj@/Ma+&#n9jblK*=4GucLP+nh#DtW98!1+kP9K6c\Km+VIA9!EaCLp\uFNyaC
lW1eZp <1D=yhn*%/!X6p5j%MqY^?nS\BJ:aZ/GQY>=XwdXP94nQ@DHj>V=nSQIQ/^6PXjN6NcFQ8^NqZt?1Zha
NnI/8? P^bCHhjIl:I^aD>9aTuS\LB>LL*j4@KJ@6&*k1THT:Vu%catYV/e8kcuEQ>HbH@qVSTuF8j+%TPew5hS
yGqXV9 BqRcnQVPQ1N=u91j6c#taJKQ^8uqacZZ?1BTtkJ9:yVP=$m4bSQj$jS8&81T4$E<mhX9N>nM/S#P8+jJ
S#L?j5 pqqw\A9lH/pHNpbN+l5tJDS5&qVh5Fu#*VXh:cBX9KhuI:DKe^G8a?&AjBStEKluWEyp^4GWGNB5F8yj
8/5H<! HLG#5NFC5*VTL$u@?l:P>$H>RXlTFaX\:dVGPX\hI6nX!NMLMWFt<Z<Kp:uE@i+Bhc1B9j8qZ8@?Zja/
/FytC> WpqFH!L!qWh6VyFeNW&BG%Dt<kDHC$MnqGn^1^GjB^6991SH?PRF@S#@@lh\hMi/S%WX4eM/J!X!uKIA
wa95jk D>E*EqJ*aFQ&1:+hn4Z$+%/V*Gy<k8//kbGJMm<=c#&njkD\wlHJp+E1in>pKdRyRS5hB^eZ#RmbPBjN
<^&Knc @EcXZwudeeyYNduRh/T^5h\/jZHITe^h=TabQIRGRFpAq+4q1ZDZe!y5aK$wMILA+C8k#&uRh4L:95lT
%Bpabp RI!wMme+&q@i$L##m@ZtFnqw4C=du1dY8@NDnbM9ch?=K6uHl91tnPTqPy??cD!C:+mq:/V#W*6F?H#T
%G1Y>* bkNj+ajtwAWSIdH9KBK^NBKdIn5XCTh8Qqb#hZe$8b&y/^nL@XHpcm/$JN8ZDhMI4&Hc!IaJAN:%JaQT
p1ZX^^ upbbS*JL*@Wq:At\^5j\#FPGQ<T4*PdWiwdTca@18WeDTy=%wd<niBL4>%\mFAEIcC9I>t9$ZPBhpwL>
^<Lln& uK#It@1G%nB8#ecP?C%1KWA9XqGp*j*w$ttJ^p6FT>:t/qq$HdG@ThE4$D?+blKPh&VqF8bqYayu%KI*
H=$PaT cimlCeGK!9!eLFCwL4d+YF8Wc4MM5hl5Fm/Z/^E&\ZqymCJZPQ^qD8\9cj1pAh<?ZKhjn@5$ReIF@iM*
ui\<CH jP^eJGHFjy+w68MELC=P88q9/5nn#DH+?nY@P8JmZ#PckXiKH!DHTY\5^h#/N:C@&C<b&hjYiyHbbEBL
1CSFu5 WKJel\ah%<XE:$XJXm51HGuJNmhbe%ClLe?it\>dQkd!@D5>N!Z\q@#J&ANLJiy?/j#!Dk*cptjKL^Wd
1TTt*^ Emu&T/!ZS81=lW*TITcZWBwi4%Xm/c$jDdqaKi+>FMi6^h\dT:yyVS$Z%X4k\*%XcZDEaPMGLC\ew6XE
KF#uHR @1?lw!%P^biwa1hXTWGtLc=\tKXkINe!k6y*\&&\SH<!FZTJVkF8m>SBQCF5\$k!R<S6<V:C\Pyi<yhl
eDk1h\ +FWmPI%1!VqVK^Qhku\JYTJi=@?!IL<SLLRRpTCJFLchaI:AX:Ah#$/Ehl4j$1IkJb+8IeuK+>1ww<%m
Jum%\A KeD^YTnQqtY%FGMSdeiHmhl9^RmMWkt=EqPHauGuL/4$JjIu^J*n*5WtNBdlQVkcC@\=JXJmW%e5JqeP
A5N4BT R6H+ATEE+4/XSkNEQ&8LPl9AC\Bl=5<S?ay$4RXn<1B#TJWp#\?D8bandR?I?b4Fi=HtW+PyHbaT\:Fy
6m:nlS NLb6IK@cEkbuY9NlCKD:==PRW:kPDZLWW>!98L6bkW*Jt^<nW%85RWaVQ+4nkuDdpkI:5yWW&!*bQDaV
%6dhEm /h/$9Dbu\H*EN>ik<%Ht46Gen>Ccm?T+>$E&RX^HLJ*DJkXlb@whStj\iy#+GF^=>KmD#lFywSWjTHaT
iuZWF& jpkQ<Kh@GM>WI^^Zu#P15cT8ndPde1dGtQ6wbTw/EYm8le1+X%@nPC&CT\58yTu$FwWtP/i4up9ZZ*\d
DN6QWN *<V?\nWj:5\lDq!YbYG8ZXlj65Ghl\LDp?p1:aJM*BH@9ccXp+^9J8$Qj$BE4%+tQneP#Dh1<y&RC1Np
aIlLcH ZAAiD>5yR?4NyTi4aCbGK*#dIhiKXuIc<<1JKMNZNJM**TEM*QWAM$64CYlLlqY?#L4a$b!dc&8AHJ\C
@R$&i\ CVl8+nJicIVDSE*hPZ#&WF:5RN=:*ApEq&bt+W:qiHGkWYlmNqTT\Zl=yG<HlK9Ib9<iq9cTLZ>bTDQP
t/=?i? VhHiJ9Yknt*bFt9^*GLjb?RV<6Ha6uJncE<CYEwhikM/&DHwlZqQ>AuG!uNe8@Ql::9b#a:Rl+$8@GM<
S+1TLD tblNDQ>GSAD?IJ@PLMV+YJbCnSdY<D6Y:^N*?GWy!w&tZY<4nGF+cMy$:q/5d<h?jIC91#KKJ/1hb&X8
9@hEIJ <YM#&:wAwLChp=tt:^a1klR1jwRy%w?8Gq$qnnb\Q+>PhPGGWtm=F&:ZRLt+R5lH%>w=P\K+C%qKFKmD
Ejlm^n Sqj>Z9X:14n+h#ji=alpB4eZQJT@:nb9aY$GkHHpR=p6tIwWJ/VEkRB\ku8$<wq?iZ!j\y!e:@\4FaJT
yZy8P! @HB?:cZ+Dl/emKeVih#/J!?mjP!ZZYnuqKcb^l$G\>C6Cw=MWnjZB*Y<%==6dy8>>5/6dP<EkNkP=J%P
kMBSw/ wQa\\G*SqETuwwWjQqYcNMT*w9eD#M%aIeTeL^JY&wVDh1EMt+Y8YGk/V8AD!T\&BiFeqClw$peJi!cb
F@Kn4< !HJPj*i1TT1yy*k<y5:ZNiLIR9Zahtt4Z8uA^tmK=>l9a?&EjLTFjLtYc!^LmaK4CIq*/H>qL1!$\M<8
RkL$6* 4F=c<i$M/<@R%$ahBdel^lcYRw@<#ku#9@?<!bGAGeK*K86!IRJLj?Cqk<L>B&%W=btMa14J*R8wK4$n
?cy$+M G>>eL$q9B?5TAC\CwPd5^uMnPWZY>A%RhSqZqVVPwMH9a@58p\6*PmJRl#1!9p#$tpW:&T\CkKBPBHp1
NmRRTE t@tLuCq^kH#F:=jM^1*>5VBHFK=XYc<q<km:%jFR8HMu^k!Q<YKGh:Fq*buktw5/!R8A:m&Ajc/np<^c
qC*u=k 6Xd#Sc*8^djNKMm!yFmLJ<j=BAw%815:KHHpYLjJCmDbD$lpu4M::<F#8t#K>pM@LuS^$mR\:b$LKZ>&
I\akFD pkt4eAe*8@Q6Ed\aG@tXM%S*eNkL5F9%J:lw!VlT5mGaD=qnHB<w4/@#Yan8B6=Wu#/8EHc6mY:@5mu>
SiV>I$ Hi+M@8kRFlQQ+yeJH?SuFla8Q>Vy?!D$cR6n?NuwyQIA+!k5lWcKJu=cn>1!BS?TFtFVNPcGNK%yny@l
YY6Akn F>MQTVZPaEj>DD5EWekTp!#wCl?wj^mKVySn<X\DeR>8<bX1e6Mc$^8yJTW8C1uS+EYDPD#8N>Q86$Rq
ZbJD!q QlPLN@?1cI:1?By8?lpC5BSpXD:GRkj>B\/Delk&ljBN@ZH>@hHF$>T:<Y%FR*>duJWQyHi\1LHwu@C/
nwmcS+ aI#1k6K+unm<>u1#bwNB%^?LR:/4l%V%/>ea5^^ZaD5/K&/y11eK?8GFiyw+Q6AWZCNba^4:y#nWnLu<
qbKcQI ^4%JH^/eEju:&In=?@^>Q:hNQR!nEZXq4&1%y*n\EZ6XSyKQ!5kZ%jXA//BNNAXi%Z5cVWdYt8!kuh5$
LM?\S\ yX?JDX<8V\w1LR#jb<k#j6?=wm:*\bppd55*na$GFbaY>ucL^^V4>1=5!l@!ZL+j5/1*h!WnpJImWK5A
KaSCAH Gk8+nKXRFhA/:WZ<#4yYVhby?*AQy>ZwZSq?=1^TjHNuTGXR<8@la:Ve^QE^!SHDl$*H+4VCpIu?8EnJ
EG^F?P u>hFBGGn+YQMbZRRc^jb%IYFR%=c/bacwW*w6SVY5GGiDh9NG9bcCtuGVkLWEnpQnXNaTlT\wTP$k=j<
@E+j4R ka*n\wZ/8:Gy:^t*YwYY9J4mSddaYuiyD1<mAyDR#Wt&w1mLDGhKQhlS9>iquH$ap6LJWq#<6p=/KRK4
?Zq5jw P+X$!>8lM=Z8^^bp\!G>CuM6nh!$C?1#hGP$!?FF8#=q6A5A6kERKPGyVY?CuCJ41Yy1#9b:$%SVW:ay
M8%phd 1QdQln=<+L:Va&6HaPPMn?5b@BXd\u>^*^wBVJi:MX1##I9YjPbT8lCkXNShXqLSY$bRic1n8#!6#86W
+y<B#h ah?etGki%4&\wAF1Q/1w$GdQ!M!&Yta9N#ay#Q=eh%8@TXy8:ya<QNT6ewHYV?#P^9a4#+%tD&5F=KPR
4aKBY/ HkJX@%PJPJYq^FNutRtP@*&%bX1h%>994bhpT5Hm$hmJHS58jLA?<lZL\yIEcZ1B/RK&<+G&#IT?k:P#
b<dJk@ %Z#kphV$ZC^GeK*h1k?wJKWHG@D:Zy9^Z6i>GRLku$1G/SA#n\6lKT&w&1t%a%Pd#\+:8849D=ecVd:j
+\dCR6 GB>bZpcE/PNX^8QytD8YS@l4:5VRnb&Fwlj$l>id41jjpPKY/5&w@L&AE!<MY6A>MAmQNheMFmM/86tE
IBbtHW FEV1cJ@K^tmS%%c#n^EAANlAQuRny4+K@J$y1VAZH8u&@dmq9mEqL#?94/wT#@D6W:6Nk<+N>IZbJZ#Y
CF<lIA !\4Vc*lkXwcnCD^n=>tL@eJd?@!KVj94/%P\W6l**6$a1PaeTtZ$^?bJj@c#qy&Dh6V5Kel&WCA:d&Ay
R:/dJt 5CuXtc8&#4%u4Q#ES*DWGcK9cq=ZDFY=V:nQ\ZB&:<u/t?8=*k/\K4wnAnCbjJw#D4ptT/pD4$L%PB>F
A9CNTK B?*GT1q@H8I>XG*hi^L5P/4H@nuD9kN\@a>ln/dH!M+W!l<jW/R8?XyT#Pty5YQ#q^y^>WuS9ZRBic%i
^\IB+6 dCaN>X1/B>pEB+B?AQTC5\KKuKSewMRny?yD@^^DiFTI8A1QiMqN@t9%I1$9:?XF/ln&L%lN=akA:P9q
9hheKa JHZ%1J4TtWL9T/%W>m4=hqHie8+hQ^hm\Qt:1>HD9Kc@m>IDRIQiTEbM#:4*$bSEKyckDb>^*=!SjELF
aJ+5%X %jQWb/4c4jYRi1Cp#5HR@/:!HJM9&bkA\KEykq!mRY?=BD#y*hclLLZI\iV@TMhJq@>:jmqGyR:\^aj$
Yj5t1J ^8FaYBq&lMeaheBG\85mB^Hy/$N5kL^mP*/A5#F1bT&p4wSRDkd%B6\EtI*6j5#$*!Vj5SjRC1nNiSp>
MB@kiM bpWYQauQSy4$SDRI&@F$&dWTKLtL\QPAcmLRRkj%GPjHLTnm=ymdkH5B<R\*BqZmEjkMQ1nGyp$1>A/S
NdiWWS XJZC8VJEYA/EHa<^5CNwJnJWatFMKDJ&CiH4LcA&lDVAA#Tn%WVuih+CFMp61MK6&64!:GV#!M5Iw%iI
a&L$\F \TaeGwBiu!kLB<IT6G*^HtyYY+/=wS!u\iX9I4PalAZ:RnRd:#tG^SPeew*=BpJ\E68CPWX6BXm?tCmj
-Ah<58 000d2bd243d00110333 Page 481 of binaries1.zip
y%ZMcp RB5I^^bec4SVH\9kjM$Q<bMtl+P:NVJMlXleFNceZdcFt6Fn8iDLbQWENc>1uq4R#EAB+Qn:C$R!t=aK
MEW1&P <k*qAlScWNY5!IS/W:$I>a<LyjNLE?Y/%/Aw^b11NcqCMSatlNEG$neDGNcRD:$w?\N/GQ=D%R<GySne
SuWN\A *NCBiR9MJ>t@PpyqQCa8K5%$/+em+\@*PYMcN=IZNtMdhTjRuJ*LA:1ITWI/ld>S%Z:QB!k5pepE9=LM
FCSl&C #EqpZ+ZM8X!Z8det#8%y\<a%PQyiM1I*\QSWFV8JMN@p\:\!6K^%K+K@=Z8C?#%CilFlkbQ9MEKqtRD&
PwHVn$ QjtC%l+#S#pKJ6jtJ!5+*kB14Cq?b#EZ$PyZW4m<D^EL+nT+uVppn\ajqjWc6By6GTYyZhAwbB=XJTcM
KwXI/\ MqD?A@T5*!MC$I@p%+iSHwYtn/wcbVD8caHF:@DkZw1^SX^HM%#bCE6k&pS6GbuBM!nGWIV8wC9^h=ad
WaYb#W l*N1!Zm^p#KMSn\ADRLkJATSXu\BDFSi9Sb@Q@*Z&yQQ?F$/EC?Rnda<5mkKe?9!qTqtHSL+4$ZqP%m/
XPBG\C !RhPL9YLC$w<k+Z@QY4L9i/j\EaN/p!aVIaiS8*NY:j>c^9cYm$bb:ul<5!T:aNIneMtP$>b%1GZ%q+R
WjHc1Y @BR4W^@+6&c/YaIC4b*5XC14?hlJj4hiEiJVLRZbL=qRTJLNplE&n9qyGncb>LZ&FIAq#F<I6!npq4kP
SL<pJN J^w@^6Ip>KIR5Aid@LE+j4bRJkS6^F\QRi^4T5Ntdmp&9da&k48SmLpFjGCVqpLDBB#b6E=qZN\YE*ZC
ynL%1T Bm%bC<nVynkHe8iFGmyVqLE4S8LnMB9#C\F%H+IRFjR58XP\w@i&NW@$dXSht9wKn>ia<n?5M<iES%#:
n!l\:y wLH\JXIN4lVTW1>FLF/K:@\k*PXNNT+L*LGtu65c%Id8V&Ed\*^QS5y%XSu!$cCyku^WAah@l%lKFJk&
:I1Mm= 4EVGqZ9T:5J@StWZ9#TXC#&WuIYt5t&@9/iE?BXDQ+9pw&*VBPTmSwAbZbVSw=Cih*9iFeuZEBihwTX1
GdZ+LX qNM%1pKR*=#h/wbT1R+=m?S\Qc?+XmwWtF48ZKubj@T<$wKb+cemp9WbFIKpQ%WE+<EYdHyQLTh9=W?K
TGX8G1 pd!XSlk!P#B6LBSCL$/n%RZRqml/98PmYqAK&ci=&*uFSStk#DdHNNbPBeqMe\$dFLp<ndHX?X=5>SEZ
t::\%% Y#$NVtTuC>VIuScFMR^*VJeue1uKJ#N=TY1#AbjhEk<WRd&t5:i>\XQmPi4!lD1hXH!EAI%lp#/eyhRF
bRuJ<i =:cd^jZ6Nw>ih&jhuT%mkAti*EC*\V6kS+?ti@FJ4IyKX5WnRJk\\<pu\W5?\qKmRNwd1Eq=?jDB98@5
5GL=T: FLu>dwEK5FytMGbkyBi9<dZL\yRAdJlBpME4w8djCVVF1jjc4=tm**i+#=>>eq1/4^>TyPhtCJ+Z6qmn
$\h#ae n:taW\AKt!uITCq#!qLwItmy6a/+$P:i6KD**anQIRKTP4N/uiF^^kMD\JcbVy$l6dwMe/bRK?d*6eL:
P$KyNc **@\J@:k#/DED:=\H#TT@J@SVLc$Wn!Z%ktZXk#RQy:65dSwSe%u!cPlZ@9Z&4@/@6G*^LY!cIHCYjK$
<%P@G> XEC&c&XBwZht:bG#TM/9:n$RC9^AQuGR>hGD6d?/X6a:5<m4MM&GRkSJ*#@Y@8XcX%AAhb56+<PVhRVq
RJaHyt X/=hGI4Me<^tqbGY>N*81k+KHb:6&bIE=ql1H5tC@l/DSXc5V4d6itPDl?4$MMq1>D1dRt1N=^V/lp$l
?Fk=^a AND6Ii%8^!=/AMdm%=$:^BH6PDFmkkcF6!uA$u$8SB<b!CuEQ8Bd&9k4q8/FeFN$XFFAN^hA69L%QVID
hZ^L&E ^86^T<!@*k!S9Z<aa:KLwV%TlWCXjcl&pcMZ#!%Dbk/>#t89c:qR*4F/$^MPehGPKN?hldF/BRJ8qZ?!
KSc8/l ^CA8cuTEMKDPWM<t*$GJQunK54BZGZFcCbm6BHMZWD#Y#ucpDc$c8np$^iE@%JF6Fkw#!Td4tKt*RlSN
lyCe1k kX5qlk%uHadt@FCSKLjyT#V8nT?49n\YRL:mVL&@NDm\1R>eJQ>F4#StDhHV8+He8bBZuG8bX6q!D8F/
@*uYe& RA*:NWyyic98%%W6l!iEm#Y@LlJD8ShCL<H=C5nBQ^DRYuMFM:ZMYeT>\QhajK8!c9G6^iHGD^bQNJb8
6CpwRa %tQ8M#+\5*&+Kuhc<I@I%Ih$&AG^d1bkR$mST9qHZLDB%A6LR>>N%ZKSB@^d%$Y==+T&*hBJ@$=aP9XD
ebq?Ab yQWPX<hpKK/%PRtFySy</RKna$>cmJdQJXMF?nmYQ#*&>6nd&y?1Au#^cB=P4@#^+iAt6q%J*M>IneZF
dY\#Da !TF\#KwW4p^MBc$6>bFFYp/t*V!Bt94WQnQP5juS:WhdE8J9K?al$+SGy:HaFMeK8//d^jk4:Z#Fa*WG
Y=5J!# eic9RwRtju:$^B9WL<9up6i=cB/MNCF<+^X9nj>>@Djt!:iMa?K\Z*Iuu$dC#4$@1<W<dE\1Ty1e!8*Y
\qZ\Cd n&TtSiGpqM><M5#RkV8KnZh?D:##?<DdXaa8SidHYA!?h$=%:86aV4pItZnLd$Z$Pnlq</C/Ka:=hF+k
!eZN:4 yG!&iNkhhLLYmhKm%Q1>pVW9&&J4JLWLu?C:HZM49<KeR@?HwT#PHyRVRi>m\!Rl%TIpLyA^NBmq@Puu
E1KeHR P/NPNl6=4FXuqF>p#e9K5?NX6>FSu$dmntH<k$^NuZ1clR?c+LpXk1tiX5XX%q:=q*<8G+IykG!+E>ud
QR=#?5 j!q@8jZZydHCk<%m!<GCR@\B9+^\%R/F9*k&1<+dYW*y*THa<1B/hEw8>nLKEpbX@yF%Kn4#8DD*$wXW
&#!L@< $?cIh5LQZ=mw%%u1elR1TF5wwD%ke%F:^NddVW/*cPnwu@B:aGlVFjhHP#\@$&eRZu=epQmqZ$dF6<*N
6dWlBm KMmJ6BT*udR\JFm&D1JW/^RmiCaVQNHWyck=5eXQHha1%KXQ\p!B><Q!pZPM$^cT%*1dkHXDbAiyQZSE
uql1%8 4^W@*d*W6qdE&Iq:hV>&!MMnGpt<\l^t9IGD<V&+#ClF+u&a6:=lH8bp^Gp64!^KFPl%Xm8c44XYYa@y
iDPah\ 4FX/cWCnhGE+qq+?1dTmRh#R#dqPd=!$^5<ZpTuSnjw*6Z%dNjZda^?N@NdS8=H^=RBJb:!?Xu6m8a$=
+\>EBk 8uqqEY\Gm\W/t#jZhnlG6LpX5e5@a6Vu<cdkk*Wn$ZSn1!:Ga!?$EYdb+kc*#/kZlMCiFm#TwS4$%tKu
#9uQt& +1n&Mwil*\e4J1l:JD=bGe%Q1FJLE#b4J1T8d#GBWnYk/%AQwc8Wc4hER:R#d/#:IikQp>/+4l<P?:P^
A+@V*N @dam@dk8t/9@w5:aB@F@NWd@X*@RJKkETLbdn\CyL?=lhL@IT:h!$tZ@V\DGAXAd=6Xi^%Jm1V5ZB&4!
b#9Z<F 4NeA5B5kXJn=BkDD&CtkDuCd<<NY<6+i^kTM>6T>uHIbS!EC<Aj=WH<W<jVC4nMqF6=8ISyTYFWal=FM
&:kC=l iaX#CB8#<G#emalbR8Wwk@5IDywd6bjXh5&Vq#uNcwN<hJ=<$aNBI!HEWBFNmcWZAcIe6jq4XXe4pHE#
>FcnW= #kaKdAnM^JY#WC:t?K^yBp1FeTKn\p4F&+\Ka<Vq<+FH5Nm/RSVKdWQYRupH%At*p$/y#XbKmHG6#atE
VZpa1I Eu8c8$d6JTPp*<jcQNS#lL=qdhanA6CJjPlEN%NuhZ9qqCmHHNa\<jke<c6\\ZHCDB5cZ@TX?\+=aB?>
4cd+i$ n*HWPX+e>SqY*&kC6At1ceaCZAQ&Va=>M4iWl/Jc=FZq^atlVh^H&SVylZ%i>1i5:h?^cm+A$5d:ujcu
@G^Pqb 1XRkh1bRKj6Dd9t8Y!6<?!\u&\+?@F&e4YY!k&\:bNhBdZmq1YM9>&pKXJYJ>nP&L>NVpZ1Y%bi=H/^8
:KDjl6 uWCWD&9MW1AnS*6^WbH#cmtEK:X>A@#e:\GKHhlj@T4=up$pAFAeeK+T!k9Qa!q%bQNt%bRy<!d+WeK6
uG1ZJX ^FXVijE5Nk$muZpDV?H4/6*XAccEA$K%DkVP5iwA\A=AmW/8t%bFW8T#mpJpLh\MJm4Tb%@^JVnT&Qa^
XeB<Y^ L!*e*wV*QDAHHG6eFT*!El^?aF\jAGk@J!>#CDN&64MWYTp#**Eqb:Z8ny@W4y+jk1$Su<HeCWejlZm9
pj^eD1 tiKelMacHIGkM?Q8#FL\=+IM$pm+5&wali*kJM9XtDWHCMdYu:MJ5>B#\y^uVY8NCMCK#<E$%ZpLZM6T
^C#RQS a5ED$GQq:eh*Hm6>8HVKGZ\eL:c@Ay=B+JaW#ldcnEnt68%Cd*FGZ6Ya+%Riy<P6wWMuZNZQ<K#?S%d>
WTRJjt Cck5>1Ak8+9wSn%kPFPc$LYY+Fk/@\>81aX!PMK8*w54ty9Ea&8W=98?A6>pp@8<G&y/=TBdh/Xi/?+C
HEka59 1@5Xk9h>hFBiHuT#ly4ih^!p=AmF1V1<FZaZ?i*En>@4tS%i8#FlcC!qSiRX8:5FKH+<!F:^BK>ZjJG>
QYY88R akBw<AYeEnlNeNH:NMWyG*/6jH@c8Q*mnn<WD*DA&qIHuw6>5KqiT#/^E68^8HK#?!4/n>Dc\X?\We#&
uLJF1< E8^?at5TAPb<+d!nSj&bN*Ct$LPXJawP=yFe*#lXp\&?h^/llcEKD<<iBGmjC@>\L@\@M@\A\B>!4k%1
6%Sw?6 *DjHtWL9MG$S^4^/REIK<ByL?A\E\S&B#%DmjRWJ41wATV\/^AnKeE?CewuXG\?%FJP9SPRWEZmYAnXN
Fk>PAG 41$ch?\peCR>BeGGBlW6h/GHp19h/K&i/C<#>K5B&a?HuFebRJhi#FJkwP4<1B#$+#dn!<uaiB%H+l>T
a6&+Ew EZdll/IG>GY%#d@C<B8?BF8KL=*Nl*6DkJ1tkFb\5>u5!B=/aJM\1!CPH%^R+cEjw!Wujmq+*h>*Lylj
J&%*65 ZAiNALV9T?i=FZZC!XKm\e>GEey6?&:wn+bK=Tmlj?Q4\<*8$$MC<48:>eYi4d@189AJ!JwiFqA!$>H8
t=XH$u a!p\Pn<$XE*994jAeBqQn%MXyR9:%Pa$6j5E=W8kcIi4QZm:^twaR9LS&5QPD5BZW=aCNZSdwT1%Xht1
#WLA4y !MduX8%SyGeP5=Eb=VXF4:N1ACD5K$H&eEPZ>qyuTlXk>5NnX9eP@%>k$k?y^ni^GHILKaP\>NbF>Zy*
q1Jii^ SaACyZ:FKm4^%Cn>/9LD<lXb%9P@ptX&PqBlLKWiIl#iiqYb:\d8:iC^i+SR#iBB+S+WEXCn#:@!ZG58
RdTe?p @Dea@5<Bt*DEPaPAK5%uKXHkVGY:&D@#pKu*FM*R$q?W%$MDY@p%L*j4kV=HBH&#I/!K<X=n>V<&XkA\
&<pp:D /akkE%\/XwI#yRytcS*Fti%%@G#tFmqaZSI=411J&%XN5!PpLh6e?M5>mjyNX6p&SAC$S\Yb<kHdMatq
ZG=#%w WFMDH@W^u*6e*5SJc5!%^tLyc%46yLn9tl1!wpDQaRD@QDFcD?>DFF@4w==cM*iujtPhAwAJ=ENbBiyE
nNH=H= Ri6MPRdd/pJ%>%>9ZVRyJXW@*<>\:d^<S$cPBciFIF=!d=tAa@NSS6!*<y/MRyZ4/k$BcHJMRQTRpWdd
E=bnWC k$18H^We#tP+/+%V+SC8YNI<cp&>EA>YG&6#T8+uA@ZcSt?5A=JXaCpdVTY1i5L?ncZ4yLbJI#L!#FaI
+pGX\i F*bQFaDLlB&#/+:A*PVQhWyV$<t^h@nA?Lcw^Gc#FNm^pa?5e/F?b1HhZymYH^M*XZi&wMun>1m<J=Ek
I@l1e@ <jw8l1J=p6mlKEq+^XCP#VuaJ^ELZ&JVnjj4GhY%<amwYk&b:9k/hQl+yhNK/naK9Z*MFICq%%HaRGc%
$4Vdq$ 5a4p^u:66DndT&4/!6>wuShe$W6K^ai+?yyDYP#Aa/q$!CQ6TV\V*\:4LbS$T>6E//D^iAD>!+/9=V4G
-A\p:e 000fea6ce9100110333 Page 482 of binaries1.zip
cN?JeG eu#C&PQkDj>/GDWLG$CuP5qh>dX#S?pmdbu@VdGyJHSXTcSRY*MbL%!H^e?9T!5@<?pVFWcFbCNXNJIC
BDlh^n J:=&Y49j=mKiZQkaaYpKqq$S\hX1REqjX\#IVdFcLhjkL>Pum$QRbJ\G%/mHet@:yQKBwm@t!u@BN+V\
wQcI+J ZQ#?Lq>$Ab5GR9RNZl>X*<%nEF^b^^mQ\aFVc^iQea56lc^n5M$hF$AeJ*\GJ>ei:#k8Z!:/SB8\19Xu
dCuSy+ u:bT=NedlDZV?9I<dyb<Ew<I%<b<Gc/*N9a6cJ#MNVI%>D&/C$&QMQCBb@hkaRaY9=6d6#HK!@IX#@S1
hGl8uw M6VTbF4aTXNK4VHV\+I9m1$5BWSw5&Xb54HKnJN^ASI$6*FmGWRImE*TGdi$&KZu&1&M8MKQ1B94u8#R
aGDnhl $P#ndLK9<PKKd:QJDkAuAcmIH89CQm8uLKjMct>%@VpVB!:nJ6a/QWR^Xj6a&%d<1Ell:H=a>!APG<SX
F<$J5y KP^FQ$*TD+tNip>!*&/pqRwuBA>9am+/?D64luCCnHQ/CjpcGJ&FJ+<:W/LA@$#<:@Dj49n+Ti+4kIlp
dLQ9?P #nul!ZG//eRhSmeARAjZ\F>t4tZVuTuW&QiIn@ny!w>8++>8j:SqlM@j!Q<MD=S&D!1p9knaG#>Nj>GV
XtbF@j Q>#*@%XE5qjJ>HikjDV6VHEi!/Ih%h$cMBZnQpV8ZaYu$%9@MXkpC\PL/HNeV1P1w#:$9NVnjn>B?VGE
:ueSXJ kHyYIZCZNi%nAHyMQ1:nl8p5lat:%6e1Jw+^>McXYJk@DN!!T!>n5RD#&RapN9Z#epaI6VZmXM>i6!EX
!d<E:> @<u/D\B&AG496L8u6hEWy$8Bb8t*>yRpq6w9ZDP+YcSGmEC5+XRiq8u8>*8Q9X<A?A=RJdDa!HbuC1W5
i=ke8> %%D4c%YQ^Z+eq*LY4e!ARpnD1:\Pp=^n=VK%ku!WSL/c5&BY6B=Iwbe:8*Ph86?1*M$N\81V&J45%kuR
XnQZ#+ kndi/#$\:A<ah5lHH=E91ymB9TYJyhTD&\kJ9D*lh8%PihqKT@EuHHejQ<Ayyn/:\y9#VWM?+n^iATD/
p6YX?\ qYi9+LHZK@mLXR$A8^RECE:ni5PP>BFLpV$KP!LZ<8?9%KBtVeRhNb4^S4!T:<*^kTb#D!KNu9?EN$*m
N5P%JX 69QeQY#1!>XBYInAA#P5lQ*MKCnJ6>n!p4QiNjlkw%AjTaTWT6Q^aN\K=bSamw9#CuLWiCkKRSB@IlGd
maqRP& VtHlm*=^p1ENF6j+<hJB4DS?iluh^5aE:lAK#K^Ca49KeD?DIRKd?p<\Q<dLqhlKNkBZd&qQ4!qWZnia
*uXiDD uYQ:pQWh<qGpWmY#@cCt&MXTwtCHc1CI&qC<#k>%da<GtH8uyuV8a$d6Pmiq>ABt<w^dBkA<jbZPBjZW
bDNBNm :hJHdHZ%JXl*I9KX/a^yS89b/TBjhcp\%1+i6*V@EV!FX?=TyQA4FGQ^?>nKw<C#YQ\A#<a/ajJ&Se*W
uuA&GL p*kdK5N^cq@\*:jLR*pC?K<1&j56<Z1@n%u*ATBYWMp?1inK*mtu!H6+4HLKuA8wFQ8A8!j5MCQ<E^aZ
?uk&// Na6W9+?*NjB*G*qCNc<IdHBHiA:8E=ibQXT#pu!%b^M*q1ZWk*Pc/:jF^1aY8uDSQ%!jbD!G4d>E8KXy
F6++kW kR#tN/+K9BS!mP&9*!ACwFPybIWe$I8XLCWKD9pClXY4=\1T\wE%YBmDh*\Xn*kQKknwCeXXXTiaeM^:
NpTC?q $I5pH+$uZ$t5Dl%LkjH/N1?1V?N8\/&hFSE@k8nuJ4EEaJPK9a^m4=jBe<:lAwBdAJVMapiNq%PYW*w*
Gj:+Ij Rbk>+jKYJ8<4nC$?dn^bRXkqj5R+6@E:qI:AdNJ=u>E4PPiASYAXpiZJX&6tbk<X$lT1LFMHP+w8LZ!m
EBy:B! ==JZjKjclp*dn$jqZqIk5/iJB8BA4&Q&Mpb/9t$qG!nIS/jIX\et\R%tKhFABF>Xqd=/6*huZIw:*eNX
@?QcAl CbHm$l?cdiQTw%!%AAKXtw&a#W8BIuBPXkAAP11S@DyAnKaXhFRu$q4RcXY&+9TXBF=Wa>NYuCCh*1pw
YbpWRM X\ceeFimk4Kn%CyQWa/>GBYdX/MRAhlNQ8&a<:cPLCWcbPJP8L#VL%Q4SCWpGD8iNEau?*c5//ykFFV\
WcaimN Q%eF+#\4\K!C@\G/F1JKhwnZp*1RhcbEk=*nJ*nqyuYlL@d!Qdalkp6@Td$DT:/wYdS^TahpX$XRB<wV
Y?M/Tj 9X?K5!a%i!q=ItuNJ6H=W8BE6kXL1RNCcRe?4eMY:QCQLEbbNp6YaWG^QVHQZtK*bEiJ4y4!EAG@+K1y
FAP?cH &G6:Fb%hwkASG8heynetN#qV1Jm%Wl!/<u=n9#JJNX5$L5L>%+qpL$#IeR<eqEi>Nb/%8Ccbl9WH<6EC
w9e=yM <yZMDyAmYEw>wNet#RnVk>LIZjk\\8q\&>F+W+&Fttjh%XAMB%*XiKqV6K\c!Eha/%#$RCWZ5BS/RimH
dedcee Q:4i:l1lhl8G$AI66N/Nh\/TntF6wTXDQ$d4dD!5S<^TwwAyGcebqj%Hqj>lZGFclT<p1dtK=1LTPHi5
X8ZXqA 8^1waRQTMwy%%bNmTc!cDTRjbiyWe1lLWD&PaTqReaY=q&N@*:WPu<?C%k1J&wwy>aYhJ+QPc%5=$4Dy
bRFEk5 SS:jNMclZP!H=mGJh+VEpw$KL>/4uG<MVVcF9c*h^aicP\th@EIMW9SMMS*l*ybmP^FL#ZuF8bd5p%4n
9lk#:F 1CA5hI+R5:RG556jcdy4dV%Z//Fl<\n=hLc?%LQ%Q1#%<$k?8pT?/EEFlIjMbCt\\F@M$1:8P//nitc:
#5AV&I 4IHd8BlyB=<&wNtM1YbnW<X$XPmY!ACNTYK$$ibFG@YMNywpFWyDpke^kY4THJJeq<@&XlM4>4jIQtM5
R5y^N+ SSjh1Cuc1SJ:%>M>X:mB4jCykQaC?R^kWpwcT+tC%@cX:8#9Fb@%VQuCb@191bddF>$ZGkA#M9yW8:Wc
c9&nT9 &TlBQp4#eY/6$H#AVFNI!<inmV6iT?w/6+Mc<V%=ki><Mhb>F+cAVQXlA:QEc&B<&eBMJWC@IjKXm&Sj
CT^/>E bBV#d\+bQiwuVV>VWuXuh<&VYQ*%m!MMC:Se+QYdkW&CBX<iPb$&aDT\5i!4\h!$ceNt#ee$eQeR1nj4
E8+quu YR<uiA/kH^6AM!IABiVVuaWIwk&CqD4R1pj+$M!=l+Jjj9N5y\89V:#b8$c+ei=qH@j?C@nj%4QhyN^4
nM!dLl @@Xu?!<A*AYkj5^M8$BPpbtlu*%PB8:Vb%!dWnWq@e>c:w8\WKK8RXYh5bcJ9THIS$MNV8pJNq=cEcSE
bTHn>* kZyqtF+=:i&I?M:=ShGFN99YB9P8%u8MDYBKQe#NwXApd^m<=RNuQ\JaVY<a!HD?dHDKB*AtNyTqSIN$
J#$RF6 P%<>H6@JN9uNuSDJ#e^!+Rc$@pdX5$h6=BHI6q5A/G$p&Nw\8^^A&>8aKHM@mhy^9Y@5CY<w*96bj&X9
6!:m8C LMjQMdb^XRBq!+^5ym*\ttqBdKcXEcC4mH#BG/cZlZyDm5Mw<<Td6j8+lk%AcYbJ@ma+SYndELeNEZda
HTZ4*E In9weGT?yp@IA>#KWnY1!JIX4e=6>1uQcJ6:BkD1G4/5k^LuPRN15BpAAPYpN*V=W/H\KmuYFaw=Vie%
PjaBZ# 4ie=NB%Cnd&^pX<>^SAGLnTw$yeYScR5>h5THi9+>w>QTn>yY64XmSIRwTh/mCmI#!B5:IMj+>$aVehE
8MFFy$ BmVmPG1C/>Qdnd\%GAtBSId8AQj?VRi\eTCuSd6BjD/LWXidbWTGNT>duYG*tJEXT<YICHny+G#LwMT:
F=+R$6 pSbJuaqpMKMXM1Lh&Ae:/655EN1:9wEQTjVkS/FXH$J41#pFCYbn<!GM^J%Ey#kE*qdLYR1Ne&?PeLTn
Yu/RXd d\uiCFXAIEew/cP+R+t4=yB6I^8j=+=/?weBnHXRpw9tK#&1DYHX%ppCBWe:qe!jRp%RI*wqTTa*BmL*
<=E1NX >^4t$KBTS?tVMK+lZu\PVAb\ASbGlcFKkmWhjJWDq9y6XdJyputMa&?Ec4WlAW%jbT+6SR+i@VV5+Qed
aH9/D1 np%#%EVdDD=p=!6T%SITG^1i/E*:5GG^hpq5Pl#mJn>+ubP8+9IQ8BRqhk#k?8Nw*A6BbBIn+T4WYB1=
XKYaDm maPAhL/S5ekaFEkEmweVt!MhF6:FH<ZF<TmME&:na=lD<*qM<P*Bl9HaNLW%15SDCJd>iCkY^!CuJ\bS
<L8*Nm mi>%+Lml&LT/#y@G^Z$=dqW$4<VI6BN#nWGna>KDJpejyMd/qTyiGB&Gqj45Cb!yF^acP:Ah:DCW6jmI
wNJB:w 8YyDAL=k=TW@BLHElXkiJ=:F^5u+RB!@@NSlND:B>@!LjI99$SjI5XP&%W6DQ?pH<&h\>#eNH^w8w6Yt
?u?FKE MJEVJ6%Dq#=HT9*!eNI6aTBcnY>$S/c*n96Pu5&uy\IQGt6IT*%<F/<!hI%4&VY^n:FLatT1int&Z9Kq
VmN<1B /wR9PQt6$bhJ%RZtcMj4m1MjqDyP/Fb#aR<#8jP6+*w1Yu:WXJFmXF^A6>B$9k<?M1j^mb@R5SuLBeQd
nR8$Xb SP!5b/mFnbbGjmt^C6QtTa$uey^lIDb><CX9c5P9^nhnPiP$HEZKAt:#MT!5#a6Q/Hu5l<ScDV>RlBlK
w:/SDw FQteQ#d8?#QRh#CYT4+%ukk94<VND5cj^+5*64$k65bC@t:FBt==djjCkCu#en6GJly/paqRSmaAwF>:
QQ\PZq A9TIPYm9^%KeWdqXR5P>@$9YwThlR9ChEe4TEewQ?NbaZQk\TuuTX&$$G+8NSKkK%I8u9%TW+SRyhc*!
!5Ie\e XcP^blM$Y+&=4HwG4k+iyCadb/H@GC#<#u&8dJXZpGjQ!%Bcm&5nJY=XpIi!llXp=F9+\MZm//kB*!bS
<W+h9S C4nES\4j6EdT>ChKeYuj*e1k@u+L/@SCY=XC^N$lmXm+@IQ!DEd^Jja<c>+aT^qi9C\=Ba6NMmQh*aii
4:G$B/ qdN?<I8>8q?VhS<Aj86AkMCiJBhkwP5bpNJRnnI=/Dkj5#w+IXi=eWt+CjXBYDmHP*HqpqCy+I^b@Hlq
u^&5q# k9H8C8G<RYqVtQw1kyV&&yY+6>&Y5T>d!^WYbFln$C1l>IJSpIbn$/\ZqSp:@JXai4p*/11$BtH8&:T+
l^u@k+ EH<n\k=^GF/HyVqh@j&@Rqc@%AcGTL\9@L4kk/XP>^VGG%^6a\!P\MbnYCpi<Vj5I6K?!%FtPTJNuptc
VF1a!: ZDihE9cj@X56iIL$$lDb##&\:LSD$E<kRh6QCFecqHDS9y!R?da1$nS#l%u+dKuTiKjnkIB9DL:GB@n&
1m:T^u ?<4$y86WM+<a?+Z/Xlq+:KF>kw4MHht\d9Z!SX!L:c+A5LIV&TFlS9$QDyYk<yYhCQGDE+El18<DB/wY
+TLFR6 #juW><lhqZE#dmjpJJF6a5yekdN>hnFTTPtP*%VMX^:J^iLX5EC$\NTh9^*?t@I&FqXNPT=&#iBAc::A
l%EGFK Hj9GyB5yyN:GJqYEcdMhJ+a*JcSF89tb/Vd&q*18Dd#/C8bY+LueaH?lu%IqdZGw#GI9dNT8E=Sab>#=
EMG$n# hnmu&wLFi<MmXRi+J&E1=SSDdeHEb@^eB^!bmQ1peC#Y^<dyd?L!QXmw\8KZGuWdwYI4Ny$+^bq&dVV=
CZD/IA J8Z=mWH#@YN\Y\RTbpq?ZwEnB\5nMXjiMpkhlIjiDA#A$9WY&JnV9w=KheAW$1SVZEILQ!Pu!PQ4=web
HH@X$w DSFGXeCkXj/HXKjcH%JXHp8&?6X:#?&D*w#IPH:VmZFJn:*p$#Atu\LA<5=P^TbwaMlAP%Q1!%j!BEYZ
9kb:8! 4X5d6?yepJ&Z%Zhd$I%N/86*%jaujmHcZPW5%j\d=lyaeNSPW\dDPhwbLC%^aLEtqt#wE+GQ//P8^LZ#
@1>+Jt C\9<:dp#FBPuKWNGY%CGDa6N?WCVd*=>$VVpBj<9MJe</tDCK>m++yJb=J9tmY*#Cwnedem*FNn*K>6t
-A<thE 00028e1c93f00110333 Page 483 of binaries1.zip
!YbA?m Y:T/%A<E^\d*pRm$Gl*9#Qy&%=QZNLNbBjqwaSiX:FT4Lpqi#qJm/W&uKEiQS*8&NBp8LJknZq99i:?h
:ZPk@K aQyKGe:%N=*BIVpbiRX:5GnEZBNjnSDa!e=nE!i$Qi4:b^#C$w@uDWeD#?CVZIe:EhJ4\5NA+%ll+uW^
y8q:+I F!@EZE1T=6lbLF%w4nupy%pkwMG+c*biebE%IYQ$C:=B$byD@88^YT#Dyu+4*ELk<e=p9u@SlZZwkmj#
y*e5#* H</a@!<RASnSXTX:XAeZ>\6bTq*u$WQGT>9*QAuL^KcRNqE@<68M98iD4KGc#%Dqk6+4EkWnF5d@HGQ\
1cZFXu EXNHa@Gkw%uSdhR?KWk46eZemMAcqT58m?LL?E=\\P@=jqNtV^H:I9EmNkZ+yp6*MLjTHBEZpp5wYFM5
=h>emy 65DbZE?61@HR:4Xh&c4&<X4XEY^XA$BbC8pqGHdNBJkSNMYywtw9%MBnD=Z=##PdDtJ^=?VH+6C:tyDM
+R1:XC p8LQ$bAB*&lHmV^P\ui^!4T%^khlVT9QG5X%PFcM9TcMC#4a!u<#Xqhk$<&Rh6k$5WE@4F#Wi*hpw$6c
TTISB+ eiA/LDciZjjCCi*R6LlK$h+?H#ZmSTG1=>#WiVXDY!Dyb6>kIiFXub9\R#P*y:C?@M>LRK4NCD<ADP?t
\+>wZa pmMe%aG?qLEWy%9V6:4G@ntk$%LVJZ@BF1!cHnEmy6annR<?F%IDbYDnYq#AB^ae$cVY%!$J@pmRjqKP
TtKNY6 *FNwG&c^FW<I=9%RjLIqK/Pp&NL*S>&iN&y$VT=CNWK5yndc/LT+kuKXDuPy?hk$11@$aJ^dkN&PTA6Y
^%V%/! htMV1CZu8hwn&YwHkA*hXZIA:tMAM>!bem!YZwNiMiJB51mWju%L+n:Edc&w5CCukh%m!!jdT@#ywKAd
/:/\qu Ze^a$lh4c@l8D%pX\mqmPdIJd<ctVbkL5QdT@caamuWu5LHDL?Fhj\!J^b69K>:4&n/$c$kK1mYPnc%S
Ij!ay^ C?F+t&X+mcZ+9D%6&H*n$jwNFC>uh?*wY/<hYXVSRq\:u+b+d8SAu@46p%R&!:8/>>+P:@mc#^S%Y8hw
B!%EDc wa?@a4S=l%6il4/e/<+E1X6ikqRhJpmhI%%dlu1wIJKmjLwMuX*t/CHQ8nH1<c5$u!jM1>VFB*&+PbVn
!ln1M+ y\Vckw/HR4T816k$1<H+1y?=5d:mV<t$!c!M^ThDIyNTQ/q@>XH#!6&+nq>+N+%\/*dX:TLFRDVT#h^D
MH\e\V uWh:5Ic6<tyaFG9a$S+kQcc11H/hSp^bBmpPpkJ$>!<l/9!>K?6>m68G<:aMk:*Et8EZZM!l%aEQN?8F
P:e=ep w5*/^T61VnRk9RkS+=W?96MDRw*nc6WJ/YR^Y+8\1jpP>==Lt%KW!tdG^=/pyT+nLWZRqAiyeK41nDVj
a6EdHh l1ZWB<ZMM4#pP:HHl^94jQykV8ymVaLQicq9%E>%hQ6<c5RTVtSI>%y*c1VFYB4WM>>:^%Sa6/Hy?p8Z
?YB\AY FKaK9$<:/kLmnutewpND/9hp//9Mm:GKb85LAMd*el=+W5MLcElSV>X!!kH$W\>c<ZEE6$LjTB4^W@Mp
jIbb\4 nI!deK9C4K\TbLNb51pL/yih?l>c%&H!TRY??^h6/X^jP?Ku!@ii%Z=w$4XGeP?=Q#J>*^=jnyGGm<ZS
y#yJ*X JVp=iRyLtb/RL5#h\@Y6qkKWa<@FacqMRXpEHRn8ybIDRCjySk&wG8Dkb6l1eeeDF<Kquc==8wKMnRcD
N$YQLc GEa6EPHmD#TCh1wl8K\!^#w?dX&d4>B6Ywh&TZMH9tQR4$&9dKmLGYn!#@8lSdHAqhl#4ZpF8%B$b$YK
FXCQ55 Ll@yQW=wwPbN1BiVHuM<lhb/dER*\jlhJq@NtJ8?<T!FZmZ@BZe+981JZqmEA#SjmtMCS$^!K>6w&aDi
KR:Ah6 18we5MT\CkJ/p*qqeKlp4\S\!i6!L&hKNA%ecuap6=m@ybbcd!#LLhICP5mDBmC9!HKRk=Ie4Lae#<&<
F*LNV+ Q15N<6FIl:M:eIHa\FLw6W%#5PMqKwMuPEMAWB*DhK^E&I4B>h%RL/<SkG+he4AluP\=lLG5#uXR\$Q!
Ii1PR^ %ahhqSnJW8ySAV#CMZNIlhQaID+yK<8Cm8#FlBe%qmJPaS#CKjEDWLlLS8!D!+RcAiAEZ@54<nCQlTwc
VnaIle VGVLIehL*hTAdb$ApDWS!Z&u&llwAp&lq+%D?#lc@%4EVVR$8aKM1AZYaLHI&<\AMM!j!ElTpShJc5lI
IQB+8K $u\C>A&cKG8%/L&cLEl^VJT4GaKmBk?yGtKRSq=DapEmq5n1cFVw6ktaD$YXyb=cPjeP%In6RACRRn=W
C6H%MV LWhXe>>MqFPw8eFyXHF/n<R4VmA8EThmP>lPl!T%/%4M9e#Jb4JY:11:V5D&Ympd96Xi\^jHlk<A1pyJ
en1KIX =+8hH8hyhVSF*1%#HW&=W!5$ZZ!@d!^1/y:mqujpyXP+jPIF#w4ua1:@SBSWmXicqtj!wm>G*C>/jAPL
?CGN^b hbV+eaIlJN\4RkSWFV/y?4Qt^w!/AaBqp9P5tb/qXbZTFFt>?n6Z@986WXkIFLqBjA/Q?B/KG$RCLeJ*
4PP!Kw *NMtjBJy@MJJdK##QYq/E$dVF!ICeGKTjMbJ6#5LT/FPV*L=%N#d&MkQjd#Z:dmabC4K&ERb:nXS+6qE
8\awhX WbTB@yb<JdJIZwC#4cNMummu?LSSn&>bnQd>m11Bm9FtIImyQ:y9bqD<>nKXy%$uc*\Cc:\h<G>#%pEu
Idn%nB jq8YRl9jRYH65Q<IVm:>RAFH<d?GC?1^?Q&eJ8/4&tXA:X!%iF&kd<yYPPTnVyNX<kX/PJZe^qKmcbSA
Rme*qG 5?Qi#ut6qWRm=tK\5ARdWZ>M8IMniBCZERGTutDn!@Dy+MRadP!V!mM4=mcDYdjTFNQX*$%8cD&nJ:QG
w!*@e1 @PDbtGc5MbCQ/p^S8RMXhGIyMZDte$\=kD>?=$kL+VE*GapD<G&5\?wIuQy!lAwua:=kpWGK^wi^&FJW
1L?!%5 w6#k^P%^ncy\kSCyVK5l%M<66GauYG!%&yi*RY?aYtQWK1Nk6D$*4!AtJ\9h8&\I&iN^E&I$I9YtVjEe
wWjT:W P9hKd5=YMkB<TD=$:Km@9D4PFHw:PqyRuJqW4$/E<a^lN<+PWRq9yiM$Hl?S$Fl8GNhH1eT<Z*FiVlAY
#VRq&F /+Yl4+SeQKwhDnwy:MFyjh&*FNIRRZh>m8i=6L5qLXlLAKDlXPiCwn4cD=$y%ES66#Dm<y%VZBh:V!+>
XHFYk$ TeZX@<4Wl:9a^?&kteC?PyY6&dFiNPRFSpMAaQXWJJ<5$hPqlnVF1jF94J18dZ#\Y/XhCAhZw1X^QRZ1
Z>h&^H T9RuJd<+$Z$:AdCet5yYq>%4hdXp1?5WARyC=jISTS61Tk<ynuK=14Y1=QEqXYBV6lCL!k:wyIL/JXXn
!*ne:Y ehp&h$&ABHW84@a\ylYdeJCQbny4wqWF5SS/GFNeSj=#8L$KR8auLy\:qB++Y#PepI?Tb/up5&/IAkLw
PGA/Fb $P%!81I$/F6F!:FBwCe*nqPVjVQH>#k8WPIPKuQaIH4nH<qXwP:V=P+&QaAQ*:^V/hn&TXAEajTP<bld
E1V+&J k+*9@Ft5CQa*j9PGj^dZuKyW@ip6T%J!:DV*IWY$wtL#u@^TQCKM*1jL=AA9Gj:+/ZCPpwBRN@ZuZBq8
#WV$aj 9\MjG+GFZcu1HjPWXt\<yK:EW#m<C*Q<%qEB^@E&Hy>Xa/=X6kmYIIJWN:hajI!LEP+njBqVh:BSLFLW
jC1q9b PK4DR&iL6eRqYH#e5*qXLm=:IVYP>&9bB$ihC<lQFdh>HWRb&WD1t=Y$MRQcAFaNq%DDT^etbBC8AI:c
imIM>L 1E6\cN>Z$%Y!8?6+5b@tbQRSQKSIWQ+5dMPqlq8%^cca&@:P<wA:h>PZt4c>uVmTNQX+Vw*/#wk/FQuh
\m*e8d /au!chE+#yedh@GF5Jjanp6Rw\VHDHtAd>&L%l6dn$#d>tL+N5!QPFdDFjZuLkF:haaV!YXP^%$?#4WM
yt^9bn w$d1JhS>A+Hc+eSTy:Hti8QDZQK8PR?\W6k>mbNP<@lljwH1+A6cMZDlH*G>kl8!CCG9IqLwE9uRWG5=
4SF&AX jK&eE/aZEDc?EWaZFll@AFyWd/cMi<EP#eIhl$@*+w*6ttt#VT$GSan?8iHuP59iMipIE9AMAp%DK=#q
PX=$:Z +&^XNpSIZC<mc8dbLCk:4Ce:!ATeY&a/X&&<>tVdeXZnq8@C^w+hRly^q?5N\95kikw@6Z6IA?biASD@
<iW^&X PNM=DFtKIEZY##j<5qkp1m$pN*tYM@eD4Zb9?iu/9a85ijG^*?L<i/ahQWJGSm&NXL!kp%b?qS1/CQij
jCp>QP FVZ1WY*?+Hu*JaRjCa4mYa\1nQTmCm<!1qA<C\/1b5ptK>RGFBdbl+=beqjc/&LTR::>dt@w5RSytA*J
8>?S?u Nm6=hpPJQc@\t9ct%=W5RHX>q1ycV@k9MaIHAC@PJw%!i<KuKe/l&/$:!P$?W48*9dCwGEhKZETpqCcI
LZA%ji P*C1cT5i<=h@?RQ649AD$tM5GTb=8MKHVldMXuu+YHX6@G*a^q?ACMCu=EPq4T^1q86MmRKn%WqXD\\V
YChmG@ 1maei:ttG#Hk@G$&/%GyF>8X!Nk8AEl<ZTWdFqFdp$@qFKib9qT&>>E>dJ^<8h=648eLp%iaSY=muK5K
1mnPA# KD*<>i4QlbQawAHA=6ih=<J$imdTFPik6jWy86#&=w*6DaYEEtN=ZEw6h\?k=EWZi8<4q<t5B\ARZ1GT
wAV8HK 4=XS1Y8#uCL*aK8Qjhy*ZT4dcmyumGJwTJSkeGDn&=?+V?lyBd$1&Qn*<SV4&nIC*18C6L?EANF:ecB>
iiRlqD D&eyEXT5<*ew*\*:RmL9/+q:VkFY>I+L6T@u5Vi$a/klH$&hw/LYN&kZTT=lKa*w:iba^*DF*k&9tGNK
+/8E#a j\9ePNhu=tT>>EC+1G==Z&Z!\>#$=hlp^au9%e<e!MY54&%AuQlTPM4FpeKPKVHGR@ZN=hk5ZeSme1@/
mFwi\S yp#8/#Aj#J*H\kQ8l9aINw:EyutthDTtHw:a@CYQ^Zic6/+@$TD<*FAZpaGTw+?QSqm5cK\ZjS9*1m&?
9mt:eE qiG&c/GN*nYH>i!A=/C%b#*dNaeMWhi=V55wwHSVIiZ?HGDh>qA%?1AH=i$deV9DZ5ZmBG^1J1:9Ib:b
Ihllhb w@bySH$FRy\?mmN<4p4&w4>i4R=cW$1YSa\#t!KDKncD:LqYX#iPj$juZ>wyZnHJ\>E#qEjn=qb4ehYB
*4:I/@ 6ZdeZFLVy*PhFqhAVL1!qQ4k+6WeyY:@e9w^:pAXh<B5/lHQQA5AZl*c\+VtSYwQwdpnR/+n?el!TIZE
%8NNyW DC@:j<APijCp$1ZEWq96eS8!B%N#B?AQ\JI@DJYC?#<^k*Djab*aHV:clEup$=w19V5=el5cbLH@y>l+
Rd4*A> bDnq+NE$B?hAyV>>dT!dwW5q<^RabF5Q^M$Ne^=>\anTi6@jR$t*GhkF>anNV/lhY\a#Awbc>Gm9mq/:
KWyciJ Mc5#HXN5SjZ+Wd9Cdiqh4!:cPmE>8w>!XbeJSh#NMN#I#N*C*EKMlA\#XjHPRK/1*6>D^4jqZ1kKw8FY
JYhL6J QcG5/klu#CPpJ#td>:I#?uGPZT5iF\XaHSMjt+MjI$P#9!/EcnM8Xa4J?+M!!nRj9lR$QJqdlJ!S*=PY
aI*RYQ GNbl<RJY^^u=%dE$bl?hLqDd>*8hG%Q54TiWdcX?SYBuw:ZX&TjLlyQj=q=?i@nlj1e1*</wGJ5#hP@d
HW#KpN \+Z4ab^B4I$@HajeA@d>Z6KL%H*PZ1\kPD5+nS1yT$NAN*tj<?&cG#wm\@%6H%SiPw=6ap8P+%$6A\!d
1iEJPD >/uM6GZe:TjW^4eyt^GA+dJnu&\@<my18!4C*tSX8@uuZuWM=#LeTAkCbNn9SJIBTD4L4AMq8=hJ:pDH
KP?pP< j4q:J@upwyP&N4@&##5baRk@!i<:qNn+mGMVD9@Y6/CHiQSd*6XB\*:T\Tu:uS*<qtD6/w!HVLtikTTu
-AaD?u 0003e03bf4b00110333 Page 484 of binaries1.zip
ML*%/% =kGXjCy1*8F+Q/NLeh#/B<NLE46HhAl/dLp@MLQZuJ>&6!yVQT4JuQGDXF1cGbhdX5e^5jkt*/ckHA8Q
kDcD&t 5cIA9!!ab+1LhPd=mpdm?TWK=PwTXN!JwDhR5@jju>D4L9DGamk4VZLtHpmW8/SV>kuZ&S5jGl!u!$+e
$kDNV? wP#u4:NLDdD\n9m/Rt45w*S%CNClV\:Ip+D#8jME4m??\NRBe\?R:6+>AENNKI/XV=%w9^b>VdM$^#H4
y6ahc+ :eb6ZEmkQA4@uCLlpa$kTWY!nD1X88<q&WhJL4&<a#:5$HQlX?!h*?nXM*6+1nH=/J$5*!S^DLK5%%&@
c?*mPu ^CZ+?I>jj1JdiLAF4E:1Y6KYJi!<Y:hpjwC^G>>Im4/G4c1+wk?XSt/9bDa15DDcJ</E=BqIl\lcei>#
1LS4Ep =%99@MeVck4b&it?uLam!ZFRH1LhRuK#*TYnW\c$@CZ#S1e*E499LnH&LnXpeT9<*jkILtR>/F\pu\C?
*Ebw?G *5=FAkmVDkKHi%Di#59M*a54XthH%4p<6$d\h8QKLd^R^#XEXwC<iNA=SE*8QkGXaSjtR&$HInu%9!D6
Jhj%HX w4EaXCq4S9Vbp6^q5Y%n#:1V%+\\qcdWWaGd+<1%K9h5AG^yZ#lu\%1C5c>#e6NLXwB6>lhPK!6BCF$S
Hl<X6j QDJ#$=#*e^!Fa&6:nBek?QAL=*ly@u^CKW^H=yN4N5qFnpQ!iL&GI=L*VP\!h<B4PT8H>%pa>c%n\4iG
\i$Ht5 !iP\1+<jIkJiu$DZle%kHEHY#<tG?Mu8:XXA>yjVFy$Xwu+dGVSZ8ic9J1$d4<Qqct#1elFV%T*+d\E5
/IQk:e /I%DdJe/#KVV8DKJpDXt\HiI6L9Sq$Vp46PR!bKYR&VGjkq6kAEPXLieZa//1QXeq?m\IhRbAyL^N9wT
5B8^XN 1b#^XHTP6t8LS$Z4djm\A%iCuWV?t/SDYMkEN/wIahQLtL6G1LaQ\th\c+\I$#TDCAFGbMdSYHwQt@n>
J!?6R# VbCR!RiG^dM4wF>Cb#P@bP&u%?X6p!RWNbtR5M=MLREA@whJV:t=>hpFVPnQ4C?hE?/<PpJ^<JlYuE4n
5DS*X< V+PATp8AkEy>PS^\=P^j:qAkIjF4M#1C5:I6hw5N=ieXbBC89mC<tK9EW6paLlYuD5Gt/B9IJBpPMKhn
EE%tTe R6Bc9Q55<pqhmc*e#+l:lMHdB^1EZ\dNeD\#@=mFTJWhD:PiLQBT5HSlQRGAh&qQdpJQNNTPpj!&HZd&
+>p/m: bL@w#%&/eJN/>/RMDT*lPC##9i5+^dcT6a*Q+w<\N$TNyX$4DV\Pc<bm$h5Rkj9^5Kh!DMFM?AyG5!64
GBbJQ< A\BM?W1F8HM%FnS$^aWmmhJZ#paM%DSWnL5ac\kD%VPNuEnLPL/T5>9!9nZduyBGlQLTT^lBjJ@h&LVX
NJNTI= nAM\N:E9D$JVeSGSt9I!#iA!i@Snu19mb9Y$a<JG9wl%yl4y@Am?Ht/X:em\b&StFF9P!eNIB$MmhZ#+
YdP/wC FYQj1d$B#IXiW$kQWlk9DABhn/kk>1I4Amj$/BJ4aXP6a8MdNY5LGnp+K4l=yEmlEA&aE/!+W&P@KTBa
GM=%Rw IV4GkKte6Q\FZ+nLBF:SiHPkwMG=>SZGRt+@GqbTpFhk6!C4NT<uL>N1mede*58KR<%<ZX:?Lu%F=6tp
J4ace\ I&#Wn%KZp1VN6<5q59E+S*&Tk\AEHRWdA<wuBqEBucS6QiJW<#*S^u%=aW%Z14mlwdauPW9RK<dZFA&8
AN=AhX jeMhn9pl+9DHTFl!TQHHXp%RpB<KM&8\pG:GymJ<:m@FS*B/d!@k1c$=nChkS%&P54ah>>SihYj$AjLS
tbTW$u NjKXHMPeJAahBe*!Wij?ZZH4mV=bhuNdVuhTpkH\MR:bb6P+91\mCDuM?^Pq?A+CGqlTWJ^q!<k*b%4#
qlectE CuK?1&*ebV!pHIw=5?+P=qAKSFV1ddPk4L!mQE8B9c//GC<@w<nFF:BlEE+M?Wale^+\Li*RnQBK%u^@
#+ELbq J5M*\D=p@*WPddmDAD!1yEaSei#iN#T9b/X#cN?WEmcj&n1Id4ZWR%T+5\Rh&1uCi%NQhi1EVc9KBdF%
$1IVPD cTVu/IF\FVdbVAyX*qX$VIt:Yk6#WIaeMA!Zb4<4%B?TX=AZmM^kjdM+^qCJWZ^:c$=Gjwc%HMiQ1Ie!
NM?muR C8^F11d>pQ+D99ID@nM?QtNQq1&\aHT?mp61kHC4*9cMk8\MyT*:Kw%kT+M^RY9n$hhMJ6n1ibCY!q=X
PK=&yN QMp*dCbj5&9?&Ik6?$iXbJR!9*b1+nd=SI@?PhcA=dnQ>HwAqIJCXIt:YLXq$eEGecuGT@n^QMHuW<:i
ik>*Va C/*mVi9Z<T6dK<u?Ip%@\$RyCyBb\I18jM%iAJ!J$1XaMF&mAbqqJ!Sjp@*q8&M1%KJlR>ct#X?VN9pj
@u?R61 k#cFI4Tqcw9b+pNZM%n*AWJcwC:aSZjB^@u$*:8ylPB$LBVli%&^niiZ+//><*Kt1Ww$RmLtitN8uqI>
G\V=Hq yMb46cYdiuXDwa#H=Vj^k@PCEw@Q^tXy/HY<GE8*H^9*Qh+beRaL?Y<EDnK*@e^9miwM=k:6\5&pH/QG
tHbd:T y\k^bl=#\@46CY\c*5J\6R&*?$BAQF5y@wm$S*ie>jRdYR51IZ+G/Y+9Sn5BaPN^wD#ZZbRHP6L<8C#>
u4lR++ wF=@>BLRhdyYy6L:%dTAM@PA!nT#@1V5#&y*@YVTpE^%jb9bWyB65i%SECu:4MGK/%6GbXucFhq>@R:l
%$%LN: %SZ14YVZ:D^hQdSCdR^T+1E<d51ejDe@D1L@eVbZIERR9BE$pVT&N*56F$t?IiPECu$Y%yD^C:V6?lP$
49b>wM PeGw9hnp5&>?dhPLSTtCEklK$L8y!@CShq@GtkP\1Z\8H6^Y6PLN5YI1N^TQcm%YuiYpwKc+ScAlJakP
8TG\4y wSdJiNH<E&\ID<y*+TZWcKcE?4BY#V<BDMW*SKy6TXp$!wVSXyJQEa#TQjHF?q8Y6$Sl8VRtFbJ^pmK!
RVa*Wc FnhFucT>T=mNX<DhquHw6T=?R&eG*1<y>PW4G4@1^\ii@puXR4!MhXJ$9GARK#E*Z^ES<^y6JXZGRn$9
iVGDNM j<PWlJ>TH#W#JJpl/e5I#M9jkIBPNub^8C8/PnRcVj=GJehw?%VnP?4meNuhA%miWJS\LaZGVQEXL*%$
@5$nym iDHt?H+6FHBt9lwHmWWwRMk*^8D8E:9WHqceq%>mQc>M6BTYFF6HH>Jw%Nkaic#G9@H@N@pd8TLculie
S6/h/L h9R$6V%\I4Sd=!mLSMd>NA^\G65+AiA1AItdMEn!1KA^<>aMGEhAqqQnV/m<4D<wZ:^+1S4P=S8qI81p
dp6*y1 ?\QbS+<Vp@QT>wE54nEa\<iSwWpB@/*NCJ?Xt+wSh\YDbVhGlBe<A%!kI^9e@p8qP1VY+alkhId\pwR4
AIcukM qLp64tt/m/9TWMEik\>!:LF@$Sjq+H#pKCNPP*?MQmSA+qF*SG=wZAiTSpu<KSS</5JSFFdMa8ICTqJC
emI:#Z >q4@NY4%hSYuMwJ=@p+<t>6yMG*F8bn4G*+Eth:Ak*and4+Bq?MDi^IJD=nI++haYH#bIDw1CX?:D^<#
YAXY#j ^cE\&HEX%LmBaQ/Xa?<BkyDRh&Dm!Xh@y6+EkLE<cYFBDJ8Y$H/Vk<h$@Nh\9G:N<RLKm6N+MlVnYGh8
h/1CK8 uDuWEjdYmpN^\qw#FwL^lXqeh^#6k#>TIMJ%Z<Z1FP#Rw@+<61t^WQ5h#w1qyb\bBYDnbdDnEH@eT=WE
%5%Z$P qN<!Eb!dEa?hqAT<AeHawwP<D^4ABuk#!We=C6JeIuuVIcNDDP*=kZ#w1y%@/\Ab@DB1>pVNB/ARqKE9
:N+*RY +A9W?a51nFwX&VK!:Hqb!AKYdp4<p#CbW$+\E4dL?AVl45ZW\$\1IauFDt:=WZTGm$TtCC!>Vjn6i4l4
ZNGT81 peYYu+j5h5JWaFMNdkpju%>apGe9>LX6=IZa<d:$wA\GE^1Fqmua4DqG?$uG9+@CS++BD=%cymDn*%\J
9i\MX= uWLmwkd5\Aic@KWmWS:yNIW9>&8X8Cm5kHq%Ac!$FGT**<yy6>:C+y&6^5PJqCI68aG5CM@q5X?jpaX#
?@?JDy %nRik>QdK+!=Tw/Gp?iPaXPuMH#dH\t4J!yEjqq*9\TtE9!TIB/tSM+Zeabi?mV9+BwmdS:I!NI\W4Ei
9>wt1> ChDt8dGM:DcHWw6wp\nq1cMM?PnYZPwJq:/LaRnKpCKMYVPbE#J=5:J$lhA6c/*SJ^HEGcH^MmQe4F8H
8lwLHL nV#PRqt&$WZ&\8LS1Nl8!T<t/j!Dtp4aaBFYC5h@MI!B5@q$<Ve5qTmMWj+8GYkS%JW55HGupi6k#H5y
Pc<N9P !a\c^QbRADkkABE/:=KBwIH=kuQWH!4>8aiZ#6MDM84ytbb\CJnKRQ$Wtp@Vjni1@P$<Fp1Q4a$#>eKt
X@cuGc 9nYWB9FHL9I6\nkWcjMX!*&LNMytVM4Ml>wi8NwFq<P8pYcl9mwj>A1dD=CQ#1k\plwRi9SPI/cMk/dY
EyDtpt W#td6p&IXG\:FY9GahS!GPL/8M4F$/Yb+Jm/=a?41?P#%IZ=SRMW>KI4A46qi=+XYVQ5Fn<$H^t9KS@n
F1V?iG <YwlDdhCYdtY4GHFJjulH*Pu5dFhpAHlTGQXGq=<<^6lQDcdNtB8+G?twdm@cVXc1bnFn%>mMGqP*Bhc
TVi:@N DVHAQYwDHw!H@mbHYIA#\Z1pJWmLYX?%uIjiinD41^cV>@W#AbIcW+yJP\y>cEdT+tna%X5G4uEaiw>=
y1@Ji\ 5RcMWKCCdk@CC:#=e$LkyVkeu%H5kQ6k^jle8PB:bcjKntIEHa=*bF1K:aWnm@<\ShT9XJ*D>tDB%JXM
bQ#$FB yc@=RFMKSq&JWFYaZbJ%$i+jk$%nc1H#Aa5X1eJbHQTbw9!GT8wi6!K?1iEX\hR@EA6^?Xl/8XQek+AZ
yljc#t &LY^b6CBWDZ4=Vq/qbjM5pK%D=p!#ypYmknAb?Rn<dNPN*j6hNCNd8w><k5>@Ye+##XKyB5d%S!E$nIE
j=PjBd 8:!^:ZdpuQ+#NCp*<jTm\ceZ%hJh^1h@iT9%hKBL\8yG+NE6X$9Abu9BXEIjI#W?KJ&N>!%AiFVEcL=L
L&qLa& \9wMGlhCp1kT/NTjV@V#\&mRVYyTA\kBuww9Al=&/VnbJIhqEYG=RdEFEhucunjCk9&N5#j+Ze\TCH?<
dc=pPT uB4a9/>?*CL1RlX?kM@9X5e$n&y8V5PlQDcyF&KD<W$5ZFAVMaj@1n5ik<Z%&Gn?AtFycBQjCy#K*ieD
lk<T>T i@P/Fc1Fcy!Lullj\5bSBn\W=%/T?V8knhBc$tuYXXkBjXXpkY$VjXAG/!wbFI#GETBJ*w#y!T>$yd:G
8q5AMl 8Sh<JAaJq<lt*JMb^\FKWpI?i#PyB/h<+cnj9hBGyKpCAh%B8HhJkcXk+yR/qt\mPyYaPj?eknYKR@N1
SjJX11 JDAKCKnSbqjDXJ=#Q6P%mYuIGm+qM*<Wd5AI\#mw?kj!wRjwR#Yl&!>h\<kc6kcwEN*ENFDG8jm@WN@u
ltDCWt 9nl#BB6L5HTK?:&8Fde6!5m#BVWwKW=S96N#CB?+QKSHkZZ$^%#/pauH!LB@L$Zun6ewc9mL@RKCByq1
==Fk6a :Mbe^Ky4/p4e4E8$?K4CX@\%wY8G*b/Sbe/FG^yLky8!Xj\DnPJPLi9Sl>T$te#6YK$Q!tL#i/iDALVT
Rh!E\a aZRYwcIGdBqDF!>y<RZc=PHc*Z?R6$BJ/YD1nEW8Iw>%ydl:^N&hI/Ip@IdtyT91hW4NdE%FFic&DKk9
KG8LXa LT!PXL!t/lZm+lRIVqTpa^6WLYkEmPHZpM+HbdMN1wm$bkCTML$?&eAXNAtS=DjJy!+eQjZ=/+t?9mGM
y%&%P$ t9#@ST&bwSAye\\K>FD?GVX#HY<NS?@#/\JG6NSGa*6dp?=pNF^GZNJ!mGqi#Kjb6i6@^>u1Fp<?X!<t
QklWl: RYjcmRe8W1WZY@L#Clc4:lkFQ8SNdh6m8!&nkM?=LjI+9t6BajLIH&ww5dR4IEbAu?E!PD4p%Fde/yR1
-Al<*m 000e161094800110333 Page 485 of binaries1.zip
Gq\#lI 1*CEJhk&NuSI#iCm$GbM<\C6Sc>L&CPp+#cS#Jth=AXaZC=JJDIe+V/p6+TZEEa*a8y#/M!uDptiNb$q
PWE!my VdQPQ?AGb9piGB^+A%=cLk4MKNhyL+VNGTpJw/Kq>XZHau\?mbqdw45\PcBCGw#ZVhSJ9VyLjPXGuJ6S
@Dq@\$ WGAl#EZ>QH8^^V1Ec%G#KSPjQmZ+$u\a#$u=e=kwJl*JH5IYA\Ce<CEd>GYPVla1*$Mn$CRj8cYT\Tjm
4:d&T5 <1&*?B:MJT:FiWJ8J@yj9t:ykV&tAT5Dc+^W@EWImjlipqycEF&VM!8MR$L1ZbQmGj<%!aiMm/Buk*iF
Bai%ZL ^u\pDjyC<pE=dQaKmAD5Il<n/8$!6+HK+9R+udau>/@=jG<WX8/M$WI^pkK!GBk5Lb1:<yZ4QyqZlEHe
B&&E68 i8HeT5PHDdJD!G:<t9dW1#ynV<KQGdGw@6#HGQRV9wVFZ^5e\X#ql?jX?\N@Nlu:Dw!<=lN#?Chl?y!W
AK*!>j #X@Zw85P/HCeu4V<j*4Q*VMTEWwPDe=%i%elAQ5N$QI5dG@kJEK$L<EPk#!Yc@YKmd?TYR+Snck8AbD8
c<y\9W S!TZZka4n*T5ZjY/kEwVLZFbtP9^Xc$:CYJ5:Xh%C%SaPLXP*!w@9eS1#!61I*!lER&@aPuKeSX8bW<9
S6mY1> #LHae=54MuYmdjR^jj$lp/TtWq6Jmyl^95W6H5<&=PIKM=bG*6TdbwZyjSj9%lu9FCM?WI>puV5>!kkt
1!Sy\l ndl4aA8=kpwBbA*@k5nd!YML?T+B/w&MyI<4ZVeewe5w*IlqAZmI\tj!ybXW<KG1Ba1!6>EyAG9%VbI4
wFINyX #&JPM:!=#?+qiliLCMZSFCMdaIl\B:MC&Z^<$FC&4mAjlSKb$bSTu?&#6DEjRPYkP4&4cH9DqBJG\%^R
Hn<PS4 m$pwAmZwl9tGZ9HGp$<d:5uFIeWbiX<GZFQ&:+1n>/yT6WQ@mu%*Hid?b#VQDpRH9w>KEbaM$I\X^e4q
$pd<Y= i44$jcq<T*D%<tXNlLiPjwE&P5luGPNmAcAX&Sm+dS1^5mFV#EAVHA=jiR:5W/ym911!wDAcNSSeq$Ml
t%&+q9 Yw4KWE$$&=5<8P5j*:5\j=&q5GC%j86$jK/GZ<#nijniC>4Dn+JH<cH+=8K\66ywLYt$%EC#5%tZPY1H
!\Lt8E 5&cwC#*A=@BljA\nP\:AyqEIa4R<\PDm#IGqupVm9q4DnLn%bAYac9mBQWXV=+6AkKaIJVLJD@\5\W6A
ld>1D% X$k*4i^NFJF<%CaJI#ANy8aahC?A/6>KhC5L@F*GBp1u55BW!MYm5BW$RlBRQRLeJkql=%FT8iND4mGw
=&S:A* C^wRd4!BkRnil*D>^KJeG&F\>lFK5IVIlqamS4thjWkqYKmH^R+/QCkIVVER<d\T+jnCpRWYG!mRT/?n
eq?dP$ FK#tqjlIcJ#w\KamM+T:Q%RHTR5=NTiEeEw5L1*yE%jiC4&CFMb+FyYQh5KY^N:%u*SkCNZ<h1IQ!tiD
K?LQQ% aIPGN$5t$*E!Zd$$Ml5M!y6JVycG+&y^F!inMHB*<lQXCCZSEnKyiw\?j*!5kyCjbk8R$QA8T6^N>b^Q
nk&Mn: $HKP+</A@LWTt/&EZ=ke^6pK%TM5^V>^qZkI1Y<X=q:A^lubPF4pnP@<#^lpGK@G+yldHQe8HwmKT#KL
9k%cYL +R/aw<B8HW&plGlpJ4K?<PMD8Z>A#>/Ey8eqa+>\YFhkH4e5>WEFnJ:qIRJ\Ej1HJ6Su%A#/P=@%+B+Z
a^L9#l eP<mtlDYnaYF!cMqE8Yh+R>8e=$:\:pIZ*HHjp/<6?Ciwe%J5@Y+kh8&ka?4^F!9Zh\c?dkElu^?MtqT
%EZVZ? ndc5TZAK<T&cKJQaR6cpGwkANGyHt5T98<Cb85R^^kmcmV1*qTeTj8jYP4=lZNlm!6pAHTIb/CL=cplq
\1pC@Q 5SlH+j4T:d\CKV+&jNCpN\ll65T<VBCdSm8p/Fd+\p^8<XCFca^yyP?mZF:=mSGdNkuZW5@6+46tqiTZ
TB9MdT kL^G?G!EDiD/WtZ<!A<==BAaq>/KRI1/+6i%G>bqb>NW?\M6\?%IB?XAAi$e1mK@TDT>c?NG>DSQQw>&
uWh5H8 hw*PuIWK6Y%FKZ4Tyk$:T<ap1/AhI<@:EP>l^FnE!HMBAhyp:pDG^*+eDTJWilSP\<cjZj+lG!EC5Ib<
E<?R?: 1CHuI$YuS#<*ZS=G4>hQl&pN=ei*J?RTYyYkNHZn*q1i1Kj^MJQD8$@<SQpS:w>NB#ayqX#YiWX<pdWp
yJ+:9V J:FBZkE&:415jMDXR<dJPBZQ^6Q*SKGkJ\wma4R^SPmTWCW&@c/al%E&Qwun5*I#+w45Fq5j^$5G+!Zn
VJ1lK? KP+^VplEcZn#at%D%Cy%n%GaMRb^PYbVGPc?^^FtdP!GB#e$*<PPL6laH^5@VDal%?aKjhqAGp\Q<j%@
BAD$Hl j/I*w4FaF$c>\+E^I*RGdTID5w:iJ/w%<T>h!Y<1qMl%dVd\ZeX=dpyelN4BQ?GKjB&CGp$4DVXe<J>$
:$MR%Q MpnlWIa/c1StSP?j<u&N1qVD<q5ny5SZlR<%@G1!:?>Y>cTNPqC+%p1%D?6Nyc>dBCFAn*9+y1+\w46a
Q*Nqwy DDPc!>NX8$*VjR&S/d=FhhI4DuDwHnYR?=m\EYFJVL/Bhqh%aG@$BTS+9NHl:I%YpdbjVi^KtHue?k9X
cdWWFc XYEeX#uc*NIbKaZ&LMdSWb:&E%T1ISNPN#?G\/knTHB@DcZSJ*L?!&mG/weL1#=WbR=RydR*?+b%MSEy
I4>jN$ MJMZp>@5A9e5yp:*Vh&pWYmd6I#IcS+\BF@c4pKLPYqa6<:h&1MGYaWR*mknpwknKq<$DW8h^eQIXPQL
cM6Y#= hB:LltQN1B$N1W4wSQa^tD@FTt6KwJ%QuH=yce9T:Q&KTSMdNiX<A5Pp$X?ull8M^t@^8C<DW>nN4$</
AquH5C pyHwCYZl6Pyn=e!PXhc/y5B6aS6j\tt6FN4+/:ZWmmHl<>A4#4kR6KL*P=FT5tudPMj6D?4PM<^Fu>db
kRR@:J +Lh?Pba/+j/jK+>hmK5RM:Hy>RDybtXA<qT#:#R5HG?qFQtQdWGy:K+B%Q8+p*MD#lctK/11VNGBkYEC
kQV19Z n^PFKb^pK8emF18^<Z?j%lYd+ZFeI6ib<l=kiWcKh8!Mbe?JG>E:G!@\S^aJ\l$<H*h\+El5\N#+aFG/
edeX!^ w9mhW%1m&4HdVI>JMVTn5%#ni+?E#Gt**w<PZw#86DJM#BJQ+Dk5FS#q=IlK>L!jkH:d&dp!Z?A&9uA^
V&uTSm \:hZ&q:%HuSFQZ+&EqN*ahQta?4hy>Wtj6RdNWCyS@$NR^Z>8yBBky4NcVyHnSa9VMu+=Y=:=e^^$\S#
Q:G*YK E#8Hyu%y$^#KM/iY6y&Hlb@Dm%YE<?^WV*&dS4VB?mbaLC*6L=4ta@GL/\wil\SdYdR?cND?Lwp!ZbY\
VDEXF< $HbZ9cY*8hDA5I>NS5*R$8n5HWE9aiQbl8k6+h$/kRdyjbNyb5buVahma*^j%hVkdGdy*k>%IXPWVHIc
=FEj5* +*a$9m:<HlNVM#W\#Qn%I*HW/S1@q/k$yej1yXpCD#ibdH+JD#WEtZ<N:8&$*mJN\GmMw/5<qn@kKjQ#
yc\DM4 jy<hE^aaq6q/aJqa1//9Eyim@ZGc$4GcC:5XHblJJ6TH>nlLTZH1>N&@Z+!JCA^4$9QhGup+ctX1G1?p
KXyy^c ylaKcmyAAK?TV%*aXHyw##juy?j:<SEZAq%^LRFXhAyd#8G\#<+lc:wG<6WnG%9P$TpamZF>!HJP:4m@
Giwn*+ jR6tKHc%K!tZuwLqw>1h&6Vtj#SdL19=e!kI!V1a+q^ZAYLq!ud:qycuqTc9uB>t!w<QcF@G*jye<^n:
H+5N=c L5eeGw1LS^dc5l6\i#Sb5u@dFqm/QTT\9pE\Wwh$+N</HS4cwl8<8XCE^wp*t\!y+p^lJ&=Y%DGG*nSP
m1EbGq @nQtC=!GKyR6NjcL&pPu&*ZuTu$FBh/I8b=m8!nl>A8SA=q@NGkZt6jNPjw*^WQjXp%LKI<euJViR&4Y
N^WaNX a1J8i<nn5ZHda\RVh$wwaH\=XM%%J/5Gbp=uniJIqX>K8/AITh\pYdE+bj+&>VH6a&^K*lq1WGDlcmub
$tYMMu Qw%VX14MS>BX#Fq<+4nQc%1eF<yw*WP/P\>6ht48Ld?X6!+?VQC98VLT=:ampt^aY&N>tmnClp56G6Sw
A5>FLW pNyFc1<:plbcG/6H+Ml%KnwpeH8FNAilM?RL#H<6@14l5@5eYm4\8i%NJ!be=MYhw&8?eH=D5WH/*l#S
>8WB1J F/&w^iQV?PCXL!XF%$>^<D*hWwqdX156w<8pPTmpB:=At#Sd?$9hpdh%ZM*wkNyBalL8k:DpkE9W<?WD
dnchW! KXI4I9CdiyCy+=C>?l#j*<h^hitk$q!HjnCiqF%9t+@WNW\aWMSqTbw+@mS8GK914t\54NR1HdWYa1M@
$Bm=Kw QtIK@EB:KpRaZXS4eFQ8RcB^L5Ty1q1HlS6m>MI%Mdhdcj!=%*wFK+4D/HE:uAcVBmJpV/WV6ktcl>d!
H5Dl1? </4tFbpC%Fl/jb:lJncY>:$SE>14^5i@?@kQCB4V=pKd9*^n#D6V5!KD6h\aJV+$#JmLnb@lTCuXyJWt
L5ac?4 Nw>Z+nL8p#QcT%kcutI\<Nk+5dF&Jlbn69cy6XtjuNc!XkN5=wK\>Q/L6ik6iImK81pHtamQcTQI#P@Q
HD44^# 9hu@%wGKn\uPKj$@pPcctktjHD>YQ\D*P14hh=&@EJL/GB8uZ@HJuTkay\S@@NIGQkb#Vdb4DiJw*PYL
kNw%w6 Y9ReeC\u>\y>*SMD#n*I*M#^J@@V4a=h?%%84K%:8ijM/aaH8%R6\*@Tk6Z:N^w4#p*pMS?\Zt?<d&w=
JW==uK aDMYh9VWZiWPSbuL>&B1<D=C9^*#tTMDbI6*@5FLBtE1n<ZtGcQ1u5Sm+=G+Fya?G6p=NGm\?bTtj?6l
Je^+TD 9e%ek$AiN=yCqShA:1FBjZ6l89Md#LGPNTQ:ji>aG8SViucjn%<ZcWla#JH9P5:EjNt:PmE8cbS<8?&^
cl1*FE cuHj!a/bbZEST*C$8RlFa:Fmbh!aK#4^Li=$/A6M=wCP#8:quG%cjc6Gh@/I=MK?W$pF?yw$%mBaujZ6
LbIdAw SRd/dm>a<ZcE&8u4j@GHj<elhhP9apF%Y@1wXXB&+GX^:64%ied&c!Vy\/Gmb6D:$9KcCY&Sp%<lNbCh
QcwcYS y:i<#l65%A>ieHh5*h49*cjYaGkb6XRqIF5ISEPw>Vj>C:c:u#ZZw:D/9T#&Eq9BK<6<Hu<V<tdV$?y*
QN&Dw1 Mu$K#ju=GRZb/XNP+#LlqbR/+#G*4J6JEY?P4>YQ:ZqRthlun%#nHY%W#PYij*JVhMay\\%hc&##Cc8I
bLW^?H @/mY$8?Vq/dZc5Me8EH61FMjJpW5WumwjI8b+NaJeIaRtnLkqX+GJAR$b*E#IJdylD=P6i=WhZ>F9$hN
bGjV4e K?m>PZylBQB?:?kn6&i9d5lQ6i:X/mT81:X4T@QWpE&+e$mLRE*HuFjaNd5JBBK%/I9q5H<%yeNn:9q%
$5u#l\ Gwmp^G>>VW$DN@^!cEZh8/9\l&HWGIecY*^QT8keVw*uGGu%6@iihK!@/5>XkWpH@ee5mbY?+iVn9Y4@
?wB9Q! wCawDJ&k/F=t1aMh:EA?^4GNm8S&j9w?6JS5IA+%twReHIntZDACjkjaHYR1^$IAQpPRjaa4eTK+=VcX
y?6$84 aipt9jV8myAB6c%%8Bk\yYNLV$MCQ@*RWpW1TnEj\a8^eAeBH\S5ECHk:jFl@IA\XL@n^*llJ+N4bk%G
kG58=\ BNF%<tt\nq+kH:!$Cm$%lIcGybB^t+EIM$RwbkFlNPtF5E>AnRc%Fp/E!b\N+i#He8i4&yy4t5QPa6Pe
+BDPd$ +/kb=58@SWIbV5HnCTVb8IVV9^u+\VjRam^>k<e6l:Q/tF#WI6c5=JbymAS!mK#1M^4PPBRe=jt?iRTJ
+Y@RS$ D<wRDjwJZBT$Dh&iTJtwhMJFPY1Wta*e9wuG^5BIAS<Fuk/tkCnSDpK6E==1NJjJDiEPEjE4F/emLQQ@
-AblK@ 0006fd97a3400110333 Page 486 of binaries1.zip
Y8N#TT <$ldjpbk=+C+Vuk<9p&&c<bmIambBn\Y$55t\YTweXk>JpFCb$MeyjJa#?N+%eVNyW<cJdH4B6A+NKmW
B<G:Et #j5S&GQi&>t<H$R1RSZVRJdRhH@IjXRnHMRXcm6CBYqaEk6K*i1d>Ip>jGYQm@%=SYi??dG\*p/*$dT1
8&bPXW 1>Ae1L!eu:K!@Qd@\u*C^HY&SDZC/!j^cWRMnPtjFHF>Ih>>tm@%N\*%LIAt^E?CetRtj5@d94?hGGH/
EI<H?6 *qeyqh\QJ*8n=PB8ew9J^5>FapV%C9TYGnAADqJK%yJGPaKZu=!LNlknFeJXdXI^6=HIqVQNC1uD!HD8
\<acM/ 4hRH?Q$FQHZj&yu8^/SeJjuWn/aST8itXD*SJ^lZy8#=KKYm$I@iP+D4KI=JIJ/ZkTL&Dp#CjW84ql4i
E$Cjkc <8&%ZMeh&y8W6we!1*CZD*ClcYW!Ka<nyF#e*88L6k:F9D<Tn@wbc*<X#\iG?uELnK6q$=W+9BLdF@J4
#E8b>q nA>\NNuHNuD:*qL$yTjk\DmYpW4Qq#tFuuHKhiQ8ZK\hGKdccFX&MWSn+VCid/w^RXqyN+^A6>6!E@^h
1ek:T% HAa$IH!!p?p=4l^!@E/nbyHHI:@%8<*%8eNSF!*#uh\F4YD:bChucw=VPw+*/$P=C=%DQ$d=i$@kLj\H
Vlct<P +Q9DG==Ru5FG%FmP=%E9caGT5BctRB?$Ey^<CKN=jER+$9cTGXH&ant8I8!Fn*tl8p:mdan6<q1tIQCK
8dWFqF NNQuLIRDcTAcM<YyT!RMl54JaSAGI*!YL*Aa6SSB8E9wm@+ju%d/I/5\blTYil+R&9kBu#GWT/$hlLp^
$YMaPu ?BC9^KhLqIVXpFKZ+&\5Vj#YMQpWI5#GdKZMdFRA5%EXIY/hc>S5j1qP/mbqNPactDF\G^5mZM\GHRVq
@K#APN %Pe\G!W1cZIRFn/Jn?1bVKkX9/86C4kNQCT<HmEq^tCH\awnVX5*Cq!VATy^6BJ*YSN\uN+&Ju$hM\Yn
Sq/Sbm W&k1=VnIGM5eS/uJIjT:uDT/#w?4HmDe5wdKlPCcHh!!T!WeS?al%Z4pn#JC#dtE=YnFEbcDI#!H#HKE
K$9S:l @/dK^cdMcF<j\nVBNV9kPR#AhF!yR*kPu<cZlX^Xi&WENkd%Ht!&a8=:H\QlP%+mLV@4!Zpwy+JQ=HI5
qcBpSJ *$HbyFl#Qe*JiJ#Cl#6T^1NnB&A<<uuCiL!5ww#HI^jnMR^=MB:4ieJ+QA^Mhb+DwXPp9^9KubP\8*yy
dQKe8& >*846uc5b$#Hi>1y?%j+Nkt+*eS+Y^t$B%PFBEV9G%lPY9QTNGC!E<Bt:+9JB=aGheHy\BNL1@lQlVb1
^$peXq dNwW$TRNt%aSQlVQ>d?N^Sip&a1$SN^MiRTZay$^?bnl65uWm>DylheE/cQ$=1i\yK^A9XS?GeXbTC18
nhidnJ i<mIjk!1^$R*$pAmSW&VKcjRhi4m4np81kw61ZA+<?^VPZXiw=dMCl8KHJ:G=LtnZ5GXTyk<h=kA9YKi
h/qmI! kbFReX%%D!QV^$*acS<R&wjVuM^EQt/t!Q<&Ln$MuIB@B:mkyBdNeBwWuIq&dD$w#FTnV>HJBi*H?M%L
5Pmiae \#:+tK@wR+nA:BLV+BXmA6>94*KJantj?=NTt5!QI8P$8ypw:eDGjT<NCjjB+6uP+1A/ScP^<FX95aZ=
VEjSYc \+/T+#X1QuZnVw%cM^aba?M@M@+TbL!AE$$laHKW4muqb6hL\!Ia85@E^kK@Y+HCi@\pk<QaCt8\1iWY
8S?GKh 5j+=41lDT=&!KqWnDR+@ETkM\?h#VB@mBFQ<IqP>8KCN\d&ab/KHMFC9pN/$kd8#=8/Ph6Ke*=AKeh5P
kGVbFl >^!ytLPR<InVTq1KdZQFaFTkcVY$^nBSht\CS$VcGcV\plq5<#1l>Lm&QIKN?^Ia1$aXbQNTQDJWNp=k
NhCM>V kY1l$1M#uMQeYt!lcH&@TZyaS?hXSw4Y*#FVH8a>&mG=i@=1*qpc9d:#$Smn?q5<du8IT*6%hAd5wW:R
/@++RD F:HPml@Y:#\>5QlD$$jeeG$mm@H8V!CY#ZSP?l//qB+Qi=/a8lmQ?$Se>tLwJMaLD$IELG!Yp^h?ZjjC
CE4c#I B*>XDD1:C+8D%NH6Ech/XS5enDd+Kq:XdR/SHD\Cy:*G@?G8+K4TuyFZpHipIGeDd1lcmddm#+K%eaae
GdV?^m qYFQcE6&GEWcRJm\Ye/&?p1S9w>GDy45?!C$D#8pDb6FB9W>CuEDwWh*<te&&hWqZdiRi@GX$I%@tR\%
:>Ny+V i*C>#WW54QpAkK+=&:pSLbh?Y9=IcBAY^q%HITpb^ZdCpWBa<C\LFu#db*Vn^m>wHaCNVj/5&>W+ikj*
wDP<n8 akmuMMBb:/eT%c/AMR9WnLIwR5KIGu#/GB/ZNInan$\?b^?Fq\%W%t4An9/kXqR^Y=c:n=pnHD/1YF+X
1qBk@? Gqij!@TQC@8a9l^P^6ZX<d1<:R:X<Qp#?p%&LG%bY1b$+P9h\MeamlTXL+5tVnA6^GwyFuY6qa%Ny<>k
QqN1^y ca=P8iiX6C:+p!C#/VmYekd:?GK:>L9Fb+^N>TJPCJYt@*LAy>etcR#Yqc8Ym:i\&Nucdu1=V<586+QW
$PJhCq m*$/mb&XPy\8hMZTt:MTd6TmRcSt\RyHyE%:wWt\#hdSl1RQ@1n1G!q%DidiYPyjc=cl%wKG6jwQ1HHu
K6Rt/m 5&lVTQi/mH5Vt+bk+SY@i?&?HTVM!JVNB?FcZ%iClE:8lnBcd&kjN44XKPQl4/JJ6Zi#Hy6M6dFyJLi%
1?l8B1 5RcLZdD^<\W*+9k=ab<%F+Y^<:Hm6cBnaT<+A$QV%8SYMKI%Dp+Jdp@*pbjVTEc$epqFG>Be\wR&^C1M
5\QbZT p4G6MR9VCt%a+1mRX=QYS>XBi:=Sc6ld5JqQIdmkJGyPT1bRnu?IR^KY*j&yVhC9@jQC>XNNQ%&L6q>d
?a>9X? 1p$54dCYt1$/i?h8Y1=*hJlWPm6qHeK6CweM!e8!6LMX9/y6nS%F&uVVkKkblh4bX@VTi%ly&n>JLbZ!
WyqZ!J kcb*R4jw\6Tt9kGmZc1X&C19IK5\9:$@==9+8tkQ8/MQp&d/TiqQJNPY??I/LQH=T@Sq8G8lLh8SX=Bl
yQc#eF !:PPLqjN4c\Xdpi@>lS<qLnl$LQ/DP&!1ANN8/X\9uYP/MWDiiKd?AD*q#+?4&Bwme%!I96#Tb1^QinI
SD+=*4 DZ&qXtiKGcZ+ZyGC+&*?qm\4K4bIZa6LEnPLCm$FGa%RNBiM@c\bI*F9C!1kMi:!LaaCP?a?D19ERpWt
n#wyVc qn14PMuZ4E65bStSq&%y:n<w1V88uXXaaw6GF:phQ1/Vm!XpKLQuPk@T#8wD#9/InHB$ReQ^AGYDaWad
J*mTpu !Fh4KuS$e4Rep65*eG&R5e&h9t9uThNKu^ncBEwlV$T:uqCcXw\iEy#w!q^t>HHB!%jwKGd$ARA#=m9B
lwy?4E &qkAh=pI&=w+9d:SKwQtPRu1c@^LTc@h^pI/*9e=S!M5kYjSK#B=A8hn>ALXX!W/cwVe@?%8>+eFk%Wq
5DXwwp eRXT9b>4jl>!SFnT68cwWlP1aZ=Q4Tp!/<?hp#:CFZm>9a%18N=<PE1@=\ijB9P+nK=wBD<1^G^<p>Q=
/bDYyE 6M4KAIec4W8Ky@mi$$Yun#S#:!SmW^kY>liFtWKThAi%t+&G6ka@6GklG1bLEde&cTR6jD?\!:a+5#:D
Z<A\Lm l>9CB#Xk%q>BcB+S&Pa:LRN?9QXnpt6wwitp@*SwjTD4%w>:Y:FMKIIP#ti:WSL9eVh16C6T!*#5RMQ&
pH/\4p pu*@&q<<h=+Vt<i#<RP<>^*#=jH:<bdmL$*n>DA:nZ!PbMR/=LR!NP<Khd#c4jZDL9MC<6ZC6nP+y6>H
i5t%PE F>RJy1DLQ1tlSEbXTdy>6W$bpuaiESD4Pq=4?KB#6GT<FBXmHN*@tV5B>\H#Hp#4S\ZM<^tpn6tDbee$
X%RXKn =uVHhC4@n?AZV$iVHIhcqya/!L1j=PDRd*D:EA/@FPCCn<1!>K^+YlA1jSICWm$!&eEtj#E&9w4HRYmB
VaTqHN :wSH?cl?R/+&Ei:F&X\WtadbVD/Bqy#jR/b*J^1HJDi@cy<nQ?:k8cR#?XZ=/i&p*VtyQP/Slj#k:t<Y
D\!EWN &/&lyWpPM1^R/nmcM9S+XXdml66XB+=ZCejVq&XY^VDPniBG\>Biihe\L+^+B!X\#SK+8aiceD#bC^1%
SjCV/! ay:<pknMP\Aw&#Me+D*8V+%^Pe+k?auZ>yQZYh/WM/HyYH/jqLYB6+!?&!8@MRMSm=P##WRw>q?<NNP5
4%\8i> d%\W6wWGc!Ka*6qL/P/MjeBMSwJGhSy@%JmAjKa*RS8+iHRVH<BIVMeQRQ\*yPI$JKIadE4MkwQ?b68=
YSPp6Q 1\=\c<aX+FiMD5pjG@@El<>\mT&^XI:9ZiT+%F:aPQWeh:lSZL4VnV<*MFZdED*5mM+4ibQDB\5\TXV<
%Cu$eS 96cy=9:a8K5>!nEk+!WcRYA$:^hMa=uSFRB>?YNjwn#I+@tK@iN9G=LllHQ<:jG*<enE4a*H?Pc!N\L>
KE:Thh ieY^Z\aP8H%^VPuk5RG>4>/?tnptAu>9@5p&*niL^cj@k<D8adCymmpF1d@@qD#\4R%jy@/P^/<<:Lnw
bZP$he /&K<Z!FR%>B?y?ywlLtP+4KS9<^6X5##c?S&64GHAARjaLS5kJjVq4H5<kwAJANRNEMPL=Kp!Nbm^j!b
a@e8wQ Jwk4#t#$Iy5SWGDCAdbH>9A/TS@H>5kJBGkPPwmS4LjlI4E\FS>1!mbFMmL=&\++VSjQ*H/mn/<IR?<!
*6%8#5 F>>R?yZQ5VN<y6pl6D&:V/?ApB!9KRZWl<j/I@kqnA=lA^Y%&^qHLjW9\6qc\!GERThNbEADCIE:ii+E
E/1RaD >t?Hh94tB^u1J>tSQTN4GP/ccpPYEbaC8KTMeEkH\nHmtR/em>@u<Yp%TyR/E&u<@X?W^4nS&DVuulI<
ACCc?V e!J1?p>JEDV:FDVP/Wyb?T4Z$&Vuy<>\HF91W#4>FYFTV>Numk9TpEbT\<tKAZ=S+WubTQmbTJmDpXE#
wI5Fcm :H%$:AACGVQSBHh:yW:e*Kqjw@4w/$T8K$+eKjhbj5tpp5jp5=t?bM/@hLy@E$wh/DWScELnk&:NbLB$
a>LT8E 1?t/=SXq5A8&wTE61ipWIMkFMP4^Q>aSp#VR<a9@#i$Q6\uVCGWKM@pTmS1<6:11BcS#HAjq8VY*m15n
eDFtcN 8CaWIJJ>SXKDj!<uR/>=tkjVj:^Cbpajulw9SlJTiAn%!e8*FJ8:Y$cci^Ztb^R<w+JN58XqYQ@tmqc@
ddtllH 9IKedQIyjp=?y@ayci*:hG/d>J#<%KTWyD/h8@h+H9:iw@M#C@?tAb^B\TGP@w?i?mjbFik@iiSMNhBW
n#y44& =AbA4qSZMh:=V+JZ+jqQGbb:CkMbWne!?Cj9ma^HDFdn\16$6$#yL5c=G$ud\K4kqb:F=H<c*j?p#ZHI
wWl!eY 5L+i1d#TmWHydm<Z+NplXnH!h\H\H4BBdtS89MnZ5=HRiYenBYh1djB\4KKZSe+JlGQ^$/AHbPSi=HVw
MIXWi/ HJu6S?jwIGwPYmKAG%mEjy&nRiMFCCmpRV?S=+\yG9R:kj?SeBNkV9jKSC*cSu1!iy1IZqdC@Z+S>TVQ
%HAii! Q!iKcD6=@pVT\SVKQFtLhwDC8E!L:tkR/m=w$TkBLnFypAX<cKy$cCL=jWT4wc:!Hp*TwyPpQj6u/NAY
?4W<Ci kmiG+Qti@H=qkR=BIJ&BW:TwFMLW/#RwB^!&c!VWueB6LSWSPL=NY/SD@eu9Q!cJ>IdkVJJ@myT@!W5I
Ki*dbH @P?GEYK\tiS@Rhy:nKSHPHV$R6Z&1Swc5H4C/^4$B&uuchLPtn4bYK\d9DGHmMC6Se+5Dewm>abyJjqT
V<NGm> 1EPL\C4:j/V<GNK8l1RjEA>nwFJH&ACE*mj>ATG>FepQJQu#CJ+E6e\#R6\SHiuQTiC?!ZmDnQet?R**
d>>^eF %nJIPXD&uc:RkB6iFK#YwWLT*kSSl&1Shu$/W+9iB\W#1Z<q/DZIE$\et&6%>KdMX&Vek\ZbclY5Y%8R
-A@Q#T 0001c5f5b5f00110333 Page 487 of binaries1.zip
8#?/$M h9en@ilD^8Xupu=cKcEaDWSj%1F/GnAh$KFd=QtDTp9XiQtpQj+E4tT/mEJJjV%JjSA&^J@$1\bJZ#^j
/b!&\< SBBh1liyB:VW/cS@BcS>m$u:LyL<@Mpc>AGy:*@qIyyHjmecNYk+!ie%PuRBa5iZcbCb+G&lp>AnW1<Q
AL*+RY %wJInWyKTd5J*mpE:&5R*AH4$GiE9h+>R+68p@tuIQN%F@t>h1wYbcnA4:wPybQuThI8WLuPI9$<C&c:
%PlIL< 4?8w%@NPM#Wwp?R*I@M5nNRZVQw>Y\MHblImwPVhTAk8*&+l#@tpZc6IP:hV6:FcNJ/W8$41@^4$*/VR
\H#<tb ZJK@&1CBME>wH1u9QM!4?Vy$HI\*J?9RD?V==n\h?wa<V=j4$Au!9DNFS+>DHcT>EK^CSh4:G5G#pe#j
:<5<Yd 1/R@XbKEVLDP=w4Wy*I<td>\&!uKS$K@p@b>S<dqIZp?Ie<JBP+N5l=lX%%C%l@+pZ8b4NhWM5:jpQEG
QbM@^9 BZ\R1iiikpaCR*?Sb&9!QAPM\WIhTmF\PVwSRhnMN<n:@bcpj#=Vl?Cm!u:!P+*p9$Ht^^y/A1KqB8MQ
K?hb*k !V\Hn@i9pjwkjM+1Zwe8pZcEpH4B=jEBpk?PR\QJQBqAukFpZt\G8%STH6mVc/ReSB%14mD4q=RdNE>E
TFtY@M =<p#q:#@H<l#Q*u?TJ=ByQ$>TQpYlH:ekjcVhRqc*C@JikC4?<W#NQTc&^9p@b$t:X=ZwaM#MDTX4A8I
e=PFAk HVKG+Ai*jR@Ii/\k?D44NTmj\LWp<&$B?j&=4\d>Sea^YW*tpRdmq&4SZjJ<RJ=kY*TL$DeIihcH9HiI
QC/k1$ \8w@X+NiJZnjJP<LuI@Z>6GkISBTp@!iRJ/HTL$RlG5d1je?ci>i5u=?lHqA^y55YVTjp>BY$y>eR4?&
wV8WLQ kcN^klj<YyiT<SyL<A$khPI:Au>nqk+Xpihw$5=Q!d\iNq%LcAebd$Kj+HV!ISt@PE/?\bJN!t<u<^n<
e9Pthc S#\T6TmW+QtInCelYikM1T<bApmT>6k\&KZw$GmT*%FD/Ay=LmjnMae<XYV?hkFuHKRj+CLpAXpEp&A?
:1^YP/ p9:B@AZcm:yJHK4l1$eSG9q=*X?Q816=>Ltiw*pSNFAy/bSiTV<jcZt$jkcH%FM+?8<H=RL>DS@+DVCA
9m^y%W B%#15Pidp=Vwk1>AHeQAJ$16RCNKihTXW/IQmT\IH@6WBVw/ViG1=\/Bk\?+awHQibWC4ZqhmVb4Bj4e
5IblI@ RubSeDIDH%BD&Sj+$Khc\5m$REq>S5AH?yQk^/FD<*m$&E?NQuDwWe&=lJP4RMlI1JZmhRFJ5>VwQWFE
nDW8ST u$#&RWQXI5ZF$6l9NFYmu/RyK9wb4hYnFl4B>jFh^NM?LmA\<JqeLu>8P#@unAw$R/<kI1/Aypk1>P%5
S=6DVh #t95/p=WI^<ju6dd5X#?N/RNEPR!u\Vw$bBb5516Ic>HS#kSBe?SaiED@+a$!AjHDQBJucXC4XRCc1YW
9#6cb& ?\l><i!Zb:uXuIK&Ch=l5JGu>eN+RF*kpAI?D5J+\N!A>&YW%KnSZAX/ZhLV5aA^Auk<!ee%4m\Q$qm:
LISXVN wR?$9BMGj4Q*AdBRl9&iP%PknlI/KkS1:\d@l4FdZcbA!aR:?*aP5HAT:S@4J#^lZMEVAZ8itmHRhpP@
p^44<X =Q6LQ9TGQH#kZby+H@1B@u\*S+tK=!uyVYn+\GXm?MB/kHpEidYu!jPy<\IiNcuk$j$b<4^@Z=VuLt6d
k+^SS% *H\P^SIb<B&5RtWVCeNE=m#MnY5/&b$AjKB?8BpMH%l9&#mi4nu+RJ*\QtAh\S1CeaN^kQFk<^4c\8ak
?5?B8@ #BN+l?\Jjab*Bl<aT&k:6A9c^<aD*nQ$G>4PVXhTPLDckQu\pWbB&@NAEtn/#CtC1$>5QpP@IkqZBj>t
^ctYhl /^1iMQbRB8ABH@!G>\AZ5?FVX=A@WDcHnF<Vj$#dCY&CPteVVlE8T<MHL9*Bttj4H*+#itHVmuK+?nKB
J5tK:/ Mp<yAe:kDKWKtub6C8>Kl*pIc\4YkPe/aP5I%kHAR>%A*#w6\QS/L*^k@L>byKB+aj/^MX6Q<8BDyX>S
?&1<ci 9ypKa:iIW>Q^k%6^WWbML?jCS:+SKh@1k*j:>F\BiJmDMNcdmHRIe\iinP:A^=Q8\FnBB>aF+IJ:XjAB
hw^YT^ YkV9DiacjGD8\Q5+Xm19Me>*!jC!8RFypAh>b9&E>\VZy8AD>A#iN<\BYL>5LV>Nm&C>\:1HiRX4Bia1
ANKL9N \AE<>Iu%n/Y^8RV9dewMta/ZLMa8Pk@9B8kMjKAQMJ@?t1y!%Rj6F\JW1Mmky4RQ=n85V^h6aHVC?S58
4ShmIu H<EH4q4BJ^:pNah<:Ryweu9CbhuIV4/N=?mebuRI?k=4H1:5\Aj8L<GH$T&aY:AP&Q\C8kl6lu@jtany
6D%8nc HkWj&I?An5Lel:pGe\dtC9Rh?k*>AHnYd4lCA^?a#+\&M=wJV=kDK=SKi8E1qy&BMjj\HD$N+6FuXJeB
BW\ZC\ I1cTeyXp&ZCkltmWTDlSPIq5XR?$5^&cJD\q+c5RKDnWBAX+@\$pTJ<<+XBTbtGJ*V#MM6yGqR<!5=AB
F?RmIl mVCLqK+j=w#5:D#RKtXa#hpY/8/B@ICCWEnul5516BWX&mA$LN#^J$kbDLm5TyJl<9IJCDnqMGeWbJ56
4@W>J6 w>k9J/T@G^6JMePNcWkP<pyt:R*%TwWW5#5q6YM1TaD4LhD<A4lJCy1jJQ4DuGHP5yCKl?Sq$ibcdCM5
=?MbXV N4P>$G#Qhj&!=lZdEWjjlw!B4m**L+KnKLjRZyln!!nK#e5!h&+HCEaZq6mkNcSpC\>acJ>=mK$\*&#J
pY/8LF #<m#p6#YH4u=q9^Mm/$a!tiae&!FJWWEINEDwMA!Wm+I:<JtKT/&PIHqt6w>BXyC8kDSPh%A5RT1p\hW
MIV$yd WWttqdV=1YcSllRZb?SaaClVZNA6ack<^5l:jFKheNXQEBm#Qu<Qaca9nGAc>A>\&balNAyyIh^FT/j9
F@Qi#F ekTeQtidm&!YIScdlj\dYk/uDSqFSaX=BjI<I\XlQyIZuY&&YWaWD4QaCBVw5nNK!Q5tWFuW5!PMpjZb
eH!<pq XP>/m#\B<8!na<$$IHKG5!4=jhmjBdLa<wcMh5HWlZcC/nYy^F/au\F%Yc&n#i*pLnhKw>DtjkTB8WiS
Q/KF^S lT/qd8=ZA@d6tSqb\!C=yMk=#qTL>W!!8VlnBF6i<P/G=Fp6BBS$AXpbYdtRXbSSZC^jy1Sn#AchRJW@
611>e8 D<1=9ApI*B4\tB+pyeI:ycX4>e%*byCiRY5Zi@#$H8Jq:l\/aGRkC&$\mmS9?jQ!9FGAdma4N/Mk^?LS
bTbh4= eJK?n1XDadyW*hp\XVj?ZV=bi=dlJWA99HCC*JmXX=SLi:@L>eN8GYYHF8@&V9F8J+VHc&9NK<w5#LBq
++e>&T A@RB4\VZ/*CTT@e5Gyqul^9tl:#B!R4\BGhW&ApMmyc&ljqFbLuuFeP1ejYCRljb<pbA=?RyDFw&cuTT
Pd^eiC ShH%5YVqF5A5Nje8KRKcVWBPWyB1TD=$=M^#M:%H+N##+D\IA+Vq#LJb/B4#*le8RbhwD1ET^Sd1:app
>cYtuL Z/ZJbCR!CCEbZb\HwPC51y**eKc=l4MDYSaAXAXH=Y+kYC&pHTX\ZRa&FH6lwSZA:9\DtC$Dl9Bi6XD\
/<lMYq MkkSKC/!=6HNq<!/l%/A5YSjl=8KHmt8VTQw1jT<AuQ:pt\!hnJcWueninGQp@*\XQ>Zp#IX@N<kA4:A
aEDc@q A=j=1XyyZdBV81ai:LRiRDI6njbP<Z:95VVVc4HDEwy#@YkJd=h8TC/Cp5DBm!Pb4pGWG>A94\nK6tBq
d?>5Bb /hCSjhZ#N?MLE4$T=h&k^EbjiV8K9nnLq5jIZmeK@QTYRccn^=+CG!RW#B5!JM@TwJQFc5*QKGnW4uh9
&6/X#y F#XP@b65:/EAd+jbiVq=h4K/GHeDGQyZq?=hhJAHmL6ZWDm>?l#9+6uQAYLL5Lk\*%JaaKqd:J!w8ST?
qakRWj PIP/ctXnY!RuDwN=WTT9Q:8ebLjB>YpZKZXTlqFitYVhAmNBtEjuAwj>nWB+eV6$h*5t$T^9Lb/MWBpD
YhQ?:4 mmYMe4u4^#<R^9q8\L!CLG6J6tiVm$pcdFh8GNe/y?WJL&W6!YqAkbaBWAEbHk85mPZ5q<hk4Tby:d$d
Tbd5>V $>9bGEcD%6Fm@$mDNu1BAhHa:J*mIlwHupy@Q6E+>LiRV%GFI$<BX$5XnupA!XVlyHiK>+R<A<Nn5^Zc
GHQZnT KCe1e#9uwEC^Hec^tLImhq5J+V^=BFbMe9MA:%Z*4*@aNuq$+>@Ci9d*#4<6>NR+*jMw>@j#<PG@k@SE
KJaGQj DtaK@/LIW$%TpqKYWSu=iRZ8HhXYYAS<FS%!Ne%*MWJM$u5&%dWGu=X9DNXB8/W@J8>XC?XclM:%=>:@
J9BbQR wL8nm1!FNmDI@<RhlZyB@@*at&qDwHY\jJ<myyHQ#jTi96E8PFeZiSV:VGK5?Tp&HZa=8c&F^RT6tSDF
kp\6k+ jQDw$\AEPZQ^cNt#I6u4CBAqE$>JQK%J8p\uTH&JeMV<h@8@EmWSAIY#^D<5kKeZhChZXj>R5F>iRZdl
81p9y5 !GI#i\G\a@=#&ciyK$^eJ*&Fn1bYm/Ecq11QJ/C<:=QWRi:W/teD:Iu@BFQ>8PV?8&LXnI1%&yJ5wVN!
Qp&P^\ Z?TG!5?ke\jtWEpS=NuhiX/XQVWtw=+D=qGL\\*!LCFpRGX@C!V#98X8GChZ\KPb44Tu*=$H<9q@C!Rn
a\TpRD Z$^lC4I>Pd^qeq1P^WdptAI1iT%@K5qMuYh/!8A<Y9$$nNh/*km=Nw8q8Ckn!?LB*&\t/S$6BSad+b8<
k=yR*m X?I&pyMn!!GiTl>cIYNyidRLwK!FSKC*RZ@&\E>dSwHh1YR/+Qud6h$hwctF=JWD#Eu*L$@Y/b^H5qhZ
/dQXZ& LulqPLqyyuiCNwI$SYCiw6A<8pwTP+P^NcRq8hW#:h#1tc+!a%j%:!C>&*WH/m!\&<C>J/HT5F>/y*mD
L@ay+* Q!TbM15HXq$\1MC/F+/Ekp49FP?CcyJJcnhZS#=%#wI=>JZKdEp95uVJm&8Zae<\b?hqYA9Jkm5eBj6c
1A5:!E NeD&9H\L5KHPNI8LH@X*Auh8B\$Me9@!dq!wM\QEYkA$i@:&Bw*$!QIRpcP>p#%tSK^*Dt5&#a9##m58
qGyP9Z 5tT=6FTp%k!!B<HY=B\/N+5Rc/=G/G=SDXn99DEYD=DY%aD$kiu6AbNaDW\c1Nn!:KM>\Nw=t?+TE#5=
$D1<ei !@YY6bQid#nFC>16p$4%T1jDR!9\pH#etqJ=tbC>=iqC^baCL=GBVAZadBladwdN+ka1yFyW5u5WYP\n
dk\&bl C&*DaM6^Ny$Tc&j@ey&q:cPyqG9%?Eq1jFc\lC*CG/bZd>nt:ZImFd\W<9=jG:Yn?9%uqVHnbPCY:n/*
peX5c! 6Fu!Ta8jE5phMy#NKZKZij#$Sqn8#9Ga4DQqXE4HK6m@ZdtL9XP<>D*L*Hp!*%t>:u1=F>k#?tTR\%\R
#dTkEu #%Em4*MB8Hp%&BFe!W>9JtcQdaV$c:Md<HtuI49eIM:q/6ZZ*c=5=%J$=eKY+bHybG?IwQhMw4i1+=A:
1yN!ZG @&pl@wluqp68B\HPqjG$KH9TuiNt+PqPZWmtN?*CGR<R=:aCi>T#1jJ:HPKWkC>WA?C5>JI4!<pAkPVu
P%n?=$ T9Mmdne<p8*8Ty:cm16eWK/hD@ckb%P>t@nRDXC6^5Aq5eA=tk#+9N%H/RXSLjqT8$Bw&\qSlX*LqYk6
$Jq\C= #GKhN4kTCX*I<JVi@F$=d5y1Ll\C&=Jun6&T=WRX/p1&Ya15GXq!16pnhWVlMI<KIq$=^baMt*^1MKRR
SEcV8P Jt8$S+=X^p>ik<*Ca9yA/XkQtAI96a::ZeY=ab#5Pw>c8NNe%JQIRK=W>?pMTi:pVu:/QMd5iX=DRMFc
HFNWeK #%5^Sbl=J/X=Su5F!n1Ah:+HF%M/mCS&p:q%PnqTbdwK:#qyBMFEyep?8aR6!\EBynin4?tp*NQ9L^9T
-AlGX8 000f1f66e3000110333 Page 488 of binaries1.zip
Sy^<K^ uQ^c+SA#+?XeY%q8>jpi=MFKITmSJF$kqJJ!!WZQyu4VeD5F5Ge$<GdVSqYV@NS8AlDWMT*I#LALi4+q
?X?^!? 6qL5+MdSRWC:b?VVw!u+b/HhQL\pn=BMYT8e:Xy*=TT*MJNilZWJ$<?lInP4AZ*Pc1+AWG8&?huyQl>!
SRbG>5 uCh\5GpVIaT&i!TX+&C*IkA>T8\=lj@IHm@:h=Dia:meFQI?wq46uiI/qILNmYV>m@*jkNwkCL4mmiZ=
aukWpd l&IeNeV&lQX1+Dc9VNnL=AND&N?i#uIL&d6JFwn+INwV!b:K!WM54w%1n=\hT+nuAie@Zi#BTbdkySQ$
E@&Z4% yyhuGA\Bei$/LK*c%*mB=XL%A^utT%+JRMkIHewC=R^MGwKadPp=MPk*9AHyBqk5u=GSii9WYBiSYT<j
hXQXX% J>NVJ4pI%edBAN@^@Q&QY1%:@^:c4eCFLi9jq=NHGq^Q8k9<uXdD5^4q9!$X!*VLV9&Py!Jh@Y?SAIQw
AN5iI! Yd6PL8n^e1G4u1e:ltwkuC5ehptT?=SXl?e=k+h%S^Dk!S%hVA>F/hRAATYVdBbbXQeImK\bEA%RQke&
&eJ#c& i!W<JhSBuu5G8=qT&D!j#yPuqQiEn*$G!GN^kKD*hL=Vi\HT*hNbnE<Bpc//QNe8%b4t8k/NwbPJV!X=
ZTFQ?Q h:Qh5:qi=&:i&W!/TKpt&S69KwX\m+6p?&MCiB>+T!/8^y!SR%+AEVe#C*NKm1uaV5ayu!4S?56IGKTL
1SK:5e taN6HLLea1Ae<IbPpKh:tA:X8TEB6<Zt%C6/IaGP=Z1uiGP!QyQyPXSFZ4q5yP#QyuwnHiWF<E>T%Lmu
VG+uC5 wj?Pn*a<Dj^<N1:eBh4ktiGE#blpQ%j:Aye@ZI!nJ$MJY:GeS&m5Qe>i+8R!*RyR5kNVkKGF#tMQd?*w
PyhCtN eywJ\m=Ij/+j%S^Id+RGR1c*kGWtY\VX%<8YX&VnK<#Kw!jIqEb/pI:NDL9#9Y*#@P&TD4$T9iT+*VVL
lM4Cl# !cRAkn%iCYdG!wBICJiLu64@jeu?4$R1W1I+L:5EJGM!#E!:KjiXNyb\dNuA/+KK+lD6M?F/LdVZST=G
\5Qhq\ %1Zk>CINS&mD+N\eKn:t@8W>H$?/My+>Zn@D<q#eG&#m$I#iTc^*F#^?QwWcd4@I6p>iy!&i!@w1kDBS
knu^?+ Jbb8<e/eG!Tu6:#dy?XbSqy5LV&&T/Dj5It:aeATki*@bL4LQK8L8d^D1&F!n*9!\qbP5#\W&hY5qweW
^#4J&A ^nt8TlZ:$hIq+45$W&VdhGXZ1<4!$GHyQCGj%q@BQ9l*?YdK5\hSELtP=&%iwe?D<hlp#H<H+=ySpRD%
=NBVIj 6#JENECRbRL#JJd>&*6T^DtV*Th:Ch+y#:X<cPGE?:5V?eSuacw=tY4ul1K:t<hQq>Ik%VQ^?ej%jb+Q
je5N^V >6TBd*>QTI4G+\B1$DPbV^>8yXPIMSdaYbp+TyKi$8:tAySLli^61GYqie=S<PI?*Sa>bHCK9MGiw8ak
>Q5*>R Z%86MD%H@T$epE&:^R1nQe+d$P9%5E4LGI!uwtttb/KLKFhA1qPteFwa#+iBGJqS=MSJmMmIQJ5h!C1S
iLLl*c ^k9y?e=mA9KMAS$wByq=Hi^NFIc\C+R:wXGilqFFJpqqDPS1>t?#&=\R6mwwYJ%I5^E!C6qRi*D=nFI>
KaA5T/ >bI*@\6+D@B6DN^N:L#55ub==Z8iNMHlRnWcqN%iBX!$^qumYZN6&QjpIp:=\GXN+=#l<t1I>qw%>YBQ
Rh*jQH @LiqQBeSFD\pF!TE%h#dSS<<hD4X:wS!GZq*hud4KREDhpmA5tYAJ!T#l<*mTbyeTG1\FPeYFu4M8nM\
c^%NF$ Gd^#=AZuQycC:bIGC*%/@*ik=pT$i@Lp/bPZC^SuTVE%@:@p?tG8%9ntln9j<?n!Dp5tdI?*98ll>Vui
cYy^5N BB18QVmB/Iti^<?un9QAeZK^^jX/#CQBXyy6XI!PRqk8!yLJ=&<Gn=@i/Q^bD9B8L4a+A+#yacinqVG#
5a:q?9 BJnj%Y##wb=AeFANMP&jttP\*dukaEFSbB%5Fw8=N=\^p>>nkP5mSdP5qw\CM=\?t?u^M^mF$NpDHBuX
1Vi/=* 6^JEH4duVkwX@Y#1Q==X^FbZy91hpP!aBLmc<:kYDIjVWL8%=&@9\aawPyT!iNnh6*5/#d6IJ=a>?8<&
aDd@?A +JT@l=KNB%I>kcD1Qq+J#+/Xq&KadKZi+M@juRh=A*yRF>lS1<6$d<ub%YR@a*H!LM^V8:+XZqWiYV<Y
Vq/kd% YeNGTMqRM1h!C&*FhM4Cnic$Em5RnM\<56ZJ^q@&b%Nd@t8#<XHXFZ:KEu6eNVD@cQ4p1KdR<>ZEbhXA
yDRtR/ @+&!y4\/<H?qNblbZeu1FRAX%aD?A?M\9=wm##IJm/8Diua#YXaN&N@Nn8WEj1RqE*k?S9SZQ=WE!&jn
+ywyLX $&uiK*e#!i/Zt&EuC\q8JyHqAnR$njAC5QW*c^kH4ATtVuC<DKQ?YR?/1>yTj&@q6=8Y?V6yDb!mMWta
cS#t^a J9Hk$<tbFG6&YRQB%k:IIKbGQ:KXp/XJSMpGRPVJQGTZheldM4e66JdpF=kHtq?Bnb/W?Z>:@+@CKwV?
kJQd\B 9jZ@@+YbIQ?MdaHmZ=+&KQ<Q6BIC<8bkXPm@9@@?@99::??@9@@?@96:*6>4+NWi@kEPheA=DVmbaM=L
D>^X5K +Mq?k:MPeNIB#m>aG55Hb\$$httymnyAAIeI+AABHCKA+\N\lACPE5AbAnlHAGeJ+BTlpbw\IP1@<XWk
jhHZX* i%@pCPMBH5&DXd:W>?I@*6!E9*?+YKXE%hlH1lG#SbShGV^qiem<F#^4GiL9TyWSka8C/t%I\E&B%+%l
q98m5t <FL\N>aQpel%Rp$+KZBc+HZaE+iih>kDR!p*Bq\Q@LQYCX\R8FRY5Yc9w%uQ5$i*BYiP!?m>MM8T:Y^9
YCKIZQ I9y*tk@\W9C$8KtqZku??@99::?@@@:??@99#@89Ehu?w1Jh:ELKtKeBFGSdj@JEIB9qiA+<$:iu#ANm
Y%E@nX Dwiw8kTeL9&>DkyenLt&MP4Mml:m8C!K\dWX&W?yKdDF<$BZ%u+<biXKQY9%>hJP\=dwiiAEimu1eP1b
a>jD6j njQb<#j1uPybhNWAk6i4j#mwAIha@\<eQ\C4KA<\&IBR>*hQ8bMCD*lJV%*kAK>*u5Qw86AA6@8:iSp<
/1cW@8 k^M*q/?t9@P#BJ:JCM:i<5E#AY:u9C$Bd#AXpIM@MAKSpb$6u?m+4ZSA/i4$JpC>:4Z*9wu5hb5BQJR=
tmCkd\ D@?ii#uI&*aD@LB=Yu>:AGi+4L@6L869b!u1MctRHtW>W?^y/^Bk^95YPa>6BkA\/VV%A@i54e=#LmPC
*CNR^T M$H=Nj&6b!:\h?h<HcqQ&@/$y+bnL9>E+Jc\5?6T^ICu:N:J+mQ#!15IhS^I8m\*\Np<b$8y9!J\LkkH
5u4\i> 64SJ%R<KlRNHie+B#*Bin#XuFScNB6&$&@AH*L8==RhaBb+uQG:nRZBbX<*BPuk<yKd1+EcPHaSSZ*XW
I&Lc^# G$t>T:LdehS%HqlJWB?nuq=Gim&T^:NcG*DCWT5wATJe?q@pu?%HFiWBYRHulP*b6Z*Z?bVH#Z*\4NyY
?9CLWY hpWEDm5BSS?+Q\ciTN5:@XKAN>c&5t8pXLhRAn:!$6^HkP:SApiI1hYbSaIu9h:XulGCd$Ga\ZCtZ6%T
W*/WMF wa+a&*5iKqNl!MPkFd\$Xui@%t?KAmXbS&cR6<GIKcX9486S%Lhp&+\5<6w<l6Vh#&J1=RY1iHBAKRP!
W+bcN< VqRH%YCtAuZIKLbd/My!Y5*TF*n!hRW+W<wu<<cedC*MGwa8XTlR9\^dkVubRwyV&81YQ4?hw$DhT<AG
4KN%qc AmaaXEWT\WFn>diC+8eypMim/eWRwYZ#+ZZIeyy*#y!FCta&&h9mQA1ndm@dQ&M9DM=:@!<en+GQ^Z</
:l!Wa& e\ejl9>ub!LD5JIJ:nTGkk55e#Rn=WmqX6K=>q\AX!kDG6!Vy&+9u*PdcwCY+JJy*&1hElGM!CRybaNP
XtKHnH C%yD@6tiLE5W:kNklBwXt*5XF61ye>n@R>?B&@&jH8diw\8!CL$9AL5yTn@:FyGyBL+/1:?FPF*8Bd*\
MiZn1q %iS%Ji1Wq&&BFR&6cA9u%Pdp\qHW6!1\N?a<WCXW=/Y5DjXL&m>*NNt>5&p:1#i\BS6M<5dcWQidAE+\
Th\pen =w>?/q#JdJhJdHGl&XyapNPG?9y5?*i8\5D^b68@M$EA:=#AF>A8XReAdnR:P5%M=GNGb1:y88AFX!9A
<>a%mp $!d5$RDyATdVe*C6&<=%:=H8eX+*G5Eq1<9QqL\J\cWQbl^I*hi&je:BFjZZ&594Rl^+eRY8R:b14h+L
IjEjk$ IZm4:XHN:TL=YJM/W?*6cY$Guq>:X&hKCm=/QSt4b?&4\PH1@+E=F9mdyX\ItMh/DCL+i&WEE+c\YpM?
DaF*LF L+6H<A:LhkPCluG6#+EG9:JWeiW!/QNm6/uQYT@8!HZD?6tL%iBV%e*1\l:n^itTVbN1Mj>JV*aQ^AhR
Wh5GiP e@/#nk5<<j:@aSpPDuH@n!#k\FN8hijDwHn>q!adwLP6%tABFLuQM:AABi@#VRhA>j8*lk&kL*/8NRaw
*@KJ*= nJ?&eRAF<4?^^\Aq<#>apwAP?ytVhqBii%8ykK@y9q/icQ:?Wlj+Vt=j9ipBja@!:knilh5>:^#hA\/<
pnu:V4 I9h=XtD<Y:6G<KL<4<y+Y#YCw?Q14V:@4nJ\l@\9T*qZB<eJ#%X>@\\P\TH$BYwYKMyBYGmpCS18l5cP
a4EnPu waFScQRLGn1G^4PlRSlwyBmE@NC9%LWS^DPlRYqwbAec@wdG81EBMGm$FB4Kk<c=wMEbcERMGm/F^tKl
99lW^= kY>wXAacKwdGkcDBd&lEG^wYlMdewaE?cNRJGy1B^4PkRS^wBAeclwVGXKEBT&l$C^4Tl<bXweE%cGRN
*bkGXA GqcD^tKlAWJwFB<c/wLGw/FBY&npG^1?l5dawAFVcLRaG81G^qPlRTJwBBRcHwjGyKEBc&mWGByKlMaQ
jetZ4R wWGDcPRMqD#ZGi8HB6KlWYXwmBec#+RGM/GSPGkaDl1Dk\c$wNF$cCkdG6iGBltmpWhw8BMcT+RG^KDS
WCbF*? SYmwGB1ulAdLwbF&cQkkG5PDB6!kWX^w/CEcl+kG1/GSbYl+HBy:l\aWwqF*cKkSGn?FBt8lEYbwPA+c
6*&&hL i+aG\KFSh&lIIBw*l\dNwbE@cFkpGy8GBqSCFd^PDyXC+=:R+CR$WkkN#$Fn/NAARVTKDA%hR?QC$KAe
\+6GdJ /A*+knAnNLaNDX^Dw!VS$B<$Hk+NTpMnA6H\J#RYCR$MSKQ9$BA:NP+JDTyCI+HR5EA$ykwNiETn%hDR
pTw8a! NDSPDR&&SCQB$HApNHaPDdBCw$LSpDa$#k$N\pRn!hA\NVVYpl^hDcI1$bA/NJ+PDcbDI:HRMCk$NkpN
jHtma5 TEPn$hARKVRiE\*GR!P/$HBENKaMDYlDw%DS$E$$9lMN6pRny>B\M#RtDY1tp?VwRVTEDw&Zk>LIX$jt
$!db\5 @RmCnD^jEIcRI$qi:ylybJG&5khkGq&pdVZikKuL?db8K*tIJ6LY=acD<T>RAeRFehhJR#\<^&puDRuT
M\A6CN :mq*uNTjQp95:YIXIaJHi=iQR^1Aw*%%:8NwYI\PHu\8lL#wTG@8$$kZ@?^NmRdC/P\!y/b^KTAbatJ$
EuKqbL hjqCw8E\uAwFmInSqiuh45p@/IaQwS&/iVpCwFEi8uuj<chSHj:=Gn5>P@dRL$AelqS&?=XGZjBpRmD!
MF*5Hk R14*FW>//P\YkYq\lhV1L\*TkA!yZ9eicS\F!w>d/Gt%/<+a^ECk4BwEDiknt=dVRAJ>unFNy:EEuPdm
mk:l\: NEbAtwh>Mk$i+NL?kGj@j4INyK\EkuAXd9dlibjHISBA>d5wbjqpBi%V@8IkKEN%&@!I9I!unQAkdMG@
<jhMb& 9@<BARt1\@9<qpDak8j/=aY+B5?@HRJSWYTq+*MuWDENp!IDXd6$m%E%?@>WDCeBV=/AXeQjYkPA/eM@
-A%Lu9 000366ae98800110333 Page 489 of binaries1.zip
lKE#GQ &BReLhWnGuQD?!ck?it4kIjL>EBj@>9@@>9@@>9@@>9@@>9@@>9@@>9@@%@c@/>m8PNAA/JSHRBQ:S5X
%jL6WX @>qS@Qj**>>@j@@>@jj**>@@q<$FqWVGWDJ#RYXKhbeLuLeLCP?Q+5k**C/RDRpSNSTEJ=kD\lMMAiEJ
IC\qlJ =u@\BL5?iILlHn#BMA?iaHeHV#C8k!ha^<EV#PLkCdb\<AV:N<1MPPRuGLuBp$dZJE?\XIMu&KLS=^#=
VSFae4 Cbbp<AVdMHmC$Sa<\TwLutB!BW<\yKJS8Z*qJ^lE\SNMu8AJJp*\BB5tiN=*Q5F/Cb=k8\SQMF8CJ%ky
^dR4GY \SQ5piD=q@MJlpn\BK5l&k/N@ATdIHmCBSA<\hCH\yjJV#B+kTiayVBGDb=kKRFQ5ITAJ^k?$Hc>Ln@B
kEWGC5 HAGiaGpAV#AwkCjaDeAV#AQwW!W@+ckjuuCpD$<+8weuuNLDE<:h+Ruu/jCE$#/K4%^?\nphHe<=<lQP
Sc>>i+ %8AJl&Z\lPM9iMJBEn#l6AmiwN8S*/<EkXtweA6QEGQliej=BLpXuq<=u!Cj\lPpWZk8eD=B=IVudieV
uZLhmj =Ey+$1nPMF?hV^AdcZpmDML#6QMJ$mA<RS1E=$HuE&SAiF=#QpH$k!jIi@AEGR?iIMSBj$B/k>@4uW?R
F=4:8k %?AJMlw<RVmD=$:uE/R9m6@=BKpLu4<+u!B\$ja/=PeX=^PEKumCQAXQEKPkjlCW+AuCD#^B6IEuCC*\
kNEZ:i BFHl@+dJd^SE*pYR&:4+GZLBWY&mku!Q=5m$+w=R+4F$l<EBi1je5nwPGMIA1&Mm9LwJA:/aCE6<^k>T
aS+npE KR#^D*hC!5Bk!:K\iSqwmVd&4D5b8y:+R@ypYN4Ld+&aAq&dNt4tXFA9nS/?dCyw<nL@$JYDhth^n&*q
#9>ZcL MDWDD%8u\SIKYL=5Gmn?t4d5Ql$WVnt+bAawb:+&q5&AKdd!FVRV%D9/@YktcHlG%hw!E=R<Zb8@NR5W
dL+mm* pLy%K%+HElLT+@44RC1i>Np<B$#1Z4tuuk5/8D%jdJ<LT18jV6/bC%aQ^$J%<$Cj8P%l<kJRbi:cWLEA
1LhkBT hGFq4\R5BE*V@SwSC$FHhcXn>EJRQ*$>JHwlcK4c/YMYk641*YHNFqIq*e>QFwNSkL%q@BIkGbZ:Sm\B
#1k<e5 Vh1=>X8Y\FH16A+*q+B//F4$6cW\>e:9!Z5Dnth*jL:!VXBlNX?$=m$kweNK%4<NG1Tm:*i<DS4K&QT8
PW:!5& !$FJGVFu=k1\#>1$1YIFtJP6Y6><FT#hu#</8AwPcBM5e%aDTY:/cNh1WFGiGH%qNTm\:4^=i#YR?yh?
XdH$9j &jMPKF:%X!/>A=yFjjC*c$ESNmnq8:YkC=8=B1<DjX4ZbkQjlTtae5K\H8^yHH4@>YCCP?N@H&<A$<6l
RJKjN1 B:@jAE9l?KF*N<I^h6?w5^6B:S4jce6:RJLLY9*=H8n9MnjNiS?t@8u$pM&kpT$h$*I#pQ#Yn<w*\>q&
NVZZu@ *A9VN+QB%5cy&#eD!V#%Z6pHRHL!F:VhAw4448%j&RIc%bLjnt$BLX9Z1+8&ApuSj:B!K?llH$c**\=1
LZW?yF #inPd?+AY+6P+d6*ACt8^+@cBTSwX9n8n$CLX@8dwS<D1h\@8@JnMIHaHGZcDcK=h6VXQdB%9JpS8BhI
Fu6Kaj =hmewZ8B=F!iQ*e91QaiYKL&\WH/Y:&8:aN#<$8X+u+kXd?c:Q6BK#ClLP$A/H+**K+/RLjMec><Dq4l
mcia&! DeHY#$HViy?QQ\ku:#85M\?CEu#l94eQkl/<R<&%B$EXZn1u*^h\:q>9\9JDaFY=4NWuZ+JY>QWjVu<J
>m9y*G yDuu*I8HRR$e*@?9\/ANV%iP?\4$p$&jnQ<K=Q*/D?5jAeXwd14^KJC8%d?tHwY6a/=!#XEkLi?J8+/C
5inmRT T9dC*dlK&BJ@Hj6!JTl@H^$iW\u/$MQ>VqWC1S%dw?@ZwNEj?NcG4&G4Z##l>&Nk+QlqC<%^$N^?WHuy
eD+b5F PJDkP>qVVwB8@$j>=Y@A*GqKY5SJ$J8@9djiTXCh&?@HukV6?RZ@TTiBbMZGG$:B%1Dy@?%yWQQH:&9+
m+QwjL LhYGQ?:/LSlIHD!ZhAaMnpJ?Dn$Li91>:\h<@!bbL#@hZQA>tHqtSP@@HpmkkY>=DqmIXi*tu+M6\QHC
d5c?wZ &ZNkm#Bl\9X#wJ1ih?4SiTClKQn#m/B>:nZ^*EW\//p#N8eu$HP9Y6*%b>CL%$#j?DPwi!<Q?@pT1IIH
VR#A+m q:%=GY^ED*:\:tY\u+k51uMF68T6@ni8kMK?a>!AZ$DQ?+5t+CyaSm!>PjI11KVL>A?8kZ*N?58D4wNT
$44k+D ?=&hi/+DT*D:\NH4aJld>=ey9+K1Q8GNlB6k5ib:5eu@RHpVE:d5J4Amyi%>j+PDk?YFl*<DljWj4jY*
:\X!\J kQY\<mh8kX1>=P#*6<GWiSE/<V65%Y8Ndi+AK%X*>Nw:\K1eD>%=B$!A986*>k+eXIS9X9$B^l%y!*di
<n#N@a lc*J8mQ<V:CyP>B#\J?k:i:\&HIj65d*Wp98k<4@p$cuHkBL<h:!!L?AqjP@8j$ltCQ6d1X/BF9uc!Q/
\BKN!@ QkJD*m>9u*+E^4C*?y=:BH4:eP&XS&A4W9Dm%Wh\?LQa<P5nPQ@=jGQba#k5PDN9/SM+uME@ZZ\C^$TD
<#S=i< #mF1i*4YJ=kcuQ==KbK!bEed%/i5X*q<bk<+\/k%4*+1uLDMc>WkFa=dB1*@JlWM!V?LT?kFF5KD^\d$
LGTJGu Bqc$!:edi+P>/6^LWZ*l!CS4c9&?\K1e@LBlZ&C^%q^>w!?adNuGLW+D/^bDZL%?\BI>9Nm9H=\lYY:%
SNG1Ck :\i5WtdlmJiBqV$5waFkcLM85PMkPEEyDip>CA=SQ6TMGk^uSJ?MiG<\5JR6Z4Y?Ckb=a#I1ZkXVNEXF
:/Q/Z@ bRceNS%w9TIVnP>GDhmdCT#TwR:H55A$LuNMS\5e$H!Y5>\CLPBj=?KHkAZi!C@P=aDy#bV:b*Ql<Kjt
kAdZq4 GDEQh6<XTh86\G4YijT%FR:B9pc@=aQhhhI9qRX\Y6bmjM%C$QJh16i8CE:bjk:bY\R5a*nN?eZAT8?M
d^9%Jq uXECJ&$6\+cMkGP6nj&QnAAD\:AGe$dC5hT\eV?NkuPtDRdhPLk$<Y4p^?QkFGqSRMy4eE4Wbt4YBGC^
>TTV%/ T%b?Q\Fa$\4?QTw?4E@eT8*tDwaGe<D!@j@c?R/wK1=**?FW/y#DwTNIFRSB1tIHRTRSFWSAk\W5RYMD
6ZNq<+ nWJ5FPpmW1^End**1LE4>mTTmL$qTlKnmWq$!y+#M&jKju9I9i9h?%@4499YY??6>hb/tYHtuQp+5@h9
$=Y6Qb >9:t&:>9j98ehajP1=TJph?>ic^YlKYS%&tNRqpZi@l4FiyiqR1%mpan6RdwFM*p?diDhawIb@F=1%Nt
wZ%Ed4 ES$cW/bZKQmRbXHY!w##l*c:4SYK?$9PJ*cKFlk\1MXipc=YlS!&X<T&ZX84HbRyVhanLn5wV$AQNLR:
^Pb!W! KFPp=t%5h%BTqtQ#da*KdCj&k%JHlSJQKj:ByCl4J@LitBTb:bu9ZChF>W9+cJ!#R9qK$++=K%P5hhhi
B*KmQd PC8y#y>k8w6C/dGB*t:K>\niJ9X*X!m8:9\Th!XFK6G@e%i$4nFS#l:KyKni/=M>FY4hX?n$W1n4kdi9
^$c$%A 9BTKYHQB+1XIjX?+n9NYWwKiQ^b+K%V>>=9ZjSR^c<YC@u:KJK&%+%:+KcLX:>pN@w4R6&6/aA?FMy/Q
l8lqjY nitl#LiK?#I\TJuT8GQ??mCFKwyBq+MW^Yu6I#JatSXYh*q#mKJ!uX*@a+k!Le\y@q\9Sbac:lpc4mla
#hEAhu ihQH>XdtiD@!hw%WNLDML$hEKqR$/89JpR4%QXN$L%J=j6#yLpe1e#C9jy$RyXDwpVYdw=RW:5m&V/KX
==MRL& FM*%#jbwJhW/86mqn!LR/a*?jSShh6*55D=KmqC=>i5?m9S/Q*qpZ$XR*j/D$FhJMe=*?May$<:nJ6B^
P*SKdJ mm!b1p98y*\Nk*uq%F>J=Y^CS9XZyk9@Gh^4AFbtk!$i?hEAlWJ4IwePXPVhE/h*DqbT5=Y#=k%S94hR
#5R9X+ cZ6&mJITHQ4mcL\m89tP5!Rwt8!MDV&GKlJ^Wp6DwnJ6:VQQnpSF\D^R@nJS$X$*VytdyE#5DT!cME^S
c4%NuZ qk?%a5uKJL5yD9&TqWup^Ki@JT8y&Pa6teNSMwQhtnh^8KK?:tMjymlC<q>Zlu&wVMXe>6tJD^W6XyM+
pNZ5>R haRm/9dM*DqCTYFMY*=IXXVuXYhdSmtyw5@DHcMW@dNp&:%ST14\aGnIcEWA@ZNV\tkqNjn9+6!Ht#LG
JHhlE9 KCtIX@PWMaw$?4<d>&!Y6&eyKhq@F@<Yn&n=TEqB@nWP%6dNtcBIu\<PHy8kyB4@GljjBKSNXqK=@%9^
EE9:+K <ecB^H^Fnj/9+tV<H?M@WXK@@!yiFy?+PW@SuQ?:8Bq=\DJjTSu@QZ+iZF!#TJGy@#&PPw#AmlR6>%@n
Lwe*mK /eq9^^R4k5?@^6Y\aWYLFTZeNNStmbI/tyM%!=RJFj?4<jcj=b@q@/WF/JX9Fm8n9>W@njHQ<5@!#@LQ
%pceu# <5@!#@L@!dJHpcmWN*QT@@:lMJVDad5\qZX*#LQ4S:$YwG*mj#1q4P5QK!9:?$XbFSQc6dY%KR<V89+\
jnqJ/@ CQ>?WXdFyP!55jJGZjEKdF8n64cmSt5<1MZ5c^H#$B9L4M85jR^Gw>HR=JMRp%=Sk&GNY4mC^jT%YDq&
MVGEya CBY$<#?l:JJcXNbitFeZ!yL@k!lZaX$@4FbVZG!F=SXmndY%CGBpqyM?#>A$95w6Mm649I<?ITLTpB=j
LP*SmM tPK4uAFlIXcLF4R4\&cGaXl8&L?$/LydXynK?En>TqFj5AZyGNd>Q?RCC11@Ebj>^=e8%AuwICEBIXN5
WahA?@ !19!&&RJbX%I@?iX\Q@+$uW%bXDbFB9/dFe4wDPSwi&HNw#+hk?t$Yk\c&64#N:iHuN$hMSeZX$^L!<9
/nT$JP #N@jH\5JCeG!54K\WcNGaatJmXn@@9&^5tWRT$?H&B45ERd@dMh8Qu1QQZ4#Bt9c4#^AmqGWbLT%K54m
wTc/>P *+e^cBiDdDHIF1Qa+N<j!Wj&jQRtH>u#pV$j@u%cK:K*Iu54PtlF>qdaXSVYn8#6!N/P:P*I$K=eFD1G
8djVDE /Bm&@%%X%=1Q6qc$KVd+h@XwF+M\^CAMMRlDDMLRBRqlmEEaalCGGIRlBtHwkwp\^CAMMRlDDMIRk#B$
5a/YP^ RWeaalCGGIRlBtGIRSlmILIlHDEIS+!CA:X*%?X%IXHYX4T%w\*?jepIT#/1QB>XqI<K#Wha8ywB@VMj
?!GdV% 9eqHYQISq1=tRVn!Ea=<lCP@XdHB9=5K+elHGQISlu!ERYt/jIRnH&HIS^nc8*1?@i<tSQZ<9dd@Y@QG
15h<<F hCF1nXGP+h>Nniy8SblcWcY61IJYlKpX%h&K@6tKCtq6Xe1Cj*hHX>*In8y9SjY*w91XLtyF>de1hwTl
JFMe=S FYFwldC4&@:8mj!8&lXpT9i&I\#61L=&lK$h+YlH>ZX%4aID6WE:\6G8+EAZ%6Zh/KS&lKWhaYqHINyS
FbC$aG lX$8kLC$w^Qd$ajcpcEhaXHewq*Bk91pHYFyX>1nC+9mDWw96Hc=EpRaIMIAERcIMECEwe8hEIb&lAEm
>HS$Hb DBBlcEea8q\MaaAIA$RaIMIAERbWNN1RHYGACANEGGC:EkhRGck\mE/E/EQ=?WwjwZ=WapSZ&eyu<nE@
pSbeiW dDiYt=8LFSeZa<b!9FVJ9Ybn/bW+n6uuXhpdDd+qiLplSi%ddnDNX99YG6^>eWi%mJi4jXER/9Rlawkp
^@pnVj kl=H#Pmwe1#ATwqGameBV&^LIi+V9/CDS1Id&a8E<YRcKSACWWN8IA?T=<pj:=A%M^\%qLY1YlP6w8JN
NtHEyB XBDXq^yB=XDu:8K+dFlB6XB:1BVmY?wb>a/CnaTJ>1j:$5QyHFwkT8mZ1?ph>Jj$Vj4S#4wbnnaAPkVc
-AIJHi 00017a96c6400110333 Page 490 of binaries1.zip
4PqyW% AEjRA@RBH+KQ\F\A4>DNaD5+BY#AW@A:pAAeA@!aKCcb!YI?aT/CBmb?C*Pe8eI<bH:6abNynVilII?4
<teDt9 MF\VH6TG1ZE6%tS6hDbPeDN&m$!NAqF4K+bl/89a?pkWLS*SqYPT8?@1pW*VnDQN!<!4#H<?lFGk#j#A
ymuk4J 9Bk5B6c5F*5FIRDy:HS&IX9LlnQl#AZYy+Q6bAG4iSK%WI@Z#i?ew5W*hM^u=*9+1khlI#:tQ9=5lea*
w\hIFC WahN*4VW9+ey8ctQ!dFbXRFh8N*eKi+ddk4*F!h^nn#e#@Zlp@tQiJJd#nj\&*q+uL@BV?J@=*ui\iJ6
BIDj:w mdKMGVhhn#h=*6NM%VSPm%!^$FtNnX4JnRh:+jlhum4@^N$u^+P:qy<5DSc+p9MRRwTHqu9eFGG?+C%A
D^Cn+Q V*/@eFd+V9lS1BP1iSj^ek?^9@mlPB/5@K^1jZth:65X1%*4itjnPtNplStic$?!Zc!#HVp8pN$*d6l4
6=q#ca EbyFY<qVYmAPpVKp1hI=EXbLu$5HJJZ$9jT#SEp/Gd4K</RB<tl=54^AZmEjP=Nkl/@AMJ5=%nn@e^TY
KCFWi= eX8<LV/V*<1!DHHwD/QldVEd#wJLwJME9+Bj\16\k9RcY1Ah+WQACPKYNJcaRSRV>eRt+4aIH\#^BM<I
kb%bJ6 J$It+kl@ekLBD!?9e9^TqW$&Ep9IFAJ?RV+t41KD%/RQcW5qpdA*JSAbXD%bSB$qQ/j8d*>=i/KG5kG@
nB\&&M W6%N&Hi^*tdwPHc>#weiV@u<cphQw+6ytEKMyR@Tq?qGalNN$*wA*WA9IBB/pA5?BSXkA^m:><H&bj/+
*mJ!TJ 6$/nMd4Q\e69+:%$jj6\uk6Z#HKecF&Zt8PwLuA!6d!@cHX:6N/*&X::M:=y$NMlL*%!B#ILRR\dbcl+
h/6!P> HjdPYqdV%8ZMPdCaVTaI<J!B>ikmHe$ntD:tiR^DHCX!h#GN=1?bE&d:/Zwdp*aiZmW85q45&PCTS$c6
u8*FAp HFNcw5b1uk/NtG>4>>eH@8WE4w<Mh$I65$#%d5^A\kud6K>b/Q%/%9uRF%6!Y%/6?6M?9ei/wlZGTRX$
F+lHKw #tX&K:6tde%Qyy$cLaT^*%AD&KektiCaCX\>kYA$e>?!y:l*LEM\SCCZc?A@+GL+?54!^Dy>kZdTbth%
McD%A= m@?X:bNMG5c?=jKV+&Z*6n51FRiun^%IQHjC^AjN$*bI5i8uWeGt!>L$hT5pMI<*<T$lDd<u\1itK%TD
nlDT9a JahQIY#wl=ahQL49^>DiR4k\XMA6AuGS>1pVYwZDkydSj1#Gtuh1h88Mc4#mn<D1!w#CFint:c/6<>H&
KI4YCt KZ<al%Xwp&*DMj!n8NP8q*1dCBQ^idmye<9lS16F%&aEY*\ehhk11+@#XT<$P:BunynV65TG=hEhEF+Z
:y9Q^h t@natbtLPNFiiwJ\\ARyW@K%NBK%$tdypNRt\XWICJC5bZe=VG:m1&eeCX4Z@#P*C+cli?^5MqQM@i&I
?pnpdN PeGV:Lahi:yZLlcEXLi:K8$k@$D1L#qIQu$Njte*J>yuRLa<FPJ!C9GFDP6k6w\eW4+LdTED4<wRPTTM
E\#B!m J+4kNPKthB9iqPAB+l#^QjGCwAkX?dWWSMIB=AnTKM<nX=A6=Hn=K^J?T#+n*=E!iX*&S$F$PBYZR<&m
u^A8G: Y8J4b#l8>m+%pFdG&acc@ZP*WMiyK^S<TQ%K<bVq?NHqjuRjPqu^/E@w=ZRD<8nn>A*/IR%@y*pWbL%B
&@SBj9 FBkK55DHRFkei*yTmWSL>CF\AZRA&ApA$DBj?qnSaW\C5>+MQ/RZM4ZMC*M#jaHyaDwbCJkS4EV*NA<!
Cp*uFB n#VutR5j\RHLNbT1h1@=9Qt&?cZ=9St1YS5R#Mc^1i\aWMCY5uAN&\yP5:ja=?\jLGT%DA#ka4kWdl\*
PTu?nc t%8/$Rdw8iNHit1^qZjC%L:c@9aiq?*Z+X6i:EdMhdZbMRSVF&1i&KhTc9+MC+Q=PD/X^:kC9ySjk:\V
H68LWC u8b9<e@=Q*nIu?RCLDGYq!tYebdbq1W=@VdjPuLp>!tuhaR:IY?QHAuTqy%!t%4cN*FIC/8NLknihqCV
yhmA1I Y1CY<VZ&#:#mldFCGq$5%Al\p:CB9m#eEZ+SZ6J/$W&E9eTBay1aCn+XK<RN+q:^%uu^>5T5<hd+KqN5
@&B4jY :>lcNX/Ly&9^qluWVh%Ht5=!DSc%Sq!#&ZEhnyn>^L^!S<%%4LLAYa*9Zk*GZwXy@9jpJ1pJuJR/\BQy
I>q&qF CaCm=M:+!4:MMDtQtTqZMuCX9Iw=J4e#D&TC+iRt$Nk$nQMbuqnWX+&9uFtW4cd<dDVqDy4/M=Z1mhn1
\X9G1Q J6AE*w!5iGKq<WlCTWCt@^=ZDdd1iPXcNXah/@?Z46a*T>bIjc@CS@AH<h>Cc/CWSCmlha/plNcnBL!M
Dw\i$1 ^9MuEp9wTYW<n!j6:uHQ8qej:YhE+S8kBMLa:!Q\/=uYwhuPMChR9/c?:%u!^#HyDp@JCALGETV$w+1J
CkW\@d FLS?Rq$twEILnqN/<mHX1+5XRG@/W*Iw9aF<L:+Zh*AdcZmI9pB*$J$$wG&QN^9eAb^HDRIySB:+m1wE
<aZA:A neR?AGY1HjnVBI1>#5\58l<DX>MVtYe:h+=@L>1A9W\*A6=t+wu*#DSC=i>AB=5HttEh!KIL#BZt8&AL
=pk>lT jSw=Iu!PQHE\a\MCpCPt5BQacVdAQNEZX:jai8p!Z=1ACb^k5=!>i8K%A^/#<A$45HceCWS\Th^aLkjA
upX^VR a1/i&<V6AJi=?>\9HM6BQa<#9jl+Qw&j^u@Kt$:t/ZEhX9iN%ZiPiBGi/jZIT8P9!6I8t+#FamM*&>5/
Maw#^P ??yC%hmn*pdC4!*nn4%?q9<DV/diPu9P!W&!:J?Yc%#4Kc1^tj=BEaM5I!%=qmMeZFJe%G&BRa%%?Nh4
LkKaVQ b^DHLFBy$/MEb%GcqCWTlQib\uSlJyQ9%XDkb&Z>M^>9d:+kSJ4ukH6lXdbcjHnh4%MYB/4^y1M9Sy&T
m<Q%wd eV5aym%SudMNN^IQ@h4GSBt5w^$$?%ZjYF<<yT1@4*qW8<ZV#/jbd!6e+P?ESd:eKn1^%<R+>6a%8BR#
<X6Zp# JY+iybiY5kdWL&pT9McPR^&#RdLn#p5S*LZ4eLLyY@W>y/pBH@%kJ@9IEjJTY4!Y8jKDlXPy1T$q@6ZH
^<tJ$8 i@nkYJRnEhCb>ZHmiPT+5bF=Qqu>#6aIVZ=8Ll68Z?<bQCdmNnDC>:+\F6/lj+9GH^p*^q%\kdNlKS^P
lh?C?^ DCi?k1GYB1KBiCqBA^GAiGnW8ac**d@Pkk*eR$5N\X9/<F<9hB1uC#/mC>R@hd+h1?pSdJPTqw%ChG:E
RCte&+ yJPBFWiGVaBHRE<TI+?AmYRlYWbYZaTPG\/SdcVT4IC$ylwXb^%EyXN=%ELEFiaNCM$81d4Iip46%BCJ
6Q+Ni: wI:5Cmkaw/FeL:9/ijT#I@1HVQ\qPTRyYI*qHJE!/bp$@I^iSY?tn>HL:ujR4=A*R:QpD5LAIDBE#kML
?XN#Wl RTYAG<E?eEB8B=&AREHXtWp><8MJYDZe9>TA+4bw1HwKj+\IyT1RR?>q$MB\G#q$KFXDPJpQEk5wiIia
EN/k#c aKcJe=Rd8hM<pL^ql4qpEF%BG6m>bA^:t\!qwGcHjZ$J&<L8aL>md:LQYDnJLLM+=<@6Nk@u54qbHQ#L
ny<aGW 9J4:k98T8<w>+n=mLX!<Lh?h:<$u<9cCDbmN\%l#A>?NPM:HE\@=cWT5GhaR*ycD^DL#HiJnC$%eN$M*
9m:DW& <4BqIHuZpp6G5lYpl:B%L#qa8E%P5T516ebd9G:p?YkPlc4^q4&#%Ht%KQdaF&Ja@M#ZHmMk%nJm/:X+
4p:&Z: NdabplPbXR%#PiEm=TWPBkpm%NLV^TyRK+/mD+ujkR+S41PBiJb&q@w#k!R4pCjF>RCX$kna>HT?LqKL
bVm^iW 9%l4P8ccd9EKmW^a#uZj?qX#SweD98cD1=+?8maXHNkaLdMkY>=6YTLHM&ne@e6!Xc=lZ56>BF6+l?pN
$*$u5l Ie%p\P%CES^w@l#ttm>B899LPA4jEWhN9NijYklYai5Zk8iITye9$@^e9:AT^e=#$WiIcBdiI::p#MRT
GtSwkn %yP$eEQI1!!eTmd!%cR6h+D5#Z%QH8ElSSb^46Vu*AB1+aQDn>aZJj@1X=EeyMF1=&h4+EF#+eum$C*P
RBpKAS J!kD<iQe/cd*d/nb9B*hL\y@^eYkRSuh+YH<W9w^84<Z<6hwH^K?wbNR%P#pI$A>PSaeJhZF%#%K8&l$
58m*yK JIiZa<MAK?1yP/AZBYtRS4p^cat5iFwa^%n^MF/C\qdtR:=GTlHjMLNFcGe?^hQTCZG5?dFadB+GIC8c
QlKuwX kJ4+*l^MWPbW\yYFBZt8>HD&H6Fwup!9SleJH=9*$I@a1cTF4TcVYBPAmik1<#tKZMt^!$RbJYM+>bTL
dk99Di ymR8t@LnhapV:PBkjn$%BdGyK9+F6b>H%@RhH$TV@AncBbGy@yaY8uTT=T8/*QJ5=#ZE9^5P6T=%:#uG
c%#9l\ E@<Kni/<@eI\uVP&Inlcc+$IHqa?#*tFI$4QYkIny/Y:^/TnWJbW?M$kHh^9QcQFlW$Y:wLXqpq5k\A>
4A5c?R tEiY*i^DaR4DC%XMwkAh8cHmh<#HI5uIhNXtS?8Xcp%bljNtG:#l?bEZGpQu+HTdlMHdZHLA>M<Ec\i*
VqHRj> 1dY=GR*6ARq*9hbkep8JKm9DNY?4:?jSW@$9Sew%ARu:^I@AZmtGJeV6AL=HkdCj>D8Ip/?^E?R*LN\q
M+mw\> bVE:=Rn8qn!Y&!j8t:kq>?hX4a=Y^t&P69nNbTW/#<kecuym9&$=%HiH>H>m/\>YY9qml%b6%^#R#H/6
@KV/>J Yl=dEaSyZCKPb?1qVIh%^QRS1lG=X<R9YRdC$Z!*Nke^u9kGNYmYYENAS*R#>4GeIK/INLHe+pdtdpe*
6uZM!< +%F\e94Znl1m6\%<dQ@W?qCq\Zku%8l#/NYA\6L>aD?+E8Rj@&ul//mE/Iw**jX%^u+iG8^q4G@<4khp
DTp5mV 5J5G1>\Ph6My%F$B#1d?wl5yD@EE%Re<y1cIWKC1SB>/P$mm9^Nu$KSaWE?:iG<HXmq16i?Qn4%!Z##!
hJ&1$+ LC\DA\@j#hjNYIm>1%yS&W^Euc!@6DAyRiWG%\hZkq1cIJ1A<>$P?n1AH=D6\B*aM$%pJHPTSPN+JjmM
@l9LHM EeuNnC<c/YPp=WZ\Ti%5!5:eTEYaV%Bn#dw9+XPPyVcaW\k@Qy=?cWd8>AqjR\i#B?qWXpA^m1aStZSD
<DWKCt bHLkk/jna/Ta\\5ANHH4RX@8HMnlE5WTV5ZAHh^K<Ta*kuuL*SN^9wYB$j^ZVDa@SF4C!<\Z9L>==%X?
cpqBAc NSiQ1#YD?!IjN+F1e=Bqh8jAtStYS&bpeKW@6*Sue<Bp?thLQ45D\D%$1HCEHT*ea*HGBNaL8b:ePYEI
ZiSAd5 >?L<u^N6HFV1h4#!#mC\VIj@85#V5/S!5YGEaW@*9!dH=PX=ak<\*^j&?l!X>q:weX9d/Qj&6yN<NhkK
\e=CZ> uFtw/8*ZpY$pt9jS>p@e=>ZjLpk&14%4+\$%98yq&Ly=8Yp?=MTjXQN>Y$1LG$iQ<nD?Kt:pdL#N6k%\
PcV&V: aML*XLnW!a$bdPQ%KN#PF&d*8m<9qlTc5IG@Iy*u+c?TR4*WquA=&DJG*9n%I?8p*HHS8y?HcyNn:@4h
%p+I:8 %B=&%9m1<VYFY?ZS+:X+>bDBFTd4DAjN8DY1SJ@S*yFFB49<eP&9=6n\RALL:Ih!T4?/Z@T1%BW/dKW&
dmMZJM IN?ut<Qd&tWb84^SG?hHL$>5ZTH4+6Y@D=+D6W^J>HNDS>4Lqtl*<R^M/Sny%d^pctwT@BP?F6dhcETy
d*Hjqu ?^q^A9EDenREd!eSKN$mQyD?KE!jhMacZ=6=d*J5bZ!VS+j*15R9XqEdYqbuIP4\@JL#>hmwS9@L+hW8
F/a?Wy pa:GH+M/5\aT#5dnl>j6#E%aM@ip\<4VBY@%G*&b\D:cq>&bhJj8#Qa>==e%6Lk<!+S*1GmWm6qNDqI:
-AQB:L 000eb5e871c00110333 Page 491 of binaries1.zip
tSY8n= YJ&K@La:FPR91NZEcmIJ91btRF5cYkkLeSSt$QhlEj*X^h@VL1+14y?Y!Md8P9&^Zue+=hb$#cLk4ci6
+WIRDD <ayt#R@PI?Je6Dcna:H?H65tRIi&wNXj/#4V\5H>JZa8w\AM&La48LDakZEEwh+lytF8eB1Y\F+Et+m5
abqq#a =KaNJcRN$<YN9=ZGMG@JSa#TAyj:!libdPwub5t>wMt/k4l>G5\n!M6@m+%DlNj=u@19DFaQCy9q>5/n
Rk1EB! u*8VuGN@LE@PN/9yqibk?wkby6LVyRLcdF=DH=JP$$Na?J\GE1T4&RB\kE$BijLq&aBmG+E4h\Le*X<!
uGnQtc *&b>mnyl*JC1l:$W>5HNNqV%IMy:C\hhti$eHMDe+Ca#9*P>TRh?D^QF\!I!m*@HLPa9pX9+98a4QM\^
?A@5ld @<1HWncYHib\!$*#GA6<t^%KlT:+6N/D*YWb#H=6kXQaQ!*##EblQ^54jGWiL$CTZTdI=t%Cj?//MIu:
*ji$na VaC#YH6^N^eyj5Nqm55EDRXS/peeFH5Sh<R$kla@>aXZcB@yDB<u&aAbEtayqhLGkFi9QWI8CZnFYX\6
LN8QBA alWQ!ZiTlVDJLYSj8jR4Mph?=lhnnuPhaX$Y+T!</#*Vwbh@pAjwVq&XE!u+Y5/udKF4+94+E<IR?FlA
\Ml1QV \/$kXEMj5bFIEuPuYA@lu$G<d6CR9?li1DQTmNID>KjE>@RGkk4\AB@+cDK^et?<Gl85Y^!1Q6$d4@hl
DBhL4* :T5h9R*G5ERAy$u9mS4JmV\w^bFL?RppyKXT<l1@p^\w*!L6ulYG<\bX5&M*@$MP/X:Bypc%+JVl%q9>
?GV\!B <?WpckKbBE4J$uy1J*tW8pZiV!!&LQZWD<K%6QMA\#jhh*qy<cL1Zwbu9yY/dZPey^9CaW%wCbhAncTu
A+Q=jJ W+X$LdYYl9$Ty+Nk+lmh&uGVi$YZE5<=G9?wduH9wXFXI^\#ucXSX65n@Z6P#X\^epWbRBtZRF!k9\ch
S?+BEm >J>AA+#cE8:YhPiuYKY>G186>@J*5cn4k>VLNXPeb&w1uZPmaT@jLeM9mJ<!>YADe^Teb?B><CuNA4Y=
LP*Ja# G*PinthT#jiuMi44La=#hI:yR@ZawmAWAZ9W&lquPBdE%5GC\F:GJM*YwA*tcLwAbNPqL<%LcDZ:BV1+
DNVpqb MtTlDyPHDAZbdAamXWZEF?#uBC^b>/GBat%bX/+PDPA!YDmb8\6YeJ?#R+yW@mZpH1+4YN\p**F9TSPQ
a1$#p+ *&5Vab8+tG@t69Cu8C9<W?/GACZP^8LHP+nJ@BnLJ*!YCB9+X56^@1LqIZ>F=Ht6eNudEmIM6VkAZu6D
Q5cX8Y 4pW<Jl%<Jm\Et+YNwE*RSc@ZRXF\Fu#FNh\\ecI\W*#P\XZmL8Ga?LZ\RE#lPhEwRm<yXp^A41p<&Zdn
ZSDXK? /mZanVk1^SQ*yYqE9XBDhJQlRiK?eIiaJ6NEN>GNQCnDkiRhPbi5ET6IN:mZHAnldhKN$?!\AVm%A$bV
KKb4li N!HMy6=CZcIN8EuwWXw!BlVkbB1KE1&^%X@bV5W%Wwah^wVk^uV%5t=*diq+5RcQ#cuy6y!<SJmJu\q+
X%!C%t k>TS9=PlyEPGB1S:#ith4?5\Bwd4<Gw<^$9*Qm9M%Ze:Z6$>KlLMyQcVeBZ%HZtMI5pl4A9FWj&y4hZ5
dT^$I/ JC1BL1i?b>X+8!H8miFh6?mJNZdG+=kPP>j$kV<Y1pyZDjVT:9FG5jI<GRJiplt$tm1mk/u*5aaaLtVF
Xc%TPN &QkXnwMDw8%>G?I#NG4H*1QK5jAbRZAt6=W!kY6WZ@CG!kGjJCNDD!aj:AHH8LuMEjAPHPjGw&VB&hRi
H@iiZ+ n?FaQ#Y?cuZ9Si4iJnWt4@TMLHTP%yWN?=pJaQJAcRwVcy:NnDa*Ml>#ibuq$EpXpikdMEj#1TdDJ#t^
S=&9Ft i+I\!GYe19h/:u8#\W!ba<#RqS%uL1TZtmi#Y<%u/G6t8Ih>a<dAlKTpDWY/V\QDKtEAqeRGei8=EX\>
I5E$8m P+<:!w=4+icA>WZhM=*6E4V^MAHaei?+CM:En?Z/<kpA=9Cd8BK?F8#kj?F8<l$A98X#e1c/=5<cGPl1
5N4K*G GeeQ5MBB#GVLXu/F=S1@^=IE>4uD@cKc!LAEE$YYXPJ#T$Ei@Jbid%p5:LCa\A9LFiG6BicAIMFGHCGE
y5\X4P m>uCVhAm9F<pjmY$Iwyi%!Yi?M8%I:lEIq#MJ<cIK+qFI9Vw1:nJeXF^E=#pSS@pJmCdHCw6cWc$Gb:*
iL5TVj cmChyTZpb8pl&Td^bPyId1cZd!8t^R66M:PP&J9G&5WGD$@P6i5BQeAa!4ttb@BEn*T=nqww\<PWN*&<
VJSb@1 jkdB!S@VZlDqIRu\MD$h#mB4IZN6YNF?Gy*!HZ$Gp9RQ$AWR@V\Yi84VHiwi/4d$S4#>diYi:y44@qXH
DJG*%\ 8/<jFPjj#ebZp:D!\+H>nD15y#jE>bQ<D\$cE1uGk14eDLcGAIZ>8K5j6unc?K14=$c1=$ciG=D:#nBA
ZY?4\% #aRq1w%#hcpJNch*G8j/d9i%Z:A6&TH::64Bi<e%\+Gtpd$G>6SmFT@LhBq=Qj5+&e<iWn9EK<:4<l=n
h=5N4e VGEPZWLiuj=qSpN1JN!Bn^*lCd/pQY=e\=LKGm$C^#RTY^ID+u$F?#X=Vpdyc5BlR%/*nun98MkI*?F?
pB6YCL :<j4ywS*P!>$%QqNZWEhM4@jR*YaD!/>q/ujFD$4p9M?9Di^mb4jN%y*?X=Fb:N4&PT=C*\$Pu564n*@
A$>Fwd $L>@N:Wh>qq+la??K9^YcH4WTDe@lQFW^CDn&aeGDj=4SK@IeX+4q+\86pS$<!*\eqmTq?!:#Dj#^=MZ
>>N!$A t=9<&<8P&dh8nGy*lL8G9p4<$:E6+<HWM*/>Ek\A>8j14>6tSw+Ke?1Z5alLIcTVp=4dy6btdAI*8G/u
/ZI*FA N5?F8Sy*y>V$/RE4w*#!LnudB@:qXFa*e8#Y\NZ$q>YMwd6$#RtLtDcc?a^j\G#tm+h+X=>c8YjlLW1P
RNLchc %iH/WXe!Xn&ietYFGq<$XbiD6=6C496V@6Xq$XHTwS/Xya8PYVi/dQDjFS*8j<65<uJ>GI%GCw@$D^Qi
cN+QPK ^#8Sym5bQ?*IctAY>&u8Wh4\<Rj>/tMctPp>G*y$e>ZAZHW><<I<8ukGm6&Q%\:^L:*9ZWKF5mqN$!K5
dpYq>E ZPRQ%C@9/e4be4+:M#mp*uP+Qw=?Fup<Ec5?$tia&=!p\yB*DeqBlJM^BG6PeE4kCekjP<SHm&Fe6nnS
WF6<M= WqeXQX=/H/\LCh1itGM>:LhH<<9:QF??cFl!cEVQ#H:>h&u*cR>kLT=P^h48$h5tuD@*Zln4I5&<FbQe
*L/PwW GHQntj<SFj#Fp5bj=5Zle/biH8EtHpX5wGNR#+GY9/SXZJ4F#6JHllEYR:d%S+&CRBA#h%y&mkY*LLjE
96Bw!% l@L=ERF9A?@Q$MHp$B>e5nMCQ6k!aL6uy8p96%PHQj9^?yEnE*9t=ZlBtC\W\E?ENdBBPA&45?5h+E@C
SctS%q V=JYdLGEmCH!KQGbBe+Z=<94^HZ!YZG+<KQ+w@#TT4KCQcR&+G$w5W<#?w!adS>SbS@S>ZlIw^A$9N^1
k:GE?\ Nm:YYwXTG/YN<IJ$AZbK5BPGWu1my>!LYECqEaW!@JR+S&$k#5numS@pq$S5BC!%5wb&bBmMINQlH#j@
!tmPmK mJI$XLWtinb5yS9lSjwElD?l<QkHI<AReP=8nHpTkPQRtLQW9B65Jd+B%>B\!?G+qSPJ$*FpNI*IVjdP
=iplE> a>$W<Y\H8aY?TX/l+X9!X*w^dRPm1ZB\lS+D+BJ1EdAB4iA1hSG<yu+CmN6yth=$CJNBn&KKKt\!u/B<
>Gh%Z5 c:q6l&%j=hE4ZE&jah@?bnQ*Fj8Cd8FXAIb^RiAbQ\I5=PaBj$5LkBi+4$Au>\!5jtaCPNPQL+%tJ9It
a6t/GD wP/uDp<hicbS$+Fb+#Xjy&ta5EW?YYMncuwt1JNM9V<\&Q/S4lw<Tt*$%W>S:jQ$<:XE?*Xp4LA&6nZY
CV9<aQ S8AycS/qEXlDb=k/Za%Z#1@*WYM6nbeQ^9<+BIPq>pjmQ#ZQ+<=cqlp?&?wp\4PYFKJk+6n\Hd/Q#XbC
ZVX4ee %>QCuiKHRlI:X%nNCaSB<npqHGYjC9iLX+@Z+@yX&Jy4X\ySmjX&iRXQ9H+M&#:%jZQEVFY&n>wb%*+j
T@l+$G G?+@TwNZ@bF4tBIjGhk^B6wc&@V:d:aP#Qm<E/W=//Q*GC&//RZ4KuQ44:+Ru*Ccy!ZNlXN@<$5ll9En
F<ZL\m ?bNyDdC*+@Zw8IB=$p^i!TP?p8A^@yu$kNe<FRl4T:Reb4tXLceQ$C!&^nj?R51^u?u\y8\H!/uqK/=E
aFbM=T XNj>FIBFdW>DFSpnm#pub&QR5c\!j<hne8YYA56$hdwML85*!1B9H?%:CT\YlpqTbh$ky$5y/Z*kV1qh
q64Y$j ?Gd@LhWJq&HJS:YmAFtyZqJ!1PFE9DmLYCuF<\SQZBW9!1>F!!64@FL>l\5?%Kn%e%q*9c+w^iY>VnMn
eikb&N &Can8B#4@@C*\I1jl<X=qE*/$YBZ!HeiZ8G+P:l+W8MnJ&KGBP?:&4FHySGk^Gu58JiTLRW*TCq=n+M*
XnG=%c tEhV\ZInEeDB>XTnjI=cI:@eIlC@!Dl>Yk?n/YeQdJ:bPdtbZuS:+X>8E?nt=Ndk$c<%JD*a4Bb/8chQ
m^y^Q8 dNHaFhdZ:cVlbumLdwN@$K<kyL5SMRDGE!qkG4EW%BCN+CB^DeA:^B6AE/Yuh?5m!J:$YQLwTL1aLN#y
6CI:u+ PLuplB*Ku9^ud>ZN^16Ck$5NHcYG=RaDbuAj*dNNC5N1>>mGW+>wK<yC>/Bkh@Al6aYeT?YDb8yZ<lRF
BCPHX% n+CuXDkqWYdkS*5!!VS5yV/ly#INhDX#uL/5?@ed6J%?^SK$Nii5*A/SV@dAQESLWwl*eB<HV+JG^A<J
\mqZDT VkVP9C>KH8EJamI@p!unX#G:uk:4%yXM9Yh?a=*M>q!ePbKL5<BM46V<GXh1&e#hM4h^6!#\FYhk4jpa
M*lLjN Nw!QEhL=yT^e!G>qN@KInby6\G8Ba1G6/M4%Fkh\NtA!X!T8+PAa5Ii:JH:L6aJ*uE+!<VBW/564tS^?
5w<SkD kXVC4=h&<DQPih55#Am%^9h:8Su$Z9mtWdpVe8$LeS$YQdnT%lc9<@wqVI%NiPJq:NV:aR&i/kuG:GIn
HQ?$5q 5cl&:eTGBX4:$t&StEi*TG#qIJ?&iDVK9A#LZYybI&?%#Ad1>@kQE?Gu95Zaa<6:YZqw:!QERTme*PX>
y!L&Ci *4quiJHjNGEy4BHkXnmdtE*eEh=AYnARd59PL^y@Np\*&#Sb@<4QYw<h9li%e1Ly=bkcZiLRh@dH:d#X
*H<X61 8DdaaHAIN^J@iR*YjPA:Kn:VmZDCP9i6%lXk*@qutZVa#5d8eHL$L*lJhKZJKdJu=G6SSR1&$6Mu#bPu
PQB4/d Qy5cD&hJKeVLFKIGjmp%h1=&ctAV%H:\6jRT&5y/+k/aVYVITWS<pV!D?H#$ui9F14QD%Jm=+4H@b@/j
IN/tJ/ D+>>N>T?/ht\d?$GSXbVkayKWyV&BN&Z@yH8LquPlLMS=nV<wDuyQCq^iR>Dky@LW1%eZ6yD$NlGPtjN
/t*<$k yA9lK919pZ!hn%NBk91$>k=5I:9$Elq/kthu%iwZtuqb<E@6AmKXYp<WWC<RqleEQE&y!PhWWQtLZW<#
/9u^QQ Z\@VJLm>ID<Jj8q5a%J8!46&dhb+^b%lE^#cDl\?58qGyn4hpIjj$XjeX=9XYj/J?w1:>lNe:wB4JH#B
6p&hZt VJGT?9Why/j<#h&Rb<I$cyb=GtnMP>nnEu9EjJ1C><#Z1NqEKPjJB6BD&BV/<NbYHhVNDhEq&Ym8Bq#8
BX%XHi FXnq<b*V?k@N46M<?6t%Meai&lM&PjdHK85/&Ke$BK^E8*N?aChIBuueJ\D?AS4AQ8++mGEiAwLnAZVt
/%mG^H 9bt6#FA$FH!MjL?PPdm46jKnpmkdhHjPJmV+tP>pBF=n>4H$NGjTI<%\l1ZR9Jqic#=1PYN?Sj>kl1\F
-Ac>Lc 000bc6dba0700110333 Page 492 of binaries1.zip
&IJkJp a:5JkY\/?IChJ5^lG&8EJ9dkBGK8Mn9KYD5L1*IkDCW1Z=YETqV:Dpl%J>!JKGIEeZecaZBSjaBu#mT<
K:>P!c Cc86pha1DX/6W5*EebW%Xt@6c&jE4?NBF#BdXc%>yBe^db/?Q/bS4ZdKT$4RJKhn6itSPN:Q!pyj1NLl
m\wdT1 #RFqR!PDnPwd/wR+6&c>/9NiHeZH*G%XG\4L9D85XjY@4E/+d%VnY:a$ibS6djywmWG4?p+juXD>JqJ>
HV+PRZ TLX&Sti\Xh@4#Zb#HjhyXNW8WhyW1&A!+d\#ES1=P/%nI:HK19?G>CP/hXQYyy@XYV@GNM?^k!8JqZp/
pCq\:$ ucuue4?1VRuQQan#968cmJDn&wdCWD>P4cydZXcJ>#jh@MtDJD$e4XYXmcbXiX=Z/ku!%BWNQtBM+mJj
DMSaiD n?NZ=nNin9*u4LG^WXqNPVwqIlw&H@QchwIeTb$kW/ujXcqWcT1X&4J4&!Xmi>5F$%WuualZXhP9h^^%
Ltt!WI 11&\GC/NPZZ%J**pV=En:l1N%uLGAS9>YGPF</Ce5XQuQdl+*^R%KdA#$h++!6u8aCIbZ/dDJ<e!w=l<
&E$!^D yyS=4P!P4+5&c965b8:%md8MZhIp&<bii9nP8Wbq6/bqRy>KJ/NGyeZu8ReTcE&9t=m%Sd6!tuZpASe6
t:%Ee* *8Ti6@nnm8YL5F+dGdV&YLDd1peFE>tn/4!9im:&c$ZY5HPSdBmB%tN:@Ky%^PD<ej4+%Q!9ndibqGNy
Su^e=y ^?+SYyY<MaT+y*!CkG*4ZV4<^t6XZ#\uVB6$QXYlq&ZG@mj=^4jE6<V$SM%Q&55d*L+lilG>P8<tY\X9
VhCVcH 48/RVnV4J96@W^buZueq#6Z6t6^/qk^JG8DtQ4aH$aMwG5=YDAZD$>\*V1hP>D6HuCNk@uwji9\bu=*&
Zl5=>Z \*\1qCyj4tXPnd@S\<itJcdGb>4ccZDq>4GeL=%J>h8?h?H*\jiDba>kA1*Hi1>WL:J4Mm^/Gi9wZuHF
BbNl<> jBRe*iW+\jYh<*+HAue1hk*awR*bcu/iY*V!lpN/wZ&daZTV&VNm*<&H\n6Bj/G1b&>EP=ZyJBW+nyXm
m4QKEP iCqc=?HqGNb:L+bh&QBF</a9Zy=ycGy1khtWkj!#>9ejJqpi=hpEd16LHWAhd64ThQ4emcP\a%#@WI&n
JjapB* lp6c<9l8GTHL:>eT!$kTKtZ<D%BLA\RWAAIACADuXY$qA=a\W/qPAACACAEALAAAAGN5cYX8hHM9eGh\
<%E%V* L*hydnM!L$q8e*SldG^qem>pd&N#L%BHWGSye&58cG^\:F6:nF#XiV?#D#?C\bA$FJ!$*PDWNYR>PGAM
?bMYj1 &AT#66eQMN:F8&BMwHBu=8:M>e:eP>^:b<h4$Ybm<:J=yDK6Rl$ymyAw6A$$TqKWWFR=9P^kp$cFqKSN
1cZAd& JXRyjTkXmYnDH!H1>96>*:uu*uu8W1hT@&Dp<h/bi<<=*@Q*Qe/bDZj$1^>pqJ1q%=YLM8yq8u/i*14e
tIMwnp @\tXWeW**:le$h>Fct#4YMENy%T@GqB+LXC*$uZ!16m8y$:#NSDEX##:GethqjY4Lk?h@EYuNj8N5:N9
ySEka\ Kd\^??hT5^jLjlnmam58:GDtje!/6Y>T@WuG/i<?i>$6PH\Sm@B>9H+nM/qP>h&aTYbj4D=p:m+iPEN>
WJQ/BH GBh>!Rm/jQ5TW6EKik?59/l9RA*5Z>Ny/6ubDCu&VL1/6j>M%9@t:eM:S4htN&*j4L++tFF*D?@iPLF4
<J<nmu bESh@^<KH#aQV\!46dniNLy#a8TYCjXu9<KHmX6Gd^kiW$Qjy\>d/I/!Z/P4/@ZklY@\B^/<??@+Gp@@
ChbhI8 @HY/HN<#QnF!k#1dcLl:auS5?!a%5ACZE#6p:Q:@wp?=!t4%\+GM?8D%\i8D%@@F/@dnTp$eX^IEq8k9
ti!PWa 4/H*tj1:/?n9y+E6B^jKF*>$KMaR8jpF?u++=>emT&QeY9wTdw*bG9SiRY@4+\$LH%cwQ*#5KQ$>MN5<
!6>bWt S1uuCL#8y#itZEjB=VKMY6NaPwllu%THn#a!16Gu/Q<D?5>5DK1YG%1&b#q&PLM1<qjXR5h!9H\\W+%e
8iR+j> *:Q5c4Z5=t&?npy&SQj5ZNpJ4St@bpY?FV1SbaiE$=nDDl#d<me6unc5&uuHt9RDK+#<\QYKGEIjHC>$
H!WZH^ I*jc5Ry&bGi6mSK6H#mlE$\:BV&I9mE!Cyk@V%NGNLp%/bahK&?Z!@T>HVN81Yt@ZK5+Kt8y+ZJW<t9F
j^T\@L p8XG#JIX$yw$BkPHWpNplGZuw>CchwIb1%LLq/!!P+XXTubREQJh#T@NXk*<ciI\bEd5wyNmnXuCCyBl
VEp!u8 IT&6MG96ISHqde#niqPRC<&q%=p5?>Z1nK^E$$D??!Iu<P^!RkLJ^weecL#VNDM9Ja8CIlIIE?6w%wba
utjVFD N/4m%:^I$byDYKFm$:1$9y*QP&HwpkwlZXbmKYC^&XalkF4KVpTWbK&XY&ma5<?8XCE@h%J+VRpwqG<&
ppdC^$ 4bPB5t#FLbamm>j8IHM>bLMip1Y5bJT5>y\?5jXDk?I>%uYN=RN6q69$j:<&+6$q^&6jmGkV@y&CE41k
9^>$D5 B<kTIlDn4j8%MtuMt:F<pq&kSS:4#QZCmI!6Yi=%F/yMmbwq/$@#*>Ct9!q:IQEtD&a6m!qNDRYNNT?t
b18*RX Wq86/#W4mMn#Qei1q*!4+NPpul>bW==jn*&J*CP!XNWP\&wy5ENTk11ZZLJu>wC!:^YJM:L!EQ=LFtld
Fc\yDY iLd8B\YmcGTcbchJTNFFBl<=ijy89XZ#mJe\>n?ackwRtGCIhWmVu=mnllD/RG=T5TNcd45&wd^j1hdI
T+B#?Z ^K!\^C4IE?EqalEL&Cp1NF%DKcGyI!1p<jT%F\E%pDwuT^EI1FXpQk5%CD+:cPD#4Bd+*EpMKpWbtZyF
yce!6: &>*nC@VD!^wQb%K&J$AJpSS1kA^cnbkACtkElFZBj:*IDS^L%ABBRjmpwd61NMKB:QQpP+R/yA\M$#J8
ktdC9V \<N^wFGm$BCkclWh#\uIHAt5TMDRi!$ALkBeA49kRl5EHY6ZjZy%5w^ShRnBIAwl6abRZq>kBHN8m&DG
QklaVk HiKtHQyW!>ADN!wSDKIW5t@4V^6Q^dL=%^>NSH@eGFD*Zdmw\Xq$a%AhP9C#BT4#=NFVA@&NBcp:GZ*u
/:A%L/ ^QwZ*t!@M+54!:wJkN*m!cG!qN#hZbylWi9:G<!NiMApBR1TCw<a%pEWnH=@wR:Bk+8Xi9eBCd$bHaJ^
yw%jA4 <:q4qY1h@T1/@^Ehule9M6Jc$TK6N1JWuS+eXdJ1k\c8bBwdZ$/nGR@h=yAGwX6!LchP6t!HkBl6WDFV
4!k4:% HGG%5y*E<9*JFNK5R!FCDC*QCK*@RH^ikYY9dt#6\&yS*?Hun>=&+P4GRuZRaKhR<TVqL=%5ebKA!M8:
4c&:tk huuI1nkF<9e!B=$1GT>dt88JY*Nc+F8CPZCI$KX+RaHNb/m1&^RGGF/b5^IkWkBPB*/AnS%Ed4=Y6kMc
9idVe$ S/Q>IMIw+K^j5Gja=V$uIpPiInS^9Gp*<L$KmaFYlR#VyNA@qw8l$&ANLiV51@w/1+A\cWICH+EhWA=h
=\/?Tq lLXkEpcI?:Stq1V+i!VXXSqS=yXumCqb1^8j:TnbqE!SGNY1CTYku^PpEFSThpJ8T5SW:D!FFEj#+6Au
W94S4m /J@yLhdIpWul+Hyj9q\LZTM>Fma>RnCD$PZZQim\GNmXXHKR6WdMhAlyEySdltp*$*KwlVH*MX&aLWLp
E/9yLy I5>C/CRJRaVInD\@=^htLKeePn^@VF4J$SHRB@Aq+C%RbpIiREqhT=JhtlGd*djETQiC8cT4$<J+a9IH
GGyF&9 5kAuIIMX&6m^ppn1i&SdJDNK+6!mb!M5Xb^KDtdJRdHwIlSCSWXKl1ybc#mPR&A5==kaYaewWpQBZiVa
Z:5*Fn FdF$iALW#A1YPWp6i?FcpKQpkk=QcMVAh=K+/W1Ica1h5m1NuGG?!ELh5ERCJFu>M<u8t^t^#F9QWk4j
VdiWcP YSe**Q+P<p8=8#MN@\u>mwQ5anL\K%cSRmtWu^kapX+NZCi!KWhPP=ptqyppJ*h!9n>qHC%4djjmeBXu
^JH%$6 nSRKR=$ctihZItQT/+ep\VJlRZRS=itWe<Zw%lF6X4wi?WIlSTwDW^#1RLn94T4DhqFV8QVIpJYDab6u
AQhFQS E*D\IyRBR\uepbuuMe&R1AX#kTmGll\4p8c98CE\PpetXRJuTA9JI6&KK<RCw$ZluN<+hEXIpQjDCFS#
ntQNPl BJjRVebDEyd5kJ*PDhpBa!uBSRbJ8&<1<a+:qlwN@&Ytq+c:^A^Va\DVCaKRclAiya1S$JknMy\<RZQk
N*Jqt9 FwwP\#X=XM+68^F:p4dS%mqN1RR<KBVIVMypc/^Tyktn$!WlXmN\I&pWZW/Z+kCWWuqY!qppL#D^I$6N
:4Nl5I XJZpya@CMatkJZ&bwEh?W+uMqqCE@+#WFc5=EQehylFITM:NQ9yi%+Tp8ec&inWCn8lXpC@eRy<9$N<X
:C4wSi /D9pE6dG^4ZJ!yI/9h<$/Gc/jd/Thb=LPF4V#FHQFK56X$yTJXD/*4W/XZy*RKpj1RX1<KB$TJE1+idZ
nt4I+t Sp\9%5\Sy$wkce%\%%Tyjiql#R<t4k$dyX:cqm4B>PLlP5!6k#bP$j6LTqah*tmC^^YbZ5Fn8F#&//b>
yNaBBu wiPI>yhWPEp\GGt=VuAtc%/iRYl9La^LiXM@^wQnZILRmb+mmC6IWki66uXDJFAV*Z>D:+iXCGI&+iXn
1HEu#$ QZpbm:%6$k+FeVRn1RbPDKdCByCKaM16AKk1XWI@!^ek5mW>ABK=Fc/VI*6K!qmN5+LJ:YpGWZ1C*q>W
e?K$/A wwZnt\#%q@Tp@mc8dpkiqM<XKe<E6qC5YWZ#F=y:WPWmmT\1Xdn$>RBbt+dHJ+c$Xpw&V?PZ*RLBN$Wl
cSHluY CSTRNcJyC4VAQyZ%\GQQ4lF+B?=?SGDJTIutd>D:kBIN:N>5?Bn5!ee++tHaD4bI9ywMC@Hhdm1NpZMJ
q*M?QW E*qy\dtWy%B&pLQ#THayc1RAE8pHS^1@ZHd5ap%EH$Mn^Q:$=9eFniA\M@L4keaa>EDCuyFjH?n6y69L
G$#^9\ qND=6aVY6e&$h1++b:6Znq9w#piXpQ48mEc>uRVi/^yTJQb4%MQN@>+Ba?%AIHyX=!pldM$YA*&4Y/C9
G8KtJ6 M*Q1bkLb*^1R>R>jy$X&dYQ>wt/hL=w5%jRC#9nXn6$9:5ZwZ1u$\akA%hTPG1h5lW88Iep88WjGiX1/
W&&X<M ShW$pW=bMXZTJ$5Z1#ECIkWLm4bH#mYkkcS+!Jy!uC41R%uZ<8!Ka>1aDqYBBMVe18VuK4X!=FdJQZV#
89n/t$ !tVdIR&n<nJj1+mnyTAyuwW4C>MPVlek#KXAQ48TCWyN\A+<caH%L1kP^1BdVCb>KwbbNN@!Wa$dNpq1
Fb/RyB n%TZYC</LRmR6WbSulk%tD1KytGEmD8$WTwPy66\wA6Ib>Cumu+/F^i/Y+qeTm1hYQ@dyh%w!t%ml8ST
:kKI!X l51pkE4q+e!VNN9CGNH$^C%aB4SCjRq?Cp:i4cK1LdT^BpqwhiyKhb5>HXii9B4A&@RC$$%8>AX6n<wL
pHLF*V :tmncPChC$:L!iK16VJ9F/SR5<$<YjP/KbG4eaej8Nk$wW5L$JV5EKLTlF^8hJIFqQ\/MXq&8JaXihdh
RHcZ&$ pN8&dMI&\#lu@yShC:>l1<k\qWne<K=LVqRm$+=tQI?tIlbFA:yIIc>Kut>/#BVHm1k>aQkQW4*kbATQ
+L&!qB Q44D>DSQ>nZ*NIXi=49JCFB/CD&/c++&Dw1:RM1uXw%LTLPn!KqW6SWXcut^^=C5calFHHjk#WTk&9WK
&%dP^N L1W9=CbcEq!QWb%t#LcqM/%:EaGV$&+q6XSL16dWwE?AmqtXWX^#mlt*IKh8<N8i?L+5YEQ@KWS*dByX
9G:JQk 4dGnTht+/XLtbJPYK<B>!+==6F!@SR>5X/I*BB$jA==yQBc44u6aQw&&c/e1=*@bdkYVG&:R$jTHbITw
-A*%yN 000e264d0a400110333 Page 493 of binaries1.zip
58weA^ H>+aXH#\BhEWN@>?y=TwqP8bbiMcAp#98/F4DhE/VKt1*q@F^Q>G:\$a8LPS$@ucmcQdDt!nT<:ZF11Y
8l%n?D @&qGGn6PLp^y<DktXt<ly?bwkp641#XGj?QqTKY:cQ:jWWLp8y&!*WDX?HWh%1QbL!XP8h<t#y1C:#wb
GVR:h@ 9%?H9%/l>*yB@X$$+/e\++4GiWu?lkpdm=w6SiFeDFI>EAGJ/4^wq<tL6pH^:1Iu96%X<SPy*XZQ1dj+
4S=lS/ A9SKKTYjpkFh=+>19V+1y=lWpMtwRc%Z*K\hXE&X&t=ted%P6Fn4w$c#F:h16t&kWn?kS=>S59Lq>Nn9
a%%I&$ !6Ddt*buY5cKZFN6CIDK6PP=cMqWHF9!CGa:dn@ETW*5%^TM8K&M\duAhhA&1bb6#+:L1V4R$YRMuPd:
ALZQ+w E=yG5CtSktA9R6wTS/&aMmhAMPct@dQ$^5p9DQ+yDh=G%<99dQ!+L@PM!1m9>kE:M55c1uFuH:MLTYZ\
apQl=& #Xu^N:C!&Xt%p:SH#&=mdabcue&qB?>Pw*RK@d^4G@lPF/SNKWSd1cJ*<bS/mqc/W\t:n*:iWH%5V1w@
eYc!tQ *EL%DX^\$6N<Ij+SXmq4tHSy\Sbp%lw6JLE!:\eBHDjbK?MtQ>EjeG@$duRGqEl&/RFDb&qPP5>6wjMt
dJw?Q5 !Z6B1d:5VT86@bA?BkL=jIuY*wt%!+&:=%l:SiQ5bP*GalXVMBa+p?nXnP5XAdwq&RSG4ney!a4P#!Xu
adnwNB m+%b%q/kSAd@u5ll!b^!YNAmB*:FMR%eLV5+n=n&YV!kbGqABADB&6LatI=y!&=/J?wFW!LyGY8MieX?
yT8Q?B Kweh:LQ>6lI/Zn1w+ip!kmee55u%b=l6\BN8QuX@i8PkE?J6yce@waVKM?+^4G%5D$K>aJPSGbW\F1*i
JZHIe9 I/Ythb6W\m$lA4\je4:!!!diD!YSKS*45nwAd@Q4G&ST5A+/u:*HXQ%Za=E%/FQRGluXGS!SP>wBVPMT
Etk19p dSwk<!j$^mFS/<LGE5!!qtLQ<^J<MI%LpjaN89&EpkY@jc<M6+ac%&icX#ZBhbn:MmXKL9P%KDtGpcjC
VKBBj/ baw>KIkQm+R^Z8y>KQd9YlD/9BGG4TeAqP=WEc=QSZ+%&bwKJaIVCmJwc&b9F6#k9R%i!\qSW6I$Xd>K
MapkKk TVtXn:Y5^E&pLtD@*Z6NRLi/B9SNVD&6SaQ*+Ym1EtF+>^p6jKYuFuc:?*GGSt9BdFtGbFTPq:X&PZbB
9uME8k y<iSuDu\t@hj5yLqIC/D+Kj9M$S@5nQSq!XE:+8!NL!kJP$A!ijed+b:uai9mZFuS4bFdS%N!u:ilEVb
IG@*Rm L/&dyF9R:^\q=I$tc%#aia*La^LH:Yuk=^=/ipkJhW<qw&@yQHw6?aPQ61/YY^kF6d!e&NHFkMmeJ1ap
#pt$m4 T*%eCWt@8F>D^4eGJJ6=d#DDb$eAGdl==$MMGbVkE=d^Nke=jiyw^wn&hFC+:kEDGNi$A$dZKbV/Kk$m
MbdLLd GVE%@@KA1hjPdDtDM8KF?5lH%JSIJ5hq8FC4WW#$In+uwnhb>!SqHKkkn>Jq5b&PuIud6W<eV/ZW:WVd
91VdAy cmZMdnyp%HJub:Wp8jW\LV!YLGb<ek5YbWepm:qiR^1E<Ek!?hXhQXFQd4iH*^q>hAW$Ln^5@QL^#u/b
>5P/#Z EFb\:dJj6HL?Q8PiuDhlZ$^9GHB?wZjI\@mRnR^jq\kI>BeP#!Wke5!S:6QJDmJ:^in%ENAh&t*B$a5J
biT9QB X%+dX*6$4+4BpamZZyXR#yX\8!ET:j8X8Ajw@5!Dl9cnZXFlyNiEuFuGiNFc\Z8YhAEt:B\am/WGyw+?
SDdDIp PJjWLp>LLT$8:GD#uw:9VdyBljJbVI:#64aTqya@bKV&R456yI+H/N+Yu?mKD\LEtdGNkGRZX1HJNWVP
I4?Cw* =Plk6m9?Mp$W*!b:TpWceAlp/S%y%5cIKL1QeR5eQQ&R^1*%A=Lt4G4kb!cCY:n==DE1!R8!Sh+L6$DF
YwG#Z& P\>%^c%iW^A%@aSbjWLN5tPtP99yaE6%NwyDIHAiQ9!n$@M8F4?Tt%tia$:@8y+d8h^G%TpZ^*@!>a8T
p8S@G4 hAKwS9GeV$4l^IX8*ZTmP4ZZpp5Ypc!=6YepB%una^$FZ/w+jcAlQyZL#il&Q9lwSPAWecnJ!6tlK#nC
Z6tDih y$:%lH\iN>X16/h66&#4W=@^\Rk?Y5Q6Tu4TqRM:Ne?>1=dtT4iQdZ&8ke?Kay<5:CLpYGahJbSX\>/M
>^TY#u HBqK=4Fdl?5I\5Ewjja$d9ZXZb!eLhj6tSCCn6qKHSBKd=TqN^#+nHVP!j6w5HpPu4iDGhEIh@Dam6lM
D:RAkZ #QatEWBi!/cciCacSXG6=SS89GNw!^=\T^NTY8CF%AEt<KMQ!@DVFRqhLLt+ZT%Q91P>AC:FyjMMcZwG
/>@n8P un8pe&\<5iYaedaq:RYV+BV8a!a+5c/Xh1b4yb>9PQcj9Y1q:1pGEaMT=%\qlL^>VMQIEwISyD=LD&VW
9LnVKV ak$n8QtNq/Smcp<ZN8mhi>C+/n8Gy$5:XE46k/p1%u$QLHL5P>JRw=Vu^@QLiPIYQDKcVqqPy@SGh?>d
^G\Rmi y$k!G<SYTmtat\6iMPBetC8#&cT*GHwtN$q8A&:*9uBc8a&6&^1k<tR!Xcq4mnE^W#WFFbLD%lTD+:HJ
wkdqRY M/SjAIYC#9NjNAF#S<jpCb&uFQM6Fcaq1hkPJcRiihGR?>leYRYZE&q5aVKh?Rb?/WtnAAEL4:<wCac%
ywD4cl 8tMB$ll51pEkBW5KP@AP1yi@bPR\Nl<=yBJJ*qRNW&iaRM#NL*Zc1N@Y&n8=ZjhP5D!<WVh=N#a*iY><
&$y@@S c?!9imFC+QBQFJy<MIWFwPYZL&p58ItmP6KJI\e#@G6JaAF8Ln4BYNBl1lkLRN>XL@jCkp=$GC#AI1hi
84tP4F @uXnRaeq=+<F+PbV4<\jC*dJa9QFAuA:@eyyaRE&A1BGWQtVX+^JQhJtw5Nym/\TXhYwR$YVEqI/XSEl
kWPA6Q b1X#?DGq1V=8KF<:n?wtqc/pim+$#>:ne&ZCc=w#+VX/9\REjQt++jt<4t=Ea@a1YRTL\bK%H>*Y:Eej
%>\pe8 &b>:i#=?^LqNq\CLw#ZLqXB&&+q+J/^jeZA>hG?GERBPlb69uY^!1t:#:6CADM1jPtE<dEh*D?6KwZE*
N&ned/ LL@?8@<9*P$\#uW1ai*q:^1k@tcVNZ!I4GE\&dQd=yeLqJNVP1\\?ZnJua!5Kb!Q=nN\cZeeNwIaT^WC
J&=$S8 QV$Vknu:%hQ!#N@HbwETll=?%Xnyu&9QQNHbM?PtR!1Ytc*+bt@548N5$u5DD!hjuc9*b61Di^!P&J>Z
*E6&$\ $u<D&V6PG6K@*l6WI1he%yBmKHd+&DRu@bM%HI\Y+1Yw:E=?HClB?8hP#m6R&nyRkq=+FaK@6W5CJhH<
&9#BM? mD+t%nFTT9V9FT!X@K+YWR:$ZH^K?@ZQKHFGwL^c>VEp\c>^<$&XkVh&@lHpSq*Jk<#!KiQNX:b:e?j^
p/?^Zi Tt*WY/ya/yqVS4$Zh+>Q4j5IY*WDAP9@+yTS<DZ9b@iAyyuY^^XA^NS4lyAne@VPbh?QG=F?jPBM9w8Z
<$W:&C $4Xh=#=luJiB<L>?da/<4Huihqene@5D*T\EB%h>#*D^iFh9&aHG6=PGt8cVWKpVa/dcB^qDVcq&Fe%?
*hV?>d WkG66qpJJ$><#*D#RB6R^E$>mh:yqq=L/I+dd$Kdwae+@R5q*ILL5d<%uQ=1nq!<Nh%8cp9Kn#1dj8@F
t*iWTc @Bdm@RKyn%6?wJ#cAnIF8*VT$C5n5j\npjb%JTK=k6#yIlGLp&uV5mak*Xl1*^pic9uldj1*N<ty9a=H
bym6<w &9nAYTH>c!L=LWVe6^E:knlBJ:\/&ZTA\+VY!L=1&R<k!MDle&?VFL&eIA%%GL/Zl5<D/m1/Ya4XADR/
&tLL!R q<p%=#L9@6N:n@VKbTyNjtF?u%YL@Q>y:$9k=K119F>XL>pZSDRwRwFCE8\PISAIaW5uuV$pIR5ESW^%
KGN$a1 h*Y//KZc1848NCB$RmALBFBCqFWSXHCFRS%\SBaJEESRbBR@bhGQGZeHGReSHDQuj</=!*9%1n1J?99t
t6d@pR t?tG!q98i@iih=h##*/kbILFb#<R1pF:kP*\SELR*y!ckEtbl/1TN5+BC6>St^BX9wlm+6EiRG/tl<8k
B<C@tY 9dL9!:1HeR!c8wh?T41eFTbhX4Wb9<ymG:1dbXBFl$!hlkw$B+TYkGbMMmElE$+RaW85^/Sai#jtitkP
PC%lmP %L5b:Hptb=6bQheG/\m\SFS#n/9=@MF1#1jZ^hYa!uYyFM6GdJB&Lk6EFRnw*/CjcywHa64BuJm+9i1L
4n%ldB eZNCVQE>NK!1YFY*Sp&YWnKJYA?hEmW\qGd+$MqXhk1QLdE@F=j4j$$E\Z*$A:#nclKCk!aNFK4e\n/F
TA?%a1 +Nw\MMwkQRke8#5ReCE/ZZMmcG5u\MV!L6>L1&#T$qX%1bPt$&<GNyuXT^i8tT^1HKMm:MTE<J#/t916
*KBBQu u#%p4Yt:ep?cnl1wH9YGqJXQhFtlcKT6MjJn%w^Cb6%tXAX>?Y#Sh>*$be%Le!p4/5$YXGhVKnC%<%d^
Lqa##M ZeT#6qVKKum*JGKBSttAtZMJ*E!kGZSMKJ!cc!A/DhLk1KCY\YSb4H9D8FHRyBlFI@\#GqqMCKAFSh?:
*uibqG E8FSF9R6X8c5Vnb8lTWDIGQ4Cj*baNh?AGN1pG=El9cdmT99$ISqG#!X?Zbue6$1bG>VHXuE#NT?IQbh
NZXuRR %yT5K^h&aZPdY$\u6?Z/aC$/^StyaLJuc^YF6lDqCK4^%GHJaK!mWBSiQDKl*kI8LEP<pRy/>c:cSDpn
/5XG4m qe1XEANFCPAI?1HS%+eunNb=duWat=4%J>1ZP4bp48PIF?IkKidQZkAW*hypFCP1bGNdn#H5knXDl#mK
?CB#^p !/KLGN!HQBS$haw/yC$uHn<^1!p%KbQqP5\MEQYMiDLu&KG$Lh%N$QW1YcN?=bQhuQKYHBMFeRFYnLW*
\h&VIW KB=5X^&mE?w1YXBl8?+!J9QPI5>wiu^CBcTHH^SEWFCF?qn*wyE^R6FEBNJ\>i!lLjJVD^pc>XNap%SK
45S^?w XW$Sd%TwHup1n4DVed!dn1PbXX\!h<Y1IFlDcPFa?tHGac14#4CbdhPQD\k6KGjy?&+M$q>5j?t?1JB8
GRA&t* XdqdwT8Z/<:C5+\RDMc*WEVZNGW<w@%Y1K>D9tCK%4H?\@nWipLWmTi&?Qb&=/DGElYqLwaatH8/^dKy
Itqumc PV1<VhTL%upkuX1Z!>FWc<tpK@wRSN%HSMAP\S^G+ItSmtNiyw+GmZdR<GR\VuEMCy6GM*h1yt6$tVa1
pjpRnn 95L+nB%qS@TWW9/$ZA%BkGCEWDKn8aFSCeNwdC9Lwe=lS\5IBWL5RkTBqMlCFAL1kjQWNBER9?BcdByM
#%>nuZ hGN5P/%+Kydq*BTILVT?Bh&u+wW6aYcppmYnhbe!jWcjYyH/L1G##Bnn/:+$Y5j+dXWB:!HHnW!!SBXn
uYVt+/ nML%+^LGXnYPtDbnnG>=hZVbMc=RA:HjNL&iyl?c?@qa8+N<wm1<k:D/*+@1a\Mj%IWNn4EbE\*R:yD6
A+<IY6 ZmNK\aqqXMy>88nDmD#Pd/qaGqywQ^Aw4?dPNFF@tR/&T8nNqlmJ5lFJ&plWSI*8LNd=Bh*Z!mQ/$w>P
wWIR*a l+Y5VJPJK6&#LtBZ4FIEV/&t+V@4<jtiydPXIBn4Z$!cCiMTk%9@4qX@Ce\RVE4XcC@^Nh4QN8==9SK9
P%/cNL YldQiEw5AQQAPF$X6TMC^uy*ZbbpPTlYBR4VC^n#^XkVG!WYRB\>K%FBmSXump^@D?mL1MCaM?Fihqbm
%N\yGW eC8=bZGMqlGTiA$BFSu6LB4:^%tJ!6yb:>%+&hh1=aEB=8mGlATZ1LM<5A@1Bq?E=\\\JlWti&dwdKT<
+twp^Z u4DCXQwB9E&#E&J\j6=APyqMjI+++45TdHE?kT*P1+N6#8C<WY?\+hAiIkN/QK9&ZJeZPK\Di&MRmCM5
-AD<\m 000b9dc3c6400110333 Page 494 of binaries1.zip
+85Snh C++pVln:&nDb*y#8kb#jm/MWR1>8WuZ%q!GTC>b6$R6b6m:H8^NX6=JlEC=y$6KewHV:HP=*FDVkpeLL
C%kENF #$+PRk=yNlTLjeK8h4+99ynSnXDXLZ+aGck91M<S:SWD?jTeBK?Nh=<:MGKRjy<\$PV/9cVd$/*+uQej
K6Ew## P@$DmB9RW=VwCMCL^Y\9YKH@F/PkkjIpWyY^M?^BWB/PBKS\cpi!SNF$P1I!MaCE:u1WWD\YeJ%$$put
$?nnXS ^TuC8!K!BKd9*a&&K$>MDNcXS+T:$yAZC*LF>p^@TXeS\1e>BR+hKa<&cPPHaR!H<JMISeP1LYNIQ*tK
HB&kA< C!WaiWZnbnLF&&NeXVA9\^\899A^DT?KmdJ?49*C^KBj&Bd?\8YlCb^6=cE$R!k$5p=XE?p\MP<W>u9Y
*BK1c@ 8#pQkTBe>VFI6<&%/LDYW@\IPlVB/T!kJ*y5@D!LqkeG$aw6Y?!=L?ihM:b8BDcTS:iHy\Z@k!<CVLQt
h?D1X> YdnGq\l&ISYnHiT/RMTGAP!jHZDjLS9p^*c^tudHL/5Tc&+bH>@*&ka/NRJ6PMlCPSEEl^A!?S%/nRD/
E>XS6@ @j!ECV*$jIZRR\kpapC^aNCmA^Gy<d<KGXaGmlm4K!PcnI/Mnb=yX#u^bWWmdq4E?$\MHLP=FlPmSBc%
hdISJ+ ^yBM6:B$keN^IR:VPwMZ+Db6t&>GdCe&*M6BRtNe=MV@w4>R#HSmCVFTCDPFdj$FmaGu5i9E<SR5ARaL
Gq%4l5 hIWP&PXq8<aQtNCWk<Rn6L6%m:>CMde8I^KM9A%u$AFj+4N%*<e+*L6ACb&nEPtZTQ<QdW/!Q\kIHSS8
AAD!&! Z8\yIC8!GbBPRVmHV^m&$BI?K<yyI!64DDkGDI\6AMR6C&&9QF8i<VPiXAc:<dmJV&Yy+WAl\kKGw4J^
bLI?HY >EHYhIctERd4w@Chk=!cRJ1/KGG<lD?#6%:CSQe5b\p$C=WWWqA?V6QVyd:DDCchm5:%DGIkQb>mFa?y
p5m4\& Kk/Bb6BJQ%=pBcR%yj165Q$$C<Jd+8Dkn?bYi:1%udwaJqwYwh>^pFNY/n\n+EjHnX\eJ?Bj+A9+ajpA
LDmZ4m L&q<Ficl?nQjH9ES1>quuTbQm6KA\4VXTamVkqy\IFwM+H^t5c/Tb+myAC8\a&8Tue!^TqB+#6JEMD9h
/6XHW\ #AE<1M<m@aVF@T:/+S5PYtJZ^5#I!mljRSA$W5M%>DPN<dSdMnDGF:KCAZ4:6WiiYp=wAE:TmD5kCtJV
=mAYm/ >:lRwDFBYCALR^DJFuuCn/IuEnJBiSD5>ck%6aSBV4WT8\nujyAc4ASqAXX*#kWtLkhLPbF#TQwdDd%5
>%DJ8# yPdcVD:ZSL^1Q^MP9qCMtNt$5d\Q!R*\wPPPYhjDP*XQIXW&uDJ\MS\Le/wEEDudqNTKNIQEAj4KjcT9
6=dB&S NAl@ytkwhFPCJ^wM!6uY*$4!TwS+Qwa4K@dBFQ#$Wy*SC&wD^9u*XFWFd>WbneL&Va#*Dhnq^D/am:>e
pP%4#a Ypt$X/+GMa/ETV8cY:DM/ndnQQP5d9NaR$9q+5S/VuPcE9hTiFWC9NEDhkN=yd^JCiTmHmuMIYJD5l$M
hpZ4db 8^@mpLBm8q5mDdG^D+6FdKVDm9NW^c$^j?kK\I889TERCTn8jYdAI5!ZT%A:^><tRknmtFkyhKtiR?bR
5XXDb@ ZcyNRw/*1Z^L/YIn5nclh$I!La<1BcR@GBmeK4%Ya<ukK:IdLRH+:iTkbCtL5#Xt6kRbWNXbQSFuLj!F
^dnqKL 4IjDY6XaWTb19whST/XiEw@P/G$$an$m4ScMMyS1:Tw!mW5nVn6pV=eGj$QANIIKKKW9p&+QihDMwbaJ
D658HP ^iT=j:X^L=T:C^@L<WSFj?SmH59PdGlE>He?%+Ea5kVK8tId9MSwj?N\VbtRmA$mRmIKi9I<8#S!nnlG
<cnaA9 t\\EWGqpm#*m?W5LJEpd^LM$JBk?LHehpn9LB*^XlVHV>X&8:?1wb=&XJ?c+/XVFW:w:&LD#Bmh\9$Rb
A\SDtK !yVb1\^BV:Pk8ehE5YJ=4SAwWtqDC+IRFwyE*8cI!Fnhld:ubhCe#Vj*hCJIH\h8:VjX\8IWiu=cLkKj
#yH!QX EnLRn=p6MDyX*H:BAkP*?&XNGC9VhFe8*DBLGIySna\%ICnhjTQ>wTy=G<c9DlmF\YnJIHCPmFXyG/Iq
?M\wdy $N&VS%^1XAYXn@kXSRB&Ii+hnaMF?dXNSlFRG#B>M&%+Fh5GaphA+ab6mYC8m/>cl5dBSQ4Vy4I$V9pK
<#ulIJ k8B6NBj@nYMCJIJ^q%8X*w9SIC&G@cpeqe8FNqR>4#l:1i6dJAaw1!1JQ%SQ4E+P>qJPT!dVZCNMij4h
4%y&eh TqwFF/Qh5!X!TT:KjeyMCe<AiVI/hjZqhl8dXucSNpDXt?%AIC$me#t$uXk<\bke@jyyX<8<54W5/\4H
\Yc+n* <wYNyR*l/\^HAhHQZZ%Hq/?9X%%^BDGI8ljPdIDtwM%&A^qha8#D<TJ&EK:1wB@c8uP4Qu*w\I?1ZjBG
%SNtM+ cYwP>ZF4D:6=GpVMJBc^\4pY=*CbM%wT1<CI5AuGw=Q%MY:nLLHQD5Yw%k\ZylZGR4Lhi!FI#XdtJY/R
HDWiXC hR<H^ZXEVYS+?NRwRQEG#SjtcM\<<e&eW/5!Hbu8Nw+JmNDWEq\RI8Hiuk=Ayq6=b+:&L^e4Ydt#LpSF
k&BnIk FNRkMnbCN6mW&nIIe<CcIbewA96jh^/+WGRMdKSNJKt\l?8aA<>LcQh$mNp$#Ha?Qm/#DRuI68w6wkiQ
6%M&dR YwS!STa1LjyI4YAnyD=aFR=mA#6!WT@\EBk41@A+a*TJS&uPIGESnnRPGRpSpteSIqCD<d<q=FyEjGy1
45FYDn t/d9e#BY\D4aLMlS=&R/Eb&V!$#\iw:u#TRLLcX?nVbdH6H+6Fp$RGdy%K#kC>9W:$JVWY>b:BSnl=F!
THH&!D <mG55?i&/c+\u^ajiITiEXY5JeP8kMLH4$^+#yp5VEDk^=APWcA\<mF$%eR4K5tH>1I!J+MFED88GE\G
JNi8tR /<8HTmQ6mAG&F=pE*96R<cJ=hApeT/CLA>!HZtpd?@4k9ES$SDL45!b&i!^9t#WGtkTq>XZ*DK<@F+le
aGK?B! BJ@<8IQpndKm=>YiLSFeZYK?uFhSibPVCtbFBG546nMq5F&!4mp8+l9/c>S&uWb9GSE\adF\a^ZHDea$
qt#Jh! R8GcS^KB=?*&wb+$Am&dmG@+$HudE?Wm9yY?TB5h#XimHLnq%Xeu^BXw!5ADXbGR+Dd/<ntcBWtRuIp<
PWWcV$ Tm8W<c>JN?Y9qHQCN&\PImEM9PD<LCjI=X8RpmCuIX/qt+k5FYYVbkqRVEW+8mm<yM*#I=k+HKBMIupc
+hH4YA jK1+GlG=i#1F\PR/\8@MCNWJ!dN+V4mAwH:EV8Bq#qClAcZFL=?jWB+ynthp>pnA$dSSpd/45>d!*Euc
9W<LBG BbJSAeH\iuR@eqtP5w:k1uM9tkC!a9MEjEkMN:jPt^\IwHd=!w6yP5!lH&dSm\?y<WDn\PbRcnBJbqMV
ujXy%H DI^$@:J#Wue8F^yyIh1cnJclLh9SI4qq$1AIGy^pTC\mHJ%Z#Qe4p^RPlRAP4+tVycY/MX5BImc>=\=6
y$wHZ< >8a$d@IcQaDtXqPB?/A:q?t5T*Z$=:QNLI@w/5pZpJE8*>dQXm$cJpL!NIStLehMl+RZ:9=i>!PM?9yM
^99*tp m<\!N^S%XmH4*YI=ta+n5eDSKeWV*nG=wE<+ZX=4GyHc$!a/15+:$ZS*\B4an*uMja*=XE>6hmJ#Tk:l
E6?ee: HJbule%Py%#EDAty%=N*AnbP<kQV+G^:Sll\CiKFmwpKYTh/Ha:a!/FcaDYqkY%:5$YVCwcV+Tp%It>F
WD95KK b*cA9k>5+A1Z4RRe\8GR\9ZVLF^IQ\\#5J+myt84K!Kt<CIG?YC?nRm6FywK#IEaw6Xp%AlJe#W<emSP
EtGnGl $btCMIt@6EuWYnupSlGK6AKw4w=YJn?6bpVE/mZweLWnj4pGL?+NXX=uS=/yYqw#Gjdi/$!9b*#q^d1N
1mZJ$u tAyDw/Q1K$+cX!=CWIcuXGS:e%G/NW6WJPip<PEmNYQdhEhQYciu5N1IBS>Ti*%Vj:&l5BCbJS#KQB$F
4ShEim 5I#/CZ!u5BcYbhYWMY^pc5\/qPuWJ*V>m$TcCjy?K$CRVTR<:IHaNaJcAG:=&mMJ=*eIpt:X=XWejy/b
&u^TM+ jT1e9#5lwhyw/5hT@1D/tVdYh5=TT!XM/hG::Fc>Nt4P6T>%B5G*ccH5yB>A?8FnCZcFTe$a1A>FBpLN
<Vaiq^ G*$l5cYSPRy*Rb65b8/d?4p*q&*^AenSlPk5iL8cC\P9<mJiNe\5IF>RS8Pka?yR*!Q<14ikmN?CLC^\
8*WLPN pjW%Yqbw@#Mk5p%L6mnEl1mtJXA5%NItWwZ+GhNVQPkY<bu\:Y^4nw<C9I\LmcZIbm#J/T@TXVb<wZmI
th*Bte yE5\YK4a*/&/j<PWbd8$WabR/CKCSd$ctD1u:5^%6ikc$*nPVKLpi=4FyNtFBk<?FllZd1>bcW^R9dSY
qy9&6& b*q#aW\L^JEme\wu+:A:k4PVElBhFnb&Gp+DhXqVZP6<e++X!h5$tMl8K6SNyq@LuG5KSA1?GKC49$V1
!mJ#>G bDNhTnauS6PiiZ5*EcN#aXK%T%aZK#QjM*CFC/c8$^kYJthq<+n=d:=J1/diDp1&k=^b<P&b@wJn+iEu
l8nVyG XM^$1j!$HRTH9&9$ll6RAY&lL>*NWpP>4T?:8Ta4TqcTeWkIJbkp6MX\MKJuhZAEpNIy+mcGEdJGlq%#
jP@@FA uWXlb6/pI=h4N!acahj9Bb1bBGnn/6&G@SkXMP6^RdKclYyAh!l<6Cwb4DRa\RmPSI5\T&YpGLPuh%9E
HZVyu! hu!JuY45&$F\F+*=b91ltW8?dhZ#+/yKelQ=p1SmPEXYTFDEY*%Lyy9&naKlh8KFMlmP4q^E?MV!V9cE
hnuu/= e=Y1EqeEjl=1^BJuc%Ep<PW<6q*NGbiLLedTB6+J#N=+?S>=&$S/EW6CiG<mBK6%!\uq@wQJty?RWiW^
Bje^@\ 8Tbt4@DXMFR#NE@E&$bDd*P/Ni#8^Y!*lNpHqmq1knyR5y*idkSWQk\cEXm#$Zlh@tVC=P*=a5Y<QYeI
@6A?=h db**HA6/88LNZPL/\NqI<PIkqFWZFl=a!@N$c!cWCGVj&HZuaaS?ERLdhS&$FPCltGH/kRdw^bR>>#8&
Bn6cDR G^aQqwaJi\GHu?Wp^uunBttT/lut\YT1ENcNtdtYdG54pui1p5?IbeNiM=+HXmGV<eQhlp*4HN1*p\\$
TqZW?# $KqA\QVD\F:@qQ&1k=Q:N4mqJlLPwLCRESyGpLIbYd6RXRBi18WmJ1Nh<&nu4bm<M>&XZyhl=1WFNHCS
A$m+bp V=uF%wTi9NMab%K%\T64PKHSC1XD\>/1c5bR+ByyK+mCT^*%H81+X^D\lcdD@W<uPH^P/wTBu<bPmcS#
P^ychp Sq=1>+GMBF1JWB\FaiI<jnE1jdCTaJEq=>q9&ya/8$tQ\PwJ!#S!1jN#/+!eZapLVXtab4E8M<D$By!<
JNeWbB $5yNy?tqhw%FcNm?Cy<BqebE/1M@Wd>ke4$TJI%P>h<Vk?qWuY\ZZa6Z5iG$k\>4!^pJJd8bl9G6!$Bn
#eD#y\ @XGbjlHYRWZmut#G4ywIY>lRpC#Vc1:ki!CY^YCTQhSqi1W8/@JepA*TMp&dmInb9DMpwHuXRq%&A9*\
^*p5cp *c8T655/!%5GmKIXNFlE^e5&1hIbHHeTA9cI\cXhakcVmAhi&kyAT#5HjhIHZWIwtbN8c!+<Q8bw6DGP
aF:NF1 %pu@F5DVRjmnV1XS&+AIm=u*%Li!Fquh1ip^^ZVA6^^kp4!<?RBCWkhBI!@jJNM/&5hd!@j^dMclic95
ETN^Wh NA^FDQaLl#DXSQIeRcpRTTqpq4FXa#u6l=hy\Hn^85R=dPT14?nkFWJb!i9ppb!#V^Dt&TWlb6kAqCei
8hLWbe edSC!DbN%G:FjLaZdCMSLutduFwVKSumw<=:A&T5<c9%w8^mSl>auSV!<<jEdaQV44?5ltqKpJ<w9HX+
-AdP1# 000b108363800110333 Page 495 of binaries1.zip
RmCn*k MyknGYRB:/yMe%5Zn?DKHna<MXF&MZS4/Qp!WZa4XSEEY\I^8WKDL>FQI@S@$>KlNeSKn&RXVQSq*yHN
nedaCA !F5FJmc*C#Y468^y#*5CI>bF1IBY8RyGbtwEbjRGQ1TlJttChDXX&wJ:5\Z+Ihlh6C@VSJl^b116YP!i
My\YJu ie\^jZ%>W:4T&TtEFRQSZ<F&AB@=ehjA$pwNmM+XSu=WK*&pj9m5:uZh1HYKY1IikY^\XPY9ZLYNqcwX
DulnNY 4c^YP?u+1VMty$/cMcQ?8BuHVhMR&hlaAiTJ6Wtn!=qXhqG&y6hHKn6^c9%JJ$+:$dP6BYm6XNpk\VNk
=A+#Y/ YRdDe:RdDE5GS\5:?yKu8&RS8Gnp%L:uR#*ay@PbA1%VESF*R$maecF$4XRpw6$FyhtWcRYh%%^lqtJ?
HtPQ#< LFa#SZ#E+tG&u$?wtL*Wt=cc=T?qahQkMwkQ@KT4cqGq18caudY:I%*pbHjARHPY4+bkJPNNL<D&^&F:
R=J=nq N:$cdEbW6&KWnb&$w8EMLMZ*c$\c\Lqm8K*&4E4XLqW!WZEW5l+LI\?R6S<CmS8BtR6wkYy$unXYenCR
T*4tV4 yb:Q4BQVKuTwLG^b9QkDqM<MX>VY1?kMj?<$q6FW?QaSTjdj^uDe16ecdthY&L%Z*RF#Z8=I!Te&t&Pi
^qPW4a t%bS/aIS&81XZ18H/DpKd/MjP9RECAH$Yq96<QEh<i*yZp&+Gw+T1:GyEHBXXb9G=>GDBW$>c&D=lAjL
\KQ4CN 8@ReldNHJnqPI5Kd*cdZC56H\:DMASuVIi%=cjA+DQQ?kIjYC!MX9A5><A:Xe^ViV:>F8p=t/:YC6!kM
@:uhje *kJ&K8b6ADIiIm*clVlmkRM6D1>y%Q\:$*T*%@SlJmw$FhcQT4IlP:dC?@Xct#+?*DRHHp/H:S*#ju8w
kF>lSn :4^S&6+HE1/>qLcH\t&np$EhqhZT4%/9Va/MbLnBM#I5^bZPXcY!u=*Eq/p8ES%uKDk<J$eYdNjbqJYE
ld8H5S Z&LW*6FN8!JSPjq5e$mF=m5?P>Q=hyM*u6ZEauLbtt4L4kNNyAAJb+Imq&bT%FI^P4l>%1!=#pZj@hNw
:ya/Qy :h\L9ME<ZM>SYE%hmCu?HtRy%G5h#AZl9q&S1T?cRNJMqyWjXqR<ja!&@AY9=TQ$HIX*$R?#G!1Ic4*Y
EW<a!t q4<RduqlX\6d#lcM>DIpyA$F<#h&8wK+Di6VG6dI\RyRjnwtBl&?Y<>SiNSal\:9$85ThCnIIJTB4TR1
iT58=% 1GpXqb+>NtcN9$jQWZn4YLjGn>L4?DY8?hPa*XBDqdJNw?bu+yw?$8B@Kn^puG9/X4&Pd>wtSC5u99A*
>Eh<b: Ac4ynHE^M@IwQWjl#uF8Sl/m%@E#5nFdwN&?Q=^ZMi!FcXyG^a?bqn@q6V^S#%HaPC5bjEkJ9J%/DTlT
uJFRty E!RHmt=/i+IGyN=X8ZtBh/J$q/pAL@a4%%N\!%emCLyk/:FdkIEYhjZMWtm9>1ChyPew@D:>wB\E<hYw
J^R>Dd %\y6$i5u6#<^=?*BbWGKl!bq\WF4%R$^??XpQWhl95H6q\AF%@H:bX#9^WAGbA\/A6Db#MB^?!Xc9/$l
umGRh4 bpIj4iew@G&Dt>B=9a/j$I&bRuM?&/Rh+khRWBhN4&uWjPn5GEV*Zn%H+jY#HcJD5:mPS*RNeV/<lhlR
5ahREM MSWnE*nSBl!5APWJA?8>H1^%JnRRFb+=J^q5Sq\aCMQ$YtF>bL>lqRkC+aTJye:/wcACH6\Ac?Melj6?
bHiJ+M D?=/QWjl&Mapy%^el%C8i1%\Q^XDp<THC\mHNSCwujpL??B=u%j\M!/GI@e++AHd/a$K@G$i<FNMQq\1
YyM^WS 9J6?iYYl^84%SLFK*ipBQ#At<QcZtH:t%PL18Db6?uTmCNcqt@1LR8*Nc%l%*DVu@8>YN!D+tRH^Bk@E
?LwJ^b a@Rela9uJwP5B11>Y/?%j:iW&\>mIP#^XnLn:k\4Hu%!!?5<NH#SZIX5y\jbXD%H+W@yq%Gn$5X/4bAN
%<1h#B ^FKnpjb+FMY&9EJwJk<1NQ1YiR4X#S=W^?w=Cm?tZ+jG=khE8Fcw4w15I?EaClaP%e&!&mWW%>c1XNLq
&d:Yn% h%m$@iX=MjN6ty/n<QD=M6?\#%&5%\4eDiXaG$mNQN+tHyC>at<A\a4=Min/PD%H+W*#Hdw?ZK@@i9aG
*m@:hF NZ@HNF*\tn=i#%E+dpGT@TVADN/p%>4$#JkJFdZDmJDC1HHYAt*!M1@J/Z1P\l*$R>+A4Ll^i1%NulhL
BM^9QJ /MYq/c6A+/KNZRcI#*lAuKDuKJ!=pImPRPIL:hB4^WI*qYCliJc*dNTJC9QCITIA$d=Rwi##wD^S#%F+
J+A<JN N@*tcRVMtZ16ZVY:DCIKleJ&md^N5/n%b/dbLX/#M\#?w<KVFmXbkwSqhLhic:M6EetEC\kia>VYB<&L
\5:/1p F:e8=YE:19d<SR4HXI<ZQpulRGF&eVJAKBM+Mb!p%?y\hZjW+Typ4CS?DE/&J^GdVEbqt&eNh98GYa//
R^X^qQ #LmkM&!PAARA<$PaC<G=MePSX&FD!P^yKPA&NDyN$LAc\*kP6?aLwmG1:wHFnW6WGy8b#jWZ88PG^hyj
<KW/tn uWuZZ#P%9%D+k#PT\TqWNlKSV9Wca=mcNuBR6V>\@Eh#Y&QT!ui8SHeR8hLSW8hFJWld1TB#?bHeDB^#
@8C%db %5Wp5mqSW=N/C5dl#^1Qh+tuLw\bPK=DadLwlF$VdKj9DQSLa:8LA!#<Gh8k*W\*=XTt/+DHLG6p\^M9
N9b?$S l&+/S4dy&9F!>Sy4V9&MuATRaR?Qyp!^D/N/:NTy1jb5S$/JDS4dcZXV/b+nRCbNT/*L/5ZpKX=KK9EW
?@Ph!% !V6qXIe+j?W+L%8#!jluHEyCM<F/FN1l+eeIE#yk&ADGA+R>B6F%llBJh>N5:5:D<mKXV:hpe^4<t1Ma
L!<Xe? &<tG8VS51W/&:h:mQFpuG\1dq!YDe#ZAKTac46Xi4Dpp1FJ:MR>XhIkX8Z/lnCu%RaV/^M:L1i=pR!/@
8TbLH^ RE9m*NiJA^G$wS#/Db%TEy*iB1N!6uACq*YSM>w>P?p/Wb$aR4T^:ZGS:YFT4CD*Qw!>YVHIeSFJBDA#
5Wp?Km A!T+6y8WY1e*GPn4He6$MF/whaN^mk+GCnh8Tkd4cNYjSn<M^LCNTYQE>iHw!6@n=VpkCwJZTT9:jlR$
eL&+8C Zc=^cPC9bHBquV5Hp^*cB6wK&R<:c>?THMt4ZJaZhX<8\5VBypaXMZI9??Sb@!JCnHAqKMtHFyZJGcMk
Ic>B!i *:&E%+iGWm49Z^I5%hnMhcI:l!mdB4pn$=9ypDD4auiq%p/8h=#b4EFVQn^1SA/qaFPHM@nZ4NeLJF/&
1u*?m+ 6XJnddC%*qEDBdc!Knc#bNSEinb/e+V>#5eEh4b=N>p5Eb+E^1AmA4%Sb@5\P#LTSGNW/!&RuTuCat!*
N?ZD8< c@NYBMGFNN&I^\@MFMStqJw>eKtdemPDnXFuFWEHw8H:P*k9DP4!lLVw5EGSGa<Pk+tVMb9ib=iujjSN
8NMINY EwthPIHcX+!+t=bC6pWWp@EC:#wb$uT16ceL?%KcA:K^DSq:?BA5LdwKB9N1/8P6y#ih#&bEddBQup#%
8l&AX8 >Y1GVNSP9mYVX!MDThmWKiNm\#P>mSY#wJ/5Y=aM6GkK*NQ19KXYc>J@/4dqw$jCR9h5W9V+Xt?9PqZS
GZJik: I\y*ZyaM@m<WPBBT/LW1XT=MqIcAF&61Nl!Cd^Fwk4mk\IV=lZ/dJ#bGan*etXWL##=NjE@>*XQI^Btq
CXI!Q+ &Q!5tke4by81C&$/b4QWjaa>M+!R!TMY<etQZcb>M5d4p>PM@JeKd:5<Gj\EpR\k@>X4:bQPSEtTET>c
+wZ$E= K*<XY^AZVA\p&l:W>Ma^P$cB$WE#&&VK!65w=$TGMFPNiij/N=aR>&lp>CZmyRm^*P6w5nCjFbJk+F8j
W9iN^! 9V^GTHC/$Z>T+d#NImRAF*/dZ16^\k/jHW#Em*RX6?/nTNjyRKuF95$K+8$imLQ$HIY@wq>BPhb=i1%M
4MtLG& &W*l+Sye=L#*RuwLI$B+=^cFeeCD5WHQWZk?@cDIl!\c<PFcaX\XtXJYtkB@SLQQ4IbB*FLe5KT<cS@X
H9ja@< *:kqSn\&Y<>SGG^%+4H#>dyEQJaIC$dVuT/mml?c^<C$#L<uaDtwGKK6C6WPD/w=iw=CBCyyDmSQZcDZ
=c/+IS C6XF=Z4F4AK5LNwdXZ!4IK&Wt$9qblRtNLq4c<^5cnV!D!1e5e*Nyl%/HV?d@84wyZ:MZm9>wCc#&^VG
iYi1En P#\a==45IFV+E9*/%Klylq+4nLiZFWQ<LZkLB!jAPPAKljPdHy##>B!F6>B98\a$Ba!+Xnm@G&5?$5dP
*:w5QW /Pq<Q6eu9F>#Z8!utb9lTL$\#8:KuP^qDtN#Z96PT/deP^:$AP=yA@&9QPnu/#pK6%!bDP+LJFZtLZ16
@c?VMy ?<DESM#$VM8TMVS9jDIbjmVCkiFy!*%yLQm?5n!eTNFk<yy6Sc\M/^:F@kQm^P!?FB>!*=W^e*/Bu1P\
#=t/P1 d49MiYCwLZ16P5SdRlyQc?ZDDmH\h1M6Ye$<8>K>^NwZLa6m#J5cnEeDWW\L8=1u\Q!9pC%tuJ+VIH^k
nbISI4 i+#wdcGiw@A4&=*w4W/9T$S9aXMpXT=adFcIllI6b6Kh*1^AM@>m+DnHw\+YKS\wHHM%daBWq1DjX@Sc
/VR/8S SY>Xai+iaq4nI$Jn^:\QDYGLGQt4=&<unC##j8akL#/:T#T\N/I&MhR$daEK/LTBEY%AHHbSKq4Ha%<Y
lT?X=4 &FM\HH?tJMJT^AHN<$tcJNq^t8tyJtJI%$$&FI#Z5im*$//PGiDFiw:C//=&A#^G4<9IXyY!m^YAG>tQ
5R<Zh@ qjX+eKCbS\$eH@bplW5WDlVYQ=RM*1?S//@Vc^ZjyAeZ*=kc<PbjL<4=Z!LJRcih>%CMXiAb^9/LC8>:
h+#KIL TK\CwS?1%&8qSF6LKNG>tmJYQPnDk1b?bYB=\+Nq1b/n<J/Hp<F88wdi:#/>4yQ+6meujGBMFIw!JuAy
bQ&Te* EHb^nHj#9uGIGCC%#w?ZDcVKmkZeq?QDZu=a9@^m:<8Z/VpZjm9JCpP5#H9$YphlWXk>6Hi&a4b%XN:$
M4%H+< 4Skd\PZcPk19i5VbAB/4%$M&kIQdAKL9Hukp^uVuVJMXlR44h#uVuc9$85S$^>6lDd<b*jkS<!BLi^D%
VPekPN b=iqmJh/DK^\!l=+cQ&<ZR4inS=+K<#/y<LH/Zi?=yP1%&5Fd%5eiEb*FAYQSch:DSyc@6P8GDZ%Tn%H
8k\q+& +b^Hub4/ed*?/>ZW1Lu+1Dc>%Y6/qb/n<Eu/4hHwDZQ$Y6jn&lK51FnImu@nXZ\qT^Q6@PinMdV?cn%H
C^R+qB +ddHHK*@yF:@6/D%Ah\@QcdRn@MR!%uG@yWK4*<<Gd!AiQY\j>X4ST\jTwTH<Q>Qjcw#!1Y9i?L^GMd<
FF\>/L dGQ@SaZ%8^%nj4%i^#QtMylmCMDt@*yY888KNE8<&CQ$Ibw<d:jC>FpQynXt@XQl5@V4%SVh>Z16MH%1
jl^%Z5 u=lit+K9JDH*ID\9wKl=R5H<mAjtPZ1P\k#>pP\KGpGAmG5F5:iM*YyM+FmjIam\ll=AcG@uE#F$$@9$
?\>HaZ HIY@j<LSVSt>@n9RVYn1mG@H$Qn9%*MW>u@d$jmAA>j^VJ^9:J%^eaaAAaMW%p5VIK&cc^uN9GnkIMcT
PVupL9 w$XehZqNeK:CkeKcy=JBR$8LCcc=A8G@&X1/l*ma=6SmBMGRGD&&D<:mQwCqLR^CAQmyV%yj98/IL>>?
DiP5%M %T%8?+lJCSAQ@I:FRPqEjDJYhm&lJnl/PiIHe\Me\WPWi?GA<1HRHbwFq<qKw<ey&KluJcFBbLeAQeLX
ak6pQ& S+#W#FQqLVYRSAn>%jmh=PC=+l/mB&A%l!:ATGGdTX$\<BM@X>!hJ*!pwVSXApy?YL@lubY!!IqDn855
5R*cbJ /%NetqVP9KIhHH4LlTewji@>K8uF%/=>T8hmY*ZA41M@Ctw=GmZtIk1ZJ/8C9Rh4yecBR4@e<=V6#QiX
-Am>eE 0007b07b8fe00110333 Page 496 of binaries1.zip
FyE$?T ^8He&?>p?Xa:@RDM9Ke6e9lBTamVTCmFPP5#<cc%GSB%y4JQdlTedG5<b#6FmRk5M*#lq=/&:uVheepF
phM>RF AlMlXPlqYu4H4JD^Kqq^+Z!ikYSjAXGH#<+EXcch%<1&+^KGlqLTtMyZb4/pNYF<?DpZ<nZZkZ%>GTSu
K6<=ZF 9u%>=h\uu1?$DWdE>9=A=&n5Y>TayqbyncSYCa!KckZTAGSBJ\u\&IWdBRRXN=yMkCu6EDC:?I#VEqZG
5n1CDK +jCt5pFKdd=/DG6Pa^ubQmut8pQp6pq&1ZpMe5WmQakH/M8ktpV/Wu#Wlc:yXH#V^:9WZAD<PMW#kQqL
d@@6Py >NN=@LcTyAaP$+CikF$h&uwQ4WP$u%1pnlQ\w%&\N^lqZ>FDuia1A=Ba@i4LZi6>yW%Y6qd6RRHhZjSn
BjYZJ1 XLKCWAt&6JpDMliATqD+1XyGJj5C#^4hnRHH<Kw1k$>cT9HJQu%qAEWWtEtAhW8XHa!j@G&STl^Mi+NZ
kbDwV% <KY%%XX@N:^!Dj%AQ?QLh%ddij#waFtIa=FKBGPpy8\:^nAeI4:=h>XXIR/^NFuw@PZ+64*BFbiw$kDj
%$54P< &Fqn?@PY59$=KLd\<EE<\nDwlAMCKd4AJ*&8bn@SBiB?9tc9$AY<\tAnn4cY%qy$eZ+aZeTVJ96FkB!6
9H@5j@ tAL\4ceG%SC:%nXw<IS=EtB>18KVltBHjh?9Xa!!\TQaQ/nuKH#*5C4PQwAh=qN/4RV:YYGmNJ=#MC!D
@L$i<& 6j4$8BjWd^\tplM<ANb/=@lDHMtH$bMHBGPD+eGp=Kw5qDtR&/#Ihcc:TyL\NEALHJV@t$P>DYpd%SBd
dtwtHw 94K@5!qZwRJ89$L>C#Ih9Sq+AXX89?#:<=GMLX&l@e=CcpXuX<Z&K+AZuLGTNiY6qe4VZaY!D/Hu#<uq
nypY:m &<8>L<qh!4h@N9FDaJDK>iG1hB8Nc@u*q/e:aBmVK%iiGF?XkIIPPny*t9V9JkM>Ha?:RYCjqhQ^wS4G
IA8+eC /8pB*6&*&hPEZ$N!9H>*n%@9Hny>L:X:SJI>1BLEpJ/%pZb!P4/Fn5p#/dTtt5P<NCS4k81#CLh8wj9E
c/dmN@ @9!=ymbIRMw\WB*W4A1C^#jX5CQleeT+J?n+ZVyY$jE@/FlL>i!1yiiI!blN:!XZBMGdG?m=FdK118na
+mdHh@ 8JG8/dpD1d$p9diX44HP:/?8bkHL<*T5y9e:LpZMG/JW<D\hZ/BnpncV6eP1k!wcwN:1Gp/wPP>TK1j:
LT?+u& J?M?HT?na?J>RjAZklhYCu?leuBFn&&k>8k:b6L>K1y@GhYjwQhQ&WVZ=\BVX*Qen%Qw?/4y9i%$VFA:
^VK%c8 j/tmI#*@QQXVkmmiZ>J:%ZV@c>S?p1=H+u&Ci\N>V\$hd/Z94#=H9lep%F?wQ=Q$jXjZWn<SZH<A*HT<
:T$k@e A?*Se*eT9Al6<^X1B^VXnXS@p6w:tw/%>N%9El^Jiu+6\X>N^^*wX:w@b#nBTi*hmHGn:*+u%bPpiybR
>\yDn^ @XWR$&J</H5P*W^\W@59WQ6k@udTh\!n<4hiS9ZS<RC1J*G&\p9H<eN1k86y#q!V<Gd%n1%B$ER#/e&c
1*hpj4 BDPTPDjZH:$$\ha1TAcHCQ*%lJS^lQAnV@MPQ!TAAMYIi@klacn@R@*+dd$5Eb\TJDXXw6^nJaK&lTQ1
KbEi:Z S?VleS8qdhSde/ppw#Qyl$!dju*I^u:15CR@?%CX1#@/M#Cd9&iy*%:d+5wN#Gnj\IDRwInQlKQ@Zca8
4^/T&a 9G??HhR#GHFVH&ACdHni\BcFG&Y+n:mpa\FWWwGD!W5mPIc&5KP\nb$<tR1G#=6&jBR4$R8$@AIS&MN@
D:ul^L ce?iSJBGqJT/RD=XLt\E=WSR:Y/YbwcuemS^T/8\KTc$hwGcGa$Ned@pWRuPKSldL\CiWLa\JTDSM+iW
EFH1QT j!c9kBCI+D1>wGwty=TIIp#KKVR=%d<PjceENHSqu5mT!pD#i=GLmnb!WWHnc&Gp/SE%8ESV5@#4GME>
^l!HuZ twVhYMdq^HIFMK=STS94DN&A\6IA&h:R^HJ#ulwENtAT!i#NHd@G8@VTV%MJbJ^$8!pHT%TVF=djYS6j
KKJX8p Eu+hPdub6XChZ@BmY@Ri\uE&=:N5@WHqIJN5ilw*e6$^6?5mYaIVuPES^IS4:1L\uWlnMK?EcZ>9ql+J
P6V!jL >i5tSMRK#<<6pX8y/EIJ^Fp<>I\bVHy@S:VMcbGy>PQSWnPjW&p19cq<cWeHqZ<!eCpT#WTl&:h:6$&u
F@ENmR $i$:at=:WRnyP:+R>+ThtJ:4FNZ&qhluhcyV?d%^=h+$h$E4AjI*+y+&I$?RQXmy9GSCQB:*6NyJTu%Q
%Q8>C= ^n=SpMJu9WLBpim?u=Vine!4q&Ki<Ce>QjJ!#CN8w6ID9+l=\A<daS@<Ve!DJ5?QjimX$ENRT8NL@qB/
6D%m6F X:I%!<m>:w4^>J?>!<kH+*>dSENjpJ#npPyn%@FL9j1H+*:JJ/Gy$jEqpXdH$%NiaBc<?NdI4VBCtpCq
Q:pnA8 b8Zk/WQ</=A>DSYt\wWIwS4cIBAB%@w5$jWp@#wc?V9Bhmc88GKtk\Rdm&q/iV@$DLaqqNl9R45#iK@@
=JGD55 bI$pc9jKIt?iEu:VdGph8ic$>8i5?Chk/+nhCcW/iB/wC?l&!TaD8JdEFul:E:a5itajSBm$hepL?!R<
jY!?Je yB$8+XJj8Wq&d8uh!ASdT$<+dPF6S!&^BbEN!ee$Q946\M8F8K!ZTW+MEIj&%5jhL$F*A@=VHy1n@T!?
=Ci%\$ yKTGLcHuC9L!qZS#cQ<j&9?H>9?l@Z>w@@@98j?@lFRXRjuhj?l9/G@wd?l9/G@wd?n9j>+jMmNDNM?1
It>*Xp HKPPPGb+EB\%9IIPIYCbRaLwA!n:X\<VDj4?m9hb%:w9*H^%5D@e@QCl$S:/G@wd?l9/G@wd?99d@WZI
Q8%%ta lTWZBGZJBXlVjV?bFk5VYAS\elan\IB=^hq6@X+i8@dV&ccnSEaJ++nX5dJ\tFeRdeDmIq5^dC9<IEum
1JH%mB w5:tGIl/b+JKq14Z&e4E$Cc^qk$\SYtwbQwAG^W$ayKXieImtI!E/BlZBE5T4\kP>4G%\#ypqjF*mRb=
tI>SAF ad8SM/!RM%wKK^Ly^HLbE6kkbXZ=WLy5pLLcW\6E!&G5k6ER?bI9mGS:Fk6=TbD&pEAY=n!#uYFGhMll
JLE>q^ /WM%RSLN9y^SIGD>M>eJn1P9\$nIDbAj*:PpJ6kciYt/XSLQyn::qyReBpLq59*CMKlmFna&n+N6HB9P
G?!RyS mdWiVM:E@k6Gb&^=^&bkdA9HluJ5DTetb4Dja?M*5ZSn<#P&paNlGX9H5Ttk&AZCTI\6*6kMnY*q^CAQ
ETBFaT %tq5A5h&d&\<^=bpdGdGNwN5RMlYd&LTB95=NpwVm#&a#apNHA\E&b1NVR#bQp/M%GCB^tbydPQGlt^5
YH><%+ demtlt^u!EcFdEpw=wP\EYRDRdaGFJM@&QG^Eb>aLMKMn9th@YNa\CZ6A:5CltyjtbXjJt8yL/61l@cY
WmCihl wd@@<iVC<iZJldX$>u4%YmaZJy<#dkN\#MeP?M%qRF6H*9QpNm#5%==@<!45Jap9L4wcc:#t1pM@ApS#
/il^^+ /66Q8Sbw/?buQ4kD??C4%:/&A>n1S/8K%+F<YHNEaTjR<NjjiQhN&MV:D*9#JtCpP$c<?Apk6L49L:5D
DZ\bbQ YLYin5CyE:hZjSG::bp9Lj<1N8=me8NZkhy?@PZ:9k1EheqZD:wZ!P#qQ/Z8^V/SHj:y?$BkjPuJt:<B
=T$SXb DJ5bNiyB$AJnj@Vll+CFL$p?@DDwplhQdZ$M&QH&Z!@@DqD@SWjPjk1w>jMH#@piMP/$eY*j\^d%?MpQ
ud!uY* @^C$$BYj9?@@AIQ6jtHqn:G#jY@ky!<Ad&@+@159AIYi<elSL\JbZ9P:p@<FG<LeL>j?K*cC1+:?l%>k
P^@Bm> I=*/qSt@BR/?<MCh9\W?QjCCy6?B&4nl8idjA*P*d49n><C>**48wFiB?%<=@eF@B^X$*Mhu9Rd$j8TV
bBhdjd Dc<BiV:d8Ph%pAiZjPD5N+Cl6&a??RcI4:hN8jbNnPCe@q@9Ajwieie^9JF<>wau1$HkHht\y\ad=8:h
5A\R1F N\@DL9QD8+5nki@?:hw4^tI4Y@N<#RHaN/=6*#+Bt<l%H@#FBP\KE/:9PBkdF>#kkFQ:#>6>KND=tHu9
VNbT^k Qk^d\qk/aqi+<<:mEhkaZ44^&euaB8?=?+V*au@=\Ibn/:FZjHZ14Hy5F>tbm+@D@9u&c+<<FSVE\K<Z
wZbXEt uawh=JDb$$@HDk9@GcD/L^@?t*uadC?/b?F<:H9yX=>bnE*tkLp9L<a?$>Q:*NuaZ#i9H4+G&>y@dQ%w
Wml?*m C:ciw*=+YC5&*^GZQ>CK4Ve>@MM=dLI*jicDBi^K:%n>clHp$i5uQ6YLLjjF=?>iD+y5^tu#Q+!>?bEq
Tw^m@W T!+GihY#+J8Z<Ka:>Dj$N@R*>Qi@:P?BRGIkB^*hI5P9ba%Be9ml\V9abB@YT8iGZluk@\PJKS9kZ#wN
8KBakl Hu#\RV4m#l:?u/kKPiC@Qi#%R9X98KS&!<dkpy1?T>jn*<@V9*$B@ahn>:D8aVnmlu?6=iah@ujQ^6iD
%uDp&n aZ$dkq8J^9p+ZDS?u:!wKkk&64!XRX^!bBAeQ8Zt1VZB4?q8!$V\SWGRwiMj/d1Xn1@SeS$hV/j:dSQN
>KKc6a ?>X*ml4nqRqBeQG^@XP4klTXh%Q=wZVM$@F\Pld5<\<8q!=yyhhtV>>$jCKaD%cR!neuu!i\c4NT*$EH
hpbn8N B<H%E+5Vc:m?/:Y?G:Y?t!c!1W=\<$S^N:qqIkLqHpd%#%c6!1:S5CX>yca1tE:Q9=*Kq>F^Al%u$@Fk
^ESSmw Pl/WSDepQm:Q:^=QQN#aI<au8N=*W9uX!STXJ$hK?ZI1u#bt#Nm1AD#6JLSL^<q$4AIuT5j4p45Amy1w
q$!P?4 kB6?8GaN$ZE+1<j#!RqW*9k?KV?B9t@DkV<@wJc@:%n>4tq$QI!P^>ES@VJh9@ME@e+V/ZlL<puANWL1
lY&Pn9 YW*ji<HBG>?SDGdT</hS?TF$QJ&Pq!j9S*?iL^%!@L8C+MJJ>$&T>l1%Q?hy8@P%*RZc*pJ6d^EhQ%k%
G#e#a: H?N<y4V*Qi1Hw<bXn/@ti5:W>%jwi!9%9XWVEThlF=&N$9H+\p?J6W/Pw5/CNiZ6?9!u>juQ$HEiQjFb
ida#w% Pp:=dBB<+&P*jPVGY%/<h@5%%*\W6Qduu>8#=+a>M?u5D*@E>Si98jtcj@#/QX@i<?e*>>!IaDyW@leE
j>:%4T ?KHnj!J@HNZ^Z%BLARIWA^RAAkAIAPNXdTYq$ATGd45HAD?#C\A!AAAAAAAAAAAAAACpkRAAAABndGqq
MABPKc duS#L*BueC>*cY+#Mm>JduN$aY^5bZI9bG>ne!>JduS!d%S9R*J=eHS9LuBpbqBLARIWA^RAAkAIAPSX
Ji8:tc dTWGmacAI5+FAGK6CkA:AAAAAAAAAAAAAACpkd/:B\BndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9
=Rl5$% bG>ne!>RS%BBbG%ydtq#hHJlhG>!e$h%cYSqLuBpbqBLARIWA^RAAkAIAPSXdTW*MdH@aaABANh:AkA$
uwYmeJ AAAAAAAAAAAAAACpkVtKDRBndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9bG>ne!>RS%BJduN$aY^5
A!aSG: S*XybGW8eGStWE5BAlRDFAACAAkA=qX6JbPy1etpdA<A<5WbADWAAAAAAAAAAAAAAKTB:AwQAGN5cYX8
E$CGJA hHM9eGh\L*hydnM!L$q8e*SldG^qem>pd&N#L%BHWFhydqX#bZJ#S*XybGW8eGStWE5BAlRDFAACAAkA
ANEGt4 =FX6JY4FqE9R/AEA/8WCACwAAAAAAAAAAAAAAKTB+*eiAGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^q
i\K:%Q em>pd&N#L%BHWDa\LplMWFBLARIWA^RAAkAIAPhXdTWDqnBV1W+AAIAIARA5AAAAAAAAAAAAAACpkj6k
-APS@B 001af5383d200110333 Page 497 of binaries1.zip
F<dtqT IABndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9bG>ne!>RS%BpcZN4Ltl5eFBLBRaAAAAABkAGAEAC
4%e=hN AAD84!AAAAB-
-AX1AT 0000c86188700110334 Page 1 of binaries2.zip
=RV@l% WE5DBBRAAkAIAAFZdTYF=\@Nl\RAAGaTAAA1AAAAdGqme!>\b*BnbG59h&q8M#I9WEhRe&S4XWp9WtX#
h?R%kX L&S5b&qnd&+8cYN9:ba>cCNZEMjHJ+WXuIZqIF\b#9E%eSMM4\ktSR+Z%^nDNc:hQXIcaqCRA/enaA6T
#VaX8R JBA\9E=FEyLmRNlFtkMJFlKIZ&$*MRSeZQAGVmcRGB\!?e?<ZZ%bMudm+^4Q/8*8#P!<?i%:V@8GcIL!
$*%aYq NDhZIyHj:lE>^uX8VqZ/4pD$Zw/wXA4?h!iID8?LH9\j9WZ$#!V5EwQ&CE*/E/uhw#FT$^@Xc8EmB&:c
5hSV<6 :Vc8atH>EZP+!CEtPh%R:y8iLEKjc9XE>a8ibQ=tjci=e>ujwe!@$/p@ddYm#$4>@p/q<m!L*$B+</u=
GpdW9w iCA?1t#$=Y<G91+@y+k$liV1u@wA56n#F#/lcF@<\h&c&64cG8ZuXFJ@X%J@X+d>G9nHFTNb$N@%>YmD
5!=tYP /kMh@FY9$j?Y:QX\??GI>pDiSJKuVi=#8mVHNPb&&u:NMb@>%G8hmQpew@L*A?/V\ZWiZ4mY9@p/d@@T
HNM>jh y5:Q*%I?u/hCwWCVp=M$QV%NM#M#ND5:T@Q#<:T\5EB4c&8$84yK!<9L6LT$SLXQtb+<aj1KDwq@>@Vn
QcRV&W +T5/jQtT99#?PVLI@Fw$l?cDmnXFBnaDt^Edl$e5:Ba*FuaL8?WR=tB*5D5wDudH&lX=&D*5HuaQk=e@
+GPk!d JHTG#n/p$5PmPVT^eWmQp\GDAaMBk\GDIwHBkMGA\aDBkEE^\YDAaMBk\GDAwPlkMGA\aDBkMGA\DB5+
$M8%dE DDmMeGBy/P5ymS\P#cN^iGY\YCT*TGVS1RYLDkPeFneYLBa5Pm#k5PC\+LBPdB!GCl\YDBaMFk\!hBae
ln1Imd Fk\YDF/@YD+MIjKE\/jDc=VIGhE=DDX!P#A=JHXI+MDppN9B/hCJe>IZl?uR*LAn9$N?l@\!SR:=uhnB
^E*QZ$ +MDktHZc\p^a#T=pM4$iDB:=QNk<PD#!/hRKB<dAk<MLB%=My^6BHm\iLB+RHkq%CaDFI>DnIR?DB+55
KQPqa4 C!<5tBMQFm@nwT!!GtRYuC+qBkPDkeHAaGA\/HICk\eDk+HB+MGkT\\MDAaGA+PB\aC8$YAHA+PB\eBi
68S1Pw >k4$ke+aka!H4JW=\n#Kj1J>!#PY*1F9cH%>uT1XCt%9d>Q8:m+hHB#R*6+iHS$h$jH^Mb&euNDy/Tth
PBW>j/ ub*S?jp=hT/a9t+$du&j8uYJN$hL>$Mcn=Rd?<9qe9Imquch?L+QiSa9$Xp+XVhZHw/Qy!yp<?FR@8RF
^ICNDP Jc?C9^G94FSZ^8iuS1NSHhj@$Eb#!b*4mj4LZi#kn>>QJVe@Mn/JE6tN89/BcItQ@=TN@L4^\!L^eT@?
@8pnWX 5k#Gn%k^A@qH?aQkkj?+JyP?<?9\S:LqJ<pX%WPWZPY?SStatVhR1$mhWpy4qc\id>Q44<hD9b*Y8W&y
Mj!#9= d#9%m/kG9jqFC!Yl%K6cdlbcLbT<m%Pjw*V>aX@L#$J>Z\9TCQ4%^:q9BKN$BMi5V&YZ9iTb@L%C:PA+
wpS1y* lZ48$eShQZhZ#>*Xe*j%*A*18Zmw^PKl8wK%%mq4nhQV6Tcy>n%jVIXauZE^FB#RXa%L&KT^RSi#DccW
=?Zey= SClMwKhT#Q!bZm!@4j%qWm1G%6XF?uRciQ4Y94Q@AqBLA\RWAAIACAABX&$qqRiLWZ5IAAA&jkAAK\AA
t%>*Kc AG^yauM9eGh\a&S4L*hydnM!L%BHWHNpc%XJL%Jqe!>ydYFubZM!NC=mdZD6ud&P+#aR^=p<Rey$&\b?
m!=bWZ kG5NyE?y&t<TC<EmV^Fk6$mqM5DX9811\/X^GeC9pD+FR*Iwc5TQ+bBL!jKinDqudj?ZP$NT@HFIY9u=
4JnbXm q\?@C9Q+wQ:>yQ/>jm@ED?1@*+pj+RQ:PZ=IIh?btcnRG?=qI6lT@XyS>Nq*+4HptuYhiJj#j/8>dt?9
*MBjTR l&pyIdy9y@@5668:Sd#6@bI:lQL$1\^BQd:A\*imX@4\MwDSX@*T<T:6@!cS5diZiITY8lyLIq+WQ4/N
X\?pCc ?q?/beX>J:idAFbJB/98pD%/bL$1EwiPLc*Z@j<t8=h4b8R5$h<FGhtLHRJSq:u<<kWML9q5ST$Z:>L?
6/V9<B d^u^i*66ti@DBTnjy?L/>#<=ZAcPNR^=&@W9Fpc<pI$t6/XIK6W9^C<VqlT@Qj8Y=u8S*w5$G#X<yKiP
#1!9dj q?HVQ=?Wbc9IBup<VJdNYaVy=4jSPQ1y<E+bDIdSZ!#X*^EbySe:==JjIh=F@h@kK8ZiZy=Z*N&HJS?y
NX@>S< FJ+icSZm\RDm/6t>+**$mNhLCZM>p$8Z4$LwVkhu:tX&eq9E4\4>&KE/bA\i<jV1@ijju>$E=8NjH\Zk
Yqi9Am 8=Fi^jZu//6u1bBBnPF8P@#LpKwjT>K#5DcuQKWj?V:IRbq?Ti66?dw?XZ<AW:*C/^mq?8$5@Gc9h>9t
Z*6kqY =QY?Y4^6@Titc14n:i&%Kj@%$Kd<QA*GiYwaqLh4#*9aSR^yc!B4FXYE?Y:ljyJS^MPuyZP6HBVCljy+
qhjmLZ l$@XQ\#hLj!J<4hl9CKLiA6I?\M%8T*mX+X?JLWD^w#cVjS!^QVu&&jleuM!j?j4dVKPDIjM+V6eFBVj
QSLa+Y #@Q=1cN<1u:P5?Sh\X*>Ca%+Y6<dYB>6biIl$ih:mj+^<pH#kI8h+MX1<dd%*?$&h1e8VNP&\Qi>9b^L
ubyiNN iuT:TG9K%iPW9PBuN%Iy^GjN<h&MA*qLXSF>8A:#HiAPFmLi<X*QaWwYdFQ/cQ%H>WV>/=H=e8XVQ8%Q
QqC*5P E4=VR@DKV?my>RFd5cwF#?BdbuJd^K<K9akDnPb:tS:u+*@<@dWwj/j%d1X>5uVI<NLn8$9lacE?Et\@
jBpS8= Z&puES<t::MW@mamiq#?PB/1dlD6FcZ/S>4QHc@*VDK+jL^6@di:wm<DQC9EK+9th*W4>8+!L#%G\w\*
Lu!V14 y5@EP\GS$X+d>H@m4EK<!iK:m?Y?i\:=Ly+P1l$:Fi@VkeN*4Gj#uVw@:/*Q+@#hAS%AQ@Ehqk6P4PZ^
FV//eZ qD=X@&q>9Q:%!A!h^FC?&y@W@4mdVnNu%D!>9@l9WZki$BR?Pdp6+qiFZp#A8KL#tWqpq?1>jH^cdPjq
F%41?V :%t>nliS&k8b=n9?SdeSH&umY&A&h!:kP>/Iy<1H<ZAeEtFW:NHwXKy98QQLHIjS4G@KWF8hy*%L9Qj!
#&P5LL *@FhaS*@+JqDBthqGAiq<GF:QkPSaju$?iiwQ$T<un:dZl9$*//mu\dLh=QC1=iiPX=n9m6a/#GEq:<:
u+ZDGW QV>@y^H9<h$m*kDh@P&D69EM*5n*RWNH#Xli<8i/w*1m@qQqy?4j<Q&1*VMw#CKi=:@\<uHamtYPpA!>
D:P<?i CHinyp$YSZpD?6Vp6wljFZyV6hjAwHXTjC@RL*%?ZwZnMh1FuPF:kHn%M=j9N=VCS@t84E<ku5%**FW+
1!Z84? jI@1K*b?W^!EwVl<Q=yQiiZV?SV@jW/<G@Rj>wCA:G=AC@5&j&X+muRpkk:6MkYPu&jnac^<GI4uK<<>
6<Ip:u 1a>jqSE>&X:d>N@^Zb9=ZenjQa9!ZZiaGPYJ@D%KibL9!c@Ilij4<Gu=pP>85cJV9<%GjKku99>PqB?>
!D@k^N Z6Vk4N&VBak9>h?%BTi:KhLn*ckb+5h%lnAbKiJZlV:B/!6K!eXd>FGD=jjWT+:Am>e65E<lp*#*EP?1
*jPXVQ KMZ*cZYh#@h#atE@^9hb?eGRCFc6L>4=BRncqG1?!^Qqa&u=DjSp9N9$H\bXq%Kq>Q!X+bD9!t#Qq?Q:
yqG>!\ +*N%?W*$SH66$*@*Y^:Kw@P^%jdjMhNVmQj&*/h9#mdY=/5S8cl?BeVdT?@ywK&hj84u=!FM+cQJTBG@
eMee\N K9VA/?+wqjH=#6e9#ZeI&b&SC?PNj4Nkl9nSmQN%$\E=n?@EiZmM?D/nu=WjDwuHDq@LjH*y#1<>>/JG
GC*&Md JQMMqSpPXt:I4hlbj48imHjL@tPtE*4t!nDt8?:\KAZ&y9e\#/p49+tid1>6?w<SD+i+Wuw=y8Ey5k@m
#n\+uP wA##HjSJ8B6>5AR*8:NN/pa*H6@hGjZW?juXpL%B^MPX!$e<S#@4=\d4yl$:i!I>TEa1?FYl%*@:1F4e
!$Ijn# R:aF$69%hZ!jn6mN^?$I95MR!8h:/m5G!jqdQ$?bE<t:#*hH?ZNP*!hT<6H1>EW:9=mQGw9+l@pn=CP#
/M#V*Q @Fd/XL!Q+n?lb/+Mi*^*mLV=4&eBH=uq6>IV:dXb@/inWcSiwtZ&I4/Hb?yw98M:&#D=:l/e::<:SMI&
uLm&ym JS@bC?ph+8E1=mPi:$>#^EiY1q#!upnYT9qXwai5ay/TW<q+1V:K>!!?RiPMe!ejHG#&@nd<t\NMY$W+
/R!*dI iT?/Z\*#jnmq=ij$@J*jGS<hGW&1G%uq4m%@cj&n?<>jGeb<qHMW$9EYqd?$@6H>6?9#uMj6P8*ZM^/D
&lHjC\ qLH<@W4j1JbjQy=Xiq@uX?Nuh>VGRh/mipC<8a1%eSBj/5<cmBiI:EG!X5G9C9*ae*E!#4t@DXijRn\V
MJ&*Dk *$^:V@iudcZ*hu=b=:GDQJj&wcn<yjYQ:4?*M5#/WpCR=#a5j&u>R@8@&9*49H9Y8XG*?j*u#ZES&b&$
B<bNqC ec64Td%t89//uDdtN?bK@btR*WKj*X%6mKTN*J>&6+*e@*?%:%QjX@@w@8@6>Xn?4*d#iT?Z=@\@&81G
6TwNQQ C<*VF<tu\KL/Ma8Z@J9iqQynph%IV??8:4ddd4966q9$=9Q$LikdbkVd$di:d?%>>L9Xbcd@A%BLA\RW
VG5u%1 AAIACAABX&$q!He?C6aFAAB&FRAAKkAAAG^yauM9eGh\a&S4L*hydnM!L%BHWHNpc%XJL%Jqe!>ydYFu
@\!TFc bZM$LtJ6eP&aVa9dSlnH^$6bcY5GYalCqtLa:KZFJ\9*EDCBWuL6h<kyb>FDSpqaJMnBklJTu+IQwiu8
N?eXjA IcCV\aeEjGk?\Ac$:MHb\*\H*?c\B@X=uluJ5t^=<%b//jnq6/NubnV?#*>i6L@<?9A:S8pljH/E#/5>
1CpW1^ ^n4AF96GB$\eW<h<hI4y#iJaA%@\^:6*:+B+Jce*!*MNjPEq?JJjIZZyDaq^@G:Qy*P?I@=96*QS@dn&
FpYkVG @/PW#ij6caYd@Zj^nh$WAciCdLw4*1nDX&yukwWKy*%e@jh!T*=nQLet9At9EQ?TP>ti6utXG<u68nV8
1MFluP qlBWkIX<b:\yjcX&Zw#l!^GWkw?4j!/*=I9^6G%>5iC/Q5=kMPAXTq\chP>D#cMn#hNWp%q^qh8MSePi
!FTWiX Fj%*a:a#*nVlQ1$h*Rc4Jdl$>SJ@uqKYWm4a*R?n*9u=?*w?i@Bk@#/Nb=\p>L5L5p/HXYm#N#NiaYdd
%WRJF5 Nua65$aC/&jH^<iW:@Xi@<bS*68*YIZdncZ:GXna#$69N8QNeY#E=q@eVyd$!S+JydlkWhTJkn?mKA1K
P/G/bW EYGtQnQ%SiW//HjPcut=j*?@liQ=Ab9qK&c8/:IKuThQ6D<N5!AIaw\uaaVVID5>QV$mZhQZm1P<@uDa
$tI@+6 L:uLX>GT^6%*l$QiGM<EdJA&@?J&&9PuLM6AN$1^<#eq%QPC>FRHn<CkkY&ERtJ>INWZauWh@Xk6S*:N
&%<!!+ :D/Nb^cGTjJM4nkin#6<^dw@4hEw\Wb5<KiC:u#d/@YPId@Z//ZmFel:=u1#ceth/>/T%mZ9%t#Yd+\:
Nl8?wN WWk?K4\8V5wqkMwB1S#n8y&t8JP@Hddd*FHLBHTLui8q*d/?nw9>Hj$yYBVamd+QE85n5d+\:i4+8YTt
w?wXiB HDN=iiG^Fw+u/DNKEqu!+QD\$GW4%9%yl&Ea^LmMl4T5:KWyGBV!^&tc9kJ=d@8@D\i<wN:!#YA8lLaN
DIVkta c%Z*Vh<j@5Rd+$/wu8j=$p^Z8XDcKJCu@Si9a#pk6hMah=/@9aQ#QAwT:e>ypt6@Tyj<tX9L%A45J@w?
-A>JHB 000c513a39000110334 Page 2 of binaries2.zip
t<\jt8 RK1Qic\9VL5/@l=pMLwVaVu%p/h>HM>EmBCZpaK6!RTM8YJ>j+jNdtV<PS1lQ$HG\y@yEel:=ut#u$8T
qaCMQ? qqt56Xww<p*Z=8Rd<@FeH=#jFHjWCP>5y18MemWYC$uV6=QJLlI:B1S&G8NPMl@P=%Q\b=^wj<cJ>1ee
DJdMAR h>Gj+I:WCdJ49Ran<j^Jicm@!LXB!*nM%uny*$4//A9RS=A@DR<tp\u=$^B*K9tB+=68dpjC?DMBw+Ki
6!cTMu w9AuLKVk#@R9*@8?Z%JcIV+^kBAKd1DK=dDCq8@B9G!KB@pTcca4/ku&Pmu#Fj4aVtQe8b/n5J94=$Z*
h\kmK/ !5Xla$!AEcW#%\c6M#IGLjLMHCaML@$:!cAFYw@Aq!E$Y@Dkljbq\d1itXAn&4h5!:KR$iQ$GApG:ZGW
k&ck9Z F*#mq5!Www%8pieCu1>Pm8Y\RnSY6#uPdKKi4nKKen\uq9pKB>lPa##Py$RdVpZ1Z8#a%=D8^Zme9\KD
%+%wLG P6H?jh#jbhYkXY+aNGFXZk/<P^*$^Re\P8*9l6tjn!b8lcYiMhN/\nEJq:$MH$&SQ#\?QcW<HJ\+!w5?
tX&Q!L YXE>D$Eu$DNTyJhiDtYXWFD8mlQ%hJYS!KM<X&Y?Tt!uPe:cSB5hmu1mR%HQF&QTE@!y#=@PG*&I1lMG
cHj8+n cm%9G+N1ky=iH<aVV/6l?E!8iAm?=C6CT8m<R45@Gu\$$8hVY=<bYN4V*N6nJP?b=>=hMR<DQDa9e1ZI
L8+#=& N*w=*PBNeVNh+Xil@$:KjJ$*^b&e$4Ik?QMq/XutM/Y*:nyLk^dZ%\$/<H$Z^lQ$lj%FX5ktl/^KPy18
I*=ple Q+H8amt9wbN#M:!/N>nqLd\yu8Z/:AY/4?Z49Ct??Z#$Wq/N%=:j4au8eb&SPVIXiV88enD\jQ%L+umh
WHJT\q hb$?MhY14=?XXw?Phh+W**L?@K#+S41Tp@H/Q*VM$*1hC#*m1?6JqbiD\X*=j<L@L$*1ntmk8CH?Pi::
Ik>\>1 B%BLA\RWAAIACAAHXY$q?@hj>A+JAAC&T\AALkAAAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\
>*?=cL L%Jqe!>DetXpcZS#MT=mdZD6&A>MFFecAQA*LGY\nw\=L!1CDKT&$dccqVWWW6#q%F^FIF:4JV*ewF8q
*LP%wM 6Il4i/YXXSCY\=Pc%NQKudyTyW&68W5$Fc94u!w:HK&XK^b#ZFJlwD9GQ?ml:LRah8uP#45*?\i+hK%9
y&S9RJ b^9VJnPdTXnk^@h+:@8?>&aZFhn#kQ@Tw*5&89>DALAI*RS/!beF@j^ZE\N*DAne<kWlBP4%eC<!Gt^X
*Va1ay CtN1H>6/lT#@MJF@6#*#*V@8m5S8cQ/dji9/Z#?Y>qJnaiu?qSHF%Z?\+NB:Be><8CZ6dGpBq<hGate%
a5mZeK @@ZEL9Nul#>KK<56Zde5J^Kd@IH:jG>F^du#%<^>qidKmPJPQ\bT@eAECA4Ek<m5X89@IlXb#jTHqFNy
#Xb$H? WhnjAI6mt&PXb!eYVI+QJ8eT*MRmZJ65t>e9wQw*V!uQ&Q#1=+YD=&^@5N@C5^QMDZqLu+^NY#yqeWbi
k1LcX# b6Yq&aiP=i#GK\%NapHl5qhjwQw6$>aXLZ9h*Dn:uMN1^:RV!+^q/>jEH>ZPNPabM?i5YQ@up>aViKqF
wAM<H+ ^GpjjjKhXVQ@5VSS6*T?KjQ6C:c*&TN+KW&<n&LHL/D8YyJRP#hy@XPN&\q!ABGDenltemAyw&klD@iK
tcwhZM meItS&E6WXmQepwI!1&Gn&I*ayXdPk4LSDFtk?K=YkX1qK+S/RFRXDykZ4tFXk&W+me@ck&<\PVWiQB:
TkXlqk <Hi59JAACTXKT@MMc$A9$*RVBTRCc!TpCGkwpRJ1GVqcXk6TcbaCLG4%PG94AR!W+p^!ZG$P5yPRFjHm
Y>kq5u w4\\RBmVp<DP5M4YFG8q\GZmCybqbc6l+<F$+B<#mT^L+PYnFWADJK\$K<<Xa$*XkB14SGBqC\PA^EnK
DhC1t% qqeQNCKn<BBiDVRiYqqe6BmEwNTmTXF1NRK\tEmJBkJKVpm\!ck&TG5KX8epBRIq6Ik5Dc%R\?6B6Rhb
H5\=KN 4DYm=Zmp!ACBcTXGbC6abC6kycRGw9JHeSqA<B1?tlC!peZ18k^QRpB:WF^D$QJ/&51RPNdAw4m$kPJY
u*B$L> I$5KNSw?BeZF/6kGj%\i&T1$Qa^cGtj#4=HnMn\nY#t8Y<M#!DIA!$/SWB&m8Bdbc6$cF66Ch4+EDFaW
+Iln81 %+QGVGj&B?L1<c#FA\^Ank64iV149$/P!&SnYX/Wc\qbD&#%Y*>euIMAAc?mPlBSB^A5#>Z^CR5DedE5
$!Ht#l kENRQnLRX5FD%9IyM>9p8G^KNqbeN=TQDI\XyVG!VF8d*/bkYalKRbDnY5k/Qytyc$P=\YP6EdKmdBqY
qQ%@#$ !ES^>W^hK:ICR&Q>9^D6C!n8XXR?BJ>N%:d!&YRLTp858IK<m#I%RuKCS4c5WEW/WnR5Xq\B=TW\GQmW
F/EGYQ FAcKhC*9<Smc<PwZRy/AXtBAKa*c6InGdSCauZl>A$KYqQ\Q@HLq!>?btANmW4D/bA&$$1G?S9DnNlw5
pm4!Yu m:c8H%m<8AaI*9@l5SLVn65TIw+4K4h\@AbkCu$Sl:YX\jELtS4S5<j@&\kQp%D=W^kb^XMGE<ZD*&V%
XVPD\R w#9%?yqhWQEq1Fc%1qY6cqY4Y6Y1X4Y1Xc%1Xc6c%cyY6c4>^Xk^Cm5y58id:VPwLaPtV^VaM+j6QX<8
1WaMhw @My<TwF6@9lp#:\6ja4mu9#+^JhLjVP#qMR>ikmN8T4*mJK+P=1*JTX9GYm8X&AQRIMZ?q!K%8mA\?GF
W%#LNL I1QY$e@bm9%G%/hWnWK:w4P^%KDMDlmhb:*K^9^>tdG%^/I546hw:G$5e!m$K:/1G=$4*/*H>@X6NFSu
FA<Zu! #eG!mh\*a?><uNqi>PdBKm+Q^\+hMLcPVbX9*>!>jY>JQ1<^<6\RY<#Hm6=MwbLKFNnK8Z8KH9@tiqh8
M?<Yp= =NcZ9TV#<\V>S8*#Ct#VZZtdeH54FhlPH@SBmja8@/u41JKcKty@X*TMC:=QtMG=4yl*ahu!W46*V%j*
48$?hZ pedkDqnT$?n/88DjNVl&#X5b:58F*PFQk@dij#qZX>FiLL98=lM\8:j:hDC8/Q5Z^*MFy:C5$Y#*dF#X
ZdLX$h dR@?9#/yl^6eah/NbbMw4Xi+9EldF+\:QKQN>iImLhbeQR9hZwh#:LV\mleP4wb8ZP5^nFqIj\>==/nX
%kBjG? %ChM5G$4Th%iZ^F^d5#Z#e1*yShj6Pq$Eh854P1Pdu%^8!$4e45\5/4DFqQCK:Fb8qph&>PL:>^9#D>&
c!4c#V EM81m:%IdI6Nt%BHl4e@5wFphVbBZYhHiXNub^n4/5=n#9@J?Em\I+9Jmj51i$6*lNawiL!$lX%jF:j!
Fb/Sj6 6VMbQick>dYj5Xh!V:$e@GqwyCQldje!h@Nldp:I*y&@6:L4>lc59PK=qc?e9MD6CNulnK<*ZZu1ET\:
1I6AKp YFn&&qE:N#4tG@a>q1T=L&Nb%?Jq>I/6m/uk#8i:M?<$t16*5Gy\eLWVHyCea+$S6VDuAF/9+=%=+!$/
4D:d@C $nXXPt?4=!5e&^?FHeK*:w=yc>j!9SqewJA<V%jYZ?WtHW@i\GDa94$FlaNF>9&ByQVi%n*V8:@>dP/<
6u6i%= $Iy@phk!uHTcC^@*^hZqL8N\5JC<A!e4Dy+6P#:kck4?\y/Cqu6h/ec\%nX6>ZPDX/aGC<p:<FGFw*G:
P8LJLl @hc<$Mu8:EnLeGNFX#k4ZN1hc?V:RwZp9j*$KWiQ?Zni+hCa9=9a+p:Tlw@:V?&%6aPjch5CliT>5/H?
PH6B!I aH*<d=QZlPb1?La?nn5X*9y4cdVm9C:w:uYMd=%DmTuD$?QD#yYAYA$Q^>84ViP6i/RF@j$8SVp=JB=E
?XA6+E qqN4eQR!QPkVmt9*6#5jbNu\6l9huR?!aum4mauhF:ITTYj41EVd6tJ@19Z*J%DW@J9=W:TtNpMaK!%P
*P<SFY #&@+I9StVWqYiuG8LcM+$IB8qm^yd:mZ&@BE9m&5*bTi*^n/cEB/w#4^P*R$$Rj6+B9Z&+i8=/KVR%M+
wWJ8=> K+:w1Ic>Id5=d6@W+p8&tIDqL:!P:A$$=9#c?>mPB6%w*PL&+!l8i6CYqPT*j*JnWpNG9w$JQ&b1%/k6
#4Qjup y!:11HlmG\nM%W6^5S%y*%JcLh>Gl:Qq<L%9^>++yCGHw<Lb/*>:<%uue1u</q?1S>#>44B4BMZGWW5G
KlGN*1 P*SkQjpc%P8H48&<d$:8lL:S^$=yPS^@l4&P>ud$^=#1H1yc%cyY6cyX4YyX1%4X1qc%Q:Z>H%BLA\RW
ey&WCX AAIACAAHXY$q6qwhQb\TAABPKREALkAAAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jqe!>D
GRKd+H etXpcZS#NC=mdZD6ud?8+:mTl#uAAmK\kXaLCFLt>P=4*H\9wMC\M:?CHHnJnHSkpBqjcS:mB95ahGCR
I?6C:/ GdiKqGT===!&8>jhX<itV>8!@6u/XMZm4+4$#N@@?^@@>RjB^@@A<&@\@Ci5@l&ij=B@m>9@>&>@pQ@<
+EIk1# h^Kj@$HTM#%p@EipVA9<k#h@@9puLHFLmQ>ICGtBj:kJZ11*ibDMtqp#c&d>w1!6P:+Nc:$>9#l4i/#=
tD*h@< ZqjNWdj54J8nWl!&dhmG6i^+1FTqiPQ&Xd69aCP<%w#Zl*n$j5M**hhm>iy\b6Z1!Fd/#FbH*=t1&dQ%
$DBP?6 &ylVh/qC=>hGu/9ta9b8y<?4#eG%*y#bdu9^/@b45XbBuBL44n:#=ulwHLI!#R\:ZFy&e5#W=&4F&eG*
\D5:l# @L#cHXuD?AE&Zl#:c8&X:>dI8ti4Lh4%aw=XA&a#^=Y??NZl+I&Bl1\&F?+c:Xi:QVj\bAd5c4+c1^I%
MSFM:1 5DbMRdMWdP5Ml^WD^wMYKhn^\9mKuT8&Apde8*YiNYjF+Glw&X?MhiYS6c14116aX*6a\EyZ4iE998?1
Q**DwT MWDD&1/4B<@hu8981:G&l<kKEdi1aQqSH%6jP/NXX$XYN6@+qj4Zdn&<YZ>&\BZ:iqD*bXnlwuXe/6jZ
Q?BQkb mK6nyhBjG:d@@*%$8&^YjY!lS?qcmC:4cu6b%>$Y49pWuXlZ&!P<HIEBX41&P>Y+91/QGK#cLb\K1?*^
C4&4Gj CMj4Y4eucMEhjEJ:Pm/SFdwL^%d5$q!cw&mEl@/EhSXHM:Nc:JX9RDhA^A$NQ=1nc<+NP@MYNyq1y>pY
E*K<AN V6$L:ytw9XFdA/h^%8!h*m?S%aBFh=8nY+FME456>Jj:T>X!jwnl>XKb%iuTXd86Y=$/%waN1A*Q&:C9
W\5F:m h5Au%mmbiP&bcWFKh46nX<Eu<QNma6WN1\Mq9\P6b%TD!lD6iwB&8?bwX?e*aa66iKjan8%=w=p!FdJ&
X8te$n XeQ>:4A:mPy!1j%Y6GitqIeQ>A#W+#LdK^kQ?MALX^59G8YF$cCBPWbp8Gk\&DcAP?>ATcpDCCY@&?mL
69&N*I $MDj<598bE+:hYau9%WN?LBB:ZRR=8CQm&RFGd9b6?y+c4hc6@#EiP8/qnE\4t9&u1<&J:DT#y5cSKG8
XeqZJY V8&chX1hIZcJje6dZ4N85#<%l\cTkScXlhi5&m!V6bpXIHSTT+i1bk^m4\MSnFwajZl9l9*yJHSTeV$S
1WQ#Wy !P5^Gm%LF*@d=%!X@*TyR=?#:YKuA86hjhPNI86&ql=>KK6!dT&#@16a&<Qd5Ky\jBjYXjB9+<Mm:N?F
m6WZTZ hSje&<Tt<FJt@T=4E$L*L1\m9FIW@m+4tQX6&m8a>dWM?^jYYnQGS:PGq?=j%eRZ#S4C!:K&CMm41%uD
RhJZ+w !&4ENp!ww%t^l+Z<ha9ImuFe6I#FSH&4>dnE#jW^=dH%1byT?YHZiMcCYP6bA^*NGm=aew6%l=w^kZq=
^S@wd% A$95h+XI@c>IJ:WZFND:cwZLPkX\IYLd^#MY^t1\p?q8#awab8y:ak$Cn$S48YE=aEVYh9D/kjZcbbqq
-AN8JK 000f50c615900110334 Page 3 of binaries2.zip
XAd45= 5Vc#=ntbFXpd9$PPmwqw%=c=cFe&5LIbc^X$=B96tpJ/K<VC:L1chVGVYhGm6h@FX8i$S5chV?*$I:6Y
/V8u%Y Sq>tFuW/N6+XV<6q5S/9RWyM4JYJX>:/hS^%*B*T$1*ZmZY>Qp&5PDWGb\t=iAld^$NZy@X/ec!Z1%qh
P%>VS^ jYX6LtQwPmd@hpQ#HyhVdIJV8>q6M!t5N<9RJDQY*bVYaG5>^%D%Ww4+!qyjd:/Jbup=pZlqNXNt*1b8
ByJKm! 6Zyb%uctjW%1dYLREm@Hcmc5D6^=DD4ad4>=dMiBpP%HHeqYh+6udceP^+Ddd5+V/^:XdP\@YDhqB>&\
m%K#^# N+4p+@TcNpd=5Et#LbwwJtwe/q5P/&=$+R*!yeqapdZD&=AKdh$pMw=Du6CNbhYl4eQJP4$%!TFTkdqb
Z>TK4$ SyF8bBZ#6NZQ>HF%\+y>1%:nBA4wR1N<mq:iJq?9<T:5+8p*4GabSd1B6StnWD%L$E*Cu4PcTX1bhEjc
%8$S1% <bBp9*S48t>aF^LNB%a#S1HwtwMXSEyj=/##Q9l!bS&EWVJy>Pw=c:8RP9QAPtVqI?6^a8%8YN64ZB=k
/Nlqda ptDeDdw=<5e>e>cqDB<p%uaCuNt%HX48nHX%dZkVDP+%RdkyR8%T#n8^%tIluZSmZW&5>XWDN+P6b/#t
XjcQ:! c1EBbleauCmCTS/iYN$Nc:PWwqXmNTQ4blcH^&:wl6X@\&wC#kMKdki9hYJhjeP/Y+4PVK^m/nTQw#Xn
6^iYZ^ G#:<ljZ!Dc5Ihhm*\c@k>HdK?Y=aF#MCqqnHkLTDK%TDGhybE:/!upE@^YL=AAM&DJe&ZFaw5EdYG:8&
Gkj=jW m^pBm/#%WB&FKPKtmV1:5Z\/ZP#IPlZepu4\qRCn:l6aHXkHH:+M4M5bt+?5:XAh*a%ch@D4dtR>#qm%
dRLZTH XqhY<N:KaGMF$!dbNLH/kdXbI184=wZ?htm6p^RaYhFJJ>at*mEI\kl>G+jh6d$8mZYwpKy=#iY1aReB
^AMi&C MYi>nK#a\Fj^JH!KPY5aYe%j<<J@QY8a%NNN/y=paJ&$^CWiQkpnA<eukTnC!G4T4Sn/H#?/>kJbb!Yu
PyK/+G t+yFt#Tmn\CV+BYy1^qad#TmC<hBI!=KN<%a=<M=X%b#\hT$GkwYJp#>c$kTI5IhE%p!I&Dnl/%Tb8CZ
Ih&%jQ Fy6tpctibdE+JN8AEl\\\cVwq^wC4ha/*yDw8wPa/IdEDt+Fl1eb@iJa*aR*D$&lH165ANKy%Ec9Qw?P
Hp:bQ? DF8ma@8%GJ44iVY!L5YJb:4yGyp&5!CXt86tNQqR1&ntN<ipm5X=8Gp8=jVuT4l4DYa=hRq^E=pm/4Wa
864hiB FwiW6&\wGt1Gc1QYI9y\LCY&YI8y$/m!a4GR&PIkM&\jSJQY!&E%%+HqbB^*X/+@%t58c9Jtay%Nn1nX
&Z=Th# ZCm?IG6>:ZC&/4G^$m@LPnVaH>F!Z>&Hj!TAdB=mdbjHK5KQD%Pbl:^k5#VY>1itdV%YYiELa^W9N@Z\
cbc+kY W>dWY9u^HXnNa#*1K:C&\d$DcYSXy?w>H9u*hJp%5&dY#JybM&6t#c!Q5wc*iYVY#JybM&6t#c!bNdNt
$YFd@@ %5!cYVN4b5&5tVY#b6dMtqp#c&dN4Jp%5&dY#JybM&6t#c!bNdNt%5!cYVN4b5&5tVY#b6dMtqp#c&dN
Gk@THD 4Jp%5&dY#JybM&6t#c!bNdNt%5!cYVN4b5&5tVY#b6dMtqp#c&dN4Jp%5&dY#JybM?99inn^S1#$nZ#a
M4\Y!Y 9l14Dc:5A!q=KD\S9TjTpVKEM9VCGp?$^j<X<M8\&yJd$@il/IHcCttFSqahyPphjT%YDaVB<cB$$N^1
aX1pB$ Hu\B4K:EHj1%:P4Kp9elkF%=$H*k^FMI\FRcX/4AZ<88XyT>N%1CD\M89LNCAc8t*wC>6VZF/:D1WHII
1IL\6Y S#&BTARNqBSDdLJiYHl4bjp/4GYIMD^eZ$PM\/?ut/\IJYIq6Q:/^eZ45Ya>uFp#c&bhQ16:B%acQElk
KMeD/w Bj$4TEJ9IAYkkbR9!iwpCCmuRCatX5>K&=9?SXtF=YDZphX!+!^nL<u1PRl>5C9+5KRK:MyN5FK?JC6p
+j#4Hn h5wPhtZTq#*+MLVb%&RNSitXTi*XM1qndFL*V+ReAR5%eLdyCYV+yuCqJhkM+EtEXXV:aqt5Ptm+#yDm
edM%k4 <I@W%EyZ>I=/Ac!FN^DKC&iwK!P4hGZ9T8*F$ql:++wT:Tw^\:HmWXc\y+d$H4!maAK:LeBqI4J1Ju1H
TS$/%h 8j?L/Camk?QS4wwTp*!aW4A4$aLIkm@R4n?9Ra4kli+FBRj&EVT?B1>+1bMQ>/@CYpw\ahtZqITiCqpa
B#NABl DREy^Tc5N=P?aH*=K1!?nMYNd*tAFViBZeQL6Ne!aCj5Sqa*Mu6CENEHw>&45Q=&LaFFQ/phpR\TqPAI
@JFW%V FaTcpyAT\wZ%SML4h<?ZXPBantWq^E\<6LT$%NmjWCwY^$weF4TlhRB4L:k1i\NSI$SYea@XGw<B5<jp
jjGbm6 btAFGbBajdp$Xk<+$MH%#IBlPLRc14ELTK!$9<MKAmKP=jVSLTK4Dwq%KB+9mdY*\G1<nIdBBM%J8E\c
>pLeBK YRP@b%ihSCLcFZ$a85\q5^aY9di$phWVFm?V>cK\Knyu&h>n^dEePB*/je9A@#Y/eYEZ/MMW:Ab=mTRR
%La!?q q8J\8MCeR$yDTW?h^H>*jDmP=ZktcSy<L8F8eeJJwGSyebmM1ap#<hJn:@&+RVA&lYp5^\b$*Tu1ji<S
#>l*=p C^j\hQAW#ku<C@F>?k554dQAu5bcVK^+dhG+Q<IKDlHNt\TPli><pJZAwS:TIkphFmGM?5JC<ww9bW>:
m:CKA^ Rn*lJi^*>KFyJ59YEwSJJR&$HF@CAqu^ndakHKWkumI$:u<J%kA5whiFE%LIbFjJtEhEISYNd$K9ZwGX
6/+LcR Bq<RbIXtpFl>TTSJh8YE+l9!C%uFd:Y4L!KpM%i:ByL5/l$hDM^?ET9YQu/4ZT&qeJWSCWIXWSmdaEEk
PWw#C< NlWTalQ5h+<NZC?dFj#VBA*bl5J8^RtPM/M$bHkchJ9VwwiGDQ6lZV!Q%ca1X/t6q<W\F+$Y6kB=QCR@
DIa5b! *@<TBVpTVqM#QVZaP?Q<EJ81wHj/uM<?PSbi$Iij4TZt4CkHeT/chqE+e6NHqZ5u*\a8$RM4NLkAS!8e
pGdCW\ :BM4TN?>X1$@>cI$+Cie?bY5eMFyLywCXtNbIh$>8=ckkYp9hPGXeet8QYM&XWGZylFVdnJnBWWdNN4X
+aQwJ! C\:J#=%GnJX4L$ZJ9TynCbAX9cR&XWGZ^\1=CS%>YMT=cBcNA!5^?Rq*YiNl/MN\y!k$>hGHm?Y^auwP
<$w/$$ kWVdtNLkZDRQ@RBEjp^?JLuQKwpZuwtiqpN5Wlmd1JDq<qlVFBttTR=#$i!DpTHXA1hMCYMVu9%d8/<j
PS?IVn aE&=Chk%4a4I/q*=+JiWW?ie/4uFkquj1GccYVQ4h%VPi:D/<w%<YH<S%lI9XhI!#5y\KACGQplCDw*n
?+MCL: Fk^#ua@%Q^#a+^!RQ6dIAmekMc%LI$DcTlWI!E^Q#P>wHA?#Fl=uKqCe<^DHKiI<Db!=A&1aD\M>H!eN
Z\BF/d *BwbmPlhEiAjWqw^5ByyVY?F9h6Qp*lVVE!^A1cVQW+^IZG8!jNb1eabKGXk^ptS/6tk+VHSMbnEjJdD
5JhT9\ Ym!Xk5A1XAECA6PG/\kRCBN4GeMSwn81&KKPluN+awX$p8Q6h*G8!XNbC+c%AGp$bnePXDDtAl!EP!Y1
1w#$Sb ^DGcPNDn9<eKZ1BAGPI^TPuq^Cwq&LY+W%b\R8NNti!1wq$lI%VQbmXTTKelA<MyS1yWej!J+G&%$a%V
j^*lIm 46N@:5NCRqIp\aHS>5Q\JB^Q$ahFd>WD8l4c6p^&bR^@5IX&JdI5jwEQe>wVwdH/:4B\E684LKi^HM^%
pnCCpG /GhJjk<=DR?eE=#SEnkYeRmeXWn<ca/VJVkFiaAX&:nEVJ4GhNJyy6Pe9&i#@lZBQla/:i\uPRynp=+y
ZT@h8$ j95njSbSjWFM>GFIJ#uXqJQ\>Qb/W=FMIhPTB*?uc&e@!aFQ/au/YXb5/WN:9Y=?il^i\kNbHdHFN/^Q
y65lu> 6&9Y@yp%5:+Cc@>#Q$=+:6S*V6W9alY*Z@N#N@my4FLVZ<H1XG?emENtcXdG@Sq&nwu$Z\llMRFn?F:m
/XZjEp G=#cEXjnlI>Q$nZaE<>%iF^e\&$ML!HEF^iEEGVa<%SYHDiVPCXDkykFmjmAlT\YVHG+DT/IEIhn1TlP
mL8VC? +m!QPM@DYCW@VHN\CK+*PC@EE&Lkc?PyJRy1k$P8B6b\$SPJZ$Ci!&wL$MKEEX9CS?M\9459bG*BKai5
pNdZ+k AZ>#WiJ@VkK8FC+Vb\NaR=!P$#9e^+pe58IEpL:EM$k<FbMHYW1eE!JDYnDm+R8i#NwdIR$N%Bbk%^=a
&N>1u\ Ld%dS\L4ABkVwQN:#TDVNZC6RjJwX<Ia&QYV!$^&>cYnW9V^c$5ZIm56KKVAcNh^AX<ku<8KTZ4$HDua
*AI19q %c1:R$>kHhqVW9aejJ+w8DbASNbwX^tu:bDQ9F@$+A!JFd+YDR%l!BhFAZiLwF%^AYpYyJkqiV=4CVea
!KR!<! b&yE8<4:DSc5I#u!8KI*QcNwS=#iMWDm\u^5Ep6q$WQD>uBme1jTa19$SWtyT@nBJL6mR%Dm8V/e:Pyy
We>Dh1 >B5CC@tIZRXaCCKL^>npat#C<BdDC8T\SH<<5<NCY+WDmDSk6mERea^N%EnyayVEVVmnDYMVJW>q^daZ
=#et+c I#$*aF^w8\@MA$RjlG\5>qBe\H5+q*te#8Eku>ZRJ!u*<XZc$qQHlRiqwH8V9laQ^Xte<DEKQ5dk\mtG
k8PShZ lT#Gu?4Dnq!4D^kX^TQ*=#d:ya@4KE889\Z8^*lQ$/@wjp1N@Fn@!8uW^!luH14Ni1%9^MnnSh:=tX^e
<6uF4B D$XuWL?iNie=tVY#b6dMtqp#c&dN4Jp%5&dY#JybM&6t#c!bNdNt%5!cYVN4b5&5tVY#b6dMtqp#c&dN
4E6Rl% 4Jp%5&dY#JybM&6t#c!bNdNt%5!cYVN4b5&5tVY#9m@4@\FRT\MEFAACAAkACFX6JdD=Y/u4G\AA*qAC
Z@5T^R AC+AAABndGqqduS#L&Sye&59h&q8M#I9WEhRbGq#c$F\eC>TbZM9R*JqbGq$e#k8at%\:J$@dN9Iq<hu
>8=hnK KX1!:N?QMyZkb$1$cI&Gkt+N*A&IIa:+NT5\m&pYh<Bl!&8**DJq&m&**HLdAL<tbe1$KXMhW1bN8YZK
titi*H 9jht?FipdCi&h&*9?!IW^j@KjQni9Hp#yJ@>>+j@eSn1Q%*G@k*t@@eXa<>k?wwht9Z@?m?HVa?btYCq
BDFWRm uWCHl+j5=PTEee:b%%>@#bIpae?iQYQjjjeh?@:::>pQQ@#Aj9#^S@d<?ZQ&>iEL>8LFC@dVV#?^u*@?
iKP/GK tj*!!!<5ad?!j?J$?C6:hwL#q#CHKZnJ98M9&e8ZL>u*@BZ:@86Z:H>^Tq/^H@:=m4%/BjNu4>tQML%?
H4SV6P @b1>iQ/G9jn=DZ9#=k*:/ai*:P*d6?!Z=?@a8*j9&IiQ:>m9Q:>uL&F/?@a>i\jVt*e\9Z@Q*5Q$?8WH
&K!lYk >8HDB@d^+\j&:9XH>9EDVB<@\u/@5h>??\*YjYIj*5L$@lQ::iMu>8uVJ@a:VJ>?l#qM:>@?D58@\#LM
\P4GkN ccLyL#L=yEiu9%ESEFMTMTWSW>J>aV1qpu^pVEW1PSZq+&Icu5ayti9DbSwL*\@pW9wC99lku#AZWt1e
:FJNpG +=KEBYH*t$5yejK=qLE9=&DREmjaLqNa:h5XeFSp>+L9@pLm>pmGQ5#kuLGCVdBhBDImZHjDXGklyD4L
yK*KHA jRNF^#nZI6a\u/dC#<ZyE:FF&lL?QR%Qu@JeyPIjC%<9jD@hS4nHuG58NJ=N/wl4/ce!TAY8$R5q\%#/
>RKH9N eT=Eup/qnQIw@uc8^Yuwm+B\*bH9#XPyScALytB!eyH:e%mP@R5^XhEV5EHL>AJMnuPqiA=jIu*tC!Zn
-A5m5u 0007ee8984d00110334 Page 4 of binaries2.zip
ZdJYPq CBjm*A<N$^VNYkbd:5hT=HD!!J\S@t%kC^k=4I^Te\!^8n8tWwS=EBbMe&u5hM/N*caewAl6+mYb\l1\
id=bqE 9l\eMX4qA4/pt%BFaIGy&AbIEF^9hLFhTJ=8ynIYY#:NF/q<wkVZRcy<=M*#W:E>!\ZQmhZhMaYCV9%F
aw*C>: \XTC=Wt5HbZ=CPJeRlA5:BciGw8ViIn$FY#ujl1b?nJX5uDRll*Ha$YcmHR8e1qnQC/%l<qWZW\FX5mp
WV:TS6 8+6:e:C+pmuET!d\NZ\kCAy!MNKFZ&:Bd\9aGM/4ZZ%@nk9lW4hPcw?ba/W:d@9bpENMHaTE/m/b^nJw
>hidWm MDYl1&>6D4T<h96H>>+9m?yM%VtnqDDhMhNyaXjG*J1RQnM5Zi^h8Z8tBYG/ZcaSM8Tm!ma5BKYMHn4V
VuA%GH FHF!XWGX<8JQdqdRQjYFVDtcI$=yLELM/IKF#9$\A5MX?iI5>KM#j!/KZa5EV\lPE4NLkVFq@MaLBw5I
Yq8>eu q@E<pd<E6:$565My+Z5E^=&lk%$8eKXJWJpQL9Bk5a#M%^DY+dW\nkL*Ad@FZnBaE5d4MJWct^pdBS<Z
nI$l#e @:+NjbuQMctAnW/Xdyi+EZMKYQFB\%KKM1IJbd4^8e^ndM9IBWdBpa:<HB845jBnYKGX9<q^b#^b:Me1
6!EjVk $p6:$<^#VFFF5Vp:ZF4tpt58MjGI4hw<qyERittcNSj<Q!/tbpelFGG<BqPB6kDFHPYBEylakKcnbV4Q
aKja<4 R//SKbS=Hyt\X$AV>c!MW1hli8a@kibH9k#$HF5kpX=At>QQSSVlHpKupXI<#J?i=kKbcyN&CuIJh<9$
j^H^!8 1hVBW&nA/ttwR&nPB5l$tj9AVX=E+B5\#+S*W54qBb!Pa@R<J+#ZaG1KGe4^XIiy<DF:AC$YbC1nHM1=
\T*KFR 5FNqG^:!/eIcK1\N$w56Z+Ayl!d*dwI5*F$m5\6#CwEJBLpE8:SM<&<Di:DI^XM6F+GYAXntp^!#meD$
aV?FWu NJc=#>FB^C4i=KL+lX!1Iy>I8lbVk!QW\8S=^Jbn@m?W5J#/KybkP/uaCp!?+//^H<aqW/H+%tV$Fq^4
F8Lm@+ WVAFZG1Kmd+wqZ\LY&L\^!1P>Ste5tR9aNMbZDLmYwRLe!p+D/\IPB1y=uEKpXw1m<yVSVKHyWDHFDJh
CBMlyG %@ecGqncAt6L5aB@ZMSL:m@B$AKV*^Mc/%Pw@WDGaqNyp:/\LV>V9MkXSLutaGb#5FY8Fea?eimLiTlq
R59wJT CCEQ5lMtTcVTbP1dm$tPQY/BH?BNE1B#AKdCdF8Y?amWe:#n+DhT$9C/MXLcY%beNHNGEqpkZ:59MQcZ
AA#1kk Cn!5KQK<yi>XJkL!!&l&=$y=FbcJ949LJkWZ8?$uSid=bY&bdktZiWDS&4Xw!&B:JBL#Au*Fn\PY@h*b
I1LV&? JY+@/KWp>#SW1H@<NuPDJGJKiqBM8cVlJI?KKVSwekyWHlZVhK6:A%ZTk&W16ha$:P5^MV%DK!Ypn+wy
BX%#^J I1ZipEjFFB&9ylEqn+tyRWwB$tNmcyFTjj1ItJbI6caipRjJNBK&L$*$ICZ*?\Cb^kY@XQm>TLYt<u6R
K9$SQK VEXXdZJ@H>I@&XCu>A##=#AXch=DhBhy$WcNVd>%WI$mEccduQ86^Ry@FB6X!*P:ZC+8+9cZKK//Ty9D
+w^9hn XP^b1qHHP=epy6%cFHMKQac+m%S4M&VQS5BTF$WctSw+4^!#Yd#aq8%btc66DleI1&YhN/+phMuRuqbZ
<*/i<k P\dNTF66L%KqqGljk*n8a!yKauJ?BXJLkujdNqP@NcJ9/9P1D!iXV$C<9AN\#HD:+mXVpii6&/4FNJXh
q>J<i\ V$#Q1P=qK9i$XZ1RF48AmaJy#&9DXKucy4Z9lWYXq?ctyL$QK1b1D%M@*T==Z4Qd5hNYNB:LXKWJMh*H
t+$?pk 6PVF4$bcqHKw^ht&&y%4mXXh:VJVZK#GFcWd5%N?yb*CQp8?dV^+&4JVJaR+c&#Cc%C/<k1t9Nel!#/t
eGLy6Q PJm?6ncim>Mk1EbA#LZE^cCtEaHEhquhK:m<DLyM<Su^CtP+kH6qWXFVMk#DSXV/Bm%c%!CtjW#V5#+4
AS?KuB BW<a>VH%XX/VCG&EJh1HXuDmb5le*T\y4/!<aY$14&?FdT6w5&hS!>a%KAi!l/tF68l%9GphEXHP>?E\
uqWKV\ nj48iNH$^:IVI=H8NXQSb*/<TEBE:TCK9N&DaByZL4aLNSihCDk@w^K<:$^F!^/L8BW@F8t&dmqYPRq>
w&F8*+ >S6SI5==?@GIANd\c:$cJ+Rh/StKG#LqZaiKly6C4StwhHi*$ph#Kb699=F%>1u1B%CmZFetp55h/5RB
<aPh5J jt?&u?I$**:d!nlH59YKPq\1d=jRJAjyB8k\uZiML%S=!T+Ki=k8K4N6NwRYQXtKiMjEk&wQ&Ym5%MRm
Ien<EF 9HIc^:1^q4i:>=1NcEqBiD>V&aqqbY<5^N56tZ%Mm*cy+GFW99HBlqe^=<%F?*Zb/yA%6=h+ay^?hjZ>
B9JESI VHunQmH>4R5\*GuZhC4P\6n!wpV*MI%:AtQiZ5WdCc6a:>1h4QhbZMHWJCTwy/*DqHj^%eGRD49&ZKcC
*Ge1kN >nBF/uue$%Jc:J\@:tcCFk%iP*n:tA4!9Q%M!#=V8h8!/YS@m$1&=N#QXQVF^cJNSb1iW>tw!<9<Mc:@
49CMeN ^/:H*ee$lL%#GpLibTy/1p/^$@uh4Qq1#Q%M#T=uq#NF/q8:RkBiYbp?B5i!XdXi\nR\+SSXyq&t%hAG
=yA#/Z :9jWy/4niuic1:6Mic<:dDQF$$6y4!l^KF6i^nuNk=@Yncb?yqJVbh4LqHi<LL+Yw!@8ZXmp1Z<yW>Gd
q6%GdD PY\#Bh9E%*KdClY=Le14#=6Mu%#BNMwy:>#QXP/teLpyMGt1#t?dBteNYkYZM+$:?ck8W:SN9EYW^eZ>
E:E+i@ QLh\iLNJ>eT+%9%M+jjpFB@%Mh*NDwSFlCPkSJ9ni\&Y9PZ4>nM6pn*%1P<&W/Al#SGB&V*AcqS&tJ4:
9bi$bI T8%qcu+Q9aY:l&t$$!X/y11I6B%<BAby/?%EwttT8$!Nu//<a+9ytX$4<SQ\K8558p!4B!N=&@a6W?wh
a5hp<S &5i$EiFm1SXDFdV1@E$Zci4TwPNR^S/ttLDuiIN$:XSa*\p#GX1Gwnl+$jK>XhJ\J&NltWwKpQa\nh6n
MTB>1T F/wkYQeqDXVRZTj:a1VtneD>:6w<u%5ZEh9YEm?b=jui8Fj8%1jZ/l:/K#J6DS&L=d/^KcI94!1cth1T
4SLkpX /VLjaS48My&ZMByZKqG1B6QVNqP>!=RV%G5\*V9eKP=><pp$\8Yw!ntk1T@1^FQcCchEiZ=bP+S!S%!q
JNklk@ u6RyD9QuLA1te4h>GqGX?nqM??D6ab4Y%Pjq&paq&?*Cpc%K6l:1XK&c%/hQ/#c$4ML\>kAy/n8>H6Nq
&aQSkD J##c!^Sju%&p/ZRXIM5/u>F6>1AlG!RtccC4:e8TX%!:ZqE#nT144lMpiFZKPq\Y>@aQIJ5ZTQN9h/LM
t*t:Z8 yhtA^GX4JG@qY=EiumyeLw$b<!Y1$hl5%J==M:Y:KP<p8*Fy:\lS64J1y8S>?=n!1!yVZudG:A:tLw+5
@KMLGh P%acZ6DRPQP=dNYdVcZ%n1LCc!?LQVMyQ\%q!=td&/BM<P@$^=H**b>H/p9dl*L9IP&TcdYQ&A&y!wQp
PFN5iK 946G%EBpBb1ZV<CYV>hXVH*baY1:@!md6C@j&?$c6&:Z8L!iy+^MX5FWklH?>aKY6ZB<G$V=cNKCe>8F
!EeSn< WmtwVqHY*Dmw5DyatGiS\?/Fq8cJ=Fb*DG/n9%@Sb6y^9tHH*NVNM?ZmNq<CRX%5X#Dh</cG\J1YV1Y+
QhXn^% ni1KtQ/lVMPib+Z>8amqEQ#Yu85pyu<w$=cl*qY8nbn?id:*4mLI8d^FynE^@a!+>\/jwSjy:d%$aTGJ
ZcS8<C /ZZ#THhdWLe=#pRT$:%MycdulB<b$^wy6Fuw%u<MVE9HK&QK4n$Ty1aDSR4m?ZmaCpu9mu15PReTMTWS
1S\hMG W^I^JSFVEnEqymSmTmKtyD?M/VZ@kA9?ybiy@XeeM8&icL4*CyehM9&e*>H>SZhhj8aC$@9%h&+$mWRm
t&kF<% pWkpEwqEIyFIJBKJSCKSTCRTmWRmpWkpEwqEIyFIJBKJSCKSTCRTmWRmpWkpEwqEIyFIJBKJSCKSTCRT
HZS:&m mWRmpWkpEwqEIyFIJBKJSCKSTCRTmWRmpWkpEwqEIyFIJBKJSCKSTCRTmWRmpWkpEwqEIyFIJBKJSCKS
Y#5*\1 TCRTmWRmpWkpE8u&qc&yDB/d#khHXAmQ#qAhSaX\j<XktnG>Hty%\AaJ#QX\4V*H<ZCh^^^9wM<hhyCX
lF4m8> P&iDSP9BSG9ajV#GXb=H^ZnjtGcPaV4!\Kqcy5qA1eEG9nPXHR:%\WcQJmZVI@C:1+G4%&/tZI?a*p?t
u!=b<$ a<<\SYDKMpXKukjjD\/<Cc^Jny%b5jNtABa:tk%W=w!>MVG>u$\*A%$^%V6M>ew:AA@5nDh&b<<Du/!X
6Y4eJR w+?QhVd#B5V$jnIhdHVyi+@Gc=bAlXu=*9GJQlu1+Tw:XAXV##*T*4FPB9wk\WQaTiGZTjiH1VhG5MtS
VPw4\Y Vp!M=B/\R%*FTIuLuBWAbKM1wM1aHkQkWZa?aAPql$j+TdyZVJ*M54JCj>9*9R/T%\M16Q9PhGbaqj!8
?WaecQ aAwc4KnRTCRTmWRmpWkp$9*TEFMLE&ccMeP%de5WtV?eDhj/^GFFhwJK/$EwG&JTaVle:YYcDFVt#4AH
IulS8k b$nF>TC$Pl/6hPc5n9e!^W?q&SyE^jWkhL!cnQX5qLp6ywQleJ\$tG4Nl5Mlw?J/EHI#NhDnGe!dVMj4
S?BebL >atViRib5y*qdna/%?enK1+HWb$P6B+pn6LnXZLW>4*D>e^n+!M\X+!S5kN&eC5^Ely:+mb&FM\SW:a#
bP++Z? hnZAwVJqyGc/l<1k4KkI5nF##4X!^9AQX5GSSK>j5#G+*:F49:Ta1n5cW+aDb>##alRM+LNMua$?QG+^
HQ^eSV 4aK!k8qpqCZ8N:ABl$!bI$u>A1?4%\\SDy1?q#E$C6QW8i&!a=p?BLP*w&BKyt5ZI4Cp^dRK!k1t\^Na
:8VZk> #wnyjSS#V%^$yYaWVMZWGR:hab6yGbRXAS65H#y4auw9tS+!4CdNKBnqulRDah^EH$:ANuHA&*CpV$c/
@5ypMZ C51KkG%!CNY\QuEX@QQMpcS:\%Rj8ltP/&eDNZNe#a+aLCeDNkcu:D44I**pPe/1D51KkA&mw5FK8<+M
PiM6## @wEeq+4!HnG%WM9c?5yGd!6k5::*L8y=$5*cMlZWXdLL6D6+ylG\RVW<\Z@a?KHpM?tQ8&Nu4BmE1cDS
R6lVi^ jVA4Hq*BP>lqD6R\=RM1PNKLqaPqtX+=:MlS>95Zy^9G#NSa=SlR&=C^X&jqL%R8<%l^Wb^B:ZiREdyL
Kud+VY Y><P$*c\6DjYG/e8XaXS\8FS>aCKh%Aeaa6*iK=Q11L?R4qiymGi4Mb1>#L%S91<^hVDXcSLtI+LI@C<
Y@Pc9e nZM<ei6TuYGw9lyC$@#9+:>4>w$?QG\!lddh:IbM%!b\>M/4b!4/tZ4%y&G1d*Id@SYat5hYdKF1NVq8
C8yq:C &Cta<PwaddX<REWjHDYa/5Rd*=By?eSLQ%Nw<E?I/be\Na?6YPiZHYVbaG$jZeGNS<=wwuV=kIyP%8hj
dnI!\M ub9&8b5qDF9nCXy4qnk*bh4$9hZXMVFujZ:lF8Cm=?cZpP?>uKq>dMWGKRCSHinm$SW5calEqLJNe>ny
!&uX?q CA#uTA<>=1+HWK:bmMHu:Bm@j/FY^9hP5myGPp1TR&nuX?Gdii^6NkQV%iA5&Lq=TAbnJGyFZMK$@hlK
\L#V?B 1*YtuASm#qpnR4=%tSly$N<5NA<Tn*88i=Njkpq=t#yR/<#PeDFd1&!h\chbucD9V*A:j5MJ%/y%8Ym&
j8N</D t?Q^mG^>#*4em5hY?q9eaKCPy??TcVb&cy8#1jQ/y+F5j?a6MtZFYjWl#M@lynE#=VDtk1>H4<:Yi5k\
-A*Aq? 0004948b62300110334 Page 5 of binaries2.zip
PPbNca K+kdMIMQ$\a<$ky&eecajXnnYu5<H4Ft>B#5u*5QR%#95bGiaFnAXAJjD=n!&EuYbk4d5>GpbP1^%VhD
EFZ19& qut\HYcb*a:HE>Q:\BTh$ImbpawAA\qC^IA#4<X$cL6PK/b4QYauM<NW&?*tiGJ/Z=l/%u$YVP&KD6Ql
N^eK/= $GFNy6q+\B+$W/WiPXPQdYC&YRGQp@E*FhPSQwa%LwPb$kMZ$G%\!bn#JF9XVI9n%^Cn4^+I$$j:?k9D
%@Da9: hM^W=nyDdLG=dAlaK1c8/#m8C&5!^^t\qS+PeGpN<bCZMHjAN6lBk$biHG?PaB6m?te#*YADPJ6==5H#
ql%TlV tVe4t!4RqwG%Ky6M5JW!<eBZJau!JqpGhTt$en^9k@$J/\#dM9b+e<R>SF4qXY*i#Z+eDw48\1Ln^udb
L!NYZ\ cLh+PhX8D<+NYlcnyD!=hw@Nd$kG#qHh=\\j=TDN=unNt:SquM@NYK!e/u@yYh>::>PDQW\^YbeW1:Hn
h#j+q: ^udbFC>kGK=*iuB8e8tVRZu!^B$Wa#K#Wa6yPWm#PX:#m^&R=$$?9/P8EX>5$LajJFP9>L>F^+*651ta
tN1!:/ :9Vk*PnTB/9m=MiV$cy+=hY/!dRcyNpe4$t/9Iwy?n?cVI>4y1dn^udbXE\:QVk*aF4&B?tBYw*dVHE+
S5iIKi LXA5B&p&^&8TLm*aw9@DnIe5tV1%:#WhN:dLJtGJ:Vjb:eG=GXN:66XIc!h4?X=*mPNy!$Gc?NP1<b4E
@ZGiy6 :c1C^j+QM^:TnpW&uTD&@ehq^+*y5nqmS$Y9nXt5?%B8\lRe4nudBPJId#&dRS!$E!QbRb4M^p@FiE$c
:<GMFX 9HJX\Vd/Q*ccMi&PG>a#y8:tMXJZ4j1$&yqiG9p=+Z*XQtDqRIJ1c/9n^46qyw#6hwXcd5TWSCKSTKVQ
k#u=wX W$L6ppiuR@wDI+>Q&AIt*X:45Bk9dj/e!*Dh@HM9>S>*\e+V&>a^d<1\GeGd>M@kGaj&FSnapyul?PD@
EPbAkT d??Mhl8FkTn16apJRTJ>=TpTE8Ib<iA9+Q>@cYjGa\N6&6$$dEXY>&ndBNdF+P5aa&i8L?bW!CFwJ\<4
9yu^4N *IuJ!cE!$V1De:\ak/Yl:t5cq*Q^@Z1=q<*mLtebp^A*5Z/6/jjtb>JKFbRX^?AW4tQ*m$G?S<JjQk*u
<:Xm@h $:&auB\1E/$#KMh\t5KVduYnY&yJp^?@Vj!%XFp?lXTXi9<Kt5dqZKKtidtZ%iI88y<n+Q6y4iu*=tiT
XR+!^h ynFIauS6JZ<8l?DbA%:J+E=MVk/4$P>@ejK8i6LQl8yH&Yw6?cDyWtZ=FFJXP4Tt<9%qGb!S=X\YVeYD
R\@X1t Im@8R5q<J+Z19HjNY6Q9#e>5Nc&8\aT5cV4PubmeSXP^#8CWJ%e@&eF1yRSmLjtk/XJq=ST$Kl%cW!1c
F5yBKA htcnMF*PJjyT!HI9/<Xh9C>e+LtR5Rml$Jtbb?buNt%95IE?Kdu6#byKHM+Tp:MPqauYGj+T1DKM#*i\
8yALbE YFPyJT6NYd+$\=k%%cy$@LcZneLmem:Sq$L8G4#5!*y^q@w1e!E*Dt8J5#E/J@P6?btp1jTS?wbNJEPq
H5G*j@ jcTc&%+P4V<:pqFne6/F!pV4nM9b*PTEh6BWcptw18t6GFN%>&tG5diVYPSyXZwBVj<tYhl*!cY<t6eY
G!I^6Y 9@TS1p@G/@@JbDlqJdXphK+6:GZX>t1X4i&Jc*/5TkjZqLq@G%!jN1i1=y@ThB:L@C##e=41t%1nuLPt
8litNd h#m&y8Chy1M%HDaDVREAAAD\<LCLd*:\G*8ZA@hGR8%>@WLjZ9^<9K&9j#I!:<mBKbYyc@MT>m?ldc=h
tiZ*8Q eayYFCMHh5&>@E6PFZP^^>1!m%ZGGK$!ilt?Cj\TQT>pB&uKG<p*R@cJ<VY@+=?^j!DQPH1yqly1$WEH
5M^=#+ +G&>&ul\VVu%pyd*S*8P^dAny8<u1ZQb#PPk$BMcL^<:<MTphb=j9Gp=\p?hK8b=q*DLbJYlXln#bHkP
iZ%bGn >ebYGaHn4ph=S=pY@N<c8<&uMVwJT?PRR@yyQl5#8b6udMlnYLhchJ#bt/NJX<5HL>ljMeaHtLp%%i#>
i\:$$$ 4QaeGp/5Y*TK%t:MQA/K5$N4ubqt+<KNC5EWhIY>c5yPFZTbdwhBybXXlw\:%l#AP%9K6B!+$C&Q&uMy
Rcc/hF 9kXu%=1Ybl#>LYuKlluj$uSq$XHT6q+6HZ!kZE%$kTXNK?Na$&#QwYH@55XuanbtH5ipM@W<V9^dC<*b
t^A8qt :4LTqD+WbXHdHVVNXlq^FRFZ&bJKP<:QSy8E=JwkkjybW/PBdWuVS@NWVXh&D4!6l?PZQmepVb$*E&t/
$a$I8u 6ijRLW/%NjM+/ClbdM4$<4myK/*bcB1+\L6>NBY4DLHC/E^dGYy$uT>E$C<$6h+9y@iayu^ZaW8n?m6N
e1n$EC ==Ytp?qNT=y8:Vq$K&81bl:lbVT>#9XG$/5bb%98y1qcabS&H5$%WL9Ztw+KPXl&XDmJSecJt:1*8VBD
$R>+p& wL?mH64E#akN+YFNZhM+66Y\*ckYG/$a4YSNC#11N8^!il%ySW<5m#&HGHdwFmi&K#PQe*>MXX9De&y<
e8:c9: J>P4jDQi&lA%FceK:9XY#>jJdJWlXlkV#@5+S/Xa$A&eQ#k*W#n1CwqF^wZ*W&?yaGQD\Vl4/Zb@ew+@
Hu8ZLR bw@&pVy8A!mVqWZH4$ZV#6BSB&>TH/ttZqlBtpb:DnZ5TF8e?Jhb#D#5D5*ZQ*tT5Y\dYhIby+iFwYG4
+^MQWa C9:E>8JW$a@=MiBbVcNXBq6lBH&ewN#T<pFne%YLnGmled$GiV6QE44jV=^WDDMi!9NC4REh4E$YHZVe
*9FS&J G%5e/hZ!AmP5YS<%Lhn<1QB#6PhR\+/$STjd$XNNN9Mat+N?VjqG>!5ZZWHjFRh*+8%8D&FjYYW<+CHX
pTiTk: tIj#DH@P:yVcZt+EnHu=tdYl<tZ:5i^c<cZa#\u4K/8M1ju:1nM<u?ih:PKP8ECuiP$AAAAAAAAAAAAA
BP4Mum AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+H@mN%BL
@#FWiI A\RWAAIACAAIXY$qDRZHcQMMAAB?EAAALkAAAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jq
LR+IG? e!>VcYSqatF!MT=mdZAqX*&5&>b%Q:!?<46pl4+4SwK#\a89tC8Wa64FKXDMC+Lpm1MYWq$TmmWhNMPR
dpD#+Z yS>DEGBa5k/d&&\#yjFX$55jyVm>8H>5kJ/16$ucAk^DB\#hMD#Qhh\Wlb%5!*@d?y:n\jpwMD6akC=%
hR^RVt 4S$=jPCDyEQ!uu9P:?QRjj^QPN\=H5HV^9MMuqRD$QB9jTmMt*h>jBL+?F\j1>WKGMWQPcWDcwGDAhGX
G%RcPM LqBRJAS&#/AH^AciAm?H+K8y+PB4Pq/nWXwRWmX+e/aI+!B!AG=QFJnCXAAi%YTijwcXRit+ikbNH!nh
CK/CMy E^uRhJ$bMBKA5H5%EHmhX#N^PR&t>ll$AIq^u^dA98Jm:wF%J>eeqP9#CPM5:jqmRH\P^S:tc!y/qDA!
&!WKVc IbVQwRJEqeX^#MZIFb$6t@mkDE+Jq!neSwEdk%!RQ/KRtu=&h\N*JcF:+#dtp^Kl#V\Ct6^Md+N6&Vqw
h5ldI9 Sy:njl<>5uw+a<<@h/Z@hKYE<aj9Z9FjPiP:9h/49:t?@%V@:D&u9u:t#Le*u#mP#\>?@^NuCaMhncqm
<<4QAi 4\MBHN#:KK\41p!da:^<:eiQun^@<ME4G*>/?6WPtK*#N?+>iiHt#Y><?5yS9F<hij&DS$=i$m>iPj/q
X:VkB+ Z@48CPm=<#j?/iSq:e>?hM@9Hn*nkhka*VmF*!<<?aY9Hu8Yk@:Ac>hiPQuDSj>#>:#$^Q?&RY%ikZhP
Pt8H>1 Z9/@j*9ywc<iQR<a@=HaQ@ZDu?>@:X599ZK6A&L#>yH>W/<>iQq4*@4Tc\>TIE@ijt#@5/<>?I$Z@@^@
h!<tek j95j5L?d6#dVQ*#=?8*Qj9Q/H#!ekZd5w$eERP86tyZ<&nd&/:Ed:\IlYk4M@wRakLH^:4w:=hiV&lj@
k@*6^e 5nBBQZpA@A:E1G?\DQRVYdFGamL#6$I4BQGRkw#\AH>VbEC\Z&8<IDaDj<jYjP^Z!twIGF?RTY?Gn<pS
96C5Du n\\KnZT&dRnB%D:G>Nk9hdRI/?XLut5CX^nJGFGmc=BS$KX$!FAVBAV*BTkMy$+e8#+R:LGmC64/Ec9L
t@aNh& NP\9^/!yD<4#K#DG>i/\k\Tt5hNE/Etcm^TjC!wSFYcCJtlYBw$qBp&cbRT1n6XS$AV^N&uF>ZA@P9LF
m!pK>u A:PuN=yI^6BWu5tBK8/+FT%A@P64ek4DG>4NiF$=\hNWcaJ@ytZmQtSGQA/eph=++MeW&kKbk:j:5qGn
VNN4=m Zc#jEHKqW1#CF:inC5LNMkuYl%W/#+t$KYH<8hSuINMt9blWyRdY#lSeBaTKPal!DP$wSFcBEKPLTR5@
nhmW?j !c#kHHt<VRj+EAqB\$u^GEBu8h^XKWSSGnMlTKPWAnW\q/!h*tq94b%$eP8Bp@5>jF:^ek*w>kVM5EZE
*AJ:T> aMDk9tkSCk&<LZ8P/@Z1S^p6qTR$:C$a4C6<i4eVlkm5!JhETF+e4XDct+P>JXQBINPi&P%EFRI68>DZ
YyFc4q q*9HDY^&Dw%EKl$w=/?GueTm+E$D1SS$6iMpA#aB=%NLbD<\?hCe#/e/:DX=\Nd=j4jWIp\BY?=lMeB1
E<J&>^ u=u#S1&C8J#LFHeE9/h=chcEilCu8N%*m4?QVciM>h>=dm&SIaTcWq+I%ZykycC=yc@E%XKNRQ^+CGWw
H1m9cj DeJ>VaZMB&e!6EFyLuGZXV1qYB>PFCj#ARya!HJ\*qkITqptaKhcey9kEpy4RIb$4qVIJXRY+RlEqai$
e=L*Qk 1yi\%Ika*A=^\Xa!SH$#pw=JhJ*u4yu&IkWhSF!ctnbl#LG:YJpmy\JwV>Sy&15IcEk9b*Iw8m^!dNSj
^JJ!6@ #<<%AlaKbb4&6kR+P!Yy6J?4GVQiq5IA%R!B=*Zp=I#uk\pWa%Smal98FQi$4ujpR\?1!CnBFnwmha5Z
jh?MT@ Rn#H<&X9C11F@bLA>C?5MecYXRHeG&F>R>b\i49+E:lLG\R<nTWZNGt+WKp<K:P/MM&ELhcNE=N<4Sc+
WQ/X<Z jktTpkhd#yeLDu?4J\c9kYKw+98k4GeSeeAT5\dVSlFRh1$lB$QpIjyLF%QV45LcWBLKwjQ=YTG5c^p!
VCSA\/ &IiPm>IFMNB?T=VmMm^VDudL>LY:9wjM<#Ab=K?yCQ@X%&*eHQRtbak#Iuwd?<TqweHST?AZEN9%thKn
QDQ&<S *6yLIFKmF&:tVLHKwPIbAJYiwPicyJwwt1I?!AuZ+eqBtEKFP^JqV=hyeELRe1KW/tJTE:TRb=1wiJ\d
!ThV%F FR9#C!C@q>pm\Z/n<mBpJQuuCTqByW5IB=iPNQE\VjQ&lN5&T1NCmj1b1tmm%HR%bD+dy?wM/uky=Lw6
S%w%EG %u/1q#?pVVKu/T#NIA^1k9=EWccFpTqR!aCT#mEH6T^B:KQ?t6\@<u*KVRlFF+tmwdS6ZXWphZ1Dm6wF
mp&$cc aXG#Q8BRB%95w5@yKEh*VX\Kmi6S:1Kjc@T9eNE5bc!M?SKR*MC=RbnV*jYw\WdRQN*#!5SHY9G%Fp9/
m4k\u! KhSHV1dI$^SMqMJj>*#\=p^+Fkww!*SuDS\!*T1n/6YEEGyE8/dN8PIiDlKp//Ci1>/$^b1+D*>RTSW*
/+ntKA KhP=5NinDMC!nD+\udk>GELb4EWn<L8WGXlpE#E#wNJDSc/F8=w85d/p$T:4I1TEi6DG!ReS4JBS+d#k
yYc%%d ^Zlh4/HEYLhE%BapIN4KLEcIVG+daVVF>e\bb1>bLZhTCtLRctAWTKY%yI<L#IP%h%GYRjct<^wPGe\F
TWNFV< a^FdBP\KcdjSD>pw^QEp#*4VSWPkhRqJ=p9EQc9RZl6L61ZtG4mcJue:<TlEVS/VbaPlZS4GRqIRTe$G
-A%VXK 00027f68c7600110334 Page 6 of binaries2.zip
&bY!!b V\G%J+uZ+cA>+yQq$IR8MdaZ8KQK:$#uYPTM?&HphbCQV@6cNB5L4$StPc4TiH9YbuwV/S$ZVc!dXT=D
Y6AdA$ NI*L#CCNmy^DIGe!M:w+#8\wF*X#N8SybSIyc94XmqPAdqqBnR^MhJ:JPl:=PCQaXiYdA#y8S/lQ$Wkk
41qeYQ S=HEnRd&yqPuqEk#%$y?4>hBj@HDmb@/hMBNB:tH?4qNTKIlt%W&4Ap\*VCjk\M%cRTSd+A*LmlGI!Tn
%KKF6# %T+t$Kl:p*GyBc#6bwW1\Xcu\TDue#VJ&yjH1M@9ShcTEl\Ay>6B$+VY%&eD!Pe#pVJSnCXWd?>ai!kT
?9A&\h nI:ce^FA5P4+VNA=ny?\F#lkuZ$9G9tw88XKa8ey?K5jb/nlE:VwhE>YaPjaS@Q^HIp+1y9LcBjpZ/?T
R$jJ*Z G4RSX4/@<Cp5:n+d6X$eKL!SFuXCeL!j@j65nwNG&a*mMRG@@MAjP!p/CA:i!/tQ?uQ/jeRnE6whL*Bi
\>5TkE mG9Jj$daZ/a^LRt*aWnyQ<a=6an9!kXYIiVJ/cYG\pF+N@IJDDZaWVQeV1hh?e=+AEJXw\S^4XFwLm\N
\DqYKA &qXqyA$aWZNSmuACp1pbP1mL$FL<P$WV=\9p98XT%@nB!&>KA=#Bn8>k^eDJ4hpA<=>mb?SAw%9V@9Mh
I\QBA: A>1<I*Z$JDA<=:!H@YyStATCw1:9LP$&6Lm@yKkC%GnjZ$Ma<FabPn=1h1%&?kh=AW*8JyTa^G<9E*PC
jw8D+X e81P$#^W\51%y#&W!maLpn4XYdcZJA&WW%pW96<SyG!V9!6\Z$YA9&T>5BZ6#JI%#+1kLt%G<$H>?dq1
l=E8+j IH=j<h98bE/5eh/tKX+jFmPGp>ikbiYyCZKu*uCmSe^1!%a<R@?Xdc>Jb6A$G1aLJw!DcGHE!\Lp9:TL
RLJ$/\ RwFXnGeC==bSWmp<bWBTV=!l8T\w*bXDlMX!GeYY>EE5#MnMT^DW+*uY6L!l/T$p8p:pd:q<QPa!KENa
HH9R1t $TFAai8mM@kVb:aNE=k&w/lTNYSlbCSEtdZbENSEDKY\F+!QeQ/Jh\n6tYHQyVuc$^#6&k:6&WBumiJn
9%1RGS 5Bb!*mXcE9Et+%Q5>#Ikp4hMeM*E5#%IpukYiG#t<uSiduPMF%CW/\HQ1qa9:tG<%bG#:RpKhC\YEyaL
d*&p*T t:cL$P^webek*yb^q+<dJaX9E1Hc/5CdSLk%ItlKdEJ5m9E6q9yh<<:RVuJ+w/i5#T:ID<kDpA:R/c5H
4Y/$Pd k:M*DyKj>p<eZ9niDQLk9h41k<Nn1@+9Hq/c4Q6*5HZ#laPu#9Zy#T6$CP%QZ:*9Z%<<?PSGu>?<nQ=d
/Qb4tq 8@@k49$ZDncP>iHD@<LJJE+PN:IZD#cQ>Dh8*pL@J$@him^>+hdGJ@5uL9^Ep^D@^c4@#S84@yH?mia6
#KFS1E VEt:j*Xy+<QXyYQ>+?Z@wGN\Hu@@i9@t&>j:@iPq!?5*/Q89Z5@a+h84@nQQZmqLwK&4%:8%A@!??j+q
q1XcJ! %Lhc+=**><ul+W@:t&>j?L+Qlu6+@RAP4#/XS9y=wwEcZ*@*S8Q/\dtWju5j=:91jc8*Xki4N*?=:>^>
:Vq9FV Eih4Fc?Y1@>iya?h$+J>m9+>?ml/=5%a?+%??:/L1DqS9bV+k+Ij!e1jj/PMk@++ZJkYiQHIKlFeQ@GG
TN$%yI #t\R4N@+R!b^IG@I1FMHZbena>yqcM9Fen6ewJQRCX*HtX@6wD?VXPu??9=w88hEDSMN8nD%>c5aK\eM
AJFb!: hW$H8a+nDb$wTT\!pa5/#nQapt!&uyhBm**<@@>RT\MEFAACAAkACFX6JaKhkWilJAAAbn$AAC+AAABn
uGe9eF dGqqduS#L&Sye&59h&q8M#I9WEhRbGq#c$F\eC>TbZM9W&qpbYJlenR8at%\XZ9Qe?NGq1bpX4pS5Rh4
VS1mP\ !FyM*5wMN/J^M&pB1HV$dqSZI##D!<dWAF+8dt+MS68<iV!KYLLCB!GbBJm!Dn4+WI4\aa@4?<cE=X9@
cQtB%X TjbWi<Wd>96i511uYTYXTtLm=j9%9i?>VQ*?9@*Q@*wm4@?Fn^kjG*\<Pn$=PV%=JN@@/d?euI#@p@<+
qH\6VN P@Ej@6ZK*=P&>j@\D::+$=@?lH@=uWH?uk!D@+h@?C%<5pX4<:K%%8b%QVZSNIyGw*\WBQIy$yE6T@#N
JWjd9# ^&c4?L*Tdb^Y%nTF6aqY1icuTC5Xnw9m=T^Jb1ciSnNnnP%$GthyHEXSM1@4NNGn9dXtFabyHCyd668m
/j>naB NE%8<j+/t5*GL<$$te*4Npp?KW^nGlFeFGXV1tncc8i$hYp<LwM$!d^enWjl$SGERt1T#Kj%QDw9nW9V
QjP6YJ PMHjia%HnhPy\e1=C!jB%PcRC*&^jYQLG8?anl=H$&uNndet!qV4an^aBiEpN:Xyhd^*%6qSWbc%yh#M
Y$h6Yk K<%uR/q/!1@\ia/qY1hRMw4VJEtV<\B4>q4duS:q1>JS*:KEapXy<i^\Mn16ISWK%&%4LJ/@yeJ\Rn=1
Ri6^M^ &*T1L/G\cYF4:WR8LKq$Cq9P&mRM#:CPcmj#PNG&MVBade\$T1N=&#wHh<JeyZM4Y^4ILa*NC>QP$tp:
+cG<Aq G+jlYMHHSStEKp%lcFlqY:!E1aPylq\NnSYYXtpYRqX?$ty1&nTc6eWpL$IE\4k\ta1%1Y9+4+Wc$K5Y
6R<eP< F:tFY!&1jk8=<K<6VP$DJ^n^d#/iILSk@C:TiG1ADeGCVVnba<Q\<Y4yXm59X\jRQc*dhGbjBK+I5i&m
yNY16p lPG\&EX\L?!cF!>lj8*8IZdZL>*PXX9KyLw&#^EQWVK??t4c#1jSFKdPWl&qqB6C<\!lyALb<<1=cNZ*
4w84bq 1R+VVYNHa8n=>DeQS/H+y<##58tmJEN\BjVCDHEBY%WZP=hi8C*mA$=EIlWFHNGc1%<RXqQIueJ\pGuk
hcMFuM E$NZq*pRKIc#:u8*&8En%T4SDPlEy:Mpuj=tGBI%KkyaGy<Sm!4nJ+*at4!aN96L1P9eewjXdw9<lijk
8Tuy1\ bLP@P5#M%VD<^LBCS1ZViR&lHaSn9eK&H$?=bR&S:1JdZaleMjd6eIBFkRiH$ERIIJ5H#5Kjhq5=dL#Y
YYuV6L 1S/X!AS/cdN#jRh>KSjcePq5B4HD\*S>Nb$/B<N5%HN*\Ii6D?Wj%#>H<hw>&*DVduWBjYHmYIeWcI%^
a@eB9V A%@lW^i1>Td+&@Yq?cQdbF<AWk/bPt#L+HDyH1#h4%&KjY?SI/c%ySwPRVm?HY/^h9R48HnaVH/%95^9
:\5*@+ %+j$?bX6DqA1Vc+iuH5+bLh4G6@B?#4WadajAAB+RI1%a^1b6pa5M5=n@K8DKB+ZTAH4Mppp@IMpcmu*
&d8*Z@ /1BH=w?D#cF9Q5yQI#k+t6uC8lB\y^YkeN+a^!R/9y\tcEDqb<Mt$99L&%DBb4Q%8NnMy>lhMq<@cHhy
$1Z#+i *GZb:1<&wX+:@Y!n*X4#BdpGpZW:GQ9*\/BGWQuuaAktR%ENl:*bD?98PT\NW\%85G+w*i%BQ*<R\YtG
!mQN#i HEw$nJ5?H\ak?>Z\4?E\jnqMQ*=AVQ:taP*6R*aFk?H9G#hp?9qBZ:&^64VY=>H#+WGHYG91&VCe=pM\
ql=ikn G6V6abRHV\@GZR%tiLBj@6^<eaBF1>5DNmA9lqTeMDD$*!KW=+9lVS+M5&TaZZ*X#69uB%5Q6@ylMLiH
kEySA& >PMHN!TRm&@Km*LL<ty+KG<*X&@!=QuRu4$*uNbDj9Y9/+*>H@D4A&L4T6??!jeQhnDN:iF1I/cKEFhS
5:4i!\ #CnY\\MKR*=%CILH\*a<#K?\&<*HB?5P6%iH&@d&F@*$kd9>+w%5GVISX/W^YI8A&lclH5#wbD!aF$N+
G/NJ/e 6XY*F948wiYd&<9dN@YZYL8B&Y@jGJ4KItDmIJM\Q1mJ8S%tdj=w?EpQ5>89&16&j/BhB@j$F@GWG>d&
nu!j:k k+N?+JaD?BiX5yT%Lk=?BX?N#+Llhn$EH^^GD?Z?AH>Gk@u!DZLkCn6+j9nmwK+&CuA\ky$S1yJ/iAki
9jRkP\ kJ4!<SAMl#EM?QN9?M!NG8#?EN\?QLnd\eHKWJ\A1EXj!?\=^Qy18AT?u9#8dF1u$dVPR9WB:G!*KBy+
t#VL!T G&IbtaB>+K8W^XH5HD:DYq96HTC8ub%N**5JTARc#:PuB:6KtW!I9XS9tLcITcJqi9R9VATpIcaWc9Rm
RaVE?i PupByERXRW%:h5DCSkTZ8h8\u8\QC=bkjAW:A<Tk4&Piwa!E+=QVD\HNw\ByQMu=Jm<+%5?I#SewC>1X
y>8D:S dyGXLAkGpd^yVXP&u=Tn@QHnD^>n:#ZIl<HVR1Vb%1KMqhCJ>Y@uFlh>Z#uueRQJC^lZWbRtKVS>ND+D
>hIDZZ YeLKtTY/&=1Mb&86dBu%BNYw/yN8Sh^ApJRwp$*y1W=+?t6WFSdFaFVtbbZcXcbnRDGaqi9e11?YT&^>
:dPG?/ lj\qWGJ9AcAqyNkEm/iJGJyXJh+CQ@Hcq8/T&Pw1%?<$<Ht=a%\%IC&5N<bP<tCTQ=/ma1KmqLCemtAw
t$hJLB &LubG9jMA*Q9ZHi^R9tGZMBkFK5+Apwu!Vqma@\pGYQQI*+$nHqtKjmKLP&+jHF^$d9FAn?AZIwtY5JE
qVt<RN JDp5cnYR5pZ6DM5LHWDjVP%FLHmGe@qm5hR>&CD&tl8TT=SK5CA\5JjFGK+h5^LC5@A1Fcb#<cKS*N<X
lj*lD\ 9d6apT9EASISES4Ep&AM?==P/X%?jFTYVcXRSCFZ5^CJZ@6h8?58ZAhtB1E%LhZRtHp^ReX@A5KAKt4T
qWlwtn KSS81DJ1qXeat?:c%VI<!wZ#EB6TN%B$Ri8Ea+Fi\X1yV8&Ck4Z&BdBdXiBHMJj6\WV#G1c!EE*yLEZ=
F%9IZF C^BALBTF#WwLQPWm6+P!48*hM1\kX+wXXFdpDSTLD&lep=i&!duljt5E8^M#!=+Zm>:6E6iblppAW>hp
*qV/yb @<#BuQRKuBV$KknA1p&9^eh:K!9yaIV#e4u4WbayPlC=ca^IG6HR/BZA@+5JnBC#eBTq&+8L+B8*^Gi:
9/ABtF CB^SFkVZm4:dWkZnEmu<5t%B\$EEdTm=t?u5L&HX+\?mEuHXWYH+qwGJVJm#!&nHhLPuTMy&CRKn$l9K
?j:DQG ZZXa!D%D+b/\kC+E%mIJmtXJiIaAt\H6&nu!KG%R+q54YiSI1/wh%cbe1aaTGwkSM&YdkbkmbcCLT9BJ
KJG#C< SF!w6H9*!9C^/L9/kn#e6P^qAHwN:A9QK9RdwM<pkcQC=t+LQ8dNZCEtCS#PGRSt#??LZC5^RkI/jnJn
**J9L$ VBJpph+P=B*T9bEl5ZQLD5!81j:bTdNptSCE#I>!StIlZHqKpI%DiZdnN8>&9cK=1&wX\FQaE5kHInhA
ei/:Hc k#WB8I:Gb<BZQIL@NYcZd591&cWZDL=iIdV/98>&K*uW>?Cu&HJ4=m%c1mSlT^ll**N+RDPw:Q/6XH1+
iTn1Z! 5=$#pM<>+\F:tBP$Bi=KTb>HSEtIb4iGXmw4%^Id5JRFV1:Iu*jhcuXW\ipYIXBMBDKRTGkYECBn<ut$
yCkYc$ NH16n!Bbhb4kkhLRi?*FDl1$JYL@t5^HI+J#Z5Dw+I&/eG#H*F9@ALERG16/&:NX\9i&yNWlZRPIVyKR
jW#IbC %RmBmt+R!Y*&t/PN?/=uYK:k+KZ:D!@6\FdMXJw#BlZBI$PmAe5pMtCuDt@18RNWyee8>9ZRTYY&JcRT
<C<D#M K&8CHeI=Ae4cd89NVAWSFqY/epDaatp<e5wu=Cp<^Sb5Nn/d+SHwkGQy81!a1tL&$eN\VFZ@5#SwLG<^
q:4^+Z k^^!FcPmSD!n8CD@T/SCDI/\j86e!WBZRi?L!G?+abXB>Wc#khwH!BmQcT8y*<w&=d8I:LldYE4bycJe
uKjK?X An+<u5FJctbcimtCZDdbJaKe@tYDAR<JTpJNBMhm%i?E84l9?m&?RMPDFlVqL+C/+$tiE/RnpBS:/>*4
J@4b\5 1!DemaikMGn6A\dLLWFLCcmnM5mwAS&@$8ch8q=Xy1C8a48V:*#nX6?9uP%m=YuGhEbDw=Cd/JPYnjj/
-AqDic 000ad6bde2e00110334 Page 7 of binaries2.zip
q=D/dQ YBL+YVt^hZZSWNu9cd$iP$A^F5Ty/#?$cEHSRSiR1!8Hy1H1cCqpke8+a#m1<y:>99?G@pZ=b#uAhp>Q
lTDT+B ^1lJKymDlbSklHBC#:h!#=&&F>88&@Y\XQ>ND>H+cSA^wLF+qmVVQ^VqmB=CR?H&d!T5KuEpjR6:!cQ$
A<??!? MhwapeB!%wW<Q#$=Sh<S#i661Ey:6jFY:m^!%%dChe^8J?18KBbb!9bdeuD/?:M<j#EHLTVBek?d6+Dl
nbu$Mn /N5M6JLm/F&8hB6uY+N8tCMXRM:9V$?%k%lW%hJh!cNhISmBA4^#NWlYTAh^<Yb9jRNR!6kL65yZ?@We
y^><@$ eKZ%5@$^Myn#LTCKcmIj5KMN^P?S*DyJhVlt4/+i@@1>S^NEMZInXJXQ@A9/q1d6*AJXbbu8JDLplb1D
eShpk: DLTpN=D:cB#8Za8YHudid^kQ89cA%RFy6NA54V%/AkGEaWt%u>j9u*$I5ZQLka9hp>S\FT&pGwJXbqaL
dA*:=K >hbW1>/TaSE8Imd@!a6au4u5hLyjl4/pyE#@1wP?FWHPq&V&LKS?PWiCLAquaQ%R%!Y\S?HW^RL9R@eL
tRd69M @HEIy=&Gk!q*^R*4bpYETJNQRB1R@C<@jC!t1dwLm!Awq5+8CZX+5%+T<myPTI/kw^$HaAlBdlm$Mlnl
YjEXMQ pa&4G:54C8iCBZZX9wwm%?N?q*deM*dd>P#\6ubL6CLTuLWkSRy@1q$C%*/iIpXbDlwpZNW!E@86l%dn
%lH!Ja G6TNEJS@dpll!YI%iI#yXX^<n4h5RjN>w%EliaHP9cw:ak*uLN4L=aTG\VHKT&KLC#wZ=Nl9>XmVy>C9
QkqGmW WDq\mblh5/m\Bw6eVaZ=h?bwYPNC5\l!dH1=eCq#D%9ZC=D&hJh$NHKM&PVIRhNW4Aew@*p8w+#CJi*!
B*9B!Z mYci$JYhBBVmC1\ReA:tAC>9uXJkh1mENHIhIc\hG1lPF=<udujpGdIPDpai/T4bmX#W+=X\XW/+&FHN
Y&m\Rq DGwBZbeZZj!b:mLGV:6%jnqAHS^JnN#*h5ZtpG%qqtSpleHaWh@A/a9&e>ZyF\55YQ=*9E5K<I+@ki<w
ty6@Vy q+\HDK*kqNN5kiq=MK:eYkyHAuHIJ/Lb?^VdHiF^5cZhXq61di$%=+WNm8+eDD1c</GlAX*>DP=<!b:w
\y\9H\ AncCaL85wl:S&ube^>LI8lP#J%YRY=TMKtDyM4FhFPElmGJad!eI@daWM/CB:>>VLQM*N%6Pa+MS!km#
!Ztw@T 1E1duZCD1q=k5#6cK5?Z1X&YC&W65uHFj9RPLV1K&bT#+#b^t$*1XF$*qcqF%GM&kc#WFh5=jt8FXwIR
mWeEA8 CEAV?l=yNRqRh$GKZGBYCwLnJREmYRd$LdDb:yLE8AB&%GkV5hmaX/kw+P=k#wcDcGcSNSe%lLcj+\*\
BYEWPK TPTp$bhM+Cmat@X!:&X?HRjuPap\Sdq\1SYi/ykM?R8Q:1J/:WJEXID<61^m%=iq6IbG!6G<Ihcn8%pF
>j81Lt my8E81kqGu:CA!^cI!iRk&^tG6/\wWSL&5BBiStwQeC1ZAVGde884X^LySeBtu+ESl<1MD$ACGitmMej
VcqFEm JI$+F^!NkZX89*uy+NkkTYYjV>yh?LLhJV9JBldkXbj%ND9!+BZV*4IkYa4X/+%G9%Wnq:R!FQtmZu^Y
pyEjF5 L=DKpI#K*HVAaEYkW/@9+X9RnFSQmFmSY$QjyaKHmwwq+!XE68%8F$4$e?kN<%tD$EM@@t>b!KpLG6Ky
d/IcRm mejqj4$JpJFNny>C$DJ<8R#D1pWMI#qXW=R4:AbRR/n/&l?+wBFY=Fh&9@:KtqZW/dLiRWF#EY$lKj#<
?/h4C* /KZXE9@4Rieh8y<:uTTjpN5nAeFZ*B+<HhT59Ik4Ai<uW4MYPSw^N8$hWBS=:VS/1?4j&NiykPMXenK>
YSBM9C S9bGdb?XynchJ\Y&lLy8!bLhPCSp4#pCCNRNa*GLMwl@TR#hi5*6\BcBZ6u8tHa9Y&=?6WB<RQt1\kQS
68*HYm PN*JTeDEdIpeVR=%N<:WVXG$dwF8$4E6Tj6\/Za6@nCN&m$TeM6?5EQNn*k!ptd5eVVY/nS1aTy#LJTM
MnHLbP jLk:iA\c8wDtwAPqW\p=a/da8i5R?=>EV1*Zq//wkt$ZL%MnVEH*c1eA/kBI>IHk6E8AFRhuHNpBZw8Y
B/w=95 M=?m5FB*a&5iLLH^Fb:CYQk:BV%e9:MP$Jk98lV%K:Ye&Phwu4NMS*1C!Fmny+:T6FpphmEHEwm@^:Zd
cR5Lbp :jAMe&G4BYwwm1bMQ9#anmhabRJ!5q+D=%T?TG$F=q%JJhplP68CBq>Yq9!A=\6+eaaXbtQVdyGKJTQT
5J5?Ww yaA9K&J#Ed6K<HWC$NLaPKll9%VIG!FYAZ9eWLQXnVZXZZI!SEM$uXbCB+Eeu$Z$<\I:WYY^=I\CeutC
6j1TKk lGSRRc^HQnI+Q8AIwP/$b!R/SlNWICB&LZ#W\@A<\Guq^K#qjAN!hRB%+e\iKXqA=la1X$JQCDb&RR/\
A#^C<H R%h5YpRNRZ&LPCp+AY6KJ6GG+bdAA$WLi\y#A$k5*bPWMZZlENnYZZB!!htEk1<RHlHSE8y1kH4\PIyn
8K1%n= Xd1MLtdb6innjJ@W:8CwW5NLS8TYY=F4GqFZwRu@@W5AJaBDHAYY/<1hE>lkM4J=VRpYqJ9^k^cml%1H
jPnN@A ^wkNql!KTBITM5kp/P1&1%&qmG+<=<PuFn9kIVLY+nG/#F?&bkiuZlAQP<RlKw8jI8&iYCb^q51ERj^B
q$a&:< B!eJ68#$hwu??WM!Fp/cKSK&Z1W6>X*yQP>5YTGI/kc5YRTVZJWq%1L%l++SnAZ5SMI:1WM/ZZWSCiW8
I^6h$F ZA1LqeKywJmC9Zu5y6uA/SAKFC@488XaJbbyt$Z>#bCawIT:NLEq5lN$9Y=aVjKGGRF!9kd8^l#E@QyJ
MQ%PK6 1PIkYGBXTd51aE&^4HV\+tL^GP%9!FTkZE/LWl+Y:#i\Z=eXSjEEZZjJ\wBeMI/^1j5u4i$8WCV!F^eB
&pm8ZT ey+kl$l61T$a#bwqTpXIq><@TeNpC^^QyRj4hNny=bP8#9NF5Fnpm%AKYB4^XJ8uWN16Aa=Ae9c^ARP8
ERJZ%% :FL&Wqqq=hR1:=<pZRRGE\ZM54^yGNIFiS$/JT8DGLTXiHXJqyZ5l<CZ%W=ZbkZ<9MkKRWAbYDPpIS%T
V:*HMt I&+8cH6XELFSm9M8SjPMIqSy:!tX:JRL1\/eq^Q#kmF6m!$^S$l8\Cq<D5H<+VISt1G:LcVcpkl9Q!Q%
d&lHjq ^j6+R59/F>QPKDGIKeAAHk6L+IiqAhyc+c^ICQVPIjk@/mEYEb<kq/N#!DWT/5DHC8uL<?CW<c1S<EVy
t5IQ4y 4pE&qR:jCA8?E^Jm#6T#MINePVFBLaVqPPpEP$SX\bQ<HNiquD?q>eX1q<w^IXC%BEPyKhi?HRwFESbE
!hp!ii LWi%ybA@<lIw%QVINQhaF$9!c>=#+M/p6Dk@J\FH1/C\:Bqk^$NeilkwBj9w#8cLSJmGZEawENJkwjc6
wFLZ=y ZMZ@NkW>nG=nY?tTHC:qAjaP1/9<M@LJT#\>FhnRAVdty\=IKCY*P^B$HPDBQmYbIQ9AEmdZ!k?6<HnC
n69Td$ ll^hH!j=IKlN*aCl=b\h&*JFWERm\S+XeAB$4QQXuF1^:9Lw8uw:9k\XHpe&uVNA5P&Wm:8ijcn&S8EL
$nQj^& u8Ce9aFV4Giy\AMaGtAAkEa=L/9aA^\LGADVH1*ClkyTPjJGh>Vy4b<:hBBy&n:EqqJ/Z$5b66I\/&PV
N9qYC6 :qLV?B5u:ba=:QplnBCDm/CM6!R\bhGZ1?NE\JGR<cDDyh5KqIA$R?ybJ$VKD%y!=uAeIKKX&CL%AuqY
Tc$SDe LZuB?Z4:V&\94PX^#hdFHFbtGZ<I/PVqnKL$bMei^e4VKRM6YBBHmhlFV6$RLDLynAFMFeS!B5bYuAN=
5h\q@m :SQS*q#L+nVdduiMK&QlM>$$K!wek+^4*dC55uhAlPZ5lTWa:QZ%1^94JcPRIbn%!Q?EVw4S<PlGdEN>
NHWEb$ R$F9HX891d/=ejh*e9kd/#k%eD/a==:dnWP!H*#S</tX+tkZjwy=>WInK1!>i@*h6deY+RL5hW5/^atB
S%Hp\% w&K4#K:mH9$cY+@<BWIG68!<ui:8::%aFqVPH9Fc4@ew:FnE5!IaWbyc$GNRiB+y%V*jB:E*%/?8@XE*
k$Ya&+ CwpLi:ck?:&HG8CGHL!5t6Y&6@RQ$tqKGJaS!QW4C/te@tpiPmW!qjGB66%/5ZT^DKl+^WWFIaHjG1E/
cLT6<B h?I8R>D5\Gc+Ttb+Gewt$FGCQX=>$\M@EBeld@V\^A9t8@cHII/L$/%LHQ5!c5=t6yS^yh/&CBHiuiJb
I>q@Ic VDDJieaujS?^R>/S%uDym?QMDwFwi+YEL&STpnpw*G>NHe$+#WK^FjeTh4kabpeLppkH:h<Q/+t?hyXq
cAQDYK aPW44hFWIw$#NY%+ak*Kip#^DG!Ny>$ea58kAu5GL1N+a:HK?n=DY9J\k/e=j1pj*nDBwYN664%9+Gpm
bcpYK& 8KjkiXCDCI9nb1Z>GE%t=!8@a+>^TIZYKdCePD+P*DQdSZEGT#958KCQ+%CNT<::bc!GFqV:^Ae*$:^\
BF8pSd $4<>tiD5DI!/\NbYGWwVeM*!*lZEI8bbn8TW*wye5H1Ra#uF<cuhkCh6iSpEe9Nt&&hcn!enGWmJwqIL
PWJ\SJ 6G>bG69WZi@HyZ+/XMy^c\kART@S!GRyXCP!phILq4CV?AR^i%hGbMKT<d\X:*R^h5Abi66PILb6jj^V
HiVN<J ?I%jLL1:6/a:JmZCNhRb&%tpN\eY*DN<BPcJ=bY?p*&uVi8Bi4M=H4R+qBJd<e+PG6?cd9tEl>+6D+n=
LCM$/% wkQ9:&ZA^#6!qL4*1T<DVli\W>A^Aa=Zy<dllJN#ytFJi%^jTn4c*F>be=9%\>wjHLw6ET8PA>CAlIq6
a:KKAc <^ekLD1WBy8d65llQ%mW:KBe$q+S#L6Gn9Nk*9uVciIQk=VAktV<@d%Ej!HmCVqZX?9n/RMnM<=I#tL8
&n\p6C @mPRYRRH/=^lb+H59#8iwtk@VSZBc/?^ZBjMpt#C<*!6SmeInydw=AlbY6%+jCaKySIW/@YX&E5t\nL\
\Gk:#H N*L4$E*4*:X1yEdG+^8C+@1XPFnT&G@%8JkJ:kSC<&CKS%6%Pn*lyRdqm^^M>65dn*9\Y84iLq+VcJ$@
y!!NJ: V6LJPakVEL9Pj^iNeq+R$GKmXL>?jciQBVl&^&Mq4pYMYD@Iu9B?uhKnhub!F5&$W9+pn5?Awd@@S1yA
%tkaZn !aMFT6<jF@5$$hF=n1bWu:d6H$lbJADqi5^4LZK*bbN4<8YCG4^d@I^laKIy5LZXJ!hu5*VPCAR%AkP$
5DmhBA N/@9@hbTZeuw8tGL=ljLQyRcG&^\b8wkiISmNn>iMMQ4>j&huE\Ew%IGZ/#<^:mt9iR5GRWFmGQ1p>P=
+R<Ed% BbFJ$VLIDbH4X@iT<TucAhE8BE&&anDJKZVjH^X1dnRK<Cu+qTHKGdpwC%NJ%G+JR$KDtddiXTIYIRph
Auc>MC \VN+RjeW@nI5wSb6FY#%*S%QJE\4PYy+ShdYHpHwaw+LXbDARtCnJ#PVu9QCmaK^RS=RkaXW6Q?b*6Ee
NQ/hBM FBAtlQ</Z%\6qPVq+!S=Mu<L/4#??ip4=CD4dqGk5KC/wWnL:WBb!m6hdAS!8VyV=mP$1I4:Wim4HjT>
5B$1np 6#C\jy<yjZ*JKY/H>%<\dNJn#WIM\+JlMu6ywD6\!TjD/*9GBkPF*pYpPAEa5DN#yH\1>I$LP<ZSJAhR
j:@cF^ k^pI9dNj**mRJwKbt?89:?lSIu%y@RA96uLyytc9>nmcG?KlV??dX@iTyZLCcK?@94:5hNqynwHp/lKR
>wkB1^ FD$m?T&5M!:PECnWq??=@8G*4\R$nnhS*G9bMZ4kp6hY?wTB#n8?wDk6?JXK#?&Sl%:j9Q1BtMPC!d\C
4Y?duh /9KtY$p!\w+\%i\Q$bX^<DA1\@GpVL$>PC!GYD+I=EhK&@Hd&kcCSED<y5>I^/Npl8jVaQ+6%n%:jj?h
-ADLN* 000e7351c9300110334 Page 8 of binaries2.zip
Y+T=j: RC9+K*AZ=IdV\GQ=F91h!mVL4KB$ew:1ywWdRh:%>hj\ESeuKDQGX!uuW$#&AD:dwDX1HhcQenW^==c+
$Bp:ad mknW?wj:4$XhZ9lAX?lYGcuu5Rpk%TI&<jwy8<q#YPL/?wc4LV*!/phB=8#JtCNW/&uhpX1V:c=YVaQ/
^%wDk5 /:DlMwCSqj=S1lB<C*CG$5mAKiMGP&Hq6*/<BcL&@eyq^P+cZpJp#SH8h*j*u*JW@Q1:4%>@K@YkiJJ/
*M!Z!M =yLl#<1jEuK+nNX>L=YL<FRc@ct>F+ZB8^EJh5P:atP=\Tn*I8V\8Q@tt@+dl!>BlkqbjC/&ZE/84!pY
nHBa!J hF@IM#H1^iPa%\uq8J1u&HIG9QwG#CF&\9GhZ+#cL&$!59:%uiCD5T$bRu4PP>TW>#%Q/jGWFiS8i?&n
Y8wjmW Xbt6Im%W/8:?:9X4V<:+jhkR\WNSZm!Qa+EIMXmmqdNpJ%w4^CTn+%+w<F/C1IZ9pY@>N@%S4MScV$:G
jq=6ui 9==FGJMRmi*hh>iZw15jCXjbuKQdh@e?*l/1MuAND=Php/8wby:1d>FS*jp1KeWPtKK%juhlb<QhZF+/
L%LXZh kV^LpPEWC^p$kcii*d*?$h1@*QTw6@:T*F?@jPE+X6bEl1\cV9w6t\#laF#S!VAX:>4@>X1CBC<ATJ*m
hq4Hiq AN=iI#4R&uR?/CtMX=?I\*?>qEpRC*<DGHb\\#tY*u&L+JAhc5hbpR5wXc6*ddT*W<j&S<ae94Tu/cj&
<8:cc4 ?6Nnc+P*#IWCF#K56uILY<b+9mmaim9eICIDJFYFZH%*LwbB:5tSXBL+G/=TT?NMH8yB&yaLj\?Ywn/>
CGl<9$ @9Hcjk9ePTewK?Y#mJi%KJptMb%\J!nIi*mN!JZjcLt&:8:@Z1M8&MwHw?#8SiVFV9#N<dh!Rh1y5S\N
hy+qZ: W8/QQ>:jja8+XIIqal%4y9=WINFHPmct<d^QY9SRVHq*l=a*udMh+&XaZ@A#*kTV&=48LV$VC#dEZF=d
KQA?Xm bRG:8@56%DZu@<mYmi1JDL>GJpM5%^8*PecWklJc5cuED&>8Z5P9QCdXKpp!:$?q6qIBqjkTad<@SklH
:ZqPQ* #ehd<?d/=qNAFY5?:=t!N9m+e@+Lu\9:9X@M&^DwJIF5nIX9$h9@FtYhutai=5*dG^NF^Yw5iAZc96?@
h$L#6: !\M<>J/IiwekJmyQ\EP1TV1Zh@4dPeF^m/ui9L8*ySXuGql\>?p%h996y>iGChnye@Mm?5nQptD5IyVk
A4P%mt +1uC8^+FYcDwZZ%8qV/@qpdK\JmVND&dpiWBnXXS%uY>$phT8Qb^V&JaNlLm/t<M%6#>#RSIbc>NY@^n
F@Y?G& hDLt\hDw<ZSct&nEWcFn%iWbw5S=K@&W%1B#=%lqb1$lc=*Q=:P#IJkumPQmTSRpJ+EcBdT&u1#hei\E
X#?deN Y4Vq#6Z/aYMuyVPupZ/t:>aH+<!Je4ZdQ%\Y+<Aqa%+cTHZ1B/H\%H:+JWd4%Lnue6Y>XMNQ!QC::*kS
q^$HG: jQn*$>6l@AY?jjumhnkJlpF#aD\^^&l<N4^ylXuJ$tHtly?uVZt#q@@>HH\\BM<Q6<MBV#m:HZ/Tm<qd
9DJZI/ ATj>1h5Ml\BhYZe:QDl>P^TR?^IG?>@DaZ+%@D?<j:4R&/8HFuK9BnCcVKjHeeY#?>jDAcqV&tFA:d!q
Pe>t4X *J>t:eViDpa>HZ=?@?q\b88=:D\aDn!D+=%dCa9Z4*<a*8S%NF$ND*D#^=V:=uinjHI:\B@Du/PQl@hX
L+Pj+T 8Ski5KWQly@TtX\?KkX%d&=8lwNG%aIM$Kw9lk?4+cj^&SqMe=d1+e*yB<Ny@A^t\=c8l4M&tW8ZJ@yi
8/:jHm 9%wQD?8N#jFR8Qu=WG4<*:$*ly+N=J=<Pa\4@1cBl4ZjBP<X+aVRLhmy:*?RZ&BIuk>j%j!>kI#9HH/B
Vmk^Jj d>D\D&<iQS$iQie9GpS\+WN:>plF#Q/6BQQSGhl6P?Qc#95KZ%9%dQn#i$?HEZ+Wnk91&#+/JXZSp$n1
IPG$BY #I>jR>@d+ie9l<9<H//8B48CW/?Gj*p/HN\6>Q*!AX6C#5Lw5DQ/kIcNS!q*Y9c\5>LD+YQwt$mPDD?%
p5LEIM ??EuN\#4ajk#Nq#C<@5*eNwIj*N@#V9^<A:@yt++QB5Py%PicLnl*<?\ju\F@aa*w/iD=1<tHe\XFj<q
/Z89+/ %cNe?q!yWwlJ&QdA*/%=pwZlGLFS@D&CD!5&\=@Q@4ky!9%\6aFi+:Q%twhP<u8DAq%:BB<?*BYEuI:A
9<DYIY I^FZeDdL*u=+<:+Kym6lPInJQIjm&XmGLE4tI<MBy6:AMMMteJ9R@@>j5Kj>HuJu=4EWK@#<lKh\w#1h
AY5dXE N@#6A++=9I>AYj^91ukjQe!JEJA:?welqqFMiVYe=8=+>YG8n/SDjypEPC<QPXn=9\QF+a>?4n>?aCPC
jl*%AY ^RlThp>%HchHDmchIK?^ptP6Ea&Kq<*p64&wp>\PyFnR:&wITQkt9Icu@HDAiRJ$j<S9//wT6Q$eea5C
@taqi? 56+ETqwwRQ=?#ePFJQpE:1u%j^#eP@h@nkRC+eFj*plbT9%9XSAJ5h&Z^uGmBJIb#a?DcM@Pu8t*BhH6
QMEI1? 4G*!My1&Xm+dGJp9/8Q+T\+Q%KQnXFyP5@V^@45<mSjVe$:/$LiWdcl>4bjy1lSb5#*V^=hHcW@<@iw5
Z#a=1A SI6V!M*4tkiWZ1SMDP6/Y>nHI%jy6!Plh@M*j\5F:C$=X$HIPl?PT*bMtlejKBjQc\98PjWVIldjw&B$
8TBkMR X*%9ib?+u1IuVQ\lSeu!TAZV?KN<c/JVGhEjVj%Y5B\W+FHkDS!\bHJqu%*l6ZiG+uHFp>M@TQu*9/\n
K\nNIA nbH$YZ&YdeGpA==6nQpLcH^X>lwNA/&TnZtdJkk&#4PE$9*qdMehh!/#KDTF/E#pX#&jQjQ<Y$/M#5#J
baC*M8 @\hRT\MEFAACAAkACFX6Ji58JKM/YRAAFu+AAC+AAABndGqqduS#L&Sye&59h&q8M#I9WEhRbGq#c$F\
cC=Aj+ eC>TbZM9W&qpbYJlenk8at%\bd$LXFN**m+eyiLInLDiYhD1JJa=uSicpmE#!1nE<ZKt>cXNwwSKFAh/
%BS\%B >K*>mDbmddt%Lt5:HwjRJDAK+lW9@bypBhCClI6\SF!G@eFKYEF8AXG$EJA:KFCyntch:@u>h?m<=@6&
?L\WuA EwIBijd#?#&@&*@9:L!>>hY9BG^d<+yAIMd#F*m<5pAkYCD+BZ8>:=Dk@:i>F9!/aNtKCMG@l$aK*u#4
+pmtPW >\Ll/#JB^J64Bj>6yW\kYSpqiQ&6#aK\qVGCqhJNk5mXC5F@p:$6iE5t\?N6\ewNd\8Y9dXN<N@w5SKQ
Y$4Q*w NRq+ZTFamWjp/t&CTFtm+K&*FZl5\!NS5BLj4<V*K?q:Bd=ZdBQIJC5FMtC6n%1Qb+Zk:j>aLbC6*!!R
TbEDMb +Zhq5ZnE+Hja:!eKbHm5*IdudZmNulP*CSS@YC>IZLNGECPLEclZd^aw6&+RKQC*@/@@9p/R9PW>\idN
MIS*>N c5Hd?H>9+@?<nh?QnhplmI6XC@aw+\X:<i?\%S<JJP5@\u:9^*=>BJ!QkIeHu6@Ga?W&jI@H&>9wd?D:
JBk9M^ SMLF9@H<Ny+XiF&B:^WK?l+Q9LaN4&*Dc>9\:$S<u^mL%@B/Iq:V^P$Y:E4eJjkI@>/Qj:?%<TB\$+C:
%CJ4V+ Z^AXi^Ba?\Wdh8#H*>/Q:>PAtac@8^>@h#@?Hl=+V5VnI*#@Eb/qMaj^i+eFG^LV5F?H<j6++FtBj*?\
mj&89i M$$R?b=B5HcHRSC#+&9B?y&=k5k6F\X@*uFJ<Kj6X\XSCheFeS>6FcVBDtt:hknTQkK*n<AND\Wi@?M@
VG4yA^ \jen:A5i5Zkp+9ESZ6>QD&Cu$i?q1kT1V<H@\EiCLaj@l&DZy:5Ecj9^TQ6IeHn@S+KEd&IF&:M?FH!E
E@*$*# =?V5D\ZJb?IE@*ulQ\YjZwwZjG4cJXm@:+Akb8>B\ad>+Q4SaaE1?XPBA6<u+4X6>I#HS+T:u:DVkL%j
QVmmWk <Nq@jwb@+*8<>t+GQhIE&>IPCn=M?$T\:Y?jCD:<<1Dkk&<?Ei\?e^D:5q?\@&Cc+QPD&F<<H##!tiDI
AjdMJ8 q=<KQn*^1iA#$/iC9!S@Lhl<<G9\?%1k?QRwMA<Lhl\<nPi@C@/9jX<J+4:+YyB+?LBkX>4Zkw@T@m/I
>eCyM! P+4u\%<Lh9#>c<EHJ\<L@1IyEMTpHSjE:T<RdM<<Ihl?>B?C@@#/H+JER+=k>%tDaQ*?c\Lq\i<F/#>&
Al989d CDb>jpiRwL<p&Qw@d\ui?@5Dkcy\YQDJJ*<VyGX<Jhn@>VHBF%<iE*#!#j<WHDmQ%+=uC@/iw^N<?9Xy
mRpum# Rjw*b\Syy@MF*=\8EH!c>*<LDKe8Ca/hL^Ie9jm@BMhK<\Ru4qRJmp4LBYW%N\WZ@qiuwKcqT>Da&mH+
\e56A5 j?+@E6^:&C6+/BpY>I:NCB+@@pp\?>NQky>i9BD<>L@@6?B@+/FTKXXKbc^T1qIwyW4/q$1qpClC^cLq
EplXK? weLq\tZBkW5CAyeECwPZlT\LZla5yMe!$VKSKFTCZ>h1hX1%Y1%m@$?yEIiHmMYT!AlJyCk$XET*mNBR
LZtc4k #hS$y:QBwqEanhJa*BTS5dF/e!!BAqKlXCywF>V$ST1SlK+R+c<9C\pPZL4EQ#CRaBp1uwPYBa8EQK=G
nYK^\K B&T%T8*DqWaHlakqAA/qVSR1^Fi=??tEw=QV1%Tq<bGK!En^:!Z4yAwNWHGVK=SdFHIN+^89WmmppqDJ
V^yeL* MlESA>?qT+D4+$65ieI<Z^%8QK\!F5C!eKFILKH@#jMNDa&\hE+A%=Gy%=dCmulFnB>KXA1kKLewXXKq
H>PYXY W1tTE*u<h#t#5$m+QGTbEMD?keGBIpbXCMwAZkaQAFil$1kNcwbL\Qk4MqpaYbykR*uaTLqna1LF:dDw
J9H6Xt #WbS1Ql%QCTSM4pcdtX&J5:+#%Li*VH+n$K!5!k+MDDRQ!A+eBq=qtGC:@KR=eSZ4qV46H4tZ6>@XeDF
*yehj? +TJ!5hlHPCJ4a414yhQBYb4W!<k>anDXG1\MqtpKLBqdqX1yqEwqI6F!Rk+Y\51+m<m=SD1IEai8aC\a
aJ\RDN t9mCMQ<@ISbbiIlRHCH^PVk$I6V!?HFLb!ju+Gwqa1p5W1bTce*GwqIGT@/XK9BXH55LT!H=9VkW\M5B
65y#*C Fln\1<BjB9yeT%:Gc!AeKyEw=GwaYnP9b?amlVkwAK\miRhLImI:y!hcYqwcPGeyhp>4$B1MRC&4WbCH
FwJDP: Ae*#bj5NR$QRI4mZKb4SDYSm+pYF8=AIT$qaYSBYFl>?VJWKeeCmACH9aLAX9hj%8K8q!?FwKK*q4Ec&
I9tjJC uV/FnbAab:K!uJqL4XFKI$EZj%8$nCKaAylaCu*S6C\Equk>RkJFpKK%#MG?TJIFBT\P?CYFGdP#XD@%
9P<EJS 8IZ+&9yhVcWqJTYuVl$4PHd$%FEXI\#:k1/WF\jQF@>N6I!Q+EA?pAJ=5lSNRuljVH^XcklL!<e9hq$l
J!5Ae1 CR<KCMFhVQFCceQ^a^jl\4$*dy#KQZX5$/tn:KFRKibnB+Gk+QPXpkKa&CKEKbDAPNCHGM^pBeuBmlIq
LF6LY< +/5!EF$tb/p+IF\5Fwj>MpkpbycYh#%8/RJ!iXZNtYQHAHu$/FHAHn*G!=uk!MP<n=SKPiG?#kJyiYD\
hDe9!B $8nykbDqkA6pyFpkpYlAYA&&P1lL^hT5pIWJbSKFFKTF!!H+WFHY^MRE@F9iWpG\&AmbCC8kZ@Dd1mT/
9$#?Cb LBmaulqjPHk=CY9GP+jW\SMPSycp*RHlCCa55DZ<:F%^PGDqC4E\ICRE:w$I#b1c/GYG4n%#:BRld&Lk
@n?K9R S+<SC5JhVp=tCX14kb*q<C@?NBWGajC5>^p=tFCDku&lSIcY@B+G$lJnQtQF!tXm\K1pbP:AwBCYJThI
=#Nhll #@A9mSm+t*CuL<ia4GKyL5BB=CMNIqkl>jpZ?qp&+@XGW/beFlV51$lBQPEICZ/jGS1SSH!*!BR!KFRK
-A!8Ft 000ab1f60e400110334 Page 9 of binaries2.zip
!&9tI= YaaHBwSRbyq+:PmEuaF:BwbtjMuR^+:>H@HLB^L?B4R6DtZlK=#&ayM6ZWKkke9tXW&FkRqc#bVFi=lZ
+>E+:B C11KXAyLB+cIyL%QJ#w:tb=Qu#uF@H8W1i9aMXcQXD+%!&Q=\mAhtJ%:?YIkRmlcQpP\*yhLqnK!!*^X
ZZ$8Y& GIWB8L>uknaAXKQ!yR/?8JGqk\IClTLLn^Ph9aSdXRbDu&HA5DLARXcq>eY9uBqdwb^=+jY?eL=P1y4$
5q^?h@ <69\ppBneLBTAd4>Hk>XTIXuyFa1X/p>w?Mie4BuhMAMVb5V<Ze<Eyp/MVBA1HV>PD4S&VI%NYY41mkb
SeVe4F H^<@^uDy^6k1tXN+8uIQ+W^GW1IW#5PT5y:N#HwS9WKneYAGqLXF^u?1yT4X!<q^4\FY>w=QPpHa/+G5
J1I*tV u<$?>bKq?&cuS!eeW$?jVNZddBZD\?M=Pdp=eP+y+56!Mn#D+lj5CcbIGmPH5Eduad$9qkcLu+$*w><J
9Cjat+ jVE:q\n*#5#N#W4\/<@XlleWTM@=/8D%pNG<A!PS+yDAW8@p+%:*%LPuh@JP&9Jj#5%bdXc#McipwCTZ
@he^>c yEDIBE9I5aTdw1BEKS4H6$ai>!WWQj/MjC9&9yl:H:Suun&hlcBX*tjQ9Fw+GM?n5eTZ^DL$Ep&H<Nu#
AYhJcM q<>GS*wu<KQ1!yQZ9HQQ!t@jL4ja<w$&1&KiMG>ylYLY/%YVNCTlbQDl=Tp<Z?D!$e9jYRXtqWG4$^nW
*%HP$D K9ZQ>Yk4KSTK^y+LW@wGS6!>:5:!9JMu4%XiK/<59>*RXq/id<8*<ZYBhS6Wp^VQ9h=Tq1<pa8#BJFLH
6X=?bZ e?bj@!YB9\IeH$hWFENEIlbIGt1^DC1N4!dJYTmyIlFMe4F#51@J:i:64D^=59IckK>hK:@68H*:t8Yc
9e4FD* leG!awkPc/9mthj:XEF%aZ^8XnV?uDIYC?D^APHMDICDb&cI4*Vt&dNup<nR!yqu#=<nkGht+YQq#C^Q
6bj1e5 a9d=m>pm1WI@Pniddi<e/b!h4d:YWnp&?@Sc?Zjq6@G\qQQ^!#jRCmZyq?ZNYdI6plK1AhN$wH?$%$6p
Tk4HQk 9X/Wj#n>=jV+uFEmSZnQ#mFuRaw1NRe=pF!<*td<SqFY+&NpHFXnb/jZm+4W+9ZPAjRcIbj:?LJW1bIc
PJTj+* CI%qcibWmbATNP*CdPAmMeASSq+95yZZ?%#I6:LQ9VPWJ/HAYcWK9#tN@@*TP!=ZtL$9Xi+y4#hPtipA
*LV@ku +tB=!%Q9!@L!<69jAdn<t6=ubi1\FHLpC?<Mm!1G1/a<8S#jQA>e=B<P*ECCFC+dyq*mS+du*qG%Rc8d
cPwtQX <::$IyV^t@ldZ1<!Xw19R^QAnSdHP^1<*t:HGEmZp=/@$?Q?h^/X=R+=$jYP^18WBkWVE!6ISjkt*N>@
/1?yn! IZDS:SDj+Du95?Dq4CRS4kHAL:!VZy*KP@eCZwKJKjqBKKQ>5LM+kRN8L#lQZ:9>Zjq**?Gl@=c%?RT<
GjD4p? FcE:S&A#W1ZPP!ib>d=WEK!I5pmk@$K@yX/9Q+?::Jq*Em1dtSqjAh^lnWFu<D=Zi=*n*wFuaD$EZEVT
6@/>/h e??#$T6id/am*tD!i46t9V?Sw4:Vj@i6@49954c1FG4ta9CY9tVYXSL6PVZjaAt^L?4kyj=?C+Lk1<BA
Xa=KPX ^9ibh#^+euLY?#Te<hX1Qh+b#e6u#:&/Tc>LmdDHFCB>+b$dKQWmdS1X!X=9^\89A%SN*\IahDX@b>:p
l6:&k$ A%nB+@I=&aAAS8qHyqRJA=j+?T%+A#<JY5J\b<F*GZ+$I!K?tV4DM&RyiPc=!8!hWSq+94B#$!kScJK<
S5eEWt =jY/Hh+Z?t@$yt??%Z!n@?bd9S+qlAKHSbL*Z%5ySmVA$n/k5aN:BeCFwSE\!+KK9LP5H!mKpDBh1X>/
=H*htm m#V+%WtE$E6q4Nid1KJ$P?KbRMJ=Yl4>16j4VJ*!Q6N<w@pt>b86?AwH^@H?nXZKjZ^>VycCL#u<8RkV
Q?k?5# k><C9\&W1&iiI/1Z\hAG+dKZe$K%+dq*$6Z5km>$<dCSTkXlKcc>#%VKYi@#$apj9X+4>IVR==L%V:%#
8Iw#nJ 1eDet9^N<nhd>j!E\LjR#?hlu/6wBtd!SuwKCaS:@jC>H^YKWm4:#:\99M>DR@>XJnE+9QRmTe>/DWwX
9GSM%E Zu:yub8m<QX!M>+bLcTy!aT/bp*/XH&!QqY#FW&eT1%kqya4QQN@lnyKNR6t6B#LApuPAn<@Q*@@aItI
\=ZYR1 6ZZL^PS>pTTW&Stdq8<=XNV91JW/k$Hqjn\^P8Hp4DjKcw8>*m8bHNjS/Gk$YVL%J4*JwGi1W9EqTj/M
uti^<M l>Y1qM/b&XGDk64&=iSj9\WCIQ8#duab*%NT9mL@Iw+\diq$lKlS#je:K5QE+=E86%XjYuP1y5d4@j/D
8GK!ae J1:b&eE%el#&wIHntJ/X%Dkw=kQJ\%ywPVwPNkIDh@E4jkKB*\K&*pC*IF<uG^w^C:=c^qjHClKNyCyc
8>/kMG 4imeu8y5huKG&6QHV^>@:n&#<in*N@yKT&6LPYMS%<R=1e&uHcSB>AWjS*#u4yBmhq:GFnqk=+WL+GJ@
Ni#hS< FKRk9yXF=laJR$XT8hyDbSCEXV<*h+DNMp<<uuA:HXdnnbw#y&yPDh<<89dw>&iP=?cY=icY=JTWqDI%
a^8tIW M@@!dPjG=VR>RN+Tc4FCcWRKZ8!@eAGbiep!jn!nKSHAdPbZIW$TLl8@j$b&VQ#w=q!N?61c$<eJ?hnS
S9VFcn 6Y8QHph46Z9*5h&=^*JPKh>up^n/=^e9b>GV<WMy1nH+W86P9AKZLF/+aMFC9!YB<G9I@Q#NSu+1@MDX
ITbj?H EYFiXR^i:bl?*P^&Yy5G#l#@Q+F*W@iMRYY?9WKKwT!nwy=!K:WMetYpmM%I6Mdl9&nlRu?T%ZLtZ?F!
=qkI%4 u*<qpm$c<m<yC/MTlKXq!B1w8huhZNy@<@5#RD%>=9Tba$jZ5MGIaNHLMnt#9AFaPSYT4c\AT#W\6En$
A/:FAl Pm%!5I#q=:?Iy8>q6MnBPl&&npB&%15J?Gi8=Gl8a646:8@4G/k=W*Q<hA$a%=\m\wDhja^G\p&?lTi$
DA5k+= 5hVM1iT?/a#/HppE#Yb5pTMaBVmA!btj?aY$\mH$ncI\NNpb5mK!GtD4HI<ji\aGB9y9unq#9KdtDE^>
dpec*d ?5#^w&9Y<JMw&XtnbbM49/KD/R\Xt+%I5d=bqEIJ:PBmj>>RKQV^FhE!IB6F1RId55nDQuEbZNMV#TQD
DCP@/# A<M%MHNN#cp#y$H+#NG%c>c5>RF9!6Twa8NybKcqM>!qdJYTbm^cQF5i!lMGS*<m#FDbYld6V8ldwXKJ
Tq^ECX mm%T\6J1*6Lpa:%:&8$bJq!aGdA%qD^1n1%hTa^*+:dycKcKXTRy#R9WQ<8q9JuJAG#^nAARM55Cq9kH
p!mT*% ?wj+8qlM@!KjwNqTA#qayicN4FLy4I<je^:AMqWBtL@B#m9ZdCJa+G4+KTYY#aNdAW:Ljc\Dq<wwpEKZ
j:uiQ% pcYZ4$D!CF#$K\1p\GX5+tj?=Sey5!mC%V1?lcc%R?:^1G6paHnk=lpmjKcMbMZMVIat=GP:\W*NW1YW
yPYlR9 WldN/t#/bm56LFP!XMtT>CL@\CYB9utj^IZGHcP*ZK$m6kaXDaW5b&u%48pPJ&CH#*\Q<@J<c\AL=//B
/yG*CA 1BHD@D!wX5^ZR8bjqZI4cX!1bE6RSI!YC<HZu/bkYwwY<9q=YYmEtAWT!>A/4c<\/C\Vn%$iD+BJXIS=
wun/B= 18dMMeAiP\=kwP>GJKG@R8FT5jBXTGpNT<4diT9ytRT>uN&CcZuWu%?HytW#IANZJQp>LZ:#lDXblKyX
AXh>m^ &S#VE<:tAdn*#QhuiGZXuNyE/i4W1h%4mjH8*Whbetcb$8hlDKQ<Yw6eKlZV+mm5VGM?eQ$Dj5YYhhnC
Sa>Lpy /DJjB!&q6WKmC#q4tH84pb6hSJjau9ESltul=PQHNnEZI$?mb1umYeB8=Yj?4W1!M<%LpbTTtH6yiZBy
><eTMJ kD@LHKSw19/\SKk+R51YGqmmBDBM4Xhdpc!+=up#<\:PQWZ!PuYeCK?ljKYl@5C*ap+Jt9Tqa4cYKmIp
wEL@=* 4DTIYD+PJn9@m1@+Q69VKPw:!PAnVGa&6E^N8b$I*=5%N+n8ecJ:?ukbE8d^W:uH!MNkuG:Z1u!LdT1y
ZNnp/8 mw>lFiW5pKiESjYI=R*K$RH?<#YB4W&HCtpyTcQXW<bC+6C41N8^ea<uZC+Qd?b=aiYT654AN*jVJyc&
V$dD\\ i6ydM:Y<k>pcF4?<5wY6!6DM#<T<dBpJm#@A\Xiw=bSL/LBFnEKn%^y<maQ<c/l$\:*PkjGBM#iaj<H$
k4$*!/ XBt+u4=/B8nHn#IZd?w=*N=1J&SR*MLYX>nmDu5t94!AGN>A1pn<ISWGLy4ZFb?9DIkuHeb\%AT*w*q+
u*tm!@ +AdQqqnYEDJ%ALD#5X!Yy?5hnjdY>qT#S5@thHceRWqSSK+PFXP?Yl:mm/TqT!l^5EnmZa\+CwWIjRG5
V^PD?: b!ZB^nwe!QqM#a*=4FEGwtYWQa+BiQetEF=#1d:i&hb8#>CnRFAPwdX?lp#4$cG5+?AX9Z#bppAK+GC&
DZ>VBL :L=eGEKFH@FLc*bck>uM@K6X/c*AhTJd?inYHM<6P%=GhMuiNduHe=E%AH!l94:i\aG$Z1QZ1QnqSdDi
4#dA!a Tt5NbPjR?eTB>9%Z@p6bw1T><CpLCW8X4Ncd#iaWdSdmKM9MQZ:eRqtn=5dQ8mw:jwwunPhV8We*=RL*
*KN4lc WtF>hX%XycPq&hHIYVkNW#M@y:FSSSRlal$HpkjwLqpc\14kM4=KWWebw%BymT*L$Hw6>*l/kuMPDN!5
PS$&qG <RGVW*q6aR>PHe<>qu65$?=Nc!+R+c1K5+ZZ1?@e8jQnn^!n!%dRmG?E/HXjbcADHMR*&HiAkhWyIR1@
d^a#ah kyb$#JCXNp8n6nmi@8npQAM*d^A1R\d1KYbmQu*A9:tdh1?>hKG?i4C?114\etH>>X6Q<L>WhLmCSbR5
TPT%5# EyYjLZ@:FL*wX@/B4Bc^MpkPFpjI1iE\bLLCpKW^hQ$+\Vu/d@dZ@M!*DH^#V?j!!Ltu1JHhhG#VyjPZ
C\$h&$ 188H/%*%lbe9Fh//hi9J6F6QZV!6?:MAFwa8F:IwZnbjGTl#MBQ\eTSHILE+k1DNql<j8=&%A@*@<t=N
p#YDjl YT+BM!?ZMV69&w*peiFTaYE>kAi9Z/1@XH>4CMlnnu\>4j$4jc9j9ISaX+qdwJAhFlWFI<R\IEZG^C1y
P4LlNk k>a#ZI9:y<ie1:?@u:GhJ$!WThEMNmeZdDi69ZCl<DJ\l?wKL%@ADk#X%hWNn#p1dV4KZMBFm?ZL^*Rk
6jJ1qP !Xj=te^ELI=aacC!RHdYG!b?/8V/?&@/RG@\8ETZSXNNYR*mh#jy/mKAC?8Hl/9\>TJ\d>dXq6WNDn11
1S9I$> Kk*9T!XTPwnLnw\TePDQ9c!RRdQGHZbtl>?I4+GDMJ*>@SDXnb<6Zbb:>hSX&J1TS!/ipVe&4XqbYHn^
^Qhtdq ZFZX#iG1c6ihcpn:=5*cp6K!&5H1P^NhYnuj!4JpDM5GLXu1#&aXZ/1pa^6<IhRbtIe%9V<>LuKB:k$i
p*RLRI FKFVe^ZbCpdPJZtXpZ6*=/^h5*Jqyc*AXqp%PPl!6AAY$1/4K/56K/84e&BIVp?j^^ZPP#mA:!mSNpY5
8e!PAd 4\8q=Kbl1AcNj8Ku6qJt=9>CtC^<uMSXSuGW\&DZdIS^dFWP%?BkhX%%hTG&891dRK=#GDD\HQ=1u%#C
$uZJ8L lqElt\5DF!>b8wSq!YDiCG\!&<yGR1RP5*:/cRhWBekdnC%>9e1et$9w#NDHN1%h8ZL6Jw*Y=tlyGY!B
96Nke9 ac944^eYumh=*:#yM8T46QqKPW1@lJe#P#TKT4kpmPZuEF=ZKMATqSI:V+a&h$LN@T!ItLDKiF5#PiiT
1^L1=P 6RGdt+6Pc?Pt*adKqm=Zq/h:<E=>QZ^>@pIl!d4iwVcwDFt$lmWMbb$F#*ey1\#W=+l<Dajp>$k#Gwyi
-A>YJ$ 000072b91c500110334 Page 10 of binaries2.zip
HLYch6 5>p!>XN9/WD@nZqb*TC&VNBEPBhmb4mdN8%P&8S\hLY+:\#iGd^?y=1HQZ<SqG%I6&1qFB$$K\!E5Z\b
MWM&LZ ymVYakq=5+9waH&ENCcYncIGk>Z^+$?NHlJ#LR>c^8+\NPkTZ@cee&^VDkLJ$hHmd8pcjHTu@9LqT^iJ
9b$dFL :TYAF?4bMVB$qG\tyCJAJAQ=CBd/&k$YTElaTnTWwM6N@QTnhcC9>pabMYckbd!\kHw1B&+?SdS*=^#h
SXwG@q qLQd+i=$8X5iQRL5=W9aAH&y<EKX*14YatTTTGt^pQWelC\EZ*<?SbQCieKa1NBltR&e>WhE$WB6:jek
%WFnbD VEtnnFt=^thiRCKMwc8e*e#PHi/8q5E:n&:=eIu^=a6Xb16Pn=tWMnS@ZkNLF5FLF@u:@!I\$Bi?!$Z#
eW$T*? E=IPlh@X?jTu*4=?aNKNX>ZXu@pmQ=a^P^NlAHi+PkpYhJ<\=A5ZKF@cPLNY^Tw@C&DYam$LaT6bdBYL
<qGItC hwS/AyE9acEiYh&Qj*4c$Z<DwN@D%DZ#b4=cW<dwu8L9PTBMD8=weeHKF!>j9uYLaC>i8qlaj/9i!lt$
=l^qjM hHwDt:&F#M#5$Q=T9\X5PauynE<eqLCkb:Qd@jTjn=5H91<6k*>4!4+u@%+q<K5?NjMQ*JGkh&%!8EH*
ERA%Rw Pqtb&juC^j4Ln^+>5uJ1@4C\#:@M8e6CaPeFdLtR+d=PE:<pW5IT6Np%>hM@S@4/d+D5XbBtRmdGLG5A
++m+#9 P?eWL&uCBX?*\*Yu@9yqH?:F?q8QHk$>GuSa&X1cmlK$eL/ZybuRd+FA5Nkjmla^64SWKGGhLPj?<b<@
*Jt%ZA nWDI5QPN1#Y%X\t#nKC9E6Pe5uq6IbB!\BnJ/nyM#M5KFZF5@MuRI=iVGu?&^lE1EjJyeyq\j1HT#=?P
#^YM=I S:N#ZqnlX&:X/5*PmZ@?<$jRJd/R%je%bYXZGT!?MB5#:DIt/GNJt*bVPRA\wIF/c@DS?JQ^5VGHYe@D
&5V^YT IuPISQPEMj9/5ZZK^eGluLP=ubd#pDeptAG%=w:y8iiQCjjGnc8%*=jXAyKwqnFbqjpmmhpcGR8G=l#Z
uLd>i5 Aj9pCYA9Q^wcjnL?bGd/mXWj4?FHW&wyq@HL5wmpyj+LcX%&campj@Vy$<j^LHHIIT#Icuy&h1TQl:%c
a$P+JL Sq>1mDD^=SYXp<8D\<wW\R:dHeCTtNF%\Mk#8I%^Yj\^S8XYh9/IpK?DIYn5F5DPC=cKQ#bitb!cHDFL
\Y&G\1 jceqcdmJthtS:@9/9:<B1kAG$X1CJe+pK44u<NGWt:M:h*iT%aE8<6aVk1&@BTQD#I@1>VSC$^qwhMDe
CCy:pM %:qVJQ&K&huQZ#\<QV&\Z/Jyh5a4cIqDbZCQ#M=<<kGV%hXc*+$\ThSZe<y!iPTTW<ZM\b6&:\d8E%n=
W$1@^^ <1*/S@XR<qB>ZZZlhaNK1aqq1%uTid=5Rq1/cPECQ+F@WD\*NV8ewnR+nhubmTwqPpy8aHb!a>R@aGXt
RVyjN/ b=+4$e/qQmj*KwQq6^^KYEpe+$8\+&NhXR=d\etCm\+>1bp6<pnFp6j=^EFPDtV4\Z:lyed^/iGSFM=%
l<$1pE ICpl8>lw%J1*Ve=?ElXF\PlYTFlqbeZM9\\?6<!Ht+NPJ+jT=G/H1^AlBKyna*e+m!*jh9Je9RWD6JKj
WX?&#@ D9t%M=?l&RGPlZ/LFR4n=E!jS8%&JmWpHek?YFJ/aFZj>%E*N1/M?ph6dSqTXlu!%hY!+16Zm=t!CLGa
%nQaM6 iSkc!!G/t%\6%aWZ/l<>Gl5dhbTdLZtXBYj9YA!1bB/YhdKljA@HP9hFC@$YB6acT\et?=Y/b8j&yKVE
9Q^XEX :P\48#d?MT41k+HnWXF4AZ1FJ%#MpCtT4nI=q#HKJdA!/G=!eF^XNa#<!N*GYe!ki:c\^cDTbG/q6S*j
8j&?lH VMkH5IlGR9@Fm\KC69eQD\?pTLlt+@dEyANJ^eX4@^m%b9&N@l8=WXEdc*qB+%be^5e9uA^yAVHZJ&!W
T<6wYQ \TTH&i4\DCFFYVJMGL:##lXWY!^cneb*CF\1+Xi@iinqKQ!BRiH>w#M#\?>KuMD>K@ki#I=cGSYXm*/8
jQdDXa @+PXWd9J\1Y<c\tb:RPSLYc5TXY=Td8VmuVGwpHAPm^&jabbp&<:/>CdNity@BF@wl9#&b=@KT5+MClM
b^%nSM qq$:QQ!>!8B5*k/?Cd8MP/GwKFVAG@&%MDnaq4JH&XZ/Rw\lcJ+yC/mp*VqJt*SGR<XkjdYn&tHD?K5*
NZHCMG =FiXk&=4P4?MJqhII9h<6yqNKyTlpV#C%h89jD<<<A?J\XPW5GNuaqLmL1C8mjwAhG@WZw%c8dH+/4^u
m9%&Fp 4%^F>\F>%^TV1YFyQu@5ky$Vhec/?5LK/541e=W&Y$H?TWitSb5B9n:*p4CEwe6<W#>mKn#PPHJ#iQmA
$dp5nt pl5^d6??e<hjm>iVteuRN&y4d*\R6jKD&tLT%6W4yWD6I>#c1%hLiF*SCT8p1!Th5dT?@t#B8ZPF=</h
#6#5lR P+t9Dn&uQ>!8yPQ86LVEJ$4taPI5FAYGG+h9VA=eMViQJG=Qk1A*EP!81JZ4Waq1c&Hy*bRuThTRhX>6
wXKFAc H?IKDm:P8X4MJ$8$G$t:pw^E>@!=<+Xu$V$Zu46RdVXbNV&H/WRham!X51MdIn/WCQuN8IM*B+d:+>ZN
>&Yl1Y yRukt:klC4k:?*LBp&B4TeajMGma8ApQC8i48eXEq$?ZFL>Jyc=BDChuL%\8^GCIi:ZbbEk@ayj#T&lK
B?EWhI 1T>V$6AQXIqXEl:*@jDp#T99t6$\M\mVmcPA><Ejw*J9MHjYIy^&qZ%jTkH%jitNY8J:Nie14&c/:h1h
6a<utE 9ep#MFlhiK:\k8>&$cE%1h8QyNQmGS$Cq$yqEYI?a>FhNTwYZ:p=QDQ\X+uVudAhlHe\8qjK!MAMGN>8
Elp=a5 SQ++CE9D%1X<IF$qTiY\LJ&#C+!VpwbH1/4PFSciP+?=@$Ll?i6eyn:#Z95?=ScyL&G^^TTlcF=c\1L^
n*QmyS G#QAqVh#&?P&d$>IBN8X//>CRkin@4m^tAkZR>%S8cWW9XiBnhSXtq9GpE6+Y$QR8$eHC\9!C5/Se#Et
Vh6heN FFb#Jw*>*yF+?e>4qhVylDL9MqtJqRiG^+eH>t8dm<A&aeQ&lNWA@1C$4P<GcJcRk@Ee>WEb=c9maqcW
#k*<1& kJ!:C&TLKW6jleq*=TVB8*pFiXW?+I58$#=N?:*&h&q^qw/e?WaGymnYQ$ctDM<M*?^LMd9n+X=aGypD
R%K*R# !DpA9LH#k#=!NQbn+>WTBp5y/\4Jc8j8yJ\eH4t+PHjZ46$wjHq=BbXX%hWZL%!?NPnRbGde8=i8+lim
JPYGbd tdDE9!e:9?=4%TYVV&huBudJGy5JF=bGJcS<hcY964?YaK@A!FFJyRAGIp5liM=h8&Hu:l!?Jq*NPbm:
ZAmZ/@ K$quAN&<!511P@WZL>h*b&dw&^@i*chpXmbyMd:<<Vy&D1F1btb!=8a&Nh^L1N5VplKVpCn@8QFK*\$G
YVkDI# 9BM/&%leZHKqtQLXqT8p<P>l?:XJ&iShC8NmyE1DV1jLL:AXaNm@hZ&wM>PW@9CHH9:R1MIZTe#PNA&>
!!u$XL n4:XPA:kD<VcnwR+l45#MTH:kHHuH/M&N9Z*AdmahJbhAmPZEC#!FeX\:c/%WS8lJ^bHpFXTp5GM!hWG
B8+>pV R^hYF#:1dhSt6Q:\MF*DblS&=np@I4*P/%pW19DWnM>PjmC#h/^Q&MCR+X>n<ij4w/I?/i<9:ceam6ya
YjuY9H A6BmwQa%>jW%IYelkn?IY4$:t@kmQXPmNPRb<kFeXXXXjejht=tS$jQD@Z%K69k6=a??T$N>l*NwRqCZ
aFjWY\ Dw^Q*y^55y6=89E:ElIQHDBiPRm+:@9/EEM\e#EeY%yeY69*n$??J&AEX%uPSlBG/BaDiHh&WyJXq=?h
e\/ld# Z%BWXVW+PNndtGy1@?Fl1+dMHM8j!ptCb9E4ZB=K:wYhJ&5Gt4mWDRpAn6?i\PPYw49c%X@dlPT^<1<q
^<IK/n bcXZ4laj@MeHG#h?$wVC$IVeWRJL:<#lw#hu%?/p!%WGa%=Jke$%PDVT1M?$Q@#ll**#l$Zy<IcW?be!
SX5\GL F6K$SGEatJ&h*BYjCjjGdh?&QTF8H4hyI!Vhq\P/G*J!pucCHSp<c8Mujh?Z<yp!ce*/ZeDFA>C:L%<&
9>w*I& t+&GEtPX!<QyM&HqH^=p$y1:qL%#lJSFHSbdX<H\y!+hu=thZC>165eqEN66CauANRK+>5wXJMpw*:cT
C\#>=y KnLBSu$AYQ\R#e:8nc5*:yyuuHT=$GK*Y#qHle61lyZ9@@BDn%Ryb<XI#5:caSYaYXpW1nd*##^>&y>T
e%91<A %QR^*L5N\QHk8#@^\JW4ycX>ybTm@<8&q4:5a6$HaM6!h1%h9bQCF^q4X%KlYbNy6#h&kK%Yu\//Qiu<
1hk^#+ \M$j?ba1\Be6NFBjF+e1uaCh9YL$NMb6mGhGJ4+JB:KN5HS6*!+G?$ejZaJh?WHJ%SJWanS*%DhHdW^C
L?w1^$ Hd=!=e18ZYcXN6Npd?9wMB5$tipQj9nlMJ5V=P#+Fb\5=\5lnZ/lEtZ6NHAVbCuGcNu&lHl&V+lQ#D=\
T/H@Cj wBki4n$+V*V>^1Sh^d8A9ZEZT%65!!*b6jFQG*eX%^J86qIDYFNnA/hXcW#6!Bu:XHA8BmMk$$taWud+
%=N@ya KqSMK:M1+\D+Vt%Vekt4%<jHwR:G\e&J&^NVTFtqjdWd1CJpF%MWqbYR5HK8qq!BN&61V6eTMAn9LC+F
pI&Wcj :5FhT1*h$6DaaNc1XJuyQR@9baKpuE:&nJXT1!Q%CX1XCeL1=5t=y$<u*:Wd%$i9*^CZEA>JA#$^kaRF
V4P9Iw &L/?:S8dTp9LT1+keZ^AhE6KmyEl%&\/ZZMce$N8#6yXc@<KP^eZJ/p!4R&NuFtum6hp6n>E1pJ1ntZI
QqI>HI qDjwcB*nT^XByMVR?@Ry=1KE/NZSTM<ET:nki?XKW&qjZ#?$hcWE\Z1qPIeMuqPK^A^Q4#q/89a$NhFJ
VDB?wR c%j6SJ>@MGiZ%5I%eBahjKt%**9ap?p:KE1w4ADV$dyIpXTBIFKay\A:$<VB#PC:DaKPY^>Hm9:e&HRF
T@ej<S KSG=1Sb$mY*^itl4W*Eb&Ec6YeMaq=Yh8y1hlF1F9JG>!&#qLAc%A5P8=5nD??p164\9bi=X<J$hY8lR
c/Hknh WBdLYSA>udR*\5!4w<EYbGWJjPL+9KpY\LYML%BLp1m%9X1&p>m8*dS&#hyVy#GD=&Sud+#c5JN\4bb<
^#n&+M ZV\h^FCt>>^9V/b#*4a1jGbtFbkPi<QRKwuKTZTj>uHN<hHS1>h9mI<D+#mEd<1B#/<WNVWB6auc1>Jm
56j^eX ww5a&qtdm%lc8@F$*TpRJ9<Yb?ep4a:ctJ&W5<65WCM>!BVKjWh/&9jS/qFGJwWSj>wMV^/\plG#6upY
A\NpwA 5LNNHW/aijZ/cNJ!\4cE?ITWA!qG?JjB%6cm+ledp/nyAt9E<ec/t44V8Y9Yw8ZJPbmhjZBu%P1pZhqJ
EWdVjV 8nm&j1JMV8>yV&eHwI><HW@S\$+^aGiVEF?JY5XNEN*yyw/W8QY4w/M*dN<G%<au:Ii1W1/A<BX$!=RV
XiVbGa \hbItTPyBN/NYqMC&L4Vc>j5R66n#D/RudS^%eah8:LnXM#IH/i*68@V5DiJbYTwmK?WCa\bt6/bJ#W*
Q/MWS\ V<?Sty5c+:jLX1>c9\=XAVEeD:=kdQ!<qE=mA%*I!pn=etNPTVG4^dWW8&8nNyWWb&eZE*DW/w&JTVTP
PkCjyS KBZJ/WekbSYdE8lNE!R4KZ<5YMycP!uGwS>J#a*6=wV6yK9w:ZH^SBlda5y?TySNSJncb5KLMybeyaF6
@!/NV& X%qbCTSF9Yc&MS9dkcThWc5&JCpWCltM*N1c@4GTVmbR^t+qKSH!#/MKkCX1dyLMQNua4E&Ip/&PZ4Wi
B!bYK/ 5d56HtGEZJtItwT+9WL89XJtLAZjyNLmE4Sc1*Nk>4K!mp%4%mJ8CSZRG%c8V%LIyI1QM%4d$=XKK9K^
-AwFND 0003335fd7a00110334 Page 11 of binaries2.zip
tJBEQ9 C4tTh/=W^b@c5IXqDlZZ#PmPNHJRE@ENl=lJ$uEwTwqWGYDw1%AXGMP@WTZ\=pc?=TpyKV8>cW%Wdqp^
V>Y/?\ $TZ51NW:FbB!St8nmXAXWlp^JLJ+TtdymuX&E1uY!inC8$aRnI6iFS$hLa6D&mBp^yeIk#HGBPk1J=5Q
%iTl>6 yyXJCPe!$6ZcNejL!n:auw%hQJC>QY1DRma*6Vhp1lR^\JWw!LZ5ZRDKLS1X%HitAX=V<*R:Py4mAR6h
Fc1!44 4R1HyGX^G+k\eFpqJGYXZTpq18!&qwt/yK#8>M%Nc>ei4+GZ@<wIb&?IA69GVlM:Z%KtWET!tCX5XVL@
JCPY\E 4nQY\W6X*JVQ8!p\e>!G/LBXac8m%/$HbaymH>>TC1NT+p8*pl#p!l\!<8tdlciQd11=eS\>!EFn#kHE
:l+5LY >&yqy5QS\E\5m+T4/h%T=FEycmAhete6Jd=lPYPt1hGeCL4d+qc@<ead1<IAVHbPWDNeIp\BnKLA$!%B
Y&dl?k 55w841$:ZZ@/b6*NP6AF:p+npI5Q:M#5hFk%WwRTWBp!6Xbd1K*d\w/&W>1WGpcbh+j6=lVA^5uYS+j>
V5Y*/p >4h94EKTqt&QJ:1JKhuGa6kbhE6l=^IiiGQW!8K!CkI64Lq^+<b8&H*nkiIDSkSWWwQD4ITtWYuZAXnl
a&y8:H 1@kAX:GC^E=MWnlH?ayA5QE\djT1XY@<>4jAqbGcE%D=/a<^99lClBujDVRwqhXS91yDK\9a>d9\i9bB
aRGRc% ++F5#1CW!1T5:DB4?@n!uT^@$1:T:B!kDHuFuJtI$ItLZ:<l@N>@C<Ll1&WWVGk==wXF@4%c/1NLYV1y
Wk5@dC 4Qb$HVJ$TZE6VY<:/iYDqC/SNTRK!VwJiPJdjJG!qq&/BaFL:mXw=^Tq!Et:NS=GniQ=E8+1C1WE:E4C
R*=nm\ n5RWbth?K:=m=BuD\edc541TPykAP^G%+WA&aLQSpGZDy\BhS^+tbGbuqnha464K*pSmuJ4F<Pq5LCJR
%KSPTK =IwN$iE\M\\NZBtc/Ln6/5V5FJ?kChjIeI6LaimhTB8%bADKuWqG8IQaytR4JEBY!qqtJt\k$%tFSFhP
@GcqFq T>D$66tm!hubtYc#PWFB#wY8w5t>9*$nLH1>DDHMb!\?kJtL=?*MF+cw:jV9>aT:ej*GDV5*:E#etZ$A
Sy?XRB 1B?@K>?uwVe><atD#=Q5QB%1*NZP=yGytbp?VccTuE9NnY!id#lApV9m+6BF+&?Zqna^bSZ#hQE%t<F6
T&T/@B J%inSK*/I#>K4I#cpCSdq*\p@X$q<!\Bp/hb16#KV\\15>Q#?MjJ!d+MLb?PCenHN#\c\q1QF^LiV$\E
B9ZwHS Z!MLaQRdSy+\>mTdeNeZH%nN?uqA?%45DdB5?n=Tqn\Y\LJI*4>d?YACZdN4bPV^:HTjZc6pNkc!dMN1
n>N*l^ ^9eN!qkKpuTeGu!b5BC@bPb=bGQJRTAtJVDAXXH@Gy<&KtRwDHLCa<KTWQ+kP&<lF/QdMw/Mn5:Ni8#y
PTwSG/ yCkFAY?R\e/p=#CpcAZ=F:EE9mu\L=J#1ZE?jw*GEu4tq\PmwlLRcKSpJ?#e8Z*u?1mhTmZK4+#pSMLm
#S<8lV :R^Wy8la8W1X+9GM@nTVca1Qb%1Pa^/NZl&GSBt&Tpc!p8FXyMwWZ/I5ybGdRH*aELAS89:n#m9bWc9a
hXCRPS Dl*IMTaq:p5GZ:I#/a1eLI8W<Kjw$48BXT14b<R#$GVZw5I4+8blAd#1DhBh9X+t&$cCyq\J*KI4LI=+
%P\*9M QiPiR$<HnIuM^<ZFLG<ewDk!JmwyT<1amPq\+D1EFZtY8Sh$E=*>uqKPM/4n+u#8qhF6HT\h6p1<Vwb@
w8cVKt W#jLBD$jTcY<wAt%lL&l?/@pY+V*#1kNPe#\MD*5HCpVK=YSdIEPiSL?yiSB&XtqXHPnA*&e$%GT#b\4
E$1MRV +??py6ZlXIFqM6t:<+dGZ:^TSGcGqW6JYmW<ccM^lTS%wLkWtbL5VuQ/=@9ReMCy5uWWPRwtcSqqb&K4
!t!>cB Nyk>A==t6/i8\4lD/aNqQwYqkS8PjQY8#>Dp*?KmK/XqJC=pDCMl5Bk&ylkVAL!?BA/P&p=&N#a%hbCb
I%qVI% JiJ%ppnKGLEKQqiVuLe1XPcmYyjH+^/54156TYT=TpcR/@BXBtuB#6H$dS^LqIq<wtStLmWLb<QRDDaF
KdLSFI !FDYZ$5P\M*aH//=9cNhwZkZFCWTCJyYI?iFSbemKCy%>RQ%Vu&>y/+pP\/G=qYqYL>P^9kmQ&MjNml<
6/F5YN Ca6QHQC^pVJ$DqM!SEZnSAyM9h=+kL+at=4h9TP>MnE<C4=WGhBNWYWkdc6W81Jtq/9QQXmQ4c/8ImiS
e!bH!J 6*IejE9>VVS#<G4m8\HFj$emC!S1K1<aYVqm5Il1a/IBnI$d@lmXAH*6LP**nAC&S:bPDI?GAu!Lk4$6
?K@aVL qltcn6kZPX&qH9eRaAj4/<yKEqqF+N$LYBu5DGFBa85X&&Zd%d!inc#5?@TWklwF+JRWk@F#w#F1jhVG
RM=TEa nS9@+SpbGy&a/J%aJ\bb*FtHk&GRFZ>XmqyuLHIY8h&DR@XA9qqZq=MN<el+PXMkwhWl\uFAZphhl>4H
BZJkh^ %$n>JE6V\E\pC^8Nu=8NVW:n?w$jjQCQ91FS\AJa>1bMHCutp$Y5:&$LC4W/^Y!$P6&i4pF5>aN%N<6K
Cn5me8 eud+#L^ikdaKEa\ADpiu\#iXcHb+ZE1Ybe#PmV^ha$1SpY61dua*@jWju@TNnlL8/ER9tVp/Ep=Y5C/P
iu1m9Q ERc8\X#W/G+b=Le//KwpJ=FFMIRpY\hS!/mXDchYq8nH^i>IaRtLF#SKA!tKR5l5=B1hHi/PpbGSn5?d
RKhb<K SknVQhE:/wCt^BAY6ZR1&FpXD>n+>+HLPT11ZaN*QIPi\VwZA1pkEeApw*X^lLW8Pnw5dNYd$T^6IyJI
w@t+I1 X=<#84XWl9tMqYk$t\t&&W%cGkGii/VL:Zb\uA=<!hI!%4H#X@CIX<DMHHj!ZFX%FRFZ8?11$K1kLjIy
Je1V9A m+JH6k=<$WFHE@i+8P%WphlRYP15yTIMhStBC6nGnw/PZuh9L=DhnWZtqMV*+@:&6:?J!hBm%nuVyWc!
lwMwIF %QH1PHYK$by@$qb\4111i4Dc+/m8At+Jly=ECtIE$kd!KkSN8GSuMnRTydGw1Am+jc=?X&%jTSFk4Zai
V%&!yI q4@%htBw*SH*=:@>:W<u%kFa<mdlRqb1qXbN&hGk!>Qb<mwL#qYCM6&41myKKpwMTap:kC^nZq=Hhk:u
B/^/c< hRXpbcLcpAJay>PJdPNyLuWcm#nP*6DYRdiP*l+R:t%R94>8*dw@@j8@@?pEp^Yn!/!5$81KmuT$>y>*
V%Phti $uc!+mR+u/5+X%CFY$XFCj4pHi<DJB1MpTnDTFnS6A?wDcSFM&LQmZ#i:HE/CbXki>y/&u4din4^ydQ#
iFZZnR Y>u1Q@#y#*<:<ce@pZjZIYtl:qPTMuN8q$**9p/Zq&<:YZDTh5=&4wDh<p+WkLMS\HE!BitKChyucNRY
/5tBQN BhuJ!uGkC&Cup<QY%6nV<\DdZWKtY+6DqbYjj#L9=Ip@4bP^NIu@1XJtec:85eH1ku#h?*qbeQBJY=/6
FY:mC> wDIQP*A8L?@EPYb6a@d:P$nX+B6PhlaDXp\Dl#JLc!&!FVphST+ZS:ANdY$QHn^p6:66MHbuY?j6<9L<
*nPWD$ @G6b%@JJ#89E&H>pKeQR%NVEBHC4<tDuQF$?WEHcXuC6+N4Jk4N=b\9QFXdbKuK!h&^H?iXLQ*CnpXey
GQ4NTc w<i1>XadkI8+Im5H+k*6QV$Q&jdkjp<d6k=Ht<Pm%?jny5?Ch!SEYcF&V5:?PD5>NjcICDND$>95jeA\
<tn#&/ #ht#b!?e9RA*b&j9IGFF4\8Hk?p!VG#IWK1!DAc4pbDNX18X5d%@u&D9*?@ycd9h$NdkcCm*/LQ$6Gtn
d%#N%@ Ic6%<V1D5YwK5E?uy!jGl1w4<uV9b?WdiN\CIJNQ#y+>D>\LlXWqPV=kMePXW8m#cDDanDb4EY+&K>jS
EFAmHe %99k@wN=&N8tB4bbLAS1$J8%1^K#dSWXha+K^>nM:P#$>QVaGHqa>:+/X5eDX?dddLb4qyMukZ9?\5YL
ICNe#1 =\5B@D=qD*FaiEm+tBcecKwnWSy6Sk5!LEi\h$GZdV&6JyQJa4y68Y$B4pG9%S9Mec58Z!151*jX&Y\X
t?b^di a>M#eQDa^NCh1n\wT/*Y1aAMahp1LR&Y@H#a?eKF/:e8uK<1kLk\#auD\<KFcFDRNdBi$GCk<@wN%mLP
:p@p/G kZkF*j9*i8:j:RG1TY?!YHC*YPp<iJ%Y6?&Qq!+B8M=VXYT#DR/NDa%%DV%!MRi#1\@yDNj!K&$PS$9=
kRQJ$y 6j\VIH#l+1*/C?eLCuJ$eXJWWQAF1ymRyXL/dd*YdDWC6lP+h?@i:dud&t4KAK4ia4H4LYdc4WSDa1Jl
we:@R@ \^8ZL>Gb8HW8X+W69\y%\HZHBWEZ/HR:&D6d5\\&Y/YnyeX^Li@QJ$D+a9*%m^jPu<@Pjl>PjVPeL9+W
P9^EBb T5hdJFL?an1\abHD*huY$>N#6+hAW+HbaEMqKLIC%GlIIh#E8Dj1L^iiS^@n1ZQapJ<wL%bZu:Qq=ieq
TaEQG= /8LwVb5E*NLTWqtbu*ZmBA^>Ea?#b$<W9K>W\NBBRkJtX>KT?6+1c8We:w/PNwC&ykMYFudAaFY8ImNR
M^Z=$E Wa?#E%MTE&X9%NeZum?<CiVBCkiWY$pb1mw@L!<dHpbHne%tK*eRdl+QDFEnyQK!MecJ\$KClGK/plcA
\1GaaN yi\6jXqt1>QS&hHY&6/cAR6uk1$Dd9K+ZLWqBuRGB:KJ4n4?nd4C<?jQ\<PDN\i4ZJXRWWFqbS/EBYD?
y>uRAG RtD\t1&!59Le!d#a&BMutKnQun>^Iw<8TmRELn84pGhMlEHZ$hHSaChWp/uB$8BweVuR5cA!G1u9MYTu
WlG&=8 JEI=5wL#lF6XV<B%4twduZh8P\uC8l&$LK4eT9F^#Zd8*IpVj@9:u\paN^k/Q$5lq+lCkpJE@IZd/AR@
h=F6#5 lWcHFP*wcG\\&RpY!aM8awMTZ8YyRAXH\&W+aFT4%jE1ceGJ<+C8w6QLB\t+14KT5uI?eBX5:mbX/&&X
%&?\Qk iYhQuQ*dH&L@jILBAqi*XT+Sl\VVtbS$CI<8A1ICL5e=Gl96Jqm+wdENycC4ydKq&8P1<=ST@$EPJ4yK
ZFiWeH lT+Q5AYF=?11B?91kX^ZXWZA^JeY&>u:QSHH?aA:eiLQBH!CeJFF6&/NmSCF$Itnw8ZM$uS?46uCNhk=
=T$DYX W/dh^Gykd&@Lui6*Y1ye%alWJm8nAY\XY%X=iRYFBaYFII\8idB?aKki!CkJiZu9p*>bDGiy>ekcJ</j
$\ce5: ?N5j69DAJ$=i!@>Pp^#^cuCIcDp:hSVCwpDTt+F1l=#56^9cWjy/8%8Ai/h4$FZqJF!n%1Cth\qt=YWZ
%wb</* AJRPh%hV^#yWQ#\IaFSAuY+hnT9ASB=Tb%FhIMJd@p#A\C*Zy&:hLHw%tK=tSIipcjWaKhBpN6p6yp!a
k*w=\N GbWB4W%LN&ByG*TAeIwlWe*i8/ey!C?w1wJ%//5H1&Du?8Gl?5H1\14<ku!%kqwRqh/Rd<$*bPqP$AbD
J8S#:C d\H8mZN=%<1@M!WVL9Gq<@4=N&:wM!%kc>eDupMNc866AiQ8P>$AdtG+hQp*FayDSWFFXh%kHV\:TGjZ
BS!Mki D>F<RGj5WI1tm&NpcZYYjJ6PB?C@uVmS>ae6/:ce!D6Bq+i=>q&1@NZkX?qhp!9+MN1KPIKk:GbVJ6KF
KmqQ6$ Zj>h\?*iB\?I<@X8YL9TuKKtm/Gb1V=WXXT+BkjH^<iHl6Cl*^u1w1j1881Kp<ke%FBuGjI6?XbhXm#T
8\k\ML l8:Q5hI@^MdtFXSi5>E%QPVLj$pPBt+E@C8H?YBlm>&WceqpleDWSt$PL!:kYuV1n>W19hZlKC?9eqZX
M#LaJ+ DR!Qn<@MnKM1DHYQhk>&D:c$XFhS6$MNupF9RQ*NJ&BhdFd5H^VA#Wiaq*?4#*yQFBIa#N/YR:1TKyM%
-Aj:?c 000a23e06a400110334 Page 12 of binaries2.zip
yK6wH/ ?k#\#LV4WRW5teC>V%%PT#j#<LX!%nlc/QyR=XWwCaNAubtht/ZmP\bpD=C41$+CPe>k!Ae5<uW?kcym
E=pXFw a/ZT&Nl<I+yFij/*j=iIAkN@!W=$mBBLjm>JXmXu/8Fi#tT%&C&*>Tai>\H+WnT%ZQ5YLc9F\ZBh4n4Z
@EBw*p \Qnp#N#e*NPu5/m@a>%ha%&DZT$6XbWFiZ!#W*ANAR%k%Sc$abHTYIP6\8G\/dP&TwYBAKa*FIkn/MVk
ml5B8h =M^WlC+\G!#&:?!wj/&54Y5nSX<HGHANHMFY64k1pE8GJpF*:1ijun/huy4wB9Jw%!AD9ybu+:5hJG!h
&yLBpP VpYHpmIq/ET1uQDS*?YSwpD@kKYB@D8>I?V!=NSME<LI#5HHuAty<udQ@Re@QGl4c&t=*uKuyj!:LI*b
EunT1w \jQ%XJY//kaH^kq*D5DW&uXQhHh%DZW=1m14dHuW#J:ML#mb4>MyyhJI+Ed1nA/Z&&%ljBj=?!<JwXQh
hS>6y: ^SH!bE&GCd$/ykRpLSQqT6Nh59MD=Pk:F/G5::+%YHm?iqTwjuyVNAn@>BQhu<:A#h%nZh&iP!mdnpwd
@%N@9! KtQB6ZM&Y:/PQ#a1mXRdZCN8>PBdI$PY?C*$<&iE\Sh$:a$hna&PSu5Dd8B4:&GGJkhjSAIy@#aLbdHF
nD*E=& adMAF/B8n&h$eub&:mqM@hNV>Hhn5HaZdI*cmZShYXuSW5Xh$!n+e#pp5Yc*&>*B/cWSRj=?jwLFT?mM
Y?t:9H Iab4c8@wcG>5hDa!\mn/dR<i@9CAHH!^G<Djjb89L?jKHZ1>Bwmnw\MAH+Y+un/F6Rq=?5pEeZcniLbk
\#lY65 @?n8+QS!CV5WHK4RPh$h4kdX:$YBhCK&*>JkTqmd=ctbneB%N#eVMGTXTaIt9k@8hF?<&N%>B:GZd:El
+8$uV& c&m&nk!Pnp/PaJJ!iRdB?TqBQ=%:P98Ekt1$!>ZT+ly5Gi\c:HTdWyZTCQaYh$t5^iqw$M6DlW9<@BdT
iEaMVc ijdL^SGda$C*$i$i/YnGpNLWmNTlMVG?Q>^9/:%+<hc6m>$aW\CM:p?nek<NV$/Niw1+K1jL=bteAnLD
AFI+D# yX:/!imRG/mI1pF*d$hDYuJMBL9PwmSTli\kq+cGBBL5Ru?lKCImb9QiXH6:l>9h:G!!FyuNtjyW!K!N
d8huJt =yTHD<nM6:196<DPB4&i*u\?/l/duJ^1NlkMSt8F\#M+PV%L\LP#jBe@m5VyHuPQ>Zb$tDL&Jp5npBNB
Fp$5K? iK9tG:p<XB!!hNHClZ+LaieXwJ8eaeKW:Y#tmp1yV>bp\4@6>^@?<QCHN1A?8jnpa58*!QQ<XVyGS+et
Tiqw?e y/cdXKw+6e=R=HANnw=QA@Myi$#QVML:a&\By4$%dY?!jLPEelMp6FWiISaLj:ia4uC#SLkmImbt#>=$
SY&Z#E p:$SDY6SE%iWa6d1NbyW<AZ5jjB>$9*pF9kCXW1ZGFZV\5:WyJMP\<a1ki^!peCRNth=!uAC4Vj%hLRj
14bNRP N1Z9jT<tAy9pQdte4y\wFwe6Rl#=Ba9imht<b??ijSptM+jlt%aa6G1Nl8!M$R!+F+H/yJ9+1mSlayXc
BGN<!u 1\clwaqSP!%/9/9AdGWF=dH^!YqC^u\+M#XJ$&p9/Kcu\eEA*m^=L?a>ca^ELJcFl\XAYI8CX&#i5&jQ
L>yY@F *4*:W9YbbkPdCk^cFZD%^QiH?#@elZ?jkG?=LW56Y@\:6WGhPDE/PnLT4GGHuip+l5:1eHwG^$aJiYb&
t*BK+* BwRj$@JcP:JA/6:pQVGd=b5BDqmMJ#J^YMB9F!=eE4IbS1a6NbQiSblJ5Hy$Qety!JPAJV6j:L+FZLNB
WkEYjL LZ=nXZ^KT8LWCBSwywQ5Mn4#mXw#G$h8Hy8ak4Ctmi%IS\jBJmeVZ+LhDC89i$8GAitNSZ/Lq4\GI?@>
mqw<:9 eG>115b56y9bY#dyHjZJtp#VZZL9@X:ka46n5^uW1\J?y$+^yw!P8y&NH&>:>%$mnMbHy>ES559qHl&h
B^QILm tGKw9S*6NNMS4n!GwPW^WltA^RD?*iJF\AW5EhdwwTy#mqdQZ!&J:Q#kB&#*H=^p8JWP5?H>N>=aqYI$
Dc?>bM y+!+t=9TQ$@j68%hi559ZiQBVI&eqZMmF:wuiph/G^9Slb95*&YtcyJJWQIalX\tphG%NYu$J6#NBJ8e
Bhu?VX uPqwS4I!c?qmK^4!L>IG\h=98*Q^:MYL%<5hSic+N>/RGi%G5:8=5S*DY@9?dZSla9Sqi8D1DV1>tY9k
XXwkI> Pl1R=ctiNZC*VbbWnRcXZTtST&RTla#YJ<RkHLBwmimhQZ8T>!V4ucQ$Jl%*ypG4%c8$kDZhjen+6qWC
pqAy=L 644FAY85Z^Y6ydWib$e:yhCiu5@V6T16&YSGJnK\t==%\TdMHLi=lwb!D5peJJSK&FklpTqAGacYlj<!
u&ZDd= +Ji9@tdQu5*J!b\dtYBtcwVVIlMmjQX&Syh\4=&:j8=Pm:MB8NGe$>ulhHKNQR>yHcKuQh&iRhYc5$CQ
R<eX!D ikQ&N$5D/Aac$:F^Fu$YHKj?GXcG4?8ADiDkh>/J&TNQdS!btpK<V@XB$YR+P+5mdHjL!/>Z*/GL%#yV
SDjR&C %u@5dP=whuVa&??^FQ1\^+:664*B#K>B<Jhw$i5J$*DNuG?&biq$hM%ZPl4Q$!ZGEypwJCD+6V&d>!Ru
Yh5#^T N+^MVAN+\5%^bny6uJ$XTZV9qqi&wEq&PS*YdhHt=k/u\<*bY*t?D+m\BdAtwBw\uVBkNP$YM%5&SGPy
Jl1NhL R15jy!Sa5AYwlP/T6$Jk=^npndVdHSPQy^=QnhDX6i^thB$QiL4*d>>Gp>Q6hn85KdJwK<i&VH5Q4VI>
*cH8<q iABa>QtRFc!yW@N<$V#41ajFDK=mF&JS$DZH\XSKlLFFTGJE4+c<?ye>i#=L?<dW%6qL\h:whFDhl\N=
pTcDpi &Q8*$iikd*J^?4k\Jb*kb4XcDJqk*HP9y>&WD6P\GNJB#ZnT/@VcLJSLk1WLJ/l<5D:jAqWeIZqH59t%
i/l^/i %%::eM?l6LSDcah8*&=6c?lADGD4/JtuT&%hF>X!5#L5DRqqCLyTmBtDqQ&\*b=ywM^1NN8Mb19Fc8G+
elTiGV ek86/hG$AL1+b/ubeV^quDw?D5BmTildKQcda>===<MQQ\Pw/XB4c&6dY*6dS^6k&>6=&IeQ:\K*1*5E
+dnSp< #a6KFlAwweYLbJZCaLCcLhCikW:ANly6SWW&#wdl&hHk8F%88bb@#ac^:Q%<Nn1A4XRSu=maEKiRWePM
:%C+Cw aw?+*jQlP=>>einL8%?&M6!&hw4/nyEHXAGBC:1huTnmk\:#q9AAaR#GXZt5ZF/kB#C6hNNJ\daTt/QC
eDkKlC +ZK$PD6dPq5e=bYX%!yQX1KV*bH*6*^wT+ZlT=&TtBBQJ\qHSL!%Yd=ud>yuZ*#^^Xh*:>&:i?<8N9B6
aZhZyD dG@5AF8G?kQw6uS&hdt:HFcXPCBRLJFnn5LwcC6AX&:EHh>WXDm1ZPnpZF$6Zb%hdQZwHL>lDD>SeFKu
Z+w?9W X<tB1%ZH!!SmAG@iDDphQuVw!/?@=yeE:>=6dY66dIiLH@lR:><F&%=a&eYy=PGLRmT@X!dVy4LSqkhR
8D5ZhN #KMXNH+:IQp:Zdm%*GG\b?q?69BE*5tCc@qb<tT%NpYqqKG4ZBG^PZuQb+ePH@u!!/@9<dn*:4c&N4VC
cApInq 8V*M!BRu4Y&hZi/JmScuVl+bECCTwl6KVhepc/k:41w<B+T1e+ZuC1>n8+nHHjdN&a5Z&P*5ldQu#=+:
6l8=?^ iR+NKK1d=tM=cXt1*J8<>:NDS+=<?hXZ>*:t&&y1cP?aq>VD8#&Aubka\*TlpkkZBWRpy?:L!Endq=ye
bEe>P1 ZX%FX\5+Z*n?QC&KZd=+pd>n+#E9ZQc6$RG+W1>Q^4=1NHKyInuFqJtS>6tlR+VLCMQF4ah86:c*>##k
bP%qcQ &h:98h6AIV$&/8akncBF\il%$\>>qyGYuF^+pd&6?^KB$nP>Q@W!kC>e9PT:$ZeZGPF#6uI>J89W#E!N
%9<R\8 Xw8EbM>I@R#AZ=Cl:<HIZ:eiM5HBQR@ainhkEXP>w+AhhipnyJKAJcH\dHyci61?=NSLQ&<MF1kEjAH*
Dy5$S\ m?^h%^eI?AKQi>JtA=m>5hF8NhM15>&$d<@i##::>NNQ9@n!!Fi6Z*/HCL=:6?eB9>/N#N9c+P+ht^kh
4P9yd9 e%5%lp^FRIlTuy!MLm^=Z*L!=j<Q4A@=E1Fi8MTMVA/?CHHqXhwetEI\EDR&wdFA!&yQVpbH>?GK9:!G
jJ%u@N >I!M%j4X*j9*:9jR5A&!Ju5DFAXen>QMNZPJ+Y@JqblXkb&5?T><iYV?HhhpcRI59FB+F4h#F!9QuV^=
XdlcZ8 $8y\w>SSI?npmuDnMkq*<?b*Z99N&*9T>l\/hJjy/\Ea>:TnN&45yNb:!M$XYV*8ypTbWmcqjmW=ti\<
+HF>#k V^n89eDD$48jd#&/n96%5D^=Et4Hb55*&JyHy/nEAytna*>tVjK:cQLi?<%9j4*u9dSDh=t/&AEF6N66
W#?yC& >k:*KLF%F%tLQCMnyRpJpKME5Q5\\GSebqK19*Ty@tL>>jyHn^/NQcJXnnF/:l+E&4YV6t8&!uIHeK*A
6hwW@y ub^GS#$/+ESn4mSlJ<9j&:QuN:>=D+u!/@pDCwTK8hBN1KPDuLtwiYSw+PyB5%LP#J!/N#ZDBG4%n&+N
9jjBV% QSwcHKJq@9?!Va%NnLXa<5*=N4&6HDpd&dRbDhVW=PQJWZiV+X&FZKuWJH?#b<>:i>::+w59pTq>!cP>
Ia6Hk% 6SEb!>%Lw\na+4>=Skd/D!atKytNW%QVM$!HH+&Q$Y%5cH^wjHS<dBK*1VEkwwpht?l!Y@Q%KIXwe^^w
6HCXCG IqKeA\\ahm/Kq<ymqCyN<6:*9pqLw$m/P\@dk#4i+ZSQnHcN8kihXyZS&R#aK^8&KWqT1cu:$nJM4iqn
IQTFcQ lAZEWWVbGJ+tGPnaEE%nE&MPNnSTe?tAqA\yeNVw\PlIe#PuXKChVZ=9##jjwBb>nR^>n$Ia1iNI1^&i
ATEM\@ ha?Mn4k>V16BbY*GWP>yTw1YWYbG8pyN!<k+dBwdJ>B^YGS\bAlD?NDw$NBw6<iN9u$C&W&4+h5h>J%P
y^S+b6 #tlILCy!Py8dt+6T6E4q%1%AVaNj:*=NG$D9jhX/tN+N+S=^n*4eH5/kXNNbAyn1W%cF9=85&bicpb1S
95tnb\ RemHaiVlwaGlAj#R%i^!i8l6*ue<LW:P=kJFwp6L:kdP:ZR/4apGw<&I=5mP*q!n&jQNi>><RZK/^?N?
FhFPcy jjjIpdR$E^9/*S/*5$m4WHHNH5?Iy=tLDu5L8HA6!KdB\Sqn+$Min/8$1KnImmSp4K1?W*>><I:DadYa
CEqA/H $RX^indwaE^$Pq*A%TWc4Wac=nHNj@QNN=>?iShX>#+k9@:!1!?QHD1EGcpB5P=t6\6pXRcu!<N&Ij/N
S65*qh AIqeA$$^&H&yi#PGSke>SYbDCu%+k%yq1K/8S#F1eXSc1HY*Y1mlXc1&Il6##M:bB1M%$$CV@HhycaS/
awII/u H*RJ>559D*&&h$?1HkM@taa#1&qut&F6h+jVLFwWItP+!Pn:MNL5VaYCQEXYuSwdJph4%jX1+N:ldBc>
K4IL%p tk+k$kYEtaMB#FqVE6Wy=ySMYyXDW4#4C^$WlK???QVV9Z8TW$%&S*MnaIG1NSh=CNZqenawR^cJqHIE
@$?6\^ P\!N<R/nXQLa/JDHbW&l&VFSc:AT*$hw:VqP4>MRLknVlVS%tYa#?mF%jH!<NnW%Ni&:R*eyFdQ1>#ZB
m&R=ZK 94$HJE\Y%l6d6ZRb8!KkitB^@Kt*RkLpqGWwnJApkb<<NnVp>4m\m/XPb%P#c=BY9+jR?#p5=m\EENyb
d@hdc? DbD^SW5*=d8TtPS>KAFj?uIVle:ZZ^%/?=*j^IC5!YLH*tqn5b>ty&6kbHDE=iR5Gw*5h:JMnt8$c%I%
wn4\kT ?%mdw>u*CA=&W&KbHJ$eH=<eHS44\w*P:dAaXIDVb%yMik%cc:$&E#5e<^<a:hNc:</npycQjLbu#\1C
-AWkFA 0002d6bcddb00110334 Page 13 of binaries2.zip
#j9^Wq yX@KW6L:qpDYM+4w>Lk+5$cnXWV9d*cQnLn6bl1m\Va=hYmwi*RIKZiT*!l@nLtScN\eNVXAdYl9d/j=
4tSek@ %=Tl#<naq@\j/NGQ@J!dCQZRy*9pMVHKjbq&#N6!h9$SHihm5Ml4Xp^w=t%^VeS6a5T8\e/uwm/p$wWK
TC5B^# JmcubmcuJ&eIh^LbC6$8+5C1wetbVeian%5dVit6>5QwWw=<>VM5LQ#Fun$^%Qq<9E?VwhFR&!Z>ti*w
h+mlMD WDQ1l#qF9V+FFYX$etK$8SHAGbtyyk#WA4/+#VBeEB+FZa@LRi<*$/TcVCmt>^+\:Nd&8/%Hnl#=/8j8
Me9*Fq <c5nl#D+!yQ%h98?h&Q&^eknSHShPc*VleTH9D9R:ETIc4X^$TpnjGIjcVS4Mp&bccpbhHpStJpG!Mtb
w&8n\R eeCPDL1dWRT5bn$6BKY*>%D@RNZ<\X$/y56uSF=Pl#@:MGb#5mc#$YVQ&QMj4:&&apYEJFTy+q\DHtV^
!:lbd/ $eFtI^&=$ecFS/h+cCqkCwR#kb8BND*>bIwBk!pbb5D6KTym\=p&m@F6:RG:i\@8*&Y*?*j9jjWXFRHE
+?X8#h #8FDu<HEkEZPQb#?+c9@68VXFSESE1$X?hdX:K^%Pp9mw8QX/4nw5N?qPFFR5I&+#bpt#h/>1Z6uMcEQ
pIG+dA nZpGS#!$>d8cm\!KTJqKV:AGp^+q1?j8X?mSD**b?8XZENVh4#CYwI$DKEd6#I!MbQR=i#:<<N>?<ew4
bkdKAu 9%/^IqTmMDmhSi4*FhFmtVk5ZKaWl!*>dancdE+yc1I#cKC5%FSpLF4pHuXXPc8eFT=pW$>#$j9C5FD&
RL$#wL PV>/k$X9MypPw%><G!$n*XEFn4#>d@@&>wh:Nmh9V5=wQhKc@5=49@:%4%@>6%<5YQDKL$Td^WKltuP1
c8NauB \<PZLk%eGlRRIyMJF!>eGK=Wm5QFck/n9lt\?=C\btit^:6en1IKG=*kRnXLHS:$yp1L/hhkM>55y8S*
l4#=:V @9KZD$H\CHLT&%<e8j9FZ*:^!1@j&S!VuNaD^>@>+8&@@Qi@@PY@@?KXBR5YLHqLI\<KX*Jewm^eLA^e
lpWtIY G8AZKFcG?!*\C%NKR+JE<b!#5VFVp<yT^<#$%NTkk\M1=$AltaKdw%>jS$i4hBcMwQw5mYJ<>9t#b:PQ
Zi$:Sk &>Qjj99VhLRP9@D:lTkt?VB%=@jdb=<@u@u5$>GBkWYCX$L/B\cE+e1Btdque#N^m5DF@tH>@RQ?C@%E
:^+J1L yRQD\#I65lqc\XTYu/Gu5T+Hb:X!Dpwyn:%i:@b\lVHjdLDp&>DL1b@@/&L!Md>?y>u4jduwFj<X!9Ti
pDM5/$ l<Ch+u>Au@<S5IA?w8FFWJDc>>8#+j/Lh6DX%\YLE8qT/*KNF9tY8BI8+t#R:dFbG:mPpb/iEjy\mjjF
nu8ckc j#dc4DcD^bB9Hj<9%:D*9lY<kuD>F!$S^^!?l+:%Mj9wDj/HkR8Zmkp*eJ*ZP#Q#pu%GlZ<Cn$5@F&5$
N8?1X@ T9V6KQ+5R$NKL6RFn6c^Hn=?TH<yMV#YaKMDhAa>?#TSPdW=$$LZhle6YiEEdwC@@/8T#^BWD?t9b*=+
ElyA&% mLF?\&@yK91<p\BlEZ1StDp\DA=ljBjRbi@nqKypJe*e1emV\KYnCl/Zm:Q#/^E@E8/dpay%/>ayaqXb
nLS:*m ^KXY19J>ApX+IMPqa%Y@?QZdZ*%>F/<N@Qw9i@dRhh@D@Q#CkL9aQ%!ymSEJl@G>?K%+@GBlE9&cSCtZ
YWJiDT !Kq4%&AAl4I+F:c1bljSjenn15YSd+1F+c?H^\/Rt<JC%S1XbB*:?Ah^LiH/?:&!kJDd<h14@1<qt/ab
qSGEt? Z:>@b:lCyWatJEM>&/e=RLn5a%CEEuGITC=F>e<$EYHC4ZXWNL6:H5:#XT6ma&Mn\+PYmwq8WJAaXb#H
*>\>=G DR\u9w5DFm>/^i<Xj@>T9Bc<bNt?^qGi:&?>*8iLF\5@>tq^NHMjh9\FGTNw5Z@IG+8EMXI=!qEt+Yw+
Gi$eV/ X+Y4%8q1HtE#P8HP#e*P%uH9C+PC/CMCqkcKXYcqkqR1C=jW$5>ub<e*LIG1CXi+BItCQk5nVEC+L@\Y
DBJ@iw m+h>I4eu:+9u9+&n/=Q=?RZRwiqWut?pquNYPK6e@i/j@e69R?8C\8tVARKZm8anI$+X*@@##/Q>Z!uB
mjIa?K p%Rwq5YSQ>+RLH!D:L^a#LSa9CJ=^RyJC5\Dw<%F$@Y/@ELw&qHJqClVp/Mn>X^FBb*ZQVLQ>\WjGTY9
eRli?p 4!de^W6DXD+whJ&V@@y=kL<RZ@6WMwYcBB8&\I>\q!:hVy?1I^GGBL<c9II?=IcmcH!SRLDAV!TF5qVJ
:a#RKC MQT?=QBw1bt41HQY8V\VQq#VZk9:nJk**!SbBT$NnH:=@QqLdIqcLZ:\e8um<DqE$LNZjpY@=T\6Jd4\
?E5<cK :$LTe*m$nuDnqSLJmyka\q%AYYQ%\wYLkmSTtpM%FMJ:^Y?GK@VPm4ycn&9p\R<QCdh%#*i>^C9:D@SB
!<jG#@ REJpiLFTnjJ6mI?NH/D+ZS\piWb=m#u+^S#@/RqlC@&B?#^FVXk9b&bt9buy/btpb*@/a&Elau4:I:wk
N4&:mS cA1=Ww^NbZXX>d9/QTMQH9+IG/d9Tj*PkX?6&$IjMyWhmAR9FI5XhH/btuCZLqwcRlV>@VjQ<b?eRB<y
IS9:nW E<:Hd=#GYPy#T:QJVluqqaYB6H5!Kj5<^N>LMJ+yp%QZ$h8iWl*>44y?n*8pk@JX?y:*&Ie?waPuV+BS
=M=iY1 \NKLA+MCA+KYlmq+99/Lca<Y9:wmhjd=m^jQb<p6aj=?RVP#M%TQt8hi+NZuI/b$\q&+aFHA:LP=PRAD
lhh<Rc XW1uATBFK=G4%bwGB&w?c8AIn:6ZV^F+@YL*V\^aHAVawKCkENRc+Ia6DknC/!<CZ=Wp&>&nW=MV6Bjl
eZG5hn C@%lFqFkpIJ#N48dS>wdG#Ma*+YCX*+Zn:qTJ8Z=a8nHaGlG$/9ZtD4ek=+?VG/$==PV5@?phHP4?%d*
AS^1yK T?c5^Elb>9Be5WKSTQahGJ+qSe?KSC9iBT/6QVA:?!<T!mKDlEw4^6?P=w=G8>%ENBaIF4&dce/pT&qJ
TlcdyD I8kh9ZJaG6*&:Rb$=9dPERL&VQ/4?uVV=hci@Jh!XK9q+<n*ETI4XwlY^Jk:SmjGS^p8bPB>?X#^B$%D
<p4Q:a I=*^*N/IAb#^ZjlL4h%1%mkmjKjD!iHjbFMDuWJcj486h&\Ryy/i@^!6u:1j5HYh:4tjQ%XqSt%IuQ@=
R?*/:u <=pI/X54SG>yuTMVaE^%Ly#!&*P>*6VR%64V*6QS*tCmD$D!Lu4%a#6GbkQ@@8WICmWpD*bthM96&?WA
*Sa^XM ^qk^PnM#Qj*+<WS9d@iVd44AZHi*b*L8&dQue#NDSuPKwb@%&ANcmWRmn=CI*qLcZbk@!A1qEmG1*w55
je6G#q $?*YXuap4BYMcaeCanIdG#uP#C:TJyHT?TYw\&*&65:P#69q6^&>9YP51Y#8cG@9/P!hIF#\9VZwetE1
IA9n>t 4<DD!E=FXMjV?@$p$llJBBHttl*PWem%TCGKLmq%chAJ69c$EnBtnIt=8dt*qIS4N/9pEtIdKyZGTJYT
W=T!bh n4d&6p=HT*q=m/P#i>Vn/S9^NLe*6Hj$h9PGj6L>!DXa=cy!8CyKZZTPuIFPR%VI<ChmJC6EIkq%VV4&
Ri!VJj mSY!<DC^R1NQM^%8JXRR64j8?>%4!tR6jY!KYTPXS!KMaG=<DYl9dGlwcAF\!#XH!<Tkb/Vb$>#e$NnY
%kp!uZ $V5GPSQlS>$w$Ll:ZLXXSWDYJec4FWw\nwGlZ^XJXK16>F+q6XISHScmRAPXebmPNIA6:8u@kiHJV4ka
LQ^:M! +IGJDK&RT5WBjw*&l5ddXphLT&X=iZtut?#5cY=5IE8DMLu+#mQZHbint6=Q+Ky#XlBnBW!NJADCIeFI
I^%#II >q9wDTa16WIeFmb?F!%Fi5blp:*X*6wG^ytb1Zy&PwhlK:6+PL$>ZlK$eJGhM>QyR:d!<p1L^hLlI6lt
k!mPQE b!Nmwdi4?^GF<KQ8P/:1/1411441811/1wwKYBwinmB:Sal?GSI1&d1Fnm:F1/LDkpKk6^l=<4+MDByp
wPXM#= /6cMVD&n!/uRZKuwtIbTIX!$eCH*PYe^a>c%qD9KLjyWJ&adVQ?NnR$huX$V*h$M?M=kT*X%hYX%Nb$B
eKZk@! YFFSaNdSbYaa+amREGGwXLGF9hFDHBaRLyckp/L+6Li*p=j6Jk=nA5tK=ARlK?T\<1KFcJ\@6%k^Z>?&
JpyZB! YT#w>b#Pbme&u9Ba>/NHn+n\ui41e?i1#^YeP%hRYFCSb>VJJBJ^yEV!uqkWHCTMqKymqY1%RlaYF9cY
\D^6tw SIa@VSeVciZubqNnm>96=LS$+SI=4YqKR^blc&w151bptnX$1Bj#Z:KJI%nP&YB*hHd%AyPR!hCAyi%5
=aBCpn *5t<QIQ8jZd^BFARCWPCRmNnXYy%9DI8jFYaYCbSTnStW$Q:A%wQd4e*$HF#V/NT!4RMW+kDFm$KYDk/
R1M+b# $6#EtVQyjC%VYwatXb:BPa9w5DDZ$Nnb%WZAMHS*6R?%+CRD#6iyKiMBX!IWw9Zew6Mc%Iq^/<NZmYXK
6EeaCN me4e$QdA6>VjD6^S6:6I=R5m?d5lm\JCA9!tMaW*N>uNtCmlla#pbDpeWkVTnde=8Lmd6@ThFl:+=NtV
@ePKVe RD&bq&?ka<GIC4481VDwVaZYcnSpJ<lYSajLyEy>a\M:kHV@jp>:R\e6Bu5+hyF!!ndlm^cJ*q1$<Q<F
aP*w6^ WE5DBBRAAkAIAAlXdTZbpiZhW!+AALbLAAA#AAAAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9
LEE>Ly WtX#L%N\dGF#cFNnetXqdnE8at%\:Jq@4P9pieej?>k>4*%9PY>MWtCFt#jtniT+&:n6YM5tiw@nPb46
<qF:P! K%Rja>MCk>=Yt6RL*GyV%jWPKDnBS$4CyQq+!V4cd5%JuTp^SYwuaD<E:WG\cj%nEy%/NhS6Xcy6wmB6
<Bq&Ei P&Mk#6DS!X+j/MVYj*LQqhD?\FcpKNEu*@h>*8j=Q8@4tDe>iSwP4%Q5ydHZ>#pAp:$+hljZ?di?@:@Z
l<u6tS a4GAh/>*>q1>FDk/K5m*4+%jYQ*e%/?cd***l1*jVC/G@i!*lp@G>=T94Z*1K:ii@jJ6F/X:c99/:K5*
AVb\nw jiV4Z/#>^htd@9:$#5Y\>F8D^=N##@*^yHc*e@a8%:ka>846%=@?l!><+ctu@?ueQ>=*:4/L$4*!t$AP
?^MYl$ kVQAHReEF<iiQHu+lnB&=ey*KKh1q<A&+j!SYTM1wmMASt<qy:X5auH@@68Q*H9Q>ehj9Qj!#**+*5@<
SGuQ#d =c*@>6Rnu*n!^<8^$4ujP&*4R5&?@Fe?jQ1G?@>G!:=yyM8X^5yXN>*1j5a@@8L=K?//\@&Ne%@Su9yP
I/EZVH >PTT:LG:d:@:up?n^$=ie@9y&&>w*H#Q=lQS+<8qF9iip:L?P*hiM:P9?kZ:k&h8/Q:XI>&hd!!Z$6!I
@IbC&i ccQ4n@@4?je#P#>#<nDW!#1BAS#QeynHd!dqJXnIP*9^q<BijRu5?W6k>+/Pe46Hb%jtq>CNhw:P4q$C
e/GRAB Y:&EMc<jPXb*\wNHZcQXQXn5H*ZA</P#m&lqeaC\HL%=A!aIAyk8qSeH5Lw+PH=!dX:hYYj*tT9QHIeD
?P/<Pw d1tS4P:D&8JkhbhbluF!=!TR6b*n5MP5jyt%*aQ1+8A>b\4hp\bn*<9a@iX$YX/5L^c<ehuP#$RFi$cI
WLZ^LE n5Q#*A6L5V5F8:KD+Ew+HQM1a*i+=jI^k5Z/kw9YhwyaXTP!Ak>GB>^T&XIFPKkiHG%=V<HKj9YIt@AH
PHjem< aGX9:Ym/dDG+*cP!LClHbXh&+j!b%aM%&GZJ8iB&4tc%5S1hYMw=X*e=q6D:nF%dSI8X?Tq+aI?^T/*S
LYJ+>@ Y1G*8q?F*iw#*H<X:P:=k6%hKmXZF1#<tY+X8QuK@AF8>$dGL8Y/%ju1A6d&tP:/Y?#<%FyWZX&GZh>l
-AE?Ij 000a8a8aa5000110334 Page 14 of binaries2.zip
4jG<jG 8t8:VQeB^1:8Q4k!Q<F$q*L5>WQhPYQ9b?*lj>m%bb4@k+X8hX+6&EL*>bX=qdFXYI1>@IDXIhM>Z:Au
PnHGI* Z%@bYbyh:H#\ANany49H^4^&\+69/y=cnn&@B?6R/C:c<:Xji9GlR4h/+%L5jL?wJed8Lb+=bA>%q>pI
&R%kaY eI5j5V4ab\/\i@=ZH=yj>6E*hbhmajGjm&LL5Bd6:1&&=!i8iddR*Vq^+%K/4!?KLWM%atuM&P1##^/!
B%C8jc J=bmF/\Whk9h</5Q#c?8Q9R5!+*=Wt9E&Q&C4i:5*5B$V%Wjiwc^8>Y%yic:aH&B/j/IqR<*9*G6@e#<
i1V/S: ^6X95:SeTui*/KLXB*i99t!qaHh&:%@>#wtXucX$h%qi\94/@MTJ/tJ@4V*j&%9@&uL%8%nM8WWE/!!q
yQ4u4I tW*95*G9:%b@h#ujYC^&Xk<PD@^F=SijHDPAQ:GWV#/+mNb?+t9e@G&NbmtY6c/jayjVZX@A/Ki*qW8!
@YIN?@ d&5JF/&:j*S&<jaGePaud>/#XC6d9H$l!WYhQj+*i=Gd!eZSV&G4q*DK1F:C+R?@??n8*i9@&ZXHt/8J
ybkh%H XmIpSeq&DBIlh%PIMCteF9Hk%ppIAdIG?La<cKWXaVwLlk/BlN\=k9eHNlmTMBK/lw1JKAnAE\MJ*Z!E
q@N*TN W6N&IPtuIZAqw8X?P1Cnwi?:M>@ule*VHu#<Jh=XRmJlHpHMG$BMGmtt\aM<B5SB^YuR!Bi5RNMHp+an
JTVhYG 86QRd+WBM=mKB@\dHl9=$PAId*Na1REYJWAqwmiwWcPKRV6PCM$c=L@+weF+aNh8Kk?GnI*yPIHKF$YT
1TuX/\ Da&K#SN&G$mBAVF^JIGc5ew&SDjIISTRy%hcnVLbe4&/P6Q#yASqy9qJV\cRDR/nBNp5ZnHHw\/NYlbI
AZtKkH 8mMpyFeQAW>A%*Q@%%&XQmwF\!BqR^%HwH+yM?!l^?Ie<TapHRQe\ppWLAY5ZSC^yh1S*kSTpReV1Ta+
L1cClH bdtl8yuSwRIBXH?yBCB/RpjXEQ8A*dSJVYmyKp?#H6EG\:wl/J*?I#i:948l#Jy85PWk\uqM+8F:LX&b
C:EyPC <kqGZI$nHCeyERdW$4y^\4/XN&81J$eSJ*+/C:Ip69^P&6MXA+DyE9KDlH*q<WdWBTwlDEJJeABjWB8Y
1P1%K4 JM#AhwQ?mP1hqyiu9Z4JH&1b:&enRcm^H=dY^+wh^J1AXR5m\#ItlkEq<ih86SVmkb<NipVpkB@@iJD=
$%SMj5 6mZX#awdP!!<Zcahji!9Db:#P$aVPKV\wCABSbEStunc+i1kNQYlb:9dVYPmb%5q*@ctY*4KJ55P11S?
m6&LJh ^Y5XL:WSR:AJ8B!yw$nlqj\dE>H8kn#SN+nIE^l@4^FK%JL$Re9hwB*Ci\RpcD=8!Cl61tC!^a&Tem\w
PTmu^% ^YQwp1$y1tQk8N@!!Kd&cN8%@THKJ1SB?^9ct>&8yL@S>$!hRkI^IwJ1TAaaKM=%yS*EwE\cRTJ$5BX$
pTYE!G @FR&6p8NRAtD9tY\$AC%RCe<6mKY#VYiJ=w<LlHbINAMknaiG<lTJ#=8ww>$<5Ad!u1L$HEn&AIBF@>Q
FVZ6WV 6WLH*m\yQBZATLltVVKEmPj%QuS$B\tFL5RD9%KuE=F+%tBdHy11Y##TBF#BjMb:qyFAE&GlY^bXAe4h
RqWYhN dwVVmnWt&#n81VulyGPTE=RHub=n>4Sl/CWAlX5$NZ*K1RMl\!ad!Mn8G5YV/+yyn^4qQ1w*hA8&A9>>
SyTnaj q$*:ddXe$n6t1E%pR&SdBGImX9GDeyMe?&hwC=VuRm!M6>WI<cK@VW\:hdRePFHRiN>%nL^qhea66HHw
ip\YED X\JPuZIK^pAa@nuFVWlTaFYMEP%My=8/W%K5<Sm!\ec9eTSw$+1RX&4B#M?tTGC^Ewyu>VX^k:DVw%qt
Q<5bKL e\kJ&mbYSHlie<1Y$/kkym9:tJWYt+a!5^&F=TSZ=FYVykL6apHTA\iME1EnmSh+JbDwhDN6+nTildB6
j4WVBH BhMIDbJWNEM*TNp\GlTan/LDmDWdB4TlLMRTCBH^85C^#c^GB?PkwSk/KuGj+I&b=Znqmb@wV1*+6\a#
GejZwh 1p:=LBFMJT/ZPA?I4/pTV$ct+6D&lmq>!tJ8Sm#hw?&\RWZXCZKH84mQmnkj/kyd<1ltSCbQa!aj+a/A
!E+uBj &C@4int>4SET8aQn4<:T#5n^4DS$qc*TYVJt<=W+twy&Aw1ABIw<+H!51SdtPMZSw*mdDp*SH=FP+>/e
JqP9bM S\NXqQS<Kthb$EN9dRQ%D1icG$*M%aKPDSd:^ZlKdIB/R*dwaG4LZc%#&$Vp/yLub*uaeyTbY4k/pS%*
=Yt<S< =ZpK1I8dkuki<\+^TyV=mi1w68tNR#Whi1SVjmK*DJ9K5b/uanaLuIC^mBucbldbyl+L^6addP=!^aJy
+9lh>a u:tZXC69wq=RJ*!K6<@=TQb:yPGEwb?cG<wGG!>Q$kH=n^KQnS4GK*5tYCMD=<\CFahay8d:4F1uRPZQ
ePk!Hc B&XM=Z+uDP6tNym$AwH%LkE+/hWM>?X8p$jQIawqbRI19&tA1KC&XKhdH8i%/cMBD6#I$>J<h4cp&1Y#
$&hci# dH&FJ5*M5#/4\bykhHDWl6T!>i+WK*bmn<8?&/9ZA/Fe8t5/$E6%5XWQQ@b<QqRtQk5Y^5Dljc?ptnFG
\HWm8C ^FJR1//uEiY5Ee@m&1Sd9t6#yNa/==G^dmSwiNiVn\6iJkYhwlbT!9>!H1P!%/=JGJ1K9WZh61\ICjXI
<Qeta: 8chdk#VwCikHW?<Yc/8%WR<ii%:dqQ#9Me<lLI?>P#Y!#hwVm=^b66QeISyyE1E6m1y1#6RJEH6<Ie8T
FBy^R4 1+kt>QM@QTN19y!!qmhIqAy@1QeFYaNaNjB&!cu:@R:QhmBqt>uVIB5pibiVetdy1tQtRj:DD6/p4K$\
%AXVhp m&YhaZVFkCTnVqaDSYSF\dwenYqli/JWc$n%P1l&@dGRbGmA8A?E4$Ym%?*@dhHQcqTT44M/LX:nYNlJ
:w:ma# w^/\hE>I^FGluQl8!*e<9e9*<6tGnph?dwc*TWm1XhAMA$WeIc9j%dDYTcmR>iNBcI?AF%q^d^l<N*&E
#Wj6FA 5yqljG&ad:9VmkCD9*8%$@V>imkW9e#t?=N@cbytIEIE^KtFhZtcJRa+RpY4$dGhJcEy89tMdBmbqn9Z
JHnyM5 =M^yWckGETmW6<t^q!!y#P!%J5iyt:@k<eD*HKdL8a+<1hRB\VE>**CdJa/4*?iw^M@/%udSGBD$6%@b
Semubh alPXiERWPk#=Vh8lI^nEppZVaDC&R\>Ndyubk!^*>T@@MJ@b*XKnIS8kYp$X!/>tekaEG=8PR@<kaFGV
+dqTMm KlSKcttDVtwXQ\Ki/TaV4ktG?XyI%R*ZV+6Cat:ZIu9J!KF^#G819&G&t/^:G4BqhT*B$X&j/npEiV/h
#jQ@>I td4XH##6PLbMBqcj?TSy%:V8$^@mE<A%*A!G<mCRicPu?IJT\*pcq8y&XBdjG<+$YdVG?QVL1W@I\&19
hLDj=p lpFqG/NR@i^b#c!d1CX*ylud:hmF4tH%Y^#N5@/j8CNw/LuqRIp#J$?Ehp@&dN>qa?:AltjjNtAlR&M$
?Q8$e? DCaqm/X?%BZmWwMk*ZEWd^N4pl9/Pa<=4j!?q:QjD$4M:4aMWEnKV:k1HS9^GI$@:/A^!%JFX+&cILc<
=HckQC PQWdhW*6R#u@jm1\Zn>/>IJD&u#wTDw8@9dN6PC/HpIE1iK*@dB5ld+S&dn4iRuQF5+c?4EuPl>wBNMP
TBD1XJ tw1XJ<JRF+cK*#dAdqKyCX@K%VFH+@DXVVJm&#t=*BbKuNm\P:c9&QcGm59=ld16dR9i^??cy6/&uuZb
F9AKej jDpMa$%bjc+LN8CHZ$=cA1eH$Sk%Xaw#6cJMHDYNB@^a#?&p1j9C<EKhduKl+t<Xb\IFha!db=aNc8h4
$jn<+q hl&ZYHHy\ll%HVjynpcIDttD^CKL%XTJ8/Z4RnjWnX8!tPuYTKSmWZ!q^q6h:ijV!IykGMIW%Gcb/DYy
HGaPXR EnwNy?tT/VC5%$:PTpJ+IYCd%KHW1BqFYuXni?8XLk6dJ^>XRGmhlHwJmiXtEMZ1mKy8INhpV5<hFlwZ
AJhVKY @XE?chTSuqq>DIy1W6dm><\w5hu^^mAE<kqpVd561:yp!#$4VVh<I\?DQNDa<6Su88@!nbLmFW>!eF8p
JCn+nM *j$B=jq^/mp>V9p#uPyCmZ4hcFV!jN*KPnHQ/VP4l>PP?euReRmTZcjPjCQt!\dWj58IIw^?65iCB*e+
KD?\9l uEe!VqShWSXy8>EwN?#e#ai?SJ5+#@QBkLb1qNWCqNlS!8=<XEa+*61w9=\a%qPK4+6G/6p+cZp>%:Yc
B/PJt# F6Nq$!S?*L\8>H%H\aPWde>KIC95FQZjdb^94PVYih+Qn#lap9wkD5PJAAQ6e8nDmPVGLq4a?bbiD5N^
??FHu^ !KMGunum&dY9I1?VPwB$ZeXFEL8AE&e=a>=&b6\CHJyWW\iFPGPPMZQYc<YGXkLpGp4VBuD:!bF*dWC8
+DPj:8 A>6NAE86/yX4GTN%h/j9NQ%WhBiL9hm>>:/H=@*#@J=D<u:EG5kc@6KXAGQ$D>9bubtCPnB1RQ9/+GpY
!k@%&= lYA:qtaXt9Eiy&ZT5ep=>ELabM4c4pIa4N5Q@e6%y66jwc!%y<pI/TP&hIB4wpcG^DtJ=Gn/u?B&=:bb
*@w%y% NZe#SHTbnFBu1AaVVb6+TM@R*+H5^V4EHZaWP+FBQneuHHLEX9Ek8H^P!$*T6>pR+8b5a89J!IILhu%Y
W@/D+y =Kwmj1X6CTyhC?Lt=Z4HnDXBC!F/cYqw:^q+QnYCKwhJ1wAa^Hpu!kMdV!eyQ91+c<5QB^Gcuk@qGhTB
#yM5#h +XEXCe+Aqm!qiYVA&1K6:GPP?q1cncV88K6u8ctJLMm\iLt%?+k1I!6&R5a&pXPFpyQ8Ep5i!@<&EIpD
bTA>u# TFDGS>8YpV!YbVJX4K^yQSlc/CQj=HEZYtN8b?amV#^1FaJ#K4bI:9hGyCyN/uu&$Zn%yD+\hPdcPNY1
*nWXuI ccTk*keb$JM=T/*eZ*P*bMaRw*t/NFLE<pinD>9^8yFD!IQqB6HY$CWnA<e\h5kEShujdXep!8^5wYj!
+Fm>?q Q\>JK\14>wXwT%?SuBFP!/48ttB^<dTEATYuAbGqYL9B6nd1@FwmT<nIi>dR*9*!4E^pMdX1#nk@:99K
SJ*/RQ uBLQqhiGnq\ZVXp\\Gc&JBIVN+F<kq+/Jq*pNl$>qlPdql/!#y&#c5GwI9qd%b>VMVXB9QFWtJt5?^ua
PW&QFd yhl=+9yAAhSKFBSap\/R=?=hThin/W#u/abXlT&uan1mhmmFCjTSm\b^H&h5TlQMQ=//<MXK8VVplVtT
dja\\d DFj&CGWi6we1PA#HN+5/n5/616JJ&cD8\Nb5FQiPD!Hyu$8dDAZbqB\6D&R?Ga#Va5NQd\H1*S#/ch6$
qPZYiE jqqM6\8//#AkG/wwp&CPG4L1J=*$B6aMKQGEc/nIIT=S@4/6==YpDk$l&Ca&ai%>y><H?n9&!l1RHltA
AX1b^m ?kwcPc+ibAcTimmI=T=ipIENA<J:u:B$RNC1K1*\Ge?LT^yd#IAYSD$y6IM$Ad:G&#R*AB^!^Hc+c^PL
BcF?B+ XphRa#8W4^jC*HGZtKiLwmSXpYm\#*1X?ScT\YhaGiyAZWaw6+c\lp#P<kJNw&W*jX=aMlPdIYpS>LHT
n?<66P #98J1<M?W$RteYtbbKL$$wLJQXA*yIQpGH:c>bt:I>^l1BnXQQFFDjY%TH5P6WJcH9pKcXC6A$VCDCqN
hQ/dP! q9YBmXGYmYAmSRN=klMe*^K+M#^ncdphwM94e+9Y4JI<C*tKQ++JP5d%:FA&&T!KA/QuT#J%>WyZ$=LW
>p@:!L Z$XNAYN1+>PF!uuWiXjDQT$/H6qp&M4KAeBDyuT:k/P*Ab$h8H%>P8\:Nw:un=*=mm#ELtFLNH%Qj?#?
1Kj#kS N=1H\Y/EIwDS1aLe^J/1@Tk!&K:dqiYPGbc&4qSITW9Gd\Z45TFK9^KkKp\<eHu5yhQ!PJ+d%dLLKXLe
-AGGdb 000e69b224c00110334 Page 15 of binaries2.zip
^cSj$% RNcZuENe!!wTSau!hdALeTLZK\&<p?BnJ!wt/dlQu%?\8R+EBn5X%lEC%#j6najPqX6FBAbJe8!XQ?4+
VNmJdl !K^K@@K6ylqV$Y+T#=b>h*6?N6daaK!nNN8cATR=MJSG%lj*BiS\l8XPLBjVIm9Byp+iZWNeB*LE&Zah
SPLF$y u:LNVtNX1^%N*<SiCPS*\AQH#**:nWD6/pkQ+t4ukGNB=&dy?>>5Nq*\SdRtkdL<#t>?%Rje$+H4JItA
E#!CEy hR?#nPc8<:&@8iqDT%6bX#4DNG1SdhuJ+E1ywcmZ6p9:4J1Rq%=+cpAV>^kZVE<<h%\jFGF/@SM5!#4E
5h%ZW> pnE!6XRWcKjEicq>bN65qR**iD1*=MEu9yD/PpmDh#\^V#5BPPZeCE%c=d+^p5A<!\GjG\PC?4lLXyhC
T&Fjl= Viwca8N:LLZu**lPd#iEqlnaDMT/Y1bcL%AGZY?WBjB9ZbS%pN%YpnGNchK:/w*TpAmc$Gw6&&i9C%Wy
+Q#XSP K/APtE9G<KM!cwR<pcNAJq1p^CA$P1i$&RctlM4kmcmD=ATkaitwcQ4X&:LBAGC/AbL#VH8qEGwueK&!
cF+Ba* %=iCbal!8Alp:nBY?!+u>YXYDQXTdID:W/cq9#&Q=wTX8RZAVXb@mmZd>/eLqCq^D$VX\p4p:?mYbLB4
nK%T6? mjZ9bpP\^h^jP5#PWQP%Va<594RBSwK8%%=#W!ZQVG6Eyqk5w$\CEe/H/RS=LC:L=JN5G\Fw^TLyyj%i
k$tw%X +Q==WI=hQ+C+JPtuiDLwDkhJB:p:Fmq>BWtGKedp?G\pDQeuFABHt*NVjG\?R6l:*#pWh>\GTEYw<>Ha
ScnH!? NENhP*YnTaj4qSJE^?P4PynSPh&Y!XQnNAKVI:=I=p^P#<*BKMF68hSSpPmFmwPBQl%juqktn$M4p!XF
#w%YbM /nGl+PQbG/qEBHENWXRJN:hT*@#C6E^*nu8MG$pYXG:p+c<VNSRdbYdDy\c&mNddHi::Tb?XI8kR1I*d
$qqTlN :kySVaN>tWeJ6IKSTkVuDTw#N$$me/PHA>VkWJj=l!F8wpmpym/IB8^#cD#1W:$#4Nw=EBMDQb4wcG9J
JyQu1= \8ylMi$P\eWBuRc/LPy\+DIWSwuDI:H8GKK6&qqm&cVWZN5lJM6Rn<nEAQ>hkSK+pViMqDLEmwT\1I\l
bFkQR1 c9W8EZMQ+k+=laFX%4Ic6qSNE8AZSIw?jIawR*umV44MXT&a<qaY%Q!yiPbLiJFwbik*iMqlbEGQ/jk<
i+$R>n >CJPn1jNTamwGmGphp%5Du>@amXkeDDSR%GCta6n1&T$DYVF=*:4LBKclY!5hV8J:^jI%&hI\Ci$kSWQ
=B9yK? @NhlEDVPWbIY@GNDpp:SPRE4%GNTJFwih^lpyKXq9p%Z<6F>aeQIIc+&qe#/!euIT^An5SVWH>1hVjXT
jb<HZm y@:<KFk1y*t6>wbB<PWmGlnVBeR%admuEp@5StqD#p\Jj!9P\L*$uN>/?C&ZwHBJYdMRA!b&Hq8$ld/M
ilPuNI *WZJ@SH+qEFZh/V$cB9Yp9aKk9q:>mNnADM4Pj9XX<MJWYk/%+=^@bKS*6kJ4JE=5MJwAV=FCYSEWF9*
BE!T?t tbL!P9XS=\jdSwt6<>:1E&<ymnRpbVp/=\l+HjCtHluJ1LTVu6iH*8@LA#tn$C>PZ#y4JETZ+ycYahpN
aH>pHL ^iM@c<Na4@u9RGE=El>#*^hc$A*MwwHY=Mi#VTZw/W6T#PnXn+mII@^p4S9KSALm^bI8&W#MqkPPIEhp
Qjw^nl !<hn$$>/18tRlAJ9DFA*CGYE?h59@Sl%u^!:6R<wd:KB*cay18T<HlMNDcM/TSn*/W1iLuKtL>a\H:Ce
:G>$NJ !N15TX#<qeQ6eelq/Yq/QMTjGX6qkkSc?1%ISl^%kRuVVXywcnm*/Lqndm\W\/l5WlXJ@A<Pq6\:Lhcu
lR\^hN ZN@t6y@nqWpS<BwuFe+m&C9a!a$#Gua$cmlLt<JA:E5>daIMk9n*w/KBpjNCNeXI!RDa?!lB:6!DwhTV
\L+584 JL>1q@\$^uQHCemcS55SAH>1YTpLJ9/e/B*6Z/tDJ:nF*aqjlh8eI!N<nKeWNdyQN*R4Zumq^hwe>ID5
XwNQm% kP6Rme:yBIE=5*p+apXnZ1=tYibtlwLH!A=WWQyChKIlV&5!@*/1m=:YPNHaaA*!+/GL#MRK1nqT<5Xc
lkp<Bh C%:c&V&KYa6&enqVAaa1B&$qHYy!jPZFy+c!Q+%uK&$D@a8Y$G=AK11QEpp*6wZB&>nY\j>Q=XHWD<^h
bE+L$F KtI8BS8AR8m#Y&CE111nn?FTpYw:JmIEY#XD1VNpPL6E!%qw4XNWu88=tSk\LdLWWQqy#S:>^ma5Nl&d
^PXh?= Nbw>CSBL+=XhbM*$9XtJM1Mh?XAL^ya1Scc+hDT\IVjEu\Ry9&%H+9ZanD\%qipa/kb%&F4YmcIwXCBB
lZXGWH +y&ePYpTGMYcYaNBZ?&pyBSXB1*=#M%$Y1im&jJjVAcFq8AGiX\h!#55TbA%NMEmMNmQTuNn!&%8t4qX
uy4e1u D^PT49#XKPXuCStPWee\qFL^#SLmayGCP:IKT@Wu#NVnK8P*pnD?F1Ri4Z$khCBRG5m!hQqYuRnRIee*
9S!b!X &6XAIqtBiDw^VcdIM^L+KDn9Yh*^W&b%Zi=<dIVqIC*LKPG>HkAbF/%56Ftjtn$X?ZnuR+=<a#CIykGi
?lW!Rl tBp*LEb#@%da%%u#u?T5YG#mXyT$AiL4ZtIJdej?A5dZ1B$%hBAAZ5Y!+qyG4A^/!FQq^kyaVXttdR$Q
S9Vi&S @KPnGpi\Gk@5G&tyJDT\q1DKRWhbtnwcEdT#Y!kTdFyqD1H#HuDiid4<T^V<^6mQ$*dP^=aMIL6^DDB#
QI8Idj >AMb#Ry@\EH*@c!WM^Z%TbPh^^=aBykE=ibDCQ<%%$y\9hPEP#RbY#6@F*i<96X%X&p#R1WBe!1F8Q=w
u/yEiK ICQF%5q=RGnRM&MFm<X4!H49n4TiV*cnW6a^DDw*EuV>?ZRVSn*TNkW!J5RA\NAV4A\V*WA4&aL%yKn@
>JTIN& my8j4^M@Z!a<meaD5^Rnw++ctZnk@#A>*8b:n!6F4AJmeXiKQR\&bqiV\iT$m=>N>ajTP9FyYdP84IT\
@&DRGG bVV^6F%Cledp=jFMJklna+aCap!WjqwaRKZB!8@:i9h9*PnThb5F4iQHpBP#FwXi5lE&cyc4p6?iA*4Q
Z1::P6 eDStP9A#RQ>VRiJC#cFK<1e@H8mhd>G1:5Ym:GJ=+J!qG>LP$=a>w/ZVMHE6aQ=C#%G8>8K6#tWXAW/C
P1/ndS R+$C=@i1WBQX^6%8p4nhn4V4QDaT%Rd/*L1&XbXRG!GXy=:jJaElV>E8MGJ=18mp/=h9>jZ\68MQl%*@
aWJ!VF c\dG8upVmJ9FXiKplnu^wP8S&XliqEWVhenetytbBKKjb%Eqj+$GHT?l&$4\KN:Pyl6SJF*H6%8^i:>u
AkqiV* ljG/RKE^D+!N:q1/p5E*IwY5&FbQ*?=?j+q$\Y+/upQ@naEB@>/jXmLPe5N9cARFhn!KcC$6%5PyuDC:
GZle8V YqMEFpPX5^DnX<YpR?8uKCDqtt^#yV=4\1L&S^8&@XP9:<HeRd<X=+&>W=TBLe?p*1k6pBYMltc%8Bp4
A6NY>w 1BR9i4Vt/Vu&84=k6YMQPp1%wmaN$@b+4!jAM^ycmlL*mX8DM>J/HS&$>au*Bc1V@6W4/d1p8y6l6k5T
LG4L\N q4c89StpVXHNqRcq6:189hTucGZucPAuLnCEHl4l+5wAbYQ?5lCXYA=DR/qQ%&A4nWum4==$Hb8B@maA
\WjE8* KnM@WuJFX8bcMyKIwpc#VLi1RpiL/^>=!><SASw6PcPqp@Sh*?A\I?N1dkjw>>wSJY&S>b*S!6LLe!IN
HHDX=l LIPRjPnJ51!jQ9eGb&Ib4u5!j<1tJR$#Iddd4A#bQ!4RZR<DuNqhcH+bl:/LalMHLJPW>TAa&QYL:<B<
FNS>#8 <%$qp:VV1Knc%yi+?@!aXQP?li/FlXmtecAp^I4qCb9nwPkySn^RwCHNT:>#>Zbcn5P%m>q&=jR>I^Q<
4VNEC: :KQdyehAj?>ZFCC+qEPE=yL8p$AuPPABN9wS/9b@<hYj*+Dtt!qV6DqhWE1j=HL>IZ%Cl!wy$H%RTP+C
!\#E/% n9W>m$kTLeNqLC?1I1PTndSHQ*u%Le+>C?Kc&*XSLV5A$q#1p!%LS8kQ<!HPeP$SBeqbRD^LMXFlBNnS
@8YIj! W=RQLkn?HE@ZKcDH=nRj>9&6KJt\Z^uVYSpkH5@T6GAAiCSRDd!PB&GM#\FElmm&#Q/6j**9%X&cnW$y
6H>5TM <a\bLW6Ec6:BC=>FDhm*9k4t4P+iH$yBldbSiuntnpB#NyIpQe4>:>#tlwe6%D5h&nWlamF8uAdn$S^<
+?^8Zi cFnJbX6+%4F#eh^JC:6^4ipmSC6h%!t/Qd#&KdEJ*CFcQ#?dY#\=GmYSN^5!BVbDBWFTl\PhBiBBJaK$
t*Xuj6 KhNHCyH6KELe*#*?B66Y$%qwml/GNj6X#e>YWL!iBeCK!:KI!\GbhjZCFEp$etjDVyA6p!/aF#/<@NL^
h6QtHH VLPL%q?a!p8!#jykTGW6KKMAYb48Im!SLdJ!GYeI=61WIh*RbAP&*8mqN&=#5wnYp9t<KjtJ+!@Em&IY
&dkhFL %E=!jBbmPw&*qGNqckW^1Wuk1py%Hw#/+G\TT@#qyW?TuhYXa@8G=pe\PMBpQcX$+6k5EAwWF$6IdEMF
R1@EG$ G!Cymaa6P:DM/c\H!m=4L$E>$*L1V18ZLHtuemjlH:q6tHc=5lA#4GteG4%AD:cB\:yt$W:nnnw\\^YQ
X%W?pp !?b#V@uktGN=wCiy5nNG^5nlV+l5FWZA\Cma8nnLNp>lR?wkqIel$mYI&>i%FMNWiRHKGbK+GB4j5I!&
c%WmyY ?hmm=l>uNqWbREWmK\M>JR@iCkIC6NEuhbyZPl=R&8=GJKlj4VqQT/md=E^KE:Iwlp>h8=^ZW>WjkYj9
>!QtKL t>EE?#@4!e8lLGu5WkAFE&6/$VZpTc@@1R%Qh@:MV9#@I1@F=H&Pj@&NW:X9m5EIDeP54:8n<:iSL86>
eNiQ1< au?=jmWwFepcPqHdAA4e1LuDknB1yni:bnpanp4/njj?A+wN<T*pKn%=mGZ%HRb&Gu4y4a>9bbSX8Jl=
nKPGw1 1lceB/jmb6L4whuWj:Xnp?u&@Ji89@ZJ1DZd5wG+\XmQX<=hJE5w4Qq9Q9lQq<SA5bdtdGVw=w6uR4VN
=K4@6i 665hQ1$qTai:SZ*&E$?*E/hB4m9uR@Dwu/::BAwJ9<Z?HKE5Re&W=8hB%L#*?k5:V1ZI/n*9ES8ZnF<T
FMC<nu *&DdyEed^Cc51&5l8\5iX:Ld?5PP:5e/5uC9::phR?&>e:d^?mNn89t+WXK6#cie@:\NmjAdSFIWpuaL
k4a<Va HDw6Y\Y=dh^tEm+%9cuCqS/%H:#?jaAFqa^/cSwXe8&b+9wVeSEHwpE$1@YpM+l9H6@8HnDi6WHiayVq
BKSQ@@ Hin$whh%*uu^Jm6ctI?*YSu*!L499ii65XZ%iIA<+HZDN:Gq+yCccE@t^Qw@V#pWcbLwm@b#9@9G$>#S
YeKFPE Y$c9S/VRhk1qq&@Hk&DNLWTDBEZl!qwEeJXbiawC1cQC%NW:pqEPGYZ*9m=EVLWM^pATiy#N$??JdiST
1aueYd AX\upL?a!a1PJB^nhDhZb1Mkq9TyqdcpeMdPh/><C8^uahYQM&Ib$e!i9=?DM/kyiQaq!d1kT*pJEjX+
YS<eG! &$jHSIMjXuE9AbbKQuQ@hdH8+M1=*Jcb9?8u+u@W1V^&LkYI6yqBa=CnwDIdJH$c9kMCRI!5#G%K\$uL
SJVT\^ !#i?Z/hdMwl9WB4ASYDnyX&pY49VBlqC6?\&m&\pIWZPSnIkJkCdJHh^l\CZPL@/9b8jL5P5ep=*%4Su
GVD!6h FpLe=y+S%4>TwF>/DYD>?QJ>kRcYBTbKP6/cSZwZJV=QmCm99Qmy:&\WdC&lpbZ6^6Ej@TiCcW9ucblZ
=ydKy/ A8pJ$^wFRcL!nwYA%<DJ=>MIbR5GHQ4+&jhj&yanTt?tT%CSPK#b#dba^=Djh*@tL1un\?GB8!l:>u@h
-A>cJp 00068e4dc4d00110334 Page 16 of binaries2.zip
acG$DR 8j4AIV@B>?FdwMynXZ*cZ4n>\p>akk6D*Cb8YhatF<L4TP9ZC/T>@ddSii^\!QaL:?Vi&%j@^iEHJ?yh
A!6l9: 4E<dCbPNj+N>=idnL>Z&!CbmG$8EY?6ud9JwEipkYj%Q:N*Se+jDbt>N4^*8ZH#k?Gij=a1KWnDcX$aQ
+AG!65 9QdCh=w<u!WPK!^cJnKuRpVNKk/RjG<9u%<<HCb*NjN\&F@>:E@iQuq$V^DJCF1APdyBZ**<ci/NmHGD
N#SXCW ><h6Y*u<<VM!RhqKS<d%Qhi99Z$%*^i4?^jj9Hnl$j*XC&?lQ6IuV8>WQNNIb%?=DZCHp$6JIH8Z\pm<
$X!ulI 5p8$ZBwFKLn&D1I9@?i@6>4nB?>h&X@MyQ*JB*?RRFpy!Q:Pdy\YN>@@!XFi8\bQyRHhtuQ?ZkHhckeF
eXTJ<p /9V&SuN6>eHJZc8@9*Duw6#ejjdmZ^!Q/!$=F\DB<8ZudnmilTNS=w6T4I#!>5=NDDp:*wdaI@pkZ<#*
\+lhW4 ctj@!Q:1Mi:Xd?pb>GVkuR4K4e@\V%Iwm/:jk8TXqIn4MP$#hRVFhGp9i@jL=%b:%N$@ePimJN$:Pepn
6\w#8: P<<5jZLy?WJMiyjEL4Ktt1Ah!ptSPKidQpGkqWl=eC@l8@JD$:9wkb@>\9=m@6D?=B1W66/X5ecjh1=<
KB&Rt& <^J>wjbwF@L4hlJP\Ly5STK*DbkDCDm<c#&d:hEDh#=:=!1/6u@=tt=PG:lp/@J6j6y<Rj#*t/\jhDkD
<^w8Ej =#6PkFW+KRj1*<cX8*i%l<:*$kN*%Q*F!iGuF?@nRMG&biQ///jQ@dnDH^j^A16$8?p=H#AT?#yLmMaC
pY=#@e $Q*X+W&w=a9b+e+D<Q8mCnX=F?FBuKqK:L@BL/?$#a&#$ty5Q11Pb@SqJWRbt:Pqn4B/8N@j@@ylhdk9
/XZ\q6 *Zp*%NXBijciDlNR\c#=*JW*49\a%*<kwlyy8>>8>JIuukhWZQc=hd\Qi#l<d9@\IV<eQu9e=\6*$eq>
HS^LSi CXAY6aKP*@uia?qIjQh5GXmTQ#>%!L1M/QY#uWQV9EH>#8H\:@eZD59nZ\@5L*:&nuX!k4R!K>Y$iQCj
?VE!!^ *W!dD9?nY<SjaQ1qlmat&T==YwMhb<eZ<A?H9*nu\tF!PQ\R/841\#?YLy=pIHVIF1*+1>eVnu1Qj&$P
D<%i8X wq^45>F$S<8lj>9t^p*\C#L5:R@li9@D@8THh!>A*B<eZ%WBl!\9hm/?6&P#?Q4965^aT/\iP#JnR@?!
/JKb#: TK86GP8wL?$j?1>:NNQ*F*=+@/E:#@:/HiZpwY@mSLb/dMA@\eqn/HnEAFJFildF6XqAjyP?<i4^@u=@
<6HZmi @<mdh+?9An=<B@4*=QPHP<<?<mP!H1uSX5E9*KT#!Kl=w4SIiKPmR*cPDaPTdy:9Hk<6>^ji9Kea\h$L
8!RudR h&B8ZB$ijub!+a=pLnJ%kqPa#DiZBH^PH?TejldMA4lJIa!Wjlu$RJ@AF>&XpAwJP4t*9:k<9Hu!\N5E
m$t&Zd ByS6/bJ@*bG6LlZ4cw5KTKtYeIQXwBCjH/p/R5:?pb@iB=i!9@DVp@@==6Zk&l=tHe4Q$V#Gdj4M4X&$
CSXjM? <LkdTmnhVw8<nKIFEAn=$5>IABkKtVt?yZu*pV8j?@c?K%>p%*Adnh$IAR>Qd?\MtHBm&GQBlCiYJubi
MP&DJJ 88E5/a%WtPPjj@9Ct>e!YQNDQ$$i9SNJ+iVp?PneWChIVe$4b^8mqdRIbGSVHC=:dPwAJSw*GyKB*8$9
V4G%Qj @9Zl#^DcQ@Tc@jBiS!a=$TdpiA8!bFIwZw@HFwF/AC@&6WYt5Sub<VQSQ91pETDy*ji89Zb!=!Hy*4Wj
ASK$:^ <Z@<JyL>:GWEJL<=*k>yqahiZe<\*bckny$QcB&#DW8/8Z!LQ9NuEdnh*8H\H/<iD94leG9?+Q/1>IS=
a>t6$$ ItiJ<ae^Rn5WQ9bP^SV>HCl#wH=I%#\j@p9e>p9?$YN?9*k+9Q:5+RA6WVN?=&Lt4$+CFZX8+$TZ8?:m
lJ>&?N Jy8le#iB8N4cXJ!lbKhC9B+>p+HLSlBZjiS\kJdapT??jVG<LL@e6R#:/!AbSwS:>%5Y?K^$cMDV\KA8
%S&8=M !nePQ>*^AQdb*l*85kT?@uBjJA@j8c1@Q#/JF6u$=<4^!iw+9J*PMe1HI/9\6!:^Wy#+R4^R?lu+M1X#
S#MKQI iGXn9@#P+Ny4D9t%6!>P1HSmYES>A8aSwyL/S>>PS+/ZunM=maM@byuXkmHp=Idq/Cnaic:K:hka?9H<
wDByky F@auM&N:5tNb^4F1^cm\RWpRb114B9YwCVbY^/l><Z^!PW5CbCB=KlJ8b%w!6wb9l#mYVuD5h*$Rj+A5
5WW\ia =W>+tm1=GKTT9<M:j^1$Rt^w?>LEHmHkRkYXbEcKNZl$yAR+\1LMAt%&jJBWD=&#hTb=Smql6k1DFJ**
h9CnBS QFm#\XFXRBqwK?+q^?P:blA8GtP4d^El<lc=E<Wc/nWHe^t%&#T9R*pbhEIYW4F6d&D\X8P8JcPw>4TA
CZ<Wn9 1IymaTRFPEEV9WP^LuX%/n#NGuuZ\%QXkjI9*4Xwc<AB+&^YbmmK<NnSGG*$mYXd=*G?:dkwJ5FY#%AR
HbaalC lhu<6AY!bKqHhlHbkMaq5M>??+^ES8l+MI@GR!AbBS?jT:C\FXL+CIhy&QEW*:kTd?$&u$S%L/mSqG1q
wJyS6l \Zte8Bn<\yNVDB6wX6ZY6yKpd?NEXc!muHkERDn1B>ENJmtJq*cDVY!HYM\hWqNSjmqQEILFB/ncPY^\
M=NmZL jAyDA:\L%*MbDM<!WTB84?6ZSXlG8HZwJM*MnddX49M^eZENc?+d4ESadE\!pW54^1pTpV/SPVnJLAwD
bDwbNP i6*CTq8:K8N+HnliD@WADlP1ki/j$ucGl1uu4#M>RHMwDVcd#hAKTY=tLBWN?c?kj6e/H!q%!BCM8yEB
:F@RS$ a:N$$dpFc>:%mT/FceY^\iCnTP8j&R#?jYyB<y5NlVq+Nw\:uQVAY*A#p$Y:<&nQB&+9N!tc&PbcALmk
!R:d^^ =VDT^^SqePE\nRC1MVK#RJW4i!6^5?k\%k5%$N?<\LBtMMNRpp4IGXhJT*S>wBFlJqcb>AMqM^T/nlY$
\XPZR8 /<hayJ#46QLSPijil<u^&T&HM6mXqdL+nSm\QSW4+MZq+Q@?EBMXX1BIaJiwp<4QmFK4BPqIuLblweKc
MHyJ?d qYw&Idue%=ee^#Qkjc5i6VIEKKq^jK5CyFIQTDFDa4MnT<h*qct@</9WlFuukMKk9y+:q/566kWjud@*
y9=b<Z 8*+^@h5jcNQlKES!1P!Ga$+jQ>6S6k*++D5*Ke95ZjD@?Rp<^#8:@<?9TIh1!bh!Z+qkLZy8=Sa$N@4j
/>jEP8 WE5DBBRAAkAIAAlXdTWybYQa/HkAAE+yARA#AAAAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9
a\P!Xk WtX#L%N\dGF#cFNnetXqdnR8at%\:F6Nd?QIhuXn*kBeNu8cautqDF+EPL8bnCl#XwqHG&$TNEY$Sc$a
kTX/d5 \VDk4hBRTpI9JI1tYaISCF+aF9AY?lYB>Zd#I:LI*>BCpGdFuF6XqNn#kjkqG:dh6C%TbJHm1ZQ98ciK
bh>^8T <p@@<1@@<P1Iqu@H*\u?@k69j<Lj1/M@!j*@jcKP@*cb!N?n!WT6/AedQ@@<M>c$J=P@S%ttX9SD8@Bm
LKB*9H Ycd*Iu/6w!Q#^T\9CP5ZZ4>kjSFadi+>@*\>%w$iS9S1*hEdD#?YPu4wkd6juil>b4#cM&5\E1ahya\Q
ajT<=S Sqn^+b*6QjAP9?j>pbtcKdh=*&TnV6Vlm%Huuk?5Wce95LQDH?+?K/^5q&+&*A\n9p#Z9N4hHe<>8<@9
Ry*E^1 :=jy:Q*tPP98:yhma>1d=YD:MFmHueHY*5#:jNu=bZejiJ<XXt5:u1&=Ya%+iL#lh9SLl=9A!wN^!Eed
Qq>Sw+ eL*q<?P%8S#muV%el@<WkijlmM?6+bb@d9uKq??BNS#^bdDt!&k#:=w&*5^uadDbQR^G8*AidM\$@GZI
E61QBp :iFtGjb*!*A>=KG>&e$@N^%PPjk$1=#d&#Wj&>5=iPWy<9Xl*N?Pw\*jlZ^6<8ykPB<H&*t\*ZG:u%L4
$XD:Jy qH>8YK5:Bq+6/>:$QP=bP\5=/PHqQTt^Sd>t5CbddbE+l&cZp<P?N:5d/*QVahMiYG5mTQ@>*9%dt@%t
#!?q1a /MtGiGH4#>IQi?>%5j\nwk::\jJ:6cip4Q+i4:AMAXXHK*u?H4E#M>M?ljC+@@?:NL54M%bLiEG*Kn\&
eSEMEK 58//%tJ#d>&B+9eDHP1ck#5aBPHNkCE\@<NeiIp%5\Vc*e*M\LRY5?:MT8=aMtNhd&dN81QR6P+Z^>/m
Qq/%<< /=W^Z?*6mG>SM?\NVENu8?HXQ9iP?RMI=6c+u?LacGjP9Y&H>*p*//!4jMV6Aa45ZbmmHKEa<hGPn:8:
m>q@DM Pi@MP*$VHtVAl?5!<n4*&D15S69PDqmZAhZLneqknEliwduy549^#HC^Ze+<#9nDJ4S&R#LFIWhjYLBM
S@bP89 t=&%+$8Gu9DCtYeN8D*cYHhq^Iy/$X>&!AADc&kT4^8#\/$lDl%uk?WajKJHPn^M?@BKuC>N>Ejttjb\
!TldRY Y^&EA=mQZ/^hb<#/a<=*CF$eLR&49<EKXny<\=eQt*EX/*t!9dPH>+TXDZa<DLIIqbR9dV:At>$!=S9k
AAGLFj H=q55Aqu<?+eZVDdLichDWJ+eGhcw*E/&JcqBFt@mtG#$&hyqLAkZXnDQl?!4Yh#QnA:Y:8@+>XqF!#N
8/CpQ< N?p>b%6lDY#+KVFeR:8&c#bpR+6:uWHTGhk:G>8++Eb\ZLGW9MwR%W8k*NLA6DmNW4h5&!e9DF#lPkXX
pY:wiF /X:R!D8Nw@&JTG=LZ<dcqdm?mpP<Ebcl1yNpK6/dkeemT>B:L@mpnQb%#&l<A&YmTnk@<YX??GZPI\cn
l1d=KL F+M%LanPM<jc!Za9Jq@H&iCq=G5u&:+WddK!dQ%T5Hc!#DNjTL/P5!^/Id!C%8ij4<h1%kT$bqu@PYN>
4bCSnL u*I?#GuNuuX>=aV9RG8YQX6iA\KwSuK&kyw>X+>wE%VqqC^NK^KYS1Rhkw#kJ5ab=?KPkn^N=VwaDth$
4E9Z5c Bw$TPuy6118kCS$KPE>Kl6W1JGlPc:a^#c%qnkHT+u!<q4MZZNbh/k&>yyMa#W?EjT?p6cWEjL!XWYLn
LkX!Nq nJLq/=!KnLi94Xp8V9N>:YH/YXXINKML=6TcY@VIVl%nY4w%%8%>@1YKidq+:SVTe$<4wdS*mm9N1/%=
itD5AP =S4#YQiDnIm51%G1SPB!b/eW9Bc^Xk5qbq#Ec8&YlIq6Xd/GP98+1Zp6ep/Q&k8<y9j!!1ZL%@BAK+Zm
K<=1QH iI@X=GNFuQ4cD*JTtk$i*M8S@Qn>dLdH1y=+YY\4t&!>+F/G9Ne6X:=YySDq6G:bAY6%p$6ZyPJ:t#j!
NDTRRb XJy9>qm64Nl6a%ZB:HJ+pp>=>R:bPyA*4GGy@W1D<M:#jt?6G?tYu#VNY=aF1*Zw@Ltp^V=kjY=ia4+*
hM?<c^ ?p!XXi8bGiJD96wFC8j:dD8p<HQmhd/H=ZtYkp&lVLM\>@I:tNc>>5!BjqCPDVpAqG>!uR*$6@PPXabc
/J/%Dm >*j1eLhEYNq?4D4PPM4KHt8jQIR5Mj^8Q#1+$$e>?5aZlWC19*dLe$NNV!1q:^kwF#IwEha\D&FT*::/
j=kT// &w+Waw?mY$tZ6#ebjhW=th^B@cI:CtipcuP8wmTW?Y/Za5!j=!5Nc:b:^:R4?GPJ!yN\IyZXTbBG5lwQ
%w%>+R /LGinHI>+&lSG\X941ak1@JNYI=JPw*X#qZIKk#R=\y&phjDhJ8CSB&^pW$&<m4:4ktL9JbE#VZYME>Z
/CZAN= XXT>QeZ>A1<iAh:86Y!n5Y:*^pklp%G>=*XVqlDia>%Qw:HCbISG#R/<55Nhc/!1XPq5H<6>EtcS%:Ae
cPD^/B M#p/Z>piaIFZT&i8mtHJc@YRiH9m^lt>wXi6WKEc<?:#FX1\LqF>4i/^F9LX%q!4GNc/W@Adtnkc#I/*
-A:YlC 000b018082500110334 Page 17 of binaries2.zip
NAAhMW <\QY1tJ/#/6hq5eHCt8ap>t=P?l\1Me^:MD4@CA!t4l=FkBk6k%XNm6i6=@pc%kYV/&\nnY9LI5/i%PS
mBmGcQ &\I:=>ZL!T#\P5+5qPN56<SJLPe%?+VZ5p!w/*#NDWKIF//=a*qaF*kq<iFe8mBNHDnL%uc&5eqk1SM/
dEWcMB u@C/a/X=Amc^Y9u5KEY6HuqTCG>!$Ahi%=ai/Cqi!VtQ6\B1A=9tXedBkhhqcabKEm9V5/Nl:uXXhPw=
JYZVIX SX9SSc@Ec=KpB/Fq&J\nYj5MS#T9XhWXP=&9httGTlK4HyXd^chXLJ<X%*Vq9M4t8=^ZY@dRQQMIhFGd
kGWA5= 6CCB%?P!QCi^CqnJ6l<tmPj:NGQK:K4IZG8AGnaqiJXmYk+DC#Xu4lBTjb&Z=W5ZSc^bkXd:<NlKGWBL
X*jDw@ iatNFJ>?#85et<w/ndepZR4@Std:RG@dycw=Sc!FKceD4=qYHCc#5Hw\9GM%L:Yl4TJ?9G!*WVj*VXEy
8*aqMV 5Y+P6Pc\kZW?WKbYVXmEtXuE1kb$e$u:Vl55IyVCRj4FcntI6Rw/ZHD>XtEWc!KNP*CC<waqb<SXM5=&
XZFjJF RSBI<uXynqS%5muq*!PeIiSF>KY1PaWb$9R\5JQF%<wyJ!Cy!6HDCZIRS&aCY$N94FnP%pTuK4QneyTh
u>Xi:$ kyjI>k>jP<X9T5l$:iTWn:N<\H4AT8GLQVmZndYT$$!hNhc<q5Z>F@#\98B$D1myI=Ipwdp!@R^c!Aha
+hH1=^ %p#F5J\%DALbVD:jT6Z#LZuEG8c#F$q!X^w@QC<1W@Cp::@Mu#Rw4bbyLq%lLZ\=\uwA9eQ@QiVtV<4B
:6QLY& 5E^#/R14hWm?kI9Ai5KJu!&9l&ujJ!>Q=dW<YK%Qa9l9Ee9Pp*m%!<j4PQ9dH%QNu#Sl%mqd94L@!>i&
/q9S9C 4KiNZwaq\#y?dp?X@#ljbda?ye=<=k6lJTjBu#%TmhX?Cb^14Gqm9wnq!@@VjeH/Bi8ZjQ*C/^i5Z:B?
tmR\IK !hiZ\i9^$=9i@TFY>!<jd<WmeX#tuFVmyNGPwnl\HldCmRM*9tn%BDM1:ZNt>C=4$+AbdCKc9it=e!Hm
?ajYWI wB=h%t1NCyb&i^ILEj6Z#HBPnLdj9D!y5BNYm!@hiBwLP6cML9#a:<Z6/KL6>/bS*J9G#Xm+>B8nkVmq
1!HVWB hS#:Wj*%>#ZZ^R&=41m<FqFVmKER44lFI#VEGdE<TXCDY^Fl*?wY^&u*/5MRY/::#V?@bp!\^EpcVAn/
y=9V@9 ^:ul$bE#?!lYD+5+TF!@/j8ZLkNKj#TKA^cJKHE4E#Gb^M*48nMNkC8/M8yP4Zh^uq#Yw5qpp6S1iF<D
$hX%qI MwPJyD/=d4TV868:ae=F4#eSSl^j+i+aQ4:BuIb#\81E\ZG@<cQa?V/PFFk$eipFRIF&<q*dn!MJQD=n
&<YmQe +5M:ed4/AA\mQZWJLPHGTR/hiHy/K+J+TD6Z5bB4Pm!T:%=QwmR=<cMwmRl5tl+hMjd\8F16FtCV^bik
qDQPI% +1Ib5PSH5akBZ4TnK>bk\DTJY\DXE$DcA?m/cE+D%#Atp^5m9hi:@Q5d>P5Xc!audYFW@Had@hSE?/9a
!D<tBX B\<JQ4:iaIkhIGc+$wu#b&wV=\9hIjHl8w:#jc@&A+:kQDh16t/Fa/Vm5MT1ac^PAL^lJPIQH&+q!FYc
uD1?j$ *wyXiy1/#MBhmIA^XtFwt/aCMb#Mdn>?HI*AytB?MpteCjw$tA$Zj8IGd8Ce6IRBk81V/K4T1LDt6h65
nVJjVq ?/&JcLWD\#BAc^%S:Den>J=Dt+n&c:jlIl5tCFuBGK:mAm#>kh5VA?tCAEY58:RliZW%4/:e=Xc?<Rp1
I/$#qp THh1LBWjjI4SqRc1mYP^VA*A8$&eQb%kq&CqI4/8j%%#wkm^B#S$RQLKCP^5JBlFLHN4J<%#J?:PlI8A
T9?bBp AuhwLw^t!#CRuSGC$\A+$H&iuDm%KVK#&RQ4W=CL/#W9ZjRF8:kY:Zdm5u4Du<npwwl#*LkZVZHNbn91
Ry%hlI VTk9w^=F15+@tY$IdwBq*$i>KCdk:68*LkL*dTw#h1WREX=KX1HA+kmVNE8$y=T^K#SG%J#hkAMQRc!/
pYuJXR A9q/Ihn5I<B?RFeqeS#+TS*mFI9FnFcJaBe6!5l/*J#/N$F9&u/Z%E=c=%CckEmhk6$Kn9e8BFTmDhau
+?5#H? /A?u=l1%m^dm%ZEe1TGCcLwA>maB>J%ck=%<$%QympYG5RJLyQ?ASn:IdVdQ\Inn!kmXaF&SK%Rp<^!T
qBX$qX J1KY?M*mN5?cb+un%JD<RkV+PV11PKB#>9l+T94EHBJp+QKVtXkEBNc@h1a?E1>YV&w*\SY:FBjVIL1J
k+ac@A Y<pXcbJSI#p/S?kmpPKYRjFh1$@d$*ad8NwS^hyMCThB:yH/kNeySTm$WCi4Cp%ZLYDyG<dpy9M%1>m*
Zu>ajA WH\^ZPXkyRKDE<R>MlyERyS<%RZ:RMaFpa5VSF*dQ+88$SSkn++8#lpkmejH9+=\qaC=pjB:8EWZRW#w
m*>cL9 G$VjXcWNSkNDBDj?bV%BJd1<tWT>!*wh<S9%5F\&$H5JclFT\L>$i9kA5P:/9qkIKk=WCAVmGH^DmX&H
y*Bb*C hAyayEJLyXEJ1&Q+w1pW?c\JaSK!pCmk1\K9MyaBFtmbIXR<H^R5F5dZ6b4#:V9ewECSCYLpc@PcK8tD
FVWC$E BL8I1hVERaNWiRF1$V@wkAu1cIMljM@FJdl6J?nwbuDm>//kSAd$CIyVw#BFp&5H:?68E#$K@yAK1<YC
jdHRC\ 1JY*=nJYA:+Gk4\lX//11eLNE%b1E*N?<GYq:jYEiA6hFhHXZwwy+NGWm1VEnJjV!Bh=KXIhkXYE$Hw*
#etB%W aX?>Mlmn^8AX?uHFpB9IYXDkwBk^aGiJt:kA!*!1HRdKBXTy&ZIVcDK1!9WN1t/pNKpPjc+kY9B^nnCa
yV^\%? Wi9BWPAEC9AG?*E$Y1F<C/Y*SF!D+FL6?VNem!@=*95JbTdm8M$p=Rll5jINpc/wS1K!DQel16wK4W<W
uM%ZaA Hy>tK*+Vy@dG/:$///G&CIQ!FVEbZV1A@jn+8MI>8bGpF4amEiTiWDEmaWVRt\1e\lV%qJR1E6h%WjF:
Qp%8E< ^HiF*NNEZA6^M:ti^PiwQH+L*kthkZ^A&M%G6#Q^a/#BAkTeB@p$>^@>&M>y%Rtd$!4*S$%aJknQI&1Q
?c$jDt XtGlHJMKibuuLw44MDF?w$*Cl>q:W/t<5Yy8AC%tS$ik6RJ6VN!H9%DqAhAklu\l^?L8^>qMwPI\AJ^e
JBqBY/ ^<%Y*RYEFk^l?<b9RtR4XHGkNi$dlm!FSW^PwMhNJC<D1RaJ6D8:^VId#jD^C*q4L6ptZApcmK^%haYN
yAe8Cj lR=Ntch%/SCbm>8<FTc1Tm9+hVcTyEl=H<4*kjlWuGkn81/@jj*/hS5G5HL8ZB+h%TkGA<NQuFNJLD/W
D6+JYm IS!bD\%G$X$\F&DB4FGHHF<:NWkSjJPDnG:CH<LcB8kby=HIjy:/RS&=TwI%RTt>kND/M*Vak:6c@DnL
*I<thQ W^Np!8L1R+%nwji/YtKJV1TW$8H+HT1Pi=5/MpbZ?FHqYDXNFM5jCN/pAFb4k&C>/N9iX&e%k@Zkm%*T
ZLTLdZ yuP+Q9KD!iu1<ZG^eFC*eH8W6I9FZ/H*eQ5X*Q8%e>J56mC#q:Xi:/IFu%!l8uy=/+841/6GQcIWRW&6
BDm8CZ %/q&Gmm>hee%GDEGpWP*8hLBT5YX%5qAQM6!1nSqZ*BIyh@Epqh+SClVPw\8>$mM*Q?VwhA&C1>9bWl@
SkAeA/ wGy:MJQ5#d9Z::+/k?dDC:YPnmdm+6^6\R>Cut:JWeSWGq!mXRRQD+5FWlZ^Ay5<8WaIB\yJ&+j%l=%1
nm#KAT 68Mb&WD*TnVw<p*+b5S8n\\XDNIEuRnnCY\Lh:EkK/beEyGH&QiubDAp1*Gem!^1n98>!tP<9KM^#JCR
l=MD$Q 1H!qjaVNySnYb<Bw^Ph@?pTubZlDuL://cn?ZSK*EKaY^dDV8&/AScmRiHl<wF5TmGn5kEw6^A#?yBJN
w+94BX #=GdGLjWc4YyV$F<\my8uh^m<IA5dX%hZXBEZV5w6hN#>MjJBF*VdKEdCBe?&^i198Sk=Wktm8S6/XK=
!?KRkC !9&\+*^Lic9Mj=1t5S@eK6w\kyA$1pB&qWJlZIe^nTdYLYL&#%/>PyQ8Fl+BMZ!FeRt^GETWY!MR1/Wy
%YZT\& RM\Fm+ZAMK\Cil\c!DLA4JH&JLXikwFwaDn@/aK+^k%>>uXM?68EY^E*nDmPileBiZ<+##lKbFSK5De$
6D56$* jEQYN9Np%Rt4$#YP&XjKD:5R+N6$H<JAnCGDWq@1RtYQ<eptK4C&^+YC:Z#**i6@i?Mu1I=JFKG?Rt=8
c9SH\y !BT/nMa%m\e1@bAtH+cB=EuMBDuFT+\Ewj<CYM=SPmeVTJlDmR5=d/Di*5mTStPiNwc/6S5ZR!KnWmEn
!C5PDw SJinZKXdaLp<^VJ4ZRy@uZ>1AE=$+?emItJyFG/^NK*+lWEhW:uwmEDFA$J+TIdaI$tYNjhW=N!#4@@8
%?Z\>Z >RV$pIY1IX>9aIACSk:C><pcR$kTmkmGGQcVBSI&E4WVSDW<+<KS+*IjEG8%?H@1iwMiN:IpVVBWWbHn
A+NmjH 6%WyRq:9NmXMe+i*Da*e!bja\=Vc$XniS1JZ5d%QY\/C%Z/ddlDh+hF^TDwj*jtaBG1PRcAQe>#<A+%k
\>amNq @1K6/?=mwd#qjy@be/h1kI%T11RIKwLQ#b:bb&cjtTF&V*C*Sh81!t>>NkPCGnZLSYhu5*JL1Yc\%Dk1
J$/%?A 9kh9tP9>T!h+MGXe=!/CePKS?N?6&tF<5Xt8c&QElbS!!w$m/N+\mT#jY4<HVlRqD=lVVHS#j@QNc#yF
ckEM&* TCmHDkNYnJaMjFK*wnw!%DT8LKuD9Q?$KLnMGV#RE&#AlDtWA4kI$5/!jIcZ#>L6AnEMjk19NTL\yi5a
1uBF/V 4MV\SVAC<PCI==yG=c91/4bdWhbGMH^@AZ8ZA>%*And\!6d5ccD<a9G:ubikykhP8Bpc58>h\Z>6EQ/J
/wK4u9 WRywth+#ju$j^@CNN/Mwyk/QM#laC>iaA4CLXe4yZpi\p*tSR/tdhq8Wd9d<eu+=Mh5\m$1k?&YSAplb
dPGKW6 p=YATt:l@hK6S55mkXl>qT&cCkyA<iFmAQ:TNlEM1V*SSAw^qHZ8L^B^w@+XMiEHJ?+IGkybbJ?cLQ<w
CByLjb &tp#qY9iBy@5#!&PC\56T1%aKknZNVmqJT:iNBu5eIeDbwCM%5%mGBA?u:VBDT=G:ScKByW?<W*l?kJF
T#iAJE ukCYkCB#^Kl+JuA8=ewc^G+d&y61ZmAItLVnCZ#RBIb<tSQQRQuedCRHa^RYBL6eiyYl:?XKP!\H^ii#
!:MqPZ &#\ZBEWIAZ?^Y@\8&buLlR%ZZH\#e\:<QW$DlB^mICnZt#e=a1?IF=baI6<quhqCwQkTnEpJIGpqM#TB
<JJwc@ hGGc+aIKQAeDP*XK?VT!%Vln5yFBPdT>k%E#5<=9&@F&D4HQP:@cAuq8=$*qeT<RwJXPpG<S:HC\tDa+
nPM5&6 uA6!Cu>8uBtHaNbBL+EEQmJI#Gj1XMRT1!HV$IbyCDybGL=nPG!jcdS*\HH#V*?AaHFjkW\BdSF/RP%Y
@I%=!& w!1j+bw$diJ\CjM8whMX8V1*5\XM5TpRknIVlhmwBA/5IwPd&C/*Dwh6XkmB$nGi%dk#CPX^Q&JGNVQD
T!&tQb 9EYnDqWXtShY*5*$HFSP6Fy$GLc+dMJ>6c:?y?R6*$cc&I5q^wQJY/9^DF*Std@SlDp@cA=QuD6ntnKL
Td#SXJ 9wu9p184dNiqp:uQX=b*!8B$5M4dI5EqlD!Ji\A8<IYCQ%yTWnqBwt8Aq$dJykGc65WyHdY+TA9Amt#i
\MTylJ n5eLQ>//BV\5kn/I\++J@dLq^y6iZMFkMlE+!NZ&pa:=pEi+4+/Ct^:Zu\WL6:MAB&&54*SBlSu1IYKj
5B6/pH HupQ\?j^*%SVhVnNb9Qya=q>9L1!5KXqC/i!kHZh6BY#%\%#aHR4VG9DDZt+H<BjBpcPRCLGqac#:RCI
-A9Sjp 00011109eb600110334 Page 18 of binaries2.zip
959&F8 q>AJZNa+**cLbN6Bl<h#Q*hbb%dn&AN<tBHjGh\d%CGuSVb/t!aVeS\Xk6QkmEK\Lwi>H?V1>\>&#<\c
B%8<db $$a^4#<65i594Pil9GTQIeY<#>Hkc&6HQMBn^#H9/#X$GJe%u4jyJKWDHCQmRhlcyB%\aa/A#5FaQeQ6
je5pZk MAI\e<BF1ERHJci#dew1l8PB/B8kaX^HSP4RaZykH&%#@ANEAAn9TmjS>Gk!\X*#e6n?9e1:QReEK<dG
NL*XNc /K>+WIAZHISa?Ab9jbZIQ+twwyIM$>QCX8?u?N%E>8mDYh49R\aDV?n8L5Flcb8c19SbbZBVt/=a69d9
pKV8*D uy+c?F5t91N5aYA@kbH^HJ4K^nlwDCYQ*h@B&iJpYVG!YhuciVHyhyQaL:N5ES5AbR8h&G!l=wkWmB\R
FlFp1E %mKP&\Sq=hpt4qI4IkWMKZL$cat<&hIP=$VLHulaEC?8b@^=FqFt<<IH<!*ckIMiSbF>nFeHHV=T5Aw1
:HhiL? +C>?teR*<DunYSRucdNmnkp&ABj*lVpV?J=NP#Eqp/nM5@G\JeScN8&+>Pb+jH1Eb1dLSRLp$hwE@\IP
Dj$u1j KLX?dK6b:ldMC1Sd8Cae%6BKIJ4hMlLtWRJ$$QeL8dkl/LRBPTZmZ9tiH<=%9ied>5$5cuaWdPMH8CY/
*HyqEc eh:dYtw/^9BG!G*iQ?CLBVQ?9mq^Y$9+X\c9Fc+Z*M#KLlb?=N4nE<DTmbAP91NqmMLME:A\5CFP5M##
lqAYH1 ElHS!^pau$q%YKe=MHLZ+VJX%hlZ%w=ua#8iyM9KhukJK#1\Wk#BP#6E1ub:CiZ<5e<QTy##>Z&%D*8I
Ak^T!Z !Q6QlYiIQJjMMDFc/\9FV>MyXNm6mR<BK8Vl8h/lYZ?5QaE6d8#XXY^YCK4LFeAJhedn\l=i#w!6eXlD
4tkB*A 6I9R66DDY5CDie9<><m@9Fk/&MqmkpDi\W:ljRMjYB!%R6DVhl:k&PK$?SKQ^phMIa+VkEcuqS4Z&=cR
>GqiF% NQIB@\4&y^aEyLG9weSV*++5*yw@6tJ?aw*Wl!h%^C5<NNt*wR\T$t/<6+\GEaZe9aMPd@Mb\uEuC6!P
KPi41b h9TnV$<HSHhAaRSmBRH!mYLi6GNk?@t<^d>^@tV#56#law>TZINT6Rp*$%h8/c4q$m&4iNQbJiA&+AVm
hm8ZXk AJap>b1FeG$I1u&\\#:wML=!DVN^!>Me/^icaaS%D1L%lChP!u81@yJd1&6aa6#dl:&Y\BR8T>ZQ+&9\
H/bHY@ K*@a#Pi\VcPhnW1YHBhMajwPL*l??Vh@QMDDyQVaJt<QVuYc6T*+wRbP!lZ6BDFdQJuDbPN^lEe5l@Yh
npnPV< +?>#@L!6BH8GVk^YFHnACp1Z8tV9b$NKSc?5K8=6Qye<G/SX+:yP@S*i&w!QlWW*DXch%$e*>i9/CeLh
Z:>ZGN +&dD?Rte8BRV#qKuVJQpnuqEFtA!L%qMH!*c!TI>Qn&huy?hGC9SaeiTB>CWn!$WNq8pT+qyp=R^MF/R
QSEIS4 ZyL8uiC&D4CwG8i#bcWYCPweAdN9=dcK4Y&$D6u:G1tq>lWh*Fu<A/%#:M@%8h/uK<8M=6t:9^EFBWSm
N$!6^e ?W?N&^F/8tiJ>iHB#:YPyYCDJ+beeeHdJiW/T9\5Y!TEClYjw=<lXDw?4k>Q#/hBl$*P6BI#AZt&T:d#
wHmhhJ PRJk?J+Xe=:+jNEj>Z9K%FjnC5cne^%<hnhSuF=AwqEMEBQpcuwp*PhAi&?pIZ#/+Vde%^i=4t6t&mW:
iuMV6S IcWdB4H<99LhYG:&/?N?@!Rt%@tltJDTa?pQ\Bi84uKGIE5Y$THbI1$KGmp/FFayVa8Du9IYJ=amAEIG
LE#D/w t/$AwZMaHlb$EPcj1Fd!y1t@PK!Ic?9k6QMMb6puLE%Cl<66u*B^R*DZB!alb^1CP4^kqG1h\#%M^eEC
X$q944 y$teA>*mQ<C%bhbie?L:KbBE@jC!j@D^/:9BCI5n1$Qb%t!ak*GLPZRT4t6dNG=t11yIY+>I>jq<EwpC
D^/!6e bibE9!jtWZNj81\EcpCWCnQF$F:1=y*K>W@jh>>D4yN8am5+Y8m:H#i\:>8C/hPWPXLD+A6Q*GuRyYj5
&dckIB E#Nik#wc+p\qDHh!*P8q+>GP@1Q1b>:H>wKH%#DYD>Dk>FY#MREnTm#Q/1\cBSQSNw$JCHA5Fp8BV+56
D/lPKw kt9%Pmi=4HC&lwYPp%^j\C8E/nDI!\^tK8?DC=#\i?cJ+Y?Ypth#mE?#:aI!YGb<RA/^ud5aIPPDbR1\
45m<e? Z%%F4<aj56lI\D9qdXW>VAu?GSBHJCRE9kT?H*S</5<QL@X/@X9n#e%\P@nQ>*%b4>*CNlWAAqtB\G/S
BFt<6W Mn=uY4WBXJDDytR/tBPpkFDGp%M^G8N65&!%A^J8tQD%9Vt6>AMu:i\5HSiR+1lS8&TpwyG1aCp$Cen:
<PVb+I kqb\NlKeml%tBjdn9d#j@Xu8/^H@&%tGdw&p?LYt\!RMHT$PBKti/?bZ#4Z*jWXZWuP>D8QSRK:ScLtd
PM^qP$ 5I:BSAKq#t#JpXW:^^5LJ\8AAw<D\!ZGcwRIjb^B>mNlHcl%ki:?1j:i@%D>WFYiD1F!Y\la5wRIhJeI
K>Xb1H E+\h/<NP%hLc!#qD6m#<TdkT<#iGLBpea$&uI<m\WGJRT<hFT>p!Ywh6ky/?pNSn6YSul5mPX!CE^nkY
nljjKG :&5S#+8ITSZeKmlhm!mGXd5jQbQ?VI$&nnWQGC/aL%^blQTJLe51=&*6IXu%b@@Du@@W+eMDTeAp&XHD
e=j1Z9 !k>?!G/TF^HiFi8kyPDIchMABPR:uIN^55Nl+j*uklEjeJK#Cmi6%Cl<ZQGj^mbwQ*/Dc*%=EpcIFBSa
cncd59 JHPTj9jHwWLyYe<bLXh&+\F<Imq:F#p9ywWTH^/jDp!=RNcu</pRt%F+M+GAGe#k@eIHyjItIha>uQ+Q
<>*E&J %PEq=Iyn4lCl=1YpjbuKTF#yRnnZTpFh#My+1L6y<5kN!dZ:X>iTR*9^>JB:My6kl!Z#G+9dIj=ZWwm4
&YY1KJ 1eE\aKGw<Jta:wLJil*&X%h\qQp5kk+niHG5/:DT=HKFE!hjMIjGBDq$k&qX?J<JRy5TP6*/aFH\dc5@
EMT/I@ @*Qh!ei&/>!8A<a9X+&IFeaPMd1^FC#lX%@c/QPcQhL4waZtF8ijSl<E+5EKR+pb=Vbie/cqQy!5qdNS
qukc>\ 1X+iZ1C5i/da/Bj$CTla/XqCZ8Tc4ZBdI^kwIq8dm*M=6aiuy@Zl<dGSpNkVNCHt!+6$VByLQy<#h+:Z
G&Ab</ liLE5yKdmw<@\nSXT:\!MucTBke/RYT!kYBFcF+1=9cTP#&1LYcTVA&^?iD6t>i9!NNDlHMpQc5PJV1<
:&Qt^@ >Hi6WwRTt*w6<1qa<dFY%e*#wN81B*$Xp:p%iJENa>LI5e45D@ZyeADtBy^+Q6RyhSnZ%Y\Lb4@lhW!S
kLXR1M ?InMLZt4nJHyeES:<b@#&/+\NHcnVcN^#LcA/nDBLp:pJPFyV\Ba81>Kc>/H/BZ!d*:=bw=ukwm5b6cB
V&&+MN F9njQ5tVa!=GqD$AD%^ZGma<nuMAEd@1!$c&D!upmTPtA=KwIy!pbG$JYQCSP6\CE@9V<jpk:IpVtV@N
+tklZK 5tFBc?Tai#Ki/PIbw1Xa6q&99:amA6/!4LG\uyp?%^qka&DK1EVA/1XaBFPb1\Yud6b%Z>DSa+8Cy:?=
E5#lVJ IY:c\<#C9c/qJEqRnPC8=*BFIYICEybR1AhlhGt?4+d%jq9pckF@EHalJl*HNDYuj@XAjhCCI\K:y^MB
Cl!yhB lCPmcIAnyb\Hc$#*a>*l/E@/$&l>IXd<D9n4dWe\6*GLtCXbKVk#j$:d%u+4=cuk/u*IK\!J@/Q4T=R8
IR=>em n$THc\KujR>1=:?#@6NtAd?SId#N6d4qSK!KGY16bL>8iwynkN6muCDZSdPC6=tqbW69ium5D\eJ#/e9
qnVeS6 bHX+AA5D@LSqiCCJGDY??BI?#8F:+dAVHNiP+Y6KBQDA=BFkCQSkq&:u?ecViG6GQA1##W1G/ANN@%XF
4!L4!G XbJ4H@B@d#:h=%y$yM?lXIE$jn?CZ@&d#i?TZR146\pkc:>@$dlQD<XpYl#KI%?^utmHW^8:&Yn4bla\
16^y1L CHd!?WjwJeQ#Z=NReGdqCkb*pbIDW4AI!#AYjkq+Gh?LmTue$cwm@5X^Qhp^1:ITCl&W4HWhVF6$*\k\
R@FF4w NIcYREyP4mi#@EXBS@:C6\EhylG$c!dJCBPFG\AuuT^MbD=@@l5c86JLhe5QeqYRmc><DmtQT$yLdSNC
>CD4di /G$^YyElpKa+=\twEGmy<YKhVmj1d>N5IFmGhI#uEZPR\Zl<jFRYNCIeC4c6KHn4S>ap6k&RKCEn#^e8
e/JViL t=5wa8FmGt=5itH6?IH>%Ce6<HbHWcSGhqBlaSF<^neVWyn*pyZElZnCWeW&Dej%AByR@n4aAH&V>Dp^
:*%qR@ QBXM$>m5QJNwiQIM=CLm^Q1\Q^&ImH$$T6$5ylX8iS=IqaW59Rih6+BKVRQM:<h\1jF<l?@eLyu1!lC*
#!wG+e ^1\$C\EQlynqZY5ClLaDw$B84166Z<=!?adEXDE\pNqSSRVl^wYdl%DedkSW?@*Vk@JRl/QcNAL8kGh&
aW5k1R Qi>LdhMEEYE$&8:cKlw^a*nC6a%#p1plP=#ySBp*uTF^QYTkIH\T9=V1ac6$DLuP8&=BIkHq!S!EF:=\
huAV^F /SDpL9tD6kwewM5@ckda>lDhjqXC>H$C*Iw^NbL9aGKml15W+l*AW&6:5**N/M@ZD$@BDAhqBh:+K#/n
nQC=eS 6jhDPXw^Ip$HZP\eCq1pB&y5q>wbZd/el>R%c$w!yR$AQDE^lQQ$>HkRhnY?T?W#Jp>L\PAj@BbShJTy
KYwhZZ Bt?>!dIN!=\WV>WJ@9%YwE%\ji:C#QN>tWP$P4WJ/&Xc<NtLaAWZyKZcJEXamdmeF%=Z%jN\M1A8R>%*
$CQPw% F+cm*6i$tmYVylwD?eF1TC/6IJE!L/CulBXFT+diuIiXcAhS#@qaQ<9nZ<Iw^atNIna+hN&j>IapeLS<
Zn?5B! a$SLYeZQhh86bm\cL%Fh+EmHZKIjMCKVj+HhNlpmwYB=YMZ\h@m&SjAmWBw?t5G:>nnj6i@tRB#uhZ>X
nbVlqZ >Sjpm9e#K&Iky:^N^bFY+#q^:NkhZq:5CTyndLQyWqL:eT\+uaM@9Q!+Jp5VD/hmM\BECWVThVZPPQF8
hk1X5G q1yqtyA=R=kD<AtQ6A&C%DnH=Z%YQHldi:d?\tIn!yL:!M#bPWR5dq%E9l**cbdtG6<E<u9aj*%cRK8:
1El<i8 hDRGQ9/KhkwBZ%&N+\I^TGZtPG#BP#cDqhp\AYB!cm4p&4TA\eA>PBK<Db#P/iTj=cqH!++W^dI5q%qY
GH18J+ Xu><?LMI%C*tYq8kbp9&yCKp1wR9uhPlyZ*8P<RQ6t>9CD\&T%wdp^h<u%Vme*?R*$61k6<y<?qImq5Q
>Q=6DR up=JV15H8<>J%l#e4i>>Vp1?*aJXanKFTVKL++Zb:kAhWwuaIXjHPl/Ld1q6mTZ5pXSKh1PaCmc6ZI%G
+Dc5S? !TR&uZ@+b!>XnLE/6#mS?9B<8$A\%+WCMLNZnhbY?%#dIaSL^NbCdbe\SjkQWyAJ?E?R!>!*M>GFZW4Q
L<:T9P SCn^^M#F@5K&dY+k5=H>!m:Ja&TNa?hYN4a:bwL^!HE9Hi+ujyA^W%#ad^&#c^tmIaS?+@^pcaijy+#n
cpNuFw @ANm>P$eH<Yw*KXqXj&jZ%nQISqi=LyKXaq\66WE+M4VNjZyd9#$eTk\>&=uTJiSYXEThBk99tMkD66n
eRTtQ+ G&$WVpY@W&Q6%dt8ETPI>QHntHlnmNBn+h+&NXWEyFNqGbqeFC5e=AKjJCYd=6ad&FG+!H\%nlLa%=#F
McdRiX uWjT&+lZN4+mRVFYbuV**biRNMX*j\Apqp\>4NcEP46WLYX/HWG@G8DKD:!%\P9?$QhXtTn+X>#aKeCV
ES!=QP p>+4n\5%p!j!?+n6XdudR+ebD6aZFnX@DBCMHSC^W=<Vd*#b^W4J\nPjF^cC*bG@JImByR%A+4R5G*Ji
-Am$5c 0002cfa2ea300110334 Page 19 of binaries2.zip
K^J*h/ up><Q<@up+RZiLlhF<@JFJmV>>@6j@+#\\Cly6TTm@bpT5Fn\>InB9LCu4LKhWhe/?*a?wE@HJ!5%kcc
9+p%\J DTQ/$JSTB/+:@+bIt+jaJRSNG$tjWhD%WRLlPlA=HRX4*hiMa6ktBCEqdkHmq<IEBtP^JAR+?QQl/WA9
?Z\>m\ a=1X%Z/P@cq^^FdlND/KYJCi5SqyNit/@Zi%@:/4\%hF%#I&W*RERZR?#Jw$VeBGZtwiCN^/DwEEwNC>
6HpGm/ Nd&:JlSymH&j?CS\P4ajSW+Am!^PSeRT@p/dYw/?d$G#jj=mCBahi^6tK^JDlWQG&<wIeXp\KXMRDTP$
\cdZE^ LqmeHNq5mV5J4GEi@XAMlQ6eb6LRMet#LHMXnJQj1&V%m5H*$qGbCa6*qTT<tJXIR+JJ6QYkVFS4jX<P
pddkL+ +G?AehKb\k9J:NyWKPBu$tD+$?Qj!&69LKKej+TVqN6/>IG=^1@h&c>Iy$/\^AT^F8B$&*1>4jlt5MES
jiK/\X wQi@+qbKK1L^yIKuQq9CaRBGy1&<A#!XWhW1/*%E/%SXj@JM\F>CKjLD+bPYuVG?a%=N1NCTmCE^^E=E
JNVR^R Nj8I#wW5t@MlQlDEwiGc::Nd&lEJVdMTEm>>@eRk8Si1ewj+LYnDi8SE\eI&4ZAP&He?&%TjI>D5HAIt
@%/PK# W=y=q:^k14Rw&TFyTj&SFB:%cnudpA#DLk=i&e/P1#@/y+e9@$#B:mWIk?6qlTP%&*!J#@KeLXMQIaD#
+yCMIu je\8$y#&SR>L/=EF95PSBTmY#ReyyiX8eSjR5&HX5lH$M?RmNX8Zy1+Q%G*I\blSCdWARDKM*Im@&FAW
*YRdA: bTSju9AADIN8M^wDIM=m!NWXJ*cw$i6BRYHe1eMn>5Ecbmia/IK8naXRl\jAVmZaa#:=nyhS#1tuHRjP
H$L8Lh %hpP8ZB=Z=4<yG$TakW%mM=pKw$M?FQ?N#CXBd@HllJ/&W?dM89L>P+TBC#MpAlZLDHcF4^Du9p#L!4e
$/#h11 nwpaa&k6/^8<4GKi8ln+Q&IPqRaGb+ZF*an^\RikB^#5ckJ\6Q@!5Q?lI>D\Y<TGMZ6Aten1:NJ4A/?S
*H$F+Q Py$\uTmB/Wt4FVn6tpuRWIWX&w?V>P>SA>m??#Yi@?+PIcPCVX@R9<b#j/ut>1$l$QPlnGIFD+?pQkZa
w@^+hX B:i*I*$^VyiR%VJdTCjImTdLAQknW88Ih+1$?S?c>Ha$VEySa?dyP@^5ZE=YZVbpP+$tLJK#ak1LENkj
JRD+<T Ww9#SqQE=<Ah6MESTllLaF>wYyWuQS@:u*e?@l+at>G+Vi<mCZTP$D9Vb/<CYPajQ:YZZLnE4!#jCQpd
9u@ZRY YIJFiW?8T:+cVhKE4cF5itmq&lQu5*nHHPyE>TJpC%1i^pTSNMKccm6?%%jnEu?<#m8+6NGERA\1LIe5
WAS#Fq GMRc%!e<Hh^FIQ\EJ1dE8SD:t%^4W$hBS9+wmKHQF4aX>TCVN+\96uK:l:ytAMd^WGVub=q9MyV1kXA\
q#RJ#S uakbFpNVSNpTQye%YL4aPNt&E:QTDnS^<Q8>?QkH^=/PLX=Pc5EK66k1hwIc5lG6+wPIqRwQP*>!Z>G=
EEm:Ck NEy@6kKT%bH%DXlPkD$#^ewSCMIb^N6pkw$!9u^NNAER=C?XQ=1=\CRjEDF$8HB!INN1P^+ybnN&udRR
eeL%WM Ic5AlMPGGhM=yDM8&bE9MyWAtVE!?:Dtw9YI&diI*T$4:M\YR/aV/TApBTaQ^VQDEqc+YuL1e?A=BeHC
l$qlcX =DyJe:NqXKkkpwR=>\B\ZW9kT@9//ZMID6mZuQZjMcVX/jG!dDDi^BJ<h5YJ%khu!/RC*bR:SN>=FWG5
NH6t9Y %GG&iBS\:Vl5ah1JRLT>FLIj^FTp$qAG/$Ti%GSlqTCCEGL48nah+i5yd\w\*aFN<XLCEyN4cJYQ/$Aa
$lK@8$ \h8yjWn@5:\%Etq:%YEcaFh@bTcaCb@Q?jW%!=dYS*@BNSGWpmV^JZ9HtM=LZa:H5eK5dwq\EVCXnanX
&S?\&8 5V*L6AqAwm*a^h8Kw6eQ!mcCcjL5>$WpBQ9W^aC>%KbKew6&pijL4b8:4N^K>:8YHHMS=!SwM!C&kw\i
*?\HC: TbDQ#5SQ16X*=@hC%iJl%+FRmthERFAKa/4tjAJeeDPE^FbLuC::8LID9wBeTj\tm=>>HAZh/=ce8@p<
1\beSy L&KaJBJCq9CyPZ\yT=JLmHpXEyp+cyF8<ItFaWMb:XQM64Q^1Be5pHuX\5F8eL/NHMm\9tFJMjjT&b%c
5w&KnJ baaPNkXSY&&%$yFqIZ&@X4EGhhR4t?KtLP+aRS#*w5cFBqX>TXcm?d?!<@!C@1HD*t4tyhC^E*DBiL9G
6!kaJI J$KqPppJkFT>ItG?%M^*VB:T9iN=$qDtFW^AKj^T@9<eaelew&T+u<Vqm$t?#VhdiQE$<N@N$KFiWFuQ
:?!GBQ q%bJWV!yGBMycFMYMWSh4?89aJQTjd#V^qHQpG=hG=@*DcPBT58!WyL+IFui%=VEyXcddKSn9%p8CGKL
MWum4q hCSmSaSQ4MTm?%KwIt%I1P@*<DdNckINTJl^kqCJJ#mIa48R888+5#G:8Ea&+9RDaDN1#>\^a&XFq@E#
#%e!pJ D\EwM4=&EyXS4yKu?R@CTFXmt8VJ\lRJlG?8tXu:N=GMF8F#u@w&DCc\QqS%4d<bY>JVi$6<hTYhyAnE
>FMLIS YbMTV6cm4hmVa1XChTD@PKKj+YF=<kq:Y\+pPW4FQF?qQmXJeh+5Ehwqp@tPPEu6R>Y=y51Z$H4t@J*t
MR9I*h p/X@5CiW1yuT*I!mP+Vqp1Vk@Ie\T+GMSP%i<D+pH?BR@ceNCb4+?^N$?NlwH$DIa+pp@^4jhlPtFel>
CD6G%T yZ=KGR=HT/V4a>=AqDM+S5KySnIynAA+RwCl$GT:tLR!STEhRZZyVa4SiL/Ikb\a&MH^#Bjmk%MEMlE=
ke8HdX Q#k5d?4B/*%qnX<cP>llidJj?%6HuM<pI4HG^9Z%69%$P4&$%EqJGwF#Ac^kuJa5ihL?p1mNe<4$nAdC
y#APWG I?+4V%y8F%VQuJT56qy$XL8e1ZHKhd8R\^cJ$G4b4ASj&RJ15V^keY!Ql+N@ECGKYLHB8!^l!ST:XB=Y
KFCnn6 H<w9%LtVI!4Yi&5uJ4CR$mHnL!Ldu>e8+GEnTmAX&4$j8lkCYm8c%dKXwlCbyKLEdclw%85?w<lyBMaN
n%Mjt# *BAS1%uS!!bTPI*V5Xt+$t$/*4DW6Z4TXMR1ym4qa&Ht^$4JD1mLPiIG5HkP4&NGEQe5HNb6tYjAh^V<
EGkS&N RIP#$=1/hyI%#THAKBh1#$jJ%t88DbbA@C==c!HbK@E+iVQTZhAIS1RPK/ZS!EQdH+Ne=jIKhlKNke?l
=kwLcP F%ut>Km=k9yF8^yH^d\\B9e!#@t?nhcaSaiyj1&X>D*dQBpkHX#LIJC@bZQ^RDb1?kB4^H/KJc:/wYqD
ttTClL B9ERbm9$1jCBqDkqHGPXV6wNT^iGbIV<<QE9&6E*4ZT9PKtAII4%M:?Ve1#!Lj51M$uetuqYHVdyiEdJ
<L^4R: LZlj!bF5&*G/IXQAYJ=6N+lXhJmFhh^nDlclWQ*y?VSHEDmZ8SyL8dJMt+jc5S?NJjkTbN=5KT6t#mV^
^cV%me aIRq$6NjKcQ>T?m@MNw\!5?j/ZLW4W:DiB6YJijP*\Rh4qNH*1GLTHS:16el486#dH4yBj5u&$YdyAy$
w\@dSk !RA8F9N6Ql9nhJV4KwHPT>hw$GFG$P#G+tAS<5ibRY$&P&IJ5lH$k^VcNQn^hLTV4BJNDwp%14VAKM6A
TKF<@d K@ZBL9MW>Vq$!ib+H4p&cy>DPu^1/&pA^6c*WcE=84N/\jQGp\&<:/ZcX%/VhKuYCtiq<$\ulMH6lBF9
lKD&hl Y*cY*myNjKF5T^pw%ala/awL/DcBD>QEHHS%b9W>k9J!IlhL%4VEe=49XS?S>m*eABjC9>L8*>Cc*#5h
=+pj?K cXB=&SQcK<ZkXt!%JCd&Yu$N>Yk=L8/N@cRa5cAT5@dSCI%<cC9WDG^5ZMkQG\8^hlLLdj9yQ?VXe:TY
QE**Pb NTjDl6$akJFMW!Q1K=ZIE/Hq<@S<Ql+i/?eVAupI5@V>aVpmlVe%HBcKi>BG*ql^Q=^F^Q:A6P@DC5Dy
LkVDJ$ @QDmil%tJ/qe:@N?Gtl/$/@#k6K!/>VZ<yV!&Xw6qRm&>qP6=muW+u*X@mXy&=C!eK8<Q=EnE:15jDmb
b/JqT4 J8ISDDBY<N<iH5<u<kkiZq/iiiy<q<Iu$!abtWp&al*AJHdkMAR&%KaQ8qk/NYbw4>N?BXaL>p1qJp=J
S\S@CA I\WVw5GcVCS/45MeJ=8=lhH5LV:FpL?8Y$GMGnSyy#/?\%#nY8k\=>aI8:^yN?$FKS61:PFA?4TJTd\W
yTV6=T +4le$9Q#<@u+<H\/Qn$hJaZMLALmlV#njCQG59KBeJjNWqLJb#iVFi9L1$>IqEw5VnWPwT8jAEtWjHiF
/dHuhX ^P=#MenMtkwPbKVd=&FE:SeFi@X5T<ZFq^:cwbw*#MGSB>!bpEe$EGC8#PtJYGj+=MwySt+q8\k+9MCS
wA9S*q Pi!wCJj$<ET1%@q<iQS1uI6&dJmeaCFpuIWQVtu!eqm>+DnSYE4IeBXncuDwN9115SqHDTmQ8h>GLhe?
uMFw#L qGBFLh&FJ@T=YWmAC^CJTJyhHA??GB!aF$L!NQRc1k=DctMPEE6:8RLt4Ew=1bIK&F$de+\IjN:BQ#?#
\9q&:F q%5tID%VyG1eG$ea9J$nDIw+=!nTcVA5HH+%Ci$Ht!:lA&cp/+%Fk/Pi/KTcT%1Y\Iye5WR@GKV89Y8Q
W6&i*% JWSHW*aq5w<S&9BR:=t1QijF@!Bac6QGKS:t^I^G#I:X!WC\9SZ5BdETNW?iWmIPmWpFPyuH>TQbEmp@
ewT&\$ a&Y<AJ=D9yL/i1=q>9CS8N+<ubk5>BYVy:!KeikqT!>%hZ/>juy\Ienl%&L=8n8GR9LW@5W=uF<AnpGV
tD%H<B Qa\*FAK@9NiCX#@H!t1wpE/e/4AXpwAH+peM!$eI*Fe1MM##R!8%6lu?P8HlmJ6\R$?YpV$#/\WLZlRi
Dq$Fy/ JJYXMtM8ppFh@NkG@FEM:m:deq/J!&CpTC%Q%SAQyd4yR?$9nh&pR\m^m%HeMIPM\&:&!nd+QJ8SXkyQ
RbZBE% XSeRdM$I$Qm9&ZD11QA#9YJ@n6pT$y^y65BZ#/pY?wpK&%A5ypS#bn6JG*c1*b:#C6I\NRGH&8d=DQyd
$VlRWN 58kSy#&mpH\<VB446j+HBXBnM6kw5eTPJmFQ1q:&+iXJA:=WbkEqReFJIXahQk?nA!Y9$5#hD6/RSY>1
#?AA%9 eG%<wLIFQbtG1t/88ZDtR!G\klP=aq>A/!G^\uIEtZL^/KYdJYeR<8@TuWXR#NaFym^aS?DaLcD/lGE/
NFQe+/ Rly+&YCKahFTMTdp5H^QMn:RWy+n%m%Dq&DV>Chq:@4?Rd!D>H!!c:*W#=<9a@RpQ#GMtE6Z>4M\M6wh
*RnBD< +BQy%Mwc/<6X/<i%KDNyG=S4\eJN5!#auY#p?Skld96VK&$cc9nauHLC@*F$CpPnFMDYmhkQn#@!>8Jd
a@%Q>! MmeS^eDFLlP?CC5=<QMH:\/cWPn<BK1^%AFPQ9TSySi!4*>/CQM?SD#y/LwJXWq6dbaC\dwPQcS<K9p5
CH?uI5 q1pTpStwY?dT+5VM5!P*\DI>JZmaKaCW5@Q\u*>+ICyu/EwPdA1=c9iREDNQEpbD4Buj1!GuHZdbp>dF
mJkm?: 1TwnKeY!mV6d>Mb+nH?+u=/IiZ:kIA<#ltih5CVJ6M>TtW/BkwpHji/H4:Fd>lh##Tm^dYE@9bD*qanJ
Mb!8SA <<TjT+bC5DY#9T$+&uVhDES@HQdH6Rc!jL8\Ve$!Y<H6&/le=lY>ah5\LY=a&ZD>%IwKn\5+kpS1&y9Y
=GSXWq Vtm<eXSA^EA!l6kk$+dD1nVbSqTSm#E@%MGG8wywTV^4KuNeBXCEwWcClpWklhJHpy6ZL9R6H\M6#S/H
LQ/TmY /ZKTpG9nlXBIMpb%1jVn1+$S=HIMVj#+a/V?FYecN&$yHcCF64/#hEq:A:*q/B9mj&n^<:>CmBc9awiD
-A8MlY 000067125c200110334 Page 20 of binaries2.zip
jYa*^D XXD<!Bq6$m*1QRNanuw!CRKHaJ%GuP#4D>T9H#yGlLBGlw+HRd\$^P1aJnY<?@*=GP\\:@Kui\+9pFCt
69m1<w %1t:>8Jnk:K91CFpKVb?:a5y6P65k5j&R5LT?>&t+=\#Qpt:m<cGE@BkY4#Q<wL=M^p9+IyDRCGy@d6D
9LmmmP 4WNiLRP:uEH/M?eBH1AI1hVRERumhE$XRauu8+RjiHD?tR=T1e#!HBWdJ1RTnQ58&ECj:Y&PDNYaj@!6
e#6L>< DZda:\hG>XSiik:E#b\TJaYCE^T6@#ilm&tae#n/+/H9CWdM\ht6a4#dmWqIDh/^8&<$ITJ6yQWIS$ER
D:BdZ# D>9e&5MSewWt<<LC=XB@H^>4ZGKJ\n1V4YmeEQ6tC#kdD9\yaaylZJ/j<Rb@IIeq==!WpEVE<:@F+<qD
A9SDkN #wX+h^*/pd^\F584h+$YLje!RutkA@mB!PM&DQ%n85>QlLhcPnFKKKJ6CkX5DwP>8yy+Lh?&:GZMESIW
dR&D<e MA4CVC!w6/#WpX6AH&XpZtVP/$4YlJiVH%w9uwe>+aa<1^E6XM5^bGKiPC#$4Cl9HIdjmQXNbT:k&IS5
nuW&J< DE/+:=p5<mI++Dh*N&MJ+Xt>auZD?Z=5Z6?+uQ1=h!$PVN>/DNm*CW*N^/M@ceA4Ze6T#?H:TJpSY#E?
/i9&Id FcLPa5Kb8uTk*?J$C&6Hky4I>4G==P5<==Y^qhLVS4P@hJq^qCJPC&mwLN8TnEVuH&5/!I/BblH1n=IH
BTYmeP ##jE>+FYT<>j><Bh<HBV@9X4DjTPJPGyHG9@NWFLKyetHZHEBq5Ke$&nTW:P&&h:CmSYbq$M+^#^jQHG
lRR%^* #R6aC/uF6=da9%HMIPMDcdMmhnpR:DQL+Pl5hDTi=GeAkXj5QnQbA4BJmDT^wcR=mwPY/X>1*@QVbE1Z
TtDam= eE*jNPP9&yL&q@=<tTwa9@yGb$Z8jW@+D>@C>FPNuj9>$m$?A\MiweBHPlB@%MR\XQ<=MHadbn5N/#pT
ckZybV &:D#Kl&q!yn\uaFaFVQR%cSdy#$e*4PmT<K>ZNcD^Dl!i!I##%eVjDXhb9uM!CBRSMc^PXtGkNKIwXBN
=#eYAA jR\E8^Y=qn%AFA@BQpm9=ALZdN=<%GK#%<c4wdGIHXmlqpE!RSS6JCc6tSAuCtwpRD4$>G5Cucq64/:p
l&cZRb **IY/&k=>:tR8DuYJyXPRRctPG\nlucnp<cF?Z6mbHe1JAGXCu!E1e5=W^JPp<+%u^e+L!/6!$@QW/uD
^6Ebek />6e?<D+J?yQ@%Miyp&EGaD>&E1lDG+@TYKjLwj^mw!PW^Z@*GMJ=>y!<@8e5?ZYK4PWkFRd4+/HMAhH
#?phkE b8LaeFcA4HtSpIYwn+=N>DSPnCR=NyDYkk&@HQ@H/@<Mb@QCj5JGL4mqCRP8E#eP#Y&&BjQl6E*t^EwX
1deGp5 K^T%\JpjASeQc<1XA@C*iX?NbY/+H!CtBk\Q+^ejR?a6JAjZF\LB5R?Ntu\SA^e^S!N$FPuZd$TDV9%+
>GkJn\ 4n#$$%t@>jMF^EwcW8QDuK<$DF^aMZ>Q6+M:T?M5:A1Jab?$VRp1p^PB\BDR=lRN!$Z5<a=nM8N%H8$R
:wA8/k d$PX/cEQ$4SJPK!WjTqG>MR#y<CjXNA!Cy$6b<=dZk@X%a&:NDBb?^G*Z$b<Jta9NF!IR:1i#6dd4=yF
Ee:w*d KNi&HdhnmBWR#&TCCtl8mqSn6%$19dQi/G%4CaH>?i\i!RhkC!E?ZeL69D#n5y%Tpt=*hy:QW1b*ERP\
eAkLC5 mmE+wScD!\cRM>$aXDlP@<PAt*#kZk+D^PtAp%5yN$P5klF:F1SQDei@uEPaaFkjY?Fb@u:Dh!NVR#<L
mQ9/YA Nk#D8$PHDM+/&5/=ptCbNT6ZyXwHTdZMpLeV8qY+HcqQ$I?iPGSZVDAnePQqVy9KHt5&8Ni?Fb4#e5+C
u?\&?w \IJMmWa14EI?k?maih!jiEe=!yT#@4XZ^&pCIX^aLRaDPM*#WCuy1^d!+uQ8cq%4IDj&h#9eIh:I/MdZ
d=w4y: 4JBK=5C!!K5*\@wk%>VQABG*eq6n#uD!BaVKlDe\d>bR4MXBG1^cij1m9*C#yAkSnTHAcdy<>t6GV9=H
uedikF 5y>#l!AHipJERbB@pwEB#GZ/F^:&S!<%4#\ncJ4$QmiE+dcj=Cwk++*GPeiRtPn:qAEV\4kkEW5?E&Zh
EJWtDp eAm/ZqklA@aW<==ehHY%ZXlP5<F6ZdTn^P%54lE$#hI1:YC%<Ial^^RK\Rdu=@NS>*jp!uQC@VW<M<!!
ijl#^d I>MZd:%%8\qEP8HacWWFY:&8X4W$VH$BcQyQnbAP*X<MT8=DAZ^nLb\4uT8Rk5nyK5:ujdBpSFmJ=pHj
I%!wM> Fk=SujTFccZ#EH4y6KtLjEVt9pq8ke<y1qlG=QtV$J4G\ETyVF1Gin:l9D<m&6k@u^ucPqat^eYt&5VE
HnJq:t 1c<!Ya9qtu^q/Y+Ny\mjVmpuc+VDmyJK=&>p#ITe\%S:Gw<1YKeNY!b$el5^!81\qN\m\6>#nNE\Qn+q
^6jF<L KYLh4t\nRKI9!Xn@F&p&y:M$PECb5%a=pbW9SeRy6Ca#11yI*Aw#yjmNl8YFm\Cp*SuZ:<AL!/\n*m^d
?\4h@J Cjh?S:?F<IM#1JME5JI@4P9bu6R6b4ib=%=!:lP^SEmM:1e/$n/pm#pM/F/Lppiq4wYVp9J?Qk<#bQA5
><ZhDc d6nnD#@V!ySE1$1e>$5:\1Y\uKYBC>6P<t\GZEeaXLD@=8R+IL9Kt%CIQAE/@QkpH#y#YwkPa1NT8mL&
J:KtJd :@<4K+h\:l9&^<1wddb/T$Q+59K>5iW:bPcTBepQ<%^uMbHRQdZDTIKi$RaW4wG<JFnPRwHju?Hk#=wY
@>cJdk D:%duQkLVACQA\6%cHSNSDQRmQ4CA8QZtRCq%uLiXIHa>F6bV&GAEhQ^ayIVB/d?<AmbMku?jBw1REB@
QWk8C* S^c/!Mq%i*#J@klFnc*Rhn9D\>1ee8XeW&Bq=ttw4+Yau9EpVV=5e=%%I?H65i<!ainMq?ReMKKCDj5+
QZYJTF ?uL#iT*YKumw>Ec1@Me&*h8#C*T>6<MajXWB&XElF:9e5KAMI*PC&YWDWwyahNE\BmDTb19Xw$mXyEZk
*d%cq? DPZB<MK!\=5lEM!#b^/6HYqGJWp&Y<ptK^+anbWZpT6VtyZt&Kd9bhCK4wM=luTDC&S11ZByQbE<h&%6
\*ydY< qkq!XpyXAGJuHX46F5^n:4&CjlQYj>llLe@Ra#cZGV%tbwWZDK9EQpnt8Hh&HLhLF1$kb%myd%qYJqJc
&c\SZj GAdI>u9JZy&<:QG\y=iZH>hH?AK*mF5bHa%am!Me<Ph^^X!W$jG:NAS/E6KlhXmKC@VShh**EYwcypq$
<:<Pjq qy=k/jPWtXjX/ct9H+:%k/b49Q*Mb+iu<QdTAtJD6PmH$$KH^:p?Vdb$uYR<K^j5PNjqP#Kpq$!PQVQY
&+$jDp >$1bmNNkT=n$$GTnc*%:^P*%$&h6D^Nq:PJtbht%#S@RdeKMbI&WeNmGcj%NtK8lF@a<4D\KI=jVWblE
5mbwta K:byVZ>V%#LK+iWJl^Xd4JLZeEAWHkbEPL%9:dD*RDwIwMMp\H5GK+=CQYlKWEbW#?Jt!iwG>QNR6^\#
16NunZ LbcKGR@P1?m?4&9L>uXB#+iuy?NJ$*ctMpK4bTyY^t&MyTW%5Z&HS8kGuZAp98pZ!9RwMXCAhFlKce$H
NhL?#J J<QneE=m?cuqwNQ%?1F?I98$D^HJ9PVTIM5lt9JNbZ/I/+qeKqe::nPn8JK\5a#VtDbe\l85pycquEcG
B#hKyH L+VBQ1NND:54Fm%w1HPb\@BIQKZeG\l!kl@DhPc*$lIMJWCeF&ucP=jWDq%k+$K?JDBMR/6&1D@DbmSy
BJp^aq Q?m>Q15^Y58ILla9H@a9i<p/pnWIkW#*FP=B&nI%>4wL^MVRNHJ%FbE4jZ1YXmwPjW<D+>DM8ll\IHE#
u9u>X= W^!Pn@Y@MiE@Nn4w\:C++!59HDPTkKE<8LDu=$B$ZQbNhcIq$9e:i5iKli6J$w!mGLb>$NCFy#\/mj*C
M!#b^b 5D<hQ/ekpdu:?u\G*GeTpZ%&S%=ZuL>jAabV:8&W\lW:pMwJ<*!aHMLWJ:uTVH+hCHRXA:ZCFY5k%=aw
i5YH<V n:DS?GeeI*XbkaQn#FGZ5nSD\W49ytFA^IpV/$QwnZieVAu4JiW?Rw#PS>e1YGd9jBk&qq@/VP\F:F:+
<:P>yK m8qInjm/j6w@?&i%Yd11C*L6YhY!n<K5%*ZVlAje!6nV#/Mk%y+dAw*ARRkK!LT$9Xm:ataBywwe5LH^
TSu:?G *#=S<Ic6n4T\ulQnkaY?@=QRkB8b*Z$/ua@AmTh=6/NlVaT+qJwV=8JZ=XJDCDPR@t%>DuLGT!Bh1XKF
>9#XC1 tmTF8\t*GddyTS&1?Bm*qmqHtyqmEjnRmJGJJGFP\!jj=1=jyTZLKK/8HMj%EM+jmA5LL1!T*6W6?\Yl
jPyC8A \\$P*LTHJ%yaqyTL9N$Yqe^J5S\RmM>G@IiHJ&=>EF=qQ\P=J=lIHP%b6:PlT!ZWa$SA<54yyWhQZmDp
wc>Cy6 T*^w6btJSMZKW^ujwFNp%81*FIyal4Tj?!y$eeij$#Tnu4NG#yH$Nl!iaFhaYPVmDF^EmX>ted/d=DQa
bVDH>+ apBqHbGiD<MCYqc8aKT1H!RhT:H?GmHR9#+il9d\kIBqhyj$w!&#mIIhNn=y<4AP/p6/uq9D+k/6*LI8
@Mu85T KDN/t^?jTJpRqhVStbKE$i>DP?eiKeu+%%Q>:9qe51jT>N9*EP6>yY$C9GE%ibdabWGd5*G4CWL%uCP!
D/>N<6 T%@ItE?4DXn68HXmj#pd=RebMndjyR:/?*Jp4>4yIqjbjMTPN:#D\8@m8@9RThhQ9i>@+!hyiALMDZpa
niLSV5 =>/Zmy9Pn$<?cH88EZ16YVnBtAeuQdDN=<C*bi\l5cT!l:*!ybmDCcqMtR4MEuwqIqqAkjF4$XS#IeYV
=!GI#w mB1cL%ymRi/4eD4?pWY>lV$b<@#nw*iDV=M@m1X:<D:LAQ?*<*nwK:q\5u#j5iKu$8y1A\tiww%9G:&8
KnFKKM =CT1*<%>*>G9%=1bEI:=NwkT=db#@&S<q\1eiNh9AeQBNV?eT$>?\dm?5=X$jK+acuj=CnB^=Bb=!@=B
R%/8aJ #wPS&lDFeJLT>LnncdjhyGu%Gy+pWY&Hm&P+!\%u6iPMw/\1M\Vt!uu\\*RnYl^@DAFAtKcZ+<bJ?<Nn
DmZMX4 jR^6epuwDylc%+?RqHpNLT9Ikpb+wS86*Pb9dSk@nReH8T1*nT$y5YPePSGAdGtVeN+YEj^wQDFS*mn9
==&?#d Y9wK&kM4YA*i8Tl^pSeR&CpHe1kQ8nyPj/ZCGtT69m9G*dd/u:jLRC<Wi9Hc?<8TSaXN$#:mXKV<Swiu
FCnJb: VcjuQ6SQ:VCpVZ9YiCcw&jq6?quM8Q9MPc>qJmN!<u/i#qn#mIIRwY9p$Q11E=^V5C6n8Ym/PK&k^/8q
%9ZaE? XCld&@<k+k?G<#4de#LbMD4T1VliiT>/aWqVe@+:ZMJq6i&/1yI?9QQA:^+$t4<juddjBK9DcS1cW*Zc
=ld<\W iZWMA?@6MMjLleHNVP/+#*L*yp*&GX?=8^<tCq:p!wHy9uQbKmEC/kD:q4Pmt5At6V5dnj\M?D58VDTm
N1<^n= GYl:t+KVMaG<pyFeiDVeYKAXD!q9Yh%%!5aRF4c?TANS6j#nbD#iTJZXZYbIlhG6dmkp8^+NE&=eT/:<
P*\R#* &LiFc5yj?CK>6Ya*q?VjYH<H<EyVyw?VP^M!A@4h*VdI%i6<X8t<+L/Wei5B??jdub>96w6m6h^&dAul
j\5YEe NDLQAI&DDTYiD1*??ccd?==!K%R!K#:j!CB<!+=>#tTdXH>pd>n?+dJZ4<@i1%E>c5ayVNNnIJ4I%lpi
aG&1!L h5&MMBFm#!MJ@Jp?DYqDy:i@w+Y\nKL/XKNPue<FN:EjnGMtYP/9IKhS/%dL^Y+CcWaI!5etb1FhKkGm
BuBLR8 \D>W@BE6/:Db#FeI@^Dqq<w9Nm#6TZcM6SBFypG8&&:415*GC\NE+:8/H=>:Gj$>KLbTmPetqNcuQE66
-Awy/B 0007aa8e64200110334 Page 21 of binaries2.zip
t#Z8DR ?/E=R5DwP\MPwV?ci6:AJ#Hl>PqVQ^+q6E=M41+$:XZE1XJB=AJPkI1Zid9BZ$cVyJY=5/SQN&\8FKYF
9VeY4d c?X1#ELTyX^u8JMJA+$R9TSy&/clb!#*IqePu@6n=/?#&j/l*q?\:#D/qYiT*IRhtl6ktFTH:bq#h<pd
PH*>t= TI^*q+EWabK/QDeyGZEIVb*K+JuS!L4LnCkIFuLXCeqX9m!48Bnddk5Fnh66&<X\H>Gm>X814>JVhNJj
VpKny9 >:*AaKJ/6>m\<DYTZdlqB/\#=9aTn5BXX=IZa@KI=QEk#t6Gw/*ZRRYlWBN<9ZNjnaH4$dD$/Gk@+VSe
RD!aYm &HSRT#i+&IPtV1j+pJajKX?=V@P9:B>i<RF!djZCn4qbMaADTucS?l&uyX4tq1!V@BL>1@H$p=*#MNMy
8u$Dm> E\<dZ?LCpp%qJFM<=yCuqlu^MD*d:4X*qAwS*+%Gki/4H%N@/Z*qlV*&K>#Cic@J=tN\Z6eCElQ4@XiL
KCbJAA CnY4Qqm/@bVaTeyZ*6\Mq$QuBkZd^A8:lEM%8iNMKR8h=uR8PYMZdG@PQ8>JZ8E?mGDlQBeYiMMap>mI
Vm:w@u !H/dq/TQe*EtE&/c*DE//C+WE<55mkLhJT#Y69&+eGG+V@8Ju/HHY%chTcS$%QLXbj>pu?n8Q<+$Z*ZM
PbVLFP EFdp!pp@jql5J9We&\ZG8>j%F$Y@W:Rqbtk:XmQbB/8WPGb&8i@yi@mtLyFY$5tt\/in1DJyXRllQt</
w!y*dV W?kEc<b\Zn9a?WEY$KVwD?8%RP#/Spc<:%1P&k:a@@*t9d#Q>XE!=YecnL::L4TDNL*?u\tLlBbdmK*/
5YeZAd =Q^q:VZMHPY1l%&qE=de+pB9c>q^$iGKLj!IAJu5M/bTa:cb&w1kAD<4&@mM>mqdyR*<#wabSip\%X1H
S&5nb^ !6Z1jbZcj*V>5h!1G!YHu\jRcLwPP:pC\d&*\<!8KSQGQ$n<K8!A5?9Z\QaVWDY811uC=:Zwp9M>dX4X
i6aBF> &QS%hVG5nXDMXLBiDY@Ty55=S*Q1>F4HpZyP1&IAl&=FVwW55<14$SnB+IkApc6G^bw^NiVaI4J@pIwp
DFCKi9 J>KQaIl:G*\PE?GGPWTW*FFJP:4pLG>W49A\=$jJMyy?b1RjSnN4L+SA/jw6F*K+Yen%>=hc<XZQDTH*
Kl*mu4 JhK>mkG@eB4P\uEyeeh$KcS%T4uD4TD4V8cYeq:SE8B?^PH>ih/Ph%8y</SlqI&MnbVTp+\51Lp^TKl5
QcQQ== <4\=B@D<<QAmWTtR5h1R5@?1%1^!HjQ&eXI6W^kdViP9@VD?ZKun9ZPPtaylc8&4pTF8!K*%eq&&Tu5j
QKw&$% G6c/h8hc^DqNTX<yVWmW1$\Xy!QtqjZy5t4cbF9Ema>pHIPpSA1l$NlWq6!%\+Bk%q#u<:6pEp!\6QjZ
H=\B?P ml?PpwJ^kdJq?6u*ijM86<KSPhjEli<qylqG1q>$&IyaG:dyIN^\@5:&J1CjNY@/5?L/SX\%*1#T5H@V
8q^^1k 6SPddQMhG>F#4?^*jm%%4EenIlJIWTF1uNl$&*LDb4hIhC?nVG@I&e<@&\1^S9wPkEVKp59a>WjK#AaI
@k:Bbp 6n::Hl5i9^y#au1=9k565DIXN?4VDHcA>9*?LCad%^L15P5?8n!Q91^#hdWQuk?+b?P$=dl9lTltll*w
>G\NnY MN=GmuY$%AY6hWV#Wu*j<dD\yw8aSViXPbPlZt+&T%^K5XNNES=SQy@HM48FRn1#%\ScVLl*Qt4*pI+c
51LNSN c<LKY%mH%/<IdAu@%p+Ziq<Ym?y<eiYypml@*B8D1=GTLVcMD\%+k9ttB\C+191l+wccuW>qEyRYp=16
Waau!J &*FX@H\llJi\^IInc:ZV4QI@@IAuQWwc9$HE\AW=kBi<>N>!+W#LnGjym#DF%ej=\wlkp:RZdF%#SkZi
CN=1l6 *hM\XP8!tEMF?@+Qe/ZI%tT%8e\NG>Be9%=EP:cPT9mmi\Zi&BS?wE#d$AEA8Z==<LKA\HtCP>Jel6aR
^q>#mJ p<u!>KZ$$uqbt<yjyyR$VSeTMPS=5kkLlWk+KB/9+N^m\IB&dCclFeNtj5I<i<+&:$4NMM<K!V/JFl>:
aE^%Ba <B/ab1F6JZ%*JhWCaT=<NeP*u::S>:%dGcS*Zu@i:#uE4#haq?ZIqP6*Q*?yEWR9hh<F?*AQ@a%6hqc/
dY+Aa6 H#u@9!V:XKa8nLah=/<6P%8N1^??>=8&SL!#\H9Dlb^qMnFGhn=aHHdW&kZZVpHa=E<yjV4qFbnBPy<y
QlHP\> YK+lPK?j@tL^6NJkSGT9!mk+#>y/uX>%!iaQm=S$E=TMZtA9Jkt&@Z#JaipHhQkLI1+1IB^a/8ju$\DC
=DBBmp *e:PwKI4C/%6^&1IYcV5audZ1Gm@^=Qhe45w1#VMe:MuSNwwiXm&:TYp6bFl\iY:9NtS#KS$My1VJ91B
VePJ8G j?C/dqID\t/PNG#mV1M4/ViEZNelhP9#?JjB6tG$IDWF&GNtZY$CM<EN=/WP@:ij9>RZEkwEIku?eKN#
nPNM<q h9B!&kBZ44G@nRME1/l5Nn/S<i?MbXe\%GW4P@:eC5EThQndy?i#HLbqi:Stmh1JtY69wbR&nQFQD!>H
mjdPp6 iJ/Zy+iu@dt?#FP&66@+T=<V9XID5u?&=<%Z$Vh=l/Hkb>Y5iZJ*a@=A>#E+ttHZl<mX>*YkYq8ye#RA
SyY6!& j9%lt%%uINwhmi>5KF9P^4KytyN<Zalqm$DDa$iE:PFy&pM6DJJ^NI/pmWtKb^6y/8FYMe+Ba6eG?T%\
u8wQ*Q QE?R:QqJ415@c5d66ktM49IQ5bHE^LpP+>TG%PHZY/Pk\?/JRD9l<kwj!9Gc1RuW+\E*YcqqFaj/qBht
BM9Btq yDEeQ%$55$W?G?Mm#mE9KYjMAN>VEu1pwQ\>B@QGRy>PY*ID&QPb5#@&JN5*$kRBMVpyWGV86%:PImPY
W8tBw% PDaICWnI^J&6PS1/qnETtq#SLjP$V/>jqT1Z@jqph=iiD^uT%HjP1yk%@$cV9JuL?a=DNpBuBlaABX8@
L>TGtn <BtVSNLj&m!L#Y:dZ>tC!/l*@KqAl/Yd\>dPt8&eQWqTX+XwW^dd>b6!Pd9ALH6ap>i*#KwIN18!Puqa
%8+y%% F^=utbnI4R@#wAEXH/nQ>dpjV??cJ8\#i:>JZm&>D<DyhtC+8%:GQR5BP5^ihT/#1+Ymy/Mw@cYPLb\j
El=5F+ +uSDml4dWE\BM^Sh6uW=aChEdJp+G$T1Y?+9H5G9Jw4D8Xk>&5kYaYqPa=N#IR8<V:KnyjGSYDYTQ\58
j1w=:% M+MhVphL*!c6&+8u5jYb^qmCu9M$BP6JG6KEh>jZiinTPVpPp:\cl68edWmc14=K@w$#kha?=9CBI899
R>TAX\ 4G1D#G/hd@B8P^L/Ee?+#ZdPmX/ndpBQZHTYn8FKNq&^A$b5E:^qtFX6w8&+@/$hc=ilnJDSb48D+^JK
nBmnEl V4*M5<B6pq$bZBXhTMbDNt@X$15C%@QE#IQ9b+j4wwLe=jQZH+X$h*/1hh*WVdC@ab/6ym>w1QG\XLCT
b+W4Yu IHI:X\#DR=#P9tECwyIy!lLSejynmnm#=I#QpI>JS/YjAjHHZDMH#J9N:FmJ\cG+8Bw9C&+B\EW@CN6a
ej9>=Z TNRNSWp8^bKDb9ADD$IRnBQGljTlnSBIti6>pneJpc+XXQmRBBjk>GcRt^q:j@@JDtM!B&1nGqyT:YXV
<JSGH1 CZ65F9u94S5/bb*MH:deBS1SA4@EcW?Y1/ZL#lZS5me+F<AVCFlM=yMEtm+>bE\k?*pdkCq8/EV$mp$<
GZN?WW 5liL>BnLVtnlWtSFy<<Fq:nqDM!YA=Qe:F$kjAQap&5:nFWRYRqQun\>TWm/+@:qBH9wd1/>/#jTiN5Q
GpetRL !Wie\!VNZtcjE1V6qAV4LlPhINjh6l&#/<Kp5k?H5^+dZCdPeA?DAVpuZDcn#A9jyh^=9NNGJbu$Kl@#
ywmpuG w6^Bt+&E?>IuLEPG?&ETh1p4X>mm^k&qb5/W8*q9PQTnQ58YSQ\@nCl=Q#w?IA/hP^\^J#Pen4Z:9QV*
!YJ6>@ bV@H$+dy9VyM=?mj^R#L\!NH6t$9qYANl/SjjX:E<ccd=/WM%BhW+%QF9JJQ\LutZEnPwd!LakhkC+@D
P@Zei^ uGGaF1H6SiV6^dKRMFDKPVDVK#$DETXuMJ:Q>ETie#DbW=e:I:QAHb*N?c!NSqLpCM6a4MyYY<6iut%5
aS=?eI *ei<J!^=uTai<QGBZcPEuPVL8Nt8NRE\B+wiyId+6RIEZHqVIlcqa!8>yQ<YFla#HBaQkn*eieFQnKPW
TyFB4# t%Lbe6!5&F$$PCj4baPRnw:JT&upMYGLnZT&5CX6DjBXtccC$$%^a?Be>*9+Tc4j?h^**k8Y#RJVEadt
!JCEE1 k$\#iQK*^eTwPEW*I?tcqA5L^<#MG>hX+Mnm/AN68y<k+t4I%e$Zbk5>VXmcAlDRASmADGR\:TZKn9KC
S?H89m PeNq*kHM?=ph?W\\k+uMJVeL=RSTbpatFV9M+YSt!NE*W1p?p4BaeBEia%u*:eH8c<%MTLki+l&q%N=K
=BecWW j+P8^1YhjVt9Q:p5:#q*#mj9mA#q%cjDi9&+48ttPTJFX1*#t>#IdV$Ic*4N9EVq11nIm5K5iD&/knGS
jZp>5N **GW8lNwnk5:cj\Ep11AytSa#ImawiGk&S=hp5dTAA8V#FeABG<ZiN^=G\y&wZQ^BFkG%<apbYZ6B/t9
Vl?pnm Rc+%l&lRnTWdE>kBQ4qZ8ddB#1+jVwq!8\I6?FQ8%*&/?#^>uuJV/AQnyby6au\eP!q:p##F4Z#EmG:X
@Wh/Lw \qJ56^68cQBejmQPCbe6KuVC4p\k6tat1XYe4bTMyNFYWDYpMn!e4hGTWGckt4WCcX6:5b4T#!%V#*W6
?Fhj%I u#&>:*PM\5MDPDmji?My44k9V?K/Ip=+\/cmutYa94PTQiZjQ^^1jFuGVNS\^GqAEJ>LGjeA\dIpwQtt
1QFm1i <cVIbpXSlAC*YBbC>Y&w^N>>X<Mj6V/C5W1:%pK&dD?V4h%#PTRVBqAjEmlGa\QHJ89KS$JpN@tA%eQ+
$?6ySD TTKyym55>@dm9u=R>*@iT>bi$FAI5hN*ptDSKbtPJAIjD:aRD&Sn\p\N%8tPS@#*IGKFulS:laa/8@X+
I&al^# wM88/+D>GalM6q9yGWMRuqbeFJuQ&:VcQ!AP$tbatmK:T=i5YBb5#8qwCZZR==:ml%q4J+ud<pLtdmpV
=EY:^T pZS$ZwlI\4BYQCh8CyP?jGNqkCi>^bSWGIF?XE\<1t5N%#hCeZyBIJV&p@L\1+&8TdMNmPQEdDPun1!j
E%LHL% JDYy19=SH61J:B\+*=BH:IyXB:t/5Pia@GXG:B#1?N%*D*/=+kVmCKF:^<EVqe!eakZTB?PqyVk#G5>l
WW8+jb &>J6EiZqKyZF=hI\/m=L+1SF6cqM!GEDMiA^:YXp1SAIy5el1b8HMWC*VHRj/@*b^&HPE>@q?>@I:b=c
kZCA<& %8t$I^mBaV%qlHnW/QZPBpdumYV4@hBQl??\bRBhpI%tb$LDBXnAlcXeVi8AG%1*T!iLPIXW4F#6*Qh!
p%!ubj qSINt$CcKtj!LbGYAA+J$8n5$9$pLD&cjQ$eb=9DFB<F>1^qcl!WYdp<p8a?Ccw+?iMV?&HPR/MqIu:8
X>Y\Bm AuP!D$#/ZQF>>4dYmdKT*bBFACRQ+qX:&tF>+I6m6tkXNqaYXw1WW:4MDdZVd*jYID/DLX+ADT&aiTCc
EXSt&E %DL%\#D5njp$L6A8PPY&dEyJ5<pE9e6CMTtqN*+XXk*cD$+T=ih\dT>nRb#EhW!u*S1PlDq#KL**\:dC
m*+PGX t%il#KhV5DTSTE+t^L4ZwTKq%!%&?l^/HhbAaEYuTdu/#8&uKR&1D6iIEK%tT>=Gc>mGbqbMNynG::<i
dh/kRB yt&!nQFl8l4n>SPV\SVDq8:wT98$Z%>PcT::8Jq*a4DPtZC56^?btFDl*ic8H@i#Jy944FQV^RZh*dNM
i1Ve*l eBV@GtJ%KhGGReF5Jw!Ndy\WZHd$q>yX6AKiS!\K8dy1T+a6M=hPJmb/BLTehk?\Q$KAMG1+HkuG%QmH
-Aqk5% 000461af32d00110334 Page 22 of binaries2.zip
ZYPM$j @aW\tZiTk=bB^l!D+&cnhMVh^e6M&AqDb:&X5phQ+<NlJY%c5$GRtXEqZEq!k5n1bNNdJ%BlZZ?%Im8:
4NVHJy M#wuWVKy&nGAaQ+J>&HNS+daPmI%BW:+bGX#wjTE/uJXB^@LaJ8#hGZ6ANMNAEI!uYjFcXY+LqqBaZQh
=+eYe8 5bRCcJh\EGyCWZd=ZKbwbW6e/TR6PS!TC&=H+ppy%YyaK/CJ#=BCETNiQ#*A6ul^QT1<R=lF%nSnkaD:
R>wHXh cX&ji/JE?1wp5ha?c<?KylGBPJuMaRS:94Pd##=58Xl#G<JZ6c5P!GpqbP4PW1/!hJVV^!dR:e+kNwu!
+EERdX Yhp5Ph1uVcnjPCQ9ey^Z5:#qpLY$Mt^KT^EA#nmBIM6!Dq=k<y6y^1*9B+K:96IcWpFMunJXnDBYW8F%
AYT!G4 1Jij*58Fjh>A4lV45Se+eK&=5SL6Qt8AwH*:<D4:J&=+=4mJ6%\j$H!YH<S@c\i=in8B%5Weu5D:K1$W
@j#<hq *A<WA#&=WkbRnbkIHkMcy*K!hD#DYb6!$>1pH:CYewZw\8+&PplDt6aVtTEHkaiNX<P5$R5XlBeY%=ZF
u<w<Ll QCd98R^K/bKN$J^8*jG\>n#I\Ih/>iuYHahq#+G^:GVFq^dCtk*VMD+h+\641amiSK:mIHj5ptV=&Qpj
^i:?Yl GH$nj55@J9j#PQa:Z$ZZMD!dnq8=q*piZdNYeRi=%y6Nq5$k^t@mN$#<Ikm@#8a+<C@9?int8*R$q6FX
l%dK\* q:tA:m6?<d?w#hIl/@8Zw!A>MhYcdXL4^Caj=6cw*1HSCtwn!Y<:yGQ+nb>\<hhlF5WN8Xn8e<G<<XG/
SC9M/% w5ZucN5<HEWEEM^$^A?eyL%yw68QQGM&k*#?TtcW\6VkmY*th?@^NnLDjWAdTG<T9!y9dpbeMBP@*t#c
M!uL&F Ku1X@VLlKwhSA8hMI$Q1eYi4C/*Jl>bJib9eLQ*ECiS4Dhpqa+<jJhQaV4eTy?kWau%eu>LW&QN#aGAG
BS^>m9 TCdby4%hT?8/4E!TJBC4H%\/#HulBLN:Yd/VVDmBL=Vj+:9:VaJjdD!989kXV8!!4G*VVV6/B:G?nX=^
WL^RjY CXV$m+>qJTN>+6eRH!D4/&bJ5Yc<49PmTma8Z!Re@MK*NP:Ht$#/hRkTZPK/Q6AM+<K!w4Y8R\Vi5Qn1
^eF+:Y yHk%FduYm9!#jNQZpQ8hldIHAQ>$#&GJ?CF*+6Nmaheke6#4jbWT9@ebBELtRLlD&ZZ?1!bNp98!4IT4
+n/nEJ 9&GuD@6i:%?dY+St>:kR6b@npdCal/>#FTn?D@c5LCHY6K\mQIYmYMC?#&YN<jc4MdP?#*4Iw?YF^ZGJ
W+=YV1 nX?i\4S$n1NlLKR#ZG6bGK<ZNuq4j!WNiLcjTT%kkp:cT#J!Gqa%?4e/jiZq?EA:HC6\*=PpEmpj%mwJ
DTc:W& k>GYw<DE:WVC8/QLId1a+4D9!IZJ5q@iC$Lp4YSRl?@CPXZR@BGiV6JYa:?VDXIEY=Nim@8QjTDRe1*y
8!8qEd ?j\EIQmCE=MC4lu>SkI@^uVV1h^DDjhMGtuNhTB?TiaC+InIY6L>nY^lL^RtMYjM?^4#4A@:u*@?mX#W
:lG^9D 6uhX*@$5H%?+WS6j!>n#pDQDQPYuH@@d##@Z^8Q**jY5j?G4Eu@uGnZ<db%6kCm!&hkWuBbna1NV^K&t
lpRj\J 5RdBHnWbmNCVZyAbtj*Lj6wV%:kY>YVD>Gkt#qT5h>!^hy4&%Wq%*?#%YG8Ka$?cK>5wTK<FTJQ\BD1e
8kJ^I> KH:H8@!JelWKC#+Xnw4QZte<c#wm\<1dp>YV+jZ@+HuYj$lMiCFWGH@jNC%?@#tSMT6^$%RJG=9tBI\e
9Vel%* #XF>yeR+F$$Fw@iyLA&HH4?<9EnNVlHp/j%:yYD1NI/>I1W*9@KNVITyZh%*Xey%=X&6c=$H=Eq@*=Cy
hk?6\C @Zc5>Y9PSuhju=Z>hQnu\%F@@mtluH:cRH8=$wDHC^<?Lum&dBd?*yR<K@\y@9FQK%%eEeh#MtFaVeh6
HVmKjG pCSFj$@*5y&+%tapi*^kC^qp!p>JwNQuJ&Ycm5V\b:E/>9&Nhc?hd6QSjJPWPa/Tcmd!qdWHN8F=$^F\
5DEZdL B$J*^nZeKXMXXGK<9*JXBjL8=WD!BESwSBiRK=?CQwq@ZHd@@8ij&*jLu:@W@Aj@#?eGZ&nM4@pe<uuS
TbnDY& NJ!<#GJtW!:bWAaLXhqq%?ja>&EXM#S%tSE:phZ@<MKc5?4t6$h*cN+*8uHQ>qP:@N%:ucIn4SC?Z/6K
/iFhK\ 65Sb^Tyny!qZN&>N5@u5>qKRq#q/9LCW^c6TelTIaiW\6Rn^y#h#ulY\EA<HF+9Hh*@L4@@Dy5HZ6*hy
ubF*Hu Da5y4<#^8?Mu9#ljeTL?l4Yd1IypZDc<6A+IqDJP?LWZSNk+\$b$9*<=%/1EXPAy:8y:ZeiwVwiDIu%#
<nZVnt Zhlt^E!!XtyDRww5GFc@/4Q5cbG?Cy\*MVjpaN+btWQR+pt4ZL?JVTnm<WaK#1FeDZW+q%dXw9n*XNbG
a\epHa BA@D@V@lL%qp!jQHc+#BM*L=h*^Mid+\Mp<9#^D:qF^pA4G!qFq%I6N%GQ#Dw#4#dpq6yq^laNdHHlDd
Hl*>LX W=1<D#HdQw^p+Q!1XDQh&wpXcKbH6RB?tGbFiwX@t:#up<Inq:\@A=a>=jL1D%L9d?Wpc%tEkM@ibkX?
LLeL^* 9?iAi9^R9k:QtwL>l#nG!Zj*DPQi+DXjDP?4w=%t?c:lXLL+dmLVjw#W$@G@5SJ+l8Y$ZKZl*NdeP<y#
t!DG*Q D=RwM:m+$j\kAe*:TAe#!#a#6p5kXLP9i?yZV=lXml/n@cjACJPK8&utu:qI19q+\^1Heb\5WqP8$VXl
8cMnYS I4+h^cw+l>y:K@j%>Yait+mu?d<Au<cm\*Pi:Tc^#adG?KiG>%Yi^kali!JD!MmQb:AnH+l=<1^#QdqJ
n@F@QP MST:P6:DW!GGhXI6Q4MF<wRkSlJJHED^pbZ59TRidQ\4$W$:FYL%PW^\qmHTZMdI/^wGcFl8^=PYPt?9
y64ZyG 5%#tI$wVKN@l%Y<S#hB&+CD@d<JSibVw1#F@B?!>@\Vw1%+tw4a&%>u@V86d68t:nQ>iXQ5DXhma=RJ9
>w$e5% c:QbelRTk^&lTVA?\l94\p1cP9laZMM*idTuRCFZapGy@DCiT#XI+uYXquZuZ%Eq4>&\uDtw5Lc5<H5e
6bDX<l hW1+ZNu+4hE&@=6j<4+&4PDlNwled@+1RZlA??P!F1mqwpV9KN*Z<>h^@Pa%4e@&W&K::!nZDj:Y9Y/!
I?heND nYn>V+b!=V>88G!=+aaEN9VES8L%ERhE<4Cqn9$bPqhkny^>$>k%L/1<ZcFNVAN*DREV1Y8%Epp*QHec
$DRMWe 1qcclP6=5::u4kZuDQGQdnWh%Y#i=dSN8G=\>##4%ic9tVGb<i$C<:MTJqmCJ&aL>48Q=S>\GkG?w4$n
aAAN+# +1Rw5tKYj@/umy?qRd@>tE#m\8Kte9\PC=/SVy9i=w6Wq6AG\a4ViRBtcpd*Vt:\?aW/@G!j@%ehcIZ#
LSkl5H Zy94VHeERZn9ydw^>B?i9S$YY+8BQ*1hcTYTuZ@8b\9i*GlNWy1RBTQmCT=\V?p$55np?aa*>T+q=5Nd
kJ5@ZM lX!nc?48H&JDNQkQt?R@W\Fw8@kBi/q??b?T&\#@8Fu1VP=NR:6YWw%VN8RLimM@L+T6:E*/MM>9qe=X
w/h>!A E#h^GuuQ^W6jbdG^WltA/Sd&#j8lV>IQ6TLJJK+JNLX/S:9&%k+LX6@RDmiNNEn6Fj4XdyEp9H9pNK5h
mECAkR #pwj94dbjLwlWpJkVkt&eq@dh:ti$EhtyH>1GqqbS%+J5QhMy\ji#uy$KIPptWN@$K*T4ML+Y/m1AA#A
B@btdd SN#b$:HQtiXNe1<n1\AV%>Kd*Z#5>ja<XHieHqdK/5NkVQ/#k$/ZW#5<Ahd#/Z<MMPtLt+thR9my^@@y
NR<@CM Zw!8jG$i9@qP4NFN\98c^JV4^&YA@p%b/Fuh@NQ4VTNJK!9:wKDDJld/9ZRLTb4+RbnTw5wQD$je<Qj\
qc=jYQ pce#aiL^ej%$CBW5n6K?8*?Vi>$@ZZD=bDPRVEQu$4VjNMT<1TduqKw/LDNp>w%!*jlJQ69*tLC&pYJn
@d#%EI AkYihVd*@hj?:$?qYKN9+m9<djet@!?R/!%X?CjG>S915Bnp$X@hR*?@=%6c6L\ciVdVBInM&LSia/5H
?H%u>A y9#qQ>jeM+5M6QD!DQV@$1h5^BBLW\>VcZXDL\^Ej&u1CRk^#J@i>#&GjW4k^M$q:G4PbRdbPNw$ZjQ*
Z\eSy5 @Zt?dLb!%t<IFHmKhQ#4+Y9#P@4Z54#m<j>^NKJemZ?@dN=qH#P^XXcmAQ^=QFG\&6pmaThjQ5CcZFJM
E/W<K9 D+E:LC:YNit:D?t*Dlj&miYhb*9yTHKd?$?5=Ml4CRBjTh4\9R65?GE/8Nn$>SNh:ZucM^eb?tn/nj8c
<l95Lu &%EX^Z@LC@pkGnkLe9$9i6bN?@jD%@/lFKRRS@@8b@wiR6>@dNTA9S9h#+p6<k&j^n9aNt%tb>tcW+tL
p>jK4j Q4:^$tC:%=Q8?>KBe:h=Dun\DJ#+el/eme=5n:<Sm\+DI9&pSl:DS=%h%XM^^RjXi%*cQW\#a:cmD46t
*aqN\N weMyIQ1tt@J<N%MJYPW<t>F@@QpLhZw%?VWQp%CWQ:&m@DjmYH@?y*e<1/ib@tu:cbNHa4ETjI<9CVXc
ce><CC Cdi!CZ%M+4H9Zcw^lhZdi6q&n<D6@j5Ql/NMA=HbEShY6Q96/>iGy1pliDy9lAii9Bc5=JV/J5$hZJ+/
E4#6$B JTK^5puXp1>+JM?mu/WSp:WY==D4V?<!kV>ml$6&k$Yd66#tyXnnTK=^HItw=Rb9=G!QEmqRSREA/Y<#
4*\Wdq @BXaKRq6\DId16p+6W#MQG6dVKANZ^cF!!\JL1lB5PND?W*=QPt:d//e#G&S$6b:tT:&KRu:H9!\La6$
&*$=@Z /j*SD$p5?j&BC<G6e4tAbDb6qhC@@uI$?q<kqEkqp<mcCYc$ihd:LQ89?HRbZWLdj!\hjI+@EV:@DBZZ
1n==kJ !G+i!@N1X4!\qi9+a/LE^n4p$BXGGmG5yDH4Pqk4acy>8L%%y^NDdTKC^@Yld>C&h%i9Il*Y^5lGY5QT
^&:hXY h^<Ju5=MSAXQ!/Y@5w4>&E>CPHHQ%=QM/NWh^9M=h/%BN*?c^#H6nNmyL4:c>P5ZmJ6?iV?u9bYW$5<c
8E>R&J 4t@jy4BNc&@Cy=yqke?t%*^h5!Z#YAVd8eyq8%R:pFLA4!dpKtty%9YRjHKN#puHt+iBi8+NE\6L9*u*
aw8X=h %#e!wpp!^L@!+wni>AMp*WY\G9@:utn5>bGt%$=*GTS&Bp#WVkWNb9<d*8e*XwQV1@k8AXT<T*kltT:p
Q!QiaE %?JeLhb*6EyP:&9\9*ZL%M%tR%V<$<lG!*!JYJXFYkT!dna86HqRcTEtHQh+/ie&6=LtX%kLT*#1K#Z&
I4hPnV >ce4wbJDdnk=F+LcX>qNtH5i5uP!\%w/DI>:G%4B<SCiwDpdZX\H8Ta&&t*#9cD<>#n4q*#B\+^?p@*%
=W+\Eh t=9Sd#/yZP<#5d%9W+pMj1/@I&IT&\TewM+bPw#Q#q>9>q??jGq&cV48@JkyaXhN:EmTC^^\K8iSA4SE
%>Z^u5 hw>jtci^%apwiM9u5?*Zj8X8jqXiT=M@/+/!4K#J8I8NHZm8hpMtpaTle=C4yI/uMFXQ@9XHy@6#<M!=
hauMCG /QX9JchEIQSqIwB+q!T9EiNF9*k61Qnt*ej@K4pXeSeHy*IF9J^@c1ye/BKyw\+u5e#%#bhe4D18Km%1
%>/b8N L8IpXLQTd\<Hpt%Xy%?$e1E^b*/4hHba%5i%BK?c%<?dn%h5pLBT$Lpt?L!:*iSK/A94:Q^J!GBC9q#*
+u8PXh MJEL*iC:Q%/H*wawJ4uh@timl9iy=Iw/Z5B/>A8w<hZt=y9a!q*t6j!Te1RC8ScM!8<+h9pc+Hm59LXW
SlV&Ey hQlNZ4T5M+?==*&muYnn5M1NXW46Y9YFPIKHq@%F5QhN&PGMiP:\XRPl!*>^><w^8e*E:%6<=e%HV/Ba
-ApwA^ 0005a962b2600110334 Page 23 of binaries2.zip
V9!%il &>DjwFEA4JS:+8CFjuVMtl9e>5$*MmNbeXP$$9kX&I*cc!YBSm>/Sdi#EdtthKM@@$TSHR:4\!Q^MHpE
HdMjih t<*H$ck=QHylq?K#<Ve^>?*Mh?pp=8^FMTi#5HkFAaXlj&t1Vc*iQ#:$k1WP*/ej:MDtDFGM9QVtF%!p
u<kjS4 !S9ytw^h::h8w^M</*:!ln&Jj^Z4NA%eKt6yt8JZWbl:Ge<=H>u?h\n6RdCS:#Ql>aclH6M!\>h144h/
W@q@&m =tR49MK@+jdL/ByRF=Diek5N=e1>M+l6eyeXXPj/keQZiyQi5KV/4hNhCZm4?=eZ8dFmtjPdh#cRbkdk
VbAY/+ Z$miMH?XI^cXHQqG+%L6tCTP8P?nhT5DJX@E\>cl&jtFuS&9Zhn@!wZ*^hebac@SdQ<Bj&GH9?lPyDWp
h$Zyaa \@6cNu@@<MAc<?H\>PnJ1lW:VQ+q^@^#NRhL:&RD/aiWcJ8Dc*T+XmGJ4yiZjutia!HMG8e9XLiR=+dZ
F%K:!H TJWc:u?Fm*598+F4CiYct%h>H<8bbSB&VDNyQyXMij&$6/>@w$6#4/:!ekZ#=@@:pQ9&@85T^<<:t\%^
+&WtbF \W@uM>eZeLIXa:8NaAte\V*6u$?pGhP@nuM&85KJb8\=I^c5Xc\n1Mk6q/lKZy#>D1*%L\li#@&t>9V/
X&Ap/8 =pQiS?CDKuNlSju^w<=IdEaR/$ib%cie49kZu#SI1EM8phNt?QmppEtn#J!Ep*4PJF?!tNZL>W5w6R!H
t6CHeN ha8$q@KZS=/TY!yPB?y\5+NFc@<1hZ@*?Qn$:+^yuH!YnD@b5pPclQA?jK+X&49kZbtk!FiYM!S>@jJC
q9R9ZD </pScj48=q$j#wY6RhJXlFBjjbSQeJ>@i!6ibm15n9LnXan4YKVttCjJJt4ttGZu=ljZT4TEdW4c$hL%
+RG9Z> Yn5R5@4Dj9FqF&K/B<:Pbk@cRZZa^*^C4y$p@ul<JGtQ6pt:6#nbm9%$ySR<*caS!pX!u&jShR/QQMEZ
:i=1lW q\8t=q?Wn/lZ%5S9qC?yP#P%JaX%kXe*\FNH&dj6Nt?M^5AE?a9Z<a&RdA=l\MSWtQAeeGC%^uQ@<cML
jqLJ5Q i:n>e6/Z<S<i@GXp%9:l!<>5K^#bVIQNJ@>aH>cuE+jC=LSC@?mal@Db1tt+X/iFRQY5/wF\&IS%dX^a
I?A1@\ SBD#<QFyw$YAibGG89dL!#E5bRB1dWdZJ9TpZJkjNp$py1NeAbyij>RPJM+e8d6@8:uqp#tFlqIt%KY8
@My5:E KYwBK?!Vi/QM#/54C=Dw\mIZtiRTPEA!m1G1:AIZ69G/pWJ&WpmLB4Y%*kFDjXjHyAQLTPG=C&jqIDy6
h5q:RQ Y%tJ&jhKueHH8#KJ*&1Tdiq$wAp%d1>KZEDbZ&ZGDyqRF>1VQ:%u$kLkn=N6Q9I#H$X@+9m6aEcE4mya
q*!ZX@ e69YW8WTAlZH:>%hlXY$=MGW&+=nEnlNw>A=X4+c!6?Xp>WV5tJbynm*51E/Jh%Hl@p8N*:H#\MXJnIN
@S6\+/ Si$@8^6eq1?payPXG/<4?1+#k%>YtwNVyi4%w/8$8yn>Ik>d:@5YXnc6>&LhYN^ajRdRBX^9a#j/:y/6
9wa8Q9 #N8ka^J/man9CaF/FwWq=?SLVJS$Gaq9a^GA*@h:CQcj=dAh%!6+D1ntmKb1Ll81Qhiw6q=/SnMPDYSQ
:Sy@I< T%+XkdapHT&!=!uY=bTe<1W1DBjXNKGhuK9bQHGe#wiSbcXZH$MP!ep14%VRM^Vd!6T86^R4QmRq:nLi
68^+<c ^H8e>B#G1wqJQ%+aqqCbN4tS!X=iiY9nEeA4X#9LtCai69JXQ\WHTKAwPiNbT5&p8hK<emRpjEEHA>5t
dl11/4 M4kwVZF8Z:T!^yt6DDTle*a6!dS>:51E$KKd$jXe>qQpMkFiPt$qt>C9Ye^9SyeL1^MXuK#Y+4aXH>qE
y4aclR I1Sj$iQenA\<KEj9Hw:Ae4Ll:K^qH@Y+>FL86*uwZR<e9RS?a5JSSI$Z4n\Q?\Nk?=>%$bwy1=c*&t@<
5Feuel 9F*^&CV\i4@n+k$ILPh$qT&:#K4^PLLe:Tj#&bkZbq^NVmc:9<ZLJm!yH9k6?F$KI+u^jhk:&@4+#Y&a
bmp6/c clP+@tFt1SCXeM>8^F4h+XH<lkMj+Y*6hGyD!<==4<NZ#li=5tc1M^u$4J*u1DEl>54<Xnp5h?j%bwwL
AEjuC9 a&#5FmcSYjb#LnIR#S>^p=j$*<De5BIBc=^BbE8&CEIeI^c$@djM+8hMTeDnSPd&eNDD?u=q#Q=qaMTp
>A+ENi 4Dt1Dq?&LR1Kwu/cSuhiA8F?im84an#Wtp$yP8dJu1WjlQW:WR&+8$$iuLjPq/C?Py$aI\P8TRuqiJ5j
1ET5m^ 14<ZI:Z$bLjQ+1dKX8M+Z/Y+9nu=@QNmqE=wq&GcK4I6pt&Hh^X=wKe&VTa^Hp/BN@K6P<l<?$*D/*1k
XV?+yi ZGXKdiF$CA&y#NV%FliFm%V:TV+lBtCQHwKYhh*+X#yWA6y@uZEY%^=&=1!!q&lhMl*H96!MQ<!FX8/E
e/Bp#I L^FTIGy+:Rt^%5+T?qkhAQRu?j#YN<56w^ZLlh8<68taA+lH&!Jnl:P8*=S@IZYJ4Ekue#\EYd6>5meP
T=R8%^ HJj%6t^?jR>9/A:>&l#^=>4t&?K&SGt@tF5bdeXqjh*i4w5:I>4cSPq9Q4NMdcXyq!>+#WmAe@Tp&VeE
dcDV@l D@nL@TedKJCRc=@M$!CL#MGhyDVGY=u=wwj%+*a%enPIFd>GdP&qYe/L$WTtNdHLPbJ9k8me8WIk!:Th
AjZpyw ^In1G8=%=4+lCAQI/Z$yDPl9Sc++TC+ZN6TIcb@uiekM8u=+YBk$Xn5T^4V^=u:?/c&EB4X9#JFH8d>!
8myVaG Y8Jk^uW/:R&^B>4wl$6C4yK$XX%qh*&#k91Nm=uKqb@8SQJL6\AMtuNQNXp<5aEVT4aF>?>^jpwnXXZP
b!@y<Z HGV9L%^RZuE@d5S%P@=d:pK?qNb#=l^$5H<lk4Ec4lpt6*ScuS%/Pb6?ym$8u*>X1Pi>i@iKLwuDc^PJ
+hw9kH pJ4wllMny=VyiV<MC#!TYNhQ%?YMV=pI<+Nc9yaDjeb5&=Qi%kuN<j@^9V4cbXFY5Mn^lk/D%:%hyTMd
GVP+Dt /YJj#bXXE=qB\u#KDKa5pXEl*Pk5R!\Nhjmi@VajIEHY&meCuc!8^W^H::L4n/MwHYKeEMZt5nWF^4Wy
dEw9!^ Rw@91>@t@d1kl8QR@b6QX$cVc*nb8q<p!6>iScEhT8+4%cj1K\%5/Y:VLtZ*Th9yWIWiSFWG5YqbSRqZ
9edYi8 kRqqy9M#H:Hdy6*t?lJ?dLt4%JFyLM8XGtuIyn?FYN?Pp69<dj1iStw4u?bWEh&Dt>&MPGnd8GEu^#B&
+G>JL@ #ZGc?Lq^5ydDNu@+qdDC/XFVQ1d*9*&d!JkW*dLb@*6&+^FJ&>DDLYuc:p@h9>R!bK$!/ZnPbaB6WCNY
&5N/d! bdy@?Ye>TXV8PQmFeyWZA#BE$pbu$6+>ja@HA%P/Gm$:RKyTSp/EYSHCZ98$TYJ#p<4K!RuMNKiDittQ
w#VSD* K\GZ*@*l#V\P*nIMn>CM?ItpH?P%bu=@\?HMG4#LwKc:>/:=!EctQX6D\!SCkZD*>!yY!W6wBbkV^TSS
=BS1KY $ZTLhkRw^EH&WLCK5^i?H^mELWDjlQMXanQ\C6tN6lQjKpNV<LF6QZ9WwqlGLLSBj!W4@Gb??^F++l$y
iTW9k1 Ch#Vy<?A:&Ri9=t@mYPD4\!VipP%Pi\LP551Fwa*1XFw\j8a+@P9:*QTT:\p%mW:Z9jVuiI:bh%/=mZt
Q\Etpi RTB>m$MJDMANkqbkL::qyJMSZN@4Why!Jd85&\8FWkbH>PVS19w#l!wZ+@uPTWYh\<pm5pI5&Y5SI>VZ
6Zdjn? t=mjy:6h=tW4c^EdmHX5q6qjj$4i8:=jPbTWyWJ^W4ddNP!d5@$?AKlwM?J5kn6nn:J*pwdP/Zy!TQ#X
JDTaWy EQwQe$P1TpShVM^w#AXnkHjycGJ$%pDX?S@CAAckA/+LL@9PBGBNt6cF:TeDeqDplN%GijIlV#@p:>$6
B8=Ya? 6*nST6$&JRu$e^^YQFd#4wG\Q%#u$Pj:?b6Q>>9d@NcXHC4iS/:C19*k:L?!+?Gw8\95MN8Y1jCCGThl
bI?h=I /yXl=64=K\K%?+WbiKlZX<tA<V*B$1yd:Qm4yiVcd6j6YG?48tCk8p$*Y*J!alHmEkY^uPWkFhYAc&M*
k\ZX9t Y%Z>4>X16B1X?IW+n#H5#WnJkQmZe%tyC=X@<!qJJ4:ahh%<pjRV^IQ8FSwT?**@:WM>Zj/$5@/dP%%?
IP$m1m <ViXlPtZnkJt*n+&9q<YiuZ%Q9$RIKh=:<#6:jZ6@@DSeAEGWFMw@6:it69*:>%Zw?:+ItPHDeQ!\cLd
9$FM:a @>@H>i9*:@SXq<?>8u:%@5Q6B*#u>!#Z+eN??QABQ^u@p\<&*mp&yyn:Z</>6/>@>S/9nV=a@Zjl\?I#
AtECey ?P*>>T&?k:\TP9#@AXBLA\RWAAIACAAIXY$qpTdBy!wDARDiWAIAM\AAAGN5cYX8hHM9bGq#c!>*cY+#
=tkV^@ Mm>RS%BpcZN4RZB\L%Jqe!>VeG^le&lVa*JqbY++LtJ6eP!hWY\WS=4HP=jdlFn!P1NLyB^b4^uqNywl
u5^cut mlNLC&JptDknZa^t#Ma*EqyuVup!JPAB9@lESG\MmlB*D+=n/T\qpZ\!b$HcSmLaB4SpyHBQA>Piqp@V
aNBi:M RpVX/BAQXWJ=TPj^HuQ@4*y/yu8tB=\>!C=Yqj%NX%h*X:j4X>>ZZ**hQW:68#9+N^1quZ?4cVE5d#&q
#qwRk9 cTuIW>wYYd+++G:*y?lLeT$in&8JXF#4mjhw<WTQqwBEw\p6FW<kD$pq6DRpP=^AiW44kWS:WqwCp1bq
6IJ@8F I1ZFW!mHbCGJhEyL=XJc:nVKw&p6AWuF$%1<B$8TSFyLR^KyNQdHin16=Yi^H5?m91\YVYT%Hpk$qeW?
uDWJjI YT$FTWP!pGkc&!AyTCKZ%ZKR<dp5/5:l&B!8H$6IV#1u=ZM=LVYe\*Zu6N^WDuWNw==l%DPM++i%iBbL
c44u:J TCKHbS:4QZqeZ^=%=LE9<yA5JJ:Pc#%b4EP!PiTH<%wPpwhp<!kj\*IebdN$@Bn1HpQha%wCplwi$:Jn
WA?wb6 a%wPMn\:yw%D+q9GeT=Ial^@=#ncD@pW<yAWTZyeT=Nppe?N+=#ID!Pj^^KTGpMb=QRe%ZNc/+HEE%lC
56LMpt E4SMuWa>y%EH<4uV?Q6Qc<PRun#KIHuI&Bn&GV?6=TCyKY!HbGhSV&wKj@5WnwipIXt5D&MJTiTueD#!
C?DBh4 a%QcMCR>QwY@G<8yKdR9!5=Q+SyteR&R%C#1kKSueS%a#<*mPtdSdyA^qI>nHVJM!>NaR4JV5>wWJDe:
+FnaZk m@+\1@Xwe%1CbM8equy?Du<Z<yAWTZyP!+@Qwa@NcYPR@NTeNk+bt$ZbHB%#H5hAZn19yWtm!KjPw%?e
KnME8/ S@>EHyKtjP+<GGJ>:D#cA9ty<&kL=Gi^uMN/>KKYnX@WemR>F:Zl^EXe\$Xe*$Z6@NYL1QP1Nk#JR^Ly
n<yGMI 1/n*K84AM9W6&k+!>1$&VnKFjQ1Ghu4+B94BDiVZ6ht^hVC>4e%N*hdPR:Lud&9j46@Y:6?>4X&h8+6&
LTFJAy 9c@h8Hwjhj!w*d:^w*d*>w@cn@j@X$9j?Eu:/chHI:yKt!/>4=yAMXXJMXXJMXXJMXZy<VBqkq81KVeZ
n/cVE/ W?MdY/mtjHKb&p#ZC:#ChacMD9*EpuH8$JLYPFca8%?Je$/mY=#dPm>BwVpJ6uPBa6$6\FGt8^j!iyuV
y&an!@ hyMdPlcw$/a>5b$X8Kq\QS/t#GGMm:KnT!mPVW8H&ZJhMGT9LVGHcHQ<@5t+h5F!tGDZ!4yV%uZlXGmQ
dtFinu p8XaemihP/dq+EBiEw^KuLLkBky5uMWS1MF$VN5y+SlDb\YF/#HbZph\l^W<yqA=D5Aq4N9EXJlL$EGZ
Yyw51T KVTMY=aRwEb\%tne6W%cRSe\JFNBc5$Ln1ZdZDI%ba*+lYcTp1QRhC6R4B+jW<+My&B+VLuWW!milGkB
-AWK$+ 000b5dc8d0000110334 Page 24 of binaries2.zip
m<1tRc CuPp9<SJ!\\B6ebi$Mw!M6BBAYnRY/ek>bS^W#lqdkt?^G$/pQS$TVDLKRkeD>/Ye+$=c\=KFK9H^^RN
FYk/NX LZVQ>pIudW/jRu+WdIhDGbt:^SK8^6ElAI:6F9Sanyha1Syw!e/ma=pRVBnM+a=N^\u*MC/E#NtK%YQ$
VFkI#9 i^%wuMeW@yJ$jCWjPEFpSjY!:t&lZBpdnXJ6X%$9$aySCT1ii$!JB6%T$M+cFu#1k1FRQW/tNm@+tE4Z
awqt&> XZh%D1t!+jqQ1DEqyu1h1e!bcy:$!<^Q!///?TEXjt+N4Rwdc!w4VI?Y1b\WY1#i\E!FnJ=$ywJ\YwLX
&VeN8< #cH+C$<4XJ@/M=qcyI+p\taGSZTlwTZhkNbm5qJiM*VV$E858t5%\GQATFJ$1TBXtZJYqWHbyHY1^>R4
uuDH!X MN8X/ubWmd!J+>dI\FdKXCkDXQID=wG8wtLK4IE!Pyeee$&/F9iEla4C8BGt*JE^A!GuII/B>SIFFiTW
IN9jX\ SVkX8SG@NQBla5tb=>EahInFKd\pKBkBJKaDDDSb6bq8$^RWiah&y5y5*SaXy?J&tyIMWbt&h&yelPXa
ZL/9Kn uAKQNK9FFMjEb$XPc+RqJ<AW6GDKl>wIW$c/kLa!MjhuFFnA%NFqcnmG=VF%VPu&Mp^S%&yi1mHK?lKt
=SQE=u H$/q+JSwBtI/be\=haibJ8*BHGEKaSuPlY<eSp\hce5L/ESCLF*kV8ECSa<YeTJMb\9EFNMiSy*J4JRI
Xi6w%1 4y\VXbuKWESJah\AW>uMcMh9$LAW@5F+!mXVdnywb$>Q*apH9%B&FSYqBYm^XecHaXin>KBRpiG@1q=C
mqAk<t 4/C!9CIw5CmbPkZ*aPc\C\+9a<<CNHQJwYkmtF/#5YaSW%5kY^*aJXM*u1nTlym/Gwe&q^yK81I:B6wV
PK/Jbm :Wn6m9bpFK=#+:1&d6kiW!a5S$d$!ybVdZ+K<DI*$GeKh+5Ni!^5&%qDqZd6Dp*FYeMyVXSkqPYyWA<K
qE+/nH Clah:Xm&RM<T9Dy+mk1PljF*dPW!dhV&Tl4W&w^GT%dG4<Z5m1XZwGkFGh?DST%RBIJT&a$G8pFjdHQY
eph!t1 lFYNFbmPa$HNT6BX!^Hp?>mG#pwG=\beHtLHbJCIawC/QBt*/I=dRT>RJ!tRehBJQ&qd^a6HCM8mHwh4
1ZB/Nh XEHDnjyII4T69Ht1&:KeYBBjh%<cNT5W?YZXPK>ui+Z88VGMlZln6R\L/%%8WLDePH<TTn*@9LqMe\6:
%Fk$%> eWAY&LW/q/H=mMqKXjR%jybSnX!Et\VQc!&EW8KXB+SCXH1p5WGXFFPXulCtFqiQp&\1yynRPMyS&XSM
18jAnD liPEP1w1QdFMPbC1^:+&E>M%wbB8N1cEXN$N&XSM!jA//wtT#eSWIqWP$tbm/mJX+?pta8wlhS^%S?TJ
5D/5T5 bGw!>%+cC$G1#P<V!NT8<lNMD$Z11IeMum!t4Db5Yuw4yEySu!TtVIRSdWScucQc<4=%wjaWCbP*!T$>
\wM+NB 5F4Dd>w!%hbL:41*Y4cDGhP8*T4%Q/bmBm6yPKXm&n!KmuBFdEV1PQKSQheD=q=E*=RneN$\!%XSt<>!
\bX^mZ B:Zn%\lY/y&JPS=D6>4/nkY@y!$eRapF#/F+6tLKQGK<>BCpLkp4dG:V<ETjXd8HI@kTWu&hm+dn#PBq
db<R1n %LyXpGuIVE1>w>1TKY<^X\qBY6$FKk4XL6WXE^yWn^$!YlW%hZNydIAyjXPA=iQawKeBd>^&#/F+6tD1
4FPBc5 <dIin4Vc!wdD%81:k\MNhZYVKYm%w9>5yla^>d%+GtA1GGN49p%$DlY8jAlVK>Rk<#Ct>DC><JqA>p&l
9+a4XT WH5Cw8S\Ym*WcblI#KuW?k16X\4NVPp>nlyGw+!?Wm:Zi+blGPYKb^9eW/1uLl:IXJSD6bVV+:4NVGEK
$<5q^4 /!RMES\HiZC$6j$8e/&#%J:66Q\*B+SV:\4B$hY6SXRC=%BV1^bMZYnlTEZhI%I^*!iH1SuY+=ujH9Mt
?Q=19? H$tq9&1tLE#>QNW$k$/W5ubQBFM:PNaFwdJtD*lN6iBjP%MY$Mi1*$wjbiFVZ6aRG*^RMm*LC4+iWWCJ
?:@@H# 6cG9^nG\w*1H+9@J%Gw&1KT+A1NtIVBbCdlIF8j?d:@l>ilV:V/AaF/bF$n&h1kHDmn9u#@bwnHmdQLA
JR+^Mt X>VSt6hhDBpeXB&kmYtyTjpMWYNuGmFM!#Y%>W?E!mFSC46B^R8%Qdl95qIuJpQP>I/14>RK*6:#V/K=
XGlDCZ e5LDtjItZ=cH?pJYeCdVmtq%Z5w5\@T?<eF%4&#L<1?/&W4kl1#5Zt#JNj4i&X5#6Z#>SKZ*t\EcDjPc
uk^R4W ywGVBcPHLbncIa/^FT!!jLZaV1Qi<jw?=ae\FTGBL<Y$4u$mBJ+jhB&?$B@ENG#?!wLlDBc+D?DnZja^
>Mj^^I c5Ad^yRy!^9PXDTHl8\/W:<TmCDueKa5#C>tRT1?1GGyIZ/M>KhGm>8K1iGwS<lDtdKRwbM%*Q#&n*^%
&AuHlR #PFMR/i94ItK1Ba\>@/AcQcZT5H:6M%MC>KhWwNyM%MSwyHl+!q9$PhRyqcwPR\!yi4ykRnL4XT\ty@n
:J&j#4 Q@lCjhIW#yT4\VTe1hXpbiq4MeL<*uIn=XCtLDS!GGSKc!b#B%VmX9dPZ9I#ZZwIW%QFuX5\=a$lZE5&
cLh&#< GG??@iI16M@YlVK%t?JS#W!q4T*L:tFJQl+e!+>y1jdCXVlV>ayhK/cN$RGn&yAW>@E@*?8N5bc?AcdX
ZyVyFZ aE@>1i<kW#jiKA&8LV?FZ!F69/%9#bR%i8W19h<+e416Kq<\hdNB=/MR9INhA&Y&aB45KkGtc&+yy$<l
PhcDJp 5jH1%mDVwJ/cDW#X*cFYVH$iL4YcF^MWVj@VlV6NVtbk/G^pTkF:1^aLCnBq44yn\R&ZIc5iZG/!9V\p
9W/<u1 a8E!=eyBc5HWDn/:IF4h>GdNTIM#@wCQ=P<Iql=YYuJNlP%tLa@bA@^i*nmi14qyC/cBS<h5*84bFBaY
bBbucp X&Z?TK*H6NJI#&lpY9Jk?M:pLj%?#:WkW/iS1cYkdwBy!<iN:NA*u=nQZVb4MRjlm\IK4>Z>VJqZQ/<d
5SwnN! BG>H/Sa6?WIe=VyV*nk@6bZn?*Pal5F4\XVW1bi<W6<k&*\Ll\eG&j1nV4YmW4%/Wb>D<=wdHnlK8Wpd
JR#kiR bFyyhw>cMcY9#//G/b!ck<#4<a#tca@\pJn%Tyq*$9yR@p*hCLl?d$&4/%M1wcIPD@F:\^<kK@EY#?hZ
1b!1uw =Aam#kNQ<6b5K#W=XYXWKqKN4Rwq*&VVN*wGR46q4!i=G!68n/m=bQX4MhYEJwTy>dDB%QJeahERq/<i
4Y8!1T /h%a<e$kJa$%?w<H@uG#?XXH9?&5Qjapu=t^4lp<aM^qN^BNVN&1%bM4LiNIaYF:k:h<TN6nY68HNdyW
u\N1j8 *pG<Xc>lhTD%Y#P%V8T>ZXhn19Mty8:pT$YVY5X:t=HY#T+Qie6ISlZpIGnTj!<IcI6F*\dl9byW6m#*
++MN** Fpw6FYyXiCM*QXSaP=nJh=GN=lNX=M9EkZGA61u@Z^Fp&tS<nTb%i\V@@+p>!m?BWLjaH5K$^Ve%FF#X
IDF&8& Ap@&KIa4^jRZbY1E9C85q=nNGdMi&Z8hm8p9!nTk1I<4%1ca@8X5:?Q!IE9<EVK%FhPj+je?^ujw&TQ<
RnC@I1 $wW!X$\*Gph/9A*%KMQ6ZDF6!bR:/n*lVec$nlS#F6Z%N\NV#@B!Y$ZZNkqViRPFM<X#<#BqZH%Z%GcN
LS=$yL PcmptK1ptK1ptK1ptK1ptC1tKmttKmttK9&<6QSAyw9/+1IPYZ^+Shn%kX849?E:Lka8b*GnF:@+&J6u
@^*ni# 5jXbFnjRlw8l#dQ+M/:<AZW9L4b8>JdF@*Lu*9$jj4n@Q@i@9@NjZ*=$=5D?@p^9QB/QhpZn5h=+NBLB
Wbk4qQ 5n@bj@DA5e?9*:6*:<:%n+:%:$<t?#PHD&P*:1=wyDP/jZ5$5pWtYpR/I#kMB*d>6m6KQ%l>QlLyyP%6
%&9d:W &>=<ah8&TQV#M>WD\qI<e&J!<umt1@P=#m&hEVw!&qZ:iR/%@b*MScP:*8lLJBID>D5!peu5Tu#!:=<M
?Xj/J6 hZjH@Guu#y$pkjVY&*L^>8DRTQ:w^MVSw$euytcPj#a^e?4p#M#<@Q#!<9#<b#ND?j!lweGlIWn/>bij
RlweMn ii1bq*it$&t5DcAwu=?a?HS?Q6di*uF+@XJH?@dmnhYd/?5*d^a9FXi@Yq%hZjkK9\8?ND<@M#E^e*^1
XWbL1@ k6LM^NSRdGS=?ed18u*F94Su>@HmcuH>WuEb9<9F%YXe\uJ^wXleZ%>j^Y>^Hqe$Q*$<$^@:6ca><<14
qwuHGF 8@j5GZn**ZeH>8:ht>t>i?<HA+iuX</hP<e=@&<5@9Hmh@j8k?wQ>?@h??:LL+<hP:m@@=$aeMZyw$6C
#4!4!5 njj&>8<@ePdmuZ6*:>:/+1PD@j&bbHJkIL/>i:8pD/lhud<mHQVbCcydP65/PmZZcBeK/EjmB6Dw6nen
W:wSw% <VQ>4bFG+66QZJ+<Hw<?J\?L+4M4G9:V@ec8SDWNHSuKbQwG@#tdT*ZHA%BnnW#jT4<qq=t*ki*w!cMu
B\*lR8 n=\<elVNQjQb#Giu=n&tE^Q=@JElAAVY>M:j@@1bq*<Hy95?*EiReYD?$+u=iEh:S^#6@uF:i>?Nt?5&
Dl?a?* ABTZF\nw!qhZ5QCuW=SGS><:Rwtw#5\94!/9!*Sm#>:@KBK:=TL/^EJ^kbCC:kIKdiJcyJ@%K&iQJ&QQ
CD1*@A cM?$h?:aM+CjQRQ>8>&$h?Dn/bZL^BSI#@WiPHQ>*9eEFXml19>&:EM\/!XhqRqWwdL^YHL@5e>9*dq:
5jyZS5 ><:%L+:6S<4$DYTT@h*h6EeZKcyWQNJQ$JV1lYXd=Dipby*8B=CTqpJQ+\jn%R+Rp1L^keuJ*ADbCLim
KbFGW> TB8/nWTalMTV*h$i%P=p6L99naG?pWHb>mPb94:B>:LbZd5CTJ9%NQ&/%NP*S<BWK8yJcN$W>QT##$lQ
cT9i*\ 1$1X#$6<+HwIWF>??ZXmP4S9BHy/CE!l&*@j*6E?nYc@idmnjaVWqJ4@!m1IL6DH1w?tT*V$9jiGBkjj
#<KalG G^\bHb$+hR4dZK14A#5AFZuRZF?XuYFXe5Y&!:TD9Z:FZn>*d9*T+V&hV*e<*jEQP@aRW<Lb?$:9n4&:
he8md6 Q#l<+5Rp1T1qX*9:#%!@+/w1hQY:!6ejjZl\j@Kh*6=aqT1%dXe<D1kZd+H14c<QHMRP@Z*>!d=pB1$K
8ABlNW 1HE\qdaXuF^4GYtV>njTJ4t$hWRA<Lt&dh6iiLPNtCdn4jW$Gl5+h@uERHi$<%e\+:KC1M9$ni=w6B6W
?EC5ln c$^n\NwNpJuMTG1EwI+e/85D+eHWLl@TJ1a:ZV%>8\<t>PkW1J/E+l!h?lTKP91jkE1GDqDBdeBX%D?t
Jb/>6* $#6@6@Q*^QSRi6??jWMD^HRt$>Hi9qW1&81P>6<Wwca*wcuEeuZ%1+W4C/6?wBI1IS$C$<FB<J$?MZ%&
B5cSTt Ady/e:%+ce>9><>Lw%6e8QVJydQVb%jPLtC%KIFipie+S$\@*9Nc=>QQQ6$BVWZcDRP/I@d1nl&p1JPV
bbRVnI H6XI4Lj@</>9jji>1/uTAH>$EC1ahKHGalJ1yC9ij?DM=>j9*L*>4<i??PJky4i@q%w#&b&W%4iL:CVb
wI*HI4 ZXJH54=A>>wLEt6pm#japyK?AF&N^Q6dM?&M^\a8Z<+NdI??&EF>k:4Im%XVY&Wd:jKa^tLhTWI/qDp!
=pQC*c MnI!PHJphGTw4:8::?%hmX%9%EjW^8V11dT>kDqBt94yFK\lnC@y1WR/SW^JV/Z%HaTt:mTtj>!*d+TW
^?uFu+ q&#9X1ly^&Ewb@Ht@Nc6l&*T$?I/cTm+4m!+iu1141yRW>CEw8b!:+&Puy1iyt*Lel!h*4F%Q>u<=aYF
6h?wW+ qbYX!itXqit#q%BBeZZh$>Z%K=hZy9<\<Ny4#=PtEqRk:Z*%qXhimd&#i?>l?CCVJ?ln<6!Y#lhn@RiP
-AJq1q 000faf2afa600110334 Page 25 of binaries2.zip
e@AlIj \RBZ:i?>8:i@@PmD@j5QJpE%%y9M>E6Z1VMc/#?G*Y:j?8L/4X6u+Dbq*ppCcu<*1jJ#bH8lm6JeI9@<
WNW\\= q5m&N%>:E\#dw1C!BWNnJEJcTqmnuhFp9G=*G$^\JN=>tG^9X:VN4T:T>6!LdXY155DN$\elT&a!tR<#
!kQ@S& l#KHlwbGnl\bQVI/CtWF/%*@6K8:BhP*QCeJ9k:eI#K@J&p<uSt6MmXFHTYtkJwu+$6D1nVc?\/Stl+c
4lqjHA yQE$TY4c*u+Y!qt<PdJ%#/YdcQ\4X/y1C4RLDecZdP<k4Mnk+BE\BhRVC&ju!SY/6F\eiGZ4IXldIJ$E
jQT>q= %JY#SBajC&e9LbC#lV/!5uJ1enwH1N8ij@dyb\F%>*d<hWD/W8#X*Z5@@n??@9?4!V9hF<dd^>amnkXc
$9<6>W $hucRCIMP\quI1%FDTE^PHPMt@68TQHpGIL45<+=A^JCmJ@%4LPlwRE#8DeklyDTb^%ByRpS?itIIhKj
QWJKWL ?lqRMjDLM:G#DlaHq!:Yc8h^8hc#>>@\8X:Z?:+DhtdP4XK$Tt%iiX*j4>hFeQa%>VZ%E%9yhhMSXZ6/
CVl5Ku Jni&FQ9:ctP=F\daDdc/HY/*RLWewQde@Y:y?jQ%IeSTNmKJ&$dBL#GX:T%VqKJi?E@C6PbEDYFI*@iZ
^pIMlR E4I%&9$/I1tYWC$*YLdD*yKTu+hIJ8jA\AJlYmwmcjymlZ5$T1VFZ%1u?%Bl1eWm8V6GRl$nI#+<jmJ1
^V#G+1 MBkNl9&M14*ld\T>aF9n1XMe@5wimyFCeR=?^!l8mX?PnM<wtNI9MckiQ=PX+/4GSlqE>Z$Gl!wSVV<K
>+6\BT HT11JZLiY%&#u%%aA/WWh$4BL@:=%=mTL&&B>R%/I:EIGX>kT6@:Dae5aaKWcJymXCQ+JJcMDiIuC:GF
J!$kkm kaFa4D@T:*ScnYWq:?*/1ElVYjFJSeWu9/#/baY?X8we/P@4/&9C$%>RYFcw$%AI%Na#u#jAG<8W%:Rn
L/hWS% FHI+HG%6AJX\M%ke:WVX:>ayV4w?NWZ^5aG<tWtJyImdIplC=pHWK#TjcD1BmEldw^XQ#j:>P9=bmiF@
9nnnik =$+hN5J$kQ#yHtHMkYNlKVMW+ZSJ/ajqH*:+ITC%6L9dy^+<&Hl\a*RpBFSHS<pCl!q+mWV<h6QjVtRE
Q=p@TJ yCB1w=%McHe*bSj^$dG^<BmqM<VV8PJRPWkCWZ$eKeu<Ltn$ujh>=9?MiN6qE+a*mk>4&SV\#A*eI\8J
w$Wb<@ JCc#AJdTn:@CFNaZD+^9JJKE:W%^&lK44dBEE+CWjk!AyAPybBJeHWkt<bE\VjXH!QwT1GZpWw5$Fj1K
kDSX=M \:@<=T>?<WtXkalKn/^k1m55%BV1DMlYJ6i*XFVZ%=h:&!pYIywT4G:!4l\9&h1Ry@:^LnukniW&G$Cq
j4!%Ip pIXTG^Cb5%CmFLGY:Kqtj<$JJtw%&h^C?wbQ&QaYE1a:!Xtm&@p#uS8ai8$ta!Eu8\YcQTXAqd<<LH!B
JCBFJ< V5qR>i%LT?6diB=8$F<uNDI!imME5uaTTyGk*&+*/Q<&Va<*u9w%iCwlTKIwKS1BP+*GKbjJP%SKbkJh
*YZt%C k1t!=:VH%<maitVaZ5>ukT/pyqZpDPX>SVECFXF9y4n/H46VaZ5J&?Rdec@mWPFTCX+9EVWbb:NAEi/>
DtTyL1 dF@qIWe!ha?hKTCNyRlGAnNGaALpGB^\j&!ARK$&cp1Km5n1jpKR@9L>jWVWiqu8qCpWQ6FpdTwwLAT1
FpFtAl P4$BBymT%hh1BE^WlRF&TPR:*Y%pcatPBw8:b?n/*d9#G%6dQ$^hJQ/T:VXiuPw%5QZXcWTAlKmIImJ#
$Xdka$ DYKmRwT8eI8FRJWk%bVwDY<tL@\tEQl1KFh^D9R::hXtaZ5J!8I>lVC=I9E6KC@=5BR<%iuh<$6I4q?<
dmAmeV i9Z1>hc#niXHD&/MlEbDw/MhHp<AX6ln=?^WcuknpYtES<Yu>kbQAHcZtB$iI<ecJP5du$mwWSL#6K8L
ky\CA5 \!RKjitQNDRTVe>:ZJ?h:@IWpVj%4%IGYX9$D/t%6dZN6dY?Tt$%R\q?M4S9RkyM@RGA!n/mJWcaew&D
VH\H#* Rq:C6jQawdQJlhVCQdlWSEpLk>QM$kH&4wl@kKyZkKwyK9yq^T>?<j:8Zd9jQ/\*uGXEPePSC@d4GNXC
u4>$hl 9WFQ$F%jj/pt1+S1CAdaSn/%HRbaA1m&NuK1Qhjyh#*@j14ZDj1c&1h/tck/dRpd!\KGCCATjn9AI/y!
@RTR*l Iq58GbTcE<hI=i!Q?jQC$kKD#id5H*DcnDZ<hWw+R\XH>?AnpC$6kjW6L>Xd#w#Ri+5RBc#k/=<iQcBu
bPTpN% qB+jJjbpkkqXQYim$k/cun4i&NAkEqVbE\l*B!>*A%TPi<tlK9+$EXW\FdG9D$p6dP>uML?jidw5bH66
%<eE5> qH/5>j@DQtMYtGb1K<81F\TWHQ!1pi<P&<6EJX\SI<WIIXG&!uKXITpjPmdjT!:eJ%RXYBeY:yHlSTlM
APqGX9 9=ueKZ>\!kLW\+eQ@&I*u5MjXNZKiK#Y5\TyVD#h4!pE5B1mmL66cGqnJ/kneKw&54:6Qhi9\/$c*G&\
pE1LYY 9<>j9>=/V9F9QSIip<%tM*FKA\!EF%TD&ZjjMLJGHWm4+@SWkdFIX$<t\ETa/W4&HNAX$ye!$*9Sd1#=
tXPp@S mCA8$Rn:!*m!6!+6?PlD8NR>=iSS*XejEKm9ChWj6:ciEcyplDea%!kZc:#BkEetAP$N>5bGFhN<=G8Z
NbY8G= &KF&W&=Kqne5VP@E?J8aemq\P$n!EcSId:4a?Q4VqG5+>^XqWWTTK?9L?kYcuJ*Cu!JhAb#mI$BFa8S1
EW4Wh% Acb\1A!yKB\S1Fb65T#mZtI4p^PRE1d$IWdj?\Y8jRTi$ckutnKp8*>BQCWw#%141&9AXZ1ltceWKcEI
w5ae<W TBHS$Hjd!cyk1tTV*G*D/#<5>^C1FQ$Ty86EpGe9Z>K9PN\tE+JjXJSKC6RmIBNR?MMhnC\w%uG!+:AW
T866Ya =H>bN:Vi+/ApYKe:5Qjp*6JTm44MFN*JV8eiVepie5<q?RAbYSFec^GML+hJF9eI^WkdG+\tjZmGl$Dh
pLpc!D 8EESE&YRkWB*>&X9m/il5hGP&EkyInYiRplMQHYlPlm?HKCkh&!MIL&MIEpWB&iE:SYYF@ZBS5d$9Ij5
=#I9Ch 4?e<mwPE/1EEamPbw1VNZF>qyhc1bDJeTKL9MYiRGbyQWIQCuSJQETRFCXM!8/p5R=4P>yWXX<aYBK4>
9K*e$R TWSLKjLI?M:RJ5FV\XVG>QD8*Y?>>ScIiqljD#C4nhXYc+%X?FQ&1aWGA@qPG\!\p6c<*91VTqX*?@L#
di!Jui >i5>bIpq\y&mZ*+JZ/:*6BMkBKm6um6P>KIZC&/YKJE1IWEj*lXXQ9EwtI4H<9L%5wQiFLaD=4%:>^+w
<9iE/H yHiIE#:D&XVIDN$tPqqm@J#L!CZqH=amQ#*VVuuM!PkI8KtCC1KPI4QyI1>/8V9\??dtb5>=Z&MDec^S
$$Knwj <cpN:B+S?KI/&B$uTMem+&1M6CQ8XW#9cbGlAqM!9S/ZKQki&qidSWXkdT**Iti64K\iYATeK1+Le@*X
E$1*Yn Snt+$=?TN^W<djF8<=V4>amVp6Z9FX8F+S%Im1A=#Wp4:Ea1Ih+blC1>QMbc^9S6aF4$96=G#K$&qqXZ
8+:iEB E%i6<KhqlaK4Bl9K<<T<umXPXq>69WbcM>LS+Tc\*jQL!<N6TG@eda/l::=@@yJi\@ZJHp=yDE^Y4nnl
4!AKtE S$EBh&L\5+J<E5K=K:Iik>8&DXVQ/>jLuPYcD?#hY*N\4&\#W6#d=*R/C>@MZhu&IlRVdbq!DyMepwjR
&Xjpnn w##t@MnwKDH&tVC?X$h8nFII#Jb%@QKXbm?lC19y<^GYy^D!\5M&NKDIF^b6GSH+m1IDiB1QS\Gy4^5<
G+A#49 ldZ>J^FkpT?F>cWEhT#8L>yZ4^V9NpPHnqW/RhNF$bWSQ?Smk*<uypEqqRt+CFN9JCtm:HRGheF5$q4&
n$?kdP *u99!iSPa=RJyXPJVBLBE@%h8Al>b&J\RpGXjJNJV>/WcQw&cG41JJCNbXwCqblcWFkCQM8I1?WGCcXe
6EF:I8 !p\edXPVFAG@j9Z/&hdGA/J1B?ky6R**pN*6ccQey8*/*i@y%Z9=@L8lhyAMZqZWlp5R^w1cL%^umcba
5^HJZJ aYhlEbDkL6=\Y==>l1ZZY$QA%EC&h??Sn\?c:Zcu6#@Yb>d8idNtTF:CSN<wRm4NN&d$iptT8N#kG<F#
a#$%l% >eHXWdB$bJR?GjGNE9$8h%??@Q9te?j19K:S$T>AXa=::R&umKeBBL:hq!qHBcyBJWRChimF=E1TWl4$
e^9?LZ ?D\wKDaC$<<?<*FnJl^PWJL1!KF&9=p#H185ZqlW4G=T1iHQ>Y8L:JE*c\/\9Z+%Ra$4@#tCNBP4Lcwp
k&ZceY n%whR+/cXP\^@mdpB\nTmauB4!eGB\YwIXu/XNCWiHyaV@GS$jlS&Whq&qyCqSmpGF>!y+:&>l+KeIF1
jADwS= #>DpB8h?>M=jYl/F?hZd!Lem:HYLj8y*h:?uMPu:wVcdY8:uJw*F^k$+=b8AF^bVI%y9BK9?i4:XXtJb
nX%TI# i4*BiSL>$RN:Q@:+mNp8tb*itE#l%E/Twny=aP?BA\hMyjmmyS<cSGjGd8<AW@$:kB$XH$Pn9nGWEm=j
IAyIWy 9u#q>=eJ%L1DZ9?NB#i?AK!uPKWl+>9XhVtW4@nG8iKkaD18FB%<w8R4N/w<BW5b$:F+Rw@?Khui#Xlb
caaAR5 bYXjDwa**=SBBJ^$Fl8CP*MbL8JV/N9m>RbSSp1J@%:tZnbqLVwpL@SZq%qn1SR#F:At&GRp+1tJ8eHB
E14wqE \V9$I+K9F@SLF4lV&N=hSTc=$&4WqBX@XFbYXq%YnSmyVBCXMcYw6k&>Nl5qwp6@ZH<ya5q=!qRhiw9N
?*/M!u bmG$&%CEREQ%?l?j4#>@8VVp*kG1#8D8wR#HcDAcniYm6I?!kYaQN&qKNB4Ww:l>!9tP#nd=jN+lCl1E
Q@BCL\ &eGQn>R=:Yc#$&uY/STiC1Nh1CpuRE@8QcAn1/9=EFFTPdw$NyMp!SJAQe?&%ihVCwY\96jkJ5i/mchj
HQVY=L AXN/ZNEHlPwZnR$T$ltJkmSQh*e<FA>%S!NSLk:P=Hp/LnD6EA$*yinAVQZ:8luV<ZTaC::EW&NbbY$t
t&JmMt l&:+ZGcl*=uKmLyDMqbhdA?1abJc:\Y1bH^n:E<=tWEV>6A?PbNb/C88QJ9IwkmlpFVN4amniMT:I^4^
T4c\PW uVu?Q69iZ?#TGItt1EIWq?E^mlmJ9^61*i=&S^9eyWYQNulQ#?VTPl#W^6JWS:6pR#GJkKZjamM1W!#%
y#m8kH *jwju:>eZ:4i#5bVih4uq:>dZ6>+6nZqMJa4eXI^j?NKEDChdPQRl&Iiuc%>tCG%/EHWk$eI$^1=^t#Y
QJT5Kd :T<5aZ?MkEm#y:SEh<DMQDWAXA1RQ1SI&ZDWbDIh6ZP*DR@nK4:=!J?Pnq/?Nkd#?@9jj@Z:e+#1\d4Q
Y%:ytM w<VWL<+*NqDw&+BpBnWHCyKma?H^dZ?c#khJML5e?T4JDH6W&Th+Gq@6*FeWIpky/D$YY<56LtSTqF!V
*5Bk*d AWY6q?8>Z1%G*pFW64&E1eiQbq5p1hA$q^5+Xup&t$yq:<tX^#^eLcRMJ/G$FEV*L^IlSJ8dKX=G/8Wm
ZS8H@q wlJQmcaGK<XMBGqS$WicM8%HS1+=CQ6LdlEQ^dWP>NqR&Y@4Gb/ju/Su8LjhIjGLV&l#^<dtJmdjZj>l
E:mFh! jj*=?lDFXy!wGt\/k&MbbRCE#S5Pk+bB*SH!\9bcqu6KqKnH1Fj/6BaLDQaBePqI#RuC6JD:M1IdW:mu
m#aqe8 $ASAhReIYJN1%$<&KIM4N5q8I*Ayn9Py5QI#GkbS8<jG9941G<K$GcA&Hcpn?*j?KnuYBwLXBW#naW=Q
?9SI=h Sa11=nKJiLSdLR&C1b@=Vl&9P6+AVH%KA=X5d#y6QbRpd$yB4=^d/G8Tm:YX^eZF&8K?BT+qJXM^y<dI
-A4*h# 00047dadec700110334 Page 26 of binaries2.zip
MyQR1P %qINpn^1NlNE5!$J9LKb*EL%5dPWy%J1E#6:1CKc!ibTKp8X9$<mQlMbX>+b+Zkw:JiPE/m:h^eWGTuw
9mnSLB %SV6K64%WSF<Kum1w1w^tC\YBVJ8ubIBhqQiRwFVi&?9k*=h#\%XQEDB$h=#jap</59uh*6R$Dh\?eFk
AS%lk/ GFGLF1<9m9L?G:Mu?JQjZ%hd18W18@Eq!#W/M:l$eK@#\Q=T4l!#b!ccEywHD=kwl#%\aK@cEnjDS9Nn
b>QK$F N1C6b6Kd/B$y:cD1%dHSc*Cy**##FancKylc=&$P?AlW!Yh9<L9<+Y%E^+ME/a\/9cJ&&##eHHhSH9Vy
P5Fy#R y+4^>Z#tEV^FhpqBd%>6bcY%Yk5$!<1$qj54m/8S#<D+ymJGnjT#k1>HaB1J>TiViF>p$:pBc@<CtX9m
ebGPBy b!b$:FndNQqVActTY+tjKKCTY!A4+yN?>V/TW^%nTyD8&pZY>!MN<dT$WLG>=Wd^/q4!M\:eQt%Dd\al
=Jl>$W $9bAm@J9!ijP@$AiFeE98X9GlhKcY1WT>jy=t?&M/ttN*QZ<mPieLHiHqLRV\$+:MNYXH*A!yu9*$6?1
hJ%QH/ 6ElkT5+aMVHmw:$A>aBP>E>XSJ%P!cR9X+hXVLb6I!!wiw%S9jL:K/%5jy5IW!>\<ppNH4?uC@YtWD!A
j@dbSi iEw6+8?$9W1B$PN^N@Kpk\D%M\/T<F9JdK:F/m54K<6&Q61?BcZbqw^+njq<J5kbKwXIZQAX#da$t>::
?\4XqB >*I=Cu=FQcu?YL6IammjWZ5K@BCW?DI#EbTwmclX:^<?VBGTdDYY9Eik:m51$wCuJb!kA6ZT<9!4K&KY
^hNCcl e9FV\6mmWNikatA#aRdN=4:?@jj4G?94W#%6C8kt?niPDR/5%wt>nncLmGuLheYq?II\A&eei1ZRyN6?
PP&:cA k?AQW>SnJ1dY%NVwT9jwCp9*FNIjJMIc&PnmPcudi:KWQCuKTD1#$cR?6y*Vkma>JX+hpplIS\uW$e6l
JCYb=C w14mWwtyZtJLM!dL&QCCw&QhCJZG^5Zp+B8aW41DYQY<y@HV++Ku1Qj/^JRb&W4KbM:Ycm1QqaGtFKYA
Lm&Zue 1eW!>%A^PWkRpQWN1DWHuuV\8%Vd&+@Aq>nJA#BmZDCbTZei5+Rjm$StJ/SI8Mk=SMn6l%Z4i%ljXh$y
ZI8kLd X=eXacIFSK*p/SDCE?c*4EV#Bk%%JV1n!q!>GCNWeWcF\AR#/4n?@h*4T#@<AJj1JqLTG<Bp$l65R$M>
Sw/Wqe QWM>dY*eV\imZIyAY<hNCSHFYpwXwZRd$@b&QWl=%I^YPp#9$eJT?4aH*%E+SPZ\KBqi&F:$C*RjFu^a
>Lk/XA @8EHKCiX&<kM&>?eAdW%NEk\4@Se9RaVQQ:+K$=V<ZmdY%yPj>:e:I*EJ*KdeKhnFCKNSdl>1lah<pZ<
#DV/98 Ll?!%NMW?Fd^TBKc+wKua+Kut>bnbbWEbdZ5:P6Q^YB=$Y4L5D<F1EcNWp*C*KA@#%M\qchEM\V1J5aG
d#&McE X>IWG6EuF!55wZV/<c1CcVkhV+ebX51l++\8KP9*TSK>k!p=4T*bXjR&WMYDCw<cJGpK6kHq/1%SY&M5
REuZ+1 *eqebjBZ@AdPNB%DdV%*%#hiQ%?t9NWGVy5+BEdl8K*H\cG!n85Q?IMYS&@:SZLNiwQCW+Q!%ikL4T<=
9!Z>*E 8A*RaK+^:+Y>%SaYqlCcaG5yP>IDHQiT=eXnJE\LQpCDBwNKb6qJ1L+B1q+C1p1<hG&5c&#t1>@@@9iE
p$t8cb /SHC6MZd$8JChcu=!8JtLk%RkTy/dbeV?TDy5kCW!+PEKmW#u%wW$@8bZ\&TMK:bicmM*PEe\=m!WwRW
t&Tccl w$?T@VEBcm4m%TnYF#mC19=A\I8TL<XI!XRe1R8aT9qQJu5QqE*YX%nC?bIDjH$$HBi&N$F$nwanSFp@
+=Vk%T QiSubCe!Gcdyi:6&MccF1n56yPR^D%&>bQlIy>XYc*ZpNl$Zy/ae68&1kp:=S$tJpe!9w&%?/@ZY<8V\
E$/+@8 WL66&*?mR+haYMjDyAI/m:6*1uh1c81m^cBMn1yjC=m86<Q&t5#tE\VduyJC4dc<wJA?R!eH$/A/BXkB
p14cD$ KXuuD\8RyBKtyTdJdKb*9@tN\X/>TY1RbN>=AE6E9SctqKc=qRN4:?hI?b6dY=1dY\juFuQjpnH4SnAF
=q1!1! $+5kmX>Kyim\QiZ:c&F<#+Pu554VdP:Fm=^VJk8MWcVMZF>^YdFMpMwWK%qFB#WbMbbWB#u$bahK6yi<
PH\qSm ckAJcu<TBab$l6kyB5p!Ya/WRqWX6nkedTa>HSYS8ikXJWBwRB\P?$Q++A@%IbQb6R@?FNNu8*nEV+\/
Q#!ej5 FGyK!9KR&tA#6hZXY1KRi&n4>i9ZG\=nu1uq@A@Rn:nZ=8:biL$%9#R@M6unl6<%mT/NZm>KQTY19Vba
$hR$p6 &1jt$hBb44ewI>:ClVQly%Bn%B&k%LVtkK/$5KB$9:tRAC%FM+b#ZA*daB+hFD@I@C1k/klWF$W?=nj5
&m<NqB 4?$wWhWVRDZCh+&Cyi/Y!:>9>k4dT&a*GCSE9e&DZ\@P4c*hnw<nSFKN4%L\XS!1M8ZdiIw\JY?KdPd<
GculPq D69:$?acV?A8ZmKDt!\nq=4MLIC6eK6miMX4LLF:<&X<D$i?TFDSPkQ5ky$K1EA%Wt@TTApiBW*#>L/I
J^!TSJ kWPJ:Pdtbm=IunW5B9yD$<qa#KuXFBFHtci:*m6CC\9i6BD#CCX=u?q\T\cD6cdcT1Dc44@G:5X/&^9t
=Tk?6c q$iRkCtF^WQ4#=e&%yiuy6\AqVIK>VeCWp&yWjYb:mpi?6?c5yb\c%WJi*W<Qw^MTXhVa*dYHDAXqyaW
Bk&Wd9 c&5AcKuPXKklME9w$$IWiuYqP4c*B$+TbW9F^EP=min6>da&tdjnZ:&Jb$Jh*tAAwHbhR&H*MnqSkAyM
m1GAa1 I<FtT8CdB?pqHX^e8#NDiGLt=ZJCuVIVBX<R%chM?S:@6Iy6d/QTtSE^$p>m>uaSQGW5uR6#MmGLpMty
L&V1B@ VCT=NByQjmTJtTw/1LHaRtw8!!Pjt+8de\Rw>&m!tj=/necX#lGA&ZlWDbLwp^\\bbSHA?SXp<tF^aXa
5tM8:A u>Fa\wH9i@9iJXnJu:I#^VeETjChP4#EDwPl841tBuk+Nmk*ijF/8i%m8%81N/tAaaKQ\l/d\?*w8V8@
E9p+HA 5dG$jl$6AG:V=Bt>#XN/J@R1<$+dc6^L9!\tP^YuDjN1y4TF9GmS>wRYZKTACb:$yPCw#uVASNd*\*IS
8S6:Bd NB*R/eWMwe%8h6WB$=&&%*dTj9J#54AB4pB$ZeN$>8e6ALZb=jXGYqwAKV%+%ihYJ://HieJ*:@16uZ=
Iq1dQV iG*t9BL+<8mkM4chTK?>iHF@p!DN\ja8SAnHcndAbeZXeqt^FmXhM4+SM<i?\amT#AT>>I&ITpHT*EKc
Ec/aRI cjwCHb+MI=4K4m$+nRdnNAG+TP!MJ&LV!iqy8NRW@XItDMymtC=Jd/ub*EK@DFALEQn8I?5Lumy>GX%S
a1yHl1 Chh#&B&&P$\Ga$%VhVYBclutj844=i6L/?5dW^j4Ded66NICn$w=:N*9%>juJ!iH&?FVpX+aFGi1Wic5
:bA+t$ Cdl=yS1^aT*Qb/jqm5hXb@+Lc&B<kS:R4DGjkDW&m:1k?Inck?Jd#YwFkwk18$/<cZ9%y1MNJ$<Vd6+A
WJYbpm $y18c>l&89#==>*Ny%F8>cI6*h\eWWBN*dp#<i%1I4/hQP#5wH4p#*l6l19+nb?%m<+Mmk=pi5FV&N/=
tp5d&F Pcby*%!!Gua*tcF@Y8jE>I4Z?BHH9wSyRBqHW8Ni<FV5^YDnmch>M&8=8Z/46S<<SbALA^6L$miJNQ$i
Yy?/Lu <DYMCWu<hHN#>u+@iXRnich*SbSEtLLyFX+XtHKWa*P:/\*XtQ!4NXLC?V*#/+jq:=>9dd&e/uGk!5<Q
=tcpuK >%5h1E9$WE1#94R$&hdidpH?cqLILB4qw54uXu46W&IPZ<G$qGejSCCqL#GbbQQ&e/KGYGW>WWNaW8#E
Md&@an n*P9RBYAE1ZNP4E=a#id=b?qM!dm1a5MLFp:>1qnbH+DZe&jj*:/>GtQq=PJFt<pJTBNDW:eV5<pXqdG
ZI?<qV E#@u1TkP8knVKy:F@$#NWBH*kq>acMAW/GI@BWkWGQWSY/%Ibam9Cp<yTc$PBJZIN$B@w$BR#PKuqMYa
$T4pkC SdFDpiEbdqB&h1D9^MJtLwW^1RSltw\Fw!LNwu>EkCq=&R!>F#d9^@y=<kGwF4#H6qia*9$\98X=VN9d
1@ZiyH &\^G/+pV=9%cw<q!ZTH1<kcF8M@9W8b=pi6L:y+iN/4??A##?W6L%>6:Jl$Ipt\tyVBawCpYqZ#mwu9n
adqFFp >i864ZYHGElT<ylCVBtKhmn+bna:9SG9$?q!P89Ee/SPJn<4t@icD\Du9ic>MMDey6qd5=e!W==IQZu$
pHD>eA VWnJwb/$u*a%E/R6RR/WjKIkbG?\i%^hDKpZ=6e:PMnlcTI?H9q1=iqKjlw$D!1lT4l?%mnttV:nt1@e
Mjud@\ JVDhjJHDi6LtGulcVbn&b?cI4SRuIdEyK?=V^<!a1AJTiq1WWj^pW1ulM/Kdm!nh+^N/bkic?91VKHIq
injeBQ !G>m!FC$eeLp<KPkcbC<PZ:n9Z9>#W:bLEBq&!6CJMT>lbn#FblKbE:Jwb+kw8/uMMt^^EVhIqBjW:R$
:I%1Z% %IM&K&4BR$MwF6pedi/&/@QZ:!/SV?$bF9X<t>Ip%+myZI%w!jTRiY/#GMw=/8W<6:TIY/9$KaHDSuFk
YjH:kV aMBLD+HbhPTkkLYt#5q\alaC:D\k!lB:>^:et!@/&ubYp$!<T6NAtH1BcWCyFuw<WpNnk:<4IHJ?mu!d
#Py^bb 9c*uBkjuM1tJ8FIcuFEcIh8&%<hd1Qp^M%H!lV<hV>^=5duIm$idFCM=m@iDu!q!yqcihFmwLydX!WG9
B8?a5A $iAJ5pMN?AN?q%J#+EpHJEV=5QeiEGXR:#hXG$$?Zt5pWJQV<Yl<Gu?4lGJ/w^Ra\?M8DMSmVW/&9=1T
$?h6k/ A4K>twJT^jITW+6Wl&y4S=BED9XE6Xb4NJl/N5TP/9X%Tt9?>N$Rll*RIB?/QnSEu>4I@F/uZ%%ij:+?
ciM*jB Pi@tc4?k1ynq^wB9waDP\8EZ<%RNuhACp8^&IwPL@6iBKTN/5P+IulNeJ1DHLP@hC%#*k1l\$RyQATn>
AIW%Z> AcjVV9>Ft^wj$VhKWF&Cy!$iyRV5kZj$a%bRaI4I6:t%qZ#1*G*mJVKb!M?Nd$CMJHp<98N1C:Y^5aQ>
AmM:&w /ZlmnYlKmD:lIIqC*iyWJ6Njym&LbZl<WC:YJwZ6Ji6dyyFAW=GlmpwT/u\J^Ek9/L$Bu:wkPM1w*4j8
ALJJj^ %?\?E+:TG!%C%neiDYIcI$#AIm@%W&cVaZicJE^nA&VZ#GXEXiTuJj8bw/k:qJBHFWT%PNwhFAwSWVF+
*!Dq?j dVLay6n/994V@Nd4X%599?9l\l<V>V1B&tdD\GFQ#@ZqhXDXLib?VYy+nKpp5dpI4mLAKli&F!>>?@Bp
+*tB#b :&mH=Pe691CZ$5^#Z8?S8wMZnl#=tL<jPhlEwJ44^E/+1Q6!Hj<wmF4uI8M4wa58e?X*&@I&NDSIHw^#
qL#dkk AXN:k/kyAcV8!>%eRt??RwBGt5?hA/cDM=H^!^khuItwtI/QBaVy>dp+TV&@5+w9eytbVeYhM1dPaqTR
tjSj%! Wp:E9w5<:iA5L86ZMa*am?^BaZ#>jk@Q+pew$YTcL4=RmR1T@yqSudX1m6:i@cqQNI=EuaF*#BNSaBwP
#GNRud V/e=5%t+l$Wc!uY>VNXmLQ1!M^Ynk*8Rd#IibFE6:FDb?qKaNL\q4P</kj4/l!pFW#D%?lAtR4E5=S:/
hqhBCm +@4T@NLp<BVmJL!8Iw<Xma8G??ImA6a^yu1dda1e<MlFTcLe\GM&8<mLwuNCFL*\MS:G>MkS55J:>:L%
S>u?yS JXlQHnCjQ54?q+l/pDAXWbLP>QMmWkN/cR!yVQAKutL?mFkc/Kd$%M9jY5+^1BNeeAnDy?cu#MR+1Ii*
-AGV9P 000295ed99100110334 Page 27 of binaries2.zip
>iX8TP WFHtXSaYGXIZa1VEGyp?^uTV<>Q1ckAyF^jL/LP^:hZ&=ei&$cAStJIl^\y1kK8S/jR18>QN^W^G5QTu
JmhduS LENc6K>w*?=jY5bEHWtyMmmqZn@bbA1/b$FVu8YP>EeE1PCRwKlkKtYwi6GC5ZD%9b1M:+pVY1QSWP>a
uD#/Aj a1L?<B&FPc>i*8WKQVAXwA=h:$G5NQVD>>@N#%P$NPp+R&qP9X:+%Q^Mpbk>R?JTk9q:Y*99@H!HY=K\
Z6ViY4 Rly\uV\bEB%P^9FnAThVqd\1GXqb>MBQun^1q@VA<iVJp/jyF>TF%De\6TMWwm@4IYhKyGk+#6dZ\!8u
Z9kqC^ +i=\h^BY>^#\QNjc*Dy+bWK5K8c4?D8&K=SJjQD$?KhXwnYn=DKek5!1ei>CKwqJJG6^5bNZK#Kycm+:
eEe<%Q iEWNKiI!G9%IWANkK5XIAT!dJ#LyVL/KBEl@?wp?bP@X:>=h+cujX@SL*&l+^^MQAX*lVnNM$!VV6F@a
u:4iSK Z=t5aIqGW</hGcYPV&k1I!1\u<acEJYTXJQd%5=EjaW\/jZ#=d9D#FS&1Zj9WuB$ub^1Y<>*T>eu4\QV
XK6Adk hwhpWicMDM4aNWi@!G/A1c:EwHhk!$1TjKMlD@$hk!/#&W8WQKlm1V\HAiuB8lyB$=Q+V5+ZtP1QutR>
^51Piw B/Y+Wj=GY<a8?ilLT!=QINDqI6N:9FE%91#KEjR&S<:^$>#KQL&N?u$RWhLM>ySb9u@1<u!thMX@yRiw
eW&EIX Qne\nTe&<=l8<pddIybqmJ\^dwnD>ld*J!NqbW$CXDQF9kRq::T*CF&H@D!TCH^@i5JtN=e%EKVE^j1K
>A%*RA I91Hmmi9>1DL=9eSypp&9jeEVWHW&IDCXI%PS*CYKN&bauR!$X4nPIe\dYy15l445X+^4ID/*edL=<@@
Xlkt*4 >AiBKWC>?>*!$nLle>Hl?P/H8+V^?9^pD&bKFW#FNp!JSp%Vqa//nh+FHV:@/K&dae\\W%Ll4AM>&id8
Ey@*CX \QRkihP>5tJ+#icn>1NHJbQiWK=H/S+BE5wPi4Fl4MT<FB=JZL$uXPG:jA*EW\F1F:$t*bTaet#WKymK
+jMjbm IGtCWyu+YF!6I:H^FhM4k14utcj@iQn>Z\qbB$m9^Mu$a5\BNJ$qVP@Q<Y\bbVV>!lb1^qwhT*t%^bXK
EIk!Ch V=!I/th@!6<=!1Iuw*SRe#lbTC#NbnQJn>/1<JQ4>N51m5/MZpQVcA\?XWS8jy<9HJ*JpPt>n$&cAWIX
SZce^m QP&QWSIw&+GycKE1J4meRWWnHNMJ%RTy</#d*a8>^ZW^95CXl/$@@REnlw\1Yh@l>9ci?jXqS<>*FAlj
yalRBA u%?i:*Ynb4nhm%WG6^XIiaDC=ya/jKP*/K$ZJE!dKhR>wpK1+9w^IZ1Rw>+c<\HukbPM/Eu/DtwTy5l<
Rp:FmB 9MCWca6w%/V<5Q6ET@!<GHywdG\+*6DIpNI4R=lTDqMH5>9KtA+P*wpuiHSFXhQbu9D6!8iw45dnl*j9
hWya+9 Q9\y%5X=?#@PWm9M$!e=WWmcT!%tmKhJ%q=lSS$aaG$^4G<TqRe=1QStCNY8<BkZ=:PKeMQtV+R11E<k
RlbMQ! h#4<mI1maX6Fqi<SQbRMW/w/uiCYnK<4Hp1m?uV@Z1TjICW$^R@+%BJN8XGhhNlQSC$6+%1T*5LDJBRq
Aw:^Jk !Ye9Z8!ql&!6IC4FTS6d4\nWuub8iyNd:THIi=e*u4>e^qwnh1Vtl>\Y!Y$#8N8=u1<4W9dV&Je!Sh%8
<+GYi* Z&kW&/J?V#AiJJ1m8ABIL%*c^9RkQ&TQ#W:E8%BEPuyT^&IhCI5pQ!<c&E^=MQPjTL/SpG<pDGBFGpP?
9#^SXq WGyptyLyJbyT54S6iAjuJ8I#uJ+K$@9Z$!85m\SM*>:>ASGXjlLwm1e*N#Qb*H*X>m:PmRqRc*FbWlXj
ubc/dT IXRy>m&8Vw4aN%m6pTtbAcB?$DR1>q&#>:JM$n?#*WW6KWY@Hw$kF\%dQ9uN/LNuD^@FWTXEP6PFCAp%
H*:YB* JH48Jj6nA5&IYJCKPJ$F^NQ6eXDWpqB*AKlKH>V6dl?iG8db\ZbSiZmF&Jh</uXaZ^TV<F#p\j*uR>m+
yuHk@L peBe*uE$hR\L6cX!bieadVWJj4T>9cPDcCSl6b:441*unmmRE1mZFP84aLy*:\p#D/:Re%VW<pFM8#MY
A!wcCy Y%mIpKQhkc4+IYF?i:S*bMRDQDH^i:/^AipM*9pS64!M1al=B?@Mpiuq1eH^GY!&yj<cW<>u=\qVnNRi
41LY<8 @4TBnC?tTIqbtXSP4R$mTMKGPJLTtBBJ\4S94E^LpK4=nFNn>JQ6>RDWL6/<au?cTij?@NMK&h*b&j5L
\Q8wbl m#p^4m*1C!5h9@uN:^+>jWbMHR@HSWIDC1MVN:ekIq/aZ$HXYQ?Aq#DhuuVk/Y*Nnmp#p$TIV5+9LT@S
+/PPK$ M>uV91SaZ!I1^WqDEMnCBDi^du/DDQL#=$M&Hq1k6BWW^5CZ\!aJy<1#8q^%HLuaMaK6:5:SpI@?B#$8
b+XKAk <1Y6hZW@M:\Kukh==I^M4$=>IJSEiclJ<5c\LNTQ%NS<<k%R\hQSpbHw/M$Sen$nw#hG\FhETD^!H?T5
+6l^Au FB\>h\+pyYemMS+Q<ujSQ$&>mTt$P8l6<iu:d:@%%99@TMbZJ68L@uS&ITee/mcML:F!DtQZcLhqYCAy
aELuyP 5!AVVb*=HDXm%&nBWec$K+ClanGQJF#y:H%/EGjqMDcINtpmedQ69@!Zj*u$:BEecnDjPIZ$#4%:TYZV
6?!VpM DXYH!ICT$^SwqF\tn!wQkwq<B8PiW@NL/?K=P>Vi91HG99Cw*\?B1F^GG6q/>j#=<?>:SKkLJSeKp6!m
XC8dul dThCJY/@pNpFQ#9w>d==</b9>PdNSGIt+kJL!eIKWAW>FWkJ#!Q$w\b#?WwuHE$ap<pw!cHaRH<MWmTI
>duDNc up^9$BSEHSt=Pu4nB55<nI!C1A*$GWbPA6&ad?CBM??=\V5Ve*CEE!kLn5jjmH9^<uZqb=KI^/FQD&NB
jTBq4S =XeNnieJ=Cmq@Bt$XGc*p^tYeWl18b#ECl%#jiSM4cq6VIQGE45jFX@<Xc/NEXF=AEbATtceMF&+V!H\
\VRIEI QjSL5S5RVw#&@Pa*@*^ndI\VGbHQ\F/u:m$kNiY\h!AYEVaawSKFw@8*I!R8ES1WKEq!EKVD!?6@i9q<
<JSbc: jj&:>V@iHYy##LQ%jV*%@hc#%/<*qut:yw*M:j#4%%6Lh+jW:MZYnw1\cI&jea6Q$HelTuiMDLh*nD!+
9M5c#c hi9t#hGdn%btbqc@naPq\JHR*QcmdHQ=1VG#hWXlCukcCDP:JHiG9Q*>@VFm1dul/MtGu@HWBudiiDB/
8>#$qR \?>4Q#>!a=Sw&wk8K4uB45?StQJk1De!!JC8#cHeEA>j^u^9QB<nlT>9V+PT><^qRwi^wQK4W+&?##^h
5Fj/>? a<SRItJP1Vpw<l^\w$4SAVTNWe!4:ieqWuWJ%XlG*lk5=V$1bDMblcc#DCpbu#p!9@R*+Lun5ilaS%ZF
G94>#D L<>jJb/1D/bE5@hm\w*&A%LFtjdnB^VHSG6G4C#T#\SS$i5tqm=la?d=PlujiVc%I9dhRyL/+9Z*R#&<
\LeR:L 9Ck=lni&9mQILiwMGtS*lu4AXJP6jWwETwV$cGmph*l1ctunGVu>+SC^hCZ^%h46=uN%B^XM<bFyCuwi
K88L#* SL*i!TtM!ZkW>V>#4cucdCw*+hhR=uZKR16PGRk%/bXATY@H\5!Db<<ikKnk1bk&a:Y1:tdPZ?4RQL$#
t#eIa! 6#mHClB9K8bXJAXQb?I:Ju#yqW^F@Qyhd:&>t:IbDJtNE+\JaL1w<FT+W/!%Ga8%%nIu+HXml5W1!$=u
bu?*G6 E@%>lW5qwwwRmd<5?uZIT?FLGXQYe=lLpjFq$WqaC<8?*SZu4/tFJB/9TMH8MnHJ&k1qB%WhAAKN8pKS
liZpQ! #nC1Sk$Z%cHD$n+$DNp/dQuj9Z/hRmK+V%H*ZX>G*jj=*i5A%Wc$HB4mcmIb&GK$Y!^eNP^^PPCTi*8b
8jV6jS 1bL:=5PdI^iZ^X:*u=<>9QWRG%9^&<VVe+Kw1k9q=k5@V9QSA&c#EWdZVBCcij^iy#QWmCq<5<=R?9PK
LZ?*:? A\It9e$#M91A*n4aY<TCKkHckTD+QIbPWDe/^&NJk+PLRHS\EFW/aZ%u+wq<eVC\nYp1q$qK@@lB$c/*
+iiwyG h9@n<Wcj=*S+JyhLM/cdIyqbFDI/&KqIXtN\yR@qjD#F@FC5bI%l%AHYq?XFFW\##NI@+<9eJ%Bup>C<
=\=mD/ Iq:HEym*J^<c>69&:j:Ey!A1PnuJyMBV?NQ?uWVF9IyPCDw\1Ccn$cnVa%m\9Y%+e9u:q&SWZ:>eb$nb
Ei#W6d $C1Xl/u9$Eu>$*hRl:Y%e!EjSWZWFZlTnV#1>i8E5<%lq>\Zl>66F69FphDN:=dy#jD/#^R&d!E<J>5d
E@qXTH 9^LBWKd*CHPV/du*IF6eSL6t*y#BW%J8I%BquWGm9KdYTESF8eHIZXjPVkqW*a=KpwPITyl8LI>!%P9#
in&Pp^ nI=&eHFR:84&W1^:41/=6VpTtcAuEtphnQ8SDKLc1/#=aq=/B$@n<Y\8KS<@@M/86\@4WS8W8+limRTQ
1\jGLR EmuNNkSI*IuNyJJqtHVIJHuW4JJZLllePW:GX*=Qk\WAlj@^NGitQ+t9Aue/i?@iR8wiT#pplD^5%G<y
eyMdkn &1j*ldpyp$lm8mYy5JLD*u:XCDP<cHmXd+hItpK6Eb8wSCw!9M94#%G^j@u>*THSM5Xt/yL1Wq>Tq4y<
t!@G/Y 9cjh=y//j9e/L$/^eKRG=limP?m666q5h4896^h/a!QLj+JPCm?k9>=/CE\j^ZtPtpC6P@n^RiE>Mb@C
1$wYYI ZVY:*Y+$EnXLqhDInFFYM<@!t4hdyu>4El@FJN@I%Ri5::D$cISaP8LuXJXddeSV54\wA*B#LSl5laEn
GE=l8R CFZSK=Yu?SkyEA?uM5q\k:/Ielt>=KHeJp!R^wtuGbGkmuppMVJB+Mc5bhwatt/a#K@G6kY#%R1HGnC<
5Z%u/q b@j+8\T1uGeTyp^VATw<Ku%QR5blGlX:i5Q=nj8KHGGSP?ewlMwkQEw1Dbth&IKumF+$k1d:hamB6h4>
4Lm:TP 9F:eM#!@@l\L@m?Z4uN4#iHGD1P6diNX9pP#>Z#=il9V6Mh6$a9X^FII:tL!$I$^JeyT:bK>HWu8yL4\
a@CNEY >t?9!G:jG4%=K@\w=EG6+cC4PTnYbI:\Zw!Pk6%tJ#C%tRm=<pK8$b95byeMRNWt8J$SNbTT^djbbhpt
M!K<l1 tbS8G<@=W8RLl@45+dNqZuLndBl6WG?\tihBAYq*X@jqTLD=Tn\eaFTDP#Ghma?F<>+$u51GQcep*c=h
K@GN%$ ikhCuADKAbEE^V=KpLVIMSLVFLZiVDKbetLW4F<8qqQeCJP6YmhQPumKm/BJ!p?RG>9w^AlIb^ew:4*Q
b%VdLJ 5qjJlSmlGy/PSiPJ/XAqC4?JXI4:+LMbuqCcuqc^XI$9jmI\FjP>lXA$E18w\HS!mVB>@9!Hyd5aRJKE
#ZP>JJ W1lSW4y8=FI*ED%>%?Q8Ie8LlRpB1RHcwPl>&#l<5yH%hXNPPnt@9KZwXEIt+6qNmh=<qD&:/84Mi:$6
NjlKq* ASe\yS?/QTbiL1bjJp^NBmMb&HIqK#W:ZdJpEynKSpbWXYiYuX/9T#dLLyi4AiD1VR+BKuR:Pu!<bu\i
=!AKDb dSyM4dR$%/F#PpPRhuYQS=1dJ?KEEjdW5DD#qd4HT#Gummt^JbGK8^wp@d+mjaPHa=^AIA=%8c!m\+4A
D6wp89 N!PW!<V<jaaDJGetX4\@KbT&%VYwkKipmMWPmc4^GcWL4uBWait>lZ6J!F@%S$DGbG\/i4b5X=EWu%A\
^YAWWT ZRCt$<pW?>MBNiIX#4YEIiZyFYW5mWhac6%6QbQL!E1@k/6WF>%ME4FBVYmY9$Pbad*ZQZT>l!ZZ!#Z9
KXm8Ie R5&B6Vq$/N4bCFFKZ>9di!iuP8hX=hFZ#:a&Su\liwH6WH<!P\>RFPVE=5V?QcZa*!FRn*^<yK:GLIF=
-Al<M5 000c24fc26f00110334 Page 28 of binaries2.zip
dXjQDy b8E%5WJ5Sm?j@clb\lKYCa:$R%RJChKa%\9*/<LPlI!SI/TwSNT64RjTcAiZj=tuAR\E6aCqDFl*@QjN
Vh1dXB k@F\MI\m?da/ujCua@twF$LNAW@Ad>JZ/i$KymlJebApCpuw#CRX+<6Kb9$aCF%A9de@8XN%MBAIGudy
>De:A& QhmA=BSypj64kBR@FtcF^lY4Ik%k6k^WuI:LbY@9$ken1Z5<4=JKdqeDFT$5nwL^cRp1QJTmqycy5k:$
lwttJT wh^R*++i&ujLCG#d%c#VmJhV44i%1\uN>!<yhi%^CJ=8K*SA9pGNul$M/jDT^4JRZZ4^it9=+ePR#?/V
=p%HX# bCIiyTTaYcnSdR6!qBRW/mAC<QHHmG*N>Tbu9>MpQC4G#:\W@Z1=^IC<mWi&njVL@SEKmp?iQE%YG#X@
t?ltal b\9t:Eb>BP4YM&F+ja&EKjc#A<CXZq#MKBFeq*>@=a4cd^dGX/^ty*j+$#Ckt+aJqmm8:uAyQKZeB@>m
ZIEA$N pTJjIJ4d%p6H9REE^dD9kw!mk!n+B5Yathin&ZZeB:%8lEndEbI\95#VGCW4BJ#1M1hDyu%Fd^ihDKa!
jXp1I6 *GGLyXSqM*cwK4:<caqBw%HdMtI1mVjG!ShTLwJ86/Ijmd\Vc%6>56*lEQP?@:c?@MQ#=?9D1AV&6DpA
qQ5!Z& cVFF$cY<N<F%RAQcL\=*:@LpP11JBPy4a5%wL^1dpt#Gew!bRmLN8/X9!4$TymkyHhp4BpIJSS8ammqS
%J5dC\ :$A4%H$^/\SE5Xqlh#4y@<54u#^1Q*q!4<l\Y!JRZ\\Vtk<i?H\l%JGpByliV$8Aka$E8?pqbW#nX!cW
p+V6:? Ap$WBh?J<Zl/Jd6VykQBcTTXnMK4TkcVw<En?#*5WtGS=%AhuM*^IPheJy5WkT@Aya!t4C!YESPl!Y%>
R%b#4d Pu!\:#yM\dQQE^b#a1w*=RjJDJLW=L%pQ9\JGcBDYqSmn\DV*F\T+P*k=p=a8Z>cJAyITq8<$GTwl@:!
?CdBbT EEMq^l:R!nal^*jTm&qVm@q*ChRjll^6mHAqh1e/$RE9kV+T//KlA>M:TbkC%Bi9Z#?:=dDyMhnk5^@X
>qN>QV /R/eIJd?6hR&^Wmw=u?<6/dG/TI8N*q48BN#qPAh8DS:*&8HI+YaJKJlItp@RWw8>PlJAyWVwly9nQL\
cWaGc1 aAe#hBVmD8h=$^<nMlk6wpC:m?InjP@GnEw$jJPmJLSqiPn4/b6FjCTJTVLXFIJ/:CdJ*uHc$<uGh#\T
AS%/Mn S?ALVDi=nySSdT>d+V=5wta!MW!E1w&baCRpw!%8&H*<QC1PmSTt!SSR:>>uYP?^&PA>eFFEQ<taehi?
SG8A\G C5ttKTn*eD5tI\1>T5ndu#i@@IMFP:eLk+mVC55lQAmy!Dc*wyPDpe=TZ5\&<kDc%IaIh1c?j@=<WtB1
%8?b!l E<L=BQ/:Rui8SA\EW4RM&:5?n>Hk4YhQH@pIEMpwt?8NP8Ln*5K@wiF4&k6Iu*!M+8AJA6Ze%FTDcPlp
Y^A$+p VSM\HjD//YeR<pX9^69ZQ>D9^dCD@mTi9X!*MGPcqJlIKTuW4>mbpw@%BAJajYqyd9:<<&d/>9uq!@H+
At&pWY qjk+YByAKiq!bJ\XB%XRqck*HWpSytPJ5M8t%>5qQ:V*ChMRiA4nK*a4FpXBEBKTmk*GnNpeJc6!cmdC
!SMWqK 1BKt%eWA%ZN+>@FG54%=uwL4>*P=?*Q*YakuqeT&a%KBTT:cZYELB?!ch\%SZChJKdZhTB=R$SnuhAd#
=RYeJ= 9ey54&KCaVN=hljym$&@a@MFl&T+yX&9EJY5:@Qu<<B$1M&Yh/j1Z4>Sd!NI&>66*K!n1Hjq+eQp:btk
5F58cP !+X$=IVSLJuJVP:=G=n8PZD\++?j@PWJb/\A%huWSIET^W6i:<D5:EDMVm#>WJlhImtFVCiQIu?B<V%=
EK$GYk $k^Rc%DHMGMmmcqKpEyRYZH=$h!tKPw$l9FQN*@i*h^<JW*pjHnLH^AnZ?PS8I4ynLyYHE>FW6P\6AGQ
Z?eY^M uS!1:#TdZ94>FQmmM:M=C!t#Piay4K>/5kLqZ86CQ*&kXDaJWL%B8dlT/\@/Qc:Dl^9Qp#6qVJXlJA!c
8lcGMb $Z5pp$wV19hTTjctpj=pu&bZlaj?eq$tVaE6t5pTVTQmZ?%p/wBA6q@bXh!9Lm\chT!>#DPB!EWMED1m
?@AElh bALX8SJq8Bw*LNdX!5Q/pIQLC^cD55!WH!uV6@FAIRXJW=VI5ILY\%DE&%^*=EnhyThQBywMleSV*h<k
=kkWnJ cmGM:=P@@Q5VEBYmGnWE/kt##in5H!BMb&MtFq<Sble/dWSlY:qij@IwM^XhhChBY8h!8aZKGju9Bk1F
SAt8lD ba@aP!T<GhLVQGh&lVAMQ*!I<TDPb4=K1Jm16yiT$&R!CB95B/atm4XE+E9MV1dt^LWR$biBGHw1qV<6
8bM^6T R?qMeS@>5CaVmYRCV6Y9LhPYhRd<=AMPH@h$Kbl8#t=QtTu:mqq&!VG&9J%FSSIp8aIiW$tSLbyIK8YF
&wPSkB tJByX4WqFh?1:ECJ?KmRS+W\B!1E$>65>Vcn$Y!8%lt4mcQKGnBTtw6VDP14=TFKZqpu!/IPaJe4tP4c
ZLDCSN qy/@:HG:yja&Cu6j5ld4\&mRZ8wnF=+<?ituJ$$qBVX%B\@<4a6RyTD1Z@:>L^<j4EFqu?LaJ4K9NYau
K&ZyIh Rj4p!c#Z!NPi=F\BKc!!nuq1cnl/?1RbwKKt$N4eHQAIYS$MlpwNa9+9+AyG5DNVX*j/>Du/Zie\Zbb+
KNll*S GA=\eyJj@ljJVICAJE\nKCIF\kqKy!u\%VjIul$JctbPQT\BkhhWi8iqILGQYpcBd!LFQI$kd4KTQ?%!
l>wQ=8 hVWeQpM<=Vl&M*e9pb<$E&9F$L%KJXNeVa4IWnTB9%!L^%BWbA?\ptT@<pNq4FIe>Md!GyLEXG/y%FNT
?!tHP< TT=R6ND1Vb!@XP81c/1hCGk=DLJNVZ&@9I!E=9WGPX$Jqq4S$8E^\Zjb?8we#%?@^pd1=HLd<E8IF^Kt
*tHY?d qBk&i%9F8cL1kwIDS\+i?F9G6@AAEjW9@$=EdV+mRQW&EWYh#wH:BPq>L<XDh6ubD:P4Lj?\FAuNTiny
mtp8&n tE!C1Z8BKZ*#5$wH&h$Pu+6N4\hVFbFI!?jN\BVLMpVViGJ<JS*t?$^\1D6+T6a8uIdyVe$q\:=wI8D*
D!miDA A%QPe$ZeT##F1IP+AdPaiiPeF*k&F$P^6>kyFF5^nL?@5lw^Eu$F??:DQq=nwlly\G1X^XRT=Fh+ER4m
+RCJ8^ hFpl>e1ck%#nmul$^NtkwPp$/pmMyFJ\ALLBtNDw\HekC8Gwm?%<&\A%II8Bp9t?J5JWy/88LlT#%/WP
G@WMd^ dAc@jwq&&?6=e45&IePhQ#KEkj6Tk6@^<9XY4%6!dG^NZSRmh!FQm>e:GBq+Mn5\MNCE4:b*:+GC9<uV
jVSZbA A*9J?JJHdY$XcR%SqT?wANMB4$tm9^e^%&p8y>>eIw=EtZk*HA/%4w/5L?<wupemR?HSiS>HTMAmGI8$
Lj4PaI pPpq+$6lEyEbtCci4wRDZeKlK1yZm8&F<a%up=qeAmdaL#A>#wt8t5!IG#CwDc4F\i&Hh>8KRhME1@BG
W1lIi? !4TXYw=:<Ziy&1$ZtG=8DqTYHdIqXEl=8\*ZD>JEi+IVW^n$q^pHW!XDWduMHuR/PS&dF5uMn4=Mj/SA
/XJ8Cc pd^C<AP>dHhHS+idJ%J5GB&WtA^G*S:p@EIT*hC&^M&c=%QjdT!%6WNWZa\%1QJJ8M1u\&>e&y4HYM9G
RZN/Qc /\%H#@4/=Ilj>uyd=\aYeNltwId>cKG=<G@^qD\1Yh<uV!=>@QEFim=hA1k%@j*5Vm@h>$y\yARy&nWj
ZhVa<\ Ru!R%^Xb>iwwP%R&9pGjRqPj@d^Q$TPVY!mYdBH^EY>YNM?Nn+>QA>MABwTWRReqSlJ^d#mctp6l*k8n
#Y+@aE $lJ&du$8u*<Hyw8KK!Vn?:MHW&dP581a?9Mt:B#nDA=jPHFX:bQHlV>h6B+1&6iSb5QLYwN<yETJ9wti
u94D45 4HRX\h=mm%%VXN@JNuhcEFZ%yD!+HjH&F&laedCe9cSN/8$aHaG$N4qTDIMc4W$EkSPu8:B@n=NP^ac&
I>S/=A bYFJq>9cpi?RtZd5GG8AR>ZXcE6kjH9+<5Z%%%6V:9diDyQp<k=RKpKwZBmw\SY\\qJ6ni=9u!R=aD+w
N1Q1SN ByMY=#cj$QQ^paMucyCi*1i+6>@dL$lc?8GHJiWFm9kKq?>NyyQCu>a%i\YpwjQ!?RcZV:C$\iPNSEVR
\t&quc T#:%HHtCK\pKnJ+1tHb%e*W\Q:\m8t%lSKLAFENEHt^bTZ/@mttTS^%a\liFyJ>DKm/T+Ji=nF>Y1T*8
<pJq#H =I$b4G\EQPXXWhYjGk<XXZc!pJumpaubcZGRMc>Z!JPNLyPt#N4H%J^PKmG9&y%Selu5FLMuJd@a$VE!
E8<C?k k1qQnAQ!jK@eSJS!G9qTwyA^L>HbinA*?P4qh&*6ZEHCunm4?t+LK&t%B+1J1Dc^K9Z>/@Y&uuaJG1/I
N&:jN1 Ym<Syq+pQ1YF8ywV84@JW>*iA*9FhNLeJwXV5MIZKAk&GJ&wmaLuFB5btKFCWLIeC1F&8$ElKn\\P%Na
S#et*n *kaywIc<hp<p+AJL!jl&a&!d*CqntwkGAq%M%Mnqtd#5qRl<CdPFXLk4G8<CyyD5cXAD*&mEiL1kdkR9
5W=wjc 1pZ<dhM4lqteXt8%F4*^5nK6W/#M<Cy5X=jBq8Rcjt:Sicmw:CNQtt>5JpVNZ>\DuNkYha:#D$>%thac
HlJNtF &6qiE?5!wqDakupp+Wq6ElChtqyiJp\XGWuVYZbm#uINnuiXFCwmDBdH<Q4YF4bR$YSn:Vyp5\:Xwbdn
k6R*&E Yy8P*kI&uI6!P*w&%kqb/QI&AhML5KSG<8Q:6VWuVtn@Jp%Nbt/+Hju+TP9>u@:>J@c5hRBX%\>Ma\Qi
a\>yA= F4Pl6F\aZ6C$uBl16=NlNIq5y1/=G%uyKCYu1ES/qL8q>pAZejY$cu5n=/=MnIZHu@/+Ap^=CWXJWMZ&
T+#mVZ Q^eH\+A5GSCtX\q<Xh5dDTiT!k\>G>>WJn8*HjltWTPe\:RDK=^B+1!5Yt\X?:6<?nQu8<IBc\maWmw#
::cAuR wQqIW&RMm4PK/SV@HVAHM1HRhHAdY4t/4E!P1iRWWi>&PTqYWIl18<HpeF<Ewp6LT<9MW^TREQRmLnGK
yZD<A? 8&uF!n%MZTqKTeNph!euicuN#YYuHcF9ChTNCp6KyB=aZ?R/=HSqw%tpq^iIjRh41mu\1pFM@ZhPbmL&
5%^pd: *a5b*\59KQ=>e8uTBXam%PmciD*XdEa&#Fw/Rp+H/@<NcPSkMi4pRZKt*DWNad<Cc#MiaZ4>I9=q15Kl
GiQpej *p/E^^I@@9k$D694F<KRT4hNqX+ld=4Ll49m$+\y<=SmJJ>mi=HM+JIq@aD6lT@eN5C<NJPbm:FiuXCa
<WpV$G =A+1>mw5?\+%p15P!q!#wD<9q^uLmw&SPVB$Jw=9<RtibFR\9WLj?LNp#Lt@&Cnuw%$%:qZ19nHi:KZ<
&hlcaR yd&*h*l1iYyy@j9=/$\8tF/4p$&9VnpDIm=NFA5lFa8njYly/d948H6k5VGt6t&mA6TcAkQY*9mY%Bpd
%>IRdS Cw5k@j&B8mNpS=8eVVXc@kZ%jyDt=+u1H6MBFG@4Fwtwq\nV%tcAC8%IqA8QC5WYYF+PpZT<F&/uB$R>
nF\dFp HR#Dt+/ES5=:iG9P%cZeFFEaT%^%8X1ck+t^<NnKn#?85JZqMi1+i6qYpd$KJ!KyZCdcFb:l+ZqQA<J4
a\Wy!d u*Cw+i$1Q5i?e^t?Ty6?\/P!6qq^YVWP?tnLaHyd!QS/Dl$15pB@9e?=RJnTt/K@#A4?RaRk#wNc+4I^
pH+Kc< \mIB/mCBP9l%JJ=K^1#c+qw=FFNK?AydXb?K145NI=4DW%Q#QJy>jal*JnlCe8L?wyQQP!uKa\Wqm91a
\pQ\m\ A@hRj%nH$1Ldk5CZ@p^i\//<bL>S1>YceA8MItmyukJwIlhBiQ<?ldFQLq&+RGmiwHjM:Q*P9$jWkn$H
-AZWm< 000fdcd00af00110334 Page 29 of binaries2.zip
np#NlR iJmqJjhme=Em+NdtI\V1mWIiM:N9!<h??KHR+>H#KXT=+iSy<?hCQ\j#kl&TS?JTk*JH&mM*8ETmm6XW
\CPb9B JKBnML*neX+k:ILk/$^<=/a+inJ#!R!q@A!nC#!%TH:X?I4^qh!m1CSq^W$>yh:AM\@a6+lbbSdXeScZ
JLAW8J NdE$CNN$H&EcVYSm@X\9Zym#%u84m&yDRkmJX$=D+?T^w<G+mmq4y$>MyJLP/8Jma&hMTX=mYJpSVAY1
/W?mT$ JRdJ=4+I^dnJ=cZq!jt:kNR6#8+bbW+Jud46&%9m>kSnTnS>@y\^hhmay\l<Xj%AHam1NhXn*5YCCw@V
EjTu$8 !:e=:>?@hAtd<wl?KWtqkPjJk8u9*Sa9LNWh&G5?5Qh$bBGajk!t%l*ei%KnP*1!uNiIqaPw+uRtTp6e
iaYa=^ %TWK5n=?/McNWZKth5puCIwYhCDkIR55i=R#iJS%Zu9$mp\98W/^\+IT*Fj1Bm1tX<L^8j8bTEywKGBJ
P9j>@$ ntijXiMdD/phXFHGX:Vq?AS^Xn$%p#jGlCtHTN+A$jRj>BCEVtS#@R5I5PdY?m9QBnWX6YEl=BNuHXD5
^5MiAY J$dF*bI4BGtKRQ%/pIJw8ZmZ!GmWuul@juw\F15CwtS&==iY=?eul$Tk/t:u5JjL1@%P5%FZ8u%4RBG>
?dNIZE 1aek<\@Q9%?G$bWk\NIGCX>%E=FABXNNJw5RwJT<A@$DcA$TyE@+Ra&Qu*8&<9@NeZEwIy$\i\eHiY?<
hPNFb+ %X6H%lk#?TbDKWaencb69wyNakAw?\XJmcaT>w46DWIM^>MX?L#8ZF$LjK9L$^!MSAPiANH$FTSZ^5Nh
R5D@BH A1Z^uXNt\Yl<P5eKj\1tHCSbG9\?^cFGE#!>pqQu6tF<<:uyuQJB^hT4LYbMk=*HDl$mh!w\ui%HdZF6
wMnjbD dXE?FIwX::MIq5aFV<XFijS#BkeuJ9nTAZ$TMbeW:jyI:55DtS<#m#ZF1ml#HIHbuX1cuGSk@yPD!$l/
TX/etN 8FNRm#A%FicQMctK8!!!#daZ*S5JtD4cLAdhS?Y1LC!C*:\&qyq4i^m\i:L>#N=jYLnZ*?p&@D&mF8#S
Z9A=*y CG&4A>=YCu8B1dQ8+BGAmtq<aG4WtdaQp@DX+kdMD^BJS&/MnIVRn@HbG%kH\BMiC*i*%J$:%!^W4AI6
Cyb+qb RYJh+NGQL=+teC/wT?\q1diKqYRtH1i\NlQ8Tw^^aP#*5WP%m&TG+8TkTGaAKne&M>t<K@*=aZHCqQ\q
h1hqWR a&w>XQpQFt#l<Nnk\kBn84ck6cb\6E%Sw5MPG+\@:@+Hk:!1^beP9l:$tky&Fd%Z/?^V+1TI5nPD+aCa
A@/BZ^ yZ$a?R6>u?SWW^ZYS6k4m$!tYq6aY9I#TE&PwcH4j%^j8w6SJF!=+NnYIdRD+ZB+I^u1HpLJGThn:8&A
RAC:%W FQ*ji:h8lWI!kTL>ZXA%:^d8$SYmmtZ&6tI>%T6A*c5qXI*Gct8%Wa!b1XiL>Z1HpP$hHS&>Ab4KaKpC
?QbT\a /cP4%\IaD@h/jF&<5wK:Mhii@jnnI%FLFT8l!p%^wWE@Vlpm6FjD18pqWEZF%$jYkDCNl:p+iJ?%#NbR
8BB\bt hMmQ4/m4dTq%SDTXCtqF*C6Zql&1\JkD>$?ld=Xdk%j86@a6GC54R/!!HYcSX*Y1yl6E9VNBiMKutk9i
$Rmdi# K>EWF%5B1lIh>ZP9DXR>k=S$T6lhiFEL%tSRGc#H?BFnmqqC^b>1TlW^Z$h::>D<?9emRpIRVPacFiK<
E!h4\= ?n1pA#Rc4XcbbHJ/a:GF?:Q=wb6:tIG^Rd8R+HK:@#e*d9qRY?piuhtFJq$4kXwDWE>m=M^edaZY^DbQ
LXjk8/ ^R\wX*qH5Q/EQZGC$+e5JwC>*P:QIVdIi/nleMBnQ?>:>PPQ#/Kk/iX\tDGNdk<pRa$?lctWiD\6pl$G
TYDYIW 6S\Z4%$i49mG!Qbt55w5QqR&=ucWG^SWF?c!Cu6DbeYMcdZ&WGZDb@L=QKb>Mc\4dm+/4R9>qYXuy<p4
JGhcw$ J=Rq1Q#ij*e<I5/SDM/=T6<6PYp&jqSt:h#Pa@L%yDMnwd9L!@PVp?1em4k%IpFJl=PQJ4MYE/IeJWGq
qLLW!E m4iN>il#j@jH://4JWH/W>!je/mkp9ZG%Bt$qcR&8^!/qa\N<GRGDQDtQSq*Em!5kc@V&h5hj#j&=ZjT
T?mD4j upKV?RBAdY$q/!8Lyne^%Wtkpp5%9aGyk<<dnI#i+E/+nE5!Em4tn=+>i6S%?jQt#@%&dEPNnwW^Yun%
<I?K@^ $a>QH:EE$ZmpP!Ae1m1%#W^F$!XHdm@8X!DqK4:F=%GKk?ByKm>Q6/PKu%G&WRutuJ4ilLVFMtE1q%XY
5V>!hE G4yR<k$4Nj!FQ6EKGKn5!#tJ1Nq5Ynu8!HQ+QC9Xky\Glui\?eCik1QBF1i^#EkJnVL8pC<=^NyHSycu
6Hu^AF lqFAcBM5$@Nqay9FbDI/eZG<CTin$Xw6FHNnRpkh1?Dje>B4W%B$6/GcSG=aYcF!+C51a5D6uVh9lY/6
$DLm%d QJ#8e*IycdMQN6q$S1?wAd6:LQ>dWIty&JjBwn>&@YXGFcCm6/6a*&%>dV+8R+aZJQWRwnJpp5n!awP#
IB4pXC ?@QQG*m*8G85m+^!+@uSb+?J9XElyKNk8u*jC@6n>Ew9hFGEyNLW+$Ik*$ltY?t&Aa%Fhc5+p/<&KGjF
E>uBD+ <VG*iE@\NAmiSwLc!54KR%IZm<C\DCSb*j/=NN!^6VcbeXdKTjSQE^TlKWI4HC>^?aE64?=huT5TcdEd
FB:a>1 6WcPp^Se&RIHI:?duB^tCSYq1+%NGW=ADCc8PQR:1&5Keh&>5GVHTRK>k#BhZ@>81EjNTWFWkTuQC\JV
9\lh>l LNGwW/TT@iLW<+$yt>H5^LXYY%=bu>WhyJ/i9^<u1Ye*NVwM:$K!nECX5by1%4HkyA%1Dn5$$<HTB:C<
+auL6c CHulT^5wn\p@Ip!9nZYVFcbj>ZWFAGtD#$i@Pwy#tjCwm9ENm&bdNyeRe9i=ZDa\q5hW>uEX*?:l\Bi=
=ZNeHi DAyJmq4k+8JPd!yPRVGwe!IY:kNQuXm%1K!$?M::Ih$mlHRY?tJ#bPa#5W1bkK&WiScXh^YXhXM8SHCD
+WKX$L b4Bb>&/lGRQKLWcN$inMZ:8N^cbnpWk+itb!8B*>M8Xm8AtDK\=q=J==TmHTju1$85KTpy&apn9>aZ&w
a6JqIe ^=HH%C%c+@^#m&T^EJZ9:4#q=y=jZ&/u6>Y>i<qi#C:qFhX6D9jRhail=N$*dmn?FZFL#CjLVV!^#cA!
w46M*: XW&aZ*GcDd!m1G!%IV=/>k#^Eb!ylIIlBcql!F!AuPJREDc@CY*j%YjQ\nmZKac%8i\RRIcctFG$/HMR
Cl\6qd 6WyGE$GBKB?F+m1?*?NZD6I4!R#D84M^w?#?y<RQkTq+Yq&54dVcD%Yi>=$u:^*JatcdRJZ9<h8k4#1b
@>hVN6 Y#Aim<H\Km9EWS^iFHjd<GGmSXh/qBYZt5&tE1Q5=RaNht8k<l8JB5<w1#CKdt<=&nNw6BpEynlWyh&@
&#^6T6 q&FXbLmF5n$\@j+QR&&P@C$ScAC$CSF<IG!#PhC$cXQiLTaDI8!LF#69*d4XaXC9B:Gyy#^wjtuIp1>4
+wWFnQ eNG1?K>=m\KDCiNym9&61=QNS<6%GP+%H\YpPkGyd@VB%lcGG#\A>KVW$EHlDGNKL6TPGbd8LtDd&CD=
VLV$cc Hn^:lI8cq@t/RYTeMSZbDN<P=1G?ZC/TV$=buSta&lTik6Ty>GK?mJ?Qeih\k!?XYXC\Xc+hGItu%hw!
M/Jl9Q dchje<nG4XulV^h#tXnjHFu^8ducWC:u4LZ^ecwkB::+Y?ST?c6RmanL4N#%<=y%G1Me^P$l*wKd=6KZ
Y&yNmP yW%ME?u#18k<+kCcww*T4@B$:@:>B\y%1u1>PBYQ5Li6Vb?@IISLd>!qp*B\ut>88lX^Z?^CTjS9&*69
DRP4Ae *l!=TN^q4S+e>aP/\QD!$6LhNpN?+BDH=p9?lm*G=XPVJC8w8un?$H#WcQbm@%@eItFui8QBk\hedTD4
mJ$!Z5 c5ekE6H$GpQ1\n$949uCJDii9@H5tW@bAl&QK<aZwQKGJ/:J<88hDXP81DlVXDNpn5S<Cp<nHCR6K6b*
u?&t:a dp/k!NhqFnJ#*J5S?qeeJFWH4hyKAnbei$n9a$#uYGI\q$qbR/p:tdqF4#G+Nuj&w*1Y$8FdW+LI1S&Z
GPDJE% b8J1q/dqbGGlRa=NE$@VThFKmwe6ZGi\/SZ=il*dZl6*YK^NZMG9AcbcjPA^WT+XYh1G46>h?t=wS+MN
65l9Gj =$haK^R+<1$*mu\6uB6B^1QN*h:i$*/^ub&*R=qKhF@5tXyiYy=jZq=j@>PRAmy>$Q!hWPqDDGPaJD6R
KGjS^L njY*!EIG!&VmBwG=Z1<*8WWBceRuck$i8=&>cTB<<?baYGGy!!PC+abGw8qXmKDD>pLCLI<yC:=t$$L?
SLiEV8 L#ehVwVXwJeu%4BkIjuWK4=atXG5L+\9?%Hq4G&KL<$R/m1Ba@9L!4ViaN^GCT4Etwmu>#i==PC5ne#N
@qDmEi #T*P:heP#k%1m&^m$!/44Enqa6MKwJlwtblIDTy!h/ZFJu<WC*AJ?p9nj&L<VI<!hkKq/$I6/nNKQ>^R
j*VR/6 #X&byly6DWG14cd9ZBdC5TDChHKiMypi>\=MeWpVtBJab<lJ6nM>YWTARY#uMZDwmA+NVYHIj&l+Hted
t$=<TD @:T?9Q#>^586q:&Gh=X\/K@Q!!6nTl?!qKmEc=wEc5#4EiytJn%556qMPHcMnF!>whREG?\CP:>@FJnC
&/iAYT tiKE8Mjj\JFVw?@1k^6eW8K#ZyjXtm@j:BI1=c!pt$65F^\aXRSJFwD4b??d!KJeMJ5jM$9PbbKyPb:!
Hh@VBl #akTlCnp5?J&KwLhanpYeXXYNH+yDC8lNyBeY<8a=hVe&8Km6>A<PPnXFEu^8FD?lP:4+pI5D!ypaSJa
ndq*+G lTc&6yBL%hpD8HaAZ$8SeW9\#FCQEE9SqS8%Ncnt%bN#=WMH\HTl9?qEDiFb5:?c@pF=k+JjG&F#F/6Q
HnXtpD puymCLyHBKCdJ+Mhwl:X=lAd1MSjKCL%DE?m>ZN*cb%kBDW^IR4=4K&Z#/E\aPHlGQX+jMqjy#eq$J>p
dtE%\Y yS!kT5q##K<I4h6NJ46p>uS$nIS8QL!B+RaKpP\TFmEwP\&N*u^Ema!jImcKq$SbCcKBX&@+WAd8i9SM
#=5i=q dLTNB!peJy\WPS&FIw6C%nwQKdjdLJJQnDyRSEXiM:i+:XB*FkNVQKZLNFX@VhcYqXpn\WBqyi%L%H8S
iwLDtZ AC?epBjY%qJciSBE4cqyHl\$q>YHE#qq:+JCKBTLy6?+5<mwNyNLBcnnZCBBTlctGItVGJ*BcCRm%6R+
<qa@bX bYZSXPZy\IpVNVZ$L$/ecDy^\q^6!5hILMi5FBp5Jqau5!FTakjNG<n<CEW554w>\<NAFGm?jQ:<PXdF
@PtTL5 Z:>+>iwXlCG&?IJNn/FI#X#ELjKj?>Sh+Gw=T>Db:D!ehL@jI*ua5#aR$y$nucM*dn!<Ch%Mmi\8@Waa
>N^>nZ Y@@w4aiQ^5aC!F=P&\GwkQVGNX<n!!1Mei9=Mpi?=DLbwiJt8:B/1ZA+/Qj9SBYXyAcQ=:R/9aK=c&/K
KKL#a6 d<=q6w8D&+*^hGc:NbNKhF1%beFkwQan^=m!Jn+:$GV6Y!Q41@WPj4&+PKk%D$=MPG5:XZ*tYhbBRpql
tE1u&H YlWtaQ&tmAJ1pW/mwCpl^6AC\j<w<6J!FGh4VmAw/yRWVEXHuIl/wwc?PcE</LRc5ac6aH1h%&R+iK*u
pyi%Hi iTdJR1C&Ccut>l=Xn9Bmi*99FLj#qye*N4=jF+wCL@:6*=TLtlB*iIqN%mFHj8D5ZR$WuI9jlQR>@9ml
tEbk!8 Vt<!aKyBh5d8*:<jC#CwlKyhIy4ijHn#WTIMAPWGKG%V&P5QSY>CZCkAp*8eQnR$Rm*:@PkNZ&PnC*jm
@eSNp% \>&Z+?IP!dd^bdFPy5l$am^jR&JIiZ\Fpk/ikGnMbPc&y%e!Q^6JE6Z<QNKJXCIiSCW@WF6b*>W%!m&C
-A?+DE 0006e0a651800110334 Page 30 of binaries2.zip
k#HBp: kcat/\Blt1uSDu=NSHXYS?dYM5:P?:QCqT+w\!tWl!w/wmqMFmb+XKubhXJZa9AEI\pGNS#86nnWE=lG
Pic@Dj w=q=GZKj5Tu?qN8uVRC%CbBCDacMHI/pA6N=4B6LIn^C/RHhT<lp6jGiI&E?Che=nHNi/BE5R&:qBY#5
wSLHA$ ^59Z@/a?4:bi9Z#=ekQ*Eid9Dw8ESltWKTu=P*WI=W!RbHiB1dFam^<T^!/@d*Vp+WQw<qGwECBY5yG&
u!5qW! \$TGR!CyhQ\+&>*n^/Eu?RXB&5BhPA1TwPTAPu/RHcjAXBFIV4@lVdp#\%X<d5mKcXCIDm4HSLcL?ElL
P!kaJZ SjWwm$a1j+yd:/qI*FyeHR^cK?6b/mmhY?n4P+HPVG=6$i6eJJe/=?\uY::R%LjAY^j1BJpw@atd<wV1
?TmEM/ QX#TBFhhb54VZewMYn#aZdX>DJ#dyaRyYX<8PXS#1/$Q15\%YFlBdFq46>YjEhjGSiDLMSLbY\8bd<q8
/tt^?W R$VW:t:Hy66%XRAN&npk+&5l=pDie?6H5VAPlt=6wL5#^d#9dVi\T<XcVpu^8!X@J@=qWKFYbyhh5aZb
!NcVNK ?@hVLb^qnIS8E1TQE4i@8l&Q6LnI>GKqkw$6Lp$VpyL+J>HWh@Z1iRSKHn54Jq$Pm:%@ETWF\Ac8BSBJ
XeM9uZ IFPWy!upG\qK*Gu&8bSb@IRwP6#u\HhPNdNCQ=KDZb^nT+qjJ$PhmpV>&tK49$^4=VJ8QNZj%Dek@Pc>
?McK*H Yii>ZGb#e/EJcC/e/KM+:h:&Y1LawEk1VIWwaRwSeAST+?cY@B=/qePYQ%X4bXA:#>8Ehm?mpIXpu%P8
mS5VNc 41p&Gw$WISqNS6cIJKhJtH/*j9h/D<+?Wi4y^k1W!Y*CtYQlSZGai9$HPE/ERc>i9SCIa1*+?eb4+Lu%
dWF55J @Qu/?9#%/=MwN6M*TG4bhEKK8$SZ^H^>>/?N:/=*GFT>mJXpAuZ&@pI5HPnwGL$FVBPJ&^M#k?jPPeuD
wdR*Ck e5tBjyhHFB<pBlV!==L911?lEZG^*iWJhAY/IcM#QwF$SkqtFhP:tWIljcjyST=p\!!?u*8wP$d^RXPK
F/8*GA n>IKwt>$V4MC$\Vd*tB6eSqq1haAE8Pb#1ct@965bH@//ciBAj/51S<M:djK5bT!*bbjumBWicR<!>>V
i%lq/P RNZ4MmyEbW#J@>Y4q:XMXtejRim\6hu1tcj>C\Q*?tVbcDS8Z$9ppVE*yAHtq!C>dLNBm6aNBVNCX!<P
#db1NG nnQ1%?>?L+Sd!H9mieG1K/?*Nyc?*!B&\6wP>jCcK*Jc@44%N9w!kFJVWpA$LZqZI*KdN+^\ERH>wWGS
$IE<j4 hKXRCjMV>^e/CXK!9NPJqh5#6/?kT&1*/^D=NwCpuNTeFImCyhh<Q5Hilka@EdY:P$ySL?e#cutR><&I
q^MQqC LT\u^91ATkWjE+kW?B=9EE5#ZElKKZ8GCH5Fyt^/SeSEXljCu\1<TVVc@Xm^KJdDZDC&Yy5G^Q$S/NM6
MjA#/5 EL!=u&d:$GhQ%t45ESTIan5R:ei9MKya15E@JkaB16&q*qm%WP/I6yiqH6>\I4/?ulLKiwMJ4dcFle*y
6jqT/h #4Q%/wS>QcepbFwb$?6*?bTZL#l+bTJk=@1T!cLi4PaNXnLQSFXpLL\BJc+Z#<QXI4:1ai%R*8Nw5>pk
iJ#pby :GKTHCbiVZ+*H@+K44=llZeX:YKtAqR:EldKXSiT@6GPl<<i41!5JGc?8pKaH1\:caTC8q&&R^yj5d/C
l<Yj$n y4/8MYL81XQT1jMN9EdV4cl#aIIF/4y<mC*Hp6jyNM4wiWnF*GEDpcDBB=+1/^W:Ju#uF4IAe!+y4K>k
M1/&:h 1bLVCJ=T8wEdjXw44:DY%%4qqHIqcBcmk#C:t@%ud^FewhwKKT=A*X:6n!tap8%qVXka+InbwDP:qD9$
V9>cNy b>4hqInaCEe*nCyC*u4J=1k*5V@Fq=<ikSwb?p8<F+P^Z1aZ=VKV<=NVdqh#/>hZ4kV6=VyDLZ$FQlhE
1:5%6l iT4P8LHP^*h\1#@<RB@?CDmbq=n^=yai@cjwjYT%5Wt*T#LbjaMApM9+8MCkuMyWACZDm@P6:*#IwNw^
uweZZJ KEkjMIBE#9RbRb1i?Y4\*IZYI<SVE<\8KptiubCicn#j%SXwPH/1+STHVC=&1NE^LQ+4HlWZC>PLpL#i
Sw^Qhm =A8!&=k1q&c+lTy6c#1w$8h<q%a^8m#R9KAE\jV!b%LKiD&jnmbRn&qq?8QYYtN6y:I5*6>EwG+8#CLW
iSQ:w4 6b/F1ETuSl?PJ=Q1%wVmWLHwqq/B:e&K\:iyCBdqtcqB^6RpXp=BFwuFI&%8t/Yi+tBuQ+Ly*Ew9:!$/
p>&&LA YFT!y?j/>YWmYV9!qju=!YG*%N#c?9Xkm+8?VD*iGBT:&LmCbMQpGZQ!P5+k=QF$C$6Lte<bT#&>kY\&
SjmR4/ ?<XPmqpyE^ph/jRS1L1mEkcYFjR^X$^S<L5:mj4&LmXP5p8TV?=En&Vp%5Nu#=/84M#M*LuTY9j^^*ZP
wacLLV B48SIPZNW/C1p4VS%>*h%ZC<5aFABZ<D1A=!NuPb!R4uTVkSRm<&8ZTP816mi/EkncHD<*y>qd=SemtV
VZp1%V ?!uqmJ/R9YI5W$^WhYR\mjqRhiw*ERpH+&EbX^j>AjqabYX6jJyBui*9G+CwV6<>m4n//$NwInk1@KkS
<LE^^D JhY^RDFTSym84ND@dFy>WlEuiTK=ShliN*!u1h/NP>H1R=@XRnchMQ*yy#@udpFu$CbW$u8GqwW<e^8E
Z@<$Gq #5mn666e*m6Z4pTIF8^6wc<N4jX&N:$L^AE\VqN=@SH#@Tk5$Z@DbKuH?bq/i&jw@>=a*94V^5d!@M&S
B=1Nl+ pR=KmAm6IwY4JjC5i*m5iIhdji@6ZRR14#*bJS<FS4hCN!p?i9b5Jj*+MhG$Fa5&Zky=ViIcqJLA+Gqw
aSei@l cP@1>6mJwubC%T/IGqC/dbhbF=VCk*BWuPPBMuKelZaWwlKpHce>Qpq@8Pl>9cV\hB4GX%$4u56tSJFZ
?MV9ki CJyqXh6:V&R#Ch=yc5H<k4Y+&E4SW8W^te#CDL$4bK9X8kBw#<KYh%1u!R5ucm*wu$+4e+GC1eqyRE1Q
:TR8RG Amw1\EHbcDAl?CXMdY/<6GR88j5wyH9^CVa4?lbk+Diu*Ymk&MA:mw!?@<Q*T=Q6jLAC/LbVtlmM#<TS
I%h\&J Dp48m?S9i*8Hl!iZy*w:Lq/5b>6/Sut4/PG%PSm4=:%Il*T&p!WIKe*bY6>aty<c:uC::dLV1CqREqZ/
WTMKY@ Zq\AB/5t48@t8jw8kY4AMaQ\\&i*RlRi\b8tH$<RVZF11I=Tcd5R=AcT\FM/LnW$841/bQybw@*W1XN5
<dVkM& pmY&9h&1R/Y5lpkbV+qCc$b$y9NBE5SmjSSj/a9i&9*BeYZWRWqtFnjXBHXHdVC65JPmJMbZhFZm<bbw
+hmkX4 MEB+Yw54m?5D8NM%ui$<XqqdceZZeHamN:JiBF/lKkiG<iQVMdG*lu9XTYayMN%tcmIwX^5pX=A^Xc<K
kAtiNq K!$#ERL4leVX\C\W61ahi8/98BH%*CWk=*9cWe5hw5@ul>$tKSCMSAuVc8p5cpbe%X$t*p%N>YLqpYC$
%JA#y^ <SAV^e$/p+Gyk&X$Au?bM%hIJ%E$9D\<jJFaLn9:9Vyq:F<eGmyYI/ahGY9SP?>^Sat5L<XGwhDDqchE
Wk:nY\ $=Z$/5VZ4Sek:F#uRunE&yJAp*BFCRtVTR&ueE#9FJuiW=VNEM4AhB#h655Ij4p:I=dNF4NI/<WFJqFK
9\IqdR +5QmQqiD@8&**#y<ZDnW8MBWZbtb?*q%WA&VWttS#cCtl@GmwJ%qAY1XthJabYYq>hm^GKEb5>J@Q>hj
qtZ+b+ Q\&ZKXj+EIhHFLq:?nbNNH*KNFXA=ddkhEm8Npp6!E<61NWc*5BXjdBdkTG@pIpVFB9uJ*CMbHq=W8W/
4V+Mn+ ah4ddyMpi4P/KG1X=h:iH5^@d$Ahj+5T$V?B$al@EHdXC%PI^iZiZtm!a>Q<FTQ/jH&=h\wLW=INTdK=
qK>Y#Y TLqI\&tN&GWG95Wq?e4?4uiK*mp9=&Y&l\>D6%SVNHFqpC*9Rc<LewY<QZ=e4VhICFuXTPtWuXAqWB5@
y6cHX9 <*PMyAc?HCYFBW*ZM1t<:XX=K95<$uFw1L>@*P%C=ByNdN6i!JtyET=9Gt+Z<?<yP^je%cd*CeZZ^+1%
FCk#Sn qbW!6\LG\>dK&6w=?XA6W6*?5?STM&e94tT#/cT%wl&ZbiJaIA:HIG%G*ySy?9Vb6LL?DF!uR%cDRR1$
VNI9IP EKdeX#F8=/B=\9K8+kBq1DciMLK%8bZ4dG%8WZhw8@+hJbuD=Dpq!4RRj5y8NF?Y%=>np@\X\dY%RYRh
:*j=Nj :pWGJM+hMKBVDQ9Lq#C/KCWSTiiHkcnNLe6>@X=#aat8ZDG%cJAZCF^=C:bwb$t@qIq/<?a6w8t4qciQ
A:uil\ $:i95DeqtuyhFEndVLkch=\>K5JWV<N&1NTI58?yS9K4<KiRbPaVjIS6MB1QeQCJ>h/<:i$Tt^YIpS4$
tP&hIh ::*%>q8:YW^T&WFXqZB+En?bk51Kktp?t$tytM:R?!SE6niA<\hYj1?E??1Jy9&=leymGhNJb#98yTn&
P=uI6! nYHcI1T9pJTlyGlmiy1e1W4Vb\>DCJdTFAQVX+@FbIQG=A?$XPqbLee5t/%1I$$>K5*&q:lu*D+!:h/b
<y8CHh k&AL/w<EKqGS\p<bcuP\1EPVp?9Qu+5!A//ADW>NVR%##ET=4<%G6lt%*#>6dj$bJH&>>jL=<\$EZWSw
<S$Z#N t!TEqwtV=V4PaZnq1pmebC^RV6V54C=>1DhJHRVy5/i9Zn%>it?CMqPtcX$#$hStN^qNHCQ^eAPGHH#u
A&B9+Q XWRdWek@%jBQnR$iq+l:tcX<amaiTYK5Qw6y9!SG>5KBeGC:=CA*/Hi>>hdd8#>6eQt:RnDc8I!wb1kb
9^mdpa FB&W:nXm*Y#!VT5Mh$1&N+Ky<e4ma<Ktl?Fa4SR\P+54p&VDa&hDCJw/p@T&T954lB^#pL=ppn5#:E8j
@E+?ae QZ5anWRbXPR%&YSIMtkMhp?RMJYFHK=5#a?9KHQZw4J9NNc4PNhV:5EZuETy!N%&jYu>PblK=qe!tmT#
^TbX#k bHI+lnC1^J$Z^uS>Eqp5WhZtSndb*k8=$R$8LnFFu&?5p*>8c&?uN+qN:yThbt:PFJiYm+6>G4=M\*aZ
9uGe?< uBYqR<&:SWYC5D1>NAyIu:+mc@S+:854k1XMW<yeWbJwaNp^D\<=?HA:/HnnyI>k@VYDmqN>KCTNeh!L
?JTVR@ <WGiS5wSyL!lSua!HGjV&=X*1Qc1*dljkiFBJWFF9X<SM?NEqBHhcZ1=/CD<KZc5\1KRISh4bT=Glm1Q
+QV4$y cT6nKFXam^EtLjcjue:q:y&Xp^n$>XTe+Yp&>hn=Cq\y^R<QR>E\t1tEcmadC<u%ipN>4e%jydj*wj9C
*1AHG< b%wMbd1Tak%&lk*1pSp+TXp?C>N5W1jJLJKqH465<K@4Q&!5W#/nX^4XSkM4/$#hZSjB#>d#beJ$8djD
&Ic@8N DhXp9>R=55#P>6Z4b?^\?X#%XA<!HZyj$H@J^9\5WYaWAcBPYYbYAIbL%XZymw8WS?<dwT\G1D:N45%>
S^<m5y Dbwi1V9TAt@Kn<8QkZ5ZFCS>SFV\<*nn?Wc%AHEKDXdpMtS9&btP^?Q$MmJ?lbNKK9=WlhVQimpN?6$:
b18:bi dC<\^Y!851/aL^kyAc?1#SCLdAi?E$SW9pFhY&#p4<w$VYG16L>M5d=u!cD*%ahAXI1VLD=I$aylJMZ$
lmtAG# Qu9IJ+!FP$%GR:d/?4Q!&jy/Z+tBZPdCjh+#hSyL^buwknI^w&5yN:AMWb@VdEaJZ:t%b8E/Q8dD&u48
lRp>h+ 4lQQl4pHm+6+SuP61d=ia4TB&jQ9JmqwG8u\+R!^S@KNmNM$Y>AijQ/T*Kn\#&/I6<l!y>$wc9jkwpF!
dkPCGc 1^X>nR1y/tL%XTXFJWZ$Zc?y?6*I!MP6b<?!=E*Z94=#/RJaYkhIKdlGb#WeDRR<ML?5jAXMpe1eWnBF
-AQLGB 000f1ff6d6700110334 Page 31 of binaries2.zip
/t&lZT IS?Bd&D5Mp<PAqim=?b5K4EC:SQWb*jWpdmE::H4C<DV+!JBna!LmTRPjMth1yGR\FY6NMT5uR!^kIYJ
ZjHq>t G9DDw<1+eF6bXq^eGWNi8$n\D8Vt59*Y5<q5$uy&Gt&%cX8F=A>RFw5@QQdwMZn/:PGnMNM$ub=PJEM?
4J4ybI Y&*>&XCwW//Z!8YBlaH:><WCt*d@uqKiMNBwnBnThXn$hyqy:D^Sa>&9=TE#QW?NMcwE/lA1j*jFGK?h
eMC!+G hi16?KQ%d5eW1wFVQV&>9b$h5tV*TbBeZabR$y<bdZlShFnSnkFQ!i+cVVn5>1/!EGu4HZYaNA1amI+$
cEt9\$ BR1?&IE6$qTByj@%Z<@@D&n$pnhN4>:=?86Lq!=AZ>?FR1PM4iFkMBkiQh<l5iCkPMjZCH@/c?FaKWl1
*5<YDw <HN^WDVF!j:P$I8+tcQZKbEXyd#\h4NN:D\&/QeJj?yS%wwV&Y^P4VwI&STGhGjp&%h&NyqS+?EIJ8#n
T+JP@P PQJF/cpjhNXYX4M@ZbkdKC=&=la!8aH/m!8bWD%L5YTn6SZ8Wj+9Kh+Wquec=R/GNBENYQV%HcFpM6b*
nVWBj5 >1!^D#RFyp*PE#y6KhSXtK!wDEn%>E1#t6FAE@y6tLEZ9VR^eYRSG+9Q9:<4np*D9kJWIS+/9#!Je1PD
qMSecJ NVLI/w=PLXNp>I14?iTFWj\Fw8SJKiK!P?tNa!wZ1wa/h8\tY<hIl%=+$YL%IK:!6>MS?H4C%LK^<e>@
EAZ^8< &HlGbn::hHZ%c\F1ZZP#$!c:9MFIlN:a$XDw^5$dm6L&?jP+<W/PXND$%/eciJKRSZTC+!Kd\jGYVCRS
yM$a4+ nmmK=@F+IL#hFbe>QyTSePQ48PV*h!pF**91=CCF9bqpQyqJ=M$\bTuJ>IIkMA?b5PB&&F=eZP<^jpTY
I9Quje X!+8lpNNLe1X>^cl@hq*4DPdp88J1PqWPqVFb%CnM/I1TJA?TpTnml=+KB=!XFlC+YR&i!@YJ@M1PEHY
BCGKWP %HTmyq1:9:CpFCEtekelW>jbmd%SZqt5=mqieZYQtY1^uLES1BVq4q>*<@K\VTL!u^YJEY/%RSjN=8Pl
Tpb<\> pyFqIiE4P1n4**H%F<wSFP*YT&\PuCcD9hi1dq*whEcya/VVZT/k=H^G*MZX/MwSCMPd6t>6@Qj@?RBE
#4cEZy jb1>Qjj%%*ekpNZc:LT:ZN:tmZTcp9KHD&>SELX%A=jd#95EV+<4yyiT%EdSRSWNXFnjPByntAPbXnF>
+/W\b% \@SmZ6BqP+^djMBW:E!qiAhDteVH9qNcXAGVmbST8b<&:16NbqY5?XmG$F<lNP9JthamCLcCy+5L>?d8
pbcNwD >\$5ylnQYK$dRY$1wdlW^LqyZG=aiSRNKki4w5Gw*&b^S&Pk>L*?V4E&:DVZ+NGYFlYYFJcCFIXFPpM6
8C5X6R <Rj:m1B^Q!9*t5/Aw5JY5uThmV#uZcl6D+qlJHhHl!T!ZZFuC+@p:l!b+5pX<1JwnFM\nDqT:HT+dWSn
>9&TcB 8$%C\/Dj1VN6dG%$wnTB@=nPbJiJ1bJBITnic&!AT*SX^cn4F^VwH&#>/*@@%@<^@?Dbw@V1/l^D?8VJ
qWQbQ: wFjGdjkIRWw=M9uc4ajQum%BeZ9E+?M5lw5P9+a:=SmJdY>pZAT>M^!XyFCGT:L6Ha?G*^n9>YG68PC6
MWKjI9 6><@HlCC4:C>e>5DTTp8/?\\9QluVFNpw*!D9*R1BaqQ=tpkaK?$X^aZ%<4SMAZBjR6#8j8y^X!58Hyl
hPFBL< aY:BinGb:K\N4cBRNF%QwI/NleiIy:m\<mkiXYZ:pWD:yCkDuMqPl=#kcHY%qk>Y:C@S:hEWCKaY/A\t
LR$H*= +mJ1AA!:SCR>k:cw&>$8NEM=kTZT>q#@+jpQ/$P<+elbJl?4EGGW=Hbj9MnDbWlHWVKmFPd=$uZqKBn>
e4iciG X5T/p5%p5Qa:beMI@h6uIbuiD8/ym:lMI*YME1kcpcWKA$#GYce9a4&RA9$j@6h@@>jl@@GH1#h8jHM:
FjC?N$ >jZZZ\6MZW:RNE$J#15j@+%uE\uXB\<&SpjPN>wXVNX!p6VAMXI*i%P5@cM68b1FLC5VqRX%qI1D*!M\
kn59*B ljHh6X9qcXT56mqmbuN#FC\4i^CySD:?:T#c=/e9LDRE&cBHYkSSQYS$m?8l4X>dZB5nVGh#C>ZFFQ#P
^YuZG* Lnk4R>QJiuiCC+AlT<YbWaIW6yekjeSZ&=mtuBmFw5yEaVL5dCJQ!an8L!\9&dN6i:Eha/Re4=NX<D96
l%mC$h yuy5^LTlImVeKYe/NyQNVcB?n=MqR&!YYTYYQ+ml*6/yKcTn4#pjje*ZT//n+Yc#%CNQe5y!L!?aG/!W
cDFakc CD%+nct#Vw?>k^#9Zb9NJEtl$R=CuHDWmbP+bHil=kN5C\w5@*Q+h*@+\^<inF:%Za6QZBqpTPi<lKnL
4kHdd? qj:^^^@FePK4F<B$cYVEN?KD@#!qBElpi+<*R6hZ>ce#ed=66@4+&:qMCn^N14bZuWd!8RSS:j4D8#>R
:AhPbS MPYC::&MMyCW8=@J?%I^8MuB4%!pD&ZZX4P*X%jVM:huEnPWPRXbh>D9B$>l\#8LPW#K=j1Km<51p:ub
8H^?Yt kj4c/ZVuMRIXYc1@/lQ*/GlmjGWq<Y!F:^a4Tyelut5K1SQhWZNNha%YX<M!pu9&q=VA<GwKCtHqKFI^
dMVMFP MqMJX*T8maSCWB&n8:a#i4c^9P@WN9VH=!?jQ%@GmuE:I$uQeG>:L\bA%:qP4\D/jQ$8i1kPt:9iXE*^
Q>pmF! qI^!w5AW>y491:+P?cXd4+qed4S/SphHJI@NIL^11cce1$wq8B>i<1/?:X@@/*<Hyk?8?q^h9&>6BcSQ
nM$4Dt By#NZ1<*<wwH&X/<iIH4J\<j*wCmtR?>XMyuV8ZVW#lW9<JVDK#e!/bY9=&dI$^^D$$aZ^XV#HM#yC=M
!I&ZAy 4^RhF4KD9Fmi&la#a@8/9hwmc4%Jt&Yck6Y%6dZHE:h9#<#MaBKZL<*RX:BVImPH\=Ga<V%+%N^CJccX
=:GQKR ?mlJ:V^&MVq61\1JPY*Wp//Fmcja=^wjW&mcQ^<@w?#TlCBnlPeAlQAySCwSZC$SYd<J!cahZVb^DZ++
C&JJ9\ 9/yt$Y<ZmdF489:!JeG/QNS&5c$H+:\ZS/b+wye:cc>j9EIh<Iju/?9ZYhQDamXQdHiGbBq9knc+btA1
eCL+ph *Z&Nc!WQP#5i9mJ!^ZF#^NiB=Si:Tcp@eJbVSJn1!$5$:u>6?/@@@Z@?+eHXEZJ^J$?ja$\9me*n#I?M
PdDeAI /TcB?t44&ePdIS>4dVjpP/tm+pCYtHtKXZGemTYj6#w*>#Y/K##N^R=XLKdty<!+MY:SH^dHk+V8FV6W
CL8Lyi 5VCV#t=nK1=a=LK^?6Gu8ce4L>c?udk#IVAq\<Bmp6k<y!nJH+$u?/&^8XTGLG>qdV&/d6q51LN*Jqy9
Kn?PL* GTYLT>bA1nkVIu<KTNth=kXy\:#yHy?a+hZ!e8#C%GmF>aZh%STYCH?1aXDJ6hY:^aDD$QY:p:\mI#!y
W*wB8& pD%SXtZc4\8F*uY5VC^B<?Q@upJWlAqBAE4A9q^j^mE@XBjwnTL**dy%/?awNEnbt6jVq:QbyuD>c?9b
du/hV! 4hAI8h/uZ:iip*q1tIkl&R^C8l$ZNMT8j$pJNQGAKhHWa#>=+HRhBd&Lm+PLk+PSTI4</I<9<D!q$Qet
^LtMhq Ih4Bwnw:IPZ$6FFywFJ/mmRti?j^*N\cwb4lA!:JbC1^M#@hl4YBMG%$dV9W@HwFi6@=HRnKmyC/bn44
mJiDlm E:ueC@D$/:t9d$@en5@\uE^LRE#+T&ZF6Sn?^94WuF^<4DIYPqb:L:iR#eZ1P^K?C4h\q6M&bKtJS!8Q
I!tpnA 6k<Fa4RG=cV+X@GJmhRMcF6R16NYI$cmEKqW\dL\I*JblWIqHS+Vhjjl!ju4<*^CTBXjFyC!#k1cN9Pa
RlP?9V EEVyHp5VlPa#ec:pBe@^Wq!E\Kn6I1Fu6%LYK#@Ed@9V@^48kc%&m!6kD1tZ#>C<*uwYCn>:SCFQ1\8Z
e!wwe@ dLEW:JFqp=/#GXaL$JG*L>Hb#9V<n@@=l+$N\4Vl=MpDi?6cL!*P#m/Kt$9S=M%SwZCPTMVqEiMP?edM
6SkFM$ NqE=SwyPnEewDe\<#5L!\9ltpyH?&DR&m+LSjDKVJ!5<14:Sw\c?KXdaRC%JnH&qlewH**/@9=qL!Y+K
YM!PyS wkDy6/9jj95%E#W?Dw@KD6WjMB/1qPPSci^N>hhYXy:NJa@XV8Mhp1:@dWja>pqIKK8F/m9ctctJMXF9
n5!D%G TCVGYS?ANZ/9DN/J#^C?BaYF&JMBY+G1$9yk$+8>SaT?d4Kqp^nhSP8$LZ<Wm5YJYH@TdZQd&u1?Y$j#
M>B5$A :JW+t@lKuidqWj86q^5m%HXkWN>PV9Tt/MV>/jppnH1:&K/^&adSWu&B@PNtIIAKkk9u8\^C>X!&t:kk
Sby#4n Aju:wtKD1X#1QjP9/@@4j&$\VW<jMP<>&Dw+PJCK6jn<AVJ4\bDjyckLwm/JSdj<$Ha?:D$FuyL6SiYi
lFdBFB R6LXd>jtCFVlWTF%uBTK4&4kt/@/8l4$XZ1HS^YATKuh66^mq4iSSW?V$l4tdkmL\t6+X4>hud9D=yj#
J%^$n< aYEBZH=QbZFqKBqLb4Ibc?Y^&t\8W*<5qF6=tq$JHV5#/4haIG/YZpq*Ywmy>Fjmt>VdEp/ZIVebmW\R
9hY:Id 5nQMW!L1mb1cE%D1LFTaKtRmieCwuWuK%@labwX*+IAyZ!a^mIE!BL\>h>E&=elpJ/B<EuhJ8GG*^RVX
jh9ZL9 e/e5Ld<YJj/Z!%NCiwC4GI:&TYWY?CFKaNq$ItCGAAe^XYk1&*Ye%yRLd$>9B*19EcaQjJ/V$Cc58#Sk
?>$S\B qn\C^>Mib/BFVQtJky:M\&a:y5%E*C6!GZyhblLE$t@9jJ9>Nn5HXDN<Em$mqJqbM@TN=VbJ4/@cVtcT
qyMm5= +uTR5L%b$cMt^1/KZ<#Iq5VnP%uR>G5C>i8JP$#V<i=8MSVn<Rj5FQ6PJ=Lbi/GKa<hCL%=5Ptw9<uBK
uc/#\l *Fh^Jp\@PCVKJmV>J^jH/PHd61#&R$RXy+/kI5waF$DSyL1G6&HMlJJG&Da$bB#TSRT8\<NVp>8a=kem
CSS5R5 nK#%S=mKTLeHA5$wLL^?SRa*n!tqt^8Rb+HLSAPXwtnEyD:jllIJL!@%>mBKE1BKI&LZ:hY4hGLq&c86
ckV*QR /cDL#9<bATyYuamnP1+tGjCGt>>aZ\hQZchlim@NNyZ1ieKI5jT*8HnKV=uj>Nl=w&%HqHRKQZH&y&KX
YVI+^C dZZmD6uG%V9b8T#jm5FRX=!LD6BRj6Pqi9SXGn*QI\YneTHmK:T&?VVB+*5EcI4!qqYRM&H4TK?TCXkn
Mqjh^b !*MHbF&htaEBGKM*p:C?+ZB6eZEItB/44ZW<yTmk6>d>>Pu$$=XE\qdlC?5SJ8G6EuXZjiIdm+1aTJH8
$P9H#1 INe<MV/Bi9WMSmlCBcYF$NHq:ThuNh>+L8iBi=8:\+hm\iVp=QD<>cWN\uSyW6qnM$DGS4ejbHGI%GYa
QG@AWc wmh$cbc@=!ad$p^k<*y4HY+W:lI6X#K/VyjZ&?!NlEcYNumRi&N=j4K*ucj\pTH%dmpD?=Sa$<hp5MXn
*ti%Th N=VTY$jwKkQWp+mPCFTnnh=MT^94p%n$>=\<8djt\8#5mZjjKV*P&nt+RkDBTFZjqWI6!eP\Tk$<&w5C
^VE>QL aTQKTJCY^DS>?5:E*MThP*hY9<$?9wM>$A#jLwVwaBkZEHa\%WjY$pHGX@IJtuKMyB!9\H&C%PQHcZ^j
FX@VI# 9WPw*qu%t<L$n&@uGFHWt9BlLb9AjXX$bjDPpC5QhSIS#>ai?$<4CNa:j96d6EqZEm6l@bt\>ItQyTXu
CqWZm* E6E#FSdj6dF+FJbFpY*tb\b1D5qpLBRw&GQT/bTNNqH@+=E?/YLH!MkW^n:u=/iG4q>HI*6yjkV#R8^G
<jbTWG VZ#1kqJaE\@t>!\94T>Q>YLth*l?jYNh>NMw:J$Wkc:FbDDcbTeq8y/Y=41/I/&64TMn//KY9#R@lYqD
-A#uq$ 000e534cebd00110334 Page 32 of binaries2.zip
pp>I\I bE8T4WQa*liWWc:RQ=>FCFSwYkFVX$5R>+#NMk=:pR$t&>8:94E^Q#L1c&nA6awLq=4&/6:i>aEi4SaA
<q\k1N /RwECE\iVXCXZuutkdApWE?J4k^c+kG<^*GGPnXB1BIK=QXEP6PQY<aw9uWJ&hA8^jT!=88uDS%?qkNW
L^ES6b NHh+jGW6T+HY#CyAuZqMpK/tE*b:uL+5jb@nFR1MktN\KR%RA/1AT:$^pW&Fcu>dP$&l?mbl/tBM^=HC
&L1mtJ 6Ieqm!<lRQX@kmIlaq%XDu\c?&^B*A:DbGHID>64MpymlW%G=%8!&Vw/Ppb/YcF=HV5^1LZ*ZCh\i$e/
Z<WlLQ bMpKWAFyTTq8DEGI\>&D<:edG%P>akl+CBQ/%=iYl+CV!H9+#KcMCY5Z^CA@99B%pKlKZ*=?ta!:mH$y
:pVBIt %uJ9<H\ESWp4#^=6QX5J^aM6b49SXG/T@Lm!=1&41#GdbYR$JWb!y^9$nI:+:ALTC#WHVAY:*9:\8Hy*
IXlQVH ^K?AKu9!\XKD5th^/lRQk$weIwYS*H&XtlAQ9jwV*=Kq#PCEFwE/Ql+MK#LeTmHjw!a#wDkZ/jJDbw6p
6XX/k$ YkYik11Qmcb/V@\&98!cI5$knuq6LmdG41ueS++=5:L!&>4cm!?i9un/>EX9BjGWYE4GN&!y<FGa=Ejp
pH+nZH P=MtY@\JbVSnaaYwSE:/Y%IPHR9Ha1Fa!P>HnGR!&iY?@qlj=%pJb^DhHTP5K+q8>>I<D1Bm:/^*iITk
AH=^1& qnG*bDRCWXTi!nY5W$ca@9Ae>d?Nae#j<*k*y!iK&kh&d\Cy\<dL>+#ylc@>>HYHiknS+Zcqqpl@eu=L
hA1Yum GYVChdiHCa^MayNWy=NpZK861/8DIJIb%$@%FFISV>jJ<yLyNdhi8DTkNi<6&QZPP+iQm=6QuMi+#161
ENAbEn ?AJwTak=aGm\EdPkFCKJ\\bj$c6P%uemNZmddDBlPkj4T%uSiCT1Vny$wV=IWT?ZB#?wc9R^ynQdN=#w
KV9F*u \&aP\R&nCtBZb?#/IL+$jeqN5bK+!hhTKXGJn1ta<yn\m99aj@y6?5ZtC@wKF!91X:A1RyktAKlppJSc
/e4^un aNn!!$<ew!\Xk!c=&L#wn<dD5SAi\yVMGuyljdh8*i#wcL@a$h5:AwdTk:tT?THYPG69c&99/PmW:WwG
>K:Ru8 W/=eT>$9Vpe=imd@?H\Ltitj9?QAGFQjR9*KlNKE8Bb6^\!VnY^wHYN/whZFtp4C:4cJGj:&*m&8WtD+
<DPIIY dPXt>GaaR?9lkE5!t5^tX\5khZthWF5^&?&Ph1!+dw#Rc*#c:LyAyuj@kRN:*6t%/?$QmKuCweKnTpw5
Y#:j1W :Fj8phkXWFt1\?+JmPt!PJk$MZFdwi4e*C1F9\65jbtud\T?GDR:j9mD+?iBcSR6%:R!Cm4KHJm/aJaT
wa4nMF 4pGhHq@:NwXLibw!WVMJLQ@:iiiS*nYJFh?^*>dijEH@=tu8/Y<4Kqciyqja?Cd<6i/\bP#pD5BK\tj=
1J+DT/ BKDG?SIPdwd^htw\F8wL$Zi@y\B=\5m6B?RB5h+AmhDqbdEL9E:l!:A+CWR9h$iw$?up>EWWeeT^/pKN
$kS6%D Ske%yLdJDjcE4:j?%G:dMXX1My+FwCicct11njZK1yQ=mDkhe<Fq6%u1qR6FLAXNbu\iXRit/4Qq/M&d
PH<mTZ D^M5l?I^u#\k%Dkw^uLcIdQT:Li%V&K:I+4BL=j*$8\qT5pPqJL^jjj6h*:N\y&W$ZB8!n=%i$!BRSYd
SAJc=p NIRwuBFP:>*?Cp/QRL$NR*qu:t5WqFAlnEREVd6Wd!wEuu>>?QB^H^6jqPp!cZD$lZmI1G^?$#M#6?MN
mB=#b> SR%pithtbqaXiRaMDuM>IZ!6m%Z+@S:e9p/5PH:4?G*&ST/#p5&6XJD6BW%ljMtq%wa//&*VKF/8JMI?
aRF:Tc @T<yb8L<Je:*yYK\8m&Cym=Q8X*8GH&+#m@p/#>9Ec\dnCePYE^N>mC?+V%lZ+muY/yFFchek!QXbY1k
q4YJT% BH&H:#aABbF%ieS6\#mcEWWww^ctE5q9nXX414jaLGSk:T+F%HNPn+udetC\R*Vd&=i=hW=@u+jQH6//
+\/4ii ijNtNB=pWM*&w!el#BGL?i%\!1%il*6+e4:HLSEjZe&Zbte^1qGn&@P&ALZBu$>pZPhlmDuEqBXRiZ9e
yRS1p1 FWqqlNRFEwLdh^An*b:+muCq#??kSDmu*AHQD@nC?wyW!ZYKiCwE5>ABT$Q^FZl8=nEFTYhtwu4>&A\S
==NMV+ cmc>1pwh=VJ5SMewq?u!?JSGRCm^R4H8d%iI=JRIla=X8WZa!=lG/<@K%uw=RZ?RjmE5XZ^m<SPtZ$Xt
Pc>u$< wI+jmZGLZYD15=hL$8nDl<@RC^Pd?B5dA6J=LJe/iHwBlaLPkaGFkcac&F&&6?W/=YC1n8ZNVPSTZ:=?
yF*Tq9 @iN4!piZS:H?JD4mb!@KRBSQ6dZclFFT6EWXWI@WPV%&hi>KLEqh=JQG&C6@9WYan6!<mX\lHG#B4R4D
XTHbBL WX^YVEc<*6dYI/$St/PNjDG>SdwI$%uGqQ=dyd5WWP%K>K8E9i!%<1mm?lDI=Gb#tSVLq?AFAn$FT^Z4
\c:>tu T<@ZRqw1Hk=$KWWpRqER%j:4\:>8eDGwake=^*kCXWBKFMZ*SED9t$p4^h<eX\4u8FaRH:8Gk$TRh9d+
t8\+8u KephT/\<:j%Q@?utC\\4bP54Kt+SaSZdt$mEc89qYpNI!PmER&h?YiEPn<<RyIN*J6Td%pIVWiww6$9l
MebWE: t<AW<>Q$A=k8RhAZqXklcGY!tTD%kJ5ENhW/hRC+QH>kW<Pw&5n<K8?K1a+Pn<&Pjk:==+8!6dyGkFy6
1*jyjH hEkY:DBKLkE1n<6L>Y!5YembtLhBPi&D4S?=ql<cDa$TW^Qn<baYqqal!#5+N#kacRYteb6EYXT:P?Dy
my#XC5 hDY*#5=i/G@C8MaJB9YhZi@<I\6eAWI^Q!>K9+wBy5?CGSdhBckVEVR%ACb>8A&ijuWHE&9jRu/iRXY8
*>:Nk# XwkV6%*<#tn+>RijI9BqcV6ETTyLmciQH%Q<Rp>mJm+h>wpJV9w6a9h+IbEaH^94Hl*D&/NLCZ9HCNQH
L<PVG9 L&:?68%ymu=d4ILecT=L^qj6<Mn%XtNb4YmTS5j<qq@1#&N*ADhu9tLy\YA*F/WyBT?*?#wIXP=a9?JN
RpVWG> :1YqTYWbkyJK1M/dwMkCVGeHc4TFlZyFhqAA!uVXqJanWlyci4u%E8b:6KMDw:Y!*h*S&h54Y&XR%T#L
$w6Sw\ F!@cHQa#Nk8Fbe%HnkDVI/&Il/*XiTZKaSRmynbR6Hm>%Ve!PlJmu^y5aXShLe&S\eE4pT5E/8BwQehX
:^h?qb ppTbm@jTp>tBj4NPh+BTHb&8kFDhBca1PW%LAJjEBcnBFqZ*IJXnTHuL>!5845*e9p*j+j\w4X!d8#M*
^DNw!m >?*kaDQ@dmL1>mP?:QHD@?GWLI:inmj84PXbTyCtb$R!Tb#TX+q1kc4QR*+WiiuaGBKbLw?T!9BR!6MZ
#AlKe& K:@>:e&uqP9&XqR+e6\QWD5<$%bn9icRFEyPS:GYJip4LPeD\emXK%j+Zee$DjIJBpquq*!WnV=R1kVI
JLKB*d GH8H$Q&!TYCwG4iiAKRLlCubYt:Ckcec=Xy%IXukep^F6M%DbGXyj1VDJ>qp4J!NWAJ$>1#XZNQpqD69
>tj>Gm a5NC>F+yM#uCD+T#ue/cjFnqRL?t>:9Z4@/NnP@GLj4nWVCXRcYu&h5eWXVb\t:JaeiCqW<KiL%Qjy46
+P^V<N H#D4>8#ZHVA*Pb&/kq*$jGB9WDJX<4miVkAcHG\h9MCT<9RTyBaZ?iwTC8DnE?M+9WTIpw8/nj4Q:VXw
6qd1pQ FhH9dG/G<h$JKmYw^QZnFCRySB&uAPmF?tB9J/@&/NGjWeS*GXZYYmbMKjAd/%KnL1Ly6dE^H9H5?Y*d
<=j8ye Tm+Z11ku$<9hAI/R#6K:wd?&@1N>FXIIA\*lKLuWmm1>J<m/&+Qu9M*iqyak!6Ii8&S!iwM!WJ%@AK5:
&GC=jQ Q#\q%yW5ByQhd1+^e@JTZZ$C<6nRHmS1<4%Sk+:h1Z1HZGR%TG4kl$e/&4HWINN4PhyBRbHXKn8h@dh8
Z*B?PJ Wqnh!:$bQ6>eJ$CFAyP#StY1aSlJd95TR6?6nRelCEKPl8kFdXGiaJDjp&RLITe4Id^!Bd$DlPtFAci8
*8n=TQ 6FT*h/@=BMXKi@j?H@>H<c@Jc=Kh>Ri>/4&#Rh#iQIj#P^E9RS!J#DBHb!J^6ek&k@n*<b*X:Pwh:6GR
i+8S\h S&&G#+*:<=BT<HZih>:VeQlD\lSMnTdT1$?bwtAy5T8Qchmp>#PtpE1LK?4ha><p+yjHS9PRh1Ew@\l#
L9KqJR 8+<jXqVWun%di/#CuaQmPym/$qu^WaniDJ&XbWZ:^PbMKB:&Y@dS#+JZeB*1!yXt::tY##>9:wa5qMje
XK+tY1 Q*B@wF?YqPplnInb^Fmu&iY51*MCXb&PJe+GByyPEH!qGEW4L^hRd6?6X1+eP>#6di&W!@4I>94^e9wy
=$!nJK p&BRKRNGJc?*ubqK1K1kN9Ekcw*c8P96:dGSe>=m%@#k\ilIb$jH/CmBm96J?PAQlcLlY#hHP!ATdMP<
deaTwD 1a5\^b%e:\E!9u9*u6l:5Ga9lLn*%4DAVIdwSw!e\+uC%p5ZLq%w=SM6/F/&eG\l$6M+E*amVyHNKpF/
c^6<Ae b@ZdP@THRFT9IPwPtuyeu<tiW@<BQEWbcm!Sj9!WPbyVk61b&&^:mccY<AS>eWaX\T<\@aa?J&N:VeG$
Q6@BG! K*!6i?#SI+1Hun=?i9bR:Y>4c+@X48VE?cHMT1K&w5JGCZDM1muc>R<YlMnn+WTW4G?SJV\DTPq:e*N#
kJBRW> h#Pl&8Y^u$jl?@:>j1piJTVpn=k#R1l4h4u1<FB&WEma%wlZjn@QLSX1GEqaZpHWMy/T+Fq4m$&WEenN
wLHJJj 8hkDiq$8#MVLjdeiwyK*DKLmPBV>F^SR?<S\MdeQyF/R8h*YNk!y4I%uKQ$SymGjB=hkY%n@>Faa>nk$
!e:5#= \mTF>JZVP@9VV$@/B:^tE%y8J*AS:MnBk$iI5q/GqB:CqhnY*D#+NVGQREYTEk\$h:e$j^+MZ9+>ZPwE
8nb%IH Pd%+=K5+^c84cVT9X?@RH\XQY:*IhqVn1%TQQa%X9@1$$Ri6&LHE+@SVEJYL?I>ZAc4wdb1KHPL&<W!e
^<+9:n J!ta1Alq^%k8V>D$&lmQw!Ti4n^Py?54n^*:dYWwl$QFnK1:+qlqjV!dVwYMSWY:m1TRtCeL?*!!L<1*
WXL\AD LK=eEcB?@9uy#%$NhtCKK:Fa1dbnWS/NeG#?$m9PL@qBAqJdDRqJKIR!j5KDelyV1H#pwqKlmhip/1W&
6%\1>W u5T&!*+IJ/NIIN8656#JwC+Na?:iDZi6kFy*wR@G6=w^NjXTk4\<*P8&6W<8<jRL1BwcIchJqIh<S9nl
Xb9I9T \=5WD+@/JepD6&?C^9:5Z@+CwuI1#JATy9nwNJ6dMw8#5>BRFbnPDRyM=\Twu?PXcA/m1j\X>pJ=WPn&
KtI<<h DM4+h>aa%Lt99e&+cJ\u1mLV<bt9<hQD^$>^!Ze5MWPk1tX<w9l1PyYcym@u4/1AKF1eL#8NC/Xu$W$b
#&^AYG ^=TVW5MIE/djkKk#IGb>biY^cVlVLFXpeneyBD=YGW1uW@&!b6?8IwMjS/pR@Wd=5teeahKXTLPZ@qh\
tD!GTT L9Jpk<AW4lJHQjmelIF*%F\Ky9S?4>qjZY$qXK%c4iw?^Zj669*F9bL>8Q6pNEFq!e*TPHcZ%>ZMdChW
YWK9Dj :RD%+ed!XL9NaSFTciJ>W%hH1J9S=?MdF1lm#XQccZP$D!?D&R<inLDI5w!Vq:+w5y6PQ>>>q#^pZ\\w
\TPD&D SD\StH1>qM\RqGS:>\LVE^B6G=l><tTV&!!SIMjNk+P6ABZ^IwHcVa:wMnRpJ&+uKIpjH&itpnNh@bbA
=VGWDl ljF6y5m5Pd=6jMHS<+$i\9TDV*<NVKPwPV^PK#5#c&64/hYJCh:!q$y+RwFhhWL+W>HInw>jyyCAdY@Z
-AwbT$ 000f6ecd36d00110334 Page 33 of binaries2.zip
@SEAVh 6Y85:Q+wLhRb55paH/DGmQi>ZKc6w1K?@6DbSDw=Hc5?6K@wpC$Wu+:6$N!PW@A:?Q9tXuy#ju:/hQQJ
u1Nq#^ p>1tC^#SEk8%/KEyCcthMG%SMK&Dac!^XqhZ%?^ZDT%>b^B4C4WWC8@u&Se6\mt4%Y:uEmD1SXDbdic*
jJ*&iy B1N1:WTaNH\SA!^mE>I8:D6lc8ZVQ*6$=ddiTZFXq@\/yc9#D?mbHIWmL*qw1LJIWEXG5c?nR?Ip&P=$
W#juTt NnGtbH!>hamPclRDZGQYqi!y>6=@<6Qtp:t%VG1C54mY=qapRlR9K1AGQk>*5!:wX^M<JeT:dYS>9$Wt
&m<&F+ R/BPDLa&$%8V4HN*u1nujb@S$*n<<K?PR@SndE^RpDMXHqGb+*H:SND\D:aw5#I+4q!6ah9Ltn%w+BFL
+ePGj6 /a?#598n8KK+pe&^\ueGWm$IkT51w1G!&yq$MypM%S:c6W<nS%u<Qk@1PP\QHtB/tnC6aaZ$AZcYeGqe
@qSpZ+ h+iaqNud\uAe4K84EakTV&5Eu6Xc*DhqIJX@%ECQ5Ny1^nA\GXcdSd\##Ht/%*tJ1te:Pn58&t\tIePC
\1t+AE @=Rbq:>hLuM6W6=TVQ<:&1j+4B@pQjRall4BA=XqP+Xd5l$HMXHLDZTKLNkpPTqE?56jjmKi61J^\$#F
C\jGe\ e/LGZQCPVt5tVH@c#JH6uakk=G>8F1ACX$:5Q8<Pk1kVE^RjmTtReaL*Y+y=aZ%VqKG/VnhVIBWWVCZL
uqFHdw /@85EW5c^\?n/lAkuwuJE6\pieGRbukhPiE9k4^SRp#+A>Pb&&pXCQRFpB@=9l!>h9WS#&A4wIPq8RXS
MYRp^Y wElYXFX$4p=ZXpdV/MDI6WXF??w:?W:FVqDn9!hE+W>Qj$/aI1S6G1AA9?uEmj%cbe^B+GE&A\>kKy9N
+^M=Yq DG9%j6:BMG1N%XyMByMZ%FdV9/D9b4QMQXJub&hIh4AGMNQh1$SClCyS6d1iHmNWF9Kktqp1Y?!w:$H8
*#ZcW> 1!yt6V8EjCG8a4MK9X%m561J1wma\1MTJCS5P#AhcG$m8/A!%YuY9L%4n//GEy&jjyyhY=!dkIS^T#A!
cutMBZ &Cw8&R*t$@ZLq!MwDTdkV:G8GE@MjQ9%%=lLYp*VP/Hq>PtY!=HLSKk9AcyQ?k!c#w&uQnqeBVWI!m:n
<Pej=m Rl!Y\1SF\uV^&$^!IyYK!$Z/MH6V9QCJuWeK^4GB!qh$jhjC%@m:PpDKb?JSdkKtb<u!bnPJ&tMlaDwh
<JhDyP q&6*:WLqIVt>\@=CM1a:4QyV+8pJ<+ttC\JVda*CXJ:46WNm9w=!kmQwR^P1J/1^lK4FhBq^$5neNhiI
#\bCu+ hkt&!V5JV9\IhZak^!XRRZh#HqSCXcyYbwIF1Dn8bVyyN68+/q@PB=F%16CA\<$m:yD*5YAZl$WnCEWd
n#taW\ ?1E6\bbkTPKj&1H=R:BSWwddZ*Y+jA6EuYdh&:9iJp!dbkXSF!hTDGFE\Eu=#KB/yB6B$8*d6<WWCB<W
Mw8+<5 9@%+nkh>X#PyiND%PYF/PV\tT4R?n?e#N%qjI84:^$>=8wlwa&N^d4i>WK*9/y*H/XVEXCSF+?1l^wSc
RN8lQF Y8ITlDk#E9d:ACi?<JlKXJHCIIDP=T+iP%a:ub%J&!w:kYp$HJLL*68q:?TVM6M:*!QpRLw?d@/eMcW+
khJEq@ <RSAScyTnaqR+XSNk1yP5\l^ZBD94cp?RdGTC1hCMBuj/X8ukDRWwlDt=5kIyTMY9dDlbtjhNqZNW4=p
5T+>a\ yBi*WXtK%/TeN?dh$uL%EIdd\XMT$Fdm+/dpQXHK5JHydYu^SyJBCDaRyF:G>Mu5lV4CqB9u=KPd#QTY
yJL*$\ ju6Z\Z=6E<:nde/8bek*1lh@=<mj#1Fj11BK4@KXmVRGu%HNy^\%jj9&*Nh#*</6ywmwL9NyX@jq!&NM
#cmQDB %A/j!*Qih@+#Cu!41u=%!8j:Mm!ML&Ip!qAB/dhbnCK%XFZ++?N=VHj<I*/b:$1nkZe6jQZc&NXSDAM1
<An6XW N%C!<KZa$5nhI56LYe%1Y1/W$/qpJB1JS8%pje?GplBk&aF1QByH15WPFakmV\GwJ\lWZnNWbyIMWGmR
NB$Kdb GXY9C>MFNhW%5LNaeyGhC1BtqceKuPKbt81F&DQiGBK&^:hBhbyNNqZcSh^w#P8CkKlC6WGeFML/566T
lGVn?^ 49^t@tK!na$9=SJi:<D>BilHTp=udGGY#i8FC!B1K@/?@W%P*c=>BRS11daGle$u5#m<NeHtqlk1B4Q9
XSHAC\ VNC9*FFR9e$^Ew>W*pbQljht%8aw&a!$uD+JVMNEy!?:99ThJ%D>H5qDD9Wjn#j/9k\RV%Xq:4W%BlXl
Ru/Enk e<1n%/QPu9n4B?5!KDiC>qi9Z1ZRN#wYu5HN/RTWRbTpKHP5w5Kc\$!V@JE>LZS>amHn4u*%wSm5:*S!
dMHK8N l@&N54j*jGa@mX4CChRVECaJR+4C9euY*m=J/F?dee?\Dq6FSNX1/+q1e!j5LKFy^RE<>dFnJw$j/KSQ
64H^<^ #WMF%1Ju^p65j=XImX=8RuXd5Wj@ymyVPTDhI:Ick/&hl:q6WIBl*<5H\<pEI*9^+p=nQ@\4$ZVk@1#A
HZ@qTR >EK4$$8+<tZ:Zi?>5&9ZP:5KC18dPF?D^FkGwBI>F:pMMVjHa&X*Bmet=1/kh$wb/k!CZu4T1D5Ah/m>
SGRH$b Bq$uQX*hw9dDi&%kK8W#^*>%?NNGH^uj5ZC?:dL=+kXG5??5*btR>FI<#6up#I^/et%etiAeF*58FQXi
t4QdD= 9Vy/>X4Z6dG\e19wHlFWnK!FK81QJZPb%V6bYTPSj!aaI^RuXS/1n:EALKG1Zn:HJVAp9B=Z+&heH?Ju
:6ZNeq AP4wwB:!%Hy*d\e^#TTbuT=Ze:P+cCmwCnNLdKpYW!\<=a8S$GEFVJ\<Zq=c:l%G1$=IQh5A/k/9/nWd
&qP!Dj jp=X>iEqSQF%DRd8yLEINHdTtjPwTNFjAJika9&y?#H&y\CXmQ4p!cZbT?Ay#:Wcm+4iAcypjRXS:!>t
$ayQc$ 5mp!9*jR/F=eXEBYlkZFiBqRSeGHcJ1iTT5n8eVVSKTFk6%8tEi+W:GC/n99h=*/qJKb<=TPZANQX%Q1
4q^tRk <Myc>q6CNYK1<8QaMF>@A/4nMNH=WHWemIc:94^/>hyXm4JG^//J%p&YD>55I8c61Pl:AhP:c6iaW<VV
hQcYDS caSGFQ^&E1Cad5DQ6=uKd^FQ+&htAikJukX6kpGXnCcKP4u&C/LKuT:qStW5=uZK=FCJyJICKLbB&RHc
<5jHQn &wj=^Q#p=Q#<@DJ>M6\4wFD+JZFTe%BB%i8!tj+P1DDAqBbyc*Vq>Xl&hN9c<*XwBL/<Pap=adtV+PWE
uc8bCl XeEW%+<9Ec1Z:5@iH?k#qtmKCNX**u9:ucJCLZek:9PG$S#jYy1Dl<$m\TGkSR@<#lWiS:w>I*l/b+dw
#BWwEQ kRq8bJTSwK8BmDwt/8++MI\+TWJ%5K4SS=l&5V<qhm&Ku9n1uY?@uYnSw#mL+dHd1+^yjuwV6WLw6NMj
Te4TBT DH^JwI=iR?EB/KN#LyREeyu/mw1LPR1p5/5VS1MbQCW\ChSRJ\E1DqqEeZk99*nKbbFGCluJaH*MQ\aG
C+wN#e 9AJSE=d+/ZY$PVlbRIYQIAZ1wK1%81bYGVZdw%FZ!kuVTX#GuS!mH^C=RqeN8<hAqaNwn<9XuI?XY4$%
YPdmGd 64>njdGJW+&K%c@4L@aTyt+H%ql:lSIc=D+/Pmm6+ZiKEECTdYaIDe<1J/&=K6bu%P9LAi4:8>:d6c6p
%6jYpT 9=ljHplqKM&aR@q*d9aJqMyZNqeyR5&tb<V+Le<nVan=BJ/&#n/t:>kHDHwcJFhZh@mc/M8R*j&MAq?Q
^EASTi !FDBW#EQ!1K@GF*JQ9=&IuJT%^DGbk6b*qX/q>^P1NFTZP^AMK@IQ^NL\>hG^\K<AbNJb#LCluhY%Q+&
p+Z>#\ k$A/i&jCYPbeVYa/m?9DBGwWSne=nTNC$@n$uy11Vpenad@H+^#w9/A?4c$+bYiCamV4*y?yb\<t!%!$
8ZlCYy HSlaYBlAEc?/YwFWy%\LKhHwLG$>R!!M$#N<jZJ!cuma>!Zc%SPN1GJkWEEa+I>FBG#:PcktSa<WQNZ8
*T?DVL y#eKke1dPMQDBC1W5jDZ/tl9Q<N/6EJtG+E\NCiWW?WMcTeTaH%=TXHS+bL*h?$1&KM>$VT\MDARw@kD
#h+WXV I=/E4MD$y=?RiV!?p!d\8G\@IjcV$q@hJ6ymnH+%^SZcTMAqiRLhqC<\V%$i?VPe#TSMj*EaY8^pi<Zl
N9kjlh KJ=JYuqE:+YJFyQPE\>TNB8jYZ&MN\4YkFYt#kkyM<IW#%WCXSS9!jR8bMTw1F^S&<9X^6X5$GkMWqJq
I&L1CQ %S!TSiA<DWFJ:FITw4i&1\<Je6/?4u+m*+WL=?4ELEqhnT!bFK$!S:&yYuubbDAXL\wVXXbh/b:C:hQ^
pjc1%p EEwj/lHc/5NMKuED!5G4nTa8LyC9*m=A%DYbh/lX11n!iZt^&Ww=n+TlSVhlPnWM5#+qhAX/&l*K?X4P
i>+^M4 6&CIaWRE1JhtB\bpC1>\=FbZe1nw<Aj9:Ty/q:J\LybF5IhELF%DIE!I@n<@@jSuTn/an1IS5#b^=\yt
8=bWcY HVC+VcATYWYBN8mSJH<ZR+4<>D^mZ\SJH?#i@c9G<%$eI<EX*kitwhGX^?pJq$+jGPjTQTI854%K51JE
AH@AZ9 T^lNa==i@dKLc\=SMhcW!mtdN:e1c89B%:W:*#1%^5leJqqd>qEIKm5+w^tJ5neqw11lpkA%GPkciDK:
lqbqKT eKEX4#SGTR=TJmwJX&e!RZuedyR<HcPaq<dLSn#%a6bE1%4i@MFTa#tj&ZQnaBDG>1H\!t5!myTHG9@8
aeuZ>R LEDWNhXa*4T/Jul!d6paDIWGLAZ\bq$Q6q?^=nF!Wil%Y^SM5ZA5p%96FKG9/DA=8RuBya11K5QlZ:*@
c!kewi HwY?&l48@/1k4mFEay+?kbA+GiDXP&KV<N956^Q5XkuW%V8EcJaH^Mmn<uEljtTMPb#*u!hpn^@i@jd8
Q?yIwl 15a8yVma+4D*^c$dmejyPJuiPAW8<J&I8hmL14jY^JDbGG#=q/NZS:@EJ#mMtWn#Rw%Rh#=4QbdqE5ce
^ZeP5: 5hA+pe&Enl&1V/DWSZEZJM\wudtu+C4t<bPJJFcMb*@/!$>QYq8X%^ta&8&ekXRd\RDJ*wuPmEh&Mle+
^:cuX1 X1Jj4VackPt:&\i@?c+mL!&mJ\=M&<WBQw6J#WE^HL=h@?Y<=kVZijMQemliG/?uQ:Bj^=m!b??buMj6
ne&*5S wiZim*!$WeFWb#BlCRjNYa1C/S&HIM>w58*IqKw$l\?@Z%Tm$!qNjYep#VX&^9<u=hue#QH/GV>5kIt5
$KXc8K FCBq8SG1NMemAWKTYiyDDS>XjQD$<P/*h9>nw&<Wh$yFMpPkQl^>>Dk>e:Vek&bMbQ\dPGkqkWq5T#&k
*SJVq5 k*w6LI\9BWqnRb=WT#Gw+8twCHG!/>19e</qM*JFYXSNk\nWBHQ$X9JYWmF1MwXn^hHk:F@?@j@>!^NY
y!Pc+% y8dZtb\ilbIGW!**5YY=h+NZWqC5!V@$MqaVTIW:44/kHe:qQk8B15njk/V1WnpZEhCXqh?pKtH\Bp>N
mE?m1/ Ew>dMKkaS+StFm/ua4N1+?ZG^wk/mCE\lZAcQH=ub<AdyL?Z#ek#1D6B4cw/ZFKp$^pXVD5n#IVN^huN
\wCm&% &hqNlc1dFAN9k@46c9dPdc!*pTqi=Y9FCY!tSF&TwC4lCXDJwSKt:^Ptl&*uXb/KGh?XEZKw<cP/\P*d
bpS<hc jNw9\Y%\NVeX1I/Byyk#?:J4>M58\XJ/Z/#TZ+V%85tq9plm8#m*GCue4+%p5?ucR:XKZVEcD@GZ+t4T
I<u8Cj 9Wkp^1CKa<Z^<Tj@@8<:REZdC/5LiK*Ph51hN&@^K:t^DIThA6b?:uFZE$+RF%QPqJcWqBqEMWle>*L\
>8FbEH uW!dwlh4ELQ:tAM?!pZpjFbV==S*V8%D1:9Z%$6W4SjHe\E1*HLQ>i@=5Pcjq5tyPqTmataK%WG:!G<I
-AZD9m 00061dfb98000110334 Page 34 of binaries2.zip
apekTi Z#Dh6FPFYK?yPu!+mFj*t9wHtp/aQjFXZpXT6q8&DjCcWkEC1pkJ:/!^M%Wcu9RT?u$TV=V=^J+!8N4+
9#%a!K /iHh8*i@@/p9#H9eYRb%<<XK/NHVhFCuC>:tERikGke4+&<Yp<m@nmp<JYD=JqR<Qcj5JlP1L#K%Guq6
4MwGHC edCtWG9PbNLVqbW!9:@mahEW=%AZ*nR!HW$t<1Atkiqj@9IEey1EcHP#1C&IqcXPR9Vb^58Z##etqWP!
Akp$mk RLX@kQLWV9K$l9JC%kA5KSC:=Sy/hPK!PC9a&WVuBZ=S\SVqCh%SYa#F=Kq1Etp1al/ab<p@AqAqBXTD
N6n^tQ /R!m<J==mIBA9G1yZh\@%w6!wap:k&c=E%PX/NKaVG?AYqYqQ$\@VA\1GYhdR%^kmpQSKX!6XR$\\cGk
@M:H&: ?8*cHj1^ywI1!JEIT%InpqH!yV:=6Ij%KI<D$>&@@1e8qceb<QVy\$hQX%&/p=EJ<JR9J+!F^*qhQ:HN
<E4i=E %G>t^5Mwau#b<TZ!Z5HVhHbN4D#!$RR@V1^y>&8%phX$y4QmWEkJ4=SYdBJEnWamTe\jS\Y1tZ8yYRZV
cPa&\T T/%iAYkiXIb$A^Lu#>jdLW1IR/APIFVG*mH=%D&cQbwCIbJX\MLt&HP#+GaM6#>X+Rhli<5ltwJ%bQNP
5kHGT8 WIt1SyHSeBnL>:I/SlV#K\4BFAyV=DW9V1b8@Rqd5AJVkIw9iBRqaFqIQJI6N8*a&NG#@eWZN@Ny!Kac
dq=/W/ 8=RkilKCFC4NyXK=YWaXBylj!M#c>4Pcjy\jVImMl!WIRLm/8n\hGP&HiKHkKRXJjPKLn@lpGNPHV:PE
Jw?GVq cj#P^Dm^p<AKn+&LN+dcI$%<R/AThd8Jy%%hw>*pYMj+c/!t69*yYkaDQj9*F#yZM>q5Qb6iL8&Kdt&Y
Zu?F>Z 9Ge!FptGIkT4MMcJXCcbc94yL&L5w&pd#W=G6HQ$+aaa!%@15ZHeKt+?e@WBJTZbc1\Y<:+q^TX:NK1t
Xw6A?< EkhLtHVRd$N1$Gp$KNA#S9C1P\5RhVZ11$?t%PN1CRV<HjCyb@LA<GG@umWRFhPEW?%uLQtVKT\kctJR
Yk/GE$ R\JX6@%u>4hKR/nc!pVJ#Etb<l1lmHB!hnETb&5ymC1YCHQdtD:Fy1ER\pDS*YQ=qPh=^TaXMQZ>ttKp
Val/R% 6*i@j>#HiRm>#9hYWWemVCheJ5@Euh9^!>*RZlndcZdVYHyJe=A$J4In^El<Qb\qtuJbeRKD#EbK6:>\
8M$X/D j!Fb*8^Kw9JRjXy6&QHdB>6Q$ZAp#FL5mIRJ/&^tIYZp?jwBeh!Wpp<u?!Y+J/IyynHZIiKk4B*cVX\>
i$K4D% S:TS>AbD55#FkhICat8^WFW1lc&$5Ydw68IPh1aEW*XKXkPt=qG6<=wX9ZcI^ZycYwIB9+<qaPu4%Nhd
$A!mEh eZaMjdii:!Ck>Y^4a&t!Qi>T/a%RLq4+hwAcCwW/P*%&t:nRq\?WDFWc9a&I&p@@u^R5BAqW48I9DyK@
h5YMwn E\eWj%yRh5+!K1m<SQyamZ9JkAa<q8PjemZRS!#F<?Z=^k?kwu:+PLdMqD+bpluCNG+&ai5W/%5a*\&1
CEhYWB JcRbAiuK!nnb*4GAKGJ$pjEhm\4:VX:=Kie!t$m:Y5*ct5G%6Y\1Lbh>yIu!*&Z/dAnnb@i!Kay!p<l4
RS*:an RuH/HmKdQJ%N*e8W<%Xy*tjla1@J^QeqCFQRhG6njWlAC6hYV9@TDBMGXeqpj!#pSFYJRBYZB@BNpE1!
LNbZ#C 1Ih!lVM6XB9hcul4q@$:RZZchQpe%k<lbd@W\ipRNF>GJlH5apG1=?/G&BYaH:/+A%S^DJXDJZ<RP=mh
?*PiE! WBw%5dTVZ4G?BC5Yt+WWmYTQE^>=/Hh^nu\Vb!Bm*Vi*A>Tu9J%GHqZ$XMdCj45++CeKD<CWnC>W%H<B
*auqtN updEmALZ<CtbCeKh*ltQh#eed4\YFlQdTq<t@Sk:mGS>+$#VRBi?=DW!#*ldQH/KPVYiK8XWtl:mK\=C
SBkTdp cV+11?hIVK/$wmGZVcita=FwKByPV5i+DlGPB6Qbi/p>Y1%^9:bGY:&@YuSPiWLZbyN/S^<?&>la8m+t
aH^\FC TKCYDJ/bMHpyJykG?tN>cL>ywj14+VAJpG:QG8Wl*W@@84B<l+NDXCNn?cXP#A*Y%bm&RTXMIZ#DciuW
w%\M@d <QIT!\>AcAeHdha*uw6%ka6u<ykCXZELqWANSdFY/+N\P8@Y/R%1BGa!Xy8=1!nd:J:$C:^ee=eYF!MA
Q:/:Ah NcN5=j?p499taHnFE1umWTuE/bI5u?wdqe4Dq:+98/:/G19ib*XtZ^hE5Qq?MN9iG+<<lPph+1tuhQh^
Bm+T*Y Z8qYI&DwHCu4cuG8NZy<*X$<cact#iQW$/hE>j!\GnBh\^^+^KA^cnRkcKjXcw*^#RR!9jEp^WkW?pdn
BD+8Vq $=B+CCjT!XVJ@9!KlE/uSJye!?t+?bAkuXR$4p#p1$5^c/>nWQ5l#p$=@kClCmuuQWK*ZmjY$*+GcTG4
eiqeBY :G5WRQujw%PDKnLQJBCwLuPi\^JQi996tC+dH5ai?MdT$9W&6>8C>Knu:6LT>?Jk*BudGSMZy*pA%YaT
BSLJXa =6jQT=mhHZk8Z4V^WI!c?Bm4kTqq%@aP%#i4QJ8@PDjHZm#DTc8/t4?aE</WN:&XjRnR\N?Ae+yM%G5m
Q:h8il B#ujmP6BH!maMqHB$=Wd$abTV?VPSN!q*@ZY4<K1/I$aTpwu/P9CT+?#Q@XkW\Q6P9y6GQ$Y5>?dC1c1
WB?HHj =qL\I+*LZtdN^K\%Xt6>LM9h%Gk\Mp$ld%IWDENSeV!8yJTu4jFl#=:C$uKlNYh4:^m>?jDl$u!Q++#R
?ackyT &IAGh&py>$5BK6EWl&SnA+R1!*Mn=6Z\H^Y4GT1wJl%LGGwK^L<Xh^5qm^+RPF8I1pDX&?!%=$Eq/\5u
MI!#9$ RMF#i!@G68tbH&1n>^cT*y/&wb:4h?juJ!hH*BnDq#k>qW#C$4L=JWl9*cS9T>AMwaVXJ6=L>IuSYFND
^pcH:h aWPulJN<Z&ab%Q8Le?V1b6JbFXVt/R8PiTHH<JlDZ?=>^pNhpp&9h\5AS1>h^ekDbVN9:Wb4Jn\tW6S:
Z=TuBZ 9AX%\&e1hX&=e<Yn&@ZYdp5$*#QN^:%yLF/kIERSF#GX98Rwyc8+4MiNuSeKVaYiALyJbwM^FVHYY*Gw
hd=@V\ #!lVGnMNa1K>S1cZTB4qaSnp!Xu59+mFR?nT:SF4L*1dDbk?tJ<TGqe&6L<wT!w$Mcm/dXDShK&y4tE1
Q#A$8l k1d%FttdyTa8C^Pii?B^<=nm*lC!EMZ?N9NwVH:&kZ:bL^!:\>d8uqyi*<B?e\@=V\ip$Qn5Ndy=I=*6
5Xl=9u GDHDlCnZHa+16/nq#qD$IT:!\jZ?chI6!6etjklWlQTEKiW*a\B%>5tF?@jb@C1FXqCXIFXIP9Q+Du*p
<Kd<i& #k!*^n^&Qa:bWnJ=:X4+/yhjpl%8$EACwE6ILCW+S94^^hMyY*qy!=W4y<6*:T4mJTmq##c?4j&w64HD
jJnw=Q :J8:FAu6y&L6Sw\jpl@qD5*c*N!k6qCc!%n^%Nd#TclIqCCMl!L^<VCcQI\1*^DK/JCNmIZDQaB%D@pt
SmD59& qFq>HTM*KQhZ6wwq5^PZ+upCLe@W?>m$RbEXebK+VGB!YG^uXE!N<NBcH6QHtHi=e6<Eac^D9^$1aZPl
R6cw4m hS6W9n%5B9YIY>CAGStbtl#1eWPbuVA>a#undl5c:l$b<cGQ18#&i?lh$HDWVyk/P@&lY\<j*u1GZZPK
EQ@!5P pch\?yniyCdMpGQ6$w!DWMe@@ej@$QkN<ST6uA5LERR8&VY%$p1R1mShjb!>5*yH$jWLl@$iI11DELkY
P>d4nE Jy1mykh:ZHZ?QDCNmyGpF#>89uk/a6HwY1/$/Hc>X!Z>9H!Wu#aVT+6w#uAHhp^eL&BEqRSXPHiC>N6I
a*wpi* wVcaelKm>Wa=qwkHaYkFNcQ+Du+Cal#n#S&6$TyL@IY/AtRni@lpEDAhyZlVKS8aPYSWFyXM^Fci>Eah
bNth^B uED6w%<8lGC!\Yc^1e=WS=Amj?Yl:yyCT4PWHl=w/lDJEbn1edb+5d1Am1T>&5k&FLVn11*iwJee:9bl
a$8PN9 #PX#Kbpk^Zpd%QW:PmlByN\@EAm$1F9p+K$eA1dQ6qnmdt6nGSM+J4&+@1e%GmHHLnY&@<5@@$9nj:/>
/S&An1 KH18V^dA5M#njF=/B?H8+>W:&hZHh%bZX$ZJq\W+@bKl!pKY%9MqLK?j!Du8y!@JQBZ66le9jkSQK\1P
BZXH9% iy6QF8*V?/N9FI@+CSSblAHG:IQaLcb$=>En>1Y\9WLetcQ\LCCht@Mc4Z$Kw8p+wae+q<GE9XW$6wF8
481Pm^ kqI#5:qG8%?Xb6nDPqbk15V4\P&T9qdBqFP:E<SIlCM&tF@iHBh:GVZIb$BV\qT9/wamQdI1m5?<+LT>
LTkR:C +K@$*$!+Bki1NnjuK=Im6dVq^$QXm>h6d8YGKtWqF58bM?jdWb8D*q?k=jQkN1mT9%NkKlS=HlKtE9ab
YdyiWK dY!adjk6Da%jaGHn@@jj94!#KQ4wq:ImbqW^#Z:LR\/46%qdLy$X%WE$R$DW1nPN9m?@SI\EHJNB58YI
9!Sa5X lTu6^^5DtQ:+apSjbG<=1T81<5j#lRbFwTy^P%L?%uEX$=pE/wIa&8=?>JR6:+?RMYPPel$EW%Q$PK$k
8*Np&& cjZb/Y!cD\:FR=YhCI6AX6ReKbKPa@cJcLyyhyqQWDc!u/XiGX8hKJ%*nI=kHhlpBFdAFK8@uP?AVC^u
NDaMA5 y<!LLA!a1\9*q>Cje8?In:A$lhuSG1k=mAFDamdjWZYI5X*qdynNLAcieGAM4SQbmAdwhltIAncYY^eJ
N$hAD? 1c/eRNWDXdedKTLY?V@@QPnFTmTlm5ymKHSVkQwKNceyehHSblM#G$T1^wadBCu>?PLSt8Dyp+E$1?F5
pcYMpa h>!!*\JSNN5\&mJ+!wMJ4AjcTKpyi%Mw><bp=1qR%Fq>Cuj/++6dSWYtw+BWaYmcFenE?GBeju9*y&HM
RR\i?B WNBQ9@tGP&=M$&hQu/:<CElb!kMh?!^ph?a!e&5=b^PCw:=WPn:DIZm$@qB6XIAdlb\/ukR?w=DK:MW5
N&KY#& 644$wtZBdWm+TqIuaRynBtJCY1/9!epH9nmlN\lR/iZ+/ceuC@%PC4ZR$ddqIVZ!KHk%F8K+Q5X#\>Bh
9>HG9$ 5hncFN646D9:?$TTK\1PTqjdYYb/w%N?^8bwW^4lw46n+l4?DqBdYm=j:k+GIRMKwT6IRBC18ML!eAV@
bL1/q> F#aH%!ApuFy55Dj?DnS><QDBF%><p%NA9VAhV/ej*>t8>N:laTS<YBZ/>uFqkMln$XehF$T>&6XNtEck
6cd?ja 8IhYGY#9W&LyK<Kq4/yIW%/m<VPiwy+*k?%^ENP#c@hlCaISn&h8j#NDtF+d9V^/nTB>Sn#><eZtW\k/
:$<ij% 1J$FEj>8*t615q4:a%p$&9D8m58HKk@=McyCd/5XQ5nHwn54/e*NnJp<tSPmKDY\pQSDGeYZIQQkpZnm
5k*LZh &t!46pP=!q^L8NSLQy!BN^tM&Gl+<6Nj@9LVp\Gu5ZA@Bc1TTGcl:WCyIKI1LNLpMVYKt?XRKKVjb:Lm
GJMDQ6 i8&>BaI^l6cAPqI$m>tVN=<#Tl<G/?uqBmQ1Ca^1i+eCc9jq:uGCFX^%BRKlWN@NY:eRKh&<PhLS$R/N
JA$Abe &Zw^Gw^/R?N@@5PDB\D<m<a9$m1w5<luhudGYhCV^=SY%RRX419L%@my@9mb<:+94**==TlG6bMimmml
l5<NEG t\JM&jITymFNWbFG:^FVDV6nyN5#uk<P9&>:9JdtbGutt=t^Me1Mw6k1jmcC*1eyl9RJR+4\q!\\GWu4
:5V&hC RI:MLkd+IT=WY%^SF5aF1LB!*@dbR<J$JaQA*h\KWE?\lqF%DR@cA%Wn4\SC%I&H:cX1hWVIJ4pqu>$I
ahkF#n B+XX*mh@IW^@tt&mKMmIX1hFNFMRaBKmJ@DH4AJT/N&nXR/m&uB8CKi6F\nHu=:M#u1h*l%na5/!9#1b
-AwPdi 00077acdea300110334 Page 35 of binaries2.zip
^=qkD9 4NTL>GJBC<MPb=my=<WAheB@8j6!=HI*c:MI<chd@ISCHZ!1DWP6NnFuTD@@knF><EXn+=hbBhIuC#Qy
uHZN^9 %Y&ijp9lLmYt#NX<8$$MYj8Pj%yq<SGiX#HDmTX<$@FGXIHG+^T$dkLT#Sh^#c/mKup/*/hVpa*jD8wQ
8!^>nF 9&>J5!Wkw4L6JiQ:#TQGqGW/:tZXB8CtwuhHtF1dF1DZIqV$Ekt=?KP!WEKwdc?A+QV@5+IVu+mW#c&6
@B\Ddy bQm\X\Gy:bwVb5bXY&PYYQBY>wkNCyNR%#bJ4A4wEHFMhSQ&!hDZ/c>Bkaqic?=/mm8=NSk\FEZ<5*DC
EeAnN1 QF4ph8Di9K$ie&VPQ5BId<kuV@1B/aCKcbQSWK::?hD9h4ZaIYE8=w!\9#+k=n?Ntd:^!<HLHC\FI&EI
^WkedZ :^G8w1nEZq85T/E@/!FR!b8PZ9&m<hTyL%YZitFqhWiZDR59cR=>H:M@uWdSIe4JyL@^W=V!4@KDid@G
ya%$bC V#>6SN#Kanl5i%@pIwamQY/ZK5Q*tDSnEbCbPEF/&QPai:PQ$:i@?Yae$\/<J9:wt&j\1L!l\cB8Cn^@
cAAiei ?nN>/CPYKpPp$B@WjFVtn*PJN\=Mu<H&VmhYFneXVF94t4!RQqGjE>ZY/l1uuh^EB?X@tE8weWp<WGTT
Mpap&= i1e/L1KA+?DKndq@XtB/*:qjb:KnE/=H6b?!\N461^b1HSuX9ua?Lw/li1KykmtBPm9#?LC\9jj:nPwc
Nw:MwA %N>/?AmkIC1HTtSa:VlcT\d+<tZYWiJdmk^uLJcKlVyD*Gm!5jYXbikq?Z#@?V>@ei%L?@Hnnhj!wC1q
XPMiI5 i/Wwq&YbDpb%Xinj\QbmeN:ZcCHnT+ATW<hG4+&h@@V+Q@qGaZ8jC6NL/WnEXGSQ+P+dTpYeh+DH+@Eb
hD/Wn* ?@8EcXly#yLq@acI?mn@aF\y4TTtFQHi#?Xtqad>dC/:deCDH=WX&?FY?YiQ+EjA$lXYB%:eBKbaHD4B
%S^WeV N>5EYdqJI&MFY+I:QRlXBI1GVidR\+jL!^hXCS8VmX\1G%<!q%4+aAiM4\:!!=%q^l%DS8IV*Cki/8El
lZdH@k JSPdZq#*+=&IJ\Qijk=/5cyERbI+\&h/a&Jl^%F5RPt\1A<PadMKEqH%MncE9Z\!CQy:5iVCRC#TH?Ld
uy\Zcp SJKh:$/=IGmG\9tZ+i+8A4XlSkZ%9qJ$YM\y1&qMWky@IadPh%!/4+&NlkqE>/j@>L594q&>i8Q16Y6n
9FPTBt ZiiQ@?w@?1=%n**#>PptAmR!9dtp!aB46C!APa+GKp<^^BQ?\+jj*?hPa=Z^<e#nd?ndm5D$/w%H%*n^
9hlN89 ktt/tBPhlN!meK#$5$\/H&+qnGWjcTAYk/CIMCXRH#$p91y!l8dYC?hc#:W!We%GLIM#XY6PPLHDd<P8
At$b^^ E!<XH/YW%EX9mPedI&/?J5/ktut%p#A=wh&9$^PwhnT!njRTGw*1/Eq?=M9WQn<=id$hR!*$i?R?Hlkt
tyEc#@ WItb@aC$Z!R#FHBy!uZC^nwp\$=k$XqH*$#@pRW5hTkbK/XH>k=+%WBL5KWb/k86kDWYmT*RM^B4\qRG
B>?aya :K/byh8J^9G^+GWM/?LkVPC&kQVQKN$4a=kC%LX9=%cSymyCXd\9i8%c%:ZS<&jP@P:GDaXd%::+>iHn
4:phL/ ncNn+WeW6SKkSNP%*D&:DDpP9nejC9M5E1GdCP9jL>1uD=MF+QdADEF/?hGn5Wj$=mDZ#N6^!6XN1CPy
XyZN<^ N9mu#huF#R#?C9+\WJZLQm4#eK&^<:iInBIQH!E<\t@Hbj5paRwSKAJXBKiEc9YJGnNlTm<DAWiG>!BA
Y5EJDL Nh5Q:A%\iuDV%?GGek4>MIuaq$LXt9%:>qPTWX>4EttuqIjWa1qZRithGy/euIJLNbn5YIhI>ZGLy=?T
Pn>q+b GRK%9$@M#BDDNbSN8V6<Hd%81X/>bq=iymuSqJZwhByhXbXiW<ZkXnt1>BWwVBBpjw@4<?dQt%6dYkqY
#y+4mb SyW98!:E?qum&!bVBI=WYG!d^m>*B:1/A+E8V@i*k1cd+6bqZm+d\&aeLKW#jD&V<%Qk$#Z/^Z@:=%EG
ueYN\D qN#k6c9@>K81^t6n1AK^+Z&B1?K^8S^dZ1=W<G=yjC\i%9>m*:+KH#Lj6CL9m/NPZW^@?lde%mVMbbT8
RqeRL+ LpPcE#y%WW!9yAQpVP$<QSn?deZFqWS<LCwkbi?dT$eFylhciXYSw%6+W$w6#a\yFqB=WX\&H#kRkPZi
bjKYqT G1EER4K%a!TV9KKV=!TcVyV8KT#XcbV1pB&*8IRBJV:X%!6JK<>iD:5^%YJ#alb#65<5Ml&#5^@#Z&dK
:RDiP8 1@qWQdwB9TMn9d%8l@1P+NZWE6F>L!#ZXYEmBV@\5ayRhWkNL5>ykA1Fhjy^#l5bAE?VMY<uV&<AWXeL
:$JIe5 IJ&amE@E+%%p15i:8#@99m!5:<Kj:@PS><ZFT>myth5SLcGKn#&$<Nk%CtuIWQ:#::=RiHy%>G4ny@@a
ui5<$P GPcwqZ*yW&I=tmuCt<bDuPWpwyjH\4bj@1Jw*!hSA9N&hlZ%=Bt?9WdJ#DX$:<Jld6bqiXM<ue$6Kk4P
8c51y8 5<4>+:S</B@</aTl:JAGtwQS!GlFXh6DPAY&8/\=tq5J^<$+ZHjyW85Fuu+F1F#:Icw/Ji=i<jw@T#4W
paXTq\ 8PCPH@b&hKDAlP$tI!yMQN?8*aQYnAl6VEKWS^\j6*FIJLbmHD%DR$Q6:hD9pP?nVDLdS&=abEt<?G15
W$H@w% Nw4b$XKK1DyG5ElF9^u9CE&=SwMBSb+qFliLhXYC1%Xm*kmwTy:Vy$>DkAV6P+J%eHBlISdDPA9EFSWJ
1@EQ:G 4plpVtm=Z4pM>bu8=5?:j#?u^pu*Ce^Lm&S=8Lt1%l@I5*KRFPYSZQJ@X:@+=>@hiCA\9ZaXki>X4kJ^
yFYp9X i5tC!&8=NZnVMEaD!cJm5*>eK94FL@eXPSKmk@ea9XIeZ^8:^k1lw+GwPu8aV1jT8IQB*h^bXbW>qa/Y
ZcqcRN FSuVe5XHl@!WtWanWZhFSReZn:K1ket5JMJS5^iRCqB^NyQ!D/&&Y1i6Nq5q*K1$E+pPC864qq*?EJ>\
QNiew: h1Q+!1<uq\&lLFha8whj:+J<dmu8!cM8b<GcA**VuQt9@@WmlXH$y=\e#<*&jaRS$nIh6t<IM+EYjwq+
*NQDGb /5dT#Su/a#^CcnTKEjE>apV<ZZFRV1W4j>SV:PbuXLuSn5dAaCwbm@ZHeGw$mEW8uw!MRB4y!6jjDq=y
j?lZ<m Qie>h//=>X#*:^jXPGq8WiB:KRNRF%YtwnZDcTa4A^KT@@K:j&H4i?Qc%dF@1n4?P/+a+HV:W*E5utk1
ES^GXX eqw^9wA*k@@\L\@@R>Euw!9w+V%>Tl>YRFPWHDDl4+^$K!ipe9q8:1Im5+<w!Z=II*>$/JCHM>Nw6PLR
RblE4P McH1RSG!$54JJG+tnnKt5=e8ZRCwpBP4%1Ken=Wa:p?By<4IQDVwJT+FYV+>@5ul\^<e@8BDk<=aA>Xe
*L@$j# 4Y=@ceGiZZ5KTpy$&^pqJL1=:1+@ZQVB+W<?1jnNj<Td+dDiKbd%=TJkXML68JJ*C\y&9di4cNe8LPCW
9^wDpB <bc+lj=eWSG9GY5L/e5ZReNX*iew\L^mCR!?CjPiGuS5aH@=+W=:K\^6BBiHCXXCE?EV@Yw4DqSj8EVl
ytnQiV @4p/ClD^ZFFA9aCJFkE1nQDZ?X4l1q1CH\6jE$V>d@<!?wCCG<ywjQ@$H@@=kTn6QZ&cFS6M8b!wET9K
?QQd19 G\BX@+9DFj6&Y#Dp<BnwQ^c//GQZiFtGP&XK8V<qeqTq%cd!NJP>F!FZ?6ElG*^:KB:&AX$iT?QjhJ>@
hyGR8= @<165Mp:RQ?D=NwI%A8aW!hMVdk>dVSKcDyT5PlXXc9M&GRERJ><<ppX<1#***9uuaLT\5L>EL*cY@a8
Te5*dK ^JALCn=CWbdH6\%/bYc#mu:#+X>?W9ZJd*::G*^iInBh$BbkP@@hk9&F^EIC:B&Y!H=9%^+5+NSV6u8+
eB!d*e +P%h:^Eymcac@9Ja=u?*BE^X=<RNEA*l9^bF\A=ehTJIQ!hRD>b=CXT9w1!CW$ZN*mQi8wPIINk&uTNR
lNFL&K ##YD1e*u9qXAHemD!mNwc&I/u$It6b\WbiGd1%@<:niY***BhaedX*@*V@><A:HG+/iQqe$NSZ6*iy\M
>9GqTZ L@k>Flu*XQ!mR4@9q#=lhJ<?uWHbQb+aG:%<DeZmKK5ImyyVP18!NB?#+ZAtjeH/R&Z@AGjKP%D8R^XS
a=@lPq N6dbjLh%IbeN^<8h*wFLwtq&/RJGRt81haZaqhCJIMpt8b4F8^t4NGbd8i+\w+pQ8*j9*9Z&P\Z99q8/
GjVV%N Z%6#au@lu4i^c4?uSF&p!GN/?HDS:6&@1QkNup<?wV>Z^Pw*5$:G/b&*C*DdyIAla>ni*4YLy:<NXj9\
@NZjb# *!nTpHE8IZVji9866$Fnl4MEGwhcw/Ec9j>1I$><E1l&u<^W@d\P1ELhKlJJDdIK4=DJ+/D\pkL18j##
caJw6H >e?a84nIw@y4T4/cW!@Xnkp=I%@n<X>>&klRRh4@hy+nyt<T/V9dh<X^8C$SD%KklFRtZQZLV>!Ywp@C
j8RYSi K+>9K>N4CS+hlFptmIIa:?YlJpC/KDChldDDwpCW+1aEwmS!y8NeQ$4WX==Nm/FRcMI1:+J$PF1PIAjd
EMJKwQ tJV5K!+XS=$%8t1#LCJjV@AK*6D$9>?CaRT!8MT=Z*%/GMm?W$Aw9998u9&\995LAe88klKhYkbTB5/I
j:\aCd td6*@@L\d@/@@?j@?j@=VXZFL*d9%uEPNFBNj\A\:ht#H=n8E1cZ>i^*Mca/im@5Qu!+BM:&9Zjii886
lCJNQ/ 6@p@kHp&DdSJ!%l&m@I81>WI>%=L1Ny<p6?qtF>C5HXAcCG%6t=D?9Fjk?4>9RL1jh+nb$RZ%de@b/^K
u8laJB %ZhMWck/d@u$X&j?<#ZG<849j9iFWCLnP\d\y4\d\bHXiAR?NY\4?wX:6P1ZDmKu8D9D58nna&FF4CM1
wjKAV< #k*Hh:CW@k:b9N%NbXPEcikR%lYFlR:XXwb+IySLIluq!ku>t*KdtauKXVpR>aVk1c+cTX&>TbL<\jkX
:A*H?k cJZDVutPX^GiBi<jL9@$nKXe4@@\HX^#&XNanabcnc:k9djjK!nb&TY#8aFy!j69:j/H@@J@@iH@*>dZ
Wl+1+q jnX%y&6DA#Ek5B5EtlJnVFQnV1!SWkSnMMb^CC$:DS#u+WnS6ca6=SAC^jW<b/wNE&KPuS+SA&Ttc@Xw
HZ%ekE LRbw>M8eS<JL9$$4FRLj+MP$S+i8/iycI/6Q%*L=N##*!&@9aM@bXh+pkidc>?9991@4#%@>?Z?jNwGh
*P98cE 8tqdj<SXa6AXFIC@l8LEWt1A^?+#GmX$^#1hEZ8K5wR8\THn9yWP<hjlD<D<CKqILTT!VHNnwSM8tR6Y
QL1>d# @KHI4p*8>!Z\MIKGDpCF?QHCPc:hBKdu<j<K@u#$d@>&=w>Lt%8muZS*a$eaW>iqF5lMmb/KDhZ4cPnq
kw9GhM k8c#u5CH%#G@#ibw$E?>H^b!W=NeuedCJqQ>YNkPGhJKGkIynbm1e&iy%CB%pppYHKhwq6R:Tak%dkt^
@^u:At SulAM/hFmPu4L^?h!8YE4yB1yl9k#w%8X/n:9Jnl!J#Q^Hj94+J5^&C4C<YHR%DN>Q$1q94mD9KJk1H?
YSD6$D /4DD=+t4C>tlwN6YDK>@TRpPjIj1ct\Gk&TWjhTyy\HBV1lejF=QHL<@@k&PB%*!8jabJCl4F#N^V&qy
e?/!9w cVGcupHcH!IKw$^Vqe$CwPwLhZ8h49&8KmjeR#mc/>yZm84aN8F+LZ!=ENSDhZXNmKqV659\B$BFB>\X
QQZpA% FJc1kZ1it1DEZTE\JV/hK$m>?MjW=e8Z@<Sy!X$^4:jIN4ww+64YZTJ@^MaDknw?Ft=4Pj*8&DLdcW9d
h/8p6? NT^D^RKVhpNpPW&K^bSKp#p<=nY>\ajZ!Bcb=@YeJERH!E/uSHN\C/&hAmZq9dpFNb^DIbNq$iKnS=8F
-Aq:Xl 0006defa83e00110334 Page 36 of binaries2.zip
at6SYN @k#eCh\l*q4K\chG4EbG?HD:<Ybt?!qi:TYG1pQ6<bFldH\4k@CRQ>:==KPQ#9!VQ@/a98HyE@1#9d$b
=<8X&L 6$GcbQNp/K5bk!VJkW6Z5dD5XDw:i/>i8uwy8I*jm6@@?MhH@G%Gq/h>MW=QpRE:LjcIy<T@t@5k@ILD
>KSEX@ hYVw$@$XqR/uQ<nj@PS^5XHkmj5=?^BXwVIXQPHGk5bJSa$e<QuDHbky9ZV<PBNGLq&=RQ&!e=\lAb4W
AdiqS@ AM85L!$plyD5idC4c+$Zb6Rl#K&NHRZFB9dRW\qc:1bM>j1%c#&@yh\ZMG%4>IcVaKbCKH=iVY6I>SB8
+X&qV# BK@JXBaaQ&5*>jFERycZ1:SDQB+D=#QauDBNm5tmSCHKdd+Ln6d/GNQwc$hjm%LtQGbZb8AZZb1j*=md
t4qMi9 #mKtV8I$*5RiAGQ/=GpVPDnEhCRWdQd%KaQI^Rj?>=@PAKLd+8Zuc@6y1KnIc89I$Fe#%YBXucM*pM<B
G#hp9# 4p5*d6!:&c@hBE?jQ6/k>=9Xdp>:9J&?uMF+GqJ9Eu4VdnYb#ib/9p*eD4ND>u9En>9HmEIN?:!^XAIj
ZpIjw$ 9M@myANc?EYhAKlD1%WXH#WkjuZ<yh?keX:B:6AFyCE=j&:y:8ImnXS5EcZH^mIT9ub%uFLGSSldF!PE
IGWR$d T^1tyD<ML@=qZGiCc&!eZi=9*<X&$nJ&HeLZXX$Kwkjh&FK>Njl4^c\9P^%Ni<6P*&IJwK^&#hBAKCFK
QQ@dYR lpyt85=:FZe*<l4qt9C<W95cV/&>@9J4L@PmY&86QR%GPn?CVC#\@Fapd8BYQNTLGdcyJplF>+hIcbFt
aX8Bt+ ?=C*/e=HmPmPq%=<iGbQyjEIaIwjb/Bm>RKtN/=i9hS*cjVG@b9*\*RZmMe<+h6k5^RuZ##$=R6ky>IJ
!\ea&X >Sdlt/WhWpS:C#*qE:<h:NT*#V<6d4M=GXVp^5JE!Yna=<VBt8D4GE<h*N6\wBhYjKeW4tq?R/bJQV@$
TM59uy 8w\uZim8Ml6L5$PDLPM&\^Wlhw/?ZFiVI:GQBNW<6t?H5N?4uw=>?P=9i@=\:dQQ^5INnYhnk6PVtiWR
>kP?66 nb\kGQPXqbt<a?p^p*%WZc5kai1519E8:JRmM6+RmCe&J+Z/JpdVYSZV&N:cIH*$Y8*SZ?<N4/VH9JAL
/GR@RF J#eA$?Hk/#Tq/EATBbhulEHhbN@dBDG!6I+MNaTwKlEA6X8##:!b\wh%n5yK8b8NKq+JhlwaG:$^i1q9
IS58P4 hDS/<@/>d:cjcBc6QZc#?Htd/%AX&&q^kX=!+:>uM8#=+V8M>jdV9?Pu@Jh*V#9pVZ:5b6&lw>k<6Nk5
^hIWqa Xk998^w6eFP/V1DYI=kyVSS/9a!1W@GjPpXBqh8jlP4T8cWhtDJq*h*bSEeZTXIn1JVn41/8pcFTXBQF
/%!FKi BKe$+kV:t$iQ<DnqD??i:9u\\&9ZqedG4lmQp&WZ6pTcJM\$1hn%bm@Wuq=V@Vi$@CV5NLhGWmQweZG<
:bqpej q=a41IG$RY5!F=a$bwhe*9Ym<$W?uZS@dY%j&Q/@p1%&i&*6!#H+kjHR@qwjVwW/*Ak1iF?cF69eJtN1
Ht^G&W \nL#EP+/DR?HMKcC1d/Xl*M#Q4<%Qee&@iRMyKb!q@C>FibKS&69:&ljd&>+hHV$*9Jn<cD+::=/8KZc
/$Rp%J /!bpPTYGWnd6Ry*i*Q\$M\#yXP6:<@\h:jZ%y@?h+&u!5$@@V#@jE68iWJA=Qak>dS<&Ep5qttwDyLGW
S+K>$$ eZkD9aF*Aq/P4LlRhi!jCFR%J@wE6!qwLJp9?tnyT8K6nm=@&?HDnThuKMqby>X@hYTcFQQY/j\T1<ud
N@>i9Z D:==kJCm<@&\yd+?$Bc?Q1DI@ql!BppX5ty?yH4imA!^hA#it$$>tB&qBQH!A8MEPSR1b6I+KJnyHEN/
dW8qSh X#ZWJZ+1wVSDM\=:w?!D>!dVS?&P%?\AckS?:Q!\T%j8HW#G$q+jDhS/8nu%bW6yl!Bu5EGB$6+?M6^N
D:qSL+ mXLHynC%:dk!Nlahna:hapMcln1%WYHji<WBlWeD&pwA^/19n6+W6$H\>N5j*:5^L\DiLDakEbYIy*y>
bbca\b yhjd&a91%I=/eY@aV:@>u@V$V+a?8*bNJFpi%Dp?wjGHWtjRayAh%PKk$#e\$*jki5NLAGNW>j8QMcmI
!QYR/V caa5FXu1F9Fehb/8PL^&u=#=%b5uV#a&Hn#a6w4=:6d/uhYein:P=&=46LN+?@aMIQ1I#l\S$&8Bi9PB
==+!RF 69B+VJG>aX+h#p9F5:TcIyibA&DDTc?yaa#P5BHS6V84<C$#6DM#@n=!DecIA=kC<nyV4iGYwum19CCW
>ML>F% N1>&6Lb%=hc9AhC>6a+I*E#bmSPTdyeh?aJS=^A*TTD*^d+D^:+tHXRaJWadybVh*TGj*^%Tde!ulMQS
RDaNTb 5dG^$hFFi9*dD%V5cileFHaK=YTqk!yFHBd1:iSHbW#&i6^I*STjwpcVbPP<F#A%!#mP+wY!yYKaudQn
AKb?KL >D9@q?%$+LMQ6@lYGQaHtipRRAW\m:unc*QK8JGDSa#n1Njd$9LPP+EYL:yidEDId9?^a<e$WMFT8Ye&
?=1<EB F!ehYQl9il=*&//eidQ6bPM4nwMH4\PWt>llYBY=4?kt4h@J4c/td>Pk!MNHdKdZ4q$:&&k&i<<P^Lyp
?m9V!b 8a%Yb4D*mphiG\IF^cE9c+&S8bch%dKnZHb%dY%&qXq/IPZmNpa!9WDudLp4dKbLF>mJp?jNyy>l/+:8
/T!dQC 4W*&@hwBNt49a=\nDpt9i>EH#?L6:KT^h\<hlIycy1pRP\FkTwR1<1#+lPh>dMS%pVAacnm\TK>@HTDS
1Yk&lu &Mpj^/EK1cAGE@d*bY@4MD%1&+C%CjnIhk/5kKNPb*F!ZaP<Jhl9e5ntCu$bG&jG/&*>h*aDA<5yah!T
i/TZD! 4ATDjyidn8MEKh+lQ$V:=t4J\kp9Qp>Lm#k!+qVJ=@cjAqDQuTNMN=cwkIqu+lN<ne\8WyZ/!iTdy^yj
6XM9IQ PZn\<C6kQ=8LpCc65y#:w8mm=<BRX:J$<QJIRQwbhS+Pt?Y&<GCZ5@Lp&aH^hG=B>F/yqae96F=jV^y<
L^Kd&w T4q>nN$8+dw/8:c/tp&SJ6R+ShQLTG?HVd:bhG=&mWFhYlJJ:%^YI=<ppq>\9T<*&>H9?yJytuqJSiS!
6^^aWd 9X:!StJJd/?9p\\%GMJ&ptcu&AwwMiC/E>q1l*CmN4NXBpPNnIWDZ4bND\DwCQDHm^Z/@GY8eFkZGR/\
Dlb\G? SRM&eF*5SSFHue%J+VmnR:!>Zm6AYtmI<+>BVC?!P^@+:DG>*@dYY&YT95GJNS5b1wWq4Z$8w^E<4>M8
?IBd4& N&Cu\%:QcN4=ui##H<8DipF\E8JGNKV?I^N#<\V1^6IZd:c>A5:*+J64lApTIhQ&y&klRIn>nm@lh&p/
D6tAHF aj^/YJHNnY>$+h6\dDI>J^/Ay/C=:FSM%1Q/LHlM?Mn:VBHDK/lM\ILFER9nWy5Q!XeaWtSGyH=DL98L
b#eM:/ Lc1n6Zc<P5hWb^!L!FJBkS+\ViFpbmi?Wl+c^%V#ZnJWk+EPL6FWXc<JlcPM*ni5iB%5t^/#Hkwa@9l<
Hwc\@: GaCqkR4?qeNnHP/QRkq:ly6cDC&*CV56RN<LNt\5Dt&1!dEdi%DE*QR$85ljCy45B/\PX4>lWI%GY5*C
c^I@X1 pS8Lpi\T9C*:jby>EPM6V6tJwJ=lWDhXw5p=n1d#tCh6W1ew?!ac1kP<L>cGNK5yEp>59G=<l<46cKe4
b1d?wZ bKcjnVM@/@Y\6>I5N:a%XnS$JNNM$kwwwL$8=GcDWnttS/1bb4W=MaJ%SiNJGtSmWhZD+l*BISX@q+Xe
tN4\=R j4qSp+G4jhu85LjTe#<RY+>KiWElay1WjTKkIuL6:h6WB+Kha8c:^+a4@?l@8$YuwWSZJNqpXB6RbJqi
S&J!I4 :ThNSiB8bddViBEhl8$TjjlCHh<Khd4m\5Jh8IDKMSL6XHJa6I<4AFLLb4/I*cb>e1=QN:pR#nlMJp!1
l5k#YY tV/Hymk5VmbwcD1E+5ueRZJkL%GCh$Kt\i%&+qp=$4tePjiJl8ut5>WMn+k5yW+iQun++MFZ4qMk9dNK
1mt>TM q5w4b4S6>w>@4LCbpyGP$bILXCF?l>=$wLEBpu?Py8l*ldXP:IieliPkZPdXN68aiqqDqac&^#XI1a5@
kMbqlj uj%!ZWCKCZV&q/C&wytGNWSyWNW9:DTJm>%awRwhh#cWC<ZQqV+H%Rc?KAS1P*9i^>nh6Xly<<R6e:<8
jFFL!< XGR&&>^elGSK1$81<RSAKtJRGSEQjFK5\#%!>1%wy^^Q+YQ$9VL>k%d+:5MqSYht^=eii?5SW:l=YDjb
:iDp^& :eMSaGa<c5IFTm5b16QlME5TWVi+ZBB4IYNZpQaXj6&86<=e8ZBl/Z?CNKMT4uTl:*WeQDpJGG/kh6w1
T+E&9J cyy8peIIDi/T//Xb\hl%ttIbR*&a^k1>8cHTZPFQe55ly#KS#RYdk^Pm??M\l>Pc6I\cX5u:nw<u^5jX
lw/N\< ERiX6luJCMV^:Z1?qMqj*q1:N\b*SG^G^VTJ*cwCW&e5q4KKq+kuk81&h*RW6njd/+==ZAJVA1DaIEGS
B:T1i! a\*X&b\&G:@whSbIQ6%5y%\J\iNKDSIi8^Y!@$R:BaRN^qLSdkJ@8/9c!S?d!!B##P^wVGYejMKT!di5
JhWEcV ul:%%8MSHcB96aHhid4QhQm^18c=GeaWA/nbIWqYq\9J%ahDe#SbGy<I8kHWaEj*qT51yy8dj%9e@N5P
YkhX=J WPE4Y%8LmbNwy+eQjIl4K#pKu1yKLWH/E*likJTPbYmAEAeW85J6F9#NhJI%plc1iVS#AAZnmhiu8W^N
L^@^m1 kypt<:VyGkMANmDGd#N:EnWKa&KCJbjqCEAH<61lVQ:!%Vcu&ZZ#5W\!pW!EbZkq\:Fa$1l6/d5<L4h6
KFktjN Y:S<%Jh+e:iC8@=5pp?ddFBbGm#GjE5IemR1D^h*AEB6mXIeM!qtDPN+VEbiiXQLhTYHp&M4#n@+6L:W
B=^h+A b46BpmVIttW=<#V@uJA$+St5Zti866yRP?1qe>$hQ4<uTBQt?\@bZE+HN^wk9jaFl<YP*Bd>uS>Y*Q=I
^IJMu# %%8JK%e$VKuB<w!qdtR&E9/DiL*!^6knMX#$>@\q:QVBA%w6VDKp5h<VRb&nA1h1hP:aDB>Sp=qtANJ=
B@etW8 eWcutNqS:mT?R65nSl$8P5qG<RBXCB*ptKGD:DTu>j5%t6:ttInGK%p<@ppCqBHFG\knV+iBIEH!DVDI
?VlAN1 WyGac8CA/juhnCq?549W1JN$B5Q&DkV4cKkl@uSuF^mQdJ:VRbHLyeptPtLIyHYF&%#LeA^q6P#t?q?Q
CHeK\/ mMhqdL4CZVSGabcedL5mE&:*!5RCb=D&&J!@I44le^*BaJ$Hb/FRReXy+@4F/cMB@=&8hV:iD<+*<lc1
Mi>ln# bt1ad9/@^!1tpCdq\FR#m+tPp?B/D::^^l>\88kSYP1YEAnjIp!*ANLdq%EkcIktCK>jS$m:86wcuZkH
!#?6q! F=tXGI*>$c#6^5TJ+B^Xq%qIi591p*pykltCEI@Gh@CTyYt^XQBM+6Q\IBR&QLDypBWSGL/V#X!FFJ6h
#d1jFV T%um\w>Apau:1AbYhMF6at6yciu&DtQnh=8Aha&\$/1T=\#Q/W1K6*ienVWbLTWqybph6+GwbJ<D+?R+
tj*/RG 9I&86^C1w/1uYm%n644bb86Q%:i\F*>5$BX!EWS&#F?$DI8<%$ma/wwM^tM99MCm%YK%QLRjS$l6NJDp
FL?u?8 hB<Kwyu8^HR^HpWS1eGlmd6Lt%8QcbpnH%WB$XuKj^jnmYkW9Y@nG?@?+WNE>TjcP@!JbeJ^%@i:Fh\A
>E@yQj Hle#whhn%*AB>m!P<<8:$BHJEWy?FnCmVkj:=#I<q=V85y9CiiFm$liHaue%L^ciXSpn6PHBBi=j5YDN
diQ^Q5 Ww+RuWXl9>#$LL6e+96aYcBB:T#Pl1aGw$VdEVQ\IjQ#KFhkK:Y\BV=GbuH%JPYCyh4Y#WDXqRKplV1D
-A$?^P 0006d31a08100110334 Page 37 of binaries2.zip
Dj4$6F BmmC<4!^%GLp4HXdi^^cJ@ndW8FSiV!5<LF+TKHiZP>6=aV&Z>>??^$PujH1ZVw#h!#$P5d$!XP*ZS!h
*?wDqV Xqq*+b\Tu8#6JuF=BLYnk*A>SFQ@!C8KC@=mGCh9y!Q>8GEbG=1aZ<\\Z/VAqJln=yEwQ=/a\%Hkwc/&
PGX#td \+$NJ>>+>>$QqkFVZmd>l/4<DwH4hwypluEM<Dy1@TBn!kC+QSq?M<k/G&NMWJhhtA8/yqkMhT/d>J44
<a@%yW W+LiQPW1KFM\Y%1hZiEChaal^eWA#W\F9VQZW85d\qAB%Ft+5kVyJMdm!SW?DF^IE#*TbiV6mKbw1JKt
5N@1W% Kp6L1wTham%VXGkVy!FQT/14QeItT\*FPFYG9JPmqN^8y>F+Ln#n#<G4d65W1FdBJ>6<a%VStPiIPKDJ
%H$6Lh aJ8l6bj^@jQXn#<Y*TM\NWh>9d*ilQYI#LHabVd^Mj^tCeVbwmIJuG<N5@?i?\&Aikd?ln!puR1aknum
S:\Vq> 8q^G^bV=%pcRpnLeF=&a^8$ePu<mK&XEy\uWmbG=PRd%=B9iqyb*@+Ca@9RV4d?\wY:pXtit+MX<MIY%
ej4EP# #Ql%YqZ<@TDPJ/RmQ1knpNA5QEN?e&+8i9V%BdZ9G:HdA&LMM?WHb>NIlmcaDGi!QMI\?j::q*E&Ke*h
ARcZRh JJSY*BBD+$6dbP*y&VSnt1ZEcAZeL//F$$JFG5hiaqP^BM4HE=6>Me?&k/GK?4Rakq?^pe*uTd^pn$i$
GBH!HC HE1Lu?N=V/JlNlwE%ddSIm!6EAhSLKIK!eBuI?K?cLiXXtXW!\hMVce9*1THLD:<?5cNaj=B:XbMZ+PL
lhhl*/ J#A!BlnwR=DL<T$Tq/q%9<hcdh9NNIWIKnnknk/QH/YGtFkWMB$SJAJ^$pAKBq5:i*58n9d%S!jtM\!1
Yci5hR mmu&<nQV<>PAcYJ&dt=minwGwL+mN:#^4nc\K%JjQFXhyX!a?wJn9H!KNB&JbG#RL^ZmBJ!?LbptE6b?
te4WkI !>FyllRReJh:^+Vu:T1HuN<i$@yJTAFBleyMmmEXb/9b*N^Gu1GWu!a>4YLKB*dw\MYb@h&IEw+lq%pT
P!tcaD GZYK&FDSAaPh&4R?WuElkCa/4aZX%h^#iA^&Y5!DZkT1Swl9=B\ynwpR%D8ecV$8LC\8*qSLqCj=yDlV
ALtMkm cK=98ZiQQ6=/8D\/&4t6qp>p@uY+pNnK6$qXYbp=KQIpbD&pwj\n8%@kPjLn^<<hQ>+i/9AeI+$*IlaF
P1kbh9 VEu&cZ+pmN>Q>$jQi^h:^\nW^W^imYbycXHkmmZQ^DT+*>uyXLC6:iDllue@ZKdnF+KS8+MdpDJBTPXi
\jLtWP L$NKGVBT:QnMbKhIYRb&N>*j@HJ@dtN4qw1RmMSJ:#k&<mFV$H9JGFe+t%%dy\W+HkVF+bYX:AMpjF*R
%qGKq> KAjZ^TqQq5i=h!VAbKd#pCNFbVpRAVPqNc&WKn^Bqty#<yqwHKPjXM\i>iq&$b=1$iZbZRY?F*:=IpCL
Mkd?E! Nl&KT!CR:Cw&^6WtIE=&Gwnw?ip&GK%piiaa@VGu6&Zt?4i@JV6>59X\6LQVF<4uZQB*lCkQ&iZ8K+N$
1JKu*1 mk*@cb&5$uRe1*tBFn/P9<C!n^:QEZK?XkKXMa%*?&%eF#t<:@V?:8ywZ^lAne@#tjnTWtayk/5wm@Me
<ulTYG W8MVGFLn5+uB44bZIQu><B4QM1^tX?<\e^I^cHQZRXly:Qw+:TLGBp=XFKChFmCt8htwc&>\t41?CIDj
mtJ@JL =El!9!Etq$9qL?4D?iPb:B1j#E=m=nXE8?a$4kTih$:R9XJJ5=T9WLNc&y6Xl\Zu@bJi:5PdA4KpTFJd
#9n!6S Q5F=VKhd#JlX/uRAnaFDGtB1E<XMy1cpGMh5C&m!Yy&^LnSalJ$Y<kA8Q?=y+T:J+k#6TIk#alT6*H:/
C:kZEi Z:?/#^?VAJD#td\=a=GdY*5jp=?&tjRXby8aZRqcCXG$%J4hL^G1L:H1I!+>I\8Rt#k8S?KR^R::dZ6\
+lRIRq w<M5i\M>F/>ilZ5HCdEtS8du:!+5*F&/t>tk8uVntV^yimISkiLp+B9@@PG%<RjZHp#i^wWqIuyAdpmG
8@FbkE FE>pcL8abkJ^>8TWGe&$wKAS*i1E@?ZZy*P+RRySeGyRL8>WW>=!9h$8tVVZm>Z5ujW%!JWT+!R*M$+J
p:Q^?% LaAKtVP%w*a/*%@&jPH8+bHi4SEbV*>\l\d@JI5MQC>44LdlqmF:#jdKI4keFa@b*p15^#^Qh^k1la+C
+wM%\h >M>mNL:EGFjnKXcl*Fy+<qS!!M&?j^q=LB/:uiq@#Lt8XH@/h@h8M1aNqR:JbuYGH8euqnch#d:PZ4bV
^Yp!>I G>a%5w5@&ZbbSVpNq41dWAWu@AK8P*q1*NZX%Vc=YpbtCbjHA><1Ab=t8dHu^9L!%@?BkpNlBXAFa^&b
q\d!CW tL&:AQbK=ijYBy?N+%dN>N#e>MSRyP$pFDV@DMH!>%CLVlKwc&6*91N1=n68DYIDu<wcJk\<&/kuWA?M
b+NiC$ ydNV\cP9V?BWWk:H4JP?F?6nam/yZC?HHYXi$Stp6WR<K%kR<uuna?P*cYByBS<>q>8B/hbhdY=CM>MX
l!#N+F acadm$FhRRFktmBDVTTF+#YW!5k1%5h^M&/FtwI1TB4ALDq&#HNB6CB&q=a\1AZ5dPlRnu$9?Y!5L$We
ih\^Zj *ybdL@cN>w%G=#JETVD%?T&GJtP1Q@*&y@j8*S96XK^FpEmZ+FSSmFjPM!NBb:QT?h=F^l<\Lbce\j:l
JicSK1 dlRIXKWT<E$Nt!1pT1nl:1ub:ebte$tyyw?!S+KM1!H\MbP5IKa?Jc\E?@8nR^MVkP4Gq1B4ZJ\GT=&n
%9>G^p =BeXYmaGP$+/ZutnnWCFq*qtXdC?41yYPuA>TS%jwZabnk\M6FZT!%EBj4Y@8ZqmdtEBe6e%CJShe4tQ
dZJ^qH @CXCcw+MT1cI/B%kI*GNjYy!uNiXa\<wyX%qeeYXZN:=41>@5nTd&wHy!tS&RVNVHbSSEaEw=d%w1TXE
F:S@WS e>X*m?$$n1jKnR$mnG$i\$/\Pw6WXX$5&pIFhCCHdX*!9ik$1e*8EK=*5@Nt@?i*d6&@j@@#?@>FyK**
tbwMXD XV5%%Re8*wAA=*Pa/jFGIwEank+nZbi4tTSqGH?LZq>whKQi/qEWuqIBSd$EABWkQZ?8G$H%%NRk^YtJ
>EI=!? C1lppM\&lQTD9^AZ$5N:PHKM6R/APwTk#6*hEqZKF1XJe#V/kMKmE=FVB\<eBFD@?eQjD%\jV<%pmWJ>
Y>Q=?T hSZTF&\N<1CJ<LwDZSGm*ZcRwb4QSmLNS@9J^tkwh>Jh:w#SKJp5/W&BhJepJ+Wd#T:\5mu#!AyRMb:m
PiHKuj q?p\aHEuPj@T$y&bQKdkw6Xwt8tHR14MG$FGM%!<Wi$WIyHTN@d=N^#T+1M>Ac>jqDJQwX:w/D+8@CpW
FXZtkR yKZQahMEX>AKu+5Z+&/FwWVEW?Ttc%WQXCd8**<w4l@@^8?FuXdaVce:+TZ&!iam*Hk1RYX+yQKe?#\a
FBV8pK QEEWpd&>uE?Xq8pp1>5jXJA%%8mESMm1/b4W%HnPEbp@$w4Y&K4BVutJ$XBWbCmT#LL5<QbeZiaE>16i
A+PWYK JWDWK<Ekmb+D1G4d:?>d/+9#WJ*TRM5$iN?w$tm8PNCI1L=J56JjpI=VPu%:pyY@a$mCnN$+=MaHSNFR
ZXQQe# bV*Wy>/AI69@bXw6Viht8!SJRb6MPjRtM<SX6/VM5ATeGqSVHRM$ma@#9iQpWkFW/l4uNnS%qQYq>cXQ
<jB=?K qldETS$yJDCt<HjiBa:V4EAakKwKt+Rm/:W=qWn$%niQPKRl%ej&E:W=&J&A\9:+C+?%^HT#cZhycYqh
N=I6Ic i\akKmuB@hF1#u8*L&\?*qaV&P%9pWH*d\>@?JGwhH@<<j5jHuJw#bk1K88Sa5Nt5hKlHNmy?@:QSBB+
>%+i<& E!ZbTQGW<c<8Mllyqh^yJYblYe6>+V@jCDiEAFdQMX8%eL8+daQdXAjMewP*=\>MYkb&Gkkw4V=@tQY6
!thC+A ?1QJ/RY6Rd?%pbtjub?ANApNhTIc^P/!GW!%4i*N\i5^#V\t$V!V*P^l51RIM1tlyaaDb4*JG\k+!4%V
8T/#mJ 8LdQM!hD56+BKXE/CXtMKb#PytR=mVc9dR?uW>aC9R<:ByEa<>6S&p6c^TSj5bP$cYNyT6TqK$\XVQQp
/jqiq5 $d$FGE/bLYp1uW#!e4jF=k@Gp6><<?mZ<:9\eRLZl!C=QL@>bMi@1V*lW1P^Gu^i=yin*E?jj9Q###>1
ZI8ned F<L/Qh5ybM<P5>pl8+u=y:%I\4WtY?9Du*@??$<@@j#6JaFyJ?P@9^w*Bh^PKqZ!F&Q1wXIVk*A<hMT&
ED?b+\ S=VLSSIj#PQyD9niQ!<D1M6jZR#k<IT1m^9EDHlcYCu^=T+6#E@\+Nu$^ET@D$G6PQBKI+A/ML=VNa@b
b!HS1K GjC#RaR$AwlG\E=n5dDXbQb/HZb:hJyZ<ZML8Rt@XI/hRK^L!<QythYI\#en!GQbTlMYAEV9I$MhS/H+
@nl9mE FLnXGX#<*lAMLP911h9G^5cPSAt=5en##pPGXKmu5WYp:$$QyW6w+d:E=wHd=MGDS#9t:AW/<\ny8ZQu
C+*4VT XXB*NA@wYAc!EmkmNy?>F?CnH*@?/iej@$d&?iMQbKW@AKden5KSBLhQ6I5SCKQ#+k>wy#@@>Q%N^BRX
91b5+K @Nn*:pNT8/Nkypj^kF:G8miQ1wdybmdadPP=M$PSAce5hD1y\t!84G>5iijn9!^@>YpQeYTlwj4Bpj6J
^<tRNN c&X1SVZV9/Nm<V^/*=GJpeVETDVwh%cc>iaD=wMu&\bm1kV+$Dk4hAu?\REEe+A\Ha#FFNqWbnibAhI=
4!1<+u t9ddkuA=JJZ:+BcITAYFbbA>4cb>>5ncDHX+ihkl+cSE5+H&FhHNa@h^JahhnkY^A/CG$\%^!JQPu:FS
*a@k&R KVdllK#ZFIkknT@?w4G$%YbE$q/dy!MXT#>+6QNpqJwE5+pEk+1D#=9dP<!W@+\\<@dtn9KTipl@@@qu
i:cH6@ BBWXcu:++j999*?I@*$4:BVyR>%$%9apR!5TX8h:Q+Bb\\N?aE^dY^Z&9ZYlWJ&HuGZ@yV:p^XP<*wAK
!Yd@Ie 1t6SRL1b/jdaJGGuPwutu+y$8Cl441?9D@!YPe>RJeZZ!k#/EFj:w>Qj@WQNjViY\FCSVCp^QDI<MS#6
XhyNPA D:dKFZ1#8iL\!c=BwXERT/KbWtE+QW6&KucZ<I4+bel4VjX>W\5=Zwyd!E*:JWe$uS+$FldwA$uAMCb:
1mIM?* $&5#1k+eaG/ShNT1\LwTCjEjWCtD4c5=4E<ZNX1jhS=K#S91CyR:8EW\F+RdB5My44BT!bT&pVb6ha&u
TGGlBX a!mXj9DNM+=*P#MhmR\qEth+!\<9H6Vj5RMX%#DhacldQ\q*C?d=@Z<>jQn6\??@li64Ni@%P6&?@T=%
p$:lE> Fa:Ciii*iA@<@PQDm+nwi#/j#QPCIcRNHl+iu94<<%8jZ:*E\8I1qc?6QcN8Ya=+ePmZA?18R6^MLwI*
%dYeJ/ L+1=%H4BiaaMdMku!dy>@hGy9@>D:hB9Lh&>m!&H?HD:MHIXSwPhAK4iZNHa>n/6?4KbpwAmeYCJdVR8
y*Vjp/ cGLJRVeiBy4D5SWchCBHPiE5:$1qW$+5ZHHTM/*aP:NIiLXG6e^$5QdFe1qeX%A&^nSKWQw!w6mPJNhL
M+1?Yj a$&mQ+mdHtCwW<JMIb\mi>&5C?+KQaVV9B#eEa<dta*AVkjBh5i\plS*:6bKhA^=4IiG#mCw=*F%E^i5
PD@\1$ ph+XJ%TRpm=?mCG%^Xq+pwLVV+<aWQn:A!1D*j<chTb8+B8S>=IeAS?Ed#=9REmh*15RWAHTG/mE/@MF
&BN5w# bCej:=B/!QDuE!ld<M*NT%i9pymRC14k*CJMiVmjaeX><%$I15:M^8wRtQycjY+I15&KL$k$/%N1/p9M
dV15Q? TIA1=L=\B$XHJmcmHFV%=pd\9m#bhypIIjp$dWy5w@GXmmw+Zt6Cc%!kLcm6naZbaLp*tWZQ1&@AjamX
-An+w> 000048cd04900110334 Page 38 of binaries2.zip
<Yq%t5 yG\jR$TSqnI*Eh^dL4%a?%1#SFPm!PcBLHN$eADiX/^TcYJn:Gq#5%t%qqtk&a#bER5WqtY?5LBT9KD$
6YcARY hPPaR%&wa^Dm9hLZN*49/?X99%/?N#w&Gk+4k^&S6%ldk4YMZ/Yh*CapEpX?*nwG6cVc=4=$H/Y*j6LT
9cuV:l wwe5:uQ#Imuew1dVyW65y+@hQyjC5^NQN+q4A/9n9l6jj*$Q4dTVYaDbVnMIcZSmmnC>j@Qtnc8ZtDcJ
/ymNZZ 9T?^+&FH96%FYSQ6ZEk+@<IeLyK8HA&%94:FF<BcBnu%BPi49$9SamyT$JM<V&aYRtw@5wwPI/kPB4YL
Y6eq#V DJXRHSiccnk8w6pyiPYIZ>1qN*YPyXbIuR8>=tJm4#&T#k+=!!W/cq6J?/BAZX9>k5m:E$+JIY&iC8yi
j&X9t@ ^Ba@:ew>?wcwRbH9qXcLidqDW!ZbaJI<AuYBc>Q=EK=k&#9#Xk1ahu8cckCXGmESkN+J/pN<cbFZWFGW
uJSMKk TMib6:4Q1D1I4::K8L/1\uywj+&#Cwy>t/>QqKQ\+6?/hY6$hBSbRD8S=\M6SHpQwF&pZDjnhCF@dMnn
^Z?R!h PZVISyykN4jm\y@dmyLXQtdWb$dMPGwCI5M>Q89>t#e8*d^/FcY6$XISSCbTk:#Zy+y^Ywt@\!mByTK5
?lXD^u /H#N>6M6QV$>b=GLAMAME><49wqAVGXR$S^\S+yAlRI&m4kGFRh1T#h$WbcE9J=$cE%N9ZS5y??qKZm#
eA&6cV N=^MW<iAM6a=9?Tdtl%!R=/WFN6R>4P41C!?6yd1&1jVT?XHk>teT&<CI%/bjMB:PGmu*P>qEhRhwQLQ
D*qI=j #e?5dFDYC=mYi=>SWkl%h*91ckDXttM?Ww5kEqhM?6FQWiRS$twC%XhXXM<*Mc^%XVYqJXDQ&N!hw&Dd
@PyT^l w>G^9nDT%+X^\B@y4kSdl/?%F%EDC*P:WDLc=TK4\qLKcIP:CSW&NXF=y=YGW=8EEG9$Fq+AJ\B/WYQH
EXi/MB 6:Gl^4H9EHV9pQ1!IM5PYC4<:&JABVM>Hiny\RLX=$e\/T?</XL/EhT5$H/mFcuFiGJ+GL/M1Qa4Q4P?
/NahG< wKDTQ=DT1ltTLZp&umdH^\jB>V1<+ZEpMy<SC^aVF99u5$NP4GdE5J@bNI/aA1LXW9tL=jbkE9!$SjJP
n^>\Vu WtbE:PpIKq\<WLwqh8Swey8>A&XBKBkqmFqGZPmNqFk/L%!VGwq*l#^NhVY:n=DKmJ5tCF%\P#inFJ?9
CiPNe# E%?F4k/B1lC*@AY1hZX%66L1EtVSh%NY1RRXyl#eThXKVLChGCplqkcSlNTFFtZBqwjNmatwH#$$<6:n
ctMA\@ NmIPiu4R6^>mMti<WH<i@pLEDRSWVK%+CnM!EqJpnj!XdmI!XJ%Wdm+*P!Ce64#h?<EHH&Q91k95M^#G
IjnYZD XpHiWuQ<&9E!GWVW>u+G>jQ?Vtw?6MXmG1b1QFZ6FK:*paQD/#$dH8jbVFI4*ykQ%4+?FZYY1%ccnnqM
VZyKB/ *9VMF>u$wK$Ik5Qi@tq5Hp=L=YGtiEkLP%&bVFPiyY:IWhQ*:yw/++9/RBwuS&daw6Q6epRulJETy9FM
8*#GFY QNEhcmJ?X>aDP8S!uTAT+>dP96E?FA^GqqSph6NR#h51\6yENGcRQdNa6Ewi1GuDC/+pw1qDK@Y=k&l>
VH8w9X ?*Hq<Hq5VFcnd4ljWXmFuEReEXJpmc/lG<*JCR=!>RaEG:Ncwn4>yNnc%<5Z\+&/>BaJL#BT1GacY#:+
/jydbJ GGWN:u?MCmaK6Z/\ZRCwlmQS&QR$X@i$T4=$F=\9GC1=*@+w=EpX>Y$^=4iiFL1IVBP1aZy>QHa>El=q
m$FC<e @q%1A<*miP?Jw>GwWm=yk:&KbD1duppu@eaZhbLpSu=jAHYwZB4L4u+u:QVS%A4*mGc^Pdmpdi85*@%T
6b+i%P HjJF!5kb:mJq\QZ8lS9ZF<%L1/buANNFqB%8+pHbPq9XwSMiD:GN>@jh9Hu%J8tS8Fq9K@lLW!XWR=R5
diZ=8& Xhpk$!wS<6La#LQJaLk&c$tX$Yk#E864J@FJp1wMmt^TWwMH<WVYC>cNZeFY^c8KFAGtVj9Bi^\nVTkW
G<ueSD EMydw11SCR>X1M>*>h:ZpGGNZ4*c&*8&E$>pHWdC6NJ5h6T*1I*<=iWdw!SF!=km1teB%PtycYbY=XY!
<>V\dM ieB$BA$X@@SBLh&wTVpJdt8l>eW5DKnklHTlD&+@8C&1nAZMpWbP9B=5qty>c8+!Ki94AjW81d\eEI&p
HXa/q% %^dI*wM9iqi?Y$W8Td^YHkkZmmSYlCn^DcKl*lWH1CqmAmaYye#G6B8!RK8T*Kp^BbkC1QPCEB<96LFk
d8DQK% EQKT/K&dN&<mn/PQ?EFbi91Zyp1+I9Y/l#JkJ/RwXXclXFNm4C/^qJVT<T#LF!5RK%EGuqRQIP4l<a1k
a>LK/@ ?i*EYN4=uqAywSFQNNQhNjRLpjc:%i9%@4I@CN?6>I*i@=cT5:>??>Zwna<@:kte^hXHMiMAKY@k6*>i
Yk/FVN Z4/Nj8*i<k&lNhVX\cCCwaL*uX4lRY9!9tCwEFGDRXX&*u8K<%+$%CHmM/LPwPC@GTCqNYb+8D#Dhpyd
9VH$m= M!QN#T@Z&98tWy4+p*RY$mSE%BhJ*dt#mwa*P>6e&:tcZRYH?\A6>dK*<VyQJG&wY+?mQ*n*4yakea+L
i>V#Kk mZE8N?KEcP1N=BGhTaGh$pkpCSXVHw6i$h?QbJ4S#&@i9\E*QqFh8^XGNhS^@L@BC4b/9B8%8ZB<#$cA
@=wWnD Gw$RaC&wAEhc+/RS%iy:#+e$4?S=QWhh%hTX6NlW@qC$WqcIE46NEA+A$mdTYQCk=I?ta?6pM:ZmP/Z9
/EDCyK *6eI/TQA>K>j*d9^/YiR*?L/Q*Jet5$N>9yAC=nyMut&=YYwd!GwlquuDSYpqZAW9P@WNDX@ENJ#EFEB
BBH@n@ WkZyM1qF+i8L1LXMKwWDCcSb\CeyCPy%$9^lm8ddM!8$%\>b:+tZZ//6Xcc$bl/+*4C@ZF>t6!9y6T?S
k%tL++ /^qQV&iQt5P=%i>YX&=Q$k=Gkj=ct5dWcBBj?F+T=L84yWmJGQPBkIei58q$FX/6nJtb?TKXTGpCZijd
ZYG^\D #=<HwN:1Hw^EpHN^htJ5FE1Hm!llS<yam69N1Ha<Y>e\4MhyJ6N#cH>hcSYLNJacAVWDuqInyt:5!&E4
EW8pct \c&\*w!%m9VHNX:CXt\Ia5/LJF^$l$GE*+%Zp\h=byHKHc\a5BT$w#VS/@Z%*9n/&:>!ERYajuZ9W#DW
Swt5ih D%B<%4#HVHd1PH*/h*>GVG<@iLV<FXl^wDPAPY<HkZyYWjwI%Lt5mKlZ4mVk69c=bdH8D9Ye1BSTme9E
Xdwpk? yIQ#DV88<hnA&QYBeS\+8@*H&=n*aw+$DInck>P=KhWqY4HW%bjXi/MwedL&=j4/&t^8hpK!J%GXlJcl
Mqbpnl w4K?RB<t%/6%n^lX^FV$G%JWXEFFliLVWMqIbpW:K$@>/cPQEmqi?ThYWEduCqbdM\D1XGRW!96Pqywp
ZaEX5% Y@Yy64yD+D$Q/@H#HckyXXi%9\yyQw$qFpNyNZM8ML8>D?&MQY<IwtpyLWLc*I!y$pytCqb/!NM>\q/D
ia*H:m EKXSltCh^+@/W%:Ya>Rkqd&hF#XMAhK@*L9^<inHQYh:YwTlXywd/l*&q6?SwT+9j*Y%J<B>Z@?yW?B@
5P5QNS 8!BFJ$6NVmCw/<l4q8n8WBBR!JiqA*kI1@mE/BwK^WNAHaQTJZa=1p+=EA9PGB94dclKXqW#4eY#eZYM
=NL\LR KNY%C\>k!4#lhA=dDnVlBJdYZi=Nw>RMjp@an8j1Z8bQZ>RcDcRY9:/\a\?K9AaYN>PK6E9uCI6\Ct+*
ukHy%u lT#m*RLVC\LVX<>N+ZI=@NPXmNL4W=:SAee8nF>D>d<d/=p#qNuWXhXXqbJ$jLXFMlyIu5?LptpwLB\M
L\JKM& 6R<*6Rj*E@e?$dRTy1$p?iX%?ym=?*#:eaV$Jb4=lDhBwk=G\R6eFLi^EDbAGtBM@\1Aw8j>FK#$k==i
pmdW>n MNRAGC4/Z1lQ//E<SW6h@k6cKVH6!AG\9qPuqFN?LKPXeH<$NRGXBicZma=nS&^Yl:qIZGc#%heqVtat
%mq<Gm E=iy/=9each1<99:MemVdn?k1V@AhPVq&8dQF#a$111WnPP@QI9Eww$A/hwZC<H!MLcXXqQy<VATblaW
d#8^Nn tMbEMdT?\@q!C$uFqBM%RHuC1hPd9i18?E\CIW*<KcV!9Ky&?5tj<J<Vb:4QhQt=H5tZI&/5YVXnQZ:<
pI4nZT lX@c/9ujuP5IWZFVX\W8GHWcu/>G=XN*M!KC/:*B+Vk6nVal@jPlE/kAl^V4YL&&a4SXR6%^JPk@#kNp
mF\Yn$ L:%KwBJ%5J6dIlT%<VhCM?&=?P@*:u&%@NX@jwy+kwZmH@m4SXSi1aJM/dh99>*T$pmdWudTF?j#Ge#e
*a**y/ 1KKbt5M:Q>F^^LuHYwtDElXFSZ8KDBXFD6p@tFLZDCeV!hkp!###ee!Ah1FAF:aeXuFp<MVi=wtFnZuN
XY<=nw VmQacVh%^6Lbti\1!waS1t9VVmqMWnM4/dAJIK&HkPyD6<yq1WdiC@H%q*PDhAkkAcd1nD?a:^<VH!Xt
&qFJDH Wl+M1Be!GhXMZ:%!l#HFiSDFLX/?cy8FSTmwai4pJNnn?bX11#6kQZe8^Eu$jnBXTJKpWmk@uhS#SMXy
t^w6Fk JVVT^PqaP!<cNl%C?piSFENNA=ATym@ALjQCT!1thS/YuuILyYR4FLYwNBM+&*Q%+/5Mbt<kkLET9kRj
kw%H8E 6YFENbw48DjI\J4ReMXKw%MPiFGiBIyiZ/e9*I<X#hSeP6b^8J1GJkqXeXZKVGmFlnwJhkyttlKaD1ma
J$Vh@I lki8I:$bH15kIQHZZ=@d&EH>tQaZFIn<qLkeTF6%dZ%>YmyubbJaK%my*S8LYR1pMFH1mP^wa\5@Yent
F\@lKG @95\cDdy%8uLlP9F#A*!w#@B*ij8nn>ny/?i?^M1ImT/8:5B6KM&AcySVW>>%Dq\a/NI\bd65^%D8HA=
PK#Q8i Kh=E1Jb!&k9l%E&i%+5!JTGSa8QdaD5t&5F>KJVw+=RZ&$KEKaLKV+!kNutPaQiB8J^5YNb!NQWmnK$>
/a+A:+ 4RFYlaJR&WCKRwG#<BEacmXl1hMbhL9$hJ#15D1IHe6CM1yiQI$qkjM8$ycQKMwBM%yubiWi:T1Cn@PG
=b=+AL CtcKye8RMNPlRWa%QEAelI<i4H^Hqe^<jB:d?A51Emqb:>A1nltT+CRFt%B=M&u>SiW!9d+luJyMB*jy
5!h%SH nMtFnV!@KP*P<FLNL%GN!L9Aua<JTLHPImh4>ZVHF^hJa?c<kCRSGWV!?G+wIY\8t&mMW&jATdJL&IRR
EIRKW6 >R$cc@j@$InA&1mydn<PRXlLLNXky/m=/Ca#lRTIAMXDNDyJC^=%8/u$hDy>NG?NW@Sp19!W8EWBPbLL
P4&j#/ VaIa<LMlT65I$*\@ENpCpNJBS4+X4^i:Ta$A1kMD1pS#D+ZFQK#GKT&k/kmwD&d9C:Y16^G?HR*VcD%<
M?5Vy$ YIae44wcWc&5dB!e=Qq*FAHCmeEpuc@S8$GCFK5bQqLlNjGNnEdu!V^J1C18^n%e1el?mdt59:aj<E*:
cw6ike #ca!jRQkEp$uuLwZFX=4&/I?$kI86Pc!8YhByVSJRh5?T^wK!Qic?tPcWtPD#RQid1Tdn4%yY/#:4c=k
4EVEAC MKVXt/ZXpLw?d\Fjb^QCY1L$y\B:^H<E!pe%5QJ%npEF>:1@FL6@tQcmeJTVFl@ch%^Wl!Kqy!#c6G=Q
t/dt@t ?\lL<YYRMXu%HT>=<QamlYT%nNp=u5Vd^Kw\meQb$MA!DA$P1GjAVAZS@1=1j&l+bGS+JBkEYPE:G&n&
=w=?y6 katGqT/j%&EGa\E:4c\?jAR%=?Hi6ep&GWA>*JXKmS*S!RSYM?@VAX51El5eHI\\VT5J#D^CXuT6XdDD
BI4yHX a$JJ1jFX$i\KkL1&u4DI/jZbwL*eXGa@T#Q$R/p8TbJ\N#u@LLk>p<6tu\GXXcZ$iqNLDF6Q+#nHKARe
-AKCyh 00083f5c5b000110334 Page 39 of binaries2.zip
+G=YA9 $^19FX++Tuc<A\@h1J6WlRini?qIEu5?N1hL5KF:uWKQGC#anhP@H5=uBKaC%Qc/8pPqSlcQ>!L%HJwy
lD:NjW a+4NDeJW$LT/bD/@eaZcTi%L9RBZkQS+h!lI<nN8Wea\1m1pFketVQDc8@ha>>DTW!Nl%eni%%#BNDCT
5q1a#@ $SWKpada!DCKZIGdd9G&hAd\JLDbl^peJmu/Cpjq+TQH@KhI$=!8\*B%yclh^!<tPN@*EhJEnEdDeF$S
BJ4b\^ W%+eV$BBmqXN*H*ltTAwZuHT&e6tb>b!Z/=*TEy8\qXiL8pha%NyQwqNBQhK98#Ci4/LyC:@y@tQ1FEV
>^pR=i p#m==8l=kE%@LJuX=+@6\aF%RPcIl>PiG9T#i/kL!@QQSWZ1:lyh1puRH$tCB?@lhaicGm+tca8qw\Nd
#15B6\ i+j&<!/n>mnbmbYRS+my1yhdjWI/PqMZ>:G=Fa>*+!1M^*NEVhb5^p1+DQmG!<>K8w4!F!Y:B^^kyRjW
5bX@=# 6Fi9L$R^B1NwI+jAVqHw+5AB1HL1G^4a95$XKqYZ?VA/Z4jcWacZw@K\H<1bSA!X\LADlh$K<j+WFL4?
nIdWh% W&%h1udtb/lBnS8F5+pESF6l^unlI\c/B9AQZwQ99@@?pF8T*WV=*/D5iGbd8cRMDRt>nRTNiEdkijnc
d%P@4l <Z%YyAZ88VaYDajyC^H/u1/B@\>RT\MEFAACAAkACFX6JSy>T5GnARAA*kMAADIAAABndGqqduS#L&Sy
@bEyJ^ e&59h&q8M#I9WEhRbGq#c$F\eC>TbZM9cYN9dpNleHNMd&N4Ltqnd+&R9$9DRBVHZ=LF#W=1@aFCF*ER
Ymm?/$ ya1CaQ5jPDmIEcTk+NBB84l$MEK%DpJZReF5RlELcq1l6k%CG+hmJ!M$aAbHwhElBl1c=<WY@HEb?n$i
!e&<?P ^**8?>/:h\AMYeq?Fq\>eAB>bB<upTR^TeK>h%X6d=RREdwS+&Fp5NGknP8*i*T!aZVXbChL=<IEZa==
t<NZA/ yKbl#F/QS=>#*iS/?6lqqtLelaeQSKwi8<4T#PjBNn*aqkin?\L$$Im<D>HG**LpCFAMI*AZGKnj#/j&
X>%p%I qYwkNe#Q=M5kRKH\^t9QqqTTC469&yNWDA6RDJ:\4%P%e4Ia:D%it=WPIkIpM*G??Xp!e:uMhy\*yc\k
W<!yYR \M*$aaZ#K+tq/9VbpiK:4IpC=BD%u/+6$yjp@tFY!THjl@@pnNEM\^+?we%c*/j&nI:+t:W/j!BCQnn$
+9i!HV phl+Q>Y$pYdI4&1IIq!y&JAKXuSFdhw9cqy*^tVCSw*!6SXXKwQ&w59CM1SX*VA#41@ihF\YpiEp5GAp
\jR4iy alcyN^ej>chDKBBtaaQMlLw:wi:&qTGQ?NFl>nhDtb+DpGd9MjaLWE5DBBRAAkAIAAlXdTYDya\MdkEA
lFikCP ADaEAAA8AAAAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9WtX#L&qnd&=NaYq8Ltqnd:%VP&:D
+/ddFR MA!q$\IT9Ck*cKam6&lQ$LNww#b4p+:qw&V5&M$bC1n9Ta:6yB<WHjwetb>H!lLJmHT!p@%?L<T^E*tE
C<R$Cd QB!c@dwViaH9CJ&iA%au>=YL<l%mI&N5kk?WeS\l/Tu%J/W$\ae89n:B=6lE4p4!WCHXXNN+%YC6PD@b
Kt\!cR aFPEnAEBpKyGw$!8iPbQZp!AhQDZDYj@DZmE<!B!i5B=Zh>H<@W>/:%M*+?8^VKH8ei=S5?dP1G<@%Cu
LmA4<\ Z\Aq#F6VWd6<bY+eXl9CjQ$EQYi<<$LH6T%mXL&hhRK$bZC$BG&jpK?bRTp!ZNGQFHk1>I@h<q=6mBji
JJ^\Ql 1jFWX>=m>:Vl&j/Xh&1Swa&965@G/MJnIuCM$L+9E&%i#%ai6uI$eCyk<DZBqYGbEbK?Z4PNn^T>FGkN
+FFbp: 1LmWwF#Sm&M:dNM$@c&VuIGG<RuV+M1:*JY#hPWN%EqpGEYi5L4++@@$by/^tMNe:5G>8Cj*=nj16&b<
a<\P41 AFBLA\RWAAIACAAJXY$qh9tScceCAABKDAAAL\AAAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\
R>ct$9 L%Jqe!>ya&>8VY>%duR8cYN9=Xc>m^NBFH@:wd8L=?YCnYp<5FALBVGq\T9E\4@ARpH<C@RR!WKEDFle
^1=/1$ GmXuI&6qJ=#qacNNCkZSA%EQD:H\Cl5SNchmk4hpuI?*5#Qb9R^+c8NLZu+::@ji!=8buR<AB%^wNGcA
VVcjIC !=MI+ADDYp&&#:pAu=u6EH68MI&bP8ALnkT\lSD^BWIp<A>:/QX/DLtFmm>RKwF@8Iu@VJTV@tS?!y*M
D8aC8X Y&l+aPH*PN84:&@Zd!pQ@Q?e9&<bwMiYBC?h:e*Q+i\l:PlTnA<H#X^mpypnX@FW!TD8qMVu&Sh!jy<q
dKF^WI @wW@Pj/5Y%1j+uiY%L@@aM/9?EX?/Y:PZ%D=1TbD^c?1?XuR@4@b<hD/Y9Gl#5ibhT&jZ&MC/tl<W=#@
D8hlH$ T19XPu+WG$@>\qwLa\mY5@l=:RXIbw4^Y9+wYT#GH>HCE=uAmG?Y=Pen>K*p@WQipN6/jBW:wQHQ6Q+q
/Tn<bS m>Z1PQ>Rm+<T&aN\1@ij</HJ4=T5L=%@:^dJeNL/Cp#?R<Fl$CFc//NqkZ/!<F<5@FeL@>*C@:D\R\9@
$XkWJN $<KuFu:p+yL4K$\h5#*c9HHtI5i*X&/hq:kt<J:CX\I9Z%>>LyDTh!I8S#*j6yGXQej#My^F4CAG9+pi
p%c@%R =uW+E5RiIu5T8It+kdmP&G8d>k&/L9L%&bQAm5Vl%L#AFJGPENMMHdS:&N@kD+\Z9<jXtB:V:uFh=>@i
ZEC9X8 +/d*tk:V<Mmw\HhPiZy:l*jcK>p*6LPVF^P&iRhn4Jh94J!P5<LqmdAp#%LlL<<Y=a>Hm9LHQ:kG!wHd
nBGTaB h6Z#byi%k&ZqH!X<6/:u@q$%nNI@!Va4/R>Sq+S!E:9p1@Ft568DP%pj=c*GH:9qtM5+>=jm8icESy:L
aG=9bP =+TMc\y#bAm#VC8Gyp^HEBCcM4$cpFFDIn*SJ9Rt$#:VaVHjL%BLA\RWAAIACAAJXY$qJ?XnZ8+CAABK
=Mb\CE DAAALRAAAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jqe!>ya&>8VtX*Ltqnd:XY9Y@VRBS@
PPF*8H 66QcSaA4kbACR\RDhIc%Wma/h&EDCjkDClXI5SRXY/lK\pJaWFhGqBXBpYAIG\5VR81C^MaRKE/V=pPN
==m!qu i4#:5H%*?VlR%HNiju:*8@j8*jQ=?RA55GF%hSqw?:\EeBW^u?j/dS6kH@6Y<H+XJWC^IMi+!IWyLYI@
Rh&ahR mCIP>MKdb4PJTH5I?\ElHPlF8?nj#Gad?G<Gj69Aq*Q##d<!J*@b\BeN9CF<PG@k##m#?X@Y!h4uDjd*
5cy@RC DQbjDR>w*bCkw*?P#!6JLiZ9y@ai!Xw@=Sie&Z\qN=8@ci9#l\4@jC^@JaZ9mjl1cZNDtZ<t:P9J!wKw
hC%qH4 NMt?Hw4Ikyw4<$q?/kH*Z6Z+P=d8Z?ZZdIY@ep*n6jkc4*EBJaq9J9=F=8m>K@G&w&dQS*Eu=d@KiR>&
M!e!T1 h&ZiT9L9<jZ==dJm@$S:944>Y+*Z:jh5qch*95T9c@6n+JIwqQkhY?hLC1@94\EYbnJnjqK4%YZ?@aV>
BmnEZR G$t::iWE96/Q^y/9\kib@WWa=/9TBJ<t&Nip?V<a+yQ!p:+BM9@SWH>&DQYqa1k9c*QYJ<hkZ#QE*#LW
dNbXCd 6$8PTNyR+CEl#TJmX?kHlQ#b@M:$@R*EN8KDB6N@*&&\Ic&Nh/!@6auaIiRu4SWnkVHcl>\9L!DcjMp<
cK\M9l 5cc*BZda<!^Rj\\QBjcu>A@JACl&Te\\FpkEJ9%DDh5CD%IeCB\^:JBnwjN=hI\FHt5/$dDH5CnmDeX+
Rq<DJ& \5hdlQPPYLid=cYuwh:jthLjyTiRQMy%/S#*\n4be>#bC$<X*hP&5R>j%FME:Cu/Iq=yVecdyh^YLmu!
BXGhA& 6Da6\K*p9YG/Den#F>^u?9I=uJS88!D1M*<an$e@WX#u+>H*K@^cJQ=yAap:N>#WQ$:@MH4n59EXZpGm
HZ*I+l w$hWQ&$>hqk<Mdhj=PhEnM?u8\hPAeSen>%Bqk<cQ/8NIl<5+Q@IS>yEQ4JVSyaQeY4h!6ENJ<5IC1uE
aen4hZ KD@GBbhV\G%j&M:GFqFCFNXZWtu@AqBLA\RWAAIACAAJXY$qd!ySAH$BAAA&BAAAMRAAAGN5cYX8hHM9
pi5h\e bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jqe!>ya&>8WEhRbGq#c!=ya&?%p4FP\#ARl9?RTwtESQIGXA#A
iAQm/A YCpQAKK6%KnAWmcY9wK*SHTI6&V4c!BYl1==FI?MVLSd8LPhWAe1YLnp#?ZL&YjujICHI\!HMhninwB#
#?:/*J <uF5?NIDVu#!>D+pZbM<DHTMyl$\1Y>IcS^j>FLZNZu?$8kdVYMeZ@!JH><5#QcM8jt!:X@aVm$56=by
%%1I&c 4nwLC8b%8%I8M<&F#bSZkidenC=d:5a:jHdl<55#LbA^&=*^DkLmhuhSpmVMKA&H&L^1D5%/$Yyq+9d@
^t<TYj 84nqjy##S*8<C^ybPJ!=VEjp%K?1%9%/TuMiHc?*$8ZenbjT=cw**?d4VwB=S?*%p!T**T@mMVXJHenS
w%yPBy p$<KTBHyqHSFK4nQa>94db>L@GPjt\aR6m\C=8CEKWknT8/>KlIq>^#:LH8mEaL:KEyGk1iH^!QBnS^6
Zt8*aN SnwQ^>t@N:deKKVJu>6!T!mpD\y?14BeTE!ZRHwQDFJkiRiMb<Ce@mch%JnjKM!tXNMQ=W*G!p<jXdC+
+hEa6G @RSRT\MEFAACAAkACXX6JcBcCMF:AkAATk\AAC<AAABndGqqduS#L&Sye&59h&q8M#I9WEhRbGq#c$F\
wd9:G\ eC>TbZM9cYN9dqB!bYb#Ltqnd>%YMa9WRBS?!ia&6%e+X5I&dmh!YIqY46\QEP!5Vu?BIPpT5NlSlE8*
%abIF@ qyd?BBWZLji+QdkD+jBPWA@b/!^%81RR^nib8e&d:CZDE4D\JT<9<::*b6/<VN+MkAe?DIiZRhFBD?Ac
<LumIp !u=j6^@/AL>Rh^*jl<kJ5khBkjERcwkZN*C8ld4\bV1hwqRcYh\kySd1Wm4%cCVjkV@yPA^i6?9@&IE@
nn\>>a Dh4lLyw>c<bj6M#jJ4VLZ>jl@5A^@#*H@GC6Gh:*&8X@ljY#E=eWuT99q=bnYhIC@$=^aE5+?V=nIeWT
M$@>Ct Q4S^Aiwt?E?H9?<a@=an@69iC9GL=jH9EH<BIBk\^kl?%&9&@^a$n:>bmd?wKRV9&nmpKXl+aPEmSYK%
Ch:DRJ ?bQ4MWDKKj/a=piGWbLmG/9^F*Ea^%kQCj/X#p>pLN4lceJ1+pM<CZuKG*BetuG69&TS#P#+KnnPL?aN
iDH@Gc ?bE^>y/V*!Pw=Bj:q:qM/9Dm??Rb4<WX=cW:VL\LeE:?@?ACuNd9$n>h$A4%<WdL?64#&@qjhSl<h6T*
B4BV:q dh>X9$*TBJED8**&<aiYH:bHY5=%?<&nR8+c@j#Xy/I>q&iY*JY@:j=ZqFP%a9<9PVB!!<mSpYc?uyGh
BbDudy XuuVWy*n?5k*!Vu8yjh9#*Fhbl65\D$4kp9?ut?9T4@eehXj=BZ:<FlNK6N^1tDG8JqA6tkTZIhjXAS1
cdIY1E 4*aR!^/LPdXZ^%61H+d4uN1#e>#am!!1>m?A&K9le#8iw9c6/ZQSwln%K8i54tijT:1XP4GBP/tX9!9Q
Y*iqcJ :c4T<hW*PWE?SV=E*9<DA+:<HutGjIJ<m9\FiaL<#8kQDS>y@Sd1S/mZS>nH5iq#ln^Bj95ZWE5DBBRA
SX6^Ru AkAIAAqXdTXuyClL6RIAAEwMAAA^AAAAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9WtX#L&qn
k@&btK d&=Xdt%9hY=$Ltqnd?XY9+5VRSS??$PVBd%e5DEwBm\<C=XkTkMy^ML@RNDG@!BYCcc+\TddtbS:nXb*
-ABpyL 000ddfdb89700110334 Page 40 of binaries2.zip
iWhE*9 uMW%\TamF%BS>ByFFE>BC^5JcnSmFkqb*<#5#5=5>nJF%McZjjqt=y9*>5*Mt=$BMMCETtWb1D^^AE+k
YB?muV Fk1<j5WE?IJ6J:FeRY&kGtA#ntSkD!H5AWI+$B<Y?9$?It$J&ANB\IH?cBQ>t!9u:ju<AZM?4/Gly?EQ
KHM5Na Ga9F>:jn%+RH>u@P*>XM$CPNk^jGa86#KmypZXqt:dQnim\NEnW:y8ADIiPGt&Iji&@F@DGN@ZN:99%q
Ku<PLQ M#W?\i>Qmj@+T5#9&LQ<ua&a9!4<B=L+ku<y%1eq9d<8?FiC#$beVb:@%@H/S1P#!qVC^ni#/=<:l%IK
h!I8H$ K$>qQ5??pNpGbL1S@VW=AV#G==4Ny4BZ@H8#>1hB=beV>uZFj^+/CZ5q@:^PHq$w>t6!B<j#9A:p/A!Q
S\dDbR \1bu!9mSd/8VeT?S+B+hAH9T<:?h+HhT>yjMj$#bRJpc8HQ*%>kX??PVbkMPNQ^uDj>X\*@Z<D<$@E<N
B6lmVb :&9+Z^y?w8Gub4nqlkIlWZ@Ri*6$/@$\8N@dHb#b=4kq+>48aJ*m?51S#X8I%G\:kbK@lSHD4mJPEa5l
+i\?Jt =pLMLIBBlJleF5W?H1@<9Z&Gp>W>5B=mPWTD+^R+B5aH=m<ajZ9MeB^mEPE\\>HQeb\W@>^<$Z6eAjY5
BG4WbN hI>4G@@&H4h$YP&\BA?XCG#nkmZZ>%pZ4Xp9@QQN6#+Ny5ZPMni1Rw8hZd^P\/eu^9WNX@T@!Tap:5>P
\=Ie+8 nGnalL?AnMwq$aEX8mXShYmyYSL>uZad^q&y9?hFXmV/HBI@>l>PMKab%MT=TPM=cMF6>XbnJ&+=/nbP
=K^DTT >4hMhWEh!/S4RyL1\!wbRlY%1KmQPwEe\RRpW/1Z5J^FjXeptI\ptFb9yQu:DXBLA\RWAAIACAC/XY$q
Mbp>AL h5\ph4MFAABYDkAALRAAAGN5cYX8hHM9eGh\L*hydnM!L$X%bG>!aXB5hYhydm>TbZM9SZXpd*JlLtJ6
Em9qw% eJYYQY@eSlCGl:CTbXKw!B>\CkaIDLEkA1S\I!B>T1hXq&4LE^BZ=:BRji/P^WE8IlZd8BiB4DwJ\bWK
EEmLhB *MSRj5AXLM+RJBcVb=jpjXp&pKWiHX@iH8jh&hpqj@4=q*&J:ee>pi@=uMA*pEkc4*@:6Z!m9ay@<8yX
hpKab% >^GPeIq@q@>eT9QZ8dnDb/IkS<@pBVlRpDEcHCnIKSweKIlHk\MF8WYDA\XSNDlREHpSD\eK<lRFDlVp
$%V#J? EA$PFPRIDR+WbI\GB\y!mkaHC8LS+EBBd6HkREEWDR+W8CE8^9kb+&iMH#R+WJBDNDlRpCM$PFCRMSwe
=heIqY KMkyGl\wmEiDA\Y=SaMDBZ/EH#RwTM!Mm+iCQEYDA\W=SIMDBVqCk\MFGcQBkaKew5GBkuk$PFCRY#R+
m++J/G WBBFk\MFpS9<*PDpBn<*?EGDA\W=SIMDBVqCk\MFGcQBkaKew5GBkuk$PFCRY#R+WBBFk\MN=#E4mk?1
>&E@=W B^\w!CEcHCnIESweKMkaDR+W=BRNDlVEw<GBk6!m\aGGe?WehD+HQ9WH?BW1tIe!+9:MZniq*B<NDlVE
*1tTKB w<GBk6!m\aGGe$I/DY8X>RIPFPRyGl\wCG9$BVT6!l>9*5R%LCEj+djBZ%VBZ=A1:cM6#@Q6C$*V4Nl6
+\nLt8 lnceF!LLw9%@:cNk/h$!Y!!KIq9%KE9be6y\aYB*CEXIW8?l#QM!q<Fh&4QX:mVLF9tHSd5hdG*y4nla
D4Zeje JFNjHTjYD6iEG/>*#*mlcRb&A1#/BD?tMMY!>=Pt=k8#+?jDeyFWF=ZhmBYD=dw!qCTJuS+jH<@Pc66u
JICpRP /C&n#LX9PdHiNtX#$lQ<!Cj<6EY^ZH+a$tQ&cF8G<m!#F*b$QQP4YF&\jD+aP4GV!TldpMV5yX>$iY?K
\wn@qP 6b<<%FliqM%A$=ua<GNMqGc^dmFF/b+lSX>8GpwtE=6p6GVt5>=*HwLJ&Z#iGTwTG>^ES:=ctL=ikl>n
GPM>k4 ky%a<#p?BwcpDCuBnRunYB:MD41&:Q#6ljGal+*$JNHNa5Hj4I6FYaV<yIPl*&PZSbcM/LV$!VLcMZRJ
GeWSiR dkI^Q+de>DRd5^R>lj!$n@ul^/u1\!yBL#PdlKEuMYKh^IG!H\q?WyqHR@eVP/KVuXRnb5&Pa6$dYe$Z
?5E=BQ N=X+wSuw/%ui!:6*:/SdaMYu@Ck#614ym*5dDNuZFa:E&8mH9M#D!PacDPY%6>N1qE%H5<uWb1Ny>FM!
H$bwK# Z<%R#&H\bS+8hiR4Q$PK?8*u$j#R:6QiWF%di=>qE%6ZqX$pN5cKl8dEtWe@=%h&>H1cnDmt$>jWE9e8
qnIe@l taG<MGZjyDWF5#ek=iDu*!FD:Yj<cQ4A@#b+<6:ctlm5>pqh+ejELi55Pyy*jqyjVYjHW<@8++?4pe*8
6*JX9< &4IwCqckqEN/Tmb+IPjLe8Xue/q9?XuG>hZq=$t1JnZ*\XBh#a=6dd<d%XZhn#*EP69\e?WuX>=YQqAq
uD6&W: p+RiyetDu#\aE1cu+dTHb54iEH:id&Zw6*YL?p6DQchQVElT?MQQSa^Vl%mp1S&CujWNQ#P8J%q!AG!M
ltl:G9 %4XFtbKF5D>#8&CH!LuyCX?pbdhLSV?:8&H<I8</^A$w?1G1R\%=P\t^dB<4@KIQ6t46#E@n<k6HpyBB
N/?*BF /ka9VjBVTy?J6b?\ZbSt&Au:GlyT6PPuVS<iu1VS#Z$$NK99p$Xa<WP5QqkejQhw^jS%hEVDh:ReHwqC
:@wnh! q/Ia+8bFV@mmLIeu?L1GyN<c<!$@\XC5=dTj4?84EK9jk>46aMP5#/@<>aY%w^F:ihE>eA9lWT/4B!iq
/8/Ii^ 6DyKaZ5@YV<4ak$NE&cK=&b@u?Gc>d6D>!R#*b4**q?#ChpJS>/8k?Y!?e4^>@Yq4?qcV?//*VAE*ulC
*9k^EL uTBMD#dF:D=N%/>C#:>/94>jtN&ZnJmliPa99j?VKcpu=?&n\YKK#tju%?hZ@u^+*cFQ99*KJQtK#:=e
8$^$Ic tiJnN^8bm8X^Qd<tV/6:F=9*@A>RT\MEFAACAAkA8qX6JRMdWV8jAAAAQkEAAC$AAABndGqqduS#L*Bu
P!Wm^h eC>*cY+#Mm>FhYS9etFRdHXucY+9WtX#L&FpbG6qiT=ya&>%V<ENAmERHIIFREn<up?jEI4\cW5pNwd^
@eyW:p +hMiyILVAuBtid9LMM#PLkVAMWMIWJ\heBRV1y\Il+N=Hj?m&WJ4m=R<>N:J1p^dtHPSWmX6!P5qu=G*
%5dL:H tMuid!tyHluTqTHjSjPBYt#PS:Z^:CqVDjLaZMTc!iSED9SL&a8$n*8!P%!$8i<VGQ##t%h<5Fl/*PkS
p#kVjt n^h\b$<neCG8m/WH9S>RT\MEFAACAAkA8qX6JRSYHuYZAAAAQkEAAC5AAABndGqqduS#L*BueC>*cY+#
XbMVFL Mm>FhYS9etFRdHXucY+9WtX#L&^9a&58cYN9nW<:CpI^EJ!kpIBFZtX6cjpkh@Ie5Z6kab%dCCp5E:B>
tWT9=$ l^E56%l*5%cC+G\tp=pN?RBPcywtKI+P&K5KNVpIHdcnq@EL&bw=t&nJw9e81ktQAYaVLa%$?5I8KaDa
1^tkDN BFYWuk8>%N?8=wq$Z\!6dXKc++Ww*C8mHBcYPt9Qm@<Z+\qiL9SF8A4bhKB<cJ/S\PWEQ1@kl@*lDXBL
kZdi@u A\RWAAIACAC/XY$qb<I^1F5BAAA&BAAALAAAAGN5cYX8hHM9eGh\L*hydnM!L$X%bG>!aXB5hYhydm>T
HN%CkE bZM9dG>nc#E8cYN96XP^V5M\EL*WTLcElQMHhEKMqSkb+A@+FTMlBepD&bw6u>CQ!MCajEyH^1APyk41
ilGQFn eYe:Cc*T1k!<=QX<jnuua4<CJDCD?V\F^5eM+Ibmtwd<NkG+ElSyQCe?ElP+<B1XHWH8d<n#EQmmRhM$
<:ccR1 FHpG@R&IIjDFW@^#AJ$^#Jkn+$Vikka$h\GD*uq5l4#&1Ql=VZPt5IYh%mq#tZqV!%nj?yd4Gphhb&cy
Dpu\eB :Lm?hu19Z9Q4&:Fj!dKIDVK+N*%QYQB8lF4%C4Jm9jNLh>ycP/qn\KBHDH1@MRi/@>ANHIe/qc5@=6JA
VaC9/9 5dicK@Ly%\w!RW?1P=QC&=K+umBmE:ttXV<Sh<V9=%<pcTj+bJB>upc9>#:Q+j><V9+PEb\IjuYZ*pjk
#^=&qI XQBQFuIpw$c*$IMLZbIF*m6@nK1w@MFK!5>FkmYC^En/X<8uMIc?PSZH*K&B:i1q*K+R9/=y8^=c?AFR
hcHV&h T\MEFAACAAkA8qX6JZJ5^=JCAAAAQkEAAC\AAABndGqqduS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY+9
YQRC8y WtX#L&^9a&5!Ltqnd<XP8SHAMAkVh^/AKuXKn<qwdEap1N&+mS:EmRdATHiH5A%+qLTcq#c59mXPmBam
#AlEnm JpR8teqWW!%WVam1NH:G@HH9D%BLA\RWAAIACAC/XY$qCk@+H/WAAAA?ARAALAAAAGN5cYX8hHM9eGh\
k9Eqtn L*hydnM!L$X%bG>!aXB5hYhydm>TbZM9dG>nc#M8cYN9hW<^D5I\DL\KXMlEJqaa?RXj!eRjPlE&^t+w
4yBB9J 9@FV<wKwa=E1\4q8&al>Q8hmY\:R$L#*$HNykKM!we1bcLCh*\V@Vy\hMS1yMSES5my%h6S1yKcTB1AN
</\h=b NmVenJ\J?&ip$L1Wpkw9%*W>laTW*m&\a+u4GjyR5nW8!\R^Ic#:TmnF?FiS%<$@h&C/A5MJ!Aj8#4q^
kJXplA a^Am<#+RI@PS>bQ&aQuPA@kCWE5DBBRAAkAIALyXdTWKD@kjyRAAAD+BAAA5AAAAa&^ybY=$e!>\b*A9
Vd#4An h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>5d&N4NC=ya&>%V#EP\nAM9AyW!ERtXln=BX@J^B</EVdGdmm@
DESnh9 <XQ!k1lnpT4C8Y:bmH$?=&JdD6DR9QjRe&tAw#Kl!yqw5J*jBQ>PuB$^G1p^ESG!KuX&%G1pyyIGwA$&
F56e9* JN!MuAu:b/VR8yTTCm@ZhV&FlJViLdBnmi5b?qC!NT:LBDEl4Q6KKMZ+X=HZ#V>*aLwC\\uIB?:P8ZFn
GnL<81 ECL#QlAn<=H%p@bk?e+D?AJRT\MEFAACAAkA8qX6JdM!uDK#AAAAQkEAAC\AAABndGqqduS#L*BueC>*
hPm*jP cY+#Mm>FhYS9etFRdHXucY+9WtX#L&^9a&5%Ltqnd*XRMR:CMA!<TqVNSmhYGQpFZ@BTqc%j!BKFDT<X
T/h/^V *j1qQIWubKucLhlJpXm\e#u:HDqPkE1<dX8wZT9kyC^R=TKweMm%kH@GiaG=pLwEIRSlXXJiTKtR8p1/
p<D$9* Aa=!n<WNYVCT=+Id6uuS@M:dLF*hENMGYHiMWt@MPHu9<bk/5mp%4:GnQpZn8=HMYl6QIGP6MJPSGZ1&
MV<hK/ bXR1%/G8NbCGmD6?a<X:j#N@IZ@DnYlu\W*PQIEQWE5DBBRAAkAIALyXdTXw>@ZNqkAAAQ+CAAA5AAAA
^^DPRI a&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>\b*A#Mm=ya&@Xn#$P\#AIlX?mdq+!hjda
G$ReQD a?SwQyJ*Fl?u6*D=MeFTp1FTq#+k?MMYEGBl!*tD/L$CV<+9n5!^e!^+/F%becPmnqI5mjGl6ebbKq$h
ZtSG?+ 9X5Tp=J<9qehthSBXGhPXc9B/5H&JLl1C>ib+:$y?k$?=9qcXK@*@a%wDEq?PycaYQi?ahtQki\$ZXH+
^XDAmi BcibjS:B8$nV$=@@kV=RT\MEFAACAAkA8qX6JVDPCGL8AAAA@kIAAC\AAABndGqqduS#L*BueC>*cY+#
KpD4EV Mm>FhYS9etFRdHXucY+9WtX#L*BueDW\Ltqnd/YT9\/CRA#Gm=memRNM4nI/tnk//CPSPGDCAMaBHwjE
*j$!yH B+DN%*B$^Dlwwpq6!<Hl*&n<:n=/9X>KL\eAFk*Qe+G%:\AMKI:IHuqP61A4DD4\S4FMmPM1<KBFWSRW
-A+yH1 000c0a6f42800110334 Page 41 of binaries2.zip
SjmCA% iRhqAtIXiQAYQ@=Wj&I$y6#JnTT@GNW<T=M5iiaq%D\y$!nQ%hy6<#IIXuY>V?XbNFue%c9Ad@ZQ19M%
>Ayk6W *JankpQNlV6V$6n\*lLWlutFe!eM\%ee6VS9yHtnS!/F^\<*&bQ=jc=<TP>ieE4n*:<j6pVy:IYHjHy8
BlRc%y 1M%4Y*:LN$a56He&+tF4ZC4EM>*EhXk*9RFRT\MEFAACAAkA8qX6Jc:iJGyuA\AAJkkAAC<AAABndGqq
JFmNE9 duS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY+9WtX#L*JqaYS$d&>5LtJ6eJ&V9&5pN^VHZ=mFMeKN:<CX
H\W*Bm t:kIeT$I8HX98Mc%P@$LdqK+el$IGNSheShIea*@k1%T^K46J1=eHJmB&N$a\d%<*6Q5:kVjD#nNcuj%
+Mb9t< yK??H:&uPV4?cW8<@dIR?hq?/c@wQ$mdiP#pC?*eQ*J?*u:5+e>!8bVqQ$6=@Q5QYT\Y54Y%Jh9d&:K#
Z5d+Gd 5!P:8:8!6:eu?@9:euB\ICeuJ*J<jC^HS$h!iHkw=:?19Htn<49emA=F@44=X&+?jyVj@9!AR/Rui1cZ
aHHAF8 Nw^<SYKSYLTa6mYJiPJQIy/IJ&&!VD\V#\\!<c!?qSVmlZklZkkW+5yaGY6yX9+pi1bdVJ5>Z^GGCEPE
W@/$6Q IeLkTDBEGCIMEaaIk&QCEGGIMERaIk!PDpPEIeIRaak\SCWGS+RnGwh1P=/V&JQylc:6!LAp#BNGmW$V
mP6JFy LJ+GJlN@Em\JFp<LHAtPBEjKF6PYKnkTDAtGBIPqL5GSaEk\FL!Wd$<lQ8$yW*1nE?Xwa&&y^n9DqDHN
SDW\DX GGTaM6/b!e\tPh6i&54l*5V^#@lu@K%EGj>5eSk!DFuX!>a1ph#h!K!<BacCZ+G6\FH\<>IcB#pweBVn
uYBJl^ +GBidpRFqkJLAcJk/FeAqwK\5KkRKLDa6TnGRp$KLMZ!+T^&G/\K&c?T\1A\KA\Kk<Lk%\tGAwQCwDAW
&tdn$X GQ!K\cA\KA\Kk<LA%uVmMCkMCwMCwQkZNqPE!1KW4EdWWe*D>4a%TZ/W>*J/imyub&h!eZElq=iZeu%>
kmlVGM LXhZX*J:i!6*h*h!j*<9D\<Q<9V$JPM+!tNXijj&Li?^9hH1H:F>jYV:&qDq?d9c+nt$>tItjEMb6Ki>
LmH!#y WNe\c:b5Ndu?%aA$hNa&86wSuhy4\1H9S=<Na=&&5cp?XK&/$XZ&$Eu+YwNB1R6Ddd1%*+n\@*/KeBmR
P$!pe+ Nh*Iww$jiVG:#@1yD9&uRb5PaV@#$?w$\X#u1VG@ASuCRY&>!#h?+:RcjVhLnjpNu@4&DI&9!Tc@H4>S
<BN^NF DbKNi56m<?8GMK!d/@1tt:biLFdyDq!!89Jn6k<49!bwYcq%HG$N8qZ4N*:XY=nJtm=+*IS%ueJ=Z6yS
ly\=Cm l:CSte:TYpiql>W%6PXlZ4&8%w/46ybNj14n/L4\JX&kD<?9Nnl>tM1l%e<*k*!iC$*&<9%a4%65Vnhj
e@ti*Q ^jG:4:%Fa@&?>:aL@\FRT\MEFAACAAkA8qX6Jhj+cDujA\AA4kwAAC<AAABndGqqduS#L*BueC>*cY+#
nlC8Al Mm>FhYS9etFRdHXucY+9WtX#L*NqdtS$d&>5LtJ6eJ&X5Y5pN^TH*&cZ4BF8uMKXt:mK1^TCA:jdyAmG
Y+!RBq c>!EA%?qj<EyW9kc%+GARh$XTTBFWlmTi15W5Y1:mT5ZB>=A#6&aId^<V=4S#94YPX<$1>HwnjS:*:\u
=khMnb cYeH9#nJ=hqE=DQc4/mjWEi!pi%jj!!QqJQ<p=PV$6nF\*\?q@tje*u:^+<!tW^pa&NDNne*bY64T:c*
k+<eAG 6&Xub$h&h*hqd&>QDk<Q=iDkRGc#ti#9:<9JN!4Qu/6<J=imj!Z=@jJ98Z##S4:>/Ye<iG1kStw1Ze@N
cW%YnY a@Qa9Nt$DAuaA\<Bi<Ai6E!L&CQ&TChmn=1qJGFQ&BQ&lCFlX@yKZ%N^qc>AnXT#cZHQ#eQkajA\iBk!
=#:=t> Ek\iBk?Dl<HDpDFl<DB+GD\MHwcMDwPH\eQkajA\iMWGl+jDG+h1?d^MaqipJ11YV+aq+D#kKCAcaMql
?:Bteb +GZkIeATaMqlkTQAEiAI$Y^cRkXHkCHAEGC\$AW+Ak\BlwR9=b=DmJ>!yT/<QlNFd*$6web*lCumNPIk
d>=iY% \lV^HZpbEauS6LTpI@9Gn9?I@+l@T%HEj#R:DBGG1J4VXnIS5uen5@RtGBL?Et\JnwT@uF4nIAaJntRe
dCV?:N jFlPN=MTLAtYBEVCaX+C5CRtJkaqDApYY^dJYMlJkmXbQDKL4RdLR5^LTYFRGBRGlWFl!M5JlkTD\1A\
+EETCQ JBn!EwNBaXAaFAcFAYp1hlkWBwXBAXD<J<TWme1kEC^H=FHNl&udtCCj!k>!hHRp^<jHeuy/Kthub*J^
de$KB5 eTHu=?h!hZWq%>jZeuN#I:i*6*J*h!hN$<ndX8Z:%/@b^:cnNj@EhHQQhK&4e9?@!mVZTh>T*l*#$hP$
?NqJ>= *dA<Xj8L<XPW:y%Pc%tuZij%D*d@>hW/:ZbeT/>hT/?>etX8N=$&?cX4Yt5@H/*V%4c@19bm\e?=1y*q
>%d++j Ju%4N:=N5:l4m@cLeSiy+4y$WGnXNR**kVd1F1P%&q*et8K=+*:bcW>/kM46tlX8ZSAQN//=#GMujX8+
$j!PEd Eb<P8H>:%Y9*+*68p/@y:PL6Fw9^+?9EBk*ndVGy856B9LY\%HR!DS>w&=i+S%h1q<1PY:WGw>i&4&5K
A?BYkZ h>NPm%c@Vq#dmc@Jpm&Ww6$6L>NiB1N:1p45::b!F@J&8llX:bW5>h18db9GJn&VyZb>196t?yAdF>N@
T%lh%l FkQ6Rba/dcRyJt/=4MHwa@J\j!:n4hMF+t+RnGYY54c#Shc\Fkn>=1l:$R>iPSm!4B98!@+aYJPquq9X
a1h$9K hkdcL<d9Q/JY6Bh8pJmXLHZebc\6qNuw9ijj@T4*@RQ6wSi*JKL>e9!Bb&^@jn?iyR<>9>@>d@mQLNW^
j^*/Ha <m>RT\MEFAACAAkA8qX6Jh$8Yk6LARAANkRAAC5AAABndGqqduS#L*BueC>*cY+#Mm>FhYS9etFRdHXu
=%Zd?N cY+9WtX#L*Nyb&+8cYN96XK>V5M\EL+pTK/E+QIG#aRaI#E!qEe1W%k1G#HEY^?FIWQZQAIdjRVG&^Ky
lWaQpb k#u@JNkShKp+?<9=P>>F>9pD!CCH1m4B&qePeMi?LD&@#\B8C@c<4llQnA!8*B/Z@YHKVXDKP#6+$je>
MK9YJ! i^5^dwI^*6qlR@c#NG^?#HE#&*ABd?VMNR<F4b#+1QicH1CN8CH>6yIV=*J1&:1N@ph6%/*m<+uVa/$n
@\5iR% VyIV+9QaBM?BdA>5RuLipDB#pkj6<^G+BI%wu59+j6ReQ=L:*8^W!LiDpD:Q>Yha>QhF/+SQ:#F^dLay
^S6bF/ H^d:&=TLSj*9!8pB%leCGaJSSBAlH8h6GJJli5kaBWMa1@M!cH*T8aL@$#pGaYN+ENTnR8e%AdeMS$NB
jy+4=Q B1S=kRT$:*#?>cqt#wHD1/<ZS:e@1J*nFNyNCta?t#mD\q$?la&^<GDN&L#u*%BLA\RWAAIACAC/XY$q
n*<Q>Q A=:k@&aBAAA&BAAALRAAAGN5cYX8hHM9eGh\L*hydnM!L$X%bG>!aXB5hYhydm>TbZM9htX!cYb=Ltqn
pIQiY9 d:YV5W:DMBCGL!&TI!Hp9EE:wa/SGBuKE@A5bRyLbTMGi?54<AaMGd4/EhnwI#B/T/RP=4<+mb\IYC4P
T@t5<u 9b!@<#t%j#6EGT&wKAym&&SE6+n4hiT9BhEnel9$PdPGb*VXnYu/#ZRe%DwGd8k+=^A=E:wjlSADN$:^
?e==/n w#hb5TEmGSyE&&4bSi6JILdBq>TNi+8P>PRQhc!@QyhkJI+9ed++hiPN*uj5+:#kNa$<t1A*E8?L/M!l
<wRSq> liM@e$XL*n\+A&iqkSBET!^ckqh%V68wE&9$pPkEij>Ny=qkXT>dL%!$=kK8%MkYVbNSA:j&aQ$htaS^
l9VtW@ F1?=GymqNca$!j8<1i5<Zb<+*=e&ac>RpK/HC!IVu%NZMFq9Z#C!X$ed/!Xlmk!mim4T@ju1>DHb:<%i
u?i!SS >@Ze9QTjj?uV#QS>6udC\*pMLK9hqJ9b?G:Kand@==9nmFaZ8wRL?DJ^$ijV8m%e\aQD^Zi+<A+j^DhR
kKnbq? T\MEFAACAAkA9XX6JhAeVS#kBAAAblIAAC\AAABndGqqduS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY=Y
@9DBhc NC>TbZM9T&X=Ltqnd?&ZQYlnS^DHS&eqF4JB>lY8VHT^t#lFPNn11kRZcS/Gc=#Y*bL!CwQMI^CB\Scp
N8p5BM TCBk&E=FLmSFIDmNRI&I+R:m4i$tBwELB*MkGSWTYN#pQ:NQH<<u&&e8CTt<#/N><:E:9#i:jl>EGe4T
VmTe=e w$h#JP&9B$Tjw=?dC@yHGcJQykl?XituHNEZYjEH@e9*mF:QIk:uE9IbSPdV>wC8cYZ>w*I=hHLkyNFw
epB&TR wBeL/^<^l$+PMeuQ:c%TKaiVu9/YT1W6NW\qi4jWXj$*%R6de8Bp=lc>Q6qQ*h*T:4M^ubH\&Tli5N5$
?Ce^+$ =1heJjRD9X51y@!JZp@H#\^%#T:?&5%/QcZuKyZK+#G>n4a>$thE4&qAwRVDbZ$aWPli$TWiP1j%Ypw9
18Vhaw %G9j%P9q+ZmhIAAX8qKiAmh%RV=/?+bS*C>!5V*>86me/pN/^WctuWlV??cWTBM^:YK@&C9&Ct%IE?eN
<4NB%* THNMGwX?5V#hL>JW@**K1H!RmNmt+b8YGMS?!6ypu<<qi*&\#<9$H?^#&ST=Z/u\NaybR:@XDZy*X*YT
hLAF91 apIu@H?1Qw*iQNb?y4c69T+\?569L<9Te!Z$Bd/eWGimq&hE&\i+Vk#QJL*wL:eV\d*lBYJ@y>AjRG>6
p^8/5w l:Hy?$E8VJ1>i=$cj#cw@eiQqM%tKbjL$i#5LM*Q#>QC\kI6Lm:T$6IT4c!5$Q4/P1&64hH1/mw>ijKE
I=\Rk/ !q<^QZ*K>D$hEd@!>PKwSWhub@Vh#:>IaTAY+mA?1Aa@BnaDt^Edl^AL8<YJlh*CdnpMe:A:&B$WB:6n
R\ZnMp uaw<:B=&D:8H\e8CRtjw:EM1QT#EReVGIV%?DBkMGA\aDBkWCR\GDAaMBk\GDIwJBkMGA\aDBkMGSRiD
uW?@Pq AaMBk\GDAaNl&MBl\GGEA+8pq/epenmIl*C+bLBaJLhIbDGyBa8YAW/LE\5YC^a6C#k5PC\+4BMdl%KB
dk<^j@ \+LBk5GCRWyu\YHBaMHkhej:WELpCahQ!t8W!BuSPbRc8S&aHJI/JHBke5n6+HTa^Dtbm<N!cG:aph<l
R?M6mi 9$N?YTKH@E:5aHBkeM!/dGEq4GaZMqqiD\cQjB=5Hl\i?ZSylRM%<PD\\wEL$?ZGIA<YD^aQCI?E8kZA
d#R<<n +nHRI<nD+MEm&<ILC>dEk<XLQbSFhwP5k6P6^GBkMDAaGA\MB6%PaQBkaDA\GD\ahI8BkeHAaGA\MBk\
&SX9kS NRS&MDAaGA#5=X/DPVAba!An!FybI/!n*I>$dwt^>CE>y+&NDZtT$5:PD8*6:hHl+TH6:?@V<jE^ub!e
S1lkW$ $PuyKb&ju>QF^RZ%in%1Z#L>WK*iiy@L@!Q6wdTWyS1N#q8lnWh<uQb*YmInj##8F<hAE9i:?iP:nSiH
SJpD1I +Lhc?eq?:mSZtJ<+9<\kdcT?+e>jKh<d+!Z@DiQV@9nt?iMJ@p:4XV+%Qu+*j*!DQ\y6?Sy@uLSW\Mkj
<^&^pF ^=MCyAAcWa$uBuR/6@kH<\h@6Z1nQ?J4@SwRSXhLMM\@SlDq$@:l9$:T4m^\@q>y@/@*8iR>JZQ@uuL@
L4uC=b uuL@uuL@uuKZ>=VlE#CK\^$#ib:HA@%ly#Z8b##S^@#=+SM/$jPD6+YBu6!Bq=iZ^@W+*p!iA/*l+&q#
\Kq#mW iclZ+\kQp&mpH$SSNh+enbe:jj\&>?qnjA?i+Q99FN?B=@ki9EDjk<:+F1^C!9ki=PS:pJQ9RW/?B=u?
-Ah8m6 0006c188c0b00110334 Page 42 of binaries2.zip
c:aA^: BqBLA\RWAAIACAC>XY$qtEy:64aBAAA&BAAAL\AAAGN5cYX8hHM9eGh\L*hydnM!L$X%bG>!aXB5hYhy
4lN/bt dqa$L%Jqe!>lbGS4bZp8cYN96XP^c6^AEH$/tc^A=uTjeFXIGXBnTPM@!K>5J+Hl9IGD1AnwE@\LBnWG
DtqmKX NRL@mL8+*CLkK+\ud$aTJ\WH$tSYw>HdN:P#P#5CEt!\*??k<4\BQ6L8hmQ?qADdqJdji?w%NeGFeYGD
IdVR:6 9$m\B!GMSke@ltGk%St^B!Kn$cFV?y4Ee!\p5&iX\HRpA:K5QyQ>G45<wLp??><R+*mt?#\5q</JbScG
M8+l:b *T#\/R<??BX?eZGFj:X^nk<beTM#H=#Q=QS%^4Y4K8?P6#L=w/JwTISV4LC1n?*M8$yHjZE:aX@y1Gyu
&E#c4m 8A>Gi:ln+QH/9ubKF^J4w$eH#\$=4tSLP/W%*j%WBcN=H?c8Aaa6*FpG>a@Gn^uXkbnyiKIHLl5K^XM?
%KA+e@ H5m8G:cjB:5#FHdhVL?+c8=J=C$XiW%EjqA9E*tn9t=VQV#?Sb@i\eQaMApY!qime\M&/hMH=&J^%&1j
VwHD?h :/biu@6<\Q@4e?TV:YANqbeFC*8K/Iy+c66ILN?jSZF#PDVE&W>K\FZYWEJci5XkXdiHk$hbqwER*bj8
mPe1S* j58/hy?:K@%#e5/QQ$hu=pXYhZujcyXT9VN1Rd$D9nH8pjwdWE5DBBRAAkAIAL%XdTZRmG8$u\AAAD+B
Sk/$eH AAA$AAAAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8XnR9WtX#L&X8a*J=eHS#cYh8Ltqnd+XQ
9En:mC MR:CMA!<1EmN%MGbtBpbK?WBjI5FKamqEkM#9/nWwcM4<RGi$6%D5BMGF8Ce<<Zu^EwAy^FCkGH9kK&y
ySQ?tV $y!h$tFVikujpGw#yTwY8qtYShYeZBb!4tJlq1WQNMw8^8k9ADG#q^+p/:D!yQX++?+aTETAW!LQ*MV&
kj?w4^ TXeSQ+<kHicH1de=:V#XkRQ?Il<$pX%/Q<D>PG8<K<@KS@pPZqBLA\RWAAIACAC>XY$q*+dK:caAAAA?
t+G4Lq ARAALRAAAGN5cYX8hHM9eGh\L*hydnM!L$X%bG>!aXB5hYhydqa$L%Jqe!>5d&N4Ltqnd+%RMR4CRBCe
XGKi&m =T^Ty4K&6E!+F+kE6BBEw&l%D$t#uWKKjCW@8D\yyTC+:q/5BMHbt=&d&d*tANLK<^!GJRF#W/WqC!Xl
N=X&#1 qtcMZ?By!D!JqX/GaXC%SNKB!CSYFqu:lneW\NPkKnH4a9Lb^@hyd&^HZRRi5Y<d!&Y<6#/NG9N@RtT#
a1a*j$ aqiBZcqEaHhWZt1t/++yuJqPFXNS59:Lm:bB@D/IY^@pX86dn#hRT\MEFAACAAkA9XX6JVDPCGL8AAAA
AddW@D @kIAAC+AAABndGqqduS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY=YNC>TbZM9eGh\NVA8cYN9ybK@DwJA
!\c$VZ DMcLtJ!JA$!8Mn1cPD4wI=E+aMIA^kEil<RHkM*ZeHVEPGmmTY*L\iHjcQ#8Qu1>Z$w9B\AYDe>#kdZ9
cHMY@< AA\wn5kiiW/&wC5MP9BG5W!I+!4\wEXSFBS=B&WCalX+<Ba@@qS@anTt*MtNJL<a%V^Lp!^==mZWQCuV
VQBEw6 KM@X&t*#MklYhd%Q=Xp$Yh#X1<B9>e?1<#ZeqmPCR<&FP%QT&QDiE6TGiaX#J\#DX^!%NG?picNHLwZH
mEeI%y D#jbp@q>4u^I:%=\T8Qj9^?&SPu5lah<it/w#Y6dj55*Sm!$h#dmaY6eK5R#*eS%YQi<AXBLA\RWAAIA
t+M\bk CAC>XY$qDFcTYuEBAAA&BAAALRAAAGN5cYX8hHM9eGh\L*hydnM!L$X%bG>!aXB5hYhydqa$L%Jqe!>#
YSN:Nw cYh8Ltqnd:%W5W:DMBA>%\lHR8D<Ab$Ra+GSAa1IYBCypBma?k6qTye1J*YI6*^MB$d!CY#\Ca#iY1tD
BZRJN< Ph6JecLCWwt:9J#j?e/^#/eAMPlB9^?Dqc<i\AubPQd<qAEeedI$:lP8CR#&*B!q@TLwHpD$^mwN11wm
CE#P:q c#*GQYCMN%c6!://I4Mjeh^5bLpD#@INX/RISh:\qT1X9wAm+Ec4ibR*uNJ%WR!KaD%hLBbS8D?^9l!w
Mw4qcQ kP8eA5L>&ADQRh5c&IDYj88ADhj=1@L^EmlFGyG>^PH=hQd=*n49+R#4iK6c/w?@/4Q5%Hi1XI5*>>F\
B/\pE5 tW*cjNtbu:T=/PS9:=\K+HlHTIIk<ACm>wh^X+TeaCykBE+R^9b=ZQh/$?eI@>Du4mbW5qYy\FqXAyA%
RS\X9^ yiH%jDS*m<lwQZBe9%HHGL4dk/uQ%#M*L/jC<&dhcN9u:pdIp&jpb?jIkSH&pR@J>=AkH#<mT=?RJYNp
u++<8A >&Ryl9+DKG=9WCbDa>L$G%BLA\RWAAIACAC>XY$qb<I^1F5BAAA&BAAAL\AAAGN5cYX8hHM9eGh\L*hy
FdFYm4 dnM!L$X%bG>!aXB5hYhydqa$L%Jqe!>%dt^9a&58cYN96XP^V5M\EL*WTLcElQMHhEKMqSkb+A@+FTMl
1WhVMX BepD&bw6u>CQ!MCajEyH^1APyk41eYe:Cc*T1k!<=QX<jnuua4<CJDCD?V\F^5eM+Ibmtwd<NkG+ElSy
>LPRNB QCe?ElP+<B1XHWH8d<n#EQmmRhM$FHpG@R&IIjDFW@^#AJ$^#Jkn+$Vikka$h\GD*uq5l4#&1Ql=VZPt
WyhMJ5 5IYh%mq#tZqV!%nj?yd4Gphhb&cy:Lm?hu19Z9Q4&:Fj!dKIDVK+N*%QYQB8lF4%C4Jm9jNLh>ycP/qn
TTRw!Y \KBHDH1@MRi/@>ANHIe/qc5@=6JA5dicK@Ly%\w!RW?1P=QC&=K+umBmE:ttXV<Sh<V9=%<pcTj+bJB>
pyWB*K upc9>#:Q+j><V9+PEb\IjuYZ*pjkXQBQFuIpw$c*$IMLZbIF*m6@nK1w@MFK!5>FkmYC^En/X<8uMIc?
9cA/8K PSZH*K&B:i1q*K+R9/=y8^=c?AFRT\MEFAACAAkA9XX6JRPi+Q>tARAANkRAAC<AAABndGqqduS#L*Bu
\lJbAw eC>*cY+#Mm>FhYS9etFRdHXucY=YNC>TbZM9htX!cYb=Ltqnd:YV5W:DMBCGL!&TI!Hp9EE:wa/SGBuK
w$aih# E@A5bRyLbTMGi?54<AaMGd4/EhnwI#B/T/RP=4<+mb\IYC4P9b!@<#t%j#6EGT&wKAym&&SE6+n4hiT9
bG>4i^ BhEnel9$PdPGb*VXnYu/#ZRe%DwGd8k+=^A=E:wjlSADN$:^w#hb5TEmGSyE&&4bSi6JILdBq>TNi+8P
#ANitJ >PRQhc!@QyhkJI+9ed++hiPN*uj5+:#kNa$<t1A*E8?L/M!lliM@e$XL*n\+A&iqkSBET!^ckqh%V68w
dIymy4 E&9$pPkEij>Ny=qkXT>dL%!$=kK8%MkYVbNSA:j&aQ$htaS^F1?=GymqNca$!j8<1i5<Zb<+*=e&ac>R
8ZG4AQ pK/HC!IVu%NZMFq9Z#C!X$ed/!Xlmk!mim4T@ju1>DHb:<%i>@Ze9QTjj?uV#QS>6udC\*pMLK9hqJ9b
FLn#h4 ?G:Kand@==9nmFaZ8wRL?DJ^$ijV8m%e\aQD^Zi+<A+j^DhRT\MEFAACAAkA*XX6JZwN=dh+<AAAtFpC
q%yZA? ADMAAABndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9at%\e!>mhZNydtX#e!>#bZS%eC=mdZB$@e64
l6yFpn Y&8:L\y/qA5m1F:>A:8VDeyBlwT/hBeW%jkEN5kk\<4leFc9YtPABNJGt5l#PYH8:G4PD^!\C!qLMya4
4L1L6P %q^4Gp:DAS95k\VTR51Mye>JhXK\@wEeeCBYG6X\Qd@u>4:K@Ldpwb8qwcH^i=@::j?&hjD<j:iG!@@%
C\\u*u j:?&q1j:@$?!69b@y!%b!/*b=j@+j=B6>dLHj&6:i*KHK%/mt@@%@@8@46%NV>aG@@A@4D*R69bQ@<Qc
8YwGY: Dt$D&l=wY@6uip:dkLaH&6d?lb:VN1D6kdc%c*yP&+C&B>4Y@wPi$#ck:aG&6Rh/V68A6kjc%6b&?D1k
%DY4T* :aG&6j>E#&kd$QbA&>w@$HQcB4R>$Ld&V@Te6kF6D:T6@VM>y&%A&\N6c@>C#&pd$QbA&>w%Qch6RN5D
6Gc&ZA dY9@Re>yG>D&RN9cA#&udWDdA&&$R#1Kj/dn?Ye/uu?t+/Hu6A%wi/B6:S@wPY$D&l=wY@5uip:dkLaH
pdXMm: &6d?tb:VN1D6kdc%j/Hu6A%wi/B6:b1i$#ck:aG&6j?k=:RNcH8knV=E^$QQcZ8kda*Q#IC9D:T6@Th/
GjFFw> V68A6kjc%9/Bu6M&wP&B64X@w8i$DYl:wG*6u?p=dRQcHtld?^h/V68A6kjc%1:yPY$D&l=wY@5Qip:d
8kuIVl kLaH&6ai/Dq6A>wicF6d?$nH<=GP=CMh#$e/HuyP&+C&B>4Y@wGi$#ck:aG&6Z?m=:RNcH8kdi&j/Vq6
R<Q*8i A>wicF9:F*yP&+C&B>4Y48p=dRQcHtld?\>/V68A6kjc%l:wPY$D&l:\tM@KA^$H4S:cB4R>$Ld&D@Te
#9MT8= 6kF6D:T6@SM>y&%A&\N6c@>M#&pd$QbA&>1@$HQcB4R>$Lb&Ve>yG>D&RN9cj>B#&kc$QiD^A#&t:iH>
5HeAy< i>4w@8H@SN9@k:bD&6=nGhH?CV&BqQbQ#&pd$QbA&>w%Qch6RN5DdY9@Re>yG>D&kMj$qaMH$C4SC&$D
RwC8=D &l=wY@6Q>J!&AY$Q6K$Sni:Rh9j@i%k::ucbl6h\Q9BbHB<@\@Hl/eNcqtSy5bmt^VTn9+!i$lN5^T#S
jCiN%@ F@GIZ5ed5^V@V@lXj1/j=w@Sj+8y@ChL@B%F@DNLE6+DZ8jhFSQ=DD/C%@tN9H<<^+h=X@^Y*tiS@<Hj
FmlE?9 ^%?dFj*dbe>FjV*S@YS<wNkB91!a&RFEl=4J9@qX@ypbnpiPF9jaRcK9/Kj^!imZ&I:5NPnb5yj$QGd/
8EhX1/ t%N<T!yjX=S9<NPj/dEt<q:@GB?>uZQ=#pTPXE<eu!\=:ZcC/Mp=j$NY%N@L*%uW$!y9D?D\w!#SN/h&
Dlb\4Q n8*Vh6LqVKYMGc<DQk%/P8TjiE@SFwN<J>:I?$<XdN=X$VDIdAZI4\n+/8>LWkjenq$PqH>8JkiXbw/R
nXKBq8 A%bM\&<9+lX?p:+=@FL=TNHjL4?\KD@ll>Pk8NFLcVGLINdVu!Z/T1w4IJXj45jL:*YcTjXWFiYH!t4$
FqtQd@ R<c85nVce/d:P@?eKRHbp5ZSMMu/ipp!P$Z!!H/+46iEq=mlI?eGC==*XT^t59aa*1K8pLD?dCubTyX#
eV$1Lw XVRcEhLVFXdMnE<w8Vm=!w<Y@JN\:KpD4=AX>Y\wuYX/KH45kq>$>HdGqIPE6c^uNBXGbTe1$SYd/E8y
l5nV1& Hd?^l+RST&&@?M1\akKQ^F/N>YT/9Jp<=MY$GH>jcw\^uC8<@6tQS#qLt8pcK\ba5Z6BQwuacwA%E:cu
V4mkG? TCm>ByyXKlJtt#kS&9qWim+K9h1^b?F5F@qV8l1np=5X@Z%y$btmMXV>aGc4KYIni4d%$J$:y&GFb^GH
Indt/< !+STdF$c4JtSGHN<=%/&/A*pAK9<k/t9tBdnM=Aa&>Ehb9JnW@/y^k:51BLqk<:8M1HneK=+d?jK/XMZ
nV5Nuq FT:Z=N6$Xck<\aL\a$<VP@$tiJ$<EwM+KTyJ8l^JHb!mISSEm=#CJBCu!W4l5:JYDZ>duEJNCwN?6^J5
u/cNkG ypmqIt*q+Qp5tXJkenlty1qmtCpC?q8MyJV9CahM?QkTF!nP$SXRPWemalIZ!!1m>BM1j?%WF^ZSVAnS
u:b/6e *=YwR8ILW$/MuGXdX9K4#n?L$QTjqSan8bcEqTBLZbiV1phbFwFe6G?I^Y$^e!c6jB:Q>G$tIBKV&daT
dBQJ$d nMlVp@QGWFVYKH6ewY?V#EXj@jIn$mBpqTud!qX?umWKj6F@i1K/kJ*G%KYwu+nM8GQk+EHVWS&wcEeX
-AKpC+ 0000b9a955400110334 Page 43 of binaries2.zip
JHRX9G BI+h1=Mk@*^BZhREW&Be!emTAG!YSF^G>1C@Jpln?dLQ\5%WYT8cHAp1yWw@qyAGtQKT%QjwC1W8aYYp
@9cVB& Ip1#%CXYK4>INTRXW1u8#PY=e!l?*XXK$/KLTucyTHL=@nTwQWXjdZIGI!E4tI5PaA^Sj!^VjDGLBIie
!F8MMC wEV+RIDT&aG5jBXWS8hF%??MAp#6TkM1LAXXhNtJV$XhDRyMayyK=pTyYy+45:J#XWkmnSJ@=&Lm8GLm
&jjL@5 Gw5\DqNBIl%SXu>SaA#CM#H<hSubM6Wq/QR1y<\aV&cM*#W<Q*9PN?S@?nmRpMwL++hl+dy\L1/w?pW:
>uW$C\ !1K#WBjP!u9>T=PkjM8^@\B4SEm8Tbt1q9mCKBbnBcNw\q\$mcRwMm=JZRXIk>/SBp%FBd?j=klYbc??
?/!jAE JJWw/d@uu=Wy/FITTkkpZX!^YyNmpGcklBZGV@<:?nTwB/WmhcQQ&ZJ1B&cK9Z?QYZY/NGLPw&cTu1=I
^l=NVE FdT:wku+aA4KPW?#wJJt86+#Y?P1YcZCM=Jkm:wJLl^CQ1mYc>HWZ<dS%jqMq#tj95#NLyNmcS4EjFBh
8i5@e= >c*tHqCV*X\Ghlm?D9V5PXp/!!<YXc\q1n/!Qy!qti58^p%ZiLZ#e%NSk>WcMZ:?1%cQ#9Sk/FwNctDX
SY&$@T ndNk@!qnMlK\=T<*Ky9h:p&E!RjK%DjaYe8MT>mKTjTMJGdWtCk%m$n8>KP8S#m\tR6pA#YR4^y?d55H
G\i?@p <nb?Z<!C/i$/dtS%GD<NV%&mJ4y/E:i4>Betph:mjyqkEKT^Wq+pQq\WQ1VmVYXmdI41?VCyyV#y1EuI
Xw=p44 uhSQ51MnPweu#jVNWhI<PXqpQ*i!w*y&NHl#<9+ui8jSG*4d+KS/<9+p1\<GS>pJkj^tpCW@DRb9Mu4%
T8Mhtk BF@SjJ>XB<&5nue&V:LpyFy@Q#l=R=?wX8q66JMnitiS@u>WHhTXQ#phJe:!lGPLJ!t5uVVSSYLT%H^T
/WP@T# 6kWn\MnXAQIjuJl<NAM:NZMkKbw%\1hI>t=cehFPubE5L%XHInFh%h$ee6SFq=9F5DP*5w1J!6bm<Lj^
m6DYVC 6@k!In/eS9yn<LKaD!PL?E\ccR#yt<Z8t<Gu?nIbEDDb<1l+M5mYd+/YCiGZ/^RZ#Y1%8cS*$4>QV1y$
Tw9#R: 1V?<!SFR%YW>!SdLi9ZlDd*nwZ/$*KL>D^:1>Rj/+Q91y/M*!/T/4H+cXBeu!hFD</jqy?VpyI=*XyhH
kkYAyK 6KNPNR8Gwt9TYbAqYhFN!cJ:5XchTKp:6#Ku*cJKjtGt^Wm@MPqeNA$&e*5k!TI65ilPNjeeydya58BQ
EP9q1? TqLuNMG6F6bMFwqF*dQ4GT+1=Ai:^YniFqYSW6KHm/wRF\PQMl$5C>+1a=cy4+D1\/eBuiaFwWd@Yl\q
FauahR S!j%SXJhXE?Ppp>9pkYS:KeV?6!Auy+RL9ZB9L:Ek$W%c*+/PTIaV+=wGhAucGj9/jHJH>YH@$K:&X%t
!6ya5l &cK?QE1I8Aj$mcMB:jNwphR@+VMu:wW&n1R/YDD4BB^>*V#PmwGyG?deMaIXMBN*@^uBJ15EK#^aCXbP
#!!HwZ q6ynTVCiVRXL^PB&4/XbB11Ft/A8Ple%Z=Bb1YwG8dG4IPtS1\X8J$FyYyb!h1=YtLALQna#yIyt4V9n
RCejh: F+/6yEIeeXt6LkqZi4y+D/yekpTJduMhAwbwEb<>?WVkXD<iLh<W5$Z##WQ>AWADw#ih*J6q>e&T>9:t
/iW>BT 6*y8YS@W=!i$Y*4Q%1KiP<pYS:RIQ5&4J&>wPiChSPN$H^\:AXnS>w4&<$\Be8>C4MeFFtd@ZmHK+A+4
^iR#VK ^u/#a8^AM5JJk>u6NJ$G1qWum*>9&GHpqVFiac:KwyqZL9ZNIwqhL8d?DmhBhTnlAPijVb?%yY#/l\pW
?4+C*# b@QtaVhHi*N\<1pw8BLI8bPnp?LJy<GmiLIajKw?Y4+HWhKHV*L@@6Q:p@iR4>YjTYaT4#%bNI99TXV?
+uJS9> h4TXI/Lj!6KVp*SB*Jb\yM@?NQ@aYXVjLAcLI%wnk+@bLyF4N9mWY&T::+tG5^k+N&cLYVmbK#\6KRbn
ppa8k5 MDZTXV?5w4NCp!L>VBC4>Xb$Gua#L9AK6TVhC%R58uF4KAi+?jYm/YWtQ%KQG:t=ItTWymFkpGdB9cbK
%EWA9$ u/%9$^nMG@e=55KW8\V@VYLKyi/qtMa8:84m+ciWYC>BqdA8ZE&L%Tw\w651RWi!qD>jVc1k*Hw%yVeX
8A+@/! eTNuu#=AH/59k?GVFdEV9GNBH/4Tu5R>t%W4>Hd/Lu\&TZ=AVw<<mmeXX%!?69R#e?hFP1wb!Wc9^hl>
H8+Bpb ZR#YRJCQBtSEZJF<VeLTN?6MBZX^XjJGbuR^GKm?Y>6^mAMXI?h:/m+18+8%Cu:V8X6l\bJP+5Ce?$uW
!Li5uh j%J$F@@S?&1^L9KXu=:IGTcBT5@1%am%b/aWtmjdLA//A+SB&>cIVaZEe$4!XiRCGebHhCV$ZWpY\qdt
TiV@!% Fk\jFhumEWZ#4!TtMIj\V^L:wpKRN+uCA8c:!mI9ZYRdPDiI=G5TPX4eK?Dt9=\>Fh#tq!wt\bF5WhT\
h+HP^B ZuW9y8/aM$DehEX*ccSbFP1X<*9?&ST>Xe*Q#$?!G4LMuBn$VNbBw&K8XwZXXX%hVaK9^&&+wlPGBWu1
\XnNpP ahHaF&jFPk/D1F9qWSYWu>ZNt%JM*CyL\$iL=kMNjCZa65d4GCb%V1nm::c?54#IYliYt1\AK:JKCV8L
dy\FTR =G5W^\&YbGJBq1LFV>^y:QT/i6cD^!9EZN&9GRJnITDp!!ILL6QQyk@GqywFM4M+9/AP?PyNW^KV?y8t
htA$=I 4*^H&u#YSiW9pR6Wba6F%N!@:CHR^PTA4WD#E/y*%I&d+FB#k%WY6Mue#F%P>uMT5&EFy1Kbq5wadYG+
%>jqB= @>wZyd69#e58MbWp?MlD!CD%jhq!WCnh!b%ERidWuSmCl1*+CKw$BAXMX46>bDyAFESRuXHY*ZtpEHwW
yhX*#W $QaiSXVVV$%/&Fq$#CN$SEyTJm+=PXN^LBE@9Jm=ktnM=IjMl!#+#bJk41%\MdM+X/L*K9Yc4m$KGjMP
TumTiZ p&AhbIE+M5@E5AB4yK6ERXmNwQu9TLLIqp\T&+$+#yLIKlZ1hhy*CT59^<y%eFbcEFc=dyVTp+Raq$i6
DC@$tj M:h&Eq>pEYwl*MY9uH>PNS1RbC+q#QdDj86H>c#/lnDNHd$lS95tS=RKSan?!JAl#anWwT4>B#/nbq&?
9y98\9 BQ>><+a+<%GhNJ*PV%WRP&qI^KPJqVb@It*wy*yY4?My9jMu%4jwMi&NZ/IH?NCdD9=L?lj68Wy:iFP9
VbDWtk k&QkeLL/t*y%Rhwa9bYWM9yR=R&>J*Y$%LPV4HmXqFlXCCZ8GHR?aFcH<ePaqKM+wt6D^YBWFq$jD5pk
Siu8GS lpqcnA*m%DmRH&6R1!*\WuTF*Alb:n*$aW1:S%lp^WymGQ8Hm&GF15CLek!!\RMyydtVV!jF>+8VbV$>
#?d$#w YXdJ\5!P!Q=ajH1wp!YDj\&1:IB+e*LEI8@wJK8T+bQXV=bH!euH>+Q/A^B=1GjLn<uJi%KCn8B9IyQw
:dBnje kja&INPGhK&nV*ZcQ^bPXq%&np:t>Wh@pDW:?HTTuJAl8@^@uR^Pqqq>?cc=QD1y@*!$\JeZp$@%w\X>
WCSqkJ ajGQ\XH#p$eVMlQMj/JZV+ww4nmE+@T5wmZ9tVccBDN!^ZbNk&=bnIIbynPdN<w6HR<!B#aY@Njt%Tlc
GWHny8 uN6$Qp6<ejQXX&e^=KTaq>t>1iem/5NCC=KTuuei1tuTYSV4!&48KFpebYijnyI@CK\@1551AWY&c?+E
TmcFJ+ 91Y$iERG:NGkC9*lbEAjJuIm$q:RZjYlC6&K*9:V\@91+temP<L^Vi=>@V*>e$p\N4FWqtR\Ed$8Vp=!
4ZtPd+ u=IMpJ<Mn9Bj5yu\H4m158cubQCyjpkeaNqli+uk@XR<PYp81:Cdmt:Z8iZy#qTS1TGPt^uhtEhAdV@#
NZ>c+1 Y^TNMD%>$ML^@q1$J6Laj&6=D=t?#=lBSLal%Pi=AEWu^ImJGM<NBJ:F9$/h*yFnWZ+1<mXeG:e$QuGy
Gi+ujA +%&j/FSuQ:?H5?>Vl!D<L@QtRPkXQpQRc$J9YhVyFA!IT86Em9SB$G685YlYF=<Y%TMmTD/M?1L?@tSR
j%=PRy JYwn&?mI@w+GJ?^:#JbE/MuS<kFWZ^\M*5A>PclmP<F@+Zt5Lu?1Hy$5p=@iF>?jHiXwH$jCEuNC4$jL
nEiIY> EK&K:M=mqN%w:qkVSIqK:tJII*JVZ/ANTWTiQFWMia@mSA\PwcD>P:>LnQ%yADu+4BLXAw1clyNECW61
NYPtWW pcW^WcjBW^c<qb:9+cpuy8alVti?=/\a@*/S\IMVy4\*J??VV:p*D^&m#&X%RLV#cY6By=qw=e*Ddy%\
cA+wIa kD9mKK5i5i%KZJ4aJH%1$F#Yt+9qG@=y<A:@>Iu\J#A@Dany$8jwhuEEq4y<e:Rk$BFQIK=h4V:<XGiK
tp@h%5 yG@=nbl^5@4R1SKC&etmjnT9j&w8*6hlBKZXV@Vbu#:SRnk/VKQa6dn\R#1#4GIQ&^V>dIVp%T#J+6T=
Q@T$tT pAP4W5+MeR5%1t/j1lX6yJi1@<5C4tutAq9m9G+uTIVYuZ48uqh&WA!J4KaJFD%nhpZdNLM9hjM<#e:V
<*Ih*# PLkhy!4kq:/BN:bI:LcchZ+chI1hiyG$q#hH>R+J#/MnBPCP5neQJ&SiHy*RbRC6b+A+DDHwJ9%9Wj@$
bRSM<Z l6kuhqy@YNaQe^t<TM*Fy?adYkZX+lF:qhKjPw?PFulPK6VmW++EAIJ#J\ne$Z@=I*ln9Z1!:BVjDH/T
8!RkF^ %*HAm#4J&yN1Wu@@!M/p=SMZA^@q=EY*TPLk1At=NM&Ci4+TXSE^FeLeTVAd5!CLm=aHE9#*a8AY*YeW
Idb%LV yhtatXFeDhPtcjB=JS+Z%XZtGYdSwk8=nFGEHL8Aj#mNyW1I/:DZ/j*b!bE<m/#*NKu@JD?eYDK>Dce+
:4hb#/ 1SJVbah\?6MDeiVF!ch1l$mRlCVhaA*XH!AiSR4>*LEXd&uHJF>q8TeuD&?mlH%nkEjMyNQ/mb\mX\k?
y^/ML^ pdYVGp8!TJ8hdFil%PI4Jm5J>!+yk*XyGa8Sw$S#HVNQuuJ@4>8/IW6Da/%8FKiJBXBDDqPWP=%/>p6m
/D&*Xq KyRHk+PTdttJqq9lGXHPb!L1FiL>HCqppX>XYVG>u?\e5TI>4I^@9^G\TWktHtAmA/a8BmS5qjwdw9V/
dedIlP t!%/?W&X*%Nq?<mCKF:DpY1/CVF9?jZ?u1I1qXnF%bN/mH%w/FPphqXTm>QImY/FJ5G9aERT#ElZlJIp
e9<4&C 6m/Dt#=+JFiDRy=e1Du>IiRdVPBm!BQPLIBc%ElmeBTb&!*+S+KuQHYTn<w/MlM\/lFSJ+m/&pIGJh=>
@p*5Zc H8jb?#IYE<<6Nw@8JbuHPe%j1VFGT%LN5mmJNp:yTm!BQXp=ZatH^VYEGRL/:uR1BlEVanCt\!ci6il1
I=pSqB k1$dT*W9Sl/INNI?$yD&GqWiiBbX:HPZtynmm5:EISV%*!Z8DEtnd@cWMVM+$=DLbL@SuEGcQ:aTba$!
41TK// JM#Nq=qd\mXKMjP5+ZCA$IjXXw=1EXTA^Pq9q1Ca8Ti!cJqhYTm$ee>6c1/dKPp&PEm>eMG>cKEP^VM>
l8E+84 QNISqM^EJXL1GcKT<PIFSWu5L+8!i$I8yT@dWDZq/<@D&CEd$+HNwu!/aP^:#y#Z<ITpJ#h=+qlRIHEQ
JC%&5C JCW8whQIET>i6*AGA:$YLbTj8LIj!*$B>4P^:YITk5>K+!=4QVm%/8NM^PZC=/%JMnd^CKFIb<*&Kc+E
ata!+9 Qa$MI9%BmXb4WDK#wn*8+XFVp$ctD9Jnn+5cp#P*1ej!ku=4MR<LnSaD6Wi^=YJWpGiFA?wc$J^wPjBk
C=T\=Z B$e%QGw1c@KnP5ShP=dT\^?eGapFk!NHi%kW:p^Z@=W4DFpW><%C#EI#Ze/6JCNdTSbJQPbTnGl$^eib
-Aqep^ 0006a26bbc200110334 Page 44 of binaries2.zip
<hCqKZ &S$yy+6qQSkAqqDlkiS$lXw<JBZwLpR@A/wltTGJKmtLWVAw5cV@LBJXSjemb!9TJjFaViySunSPd$yC
RctQJ1 QCWRYFRMp\b@wlp8YanHbBF*nR#LYG<ySutJYSLHL!$BKw%$yVRP1AWFIB!LFcnbTRqKH4/L>GFL$C&c
Fby\Wj 6>E!dDWeHhJ=R8b?Yk!T1#y+iHk+e6$!!mqPjuBkB#$8CdY!imBJ1CjLQQ*HXdXA/t:LFE%WJj/m=Zq:
#kiB48 !qNILa*PXQDRYjy\+5YdmX5=i5I#L&wMGb18Ztn<NQWmV:Nhku+SThqampjqHFp^<^yab!5Yha>KdFP9
R&Q+\b eVI=tRTqJJS<KD/jncyWm16hHIX?+uRiL?1K\94bCeF/apuhIjV/k&Wja5dFLJKheRXVTDtKQi%JbHNt
V?9%/I WdXN1kW/K+V51$lFX=StG<XwR4#dQy/wdiNlyPJK?pG^tAd1>iQMw9myya&utntYSAY4ISp:DVtJ^bAF
5KXENS /t5*>bKNLQIXbc/=iFJ=HIaIjM4>\Dk^=&+mi51E=::E88XKD1$Z!yABpu6+YJ+EhVZ#$5$$!DbQTQlB
:SqE8l TEetjlLTdFjKWp#imE+c1t$+RBQZ#+iTQtMtH9\*LhZ!iT*e/YW6q4\SWnuDkm4G&cLFpD/TFqhh^ybm
cM//Sa FKk>4kSJ9F#b#p$YqWiH<JuYWTW8R$MhjEmNXC9XC=KTPGFCQ5V=Etu5Sk$%6ZwTQEEn=NAYHeQ1k1n%
&d?m<? W^cFKbPkj4y?=pbZqETdSdpBIV<&?*Q1WKmN#KJ1t!!#+L$TWDHai=+NEj!w^hWp&6ZWacbHTZtILI6w
LqEdGB SZuFe8c^qKmGPEqnw!HK=k%MXYSbppcl:tJw#GC!IaqPj?buJ5&MZ&TSDA>JIJap=Vqa?PVuIPa$GFCM
Lmy:C$ NElLL%I*idBmVLlppK*LilLPYCCV!M5bVIck$5cq+tLiJTG5ES\!WSc$!dbkjRS:$J*eIRMwYW$#X9iQ
A!/>he b*%bXuF\+Ij19cmjS8IAJcHaIbS#i&1yCe@mD#FaW>%XRwVISBwu8NwSBwyM4W+1Y\pp1qwVFHDX!w6^
Q54kh% k\/8y:MK?VRwQpqeel6cNITwkkpZXypiqphbXIRYJ^eF4Vj#6XMMGWSJ!ETK<tQVJJTtF?N>bi=1C/Tj
>AGak% F8N<nFA8upZJFWb8>9+pn5bt5T5+=B9G/eq^At@pEjKDnWAMu1#wN/VBDb&E%FV%hpVTKFVWt<MlTthL
Ak%tlq j&DdcTVk*Z$W5wBRV=h=wYdSR\u?Y\QhS61!jTuDK61\@$K*T1*aJYTZF>&FqEc6ApIVEK>aebQCE>Ea
JEnSDF ?=A1GdSqN!6WnlY>bD4aJbG+nqR%:&MS9CE^4WXYS\nBJJaYaVXhIeHWC+HN8&=SkDSpyy1/HDI8WuQ9
JLQPyM l9^l4?6QR\YK!<VwLXpTXiwWVdQR%MjQ\Sn#dnGlemQ!eST#qiyHjHQXaCXkR/5WV?$TcYWqla1Tu6Iw
185#C: h!9At4wHK9C9w8p%umZ9LD*W!/RY<Cm//?j9\mw?5Dn@LR%bTKuu@=wX:SblwGZXn5*kN>pZt^qbXEEn
n8DBc? wVM4%ZH4PIu:*cVBmblG^Bl^wm\K*AiTn8y:klEX\pnumwl1D4^#h@lGV6P5*n\/G9#&@8Tu11cdX6<@
8N=G98 lE9V4cTwlW?c^W$/mqHLI#&lRX*I6MDGQTuYZ$TPJw/ZbF:uy>?kNp&cbTHj$SYXa6V/\9INZj<QZTHT
b@CbDp atkXaDuTepdw%yS6h==a<\j6QlN%iElmK:dw&uaTB%mLdnw=j$mn5K4bBYuEaE%%#WJ6RnGpFacGCb/c
Kj9eFR md!%kLy1+%pediD$*cQBp8Gd@%S%B@Rkk9Xl+dH4KNkjNhXJ9DnR:Hiywa>hKtue+TGLtQNKpFt6lCVR
/\5*tp pBN$Ep=?/GhRnI1KmyHJtEb6JD^>$SQ@wnjH%PP?!lZS=4%8X4%PcVm?XZ!Keibq88Lb<+SwXZ8!TG@^
HWPp:Q %MqINRmS&ND<CkV!&cPk:5bN$1lTDj/p=wtA?nCwS^G6p+iX!=5ppJ#KkMm>uWaktD8AIW1!&JQ8GwL%
CB5Qbj dem<8mnTk=RSlnmMFK=y=da#ai?cpQ+w/nTnK&S1ipyyE8Wdy&FuWbc\$y+%=WmC>EyD5N5eyMHhcW^M
4BZj!? SbK$4em!NPlGIjjWk?ybFn^RH5y*d$5c6Z>dddPXey?jIDTN1WZXLXq!6BBWq+!1$>eQ5D+kl/qaQcy!
J8aP54 CiXSZdN5n#md4b/15hdpy$*VG?yHjGpc4NWn9Q>SXa6XbY>$@QRAicF%yK*K?pXS6aXHbT<@Y@w=98Qw
$GY=!? 1P/=qSd8MXFu$ibRZP#NtdIp#q&MQELFEQcMT?^eFT*G>JN+HCQ$qI5/\GRile6C%wCyHFGqdKk@V6J+
PD=H^Z 8SydCRXWVlplP/%+@ntWDckFqYTShXL@bI#&y<!da@#IlQqT^eiZ:+9XyHwmFbL$/jeD8m/Y&ptlPun@
\C@Q5F &@9By+i/imIGD+9FjLF+1P4=Q*qa=BcLSXNb!B9cDb@>/9Ip1^c4m&XXqaw1HJjtbH9Qi=u@JPI8G@^B
KNd:%% *:q+WBNSk!e8/1Lk8M6:nX^:/#auYAq!SXTYYlYJ1jhFn=XGL8NW/?T68XAcilMqwhGlM\YXyN=?!1T=
NyZ$G! >aD^/5%$Xci#>/cl*n:5@*QeATZ:5REJpkTXHK5lBTHJ@pT6hPtA$P5Q!\ZS>!ANFqYY@L!5Y4+I91V?
>X?wMc WNeV@Ajiq#YBM*@y?=#YEkkH?itl48/=I>46e9F\bJEy\nZ^Fpc=E$=i58J>69/dD/uqX5ahMpJ$Qi4B
:=&?AY cHqIIbp9NJ%REiYJu6=ML$nN!G+KWnWEy/LkjAn44pTTwkK6+DG!FlXb%NhHZXhyyLlpwY>dGnuR$je!
jAR6j1 DX&q%MK$ME+^hjmPmm6I@S%aPcIDPu=V@:R\HK5u:\iDV<8FKdlR1AikV<EuN<A*IX>eiD?!Tw*n$D</
SCCJTG IH6lndqF@jBl+Fw5/NZX!V?Yk<EjVX?iS<wmRn<1V!DNRnYEh+H!tqeuX=X>5ZwX\9?Y4l6!G?Qtb$Z#
KC=lV? +RR:JmR*Sjb^aA6bKHC%#&ye$S#iWcJ!$Sw+8m^P$8A+<AA&@kQ@5DhT#EIdM8dXXbY5!/b%KlAie9S*
NqeLT< aJW#Zc\8t@YHyttW#RjI8tbXNhu1\+AEac>8u5*B9?PdDpGY9QQBy=Blq?LVhhMpWVL!WHZZMZDXSP8$
CylXPL tQ8n?cbb>ZnP<kVjWVYX&dm%>>=dcW\X%/luK%tGcVFP!kn>45^A5/b@1*Yw*kDSqQ++YeKcF!cSHC>G
=K5Tl@ nW:XZ:9T@VE1N\pqK51<m#?$^\qXHpZ8<^P/ApchVbq/GheqSK8%dMJB9XHY9F#B>h>qF$eLwKNLwQQ\
lq\BS= blM6R#ScS*BW1q#@LE#qW/=i4hh@Z6bX!S$5/4lW%Y9$S5R$@:=@#!%PnCLyM!RZWM#Duu?ppFj4l%XN
Q86:G4 eH9wdPE:pqkXDb*tQJLk<d/w:cW%?A$P$C#KYuCje?n88Kw4l*dBHy$*D$AchXn$DyAiE\$PIR<6G/%b
L9pNee 5KIaGYNJ/AHt!X5ic4GCk9Pw%nXp4!4&nN!mtwT?6p/6T?TT@1kRa^h@LP6iywK5j=KMHjN@u9DVI\8=
TwC?Wj p1yNV=h@dPqB9eF@q+8/Epb#WZh\K1R$&e@I+Y&L^e>/VtR98d18%AG?a:EdJh+uK&FXa\jYD#DKDI4#
kG4+\L iPI!uKnH&p4Ll<nFp<Zhq:$*w#e:nAIV/p?N@Y=S:#RS/pE&it1NlmI<$#Gt$<\:>H4QDPnDYcmWX8XN
:LPKj< 9/c?BBP8G/VF&MAB&9WXQt#X+%6bXMGCR4tw<>yYXW1WqY4\LK8t1b>!QA%45?IlF*h8+DDyVSZ5!j!\
cR:?E+ 1M#JLCI5?/ltpeXuah^RicwWY+!dXFmE!9KF9PnSZNWc>!lc4tkcYkcH:8jF$G9TT9ueEYtF1!cnw#aD
J//nH4 q6MTjP>i6Y$8aTpqM^H1DWCWb*mGp54\#/EI&DJTZEMViu!VyHHB?p@CjSi5\<cC>mlP1\6Jjm9^\&SX
K&B?KH K+pcp!bSyW61bb5l>8I5TINiFuD&&KMSu%eplS4>wyaFS^CtK<W4eZc6>/C*Gy:I@/hcY<mJnE4pXH<N
JamX*# qiYl^D1K45j6a/#5Mi\qlF=CDwZZjjpCNW5udkH4&Rwl%jR<nV1M1hIm?*m#=BleKP%qL:GAmIyGWPN!
@^+9eI ^WMe=c*biT=GpmyJ4NNh=G>Q+m#dTN&\EtmQ\TXJ=E?M89ktWb9L4JkEM!?JpyGqENtcZEYNX##KGeXJ
E+E\qY Mt5DHuwhG9EFRib>lwNiptSS=ukY:GB#DIRuwdt8Rbi+F>iDLJ+aYhVW*&ITip6=eNy#1hI$!$LX9@kq
AqaKIW wpyu%>&EF5>YiwBDb&H*$^6h@5HkRSi%IHR<PB/KAKZ6aWn<p@B9F8iJS:%?#VYjGBFtWWl=JSwTh&L%
54V%a# F86bWG<m^ZaqWhid9IeY#>+cwBkGB1SS%pWcicSD#pWWbE^Y1t4h4CyGZ&8h&Q*1CRM4=XTy><:RJJ^X
<=K9\Q c#6c+>:@&T99<JHQtjiR5=<wS>bSh89tHueGRX<JA9dEDL>ieQ^u^Yk<R1nM>clcX1<*Yhi%@mPw:GD6
yRI*CZ >+i/+5!DMM1Am1\CN?9/QA6NDESXTQ^lQAZAQQ=^\pYe1K8EpIcY:MqKG:c5?KMjh!W!qMXQmmHdRtq>
*yjG*< yS?!:hlL!+6lEeZNIdK+>*CYlda%uqV1E$cm=qwb>+NKX&I1Ghe%4+V?SPeVj49eDibiqjZPI=Rt=1w1
+l%te^ F5*pWe>F$l#<MSlaukYelqZ#l@=$aq:tw/wGyh@p=JW15?I*>NE*iw1c>Mt/BXCKYiZwE^T+l<YkdnGc
L*6Aqp Py!F464#X>XXD/*CX@qHQY1J>WN^iFS&quyLmeC!m6:4aeYQt?myDeWNebqN/LH8!aG4nd\#E+JyqA49
LYn/lT QX^V/>5cS@J@YPi4dh?Kwj>L*CjKG@N#H*n9jPT=u%Y%ZDWXGTcLPwwH$t=L$9<nndmP@aF*L$%>\C:1
n9t#we Y4+n:8SqTK=\uY9=WM*M+V^RTRb>:eTLdhlFuV6mq?cJ96mWBYFuA5>?Wya$EKM4T%eTtdP+P%8WHCT9
85SA^8 8LiuGE*JKc:+eVPhWbKEppQ44^TTa>KwyMDuTc^$@VeY=mcu4^mYPn+$SP94En%@Ip9n=qRlbTCJp1Kh
aiqjT> 1*#P#KGaBTWkNdj?WiKBmpH\A/eikWke%^\jD8M1Bpm&BZT1<t$ml6@@XK@YP>!Dkun/k4Y!=u@yXFp@
mHw89E YdL6^MhjF#JYca<*LqG?B@X<?WdYbX&?TIHhY5y^+cj1l%inH?=Q<KVBPJ&L1/KmulPl*C#&++bE!1k:
H=LSYP XSyW9=BK+6/H^H6YJV<pV+Wmw1nJY6SGJ6S$blFZ!WIPS$k$Z#G&k>9yQE$CyCcNXS*m?IuwQQXapCbi
empp!e HHbpupbyCR\XittmT?kXS<H9YncntS&/\!NL66IFW8euR5q%%SpG:KN$&TA6b^nZ$Il!\j<AhXR@!heG
w>MMWa 1!JJ5yBQEBeMl?I8qYHi>D+yiuit8PkpDZ*Jw:bq9l\5/1dbDqH:!!kuIn1IcC@FmI<wb1cQ//K^lBN9
1KiA48 mPA^:nTcbbS/ayu&Y\5J56n:wWL+!ZYPTEF/1KblBbk?@FFWTAC+%E4/!qLwqbTiyhm*Yc^dNuqZ:k&X
K%SRY& BeLXIMwcn8RHCJm!?Ajm@1CH#Ii*VJjtL?A8aitS8pk5CB1ctSjn6wPlWDS1?=GF#t1lWaj:tL^4YuEX
n@q6t9 %1B*4#SiDMPu+n#i^NPn\!IQW#@mPHk^6Q^Jwt=6Z15e@><eJ/tK@\^?CW@Xh=hJqnMZWqC\Ik>E9SlC
cmtyuT @J@M?TRH>LPTEi>FCWeqci/H6j/G*?yXaAMRQZ!SHt$+Eh@MpjJp@PatSH:X#Plq!Flj5u#NFPFeXSh<
-A\HQq 00088a9bc6200110334 Page 45 of binaries2.zip
4Y5Rhy 8yJ^GM<b5a/J^cnA%F^$cb^wZ+!C+qbqq//$jInGt/ZBD=tEeXTl1YKaiSIZG&nqS!Da1F\=hYH1^tNI
5NZRDd mjIw4HH81MaZ<#m!JQT>\Z=e!Z$VLMW*eRDha@X%X=1EGkDCw1Lu#?lXJGuXSLJ!na/<cJXLm+jqy+W\
myj&?$ j911^aAqh1cT@4$/*K6K$+uKX*hj+K5P<abQAt9WPDuJX1aXikVWK4HDFKSImwbRVB1Q$Fpb#?e6H$LJ
TCl>88 V>GnZqtalmMe6Bmb9m8&4!X5BQpcdFTZYlEyi:y:XPwh6CqdB<u=b/<5>ecSPZelyh:aKyK9$bI>5SCh
wX\DYq El/DJVt%TG<RcekjQapD&VnbQ/u1LF?B>=!emQ=Mh:p*#P?N/ke1Lbt%u$nMq8uXYBJi@$uZFaeh$1n8
FtA!EX K!yjCAFwe\aXE@iHb%H:LY81GcXRiBJ\!FDK51mN&<1kEXPcQBhCujqc+%Z$LlJJINhkZIjPp84F6^mB
1X#nKP FkPwE#1^y188/+hW=<<4qcZ<=5l&We>m@TTpkD<$R!6NeTA9tWBp#k44VjJ6PNt5q:KH+$&a6MauTbcA
A1?XC/ &%$R**ZT8w/E?I:1LDCLCL8ybeVjkKZ!u8%ZyZc=dwq<Fd*k!GJ6b5G/%#*$WRybEWpY8j\D:c&Y8AXj
k+I/\E p@5S9FI8c1Ep4+hGDqGdHe?KhF/jFiP?6m56pb$^4I^J5V:ucyicFMlYPnGH5wZ#pPPlaatVl>mpkVBd
%=pwe> QB!t%bPHbcnbpG@<JEb8%S54ML%wL@KK&c>CSPJHLGdmPp^Ed@JFi+JM%j4D<nel*W=^\b+PJe\nm$?B
#&J/5\ p*\$>Z\b5lTZapDn*\Q98T>u&^1WytEwXN\^Wj6VSHMXR:=Q<aheyBA@XZ1$k1/wQD%<%QY&^Hw!JhF+
#i*:A4 P&<Lu4k>c?*ALHq+baKbK%#YE5M!6NIRe\@hHPEjnl*RjPIZWamG<$!ZLP#Tu$u?=a/m*8NN%/P55aI4
ZQ8WhJ PXk/C?GqSVX11!iD\j5BLp$k?<bWLQ/PV?^KkIDFM1DdHF=RBk%#TNdmH>C8M4N#14/p^YZ>^wl+ScZ$
+l9&MQ =AjVcFe:Jta4e&c#&IbJR+=@!QiX+eeihM1CZS9*&\@h1LMw&XA://WYXC*?WE*5?ejFqhtn<dDbLM=N
k@k6p@ %G\eG%IYqdmpu+PBy%/RKKn/Hm8u#ldlCcaqXLi!1MEn/$MQu?ylMm\n9c\4<c@RK?b*tM9y!BaF1$p+
&eW@6@ <Rn$HlYVAY:ja^W^AcittS&b<^ZC+BPuTa1aMF%E?LAGJEI:el?5Xw^#%ayyuMYWBAiml8GmKK&uIIcY
6a&R^C /5XR8Gt$tK!YbAX:%KJnIeW*<tPLpbcEpG4euDTJGkjF$^t6LbW*nE/nw4%mG44jYu?J\PdjSLG*imd1
+RPL>Q D$:uWVXK&$n$JD@AA?#>^TS><Th^X4QJWXWVcRE*Em=k*Y<5tYdydh&En*cR>!kR+!n1eCIK9c4dXiR4
wuMD^N @b1/1HW/VK\1T\k8/LwXM5hn6M\n:$*8X*6LmAP^8N1?#q*@TWlCTL!4di^emwjllPwV>#wXX#^BK:PK
!Cb*WQ VEcGmEqR9c$8$$eWb>FWn*A\SY<8F>eP5D=5k?jWZ*1$tkQ^KZBq<+jIaalXYk$9$AEhthYL4%ily$1!
/P1CH/ 1Q/5jnY^qJwmmqQQ\cmCCyiLI@F<%PE#BFM\4#D4G1+eM^<?<Zmi?BGJkWDa5<calL:pu5q4>SnYY<KM
q95nVZ W1<mNwKN8=S/$c1a@!5hLq*+bqFL9cJG*pP%dqSBGAy6W1>+Va6SIwKZEJplqc^?a^LH$H%1RD#1SdKw
eN#<%S Q=9Y=@:TqS#Tw$GW9^TYwNwyaKViNcywSLnRhcd$cn1P4Kd*JCB=yMcdaPytXjbd$EE5tFEQbNmHPQpZ
18u+iq /5ZHD^PR#Z=>YJki#q@%Z>JmE^?8&t\K:^ZtYZw?FD5Kp5XnhdK+n*/!$p\y%Nm9NCaMiFwy4QPHqY4h
6lj$*y KJZDp6%C:XFWi=!GSQ<pSKQmAXlJuHYalqG#=u9MNEu+ZQ&qQ1Dk@h>LIpYcYlK*&Njp6ek+=%=+Y8cM
XhtbIn h>VhabFnw%IP=8Q!aeE@Rip%5?nMCZ:Imad<^Ilt^itEm:1E*hVXQFZ=Tln14%K@Q@PLE!96>*d*u1Wj
JHVE%X NR@#EdEl:8tD+Xh>heYXPSlKcqF8V6F1A/!ulE*/CDYc%95+m5Kuae!<<ikpDb&e\5DY+QtM=tdceK%m
u84S/R cGn1nhBFWuQ@+T#&ey*<ZX\>KVGGFi#X5l6=FdH>8q\\>?DHXiqw!c+4Qm5mLVPl%!W*!CD5ql1>P#L9
9Fd6VJ FaiAqy!n!GR9m^>Y:t?<BIWQQ*^1M5t1j%lh!$jS1AL=ZV@W+kj=GD8Lw<H\K<=%><#HQRP5RWJR4$Md
@%5JiC y?KK4:hw4RiLtZZ1mX9yFnNZ$8Q^/ppp:n*h^KQDWSqj/HwjKjab>%5#6/T1ZZ<*/S6i8tkit5X:qn=8
FXKWXd Tp:At\iYpH?Rym4iR>cyeNwHeplND5bqyn1LNb9>IZEcTaBW:&KHLTn$D%?1Bm$P!W:S+npLTbe<!qV%
5//9h% ^8>pS?JSGFWRbcZ=>NVm1lmLc6nD?p<nu8$ha$KSa?IbDFHY44hk5qFBX186IS%P@AnySq+h=Pt@wchN
C?Bym^ #CLT1G6!<ee/IP*$FQ^iZuy$Hy1FCWQ>8:k&*bGbYFeJuNp*<T#Ka4X?\tDS9\eum\j#?auaqSnLi@m4
uW$bnL PAGG9+bX=D4e?iI@bm*6lM<uqCB8t91V8wJqNR%\uFZ=6Knj6PM66ZBRZPjGVn^nM6I<Xn!@whXdTByM
BlcL/T R9iuLI*cM5WF/>:HL#R$Ku4?eTV+Iq>TpLBF4@5^+S>b6<XI!R&>QcKi:tF+ynWjme1KRpGA=A?d19/D
C\iAE# @S4XcARD9hk$FZqiVYIHhCLl9YZmYa1eiy^\ZH%JFuC%QulaD8K?FPH!S#BRyjW6=Q\J5#6k?KtbXW>E
n:JTB8 HKDB5YS#bPq98uaYE1jDeb!Ijbc1G#d#ca^yQNy5belV1Li&#CG4m9e8QcH\ySlJ61IQ&jKpmCRcn?j%
IlC&E/ &<ET<TN\DcDwW^1$*6hH$wXte^yd6a!5pE@P^^lZ**y#&<@b!klS5!^YL??4abBM>WV>C+8V1kqtXSn4
cwaCl/ KwtL?l+!XC%:?GmlnJ8JMjp#4mhmwL:^*Bt+@#@JWiyCY6Ku1:\5%eT8em8EkWd&LQhy\C#cbc8*t*E#
9ZQR=c JG:%+y=C:/ARbnPtIZ$lZXFB$!!LP^9HNp:Wj/K+tyRS>\6atd%qq4H%IZE*d?lGpwZJ9/G&$<8Dw9EF
E#X*dG tdeIIu%+yel/JZjWeq!1N6+>1W4<t*Tnp:44pedG15JY8SaT9eQ4TTn@1ncQ$DP?LkyI*ju\wZ^Gt9Yn
N4GYS& I*Y>4t5dD!%DkZd*jwD=QjJ:@I8Ta9*wnhaSNdQwKKyycDi1:4+$FPF:qwwGLdWQa9V?alT$CyW:wha9
%F5!#G /p$S=85YQbE:XDSc>@*mmnKY8kbke^55HlC*Xm/tcblwZ@Ti=bq:8>\SEtb*Yc6Luejlca#FNQ8SET?4
K\9ubP ypM#1p9YncybTCNjGhupARe9HI1mp>+PLp5/HmIItaPiZYTLLQRmXF>kbH@c>!Wcj**nXVdY:6G:pQl5
TRn?Lm 4hB6LQNP=T5NIdKwp%Mey+%u+AdltSc>bm>8IK&^8T\1q\$!NP+6p$X#*I54DSw%KP^XCitKjE&!NGyL
&:@lqG FT1um8G*j:dp>mn@hQCu#lG5LVYbpJejRZYJ!1ApHn:n/R8bJVXHl4#Zm/6S>lPdRiq1Q/lwKWR#YNP+
iyP$b/ kDXh4XBqX%HXW1umWd@8hw*+wuj%>yCy?Z4T1P+=m:Sld*91npB#S!4nV8*$i>%F+l$PX:w6iWK+h^>P
R6PVZI w5&:!$Z6hJQXn6#S?MNR?SYHnZ%FTS&HlA?miw91Ty*epYBS@RtX4GB?Q$+DTN$QEQZ^XY$6um6pd=LF
ANQq5E &XH@eBcqqj$\l1aaVYTNZDh^lc1?66SPR%GGiFcMPkTu*8@Z/?Hm@Q1XqnSb%M\$:55YJ\4H>RK^llG<
$b\TcX #ptY^j$tR#F81Ku^w<9mh9?4A%VT$BM&GqecN/IMe:=Zm8jQQ*8u1JAPFBN5Lm6Gw^Nn6/11lZEVKnje
\Ade$6 m>=R9lldZh:qT#TpbXcMPnNEnlkjIy+XR!=%GQ\bDhjqn%RjXB?P?wm4LImpYB\#TTN*pdeZCbN&@G5%
@XEA%\ 1eI+V6T&K\c=cFyPFK8Nlth/n!>9DPY>u&!T\I<N*/Kiny=lp9pb#<JW*TTNP/Gu*4d+e#\iTyhYyDk6
+tL+kM F>YR?^Pp1W/J!hI$dn^W>N?hSM%?5/AGFNPR\X5hpQJXCe*&+@F>$SD^LPJmwVa<CjQt?Xmkd9<ZM>+$
LuEDuJ S#1Y5X+GFnekn8&PTKDESW1iKbGt$im5w9j<YSttFRX!ppk@nh5>S8&V+@:FtZem<TGkch!1hdY#W>#=
Wj@**J M\5F:eYX&VKc6^awKXuSl^j%JLTd!KJAw^YeYIYMF&aZR/=8HKYIM?a$I?8u^VI48pe%!1=dGY<VC:M$
%aX@FB CYMWR=N8CCK!nD8SF!%Md$=ZyFkThY&N9A%b:JA6b19hED%CGt!bqhKNKIM%@FyLWk1=Tn+qJ$1/$Z#B
ymDAPA ^M9FdGbYtD/aS4WhST@mLIdttFFCyZW$\pPiE?4qAPdNjamTteL!V1JKq?ACqa!RcHC^e<%$Jb59!aJa
YGMMTn p!@jP1tt:qGNi^uGGpKWE&@j+&&R\p@PpyNtNJela8c4W5^d%1$RjPTw5E#RLE:F6#:y<bTyNDT%V!PY
&taJ%H FLZ$btIQa$\5=BwuW=nFHQh*nk1!R^@epPQpGu>YDCHFeKIM+e?lEb!Wk1!+Ea<m:*mTlYyCX><<dB@/
<^@<+a m^cLma?R>&LYH#yRFyPwtNE#k=KmV$mQll1Hta4?Qh/>MGwLF$K5aZ=6cNpR8y#4jVEcAi%#JaKQPA&V
b+ppRK @I4t1LWkRBc/jaXT*CRc%^+KP=I$<W+^1+*9*h=NX1aD!l8VTN\tAaGkZThl/uIeiI4/uCJjI5!u$<bM
$$tqQp :H*Q1V$V?4EZM&<j/5p/N9Ik?FVelk46t4QXKhyY<y^G/qE<:mLP+\9%keZ\QWXL^A9ylb:@HA%Z5XaN
Q/WKd> tyG$e4?1%Td^XIE5@WHjWEh6wKZEB6hHyRJi\J8pYWkTLIcKubWMKT9<CB%i\!T=$HQXm:?!iP19?yqZ
R@DW:H l%i96MJNM9EQB=cu%LyANYMw$*j@T#Tt&8yeIt>/1D9PR49R^DP4XqN^:M/1Q$P?6k>1V:*B5BYPl=a%
dImV5! d5NtwYGKq49cHI^E5!d?@u$Y9n?%L4jYbcRaY4KFJ5#^JQWwyVGL!%!nd*ZNIjMJ<C9j1p&iR=%/18X*
<49!je &9$m@lWc/LPwipm1VKInDV&q<C&j5>lCQ!IhhZDW1actPK8hl4I\FM^nI1G>bJRbu\dhM4IJk^<:GQJy
&c\dwP Fp4JE*h&F@@5Vwt?J+!y<S#i1BH9j$i8@4kXX#4AyHH*Jn*i$Ew+tn8Zyc5=neqKtY9+lnV15=GE8y6m
Xm>YF& =G*&Z?G>JtK6=ahjE:K9+mQ\#NMR9FEN?h#/HhA//b#<XM><AG*CC@YHZF6dS::WmlyXV=Nm>tM^iF^u
4RZQ@? Gq+*>=5*$4ZkRWkE<c=bYw@9u+tPSYjjFKQe4ND\@kh*VqIMY@#ey+4EDjQDQJk$CielCej55^cmhm<c
GTNiIq a+n*/q$59PZ$cp9?$Bw<5YpDcWl%LQ=whb9j64nT^>Fq418?me/uK/=&R+letnK#/whe&^Wh%?X4?N<Q
R+Nj=Z @%@yki*nidK+K/lZt@lt@T@m%d@!QYH&#c1NuK:w9D><Q9%:FBCuAc/PJEqnn/!jn&VFnbSF1py\y<cY
mKT:al eqD@at+R$*S$%8^#cYlRqK%EqJL+4GaSC6p1ZZCe:wj?P&F^<AKKFpacp=&=QZYl@B*!>Qi8LM^m>B*J
-AV$DA 0005d57b9ef00110334 Page 46 of binaries2.zip
+^%mC= /wA%Q:p8KFb6#9A>K@9JdMm+9lcSZQ#=apVG$SDuFjJhWV1n<&F1j/\ml+G\&1%<qX!n8pnLMF$l\bmJ
>R+@kw yiuKpSWDCc++tXhJN+*Qe5S5XC<@6?+m<R1I$?MmH&pc@V@:<%CI=P@RcPkVH96c+@!MhNWLHG#qH&*P
eBH&=R >P@Su8+@G6Z%b*wM$%%Y/VqJX*lMuMMhH&>ekjN*/Fb6>5!K>@:iWeebX$u5Be9TFhuD<mn>ablS/te\
\lRSRQ t6kSe=WwP<&:nZMj?El8SV:WJJan98Cn%>P$GC%BD*\pQ?:nB*pWjWiIicbS1N1GY/%KI%@1pT#>p=S^
ae5NbI ?St?>$iCVWI8X<^INM+cM=p$%mPCK!uPVdT&aX+9E$9$Q:%:be@^GX8X1Z??@$F8S?^$lWXFTemja>$!
QlZu8/ eQY@5&:VH*5jlhWayEX1?h@Jn@yqLBjn=!56PXhu$j&w%!a^4j%J!1^R!*>Qu9=ABjGR1qX?p@!J6/V8
FmGmMq TX1qH8M6j=KhcSb4E6pQ6BhLei8Fq5a!?wj:6QkuYb9=pV86Bm=:Hkaa^TQ?w5GbNp+/KwqjKRFPXweD
<elQC4 ypu$?ZkTR>#?JnSIKc=Mc$lClYMcuPDl/PK!+?THd@9lG>PwM&u/y?QIXu>V/D&hlBEZ+Smn@$cjm4@*
LA86V! V<i#tpCiiIXHMX66*lZP^w@CKIpZi*Tt\!8JD%L#Z&P9uH??8L\<y?9FP*4\D4j$?QL!+q18@PD1<9wK
#eu\\@ %$9e+5Hwiuk%Gw&G\>GE@mdnCY&#<YR/\*Wt6@\*9bulTw@G>K:^cElZ*kZ6YL/Q9qm?HZj<lF/@^FH\
a\T4\n e^\Lj@u\t4=9NJ1M=Y4:u<$t$\p@9Lt=te>9d&td<<$NQ%ni<uXyt@*S@=b+q:/h*p%ZZGk@W#41D#hV
J9%W%C 89L^j=nSM::\t@FSim5j\GS5Q?ycj6dX6b+1Ppe+T/QStE<N:RkHS^h<C@a9S+@4B=\m:F&@aM:Hm1Pm
AnA^l# q?Vp&Ruq>?w96%Q>Aj5Ki<CS$c8jM#q*lCiDKmhVpAY5X@JHpD1wepeHQRT!>L6\/NQJbBwP%i:\Hj!h
$=#S#C iMLwA=#lNi*kTpDD%%:I6=<L#JeELS:!c1Pu%%eZ9BB\>4CT<G&V&bl@&R^udIIdA^dICqI+LjSp!ShF
Xh@V*% hY:A+5Ge@?V66*M>KVeE+\&jh4yukPuM+dpBi*9L=@!Gpb%PiJZ^cl%h!btSba9HDDmk=%NBH/bQ#uHm
kdaIKV d!JeGGSdNu?VleNZBlb9np/wQbDQKlZNlHytAm#YJd&TuX@n:P1yjZe8/NIXqHy=bR?8:YmXhwbammQb
5nR!QT ^p!9DK\j\M%M@t:$\w8Mj8Fp!MBiAXpG>l*nmG?Zb:K+=JWLYYH?#W!9B8\EtI:qbnLtH+njNhiLQcV#
\89&KN hC6A*l1akm%RFiyYAuh/bRL+ILR1c*Q1\M4K$ZQPb*a!/ZX/T4Gnc@=lm8wXu^^tb:#1=4KM<DWjqPwm
eB6G+Z u8b:y:?q\G4A#u+AN1da1d:&kSG>5XW#I#/M<*lyqHwlZBB+k9*T<aF8tYT9L=%a4\E5IJwMtR5DY9pC
<iwiML +d54tA1HC&\L&F+NbhjMeC>pVTt%ZwB!?ZXAK>JAWFWCGM4ZMT5tHk#cuW!WalqS*mK&^qRKYG@%#un^
e*Jwp< p1udaHXP@AHaVtuhA%@c:\it11u?GFCWAW9myXi16X1:HZATB6NSyd?l4u1SE@N=IQZyl=t#Wh4#B#%Q
&XLl/1 SLB#+Ta+8Ilij<A#mL4w$a&ie6wq?DAS++Y!SHC?h$Itq%h/9RAj9I\E^\1>E1!M:NTIXYE%SG?EbqRi
=NQM&h CThtp8Xj4!6Iii/Fpip:pjlC\!\RYF\=4BPqYIAKakY*WEdMJ$i?iHanGI6IXIKq//%^bZ+em%lqLe^&
RlLe^\ y#e1#*m:EVu4JHY4HLY@&>!5%B16d19X:CknG9GlZwueGI$bYJWT6\w4hleSIP?h>@$*aVAm\%uAtu!N
MA+Tkp !H5&e!1%uVCjb*uHFDWFH:=!YPW5!1M4ad&Z$HBaGn1w#G1aiIdPFWYE<NFHpBwuuQ91bqa5!DLV86L9
l\y&nk jCemZ5W1XCh/SVn!^bYwdhenXhWaYF=JE?dDW*+chKidRHpKknBAIW8X1pGG*a1IJVw$%Yptik*V1J=M
=Fy%Rd MM9y#ElYlP#6:+S1w%dbLJXd4Xd*8E9RE4cmX8IEmV1AbTi4#nm+AD8X<#>#VmAunA>&1Z4V*KlQIVYI
a\AtG$ =eq+lY1u#mL=yjQQjuw9Ly$LZ+Nitj?SmL*?Wd/CZFY&KqPeAhmyC8>XVPXE#k%aynXc^TQZH@GhIqdj
M^HW45 1S4<D44WP&nKen!1n9ByW6:QK4HT1tnnMdC&h5PyEmq1\A4F#q$>pZ@yJ/e5aBuhKhP4up<kEWn&h9C>
h6SAKZ &Y\$G1Xpe:MEiu*S&tNwIYT8IYXGT1<+Q6a+wDkb5EA4KCNV%b#$cPWRXbi:5TMI/5551Klnj$%+!p#F
p5JFn$ /=V+5Km<m11T/\WLXQ!D#:/w^E1^Ipj+JA@q5KiBZHuSt#Im$p*WABE4W*DQ<aR=/qB+<dX1^WTq:<T/
w6pa4Y aXa51l#8SL+!b?M9HVN#E@PB^K!RK=E6L!!VMVj/eH=n&yPT1/+%$+69nSujBq6ul6Q?+W?<V>WyB8DF
XE/KK: w=%Tw>61qDdykph<*V5?dnWd#JBH<tjGkky@%*JbK=6Pk$wYM&I=MFZTtX/uK>Bmw=<PT&BFS==F\IIQ
j>PiJi R+NlYTyepZXR$C9$JdXmXhE#^ZS$JjR/GcuYyHba$Enq:M&D*anj\\^DQ5EcJDM6E\Hu4AcdLZ9^#8R4
$A<Huj \<ycPN8DK4FaynNdN=1hVZSqCcKK5auaTCVeC4H?Chc@GcW4B:=SGY5ue#yn:9^lh9y<a/*WIG&yT@Tc
<$Ftd< j=\96MCIY*8+Hl<j:#a/A1&aPW19W<FXFiK\d:XAnX!XEa5AF?%&yuRyX@#5CTQK1\XLi:yK5W#H\wjN
h*&P@V /qCCXS$WYPy@:h^iKeGKLVpbniWM#%SqEpcm^#a*n<B6bByMFXu?9B4#F/d?tu\FG&alc/\nNymF6!t&
pT:Tiq T1\R8jL#kn/8=wPcQLjSXa%E$+yF=kbk%Y@\aV1LdWcXaS>Ph=@hjdpn%69wE4VhS8uLq<I8cLZdP8d4
d8WJQY *9Hiec9SdDQFKn<dm^ZGF8#6*GT+&K+56n<EbX8P#en%^w/AXhNA5P\\WI@MJIlcN*e@b!PnR!JTwa>L
MIyVel wh+4NZJ\a:+tAZi+R1@5WVHHkJ+%$Su%4N*iBlZjkaYIHc4EXwy>b@#+W9YwC>YHGXlcVm1^%Cke#<cV
PWw1Al mF:Xjta<y#hti>/w:ZNn^w>JMJMQT>cL#ipp*mBd?B>?eLQMy9&h\6&ZjKQSdVPJ+qI8/<M>kE1w+8>6
lcakAY 1\hWl!=j^VPlK+k6&Kq:J+I?:Q1:/$&1ZW*$b5IW!l6M=/u+5wJ#:<NM#X*m\?L?8ScDSpAXKFY$Zy9H
/t\IlH S=?MaL/KpVMWwqHjpl:Z$qR/WhhF&YSnk\@$k%E5<?KSLJbL6dLP^VYm9pXX+m:Wm/MGLNmEW15/Fjup
*5hd&W 5bhCbK!eM1aHR%chFe1MBhqdQpk&c@q$*kS/ua1yM%8q&hdP6:9<b8Yk*Y8^RG%%h?WPn+:y:kX^+?+i
S>DPJN ^G#Q#S^%i#wnZw1GJ6/5G&HCiy^K5LLa>IAWYGc+<LJNtAG#FTBIm&jG5FZ%tjSlht&KA?lcdXd%Sbm@
>yA4kQ $$A&cIWLS</WwI5!4T/hW8j1wy8L48KPXhbpFXbVmm>W^k4qm4jmZF%j8y+e%6EK4Mw%^4MX=:TIHF%8
6&>\/K 41Qj!CJ##Wqp4c!/Y*&nYdCBXMZ6$d&@&/#XD%:9H<Bm*SW1bakJVL4da$#yd:jSG>wJGm5n\aJVT?jY
^%$51l @JW#ZV+jXk$hhYBH>AyP#1RKcVyl<\PRmqPi%hdJ%GDq^V*?uLF4p\EVTFqV8R^/$yW/uS^XM*PaC=6<
tP5<66 hji5uT+GXe\H@lq5>QG^+5*H^=Q?tKWq+kDaLX5:LGQQk<8aBaQc#myjYc/#icWmANT46w<R4N8eVL*t
j%M%E% <XJ%h&/?8tkBLlXXN*8bkPRp?Swb>#j8Nm8%h96kj@>A8LBT19/BZ9ekZw<di1AVZjtmPMpJen<TW?1N
>mdMbd mXm#9PEkNm9H=T8L$NuaZG9Ah/^mt\$<GAY?wyXi5@PSAu86\Iyw9ZD6X%#@Rd/1D%G6HDFitdjLcqQ9
T\p!K6 1&AcVyXk@999J!@/L=y$1hj1>WdhLy&DR#ij^iq%@thk4>ZqPlpy5Ec$DP6+:H4mLNC4!>mdCFnXAqT9
J\#<N# M^hn+MV1HQ+R@D4V*h&:8%1NED%wN@c4ALddYpGX6iHnXw6aeG5$aTXA*Dc<+Kbm*4Qt^I6IHRn1!w4y
DjbR#P >Wj=1nmNBXlRy5weNh9H$<uMNK1k=E*QQ\>bj^tcXuRy&Ly*cTXE\W\aJ=m>bCLu^tN#V?yl5$Ph!hYD
y=<=Lp Z*B$>%@8:lKE6Z46wHJ\5H>Rw+$8Nj^X/:Z1aiX%>VYh5$Nl!BLwWW?acE+nE\BG4l#/k#a<WmjWdCZ&
MK\4K! aR1!&D6tZH5<\H#FT*e>?VwWV9#BbF6=J=<9qilIZ^@WPuV5qZyD\XSaZ$Ah:5HMIiPHSC1Vc/?4Vp@^
pW\QWt PPEWRRa5nSLqi%SL8#H:XSuJ4eyZXaMIStQC#Heub4cQ&ip?MY*bX9YE>GG#JEZTTcB%^YpIT>cjYQ#J
jSN4<R V8>+MnMNY@%4/64$k:<=Qi$*t:X/yjc/6p>wXk/1lC\>4Nh1Fd14HNb16aMcQc$jkI!4%Y4q<LXFilnY
$jD^$m K*XL?@iGeAPWJ1aK?*WP/hnM88B:M41X<^eJDbc^e#N%lGB%Q@&he4=WKN&64bX1FSB54XKyNBy:VLC:
1T!XC+ i>*YuyI8Y#y>q9i$+L9NWuuZJIb+ED/I=tR1eaDXYX1k%:uKX>WABW9>mRyyeLYBQa69!KWR<?El^+AX
&@Bl@< T9bCSJFYJ%l>wE=@>TGKP1d^SZPW4Wm4jy>k1?\#kyXcyRw\K#Y/&\jK6S1DiqA:BPHYRMD6Yy9k4hbj
9LRjQ+ t@Q4YtJ%F9ym\V+$?e4mhTV^/:GEa1Qa^\!Sp!leGDp=qVBehX<=/Kpc5hNb9%\8=jPEK9%>IX&+$cyX
M\#6\c K=XTk\l##$V5Me^Z%y%$6a&d&+Z!?69%pd9Q^%M#aRPQNWq8TwDwuYydl:k/&/:tD@ijQjc4wM!ePHmn
B6?iE9 mA>Qk4tl+F%iS!F$D?YE+KL/6NZieHau$6WEqc#<ZTLW@Yy69:=j1XaPK5D&ABD9E<ak+ewlpY+FYA9S
%jPw^? C5kHyJ:WckS6FF9!:+Xku^m>nnt8Q=RA^M19t+lR$!TDG*e^#wQZ&KQa/pV^+=:h1FY=Y>ld@$cIE1b4
ea&#eG Z&Dn%G86Xm%=uC<hm+8y8$eGD6*n4:WuMc9i>6&ZR896<jFia!\1<Xnq@w&iyMCJd<Km8#H#i4+TX^jS
4k<jAG aq1mtBK4%+u>J?kXyA?Lw=eDLAE<X=KMZC>M9k/NHb4\EGiH4eZa\AiwBCCIqT/k%&1NWK*mWc%GkFaP
1/SaFQ GM4/Aj:$pXA\ZSwHDYLKBP&F89=bA1lkH<a?J+$4MRt#/kmtJibJ:Dk%D?QN?+nn#TX/b^1weWk&R/d>
pZ6P<W <l$8c*hj96#hjhp5%R<1t/ZGec6WKyVF8WR$Kyw\KeJ>1NDnj16\>&Y6DH8HDJ/8!Xi#Gib#m!A=5NF1
9F&tA5 W*@VQKLZD/I%mbF1%Bp4nYcVMDh&j*b&DuEAJ@\w+4=Z%%e4JBwJ&!kVaD#^wLEj<hLX!u/nZkH:4RJb
/lAbuE $GkF%M4<8Fwl*cqTp!5>4\XR/$1\^I$QGkh6^9cRZTY!1E^#WliVlPpu+4HV1C#u^5DH=9qYH+K@?GdX
ZX4=*m E?9$/yEhaan5LJkBXtHAc&T=$kXi@nJ:thln&NynH%ML?6KL>@Tyjt8HF5DcZjta*W:Hi!%V<WV<*Ym$
-AnDH% 000e124ed0e00110334 Page 47 of binaries2.zip
ZtL4St #wl^9k44*$KCl@4>NVe5a5CGyMEcaJbqLNpGp@QQ:9kbt86lNiuq!9^NT4tTBtAuX*JRYQVjYlkK+iDV
lRIwRj ZTdLPkNJLJn?TKbY<A4hHqSbeVwkKF<D%aw^ad+nKme+ceP%*cDHl?wB+^Wq4kqSkMj5G+aiya+hSqPV
kQpm$q uqVcTkDStLEGA<VckXC%hAw=q$Gqth%</BiIXwXmTddT\eHLZ\KWSKi$>eGKwT+h:=:Pd$@:8\XCqYCq
I>LS#& F\ZY6/*h5S4=\6b8X6tck^w^aR$Q#<*MqWnPSA$d%+Mua*ZPV/I\!HR&WRQ?e#bl<=tRk9CKXKTadF%D
<Va?&& =nmwPy^EHXbj>E^XAn=k$u@JqAF>Ry/CEdNE^SWmqtW4Tc1KT6XKHYyVDh5Bdwqe/&$qYyA61QdRp@#e
AQ*+W> JYL/+Gn5epGn58!AadbpB95HV</^%D&>*H1<e!uiSLjNRLG:h&VjMKy*t=6p*K^9*lXE:#*i*h5VF#>8
nW^cR* Z<^#k?ed*$C4c&5FGLHH/uu1&uFPVd$WCd8$pP<<p9p*H6l$l>QMky8mVE\t1>5+Aua5kXu&M$/ID%6$
WL\/&L bSSw$n*BK\Dd@$el#&km4p?lAe*LPn%6EmRXy5<K>KK1wk5%8KJCqyXlJ64>8lM1+Xu#T$Qw6wt@Sy8I
y9y5+A 6mQyJb^9Pl!d<R!FGI#anhwbc<XaeBJHMauDAjPd&T#Tmt?NQ5TT%ZlF!F>:<d^El%BC@IcQmMm#ASde
/hqYC5 l%FDX@Bkkud*>Qj9#+Yw%?:!=bd!aLDl:nmw:t+PCpt/?n*Z#Kcd&/Ct1#!#9DB&KeZpPtHjjLCQuYdN
<YeiGu kCe?4EtCCKycSq&5HRjl!ne+4$19+yRR%/idb9M?WN&HLGZF6<LYDcFZkXye+V@m^R^/ZRkY=w+JYcNT
Dkb!Lt EG16*TRb1%jm^@XDm/&:V\TwP1^KGBNPXlc@t$LL\eqb5GW%MP6TN6DI:h#!Vci:P\*m9KXTw$^MyCHA
&^hTT+ :4G%CplFMiL4#a8NP+P%DQJ6Gc!B4+#N9NR$bDMeFNqd=eG*!wYZ=mSS>/ALWh/G@6Mub55:4GPP9$<?
9n>aq+ b&NSKh$L9&K<B59uK8SQey:SYIChtZmXa=$Q!Fy>ZXMdykJyCtljt=JpX%cjkCbeFjT<#q!+LnK&LwSL
ncCKJQ kqXpdKNBFN65N>46iqQb^WR#NTTYI?6!QBRCuw1yQ9NMBdZ1Qtk/YuBTMIqIL5ZTV/bwNKhA6XE1IS8m
\mi#\W %?cnKnHBElPGi:?qNLuZ/5>&kiwZ\JyjQ#/Yq@H9^plh%$bR$\B5>G&*1m>=*D>ianhVm=MEW=ZSHMtC
\L#Adl h1idaKFBtDHy\^QN@S!!:PIA6mM/mt#aAC\:+C%YNnMQGa+%6!6c4WnSk#1+LXPymXnl!w\1/FlkFAZa
MiEQ6K PDE@BwuYlXAQlX^4RLjhdua/=qR*ZZDEQ%PhmaIyY\R#>SlQk=8CWR%yYCF5N:i$J<L+>*/#8d9iIFB^
TVN9I\ !TM#kw?#WmwSE*:Sk1yp>Nw/uyF>C?%1nSTtAqm\eGn/X>hmEly?$kV&RLFLDVh+JEJYYQA*th>@@AP>
F15h&w C4mnCd9cSCA1HFP%:<duu*qhT%a9&/c4H8E@!%hL6B8bl&\1Vwp=/R=NXY1b\>cXPQhl^B/!Jm!1E9=L
jk4uT@ dJt5Rdbl%T6^+Dy^k??FXPWQq#baMbC6h<Td1LET1E$mTec?uDZ@hG!=C5EqjtNS&XpW*dpNcjdEeJlX
E@:NH8 NMyqwL1b#^ec:ba\bGLJeET+WuV<ht><Yqlnc5Z%cXhA*SNa^!In@J^L6yCIYKaCT>RIYS\tES#aEFj*
Q@u&L9 5PS\QLLNW4*G=6c!aC#!l!ZYycdL>Tla4KQ@L1#ZZmk#<$#:?j#:Vppw:#X#&IPKZt9RqtwX<VLJc@5%
a^A9d= ad<X=445SHSP#Cy^R?#ZJk6dp/<Md1QddTBZh/J=V8y6M1?^Jlc:8+%q:DSP!I^!%p*GDkbNIcDeCXJH
8?Z^I> 5ckckDXj!Pj9RK@6ZTTw=R94#IIX%4$Z8<j>P#X^TdT8!?5mhHiQ?XlGdIEb54PJi=&Wal%T5XiZ6:i*
V#RaRI IR#BThARHwFK:hFIPDH@iHbynR!P5SRlbPj1q^Jd=$wIXtyNQH*>tl%P1&F%!a\hc*ZI#Z#\w5VmpVZc
A/&@Kq Tp%RA+$TbVJjQ1kIGePKba5X*mdG9SL$aYHLDdFmIX?dwFi/1VecHcAK1t$45lbX^?JX#+R4nDMVS?KF
j8:m<C mi6cNI%$b9V/@RX>#+BP=PDFd15F@p5!6Wt&/6%huqVlS18NQKb!/R9bPBG%:4ZGW>GCadN?Ac^h8Cqa
Hj=aGV /LdGw4P!*nwK1&^5@pTyB>GCE1bdTehbi4KE?j$%V1i/$bA*NhnFJ/P?Tq<=VLDuu/hVPV5m6yD/P94S
ta$L!W q^mF/WcY6Sdu?hP*:=V4IDFAK!T:V<L%WBXhl4uPXw*e%BHVki?@L9AGXA@MNcGWT4ihYq8bMEGLT+@$
LDqjBy q$c#!T:lwRJ49kylSyQIe#1dKdCV*Yc#ybXK:lEk@TlQ:KDYHCm1bhcX\IpB:B&SK:Flh9AZT86\S%kK
#9B\LA W*jTL=HBCqIqt:Y<%%ib8+iknl@CcKLl>cHE%>W5NQ?e/MYTc#WZQL*iV*M*tQ+mX@CIa^&ekm*A<lPL
m>\KPi eEqJ!+V$aha#&BwcmlE4jmeAmBnQT5JEuAWV1*n>b/ZkMHIdXPW4\uI1TC8%R/nKB\hK%BXSli9+pHJm
SR^<q* 5*ac+ueT/Xy#Ah6tdN9Enb9Nbp>qm\aPLW8hA>C8Qay8N?+*!?%&8>HZFG@l^j&hnXK6jXC4E+iAh*C>
j+\m$= LDK%lC<V#p<<tDMQY%$pHjcbII@BnQ8R4M!B9*\y:<HL4#!+%ieMJBaTE#4T$eV#hqViY/J%!I8$=Jiq
^Vyc*& C%jZt&cT%lVTjtn>nwWJ5&EkiWFYB5Ei<nHmhE!+PIclPy*aSk$imqZQw6e@YYCSV6GL8:\+hFY9=d6>
?\DSRq NYRPqTunW6ZR#Tbj<9^uq$yJuE<HnVyAddAX&=c:llM5$R/hbXARIh5F5k!4?!YGK@G4mZqti/&hWl5:
X\&Wuh c#R%%\mMiQhbwXR:cK5\d^C1yC\XSKcKppcA6wG5JL$kH$K$I1LI*y*wT:B\%9eeXQ1jqnZR6*eLyHZ%
G^1uZ5 YLEdDTiSG$e>^YL9BA@%:ZK%THL8bbIG1@^KCZ!\/Bp11%IbNJF1kPtE?QB5E8V4WJJm9MbXqiM4%=CN
dAQ?>b Da@EDaAA=V4BCqpww9YRwYW!lD!FM^m<tEpY6kLAJCX#M%@cLJAk+<5td<me*>#i4KkB!/4\AYwq&p&&
Gb=K&? aD6!4ktAB6ERbB=W1F%b1/NRLDTJjPSM9N*hRlN4w++%5188<Se:>+XNCSwh5D?/ZT+y1q@!?Bd?P4Kc
lZn\b= 8?D/q5@EcnBBN>+X!R44=t:>q&MD>bjYm^6^=W%&G<Tq<#m<wPAI1+^ePYc9P1%1Gy*aQ%+n/jp?E8lR
hlniTF Iy%IDlZ@jDZw%hcbVIpQ5^=6\LLVmcEhZbp61^=mK:t/Hp4JFV8H??W9h$RK6N+QYd+K8S/!n:DPkVmR
bw1DW+ +i8cSEMa$pKlXCk>LV&q<!kZPy?qe1%WA:l<5%qn9%&NAIW1HPR4EP:mn&@pZBQScmBCQRDnKDbL%?dP
AaCSlK N9HcNwmj>*CMM@X<??+P1EJ/C:uC1%>RJ*<J*!!5u@pD==P&i1BZ&6b:p%==VTR4!haC<iA>W+Xdy*NR
ZtM$@F &KT@Z94!=W8?*BY#Yltemekjkb%:CFl<tuG\W^QZ#C*BVH$$<aTkwVC4<Ynp*u@Pb!M?nPWkhY+VLb8S
aMK!#D 9?84aM8GWL8Y%&9:kSchmqKH%u6hTJb>>mbiRdnXGw9WYwWRBcRA6X\wAW9GhB%Z8nRW+lIlT8AT4^bV
G@#t%W 65E$a#aPeYBmyZTmtac/nX%I9hd84pDLb4y+Wee>?bt>HXyDDSZSNbB5w*ueL^iAZaQ5KNnI+QyR?pnP
<TIbq6 =8G=#=jcK5*Bk/Gq6X5N#RKHS*>!ZDC*IS!H9:#h??Z+F#FwZ\#APkuWA9=hBySD4hPSHLc^lWw+Lebe
9p&bN: FFd#y+=l#W\I1E+u=ybR8th!>cSH#yId&:KYat@\aYB5LRJG!NLqNLdSXS^>nd!LI@XJnCeN^KZ!IkqX
#?@VYQ 9uyiC+#at6H4ytI16J1HF!he!8WGZaF8a:*FADQ6%81dAm=VtTyN8LDRI$\6=S+KVY8*Ad1X<>d4>SyI
$qPHnC LS4*6k5mKh85d:YF<4il=WJ$H#CwB\I1EIdcS6@h4mq:cDLB5y%n8cSpq@c?KR5t!Xyi@?Y6aI1w*I9e
!jFiXC :j#*F?W<Y#:=qlC1WI8\E!?QWC>hTKK:hS9YjXBm9uIi#G!1$6Z5Xetn%lIkRVa8Y$K?lJcqTy<EF4BR
@JJ51T k+hKtZGGp#wSLXR&ISbMNy&eE9H4Nk=E96cXaQti:AZCE#b?j6P8+TK<F@DYCF6Cqw!N>XabbmT+<ZdF
\X5/L> /bb+I=E44pTuTAmMVnn@NRle9lImZiIqlG1dXB<CS:l1HdHeS48Y#>iceHcAAVe=^I9n:!Am!C6I>5AE
dyd+tt &+4qK@n\hNaT4!Ep/#hC>i&^E8#d9Sj#&?<:Bj%*wYh?9PFIa^Wn>V?y9luXte!>nNMeV==I^AR:qpAh
ytHCMi t$*tc>K1WjGM^@KXQW:Ml$Zj+yY\a5VG>HylFbQ5Hl=Piklj<eIZE%PmMHYu%\Q^JG$T1k^y@9GtAS5R
uMQZF% bXp1D!9CkWG+bG@R6REZLVNqF4h%Id\tt^+wWi^148eQ/hpk4&/LF6%&cj&+&&=*&w%A:AiNnkV4D=RL
n+M>D& 5@kY^S6cG69KB!dN&e#B6?*ch^*Q?8W%e@JD54:>=bhjBNm>F@*B<&j8Km=Ja8JpGAHk>dCYFBbmECJP
9Z9AQR *cXwDY1+CRnuK$ZbEaKTIV9WTtV%dHGEpt:PQ&5m+>mnP5l$Gp1/m:TB8A4Sh5%bGQZc?T<MK=$FFqK%
6^bL@% 8kN1dmi!Wp8dh\\yZcE!mYH#q+lcc+I8aN%pAKE\kT?*RLkM48\M^C6e8NX86qwNEZi5#eD+cFuFDABw
A84PV4 >H1F\u44:i!+T<CKHhy$Nw:kH?:1R1mkaqA6t#1SS%4JqV:HjAG::<<++YuN*MF:lC1RJXnj:y&iF4+J
<9cCKN +m^%&aRinmh8b6mhPE?585PLT&?mC1Kd1BS*Kt%ub8b6W6p/>6ZCC$ch=N4wa<L>JY:WT&YXWDBil^JV
qL8uLm Z@W:8h+$HNZ!VK^jTl^yChiG8TVak+V<VAhXaRYGphG16!ZGdSQ\AhyTHem&tHBdELtmH=iEH@PJJy8!
DjE9d^ 4VT//>VKGd&6=8:h6?Qna?KR^*$A&*YZB1E4Y4HEl>w1Z*F:mHkSPHG6a>!a&ZG:JX@W:i/?uWFLZBPd
%la+bi qc\d\H4<C#FkAuiQnHnJ1?Ap6^cm?tN*CnkCW1+\X1X+EuWQtAh\A/\#T=iaBZ6<NLE\^<mLdEi^9m*=
JnH:9B djBL8Kh1PIue@^Le5XJGc<$FbdlV?5IbimSdG$16R4EkX+S$DykDE/1QH#8yFnbJa&I=YuLN6<V<F>T/
Z=FV1* SiCTFp#IKdnMp>eF*Bd:>\n6ppE4yLw4eE4td6iK&<4=RyhA:d>qbL5>BqcE4GJ/\P=t>pe$Rb5HVKH\
\p9#G@ eVGq%ywiQ+Lt#cyVh*h9Pq5Zb:BwVC%IXIKW4*9<Q%PuC5hiC&4K/FCmwMG#Huy!iJ5jL?TM/8dN!yqb
p++T\V TyPWN\\uqq>kJZAVbRYYHZ@?YTN<EdCmMj*kH*b%8LN=J/m!W5u$1wEZk4b^aQ=EiliBC8PG4mZYk?ML
u%4p9J XGABtB/^mqVclAJeeqV^S?yVR<W65AZN%qYLcwYpdGdEhttW85hC4jkDJ?+IK%dnyhpRq\MeFW%lMw%D
+TtRJG Jq<S9?*k*BKHJbQ4H1w=^MEEXQNQwRGDYkuWj>$:ukYy?&Y6jD1#hk5P:LXR!>A4iD$eF416lEIVWwR>
-AAVIt 0009751b1e700110334 Page 48 of binaries2.zip
5h^bq6 dh#NX*M+t#%5TyQJYCtY5lK:6VXl+NPwB+@FhWbM5*G8Q>&*mRW44C!QII:14FCCEtwciN9<pnhRRcq=
kCPS*+ a:<q%bh1Ed^$^a*I$AydN^YD6%bG!I^h6$1*@K=/#akY&P=J5Vm*iACw*V+S4CLLI4ddNFiXaM8&LG6N
p=Z/*W +Ld56iV\9bC4INylet&&YHe/9bp>LRk=*4FpQRc1JFaJ&djH8?5FVnJtFq^+aZ$DBaWl//FeKnMemp9H
yFZuMm &%/FJQad4#aJ8chc!c5F#YQXl<j1dkyKp#$Ru:*tVSAj=5!j!WS6I%=hX/Hj*>Y%>wjnhn@ZhilLZ?+k
1I+u<? PPt<RNN5Ru<<MFDB#k/kA#P1t+W<@9KKyq<1JdF9&FAqWNil@JIedhVKyS1#&!1n^#VLc+ha<9wip//R
k^&MWd Lc6SLidFi*T#h:\4SXCk%YQeE1Tu^&@:Ct!n1jJX@XcGM*MeiX+V<tXAP$c\ZSc\N#iuh+4ettWHk%=J
qpCe%R aj4q:R6t#<1C:%=1IilWttmaQm\=%>hBLE:eS^Fc4wRNGI5QY&LH/yWaM8q^/HW+HkXTHR%@aAKV1jDl
nZMyVF 1Rd4J9c%$q61=Qk1^N6\!N^>+RBYVeuX44D8G=C5JaYX4S6R1%%E&#Xm%RiCWbtSA:wAX%=#tpZttClM
/h9b9R //lGBLV$ut&DqwPmtu9jI$!JY8utLhM4E&!uT<C/jFWLqbXlEC*a4!nEdau&Gk68\u1qqWMW6C8+1V9a
hA@atn *BBA>8$i&QPZP>cR%#aG%pXDE^\$$ZPwbalZZ5W:>G#85VhpmwmY+SYKp>aTE\5%T$#hTZRWBP%+=Q=^
N96\a\ =K%^l/DJLA18R#i/GwZKTPQBuj\Z@ktIN$5wm/>M1?Bt!HNkLbk88FXYT&h4B*kS=Ttin11kLDCKMG&\
tP<J#y @66R^d1pY\$j^55CLRmZ5YW%15Z=>pm:J$C:VK!+ic6Z%wud4iBkhuJ6m9?y\S!HidNLX&Qd*Wd@hu:/
58KkGZ @M=%I5=lp4J$ePK>ZYdBc<!i%*b?S#SXjWRVM*Ip\aTN^lGH!6R+eSStK<%jA:qPR\<><*mQJKV?A:At
Kyk=ak 6!enLb%EuE+d6YtVK:b%iIZJeRV*^NYl\ayEklLuMSCXen1DGQ65=nCX=uhK=Ycn%?%y@e!aH81%K!K%
VnNJm1 SC!*XnN!FehlTeFn&&ahK\FW1ek!h\DQl4P^6TiKXEPJubEXXBuYHkQ4FN986h5lkG6t4DBm>pIbGdPm
w>DM!% *GkGd@V8+Qd*F<<aXCHJy/%n!\>?8:jZQ!/waCXK9u5?u!?NZ4uXKS5qYp4l=alK58/mGHP6uXXnT<>b
1DZ6>u bHnP6E5G8=6tIY8Nc<^eb@yB9qw9K>cHQ^m5a<5*9Sc%cTX^4Z:HDPe^\W4amYLB%=4tDHL/C9l95*ee
?=nNl& SaE=IW@&&/ZHQSH?bF8&tC=F^my=%wX8!!*BX6+AMX6Zb1%PIJDwuyK6?lulp?@&YYeTk8&LlPWudcJb
t^/Bnw p/\NF:N6q/^m^dImJV?KRi:8D8c**#iWXppS9m8WBXcN\8/Y:^#Y6d5Z%lXE?=\!^=RRtTeWTd&@h54\
CZi5j5 EmjL$=>btk=V@I%%F=1ww>eTc!dn$Tmw8G:IVpKIF*E/dhTtH^S^QJV8nc\PK/^dkDW9KlPe\k$Z4*4j
q%8hn? JGTJVI?SaiQS51HpkQcJape>:+LuJh^9V*h*!@^=lyjwWTN$bidILbG+yacqFbhb@pLSakYbM+qcw5MT
y?lV4^ pMjClu8tP\t>Kmj8IZ?t*dC+c5Na5iDdXB5wCl%%&!>!!?Z*d=weDF&ZWJZcTKdZZdNbtbALy%I^BZy%
J@SIhM #5tu@Y1$/tIZw6WMT9ZXe!q//ILwLDnt\6wmJYdD\VMl8>QKtnH1/XCJE6yq1e6y/DcPMPLPFwQ/=VG<
<ZBZ!T 9TyeXSlB6LJ9?KDS$8ayqnTuEj/?ew9i<Hnp>Sc#mTYW@#=+\cKV>TXl#=!G#V+u^p@AXIt4jFIMY<:A
XEy4ky dnYd\u+bVyc\jhGJIX>Q^V9S:Wa<YEt%1a</Ih6SjW%\Su!j*?ci1^b<J=K%K/u?DG!4hCi8aNcDu=%1
TQ4cKc +?ld$=9MQV^W#4hTkn1/Mn?F%hbMwpc$wT4dEmtNT5cc54dCmR*a$BhH>GH?hMT>4dw8?J5PYRNtQVk9
H^Ib*A PyPeY^c\tyjjd8#iTJ8bpJiPH*bM!/lQwI//INi?hb4qClCp<uJD>y9VQtMLEXwVELHZW5PkdVWEYVBq
PmbcP@ RSWld@DnhjTcdI/:*RlYj6lZ^RtQ^hlyPbKS@/pb!>eRV?<Q=9QB5:5:yep%JCP&i6Ljb$<XJpYeKHpu
#1kC/C NIpQQZuHa?N>S1:YRXRcVI/5E=DK^QEQdeCt%4qyLCpkp6l9$b!aEW9$YT4NyT<P?DCV9DRdNFjGqRS%
lTy<d! XMdYGhd<F:4t<>@!BcHWyqI5wq*6k*cnj@NBP#JP6ByKMu6aAuSF\HwD+dE&MLit@HRM+?N8YWRw/$?%
JD@NNN 514D\yLZqT8ZlK^F#DbcP^&PB*jae8&L^6R*+n%?i?4GV49ZqdC<$YYR4*d4*k6cw1j#?Z@hCPY9Z?=K
Pt1GwA Ziu/Iuq48!*QG/d@QY%JuTnZTE5\uQWXD4&GqP\LD&N4$d<LYhYLy=P@C/8/@d$aceI8\^XaS!HXAcnP
\R@SA& ^8DDF8QDmnAZ5j5TCh*1ucVT\m!F#qVm*%>48L<J15j81dWkH+jEPhKW!K+mW1WnaAHdp+#cpPjD>Lyp
Ap<iNq *5WFaFihW1pSLtXl#^\9C/=mmjjT9:c9nA$b\aJc?aF\atHFLGK:+mj8mll6@n*=11l&mjQM==En@\:%
<uFaa# XPLQatnJlqdZE^k^QE#iZiNY@SI#4pSkneI1@6F?DA&!#G=pyZk+DFuQ*nj6l</Mck6#\EC4epa@Wm9d
G/AXiw VXa!yj:lD>w<$Z^P:KRicuV>?tyd8P@nQANdkIuVDHaiAmC%k*d#>EbmlhNkCl<nc/M9QY<A:BCcW=e$
I8mAy: +1FXqweyGnem+LG?4\+PT/XclC!C:Pw+NCe\6Kqc*iNLAFd^bN&yj^!M&LimFSP5uT+Cd@>he6Z<bPLB
tJS>:@ L?mwu1?yI^@y\jqGX?PCMKhcFn8Zwy^ndimmQcw%GC=ImD+56Mw>81?$Xc^&8HFp4Sb\Ny&5A55KqjcA
W@LbeI GWt9tbGXlkdj9$%cGG4>%XV<EqPJ<bq<hXMHa8D\Tb:y>W6iuWkNbX15BLM/VM>j#LqJW?l11bSQ*<#p
dPSDT* Tm!+!>C!FQCBADhV/ew:q&nlSD1aZF=eH5BFHJN6tb*CpqBBJ6B&:jBT<#jE!8<$^<!ItXAF+d+BC^qL
&^G41B qnNWJ$=Ycwmdwtu!6Stq&4Rd^<S&8P#tm>k*h@tGh5#nZNP>>eKcKqQ5XJ^G4etZ*pCdC\/<Md1$Z6h?
dZR95< 5h!4?>y1anVCM#TTqe/YQ1>tM6N?>/1\CB9\QBn%eA\%q*W$$W=A$Ihh9m1>DtP>/byp/#jaNw@bPele
N9!WDn &C#Znp9b^5DcS18>NJ1AA$>/\!+yVKI$kR8QllcAHG54DYq:4@R/$XJN:qy:ijC/b5H$X1Pq5RES1:ZD
+tL+m1 A=uWkh/1&q#XhYK>a#AlaqX=AmNY6%QdcjbHk1Y:$>u5SaF#9kW/TNcGhT<qa6*%Tm8I*V*LbdtJPpBc
?wm^^1 A^iecp9yBK#c+Qum<61cKt9>jXRyJ^Y5Wn$%$TCh?!TMX9??\&qwYbned<&CjEGD6jhmVY$@Ai>qJ5#S
=*=pSc tWLimek5X%4!9&5uS&lNbkt#WeQjTHCCYu6<R#R:@1G$S:1Je<^m!BMhyNuc8+6*l+S6KTlJ<1*q!8H4
QSWNQE !*ea<HC%a8a*DhEiP+lFE%aSi<4A>41eWh:i=jVkXqCNQj?\kc#8qt4AIq*LDe?mw88L=?KnEPqcPA+>
jl</EE <G=X9M:FnVk&Nu^%bbNH6IP&>QK<CmR45qE%Zm$GFIKF>*k<C>=lL5\R?VwJ/W*tebyIRIj:VIAQ1/%p
A@CBIZ beLt?Mh>l@Sj>pVpnR84Z:kyutFYl=91:d:S9a^NE#eki/MP*X/LkIY\FWet?M\H/Ve!%!qDMk:4Ry5S
?G?XBu Z^DS9n5+4FXL=tWmcLeP#:WFN6jpYpj/$dCyK9G^*d$NIqaIFy!+nhBd!@#FuXX!diEZeC!XqTWT4jp!
*CSqR$ ZJ?6y1bn9Hmt@!NmJXlQ+!LytF=b91w6eL$C:D94DZkXqb%c^@mR%DcSjnc#&R1\p6LIDiapk<*TymV*
AcEpVM Z@^ZLI?bD/8DYNcE=!@mY!Fd!dKSaC4w6hSRB!yZ8dF:8QFC6IWQ&5tc/\#GZXcYGF#t^pMm%\:4V6w&
/pH@eh WILKP5/AnV+^?HkWqnd:9*lNj*R>4CAp!<4Tc?=+!n%QL!+6wXuYdTh\au=\G8qPd>@&AY!QiKwaP?+1
MRI/RG duZW^EH^#t^&ZFA*Qp9QRpPTqVWuVpy!91mYZD/N?m@hiyj*tYeY^d=l:S%uw#GWb4%Q1:jjuaVeM+/K
maJ@6@ ^!%?4LPEBqSH$SmB+YyZj8nD&84betk55p:ZDy\RlRA4eiFTyApL9VaH$ZR8hVY^D/I:FDTB:KnNX=c!
4%&FBH Fu6p9>pH:tC:bD+<Nu1>9AnN@q>j:q<i:q??Q6!9%#aQZq@1HAD8umnhMK>hK&\i4%#iM6*&nX/Fa1MT
K9k=>4 u!bu8SnBNl9>/cTFqHHBDhhTw&Xbn*SV>pA4a:+dhW4#6wb89t1#AJa4MlbDP!!@8=T=V=h^^\:PcJ5+
<4y\R& K\/V9GdcQY>5ljpK1?ShiASAept6\jaE?4DXkGkPnT\E/aYy1P1qwF!+GeqZGK=IWihGG=1cQta9F/Qc
:@Eu$> :X&Q86%489bE\A4FT5iAWFpG5YS&DlRuHaX+Dnb<eZm=j$CC>9#\@QD!>eY:k$8bl@ZPyJRYk4E%%SAY
lb9DJd *FhV=?*da/Ne>SQVyhZwEbE&R&lHM@8Q/aT$6JBDFca!ptC+wE=lXTYbkQ>YjlG*9:8XEmwX4<KG^^Py
T5HNIZ V:#TcZ\!Ww^SQjeSkPJ:mn5AnPPYiTF#iCJFn#KIcnnYDAnQdRwnIKXiQhcHJW:HEyu=<QahuE5FyXaG
^R^<?: 6tTuAcpTuA&$c$QZNDPhh>Jnp=XBHZWkb1?:ub+RLF5:w6h4umZ*LBKu/ynZ>:YM9nL=?94!pIA>9Dne
bXl$@& Q:\RaAX%B%cmV#npZ9eHkuWSK@w^+wSh4<kD+Vdb>1E@!LTTKeHA45D@qN^#%BRW%pSH=6nN$%N99GVV
uL/Y#Y WibLM%>XC=$E?e468tXa=46*!uG+\:%&B4lYVt#Xn6LQln8wTRJ@ZMclyiwn4>QZV1Dtq&B/BS?iY4Q#
GY9cGW 5ej+\R?*:@KTyc?wqlSYp:CeRdJ:1#FHeTJP4XeFpT9Sb9eccQa/:h=%>/wHcD6D>qGM9X&\$i8N1F\1
MyFib1 Z*X8/AFVLEuak@*D%\iZ?+iZB#/!R:yPl@c%1lP4lTM/%N8*ReV&ZZiC&eL!Xd!KSJTNQy&Ma<6Ta8\K
KCnQ@: uHni/HL%K+9Y\KD9ht:tQ@bJp?cw$y4H9dI+nSG=ZtlV=ZQ>BVwd!LMwXC8!k8!^>ewI=KyXwYNVt5bP
Y/J*DR 5h4/TNIq^D<<<+ReTX$VbJ8TTqn+pR&da^lt/$Gnd$1kVIaTi8&!%^Bp&qN5i\S8:+ybeR>^YE:baEi*
L4TZD= !%hYN5\9ISNLtX+QD\nTR>yiA%qm^ae//W^l9a1CI/Qldnjw\&K<>49BuTm1p^B51>PT$wFG5+W%*54j
hZd*D! Sep8JT/&pq4%X4i<<i$8CNc:*h5\M8DG=kZ+pKAdFc?inc*$?p=tAkt*pZq<q#yW$ch#n5inTEWTV>N+
tmK=SY =8Y<&1yCcq:h/TS!%5hF5REyiY98lPTAAeQc$jw*l*YV!LZt^Y$e#Gp*ZpnMWXImy%Ii^H/I#lB+$9Y/
q%wGE& *TNK9SK/:SBDJ5lHZZhRV:Z%@=\h^KIQZ?8\859#R&K:l?@&D$l4Itny:9A<I6n#C=XRWZRD\Xit#L:b
-A#u/D 000a9d02c4d00110334 Page 49 of binaries2.zip
<Ia5T4 45eT6^Qh!WV5L6e4e:qq8+WVYNaKDHEQ*yX:Wk4ElTHhe8\1@qJ+^hud6#4l$B4%lEpd/y$S:WcGlipA
+tHh+p \QML$\=5yqjRu1=Mi^1GJuu1kqJaPW\u&ZA8Z!XmN%EtQ9Ii#P!ZtMyeLP?GlDP$4Y+IVn=D@lp!kE*d
!SQ*n4 5CIYlD%W9H/RRX8ThRHDykM61eNMGDihLwNLDBuK<uCpDIMnhTJj5TypnAM#4E5HqlEqin$<INYa=P94
9StGi? C=*Ck6MmNdw/=w>?Y:MdeYKL1+8IQXYK:aw/BLFKh5<8X@HiGV&!DBWQF=N$C=JXEBYH^LPBnh9=t#hi
Sb1dWI m5k%TqQRyDYbVu%y1%G$iS@Iy?M!8a9hKByBPddGQSMQyLC&Ka1V615cGm?iSPpT=l@YKK/%F^h89c&X
q=JZBy nRw4QTuqN$6Y?TRYdL5^t*9I<Yb19k*wVCMTy>h6WycAc1jVbtSB5/\aD*6c9K$hd5YSKNZX+yhknSGw
DhkYVh 9wdmSNjDk?1BpC$BK&^MJwt!R8p>yinHBhXJXPK*qui1%k:yXn*t5En+J6kkYW8i4W@R\WbH=ZTQ8ZC*
1HXQ:P WXDuEtmXSG9Pl>^Fe:#nV6DVcFmd=6hjthcpR:$8Lu$Tu+!qpF@l*d1HK@PBRyejbQTQnHC6Iau$JNB\
9MGtNh 8@YGID:<Rj&bWmwpu5StkHYVwWW#w=IHRR++S::^\pdy!c>SZ!V:?K>:wNIP/6p/?GNaCYKm%&5w^D&F
qcHiZP FVN6%jE@p#^1u1q&4mN$Dk<8AY46NeF/YCYNGLD81?^>b@++/!QPI%mc^u+b&4eK4DLmjmDaZYLD#YMp
I+jAiC F:C1!*W*eQ1Y&B9F:kk*Y6YiJjAj&i^uK%Z%8S+i!+pG*R=qdmnGQ5qR^ZjCb6:=JL=L>n#JHFSLL^dK
yh?4VX G+c^V$y^+l%Y#\V:Bee&LM*K5Z#GkiWQi%aTB\a/yaleAT$KpnZ8&9dpwNa5nK4q<anIkBqN?9A@>llS
8B*lqw \dVh<ehE5NChhBBqdMC1*5S8Ly6DCII>lCd<8q+=4P?VBpWEc=wVu/1kPaY+!C:Dh?4iaXKF8/+:1W:e
A1tKc4 pyyYHHFbwt=**GV&:1:MhhNTdpp/W+tF4nWIKZ!*kTQTBTKcQP4F!N:PpM</S>W946W6<W=tnb<L8#t@
jK+DN< XDZbB!6ima6lEpChYA9ymVem<E=eR4BcNVq^F#QLX@FL#EJYE5ne!dWkwlZpY6k5whRMtIwtnATJG?jD
C4ENWe R1?1NuX:R*BkBdMhkCZGjN$YB^RDP@Z^Znkl1pNC96ww&EQVl?8XP9$S9d:iF@q/?W+hN?1LW=YTjpG@
d+HdnR G^E5+@y&SZhmM=dq=+RXJpEXwnNjKBMhE^t*&466:uXRpMyH$aT@:b^/b^+h<*V4uiSN8u+R/V4SGk:J
d:Wha/ I:Jl&Be&9j:!uX1#/qM$aIech+8BDhJY:TDD%wDX%t98l=S=#VhVH<61$<<:Am6l1WyVZ5nXk^@Elbqe
Qui>A5 d!JaVS5iE&mpIRq>HnaP/+i%Vy$i6RZlL4FnD5mPhZ+&:eWD5D49q*:+PY8>5F?JZt6XS4Z&85/TXmn&
:dPKFd R9TPcLCPJbZ$XBQ8B$:MFK8yE=Jt*DlG#KS9AVt/R?Cw*XL4lm6y#S<5N#5/Km8ij8b#9Y>D9/YRYmAh
=jY$h: J/?9bJcnDntZtW<&wq45HY*jec&1W=kp5>I?i1V?RNYNyRGPmFb^GW?<a#4y\#/w!\J5w&FJ8:cIiC%l
8R9$Dk jA!/<1nu#e1@V&e1ZuXTu%ad>Ibp5\LV=kFB!6e/$b8K&Y/HFPI&^*R+FYatH8KRCYQ!>bJlFW*+5Mc\
%jTSVZ Xkubk<Q>T>ceXL=iT9&tD=DtH>acK<H&uYAqFCDMiZJM4Jdh4n*JWpLncM>ka&e\dJ#!uj8D8h:X^kLe
JZtd?W ?9\#S*ly5:&mM#t$kqPbeT9M^cil9qQcQhhJ&Xjc5j61cF$il8=/tukHQY&MMw!#EmjKnT$BFE+1%wiu
NQHAd^ cy@wy<qWEK8tWJB1bECL1nnG6Mb=%Ln6?iDL?W$WT+aNPYTbimBnntw!+/yiQ^CiLJaPWw1%HF<#ahmQ
?&p@ck KQFK6%<b&aM1im4YN*pw%4/K&He11C+9bNC\PlJqtaMVu:+N<hh@BdCtFE>S#NQHV?c$:nWp?bBl*t%%
4y:!1u *i9NIdtT8BNb6BLF9wmtFlMZ#tqnNFcm@lidX#u#GN%EhS1b\H1q\@jiHayR>ZZJJM\m>uKFaKW@%uB%
5V*^Je <IaE<:Sj%hnc=$Y68d\JI@#Dq191BhH6puJl4wR4iEX!ZelXcqy1ndhVCdG=T*St8Y1pGZZc+L<A6I+8
5liuGV mARJQV5+:Ik^&=ZESBEFQ>A4LHqSmikM:F<!9hd4%XK>ZtKTlam>IK*+ZMPaP9y>bV:!6G@PaeH%XC1e
wuy<R$ ?eW>cE55h<w5PA6Q@=Ea4=aMlBKPetHNp4:^6pI@n4VPj\iK@<6<tcQ4QMe9@H+#8Qt*&iu5hHw/6wcV
XNNuYb X8apl<4idS&HTywDnB/%%k:yiu*S8bI4S$c\nTjhCh5N*et\Q^+Su$HKYI?i1P=pdVW=EmB+/=DD1jTZ
TjLKcB +J=/yt/^$qR1QC$X4H$LY4c!<c1yZjA$>YjClnp$>iHG8^<nqitcPG/NiYeXDW$N&ZydqPNSB/F&pSP1
9=4VAH PWqpuiP9Pq5TckWS=8HBQu&?5q$6dhY*K/B:>9/LhZ@8y5=KhHw//:eaVuE^kSQ@K?uE\!=!SC*btmX4
4?SjNb 9qViP*:L<=WF&c+p*P^1CyM+m+qLi:ud@Pb*we*jDh:j>j/>JtKnTAXI+Dh&4/@dG1a:iEe1\:8Dh@8Z
puK%MY HJpT@:a5Z=auB>e&N^P@yT6J8RC1l%=WkHW$NI/Lk1i^IC!qFNL>$kep5Z>ak#qC4@TbHpSy/YqBaSX!
SWRqh1 LWk&C19CKD64N5!%G*\5*G\TQ&bE+yXw4L+JG688d^GXAXwkC%mJawehYyAS4Kw+<dKI:FiTyBi9D\>4
5qJA15 %i%/cc8$9RqpZ^@85=@+ZKhNZqmcpQbdpcFZ$=c/twS\@=Y8aL?uu8nZ8454FMyEu=mW<59iH5Fb%@aX
eKL:li 9Wp4d#+KMX#Z9ZuL9<*?djd?*\c@@@::uK@<aDAjuA=P=hKu4?#VGi>KyJPH\%$iZq\Tq1V^\e6CR8R%
eywT*K L%tRL%E6qED<:@DAdeJiV$=nD+X1w@:\GG:&Hn@q$nY/+ZmuyT^^/mjlT!K=V/6K@eM8/pYJK=p!ZBJc
<b$knD *T^IC$M8*GjJm4?i!MYq1E$jNHCA6hRhRa:YRcldyc*64SLhEBPHmK\j<JH*46nybLp\N<1I^bEIk6W\
=k:9TX *iE=t#kXIu4c^@dthkpLlI^aY8@:LKZa5JjkPn64tAj\i8&4D=E9$?t@H8<hu<=519^$%mSMMc1KM!8q
KGDQQ: mK9L5lWV=l1cB1P>JA1:+#AkdDan<AnGkY=&C$lQ?^#G:*j:ZTphHLY9P>j6!@aFeS%cn96\uL*iQ?Dw
L8#C=u %DpCXWT:hH6?8C@AHyyNTGbD%^D5Cyn/XPGXc+>V^44M6#t46#<iw:<R?+iup1X1bS\hk4BRS1<:whjC
*E?eAJ J8l%E@ScX@pKRa58k&/>j6CSl#I%9W61W+hwFBT&ZhwtXIH8hlWc%GGn\/=mq4Dc^+kJFqJcA?8mQtw5
6iF9*D T:Sl?9\tA\8G95@Au15I9lAB1<QZS#dke94CLNjn6%NC:ZRtScXemXliS&FQ!/1&\H?=PI?F&cRW1q*b
h^Nm<h F>Ed?%#/6#QFn&+aWkL%8+D/w6>@ea\@P@Phulu9l^!#wG6%9<=iq5N>81P@C&HK\J#?Y&j:wYHPHFbE
GVR5&u cEeM<T/cw9ScV1:!JZdQX<ptI<a<QtZ@5GW%ctqQiVM9LR!bZNERw8Dp!t%V&N9W$8d9!>5+Bad+PJl\
d%*\48 4>$?4JaI#1*6#a*NAkHLwJBYT/\aMyaI>lwBP\FYh*VD:tYX4?i5My:n%$P?$8e*Ntq9&%5%8J*w^JD1
J&hKkG yK/=m+64T#qRHmDp%bw1^dd/y:NwmlttSc?nl\CQ9>un91nRtd15e@T/pV8a4wX!h#wJe&u/d\p?9jkD
=w*tyH 8i#8:i/mL\L>\Z@PpMJ5J+Z?ED&$1^Y=Xq=Z>pt9J=D^P$C1SMk+N^Z8^F^HB:ItHEDe^bYaTa>&!J*p
\NtII@ 8A$e*>Hjd65R:Wb**T:^nMu+hMb>j1ciQD#1dlPPV\F4kZ5ET!jDVW*A===YELL>1a&Bu!5dutp4MJIM
BeYIde bL4Yc\S4acP\ph@a&Cl5daDY6uDwB*Xi^P^LnEb+8+AhT*/BGHlIpnk+4Nc&mX=yd$V:Ji!CV5jqbSkQ
G^Hu=H 1/G/1G<GD:l/eV\qXF<R1Di#$LhBJ?temqTX44P6S18u%pC4aJ=k/Myj:5y>>I:p<#Pd9kY5BKBeACW@
:@lKuL %49Y<>a/*VbSuT?R6J8Hda\X1RNWRuTL4kb8yiy$?*1j@:%bL>Y&?W1YS$*&$LC&kI%ticjeKDj^6E^j
YW=5R6 5KM\::b*ma:k/\HK8<!cTSSAH?c&mt:@Nk1k#$L=1hB4Th6>dJaa$^1*QY4Zt8PbBtI<EX4Tw&C:Rt81
9!#5CP dG>8dSCw?j5u?eKVnWIiuHkLG9JlDj:ENnJplt:yTCtHJ5JA94+VlbkIq1*Z4hKV\5bYkhCq^jH/AMEA
9=Ske$ Jqnt^FFEl:%a%8&1V/j?%B14SMMdyS9HY//iZT<ZYynF1>H4l5!nY=QR#hyh!%^+p9<%yXP&&>yh*%q@
P\KcHY #yh%@u9?9QX<h**>Pb%=9i\ABEbEBqVVk1=8J1CVbG6#1$J@Y\\$WCXbC/T=RhpYu?%6ZG9dnSK\LDi=
G/8%?@ nWMJ*Z^*hPjd$mGy$YCat:DPhl5>>NHaSTiXHwBF*$58FqAuwyB4mj*B$l>Ni*+I9hcEZI@NuTAbwl@W
A5A?i^ 5\ENuIB6h$kS*m:pN+Dw^5bZ8mPITaEm=dlYQ+V$GHY+^E/44+LuZ^Jl4m@EcmeyC88XaGZ1*!4RD!cG
RMtDT1 BZw>iKe1<+WM@a%:GNqe1hYLynnItD4Yk9yQ:\1695#H+pwJq1!Y::L&lTS4<M*Pb5ipnQXdkHYHV@EP
d>QCPc :4E>J=#=Ndq8q^mee4%Sq*J5WlpJM:%8<pc*ALb!<L4/ttHXj=Y&>IRDZN\B\y$Th446L@I>Zm\*ApE#
GGeyTB 8I*tLkaPE/:b8YSbcZ=nW:Yty&l#9!t6C%Y<<wkm6BYpT^>w#E&<j4BIMm\yiQ\Q/yX6aHq@j$jZ\9&*
6dGRS1 J&DJyNJY&PCB=6V8huV&GJLZLLVPPZ^RuMSij\ehpYVQ>6atXpdlmWnyR>GelKKDC&++$5Ryc>w5QkSN
b+N=tl SdJ4cHiq%iGe$RqS%C8aM%lW+WJ\>RlBn=qcChGuP$>*hy+B&ch$iy<K#HVPYN8p!\byt4ABCNQ6&mcy
m*/TtH n$CN&N>j/JS8=VeNSPdIB:SJX@#<E\/idiT*<>5F^=c?AH*MT:4d\nchTyk4ySLS:W/=Te8HtdPKZbD9
h5Wc5K :uH@:jqu#maZq\IbPaAXSM@m6dVydLmtVil1nX1u%4QBmGLq5MVTjHRpy:Zy=^B=*h*j=?@9N4=>@jdp
a&cJp/ &#$Pq^an@E>m1QY+*$T\aJF1Ck@eWPR4Al*\A+MS%$5qkZXDyLR1^Ij99NyF^i5w/5b6HiqYRLYi?byd
myCYud 1?B!:etp??%8^Yk6^:CPBha?WY6=y:BViFakHYVu/hQC5/eEMq=/T1h:k/>=@DE5JdEItEd#^V\BS>D>
W>6N:d =Ru!P#ejd!t\SLXdt$@?\1A?EY!JX\LVk8!E\NkwRXWy=AZVQH@XN4y#:+Ank*L4pL+mAGn6HjjBl#WS
ZKkWSb Ed?6JFyV8XD!%tk1ZtYetLHl&M1=CiXY5KSIB/#XN\F4+i:?&@*Zd^6j9>$@?Wa5?RpbQNCJtYCSWt\=
1h@CY@ E^KC9YGQE\M4duIwV95HJJVJX5y9QHqTAM&VDa8kD8eSm?6eCNac%Mqp$LlH/EwYp4eiuFwqwnRNcIZ?
-ATYZ^ 000eb07123c00110334 Page 50 of binaries2.zip
%pEE!S l5!GC+*JTn>=^Q@GQcJZPwhQtTaJY<GSaAc6!nuHZj+dIdCq!JaE%W$CDd$mH#<Biu!Hny?AqapZ4\m>
D\TD&^ +t+D/YSpTwB8CYH&/i4i<V>PFKX@kp69R>!Yhyl$$aYh:kuZ+?^<:LHZ+YSup@6*q@X+VG&TiVKNPuy4
6jD<dm p:HVRumNp>^F9N/wX\L?b*ENd&$@Kh^@Jj=LFM8w*6>@?$4ukCmYkD%RaIiC4CnEaMSC4!l<aPMW9u>Y
91<9c8 uLbLV:BEu&#pcYZWAP\?jIu9JFB>/Wu@Gu@$!WNS45y<ydG9tD%Vt*AtA:i@iI8t$p/nF$wuQD?\j>^4
p$FuVc Nak&DWHD<Yql=@p#jWau9WAES&5RwJK<*C\B68&hdRL%mVV6JR#9/Qa@A>DKJkHdjET\Q::LS^j/1e@y
t9bK@u t$4k9TYT+IRpR\yR:\y*Z<X#yPK&LQ%Eh+Syq^86jy@%ab>TKPVKjDkt%>JtVYiJei51b5P#qbC/FAb^
WtyTVW lXY*W/8ZCpTplc<5Z\qk5PL:\qi\a5naiw$Va*w1DejPmG?tuHVL/dae?ICH:ZY>T8iH/LWAt/t$SSL/
@Z9S9A >iElP+uQPVy>aiVKH1iJ$89NjB=c1pjnBY?>BT\E8%B59/Abc#^68hBRY#ac6+4:@4nj#**MDRdQGhth
G^^c#@ *Kjed:phID5+!<%j+5Yh5%\?9=NdQEJPd8u5nE=kukV1w>#mLJh:VyD?=#!>lZ8<@tiPqG%6Xnidb:Tu
FjHb$1 S\D<i&/S?*S&B@\LA*1aA/X8q?nBGZ$Sp9Sy@+ZeH/<IZ>wQpN*bQe5S5p?JdHh#A$lmI6nh%nHtItqH
NV@WBa mMpRYqNJt<k11pc9YlTJ*q6NVX@lPW$TwyNIMp+5p&6qc+NI>C5aeiEiuJlkJY\Jq<*6VVb&pMp&Mu1h
\QI<@8 cYTIG:>J!4>pT!BjR9VlDaKXWM%DZpFC9:/RyApPV=8:!cbh1P5/u8h*1/pN!yi=FdiPlJ*P#GkX\:YE
+aKl>W GS<?^h^!THB@*P8j=RnDn:5A<#qBuGNee^<HL<>!Q>N=j=RdFDb!u%+S\Y$ZN5@tt/RCdY+?Y9DHFw>A
Xd9Z*d 4V6uA!LZL$ThV^+V4Mutht:^K9h^5jH+:u@:95nSWpFSFJbKL4h+Dq&JHy+R6J#LVdn8=HId>I:u8eE&
9&GL>Z ?DS>bYtD/SYQ\J9L//%8Q#8*VAqm\*BC<N!V5w4ZTG$T?RyY*JlEX5:<^kb6DbpLZ=PSA::=dRMcE/FJ
T1yXB8 BA6/9TN$:=?RSk9Fl$m8I<l!8TaLYQbM\PLkCl%J5aWjtER5$i5&1R^j\a1&IcHlw$FF%4qZ/X^=K#tD
1Ze4A+ XZN/dYKnyJ1F8Y<G:FVLZc*L:F&=lapR#ZGebe<Bc!LZ+=QeaKj<QjeSHQe=uX@l\#8=R8FSnt+KP*V/
DE$k8a B#n9>J?6W8+MQwD<>mI*&My99X4p6wqPRhJjH8i@elQj9$A%Qut=SS@/Vp>Qem>Sp$4pmnh9dBL:JaYJ
YZ@\aj Hld!YBZE*ZNulh<@j9?Y9!jYMCDFcd9$mPm%VGnTw>>!SMCpyVh&h+?JD$6RHc*RnF#LLq=Ln18$#RP>
NAKV^j 65a4%16/l<GGSd\T*>\kLGHljMWj^P\>6Ki9hA/&GFn+mZ85PR%N\M+%N*\<FtDjPdD58\K>\l1G<:>!
y>G\S8 KMBKil<D1^qj$yhKp%eX%YYWktRwl:dNy\m8i!4M&q%Dp>y/AXlGq8hZ>95je+%!mWAk*J=@GlTC1H&$
$J*h!> GNByJ!J/tV9dKZDbT&tSI&6$c@Nq:mMuhR:PjkajZwAk$dYPNCWaQb8QN^@V@%+?@yL@j9bT^i5mJ^KX
QtZ%l\ yPn8IpjjeyJ:lY#8*IJwP9?Xh9@<W&+HRyY+::cI%>*eS^K9JG%d4Xcj?dAt#HSKEc\qk=Y:i6hqk9$B
%=RIyE =C\VYLBiJYGNA<u5R#!5qdakVREu@1A=*Y*k/di9yD66dt>9XYy%?Iq:X&VyYKPJG&HEW6X!#WpEABay
QV:m&y \\klEKwFMuSkLMG*kTC5XKYhT&R>/844<^4uputpTR$/CT=m^6^H\4wKM:mFBmi$aWdAKCw/%eTFj9ep
H+XEey >@==tWVcwARGtN6>@pnM%b*By>^*SniZ?@Rh>klWy6\C<:5&e+8Zt:Bpjkcmt#6u<<ZbaQ5LBP#nQK9K
G/wJcp t:5pj*j8<w>jLX:6:P\R4I>!b&VFan?d^Ap?Fp4=*MiZ5HRYJIFQbCES%+YiBDTlFJj+5PCWYt?&i6CH
HXP+$= jjRlAC^H\JceD+eS8\j%llpTW8$b1um=#LXDY6QYS8EdW!4#*@89LGNB\jiAby8MM<SmP^#WpVn+#JKI
>RjR>Q %iN$jTWqb?<PL\+PZ>h4VK>QAC6:J5R^\hHyh=IJw#Q#FNaQG9IQcAbawSY\<^QH@wJ#VC$yRpT4qF5%
bL8lae h1$q+WRV<EjHp!:^&EcDBFtPV6<npupjmjPSlB*RR&KYPNtLV#tmM?uP8<kB%6LH^T=:tPlnbL5T>B>#
uFRGtD <^!4^jt6^&VZdyQwQZ9%?Mun8=P#?St^/Tj=S&i@w&^tw$VIE4&TtbQLkV5WYFDuaPPA@<IhRw\Cqp/n
$\mLC4 *KCD&&WHJ8^Z?CW5D@H95YE$i6:e^CkTE4Aa?5Zm%b#?6*MQ9ZJNRS8?y6y&@l=/EmFLmBd\KA<:>m8b
\Gk@/w 6F@FXW\!E5pV9cH:mI$Se$mHe^I=Bamw<9XBlVXmNlaJYIRQpH:1tb6M5F4dK&*ebnh#H/\66L1<6aq?
EZQ^^8 T=i^@ihQNeNWKdapJVp6:9%Pqw+4^DyL1ne?!j*Ycnc?j^1WRdYp#4\mNIq!#*KQ&FhAGPRY8!Y^PmFj
MQ6qN\ aiZpe6@b\$ReqImVeM%9uT%&aLAT65Z<=wBweD8QBl:RtkaR6KZFYYF#A?$BClCkBCPSMySniy*$LBlA
*A>JaC L#:q!tT!Nq@pjtPueSQ4:DeJJ@jkq@D1n:c^ahPH@dLJZjC=+Yi6%l*LRHXi?J=lmp!du4Blk8BP@E^E
Y*Za>+ 1wRyKJj$1H6&QD*b&CkI5QAVI&kwEuE14pRY%ABY/SY%paiHqVyyamYmYL4h*GbHIkF:L9qjYm6ybeGV
G#mW>P 5Zb^E^ThA&6c/K&^+8jQ:5^n8CcQ!6&8bmI&iCJE%ISFkV*?>%!8&?wSWD8N>bj#n*!1uyWGVFHAkIV4
ue^Sh# L9&^ZXp4LScqW4XWidqa%C8dt*Zl^:*ey#^B@RnG#lMtYu1hl=a<ju!!GLBd+ku^:qikMqJ9T!<Yb:Vu
!LhGY& AcqJ^N%#m$KJQp^CqL/umiDCTT+uLtI/K9y4Nhp@VH^a8\?MS<&aDbhp?wqPXPCBDD451&>imbC!yt^+
Y/G<4u CC8H!QXJkhWp?Jt?5p:<nS<R<Z/:J%H:SN#*NR:4TNK4YdA*tySwQYERYD>H69>Ymjc/JY5ChyIC1%qC
$aCH^6 :EmWZwNc<!N5iMq=PnISYYcEGdTDb!HJZ*QCph9WcZC6Zbj4e:1!+Ie/9^#m?@Sn:wRa+Th$Yu!S!@Xj
88SIPi 96kyq=/?#H$1:=C%\Z!+RGVVBL&?yDN?eqT1dNX!iQB>jybDTIjwhZh\6ummA&mIcn@P#^+@Q<Enw99h
DVT+SM S:5wiQ5=6^m<jHH&M<6^\yLM&Xj\Pm%!L\apm+pAZ!=IJP!&ZyAMiNEuaEuC>?n^L5K\^@BLGK^D%14Y
Kc!K+t X<t%X8L=^TBW>Amy%h8SiDY%mWNedL5TCbJ+LSB=M1bE6&T:E6F8jGY6mYV5E!m&aMYpE:e=1DQ!<19q
AjQ1W8 Wlt^=MIw4Ii9D<HdCXpwZR\45k9AmEt<TmKM\#1b^Nw\b%>FW>@+GjAijHP*wZRJaS:Mp#i+#Ju4I*8c
wiq<#B KD@S#P6^j\lMCcZh%t/#hZJG59DVT!k6b#qay+VB>$?=WwpEIQwqp+y#65klwF=j$kPTuDX\+=@^<6pk
e?:PPQ L*4Vj!a1Je8H*p9&/&QcPj$#V&w!<ZB/djGCPDABTE8G/BY?J:\B:wihM1&c^t:n??IMu!bNmc#yLuGT
\>CEL/ AXA>uw\@b%ba&ZN!BbRR164Et<jcNHm5IPA%>hZ1Z4XS&kTyXtT<X4d#MGqa8LKqe\i6CYRLi=cAJtn#
>B9\N4 yC:TD+a*WZye<^mbPBtGa*ZeawL:D>DJRXAh?VS%$wiJN^>Iwk^e^KaQT+cnGYHcVPqYT&nMN+HL>&@j
5Vy%bV %m#ZSd6JRGQ16ERZB1y5/E!5W=tM8Wd?WG/RG=^$MYN4h*e\wCi:P/YuJdmijtd9V?/EqNVed:5E:PA*
h6le?j ?9h9tDqi1R=!b&euqT*EZ*e?$59dVK#@?R/*h+<j$R4b\RCVu?HP!n%BF**c!>ub1&*bJ?*/=iAqYH&P
5HXPFm h91euaY:H\i:nh%iDkhBaQbJR9SIZ^@$npuBi#6SQp\H:qaPYYk%XaibZDFmnEjjen@cqlkTe=:#Qujn
+w8W?Q FY\aNVu%ittD6CSYl6ZawchQBPDC@RcLYuaw%8wE4HRSkVPBjj?Y9AaZ5dYa+G\>AubV51XK6Q+=T?l\
!eL%d5 Z\5nAP!X6Ste1buD*1ZdY*eTA>c@TaLw#6&cyjp45AWT4d6TcdW4:Rh&n*@w4GQ#4u9nZ4jj:WuD&l$M
S#H=&N 9+R\laIK6a:M5bKGe81aKXLnnHbpS%R&1=5Xnd^8p5apw9Z^HR?Pwn9$m9*!&F6=dMFjlSR#:A?:bbj#
?B#>>8 Bp9^daJyt?Q1DhLiY:$GJ$y\pmIh&dl*QDqG@&FLVt<\45cHT#be4I!BSi^8\k#qk%y94EZtT*Z/V/*A
+:mVl1 ESH%\>4t%kc#+c>Mul5mY$GuWJHynuVmA5qaw4$K*Q<>Ld&\hFM^aSFe6+IYMPJ>bKuC^6tE?Xw=lQ*K
nyAY>d yXuM4duIWIwpSd:!1q815=>&i/Nnekub&<FV%aFF514SK6PQbCawPLD:JLVu4!!cEeh$Smnd/mGI*bDp
CXX?u? BiAyE#P=nItWP!BL\HL^mcT?IA$GtQ+q9!q!qSBqLHpcpRILh<WVmikWPCN@1+Aejb?^!lE/D5LC1:VV
?1Aep1 RBC>$eLSCK:HQW+pJ#a<EZ$aw*cctJ&^npt5+L?1NYGPe1ZCa%n4wk:**JB\y:<aAt1<dt<I1By*@eaE
@\%ZXD imeEnAn:Qj%nk$Qp1P#wTX/::6QdEZBRS:9yHcL$CkSdB<ZYpjQQdkqa5JjmqyL/HNFi9YYFW8lNGQmG
9WT&:R B!?<KuJNm&>KDG8D:S5^Zj8lLJGD!tPhw#$pCV91D=FH&89mqJcdJW+6KTtw:CGT&BwGbY=Zc1X1yTal
6yKEB% %kwu\Y!T!RymBa*T=i9ZP%^=LN\ZaA64=+qFhDaEW?+cIK$?iQX5pDaMkt&RQk^Y*N*6CK^nhAEG6W/R
d@N8yI L!ELe6RD$&X/FV/<KaM!SB&YYXdMnL5#<?e!9WwLA+lu%L\TYY$YaNMRXh=B@j$1GlSmPkVyHbM8l*hI
iA6tm/ 5!%XaePmn+l1^Jc>Ny=wq\tyV$Jj4pNPe$LIwFI>4HE6l<ZySB%YM$eTB/$n8?Eb\84Q9=qE6j6!T>4p
Z@NFm$ AhRtXKhGmM@FJchcqkyaeSJ*!a=6dPDZKDn<TDDa#ye+e/eCXC9Ej=G96kXW6#ajd:ItDElyiV>:>8nb
%R^aCy >4MN^lb$??WL&n\L^VKRG@R?5Dp?hZV!<ya6\eF$=L/R#HB/^bJVA+Q=MM1BIX=L/#\=tijFXal/ReEq
!ZZR8d JPjI#A9YuCcB$<&%Qq6<j/m&I8N%R=u\@eah%PH:i:n>/dDAlnjkhh1A>Q&G*Aja5GV1>DS*Sd\J*E>9
l/CiWP w8q4$pbm@^%b5Rh%RI9Wp8wl$p^jH%=eKLDTuE5:G+\nhhkVZ?^?==5*FhaE+adMB6cl*1BZ/ZM&<aq\
kBQQn$ iu/p@AWpK<D&CNnT^58eZWk@jZduw>9EumBN4:IqmalIY!NW6@JC1jjQh8k#A*\1S@6+6QPMCAHP#C@e
/\EiK& \69D5I>!4%/?#L%<?R4Z:^6*lV8N?Y+@=V\&!Z5^aQ9IDkjBnpWjSpT<#hQmMP/eabXB8!^iT=XcVeR4
-A$MA+ 000e5a0bb5e00110334 Page 51 of binaries2.zip
^HDWbj dB&6YdWi!6Py%F9%SpM&epna\CiB9CcY4*hRu?Adbp<F&:MR89h\6lGj/uS/Rtp#6MDEVnX:Vew=kB8c
P%RZqB @ZDKeL*?89c/J8pT4$pjju$bkJWy1Ja:4Md%jL/c8Zd/NLTSpB5Y4d5Ndj9CQXP>!cTS1?nDY8dW^+RC
EI*nj\ AM9mhaN\lhcd\&*86$iIu+q<*N#k+KyeEq!*&MNQ5H/=8><kqSp4+VhbD!h$jjp@kt!FHZNu>1?$t:5<
*Tqhw: @jNX:8W4\Ey@n::iFjJ*V%mPE/\qF4Lk^S*pnHeb&d+5:?^<LJ&/t8DDQGyK=c9MkAQqXnhqaILR1=19
/K:Bu5 WkMuIXNYt#mk94tNFAptV\S#\D:E9KFZta@kATn*dkQBYLJli%h^julwNDHp5qHt^Im&ewEpE/9Bimmk
MqT*iy 1:>yyQ*W9RD?>phWd%=<<!b==n9paqh^G?/Cb486tVce%AaA*6Ciai%Ce?JTGaV!G8ZCM=kbeQ+NCNuB
Hk!y&% >*8icmH!WXDqDLW6!aSBDlN^aEGXX\MA^d*R?<tnnc<?Vw#*BM@mT:wMlGBjQ5i@LE&nXCCCLbWb&bbq
Z\BVh$ @pNll+AhE^@tt51SDHhphdklR*a^#Acn+cA&/YV6&5G8=Ph//9BWW&CG9S+m/tT<kqA*wQh?a#PYCSeE
nAEPlN DLDBui@9YNLip^#c15HWGZXHRtj1e:LG+X!*L5$G>m?=W8e%B?mA:PZ4A&=#^RuEb4=1QT&utT?bC?8$
yNQG>t N:/5t%V>w4&F8Yp@/<G:VLBRla/bC@Qa8FBXdEYJhNMhhTh<DyHW8XN/>m4*mkBq5=MkKQCIwV8Xn$<&
Hb6IE& u\m$>QiZ#YL?L^C5Z\qX9B54AZD?q996SQAqlB<>8&hk9<l8/Qwd&DS^+qeDIL9#Xaaa\iayePIc@Q\a
%VX:LA Epe$c\XbjT/?kn:MDd8cNZmdiKknGHCXJ#*KqLHNmk>l4nWt+>WTDubLwImQ^G86R6w\KQQ8K*Qn4&!%
u:=4BN MkMtQPH&J*!lXEFDJ5t:VbwV=<PICS5XVHI/DNKe6J@k@1XWQMnNBRGLSJkLL>C^:9IT#I&/D!t$y!@K
d&w>F@ IiYdl!:jCSj88S4M*j8qQH6tGb4iAWBL\+ie/+QVl<KK$5c#q&DABBIS+G<=nMbTa49Vjm6daL/E/lam
c9T6YM 5CSc9&$<?t*AC?HnaQCS+R*!?hXJVpkYj+<bY5S#Z#HNktAjMejlBChyKEBTqwF6Nq1hX48uYnFThpkj
D=&5/p Fu<KRniNhXceGw\qtHAJHZ>Ju/5ha1lk4Z=R/&4*P<5^@cB%hKNiD?ukyA$VaSK=T1+EMGWelRWZRKuj
@PEa@P 94I@Kk?@W/qP\MJSJjP9kyN+#Iu@X>deFb%MD>?l^:TRK>e%T$e/<!N/GhhMP^4jc1:\B#4G@6P:&HF+
hZu81w J/iu#A%w8i?AIL5:6YHt$*FWK1/?@\uKVZ5!ck@#H<yN+5M=RkiEB&Sj*uMa>?/^WY^i1Jd=L#\SZ?+*
C6\!$J YBmDcVPBjkRdyw<T\j/G%$G!h\w5$?!bpm6Wy=NZn::i/cEZC1RcE!<8eSpAHR1:KNVekamFj=k4IDAt
VMYj<F AjTKL9wqb5M%y6hGVe^Z=5K%iueT5mX<yAkeCd$4<jpnpM:!Ne@=VT^e^chIcBLaWI^bZ/b@d&^6X=DA
=B@@<! y9R/m%5=nTR9$cN^l??pjyTJqTC?QD^Z<Z5lYVAVX/6D>!GC>AQ6:jndZcR^<au=S86>9T868ZC:m%ud
bXt+4# ^>w+ZVI$6i<pw!w6p<CR&T@Ba#&cyeLP!\GLTqD6IQh!R<h6IlpC/SDmA*/5ntCC>St^+DN?L$H:ER>?
CSIQD! +^&wkM&h@LjB@:n^XXp^6p<D\Q4!=CX4V+<&96#hPdS5<Y^#EBbH$>wXkmY^^9=l5d8Bc=pHD^Ej46ik
H:IBla N$EZ=5GAY^XFqT/VWIw5*T=q5lPKeFEe8X$A16@a#ZVQQHiDJT5#b$nhDdDmJ?J%85>9$Fh^Pi#RCZai
Aac>dE jBQey?\<?Q<=GH9\?qKCPb1*huF^cipT$wJ<GuYy+jK=t@X9h?wQqpHV*<TBW=I?E51L/d/Q>mjY&uW1
aDiY:n je15T+=FaIWN5#yeKt>55LHCyQbd:8QLnVZFR*RjD6e<#k8&hL%@Bk:MWDKtR8p=ie&=ei:b@Seb<WkZ
N%Hn=F 6wJi+py1E@m\Ab9@q4ijwek&ZZ&C=pV/MQ9Ji8DDBC!4^DK+p<eBE5qYmA@D!CFPjFC!QM/=?lEqY+I:
+T@T9: $=LiXNwmJJ>\!4BEaEGkidb8IHH9dd6u?W4AdqjE/VTctC4:a/5Jm>jS@i5L$yhIP$c@456D:t:%nu8C
n=MTlC Zw*W!4EkuYbKC4tYX!lX%Wp\MB/K$&=J*k66y>:c%WdY#L!ZHjjuGLN>!DYyR1@Q\ES#LCny?t1DP*ky
$wty4= 6Hq&D^Kw@^plPD#h?Ju^bCkHnPXAH9HmGAnhR5b!en49=C^*<qJaMVHnX+@8:?^uCLRe#C?WpB9P6bt6
&%H/M* 69kui6CHiiylp<iw4k8>5u!6a:^nudn!J6F8Zet%lpF1$$l9$4:FCLmS?Xw6FeBtN>knDHlbej4GTnGI
A>5+Tw F5wVnB#<u$!h?<KV:S1eV5JGa!e^i@?H#ImqdR4WJCJXhQ^ZeyWGbyLjFDyXw%8A>iLpm4BCPBX=Y?ET
6$Z$Pe 68Iy*m$V58%hbEX@WGnb&uFP4Cq^I&:#AHy6\5\ydi!<awWyS*wRNNeNRbW>S&!I56>ZZMGQ:#aitZD>
@8K6d? KLy\Lui&PF8i5b^quy!DyCW:?Q/L!hnFRMk%^>dPw+&%6Rlb$C#@uKeqyE=I%TT4^K\Q5>ENMHWWhlqY
Autm+= c+XH%^m>CmPGjNX!Ni$6c$%bWe@e+R^V#qXnLcu\qV%NLG$=6KM$?kVShYTletyMcc8P6Iqld#\bS&qV
##Vhcc W+pqTG6BbdmZcQZQi4C%GtTuBMw+6C@P%Q*MT+P%L/jk&:iC?M>b$\C6pmLB+^l&tXk^d?QFna&Ittun
5$Pmm> *:GqXt8@5iF+JH\a&uC=6k%/#Z$Wk5*q@um%wb$L:6Scabi9PB1?*H%>Vt@J@ja:K>CR4&hu!+jq\<QD
b$SDDk p1AhmA=qFK6&:BjTt$m+C5HTSkb!VLDEjKStl\l&l?hm:\1>pwRqjbk:?5P+KdjW#wFd8IJ^nnWiF<b&
8498TN #n/#+y1c4?KBujQ/qmbWABa^hbP9pkXVEPh\+S6VMCI=*>mPbj5HSRBdJTVEcJZ#NPSN!JRpbLC^=kSd
tnZS$K qX6akYDBn/*q>4tMS\1^uGukJZS5i+#yN&P?R1t5H#c55cYaPI*8:8qe!>pDM===l%mV4&K?ayy5E@VK
bw>9l1 HkcY4*@Rmd@@I6ZRuIn<SX&?A88ZL<??1<H/S+:qK/H/<Il$yI&QD+5q#J:jIGlFKZaF:G!kEycSBd*c
Tc@#tu >B/#iM^j9FPGHh64hSlY%welHVGwESP8G#L/4cbn^EC#VK@k^BXE%b%i==c%b5D&Pwi%dYlKwFjepP4$
jkBZm> XY\eDide1#uLYN>9eIkY9kp8Z:hel*q5\:JP4P*\DW54XD>Z5Y6tn8nWN<HHijQl6MCW?yR8Eu%EaINu
CNdWDQ BeP&EY?E5iLY/e*e/:HWQcG68nX%Dh+J5ZNA4+%6p1<D+Mpd$i&4b*ec49@KeqcR@TL\Elj?@cP<M@e:
XW9i6G *SG54N$CwiZDR5X8n1*cuB5:!><eXVmIMd&H>9$%IqtqYNKi&I/X$M/w?#tV/aS\I<I@!u!aKLXi1VXa
cFmFTN =6bk9%dh+iVN&+XibZnb^PS4jZMD@pI\+D8I%t?5JaFeN=lM9>&#FwZR\AceF!V=EhXBEbcYaFq#GHBm
qDTQGE #9%H$iVFP:X&WI9%Vl6LcFN%hp5MyXP&6&<#u<p^RWy@@%n?S\+4%?Awd?ukYJ5Q1V+uDN*YbHE6nb%\
SeDQu& q44X8E!$Rbd/Ja^iFhW@ey>!u$kAQ6y=@tnu$e:P#nQ/\ZhjnB&DZF>?SAwNpqMJ*%^88bDBT/kI?9L!
*p=WVE +a#\@Clc&ACib6Y5#=k99^R9MnFm:Q5b44V@i=G^h?J:kt^y5BpLcKEQM:*Cy5FA?uWb9%14cIX/4cpK
i96X%C eaYD@*YyYNZPVde*N#a=5V91ISh^i@Niw1/Fi$CwXk*w>W/%=H5P^aIXM:&TCX5:SD+MnK++p%mKaajt
1+IBAj @^hahddR8$5qXYpc!jVKHiSm$^wA:SCl@8M@@8M/ZX4\n?w+6Jan8m55GF=@<GF%wEt1P&Ch#cJeW&lQ
6N*Yi5 +9Zulk?R4+VFJ\bLLkRcb$ASHJ<i:Y#e4\YCjTV@%*h@Pq9w@G+i::H&T4Jt#LRhQFP>cbpdpPW/MJWa
F#ITS* h^wFiQtK%5+*MYV#4BN#EKDD5I//==>q451&NyJD8:Et#J\KG/<N=ePI=yCE4hTP6hPH$i9W=pAPi=%&
SC$wT/ 8:1>pj<1n8A:hl9CA@GNCjb?A&Sc$F!K8&@*E5+D\SInSwjVme68tZ>kKcitFL?V:kVTP9JeHScY6Tan
H65c>L n%hT4#:M*ydLAmwD&@BlcCJbh:6P5c^A@Z+dC8&$?hGM=!m#c+LMluF@w6:lZ5Qw>cQkhMcRje1h#ZMK
F%Ph!B HLVh=^6*\w!JDZ@u1nn@=?KSFNwT+hFq=&YP>\VVqp*bb/y/LV?CXF>Gbt!PI#9<>@*:5*9%QpuqqclP
<V#j&T 4BK#Qk#=YwadpSWutbyd$^I/iq\qipY8VwZ6HK8V$L\%A:a*HMFB9MGS%*6+E?<LE5^l?e4FX@ecbMiL
5VK^6k HIpq6QQd!HQ1ZE6+jiJ/n\/E6RFa!uT%1aR!+R69XG9$1wit*1cJIL4*Q$Yhtq1G+:HQ5iwK#KG/\\yn
y#ad9& J<KMQC?SR#yhFdDqP59ZV\+Xw*dG<PEbTnyiQkQJA6qHk=^C4*</yWeWyh!b&4Fm$j/Yi/+mhDuI@Vjt
tPd8YA \aI1YdPk&%eC:Qj9L=<V8^eH^Rdb5QX!w>tY:AupT!Aa56$Ri8YlnanpXG5&%cwmlp+FFF6n@:^YTYyS
:RZH6X <+!VdKZpcu8VYi<*Lu8FL=nLe4=^u\q^WH#:^1uEuBeDTd8^8X$>/HBnPGqeP+$d@uQXyM+BP:eSF1BY
A\$VVb G&^l&SJnWaiuwndypn6h*$MDL4t$pPEk6k&cZNG%8>iNwN&hc&$56+aYYQtANADAcc#H+ynalS>S=K5B
e\!B@< CSwp>51w@i:M?iZ#4<^w9*#H@^SVwQ=IYjBTBDV^e/JZhpD>^pu@G&DDZ?<YVK?9RK+uC1$\acQa:<TL
hwhNB4 GXlYC8E6\j#m*yD$ab+TCQtKRhh\VDC>\5=BBb$b5CJm/=/S+LcEBNc%D$^6P:>BX5+Gi!XRdaY!uAL4
JS8+GP \PDLBe=8plRKYDu\St*ANhFyn+^ib#4FL#VY+@GyF^!$P:j^M=\+4LBi1*h+yy/\+DISXH?lK:hycnja
ht&ZQA c<mk>nB/8YZniuilN$um#P#GY8bNhiDiXPpXwDwjdybJH*/WE@t/aItKt#uuEuNGMF>Qu4FT9QcT**ct
dP$uRM w9l5<E\t5*<=Y^nZHkkHFm@W>&jmMH#kMP%@G*B+*aHNTj+EET!ABTN?Iq+uMGIY5D*w\@DaEd&YG#dm
Jewjqm Ylt^Et\N!ZT%k?yBdd>TC!EVuTY85\cqq8/k8q*+!6G+k1d*T\u5@XhJHaa8VCLl*nKLmaILV$knQ5Va
VPIPqb yGHW>meR:ESuH%^i/4\wG#@D$9Z1Wyyi&1\?$/hFXL=hS@P6Z@di@kJkMW1!\bP$GhnnL5>\hwY+>V$W
mmC:5P WIy#R9#E$kTIY#MnAM9A68BHLMM9aRV+TZEWSQWBMH:=DP#&/!9l#9Lmy>#k1$^8aZwF1WKll6h1wL:t
hWC\hl DiHDC$&wiIYAHcQ/!1Q5L%<!5D9*:QDtcC!*a&N/=d\%yE5RtKJStBJ58Db1%bVyFiK%j1^qnZP4X4@S
=cK<YZ @GFE%69%&6a&+npeZQ@&lC&cDhchNmVEA=/55Xk85IM9ec8EVmKapCX6j\\du@W4R*Y8dh!^n=?=>N!t
-A\Wd> 000c0d8047000110334 Page 52 of binaries2.zip
dA4kHX pjZR%MIlG!ZSIpmB/66j$I!&&$ChS6iBdS%*VVQG:W54!Jybk%cbF#Z#95/VMV4R$uLweQmX?DB1yllC
VA9@iY SjKVAu#tEJ<>?p4$tueCb6*1:L8aPF<mimXW*+PTSea14p6NqTE#>4hZ+MT9YDhGtB%1MSQ55/@CmLhL
K+YSNI nY*8mRhk#T@B8K/dhmH>yAVYP9Ql%:ZKRdY!Z&61wWSW^!E#dApXMuV1eBDj5X=$@>ZIXZRulGTlT8Wq
!!BuNJ :b<bMeV8p<IYcW+hV9$jByhStKp#5dddP8JN6p8hF5ZN%nRHiSaKl<VF$N<DywD%q?MZ^/nR/EK1H8@!
R=uW=h VI=n@uNwZ!\68ki/u@1W#cq=J!de<bebea9+eBN<iIXRtWADD=a4&T^4eAkc&M!y9<8$NNC4cXJ@$QXn
\88ll* nu*HJG!jKc=Rwq=^jl6dP<TQCXFPbHMJ?@#?Vn4REmhGC#b$#ISjk8eRTyNY=<PNtF+4qbTw>RDYV4$#
^\mMYA HZ8VH?58Ic$SPSMG^c?R4><K>=I6VBS:J=4VB5hnRcRR6%4=VHSe&Nni4B>$JNHJ<mcEaDZEL4&/iG#W
dZIy5$ qa<wl$PCG#Fjn!^1aLI=lQ!Q>\Dy&:j@V!Qah1QH%N1FqaPt@:5l5L+:9>WtBW!\&4bL8?Y\V/&QGl$p
SDQ+pN PLHiXNwl9YpF^#QW@m#nq@DwEhHtln+*M9/8/bBjqmJ!Q/wBQDnLCeET4p@w?uCYp<CCtn5D:F!JqZWu
*BJF1% pdCI:JR+ydkl5I/WD+>Y?dAwVnw&55cMtDq^yhbVG#MK/HBcJmcZZWq=nyVnpIZ/SJ!I!HmSDPK9+n4Y
mM6hPP Qt^$D\9wc&GLNTeid/c>CAM@5CqadP=eadLFlVcA9=dyJPlp/tP>d$KBCV5a?869Ghlj@yW:t@c/:VdS
dc8<m+ /#EnT\RKV6#XEC#lPqlck/hbcALE@Yw<e/I*q1#\ZdbjC#5GH><5+eWZQ*=M5N@99>^>Zad*<Y5d&5>m
BmV+<a ibaL%+@R9Qn8%R/<?yC9A<=9G:BKQQlwaaKZplwnE9abP^NLR1?pEBPNhDqjk9*DnZw4B4ai$!6yVkiX
#A6S<q R!LbY6Q<\#=\WPW4YmQ&yD!H#haNEb?\c1SY<y/Vm6taSaThXcpu!HuQM!N8T*Q+XjZH4Nm^DLjRaTTa
?+i=pi M+VS1Xe/&I$XLtqmKy<V6\VYSH@9Z$G9nC+$J#Bm$wSb^uc:c8u51wkXSt^>kK^^%*Vtw*W=Du9M?YFI
4pYQGp k&E:^?q\pX9?#*j@&>*ZS\@L^VKC>i#qM=Kn!?l>>Nw4MGe+JwCVZBdS:jL5pYT8LV>!!Qap>@>GP5Y4
Ta/jB9 S&6$9y+6IZXj1W4<mnWu>mYYT&#u:IJmpdeGaI%itSE*YR88mVGLl&qqu/t%56?$qD?u%^8d6I^?$ki%
dwWA&e 4a$N>luCXZnHXdAFF4lQ9wqeSiaE\j\pZ!4qu?TJS*>:5qHc4HMCt>R/#pIuAY&YKnIY1ce!VqWAq4@R
1>RYM4 @V$1XLeSIhQJHwb^@QK9T4DhZ45NVZm9^!T:B$:5Ahn8:8>eKK9PCTNb#Znm^q!V+#:5X/V:M:$?En#X
?1S@t\ 5DudkSQ@/=jq\%qk#duF+BH5GTFmI?*Bnp:/YBCNC=tHi#\+&:nLQ@tYZ+wYybj9ZLYLybQVVDbl^Qj=
hQ6QRT QH8ehpyG4>CHPa?!a</ayutF*hBy%C8XDLAipQdWuE+m^idY/bZHeHRphi*4@aaty>%L$SX<%KDVQH5Z
9pwJJd 9*$qRG8%LX1R*>luVI\aDci=b*$<*i#Y=!XJX^IbtuR6W@ypiypPPtaq*bwmc5/ceNEYaH*LDj/haIqK
tXnjh> 8$mSJ&V:4k>na6&AlZ4EmWZG&wS#mhn%8i\Kc:?$@Z@=cP^%CeG=w*pbD$6m!9mnX\uQ:$TbH=hLI%m?
B^Dcw8 j<Vh?4=\BahGY+ua/SthFYbnuPl!l*kA8!8kPy$k$Wc?kBt#M&JWAcAaT&CFP6^G9kTHa<wk#:%Y4BE*
#6j6F& RdCpZ+FiK%CHYeDP9K==1e+DdRjDBF9ne9W:KMZ*4CeXNP:K9kqYnjNdmNDj=jpjmAl5dG^KY\L4@VFX
Gay6aW V1^K5e!/uMleMLbtuYCHPwNnymE/K*!%b6jV*d%@Bcu?G/qPd#Hy155Ei/#KE\F<*G1=ydPdp*K6t^@<
uEeRI\ mV14bDI=H9iQ\amSEhXE6<5BE?We6EkaQ6MPJK?YC/bNaDk@Y+Ji9+PG#@Atju%ByQhF$q&?cE#PMyii
l6Ky8N eAiuDY/TtH?RXGQJL!b/XX\jLX+=\SIn94?VWF$VD1eGn#\BH+dB*VHj1R$Hkpi+*RwKMWG/Z&HH@!^$
V4&hwj S:^XMVdqb1m>V4h#YC&l%^wpKXw*Ad\Nmd6CX@4/>Y/V6P4>&maLYcTie1a^b+lniy$Qe&BbcV$5XMnK
QM<6dn 1E58&iBSF!Q9@i+8^J9d8e*4=K:I5*GjmBY1E?mY<P!S9klk>*mtJPS4n%t\8BMHY1&q<V1Z5iPbn?1e
wjn&\N hQ5AF6&eT^8QRJVRtFnNbV+Md@D*lXA1/6VQFkQR/\:S<EJRyZjT+$jRuDmRl*ChXPh<$jIe>Fnp!4t:
Ln*6MD =Th%Xu!EjCX6T?K:n*=nD<W4yhmN4!^i6=E#$Y:!@AVE/cAS>=kQK:$&qYBb\LbJl>yQ$TmZA\A>h4Gb
t?\J:% 914N\6p^kbH1:Zch&+a<+RS@m<kXlFJJSh15Hi!V=M/DuK%K:A+>a84XA#bli+cT/N#Pmtjmw9XyWCQ6
bt&u6P VK96B/TZ!a$Z96=w&<dy=HkQ>E1\E5EC#Va+<c=w^D$G61ZiCZ4%ldYL5R:WJtJqj6@^yD@GFBX\+maT
>TYwA8 uJ/JheQWT4jQhJ:wh<lXF1mEdT=H>Q4pm&nJb^DGC@a:AXnL16naijS5\:PGu$mXJD1npy&nqTJM4=c*
95C?bD ^8:EkXd69H^?4@=ldm<NYN5n1cenC%a/^BnBP1/ack^Q+1>Rmwqk/%&V4@FwP5ta/GE8Hd8IYddt&XIX
4kB9MG jSl!bP*LJqF1yR=au*AiMh@D#IWJC=YaaLXmHidEd8$AITqhDMn1kK8SDbIX9@J6EK<mGwWS5?L$C:5t
wZ4*pN &6$YCFi>l!G/Dku:?*KqHh6W^lXQQcwD*Ru%\!&MBm/nS!K4VRR4:JSuk6Qhh&c+BQWbc<cQWLH<<YGJ
n\^cY+ X^ekXu1h*5==l^!d9Z?E\N&nb:VGyXlkR\iPFdllI1iSe?L=lmdMYmSY@y:he&B>G?+t1MMEc=94/cA=
+Gik@> Cd*8tb*V+EytuqZhXAF:CQqcce$<>%1#E1bB5>G?IeS=8aL8u8pT>k+cliblA8?DCTP%TZyPmQP+<ASF
&*VwlW p&DE&l^iY@>EFXVTlNE1!Ee&EkkiKl/%S%^aykKc$$nq\*nTI&Bl/8CtV\VdbDlb\4aNWRWZPSP5NekM
#lXG!E \TBm*hkB^VIjl8LSJQ5X9QaM1JKJk4\%E4D*n%+6qPtT<pVkE1=Q<5TIkVXhta+B@QjuG:ADN==>H+n!
A@*ej/ @Glu+!6uVicbYnhKliZbRHJVPbZ%piT6jZ*&Wq*FwlE@8tM9w4kqbI#NNjk\A!6nbDnqS:Zkk^w!F#E/
E1nNQq mCS4?l4$Y6>HN%MQ\M+6JSE@i6lH5q::EL*CPSMGG6M>tcuAhI%RBd&n*$I6#+1!bC+Y:nujhGP#ZpE?
J#RW$\ nA*9tw&hBKNCwFtaP&+qdnwc$:n\4ShI#n/w#nNyMct?ba%ajE=hJXEi4+KInt6Pk!ZuS6&G:6MjbP!^
t?D&R* tdBn/E$KdHq:^<kXAud=puDciQd<$WDXahqIuiLeeDJj#5/A<$J6YQ#:$cNH*:<9%jnB>9#b@d$Y*=RI
nY@9C? Yp%XSG!Y@q+?&:mu4*n$$uIWSeV8*KQjbctP=QA&1$*ZZhGH$cNY/dXFGpGH?+KdkG&%c*WR:IEEaw>u
nDCNE4 K?%M8b?yNF\dIliGGHHy!abyT=4H>iZLJu5m/+A&D@XaWmtETTQ^H+\aa\qHQY*BJw+Ge\6/kw1*<I=4
Ahu#PD XC*@^j1YTtGP6DGjnZeb$djm@PikDmbeeRPal6M4\EXiDLj!t48A9RplP?V@E:F!a%P!n>Bkk8^Z5Nw#
%/EH@4 WbKALp#b?hubpq<<k?TqnX8EQ>tBC\IW#A4X<p\$+?ZmB*j!GSE6$RRcpJCB@AAu+&<cd9@IqS/=EGb@
8WqSnM heLXYM@8NnDIRca+MLX&4/Y@BC*<htNFI&/CES>I9\WRdLdQQmhTb99m&LGTePpeI6!^y<tt&\XYmc##
?yQ@5a IFq1t@8EKDV1Yt$V*eQbd9$tKSMI#/IYFnPVil^jD&+GZWBL$>C<=Z#wNnyVYG<C4B1PEFmlPj&m:pSE
=D$<jV aVGHVXGpH/!K5E4c:1+&6HY9E*/1Cy1^qP#$bcRXCc#t>4M#bcpE&ELlBhJL%1QkN!Iw9/NS?Ga?9%k?
=tMqE4 wNpTZlS*B86Y:Lw+t=<Fh%V8=R//NJVK&+WC@MN@TMd+d==idDp^Y9D</L+k/dNNkbZyFZ+J1XMkLL86
=\P$b4 Qc:^qXGbHNHyEm8GBe58J+J&Z^SmPACY+y4*We$kYFk/*Ld>:y+:49C<EwIXyFy:#ek?pZSEJXmW/Z^F
Xd99B* >ZyJwn4Iy?u=lDP^h5SqcWQyhiC*#nYhn6$Byl$SXi*=MQNF$GKXTX&J8:y?8:!AY$/9pnm^?@961pb5
lw1ZB\ iY\e5YNcHeQyJH$I!5>AeI\qWGSWljii<bMe@?<SGwM@&e^95Y?Z:TKqeY:h6R\?btZHb@?#ntVaKT$%
+nTm6M JW=KQ1RikA51Z&q>B+uZuc@qWtpdTY5I1mP=5>i?%u=4<CT&*hByM:KwVki\>Q5QK=Y@XmTtW>uXYkq9
tn5X@= yPe6%#BjG!/u!lN81c:#*ik?Z?XFRcmTiL*n<w=9&l4#Z5!l?#\QbGCXYHK\4SZV>Mb>k^G!+w@u%G%&
8SjMQi a5\mLn\*@/+i%4kHJ@HiL<i@@QILn!%#PF84\ELPjq>1K^pj<HDnCeW<>a1lba&+%h#b!RZ<#kSj&jkb
?wY%d$ Zu%+PEPjaT=9dnIuQtNtQFhkq!yy#?DA!Ip6@AyhM%G!ZCbeQ$wiia+LS1VG@diBpm\D??lbkT898AkY
RQlkkQ &SKh>qZ9/uPt95>ST?d96b^kIX<:P4/65y@!ZDXC6lH$Jlh<&nAeyp/uARhl*J8DbC6R*ih<%j&<6IYB
F$j\@^ 8@mJhKDaIIPHS/nATa#X^nZK&myChcjdY/>wuVpF?hBQb>hiH&p8lVFL@uWY4d>kJ6&itPj8CyhHQe>l
F5!<KC i#GZHyuchETtKH$\aGplpWaMipYTW/P$A<wWPFYt/uc&EGmZD<969A>FGmnF<q8\GGAj+iHbuDFhCJ9i
j:*$*t pjS>#E%bu9%8GiNAFnuG$ttE8VEn?*\DyM&>L#8Nu6D4qiuDyF5&iGw<:HTiipj9kwBqimZc4cSMeRSQ
Bq?$ji 5<?V^$JY9XCG?wl4JhGX9ylpXXm4??Dl^Iu9^FZB>G1VYBB\S^5SD5QC$T\N>WWyb8YJt$SH9mAdyCGF
:&bL6M X8L89^Xa@<c/uFw=p6#eiw6bhCDZa$bVR^^Nw>hGWIlj&G:t<+liQYJ*VNCm+RykddX&uy%^APbM6Kj+
E#yFny c4A?@K\V46DAcjMV9Q^uDCk:uiRB*!?aCaQWAY8V/A>E?JA:?@V:S\Vhj=PMSZE1MlM?+Xa^n*dRi\%X
ta^SGu X<%iw>h8h*6p9X:%$H>aNKe8HBNhyW?iCIy?VhAWMSq%9<w^HTk@Xl<%X*1hY1mP!LXkM&nYyEehYh&Q
%IdBJA me^%VbDc6epby9hc^Q+XtiKI5ZMH6uyFB4CMl6&J6DwWqYl1Hwiq#eMS5tWjp%k+W4ebIY@D4HnS6knV
#$:&iV 9V$E&bqiR^1^p/=4V48<I&ZE!l>$iL!\a4FkYeI&h6l?Fec:iyEZH^+i$JwYE?t1lC#B?:MEWIYtq&DG
\NTIiT #LClGwMb$!eY&##H14HVZG@6qPGd$yn:d>ym=DiL:uAX\QhHRHWhA!hduLLY8eK$V8nDCt!Q?*l!*q=Z
-ABHM> 00049709c1f00110334 Page 53 of binaries2.zip
/$@h<K y+\jaya/t55%PkR1PDH>%Za6EeaDatww>p4=P=<b6Td=$AR4WPW@wL5yhS#5HC=\KnGu@bPqR:w/VB$C
q:>V\B 61e>*WF8M&Y#WlCpb>!k%iGj>p@8aHwnQu?dlck@:i%d#W9ec/$C/\JYk:C:9<>9I&jmjBbT^ZtXkYnb
hiP#hZ NRGKLV@:1Bmi@aqeJel?5mXM8LIJ\:%c&c^4=F&9JJ*uG9cS5Q!A<$Y=F$l#6:G?ZGnYMXhp@YcX6uS>
1j1>/S NZmFtw>Hbc%Z*&&kWYJuCDQu1u8Xue?5VXGD$@YRYl9w6hdkXN6&w%d=Xcq89/F/!8*TLFlJ5t$E5T1F
PRSS!b bE!8!Y9?FQk\d9NeyMQyFNKi8HDHh8\>BlQCthnB5WEqq6!J5ZBmT@jtu5L#H%w#MSG#>$9@Ma&1y%nh
CWPkDe d@*CR$F@?WZTmG8^!%VV@+%pZ&mL+4uHhRC4#+?jnW>=pk:uVWB9Ym#@*8XB\1y%+4*w6<b>+1SQ+8b:
u$#%88 RVa5Aq^EFD@MMW&R^+#8!mVb5:Ne8A^ML^:pZ8W?um%IHD?Z^8?E1wVVEVwl/@Wc?9BMNYL=pejTZ=pp
V>\@1e dLhB<4Zh=R:cdSKN9%cE/J1tN<$n/&QYL*5QB\Z%D6YBt@\bYSL+MA9YQQVkJ##hDGp!eE*qtSHDllZj
lFnQA% lDceH16V+PcD1p>#u:^kdjL+<c*lLW4VdBZY$d4m89jLC4&!#%VLJSuYZSc\#QCZ*wbQI\Cmy$*:lP#p
pwF4SF YI#a=+?Auq#qd^qH^+?A/lclKyAT6NI4ecHyM5/9qdkZVYLB!D=C$&??6l=?=AS$YakXVPdWC!J55GC+
S9liq6 BcYqcae5E8lNR<#nWJh/5>6w5$LMdJnu1NilPBF#I9KF/=>y4qL4T\DdZdG$tmjqk9jQ?iK^^MhjH1e8
bL$/FE YkZc8!jT&ppJF1W/$1M+Z>naLqZRdLwHk8%KAd1&^DSiQFiGK/c##b!:%cC4><%VXhq5ZQmI*&1G8PBc
d<RPGY C^/a<w@$Ple#iD+*d/J=uXnCktBqqk//%iai@n8Z=eQ:PtbbXVu=89K/Xn&wXk=Jm6Z=FQ/:y$k5jSte
cWP*$\ wF%tnWi/NlnWF>$Z4bBG5Z!I&RE>?d/:5$/w$l4A8*$Yh&h+ni\D#AqX^^!1^CRp&i$!I&/n*TZZELck
kt$M81 EePElXbdcbuZ#t!Qcd@k^daTJ8cwBAuZlH:K4%WG6Rw#1jJXintllZlBl6il4#lmQ$<+dcLidLh::Q:9
EMNAw% VWa?!6F!q:V&Swa\IDm:6AEN!:p%#nMQ$aTBFTHVc@&!y<Bc\E1Abi<y<t6NeV4inj\de!$AEM+Ppl&#
S*uebe :ZT1\Qdj<%9i#>?@H:#uci5uk^P/<E\/qn/+w9pjuabDpC8!^KS6dij>\qjB@FP#lGHNNSu$&i!^NN#q
uy6mqA Sebj<D96G654&d/9<!Bl4kjelbHYc>p5dyAEcW:El<Y?b$5HY6IiX\*CM>El:q5:BL*T%wH9j%@I4nFd
8@k9bG qc?#&ZyeHP@h\l+@jt!p1w/J@RyQtiSm>Z86cPjpedJnC$<KtMq\IJP\8ywIaV&bcCtlCRmR9dqXTe9k
h1uwt: <4!n=a4M@iB5&FyZh6iBc&8FZ6j=WduB*SjEQ>^X^ep5+X6*V5^<48np:c^QN&#4HKNp51iVtY9cdLDE
V<XPkc BcW%=48$AXRm%wQ1@88D%@6Xwqmm*Dw*JMaFVW>LhY$D*JR4=MF8:<X^@<Z^*w5>G><8q?j+w^8M@Pa4
\cITH9 $8/$uTuw6Vh1n$bZw!8iE/y$AaeE/BZp&aEmnFFIdhce/P=%bb?DPtVBml>SJ6FIm#y9Q<MhPjNIjESu
L#mT4K t+Ta6/$G8jp1nTbM96=LqS%uFBh+lky#a8RT</mPweX4^Ae<M#XJ=nA\wSwGypX=H1Gue=MP6k6K%jw4
E1J&B? KV6meq$Z!t&5c#EY+h1<8b$:4Cblb%:HLk$KGNa?E6nw4>qtq\D66ctD:?5G/!FkBcAHcBjHX+BL!C4h
DqHI8% X1XTpV:V1M6Ihl\G:dS@jA\lVyeZ8PI9ZHd^=:Cm*TXS/9GI=^F^E9*XmQn\^D%PW8mA6e65GE>be&Jk
QdRI?j c@9yQ86AJGA%MmwS&NP!S9G@=i>CD:p<!JWH^DMD4+mSXEHK/h*G%/<&&AHJdE??IW/\5bHjKqZ4VLBZ
?LT+5T IFmi/TD%n^Mqql9Yu\K&k8@<NyD4XAN$&1yHBP^\$qJe&aA6e!*T85yZ6F?I!mhdA?MGcqHbLGB#E<?t
Qln/ma y%M#a!Zu6NjwECRhAN85<jS6KIAXFcpHwNQD%/?=CTAc&M6#\9&\W6?9%\<E%EM/&dTLdyPY!uGZIV$?
e5:+Iw Qi/jK4R9?6>Z5cWZ>@d/4V%yE>:Z@n+<kBeb8eTHHhkiM?Jn%aDFq*lR+&kqIh&8Aqlt1C&tX=Y9y>y=
GSNiJA pAD>Jyl!>&#k8ypmD5S/hKdcE:hcR!ekTSY@q<kQ>#tFBW9A\yqIGn5/E!A>ph6b<ll5%b?tQm=h1jb&
uE1eCd lRqQ%hn$HEJP*&JcdcG<dq*#BwDn8pAMV6#%^MVV8R*c+R+c$XB&G>=N!I=u^+B&&Di=%t+n5/nYcSBP
WAAuRq >aQcaa*aLYn#eF?AQDkH1S:KT+j:cQMI81*6%@t>nbwRK&4lmA$ek%\b%hQV$\F6y@*@&9?9VLu>:+I#
X+F*GI R$9wm%Q#iMmFCN\GG4Q/4pRjqpTQES\THNNlVp#YdL6hS#/REP\B$h&9!wnN6Weu>MW*NLdl6Em=FGS:
@Q=CmA @Qk9CeK&?A68mV8ywpMYldTk8JeYMhCIN:nDKW@CIyXabC\*Y\%Cq4&KEdLc6%>S@TA/p<VByV5$#:+b
%VT^8D VZwR5MKIWR4K4X6d/!Jk%>ed/<GSTL1KeulS!m\AeLQ1ptbPQPpjn#lwl=R:M6CIbk@d#aQ&aS&D+R>i
FN@KjH M/S<QZ#HyI1teW!%C9jBc*yu:jCkCZ>MY*wIEBNtDn\=Qn&hujJqwNhZhQ%??q?@u::wM!ED@n=jS*&8
\n*%8H #GXGdQ4\%L1Kndy5/cA86AqG9M8?mcby^M!I\W#*mSEd4Le9&BHBZh$EW4yB9*8MTRTkVLJXWR/Jl@NR
*#4y:= HdulYA/KabE195G\M4$iwAkL4RqG:J@RIe#1XJVw#Rh9Q^8t1IitH^JWM&eVL+#8Pmm%yjScW5WJ+#R+
P#BmuS TbwIh6h1uF?a<&1=KtHnw6lVLJ^yH?X%*T+*/wK!S>DRH!HcPRC8SJME+V8kh$EE8+<iSRD%6SC5ZQth
>6^QF4 :eM&Q6uV:p6aL/jn6+41+QS*B^bZ8\P!#K*bT*I<G9epXXPRJV+<$@u1#IkJSe*>cTDVq8\dTS5lG@ck
&!Qik* Vw1VtKP:t1k:9^%5mDhCSk4I$QeC@Y*t@@L+L$T4+L?yyNHAE:u=XV8HaQwK=#>J:%wW:Y!RRm\V#ul$
=6Et8T ZdenS>pXkl$Hpy$^ZZ/+?jE!9dE!PIunYERDqh5C/d4SK#hh\KNc8eShZNYLCH1%TP=eQXntuQmkeaab
6I*b^F i1TjV95<IKE@+c\a$C\wnt@cB+iHDP\:dyy<RNBiHL/:*PjGan#/>B\VSe+B/!G>6ZPI?hYkic\SRlXI
^Z=+!* kXluy?>Q*@@daKbYDq@wkaDLF&LZp&MJC8N*>up5!jWR@8Gy#Xeu^dFJRKJ1F@IX*5RY1ZpHHRG&Sa#+
ljE/mK X#Dm%&DEF8%<4nQ:dBDIby+V/WwE/?bjwDD>K5BCMRauJ9lIX$Lyqa:D+wcJZA^R&NnAYJ$1M6nwl%=*
1kDZm: i#K8\#wLc?tPRZ5n:5ZRPhwTj4u\ky6YCliG\hVh=SaVcE5kDiWITaK=DQp1Aua9$C9@Nl5Z1<nPnGTb
L*WWbj cQXdnmjn+@FIttF&Tah9Z\FX+1qZl!Bdp1du4!@iwj*jP!LZ%^hE5Aj9>8u9pF:ZwX$HB>eH>KG4N1%n
X6!:!l Yl$pJI?JDd\>uSK1k=9V&d?>@@**?i?@E==#8l1&R5Kk/KtR1%V/TRI8e18#e!n8^4Mp1?8a=Tp^FdJn
1tuQY: &\eNcMTwLt\e:L8V?FSmw55Z+8ljW%\^*BIbX/ZT=q<&@@KZFMI%&$?4iCB?mV^$Jb:mLIq4h!^l&dQ+
E<dtw: BKMtMZ:>AMW/^ItSMDX!Z:FtQYqh1umNki\HWC=n?pHQ><!/jW>MdTLXkeqX8HGDG:YKjC&Zctmy6^:J
*W1N4b X\5^?PnJG=*9#N#A:KnyKd8imGXPYA<hwR6dS$mYGQEqZaqID\<WQmHZ!@NLNNqF+$=MEu>NZJni!=>C
H/R#uC 1kkpD?&9V*aWeRScQ1h#\uT8j#t/+9u9AQn>:?nTCXl^Si&RhneSSp#/5Bat<!pkSm!q?4$GI>#G:WGd
Be8mHa m<>cuZd66dkF>/6>qc@QhGdWuTVRqjKdBS%B?bi@dCdk9+!6^HQ\kIjycQ<J/W%<4&YVV\yQN4bKtEnI
LA=uEp iSPkXYJMpmq5I<+qTeKJqlu9njnq%T85DaS6%9%IbyCNnq51aQ<uy6e!i4hCHibiZYmYGA4ZY@N=eDuh
Tadwca BtSD%Ne/QB$nia4+RXj/%\+:w@c\e>Y?J8K::F\ewtZ!PZhhQRjJwuMC5iS*4>F#q\kak:\8Dm@dF\j$
Nw=M5T ke/\LdAip<X?DPeHWiweX\cW@ycANbiVJ:@VbRbYQJ8>ujZlX86Ly1@TK@5qb6^BRT^+>SHVd&!*&JmF
1wEbT1 imicp#Bm$y*aS<^yMET8c#wF\YA6!W^w>D=Q$m1<Emq+eMdiK9BlVln@Ju%N8XG<FGaXulR&6k8akkZn
J#%d$T V?RW@hlS4!9Y6n5X+S:W<!1G#@TD/MkPNwjudAkb6+LG5E\\aBc\/>!\qil%9TZNINFa4>!T=1bwIZJn
GSNE8& A>tZE9ANZ1iyGn^1<<!AK4VmaXhJ>4w#:F!*4#8EFnADwaI!D:un%L6>cRD+GqD#ZGK<=bI@eMX#lNDa
iC*XeR pJT^YZ?1kYXY>RuLyXA4a!4aE8Zi#Gekc8m>@bqQk$eB$%D<\%N*Pa$I#!bZE6IDKZqR#Wte^kjXZ<W:
KPpmdA WV&FMbDd<QFC\u$bW:+pCa\e94L6tqdyn>dEJqe%k%+*^JVNY&pYBnJ9E:BRuAA5&B1eay&lAD9$FERt
!/W$!% Yp@aDwqqcq>/Ma$&liB4a*&9^j*p>kSNhDShS*N$G<1u:YFA4\/5D!<$my%!^M=bMbBXZk>kcRXi6$ik
L*bA:: X&B%!B%5yBuG/$5AVPS:!N%PZuN@DAALd5*AaktQ8haIZAuT>h>8jqhmZe/SSwYD+Z5<b=b<<@95B64X
iPPIuq Y<uRpT:JY5IE9+T%&tZZBKHHctGVjj>Nh9tVb5\Fw=*c9mTeX9bj\HwjeE<Vyqq8%C^n8*X<dJL5A%J\
aADt$Y +q@Xl1XL<qY%JHS9Rm<Sd8/EtZ1pDtP5aKqi^VlTyqlalV&MC=bp6yHuDp<%8%VQdy#9=D>t4DNdbelu
eTt5\B 4$F5tHTqQTm@M55AbEy&Dn<84%8?SLjFZab8jRL\cucm8BVXZ!#YD4Dq66Mn/*CC>4yZF>jA<yApK9eV
c>^+WA P*<u+*+P*4*nQ9cH=>JN+Sy>h1?+M@cw^$d^Mj<t4X<A>WntJ#QmY$Vle=#luMNSuX1Ynp$QWWb<BZ%a
MqPnRK $1$%8M/FlF\kCy&ad666ccP!C+Iq#athmbW1cpXj*XtD>d6C&aa:R!pyEc1dbPPp4AcV#4VQqm#$+!h*
$FH5kb RLC\<YTn5MEPaw#T\hN<ab9p/*aX+<wPIYGllk#y&l61<1qJYXYN^>:K$GChcAN*4\qk+=ZwkFkpI+4t
Am6J4: c?5!kK?<#9S1R#Tnqwu1!b1L=%uhmcw/#e#%yG+KdZdKLkEMaTF1:aK4pyR>=G+JM1KYG=9LFCebq<k>
eyAiG6 AjiJmwqqZ^QBnqCc%BNwNHFcaJYB$@Me\#5ZetY/9YXYHHW+b\MAAt5In^Q$+XDkPXKClaRqc8EEC4w>
TZh<B: cHiFE*N+Zb#@!I#@6lbt1JcpET!wFR?1TRLSKw^a>GLe:Fj!G=l=mZI^RQppD+DyluVlnW%MiK&BaA?c
-A\d*K 000fdd19fb300110334 Page 54 of binaries2.zip
FdK18e 4CIK\X:%$AKIBhl+FI*JtHFDSQn*Lc6aanmcPD/$*4J\Yk%:/=C9^I$lXW5<yEL$J86J#Ct&nP$N^p+1
WanN5q \ZI\$AI:M<8<tRYd^&#EpSRN5bHBBdwZ%\44ydR:X!^^e!/>m1SNlnbV<MyALnc!\Mw6a\mbAFK>JVAJ
<R4++K aPLKYG<=/@5uK<\WCmp%bL?E#RLmA&!&tVy:ZJYENl6hnkGIT6^8:^Qq@R4@WZ%?!&#+#5e!Cl$Rq$Q9
Aw6$N8 ?KRC?jyZb5MbW&%qu<&h#RJG4G>6d&:#A\cbWN:al4iJ=G5h>E1tDu\*5NY9!c=DC5BI^tHwGD4?Db=B
6yS\45 QFY8QQFa8k\L^NnYHq1*n$dhuV&a1!$RKRcPwBM^HyaX%*ZPH>=nP$jm>/w=*i15=^laB6hC>?c5++cu
^pQ1pu R\/TTV*>=bWMmhEyi>\1Vu1^uq@//Nw4Byb4iXZPlEaQe%FP#a4YPdcC4L#K:a!ph*%aac\WE^?YRpCS
W+Cpt6 S&VB6>ym\1JWhJih\=*&RWe1><tG4dLVcZ?@@99!8^E4+FX/ST>aHqcayEqXcJXb<Y5<RqR?&Tyltna$
&Ni9Ik JH4\yEVa=y>kAmPt8&=9%db1hcnEda:D59w$RnpY6E*wV#nEmcSTcKTHKZSt4Eld<l8=16\:H9ZAk^6q
6kF>*Y cXm4HcaXXtQE&kmV>GHMF>ZA:6\+5RWALF>8b1/6tc$#IhjlmQ5nZF*J#Aq8hZ:PR:8+@>?=>qK&X8hw
8L?EmT LIayy?IKB!PiYwM5mbnJ%>>c?EwiL4th4NaS1bclM*@+F\>JH>bi8/a@hmFl8WkjA4dhM+LhbYVd:aNj
*NlV?& >&G/XC4N?ji%MJXt4eCDh&4T=Zi:J9RcNPJWRkC@Xm1dY$Ta^HH4QFcdy&6nDnN6kHWd\*BJ9l+1J?=^
4qa>XR 1nn^a+TjSH@mih5VH?SyXD1hTHYHKeFhL4j4mZN6%GX9aSt?mSnZW5DXMmbiYFyGHLL*@NWXXn!X5q\h
&VT&KW 5nP$HlnDc?jE&mBP/JXdhq:c6AJ?jmHNMunc6Dlj4G^<dtGqMBy?HpWuR?Vj1#t%#^SLu1H+JYdnmGAS
@AZ5\% W\jB>4wAFnKHhCiBt4C8:ci@e4m8Q6nRqH=GN%<8!<AhHylXk%WD6&PX@wA5H4GVPCW5K>9EdVj4tL+M
nh#=*B aAEw$Y=%8%SDDnEmX<%DJqba5V*JaIjjTSSnb:E?nkwpc@FYyS$btm%8eE^ba*yq*48?494hQ@:nC1=:
AlBR1p !P$mt8%dANA$+1Zu5EqPnKYLj@AWCqZWStMqYEcYt:A/G#cCbW9&$6wAmnaMN1##86D8tD511JNcqyXN
1Kj\BE u4/%nD%S/&/ZZ1l4^11Li8SL1EKqNNB9\Eue:dPi^BVd/mAIIJ$&&8*D@i19TGHd>&G1Mp1k*AK5=clH
?He@i: G@5QVY<!%Zm@5qXlVk5E6&5GLC!e/4cM:lXk+X<VN#1H\VwKLEj9$LjdG#=aWY^wAcGnH?ucb*DlnC!*
yKt8Ej iKdmi1DZeutFD*QGu6K4X@6wa16$8y=HPe8lJE9bla#5GE1ulG96NTZ>#c$NK=Qw8#BjSN1^Y58+phQ4
HNWJH^ D%t%btp^mH<LLHp=6!auB1\iBw+AjwqbtBSDb&6E8HdE\+T/ABk:yCLD?h<:SkC=6p?etFP!jN\tG#5F
!:4>Sp dq:k9d^WE>=ujH>Xdbk5u4TTTKdIad%Y1YMKM^J<N8p%&K$aM*<AaA@cVhGebG8V8ZMqkd9SmG5yS^C$
WB/pnY +/kW%nZqwjKmunWbaYVBh6t+?Wi%!Myqw>iT$G9*SShKeh@!HmWlSIuGK:H+>u$eb=DyDqy5Li:bwbD5
hGb>T! BcdETQ6/F1&5Paq<6h:JF>1+W:4$n1Y:5:bqYV1^?6Byju#4ibqc$Ykbp#aXS9\TbtH4Wl@*YHNmu%PZ
DRX\LL NCi?\$ZdkMKdTEAS?TX41lB#^%WT5A%P1BNeYjpqmtXuImNM$FclQBG>H6d1BP6l9e:$YWZcNCAYZSn?
?W@i5= +X1HPHFVXTetYVJ*P816p^+EE^Ke1M?!aE?amM+M5T8pDe8ZMY/!t5VMN*Bjl:WkkdynJBADPIFX\*Z#
=tA@m6 FXlD1Hht%w=>Md6BS84J+*/PF^e!uFn$aY/!K:NEXN+K9R:Slwydp5%C#@NdmTeJTe=6TRHYG>YnGNcw
ZFLCYS jNB$J^\B<?HRwAk!c+k\n11@<CdC/8F$J:t$D%+L^RJZdt!n/qMb:ji$KLyBjFkRNaXaqCb&Ft<iNk+J
YQMSA# LdyFDplh<wGEmDtHBFdPIe9Y6mLLPa1hIYjHpFLea@%+!HdQPHI\YpmDVS6/B:<Z&6aIni=B4+V4Q$bE
Butqme Y5dRi=P9*B9tYPp%Xy^W\N+Gk4YTLDXly%a#wWd5eCSG:NYXD8WT?c1>#6tw=R:K*GW*NBed4:T8t1@E
Ki<N<J p&:CnHnL!LRE5=CdQ:Qk=GSw@8Fb<KhPi6CA8<hhWbS/DGmdiZPjH9WceQ>u?=ZZqj!ce&JC6!B%l%wW
M?5Hml ZSEwSe4?XdRuII^\Ze&+c\e#:>le=jR6yq<C8*uRMNuc$hBZS>*FSLdeDWm&Cdi<bJQGWyqpeAc:qJH/
L#m>bm NnSkt+b4#H#Fy%$wQSZ=CtCBK?nXuIqLMSX9QauNNnWh#b$w*!^j:5CK4ZMS:FiX5Se&ZIVyhZS6RYdE
&&<CL\ Ib$N1<+WJ+VwN<>DHuYaN/=Pc%%i$IinLC<t&^HKulG8I&ucFY<makBC5Hm+@@4ZjSBlE6p=5HVcVK>e
C%%dt+ Qq6uP5$14m?qHIaq<mWq8WT&m\e4mWIJ#\MGqGE?dKn6!9>96qFp%%cTya?N4nu:GS+w/VKmFwKWcwGG
4cmLB5 8&#C5X6=yNp$yA?Z%^qL+FwwdbaK=chC4q#EZ!1#V+Jw6uW16CEN9p#ALn%#a1+mhl/:uW!Kmi4E\IwN
HiQCjq i*q%aR=EF1%M8$Ej%6/h#L9F+&>5iB=*pq1>/BHM==+RP:hFNyMFSteBedw+ia?#9PCdaE<EtDHCAJ^\
nQeDww B<&amdl#\DWh>Qh+Lcyk9m5^\Zc=/^MJ&F?bZq>H#kt&a*GBZ@@cPG!HtP+lmhMcM?bt^:Wq@8iB*5Dm
A\JJH5 /dSHSLQh*6WIDLquB1$Mb#W*Q^5dQe9N/+wC%S5^%%XeNV=SLknCychE5AV1LqN5Z%%+bmZK8d6%bG<<
8LhXB! M$d4MWXl5WuA\>HaaL&&&V>14/wYjH==+h*PL^uY+bBQ8<\=@TA?^N9X%QTdPDQEaL*Xbp9Y$nFE=wd\
5JZXDi D+e?N5LSllM&hhkq\TJY!SRQi1\h::@i@?6?Jh6Q:wIBm#H$uB>N\yn4Q9+K&TykX6YbKA4^Z!8XDyh?
C#?<<L ebPLFVEcQhG6e>CtXhA\m/jhJYT=k1e6Dmmt^#EtQT159VE#ae=>b%wXnJ9q<qQSkTXWHNH4W%KdtF/Q
E!*D%w Y$K9ylE4\d1CElP56=?aBRiA&4DmiL4T$I:aM=hG1^+FpPEEX?J6<uHVQ4hmGV1E&iZDu+lYkVYKXZEQ
Pd!>AA bFFQN+6::QIBwkF#Y+m#!/wVT%nt^N\:<wDa<K?eN^w#+n88mPaB>B*W<=DcuKp8dE!bmJn>mb9wYhK=
%6hbB+ mwAN+Ad4lq>yHuV1MGaXYG:i%SEFTlQe6WPZSF4=8eA=/uaN&P/I@b!E*@?b/SXyHaS#weS=P+V%Pyj1
:mJI/J ::YPZ#Ad@N5<$wnNQ/CXZZNZZ%\QHe<<1ZPmj8J4l9Z1$qm^MtMq*ZPhMG/6hwinpHI=</SAhZP^E<T6
Y$QyXF =y8X@Pu=QAdYP@/BD&5abG#cJP/cRy+9kCyQWEJCIuNmJ6pGAe5MNwHm>EYe^HVLSZnk+pT\?@8Y4yc/
EwVuu* Qk^#XtK^6X+ZmYpEdleShKR#BZL6mnA%GW61F6p>mnt@ealW&<:IjXDk69$Sm%w&eSA\G/H!HeB!J@J8
J=#&pi E*K%DCJXMEGtC8^Vp4FE4JC\^:81tmm\\w4NG#8Q6FLXuKT<kJP\lRPKh&Iw8lQL&E5qYcJVpdF+^pcP
hYaR/> TNh44WYK^c9TaTBRRycVy?NeQcpR%eySd+dNRyZ>E1Fn=$l#?Dn8&lY?C>$JhA46lRtaH4c4bP8RSy!8
pSu6q5 Et\b$X6&Q4ddB>Z>@X@b&EHt&1?5C&55F8XqVR!kHBLqZVq=h9t1V*1mBLQP*Dk<=DR@kX*iBpq:#XpK
F/pdG> ZC$LX65qm:dHuk8Gp%D9>1:X=8&I>98$#FScIHw6QC%^yl&lDa!:VK=:\NYL8=RH!=t:NW9!d@NRGi6i
8jn\5< J\</8P6haL&?94VG>ij^PBGt%&5i/lSmPVbGZJ5AB/&JM&6uPwA/18i?mR1Cd#pEaQ=E>p8aR1eBATlQ
w<+hq! 8%%&Mcu#EQki5@ZVa$deI$/<@%hYmjN4pakqV6^5w?kDVtbTjc9:V1!bKp=1$?=ZTLMhky?!p56WK#!b
RW8%ad P>Z$SJk1W/:ZCN\tN!t\%:4wX>AF#a5Rbe6G@E8TpAJ?eE$L=+ylHVXKbcFSWCt!/\4Ml#h=&C@S/#1B
XPDi*Y &micQYc*9^tIl816T%n#?Yn:mVnEQqNQylQ56Zc19#CTQjelZbC9nC1emFenc\w=m%yS*dy$=e#L&e$H
1dH>^< #5HlpwcwWn?&h1#h+BS<YHwkVcci\MhCwm5#DknENyP5TF1u+Y/:5p@pTHV*&G$hXwpb@G+Du!dwj@%X
j!1Za4 @SL:1cat<lZIXm5<9A#IZKQVBTRtq$New+hVG@e>6YEQ$TT%6JW9tc:eFqJGmnHC5#&lWyG*/w=Ae!1$
e#\ya^ j+QB&!ct*C!XSbI!8SK\&nCWETbpATuE1=p=/mDYhNPqSqb8tT#?Nk>T%t96PDhHy*cL/>&5&C8qX%Yj
a6<59= #w%\GXmb%tZAct85RIRBXTqNA6%?8QFTF9hnL/M&TH\5pm>l?jF5=pmy$*ED6k+HeWR%lqPmdbwVpR6J
jIWQX$ YE+h@YImXqWueV!mXPA\JWP*161\/E/$EnmlpbDh4*AQL9a$kEkqIHjhk\MCe\mXbn8NimtjS*P9VT/%
$@?T*b p%^dq4S6q5>D<N18iIQb1Bp1E^n^Y>w5k:9Nk6D4W\ALYMF?mZJB4$@yAh^NnC!4\+Fi=<cJ4jtQBe68
CtD:@4 LPuy^9N\jGn*D^E:yhmL!#D/B\?8Xd+!5DIi*pP9K/YjW6<\=bSLV4\E4B>e^wy?J@JjPAmJXhiHLVLm
D^/HAK KWTI\:b:/ubTQD5TpEW>L>#EVI/dA1uR/%&ywR+1SPM=8TJ%k1%aGJdaMce:NaiTS*4NkELbaWIFF8!*
SBm?<5 cHS1ii:G6+a8WLXt=:DSPVBHqHBn8I*lXBT1bZnSa^HNdyAhNbJpm?=%w<V$TdAYC9pTF=6I=Rp#a1bZ
A8p=/4 RXcy\HMT6aDc+=&*Hk!Ntp<wI>bAIijjmFK55CLRituRKmNYYLYd5yiD86bp&ZIAXTBX5kZX*qk%5GkC
H1VT:h waYNhbydY$QPyydW5ZDXVJN^V<mVm\CFG^<:J&cwD@iJHMpi#e9Rd$*<F*8ZQ>I??C6:p5W4pcut^Dp^
<auVc1 MHyI?DbH4PSILpTd1!P9WSBBmDbLJhQI$H6=5%bCHeBl5>%EXMDMI@pIdW/%<9t8bWhBc<a/cVDZJZ1F
lL^Td: C5!%uFyRyJQZ%+>:LSc9*D9n=6dCaSdRCapVT4Bt#$c%ZqN9cKEE1<MI46R@aamKc@km#Cka/VtQP#*G
XdA%ju PlQu6$4t=R**ITNS8<1Kd!&ty@/JKjiZMD@FSA9EbhZ6^mm1It^RB!M&4j#q!>&ci@@ZCk*NmtJkj**>
F>SpQG //?9SSHiN$5Ykucj+j&%$tATw/$u\SeTqJ%Gp#lqu65@Th?&NYteihAE5Ih$%#qwH1y?#HuG*JFmCA@n
u\qyuJ mL*HSKjh4qR!EcQ8pIV6dkQQR1H<>Cu\XCwN\JcJZI?JZI>j8A@&N8nDb5Liip4KZCV6/1!hmZe1$WSi
@hyCTJ =D1NPCMtWy/R4*a6>M1wTyl8Ek<mEZ1>DaZcN=+JQ?YY!I#8l/uY:>?cL*5itpmm@:B%mFVZ8hyTp?QY
-A!bRS 00044586e2d00110334 Page 55 of binaries2.zip
p/j=G1 !HD6CCj85#?SAi=#aPjZjXS&=IPlR<mYBQmic5*:?+KktVpbP/Gp8IQuBZCYCw\WE19NB4j&895m$>5k
w^t6p5 69E\Z>t9pW=M!JLJ$#l5A6yt&%k!S1AB\158^@A+IewhX5!qmS&ZlC/jFqbkNeI64G5\l<Y4tQ^#c*X\
P&Y+p! c@F%yqmLe+e+\C!c<i!B5dHc5DabBwPeqFLXk/mJ^y\1IX+Dutw\Y&*#/bWMpuIyJYhVpdP#WL&QXSB+
k>8M+^ Mj&Z<+i%F+Pti*uIm+#aVmBaMGIqYH*PGm?^YjMtelmYChd<XMT4j@*4@1<1Yu?%mA/ZAQ!X@SP9K*ZV
ycpi9? a58qP=uF^?&CVMWG4LZ>Ywt4AA=l!^I@Swq*ubNSqYKSKhNDDqRHD*HuX9A%Ky4cJac#AHLNB#=5ABjK
ha?ZeK i!BaWy8WBQ+tKSJLDhWFu>M<\K4PY$qZ8Jq=@%SJ=FX#^$e=kX/9lGK9GNdLMK=LI^i\VGTtTPTWtF4R
cPPl*Q KE1W%yD?l\<mbPhSQFcHB6/k@#A!eDYTI&E8!!qyDeGJi#>\+p:EmTFAK>qtVK>4iRP&1<dP@q<qI=GD
Z<k=m! hXK^W@qXS$EkS:EBF*/96QdFwkljyGtdEP5tN:SGSLb?AD5YmNaQ=cdywaM&9B#6EaR4LB8*hEG\eFaC
XlNHIt %$C9ktjiCjcy#PW&4+ThKXiedn$M/+KZIj:dcwMuC*l1yykT:En5YBA5q\Fe<I%I%^HuNk$=1ah#JY=Y
1R/VP% ?m&#l8T%DFG>mwlcFCibW>GWAhYK##>4D%@%N!t$$9?*T<B&XQ$XYQtlGLdH#GeJNQatGwGBbk9M8KHT
/6!B#< \l\m:Qh@>STuDEV:X&dFXTbdd1hJ/p$BQYWMYKh?wHy\WKtXDlC9I\E4\E1Kei&R1FhJFqK$A$5X:Fl>
1lyeL\ HHXXt$tXKwp$hi:L\PdS6?c8<I$i6+:*htHBH86y?y6tEI8bI!LY59>94dFFcQCpNbR#/Z<\5cRaLi\\
:tSjAt =aqbMRn*?mIMa6PTXWtHDpE/b/ntkqb/nR6\&caXk&eiFa9^J#GQA#q\upimDtKS+@&Y1$+>8YFY*A$W
c!!R?P T/D6M:BcMMt/W!pRiJ8^j@&4^q>V<j%#Xc#$@*qhRb=mhSQ1$b41Tcw6Qe=9X9a^hdaCBjm\jWCT>SDl
=HiP@* YwuGI>umWKK#+p+icd4MFj5k&<T&&i&Ij&$LG!+aG<=@w\jjqCQu9=ZXLdF*Pw6%VFiHZTPPMa*Dw#Mj
yNPEIS LMy#AK\/!Kyq#QN$!SM^4!:X%aREW\t?CmGFCVdPltejy6/N!95kVI%/Q$!nbl91?yVD!5+qThQm/lL6
*IBj8A Wqkua#l/P$HAM1#kc+J^6*h\<C5mAGp?lGGSt6l%ET6SiGHFDC/#+XS+5D!Y=p/X9&\?96P&<W!6?W$i
TKWei: Vw1G%N5MZbNklWeS1XGTYmHIe1^H^P^%F=kK4QT&EQ\4BXuKnanwMcN/B+C@FeyISmSwh&jth:&^qQ?=
W<t8Bk &c>LC?4\Q?c*eh4V:MaHm>4J=Gm\#q$dKc^Aq8qXu<J^MjI<j!AuGcdi>b#h\uH>WTm?6aaZdMtG6el6
8#RydB 5ipPe=G+\pW<aFc4JMlPWeHiD1aNA>998q<^mNlW6B\WPDhcZYq4yCViX1&+Kmp^XRBe4dC>\<&h>1ZN
FYYd:Q u4R>VVdybG>8eli/ct&@5q@HuC%BCyHa#kFRQcnY$e?1Y1>^Bq\#lQnaGTEmF*!/4mGkSpp6tt>C4&lj
GV+jI? I\AD*:6CT=\Ti/&d!It#1k?L*mRNMbi*<:npiS+/q6n$Te5wXujm%dW/m/ZC\&bm/wA>SVc!ZtZTcVTa
kdwTB# KdVSD1YDS4EiC?B\9Bk<e?+@DDjm#PQ>I\MY@w@n*iG1EZ9MJB5DT^Sd*W@RmwD+::l@nLjai>R@RRaS
mhQE6e !%k!h%JNJ//K9\K*?>JTVkCP8^Ync?S?yit^>maMHW%nSKad+CYYVIS=&JFID!S4X#PuAP!BjLlJeN/J
T#5+5A mtS>\:+BZe#PBhaTyD68>V@MI9i\BNdu!$C^S4KC<K*%bJ#:QD89$>S<ak$BYQZp%ZYae5yy\=I=:Ku?
8Y^=jK W&6pF>Sl4<lEL&cJ?E#nNljtmIym5kAY<=wuP144@>@Z>dT&pT>dj=m:eMAD:+QaIEHi6:kBCTTR\adJ
Te#9NJ =1$V<IANEuTDDLpDh=6qDN*RDh$Q1$p9=!6w+eCk>j6XuXNX9%b!Z^!Qa+<V&T:X@%Qu/QtpZ!M&YD#h
?!LZb9 Fh9hN9K4%W:&d1qGT^F&6mu&qhbVi>4iG!V^&D>aFiQEYbGJttDF9n^qN/5KMRp<YdWiN4wN\HbH\DKc
6A6\=% Y^hmW\9HMwlcY<8nHa/ky6d/CW@/*p!<M+Ze9?t6+1<\<J5aimaA$>>VNi#<Rh4wDJQ?hZRiphNwFl<+
=JYCRt uiA1%6KjEi!$NK8+c=nYZdcm8#biDy9k6M$EP?bZWN#wyX*Zu&Xb58Q$W<PKHwehA89aZ=FCtDyykP:8
dc8^VW <nYPaMQ*1J$5NG?q+9*$#<h!:!Z#H5a9hnbcS49#wMQED$DD!C&IZLAn9!4uhBDcLpZqRZ?9W??!1^$?
i1^+5B ej8$W<km@XZIa=dJ#w>QAyZlbFE?djeIdLJRZ1YQ#tDC=K%@k?tQlyY<<diWVSKG$?>5qy+BJ5b\YD8a
BF&XHt aZ:N&ThC+4pNkHbn>?M9aXbC@LFQB>dD=WhekMLMTu>XW:Sa%ZS6q&jbnwSY4:F1V!Et%eN\YF:wKEeH
RdIl$: S!b/K=J1+mIjV\kb&DRTJ<MKiPIS<!m%:L=$q!$XS/NLkM<cm\pm%y4ykYTubGQ:A@!LDMSm*qXXytJI
Z4EQkm Kq$&yLJnZ/qBq?946bl&4Yn!%hN85+&X\PNcn\hIXH$4FtSLA:PKq@+Dpy#J6Iy+@%*C5KQCtD<Sl4$p
h8a8?% S1F14n5l:4LcCR^AnZPh\ZR9Cw\^MJ8&QnZQe4nLAhPN:&i+hKMKEPN:l%GndBmk??=N:TG&51mjXCeW
Ld>hZI dbj/1%4Y:6ZR&m4i*&cDMN#ih:Lmqi1Mu^a:49DW5QyCn+X6u/RlT9X\m5HT9!=bH!?NwYBKRA$H*yS/
F!=ZRG l1Ey5<B/VkbPV!6tX#Y5Yk<1cMc#I<W\9Hp6jI8!RVnCNhY1?M<d6XcVZZ?ZA+:>@be<WaHFTW%+<ytV
!9HtSl tjPEn8IW#e/RGdc*p^&wYeC\1cq=\a&X^tV+1+1I%:#V:pKbPCS5i%iMJw1KKmZAcQR=wXZuQ19%5J+I
11^Hd^ &:$#Xk8+L+Z*h@*H/RKApdn$WI#N#n<j6>EPleh!B!A49yTJQ#@<wRmuV!!Z!E9<&jLyE1Jc/4C4#cbX
H!F4aL pLD5ckL8>LS=%KP6bND=a4=W</a@J%69%%aaT=P:^M*q+?4y>qJXZ>:?q61ZdLyt*:@Vj>:9hh!$>#B<
V8V:Zc mI&eRj/JI1cnDtR?#qb&Ie48b@N>\E:6p4%/ea\ET&E8/Wm4ENktctJCSA$pN=$cH>TQ9Qy6R9D!6Wj6
TSHyqH l1>j>Pqc&hT%46LalL?m*P4p6Qp5Ey<X^b<pi/=RVSWqHXh%4:Wp%1u!qlAKRdNJakWkByWVPC6wYhLN
5hmZJQ F%nl1d>8c\^:&bn1YELP:=L^%8V<Xb=B+taiJVnQq$J:K>u+M5ceq<hLcCK@9Sqy<yYR4Eu:?m>*%+Du
TFa=eH Dw/aPHH+d*NaM/9##*8KnW8bQBV4ephNY/9#Xqm>B9?n?86AAhd^aIyVuTpB1V$%FDe<MXC#66+IHYJK
GSAaVi Mck?ZhMTheyE##G$?L#Y*5<&umm>e1JlGbuFa%PPZSY^FNBQ$GaZu4$X:MLtejY\@QRbXVE#:IPH+IiI
?<?/#? ^16NWYPN1Z8<=K>mYd1nF<T#>Z!^l5@1/TY/Gl$my^\5l>NTEn@P*#IEXp=4nq@@BV*a@V*ynaiD?c8M
Swl4PD uDn+n^SL!&aVKP6%yuy&V85e6SQNK6MI#yuEYaMX9i5yFGVq5GMhCZmWMI#69ja<Hepwk8uIY^:Xy>QL
*hV+SW EPmZa=DwQEu+K+h@*SYVLqaJWw6<YmmN#MNDDKeML=MH+/$WaI?QC<Ey/5ByTXC^Cua5F^^P4Di4w6XV
ALZ9FP F=/uCiGX\tPRa=>8YR?9p$N14J&9Fudp5=Z=W@4@!c4L&Z!qlnYXJwA/n8iGui&^w>8:QISj4PNK^tH@
nXkVTb utCJFheq/bmF+6=pb#6!h9mhMW<&%Yq4I^/w/K</ARwN&=PQ@d%8+ybI11AiZ5lI*%umNZJB6D$/H&dq
XaLm#^ ^KBBJm6V4<E*?\^RDJ5h<>l!/$Mq:t%pN%eY=54Q^DMKqeH8D4eDt?%&JYd<lL%P:1&mI4ycqWX\ydZC
qj<^CH DKE=Xyi1DMVC:\6*Zc/T6<:Xh&Z/>JRehc6YX&549W\1t>?\^!WVlquY#HwF@wGWZS&EaBMHJZJ\p\IK
cJ<qCQ \%du=Kb%6FNt&dncRVY15Bk:i9=tcdY1RXln81l?y&:<?4H>I+tqa8QA\wWY8VjK!Nb>Fk/d/8GcI<Nj
9Du>tK tLW*mbQ@9Y@!DeB?d/H+dKCwwCm#4NyW@*!9H^DLdk9XDqmJmPEut!a?$Km*ShE?V<uT/K?qLqX*QNaT
+WiCua %+T@48j4/?Tee*XkMLXJMc^tFS+T!dA**PhmiH%pMHa^tBuC<N&>thWPmPGMJ&6l^+\j^n/a!d$enKik
S8ye8* :?QK4niRy?Xaa^!%X=5N++:PbW:G$TBw&TE/=R4/%9=q^kTn5ty/6?!4+CZRFDe+c6badQNl=tRbk9\:
=^q$GJ M&^aN696:GTk?LDe*G8B6I9:D^lXYEnpTE<$T1GtqX#VSCqt/<%tW?+Sb#Ilb1YE^y&n/9$W6qShw+ih
J^A<Gj 4Y>TYp%X<YJ>5\J@\bPi8!i##1:uTuG\tF>ipBXPXW9jVL:W\9F:PYcYJ5ey=uHHMb=DVVq!Gp\GBQmJ
#9$NbW PD*P8qlt8>caG8MGwM1e6cpMmW<Zw5\Jba\%9+K@1CGi^dYP?KMmE&nLSP8na+uDHGJqIeMN&^qRYd:X
%JTLld i\9F\MH5hV=S^pyAQQdVy$XS*G/Ew&%:1:i!Tykyw8$cpne:bWnX5#8<iT<TJ\&+VL1MLTIt=+*CKX:K
dAeBm^ CnBWHV65u6R>^X>9Xnh4TcMkyyAGS>J4!1@m4$LkhuM<t481ie%%XYj6:iLKtQ$J?4M#ny#F\hHld6wM
qjE+dk jM1>#9eeFjPcWZBcn6W<t@q1k:iEMQR8Pl*?T5/6%6Su<S#y6RE%Ql^FHdhSHh6PINZD%L$tn1:FE/uG
!=h@F@ uw:8K58>\*&%m>YPy6k9=^/dj6*YVTGuHGydwwuXc#hRM?ey=Yd#*<tm#&JSQBh:1Pdm&hec:XCnAWS#
ijV<ti 4N:SFV#\iMV$j#qdKQjIWu$Ye+ku=VbaZe?VYeXqL?QP^Nc:6k!WmQ!i\1@Q$A=kjn$EyQRWJVH=aWc#
GhnV1M /GtM<!lZ:uC%uc+#Jub8&e%h:T$IM6RQi#@NMZwBS!JT^Xddp=dc\tbWw==VnC5YPQ!Z99/XthWc&Nwy
@emcjN aW*qZL:8n$%iFP>@!4GyKQ:$?iFlJaD:E6KF!dc*<m4H#kZM1ewt><W#unP&&NIJcB6QTu<!TkSSkkk=
pJ\XFS ^JEVkNJ:&IZp%*W!cp1mM+t<Pm!YWJ#MimNt9Ww8i$pyY14Twua/i8M#w^LHS!w9>hG?&8B@+4AA+lPt
EapX#e mD:Hl$:t5NuemTSw+M86AC9YwN#mR4*t=nYGVaD/n>m?M4qm+>aGl+bdNh+HjBpV\9TT/tFd!nZ?$FC6
=tkAY5 +Z!a1!8ScAC+meFZ+9AZdZh<%TM=>w@FF5#4yd4thp5Ld<D5>L=ktWb+c\?H%iWD&&=<Lj=>yK?uaCkY
9?HV/& nQE*hhk6YEiY1=6XKy4t%<t<c!^p\XX^5^L8IKFljKhm6G?=K8%Fb6u*%Lq1P%+&Vj6Z8/t#MP#N/=Bl
SFDp*? unLDB66ib!X^F$#Ihi6HudYXy<aCR%+J&=<PtcS\N8SkPh\$:aRw^h+H:/j<uR>jw$#mpl>e9#Ejh4K?
-AV4cW 0002e42f75f00110334 Page 56 of binaries2.zip
EZ5>:Z <VpdKGwkj9+!>XkSF6&YXHIS6!*EqP@B/uSjqR%BN1Fl=RXj*>Ce>mi?aACtl6XLG%8\cuEp>6MkjK&?
kyjF@+ K@//jNSEt^L4bZLa?TZM!G1aeDnk&JWVa$MlTjS?ubhN\#DtNEp^t\nM$=CB&jLVDyw%$&Y*+4/ynI&V
*JcLM< ZRe1H*R=jS<Z#dlTy%!B=/w?5>PbaiN>BPV8/%?a<?9DX*d$:ZLJjB4bDi*@$GMnEu@SHL54^DpF4KcE
>>&ITA D#XQFc$ILK1!LaBM=6jT+&nBL>Hk1:#KbS4^T&6eu!8CjKhkR=pTQ!KQLmZ?ynbH?PN9bPmEnpjwF?hC
KV!jXe tj4ncLeI^\69a+>YQX$ajS/?tNjD?cJ8<PY4h:CwpAi@^l1hXTST4LWw@P/MnS&RJ:ItpLBJ9>Qilp$l
kd8>EP bH5&q4C$FP:=u>?ZLC9%eBZp4=Lit%1b4YI?*BMVqZ:@/dCa$nL5:@imcmhj:4P!EQHk6PdbiC*8Y^N8
^=X+kD Z4i=bZNWS\M\RNci>R$J4!y\y8uXnhASa&h*1\/:qqFm1y!8=\6l#J\6qhqLQnKjmYAA?^y!%6C!AdC:
XGESVh kqqFMy/NH#hh*+e5EAj8j##FdNnbuabVwItNdc<QGGGdbedKjnetHwM6cW8#Hl!*:&dX8YF5hINnD56!
IHH<Da ak%#u%Yu@jC%Nu\@HLcyZhmpM\T/dc*TI*:eI^SZc6#W#Ti@yVcC*I#4lX#qN1*^j18TG9Y?Np1i*F6:
Yi?mRt +/J4@T&>6a9LjnBL1?nFm%^C!:ARaXjD5Qn5ZBt?\AY%FK:W1*hZq#?PGVju$imTn^cIN^A\8>NR<YyV
yh>pBa ^MHQ%e?MGq9a/W1Y6:Fl&P\IINPlhRcQCn<EypV8!etil*5SBTb*D4?k\#buDqwbDW/D&mn:@/piltH:
qIYyCm ^86lD@&h!=9#6GA<@jt^W4=VITjdQ^9IR4:c9dbIbwC14w\pwK\bjY1CYA*8tLP*N$c4A1AtuNeMK*<j
yEEb%h @?=LXT4Z6QL@/MB\1aMJKab9=m6R65q$WYl9j@96l&1C?$*aEcWV@@CGKJ^?6acnb*+>nAjn?^%mEuG?
B*nFBQ $ZFPpZHMFubuZc!^P@ju/VCI^Hw?QENFZL+iZ8%pGy%C&$:!ch5!5iETZZ>bPG#@?qBukdnCGynXVeeX
#d<Wkq pNPn1MDX^@5@@*#YJ=M@hbJD$yCFW&Ibd^I?Ln!XKQWSHJ1&!!FaDR:=RW!DW1FnG$6StBaSwMAFyCIu
5Kt6Ph 644X$ay+eb$T15!Kb!9h:M^V?@4d=hWQ>DkaDB<h+*^pGL=WAi9Wj+EPK\^4NL>$&mBiI^DtbN#Ey!HA
>!PFKN +1EEEQiV*Ma/&:YN$Ylc=y$8/!cNkDa\c:1JA+Hq^F&Xc+=?1D=VNYAj$j?piylpJCVSBanPbFj:Qmdl
WpI1<& GJ9^BMVbM8unXe5ctGjnyS&Q8&TXyNtG/\96W#N&juB>h?ln6bD\+Te1nteeyG8#p*K5#wtBtXnL%Gp&
XdK*Q# Z/j5KuTwC1Jawu%>>+N?TX\#:\mMPPHmQRbNJWX=?5:%bRMH+<&1+&HMR$?u4B:&/eVB&Qd!dT\&+nH+
$qSQAn #w^L^uM6&RcdT6kl/&6u?jYM&6N+INMQykHkRy&#dquDNG&1l\*+$qkSZq9b%HIc:bARFwWDPm5V>hPP
lRRKAE F=^JbXYRqXC=Y9VADh6^dchTA9a?tn@L<?pE1tImZ&&<&wKXXQ:>dR%h1c$eacuH!uS+jb%M8bk6AY8T
aJS?Ym 1mp%PV?!K+RaS*n4imZVE1EiI?lAqyiHR%\iV5B4a*b?NhlIktJu\&q/AJD=1#%6KWW:1X9bpSnG<DDl
>MG/k* kWF?DjZ9dL:19D&k&bTqiRtHda%%Y@nY6LCy:Q1XT?CG+y#&JB+ePwBK+cDHiyPJENk:IMk4=*GmMjG6
QL+j<# SJIXFl=P#um#\M&WT:*b=K***44y+:K@+nSSumFm&E1HE$<4:GGqFyb^w4T6tq>q*QVd6jR+9uiXp*id
qMHqlJ N6HMG%E\&N!X&nb#:6:qqFh8LD!4@XBuDMlV+E?=&M8=awLK%89m4k&4tpKB:t5y\EFR*QhMtlTal$\<
/:Bt5G JyJ#yhhhIt!6/w#J8pXKmhwiy*1a4BZp?cpMtyFJCB^Ih#>p@84E>my\4?+1>cwwLSe%=F84$wpM^dLX
a9=Ip# Hm8M!91&L5B&HbJ4jE^Q@Kn&mWiB/?M^ME#epMJab5VZKSDLc!1lWu+X1t4yeZ!AmBM>FqH+$P^8K$4!
e5#qml 1b^Z5uF>%MB1D5NpRn!i<5md%eb<9lMtd1!uE%WYlGL^&K/%uGy/Il/9D4%q8?Bb\?W4LB9naH849q1Z
>:YWpm jM+4E1!PSbHMJWl1nP5enZuIkk=$G=\4pKI!l+PL5$l5B<iP*y!4du8y/FBlYFJT4BKCC?q#>uX6+Cp8
P8>1Lw h:QZ%6>!1JkJ#hWauBjAV8!?KS<MKa!Zc>uy*K\$^?ycb!pM=P>?ZF^ePQHF$hK4HZXhCT%ei4YBKWwJ
&&q\HC Nn4jl=>D<bC=1QH@&JthJYMn>5:Z:QbMNT!dd&V5t:SXKBd=VtVyB<$>Fnd6bHK8HJ>:6T!IY&6AN<HM
cc:E<P Y>cI\*Wt=%cl\YyR6Ic@=k$dEt\DRJSPtA1RVI1DKyhHJWRSRk5kHHc5qF6n8<NMNQC94InJ$SAXM8kp
a:I\6n YSGZcHY$LFPH*T4+i+H!cdccL:R!%9FmM8!:6?M^=9\<=9I%*jFTqp*yyXT4iynIL=lC8n&YPLT1t*l$
DPywXl VM^+h5ai<\qHuw1B4B4E<IW@kIQ6R5jlbGwMB+PbhmVX:QIE*XB!SmVw>ciQeFqXFl+bl&6/lXbXk5@I
+S%aG$ &>jBC*CdyIH668ZFLLmiK$k1mmmKTEEc!+9I!!uZkEw8yn!:6:YCk!V=4PRTANAk=y$Ra=AuEEuk6hXS
%4ypd^ *Y5kVtYWKQ//t199y9i9=>e@>LI9NuRZutjJDCiV#:8CScu66REmGStKk*F>GE+VQE\&Y9TKiAl+a1l*
aei6!c ^^WA9!q4#y55aHEXcn^kHCQcFyj>c/BITQ?F11p$c9!ItPK9KR/DQ+kH/!*\=*m@!@p%<<Ji8TqWE\lw
C9+mEa P^$@CL8YtFS+#wR<1XVBlWw51^KaB5!#h6tF!L4Rn8I%IP/M>Pc\<<W$&h*qc=hYl%e+Py6aw+6hT@?1
/AlXM% KQ@=P:6/>$$Ph/<\>Y^#K%yQt#wYKyyj?+^Se6S6PV**NPcYHceR^cCinnt^W^V++Atil&<1W#6F/+4b
!X$hJ= #/ReN1%+@W5@8/9JA=t:5yLbyl>+5pKK\:n>mihAc=WV@hZ4d+<:/aFbD59up#IW%LDK5TNtFIhN:+t<
IWt\SB ZEuP4FI46>cuVlP#69udJ5#4^&uQ+JFY5^aR16hd!CZM!1tVtuW^9@pS+BeL\\GbEK1EbNddVZdY$H4@
Y6jcHe t8%#LMGilwqb<\8AE&GJ<hp=kcLL&@kl\E>tQbm*&8:X!mdn:CjT=Sj??k\@SdVW9L4DY>FFi1qBeDB%
QcB?%T YKKK8%#$k=BbZjyKS/KXNkdC+1XTJwFP/S99u\w=d@5t\:@JJ1D?ijLj=JA/#1ICwAWGM>K:+&tEm\&A
T>/lZZ tSRTA?#@TwjG<^8hF#KXwtGXFc\6em=qJ*!**hSit6NlZ:8J9\/YaIQ@e5\*h8G6Sn%lL95>S$@aZmaV
+p1uBa BZb1kXj6ZH6!MnIMj^<MLZGtQ#&S6hXZW6$L5=FWNYIHCbQq%:<1!kdaQ1i6#@!%X+aT^$F#!1XTh#LM
^<Kjn/ $yJJ/^pl4h51<Y!lHB=CeblcVbWi4=S9XAAkdTGNXpP$X5h#*a:5%9=?+&<dZ6L4W1LR^@6Yy8>CTmhq
R9Vq=W JhDTcVEZ\bcqkCbY!*h5Xm&:HnpiNy=pZjb9m6LA>q/awmD?:6:um>l^HHLDSnN4T=/<hM1nMa9mR>>*
d+6I8G b!?GMW8QVEkXb%tYuF>:q=@?le>1@4Qe!6eWKbWS<1YR?VB=Wl8HX#X%Fc69n<NG@ckJ\PSFTtSZ1bhi
/m+jdH 6J\S#e96T<p:+*1*I\WQI*YJwF>VLV*EiX8Zi>QjLe<N!b*V18!!6FPa@\98XNi\/@ZnWlI5@BX*P<6*
twGMT? nu$ByW^\Rcuu#kVy8yGd46yuiu$?H#b&ma#RJ:B19@DZWBYLkuk<bJy&kXGMi^yd89b^E#Sa%eV^<K86
BYAbye k@1tQZ@S9TkAB%4hcJp1M1W:bZQ?<FZQki45$<EJR:AKqWky/DY/KN1l/?%aDBcVY\9hiyjIjeZPKKDL
XRSech deq>HSn=6RR/T:CiWCh%qIq1S!SG#%R15dSah9QE8ku^h*uNtmt&e+GYMPGRtYB!m9Y&^KW9newu<T6k
$/=Xq% c^RMm@6tQip+VaCJ?Yu5eIwl5VMwPti<Vmimp?$tVE!>F<M8M*mIN5eN&=?d6YGHkQ=D&pymTbT/T8dD
XKW#8X kD%/?>@cAndw=wuPmFl#+It:44!F6lut&>1yI8:G>bGT4i56E&#BMVI*C%#D65c*kiLjX?6=kmX#9qPE
qI\l&D p@NFb5V1yR8:5q15yYc!qa%cXX@b+CT#AuC%WSy^n&5PIVDZ<i>$P9:Qd#w5MXqyuPXZTI+hnC#iwE19
NKk#@4 teMie1NmlSSpjSucH:*i#=WV=$$k=u&yT?$yh!Rp&/b/GMSRhh:9?y&p6c>n9w?TjR+^/CDVB^@YN*IX
M:>\lY kn&JL*kK%YAJBpi\?G#tKPa5dhj@/wXQXZG6=/y5TN>jEPwplpY%6FAW<WJ1Jm6@L++/pnlmKM#B^PXK
DtX6Wm p8656>W=N4@6Dn$hcZP!/jBp/DSltV=NPEXPNp*M<uJeAeC$4>/5p/C$w#KqqY1unK9jGQRtlXPjFW>T
RBuJC* *GLEJB%Pkct=E\n8yB:?hq+*6ZVjjmIQ+RNViiSZuR@ZLciE$1cY9LI+i!%*Tnlce^?nu>@Y&it$DhV5
%1<Z?T #>QZ*uy!>PF+QDDt!d<9CQFH*e=l4*Q#:8nMd<T?ZPSB?FIBp9P6MyZd6>$VHbq6JXpKj<<n<dS5M6b@
*Akj^Z *<%Pc?L^+Ky!jtmHqMqBBSe?l$^Q\BZhD>/?Y1MVI%WH\hVei?6wFV<RN<CG<?FJknZR+BTDj54Ih<@<
\^^jFh 6TAH!*>/KZaF/W1b=&6:nQDK@<hj&%B44M^jc$aFqWLDm=dFMw>\a<cjn*q8Ze%FeK8klGQDW!R4Ek*%
&dWtk1 <=Qp/nAyt$ce:+^nbNu^NIuEp=4aqhqy#V/$Ni\+juS%/LQ<&8Z+#L^\<l<Gtb6J4!+!SEJ!>u>RT\ME
/pb>+p FAACAAkA+FX6Ji=ei*qjHRAAbn$AADWAAABndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9at%\e!>m
\qtTdX hZNydtX#e!>#cYSqatF!LtJ6eMX:V+#e&Jpjc%1PPekALp=qaBb<<G4&$u94\w6BEp^kdhC\i+EJE5ER
T6p!B4 WH9L\S:yMAhycim>EkYJdHaNQ\+:M>5tEyKwk+:cw^i%AXpkFnaRA>$HId+8EPR5u+I^jGmhW9q>n?^@
e5H<AT 5%pk/$8#1/9a4Qi>:@@9?>+n?>@>?$@@4cGQy@nh^c@C:=&Saa!MP@4/%@@G8D#G\&>@SQyqSFH@\V<+
EhuSFq ?jY9j+%Q94LXL&P::V@+l!@l:WFMH<XEe:Iyw55Dy*F@6n6e?b^pTyTt<yE/jjk@@9eLyhVV&/Kq?bJj
Ahp:X? NlQ9M$%$nb+EWaKj@umEGV+u>V9%NJXQZ/T@W&Vd>9\nY5dLI^+PAwNM$!R/8JJC$Bj/<!Gq>Gu/<Fm?
1mGE6! ?FR>j!ejQqk8a+l*u?ikiZ#Bhw+Vp<@NT:dMYV$pSd>:?q!?jj9\/XQRjHT$6PkI\<uW^BE6w<m/EJ9w
?ud6lh <D1^@F!tD>M*V?WLKS?\tT1/D?d&\M5G5#phHPEDL%N4@ViZ=Py#yh=K?jd$wcKQjtDQVRQmLmNRke/A
Lpn6EY mcG\dX:bLdppjk*Y+C6QW\X>cdt$:<NQe>M&q6HT^uk#y6mk\Y/c*8WZp!8bj9=Wjpp9wLEpC?LCVcaN
-AWP?? 0005b67346100110334 Page 57 of binaries2.zip
WWZ!BW !$JteAddKKJ9Zh46$t8c>%Nm9k?jRt&L:Q6#&+KL4QmBdS@>c=hMF!c*YG:I#>MNuKq*FaJCjT4V6!<p
k%^itw *X@c5NNj^H>BB@5SY<\CW>M!IHi5jVT<?8MLCViD4*4:yZ^l^Vkm9EeXLQW6&+/NKI=Abby58e6RQaT%
u&dKuj i*5>BYPbj9tqqLhFT?\k/\El8n=/kPH5&WPdSn^uSKI*%cYq9$n:8Q:$1WS+5I9te?Q?pY%#QI#m&ADS
5X?SZJ DQ+%D?QIIJ9n4a?QQ4CjIj6Ttd:+MyZ\$b@H5aYk8B>dCPeS#mE!6Ik+P?^hBMhFlA#Wu/8aRQ:mBh&H
tK*K\? wyARa?>d$j&aw<P&h&#c5VGH\W+:86D*C+=J?HhmmVX!RnJX9DTY>6\&4jnIN8HjR>8?c<HZCcR%Pew9
9aFi=e FWcEKNwySChE?kK$^NKCT5<CTXqF6nGtMip8IeANnRt$1$YPmtI6c6HIqH&p>dLlH+KL:Nk/Kc^/BuL:
W*nCEE d5!W6utX9%<wc&@1iS9lyku5HH?L@R9i>y?#qcdV&5c*Z8$l1q*4EBQw4MaLdN*IiH<&E:=RpWmSS&Ae
ukMTd@ M<h9Ri1+tMc%X^SYWZ8iAFX<k!$pB1%aC#Itc?ebjASFRjWSt*R/K?y//p&41RB#WRuwHDG>4c&X$pVM
c\>:TW jCFe+%<KwYRNN6XH^6^/Q+=FWb^Mb%b6YhPyJWBdCDiPPQ8PQCJ4Jtc+5lF6bAnl!Ni*Sm5ENC#1mEQD
%5@dR: K1biZH$<EWLM/tplQQlSEC#&4#^Bw>1dGjm:YEjR6qXG15CZPhT^Qb+\*&JpYV8YBZJ9Cm/+XHmGZ<D&
Sb>%8n PMXFN6TPL!Ln&<?p^Y\LeI=HLMI9SlN4=5$KT+D:NAQ%Y5TkKD\Z9%PMhA*Dl+>MJb?B:<!4ldhuiJ=X
$T&lM5 @GJpnaSqRRJ4Xp\E96l+G:>iF#ycNN@I?N//Na^u<yqEDIC<L5a#nJ^ba?Tnce%/clae:NiaAE!F=$IB
>Zku++ MmAjJHaCChwcm6Sn+*&YB@GJnEmmSFNQb!!=Z*R?c%8DHKTRiM>AIZ/h9wcywK^qkK%u%SXmE>k/mY%L
&*I%<* P$TI=H9k8+c^BN5N!u/9kMR!jT%qY4Pymw>Hw/KaRj+1HyFPK<\k^ATI5QSZ\khn>uaX5beM%J5thX+@
R8q^8? +/kH&@HET\1Y\J%dpV&LE+$i%5iJC*=m9Rbq#cTImn*DVEk>W>KB>Yw9luWL6nN$>lkN\He!Sk+K%I#E
aRVDF/ :@!X##cG5wYakY%K4%Z\VEw%4a5h/!/Eam>:J$YhMB!IKJ/SLR:huYnN6qwZ!L?hwnAMp+NWRidZ6$bd
<mFwR: !t4HEknk1eiP=6mtCZ=5K+pV/P:Gp>yjh\Z$lFFaY>*=APEDW9?N^wlCNlpC#PNQn?IqIkR@=M=e%?$a
Cd8/jP KlKLa<5\ZEwAZDtyJyZq@Iu+ENebdV\tbw5u+AlCX<R8ILeV/+S&MIS/45BwqTP!IHp<65SW5LM+wR46
@F%ZV8 !bktmY%^FbppTT*k6S*ByMdRQL\G*IJ9PWdtRE:N6Tm$+CK&CQE^5SIwQkQy4w81FBt/k*F%bXI=%Rwn
C+u8JE WGB1wqw\Hjm!%CInK?H!C/Xykp4lc6K?R$$pyW/cWqyNkNaa1/nYecWN^y:m<kNLaY/eRQ&SMctGwmRW
EddhR: Ji1bZD/b#Smy/C?JFt^tDVNi:Td^LIGjaqmM#Apql4ED>PK?^YYbW<ilMldI>buL!E*@\FCAhENciJAZ
pa^@+/ @wB@Ze6%D^NI#Qq:WaeXn%e^W5*KmDJ/pFGY5b$=*#!ZKucV:ZK*b8<b^y<Jd=iMwdk+j/MeTmhmM4GK
PEBMAT ckqnWcY1VA9NcX>kd66NpwtICW5VmLJ4/@=nX*NPp%8nyRKl\dbmcmk>F&\5IdTL&W6wGX^wP/4Z:4Xm
!F/=>b !8c1%eTd8cLtSkm&Kwu6^TYk&Hl8B4etmG$!*8NKWZF*jLEGTLl9tRnW4^P11NL4BM!RcecFZ*B5eG\b
*SYMqe !FFk<h<TcV8:!bASFbel1/1aDFJZFcJWX+HNBy:m\HKJXSCh=<cZI45>j%RAwF#j9Gp*$:#1!>c1+BGc
H<c>Lw 6kJKR+\d@VC^#BD^yGLbaK/1u+CBHKY&dqp?>Cd4DYRi?Jy$cdSCuIl/aq@<YhcWJW#5%?BXcd=J=^XA
/Wj?V# ?Gwaaq/$l^Zaild+Htmb\VytGXAcjin4I%>IJP8%#$G8KY&//p&L#R#XRq@SE<QtYW^RX1^A+CqP8jYc
Q!6m5V C%KSZLeXi\X5p*yc/cZW9IyGXyW6CZX\^Rm\>9ZT!wjG$QwGwda6l>BJRd!YSQnENj%pDnX@MXt6XnWI
iRSF+j YlALjc#bZ!=hc+h9mdbK&JWui6%ynI#*J#ZWlVHS5tD+BtWd\^J@\n%QD%jJqe1IZ5a*8Mnai&>$etI6
YRjpJ% iYFK!YT!<V9S=dBYt/#@Fn$ZSLmSTDVQWKt/p^M/mI#SiI\iPM+wRRcl+%mLqdeJaN>A!:\SA#@*k9FT
M&5pbq MCyP@!6Rj&?CIKqy?aMMPBC#$KmBjp+T%S>SL%\6<yYZM@LYZD96#=FycNyQckRZMqjaq8X*/K/CDTeM
aDbG?D h##iFX*@8TRPta&H^bA%t$&61aWXMj&A:MSG$:bih/8tW=y&\9wKJp58ItTbFMmSi91jStICW9mwmupJ
w+1HQ: P8Ht#F<F:Wd/T5^Rh##ZTVm?*Z+G\BVBYLZ9FjeMB4$V!?JPBcR$R/%bN*+i%A%wWZ?^\pnFlbtTZtlG
?#b@Z9 CY@/%\c1MNT%1tYGmp@XdDJDP1#!Wt=<:4WtZ15$P&k>=AJX^Wb+*eqje@ME>>bwFCANP1#JBDLu//:#
W8ZXut =YTG?m6R?$TkIQWAPuN+tH65>N@wSYwIjcIV$p5V!:W<9&p&Ik#E*wi\qc6T/J9$!t1?6$QL=EWHqEAj
I1jD>= QILFy^cAa+14i<aIVk4L6yGd+EN4bp#<XCqWVkhRwnV^9JwV8lGWkSNn:LG^K18mGG*JcCJw+8ilqA*1
GpXaHD ?%mMSIw?Acb!qSl!TR8>&9nFCT4:bnP65eK^tdSAG?^Pt6L9\q>cP!NDFBJ<?iZKZtA8CHP>t1mNuXZB
M9/=aq GqeYJJ<YXTW5X<mtAh?>9V%4^$i@Dh4WRipt#5j=M1MqwLlae@VC$@X$P6X^ucD4uTXc=q<c+#FcllhT
9!i5t< wl<nyCVq@%%dcw/pKXah1lIkiFZWJ*#AZEu<C@DN\:AL@?QP/E<?unV!liSGE8RKwc%kK>/9+>Dc%FNh
YEFtqK P#!aipw&GpNZAKCcW1=ajR94PN:^Am%pb1MluyF!AL\XpL!C&n/k\I8#GqEd#>Ci8YEwG6+nNaVp+$6R
XDdT\l QaPSZVSwNLeBd4aHXc&V?W<kiW\jed$HXkw8@W$4H+?=AYdc6@mFy@kZEaICNKeH>L:ua/&JhjJed<Kl
e+:!pL K*I44PQkTD<W9?R6&K:WjKWCIRWJ6Ww:KYPXIjpeyQMH!^<km&wG9KSG8wt\%98*6d\+$MEG*JuhGm*H
<nqdu# ^9!B*qR$aDMay>K:n1BMbt\4c4YX*^iN9DyTSa=G>?XTY?mkb+#8EYXBbCB&acwp/jR&6il/1lhMKhPe
qheDX> A\^wQJ@ZimQ+ReVE6AS^^c&CB?<mZb<aPnQ1WF=\jnFENReHA>/e&#1>Y+Zc#iJWcJ!=E4lcY?DnBiXd
XAe6yZ :ckkScFCbGRQitQyGZB8&/k5489FKEAP$\JS8m/ZVZmq4>JtH4cka$Ih@an:8+^*4lM1BcM*!ySqGNM<
\>c&kI w+&<^nmXD8?@bjQ1RhdQWJHNC5D$5BWP+H@EMjY?9?u1NyTZjCZY5GuQtDmJi/AH*=>WDGa+QCCdNuK^
YA@YlL cXEStXSd?@>w1S66K>cZmj?Tw^5!#HY*:/LWp:/b<L*YS*WA/GqLu\<1B^e6JA\GjVGD#VLaXCiLJKpE
&&cyX4 PyB^%LY4Xd8yN%ita1Gq81!pe*V5SQ?FK5$Z?bWkPISKkmV9<n^eqRJ<R<%=aH^:6I4>Ye>:P%j/HbtR
PnyyE* 5c%+GiapYE\*G>VldqXih^IPe6WF*?WDDtVWXBC:!L/MG*+$5Zuu4<4NtnVj:w4/NeNhqYt$#DVPX*!i
$yAN&> bIlGpSRmy<#%Pn>HHi:a#1AMYiRZ@Ec/EwM^m:6pew6?\qtdXIudI5NF+6iL6q^9c9D6Qj\4Ju:J^CqL
*&lPE# BqHumH<N>PnLiGYW4HKB!6EKy$NEbwH$\Vd5lpR<=^wBR&i/QFReWhX!Yeha#Zy%ELT8R+:n8u+Z4AJ$
L^JQGQ Tt\4Q1:\R&MYY+wD8$<m@icKla?XPe1N&/*CXdDyFm#^aK6#:Tnm6TmQZ/IQbJQlk#6hN@EVy/QYeXi!
C6VwE: SbhXmqZcMM5BQq:&nLZC\?1t1kc?Yh8KAKAp@ET5ENAd8hcYGu!p+?P=IuXSmbh/RRqK:me#Q$@1aJFR
^ibCN% *wX?l@NF$*N5NH8&FX5cc:6iYj$Dm&Wb?bZ9L!VwHX>58n#Mc:a#=!?E%qu<>6bw8aw:F\54JpZqyS#I
QT&Z%n nJ:dRcF&5X=aLVcdDVZcWn$AlNye1YV1QC&JbNbdtBiEa6Q/bT8#QGt:Lq#qPjKwJ&tcMKR?n>L$Li>X
RPJ!QT 8FRt6SaZL\i5@Y!6Typ4Q%q%1##dLICVai@eRAF^hGlI>XdJSDtbpn1$?L%$8<SQ@cBVPYV9MmkMBBn+
!NNKF^ =tui6\@w<LmPA?Wh*6E1hWi9*B\l+ciq>BjJJ5SCJ%t68qhc%WcFah4Dl:/:Ieuu*WyNVLLM5$CJ4G%K
8haAp4 l=ASamNZ1:J6hV%1yGyd%ZaDZ*Ri*Qkk@4yFy4IFbRH$q*=GLecYYDHWdi8DL=6Jkpii!:/8eZ5H^1un
Rhkty1 =DlXFX1>AFLqBGl#&9ybtIT4LwiVAm%u*mX6E#DplbCbG^:\DXVc!mBR1yYP+%S6B%?lWm+YG$c=NSKJ
q!/PdH TTE=C1?VDqkHh41/=MwS1bNuT5k5\IS6&?ST6P5YcIMtikZ9Nu=KMHmKF4MN6d=JkQu^SbwnAuNFNZk4
PY!B!y iFKyJyC416q5/tAD@qL=cRMp!SXGNt##Y/NFkAW/qbEnCJMeuTjc*1DVjTMFIjBGNK9%PpR<P=Y1Jc<C
yY+G1? Py$PAI$L8#&VKW#AMbQ&?JA9SPPBYK/ad?h5R9kmk#!PVBuuKWjZMYBRB?IkyBBBy?EqJduKN%%VN!ZZ
9aD@Q? w*DX4pMSyq#@Rc=lMuZcAY@b=^yF<Z4=W8dI+Mb^XqkQq1mD/&dXADM*K8#BEn&D!tVcZSGDi>nL<XIy
Y6+qwN SNR1d:wTu9Xq8W4>y8=CSGcumbH%cbljaj%R4@1b<nwAKBdTb?ARdh86AtCt=6qwthMW6k4aSw#&=#**
M<Dmq< pGYYTuVBb6MAZXhB\%Eh\t:lKk\\9tE:==R/<wiZLe!=DAe$c8Cy5qtFC>qq#Ywlm\W5J6yXYDd<Hi^e
#p4lcE \6QkG<wLWk*=L*5NSLlwQQAN5*aqt4deeDW5@bI=Rh>kpYbcA\$F=$^%nw?6lpTBMlbt5G&ay>%1FbR6
S\C%ad +kR?%CHR$EIlM:Syt\6?9hwN#\l5De88LJ$m1NeB\kRwFC+e45JleG8$AKCWK%4IwBKGX\XTS*9VPJ6P
e*wMjd IyKhnZSYZMEBaK6R?9A\$DXa!Jd>hT$??DVWiRbu4lT/lW&+R5eCE>jI5Rbb1iA/?MlBGnc/D\tHcuXS
pVN$N* QNwPGh851QElhbe9ID?$CIIX&1!RaGjkG&V8&ca/y@t*C@PAETD<u!W/nTBelHKXlFuaBR%RF^bAykMu
NE\lF% $*IBuNT%ywhQtacKtkZ?JLDheC/5X5lqTL+R\RI+KlDZkGjF\I15DELFGaS8QAA<=^R$LXckEEGFApD4
@#Y4$G ?DWp>6c!>IPFV>Djd%BEFP4LIp\X5q+%PeS9&+Z1T5eyT%ttQteGNF5kLaI\E*:y?RpRQwhnqnI6W>SB
Y&uZ%: XIw8>XE\&PNBAP+=ekTqH></IcwRadcm/aLAn>F1LmAYeiHK>W+c1mRqKGl61#5/4I!\V5GW1AW\DhjE
-ATYDN 00005f6809c00110334 Page 58 of binaries2.zip
ZVK1Vq 6tZp>N\Jq8eb4IF1E1nL4XI*RaME*E$Et8:E5&L8GCXKke^FJy^mXa5&$c8aX6eZ:kJhe<J*t6^hh:jY
$^H?GB /$AnTX#Z6mJ*%$+?J6*6<9c=c:tX8&NTJQ\<8D*cRGXp$B/b8^d^\^\mmh!:l#TL?VEPM$/T!D4p&=Rm
1SQM&Q w45a>th@!tN&amAJ=j?b8/8^chn^^=N^bI/NQa\$4eQDR>5\auMW8YV^$lI#&*hN5q??^D4QhwYn:i!T
a?m9Kl j844R+6MuID=i&Qd+GedVGQM:I%D&wpT?6Di6ehG>NZ&HadF48NVlwwXG>G8cbwjS+cJ%b?>G:<Z$e+P
uBq^1u ^kuD&DXHNN4lP!1tca>NGu?%*YJX8^P*mMkk/*iQnblGbQBVPTMV!$A*54F1N5&SajJDXYMIBw$\%:i*
G/VmpP &<m+G!e?MFay#LTNS45G<chlnhL6qk#L&Y:QQ@+RdN=lYu$J*$iYMh=89:cM*d5IpYDBJN6#a*SZj=4>
qlN6GG FGT?^Ihq*Q$KZ>uGh!Cw4VqG$Sc#\TiIY@mZS&$jS?b&1*ltFwM5q!>8Ve%ZZ#MmVj8iDRa$MlMS!DKB
?Ft45\ #BJ!GJCL6cL9d:j!CaEV=w^*\BhYlkJpc64+P!!Q@ciFepYRb8m>Iaj=He*y>\Kn+=nX^T8&<be%64>@
Puqi=T !Zip^h16plXRNNP&&u+ha\K<E9wl@qLmqcbNEqdwD\YG$EldAJyB#wT<y4\%&pA=Z&ujtLdYq/!WS^M8
d\%5lR +8TJy&q=QpR!Y@n:?4ydlPk\kdDMJ$IkM?t:nA&*jTe^Gm@qM8&:CYc!a5$Z6wQ:AkBu!H9S<IthnkA9
F589TF 1LyapFGD:?nX?VuLZQ$K=T*<L11%TPDJh?m5%WS8@+A?D:*aRty>l:6SL6XaNTiB%XaP%wbikuQEjLJX
d>W=:N bH?Z4YG:P$A#5P\cYVyJH%ek=4Wp:#1XXWEJykm\e1?<4Qa<%qhA#$\pyw&5ekH$wXC!4Jn+Ch@M+8ea
Tn/X<& c1CKT<K8REaV&>N*e6uPN85ACJnbL5:>AAW5R&GS=+1jZPIdbd5medMEjN$Ja*nC>*ByAw?J^J=FRG^A
\1caCc DHAyRiYl5wGpXn\!^#H6/8iZhtJ*R4VHi%A$ApAIAWFpWMi^PdFy#$ZR$==\X1mJC?XYuN&tcWWW&dbq
$DJE$M &/+:5?JwF8E>NuEq5jiT?GMd8BEd>unZAL:a64PkMyCW/EhVkXTS#R@ttSQVNE!LEi?>MYcnGV@IScQ+
m5n\Ra :1=J=#K!DT5?VFC=!kaGySH9eBGV<M8&VBHBuMC/ESCI:NEwn5qkVGQ5mMcGc!bPiX8$5m*LlP<IMBWR
dCTklW PVc5KLIbKQ>p4B@WNYC4cL\:&wGXDGMM&5iGIR^daA%bN5+4#mN?+wAl:h\\SyJDqHHEaF!LpSIG9&<j
umBN&d &+bP%HjG#tGFYl<8%A>%<4Hq?<?IQ/I^+^a?VX#>&tc\\uetDYN6ke/uLJ6Z?8?9VWc:hC5N?!9>=*h/
be=EBM :LZHLPbaB@*Z$WA:ml%@WahB$QM>N+CNDM?t@X%/8j$>+#tLHAEVFDM@j:q>b+Q&uGQdVW15FMwTW$d+
ZM>q<G NR&hnN5+amw%Tu5y^>D$/#H$iIK$b>watANph:kuX=Bb+!eN6C!#JMbXhwkN9p>MCQ/P\SeYCF=8yclc
+>hY@X Zk$6R1bq9+H9PjLdSpK@p%/mb@y>HQNu*Cj=P%j&wEbPmj=#ERR9i:=E*>ZZ*i1X@6AtQLe%@*/G4cwG
@bY6!^ &qZAK\=$t%>yHda^$W5>J:Gt:@kTT/n=w@6mG1^bNY&u\Jd**<4iS?hAt\XcEpqXXTt1Nw\X9HPZMZym
c5cQqj Qd=SyRJG+hB4Q?l:T:Saw+ZclF6X%EC8M15ZiW1XLIHYY%EqYRaZ@KHM5%1mlX>$KSSF>^=1jVeLVZ6P
lS?*X6 nqnI@p=uq1XC5Vl/b\y<Xcb!/T$Y$8G<c$Q&LH4$9\h#WIaaJYtB\dZiT+LkZ=&@9N^$4LJFDTl9T!!K
jtKD9h 5emyR<$Z&aBP9tI+%u6t%&+1a^&c/B8JE:/J#j6cYPFn%XH/TCK>55NST4:*pind&j\e4&*!@cQ?cVhh
Q@TqK+ c&^WA4/n=N4/E?>P&aVh1:RyY/1T@4qet@54i+SiL4JHAE<dCAqeSS%BQ=taP#H\hkd/GYCTX#Fa?JQL
mb1pnp MG4\\/%AGB9E?lunGPjncK!j$hW#</N*i&lV4eQadbEL4%aLbj##DyM%euLES8Mc@?\nQw^J:/>G^l>B
aANDX/ VC:9ED^tKi=ES?a?eP%i6H@uHqea6J**I8MA:c/=d*J9DBB?L:yDS9<@Eq!Rdw&&cZD&=9^!q$H9K\<L
!S:IF! +XPyu56VSe?j!:P#N?45:I\?yVM/pCA=%Q66l9GBH9qdDE=Qn$tt/4q/e*#<ZCp/^5?dN=@VV?qk@>HB
!1Ri8G \eE?:S@>=8mM&FnAYDn*^@%>bNu9Sb$?jc/PKXX$D>Mj@QmM/Ghub<hHhGj@*mhH?#<>&D@aB#>#A4/6
B14wAL acTp:j+G\y=K?jAWp4=S>\b9HJ!>wcNHn@9#V@a@PV4d%:T:YLHm/5Piq1BuC8Lu+C99Zd4!kD/n5%@4
#tX^^R $@&nN$iQjuS\AJFM&=hTZiML!lVGkd:Z\8DPG@4bMX*\Qj4pk=@8E#<KtjK>dPN$+N8#VW>Qu>/IeF1i
ukeFiG jjb++E8jHB*>/Al<S&klti@DC:/u&n>kjVNMQ/PjDj4?>NPD@h<e@adk:h%e/@5jL9ti\n95$y9B?/Nn
44XM*$ P6MuS&h9n5:kKydbV1V<8&9//q%YmQL+J8$hP48Rij@wCA=tY:tPD5qB=p?q*6e>ViYRykeZKZd\/PnT
9D4\^% #tj\$l6D!*^d6M&VT**:ab\L@ipuKb**^PdbNR95H^*A#6yHj*jy*<Gd<9V^kE1KD9y4H\^&H8a<$4EB
<G$AaA 9u>%p!>tTu9cD++9ZZZu?IdqtT<kZMwuq@wP^:?RjjB???*#T&B<hIN&@$$9M<jGVd=*B4+H@!VjP:KZ
t@V*DY tZQ\6#hwnS@*BnyYX:SuQ:<^+5%XDq++=Td6\bWJ#aPdpeb&n9Q4PZk=e4C#?1hpN4VMyHN\pQpC=V<a
>nB\aJ :Q#mmyb?Q9l9wL*Z/*56><@jZih:J@&6jN4jQ%SuF?adSpJt!t:k%dpelL$\y$!%&w@WaC6/NEkacbq9
mKipl/ m@bcdND=aPALq?*#p*:AP5B%@<$u^%h&by^<etuujdQ@=68@@WbXBdRQQnI9:d^D@/?aNH+p9+E=l9yG
^+wLHE ZNGR?>D*1=8$1j\G%6$=9wqkJ864b=491d\b/jJtnMJe^#ht8\Q@:yCna?MtZ@NW94\y6FK@8=t@pqii
Z@$6$R jX&+1T>D%9pN:W/@\bh$VQd%/EaP9ut8d$hj%!/q$?6<D</$n>J@qIN*ln4??K1b?q<QV?uu%:84##B?
m::/86 l$y6=^>jehpj:5F6l^k#>w?jp#yP@?w1qa>%$+C!n\+e!$6/!ejF*a^4^>pyub:SGX1Ha*+@?$#nM:QK
ea/bjR =P*SN9<wAQ@@&qF>5#?Wj\\6lj*VCZ6@BN8!j+mp?TMak?=Z\?$QI^1nQ#jGEi<l<BaL+uZM8\4>@@F!
/KPJQJ Q&umY*:bPLjq<HSCM$m8Q!BKja/%q/!X=I?T>@u=j!\W@<&9qJ>c$jh^#tX@J:1j+bW?Z?B>wX@DI$@/
Y*GuD9 lukK85ZXueDl4qw#QC6W<q&SBh<=Ane5DjHD1#?$A9!Mq=J<RYGF^VSliB/i/&e=LmTZt8Qj!!8tjM4Q
6^&DZw Y/w$9ZyYVVaZjC@8?@Ay4@J1#djY184*XLNNMX?yXTu:?=Kl@L>RT\MEFAACAAkA+FX6JTaEN^KnMRAA
tlp1&? Fu+AADaAAABndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9at%\e!>mhZNydtX#e!>#cYSqatF!iC=m
V?H@ST dZDNjW%9&&m/ybT+w+<CLAWa!+94*ntXwESyWKStWKIZI<?1b+AyT^ewWk8SZyn!wuFuW$/A5SRMSAXw
WS+?eQ !a6JL*8<KGhnbXFTF6j=FZ%lwFPL/Y#uu*nPib/ZqPVaKh#F4R!yD+1YiJ:#jL<9Kjp@@:jK@<#I<l<*
aC>4!j MyquiQ+j8G>pM=q5Jm@:@?>yb4qp#X$YB@hn*M>^9<d>Sue=iHC\*<F?B@8hG**dMjaja?Ma?+?^@@lG
P9nCJb Q*1P@ijaj++Z=>l@j1PH8<d?c?!@^9=4:Lm?EanMDjdjaQ<N>6>k@<&N\5y/nQ5=:6i+*/kwiHAkn\N=
@cG@FW HMnnRB+SD@I+pMiBQA:peTCQmA^=HMnnRB+H<nmRS&lAHkj!PJDHkV\P=CE%B@I+pMiBQA:peTCQ$BXy
hMcFQc 8J:njw*:ncwA<l^DkGPAHiQA^#mI1AX@QMdGMiR=ln#HpEhWBZtPIe<^=DtGQMiRS>RHia+l##HpPaa<
mm5I1/ ^=CHKn&GQMiR=^n!HEPia<kncldNWB18%:nj1Pwl##upPae<==DuHQKIPTDQPiR=l^DuAD#H\eXE?NA=
W=8TNN *uCPF?iR=^#!mNpk##upPae<==DuHQLRqPiR=^#!uEPie<l#DuuE9GKqa=HpY6adNVup8aa<%=DuG9Je
BXqtkG R^=^A<l#DZt8Ie<%=LtGQPIcpPec<q^Dut5Iek%ReSee:Bwj9Mcd44HnG9LRlc+l##Zp8aa<%=DuG9KI
8eE*V$ Y+uH$E4WDKY=WXiDQDiR=\d!*ECiG<kn:kh=dmDQDiT=kV\*pEheE9LeRJ+d!HMDiY+kn:ky=LtBQDiR
*@^RQ8 =\d!*ECaG:w$RG=\\B6<?Ab99PHP@<?ZV5j46Q$&H#*Q\=Qua+Q*hQGVY@4c>*1i*<Pi\P9=QV\Gu8@*
LAm6St l4%kEI^Gw!CPi@GwN+1=^9HqcDc/uI%tq#@@@QQ5=>uqjDV:W@!uL+Z4C!bReee&NmEFu666HL&>l8i6
4#Vdd9 !hL#ikEBi?d8>Zwi\L\SwWiD*tmIX%#m$TY\=+C@JPdQMS:ued66RL%c8!&\DpDq&G%#>=JZ!>&!CJbQ
X5JByH \4kHRY<RkHLeG@S/QaDHQWJ!tSEacCAM6qku5#@NSM<hG*jSe^6ekW\>h&+n**=BXM>VNRe>\RjjaIV6
NIm=5% IhBHZm#IXDj+R6i#Ji!j\Be+NHG:a%upK%wYDKmbG%bKq?y94+MVnn49EZkE*6A$:D91ma%yaGFM#n>j
@VwtLQ C1^Ch+T4%/+BuhDknmQZmIRNK$G%DY!1<BX\iqkAY@hwcBwakk!I*+9X94HC#8aG>p?#!cZ!4iFS?SJW
cZ>k\# PXpG1i*bNy@+aKpiQuE#E1b@ReWB6&M^5b<mn!a$MjR<8b#Dy$Fa?RyS1$%<1?Nb96Y&<I4RIG&*SR4b
XMw:@L lp:+1FyaC#W^M\\LA%QuWDt$DYZHatQRnZ<i\c5J?@N<MmNN4p1=*ddp^kBTQjMP9ulw!&4dk8^>T4wu
MA8w^A *6&Lci5ljhwne8Jcq%D&DA+FbQKhh\ByhiRGnkq6V?A6cle4pBLa6lC&SR&M<SVj>#YpXNtED\kL8\55
PSi\<J M5YMDwdRBi#Q<#t^kN$^jG66SbdD6=eebRX:!:ITYALc/<HX$*kcDppe@6W#iqdZt5SWNlR>^:$nT4dW
*D418# 5tymK5CmjY%5Ju\X#4K^H$1*SQG*jW\5:I?<lK@18ci+p>E5nytyqu!BJYmYbXDF^JRG^\ea@N\TWEyC
Y1CbuV cCMF:P:bc?BCGLyqA86=eT<\eVTS?%^kqjKZ^P%a6dcaYWSR9diNnpYnhkJ4WVanlTh&q=T!wtu^LJ1Z
F/?RnR 1NC$%Cb^LA*nCdIHF<WXYI9d%u<Xukqjamlj8bPnyeSlep8m/%d&kyHlX=Kq/hG>ukEG+eqE?ebmZ!nb
@a19WP cNwTRHya&/wJeaDXLNE6WZ$mm!#E6mS%t>DYtDKMi#&y!<EA!CnHLE/k/^R<d+=\tyD8#&Jjk\&5&6jE
Bjb@%B ?h4IaKt!qcP5ZP!E9:Z1&C5tDyKMGcmi\jcH\6cDjKqW1aD%JbGJqXA&lD9mayI1LRMFHF6y!n&^h=6:
-AR+Zb 0000f4b00b500110334 Page 59 of binaries2.zip
4iG4Gy SiY4PSP/Dbkt6TR!tKwQK1XGbdNTede1FY?T^JFqaCHDW&=dZ<QVcydwAR@Gt=T^dTjI+qky:LI?>nS*
Fh^%j+ BewZi1+Y!<@KqjJYw%\G:GR!n?eV&6hT\l*NnZn/Y9*K<LciFkyFZa9FktXW4RbPaK$ph=q?kH4&S@T4
Wy&Zni jD/jKhRLlayVKXe1qh=pQ6wELQRM9y&P$K:X91bjj\&uF4aCYm#Wu#$4%4DY<jpGwB6F^#LGy8X66jJ/
C:m/9: wRlRlpp+t<%tC5X<JX?ydFWeb^JZM\LP8pDK\6nTwKKc&#XSMXCK6R$?Jw#4>XK^ZCmZBbuy$:lYY\NK
wIjR+p RVYMTdiK\ZJ>K%@bE56/n#I=pG=P=lQaWTpD>P89>WuTNimCKqbm!Wch4M9qR4%WL^ecyX41=^JqY1FT
8Rjm># y=cKcBekacqRItmq&WP:V64jIbRt^iL9/9Zc$\TcjL?ti%pYtC4QYpKY4&w%$5Zl!1Y!9XT#%1!qu1&i
%D1>ni =^RKyZ!&$Tk>KAF&b=TB#wHKTIJ9jjWX9GYnZu!&bC$cLyh4bjAq=YKN6u%aK^S1>BCA%4A/RC/X&wc!
b!N9l+ ?6XB1W^RiW?yqM>V8qKqAVDdi=RF&W4FATn5P@qT8QnV+@JnaBjl6DZN$qauY$D5mJ/l=BymId>b&m#l
&t4k>y q1@XC6A$6X#Ca&P4uAcTXSYS9F&<y%\9FVIbC8e+DF4+X#c#A&**J4%eqyw8F4<1qutk4<4ESmmBd1dk
=AIM*k qEy\ZJLN=+D/AQjC\#\564WFq1DiIHS=1+!EkJSRe14XMue%mmSbLyb+TBENWi9$5yuM=5+P<dPbK8$L
1GhwaK *I*m:\\+u#d16Y\&#$<I%*#&kYDtwiM<+LmWCA/qR+hq8t1yW4b+%DLwFjFBjM!B\&M6N$4kP+KKM=Yh
H9\#D? !p/%t56p9EqMZNn*1&Ih+Q??KCKY5>qeHm=dKNVLRKYKRXN8IPwIeK%EdNC8kW!=Yc+$cLph+R5%+TAF
#cGW!/ CqA!Qk<X=!w:Y#9jeia4Qywa9mBKdIRy<!BlG&WHt/Xm:wH%SA&i6$BV8bae&aAlTL6YKBG#5k*edYmc
><:>mu YHX\lGtLaF58XbE=Mu^QE@nb/8Sww5nF+tPCK9lZZ?iAT?8AT+F=T&E6!=G$YCwu&Nl\CkKN^F6^K?:i
/Sji+$ *w=dIWFH:F58CYHQR=:M5k^>B>cwW=NkwwT@EqDBLkIVdA9+cKpBj/:ZkX!VLI1KZ:Me4&dbA56:BW?F
#:DZu$ ptM:>4dRlRE4i/VI<CI/Nn*aM=PHA%SE&SPm^uID*?JZhaJC^q\8?\BcLnEleRhWL$Wba^qm&#YymJBB
uN?X=G VX%Cn1ai&8DLba?8XXdCTlbkiA$ha!Q:LZ1AI?F:bPKI&Fm@#8WAT+e5N%n#CF$9ANq^LAQLuF#nc1F=
1BI#y9 RHIpZh6^!HbHGDe$5IF6kT\eGawyd*ImqY&t1ntaGL/KdiWjADbj4p5MtRZISTqW9tP^?9tPQDNFAhNl
lWinP^ Z5dDh5X%*S%*8%ZbFtjCEYBb5wYK!#u1GL$HiwCnICFe4^8Ey@peR^Y&LdQKFqZSDC:pMe89iaADWL6N
kV>6=* aCH6PIC&TNmntu>Q%1/wGtT#n&Bc/LlWimR/=pRE:W5LA@bwQB::>RdAJT?BdkqBD#VJ&\uuaw$?ShPC
1F?Aw\ 4!*8:ZkAJF5Q!Bae&mWw@c6SRw4PW5X$Myt6SmuG?A^/QwwV\q<P%^?Q+&+*b=I\:WQ4NlyG#/L1el%P
lSlMTa =jn$I9kWhb#wtd+FE&^9d%h&jq>^mY*qGD+Fwqa+c%@qYF^k<VDS>inq!*Aa99V>9C:\^^T94nqdwS8%
G6Mh#F tt>*uE=NaH&Ly9W<kiZNc:WAmpA8acme#Y/YC^Z+%!b49e%bANNLB$i>?EmmmZ^j?tMW8kimbwmbP9NZ
Rwmi1i >cKBqwyX<^$/q%Z#cpAXQR6lu!<aS:>*<eK4Mt>5XRwY\#i4W#:cdKH%CiKnRJCHbD6P/BdI%*m+FMc/
a4d%:P 1yukAHb<&ybWGe&\NeCyjD^D#^^b5JPue$MZXbcl1lt/eJAt<+eBpeFZ>D\E*j\DqDqp%cLny:GF/mnw
I*XNmY \l14BK\9:pW<5T?*bN5DQLa<l@Mlu5iwla=>M*>JC@jE8!cm/yC\IYBSa&Fi6I4?MQC:ncJJbKquWhXF
nBeC+Z %qNmp4DniWLZF>ciX:N=5:X@6\^bQ^p#eaX>pV&wb@INZucS>Vbba\65E+bhAA>>u*BjwWw>V9nKA>*L
XLwmTY 4\teSJHnj$i?IM^HV<ndhyX?ZCtuM*4T^5ecT#$^MQ#1bb^H*!S<$SnZANwF4D>&E4cQH^ejq*XSK^MW
!ttY=R pLS9+BmuB1b+GJ+#tS#LpFP&Pe@ntiqmGc<SZb#4Jd&1AL4T^1ATiiRc9B\P@iFL9!+%W9kcbG#V9Z!C
nq=Q/b a&q//61?eKiTuTy1iEcVS5WRX5+>D?=F%<J6Aq/?X>k5mbwLV4EGYK/Ry+9nh6YlAT=>y$I:BAXukjYM
5&!*$W W\55H5k%p$PY*^K/elQppW<hm=:l%NR#c6wt?4aTi>e!!BIZ!%D8eDHp#LLBjJ\AP*+kehVW<BWjw!5@
6j1w1a RwdM=:jRe=Z6hM4Y#Hy\?yCiSYReP4VaRpkDlh/XwEECK/R:pCdq?@m^F9hA*mS8JLy&JInEnVNqcVd5
AIGBy? bK4iuBZwCX>QCQi?GC:!%dCRNKkainYI6%R$QL9nM/dK/6KQ#h$lJuV4&+G6^1cScX4$cGlAT8YXaVnu
qwdn%p H9Se\CDwTatIk!/PZNnTH1*A<bCBHay%8$4c>^5Nk@wa>\48NLHnBJI%9KdEqI&&I5eSDhw4^1+9aeT#
c%AJMa L+HGE8h=a6KGS\?H\XBc^FyJ?Nb<j&CWdGmDeRja>aR4We9dRKa9EXIa?*+%q$QYK:HqA%@Z>ydbTp?+
Pl=>kW BKMS%T&^%CPh\lb:<ZLy/XMMVV!mDXbk8+c!5<KZk/KG$&^/kTD*HBDd*JT^E@6H8wAulpnPN<t=Jn*H
%\nQXT JAwQ1E??G*18QZ!IAeMR:$uDmBG5V:S!R&&:Ljh6>t:RelMt^m$I64C\wc1ky!w*T?qEjCBV+4/bI@b=
C>9dlw ^kYpCRD:PmWM5\1eVQCGH1ENZ?He:R15H@9K6!^<$hE$twD6$dqk:C&YaI/X!l\uX5A*pPMa^m\M\dIY
ZYn#YQ <@D5@a8FW9ub5+L!JZLCN&ZM@PSnBActFTA@41C*cSBYP8Ni#>:bcTFdXM4w+l*+XW<VqTuA/qhi:Iq4
a/kVyp >im*R#c<Dwau$DQ+D4\B=B5tV1Z*YyHQV66T9tWqnJESA^pLe>jPDkinL9<A^k:h&Je=NM@VdVuq$^Np
FQ@$yb B9?\9CXnE?kblCukkG4&qVN8%D>b&^%8C>@6^nd=EytwQbaIEN=^PSCHuVE+JXR9MVGN:LMH<Eh/IpL$
*yQmti DH8Wm4XK5jm\YG<D%cNuDaRw&9+HmC>8A>Y8%Ywa$Di&E<Ld^IZNHQLcER5DE5=X15n=LB/ly/XRV1\J
IWIS5V JKCFpAQeBkiP=cjFk1YENiR=%umAkYFN:N9G$S$HA*BlLMNi&NJ6R6X+j:P*Xhqy5lBl@I58&yaiR@Re
yY?AtH KG\91akTW$QjK&/XShGq+5N/acC\uq?Xu95B=?6A%tqVECCnR!mZ*eiX^4abBRJaZM8*@/H!D&YHZp4C
!yGbEq 4y:u/Kq6A=tu=c+BPR?@FC:#^4CEu1SBQhe*Cl8iALjdGEWm^&iLG/nK5G&HkeSR56ERqS/4w9e+MuFy
#ZKY\T a<pJP%5:uG9l1J!SJP:pGV?TE/i!J^mIZ+E\#IY*e%:pYcF?RNmBaPJYj%l@8LHlhj!&$^E*AV^c5hIi
&DbEp> <PnQGJu<*6%8B4J5XdbetZHl1LjTW#>QaSF\ZtJ4VW9qE9!@WZVh<pd^wiYha1Ti\?AjR:WHD?HnCX>j
THYj5$ clCeGwVLhGWbmP%X*Na&w!tItTyLnyRGcJy?dwIwMN\DA#8WPQLd=a4P9%X1G@WmaK6T$VBWi\C&mJ$P
N/deF& Dh^JElkJF^1eZhl&h&Dj%uaL8JQ+!Cb8aa6#IJZGq1SE*\@W4/Yj>JjI+qq\FE/*+R+D@#D+Ib5l1qX+
#$6%4V <HCD8cTa$PZC5VcBT>6:i^JJ4V&*6SiG/Nc<4hKYVQN5\1@Ku8bQkkc1bwFEElb=TBkBJ&%dyX^<X4B?
Hb:=%h 1GaiEdiWj%y<8kHwA9qK*8m\^\mejG$#Z&1Inu@9:kP&%Y1F/CKAY<1#m!kli\VcQ@4T*bD^p1@S<:Bh
9I6d!/ ywHSXFRcG<XuwJ9qb\5FaG:WNna&LJ?P%XcHBtQ!*T^^#L966kS+d/<XVtLke6a=:&\mY@y5YAZdq%1p
&k%qQJ CdYumWV%:JhV\kmqA@VAkq6/?9Db\+&HleJV9?dZnHX6iqi?bJZ!hGtB*a>e%&%F+Ym4>P<KF8Vh*MSI
pW<XZ1 qPMlRbc4LQ#AuCM&/a1\dTFM91miG@WNV5DpTtn=Rdj\4Lm^WY#:+q45w>JRRp?#Dbjcc%HQadn98lEM
EDc@CG 8%ukGG<VhVmB:RqQDX%SPCIa>u*lJaSb9!w8aHJ5?qphu&/A:>NcdiMyeK&$DtM<XNm5dY=8ItY$*H=4
KJcPki L>4j*&?%?mFu1Dt&*M^Z6m1^A5jJMEFmtRpLhKZQiiEQQaSTA@HLdkEEieXRmS=8:Q8\cNG9JH+==kZl
Cw18aZ pw\j/Xa6N\4yX*$*&mTwVJMn!PJ+ElPdpR%AZ*ku5R#6MaCSP&ll*lBL#@KbS+?p@Tdjl$@y%lLA6pbV
TKm@YE AI@Pq?#N#bIDFS>G@hblGQbdpb9jFLJa!Hem1E66m=XqbX*+W4lDD<nDNm$Mb$AwXiwdG/kJtV!Dc?Nb
J^K^BF +hpGa*kD4mW?ld1DaZY&BkjchE1\d\RXS@%?hEleamLZdjIM^t^CcIYXl&Awtw=VQV>Hi?FwHBH5YjHB
IBl<?< I=:@+MVXB9uC!E?L>C8L<<qaH!J<ai6Ny:u9AnVT^bJyIYVaHQn/e:Z9^DBYbHT\\q4GA+I<FL=5pQdK
J/dnw9 G^6!jMn\8L+B9wWN%weN!%!w?1BieQIPqF1!uTcJknAi?+KaFd/N!t^P\19I1tjia\d\e:u=dW>n1THJ
cQE?*a A&Qup46Nc^e*HmJ:FMpbLRB!YLFiKAbPdXNGJHa#BFHSe#<mLFa5MP><ERNbuVwF=9\wS&e?w$l8HuIH
KtbClK Ikj?D=cXb+$GbZDb6hdb:#%qC6tk4R9%l+WAKqa>&$/\%HPY%bP\8ZKqPb<VYZAuT&CmBn1IHZdkYd!\
qe+&5A V8!LCmM?9XGy@IiKiFyqk%=hkIYjFl<ml^Sq%Fqm*kBhJ!B5u*!6nMDmq6?1#Bd#BbBu/q\KddA^VPG+
D4G>KM 8&%5@N##HnjpuA^cbGBBDFiGYMmj5DL=d6S%:69@nq^qRd1ulYqjbNiM6Ct=W1XJ&AW9IbmMX>\/WHVn
&6KVp1 YC@<#1DDMaLHpRCT9WTRSR>9WP%!\1DAe\#M#=!$\51&A4pL^/B=>@inKKP?u8Qy%um8\A91YqRhH\Yy
y:bd<p 4wNa8KI\pDi91T5@qyMWSQ^h&&9LtVb$ABk1%D1E%P+P/4YbN#D!Sy+H&SB=R!C#n%lDK/ZF%ADV1/j^
?Y8AT! ^PVMbCXjd>kl=dd@+wYHQM%A&uH$and5>D8iFu&y@VK@+ASM%QR4y$t?Rd@XS*:PeLId/!PIQRHplQbh
1SkhZq eGM&te!A#jMc/*!XMu4P===nJSikCLAu%%WTqSYaiNT#+#jF99Bt^tQaD@8pm^5uXyyNb#wq:JRGJ8Y*
>mAImI l1<l1*!SJYFikZ@8i<@S^V+*q%Z^+qFmhmR=T+6F*ED<Tkln^A@C#Z:LebR8d4q!iVybeF$wZ#KiV8Ky
yai:5X blDnYX<MF&N5PiaL:<WL**8lmM@%PlAA$:#G9nX64^VbKhuNJ9R5hdZ9b5TnpEbS^>B+LF+9yk5NJI%n
D$TCt+ &uk!meiVyb=SE<T^AIuia>DBcAGD$aFcq#ih*6B1JFPEVh>y1q>y8t&&>4MCt=N#XeCh\5BCit:ei4KI
-A@?Cb 000e5024fc800110334 Page 60 of binaries2.zip
t^Z+6^ 5R>YQqIL/#RG&WCnHdk&&q5RHdVd/qTC1GVXuSW&aMcC@<nkI*DC11qV&W!l:P#6ShQJFLCkdBTNhTw=
6Lj%Kk e<I#PYyjV=L$C&%wjTcR=#wbwq48GLwKT+yEV9umCE$HDdjE$KNM98Tk6>\u+iuXhQHQKi^<MwewMdIZ
/KCG<* \!umLM%RWnSwhRk<dA?leF<EMLe$pu#Dq:kE@w=NihA<pBkme1HebA>QSd<YZTh/Xq9HBnpPpnGQYJn%
Cmkjkp ECcYdCG?4LG4n8Wpe#yNDBkCy$t@e1T$:NKQTbe6!n:TLB/IPwG1F%D&Eqm<Yp=epi>AW#V!qhS@*nXQ
PZtut5 hXTEXM?TN\JX5@CX!S^N!jVuItHSS:6:4cqwG6mVyc+ZDC+t#jHSPEkb9#AQCntW<E4+TkA:TSk%W@5C
\juTQG %nh^m*5SDj!P8:i#l=8BFX$9=qiA@5CaAuAM=KNa:c8EZ$kLkCRm?B^tG/1hNEN#dy@iHDmqJ9\=CJ+a
GJuePM N<=pC8mqK/RL?&KEPDWYZwl#+T+=bMwX!K#CuD$#M=Cc6aSwJ$XN+qe1peqZVT&?B>V9N>q91lc\hCW/
R=kX#= +Q9V/S?J9EAGYT!8BFS<DEbuSbdiWtjqZuR/R?NjL+\9yeb%nF>S5XA!*M4bamQNFh9PXk6n@u*kpjE?
YN\PG5 PI6nGYXjVijKYHAFiW1HHC=uZ%@+K:yNA*jF4jARGL>1NuXcA:lNh&?QD1YM<i#8V$ZSRJiM1a!yc&E<
?6=6K9 nd<e4uR:B91Ftuma#Dt9lK@9GE&LN<Pht/4ukDJ5Ahiah+>/4nCA@=l+>NZ$cp:9844/t!y/wa+XG>nl
<VYLnV $DmY=1+$Rjy1aDPlI<CpT%\IDStcD5A1:q=q#>*bc%XT9u>W$k!qK@Y4lZG61iG4nAHdaX@4L@t81F9h
Md?aX+ YhXM6/KYR/Qu!9/?1!5ap:5:uj+=<c#Z#NS#Rm@?D^XP9nJm$^!6=%Ca8ADhYWJ&PtpXXH>GILuNy69W
4D:@IR 46RladGyKFu#qjDXJQ%cp5h4kj%uNVFnYAjGj8JiuRS/cYH1>l<F&hG<AXkZ5E&qG\K&6G4jQZBHwmSp
?ku9uM NI&WMbQY>Py1Mj@:uAE%NaMZQ#d&qeRqmItT%dteV5P$Gp^YVeL1FF$aNMYjY\wynIZ:hH1tZmXPDYVt
S$\MTD D!SMGlyqcndV5VHVl+tt^Jjp#EJH#!?wW#YMQ#hhA+#$HnTdnccJI@IW?=I9>j\/+W9Zkn<VGw#l*1mJ
udTl!^ w8tleDdRcd41hE*?dKRqpLubFX#$/8V4kt/D6h=NGDPPZhB>LY=qVA^X\<^ZbM#ta$dC5SJP#&X$=XuP
5Hm&Vn w\C=a*JIX?5SuR14G#aNZ$himwbJN>X#w8tE<Y9/%bXWCPLPb^PncicB=ipdE9%Hw*KI$GXBwKcybW/V
Lwacb$ pT@wlp$T%6k^K@WeuRuktYL?WRm4uuYN+@p5V8a@an>+GSm&l9D1!cP8>HNlM%E#?B/Faq<*nTPnb%e^
Q>Ey$+ w>hSqGy:1wPIBFeI!\DCX^MQq+kyepK+G&kR6h^YGI:HkjJ6tq!^>K6><mZ!tYG5h?q5ShNjDue!E$*4
Qbj6u& TB#kXHT\y8e8H%#5DFF=A%j6G:lH+@E$EH>&X@W5jlYiyjH:S/aQw?jJXIe9X+!miC=#AZVPPQSnZndm
&cic@q D+NAPCaGX6III@Y1J8eG\?qW?NKh>&@=%V=R#!TWVP/Apa>mDBqRtKV9mbZ\QJqIbGZ4^tDth\W=>JQH
F%5=Kh JuaE4mN1SlRF^A$n<PX4<iEplLGEGn>u$i9Zb\b%jDTbCPE=?RLKAKPdbqnE+bAKjTtPHRnl4mJnPPIw
VGi*#N m98jRylZ+<mqicY*YiWdKh%pCcIkPw1mcCI8#ZAm^$p<u<<Y<TThT+T&A+LDnjmw&/E<cIcEieQ\TQmG
S&WLQ\ GpS:i<8ElY$DKW<SRKNJFEh1+PuC<FZGMDIAwwCMa+AwFJDl\wwj59+$/WXN\EWl@CFS<@=KZYD<G4wK
1*tR>u G$hBbAlQJIaV9kFGD\BGA1X#^cFkW+hhZd6h?w>W?bD<tmHyeq^JZVN*IS?9=I%wBbc!HaXHiInGS$jC
MEEYJc YDy1HZ:Du>>m^Ab<a9JGEAuQBDAap&MpeSSR9\J/FLcE491XYR<QE/=<u*AhE%6R5eCj4=R9G8p=ha%Y
\<>S#E Qy\E+TSWH#QaAYpcGYC5y9=lGw@HphI>bB^yIB&/dHEEXSCQpEqJGK5yESQy61S$\<SVVuVNbbAa^cLQ
G5jWJ8 aByI*yjd&EDnk^Flw:H!DX6TAjiFd$Ka5NR8Q^kJZaw\+Yeuy8tbc$YIMFKccuM:=tn6CEwFFD\CV&In
ECFWRF mACJ&dhM^L@\6mt+SG:wTwQn8u%p1RR*WnH^FEWmL1G^cIpA+cu&KwSqNGtVChmIMSjVm8JMBI*A$I\<
KRPNZV kuEenbW96h#cm%L:Eq4?RE^^D9uwEY\uiyaDLQ:Z+59lIuIC1na&e\IT*J^!^D8l+&keWb>n4FN1my*D
lE$TM# BCE86wCcVS8J?DXcQ8R&J!\FX4&C?6bQ1$<9JI=Clm$eiYK159:6cB1CN$k!L+tpS6wyA^&E!VcmZjhD
8=ewk> IDNjHaw::&qQG?$S&yn=TFYXH8E%%Y^kw?p$cRjE:dAnPkK<?wP$\1wq6GaIwmQ/DJ!=6Rh@QkV8wRa9
NpVw*L cnBX*&J:&Yj8EtmFZEw89Sql+!lG9bmcIR#uIaT%1Chcw<5iiByVi\HW*MjB?*68GEwpmZtq^+MP>5Q>
CPayq% XlV6R+#IiEb!pNimb?bG\QL+E>aLHVB1d6HEutK!C?djEjmMVaplIab/hNk/%MS^iInw&tM&cWEQ4j*D
%hYhXV F68QcQW+\B&!EAn8bBJNJJ%\GAQp1:Sw4!=ZA58cn!1MlwcGFL/JP??=86XTH#9ed?**Y\AeL@XMB^H#
X%+pIm etaH<4BYVca!YF*w<au>PttQPK/VuR8JJlSi\A4qWFS<KHTbPk?JVT8DP>TN>/X=\+SmEC6jIIP9Klhw
4n=<DL X%eLZRXjBl19hbL%cmG6@=SP=Wb:jS\d5GG+L<kpCm\Zi+T>K=btmJQ9$p9m8A8?eRla9BwjTR1hGFyZ
&NmH+R ?1C<4*TII&Lw$t#CeiTk6KP+%J=m!cPSkYiH>/kYel$u\M1Z!GLj/VkbXp!9q5kyihtV&J5u%?E#l+a9
wM=kMc RTS?IePlc&BXB5D&>/Q>cSKPlm?WDMJ$cNn*!ABDtRdWwK6lPR?YiDu!BtMIta4%cM?+<!H%#FWeQMEH
lN=8*A >L+a&DlYc6<I=ZTeYD$hTm$SDd^p1:QEM$X>i+i<jIN<R#Y^/^4@\qNj$yu?wh>u8yTQHu$yZNW#XnRQ
5/hQVK E/pbmei>%yE/Zb584QpC+Ec\/I\>#KEaiE>$T@NKLIpMkmX%/qATy94=wS+?YIpnEpb*djJ*pnFiJ=P1
u*y+R$ mXpNdF@!=%qE4#4paW$MCcR+&KEcY>An<Zy56%lmWPwm\^hDLKkb^T:J^GqPm>c#%ZmeiCW#AR+mD8*&
@HwI/m Ed>EEc<&*AZ=WJ^L*C!WtMKB&T/Bd/LwI%V=eSyJ!%IRySajc//Y%CPbQwLFDqYhi&G/mn?u*I*JZcab
n$QhDY =Buy6cdSeKl=Ewwia>#Eu8JwYdMT^#jTwLiTbna$$G\H#1K#j9mJZ=p6nTN!XXk<:YPIE+XBcq@&eXIh
tGV8i\ yLMI$=wd!9GQIkQHHm>bR?%>5J=N>jm1Zw%j^ca<l1589L+Fc^C<JF$T^uHGIb@ld6KZS$jWTZkWKTlH
i6@*E8 JhI/ai!yV\w5ew/%*#LE>B+tiKHdcL1P#D/SeaRXDtWKabkM9uqANFnwVbJtuaM\:t*1@N\TY?Rk+VHH
*/hykR LHkT/DB54AnADeiXp:a/RwiN>!Py9?JbMnD\#jqb:hI=T&SE\hmp1c?cb9X%@nuWBS6WqpA*GpCVi?l&
DD#<Yl 8//RNR8RR*ck@WC%#J:Dq\8$hFLbLD\=^yiK^!p#^<EG:u1GRW/8BK1SRAdQa=ZZcVRdkCa@k/4j#kJu
4TZ1cI >Eb\48HRGJmwQ4?IaQNKNn&QIN<%+eZ/kcPa?4W>d91&Hpm?Q8H+SqYlphjZ/iGX^e:#?&GdD8j&\qap
jte\&/ jKFqSiY9H6nt&!%?<k$!@e=LI4HKRZ##NZ:#9TjdqpumRM>H!eTiJ=hMGXnL#qj=jkBD$+j8q<Lq>%PM
BKb@<! hZ*=uukXN+Nk91M9Z$+$4<$nhu:Ld#NY#T=hQD&j^8<>&X:/bZj=dqRi5Qq<94yye&IG@d+Mn%=!S5Hu
FjI#Ka Y/6aeuw+jKnK%%dXaPMlJ:<X\CX9=jT6/R>G!Qj=bVY@=+BdVu:eaQES1:\@#?>&\1Xdl<\dwthw&TJM
VFG<:G :kt^9qYWcp:Y1pmSW#pEJ<<@QZtTi=JV5iR#?q%?pjBd?T&D1yZL+R*BS!\^DwTdbePq\hj*+*Aa!kqb
R!k=\8 Y<k1pQZ66=c?iyK4WtkiqC<6K!hK+#F!=qCmEp9XJG@DS/1mLiFa6an:MbiFuNWeCK8ich>lKE:qXZP:
qAedM6 8TiQFKy1iZa%T!uEnqaXL\ppmwBK<ch1F1la=jlE@>a!6wER*FBd=GLmi4^P1Y4qdb5l4Qp=>PN*I6VH
++Sdy1 PE9acm+IjyHZZqa+$plaA4HS=q9=$$IPqQNWm!4k*@qC<BR4K\4J!j8#&T#Fb9II/M@AHRajp&XBEpa%
HuX\kY iuVK:^ty18wu8qlp1u<cC/>1XcTuVc6n=Wm5cqWyXEW$AAe/b\::?w5qWAb@qwNNXGb/%h<NLuNPuL:%
K@wIN? a\:Y<\%jKCX99Xi?RBm9<A$MI<yt?E1j\%u&n^>@ic9/!?JnW?GnJmJF@iBmTm<XESemmR%#Ci/WA8H&
>CX6wk \inb1p/Wd#XX<<iQiR$nqBPbh\6>b8hFDQ@@tL#=+<1CN\9Fle%9HN8P+N4C^?hqaQI*HJQ^>DHSe?=6
n\N<:Z +p6XK#Gm=n//M=8GwW:B?6MQ=5?$=%L6kEMC=Ma:&\/aI&Y9w8P%HSyhLQmX/@h/jGl<cp\KJ/iHWp!=
jWi^<h 9IeFCTW+bwQ#Mkn<FPeKd:YEwK?8m9l!#N@iMhi8+8Jqa8:*/h@+P\NG<Qh=+\CB!Abau:CH$bjC=d\e
*ZeiHw +ue+VtDjTeL#qu1Y/@kT9dQY4?CPWYVVV:INMHc$:GqmJF6%4?<HKtHS&4Fl:/LV8hK*^dapQe>PD9bi
Q&QX1E #:+t/uC/*cb89Fhey#6h+naV9w/%nHH^naYnV\c&H?p<bBk5SA?YF!?1qqc$MWSbnNuwNJ8?:++B>G+K
=<W1kG 6&k5*m*iL>#^+6&:h&G#&\#jaY9/@9$mhL1PnKFau#Z@9WPR^B!:Rtj<!#8YlD%i$lyKV#RM^$8><miS
ApiF^E lCN9=uR#n1<4#=h%t+&Ac!DZ><qtA@8hL6TIm1i>pLE@j>>AmySnT#@JhnNC@#\i1+GV@M!e^B<8Wi%1
@hL4kV Hbj#91EV!8Gqq$6p$M9AANlF*\l^uMRJHE&t5dRyykF\JFGFKL:SaX@<K8#G*TABZ9BHq@V:S*L6aN5$
Z5cL^k np=!k6>b&ZJ1?n4bcZCBMj:+@yj*@HK!I:B=/ZGA#KVS/pjpK?eTALPAp5ci=MX&y!NE=h9cey\W!q:6
XDplh1 EuqaS!@!q#?ujLXlpX:Mb9%k98Y:yimLjYXw\n:Hq+:J$5=G?qqyX@SZpA!e/c@MN<yJ\^\>pRlPy&$e
emaLiB Mne!64\jqV<uyXy?V1Kytn=p6#<tdNJjTR$*9%NHRc^<euVdZ9p%KF8pqL9=<aKcEhBPj1G4c6+8@WKX
wq?$NZ 6aq9<J5e9IclIQPLGNyjXdMG&BJW>k=YNiql1LMEG9JI==NLjw<4?XY8lCL@lF1D<PulwL^TYHVNelRb
1dcb+i &C:mXQ1/4K#TaqXX/^Rnt@#AGK&Aw15NFY64Xk8q?c5&iX#Mu@K?qtiAQ51c95=9!1D1pMl8%=G?LqjN
=R+PqM QHtW@Tb4?mZ6</4c$AqZe4Va:FncV:I4aphHE/AJ!FeVXGqd$ECaN1mcRi8Yp*e/Z^JZ@Ry/l88#ie/k
-AG6WJ 000531969c600110334 Page 61 of binaries2.zip
KGu/il 4<5aE$6nbYW#:D@F4J=9P6&<QPX!&W\8!^=c9WlEAnaP:%ua#V<q8JCCi1:tBbcV<IjmZI&$#H8<WP<d
Lec6yI 91i1!Z&SqYQH<54#lN<:dSA$>XMb&pByW/pHtkynk<6m/WF?cc<C\B+i1tM=K+%NFaTjQFu&qBybX?cX
R4#u>+ V:=@%^:D6EYY99ih>6Ny4$IljH?qC=S&pkHM9KHA*a@4\FZVp*y+jQiPnPJqE&u+!nKZlJD!#XhZ&$$4
%S^!56 h\5*L*VD8@qC5<SXbiqkk@bDw:ZRpt1q=IWnB&iyu1&QK/yA>hYtVn6mV=yu\9aQE&DVY5iybqeEbh?a
\=aaKn 6899tB4iLY&k<T5>A6&=ct1LiXLe\NI?S>yaXIa?<tRp\A*V\tbXWGdwFX#Q1tp9m<>/cd<1%XwD^%Ga
k!IpQw 1yHA6Lqn&^tQ6h*kaehn#qHA89K>EkPe6M=^Ml:^>FC1Y6SDcal>hlMwQL<58&8tb&?yF*8qBWb\n5e4
N^Tb&u L#pl\#y+!P>*>MQ?W5@GG&QYw@RVee\mGCcj>yQ?VhWP58*pheA$8Q\VPwLyhQqY%pDP6Tu5ISqHwbFZ
!6lGea Jhej%$kpN=eGtbi@WIn*T?hbyQYiBFeEjBe$iI&HYF=&/HqTjpp1kq@%^$5>y<y#yM&SXLHR!&YCd5DY
yt<b6V d4EI8*:wG*tpnYMQbnKMZJRYLBd5AhHFaH*%/9*:h?@Hb%hwCyY4aR8/jed\K8^WLnDtnI6eJ5V=KIJ%
D<DkVw @T/<Aq9hBDi>PFuDH*y%8pGZ/WB8W8#ITuImetNj9tElZ9YFeNY?4/JXQa8/jBt@DHt6V4e45KFe!mG\
##eMEu +d6pkICX+ymGVpD^Hy&#FER?>QX?1E1PDPPyME=S*+?h\JHib#\il4#pL8RqMpLZF!yhp%XFQHP>En:*
p?@XA/ !+KCCX%=W:mCVqn=nlJI>5>\T^!/@?:ni#Rpm&q/dW\anQ*$IuS@>ew*4Fi@ZH%+:*@!X!yn!jiP^ZkX
Xla9$e q%j>/A!E?>ytJZ*!4!#niD1PuiT6nyhMDnw4E8yXVKI69RVBRQiX4nAi*+KXq6nt:$lID&@:!=>54dGX
R8jHAS ^!N@m>9<kK*<*md/M@=TqaFj!4?/*jR=w/ItQn\L#=k6&XQ!1/:y:/dKn@H!h?I<4&y?SHZ%q9/adNL9
Ehm*yq Jd8Z9#e49:auQ>GqZdA6X<iVMlb!lpPD:<yk^py?JNd<9KuyGi>e1tdC#py@c*Z=P:jJNGw!^&1d?m8K
PPIS5Q QwS>Ai9Ld\u?t!$/!+p^LmjuqVAMHRc@^Z<l<GVPNkmm/P#54I@:%Q66@9$Bl^&iE\SVatL%j19@8!DA
HC!Pa1 /GVQbBuL96%hM!w:\P$k&V!R:aQ19*4=S6a1D@wE#<b=QAD:RjRFecFu&de:GH#+5PAN/&Kl#@QF@P*d
NVACGh 6@QbA85e#%#$WbbL4t>\9:!eZX!?8blh/DLRhVA+Qd$auD+@Hb\MbuMFFyhYQW<X>8*dD@MQ<*@B?6jF
hp1*Hl !8F=#FtM+&IhZF!MeMBLdF@m1H4+$<HkL#@>>B!HQ#$B\8tJ8YH=<iVp+Ee<@lQ8A>5&Q1&+$#PJwRMe
^DIL>T ud?<Ic9*=5%5bZpn4PKL$b9B+QLN:HLkHcmKhk<PVlWb4H+C1<HJAba@HH#@Z:=@eyJAu*^@<8QBQ*$@
iq1:a? t/qu<h6@\qiPMbkNBp8@P#%h^RWpGAQ>A9KMD6bhhQeE$H@=!$CwZ1:pu8?J?1NC@@njj@#^W9:+!QCh
A$hb$d K8:8/X69JbwGk>u/A5#+ekmhHH\cHL5uMPZy@#+h@GX\5aL:B!WM61CL&&DA##/Bka%>9?Y:V8c*?L=h
*ZS@Tu e=?lP6A>aju>BZS>?u#\CX>qC#&D<YBRXV$u>yZ*um=8<=&9M^+CjuBjQnk>HeC?y#?>YeE>PFqb\Fn=
V4#md# R5?4>wYiS/NX*Qp6NZP>Q/*6:y=i\KGjZ/:yGj=>Kw^@yFhjmBGi&G9&#b^<YNZ#HZ^u>:MXqFQ/>eX>
TbNJ=A jLHe$9Nbw8hX*I5LyIp%bLnW=?9pCT$<?>T?J\unY*1imq@6uu!I+%Y?C/K8Wj/X+pG9@8q!ni@yG6>%
H^M4n= Qh@NN+uj$R48w:ZCenJaLPLeGtGE<J5:+mml4LnXL+!d?NZkZ%d>iituB+P:9P4kk45@jFk%PX^/eFt>
+1I>!k /^nj4@mX&DhemcQFeHm*+W#816/CHTESi\h4Bl/e94uH>::@%L:1X=uBl:9+14\u6*ESMHhE%Rp1XjXi
hhFyn! 4\QjH$VQ*u4i8Je9@#md4cdI/5ZqZhGMTLw@%9+A9yd1&X:Np@j#=aiR96dWQEJh?qTbu?GL9&w>ky:>
C\Wd56 hj88^8<uXGd^Gm:T!KjcPjnyM*\#8:jmKLZ9=*C@j:PG!?4@Kh?Dp+9Q=dTLC%9$:K*/e?dm5*^*L?b4
<Cn\Tb 4&d^HjcFun?H1//b%q?%:?=kDZiGQm=a</!*c<+JQZ<1JcN4NW@P%6>#iZtkiq/%L@T</5<ZF?k5X#>%
&LaNFu 59lt4e=V5Bu@thJq@GcEFtp\Gw+G6*B@Gq^1L=jkYm6>V8JZ/@aq:tK?^uhNk!iZypah\Ihl/$5$I&<G
!lnF*j q?8+cH*Yhdnt#*jtDiA8Q1!G#8C9<Zwc8E!T&C=cT9SZq%l9<WZj9N4DcG>YZh4*!?Ct@u#d919H&B*M
GDcqhW F:hTCjyDd#e69YcR5G:j$+9h*h6/4q44iYPhL<bEc\%4>YL&\j=M$j@tG!Vu$eWcL5hd/*F$wAMX:*=@
H<MN^n @mSEL6@?djH=j8Md$B*h%X:j+u54nm+?q=<^tym@@jD=SwjX/HN=5t458^=Hu<>ZTMnw6#=<44E:aGt<
1=Bc&I tH%:9%\c9=qdhYH\>@6^h$H*Z$B+Wd%@%8SCQQy?9kiu>?u=j6#B=X5Pj8ej:nW^l1Reyq:P4H6FH/S/
N<9Z1* D6b\4?:DSY#PFu@q!H9^6%:9Vyh1n$b9SmnKF@Q19Xa+Wd+=D*!uT>#u>@E>aAQ*h4:+G+j>H?:RNXw@
A#wl&6 nE>qaB:j4ijhH#D1Q$u!JM1k+p4l?Z=&B&+Xw!q$na8=<Q$4$Ipe4:X+<PQbJjlm!AnFjPJZ8>WDhGPA
EWK/qF HYmjVG<&$!yVW*GYm@!K\\\MRNZMhilpB:@SPRj$LB=/:jaQ#\eZq/6DN:4>kFqV=mB\b^bnI8M$l&aS
6LuH!G n%=qkK9LGtVY9@*6:ai=#KR5?B*PV^jbh$GdnnnqIVAZb5bDBtkeLb&ie5yD?@bV$!jIF&uQ9m#8NLFF
mlqh^% #1#bdQcd#JNHV#LjbHejbZHj#imc!i^tQ4?N6M\He%68t!WI^pdJZPLjcy:RC%hlnW9@F4BVV5Pi@VpF
t&H@P% uqb@A>m^G9dQ1+#Q^6X@&<Xd\XyHN584/c9yiH\&Q5Q#&c8#<T9b<R44:iZXYHjG1<8u:#4n\Xa^:+B>
Sq*=5$ qV\t6!tPjQaKu^!Q:$aG:Qm#8K8ku?E4cK>iCX6?=6W4EjlV#KWeu\jt^%@hSjjXLiV^C9/b/nqX/TjI
hGm/YV 4*=h#>NZ9$=ZwIm5=y&?En*j#%h*@^48hJZduW/XkB8&K5c4P%GZtw=@#dE?Ij#@AFBLA\RWAAIACADk
bK58n/ XY$qNL+aG:Q9AACaYRIAM\AAAGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^qem>mdZB#L&b!bYX*aZJq
P@%1e/ L*NqhHX\LtJ6eIV>!&6ni:5tCH1X8\lD%/S/XwPmKIkESTHBD4w:S\WJVR<?kaPT\ac#p/J!q1P%Cktp
/9?!&V SN4I**EEt<kc:kMP5BwyWnK!CY8j5\%FERE&&IWEWmLFF=cQh#RWNJ^@\ApK5BYDJqG@#*9:@iV>JY%b
IVHW$< 68TLL86b#*8@@D>iHj*+u&*k+=@@u#a&e9V>@=%5dQ\@/by5dG*a^@@q@!#Z>a<D@6\+PJB98PBH>PX@
^kVlhX @@@<:^8L/iuG+F@<h^548t:<1@>8a+?8A:18/L4^6*Tj4kP/48m/<i@wQq$HhF*ShiPc:6N%RNeXZVj?
4jTJD/ mi:VhWDZFX$*XuTj4kP/48m/5dHHq\FhX*Vh?G@wHq$HhF*ShiNj$H&/D8m/w89G9/L:hB*RhWZZnd?q
\yPJny ?*Rh$HXF%+%@S@jyP1D4m1+d%*Tj4kP/48m/<W>$u/+D81:w84Gm?*Rh$HXFX*yAilX@T/@ud?u%@C&>
6VB%=Q H4yQ%\FhX*Vh?Bh$u/+D81:w89G9/D=hB*Sh$ZZnd?p?ZRh$ZhF%+>@SjdwP/L1m/<a%*cj4kK+48t:<
LbH<uQ E>&u/+C8K:4TQ>H4wj6$ZhF%k+@MkC<48t:<N*Tj4kP/48m/<T@wQq$HhF*ShiNj$Z&/D8m/w89G*>J>
VV89c? 8k:w81L4^4?n?*Rh$HXF%+%48p@ZAX%ZhN*+J:yQ%\FhX*VhYNF>8k:w81L4^5d9>Hy?y%j!P:&i*?u%
pnMPB/ $H&/D8m/w89G9/D:hB*RhWZZnZ>F>?p/wP8K4l6@T@jyP1D4m1+d@+:8$*XA%^XhN/:yQq$HhF*ShiPj
@n<KKX /D=hB*Sh$ZXnSjjyP1D4C4j=1K#whhDbR>eBZXh$*jkZhJ?8A:18/L4^4?k?ZRh$ZhF%+&@yQq$HhF*S
W=!1qw hiQj$Z&/D8m/w89GNh&u/+C8K:y8@BQhy?8A4m9eZ6F681+?j/a4jX@>Z?u/4?ucw86uuEd$?ITiRE1Q
IQ::M# V@jyP1D4m1+d%*Tj4kP/48m/<W>$u/+D81=\t==!5AJZmT>$HhB%ShiN@+d8$*XA%^XhN+mni*Sh@H>Z
D%PRa@ G@%8q#t<kiPB@<Z4+*6+jdm:&5mTLC$Y$:Tab9Tb$X&/k&5^T@TH8EW@^^>tKZ/j<E@=99+*@^9>6ynK
w^$p#= d:LE@/KIZ&bJ\w?Au@QDFSQ=H@\Lj5=@!I?Q?@lujmn?W*:MI9?Cu+?jNm9/5<5nF@Zu?1V!P9Ei?EpT
Y!j/<F 9A6=Bj#8/Du\a8VSMu*y<q1Vwn^kc8?J*+4<td$:iWb=C\p@9Q=QpV@=NiQZ?nw#PSn!NH1A?jlt1d=e
lXQ>QQ PhJ<SQV=E#$Y>yn<YnJ=41L<YTwQIjnl^@w!m8u@@K@%hil>@pXSD/5<ZRCHd&YJ@uF1^>n?&\+/$Mn+
nDlaKi Dil=\P<+$$jI>Ina&%A5GIlMDq=1X*$NeqjQkGL1mMw*jY%yAJ!l$>hb%EPKu?pyXyS*cM>V^CFJ:S&F
SL6=>A X!>9XXHK>M@5>@bt>Xu$KCZ/EwwK4KCkGNQSn<<jjSV?:*RhYH6jem*/aeKZwn!ZMpLlpL<NL!M4@l?9
J?B*4! >e#J>KH\n*JG&h@\mbNF6%J:Tcp?c!KQ:&>IVtllR#GV%<u\GmXT+:!jT9\C:F*#Q?4n!jtwl<uplBLj
jB\di< /cwM$RPhGCN\Q\$w5=VIFPNmE6luy+8<IBM&Ku5ELkXSibEaQjZ<VbVX?8d$8jSk/XE1Gq*qm=I=pZeq
e%?#YF TKuM$ue59:LndWe@%heuL#/%l:DnwCIwY/%WQ81j!?9k+^>k=d>Q>bcL%RC49AXDNy!LV46\Z$@yayDQ
$AH!Cc tjK=KH!XQ$:q@JPHLw4EK6y:XEGSbWZ@8:SaNGqqI64E8h^QVETa$LaVPZWCmVbJuA<m4NJaWth!6hQc
K&wNy5 *t:SZ4DkXXVbaKhn/mK//LCtSk==btYbuIIC4RpFP$!y$!KRPalQqT1yuYm4qd#mJI%plPw%?Z>VNcIb
pqBCHh Sbn4c$wVP@!tiQYRJQ1K=B!T5<4W8JI1hbV$lR6lXhBF+m#Xp$dbq/k<+%NEV!5GWLTScD5q1h5Ayk@\
IK=b%6 k/K?aNYei1nnk?dWbTnp+DpkKqWTP/Z6\XJnm4=hbZ#tb&jmW4Fwy*E1A1uwd!PIphSFqt8JaqB4?JQE
nV%FdR ^J:yTyGRKtVAX:^\P=XW1!tqp8lM+lQBVw^\tkcyLLAaS^Vc#IY$uYZF#KkWnAS:l1I>kl*B%I/4CBVn
W^%C=M uM4HtN?ttW**F%%ZP5*p@=*S!9Ym1cuE>Xk^$8Xm!pXM!?\j\\8IlE\^DRe4Wl:/GtIEA>FT@*GRI5Wk
-AicdX 0008719518000110334 Page 62 of binaries2.zip
<u4?m9 5cL@p:ilJp%SVh1IKIwiQT4^Xit1ENwy1#SSC$5$yAEtXpS1=wC1t%TiTe=ZM#iTXMpi6IJdTH1Py@yk
li#5AM jm1:nBb=bd<#K#1e$u!P!9QLw!1Q*Ea8&9qSNL11XHEt/HpY&ZG8XDNXjEutt6G5chQB1SuFS1QMyE85
Aja#qd NQp>JIcA9#Y#B8T\4ZHSV%XV$\FjN:%VN*ZecDj^ThjXT6/Ju%685an6/&i<MW=%wXCnGCuQ^QBQVZ8d
p$D5W\ 6dnPX*pq1jyP\ek*biI1!iYG@M:pyB+DNRd5t!8R%JX8bN9w@$X1*XS$aybP5td^&*?d6XGMDH%Y$uI5
&@WVN# m818yeYkI?$Bk1lVtbMGYI9BtlcIYG\X\*5LXNjncV/t9kk@HSK^4%K*l%Xy4FbB!TStZ/b&WI*u=4Y1
@M1Si> $BS^Xp^VQ*R1\a/@Dt1b1/dWD=CL=hViWLDj#i\$Cyu>Kj<16>qNC8>CH>d5pe\%1Kq\@a@+4E>M=$bG
8N+p@D iDHw?YJ$\$<JhSVXJE<nl:nw:4w@nkwhQXlb$Q&yH5GmG4q!?tXFM?yeFcucCcBG=Di:LZFE^HNKJiaR
F1pklR jCG%e&A*bY/:tDVNA4B&dmTbC@#k6Ydl<QNuyZJ<41aYZTwtc8kZypFhXakuG#^njY?bjqHh:H/9TT6u
Tt>@wc y9=B4L*W*%GLSpYFpet+Yk#cQFcw4kpVjj@?I6*cKKwdGClq@45bqiG61K?c1D66j4teQ=pyMFNRIb/T
N\aIlY y5H5D+I!CR#\MIHaW@=aISak@@<j@&PS^a\>nM1qNXjWRnR1?NZWP&+Re1i%$?#+tF:dcTN>j=\$Vp>9
WP6HeV 5#>*58Nchn^+j@4=J@4L+@j$b+QV!8uu$/\&GB^uy\V!?$GY@DRa9M@wy/h+m5du4DJwbDZ<biM$T$+4
9HQuPt 6e?D$@j$H=WK@Sp>!DH>bbF?j%\b%E\YKcE#b+FKdLaEQRwmt6SnJu//Sw/lw1BYSVA@ZTJ4GC$XH/Aa
IW*pBX #AtX8/qd5=u:wwqdeYbjmXXahGM6<#ikt6V5?MSad:E9=/k?bT1?1ktPaqGhY@M4@8N@VCN@#iST$HSb
CcKLll $FB/q6wj9:@hj#@+Yq5tA\ItY^+ZV\jb<9*^MmH<6n4F&$cq$qnTZ>K9V$<4>FFd9h<mwC4LYyLhLt8X
&4+a8p %Z9/m%Z6iQtKHu?\16XY>I?jK%?Q*!?V!4L!hXC=QW&PX+&jqq?V$>Mc@4K!QKaH/qRMt$^ytYZBWVc#
<T==J* P%*ZbMHTZ+M%CTLJQjhI&K*BGq#b%M&d<P>t#q4k$j^tw+8HyaLEK=w\XI%uy44dHbGRVN^BLJw4HaIE
/tmI!S Ia^ud/HXK1yBHJ$L5T&iBK>E%IchAbZX%\Eh=q6CnZ=%i=\eu>b8p<y6=jR+?jw?8TZKjn&q@^9R*XQC
#FCF9i yVca%=c+eX9JGq>Qn\uG$&M/Dik@/ME?$?*V9%SY@+aibu?bbdi%=ZFC=B:Rj^\Q/DGQd=QcX@#Q1Wil
S16^41 w#M=WWe=LX1kPdY#*<NK^aC*Bb:hI#KTJK=EHa*aX@GDpYqMQNkLci^#SaRNDpK14/Ra4B9ZI@1$:6D/
eeV:Al c\utb?w&85kM95c^5Tlkq!c6qwl=M<ubI6jkh>H<9NRDhMWk@Rp\aqXqTdnT*h9QaPWTFCZiduWIGPIm
kjpXyY @9j$K+FV?j%+?d/a*Vdi4&w4AA&M*ui&*m<4:=j$/P>@4Y$6c+Qc@JRiq9:t%Y%6/#T:QccV+P8<e91i
icZFtc Vkj<JZGe9mhb4Q1DPc4B1hRDX?=5S5=dWK5iEDLyqAZ4P:c6LiTcBh@YHYV:q#RL\1D+=Fj8mcmA#6^B
Bt8\A? $yjtjA*SZu<6h5y=RCFL*B<9bl+#a?@Sa?uMX:Nuk#\R?<NCn^c9NajWA?&N\iuZw8BKIG?hHy<YV:<P
k\@Z!Y dw8u6+P9qYjL#!Aq@jQy%4@@/jQyb?nZ!y>Jb=K5Qd%6FD?V19#%?NWYpj=Xqy/iy4epdRqH?6?j=4>*
HcT?i% dm99d\i*^*TPDH:Q>wt8&iD4%t&&@=p+uMZA8VNdhI$cP<Q!j6%yWE@hqdEH*I5Y9JN@V4LkKI4!T=Ra
Zl4%lI Hq6NR@^ZVYEVwtaK?/P=TqP/Fn%EX<#mtJ\c9^+w>qTdT6%W9Ytn1<i+%R=QR@mp%Wwm*:Ra5tciK9BR
>C<%yB mpwE6!a16/8jWlK>BFZC6uAqLXa1\Im?Xkk/$1Z<@=YpA8dYKmu>WSFj=PnVQ>C@%bdB<etKiBD<^T*>
+BGwnh W+WimX$1?15!@Vp>F@+*Tb+kq:qHupRmP8V$5nTEmELAKkt<=KNl?aY5GLQB5^uPDDhRw>BKFCIH/jVF
@J8F@j FNjmcMWwaB+CBBdHZE?WYWDC@A+Q/T94w4^ZFnKweXTM?G1bTpZjYi?yKE5/mMFW>BD@<ihK5Td/qi?i
DNcDj& !k5klW4*cyXI6GhtV!ecWQD\LYFIEAb4Y#M&bXLQKiqZm>RRZ%M<q+j9k%Ec@c8y$TSKScuuKF?KB1Hn
q!hPHS aKEJC*\@!h!p=8tt1RhK:X!I#9WRIlhYcTnha::8FljhaNJ\uaW/k/!\>=ZE@yR=SB4LTawi*#ajNEqD
@m/*tI %wB?AL9JMkqtF$h=lBB=CeGAwu5H?Q5cPC48cpWCe=XK=E1aN4M5wcjW%H1lZ>TmjESm!NZ\Mwnhc9NX
>Ppu?Z \Q!5b1G>anA#$@C9SXPnRc+E*%djXqwMG5b5CE8nlqIBVScFpLWi8KLBZp!#J/</PuBbqCK*PFe+1l/Z
I<BJYK #m^Fy<LeR@5Y#T&GpJ*H+M%BKwdM6$X<k<tRRR/L6M/m9GPR?4H*ZkN<6aa=$$u6jTNLmqFC^q%BPX9h
SGw&G< a%e:\HSTMcT1wwwIPVYKHm:QQHAu<mMNkEXydZhalSuBBakTJMF+%KNtCmak14cpS&p>jG=Ge*m$1Hkl
pGJJMV qj>Jm$=ZQR8%XEVCe%GR&mXu$a5eLB9Nu4EH@MI^TI8iwF+LqJmZ//<+MwWbZic48hbJdJ?=H6iu?N1k
VD&$%j t=*dnpYEn5qI$8^CMjFp6$eDplD+51NpqyquT$L8&1YBH4Iw6yq/bCtK99CDNdI$XG:\iY@YjDGKDEh<
$<eD1X nYQH5T%5RRDHPEnIwke+R%\:lLCLRZ^bWDGJV&VZk!EiEl6^q5u*JIdK*uR6QP!y/*B&F#QQSL9XH:pA
9Y%Kn4 >G@EX\%8JKd\uAn<!LZnYqb=V=l8Hd<uRj6?m=kKR+k?!bEl!+nMwR4>BnGnSp*iFH::@n%J=8McYV1h
RhDQl& u!wkP%qIJKNJqDb?It9wy%yY1?E8@iXQdG@SdZw$@lHh\D?>:?C*bH@SI%jwEh:ZcyAaiDqb:Z&6ep9Y
y8JVp5 GQ$yGYZ$V?Z*>DhydB<q5hYbFEN?NwpV1cymLSH1m6y>T+%?b!G?9PaBJeFEC!iVJu1DtFAq8&dE?R6J
QWkS<m *S<LKT@QLkZty&9^KA<+iu==VSARZ>M5W1pY*LWw:GBFS8uY/hjV+8jd$&W6QX%Y!MQMn5u@8Q&/1yEu
uFKRuS k%<NKl!AiH>/#K@5?DT4pPPV%W/Z^<uy:=<H6SWRYhY!=i@J/Ye!kw+Sd!KZcEYQNmDZlt!6+/<%iu!e
jc^9WI PFqq&Vp?uhii@aY<&eHZ$?TWHNuq@?6$eL4Mc59*niZ^ci*Q^:h+<tL!6Zb<T$>a@M9k8QE%?JlF4$ba
!cM4Ek +&8eq%&#hENm&Z<e\6aib4Qc4/lCKA4hSLqXVjRGKcHYZqyeW!qJZGTu<jN54hnJM4Kl<1kaX@laLm!1
w<Ji\+ 9SMb\9/41>SmGtL+@Ea/1$1chG/L6YXq/#m=Qe:P9^+uj!G\@qJbXkkw<q&*VlFdTw9H=MAiD!wI^b\P
>baMb? /J?JVpV6Y@yYYXXkY>Gj@:V/ZLu>M>GPeH!@>du&tZ/=JBkdPFYY=DASZ&>QV:i?JlpkQ^$e+:jpM?F9
+$yywq EK4KGq?V\hhcm!VA55Q?E5H:6Zl/&qlY+DeXR@IqeaZ8NRhFhq?>GMl6G\$NF:Y5KI6KCWQIZI5>uLLB
&8BtBb ^JJjBGXe>H!AclZL!*9WIAV:R/Gl=M9T>cIt<<FTi^XymH^FyA:Y6L%^?K>QKm%F4wkG@$1HP99#b\V:
1TdCWP 9uaI\u<#d\!E4+kbk1<J@eq6nX:=kFlcI!4TQ+K9Y:i*ne46%>9KMSGTu/6&Y@6<P1kR&<k*P1dQ+<Ey
uejyy/ ^^/#JSE>PX/8\Q4maQAi+eqBBhhV@BcS^<4!y<4^/VL=/ZQ^<@u^Fn*G5Ym4LiH4<dJanMKhu1GM1l56
HS$b/w jb=E^Z8S$c?iw1YmJTL9dDbQ^$1#4Gw55w$%Hl^185\>%b1I<ElSe1=wYW@>8^AhVWK<L<TXm^+Sm&w/
ed*DZB \t5KGXHm1=X$b5Y%><@9bHDK#H6@?nu=89X?%TF?Lm5D+5:ZX:h$tIp4:%j:NeIB+ann4HLM9m6JcSKV
V/w?Xb >F?D^4LY8F&?==iK/QBQZ\q@A9Q4kIR8@S>>9V&GTF&?Q:+q$JFQIKqh1c^?1nEn/Xq?JYHe1K\/FWI\
A6u:D< P:&6He>4Z^8*u&6\k6LKX@4ju::TmZDeM6A5hb1twb^bC^?KwSkwKt6KHcVEVk+@5wq4Z$<6SmtdVJP^
?#AMBJ Jl9XjyiKlGDXiFth?/miw9GT/mlLaFt/EHt&CHicY4G*S1qMZ1#b8iLu^Mu68FRBS?k>w4FFE4iX4QQV
k#1YD& wFQ5%Iyp9d\@4uXIiS+jI\F*uL%jubJ:iZ^KH\NaQRQpaWlAN?l*6:Y9:$q<+pF41&Y66bWlm6T+@hy+
Jw$X96 V&hByZnMWcZ$y</#+%9eJ^Q1>85YKRAp=$/S8KQj<4@kD&8X$&Yu?H:\p@\eL@m&S44&6JLWQn@VHJZZ
bIDVnD E$hXD1qEcwL1CyWN5V<cCphn<<pm#?4APeGLqkIX?Su1e6K%CLP4:mnP4EWc+SY5b@Y<kn/Na5RmkEVQ
j</h=/ B^5/DR=MZP\L@Yw8YSKydQtZnIVi/dHeT%##$$86@TVkp$mtQ<MlVmwpXDpkuQ/$Iwq<i@1%$mEKpyKp
LkIqMw L?BBdRZ%KPj4u#9t46w4Ij&1abuV%Z894uKuM#6tIb*YV8WEhaQkK*p:Fy^X!YZ8XSyMKKt1mmJF!byL
$nkbIc qaZ1jI?%icFSE4wGLIy9dJLmK9ik#C&$G8aRSZJLQDm/wne<SCIYe*C/w61:hC&tJw>8^y6HIy&8IqFa
\y@p5X 9+d8k#k:L\1G@B!XRP4+<NF/L&CVpw\1/l5@%eTBlK>Ti$>M4:%@SV>?Z?G@1dB@FPW+XjHJRWlIiM5l
kCe*N8 >:?^*kq\wZJc!+LypaZaR/$mCST9uuV:M5S$$/ntWQXRHF#I*AuPRpnP+::&$#mCwjXYGyQI$1l9IRq1
q+9Hbn II++l#J44==JI*X9eTu*?wNBFMYIA=qDQXWTMVG#cBn5y4nP*tQyIkhmlSRcZwyS&bu!\<TQuA%i!8SB
qByHc/ 6?Dw&Y5PIW6Qm\hVNAlQW\lt8+d*/8$mmXe68yqk=$$p#MI4pMlIEuK$Ra9Gdw1y6Vk#Gly>*F/Km89T
w?b?aA EAZ#PQAcac*t!VM^wjDbSdHXGej=+5#/d?I/5NST\JHh4AF!QCjue@VNF8NmLc<Le#9B6aHqMnI9*+k/
SSZA4b TMJdM$tXYpG6!aym!H4b#:%E^aEN6blF6@8LmhaVi=t5bq&<wTmJ+&XShW@pcpdQFdWuJCH+YI^dj=Kw
VEqHuY yFL%cakRJ/EP#D^a:>N!K>^h+<n*jFI+EbjpY=q6XEAVCntLHuKVe:tal8J4Q>j=d/BjJRKZSM@wJi:&
=tT%WM ?w9Y8BYmPAlTFnM4EG!Rnp*<>clCL*w^1q1GXwh1y4*y%5S4^yLWHRGL:aaYGQMhQR?i!a9\PJAGV@W>
de@&w9 BnWcNR>y4M$nRy1!mXP!YhSSa8/\6>iaZSqFMNI5JPGK*9GkXW\Y6DCJF<IFFnbKQhu4$Y!LjIn4G#6m
l^1<Mn q5<NPdHEK=nXQ?j*w*#NWk<&JmF&H!1pW&?W!cJk1H+n+@S&Ye6CYdy/CpWL>1eSY$#LyDH9pyDpeXVD
-A*upj 000fbccfafc00110334 Page 63 of binaries2.zip
RtP%XR &b6EFV@FKPcTYNF@KDb$ST1FkJF&mWYu!hw$=GGKuyI6^5&aJp#Fw*Eb/?ZK=5l/e68!eeHPDiLP9hFR
B^q<eK $=ltWihMF9QXA5Xb1L<T%KL5t<5*6c!>py4=ckY/SY8Be&M95bKNyBlXXFwLq+tj!tC%Yl%HJe6QmwbD
h:S<+R y8tQ/Rj9P!\twijYWEmC1Scw:4=MWXY<N:+E&iaqV$d:4Bl15qYlJ*bI>T$FESum66/mGiXPm1Gp18n^
q=GFjh je5=Fe&FTWN&LLS%Yl+&XD8wwiVX?Nd@c*1+/K&%YTRN=i$tYq96/pjTI!wBpM<^hcjXY1uZ/XkhdMk8
\VG8=$ SW%kZw%\T4CiYqF*mH^tWZi4F@WuS91wCV4T4XuW@qJMR!he$D&bw=J1j<\cpbPwtLCaiF6^E9^P%+>i
Ke$4K1 Li#wF$PDd=166i>E:dkiM@B*yH%I>tdEEE9n?k4V%uE/YPX&XQke?J1+m^65&MmF!6SI%+m*K=ppWkcc
I<Jd9X j@ZVJ@PK=t#h6q#964SGGZJA6qc4=Yp\X:*KPey/SAdd8yJP*FX$5#F\I5tm%J\1Pa@:mHKM??hDT=<J
FV:kJl E<?$?Pq8Kn?N&@Re@Vl@1aJAP*p<+mPhk6cT=ythXCP?EtS!8XeM8TZVJ/=AXip>KZ!PCuim@EIeTp1i
jB=j9Q JK1Kb8Mu&6^m?nXpHKJRcyKFb5+$CR4EXKSnYLpq6u+NFV^J/E4\#8M$FDaYw^SJ/Py&bY/q9%qeBBl/
hPq&k\ I:Pw5h+:yw#wWaGQKBJL!XlqSF^Et\V#9ll%u^inp5T+$#YJml16&q^/R>LR$=B+BCC$?mdSQAb*:WI4
^ecCkG WSwZQpeNwptWD+^!E*Gu%Fy99/u#+D%!ucqcFBcELEc8RhHWX%G%ly1I>u1lY=i%JB!^RJNRu8Zl9YJp
\pIZ># $4w=J\e1Vb:t4WJ@lReZR4F6bQIcKXLu1H1n/&ZGX6@yT6k#uCE#tTalBd8t/qZHKJiLTSLdTqq\@e%X
dE98mY N<tVlXbm6^ZNDM@CFI/wlNlCE8c:ybFDba*@RV:yC\#eM\Vad6I\a>T4FZ1Q*Kw^4SG/^>KMVcdX<nma
h8%TbA n?5y4LY8$T^M4Rm%X1tQVRmXHpt&hycGQGMc@M>RPB4Za#l%54m%^a\&?@9EhFPe?$uZ/\MnXS@Tq/tu
<#8FNA jCLXyKX<$T8Q@Q&RdpuntSNb%BQ1b:>PN5tm*H+p9n#iG65lYnWbqcYc1kBjyTm<GA*>CG<\Cd!N4GZ6
#KFe*X HGT&45Rchk*tqwiXTwd1<1KHpJ++EWpY6WTGkk@9FNI<cCmXDNb!/8GTLEy<JXHBh&Tml%wEt//TlG^#
D+SIGM qAuXpnk>&6:>1\tiamkX$#/@LE:YlJblNWKDhY%9*\$8m+mFcJ%ZXEYq^$t&hnP$:1YiWe:YynCIjqWV
SicI+A PuWL#:QPIYHqIn\L#ReXk=YA6e!puuTY:Qh\4WXm#iq#dbaGYNM$6D!+8=qwAMICaF/m/p4H!8NMl&V@
K!HL!d TXm#1HnImkHn8Sll1p@w<uEZIK4a#LI\uCB&hK*!N\=5Fhe/CI9Ji8FYpAIYkjMM8JhuiJNkMha&WVT%
Z*C/SP /N*X:u%\9Eu#^EXLH+cAd^nZptY%^9H^+NjQy#>X6N!$<upXQl48JeY6**GI^^4Awpm!^\G5665PYVSj
m+Pn#4 JE6N4acCw&KaFtM6D+tGp/*i$XS5TLNtTcllTmN@N9TTbZG#qbXQ?AkY4:IY:kSHNkT6Ek>=YdNMXk!P
cy5cW^ dYcu1CWP#ZQ&mXliM^1M4VRN&68u%amqEP\M<&R%bT#%\:Eh4FGhLI%1cdl<>*m\bQntQ%Y5#nRdSLC8
V\XBq$ dn%*:bZXYST8NXM>H6eScm8>uT$mRBaJ=#m\y&tdeE=a\N5$ZBwLF*MyZX&u5hcQ=p&=#SmVK%cawe4c
&RCap6 EmecTW?5keMLppL@njt4/Xy6b>E5qmAFQCEV=aR#e@cnmnn*X1&%J%LccX^W&ty=/MPewCR6^8&BTcX^
@wYC!F K1C8B4Ww@*!/Y96+u\VKJXqw4IkLwj&i8!!SIA##1:JwRqL/^MJQ\45NNaQF^G6?wpE$QnXB&>6W=piK
kDHVkm $Mh8^F=tGlWtl/+yK@?%TS#&16R1>T=1njiG*/yPL@wEy!RLa>mTcG^e:CtEAykw!&d%Yj\+\SwLJh<Y
kZK>$6 9=D/+WlytqCL8q8!=QlYWF$!15/9J:C8WMNW4B^Z8IZ!8KcS5YP8b16by&iD:#bMPhTP?cNl5FcP<jjQ
$u^TDT K8w*!1QSm/adCIHZWLa1S\FN%Ya*!1Q<&cy&<S#H^#Y94VRT!Xkp##bHVXj^WD:^mkP5YhVF+uZAc@Mj
FY6\=d %mJIYil#nl4qQSye>JVbp??Jyedewa/e@hlan#BKR&wtDnkuYw<acj+p!n&yEK^>NWH:W&cb%P!yEPcQ
4<D9&p C9=>?dqaTT1u$mFJ@@%=RJjdyR=i4A\?@@y=<HXX$$nEaHX:P:?>ZXZ$?J?8d4h8d&<di9c>y+jl\%Xb
wPdQ/b utcXa8X&YXHnyILAydtQu@qS=n@y8V#+C#*u:eyL1yPRaWtntGmw!qc:M$%CD&#mmh\u9tLwnw5<84lA
JZ5e$t YR8Zw*SA+5HGLCV8$nX\LTNSnCJkSb<TEE4am!=9R9a^mm1HmCH1l&PVL8V>NKB/9DR/XpIJRyL>kc*$
q5Yan^ $eFJXF56d+ujk#V$6YVJu=eXH>TBlyBXVR@\Z@B*YRM+<=N?*6JiAnu=jq4XNNh!VA?:9F$hY:pP+i1n
HPlk=Z M4K6W!=i5qPbm\pcK&?BmChpYIJ+4c6ZDq\w+ZDu\P5D%?y#R\G91?1+RLta4Hiqbqp5=Y\RaVG!LCK*
hdB^Zq Q\:HJY9>bY+Lb<X%aENWPRV+yh/@GKa&tn4ZL8HW+V584mH%X&DqnA=+@L:&>hb\4J^?Hk!?Lt@N\IXB
1aTbAL QRA@Bb?6Ab+J>iL!dqBXck1Tj6EB:eZ?&d166XaDX!Lk1#jK@GW=GQ!q+cju5a1IMI?1/DZFBp@e81ky
Vt5a:w w#V1>4i\4YyAD$GHJKtHu8^MC@$bYh^Ed1hTG9e8y<X$#eXTj#V^*HhmIjMwI=b1ndmu5##$upRXF^bb
nY5bHc V>l@LTcSS%6MjBBmSVZ45tGVCpSYHj<XYPXIF!9LSt*XMHHVYEHZNT11Km14ATuCZ5*W\iDj<$5ALjuB
VZBiB# B%>Dh%GK@/=b&kR6I/8KY#jA%dLd^c&@NN+*Ky:QYb:mPTytM65^YJ8C=$XK&dyX+Ru&$PJt8bRuThKR
yyy!=w D:c!CIe%C#QVuwl?4cmJ+:tbh=Sd!MKiXL&*WB&c81TNe:%Sb1eaBR\=nym=aSn/Jjt5aF!ZWK$&5ku@
aqMua# >F=F<*IN%*<9D*F<C*V$FPm5*t>nbIkTk?AwX:n@YW:q4%8%T1*&=&XNda4BdR$jFa$c9Se%#Y@/*&@h
?AN\S8 ul4F/H>IL/Cbl!Q@KCG9%FwXLZBdhX:lPiK=qCGdpZwtRiFNR4qLYq!jGBMFTpJ$%uQLYSINIAq6PK+!
cJ>>Ab w/I^K^%M9FHWXdAQw4LSL=tXaqqGPR8nNI9FEJNK4HBkLYWSVqdWT$T>\N:=K*1Epd86JQEkZtZ4E4Yp
&4w5Vd V\%mQMSjqnW*J%H%V=1^a:uWW:=:dKeYthy$h@tZX&yB95h9q:e%Qb5d6#WHy$^Gp=&TY@m#&>5@/?pl
XyN:W* n:JXW*$$\HQe:peDS/QlS^=:6hISV#&Hpyt%C9p5eyMnaAYBNIwBS*FIu#RaM$WDwGpY9QM+%i!qIXG6
LFl8kT XhRN:!H=anV?&15AItD6^PP?1<lj%lEt<4=1T\nlY6HLQ!IHB&nZ%8T\ha?@myPPcJTLJ1?>1pmL54IG
NWGnCe >:JK/q$\jNiXSFd&TWbbFQ9Ea=d^TF4quKE#J\8Gb+WjNYS&Qa&dS8X>^cm/aG*!8Y8&EKn#Wk+:Pwt+
@ANKhp ^%EQban/YlVEJWR^C=YEQ4VCa$yyMVV?&qTQ+L\H<b/GGF6eSS9Tn#y:!EKbIwinabybcD+XQ4=Q%8!=
N>6nkA u$V/*4ING!9ca&@ZV$MeLA*#*4Jw/tw^GHmbDXCJ+&XiJXV$#E^WWKu#eY&KuBhml@HCTYyn=n&Gq<VV
<5h5n* ZhJw4E9Ie/b4yedS^LqmTQeXjjmYB\MhX8>N#$K%qE?QK1:ub8K$n#>b+p%bWcw\46hMw1t\Wdq8=w$k
WA@Qi# YlCMi9<+pGJnGQp^*m<=B=hEytNtFEXHI>m+ZI5RS*X4Zwad<q/5#HV?uqj#FbNwMGPIMWbPy8ZkpmTK
/^P6<G J&1p&dPpIbeb+khJXI\5E@#Twk&pYJ5JdtteJFR#&??#NB4#48*B%m@4STGyPn9SbkILT@9BLZ1qccTk
e<!bN> 9bLjR1hS5bPFi>P%F6dA$&mP1d&^^JJWhE9mEu/mJWGdCBjQ%&cA\&dl<NN:jeuB+eEW6XCP:5u^$HRm
K#XDN9 a\>hSitA=!!8E+?GiYa?n<\mm%dn@cVe1Lk?dCYiNShYEJmyFEtWLAkLG%4qbR=QS9bHZ1aNV+!tDBjD
*JJ=QD ZL6$jY6A*DwS?lAmBX$Me:>hVwj^^yEe5h!Ey<aVj++$nEaQ6Xneu?NDw+yS+1#aWZH4e+l=MkntTlC\
I:ul%< y&c$>$LkQ\5?iJ4Fe$15GL=Yc:C6c#akPn9a?w$MpnVwe56qw++Qj>tw/j$5DDG\IeDF!N/J19EqKl5X
HIXu^K ZNlEmGkkRK16G1uPc+$cVD$1Hi>mTMQ<eR$K?LkB+&AW&9bc$6DjyhIt5\:/8Nw51mHY8W$luYub:/LH
4lBRZ\ K>Ip<&1y$J+q$Pye46nQ+meZid9eD@$mFda:n>Gc8FY^hyD*1#l!pVRGj^pMVIMkcFm^KNqQy^bqQ1/w
:Vk$&E nHt@JV?yMCZi$:??%*P5Rj>b5^LGaqa?@kwDduW:1JtqWEP\$IhP<XQX>H!6IFd=q%4mJ*:&^+pRcSac
JX/k9t DiIKw:mlJ4VISS%X<VC%LLVI^u$qc\M5I5c1ncbXMFGY!E9Im*FNayd/KQF$dbJiG8X>5&IY%R%=<FL:
DDkq*$ 4qKjjPRJkwy/4q1PBbhFA<WDGdeq=j?SSX#De$N&L&$<DS/my8$:Ep=il8IK6:tY1$ytAiiBSqJk4=&/
ud:BBi N<+l/1%nDtti/k<depKaM+N:Q?q^GanVqcX4le^bQJ$614YQPu:DPCd6k@Ytw@XS\D:^LNSl1ReaFT\F
J*5TN9 ES=<nWDaw4jXiwiJ^/N<#+G%<KSSE/&qBc!R!@&FJBSD<VpEPS^1#G!k6IZ%n^MQXR>CHDkM$W+e%!&t
/!/!S% IPM1Dpn&C8lWlCGmln@@XK9WPn!DktV/LX6qnZ@V1jB:YdL9^C?6JnVYp^%@8EV:H5##=Z5=WY9!SA45
DaFaHW 1/Y<L4^d@ihp9bA=CcbjtlZnNtVjhJFGw\Ln<ZQBm9ciJc>SKwahBjHtH$M$16TIe$By*EVl9YFQa5By
%M=PWq %N@856d4QH$clbeB8TpnMl@%\\FT5#nXHPL<mhk<6XmSl1H*^^byqJHAMKGZytTE4#kM@FjLS4T#R^@\
:H5NTn &PL8iwLW?I+\8cbt%IBnqK+dbPRM+^yC+:j<C=#jqc@!6MG=V=IR$R@n@m%mphtpnVRi<i%tb&LdlSI6
!D\?Cn #C^/A%\TPli<Rnp5$QIFQ>Fa=>DCLM&lwVdCCwdnn9c+phci88lS%tIYJtRpc\ERt/NZnNNFP6SJIj\c
1&aW\8 ywH&wwSe%Cbt>9D9e1+A\KWYc=YZ\qe!iydm*:wum8<Njmm9IyRVlL6BXDReC^ACyyBmIPEQ85q!?JZb
:lNPIP $9\EQCW5QhaRTSLG1&il&CXMVpw!u$peyk\Za*aqYjy$<pP$6TcNPi5X!k=eYCWVLcMII\haFBh>dqa^
\qV^#6 iF4JYk?SS^/mnXbtGSdDj1=+6b8iHD!@!Zy1:XG*LIRWHMwwAqGL!8K@Y9BJn5TjqWd<KEwe%cSd+RVq
?<P?ap E?k>@/pZe\^Ai5RmQh6\Kld15eyp9K$GXH:F*Plq1Jyh5u:NFPG6mnZJtikw4w&1VY%W8@Y1S?XQ$eau
-A#R5* 0004cbf3db600110334 Page 64 of binaries2.zip
?!E61N ?XW^#GC$kqI4/+848K#P^$hL^Q%S%n<eiT>y+nPG9XuJ>dSZA^S%*GJpHu5du/@m5q$j&kii/H\J:!#%
$a@\V: 1KMd8i?Dy@k?V1B:=Z@NnTblA$C+Li5lM4/KJ1&aTqdL5mM@XHicVKZq%%5S@QSW6\QY&Jq1?5<ciKpw
>E61+L y^QX4^/?\FQBEYjnd18TSaPVI@JFq1#duGu+XSJYtwTmd>&1GQl1M^dZX^>a5CT#paTJl+VZF@1E\Z%Y
Tpa::^ eBjXKThbcA=#YS9YL1T^>E&m8HRY?p4MAJN/SP51qbNl!$NI1b9hpZ+N:T/Yl#&%QDTDJjwK=R&mDjqj
E4ZRWT V/Nqku!\j%LVYb+Cj*N/K9a#jh6/#@LiYD>RRecm@XS!65^ZT&Lk=#@yieXyl#V1?!4Gi^G!iLbTa4Hd
Y+8GVS 8Qk/u1cYbL/6MSwA98+nl%Ea&XyG4Jlq$jDI+94c^Hk@Xn!pKdTCFbM5HyB6hDY%+6Wc=me:ZVQ*e$JD
RuRm6B Gw9+!HjSM/>&Gp4AX+&\ZW+C!E5tmP^bad6Je<SL6W5=\9Hi#DkbW/YukJijR**Z!Pw/F9Ih%%llFyF&
/H@h/i W<?Iu\Gu!tj&Z=Z6eupq?qZ5ktN4>#EQN5\N6dHNV+1TmtFTyhtd\dhN%4kcJHw$m$Cu85hDDeP\kdDD
Wq:XCH yBm*>RjZJwp4wG!GmQ6jIR44#ukc9SBQP$YKNyY=$qtw=lEhi:1KZSww5>6XK/&e4yclb$Ni&Fh^em9i
m/#:cH <5X<$V^l&j^ZIbHEEa8blA+V5b6eMy&mW4Y&Y9+1%P$Wd#uTweR<XqZEp8S*M<?Z\j6amkPNZ\>5>yqN
&/VKc= Qm#G8qdbtj!Xw1R$C&Ph5me81\<n6y/<al1kC8I4XDRYM&>w>!XYaW!jTlFj=/kV6eLp%GI^j4qJYQFk
1L4eA& R:YnbWJY@BQ<u!L:4%+nIE%!YZadyYm+#uVJ!m:>M?t@4iNw@%dD:Tmdn8%GDy:9XtSyWb*c!8qk<HtA
GR?1ND n\cRjY<tFn@HX\+qRMHmNKC9Y@mBCtm+R$KH9<C/!5#Q1jmbL!H4>$bmh+DWG<9CA6dpD^NP%@dMSp&t
+eFcQP TVHiZyNF4aHY<l?X8pc:>6I%>1dSA5m+QqtqldZbSERMuYHFLMTFjSFt*GTa?e!C1ABdyIQPq@DStYpT
R%6<H% JXW@+>Tw5Wh+mt$JqXhbNGmS:cHX%%4aDM6IL&6K@nY?au?Hlb!P:cSkM\pHHwui+&I!\NjQPI8a\Kqb
@eGplk b5e&<kZK+C8ZTa1c5IMqeqkVE9HwBX88E%KmWdX6GmkS/9VDk1p5GJytm&dYKK:JF@Xu9VM\nd4twm=Y
8>&F8< d^qN5nB9VW+SZ%Lpa=QNlp8mhKT!QnRP8*>5W@*D/DlB$?bLlKpG:/QeY!$V<\iH<:lm4i!18%nnIkL5
E:pQyy C:iqjQEuiWQ5eqVWSdyFGApjEN*94blt/YQhSI=&WQewEPNX%BBEFL=1^p@$K:&#tyl%E9wYB:tYIRSh
FEG?5y T@#+lZtpnywN8a?KpnJd5l%tQ!Sl\Fc$*e\DF@E&I@W/+$BHNG9@TbI%KZ1HXGlpKc=%%EWb5T\cc85#
ynB\Zi nc^^PA+@b9H1EXQVuM>J4A&6?CSZj1w/XKS!G1ymqaa4#RBaV99a9F/<QqX/cmSL$I9N4\biZpNWeiw%
*T/y9I GBY\eHq:LJGQGtKGEAwYFidGHDiPYR/jin=Q+wkpRKD58SI*CZQW9L*i&ye!T=lwpCuJ51lpPkpXkKt1
Hj:<c9 b??^LGb^6$:W&9ZH%b=JG94nm%1Tdp9Jm@G$1KI*wKhbtEnkSu9a\Steee91Su6&hC?c>+*^jETdhbH?
q6Yj8/ wV@niBDXL*qQTFH>FAnTw5@YMSLi1kYwjDWdS@n!tSRp4>S+H%#h4MJ^C*wS6!!wB:L5R+L<6^4FB@ME
G!&SN1 bQNjX:htl@NV@b8$&MA@X+w?j5ZC>n+c!5hplPFb<a^u6VlhqZymQ>wwH*j4SKPq\1TwbK%n^46a$#>5
9n9DRl XX=*tWNNe#Tu^bcbShMYdaX%GnYh?X!+MJFV=mPGduWe?d@&5V!NPq<!L%:VB>RtS@py#NhMA@Ae5Nlm
T&aLwD y%IP:8@L%T&jQ<4Z#LI#y*k#y=4!E!icDchVd8wTRXhV>%V%K&Gwy:#G@XqiuJ4t$YJ>M^!KWdhG6GW%
Sb#G*1 :CQ#^jBY6bNG/#QC#4NmEqYyy9EPndWtQY9L<duG$iDnLG\!YJ5ZEXihl#4WcM6EtB4n&?/<:>nn*k!<
1#ahih #piMYk=Q@!18ZyRa\\4^1wpQ/dlm@*X=!$W4jL5mE!$=hMZHSdSqJu^hRuJkd8bT5*jHF4*mFNCTc^Tb
YLPwSd >uKi\59>qW>BpeP44\&t4McHNdS<HE%n!Y\5Yh!LH<:<PFkeLaaQDtwwi\y6+qt<Y>Me&Fk^SqZJcV^W
4FL\uc PIp4NhJ+BqY$=nAM!EuY=&#E#i%St%<<#TwLW&%a9<b:$@=/$VimhDalNMn1=hLZVWpI@9&KNiSj!FKX
naIAZw /CGdFVn5A#p5DW:GbYa/m#id@WZ!NFIA1hHFDu6RtB??XA6cAyKhw8X#d1Xe<nlV$^8Hl\PJ^&FXRVE1
HqLl/8 JEtV8CnIy@uHC#C<pecVh>/mq1&*MCZFiBqN&M\Wd@TVqlIq4QuE$i@TcAXImECER8Y%\iGtdWQ4ZdyG
ZyY>*p &LCFq*@w?6ZS@/8+N5I&ib51kTQ:Q4abmyZcKaNF9^/e*1+5=mh1X*I5u^G9+kIajlw&pY5I=$9<tK&$
NwcY&N W^bIMIJ+cPyQGk1Y5&tA%%tS@^d#t^:+qZw+cK=#b!ei6bI?GcVtmbt\8TT1EhPCYSiHId$YDcqN%4aM
peDTN\ YcN^p5WL&8M==MW\n#wcK8Eq+?5dLQ<I4Gnd1H+@DLQP9QE?9D&6H!/GniBJ:c@&cAVV8>k\E*qi5iw:
RR!Eu\ iZbJ:!$V4%Lp$8PE<?yL<wA46eF1PanuWwTQ9\RHXWdjR5?j<qpMDL<&551y1AMMPJb1nm#>Xe?hY<uV
jN5Zn5 +ZYemu?Y/w#M1Kp%Zt&&68Ry&66y#d9cFS>4R!<wVhJw%=A=5J=&e=hGynqFM?ST/*T&+amiW9Dlm>Fk
X+lTFj <KIQJm/GweXYy:m&\**NQdIHpV^hG9qMqiWjD94uTwmXXE+%9uB:YnHF4ChXVVX^Wj?GHFZVVei*K4mb
KjVAY$ nMpjeV$Xm4#*&ltE@:?KZNIVcWu@ZYE:W%*5Cw>CGGlt#&1jBm!mZdj/8Jqm6NAmcteK!#VT$J*p&dQ%
Vl1eQb uc*4w%BD!%&aY?NFwyuX6Jw&nCeJl=HmtXhc^CZX$clmt>eS?6EnHi9SyYA9tNP5>an^Tj5H\+un?y4B
Z/Gi^a q9\*&Wcu6YIaNCR*K!JY8SeT5<N4ai^4Xtpea&b<Vi#^t59lq9!QDP9HSPycVY$H*LS#uS:8<\D:i!R\
a%h*Lu +p?WFG9H::YQ1JFF4/JmBhHiAyNE*wlZpGpnkZ1P$h@:#GGjR^h<D!X59FDQ=h@c41/mXi=1Snb>t5aN
a#dGHI e%KmcYnSBMw5DXQA+qKPbH$>eFIMC6?GBik?n6VQ1DS:KwmZFV$lM$b%!dbSJR6q=NFw\hVmbe/WNBwW
1!6neB whapQ*9HW\TlenAi@=hGw>R!e?!Lpj>y#=hw@9Y>l\m5=<cupQl84VB6LQNJ=c=k9iY1GGaP?%=$4$XP
DWDwb+ a4+t/<DGt\ZXFnbt?u1R!D+84p$PZl<TE>kY&*=JFl9&pcee6nw4*6C91ZFbVeZBH!bH5LZWaCI9j\j4
+qLM$& E6XBmh8KtR@?%ecZhH%Fy9iL/<u+E:6B/jw<1PlWCN8L\%KwNP!9>1Ki#NwPcqueL=4cNGQ4tDF#6^mY
D1huC& XtcS/byGje>bGn%6Ek&b54%:$WRq@>9M=@&GaiE<YXbH%Yldb$kB&p>CAXbpLy6GDycYF*Q+KNapcnay
*1a9*/ SwXT#FC&l+6SVS#K6hj/=I+Fm<yQ/GTF<H8/DeC4Ry/MK6IaXnG1$$uCnMYP^wi#1K^5#ZBhG@Md#$Nc
&:GSML c#mXu!%%$qBWIb==tEqMkLXtXG?mm?c*J&84Ww4SH9NRWBac4MK?8umhVSn4FBZ#l!:WdD$FcJ$m$WCW
6p5Bde 5NnHV$V914QRXPnX<!dHeAba@b9+4@F/*PL/<Ik6*=uu=di?BT&clYWVM8PBYXqYDJ$ZQk>a$=u9Lh:p
wcP4+p BZ>bZARh:aP#!MHct9M\\dmaTjK>EdLN54EnC#1&/E9n5m#=\&m/pFG*CR*?6EZQyTXl5FL15?J>6tdp
\cj1Li B95A!*T6LC4paZ%%8KiM4L\8DHXJ%nw&w#pa<WnBVGi!i&nKqL9&9^dn<>Y4jXicNA@#j/M>qeXRn==F
5iu8a! i?Y>1D$c>y6Fjh=lpqlcGbD^XR+%5qp$e>94?G^WcjwpdbHEa&:w6eDe@njYHKYVuYIhG=dGlb/hLBy^
w!4Gw# tWaKbT&ncnHcNE:DFJQwD**5Z^4Y*ZtEi4&M$ZI:TX^EdBG8JDyTj>Cq^Yll4A$&KuwMI$wYiG=h/>aC
aTT\uH p=I%i@m&qwS^E=:PD+bhbl$!NyyNW@hSm*BpPYc^F=d?hL9MVG!Em1FwZGETTnPK%n:yc<lDpkZcmD#n
Y^!XkB VnEc+=YEuehJVN6wct5<=ehKRZ$GbDS6\6I\WjHRY6%WQA$&VDyey/8&&bu%EBWSS!9LZM<uaaSX$Z8@
4BStu& jIYPqd>t6nnYn*C$uFd>X?6&5Gn8KmytC1h*NEh\4cI%5ZE1$hVS%EiBbuGFdlJ4kqiuFc8\K/:qSaw^
#e+6hP 4PHW6ij^DjXb6I@m6JHFP+@TTF?8Z/%^P%cZIXBl$$c!tDHYm^MXW&V^JyF5:V!JI%4^WdL$dV^@J+6H
LwaZ\u ?pc#$*&EV^acyPJ&$DB+M%%j<GHI19@1DcL4+iHnKDy8yc^SwXV\:hIR^T^/t&a^NLM?tWBbnA9:*Q=I
K9ba\q m4+lQa%dKKIT?nV5aVM*$D5ap#S1D@XR41Xju*\941%Kn^w6kuhaVIQG</^LLLN<tK4*Y*48J9bV4Wnh
XNVW?$ a\>S5Nqu9ljDc>FS#::@cK*PKww#SJbD9Nk4%j4lcIT>D88ZA4W6>YjmQFGY^IHtMIM?hHMZk@>w^aDS
EiQB/5 wH\>K8q/PX$T4d!JPqb>yENSW<d?QMYwSTaJEeARu@WI8nZI?XccLN4!E6eES1Miwk$aYhTTq*qLlJW?
599Tck iC#AAlVSWEZn1581&EW9?m8M^wSEe:#WFEt!hM*Lne1G+<BZtwZ/JuetYL<Gpch59WW*w^@d^PM9ah!9
iiVRL: N/9Ec$ue?w$M6GT>?#M8wQWJJY9Vh/LJ5V=kYPi%STN4*Ii%p<qYRqmKZ@*Z+u@1i@AK+4yBieF89wWT
8SyN?l C6>4aGPEE&?%m?9c+mMnFVp/P!@p@hIwa^MF5!!1ER^+lVHWV>p#Yp\#bAB<TIX96Gj@%R@nMhtwk?NP
1ZN&u@ JR#F<cdh5ER/nVhcFhM\ZnLK/EjVNTPjMA!=D&N*+6XkaVqeMW#=Dq69\=qjnH#a8Bw9Hyu@XK<?9Scn
<wa?G? cK9X?<YXS=HI<\%%^TC\5:D^LetmQ6tu&?Sew!hlhGp^G1XlQ+%Y<&Riqp8m58Y%X%PMm8!jL5@T8X!1
CRcq*R uHFmhW=@18uCBn*^p1i%6yqX/FlJuhc4bqGVhS16aE9ZnYKdD&^it^8TwV5^*nCmPhV\Q@H/GjW6w>w5
tCmkT8 n@EYm?6GeBK%%MV*jYl@5Smb4W:?EHqN@L9ua*W4^>yAEH?uPmpymS<^!ay^WMPV\9G\mjlXBZ?*/B8t
dId+Iu m<45pMNNmmFBXM^<*kL//hcG@EXVdGXu%bNc&?#JmnW@&&IPb?5#E6K%@+8HeL6LGQe!&VpZ<T9!:Q!=
STTX?I dKS#QK>*#ib><9>Q?S!qb4J+XpG$D!dY4?uV%?^NGGEEX/kXnmyR@tC#4nM:Gk:#B+t#=ke@ib^\FNPa
VL!1Y9 D%4*bQ&9IiacVkctT4Thce%V<6K*SIjw@IGi&Z4?$t4tw?eI#R:lbAlDtj@ke+duYZ8e!NM4l4#4t8>c
-A65iK 0004e5943d300110334 Page 65 of binaries2.zip
S@eSVX nK:S+>ujJLGHGSt95Vu<=DXuaY^#qpY:biPn<QT9\:Q/6mhdd!19L58Kj*\u<XHN%l<4naXi89a8tc@J
uep&p\ P8jY#9<5*6MT@Z:>HM@Yy%Y9@&$T%?5?Zcea4YkLFjHTN@ZE=$#@G9i<1ncTBW@=GLc:4QM=VQ@$19^$
CI#l@J 4RIy!=:WQKX@ldjlFV>hF4pYda5b@pRCyF+LqcSQ*$ue>?19IuDY@*@6:%Lb\=%Gim8KwTd4e$8<E6b@
H@/$$w upcuaBw<6PVya<TQE=Heu!>h&+pRNnnG&mcK<Wc/NF:%6uacF<Q#QmX5SKXapPnI\qnIyLEh+XR5^mNL
NPld$y Qj/bF4P$?FjwuQ^SQGZF&BAPS!<mbG\l4Q%@SPd\!pNCPL\Guh?$4q@V:K?e6?uV&WhbjAbGPmq:ak5@
a44$^6 $a*y?u%jBluZ*ldZynY5^*nVdC%@qeX!Ij*@y$@Z4p>Gu1*Jt?RQ55X4e>jjj>Slu1/@Y#?T&bNbMY8Y
p8VkK$ mS?>ha/u&dwWZH@F<jCuKQIhTXYi<?MNnPG\B5<5nejdJJ=L<RqNcdK?HDCN&+9mqHERYXa9EQ*i@mN$
VtH$Rm PQ4@&F<q$ZQ?+dh^im>/^LX:V$S>@J=Cm*Lm>cZl*SYn*$d@FS&#6dSm>ClQZtF<ZKJVid$>P1!InP>F
P8+Q#q Q+*8JY895Sn?y6Y/8L#<TJiLV*VnE::T:e9Lm&8=<I&4!?54ZC:^FVhG%<P4$Yk$HI+t>DpbV?k/G$?t
VEYpl> M%^t<yW@y#e#ZPnYtQ=1QB4TlS?CHqmin==aul*j?A:>@BK9k8@n6jCVD/@y?Wcn!Xk8>9m#&YR/+b5*
iH9j@u N#j#?h$hZij<=ab9LP@+54T4jhL9q9k4@ZQ/c:4kk^=uT1@/!<&WLun>5!<#85Wj@Mj+X@yVjkH<#9Gi
u?<Y!q /IBe!<G=8JbnhV&/w56\lL@AK/V@91Q@9iNuweieVjYC^=@J\<5V+DW9=*kc?ku>dlwh$LZ@qM8N95ad
bPuAIJ jkN+bVj$+%bLnl*l!cDK\SSpAi8XjBKpD1y<w*e!BLIEF4*$<ZR!tWc9Xd@SM<:+XiMPw\>\l6j$AFeC
=\C:Q8 Gy:&Ry:>w<B<ThDmJy>6hFeQ%VWj9mEj1QFpN1dH^!p$up$u?GLAAqqBCqnSuTX@KKy#A^a*=9\yj*:H
MjWqId 5QI^^!HC$RPePI:AF<hPkd*Dj<@^q@R8/X&Q>ZSqaQF=:eiJ*!9?kw<C@dQ?J\/<M?CGV!KF>S@q^MFL
1dDn&> qLQ6lwENB^Tj^yuwp\?^wew@cdY8eZV%$H:/KPnTBW!>9LId?y4%BiNNDEjMH#+n=b!eSIni#PV#Sn@+
TW5%ee /ipRVId<b9u6M:CjGEe<8>!Vp$6?emFutD<#<>YAuRDV5Z!bnQpk!Sp@X$#q=l&#lM>@A%P\bWI\5bZk
piT6#K #6e9nCy#>WdPVV@$i8dkdGDK$6NPJ4%PD?eeE@V/!5@<$SZi/&TI5^tC/&a8y^H>+^eYBZ+JlJ*4/*pC
>BS\<A :G\N&Nu$4*$/5EImp5M+nyjG%A8Sk5AV+yhiIZnLqL&?hLJiA%l:&Z!e^+11!N$%VEZCmhnC!R%54+d!
pZNLEV $C^\L?TeW4bikLu<e$A4&pBR9Ya^Vp@JV<imtCRe8D8bKGMbWd+!@$T5<YEC4Hj/#YV^p6q65Lwp@kJ5
AI*MFj RXLkT+?LP%MShjRuaBRjhH=Q+%/y&8#8h!BJYI4bPekTDT@ZqAbiDj<na#W%uPVy>EDh*QEjLiWQYan\
lLHhQ: u+y5t5b$uWcw54=VbQuRV&jk/@YFmpSI9p>Cp<549X^ADwK9q$EGB:+T4I#5%Mm15B1mhk4i1I/h5NDC
bZJaJ1 &e*/Yy=Zbi/F$jTVcH#lMC8EK#qRC86EGR6R^/Lnym1Itcd!^LMd\XlWwlKYLuetqjq&4GJX6H#BwYbC
<N?1p/ RSn#>RaT/I5Vht/!?GT@5X&8%y9$$imIIIJYDc>Y#5IJ<?qGuk+Qk9MpeM&p@A&jaC^l?I\VYGi#&Y\N
Eq%9p* %btdMhQwNy$dnC!jp=DDX\/4HEY=hTYm>^IYDt9D1/A*nD^Dq+4nmYtLGFKVlHM@8%pWC:J+>+I5Y$85
HcK!6@ +qY6\uTmu+lE94kT5?%/yKacA<6u$wVq5Pm+aD9hBPayCCIA:@TwLh&a+5N<J!1YiGmtp/k<eQVG?AG&
V!E?tE muB&/&q=>^8lY1?Y6$8:#Y/#&#<kcD8nwb#*hNyjnhV?5NjGE6!BlTRR\=I$PBPYheecaiemQca^Q+&\
a%?EmC M^ba$e>MSM=M9>4l9dl$KZ\N94L<I^X:@XT@k1/1Y%Ww#kC5cNYutM1BuB8\#LWStW<nQWu+PWY6jqI#
dNDNSD ?BN51W?\qPZ%<NP!GeJQKmy4Iwy%a6b+DK!a6dQI^BR6c5AKa?eG4j=K@*QKCydSuVJjnTIM4J9Fk??N
KVW5H/ S4%iL!Zd&/WtAd9jdjdBYmkbAH5X<ZZMFkeMJ\QYHqm5!?p51C!t\ZKy6l@nJC>lHLk=Mh:mZW?t\RC:
1*meNh eTPXeaZJ1/k1ZT>awiIZjQVFJDcDRI^+%1@nEb?Qkc:l4DPtmPCVq#nF!/D@+Qe<FFq<4Xa^5jTViDe5
yKVqcm m5YW\#jS4#lckm^PC@Y5/NHGRqimLb>aKm>WJNpJ=q4$LnJMlBRtnP?C4\Pb1*S!YVeVaM*lij&5Wcy*
LB\eIZ t@ZTNu&WIIkBc:@jd#dcHWF$yMiHV*9?##q4lLucNnhVWa^V%1<#l@XPVaB=yIyXCE@M%MJlHC9WRcdM
SHLjBk *KtEjtZiZLA8FcuINmn+Cu6J9hnakChpSekRhWb1NcqbF!^TPZ4#+Djm8QGyJ@@BFmV:jKaCQ4IbdL:5
/SiCI> ^TjV4\\4Y?EnX8ynMeDHLIih4^P&pPZEu^t5bmGd+*NuB4J=QG8\@1M^ZTZ\ni4acdBV9nCZ#*+5LQKE
F#!SSC =Z/Z?Jy:u56DDl<$eV*wH@V*/^&Fq9%69NcbGuZt@LJ@:Mc6i%FGmPXTqIPaVZ#RyucGmRKcGIQHLqDW
Vtdeq@ ESdLaC^!&L\PJc#cwMDT9Y$%+JY\1n6Ga#uC?9ytI9cEy!4u=CZiBR6TpPZ@9^:yTcZt4?qZmGFY5ma/
l$lMwk aweb!LJl4anmP%T8YJnBHy<15QNIGAiSHPIWh/J#A:Cm@W#@8dSWYy#69%\5FpVSiyik:hbL>@j=@V=A
<aD4&\ JXn:?P#V%*1nnbi1PkQi6ln4ELB#6X4bFw9$1&pNM>=hDQM:\*t4ESl&uGhnJm#4&au4Yn+ZSd?PnIhE
HpQbXC W8HHydD*Ty$ejLFap+A:ZPM4u=AYGNCnbtih&C6*\eS*aKFml/1^qdGjVB=j1l%%wja\A$8u$$n+PlLy
8<LaCP Ny/NJ^Fj%Z>tQKe*=u9i1P>#a</QC8Yq/aeq&<WYhJw#1uyPVL<<CdQMymh:?eX>4pwm8A9Sm+@h*cde
&taT5G BLDhA@yKyQ*R:QJLHaw>dF/ai:D5\p/j<QXGAlPt8Nd=!qRXjWyAM1JnBujmjJ&Ki#pV@Zwq+b>4eYkE
WA8b$4 XIFTXc5F^/:%#kn81#k=R!GN^ybW/C*uG8WS1TQGy15Y%qLMYAuA!eq!1X:YS\tNcG^SndkLiia4hYAl
/Q/*CS JyT6GqRen>TPE8QN9Z:B>!aKX1k\FtV9?EY!Y<6w*\T?V5ZXtc%#64u*5Ml6q+@c9cbk&h%*kH9+ikK?
tFCm/I Rla*i!KJ=bYJ8*AVQFkNP4F8uZ:S<%DhR4Q5QC\ly>SEaYXASRY^Te!*IbKuakJ<pSi:YmFRI1m^X4%T
NAjh$S YC@MZtXW%TVXA!!/a/m<tWWBY8d1$yp/X?>/L4cKB%dbpqXa#Tm?WB$4#JXw^WeNjiu==LCP%tBX1VGi
*CFVGH 4RYuJRTqy=9d/Dh!p4uqJLyY#4w:@WQ#aANXlZDh^<X&6Zd$:9CwVmD&DE>wX#KcwF!d?N+@&K<Qa%ku
HcWl5P M+*B#e&4$unqhM$#%8Muklk8^J*!hT1885LKQn6$LMIB+K#APk9&HR:\cnZp?BeAE$nbW4pMh6KXBy$e
9bCWq* XZN#YA1dj9Z\4B$8BqZel:t<bKaFY$@VYd<@PSt#6pRiAA@L*k:4&I<lbM!KRZ%u%c?5%$Y/KY5JbNXn
1MVHNZ a*Qek+*wET<%h>YPYn5Bq+118:%MII:Il*NpjFJadJi4:jdS+iFS&@l1dBXwRXbT4*X>ujD8=aYPR&LC
c^Yb4i w55c%yKL&$$*!wCI4&w6#XkkMcR#$WDmDWAW!$@NH?b*Vu^XaK<XYFG6F&:>T8k@/FiNIebY@IRjV:Y?
Y=batN SF<F$*CwBQQjjn6>jjK/RS?%c1%Y4>qH=/nq:4ME9V:?EXn+P8\#n^SaI!*DPyaIqIhpk4WbS!9tpS?t
naH$LD hy&FGIMp%8D\q^ANtP:9L^dXKlB6%\<4>K&4T6YAJZMa\JK4$&^!pt8Iq/tMFWhHLce:M=%aEI6Q=i:4
#hKi%m uVQYknp*$^naCcecBPKJ<lXWXwpTHF#\FjdL$K!mT<HYw$6PYdiGeaAq>DpT:cam#%+&B>Tb4y:<kwN&
>XNV>L <tb@u!C5%1yH=cPn\/M1Zitnm5>K4Xyyqh>X*6E^c+qAqpTQS5LEel1bAnC/e8wQ%9BIk%C^qcMZnXDM
aN%RCA #b8><Z!A^a1ZHu4!<%Ap<bib/Pub:q+8X!4SK*%*XP*Rc!@Z/pbX@6Iuk:l:$CMS*CjuB!VF1?#%>MRj
<c&9$L n#YR\MD^KiTyw!<e^I4mEqGiV8PIW$qGnmWKwZ:PYB?a\\GcCw\D!MSZ<!SF$$tmhT%wCE@Y:%^4=NMP
k1elt< 4&kQQu/T^FJj+8dPRV$:P&p$14X!>X*%pNA5H%WIYdyb1%dL>K*e1qc4S%Y/Y#5CnT8XT4u%#nI>DP8X
@alB+J l1Z>iWP/AWdVcC#*\:8d5lKjtw=%WJY*plCLqAd4&Lt=PpJajb!V9h%e9ySjdG!W1tW/Fh9Xe4qeX/L8
+e9#iA p^W5yGW*l!\u$jjDTdhS&6*up$:=!nGNiWkcYP+w#lZh/M5!#cD=Ep%9mPeBwV5&LcVmYMCPLI5^!&FI
a%1#5< +88lR5qSmCnV/wVXG^4$%^nm^LT&<MBQ@KC6Vp+I69IlI%m8qm5A5%!qd+hA8XyqWI?1LSC*CkK*1&&C
EhliDy 6%J:b<G9c<uXZcpeb5W?>HeG>R1jRkk:npW\j@5Ty\8nIKh1YDjh%%:$XJ*a/i^ph:iW!^G1>HqQ6uC>
keJ?!E Z1?W!?T@:5NqBcLkcyM>&GdViNRwFZa*Q&!P>Q!Ln=EFCY<56PXbhW<1#P%QJP+@HdNL\?G%!ZkNXVei
4pYA/$ a&S^k?V\JLkdC6:qhbSC>%TP/he4Bhd<DSh*wq%NWetb9$>EQc^WD&8H=W4=1A^5n\D^IYEMCyhdSN$!
BlQ$YY 5BdTC5mp^8k&RS9qq9^=whkuE=hEa:GdSl+tXw6yatFW6W6CXaIHKyT!Hm#&%!%PCH*d#^>5Qm#8N\nV
t9VNKe nZ9+PLX15%qN@yR4>XthE1BEYWcZWD&RuFX9b*Gjd*:w>\@1E#=I=8C4!:Be#mPu!p</Tc!dGNEWp@19
!ZYB6t TqbJh+V*HupFp%m@#mdk1?c/S>h^^9<1PDh54yy?Hbw+%I!b8I%?L5aPQpAqAEFY?kBjK%XC6aJd%TwB
CGJ$q5 Yn=mKG6H?NSd\tD/1B@XTTkV6Bec?teNwIy>GMieNK@EFJ=!PJGDM:PyPBkYPLWI+<*uKIM*q?!hJV#X
y5@*h= B%E*=GS*\S<dm@9:^YK:XD51d!M5ZM4uh=tnSFWI+n=L+^NAMD/y=?p<&D%k$:nb%eM8$aPyHcRw#ZAV
nddBlM =:@?eV&9ny?1u<XeuW&e41^W#e?Vb%ClIPyn6TJ%\EH+WTS>R>d@P1Ky/%eYl^KuXTjHaX&/YZqT4=Wl
uy=4Pc jm6AFl\6k/$5n!6q5y*KXduR@YwA6ccEJYq<XD>1M:a6DyZITYYYp+caJE$@EXhS5:L5+$&utlQY\Ktu
VqE&Yh lV%L1#k1Z#&#I\KS1&BtkFWE<McmBItCKQ<8G:<MK$el84ndd:+G8W/ci\6ChdHdq@DE\d+b:qIGeKQb
-A1hS6 00051dfda5b00110334 Page 66 of binaries2.zip
tLn4Mt 8tX$A5ZqB@M@%MFITF$e@4HKZd6G5C4B*N<t@i1Bu/GFH6cLZ1JmLQ+>/n9C\bWcFE=#*M*>LJ9Q#9cb
>H:S>n qnWGppR\jbJPLiMu>QYw\wdVEWH=D1mYVRn#N&I=\WqZZNy%86*TCBmjWSKcEAN+#LHl+WSC%YQN<G9S
T6pu\h p&ydTTCcMNbpkPXP=q=PIhWVh4#b8#\lc$pbT:1XZlYm@L85WMHXk^+pMG:&><@t<:PV@V!lT4A&D\+E
kYyS<9 %k?peaicwJ=Ma!e@ekLuN@E4M6%k/Xi84JlPw1mymYS*<>Tk$u!A<I^\lSCVp44SKDKSa61/le^=WA$+
&d+l8C cYy^wqbubBKR@W88DQkJjRyB#BwXF/la%1&p1e11Xe5%tE%XZI@\qilcc!6yRX8\X6IVX=Hq=Pj6cL!Y
BV=edD /yR*KPW^M<6JjQHmHI5B/Mih?a6SVHd8kul@Rj+NRL%jdG@Z&5%/cbFu4uaQ>mWRDL4&D%:Q6*::5jC\
/6+jKX aE&el^QLjDXBLLGdTamli>\lRA6WLVDH4<cAuZEReV*A^tYR+4qHASyQ$hIBIDq5&bXS+KSHk6eA66?Q
/Dea4p Ry$S=/DE=jcw>6qbk!AyM#@L5I51mm:M+LI1YVcGtdTHNTe1+Xu%n:4\6wHQiy6I&:umJK!W?a*NiabB
1qM1IZ DEH5V1*anlJ5G$jXIy\\6#Kk8TW:=VmKJ/9=m8CDuQ^aAppZ>+5T9!I!qP1R8j8e6$GI9\6m:y@>>9%H
</aQ6* cGHI/^!4%4=<cja+YY!=VJjEWt8kGm6E\=T6y5<+PAeF!/IuSqA!YB4$GD8FYWcJYR!?TyHkcCTqPhiS
5Qibh> PF+V!QIF^%Z=KpEJCZ&1c$a9=kTwHpKZ58Fdb8?G$C9DLC:#J<qmB4$tlIY:a$4YYA1mX65N$4F/IZqe
XlbWTI c%q8*YMmRNXlFRK#IJda#GTt$M=taqi8!?KkbbiYjSKTTKuKjtP*Ym&XT9X/1h11C:BE^G=VM*JmGlEu
t%QI#C d%+ZFkd4L8T!\&4Jawqil@CNP\=cZ+emuFCL+P4i!%ytMXGFylPNQcQRN^lu1tLH+K8aqB/FZ*Nik?eV
J#&jeP 1tK98M=wLMDPVL*Kc=$Q!F6>X%Wjyk^6CtnjtbFpF#cjkCbCFZT@^qK+Jn1&J5Rq^Tw/6q+u^ndc>Zc:
Gu8Fjm %qB^MhFKDeuq!HuJIRB&BiRhTlXFCMJ<$ZK$EKTa*%kS#J&ZFKu+P>9j&!Y1qqAN$Y9#1!yJkhwB=?KR
^iCJbZ b?WLteH:RQWi5Pa&?**?ITNiH@FBH=yHM4cI6hyPh=d19@E1MLFSqK+*p6ieV9ZNVCLuqe<aJ8^wE5\y
Km^Ilk 5SnlwSBj6jb#!Lw4%EwKl5GHDeB!AN=!bbJ!b1q&6>#cF/6Y6PlSDhKYYYw1X1R!w\wiC+^mAJ5p=68k
T5:Ra8 cE&I&lK/XwF88>*whLRRacnYQ6/aBGM%me%cXRY!P?6c?ce=!tAWc>y8dtXQh!^^G98d^FL?!KHKlX>u
T9qdq5 8XS15451mqWetaQb:wMa#YR\=TGhDjFtX/Ke>QJGG9GdVtKh6SS@=!/$Hh\>6ahX\a=naCitkk#aIeht
5IjTZ* JEA?X9Pb=DD@l%V%5t?/HlH?w*+hYy*S$E1dJCk^u&<NGt4W5wT6KVpQ+eT&&BIYW\t@JdFM*mD:5B1X
8hG/#p PHKd8M:jlc4!ma<&SDGR4ZWpt1lu1tT96WBhV&m6Q^&QVejPwuTHbD6uWZdHnXAYPD5RFjZhZcC/ue9q
MTQjkC /&R95WAtZGERhR*aD^<P?4P<p@W?L?WTWk$Dm$u#E^=G$Tn^#K4Lq*P48@IZwhEtX@Rcckl$FWhh1k9M
KJI<1Z L<D#YL^Nc5%aDp@ElSW9Num5w@<p4NjiKDQ#T99=@Q6iTbn*nmZ5WXp9XXlL%dJEtiSul%WS9&YY8l^E
J!u1XQ hEuMJuFh@NeGK%9V4\^89h86w%b*w1yLw$$YNhdCaw?$5a/Nc8Y61MDD:Hnqk$FDCLS%m6LSKpuePtDN
%n@yWL =ZM=qL\$&@5wWM8l1IqNJiH4@u:@JL?^&FDX8mppF4:8>#*VJH\TH!^IatZ5MpT?%pQYIa++DXH?eVCG
+K+@t@ ?Z&QPDk?WwW:tcnlSBjm/$Sb4W+5CI84/qK#uC/8%>Q1R:HFb6whMl?<L4F/bI8&ZBZW\FFmJ59qw:LR
JK<iT! GF+5i/!INnH8=YAQm%m8m^eL@hwAZ?qL4X:9AFY\61*IYqah\panE$da5Rji:A#YPn:X5!HjV8jnc*1i
h//F+P AS*H\i6>Mun4%SLy%Ec%qF9p!HFb%J66%DH6q8+Z?e&?A$i$HE>@lH<LN+ka8\tTE81R#<*tYEItE%EQ
K16Kb# b5b!wbQ4YNd1YnMpJXdcdBLK\nZiNJ6F:11iLGJpnFWWn$et1mV95%yNy*J$SG&l>HZ$NJaayiqGX4WY
DR/hFp %@tV8Nnd4aFmkFawi$nK6cYGL5Nea/>G96TR$$H59!d\BqTQLDTlVKY9uYydlVBBm+>iua=#w<El+cEC
!L4adX c#JJp=KS<cn%tjS%9>FwCtqDZw#5w^!Jk&ynwKmK4XTq=!NkCheT^DDH>@PqVRWP$B$$b!eqnVGT#:y:
<Sy!5I eGK@/DhQ^t:AwqdIM%BnLTV<Mk6>A=yLpw+EV\p9=*HeQ$J%bHEaBqb%$MV6dlXQmDiJd#TWwq++5SJ*
jKH4/D AwDI<c\XVMSXMFG$?idpbTpEnN\HXj&K6J\1$uK%BXQ=/ElJZSbV8Ib@Wpq5*p=h+p/mZc88aN8Mdb8p
ZcELmu ecQS/KuC$eTlMYQ55jHRnDA?ci!&&?*/mhR>1T\?&T8W18&ncw$pBG^h%11=HNqK@FV$$Y#Z>%Ew4CWS
pHtB*G 4%pK5!5#ISGMtCE$K@t5@d+FtbwuW<81nTchiw@6G^eqt6tbGYP6@NASXZ@4#wL5W/qYm?\tFqAVEXJ<
DqZaMd Y/Z^&PM!+C8:9ZkN&5e=al<%SCnYI+9i@/TNJ#n@Zm>!E6BX8=c@Hcwn$%KlnI?Kyt/&?TQHu@bSLpu\
q#5wWk /cliA/l%>tLd<1*8lCZ8%L9MIEK&C&RbXw>LDJ?EVWYyVZ9N9XIdD%b9cL<jmLD@Mq?1H4XXthhSY4ld
kb@Y5d !w6PXaFQV$4Q6e?E:WyBBMR\MdIuIqk$/+GDT4B1Y\M>i#hQK4pu^41F6FZVY@jeudX^*m&n<k%4>JS8
5t44V: P6G\!u/Hheku<6nTqnG55\ubVhQbJPnZ+hC:@eVn$ewu6=BNDI<pDIAE=TdBCq$w14ZF$DINwW<SDIa5
%PL4S/ b54CX\CabGS8=$4diXJp@LHNX%VPd?>5q>YBbXQ+CL$T:Rb:5B$^mHGp&@6e8\5Vcl?TmZPN%m#pe6nI
B^K&%l &>*QN*B8%HCP:G8F%?8>^@!&JI&PPB:h*5*9=wF1:n/Hb<E#%@jdVSdDY9ZC&4QjJ?kct8hlYH@8G/kH
p%W/E# #hhT<V8b:NiJ#ntEJpbD4<Ect+lV^5=nW<q/hEP=%W#>%$m6cKBybIRF58Pl8D8iiJ@Cd8KIwkHLRTiG
k=y4h^ huSq91^GmK*q/uwwLXee+Vnb9X<RFil<d:F?Fd1&PEba+$RecQmP/c1R=9PqjPtH$k?:yX*=KJH\&!Wn
4ICmB> FPD!q?$1^?&1BClM+cBjkZAZu@^FbCPSXlMSGppeS:qb8nV&hpnY6pF?jwR?D88QP+5FWIZ&F4yY+eyw
P&/:&m Xw:Wc<hqBAP:*$ZqIjQ%aLN*$66hTJwH*5*Bl@:BB@XuD<:tmG^NVnbL>@j*8h&i1WIVeMdb1ZWntP8<
mI%Yy> ZM/>V#e8!hHCeH6up8IIIZG6+tahc>F@\Lp^+HLi5hy9$nanu+DYM:Cic8jTCn/KiKwt8Y?qDy*9NcE5
6$4Yj% ^?^N9aK+qT14%G1bEAYpAHW*Z\KYnPptL9SSX+lLJdkbJJP*^bY6e/VJjB!T\CSKCXFaV9T=*?#TAh@j
j$4LXk F&lb#WkX\dku&Qd&/B!11+18k4L%S9>pN<@apS<FH^qTH$aj/Xpa\B8mZjYnY?<$Vd>KYXy*$5>L%JDJ
*cbKID ?5QQlPpHhYn*B=!6&!#B@dujbcqy5dCS6WhIn>mM9im=y=YmTJM*$E6X4uY4VeSLbbuL$5p/yJlqFy*R
CuCi+J VM^@>4>^&6bHBI^Rye6qdKP4PQ5cSShHGyMaV?4IT?XEE/y?>dwYPLFX+?8&amye#TGKE#=&h?6$Ad4%
/PAP=y #TaD#N!6%4aFZGbb&!$bEJZ5JwlIFa=k:Z+h9BX=%i9%/98RX:&hQG6Kbl+a!M#jRS<GXQeSk*wpwAJl
yeTk+C tG%\Zw?W4J$tyH:VDPI8l@^uQRpGR\a9j6n<<PFukbW84:j8=4?>*5&^nb^4e9TABcZTc8!#PLTu&Z9W
:I*#wu ya*##wNPYyw\p<a:Ll1&eLnTe#kc?<RA+i9Rw5S\aJ<hcF511&XS5DCDl<4M8MJJk+mYKy8RCCcjVk/J
NC?EM6 ^HZ4S/Jjc$ya@p:?A9RYNNi&ZeKH!F:AY!X5CXt!Tnid8@A*II%*!5=dE5LRh1D598m<h1nk^Thb4k&?
$L#XBt EMi:JE5I%Vd=8kRR/$1RqX=y8=4LXS5IhpAAN#nFC+?=RZ/#\6?w1*wXAiEFyTTHy=NNnT?Sh@MAXQ8p
ZCiLNh ZiuL\aijZ<@998>^!ycIuP>J+N&1yDWmyt/E^ZPmX4Y:MBJBe?wl*5RlR9b!#Ct&cS5<eaQ6M9iFPQj<
nAWGdF Z:#!\TdDmb$C=5VGjL&\nppPD\<uQcT9?MRZF%P!MDZu/=FEp4dl*kQT*QN6A#ak!4yWdybFAwP+#Td^
:p:a4X q6BFIkZWbZXdE?I%^Qjw5pX5Nhu^J@Sl6$pu*R/=t>%&8>P8B:Ij%V8T4D>TKe#1Y\^9?kHA4dhXujM@
%&>cF# heZVci9D>&ewnYEnGNASql>?yp<Ai@D/bQBnaTGw*t?W?tLpGKYGeat58n9YJtbl4*taaYJPnkP4X8DI
tJT@Wc wl%D=/w%RWleX*5B^9@qj&YXE=:XRcZVWAjXDK>DG=*&%!E>MP1%e@eMK^$ZXqLXtkN1aTj!Wp9dC+cW
/$6<bG LnCb^LH=W<VY11ALYLebRBlMpM6NEJjBqRe4eZAQW4nbdmANcl#15bq1:SVM+*19q<>9Nn@M?q$C66$&
DaCHki Jc&l!MaSj/5JWeFm5JbhujYINDP>!+Kau?8EWYWJDEG:i\C!M4Cpa<@P<k@!P$:ZeRPN%DaQ4Sp&6Hc\
19Kw1* pw&1%pM:kyLZy6PI4#%X8tw+jC^GwlYtnc!y^k8V^4Qbj@:j*qk<R\6m+L\PJci?Huh!8&p+IkQnZwI^
tAeI\q jH::yY+lCa+kwV:VRXXakYHp6P4ZE8P&DjkAdcpGbJ6M*CbW46nHJbHHjKDd?$$n$d/#FWh@9>uaZ##$
m!y68d ?@$QH@4>E\Dd>bAGwT6Y5iTH&1yj<dYFjBGkQY1aMt+*&Py8<BN%8@5jb5*A%j8N#RMk?kE!?MPHA*Lm
wi#Zp6 Xitm^t%@QNMpwqJK/VWKA#ItQu<y!l9/KB5%tmVebFEPmVSL!D<CqCZ^SPP/EpKhnj@4*<XQX4e*C9>L
<le:XX e5hcGY$$F+#lV8tiC@SI6>cX4eJa$BWyuTPY\IV1<?hP%j\&YW!5S$68?bba@wK64\le5wIJPRYZbjKt
LL\m@d kA8XC&^4JaNY1L19JjeH*FS5#Y&:8Z!ZRD*=\Ml&i\!5KFuF>InD#S!QcLD<4c5W=y6eu&F<FeP:n6Nq
9P5!yu P66E8HlDIwiLJlR4I$8ZA@4h^5I!AQp?BKDqtp\NZ18iHX165^ic^aX4AXTFXchWtb5naqk<F#>h^I%!
Yk9Rm8 B^u@<<@@F=uuERM4F6PV?LCd\=*6lcDKS1ZwI$t<ELV%I+5u$q<S1HB8/FJmP#n?kAp5ANM6NyFK&#CA
+iXcAH T++1Q5q<118/=ak<@dCtXySdVH$S^QbSL*Z:\qb<RlJ*SBVLqSW$t<bAYwSM9eZ$Bc1Nw*w:89AZKQID
WhtLPp $wV55*JGdmQ*A#i=$wXA@j8D@t^*\:N%G:6uWtKpFp6Rk#cWa&#BJ<>I*MThX%#*=>X#bnmFem+AP+^t
-A^KDc 000deff2af500110334 Page 67 of binaries2.zip
/<?$BN HilFDPIJq$JNy9@Dj!>Mu$a#iC!9M:wilkaQm!1&TRR44K!QwI=1dBCDCXXN9G*j=\^WMDXu+4ip>qI%
@SRAb6 kye8?CI/6M#iVhuk4i+mbhb5B6:!Z>Y1S618hIy*8bRZ+yI\:b+RaSXbX4HhlwY1BF9&bhq1k8dq1CYu
u<:SNB :/Z/WcnKyEXeC=i#t>pQiTE49NajEA*?th^YpeT9h@P8hSj=%^K1u+VSN$N&I1==KJ8NY\uB+8qcia+Q
eQb>G! Q4HKYCHhhPJbN\5PS>caJhk5bp@Q@n@@c/u<$SkXRqKI@a?8S!H*1wMKGNwc:KZ:BSSuXZRSu?JHBm4E
AuldLE &SF5aEb%P=@Db$:S>I>!Tj\dhqRJ%E$a9/SH/>ZhWyZFdaZSa<:!8WMmijPA1T8$bVP1!dL+AF$!jitW
TMEy#K ac:&<bWkQi6@PFFk/\*X4^1*My^b+5n>K6NZ!C\y\cbEw@idN#eum\&:wDyaw5H\ZH@?<Lw8Q=XR<Zh6
mp1Lnq BB$#Z$WSZ19NwpP9JK4ndRA&dPdG!=5F=yuP^BP#%tBX4&WaEhXHYR!>+uR!@V>iT\lTHN?J/YIiLMZ!
mj+Ea& iBSZE8>\S9IiCc^FXiq1F*n*hYnYp5LK*k*acl>m:Syb>abk6M9IAX&AK#>##lL!cnB6HnRQGF4/t^&D
GdjkY+ q16=yW8t&!NMmc*$=RQ#qRud/SK\4q<S+/DddA!D6BC@alD#u%TDKe^=w@y4I6CQC%PiBF%ha<GIM@*<
9R/=!= wdt=+GQCI4k\8I5GG4tHIZNC4!XDywc^qhWnadw&n&Bt#S&l5>4V!S^ubuh%FHN%yBGupaY#WGjKEenJ
!PZt1> LE18n//6%#tE?!GDP:q:jk5L$LZpTwm=CttGPki&kyHy\qXELS&kQiBF#FM<HXXBYYAWbXyu?:i8luXJ
:@&\uL 4%Z<M*+5$IK+nC&dWckq/$5SQwHIbMYZD*ylt=ma=\Fty&6D+p?mXFp&X?941yWa?*w?u@&+<K1Ind#X
EH\w@# IZL$<GB@X$pMYQh?R<licYdtmkLLmY9l4Vj:T?XjtM\WJ6pIZZ$$w1LDDm#4:HHpE45G6%K?Gjhhtie:
5HdyNT C:+PN$/!nw*CE%e6k=ZwT4C!+K4Z8J^BuH%&e=mq8d*Td1Qi/@c$j&bMN@ZTFbXcIyFd4SyhJZBaW9Da
4RT^qE 6>uEtRBYK4I5HTC#EY^5HwklXXi!M:KCK5Qca&Ch5i&iYp=6\%RRbt%c5@66<YyN6ZLEey<I?Qwqt:1T
bqyiLt 8<q#wYqj?Zw!%TV5QW4Hj=^L%?1NTW/JH/#H:Y#E4*TQTa\m/5CRKl*a!NQbVin+XAWdmy8GdnPNkmM:
WC1dtL H6p51^q\@YK\n1*i>F4My4ZC6h1CBe=#kyY\1*9Gk*M=4F=S9kL=&?n%R&$/m*$>4dy$8!juHjtYVicq
c4ya%6 /Fmqb$%+8>5WdPWQwGb4K1#4/5A&8XXmW+%paT$MJ4cblLAuwtH=Vy5+c=1%:t1&:byX9Nm1/6w/l/mI
=@C$Mi 4Q8D?h**\kPdSGmyY*AVB/jX8V^+j%i%KpQ?&1cCYMa$VA\e^wF&FGBHGqFL/#S>J&W/Nuymy8P+^qF4
k$KhAM @5n!4\FY6dLHWWWt<>WLcC#@MJTl1&\PK/!9AG6PVCaEli88Z9X:k=Aqt9a^y5T#bWPyAV$l^w=/QkZQ
=>5?jD 4Ldbl:Q>@X*?j+cZ?Kkb8q&Y!E*S8KY/qSZ959/FweWGMqeTNTXMSED&SR#*#HaT91wp:1F?y1%PnyyS
Mqu9=k Lydq9qJaI%Q6>886=jI:WFYuqR\tMd/%y&1ZYd#RhN&bV6me?:SqnR!NSp>dmeMIqFCWFE*@5qGdZpa=
p6^!LM utpWeY!Jhe$tPLaC:6kC@/mZRChKGJiqIcil?#kmmD89GNV:=+n&1uLXPK4GXMq94Vi%1T<8e/XHQNGu
^pDIH& :k*:uwiW#pE8KQ>6<JyXJ>6LIy/=DJ6nVw!jkKpc%$Q!\Jc4Wy1NlwljlyM%:Iua^NC9b^Kh/HanGc^W
PytVDA dim6V1l&XK/Tc1%@u>>6BaPJ?&/c4MeF&CdHFP?%bPKHM&%ptW69w+\LqIuVX%Eb6lYhZHuV9^WTVmjV
6SLa<G 6a4acBmNDRwSy$XCVnG1et@5ScKV!hV+P9WPAjuDK$:YYd!y^Sa\&<E=5bup&LKC%d4<hu%j@ilR#AM*
ZFa@AZ 1$>u&RtBP5KpK6!clA/Rt/qMd=*juJ$\6qClXRESn%11G:VN8mALwT!w$yFup&pV5!ad+&+*kyX9u1nl
iwaR4W lN9m:DRh!Tn?%FnV4$db=5uk:4jBT+unM&Q#M65H5!T+!DVQ1C=E6i=FM\c<N6RL4/LyHHa^?<p4YKct
aJNFAA b8N^AqP#jc!8TY!uwjXA4yqPaSw$>>QbmCAb=/$bwC6J/1mP4VG58Z8/=HIQ8d\\6cGMSdc4jhT8u>^<
M>!LP1 CWLDTq56w>EXBi9^Wb/NdmMZeJLV1?>*h$YF59%W*XX#YEV!yp4qp6Bc%G!>8hjlKE/HQheV5blPnL#>
LQWVAJ D&j8:LS:Zet/%aPpncndbu8ydd>E*?Q4knt5yF5ZJb&y^lPc!F9&euBpab5!!InV+nIVkk$hA>W1@*lX
@JnHk? kkjcS=L^uFkq>HReD>1eQwHXTwiHY5:%FFdJFa%WFI:@+*?$mdZ!9/cRQbbI/FdaAkbhe&\#TV%B6i:^
XK6>:b Jyki?&e&Y>+4^\nYLlKDSFYMS+GCqd1R5b=XPl=>8YTh^I:<XchW1wiQZSHQ1GtKR5YT:/Xj:bk+e<KC
%/6<M> 4Z^DJLGIaqc^ZapVh#tQc^m8/>hkB5<I%5WmlQIZ8#4>lcX\j*QZjpNpSaSJ51k/\&itdk:Z&#8!DKq<
FA=N>G P4Itm4Wm%mwy\1h&Qe/$m%8lG\WQKu\bc:YDlJ$JX^p@NbqbZbRW4\$%8*=>6TQT>*tPke*D^YqERhS1
TmM?%> l?#kh8Q5J9VMK/l>tPWu#FjW1jTG5J!/bBEQJ?8N9uh5SE:FH4??Pt1XT6WIYTVbNZBwRYBaW>Yc==eA
kG%1@u 4PLJ66NJQ#m^H<R1Jqk:ZiJ4+#>JX/%QJlt<V/@1S+5kMYQ4Q6aHlM%d>^\*=jT@#H^Cn#hj/DliYil\
C!GtwC LcMt$ZdQw<?$dNi%4DeHn1e/Ya%ulekaSJ$YIl*eEyc\54ZSE>JcV?Eae!<%hV5%RV#$*L4EuFw98QCh
%FT65k bVAHpiw16NkIbuPa:4@thRVSXE6qQ4$%ym8J+C=D!@NGjCEAKhm=KFkb8TEVVC+9Lw<RIw=y8<6BaTtw
$9KEcT IBhwy>1/%QwN<iA/nVELamc1IH^m\ELHp8eM$+uL$PwTytmajt%EyVd6iy@E#lu<Wt=Yl/qdb%n*yeLy
waDZl@ wMt>G%w/9NmhSnQ\q55+*5R/!BIwF%iZN6@#$8h$D*ZT=Nm#h&PhqGiVMcIbBJyVH$q&@apM6piSjM=p
KMkGBP S4m/jqY?DtP:/by$/\N<t?eeHGRydJ=4^:X5jYAq#Pw9nTcR\JQi5D9CBEkaVbDCtuka&<AA:dBeKq<u
ZY4Wt> &14JW&59n>=XLbtP+L9pBpT6Xq6H51pD5%X%8K4d^Q1N\aTKXiMJkqnDV5GbiWya?ua&t=*pH&A15YI%
m=Y>9D #Tw=*m+bVA@CaTq\cu4@?^15W+<GnK\N^tcM<iWKyL&/8ualGnYn<!CYme$KAZG6cJcLt/T8hGk=&AC4
nH*DJ+ #5TS=qDGNhK9q6t#KdI:L!B:YRl#hmcje^Kb=$1u@G</Qp\tdKyh*Ve^RZCC4V*?M8^y/&yw:bFy+t^C
AAZw8q Dutnk\^d?*V^1WZaqwKSJM?/Y&/>8@#$ma<Pn@XVd:BlmQa+RC!Y5K4aM\c&%?YK<9b?G!K*&a:eG+5i
LL?V\W w1y:W:8W<WtcqY81SAR*t/>@ZInQ!puajF<tB<?>iq@Hb$<6hmi6+4IB+@Lw5uXl%<=%?@1/jZZhqwM!
q+hei& /yLitw^Q^lQ?QJti#D:M/P6$elbcPCande:@K@y%Ema^+I!AHJ=cV:R$VF4kH><:bQ>!JCJuWqnn\k&J
9YydiG DLM=*BmEWZ=Tp#$WB<8A:I$/>QXcFC!W4hy6&GEm<$dt8tXI%tFh/DDmC!L6y/NY6XK!KBNB?/4%WWhk
XC@n=% e$?8VcRjDS61E9j6&+ikawY\pMV6SqPE5Vd<4NGXHQDb&c:udqm#>4lIYT8yZ8?=mR#Z=+MQljyHdWIQ
D+yk#A aqmm@8$S5L8/Q41<cMt<Xqtl\FQp41?ntSuimcGtd>lk$KhQIN+dT:?Q=NX6LEkR!GQjRSQ+cpM!ddmj
GpMT9T iq*R4iVbTDIXjC%bdyK:*Dk<ZH<6&:qpV1VW>a#GZVcYGF!Y^pPmc+h6y/:&JQN\PX%u\JY!ZDe!=FXa
4hV:4: P8#@+l%>$1XXSp1YncX*QQGWb=:!wbGpE:?=VyDEjPM55y$?jDkB5ATTPn5iKt=&%MZy%p@wBjZ#FwyA
Tn6RkI +Zi?#8WTmm41nnX8!NN<#1IyQVbdRPk1dp=9cLP#n//J4QSJy?tuw$8>$E@dhKGne5XuQ$t+E!I6S4*T
INDX1\ bhL*C>$S59VI@=@wyFR6VLdJ:X1V1Pq/=18Mi9bWpHt\X/MPklD=AC6J+XJeV5B<dR^5P=h9dB6#DKI:
ycFeZ5 FDTB:KnNF>c!umnp@TY!6+*q<Nn+iupSl9&@8#!<dB%i9t5h%14dS?<8hR<AV$?WcblcaMKTiP*nA@Q&
^!lMY* ^Qk1nI%cjB4wCHHCN8wp>J1:D/JaJiSdc51\h+X%wXWSp1@dn/hX&mBNHdAMYH8an$C\ZZW8&\cyZSSa
d#CikW l9Y1w:DCE?!VaYKk&uikQD\lS&IpXDWncB#Ht:SqZ#5=mK?YDNJ=mqDKI=&F1cn1S%/qeCQT4*BewXX+
::$Eee $MdWN4dlGSuXd8>/%P%i$/WuCqaaK\d=%Kj!Ru!bu\QDTXeljwRa9tlhHl/Sw9*a?6m/jHhBl$V&adGe
tkyZ=y nlbl5VhXF^F<w1:Pl\>>a/:GmitnYi<STS5l6TQucJPPH\4VLL!$\WQ<&%Im^<w%\E1aQ?!?DyQT:4Rh
Za?K5L A*KH?#nwKJCVN?4SY\X$dYPwA*9wuG%jAXmXbNC#p!/l!D\qQQp:$^h8a^@^ABGEp&GW$ypaahWk=Z$e
4EP@Qb c@Et/:>nPd!#RHAy4&^qaK*SnE5q/8lM*diS>SI>a!*NiySiKEAhhcBt4:8hulCY9S$yBNFqm8#*TbBt
pKq5%! #J8\4tZ%qiuZh=e6A4b%$Vy5ZRm\k4wDK>pu9PSi>\qlZeYKja\<ahe:<pDeB95?>Aq:w:R\n=YR!@E9
^uV1%9 t%J?V4DtN/K!mB@P\lm<8c\%pHH!#Nj^GS*LQk=>n%F4ZhG49&l>jIh*a%j/\XG4*Y1%P*KlI>TDw1C9
D%ZX>d 9bM8ZZ4>*5pJucaVeLl:R9\H5QSqcGMI4QHH1/a<JDpX8<pCC4wCST!uuWXP19RX%bLC/6W@!G46Y/^d
Qwb4tW kwlVt%XBhKX#5H5NNH8hh8?/i>WD6J$l^!nGQm:a?H1nKSDS4:w*>IkbT^4&/LD%:8n!5HX==C5:bPy$
^>*>DD GF?4N4F/PGJDjjkRXP!J&$=RtF4wwlZJ>SNCXVY4K6e<h*eSYRZXP5N1<am>iFKcNn!Tq:MqJ@kbHW5!
$+Qyb@ e:w>KE+Ai>VC=bC5?<QY+d5n8hAN@LnhPnJk8?$ib/n^CSi6^<pyZE:/9VH4NBLGHA9wTV8#!iKlhnl4
JGYZp4 G<>W?D1diTKaGTQIN1TWMQ>WDF6kGG:4Wj*E^9bL=b#\6e6SR>C$y>n&CN#iFa9mH9K\ZG9JAT@Z4^!a
NTG/BB 5LmEdC^q96Kdy!NA%*hAqpS^T#ihKc^c5KQa:uiDQT#P/$p*lBQFhBLCNn6NcS&wN=m5VS8G8FDNC5i1
iYWKY& !^Zw*h&>l+YdVQeQ?=lVQA<#6ZRGFJ?iu<?tCm5hBD1yCdCnn5B/GMQ/4mXwA%dldJ5I&%dCek$CCC8+
*9HEVk cqGCcGFm:#DW4*wMj1IVItZ@FjT445jX8VB1QHi$@<%l*Tc/X4&=nbM=:jy4ut5TB9uy<q++N5CVL6h6
-A#FlZ 000eb4a435a00110334 Page 68 of binaries2.zip
<:I<G* PtuJMtDihpkkE?RE4E/>%<AEB^Ku$95qC*XamZ=5phl6jV1pk*CII@C8%jwaEjand:*$AZAmmRH1B$jY
XK4juH CH8m\RqV5j6w8&q#8&Y:CeuFp$5*8Nkh9N^6hKX8nj9&TlaNbtV#*?@taZjLna>hp8$FSJMQpJ\uI?Ck
&%F$Kn 5BKAn8elL9IJCkQdhlYw\uZe:&C^^*/ZQwY+ZYY\ZWb!AVZGw=EqiMe5nMe&Sy*py8uZ5RYeSqy56cNl
R5Z?\P CC+?R@$bKwDN&qBVtNMi66N$bqFSSBiIql%aTS$Y\9lC?kQkppDG!^1PhIwGb?yE9?K5pDWP9MV5$wFq
@>JdB= SQpMJ>Pa>P8:C>*Ck6u@$1M:G641q$a*p5TYX^eXi/cMJYCJ4pm^\nuh=!=iFd@I#t^5=Llyn<ncad4t
jR9:PR R*pVZX+P+6&m&9/G&XY!TPcMKQIBBTGEc=6^JS%cI@R1l*\=+p84nM8:I/X6C^Wu:R:RdiN\%Z96jbT=
bMMuwi >*B6Eu9*I&l:!H*CTJE&@bEEC<AJY+aujw=tEKc&P+y64S*6dFSa/W+y6%&!#mj^aN9%&h^LBGVLn?!q
PyVktn S6#\mylKykBR^i5F58A5G<dDuwc/heK6BBKq8%4mE4!NG/mKtRFXXDpT&lK\+kHJJqGJ^6qMKR^kh:NJ
@dFiR/ VPIQXui1*k:bXn$+PLCHREbw%yLyXalm?Pn+SaMh%&=>ESIA>Q5jj?M6m9FGaJ9/5VYj@+da<uRClRkE
F#JGV8 BNb&>alRbBqejqhtiM99ePWBTBWbN6hyNDkp$MA/\>+?QZ&Z!N9hy$eBkiqLwC!E<XBVu#cNYb4%hMMd
Dd$R5# ?#t!TWhYLt9J<dASaN%tcDHM1PSJpCP8pWeJy8<$uZyGuYQ<%#&\qE@ADn+bXu1j^Nh4uG5>lSX:T#Z\
IajPPD D\hc@QlLZetBRPIqRK&?I%ldFVw&kQXRhi<uNal>nnm9aGta?GXwQ!m\KwlQAtH*TR\*?ymKw/d89VSN
^whAq$ AXX$=VFl&%IXaey%a@FM^1R6%?cp&i\ANy1tH?CbKK#%DqwlYmAu#?1XT%t9hAG5GN4AdR!Ni5%b$&k&
JC8e86 8D\cA?h:VFy<Ee*LCbT^FnwNNdink\&%:\h<qY!PBwlbDZhKEX$BLS1TNi@c>8Kk=m!518Y>LekVnmau
lN#Le! mD@&&tLp!cjjJ5LCh6JFqLED1*aVl:q5D!EI&+Iq@K=Yd6WPIdAPn<^!\wLa!HK!p9j^bJ@lP@QwMJuC
>luR?\ Zdih%Cb8e5ClmXi<K^&44Fp^nqT4\SGN\Gl\4a1AkF=5=L@dpQc:iJaYlQCe&Ey$Qb8h#KBh/imV=mFk
SthlHQ &>XYnchFXkSb@yT4I5&k%p4+X18Z11nKdjmq9p>mR#=bQuiDBVXB+F%d+TW!P:VPK+6L#EJXE8n5hM&L
<tmKjS ckXh<>8qcpj1SMRTSwHEne6lZcMtblM>L!T\k6pP\JJk9t=LAI1Buj4?VJ#1I5TH$K?&C4bq>uC6ZKNQ
yue9TM +88:R>G9q%kR?%GBHjpCcZwHJ>&I5I#4l#Zdmh%ad5?a5MEp1CJBp<99I1#a:QFZmPG<BSV^?@#ikLtJ
45J6N& RYp/<u+=6=@e#Z<nG?1M?H1mWykiw%N9NcS+y%LibmBj$jh6*N+8+!6@XGSYGaw^c@Zcd1%iL^Gp8<Vb
BnZQpd Zj//1eD8%\F5^#ndXZNJS$Q/wDLhV*e#>dY569&<I:ATqtw$=aT8u9\kKe^$9aqkNY6+VKBh>bTjbBDW
myNQ6D THjW/FbdEIa%\Rub5Zyc>CmikNX>9!SjQ:LXC@?X?EyHBclY*>Xa$\ynL!R*EC*Yph&\p$qQLiGVIItb
k*4H8P 5Xw/IYZG>V+p%pq?\:!dBSJH*PuK>iC5jhXy=SkVP/&&BWZ&F8wa+cYkPy<Q+L8inRqaP9D:dZIIG&k#
<pL?wG 4JZKqSJn?M4EL>&1dPM4L69q$9bPcchW1tpS>S=ZAi*X4cciWY+\b?61H+?/t98W!SXD4j#W&bCR\:=!
SNu>!R bid%M!Yh&mL1qSDNq#CXS!N9%9=>NqQ%1y9/JNlNnnQ=4MC$eWTR<wZM\b11&Y/HDPI&=*Tp\Ewm^KET
4p@=%B ^9V4JeM1quC4!4BYCFu!A!@beqL>imu>t:=At8M6#dET>5RJK/pAEe/VQwqbutVdE=<Xk/P6k1*N@X^%
mnqVKb $c\cWtVh8^>tRhlMNDKXbJpHC?H=GeF/NqY&N41hB6ImLGWBK@GWRN^?ljc#BF>iJdmB4@SVNC\S51Wh
kEnY+C 9ySKi:6:8@T=k+dD9dy\F\D9$\NL?IJ4nEblNGVam!9:%d$1W8hRp/5kZp$?L>*IkBbhea^yqi8w<dXu
ZAJl<T m!@u64/HaaWQPYThimS4n11!+/yYP^KbLJ+PTwyX!Y5qDMeSEbiI@FhG>wnqXG&dq&Ih1w4qLh&jQ9L?
<5Y6/4 hc+W89JKpQEEp9n5R<m@@n&ANcN+mtciE:#q@X%BNRjH9N95%8P/<&dJw+deQZk\C\8yhCKQLltq!&?k
!NPmL@ /#@M#<=tH$=PEEekC+hl+Q4J&uc%9M&AJ4kA&%jd^Y*Ge%6?ReAC&l*6bN1SL:5qAuc96A8R//^&/SMt
ijFPkC 51naL9!hmdja/Z^I&Wm8jQXS1AS:8/STtD9l<6/SZBP/Tp>L6j=lKmp&5+cq6BK%ctRbpZXQbGXVAFMR
nESm$y CSK/h>V1mDQdqeJE5amj<BW:B5RpI6APL=t96X1qXCNyB5yC^X/RXj^ST\?$yMT:RJt\J^aeFq#QyMPb
nLmWwK j*kAc+u%#m:4%Q\Qj$NPn:aMTJ<#cL8d*=DMnjA%*>hStd/=&Nc$E&Mlk8i@*R^t5:QJYS>TtN!TDqB6
WW^#AF aQDJVlZ+ET&LkQCXDYKRG\#1C=t*<aw?T/WZyb$%bE6:?Eyj/45CdL9bW#iYDNB?XPp@%8YLE>c9N6HL
ydh#=? =^C#$XVK@%DK&@kYnG^q=%XL8^ByPyuNdD$md/uXytwA$:$tmX6q&XtBEY@I%6ymHI</!EqJGbbcVyJb
9%mDXi =@!4:ybEjJmI&Vw/yQ<9:%SK4&w:bjCiw@?T1@9w4w/bVc^jy:PVJ5MyITbI+4<ut*na^R\<nb4PYLQt
Ik<:=u T45H@R<HjVJLFFpy8NtHa4XpHcT$4Z//MYVJIN/Ce9%jiZRA<ZXG6nB>+QuI&>^uyXlHi=GPplN8=lnb
SALw9p X*<Tw8c&u>NQ@9RC!L:K9TKN6=%@lTFIP*tS!A\9pGZT%ubb&eJB/+kuP?/NhNVeiKI4lZV4h/8q!S#l
?DAJ4S K@%FD/1$>ENiaSY/=1WclW%lNHp*/ldc9hM6L^^lyqMG/y#WK*G56k&P:hSiEe5ALbAF4MVaaahe5AlY
V#NHA& Nb#+6In<X>KpF?>c4Yyqy$bu<5+&pH$H>=/I@FG*VX=a!eFwcP9M$MnR%FCVEQj9/RL^i?dFt<*FIy<H
eWL&Fj Ad4NA:RwE=\%HX@St#T6Lp$1lBh:$*k#=h\@@qjBqLn/&\^C?P\DpSZS*Q&&\W4wdP<w1N5A>DuQlZ!X
tR<+bn I#TjA<+@+TA@X***m1SnKdiV!+P&id+WT9ph\dc$C%PbKK6<bVh&PPpKYWi&wtTt?nWaVYIRq<\aLkqZ
\&<n>/ 6@M!\yAd>%t#+4MuiuEyb6MZVS#kKdwn/NEcmEyKa+jP9%e\>cAmc^\4/@T8PPlp6VA*KwkqpAnCcy18
>4%EWq >bFhuDKSul/Dnp<JJ\k=5S>dmE$kRA^5Jdp8\<iG65*<SGPI@DGh@u*@wH?t4Y1+NAlVLL@l!pyy+8y!
uR1Ybw Slpd=8yiMeGTPN<Mc*l5++Qk1X>@?#^kXM@P+PIRZjj4VT+t+b=Rbt8PiWpa96l?<ceZ#:j@BC#y@uPi
T*+ByN 1@Im>\K=$Bh/#iiBLF%&/ELA$p%A8<jGFJ$9nYbd++1\W6TDHai%P8LuTDZn%Nw+P9SC<lkB1Z#Nd+P9
NV*+wF &?B4VjW4FC&tDL4*K4BPbYkdPVFp>^JH\VA/ZRqXwL6VkRZX1ue+XM\cX1MnW/tXJ!W6TWK8Y?MEK%FT
dy#85X 4GH/@&$GFkL>pIH>1Cya/wS5?j4I%!P@N5?%@&FK1J%=R?tZ&Y^*E+$>Vi9c\4AKd5/VWX1qSem#EtH#
M8BS&a 9dDNWNyV\?!Y*%kEE%5HLIVJbuy>kyk>D\k4%WFZGER9RFjR6MnW@BPlS%k?%%p=hP8=AMwjBe/!9Mnu
FR1By5 CuuYl<=bnJGWSmaCXuMA$Ginp^GQ^NX=/VPX\:wZY#j9DHi*e#LCpPtKp!*9hPY^KS^6c84\>?XhZAI#
iEnpCu u4AR:4Zd4R1ha1>i:Y\ZTGQ5CCkeCY%B^^Jl4#tH!MD1A@GCkwu1%+<e&9@aR5/DPE4@Z>mtS>6=XWZa
GKcj<> mYR^tW/!lb$$MRie4GDV6mQQtqNqdQQpdBb6MeP&/M$DVDZp*hqe=kLN&lZ6%M$dWVq8tN@6VZ*npLTu
/ZnQjI C4L$=S>t<*@+VFd\=:M#SdZ@8p@tclN5JXl4P1&X?j4Q6y<VwALtm?hTY9VQCM%@^4eaaMP&wAqTpyw9
ANbeh+ /FwReAqc/Fu^h:y%nSb#EhX+=E/P#k/im6*p^ePn:k:l?ANk#jQ4pWtG&%1A##P6wGSQyqMLN1pau8tK
CaijEM In1D!HY6+W!qX%VIFR1F@K5C8EcaqMu%aY?Ha+uSCt>Z5PMS%&X!#IGLJI=cqiwP<bWindlj\pMR4JJa
wDByhc %=wJThX=*?FEFq!>:p<J%heE/5$5#G*RVVyuwqWQiJ+:GW5>>RccPc%%+Wc=?<Z8CeVR#Ej!!LSK8yJZ
q/Gi8Z M+AEJm6+\KBCBl?euQDpW^#=/m:BK41X6Pu&C^dBRFKaTuC?iJ:VC>%/wckGcPu#SW=bY+BIL5t+WA=S
!%un@b :HP58A99\=c8cDtnDytB*eT^aeY:D5%NjQ%B?F4TeS@dJec$!tPQ&6ZGiKcJGI+P//Rk/Fe!mYA%qiu>
B^IZwX FAnW*CP>6lj$&mCJZ<FCdqWSV&!nRtdwuw/$etklDQV4J#GImdD59bIw!^hipc*+mp/Ph$hIBnBlYSJH
eZJd*\ GS&Pa6pG!bQ>%/@QdLBK6PXQlmJ>+P:b#h$<:?LXBS/:pYdF4Z&9%jcPKF?GS8<jPuZGtJIljQKcqC9J
QFp/9: <9$/G<Pql9k1&!TFAc^A1PS$nn=j/Fj8ciPYmt?i<bd<6%:bh6%BwIKA*c?*Ld6DE1+u4RBYY<+9FZ^F
VidR>^ 9p=*Yk?F4mYPB<6<NJ*=IZ!6Cq*:Fp/RC6E9%w<!+cBE8$PG<A=PNWK$WQlG*\lmM1DIPK:YYwk:nV4e
Ei&&p$ a1jhX!H!L+W\%^eTVTI6C8?XaGZ&9/J#hwiEPjl/>EqN=k6b?n8!IZY&RQ4t=1@6c:#SNZY5LW>?YPTd
t9+TQt J:Ijm\eJqlatjqHwj=@9^5QHb::?kj:@H&aAhedGEw6kwQ1/D^tM$cwIIyDSBP$1SqPP4CRA1AVXY\6m
#@e9tN :YL^H^dQ/T6Z*m?+Vl6jFuqHX!mdb#WL\=m#AjXtS:Q5p!k1IjQS^#QlK>NXZu^D4caj5DytY$aZ1u4q
uaFR/? FWW!kIHEML&>8cuZL>d\DueKEj?nYupHYD+?L8mTj*^+AbFMJt&bHS=aV8%8S*iQwZnNW86nnqjB$iH5
aR:%w$ /mjpuN?St@N1G&hG@wXw/bbaV5JwV1%:#eVRdP!bn/cL>#Zc1Pcd1dY@#KT%Cc1wq\<bPb:WPwpYN5+t
5jbiYc aXpL6=T9kZyAq>=Bh^?#pNFp8%6aQFcb44q9n+6Zm=jQkG4l=a@ju:$p1j6aKNC6\uNkYZl<!N$9ZlaY
PWW#D= ^NnCZwGSjZ!E<jV!ebF@LD!C45<Ki@@V*mPd^iVJR5Q81$p</w>/a=/GQ^:Hi=cJ4/JBbGA^\%4CqL8<
q6TC9X #F\!MX#XIZVXi4XV:hu1ajF!bHmWi4?\tpm:E4$Yn+?=^$Zl+h9Dm+hHE5p+i^F@+pK6Vw@uVRRQF1Yt
/$$BH^ !K\QSd<mBae+MAR^KT1B6TBcYk*m%mi6ud@&q5Qk\Nq!uKeD/1K^k>:d^L$up?:DImS9/LI*npcQV:#Q
-AKtL? 0003908947c00110334 Page 69 of binaries2.zip
w$kP94 dVd:MJ8i$bi#1dk&bAPVZ8*9a+\W<1YA6Xd+<StP&/96$4MjF:tZd>?A56@juK>YY\Vt5?>9#%ju#>BG
8\\JC8 eW@+*6@uun%:jL=+ed@%nKV\+69iH5V^%6/*^dQ9L*NpGt?>&cK@b?Ny6/TBa5pAnLy1NXp^w1=IkS#Y
M8ka4^ RpT<6=JaVd9=pw>GW@W1/<SMDMhi#p%w6$LG9N$l^&Rd5PaZn\?Q*^+K*^+iZ#!RTH=BDk>5ama5Tw16
>D%$p% bpJT5F!lPYbkL=m\MJ\Pn$kyp/?WK:\k&=A+V#+5pnyeS+\R<aWTXnwlwF>%WXM$TQKGF>HNw\Z1ahdK
wW^^6Z VDyMt?4aePeN9J9/$*Y488nClm&hVXm^\4Mlk/u=Gyn8N#edVenJ*d&*d!Si6Q*>i/E\YD$uF?j=%4p1
B<K/DQ &d*de^dF#=@jL>=5:T&i9^!<jWuwLt/*ulXi:n%:?\!5Qj??&H9:F4XI?h56X4eIR*HwCaJacqL:ZFb<
VdhNBc Mk1Lt/X91>Wci?=%PNud=9uh8&ci1>t$Lhb\DdP%!hqyV1cmZ4WB\?dcwCJDR5P9hq:pH:?S@CZGM11Q
8l/I>A n\@jTBRVa\uaI\X&KMmKRR^BLH#F<BS&VlH:b<Nyy$SuSd:\wyCnM/MKaA<ST?Va9@L%&kbKRkVa@8m\
^M65PK &e@tNt8>ta?w$*XJ5uDdWucp^S4h6c&eQ5/R&>8+J?4D4M?^aNB%u=ucSIpDRCWj=?Z*:+n9EnGijZ@&
E%!Y5! bt8Hy@X89aG>??L=<&hd@^LN^I698iiF::jjH^jj#&?j<V!A%juY%6d6:!?la=h9j1TVk5j9LN@AJtaX
B5/m=> !^wY\Da+!e/TiK!LIeJcGdGHnc=DwT9L+bm8yi&1:lLnEe\5lth4KZWbL<RhX6%P6XdKE$u#*%m@E5AR
&m>9=H ^a@=d^DF$LG%KljG>FRdnq$R*$!=YapLmDqXS@L&/F&6R1eD<VWQu/u$mnV$8%cLk<RjQ*EG*8m1M=F<
%MN5w$ G/iX11!6F=T6=iy!j^HGu8SX5cJJ:n+9dp>aVn?PB1!4kn&bumBtTE#69&c%&t^5Eq5=yhbAtQ::5$Xl
bnVFE# RaI+@@%<c@phZ5:#=&?iwWPe?Qy5m&=>k*1>@*/?&61:j:6c9m%kl6J1NXn<99!iY:#ILbdLe<l1iLM4
\E6KW9 ?95H>ueIYhY\VXT#cTy&$ue^4B8EwX>%I5SpCK8yyENpFXZn1#bFa9bYR<6ZPKh<w?&iM/tWGDFh!/<K
Xi!lj8 SNF9EMV=S$lmkyY\JX#Iu&NuB=X5I?Q4VDNDQQlNT9/qYkL%EtIQF\lYRnWHQ^kc?6&FFE%\aaYFt<aV
Z=wj5a D*9j?E:45KuShnTKHYYESc\+H:itq=4h@d1Ne:ATpuFaaVI=G=@%y!hV=8yJ<+VXcl$LKMGnQZJDh8w:
np44AV i&?&9n>:BuQ+?=J$/l/l8b*d&9w#/W5T\M>I*u:@paj>d6$PX6<Ld<+L!&eR^H>ijX<MkCaS>ubF@@tT
Y:n#KR dlaYK@4:9WeJQ<GJ4dGCJe8JQ6l1Gp%P^tw<YX#CKmYI^\lC<N/VZXY9phpp?lYm8D/J9J!=YMM/\KCH
&b!>*9 XA=mEm<iC4CaCE$mLQm/IHRjZ=BFC<PHKNeSbHHeSMF!bAIiB*jweMZ@JiLAyGKJ4#9py*@L\@mClpdI
b:Y/ly CS%bH:%LS+eS?GumG/%q:=86jq@i&jyNA*a/qYuSXyt&&PZGnZ1<8##cX<W#t<@GM?a1RquR1j6%:BQb
4YaN+& </W^SI8Zd\tWY^#E6:iD:jM*n>9p$t\S^LjQe6>ID6N9#<q4ZSVidN&ju:@bG6\VwHCc/h8d6\ZA8qkT
PKqIkk 1?p8&ltZ6&Su9T!\m6$y+bpAdB6<lbcFm6WliyMkl!YynqFwS6hhX/<q^%ZG=wG9#jGc>/4SaallWc<p
CF*D9% N\8EJV!ed@mEtu&E>jTN=Mk4Blb^+l=dVpNV5HP6DS?QBhlQDm#H45BZiMMI@yhdAm!CVk15yNY6judt
:We$h& Kj@quT*aqlwpSVtMdV:dF>W1yVAdC?!+c1LIM\J&FFR5Aj6lMn$bw=L$yEePK:lKu#nWmM99eI$DHjw*
:uQaFn Y%L<5Q*t:e96b%9jIam*j6hw^LQ#LhKq?H\&iLP+Z/=ICC?@Q!I&ed9%uc!tBiul^i**l>#k#TQc!qhd
CSJGV9 iVceClcikL^9N44:*B8A\ASai#IiilTF=dDMH^l*TlG5JaPXE+k%&YB@BD*LBA9i1^T5!bTMHq9DyXjR
S6weSe ywAVu:CeFkZejjlG66Q&#5/4e4YGPHH9c6T%\k&^mGe!a&J+#Z*LABaq\$klEKy=euVkLCG&kTR5%^lj
J4By9N jJVM?nCML#K4/Y/8&<GpDqT&$T?Zc#9C#9Il9wVSY*WwT%R*%V*kP6IqW$E8u+!b46%?X&Bqy8+SV*<w
Yctp&: :TwV>6+?K!!?kS!\l:@jDpkPQ^<<Y*\n6Wy!?B#/FdMtB?jj:??Z!#eppM>@JLH<:b/I@P!ia^PEhPE6
\a*^jT eVd@Dj4%ERyYniJhhuacVi!VpPKJjk?X/JPJ&\FpD=8$GRHA*Rnap59l5GL*1Fa*S$K:QZ$@ALi=h5l1
SwLD5y iqZIQ#BVYj+?jtMhC\a@Alw!EuiRm?%\Wpj!+DM4I6cI$#Y*N5QS8Vl19c6Xtc<9AC6HJmR\RYV?^H/8
AE\pE/ dH$ji9$5N?uy4pbFM<AK1+CDu*n64@NTC*:9M=1pNSJF+SMQ%p^GajGh6m+TZ:6mB6e*6SCJ:Jph9^An
A1!typ !SDGY4c6<:jp68bidV@Q@W+/>@8QSMw*$JjQ!LMBei<Z6/8*>@epmMqCF55yl?EQm>Z=>:i*=##Xa\X6
:@uy/8 Zek9<5LaHdk/tBHd%F+iFAiVI#8SAJuY4XpIejVZ^DAGQY>9a^WJKXk5@YL%cpH@8:tuZ4tA1w%aW*Wu
6=PIYM >\k:mbAqSQP+qaMj?+%e&t<TKmahmiKJ*6Bn^CcIPcZDNaqetpc5jHhWbw8+\GtEHcS$!mk@9bBiTcu=
lSn!8F 9@b^PTKG=:=aY:m/9NN>#F\:KD4&=Mej*LhliGYTSLQB*?w>$Xc&:VyEKBlXdwdC*=JEJAM%9/6yeJ%*
!!!J6a @^%G##tmmPh$+?9&hm:*mk&l%i@E%#i+ej6uw891uEn:bpX<JSjuZ&IP?@u1h=/YSdnCdmJ<H?Vt:j@E
=eT?#= 8RCCXwJPTNj6a<Mc^=%P8tmp=8I8htCJ4!bk&mcG#S:&n&&i#M5DQ/9X:qkY19PJ:^Yt!Q:%SA\VBA8J
bqQDaa M^FXCXM\q?!wS\+<9TkW<kI5+5VI4+6GuEwweTbnn$dGX@SG6q4qGqqmJYI5jh*i+WAmAj8SucEL:bY$
8A51FA ^iCV5W=^E^ShA5?Z9yTVSjGQL%Y6en<Xn\F9!/+q&?BmdQWKV9:5n+Y6@S+CEYw9:bTRebFQD8Q8mMVn
<+Z@!I jE=8Y?wmNB9*#?Cw\tcCPe#D%?@%K*@J<d^CPDweJF+k1jNmpX@Rb&/l/d6TuuQ5dBS4/</I1&Kka&YZ
mM44H8 MhuDKtyGnXkMq&V:mY=W+IWM88#4^KITwYSN^jARZk:S>WYi#TVEtd/^Vj#AN+m<D+?pcq>I?L:KcS$=
t$mByY Z8dB*tlSw5&ERYL>I/4>Z=ZwWX@JPRE@TaGXL6kLDmVc?F*nK/@!p@%kiKY/KE!lHd\MSj=cE+=lA=&/
tIaKM* hEe&pJQ6iRluKFN@XT+V4D$!tyw>n9AV4D5@qLl<W<L#?i*<V1+En&^d9AwydKK9E96HT6*RDKA14J\F
ZG<<\S ILy?E&nb*!G?=uucKCuaSWG<YGbkubS5$\LFcH$ia5TIbD:AX=&<!W6RN6jyYwWq5I&\BI?R46dcpZw%
SemaI* 5+qVZP!:EkXJ9icJuw\y<bb<X!J6+S6dVcSnZ<C\lTktt:nNTb&S6%<6q!1IySbGaY&>c$G&E:I\8llY
%M9Kyk NGJBEJN/qWIal*W!mc%l44/K64:^QiA>iQAGblu&LWPc\FXyb<cNZylHPNIX/il4:W?pplVXLuW>Y4Ku
ctM<#D Le?JeKSjCFd51yDCyqhe45aJXp/<p6t:aGVq^JJ\!H%Ah5Gk<nC$F#tl/aIunuLwmb?GpAXnPdG#*?&A
4E9Amq 5/^q+i:$^&I*/Vbe%K5FMa#6andEt>jc%Ht6IPA%<>Z/ZuXRG4yF88T<quh!eGqa8dKu5+DXBN4Cu!Yk
Ii8MRB Chyekb!hTlZS^NFRC^!tc<W\uK9nESM<j/BT4TCynu1cG6uDJJ8QyFAGIYK#l/ZC$b\\:aTTSly9jiPQ
8j$dWT :\<QG==wqe<TX$&A1#%iypX56Yp:8tZP%5PhDPtC/Y$IHPI6L4=>C=@TY$4wd8hKL%D#y!YqJI8jd*NG
H6&9#A @VuHC??@Ad?HR1H\<8ZLA9tENlSKwMYWb:che6>kRlNL/P@^ZI9FA>hRTI+heThR6t5>5llZAIEC8<uG
E^*>En *4tZW>?F/GXVtPtKFYP<?ydu$VdFpaCdM*i#TeR\iuJ16XKB4CR&l6Zbwd59BPD<a+FXLReW1#WCX1cI
?Y:L!+ IJnA5Z<4ZpPI&EbMIJaIaLiqY1yW4hS1/MX1eW$m%^AnVVjWktS%e#m/hHjuRYLA?w>Tp:Tu@bDc\5#F
#5FPpN L8nEcuS=B^KV66t*hVW!c=Lu/alRJm<HdXW>>FH8FN:<&>M6@*n=#ScS=QK9GFlWn$LBFqE^\TIalCY5
/QH/\H FwYZbBLn<k#Zq!<j9!&M5Xmk<E%tnT=?jKaj?MNun>>E^*JApb%qq5Z$!u61QGF8DF^H\qZE<KnP8Jwe
Zjy*8\ L6q!5X$5LPJ\E*awH%X:a&$!Z&4Rj&wNn5mw6/4d4\w5l4<^QR8mY<FVtMn$nY^m$lJI:bRS@8>y/+YX
RPltB5 t+wLm?V/lXTdw5myhak1%S%YYWVZek9?K:ht5dVG>G8ba1V/qe?/yRd:/YF9hQEtIZ5*?EF6aNG5C*bc
ACcMhI WbuIwQI$mZw9VFD&we\/XKW@AX@SXaXEc@:qt<HY%wA8y:k<I/Ey>R+9bMjmC?X4DmX4j?K!y8eE&:iH
!5@%8S q>?@Q\8Zb:m*>:KkY#F5mRI^hmHIK:LjZ\L4l%^B&t#k^uL*V4QSM@5J!8PEZ4Qa\>mk%MD8nE%5awZ<
AQL5=c Xc5Ji=VLbX:DYlN#8PiPlAj>^W%T=*YuIKB1*9YBCdwRAmQD@pm@KHCKHJ$h#FiLEe%>HAEuhZTcZk86
kCd\\W X!B5Da!6wicj\^L\aC<qLCZ>PVy=&$bYKEQnyZ=$+:X*Shy+q^LD!mZlQKkJR$Rtad&W:t?WmYWwV8mQ
u!qwSA $H?DcX/N*j^L$QVZ6%8@M%@@bYFlym^n!?YqhHt?@e?+m%nMaKL1>/ejnP!#q+>1I!<Y1p<Zd:+@m$/A
WSJhDj q>>+68\DW=dnVq\YR=LD8y:HLI4:LIhSHVQ1Rik!Z$WPd<8mDDGHbbeXC?Q8#PK=#FebaRD%nJ=Zw6X&
5D@SS! Hn+N5ZIB<@idYFDI/SCpC/a8y*jI5m%X+MQ!MCK^mK%/dV#SKSNet*cB8X\6LuNC!1BecXY=q<Q!hGIP
<&H\Vt 1=5nTYW6dJ=HT^4%<8QDl5><pe>hYWDZ+!btu9+#up!mpii/b5:G*QWtkm5&Chj*Tm@jDu+h+QN*pQd:
<!??K+ k<LlSYk98FaZjJW!6Z>Gc9Lq>#h994@=np@>+l<@A6tF/Xk<%y99MdQ*DQGC:ElGXjG8>M8TMNcCJ+#e
EjEJ\q t:AeSl<A%G6yp#eu<:/+M4EZDC/lb$l&Z4DqNAtTVwJ^F96D6^W=4\WX\w?FBe#l^$iE@RqSmPECwp+F
Q>:Mp$ cN<H%D:Al!XZy/i%K^JN+Hq/E!%jp#ETl=@Im#&1AXy$@FScKDN>%:1+WGBqPJhPNllH=4AZ96n*9aeN
DmKaPt u^W6Kb\/:\d8<Z!RjbdFXy9y%>Ha%6:n%Bu&yBihDtS>6@D!DeGJn<HY4%6d*\6PNJ5w!Wa\t<G=*H>A
PR#yiT NXQl&b8*hHunZ@WDaBQKQ\bk?iQ6G8:MX*pG6ww=1Mm=RRTL6bcNNMX+#HaVM8J6*lcHhieM1!#cbjXc
-A@K+k 0009ad767a900110334 Page 70 of binaries2.zip
LTu!BD Kqi4wq:l/&nQ1pcdd1c!$^$^j*b!T9pCalI\*qm@LtA?IVdMpR4&b/F$H<ph&N+yp\@dE/dNMAIVD/4X
1#Nm?& c>LPAh\\:IhLlt8%h>X*XTtZiEj&<L9LAK\MMdLcaZY8=@Q%!4Y#H<J+J9tTN^ueqep9>FX11YiVebS<
LM:CCX >SbViy5u$w#i:JL4YmW=@P9Y:$VY*/FpB><jFbHu\qmyPwTHw@X1BK5l8aW9d><K9uLlZ#$48GjL8K+S
G!5=w: ?phFG::5N&E5?n9&yCWL6ceeLJ/e5H:q&RRN!GFiNcZ/XZdAkdtXdit=F4/1?#4ZWjc!5a8\+aV/>k=K
:/BjS9 JJmiTPbA<wy:R#?FSM:lBym:KCAbT#+5bn/GcH$aNDHp8VA5mbF6=RbJJ19B&lLRNh+p@Zqem^l*$eej
>%t<C$ 4^?5KMJnl##+pCY\DQVyA6d^NNT@BFlHX5#JHa4:cIP5:?Z**kBQkQw:Ij!tIDTVnYD*L+TtYwTI&5N9
Fce\94 BeL#:hadZPTL$9cNWje6AT6in*\b9H&n!IK=#:+6HNt<&5WR^R#4j4QDBSRR^PC4SEBq8TPd\*Xb5w6q
ZV<WK5 NqkNB:NJN&6Zn@cqQ6hLl/hcAnQ5>bBSJ?eXSC*A:u%kN=cJC\IDdEnu^\X4&5hed8hXFc:P1D5TutuM
9m%l5X !RcHe>?/DB5+9PSPuZiewAP!q??PEQPZXk=#Z:WYn<9Mq!!FdWWnQnc>&qBTellI!uHDu8\D=uDECc1y
k*MJ8H J>1l:ZW\R%*JPEH%u/lZXL#5qkypN@&K#%@bKH=VYGny5Xm$SN9udAR9uw9JXNnciuQK5L:hG4#bCyeA
Gt@t!E NH$Y#JPq#><D=AV\5+j:naD5A#^bCSj9KdJC&LH\qb&#SlZSJq:1CAFe+W&Q5tX58?^LtK9%!Zm>laQD
9CTP>E EtnDJQXcLbM%DGdTmeq!q:%YF5CEJ<L?lC?MKqnIyHq*!HLmill^acPGTT/HRbuV^chQ$kl:KJn!q+6*
I=ck*= tM#<:8LCG*S584\pe/QyR\46&i6hCi=\5cFMAYEy*G9Kyubb%u:Cmja^%^QQItAqtwYSwGQMbeI5BS+P
y1KiLq pH>=8pXYE&6Zk9d6+:$b6Qi<Gw\9#:?SLL:QQd?HdkYCy\Vi/S6kT>jB&+FlcllDFJ9qSCiL<lnMj9aw
bR:TKJ G>XeGE9ppl6pAY!H@hl?d>\u9k:beEL1l9Q?YHeBLCGET=n+8%$8X%5aMXT6HXY:P9*Pcp!@cB@h1NhD
\T&uEA PVlb\$SMw19WTkBV^qFEeB=MjjnG<cke+p/qGkHL\:IuGuZYIQGaC@>b\%=!iy%:tV<hKX&=4%utZ%we
T\kIAR $h8+bn4S?M=Y+>J4QQqlEReP>dD5/qnlJ5epCNq>Lw\b#&^t4&W\^:/<yw>PapS*EByt99+KS+jb8uZ?
9Hp#J? 61Bm*kIM9JytwiZ<m<hu:Pm!qaYQW*#:jR8/PeB/?lcmYMEn9lLtlL&Kc<J%\/KQDG#?MRjCIpdBEayP
TMpN44 W>45XL@TReTcBQAXW@SLLIc4#Nh/Xh^Zq5LXYueT1mX$yakEEuyZE9NHIy*%c+:4t%m=Tp!S$CT\aSm#
$85\CE 9W!@L4#cKcPAVjp/m$e=ncR8$dN^LRaXaYEmK$F<&j1w/9hC1tAtdqcH/WME/Sh/6Q=DNNDTnpk?9/uS
6<WhPC CIpLp!n8#*T^mVYm/e+aHttFklI/j@5eqhnubSI:?V%S4X9uY*@bIt?uIB5IN^aLm^#hM/n+59m&^*?1
@KLN48 6nQPlQQd=ZJ=9q1iA%qEN9BJku14<MnLZRlcE6j?<ja6A^+pMZ^bX4Ne>NTRSn5R>wV$/$kYu5F5+5XD
WK%:hk JIh4XhlN5IX=MiC451JKH=QRmm#VLqpdnqEWl?dIuV^RjiA\$!QL*AJ4XldP$LwFmPIZEuX/#BZw1dkh
$#\h/T h8mEuajaBE<&@Snm@=!MQZy*Kepe4X8:8Lm$ekpbRV/Ny6S\?>#N=5NC+<Hm<n?w>K44PkcY^bDCGH?m
$T!Pm$ pylDplb9+5A#^!hP5A!I=VAcIXt@EqV\ZpG>N+@*NyM/AH69%=jj&eBm5V$A68jLe^lClc*dJeyL6@:6
=&RTWP /hbdE5QEYydE@Mt@aPpN&=q\%VXNju=1GpDKml9%ulKY?M1nLu8R\\R5t<T!8JQZASJq!!TH+iTRJD+1
$tb+JK YS*uZPPIWm*Bp&uJdm1>ImSjeMt\bGBB$B^:N>C+n*b>bQ%K\P/WJik$tyky?*VWlPZ4/Q8:C:KZ!D4G
BHwi?5 9K:L%miiBu@JE=^G/8Xapp+4JaY88&6MqdqW4JL1*c:W9HVqi5b>P:Ktuyih?QyEDIWh<%=MnAL8hV6e
8\kM1M %4>Z!8<BKPI1wjS%c?96!<ZmG#*VN#tH:8<>Cajk+VQ+R\k:@p4@R8k8X+@t#=\9d\u1AS/GA=JdL^eK
\+\FWn :P*kncnj6/TX*<KB^j9+FqQ&lSlQ8#95:jVk^jcH<F>^5nh+ni1t<JZ%c\*4HY5pqdiJ8#Yqc=XZ>$S&
5tuD<l p<+6S5KN*NhKKR<^Y?CIMPBq\?tBnYKRF5aVuB#<uq!h^@!LuT1CVmJG+!A^S@?HLIl=plPtEGMtQCd?
Mu:SFF K%$=K/D%VYFTNebA&C^P:knLS@yImcy=K>:mddQ:t?%>XEX@$dah:w*WA6!^tCAk:Au1Vhn:d>SX9#Kn
K/GR== 99KZ\b6u#@b?yM?>b*59+c+IX?Zn=S5Y\4?#LCaId=j*5w5TBH>#K#<hcAdlZ^dW4n+*8w4H?*%9:>uL
>l&>VW Qd1<yMj@Jw^h5CR8qCT:W?e+5jCX=DDA%FZa8@Bc!:!/^9k1kln/Xh9XhLc54<RpYD6eae1%ct\q=d>^
yXNpW6 yIt%Lch&qKM9pF%HFT1Z^ySi%XA&Mi!NJ?PwdGw18RT$/q!c\L*E1H?&k&Z&lHb^wI&D^dB6iJNpn5J/
=+NK@p Iwk?QGnct#WS8E1GSNP&HhZJdiu89>c5w<=qtLEpnuc!!RT5L95=dA*ZT9quAPM4aPW9yGjD6&h:yCa6
&/lDqQ 5Z1@kNEplCY!@4=%i&5VW4t//m*ViCAmuc!4q<4$=SabW8:5K441<@:+55CBT/S<<$4aiw>Hmwn@P8S5
MP4b8A VuY*1Z+P\5Jq4HP5<4w\>uMPYSSZ%Z&XCP!eX#:IBmAAm=!//Xiyk5qLeDn@\A^GJ8iB@Xn&j>AE<K1E
Eq%Bpw kln6ey/G8kubpwRKN4ce+K5mdeiElV#?cDPIbV%T!PXMk!!l%*dAtD/a<BYt5u$wK??cKwLl/k#R**Gn
G!<ZDE VV8!+!Tc#<D#B@5mlkE56mQCd9w1MZ>B$^HG*h864S<LC\P&<H*4@DQ?cHDPyD^@Jq\qa6MH^#eAPI\1
+p1k^= @Q/qmll/pNNjldBdY\18^Ka+E9Z!WZXLkaeCeV1Y\+u59>IS^KJGdLm8!?1*11+SA&ib4=DEbYVXuc>#
e4d/*1 1%w#aH8hXuWHqlL+mm>pPu$VH$iVPa@1#nLYn\XP$TI&\i*4X85\n*%a6wtq%5qHVqmn?phX8?dtmE%>
c@8$9M E&KeN%@P<5#WH?lD5w>IdQC8+GbV\+hhE<ZN5:mDp1*m1Ly$cA5!?!1GEWapPV#aW1w11AL5%4ueQceD
6><<1X D@n8WTu<qj@GQ&Yy:Q*d4&Ikp:@Ddw@aXq5@QwwL8@!XQX/&u6/ITH=LH1?Gq4?@?bEP8ETLWcYIFECd
5n%u@: +<V\Z<imZ&Ej%qpPE%N4=Y1hhY+X@t9FA$+?9F*+K59LJ1bjc>5F^A5lkBhR4R>5JaG8Bcdy\!NdWWkN
WeMVij FBC<iCCLGLGJ:uXZY:B5PA\pMhj?w&u!+yN/P?nF?1TDJV=y8wjX/%Dc6ci#/X4MyE?R$8jj:Q+Ny=Y4
wSLNc9 1PJ4/8JaZ&Eqjp=*j/Bq5#ypnLnK\atyXSF#<Q>E+9/aHk?:miV\%*NHp+FnTLjt?6M*Q*/:=\/>:%5B
>uHqQ1 hJdT9Dj&j8MYLlJ$/?>dK1a=^QG>INGHqTnhN\P+Q&<GHIXpRe#II4=IB=K6aklmVBZbZ?M4jBw5yN?W
Ci1j?C >c9X5ucwa&Ra<^Y!8ML/%RwTpDDSchBeQI^c^J*6S<t/=l<BwZw%+P6C4iSHV5XCFDNj!aY66qAQk!%i
E*:jyT eTY^NMMPLj+95P4m9p?ZTqYt5jCXy&nG4nWA&mPm@5*j@M$tjVRSH>ZJY$%HhJ>F<D=:4&jTBSB&hE:C
K&5BNm #n>iHpNC8D?WMGKQ\^Kq\l:^dH=8VFR?E1cE%1%e*8#JYwD9>M9dRPR6huYJ4$9Bt:BXAT%?$B6PDZ&D
G+tMjW HGc?tlVtaNYYJk\pew^icBVHqHbEECNK*IZ@m4$1P>G+5RdeuDI:4*YX\<ntpIa6X@5//eQ+P4W>pMNi
4%$Yca y>&8:BS!*!RR9PC\ITIRD$#a^\Jwt6hcm5ZDw/V#RFkT^Jl\PuHhLY8n4PVWnPJQMy*kI%<@c5DC16b$
$1=4p> !Ybei9Xq>tF*X$BqaMQwR>G5?%%uLB6R9*G4uc$Vt9FIb6$pJqZ@9CBP=DB&<DSKP*tT\!DtPil=8@Zd
H6@Hqk LY9Xe@q!Lni?9+Ra@ndAdjyDJi*dd#KalHAXDj&Z4h<@S+VhpyVja9u:Kai$PF:^hp6eHw$b9^ZC:uE4
Ln>pjm ADjHTmbY=LBM>MhpXNc9t*Zbtq9XF4w/b8iYmcyCYii4%c$b5L*lCAHmAthiH^FNjM^LMwj%K#hjQY1T
GXKB8y HV@pVC!luh6BuXQuY6L4E:h:hCG5LeBTwc6DJXRIZ@mkY8P49nTNNp$E$aQ@Mb4W%DRe?$*HXGC&:w+9
wK1wZV M%<<w!9m^k45BD8KFXn^e&A*kbd<=h\?\\X*uu&DkSS?AHDQ9@QPLGL!8Tqt@9l>C/Rh@Qd4+CWulSck
Cm=Hcb 5:m$RFbb!+^>+=L+=VeS^D9A5F:9RBK4@#4c1R6jiYpnMntX1t&%Kw8nW\bn1^!j%!=JdY1iTaW66%#6
M<VC5M dLQwjiC&X<TC8T*ukihMTIDm+aFLmdp8By1&5L%VPi4\BG\bZD8NB@=#%!V4YJ*>LnNkQnKDQ<weQR+n
kAhI+5 n5Weuw4byKje&iaBBuDJB+@jEh<G\*nw$n*wS6D8#:W*X9h4/kCamV8^eHSRa+JK@$:V@b\IYPHyXk\5
1tTn:< jd=>CW%/1\#ipl9jieehAd/<FWH<>djjIa&J5<JZNal9SVm4QW\cqw$tF5S9VSL@?CnFdAk/RSA:Z$jn
u?HGy4 L9R4Fq$nMMF<lb?DDny#aEZF%4\m\Z$JTc#4HJn1V1=AZp/Bw^Lw6pJdVy=6aMnqQFe*TRpF9B^Ew\wI
DJ&bwK VZVcI?P4VK/a#<NkQh=ljeFJ8+?/:I4*lB15%^whutppLISMBNYj/eJnt6y%nlw!1D$mLIPK?\lR:A?p
%pR@u9 eCdA!9H@1Y*X=i+eDp5RaVH=6MF<XZq:#k4%jHt:SFD\QCBLu#?T9H$<Z+Q:>49+4w8N=baK+6?X5XII
C1<%hH >@6LKWye\cAm89:K6H*:K#@d\P56JP%iRC$d/%iih>wV99I\eiL4d6%YZK5kX5JYMiP/iqR=1l/Y1!Fq
ZA?k>% w49Ehhik>NIhXZd!*#kdq>j!jttBjj\tyeP\leuni4VKatJ\@kXb^C&5VSyGa*<CaYW!QB6Qq<=TN=18
tI<:*@ LtZw=hkG!N%EWj@bl$$M*@4=+MQQABc4JP8R9/JZ5W!KJ@%d<<d*1IHT=&QKCKDk\*auJ^b81yjk9/y+
8VEn9P uiQLewqGt6ZTpSWCj*<p9m:ZaN*/ZyCbt9jL<@M68@\PQ58*6*5LpeP@Y@JuC#udLZq+YMkK4Aym>5=*
6abCkC 8D!^wZ:PtM5qCE!^KM\INq#4%W4KjIX/4jY%4ZF8*iw*Yn?M#H1:Xu&%k*\PJ>ejZ4BHW&Dd1TAyH5lp
HM@8^K #eX!k^%mmc>KtCVC&^VFy4%=586Zq8ye/?JWDmyK1Mq4t$a&R%Mdl&!XSJMkBcwjj5a\&t+hjSyhB:db
t6naSe :=yqnK>94CF4htQAV1c#MHSdC#jHPk<eI=1I4$F9ut<6@!i!aB?j$bFjtuLF==8Z5I>W:=/LIKcjeZJk
-Alemp 00049df839c00110334 Page 71 of binaries2.zip
VWR/b? A*<eQpB*@nl@>p$/48D$@C:JQVKeut&Rpj^!8Sy59Z%:/w#hk!Dt:k:i1dFQ@wZ=Pa#4yqpZZFi18Nba
1pimY= D4?4qw<1=eN1R^5qwn+P>uR\pI5euSwC^A8&m^/@GX*FhpJKF1bWV54?YSBD:d:I9!LL1ePq@<MRMkw:
\J@k&l hTc&#Q1C=^L4Xd:bM86^GMqut=4kl=+eAFQA?nNGF&LDFdS1u^8>AY9jRKY94=iY*RQ9ddwV?:Ccn<X!
T#p?CJ %lPW\jVk96b*hpt@GkGZ=@Qde>:/?&*nhuY8Q&QGp1>/j*??FFD%:>@?KF8Y:qjla^ujQM>Le:NGnWpI
ThMiCd @%5m/W5J?#>dIu<ZjB*P/9A$6t4D>K854JMl4T/H/#Fj!?YW&HwEd/jYta=>!I>Nq=DSmF\Jk?bZ/NiH
$%JZ@4 @KNWC^NnF&I=FVkjC=JC*Y4uM@E+Z>nb4l%%yNDJ/mcE5Jymq%qh/Nc+9FydiH#JQ^^b%5B$e$n=>\<A
jZqm+R /aeQ@+5S6w%EFp\tiDq>/W^tWa!5?9^Pl^V\/FMj\cW?4MYh^q\?*PNbiV9@>%>n+*h4d$QcMbBTZc4G
Anp48? Qd?>jaaEPSN&/XdXM$uqjF9<B@Sc/Y%N%KCJk@85Hpm@Iyk<?FXE<b8Cb1bY=&@FhBINT$iSq#B\NR#Y
=MM9Qk FHXXDw@Y=dAaV4w&551CtCX^8hyVH#NK/QBwSG\88=L&HGuHIR@%lRRSWjEmFeVjJHT5e>nwP#!kd@qZ
i:9=j: dDu^inQhE^LpkY*Baujum6Vyli&i9?aIIp<!>dZiN/HBlN*Rp<$QDP#Qj<?VVZ9hhy9+&thpmcCR^F%N
dJ^Z/d \SK8k/WNiJ4y$n+q4A6mYV#Hkj>>MnBN9!LNSpDid8%yChZdJZlJQ\Jy6</jEY4jX$9Y61=kZ&=I^Mp!
Rl5enX 4XwQu98Yk>8TY&C/bH+BZe1YFH5/>E>T<QH5>5%YbD1S?+GC:L%1yF>q?!<EdnMG6ld#qT!uw*KLKF66
&a<E+p YH#aF\/1j5Xw^J/$=:DdYlD%?jD6RZ5qH:twtJ%bbNnbqH4B*YM5mN5!HH:h@DE9h5\#<ukhPR6pZK/8
:TMPyS =cINHDLEXQ=Q\lI+J$+P@l=<bZSlPWERp!ZMP4ddXW>u*=cuL^%at!pmR^b$X+t1YLVuTEcH:iEqw\e4
=lDePW ?Qd<=d$Gq:cA<9KYNi#6+D6B64hp:9Kj5y&MPY6iMHPQ^m44y$Q%5e!1LiTY5JCS4tXp9^ipRGD^:J!#
Ia&ua$ QGa/FScc18KF+l*X4\DY?M1C8MFYeFYeYh^M!+jM%9Jl\$4?uK<*6tpb</TQ11<KBa+bIqT++C:aQC9e
*bII4w F\?mX%E=RVC@!JXK$B<9$F>Z&1=^Ab9$P5:CJAEhqmw/F1YuI=/6JkDLb=n?HnY1&+1R/iRA!#l?@u5q
L1\h/P dLjZd5MTQ8k^bR<kmV$B&>*@nS6qhjTEBJ:+awPRiG@!CRIVQT%\a9%/#ywW!LIeJtm@u#P5lDkEM8uZ
NX4DXW Si/iDCVDZ^R9myWE%I*:^:%ui+>Y+$?ELZBp5JDQTa*MaI9hY5cXpWW<<a%FJ*REEH89HEj55H=qA:=n
NWLL5! \bmGSaZh$cuZ!8WM5B/S>hTaVmLD=5:=!t5+PqK/>8&^wMXyn>J$XWD8:9Edn$8EdCbA1>XZbMW@eM!a
=AbCn$ BDEGV56!4tm:&b*9T=KyJLI$mjFpVEea@/+Xc%MNRaccNabp*AT5H*nA9^PYYE1\w4c:i?L&MDdYDi/Y
A!J:t% PyHNJLHHuY#GPtE:=BEEHZb$ZnJKkJBb8Miw*m??d\t56$9G<Nq>:69#4hW=K%&NHy@jdppJPBJ=lYh\
^mF&G^ l*=<?jBNm@p=#4BDJF!hw#Ib!V5\>5&nN5!?ZR5/@jmIQ?b\E<HclK&m>j/n:m:wihCMLYIM>RK^\he!
:P4SYS #GFY5DQ9c%=1<EDH\VBl1>!89wBS@Ml&Wq:#4l!daNM+>\wb?pYPj+GMRKG\LYMJdQdHXCY^G5Y!/*LC
QD@k>! t^uEt*ZCDuWH^$^VhNd+c5P8y@5Hj\?1@kPbVl?\/c4LlP&4<WRA>=6N>*V&6/Sh!!Y^/%mLPep&i*m\
\RN!Xm PDJ:iellMw\kne>9q&?akS8Q#>=C+wwFDNZ:dIGlmC9&j8k*T=\E?QJ5:!ZP:Jh:#>Tei4bZ?Cc#ck5<
4NdL<Z N/?R9?W!m6?%YiSbkSZ+6#%P6L>>M^BpZ*:n\l+baT8dMWT@npehm=*Y#TC8XK96bnCIChLDMkj?b&E/
KVk:=I +y&15Tt*@9bIA4R1Je^ck!dF/CcAX=C<1:aAd=NXjXnhbmYL$qP8NPaKeY!9<&WP4C66lwW1YcpL=JaN
4$$^iV DJT+G9u5h\<l*6^JXMKtI5@GJ$SYtE:kLiHbI*MS\B:\Vpuw%^/LaApuD4SdT+e:jVFkhZabW%c*CnK\
DRdZeb lYhKX:mhhQQHRkEw9RXLMRb9KiJ+B!:Le@JiAD?nim9t%6a68mDj+K=c%Phw9TKVI+i6DcX<juu:K$LG
M/P:HE A:KKTe&?iWqQWHn=VPwuBlbN*H9pKjFXFMJ$YL%i!S!C$dnHeqn=&qDC5wJ6p\%%tFcAKSIAQc/^NZ6X
9+=Y<X l+X#aAI4%h96Gw<NieEF@ycS!\6V/jX8X+<PTZQuRGiGGyqc#ImyXa:ali$bTtJ#8!miTc=MlmDKWqDh
<^S@4P lGTdKY$w+6JcPGTydj<AjCXamdBA5\%J9C<Yea?BdYy$ku:/&5dF&AV11Rew8QpHbIWpQpGnJFuEyV$a
@B=t81 S/^Id$YXL6p<AmuQ6^lXAueL5>>#L@aIYBZMnL6EyNl!*6wT?=qJ??Mi<y^=LG5kZCW%!+YyHHumaqT9
!CClta N8cE*dPZC/<$4dN/:jTpu++<YFp+awS%ZLEGFbHEZ&AWE&F4ZhP9<Yw/1bnwaT<hl+lb6?daW^X:GP*$
/Cp!4A G@jd^NS!DdC?+Dym@k+*F!+5VGJ596StHbdE:8$AIY%HhYS61/$6pyY+<q%R4^LlFWHMl6QQHJywh=5k
YKW#S^ 4paQR*ahG9c*=hw+61q1&auP<lWF&%i?%l8Fq/I#tbwIDw8>BLK1epZ+/H8P?&A^=?heMiYwE@:^X9J/
YNb1SW =^J#%Nnn>#*y8!u6:m\=:V:kY6bj&a@X5PJd4&X:??^SalJtNdY9&$PbR$CYp@D%\Q!ePue!</:1lm4a
i=$*qR F9S48Vu#&t86TykG!$dulyDp=R//S?aq@B$ajVt+\IeR\ml6pypVEn#P9$DVJAT^DwjZ$V>SB=WMahSP
mdA6#P KNY$88mJt!=IC5@qbNPkpi1H<cSH\MLX\beVIt!D+YRN&#bEFX#WVMmc>HtanPpbAJ*LhaLYac%hI*6a
Q#%4w! \F!K#n#ZK+QG6!GKu#*uH8hZPa:6Eyjuelb5LSuPJY6dDV4m?*L4i=/ujP&XYL@?ljR4y*ZaqZ*:K/jY
cm6^&C 8hd+#h9V6&@JHLaXLI&/LJ+chcSjjaKAE!i^WQKnX9BSFWWXYB%EtnX>B::YDnHN%BP\e!6JlJkcuw!\
1+Bq%1 KL/FYiFeCRPL/bHeXGC/RcmC::#yNMiG5qR8=l?=*4T\ZT8nHwb^He4\Y1Xk%AkW/kN>&=/9KqC=:R&T
bB*6R^ wl^^^nYb1l@aIycaW%ey!86XpNF^!&t\=N1w8^6QACn^JSEL$5LXGjJ1\Zyn>?XkiZ:HK9NeRD^j!yZ9
:NyBGF +cipXHM=ZVDaEGASe/TLiLnLEF!WL@V#6:JSEmMZJa*HCZha^eVaW^HGWpVBVV8FQI?ccIk^*AY\\qeA
pL#Fy4 &%C?anb!l?iCt+J6615%EQbIE4H>&hw+W==uKkQZl1mFIWFeiqE\c$uH46#jd*Mp5kbwe#CQybSClDRK
\w6CG? @!GI5bb\%NMSdBJw5LCkAn8h4W<FX6@D/q>5d1p$=5ka<>q+u^H>IMF@V8yk\^YB&PFTSJ*C%bP/GB:q
n+BM>D NZeFG%T5Q/NMS?^^M<ji*nu4$tWR\*1XH=+n=L8Va%D^bcCM=R9:511i=adplJbdi$nNqQcA:BJy>%<%
kjInHD /@/4NIKeYpt^AQ5M*Vt:HHdw%6pa98yhP%@d>VYL8AFBjMTNbyDLl>pl^=#ItD&S\I/%lI8\E8ua$&LV
Nnil#1 uV!dSDb=pQ#8:WNCFBb%6d1N/iH56#=I!RVT5?mF^e/pH8jZR=lBV/CqYYk?en=M6b5y4DeBXp%HCK!\
#%9M/9 uH:YeCK!5NnDymnY5d^ek^LM%?/?D4V%1JN8u=jJ\*V/jlBbQBRF8@N!T#E>9*Y<qLu!hdZ/5!<h4G!@
c&i^hh ?4\CkbeTyFJp#<Zb%dVReuY:B+<F#e1:nh%dFLu>^6$@9$6EWRT!GW>9*u^@maywXCI&&\*A&l/%4:5!
mt8p+c D&dMk4nSdS=\n/?5!8TMVyhEMV^aDnpS6IhmECMA5JVR9K>1BtHl/jDa>5WnV%!SDWQ*&/B1>S$n?$LK
/<nH^D EbY\cNQ=l8:%ptS%WE@V<\%u+8%I!FK:1Ki/<F9*tp:HHkDVmal1>u!b?WuRbJNJR+u:i9=&?RS8Pq?q
uXuhN5 eGL@6:6%m%m*:ZCeYQI/QQqTCd8:>@9!XkZ9?whAT&^>\@QYcwR14^+<qkT1eH1y\unJkG/h<*pA6tIe
Jn?Z>= !Gd>^<dtLpiiR<1hbDHCFQ@YC6t&!Mdc+TGapLiNLn1Hiqih+dZPY$Mp5i&Pn8\6Sue/d=C9%%9q<6?X
LXWX$J JchV*6hiCS?p=!QZ5F<dIcj!C>?^KX5RelW?KRlXW1<Ld8>+$NGan?IPQib+IRPd^L!h%^dW*p^9QDaa
>JBdK@ Ic5Kd#4SJXT#TA4QQc1k1bkik5RHQ@h@@9quZq9teDdZkaYi@d:WWVK&+AF/ty>TNuK\\>PZayliji@q
?pXhVj %lPcB4wK4Ki/<:ZC%d1X<ubNM?<tnJec4#w@=*>cDZbK9Q8IA*?N#cYYteN&p5?B6u5M*uL:%nMipw9/
R&6lX+ $uwQW9kKXd5h$1?YY&#K@4&tE^d/6cQ4&<1Hcjqh?SBidD*aVc:+hGA+ZJ%PHRHCiDaH/Xcki5n%1we=
lYBj@q GR8DeQELtWCBDVK<RkXBauySQi=S%qEScn9h*ZqH/!^+qSdAhZH6@bFVnRKPYjN95t4>GV9yD5R>>%C+
&E=acm *Py=Dh948e#I%KEn5\lbDp:RG#*n!bie%huh?!6WFWkqtXynVHtyilY\$tZ:M\BjBtnQ#^ZVyenkZZFa
66>C!H /6n9WV<@D&P@%IXXaH@u+l5!q#adCA5&yS+et8!/P#L>T4bqudjGH@B/6VbPqk+WLQPX8F6PtZEEV?PE
abGHpb N+?F1uyll5cI1!Yh?GicXYG6HEKGp!SiTKmC?Y1dYJB\^^kSV5Mm$C#DCHZd*^hqdB\L5pWc$tkq+j+:
IaWD>N kjWj&bbVL$jmj<$Q&EWH89abVW%^NI!9>YAR9:cH5cpn5=t&hwCy!AaL4CKI>=+lBT+Z@dS9tC^:C1wC
P4JiD/ T==QSBh<y&Q^XZQuL1?F&/9dBkbtNYV5+V+9dqp?qRVuYp!Fj#l@VZy%F*@h/DccHJDwhplpn6yZMm<e
#%jmIm !4GL\ESZ?epdRVG9CbamN1MiXnmuA?QH?1Qt!6iyyi1I4ny??%:ZICC8@b^w48eEtX*dZGH/1E*5*%Ay
@Xk59& nl\:V&C4qYWB!&nauR^6w@TWSdFEHJc&D$hw!#Et<ZCpd#NC*5wh?KS6E1aHB$m!M%>DGdFV%!&ujZ+k
&hM4b5 FeTcalhZl:h*<*K59w\k^pnu4hX@/tM=IJ*/1m#Tq@u/np:4h\^\8j#9tdI5pc%KautKFy5c9/SGjX@&
^e?w&< <i#4CeB@F$pD?yl@*!eB9IqVANVYldC>aRiy/lH&=\m\QeTYtq!*^^9pChkYh1p*EZV1EKmR^QSb*dhC
8WSp:R GE?I1cQaK?WY9nN1R#8PuwP1bj+E869T^<HB+V!ZEuQbQ*p/lSJMakDd$=u89BNP^c\$BPpSN&l%?cj>
ThBaWF pmia*pnM**al/q9:<EH4Ek?c/<C/k6Wp:Q=9<:5wtCmT?I9taZZb?JT5+9+EbY<uu#@Q==@uu?qn<HqA
-Aq?FJ 000581c609300110334 Page 72 of binaries2.zip
!\FlKe H/iDW*^Ay=aNXKdyId/TKCbw1^WG6@Q%%p?C?hhGcchck1Zc+NL8jT!S:d:8N9qE@n\j@DaIH&<H4@jJ
P%LdFw 164e%P$C*BTw<>dc&IJPB4H4%<t\#8X/KK$NjK*Y8hT&Zc?Yj%HYHhdXV4qdtke49bL%wFcqu=jyt4#n
h*N44Q @+Ie^6eeN?q\PaYMJ<+9&I>>^GJCBBMlTZk*4NSPnEWTY:p*#^TiQ^uN^P?hw%@/C>P86q%<*Q!bq+L?
LZSm6M @LPWEXjnpKtY@^6qZ?8Ia15t%q!5dV?tl#!D5+NAMej@P%#/Z=hBTQ!BZktyyYjb&\Kwl:ZD%8G:h$j9
TcBE$* !1$1*iFnISKMHH68L<au!+>GY$Dh:=+$V%=*Z&PZ%t6ijLi=9!qj?CJ4$&Ad:Dh6ml:GT=N&9Swl:n>V
<Dp!WH m%niJCI!#R+$dLhP?4Zh=cuwdV4SjmpL/SytN<$n:&N&585#HBVWSi+i<Rn<n=\T?GhY4Dua\T>+8^uK
/1$&\! bBCc!4Eklk<45RphPD*YNje*Z>S<t99tBS8V^:j9DG<^ttd45I+&FhiDu>j+!nFVdbhpYQhb\dLAZ>/F
>JTC+t *Xm/Gt8m@nM>:MtW*B%he\=pG@XP9XdHNDm=CCZB%1MKMbRAQeVR=EP=WTG@RNAXi+yl4WMEN>4RqBm\
<LXN^c hhI>/jj=<@ZJ\eq4?4L@tm@:1uqXW9icMu^a6$6!<TaJa6p:!I=?w+5b4iwJ5B^8%&A+NdEG9w*RQ*P8
hcpJBV ZD&SBLcHawpip>&<#<?=>!q\#??jy/=cBh4FC^u6yISF1+:MKM:qC#8qMwbN>$Da4nTk/$lMp<X#Fdnm
Kat&DS P69P8V6N894e9KuH@nS?$V9+wBZmkt5%SGB&u@J%Lt:\jG:SSNe$QCpG\4k@\>DRp*FjkY$*WCdi4nt$
iwD+KP 4Y1NaG5B$e1SkWwZDGLXt$imem6H@B@$u!$/NVw\kHSi9?^hRt#4:PR%kPYLj^#$DkDy@pHQlk?#imW^
$tiGD# QP^ek/>T$I/YPPVRPZQX:dIkdtQeJjeRNtES\+YFXX68Y6VPjI@yTh=uYh#d8DHR>ZqCC9tZCwNckb6W
T#T^6t @mc#uDBCQC@L/#BZHLtjF%\&WY8$&#$P@@h$y9++1q*T*l6b\wDp:NIYNC#uNnkQj?qVZdVGwhj<?WCB
1>IFkb 6aTXAM9SW>VZt8HW*+@mG=+A<HCm=HckaMjI5P85SDJD&\#8Wa*AdSt\l^YqKE?!\W4^R:wK!llHhjlP
e$@YZt kCXwY<#Yn6T\aAKV:F$/?hDHGqL/IG#QZl8+DQDB/+PVk#/jAjl:>G@C><ilG%/#jtWVHy+P4KRD:lyE
QEJeNm bKJD$yii5M9N*B*E@k?Fh9Zb8u/h#Vdn&VQTMET+Qu@?*Km1kauDMt?b=Gd%S?%w=?J^<tM^bH8uWn&T
hjmWH5 VXlhLaT\tW^$KtEICJC>8XNN!?D!91Qqt5:>E8mq\ed8JuB649F%p&@6%uu/k5TH8&w+tTh<F^dGj9Hq
4Y>qH1 p#QS6CheP5Hd+iBhII<CcG96X4X%%Kw!dIBR9u*mPaC6T^q4*#JkY##Qp>\:%n<h4lAN5IK5YAW6c:+b
iJ=4:R +AD5mj%FF#5p?1MVJm8KPuu6DP<JXX+kIAG?ky+hGMJalhSt!+t?9T5jeqKHQFmJI<wtGlqSb?M*db5E
h1=E@q %k\@#^Fhj@G#Rd=<p$EVyq<jye8PK+4#9EPFJVF1mZqX^>D!NSIDuytbJH5atKmGkXqS$/nc#I9$><FW
Pi#^C: :d?T6mPt//a\6:/y#XlauHN#N*ha*Tci#d!InS*nD^^T%LEEBG&:K<B&nuBy<WYIiul$iemny!+?945A
K51B4B #l<J$+<C19^F//k61HaEXW^#:=Nh>tH!\XaH<<jA4kc!WJw8I!TalyQ8tG6J$NEEPi#X:N4wkHPZ^VD8
eI\8=F 58ZE\FaQ$$P&kWnBctbWM4Bu8#w4/mG*mCi$Eq&lnm55\M9mJJXSe4wwjQ6tm^%R#QdmAZtCRmH*1qTy
DM5XXQ MYG9eP4^Vkjyj=#wT5<d6y<C6wL9@C:RhcwJPqu1/b$%VeYXHhlh:pZcXQ&K<R6S?&S#aNJAQTyhbliF
?T$/a+ 6=m9jia4qtD\d1KPAh5mpBlZIQj^*d9YP+!dP9^$<c=%iZnS\9n#m=d<51Y\hunVMinKM#XQi4C&!VKd
#Cja%V &1y9wQp=Rqc?<EbL?y#$PTuep=u6ZN\*9F/6bk=5n\X^Z!%kmTWiXVqdTWm*K\CYBY1V?c4/>W\uD@KE
=e6ey1 e5cWq%MA%?$WiTC&w#P%uunWGmaBTcu+w&S?iM+yQFkCF5HEZ48H!RRwV?S^q4\$ZP&u1c>LX>di4Rql
45Fw&> T=l/#T?Zd#FZt&m9&>T/AiC+KSBDEui>MQF5dw6&iILG$<TPJyZE/?tVmEhJjHeIYZ!FTkYl:IWI&>dS
uNl$E/ S/a4JtN@QL^<>=F?RklnX>eumGLCqj:!Aylip%q^JXa6+*R&Q96ApN/eue*?aVc+Gb#>hwc9enqnIp?\
&Q*lNc %:I9C:lPMA&PwbZTQ5LX^uiPS\lIeE/HJVF=5&*TF?&/E9cIiQiLCtIL:hEBje$#N4uy\Di>5^l?@1eE
hW%1>q cX6<l4DER44wWEWlI!kibWRMLPICV#nqVXlpEw8P=YG4Req!XDFCX8j&K/yj^Gdm&BDQENAG^>GpB\W4
a+wuu4 klm6wD!/6dpyCub#5:+bAwqpEK8EF/M5JADClAJ/Au4<Qmhn^:$id*An9=FJJ:K+hZS=hQH8k9V1y$NT
u5SNTB 18?+Vi!R>=1TSG+J5PA9CN6S8w:aXitnkwwpQi>\y<@=&YeGX5Ghu\*?RcAF8mT5V&aAFk8dllPyI:tt
l&>e<b #>X1/nunWbe>HjTFNmCI>#p&$VCLtAW^lPplCYKD>i+%B!KAcq+k=X1/jA=:SRAwW=b>eDcIictPjPFe
BZB&:t DyylWTyiaFmb4$hw\5JwklHHJ*RJe:T=@pcNa\M*8CP?Z#9Mlyd%KN%NMLYyjC&y+aV%N%\p9eqSG\u>
*W1c<* 9:dk%VLT5G9%^DQnK!M:G5NkRb5wL6h$8Y^j61/ImBn<h+SN<I\pAR\XT^Kbdu%5ZS\T#9V:!/Q4I@\V
ReDyuI @VN9T!jmRc1iVZq@?^!Zt>@thKHQ\j!*#@TFACcad\n%D^<tp\<+C^C#^4y51ic:b4:PhL</C&JCWY6@
y$NuP@ /1m$Jj>G!pdIl#&1piEp:8m?F84P:\a/\nPZX?td!&>n=hN&:p@Q@$Selj^Nya\Gpen6d#w=BN6Z8Q=J
PXKt6K b6imcchAB4F5PPQXhh&PGAFhIi\+WHdG9Q^!<@Sn!wGttYbL4a/d^$GQBNJN+!5QZeC6/t/Jy:l1FBF<
bHbdDd 6W#8ZCNaJwwDZe*jkiYEpj?EK4*iERqmByc?p!J6adpiEbaAqBFWN8EeG$:jjiV^4A^4//4D\LJF$S?!
bjViu8 EJamdja:CFZAPyi99@EZRA6SVMlP6c^bJy5IZXt@Vt&@P9&$RWB&i:^%yI%wI14cn#wCdJME<T<R^P<k
H1XBmK mC*d?cN8&hVJX:q6Zy?YL^G5&*?C\jTLAA9DGJKa+CNdCc%Z8k/LB!b!M$C?WMBcuRw1&EmiZZh:51:D
D^?ScN Jk64/+=Bi!Ql^VA=i1d^R+nltR:Wp9e/HyH@n6R!^lLIRDqCptDilZ+XBZ5R?M49#hdFK4K#G#>yyq@M
JZ\5Ic PMb^/$>p4lN*K%\^Z/>cDP!S>Nl@Ay+pnAqF<JiZu%=wF!<Di$Hu\ZYZkS%dtA*:&\t+t>?A1u^5#j$D
$*iAJq !N:<lnYuJKmJ&Ci?YF4YG+6?uRcbJXXhjhcu=EcTH>5?15MmSuhl@inRk<SuplNh9ybA@+dm85*6itm\
ZJqdNV *j:V>y@?qEK=bwhyBVepLyGD4eSduKX\nde+eSLk<RXYVYL>?lGchWkTw&B1=LFm4Zy!+\Y\A6p9aC=n
6lBPam ?5YtR9k?DVPd!HSk8ww$49PkX6G98/W1S8y6S94XWk!?i6JM+yppq@#eWu5dG:CpP9J1^DE<VQ@nl5=*
t<uabE JHGQ5P!W>^BwN@a:TGbw&CQ888hBC61=MMVpaNKYw5yubpJ5$a9aRtl#m<Dh865TcG@ttNQ=AVZ=my?e
JSQ+FK aAlLnIT9M&98JEE54jwaQAY:CX?Q&6^<%8!$1?<pLHlaPXH>?qJ*Sm*!5mI#6=*ZFbS@?6N&A9uL&Ew?
hTh8Ry B#h+ta:Pu=Db^I@cN9pm@/L\1wTNlF\*Ac=&iq&yFNd^D44l*A<5C%/yGy#1AdiPXX>?\%YLw*=VFi#@
8>QW#A !H#h^i^YtMM<1\9DEpQniuM?D!Gu8+C5FThPQcN9>ma9%itC4!cGTeh&mK<<:iTV:mHk8jW!h$1HnF%m
!11Ybw /uuL%T8BKy9eb:IcR&HF<&@B/h1/p=CBAD&j@<PeLGW6k:Xa5NSYZ\>b9@yRMRlmC!Y&t?#M6l6HddGe
hmP+n? SBCV:eR^am/DIdy8/BaEk=XB*T%6E%?V6IKwSAwbuHG$CuKaC<ajbK+yD+1Z^1#<m*^lJ+<6YFl6JiGd
*\+5K6 #lAtaqeca!&wmQDk%JReE?mL&MnlkI>uajpN@4GHbbpR\K^kN*qkK@F%5!uDIDFad:ey\$$^R8VGF4I9
P&jBRL JiEd=ZYtZ9JpaTidQCHuH@a#ZX%JJ?iq#wtV/hiA<iMF:$u<?EtuK8N*$y8NNchDN9:XRJS=kJ4W&IJG
EYGjD* &EKyPiE4Z>T#t$t^!6ntt&NHu^lP\qeLPa$I#\b*E6INcZqR!$tC^piXZ!R/WVtDM:BX<QXC85?&bJ8w
:#b6m% p\SPDq@ah$$4>Euu^Db*NaP9BZFqe>cclaZMP\R5DCeA&$Pe8D$chaaC:NBLEGh/S45XE\qujbhlAa+5
/+SGB= TBuYN\?cQE@8RNDESNNNDEi*yZ\/Hkb<hYB>iYFk:I!%:JjkI+@DXBE=yCQ6!:&RNVF/+jWVu!=p=MqH
nYc/J: BSd/>@4mY9bN+!&PQLw&<##HWnhQ#*&bLhV?qk?9$i!*9tq4lIB?uW&m$ATl^&blk&Q@DR:=p&ZMDcPh
n#FScZ /1EWuJaQZ<N:H!#8dYMJD&1Y6h&/QnbJDkEyJQE9/5QTS@JN4TSMd<I5ES:8lF=QMwi^X4BW1&AhKVP&
QqpB%1 m\AF%kXLMh9Ic+iuYq&1RaK+*5uj#Fkci!i!l/^ZJ#FM66IBnF@bbRCcpy@D6*e*4X/m&?RyR*i?AZm6
Wbm//u P6H:5e!G+8ecw?6MLSbe$QAH^q=e/Ck^=mdQ/bR6I4KT&PbQYS99WG!C1je/cKcKF<RDVL8%DEXBab1n
y#!<E? FqY#1\P:TZ:8!ZX8JPRGWhnE>LZhqnE1?!A5YW+eVC^Z$C9/htED%lh=&^mQnZd%E1G/VV=P!ta\&W!H
$6qTL+ :MuCQu/^AIL=\w6C95ABa1#T\h%ejwj$/$+F/<wp5NanTW!Z*qCLV$*L1tt5^uEEK$M/uaTiAHbii&Pa
L%qiMD Z+\wl1>6!kK?*W*t1!*SnEatcmS44m#ShKCbV9yyG6c4tWeVdS1/$kbhHaTBBjAM+WjMuQwp<<X5B1BM
AV@@6@ m<Ppw1HZmHDR%KY\MFVnJQ^>94R<apl?K:I<$B\C@a4=cyqKQklMYGlaak5ZWNDZw*bZJDGu%!Z+n<4+
@=T:6t l+&\R:Wpk&DBX6!wJAqW1\lm5a9^=dCeK/AZ8=A4+E9?SR+A$^i!lR9d&QBcBYGQGqC9T6m4HpaA5Xp!
Z&ipe4 HwZhJ:#ACG>y:FZF$&mbl1+bahMjwaNN/FiT^6C1JX=TIZcV#TVtEq9G>kb4J=Y\uA!<C+Qad9^##WRd
Bjb*QW !\+YQNWXt!%Am/%h+mb9D8G^W^iZM66S%i&qV5Y?%5HaZ6QFk^=84BSQLmI+quPV!Gc4/<CE5SFYYk*X
QFT*@9 dkw/ch^wM#6:*JYEMS6h#kGITh^8H^L#jpH<1Dc@a#G<<LYM\kPTeykhu=TlZ@?P^ZDG4C$j548#ueiK
YB8ee$ >Xe:&#6<k$EtqA5:mDcSj1&B4?V1hBBN:HVJ5!QKh1>:dBd##G:jkiIX^FPX!lQQyh5cTDL^ac!T^:>*
-A9<T^ 00036a4a5e000110334 Page 73 of binaries2.zip
:\1:R> AHi%CbJm+RktEiQt48K/!jZDB?#uSBLRc6n8w5cP8Dq&/9Jlw4&=w!8dk*E6<$%$AKCMm45\wc^DAK<8
hDN?I4 bT8^LP\cV<I<BT$m$HTXbnn+!@I8WNcVVVPQR5m4+DnmVL5:wTaAZq*tc4Vd?^\e:4TQP6K=V#=5laNP
y815<S l+i%*=djnc!AX@tKYdC<4DBJp+y\qWZ^P>^CXn==XeI&dXlIhPNFmdDN9hnJqaA$@cL/1q1DTh#tQG^H
#=\^P8 t5P/HKhn\^k9eTKqFJ4yaadPNN?6/5:y1yb1j>TDDK:9!5BcuVC65Jwk%pGabA>n9/kK9LqJak$uluw=
*Tp8a% :Zw&L%c&e4JXC&T9aDnBh94IS4GaTl@6L89eV#^ZVAT^>AbPbPe>t>$c1dX\=61ZyeXNhAL4NDn6c4>h
DP$5%h M%>=JK9cn%%wYG:Tl+J6>+!\?+^58**$!!Feq*K=Mj??EddTdPS=<W=Xy9#8XIY9\TJPJRZ\T:t<@a1I
>SpBiY TSK*^t8%id5&>nDVFdD8EK#R4!&X^D$8FTh=QG1L+<=4y*\=1&=wqmyB/i+\I:nL:Za>dM+GZ#qc8I9a
u6lHad SI^4KiB1FSP94T\nV6q:@cwXRbwlP9Yqb^PY>=CBw&8hk*F^8ebZ%1&Z=94IpN%LHyVBk:GHc89QbuH:
#KTTPG kpqkiSF&i*t*DLWEM^6dw^wBB$4<uNp+Im^!/mB54\6kwZQIhlKwCi91ajwLy?61k+KY>DP/8h%hYdnD
e&qpYb C:P1<GwRh1#RJ=DFLR+Ty+Sqiaip:ZaN&=eBLAAq:qb&TqZWEKPKyNFm55KLSR*Bhi<KeTe^nF*E1y=q
8p\j&+ q&>t?Xd=Ca>6^=JLNtd/>H@5%4C^6Ku&*h@<#S18B/n6I5/iYALRLPKq%:D^AkCNYWdXy&/wDaY\GJGk
BSb4N> R%l64bMV%9Y4:BP==Hq^X$Qj%&ZnanXI4bY%dCZ>+#\G%%LEIwuNYhZNZMB%Nk&N>n#Lyw+kejiE:TSt
SMHPy> dLPDJIBM&tm*Y+iXZ%DCh8nLXGXV#&+V5P=GM>w+jtl&p=uGl?XZbbc$RHCuc5DC\/u5!PyiAdcD9I/p
^MR*8j t>Fa*%FkPZ8HbhnYW?hD?MjlJ%l#\^&!J\\8kyG:Vh/y8Bu+848:Jwi=ap@=/uVS\qcbhD&QcycnHpyL
nCjMG% >E4AE8iS<jXc=y9dGFct/Ki\Z!S+PiJ$VuTGeq^X/@L*H:tR:8+t5Hb=F!T^BtZG&9ZN?nX+ad#acXSH
REFb9n ESbHtPwah\VV1R=n1694w%?4ipmTtC9ajh$tP#6=Hq:k5:#WEn=pjH>Sc=k<u4Te%BBT14b1%ZINXbcq
Pwwh\j T1t&VV?D*%1lu^$B&CQ$@LEpFuVJ*dtT^N&IR?!pSZl4b&mFhW6=1LKwb$NGGFtIZZb8@pa>56%h+&6J
MCq*4R ?Iw!:AQ\>ecKMbdta*n+Z%eEj+:#DL/npJ>YA5XmEq>eT>BJR^G<eEL%1@t8F#1+W/!t5hBX^:II1w1h
eRQ^8A FhZi*Zml!NI/Gt*I8a%Kq4mES<VpXB@*&HLmtFPZLCj?lk<hA+ywIkFF>E5&%CBGhAIK6q=6PK=5@BJn
yWZ4t> PbnICBP$FSlQ^NhY6Wc\6tw%=mi*4\Bm5aWSH/=&TBI*%HSm!yK:\?thu6VI\nk?+j/5Wbk&clCQiI<E
J>G&R% W^8iL&QeaDPJlY?R9k=4ZlJ%jSRRA#mB%aICc:CGXP@M1y+t99>*PLF+I9PRZS8PP1u@?9HT@Fh%aQu9
PRRY?L aA:LTLJbtHq?J@ppkZX8y^Veu^8X^k^4%D=w6yQw%%BALb6PJ$PpehV<SVRSZk?ZP<qH??mhMBc+<wa>
ieRlm/ Nb>&MZ=Qt/L4JIeFWVPI^YnmaQF&1>+m6Pk4/nHB*SwZ$jKNI+Kd9J^Y8/*qB^^/Rw%mb<nXMYRWT^=:
<D@wl= !H:QPAw\mlmCphBHER%ZTIG%RBc:1MHS9@tdmKS$M?@/qYjD>JY95iGpC9a8EFdn^bwYuE!6b$ItZ$kP
$$c&W^ XPa=!qK8+L?c><1=HI%K&HC^<h4w19qcQ8pt:Im*mp\4MI9DE=1euA\6Qn\L<hSJD^b\6><XR/uHkLbb
5^NSGV Ny>$MSpR+j@55Q!8uN6\TW#w=1Z9WJ8m!\KqcNt@E?5JCCNhX#Zy&5HPP*bZWWVLZCW86^yHhhP6Iwtq
q!dW<C =Aula1I6V\PT/&Rp1<>q%5>Ein?+dkAlbTT1l\b5\*CNlc@E6QPqH$T@AqnkC4=cMHEyCja:L&K#/#\W
yG4b<= Qap6dmu<CFnb4*eS@FjX5Si&ZIV=P41&JDQ!pC/GSZ*i^RWl?5##WEeh>w%d1cTeZlyHNPW9uqm>&?F$
/pQ+4< HiwuJb1IHIARFneQ*@%!CBItpb<DV/jNjPZ&&S4#NC8:9bS!GydwT$b!mZ\ZSApbMYIw+ZuEkDLM4d4/
8+%a=! 49#:Sl6Nht&qLQ*d/L4d+\+ihtp=YD/ecC^abkJ&&aZn5QJI1&uIH6:hbC!Bc:/$Ze49@mB$#iPuyX&P
KaJm4H TSBu5S=y:kP?RlDQKmjt1tI%t?IB#Iubwy/LbbQ+Tk\uht\$DS9b\#1:p&Y*BCXMDM@nTXL4H@wKNFP/
QtS+AP >MR@P>VmVR<u1q?>iI?49BCd+EkElDHTALCZ&DJtEuiP8KiDQy>9SB*Mm^IV656Vu$nB@5J<jSeFJ>mQ
q@^kPt ^Rjm?6etaV8w#TS%YtZB*Pm+6cSFaQIFHp?uQTLPhu6ZI\npunt$uLAbYbmjVXIy6PmJ>e\/q1Y8+14=
=jTa%5 mh&<IF#/kRlLwP+#a$<$lCiC#kM?n8!NX<bwQ/aaLFQV5cP^\Zy68*@WZ%W4?PQqlW<:9&Sal$M?:LLu
hlkSq# >I9EEP?iqKdHqTEG/>*eI5XTklW!e<PNRbRlXwp&uLC4\!EJX4FKW>#w5ZX<?P:\:\:L&YG!CA+5%6DZ
/:nuGj MW1GqDH*jj\hhK8AYhFkwlnEj%e8w%c&I$Y*c&w$81QZ#qGd#wK/iV#6LmHLHV^6CWA^H<tlWc?Y\@^e
k!qJ:m wn41Mq6:muFnh@eH5aEqXS#^>Re!t=m9@cd\%T^mJc\dKDFlQc\+C\EAmR4IlM:lqYaA%FE%45y&VFc&
bD>\YC X?!>ew:P%$*:*wyqtBBtH%@?RFwF%lm4/l:I@tj@G+jNb@Gt?MpaA=ndR5+8t$/5aXpT<?#II^LD9*Dh
mc*RXM cC!IF>\Snjdbbkj>QGR&b&wLt%AtEuM<ed9V9pdBdRA&kB8<G@=J+/lV<%LMuk#9/wkBJTq*t>AqtXc?
ADwYj: L*BKkS<D&^%^uJQ\?:<^Z%HYRVnuT%!*R%l9e19?RdQ@t5ZkQ<+nm%lhHb*4bDHF&A+h^+PASy^T8Yba
tSDkM& 4!=NFK5\X8y?%A*nq1PV#P55HkIeGpI=CPJi<<%c@jS<HkP4TNK4iHbkcbC^YbQ+%lB/9kc1=P1Ayj5m
*Zw8=n mbt!hRKYBY\C\?qik5V$qb9\IMYJ5IiHX1/Y8n$Mh%b!5XW$c9aR%i<mk>:8^uV6mnI%HW6tF9p>mnu@
V5d/L: +bA::peik+K$QSt^1tWZB>9!S8l<B:A<md#dkF:hBWpXVNBWkj&BhC!SFS1&9/?tmRI4wum8W=*tpXX1
6EnDd@ md59q9ZX?K!phdR\$BN&Eu4/JD4&<pJ&FKl&9hbiyFm>Kk<DRRqbLy/Pc@YpR%R:S*%4Im9X@?KXL#!%
qNJ?CR hX&<mc$yalek\uaCV&G>MIHyb46C9k=b^Pp/aZiS9iZka:6>XDp<@IYhHXT8@eK&5PbmK@TjDT!kHBL#
yRc+mt 4y!iMl>B:@VECGcd8h+m9/lqB4L<GVV6Ndna=Y=bmFwW*@bG$qQYSdck%?%h1<@dEi9*l%%tcb:+t1ed
@P>k+W id/^C+!:VNeD+P4NZT1D=enhtTj=n+:9VSmP/WpHD:$L4NjZq#c+@tP<VwV=i5%Luc=$KK8QT6ei%Ml1
1MCy>? +54ctT/kn91=d/KGaMkTX:Hn@@K@5qpuuuBu+&t@!!EtDS+C*#=:Q#$Y^D&T^Ih@^!b^dmNT5TTJG&$$
w=Q9aw jTDIVKb9=hDJt1ulyD:6abp5&!HpKS8=#F1S!X&bBNeS\nLI6T1B&?AlBjc#L9ewkjPmSNt#GYqSH<F/
96%@$d DZq\VTjPqjTb%W8:\qG\FNX%ibdD&:#5q@m/TcCiEGj:HQc@Ya891^N4@V4/SehQ#LV<NE#GhMJiY$YM
q$dt1T WjcnL?tCjtXWEWT<G6qR!Fp$m84P6T6ZZ5=898CbyA$$/6TQ9S$dN$lk@8j@4e^Atp!>kI?XSFh&HBCI
TWH#Y> dcc5cF4ueLhhQmR/E8?i8/@DJnGD*/*n9\u/Z*:S8MSl11YJjAG!qVI9L\M!%^n<Bw&JPHD:GnPe&n%8
@bZyN8 YBGK6nAp6jR1X#Jd8T%WSwp^$4M>acuwY\%HELB6nH?D\+6m9$byX#Ry$=YA#ZPhM@PX99<ATKFi#e*S
^t@6TF ALGYt$yypjS+Ii$i6K^*Ap^<4LlEyw&!$LEZ6kn#\6b%MX?9Nhwp+VMeiB&NFWkaWJZYJQD&!+&*5uke
eL&WWT i^tNRiLZ<q@@L9yX$?$niXYwIK@D%?EpnynGCE1$#ZIm8yCG=hLSi%P^cnyJ+BG6A1&WHN&KY5NmP>Gb
u+X!>k \AYNlP^ltYh\ecTl\=*BTMlh>^CA\B=C=Y!uZm9qeln86e&6hk!6cNw&/?elbG%Zw5H5%A^XCI#+V>15
t\wWn+ k:8N9QD%B\ALYCF?mduk/\>$A?EtSydN+eDZ?hJLWdRkSwNSN%d$hPN%PNE/hy%cQ>T==lIw9k!4j*Dn
6G^T/Y Y9Y4=NS=Qd#6Jy196Z=Kj<PWT!/=<BK\juEhK@ch/Q<duR<*@8j@m>4Dqlu^EmLpah5>DV5yul%J!QdB
8:GBK+ buJmta:d8mJCG6bLhR%RIS9Q^SYyE:b5cXkT^%#8%BlKHip%A\ynl+pKLDl8Wi>We#!Nd\NVwK1NV19i
&CHBuk PdJAqElnlI$SXBVYM4!a5ZmFu=N=NbJmm?=%9eV<JFn#?X!Jt$&p<+RFMjNXpFWYiE&mNqB:T/!u#cJY
aPX>@l P%X4qmnp?l5^mlZYT//MWGlXEC85Pp*b&$Hhc4J1PaA1pCy6\hwd/\aYT!CM5LFJe@@Dj+?cVW$P5*LX
t\:EX4 TyN^V?mJ+RX6peb>q<RMhi8R/En?cI=uEG^w+d@+8@\9:cP@+$m!SCW!6b!+JkbPD!uj^wmNHKtFcHN*
&<mPnb JHGNIKq*G1YTYYSaddBhLcEQwIXt@$/%a?/S@A6hudZ!@%&4nwLXnQPp#qKZ?AwVtH5=6cFIN/>9>u6N
lGbclF X1>ebZ@n/VFL/IVCCTZ5@C/iWm!W>aEYTqlhSuCq<RqDXELDF&FH\WmQiV#yMdcbdqk?V/ZuDQZ9yG4Z
cdA%ZC SjGhJSR%QnHq?SIYy=lwk:mehj5^mtwIG>VBmW*Lj:yjdHn$j!Nj%/wwB9cZh:@<<p+M+WQ#bKFwD^ui
%+bmM& Z<y%yllhi=J<IWZb1VhIW8b+@JQMdh8R\bqHGN@Rc6G*#qGnyja^%^u#SIwlIw\nnl+VV:6h4w/C@8&R
4GI=Hc l8*8AM><j9iHH+Cu5nRA8$6$:SNh?/<>Bu5Z:GF#aWQX\q\$ddS4S+bQ##\B#QYJMHbSJ*+bGW>TNH\y
PV4HIK ^nCmEqi&45IZpRlj:$Kn>w%Z\5N&?mIX/q?t&4>@b:H5WEA^\@^lt^AbF5V#1?5*S+b4S!V^CeeVGiAV
wCZMpm V8#<ewnPnq^\hAnbpkDjW/9=<FARNDeu+!CWNHj\9kC8WwGVRt1%WijSZpD#ZkPW8Jp4H%dJJmbp!iYy
u?apq$ 6^1A66E&pa^ln+D\155=QC/I<wAXT&pT^!Zl=R@=NXmN8QqNVic\ilYZj&/nD8+59</MDYXG<#nXQ4X!
RNI?K! TG<$$ImJbhm9L#RHeKpSSIqGZajcJ6q1MF5j<?thDNbN#WZy&meW89h^FkSbVL<FZ&e/m$HL9V#qSW=5
N18<R@ J^AYkqkJ1@jb+mW^c>FEV5M!aT%PSdL/q:<:@EXX/!?Y$iEYkL@n?MT:e5&5&N*Tk6HpeY%8akQY/mFt
-AJG&Y 000d908eb1400110334 Page 74 of binaries2.zip
QK9XK% pdY1uSb<YbLH4T1tdVRCa%Ey$$MNXAe*<e&>+G5M9&&ZGM+</JwLe6kA#8<ikLBpNmpF@qFKJL^e%&NP
ThlX18 <@qc4bGNu=A8iSu\JwY</8:+Kmj\>Wy4lluY!:C8T#MZ<E^py$kWqJmGVup*$DTq@?YLKNq=qI@XyaE*
qG6/c+ tD?Mwl4N=Emc!&yKtpNI+6+VTh!JJDEWcDudn9t/pVNk8?45HQ/hXCS!5p+/h51@/CwI%CnYEeL9qVd8
lGElTn La6\L$QdlK#dQNAcGhucEj^aIFy4!biGy\:cmHK$S%C8<G#e$\XlEc\E4wG9ktjPCj8D:PY&1IRhKVie
@AS9wm :n\NG>eF#uuGbmlZtF4CW!9FqLAn:bm:pKAm>8yh1BC?+qwwZ5Tt6SI*c@PY&WKcSpPGwppIVNnyF\51
pJRBP= itYM/FmiG/K#6TZQ^NDK@N<8Ah6S<%hk=b9m&Qbb#lJwHE$$kwG#iSdeMGulDlH&l:>+mXMG$9+hm?IK
*<la86 $=dHcbJ=p?eNaA155^?wHl&X1/Wn=P6I\R1\WtJedSF:qdLRwl%+1lDHG8Pw1hqMyqSJ6KqLZ\a&l:p%
FJ8/&B m@\D*Y:&D@dl\jd%MQ&nXlCLt!M1NqRH#4*S#yypyDqYJ?%N4ClG/@@NiGJSDPJiZ+SFdLI#btmqmJcp
48B6Wl e+F1IYnq1#dLc#jlnCeR4RG4&#Sa9$/$qp&m%pM9QymhNN%$/5pZF5Zh\FkC:bCB%abJ6y%KkiB6^9:h
SIB#qB L=y@VTZ&#%&^M9@uZSq%myX6tEedcmiy6jR<6%$?^NdbMk#kX98ING5L/X4J^1QawmZbYRpun:Se=wyn
1kDMiq pG$T&^^&^K>&SA#uVR#uH8nGk$4p*MP8lmWP#tc^niut5F9EMcb^iqRd&!T^QjZ8wJF&!%np/bI*aq=h
Ta#:E4 c1kJ1&5q?TyECl65ZA#Q9p!>QG+/C@N=BiE9$&nalwa?=YZ^QNPbXh=ctd#CPlpn$N5JCybllX\VnL8>
8>L5lT w/NjpAFIe!ENm>LE416a!eKLKGb\YR!uIwQq6k^*K9>y?@qC^<a#Y\uWMt>&Pc#8!NA4klWSSbSGTYtF
HHh8De IM8=HqG#%%%kK4DTu+ZpZ!uwWl=ESLeb%RWAj5n9wlmSwN&jYh#%^p4?=?c@Lm&y\:@R6XyST>dW9Fkh
>:JR9Z Ww<D1eNb4MWP!DJj>T+CF!PNDe8+bXcZh#:%@M95!*4@Wbk$NLQt=?p5>uh+LDb>M@$1B94IiyWE&Tp/
iD?TYE &N9B6YFkV:wiX\\1NlW4B\*P>Ta9L8<b^h61FXipJKaCkC6q>uh+8NPlnNtV5cjJNl%5#MHuGc?H=eMc
+ccJ/j >t\JW5nEhw/A/qGFb:=YcqY8kG8EFB<HI*R1C\4nNAXWL/qH<!B<^jkcASn+L9JNCWweNG?mIM//QT^&
wN\BQu p\#EZN:N+=duiblaM6NiLBX@G4Lt$4V4K>?acD5^6W%hpa&<X>q$1w8b9I<:X4A<p$aa/:pAV5iL\#MZ
cW=lG$ 9w:Dm>HSPtKjVYj>@iG/E>6u!5dAEtM4l\qGEbD<Hb@$<Tj&N^1jIIiIhT!=P/tYE%epZwG9l#K!XRCP
wqRj4d y^XZ14nS<F^:A+/PqnH!%FCCq$R!EdQXpW\QV/LV!mpAi!V@*CA+F&Im&h\\4M+qu+4%c%/ThQ*t!bhb
6<tRZM FB/Y^Qy<GSl4qBYE:&\tw\F:M@W?VRuhYRykbE:Nhhl!!tZDWnp<5hJl/:iK#GE4TIN:4E&EQyJGti9#
KNA6Qu eibldn49#=EWAB!eWilGHE9m1hq6h>yB9=46bHh:DByJ&FK>&^?!QhXZ:N%BAtQj1XW5Le=etekKF9l1
NtW^NI K:8lm5Ep\tVi>XDudIBph%A5\:1%DE^NHCMRXVPZl#$eXE*X?A>cjK<EhyLIjXC&k1<CMQbhL$wwMD$k
jeuBHM c>nuB$q^@b4@i8h#SJb*l9lew^Pl@YpcWn9Y*TctW+DYKV6W8w:hHLcF$^aVuKy?qSE*$$pE1G6bua+#
%i?NlD Y\eY<@&6EbnD@q\yJFEu/Tyw^tpe%Id*^Za!$h!G^j6Li6V48<ueF@C:HR56m:6#!MHEVKyl$A8CDudS
cciQ8k 4#^#Pk!$4YDLA*@Y!HjynL^<w6H1eMtm<lZDa!1E<%ELyVIcYeTj@j@/8y:YPQdqKkIlt&!!#CKLRBa!
i6l:$P /EJYd=YQIJEbeL=FFnM\A!P\+HwV*6IGZbBkB4yBAn>Dhqqd$A*h$B*WnV5ja^a&ZGd:*1@1uK4/>hk9
k=dL*n quWq?hwcTVZ%@>R=l\hkp^>qMuZaL&DC=K&@k?tQlyY<<d8WVSKG$?>5qy+BJ1b\YFQ<aH:N&Th<:PTW
1YwR&V aC$$8T\Wi@WEmD@&/eB/8Q!IC%CaYit9cwwY1=18:jI5&=HR/nXY:TuERD<uLuTWw+Mnp$+uIM@t5ScI
$9>@b1 u<<meVK5kCeiMI>T!#/X:4Kq+tl$CjBSa#FB^Fw#*bQ5qG^59+F@paFa#L8y!qRMTcZLlqS&:B5%/Hy:
T4IY</ 9SZVdlXN9up<:Qc^Euna/9EAmcy9^aJ5cYBY<hJ@?cd9JNM1+9%ZCePPC4P#^BN9&kL=##dS$t\?@:en
D\\9@c hyj*cXw@a^hknIHb6QXB/+1ylGEqP6@QePqGFTDZiYq5\>A*=MalkWy5bXE@1Z/P/!ZY5K#h1/G%Xd!@
>9YIn+ #Rbl8Cjj!ayZ1nN?YB&+\qQD/k5>F4b>qIaw%eMyBp9@8tb>9DcGknpBNS^+X?wbl1dMA85=GVk>dylh
W9QW8a %dB1Qcmk<jinFMQ\=1*\LewG+RnZXK9mQ*nuT8#/1^^\QN%>!lPXeV6MWSFnNHHmycLjQAewb9DBpFF=
i4S!M@ +C^YDQ6FtTj$Jp6mM9^XSeS4*tq*wW\eE4b>d=Nuw1mwWkKMSy<VYuZ85%wQ/+t\MS=l6aD:Wul@%:?j
jT=PF+ L\AamW5Q^hn5@PjDQ61l<Fn8AGVFq#L^^@9jFPH$kiWTiap@Yn=hR%SLHZc#&:WXPPyi!wA:Qi+i>Gk4
6wa!l= GZT=Y1:X9Pu>bP9>%kyncZLZ8Lq<&D#iZ141!:jjyjaqt/:b>@j$u:hQPt=/<nA<^EdPIQ>GBeCcme#H
CqFGk5 &e4PlRDmdL+Q&Cu/YN=*MA4D+F#TpXal5E*W^B\/k<WBYtkmA:#/daIW?dXH:ac9Z@%XNuY61#R&+c<w
Nh>$I? 6#w=dV/L^GhF<RjJul6WW$XJ^%Zhc!&Jhc1<J+SC$G!TYAGIRiWE#kycquV#BXb+/1@:G5NiN1a/qyD#
A\d!TF 8&R<W84L#c#8iNT5Ey!Zc/G>qY^<GYQP!&N/kYYNNQqKTNcpjj&V8&9Ae$hHVJ\+@Le=4JuX?ie>^ecq
I<ZWDC VB/KhdtnyqYmAw*N1q>4nBu14!MFYKjBFKe/W\JTi*cRi8paa@YS4BEcap1l@c8PPul$nb$\d#F^QN$Q
/n>dBP ##ciKL%!wtEbteXnW+:hFLEW$L?k#T+<i!@alh*D=u:>+TP1atdai\@B>^GNN:8m^lyV>*k9w1dupGI9
EC?&Fu mBjd=YwLu>ZVT*R%PpSPPXkPy/Wpjql?!^BaPc$=j9$4>GCj:pl9QA/DZ^JQ#6QlKbcY#TbR%89MBTmh
e+yyS1 %nq1J=yXylGeM+t#Bm6/%%Mw!Myl^#wT<ClltLydQjk%&nuVpde<j@/#MhTB$\TDSPhJ\n<b@9T8tHY^
wh*HB$ TqSh=NNCcYV8:&M+bZmbQBn9yRB:iFkJVqEHVt8CmqY\a:*meGK:&^T6u44\QE%IaBWik^#:iM6/iJ5e
M<RlG9 WtQ6e4P!I^?l*u=I@#>bhd%ad6T\y6IEWMj^*LCLJ?#wuq\i\m@YeTZn5H>Q5MTK/=J$!pK^$$=$=P#\
kku*HH P&PidK4V%1B411p*DYZmVMQ&=GN@4=8+JYyXDET>pJG?5<S4=IJwi=JhTanWYj%GJm6V4<E*?\^RDJ5h
LcYID^ <>l!:$Mq:t%pN%eY=54Q^DMKqeHlHY+Hh99>S5#+AZ8h*F6FSZT#Ka9kTt8FGWJ#4C=XGan*MmSYh%%9
<y6SPN p4e8%Zhq?9TaHHY9Xqh4K:%MKy8@aa>LJk!#4Ju%C9\DKd5/CMEtD1PmEM&pkMK\%Vt=cS*6qFp&4ubR
Wak9+C nTw5lm!!iy%i<dYqQu!Lba:4mAHdFN5@pqk1N1:HTp>@SL%SS4d85*Da=K<%S+a@MY69Emj@i>jpG+Cu
w1S1l* J\9Fb\NFBWYbbhYt?9/h@wFahq?wh5BGSA\@&DV^upc>LR4lX5@J$8m9yT=XD##YE6iE9&/Z&?9puE6%
Y99:eL aDC%TVG5blWiE5t\N>#uaul>bDB&MbkF\9C:P#P41jLAGW@Y\p+bQ+#>aTd*MllQRh@HqX%9IE@L5XX6
DyEY5Q %1%JYtCpSX$GCTjG6A</SlByGM$iQ#NnkqFbNd%d>4XQ@w1t8MFS5<bmt\<#J<5R=L<#\+bq5>*PRRcK
\AhYW< >?9huSbIl:n@kFGFlWTP>FSWiE?=TlN>Yt^*8%*=lDmVCVE4JVV8HI6K/WP+XN&ml%%5d%JcVXZ^cu8#
$MZ8:C AZ@Bw=/:J:M84yhKedBcZq/RFW=XT:?bjKtF+:h!#C^NnqQM++=nPwice8R$tk\I<BN^iy^%5WdGbp!N
/:5qCt eRNRbe:cXIdEy\6S=wR!^yyj\X@WEM@mYpj<WbEJ6GYm>hG^?C8HYFuIeMN&BqTYd@ZPRnF\MC4G=NN>
4ZFaHt i8!HD/8m8N$JS>9?Xt>qqVBVSN5%JP<P!yC1b*h+<%apVly\tZRbY$SM#l8FW:!WFYCwPudaQcy:m4@i
EDSIML dG/&ppbBVCENn1VZqF@FZ+ZA:ib+NHhX<=4415:c6+54a@au/M@PPMceCY9KR9E=?JS:uc<=K8a%w?C$
VhmjYh HA9!mjBXWFHWlDD$Lnwh@nwMNl1GZ?I=$t5Dcu\+mny8w#1&uWD!X?yiE$eH8l1%dK?YShRjy8G8P5S1
yYLN^> S%Q5y*PQVd>8//cRW\/%LhHE/4W:1Ju#qHK*?+>p$Yi^KJ/LYn@1%/^FlJGAkKBPe1#i$SW<<HnA>H?>
8l9^hj YCu*!Fy>FuPIS?W&&F\9p%uFbT@n#5VY8:aMqIn<q5K9#>APaH+hyy^T^$ym<5NMb6HVFPhSNy%\CmA>
dMZ+5D w?mNYJXt4HK*BWGG?tH9y#qGL?BISHJ@cZ8CAyiiGn\y/lek584+teSj*c#Y\NbPCY51=@J%9&@!w9ny
:cYphB l^!dm8IQH?@9N\K+L!FhtG^:K/>!:F#AuKy5eqe<+#qnm!&hkLd^yQRua/9$?RwKVpqYF8ji\/+p9&/V
Yn9@!R WXMTZWnp%YG^lPJp%l5^/%X!&W6K$XKXF4ZV$S8jBbW+*qN=1a@&%Rd@M+eFEJ<\SdJSnm+4/l^Q&jhG
iuGwec atCquWL>%GkbZLHt%$Rb\!bA@Th5Z=qe5ZF4k$QD4SwjA:/MCYF/Tj=1T:uGH^11Nb\Qe*WqEk$AN#H+
=jENqX Tl#?yP&P4*wp^@/&&wN=9XVZ*P>y+S&auh+YLNMId?*l5Ly<aN8N4<Y@n@V%FA#FknH?wk/:B?9IiuP#
kuHdEV TWZV<n1bh+8FLLk1dndCHTR$nG>WnQbd4py:pXu&LZY8&w/ZVjQ?%Y:1LA^:<#yttKjM5KHK*qqJ*AWV
5k1Fqn e6*/WYh6=ct^\JBZ\9cujp4A1d<y84YBiM!IW8^n<H:K9^F@4iM9/PX*%Sync69H=X:/Ly?#kcIG+8hQ
jJ68yb e+<XahF>YV%Z8KyI^lbV9kY4$%%XNkVblIcXF*^>R*Qci*#BAE\N1=e&6tDX+pn5y$H+Yu%Z@HZ>wIp&
C+*%l/ JhdL=LDLT=mS%VDleMC^K!jGnpKT/Q$/L=5!c4MkJCS</JTdhk!W+4^&GnJNT!Qm4I!Np%$HKl<nSa!L
t:L?wt bq!yW/:Ae%Yj&iuM5QE^AuL!X^Jy>5DRPYW9=5N<G6pN:Z@Sa!MTj>Iei!nEPRY5ywRQNW<X4Rk51qL$
&RKC=A k>4c#:y/HC*+JSy<qXi=VCN?ca*4e$YRH^S5KFQmB?VS6eVj%PaIj@!NDJ*R<Rn>+qIwW:<j:SdliPF6
-A5\LQ 0000a3e09f600110334 Page 75 of binaries2.zip
b\AWV# :NG1y\8n#<MZ<#1eL?yGZ:=/B+5KijS44MqbSTLFYw9C:<:a&AF=It5CCb9$P?%6&BSC6thnCW6L+b=@
6YtG\& @YQJ58K9XbC@1mJE4e^YMS@8maqK9#<:LKc$DQ94ucnc!bj:4C^EQDm6iVa86QY55Y5Ry4lqe%SHA#BA
H66ZSp %y:%CD8/EAaFp&DT1pPJuh&6P8^YSwtye4yi4wR^e:FYbm@=p?XCBAQa%=C#lyaNkN$X#C1T<Y#<8Pu/
yLiZnc tnFNb4n@/ST#aYh*MwIud*dGQua:#mqC$D%@N!aik!%yT:MPn66*5$La*R94+JnD5y^a\>^u%YtV9^1?
iGbdul H\:d%C=5$lpC*dbY/SHjQ!EWX&4e%M$u9/W&k6!M/+Xe=VcFaF4X11SG@XRdJW@84d%yi4d?q6:c^YW@
u6HF?a tKXqRLF@pW6wGSam:GwaFy>hK5MZ8KDY\yX/>id1<95^+?a<Gq*!$RL^DkJt:#SW9NwWejS#>VPn^lb&
G:P<Hq 9yLqdY\aNn5C!HSwueGncty9=Z^QV9a<*I5wMLq#?AWh6nq#$MyweB4WS6u@V@+K\@cN%<Mi?n8ZN?hy
wTM8II \ZV/@L=T9qMlJ*6/NyBFybIWLR$JH5QKTALKt6GuJwnX+I+=i*6n6CwAc5J=#dD!:@F=Z/yT8ccX@$eH
9Fbmud lt5hVEk^jLQekLJNyw6Ci@9LL>>XE>^9\w+wujnPN$Vl>K5%HD*#/#CS\Cu4aH@e/Dmu!DSqC:8#L6da
<LX:AR uj9#hBlEan$ju1EmLq?HX#8bS1jR64N<&4bMdLlE%%<YDq9Q4/%NbA%H%iCJ=E6BSwnQ:?<?j*:YJ=M@
H5>#d* hbJD$yCFW&Ibd^L?ZHk1WiwnPDS6q$P\Gl#!p@c%^/aCdY^DHtFEkAIZpI1e&P6YS!9m%ZXK1DI4Zt^$
/9%DFS 5:NM:i59q%jj$iNkMH^$nQPSajk!%ZJ:WdeFHXaahly#W6kymNhPPX?*KTtM5\QKId?j=DdY&c=6nEdV
j:DnBn M8>$YVhy$4PBYhNNHAk5b?/1ZHQ$R@Yb1kH:mQ=H@LY1I:>YANGb:G4j^!Rea#PikDldJu&<cqpD<&!<
PijkHE 6PN^q/!TNN6\jcF>c5dPD/:9Du&5FlI?@EVF<a!DhG%&Ww:XPVE\E%8bPm&Y&=ShlR=XRSS46K>996M9
cP$MuR mY9tHaESJ%!<^cCyyClQ*:t?dPBk9Fq%QI^=/PtW%eM?uSmMdT@j^tInHwQ9#LlpQNiTddTylB&!9y4<
iliI^+ $nt%y@FAyl>MA<CFPtjh5wbyNL<T?NJaEX=d&hS!G8&REBcFI#w4E@ZVnlieTYXXpJXR8X4$\A*deY&u
K>lR6b WkL&Qyw@!@QyBKymIq>69N1CqXR?@::Ynb&AE/YFZat*dt?&%<tW1<Wc5CcytqKV<#&:Rwl^lLi8X#I6
EK4eBh Eiw^kk=piVpMeZp+A/>N&juXcCMJmy&Ny@pBRPc9>4R%W9G<dtXHalnDaeaDk@\KeW#6FiKy+L\>wNtW
hS=ND@ yZpJl&&NhX9+%mAbaNi9ZAI*FPi$J@Hw$AFWCwMi/<$tRtD9kCC9uMj6/$Q%yWTTFSaiV5=+5<DNqE*e
t:e9qW Yy8<>h=dN*%e>qieJ5w#SA^d/ZDmeaM>4NVCMp/W6qZ#1+!dj4tYH5j*4uL!d6MttupuCkc:h/Y&#b!:
jWp8LJ h#uqqS8LInc8D^&Ry<Cje4GZe<WEqc*Z^X$dXnYFA6*ZWwCDwLm9Dl:8eI&Sm<hEe1:$8p6%:aS9PXt*
<k+Zdy TCqS&&QJ4*Z<4CXYE=4l$8bt%yQhDE++mtb?XaF:hXiyX$Xy8ckl*\1XSh&jmtY4J/\\K89d8kDdhWm8
YM8beH <Yh/+pi%V#\KZB?QkYHmnlVGMmP?VwFaZqMJqjK4WFXLn?MDSJ#w5anCH!*i:WXJQyZ#Tnc8n^ya#ZGe
^hmZFX VamuW^==5>1a#*jC^I*%%HF59bP$m<h&4iXW$^Q^iDZ$q8&Cb\&Z4:B5nIQ64jy1ZjI=4$m\PlbFcqiV
<5Q>N$ kuBmBGSBB:1N#lXIWbqleHEYmi*k&NGde@EuneBC:!I?!%!4<X*wa\$<^iX8>6wGV#*>NaVtwKmH#@XT
=pRb1D H4+wH\\ynNhd&iuedDVH/qyuLR#pd:=jZF\+<eZS$15hhX$JLX^/6aEyTkp&Pq@HH$Q^tLtw<j@atb$q
=C81w\ a++V^*#Nd5>W\:L=S5c?TX8FayH9SJb?$N^nahQPJ8jK<jtpqkX^c\*wJyl=!^y^8M:p*Cw$YA&K%9DZ
LKp?ww 9GFDkt$AmNIJW\GTTZFR=jKwlClCcAGE\+/Xet65h=mJB9/XFVE=G1JCBy$pK?IT4a/Ybi1\i\X@4%A?
T4T!N? LVdLqXdGPq=Mlu*#:ZmMPV?Q8Z^Nh:!WbXN/KhY1Hmd!C/cRdw<qD1*1Jy+eE#PhudHHjMKSy&Ik1\a^
Np8<C/ jPEQaLBh/DSTa58aJjAV$jq\q!jwlyI#BdRmXJ+SabHlpZG+yqhwXTZ+nL^>Hd$A6$pc&G=dZ5!C/%q@
6l15:5 <AeXSSEyTGN=EZp==Syw%DDQ!Yi=XuCRJJ?XZAIAG5T<E&IM<kRmCd!&PuLmik9E1a\T^X<*T@Zh>QH%
qW:h&? <91:Z9dFl8:C<!!b+YV!?c=kWYy:daBIJ6N^uJ^kin#N<DDbcNE4+nHkmiPay%kjkYQ$atDkJkj5D%+N
l<ZJ4n ?^nS64n5Z\NF+kJdEwqLw<cQmAq@4cuJR^Ea+M@^ebj#c?cF9ZJV1Pki$Ha/jlB&LVGy<J\JiXKykk8X
kIemw6 YFcF\\&ab?&!C=H=iKK%c$DeGiuNaiiLcdK:!>e84R/9eHR&5WWZ8=Z?XXH?!#h&>i/dHP=iai4F:qc$
JZPX1! uub%LFTk&J5^TpI6kb=:tuLLVuPIaqBQ^=#aKRw!?etG>Z:dbY1uHaYbKa5Z=dBy^i5@?6FhVS:I*JYX
>Le^y& #D:>\JMXWl#G:W<<B%14uPm9Zu>:*EpQ#HJa@n+yR$EN1^\:apb^&QTS!M8X=M\16ZJ4jiw$M&8d9&*C
WKiJ!M 9H/e>k\icVX4wdhaB:&FZMP5uD1yYXjLt?<Bj4E\HJAJwWyIb4*hbYeN4ji9&V:HE8^yuJp%9\A+Ebaa
kGHA@/ j#5uWB!H#K!>qde#5\:t4db:6dLJPQ8JhQtJ9#:DV^E6Nc<i<Lb/8jn<WwQkaP/\SBX*8ikHIdP/>JYP
%&?SIG SC66DIVFT/XMAy*TF>+@FZLi>pYGj:NNRQ*n=L@JIZYeSRXAC\^tyHjH$\kZG\A#KTRG&Q?NDw&ZN#w9
5QFd^! bCyF\!w4YF9pZMyP?N%?X*6yVwh>:Yd?Pq1CDj:LKh@aldiPy&tYad@t/Aud!*T=KnBn:G9jp@^nMQyW
l9WKS: $qd$^m&S/W@QbG*%qXV*\t\pXa*aReJp?Vj@W%E&\Qa=dZ*t4:$!qDkPtqM8+a*VaScWm1YiEhK/9SLQ
4TPh^a F54lISTH1hW5^I54=S5XAEldTKQXEK*X<X!*M?$w?:n^6\$9/ZWyWinnjTuVh!Gqp:ITcPt$Ywyk!%yA
b@Th&d E=9%G#c4qq&QHA<dV:I8?*hFcYB:L$^SEH>%:@NF:DTN8YGntdWqV%+/=hHaBaH::8#FMGdypRty+m#L
>JA4GT p9N4:>1GQ@Fb#Z?YY@tcI1W!R4+Wj@e4Me8?^Pba$FjjHwjHWMAdB=MZKbFhyX=/$ZLtSaD=L!Z9nP9D
#GpGtd kSR<nNRqku=N6jRR=?YCl^5:CFk%QVjKP8JYq<jt4^Ve1c=l6>8H6TSa?C98h6b9HQ5CTyukkqLQZRnT
kGTFK6 hTe*ZdZQ>Qy<Qt#5EltlV&DXj8K9$!q\VqaRV$PtcSea^dmu5cX4H#hBw%XNHA?@&n1wd>4#F>&LAuCk
9N>P?9 %a&Y1dY\hT8d<>@j/DqRuj%%eMIR4EIqWky/VbPZ+X%9^&K\tN^c/Nc:SP+4DpaBZi=L:89A!K<q$FtC
AP!?!n >aR/1/NMXD5mMZ1tWwtq^dK:S>bNmL@4c>bM5b$L6IRJl!\Ep%N5>!W8jYqWQwqjAX8Dicc+d>cVn6MM
lT$\XF tJmj^w/uGBI:k/J#^86$In4bd5dE%H5^VMnW=QT$kTZ=\dRR%$J#cd!\^JIwhhW@@KQBH4*>d&$BG*V#
ki$GM@ SGhE4Bq++1+4d/F6l9u&h11I8*F>yGV4i5<EY*CM#M$C%:C6<Y&k?QjXiy=k!b#9FPHpjJEb5Z4y!1/5
+9<6Y# Xq8ytY^qw%dXX#a+!c\AZP&WS6#ntpMI#HZ<P=&Q@@PdDp6MXlyu?ZZW+ebkbQEGXZ4NHHdInawXWyD%
FE6=G5 bYl@>Hw@Xp/eN+Ga>/W86ce<pJB5@:j@VGKwP8>*@W:T&6ey*$jJQweahJDyk\@4C:pK\b:EF#!Fc4AE
aVi?+e k!NajDb#FHPY686@>5Ku14nY5+m=+lELRy*E5KmYXwwmZpuNbPZ9^XFHEpeMlVta8N^Ieq$e>n4H=4jh
K?Hj@E wcendW+&Hb+NuYa5$/eby<nJywqbZw+4AJn&%b6%EyS&JlS5w?GM1><a>GcFW=<XV%Lea5RpHW/B1dpV
k!YPnV CB:?/j?W4*yiN:X$**+tD?EDW*upX=$Q%!&ulNKtq4!!PH56D$w+YuMjw*?@4dQVcS8w&j9#%>=/e9Vl
ec/h?8 iD\\=5uuF+V+k&:u5Ni=iZN$=nhmZ!:!IH!yAMuqZyuK:h98ma:M6yI5ld@tpZliNlu49?>t=#Z^NLm1
W=EQ5\ uB@cIYX!WMGF#=DyCdmm??D61#W/MXJ%EE#N9diPX9EDeRQ5@9DH9G/m^q1X%SKPRe?ETMe#j!*I\jLZ
KTWuIJ ZwyDRdyT=9ucHmP<<9@^X\et<m4NYG$Q>Fhi\GybLQMIN&c<j<^#/&aykq5FJS\dumJbpYmwu=!WNyjV
=elb<a 5W+i=#9VFFq&P5$m<c\tN1%u@ubh!8\+juJ%/LQ<&8Z+#L^\<l<Gtb6J4!+!SQ@?d^eZj\FRT\MEFAAC
1A?Bj+ AAkA+FX6Je+HYGYcH\AAbn$AADWAAABndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9at%\e!>tetXq
@jmDj8 h&F!bT>#cYSqatF!LtJ6eKX:#+@n%y$uqc4P$BkDpbynDIW>nB8=>LG$SEATuEYeSePyR!<tnX=MNMAi
V/wHWK >nDb/pP\cC?Diw>twa55T9$i#aJ6LVNLCn#+&D=8IBkpIRR&FkNW*ZLdGYD?kQb6M<lBDe^B?@p?W9Yn
\h@tbX b!=^5TSTw6:ujZ@@iCV4Q@/u@@ajNLWh+@$Rd+:*@pDVB61?P9@:9>T86tH@:4bI9dRw/k:$l\@jjQMN
N9/t\m nuSt1%:ch65h/I>PaYhP#XnmFW5>n1YW>I/p%QEu=WP<HZy@Iw@pT!upM@GTH@%*\a=i5GN&jBi5jG<?
=@a5Y% u$6#Py$VMCakwLKdRew#8h8i$R=RdCi9n>uF$VGj^9HeuM6+byy/%ANpyCn*e<npC9/TQ=QHJ<heZL!R
8KwhQ4 :IlLe\/iu<kT9#&Xe<Amcewd$PRGYE4?<ymJV>p^j!HE$bN=QAh/?yQ+#:A*heY5Q4%H<pbK/KVn@BPF
\GBX8Z QbL!?LY+EK@bC<:q$#t+nu<m?/EpL9Rt:$pF%H6/u/n*M!GQ^DQ??8n%^i5n\b@Mu$/uyluH$hNyHEWt
!:NL9A WhdBAGk4bi9ZiG\98hIZA@AFj!%HwD8hQyuLYR^X##AWbQWb:Zd1Q48YYB#Jw!Q=LZ9>?8IFj!Ju:<u+
5!PW8m b@QwCWcd>?KIGCbnDTTl>T8NjhtDBd&Pn^t:aLCRie?Eqe*yp\/uE?M/tDa:huiY/<DHWNi*4=pRL%/I
Qj&BT1 J!A^@SqkM%Pj^4w=\HjMah=#qLGm*qeiPn8NCRu9PGc9n>kL<#*<aZ5CB8=BXJCeRGepkBqhP>pN\tD/
IZ@W*S /PlV^q/#YG%VnL\H6\cG$IDFWei@:Hjp%\=SqeijknI:k1H8knYu><C9jQI#5A!+Qwkk<MNP:wEK4<=F
Cni&qH Hq/^LiCNu&LHGEV>!h\eRXDcMHwWAWMByi@N#$^waCi#p!k\q<iemY<l:\8FmKdDiHyQ%><D4:w$mP$B
-A*:Fl 0007b3e9de900110334 Page 76 of binaries2.zip
Hkwa8R y6tLqch$S8wIm!@BNViE?FT\%!ab!Z\9jwK@PRVXa%Mj^Iqypyk//j5/y4?W4^KA++Y^c6kL\bS=SyGy
^%Y8%$ t@wVyVcTF$JHI*^PmPe8lX^uken!4N!!\LT!LRlVNM^wB6QBC*LIQjNBqBBb5>Q$GjVMdSt:AH1YPH:B
mVDdDX +8nZGDk%@@P9l$CZWNQa^e8N\d8ybmLG?&CCZ+$G=d@L1%^\t#HqXDFeiDRHeh%eLF$CV%\4QnQ*!PCh
@Y\=bT =D*Dt8c/qtZb<p<h%9pGdQR*Q%GbeqGPF9uCVjHPT:mIA<dNLkqFCCau$ZLD<y^wRAKD/u5Dcj+5M9@5
m%i>+G QjMhh#\y^^NnPSuHtD?QqcNFph\SnpeV\%ybpYc6BH5%ZqK1i\inwPaTIHiTL@K<#QQeVc*E*I98W%B$
EQtNIX &<kc4EA&$w!X<#HnT>hhK4a^ayGQ!u!eL!cn5Y9plLaw:aNt:Mnb&LXG+MXcTY$QHHQG:wK%<1Y:HM6:
VHw4Bu <V6Su418Ma/NQePcGGQD!K*e>TkN!4&<nMcY<jpi#1\eVX86^Ju?MX6cPhDn$y\PTND^$BkaI<N\4epC
*IS+me aNnDhcBCK#h!N^?:Pj!CFAW<a\#&hIu&YMP94u5\uECXa/CBkyG4*J9ABVGElltY/$dcHmqcmI?b8%!P
EK/w@! IWp?jACpP^!NSu9t!LIt++qqpB6+48hXLkFJ:*u8cAMQm9/VX^<4ZiZL^jJkAPP+B!MK?6FpMkK:ENCC
F*4GmM c9IY+J!kSN:yPWdtEK>IuW6*NBnm%=K!DZ\5HqnRqRZKtMK#Yw?R&DBCec!Ba=@bk6RMIaa@lDdGT#mI
\MyYIH mV\yDZN9AtpZ%8iJbc%Y1>d1KEjDkY5hcDy9FM<A==?@Q^\4pbb!GJY/PcHIM!#VMy*pKVliESRDEA4=
\pGR^E c1L6Wdamu+T+IH5A$ea$nRVLCaKiR6<!E6MAaSIaaM9W+BWVVbQbJ@:H:JYm8^kPS1+:wil#q%*TR?\e
jbh6w$ aQ@AMYGmXiWSXSLY6acc@p4c\4bBF+SHD$a@#E8qnTXFjS!=qLETMH+GLn\QqHN4kwby8jye$/t5CQ+^
>$eLeM uDJh89hHB$ya5yi^hCXSlahQHMe^uae8!Hw4uNa$m#lPEwCdX?IX9\5&EQ##k?EwS>nt^QLTRL:+$TTi
q8e%dy SAy9RRAQHH8pa*I@nbKAa$9jb\AHMZq9:w/ZMPCTyHcSZe^*VJQwG4GV4L#<N<=\D/w?WFDWBq8InAie
u?Wd?1 G@hHD=aWD@B6enJwFIRhcWBQXEtMqYhNI>kIm6dPXJeuyG&LX+W5:+?MpRYHY%C$K%Y:CbR>pcaDA#8G
nqm#iB a/G/tbbqS5T^cn&?=FLaWQhHB1I8Z/R1KydK9X$u@lHw1n>Vu5FbXD*T6K8YJ&G9^CimmCeQ+BtPLKBu
&?DLM= =jLY$uJLMm/AVyIR=!bX^plV=aWcQT+VpaqAnmanBE\lbSyVZKk<BhqA56iXa?1P?XAiRNFhIW?AqD:Q
Jh@tE! yDCMGLuJVPWWFa=eYlF*W!IGY#wkQkEZDyuZpVe&/NtanFCAyJ^@qa1$$#M5qn5$Hp1FmXH>uSl^kK\B
REBTTN yqWNV:k6$ARaE&Nm=Tt/Qb:K5nM\\XMRVWnYJHbm/GtR==Nhw$c8qjD$I?T$<VmX1bnLE8CeemF=1CXq
uyqYPq Dp$SZE>kYYRk<:1*hDkZwnTR%>!JuKdWE1S!wR!M:Jw:JWVFC<1PKHKlQ>XAPN$/AA1:A:d<!CI$kFP\
QR+Cuh QC@tI8&W%eLpDyqZKl%4TQC1yq&%indKIkwI*PyK<&Yc1#^8AY!T5JbMI?$B/iB1QhG6ZtTB4DSG8W&X
:lFdyC w9AC@b!KTW:?aW4!4+QBlIyG8&9DqbEph?VCek$*#t@RBT5AWuwp4tYTIN%b%J@5/9<PLKnAL<a^qmk!
bJ:eAI uT8/5JeKbM!RpGM=miW1Md1X%@YYaqLDGw@lX@SDQ\PKJ\lXHqa?=CHi!1w<\$y/ib&iMDE+Sy5lFdCW
1lnNEe ccCt:C1*XcWP?TYT#my9Ic@bYcu*pHqCql\6h&#kDaMl4:eaZ<H=dSBGXWHG55y4hlNFQmWHZNB$e\YN
6Sl6Sk ^tcJAIJmY*BhqiRK%5yh=Y>Fpb1BHHmSH!whI#ew>lH\Lkkn1#e$9+hm>l6EEclS@:GdI\Xh?CB$SYlV
b1^bH? G=V+8JlLR%pWbd6JEmj^aQCXi/Wn9B\%kWX1Gb5El88NFtWcR:u^mA4J!q1nAbWJFWKw:m%^:+Kh!%#X
WQDMwI bjL#TB61m:E=JX8WaB4q#<54ak@PVc=!c#qLaK4Kmt+$ANuTHM@l*KceGNTtYK5%$lHpyc*66HSD*WVX
unKAnE Y5a#PZl@eH<$ZyRt&hEeVX!+hP8=c^CDQ6H&YJS6Pn$quVQAPh^&MZ+YcaPD$ZlMHJRICPSi<9@Rc>iC
k4Jueb w\BTXF:=w>P=hyw1biZ!9&wwEKQ^cD#@EZu^BCWPH6%tTYNVNBDc8iWh=q\mGF\QLcYtVc#SAm^QT>My
E>?DJ/ a#qJDK669XXhCbFaI?1&BLH5JNe!V!9qYj>LG$+MIt6mDR&?+\u%lc6%+YWX5A/?XhJ&SL@Kenw@SMDq
yMk%ME :ZIE85m&!@FIRqptc4BlGF=ii&*h%I18Adw<TY/amCKJ&4&TM4A:Gm&YhN$BtnCW514RZutyD&tH%w1V
A%$mF@ w9!pX^kFdawPCAInneLPyGkV^au!HPyF+*tlZc<@5tmmHK6%:nlZm>J=Pw<S+$k!u&99YQqm6BklAWlW
T%E1\* 5ZITG:HZBp*V?m6nd#I\X1kFD91FHXtKY4hFXuBH6QbbE8F+:8TyFKBpiGHGQFbQjnl/AM%^A99ZuuWH
eYW\F% LHRqu!I%Xi+C!9IYC#L^W\wXdYAanqFqGc8!GQ*M=E>h#mXhHJGC4C!RFcFw?C*/HKwd:mIiLSD>hFq6
l9C&+# FE?5yKa6nQ@>/Q=>A:YQwWh^P9iC#FPA+Xn=c9G=yqZYAkbinPqcG@tG/*l&A@5Pnd*B!LK=ApQdDui/
ubeZek 9J4K5dLT+u5I$?XImV#BAe=^=6llGIVl+MHk@i>bN1M4Z##^lc1kBJ=TPpaiZC\>yQAqBM=H!<pC^SPN
@TF6m# qpM<?*9ceQDAE1\Dw\HtTtHE<>^1Eah8*1/RByaI^AZ\CCZ4#JF%pRYN61ehDD#&AtClbE%ANpEFt55+
!Z#cnI SdSB%y^$bwHyESJ&uCctt=SiYIjQl>wAH55WGC5Wc8uIQibkilyS4Y:h&FYJcVJCKECdTDNwT81kjk:w
iClK*i aA<4dY#RFw!eJB^TA%4PaTb4qd8@qqnXtGbJ%^#l$wcBhmEL5%BhA:Z5Dpy/>nq*SAJ@XqeZ+S$SZdhT
ZN\T:# *?ia6>8R8tAnhSZ%N$#^DDT$JY&P^lD%q1=RW6khI4%P#iuV5pVGpp:yww?XTd*?u*Sy>l%L5j!ckYj8
4B:d5& I^yJa415Pa%uM:151C/Sq6PucDNKpyi/MN?QmG\9LwHBN@w/Sje:a%Q!LPWjen/nmca^$pcbEkwlA4/<
i/DGV1 VqX=^Zbk8uLG8\R>l/I^\&GEGbA^pK/R4%K$p^ccHD9^@#iRk#&uD5MiVaV6X*dup/T5ccR!4ytTBNAW
5Y4*!H qB\V&hRipy4h4GbZlJXueyX%kFciPTj\6ISywYVH#yPW+nV1YG/VD9!mA$QVIqW!VwHapW&yX5Tp1=!1
$Gm^CY bwjNp&ah5m9TA8CREnTNX4tuI+9ZqCLdpla%X^G^QHB4#:jb>Tb+F^S@%%GY$$P!EF\qJ1wq?qVH=dJZ
W4l#Gy e488YN%#9TG\1G%1dj/PDIWCwVk\u$:L$pF=VQIp:/X>y%punR6pn*=NaKuMNCWVW&NYp8IkPiIkwXdR
1FHq?R WjXeG&SikALlhjJ8hwc1XWWm#=It:W8/:n+%W<S%+TB4AKtdFXcm#c1Fic@XliY9pCYu&pC?ydyRjCmy
B=%yIa bXCSbMFu<!SdF/9RK%dZ#uFKVDNje4A/XX!u/uI@#EN%ECbC6wK?Hc669LRN$iM^Iu#F>T6&J&#ZhbC1
@S:N/\ MEGc1pIlT>W&I?$kpX6b=c*YXhK5RtK/9tL/FbhKSuwyT=qw#bdTRTREnkZ#TnhBYTpc4@c8/P/&SNyh
J9\6>E WaKG$yR1DFXpEE:I\Iu9J</1Be/9my1S6t4F<muSSYXCVp1u!4TKZZmGTXuTcdC5S<8aXH/LdR$LK&yl
LMlyN$ l!V*kL^RF!Xc/9ayClAaFEC8q#RlV$14cb5G:q^+bN:iVy9@%:5YFZ4ah14iTqF\=mSLQP!!^IG<XSY$
PW^#JF /^SI\u%>qRJ&jjSWNZNAk&tpG?Te%pj?V=!<cXjN1t1cNdG:l5B%##VKG4jXuSkEW9w*T6q\b+nbYJbj
=MheCN e69>$9PCN1nh6qY\ubXa#:SD?bk$ViGLn&qTPKqZwP=+aCEIQL?G#F:u#:%HI^L=6!4Be+yFCmImnhlN
Ib4E<? 8bikq$V%<JJ%FXap5NKVi8<TABM1YZK!:>W!B/t1<SK:adcZYFXYbcHuIX?F4Ej9pkjh1CAAWnWbF/SV
\:^FP: epm@#i#Wl+*5yt11w1kKV*qpZjh$Z><JT=W<!il1S/uYS?1hT66CM!h5:nhwa?51chhbJqmu1b4^n^Xc
d\Bc9\ mlhI$/FW*p!EmT=QA#@^lCe!KDy9e9VRVXYSb>SK$^*lW/F/NZn%X>*cN%X8l5l49EwWDicw9T^\&:S&
d68&eQ P#WBm4cly$5X\pinF@CW<+Ipy/XwW\p:E\IhQ#yGqP?tXhFLWPwVFhQ1^knElTql*hIq&5=ZVipqqh&!
HySh!K MQC>#A<wnqb6:^1w?e^Z<bB\\d=XuW>D1X+I8$nSjZG45Y*JGwq$$/=DL<5CbX\Y<1dGK%V!TnD@LjGZ
Tn>e<G yQCQAQI&tbTb>Q\k=Fpw4HYY4w11!yX^RqHaT8NK*lCEBewcYyiGA1NEc%&ECL&m5WNiiAZCKFku4XJV
+AVdW< KB8j%VbZqn1XDyYw%<KYGaI%k>\B1!E<>#LJm6D*Ejq%FVRBkb8Ai!L^\!aW6jIMSA5PGXGFut*j>\8:
uNP@G% 4G8i\Bk%*DwLX151ZYe5#AVJ&9l9?qmCYny4&aRKE%=\\WFjeYiZna>EF\TkDBSQ\aajCmTjVPqKjCId
jb5#R$ =hmkn^j*pYI+9LaY\k>D9%*::R48WRW5kSJ>Rc4!qIP^P&GhkIIaaCWKbKK!ZEPB9EE*W&Xy?+i/RlBX
FHmH9W VX$$pFk$QP#4MD\bA>ZHX!DqeLleKLyy@hB9cykuYCM5RDyneJ^RbtR5kqA9:P<TAcX>\bw?NZBSFHdd
qT%>hD %5Wc4qGllqbX&MBMwBYC%b4BF=YSTG%hR1H\J4IdPE8G%N15Ck4H14B1VLS8\15W4&/N?4^Qt?R<hii5
M1?BJ4 AEM%CJ/5cP811GyM+IYITDnJt15kVtHal6i:@KYP!8QaBt:jIID1#K/<LIYNld9Cikh#m/=*RAM9aBN^
Q%n5!E XbNXh1m:L+/:D5P1Di8mSd<BeI69WAAN<mG#Zjlk8Td*by9N=tb64?&/SqMY6H=aBWGaAq#bFQq>91QF
F/lcHh n5l<^eNG9W>:cZHKh>6%kBLaI9FB!\E!yq>ZdXN$cFIXi618:#wFA8BVA15Ea%MM%bWj&1*9W?Km!tT9
XlXVmF M%=u?F*chkA8ECGh5na>hbXk9GAhItM$SS9aH11KV^c4Y/mLmNH!MGEmW%11c<m:AhuNcXj6c1>\Y<y6
VJHhYp !P8FT@^mq4BA:^GTJ>\Ft+1C%P**GdT?:tLWtZWIHci6D\n#+CT%nh+\CP\mXK558/BQje49LNT=F*JQ
bdSbHR F6TFdhe&9CMqm5kCBhRHb&N?\:A<k&Mwc>elD/<LP?l!<1F%l5yd5aI+DnFFVT:1\@RCthwQaPNGYau\
cM:&DF uZHR+hS&!ALYpwuRMeC<FjaFZYelVc>q=lewDBT4Ky+SHpKFCSQpW>mwNNSFqabb/5P%@DANR1VMAMp:
i#t&a? SGiGe?TdNJ=kwG^VC5%EWhH**&INY^PneI$Cl/c6de>VX^AEdWnERNbmDaHSl&GFu%Xa8w15WLaA+&$C
-AkWw$ 0002943216e00110334 Page 77 of binaries2.zip
Zl481q 11BX+S&5<SF6W&&uTA<&keqZTIEIC:68YKH&>he+GVBEZyWXeE?:4qLRLbSAE1+Jh^aED9&ca=a5a==a
a:C/wc ab$9aa?kd@MLbb#Al**\klJRW!t#WlqBbwPqA5T&^=1Y%+XQJm/+KtDKd^1Kw^16S+ntA!\kImX$^tpk
QMd5=w c<ImR@4qFZwIESbNpjwWRy*S\Dn5C=ZD#*#M8kb=YhkeaSRCLRkPlZDwKY$+bSeJZSRR=?58J<G6IDFK
=ANtS8 D+R9aPI:aCE6kRQ<$ZAWTS>XF%Y$Rm1CPtH4lu/pkKpVH\Kmynal?XaB#?AF6ASnwl>kCC=$B\ye%BW9
:+F@%1 pN$LkZkIKHiu4LDh$IcTWcTkRCty/khpSV>kFV14YmJDBZB>kQ&Ga5@H?1$INmAkWb<IX6l+X\JqVcDJ
$SK#Z* KnA>w1PwMS1eNI^GIQlYReCKIKPWcIhyKQIMYc4KAm?5t/LpWD>eMjSJ4JSVQ\c46>SSXWRB#RN=taB+
PH\!<= 4M=>9&KX#&pt?HPK?k/lA5aDcu:R#IFdMBYR?+AJB1EdcL8lZl^HG#p/1%K5tcle<\BG+8S$tB6kcl/K
PA45ww Fw#\C1^ZwtpKnlW4VSQRd\m<BBtZ\4ew+FhFkiJK+RnmIFSpN1J?nREF?C/cKwe+61TPEIbdkXY$k8AB
!a5Ij\ nKDJk#S\BInXRLa/1=GSRRabJEjIR*e8lIDCWpb#kT8+JqeqXM&R\4+qXP5uqBeSXSWqXbAyKq/mLlRy
4WTy?j hN+kdWISCCNYPL^\YCa=VpN*tRDQBYh&+Dhw6VAqA4GCp%Ht<j^MyFtK9A6hA6\ITJ^Tk!Qb#:pw@WI&
yK96S? Dam5tN$mqFBQ+J6BmD\M+:9eddlwtX4mpRl*\a1C&&m&5jB4!md:iabGFya9ZL?\@AAK^hpK#WGFQPt*
4#:Nc\ jqKqqHGkllZeD%#*m!K5tKYD6TDY#SZ#El?4M<^lP+ZnWG:Epm8l>Vm5ke$4WFGSI!R6^Q1XqXTZuyP<
d1jmKY ePmGq+>hcbR8>1XFc@nTKT$WC6@Hcy:!bFFKS/eLX/XDN$Me^$lmJ:Y\Yni^cnG6JDFBMucM&E&\e$#L
WAeFWy ^#pLGwiF?%6wy6T^=HdM9Vl&MMKIHA^NEn&PEwLF$u^I*=Qa6tJu+lmbZclXqcu4IJ4wMn1nJ+u&4AV:
<8tN4G $TS^JuG<S$<%JYjtjZMWJ*EE9p4uAX%YbR/WdA/mYEdSJI4Q/HG5kY:1i$qMV!LllI:9i#E>*wRVtCw?
Hd#Fj5 w@tN9cSMaT%/Mt\a$>Nt?pk>F*mjutpaS9hN\#SH&lBV+Ee6m8/Q#1IHA!IiDYLV1eYQiQq\mB>\alnl
yPDGSZ MIniH?kHPGC1/G!p/:y&wD<EL\Nhi\m&:pPc\RNhj&mlJ54pCZ:Z>RG>#IEEwakP&6/A&NC$+TAitVFh
Jk>ceK Wl1P>D%>El%IDaRVbI=!8@$>TQ:F>k&B668NB4bQ6%6<$V@dS656TP9d:YhdQ9nBhpNcQh%8wtk9\a1#
aYNbJ8 PN*?Z6P%#:b9RBma:b6B>Jp/^QHy>npt$e\@^@j6<$l5*$Db/pjhjHkZLE1eT#^H?k?I=*m:qch5AA\@
qBZG5= bXAKBkEV1?Hd=?bjdDi^d8BH6nEjakWa?MD1G5pLPdhdSk>$1WMe&\Vb@uPE8h/edn?KTX:HWV</JSwH
@p*h1C 8+Hwt!Ha*JmSXIQNYB&TlMl6eB/1?&jIbQ=+8*ZTyQ9S<pE*wI@SmMcb^ua46l9H&t:=hq8ty%9Mm*Gq
+b5GqG PkS1LkhaluM?S\jYpH=m?RQ5ycVQt:JWl\TnVpukn^Sw?<aB*Y%kj$%j4ID!JjT<adFBQ/ey:ZpmBA:M
/4mwKS KamLQ\A891Dlj!nwkGSM<&CbWcPaEncSZ/B>SRKBEtYbaD=Wc4Vk=iaN&:^yA?KAbX>5$PKm*>5!85JK
CEbY/h /+C6wmZFu/6LHGtAcm@LAkphm#!jq>V\JEm4&Q\/SVFE5R\b/l\!h$*aAM$D\#lSN9PA11GQ$c1P+R8K
9mLE6F PEQCap%BDS1n91tl%R4Amt+VCFeItXL/S1bQ1b=YkR\E!kGIaJjShJVX$S+FZ/QXwbJnF%mEF%>l#RE!
h#m8hH AXaj4pk^F%#P4p81/mqLWSZ4I9^H>Eu@lG:#c/1\VNXaMnJ/DP\+Kk<PZ#XWD8q$tFJXEim/\YyKbSSV
L&49L& \D!1^dwDq4lHZePmGZaD$/XAnjm=kuW%W^LVYWaA/pS1XedW#T\YdJS:pDaF&qpyW6kwqREcCBRm&9CF
WlCi4! Pt\al%1jk9ydYnFkR^PJGVJWc>:/lcP8R>GFudJMmdc/1qYYtB65we51cQEMA%J:m9/aG6wCtQ+^nLl:
X^I51\ y5Vyck^NyY+qq6*DHSKLh4S6YWDGSaeI\lqhpuT/=%G/G#J/LPtlNSuVmTSP8ljhbwuXwTZC\d>A#hKb
m+ShR/ IF<@mPSAtta$pAN/%FYuy&:y\W5eIu4w%D\+M+%a*T5^JF%V!KBpu@I@Qbec!+HK5@V\1hySNSnw*iP?
H>HZ>5 NJ>/b6cJ/Pp1^VW4wpn:w#a>Rl%8cEuV@JFIhh@kwe!wt?jcH:@y5bPS61L9kNWkNX%jwQ?TRBFD+hnZ
N:i6Vi 6WNN@\AqD\WKb@dyF!*/IKJVpj/>TNe??AA:dItW>X&\ajkeA<V%QbbVhXuylNHD:*V//ITJC*F^eZLP
#Q$=TI L!@q5&e9L<<FIQ1ik^@^+aKywi4KDIc!E!:p=cYk$bju<liZL^?j9*\$t<*Pb=iHn&cQjmpmKE6tIa8$
QSNGYQ @i/1?\#+p^N?euImLuHpM^JtJm@Qj*EyD&iHn@aj:S<?ul$?Qu^$CHwpd+k=YKj1m\6m<lmLn^j@q<%/
XG>qJG lV+/q*<>8@!y?4\Q=P#S*#:/ENkD=<elXQZ>Hm5WaZb!e9!QF:?/55c?jHb=iNFbFYRQ\jZ5p8lm?BA<
udMYP? >*TlFCakLD??/T?Hq@IZ#:yyDk<jQ==hQu1E<dFVE%*>t1=T:5ZF^W%@&j<yNBb%QF<T*e6HEMkBZen:
K56Jj& :tqQq$^#\T/\Z44qR>?Z#*y=CRjp*/PSmb#\q4\>tF*eh6Q>^?hZhD@<i@D<6/Su8p<=9MW#kT@EY<=:
Wc56V4 KI>&<yK1Dl>>A=:N#+n88#6hRe&eQP46!H4*ZKwS?whkGF#VE$SuM4^y*!N%:R*\=*&k:iViq^hZ<n+t
5My?Pd *\LhPKu9k4&yK@Z#PZmPhl@F::8#9a*/CS+V#+:JmP/>#W&>mlQ&kjwkL&c#@wjDw=61Q:#<l8VN*1aL
SB$AhC ^ZDYjjnq>iti=^*+$j@AKih4aqA@9YZQw=Q8!I??&b*/<JdX>tj\K>NEZjukTqe:c:Kh8FiuD!<?8Dum
AAD:9> eWTJR@uG8:jp%jb=4?X4>#1<:T$$+p^?$eZC<*<D8*>^hIQ8di!M+pn=^9h9!/9%^lVZQH@+Fq*RM8Y6
Z^R!bc GN#=at?Ru%:e$HMZC/!:@c*>m9V<a!Z96l9$8=:*9>4y:ISheH==I8X=S%jj1i?TjEQF+M=Gw5j&DP=V
T/G%pW :nyEkQAV&b*c9@^y6KN:%8i/H56PP?#9iq+j5+9uMBW@@@SeKB9y#*4j^LkaDikh5Dh=@q*9nPL=Xe#*
Tjj/dP 8i=m^@NqJ:i<>w%iX@4PSt@F@8G=jM8?9!Idmb6$h:?\#h5==?T&jd<Q^5+RC?G@mkZ>=C%j$S/L<>5n
tF!?D5 !K?p56GP=>*I6^QY9u!L:npuid@+N&IRhjA&$@1JEDhH/JhSS#jE=%6$*^Xhad%B>8K&46/hkc:n%EV*
TA:<A& N5>H1wLjPQQ5lF?IG@G4!^ubN?q<<md&eZ@J@DwP#nup9aE>Q:@<Q#k6XK:d9/c!j<m/+5@/jKAjZq!e
1d^M@$ 5$9&@6XW#!:@tl=Zh>AVptl@6Z8i+?L/W9*9GD8jSbJT41A?Ry:nV%IQ<bK1p!:y59yHFPcddtN9dbD$
a/A\*C uIL\p4d#q@>qN99qDNphLPu$qMEh5CFn*/Y6$=L8V5J*/Rq%EaadkQ*9kBZhZhtRjjSHR@?p:8>\\jYH
!mVIIK *VYXAh4IIV:SbSL%5i<4>h%lkHNwN8tPi^mi1q5K*X*:aKQinBWB^?IZ!$P/n18ic?NTTF1WCy#dhE?Q
?Welj9 jL%:\KC:M^j<C%MZ5ipKh@@GuuQ%Q=JM6b9F#u1khd1:uSn?A>n@4iKCL46!>ehwGWlAIw%9Au>FwAcS
wVy8DJ y1:8GIZ@eHWH=@ctkPy&@M%:mIB888eM8u5cYC#S/:hEd@e1cG%KAq?hW\>lhH@%%h<NWtlq?%j*5IRT
R1&j@b 8D>*Dj*@WE5DBBRAAkAIAPFXdTZ1yPt=&#AAABb?AAA&AAAAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5
kE%jGu dGX!L&J6eHM9buJqbZhletW9e&qpbYJleuk8at%\#Z%Ld?Nat1Wh+T+>AtM^Fqa5!4q#QCbFGWlTNWnS
LI8?iQ m:FuqXZAlPWBp6RAIkY$KT>11ndyCGA5^R^EBbCmF^&=:QEmHS54FmuFwy!@wl5G!4ty&M+@<b##jbiW
Q:1<lV =Hl$w+HPGL=EWTLQh<:*8QhT59^j@t9%j/@I>J@YXqci+QF@aq%dZXqbZTuK<j>:5nKjX5$1p+9%CP5b
5E!Znm %m85N*4I^edFeSjHZS^*d@S6S#l?lJ$nHD@C<cMdQjWM^<>\@A^Q#uD<:Ea9h+ZnX#l?liNZPHB%I^A4
4:VQ%> N#l?k?M*PH/D+#e*Cm9#Eha#4Fhad>RWdF#a+<IiF@c+5EjMk#$8:HFln\6:ZNknJ5MiF@c+5MiFQT:5
#&dYXn ES1\^+W>L8^^aa<Li$nNlV$8:HFln\6:ZNknhMWc#tha4:Di1AT\=\kGHAH5CBe?\pXEF4^+lJ$n&HME
VDZjD+ i+=kn$kFi+=k#^H5PaI>S:BH=IM>S:DuCQae\b+n&ENJn&DQEi\=kn%H5PeI>wnMwk!6+Z!F>Wcql#%u
KkP!?i 5PeM>y#BunQaI?/AQYi\=\^GuAH\DBeZF?GpM:#lDE@PaM<b:BG*\b+#&HMGi<=k#^u5wT9QaM<b:DtD
D?clHL QYi\=\#&mH9FT$hm!bZMN?y!&HMFi/=k#^Z58aI>Ekc\=\4&ZMGiK>l#BZ5pNGDQFi!=kn%ZMPRKwBI8
*pbWmk 8NkXV4#Ct/=\+A4&MIT8aM<X:LtCQXi\=\4&TFlJ^NBLXIdY*Gmw\b+d&HMDi&=k#\*5pjCDQVi\=\d&
+HpRmI *MCiG>knIRq:dtDQDi!=kV$*5EjCFQde\J+d&HMDi&=k#A%DGmA*8PANV4:BG&>+<Q@#/eDHnKWXHQk6
=\^JX9 LHn16\I<6u!hkwY6:uC@E*R/j5eQ8iMH\\AQad@VTV4DyNMja8wp@RRQYC<T#BjD!eZ$anLF:uR+?Z:!
L:Q*=Y @YjEdRY6Fl><5eHH$yK4<$t\AJybIpe/QpAFXm#we\Qp@6AjD5Nlb$BwwmdD!jCC&JPjkAl5\I/H+\Tw
<\SIu= h85kcPY\4Vw*npHB%ytDmkwGQmBj58$EakE+k&+IWP\CM?\VqySJ?KiJMy=!>*5kk!^RY*ZA6k=5d9Z1
AN1Ec/ B+/BcPZw4X8pFXya<:E#EN+AJX<AD+iRY4AutH?cAD9lhu!B?eA?AC4=EkqMZRwAT+BRu/P$qG!46a\5
8LnK!4 k8jaaRia@4DnD@$E<ERiG1XJGn\Xhn1eJwB\AXy9PWAtd?X4R&yl/9BS8D5b<u9aue#S<HJuKF4nEemJ
Y^eFch taj$:JCEy#KQEXi&MEXp6Y^aAMRDQkcA\&LuL6W>NcN%T&?Nd+q^Si?D8B<!5DwT$lM8G5kK?>MaCHZl
j*d\HR !!&\%d<AQFAkPBbMAW9pDJ^Qq>WPDT4<C$<VWy&eMb+Pp=<T\*aK=A6lJ/Da&IJ5I/T^c@5&>dbdkm^M
5&Ld#u IaASRjk9M^bpiL4DAA9^NJHaEy$qym@E5%NTup/yM/G+K4SNF>1?\mw:IMwBteWakdJ9BXma1h%lKmj?
KWI%A+ pF5N4iV:lF/hEQ6m?6N+RucEA%?Bb&RSZSam#AHBqY<RE%S4ndnq$B+!15pe/ApIA^Pk<P>$PL=Iywlw
-A:@=A 000a634a06e00110334 Page 78 of binaries2.zip
w*!IWw W9+yk=YbwLcC&pbTuih$#VH%84PW$Xu6apL=CjcVDmM4Wc*HlEd?n1hEuky5B6#K4YmJ!JkDR>B&PK5y
dK5:wL /t9SYdM6\=bMl5Ahcw=WV1Sk1<\ABtQtMIZ?dLl%k!bRAQ!DWduiMyjQRM$#P>5Z?XZ5%wKLyaaM/F*/
MKYV&Y iKm#/H!SIJX?T8BeVpAR^\1TLmc1Mh8TVawplG%d\<6&eMRl5ETYQZe^aTY8p+:+N<#+a9pi5PPj^tCL
/6w\iT 8KLAGqLeQ8KYyDY#lKF#REm@Dw%ylc%!P<w*1/ILcW!6R\GH=nKQki!WQH?cVMq+DL=%lSZkS&wBmT4d
D@P8b< A#J&BIm5dbZbZ>BcaSi!TRwZc=aTF8Sl<t*S8qP$1l9XIXFbN%SpARVnS/L!I<Mj$HW@$%nSetn5!aMB
byNnH! Z/klEq^D\=jiHhd8XK%t6dJldRD=/<tWTlP!L8/%5:B?qDNY%84Z#L>tS$DF!%ud%Xy1ITT\P!Ha%54Y
8dy?^V t4XlaYqY1>Xp#FwJ9uZd^BJbQ4Jdj#B<MheXy:^YL=j4=XK=ZG/WetRu+!yX^F+5tlyY/8SmecXW4ye<
ktZNeE c/NS6c1h/Zm+Q1cD/!1^uRW$5B=JZIq9:Zy=4dShKuP8!:bTLqq%k/#\LGbCPQM!ZM\pRnINPbk6dSi6
VeuTi+ ayWTd+!V&5y8%S>L8&DZ%djAB6FY@R@/qBKZ!*jL>dXT?i+&\aG<DhlG8X!^VGk=YpP^LMcYhkXawt8X
elXd#$ qWJ=w%kFcLW/>FhYCul5puD>pap1\TLJS<\nMmc@dTG/QihdB?NKw&SbhYe8>$IBM:ppHV&uXCyc>XKq
%qB<WX 88FXN=whpAh1%SpVh?*i>ud>5YI?atBBbRu^DI?4ieD1kt@JI1^qXb#M!?LyqnQuc*h<y%^!m/9Fc8XP
=Me6Aa BYR*E>+tIP?l\I:9qe64=i&%dRQNWMLcYm*QTbc*5X<1%dGW!\Vh4t^ZLM8%GyYYiqqcSc^%m/D:yZLD
yNtb5% 1qTKh?SNqY4F1#4?!8wKZh\en<eh4NQQlY6b>/*:!JB:\Jd<bSI>LFp8I%ilm=nYm=Z%T1XWJD^q4nS\
RZedlQ WT#XiSa>LPFa*h<1I8#\uyWXw8KNeGtuB6lN!N$bl+YXbK\/Y?Z:qkZwMyAb$4ZXapNTB:Dd^WK^iAjA
Hn&Y+@ JS6BWuI4qa%KuhlE4VSRk1\14q>yFiVIh1XwqSyYHauikPp<lEBmSK%9iy9X9/?64NVGuKbR?i>Iq:#L
=wZ6WE >@C5941Ke<8Re46eL1:i8cP\^hIhCM&J$BWZn\&Ailbp4BVZ9/l/FnWC5kYqLC\qkELtSwi*uc1d%h<&
y^ZPt\ !hwbJ\IM4P&@A>\c\GG!6dycAK#FwAX1WTh^dwYV:HF*w+F>m!pC^k?1*wNNup*pPllZ!6!nL^\HaIZ1
j:5:nJ d/8dZ/>mn=CH*N\9*!?V/Dc+*m8ZCA8tRC=d1<W:NeqwG>AX+X4QhK/RNue41H=XD+umXS5mQdmTKyIe
<KXeM^ !JYRHNhbLL=cyealbtFM9\w$y$iF%iI1#+bW4NW&1!kLGSyj:IB8SaY&5C%BSITKT>Thc9YLc9X?lZEM
hJGJWR $k$FSZT9@tb%lZb>DjnXDpEQqVA\:\GW+ZY9XkBhuI9TkMDc*u+pba!EZdcILl?KF6Y88B5YKd6Iw\hX
=KE?EB tSA&H8PwwZd#$RjwTyHNH<XiTR=qXy*9ESILw8ylajXPwek/cMG=XGCddSMkA/!P!+cw:tBjZF&9dNmP
196R4t /#l8m*R>IW!Qeta<kT^l&R+%!hwJ^?S:PAa!61\cbWF?XEAeFZCKm=w15q6+miWpELbP*TdnP4D4h4FT
+&#mNJ 5X&a+uAL6k>I&H6kWldI6q?k6Em!cyFp$VkhlpLa/G#+ql<XRdha6CRFJJ5#bMACPnB$AiyRiIK/JP#a
#*@8*^ D#!m*6?5cp^dRybk#QB1ka$lPkFl\1AmMKHLb1wZC<^VyG*bNj+&uM6%EKX*dhh6pVGS\h:BIh>^?Mwt
dal*=\ ?G/C6FjhEb&X:I4X1Fa5:nn5iaTR&dka\KNS5L*NCqGR?mCBIYn*Mw8RWjZAb%5jmH6lALm/VnbncmCL
IT$bL8 HtDh*ITLLaa^Yy<Kue\d&K9c9^\CYpHJ>:Ql6kiAd1>1Fc/#+yTM96ae8A^a>\B1%^uXL5BlAlewn\j:
bijHTN AbJwe@M?*Q\AdW?B1A!8/8y9Xqb4MqCD$ym?D:X!HI=H\cmh6ANVEKZYqM8bj*Np%E*+pdMpM=&c5iZm
kNk*L: P>:tA=c5L!ywuFbY%/X1XNab$R//HkpbJ&C55SWip8>wEL%AP!h<G?#DKNc>iZBbW444AemSh<5NkHbA
QG=SJV YB<du>5KCH>SbWNea?t8dyTq!X%hpS65GIcL%CChBXa:mRcGL6we=u^=:qkWM%Fbpi9A5/t\T&^IuL9a
cY>+mB hZ&A5wMZ&A/LF=4nGnSi1Wu@WwZ&E<MbnJQ^m@BFMGK:@lnAdQ#1RYN:#yiLRddK4t9apt>ANFLt:AAR
?8+Fu: wPlj/5#IEw*qqp8AQm%/<8yp5KZTEDpcqNdJ65+ccRYDwN%8#CpLItVtKq+PIHFhpdpS&IAbnYn#:aC/
iBlqwX ?<=K\bD6bAMZE>GT^mmXRA*5+uwJ\P6\4%XPAmAHL%\li1?5/**CmyeS!<DWBemB?*YkW4jI$%Y?NibS
@4F14< 6bHh9hYdiiJm$j1RT@BmXK!\G+QYHdY1NAlilBp!G!pmC%ulZKcZdXEc#N&k/T8?L<YckkPdbI9wnDl?
n<WF6: ^nnRRb4w#JI=Vq/$\/C$#l+dPlIwpn+^B^E*k<A+Gtn*LT8Dh6%AR#y\\pA>VMHyZkR&$wmXWhM*9/pG
DSL#>q udHR^$I+?j6\EL:\kR8!/?S4BWFC=GAWIM\Q/GkLhP<9I46%aS5Gwb9qWlb1j9CdXe:TwdQNLZIh1Pqw
:mmu<% HPNDdTKThqJpc!wh=HLhEqCFD8lyCVGF%RZAFSe9lhDaDd+&aW%+Rp9PawT65QB%aQn/TCSlLKnai^HW
n@<nt? $VXt%/uE$h+kGInT5tpH:TA+wM:*CJkBI:4CkIEeCFEJcQF+4WDZ45P%4yZj1P@+it6idu\RXncjC:e>
w^NlZq mE11M*H4=YARK1nI*B+EB:BMenlV8pyeKI$eepIHTp9yIHyBQ1e65MNBqS%BD9RPI8<CDHkH$RkNnJL$
>d^/Jc m!5/@BqIRGh<8j5CqB8NiX\JewN5jepqICw!S4eaZK!9X*qZASLM\$49t8clFcCC6JPk%K!WnM:%i1A1
<jH>>! c%B^w6J+&M=pj1DIAA:eDqLJCh$PaY8FA1wii*^IIW>php#lCLSthaa5tADuQRle9LSBuhECG4:>\Me&
u&>#n= \#iWA>iRSXwT8&4S8^LRVPY9k@Z%DaJcVR/bKplhX@H<:CPjRLNJdu^IZFHuekuRh<9%WnD\B+c5QL/R
l+Q4ZJ qa\D1#GQ4Py>Au>N:\4yIN#AbDXpuJcFqXAN55?jPwHiWk9p^mW8nlG1m$/+XZtMRYCj:!LhIIPZ>WBK
1&*e%I CRtVLYh$=S18*Bh5Iye:\N*hBE@L1*wXIQ6Nk>mSAt$?=B4tJSPZle:RGQ*Z8>8qNSZbJ&8D?WJlD&lL
*lt\w: I=ic\!K4G1B+ADaMEX/dt=5iiyD!A9$dhF!JKKIGAk>IhD*aEE6qa8?i6+je8?l1>H$\:99BQLK+5e8M
XwK%Cu L\+XRQR?&N/9knMciDBt9\u5R8BY1&KTS\XD%dtV=bEWT\a$yeaC*A&E+DbHNY9%MtB=A9u/l9BDDMC=
c?Jh@@ \:dZ=am:&lC?uw\TCI5GA1+tMQnT^!mVyqd+kRp1e?6TFP>*iD&/A*!>!9dhe1uqE*tkLk+C>B98\P8E
C:S>q9 S*#K+ImyhN?:Z=XSL*F>qtw$Ey6\MEdE1M$dDVmacHIuK<nA&jEAKE<a<wKX1m6D8MyccX68RbE#LLLb
qte!6P j6>BEc9Vk1APN@58PtEN5pYApY@Xc\1^4+QPSuWVZdyGyRKh4R$upBAKnIebkaH=CJNbnM9:dD=+R/L!
IcWSFi yLSYwwQy++FY9V5q1MDAInaV6w=8GH*4QbD^huY9T1X=VYh#A@*ICqZi+Q$F>c:=CE<?dVEdEj=#+WLw
JiT>uN elN9=j&B<yQTE>@@XpIL%Scn<NZ!*dZ!ZeAiBK&A#c:4wAjIRmnID&S6mw@D+LjX*#dwZEA*4cyE4WD+
9hX%*T SuI^I@CHkiIPKnJkh8G*8?W%Ri&nYTH1uejq^@A9aJ$DX\kDteAQnHi4$q>uWKMQA:yTK%p81=bCMySN
DpkKd& qSVmjY+HE5<wR%Z&%:EFab6<$dIAFWQV6SLw4kqjk?1:XLwlk$=T*6t6:t^KNpty4NR*iAMCwYZ!XEC%
T?>=bk LhLin14PP6!CN4\HXG&W%$yQAF5DZa+k:6!B<KlmFDq\D$Sw\HNpWZqkS9tA*jWi:KKLtDnESjZn*dY1
Bk#mKp qXYIWAm41$$bRT=JW&6Ja<:yedu<4Z?!8mK\yV6*%?/C<X*EqT6NR<B?yM$:l!WZ9pZq&H*k:ZyA>6CY
iH*lM^ ?^8XDXhc<$1%5iFK6IW=^R^=ILpqbhBq5\d*iqb=:dH>dR%^nJ=<yWn9Qq/41<+H$5MAe8kY/=Xmlh:>
JV%::Q \198:5n5^YnekF51EbyhuaA>GwRd\RPXPTjhpa+FlQcWd4Y^Xm/j<QaLi4cX$q*!Sc!%CP5kqcTI8R=G
w@BeK\ F@Z%C15XSic<=?%GcRLemq%bS:?a<S^16HXC=d!wNRMLLR&Fd5mCXLw4QY>wXc@eBhj68$@8\5G&SBaK
aC9c*8 NCknyC5McwcXwS96SZ6JYFuj\GFwWc!/%VCSnqTwRTYLMFZhk?ekjPBuD9c56jJnhAwLBbVN!lP\yaPj
G+K?ci PJSb^tSCGKt$D5L8k!y+:8\Cqb!nGB%VppWum=@aKK#RXqmJd6bwyyI@AN?AmA$l9L%YZ6X:RK=XMu#L
M^LWy^ n\M!%5CT$YiSq/>5:HqW8L8LJh:dnT1CKZ$:+c9RuhDWnhC$WTH>BjtA*BLC1B>Xc?%JiRWPbwP*9caB
$nyey+ @ZnNq5DC8ImkdA/hpk%ZXkEdR?Wi64HZY^hRykL+VyK^\CbKYQRPElF=KIH%uN&LB&^VQaFiY:8#k5E/
AS6dbe &F6kK*#949q%SlalMWSBSQQ?P=Vik<^^L>:6^jFi*ASS9W?!Z6&wI1F#bEqmVilE9j!=eAeHjebY$LJ+
IAiJXQ =+qCX<6Q%u+nw!8484&tlRNq1*Yk%TwMHJT#%TLCjh&6iJ/I*I&nZlS:FFp1V1H18iNpuHqa^EcjT5Zt
6KanbR HlPT!M>aP%k+/Pj66V6MaS/ADZY+F>Bq^lX:Ay#9FyFKh1ZmNQemWDYLW!#?l#5A^X#hCKdEHR8\8ql!
MWi8*W PR?6\eGA!Q=#:TMC8%yi&=d9w1FLkRIG!mlc&*jZ6t*#HdWmQ=J!wdP::nb:8/VcI&F!LemM5e1WH#I9
88wptj IE51k*LA+w#!jDD\Fdq%Z^QJ19+PaC5FBC8p@>$cNBc^T?\X*GYj<&+=SC$5XkD4NmPl!t&QmGnEXk9<
L5%Ql? FHD/byyP^5AGhKa%e*qIiQm:#$^/BkeHDnNy^!T^>V9&J6mJklHIyQJnkT/Z\L\i8wAWYMeNe=%n+LL=
*X:CXP LBRKZ1W=uW+u+&tTmyeQM#h*nI>SuA>pcR&w6Aiq8dYi4BFWGCQAu!lj6BII:#IT&HXal\H<hSDGEqXa
aZKQmh :BXy64EWN/1V/a\#pDY<=wu5\\aK*YLBRp<SP+!1HRFE>dC$<$>pXt*Jy4YT4eN6%&W$5+cEiYC6MBmq
lpV@a8 t+K&TtDBiJJKZQP8bF=FENJcN=DB#/G%V^i#Q>/+n#y6X:Ske:VLV^^K6lbw8Z*pWGnw@DXctFmmKw+I
wqy%FT !*94lSWWb/YLiV\bn^aTKlS+!cRDwtL+<>^@Bli#u$mc%u>5?T&B4lTBmIdj>buC4nVC+P6YHMwepHC$
ynTC&R F<eK!5<!$F?D\kw:VYapQE=Ge4h>ZnWS!%D=8V>w\aT?LdG%/hdpi\L!DeMku%&>1eG:bW&Z*5ZE$S%#
-AyEJd 000d93eedde00110334 Page 79 of binaries2.zip
jqp@py 8PjB8=LdwF5b#&c#cVw%!Im8!Zm^lJB^EQTbS=mjEh&%F::Fb:=ETekD/X=^^kCjjEuahcSDEcNPikJK
kLSQjh 6m6Y\$*H\qhkcaBTNm:YXB/\+SeH?<<J>\!#*?wL?wE9I>Akw!5>P@1+mWSC6WJW5RMSwSpMFBTdk4XB
wGYXy= &BS\ta?VKX!eT4p?NNH%&ZDbqZ*P51YlNjAFqjm=!kJdD#KlGe+a#KFYRYeGX4MZ:/%wYFFt!+6u/iW5
e\p8q/ uYY\VGNY4uT^qTBj=nC:YT%W4&h?9&YC15X8M/JhRA<pqGWDB#P8\Jji>b8lS>nj1H@SV>tLW$!#eSdV
d69#BV 4B>9^1le+8LDPh<Bk$1mY4/YC?A?wRZY%<ECXbd^WcnImK8t!I\4NKPc$CX!$ZJ*>/J$nHu&D+#1LLnG
\u4mu# dCXTmc&^mT8l!\cCPl>kLKnj$YXtGbG=PemEDnE*yVn#%wcQJ#Z&E$VwR6qFu<5D+Xe#wb^4uW=TRTa1
HdFi?J wQWPBqK+n?5CCR$VCCP*lK$k=:q4lKdM>C<IC>@tjkc:Y4KcP?ll16AyZV!Ziw1/qYw&^hIN+JlBRNtH
y?DPhH :=9G!eA8^uNkPySpG#K5uEDCcp9:A5A8Y8nudYKp=4%KSi1W5H@JTTP+Wtl>1HFFyb?#@hj+Ry$Gd+C4
4C*KTi !QN+4t6RBZLHG!$T+hGpTnSJEyW6nyT\:P&teW4Pa%Ciy^NTT<yHlJqhP\#=JX+qq\dtXyWpWE98ZdFY
:KNkt* HYVJT=GdkBSa$F%b#ia!?@AaGtK<6pMHe=t>atTB5ku4GeRi5ZFCPQcJjDDQamtdSG#qRTX*GX^hCB9C
y+A@N9 8SXGFe8^@uqP!h9DaPpBlPc+bVe%$+!yDMnLnQEW?miHw*ARt96n#+*c^H9P$M/<iyB^Zwk5tSBRAN%c
@nT@%^ @dJk8?Vy!jABw@AhB4RTVq?S:?W5<@Ga5RWZl@J^AkqL8$TR=$GR^hN!YDF@RdIyTt?Ii\elw/#b*ANJ
pF\MiJ :\9Aa1Att@SXuGbB@WwR@*J6qAb5i5ktYEdBAm!M=!t:WJ44kTHMLA1dWmab#AI4dB?R/w:T*SGhqjAq
M/L8hC Am5qa+%4BljL^?jC^dtD$N#c#/AG8e4bN6QbyhKwGwKtHRiW!+*tHu%Lma&Dh$>#wcu#yZw*W=4Iew>D
#$8j<6 m=cE<&DJ9\dcQYnZk:^aljM$at6E95V<k1WK#EHZA>>VM6b<a4&<^Q\Z:aaAX$w$/Idt5=6=HPYQ<&Lq
Bchiud buTdR4ebl1NRaF$WKSLGquXDha=jya1K$LyMldDEFw\R96KdNdj%u&5$Q<@JG9i!b6VdkSaN\HyN4>tM
MTnCe4 6IiGcK=+#F#!jCA46H/XGk@LFp*VK?E:4%65mAeTZaHlT?<PDGh?SqnQ%Y+DqLkC/+XlqCnjymiPqbLB
L+JhLl Ljtipt$56LYFIN@L&X<9FXk/<wK1Wn?jC>#PBV=wb$&?\Ibi5\ya*1TLRw?+DRHLb#\DT+SYV9l!Nlc/
D!qIt< q^S:^4IqlMPFV<tiB?&=d@Q/@N?!5mE!i&R5:k&dVhRRV<EMa=NH!9iQ19a4wZ\=$>BP^^Mh8kTtZk/M
YDw5+t Y*YqAY%b=5H5lp%B>TKRVWC/&aDti*NIjhS+@mE4$/@k*^pq94#?m=dymZcwE>Eb+k/Mt>8LAh*kT\$+
<FKN!Y GH&NAJlAnlBZI$B4GlE9k?V8u1Ab>+1Lyh6#PVQ6\*k!MWwHTcB?Ny>YKXN/8c&ketiDZS^SiheLmS6G
$DiTje IP5&F>n8CV=4^9>R14H^Mjw>q:P<e=6MJ>tIQDB6SF5@C5&<1/CmBd$diab9#HBGZEp+=@Fp=yk1R?w@
cDt<Ga C8aj^eYZy6jD&Q1HbDI%N=1EL>Cpc4d%I$u=AJl4I&nV8^:KE&Gd8*V9PMJGpnuQu$#4tP/NNbc#i5ti
waB<wq V>:j?t!+/8FEeyEqM#Kkby5>l6!li#&h\nmKStEcTtl:!:H5:WRT#T\hy:E&T/cnJ/M%qm%AVkp5a:Xw
=Mj9=k IB&><EWR#Su#IY^LKPNSkj=#BL/nJBd@i1/*ZDb&GM/ulQ=BpqhmPl*HlJXlE\I:BPG^MD=pXAM=EuLC
#/HI$n E\!BcSlHRTNp1SK/8&EWSTqY5YPB1e/SCT8#yQHl/DDKP4cZnK^RCM<+IAhj9X<<CkAQ9En=A4&Njip>
qXFXXn wm#C8*E#It!Im/uPi/a1G%l^4+c$yuEaH<dpK^%d1hReM%DymdaR!I\pCklJWRNF%!*tb8T1P:$wnk=H
jR5A$j w%n=i4hW*9FW=VV6ChiIe*w+Tk>q&DSq>bD:HQ^dqaV>YqRC8lpQL<JkNAeMI8^I=GtJQERkn>IaY/pl
/XFI<? &8V8LGY9WXnIlmBL!u\?qjHyJZE\Y8L6ykTDJq+:$6kY1LdM=C^HWC^eKbFSFI@GIA*FQTM#Ad5C&%Y/
V5mWGW +qnE\THPI1\GhM1Y/ZIY$15aP%ByhPZSwS/D:al!T@pXM!J=nEcMZ@AFKF=MpWeSWW$$#&XY8p#kmIBI
YEaS88 hHkF&S/dktu+l9C\*lXAeB%G+eKe!HapwL\ACR6h\1cA>\/B&=Q!*GXACYQq!yMPiRI\!StENdI+kynJ
ntX!&T +D8JNLdR*?IaMSc81iE:YnCEw!$SjBTQWyaPw*K$5<CaM5jEw<kmMiaWpcXn6ZVMJnkWXTE$?W:jRG5I
1SZM9: etlwS+I1bqC!mCjGdA!k<Sl<\>mLVFVFbB8y#KpIJLmbTDl*nHQH5Zd#NK:CR\/F^&dEl8mTPhI64<F<
8?W^HG mWtSMjp1lV+CT=$=/P^/i@Pk&8q/5YJt$I^?FI++#mw%8:YjDZepES$#jW%ZIE%SiGP5>CBTHwBeeXy5
aECPSw d6VkBGl=TP>GCKp>SBdE#4A>QyiaX:qba?DePQe9qRddEhpin5bn$^jRP\T^MCc4NBVRQC:ReWC1M!?<
MRp9?@ tN:hm#JEZdXL8+iZI?NmZpcdSYYMdn!4E?5!JAXndS/SXMSGFGkw^Jt^C59BLM:l=QF#RZJqYEqR<*GQ
WS:YJG aRcD8nByX*nHKnK&l&a$nwJwaEP!qN6N/P^tLjWCbPaiBCMIM:#DZY?Z^IS\V:l&lZMpwAK>6!8j8I!!
XhlwXS Z4^eBJ%L%k%tEq^+mQG\c5&&myT#=tRP1t^b=?k+$P*m$kk4=Y5cRcN&#?5BGWWFewltI^MkDBH\HYqk
tni:=j abaPkVRae8*$9Wt:\jKTNQutW>nM6+Dt:GH^VC:D1Jm#^Eie=8cL!lGB\Zme6SlV>uNJnd*QX>pI/=YM
Yi&$w+ e$SuVPkDkFCZM:Alc=R#>nVC^P$m^&:QSCWB^MZKq8$B5pi/I6TTVyRb!!5PI?YPpFccGS?q=w5jh:Lc
Y#tqM? *NYk$uqSdcBHi/dayWdyGZwY+q:Cn6V>VDCB9JSFCHLJnVGmi?!8>*BX^qWYX8yukVZy6ajaF68!MBHp
X5M/S% ^MCmjRHjXAt#e&@ab5nKZ6lt+cbbFM8%8<IK8\ch5H519BnXk>JwWqLGqy\6eVZT\GLdqqW#S6Cqkq:P
^8SSED RVPSJekBVL=5B49KVyC%NWSk5X?bRYN*L<+4HwyP#ueWyR#wpdu1K^t$#9tcQRn^K5iNJa$pu9imnKk<
=md^QW CuHbb:l%M:julYCejm=e4XiSNL9ycLqGGLWq9LXiyCL#Kh@Sk:6mXw&IPhSqQBN\ATWCcqi#Khap/$1X
m$FZj/ S5ctlm!SI<1in9KBiy#hJWkXdcbNk4#ia:?DH<=%GVME*P%tXhKA$l:#XKKQF8=JdLG9FTjBTAMLuV4V
Btq/8n c5\4/d!?LE<m56V/d4#Vt&Mw+W^85/M8aE9S&>tX&AyBPS^JAphEQl!b=myiLMy#eD\\+Nt/aH$by$nJ
Y:b&\w 8B8^Ym&\!\YHQ*hWcXKX\wc6>mEP&!c\tEYE%hwS=>D^E4mBJjJyHEN6>PHm$<nWb/Q\A4B=6m98ED>n
ID%1<J ^wR&PYp4Z:madJeJb^6/M#XE5^uS%aYuS=lVRG8b!KDke:IqQLqKDAAcj5c/l+a^GPYJlL/WIp9*R5DE
4p=:#T n=EAG1KLe#eYWIKjC9Sec6*8hmYT?hnhXd+wZC^iQdSGL!TSFBp/t\/J/W>FYtWY+Ba&$Bn#!>PZGQ^F
t$i5@D lP=F*T!8<^p>At&$CMw>Mw+^\E<p1EK/N9i\hNBF&nScB9ZaY+@MJu/J&MKkL#=FhGA>^jp>%dyHTK!W
6jN4%T j+>dS4:\*aFR9YCphaMFT%DF\#IKkiSkHbqA!tmmq:HAuPP#$:V*ppNPeE>jypVQBNiCkWRDVeIlwAWb
Xamb16 yPHb6kC#bSC!MpjyEp5DEu5bZEbcF%n/EyDcmy:TiED*nJ5lM!IMZ6X<ay*y^V*SYbYG!kI1ZCNBH!$:
WMRiYT NGcZ!mm5&KQIVJICy!N+P<XXRD4qT%+ZQL8T^yK?EhYZ<Qye8BnXt@1eSCc\1HcWlXP/AGK$uwQL$XRY
9e+d9T XkAy:4\CaGZI*MA:$eGD5I!#*Y/Mi6WDcIRM#MKKWVWT61NIue!LbeGVQ*C:E?%&ed%&NJ>+1$QSa/KQ
4/C?ia ^KBG/LW^p@Xi4KHqcXL%h5MkGpk$T?uISbb4Gb!qB$whT:uDWEB+e%#P\!M^PBLi&I4PpSh/\6p#5BGc
*l^Vh5 Jpb&V/6GIwTyM$@VC<TLtA9QJDqadu5!@FLNBT@puRj%PIZG=Eb6n:iBCK%&N9php>=i%Jc^QiFGCdXN
E+<VZP ST8=VMb:tdbwSiTI?a@KwNClWw:EbcHT^5!dEyR/Wtm^RJBD^JXp4#KYG4&IPa1YJ*/uDaZa>DTInT&8
lYd#YW %lB*l@u:R^XinkMN!wTmiRnG9Lty:aJl4C:YAQpkcmRT<#8LZhbmLJH$!tGIb!JNd5PM#LtyWw^/KFFi
ucChpN =t*a:5XEDdI<E51S#41=NaEcLP>GKIRAq/KLqwALZtGMm/clRSj>iBCwcIE<E+h<l>hP&qpjT@Yi\!4l
>l*dbl $Y&?/FPBaC<T4q$?\$Ja:P#\Qi%ecSGd@VCW!T:6a^Qe*WYESRbT:=YNNJXDSVe*4mK>5cN$h/KMGd8L
*\6FXa WVeDqJck!\K%I/!nIMQG/&\JyVT#^Wj!hqtJEFd<G%FCJmc!lcMplbtC:BITq$a\V^Bq#dJyl!:aMY<K
\uabV= <6NIFJ!qWKFweehLNP%+I%R1ytS#NJA:hT^%dZMj1^%tkQqmpLWpLS!VJ!!SVTa9#peZl:$h?Ib^#cwb
dE86N+ >#+ZdwVMJTSmu:jbWVaV/mN+e9?Z8*JD&lT<6q!#1R<G4eH>6nGwLZQI%@qBmNR4<WDZ9B%^%YMRS>Ii
M#MncI DSSY=uD?GPqBN&m&khYYHA^^LVhC%a?kAk+*k$dw!58cwHIEtHmL&?RZL!J9iWdJk!!IKim1H!4+C1NQ
!%>*<l >HPWWL>inwuandClV>#RnbwN<uG#TcCd:j^=>uW6IB9A$G5&ZV:EpDtmM>8ljyM5u@l*i9#dH@&GN:<y
1NjtZa cT:q!lNHL&6AHjN/b8H<@a+=:Hu!mT&@>WFpcWbi1G<D?b$<@kYRYPC$>M8D@KNm@bWie^Z?Hd8hZ^nQ
4SE\6H #R@c8Hb&RN@9tCh1XTmw?1RJh$mSI69A@CJNT@:RpV>FaD8?@8^V@kNJ49+tk@\?E8DNW>88Fjt/HCG1
?T1n!Z dSi!E>REa:Ac=DyN%^5^4N4<tw:<&FTNy?8QmtE@a+LL%I1%@HiSdP\ZFJuW5c?#9c:Q5!NPWh=iFQLt
hB\&X1 b+&KVt%h96*KqwCjXjp?wYyEqy@Z15qmLCnYBCy@yye%Q^FX4BX11%nXcKIYiER+4#9&X#nBIPM<KEQK
!J:/\* #T:4G#<WhAY&J5mPZe9u4+R6LqSRAa1CW%DGwwZCQqSVcIdNb*KG@EmK#Y9\9dYmHK%B>/byP$LILFjH
J\Vj>D CVWDKWnC*m@wbR9WkH?cn#jm<pZnAu:u?cHAFQqtj9N/qi@Bc=VGKhn46LkR?AJL>p*YEVSh\h6*tGwG
&VJ\%1 q98?mq:$?iVhDP<Z&iX>Q@84R5aJ<CRy<JnC&QdQQKIu&DW?ThXbny:=%1jFIB!J$I%w>p=QjklDc+JL
-Anw49 000679b8e7d00110334 Page 80 of binaries2.zip
*C\Sh1 &J1h9DPV\=l%5til?u+tCD\RpK>nZ&b9tNEM9y#RNWm!:IYkJmu&8ZDbb&GH$?lM#^qeY+TX*YV&<?^N
V!M/yB #iCM@LiZ%#PB%a5F/klGR9A8^/Yb*BqJ>Lq/=8Z5d#PBDTN%5QI6CGH%d&DuF*1V9ppu>JQk#Gb+?5dJ
/V!hq@ LybNPj>*hpyH&5dbm8PaM&inGi6amA/IBHSD#ynlZXqe#jkVt$/!eGF#6yGLBTl:e1uZ4/5l>SCd9?X9
t@\@9? %!I?Q=NjJJKtY@m?NWj>\6!Lh1AMB!R\a<pZk$K=Gy/P?P\ZCtk5CXK%uu#bHJn4wB&YM%N=H*KZK9e$
e>%wib 5nLJA9+/Z:cQhwHHj^a@+iT&ZJhIM*:yVA=L+6D1qG?a$&K#cZdVhnNKe&&pS^%L=#jnT@ZlSV@D=bTh
ya!lVq K>>RDa^=5<l66!NSnS^W*!A\:qLeh6R\8!N9L8ldktIGZ&Id*Np5=Lj%*<=t9+^t:?VLBG%SW:>hkK+^
E&#Q>X ?d$haRi:d>?>jh5Pju+:c$h9L>??be<bm9#!<?nu6&>ujQL&=:e@u<:i!Sm6t\LmdTyD&t:e/$q@Q+y?
!#MaKC #8Jj@<Jw^A:PIDBjK8BH@Y&mamXm%nYZQjq&ThkYW!K#65$:84y&!c$uj#?D9S:@qkXhiSqy=dnwG/FQ
^S6eV6 l++Q9>ZRVwAp*&8IiPtkddCm4kEZM*C+QWhhlJPkqcEWRZ1CVd#VZp?PSh*MLY<D8dL$c@p#HG*C55E!
=%AIP6 qPbpyc+dbIZ>:+LW:8dIMuBEn=$DFYlL!J/!:ZY:y>%8myGDyqMtHwhuL<kZa+qMSCE81Q>LLnwCEBEH
WGpe\d iMNI#<LB:y#1T@m\C?SSV<aL9c:R^AypIW<Z^$9nL^pYJwS61<aJ$X<RZTCARA5W4y$hF9tJ?VJVtJlh
\+M<in Jb!Cc#eX%NQib<Mq@S/%/M/XXtBMAm!\qFwDc^/5BqLpd&iH8?@QHKA#14yW6^ihG1FQ+=e<8A\4nF>E
HcEd%d L+LBC$TaAAiGib+utR*G4N!iQQVpt6$M8TebyKCu+8h8:!WiS6%dk*6?LTyatkTdT+daZ9mYqykXLh*X
@?NEeX i8<8SXi\ljEy\+!Ei&K4jBuIZS!y!N<//^ebd&$ZJ*jlY&J65<kZi^bH+HJV!BD8K8lLmc6<SMQ4?IEn
+qw^6L Q:w59*5atB>hdDu<&S:?MdA9Q?DVeq9/m8&:LjjACh^Q#M$kSHp&nE@yaYtXbFSTh:L^kA+X>JiSyY?<
jTt:W+ 6DkLV&1LS^%:+VXZj1E4?>Ww@pp49><kZw=pXdL=n=Xt9/Vb5p$*?8NV:d%*PM6#6nFnJw!NTQmWnH6I
hLiBM# 8KBY?@j<S\DwQ\t\H^4Gy$!yKQ\%@kpBj?4Yh@mHaiuycZ^/&p9>Z?i@H>RwNq!eA9V$ND*%j/%@8<DP
GBSBi> 5><MI$E>HiuB4hwHy9%<<@:$yY\j%8auQq^<De9DL@u1R::STC$8y5/jC^jVq+J/QL!?uuHJ=^u@+PDN
QunEBb >RTd!ZR!jVPhVQDIJb<8bJ=euE<\Z&DG$n@Hk4q@j6I@/jhQ@5>J@:k@ijPXAHQ$c*RY8q9>m#jZ5:>i
ZelIe> V@>=?p>aq!+>GYChuL??GF!<H9K!F=Q5&un+5j@5=Nu=!dPVa%tQn&WnK/j9n9i@\?d+=Nw^lJFKQ=B8
CG45I! l<@*L&aV@cpSL5eZe>TEqF=j>CiAQd@w9\cw9:@Fu!Qb&u1/j!!$jn^=>mNI+eu?$@%9>4>=?98u*?\V
NQJCtB <@ky6*@c@?:yu$<tG6I6l*!l6Enju%\9SQXYj+H\bQl/My!<H4+GY?#6L+jwN<euAH+GLe>Qn5>4m!<5
J=T+m& EQ:V<b??t<mLHJWyZ#:hPut#lH8!yDQY<\qSL!d::!jH%9E=@QmQ=D6b\N%ZWCQ#$?PuaqTNPpeT#@Li
hX#Qq? +>q%j=u9hAE=Pb>MIQTp@?G$jA1X?!h\:#LjE+MM^u</@8:Qjd:+JVI+nH:IhV:=y%u@a#4uej9S?9IN
ktyYBI SGb5ZT#kQn*Pyu$kQ@*#h**=?!\HBT5<#ZWG*$Yh#/iV&bLW!i9J=BNqda5Je*=<eX9unDAjqT<TKa^@
lWVd=@ !HYGj+i*?TJ6F:H:u/1A\9np>Z5/c#4S^:<ZJ#\W@?b<X$/8d?t<BC4B>iWuT?<^GW>8/Z!TM+dYkq6\
$kJd?Z jIuuX$dub>Q4\cLPM%cwJSjjXuu49ck?/b<9/Z^!9DB>h:\WX/iuQ^m?H<1nm\ZeJbR9u@Wu5?H1+1H9
5/&C\4 ?9%@uH\kj#QKJw>5/9#=eQM<Y54j8RH:jaP>>Py?H\p>8d/8LaZ$ij@mA*$qXFNFQ5@4XbVtijV5?9wn
M89hdT jS&V!>@ik8*9:?@:?$5P:m@F<*K$a?4Q/>XCHu&a4%:\65\u==MQbNX^@@!m>6F4IJ/@Ey%>E%itZjkw
F<Zubc Z?Q6^h+KBQ$R:pq@W96+jl>L9j1N6L@p1*H%+&!^d6\?1V>h^N%HA@\B*Kj>H#?Pm*Si1B9#>1k@Y<#j
%yTXT\ >/lMpmZ*wuq/*<4><$@\lhIZ66SJhmlQe@>C=?RVXZAJ>!qRJ?>d?Z8+@SN>j<&nRq+*VQ5:?^V8%9qp
Wi4iwm TZap>96<u@:+Kd/\*iS95Jm@!*H%EK%S8BSb5&ZbJ^@k!?^c4JNw^Bb4/>aF+&1LI\byF%L%:@W9m?*S
<9l#tD ^Y^b>?Qb%4LRMC^BX\Cd\WW@PS<PlwQ?5u@*EYdcq<88cW8:aPI==@8*bLFYwBj:blH*4@aT+R6VSjhQ
1YE^+i GN9uF+u$Z=h^$jNbnQw9Z?>48:DaDkLw*iJ:#5F*$cZu5@/6^ph1h+&X>PV<QDq@*d?+ne6?#&LNu*!q
qSmA$8 iSR5=hG9nb6?WPj#/>t$6qTnb:jV5h@*6:J>Nku><?F!ZQ$IR:aY+$#d@cY/AWL9FmMWR/KqWjQ=>N4?
+X*pBS SGeDVW:@6u?*64=e85d?^Qk*8PZjn>hJnCa\mQu$EQPdQkbHu<4jp!^@d<Z#8$@WTZcu4#<>T6/u%J@A
YM9GwH 4S%4u@?&#6j9pp>ep/QB/$@hAJEt?XN<n@8T9#ZuZ/<#w819d/d@NJ6>kp&jR:d?>KQ91J$jL>ZJZPi@
a<TEmQ @jJS9mi9\Sd#>WiB\ScnSdVKH&**MYk#+#L$a?QVj+ZPdQW^<9+4^6:Z9*#R^%9jutPkPkDnN@5j5/69
JDPdDG eG8PG+VyHQjb*#/C8<>cnJH+t!qH@he#?\Nh9*MbK&I#?YC!dTHtnu@W\hPY/=68*cp$QE<uH<Dh\4Ac
5n&Sad 1Nim<9TjJdm8b?Fmp8/n5<+^#AR%c*A^?i1>T>V+DyR8nJA%uMMwV5Y@1edd6Z^%Zme\uE*aXb$5*QCa
IdpwV6 #1==n?Mcl!bJ*@>&H?4%L%+9DBnQ$W4l&HujVPbPBIjH=/c9/RebZTM$BF&<1#K:=wB\J9Q6EW5&bIND
iS8w1% iePDljtmj=:QHA8j!+&Hp&N#\\P4KbqlFQE:9J<XN<%HY4YX4eL!>p5e=Y\ibPjj5ynJ1Q#D/V!!jyW:
9\Bu\q w>Ewu5Q?c5A?WEZnHHlW?^XkS&qQ$ZJaIwi%j>jJH?XRQ!\Bt?pqA\&dEYdb9MT#$e9Sl!eiV$dJ\wTu
:DAl%< 6>/Bc@CCe>TQVMAnFm^+KZ5yV%YIq:ek>Zt!NN$&nca9A>#tP<jCX4/d4=!J@QLDbD@A>:%*Ka9*/L:<
y*!uB= kNILm+FNQ+L<<ndj&#1QqqCZ?d=eJy^SHYZ?VX>?#Li1<:>EiEuyn@w*k<@t$iuw\#yul@<NjQ<jWE5D
kT=/mK BBRAAkAIAPFXdTX6e=jPy\aBAJbbAkA#AAAAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&J6eHM9
4IE^*S eGX!e&>8aY\9e&X$hZA8at%\hF^>nCSHhZ<&*P$ck&Mun8&RC*B&HPh\#6+6caGF*AHHC9=^nEJ5B/nZ
WiQuG/ 9iqCmpRMEpwklQnP5TWpY+lEJuE?FJ*CaZERSA+dSbjEmW+/51JtG#8Pec!dDmIZHF6beMLMDn8nHYSH
h&pJbn t%jhM>Q%*18b8>:y41/8:1:*@Z89=6m9@NpHLwZ\ihM4AZ/S9m>eA4BG&!Y\YLj@^y&Z\p>iD9XGne%Y
PXnJkq j?/4@<N>>#Xj+S@6uD>@H5=@>#^5j?6LeMtB/?uMqRC99J1?/B5PAm^iS^6>Z*$h:H<X6T<i1956W69m
ZY>yI5 %c?HX%%:A@#eNZVh1*<bL4@mKF#%<<9\E#i>Hh:$M&?G\+jiAwiZq?HR<mw599WhePNdn<I!:T?9HIGX
KNRplG %TP\i8RaHD6&DBc88kMY4u<jLN=!G!\i@uZa@@1:ajHcB&D@LR@CG&:<Xdnt+N%\>Qyjk:i><TN\*eEH
+SP$W4 +IdqB?Eh6#=Aa#$Mq::>VunFP*<L>4*#>&D@pV?EX?T@Da6*@BH5??Su+KiPjJC&Q+C4<u9l+G$jlRQ&
6C8adV e*A$?%*+!Kj8y&e>BXhe>lm<=5AnePZmPhw<9jJb8PKce@D1N#+C4#9$idn<q:+GB&=/FF=#!%q/4t@A
Ij!Y4S c&@/B@nyt<@Dwb5@D+ePucH6LG*u+PBBD\eQih4*5A\uaVX5m!jl&JYu+N*Zuaa*W:@dD=/GP*:lDC\i
kHeq^l @RI599eS&Qe8G9Q&5:A@@^I5*pZ:h=&D^R<>D95@V8h@=?8\iDehj@IeLD#\FXl<<B#5@<Lj\IH*jBEP
FKD<6\ 9PWeHLn6u?BuQ$#:H@+:iN%>b?Cc9@y:tw89\QLSM:B<=B@l*Y>:DD:\\Njk%Fj@Fl+>h\/8iWPZ/QAh
a9lLIk PH#4n/njHq^@=L9Wd^iYX@jk&9j@C>^<%*@A<y*@Ce99iStY*:eL6&bDYQ:kHq#&mW&+:Qj@DR=</66\
L5HZ6k ?PQQ\M&j8Ak*j*RLDy>+u4::5Q\^/9ilQXm?t<c<@+i\jA?%*WQn*4MHm*>M%#:<4*Dqb!@A9n@>H6#+
w>KtSa <Ljl/5@>AA:@!a9\&n@jkiYV%QjV%Qi#6H&c^unwJXl?tL=Q:5Lm/Y@S>l&+<jT@\?HVjVl$t91E:iRi
Ni1c>9 ZQZw$*DDtj?G!#bK8Q1ju+jDb<I=88:MH6#+#SG5tk8\/myajjkJYQ*15:B/>mK5u68C=dQW=>\i9Qe*
W8V%Ru K%l@:Fu+!:>?E4:<$LN\=86Q\1PQQk@jjQ^FiNjtm*D5CS4Q:<H1J9Y@RN>Q:eE^&w:R@98j@BHejuEQ
MqYdX4 5twQ:u=/ACijik/iiQwbiPcyHu#5lV&+=?JLeQ>#L<Nu@89@+C?i&+YH?u6\p4c#L@Vk!*V?NP&jCei$
wFHHpA Qd/#B>?k:hu9ZaRLY%9\hG<EjueQu1L6R6n&>8C=F@+Zj9A@Q+V9j@@H5DN+CT=T&?/QZ+a>P4>H?>59
&@XWXZ :eEZV=$mPR+T9Xj@y^QNX@kZt8mQSV9>VQbM5&?tVVk>me$8V9h^hl*G%#jjll%nQPL$jD8emY/D5:9n
+R<Lp\ 4Ej:XM%*QDamV4=uR^n^N6m&6RNm@H:^JPD$H5&k5?P+V#6H:PHE5Ka>nJyu+=9&%lm@Zh*B5AbPmNtA
lKeYQi $eZ^?NaC!NjG/EJnBeXt$^yNAqw4u/^>u!pXEGMCV%tDW++@Z*\Pb^hMLnWSmZGyIi\Ta55YET>c<i#a
1alEHY 9wYJ=<6Ed#id$KYaq!QtSpqKnEYCeR5!SpVPEDP&t+%6aqqkSI!w#GpWQj4$kRA+p%848BnnT^9^tD!Z
5//GyF ajI/jXnpE65$N*MjCaGXh#PM:XE?CqMycIYkG<WXdh9p8bDQl+u:SS%M!*RtRSpqMmlp$+nuN6FRltp*
tpN#@: \ZYCnZpQSJVVbGI?n#lC!K6WaQ!=am$<ER<?miy>WCt:&VQNSkn:nJ\S?!p?=NwXlbLu?kG=dYCY^mR$
1L\Ic: 5DJFjAKt6Fh!Ii@BDSAtqL&S><FtC1^8u>&ytVJ6Q#Tj6<Ii!i9pA9:5cBNYq8pFNJc4Q=RenqK#KlwJ
b=$VL$ *5HwZ<R#W/KaPXdACM+R4+FK=R6qmpK#CRQAqTG@p%TbJ8XwaC#SGP9>tWHqk5hGN+yZnNBh<VWViVZK
-Ahdmy 00061545b5900110334 Page 81 of binaries2.zip
tjtaLK #ypEj<!Ik<n<ItN6!l6Bjpw1LqSYSBq#Nw\&K<y5et5pTeAj!pS8F$y%p#IWKB$jqNN4lCea#:iSmk8q
Kb\$MX MDCGNe\haRcF8&$6!X9BMLcXX!9WNcQ5dCI\+W$It1FXZl=cLT/wQR^lLnDTyTn=laqX/^M4S/^%6R&*
p*?\<\ bP&DLmH9kby/X9qltFV?:M5I*a4cJbV/EGMGS1F6idRmKB\@k@KHnZTinbI+y4G+n>6IewbwyX:qD+n#
@w<<li *puNnZA8XHRTWZ+JlZNq%HXe?ehQI*$jaT/M>CBR?uRwdaCie&HbljLkhnkXWWp6l$4XMc$b!T6cyyt+
W^FJMj >=&++?RVS/m?Y:yAYPqb+dV*LMmM:6JPL$::6Xh\qalK&%1yy+#!LSYhatha?$t#S?P^B=8:tiyDJ4uC
uqZ*p> q>CP1FXtSIVH\9+cK!nYD6>/4!l6AyQZtMPYWLquVBQnlGQwp$<It?Yl!SY?tnSVq\^uHJDXQb8@E=$=
8mV\wa ?YRN<i4h9D:P<8t=QKjD&VNp&H=$hBR=:wa:LD!/MB#w+GdL<kukH8D$l6NaZLm^S4mq*I<\:TZInL?M
\YJ%IS VBq\wAJn=mBPA$qE/hAa1?VXmPuCPNmPhbnjRHTq//D*NPji=YN9n=i?n*+N/el9iq@TGi9H%K%eIIy:
Fd6>\L hL*T==$C4i@piKI5Qj1i*\!$Y!9#wuT=C&&8^H!#wN%PcCkKGwd8+d6?M+#p<>Kl6FYw+JjaTymE8C8>
p&Caq/ #CjN&Hq\TTM1GEW@tDDDXkN\CYA1LcmJPEu$bdeSMSCLZ$%$BZLQm5ZJ4i?I+&&@5XC/ahayTVV:NQFq
n!n$kd Q9BEX/JM6addHuQjJ^tn\++9uC9e!Hehji<+6L&lw<Pe&y\j=VScPcCGVi^XSiZHA<!H4m1LAhF>/N&\
T=>Mj% I6+JQai8V%R9^kYdBXSWp*mTeGJRGC?lLnqP\@qeSD*MB&GY%8l:ML:B6G6ldGR/XZlt4GJdh4jwyyDA
m?Cm?j l>Qwa*C1apRl:%jq!K@ZhMTc4y88n&/Rham8*9ahpwRTZeNlTZS^XiX&P4RV#wTGpchQD>$PKi*%m5Td
>QW*I@ !D+pRjii/Ny*SNSNn>*R1R!Nji6/d6n^Ha#eXhRlEkwCca&6+dmJjp&=/hJPI/c<HJSRL5N+SZ^l4MT:
EFe$>c Gdk/BWTN%X/4TYGT*I>8iJun\#4!R8&VV8Y=>MYkKQ4=bp%Zt99P?wAEMN555ij!u9MDF:y&14#$49Ip
dd/lSw cquh8PP^%*GXG&&MT^?8!Eu+T>edpFcuV1ZjGIdL6*%iiVew1q+icP=G/:/m<//jw\KynbRMVAwLCk=u
c/1uWn j9QM1^A^9Jm!l4PNe8=%cIQCyhKH4bSmItbuPEd5$&MKMlAMu5CH^YY^utF<RqTy4G9wm8WY#V%&14KH
%Bdp5* 9q>84j6lNc/CjeZhmtnYKXe/bBq>&jZbX6j*Zh=%=D#:4N84A1FI1Li&<F=QB4ldnK8KTDniL99iL?BC
i<bR>Z liM\>pLXw:HLi5^&%w!AMR%*ZTJi%nte8VCeaAaW+WLL@Wa+VX^&PFAak&8GiXMVdnFyV^$bntJni&5$
eJ*uMm &wVTH?cema1a!H%y?yN6D*&kc!hwSpQP/:4FamWw*mK*K$T/#K%R>!^d\h^qtX%^6JFyyAbT#>SRlIQm
E#:ywZ iNDDhJTFn#WWJ%GHw8@wD>E>HNHyqb\&N<l^ySC##BE@uDI@KtbW5Y<eXl4L<\FG?n@GC8GM^Wp\VR#b
M<5d/u ME+^&yqKb*?MDKdmeJD:>&k$RG?5\Ie^biLn4BwLwZdLhZV>aE@4yq*juF/w9\NNWickMMFeyMpX9E#G
nWl%1@ t=kAt=FDW@C=<Zk@+?aQyd6pdi\ESB5D:ZXcSX9MPGVCKNPa#Gt\TFCb\VlMq?km#uNwVAKA+yBbi:*l
yJj\8p aYy5Z+%XEL9$TALipDE$4&=^YSC:$JVu#ZenWtmV>qt:<DTC6lJNa%FML\%nl$dGFbkA=/R?MwuEC51a
wG:&G= N#c<G1@n1uI&R$dwcwGWyD$edVpE#1*lFLR<$tVl5WywV6?I^/<w/!TtABEG#CEAD*+&S8FhlylMMCW#
Rh^GHe XDMEcRJL#QK\:h^kC=JN$I4bNVc/h9JWDTaTwXKa\m\bhC^%Z<4ewklwnJJpw!&!<J&ESnhYJD!N!kRd
8yaQBl S9aWIJLP=e%SN>wjF8FcMHD%JGdhnZ&bQh:#DWp!Cmt4lZA8t$^4BL:XW=ql1<K#aCV4#lGeqNiHW!Ay
W&upK* uA:hylnW>D698p*d5ktN1VX*#cq5^m?I5p!DReimQAe=VIW&uc@X8SWymEdu%^J?L>epKKw%=5VWAlND
8EF9$< AYkct!=J+QG4TYl/pqCZ=:SSVP4w4!<^TG=B/njkBK=AS:8?y9&ch<%NC+j%JT+$bGNQJCDHccZ8HF1J
kPID@d HtNHdXnRaibD?#wY^$M9/pHpeY+n\By$In<S@nlj8IKP1S6ynMK9Wa6d::qcnaRH1G<aLt*%w%G%HLG%
^mXXAa ERbK?mptX5\/eYlmy%cElmk^DcHchawDp^p@K/&teQ>M&9\clR?nk4&wyh4i>EXFWR^Y9dL95EM?ceD%
AWZ8j4 Km#:%emXFI5G*CF+6lTqq4ZLbHe*5in$TuSh<ynL18!/HcI4@et*1^1VRN>#/<Miq5Mm:=bqmHByTDem
/#/FIp A#18em\Ga:>bPS?R1:L1wB>R?LyBl$MMEi!RwqqQI+TRJ+VEIj#Bd8ZZKpVq1X1S9bZJi6:XKFBnh64I
dBSm*= c^LJN+=e+D\@cIayJZKH<?91VK15!md$kMnu^InuqAHHAX5+Q5CAD*n5?:#1BR#IBtmwPD+/VnNQJP<H
Jq?mCw L!eAR*/l1KHnM5leQ<ltu/T1&Cpw<kq$HR@Lwp?!F#A1Ct>h%ZN8qPe:c#XTZAY8!Q5WFqepjmMT$C4k
MB@&$k WaM\WnEpM4yBGL15ktT/\Xwi8KuuP66pE#cI*:IXXk>pp<=#FIRc+W#4BKIM>bDXQ$*V$4^YI/+V+uFR
VVb^cV ZLP&lAtRYJXSaRL#\tTBw6RK5V@MI+c/5R1^1X?\?eBXDkQC5EEVG\AG%:j4ac+6$d9uc4#Rp*c5@T4j
y$?BK/ \d#ZI=4%i+MmRAqb:e*88K+QhCXmhV!J1P<EHKtQPA!+k^?Pml4GKniG^CyE9H/=#&>d+y1c48Q%ADB8
>LYuwH pG#*mN+p\9XLB*pNhKW^EXYhuLF#R=tW5!R!1emVytkVqXC1CpZKV9Jtwn4HeA$@!@&$4wFJbH:cw1DI
laV<eW N$9XT%mPXIa6aL?&1HGj19Vdd4PD&/+pFhnL1ZHwNptmTI^<DSq=LG1/I6E%cFWmZED4?\Qj^DM:yEuL
H=M:a6 kQkTi=S8&^$jiSLDu9h>%\*1%JelWl1ZhJEn$:$^&CDcBuT+LEt5N+w%Z?Z$DDV$>pc@hHX+qbG/Hw+4
i/jn+k 9>:*L6NBST56wpaPW!pWw!MeCVa^F^hX+S/1RFYbd>RkE9LRFAX+^RdFJDm1E6K!jqnW?w+HajdeAlF8
4u<#Hi #j5^?5KPuh5qH!YnSlKlBcLpmcE9cn%MbC9IQ!YLmwESknV*Hau6AB6=HdtNmm!9Z*H>c8^6:qh\N\@H
=Yd9E: =A*=RLTkTFe1W5N+wl\HCy9/%m8?p=PnSY!Th\j$EQiP$aY4\1m>6ZD6TulGK&M:/VKw\uLpcTFMb%1M
*MPb1D nHSqw6WpkT&naEjpmXqPGTQBby5w5$Jh$&XFZl?V>ePS>NjSVhu%*8yc/$pec+Q4a8!>BX&^58uLbt:H
#t\+R9 R=?SwHYDjT!#Vqp8%BGIG&*l%LZb*WAYb6I6jZ<TKuhGa%TX@%qkHhw6:8WiB&/=HFPpSA$ba!w6$pKE
Y5!YjK <+w4yD8LCqq5d<=KGihYbC6:H%HW<I^*HPHIImSY%mGe8kkjS8W\$G\d%\R9l98Ra>?\\K=9H!yde^NX
TIZuRJ 8PIC=Yt?*Y/Ie#d!=l*w>MwEMpJX+ptP<MSLYAtnGKEG<+ZtTyEky8jLWcJHR4&1m9e+LeAVNdQcHGNV
*NC@5I 6XT!nAE%wZYCS!&:MA4PF>umGWTnHHQ8n$<#WEdl$d^?YKH:KG6RYSkwuH6bP45Wu#hS?j?5wNGwtE+F
6y+I+y >dJ$TP5uVBRSwI:<WiTqMFGNF>etmpwXuF61cKSPtMme$aBp58lXR<W#MMXETleqZjm1BTQXQ<PHVR4/
hRd\+L VyWB!l1W1PkIXclqpkpa=PGGM9J11R!9D$\6ViBLdNIaD=55t!k=NkpK6u?aPlScISX<1EWb!eJH^T<a
X8QZL4 k&GaKtA$e@P/e?1Htj$Y1&%$5euW$eyQ%QaQ$<ZRKEy$E4LJiNMw<J!94pNEMipw/1!NYmiYeJJNCwFF
^mQb+B XiM6QE=np@Z:TRCJb%QTCTFiM<GnuqVPQ4YISn%!an%h/lKn%BFL/S:9XAM!j!c^bqLn%cmVn:L<Y!?k
XiT#u5 dCeTeXcZHmP6mIpXYS!IR%&@dJk=M/#KL%X9w5Yi5:DSj6iE#wpEdG1^n+1^E?XRtDdQQN&l/+ibAnZ!
^KcW!K ZZTWlup%HI$<h%lTJRTmjqj+AH#XDW<1^#ayYk$b#@XTBQ1u$nwtZaGNWX&yan5nCYbEa5:aPY6t&Q8m
9hF==? WKKJ^S5CWVR^RYYEqmkqEKQw?tG=@mP^epiCtquYGa%Guddw!<ka#uBXmwy@&4e*KSnH#QE6Bb58IWw^
IR<CyQ M9MLy+%a4eXK<p*KF<d$akVqZyu=^W\JAJ/nm+t/TJ/QMTujEbWYV<y4RlqkI9Ci*KKwmK\?R%F/k@MA
Ww1RW! Ed:<&CVKB$\mZpcdCQmm>ZWw/@:T!@Z$^K6Cu&VyE:h!SyekY4+!*Gwbt!%P=:WWmDbb6+FMB^8%+6BI
H9kFi: Q%uwJqp@dPbWJB84q4HZ4:DiI!Y<yhaWwC!5RdHp!!bmycS=V4C+TX45TLCML8>Gt!4iWCKIKip^ZG@^
QLjiBF QCcmSlt+hnHy=+>\dKMXiX^ypALN4A:6YIGH4B>PlM9y^c<VLKIpci&:iGC^GF*cdb^d!&upTuP=GMd\
8@Qp4a hdiJ6%J^l=RQEY:^ZK6JqW>n!6$#mc!>klWX5jT9M?nwGQu9Y!\lJ6jN6R^9El=X8q+C%SwT9n+1?1tH
\9Y1iq 9E9TPly+t?BA95Vd#HMEWYF%1G!!=j/H<Gk^5iJG@wKJpXq#XDmlnQ8qQW9qCFDWni4RVT*%VwE>antn
c=pLSk VeRB*QjWeScKp:y?GBPb!mkK^Xa*bLY$lw>9j+^F4#yQcjCapa^N4mpZGJqe*SL9G:Z!Ld&Y#dDqp#Hj
T8mhGV wKKaEjEqK&9pkc#C!BDqw4qEp5FGknL*b^Wp&eTKD<=>5e1K/+i%t^=N\cRI1c+*tp^jQmW4EVc&M@Pk
1Lia9F QnYHJqtXuVDWipplm9%$>WB!tT=nPMSa*BIt&<\y4WT8aVm&6wR+d$GepWTL//<MZ!!ZWB4!:l1@Mlwj
%keync VtnktjHP*Ru9!:L$G>PqpSFbS/MN66A&8ZnhJL\qaV%R=F!E$5A=>Le&>jMYTSCb&Z?M#cP^<niVYNCB
9aQB?R X1=/FI>wbA4d1y?5+5CL5iueu*S%pQ?\lq^qqX==yu>jRtYEcTaKZ@b4<t&6=hPL5>1&Vn?>ZBcN/kW>
^8<cGJ hqa>!u$SVQ$tC/b@RkWVE+hJ%\+n\^=Q+yLMJWt&Tj:+Sa#DC/FuQ=ik%5pL4I/645R=iaB$IdGWnbSQ
5AtP9b FMe=t64<6!Q!E*:RpHCl!ZW&Qj!IjW=MK+K^KTKQhWM&K@B6%!ZH:+?/bq?ET=NC%Qbq5$^HtJF8uh=T
4A%GBq @FTVC6@%D^+pMATV$C\&ZZ19MESS?=TCYXHW<66pdldnhRQGTy?IS^Rw@YFh&=n:11ddeFk&&hYJ\SFp
mS59$^ HhZb$>\ZkRV4@um>jN&8%MX5jy4/#nd1\^Q=^Kh&#itN1T6YNMjVSLu#/$&&69B%#dG4K>F4pM9QutW&
aXRKW\ !tTMiyGYd<+uju<l+V!4BbSSNd?b5<!C1WSn=@u!NwuSJ!Bqytw^D9^MC1nCXMEH+^lbQ!\%l?96VBV6
-A<YRq 000590dc56500110334 Page 82 of binaries2.zip
=c:TlQ Yq\e^=X\VjhR9J9%TuK5<uI+TdC:d6p6!*=@M5u=Al%&i/Q@=?#da8M/#nRFLAINjFqFMn\i^\b&p/jE
#C5D#W qktnA$$pY:a5ta5<SKayP@N$1q98y1SI51/<Nc&RlnebT+m+Tqa:kWqMcC!CkT&!w>$k#A/GHE6Pt5$$
I1wZ@F Va5WKcyy<W:#IlwmBddcdMJ/*Q>ThW/h1tyu5ae*5hZ5e@y<>j&Z:@?4T5*e8FXeZX*NF@u*CJ1A%V\<
%*uK1e Wm+H%**%M69!YZnX&Gw^Ll*m6tJ@\GX/qhX<PR?Y!Ch+!u6F%&IpEYh49JF/SA\h*t=$mqnyR<R5wDwt
:8jQd: yab#VWhjnc9%#b1$FRy?lSucBdF<1H<+=K#I>GZ#lN@cY9<&jWSEVddCRSR6L^cKlj#/S1$\C!>TmGpt
iLdlWH X!VYG/MTpZ/$4Ru/W*#G^4Eahj*L&=My1kp=&WK?eA?u:<q*EF@LB6$Va@$ayWin&4\hWX=WEAqlbVSt
mCMJYL ^Cpe*eWm9C/uZn/$Jwub#HB&HVqcCb#q&wm6&WZCj6i=&EqawR4*I%w>S=KL/w+1>?YAhb%u$&$5JlKF
DFEaM& ky4MGQ<EI8n?5XY=jIHI>8G9ldl<u@*ab^\6L$w:Lj4H@Pp+Id=/5hXC+u/l*:?<?HyjIQQe!9j**@Ld
bF+WFy acLbY*mPjEmPh1\candIPKbeCT9J5CbW/=K1>lG^bVCnBWVaT/AbGaqnSw=\qJQMFE<1XPH?acMP9$*G
yPC!Fk T?9qwewK694c^!j5Wa6NCeaJZ#T^*w@Pd4>$jjH%MjJ>/yJ9whYPMq@^/AP?^tI^FXay95K@G>eVtWJe
FZle$9 9tw$G5hKk*4cF&NbuG\mdWB$nj^4ZLk!N4NKyVikGnKQCET<mFX?MNXJ>!HeyVyHhG5$8MwFEaZShCSK
X*Pn9# F:R6!hjt1#dIakX&4a&^WGVhXCSeN^bC8Qd^IM18ay8w9Id!R8ad??Q:>$9!dC6t+@9n5dl/yVH5*E>p
:PE8KM %=S@:X>N$MERSbG9!t*$nc%?wtL6iALGT!ISp#h:4D@+K:ntaqdE+:Gae=KF*cw6dLuN8X!85CaBmLC$
w4tbMG :aXZ!LPT>anu!u+my4?NtMt+9ayJ8Mb6#^wR:uk+PE$$Tpp4Vt@T\I>t%!TPmVWhX&pq\T\t@F/udc6=
#tZ/B% PFd9!>?njjDd9Z^Y9bY9:6*LF@L=5bk$LQj9\Y?FXYX>cd/PMl&4?j%1dm!?KD^S?ac9:5F4=qhq9&J$
idPA+p +#$<bhb$acbV6Ye+C$NlLDE@RISDJGEYyTQ8\wJu4Qd4ZJ9WEV>bVZEYuBHQ5b1eT^>Y@\5YEqZ>SHll
bwZFV+ Zku4K4cSl9!4d!Y%>wQw6tl5t#bjBZ?NBuaF@^55eYCaBD\:ytKbmC=lSaQEBj+G@>AQqQA%a%H@K9E%
aXSewX 6+WXF8FabpI+Ra8+hdGI4uHayWi#Mh>bHAnN?Li/8q&LKB11uWP=CE9L&yK/wj=la!bqA8t/hq<jP6Fw
?jCEpk qwYuNcLHX+GnLYd%q6hIiN1kIhSGdPZQ9VKiQYQCZ6VEdJkSX9il5N6dDNXBt$AXi4ch9pbK4P$eWn/E
K//*Zk 8S!/1*W@a5wJ4ut9>4^a#?+K61h5Y@*DipCYZRY$8HEyCCiawt84:QqmlbDkJD^S1mNN4\WJdecIqwja
=>RlCE m+Q1\%^am?S:49Yd#d+*S>y84ZWd98^\pBE^4<M4:dMnwZ=61?HH$l:5&udEEiYac\lEuF$l^9TX5D+5
K^D>M* hPGPk>+9SLl*Ph1+XpS!!leNEy=mQKwEaDQ\+I8Kw5tNCS%W5K$^IS!44All/HL+#KkR4k$Mkp58NajR
Q$&%^^ cmKLiHbA=G1&FI:JGMc1ZWd@kYhP/a5E6SQL1bw>X1cc:8!<D4h1/9P9R^%m=u\/iaPmWRy/%@L^cQB?
l+8?C$ caWRL:FcqNpn9GDYJ?!19!/E<JiHDFc6yBXGGnMR6j4*GM5JmW!mQCG5Ba5ae1GjPZEj=<bHR!6RlGad
!XNIEj mGDhA%=CW>@8\6+&I^I1%an\4F>D#Bil/VG8*MJen<qilQFbe==$!B8Zc5$XEhQGlFenF</%W5%+YC5i
aHe?$l mpdyNANhQybhLSSYIV4c6nwYW?eyL^b>YRKiq?pj/??ZeXF$I@\Tn$yk!999$VMLa>ta9ImtMj#nawGV
SQWHiN *Y^@@!&&AqG9HQ+!EbQ9IIwT>hycaY$>*><ap*e/MRbQ<TXmPqXCYya+VyD9X#G%Ze5LSdTlcYcc+SK/
+bTEV@ nQG5EF/yXh&Ew#jX6h8D9i1jZjW^y:MK#/Fe&>G:%h+WCiqN?pIqIy:*TTnjYH!XEi\QqtcCG>4w&&FK
XC1CGm Ti+DWt5!4+!8<cN$t@4ZTLbc>#&&pFR9Fk8e*cLk*C>HSB/i*iiQ=5V1?64c4T\FdNL?S*E<4i%Z6!!G
5papd@ 4*=jqkR&FtZTJe#%A<MCWMS#4*Q9ic+>Y^^6$Qd@CM>b:@Qe/=cEJ<RLi<eX#/4c&T6VS#!4dK#ZZ<MS
hE$jd/ 8qANL6qkRcZ?RC@WuJYj/a^SGwIF9d\1*8RX&y:wI$V::!jAu9KWhlHLA#L=dGM=b:QdpM+F#q$+9a4L
cq5&bl 6\BD4LmGF:JNAT5+A!9E%B8M=aQKQw&$jF\+tpnCE:&N$C9mc4=&VVN*qn9De:$e&c>#pZmnjiC9hS5d
*HTJZS undmdIiRa>d\4%KL/!9KYMl@j$G181w9QQcXWl4b:1FVL4C6>FCE=G!IW6/%jJQRE@9E8w?Tn/Z&hQX9
WVt>hE =q?@WM@ll\p>GAWTP5SXm5^SMm8NWYFuZNdmGmW/\wS#<VXZLGd*!Xu6Ia:&m+kVYiFka5Ve65IJy8ib
dJK6Nm =5CIl@*LXNd%m?Bh?kAClJyewPLlY+\b<4WkK!*IX$LBm^a$DQ$XTYAIFJuPkXZP<lw$^jZA=MdZJW:\
B9uBMN $X?pVmyy@\9??u6p<1t1G/ZZ!bdc4<P8#DqMt/9uK8LbTwQBNqMXE8a$RLN#*LHmq4H8VDn*m6nLI+y\
J>Lwq# qXb:4ZD?Ky<\68=HViwK5wFt&BlXla=w>A6GP!@uQnP8@DiEJkGH>:w+J9T>$CDEk4>pp$**l4\mPt<\
JX5wM? 9D!E58!c<eRFGY1lX%&qTI#5<H=%+RFjE*nTY#HlZk6FtHNS#a^JtJKBtT?cLa@CMV>QP=<^DhB#LmW8
SZj5^m Ru5RGVFb^BQPKZ?iYSL\@ZNEn+hD<d&WqCR*?P@<^?AGB5>NBFC#\C965JBPD@pKD4LIctVI!8qQbYe<
B+TQEa qkiuC5<Ha%/APG8X\/Bd/>IM\@ZG%!TQKY/TkdR$DeSZtqV!Sh!illI^F5WZ%8a6ycPyW1$1%lLpI1^G
tVQec: &dPXVPZaZluaTYbLc^GSW4MV>ZqZi8aqNBLKWEVIaukwRyLBXNcZl9tpAX<nHM\k48RY?<!eEQqc<KXm
K@h*Q$ 6LdbLQMduQ6ahk%Z@SET5n+JR!\9y*my8EuiEI!Hm:S$G:aA/CqPJN^WbljY#NqlJaTCpDl4l1lj$$$d
^kWSa= u1i4/d1SE9GQQXM1WtIiy4H>q:H!w<@Z+LWTAVM=FIpt?1Lp&>cXZ5!ZJSJM+q5^>W+wdyJmlPI4YM@A
T4km8k Y\d4pWt?!n8B=mAB>n44SVFR#mcpEakm+G91n/N=tR^J@/yMAIJj#MnBq@W<%&cmb1>>pCm/N+m$>4%\
numIS^ daFqC$FYJ=4\uQQ4:LpZ\6kd$mF:cJhyV/5QL=Tm?K1>5d/m*tPI$=cL/+qa4K?ApW+?1$$F+\AuH\?5
^4WFZ/ hWHG\&lcXV!ebaD>VkmYplSj?h*APXeSqnGPil6SiM:/JcY5<5yn5pFP1D^H&8EC=/>ntE\bydPI8!uh
/B%/wS +i/M4XFNy686mcE1jMS#hJp/?ykn#q=c9>FBiHajyTllEM#*wbh=FF?D5SDNF<Pyc4^A^qhp9$C>TZ84
e8jCq9 54/8b1w4@:yjXp#^hRnZAtER\^+aP5kdK@@K!R^yp@B>dV>GcG6^qCu/EdFE\Fh1WiMCIi5TeTWWWX>H
SmNDL% IkauKlaT\lFH&uPC:Gbub!Ae<d/t6WG+A=1IYiW%y8ebZW/i5JJal$ktuF&H>9+NI8^j6j>IlH6Hw\uK
Aj>TbW CD<Bp^uhFw61mu^<FY&%4P#\yYYJw>L=F1RhJq!nI4bibMtJt/W$95I=PaHyS#EKnMA6/1DCcJqVLqXB
uTNpjY y!=I>P<Eh#GlNGS!\ypaw66p:qRu4FYtHca$FPVaDY9P@CIpL:6*tdWdnk%dHZE$VP6Lp%94YF9nI8L$
qaJ?Z5 C$LLZ>X@*A>11tk>CV*EtPe8c<9*wAJX9BZZe*%m5GTZ:%<S%>WwWK<<pTlZc^cE?ay@B!!GW@jH?RuI
dju^nM QW!WNV55YHT+=c6KGeXZ6N1+R\6jecu8ZYH14=auE/+F5##QtIEYu6AbY5@Ie*uuW9*&>k:p?9/+wY*D
j5wISY :j%^>IX%NIRnYy*PtDt8bc44u*nSMc*lMGV&TRH+a4@RN>mlmRGj!NSF=1?IFuBQ9u!@:EkF91w<S=DP
+:$4%M CLaZVWWiItE\5IRu8ui1<Gaq4$q@/Qj%!/\KS!lP9p?m>tyM&Nykmey:1Lyq=l#C5VGc&ZBpLelq#*>$
JRLNSW d&FwB?n8FV4N@Mb5!4C9SX%NKB/PlE81iP9/Fe4F9tlwQ<H:XMiLl&em$+P4+Zla^nnTZG$55nyJGwPT
T5Z$!L MPL<X&lQ%@Ie<cLL^IEW^iJ?9:#<iF:&5=J@Ze@9q^cL\M?\8nkY6he$EJbI/J^aL/!YV%ijl:NZ^Xn/
4YLJVa PiJc/%>ai*RcG&AJ!*FEuH1Eb=YQ4S$pSBAQ1&@>c?88k%aG<Zhtk?kGu+a$%Qh4=wp<Yd<pRHaa<?Fm
A\eBMb R1:1Q$d1yP\+L<R+QWa#VQJ@%k@Z^C%$:*K?!KwISGVTH6t@49ZHbRqS/W%wR@weddht&ly&4WK+J&5a
dI/Z<T *Yml*hKFF>/mI#Sd*S+HI4^D4kldcSFKAY*J!cJt^Qq8>MZBR*!q$@Y=twPq=Pi@81!uF<KQe9/cZ>$9
k#&XQw yD$9^4qd9/mtbeWlYTL#!ZGVZPw@1+#1X\YJHAXPFFqV/T@8u:W+JqS>5NC@96yIKVd^FjWtC1!!uteY
5tuB!D 4?#cy6+e?K\\8+km+SK5eC<#4E&!E&bedW/+h!kP^6IHEYQQD>i/P5LckTFa?!G<#y#p1/cA8=1?m$X6
i#bwk\ HyQ\=\EE=qXK\6uC&91>dGGM+m%+uZ6pFLEG%<>@&4li9Ei:LWR=d1KD$le1\TTCIRSbL%Q#HyKbw5:>
jjl8&+ tDuSNB#mc^=qpRJ&4dK$SRln>T>dw1QEulIb4uKGc!ZQCtG6FGdMVLW$J/@Ej4uCTLPE%X955P%&98#c
R?9J6u =ERjthwwC9Sl%Wu$XeGBc%PAZ^TZ:chw8bl9nP4tIb:ww^AJ$yZ?Qt1QpAIkSp:bKQ\q4piBL=XINPLR
>8YY*! KDRt<CP#^qXdGjD&$i8J9DVI=eD&i:n%BqpTKynHEqRNaLMQDkJD6CLZZ:eb+ybn54H=t*N=P%%jmwTL
u+M<mm Ai/dHHFM&dPm+wnhZS1iHCyKFY/6qSFLZkW@kjt1??CE$:q14>Ww=&K64<dDY::\Z^ba/KjYCNY9u$ZP
FELnKd JYKNEA%9yC&^LJ5\^yj*TbDX*C4K8kM&5/+&^lM\EwyeMPj8t\IT9anl6?1ZIF6hqNXkaY=@dan$RnlL
%#1iaZ tR/J%:E*k>/E+N=dQLT5qC51F5I%B<Fbu^P8!:P*P>eDeL&iI=QB9MZYY:HkueSqZLY&^k6&c/>hL98X
?Y/iSj 9G%>^dXmeT%wQa=pX\HqIp:kwn^pa@Dc<yP1emSa!epdaP8L1%LHZIXBBQ>SLQS^@J&qu5lmVG#4Z!6?
qJ<SLh I4k+pPBJiSB\kaFQSD%#4Ynd1^4dt*tYMK5>:N:jM/L9<t9L\y/>hJ:&tJcqSw#cc<SWkL%T96YK:PSI
YRPh+1 XHyV<J!wFVnSQA8?4nl/WPS1Ql8QtlYGGCpQ=IpV&d/?dF##dN5TZ&W*b4?TWuK<MTH6MQ$FjMcDq+m1
-ALJB> 000ba2015a100110334 Page 83 of binaries2.zip
GNXZQY =cZL%iSquL1<5T>duyA91J%wY@c?=K8eHS$S?J<<S!G$p/1h=BkYMiLa@e^cJ<1^4:K%pJl#^TlH#%t+
HI?G46 ldHE#FhlVRt^J!\+6w5Q>GH@BW^DLE8uImdmXIW6Fw14&cnRb/ia@ZLYEtNYm5//SKmy%4F:1:WInBe8
@NbJym %mmZ:>jX:dYLlaYy6V1y5Q4G#iWG*E5Kt&$VEh5nS?\P@lIKlHDN^BY8ewE\NY:dIkqQ#%@XC+VtwwM%
W^$>KC ba8&Q@EJlKnF@C*cMeGSI+h5YHn>Bt6?wc+nG9$Fy4$MJ@1ldEL=TK$jWd9=EYj$=Dq:k$4MI^HPiX4/
=E5C*8 P8%&qhSi!Cw<ZhW%RWm+yqn1L5Dc<5H#QHPQ!>BLIX@NkS#QF$Q#qdp<k?5&kItLta5!Sy!>8eJ8mR&9
kYZ^m: 9?LZ%aZXHtk9Mt?@&bCLm8cDJkAnaw&WHDCYW@QeC&?bQcRSybIL%+a4L4ZjZAyI&Jt4jmHCG6YY+lnS
@H$nSZ ylRam&8H@c58jWhD+iya%GG#lD*q$Jw=cyiYR/ya1K:8tHD1&b5$lX4$>KhE1Re8=yydJa!<RJVciKHW
V>bSk$ ^CBL/\%Qu*NMGw4a%qFa<>Vh5=HhBVq4$4q4bZ:DlJJ@DW*KD/$!WPTm8dZ%uV:4SL6AIY^yY#n4llHI
ka$&pq ew8!Mm:5NitMhp**XFS6l?Gm4&k=u?:wF^Kic:Nmc%XSS++pLQ5hKYHmT/lN\qp/F=/^%ZNwuyJ4jt#+
C91R?5 w5Q:$^Jj\=N&hFn9JhV&1$!Y5FZXFt@R>mwJ4\biey1mKB<4^5J%dM*EcD$1=4\JS#kKCR@\%dQ*&dch
DF/ilY 5VGuWFn8XVltSpZMyNNXnI@w<!V6mentAlj&dEMn4ldtFBKuL^XYQCZ<?c?l$bVX<6i%<6BTe/XnkFI?
IB4FiJ ^6w@Vd@IdXpl:Ku*Zku1lt4Rhk1ZLSh&A8y!^ya$HHHPQa*aY@BGHQ8jlFaan+S%a?ETkwK=68G!1Zq=
YtQAke \S1L:1+5+@&dBpjyVi1Twq4=hW*N&VA:M#*QdweYyb8H:A*Y>bXbld&\6LtiwLpPp8jcCD%1Ljhb\l8:
$Zt4WM HlPq:5@Z!wcPYdWS==A15b&Te>6we#H8TMuba==4V^&6Z$LQqdNT=!@mVChj:Lic?+RXIq1JqRGqeKS6
8Hb%Ln npYi9SLJmZAGM<IX5NqJ1dA?Hhhll$m8AwFnj1%=GeJ8RLSCMFF1jwHhK8hb/&c/=*YF9Wk+j/YTGwC/
&LM9d= 8lHFwwnXAm&M!SEq%pD@8uDBud#wd6uPQ+Rn@:SHY<Vb!8X$ymWYi^dl6NASNyXc@F<+K:6tdm1eTcy4
NykRPd I&G9^BJ/#neiNL+HSTp@H1cTI<Cc:<@K1edC5blJ^FBSNJV%yVWmb9!nL^<8:JKweNY=9QAPBdwQDL?\
i$/ZL% 5H1u\:6Wja&D6Z8e=BMn\Swm=64uIXeu6NZIR=e1hP%QG/d8i?J=d1iy4RRTP45n>\:QYXD/MH$4:!>Q
C<wEAp SM&F+wSu&XNN$hMqFtNq4%KLwH8i8SPC==tLD^8FWtF61tQN9DEdBwS#FTT4a>Bi&Nnq!$w1XI:8FGHw
bh\nD$ b>c<G#PbFZw&:HaBn1nTuDb69H@&4<LSDiC+hPhYGe=Xc?!$Rbn6P==nuDl:68!5\DS$JZdXeG#$+SRT
G5JcSH ljNLYAKcpW$Ic#!J4>u9RVmuNVyem!m>b/WDiii8bpLu1*QqIM<^6y#$FYcaKb^<LXua>ITqJR4:!eI6
!jF*<+ HdpEHShjHSeqT1D1icZZMCk^$G*GY6dC\XkD4JJn#J=8X?wGmbB@>V^nLS9^X@n/Nj<yuARYn8a=aY&=
jH^jiF =N=d%h$HcLW&8E&JP*d<j?B4CZ*i*1ZTJK^DaHN4aKYMnCk6qd5Z$njJ4@JZEhaZSdA\nRm6Pi99Ee!N
lF%K$K :6ySk8YPwFDIJuqnPTh6nSh#@%H@:J/\Git!WJ:VXVu=+Eyq:WnXumwl9wc9I4l<V\nudC6Zu=ZVBk8u
u@ue:@ c9P%Qqd=X^?b+QQ@>@C?q1?8Q>C?nF?>9*+1wY@>+npY#4GZdZH#V*k8@^q?IXPj%!b!@LW4FXc*m6Xu
&4#DZy bhab*JdF&ldP^XnmK=&b%wj>lwl>I$cjRnaKGn>+p^XcT+6@p+h/WGP8?WbC:%Q:W#1Z?nJ?XbiB=?KV
:hCmMe B1h#DSB:Fy\tw&9tJ<\bj\FGb=dw#Q1F6w6b!WQhITGEWSp&hZ+:ISit?tP61!need5&u?+5HD?H+!^?
w/HT%< <4@kkjQu##ij#?A*@HGlGV:p$RJHy4Y%4dY64S&Pnw/PXEhub%hZX*h*P6&V:5FQPkd^A+@l+eGihL14
*TSKjH K=Z1cG>4c&66dYt=$A\u+NQl%:6+&w@\u@R9?RP9:Q^bPHut\wXYPCPiEM/Y/l^J\ct8hR?tB:9V*aQh
4b\SR/ eA!tl+hHJ/ctF&+9+nE*Q#e:NV&@8Ll$=!+hZ>LuZj?ZqbYqyTX<=kIee@P#$#NVp?Qn+:ue#iEdN+c8
#*Q9m# D\$NDF$j9D++NHB>AH?:jtQ+bt=<jGyt:9d!*d6Le%PV8bHBkZT/P@TtY8D81B9X$pJZ*N:Su845G8u8
c8tKaI Ge^NVC&8+J?P=&+P\c5P>A#A@aE9QMGNt:qedu^!etb&dtF^cRW9etpJ*5LpSG=piBCjS4h#kG+u@cQH
h\AM+i @?BduB9J=TdkGB$jGaFu>G#aeJ/AXZea5aWn<@Q##e*N=!<k49nnAq$8jtWR&NdYVIB4K6YdRqnVCP5k
JRjqk/ ZkBi4pS$iAVPPCKB:aS:$N+P>/AXdkEC/+<wl9MnCTq@+1YeQ\6nT>/t6p\:ulF\:i1pRRTIDubj/$y*
iDRKeD \#e+%$kPkb%dRFDuytctANmFJd=J/qm=1*=hYX/Y!M+6LM#QI//VlP9NwS9ZB\BVABN?DQnIKtAZEhlF
*nF=!i AucRkj*hJWT&XTFL1F+kYF9^e8HthKeHB$jGGhibCeB%cGBkkG@VAA/kG#h8\19uJmbu+JIB%^ZChRGG
/Vbc:u ##nnTkn&DBKKA@!LD!6>Dk@D\BnNAc!=HN#5\VVkin=AXyIYYZIi$TSp<dnR*B^eep64C>G%LhNBhP*5
QQXZjS yQ9euccV$ckcJp\SWnnh?EVPAY!#BDdEYWqZQ5:?@F*t1<TXCN9dn8ed/RR\8+G#ACybCmS5duS!cub8
T8^Y\t huy&ik1Pmapy8p5KYeAWnmYj5W6Lm4J#C@Q+J?MVAX?9A&Eb$\H<AhRF!mKqbtC54N^hZy!dHChk$*@+
Bn!L<n +NeZL@:#l&$K&Sc/R=K8eL$y6GZZ$5PA/<L!*iYFYeB%GAdMAPMD?A+AZ&HW\LCB!=?FK%+P?D1KMCGp
eZH?R5 cWbYj8C*6H1MHyLAnp1CM/+K&LPK49AR&tCENaM@\BJj\C?CNaQZLP<!&$XylPpp\\kw$^TPmjGJmWt+
=*cILX ^:uekAR&yaDNNCP!Q1^ujYAXc!Xj#?J=<b#TRuT$5>Y@SlaCdQAI@8wDT=kC?hAwAdB#6\HaqV9+8ZTH
lqt<Hw QwkNAP#!mkIYKD9Qllm8?PaNBlYRSFBlqPI*N5bAK4n%CP\KAk8*QQ%9X=<:ePJE<8I@@acAJYRbXh>9
mZFZk& AK^kl$h!W*QLh%eYy1jGAheliM&iAWqajGWeNBMVM#N#<:eX45DZCiI4\a4inbGp**9wpdSQZVBZnC#@
nl+&V= AiB/kaAqcAqh@MKH\K$lbe<nXbt5tYdyZ6uG6Eu9m4i=E*%4V\?CPkKAnyBStCBMy/bu=/aB&B+!Y=*w
eQJcZh n<l5wTq8%t&^D?!:m1=1lPFbM^LZDtS5mm\^II5HwNw%$wuAww8b^AMh#WRPkb&hY$SpAeE:T*#eWeD1
J&\FyS nJ&jubwlB*5VCE5kEq@yGB^R!KIdBB<+D\b%bRui%MnHVhY9:K*ciiLW1YV>qZ>1i+?kSZSd%VCW%t!\
mI*Z@E B*FhlQE\Q+pPFm#BANEPjyA6REM<QkF&jtH^>nLb+WWaA5DZaVK4CCESqHtKH^BV?Gmu$WTPwJQP!V<A
j*?/dT ZQu&KtDb8b+@T&mm@Y%GbJWX%4^4yy*eK<HcNhLXnYRhHKcZB55Lk&<KRJ&ht=5uSlBni:yqwNH8S$@N
bQcWhb 8m$P4DD@/?#bh#F?w?Hpt\ny$METy>FMEK^pqRh:$MXT<EB?Bw\TA:9IAPIHjkNpChmXFb?^$lCVk:%^
#PGE@i +@wRiXdtc\<!m#kL>^>9Q*nBBZC!!:iui=9&HDn+\&h&:V!SQHZ1j=+EcK?<^:m&BXiLaX:u6Y+\JlPA
:DD^qw K#4a<ZE\>V^ti5kikQPYkhMWBE/Lad+mVIlhYu$PalmV^8kC*bAEti+>MZbpiBnHAiKK4NTRQT>Jk4Bm
kdy*E! \JSl/t48NVDD9ZDl^B$aQY#p+cbKu5=PR\TDN^X8IJm6ZA:6k\K&Hh/:DI9Qu:X6Mh6l=m6iTa8P1^^L
B$qPDc kPwI?RD&:>jTPK^GGhSS5ltAARJLI<5@qyb<W/\FV:+lb4+m1wQM%l:yCNEQZl?/mT</M:?$jP96q!@Y
LVt\&Z Hh%b>9%u!udWucLn@abn>Xjii+?BqZRFZQFCae#JkHllG8:EDZK\GNnmMiV#hSL5<PJ6^uWS@P9EKIbu
4kVX>@ mC4C1GBF554k+l4/IpqanB!Hbb\FjMWa:u!#NMduJc#\AKJI<DJ^!SaHIWG4:%$^*tNaB/WlJE!B1Z\Q
u*\jb@ PYlBaDp%/JdSW/5jF465MThh^FecW>K@pmFPpY%D^ub*neB6/?!FB#B&/lqti+EH9MeSRJq5BwSQC=VR
*=$1P! \Bem8*\uHBW9MYFqRK\eLH6YLX\bpCpJSE>N>@j5@5p9V>V9*Q4M5%6*9AtEVb=1PHY1+jKy8m5ZY>>4
$n/5Bu W^eL%=4CYKB:EHFhYIIdMV5=IVMhciW^?McAPIh&GQ&G#>jJmXHJX+KX&Ip@Ee\$jpN$8\abYpw@emM*
le=Hn9 $R\V4yS&ue?eXZ:&QPEKtDdLhK\=eK<6EMFIX$hZ:RjDBP6In8:n>B^m8ml=eShDFA+$CFmMunyqYI#l
\G+4Y9 w?>pNeb1pVq:iyZAe8ApCW5tGK^Fb!it6JnRp5ZApG$+l<FdnwFF!qL!R%<L/5w\wRXV9EKM>RqLAVHh
Z>^NX= hkK&l+HqkAX<IhnMpW>jj9ul:eiP%b<+eY#Qe>@>:uijQud1BQL%bMPyp?<*ZE:Yud5C4qaNjL\@cW^$
8^8RFF \MEC44jBEGN\NmR>N==w/AaE&#jHe=DAVm<5LEu@mu\hS:PK8GKiV8SEYJGyAGk/Li%^N#ydtXePW#kM
GJ$?#w 8Lb!%5YW>R>jl&lY!T6=X*K9jm:J%KHeFR%<nlPN8RY?hbITeN>8L!=lwKFTk&+GqkJIGqMYa=X:bX%C
k1MBe1 B5Rb9FX6HDkSaV5X4J*EX$=&\MuAF:?@ajc^AC^AP#M*QR5S*Q\eZ6&hqiD!mLJAYImmJ<d=uq>ZjPJ+
&4i#@i 5!i6kB$a?qQD:4>:+QH6>TiTJ+:Bb>&P^^@hD8+X?A1E^a@Vq!<*uK!49@kdbhC/KG+CZCiu$eGCIS:Q
kIPK$E \hml$GtAEmtj4!SM<K&n8GtC5>Gi6E#yMFyCSQHNk4Em#p4cyyXkMA!DEjuc/kCY^RCySJCDbh?1*G8d
^#S/EA J9=R%IS9HP+m8LPF\IQlZX6iwuB#kaChknCkl/IuAFaq<^hCtc#QYPd48#VGjGFCTTH6uZm*\AdnV$C%
dq6Gmw w/PV4X$QD>ulRTZDILB\XVQVeM#m=?\$M@dPZeXa>4F#5:QTEGQk^JpPSna!+P#l=Q#n88>5ju#4kdwV
FI?h@! <nl%+6lLP>+<JaEqcN>9PN%\?a<NX#+MakG+Q=mFkaNhSpMMeBFl$TAM5SuGSAjCNlRtIH/@T<E/<yZV
uu<#k+ %:SEFXM:65EnCP$I=bhpqd5DW#^Ihl6^XeBtFK#NQq*bF18+!Zi9BG8Hwm9q4t!Fy#Wl+C+^hYFlhubt
8mjy>\ bqaC!\wFl<YB>HSBD==WQH#YD=\8uQh%Pbqd>ddL$Kq#yB*yt846pBKWh9T\Yea+d5w@y6uhAyTByMmE
-AbIQj 00078b7c4c500110334 Page 84 of binaries2.zip
VMwl^w uWQC5mEi8n+IlKZ:#u#qLPQQ!h*jiiS:#%V5P@e4aC6<$5ey55KIckMa+6MI:PZL!a8@wSGw:qCcA/i=
+H?=#W &^RSa?yLwhN%N5PIc?+t<uX1hu/BeEW:#Q/X\/d8dqLY4uYS98ajkC?km@HV6dVTFCY8dVKARV?KuM&R
<&upV* FY+tb?1V6qp^quBq8tbT$6GSBS\pXYCi%e$9/Y:hZq!eS^yMRWa=k>t<BDa>&NY6K^RTYKXRu%Z\Eq@Q
9hAP/i w1?*AmiI%n1qERcdpiIH85uF?1n&!KRPkaXkd6KHqpSaPj!?qNGVJP\pE>bQZ^uXunS>ZQ*Qt<81n4##
L5Vd<d #n9unmP1BCl?JJt4!jiS4\B5R@LKSW+CyZ<FMCkJt=1?DVeBCE8nB?XuXBFbd&LBcWbyu!9wZ!HC!5Gd
jMZuaj \L!GWEXiB6phjGN\YcEl\9d\P$j@1ptd1Bmid&a%IlMGFu@QWQ/ccTYLTMVydieWw=8CaekYyYm>R5EI
/:h>%H //=AkkpIIYjuEhnFGWm%Q?*?>IMQ4u=\/aNL:bjcMZVW!\AcZ=W\$i\4^IHGqiyMTh@cC:@S:eQ+iLB:
MQBF<E WBQd$ywkV5epB89VCP^6tec1/EpThy\Jm<LEIAGLN\uV^V@@@81Ln#^VejDe8Z@e></?e\BuWu+tKYnC
pd*?^b eDlJ@9X!R@$@Z@Jlqb/KDByG^M6w6tbIt!C4wARQ!q@Hmc?LYy=D/lH^XdE$nRIdJkJ\+:5W51!Yp!Zt
<H?pIb wWm+69tttDX?Vq+yT6KA%jkcWkm/A#M<lWwMnu>CFRp\\&w/HGmm:>#/:C?>Vd%:/84P%FjZu1tGn>w#
bu58$B b*=/=1i@?MW9&BKjDi9Db=t\TmEPDDHA&J8TMXNK+pwi>lwNY9TFM1$dyn\YhSKFLcpqCP#KHR%aJP\M
5jZwVq Sp+1k!W/DdJ@VX?6i@L^uVZ:*1p=h?:IP#>/9ja+<lSSbS5MQ$?Th#*X<L<c/n@5cJejK6eGB>8DBk$M
$b*je= Ma4LGPl!Q5YjN#l5pu^hZFb<uTK?wkKL418:T/EwM+GW!kpad!XR$Dna5KHhF#c=#EVTwWIS$jW4hAyY
^1@dGH Xe9yIPjSVh+DS?QENHlS!hY=?Xu&X=RTkypb:Y%/8?t6M&h11t51c@d6k<?D@:n9IQ\<51?ty816X>:/
V&?ZZ\ /S5@jiPnN#://L@?:Ge/5J^$Bac+ZcbZXNZybF#B$/QDVXEIISHX5@YS$jHSmjFSH%kIulaY6D!MRkFF
m<I<cN YLniIa1e44MpBLhy#<6QQd%nX>WSwG468ZQ:j9S/=iGp6L:TB1MSdpmmCc/:?D6AE$B6@@DZq>m!hJF?
yWBq@# nSE^*CEp:Q\5&u9Ky^nYabIA!d@PRqAu?Vw>JiZlH5uTER4:Ee5Wmceh@KMV>Va$Xh&!FADeBX\S&LbY
%@9$tV !E8SwRR1K<I6HAD4!EyNY!t%W9K@llwmlRXwR6BZ#Y5X#h#NV@@$eh&b/qe4Kq?44H!>el><\RHwXl!5
i!S#uZ 1cm541\<YFq#pD=1+ME#@@DYG#>?+&ej?dmibWQeEllme4AIKPPK9GlHn#DT$RtSw=LdyBKDm9XNqDbH
=#wEB& e^M=BqiJWE9Lh=b>^twl<W&!pelZXCd?9Gj*$>8*d>&<+iFhFc?@91@&TP&Qj9n1kYPMy9\G1DJj/#:+
HHXHD6 A%=aS/4nj?#b@XJ>1mPqhFc1T$^Mwyc+9EkXPC\J*pBWl&=K8p+ajKZ!/<BA8mi6cIw!DFJ$lL&RSBb@
L&:IuM Se?4Kn#M%++&udE!SEKIY#LKEGj<l<m>?qwK*qhMn+pXp=l*R^#9!?lk$?D1@*T%894X!u&9I/4$^cn!
/VS@*n h$C&yww\yi<Hc\@m%=Gc/u>+//$*jAj4mImyYEepBX<kpTd=*<iWHR+DT/LmKNi^FLBTu=BPFlP!lZpT
Q<Yj6a mXY6D16$R$NZh#?@+*6Qd61\bhPYB:@=#P5%S+>ZX@!ZH?:/mS<6wTCl56hph@ejeKlh16?%?@pZ@nZ=
5iH/AK /%SKK*jlQTKVhu5BLVFKY*At#HERXuT9lP66FVhNI/=DcFh><$6?qY^\1qMm&>WqC^?a=%E&%pP+59Tn
8Eh4V8 jG\t1Qlj+F4mliDIKQjKFY/KCXB@J:1PVtI!e=j5tcyT=#=N%9$a?AtkX9!w59JXmi^4EqV<DtT6A8dC
Z%BL/P Q/w4D>bY%kK5NaePun6+1Qdkn>>/+?!:VFkyEeN%696yaThqPhIM!$JuF>wn!6Sq45jb#5nNEcW9wpqt
464KXI WY^l<dc1:mC\EL::lB%t:j@/9!h*@+jV*>:<$JcHNn*<$KdH94i%59JA*cp1%A+dVmp^kk%^\<tV!TRk
WScDnw $NZ>\c>*Q@uwD$=i9u!/wd=Vcy/awKTqVX8=8*IdNRj!WIAy^<IEK?1IRb/neP%l>XX#1\SwJ*pmV8E=
@M#Rc6 N8M!AItPG#bR81Ea!*a*MLwZRwGVH#c%?lX88yM!&EM#9LK$MM9NB:u^piTb/w4Z>kGpFc>X9Fd=I$T$
1TSJq? RqIYLDB<Ac1ELJlk65RH+dMckc$FaA<h1kY*?@NRSB^+kJV8Z6pRe&GJ59k$=*4ZTAkdJpW<N!KLAWye
DMVGLF bAqFleXI&LpbJm^aTCD5+Me9Q@EAHA>9&jVw=5ijKC844hn:@iiA1V8ij9y=6L^A$bNMXIT*>>wRRQDd
GM!<!j ?lej?+<QQu?/+ZLD=hQJ@$+ZKw$c%b8t=&n\#<<R5AR6?Xc\\8M#1Q8H<^^1cmFe\hbKw>5lI\5/CGE$
^AT1/i !+1^FF!Aj?W<EnIZQ!ytCIteQ5mbb4PaA#i*R&a=jMXV58A<R==%6Lj8XYLtc^LWC1I5@p4E4YG!M1^A
9?:Iu8 ZYA4RLwQ?R4AH5TjCP!S&81*QkwM5W^lbRC5lW$ILjQ%tm!*T!XG/lQDXAiRButCC*n#P4BkmY<V5JNe
t1+q>V %MHI/TZAhDMit#a>X4c*54y1:#QQdN>Jlye%R=caVy%5cDnbNDGS?@V@JQe<<e$6D#:\\mpAqaCqTAAd
DwVNXw 58DCKAmbuKbPGn\VA?8nmuThuy**//>#W=VuwCww!<\nRZdZ!bbAR66F@MIeX*tlDS5/8S/KFXZqa%8W
1h^?lJ 6ERE#9mMyRhXkS68L9a%hT9*PnZNbynC+NHi=C89E/!9\nhpceX4AXpqZjEj%jlDpdXGRuyIjkG\l&wQ
nb=yd^ H/p?$*n?R1kG&=:m?\XGmA4%HT1bb6Yyt<tKC8wk<aVXSc\GBMBPVT6kX^nbFT:4WK4D\H:<+8cHH*9k
y#i+\6 ke&d6&#c>Mm#FReP:N4/*Y?>lGFT\!tyRTC5!e6A%5>uiu8V**qm$/cHHu#!le8u*&>wPN%\?w<up=%<
TAtGSm ?#G/VKQ?BaTq5n\QwZEMRhAGI/\#W>!*B4j^T?Xj1byKjXSe=CC!ypkS:&**wWW^qX1S+CSpl45SX%Zw
tMEkWj lk^GttL!1!&bF6*Db6nB+4Q<i\59mapVD<Sb<l^#eGhGt=K9:*8hWGRkZ!N++dNCe/<WE%emVhHFAtQ*
L54:\R HcwlYH&&kmt8Qa#IH1q8BAh:RjbX?SF^X<BZ/ZQldYN<pR=pNyuW1jceahq^ScI^AL8AqZaJLFnm8ZpM
h$5^bI ?El#Ap6<@iX9Q:Xn%^PdH\c?dm&4Qu1m:5ZHj%AuE%WEFiAD5q=8iH9/#6?W9@mh9@*t=weijPkHJ%En
\&K^WX jl@=inq=<ZjIMi/kbA%hbwP*F<FjaSSCB\ptCK91Y$Neb/cWHbd6A%&hTw6J$aD8:Wl%KtlHtGPauGDJ
u=+=Y4 B*D6yB9V%8:*=!B<p1/K91+$l!Z6Vww=e?li!R#QV+*&:1ubB+m>Y1qn11KtX#Y?59&XHybCa8S4>TE$
6T?uIP ^Rl5Ljua\+h4n^+?h@n94:V<6>bR8!tQW<qZZ&QHNK>LBbC5ljZ+6R=tLRFLLyb1:p6Tw5DRcX:q5JBW
Bw:\TB Z46c6/81/5CPB^=><npM%*>!:NTdd!dSw==pq+1MjS>k:j*5:bj@$\PdAhYHH9u&<+D1?/eS&55N!a5y
Fw:G#X h4CpHuAQ%9mpAlc>PTA:!cnPVM%PAX$=HPb+YPY9FDcS5XYtq%/YFBpjYh@DWnK\aaN5PY4Q!NkJ@Tw:
cG:&#m X&YIR:wE*%ybY8V&$5Ekkwiw1di/6pctMSWK^p4jJQQ*X*%LDJT6IkhLISM!Xca:6aiI5aeSX9\<e4V&
X9MMCC #BWA>n%j/@Ljawe$^DB?yjk!R9p:SyDZ1LcqFHHt:E$Pmmiy?4?kFcBp/ETE9Zp6Ydju\HP9:DlRh/C1
LPkKdD 19aIlP5Hn11mDYIKnAT&NnSeVw:$j8iB^<AJd>u!+GM9IahS@MjA1i:TybRQLHdDaF<mMtBlGbFdwBCV
S9E+hb lP5bhK%kQ?bXlXQ^NdDDEB=%hT4j!1B!n6jJXZBbkPHcD?K18n?b5PSm=Shc+w\Kpb9%Kq&tR@aF?6E\
S4Q?D* ^AM4h?><@qqVLWXDFR4QX=tpNYTBK!9wj!1$pJm+mt=YleP%<wP+ipnCi9S\@cGnS+?i\RamQaWN:LD@
ck?Fk/ TJj1baM\k$8W59?H811y5&=aBeZW%4G\/JiLq@BiV<%M=HK>!V%:Dl#a?X#b5#8Pu1m9QFlhXjZKkV*H
+?KdYQ 1HlP4lZLN1e^M94+$!b$\iCD$dP?j^pkBXAleD1b9ETET4HwTYHeNa+\TeBbYbJc/^TCCkjA/16kK+5!
BbGh#F dlyCFV?6X=1yMNqPL+$j+Gb:TXiXLMMTjBjk!n&CHSRTW?kp8&A#LT&6Pq<#HCY#i?Z!N8HcR:$AbIc@
TM?*Nq @L!ywydpI^?&T9&A^Ed>4JD^eA$>GZ$5BMVXqdWWP!GwB/WSX5kiQqwLH<jQZLuT>l8b\1aC9ka%MRw>
JJZlE% Xj=PahR%=YMHFGiyFnCK%k><LFH&6t@>F8a?/>*VXQjtuy$:u>8%c$jb%l%%J++j&A8+qn&*<$&j1$lI
DNc@E< MLRu4@::ut<@l1B8&jVkk=C$I8LM%yMZP!T5KSW/eW5HbQ4V<\R5SPCAJTAKajDe@N#C*CI%V@IIR%EK
!A@!5? eiX+8E9caHKyTw5l@VpXtIR8Yj1k8Kud:?y6<\t4Dw/QY*Sb\qh>5I\mm>p5Nm%<@pqhLbK9=8C4Mm\m
@%^hDk bG5CitycW\Z@yE#HF=$IW^@bR^\QA/d%l@EVTH9p?QHc^5!HH:b@1HBX?T8y^mq&Rq*hKu=pkW$1+9+5
AFaX>W BG4ep&u5#DVi$5<Z5j5Ep6nQQ?5>W%X#+PkLP*j8&4Fn^>cu9:j>J@Wu/k@5*jXe&c+hhR$!DEaHi91Q
hc&Pa@ j&#+@b>i*I#^<1MRB&>/uwMy?5<@J1>K@<ecMie/uD6AQD=NnL$48\+RW&/>a5Q^JbZXPY+cG9S^^Vc8
TK:9@9 Vm\%$*98/G*4$JH6XLpP=ZtA1!I5YGKTuVJ5kF5We#MZ>LnJV%@l>VAG+!9NVe+5j9X!Xi$?mt\S1WwA
ewKm#< q%BDJK61K5MM49E#HWuZ+EMba4dC#Fa\^Ak8jB\>i9^Zl^59junyEy9hXE4u1^1%ZeE^\n+&tQRk?:5w
Q%98mn hy1kT99$b*>y?k\J??Zud#jXHRJ1X6WjjkqA*j:$$>>:bH9h<SQJ+#9Lu6&/>Re99M?JK*uQ!<tGn*@:
I=Hk#L dW=9N#*$$AM9AIp^SEdaL!j@=Zeyij@y^ujkGP#tjlW5paAyqt$S&Pc/8BD$T5w/BJb#6HnaD=qT1wBF
>K9Fu$ 5ukH9Z/:Gn5!%!G?yu*C6thpVP^*4di$lkKu\L>KhSn%MdlZN$euy9:T6L5KbWAKc=tX^NYD#M5Kpk$b
%69*&Z VF>B%IRJNMRIcnZ4mEDYkK&Hc<G=EtGQHtXpn#bi9MTcp<dZDmY!?$iu1tHJ*9miQ$6pTXnpwHl1+8&t
N&l$pZ 1pP%u*%?i@q9ty1PHc5:<N#*!*ahPq!>@cpu9@Zp+=8i&uu<^DH5WN9?!BNQ9WuAwSuGaQj*/d4HpK#j
iL^XKB *QLRqpelcWZQ&wCi6iFp<kQMMqMT&A=1/KApLN*NBRBk:II$@hkRiX5&4T@LE6MT+e1/9+!dqH8F%$RL
-A&TFW 00038bc69b000110334 Page 85 of binaries2.zip
<j6mWy *J:m>$#YGFQb*yTj/%DeqNaI!/wV\htKCpTL4mXT>%mLqtq$enTM*b&nL?>lTaHmH\1FpIaX95C9$=MF
JpH/HQ @*$%XMFlDSGR4n%I*lXAQTRJK:NZmIZS8T1?H1$@Yu@<X@Xut6w?VQH\:iAE6q%bI^>XVm>IkSyMZ@9k
#+IlFw cq%%5wh^qVYimhHi<yjL<FVXu@$qtV!bjQMuaH@L6t+@XH@p<M=9QjdaI*?:9j:amZ15wNh6*@=tk*T8
<QM=^b FDCq4?/GkGuLJw!Dj@A<8qcKpW<*uQ#69@&l8$8/jkW5yh9k@/mqa\S:T\DabhYE5L!<54T!9KIct/uT
pQ@&P4 TSK!\Xjj8dJ&TubV%utX4iLYC5A%HjK\Mw66JdytjMty&djDtTB>=b\M:E49m:5P%dKm\Hc+5w1kXH!5
M=%@*9 WAcbpH$hMK&5*L6*d<Zi9XWXi!84yEBe1/pTHDkhITMM5ZA6A$8kHn%ij@VaL*>bZ>h$=XJHb+i!\$Fn
E@9uu< eRC4LKWA44@@8G=Q:T@Q%X>q^uL5NN4:<8/!R$jatThQuZ###b$:!cj8PuREjjqlQN8^+?BjV%AhZWXN
=q6#\K q^5cp4@>F@T5kP1tLR>8id:lZ!Hl\YkK<=:@4aAACC:8?ZY1w%&GN8V/$+QKFGM#YHm&u=#N8WJ$BX^>
GtcqA= jXmGVT1@ATnd!ElJbD5/kuqTVNkNG*w$\4bVSN#KkmKm/>6lyR?n=JNlZLpl1&j\#%ejiIy$BDCm18Kt
a6=R*8 DDDF9VY!&w4\:c8y&F9%@dK!5tjL6t+Fq@WM@Q^?&ha!iGl9&T6X?DK%KuiXhlleK$B/lFEq9l+@>u<d
en/w%^ ?@Pw1P=$Z^lQ9:q4tSA=BF!AC5c461JkBBWXpBuVhl!mMXQjbJ&%<48kIJNaWqYKwy&pqTRtCM4XNNHR
ASu/Gy NC>#%AZy:5ASXCl!?y+IESG%tWRGIa16J>P4h:*@@J:Q<*!@i&>M:449*qXFMXlCjjdutRhHBmGdd<<6
GEHJ>T LGhn*\lMtIJa$8=C&Idt=nldT5b&a4:nIy9Gq!>h9jy%dpL$EkkF5hFTw8^S5c9DwXNulyNp&I:@LTMn
VqWwAn k@+4E5VPVP&::mSZ^utt5huQ$\iKqT^l*!h*:>:=^e:hRqju%\dBC1Q>k^$8FyyKd$pnIAeW$c+:QDyt
BGE=!\ Rjb:5#J*XNT4c8P\<LXG!ZbC6EwlK*#XShYe^wIedyYCZmJ5NT6aFb*+SLT4!%C\ZQA$!S^tNj*qid6Q
cBqhbM EN+bXw^CPI+#5I&:tbt:qePFt*i>9GEDwdq+$iKkpKDFaTHlaYS!Lkpub!KGkF+TT9jqG!I&SCRt&9B&
ZL+lt# d#j6J4cHW*Fn58K>hpD4EYqhbY\+QM=ZZW&B=<*PPF6Tcl/>WHd1hmj/V8q>dW/aG:R+cZ9&>t%mw&*h
$#T%=i F4p/Lm^5XhCmGe<8T5yL$hIB@^MZC?5TabLC#wbG8/@aT%=i:u=Q@yZw8yMn@d6*=%//BI?#5e=l>*@&
w#L48& &YAH*u!<>jV?X*MKClYFw48I5pc:1+Y%h/TKcKC@V:X^6C1S19mK/%n?a9/n>VZhl8JdNlwXZ%8XIPcj
N$DjIY QGt&lHEBPAIVbwSah/44l19Gq9P^HnQC<8Tcb^iF$#K5RLeKZatwY?m#X#b9IJN!WXBRWFl$YFna/4nX
6e1Ph/ SI=aiwmMncRnJnImImKGAA=h5uHJ^wkNmdbEG:*yk8w&JaWX5BpP!Mb$9N6b?W/:*XXbYYZlc:$KyDK\
i!\$D@ DdZP?LkawK45cu6=S@9Fm@a+H>>\FciWl&*bmSHldt/?d6Pt?5cIMtjC$9?X#yZCm4G:5=!qb=yn9h\<
q/8Q<E Ac4ZE?=#h\LWuS#u@?9P64:8#9dY9=!Jn*9Y&#5+wdlT>KBpEntCZhPwCy&:SSb#yhWEtnplmP@wM1KB
?>Se1n t^DDXnueyn!ccy*A$8yHZ4>G?55SFG>BjLlhlS@=y+t\LwY5T#5/p?#lV$:wjq$$u6RXBQ1+Leun6\XT
i^?iLH tG%bmR48MqJ\#NhEluRXRdw/iuZa/uA?AYwW#1m$KIKZAa=InIlaplk16E&EFE=X!6ZBellTtGWnE#ch
DT%e>i pM%!ELRXu:IIEeLY%hWZ%hKjXF6dFB<ZFEM!XTJYMMG!:Yid+/LhjYMT\X>qhe66i&KR6?<$L:<I@uEq
a#Y?Zt >M%LKJMVPitqb$8n@SE%>QD&i5b>?twCe#j+Tl4&4:u:d@d%jH$?Qm:R<>ty*9HXPuc6aDA!%w*T&Ml6
bm#Ikc J8T:*4/6nGHh8VpC:ey=QDPPmKAE@+q$@b:pX*ZXcM=YY=TRJCmBK:e9%t5F!<XP\qmZPD18!j/4\heG
5Zd:Z9 i:Tjt&>RWy/<LSLYFcPYli>YXDAS6C>6YL^wWiC1/FY4\1IZS!<PY^\iE4+a\netJn\ml4CMn!Saw*Da
>PFGF= /a^Qnw<khDeRc!M&JmWtpZ<D=b4CQk:pw4#VtT\iWbmN\wX$P+up/4L1<94cl5LtRu68EX&ylZHBEjlu
hjtD4Y WM:dGXpT^Hq^j8:?Eaud6$QI5/TZBAPDt=RaGRF^4RR@m\h8^Mupm6JVYe:#Le*?un4A=Lj/!d?TECbw
=>SeFt tc!=6&+QZ<8NuiQq<c!Zl:?n%uDB>L9QeZ1n4bTB:XWb@lHy+S^qGe!\Rk!4eu?Fc#%b\8#n6J&5Mk=D
#qkYyb IB58LGIVV#^l=A5iE<R5lV?bHQw*\@=RF9G?$>!tBY*Vq:$1adFJiIEL$uaSWVe5CRwMZLW1KIn$/mLT
p\dtPJ 48lAY:^<<jPL!Xwme+qWc$^EVA#\na>Mm?I#Le$iu^!bGGEnaBM*JmdbWp!!AqpCN6PS:tV^tM=q9Kn=
HAtL>K #HR/HIT8ui/y>4LcYphChQm&I*q=1dk5tLMyuEBI<q?W5q$$N^\y955jpJK>QT<qn*>&8=IQ?N@Tydw@
ALIiQk K?8W$>qCQ18uD<\q:/uQ#CFWAT4$K#%y8#Y^Q&G8u/iH#%TQ1eHNbwkVd@6JXW>MuPWPV$=G1M+\RucR
iwl\Zk a$/IWA\lcM!\>ud44ph6N%q<HANVbt$dB+4alY*p^l*C6X$*XmnL!YZy86b&p$9QDDHCEpX^$/d=89tF
wACFWV d<6V\G:hbqNGp&&4#4^6*4ypmd>@aGDRwwYLF+dA@8WdGeEl\FVh?B+SGlFlm+!IV!dGAq^uXJw>MwuA
6&j*W* JY\ndIT6>uHabAJh$=t8ZMRL=beqd#?mCM:C&9L+8NXSS$1P=S*JI<MYTAHddFA&JeqIEnFjFYhV5w$\
hHI1>q CF!4:SICwY5IIy>lhV4QZD\V/\Mb:P*l<e\Ve*aCXeAK\8c&ZX<V+Pjt:pGKh/y*ZFthBhiVXT+DYEVy
JucA&F YXm&6myb#QHMAhZ%l\/JARZ4NT:*X*H@imP/b8LK4&1yRYh4pi5tCNePdY@XXF8m^JdAE@NXteNmD%eW
S4dFdA P+KjuidtNnPCbJc<I>9E$bE1FlXNjCq^5d?@@/KFhC^i8Hn^\q?^a$NWyVQpijF6mK:LI=cR1dTEViGI
PFbZka SF6pWn\^qwDhEiXMI/GetAncJ61TpqK6e6nJSt1tWiwJ/wLCn9V$\8dw/KkhZ@#6hEpB+Z1ESDFRJWG<
thXTKM HaC^+<T*:BV#tbFmIDZ5MM\t8yR!kc\VlqNy^=p+!GAm1<hWeqy*C14<\huYNheQcS&R>X><+5<&%nY\
t@DRuT =Tw!pG<Ek/XqYDY41ha\>JpMePQjAE@I/MQIHnTjh%n$1<c%ml$u4l$$eK%S=h^eTAn>1l!pi4GeWHS/
h??8y6 Wq^aIi\Jc<&Vk4ZaF8R:db1d9&jMN9&tdGQG56YpM1t:ElMZ?e>kWBeCXBA%BMJ*Meui=VmjZ@I<Q>L#
8Q%FF\ ^CZET4wqllK!SE>mKtGd6mN1^++wi^yBG=GId!dbpqp\55&WtcpK:6qM^ReaW5=Mi/HjuK#QChY@un=h
ZwM!H% RuL+CEqmN1ah&\nWqBS6R/Yc!h%JGBPpdDb6V^Yb#?db1XQ&C?*PPb/K4B+iQqE:YjnKdjjZ=/h:8ut/
?BM::j M?Vij5+9&Zh5W&R>KWiXMjAKN1iEuqnLh18ThYpME%S:i*kGTKiWnVa$%p@tK=1n19kXBXu?kqHVc5FX
a?<S&V 8dDEdJi8mhGT&K^RbDq<QC@Wh=49DDj@cWFJ?9*R:9%Y<YN^Lqp$a>EMwYwIPc^lIYHlaiHl+dHl5bHl
81t1^/ 5H\nIptyEqQJ4%t?ajpGym5IT@kS8tRLS!dHy>uVkC^lc$?mL\NiY%I!&cmb11FNWFX6m8!LyMj/S#P1
XyEyE6 Z?BiWpB<#e8AVIZ%SXVeSw>K8/bcaDX9au!#@e%&GwidCy#Pj@9G:8jy!bl/VQX!&:H#4@wp$?tT*h&V
L\u:NS %K+ZZF49Pe&1F=Vi$LcVB1!jKGT4Lb1\SZX#1nE4$pIpM#LwT%*e>Rm?N8lcLlG1%XwIu#^ytp>6J/YR
kS&/yZ pEMV\QZukqlE5W9Z^YnDmeX\W+#9#GiuEc^8+amm!48^#WBYAwFdN+R5tnEVwAa6DkyD9Z\aklC+pSXM
cnBKLh tMJKa5etm8=plBKW!#h5ZEK5*GAnBIt!WK1STeq&am%D/:SDJJNM6mZGJ>9VGXpS\:5%59lcYqlJ!b@P
W<P6&w jQHFcWIXlDYAVSHn!eGmFl@JPQ+=4NC@lC\I#q=PKpSD8uQ*yT8Z+>^aBH6=VQYbE:cV4GClK/F/@8J1
t&Kq$S R6WhI6nd\!j8/$5/J1BhDBinK5YWp@1GL+uH\$%E^F1ptHyAXS=<$6W6*c\w4$Rywp+p\F%X^$t6816W
t9km*y \Rn1%%DX>eRV*S&6!6PyF&>458Fp!im\HM:#j*ac5>W6*L#tJi1ucpT*de$t^+bRZRTZNTkwLGS^?PIa
X=4YEV p4>$J*PJDPBR^CDwStaT+b6G&CbH5w$EA#lmA?kKhpIiE:n^!R!6$Da?mcCF54Yuy&ec@eR:DGSQqb#?
L!QLc5 <&iqj!K&Mq>Qm+4Nb=\aYWC/nhY61F\^plqQM:mquS\PT=DqjiH1^hX#EA$GH=@^DN9=BaJLnC\m\:HS
%M$u9e :tI9ij!L:>#ec=CA!lJX8QK<CXWq1&1I1uZjVw5$a*h%/cy%kH16Y<Qc451HG?yXaEJu4=m^Xca5Xp&b
Cb5nWE !Dk#4y$@E<V1h%D%mbPt\=*I<Z@Yh<c$GZ:?jpGJ%ujDKwq*JT/eMaNBJdcT8$1*tMW^MTGkK5HK$yjS
ZD>J5P lRpeESqQhlJbTwS9emTpLRP:Ecktp9ecTacWLhK85CZcS6pndR\/R?5$JkC\RC+yKVqh?1iT#</e@65Z
K1RGt@ y:@+G#G&=EkBE^d/XiYETBRDWZ%Xy8we4&D6WP=414KcuHdu6c9u@iC#I5Vp<a^d:Piey%Nt$&+:&W9\
Zn1aL4 jJ:%t945j>$@$N?4J8#XT#LFXYYB%ZZTcDFCK#bH@T/%hEwqdFi*FK+dk$?WGP=wXH=PVdZP/Fa4Mi^T
KiE6?P \Fbb<=SmD*h4#:jiEMT8p^d>c9FjQ%1=!H@c6Bt?BP5M@\nw1XSVDt@LX9t%mCWL@aH1a6^I4!+JC+$B
>?LM9= R!MRddASVSQl4+K\<kY/E%qJ61alLJEeu^^BuCRLtG/lyGcVpyJ\n%eTYcBN6nGq+=QV$^qWFAtTPZ\K
I>B\Ll 8H:&YWuJb/JiIa$FYA+ieR=Z^TeE#%S?ItbVK8iP5qXpPEY<=R^:dt>jV/+:Y:1R\1llpkR5/E1\^uKp
G5$?1t tDCj?m>iARj8n9V*tH!64y:5aH!mpK&TJI!c+hCmY5$Xcdq+ub:KPIXY%TZbIGEJ\XWmVTjXcRaw>LRQ
\Elndq q5Ph$6u#C\1Ya$+unQc4D$J<*EkE?<:\>@j#D<hX4/*IdYbpat9M\5DASa^yVGlecN\KS&=PQB?&iF65
ZdhZ&E yC*GFlpVGtMneAqTG=Bq=!aCJnBaTY+4Pc:JBCddTS8kcCN6yGpB4Yd6p@B8p$BdRL5D\ZlY5\R4ejXQ
PLBNK5 u=YWun+N9u:?6<?@PF$CZ$ieFk+^K*H5EHG#ZV85&%IEa!N*qEK?en+K91<qTF$cHFP9PV8+Z8J#SIRJ
-ARGj9 00027d9771e00110334 Page 86 of binaries2.zip
GZT4\h YYieJ#8$#<KeT4n?@b&S@q+%1EyFiwRtLtMPG+?1P/pK&dtDXWc#19L%Lm=iq*p&QPY!6cNSyKuK=qV4
H@SZqZ !HC%GGSXL6N!16IyHec%$/ykV#+G4FqD9Dja#a%AuVEDQtt+881%CFPB8K*bRa5YLXweHJ?Rp%Ba&F^b
nJc&nl Y%NhY%%hYXuyKuMXNd8KZM&F<RT#uWCPV+4AciMVH\ueyQkpP^\eP=!dbNKqTVak!<+4ja??wkV!#l%P
kdZjEP \yc%LRupNQ5P%QTC4ZS<WZLtV!D5*!CI/iG#EnchYLC!8=NmIJ81hC*:Q+4DPwRIW>mi?>Z\\Q++peEM
icjy>T c>mPW%IQ99Q#uZ@h$Z\ttlFuE>q*#RAGIQd*+k%65jBXt6yeK9PyPF8q8y:NJpA%PeE+P6V\WwP9NbQn
DjtwLk E1^hV%by^%n%<c5iJib4l?4aE5Nelb^PYk^mIJ9nN<%Q\?wjqJ\uq:k/Xjl<c!Kl85!bY%biDn%Q@\&c
NBq9Yd jC6^FQNJS*X6VY%>ZZN#8VMi$MZdplnSJHAY\lZ+yjEB+ma^eRE/CYM!n$qMR!CuEdI:IbLnTTLnY@d$
A\h8@5 4NLVSNaTLauQjQaFXP^y\!cYRKTa8TqmHnPMEq>$yIlnm$k!Y<$IdiXi9*Xu@%^&YkGi8??e&K^VWnP^
lX:mN6 ?@PhZ#mh5S!t<Ib<>9LLHS!baF!lZ?Z6JHPq!nIQ<?MVip!TWhJbLRT:%NnaaR:?+Ht\cpyGm\wQT^XM
&=SL<X Dhi@/PmpT+\!eNET<8A!a5%Zni9QBdG!t%d+#jB#t#FnJ5EcPCMwKW@F=RSeMb8&b<jH^bbj$F1?qmMh
W*WwJL %dWXXbYXFZRT48WXqRS$dW&DnF619ZDScRh:p+mZyGS6bCRSS+tBpR\iHS^^a6B6aC%lut#HVdGY5E%L
\Y9ZML T$:bqySKDQ*5DMR\QVq#twA>jiaLSXkAY*Bp8$NSq4HX$C1?E5IP=RKq1J@I!Mn>h8KjD@&+MI*P1X:?
A19mMR pchppART/L5@h$d=RRR@C:yP>a^88#q\t@k/%N>:qiA\JpFPc1Q+&DyRl!5hWQipC9X%9@tp$TjeHKh\
mFDMhM 4bpWH^bdiJKP%e*^k16S!ql9^9=hb9Tjn\?Y8SG5BCykJTtMQ%&dGcJlCXmd<*K:>wZSRXKLwtXmc>8u
Zu$N4> qhYX^SZM&HJZQRm4C<w9h@eMZL?iT<\qnY1D4IW!Je%JDGb5w>J&kLn^@G%mLu&jKJ9G!Ka^5n6*P6j5
@%Va=> ?#QlTBRq^ycW\mR?@btaVq@Ah1K9EtELMqLVXi+6SdS5154Y5#4b4uT45ykeD5j?pd6*%4m^CQalRp+N
C8FFNK VD5qFSM:8DdNcjm#pMF^dV$*MX*n:qB@V%iHPcNK&mlePkk\1VnlyB/B\k+QD<i+%GLYVWwJJR4+G^w6
DQpZ6y %SLXWu+B&?tpaV^Jkq&%aCCTKH#XIWnX$XHFF9puSpZM^@8C@elnbddPIK6IaE*qC>!I\t&*N%>1d&@u
al5m=h IV+N^FXC4:yTbDCy%%4tK:GYn6y1/Rmq*@1d1#$*S??NDjbiKLWV6ncCn#WyWITjw+R8C&X!k<BtTF%a
>=QEeD WCTq$>LTh?#P*ii1ePZ?CiKZBjFuiQIF\X#K>9AZdD1JJNbJwXSS5\:P&DQEnt&TG=AM@9bWl:*61<Fd
JKmPLu B^I<FX9J*k%LL*G1#Q48W=@9eEc:AZFt1+>9jFhQ:$$MBSpd69k=%Vw@^6WJ$ydwPt!t^WVJKwiuWWai
?:MIiD MtXdnNHS$l&H:6ecw*uD/5F1J=cuLqYbmV4C6h556VAmJJQq<D/mKdp&BPyC@<BAj=LC1humImR:yFbq
5X5p45 Y*ci9i*1N^$wm5TqYq6QbK&84dTwXqhq5hK\6hY%eJ@yd&m@jKYuj&Sma1m*8:Y%nt!1iF5!^C:pLeML
Ejm=m8 ENuBwhMJKBq*Jnc?:LRu8Ll**6Z$J$XVHGRNu^FJDCu<N+=PpCVPX/mCnklVmHt5L>FWpe!A%iG\>\+M
nQJFIb :=@DXcS5CH8=li8^A/^juW+@nl8C4S:?$d8:MM6qlPjR>9QkXqW#^1JQtb+jjm\nCX$jY88J1qD?wMc#
KmhcNZ k4KNiu!Cuu+m*d^GYAKXW1wM^qW6pqkHuE=YG@P$VDt5eDYV5CiXcZ:C6YKtQ=HXu>m/!H<S$VX!8*Fy
tCkep: 5+JF8DZd*6b>=awY\:Z%ZE\t5BJV!+9yKCNSZE:AXqTS+TTnNDw8Z?u8H:=:n>/MDkSB1\pkG!qcP<F1
TJ\dJN l=Gp5IZ#T6D8aCiIncppyH$e@%$F/Kye8Z?GDW#I\uR/ZRIwmdkehaL%^JI+n?S\lmy?p=wcbS!umqwl
&n!&<^ p+tVe@py#6:i@q\@yXlJ6W=%m%eV8HB<9n56%w?4t\D45*PcL%/>&6QVQ+lP>N9Djd&hB1=X^y+KuqtH
&F6PTl ieCaiIbbYPb+t^4P!ZIuaKQ1aXYDyF8qTXu/nR!&6y&5%wHE/ppPdN9J1lyLZIL=&6ywMb#EmD6=RwBh
+Ym#\b +e<t<I!FM^jNRCw%LEpFd4JVhaS%i=:#Y8@XK^mL$>JIL<*iVh6JAyYB4ABVm+8b5ZVRu%E4W>w/&1>$
%lb#FD >\*i9Vjc*>$JZEqqjPL/&HX8ye%tb>MZJlI:5=C>cW/!qRlj\yc?dN8*#@Y^Mm&JFc/TQ=WI4JDGb^lL
w=EXeC eZa+>MTE#e9IeEl<WE#nFI6EXp?&y?a=uM*h*d$5k1Fcy*yNhjhQp$FeHN9c9TQc#a6X1?jWj@H!mL:\
BWM%4i DW@?:^>Eq^\QYyb+kGYmuA\>\<^aq^=dNHqTNqw$cpTC!tSlGRjiKNyX6ih\YEIXI%c4@K9P:k4MdXY1
>NM=>k 1J9=1p4KYTMw94K&X>H@YVQ<=#Bbb!\m6kaGJY$Huwdb^L4Xph9Hc!akllGm41$$9S6ZPSG%1FkPJaq4
^&YGlH SPy$ZCdDcin&9h5t4me^p@nk8ZQ@QTjH^ya9Q:BN#CIb6N*lVM9b>><QR=:yAM=J1NnVaC#BYjwuRqSE
uckjP= MhH%m!>Pc$uMjE$*>T\ZSalIhmmWM=LQZ:4W%Sc6jFbQn/pi$etae/u1%5:565>^B%p>+h=+iMb?@e%X
PkSuBH tTLP+#XGB@y/4E51aKekI@clPXeWE+FX<ap^Q%S/5qY:ja61u84kWSq1%4*Xd11Y5X>tc9&pT1*4RbGN
%Ln:%q t1>KLcK*Zihkqadh6=VJT1DPJFmDkwLCW%RRFeaGP#py&?^jaja1+h11Xw>wXEY*My+EdbGJK@<FHc&Z
lZRP@A L%@6HTVDccCuE$!9+cHEl*u$&nqk8^KSCH8/QR$tMC6Ykndhu4Q9*H8+>w&SE!B5+Yi5aeHV#$yA&DN@
6ELuZ^ ?w\b?#hqE^P!mDb\4cyWZ/Rcba=mQY%*yNw96q</H!$?K#86Q4EbtTy=qMYV6?b!VJGDEb=?#m6ZLpEK
\FTTpd R\!nZ*>$\Bn6YY<biI>^9*y$6=+Z!#MJ4VQRbWJ4w^+DL5TqV$V:Yw1H#cKyKnMD1\66$Sy@1XH$c:8S
*AlMwM M/mSuK&G>eTKaH@&dBnYSWEELQ=/cbiS/A#SNje/ZcXZ4&D8ZKNe1MwM4lRBDBt5GX6G\Jc#+FEGeY@@
$Y@BYe dVKI4\t8hEtS=YmMTmS5*+c/VW=u/=jknW>Kmh>#:l#QPmYBy1ePRe9pH9u#b<^TiD\k:Beqb$yPj!FY
:ku=e1 5bLE?a=$SnXDKXqF&lVq%nyTuF>&6Nw>haDJ$<QhN%KlKlX!#Rq?1tICyeN##u>#=RytCQZ$*?R>HZhH
dLq:P& GNiYXlR1MK=KDC8!<y!^R<aRhE6ZnP=N:tJ^4GbG1\pwZjW/LKH=?lm!XRbjLjFlcZZZD1!yaDu+H#\n
l!Le=a EIEI$1$LWXNIhN&8jV+hSe!&Z^<h:P&=Cqnqbh11lK&8!wym^4NI&Pym=5KT15YaT4VmZd:c$\??p4GB
Gi&Raq nXkaD/@+19apEdS:Zw%A^nYhLPK$NN9Ke?@KcQGDRqn\Fd?9!>ZM9k:d^KebWNK&yWLa$*>D:RRBm?yn
1/MY1h 1!VYD\S1Z14h&hLTinEYSH%YA5LQ?Chu!kSy1bDLlh4%iya#P=/ieRV4JYPVByw!iGI48#pc%=PmZjW&
#4n&8l G&PDkp!MNaHXE#PpmdYLch5w+&q=eJP%&N<1l!%%mVIAD!M@Ynwt!iGGinNq!Q:4<YW#=9kH#qtEeldJ
N5iQhC yt4ZqZ$?EJb$/@=SdHE!^DByci*eCEuywapbY/R$dLpwYFn!*%#69nqKnp+QPV4CX+!GQ&VM9##**5F#
%wS&yj ::=::9ZZNpdAnLL6PYiPmj@\pLqal%Y5<<>pMCE/kVmmAF9!&Si5aEFabm^ZH/QP$IK6*DQ5yjTGeMVZ
HaBI4= R?n1=S/h188WWdkYFiknCRA$Y:u:^u=NwB1D9phpdEy@V=ebHnbHb^@Y8L/uwCXp!T\&N<JXc%q5nFLA
8qGS*G >Gm^tuRa5YaTZ/84JlidX15KJ++*e%!mw>Wml/6XykBq^DNuBkdPCRT5m^a6DAwKC\1KTN&81\/pI!4F
<Fp*/$ @9iJ&<Q>Qd^nwyWuC+6&XabTETV\WYDcyGA8R*CCQB*l1*bkP#G4nQu/5eLX^aR>>>+=R9de\ZjP9Yud
X@y/pN 8Pih>>=Xt=Q\BpGa!j9!mcna#<S$P5$^CtV1V5N$RuBCPV6HC9IhZFb8A194X?*^=T&6#9k=QyDBEw6\
:qqTc9 C\imDqXt/w^$i$J=Q1SbTdX&Zd%1tWM/!tNVB8HthE#cZHjCHIt8^!5jMkilG+Z&=lT=BtN\1b=j&9C+
/Cdm/j HDbC^JQwcla+kc>hF4=c=DDB8wm+Tla\p*XlpKL4hweP!$nIQ@jiHjy4YA!4hS8I>MPuEjEL?R6Rt+1L
eG6J^p <CCtW#q=Plkq$$wP:M%l\4Y91^&+I1u9anuM/*RPAqaBF5m???:Be\jjXV8^D4%*EP?McVuS4=%Ll9Cb
16ISVG #$?ZqH/GwPIZAmb@EMITa+>penEcWLWc^5tP5&hdY8!I+@5\hF/i@tGS?h^K^<Btyai=QiEDJn@4SYTh
ZN6&:E G*i?1%6QT8949#p<nDWch$eH?w!\lDH1Zk>EN$jhc<bc@J*HkG*+JX^4hE9#L^G&&6\>h1t^%SJHuB!a
$kF%<@ PHu!?A4CqYEFZSe^ZYPp>B=*1iyL!d&F9/dZ<HLwNWRKF!t!EykM/%EkY/\$dGW%QFk$d=MDT:mPIPAE
mTcjRt ZCjyX=P6=>:l&:9umK@tGF5!Q>A!yAlLJ4?4<DTm@1jBY\+*jZ:cptQ@Anb^TREKXXHjp5G=PLtqNNi%
4+n4X@ NNdF8jp\H%q:BmaZ5A^&w5CyIC6>qbe:=>bS/8<V%&bM%ML\yeHB+h6nE@?eGB5i/JFhjJl@1cQ?Fq#j
AQwbNY M&ilH##$wX1ycDK&!y\KbJpH*nAJX$ZaGmPY1JIA8wJa61PwQF&4%FwaZj&RcwB%FiG/pIFhHBRh6Dk5
yh8%y5 KbY=t5%l%i!W9JVeEX/TTH@NN?%K9WIMm%y6KkcaS?tl/Bkit6l/1mkYV+j%?&ZkPucQ9HuBFZJL&eQu
SIMdD* =Aa$*?H#D$SYAyb=4IeVt^8V<NbW=JLeQj*Fb&j?XAKQB#dV=#1#A!i&qCV^pj#$nE^Y5luy:QI+MnL6
VQ?ItB yjVuq$WndAnkQL*e9eMe?iuTT$i*LCe=4i=\Y6t:eW5\Bt1ScmWljHQ+%8&:h:/@e*8\9@i18Dt5$p/1
KZ!8t* lY*GAkN#1>hB6T%8<1BY%a!l+ww<D:^B$>WwZDQ=Yn&b46ZXKn:ewjP9Y4?&1S<?ijLV9S!FYBWEWENR
1K/6mT AMHcNb94eLhL*X:Khu9d4Z85ZnXhIaabXqCXATW+eV@chQVa$Ta&mbG9R+m+H8pLetAJ%=G?d6c9%a@d
l#NZ96 \$#ah@V=Du%!<J\&qR<bL1#4yJdE#TYjE%<@J@X/GuF@X4GjCc^@a$qMwlkhN!KMkY^?l4*\jGQhYci@
J>SayI 8K^k:DN8aSp5k>H//5nKmw@:4=:8uk\=uNbeH1mFRd^>kQZtIEulP*j@?e?:\?V9!YTilpu8/+i!ajGR
-AFpkM 000f7b2aac500110334 Page 87 of binaries2.zip
G6\Tt1 hW9dRaP^H@<e&Aa4b^@u1#chNGMuDTi9==G8^Fi/9m\%d#^AB4>QW#C=NRV4wpYLmc!LWC\cFBKbK9H^
eCimyc dS\k#ubp=\:ibtPl=!ydVSI>k^\8KldlT*A&HT5<yy+eQedtE$#mcqpZ%I:A^Nm>WeG%H9+4<%W:5Dnj
WkjV%: Me?D::#:4tla6d=PZFm6aMu*L8FR$&tEuE4Ia9w4NG!J/FiPVyReKeuubn\8=HeRjM=!pyyTjPa8b6EV
A@=hc# @yEbthK#B>&cH?:t1R6lwF1@\tAiRH8Vb^w!Y&<V4Hh8*:4be?$1b#*4%B/?++V4S^<j%uR>?N/:%m%<
+?/YE8 B&Z:*wpV^$>ahK!T^jX%DR%%kLRP\NT1ihX!1%F5BXcX%ya/NePyR>e*YjW4jy@mqaGLCNdwIIlkPpMI
1b\6l> %<W^p9^\1GKk%P*&c\Nn&H$JL\ji1*biZSW8p4#EWIDbXNnWXQl?p\DdyDW5BLF!aAh8I$DeRZK+Hkyy
n5>Gen pn%M>6I=A9VeZ9JnFX<^T%\DC<J?auk/4y11NqeykD&NJD9J*T<+teQ^aydE!L\ZqDC5/AbJ#T>^PEq8
#Y$niq qZQZnaiuD@HS/^tCqek1Rll>BhHKRGc%/=F\aHSpbHlkePCtPkh9DSK5h?+A%wF4*X>jct*=51/8q6SS
Rbn\=P ShYuu^\H4IeQ$9Hii<w!iFe>i^jIHn=+?KQDH^G\^#@BaKwKlwjiuN4/&wbckyVPiu1^iu1>&84!T4DT
hPcXd/ !H=YXFdkX5FqC<LZ&u1N1%q:*GBM8c4?hCYmEK8CXyElnQ:!^WFllC\:PTtTkCbp<?^h&Gp/NkI9l<W\
=TXQ!F L>5YMe!mq!F6Mn+RcVtaCEqe!R5$aBB#BlaBa8H4CaP9l$RPk/h9E4B9A6q#::=#WE\uTGJa^L!Q>1Si
S=bCLX lqXh/V^#tlu:teRt@mw1Xn8^j&JJ#I$kBG&B*X=KBqNyNMH/4Aw^iRYG&/WDmAtdu^cwmlE=HP!&=6ch
6>W*Da 5hHSY<QeTmP\D6!/ha6kyei?*t6jj@%9F\uYe8RwK+1QH#@?$WejHj/RkMX9@c+e?mMhDP^l?yqQ/EhQ
#acKiK j9wyWIJXCSB4c&9L/aZK/&4ycdt1J!14XyBcMbWdAX=Lq$InBu&4?8FYqiQVLYA=Ra8C$LAc6FnDGl$Y
$@$!PZ E5+lXKt8SYHR>8ci@mE!t\clZ4>S5YFey5X5BS>qtla&=VW^5nklpuZRCXeY/hj&K\k+1eA@QD=D9+KY
PCle?u kJZA*H68:=6:GXwa^jS8cPQnpDXG#LlY8$/Xm9FLuk/mVRR5J\DEhD4DGXwCqnG#q**b$6nm>Gj@lVuy
M8mk*= =SEPW%q%M/hub5Z:8RN\L$dY$&@NHR\K8EZAEnpHB&:hjPwtaPZni6@%c>i?99mZm&jQqyiX<iX>@H><
1Qt@&w >NEHl=t9Jyd9$Kq8>HD\k+MjHQ:k<Ej@+!NC>6Qmakc&4LK<pq/nHGe=Q%dT4dK5w1!!1K!!4LkTTe<!
!B!FbE SGYbJYTKXplakIDq/VjT^&HYSwpedwwSYKNbBKP<P!^5eXCp^JqT8Ee+JTZQ&ZWN5TI5h:&KCllS4=YC
<d/kCC K<R8PAyIHiwn*XnF<8>iLnWVeHSGJ8+PcF\@aj>XGa:uDy&D/$y5jb9PN<<J5Ah=a\j95TQL\:Kyma5*
!iC=IK c=yQj+c+IjlK6CXkYc$1Dj9Fu\F5Aje?&y*\CiKSQ9jmcSH8W>*<I8EA1XbM8wXLIa#EI6#tjuZ4:y%:
S#mT?I \p$/By//iZ*k?qN>V%%@/ldhi=?/%9b%&+WLb</WqbaXqSaXHTP>e?#>D#:++A<jcDDyjPhh!$t*Q*#\
@q/ln& D9*IB^<h??na5iQHXBCh\C51w%6yGY=<FPE5+u5#*<!n8K!IdBbCuRld%@lqT!9pMIweP6mi%u!65MFd
j6$BXE ZdW1LGkS?8CCRlbHl^Fhp:a4k+qqeb:>VFe91ecJpb8mZntJWRQ=W?\1P5yRA6G>hDa%bT6=#JLaBX#J
G4D<\i k$Y4aMhqhtAHinlS^*:P+R@X$m5&l8qkXHG!VH+Z\C4n+/BT5J<wB^aqBT=!ecVy/k!:Pu@>t&p:Kb8+
j@>u=! yCR>W$S\C%ey\YX%>@D%D+wpQAE188nTHXty$T1*:8*8+iM=N?H/$PkakRya4/9nKh#+9Lc@4c*6@Qu#
uXKJBI 8=6Lt\8dC@qwi4@y@je@?MP=Q@#lHS^9!9ut:>:p+*h<i?jNQ^D\H:#@AbpmhNpZHtYwtw8cC?qY&M^u
:yKBh$ cXH#$hJC@9TZn1JCBl1ZRuqhZa9IaYWP<?wPmR<*BT$CYePmyeiet/aY<=\GXSCW#ZT>%N$*NHd9Lut9
+FCZjW X/>IBa!IaXhqEYPaLcD1W\lL6lVu/%kRM/=Zi+j8Vk^beGZ>cuw==>:e8@j6QZ6!*5+laGEVu*6QteV5
QS*4HR A*/5$%%TjEB18^BX+Y\:pjZ$BRQ:J<Mwb9L?8TTjZFc!Y5<Ge8wGqQRLTpy!yKe/$>P%%=1bQMhDteEp
9%l1Xq lZ$Ti95GBwbIBN<BPb<TSA>e**>>@@+D?@j9d!Nae<@u:t=&+m^$FD4w15=&:M*P*y9>l:*@:e*@^pm?
ElNW+\ Rij49*9>hV^5iaMi*ul>!?8:>8=/Q@8D>>>@9!tQ>bW?uIX+HZyw=n5P@ySi8hAl@\Qh?a5+/CiI&?Xu
TNm$H% Y!/&6HNj5?uteH!+mEApXIt8BGwICiGR5QCk<MYSElDi:8Aaa14>Rmi9kl<n::ZVmQqZR:$Y5R\tLM&D
&C#PZZ pYZd1aqDm=#VIeK&\mAiHPMAMj+=@FhqN^%T/9Ze*nji#6t#d!Zh*>DAc4/1pJPqQRLVVJ4@nQIZ^CFP
E<tY@! C&H@!yL+DAeWV@@qV!Xb:N\$jquKdVe?un=8+jdphJRK&FQV$\E6\e4F\i/IL<Ft<uYm@Zmkj?CYEQVA
LYuVZ^ >RNQ:V@RBpRJ$+ja?wVDmePP\?dAXm</et!:Zu66$?89d*y>$/8dZ69+4^6j&$nH<w%9Lh?+@NZqd?HV
VZ9!/E %*dqbQ?BaH&j8PDIF4\\XMHG4$SQGWW?:I+eVF1\$:jwTVb>M$e8IWG&8c#5:Futc+jl=8nywIWI<c<K
M9=GAk I%MJ+!BICwiFS<e5D4NJ*h+&LyZauq*c$Zt6u>V4:aG?:19j6C6u9Jc%K/V\*1ae\nNu#>/e9Z5$6KJl
YL?VmY &hey4/!ylR5Nk=mp?Wkj+hyaZ/*<HNN=jShmPGjQ!yW=BG\P>tG><+/EJtSX>+iVK$1+=1C=+LRPMJ*?
?491%n @A5F:JETb9FjVu?i=T\:V<L1T&ieu/iZ8/jduEWS&eqa=8yITpuPVuckuT5>Qh##CdSVkc^EYd@h58h8
9$edL\ +Hw9kd1jKhyGH^+>ZQPIVl^Q+p!Imw?KX$hwjKmN#6DRncEdCeX@*jnY&4iYL%@?Ft:1jJ+?CTGAZ>&a
BZQc+$ p:$4G\e8Bn4ne?#^=tFZy#=m?ES4DG:^hApy:A8dC=4Qu4*aI4m&KHP+neMbVTE<a\q$JbNy<iI\AB5Y
@SyH%p EtFHmY%1m51>&5>&hMGTuSkbJC?uZXb5I/NP8LwIX!C=d\>^nCVwQwC:X^kLTT!XE=Y%DR%w&d:TVa:P
>4djZ! cF<*E89A%TZ/>TAdVnni*48HWKWnS!V^\ZjiFYSBcnKeQnbY9:l11uu6hVMk@N9u:MaKaj@&GaAq4He:
yiDq$P T?u9y8N5HQ4L*Xc6Z4$nQ#6^c#a!9Pqe>y@1eKTFIS#5\d%YRDd/QI>IR%@=>i66B+mjn>RBSAQY4Euk
Q16Q$c a*ZC/6k+uDE+eaVElITGLA<lPJj@c6t9qlGIITH$JMS!$FjiYp:A&9aT6itIZ+qYJmCuZma?#wTVn4ka
CL\ip6 @R*%:XABtClM&DcZqy*><tI4#\*lEqYXj1&ymA<BY/NZM%%D\lbnL64m<MXJM1SB&5?&y#T*h*V*DyB/
Q$E%Q@ ljj/#YYbF5SBmiImlCL&=lC>XlwuwY5\X4I/qiZXDcJk8@6H+MB&KF^QYQl/<J!t/\wGh5@dMItX+ZVP
&RVmcV Gpw$:YE!>M8hj=Hp*GqP\#K\/AX\:m+>I&1u6VVc*h$*MC^&^%@@8u6uX4y6/?b6KeVW>FSHEwt?RBZp
4Lm4j5 >&D6/lQ*bWh4=!YMk4l&:Vwy$pi=c>TSIIkGJCVEBeSF^$ZV\R@S$TF!Bwe5MmFe!Gj\RuwYnFb?i4aR
dSMQ8e Z\pJYS//$jc1#SacE^1n5R8lF\umq+1JXmn1%\:mp@<V@q/e<JcIDYDLL+C9:bM/<Y11n<dA?kY5ISDD
/>CAVI IiGLF\QatCT8^bRtPpi&@e8PVncdTL&Kq>Pwa5P8C1nZ9aK1PuJY:55SaA8laTW&aTyaMwnHBnk\wZEX
q8::V? S$iAjYM9aA&qp%=wL\kL8t1D?JBEJqA#wcdA%Vi&hJ^%IwaITj!b+Q1*9*%i+G!?KF69Y%5:uQ=?1%dF
iAel&+ y6k#HFp:h8@e8V54ib661\&X\@cmekhCEX\&DL@Y^!?iq#?kndH4&nW!i6jpEy1KwkEBAR9t1tQP*Dq#
Mhp<qJ =pVQCa\P=CN+$TK/LR1i8TlaEF\+e?HMtj\\W^:pCZB>m+DhCFnX=RDkAkM=u^aadS^BRaHB?Aw1p?l:
wJ!Td! m\KDGGRtdu^MLIqt8:P\>M^b=m99=bDaM6G%PIdwT4CGpeiK1V#lm<Nm\5LDR<K*TdG\hCjbC#w/LuWn
>*in*? KnE/&CjByp6a5eYXElDDkJW+6mIPeK\IZdq!n&c5IM8+R5FicmZDCRb^h/ephM^<#mHNX+a%VwB>?>^i
?8n@My <uR+=CRKX9m1lnh\ZS@e+6LQ@9IFHB\\>9Vj@8&9j*W&Z:mpPpw:Ym@c=//P&yGXqb/SDE6JpE*NV4I=
nCq%by uNX%>VL:pM8?QV&i>jS*!5n^%w=Lq:1/CNbe\E4<VAlawCGhDW#>=A!eG^eRmFw@i8@>E\ICb!/!\1kQ
KpPtJV :=uV/QRYcAub=e6JEeiEkPFBRa8Ck9EK@u=?@u:?@4lReAdP<Rim>KYbiPAneG=C\l^mhA^+G<jANyih
mCEMZ% ?jLjMB<Sa4lLda?1LtT/lmt/l1DXQD!e:lG1bBnwd5?#q:X&hQdCdBwq>Zybm?FcwFwM:b1VR&CGLqQu
<%KJFq myYlEKIAqy!j\1QHmy51tLCwlWEppR*mXmtatMSZqDj6&dM!hAY>DF<iPY?iM\T^XDph61\RqRaX\8Bm
:A^B9< 5*m8lP#j@ub1h@Q=T=%hudyXPDd&!b&:h?@Ati=IVca@DFZBhKuZN6VYqbHi>iFaBI6k#?ltKeVHIAkC
iBAWZl >kLl?6T**?/j!=B?T<j+6?P#=+^@??$nQ@4/6\pQ<jn6R<LEd<EBjQ9AA9?bM^@SM<KSj8\AH5aJWu\#
q6KKu? +eA+9$RCeF$iTp>#CT!Cnd==\P@SHZ1lPQ4mI%D$Ij&wQ*>6nb99kn9jnn@q:=e\Bj<<kXm:l4/dEEeC
pKQFGZ &iq5Qu5B<$^%$F@Wc#^lGShGhMXMCA!EYI\=>!HlNnW5BZte:huPF1lZNy5+mNk1lanAqd\ecFjm&LJq
45kRy^ !?L+SuemY<=KNy+RX#^/XA6mWdA*d><dJX^dPAF:\1ZnmPLu5BntX%1^km+PBCePCtF=4VM=Pl?4ZSLm
J1Q:KP =<nKka9P9=%taE?B1X&!\W^GNuTW:6mJ1aa:h?@I&4pnM#$nQ=ZEd*N6R*%DdZqlNFeHR:YTCQchG>?5
>SdbRt K9!+I?44m&*ut*MJ!ah#mKS#bnM1**:4N^%9jkJ>6y@ByiPA4%?C?8=+k8A/a>y?\D!N5B\@eIA^u*bA
:uVLDn jmSlGaAN\RW^\*?t*$\@^yW?jey@AX=/D1GNX%9nN9jP?LhQHVmA@&YNZ+J/@iDw/IV:\DYMCN6eY94q
F>@&=$ Se!yXj8WYL&/!KEl6lK$aSm*FK:y8mSJn&XAbNli&tK1%=+4*EdZ!GKa4GFw%:%:RwFt*NJqC=a6nXQA
>:&Bhp \kQh1=\h=NeNBh9hN*L9hu>ZP\etQ9upa$=Y9tj!XeG/DMVQae9yHXMPT&+hR?B+cGm%NBJ$hnYZ\q#c
-AEnL% 000f2f9757900110334 Page 88 of binaries2.zip
?9MbZ8 *h#XyYb!<DRhNV9ukuMuV!Dh9j9#*XqPpq*quBG4h\V/1BR5!&DjiQ//5hL9a89FC?h#uZn:IZhu?+G6
nF5FbD hQQ#A%>9$XM*6+RHB^+^ejG%d+YPjnQZ$AjjBR#+NEAk**p$p>G><\@\XZB>FDnD#Y?GL*Cq1?DPAnjG
\tZiH& NhDQu#F<!5@6B9+B9+C@u:#/6\tB$WEJ#F8T^QVHpIIFZ^6d#I1*iLJ?\#B\NA\G$^J/mAtQ\ZAiyX6b
NbyQHE 8=LXlDt4HJWa+mCmNN=#DJG5ahCXwFm/kM:=<?qSkIYnp5P&W!HuhiDymIL6bePyR!4DV=\+#H!FeRSe
L!^kSc !SyiRbn!m=AN^yaVpuXKEH@wPm\GMhJ$!E14Gidh#e&:t>9M>cDhc51KGw4$F$J&=++uX$e:Ac1WJhVG
D$HI5V ??6mSILX&>QQWY=MqiiF51$Z9:#AjAXq>kj+kc<H*Q#<*AA\EA+k/b9kN*e@5CAw^^@/#*\Ib5%<SDTd
lHC&lE iaN^uatQ+!!A@!9#>iGn@iV=ELAlBQkNi8G=95Ad4@jI#T<Pq\#yW&H&Au<T8Hii\mj:@hdRm>=ITNlQ
y$DQ1K jCXe^!GQ++C4+16FDFiG^kSlNnA=4E5I%eXEXanlJTFJcy<aTwd#py8^L9!cwX/@+acWi4GGZWeL!Ywm
L!A=Am JAD19IBbAZSd5BTplYG<L\iENT\u:H6y:dnTP*l*alAGMXj<u!C?twRqN&eFpV>/1SAY45+:KHST5WTP
MDT5y5 JByDX16$ZZJZN$@M/iG^bV\?l$en<XmpVy=P%$18nq?$<*!nYp4j$FAi/?5nJW\Tn9B94t@RNTqhDa$h
aGeQM1 ^NtLF@@T*P^W+9ZdlPqK=94=KRd8>*PnN=/JtwD*HnKX5X^#@>9^Nh@i8eG+Q1SQbyJt9DGV?ey&$%5E
L$=VJ$ dMm*/pn\XjL=\F!*AF\Ze@!n=R9:*ic!!MeZwaT@njPQDwbN#QyX<dZ$\yiC1%y>XqQnIJFL1K/PI=Y/
GJS$Wh YEa8CX&VPN\9Fand+<?&pDX51qeXG+a%ZF^W^HRNZddk%@Qt#b+>P&AY:kH#q#Ld^Hdm+ER^CYJW4*FK
AHq/@Q S\\u4nR%HFkXSV\u/uXyNDEYL<EK%k\=eTTSq#Wb8>Xp5bw^8/!HN/ykC%KjDJMW^4c!^<N6@u^l%*F>
cbePS5 p!wnJX9aN//<9pH&=<4!c@1^m!%uL=#b:Z\k+9Zdy?d\l%8C/@lV6+lkkY9pi\j<@$/Qm&a8twFQFn/<
CjG+6H NR/YQ4^D#&jTn+^D?c/bCZT@ZSkM*=d=1pV*W#PtkNJ<!iAHH@4:\%=/BPH4n&8DQl5QDATy&bENmR/D
u5TJSD LHk1nHAq?XQKeyk8X&\Y^Zc5/6D\EJLC5ZTG5Mt$JG^=iHlE#PIIQiGIS#PZ%yFl$6$*PMd6&SDDHXJj
=V<%p9 T61%8Iq^JXmJ4LMDbkNcSycAJXF5AF6<qHA64>EKFlEuSIm%RT!JP8H4HlHDe=jBAq8b\&phHZFTpZ?n
J&nwF? 4:?tkYiaacpW>4:yaaQ>=me>ym^8%emC5DJYtCe^RSV:^hi1%R@%58!cB@K$ZDl:l9t/j^Zi>Vq5:#/%
SDhIy! j<+e!M\=V<HPiRwm?eCcSeE\pl+8A1Lj:q@+mFZmG9yHW<mQljmtV=jPuQpj>JSDE<^Zp5MQF?&H*R9>
J>V^AB GkkSD4$/un6*EY\6tMb4Al<J=Q8nw@j#L^JNQqj+R::WH5dGG@yX>Xh!&!\=4?Fl5bnqHSMt64Cm/^Lh
mJy\+p EWpQijHq4T!G!Z8>Qh\4*m9EeF6XSTXmE6u:mGD#tc&CKn<T5C!J>:C#W&kK+p56Eyuw:?dIQ^6P+8l\
CRF&*e ZPL69eSZw88CbR8m/hIkBj8&<QZhk%K>>mGQ#>XqZ&yVp!!#G4kya!S=4>YkjNc4SDG*?de4aM8h9t=/
iD9ZyV QImH8=iZd/DDlLXiM:d^a5QF<9Pq8$GN@W@hGS>j^e<i:b<nV\BZNBkaF:$@ITnlQ?ubDVcQE$L&@+Qi
cE6J*/ ?Cpl^PEym^jmA@*5naWLk<FLk9W6F5Vk/=V>+QWmWQESZSHndBD6Z\Y:/&Ek1B\hJ^J=VW#eGq\5N//Q
8t>w/V 4+qJWA/ZEbkRZJZXXA&4CXQ*YcXm<CmbVSGE/=KIFM9AV<iZ4c&Z84yb9R/\i6ZYMKuZw$LZ8Ht#=$MG
wkAn8y K#HMAupB\=KndiJm5akdY!=%ZPpb8u6*REeTV*^<&HB$SA+VWie8t:5AlEZMmbM/:^:W=b1HQ=clTG\P
!t%wMN %!9%&m9VtweGB\c^Z*B+cIl9N^uac*1YtVC&=T#1t$m9e8Y\X&B+9KP=S8@Lqi&1QN/DkK&:WH/tYjp9
?Lj+lF *^=Rd@G*1/K%/b5duZ6j9leVN$X>h@#A<yD>+1WTbnhCRlc88I<jj^T!ePENkyJDnL<m8m+j9/?$cNAN
@4AaL1 JiwQSK?lb@8nD>#B%aJZVAln*V5iHlej14S\dn!8uq#<PGBF=J@*Itpuy#I$jDGlT5k!4M6=Xu5+%mqE
LSi>hY GQNB54h9c&:pSd/eW!j%1m5qqQN/qK\t$1:#=t5S#B<BLVFY8dF\aw>CEMMmJk>CFG!Q%ZCTikq88+Ie
%H<A:Z Z4D5%<5YBJPCDaYuk>J@dSAj%AFmqe=B54/#1/eQ+>YHS8peGl+kREhHeS5c+yHN*h$CdD5n&%Ec:cd/
q<e!Vt Iy<q51=Kh^dY/nZI5pJZG6$cG?5cChj#yi4hH+?NX&nG4caQh^nyeAZuuhCa?B9!k#hiZd:^*<ta?99!
S&KtRZ =RVEDeV?\h::mBjVD>>jKMF@=m9?^b$deTFVYG:V5^mReu<5Zma8nKGLiZkL$CMeuQ6*\SXj9&HH6hDt
</i^d% IQj%:MW9bh?X/1+p1!qt>i4aeL4FKDG<JCaTjLX6p?HcGPlnL<iipJ=i>q::i1Sm4WHXDd9k9BK@=5?i
<#4Lye y$Y\q5T#AtabKyb>&CLDItaQhySV5C1TKCZW1IM=6&<Q$Z@bkkZBC?D4kQB9un6uThYlFEcbVdL:lheP
8n/6t< >e9KZt^>G^1T%Y?n^q/cZ5*ahlLE:e+=9G1d?^@h*eLVC>L66eb?c?tL+Y$R>NIZ/?w8uCt>n8#4X:qS
dV\NuA CXEHDq#jV+=JdN^ZB@d9Q=CdEB5ZF^8Vi?DG?FeJN66KY?:jd>#+i?:Gnc>6#Q**9*?%e8Q!j@@11%\a
bJP1aW TI@?@i@@@kmJkH>@?P@:PjBQ!Q+1=N@@99?4@j5VRtJCpNZ>cu>CVF^MA4%$:y19/NZn\lK?wm@G+m6@
cLdi!K #+%Hena*h<4+nc?ej@@:*/@uP64?j9*9Z=YYqy&>WNiK9aNGF%=MDPkcTdATW=<uVMPb4lFLalLNwh4d
*HB5iq :HX$mZh^eQm&<q=XyaSpZ9eT9=dPF#EM9T1QY5Y1<IRIaqVDmIL6GaKCdY%B1cqY5C48#*+P^HD\knlI
5XX>Mk <n%pEcMa=y!Y\?VAwkqYFXZ#hyy49j%ayV1tF%^kwh<a4:5a=V&NDC!5y<96q=%1SJPQl:8H8%5<L&q\
F?=mta %NdZV>1N#AnZ<WGELY*t>Lp#Ie1iEBWjG/8Ve*SHZnRG1VcXW4i>689X%#jS<h1/nS9j&4n<Z=G!I:E4
wMpbD& /S%%i?!ICapLmRtXlF^M9PVq\8tp@!AG@+XK!ZLY6hDyKHR+8dTCd1XFyYZNb:?<&CK+!yK<C4KcbKXN
YdF?wY iA##FalGSGJypW&G99B8A#5WGL!emZ5nN:uRu+MTb5mjuB^qNYtt#qcHNw4bmT$pX\eYMRFLCub\dEI4
1Byn:J YML%<CFlw^nECEpTY?e8ZSaMPd!H!>hWw<+l=18!t\kBhHN%aH*$/P$^:H8d\EIc6Z8Iu&6k8:88hq:1
M/Dmqq 9PDEpnpEDqEb+S:I:c/PLH8Smc81%McT>Acmc>*=<nPqycZPbpa&Qm4BHy5AaGN\n+8NJ:YH@Cph&Vq$
NN:ehk :6*%?6+64:@^?889d@4ZVS5*48Y<?9K*#MVhW5:XYhGNCatJCTW$ChuR?DnJ\\JW!d4G+4wB4LpP8+c#
IwN=!t 5IDP$pIWSbYXq=@>58Wm:*>XGd4CpCZl^NdI&NWS+SnPHw=NGVmZSBkdTdbqJ!FW&5t=%#FY4^L#4/t6
V1MZek 4ECKVnp=yF+DVAW4uk+a8$!M+y!>FpGMPSQh@dj9nbki4Gy:$IFEKNmq9!a=#NENSJ^RdtwJPEp=I8a?
VF$!nc I6!EnQ@R1GD=QiPyuu&9X9j&*?#4/iu8/4=$Iby*LZ6\pct:b=A>u&9BChm!GtM9b%6XFW9m&kctc#pV
Vl\iKX 66SJ:/p#kaA%?Ey9Q1EdmkKG$QkeluZZ*q%:@>88N>=+a<94/%=::aXZ*>wIXIY6kJT#h\9q!hKFGq^p
4c<TuJ ++Y9MV1H#teaM%dT:CmGAXhS?XSR&F^aXE1we8FciS*ZT^m+X5dEEF&F4$6m5DIPwEaTcbeu/wGqhNy4
\HQ/>h Y#mITN:4&JDK$ap%LCH@uJ\X!*+N65+KMJuKF9E5IT!CSuBm^hXlm:mn+&4j!MSwj=iE@w*W?mEGqlZ5
+EH#aq $4kFT/PZGlGuh<=JQRX?TJwq%e:%lp5Nwq:H>Mc*:<*Xd:LW:#aB!<bVX#NtSZC%C*t8W**CbQWGFq#b
jj1C58 C?91%hy4Hq/HYTkNLInLL=TXp&%CnBZC^mjE^m6WlW<waBAluL&Z/Ly*%=8E/?>ii@&%Vc>6ZL+S5L/q
=cKj#H 8RyAq!K>9qA!6MGCdHRwMVaPGjc+WAXyPIP1Ce8+wnwCjC$wJQG4!^E4Chc/PwY4@QLFT4*GS5aTSRE4
FpTFkN Ra1l*1FLE4PNyXDd:B^Y9+dk<P*BZm/XMGLDVeVZQT6D4VEJwcq!ajHy5tXcEl8C?FLn=e/i\d5V<GAd
mI^\yT 8adacKpVBR6BVNc\/Fe#Rm^<hZ$w?S\XdY4ktMtAY6W+eY>Cd@PdtFDTiP#&4eGdjhjc%1#&e=hSE1C4
K<#1PR 8%8peJYZ6SC\p&jZeYhFZT*V6j^MYTtKDl%P8?nZPH:j\?Km8VAq#laVV$cVDZ\qYN>+uYB>@jZZ%4&/
9mJGhS EjXNd+Y<BjAWwC4NL9q&^nepPCRpmGX^VDVj+8klPw:8ZB6B<Ma1\yIpSmXmKW+G6R^54c&4c+S?%eb\
i18TG= hXQME1I4YW&S1!P\MaQwGlEcESpSAZQakHYdw/YFe/<n:L%iNc*lC5N=ZVB966WT6n+NtCiSa9JmqiYE
#HHK4> S6mPX6QVpbwJFTI&BHEwESd=A>K9StDCLDW>aXqhTqIh$tRWEGI#&AV/!CiM6dpV9Nh<bGBNAp6kteNE
PpB4bj &L4:J\NP>AFkwD@J+#y6M/uN8RC&qwE6I#qe$F!I\pN/k\qXklMqKnG/amYWKd8H4CbC>4Xh4:??lXB>
^Si^jF di&@Mq8ZC%iDF@+<&e/$DX/E:D4h+5l?+yhEwFAjBLEA!=YK8e#bWydCbWZqm1<<d$*V6hJBenk!m9eA
/=\PMQ ^9CCS=:yVZJ+?bLE:V#qHdDc!6u9:^pk@WXtW?hq:5/YyqiWDi>h8bLEMK6ZCWewu5=YWRy!hmR<wRqd
>iHEJY Ze9Xc%jl/jSN1yuk:q<qmJHM=hA@B=#i+YIa4YAQ8=RebuiEjn*!ZmGGJ?/Pnh&Gh#N&q+%m51S8n>*=
$>A4^W =#@@PZH*iwCdy^6YcCn@^6M#EK8YCFt8HMc?X#5:5Z1t9nC&y4\Y5DcZ5WZ5!GXa/Y$PM>:&pGlARewS
m!:CeA yakd!Sni5\pFy1?>>64cX:pYphpK4k15$?u$uk\6TteYB$eVbaGmmYmRkT^4YWcYjke8Hm+>Y5V6AYZq
^m4SWL qeD%a1QG6SymGH!NAtEnIIa*\5PJ6EXA9&b9*/aG?N8\1KtVK@*9D9X4L+ihX%V=b+9XNN8IC%9+1t:#
#59CN> wCXZ:5qSlC&9pWl>#!B!hTlKuP#yeClSWuYeY^e@S^L4l:ReN9lck/qR*heGS8+c8<5J#>9$pR?C>8:h
<9tGJY mV5H=uk!YYEEm+<VlkXc18PXydFDNK!=JB&#kt5b%4K!byJ<yNyAX:CX!<tCw?eGTk!i:Xpk8*GqnW8G
-AL=mm 0001fbf5bf800110334 Page 89 of binaries2.zip
t<VNJ+ N&&E!eTG5ClYkXTPYdQw\h6dw?5@E+\q#kaFe=%VMM/k+Dq$#k$PDGbp&cNT5yn>HDREqJ1C8QFL<FX%
u9#FM/ d#TS5SRbG<ZLV&Ikl!Mm+tE*SaS8YGLdtm$LqLht&?5Ne@n8MJqN*L@B%4A+4#tk/*\XP&R<=&5F1<MV
Y8kP44 <=iC5H8I5EiX=eRY<e>CVwcuA<I!5F\L5$?XVMmRCT+lFq\^dK!4yyHNJw!MJe6*bGkai>>GS8nDID$j
i#:?Yb H4q>?<:D8dM>%iGBAT>VwX4l*1S4cA5K:M*Xy981h/SZ%hbYA6jt5wLtAtnZPQ^F#@E=m<@A\PAkA>uR
@$Dh<S CBRP9:4^6de&9k1D!dCZCNbb>NMBAY8pTnYALu@G%qhDC<+8C1LZC6A1DRTl==!Xm\/D/c&6y%\8HGbb
SD4jnw LMCC5I!4XINDDDP85SHR1e8^X<EYGbNEEnp^Y:a!pJjnEDiHc!XkN1F\8KGl8qymViT<4mC4TZ+H\jP@
+kb@y$ tICKqqY=ub\>VFmJJVb&mmA&Rp/t=eR^aylPKILnC+KL\<?^FD/u@B!ZaVa%ZtwlZIh8*:6Hu84\<PDA
NmbG6$ IC@%G^!+ijMtQd<%iC9BVem1ap!pYaQmT>liTqiGE$FYYh6RQ&uFFJ1Jc/64Te+%X=I!I/%G:?tCkANV
$IQce& yp!=wY>4yke9ItABLSePl+a8D\YmG%?RcuAPS!\Munu#8hpBAa@\L?SjV=u!CNkT6EDYn+Bh=M@FnMFB
MG\>y& n/bMPjB\Cy$H/H\aMN6j%Ti!V/Z<HYe8qC\lY/cB@jLLJ=:R#Xa=SE:5aw&MIyWc!u!%SeRpSWS5ZLLB
aZLlpN 6p$9QdeXaQZ&Jc/X8D*Ri%W1%uS5GHTNY$1aBynlmABqE<6Z=PM<TPKeHC=$Eli&BcEJ6NY%/6CECGIX
W/NBhZ I>:*NyeR4%AJIdcH*%MG<aiK4#INBWt/c:n1JpbHGM%?B4TjQ9dS5=9Z=!yRbj!ly:6:pD&L8*Gpma:P
JZBCh< >MJ!Xp=/Ncj$GGL$iVX*L=a%F$EK=>45!>a<jJ1B8eHu\*qajSC+KJkMYmC:QHV=elYHkATtG?6Xa81n
Jdm/^$ Kea@5$BL!Q1c!Qyni1!GXaBhM>5QJaqAqk^nA%mH6w8XA*8&V8GKuqh:cETEE5QM%\&R\SHR4^9k9#Kw
9*T@db Y:MVC%5+9hp@NDF^?!cd\:y8tA8dX1=kMY\\<&eG5aC:hAHmmZ5=9X=bDli&p$MVJIldniV/i!yZ^:+P
c4C8\i 16iAK^1\#4%=V5eSkc945McXdH8+4#*>yF:9nlK1!NH^5ACp&PqJZ>65N*eF4Ae&cZl=lch4XNW<CZ6b
%II81H ZaQi+m$%tn!:AW6%yT8XaC$pa>lln+<LIECi91FkFX^uAk<!jDlZHmIG<F5l!*<Fk\qt<QSbVFZ%V#T$
!Kp<d6 \uhC%uecIi5HcBilL9HGqAME/u/B>8Gc/X^iKy^qYT!Y5WM<upIqme?ibX!b4wXa\SwXH<YL^WIJT>CX
?tI%w$ =HBp+9INT:d!VpHib%WI>@WTJ%@J#ipW5$pFJdlRAqaVic?##MT4AD^LMbe@I$pMl<X\hVlG*D85RlNY
*Y:hJ& !$pHujc>5YjQ!n$wR?binuP/eA&C?GMVX$Td4%+na@*i&AnB!5M>WC!ly4jp8tqa9hH!/nuXLhKb1jcL
B$1N<< KtQaLlNa/661DAeY8>H=IQYK9qTmB5S\jQ!CBBHBA8&Nl@PAl@@MRH>&X1TRu$Dq*k%Y4eE#4cni\DYl
<*ki#q lVkiHpIcV#PRybjC%aLdAYd5w?q?WneePEeLa+8YhSa&H!%XlCXec^T8T!JmI/QTamQn\hhRMweN8t=I
cP61jW bCtM:VkPDP=nSp#eW%FE+Aw^nQLTQZBiDd=c:iHJ!b%bAR8YCYHFepL=&yYit*eu#LL@n+Y\WLC5a9i>
GTlQKI nacP6/XeR9H%EIbRIK@P=uBNY\%tF=G^*n?GpZa*?*8NcV^$9>dVA=@X#h%HQB9EI9#V$lXbudK?q<hN
Cciu?: /NE/NcdlXMXKF4AKZ^&FCDZF4ZpIQBqW8n>eRIAApWZ?<EMu^jIZ@ky>G#QuBV^TQ&>B%$CYyHHAQDGk
9KX8@A jQ%u?5*\I:+!aR<Ib>jMu8:ulyJ\E5aG5DETXHR=8cEPZm\SX8FcXhWWE^MSD@YcSuLaStJa>lbF^mh8
@p51M5 IQ$KTHeqEYWh6ZApJKp?It+P1%i^luNiXXcVnk&4QI/SmJZpD8=L!Tm&Yp+6uS&wlluy6d1\Sy?Pyd6b
kb+4NA Bp$eqPqP\6eVJ$//^G#mG6M8tE$VI+PA6d6Hb1J%>%#6?Z18t!GC\Xb*#!AM6E#u?JKaVA=um#EJ1/G?
*jAunM 1$4FEWWT$<F$JXmd!SnP5ejQDblmkuVn/j$BAET+6qCkNeL=T?G##k\I+A9k^yVH5NZI*mBk=$@*>yZZ
=w\<R* IYD^^ahCYVwj#jQ%>ZNDF\B1@^Y!<Tl?mZh\FwAbC&AbX$^=emAGEbYGXihJMatR\+qaBImF!eVZ4Y4J
$w6+$B h4aDn9<qKjWu9q=B4RTb\+R4M1<=K<l1tw$1SDPqQu8!mnZ8<%C4^B1&54Ic5eVPK#%TDaMZBGEQH>LB
QHRHpM SAH&HAQLw&GI4lyY%*8K4##$pZNNjV#NlGQ:*h%Zih#h%i/8*ZP%DQcRJD1^Nb@>G==aTqL+TKcVc/pX
:G4b/m a?8qc1%i#=1p6\tEdT+1Kml$NmEt5Y#NARHtcWd4aaC94!?&DBG\MH&+5$yc1@maNa>kjby9<m>\MbnI
VtWc5h *6C!&N8dZkZR?5$ab!E<ShqPn?d:CLBA%nCMldF&hM&!mm$1F%^=^qMPtWu^WcSi+&E*lTa8&SAbEb<a
?/Va$& caN?lS#i^eD8enTw<QAwP8uAX&+#4/+W>awM*j^JEnnACDpyTGeFGQXPK@dpeCq^bZpN%^Gn:u?wy/P%
kGyG^a yh=\hXmJ/5yE<<BZDy*V\*=PjQKJcqWZ=%yT\%#JhQZ1%W/My:#/>e:y!4@^E1@X\>$9HF9bibTQDM#L
mXSq!S eJ:SI*?F5IcG^i/*/p1!ua4B%&a!t+kj<e^Z!$G+i6PydN1bM+Nueq^RSjhupt+%juTKIa*XhcFR^S&m
wJ*@HV tIAF6H+*YD+#a$pYE/+?Cqu@PZ=#NLITX*VaPWJSlHpW=S4Z!ummc&TWQbdEMCqXAyP=m8YhG#e5IWBq
5:?46c 9@a&+C16PV4eBF^48Y=aYeM/EGG+N+<^Fk@Aj9=TIt^Vp>R=pSkkF:b*cPJ&j:hMD8jBc?<blD%wRjY>
uPB9l9 e?e$Y%ZhGy6N>VL1m\8d:+$P>kQY#m5+4u/>P<FCX4w@/?ut6m1hN<d!hGEkY=B&Z9WYt1Janiutpj1a
H8^LC? 6FNiWXbWJGbVVu^<<B1a\!baAh+?*n+?BAyD//9:=YbK$HBY\MMdn^&@JI?J5hMX5DN<:$>l^T1MQjBw
>=dp^d 9yiQmc!@q5W^EqcWCEW#kCXe%enlWMI^Nw*5ytR!kiG$E1na$JtWTHKaSVAn/=C*nuEh+ZCVSBE4WDie
1<i1Vk 5\jY5C=EuG&^l/&qVpCXwb?%nDW5ZJ*K8wbLMMeRe<JptHyLA=cKPl$$1M4IaqkM4Cc!t#n>Km%Zq^4W
hS*j\t SWj16c?u??1XK=e9j*Qq!9qX+K1d8=wC+ptk?45FSkJW91iD1@qPy@VGTwXtw<Ha6mwqmEpKX#bZNlhl
*jt=9L #kQwGny*nWcKSi9jA:!>!P4^<b:8QW&lcntt\&Tmu@1Hi5A@iZCjnuEL5E@@B&H:KMCLYD?NlQ4MeYXQ
LPD^Pl mchD*@D^ejhX!F1AqcmmR*p:be%q\JYHKIK9>mmaVjHk/BL\NTpCC<a&4N%kp>ZcY:jcm84aM8piIF!H
<w!Qd# Vd=Kp*4P!lX#F$klw5FaC%ENk?1@#JY9BT^nDZ6W5nw6K8bph1=@jFnZPdEwQmlWQTel^HQ9GXPIV:lp
4m<n^& bAlje+R4a6hw6:=/>jKX!>>e?wa$1:DXHbqYN*=HA8iE^VNh$=YGyieZP65NZBY\DhbRI9cLFGt?aqAA
5w&+S4 <hYA/5cN<TpBZnm<9d!>JiL4dYtLuDu@$YNpHZ@\+Mijj9#yy^<i*DiNKYd5tqqiI5@BX+qMEGWQQH\+
P@?n4u n%+inHZ#=i+S>tWN^61a5WSaE5RtZ^NJ9cbl\&+pqn68YGIn9tJ>ViL!6eSZJ166X%Kb!heJq5MaR>1k
YJjTac pnp=i=a6t<$Xc<d^Z?a11a\u5+$E#*@lewy=T!ZwJK+PE*cRZJ&inqa#tGkEuR#P9tec\%I@nDRhmmZR
j5FG+! ?IdT1>+B>A%lCB!lTu^%8kFYpNYhu5GYDMT\t:A$SqMIT%La&h!qF@%Ja$en>*BM\4Y<kk#m=wLCR96n
W1*tln jL*^D>c9Z5dl:c&R>Vdw?uBepZYe@<Z>:*:<d5*$/hMD@9HnD\@Gd#^6peapmd&b4:+QFF?b499=Q*D*
iC?=kW <uGjV5+cC?M=XtA=%i:k1VDMX/J4IjE%PR1dhbMmSctTdkXj!e>b8!F^q!K54d!BE!dk/=nFdpI!B#t/
@N1FS1 $AYR5jMCb5@VqFZ^aTA:*?4R55t<aNqKTheyX+hHEw#&eYih$hFlG5Z9mj^>V#HYmDh>DF^=BHwDq%=^
Qa5y6p !4?9=&wuWL$T/\d*Bne*ekkJW\I%DMY$9KNhHB&iSh6&XYcW6S1&E<<?c4D!6dK=8KmwpQqK:t5$<XZI
:BIqiI Pw+QW$k^i9GJn\V56Gp#Ndni5+m8+*\V\Z*@8?<YEK*yuD:>@w<QdqkhwCtQyk6hb!yewYEBdeB$<@Cc
iu9\EH D5NaAa9KKqRwN5HZIR&4=HBXDnt6pXn#S+Ia8^5*SQDPXdwudq!:eeQY:M*p\G:hdK8%&E$nF48yk9tc
Z=AQ/l \*!hSNnbF9&1W*ht8HkBkp=M&QJ/=iyw\p4R/dCiA/1F5hlMdA5L6K=D#FiWDp8HJLp=$pb@>ew*Hh@<
CM<+SK &^\m1#8IP5jQH#Mj\>AHGl+d8Vw6ZhNX:Cdu6T=8!G1b4GJ%915G*m95Jk=LRL?8%HKaRcYHKR<jQ8Ly
kW$BFT MI?RyJqHd#%B1&D%btw#a<eb*\eQeAY\&J:8@jC:G!1&wZANtQ/5:!T?e6^yC4%<\KMA8e?jQY8/L=qQ
Qh>u!K kZPR+?H/GA!GER&4?Y1*^TVFE%*V$8KVI:EGi$Nmpm!KI:/8Vh!%&dab5N1pGku/hYLC5IedXDcH?Vy9
5eha%l uyt*5YlaW>%cAp@p//^WkymDmc&hQB5G4dCNBtEQ/Sy^=h!IXH:Q6IiXPX^V\#51!S\ikY@Nt!R8u$ES
8/<N#4 1h5eHK5Ck$DW5NnXpeld^ciqb/W4IR#D!btLc9EPdV1bP4biVam6WZaV?F4wlH1NYRBe^^XW+@>k9J:?
R:iHF? ^@nV>@Hl$cPAYTC6N+M:uil/u*@!H+V6?I*:BK5*T&!C*?8JKXNM<^mTPEAS>45dFqRShNw9PRCpAhaE
y/Q59I BAS\aFEIK#a^!?EmlY6XFVp%piC4HZ!N6G&I&EB<Vcbdpw%\laLhBYEe#:bJy^GZ/JS+W<$p95=VhY1#
&aXQ:R j%+Na!pTF/mZ4STV8EIFmV6:lmj8DuLR1X+Q\XVV$>Z<eNT!HZyQ&eIT>n@^mTw^Fd+P5C!BGG:jVWdT
hGD6$Y HEEX$lh%ibG^>ChmG$?cQXPAbYFe+L#ie+%*#uRwTh^mthY6lnq#iFn#NTe?n9p/dwGVAB6unMj^qj8Q
b>YlF: +LHIRV+PRR45ki4V>^?5ieIdFldACXnDbH=cY>d$wt8A1/@ja*#XeThaWk<=eSe\&>hjT?JI\nXHWn6F
6ZLS9u Tk=Z^JPbbI?Thb^JmbGJG#bmKVbD8+HpMHF%//:NY#hu%+t5E:9yb9hXHkVDeykW:N/ebZF\e*:B6\p\
XCum:9 /!etbhtZ^i*SlIWaladq/cah18KWdiJDWlGnpD%$Vt@pALcHD1H>Fdk&TEq+F?5IHtH?#WXGhM:1%ZG4
H:CyaL X/<PC+>Beyq6\:T$hD1eYkkV9QuPN1K+LCe^nYI8/5Qwd?b48dKHC^F8k6%E?yZABJ4*ldJQ*@<HE=ia
-A*=lF 000380fefc500110334 Page 90 of binaries2.zip
Q8Td^j PV=Pu#$MtPeq8D/c\u\FqY<\5ciLjVXq*GJSc$qMkumi:&T?Y5\uBT!V>qHAdIlm=i#a^IuX8FaB%$ld
#9mM%V qH$HCYL5kp6M*JmamGY5!ddp^JjY46&$hhhL8!CMdhK+4iQD*CPJweNmD?@h5!Ka@J^=F6Qw<aC@?tLA
/SC9:H dCYpq!/DSR#L1d!c=>bi:SqTW@WMTc!tEuC*1>TYTt&^XE8\t*PTB/&^><1NR/mA9Z4=e9PePj@Z/9@4
W9JjtH !TjyqlAXG^EbCcIty/W=MC8Qq&^pb8:IXGd^>X:!iL5/P*R#X1PIa8\Y\*#</yyKAF6YnHRP<VXH!iF^
Awqbd\ BlEjGF$C:n:AG&i^jQ@lw?qmG^MlFjd<M?PQ^CH!i1AMKeP6FSZ:MABlSD@G%YwT\>%Spyn9!LYLJPbb
Mu@QX= Q#!cC+M\qZ:>qP!tJBLD#4SI4PG$JTb8\Jw@LahjI8Y/m^X58eHZmauSjp8iDy5*t9c5WH!hF&AW4bFB
=P?G1q @Bl6b\Yaib$F!$J#XG!CY*XRD!NV8qw6+^LX9ES6Kl$/y^J+QHCN1^FX6Iq4VIjG8AL&c98@^c=i@YVC
!^p9CA p*LE^$j!#qmC%J/inl&C9BSHG$:P*P5*?^SlP<!8YKQZEE5\AT!bVRlMPIm9K&NJDw9WBW<bWpH*@nmn
EN8kKe m<iHc&A>iW>>PI+D*+PR9uEn\B8+iup@GJi4RluKAm>ey8q?9u+#jZ@+bd/1jC^DT<DPCR+EaZtpZk/*
#Bc@AH e&le+&&J<dK5Qnpbm:A*dCBM+=Q5JI1b4!TD6&:b9Npt@m9#>h:w#X/NK#pA16S@:u#VIk/aQe8mZRMt
G5IDMm l^Ju1\cAFhwmNnV5IP>^+Q%Z^q+#\!w?1AMTepQXGy9D15TWLnp!l!hGB*89Z8t+GM8w4uq!J=%S>1Rp
M@M&FI i#L^hAiT=</5A41qT^\^m?Z\>YEWm+6N*N4Tcw$W\>Py4c+yl*+q9lakQJ\neln+RR+dwD/6RKXQCPu:
Gn^RCa @!CEEKiawu?E%C+lP&Y/\Cy<6d1%TlwHID45N@&:G#etwVyqmqp>\cn8j@lw@uS@j&$=\aX6M9qcHI@%
dH5<b4 jqE:>Cy#w85GY*JKWky^F4l8*p^$VZ^qX&K=6A**5m@BVbI1pPlC@qZT4&b&VwuhkEutp9uFiRkTl/+W
+KRPan RT#N5Jhcie:$^EC95YD!lBwkdm^#PQmiwYC=Y>%F8NdW6QHiqp=yCKNj4b9Wc^TIT1C8wd5##d+6GWTX
\$5lu! ub><cAYL4?WPDA$kXcCGFBm&p&yLR*WV!?Ftn96#HBF!iF!kHQ<HwjpAV<d9n/5QEM&E:KN=JG?j8<Fe
deR/A1 jX1R@<j+R<F%P8G1/j1QTeGwANDX#?@B8CtHLdLaXLEk:D\6mPQne=SF4QS4eR:=NGqyV4KepyN=R@&t
$l$4hT SJJc^Nh665T%/>c?6P8q4b5*R\/#@$y9*kl<^J:8d<\!$!J88RK8<%Z>uIuwjI8=FGA%m?e9+Fmm8LA%
PwEaeH ^LlPSIqqMH^4m:KJibPDYqN!$HLZW*=Pu1!T$tGIaY&1p*4>T^SA*jupZ*jT+W#D6qelKyt@YXtu/C:4
%aaGCj BFt>=6+cWaSXDe@m:dRalK%S=W%pN^XIZCI$?6EWAHmDIYY?A5:^<Rj$kiC:#=<Raj@F?#u/D9?EeQwj
Zhi5k= D/eLZd$i*H<cGlj*G@^SbjECylP1jnN@MBM>Q:ihH6Ln@wj:H=GGnR/E+YTLn*j5e^y<4c+1VmBZNW*6
!N+haJ Rp+T\wK9TTu&^M%4%/=q96Jy1?Y%4b$>1F6nahh8DVnq:PF^IjMuB+e==nVjWyXwlCiI5mKIC+@JQChR
l^D>mV :py*L%b#>@F1dyu+j$I9Kyq<Q!Vnl$Y>Rk^45?u8CQy!L%?IA1A:Ai98*V8h&MHNSC$Au1Xby:IK&MhS
cqHAM9 =+HdTMW4Th#iclZF>R*atF6hK*W\#cWeS^R@l\EFXwVd@Rh<*GhVtD:HI*%GyyQ*jQpM&Q+DSBc?ipP@
\EaW$6 KtQKDEZ^5eaLM@V<YA=dWGZqdDBY?MyqmlDEHHLmWKIll^NTdEt<l>M8?*NjA1:J>t$kLQGXBDEjNw:y
N6wS&A wF=mGCuPH1+j=1u?FbKAZdb5H19ZADQ&ME6HERMt&eTR\\Ge4iM?b?Bc#15e%C4CAdYKWEcI<<awR^Rj
WFVbL\ $yZDcmlZFa?uqe!\Me:pt+/@SQ&XRh&JD:6*b#n!MknZ$5!5@IK5kqNE&FMA&AG4PDQL*ubuhKkj!d*P
\hw#!4 !a\XRX^dW<?iVnMBY/nKt=m9N\^1Q9*hn#@?>AQH<bt^IC?l?iDlLG@9Z*@*aQ!?cF#AT!Vt>ADl?pB^
T#eahj ZB$*=HFK\HP?GJD+*jnpiw49<QL$de*a@c4<ND1a=dA6u8\tW4BHXh!@al?lTZS%plhAKnWq!jcTdc5>
4M$V8^ JVp=Jht&XZDhlb86YiZX8TSlWP4C6RM4BSNpEP9W?t\nmV+:aHJRESFpntDMu:hWLGJL4<:q1:$*!cR%
<t*yHI hnlZ<a/*D!el1>m1b5FWXW9qeC84X?/n==WDVkaX^&+/Ml&yGRYby%kA=&iiPqYcXRKmbpqp\4u@>6nI
EWjpIC pDch6LPnCW5YeT$w1<5SHjb>p5>=IML&AcB><Gn/>Pt#H>E:@+C?<PD?k@8MLIJH\P??pHkeV<Tcw65Q
m&u@%? Q##+Vy&+/W@GH@y!khy*P5&n!y><yu9PZ9QkAbhS1QDE\+h4by5ly&^^hDm9V5/bC$:Anl&K4<t&^Je&
1?m:Mj kK<ySNuEVT?5i&u#=m*k/<dCP9m9q/=l1b^1p?V8%<4Km1KnalD#*CcLM&M^mA&QFn@C5M/i@&8^mDEi
$+JWK6 Zkd4!T:C8>mX^CyYGH9C8l6ZL&VpYY88p#yH%!whpp1TZG:9KAYw8@?1pM$1TM$n^XwKaEHaW\R^FK\+
elI6le 5kY=@:\:PnVI@bPQA+9Sn<SamPH!akBL5k=<ZdAGQ5+Dbm9^du#NE>P>jKd:*ChKQYC1*kh#y##!>y+=
KwGt1^ 4pn<NIM>QwZDVYRuE\Hy?FH8Q@/pQ@+\@t5!lwKJ4=d$HeKLu6Qhy$>@>MNVD+%+IyF&6q?\cVjBH6b<
aS\D!n 4YK?Puj55KiqJ!iq&FITN>5TW?!y!R:/=KX%L&\maIH5H8Dc\cWtMu4+C4c^<ck%X+Y4<AQy#yquAVSk
Eiyu=/ WtYVAl!mtlM@MLKp#puT/&4eSKe5lTWX!<D!Ypc>>jnDR^@1bhcHD:MWQmunLkqYX1>eLNHLR%bLFca+
9icAl9 #8<<qbtjq%GRhaykLTFJZJJXi1yEXwD!u8*eY^Nnw\QKmi%Wp6k!nc/&6l=6X<$XZD+M@SyQjk+RJG:m
<mLtk& <j:+tteR!y<?uRq:Z$lLeD:!un:6^w>AqeW#m?%H5:!RyJ*8ne/4/d/?*6N>b$+uC*k/!6:<@aN^t?99
4BQ*jF @+M8lJ1m<uj8ZkT5&\@n19JWhP^<9?kk<X@6>l#a\$h%Ha#Ddp6P*:EnuYC%d+Ql>FLm%mRHCA6e%/+V
jI4%+T Bj9K1<JZ$YJnEmBtS/hTKhmXK^dM++1JiX1J#nK4EJWMqwKJiTA6QZ@8PdcITSAZ5acFE\yJLEGnX6di
l+5een cp<=pFYL!kXX/Yl&$cZJqW&6ujnFS8?^?+yNVSh&tLkTaR5!<@L#<$<^aa@pb=YeI8/K4<QP#wG:cKD5
9$CDK+ :?&?b5#6$np:IT\YWJFF*F^W$I\c?=Z^T+t9It5F\+DyQq+\hA<aYLM+jnS>y9jD:$Day=Xw99@$AZF4
1AtFZN CXbJ%uu=?Am\bC$BXDScSReV4njMGuLG%ajP/R@H#hnEjqK\jlDD5Ih#HL#D+cnWI%bX:$8HHHd85KiV
C#QtWn IN/YuJ&$?TXdTuw!CJ9>$64j5CAGb*N4Y%SR=:aKEGMSl:T@FtM?:aywnmR?SqkhQSTcmkTi@b#je*:V
eC!1?Q b^G8wXdCNyBXC$tMC&ik>/wB4EcY5PYVWiWXK!!GG%ycY*YnPlw+8*uQeQNPC&H@tqYRpbeQ?W5GE\R^
4$E6?@ AX5CEa#IE#t&Z>$l\k:*t=K+\$La&u4BFdAm5&=*JNmJ4%CbZM\CFJ>i+?WNaL$i*khlH#C!+\>8EK/#
^BnpTT %9#+RER^GI!Qn\K<9IT\CDQPtn%48lh1@dpeuJBFH>*ecQ<j^qZ?V9HX^<iH?P4=TC6aWdHAXaylPQCj
w6^DGL h@Tw4nN%&JL5!V8I5Qb$amnbVb5VE:PV$$pTy&!#EX>j&5KCiH%PT+9bV#im?ywdnR!5hDWLey1\qkqP
V1>>W1 #FI\h6=#\TE^\a8it/YVhWm9H>i#+ZqJB%V5GIeuY6VPVi\@PmHR<tF5^JZyiVIX5Z>W#d*kahjq8!eS
pu%SC1 6mVDpe@AA6c54JLhJchKuC1=uyYbi?9P^P&lRV&SVWawepCSZS$tLLhJqlc1\nZ\FbSpcW5\pu:%Jib=
Xt%1>T QS^Z5LLde?MS/mY??@GBy4WkC&AqJ?DqHdDtpVSiTb$@GmKD$Zwb#PEwI>>PX4T94!>l!=Zm&wq>?In5
pl\cB+ +YlMkwh/dXL/Xhy#C8NVaDhlhR\bVmu&4dcZhmW=WyNVW?*dNt@/De6lI8\YS=*\XY?/\9y6ZnewGb$t
NQ+iCw \nX/9yK$Kl6u^lL=m+V1e<FB8^JDktj4YBRZuFw$:CZi1wMtG:TKaGT%Y1dK$BK&J+Cy/<RuLyp:LFPd
?kESPH tK=>R&nlkJ6#yS$h%$+L48h*u+KC#aRlVK=4QqT65\V&MKJR#u#uX@<p\5LZ8TdPntE:mTB81JZ?X#GI
tcm+AY ETGPI@*K\9a:S9HyBFJ?QpVDl?MCN%CpJ+V44IYpaBu>eZWhpF<dIFWX*6MD!F@/^$PCq8#ytj+#A+MD
&nJ%Qp Ai5!E1:jnc9EucyW=Pwt?k?ttH%&W\nZ+Pk\nASm8lK\S+?y@y!1\1Vp:LRhP:LTRNF5w8#YVaudpl*y
ChS%qA bD8SIQ:N84X5Nt%=&Xat@ZSpu6#nKZ4eKIq?>ayKHkC@e5XTnp\wWV^QS\\Dbm99b@cm=X5*@!Ft%t^#
la1E>i BIXaVqLAlmGmIwq:d5IC/4@Y&cHYH=9IGwh5#cul1SJC%=E^YWnd!b9XYBD@9%dCpwa6IV^JABhpE4!u
4wJQNw YMEm=MTE9Zh*nAq:#iLF18X>tBE9W\mpu\/GE>uD><iX=WRHuJjy$>*uQ#4\\DmA=KQyC+Nu4mHC5m&q
\GLEK+ pTWuhk&*6^Jbu\dRV@<DQZY#@VShw?Pmk:<d6>adQ=\**Re1jI$q?L<j:XlKDPjEP?\Ec<G^w:49T9n1
^\ckAJ BGFlK>t*dTWH%yFKKKitdN5pl6PY#T?>p6neKHyMt=%t\*1^KNmXeX^1KmI*RFem18LV/j:LN?^/ihi8
hwqEIy EN&5c%SNIA6:VQt\Zd\81d9*ynTLcGAbYTncp&wnuVuVH:PCAG8jhF\lt!P4t84PCKSjC&Fb\=K%XI1a
t1AK+i E$um$m\l4DKi@9:>QTb54#Fa9N$pLAP4^lCw\9A+$1<tlA?tQEKT@NGny^>MPnAHj8uCleBXaNY!t//J
9$QC94 l+<iQZ\+#kELDtQeaHu5D@MYR!8mBhiud@!H!GHJ\n>C+RRSXnN&#Y\8?$hWk5Z\?/^j?S%#&XPT$uhp
VnM9!n ReGt&puBy6k&d!ZDCX5NWt&d%/$nBW6TiQPY^CL6Jw:i8Zhd*H<%D\dDVDHLqPeRKMLPE^>XWJ\?jYHI
kPMw1: =q$9d>/%IZn&jLQ/H#NmX8m^BBW!1a6<1ZbT5aMG5C&!@b$Zm55!PtNqn54RhhI9JiN>5BhedWJ5cY#i
8?<\:^ dXY\ybtIPbX\MDHVpe@B@$\huCBZ=@6:h^BNNCew/4lVI?dwceKY\uB!PuL5!^:hiQB@Q1a5ZSkeE4^\
IwiG?? #a<@QNBKh>\R^&Im*?iIBYh<utdTSwjE+an?+d/S84QGJ%TWYHZbBe\%!tB+1huSa<jR4<:9X:^nG?qZ
PAQ:m+ X4AyKeVZdat:61da$#MIYcXk%=Q6>M1G=pan8u=9hInpHWj?G/WDqlW5e88K5QP%1VTjRHZ*Z4:=Fa=d
-Ad%:/ 0003e45251200110334 Page 91 of binaries2.zip
Jit/qp BS8q^KJ+=!%Xk4lan$#5k4MDw%mtYMk1iuPhNHk4>&yy6?Lj/Xy9@@Aw^DD>Y6&5ZwGH<&>YaLQalSY?
9J+H&Z bta+Chb$p5K1$KuAia9d*AhaEuiJmt%Z&*H4iH^ViS*QIiAKaph<R5L@GhejHn^e8HVlMn4@W+AX\l4m
9PyCcn tN*cy!WcJiGwy^<tBEV#pJt+GJ%&u%^j#GR%&mej#a@GIk=IaR+m9q<w8ALaKu6&e1y#^?=$!GF:!nbH
!:heCb $1/ZdN6V$^*y1a+W&@y%LIeJ&C$P?BPZ5MJ5RuamhYnDCdX4SS^KqJ#PjA6V!bl+b8bcFYRP+e#ALE8J
\bajYZ ItKJ1BDZlG%R6lMDP$FYEIDXK@T1NddXQBFS#aDyIFn:BpFZ:4n19QINL=B8dGni@j>ceHZty!JI9J8\
n&9E&e #HTpb&V6aK+/Bhp5=+F@*y5a+>GaQSbuS=uEhR$<q18<:A^KJlCcYLdt/j<Q8K=BW>&!Z+W5?@Gu:$!%
a\^+F1 !>m!dcWmWR>WywAew+elQII4IVd8\Z$#HjD$neuJHi*BQyw6K/?+e:$\n\^RlT6waLh9e=Ae#mLCy1ap
!w#MFt PWkRd>%1T$%Qh&TpytT@SIKaaF%Qh\\jbnp<k8L4t#%ZP!:L:y^1$>NbPq?ThY\Z#=:8=iHq<e#C6T?J
9MDib9 Tj*Kl8jtVa4?!:A8Ic#l\%:m8j>Zic#d*bH?*1/PnybY!+lP6WBiaG%W1tFktC/&CSdD5NQXFtwLaZen
NZ^e8e ?L<>I%N!4*VSEqq*IMp8!J=!jnZBJnHuhST\:WnG69CMYn%HV^QYH4jt^m@k1B:X:cj^aEJ%PY::jnKB
qn:58X %hl1\=qFM95@JLnB%jmE?Qm+8B@GXZG1a8#V%nw&dtW@<CkkVlda=Vmb4wD%GM@=\h6ph/Rpy#NjHjaW
LPiY*+ ip=k:64t\IJdS?w&KFm\hj*tX^LL\Nj8c>#1#:9y&w$WLI<m!NuD^Y5ELDAqyuy+ip#>q<Zm@>J>R<np
iMiS?k cIXaVn^dn>N%an1^VR#G>k@DwS4wbXueTm=Qw#VNaABQ9Y^XWFK+9*<IR>d8nk=ADH<nG&pdG&1eXnt<
5?JC#N &=tc+5kkJItw/cqI5*PtQW8<&Q#eMTL5:bEBR^KL:eT4cAlaai#=56K!\tc$N1>aM?W:C=mQjeD^$+@j
wCX=&% 4WDZ?4LqhA9=n^>@@GG!TYWEL=:Y4H*\+*kCKW6Cqi/^lL1B:BS4/Mqp:KMFQQYHB?5%PWkKN^$:h6!a
9&AIky *?TKJ^Myc#jYBEHBPyK#6!btp?GWuyGSt4%XeAY!6qLtK!hk&aG%GE=/ceP!BW^JB9Xba89WGe?@ku<P
i>$YpC Dd%=?ZQ#LI&\Iw/J5B^#p8l@bY%NHid?6*Se%5ACK++WmG*c&KCG6Dh\iw=@w:+BKFhw%=6pDX>SjCZn
%ZGVYE 8tn**!V+#:8RuKSZ:Jp:RFj/+?#yP#J*TA$FB==!d>*==\VC@&wSkAE5c>nG8w5NhYjL#&4CPym9*#GP
B@dHtt Q\mcQ#!a>QGuu*=<?K6qIj<cE4y<JYcI@PQHu*:+:tjIcm5b=\<@QplR1KLD>khP#/4e4Hbn%ZGAGj5\
bm+l=h Rb18>6u6Dp*Z+<hpnl+4YEeKDGIuqtW/5C%u/!=5YCR6=Enb>hJ9%&%b#<B8Kt%yd\Xjl^G9G^CDGD$/
%X/<lZ NY15NFuEwR9tQVid:CRQD!^p>H:tZ=c@9J/%M##kaPZj#LLWV\VMX+LaGQ8QnVYZGNmi91Hd*M/KapHD
ID4ea? :RC&jCKN$<1GHLF%AuSFI>&XK?*6TmW*%DJl&T#i8h8=\=/Tpk4^C\5ST*^*ELSbm4Aq#89@yJjRk#EN
/9:WSS &+p%dJ%R68:5Ye^HSQPXI&HN$>?bFQ*BpL:!<d5jj9ny^@&<I*Vq<qjy@Njq!*MJ&B<ie+PWPIb9?^&J
B\1aGZ :dnR?JXA%b:knE>+<ECKKFV%$=VH4iIyD>ikab&uEVh^m8:a$YNN^+<4ZP64K8*b1jdM*V8!aCwS4Ktp
e>RX9V aHjSP=Dy!M^I*daFlCW^VPCYj6uS48P\^6JBNTGSJ?uq9L4M*>jL$=5k^d+Tn&i<F/+V*W#u!$LZ!SYK
heb!T6 5:kZ%l!6y<KJ1N+uHh5nMcTSkV=BXnhc<NuTIt#FSETBhiktq=l!HE!KYPD1:N#>X<t8P>QI<Cj=T^+h
SLlyL+ ZL4$HTk=bXHMaci9d6@:=^$Rh1CQXY!u$h5B\4dWZYSBDMJmiAnb\#<<?PYVYQ#DV#@>>HiC>X<B/ebZ
<A8V?/ N:://5dqd?Z<Q#@>DFqpcwE5wj4VATE4mXXIX9BXXXMaJiNQt!Npdp\=<CmYmY&ZMRTFlWellTGHG@WR
GYdMw^ iH6K1nN4N<SVK9mc5t*Z%t$!LVAni@MYI1\IWl9liwuiS+!?Gl*pJcH6Ld4G1dmyMCjWj^4GDu1B1&D4
YDAeNK 6MZ4GhKZ<GF#mNG?w:a/TIQhWp%a%4DqHEJ1/CB9y?Pd1@Bn:$LA5q?y+*8CLm@>:PV=+BlkT41S?%+9
K1duV< j<NdB^nZimL5VkW5!YGE9AqPGIkAhkiR%Z\qRZ\Zk#F9$>WllFXi4JnElC5t@JMwLm<6c!+5KI\uPT!J
e#l/^D eAaTy@4\A%D>+d6>^FXmKmH/&1899Wd*X#i?>S<@Ahu9H4i*mN$@juijtL1Tl$dHP*L68Za:?Gw6pHqK
m%uuZY p^WhQpnn!nYR1#4yCw?T:%y<:Ql^NZ?aeh*8TM>m^bPcty&ctp1+b1hkGmVl8uZ>89Z4BS9dZ<CQc<B%
HYhkP/ auRaHpY:Mct&8MkY+?jt+?ulM^W!&MQ#Yi?y$=:@HdF<@TcI<jYdN#*Hl4I=bp<>CXkY^:EJ>uW1m<84
BH/TcC /?8+P++b&!$P#F%4:LcX\@Ih5K++jwnLnH!WEhc8q:@yWPc\\yZ4adnPKe4J8D1J4</$%PV$>DSuGkML
BabmZ! \tbq=6/?K:PuB&+cpqkKV%WD\MY/L$pR\*RmaBMi@jnDL^/eLQ@8*=<HX#i??6yG\9T%%%?uP&G:<aX@
%5N^Qk @CnR@1CN4l?E*Qh#a\VXjW/:$?q$$Q&:^!Y&P5ej$A8MQ+^Tk$&hQAwi5GJZ=@GQkK6+ljXF>6TWhHL5
B<RKw/ MHM5JhYBJaNd5:j#VKPM:htdj\6BVAC>a194aH6+eE\C:GwRjGN>jYXFadVj5#=1C\*JaJ>u9d&uLZ#l
/e=?&B FRJ%$$9R#=8*QQ?e%I*Q69b#ELkwl#EIY%GyXG\nhC\Di=NhtDE8cBD=&KGPVlLCCQeVHujH\DQEtpmG
MA$ySm mP!EkXZnJK+TXSqeb=w>lj\*meDap>Q6\DhL%/+heX+Hai>!eKLj5pNJ1p+9NpDHu1YnuIHN9j@nD#<J
FARiSK mKDuD:mSuIYw@e@@8SJWjW&I?9444:@>^6699QH&/&<R6B5*@96@@mV@/wj9%EZ\$\>jady6Dk\kl+N^
hQ:#+> \1n=H*@TQ<nH@/P9t^>??uc@M!E1\e=ehVJZC\8LCw8PFS@H\dm!IHa=6/e/WAcjuypBaFQ#mLDdtc?b
mqFBZA n8&94F8*j56/q1ZPFpte*Aa>>BJ8W4C%lZGL%F\PD#KDjb=%<=$&nYF>me>Nt+t9Ij>X58qtSqay&1X^
Z56nKS !@SR+maDYF:S!\GKH8lQnJ+h%eP?ac%&h?JnL*t8pMJna!PR\n&mZjW?Sdywt=&<FbTBhVyS6GZuGkJ:
iRD8:q MkGLYwI$y>A%9TV*8lCYVCeRX8&#\$IY+N4TiJEIi^GC?D!mme*Zl@=D#89@ej%@$9EX#1@?==KNwe5*
e+&yYL <5lLB9YN%>>+?<$**u##:Vjy@5adSN^NG>>!@eh@@wBCN^lT@@tQjVGlCBnq&P$=Vwe>%>H5\PB1b@QA
wbwyRD 4i6<HPAhINeQ:G<:5H>@&@+ue=>M\BB/=nXhA9V#tH^bYFSE:^:B?yHkCtDl\cbtpaJ%bnnI6WtFi=Ph
Ci#M>4 ubGb:<^*bG#j6S:Admb\%66=VSlQdl/D%L5mJp1h\?>bN>u9=8Q^4M<$N><b$/dNJCt<jm%hETTG/ZH#
/empEj qyDuLA&^&5tSyWqC&G\i%WW164KG*Fki@5<l^b/?t?!iMyiGB:Ch4Iji>h=49d%>@eMnLKbHl<p@/dtK
8=q6NQ YJQRqW6@c?9LuX!XmGP*M<1SuPSISwwnnjmcdE@DE%QB66&/P@HQi*h8<$KYQ6=ccGya?nP@dKu:<58L
6yd6IA IK\KE^e/HH5hPjaeY##hX6yCdT5*llKmJH%jFb+CXP9^NtELtd#y4a%!lG+M=dH^PjR1nu%PGi>P5JcY
I@XIY< N8<8hi=8*y&:P*hu:yM+%?^i5=QQJ=*PKCejaDb$jVPBT4AKZW?wjS\k4J%pd!dcXwm91h9JiN1i9ZZ:
9d#&1J hphYjtb?S6/&X>d>h9$4c\ubLepZXcKVR*c>:FP$%yZH?<nMK\J%t8<$N#?5Mb*l@c6N/>h6ItSjY4hq
AeXi:Q Lj*#>e@NNw5X4WX6<\I\9HdQQ4Xay:kT<WR!mup<AVGYbHH9#eFl6upbY4#69KEMi/*EeYYK\YmCFDc*
t!qmFQ WNjWq>6*c5KTILauy!R=$qCnJ:nT+XRGeXdtn6!S&^N18\M8HkDd%cYd:C+C&a6%LSDE=iVDem55A?9I
w//lXD eiVkq5Q+9Ly4#^=kT5JZ5D#*8*N999QP:<:^cYBL+JKe64&Gj=Jnw=jAC@HM@8aCwI4#VHM#kD&j8%9P
<\KwM: NZTnp+DitR6at?uHbSJ<piAKaD<=Lu8SiM>Kajy&S\d+T9\pWFNJ1&:dSR4Yti@MVM%?bj%/5wmJhc@a
m9Twpc #mm?V1BmRlanuauFRq^*D^@QcY/E/nT*GY:?M&dPtLu\BeC/j6P/Li9ahAK8!qmcyi5VydEPC!e^1^Rc
WHK>c< X4a=X>cC5SL<bTZd$>e@PDJ/i$JBP#w$MwSNbXmW\!dVIGDq/RMe<?>Raei&/94CuRbluXH&bFScpwJN
:^:$eP 5/eqpTlG&ZTYJ8!S*IHddFlDqY6kP/X:p1#9qw8kLG!uC$nEaq5CI>8W\<ltE*Q*a4uK*nh&9j:GG\cw
&wdGZl RJV8::#D\L:==n5teji?kZ?RR+n8#YbaMjtn5BT\utp?e@=<M>*cty6##>NJB@BqkHPJ^!C%5\An/W6q
u!YQpw d\NbuMYjA6aVc6<XCA5Ft<GCPD?DaHZR\/=6icqwVmy\yL/<=di@JWG<bi*L/^!ZhGECy8tAH&im*V$<
eXF^\d jh^\VQPhkVEPM@#>b!!ePjQ=*&=bS/lCCK>:CcGN=<#cJ?5H%Ie9CIY4A\&4JZFqQbK^>d\1?VLJa9yj
wPHD%* ?\iHCWiGFtQi?iCb@YP5h$phZ8FRW\jD!tWPbP5ZTeY@CPK$yPRpP/qWL1yNV8bt5:R5$dCbu?WPDI@^
Gd9=w+ /:G9k#l^d=e$&RFYeBdAjut&Dpa^kG$8FGT#t:KBDb%:>?:c8@jNN^Y1::#JmL+n>*jQ9ZQ8>\b6**^V
G1H<84 juk9@mqTy+kZEXpJ%4L#bijQ$HuljN9=<&%$=NK=8!$ZH\A!aa9F^YB%1W#*d/+wLuNXE1+un*>!k9eP
k>8\Sy Gk1YyC+Tpw=MMy6T<#JT54huy?buF6Djt$eY<j4%MJ*Yd:G*<Fw@pqh*pSInZGMb%Gq8JH4>*GdM<Qid
hS&=qN EWl$udq\+R6pSc<Dww18Y=/VDL6bJt+\XtaTk:D\hZDyEdK!XSiMdTXk4#Jud\+Nn>^Yt+/M=TqAkWN@
^by5GZ :PM\C9wQ1/%yK*aTab>paJ<ptmdbCM$hcFyJnqTCtPmcD<cY=Qdik8ZElBW%*t%&^dc$ZlVPj9tqE5Wp
4lj>:9 ?5leKTR+*lhw*>?d@eHi9Z@a?<:ih+DyPaL%uAD/L5d@!b&?14H>A@$\@a5<?5eMc1H5aCkqVM?i8WBH
=Dc>jR &>h6^4FjA<#Iu6<NTW%&PTc5FbYXFbeXX^SZGH^XlK&yLaSc#hyNMD4!W@MeGcSX5:jtRSBD\=Ik@8&Y
QpB4*y LY5*p!C?cQAXW<&8ZuL/iwK1jt:?JH$JX9>F@wGLMB*\X^DAAJWj%t>b8@a=4y*RY!a6R+4uLXnKm*@%
-A^w%I 0004d27679c00110334 Page 92 of binaries2.zip
*ZyRQ: Jm!Y^JY%%e^aIl<<%Y>IGHj*kLTpWt>n8\d9WTHm59ucI:BKbJn?K5+SwJ!:8lKF@+19WYlAauMyC4%I
*P<\8p <ep<p+DqMCLE>85e8Q4?#q*bbceqMRihYqZBE^GYGF58w4m+/GnlWRDdBHAIYJ\E4FCWDpB1QjZDt@kJ
kCHw+D 8kA?&Q6?Nqcu=5EBLeVP14I#=ij@eybA9hl&5c*6G6<5!PIAne?eL#%V%u\GCiE!l4Y!8KL1$$<@Pj:J
R$M^mq J!c8yGBFEGhl!WnG>k\!m@Qk\iaZRPZtdj*hd>i@!B4Yhy+DAa#4eH>QX/\QBmNl=k!pL/beL^JaF/:D
\</i^@ \VFIMy#Yp>t$<VuXkSYkl>adheZ#iV?5LNbyKkK!qeZqqhY%>b#hadP+w%$+1/AhpR$d&M+\NHmV^?bh
L!pJN\ 9Z!q@dIaVbeciA6%LRtm&twuRGZCEq@np+CtdkyNnpyLm$e+SnH&&1*lMR6l?*5FYFZE%6y/pY=pFbP#
8Te6!p W<i+qlWV6AV5WTT$*!h\Q>n:\dp@$GpF>V*L!dQFFHQyB#:+A@&D>=9iS!KG1I<BnM*qb</i9ZD&+6t9
$:XP?e L^Km%>18E+:Z415u%@uY%uaB\BK4TYCj\WVE554KCnyeKBR!?h4ACybaTk1YNCwyX=LDGa/6iX9#TP?A
!DRXWS \6p99$l!GJHiLe=8A>ilt%%^=LH!WF#A8tnGwpXBPBcD49>KXlPA*dJ8:Z1Y\&5^:ZS!D<A<Qh?W%&#9
^SMFl\ &eP8D6a=C&QJn+XbnK*%RJdwiBYplV\iHMR1lyGlpiHBRdca!MMSKc#cL:y1G1T@5h4yBK\:^HBCI/n\
c\hh5^ NT&TELbH&euSEe5yM<9SSkwe8N/Dll$eMLbQTwbhwW9IjqpunC*GSKjmy1KnVeicCJ:*Q@nkjaL1HiC1
:LQ8<D Cj4i8?etIY6F>+N#>NQ$d?ljH#%KW4&=8Lt<4Q#C&R6@8Zn^\6h6ZY*Z44Z%Z46P5QJ=:T8k!\l@jS+@
$t84uM ljRTnnLMDCNpQ#*yR9pZ:?FYup/q9TAqFVuu#IL$@D\!uQL#6th9J$FeAF?HZFkAC?9H*6YD\B%\Hdtb
JLpbBI P<jL$=Mu$>FBNBXakY9I4>dyR=V5?uZLu?NikHuGEkin+Y+i%1?R1!M:CXuDFw8P4iXaMeeWY#4dki\X
q6de>Y DY$@V?@9q&Y>*V\%4%$yX#%BwA$J?NyCALw#T9E%PTpTjCYJdI>M\lTe=Cmp%pWY6\$wd$wVqkNeZebK
c$mW\t >k+\69ZLX4KKEb?wJAFaVNkYN^W*HV9&\dEQ?CC+Dq1wi5/ab9Qia?kiyB@Fea^\LTy&qjGW&jIL=iRn
TXdu/9 6*#h%hX%na:4e9dTZY+EL$Hd%Zd^I4H/\qpG6ydiKPB/<6PV^$<K4m%/lpIlmh8M4FI!uMnXAX*#!aZN
GMtR/Q !<@Q!ueYpPZ$!w5pmGH<dGn8STpS%!dp?9t+i*4/B#K5RWLY/KC\^aR1m?FN8G*BA?IV#<@Y#V9E$%ut
k\N%A8 aHnRtBR5Ny^ll/mn/SlKJ+w1Km1%9>QF9dE\wMk$B4R<L41*y/<ZER16Y5FY#ya&KF^4tc/%Lmla/acN
mtH9Yq epatTdN9XFyWbD#lGp@A\6Nlp@lW:5*BpVEl4Qk/wtKF5P$TqmbpEcDk/kti\ac4<Pl^\8cnD#:/+IQD
>R?Tmj H^#<+CCtVd&4<J8M1SZak?eP$<<*jhS$:Qk^ilFTpRCy:8KZF%59ZtJai\uRki91Jk?EMLH+&6eZL6bh
bhI?Xe SFD#A9$c6aS1hYXFqi1MIF^dj?dy=BM>IaeJ=8%=&h9#tc?P:T@@DwVh5t:#q8b4ji\PVN!?Q6eN$*#h
:#<YKp AqeF4kycSdk8DkwLCk5lZH?%<FeA%TA5i#4L@/51Q>ZD8%VbI11Lq<a6=X&V51d:GBIA#Fm/D894/^yW
bPa\Iu G1BXpL*<#bXPbm&j*V%ZiSlmS#9D&kES4Gad%9IE9Aw:tL1DNP!V#1l+nA1$S=Ek6petS$aT4K^kyVK^
?h$/J4 JBhP5ma5VChbF!66:P&Tc+Akll6L8KJnB&=n5c9m?QFn@?MnSldAa6njRSNPQhN^Mt<Q$kXAQ@%S$@Hn
lbEtA6 <8e&X#K5nSyYSuZk?6DA4i8+Zd?qECaCE&M9pn/+iQbLZGC%bGJYX%bXXLt1QuEy9tyQl\V^>n^$eyPh
>tRHEH qJ>HhqP?k\tLD8?CnL^h/>i@?D6P#hm9>jiQnNJjQyRk1@6<X/%cFWTIBm$PmmbW\&IYl@^KmYEt:DyY
CiELZC 5i8&9QDeQNZqwawXpRLkK9L=9%/\XBT5YE=NS+8PE\p1KuAJX>h1l$h#X8S^J+bGa!J+=>W4dAm#e4%p
muXHPe #Phy1CWbZEt+NlP8#mihQJZAuw#^8$SYGey4m!S+w>I%Z:Qc?p^BnLkYEbcq9CTS?N=/TaB6aYDbC1nE
lA&>I! SNhQn:5?P9:BS^<hB4AHD%1k6N/6k9m>e@nbn#://HnVy@VHp1HIm\QJqd4aTdD&Z85jGBm+NZB4$5EA
\iBApt >@bi8>d%Nj*eq!%j%kHb&u1icF:%1bY9EuK1LuVtySKKy#I#Bhl<$4B=&@JAYDTQRlC#?dPy4a?EFjF%
FEQZXN 9=@McZcL^nm#/MXlm#F?MD\5bQG9FK/@$iC8B&QZBm6IkiW<%RHL4ZZ#j+*6/TKIbW$*tTLFZKBawc\u
k8clMA RMZ&E\ik&5u9Ihbi=5HSGDN<YT#lFlZ9q<WLNdXXQLCT?S1%a/jm1\$5JR51uykdtSadbSi?pu+>qh5*
eh*S#p TH@dGHcLCtHXSuaRXw=YXcSI8DcCKImk8Kw4EPp=j9#ES<eQ8\+jQu#\<LqD@^6a#iPk/#*/\ePE/mjH
kk9e/G m+5@=V?WaAXhlc$E/>C6pX8*^t:h85PQjL<%hG9kil?l*uYyBa^FFRjcl/SRE/ZXJ$^eETI8hPSuw$M$
Wm\9!k 1<BBHt6GQ1FLl6N&EJcA*j+K?M1b%N!duEG=t?DD&!&<*AlNAub^TFlMYHleiHnMawL%LTD/GkG:/Vjc
%6I^uY KN+adEA=*@J5Q8G/aNqe9Z/PeT$<Jpa^t<Y\u5BaSycRc&YBVQTEVyYV8T1teI5i#<>GW%5X9WA8MVW1
J6$JFu !5q<na^MmptC*aTb>=ES<bGpb>P!lLCbVmibD5P*ldB*SlY\T5Mcl#C&EV!yJ&Dy\1tw@9Vpy=<i@<S%
h^9h&t k6n*EaD><KA^T@jebFRN9l+/?PFl8kw?PpEZlMDcXp$RwbQ*Wqi*kuZ$%6mhY*j8nN*B+!&eRHbkAIT>
1y<G$t SMC&j9uqq!myk!%B5JKn+%J<dhGB%Ay:RX=1b5F8%1hM&IL6&WSbNJ<XbGbp@==N+uY94Lhh9+qa?!N@
Td=maa LP:#ejh\Y^WYS>CGlC<P^^EV<@!9LNc\TPJ%t>c9Y^jCNJ$MKp9lyR5Y!KJJ6wkbYjb&ZE4J\u4T!JI*
enhE<? C*?&qXpLeEWCe@TR@Fa%@I=e%*4TPV^h66JPMqlkBX>=<l4^qi\tQI&Kn$yVp:4wS4:^EEil9=ew>LCp
VF!\hV &FY6W&hHy/I5EpbM&B4?V%#Xu:11EHM@eRK\H9:\+MFDQK%VM>Rk1wY^B/W=?@ku^#@>qI#Ecm\mdST/
MK^Mia M1^DBC5BPuHu*l$e>?R?Npc$HikuaL6Sjm9Fp8npbEHMVW!Ec+ebtck6SNp$St8R!<1EJhy8S\<cTYLT
Lq\TYa 5C<VaeppZ46?$:Xd/Ehe\E8nQD#hjXcS<A$QD\tQIXAn\!Nmuu@4X<@@%pD%N%wW9^VCRyi\=XJWhTel
XBL1t$ @P5F\e8mq!%dkhk@BLGDdcjCa$Jbp5ZE&GyS5q*wVY<lLcyW4cldic9bed%EDt<%aMW5LaG%$lGFmH@W
+Y+LGF Dk#wmw?$<a+KLA8KJF^nI+t9km4huZ$*d\/SIDa%LIAX\l1HSCp8+k%61GQdnE!Ym11VmQY+CNmQCXeA
L4S6JS c!J=d6IVyYbh:*&I8YI8A9dVV/9IEKkqA:G85dZ%$mYCFdk!19j8VD+JYYI^kP%GZVYy?w5NnRblNc=G
:^M^CF 9Rku%+@pydIk#kSj<$FaYMV=y\B5/m+lLBuF8eQp9l:\<=De*FR*nQRqTJiEl$jG$G*J<:>/@wZj@I!\
<tN^Pc />a9j?+=wMmHkD69*1>B%8BqC*lF6!!kc&ym&?paAp>FDC^c:dCChSK!q%yWLR!D16nc&CAhH^^BXHT6
t9Y9Z4 JMQyTblK+C9AnInHb=DDMeSZRndL\qj!hFkRm+ahJbquhP^akGYbn&4^YkFYbPAu^:tQW+A>>N+=C#>@
N1Z=Lk S6mDwP9HMp9l$=MXyDRIX&#5\mSkNB5Nna+!1kB#+5=h8nN%/jMJcVi=%6XyFF?y8qIC%uXT+cwN+yw1
^4jw+e B%9EBcjAX$I&5!BDCM9A=8iJlq&:j9%4%&@j8djj#ehD:dEPJFkJ$TX+t?m?@QpZq4?%d9LBlF$dQG<y
Ke1$P> RVy*/RJCe?/9F>CJl?AF!=d!HqC%YLByd/HT5WZHZEd5mi^mA>u/S8EtG<l!NuKS+1X/CJ<cX1%XC6cK
<4@^Qd !5J+RnR&LRy$na$AT+t9YNpYE\G?4kbj^ZJ!>9ZhSEd*45wbIS$+1DX5J>&:VMa!5N#Knl=mX\&CQee@
p/L>!w Ieb?:Dw5R$:$5nW>BQ8>TXIba<WPj+^G*yNXwC5JyD45%$YlEde9nN*Bd$Fkn6&>T^y&nLFq@p:eA4Ce
S8/J#l ptk%XYtNF5Rml+*ISF8^w+Bwiw4djqpRp:tWB<5JDh:=iX6@>?KL9%<QF#d*:5Th8S=1H=muy@@1!FkT
Nyd>>h 9^E^VICImPhj?NWLyk\&pF&@KiVZC?a8A+yL+^aR8E8nF!!h8&\8QwX/^VbCiLDm/5DdIYCL6CM4mRAy
Ite?jV <thpG+tiHR&Z&JTm&/YGT>\PwKL>!tTmj$T+S8$t95ctmS!P\ayFPmCH\!N=JQEPBMc#tK<>lK5T^LIe
Y&FMMy iEmXE/Q\y19#cqiu6c\auZa!iFy/@SB%b<Jc=lK=HqP4=^VG4pMja9VJmiMuV:118iG#VpLl*QI=NCLK
/jQA8j kH/HP/QaQE&KqdGX*&^$qMVI6i=LM46i&::XRqnNX?/P1FE8LDyE<+t\QI/BNY^ijktb^AZ=iT?Vku$S
WV6MCh RaceY@eP8BFSjdn$^h$6HP<S!JwWTe:D<lhiiQ/Fha@4X#4Yl!^dl5ZLej\BP>PJ1k9+W@J!aDayBc8S
#?4ecn Qhy$>FmST!NdZ1GRFc<H@XpN=K/!5t%W/^aIeaqGpBXhWRY!8tw4m+m9h5L!!b*kK*=SAE8Al9QV%bFM
Yy9Py@ X&D4:Pt:&V?5RlMK%=FBw+mN:!A6h?/wD5y/bdJW8TVc\+M\DGDjP@S#k$tNP9?R>K8cyqBb%XcF<I9M
&p?%G< A?nt+y+^ZlJ@l!Ah9aXF+tRcn#K$E!A^T&KXpyBjlEW8Z%#k1=LD$wba!HyXE#cjMC/AIPc=PIV44yhj
4/Hwa* FF<u=>ch@dLFG88nutFe5RwN\CbFdmBk**4lb?1XVPLqIiAqKhI+Bia!lVF@naDhB$eH\Z>Y5jBnn^+V
Qn5G@$ S*aTb<W+4peIA4S6cdCPqeYwJZmX=Dh<YkpH8LnbHpXEnTLDKTw1S9M%F4CTHCbbE=ZGjKXddue9FK\T
eI?$Bd ^J1\A:yYD4e8*iDB:!h^4AHV&AB5>WpwN>euJ%\!IW+N@#Put:<*/St4X^dDJ!6pJC6JHJ/nBL1PC1!<
wi1c5J VZ!I#^F5FejC?D6*Chm:BC#>Xm4yL=JaYW/mZ<%IIytQhknmE9Vy\&\mnuJ\A6*:GI/D&MV9WRT^bh<@
G:KC$# kc8Z1FhQ4<A$:Mpmj#<=Mmp?ciQcF?la>@Nn@hwRE4c<wZjF!tYlCSyb4GIPqdY>i%kPm$teJ=RqWW\i
YVQ*R% V\Zd^jD!!HC51XXdWB4q/EI&n%N#Dc#6K6ZB1FbYFMW@/Z!TDCSCF*8LMVwealm/A#5eamN*CKyb#6&>
VTLV:F KJEdH4%>X%qPa<1J=Z!hP41/4H$AtlNX%c+cVhkVH^>&cYAj5=eW5wiWin&B=951&c@Z!GMKIad:Jik%
-A!<!\ 0008bf322ba00110334 Page 93 of binaries2.zip
8hFStX Ae66bBn4^AiHbcp+>5Z#SejDMQy/8uTXDu/QGkY5=t6nk>=PZPnI!<lVk#W\nRF1qaA>pq>C6lNB@Q5Z
RTmW?N !TRt+8*>cwEduFjbDQcMQ#ckJSJXp#HwNuG6Ai6dFtEM&m=uad6u=S/GhpWwA/1k^6hbDLMelmAY!pw6
$nNE:t Y=F\6y!\SYIY@m\<tly8$+EAluDtSaFXB1\T+kP8P=/Mn&Xaa&Mn5BN%NV%dHRuHnGBhHd5nT+&8di:y
6A#h:R lce#1p5!FGGSM$L>9<c&!>IH$Kn&@%wp5cFl%b/a!hAK5whI9cwSXD^d4L1ci\P=*LN9aGVW1PMcHl+e
lH:/ES HBm<!T9FBh4d4Q+uSuueXJjSpYaT%8S4neVhck#CEqPlaa<I5BDEBbDEbBL@@pXWRTR<=/GY9YE=w%6+
qMIC?t YqITllku+=c+/aZj9LXYp@R6W^l9Y9@Ce5TA/h!DDe!<ZF6lTnIai*6#>8:Ld5yy$m1YKZ6MJi+A4JLG
QFSN1B KETFhX#jJW$j^1yADDK5a1dTNXBe/T4HQ&tPJ$nJ<MXnLIFJ#6mV1!GG/TSWX^Nj&Y\m99aRZ\eGS\%B
Ci9!E8 jGhM+9>C&G6<KtB%H+AtLB56pkBXk@<WaR?>>\5H1>jDkm9tKhS$XVjK^m:yI48u/mIH5ZlcFw4jHLkJ
@1S+9J cMHb8+\/V?45WmyYTYL<E5BXDGKaG^yZF45\qEBatE8yiStEd$qtCXqXVFl!apQ>ii?<!GHQb%clDkH%
k&=BRk jblddF9:t>@<pllGAtD=1#p=i@uM+SZM?6knbMX*\FeT\/^nqj*E!LyWZHET59Za=wp@TNXH%B4PDTR\
GHL4Yu jyV?mW9Ed8!Vk88T<Fl/H48cZP/\tNZl#Njhm1<wXTbBjF5J+u5wn:9F<j@idpIY6?=4n^NYcdE1X4Gj
G8nabD uHVJwCplLKQ1?4p$Q9VlIjF!QqHY5K!Hl^n8/%jq44hHWVVAi<V:WFRLhIeGl+bHSllaTPJiB4bhTYI%
81Nl4I PIj>uFbVqyC>*8#kGR\qJIkJYD1QpPppWJjAmu1bNC\I8*:^XEbW61p?M!ebE/tVp>PV:Tu&dS9Y4dYG
yic=&E JT!WZd>&=X+GnukJcBqeQ9BeWN*dlEYVEMWPC:BHJWaB%yaybJYm=cZbEtQCaG><!%ZJwPJ$AXyHLM!p
&%B/V: %XFQ^n/JtFk+5=TbG^cL=Xjm=?!GHL:Y$*>#&CKIJ#Sl??ld/nRI&>J1IT#Hb#E^?cR^>i?RMVjb>Vlh
<QqBhy D!HayMW\%C6!phIh&DjANS8w&!JaChZiZ8\V:\Y+^F!w&qFyVBkbWppJ*a<pq=jJX=Z@cBQL/ak+Nlu=
Ik5564 iTTPT\nw9Q\nS$wKVlWe!en:@Y>j@Q%9!aq>*w8n\:KAj14QckjBttJQVp%PV?ESMw?FJR!eR>ueJi^R
jJ:^NL p5qk:59BLWh^XZ$:&$T&$J4kKTyY6uGFeFbBY&9EtAA4TF%YZIGjE&kb%>ZE%%nE^SaL4l#Myth^4F?J
!<nMeL 5D6PEc+>lP5AEYJMEbb\HXMtMaumZkY6hP=a=uabp6lXyZ&h\=Mq<YQIjmnnp$WPp*bq8lymYQZ%DjKT
X1BG8* iGPhPKBqbAiq*SjVMBlapS%18I4k&twyteB:+<wpcX8TJS+4!&ECqyA>Rq<Dh%@?QZ\hI6=CL*iqZ5p\
@Zc5qS hk>LV<dpy%S:1mM=bhjcZ^DBuI4h6H=6V6Q:kPy>kla*SqMk=WhY4p*bLwKWqc\!wR1QwXREM&QINIa6
Q\18ZP XFclTF8LAB!J=DdTWb^e1YRwm+9L^P%F@+A>Qm1YECSeX/>t\1=inYhlIiFl+c6n\&LbjTZCyy%HYS\m
Y+bFpS Vq4BVmJ5L^<>9h*tPN5Y1!TYSBp:P#CJD<6pZV*j*Iw1N5P#>?yTbqMdBl!ywAS*jWK=Tt%/V+@WD#C&
:@wXX1 cF!=CW%lN9^1aNX5qSwLZ^8q9St*e5Te<pw+epm/Nj<I&$5\nW<XuDyCV*>Qk9l*JFGjS\pMbDFd^HPT
Y:8YPn Heub!a:$%NV$%P^6/@:*^@yRGL4p96CSDYC6B+GcI&VNX4=P6wY!S>GXlaT:m$t4pK$pMItuHA<YW%nm
+yDLG$ GMYCLD?Qn+%mnyK%FIeEBcS9HGEcFlP&Pt!%=m6Bi^/X4DeHEJqkRj\aajX^ViKK4dyT8hEpdQZJp&yK
Q*!Z\E y?9D\^>cJQEp!l+me%lQbBY#1WEHJc/JGCb#h*kA&<S=S#!9E&h5YS\L5E4Fwlc#1$MLZ9\cln*e!Ip/
RZFihu \FyhZ=kFFI?eAq>J9$IRp\XFAMNK#n4ClQ$>myaY8m5N/$MT&V$5E**8/R:$dY*j5u:hd>hQ^6QW5T5b
5?Kc%Y IpG&ma*j9W^N>aENy5L*<e&>lb1!Eu%Cq*%SEWiMm%kaF:NDT@K+8lK^><1&p?#aFA9$PI4+dmeyDL=m
RH!8<+ <SYJaeCJb?B4*P4X$XG\t%m@Eq>:\Nhllc9y/<CHyZi$6$>111\hYSbJVE=5>ep1u9L*5TGJNX>NcT^#
:TW%51 5SuZp/+1yX=%WIKL:nFeFiPRbW5</pK8M4mAq9Z55LKhltRGK%%pAm^MJ>VBhBm6LM#Z61wcB@5*y$w+
=>$P!F LAF$TTdu=iNL>EXF&N?D5N+5mL$p=lTa:Nmi+5nMALDbL=QNdCV1%1&%^y*Y@Y/6w$qkFYVj%@TWi=+P
?*l9y= THChNZQcwR%nlBYb5<XN^hw+JpeG+Jc4EJPmc:F+9Q1IB/=lADa8LA^<JcWcFlahHlTPZaTG@*wKjP$S
GW=K=m 9yKC9ZNQCC5JP@Jl<ac!dh14S*i%VydE4GGXmnXNJ%MGc&S=+Lp&l:Zb%CLVP@6aDHP^P@e\!Jb+FHSh
Lm!$=W bhd&TAp%GZhmP\$NeRiL^J%EEn@^SI9BX^HERLcywGA:m>$nLIuJmCLntAq:BDQWM@:\<w9p:BBlF*8B
*%<y&T 5bLW<jTJQEJ<hiSubGRWyGcnGP1*/*=b!&:bYNlWDPa^5wXtBKLyjR$k*=uNTAKA6k=VGB@q1nbZlbES
SRwY9N KLdGIX#XqaI:PA664HCNA$ZymA+QRc$P$SYqAGHS1/NZ4+wq16K=+@Qe1<JZ%XEk8E4al!5u=GBkJ^P&
jD1?%t RhWTXc9+9<5cuDmpMkDGLlE/ZP>^p8+VMb81bCk4d\D1G^m=!\KYG<pA1/!J9*KF/:qaHlP!/FXC=cVM
ek>NJj PVFTP+CTeb*E%^1A&?A5ELFdwAl:lGk1lKXuS\1&@^/MJZ!iu!cR58*p:y>MlnPKXJE4iPWZkNY^y@Z4
n\@?Kj Z!$//mym/lXcmG5peiV#\ma^m1YAR8Z8YBynBPBSVXpk!=wYlhHm&SDmSeXNTkV##Sc:Pm\e/\jB%<WE
Lqe/6L J/R9aMW/&GntK!!u#=*Z4nIZBphGLaIaV1!1ahQa>lq>AB&6Py!wJdEShj4a*Eyk:J8RuSMT<%jJX&W&
AHT5b6 NelMWiqXJP$/CPW11HIFJqdFA%wldR<*wdH6NDcmNwpAYQ=FkG6L1$W@<Lm4Gqh/Ai\pkyC5JqK%BWhI
1VDIp* JkQaE9k/?RWpmX@<@a8wc*uC$#CJQh$mn*B^SRcTRF9y?!>cMH*Bt6yb9>F^9Pm+1\m%L1bIuu^nJ4@Q
A/iHtG pqqbWla8I:S+XI^n:jc\REa9A+NJ4+%c:TKZAN5EKR#CQ4q/FeykBW$WWBJjX+XFS<F1I5J?qu9%G9\e
S5EAlW nlAdllNHueRpStSkkNHqy8e8e&P5hmtE5MJaq!VaD&qpD?qXIwhpQ+HLmCLCdP4T/uWIM^=+=kLaiwZ*
hC%ikc mZ>#8X*Z/X$X$9b\^e/aPERDBtNb^dIeNn4&MblPCN6<SNqJ4F:ybL%KlAXj!i%=?jipaeuZiZ/t8<V>
8iG#a/ ij/AZ*JBKq$PSNtC9P&w4jn>d*=JDIP^t\4Fb^FkeSbNR9YaF6E5mQjTa+=DuFqHp</=H#$G%MTjXdGq
5W\ywd +8bQGXcI?TLWS=GFhbRE5TPPyi:1%ZNZ4\+KC\pKE#kZl<t#%dGu&G:K&6*eLjy%eERMam&JqWqMtA+M
%GIYAT >HNQ6VGtYN9ESuTm164R5Ch+dL$J4FlQl=V#!tcVT<#l?94GBl*#b@YK=KD$HH*Dc?I:/AT&BC^4&t+Y
8WnjHy ^WP*^+\WRK>M8MJ9k9+ec\8\tnqan+IaAJ59K9dIEZJ:\NknJSIuXwSh9&/^8#94X^<PEpemXMW8L>uQ
Alh*=E L!Lm?Dm59#E!:NqELNAJd#?D1>t4#1NcPP@FI8nRpEYl!m\&TT5bQG*/XpwRkt99m?uXAC^>q^X6Dy6J
d%N$4j 4GCn\+IaVn\l\wc6Iu^Zy#Fh5*a:L@S$T?Cj4M*dk89*>/\chyC\bZmNpY!1td%^euVCIwqb^*:+u1c5
5!iNQY W1/<iEKyX#cdG6WW=j/BEY/qGECHwPw=89^NP&HcRS?8CGplnqpWD^q>&CbnG^8BK^uEnT%/+VS<i$RW
Ej$5EV +eTT@CWXi+V=!5DtHaEp#mwl8QQYM&44Z=ny:8:nwcKJ:4/y+9DtC&GJ$!@?R6mJ+^P9dHIeL%dIRtkT
1A=L$L EEZMYRG*YPhj5*NmkthP<*=t+jIeT\m1pM?nVRyadjtKJi!CGDk1>a!+$/5:+qAIG$&\4kK8RjRJ\TuQ
LYCZiH X1>c6V41FAP:\@p%iNCQJq9wX+qMjA>wldCDA@45H?n45=lPQ+5Vp@Q!!epVEuWTaA?bB>dE8NnLWib\
jtX=cp FWqJYitwS\Ek*1Cdnn1AKwAF98D8bTA4\A+Qn?1p*e%?bGQbhqK+1wIJulRKRT!+\lBtXKFtT\la%4DR
TmTDhS 5iVE@wFSY<<t5aePV:mF$W?R5McXRISq^9:tMd41#>h9ewk:AtRlphG/XMSMK!+E^w/tdF8\:#Rjd\?Q
6%!Gq$ b#\Y9&JVYht>VW&Q=RPcJ4p$anIBe++>89k#S#SZPIP81+At$bTiwbqwFSGY?Hy1B+A>=i#1bu8aebWY
b&R8F% Y?G4%4ADR+NI5NCyP4K/nbKa!ZFmR6bI&B*Ym*<55P1TNapP6%ZXe>Pk1NjdIwbJHq!FdpZBi#9*1LTn
:TwZcJ ?F$Kym<VbRXaEeW<PBtm8ANckZE%!=:+1GdCNlee+bn\pTMMK+qjDY^Jjwq&akuZF^c/8$9ImS/j<a!p
A/5k4R j\bp/bd*B$H?MThYtW=d%1*jpF%YdED4W51&CKK#1hAYE?4*4KeHtYSiHqPjtdb<e&mP#6=q5>8DVtA6
6ZaLBt nI<jhYtuBlbVMa6$SydNb91!La:kJC#uEF<bX5ljd9^dSdC8CuM1Ph^5hp=D9>/><#lll\iHl8ppeKXK
y=>hu\ <bycRGuhwFT9C?@b&bHNMB4aD\%WD:9Ei$XT9by#ni#twFWSZ5:\kJ11ALdm/JAm/Y</YB/465IiGd1l
4Z>L1J kS*p?ku/db=+k69W4JN>Ia44&&4KuaWkLJ^amGG&tE1WJPd5LBJ&VNlyVFlY5J:8RSpFCqbT$DC8@6j/
F^lt<y *@^!CtA>hG\qtV#KE!FA!Ea?&8T\^RV/L@J?%5PHS\b=iD@##M\q4:!$WnBXkTp#W1FKwI=yy$c#6dBJ
dG=m/S nGw+W$idTA!9k5kqaKMZBT$CuE#ZSeB%%c1wLAp*uY48ay@@yyLDa\yYM?k$#BWy\BdGW&?9pak%dGI%
HG@lNA kF%%XLk+aZhabLG^1W9a11\tdR+4>hw*\L5uYA^j:YT&1q/Gn9bY+i\*\6w4wtN9D1lyKlMG5K&MK!Hd
1pV=w! aPE4C?KGluLH@$*AEtELtK?A<#PwYQ1$BNyYT&LT5Cw&<c\u\9>EXQ+*S\1E5K^mj/My?=6%q8:J>Y66
?N6wd8 S+51hZCw1Mq8m\>&t?d4?!!l/W/wa5Lm%Ku@5uDDK:6CXS\bH=4W4XCyYqcqKkbFe9jaWaHX$cVKw+1c
FtKctc CtPm^WScnRc^SWJV\BwaFLl1%b^X5XC9<HQPC%>9DuD!it!C*tFFX!YI8e^wTGdS>F6My\/4JGbuB@FE
m@MI+> q5R8C:D/eH%+YG6Zq%yT$Cnn5dG^T!a<>QdAF8=kYKYSD=ZT\q8\6l%K6q8mumP*bdAnStIDYPDc1P*l
-A9WIZ 0000f49f9a200110334 Page 94 of binaries2.zip
H^G>N! tuwL49WN#cSmn^C\?WiE5mXE&CQ!Jjb5<^S1mCb//Qm@q%61CVk6nGXkH#iK#a#h?p*4N>mK&PP5KIwQ
!JSKYC <YYK<lR?VKPtm+XR>b/&iM548=dpMFN#=N#d6E>Fpk%*X1WEt5RWQtyc#eea>nC\p&GN=m:hXRSuIPaq
qT:G@= MK#CX+LY&ZZX+P5I<@YPI8#*194jQEiG$AjRi<%eW@k#Fi9TylMD/#yp\C4:8w#FVqW%9PlWNmj\=I/:
utS@!w M4?#W#1%FcwK&R+Y!1SyTWIVa:8SjqK!iGKMK&M/P#GZT+*EIViH4l6^adpt4M:==:\<DpYRmkXln*^Y
6!DQCm Y5J&WRtMJ$RuqCStempu%6$@8iDIMc8K@bqN4D5uN:E5*tBDu4Rw^liDMwEq5hZL<%p9AQ#M%GtL%:/!
Q<=H<k ?iWNPW&c1hden/qqYiCK>R5QB%@KN1^t\l^$Bc/EaiCmSWSVAycjwHF*VllZT=Dq=ER5l@p/!FXEt1>C
qEY=eZ YBdEhPIak1:6N^eBYQaAYIymPMX?klqLb9HHTkLVKR8:ZL\8l6W45uS1I+a5KaB/9eyn#>8b4c%T@M:V
\Nwq&$ Q65X6N>Ik#eQbWAy8\F5F<>dc>HNTwn=<>l<1hB6L9kn5^NiLGAm\u+GPQEqaJ9*l=ibnm>M<%TTGPA?
9:!&k5 5RwEQ*Lpn@R9wGJ@@?L@?4$X$:Z1ed*MJ%m@jqPmw/p\!M5LBIZ\XYRq9j4MnPjZdu:q=Xe&lpwm@9&e
amkCS# 9bQ#ip%:4ab^ESK$\6bCBKwk1DEYuc!\/FYBRcJKX#GcwP5mW8PBkZNY#RpM&/HMy9M5&JBZH^\i$REu
@1J^Bk RjX:Fj%Zyd!*S6u4MTZ^L#k:%c1=:eRJa:GiC\aV!YCPICw^#P1%Z1JNSqSmYCaC15EK4R4YF8=ZWhAK
Jma?/V b\Xa%XS$n/<I<tMF%\=4HW^%G:cX%*jXNJIpQ5I1X9RqAj6bCVMY!ycE<SEaS1mhiH/c!81\E@5M1Xk\
jcM6:A F9@pGN6PL#=8QG&T\RTpaX@mS9aNIVQ?^e8hDnJ?CXJ\qc!qla9Zduq=!$89dLa%KTG5WM*S6:%NS55H
E*8JW6 &:?5Yw>J<MJcY^=DWllap6AFT^qQVMQ\Z#THu5\J!%Jl^QNZ8:1N8IVk19n/u%J#P5aF9AT1#H6VyyP^
6qjHuh YLVqeT>Y%nlyaLuQDykihmu61nh&ea%:S$5uteQcdP46=6F^M4cww=GdR?q5XcSqeMYVFSMiyl/WLF%:
M#4?1# jd%QQIFS/w&tu<PT8K&cy<R&%nu@!Aa\<\?C8PT##$4apaGGldJXKuct8\wT8:5@+iWZtetZ\S>bEt9n
m^kZ#8 cj$9JNkb+Jikb6i8Zd^++e^y9l=V9h!J6N:VylGwt#c@<lLB?pww\bb6BVdu:S!/9c$y8%jqj+=KTwBV
9&\Kb! 6\/V#WVbGM\$CaRtJX#>CW>C$*?S@+#ARH?ChW/p5y1eq>RaIdKdMEbI@FjNX+p=AhG^Wed*eeK&G<DY
iqNR&^ N%lW4K#W$<l?LAEJeuEW4B^611tSGlmPN6&X\Xm<yiC!tE#wWyHy/C!NFYpF&T6Z6LEH8%k!:a^4+!Yn
JM^5aE 5%q\4iiD9unB<YelLN8*dBI4&\tCGKmJaaTw$%SQD#j@PWFy/d6LDIIjEY@uei6yp:1@^KaV^lP9J?K8
BiN?#e Zd9&ia\Hiu:=<<?9*dBqQidP9:V=qXh5&bKpqe#:Q6\IXcQIVSQVeG\aa/YPyhamP!/I!AqWX<$lYAFu
HkKnW% ID$lbAG4@/w$6yp?#*LKyJp?$c<nIweu6H/X4M/w\M4R1up^*a>Lat6B5Zm^Lq/Y?QFn!#BJCy<W>X1Q
a?n<!@ 9q=T4%*KHB:l*W+5l6Zewlby??Z&$FdA&!16*cC5MjyIEujEh5#*d>VCw+b*@I4l%FDQE%mctdEqRqpG
%^bJa* >9NTyYJ^5m5D$J=*>\$Mm5\9?XQJ/SLeTpRW@^EQ9\C5mlHL$K/%/@YWQalpunn#MtdcamQA?qe&&e\E
#!+WR@ RNNi1b5B4H9&AXyhP=QhbAlnuT\R$Qu468lA/FTw$5BAVA+nPDF4!6?j<QZ*Z:ZnFEwqVnuQ5$#n?mai
Z*NTwY ?&W/5KbFQK1tMkLaIcPbZRbht%5KG^w5aTjXAWC!X!HL?#BqG/dK9ZK^lLpSW<#lK#\!w%YJ+SalLB1S
*Gklu8 L9E$l6aYp:KCdH<@Pn#l:@DiByL5DRbjpSm8=%cSSpK<*FtTJ=/NE5Rqu=%G6Atj5CkY@jumd=cpqj#=
8RJ6Z= !B>LCFn<TPtj%IZA<BL+@EQ4Hte5^nw^ahilk$Ck=eHm/&R4!$6dNt>$KLiqWBE&t\md5\>X1T9*MYeN
BGAiP> \>n\in=AneXi4t+WGW%mGDKZeJ$DYGeR1HRD4Q=#/F\q6W&:uX>@\:E=<X?HSw&EDtQ:u!KIAckCF1L+
\jH^?& =5DQFkGaS4ER6py9N^ZPulBaV*!mR9+5l6WWTE5WEi4%T48i+et#n%qlM5R<b1NS^8P$t:La!N^NCK:e
enPAtj Dh\kRWR/&14aHEc#Ypin<\lW:J<FYRd&C\JYCF8kdKjj9@ndq@@M$9jQk8^y<wkMbA6W=MuR5b6MBd8J
tc8LmG i*b+B6B/a#\tI:8bB<h9LC\8Pmd!FbMqqcPDJl+8PTbp*>dIF8y<AGLI@EQTEEJjCJuDHCXWihSj+A\m
mXIa*> 1d@jDEKYaHWLnMym>j1=p>?h:q:&e#k8wRQE*%6mVkL1HWbYVCiXmWWA:=e#ALICW=A>+bLh6W1=epY+
NpF&?$ qIS#B+e5PtE*S<%/qBDqJY+5R@ekMG&E88%wWaPQ&mX>y:R5%!p1981/6Yy8E%EPdCNjF?iXmn$mFGZR
c?CRKE YLYY5CR?W9CHq>p5ilt+\4W6AeJ@?1^EqDJRFZ@u^etW=SJ^VCFH#w/NJ=qp8&+#XnCybV&&mpwJIDWb
mM5=L\ KV58VJW&pB#e6AFq=AMIS^VCwh+eyijR5eE?+CdlPke5bb:TE/\!>=9n=#?H%K5VySLN*?n^m#h=Rl>Z
@LE=6X PE$ahyP1VGSR:#K\y8q$#X^u%#Iy:tRYuu+mY9cE=14T44^G9F+u%eWebniH#Kb&6cikR*wFY+\Qq:mH
:GVk:Q Y*t$$LLI#X:S1V6T5p<<wamyNELdTjS=%%T#JAd4Y%y&m:QD%1$kT<A!ZH<8aBa4L*d:H%t4q5kBZE8P
b6\Dl@ =I5l4TqLQyFXDIP8dA&9p?qBbCpJY%pMd>/!Ici!&FYJ$KAR6ktMBdD:wF=Zey<ApN&*X&\pXbBKEyq@
EZW+%h BHKcm<^njD$>jImnCqa*j$^#yCh?M\lYQ+llFJl?:4!w^&4&e^^^SCh$NKwTT^SkJ#T\an4%hJ8T&DTK
wejIuB DSXd>aqCF4VqS/+cbnFMd#puZ>q5R1W@+Vw/LG6FbBmKZCqhDhITmyP@hKqBR/95y&>$pGJpqHF6cLVa
lA8d+K \<^ZeuT/11F*5Tc8PXP<YKajE@dMb<4kFYhHQJtZn+m$L4AkY/AC^R#5!+>4YdceZlI=#IM^%+w5b6Ny
4/TMTd !<b5F\d1atmkFM9w1qVCcl?4%=W4e\m:qhy?aquMPXwS%Ym/bMCDPZ4qBqn>@GjMaKd/#ZCd!aV%>%56
NH\kZm XqPY<>I*X#1:Fc/D*JE+PVAlbSPC/kRnP/yNy%:h5tQGuSyNTY^8I<a56E@WYtIWRYE4J4*di56iF=K9
lLRu/N h^Hu:XeD:hq=bWRlA:ASTG=MZncPldQ6ynCtZ*<ai*%b\YwL4y1>bKc4nCS5:dnw@GM?&$=K\S4A+6MC
k4hNN@ BybVhm?#Gn=mAH6KM#d@CGwcC@Kp<FnKmnhy@^WY$#1bJ:/bQS/ChhM4t#dtFNbKV^#!=L1IwmqQC&J8
mR?Wj> &XLI\ndP$R/QeuGpY+<B#@FHBM9L$>PNRCR+@h$IX9>yIC+>e%8X48l/wj*Kbe%ZnE1hFJlRCybbiyiA
NnMFlM yh8Eq5V>ymV8XGX5&ucT%M=JyYMXbX%/&:V5JiaTW<LINIh=@t?*CncJhyWtZ!!jb*Pwm/*cSqGXLT&h
/eudjp ^nT4!$Jb*6je$GBY9%bZ6StKuHW#Cj*#=P!\JFa?LBt<AFbmD?#QClP*H<uV>lYPAtc5qEelVbCj@#Np
LjPAiJ 6$laAyTXHRC\mDh6*9T1A:PH1:q@mw51qE*Mdm\nC<JKD>+i:wXYHp?V51*&=HAQ=5weAu!q::PIT@JT
hMk^LV mYpacE:!q?B%t+Gb!Y:?aX!JiPwWYeMTdi*yqe/tpXFLlbMbI$c*PH*%L1DX$!i5KqbdPuw8Va*iMe$P
kBQW$a #$q>/uZV55KYp#uKHFd#845=K5HXD!&1iX5cjZWuh#%*e:ew$w4LI!NBi*wX4w19QCP!1pbjRu\^+Cy1
kZlBMQ e:Ip@9MS#hnVy#<:w!W^jiYIPDK@l?Y5\lEAN15AqGXk<:mCA9%dZH@/+nyqMWuAcR5HJunK@KcZNtdu
na>Ec/ NFjYX/8te!S:ZC1qK8=PNkeu>wC6AC<HH&Eb:%ZbP*b\TXB#@#5R><i1QE>8\jd!<AY!@qkZ+k8?$9QX
>k*\NK y:k^^%qKd\4Ke*6/i!W?QCKb>Z6tSwh^JediIXnyQtE^uWVFY8NPLbM#AFWKYV:yma8@YKYmRI*e$E\!
Lu$uim hICn@wK4MwhqiJFc5>na$DAJbNc%q+TB4a1#hHE?<aTmb1PE@eWmJkY4L1IP9w186iWjMh^aJ8\bMa1F
Pc>F!H 5RW1wQnm!*qTLFEklVP+B4K+MDYjm>:wlyEX8%+tcNEM\HGJ>ew\*9K:>X5&&VdcCy64iKaYD+T8aq\=
6yCWXJ N%9EJW@\Sytb\qhIap!R5iyaAuajj=QHXiV5CjZ&ti1B*DAGVZq=iQqMI#Su?IK8hQwG<1T%4FQPT?&c
6L>SMa 4=\iGS\b+5w%T$bHG<TpY+H1uRtJQ!qJ#L%auZwXRK8chtFWV/B@<1Tm4bCXqc9I^1=/dyD5/8:9H=Xc
4E$cnN ^D/D4<y118jWDIHblWFGnHGDDGFwWLEwZk:YD5=ita!4!PF1nt9XI>+pe4m48@6c:y<B&S>%eIII?<Xu
\nR*kT PqwI8%lqYqNQ=VH?ZPF$JK5p/$lJjwpMNZB\M&%?ukQ#bZcSh:yi8dBE$6@>d599%4=15:9K!wwdctWE
Ae=@*\ Hyq8NhX6J/51iFSweXFVpYI5t$::^NFlXBqiA%l&b/FhX+SmnPdKuGZVpKAu:i4J=Sj$%MiH6<H\@lC*
bZAVN# MB+Xu8X$G5pSeuQ/yh>@=QdnllP/%%pMa+\T^mwbyqNj4!W<$h=1>5Z1/kqW5wt6yET\hEe1$alGPp/1
F4+!m$ e/p@8/<GZ>W<qAai6eCA<4BYQSIHlXETm?wR&=mRJX^4bD!h^qWW4Pt@!u@Z/&SkPb:+S#GhVy>YFnLj
:>YJ<< JhP/^id<e*+i%<@ImdqQ?jp<lm?Vb&uTkYWj&:P*:61<?SY!k#i>>J6Rt<*lKC\44=P=VA*%hjWN*NJK
ZWcK5F 9$@d!RyT5SXF4tK8MIc:<\E4&B\bWdFTnKeeDn+Ja$Z=4klNYIc^Fc<Gi#$4TWTIae+B8u6/i$:#ejN^
DX6?Z$ w=6@=CqMH#nqQN@Pci14pl6l@=Wn@*eu4IT>M<F<9aP+MeDX95=N9Rmk1@NuYZaDYC&NmdtkL*p+ymuV
nhX:dV w6cd5>tEy6b8ZmRt?9WTa+yBGu464YDK:^h#qludIYpBPD*AXY^juiWZBe5FE&IPh@AG8Q=eFZeTb?hQ
ViwqW? Jci@IGBLXEJPiV9@/<W6laX&l<!nWIZEQNKLh:XkM&YGA/nTub/q&JLn+?MLue*qc8yHw^wTIe8aba!b
k^Gw9K >FE^Z+@ymCJHj@e^Z@jyKRaR^j9EiGLjFZVFwK?XK!Tl!>wXTZ6/:8Ql:8H#LMQ/:KyVQBe^!$q9l!GH
HJa6i: tc@DI>bIwqc\h+Y9AQdPQWQDD9eQVAKYe*c6p:1^^JHq+R<MKk6lwyCc4N#SanYdS91^1BMdHhW$kWd%
D$q:L$ #nVW!M!dTaich5V16qHTAaS46RkClc8KPMGc+1%@LXna&N5*MHC>&YR5B!hK9nl>SuV5H@PQGEb^ZtXq
-A\>mt 00091c21a6000110334 Page 95 of binaries2.zip
*>1=S< pS*6Qh6=9KID5&==+=CDV1#%JtAhnqSid8p<Z!jd@E^L\Q^h/*CqXYPtAAnLbY&/J$A:1Hw&^V+l4a+Y
K+$Qi+ p^VP+WE#QBW1&N9D\%9GPQL8WuDZ\^8Pn^6B:S6:^Mpncy5q#K4LESEj=9Eep$6lLIJaX4!M*St#TtJ4
ea4kNQ *Kq%<u\HAA5%Y/?ac^w!:Gi&<L=V/cRnN?et%mecdp/nG9wwwqe^FjnYCti4/^6p%6GqBwZ5E$<\mCc8
W^M6%A XcJk1=We:tmX>cwDk\N6mAwjE/6aVCht4C1N?KMGNl9hFIX&i*:i>8%=&NcTu\GcyteR6Ku&XD6^qIS8
\^ic&I e*uh^Sd?$*t5wYHJC:JKMVSkJCu*W!E/ah4E4GHJ=LWMHbFbMlJkWp+P\dykYik!Lu+VZHtF6K^G>JBb
8Qcab$ Nq/4bFC+5:pXn4$Sa$Y<Cb5?JEI<KRjLZ!G/*kG5h?=1\k:$*>T&p%WWN=wF9FwYM&j^Ta$b5DZG?\!m
+hWi*> ^lTLduWa5eXMJGlA/&9aHJP:9FpcYZb9pSAA46Z!jVV=5V%MCqdb\:#eSHCq!#eZ\CLL@piY^J?S:jVF
yE/RwV cTMKLI\qFi8RRT\88>&S+enL#p:JVmGCPyLndXlb/!yHC4Cc+!Ye@qhSMtY&m\JB4acwjJqIKp=5ebFC
4QyDct 6qCCE?#14LRK+n$=mAkV9CKGw+t\5*m@5AhQ9&ay:EP&MZMYC@X<+$@JhN1#P6@FbVD>9MJqSH8\>!at
eEbd1t SSISp6B<udCEmZYk&GV5yJpmNi4h4hcw/uwn@N$hi54c1HJ#JI!wwwmQ!X%/?*lKTl6Q\^EY!B\4QXt\
qi=X+Y R?Fc4@R4\5PGpeaF/LmM86HjR>wG*k+^X6qPy$9PcGAlt8HdbG?!=ST/!5p=+V=!X&Glk:ApRHQ5?=^N
jNDX<k FYWaF!AVTeYG/#D&ce5MT\tCtuyYkFYEJWFeyE5N5=8$IGbpX:Bl9ELFJ@D%FT5^!G*851Wi&B$6i!/=
>8u^aY hI1X4Iw@iV^DhHXkmGu#q=LI:FSy>Z/&t*kwnQJ$:yth5P#uMK!maKWply6nJ^uF+8&$1BTwMp4%VVhC
$?u?G? TSRZYjIPa>9WGGjX4?46^PLqYQXyA>8Y$6bc4:C6b#c#GhYAiu?bw>uRmE8uY5ql5cWc%GWE5R>aS$i@
ND@#Y: !m<\hC#C@<Va9=$8KT%\FJDP6De%8&VmA^1L\dEKNYmutWeF\Gty$bNtG$ZI1:%kP4e+ThQYN/mbiEdW
/Y&qXH mbDX66NiTeKcpnlln+RWCXl&dWt#^m%h5P\=*l!6nYF9h\?%wJdX4j5#5hkNTn+P@6D&Dq*h%<in#eBZ
$lPY#a m!DYIce:+4\1YP>M1EF:Iwt%:TSD+!jQ&XQXKH^I&Thdy&!iT4DyYt<@d#pbG#G&V4hdk5%eZhPk%*kB
6^lB$/ #%1M+/%u%6cK?1%9IFFH=HnmmTwS^Fd>!6iTPFZG@<jFqYNjbSZpeV!S%G#J@**/L/jQjP=$Pkwh58mt
y1iTcb R5>MKyQt6uIZn*yAY/4Mj&AQCyhZa\QH4F6=/X6L!!<m!/6TLIR6WyK+mQ6mTSLumAi:d/Wi%=c#Ely&
<tS+F9 H#89DG9\QG@Y4n=eK5q!YD/1a1!\6E#5<uW$R<@Dw#iL??DAD15R<b&JThYtF44!b$4DI5WPaNYPb&6<
M>Qlh? \l!&I/cyK6J8W\#VaV&XyPQ^iMSZ9YqQCZPT91#BGF?ilw:IVW%dFicEa>m:qH*DHWI@ubVZNNTd%e#<
+Ai$Y# @:dX1C^RJ<<uGba=ttP=j=cIImIWy:A48LpbM@Vd1m4b\KtR/Yc/5a%Z+etRAABdY+tW9eW*F5d1mhDK
KF+*1t jt4RaXD/p&8$VR\S+K1W%l88D6a=G$%aE5W5mGEWp&MdCnG<aQ+5D+Wl$hYd/=NFHHPQ9bh:QMQ1hMwd
YWDET< K*JayZPa4$4Bt5p/HnX6$NXR5My$G8!*GMZh9N@BW1Fw#N8y+e6dZEt?\l6M<*Vp4l4hk!JV%JK1*K9c
lNjb:S SCE*H8eKTebVquuRM9mCLF^>4d!1^4Yi^?kBX#nL+m&4hE+u*NeSKSPa?H5#!YBHAVaFq=ch^+5kiMCm
tGH*G1 54cC^^E!5lXtj=5c@%CNG=&%w8@XScMJC&R9!eBbVqnWG<m!e8Al\yYK5TKITeNK#Mq1E+5VC*Mab6PC
>!IEc= ydPEw64J<bLtEB<Qtb#kEbu8#MRK!ZL=ZT/dCW!V4%#nbLYIIZtF\K^6J!V+L/cVA6b1FF6*14HHI>QQ
$GeF8i YLW1W:lSPc?5Zut\BI1HJb%nmPEGnY8>:KAGZZuKem*SBSAI\4XaLWM@B%^XN=h86c/8Mi!tDmZ*/V1T
FuHB:F hQLE^QZe*K@c&4/?kt%l>I>pZcPc\qJb4IcdaRcQ&bI1plkcF4<C@e>%>X4+6FyEecNFHDi1^BS?4VcM
5Li@l% bK1R^qb8%JD8t&^p/#m=9qIJ+l\%N%PdVhH#yu6=V@ZmmL@8DbE&Ei+Se@hLS1#Eth=eB\Xu<qZ4X*Fl
w*S8S\ 8bun46Wm%lc!AH5H\:!=@u>+eAB^y#+nGV9b&&FMLIhm1<Dc!tK^u+iap6q$5:hd>C8HET?y1b+<A4K?
$QC!GI 4X/&:kE5*9yWCYlJHyd#AF>tci%pZK8pZ/mtTpY*Y5S5a9Nd#H8!G?:eG?/>m8LHS4XiqTie1YGEbbcl
14&6Tk TRbu&VmY9XB<!eB\1qh@n&ESM&euKXw6\EVDclZ4pkRAy%pJ\*$4X/1=1Kc#R$@mtK:8:PTI:?1qHJ/y
Gyl?PB Ht4R!hVIhAiJ+e^CdulkRe^<=VDm+BAD1+8ehDYMYMS*#KZCTNnyEnaqmhudtcSn<hiw/emKd<yDq\kk
Q^W6K^ Gt@W&#!mNwy#5d?lZ\&?mucFKa!tS=k4%W\ZjYCAd&XdFYFC8C1=1@I=Xe1B=huXX4h1\w!AD@eI4nKT
$$cd8Z kmie<eIME%PZNLZmRe@$eAt\>NJ/%Li5TYHC6uSawG&WEJR^@l5JP+IXK/ZA&GQR5Eid5uZMcb>K/*Di
+:B8#N d6?4ZCm^EtdVe>Pue5AjI^#bLMau*KmHN1JuX>p#M^*ytjbt9wCBK/i+PJ$#kDkmSnp4Re!V%^Y8h!c5
XA=KHl 8/IuDM6yqE$u5b%/4tq*S$&LcVECka!6>qmp%L8%ZXtuk$NmN4Gda/b#nCmm+iARenZX%bPtLF8Q&8wu
6#XW#K unnJ@TG5Z*WeW#t\Ew#8aQh%hM^mP+C9:aJ4Lc/cC4ypmw8%M/L9S<*=AJd=T6Y%5t!8WR^mbVP&YktL
Vm<ck6 qCLLHp*a6m4P%!pX/>L6ente4h6n=i5ieZYRwq8&aNa#EL*5=MDBRc#JT@R4\i9qq=^QjM%$N6jDcad5
dMGT?W MQ^Z8K?5Z\i%IB/#BwpuJ1\XV!w!aRDL$=&M?IVc<#\y^K5^dimTpJ+wP:FP8X^@BQ6/!H*>y6*eJ/=l
*wKt%Z 4VMm=/L?JB/ul^\y%qbYE1=eeF:jaMcHGXhnCtNuq>dult6P8F=tZP9%5F@tp1b1pW!N$BPWmnT8c8Th
+?E^X\ T6w*NG4DmY$?nY^Hw%K%T5YKD+6+Ci69Ge^WJIXM?:ki^tI/=am4R<>I9e/cQ6XLTYEPNKp?ceu6VHYL
4whD/h #HCR$iRwLK@V<ZK5k:/m\9+mlRiHDM6y#BImN4T4DqRwaEhIiDNnBhl4bwtm5u+chWbGBj%RDe^TYK\t
GFyl>I yX=Hl\eWZ^Eibu6a4ei5RTteCuLWXqYJ8Xw6\4IeC:PWdK^kZFYqw<FZuaB6MMNN!DKanh9D9Xe$46Xc
Fn<b:X 8WK#/5b#cXjp<S*F%qHR^VL4D6bkDe#:Dp%aRdVFPC+%t6C!4$d@C%$/4uIT/*VF<FRS%B$mkd/H#TWX
KZlDc: @8jc$*%I$m%dPl$cFZV%pS+>mjmL&#QXK#AXmRmHZY^TpS%c9/1y*CTHSSAn8#=lCSH4PuFhW*^uVFqP
1\E^#n I<wt%6:PyNbaT\lewewnIDkmR8Vl+M?aMy5p*GVX4+kt%S5BSNm?eC+=CqR4<%9LK&RtL&P4eIZlNJt9
ckTSAZ uFh9FL>KCRnh6#$^JHaVM/tYZ%5Qamp8%unK:KTtIpEca&WqdFEyp@pS:#I>HW^C/GmWZbE6l9Yp>1dR
THk^Ac j!Nyuaym1b%\FS<%5#1Y6A:H@qhKIeY!bhP>y*y+8!5Z^+5#PAK4n#8J+/DpnI#$nE^:YY%>R/M8?CG?
K&9da9 hl4qE4\wkeeS5C5\PX6uFqDe$<p/Jak^B8k^aQYRAt9WyXG8ZLcbYlEn/PbX!cdbJPHlZ>K9IwdXuGYt
aNtmpq 155awG%+II#4TRpq%yl<Xjd\yScq$LH5>Z66AE+w@aw*ZEqlip$hD\KwS%$!F16JD:PDTa^ScMwtb58y
@&tckj wXH#XawqyVjBWLPZXKSCnP=1Qe?!GelK*YqiE/hce*V+Q$j1JqBc9IKp5Nc8:l=5C4NT=WhQn/t?pjpP
t5S</* p5PP\4y/dd=IaPL1%i=iFY+CZahWG!^HmXY@=D%4\hQ*E1taBK#BYI96>HlWVZ$G*Wy5:i^T?/%pGaQG
PLa*F= qdjbmnZhcQm96Y44p:ccKtT51?F?!KMFX#%TT9GX:YHG6Wj5d&*pn+$N>SFj+d:KSWQ81SLAMkmA^@W$
1wu/tF FY6a6TS&Xe51la4!/lwP@VjwCHGH@mQ%k<qbbVqJ=KP/Wnt^!uJm\4=6qJ^KiTKkZdqm1hhW:/pTcIKH
%np/9# \=X4Y4q/8j8Gy#w!MnIenp1^#XYWBIFEGeVBM@SJ9h+eXN59^1!CiBK1JtGHLB1Y9S$nB>C8CtMtH!!D
N=wnM5 &Sd8a4w1Ma^^jV%wyt9@S1ZXY<#<yZb#NK+\dJS#4$aeFjPWDeJX=u*Xt\Wdt1>T6mbLQ<aM5yK:N5L/
T+GPF6 6dGS4l9LXFmZ\P1C>JZ\9B+yK/aV:<YR+i*XK85wm?Y$jt*W$B4Y$/ZGTT/5>1WkDVk+ke4DQZ6XwbMw
=e^I:5 YPndQT8ZpT&5A@+iEyL\MyK8W=<JetTpI4&Q4dJ%ZFRk^hZjZEa@Hcb!Kd+P19plRNaW9lbW9@>FaFYp
V&+peu tBq4:D^4db$MK4:T#naVnGG&ttSP>HC@/qZ@BVt5w+l1AT4i%E<4&E@Rl14MV*umCd$%RQNX+/4VPX$/
5y+?Eh K<mwenRSjG%u9lylJy/?hA#FKn^DXpBXA&Yd6NRuDT?m8Lcc*<=LCqm?NTyQy$QMaRY86wnq4&AN$w#C
NehwAl W^XLSA5HP#b:LG#h5&@yLGK4B$<#>^GdmcY\D$yk5CR^CXWd?Vc?\FRjm*JkP/@KhETl/?CA>E8PtwR%
b&WG&B %K98^6JX^ewmbpE5lP*nHECZFBY*6&1Qnyud&1yW1<AK8k/1ceLGwLX9&qWK6<XTIQRaZ%p#TemGMbAB
14\*>\ G<haDu?mDThhB/Q=&mL^LaY4mwYP*S+haj%K@%X66R#u^4X!DE4XP6>Rn:M<JnNFSdPZC:Aet%CYp>cw
8lJW@& 19QQ$LM6P8N8KNlmR#d\STNV=DqK4I1Jmc4e6ENTiK1ZLqWnt+p>X\<%K<F4S4Jni&y?l6*F!+JX$lCP
46nEDw D56lyX@l=&Ab$hDkmJVDwGH+i>N^@h:m/tlkFX<HB\bMN:dHttbZ$E456EQD&mX$FVG5^>MKZ#8Mum9V
nVmje< eNIXjbW/!1eSqXq%Se\wLai4J@FX%#\y9uLQCJpH&qNnZIt9>VYK4pX5yB+:1tyBn?y=yMhp$/e=9BC*
t4b+VT 5k4+Py#jXd%?p=HWS+h+AlI!4%bBLd!C1/JIPn8$l5%Skym4@@j5Y:HWi?yWd\<#$MSM=cAE\whiMcmd
h\<PKI e>kKwSN1niTT=t5*<^Y8K!HW4\R^AZ9dGw%RcB4RGyKaCR5Xi%M^6665A&l9NeHFM\ll4B:6+qL$ASHD
k1pDj\ h$hHiQw*+T4&eKNFD19Ij/*B%&LLcHR%a9IwS?Mkl#@SlqPNpaAXPe^Xy6%GFy>S9a$qiH*C%@ycy184
peT>bT kwN:^iwqn/qJ5^nb<d+cthWp5Byy8%w&mVp&&tHaTp^ahdbw!%kWLH8\MnTcZpV!5M^ZdQBACtiQcVP6
-Ab@Hd 000937d8c3800110334 Page 96 of binaries2.zip
uwb>D& ZP4%L$bA\kPSj@F\utY?i9lEyDyTW9N6bNTSy8eMbcPTHP*6TMD&cnuMy1$$/tAq*Nm>TaT>^/YtB4B*
WHL^#R VYDXYE^L+Et1^RXcnI9AE!VlAC8#6Sih=tNK9aw=nLA@@a9JjG$\CnX4Dd:1GZNH!cw=JpNVCy8E4!i6
dFSyu@ Dt!%NMbDDp5Nil@QPb/R%u8ChYTa>T9nY5GD<QSIRy+$mVph/C>?Z=1MMcJqWk/A=Yt6Kw#4cJqpJ!46
PNl1lI $>Jmtw@ck/&8NK>QKFn<j?>nqAl/P9a^1A#6@&<F&$!!\lTc%S9Qu$WBDAieEkuX:H!duT+%?8%4SZC$
9SLGC+ NLJ$=EShD$>HBF?^pwmw!=%%w:jHJ1\PLF5dE&aGV>Z?n@KE9RHq^XyKFD5X5l$CLEAF1tA4G1t^t*uM
6e=jW# HE5K9u:V$Y:J1$?8\JYX:m#AnJt\Mn^RnXDS8FdX%J5F@<4QWW6/WQ\+mypFVFbm/@A\?#tEK/6ZERJF
Y?BDCu ?p4S+@4Nwj*5!p=C61^T*6BGK+D@t+N^4XYCGL8PqKN5bNiN:nyw%*$4q$$HY**M<KGH%El\laTHh?C&
FuCEjp FMj&nBlTENn8Zc/4e4kWyd%h!YG&l/Ewd@bLbTIZm>\%VPD9BhW^A>l:B4BK\>+$kVY#5S$!hap^yZi&
R!q9*p R%C>^qJ+WIul5bHljlqpK6&94T$6p@m1DPIcD6ZwVDjVXYp@Hl!b4iY\/ilI==ZJX+=H<*1IWTE4!TjN
Ay6:<d %?4KCuQRJK9V>=t8iVIWIE?+i+\HAS6PM%aHXwlJ*Nn!j#/5lqPFYGpeteBaJ1qj&<5d$ET:pt:%u141
SFwaJp T4$pi8llkhW6LC?F?B4c^B51K!w%Z\ZZ%596*I#GJAY!nK8$%w*Iy4>:@=R:\*4*4qFL<j*n\C4dCh=P
Ki6T*4 6<qa<<DuZdCEGXa>$F$6+aA=#Gp/k/?VCG9w%+1K58JmR:eiXaVCkBZF%=PI@J8Gp>c94bc1G?\lyaQF
Ckt>6F VN@XD5cX<>%FdDEhudSFA*5%*6hnAhT<WZQ#Ch9EY5NcwnD@P%m^N:hGSe$1JluE:?6^E$4D:qp/%YP1
d5kLcd !4q/1IQLlTYG/L5pL!Xq8!%$L<bZe:BERq<1Da4KNiDKeula>nlKC^b9%B&dMK\qe8Q918plh!j8*qN:
S!ZiV\ :BT\+84e=Dw&W<X&A$wmKZnK1Hb&t:APDP9=llJ6+lp@X9@%ej%cZcPdDSWA^%S6hb+MBZ*mmj<@WE5D
XCV>qk BBRAAkAIAPFXdTW8NY1+4l<AAGa>AAA%AAAAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&J6eHM9
t9SR?E eGX!e&>8aY\9e&qpbYJlem=mdZCqi<?Q*FciH?tT^#VY\FcJMacFPa\dk\D!KW$RBpp\\ZkC\h5HB:Hm
:eRbW! \>bm>:mIhJVBnh/n&FCV@d4%H5&PNd*Ml1#W\Wj6eRiFkC#$RV/q?#cHAMql@\Dy/IEQ%eEiKy@9I/9X
:!h:GB :YRQ+/c1YXW5j6:*=@6<9+?p@8&@?+@@^6DdE@#h\^@H*^*VME#nnn:?@d<&44d^<Nh9tZ+bYhc@$V><
R4ZMlw ?P/::@BPS#d/bY\&@S9>w$Qa#S#qPQt^WnQqKG!Y!qYGQdbMZh5i1phQ5JeQyZ##=LX<jT/j<N6kn>WM
CBbMXE Y==u^<hA#N/i*CMD@a?&S$4^S@!SjL+9#@ijTe/p#QQ<PCi<5mDe5klnbT4dC4&uB@n:Hm+B=Y@+p&ie
aSalX! 9*:#=lqR$Fp=?bjK!4ZP&TCWNP?Sd#hAFhVt#+BtD!F*hnS#byCcH?W+ueC#thYdQImtIhVZ?Qee+Cj5
Rbp<aQ #jq4hk:$DJlCAc#iX!VbAVVHT!pu&#yNKdEh=\tByV^@CGj^@M5H^^tk8VN:N#</#w=\?u?ACtS\>6db
a/pnA# Z%?B&ZQ&#SN+/9W#PXP#B<iPii^pWNmBGBL<=X+?I>M%$uw4XctZCuI=??abk:9!D^$HC9@t!DuKn%RG
*Fc>Dj hS%uB:ytZ@aB6?l%TA:4k@YRk9!GQZ#>?9W#=MYHiDpR:8RRnWnDX6mNlKTRdT$?yB%CJSYHaQ!^J?#a
alahA6 icCeCaS>AdQj@aRR!nKBepn>IhyZFp9%BJL=N<<p+/@bk#^:eK\iHDt$+XV<Rd\J8cS?N9lLDFI^kJV1
Q!&YBA Dbj!G<bic<!:6Q5m#:=+AD&h8&w$\\BbpPqacdqd5PL1CZ@K?b9Z#^m:DVa@h9IHDttPF=^E5\I#!ZE5
cNuPB\ J*MI:jSBFpNPW$w?@Ad^jjmMIWRjH16*pS/@kah@k^A:l<+IWEJb#nXuWY1@%JIXS=TaSI#kJk!AGL$L
w+9<Wa d$QkmJ^tPa+JyjND!yp?S/+!lQNjTQ:$&VQE/Q$ekAupcdQl*n#L*D^#FS*Te+LtJCZG*&8+#F*d<#GQ
%JySV/ GFDIK?8La^4B?pJNlGP=EIj6Z?cH5F>y\eNMSp/1#F6++VJk!C5pq6a=@^Cb>V=!A<qFwkHj\Sk/^/&*
k@ymDy JKL!5QK1yehI4nQJ>WdKQwCa1V&hl6WWB/BBV1K*SKD#/1+=>^b&ydn@DZQG+A%4Ayu@wuE5c*Jc#a8<
9!A?M: 114VEQdcXy>hY:FjK<Pei4c*>NYwa<>!CFaVSDh@AIPudkQ$%J*ckGP5\DtebhpXFTp%Mmw:<9#M<D\t
+XcmhZ MZt$8<ajYqC?k44X/it<KF!AR=kBp:ZYyLLk8i*bT<@LDPCj5jteMk6&I5J=M\GaWJW>h$P9<pV94%/w
TmBXcB w!ciYhqiqBt@<IKunM&4ibmDdp!ID5MR+Kp:kh/&l^HtAF8V\!?XCNSSGHy&/EXXyI\SNPd!Xqk9DPh#
L6c\B1 6+HcGZ^WNhN<^@a<d*I/D@EYiylJ8S4N\\#i??*:GD$KVGQy!eQ*&M6=lXBD>CR*<WM+*b%M:p:5CZA\
Jyhi%6 QjVCqii=BW!*R@1Gw*CW6?#G^qQPylAdi9N=a>ml&$^*^?/PY$%5&*a>6<Hyphj<\16C5mAM<RJ$6P\M
EkyT<+ R*H!FZ\/>$JnSHIkhWJT\<qy+$JIFXWLd:qe+XQw/kPBkjn5G8>J^q:CIjQ1hD+^cinjVm#H#HN:AyPS
kByK1d H%D<%QMY%VKpH<MCd\HmE\uDiM4<q/!cR=H\>CMDi^eMkHtLGSY/5Nm6CB%=1?WTTt6<p=tnyYea5pS+
tHlB<p Pecdl>ZahAM+b+:e^BS8KJW>8@JC&<%ZWSSXK?$t<lMe6Y6aMWnuKjJ1DwHG*cqZVcC@G8hjPw/dC<i^
XBHA/T hX:h5%e4d:pK6b8XaT!1ZiMh^b@GV^qHA5>Q:=1tN/ij\$y>GIDy>d#MZMeJHGkhLVAMuA&w:du\ej6T
inTRid T5lFdK6tQEdG8QAcIkbiu?TPIKkR8SAP&W8C9Ta#*k?>5YF^Xe1Z4YVIu*C!M+E^e\wjXG>!kYq9R&9H
m<FeD& QY#5ZMBhERT:bC#CM\L4wTDB$!!j#?>P:p:Jm=Vdy&GwXXcIFiRi1qG^ZEYLBR+dH=FuDQW%=?ZZMR!?
V^Q9Mi DVblTicP\bw8Pa8tLyRPlNJ?ewLAXn8Sh^b=utMaW+?5%i\DZ<tZ5y#qJ4IR%tyQ$\:^yh:Hl5PCAJa9
*9XmLD RSWKE<t4NJSa88MIejKjyP*8\M*Ib8lMmqhiE\nL5VWcK6nLKAA4i=/hGYQhM\p8Z/4!Kiw+*P^YED9X
Ei58XL P85\I$^BIIAP<5BSXSa+tAkPHG%yKP1K@=L#JQq1lCqZNaYPEq+p8TFnHjkKI?TkhERNhIW&qnlQw/Z@
E1y9nP $1>X:418HVc<KHw\VZHppG:&kHCAXw=A\#E&#KGcCW:%Z/wp>!bIncBYj%FMB$>VEkXpdNAIMK!dW%*d
SKJPm^ SVJj>adKl&D?=#c<DE+@4yWp*F^#SFYBW\QwGdlBwA+FFKXpDnK1cTkRZAJjeN8%J=XNhZZ&u\5hKPK+
eJ@*NY 1ttR#aCC/t^T@!M\T^leNhWa5bZKl4u&ZDY1+a&&YbPEX/qCpcq=+Cuwd^kjLd&@XZ%tCDLZF<qZ4q8=
?SmQmL W$<SGD<$G8!S!WI%AVd!tpJ+dLJDZjYt!C*%qii/FFG>%aY1iu=BA99\E\VdKuB&^=nlwW56e6=*%AH%
>8c?np HdjBFy+:5celFJ/S&5j\F:KTCqpD%aTkATk4@1V!*ud\>MqZhR:P#<NVjCu\+1wyBthSnCqMtA/::=lW
y*=Cc^ u*VL&HiqTwN#+6KyT:+1%DH\5^upkyXSVlTFCh&KmVpKB@b4wB=Npw5e%4qV\AChpZBpKeW+k8LIb4%=
9S+N44 yMW1yN=W>*pcLPH8$LY4/cSZw/A+RREhyBX=pIIy1LI61?Ykc*=qhI:neDVpDyKdGeA\GWVnLbBbAek8
db/!9V AnT1INQyG<^?IpJGcM>QK:LptHJDJ+m1Xp6hj$t1WlGKC4/4H\p8BQH&bK4:Cb%bc1:WJ^Ph%c9qm8bd
wX1\Td ANJbSiG%GIqihlFS<e#XECTXVb$tX<ItJCm8<?E9FBXAX+EY/al6a*w5pAVi/Z^QV=BGGbPRQPbMRyVi
B8ZM&@ !w8$kBLenn+\EP4tqyNL\!HNM<M<Sb1kCZaSqTZXV*lLEFPGNAPH\F/NWXEYVS$F!Wk>b^weW=^!8%1F
P>NWX^ !>Y!/uC/wD+D:T6ThAB1Y4kN6qA$c?c&$&65WL>E$$hMZGRYTwLwqJDi:!kuR@YnqcZT5?d$9\A/M5d9
ZW/a^u V/jN5Zc/dWM5KqFW^X\kPSD6^XWV*Y@H^$nWcnX%nyR^HytVCWKEDZGcWK?^ZHXupKQd6M44By#amm:k
DWwScT /Gk/j+VG!S^Qy%nM>5HiebERFW^iTauGBY%#yRI86m6^?6AW$RLPt5Bc%=qMy@DcVDSC8Dp/yYZWSYW1
K5//Y# >W#!cBIG&q*dlj!MuBnNK?Jj&#&h#KH#DFNV8eLGhFm5Xl&<=W*RmC:=aG!\>hiMtN\:@c@G&EW:h#yy
#6GeD< n1tRaN4dcK?Y!#d18ncG#5kYAZC5TXIMPX\lYXj#I<NAabyP=qV$C^Rmkca!m8yF8%l\+VuWu/Jwap4!
Kbek>h K<1C$4wE#cE#iyWyyqSVKAe$Q$KaXtiqPI8:*=G9:CYZ9waNJtQCa\cDW1iGMTI5PXyQd+ECmY:*4QYn
ij\<5& NQd5Z>pji=DwC>E#P@*>uXIii4=1Q1cCM=tmk*Xtu/DSCC4$ma5!=G&*/paV%+\mmh=ITdENEXENM6yd
qP<mjd 8chwu/1GwuV<maDBCtZKnSd5LK%d%^9BAk@XV@qcyCCt8\&YSBjlclY8JwaBh&N6hW1LYNYR*#&@P!9V
>#=ijm 6M^Hp<tPF#LTtj9dnD+8n5ukCqtyDV/hVuIRFq%Yt/D!i<8&4e5$>?#S&A+ASeZHQ/JQdVBaEjQpLB\d
M4mHq% +\lNLhJnV6jcyk:p=u/TymtjnE^#J@Ib6YS\he!%t/pkNIn\!y6ZB6H=KcI$uhwkT9AhQN%&AI>*^:8t
Cy44GJ =#MCK*I%:<ZPpIN/VVG91FPiu<LmKcR:kbinjkPb5NE:y4G:>F<DVFBTGBWYE^nFAHWLIu?lK??e<tPc
M*V^wq N/KbiCn:LddjGYN1#^q:*Y6Nk4Y91QIYTK!wP1$Y$RIeWyG9BeuNR^WqcjtaLp1PkGWpGW&w:\6Pkte#
5FBNPC cF$6I<Ryy>ILMN1/wFFBFZlCTMn>B:1i?Te\F+8VN?S4XI5?5SR%eJTYabMD/*!T=\W%#=n@cCa^>X8V
phC&J> =IdAQmM$kVucWS?qn!#PK1^h/PJpZ:?JH\1BBRPeeyd/BwFJbh1pbPmQyIn:?AL5byTh%w!TBZIX8pE\
E+59\1 Dbyl%T:IZE\!nhRGa:&kL:AWEA81tP&lm6KXTySjB<%*A*Bnp%!@@T%h%9*ab>6NM8YZZAc*\hI%Xb$j
DZP4WV Kn9YF&Mh/J:VNA4kbTSBWJd/1uEX9eZCbP4hmdEIjc#&<M?lJP8dnmAI!h=ASj?k#WYTdA&t:G1lM9Tq
p*bl*u 98la4<%yD%>>A1+4CnC^4Z5\jcp/LG8YZlMM5bLIdqB/S9w/#Y#YNNVtw=9R*5:IY6PJ!q+8aw\wT!:m
-AAi$p 000c2cd1b5600110334 Page 97 of binaries2.zip
DAVV5w n9wc?Ahw%AN6Lj:!w1DWKL#@lyTu?Yna=cyq:bXk8wK5yP+^CK4I!a15JZMDVE#qWj*I!FPneNY6B4q>
^$%8&I e4Ga^@%$tFF?KIwRZwkTemPw$aeEhcB#cq/t$RLPc1><@XKCAPBXTp1EhDdLNjL+p$?CZ8qKm#YM>/NX
FQ^RSm =Ej%wQL/wNi/4$ncZ5^EcwG\h^Al*WaGRWbT#hY!Y/*cJS#hdyYG8%41Hmt/YnCJyi9&cLACJFawA4y4
jj9y<4 pJ?X<Xqbwyl8FTdBL=uPDWWGAy^Ve1LG=HVRS%1FZQpw5DF1?A1%qDGhH\iD^X!ZyL@4Qa$SEF@TkiaQ
tXn4DI kaMaVpMXV58$LE9T8F%96W:qddCThD+?LnVJ/^tFEdC/kb>DtkuTE%%L>S<dAH&aB1&y5DVc8/1Q:nG!
mVyc5L CphwbaT8q*8FYFS6FKQ9mNndCEQ/W$bKc&Z@A4L#kqkEiSu<QBAJ<4pEPInTBjl#%WE8idw>&M+tY11R
Fb!TID &FujQ<B$t9n+YIpP1#uK!>W1ZyG=aHph+bVTA?CuZHi?=K?mPC+\SEH4RP&41A#R+tDXET>nyQN1^VV$
Fqlt<6 dX+1Qah%aDZj/q/D+EHWwEjkMeq6w=L?iyY95kN5&>eHkIkEGy&cjWyGbTGdTNSB6#y4/pY>IKEWJ5yw
>kB5Tu Wy1IS!Zc!+X8?k5hIpAZw8qmJ6B#pL&WqL*R6u?Dy@e=%/8GRyMQ#TL6hR#Rac*kk@Aw9Mp1Yc$wu<>/
=j<IRj Z:&%iFlYccNyFT!ky+mKdlq#HujBalE98!Y/P+%K$/9ppNRFCK%8w%hH=Cl\lq>H\1@>E4S%XpL8CpEG
i%aGmw nyAyi>YuycVcSFVd4?b$mGBEJTLpw5>4$cE6nBe^w6VVqh/@HDn?F6l9ECT/*NCR\nXBt/cG5pY*EnE4
yT*SMh SWk/R&H+i5kN&4*5&dJ9tYkJHnScKyZRA9JEY/emF5kw!P$Yeb5P8eG*Z8d5Dey@uBRJ<X+NPF:@HhNG
l6du*V LJkQI8*CduuYLSa$Fak+ILYM??^CYhK>C%XVnlWQcnd9\M6XiBaZVHcl/L18ZuVha1YBnAEw?:RW<Nad
>VW/^Q %H<bNB!wAwcD1\TtDc1&*>ahWhWTe8PcbGEtTS<VYdc/wyG4P*ILiRwPL&ZBc^YKBXVDiTI6Sd8Ip^XT
R4A?dG mmal=mJQKV:kDd1=\TXX<XkG9Gt/Jm=XpCJC5w:VJF:ycdSaqNw>caqWm:5?LYWAm%>#EET4a6b%WL?Y
M+kC8F Ji?RWK*QEF=@&WYLG8TiWuVRYLY?bD+?Hl#RbWyRCG@lcq+ImZqH1RnSuYLIjyRlbGTKKRkL@XKYWpH6
*mZVLJ IWa?Ge\pjPdDRNZAmp:YQ6m*4X8=EGuahl*KIGbCHCh^!nEyiM4JX>BScMQntQp1S4@dFyhIQ&k6JT?S
?eP4Ey m!p5V58wdmG!/=K!nHuQAAhw5Rn/GquYwaND5<c:TFIIaFcN6XG*m66FXFea8p6JJ!uJ$iT6&&D^5i5V
laVT/K >KZ9^#H$WjlKGeR:u118yZtRwye6X:#8KAK\6?%:Hlpp9B6!G:uRyyItPKiEqYnbbaTTpC/1Xd9AdK44
!nTp#h 4yGND#j4@FBIS#qRdl8nQmESJiZ6ATaabXMK\WtKFDqLWaH>FIMQ6STSWS%e*HNR!+by%p>#BhemJ\1W
cJ$cbC p^4J6JButMW6kkCyNIpq!bX!$J1K%YANPLk5qteIEY!q1lB*b@AhWZ\:FLWCW:>4!/91NqDwK&$@>+p8
utG#yD aC9TCkyW?HnYuT$REc&iT4n&VN4#=ywN#AK^KcMbqQyS$pbS5w14Np\Vj=H1tc>%>1F#!YMNQ6mm?\&M
EQhKHd p:bALyIYjLhMp#a<T%5+nR!V^DpIG$cK6dePAD$+/D>l+I:pL5y/pWRE^^l?tQy?%dI+%T^A9YHZ&>uL
\1\%cS yVe69W%BeHBXmqpSJYi?9$mThlYjWicR#wynlnPb>mYK=K+Q*wJFl:Wp%RR+c=W5X&hSA9QVlR/\4$MW
NT=Q<K /*H/LtR>hH$y^bw<ZMX6CLFyHSYy4AFiTH?qbh$Gm<1iML<*6>Yq1wj4^IPychh&TMpE$\pPl@&IEh+a
6G<D9j @WB!a?Je9+?Nb1YlPbB?G^QnhC6E8I+AnG4jD%GujL@X>TStNVt:#<e?6t%jiFyAC@SYyC+<:FikHM!w
Cu\QA* MEajD5?V9dY5CeX%C>R*M8VFTCjRtc^4>A^6qBbyGdhXGwjh11#d6tGh?y<R#Dwmldn*V+ppVVFyPhtL
&^aDwH nKZ1/ehc:VB89RZ//m/KF!u*hW:/wBFPmydTJ%1IiP%*NRDed>6cS5$mnKE&mK@ETmAWyaSTb@A#/J?%
E5Tq44 aKt+w=Y>mQ6N^GZl!#JJ<GQ6weLIBdXLK%y8&hZCS\eD:*NYJ/AiNK$?YIAHRHQ$N\GXF4wSWNQ1Q9A1
J8uV:6 WRRlY69AH1GBTtmY$<X?+k=>medZn>VRRqAw&qXaF$bm8JLclLpu<qAw^^bw1P9&nFb&mBE6^ID#AcCd
APVQ#A N!Ku!?ZB9d8=juatEA:AR6>Q&uX*:XERytpNR>FE%X#>4dL8/R9#l<HHhH@8$NP*kA+lJuC#eZb+tB@t
BXXBeG >:^ePHjHtdKn+m!Npe%\B@TmG+yK*/5/^Pk:8Swhm9HaeZ/qHA8dR:j>e5hj4#QL^GKi4t4hB19RD%E^
K&$dpD HGXbdw%Gl+=q=wj$iMJPuq5cNKKu1*a5E:>n4dVbQM/5pckdJA9NBd?tC<?GphQ%>HEtuCC@N:LXQRLq
=BDt*8 GR%lGyq!nM\!uIQNH!^nHHkSekF%IeGKWw^^lkHkYAM5$:JGE@PhdQh84l@kw6?WkYH?%Yb6nQNe!LDX
R\Tw/E AWJ8dVb$I<*/$<*GMyY#&TlE=&D#@SmuH&\p#4iMk<*G!M&jd#an!\\?>qDjKDXc\aCFZAQajMi<B/NM
ZAb*u4 C@6LHQ9qB65/!#D<Jn9M6JTQemG\SwVeJ8Hjc4pt@aLFI<t%dP!lSQBCa\&V*5&h!R5c$e^CWHjTq/Ni
tp8X^6 b<Mpuc&Skq^*l$:PHBQAk<*ckyM&B=b%D&?Zh<hB+Ii?#<qkRRy68EF!<%#LNVQC@mEZB=9Lu&@YPed+
B@/<jG abTVK#adl@IkFYtB8b=\naXw!F%#B*K@!kVpdC+FAu4=c=\i+I9KQdkNR4!14bjM=\pcI6Xn9>ePYijB
e#&mhi blM:NtHZIiV1a@yh=T@Ikl<cEde?&6\AJcZG!I!eRE/>DCCZY^kGL>FnN$FIJu!qIB$nimBehCKeNCc=
Bt/S^C 5G?65Y8u^qpC\@t\5jE%61A\dunRY^DENYm:9R$Y%91hkpIe/tS$BjJTaT>!8X/LNj5lVk=R*6bX&:Td
ewu=9= >WK5%:G@QqnEKRkLent/@N=Zq+/?dREdL$P\p^iY11tDypMw@VB81E9%\C/?F!>A%lL>jIPG9>bau6GD
/aqa>j K\X>+!GSS@FXS>e1<mL5%?ECA+D^+kYKYH!G@yKcjNpu4iQeC$BM?JdR:X6pdcH5uJd>RSMCG6SkRNBP
<h6KK$ EKGyn%9$kKRuXTEuPASH$I%t^Ib8AkpTTqhY\#^\kRu$9WJ^KIlK@eC9t$+FlABLYk=t=mHI?\WLwKY%
W1P^:R m=M<i61Idq:9HDwnLLRC@SAT*t&STKtcnG+4$/N=J8a<QZ>qk+KFI@T#YQR$q/Z9APQQeR@9kmYCR?L\
jV@5eZ M1Z4EYM\BRl<4DSB:aI155dNDZ1a+6:EkDbbMDaNe&V6KAjEpw%hcPMFSc\Cp$nM5eBqtL9k6A!5TA>>
$eMR8h jVVPuQ!ibXln@ZAYYDDjGX99GMSQI@B&mw1Sba+FIXqtalI:^JR\#uS\!mR#miF&M8i8MS=u5AlEB>LL
YejHMJ A&6pjX\puiMaBtqmY9TIKkb\mM&WjtI%h+B&DAhDGKC?*N4F<HjBt#BVyDH!&NBEl:BiGmat?jh*M/Ia
EBVCQk D69j\#HV5F=5Lu?JD!da+$?JKJG@luQ*N6kmAhcEtbbF8RZTy:NNSX@Gtc8Q:aJ8L\tnianaE&QBY/*@
9=LP$/ LbKSBQ>!5>a1kJaD!/Ry@*nT=/1YR/idQauRPbh*uX<X<T6<AWZTYBnCtaDlEC1q!iQZSD\dIpuCEktC
PmNjp? e9Raq$mdXL:wcT:4!TZLcC+/#5?JapBQq+1wW&QZDlL>D@SPa^tBTBKN*XlG@?+Rm#JNdVkZJ+I*<wGt
a<Phb$ mQ>?\CFNuykDhj64nZqMP85^/b8k5%uR>L?Jw4e#EQ14J5>LN@jc=EB#=Qi=J1bLWhDdX@y5Fem4e?t*
9CZu=6 R9XnKCJ4VIi$l1+VXNXM@+CbwSppwC>JwkjmTt4MD&ZBNLcD@E6MwVb>wau+D\YhpaB?Dk:+AbdS<HCJ
:=pT81 NRlGKIyp5$=\Xq&uB?6Z/*YSR1=Z<db?ya&Ilcm^>1h4MpYJZa\YNPFwKG15CtVIP!mSwB>q/L:VtI#*
XC^qnC 5TV?XtPX\^Y4C:4KkbQBh!Z&cRIFEn$P4:GTR>%MkP=Alt5@=NyZbA5$\lyN%1y8G5CTJGEhP1C/\TAq
Ql%Q?C <\HAWmhJWi/^VEdA/m/>DVcl>@Xc\ymTARBqyWl+Kb5clRNn<AI/N#Wc>bKRCeD@CJ*@mcE>Vqhatljy
AyV?EQ Z<aRSE8A@6ybZW5$$HZ/q:JyWN&y>MB9?MMa1CaHB&5c/S<bX4l6nF/+m&8/=piZG@YYeLwD*Tn>tZ=Q
ba6>cQ YF5YAQ9R4hb4*Sw4BGmq4=kX\=ZX:XMXX@6G/a6VBX#mw^dS?n@Xq?<RS/J<je8Qu6it=##yX98Zky=1
<@:WXK #yTXm&Gn8$1FwB6VhP69hWpZEXCE/BqNin/XhyyRM@*M1wqZyl@aw=>hMe1FFRRjB$FC!:aYjV?1kKWj
+pGHmX Aca8l^:5&&:+QM:%aG>j>InWQb58k/@?V%6u^l?*kX?X+GhaA<b@LBTp/6^#Tq1CeeQ+CYC/a<uc:Chk
tW><Hj nT\IcM&4Q?=bu&b:SubpYb@iS@h/B=S=B&<b1qH&KjdWZYj*nE@^*TIA+5S8k$*V^>D?>@$%tiG?AV99
DQcXcM *@dSMb*9w?<:Q><@WieuJ!hKQVySS^Ii58+yPA6aji:?Jh9u?@!e@q9D8d!+PD?ZJ?yCZb^eZD^/9uh$
FPDkKC >NpS65?Q>n:j?%^teJdCaluKMZ*F@VpjyD$<X?iK1TQ/:!JH??4p?X>lpQ9b@j6*L9a?8*>$@&kQ<9JA
G+9VP? 5lSn5N:X=\\c:n?Bq8j<@Gl\/B$T@yu5Q^>h*L@+@Pn?jYAQFYcDaj^5\My#^9jJZMn>t/6w*Hu?@PLp
V:Kk>T yQ?+h@@m5/P@l8/RK^Cnc*KB=Q9cPiycKQe8u5<85pH8*9*9@5j>#@ENQXtcG5aHB+NeLbdRD/@u!^*%
5iR1BM X<@QB:tjE@4Sjel%kyLpduW?%\w#Du@j!KGjZV#@<$H>9d<?ky@9K:K*JZ994Lh!>>p=BbQhVNM:n!=P
TeP@!/ >BELan?uWPFd4u:N$p?9?dt@i5@pn=J*:&V\<^=6EA!hBjKK:SwjZMtF!HP&9@@ntjYB/8&%Q48+n#Ah
XnFB&F jcbIdpuy@LQBX\<=ZiZe=?^^D>HJ%>8yQ6*GTK9>Hhu:/ndaqI&9:P*VCCb@%*?<aC<G<Mp%D&CAI>ZH
HtLwde CL:/+Ibj=V:4Q!myHW4d+PeBnN!t*ECMQnK5k?9aD@mA9Vm@P4^*jmNtJ=C4uBeMP9@5bn\j:9j9#\dh
9nH*1: 5V&@EdW:>!?$#yRdN?Wci&^I^Z>P4pF#WMDQtIQd?G/H:S%pue84\=@LV&?e<h*XHLT&RdtB9ZQC4:BH
tpP:KM N#Q6D9ubicZu+E&hniFEKj<=ui>wuW5>B\ih6!\@uHn??m&&%>ucJ59j/Blhq@9::V\iAGC@l=!iAbDd
Xj$X!b 8cB?*=>BjqdjZ4iZDi@uY:5^J@jAq99:Wt+D&=?BjRc=/VY=A*b4==<>+a<yTb>Dd1@#<!G@8Ld*N6n4
\5ce9y 8jFmTEd=iJ9%1ui!8ll$94m+<uM8ZqFPj4Dy5b<P<9a9j#V%V>V=&@@$S%n+PXD!@=PVh^/!H@HGi!e*
-A8<pd 00030e670c600110334 Page 98 of binaries2.zip
Q4kD&> <\1LMPI/di@tB6bmQ?I/cH$#4+++ea/P$ReHN*L!#>nNHKZ5QL<=Y&B&RQZ*@=EL=qnjXFq?e*MPQu?M
K6:Q\B bS\>=jSni/H!@k%F4JQ>t*K6I<yJwijCB#jpu86Cj8*ICieu:IaJS^Rn%CQ6=<jZb#:X+QZdp>Z#@:ZQ
Wa%@Xh 4@6bQd@A?RH/j@n=#q5yh@cGhtE#?P9PH81@8kC4dZ&5Lw=PaC?FmM:=>>6dMihZh:L*mcmQqD49?+>#
6!IbFT lkyPL@RR#!t:LPYDe::C+HJNt::Aj&QdQ?Eu?!i/:dk+/YFWSYt=VI@4*AKdM9bV&nwD$cZdNa>@Tn<y
R>JX\D ?@6n<W@AF8q\h?&QF@\ieQ>$wP>?eM8pT#ptZjGq9yH/S*N+y@=Sh=Z+^hSLAe8W@j&Y@ttP6L>^n/WD
qXQ5lV a>>mmeXaLjHGE%auhQhj*<4DWZ%w8Hj!1u>Ewd>%^yK%jq!l^1Fc9@1d?Ky@Km/=P6V&8%j>\\$$R1J9
SE?=V^ +Z!LL=DG/C/L4BP>YCMpQSuZH?y%jeXiyY%:hh?t*:=N@#i:ppBdVWnF4^*1u$*w:>u$#/DRZj<c8%4L
wpidL/ 4bQ61^i4?NYl>A4VZ9%n%=:189=T9e:d:?\K<*<BWE5DBBRAAkAIAPFXdTYVEYCV8C<AABb?AAA&AAAA
#M*lC? a&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&J6eHM9eGX!e&>8aY\9e&qpbYJleuk8at%\#Z*Qd>9w
G9XVZG 8y/W?McTkqwKWM8L/:N#JpFE1SlTLWd$wubZ=^dwYL4ApF1aNFBVZq#ed5abwJcCRqTAI*1VYdbinLP^
V9IqWt 5lkym<u<FijC\MubuG#:u:nQ<:+jKey^et+LuEu=pSSFmZ#i=@*%9h<uYj=Q@/Z?Q\1!@Ii%R8EyH9<:
MSj+RR 64XmwXA5qPV<@#+4LJim&YS^5J%k8<B&ni%GV#uaPVn9+L!D<</N98$E=$>\eIL#J#l@e1PZZ8D<Be=j
W&ZmEL +MpF#q@e/P&8ej+c=/>^@lwu4t<EwuCD<#e+j+Q#N#l@e/P\$p/\ZYC:^ucnwtDuRB+H<nmR^+E<Il:p
eD!9lR eTCQA*pe!PNAHlEb<nmR^+E<D8S^II@RkD\P=HEkn\N=HMlDck:peTCQA*pe!PNAH1E4$4BhaL9Gh1M1
*DC4aH kD\uEPAEaCi+<Rq8It4Bm!e+PIE<J=DuBQKI1mDQCiR=kV\upPeE<wn/IM<J=DtBQCiR=\V!WKWupPeE
/8n%5i <y^AulQIe\J=SM&mGW4Dhw*6SqWQiT+k#\Zp8aA<F=BH#AF=LmDQBaT+APAFdm+t\pWZiMMFuq^Auk9I
=ab5:W I&cDQBiR=\L!ZECiC<lDW%=Auk9Ie\F=LmDQBiRS<+1XVpTTc&p*cuLIe\%=4mHQNiT=ln#mByDuG9Je
&1<^+j R==4!HMNieR%IM<%=LtGQNeR=B1k+m/+&VW89Mcd4uHmG9LRlc+l##Zp8aa<%=DuG9KIY+uH$E4WDKY=
C!KJZ5 WXiDQDiR=\d!*ECiG<kn:kh=dmDQDiT=kV\*pEheE9LeRJ+d!HMDiY+kn:ky=LtBQDiR=\d!*ECaG:w$
RB:kDQ RG=\\^6ejIM**9Dp@?hL#?6%@T:*Zp?c*@Y\?X/&?PtcQjG>R<<@>A?>\NP>QA+Q5a:HMddDtC8P$c:m
&Xd/TX 1@H5cn!@?uq&NeM&H<?t+?u+T?EKJqAXH+jaE:1L8*iZiLeYIl6A*jA$<PLDGN9am<jD\*mw$E6p\5cE
#?65w> @Vu?Pb=&DcnZNLBPF=k++F+&Zd4ymi^W+HtHl$JdTB8?l<NkjDkP\Ht5nMi#MhkCqa!qAZd&B+G%5ati
%kwFB% 8\AH5u<Z<8$ukIW!qLXS?PHaQ+!BQCT/L/m!#6B?^w/\X>P4/i\Qe\A/ZcwaP+6<Ch4%ttVtC=CX$W*d
KH<kqt C9Rl5jEA&DGSQbAFPQmT6aG>Api%:6We/*kiC%i9&^TYQR9eeYhB^aGXw6w45N$X=qC%emb%GJeT\L=i
Wt\MNJ Bn8P%eJVw1KB<H\5jJ9aK%?Ch4H4AVBD56Ph>VFlbi&yu^$iHkKhbMp=l#\F<9RK$KL1?e@^ZG%LwqcQ
t&S*$? ?BaRjR5RZaEBcRKTNw?:Zht4F9L8da\<^BdV6cH!NJ1E<Fn>tKC#u?j^#%MmwRpp:t4J&9W6w&eF^<:8
j:L8ZW yw$9iB?VqpkT##wMl5FlaJAqltqmYqk$DZBkA\%E8awEk6:$BN+TI$6dldXXDT9a@tEc#FkQD?qm5VbC
mYVSA9 V+&t+XF\LG^V5p%XDMT8qjLPELIG=ybuydAE6Xj<T!$M9mQ5RNcnY/iM4&I+Mi\/E::#8bA$cp/S>SV8
D1<CwC dtX<Fe:mKTnhW5ZjCuDNt&N^L^1b5AGc+Q+BwIIMC>QEc65WVS>F^>KkeF6kFFV&XpdcZkb*y86D5VKN
>eN4E> #ImmtkXWNwGh#8jp?\X^i%c#c&X84W1&nI+XNIY%nDBmdHE&#<6:6*aYatMjMZ\abH1inku:l>q$Jw:%
aWbER\ 5?J&5:*%u/%84ktwb@c&JZRN<hVIK<qLAlq?BcKAZVE\CNQGeK$ypeG%cVT6*mRibwnn%p$FI/y9CYEe
XLu+X: C:yu\q4&8Tn&SNWCu#EGZd95i9PaZaI5kyblN:@CkjXXn4KheySt%yT@y?D=lB&aZE*Myb/@K>Z9qi1%
+pMkwL #jy+m6^MZEIcYE9MJ*SX!X$BWR^dcSyppRa:&<w+4!T85ZSP+$CD1ZG9ZuQ1G:ZNhu&#:1qnWb5GF65V
Tp8@1R Hq6j>iTBi5CPaCyCuuMt#P%AqqLAX:1HMdAdqh4V&tc6*6/5A^b<aYHc%%LCQT5NJ1Nt+a*qTcX5YkYd
qICRaB uDImiFdP\9a1a#k$8S/YTwX!1%K8P@W1>B#E<@EGaihN<P%^I?&9/Nhj\cqFBAQcKn?6NNFcPGwD9q%^
>lLwqF MtR5ciL5=p#5MZnBN!m5F+1qTut#SK4%#nV?8qC9H$+qV%wkLI!dqwTV1FuJp&B#Vckc^8XY6XI4%&1C
bqiw$= dC<VCB%5yRk=qI/lWT$WY$DhhAE:>k1FhiB*ytAM8KdTJXM?WM%N:C^TdRtYNtFhA*K4Xt=Zt=tZG!9u
DHhHS# jI6qLl#LLyhL6Y1=T6B/=^CnhV#Y:Vq^K*@ZcnYjbNBwZ+q:YYC1QJ8XyaHLNTKVeK%c1>wb1EdWMwFa
PHINL> l==hKXhL^XK:i1<K&P%^wXkwd6eqp8Bd$+j\q4XY=YuG?m9S<PNc5%clR=A\dZ8@YT+*iRKkVVTuXt6Z
w$G*qK 1^JPppNw+wN1ncAH=X1qX1&YTnYKJ*=5i\?KlW*S<ZS/TL=jC4hYi%S:BP#K$\1%VYT4X<VhK/JuKLqb
1ZY9pa \4JS*clmLREdtla6w:W*c%qNaDeAX&%/P!YS1%\w6K46K8RD:GED66*8$JWQ%\5^NX%=YKu^Sk>4PAJ4
lPRml5 $m&WuWwXnp8!yjZTQdST1Z!@XC=Z1=9XclZW&+B8I^9W/tmdXeh1%PRWHAuwqhRD5K@ZHZ4W^9b&jV6w
Y<8Fq= FI1N1Sm+5qd=8+wB^<Nc1%p5\kq^JdtYm9eEp#^LkMMD5Vi4PJId\%YSD/!N*>Z4NZADHAX8X!6PyX&8
A+tcJP pY<%jpBHB8w*RC%+$/u\jRm\F5D@HeByn&J^9RVRh4qXA&yJF5BmBXGu#KXbXh/ABq1uXuj4hZh:!^WX
EXmaKW NEXtEWBY&!+\c4e*6:?BR^it^+IKQaMw5T8X%l4mlLD6tqPl56d9Ya@X+CWLNAqJdDq\eFVjlMc4mMlc
j5FGkE jR6</1Jy<AX9?F&F%1%T5\Y?y&QnwEHaa<X>SFAB4##<cl&+lK#YttZtLaY%LEh/l&1N/MT8AbpHt=6I
Z8WBS8 9PD4%ui**VylHWLDbnR\9B6=5qCHMd:lFN@leZ^5aKeCK6mXYuEhdM8<6A%Zd4YA*JR5ml/@cVqiE?lE
K11ya6 +%cu%8FQn4%XB%%pl1&/T+QY=Qw1w\!wliI/HKBP589BqA*R^AdLqwBYctB:D%18$n^quID1yXP&inc^
iJJjMH dYSGEIeMc8y1*dIhhA^h&uhZVE\uFtm/58h^HyQ&h?lbZ<hEJh@A^FGF@9!\<6Z/PtB^XdQYby>HYXyq
C5D9dy %n9wj^T&cb6tqcyXSY*cn5P58%*jkwud/p%IKldIR5u%c1%iAt#^MDmP@&6<#Jd!qdXmqRld14X\yeI1
S5PuY& e1ZyE^acSS@p&@LI*5BBc^Lck1dhLSj&*c69\diE5TFdc>j4NQE/K>wkQqdCNHHLID!SBFGmY/CHXW#b
+6BSHm %!4Ny8W*QeA=AP$TYEnnkXIA8t5I%?qdXDHI$w>R*FT4^LjHRaD8iBw5CW<tj15NeIXq^uB1^H^aYZK8
eALl1* NPqVhC<jPPLin8eIa^VSPNZilwEBT9>1p&!^<KAk9EZHuyb+ecCwJQ*qeQ*JJP:*aXqJmI\E5Y:d/FqW
W4!nu! ZY9B1S\aF\b8YtLYy8&p#dPdVB8@&+bL8%6%iqTlkMwAtb8&dikMW!DaW&*H$^jlKH#l?=wRpc11mki/
TTNhXw LebYC6%8Nu&:=@RWq4VJtaSq>dd&AA1?XTmkWN#R@14EV\S5V+dll9ClaW!?L@\JP4y:TMMqFnCbM#>5
GIXe4w XR!$>FlNu<yFH9GcJGu$DE^1wW4CHh9&9Wb%E=%89Y^:nKMHMn!X<VBec$!ZF8Sn5y&phM9pc##<wTRP
!V$q#L BTW+kB$j!e5lXcndEV#F>&%@1&=*HcupaiNNqFyM#MYGtjwae\klnCYa$KnuEimY:nZS=TA%P*+4nT*$
c>15?w nk>4KVCcI!FM>^JI$$RNaAwjk?c^ejYK#FF&PtL!beyBGG5\VRpdAychHZJp1?cQA4@jXlQ4<wlcq9+b
Ym9Lk# XcSDVBIGt1ikR6!uSI4MaVFSLVNEqPED?ea!jqDpF<GLQ4LiBtHL:ElGjRCQ?n+%@BC>%KPW4XKGi@qN
AtBCdp +tSeQiXL\4+65Db%@KBYq%qX<8XEYmB#mAHBGW+V@$Xe1yckbP^SGDeJP9J>j?JWqwRj%ZSSK\QP=6+P
Vc\>+p dL<nBlbBDLInPm+lTh6t+6lMF55IRt\<DRJ/XSq$ya^BV?V=AMZbpV>/+dipn^VGT&T/q!@k96@StBd&
IJBnYb umN1FlWncdD&Yp:tBV19qHq%DFm99FFqKaP?HJ*ATJ4@\8?DhL?qGa5tjtT\K+=\>b&AbI%=VVl=DpKu
ia+n^# <KBaq^IuuTiZ1d^aKchPDV&nV>6A\abTAlAkT>#aJ#k&8BmMZDPan%Jk^\@<kJAh>Tylm+eH1tN$TuW4
LRRZCH Q*uyH*4yPJ\PF5V?KLSaR1B?cZLRShDAX<=K8khyqu\j%RpN4wGRVpNamVjY=eNMFu9C%u\5wJ<K?GN^
aK%X!c dBKG\4<WL5K*uBcwHN\TV$G=k&j*kC+tV9ZMDT+FGF@e?XB6:NC&4KjY/!\p:i!nmWPb&BKjHw811ieA
6@=V1P h!/#Fm+VG<PjFFc5&%jT96>8=%D4&B!BDbTu8yiN\kdh&5bGndMKRLZ%5^e@k=Zl8M<RD8JSMJIT5XpX
t8?&t! 9p*jH!4XqDa&Wt:qWY6dyC^b+>AJXN?N>ZXpQh!1K1YeeYdnXy\$>R?HkTbME5e6!=85^VFAjwKlmWi$
Q%X+dW aR/&d!k:Pd+eFLWhKFpnCb48?B5dHDyXhTID%TSE$VpHZ!LyWJBHJtEGCB1jI6K6c9e^aBnlZVnuKYYj
SiBMNY n5YnHyY6!F8!\d*cAl9a<DDedSMLC!wMY#B518a@<$4=W6NDM!8P&<K?DqDB8XX8iTQQRI@TFAJ5\mKt
ZMh^@P W^8VL&1cNtFB%Ya5d>a^+19XWNtSMP\LaZ!hqjc#D>dMFBNw+<c5@T6qeH=cX4=EV9tKV<9mCPY/eH$E
9XCNcH ZiQt:a+QHTQ%Bj/l9d&>X?j41PKSJQZDJV?hEPhhAV5!<STVEedtNajDp@5a<ZyDd?kLaiNW5nW4jHT/
MPjJWC Xqq6VMK5+q\uCBVYPh#iJtH!ldI*HbL$qcDyC#*X5*cK8F>6W<atTykCDn%/quLG?ln/y=$6pm+L*/*&
-AeJBV 000be1642c200110334 Page 99 of binaries2.zip
6H?XVP Xq*HSY+K/#nAhVpRB%5Zmk+<SVRhW6a6DTYc1GjEY:ZT4D8X?=XYF/mm/KERSWX/D&M$%Z1Q>V1Td*54
qkkbC9 I$^e*LDnad<6k>EP1m8&:QM54y1\VN=TZWN>\G%#:Fq:WmqdTykYJ1nAQt$TFWMGuHJRHY!yY*E5lmFK
b+Z\m= B=B\4G@<#i&@h/6EdXiS58nnJwaE!XMFnMkbER^e4:JJJSQ:j15<>IT^=#jpm!u*tt5$d5@yWlAkw$KA
e\BFRX %#/16<q&m&QjV1DI>td>:&5P9bTE*ZSKYIkd99JW<9TZ\1Z4IMuW&6S#c/&<=mq\F:$*^8HFCp=XEL<>
\mJt!q BlKdnVK:?pkWVW*Zj\hp>DK<=jdtNpIDctdY11Yt#QBXAwYZPKuJKI/#E$@L4RQCDk9E^N1/n%dy?n&9
$lNuh8 KS/P%YEyS68KP&?=>Z%%/mDa4G?/P6MptTMI9GAX%AklnCYA+j<k:NdYK9e6:\!D%@Z%>TKHc9hB6:\t
wShp*T idKZEt/CMJ%=m<nd8>88?#5Bnyp11=^^1VJJ$<?D#IGZ#Ih!#AnyI4ZyHFh#4XW=p%y@uiPHi@hc>!6Q
=q^ikK Kp<I&$##q^A86#t:5CZ#KaDhe+NyHH\nM%8duHFB!6KW/C94Xb$LZTwckh/YBuLjDd@DAB&wXyq$u>/9
Vn:cH9 4KZ&=eaBthVcY#R9^&Q::6:8Zwk?^kNjtidbpADYnEJR>u??kbVImnWyPVYyZ4C9QC%d*<GVmX56ki4c
LS5XiE jb\TLYMuQT:/kFJ#w%TX&bT>LaX%>$Q$dy9X#SJ/GSa\>bwM<RPCLlp9?R4ldw$GS18*%!yQ9&NNYGX>
me^n>J iS?wRF/#ANy%8w=RBtQ!*cm/#JX:mkyNS$qMy\LwSuMDPVwIbM^:TGk94?$SpVWFp/18CKWD%puE4V/B
i\Q:l$ q1Hy<lNaX?*LP5=*uFLX1yc1MDFA$TIA:$h\4P1@LX5e<&#R4?Ka!KL4RNTeWS=1/hkX\tLkit&66Xbk
q=!ntP yXSFHIL1@Sb&DCVtD5<\qqA1PhW61BtEAd$Z:8&/ER!:AWZkNakp5EI=WP8ckDK^>IP*R6m64FYKMkiE
nwZ^=4 FQBp4ZX@:eqce+$idcZ8#NFBGdw5d:l$1kH+:l*6:i>FIYiwWhll1&$CX&AXGb8je//AleWQ@5lDKLZJ
TF!<4a GhBQ%>aikHGX$=#k&wTL*/>a>C8ub+d=IA^Th4ZKEAJ58B@6lhF86MEB:Rcu!iF$eV^NNS%4JK6*G*j8
M6KWu/ MaCSP%LCmKZYQb*$14ZJF+#lZNB!V<bmWHRAn/cFN/wPXH\WSj6lhBV6S/=\JY!yD4/AVZW6uCYcWT&y
TiVmmq CF<Kh?RBihV%PcjZbwFWd%HS^Req/L&!>lV89Mb5&i&yV/F/dMABwPu!lqNq@AA%GpTDMP1wpyFjT@Y/
pEDRI> M=%Ne=1YTB/JytXpKH!jw%y*DGFE<6QKQaa\u$MG+%pX?yXFTLV:<GhuA/$D9\LwWWS5Y/cF%kqe*@Vu
?>X=BL Tul1GMiyi=H%mIqTpWjCq\ZTdt%6Vi+PGS/%wP1K>k+X!*^Q>X/4:Ik@X&&uM\DpRApVWB9<cna*lDNp
CQ45NQ mYJ@HImmlT^Y9?9Jl!NTm4dYKwX%=CMt5dY%y@ilcnJ?k5:+j4uTKqeCy:qB\ln@l1Jmpl/Wml8e$<ZR
%=SLwd DGE$Z<SAVkR=TCM1%tAGN1JIXt@WSijQRyDd$:W&bZBbwWMI1y1MyeJ?Ym+na\p5?D1B51Ym%>q:!k4#
e61k+t #8iCVN^y=q$Bp$hMW!Nj>iBb@GLhWAl98jVy!q1>@8>qqyNS@JTkVRuq=qwFZ8*aXa/cwYa:WFnR6Rwy
k&GE=n dGt#Qq9MF$BPhb*qpFm#%=C84Db?:u8QcPI/l\V66ce%Dn41MlBCL1FZ$:56w94jPPBcqWuSIKBdDcB8
ZMDDG% eVpyW/4%DtEBQJqQJ+J<uDE&+AD>\i<N?WZCpjiwJ1WL/4dct8W\k88T\%n*<VMG1VkpT%QSXejl\J>$
CHGXN: Ed%SkWGA449+wF/L=\aa8w/u1$cYpCJZILI#yLJ4n$maLF5Q8%/*Kl<6qm!:J#&TkTShG@aFaideTNkP
jn@JT: JASpwkEDkWYTApQVTd^CYTSA1Vd1pZLZ>*:\tKeSTN6PR#:M>d$ip=q$?n$#N4Q>Dl+/%LQnhMk*GP\N
M+y&== Ine$hI5QC4Z/FJBV5tYnniiVNIWadR6jya!i/duu/Hjbl91hDG4jwAyjZ@Z5BA/>&TFjPGk+CQeGBJV9
:!N?Nk ylh1HThJCJ8pqN>M%c<=NYpMLPNetBj\Hq*4Ph4RjIGRPqBRJ8hiXqFm4A*LE4an&ceD\p=BQnjB8q/4
E8kF<^ JhMF&<Lwi5E+VlpjL@*1m?BmBCdGk=b@EBMVhNnN:P9%W951KI$LbN1*+#nM6#C\P#A/=1e*NVhcJP?T
DwY!iJ Ji^<u1lVI/bTbH4LWB^LWHE<BGNQ6y:CGtVHiJc/qeM\+kRDDN#b&?jEd%Ew%>A=SkpMuPRyA#qlJB8u
\+hDD\ =u!hiFcQjZDQ+$1mCGjCCtTtcD>VM@$K:m#iDD$:aWMkm^JD/JPnbJwAXmm@M/yiKGN?Ttnm!QiFLSIZ
hNdH>q XmcRajyh=F=tZ/NwZ!h@kh6S<:KH/VkNA@1kWCw:Wq8C<C5wP*XyEGauwbwGe5V?j!RyG1t!y>mnLpn*
wKVtih lk^eZe*\1KtMA/1cm8++*>C+j8hAawnSY/=%YNmmqu/XmK/ZN1cu^Wq1+>kWmYJl>we@eNDZE:Kiyk^%
$pu$&M 8==n<pdAAWQA@K^/>wPhw1FdRIt!#%J9h+?wW:F\Dq1Ra@*wCu!Ht1J>SYaH\XtGH9%<tc#TEbI^4@IX
@GV^n@ b!/wQ+F!ldB5\KYtE$$j:+D=C*HyY$!cp?MJA%mZH$^QVCS\@aG\/5qKq!&9b:wXaH%XMLiK/&IwnHX*
q!^LAw i>jAJw6ZRlkP>n:XNbCQ+&P^4!E5\EkmbnLWBHd1$14u\BC8\4E/RjCaQaEEdupQa<N>HcXl@EDH+p4a
AcA&tB h*V1qQEelBMR>uW\ml6LL/^AHPCumKtTi$=P#%\/#kE^h>ajN!\En?l*F?dhBj\kicYW+hSp8&RMXdNH
Awk:lQ bt&y5*I@CP#I1N6RNH!dZH8G5N1*c4!K^=*NZdAqZq$N:Iyn@SQ+91K8EeX1b6E$nT^X4bpMXMBM5$8m
$+%5PQ /VqHaj&PaNGhJa^\IMy%qVQ1Bn\tGpqatDGF<X^&hK+pV4+ad1^FB?5:kS%JA9uBRGj?4L*9Mw!1C16/
QHu^/b *uVX8ACY@VaDPFLHEy@?Bcq4<i=>Fp$J5yb/6H1%PycjM/@l&$!ukn9cqK+j1*uJF$Q\?m+>84/d<yX5
/*WY:E 1V/NlcC!t\18<A%T&J:\:1&1&e@e&VHbT6$1CKqw=yC/<6\VTE$e!ZtT?4Sp/qiAj9iuSiyc$ljG!<>R
pkc/qe JHGN@E#NKZ4V#\IahF&$Vpe/eKeD\1=CGqA?i$X*VqJXm+*u:/S*Wp*H5cp4A&Nnli:qA4jj>LNyR4kS
TXn\pm /k6ZG8mTMGC4dtybA::4JlyIS6jR>C?IyeW9:\p8u5X?&H\ecBJZ89TYlt:&ud^>ZeKGWl!Gaty*1YV#
Yd!<\+ tCR@1w/F:!5!F6<TR+Q\LNb/b^TpH=MJ$Z>W%H@MJR?uu<I/!neMatB*Pm=\lYjKh%j5T/41Y<c%jqp\
kd4J+T jj^FND&h^/LypZBiB9LTyj5>4I/b4hM?\VX<Bhn6CG!1bMQc#h#KYQkXwpt#qml/Qy8bMXNGiPV*^cj:
Q1<j?C <8GSe6XnRLjlTAL4lkCi1HqhJ+ib/Xp<&qlaGL>LDC4=#8c#ccdy\H\?=m<l?+w1d6Xu5uKwa!Sk<kZh
b9uM\w 5EQCT/JG#>F=pudB\Q\uDTbc%*SMGDdNbJTw*lYaD\d:B499G>R&HkN^=>A%ck:DIIG1P=%&S>JXGpEC
IAIWG? HAuh/JY5!VKay1d&TGIl4IM%j/L#h!q1>yATD94Gtjje9bB1X4/hXb?mCPR4mn=QDPw4LZ\EFud?a4m$
T=cbR= 5Qw$M?cLkQye\9ZV+#dP$:/BYNh%A@e+uE!P^b>h%^k&$*S+uy\4JD9l!HSPY8nN^e1AuM6eRJDcPJd9
\I5eXh WRRy1lw==MRXWqXjWj?nG<G?lA$:>LPeS:tyP^Q&S*$p/uEm@eGCI&NEem!EJawSFXlBK?/u1HmTK65q
Ec>$mT 8G6!yA9WME:wY^JW?/8c*k*yXLL>KKlSel^NR\\mYGA^S@<TyMDV\A!LPbEHdFIMBVKp/pMmk*Bdkmne
!/wdub C<I\CceCK>q1qY>$9nR88adHWS\J*&T8jTKRMBwueALIMGc1D?qkkpZ&=6HuC+F4?kR\Qb/Ad^TK+qhS
t\<5ea h>$Mp&EeBhH^=DmKynJ5ay1GlWpRnBe$MnM>e^<QXtCqCZIk$SwSeJIE$XLNi:5=QWju!ydaII4*Sejl
91XcLu %I#Yy6IqW4NV1u4?Bk>lLLtiP?amQ&8Bhu4CD/pnEP5tiMw$54ecSAy4WHEJStHWhHmeSFPydNpqml8n
k!t#%# qH+#q=pt9C@Y@Jj8$#alcCS^^KPR5Dl>l%i=S!qZGAPZlAaWLp*GYuuRl^qGGDVNPBWRVkP/T\w/TYF%
WIKRyL yYc%9=<peVTBIId8*lH^ELkM*wGCpmm8\DZHel!bnE%a=S5AWGd%MFCE9!liLH6q1ki+ZnRH9lQqG^1u
Ih<#!i 81*tJJLaDkW#EFDTFR8#9pViwDE^Vy4R6+A<+YkNncRu8AT5TDJEF*AMKHmq&By9T*nZ9SB$w>&>XVXD
85w6aA N5wb1aKEdmJ$$@G+/yqjl<LaaY:GL+DF?>Dd+IIJyR=y>mkWYCw1tEAcCTL\*YMyB\$j<WFk>=lW=AyS
^wjC%Y EcCJuMJK:pAejTqe=5e+I9LEqAJw^GR/w4XyK4nRBJhFp8HlBwmmAF=FNR@e@TNX5*E68nc#h&V<$Nk*
dnbkEF !RFD$$IZ5RPwcYJGMBLjlE5IGBnR:LJFkm1WL/l%&enTtDiWn\5^EuXFIcH!y1=+8Z1Y!XeCP+*kW>w>
w8Ty6d !kkG!Eq$LE=wt5Fh9H8HewEiHpHN?*6pm\&AwaTS<N&q?5N>bLbIXG=AM>FjTeRAqn/5Yb8JY!l#M*B=
dHIMSK 8m!BEY/TJMM>1HpZ>^eqm*Yq$hbEXp<HhLJ!E%R<\uaTcQAAmiqVSqC9ypt/=C#DEGDaL!TKwYW1hJ@K
!A#m>X *ZWH8?ya8/=4VkB$j:A*&EQ=5Tw:eF>IS\DQmlLy1wV9P>td<mT@9NN5A+Y\e\1XEVjNXLwh8hlBH8aR
kYTM#8 E6:jF<JlV9^FdGAuAYCNt!>pRQFPEJL<cEN4d#TJJuRSlD&TMI1ML\55Ke5=uBX@*>@LA5tAWMh5JD\=
hEBt4F qtyEKT*dK^JjCNhEREWa>E!lG+qLSd9:weuP?8ltB@A6tu@kDlkVT$$9ay?k%DQm%ek#%S4:HV%*Cj:P
ak=CB6 uF5aHdBL*Njw*iZhXhYTRaS^1E/&G\p5mQQitc/bNbB8J\^kRb+c>*t%\6t+p@l!=t/8K9GIyk#J?Tn6
cEiN/P p5VEi?qVS6y?6G?!kMBPqT>kYV<p1RFiWc9KX=aehyLTnTIt1\FVBCBW4RbHnq%t#6*MAIlqp@HaS&d&
nIHB/E DRkdJ6M$9q?yG?Wk>VCl5e>F:9Mw&nW/QFJ!PXlnaXANSiX!HByiWP1Z\lW>w/ihVMNpp9Q$TIQ*qdG#
l\5A<: YJdGZblMM5Bd\\nGyd?G?!bQyW%l5ZQVS:ZCpYbASG\YS:A9+kk:R@nnuJHpEqkmSW+!RA\BhniLwC^#
hX&&y! /DH>!=YmBCtX@mi*Sme*NZ^S6%DNp%#?#ph=em6uS4Kk8$4EdjiZ5Kq?*VSVC/c5nHatLipWJa=AX1Db
q%AaWD +W$uLLC#Lpl:LwXHb/@FK$HbSSJ=EB+b4d4C#YC4n9YW&#dw6In$mlFG?T>W$ikZRJuIadL5d!PFTND>
9laX^8 +>XICpQh=D#LYebVCwC%d#Rdyt9d%Tp>kabtiPG^5Y+wG\kjT\?B&y:Ip$k1*>AW@FFY#wa!LyN!S8yK
-AI\<M 000727686cf00110334 Page 100 of binaries2.zip
\PAnNB 1T#dkHVdc5\?+h6e*ZdH$aYn8V&Z*hNkH:wilhI^AJThA!6YGc&\<lSGkSp4cP8k8VLe%1ycqkq*PtEI
u$4KB9 >Hcw+G&*p+eFeN6XVi>Hk\Ek?\KLqZp/TJe\VPjnbAWcRj&PQ5e#V5#1&\k1p#L/Aa?L%mbRG\i!&NcG
k9j<*I La^SF#H$kB!P$pnTIaLPplyww5y+Y>Hp66^%hKyjyl+Ce=HQ4*#:<4Y\Y+66&TXFy4&Sb@cPwwF&9/Fa
mIYHC@ tDYiH?BmG=I4NP+9Z\T!lb:?Ja\nV&%b#F<W+BJd@>nd+*e5CYdiKtT6WkQIXVW^ajiQ?Ge^Epa!LIHa
!FNLAd 66:CE&L!=^>!j>QM5iMaGIGYN%qY\&4IH*%L5>P@8ZPA8M/Gh+1tn?lbi&t&A4c\NXha6t*??MXP@*Dh
<!Ta^p !bAMN?Caq@mYlm:!>@X&?yj?>8VD+5QCZ%>94F5q!EHCTCcDeQCqeH&/<$SWVcjpJZJ=I:6n\@w/?%Q>
lV%?9Q :JtA4l6pReY68e6PYA%1%@/AbaHZmk%S6M9cKD4cnZLi#M?\QL$FXw5ABCw%iL$eq:/GtZm<Ab5yEpk%
hh9\9: >Jymw:n?GGeweWN8km86BaH=blBPDe\A%4^BYQtKqLDqQiTYDWMLh/DY<ISCMC4kwFBieb$u1Fqi</D+
&E*15! nMDmZ%/DF@E/IX!pnCZ?kcYD\R%!B/h8lC&SS!KeB<EjQBa!9@K=Ej!R^*FDCTh<$qmZ8#YEp:iR?@P1
niPW8% S9\l8//plEZQCGFa8IPE^jnNba%AeheLnWKn?A#9@LNeI+T@>up<EcN6CIpQ5eKY@9IlZScmywW?chAX
SYJ$@m #DP?hb$GaBb\I&Sw=T9Akj>Y?V+4<5?IeA<nK<Acq1h<RY@DWpIjSAa4?LDEyaTiiWJaT^%LLE\>M%pm
^PN<j5 6VQ6t>+I:aZl!\>#H%QVndh/9Zm**D:B^j@G55!hA#\#u4QRQRNB/eajLQ1edenHJb9tlb+DAkN/FKcS
lJ:#La bQR5N:ALhBF=du=pSDnGSLW#lyKV#J9iaj<Y@1bC1j<n+cb9qWnp>=ipi\+nVe@TJ^p>/$IQXj8CT+CL
%+PmT4 qK?FcLB=?y$Rbl/W>@n!<BitS4pJ$1*QXEPl*6IBJttHlFEpl?Qk1%+Fh%:!FdhwYKuH^LmD<H&#AawC
TYYjYm MiH8LjN?:1K*h8==\D@JEdqFEu=PVhkB5>XiTD!%4^<G<wdFG&M<T*Ru8I:uCG=Chet:>L*5<<Ke5E:8
FSk6Zk ?RV>q5kRmI!JwLwSaQiBLGV:BA>G=t$NpjINjPqDhk9jF>\FZXISJIVjh6yBP<ul6u$uuGT+/kl?S^++
itAX&8 4+qplb\B=PlL+cyLmZX>w&j@uh4W56>\mAC4I*F*RnqG^^55Ft<ZE/j#Fk>9P!GAwht*Ab<qIbVbhpLI
6#*dBW @?8C5:cL6?@iJp/H4!*En=Eqma4S5IRR==4S<u:qY==$lT!cYPw+!b>@nS*y<?Yn!L+V54WD%*h^+J4u
@!?+9/ uV=wRSc5EMny?FIPhWK%L6wiGwy8CcJAQ5D^<:kL@uJKp*<>bn:DtSnhPe69JiFt988*?aVQ&=$?5HBG
@>:le8 TyX?B:B>ich+Y/jQn@cY&QDnmScDZk=*wV>Na*9t8?ZGNSe4Bb5B#D*6?LtZKbkWiXwbhbk!*DS9eQyK
m4WPTK !RIm%pHja5J?&BRNWmSmmW*etD9dKbdi6&uuC<n$XXdWca&m>8HH+\HBaX+^48Pb*/J^QQp#W@+Mp&Sa
pRiq%T /VS=4?D68#m>4Xb6mt=?M+q95=%tYllb>4KKNV>6qEwCiDBt#kBbV%@un?>A+X&ycLVqjwbKcQEHEydQ
ckl?t* >c:tX=MENH6tjp8lJAYSqm!tK8$+TJV!&bTyR:HVZ&?VApu4ydSmWqJ!L\8*!Z/i!dJM>&?i+XC/bW6@
=#nQ!= %5hKK/JTa<NWnLR%B^u<T%:LFIT<HZ@ZnHWb!l$YYmZyn:I:5<+mlXJDP!1>4XDmV/IILC+qCTtI&PW@
wq+bT! %kIIq&y>Bp&Hd6?We!yYR%EA?:kl::i$$JL!V85:wYSSIF6lyKCVM^SIWhc%KDMu6Cc!NuljFIK&KN4q
C<ZaZT H?a*#Q5d^1/i%!kYyMAn*nyjX$cY=^8KqAlQBdawlb8SwmnqFF=F:Y1i4<9q8mQl<Cl$6deCllSYSQbM
NhkMn6 $WBSG1Z*y1mlQLEJd+1BbY4il%4R9PbJXw?LWn?!y&:we\k$$jINa!Zd@tK+hGm6!S+@EMW?dnT!/8R>
Gt\6ia T*n6@1p+W\=4wecKh1YRLCt8dRyI1&E6$!+LTmMZFY*dS\B&DF<Y5Km>>j&L4HA%JdD/$mJDTp8/6JI5
@h*%qb cVutiRcubCX=ZMmy4=i?L1qj8cFi!Y@YQ1BmQT&\$9DX5pP!q&Z:5Tqi?LMnH:KK=\NjFB^jedMTXm9N
\MAF8X PH9h$*ED:B9/T:FaN#et8i/RS9!RK!9V<tqmt:w!X9Z=/W8?uH*DN=8cW>:PCFVeE6Z5WM@6HA:6H?h^
eG4YA# djWPW%ct5A54:TwYB5+Wn^>mLeTYlapYwtq^?WF?b6EJnpk+l=QAm1wyHXH^%#a!dcTXtn>JyBNe1in<
@WmZ6< jGY=eFbjZtTXy!?b5nNkLc6*ZcTG5ye*<QQZV*L*F6!q+@CqjQph+5J?p5jF\ElLWPpVk/Mw=b9/D?VJ
*VLQWm CkD>nqJ&e>\:@NZe1B*&\*:t*R/@j!D*XZAHL+dlWyC*1LbeLS5=VhMJBkMMpn+5!>\QMB^@jaQ9TjR*
XJ=1\a C%m!wW^dADjE$\VtSyZG?&KX+Ti@+\EkXGB9*@LMY:/EF<N#H9@K+w=1Xj6L>^<PcPAXR+CWm%Em!lD?
nI\V:Z &V/@SbF6cH&>a:d4!@uRN!jTp*&b!BQu$VW<myV?yPP#*nkK#<PnHG=AZYLwMIu:E*/LI?:LF&S\b*dW
+9b=M$ QNCd/<&I\JM=ijV<paJKm&nLAa:ESAqHk%F+NDnK<\*BXi:A\itL8D@mq%j/Wl8EKc&WVew+!J$<?kmb
=n6#8N ClZa/El^=h4Bq<IFeDn+</@\CQnElLPei6MJF+DC!8a4HKLuDKEjLt*yb/>pJ5&*ATC=SaJ:DmZ#:=YP
9%Na:> EntbVmn*$+PJMA=i?LH=:wne@mP9E4:BmnTyl/ZAJB&!ubNeE5yjyJH\kF+>CG<6HK#=1$9j?HRG&W?@
m5A6S# Hibu==iT*:YR/^FSB!<H$W5ku\8\j8<yTNj@%!Z:EyYwI9kIibARGa\u>C+aN^9<eG\mj=859/ZyL*?L
Jt$@X! GGPt41N@DN^%<G#=?/J+ybi@\eeN\!amK?l=iI+>=^#M*:yc&c@m/w@pwuK#q4<hc%5j@=/5*jnwFVbW
?=aRni &9\B6Kd=GVTPLnB<I*B$QkAwNE*Hel#HZ4qRj^Ba/>nQLI&Xq#>C%\FTP5p4M#4S8VJtpIX?w@G*@EeA
!hVH?F DVNy:QE#CeKi\<:uajBd@BMCV/dnA*=J/B!cQn>Q9N@t9^?\bQieIEkA!8>wid@X9%$RaHTD+I6qwmh*
Xlk4mF #F#>khup+cBl%9@d=bt$Bt@/GI@GiVni>aQwC?JC#*J8b#l<@*:BNhjtm@td^b9=dIE&^!MZ*e6!^jbc
&in5M^ 6<84%=i#T!^D46K\uF$P#=/jDW?H5*qZkMYq\^>JN%Ha1#j9=?@u@+L&^$Z8>4#*LMb>$ac#!#F8iIZn
E<lL1F K>=Zdu<&HQ:Q+W@Qej8#W!CeubwX!@iuy\jja@@Q&Id9diQV\H%F9lJDB%iLGZ>=R=y*>u1YY=SSjDq?
#QAM@l jVY<in&:GuwH11Khk+M#RWb:@lNaDW<QD4+>?Q*B6@@\:iQVFQ4$&>Q9D@:=&?e#>T^W#+GaX?+^uL$j
%kabmn L9%8=&^FtjEqGFPZ+>i#<eG1m?/eAl1MliyXL9h<t<Jm?@/@jj?>99nAWn$um46#>8b>Lyy&l4QXBbn^
T:PM<A %RkcQ@k+PHbP!jl@uRH<Mwj:i!WM61BL^pNi?^kGFn&ju*@Nh=*Pd@F>5<J+yM+#9D559*%P=PjDn@pK
dAQ?+X Y?mbnIeN%VQ+$16W#&iL&*#u1+^H5$@Ck69bEQa>??q%D9jkNLiR5jB>\NFS<GN1Z?y=uMih*%I#&&jT
QRAPkm &5:bJS#/?hYKuw%jk!!>?l@ECI@6Fj5YV6<9ly@qP@5$Y<Ma84:<FF@C=@Te<cYi<:mZTBM4!HCy#@iV
\RTN9k y:V\:Jb>#%Idp@G1ulQ^1^*\njN<F$ShwZ^d!<<?<84lV%e4jM>Y?H/:w8hQ<DZ^P<:lQqnyYJD=F9H/
<Stp+G CtGE<P5:+mmnjQt9$QQjHDj%1?G@LMb*8PuP\jD1D1</8GSmij??5i4T\/9GZje\pV^5yQaNe*G$iD@/
l*JIE5 SIlw:t4ekl$jHB^+B!5GHy/>@wV9Eju:Xj81Z^ZRCa+@Fb8u6*ESMHhE%Tq/15au:\G?*+ti9hY<<Wt?
+a@@+8 ^6y=+%=i*SZNmKSQ^^15jYtyut*D6@FZ?PImyK<XNdNj?qmbu?FLXX<bQj8*:B6@JmuM+lXeyJGQ6ZQ\
jF1VBL $&j+M4=Z+tly*<@kj96/Bbi>@<h<D$+9Q=jV94&$Se>i*y<Lq=@q8*M=Z*p&m??\L@V<Ph#j#^yb@=9b
^jn</L F+p^n@5ahX!\+qq9Xl*<c9c^qI!8jJ=EYbdQ4V6ZB/4u9H&l=:@pLQaM>Fj+u!/i4cl5B5FR?<TwkX/Q
65IkT= Wi<N^/Q^<Bd8V<M44iXTZC6Z=/S?6Y4juW5Y5T6<X#S+itZ/1AQ+MG#>G5ZI/?HXKm=Ku<9<QYhLj#:Q
4Xu^R6 ?hYH<R4j^j6</A#@GK</y=T*9NMPTpyW6Y!*?KJ895\y?6uM/Nqi>ijjGDj#=:^>1ij<QXD*LG===<F\
4h9cRt /P%ptjqTB\t4>pXH5bQ*M+qjc#X94QI6aGC$$8%h#9I8<uGeQRQ$?HIFh&huhTS@wDX\Yp>t@9^l>Pu:
b>DwmL Hq!>?hQm<$QMb/A:918<#n1VYiPPPLye=Z64\dB1yc/@K=ZC5#?ZJ^8uc6@XPIJ>Q*\/Z!Elw>=/@:uC
b+!:+b :wBh+?Z5/<@IJjFdTPMw6i>j@9^JZQV<GCY?id@+DJ6L<ilQ<#$+?/TiQ+tLITwH9@NQA=M6?F:N4E?K
cdNBly Q5#$HK#k995WLpdG5<WjPjJi@Pu6+b$8%WYHQMb&PY><W1:VW?G::wF959Vu==@mi+D!/9&d?iJQHQd@
#&eJp= <R:KP=I4bYAi*/*uui<\/n<>M*uTTchXyPQ=huaHd8QkqKmL8jD>I=Hjw:=jKjHk^$lh!NAnGQln9>yy
9H8AAj HCB6ASa:eT6+e!T\P5@AAXK&!B>^#5CAwN4MbAiR=+Ci^TQ98?=*#+iZX@tlG>%?1BMd5yee^l&uPZV5
VteuVd =NGdw^?Zmpc\=CbW@9Vt@X^tWlb*DNDT&a@L5h4X#KKpTDJA+&nyDG5/YDpdQlaW@pG419uL+TcyLhbN
d^+nCT K#+4Q8N*?\4Qmn5Qh4kX@4W6*h%i#SIEE%yZ>Z\i@%d#lF+w5Cu8ijBd\ZJGhAq:d8d5@5dLSA*:a^:+
L:Q9dS jBI$@1cLN%qm=YCZ!<9pbZI?RiQnT##!^PRq&8*q=WSQ^9uq+*jJ#jKah<C?VQjytkk!4y^M:paG:A4\
>PYHCt =Db!H9R#jFP$qQXLRd+De!uHLiA:?L/<SjjHJeieybh5Z=+4e1dTY/m1@d?m=?VqZ/e4WESY<!cG:Tj=
#yKbjw /8uQ/9tq?5pK/y&PqYQ:Wl*4V6Tqy8P@=qkjE@+@WE5DBBRAAkAIANlXdTWhLhcl4BMAAKI$AAA9AAAA
I&QwMK a&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L$X+hHJle!>*cGF$e&=qh!=pd&PhY%8V*LcX*8hW=V>k
1*FleT b^<ey*yc$pn!Tp:XXw%%5SSdq*KQwt^q<wAt$h*\5AtcIGit=jJ@#@ihA:DbF#tnQFl1pRS\46?=\d>i
euHNWi 66*m\cY6w=e@mtd=+P#^&YZyFw9:@LP#<@<>8@@4=TLWZVi9<PQ?=TLi?BnNt=tbaa&b8ha9@9IdZn&+
-A&bVp 000a71a4ec400110334 Page 101 of binaries2.zip
V5@bY\ ZLSldi9LSdG!dZVhtbq6%9NR!h8#>Nbe?LYL=1&:MV@^*@L!ah:%qc88ZieLK+<jZT=1Z=u9Zi&8>eun
=EeB9W #?:!&^@@<P6qEc4Rk6DL%yZ*L=i6e@Z>!*uX8@6@\Z6!XNq/?iD?\+iZ1>B?KpQ^/?YjE:*tN@/8$8@L
bk5e== ^4dqbXNbZ!6=n:CSij@>?+u=t&8nD:Z=bu4jaFN<cD/8dQiXpyPinJiiQeLT9iiQ=Lt=YQqwREc@huXu
uC/Hqy <N8cI1\dZ>tPS+TFYh8jR&5Y#ub>/$#jqLaD+:a8DTm6q@nhBhJqw1<Lb/+Vea?un/h@u=yZ+edl$eR5
K>GC=G 5Et*\kdS6ebY4dQq^m#5&qeiXN*+dmYdaNuE?M:EXim4$8Dnc<eDtnbe?>KB9Hu4*eL+8t6D&ShCJh=#
*/SqS& c/Y$lk\T6ZEK@l!w69m9Y$Edy9TLBb/A%$SwJI<<GhL<Nk5y@eZH#%&</pIDM!9/%uid<d9*&CLW6nL9
jikk#W Y*>6m@G:BR/:+dF*&BFTJ@tWi?W/?dF&diG^ecNMk6&m/p6jL<Fp9Su+M/YLjqt:pmJa&!6\Y1=>:YQZ
m%Se&M D914dL6$e4C9a&e4%Y!E8une>DlJ6wwlHWyqm%C#b4Eu!e&pRdGk661aGESlaBMYku@*hiqW=:XhC\Yq
y4YS>E n%jV#<wkHXecG\$&/dJmZ6Thc=9YS#h<Qn$m%kNqmDFZ5L<Y6QwCG:i85*+4XDE/jIJ*NVcula=ED$MX
llY>*J K:hal5?^QQ5ApGX/@Mlh5R$eH^A:YIjRYIj/hP@kVKK>B5F&ZnpVcwk$ZCiJ91bMckeiX4=aGVlmYiFE
t!l@Dn 6!b@yH4lK=y@IwHu%KEdSL^Q$m+wAC#imC8>HduTXn&?By>X>lqIy*I&89n6:?=y@4^@mDj9X/EL!>a&
hn!=6n +MF<IC/<jl/ui?9M@+eiy4$B@Vi\d81nGhdSSDclB>bZC:wAj=54B@8akT1AA^#t=B!LEp&u@!huuyAH
%8D=mA m9EH6+pG!NjDF5DT5mjEaBPCSimZK@\N!WEbla8R=49cjQV%$<j**q=M#Hh9*w8p@@4?^je1dwEbY^T8
I4MMDF /TAtcAb1i@@/&eY^6$EJiGMLIFtI1/q=CaG9:c%j>&9#T&<4tLpkIRmI@SI+!&WheF+ILFy+n:mlL<Rw
Xw$NWh \j&D5@8*D^+>MuMHW!aWCGB+GP64ESN\Z1!kDMLZSFRwnMjCXt=u8#Le%PISYDe%=:D4Ca\^?FJkC9aR
Ccp6>$ 8jh+BZ!MEB@G=\+H&KcB?a1wl9WR\e*K%ju:6A@EjK+Q:LC%dAH:c&qwetn$u%^YQlX8=nRR5\+C>AnQ
D=?W%A Fwb:a/=<Ficdny9P%nBcRpE/Snhh&Y9GFKmH=wi5A$cVhdN@^4:VHLHw=\LHqy4/!X&HK?DD:>y#dF#l
MD1JjP F^6X1+X8X1T\u\PTlC6Rpp>9SccS4khIE<B9=akSjSLMC*A@q#m:/Cp%<NH%CjN9JB4TFMRaF/&FRlpn
@#F=Iw k1lVht1IbalC&FGm>6J%*jcqndFb6XDD^EDd&N*hh1$D9BjEAFk1$MlGehIN<np4i4MN#B\kD=4:yECl
q5w\D8 >*Y6C&V6SJ:DMN9!qQC@WbQNEqX>kVFB\$Q8J+BqiCMeJtWDpn1$+1K?G%d@*MiPBH4%mJW6$$d!XecT
WbmB<8 P/lcRyHG/4+Gw$uADCp<ubd@#LYhZ@AhI^iyPVAGjIc$VTI^E:AlcF@<PDN@Em:/k6mnunYd@jk%dRBC
*h<Piq LMW=E+?leS49/V^ID*:yZd8lQQcFIdqi:VTPYD^NQNT%$$#1>DR@VAlJQ9C?k=wBqLaY^/^8:IbW<B<Q
NP8ekR #y/aPWVu+J/dSnc^XeALEWW/N$41%tQD8p8!T6a1ikEiZJNayndIZBcRGZ:dClap/bpG8T8ChdbhlHLp
+MT*F8 khipkAu=tEqNFeXhEtTWc6VFb5AY&Y6ZNn*6X@:NdKX#^c4&EPVhVcFE!BH?B+L8cARIK$yDyKkZjwuh
waE6T& ^MHF%&GZE$qpKQpd/\p8NGyuq=J&Ya4WN\I/PWNb\eLu1D&GNJplu^E&C9VRm:a\IuR:8nNTBjY8qjP\
:BNNc! KpRApXQGR=WVpHc5Ta$C/<m/KR=^W?#*wpX>%1AiMn@cDXdt:P*4ITAS1$cdPVWceiq$?pT?I>GJVIcX
VQwe9K e>mMbKHMGmMV$+&t5$Ic!nHKAuRY1^CGPIWRlJnbiy5!dMk\dqZFJEC1lR!@GV+/W=Y&mh@i8%hAp@y$
<16/MW &m!dKjdk+iD$%NWWY*pHW@qRZ>Zp:Cjkj8Ny<&wV=5eR49yt##Kt1P8k^NKyc$qMSNWbwjpJHLtu4kwR
ck@Z:X i=X=QQtj+RTtNmj\!k/!$SC5pmEtR$=ADCd8AkJCRCWEtKDJZdeK$R%iWpL\Li1KdBu\bmm58$6EuQX#
HBXJJ\ B4I*ePiqRN!B>d<R>V%@hi@=dCbBn$EPMX4I:G/CWQE6CPX:BwQp9!p=j+/C#46V%P$X!@ISDEW=inwp
+eD?=J 1k!+1a^WS:h#Z/Y\SJ!AZdDMGi$k@NMpR+?K%Ba6HZtIlY8LqK\hTNGWkdFK$w5mXM^ANhYn$ic+L#XC
$El#%4 Cq=TMRtb#K>L%!CE$TlTmTZT/DRk9c6hj4\PmGE$ai\51JX>Id8@n!Pi%u*XieTZ+TBFW/8FDD@WdKE$
*ZJ4=F bT>J^4bElyH+WMaSPRlYqX<A=6bPM%cyKXH*V*JEVchcIX/QE9N#6+*Z5QLRdJ^6a@J59%^%*L*PK^<P
+5ZH4B lDyd4NLb/&*MC%6B!D+=WtY/S6V8bpR&=$R^F=$IcJH!w9wG!%BIWqe^CHTWWIRSkBbC<lEdTZJT#:1L
V\:*$: V&R4MT@&uPH&+F5IVeQq:/YSW9tQdI<=lKTTI*$u?h6FJ/F@/c?JLBB+EyJWw8KKTW4btCn#eSA:B%+H
6DQ6Jp mM<#bT6CC+BQ!R>TN<WwJk\6jJl>w>BKmd&Y8KYCtwnAqeJSe844SC46+5bHpVjKQQb1WA/X!XY#a/k6
8Wth$! EQKH:WZ>i5ah%HASRnY*l?H+HQ+KD1D>V4@alqPWKlw#kTpmY^IBI>yIaSiHqEI<FEW?<wi/1#b19CS/
&JVh// QiCkYjS%pZK&j$91/#ZNE*8ew+=KCbV$AJcj5a/LqH&Rpi\kKF%S%TFH*\C*%p!$WqHNXIDmQ<Wtle9G
y>S^t4 jT?FuZ5$4H9Z:LJ8<qb&SMbN&yc6R4I>i4eFV?pC8iVBlPqdj8RJa+*Cb$M$bhDPVeKy?T6#hhlkVaM?
^mFES? Rjymu9Y6AJP!e4KVcRp@G5d@kjeQ#!aHwAkq5eeG$>L<AK8p?N<9^9@=JV:<p^QbDGu6RaN%*#X#V4XV
mL8kKA &SGPhS>yHVmlcKNqYna/YeC9pV>JZ/AJKKPSBE#MK4hb5XV<Kmhm<HD/a>9&CqjTbKDwR\>46Y6/T:*W
:#a!:9 >1!9^e@G=PJWh?6nq=FW</ceSIybc!tt=mF%dHjAeZJbdaHIGZi\?bi6e:GlRZ:$nV6YPhE>w=k\HZR9
%tXP+n w6>kpcR!m&GjLHN&^PII>twYaElVmVS5S8Ti5lbu5C6>lF1YnS#8LGYH&6ZW9Atqw+%1Eaa*/tA^lYl&
SwDFy5 Sn9&JdRSc>il4#6^F>ENQe4^iA9w%WdS66qLce1eRV+Xc>hQSNDT9Bkq*\JS=L9MB6I//T9Y=dl%NI=Y
b&tCHn KmcKdmTt%QIwWVPyCYl<pS1HhFDc:CQJibXd<NeKHyt>>>$kmbqCDZkWcItyC%X@%bp4kb+=\CH*%im^
e6YhPm p19l1Id/mFuWwPn6^e9b^L\<9*n\naaQ@H^+b1=D%c?h68cTC^>5<84qVA5tSn#?+**X^@@?A6D>KFRe
%k@1!E YPB*mGB1Eh^hKepWp#qyIG9GTuTRRPD1FdPqWqI95IY!na*e1BZ=pKySK%G:R=wG>*ZCV1%XTt>N6&uE
LEdnWR X8ReTn/Wq9pbIc:9&HqKFZbwyj<:q$I+TMjG%SG/lZqEbFCI8KI+b9!:A^q*m!CP++E8enD1@Lk%D=wC
*?GQ%C HjwG!WDu/kGlX4a6%ZkAK%XwAQDmeiP\L!^w9dWGaDHJHBK<JMIqjNlJ$&aV5P:DhDa%JK/nw#DyLHGP
<I6k\M StAlSbjyu5lj1kMS!>=$kl6<+F\q9p<DbD>wGaIMH9Ll4lN5CQMPP6hwEXMnVGJb9=/#<dKRnyl/!hp*
KFJVn/ MMMF=M<iEqm*uJy^?1Dc%K:FL:%9E=<!tnkhpqGG^:9pA8@/n4YciZE4dXSc<>LZ^:IauRa$<q=P*F@/
$dl:X> cN\w!JMBNS4&<EdDDPu/X$#@=4&96CVklC?F&u@iui!uV<\#YCn\RdH/cMB<ec8#^Z6=XYJmIFjHpBJ<
F%c:t< ^L:FZLhHjAFh#?m*LMmn@*VM!*PtN^\>8DD4A5WaPyK5yqkK&VD8%l:n^HywQeID<>SDGbC9yNHDmSt&
:TnW5Q ?Ijk&W+cR<%+Gc@Tq?@KJjJGiD4yV1X+c&d&?uy#nF$yq6NMe8Hd&I$uj*#@J@w^DLqn%LD%FRhV&/JM
tR%B9p q*Ct^YR%n:La6Bwqlq?u89MIZXHwEnM+<qcCYuImpkGXI#l@G9I=En<%H%$Knuq1RkGtjF5tK!y9TQjh
QX<dI9 #D!bQpA6&+6$^$Nlje6WJ=*I:k8EBc\Vp6LkK$6FGTL!dMl1Jn!^R$*iRW@jMStHyF?=1lH?hnJ@>#$H
*Eb4Ja XJ@XtW+WJPdN$#+4&Yjdn@X=8&!=lIZ6%m!w&Pdl5n9VjN=&>MED5u+MGm%aMF9>bkL/Kw9KLlc<GyFC
qBN!S< Aw8W1F&>wi6STEFJHa4V6W+TmL9pndMXpZaGY^P+QkKMt@GMa!mmwd#ISi!b\4P=T&T&^yq:n55u<ukX
\Hwpae KtS<<TS%\JFj5$+cJyqyZGm$D\h*@c=C@qS6VpHb&4h/TyhmFj$56=4*M#ayLuY<\mD5q/66/+Ka6N?B
:aRJKw ii6E!Pa<^qB+8cb^=X\V&WMcKuXqYntha\GqP@CHJM=j?:IH>G99pap>+/ZWdlRL5yp<=EApqRc6=Q51
iPSD$M 4qHjT5Qh#$Gmb<=\jbW<i=TwM*$Sdip$h6!/q9JY@FiKtX^I$6:VkF^*a=j\wCqG/a*&6ctX\R&iDdKa
eSM+A@ yZ:mD?^S85/i95+Ne=$eyd1mhA5LGcHp^ktC<^JMq+G@#=@@\P@tVAhXAFF9uC\l9%d!N%w#*I8k>j5K
^EJ&5c 9RlJNVdQ6NlEHIVcYN<twEtj!VYe\NV6bGV+$?q$XB\QW&=6Rpw:Vny8dI4F1/Sb%@YNbHy!\&VeBA!c
6@6/GA p8wAdWBj1j8w**G*ddCE@DukV&>$cN*m9KS@1eYk8*Vdy49MQBjMt4h?Sqq99+epPTwTHIeM@YJ4j8q#
9B6qik 4W=GP\JbyPtXlVlatIkRENVSQDY%G%5+^M9eW45k\/Mn9jT$\Yepp1<j\WbqdHd\%dhATk=K1e9p\6Q$
A&J%yy KAp:nk44Ech!NeHJtC?>#dq@PmFu1$JKSwi?k?6>!4M8HX*X/h*iNDQ%SHN5SZFBLQ@>&e:?MHQu:qa/
Q5t=N^ DnHtTm5idjnSCLnj&uiKVtJDCS=Vi?waSnESRtpllZ5XM6Xm#D!HqVi%8c>F8<YFL^nbECw?Q/mbna1D
n^89Be p:?NGpIu<E>ZZM*DdY/iyauQ?>a6pL*dGyZIEcNK<^m:M@LaueSJt!kNenRRnV6S!bGGQqX&qhF&/XdR
X6wiSR Zm@1L9eeAlMlJ5%h/:YL!X$8&q:!4T&I^kNBuS@kdA:A46dYNIj@98k4HP%PyaRy>VnlN>%*5$eP$<l6
\RpRiM C?*DHW\uXQaJd6>^!K\XHJ$GpCeD9S9L*w!+1LKt<A<jqG+&/#$NQHHAC1Kq>KMJ6!j=>ZT$/<uE!P*E
Cu#N1b VYJSuDu^JHeq&1$e6=hQp6:wBjn<pN89+4nL6kX%9hJTd!?#THy8$w^yjQm@9RY&e@>L$%^Y<9@BVT<F
y^mX/E a$dbtTciS?^mHANG9bD6a/&tW1/&P!pQDd9#&^6*kl\=^=Y:lWM!MX\%be156$NmN9&WW4qdT^AV1@p8
-AGZV5 000477eb58a00110334 Page 102 of binaries2.zip
ltykGT #LhY\ctJ$Y5LC>ap:dn^#?iJAFE+mbWF&$>pBRjwik6l::bQmwWnJ4cVDnZDiDWE%y$R!u&@mui<yET6
<HRP1h Q8hYH@&u$S*nRSMZi4qVcKb:eC!u<JJ9E&+nKMFii>dpcu@4<j#9&N&/:Vt\:Wb/LQn:Dm#pWeddm<@c
bQE?>d W/cX=6L&mp?nba>a+>a::h:<>8unmZu/SE5V1RG@#E?Gnwq+*8kc#eGhX/huj:p:uY<9?dJ<!#^AYWe8
NJ%A/p wB%/Yn&?JS\WkAh*+pn>aBQ^*P\+5um5&4uL1K\AZLPbhRQtNRH8hQaXh\QeHdS<Qw^lBj*MK+@h&tK%
WKq?SF MS@a@9qM6$d<P4Xh$wBd8$W!DhkLQ8Q^lM=l64X!u\+SR^nhN$4<EcTKNI</E9l!LdS@aMKtSFKme\@M
b9q1#c C8^:pGQKuIL^+>y1d#N%&*h$?WXT@cA$kFCY*1\TD8RyyRQw5VFu*E9ZDVjtPM546DXCkY^#DVWP:iGq
<!h>Eb P!N=lH9E@mmEpj&N&B#5dFiJ+%6JqTVKYZ%:h<H8II/ME/nmnuqKhm/e<h\NR*?/R#a^8eLy<&l#kH4T
lM&1^= TcGp@YP/*qDtFHTp<1KTt$Dyiu+K6NqP^6p/>^9Fm!G?%b?:c4::F:6mCJRC\1:?PY^TA$M4%9H@N/G%
MAMZ:q L=YlX@*p4yuEPGhdVSdVuYSJ@ek=4>:8D%YR8hSZ&%HLAY:tKVW>>4t:hqXwbDS?+i^/H^T@5p<jQH*/
n+LX>? =EmVa<K!jKwpI/849NXCpjtZh%8djy^5il>6S#H\nJ<M@%QNd*@<\*@>C%BLA\RWAAIACADuXY$q*8$q
Nue*ln lYIFAACZBRAAMkAAAGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^qem>4bZq!cY=ue!>EW*B%auJydte8
!/lqS@ eG6!dhN:PNMLHMj^*&bDbFEmJh8m$*FMpW9qM4uW$4TqPS$WYY5a&YSa!LXl+tmme16?e*&WZJ=DtE8E
59dIyG pP8yIb#ePm1!ZHI=bnk+#*PiuuQ/>@9H?=@9/=MC!aAbFLkQK5CA&yPb+/IYiPyDVJNDH+n\X1N5??5b
4#Y=:M tq%eHmHCmK#RCI!wpnun\CeEhSwRStLhFy1qXNKSb5IWp!wn1M4N$i!&%8JhR:<Cdu9QVK=+Xk6MBGjj
C9^!?d NTSILl+SD>cpum::eIkTF#Yby+i%%J*DmQ>W%DSq%LZkHHM!T8B*=E+ByPq^AF#LeqSJNhW%pdT:NqCX
JV\Vt8 i1tK@Pbeu5T1ISp!dQj\A16h\dF&!iJqG*$:h=ycJjNJ*Z*q9V=jV>H?%j!1\/ZD1PQc:Y!N#PSe1cdi
?kjtk6 cYhm\5BwE4G\8p$9%1$uky9c&CtitwlqS1j8yZNuBcQCbtepI6=Y5tm<HpjB:w=5A>qP+6n\Ry<K1E*Z
kahY6H WiqFRYPqi9j!1a:D5*I?Et8pS#EQ8t$NaFcHBRNlFWdhJRN^juqXk<8ZaeH#:iS<p6\Sihw5SM*$RH@Q
jYAAbL Rie+JH4Wm\8ZeV:RcBJ<?Z:99PSSqh>@DPGYD\8SAVpR=Rb#JQ<4P:J?YFB+t^h%4IF5Gjld+QAZd6Yi
9bNeYY !lik>AjNLLL>$4/L6+KW\$y>@h@iiEuM4mtCACXGBKw9m?HnmVJuMlpWG6tZ!pVbEWkwK=w@nWqn$FEu
qKJwi^ 9L!9MkKwXJRq%eiZ=p1npH$*#ul1RBEEEkQkajIKWEAYD6*+Np^YAkwBbLdI+#*%4#!\y4J:lkG\99mC
G&y%1p hRT*5INX81#ubbdty%Q4!\NANnuGq8%p$KBnK?&>p5wp!n:uPSbBZGKAp=6B!a%ka56GK:>TCh@JuLR^
dyE<&L NRaiYXaj#J9E9Hb$D=Dpqe8?R?MEd!iAl&cDAuHF$B+ddq1mh6Rluu&e?QL5j%w94hw*YySY&q:S=&=^
MJ=<ny d#RA^uh%6e8dZ=5hamw1/6lQc6^@4ZWZAPiY*G?p1KCJ$Z$T+/cINmbQ8BT=*p4b>P^l5P===Y1H&H+%
y>eY&@ >&5+9mCDVe:$=&PVd\ynK^!+e&?mt?e%6eIXb11XVt=qSISTCF1C>4X$q/H:Z$^4e8nL%@hLYi4+SYFn
M\#&&h L*lh/!hpK+aZ%:nCE^w45kK=dtt*CdWnRh8I=XwRt^e:pFNbS6#!hBh$w6ZBD9WjbtNTE5>QaaLC!#@k
Hh<u$C q6a>n>*+cYHjQR8P*5SC*YI+S$=a>^\GmA8jp*wT=?#ww<Td&CZT>pYy\kYknL?:YGPIbTe%yw5@>ZnF
H8%&KJ &BA4py5LDWp1M6<&^V>V=mJZ/T$n1t:qaJMlS49wHj8Qa?wdYI#?Zu>/4ka?kKP4yhaW>554l<FZdX9N
6@%*Yn EY\ZR@Sn<bYEiKMYbLbTudSK!BcY6hQAy>dKALZnPnDk>5i%8k14$6hiTN8M//dK&bG&mqp=>E!iGjuJ
/Ln5ZQ iH^Jq#=P4H1MW:mDBFaTGlJ$5EF:j4=#@Ypn#<FCKnuqmNP#?CDtCS6>P#=^MQ$i^VZR/%n<H:k+>+6&
SCCFGY !1FDI/HBP:9#A<#Hh:wuKYXk6i:YW5C9Bd5>#LTd!>cI<T?kyYqGR8eN#%4j<Z\Yh^bFa4n/55k?XNR=
KHHCRe /qW1tWu>HtAQk*<B:\An^d%B1CVdn\Ba@jEJb><mlq?NHIS1?p@hi#w&aRp<5lCmDe:dB*itw%RbHQ^p
i/JyKZ nEjtcjj@Ai::FuAaAkDuw&mbJ+!Le4Z:tb<jI%!/<$ht?wAH19ClTJ6TlLbtZJ\/K\JXXCDy<M<adDbd
Li4L\# Y#eA+\S\CYnuG?Bd^yPGANkRaYaePhjW%nGty<y=j$8juB$eAwADwtXS:HTQ=/y^<bN//nS<^w>y9X:<
LYT/IH G%BLA\RWAAIACADwXY$qtGC6=SD1AADTGkEAMkAAAGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^qem>4
#^&Ndi bZq!cY=ue!>RWHB%auJydte8eG6!:Q%qeF*N$VaKd#Fa#M#M#G\^M$5YM#NaFnNb#NIYM#Nb#M\5m^p5
wt*KGq 69nah*IuibIu1i<:j>+/=&T4XLW&XQj$#DW>QXhQ4=WGpkjPZtZFnk\PiLYbjNF<K::^q/uKC#LMh&5V
Mw45D^ TA$<n&#X?uw:F#y<S$*4n*#XmTEPb^@kc!^QP#@^utu\QiYC@%8S*dMHPhSHJ6eRkWkhY<hX?WI$@>y9
Z>yiAN blB^A/$FZq@NM&Lq8:i>ESXccEFpi%EJL\6+94bpGlAumDJMpqJel/eq1F@Tij8*HEk<AwD9?=>y:ptT
5Sq^XR SeJaV?=:H9#D+M>:85ABL>XhKw5J6/y&P\1BAw<1KA>R%jiA=nceY4L9:1yR?<\!ptY99B\CV@C*9q<T
yCTEBI c+RSL>9ptk*k&^%ku#4H\kSTRZm\:CdJlin/?6*6X=je:I4JbD#DtGpJl9\$S4W&S<jllBGCDDmI!%=M
!B=@6d +tJ+SkkLMZ1k5d@A8E9y4S&N6Z5TCDGBA&IQ**6cSS6udRtX<n#+MR8DqhAKm8#!e\WN!+>nG1dbJF:\
1\ydiS 8MP1WXYA:jL>eW\C*4l1<S/XA:qcIqCycb^/VVHi#tK!dKy6Cy8b!ebtZ4deMi5TWSc/1ym?*:h>jhAZ
Db%%>$ Kn!Fn>E6EnH!BGmV8w&BN%W+XwL$\<*9CnG>wI$bQPj/NTCABqy=W^h*i!h4ItFub*6nT$MZW&emSRqF
CRAI#i IlX:M^h*R!hVItXVG%NDb%MmGXQQGlCReIAMPBI!KPADBPn9+RZ@AAaKAwCFRWIFB4<5iSMqKl$CkJ&H
#kkd<j =YEpD*S6uaTdwNS8q<tX?!ejAVpm=<V5/yw?W=qEiQblMtjlX9uTFnWkB8EA<V<ER9+YtLD!Y%bFP+dM
\MHYZc qQPb4B<CAHkZayp9^q6VVL@1jF1GaLBR5Z&%A5nCk@kiLN8IRE<hFWZ1HpBWW\Yyyj&HLNp@bMH>pnWw
ZS^/ZX MR<BBnw%B@k6$ZnME9@yhPHqnAMA:A<R=A&?HS1j*GjFC>8NaDM5>QpCAK+>QV>F@qm$j8P6Li<#@RF^
i46Jhe =iw5>W6m&m<a5*y9G9?C<cWw4qBhyGQ=@kS4wS1S9WSA+FA%yN@5TZVndLetX8b:Kw:*%ZpKXXDKPK>E
RBXIHJ w:ZTbZ#kLRn@uLqG$dSwED#mqme%e&tYeJ/iAMiHhnBFIN:!l&?1cXN+XNuGD8L+hjS/KDRjm6?#Q+XB
em%EIF *>Sp=19#jk@<\A>Et^e4@=lK@8\%t9/D>BiMyc54bZkkLmhHPjkClm*C@L5C:<ABe*ZkBl6LqGqP<ZC8
n\5@K/ TF+ijLYQ\P5!=QIMh/5&9c%1eKaX$@!!P*1pLe*4F&KI:X4p!T$k4VQe*p^b>?^y=9cD\R?Gl/#NmlL>
QPM/>V TWM^m@1GA<1>ku%TW+GJ%$nZCk+R+#4bDn68M@bB!@eWb=LSCqiCG\bPE@WXaYe4*qSGLeKhWqY\h?he
lcmlhY 6#*=<p5FK+Y+dM&uYk!Vm=PuY\lLH:YMu*!mPjVBMpdQa@VbW\JtBptDu8hhPPqGGK++IXPc>wVjLW6J
9#CHEk u\!jLHeKYt@QtJT#pBlY<nGy#ltWXiMWpTd1$V+EDdb?&i6&qdDpDHHek1AyNCwcy8PD5pW9T&QI6l*i
#&W#Pe ?8/TaALL?B9GlHKG9#A5#WApb!#5bGJnT5Su??5DY!EHe\eGa*6dkj<J*h>D?k8/IKC@\iF>wGMbY!*A
8&hKi& R65AAHcNcStE*DDMkimaXEEKSm:Q:%QKA:L=Md\5%a*qFqw8T!&KF>5PcaNm5j?AY^IaBNI9Ye+@bkb@
DS6GRq !qNuq+PACBcC9a9i4eE\^W4Q#ARb@1mRl&+C/8$uS>VAn:Ym=5L*/pc#wYBX>S5pmIStAL!V8lF5C:lB
9>4t<p %ZARYFu\RqQS/\5NJ<%Rht\EQQpl/8@!A#Np\YC5HD:JGDN@qaWtCh54%*Ca$G?HJu5h%QFwcpZ=Ri4E
L5u+PC D6detDH!NXX&5F>a*5SunNVG:Xh@lAMEj#e6<b5pbyMqG\T=eAa!cLppALm#?HD+kKPiLj=yW^TA6:T=
Fw&&ky S?q>Bel^:\F6>FIja@6Rk1qJKZa#cN*AyQmHpL>Q#WG+wh>>JYQNbyIqbS4W+k$AQy&=!^%?@IpCT$ik
8pycbZ *yCe5ElwPSWPAK+P&*ACICYGH#=*1/cA\VJY1W*X@814XqD+*^QJBApceC?m$R#6C+*yqNi&YCy!A*H$
tR6cB^ 1ILM4hB$bhe1\$Y$CqK5uw>&HC8phnMNNVn&5VT^<pHYJEV1J%^ky?p^=u#8uPLQP/%Q/&:KC9#<$Y8V
l>HXD* ch5c<XwV4!%XLkwDL&+hkRMTVIcVu$jM*6Ej&%@n>IhA!8b$51PBlW+<<#k@85RBt4V:6&G9t9JTc^NE
Cj!NA1 DXq:eXAe%1\&ZQBm?Imj\?4^Q89R^>#jnJB&j@^S1IMXHhP8F6Ym^#ZH>9wbW?NnQn/Y#Ta4MX$n#V9j
D9bZcj hm&%EBb!>Pikaqmu^bB?MP^lKG19$TT+qiTe<tqa^R^R<Vqwj4MCQiGe#M?h+VIp&BS6=Zu/jY4HLB>+
^n4b5* AcCkWP<Pc/bNi%G\?IjFHyLmC5*NScX<GPc%$GRN&Ki/H!jFWW+T5?khdRY/NA5GT=by#+N8&cRV%8Sj
^&!iaH R8K+9Y6NChVtH@D5?X9w\#qah?u&aNQd#$X:BQ8%B/X!?h+iCE&j#luLcJR9@Xj5>FmqFkh&NR!Gnc!h
QNCc!j Cp\Wi>wIHVAR:Z6ENlSF1t49munAhy9<4!ZGq\klAdPKQClANwVJVQhi%K/llTlDRy#d^=>D8ud*Bl>Z
yhMCNJ cBt+5EuBIDd%uw&ANTHEy^TCH5W8Xd#PN?q$?q5d$YZC@ZnqZq^kyJGVLj&Ly\VVEc&PBd*Tk\W\p#Xj
u\q=Ak #=!P+EmDGX8bMLPw:<iQBpMSlTQX@<Rw%t>R@DpDpWHDV\DA?y@dIYhWqGDpqcjl#SImMuL1EmKAHE9N
S*8PWM @Ia\?HBJXS&GJ:lRR8B?>kiWQ^%$mp4cL\e>Nya*au%c<qd96d<^ah9!+Y#ytH4p/ThKIB$Nq9heNEV^
-Aq!dL 00023f4443500110334 Page 103 of binaries2.zip
$PAX:R nRqPuQY%+#p!G>iTWdYPP8X4H@pmTC+P>6c6kdh*4MR4KbjQc:$@w/:c6m?tHPdymGMEbYcVa9uaMXG9
a46>=d @mYyqA\:!MC=^K^KV?cJipcV!JCb/cT&VW*h:mHa#pwK%Pp9B!*M&!J^@\%uYDHDNeBG4LyHR#we:E&R
tAZ5wS *ZScXSwFWd^9!FJHTH+$\VVpLuH^b4:F$htY$X/>ZiGb&\!Hl\<Lm:JmMBVL*tJjiHcmi!VwtFDYnyd%
SVup>? eAM%+V8K!:J1Pd!ALyGR@%Z*KYPq?ji*ah!ICAqKbj&9/ja:MMnWTWT>==NBndpwFL8Qewa%XP\jNBQp
5kIA8@ EpFm5jZA9wG>T@QBek68$N/pYd$N^Ij4Vl+lwwSV$b6A*HGuIbe9jyK&jb>je1MW+PhDhen$TEQE\D1S
hCZVZk 1IR&j/#WeL<Ry1lqXVLmJkl:phA!p!<H4S?m16<c\8lu<SYjB6XK:$C\H^G*9MDXPIPLE*!n=D<^KS1R
=y/A:J *1QW:et4/MiMYWVk1R1Le?L=:cDSScYJ6P^h:e!J?E!5@y%d@nYRj*QLIdmtn:+qQLdjiAHAtFXN4&FK
e\M?cd hHV+e@=B&b<q8E=9?K?AHFFVB!PQC9ej?!:!pC&1N6R/#qJD@#PmaHNI9@@H>d?YCJAnV#bd8>5j:?mP
$dnF?a ApR=R4BhVPAt<RZp8PZEqekD@S>CBqH%5%4\ED\pWn:?W*V!V!+RLS8R+<L$bj5wQScdtK$1B4V9I8&A
NP1W8: M?AVANmm#Jl%&cK*a*HDV#19GNP@W\e><1eL@GZlj%*kd^eIDYmhpl1Iy*C&Cm^%SP:Tk:>dVkWpZZm?
DWm4Rm $u$=4A=FH>K5$%I@V%*?cMLRFdnY?iGybZ1*@+eC9>9N/MZlDFmNtQT:m+jRm8Y*^^Zub/JH/VXn!\86
b#yCW/ ^d64LRFZJyMN\85l<QwyXPakXAEpT*PymY^bH+hSHhDEIAGS^NJ?NJ:b#!qlSlV$NamEmX<Qn:mjhtW?
aAiS=K ZG5^BDIjw^P^tFyI<leVd?bP#eaWnyw$VC#aRd#W1cn55MBpGT^HT@d<BFQkZn:YPXFRJhk5A@%cI@lX
/it!!m y84XBZpc*yan#N!9J>WB4Q&WMjSH?bcQHi*b+I9KB*tci5&\\8NAb^1q$yGXnkecuF!Yu?yIiu>*kd>A
h%>NZ= <TjcpWGLeADA1!iWcdqp=+c!?6FD@1Sk@+ml/q@dtJbq:V+&CPnCY9J18ZjWC^:G>t9P9:yA>pT1?F<8
by+VD6 <Cuh6KMe>YtDF9%NnC9MJ=<4Z4W@Kq&/AX?mJT5YyHnQMydShuIt/>8$kD$m#%PNYGq9\>Bl@qG$yVy=
=p#qSk MPYIJCD:ncl=k<6\%D+X^@i&!B>:TF=49hy:QQ*YdYeSEpA#P+hA6@<IkRWKd=wtFcM4lF4&tRe\aaTD
@Nm^#y Y$6ebJjikH@<!\Yt+uK818h6*VD65Si?W5$JRE%Fk:&SwJIMjde\PPw5$YD=kCAW4w!QaC$EeX\441du
^>JJd9 V*$6@*JPe?8up:yab*F@AaTdnC*!t^T$VcM1!6mN6yt@&XiNQVt5HSCqF\Z:=lnc6ZFi?YW=KhG?w&<Z
PqcFn$ ?%/$kkCehd$>eSVVlBj@8<pbV:EdR9aWq+Iqyte$&:85VucH+ba5HD+++I=DJ5VZM1Jjq/<#<@#M#6h!
a#m&NP hQa!t&1p\@Q#Gl%%aniQ:m&6Q&<9ZwV1a>iy!j&up4Z#+t859TaL>mKF&J=%!CChV&ikX/Ji56uXZ%wQ
1RFQM? wh@8a&KceXShide^kEK8GuJ8d&IZ=c#8/j85>JXeyLjiIltRQRI*qkISHBM6B<=yL8%R9\b:btV8@hh8
8Y^$eh JAaECRACA9mH%@9!?^aATXyeT9!QL$B?@RHi%\AjAdBRWNBRpLDR$NAjaGE@IGAlIeDDI?Cna!BnpSKT
i$De=b p=ERplBV$HI!WqC#WSPVMAp#5*H#CkkIpDPITu*pp?VpF?D>LRRE>5MHBHkEQCRpQF+1Em4i@:>j:>$A
Iln#DY bGlADMADDIREAIwMAwaM<6+QIQ#XVkmRQ%=@tkECCkaPARpFDRQ:+heQGyEAwCBkaKDkaBAR+PC@99Z=
JtaAm5 >V$AHBpClblbGBJX!SCK^BGN^V<8F=yWyLaHZZutB^t4pXMADC\GJla&DnpFJSW%DS5:B!eZN<>HWVF^
<Q@XKZ CWpycSXXNZWNVT%6a^NVM*MLT!6uF%e*h\>Q4<Ck+JDR5QCI?IVEyPTW%LV$9Q!C\1Lmp6K!891G^1dt
+ZBCq+ q6c&*4:?keGl+bHS&du=leYq=bZX:b*h9j&D\/Qnp/94t>8:?+ijn$?@:RIBkIH<?jyj:WL?bSewPDka
1BRB9Y PNS98$BA*Z@@ABpekykbEpXaCe4REbYE^S<cVTR86:aHlySX?Ri/phMMLAab&#d=%Y@V@4D5@#jDA9=9
CHT&Ip Yja*\@=8%!wADk#p%?CBIRMEAa64kaE!Mt9ykIM&iahZb8EydSX^4kJtnl^6*6p>mBEmw@11^ubJGDYn
q#=nAV M*+i%XHHtN$w*Ta&1weK+S$I6&=bH!9NP/AtyL=AWp=#iHFhZHXtBE$FV^B1DC:<phW$H?!CFH@W14Yn
6V1%h! S*+/J=:!HJL!P+BHiDE=FYR*uYwADaTRV#q1JkKK*\Ky=TB8\!m/\DqaKh=!!*8SwN+u5:ekCN>^jhGX
EFVw9L ekR*Bb1:Ha*^n95T1!\?#k&$ZmjAP<jL6j?d=PEq+Y\y&@nl@wTD*5lGX5#$DAbe44#tF#YYailSAb>w
TLZ!G? aj9mCahq\I*&@i1H*RMmHDpEG6qC9IHWe>9Ka^%6?Z#K6D%=D$GZBM&H?\VNmdm=%T^4y*11IaTm>IVA
lNud$E NmkIS6i5?B^6%kq#!/XiW?n#G=BBc$tR1KXetNL!@AkqS#jD1KkItCF6c1<4hWu#dK4<&#^@8KFn?S/k
RRB>&K q$yLEWuui8<H>+SyDa44^@l/%Hl8>6wh*C=/hTTjCYjHaWunE?8yjyq$>VN*Sh&!%%Hu%ulq1W66HJ<&
AS=jZW AHcIXMWl4luyb5P=QJ4JVn:\?JSi#tNQ6X5SR4?=bX*m81IkD91=n&&pphteaI6q1JB?54!kpd*/@G$B
9^TEl^ b55Edwtm5NLiRb!:MEP4I!9eMlXSnA5h#@+?XMD5\Pb#AeHd4XP:qZNddaI/?^chRl4l9w/&:R%4tMtp
ukPJ9* k8\T5/$Dc9SQ$y>!8yFKH%l5hG9+ARh=taW\n#mV#Jq<p>?mXJCd<=wRThtJ&E<JNI$mhJ?WlEIm^F&n
$W$+1u Q#RB\MmtYdlK&GHA%XFc>dwbyZH4YyK4luBL>hp*=8P>5kYTlKRcnHLw$5ka$WGG$R<8Y%e*tkkhd%mG
MH?VLG iih6ia%^c/C5\QBem:C8uiWyuP%h?CpNS?MFeSbc/#%9n\/nMQlQGdDkw48:<iXeuySW:Qe+Q</^:W%a
YKP5bW CE?\ViyaRwG4Z+diNtiL6<SJmtHy^lSXYnGSX$RMRm<Vn16N<C1J1+pyjq6ATbyy=PPJ1qwJLq@P<A:y
uGKuNJ *m/Dy&F=CL<^lt!n6^GBQGcP:%DHTA*Tk>RZ8456>AFXjGnk6Xd?HL!^dFT+!/iKecGNQESThGlSLe&V
VJIi%< Q=pe=ia5S4p6ypZ1dnCQYXit*YKAIA#A?ZK^AHEt94NiR5l$LP&?:+bGQ%:q/M+WSAuX1iI%@T%<N:QC
F\>/=q L!K9d:Nn+E9^=@QyKLX&Jt+!5L8!bdAEqbXl96/mpqSLp9qmMyI4?Rm6@M@b&jPH\Ypj<k*T@V?Y9y=e
\+:kEN QyDNem+i>Pyy5>uM%R1$kP@p%&qP#I=BG&L#D:I144XN1qMK%eaAZT4n4MmYb/J#QhDl%9SYEucKIA<&
pQjF9S wJRIFHa5$@ZcZ?N%a6cJypyL:pAaC594?k6:6#EJFtdYn5jRw>#GlXh:M6aZ=+>d<bJw1JyG#6EiQe<W
\XL^L^ 6B8wkiAAlMBG^q&>K*X%Ly%&NB\1jM?<%DDtCEnHe>py66alpyJAT5&=KL<J4PEl>9FShBk%jS@4#8e?
?SaLe1 1DnNl$*CpQ&^*nehL:e1/RcGT>R!>IcGGMXT6u//8kC8T6+5Gw>Qa?IwVCeclcwe<jp:wpVQT:^!hlcN
R$AMe/ !:NNmbI6h9DTM!BK&pDtGJy%#$FEE8C^mNAILtIKSb5MX5iat=5!JG9EeBC^HbybG!$it:iC+\V5RNP=
5K@jGl mWwMNBA4l9$V<FVbFd*k/+A6piY<nM$iJNuuaRWS^EK>%l?4yS6\!%BA\\E9yE!VB4/SZ1pVk%5myY\u
CmPJ\A YuE>&A5BFS8k4<8NKqu+6p<<6jw6KZyyey>*PuY4aBdcGRu1qNiuFQ?uYZVRJEZp/F:@D+MPWP!thASm
##t!#5 l%ELG/^!+J:Z@qMdpE$pnRB#Y>G$A1MaM#q!XVnaEF5c:kTV<F9D^dctyn96+LP4aV^%ia1S=T$:64Vd
Nk/:%h ^\?&*&HimFjnTPG+11+1AwtXkcWu9Dkn4V>8lb9:?iy<k&/4LGi><+9R%eeQh@*K\ad^V>*qH8Q<>t+Q
K1XTwJ Em*PWA@+I4IuEi6@iCXwunV#5Fph%d1CTSYQab&wL4+qpc+jLhaN5\\!6\5$^tAjCPlKc#d@Gue6IjwK
N<ECwe p5DAY1HlT#&$=6aJ:eXcehj4K4RaCBu?#5/>QP^yymH+hbXLw$jYu^GGB^cy:1B6<5dbC\%te=M@q#9I
D:Yb#8 h9tHFmNP>1Iy*TLW+PIbTTK19l^<L5=I^lj*^Yp5Zw8MDKdp%Wk8!+<:%&:V>Vae+c8h6Ba@C+8yYA@u
+!6%tV NAAb$FXZ8n/MG#DVGS+WuwVRk<b%%M>QD^Vy:SB:1i6##>*J&16!<JnRcGuRGZc9SkGbX:PYPca9\tn?
ZF+hk9 HPMjLZjG<6kM8*#tye#ja64#cdcmhSt6tWyBTSq<iAy1MYuRMEN<*T$ity<cBYMnXQlu^KwH%PaA6/EG
/\1&pF >kBF<1=e+ntRFA1AcBnS%pYF%k+cBTINAa46pJFLmW?V<^HXG&e/#ltdIK?W^C:!hW+E=N/&e<T+i$6J
hTmhRB :S#9MWRkYAyNecH*EB\*Tu&@L1qb:NJjE#q/68\yVk@Q%\Gl5TLKTD9cwV6H8\9M?K4mhk8Wbq#Y+&=C
id>yln K6eHMju^jDN**md=lJCH?TbGGJ%PFlFeGX88ajq=?FYM\l@=PEZANcPQ?DHStPDPc%E*D@X:^JDcM$QN
kR#H>W eJid&EbEy>Zl&Zdw\<<JmVm#T6FS^Z$cNY=FC%KTRq/I5Hm^qJnZE^HimGwTV*PuH%aYBb86dK5uRX^\
a?&+5A XVRkBQkJ>a:1WJB^KYR+WnEDIFBJ*Iu9AA^I@1N!=:!\qW:89Ab%I@Q*qZ@t>JQ$@5dy9$T/>:WRRP!D
MBqw&W %APA#XlC6^!S*8nhpW\nX@+uHEdK>w1AHQ95jY/t$X\tGt=t=h5CMhL*D=5>@*uZnGWD!BELC#?@Qyd>
JIkB^D ^6Zbc4<dLRwuj/EVA5mSFnZhB#tb5<!wQp^a5lFMk\*#C@pq1+Hpw+YVydPLyTtS8I&46cphEb@^Z#@+
8He&J1 N!#C::*R9>kAiRIADwBI\6SP\Sbn91%a4qyF>Gi\h$aA55uLZ?@uMe$q=@ji\+@NVMNRl=Ty@:MNA6tA
E>@c#d dGcLTKS=P#Z%1wYbTFVQkFeDu4aYAHA:Nn6F\ebKlM64uN8Bmn4Iu$1/?/<:j@bEc9BjP@?=:$>>*Z8Z
YL@Xip &<EEi\#F+cjh4JW6I<yyEP4A*5eMKw*8C<CwSMhl!qip19KJE&qLN:YEK?D=nyN&I!F4&ETL/D+CAV@t
=X49Lm p>d\F8bJm*LRF=Ye6P&*jIhpwBc@/6VQkta^>u8dnl?Z>M8clAWSb<69p#b$#kGpMEV%IHE!K/6b&\W8
R:Zu8Y t>kjIt*Q/C\<lqQhJFCI1KHu%>YwIAPDJItT/cba#ZIQ&+c<l<5D%n*hYlAC%Z#Im19k=cnBq/ApZ>#e
I@/Ppw EVh+n!R*9*H8t9%+p8F+FM88%\h@wc/i8jy+*!NaYMuD@X*\k>ZdKCa%PA<jKulj&9Q^LXXEyuPQlH4a
-A&dmB 0004b30b12600110334 Page 104 of binaries2.zip
BWTMD= y#iX\FBK@qu+6N@p=#MEM^t/bn<W6iSZtX65yDmIE/bBwtM9@iDZFJ9!qRR4KlZEyp6ndI\#hEK&ecM/
9DD</K Jl^+WpIVp?X9TLW?AQ^uJ*TLu<9Nd<?nY/aZXVjH*HJJIV#yDPR1#wG&#/m1p!M@P*ZH>^YuHan8n9eC
/Hbu9% ^dhn5PXbZYjwjE=SyI=E+6Ie5=GmHpik*FDBw!&aju#!*Gqi*^*WM@5T//p:LAc=tPdL\#Y5Pp<e=jp^
ZwVJ5Y &yV!Db#q:HCYWD!SwFue9*8dF<\?i^BSJ1WWw<l4k::<i+\XEP5\#/=X^ZCebm%?:w6BX<#A?RbA+S9%
w^9%nP =Eya=Mj=%d6!LmwR?@Gp^R6b>EcF:%?<aaMJh1y5TQ@K4YQ>FX/@pQGQWP*>A5lE6IDV*G%TiAbh!dZu
F?$6T# idi5$=/!NAIA=&BatqI<A5l%cL$J1>9MlZ@1uT9?!aHt58<lk\NiSNPwhul/P>I?j9Zj/k9W//VJjAbI
eHY$<Y yJI@5J#BI>\18u8$CWnCL<>L\6KS:l%L&mLK#c/4MlwMER<i&&BSJX#5%I4AD%KV%dw%kpGB:VN*QZw<
KcXaFH VZtYB1jXWyA$$A>aGjyVHJhbP&=ulYl*DhA9Jww=S/T%c<kpJkyNy=999>\9nAGA:/!<4uM?yqmlYIXY
MQl8B\ ?RnNKhq69clkd@!MH=/leD?hY=wacRp$^%=/+L@AeZD/mtD@aEy8t**yVXM$y?6KV\1c:YPaF?9Y*d+#
P&AEp5 Pp\hYZDLA<c86#=kVad=+i!BTH>l=WidaCwWEG*Q#M*68WEK^<E6CGRSuRKkLT!LIu65NV@YSVH&pPHX
aM!&tp SIEuu$RdEW>AyN%BP*F&S^hLk4%LPHlYeR\e$NL#=$6X+<9qq+myWcLNiDPnD6::SD1ZnlNw!Z%KmH?h
C+N4b# Aewk=Iiq>iFe&XWVcGCBlHHN&hkLHN<nAw&N?HEMiFcXM\GE/88YHZikPn<eItciV@dMK?<8*1Q$Dhy1
qP!KI= VYFMh?IiF^nt<Vdi/e\X1A?+LH96HRyh6+tBI4<JkQFQ:\AAQM:@I\tA4@<qAQ:jRkDeY%Hq?eH?@yiP
JGBQ$B PDuByZX4cZGI1%c&utl<B+VX+:ac#Z*V9E?Ep^BWpt4H^F1@1P1RKhBcj<&&:pjk&j*cycJYeJWhFl*e
MA+p<h !8KXyA?%a>&@?4yS>+u:n6>!>*N=I6E#5w^!Ji4!>!E9N98Gn6ANeVELHa>a/dak!bT+1HeADN?d&ude
PVI*?V /BZuJiKY%a6&9=JV?P&RFV5?eMwqakj:bq?/P9ame#=yF&PV6mZENJ+*HN*@BQGtY8dHbZmqc\5/b*C4
u4n/AS $k*^4u6L45DiKMaCd1KTtFK1plkc+C@@^F8KWKSZNCiTu^t8^B%MDHSiy!Z8TD1$JiIi#@XLh#1X9@i:
XL!^NG Z%pmRcu/y//*:6LGZej&\?:hdjC5M1FAB^qKaFY5J$$tTe6#enNJYmYb^pu&5N*:HZ\qJRdyA6N\MS*6
?dJ$AF KVVddmpK:V=X*&%pmd1YK4G#JcCLb=bJR>5t1^IlJ*1w%GNXTh<$>hmuGuYC=1hFR$%Q^5dG5n&X!!M=
J\XIN< t:L:eSq6e\e8a*&59upKq5KF?QNyTYWy:lQQ+!#L99@wNd^ZTy?et/*+4Dh&kjp#T/ueENeI>?FeIVSb
>>w?u? \kL?BJ1T4F>iBBYk=NDwK!>IQN1Yc8KTMJqNcD+wFdkui&KIhj8#u*MKVN^=9G?YcyeKJhtNN5e>a*:l
tymR59 R8WWm$@8%RY@Xeh+XF@Ed5bD4Ftm9S#i<\4i:T6%*yk9lEhqjp&P%Th/=8ABBnhBw\n%yq\$&QmuXeyt
ndbML> QyPFcm4@VJ!RLWL!5HQqkk9X9ES=Dw?ZX8uuPcXcbZ$Pe@6KIZl*?qkedbd4pY@MYPB+T>a@iy@Q>ItT
Pi&5>n X+bBD@ldy^!H1!D$R4tQhd=kbY>bM%Y&dQBFwj88WHcCchej\XJDP4A8SymbtueFp*=9Mcw%8#L6eCjR
p1hlk1 *%=5cc@GIF%FC:>&%HX=!4#p>nt5JB8<=d?iW\p=BqFHq>G+Ep8PEe1kW^D16B/:6WidAQhqJcAJKc?e
*+mA4F KQ$Pbh>Y*EpdEyS?Geq\$Wl6em&T/?!uaDNu/+41FqT66McPWF#p&VS>Aml=FmFMiG:ltlD5<#K&#*cH
Iw#e8V GqNd=V1^^1bcQe\XX?PiQSyt1LyI@ByIGK$c<*TeA&pK:4&auG<*1YQtPCW>JwQ8841C6=h>K=Hew!au
^cA=+? I&/4biZP9G%H8qu<M>mtAHp<VTZJ:t=1idtDm%qTn\h44hNqEdqM4MdA8NFRiiVIXiuAcycd*%*!&9h#
6u4V/e cJWVLSm+S9HG5ylVB4qi>^K@aJD^Da!YyLKZq@4<TbYi9QT!Jjh#&F+wH<:1n+tq=eb&uRDkw^MpWccn
DaXM<& 61KFt@4XMAPSt?\=C?4we<SlqIJqCS@&tQmimZy6TcFLnPhMEm&*1+B@*XJF6SD!cP8R:I\?ytuq?9J*
i&EXCt KA*d@JIJhP*WI@W=yBF1KDJq1:k\TlCQCXee\XB>h41^pVICwluKG$/TlAmGKk*c&mt!AT<en=cik!TZ
j+S\%J Nd@9LHHKVbuQmYZ^\9pmKPci^pX4C9p4dN&PTJTWALZI%J*t!GF@pbLV=1n$R\b&4W4qYR=\mJ=XCi*c
nG<H%# %^1$i8pX1E4H5hTHpqEaSlFQW4FJIaLd9dwAWalE#lb$dVtuTVXttmdJ:8FV6e4L@V4H%u45X^yq$%dl
J<^!nQ nB4N6Z+u+EHFALVEa@568<n1G*ia1hW*B4Awh@VEDFySH9Q4bcwBMSi\=YEyw6%GqLejAhTtam/c1Tle
iZdH!K qJDSeS?$5Dt<B+J:55ID!Mu5?QCehVYVDn86R@j1Mc!P?ZT16h5cp\JD%u$>NQKiEdX:RybH:E#EAdBu
51h\e9 ?dkW*%YtB8cX4bmQQ6KFh&\bSaSZFp^Xw5<aV@KQDk+aB$GB5T5w#!&Kd+HT<6mn$VkWW!VV8?kmYKiQ
NKB1ki u^&It?Wd+>HI#?mPjjjW$BHcbb<:%iDh59&Y%L%Ph/B8Y:qaSX%HVlah4d*NAMeRTC+MtS8*$!yW55WT
ieSSC< I:!LuwSZSAqQ!<E/VNKtTiI*kHi/j&HcB*ZW>&Iy=ZSlK/<@$+=hK^:tyK6TSSFG!e1+1%G\*C+!AG6k
=$5>&l EP>8XwdLJZQ=8SYA+KZ1#FC$ZmenTyHmM4NiFmA6KH%MuQK\ab$SShWGB\ZcSG?/LwMVZu/m^5%Yah9:
y>JPYV ETh<aj>tuZpRAaIF8/pKTtXA9@qVC6cy:upY5:d86WN4ku&um:wjibleQu6:\a8kb*m!FCVMML4XR??e
?LuA5n Nmmcw*=RS8&P/L=mthRNEWqE4dPlI%/RdX=^Ymmd?l/we1mnpaYi$5!*n\M&M66N%%IH4a>u/b5mjk?X
J6cL6I cKI4JW9ujFa<T<IF^?wQmmEiQXPN#q/&ChJ>#w=/A@qD%lae>?lTt9Ic6Fb6<HuHhV\/+yI1I?l>1@u4
u#VIRP Ypt/ISKpMR6#y%?wJLe6YJem>5?4B61@4bhpHKmw5K&!=e$t=&QkSm<dPhD$1Hj4J:Jj<KV:Z*=$%6K1
FyGW/% 4$>u%ppARC%YDjD$?\5jhlw&46AQWXVw5QJiWFLiw4QEBBVV%ljW?W#Fi%TYTK+D+hK:c\#!&S8Lp?Qq
%epMSn N8>G/KhEiDHy1!@YhPQJ8ST@8:YXB$6XlL5?%my1HmiQpiwny?GYqyIdE#9\GHXK69hjtiJKdleqd:l!
bP^9Kn SAk^y>Qm>m6ZN4W+LS>EDJRnm46KV:Cu&dmmn?ph*c^QV1ch/8h\^PJlDCk/RCnPNe!:&jk9NtmI&!hq
qRdFh^ i&LpiF4%BWb<n*CS$c9D\>PR1LC<?klnt??9d%t8Q@pk99thLCGGbtEFaZl1!ek:Yp^=R#d1EERnM@&$
AS&*JC k*$:SAXQk>m5=VJG%PAP:Ct>6PBaYiTEM:VN6/M9l<:L^*1&Ab?Bu&WeA<D4T6GGyw1?E9l=e9ktF88a
wYWjDT S#:ye/$amJBGjNC81&M%nCh5pTSB$5pZ58c*tdTiIMuC<FWJ/h&mtjn%YqXV?t:5CXMc=R%<&Aa&Pd^4
KRETWA uZM8\WJL4i:JdcH!?!i$?t@wu@BQm&y?qI5CW!VDV*RT6MyRE^/m9>SCX:5:bijpT:EbQKc?A@!YQlaj
GM=Zh% ^RN^<ZWIk!$$n^cSTqDGb=6dh/<4QTy5A>:&X!Ti+TNc6+>%nA!nK4L*cdYcQ=L><l*=Tbh!mHW5+>:1
=cIabY \IbwjBMc:BSBDpl4#Q//D=wappNQe*=RqR^1/BcS1>!<\#8N@PDYdTM4e*#y6C$@:qQ&^TtVHCat$Cwp
GNmt9e tB5=y=AJGuNMQ@TSwnDSDF#pR!S/F@JKhB15@^\h^CB%NhtLJwX<R9:b4C^n:XVlcRjlXGNycRW^Qyc&
$l%LZN 6<jw1LE@V@@!<a5h8c#P!58RaL<*:M4$db<ue%id4nm*+5a:+GqlTblB*<^an=%BiTupqyFE5FEZ1P\y
+a1D>G mtjWdBK?$w!cmI?JV<84hEXjqHQNPLpdyeH89eN:ipmMc?P=lWB#V5&d=q&4#tBqNeM<MY?h*Ru#Tp58
yXmdDR /nT!*+M48%9P+VY45/!4%!=Fc/8$EC854L?^hu#%tn=@#nWiV=DZXJ5%>nWX1K\*u@y&+/It5NtAL#VK
i%*NYP KR/6*@>R>YXW!nZ<=*Bn%Bdam<V<\8NFQ6Sa=MHcRttBnFtt^kX8eutNXXZ$%@Wq4qD<S%J&quGSKALL
T/BEpG Bym5<=ljI\qCJHlVn4L&pRqWe1HGmaWHb=iP$qX^K<j1lJ:^kac8W\G:!m4^9I\#/DKjMSmYCSIC4WEh
NBYZPN M9Sj!Kn!wwK@HRjBmcF!$I<?KG*8BPTI91TGN8+5PIh^IL@1BJq*lh&nAADAF4=J9N/6EKPM\Qu+hk>Q
>5dp:y 6LCEn%V@tem=W\aAb>quHTGLK#C6GKL6hy*dYWiSk/\B\MuGPp<CyXIwXJ/Rk\H$L\*K@6dy9<pwjEXD
FWKREt X^5mERamcZ5LP&h:P!I?B/N@i=4q%=d<Z=1j+k#I?i\&5l1K/EN*HXE#X:!V*lK+mwIFAJbP:\hmDX<H
6NkDjw c$66T&M>^@W#5#k/@Y+?CDwaBBN4Cb5S@NicML1WDZMREC5j1Dh/DR>Q#6Fed6dGlj%NcHM18LSP8eya
BJJlEa bMM%1MlL:!&q$t*cc>/nCmlT*ZV8?Gwt#8!6ia:!+:Qn%^>9KJ/ANJn^KqjMb9j^+&QP/9i4BYq5^y^R
cF?yd^ $G$hl^<%C8VQFKJ9<tT9YyA@XXeQQ&lhlu!Bi^\u+c9ty>/5WLMJ^CLAN4QN#dc8anS4ncL6k<49MZII
6j>%>J B&I?N8tZV?%8=$Iae<S?Y<6yB^baD/&E/y9qPCYPLKwdYi9\^A/PmK/PFMjkn>dMwu:c8KhaBk8E4ClA
:uiJBp C%N+lX>qt%hRR1I5KSdRW?$@49MP&EIcb!N!LbT>l^qbNy@/?cc/Ppb+KD&9Xm?$$J8c+YJS>J@QJ!d:
4Y$mb9 A*LEL161u1iA:S6\:p5TP*CBKqba1RBkiB?d#1Fb@bA9W/Rcwq6TWcIPyNPjl*N!&jj@i#nun@PJ4:li
uTJ>*/ 4ABK\/iD#>JwmNR9KcnIQli9hAI4FbAB$PD#6G$*S&t^!1t:?m?5%e6^e??V:BNTFdi:p8q!MHuF#9ID
P!@@b+ F!By+Zec&V@B1y?%XGZ^8&$1TPa&ZjdVejXPQB%jl#TK9&4KiEmj\c++j\d5JNi#T@KjYe6ujDilQE>e
Pq!Wn6 n5<u$yPG5F&nXDPbJS$CtCnkNq9yZb!wYpyb#ttX%cWwRDh*mX&j/*?!a^jhkA8+>ml$\#iq@P:wqPiE
ca5^J5 e\Vuk*N^QyjQHB5nJuD8pe*cH*5JS5MnnL/wMGt6wS@9QhGCYZ>@%YmH6IbV=$AaClJ\C$p&Hat8D/%n
T#NHk% Zh:$%L^E4#&==elH<\*n:+h#jwHm#<tLDBwAB<nt@nKij^iH!+j?XynLQmIb4l&cQkQIpj9b6PuRDtXW
-Aw:Y: 000893f852b00110334 Page 105 of binaries2.zip
AVkpEb ^:cJAX+H<wKj/69^J#eZRNYDDA/awkR4:#9a1Qi%6<P@\JFQa&eapV5$hNpK$bM=+:quqLN+XNi$n#Q&
5HB^8i N+hHVP+Y\=?MGqP4MQcBk+cWd@4y\^KNqybW:ElX?ATNENldiR^&%GDQDZ=S?I/P9a:u?LTFLpDC4dt4
a@Ft91 pk/qLBG=:#bkS#RC+@^AFpt$d=<<XcZwlLBeK\aA9kN?9wMyL9Q55p\NJLZjEZGpBaiC9RtpVCFY6>DQ
6XV6Pe BtuSZ+bkD=cbe!8bGpQj6=?ny5MMPZJFWC4IEc#BJ+cmt@^wQDbWj:kC?:#Z?@=>Sj$4:IheI*wLLcnq
HBbe=j /D4VlNd8J^TMlM%IpyEuWpFqS%1wRV!#mP/JDlyNS?kakFlqZbR@mT/<GQXh/B8ub?#Qm>dkS?LESZSi
*pNnuj NHBAP%!=Z*8<bA9^!t%1*iwQGT&M$LMNFY$:cZmn@THe!F1\hqyXHjS$>$t?>VW+k9pNlK>H!jN#V8uX
:FQ/H5 */pMuQmG^hX9XP9ZATF$e4i<:BK$q?DK\cWNe=:Vi$!KLi?=R&wh=!6l&814^y9Yp5hjQ:h@H1%XLhkl
^m16Iy ta&<eVyRAbnI1G#<\e&h@PdtC9@L#j&Zt@5@!e%X&=jG#d?^F$MYPHAQX%p^&:y\cp*Xhl%t=P^beKJ1
$kk&cL e/!wjZ&?4aJCt\!cuMYhjSZM$6dTKw>yYpkp$K:T>ckdp@PVe6yLiFDmy6i/=q*BhHF=#5EiMNQ*!JCd
1^bQQl !+1@PEhPKd5VqL/y>B=MTY>QdGc$68Nc4S##Vn<pMHPuP>PKXS/mcCMP6h<^a!q4I<lm:N>kwTDBamDH
RS*V6R *w%T6d:mqI8:I1?+11/G:Bmn4CTtcH41kH86mFX=B\V%mdRVjekL:9wYyH1Pw!6P:n?4PTY8E1e9p/B?
6IJ9a8 ^m/#\TF$u+JIYBb+uXNT+tH>tc=Ry@YIXcjtZHYVBXFaaic#DGRhSMMJej5R&M>Q^=ju/ucGNA9BtZyy
q<#9LJ nZMc+1KS?!nhu+6Ldp8?L%cNRmkqIGj/k4#Tmk+VP=?LpRWy1W9Bm1G?LCce&%>\RqbKXPnyMCc+a<WL
*LuDL4 TtCny!yt9##6bJNuGhPM+@6k1Vm&JNSc9h$Q$He<t=6<#aTPJd&ye64b$WtDm&itdG=W+EdwN4+8mdIT
@/+GDC k9Z/$qlBqChc/ITZccA!T?E<Y:XmiiCPG+LJNXKXI@:nCi$:C!nI/GGuVqIApyMd>=k6mTZ>yqGwXR#4
Dk#RZy b8n5By!X!5EZlby1WX5/KVm*E#?+@bdTV*&Y^FBan%LDh^Y6K@NHyKQbK^**amw>A/T4I*njhKnliDYK
n4aSit i:c^pnZm<kp>nGNc<qX?XDnyChPA6P/N:Db:XVpLGuktIp6VRLKw#i<SlLI9cy?wdPnECyIaeL<D4Ded
tmc<PM &RZl/S8u$5A@pVwlFnyd\k>pX+N!CdIG\!waYXEpV4icR8*yJb5@qFZVEnT8/*uwuk<QKWn*6W>u$%*y
pR>$>C Z1ZVD&VPTa</b9M1cS#PlR&VSC^Iac?p6S/m^VnmEqwSltN=wW4NI=@RmkyLXt$4D>maS4twRTWw^u@e
i#ceQu uT*WMC4WmJkQ6Ji=NtqSX?RkQmT6hFjQMQjZR@Zn18cyhec4Lh$!#>Rw6IT4Z/NYFNth4W>9ZSBid4XG
dhih&* =F85+PlueE\9^\IJkdCRICq#5pLlTA^=lGZ^utel&eYc=FFh8%=Z$XLR#pY#!>iIlZDY%am\ShN=QQGV
&1QN/H \5AmLHS*F6htnXpa6@:lt!>\EaTnJ*wZ!eQQ+h+&i%:\FcBQ#9hK\:5GSyIN6c@tIkW#c/6D*8WC6c>>
5L+ue< XXjVA/>Ln^LD1DmZBeN4WhX$1TA%@SWi:VH>A\E#I$54@9Kew=\WYKdZjEC:9DPNP/nb%6&^muAcdJSS
=95bT1 =\jSH&yB1#a5i6*%Wp/eJuja^^GnT=?SX8u5*c%y=i^+!u&P*l4#+yV#h1yWjm^t55MLK/8V5P*Z#m<X
kVyYJ< >wdDGbI1q8Z:$W/?pBLlSPSq^uNZT+S@LKI^dY%pDM4%L8M9y*Q:\VddBh^T5@nW4+JKl&ST?<aBkF%@
kdAA!i JqPZP1\bPW$9SA\u#dc9Z!ZFJI66H=VwbKM?LWXe/%C!/ldI5h66Xb?\$hLdqGh%lS$/kuBcjCPd6/<i
in:GJA @&S&QT&\#4#*jKWZ*BaEGF*l9^Id#Dh%wk%jBK^\:dVRY%l44<?K&adbDq$SRLl<w$kK:6iZI5dcDudY
4RK*dp ZunLNR!4YKAIV^G\GD/eR\8RpbQ/VF!mi*\j4/p9%V/cGCT\5CL5F8?uhn4/Dtk54t>l%lZCXykaktP>
H1e4n^ %Gum&YQ\4:#A1nuFhil6ySG:+cB16CcISB>pd5pbnhm4=NP\jnD>88e/#Kip6SL:eY#d^SN!ET1>BeJE
XK:TVX =+4HPMd/E?t<^8ipGJMLL@QA16qu&adNba:eyNC=+tPh6t>bl&5$eZGPZ:69B#!:klydZMdtIPdPA*^*
bI+HTw #!w9#@Yn:idY%&kK%#!6HtH:mGKNSbbQDk+pd@RkF&\?1>HZ@TAqA#uZP?@IaeI@lV\b^HI>LqwJX*6/
y^pplA X8<5N/&nMm/11LDNk&q^dDHPLaatCwcFV1R?d<y96p@$Ytl5<6S\<!kKNb$HJuQp&b:mqN/BF4WRcKkM
Q%#qBW pQhBb\B8%Bnl/8XJN@!An1iTBSHytTRuK:%N8p/$VN1Sa<^p=9^yQ6BX@uRwpnw&pb*mZk8TFXGeF^wk
i1@E59 J4EMWLL*dBF8ZQV/+=&d5wa^VFbJd>E+wuW4>cGEuqLHiw#lcD%8FYFa&e!b/u#Zw\c?/<d:kkM!KV1b
<i?Ykb 4wS$/hVHe?QEFH9%#u+dVqSFFljuS4=8tyBEtVQ1eWHb^i!kF&ta@A4cC<?W4?!CTYa/9pQn9pw/56%K
eCSlWn @KQ?!yIe9tMm94BHdILaJ?uKH<$Q!Jy/ct?16KB11:/a4<?Q:^VmWC\P=Z?jNJqjNLMJ@<4E:nWVA<BL
&%u:aA Q#B85+:tGDX\W1G^>yXNbWKd&DtdnFpJp>$66NJbS$XFFNbCMlmK8y@RduK8HZS\T:i\Zc<c%*j/TWuw
^<5eX1 quS?&EL1WHa6\\X48\8HiYqi?1RY/TM?uI6y:aIAKZV*R9Z^<%yi%l+tiV4ZGMXMu#y=%NK$FWQWPjYk
9?qXy+ 9L!%$>P#6NGa8cW#da!\p$lPqb##9jKaheqpQ$%Fb6Lb6>+R&Pjq*N$Q*?8@h:8FpLMG/n=duY$F+q\Z
<Pi%XF jEq!H?T$hK$$ap&KB8#WYBdtDml6!nac8>>V<iYGap>K=yW41Su#ymum/WywK%BaM=BtBD$6^4A+kA^X
P&tRPX $bm*FuDkiLIh#jQqImy:K$K^dYq#wyJeEBuEKtuQFBYY5%R1Dat/6JHJ&/^CkRNYqCYW#uW+%m4JeENH
8K48w< 4YuFFn+y6+VL/85/>yIKb:ieYJhnGEuYSq%y!a@KD/p^tIN9:tjIbJaM5ijcP?T&j&GjbFE\YhFNtqKR
eTHE:Y #uJF/wa:6@hK$MtCl1&RHKLIXQZbF#QYcq1Neuw:D%M@%$B4h<TG<!pNq<^%1dPulFuKZBVQ^<uDBkHj
Vcl&:E cV+MPtR^#q/y<6cG5j*R#kEJe!1X#1%H+P4ybNKXFu:wtW5GYV1/68@?hwM1$1yhH=\9=ESX^8kk?yuA
DW:a5E wmnM:LMEA4#PVhkd+&KbCFdLKw8%PNZNR&@CeR^N1&/&@*liI*pDSL/=<StNIpe/1ZI^8QG$!w4*pkuy
Kc5\EZ GC+ic\ydqh+5k@4wK=tS1Pl&b?jyuE*ECE=hnWEjWW^IS=EAh%Yp!BX+t!dTKF^!\T&?<RQl61b/41<Z
\Zk9!4 yV+8T9/FkuFd<nyQ>q&Tc#H#=M^Ww?&cA9^Gt\J+JJ$hC:aeC1X8:GDLqNCi1SVR6y<qdnwmth@4aEPw
Y9n9h= Y@Bn^FGWI+jcky!^6Zy!$$\!e6WPF:yW@N!S!TiQ8t%TM%H\\NQ$@V6<w$9XHR%m^B@XZt8Seyn1uL^L
4$1!CY BakMQ6BH%tpl:Ka$R@A^6HtbcHED&kX==$=kKDdpW8!kkP$HQF65hB?TD^SLk6T:X!Z/K/w%WTdbk+Y#
>DRame <SDchHq>:6NKKk%m+uAtZ>lW>RhY>/dZKn/CPG1RNpew?R*w1qJViKXu&F*D9qV\Lu$&Tl:Kwib5Ya!R
wS:9Bq ZIQnSBmujwqVl6GDyJCN9aT%ku6CZ1&acJ/**FyInTZ+FhLGRAm\9yCYFqFaHjMMdMaKQJ8N!*:^mBX@
tJQ:^W B=\81ZBG/5QH8la1\CuM*MVVl4BAD@Q1BQdkLTaZ:pSPKC>TMcn5BVpG>Rl1D:waW#y:iWS<na:dFFji
huTE5l Re9i/JMkGt&8ND=J4yNKhy5!wPu!c&#ucH$d:W4Kp%K+IPTDjD6?Y54nTDK$#RmJGncC1D5pMq=6&bed
i^J!%t XPjuYw4Kh@bd1P!1=cNuVG%y@RbKy4@Np:=V*KACY@PwC+ju\6//A&@u+/=m8a>4LKJPll@/e%G5Q/h6
uci*Rn GZG^QShBe@ucT5$=l%twbLKdW&WZFH<k<byLIIpP&jmA:bm\mWiqy4WNZR8<hR8H^tP/in\!mX>n:qlM
H#NPiC kea:Y1w!:X>w\pw+8d>Znb*$+kYAbVYSMkB!4JM4Ca8Qnk\jqEZL%VmjX!R><NMBPcc8@T5IER1%8h6N
^ae+D& @64h=!miKMkY@=ptyJ$GAJNYiAiVn%h%#:dmWdib^:PPtq6%AeD^V%tQ^JL?tp^D?#V9WZ:T9apD9?9R
Wb$Fan G*CqVe*MmCRNub^MdY!I?K^?9j6*JGGP/Lh@cV!METALmhPN6YNw8G>4d184&we+K4eK1\RAHE/ZDpQw
mqWM\! nuLWb:WS#9yC&\W6THj&>$4pHDEph?mEeeqWn\$REFwm5Hj>?K<JZFDhd8JChKYJX=WQ++Tw1tTXZ@I!
6PqGQh 8jRK6tVWi<YXbtCbBahHa\=Zw>=%R6SS%5!4iwlD/>QZ4VR!nTa1$e+um5iX:JYuG/@PHMh8hMQ>lP!a
KFQctC ZnXYAVbZ8Ym?tuFIwlX8W#h1LeNdc&PnZZG$NDtXj1?JAumIk8bJwTTm#u?9SM:SAQ/>Eyp#B\CM\9<!
V=pK?A Tkj4$#^Y>c1qd<DiGP&%%\@Ieji<WT5Ga9<5^=JtdqdlmZtqH9#?h!HhaYb/<:9>JB<dPbBBaSIA/YA$
I5wd64 kcVlI#wGN>q$+%V^6jwjRhq9ADq/VtaSIYDyRjkRqkl1R%==DN@aD@<8yIjmKnQKHh%K<@WFGXVXBRD$
KiwAQ8 m:dJedwyeY8Xm/m!RbbRd$BwnkZpGL<:Z5bh^>5mh?4i%BILu&hm/y*@ZWl:jZCqDqw!HtYVFVJwNAkA
P#t$TF &K<?G/M8pIm!E1GX\b&bV6ThlI$MAD:mb8:bT8!nL^WI6CD:j??FL=kd?e@E=WR^ALkV\VX:5\mlR/c$
I\jdqR \yaZ=X\!AKBBBAD*?WYLQnC:b:8CQq!#aWd:Y=h1C@*GG8H@lnWuT#e:W=j@DY<l+Hu@kniR&X?>ECeL
4dMt@G Y9JIud*6^6bJNh%&FZ%RR\5ADlZ1B*Ry6mC%C5p%^w=J>jRHMy#>P/W8F1aYlm/t@:9T&u>S19pVpE$#
1qVK%5 VipII?+KQehm^+!yWZ?WmDqpARCGkdldSdZPlV@Zb#cqd>b66uj&Qj=YT91@KLY^hHT%NLE%hVG$?h<X
Ea/QY/ >@&LatSZRCb5KkWp19/p+GGiu!*T>!@XZ/iAa\Bkhm/JHS9FEh#G^GQaNqMWlqj\Ehtj*HAAXe>@8iG@
jQG\P9 %K/:dI=m@9SN#kw#\jw&pTNhlQPkEXa+6>5^nYCWYwiiHcmFp:DS6KLn\8/M#B4/$8Mi==*H@/HBj5/#
#9#mIj 4TJSYaT^JE8@8@@X%d\dTWV*:cdqpP/l:qqu\^K^4c@n@BCtYm1yj/1IAy6MiehNw14a5!Dcuj%hM6QG
mV<mkq Z&BeJM\bDK\Zn4hKwq5ZA6@eNH%ht%T!WHKR<ulJ5X&MN@jA<#WZ%k!Fic^wMWyPRF6F@khN/F6ki!Ll
-A?$n: 0009f663b3c00110334 Page 106 of binaries2.zip
:&BAEV S>AE*JHtyTPj%StSp5?wVE#bG>IRmnq<KYlT&Inuna#N^T9HA6&p8/I6cC1&K6XV4h4dhWewJtab#K4m
n$wtbG 5AyTYAqR?G6Y$^QkE<YwCjHplu@ulu?B+t?wAq&5AAD>\#/+&Rc&hI/LCSym*:8>Ni:W4\C!Gc6X++IR
K6=WD< GGP/%+8C>qVtHE@Z#HD?!k&#adq/I@?KF5QZA>&nS+/SuDR<=L/B&Yt\XJ%wX^i?jqqcCXdA^BlDH%4C
K8L+\k m<+VYlSTk#/FGRnuPyNi?KDy1qV6*u?q^#a\%y*?F9%/BB/TuRt*BZjEIl\@&ebaFTW9dwKDLkKiF*R\
8y:FX6 1DWY<?VB?wPEX8%V&FcLBpNX9!YF?#4tC>iAFA/6#\p#AQk8YT=>9t>8\K/i8u@iFKTVNb9KC9c8LB58
ele=ae =N4TSXiV/M4PPEE<^*$8D?=yR9t6yW$=LPC%t<tn:m9ZN>j%DKp*PbG!X<nLZ54yRu5#6h9cjup8mm9T
WeE$*M b<n9k>hl/?9RJ^$Ep!M@^c<WS^Gl9>/iweZ:yby*XYSyQ$Vy+NDek<W/l546CH^ni1?JSjCjPMl$Z\>E
/??A>$ *NZ5SM5Ai\bjD!KKKtTYb<VK+*\%l^kybw&I\=!@+ePF/Q^mTHt&qW/mEd&LE?b>hbci$XnIPX8WHTcT
ch\K/C 5&+ZuG6&FGPp!>TCq99^^#%?cj$N6hG$iT<^>8#q!:ZV^Blyypjm!kj4be^^dBj\HI9N4%%w+>/kKh>u
=lQKCF Hm?IZyCL1bNmykmiC/$8pH@Z4yNKGNya&yncE/ua&>k:iSuc&SQ^tj@qw@?=4E9@/Zl?D?9jHM?eWTL^
temXt! 6?pkDBWdRIy<S\E$JEqhPcuC/!k6I^SH+jpJIJ6bMZj@pq*M:dq8&4@\+T^I#FAR/#?HJI1iAGC%=b:!
RR\NGN TnJhm$161Rec@\^4G4lFB\DaK%>%GEQjQn/c?+Y6QW8wK8wakjm9Q8^Zw#:@%+j>+ePiRIu9jWPh<qqX
MXeqtE DwtPq>aeh=DmEZc>aMSMYE@q/^cl9jK>^mn=p*+<X<8T:Y/c1P$t1q#^6khww=D?hK?=pMH1TqZAPt/e
X/i&#h qlkY9TAA4j5=T4:VX$Sa*RJuD+NS6Nm=yiBDl=YKy/@BRyNKwXH<1JTWMp9h*u$nHtSaPDX>E<D5XCAn
4<dKQK N<#K1RenjPNH>XAJS!ZBk/m:tuKnIpLDt+=WB4Kp>^1Kcu4R%tHV&1=+<wIaAJ>:@KDb@\Qqlym#k4+j
/HqR/E Nt:b?uqw6N/#$c5dn8^^dTZZYCVc6X&$/GjPY&j:jm\&Aa8bTi8?j:MaL$u$MbN5X4C6!\XZE*VRFe^*
ujh<:J J&=L6V:pVM4@iRV>N#L?EctjCAA=Jw!QKYd\$!mbuc*DJ#JwkmSBD^+A+CADYR6:F&?>%R&>D1%KI8lT
%1KCVI 6b4yu#Zw=RWd9&9RV!\Vhwa>k=iapE$eDZjY8KPE/ePdFKJ5?nGZ5TcSpSaFTVWER\WAu@$L&BcplXwG
+\?bP6 nXDFEjT!8TNNG?B&=TiG86EMX^bhP#S+@aRc8y@G8#B?GC^!Ei=1X*u$SG<X4bIq++&t\Bnl>#:E*5M<
Ict:ak \*NT8ZFS4ai>Dc@MHm%nDD#pb@%!bb/ut#Mw#Rtb<!RDwS8V<PIy@e@kkMYc*n/P6ZaHQ&yqKpP*=ajV
mJEG#b dI5%6>IS*uFj^q=/8A@w^R4kSaBLnPScLdKeptkR4ELFuIQ^P1kHAVy\Q?G&L$^*+>=aM1<P!*ThAHFQ
Z9VY5< P:+uXJ&l>Yd?>Xmj18W=/4dYFZ&&i<1a1D&&nH#94\=BZ#WeYXFG9lPGh9S!WJ+m4Hc!k:&SwH%QI$8$
N8hj6X w^we65*YdQ9wHQQSCAQ/wtAAR?tI6/qnY8NV&p/GIER**iccHC+=tKMXBNm/J85IHk:/iI$k&^ed$ZJ+
&W\C<d +&wG=NLViVa<tP:B?JA=XK>9K88N6<yec8^p5XywJPASB%K*<F%u=m^NLy=iVE9i&\HK1dPw@QwAm$He
Lcc48/ JIW@^6\RuQDZtBQ@*naB#pGlAJl\j5mNPM>5\t>6bI5VRc@utIZmTt9=td@lRMdn9@^WVPKWn@A4akKa
QL&&ZT #NS^MVl6m4R^dc^WiWki:++AkJP*?^NtXYa5yJ&yJmGINBVicBZ!9?A\M:4^DkB<TQ%9N8&@&dV@p>t$
qtZ#nG >VZ^%RR$w\c?MdkBC8=Tb1pt9%1CXXuXhnHu%iaw6uMP<Rm?>XGiMljCcEDiYl$u5%J:HtGc*%Q/FtPH
mTkIG= a?q/!#MLjh&VK$Xh\TLn96Q5B16=:dHKiDR/VQ%eec6wYKLL<B%:!GjyH*JNB?#WPX*a\%Xpt:4WW/8j
JVhSlH 5qiKjT&qb^J68^T=&Su$wpqD*w^u6:5CQPCGX^Sb@a@XpRPnTwj=I4b8ei?=@eP\?DV$kMPt>c/W9Hkq
?CZaub Ak6T/+M8tVLLBTTFJF<n#NSJB6BinCLAQ\%kFSaYYZGmGYXy/SM9p5!+LLWa\WXj>?h5Yu&5ujVw/%h?
!#c4:V HJK8VVAu@QcX+E6AT!9wIAj\hD=hmtE@Za4e8HX>Q*NY?J88@^m1@+te&b1=D^hXPd\q?lhhWB<=mYSK
VhZp?4 *mGBqZJW:XR5Y5b^:@VY+tPW:!aR1@p@c/YQF5TcnjFZ&5#bn4=dal<$:@?apZhZh%&MI/QS<^!AqdVL
t/TE&? @D1tW^RkMlK>Wc@*QjBm%=w!$k&9!bQjilJ>&DenWA<^qPF#iVXhK<mVn&Wq>wR/*+^=wZGECHWN5$iI
M+W=VY %$+BTRQjXbBblGPiZ/$>Yq+EhVLYRWj>+G4#jW#D%iB#ZlM8=l#@lJhA4aP6m*j4@Ha<BhEVupdMEGa/
>RqL@p CFt!i\@qdJ:5WT=8i%JAK*+*i*8lb1RHjQ@lGNuuRG^B:aY/Gn>di&wbpB/Typ4/ZVje4^!<TSYtyA8F
&=>#W< Mn1bh$ZlAwXMD6EN:\DWP@aXda9cXY$//=?L\SFmYITMApXXkwtaMXceuLPMH#QccqiL\Wl11!4hEyKG
jRyCTP ?eXeq$mh55wHnQTGJ1ELhPwqep+=Qytu<mAtqVc^wM8hPM^<:Y%tZ%MlI$KAb9hHibS?*A/&!yw=uI<8
dm5qjX <F4M+Nt\@KHLKIYEW&hN&C9e6a*dTPeXGF6pddJ+GLPR<hECGEGF:BV4Si$wY<@dn@T+CuH6#yTk4%D<
ecQ=/6 %R/DSVAM=?=euTND1n%c+Ecp?+9cHwjF#QjBC8mSuj1$lhAV%%1iQw^:>9KmV!8$EP=:tR+</nae@p%V
+t/iE/ kp<Fh<j1:+Ctl8HCCIm=c%%VZH8qPjdkK1?+yGciw:\R#V:^*mVdL@by=jCNMHRbTh%RED+$@c5#GF?e
MPHLuH uNQF$=NhabI*YWnp#qhdI%848^dbc%Yl=mw6N@R*%4TquHFkeNnkJBd4mbd5Lm6j^qIV1b$C:Y<i$B/q
K?SX%+ uPy4e:^GHC$twdAP?cPhWAk:lkInLm<4SHyu1S:%QK6w<Dqp%laDtGV5l8TVqJlLMXaqmm$e\6lw1acE
d!ij#i aZMt1^dpeLl#b&&*e>JI>IKih1w$lHip&CqT=<Tw<>LI&/kh^ctw^QYGS:$DcIPZ&PLR^>&b?kGl5D@Q
&uI8&9 cD5GDD\C%AM&D=k^>4NANw:E#NpLJ>jJ+y$mV=@RnEl$pJGXGtK5>m5L$+QmLjLnhy<#R6\Y9/T8=a4m
VkSS$^ :ctjN?cpCyP!V#p9SenyyYu:Y?IqhA<KFaT:H%$DYAe$q+AiBby=aM=\6djqHPti5jL\B^T\%/\VaP16
?5$@Eb pEpPZ!aLB:i+wLAHbJ#^GENW5jD>BkTFk:Xl<q!j1>^!nNY4/ANAwRl85*4IDE/WdS8JCFMcyR1QHZ9!
$tGy^* K<eNwN^85GNXJ6RZaplhJ&RKA?pdP&SwWb^k*\H8/a:EI?L8Q9A@NY^wL!i+=t4>wA1J1^w?@%1AKSq&
yZELqe 9bXpI1m@/8cnNTlcaB*WN:bVM>yIm:b?JSDIPlXQiJ!%PuJMmG#n&5BHVGtIa5uEPcE9$N#h*ABWWG@#
aP<Y4= jKttMWaihT@iZY!m*#ByQpJedCY4tHJKuC@Nb:t/aK^GYKCB<4XT4&?>nkBXNX/KW4Guy+l*W6>PWqCd
TR:ZBu yM+^EMuXQy=/=w%t5$5c\:GyZ^FMHE8cqLPYIW4H:&PQ6VcK?*cRLA+GyI!aV%cNYRKLt1@VD&W8j%&B
*GQ#+b 6#*tkLE%B\<mbByp#X+=1GHHVm1P^69YGyT/uZA>delLJKwTWPbB%qHYW&DFX6webyaW++q9+y5JWyIY
6haGT4 R?68FpNVXP\<4lAyNTNYE=jmB^S4eFbbIb?\bNG5/5&WV5\XH/Y>8eDV6tP9jt6w!%1*6WS>SI4HMP=P
lCD5uY YTJaeP6V@ElI4<ZIb@5=8hTQlNDF4jTk#kXTE*HBP684jkGacb\:@bFtYMDPctqqit9*6wKi+%EXlHF$
*L=Skw dHq^?q85QX#L$:#&pHdYDQy<SIVnIH<=!<pLuRT>\wI4>Pl=:IH^54118w4<^%Fw+hYp<MV1QP4lpK$$
%V$WCk W$L1M^>cGjt&FPEpa*NL6lWEJuqb<AjC5%t>6jNtIwRFw\WMH#//EkTN8BNcVhbabQqVqeK61MAeS:p1
/wRwIP 5#Y6qqqpY+KJC>6<LC*p/^N?cH=41#:Nt9uRJ@b8^p*PS>$9pE&6B!$NPt#K&XSF\qbydDM/@cdyanH5
NCdeVQ &HSDAHYC@J%Ww/>4qtEMF#\alCi:V>u9AGHNKXQ*pyHDE\%+%lmSdPR9phIHbjDyGy6WuMGXdGE4kT?X
QYPaBl Lu$kE5?p4YXN/mN&SXRl$+KjuFYG\JppinQ9&W=h/VS*M&e=qCRHA?c4!qq*p>udaW$A%PFY<HMEl?t6
6&K94A iL!+lJZPa</LBTppSBllPkl?4&KcGBnC*B>#KuW$t/6J$#@XH=aW\JQE4lDy^=Y\aVu^a%S:$lZ#mwuS
:VdTtE td^c55T#MlC#kAJ&+tip^W8+8k<cId/SM4\C!yTwFB%#uDXp?=AY+yRTaVK<Aww4Nhyu/T<I*d1ln:1*
$XmW#n R/eZt8VttCk48hGTi5/H6Ji*YjQdFl5tTXL%i488J*i46?dX+@RFnPQP^Xm+TWb@hH>qVMG#m8CBRDeW
iR?Ihh =:1>5PlGuM>^XGa=j@VH+4ik5wQ5^a%=LF+q6lnLjm*4/B+JFy/@We>#midw&leCR/S@eEQQ^aIAM$CT
Wi>NdN 5MwqyT$hqPnptV$?*&X81/h<CQ&^1BK4WlW6\/B8NSC%&!nh4Yc^4!+!F4JdZcuR\YLPbT<hYKIT=aWV
H^E?c^ ua<>\blilVA*iwh>pHcAXGGCBVAZtA>Tt#?k6Y#$MPeccqTQ=lBuua?RCiFppDG^&=aAqm^w!eQRN$e6
uWGBPa #1lLwG66HHFm=jBDw<ZD%+Zk$dwK*BGBP#t@wXY%:=DG$I^LZk*lKeuBD?IGV8>ECQu?NaEm@jeECknH
&kJ5Vw *\4t@+#=&WAB&S\SqWNJ:#JPi>:/Fkw#F@KeMRdwkNVAC<aeDPjYjCb#E?ct>l*!ZkQw@$^Y9G5DkHeu
b?*H!q >$>TbCG64Q9J8KjP%*I@<tuwAhp5CujKmAaY&I*^TX1W+@e?k5=umH@W@M9dG%wRmXwc&bp/Ecpa&unb
Nq<ZeA G6wS<hu>?9Dj%j#@&u9?m\qMckDk$?YGVI</W%1p<GK%p1HYIb=hQ#Wkt<:kwDVP/Z1>/k9LMlYh/\Zj
yp$45w Ly4VQ>qR!jD?Y>cj&!GljRD\S*LqM=#4dN\uGCV=Sk9Si5wc$ZXANqe=&W#e/5GyPEZ+YMhkQ\DFL@#+
bjX+Lt Q*Q<NQeAaJ<a??Kb%nFXJ?a\@G9?P/ewWD\PpGN9jQk%kF+pPdnLnq#aY@>KH:Q/:Zh@WQ#9@iH<q!5l
SBX86= P$QL@/%QKkF&@>IuEWEAaJV>Nk!tDutb<pbKAKtGiFH?<Mh*RI=Rpi4i+*QG6qFC:<>Sh+HPQu!q^V?I
u&n\iQ I<qjP*8RH$nR^!BXh*WBS@QqXTmRH$iF?B6>/VlV99\kWVy?JScANcbAm*BCjQN1MdNMI86B@Hc^nByV
-Aq\$t 00004bbd3e700110334 Page 107 of binaries2.zip
*>cmK\ 1/G+<cA<Z8A5wD&?8##6hlwXqT%/JLQ!pZen$ERF*hG??u5!PS6:L&XF6uDl%@DG?an/W&:81XY%R%/h
eaT5NC mhLtY#eyIp<M+SDZHJbSEZ<&MBTAkVD=Tp+&%M^MD=pXqp=#uFh+$nhV5Xm+++%1m8LqF>I:@?aylDG$
p>ND#V 9C@N#^qytB>FRAt6Hwm:%?$1Qi^WDWGCb9%RqIyy1/\W?1h#PdiyP%R:<68YlStYDH9J$+a&WKa51NTw
yV8Wp/ TDRE?KjTknE+#1&&!n5XFp^B/JdX&i%m6+lRFypimwhJQ1F\bI+Q=y%9A:R6BKPPkI8\k/M<4:*&9?>y
/\q\Ra iED&jdB/y?WtF@4:&I!=JPT5Le=AjIcQ/EG5BZIc9@D*N6C8P5jV6E+%wYNXH<1u*u1HSTm+VF9T1YKM
4dCVlh W&+RjMm&uGV@GC$L>*PWECWByFZ%\y8NM!!wmHC4%\Eql?JwA?K#+Sw#6IaiynP8BbJtAdu9qTacwiIq
#mIyn$ jTGNdwejkHkqI=?QmYIYKDt/pa=<eP$CYulW%*T99tRM+VB?j$/XJ=q!SHm=kJ::Pq<^:^>%>>*CEiPh
YJj1:W QyuWSR@5@S^C1jT#16A/>R/Rth*DbBAYe:CcuTDI:PHuMNXY9Zp+eIey%6=n>a=qXnl^=<5H9e8WA\:%
#<ia1L N+d956VbhqXnHChWR%C4a>CuGJLGT6h4DnIc6!VJ9FqNITmnd?41jVwNZ>HbpMmd@=kX5u>\V4@9$F*^
5nSi+G WkkBA>dZ+9iQ?A\&BkDu9+pFBC!Z5K/nK4DC>lc>P6ahj\MA*<Jc\aR$h5yNkh@RC5eJyW%KRZ?Zh:TC
ZVaSZ= 5aJ#&:W=IMHFkV!W95RXemPQaT18!aquR$pqSZuIQCcJt6?Z1+F#bXN/b!EZSWWKG&H!=hVI4>caqE>Y
FVea8j *@l86HR?ECiEh<P$?#uZpF6j9^<>GAtJQeeX*P+y>m5$BF%Ki&uEe>l<<L:!Lj==Y%5eb=9QEkQ?#6L+
Rj\&Va FMHTG#FXV4d:*b5w9WiuwnXc&J1>dNhd#INE8E6:MMqBdVPw5m>#LhYNmAMk+l>lH#wLpJ?Nh/lcKHIe
8bt@%M PF+qZ\w8FD@CS>AP464m!>VH$cGB=nI++$+VHG*W4q#A$GJJ=w>HCITtjC+$jd4R56W#I!5$>ycceaY4
&b5RPS AXumP9*I%LM#u?npSt@p6G&6N*@tRy=Dy>CIS4pc*Beb!^5\QlaBN*#W/i9N^H51&cakE&ZIa$D&nXWD
\heEFL WkjX>ybL19n68W4$teh5J45&:R^mlB1D#Iq>^ADdb\=5y94dWY98a@a?b$mGW4&b/9QRJ%%+Qa:pS/GV
ZYb*Wl %:AC9#=jQy6SR4bG%!X1EdFQV8Fu\pc>Z*p=piP16B6E+Q\i#Bi<9Eq6=HGB$Y!yXBdM?^K@J5Y9eVta
H:Fnb# A*$^@\EiE*5mlAADdIYR!Dm6<9F&yGt8Iq<FIpbt@@D:*H+V8SG/PI1Ra?jdqMDk:QJ1I^Gi=%bJME@i
=pHjdn K^Qim1bEC4BCm9C%F&DIX:EC$t+MXT*>/E:/#q<mDY#jK$\^pZ?P:yMX:A/AGTZhK?K/LZb*pP@t!*K=
NnnuLR IIQhuep4*k?<6@lT98*?Qw@:hXjN8a$+XtBRp9F4ZAA5mt\6R?u8KT\XI:cD/Yj?p#9Gt>huBA#IaFYB
GZqMIC JwyFwai>Pa?h4:+DjNGdY9KAPZew$lRHpw=9R8TySDBhu195jA&NMwVqjcQjqZ%F:hJNeR%EY#*qFPP+
yP/:?i BCWJk@Ad/ZK5q%J9KQCSp<:eS>iZH?V5Ce:L5Q6/p*D9L6PV1XBNZJ8YGF8FCHV:*6u5ah%F!VKXJZa#
HnT88Z lIK:#CE?^:I*Wk6EwXJYT>9yEn@Q&CCPCdS!dZ>lQN8c>wC1eCBNJn?q*/k:^=EBTtZYm*YmAPZRuEYE
56@BSD >ebAPVIZnyS>/eVauTbF%Nd1XdZk/Pd*LNP+myY4YBVNP+T*Ba=wXLQ?iT1?/9?cm4*tkH?emmlWkB#*
L%dq<C Xac+^llmJ8RZmq4LWu4HLEh/eEA&<*68$Jkl1j?k8cI\NJR/SV5+168jJHDF9Vp!PGDW%VKy!bh:d&Q#
aDdtpK TnBjn:M#I9#5tKqDVm@wCJ@D+=c<$YeSSHDdWJhJ>#J/T4W4+8kW6n:AelqAG&$H*yqaq/@8IWk9ap?S
I^N?yj FtB*N6$ND#V>lJPhM6@<E4NG5EeMRSPeTYj:!?P=#y<kRXKTb=?*k+>Z6GFDXy@PyH!#KdWX?STcC\C?
Wi=KM/ S*RZQe9LKpRtE#^keJe*PMWZ^+ID1yX%eVXR#C*di@KMEl9<AtT^CYIJjF<aueC>tWMBd<+kc=Fd#K:j
JTRbHd eikDH^DH\BmNL!tQD^Tc+G^DyS><TWi^bYJBRB5Qii*m$QiQ9\+BLb9lnm1ume<@i98?Qh9EeT!%XBQ9
VJhV<9 VS*jTuiby:dn=#VAWI<JSi/&j&&qhT9XwR?NJd$Hi\TbK$YK?Fa<HM+^#?!\@XbkZah^GT@dZqk<9RNS
QlRK&h tbbD>l*hhP/!m6=W*%lp4Hd<1k:Z$TNT$hHjbdHHiaPn/k5d</QL9W!u^YlHFb1$ETnj@8tdPl9VLVSi
yMXWR@ I/H&+@/EcC4pP@PWAS6q<y\/wK%#pDipI/9FndnR\n!n\/@N1W@??Ze?m?BZCQE4u6C&NDR^6TDme@d/
cMPhuS +?J@lqbKj+RS!L@BeY<PARQcw?\H@kEE:I?EFyn+WIq@mBE19\<AtIidt?e%h#K:KK:55&5^KhNLmmIA
b6/Cia AI/^+!R9eaFPwB+Yle>?&1Vy*6pW@M>Baw$pABmjXVA?YLBt:n+W@hdmkC^#9?XKB<l^EJDNjm4/SBXF
JDSb4F 1+D:k^C4:9\4e>1jN%Z/%dd@b4V?!Gm>RF?E9i#6CN1#my5Fy1IuYC*=QeQNmu=1k6iNS5KmiJQ/cj>S
cqV:>H c>M?<kK@FG^V+>Cl*ceL1SCC^mwc5Z6^A>9VEd**EYTXwc<qiZ&=hIkH!9!N%<IGSB5Cl:\XZZZPWS>c
!6pFnV iWjH#*KGWVySyc%XEyRaR=eTHeTIF/qLCbC&E&jJ=A69d^cm\&PR:XN9n+=9q$?^J$bckCJ!FAPc=YHK
4lhyRK Yq6@X?^/15SC1kwVH*Tl8d@d$HQTqS66dHiLI=/4&SN^?HS!t$ul+J5mVAPSCb5GXqF=^?P?@Vcd\#>n
iF&bD: W\mid<d6F\MXLe*#Kd$tTH&6aqVHeRbB/RPWcSh/i1Akk!wL%WT+#N+@8:R@Wj8QkL*tBiRwhKHP1\Dd
hZiW55 Nl:KC9iR#\Ld$:K1LkDA1p>>=8&5I5#5^1mNt*nVt%aF%9b@BSqH>y*jj$H&q*6&4:NRXNa6w%Xyn&eJ
\HXSZQ q8uKjTh8ap*=WENwuHyJXiICH#bhQhNGQmlm/6\ikqt^VKdXyJMCG5bnmjcbD8L^&XbCh:jNQhBI!Db$
>pBuB^ LHRJ!dN/aB@pJu9b8Z588Nm>jumpuue:8AaD$&/bY@ipqLIhJ=mbL+M/uV1qah8aRcaaNMDAX6I!kG=n
edwcT! ?A%WJqA:ntT@T@Sl8M&>#h?X8G=VLSdJ<+Hcw^$b*8ECWG^:!##LW8VGdZ8LV?Zc+Pc+Y<y*QDLE:!IX
aj:&hR @QXu\RLZNX^<>=R#5cbIW9w&qI^m9R#dbH$8>bD4>@R*^KZ$GGNPE/cjB^ye5^@!#F89l<D^YpQNCW8d
*w+pQN YKkh*5H@BYTQEDCAIbV@AdJREWCPK6YEl*+*u^!kh6@/VaCXRuhE:AAAVKBIiPu<>M*umuEHiqKah?DE
aN*qX/ PBL^4!DnNH*<<X?R@cZ&FJt^G9GApItDw\c!hyQnRC!h*GNN+RuMyeb:lLm6je<&D$?YAMi6E>&/4ZP/
D4Kpp/ #FmCd#\LZdj^^w?=ia6=BZFhCCSNIwba^KXSMBIP44DcWdD:Hlt4S#/dj*J!V%ZuWdYk6aXQ1hbRY#BH
mL6lQX P=8<aBhX%Z*KQAyJM!c/EGV/Lq&<>/*b5p$JNH\A%X5n1PPyyiw^PKld?^ydcdqNL@N:+QZ*&Pd%lyEn
SGR^/n k5=eejpht:nBDc<hSSyHDaQTn5ajhy4\nj$%!PRMMkcu\GKd=$@XTa6/c8cJqFVk@ypJI=94eGBQkk!P
F8F*l\ mnmwc1R$qq:L/W=?iBH>lTJXF=bywtu/AJD=@1Y4a>q@B6tDF\RMCFRF+B>BqtRJ!NHWAQdT>qbIXFi6
Rli?LT 88?1pY/+M=>dA+Abpp>ZH:SnMbpI64p?qi!Yl^4yX9==&Al>ujhZeHc59=cER#?jFV@&$9>piq:bwthT
d?qXLY $qRcY?Qch+dYplMCp^#Eb:Qa^T5bDBc++cL>Pe#+m$Riw:4/J5&W$C4Sc=B4G<#J=BYqKp6XYX:*WTiy
STC^E% 6P^BR4c#:wtjuZ*#kXeCmX6!yj&/u6@$h+cESWiXn>Q!@i1EnhJnNwdjLKj5%^%np*+Fb>@IqqeIym>E
I:kiHP jGn:YkQYVqdHjGuB*u&8?%<Qk%wFjkwmPwHC+*?SMXZPhahmGY*:1HtCq\aHC5J>6*N^i5i*Fn\+/<$y
%h$5Td ek%TPSPy+GVi$/SJay<uJu8tt9!ImVmT<$GFkW?lRF\Ql$h1Su6MyLVw<^qySw#q+$@\ZlaBk:/QSn6Z
WkdJVA jT6KLM5wJQhZdekH@ZkG9b#kkHC\hdB**Y+6^EcYb6F+hkw9u!KPSt^>IWJ/>5Gw@D#\PLA>E&kt*59p
X**tt9 ZtZ#u@jNR:!yqwktHeh#&/<k+Q994=GqbMyZ5$I>!TXp*4aLCcJFpXKC55\$<RE1E5541d/H\6>Rq/WF
XydpFC :YI6*c:EM<l5C:B=bMB1pKLTqySdFepQJQK!Ge\n>Nl?B&jp+p/Gh5cY#pV1DERmV1b&h4?yHnPn9%#>
%=9eJ* G@44><D?:dnS^5VQFh\YQ\9mSAA\Mi&<jcFJ%nu\TMnLX!!EY%\*+kmRCa5S6F5?yy%^qpMq+*CBn96G
*y6LhQ d%4^u/M#9pAA5C@h*Ku@bF?CuV\Hpie!1T4$cDMPpM%E#>F*H5N4@*aG<k*L8J5EJwWi>#hq>b@N?DiM
6ujJG= XX/b*4?awSQ%K\VEIWZndBEZ1Y%9QK9#TYi=eNy=BiS<SFanBn#*<L^nmdC86%+9qKZ#W@^=%PqZl@#Z
QGj1Fu uj=q#R=@cdwcN#ym=CRq$qD=tbX^AY<ZMdheBK/d?=JqnF?+k#Zt*D5BkX=T\8y%4/@eKe?dmmpEQ*u6
#R#6t> dBWTHlMLS!ICA6l%RL<jD&pnXnQi$@8t6TJH:c@hFZ!5H*XIFcMWj1\eKaabN%GTj&@*Vi/u=VE1WwlP
tJBB&l MSCylin&mtVNP%$H%PD+kwIVnnFuP8N5+Aj@:Gw$Xqmd?\PtKh+uM1ptS9Z*WnT/=Yqu4<96Xj49uWAH
&J1BIp ti+1*L\p<+F5/MptSEcGJb%p*mAEDE\i8ZN:w@QRkBESmlbI4@SQMHDePuIEFJ>J9#^&ydKR&dJjJ4^Z
Jbdtww W16#Z$9Tp<Ja6<QdlH+NMyHwWl5M@cinV4?R<a@\Pm\GAINqt96TQT5VWuQp\mbp>aiab$ZaAVp8B<6%
wp+ySR YCRaNY/^hyLhN&P%a<SKbH>Y>JjRHj%!yD*ES*c/DMw*u#T5dPZkjYhTKi+?wEn*Ie^6wnFn!#k$Zh!W
Eh&^Ql p?^nF1X%8c?mum*p4K8q+mKa61nNPcuQTAXaQ>K5?H>hEK^NV9X&dB<8SPGGGN#P#q!YY4Pplh%e$M<>
k>A<Kl Te>k$SB=wWl@:ZQQb*NIbihdFHTjGl/=Tau1l^D4?4LQ?58S18&+#1%J6Jq!%HC5LPN6dbtD9aK>&!=/
kX5qTZ 6Kc@wEt4FIHFHm&u6Y?JSw>yJ!iqN$T8Rl#%IjYA\HpYPJ$d58nq1Zc:=Kw9u8FMP&hB4aZ^FJ^B%MFk
yYDjmR YjcBjK<?+1yGjXp#Lh+T?+VABDutH>MGGkq1L5<c9F$Xj85y$JR+n1=qNDcP>G%11FDm+HNS$XHy=*CC
BL8bn/ aYW4iDEbeEBe6I@GLuudmqWM=EBa!Jl6t/cjEbic?&BA?Ia51><6qnB?yKn\X*Z@B@M?huWDy#1N!*lt
-AJZ@P 0001b18f9f800110334 Page 108 of binaries2.zip
e9NX6^ LyXD?AMtpuuSRiabjeTJQ9*Pu**Rnn4X55Fy?dH\8W8wli5WPPmt>p5CaQ6pBT+TLa?&P6XD1pZKk:Ic
19Wbnd \1QB*>V+^N$YMN^6&wBq>4<hKbc$9S*SS$MdG$NuIn+4?*@!uZ<e+^<68Q^:XRJqA\Aa%A%yIJhwS6aL
MbKhwP :jXqNN4/=>JC!#IAYFMSWm\$/H:yqy68/E4SSERNB*4&B/4Pj\5ywd9C^R\Haql@&RAB&W&GdAe9:Aym
6GbjKN eE*whMTdjV!%QmEnB^5SY<Y&m8b^&aFimW61>#6!Bn*E+Xc8^V=k/Rh5R8n45A<SLcWQ1Sa@e:GRat=8
PG/p!\ nl8b\QK5+*tl?1j4ZMR@W$e@+D<XpaDNeJSyi^*d9>=KEAZmj=MVH^dwqc=Tkd^NNSTI&pCh$B1aN?F^
iYPeAY Yi<iXH$B?=#T$XQZ*M%Y:JH\KTA%RecR>H&mI8KY/%C:MbcTJyq6Da>C6E$?knMqpmd1G>ucPtRWhl&c
HBwaLl 8%6k%SQh\^kQ4$X$*aIbT/aQlK*mbPdJjT:6W6nR&QAjJ8j>aVI>tqjX9GR&&6pCCEn@NLk^?CNW:SC%
c&bSQy <Fd=WLH+mEQ!%?qCRVwn!WbnEZil&EM!JX!TaVNCK$q*T^a>RCeNl46TLWhY4ITZkE:1uQw$/YWb4N*\
Rq&w$h hY?K!hl%9VA@$\G%b6D#yqMX?9N#eLbRV1bF%baI91ZH8@jpZK=9#cNCGuKqclm1W%#d45E=HCkn%IuP
nT5iai pRdjeD#+Mb54n&1eI6^j+1i@%\D<t16@Y%S<Hu5Q41kyT/$GAMCCd?d&5d/E@P6peJGWi6aJNG:y6:<R
Lj/Ep< ACa/YIC^Req?MlI6\WP:1+Fam9Tj%<beEAD\IYaq9tnRLp5A@@t&l9B>/8mipl+AnN8+EQ\/YEbRdGHJ
N\+aKF VytCWcJk?L#\i&*E?^@INQ:n+6<6maZMC@@T?6AARI=&$e^tH=:HbYkTdSp\djq5H@W*/:YY<l*#<wuy
H@qVBN </nCA/AeRX4mcZ=\/R?THQ+Qu+WEB^nHh>ek+=Li/j>^FIN1umIjn&y+9*bKnwD=iy@/MQ#b5<aJu<9%
QuiHH* ?d:H8V<RtaL&w$Hj:6Em:G58FeYH16K1iqQEQIAKCQD#aup?C5EVI5$pwW8R\8kN=p&B$QHT4H8VCD$w
nK^!yJ S\@FtIX?%8hWGNnwL@Vui*1ih@Q^ClqaMT<$^VKjYj+@9TVL59^PE<EBwyEZJtheL*bbqKP=pI*y=dA9
%Y6hlA i6d:JHbAc*M?VCqZXpuu6^Ay&nb@GwwWtqJL#8d&**=Y54n+DP+=P=F1RTYEyAGS5H>>L%?m$*Lj^:$p
4DVI!S =XB%Icjp\j&Fq/K%$>KhS+q$=wD=S&Y4V+\VHMiC\>5BpnJLXZ5=PHpRA%4w9YXjMB&b>yb^6!L?jbDL
Ih*DYN EQa^CHjcVcjPI%Z9TSESILbIj$h1=&8CS^qJjR>t:He&b9AkJL#\ck%hVydTFH<qnG?c\5%p@la$aqb+
9u^tM! @B^#ynuJRh91\n^DpIGq?6H=*KDKLXynLb!YPXJtZ6wMwbiYZnKh^>D85nepWuNj>Btbiai\WYNdBkKa
4%d4Im LPwh?RY+9lCeW<H=1PL@#Ci!ZEW<kEmI+T9B=JFb9lC!kLSI5u&kW\eyGmL1@FFJ4\AjQJb=5$8Wd!hZ
=\mS>R Z\l&uy1EdP<PNayGZ5CXBA:Q>>Z6?nVL<p$9^XG\/<hXl96AEc%\/4CLH9Yed&uT91K!RaL6eY+PcWyL
Yn\Vn? $6d\Cu#WQN#jK#l?Vaw@b^W!1GwXANlXJpRE\w\aX=<EXiiSGGBjR/MmC<lCGS8Vbnyu55*aci194@Xe
:\naAb a6G+S9$#F5k?Tj<XC>!<lkYD&eDBpn<w=R=Y=/Yw@!BGpyDT%>Ib%e9VGk%9mh#?FS=nnAR\n^H\jWdc
/NISX8 lM*CEpw#<Y^61\19^\n9KD#n9/ya4B&V5kLB!QEQ@1Van<:=:Q$/i/VI@4^Qe@He=:a9BK/L<BQ9MqwW
Z$IH:+ DJ>KItEjny=t%6N=iN8H#Ee9XE4$?/>a+MQdwMH%TdjZ>D:4jM:uKkJX&!T\N?JHcT%yN6ZDZqCL>F/V
dC=Ak# w<AIwN@tP*nN%*bR8awP^=8#ykbC=P!+L?<n16EZ$jZXWy?wyh1G>^Fi@SBBYS$p1tlnEb=/ce<:/R8t
9$MW/S VX:6bVjdd*V+F&D/M68jd>TKewdi/id9H@Ch$!Sk4L%L\XcX=AVWmJJtcaQYW:?<jCt<>K>XBu6n8bt%
K#j59M lG\P5tb>mWhl/:Ch5d4@/GMy64#YFC<^*HVPpc+pVRAVpVTLhq1:p*FeJmA8YW\CjM<#tpB*pDY\4h5Y
+SD?DM Z+?V5dM+!%:pRTMi^%w\6:Vc61elM@GGGCBPhp&jAhFQ\iPQ\K##H:j>mQ*^=>P5B\:BRJ5P@JHu<M6K
RqNcYd 6CEDV999YIBa#6DJtEnW$>4b^hVJ\6:X?T<QmDW&?Zhqtd<G>Y>8N^phTN??9dZn*kEAuwXQwDP:^aEM
<S?DAL HXJC9*I8iu?n!MeFAA@>1lqS^@K4N<^@yykF>+V%Wh4%@L$5M@8pi5/GCu^by?RbBAT?Di!NE^?Y\V?8
pBp5cl WFHmBFdGNC>1tYQK1t&MFqJtcPc815K5Eu6::QJd9C/9hG!X^^8/c$!kyynV\KhbTBWqVn>GAH18u/wM
G>4jcI 89TH5wt5V/wq:l^:FMQyASAcFXaCJCD#JFK4H*A5n4^Myu$%a/yQkt$Dq>+Xi8FaM6>:BcW?%?l#ZFc5
kNLAn\ ik#?=?MJEEtAdEGkWepZPA1&tn/l:$@N4MmMZ!:/AeA6?nu>X*S!k\iZyQ5?jjqpDK\S1V@4+*=%&H<*
y9#ICy ZL^@id\BbZ&pV?lCymVcC?&<!S+!pY^F8qa?FcIKiln%V<k5J$>\^1\=+^LEMlPZ9eu^SZQR^H\:VZ5$
5K&BAG hm4KIQQqS?uCemJ*T?19uHKWA%VZ=Hm5AdqH^116mPS!y5j$dFkV/e<\dX1XPIc=El##hSJM\Sd9h\W8
!pad#^ C@=<u%#aVK!6PmZwNmp@GLD451GNy+iSb%YWM=K^=5qIBS5*VTq4<TDAD=tydM1p6SW\DhR^BKlyT>jX
h?Mk/p p^QiDW@CCtRn<!ia#8MldRIpG8MmKlGN5i4^kH!akm\Ru*GFV5HlXKR^nNG#M^4Y\9^NqaQt84Nib:<t
#1Cuy! k=l<@%/TwAcV/JVBRM5QI+p5:XtE?Zj9?k5Wj$/iZ>=XERDeh\SkRh?ZiGCMw#CQSc<iwD4hQAG!TR/L
1j<k!D 1SDD+kEZEblG%CjWY%eTV+y@p8>Sj9<q*@?/pi@$L&IYK4ASm6%<lidp8B=hik@Lm^a+IT6QGdH>LDtp
+BMCuW VhSG?nD@nG6#dBXk9K&/uQDlhyNYA/++Em<PqJQHPC#?#Byjb+DeNI9N\XtGiHHXeG$\n?A/8LpPhR>K
SqiXDA u1N<?:+FFwEhc&E\h#KiQcAnQwm=>\QYup?iuGE&SA#VIdJMHJ:k\Stmj*IElytZ:iiD6&y>ca>Le#Ij
V$bXuy ea*dM#c5Ep?nhyEN4LC\5l*mKw?Zd>8/p9:K<ZpIS8kDbI=\\8^DmQAtlQHqyIcTH+\5?RPP>YSkNu4h
Lip>KN 9Bw5ah#e*clDA?<$c#n&dDwN^&N=?q\MwSQyc*IeK+!LAMbmEFDShch49Vdu@<TLFpB\R<CAdLQ/@cPQ
JFi5^P @8kJ!LGaaW=1X=G@Cu:CRm\mBI<W5R5wARCdi@\ba!IP>6<$=^/@qlPTml!pNQ?=lCe%8@=c\lePJVL%
B!J#wJ y8KTDb/tn659=K#BwcXY/dcSD:\%Q&qtccKm%=qqiDGYItcyPnELFCFQYC@C1&Laqiu/tq<6=5mDL8\J
>>aiDa YyTh<<\cAi!WB#tJ#1a^WJDHPZSMp4Dq8cc6uhWdht&w^>DhPDGWYkdcR$Z9KIXWDhaPd<@cE:<\Zm\>
H%^^q! Pbn?j5I:bSkc6n<8>/lTaBtcFB=Q@4bTIDlkAMkXmCV1tJJFbG@1lb\y\T\/PwllEquh*XNV1^GweRmq
S#RDCq D<W>&W/hDPY:c4$\mX^GjK/k==AZ@4uKLmn1wGK*StM<aqFMp8L1&^Tt!RSaZ5?I/ph5kXWlE14yD&%m
<*hDh# #tYcC*uBBT@t/My^b&a8>IFh$Dn%wP^&uV$uAb>TDd4jJyQBZ4E<dA+LplA/Y<AmL$e9Zl$XaNSNK<uj
qwXVdt :nDD$Kp#n5XDtBChcuI!TA@D&4:*t<q?$nGe/JG@SG6@EFFN6?CHuEAmZHnwiqVCYD5uSHhB/nlaLkVZ
Y\S<=\ V4@qu4$\RRF!R^k=pc5AJhndn4QVyaQ\e>:I<TtNYjC>tDIw1R#CeLX#>#p!@/q!KjeV^q<4q>lw^#wy
A@#pQw Q+>>aQeS*+GY<A#J1<>\@k&HW/T5^@8j4Fm<FRDk6QaEY^tp6*mYRZnw#?h/c5^:6&$AEEn>#iG!yXHH
j+yM\P h8p>uTCkYtZb>L*+n!Z:H>Sa*j^XDeTNh=nGnLk%4aMaVKq1<tBAH<H<Q/w=FRAAV@CIQ<lb+Eb/4JIV
CZu@M! >+PVtqV96dpDe4TPpFV%#m4CFpcym4SqBSZDnS@5@1&cLXZdH:DpN^+4#w\laHjw#5<Y4J4@1Cb1FkDM
W@@4tP C>mbPWep?JwkDIaTQ+W?=qT=a\wAX8&%P=acy\/E\@t^P%@Qj=Hd9$n=6&w81Z#>>Z#Za5V<F1hCjWp^
V6+?de C+^Ncj>SndW9IMeJ+<dR9SdGNtaPYwmNPAG6>WQdL?X6EPju5cIpF^/&tX4YSHG%aQ%QMd@L9Ta?9\MA
W1@+bp CJ#@Ljj/d:uZ@<q!4!Pl\kHRVF4nIFtqCFe$\Lw!AcRe%\L6<$<dII9$F5my=Ai+Ldnd5899c!K?unVX
MKPZcX <$9\=V@#6DRLP/Lmul:ay$b<ciPq#CndCSwSjKLXKB:+:ZnZ6L:5HZ*@1AKyjmVteY&FR4^Xq&P5p&+i
R*6qQ5 WWXEdGLQ:QMW\j$eYQBEEB$lR55y8$ncJX6PLck>h/y8^wtYYt!WkAcayTwpmSCTyi:>1lK5GBDB@BGy
j=!E8B VAwI?>DM9K4DN<8py1S9ZuZKewIJJ>WLhq%TtaNyLYL?VCj**MB6^J8?a@+%Zww9jXV?a9B&%>+#dNc$
e#cRYA @tqP1*XISVL!kAi+Ei<+aKj#$:NA?Ga4S%5H6/T=NwTLcBcKqyL!1m4kE@^\+L=N>q&cd/GeFZ4aP1Ln
j1K>+F ctSkyPmVZhF>ZYBLFM=6J//T#4PmP&m*</Y?\AeE^>G:14Gil\E:Wi<Yp9Tb%Quwlet*?CSJW*D*9Aat
tWEQMN HI9CQD<K6G&=aqkn&IE4nJJp>Y?cN4\@tHXpSc1pBn!:Ilul$9QLcwnqYZlXS%a\wY>+5ZCTi8JGJy&5
Mc=!GE tYNM5MEn54euLb8G>d49&D<aq\>9#NnMA%NLS4a$FE^^MHy&c5<LhhVEVGlT6?+44ZFQPSQ&+#Tj#A1P
K+k=5X I1W$b#1dSeNla!V*uld^d&YIB8!tuMG@GlBp5Y1/e!I^:B=RE:q^F$%jFlYnq*#eY/<=#4d?KN#KpXLd
1NZF&k ybTybt9<pEAYPiNjNm&yqyINWn^>aK$ic%KVbSa5HVe<ZC/1Rd86e$MDHYpP&ya:QKH6LwG4:wa$I&%S
mC@=Nc BJ/+LWp6^pSq#h4AkaIPhyH6C*5DL!I!n6&Nb$/+1^?+\=5pSP!Eb5^6q<y?5NTj9KyJ+QY$1LK?G4?i
@SA?N? #:\^kwZPHpJkq<w9JnLPlW/jEN\y?:AV/N1/Il48cSZH>h\!lCbqDFGB1<!8:&+C=*!cL5j&w>FiYV*P
5YDw9/ ?HBjbbIch+Xj$t:eln+Bn&q5y@RhaLI&JJlclm=nS+R/%V^d6W/u+G!@X$9D*P+\!G?=GpnumEKFK*Zm
kqlbl& SEBp!ptDBmn9B1%H8l*cXZjqFt*G><Sd5FlCQM%PjMKdWuj>lya#?m$Ka%A^+qa!+:N\y=kuR/VD6L:+
G^wYVu RB5B:j#6\*i4a8/HaqVa59E/C?CM8wqAql^/Syu%jb6PtDV@RB<CTblJdHWlJ=DeKVaTCG>/GN9BNemc
-AnQ=h 00012932f0a00110334 Page 109 of binaries2.zip
dS>TXG I**nDZVHj&E/BG*QPG/5NEPJluPdbq=H>9#5bd:aT48GFmIl/nTLImDCVck>1nh^*NDApmaBlXWEWQQH
nkN=H! F>/yKw!/mSJDdTZe\B:R\wE5&GNe*wQ!pE$m58P9F=FL=!b9b&PLF6MtM8Em4dIYdakyG?>J9Ja#nccR
/YKjCC dNnFnmwaqyj+@IVnqqL?\bX=wkj@w&4GRDw14!T+RTuSHp6Ch=q&%yYMCQaDJ$tPb<WRGXeWaMkQ\qS*
nK$E?V YZeMMZX$ZCVFAGwD#c:ZcZ1RVt9E4tA?nMi+&5w#/NHQtB9QedF/%iKltW1jm*Ajj\qhHFQG1VQ:!mq6
9RiSN@ mM#%ZL<$X:JPp\FB?wj%FNHMSj4l5KVPqHC!M9PAC+:a?YLIulYGZW%CTJ!<+&WE!hq\TXWD:$e^F84<
BhW?jJ dQSpTpVe1HKEICX69EPiVjIM#YDdlkb9h>?:?tdJ#6BT>6!Cw=4XWnh:Fk%8V@!/eb>VX9ubCw^u?A<V
:k1V#Z h5=6kDZQ8/iIp@\jSaFpXqe46i4a+KQjh/WJ:k5Z>ch<A5?PwHB>ijKh<=eXTEjaP&Tuwwi+KAu8<6<B
^5/:+: $DFl999n:+D9m?<AHKijH$YkKHwWF5X@9Xpe+8R=h51KLk#P@CKLLAcdpAqK@RSWPB8SnQ5mlQi=:/ip
W9IGuD +G#qP/CZFlk+tEH+i96>X?KFFAhn1%k8FCwAl89NXcyB6PIy4dqN4QLW<=lq<I!%A$u6Y@=m:RWjTnML
k^h#^& y5Y&p&<$PTD>HLNQt<\Aaw+IAPiae%Z5c&AJXyRD@RJ9N1<%l>NIXPth1WwAH:Ieaq@j%@\#:RFuPpY8
D+>6Te QtCXXuI$8TXNLVY86ZcEe6yAR?:X9+BAQk9pKTJk6&?X6C/leG*jPRAEZXFJRXSMP!G>IV6E6E*k1>&Z
YKy#^= 8Z6ii#c<RQ?i8%I6WmNYMl@jDy1XH=9l*?XC:*+b4jBV@Fbk%aR\41\&lijpI^1Ga:6pEVFbnte#ZH4M
Pm4!T4 Cc/ql4WW<6T#!G?:?jNm$t$IH!aa:^Gm*\FCc::QB\tSPPYw5SwbjdMn=F%Q<yp/LIPlFKku@CZqt=R%
hDq*aC hZ4JVXSNM\F!R+pewj#?h*t6lSSbeWemKZ!11iu\?Xa+j8c1%Lmt5hXN6C*^p9R:LNLHcNLebq!k>Y^H
YkkC/9 KB8#dI1A=^b$<k/b$p$yh+jeLj>^6/6t&4k?d9^JD$LyVib>CZL61wLI^YcPyVD6XhM+CX*XiLVwD?%B
i>YRHn c4@L9NS5^ecbK5i6\AbQYGQKJMF>8A5YF?VD9ZA9H8qqy+TnK++n*\GMM=#Q^i:ZydMHt#KGLwSMh?81
nie<NS WY@+qp$cVc#kIc5YPEJ?mbF+nqQTWnC6m$TNJ#YMPbSLiakH94AMiM&t$<M%uqX\XymPCE!1*w8?>@9q
Y\8b#j k&RBH<cCdG\6KyeDd<8>Ew#q&\X9B>+BTWw#4yIM69VuSny?M!K=HeNcEkB*h11bFXn&cnai+iKNnlKH
t^cbmB 1*NAebG<a+/X<etQC4ELp8#qc6X+%9d5Zi#la41ba^ab@N/pCE5e!Z$\*8X4^ZhA+@GyLP8AGc:m9JtM
EWGmp= YcwBDC+8p58uctj%1EK*aDu^YS*#qyBQ:KVQQYnJlD<IGy1Ytyd<P<I@wn?QmtN@Ah/wddiGVZGWE8q+
@RpyXt &>PSnBC6tl#!^nadT8H*+$V9aYI+y1HDdDlBwqY:Ql^iq#Nd%QP9I%Gdj@//^qFNy#NH$Il+H&WR!@Il
Wn@EPm NSAyN=5EWpG/HM/b?Qt#w8jb*LA&p=ANAan8R*iy<n&?6G6#YF&1#8jlZVnwI?c:9P%SnTY&qt4/qTR%
BV/FiG M#lwI\<&6ii98ICde#F#Kw4JWhhm4AL/jCPZ&!uyBHG5PyP*9i91N\G4DwnkiXNNF4\L4GN%dh!\6M&B
M>uZ<< HemQ4jEGdlh*+M:1p>auFBZQA+*^N?V>a$N=yYPE^imR^d:*Gj#TK$cGi!KjB!u>uL5jlk<16DRdYEje
&bDY@J uVqZGR4$C8@QXV>hqJ\JbnFbC1*yp51KypmKXpDB>h?>RKGV68bmKWawwa6DdTnTe5wqZdlPmHG!RP@l
R/P%c> Dt>qC!nqnC@GA<4Ke>wAJZIXAY:Jm:9Dq6AMeIcBlJ<1KY5h9iK5WX?#F!*IWn#TKhjcL?GMd@AY^mKV
i4/+AZ G8y8QntDK+LGXHkBcKIH9>+MPJt&*qTb/RXw/EI9eZiDFYy@C=DcnlJX=XPt>Z9F^a<t!XlIY=1Ydwy$
%T\>e6 h?8ym1wN??1#HG:ajTh\X?!Jyy\ylTMJI8knDHbV%tZY%6+SaV&DIkc!kehec#9%88QVD85/WD?=y!84
FDd?lt V?ISLV+V//6h&I1!ZGqR!+bCJyQlTH\h/MS<u4$!TW*EZJA!BR&Ch6Pec>D^DyD?&5Qtq#>KG8cARS\a
mk:X<V Y@%VbS!/1hIiC#qZPh@ibmF%9SLL6K/yYb!+RF@VFc!WdT*MTKI=AB#W^GE5y1T4Z/H&%e1TH1^CTI:P
mbAu*# nG\qpY9+HWCTBai<FpC1c:iZ8bhVCtSk&dyYe<KKcepLX=kc+=V*W=LK6&kuFXl$e5Z/!mFM!a$Z\&Qi
h%Aluj cehAt#JDQ%D\6cL8MS/^m=ck1A&#9TpaLu=>AIhS*S&APBl$<Y5#Q&a\G*myFu?^KRVun6#C9>BVHL::
HCcNbX >9Vtw1qB#uc$lpBD!CN+GcHRIF/A**e1*X&R$P1TtTBHWS/=LEquw86%pL=$u&eI$mJMC^e$SXGeqH=V
99hIWZ yLpS1CT=RS*6Ck5/RiJ@1VVlDp66>Lk&V#Z!E1\5:yR$@VK4K4:D>PYBMqMFj6:A=/Tiq<ZI5mCm$Lqe
$b=LiG i$*eJGpb\N1>6<V%HbXQAAHRaij+Xq=<KnXC5m89aPLKa6BKGR^GqnAd5eNi/ZLCY>Ca4Nb5Cw5eI>Ck
CYW?bd nqJiFi4C6Hq!<L<<k6n^=>?w>#?*yNXJkB!FX\SFD$Ln^WG44LI1nqTJTFL>QpCPe&dGEqRBn%B\@!/i
c&%6S? CwXlKQGae9>@#6eYiRKAGREeZ&DeZV6=c:YMKK#QlcLhyP5B\P9Z&M9?n\6wi^?G6=mqceZ/><JH@=K9
l+qaw/ Nj#>4BeSi!NLW!emQ19j:@=h+mCy&jXjYn@wDkCtS5&#hL1w#66Nda+$lP4e*nGM<APA?%mVu1>=1&p@
d9RX:= qNmFGeaR%y6=RQn?cQ$j^^NTp<V@jn#BbkiRI#ht^PF##I4?ZBtwt%+jEkcHAVaQAEatmS6FyBelC^+d
T<DJeE Gl<t8!\/S:y9@j%YlTZANRk$+>FQD?e$!KDNwwAetRn6<9Gd@5kKXVR>@\+yI$?w9XyAn6%%bI9aS^6/
ihFPYW dDm$%%W!=HIT?NdhQ+V<peKwX<P@kXk:/Xdb^\eB\ieCi#i!Cn!XG%aF$aw6ca<E&!PpLnHJ@dYEuRat
T<Juh$ ETbIyu*&KneR\9#WClW@ae#=BwE&ipyN%%q!IDeh>8&e\p+Zp58AC94S%L9/\QKAY%ndw5=bm<#+uIdd
#@uXn^ bdBlX8%\M1YPwV*CXu\#ndZZJuTN=/T9BqjmEWj?uR%KKP%Schm5!hN<?#?uMD++ALL\w=R\8n@IeNpL
RtCmhB V$^m$+KAPjR=b\CA?aXE=>1N^+5K9YCJPIWX+*=KwTy@XFn?#!G&btLubtjmF4K\N#I!hYc\>4K*b#A%
bR*C89 ej&Z\Y:B@bjBy8@=%btbhG*h1h?cyQXpEReHXF\<:ZPyAeCY:/CQNaARqVLGK<QBRFI/iT4\=D?1Zj<J
ZJ>Idp Zpb@ZQ!ut#kt6dD@m%:Wi$AGBEKAeA$L/RY?HV>j9bPSyMpB6^wkC@9&1+J5=A8eXbaLFJKhM#/KKH*m
#^&d1B d:%p@%c95/&lm/ZH@/=b=F<$M*$DbKE%dKb@=CpjuRqeAKG/qDVMaXklBYV#hyN?DRADS%8F*4EJb&:N
HKHK&W 64h&@59DhyB@e//DTNAjIDMd&qDylQtlTu<T8#bbTlky8$>+&m!&6L+4!p!/IRSnABNM%QVh&*$>kmR>
*RcFi5 ZMEW<^TiN>GL6+Ij\hh:GRiDJ>YeC59nnuQ>P@kyJ/5q\4L=&8qyMuQ>9@pX?nbJC?#=b5Qk#p9b\hwS
m5+C/u llm\c=dE??9Y9MNX%VPh4<mn#X?ayJ9iCM&@&H6H8JTRdMe^!$PFQ81@G#49H!&EtCJX=Zj<tKD+$696
hY\%R8 iCJKGit^1C$<dnRhy5nwGt=QD+e+K4XI6PXLD4dl9ZAAC<CGqWlMm+e&Jeqp@iR#R\uPK^&hjt>Y@yDI
y<EY+q /ANGLm4@<eD1>kHk=AqS*#tn*p8ClL&RLMhY>8&:CFXi:t>1H^d5R!S$at9Zh&ZIkTFbli^+pF%m*PJc
#na^C5 Y=mHS:n<we5ZBhF#N*4DWcV5uA<pQa%\=qn4W8P6BQRmpl*mlh/!$j//l%Vd4j+q%c6CmBlcV6?SteDN
kL&INe y:DGm:>!ZyL=q!u&^*MFJna@W1MLZZ%1cIBkhSC#HG6j#@=S@j4>bq6:9#et1F8h$QXbQ:\i@cFZ1qqL
e^<I1p 5CH@C6M+e1V*wKZ#+=Ajt+#BeY>Ii=CPn<&P5X6<cCjta8E$=a/KPFeCXPX1tPRkpVFM!Vl>+TGcuj8X
>#iC=a p*H$ben?/bZ=9dJ\tb^1\Flj=Pka<Z9j599=tywu<8H%I*5*6Qau:8eL^i>e!CF8NJiq#t+9GSQDj$<c
maM*bK @RLGu<lCB6%XBPSaIXH4hIbnac#SRQ9J/$uE<ZYu6kPA<Vnlm%V4XFmuaWa9tqVNCaR8XH>L!Z6bN!GD
6adPbe A>:FHcLTM#yeD^TRX&?WSB%RE#yX8^$DPTjidGZj^bdZ+5<NwQENmYWZZD>^\8j\R5TjNFF!9$?K*a:W
<Xikj^ cQG+RV&W/lW!:!uWYtnwRERTS#kTeRa+VAe%=jR#AT9qkanVV&B:u+4LtQ^t6AKWpnj#@J=kJF%*B6L+
R!!qKC *^lMAl^%H#Z*AeB*pZn^DZcHWcT=m\*mca5<^dy/BZDAGhnel9kV#M95PeGVapamdqD=%dXwuE5ChHYF
jEPtqp d@EAdyl5YAj>N8Y86Eu6eQ1Z#+ILcDE<jtJXGIV\Ye^/1:wbjLQ8bQjC*><6e!VQPX$ajna^1*b=WwnS
&8?%^> 98@^l%kVc9QpDFbK1PP?jWew^uMQM@+WpwpdFK^\?CtY5MLyb^Kq=VWBPCAWZ<yY\4B\ZT1/VcFNK5A#
P9b+$& 6Vi8HKyeYF=e&\i%t?u$yiYipb!EJKHL<eFkeuhl^cX:TH9FTpI^h&XL@!\P^8Q!VaZ8M*V+y^/^VyX8
qKu5<E %85taTkdmm!TVj&tc/Ly%9LHBNE4MIXyMDd?e&T@#Hn%d^5HNBjkNQmAK$?p$&XYGTQ^:6<Q*Ju@?R+A
tPW!Fq wNj@Q=I#nkG+@=e#@u<Hb@#N5CZ&VdhDD9QXPXY\WH#JiSDB:pWFR:DLl5C@iD!LnX=j<Gt:BQK6aWpt
u/Ca+V dQ:6hGDG<RYBwFa:!&+kM4IHQXF?6cD&bikl&4R%X4<<l1d/Qm9jaZW#?^%\6!c:>p1#MVEi6!w1hq?K
:W=M:? 9j:Fw4J==Gj5#aA1V$jkyWiw5wLqdh\di5de$#5k+MQVY\XqlmuqT<hQK+YH<#VBR5HSSt<l9qkE48?4
hh!8uF b5Ly=9ehuu$@A<cj=R1Nu%Viq8#8yR?ild>/D4lLYct/HEiy/dFW9AP1j^4t>WI?y/9H@>I@yE4:c4WS
chtba@ uh>Hcq5dn*hIwHiamZn/=1n16nd!RwCT<Aa=w8H!4Ltk6>nd+?:CkWpi?MZ<=ibnhFj%V>B&Ww#tn%!B
?tIPiy @cVbPL!NNt>w95YWWy@Xe?+uQn&y8e^>&F<Tdnan!=1^?nu%nXY=K5NJ+CK$FP\hIN8w/F6JV9VdwFDI
YV%&ma nk=F+RW?pc/:JZu%pk#F4#:uXu8?T:ba95F!>#4>:+AWSqTJ6@&hV8^P@jmj4aJdNLe/#Ze@I<cic9Ed
EylXq4 %=*%wNiW/q1+uw9q4#MIha*jAW5/=F@EZ:@djdNHV:N*hLIDiHe/A*#Y^wk\d\kQC!*d1kaj/YNdnF>K
-Atc&H 000c0f4742700110334 Page 110 of binaries2.zip
j4Y5eM 5Qtwl6HK%8HiAXMepBE&F4DWMLnG5*wNm9$G<ET8C9Dm91el%d@pFYj^tELlWNRV9n4Pj@VXDn9?MVIu
R$1^S@ Mt*!D1nTV9=?K9PcuE@?tbqR9<d1HjCcSM9G#uD=>D#YVE6W=/>/Gnc&aF5#G%6h@XQ6W+P8PQQ>JcdE
LqH$S1 JZtN@dF/Fj%Gli&$=kth/n8kJGDZ8yl\e$wkTXia#@h/j/jq/uYpd#H<TD+AZ>yW<By9WiP6:hn9%\/W
WckBVw WQphIK!<i1CR?eZVye58Fi!8<KaKNbb#pQwhaBPwSJFLyp=Lc?X%dbm/j?bQ8l!S*FX>HGq@?kaC>ttN
8diki= GiSPD9cVbRW5+d/t$<?VD&n^ZC:qWu+J8Pe*PDnhC?\bYS4K=9GGD4ZTu=8?RyB@CTly4G@/ZDJm=IR5
PY+=8t :y#8Znhj:t^nNdLD4c*Y<6a*q+#CSAK:+iPeu9CGIpMS\?Xd5*MDM>c&#9PGd+$@M!Pe4kI!6WH$\#Jp
>Gc<!E SH8bPRuMPID*%hJmhN@m51H#w<^CIjLK$i\R+<8Nn&#81=#qP<B<p5jm/i9R!@XC+n6A?#1H81+1KujI
ZWS$tL wS@===J9up?G^y!/@bpiWS6u<1DMRXR6@qY/uI=B%>$41>Q1yweb*a>VSd@R6K1k$pj%lLbH&?Sakbpd
<99y*q #Z8MPDGZT@#kVMF&Wy?tQDN?L>8y^\FdZmaS9yEl5Fk/Z^+I*>PuXlIdamjdGM@ZA#G$w$\c!p5P%<pn
ABZ\CJ h!YlKth^K5I*LR<ilYi4EWpdR:=w!n:dtC54WX@64%Mj*kFnl<GF9!CRQPBdKH4XP?\IFWm&&^B5hbb1
npmZPC bcG@<4mwj9WPMIQ=5T=^@=$Pkc99MNPq:LSRu5jD:SH1qYYl=/%SINet&6kY%@LJyp#1hYNmJWd\J<#W
q*%@*J +cY1iBLI:l9!BuZZcZKN^F*F14Z>/R<I^6Mu$%^VF<ED*B&1h<By%p?4<w4CE\5G=M<T8Kd%KXBk4@pK
JeybV= PIyki#?tZy<ZwZ+8?JnNH6BDGIhKhwXIthD/j!aEt=@iP?Mu?L/$+>tkTN8iG*&alZ5A=S>^*mCnGd>I
$=$LcJ 9Fj&D5AAtV4X@e#l:t^Fc@T^l!*i<MHSj:M>NZ%PkSbXq<\^:<==\q^6R\6jqhVe#bIl^hcyqWqpnyHG
JiM=B/ SNjQG1aD$>GBw1YhPd>%nI#RucB^@4nc&w*X*l$6?1mK>XH6AIWCeyd4eLNXJ^QlVh1bd@RV%GV>!L*6
=&Q$cF Kb^M%mSQ?pV6m1t:8WPP8WN<1THXcHQX6u/GJ!$CDBi@5!/it#11S/bwAyb^lP&FMmG4HjipRPPMiEHY
#Twcm$ a\#N:T=?#Pawqh^LD<tQG/T8/!%N4yhVJ/F6BQWnBG+#4Awb&8Y1Spmqp4X%W=lqq?>EMd/h5VjyK@FM
utqyC# TG@HnpQ$HMI96N/b>mL>IQH5Qi&K#k>I:Gk/+khpJN!+kY>q8pyCMVau+K@u>yK?V<hF!K@W$X^^pykC
m=4G&c tIq^L&+&ZdN6b9Pp\><6dZ!*^FPZp8Y8t*L5yN+B>wT#&TZeKjdD\@Mmub%%adeTjH9/6T64F@=Qm:+4
T+pcHw 8#dten?<jh6h^9Va8qdi6Ee+MmB:JbZNXKb&FbPtyS+d^wSnZh+B5CbH#8<A+/B4Nu5E\kh&D5LF?BHy
>@Ie4L W\IS4j?49Z<K:@VL%wdSZ&^YdD8y&Lb6&:d6mqNJK4b6&:d6mt%>>i?>iuY@*i@1jjlhi%@4KHq!MQM<
PNapbh e+^:#Du8Mie>%4Y5k&9W9*M9n9J+Lh*WZ?@DP/j:>b5>1/1Ytyma8ICZFtyc!$QL+Jk+nt@Ecp=b!TA%
&EK4&q aqJMcwhyNMi?Yc/bS1k1K\46a+Ku9iyW:q$pk=Lu8tL8=dW9&Ll\6SVYyS/I/IT=5SM%&4ncdL#4:/NP
&wXq<k #K9!WGl1@V4bHailkM*?9kccumD?1*S>Xd!!1C5?keKt4w+#Dp8wy&#bKhhEYAWE*\8#tJ8Gnqb\1tJh
X$ImjE !46nL+^<aZ=%cEt/N%%y&RCK6t>hb=*XEXZebXnVLQne6Cq\Z>t<eaYPd8M<aR!\Q@/c66WPi&n$+mc?
^G%ti1 AljqWq=n98a#tCFHX?yn8YM$H4BBAHKmPb>kl848YKtlP*Y/i#!RcHZP8w??bJqjZjIF+KHYqAqk?8Gd
+?tW#^ V&Ke1LI@c:*n^<nnySC*H=KcGZbK6SE9*A?mGC$46lq?@KL/JIaYHDhRSL1JY+@n$Kaa4CBME%/d!#wB
kZSmZb jeBet#E4E8\Wip%J@Gcpyjh$9@8Jp4%tlQEFCA/<PmFL?RI5FYPuL8n4Q4j+&AkycequIL^A8/h<R8lV
ajb#:h yZ%&F=GpQH\BaHY/&!K^5V%pe<G/H4<A84SS/T&jX>aQFZhq@TP<JQQVd/>YCCicuEu#@Vc&+!W!*&\=
+/+488 E4dtJ$^j1?$5<%\5IQTRhYKjG8L<CwWw@jRYR/MXmbj%blHiqtV=CmY@#^I&^:9RRmbwHdquWL+1m/ud
e$w$\a lk$Wj+Lq@%uE!:k&Hhqy>Kt4%1TwtTmWm15piIeLTW9YQ45LnM$uMH>eBRS^Ii1DWl/%pYD9buEuGc+1
yneDXZ W8M6#i%6Vhw4HIX$PiaA6n1yHlyZE9S?:tTa!FpiJ%je/:>I&d<RaB!%*S:mtK4H#H<BkFE%$eWYWY$A
/&J+!P d1ecHQKNPaN4TEp:n9^H>ZS&8jQ:Vuk41\8^q#8K!$btJqjcmbMcD&mm=k/IJB/JXMcjbNYpF&PmTHk#
4e84!+ XDF4kZ:SS5V4FRKcb@%MV=9&GM$<yZ/#>W@i?F<A:$:uQm4!hNYCwki&*c:8BGPhYebtJh#V&9eRc#H8
lJW\=T LM&n$&8R>jPe&KqYY8:%>JGF:&F5DQ9u64*V<!#L@IpaTqBqS9k>QbWKReK5=!kSMlP:+WQi$Z&SCTAE
w%RTFS Q+J<?e/!+FB/n8A/S:nF>pG@AK:!FnF$mw#i&%kIQXkKBhwAl>$Qa:@&MyAQC=L=1um?k&>:!4!q9uA5
bGZqJG BHYjqb<tF:IcaI%X/=WK+1cn<:6@hk:ZlLFnJV=%P!+LHi4hX^wkTqayVW9JVacub@ISwZ=8XkRcEG>d
Pk>H*4 LXXt!56$5GJ9?EyL<9CXDp+Jq96w5=VcuV=:QJIdNk$LD!bpdCcJ<kGGRk$t6WP!EMWqbY$m\c<LV\!F
lR5^Xj =#a8d94Vdn^:IiL!ec81y?#eN/>1K8Zy!k$lhtaLt@t#WmplSm6b=q#n>Vin$PAMe@Y1n%a4qVTNFA@1
qSWy@J F#>iE91cT4D+CcCSWM#aD^LXS%ZY&ETwbk8dKyKH/J8RENuNi@H8+Sm=<w?kaBXnhq#KjDEZ$Y+*cenG
G\&hNd ^4G!ThnZy9#*&h?y#TtqL+:^C=%8Y>1b=lTX%Bny$F+uk8?MDN%QLbMcu4dZdpY5:1aQtP9RI!THMW+*
QWFA=H d4*5PT1^R:nYJBBG<puT?tJR8?a9/a=+BeKWt@Ee$SlF95Z?KwQZ\lXHLYSPj+1!qKXZ<$!#1lCi@iQH
j<bJTF jTLt:at8jLWC\!i!u$6BjLeMGu+:j+BZ1TVk1&5%e6/w+/&lNWHWlLSGEy!nMA%\!Nkubn>V^D/dGjS4
L$?cL? iJhh8Y\#ZG!a@?!iPFCW$h%i*tAh?1T$&%YwYJX%ilJNN8S:YkKu4k%hncIRTiZA*Gy8?YDT#1\<HN@t
AmyFu/ V>B>DqmMqe4pWiRdDH5=$SGYkB?a<FVk<t\a\B<4/>q??FDZeyeI<J6Nn:*eNMK9SEt?GZ\$@qmMGQpC
GDe!yX JCemm1CML8^eyWnMt>=Ye:M^Y+8>%!%mjkHmK!^I+u>^j&iy<mS^ckY=a%EqME^RLNm^q*Wc*ye/+yWE
PEl*ZR dDywDpFVHcWaJd8/YyDRZQJF^Enp8c%d4%nnQLDkJNeSnqmnuVdTJA6e4HAb^<@kQiRq%M#jeWWLWqNZ
&tkVny w=<w/4a&N>9\5lG>kD1E#/DltMEF4d\8$m1iT/Bq&FWWtqe&bqNiaVul*Cd44EP#Rq?C+tVwK=/cQt:L
I=lB!< #h1i&>l>dnwXN!D!:n4P$S>EF=Qak9B\1hmw=M$WaDXPaFeZhRRi=uh@ZA\wBENM$LVC*AG#:8jk1QFw
Xb:PD6 mTZLc6+L9!*Qm#!uaqqcwDX#Jp*q$XWeNqnkDYHknB+&!cI:uMYp<ta58%lm:W5%h:eyAbJZ=Ml&@jPZ
AG*Nam Y9SRZ==$mbe!BuHd/&&S1H:&WNBLbnq/bm9KiPJHQWDSh1FyDB89/#/!E+ByYWCL<iWWW:!ywG>$&=q9
616CWm 8uDj1T$bL?c6&u1Zc&BD^Zd5L<!c&8^ed\=pCV6IpW^*ZjRuwAKwk8!p:!bNZ^S#\<FMwQqQ?mJ@F>bp
AF+uF? m%!QCZuVXq>eF1V?FKIH=?e*CMXqm6tQyBISwTl$wPVc4QQS%bE=YunR$uCB+*WuDFpd\:cnayiQ*S9h
41u!^t !ZDiPibY\idSS!FY/Fk!hyl/y49J:59e?+Xyc&LT$1=^&NCeheVkhn^I+4FQa/?F+@L/XMGenZuMZl=5
8Gi*8E tJT<9i^I6Q<>?J\=hd?#I%SKcR<KTV&WTbhcqQ&!$%QNPDFHSeuBILPF5FLYn%56#1e$l$!hNIETcMVa
dpu>Vn Eh=16wN6d:TS&a4/dEn1%#JT?I+mn1jmV>1ck&k9n&@u9?EGm+p@Njpq?AyScV5T^IBLYq49Z&mDRJ=u
b9YIVu =RZ&cmeK+mRII$baiBy!+dE=45+Wlt&RBFeJRl@!ZG:NFIMb<Z=^S==$L1c/pcW:J=V5E:<XXWC8^wXm
%>n=Sm >yc=wRNJt>IlpN^IXnMh$&*+8:PZSCJ#\aCyP?5l/IHFdFda4iJiFE>MFHNw+/X?AYc5aHT/DG%>J^%e
GE@FVd yRp1Rw>&=Ik=GjwQawZtm<B$c8IQ4$WLedJZ$!<8XaW%WyC:SPul@SAKLR64Gy1T^?dFj5lJ4bnEHJ%/
nGCEeL KG>A>kGj1uSK+HKyKl$G6/c%FJXi5b1iNtF6=j8RVyV/&K6JSX44CIijIW/J+TBnJI=8Vp5&:&EjJjd+
!>nyjL IwRnT<i*b\V/u8/w+Aw$dnKJ#dFRy+>u4pWucnY>hd:\C$DkNkMnPQKWe?/4J8#L#X%kEcDLl8#4iq=c
k1^Y=q 46ElL!H\H$1Rw1m$81HNpblIljSkD4QMY/Zy^9951lQQZ/SNdR%^AMXe1m<JTwdiPSaeh+>9<+A=Zbe5
p^n5lk XF>WKAB=yT:Sp%mDbH68hTSQjajcDEQ:@tP>+I*i=D9&6#1&pSGd44CTK5@bw\TJ%VS!%ILILWI6K/=Y
EW+1*> G5Yq8j6SA?lJF^5p=ak\@W$Mi+/ul\4#CZN:+qN/Z<&qSj%pe#ydpLEt6BpSHBm@u&*5QRRB@jy*\$ac
uX$1RE TC@/+DTR$$?qe&Gpi$?p/<ae?<HqaFHk=CDWY\uwcY6!LMdP!jmyP4KR^S^1?nXJ6P*5$/mww!9uWFQk
a+F1Z& >J\bT?YmJNQce+ML4#ahe+Wu!MLX9#AAEuuy?iihM?h$^LYK$bCad:ydYc6=hX+J$@mSSAumWcXB$#B1
=T!yn9 wNJlNGW>j9Wcllcck6^DJ=M!S&MCim#%5b1d%HpXw?VBWCBDK^DEYV<Q6ep88<pQLPtL^$F*d6IeY&+h
GS996L yl!YGtJ/RW19P!J4LbhMV+e&=G\4+Ac<Wt5Z99P<9V4IY!djCST9/qt&+!%?L>J4uQAiNXFptLq%mJ%H
JA*E+W Ni8b&hl<D1t5LAkBZZKpV5*dnl@G#/Lt$wk=p&ywtdFn+j1SHt+e+<WGDi8Rkh\VNALB$:+kTX9JFXTK
?FYAu4 eW?/^M\<><=VnMFmBTi=6uWydyCA?RPH<+w/Kwud*^$%^yC$DXa%!6Nu<nEcQ@JKhW:<$m/@CT%i%Ak!
GmIJ=* =+JW@K$kc?Xy&nJMNbLc^pky^AkKl\&dYIRddFnTiY@*ptFRR9TPiQaC#<hA\+d&TI5h:$m%=hhAQFX5
\Q@P%W l@kVm/YBBZ/a>V+cwk:@y=D&\QGw#?XdS>Lu>@dFX/>FFYTJuE$6&1RI1jZ\9DjlMq*%Ij+ZH+/uE^*!
-A8?Y% 000f403675b00110334 Page 111 of binaries2.zip
jIVWi# TN4CYSadQ5WFt\1:9AV?CGVCYGAcw@iMbXamTecGqF#hy#IVQw^XIwqTuZ\l*IJ&:uDECD^8G$W>$JAN
&C>XFa kTEE>myDTDh+D>VGQbn!yEYYH^JGki5Zd6DV8CW9\Bik<A/JWekPw&V%Bn5jXybRLcht56!%5*EG?ZEw
R6TVR: :PR<dR1H4Y18L/qVVmiK>F\B$##tl115=FFGlVbnpX1bV@&QMZJRDddP6@y6LukPHCAqJ!L+5EVJN8VK
%mKEh8 !9HAlYQ^ZRTdI1nnTu9GE6Vb@%c9#Y8T@??T$K:V=D#W#L!KQk5kb#5a1VK<A6&CkF\WN/ZKE/p^S%<i
*KKY!n pFMhDI>AD*8?e^tu5PP>mX*9@nWa@b@46c5KkG#hXwGuA<X84eq$4Z=$6DTF&m46*+B5^=Wh14mJ?FG&
V>KXb! HR<QQVSV54AMF8i@Cq8akldY%kTC%kc&XmaE*G/Yl9>u5jb9FW%Qb@49!WYMHJpJ1WBA\=&kkAnnHBq5
acuAZT i/\/1H%y\nP::lK/E\DJ*IiVL8<<Nm%:#cI!?XDAwlbCQ&S/P/L9iRadabk4d9pnJaZmNjSZ@IViZ9m*
AC/\=p C:A*>P@+:G6RRZq#Aaw%MJRB/eB&k61PtqC5p:!Y\DD8kb5p8\5=9qIRpZiTCWbe<V?lIb5/P*dn/MmB
EQ#>D? eudF@8ZY51hX$:@NKyAYIN6GeLyBtaBb=:p<MGbRVGNntni?GyD#+8*1\68hAh$E>ZMtYVt=MKLy\iPj
Lw!Rw9 /<lm@/kn8&ID5kl*dk\Cp%laKy@cbGDDT^:!A&KqANq/GtH9phdM?GR<X?4Jt9kXehXld9>Tb<YP69nu
^cCY?c !q<lAJA6^u/AX>p5TMlD9mkZ94%NAFqCYkLIFm&<ZZRZnmSl<WXeW\6w\@kh:p@+u<&<DRjIKXhGP9!=
=uwkXJ 6N=d\lmp^!#YIZlpi:\F!DuPpF#=/BkI?bGaklSSJGB^ak<?@qeXESRPqMuV$SWSEhBZwaXj^tLJ*i8R
5W#<Vl TYtihm\J#!N1X>##el#l8kaH#mdcqNZFX?JJ4@@e5u\Ga84?tHCqFj#/6b>E6haJ%@Lp#NlVj\9^C>H>
k+%:=q HGF\&$yM9RE/KIeH@5q*utjQkm&5m1yBHCQqpKTRd!<6h86a*EB?I&w56byuL:emR8yWQnNZ%#Y:hFmK
JuCTFn 5+SC9y%BdKw@C>tI@Bh#L&l\Nn1SR<Dl!=EJGM@CTiW*JApwJLjKyBVXB?Fa&>L/d@&LZujX1S\TWnTL
DiR@4% EqVYn&HPw@HCbbJkR/cMi#6G#+jQGHYI>5JXn8h^cnLQPlVPYa<PWpRI!n1I$leL&EtD#:m/y9kPBB?B
D^:R@W 6$uLaFnDh>*=aY!W\lPEDlya9#w$HQR*C>uIHwBG@V*bnClnj>RSKV&et#W4bbmyc1kn@NkJ4*k6#Ip+
b\6mRC QAHih+n*>EkTeXjdM!^4\p&1=&yVy:e5HTHJkGFp6FN/BEAwE@yG^:8VbWd!Y<*99J*+6\mCyb1w4>H1
wC<\Jd iLmMG^+*FI5tDn$J8&#!=6e?XuE#c$m=naNetL&EECbZV?6dlYYlB#I4wKPGNy<QlR8BcqPB&jw^J\X+
L\AllB S#jw$$+PVS&q+hNjQTP*^dXPdTN>=kuJ/*/4I/G!bjH?QTMlPWD^k1pBIJWqNN?@jhqiIlH1QP6aDtnk
4p=J#A m\<mH#@FSV=CY#b$a&QjTMM&R:%tPAaAA!N<1R>ethQ%kYiwlSkd4Qi>Nl:GbDGCHq1d#F1V\SyAjDeh
5nGl!= N18=jD:wBp*\TaW^T5=E=\I\^u&L/lI&/jIN/e\jYIjM/WJK>uB#diA%d*?L8tST<Z9GbPGAbLpmd5K&
8R9m48 L?+EAeLZhqSuY/:k@$pBRSNB%En&aJKdh&TTZ6lmWSD:SALyyecA&MyPyn&wu=#5*TG?Ebqh\4IBJQi5
elBty* KeYlTFHq/nW^QS9C5V8Z@T=bFmLqblHN6QIph$u\w6bJ$<!y9TGh5J>+j*/*K:9/LK6+*Xt4FemlPMC?
yJ=LyB +c1a:ciXW1W&PX#4eq>$>!Mh5+FGY>tYG^+Lyb4cmKadY&NuKlhha9y^1k@>W:*hwGClny>*T*eIYpS&
FhM:E? Q6/F+he*P$<^td^Tb6t#9VikQGh&GBR?!F8@IG\/FtFlnTNWK&KGdAK4pP5*AWI1bSTIpN<tF5ubtlG!
5i8FBA ^Jp$^JdHyJ/9h6aq/G18WSXy>\!TbJ1FwjkQ=hDeSYKEhS\Jm!FwDKm>ubL!\qbPK>9ah@^h!lJhVtl/
:Wh@KL /&\IS?lRCL%#C=ylt5ZDHJDHSdVJ:+MPiiY*CuL:W/uND!=<JJCS>115VLeqtjP1?whE#b^phwTjlQ^@
wkT#n* hqE#XhQ5mHMCQTY!$B9P1GwMITwdQRG>e:&\>W@DjtB$i*Fm9?WlH:@pb%<=n@iki^>iyPX:%NmX=N@D
SKZL6P @qFB@lMW@l+!paD#GkHb$nj+PwKFu=QEp^LE45/Lk\t4h1!AdP8VX?ePSIHb$dN&c9iTBIcaBdDN9%iR
j#@B5L A%w+@^J+Wd564>QGe4\#jt=Hu=buZuae*6?=m<6!E=8eG+@b&FMW=dy6%e5?kGemH6p&Tc4+4e6Yyy@c
4VZVQJ K&k\atu<wARtT\5pt#BL\:Hb%!aZWMIat&EyQZ^T1R#dRZVya*#hHZmLBW?nT4mcCq9+!uE*Z*NDW^MG
ucXFdI 1@aM6hy1FX*IpjF>6^cR<%Ye<V8<!K+^p^/!8\E>84\n^6WPFJBD/9MR56DS$P?\bCKLj%bC9TPNFk@C
iptanW 9lpB<naq\CPMEH1u\cRVbt6>NlwmcqQNEL1/CF^mh%mlD/j$\V+4WFpq!\eiY*j*Zp%p^$DctlJT^=nE
DVJ@kT /dj9@9lku%Xi/y1MdYBFC5WjnlY\ca%Hdn/Ay&Y*\8h&%Fp%1a?B8mmw8u5HAjLqS49NLhG=^XKup4ad
\lZK/^ dWYkK!eQ/*qQhG%w!Kq1d%H\eMe+utZ&Tk$:5P@u@=dd^#&GBKwAVT95NiWT/IB\ABm9l*BWQ6*/ibku
J:%Zj> aG5EyH8cC+yet@YRC4MdGu+QCRq8TkVNjHyj=TwVVC$IjYV@ZXFtMLS+ZE48RWLw^@*/nMjKd=P@LuZn
#$I/Fl CB9a&NpTmQ&qu?H5ReB6dGbk@V<h!@yn#@>iVqY@L5almjkn!4MBGbA<N9Wn%^T*Q?c9/kT^ZCMn4JY&
a:Gww< Ahu<$cMW48nJLGAplDGp@JnSNQ5E:@?+#^*Ryk%=EnK!Yi@yA\VEhkMKCDXdZjpcZZkCbI+PTG*\+Gb6
WWXPWp :QhB=*4dkA5*5PTABN>5qQ+Ki>!%:XlaXP>1Em<5m#?>ujL6IKdDNV8#a>y@ap*>9kK<5HApG*eYaEah
dF*KL% w^alK8TA/wBjmeA49FQG+H8#jETb*%YTa^FbN?#8CVuj^GbZc!&Z!QVl>BFRtuADA8#:n<NiQ:9E@:HT
@IBYNB /#+CepcG>WLp\HHRTZpDPHNLDqkKKt/8AVqqNcq9KLB=QHKHbAd:G1$XBQMmaj<aJApb*GneA9j%dQEh
wHJmQZ CSl?D=DFMnH@p/S&HJHRy!NS9pdcGpKJ&RYRShYRK9ED=$^!pHIdcTM!eD%RC5dtQ!@^<YCALHwTC4VQ
%ipQ/5 :/LuWG+6T%hc9^J6>&iuAVpLMV6M88a5t!:+jPluH9dWhiZdLZ@6=An?L!d?/:j@TRiNG9Z:9=t=aB&R
/?!8NF 4Rb4+$hbIN4ntZMAu@5l?JE^jnZ*=:6YP#t&jIYQF%bcbq?Rb9p64pBh@//YE6AtnRkLYMyn4?CN5dKA
RMp@LN Y6<w99eaAALjIERl@hF%>DV?5?TkV:qimVw5ByIja#BhFCulQi>+8WBwZNye@?J&9LMeYDq8EDb$qm+H
!^MttW AN4$E9IM4^@@BhwQQ5LD=<G>upQWq!+I>!RBF+K?E*N6?b4tMFpKKlZhCE^W^lH1=6mNbb1qPZ&LEIm$
!Jh@ZY l#?p+&Wic$4?w#w/8/$/J8\c*@5WZ5j&<4jJ>DIKF8^Aq!q&waqnGISK$VI+w#G6QWL#X$A&jmjnSCt%
Lc&ADq \8LKp5k5$!lDKK^^\ywdqbiy?<>&Ju*yjyaI4AwVtcNHk=X^%^D9*Xl5^IR4WK#wG:qi4JHIkXH6*5bZ
\k=DtY h/6CiyC#y@j*8knLI&Z=\#nWyM$R?#jJJt/&Vq%cAcl1t5F11aCGFkZjtajEZ\N$:!qln*m@NtP+RZ$V
@AihV$ 9yl1FF@M5hm=pDFc=ySjRLYJZy&I?$<!JqEj+JEQcVDFiX^NtTH5q+e@>*5nG=!Y&Q*QkyHw5<InuCP:
I@>9LQ iGNZ!:#^LAeCLV6NiqaW=9?tqnKA^RpXK#/M$9\q:jIVSG>?b&u:!!k&huCk^Z@w^5HFZy%lV%bImN5@
c$cXKp 8yta4KSX@AEnK+$E>w8?iaI5JA4IXmqB%k&StKuwPt>M4=@iE\$t<aI1RjpCFhQk#9%Sd4DF\Vmt9Zn?
AnZtBN \*/em>6/5ViIQ!T&I*w#Ep&ypc%E=ST8:d&48wn45=%$K+TR<ibWBZKFFibYCLyq/\#+nAKH5M1pB#PT
+@W1pI aK9yBV8N:tj+%P6kB#SbFIp\/NG=Pq*eamDBXWD+*lKRqII1nNJL\/mR!mtn$SBC>QJ<^j=y/iLi6B8P
!6Y$#n nK9l8KX:4:9weq6he1>nL!:LV+P!?tnZw1X44nZCJcRJSyemkJ/*t^A\y/:t1SPamyEj<=qSeZEE?X%B
9BLe^6 !8:/X1\N9#HtAWl?#4cXG1=S^I:8jA5Jh84XyS6<p9+S#!??y/Y$C?@KBHEG^^%XEci/5qpZjGe$yI>H
WTqDX9 &h@Fkk#CjnKFl*5*m1p^d9P1QGmBZ6*6e!#m/<IHQP&N8!q#C5\>5kqpHAW%RIn@6dD?AeZjWaWELQ$u
l>l/K/ t+6=q%y%!K8u5W:5p>t9L?+GZh?^BtS49DW&HHGL&/&YAB1+WplDX18HC9+4MqD<X&VIW+H=b+^&CkJ!
!N:GJC 1ldW^aF<K9y*eSLc:X?t%V#bJ:<D54le$MBHi#EkJ^N1w\Ny6Kb9kI:#@\8nLLuD>u<\i5&$j:p/>S1T
p$!ERG ek:Pw41I/JEA+#h!*w1WVpEpFSXH^mE89bc*dnR?wNt:@8qZbpc:qc^=A$d<HkN#/y$E8pSLp!u:K#n$
8X\Tp> *pQ&6:WwF9SC<=WcpQn^VKq/dJd^<1<?N<IHMu4wBq&FLd/kN8NjBi6X<1H=m8n<LIw\Iy8hXI=K\C*^
SEK4qI ?9T8W@yYVQi!&Ja^JS>G#B$yLCQadY/ZI?p5/6%SQ^e^9E\EVj$<K!#&SIHhDJhZ8+wYal1d&HM4\jta
yEtNh+ C:SiaDVbDZdqINeQEtpWHI5X>edKb&\$P*cMe=%k>t>:R!9%<YGZThkKu#K%:115th=uJicaXIB96dMe
cDDq$X #iK&@AyV\kc$*1Nd%t=1BM^X6TqtjnC9By9Yewp@diAH=apaEIYEuL!=Ael$p^DGtHldHdy#Z<L+%tZJ
cac!yt qyHTDdTt@@nB4G:M^5J5$*q<!lbn$<Cti4qYMPeiZ%Ql:LhBaCTH?Eq8:tMY9&>EA&Syj5/alpXu<uP>
WStQpi EbQSDVu=Blw!59$iDH^D=Z@D/NB+&M$WQ+SZE?>M=kcdbF4<1jwWRMM54h8HN<<$1mZhi?9!?\FkY8HI
F?4<lJ j#mP@SjRAFFbu!1*TK?jcAuu6@nBRdX%A+lmGVPc\nZ+k5%TYekyED%FSw#bE+a$nBY&p*H:h/V?m<a#
e8X/4b GM1XDQ<WdL%F4#q6>>pJVPI*TL!K=/c=^udCuWkWe=dBb/Qjc9i@R6Q$LPHAHE:>t9#y!5jGZY:%Q1<F
&++yCJ EPWZ1&!TP$+Eb+!ZedK=RVy>:1t8L#\K6=NHLYZ1$#FD%/!=akTJwSPS>i%R:$>\lS$YTE%qhDSeWHMS
I@RpbV 8@ZAP/W1MAWh=WH8D8m?F$q6W#*RkaQZ?/HdWJB$S849RiZIH:/Y1cBR4>&YYqYG\m^L%Bpbe=4dj:hI
>Ak/Ec >!<?qn*jZ\6D$dV$JMNCnhcl4IuD:yjK@^HewnZeADN*t=SCTwy8NH9^5$ua1pIlZKc?$DQ\iQulkLVR
-A^JGR 000cb8e9d8b00110334 Page 112 of binaries2.zip
GtGJ@y Sp<iETk$udP&uGy6K$Wy9V^%k9\Ccubik<RjNMjHd/*D8l6uYAGFNKKhw?Sj6BH!XE9?wa*\h=BN:RN!
BiEjmj qlZql^qqwq#DV88/M>I:B!Cu*XAAPTH^iIL#qXQ&a?J$>HbeKDDw>Z8\@\W!65DZ/#<k8:^mtb+$kc6A
AI+\:n &eTa!1G$jZNEQI+\lyjCcQbG&W&SS8C%Cq<^SbDM^tXuH\E>/+qG/!+jeuj1N^dPkklLY5nykpJYwbRj
M?K$tu cb?KF&?Jm9=cuiYGqHV1aS!?/pSWViYqQ&:TNYaKL6^IF$4$/n49HWm#KWqCBbQ?^BDI+w<lG1KWZ1&/
mw$6Fa %M5m6:%aDyWhChj^!%ZimV>k9GGEGbeltE6/&S%j>W$#ciY:</bX5G45ZHWc1ibGMdSdR&*iZJ%D?^bl
X=JBdn >PB^Mc%8HWk9LkYn:mj#8BJIBL^?>1y!qamNi4Gih>ph:4t@6kNVKEtB!G69I1Byd&VhM1ZJBC8yycMq
DbyLb? LCdAjy%m+6FXX4k:epyTYwdJP8D8JXL/I1jXPDbIW\A#cE8/d+PYVM=Z%>A&C>E<!PBKeihpYXZ=w@SX
#aSG\T >?Iu//Xl#Z91SZ6Epca<Z?V9LSj*4li8aht5umSttJBi!b&^JaMy@ZHZ<b4nGnnTnE+p#\4tCkkY48=l
*GdlHb &n:ScQ?RFaq^Tpikw8MGy4?B4LYGhi:*?cQXAX6KDh1ZGW\!#YA4BtGlPTBKu+1TTMyYl&\b6ha\5X$K
6pn!KY >J\cS+:ykI1ily*N#N>4aFda@LkH&My<clKN&abSjlL@h\a#1l%4=Z%1T%Sk#/+aP=R*DyQE?te^eKJQ
kmwA1E I@jd98n:^XQ>euh1nAGDTR%hH%ktteQNwIdBRXJ^8cWPt?HBWnn+np%cpNkn^k%VZWJ#4Z%an=8!AT=#
>YIMC< 9KtKyWGA+5TI:FpqV8Gt>qM8+NH*iE1K:6an&l?HA$HPte%\EGup^HF4b<DT9mXNACca!c/e85T&WQq6
PLP\a> Imc1pNp#AG9:wHi4INInHn*K<66lWJWH?ai==:$R&6HPq#6eh44%@5HmM#qI:mV5CVHH\^W#9P$QSECu
>CFI<u <m$*k:8CT<ZIFcF=*AI+8@Ic!/:e#?4Ahu84iii4<RmkCXPZ=5tbH>XHmyNF>wiILXMwBp+&<4FewuN@
qcwNqA >u/NlMaw>l:>T\@H*+ul6#qVC!?ht\4$DY%kHX/dJ165R%EFJKMdbn%5Tj<XbFwbj$C&F\L+b=BbMRC!
lIhYBL PPnQP:=$iLC\nH=%e^l*%pH+6FEC5pnXeANHCX\<aFW=tQn<9dMChu@+@^jIPE#<@kLbFNR\tyKDM@WB
cZ5B+C 5=8+mVl!IwVnwMwEjbBRk&CaA/ni1Y1C$ND9@pl<WkKk!<W%A%bnY>@5Yw+d@B1NaDwJ881db?LFiXnX
#8NG=p lS?#9/P<*<i#:Kj<qHb*DiJ$6d4kZ9J^P<dSJ=wcIC!B4p>9@JZTS<XhJ!YZXTmTQlD\4<bb&iW$n&>!
TM*Hub E!t^^<Mam!8qJAD</%C^RPHWLbw^5du^RP>#tu1e^amS6>$?Ew?Cdc*yd+jTl<chcLZY:Y9jTKw&lLYa
Gwh8Y9 ^*yS+lWcbS!G*@4&?V/>n>LXPwYIkkRHw?S=aFE8BitKY4W%YEyd1/VBw8#eamTtdb8BLPa*JV#qSd%8
DHTDT! /l@wkPtC*?HZ<k1C%TmqZ##>QL/%IS!piCFc&eP895w8<d?Zw&kHdhI=Th^!SYYXcV<\J%W9+pim?eRT
bajmGy 5l:timwC9mj:&Pwa?j:pNQyt5/\1MX&PP5VBQi5jk/4Y/qR6pP!L^nB:%mpb9$^Eq5yZ^*Y*PwhV!kRL
5B$\Ri K!BNuq?$4mSjh&dPt&@q>#iR>V#lb*=VE4un\$=WMG\PwGtXAmai\:tuYMQFZy^5Vmmlmd9>1YSRXyqJ
9KF*9Q BlFbqFdGaSnl^Nl1cwlG:JB9PEFG?8/K&j:cdk5V!PliNSH#&E@IHVdtl/85Fmyc$A@^k:P4*pc<14#$
LcnEc: b><8QN^W9lJT+Vp4^VhudD$$Jw6LIdk!M6kLh44kF@$GIB+&@SD@<*HXZ<nuS4=P$dCPN&JQ&FBRSF+B
B%c</b GkcT1h=9A4KT+CC@pqB#uZB+Fb9e!R?FcTaWqN&DnFa/ThqttD1^TmZ6jKW4FQE$<A\Rmjj4iI&/dKRc
Wb5n%B !WGwyA?ule+T1aB9l8dFp5p*TY=9APuNS/6y**9naZ%6HylL\%DwPi*KNLPdd@wKa8cjk+npYKW:E5Ta
9I=@6H YaheN:F5dw+*a%TS#l<F!Dq5Z9u<9DpI#NRKZ+IFdnI>^nnGZKpiZ1kGTG!<e5nMCZG<$EV!XP@tBJCH
ZqP14N nN/nW4hZBmB<DmcjPnC#B/\NJF@<^QYS%ta>Bt:e#?B+V^KNF1y881M6wQ+XbH1F@:/T>SRBeu4>@atS
8>S=b= :DXe%<L=6j/pmCLYKd&8kG\B@G8S^%?M41*n<b?dcVphTF<=eZ>9VeNcS+WEC9l>ejT%eVqL>u^iy#el
tBK:1J /$%4FyH5:Z8Y>YRq:n9^qcIZTXqWFwtVa+X#dK<?Ytt9+w5>jN\ceZ<wIatLBT^t*5wY:6GqASWuYB?H
AL<wQu S<H/5=S+9WD=aalL6bRcda%QdX#Sim:?l8eet1mnFlL99Jyn:NbV6Vy$DR5GlA?KViEajlBPDbD#=YTm
A<*CyN InKqKMjX:FZbVC$TIpI4LkQ!TcRNl+$*X$a/AlcjA5FJ&TC$Hh49JjSNGZ$\#!Xpdp%XRt&eZ8AY\iL^
n1*^e: :Z5+qlL4SWXBJSetM5LLTN%<nnCJ$8=#Q\hRhV=yc$>cNQW\c6m<dMuuJTSbTN1+>BYuM^9HaXek*%y#
nQ$+Tq EVTHe1lVRS@k>w^Xt98L%*L!jPF\uEydm@ERFDBApJ#/pHQRG>4QKM+c8%*WPFYFeq&:il&NB+>$B58%
>tDWZL B?b>LXYnqTPEaL%%b%/FVjXC\S?:SKb\#RZMHadA/+&tAeXm\ltqt#XZjuBkuI&HIlZdHLc\WYZ:LjMy
bccBE% 4SE8e\a9uDW:FRyI%M>HNSiXXj5i61/P?eIiV6=NqIHtEmbQ//>dASMNZ\AAuN*@n!4JPQ@94aD@@:kX
ShYNt? eNmEwGt9=^qZilEJ@L4pln4paddk1:#V\4#VemEXR>GmddwtD%pe\t#+I>\YnA/eT*FuLmBYd<wjEh4N
Jqa$+1 >4:k#*wpA5CX<^8Kt68bDiIH\@FTDPFNW9Tcl+*KWuY+E5%66iL%>*XYRdkR?AJ\?>&eW6VnynJKuu9\
IE:b9M =bVGJT/@1LkQe!<Gk#R!IEP:A/h^qDiq8R^PW/W4XS&^+*@+>RWH1@VeF+NC%JR9w<t9Xltd^4%T5Fi$
lE/#^H b&1!^/^e?EQWP<tJ6F4CJh1A%L!Z>E^LF5JZ%QPqHCDL<q=bL5TRJLMT1eD!BTN>mBhX\LMT4N<Z<HAy
VJ/?@Z HR4?tyB6^b#G=ZGR\nEXC4cZ$*dtT$JDDheI9*<9nTcG@\IW1me51YC8Pb!C1SyMWhRkh6#C^%l^H9=w
J%*6/q NV*Ii5kqY6R\\n!RX/SIw*IN!wJDkb&JeqD/LlpNJytZM=q<@?dp=BwQpJYV*t6&+XFeF/lhKeM#SPB>
F+?\K\ @kA<jkGke*QJ4$keqpP?AH^J?8:Np%M9nL!tiPPB:8<%jqkF=>yEYWe8&?FZh5jnE9/!EBljkIjFH?ct
nh1AdR C*=8l/pa>%S<lcaY4<ay#WkC<J1mQD:W1<\/$P8TDiy=&5&8^ApYnW/=Gnne9Clhpi5H+cEGw#!i!8T!
p^M+*/ cSQIkZ+5upd5:@:X<k^PKwjl<PJuM9Pa@c9%i89nd=$y>uB#8Snj948CLLm>#wjWJkM^8+>qy*4$Qn*k
bjXa1H X?@4pD#G$@dJ%hkKVdheKYM6un<MBS9*&1iHTWNAYIB<AZDJMm6MYE#NiHyn+Han&Mh1L:tP/pndyAJq
akEAAt b/1#HGaYG!N!4WdRL$WQmt$ly/lBE&%XMuaTJiyRXA@uFcV\MW5>lqE8&pNEBlVYSZlF1A/kKWN?WFH8
=QIZS! lilTCi8K?qlC5uW\aFwWRl!P^ekJVE46<&B^SVMWm4!MibRlkNmD8Lyj?j9WQyR\y+J!/m^E$d8XZd=?
S48&HM AX:LBX#eH&^+%ZH9ZC\q^#EXX8I#QF$?4FS1>4$&By+>DP5pTBjK*&baT$+C:16FXEb&%NB*Sp\C9Z+d
Anq:jM a1/MqWH%kFV4*c&%uTB@auTMXF%M<RZ*mH<Bb54!!#lb!c**RbZBBDB^Lct6Xw>IdWEF8p?!HF:uL<uX
EMiK:t =Tb9u?:LMWZ*tIIGnjS$\nyDuwHBnGIh^S+G4dlP%d#TpEAh+KNGl9uGYu*$YA8jGMit:HYkkIAk!B@&
ZPS/H! =/8LtJIGHwk5CLWp6F8Wp&w1a<R^MD?N:8/Q+#yd6e4#eVSi6KD=&mAEHm1q*wdV%4TTZ>Dal=PLw^L5
j!K#hH \Zu>5@6K#b6E5cW!SS&X#>j^=Emu@a+Xp$a<$jP?AM16q&C/DdEVi!Z<jI/h#=W&NCdZQyc1B+\e#LiV
RWLWVA eSSX$RTm&uEW=ajp9\/VjB8JmpTkY$1X:cpWCd1LPhP^!#Zw<%Si6L<AWDn*XbJiQ#L=qK&cVVZR9MhG
4<Hi+D b\J>:ibbFqhE//Bta^m?IW%^S9pSc*CGlK%dZ\HHbuCiK@qDCA=<kM6T6YM4eY=!nn$\9%#TRtwWAStb
d?HK?Q +5D#Q8$+1V?6\W$$LbWTyqqNDp<q:=t/p65VFE<AMECN66q=^NS&T=F%mIALjlKEpM<kW%6VkpKG+^%@
#8qmYE Acw%=%ZyJI@\Ik!+Ea<<aK^:=AeT=#MTXh+q1Fp?P1S/&Kh*1HN?ud<AuW*JKX%yh$iT1q<c6uJV?jMG
WjQBXF K^tJ/wW:4<<dRCWXJJ9cdTN\NA&%K6$CHGaRGdpT9ICt5c&tG^45G?c$PK>JS*9*&Ytuh*ZD4NnYKqHa
IptRJ$ y*HMC8WZpNqScpHa<#V#nNA!y%TZJd:%GLedwBdY+^/&dDkM/=Wiqil1$:=H&Np%&lkqEyV$Je:wi<H#
e1$^@S aaYyh4b&6u9beWSbhlPbRWPSj\GYXT=5EdW>5Q&e9=t@9u//BK*aet/5wn$DkQ\lWL%pBQFSeWlpkMWb
>W=:?h EnmG1#*d>j&qJGmq6+at4G/l1eTZD%BWm<TIENmHLAWWcCX=1KBcuYSN$C&n:EtX<H\:?dTX&c!J&qwN
:GX*:^ 8>9hDFH5JiQEdwu9C1LmipwJk8J<1GkXC8L#+?$b^i&E+q<j<:T$q^KZl14>1$t>wGmL*&bdZR=<q5nu
65=XaK N>mPhVweM#!ZW=<h5lCRmVESC&wd1EAP9kD8*:+A*9EZGYy=aqS=hwdAAcM5BdylKw8BF=e=YYTlIA!P
@JjtDI dIlnDC@^&Zw>!@l:H>dc+4VC5JMbEw&?F:c/:8MT>SqD66=LT4Gdej^<m1J?$MMLHW4=+#kPI\ukm4K*
HXq4HT /Aq?PK?LZA$5WHcG^&GH1R&F!EXL5mn+q+<Xp/=u%5KJ5hcL+#cTWLR\9RRGu>PYS>=md1%nIQ/eC<$=
J/RpZk ?c*nt#46*LpI=EGV=lc1b\+WknqlTlp^thTw8EIXA#:9B%=@*q>cVY&*ZSX?Gb9Qhj?AN?PYd:4RNGum
RM=pFD qI5/4h\K%ynbQCekKtD/YK$C@alQM>b<mGw\@CXcJea4:Ta&5SDq?e@e1/mub+k@VEwGK^M5nKaFT#C:
ZC=e9a GCl!kA>Q#Y?+wIIc5be#:HM9FylNtnpLPhLSENJA^lHdTplC4McIKVJ<Abc1/4b&dZNmqPF1F>lXMRmR
?ju4bA 55TM6K9!pd\eDiQ#@iVh?VS@P=ee^aw$&E^M+^BVia!ePn\uC9/RHZdlKB$/e$lJHpbGDVFSt%Jbnu>i
<^T86h a6uMGCId!wyHP%$Fjd!9/6w/RyMbAQ<CaBYY/IniwNE\dDY&N^&hFmTHEh6PY8L:$u@\a\^Sy!/bM1aA
!+dp#i M41XjqP4KT@eZ1EaJelJD1Zl?N<BC^A:VFFu!X+PcyR$nc*JJ1<q>W4AL$1ntb#FYq=Y:pX8pecRRQ44
-A+&BA 00045e1100800110334 Page 113 of binaries2.zip
lMTi/w W%\wu>9a&BC8&?aAP&1%56m=u&qS*PbQb&!pW4+8QJwhqjtc/XyP@9C?4=CbjJ+i+S8KNLc=lcbekehm
W=SitI !6b5S1!R8%CP^Tct<#4aT@?whZY#RTJ/bCiJujkCTQcuWb#ERDi$+XLS!am?btdA%Y\R5*NJEt:$9CJ!
e#8@W& ?4KMTDt=qPLYV$!nPVV5AQ9a5^e*/A1GC5VR<^dMuK+dFTY48Zl$6%\%GNmXD=NE<TQ^eui<D:mT#*Qj
TQNFM< n?^Z!*Pcj#MMYQFNPqSNThAT4^8tFtJ$h8E:Jq/=$hGJnh:mlqp*IM4iD>:=FK5?qtXStlP>G>@p5cC8
+P&BQk Hnn=#u^Dh/Shn4<uFD9ZY9=BLB<9TV4RLqeFbwtQ@95!W1b@TQ^Rp*W5&^5/>lP=E>aj:tT/PP+L<C=n
a84$Pk 91GulGCt!tj!Me#K#W+dpCDWG5%wR#PKkdGV6hjI<l*=JJ4kFnc^>FRBe9nnIdK*/\b%aQbuIHMAbC?Q
S<D5mJ %6*Fy$jFNlGL5yXWaTVdpR#Q*NdT:pI%1jI%$@44J??>?6pFXuC:thQ$hQM:Nc?kH8?H^KpqJVyDie^R
V6EnDF <SyZYke8G#bVXiD4%1EVdJtQYm/?k1wNm^Xw+uGu9>MZkEeM9>JBT?YuGibDTi#qFJiKq?wEul=1=V$Q
$D%JGI @mj!BV!SRuYw<5=F^Iw9KCX+=F%W+mSKb#u?k5FtIy%*D?T^?cTIC!E?BVjDWdFAimm1:wWDpd@H6P^D
Pci<4^ 4NKCH\#68n<1lG$n/V\?Le?KpkEP?X!tW%Rj$?KJC>5dcTkHBHE#C^aZ^a5Ej4T+enIB:I$C$P$e<=@y
=Ph>CA +ku9Jhm@Luwy=mqSpZYW>j%y4h6Kjq%EC<:hhZ\TGdWd^9F8eb=y#/hy8<WPHpl1$LKZJ>CGk@WVHp+E
8%?b>u @:ZPI4XB6CCGl!I^/Tm<l+Q*9wKSkn^Zm<R6L$PMl?plL*ZC:>>P>DXSa9>*+*C&ub6j&Ew!GGH%kJ^q
ej+Ze/ y5ka5WZE#ACVdA**S@K8/PZ6NEBP>CjPHn^$Li^X8mNKy&Y55^PDJ5l@4kPdBkK!jTcbpl6+DS8#99pq
F1%=#L ^R%WJHk*K*+D=AS^XD\I9t>ZVu/WL:a$SF8M?/@D@XWHJla!N:A%NmARe:T#5!HkN94dp=:bZ$@@W?PM
HCAb1C Q>u?9*$EZn+k&@hDRl&Ey<@R=nB^<PCZ/pSBhl5tIBQb*w94\@WctX>GcVu1X!\>E6CV@u@?mB$GRBaJ
Q@#=J> Xp?QSnKqSm+5Z#PP@d%T4q=XJCBd%Bl9+\iSL%lCQ8cZW=YMwBQlXj#jG=d?ic9@qdQ?@<lb#=lLD:Wh
q4Vncj hT@uHDTI>GNG%>BWQ\k=QH+5Wk?GiX+PwnKpy\Yw9#Euu:Njh@R+i9+WPlA/pi\CGZRS@T=FYEp<:P=>
jlqc<q e8T+A9<mDEjbHjCnu5#4i?RWWN@8dQnm5$YF+Mq\*5+%i>Q>VJ>@4HD?R5&KSXBNj@Ze:#udSKqW+8t%
cd*/Kp CL&8b%H*8L*d@R5m#qj>FFPE46aYDH??yKbA#$jth^qt#Ql?S4D$tRpZnlAJitdHjD8H4>6BWb\%FtWR
+j98^T &WwmZy8=5Be/eHyWGEhj8Vl\6Y?GiMZwL%I*SQaBPG8Q9<88LVETy+^VY59lMH%!DWDyK&<mnEptae>F
^\F@ZW R$5Me9F@5S4I@*#?Q@6T@iWb@?!1u6TAuEWpCPEp$B9HZ%bhpNbb&DKWeHiYkHRIqIXh*l&yIH!dZBEb
9dTZ*u CClWh4JY/:>VZFZtY$mkkB:S@JQZWdC$LJylnhWeiH5<I+VuJ5Lk&ydAX=yZaWJ+t6h&y^8NNqt9cSdb
E?E89R *S>tn!MRtBu+jBiy*B&e\JlBi+WV+:Wa&>EAM%!b<\?4#kZ8BjuNkZn\J:d*4c+$!icn:$bSwiiqVL^C
XiI!4q DQe$:\ewqD^&9cNmtpX=DYAJePIAyi5VRM=ZkTbtGk<DN:m!\*yHtq/H\d^mKeku1\HRnuKYq65pptdQ
ACTR^X m?DRlC%!*LXJB@S9a9PQjia&JlV%5ahQDV%GAu:c!YCT@F@FEMQL%:y!<i6:Q?Y1P!iajyk6BecqDW/@
/$pLcZ Z=*?eAyL\:YN8%*a8^nS^aiQWRC9PipZM?LFCyuIChb=@^FR:hkKLD*DD9t$MNlP9QktQ5X+C?eI<1YW
ZhwaH* HbG=1MACK5!+5P:j!4ua5B:qW61^>YaI/9M\cXClBMiGcHELlMhD94bEy^8FV:luE\eG4W5?!P%ntLL<
#8yMj1 AM/PPW9lG>i!e+H9WRTEQmCA**aZHNK@5%Aht^9KMYAk=Fu98ZMb%+Hh*yeDiWSbaKD?R1Rh/aZ8*?n5
i/cH1R 88I>JFja>hi^JW=bE&e*P$e4AkEuJ#5nC\NuE!eCbXpqAtELX\5um:?wVB6:c#5QE^MCISNHb\6VC!MD
?$VTPb =:@?LGZm<c>KYibd@^*m@l/YquaAPj&%YlKBehXVdw%9VDb</T:$Qe/=kJ^kk\mFaB&YAZwFTQ8QNCe=
QIhAHd tP=e#Z<JeXYJw*?NXhGPJnZ6hC:N\\ZIF81pK#&uthM$>\DQdaHbJBSdYDpFbQF6Ld!*dtNL^/Wu$wb?
wXE9PL #%YQini<@hh\KV#=%%l@Q$t$HAdImbtbtWRWeLnhhpJBwXe@J$tbw$+C=N!@tH8ualLKlc&CuQDAV#nq
%+diY: Z4!E@Le\??QCZ$I8$B+\!Tt<lWwC=Q6=wuZb\dGqn/iSdh&51aV&*/wi%J:1pc*6GX+T4yG!FPiyEE<6
=QZK># pCQJCW6hh=nuQFhP@QwHq#p@e8ID%mLQp*NTY51ITq8Hc#hmQD>#l%Ce:#E<4F5MlWdSpaMW$<?mZLe:
S5Euc@ aSQ>aR6i6n^X?%Fjul>XDL<L&9#^=/&VNwTI%P@jPHcQ5%8?K=MX@5AHBb\8G&mpLt:Y%cuIh@DDpbi\
yGZ8T< yH>Fu9A>6HNP\y$dC\R#K9^&<WHIJn>n@iqK1\LFQVyc&Ne>V1$au^Ey<MPCZ*MY&u%yAd<YD89aq%Cy
^FbBpY =IK$c^i!=@V/eZDDk>CVPtR9Vam>DkPm>i9JYqbpuDaeeD1mHwR:PVJ84d8cZ6<1k%qKAA4IKVNS+6Nm
^4?pad 4TD9>TJ?t=MjyiKJMXEKBK%M@!diS4RZu6uH/l4>jhbejHnEa1=^#CB+%j/^:Hc9HWZuVZdG^nLIdM%/
k<SS%< #/qyXd=hYN^Cuw/S9$LFe14:&TGej/$XG*$*tmi8dQj#iIhXSKH=$/I8M&yeJ*AM\un*aQT+G#>XDAii
E!+4j9 Pj\9!ube+R5AkIZ>Z@H9@/X5@>?pdE>Q#QMKBCSpC*JAC$mkR&<95cuN5n^RpeAq!D1GB@Da&45#<&4n
l?R:qV K!>/i/n:&b:qIR4qTqi%ePVeaM&/nwH48*jybmc!%BiIS>m9a1e/Rk+6Xn1mhGIXl<pTe+4%ij1&Fi9c
VJ=A?J 9kAKVnnbq#W5=tyB@h^Nh%CE<jELB/n5%j#Z$#EhV%w<!9:u>wuPEGiT@X^yFDlSpT:A!JGcDQ\DietS
Pt<yXF AIyBYlSITc5cadylIFGJ+tY8@YmyN::?8nJY$lbi#hi:=j5eiJnBLwIWnRWhScFH>Slmlbt*bX+WN5t5
*:@&ky NZ^YwT\4#ZYyGKXAn6^Sa9HieTMpI>#ZlcLF9m6hEYid*bYX\Bm^BbXjDRLAaId1!uhyXN>Ll<<JHCqd
$j%^t& CaI!%KR<CmmA@QEipy#$FTV8m+yTGR6tV*!lq?DL<<4Gi1d6d6t++%iYSZVFhn:pV#RZ#LLy:DbH?PK4
<F:#Zi hXAtAmM%KaAwCkj@9LwtSR=\T*bEDbhFetLA:VAq*HMMhXPX%J=\kDh4mSLZpc+QA#?iR>EhHbickttb
S+&cCR 9%tl+&QqkXc1R:JSCG1?nW@JQ4Z6AQ^#TWI:b?twmQwbWV\>Aq?T?B$+#liAcuKiLt$ZIT%E*ZXR^58S
!c%%T/ hl?&N5XPRMHI1%^dK1F/4ccS5I:%Xct\i?GayN>e^e6albl:upuAMWR>l4Kp5VTnKC6EC5!miniG4&8P
KDq6Ek R1@KcpMbMijdCP4iJ<+/i1T%eL=n^V:^m%1naTN:Z*IpBTA9pkKI$n\9AM^^G^E+E\APiH@BV*JStZ/i
qqT#:% &y/iBe:KMpZak<^N\y*t4G<TdST$q/#mj!4Nci+&4DDS:^+MHiI+=$$m@TuIAyYXahy+5V8/k#X&4G*k
PXAKK\ HKpkR<JI^YTe?P1%GHHMKC8Q+*B:9JVVL94tPbBQ\$EYIVVwZCVC=apMITqcmtwTyGABWqB=?AZAk\V%
+Y!eS& wRlFV+ZS>6iSk>N!:Pqq^<Rw?$aBCBnpTl^hGJ<uFLtl5jWpSBli/k#6KP5DiS#PBKJ>R6nZLe8HbqyG
uFLK6V 6elwSK%AcXBRNpbSEAGR$yKmRG1Gum=l4:5%b:KJjwnITQBQM*a&c8H1H5%C4iN$tFWl5Ll!^h8teth6
n+H*ek QbD@wH&QSZ#JL^\\/Ed1@W^TkGdY5P9W/J^1e=!ytl8quVZB+KwVL=chc@iwVID5uYRlmDPPkN?YXl1d
#iLMi& WE=KDX5$b/=%lHqI^k*Y*+@%LLT*X$?eK\lSRD@mMFC^%W:1Pcn6KWWy#F%\X^PMYlM1tSyMHZYJ^ZHb
K9DN5u YhbR1cD>HC%iZ@<CVFM5!m&nGncKjdQ=ITWl\kAnkmIQaq=Re6\c8Pwt^?#\9d\GBanY+Dq>\MGeNeAj
h><\pV \aEe1jmBh^H%Kiy?BYQRHP@Sh^S!@//c>+d&a!t@nH6b+he9AKnaM$RlT$qYwEVq>tp#tXT4h%<^FaM@
QG\8S5 d=IL?TdcnlYjYAMd#S=l1wwd&GYQ!/D8G*Zyh/!H$<cMJ$:>NJF^F\>E+BXWt6qj<=TE9I8!tJAaG&w4
STc<%B <^5*+&pmh$k9^Winbat!QcpwZ+D!A^>LWXZZXR#8y*LYX!9bQeTRu<B/K+al4h?X11?9jq!+BK8dEtHH
8@dnpP ecl!M#^Y^ZT\BAqStJC1+&%Gi+wt:XPd%DjLTFLt&9l:HDLGZ1ZN@yKp=eJX6ZCTZ>jS&lIqdWwqE>4E
nXKwIj b1EFnbqECa\E:Bk9iw6X<I%Vuh^<ATAXSn<dia1DXa@ptPSd$\:dL+$m%%nDp<>CDq^+H+4N&jk46%Gu
REMD6i Sc5ddLAZm$eTSZ&!am$5\m6#qBWYApdj4cJ8Q5JYH<!QXjypMI+*:Q$KQbWhhn/5Mt?P$yddKBNaNl:D
L8P$aB J9djP8Fe<yP!dI1&yE#eeK+#8G%cjV:K=<@Qud<ATP1pH>&ZP5<?uip6SB*V+9Yld+w^T^1cLN:?a=^+
m^cX\N jY&dXI>*9e9YCWE<GS$%8E+45WIK=KnWVGZRTtH6dT^X*MRP:XRS=G*bN&ZFje5i\/6y:dl<Kw$LN5mu
9P1<*e G<uSH&IE4%mN^$Ku9Bu#B/K?T%KmMaLVjekQ1epMG@A!8y%%ndQ*Z1tG$6bSCeQqiI9%dmXct9##$q9c
4X*Veq Xw8^1Q%Yc$9=i+nYDY<T!QQ&G?4/*e5#<m?G!l^H:#FaP+hDuwtVut+lSDFu@cw*5kHL5ACDDCh686\<
W<HqPT dB+iP=MWiDQ/F@eS>qPBc6H4CX/>5HQ?K:!4mWZNpekE^ZV#!bd4AaYJPR$y&w#^EZM6wK/<QB$69du\
<RlKBn N$$^Q?l4!il1Hi>c&Iyk=#PN65KYnSc<l&m^WV!Dii*dY9D$QS<tSRQpMaNjZ+B^T6H=NG1!K:GtV5N1
GMPi4b DLmwWF%IQp%1lAymNaGNNheZl=ZFD\+ueB/wMn6M$Mn8w6kPun96b#HLbLcB<y+cNYSqdFZSPM=RNY^^
GCSER? H5n!:@/a5RL!aAS$uwt/yWi@quWS=:uVt^8c%C>N6e6nh\%Glw5JXIVFH*RaNIW^Zjwy#@5D?VnQcpi1
p9W6N! NJuj<Bw>LL+ANEhp:tG@??>/*/*TWcySqu/j>LYLH>5$R4&Vq+e9ytqS?lyl*q<>S%:S8FD#!E:w4I%l
SiV!#C <i&SB+dN9KwS:&$!c%5MuWBeEZD\:uecQ?6PZX=Nl&6L\BZppPS/nt:ndY6T18yPy&c!qJTiN4Pt!>5l
-ATeqw 0000905bd0400110334 Page 114 of binaries2.zip
:4%<nQ u6GN6XjR\lPD&q?hYkp/Nm%NEtK8MMW14V?WZy#9%weaBLIIK@Tkw9deXhQTmwuFmZ<BL18@AH1wR/hi
%h4:6e tn>1ZiXD+4q?1!=nKcP=#d:<RF8&^nF=#X=IY\lh+=I!%\>^HeaKWdlRuPktu8<:I8XhQGN#GyQ5w/Rb
WFBDZ% lN^HFZ*:CZlRmP#IS+i/hFCyukHKP5A/G9kC\KZQjBI^G5uhX@nXm<lljZ+B?M=uhYYtJRet^<Dj+ZVu
<ZDe<y %XIi!@n/A$daJ*Zu%=HF8^cd$CXLl419X$*WJq^p<#taS$XNMD+j%GPj=B8K1\WiTl#8cL$kj9G&bmPY
V<A<Ah m%B$Sn58XZeE9I8:G:\+Qc9JcGkGq59&SIXmEC?%*u^Qyu^J*%$<tE&5RQFB9kkAp!aJPqQlb4K5?j%+
4<eiL& KVdS$?ZdWI&hCj:cZ=H<i:c/XN6E:9C>dP6Zq&/1DTdGkNV\41=#=\4:T%cpt<ke9IPKNWK&F<8!Cn^S
d^!S\a :P@m:GY?JApQn5nJVa/j:?E</6iWn*E@#ItCuY1A59YWqHBSB^=e&ZAhMd\WAJ8&QKZujEpK<!!kca?u
*=!hMH E@=a/D%+?W8hBS/5hBejy>ti?h/49<n#eJb?9Fel=KKtPL4yMb\:W1ikW!5%P^ZDaW<hC1/:ii+wTI:H
L\4J+! tXhV*CQ<P=>ISjVj6#KI\K8DCd?698AGA*LGYIPR#kunV#@NI^%%abWk%=6Q:RHbXnCk%hwERT#cS6*c
4&STS: iJlMS&kEwT:@ta1#RRFpK@8QVKDKBCuLIa1E%4?L\nZ#1ARA55k\TQen>Rk/Mw%\8>Rtd:\Nw^Wc@?IV
K%@<u= <iZNLc\6:AqpDb#N@&yMd@?*^@>dm?n@R+M=4ACRASq?aDnDhaaCn#cDZc&bd1/QDV+K!Hu4VNlG\*Jt
=%u@/B 4lX#hIteLaj*+?+m@=ed9Z>!&Z?dlVI1RLdDjAyG^uy+a\Zh!\Ge=uMqWhqbJCCLT?$+*\S>CPMdKH!F
*NI9Jy !uE9SA4llhN@ukY>GEDP>a\QC4im+SWNTaJd46Fpa!!I5BWkm=Li/GiN:huX%uHW\Q^cA8lCVhd#*@5&
DceK6p @ut4@!Wp@>c*<W6wSdp:=IpwVLCQ!QH:BMwtSZ!GC=AbD$VL4dhL:C$S#4Gm8ICi9y5XuRK6IL5kkCei
qi#AtS %YF%%PuluYl@<u4Vu5HV=BhX%M/aWHBYB<WkpXtZnnRBlP^9K<WTqPciCHRjpXhPG$JGp!9:tRi>5TKe
<\Ek@W p?V44=W<G5Ed55d#TM+TPXXGA4YpkQEY=8!99IQVQJ&uXTG8&LJan=K8#CR+Jc?PD$$=1t5>AYPlb*J6
^^\/D9 ZmR$mBBdBj1mcCC+6VG>?B1\cT#N/J?$^Y!wV8XDNYi&Gb+&pAMWC8>%MBQqy5N#b&=QWMPS+XPte5F8
J=YVbi =n88iym4B9:B/?Nl#C1hJ@Qp1MX^wqe\1I5L@!VB?:n\h\>FApdGA8Tej9?kGXi!Pp@Vuj5bI$?mT%d=
*WAu+N &k4I%9K:&TQ^44RZ<G4mE+Eh\l?^5hu=P*Mn+VTIBA1+qTL\p*QMh1#5R41\:b=!!KS^Ihcb>@+6LZMe
$lZXk> Hkac4T&LbjSInYdXpbDC9tB6cu:F<K5+EyYu/eePab8&dTLqaIal4lW<KYqPk16G+4tQwlwwPb@A>e1h
&A\tyM dPen8BaE8:ct?%bHk!*$VL9hT+&8I\J&+^m&N$j+X#a^9iKEe4Rmmlek=?8TQplbT!/dN\Ik!LAHGj%6
Ky>c<j 5DkC=M8!m9:<W/*@YR@n<ZpQJqwSpFb9XdKcm1bb$>WKlRMWHSyNC^Y/FRe/*%GCC^aG=!==R&cH@+1W
Cd$DQG RqPe@Y/ewRwE!6lkSP\LhkQ@I/%E&X5/nR/4Si/q=Inh%b18Ry/XGmlwVpJ=/Yj\M!#bl\wi*Va@cJq/
6wBc#5 !4/Ih@jQCnkwnSnYi=A9M>6Nk>@t9<$54:=q+n=b8STP$cKKTp/du<ahp$!B@JLk%jmBZHH4uPp\#S1%
kX4ew> D:YCP6\m:TZV4jHAe9J4iJdRpM4Zu%T5J@nB*RqGyyE:VNHFe%ac/iphm5au!Y=&aWlHSQV%DY&k#HJQ
Dn%uCy T>tRhW+u*DlPA4$CC&Qieu#Kq=ul/Iu&Z%41XRIA@>Whnt?aESTZ?PVWhLMSpJHbRdn69GH\#$TieD$k
VX656+ J%q>?d%*bY:q9tqemQ\clbI<M1IBpFPdZ65LVuX#qK\uwu+1K:L\69$P?Xh*8DH<L\AAi8%@CcL@Jan?
MZ=#<6 *!TIb9Mm1VM&KHIW?Q6!$$=lHN=YXZ!L/q$t#hZJ+?%CY\\i%4X>B5@uPC!M/TaZ$yKH+nepKnXEta+y
8%wZ<a <VYnu5NpFSL68<M$::+ADRp4J\<=w@XZ*!LXDHI*1!Q8n>m*?4h6hJwYK8tYGcRLZ4>Niw!%Qa!?KtK8
wpeI1L e1!MPjXV=y$#<\kt6F\RD<^4&aTiMa4Np%@S8qKe$FkS$b5a^Iq=8mGG^5%HE/L$tKAWSaK1=$XT?19A
+mB\&I GTuw5A+Ynt#=KpP$XpLjZcH1NW:Xpll$8>uhWp#:HmXmTq1%pmehtNIMHCS8LFA*JNMT$q:IJ?VSGH?m
1n9=E> &k+lMbHw?>!>K9QAcLdDlm/MPa*wFew>/t>Kj4LMDbwlD!B?B<=Lpa^?EXV?VGI#@S#EPZl<R<iPuYiS
X$pNHN <Veh8wY#%dXwquRpl8YK+&CJ=YuIy4<NJ&:FYTR#wdKBw/*^:tHHQe8>@8!aMX^eaeS9V=^jc#Y\eX1&
V:@t&% Mq4K1Lll=*MP&mwd$u\RK?8up5F\=kDQ594Y#^b+&19t1\MPYhtGCMe5d%=E=KqJWRTmM?BRu?mjp/m4
\!#<@N =pTSjC8B\QY46qy5tbVijFt&GMIA=Gc9a+S?\!<mXqMc:El$mL&!pkm^*6mS@*m6*tdHR8<R<=^BB!@V
%YHe@= :NF>cHjce$4/h#Fi$W?QuqJSh4IeSVHJXQ6NEWuPiQ$C/a:>R9t5LVIP/8!?I1MV?VF^lT8bkG!Y5ySh
\#y\CK @qhaFRuu\X?58/Map^dm@Nc?LnkJAEwmppRtd^+8DW9Kd&bP4H%kdm4>J#WS:+w@X8G@AQM5G%m#PIwd
D?G$p# FuqBIk1ppSRFSiBm+daGYka&JHdj$$SXPJjS!!\mLGhHdR?E!PRtF@Aq#%*A=bwpmG?JkX5uBZjyVH<k
QY1B:9 %SXJRI9=cW/>b61tKT<F6<G%9bDGRJ$LuGti1/nS<APZ4ttE&>#kn^N!pC?qeleJ<#FE@>\NwtVuC^E!
eKuRq< 1ZcBIZ&9qdkhpuRbPTwMWt*?CXAH9=yW$N1WuYpNSi>X4Bl=H4uj1!91TN4kEmQS#@Di\bpZV&HNnGt?
ZPI=$H kQ+C8PdVGKi9mq1lVb$<98jjq&hdJwB6WmF%^%>T&X1t&m\jdwmBq$1C8^hJ8W5H?S:A#Kwdyui1&&:B
&#c*8* MS4Q<wZ8M:wHHltMmK^un:Y6Hd*n\9!159&FTPINeuctR&wbk>+TGmppRp?iF!qy!GC:!#lN6e@l@YEF
9lj%Wc 99?$N4J@wA5ahF/Lw^<^JVk*GAZJ4hJe:FkhN<5eBm#JPhXu*WT!KRFMe#yC<K&#ZRKGLFR?hS5yaBm6
VtbpVy Vat=A:t\EqX1ba&*Ay4%>*QK>I\R!QcPkS5Lcm<uG%=LS@lCXKPNQNJR*X\XEwN:*8@+%j&JCjyKPQbn
X/FF@y hShqQ!u#ZjSZ/W9/#QmpXS</CAXiGQ69Bp&*m?nm8#5kQ^9WFYQC?Km*tJKV5PMV%59FBCQ5!Ae18D8L
91%w9V w*c!C&Xw/:mM<iT$XS8n=LXPVm5^TBl<^alQXL\!=u=E=PcNhB6dtjDudVbhM<TjQXS?W&F?p/5Z%c:h
>*DiX* JABL1YE^Z/!M$6&ZReGmDPA%L=lEGYB%XIYkauSN&:tAnDpI6e+eLuV%LMwHV#X<a5Nea+jt4L&9A6j\
P>JJ&L d&e5T+J*A*CbFwt*eDG=b#lqWTd1?tR/A6pXKp56Wka6w?4iQn%J+dnDDqec8&!TP8/&yl%+#$HKQ%!c
6*4I*M y/dL!V\tDQX<:B\uYHGhN%?EWk@4Yad8dj%&HHu#eamZRWlVZXpIG:BPD<+j>>dj#$ZX*XeJ9R+Y/#e:
@<JJSM =A&6/!mIP=IG\*8jN^VjVZGFu/=WmW<9yT5Y\qkN+pRjXpI/i<bcuV5PjJYnNNT9jX?%P>V8aLMin%:>
@j?qhJ a<9m@qwQX%NZjPdm?$LWWlc5y6DSAtdVlAcP$DRKbuuRlY<BCja<b=H6N#:u1akX>6?6+Tbj$pbTFFyd
m*P>Ku 9Ti=a:P9GFnKmpceSI5nH%m/5<>uYR%?EBP*8:GpiwP1#pwYE\PZ%Y+1SwA?!qpjH+FR!ldRJLYBeik$
e=M=Ky 9Q+e:IjN*Nc%&DM%&=B4KTPJ9<&C9JCLHmY4h/DP#E^Pemh4ln/twT4Kbc=y:c8n<+^=!Q!4*\pjWbNB
/<+6*N t>TRTmIw&JW/m/td1QdI^QRcMYFjp+>c&qR!4DTmYhyKC**Q<Qn>mjw!PtlG/WFc!haSC&+#*V1B$GHy
:TyXyD V9bWi:w1plCPpZ<btKMtZL1+!EK*k>\Ik6PbDmMQV&1/G@QmLiX1teQwqT41LYWCd/RpbeDll?heVF:A
Fd+AYW ZJDPMYJ^yBZ5LihC5K&t6FGcK1c8?tDQ@W?@@WYqyEiCyS<=B9G>JcdKDt@#nX?ADkn\ty<i4m849HcK
8Aaw=w #d><QF?Xd@TpMQ8ckDBapMK@m?pN=huCA+$?q6Tb/C4Rak@V1GeZ16GyBMWleADt<8+TJTkuFTPFPb1e
bc=VC& XZtJkFp$e4E>kVPM4m9diWVZ4n/p@Y6Pm\Q=wHeJTekdbVGDRpYy?9PlbSP<+JT6uGcSV95p6GM!>/CI
q5>?$W kdpc6@m/PD>bbnW*?^*Vh?QwH$?y!hF^J=WVX?bFJ%FlbWSA8I<mKc48\n%>=ukw^YS@np^Q^&w/S>XG
4tK#j8 V\qYh\LIAYneRKN=+Bd/XwWS/1I:bL^Q??9*bRum!>!\FWLN4pXJK>$WyHJd$n55Jkwe6DBBE1i/Zqak
^QLuC% 66DVXB5?i#m\V855&VSchK\b*8M6?wcNq%XELTHeJS4E\ZT*+N=>jpw^XqT@@ayGb9Qy5Au+=Htw5#LZ
4y>TVe F:aKK*MYMXCGFhYBXFXWSYA:+RlmpZ&w<+b=B5T9Y$yX/CplNF*61e+JB@aKt%8V%\SIbBZCCqYuNLNp
!TI95# KXu5X<:9jVT?y^kbtC1MjD/%=LXmY/ZTFtupYZQmSFJDKd4NdC14L9\d*hHI^Q#jmj:jh<%cuICeWp=u
J8hHm? H%4YKSVIbR@eK/yTLA@5iXJAV86=^/+EDmVIwJT#jyyZ8:FPahuFj$:$=hwB&SanLB15!eV^8:e/D@wi
S4>P%C j8JGAkX@$9<YB:M4X\*ByN!e11:ASjDN^Cj:w:>%GQw98pPSnpDV\5dG^NHG\Qa9%5QS<*@TT@tV99*d
tTPX^$ N!CFAuJmn+8yTXD#*%9R#pRaaQ6qHH\4/REbWD<@<8MF<VYZIw%n$SQ=y+ul^AL@wbem+j#D^CP+bdnW
amNbuL hQQQQ@pF<mY%T>nQH>>GB5K/9A5*u6VqH/m/yueq<BM#aQJupy@>dS=\JLjjA%1M#L#T=Ekaw*q/BD=L
HjFiaa QFqwQuTlbY#ZTC^Ctm?d+>t^6CtGZ:tub5^CWTD%XR6X+RCFHPmNuFBbcP?5D/5X@pE<jW4/pGV6*ADX
Ske$&% 6GwP?:P$FNS^?:p1:LSC@9?kq%L^BembZd?H1LD4:1/%*5lSYRDyYIwC9Rbpm>/F+nalHSNFAL^CWijE
/XT#+= Pq%k:!4?cbDu$d?jtEAC44REbM9uBF?pw^>YXJpSjdm9MaQ4hd\QA6Il466YXRdbcS^TiLKaa1SEWqJ&
>SbB>5 wj?8$WdQNFt+HAZ/HdwSuWaVCVmcA=CJ*e<$\cYy5ycR4^S%m:Ltm4ea@\HIIneNZ5wCK?!F^QkNBDNV
CRPB\* *58H!#9<V:&?RGT8Cb#W:qGT1JGAQ\IBtclweB:#^=/p8TwZp!\Y=jia=#BikG!*C#6K?RSF1V8NZhY!
-A=@Jw 000e96bf5e100110334 Page 115 of binaries2.zip
hmtIAw JV\TubXn=@@eWC8HG=CVl:Jm>\!eFewTM8+cV/\cK<^%jk4ITRPt$Z>V/j%e4yB*#BT>BDX*ZY4<@?J!
*WSdy> Bpa&hHcPb9@1emZAHQ@teuNAkA#I>S4b#I>+d%:N?*hTF9%19t=LhWAYbhqQ%1\h^+@?V#J>%NTE\mRq
#muYkR deb@8F\J5QW@ZP:lV<K9$E6A/^caBIY#?*#dSkjpp*wdidC>+a\pT/dlb=M&A5:1PXdpll>6556mFtun
QIAiA8 #BMFFC6DAlDMdI%$HTtVCZt:=14Aw#XVWHl>G^PVEm+#=^GB&#dKpR=\HqEXqn$c:?p$SXL\yDMyQD?R
i1ujkw Dk>Ec8kn5a8Q1lW*F%$j8h>Zi@QhY@/:nj+!>Qa@DC$mAMnJiA%A?klZWqlXhm=a=l/p&iP/j\dpnBCH
tnuiI/ W?&MmeW66!SIjmJP!\:C%BV<5/HX@&FwT^%AF6jRMnH?5NG!Pt*H88=/a*eC4ta:IGjT&TqVI$\jmBH%
\WCJbS ^BEI!TR6EKWw>5<kj!Q?JJ#6ETEBa^FMpuAmY9lI$9nTn$&\hpXt/q<B#:h*\*&$pWGkR854:FJp?@8Q
lR1^@P /H\DhAw%eAAY^lD65Zb5uJF^a8Ek<VL:Qn=tqQ5Z=ma1FjZ4d%:AFc<RpFlPci\uZ!:aAB\I^:pL=$JX
HClmEm X6n=>ww&Ac#XEQ/9WR$Cw?EFm1<HXu^1h:hYJ:5y%LX6$HaYa/aPqN+^*51VFDmjcQDXp8+IRMMYQtY#
E&wnh6 A%ARHQ#iplTFABt&j6/hQqqu*#\!dF?DmXeMPThw*Wk*6T8S<G1Khq8m#b:e64FC:nl+ZyP&PVL6Yt+t
\4<EjB #%Q%@XdHCNikATi$peELA>amiAQMYjA9C/My6aBq8li4K8VX8:?I9*h+/t6AWn4ajK\AJm5dYy5SpCKn
9n%+kw Wu9XcS8Q:k@R<L!F<J^SI4\^wuJJR!8\IT*FwiD%ndwbRB9MI>Rb:Klb:dmLq*eVp4DBM>bZhuQ!bL+&
9ttJFt w$CpIjq=Zm?%\jey<:aPq!5YDl4ZpaGnX&5GbEpK^FA*5Rpu5Z%TVe!FjVwTlh@I!yNL5:RdDDNPK>GF
l@+SKX @JIY5Y+!yeXh+6V%TK<\A&a@mWeWuIDI/AHCT4u$TZRpB&pV#>e:X>KnE4<!RNaMC<k@ZAy=#PjR#SJh
d#pi5l 6TK?*^j/IJq4ZYKJl4ZT^C6ljl6SJb!w+jn6F\SydXLpEI!j!Xu@Lj!ha1FA#$ht:u4=\P=YD*S6+^@E
b5WdR& *^?u?Ij$E>e?IN6FDG5w=1+&R!<8Yl@Ek#e9a?i5HyB#X:C9hWYAcR?!@w%!Gu=%V/HyQPu9^F@m%meT
Q^/>4u KPD>QupMbRI5Bd#1LZ6\<BE<KFbqnR<FW1LF#56C4AwF!L\lbQJpT4:j<AM5di=F$LBMB9*=5m6lW$TN
iy?Pe: ceVw/8uRRhtR<qiHPdIRDwE6>#\8PMNX?JW<peSD&LiCFBdlHTH@pycG=4Q%!F8MC=ZidyJt!tM?Ym:R
ww!NVN Z1tA66::h&LDhEDPF+tE$A<^<INCudtaE&q@Y=Fl\&PRD<RCEEE:TXacaPd:%eKt>y9E$Q$ceB?#wH4Y
/R^T4X :SVDYJiXP^h5Qa8=FaVClkwc&F@#cjP<DGVPnuK%LJQP:8CQ4!+McTW4:bT6Kiy9enbMCmD6ZH6Bp=w+
^u<AD^ ih*tu<ZM1adB#9d+5<T:S?*LZj8YQE#D6^Qa9cHLA<%Z9y#HTw<httHcwID#ipeh@jlQI68#4N%/lmii
\>$Vd9 L!#qVF#N!n6Dh#$F%YR+G$^!EA5kkh*6pl*4=!G?BY?l1I%?d$^DnTMm?XicK&!=Wc:mJq6WRu@Rc6LJ
t:V<&j :>cdwMXy#PRL<>njKkp$Xj8Hhnl\NwlqGCA$C458SdWi!k8QCI$CnLhWt?=^S&+KKTnB:9+/kwm6>yhA
!NZGmL 14!nlhFj?1n&j@*<u#aCj<#=*%H=:/6eY^\k&<HL/1LXqM$JdHq*cZNkydIMJjeIpFPlKX6G4&81&Snn
dMu*61 eYM:pil%dLh/<!?dtiwK4*?P<NJBkC\&&dMTtc1llYSp^4umd#*&XF=!<IA$EG=BjQ:C\1IqqKIHSQHi
H/bt<l WH$8e?B@cJ4?H!9*XSekJ%\A1qA9D@8tK6k1<^y<a>ID/9$SpC%p:C6H/4WZ!4b9yjj>%CAn#Sq>:=?W
AG&*^: #8alan<L5jckLq/RkPFmAVp4t<ap=ceMI:leDVDNhKIE/#:^j!L$J8!u*LKKmdtCq/wSy^WPG1aV?5uj
A!5aHh BuH=c=AW?ZtbJuBPV<y$DTAkwkLkL@PPK4*eu%GSqYJp:TFCn&hkkt1qM/?aD@NqmuCEIn1LJ6dGD46V
YXIIF$ Z144ieDm+/+d5*<!YALZL@=li:Qt#wqPHtl6?WiQ5>>ec/ZSXWHPae^:a<a?t?R1XTe%D&%Ck?T/JQ>=
u*&tdb 1S=PA8Tp>peRiyQLCt>k8L\cjKBw?!qSdj:bcTLyS1m\j1QqE:WG:b>5\PkFn5u>Y#H5@?INSl:&=mcP
q=+6?t VuT&J5:@i4C?Kqd4*#^C^B8RmXSC=p/neuRh#&YH9Hemt?A=\PwK!Gp#uh<8QHw:!ttYaWanb9Aj#8FJ
$%!C:9 @+5WuyD=//I*=Q?T\9>LC9?@TR49Gujhpu?M^j*CkGiR\!Q\StWae6y18J*ky/mPcXYRR:9GTYu<EdAy
5RPk6M wlMn8t!EebyAQ^L6B!KDqS=VG@T<%B8#EQVD@A6\qSded=Fqp*md%>>&d9aF5ERY8^^=SCZ^>E?EcdlV
T6l<+k VX5cB\yym@HwbaGKYSCFhdAl?RJ+F4cnw&RLP689nBLG<qMcS+<C$&6u=eD8=VAPXY*ycV5pTp9had=+
M1yeKq bqF^yPaX@Vk#eV&JS#1LqDm**hX8pAceYm!>hmhHq5qKuKtS6tmM^GlkWPKta^bQjVe%@BGmDWLGY=TX
9p8qnX wu%DMMSnqSM=L6LtV%J4P\\ImqKS8kInFnw?8a*4qG\hjchK:BykL&#>%R^K@@IF$I#V46tj?LD<ai=E
a@cK9+ dYB4!Keh!Xh4i^QQLjaJIcjw@B$t:K#>Ic?ENhG*I#D/QmGTBVZF5YdJVPt#Q46RPt%#ulBwIYma1DEt
q8i?Zd 6dCYw\Hp6\#dG:tW9AMMRu/cK?:?!ymP:Bt:jEHmQKwN%1i?%9p?#ELAZAPN<!T*VnuGN5#$^Cy11=8V
5E4c?: djL/6!l+B5X:4Q4jVmXb=un/$GJ/kqTa#p>SVjP6WCQDCt1RcndD=CicmFw9bhkkcSMupS!#^hQW8!nH
K/VA*% T^ZDPhy5yFdqVcH5dRTV=tLIYKISPB\#SVn/kXVaqb!jK%jPlkW88CGiNQcmuCZ9bYJNpR1NQ^G>pGS:
+$?@1/ #n$Gw@5DPW:Yt1iKV1^cpkEP&bI#uhiL:Y!bpC6?+jAQa1y#/?iMInb9R?6^VLLWTqlN6bQVu4Fe*!k+
=i>5uI CtPPYQq<@DkLZ6EKu/J4ma6Bqj%YZkN9HmZeH!6b/P58LYGCS\cC:9L16KT:FTa4?n<B=wWqGt:M<I*j
Pm!=k* &JDwy/Y^FM4=5Yt^jcm^8LD98het9\DiYHG>n4#*!J<WF1hww8iiWekDY@It>n!Y/K%8EDS!PSW6K4M^
R154*W B!/kd1A1Q&*ybe!ILT%INB5!u*bj9ba&w/eX51m#li=Wu4YnED&X5jJ#JV^PNFX9\ZWdI<#jipatLjwW
bM\^6Y QKdkGGj#YweEm59n6<w1TpVhqDwieI+!l\*uE?8#H8JL=ZDw$cnHkhuL6>\NGyyS\@dE%><+i6mJ+!\V
%w1qc5 GW8^<>E>yqSmtb?Q+l^^wybb/en%Z5!*M:p8t9H9bq9KY$hHuP&eYPY86QA%1dP^R1bq*u$w<5/>m@qV
DQ*+8? GAN/?VKB>:T9L:I4ua=XP@TB:Qpjm?p1HeElqS=R1uCKDle8q?1wGVl$H/dFGF+ZL5w/+u?65d!EMqIq
#8qL:L BELkNVI8#KZX?kI8Sjp+F$JWYaCteW>D\tpnc=*4GPFcmhh!N1*XY^eLyEqLwAFuG6WXy$mnu\*+q8IZ
LGHP@N lT$bNIWJDM6dib#TY%cG9PD&1&?LQqBuStc!N/AVkyNLnccLwA^l%9/mIp:Jt64qVpm?/c%X@h1#!FiC
XBj#<8 G4SViDS+EAydBc6e6LI8:^wEmWl>+yM/de9jFPjYYKM1<pH^>VRH88aT6tW$=nT\HFeIQaHpLcabZCZ1
H+VMQP ZP<TXa#R4l^*bm5!HiqMXZpmA!tLBRL1t^:CmyT?ANYK\+\^d4A?Fy?P#hD>%!^8auTFRnq?<*9:!\b=
K/#WpI %XDkE:buIqn\=+hB?\6KRe5Yn%EQMW^jACCWti8cw#t$L+A@NE%R=mMHq%GZ!\+4S??XFllJ\9aHFR4R
JJnlm^ pKwIS9qqDay?<m\^*m+@C&lV6GM6yTqpC+<u:IIELp4t*yn4mQ=84NKkqScaN+Lt>AK^TmJqD+=lRWNG
W\KeXD IJlAH16I5F^W:FnqwAFYMW^&yWyDhyGXKwhKC8=9FktMP+V:^tk%nKy$GYe9%WlXDP1a^5G#d=8>#FtC
5tRM?j *>1:PFY\yV=ECRSW!c6SJXcT&*B>ltJlA*:cP!&+qctq$cm?P6<CGIq6HT=W:!uNYCGjyByZEkPhB1ZK
^u/&Dk pWk4+5KkTSSd:$eKF$m95@TCQp/%Y*+9Nt%lGn^>*?N&W+R1tR/6ekT$NlNEHd6atDw+Da#htaJEIB!L
/FH/h\ YH\B?nneub1$uGJjLWVRnN4IPD6dS$d^R*l=XGhAW9mT>QZ^Gu:lA8Z6HawJ5*CJenAGbF9Yt*mA*nIL
&><dnL 1ylR#:XKi<*@4MMhP<BZpDlqj/5/q9C8JWpH#d*L<AyR&eQYml\NPjBI?wFtey!&IAEtJH11bq4b9w@1
j5/mWu !NWat&L6!^KL&1M$1YEq*IqykipdYwlNyy*&8LyRZ%jFa$tTNW!p\LljSJXt9qT&#bTCj+HqQqj^K$qu
//H%Sm =@Gqyd^Y@ET@LTAHYl&iucn?AdNb^N@S$%nX<MRNLdlN8#qqqTt66Gy4*A/FEmYa!%E<%>bM<d&mRRn&
JZpCCJ &!V>MRd?XP5Z+IK4??XWdpG?4ZKFa#8:yL^%IG@KH:e+KH5w5p@H<MBq#R?cewNDk$cV*XuSqCA?kWG/
w*N+H* bT+KmTtm&cmJ8wCy4=M&*&l?HpZmpTPQp1jp8I+ByXXp!tGIDIT46ADSIi$5PnStSElLG5GRyPkLaQ\:
m1S9>p in4J5bnHi@1#pXiXZJZcKc5&iuD8GIQF%t=Dau1VybwqNNWP\<8Pc^ImikK!VE*l=eheu8VEX91StlAS
:N8hj1 DMHPWlSDh#J$p+?I$=Bap%HRwHdDpm5PR&q6ZXI#J+XN%Ql$6YjGmVY/a*bj9W%n5FI@LFadm#&9#j/J
It#6<b ?K\EZAKHkwcMI&jqeLy*Q:ja:dKTk^@yH1jYBVJT4=E@d%H4$HXVYY<lMCc+w@lQqcH9V6D%Me6MdI1Z
54:@Ib 1B\#D@S99CMHn\TBeMT@&@JkG*@&E^MjVuI^$ZLF&cIw^YS:5:MtjkG&\TPl/!=hEI/Gu@aJEBSptHK=
mN^9u% #R1%#b!NJluTMN*nWd=6w>aHHJhNq^GyIq^FJydeD>JR&8Fa%<c%!?1S%V:\YAH/nYHalMna<TZ>wMp%
F$5LJS E&dT=Se1L?AuQBK?AM=+&byqdV<Vm!@#Z9#HHVJW/abhch+m!E6Le=P6ZMh\VP5<M^%mcc^VC:CwM#IA
dl^M<D Y%tN8q:CR+j59Euc#PuNZ5hEqS:SNB:DE=!^t5u6YEM?JIwISDnAql>=+%^kb8!QJdD<WXE1b<K*SHh/
TM!hVj ^ZbKWp=TJciVtPR^ja9<MFG*pKM5?d6uIi&S8/qK+$aNWe9pJS6lw$dJ=#!Wu^kL$XZqB@YGHM@HSbiL
\*JK?I nY^tStGIGZ5HMXtQY%wejK+Djh9PYX8LCqWt1k1h>i6yG?bbi/\^A4e%:>FGWyc#W\cym=AQ+GZ&F4>N
/YGyQM SP5euy1S/Em@AFuSL:NK8FVH?5+WP%<Aq=LT\@ntl1BV/b6R#C9qw^>*=V$*p!\@iT\Zy#DcMhVR:Ll8
-AL$H% 0009ad82cc700110334 Page 116 of binaries2.zip
?Z*<:c =dn^LAJHe*EwmFhWB?Jiqd%nIQh!B#dqlJlF8\e/Q1k\dbBiAhR/?YIZp!IHyi#*lRcqYwdB4KR#byFi
8Y?kSt F8jb#MdIZJ/L>&5w<I9%i$m=/i#hhb<cRRn6&c$^dtbh=uXamYdIVTKty9HlWjk@*T^VE#Vc*59aAT4:
hP+%=H Nphn8NQEPihWDndBPE1JntApWWGt^X\yLKyikG^8d/TSae9j9FQ1?!lZ=*9:PNBbwu^YN5QtY>>n&Jjk
5D#Ldq bDA+d+=KS8^KKqNb9KRP>iwCGB:Yb%VSH*G:uAlH:%E>6<j4biIwFDRHS&&hF1LbKtB14pLpMpP$D\Ai
c:Pt1q iiWWCY/ZVmLt/d@%>/4L?j/6lFAXG@h9PScpGmADM9b*c$6NMJe=B*a\>Xp%@at*yk5k=^Lw+LeAy?J=
CRm6da d#kTDYMe9qaKYw#t9&Zh/j?eheQwALJIZMdD>qu<\n95W5q?/e<ZlNVnlAG!PCNd&W=ji$hR&uKSA!Me
=PA&!P \#8?V5d@e#umpBYRmaGYiKY:$GGMQj4=dhdJ>FCG^npdpEXJ1A1nL<>ZR<CZ@@$>qqw6+Rw^:Y?1*9<*
b+yDbL ?5HS\5dpV:d=j?Mkp9Ee@&$&aMEB&aw>R/#B&jH8S>9=5Ytjyw%XCFe#kJ^^SA#%Kq%JC#d:EXYt$C+8
QiSWTl a!PP^:@yLD/AMmWi+CAm=E!jNm!MaAp:!WTcKjA1d8ZL$iAi5XLbtEe^M6@ny?Z#qT8PVZ=^ITeiB4jT
YDA5ak NVT5wck<w@e@I=Q6:&qKC&DGIiq?^JtNSpZ=Z^:mNp6>T*\!WaIVba!uwM8unjnbSqy!TKty1\P9$4GF
StjqP8 Ncm>dkS%?d&bp*&w$1XJ5d%ZXZuiA\JC^4eVmi$y@D6bDKbV69NhyuYI4GmhtAWR8w>p9i>u!Y:IZttR
Z9C9m8 IKlPu:4M9N@9K*\X5uGKYVT@6m:ylZ4@L::daX+Cm4b8lq@a$AuyPG$ZBAylX=+SqEKHe<XZqQG6>FEp
T=+aQW <6#9>DQ^6dICS4VA5:cKIIWqI$M8ST5CR6whTibl&ehilJuYwLD4aSIhFkh5FTauMNqNVK^T#MZwD9P4
*+!5#: 6hcKyZ+DpVj+4X?:!JkbmZnqiy*F4++lwYK+!A#my^<TlBdQZDbmPR*n$/N&&Kuayt*&bL1mKnpFdVHI
4Mm%&M MJ^k:c&DXEV%hylBmu=h?^/TamW>9bSL@6H^eJmt$t8ltH$ldCdk5\<?>IJcCAT$R8Q%%H=t8Cj??B$t
5NVb#W LJ\/cV?H+/SJc!yRhq%BKZHKh++8HX6uN=nYLF8S!ZDi:&t*#PcG<dn**D5c/Y4!*/MmQCYIqN/Ej%?!
=B%y8! 8tLm=*\LwtT&uW:Zb6D6@*^X*pBtHq1dKik*^>l&l$&>u*u#Y@&4SWlPBRw&kpA/IPPVFtApRlniScu=
Skw@IX 61</ZG@cPF*BDR!cZaNKXLtZ#VA>6Qt%/^1y>pl#%m$NA\n$Z+GN?*m+CHd9DRtWD<Z/WXma+mZI5J#K
EuNj*e !E/9C9wl6Rh/<=\AwS&8DPPPae&bw18@=^ypkKdZ>8IkW@@8/?!+j#wBjpC5>/%yK+qP#6CyEVm>NHjy
Ccnudi R+>yE9Mq!h\6Qc=</RhLM5eIM:NyG\c6?B9t1+1IB1kq65a1HkNdF:J96lC!TyX?q#!hDZD=c&PF5VNe
1>lw<M <a@HWNRiqXYbnDp8FwZ6q#$a/WBAS>$=y&LCNQK\<BH6#abtH:bNLlBb:qHiiJE6%umVi1&E>pH>W#&p
Z1mXXN 1l8P#J*5+Zd@=>R>>jRX4\8P6TpQY&u@EHdqqhmWt^\T>p%hiH\JqXHuJhGPR+\RV8IjDK$+A&Yp:cn:
^Z49N= 9Z$kJF>w>jM\XEm&!Kw%>%Wc^A46>dI**BAKCMp&!M9<pP&B:n#BWh!p5?JEb#9>TV\4cb4S#MiZDhP^
iqnYJM >hy@B\I^&<16A/1WNqytm&^^ZQVIc!ADY\J5b4>yVw<M?:5tL:bLl*Jq%@>K$=@4DN&qpNBID@nG+T&J
F^EhXK H$HA45Sejpk$LT!wXn=<9&>NqiPK\Tj*Cch=q4Zj8aDA&GT6@XuBb+q:bQH+>&6X1w5eqBdZ/:hZy/:*
GGEwFQ hK^@pN6@\Q?QP6%WJCBue4LkRB?i%\>9q<$FQ*Lu995+bSGRSan5FSAyWKb9hT!:4YKAT&F/kL4?J*:<
BwiDH1 Q%BLA\RWAAIACAD^XY$q\!qSRSEMAABPiAAALkAAAGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^qem>$
4:d&q? bY%\e*S%bta9dtX$aT=mdZDquW&8+:kSkDtIAC?!GCTutH$8ICRE6Ey$FT&IaZb8=GS>li^!DC$EcMpS
<?^T:t j/6aLFK!@i\Z&i1j%/Iqpl?4YC\YTjjj@@t9j\6*@d:>?Y*:<>>jlQnQ>9MZ$du$@&pl@9yu@!i@j4nj
\a&c4H +5eQ@<Q?5pudZ#>@@6^TnQ56nQE@:C?d6Q$q9?L1=Q@>%Y@eZ=GQ?BnY@t5c:A!5Y!dhl:AKeR1^jkY4
F>9e+b Si$?k>ZteJGj\YyS>Yi\dlpMYu$E1^%6>DuE?nD4bydPI6bHYe<p%phb:Yl#F4E?!Ny91MPH5Ny*V/QC
Hliw8Q n:Fc5b=HlS>nhc>?lq!hYD?p9+a*6Zl@%n:Md9y##HIiap$9C9H84CDP5\n&jqd$*ppEi=VXlYYN+eS/
C*hDE? G5Eia9WB/F@N\w9%LILhb?%FSPX:1:>:C>c+4QD4W886%y>+l=lyFK1+L4I8Xmtu<:MG$EEV%KKD/6QH
$c^FC\ @aWQ@R=cL:Iy%p&JV<+1RpC@RC*6:nD=u*NHH\m>wC8WyVRJ<M^Iu^ul\:II@Gt4kAb4LF:41>\S/<d1
e?mLLi W<IC=\l#u%Y:C%ZMJ$AQD\qcR/bDiAc>qD+5m<CjNk1a/t5^5SYGAyWdVpNy+^V1CqZ#F/1&V%l^XZ\K
5ZSymh =L411$6cGJyWlK!#pyhDmXXYRC$$tHPVI8956KYa9+<VjRG#ikt6E&Kq:!QYWMSWb?Wu%HZYtF/m5q=T
lPE?I\ XFLn>WZh^NwX4FPhqTtC5uc*5edXa$cDYi<*GmiuRK98Kl<ZmuAHc%uEMXbha\%YeYCmTi\LmZXX8R4&
yT>Tcm lec=lM5D4LTIkyY8pwaTK/#SmnMc#E>1p8C5dtK!6VTy^P4i!81LWA*Y*KmuEm85y14BRc^W*5p5dt>t
VEqTyy ^tEqSuH:%N6aiVi4K/KVdV8<!KLE!9kcHtW$PAaQmhiaYMe=G\:pYymytw$>#E1L&LQD5eRc/?wBXFY5
iTiPRQ ^9C5t%?DXSnb&=yJ9ytXF4Fut&KJFhb^*SG4G4PbP&I%q/!Fn4Q1\/!pCP!/*M6cF/5q!\WL4KQP/%Y+
G\Ibu4 6lNNYIPhBEA#ER?=/JFI!Nb%\StG@NDLW>MjhmyiFc9:JBe5a5$dIVlwC$%AD+YE%nN=aTQ*61Ey%Ei5
AXK4yY &Tbd>bbaqTTCHW/\1qNl6V6d&tK%#cZikdY@1F&^ywHy=K^&e>ciYPQAhHLY&ly!uQ1w&PjQ#?4tPI\K
n:55// B&M+AC5<wp@K/waty9Kd&XabFtbXy&T6mVYMc?kVbJ^P!84E!9e@P$AnkTQnhE:YQkRQJR?LBV/8aJyP
aSyuCW !i48c*WjDR+IaFb=R6a+pcp<>lm4KMLWpw8YH<4pC%nb5EPjcyM=l5Acu8?#T9eEwajDSF*J*/H:QA88
5$TKwl bbme/@h>bb+VZCQF=W@<B<!1tDJGYtLMNcMJt<4:nu8yaLYbDDcpW5Lk!EX?H>1tL@JTbZjFLdq\4QH=
B$d#V* WWGq/b*$WD:<NHhbK>uEnu9JSuAEtbR+XLQkM$GpJH19jT?n4Q/aAkuuiM1!n!BY8e8KWYF!/h:WKGZI
WQdPkS Z6I!Q>JqH>jG/^eKcLbbZSqd9wVXm=X$%:t&cT8^/u*YQkl\!d$RK:nB^8qG#Cy14F5t\#ZtkEISVXbj
J:%8i\ <pJbb<F+BuPZ?@+M1>yqha<MhM%c44T$FdP/<AmCeGJX5Y^w?^%YX#K%\!pEupYcb=Yp#4MPS%mqd%^!
\66RJX /jkSVplh%Aw=/*kKuncw:b859y55qLWZnBiESqHBB%+lPF^qHYLnM1#VeXc$\GAWpu?L%eK++uQY?eJ+
%FiCaA BlC<H5kYpQmJ*tj%jWb^Md!5BZ&YWVqhIB&$!V&h>HcB=>151hH!qZ4XbJWp<tw$ej\d4JI1c*yp/EkC
nlHJhT MPm<=\#+cc68S%mVClQYC#j^NqZYXSGX4:KPFSW8YJ$A<lcTGT8w%k4N$GJ%Ku\6jMV=\p*R<C!XbaYt
d>8BPQ 1dI/BGbhqFa!5k15WRKZN<qdYSNR#1ya%6w5ha!5/mC4*Ghh*RAcdcRjVWZHG4IXt1HBPwCq^/#nSjFI
IjV=4? NXbN4ZcX%dpM$^HY4bB6EE/5:kc#ktRMhP\GK/k\aiYSVGXGHqlS://#T6I9c/#YYhkcX<RY5nhyYpBa
*!MM=n %TFYGNa^//\44I1jyj4u5$BFnXZj\41%nGha@W&Q4K%pHj+/1%858bd#%?RjpZE\GTe!1%$L*:uJPl%k
%Ay:!\ 6cK:dNwbbyb!8FlYeV?4<:SW\b1/K&d6JX1pI9L&#&idd!15a?Ei%S&i#dW\1w?5HYEhdtXFNnFnbW!R
BmZVb< diC+IEm://XI4LK1k/#Y<ubd15MdHc9J4C*1CEha5RynX9AbwQy?K8Fn+HV@n??8YYKVXh#Kc1ieuVXB
b+t^<< DXdSbuW19JT51d5m%ll+<Z9F!Nd\MwLSal&P5K+Pd@TD#5a/YjCK6V*Em4$%^L1Y4L&+mLC/ail8EN>h
h4CMEF e%p*Yd5n4M/ElWFu1>Ap&/!!#a4t8^u4!LAKEca&bNW@PbT$C??^#mRKTC8yjdj&k+/@&aVe*<8K=:5=
E6CecG K=R+RY?hBHkyyR1VL6^m:i>k6ZwQ#5Rh4NtEA:FC6cM*=^c^KpF1F=tmG$4HLFnE5KdAY1Z/&6ji8F/4
MiH:T1 9T:e#&4Fy:6D4H$IH:K5XwYLubpHYXjb1L=n6ada&&RJA?^>4F#e*&DYDpJyjYX#JmNYM4a\4DAda%pH
?mJtuH =e*%GFn:Qhcl4eMtG>WSK/1*E*\M$@G:S>k%&m44ey!%<<<Lb+c:EET454b>CdNI$i&^C1T<:DhS<d6H
d%<=Fh QG5b!S#Za/^4bLYDV4BV+E#pQcSkFTZ4NpXDk8Jb4Y4$cDYy+!\V6/Pm\mwQ58y+6:G1!JwGYEI$EB?S
n*8u1X aZWh9>6l*bRHGwR=XFZbFDStMe+Y/%SnuTK4%1E*A88Tib1EXZK5+$KPCyY5&/kK:eHI4:aycM^muE%Y
#XBVT? hpCPw4TDnk:/DM:E8GbEK&XqykZb5p?FhWAG1ddq@^bYe+\%^e=<bacImKIdIw5*VbmXt?:lbb<KK?1n
^F\=q! NdFYYdtwLR:TP%Xqk&KD\ma*pcSB^=T5YS6#Hl6c>1t^wkB$:TSH4d@18NcXh/mMhcm^Dlt4JK#bc1\t
HeZ9jX 4H4t%8$M6H&NFd/#5$RKDeZEBh$\pM4E4A5ih*Yc>BR4!\M<n%mS6AXij5NNb59qi5?TY4uKK851HI<y
dD8PH& XXmXRc6>pZZN\@icb+WBe$XBeHAt$BKPD#q$iduMqAJby%*YW1\^R%%qnc8+cAA!8Ja1iY:FRtt<YhG!
MjXDNY IDkV&MSb4hE=/=J&hcB5\V465bbmlhNu9G*1%VnD91EJqRmLlMM81=Gb%ESy+nSc<Anq4lEHb\9Yca?%
cmlq8Q IXbt!eL%WGZQM<V^h+KAP6RTalRDZSSPdcM+Xn9WwnY<NDiN=WdF#=4RwFtMKJcwMK51WP6mnXW*e@!C
4TjCKJ TPnVh8NKYtFJpc8eqWl1AqdwjBJ!KdI^C<5cG\m^4phWGDTaGZE8\S1N>5mE*!DSwbYT6NW/!GMY@wWR
PTh?\N 1dlR4b^kXSq%9n=6/almucFenuYMktXnMA$Xl9PVC<ec4BFE#^iJBY8L8mT^#q:&\IyeBY6!J+q/ZK\*
t6TML6 =JI&t5^R:5K\?q:ibc#tkFnl5LPSFc?y^>H#K%+Y<tbT1@k8$:ky5JwNW5B1h@YGZIc4pVmjYG:JGwe1
-A\E<$ 0004c985dee00110334 Page 117 of binaries2.zip
DQLl>D #Ky&^hyE^eiP@GtljI8Q*c=t#$lhw&YI5Wq6+F4R$/d!:>Bk&ejlXh5WJY8Ik8K+9>wVc^?@tIBF#a=a
M?XbwC Fai4bHt?!9lN>WPNqiZiPYjq$<qWMZ!MYbiTqcK/!I8?51kMPE$5?L$VIG?/SuIknSdBLZWY/#q4Y+Z>
?W!+D@ w:w+D94IhR@4\Y!d4IX^!qZaQcqSh*6iyX:B1lymhX?XdWuN<!9%jFdcaVP^8kH\&8kub&M%XdGYS%SQ
<5PQMZ #p1PbcP6QM<B@W:Y*BK@=MnN>:FtZ+j\p6PA*<iKjajZuKRmC#*Q#Vbn^cJ<#TFQc!Ki\eytm%q:JMyZ
t*J#P@ HbA#=lt5jLcaFj?*Gm<:IGjMM%nbdBF4hmVqbiiW^*RK/iubIqc<yQ#CM=:nM<b6Nq6k@S/^TnmF>QS5
dT$FEJ kjYd^C4#I*4Q#Dc^a4H1<*!Q@T%Zap%m6h@DiF*itSWC%jRd9N/QNT/y9m>ya9Z@aawLP^n=4qhk6h<^
REjT$Z :L<GXL:9>a?@CdiZ/jLP!y9JXan4i+5W=N1dD!ANeu%*=RY=@ttWu*F6e9*LH%BLA\RWAAIACAD$XY$q
+pC@aE >8*KY!RBAAA&BAAAK\AAAGN5cYX8hHM9eGh\L*hydnM!L$>FdG>lbGX!L%Jqe!>qdubqdG>\bT=ya&?>
\hk>D! W#F8^CARHP^I9m4&D<=XqF<p9*KJ8>D^Jb:mMmWhLp+l8!\aHCWyeqLG*q5Q5#=kYAMKHib=A8P>A=+w
j#X+I8 V=Q\b\W<>yVyicb+yXB+TN4c+Ri5/ec/T8KLHy^#qHppyl5^T8KLl@nuZykYNJiNDam@NVT\4m9Z#EPX
q*n<j1 a*4@KNDC\!ELL\Y/<FDp#BhB$aMYLJp9IWQ?9<le\P5>=BCY6N+GZ@hH?:<$%LMl>mT*BX+e5!i=F9lm
^&w<+u 1V*JyeBZ#&$<H>&F9j@d<dY:eWB@b\\dMNJK4#9\ekQ$S?w/Shd*NMER+#c&W$d8<!u*i8q#l*@5e=8>
i1aJKJ Ny^w%baHLPYhcGS8nCX88CH&$k@pPZM?E=6wG9D=m%m@<%uC1h>nw&@jD<A?A4h4ji<VWE5DBBRAAkAI
WhX:kn AQSXdTZmKARl$\AAADaEAAAyAAAAa&^ybY=$e!>\b*A9h&q8M#I9V$X5d&FpbZI9WtX#L&^qhHSqem=y
=*YNFb a&@XXE5PknARjRWVZEq9IC9nLjSYbhe8*ZtqH5YqN+DhPNPQA6GAJy4+&6jy/$6dGCaACkYcSpN\LaAh
VkL9!T S/&n*m6kW*LpieM<MlXY\ZMFZ5CFD8hmpMaV:#%HYcHRRSTDNFtTaa1%GWA$QhA6$uu#uG>tjQ8u?=jp
CHpW</ =+ujy@^V5u91*Mmu>8=d$eEi?C*G&p%$P9?WEiRF1H:At4qqHymYTSewbpqT=#4Xi1=#n!@WiZ^ul*NI
J:=lKB ^mCGhI/%ie?ujK:6SF8!@CqEG=j8=YhWH=D@A:=m%5ANWE5DBBRAAkAIAQSXdTYk>JCmpAwAAJauAAAw
RlePy9 AAAAa&^ybY=$e!>\b*A9h&q8M#I9V$X5d&FpbZI9WtX#L&%#cY%8Ltqnd?%cZ&kd!Su@jN4GLnZcGNcl
p8+#$/ ^CdNyT<NB!Y\+E&InI&%D!Ew=a!hEkJX\9Y/9jyFlu6\!+Y#?^L:wiAiLeEd!JGH6LRQjWpjikFDBBHK
%yNiMt $R#eY!JD%:kpeCZw1IPk8J#I>QjN#E1:58TL&>/%D^==QQ4?#t??&bY?V#6EjZTInl<@VN#?>lySkQH+
$\=iR? eWZT:\cI9yelPuZK$Ftmj*!D/QBl4j?hQ1IQn#K6=i><nck/\91c<e+lw8??Dn*&mV/J*piYXu/Ni4Rq
t+nC?c >WhLT*4kF>/W!&YM#JH1n/VWA:?a^j?/6iYF8M$4iqZG4Ve6$F=X94!\tJK94C\9^HSBCF:#^<\a?6b<
1\9Ra9 SlBbj1Zm4+ASkm+V?i#LZ%=p&m&VXYBcuGPLidjmK:ERqSY$JhAF\X&:JW@+/l$aFWMZ?I*q?:/me^W6
Xi/:Nj MM%:X^Vkpy9clM\jSh!WY8c>ZI1t@t6C/ei$@!j%^wyyc?KctZ>T$\?k+F5^Qpm<>aR:wpF^NpYVEI!l
!bI=/= MnuabnBJLb1$5<HEMkVCKJJdQClEtWhb*469wdQmK91H/N>5iimVhA\Z$kS*hTHJJhPXKjld^@4pF9T&
5cb!C= KTN*$J6$CI4HyC!@L&W#l?*/8W^j=\Qc6dZ@/:#<q#J6@@t*6LP#k+WG/CE/@46a8P8mk?iC=+L4TlK+
EZih5< cWZkWlmAH+AjRDeAQ\RjSmIEQ\R@lH+whRAF?DAWWEKI$eHH!wYEH\t?BF?Cn%WKelGakKctynD!9AkK
euBY9b eEnkpMAlkWMCB<#R+Se+JHBI+BDAAXjw$AePCS\TPCS\\D$/?MAlkRQ*FV4j#@ABb:lJ$BEB?AlAB*#Q
J#aMPB K>?5E>D4>B8/e8WK+h/t/>i9$+$dN?nSw$h$>?=hi9LpCWXSSE?jQ1Zu#=@Vm^e9!LI5GlkawMHBRSwc
iDM!=% G1InS+:R/PkwuVl^kp/iQEpZL%/pC^e8$Jp#b&nyt1R**=V$K*yM5m/w?9n9>QnVV?tZ9@<Dhk5BWJ?W
k?dW/u IcqLpWuEk^AQRn#Ibb:WKwkHFwAPQ8KBSYk#*p#Ek^AQRn\RhH%Xe*DXlwdtT8eQN\+5B%Hw1hR4RA@S
+RZ+Sb >i/w/jHQBRaZGF^keIFBRRIGF^leaHCB\RWGBSMaZGB\keEFBleaFHSkeIHBBRaZGF^keLEuLuC+\PE!
5D>IBX Dmu%<lRTjwZ1Tk*+T8EqA$8A!RNMFMByAC\1DBAGiBMAT\A5Km#AERBHAB^B!D!yR\WeAVAE\BAI1WIZ
qP/dwV AEeADAFjt?4VZ?kRal:>Emc<4pIW8p^LHY1?S+Ay^KRl*!QAFGL8EMIRV5KRjWt>HYy8<DF@mQqD#M>d
F5+mMZ FQL>\Z^kCIElXQeH1b*a@q#Tuh8*9@B:19nK4XV6$yJ!KS8h4\/=:FVbJRh#$:V8>tpjTZuXTH9bb?11
YLLHtW ZhaibN9?I&/R/^YX6Ead9&*n*w%11:y6RpF44K&65j*MeMSPXne&NmLXalh#@%^n?^qQ#d=lS$:pPI:u
*VXww! RWMy#M&^@a>b944Ka5l$m&IRDTY@8&1^&G8*KJPyqqSVemQt!Xq4bH\pc1%/J9C<t5X<l$p:auFCRep*
wZ96*> dEiLwVC5b+nq5:htQYenc5p:G?SHQAj&6ZS4K<^YMdhGQ=Id!iuY>nbd4S/BklJ:Ty#HK#Hd9hJD^8VE
8GQFTQ LV?hV>wZ:Z6CDH5^91!VQ#?h5m@Y^Ge6lc!V!=>Qm+6&4h1w5$I&!?Ly@HScZ4TdhcW\+mq\uYJYkMc\
#KIZ&S Zl@E8?VFVcjb9FV*>QwemHhy1Am^9cNEZcLNc^?JZjjaDa/m%8%=G?541EZ?Q?RyuNJjViayZ#@IW\:!
/1*lGj qIM<=TBQ/bYu@LB4T<ljJZjypejwZKP^=/6/yXN@d+Qh?99&9#6=&6P@$h/j@%V?6XtM5/l$H6W4F?8X
XAKJ^M %/Z%&@qbP$8D@/8>>d9/9@4j<!@*/d?d$Sj1N*4u4Ty*XbuyD#yNwKy!XlN@qcnYVC=4&*y>HRdIT6j1
*9PM#d C9>HPuGNPBjV8Y&yFPi@daP=t#jZ/w^@^6cJdDGKj9V&Y>^1Nh8&T!qeDVu*p=9c9<q:$Xn#XNSKjp8y
!Nt^WF le\l#hZ?VW+J:i!ycHm#qR^Z$\a/Qt@NcH%wd&#ct%E:P+/R@Mdbd:6hSS+Mk:i#NV6Ky6KyZDdbqQ/N
RwwjDH 4MZiYh%J&ET>>P>c6Wlu+t1^5d:V^YBtBtp^*B99SbN<i>:S<cQhJykJpIlH6a&wqc1ddD%*FEujdwQb
?NNcqR IBn#I1B*p1t=!h/>d9wABIPp?#*d:K&!=\*D\P6M:XQyjdIRtQY<5XchMyLI>uQhb4\%i\iIly$8/q*%
T$bb%m !*i1%YFVKik1S?6P=jJh>c*b$5Q91*k+:bdL=*NVW%*%:Z6XIW+4@Xdq+PS#$@=$h##F&kaKm>Mh?6QV
H8C5Bi =@&y:kG&c^H1mNP<=4lYAb##=<@qit^ILS8y\tNeG>m5D9>V9jV6t8Ne+luGWbHbY4&#Ypwd+HJ+>ka1
mY<C=y F$S@dJ^L4*\i$Su4iXHkcuPGL:$^c4aLwb<c:?*iGHmn>XFQ%#=\46X:tt!1G@Fb1^n5ZR<q/1J&eiu5
ql8:B5 ZS<qTmqandVLyFi=Jec<Mc@q+NX?M<HX8l@%8D#4ww:mTYXMiySthM%+8+PjHk?*/NlQQNd4bnT$*E#V
dpjwQ5 ?Ia\>HbP!<8Dtq+8c@9XLW&9e9yG%Y1YNG$S&XLcEj>!L&Y>!D@yT?q=%LiN5XTp#E/jqQ$&>Ve^Fw85
y+cqck ^iMTF=c6$ZHKlncn*cL:&h/i*84j!VC>qYG@n4Qh6/ZwdVXj$hqS<^iLVVWT9TVKTy%tHqNnth=Z+$:j
^^4\MP T=%4@4Yy^?dQVP+JQ:@8+#4%5QqNQZ=86ESj+uPnAjPecEA&^TiTS@$ey$W9LEk=NE<j4!\9!k@t5T$D
>\1miP !=DuLCHP<jPb\5Pj<yMN4/BSb6d%p\:4dNqTV##!/@4BmCW1=wHGIG@yXw>iXqibcSMeVK\L+*Z$<mJ$
^6Q^PH :mP&m@4=Yn6Pyy:9P/nuD?4=k*4?wJ:j<:qD1h=8mt:wak:%RD%bbHNXyPnLq%N!>RQ@=Rd@M5?$4awi
tT6ihj >W5:$:d?KX<^aJ?^:>uty*V%P@yMNi6=@j%&uD4QQl^Pj\*Qjtd!!Dm>4Dd\%t:ui6c#d>9&hMLGW6yi
&18GHq S?bl*t\lC8mN#q=G9$*XK@\hVSQFan>@F$/W=QWJ!Bble:<lZ!+&Pu+*Nh>H%qh$n1Hdmadp8adpTaZp
LjCI>E iaT9m5<Q:n@la^H:$Bhjw9/@!X>aYI#=!>j$jKwNDaHQy#F<Y8EnH9Gln@CD^jpMj/84E\q?ahpIdnFj
m6<Dn9 jiu:9q?lkSXnEeb<!!<WC1J!dtYllei6cLa/A*F8JY=L4ymM&TJ=wAN<?I/QdE\t?BXYN/hH&kbiVl$i
l/aCR5 tXRuPBJ<N!h<e%LEV#4!e8cAmV=T$8K::+yKIVFj*DLkC:H:k5$5=ETlhhRpCZShmG:<5%=*j9:?L:AB
Wh!n&= *Awy9u>&*bBy9yZ@9M%QBM=mA:WJcV:=D:TBL#4+Rltw$#qJ9qX+<N=8tG1?B?9h?An<w=#b^?TbFtwh
jH+B// 9JqM</uF:8D#1Sj6jHBZ\AjXibk8P$ER1JS#6!C^ed4??N?N88:Bb/Xb&dJB4P5inKaI!FL4mI%6Qnd:
Z<>clh #blSw/y:tPK/lcXNM$4%Mc94ujba:nZ&c*6h>&DMcL?/:5Fw=65^<@>uhR@S9\BRT\MEFAACAAkA>FX6
VakYuC JY/GK8ccARAANkRAACeAAABndGqqduS#L*BueC>*cY+#Mm>QSY^9aYSqem>TbZM9dtX*e!=ya&?>W48P
k<jEbm &#ARHNpBTMDA$cqe&qYR9@B>pnwLeGECKWnABZ>F1ZIh>Tp84/S^lRZI<GcZqBPyCJAm!P1^ty*lEqwP
Jj4nLM WGGB*Y+NmjeF<IZ#iq*\%\y+YZLt:^$@4@^W?JR=8<Aj\8ad%yapF*>$ZehbKyS9EJWpq=Vp>a>CY#iD
11:FKh Z1PiR1iWt5LR%uW>kY@$T!C\WVGNAwdu^nRtFpFtX%LIHWbYC4tDj4KNPWtH54a^d/WDMl6DLlJ*PA@e
NHZ*lj cNXuVTRF%=6Y&!G4d66Wc&y=C*MV?LtQREniHiww<Bcwla:1eKRSS5?C>pkR/DPEJyPlK%A/VFkS#FkS
\K9HPp jJ?\8ePWFeEeeke@Q\*@%?hG5@lG>KmIim=jeCKL@RQa>wC=AI1h6M^&LDHL#FWhb>al5W:Y*JHZ5<8Y
8RE:eT SNaRhZ98!>6<@N=SjL+i9j:$iaj@+uN6m:>e:ZL!yNqQ4ltc=KBP^^S?/N1%?6md=AMd!<RB8l%W9IcE
VJ!Ylk ALy8iP=/8G=I=l*e+GiH+ih#Bl=dwDe<I@c^uW=!uKIh@@*CZGJh9\j8XNd?BFBLA\RWAAIACAD$XY$q
-A\+PR 000effa37ff00110334 Page 118 of binaries2.zip
AZ4TBV wQTRwyAKAACYJ\AAKkAAAGN5cYX8hHM9eGh\L*hydnM!L$>FdG>lbGX!L%Jqe!>\aYN4aYhqLtqnd?%c
nyKcNK Z&kd!Su@jN4GLnZcGNcl^CdNyT<NB!Y\+E&InI&%D!Ew=a!hEkJX\9Y/9jyFlu6\!+Y#?^L:wiAiLeEd
IdLZcE !JGH6LRQjWpjikFDBBHK$R#eY!JD%:kpeCZw1IPk8J#I>QjN#E1:58TL&>/%D^==QQ4?#t??&bY?V#6E
9@Y6F* jZTInl<@VN#?>lySkQH+eWZT:\cI9yelPuZK$Ftmj*!D/QBl4j?hQ1IQn#K6=i><nck/\91c<e+lw8??
RlSY#j Dn*&mV/J*piYXu/Ni4Rq>WhLT*4kF>/W!&YM#JH1n/VWA:?a^j?/6iYF8M$4iqZG4Ve6$F=X94!\tJK9
dNRWy/ 4C\9^HSBCF:#^<\a?6b<SlBbj1Zm4+ASkm+V?i#LZ%=p&m&VXYBcuGPLidjmK:ERqSY$JhAF\X&:JW@+
ejBj5& /l$aFWMZ?I*q?:/me^W6MM%:X^Vkpy9clM\jSh!WY8c>ZI1t@t6C/ei$@!j%^wyyc?KctZ>T$\?k+F5^
Y\85pQ Qpm<>aR:wpF^NpYVEI!lMnuabnBJLb1$5<HEMkVCKJJdQClEtWhb*469wdQmK91H/N>5iimVhA\Z$kS*
%chR95 hTHJJhPXKjld^@4pF9T&KTN*$J6$CI4HyC!@L&W#l?*/8W^j=\Qc6dZ@/:#<q#J6@@t*6LP#k+WG/CE/
tZlnqL @46a8P8mk?iC=+L4TlK+cWZkWlmAH+AjRDeAQ\RjSmIEQ\R@lH+whRAF?DAWWEKI$eHH!wYEH\t?BF?C
LeLMB6 n%WKelGakKctynD!9AkKeEnkpMAlkWMCB<#R+Se+JHBI+BDAAXjw$AePCS\TPCS\\D$/?MAlkRQ*FV4j
C+!jtu #@ABb:lJ$BEB?AlAB*#QK>?5E>D4>B8/e8WK+h/t/>i9$+$dN?nSw$h$>?=hi9LpCWXSSE?jQ1Zu#=@V
a?Q@Xp m^e9!LI5GlkawMHBRSwcG1InS+:R/PkwuVl^kp/iQEpZL%/pC^e8$Jp#b&nyt1R**=V$K*yM5m/w?9n9
*6ut6< >QnVV?tZ9@<Dhk5BWJ?WIcqLpWuEk^AQRn#Ibb:WKwkHFwAPQ8KBSYk#*p#Ek^AQRn\RhH%Xe*DXlwdt
$%=YXQ T8eQN\+5B%Hw1hR4RA@S>i/w/jHQBRaZGF^keIFBRRIGF^leaHCB\RWGBSMaZGB\keEFBleaFHSkeIHB
5yptnG BRaZGF^keLEuLuC+\PE!Dmu%<lRTjwZ1Tk*+T8EqA$8A!RNMFMByAC\1DBAGiBMAT\A5Km#AERBHAB^B
<YJyTY !D!yR\WeAVAE\BAI1WIZAEeADAFjt?4VZ?kRal:>Emc<4pIW8p^LHY1?S+Ay^KRl*!QAFGL8EMIRV5KR
QYdmV6 jWt>HYy8<DF@mQqD#M>dFQL>\Z^kCIElXQeH1b*a@q#Tuh8*9@B:19nK4XV6$yJ!KS8h4\/=:FVbJRh#
py*A@9 $:V8>tpjTZuXTH9bb?11ZhaibN9?I&/R/^YX6Ead9&*n*w%11:y6RpF44K&65j*MeMSPXne&NmLXalh#
S>VY+d @%^n?^qQ#d=lS$:pPI:uRWMy#M&^@a>b944Ka5l$m&IRDTY@8&1^&G8*KJPyqqSVemQt!Xq4bH\pc1%/
#@6y6* J9C<t5X<l$p:auFCRep*dEiLwVC5b+nq5:htQYenc5p:G?SHQAj&6ZS4K<^YMdhGQ=Id!iuY>nbd4S/B
*>^ZH+ klJ:Ty#HK#Hd9hJD^8VELV?hV>wZ:Z6CDH5^91!VQ#?h5m@Y^Ge6lc!V!=>Qm+6&4h1w5$I&!?Ly@HSc
DRpB4S Z4TdhcW\+mq\uYJYkMc\Zl@E8?VFVcjb9FV*>QwemHhy1Am^9cNEZcLNc^?JZjjaDa/m%8%=G?541EZ?
5N\W&/ Q?RyuNJjViayZ#@IW\:!qIM<=TBQ/bYu@LB4T<ljJZjypejwZKP^=/6/yXN@d+Qh?99&9#6=&6P@$h/j
knApa* @%V?6XtM5/l$H6W4F?8X%/Z%&@qbP$8D@/8>>d9/9@4j<!@*/d?d$Sj1N*4u4Ty*XbuyD#yNwKy!XlN@
w%i*5P qcnYVC=4&*y>HRdIT6j1C9>HPuGNPBjV8Y&yFPi@daP=t#jZ/w^@^6cJdDGKj9V&Y>^1Nh8&T!qeDVu*
FtGeZ< p=9c9<q:$Xn#XNSKjp8yle\l#hZ?VW+J:i!ycHm#qR^Z$\a/Qt@NcH%wd&#ct%E:P+/R@Mdbd:6hSS+M
IjLjea k:i#NV6Ky6KyZDdbqQ/N4MZiYh%J&ET>>P>c6Wlu+t1^5d:V^YBtBtp^*B99SbN<i>:S<cQhJykJpIlH
!XYH%a 6a&wqc1ddD%*FEujdwQbIBn#I1B*p1t=!h/>d9wABIPp?#*d:K&!=\*D\P6M:XQyjdIRtQY<5XchMyLI
bcZh!B >uQhb4\%i\iIly$8/q*%!*i1%YFVKik1S?6P=jJh>c*b$5Q91*k+:bdL=*NVW%*%:Z6XIW+4@Xdq+PS#
WyFCC> $@=$h##F&kaKm>Mh?6QV=@&y:kG&c^H1mNP<=4lYAb##=<@qit^ILS8y\tNeG>m5D9>V9jV6t8Ne+luG
&@l%:p WbHbY4&#Ypwd+HJ+>ka1F$S@dJ^L4*\i$Su4iXHkcuPGL:$^c4aLwb<c:?*iGHmn>XFQ%#=\46X:tt!1
MkeIQ& G@Fb1^n5ZR<q/1J&eiu5ZS<qTmqandVLyFi=Jec<Mc@q+NX?M<HX8l@%8D#4ww:mTYXMiySthM%+8+Pj
V@+dT% Hk?*/NlQQNd4bnT$*E#V?Ia\>HbP!<8Dtq+8c@9XLW&9e9yG%Y1YNG$S&XLcEj>!L&Y>!D@yT?q=%LiN
\GD8Lh 5XTp#E/jqQ$&>Ve^Fw85^iMTF=c6$ZHKlncn*cL:&h/i*84j!VC>qYG@n4Qh6/ZwdVXj$hqS<^iLVVWT
jbNK9P 9TVKTy%tHqNnth=Z+$:jT=%4@4Yy^?dQVP+JQ:@8+#4%5QqNQZ=86ESj+uPnAjPecEA&^TiTS@$ey$W9
h%4TpI LEk=NE<j4!\9!k@t5T$D!=DuLCHP<jPb\5Pj<yMN4/BSb6d%p\:4dNqTV##!/@4BmCW1=wHGIG@yXw>i
dlh=w6 XqibcSMeVK\L+*Z$<mJ$:mP&m@4=Yn6Pyy:9P/nuD?4=k*4?wJ:j<:qD1h=8mt:wak:%RD%bbHNXyPnL
bwi*ki q%N!>RQ@=Rd@M5?$4awi>W5:$:d?KX<^aJ?^:>uty*V%P@yMNi6=@j%&uD4QQl^Pj\*Qjtd!!Dm>4Dd\
1GC#ZP %t:ui6c#d>9&hMLGW6yiS?bl*t\lC8mN#q=G9$*XK@\hVSQFan>@F$/W=QWJ!Bble:<lZ!+&Pu+*Nh>H
ukH#Zd %qh$n1Hdmadp8adpTaZpiaT9m5<Q:n@la^H:$Bhjw9/@!X>aYI#=!>j$jKwNDaHQy#F<Y8EnH9Gln@CD
WZ@DIG ^jpMj/84E\q?ahpIdnFjjiu:9q?lkSXnEeb<!!<WC1J!dtYllei6cLa/A*F8JY=L4ymM&TJ=wAN<?I/Q
c@DkTc dE\t?BXYN/hH&kbiVl$itXRuPBJ<N!h<e%LEV#4!e8cAmV=T$8K::+yKIVFj*DLkC:H:k5$5=ETlhhRp
et1Vyp CZShmG:<5%=*j9:?L:AB*Awy9u>&*bBy9yZ@9M%QBM=mA:WJcV:=D:TBL#4+Rltw$#qJ9qX+<N=8tG1?
AVuBje B?9h?An<w=#b^?TbFtwh9JqM</uF:8D#1Sj6jHBZ\AjXibk8P$ER1JS#6!C^ed4??N?N88:Bb/Xb&dJB
$a4lTQ 4P5inKaI!FL4mI%6Qnd:#blSw/y:tPK/lcXNM$4%Mc94ujba:nZ&c*6h>&DMcL?/:5Fw=65^<@>uhR@S
CL*!JF 9\BRT\MEFAACAAkA>qX6Ja9cKDiaAAAA>kAAAC<AAABndGqqduS#L*BueC>*cY+#Mm>QhZS5d&>4SZl\
&4b5kS etX#e!>TbZM9aYSpc&X=LtJ6eHXNMR:CMA\MEpP:6D!DEeqLJVb&@6KJMjJGtI4Ek6XQIHuMp6?WMSQ1
S^wn=* b8!EqZQPq#6L>8u<eSWZ=X/=?*Hn6mXH>\>al+lX4QTVWqK%SMy#IqY5LNJG%FLBZDeSY!\+R>?L4Jt+
$1X=JB #?5$bjX!ja9=+H%R*!\KyKEJCu#A*Z\da?!<H\pAWC*^pX@hTMRHHy=/ckc+qZ8Sm*\BWE5DBBRAAkAI
Ij$>c# AQbXdTZDX!\4l\AAAQaAAAA\AAAAa&^ybY=$e!>\b*A9h&q8M#I9V*X$dG>9c$X+eHJqe*M9WtX#L&Sq
6NhWlc a*J=eHR8at%\e@L>^kABbWC5AeRCWM#I\AIYd&DABSwkpk$NEAwEka\DB\+AcbDIj#Bm?Q<jRwEkTAlE
M*+J5< MDB\#kRC@9J!MJPj+V8#5VGR@9?h?@huMJ>n@&aR9^#C@@?BH&4yd/BCA@:?@j5=6t>t+Aec^6G^&RAp
bAclHh \R:pk<\E5YjPuMA=AY\DuIdcPBMpPSMAWE5DBBRAAkAIAQbXdTXympK<lAAAAQaAAAA\AAAAa&^ybY=$
9SMHie e!>\b*A9h&q8M#I9V*X$dG>9c$X+eHJqe*M9WtX#L&X8a*J=eHR8at%\e@L>^kABbWC5AeRCWM#I\AIY
mI6Ri^ d&DABSwkpk$NEAwEka\DB\+AcbDIj#Bm?Q<jRwEkTAlI#IRCmDteM:tNRaB#J9>?INkMyH>@/Qn>GeVj
SPCZGG $A@l@@+NW5uQ5Z<@5:G^AZ@*:><e&#e#<AMN+?nadACTa\j!aYcC/AteE#nBNMkCmAVM&ypAWE5DBBRA
TFbu$R AkAIAQbXdTXPjAEZnRAAAQaAAAA\AAAAa&^ybY=$e!>\b*A9h&q8M#I9V*X$dG>9c$X+eHJqe*M9WtX#
qbXSAK L*BueG6qiZM8at%\ha$^D5I\DEYNlNSGDPWanJY+AV9Zwh&\^AAdZu$L^pyhemRtPtR\*\/ICV9&!@?&
NY8<q& =MQ^SVXP1B%1?/pX4eNu?lhel<\Xu9npuEF*LB/bXZm/lcdjwKR1TYXk%jcl*ZqMMwHnppI9%>Bm#=l4
PeIlQ4 m%%wdeB>H>^Mq\VKQE?>NmVqZ6m%*b!puSW5+\#>#4+BWE5DBBRAAkAIAQbXdTY*\<mAy\AAAGaBAAA^
uHLnpi AAAAa&^ybY=$e!>\b*A9h&q8M#I9V*X$dG>9c$X+eHJqe*M9WtX#L*BueG6qiZN5LtJ6eHYQQR:CMA!F
mNNw@p ZSWJSS&/IM:AYKp*aPec#E^paAqdS/?i8AJT^!\=W4iKKV!u1XyX+J@+$=Q6!PjL6cBph?RJiWRipAZ6
pPJpN+ pn:RQ*My!Lty1ANCCKm1^BRW+%VWXeInm=E\Gc%GiY>9I6!@\V^cc/VK*IF=!<P1y=W/D9P5eIh%TZ<I
dHuplj &\&ZdVM#i>?d#JZ*9pqM&BW#G/p@4^?MQ>Cn5/Lu+EDh8Xm=+8eZWE5DBBRAAkAIAQbXdTW:/CpTq\AA
^?8n9l AGaBAAA^AAAAa&^ybY=$e!>\b*A9h&q8M#I9V*X$dG>9c$X+eHJqe*M9WtX#L*BueG6qiZN9LtJ6eHYQ
4JhL:F MR:CMA^FZaEW5mQP\M+N&LpGe!eemTXMbQV1&?SI9WH^h+wcXYDH?W>j5TNjd@iBQB=Yb/8V%hF1wL*:
A:%LI1 E@&L:Ih!dwI$1LYc\yu>$D\*ReK!T>ekFa4RCD/W4CyyNJbWT6T\MBuLq1j8#WWDn>@iN6Q>y$4b5H@T
GuV%9J YJlVZDk\e*ctnnH?@aMJ9a^i^V1&IGc85i9+>RFRT\MEFAACAAkA>qX6JdkwDScYAAAAbkEAAC$AAABn
&WG\QB dGqqduS#L*BueC>*cY+#Mm>QhZS5d&>4SZl\etX#e!>TbZM9eG65NC=mdZB%n:$NAnEMlZ&AlE=yEVQR
N!?DRp 5\E>c%BjSc+MHYZc6$Z/NBtJDeK#\^$y\L?jutI49q^9k=nhtTjtpZqkD4I#@TZ@LFlICK&yE$wy:KyW
:@EIEQ C/t%NZYXYQC%M/KM:FwEi#<BMTX!>N/QeM1d/EFi>JY*@b6?68%$H@aLQ^4#M$A%nnuuEdP^I!hn/Xl%
-AyEGW 0009d13bc6400110334 Page 119 of binaries2.zip
?l!pF< @GBbb/Hu&M/=8/9u=^6RT\MEFAACAAkA>qX6JSn\QtiTAAAAbkEAAC$AAABndGqqduS#L*BueC>*cY+#
D:aT5y Mm>QhZS5d&>4SZl\etX#e!>TbZM9eG69NC=mdZB%n#$P\nAMlX%AK6pSb&DuB8^ek#pV:Sk&n%ujdZIp
IquJn4 dlCiudbpAQ>?iw16?Hb@DPL&bF/ab?cJPenB>dj<5?RlKdXtVmmq5J6TQcVY%5^Na5HZ45kT&K$Iny1A
Q</e5I HCM=1&4AcL#LC9K1d:#9*@T#dii+5K:<c5#QANW=V>MWMD8Q=Pk5Hb8PH!#dLP\e*#q*h@Y5H%BLA\RW
cKK85X AAIACAD&XY$q/jbnGwaAAAD&AAAALRAAAGN5cYX8hHM9eGh\L*hydnM!L$>%hG^9d&6FiHB!bZN#L%Jq
N8<G!? e!>#cYh8LtJ6eHYN5R$CMR^FnaS$5mnCGFhtBu4YkR4JhPtwQeeX6BtDMX^^J%GEd=8Y:@!<=N6SV8e*
p?$HRc yT:\DB>@*6E?e1F@pt!KJL^\/L&Duw^aNEdC!!QjR1#q/kISnlX5t=SkM=4AdXmq/F84wJE>Fw4=\/h!
!\iTYN MRVQP<j:/eZiZ?WYh/PeM>Ep1<c*19wFWE5DBBRAAkAIAQ%XdTZLYlFcIR\AAD+QAAA9AAAAa&^ybY=$
Z>Je=6 e!>\b*A9h&q8M#I9WEhRaYS6cY+9WtX#L$FpdYq8X&q/MYJyhC=mdZBXX\6RG>i=@uhb\py&!p1BPp%5
+!a9kL e!R9k=DV$68=e$$d%/^W8h%X$lwWLdnGN6h*/1u4^Ha/4YQHNtnSKKtkM<&mkn*V^%ktMIEqRN1^:BTG
MEYDTk S#QNPE%:t#8yCapJn+dPZNjE!HlMIIB$?1@pJM:SHMTu:>@#?N@4@i/PjMmMHVlhPE@m9IYV\W>t*PZN
y\YiWD \h/h=1CWR4A6WG!4CnwC9hN%J8+MmHK:qjGLQe?5VCA8LXdWkp4D=uhQnJ9<RhpJDlaM&*iQDE>jy1Da
!#H*iR 8%S@$IB&l*w\kZ!kK:N/nG544HY4I?D&pwlDEaHk^*iY\86<^MEDNQE^9&HES!A+<>ubwLAMt4S:MFeH
94YB&V ^n$RtA*\$L$a?mH+Pj^#mPdV#<c6Gqm8!Q=:M&C<$X&?C*EKWSyP1h%&iHA4CCelSPpM=QeA%!tZRL#e
y>QMw^ XI5GPV<CC:>?A>#K<Ll%D>m4=DJ+^iVV8NXN+CJbu6I%^F<H1+LQQ%&P<58I6+JFjGR4/Cb9G8Nl5LjI
Id%V#w G+CWj+49D/+9kT/Vu+E#eD>a@X%qeK5ewGIGKPVlu6u%IZ?WtWWiwG64B8iM=5!aQJk<!nPjaFhJl5@k
DA4Mj& *L8</R!j<H^JSl:8jj+VQ9e8j^JhJ<5Z*iYZRYIwZaJ<dZ*JZa^uVpG8^1@L+lqw!F?FVh4/Lhuub&An
!?%/a# R>H4?L94t#b?FPjG+m\&:%>p:4e8i%=VZ=6M98R#ZGHi=+H5jW*>%8N<JQ6<n1q@6Ape!n/jd>4L^P>u
^&$IT^ =a9wKPTbNu8nBJd^91bBKlDuq/?D=cJ:@WPF=Z9<bi!@h<Hc=@!yB>Kj\=PbdV<hPX8B*889>>&EcjN8
#/jQy# GYYch//F:M4@F#L@y8aVpMa989#1CJ&tNJtwl1YdI:Ttb4TIylc9DV%=BKbDhPZnI*9#/SKqe\pXWnij
FWIRyE y8NQQF6G/elHR>WV$D<+p:e&>e<<t5:!K<pjRFtC@+/=@NCST>A@mcaLDnQtjuMVS&B^<AA\+*eWE#j$
EW5AB> nWHj@CmBW$cGu%m<BKuEu*na^D4NA/b:>pHQ$XFN#/F<=6nyPbmeGBW=PBM*?XSmD\\id&JI=D+8E%dJ
knl9wJ JL#Vy+pekhmImaeGwHimCV!5BBu?w!ReVwAwCL\61@aBtP\ZG:qIYAI#&/TT$HMeiIpIuAV>?EM>1NX&
hBN*Jl TRn:hEFin$6M+@yknjDAQ5i+QcaVJk+4^Eb$nSS5I^ZwlPyiM/F^4wk$HM*BRDXiF9*65lBt:F>?t+RR
hTtMiY h#QAR=kuWu?ZXpSB*T$LECPE5h+@:$auMX==dYeqeF1WuG9R$GuXRB^!SS*AWu#XHR<l*^#WkiWJ=:<6
N+/<P# whP1*=wBN6DllV<YZ&#iuR?hB%5WGa@\4cm^KA#<DIJ@@BM\jwZQ*&m>yl#KAcMyFlBNh/=aQNQ^+$yR
XjHjuj \/Pk6SAyZbFajPBEKSk6h%46HJi#h9LauyiP:IWuem<^RLT<p:j1:*^9cSq/TWMkGGG&jL!RHDk*>V+E
@II!Z4 LAEAt=T#ML6!\$l>DH%p8>HyE*Jt4!T9dS6wl/D%X\BC=L+4L%#?!j!jW>D%aq>*MA!l6+wtymc8X5Q8
S4IGjQ l%a+6EnwjJGcT4>N+ji:?my:w4C$iWjQmb/DY/F!*euu6nma1i&u%Tu/>t@kqdMJ%#imT9ypPnd+#B9:
auCS91 \A88<K<J5:c\c9SQPuYI8+d&uInB<5JH\V%>Qmj+\69KhwC$MD5XG?=%NaFt&jiZR=y6>51q#1@YlRpw
JncKhp JQ>eTQnb@:>\R@H@11Mb\QyE/JA9:$1SEZQW&\T\pPh99A6=L&#?q/6%9e<BE99\>MiYw5$XN#1>9WIE
+^jB51 PQ*$/Xi%w8&ui8*mk#+BBG:Z$RQBL=VVY^&K^?IFn?Q?+%bt+:M4@jd&AwpHnu>p8$%hY%lKhjH^tAME
q#>$JA B@8l/QnD:NT+6>$KEjB\Q49mYdk!tC:k++aAuCSwaJ>>1*>Qi#8H6!YFP$u5yS?i4$>HC/yKpheEnJe4
VwZn1P FiP>:jEIlIGI/G1Q@YLHEG&%C5$!<1++dNy+i5tI^:$ERLJKZQn!>6T%P$%YQSIDu4BENJ=hDZYLlBMA
GhX4jy uBwI/@d?JQuPTmB<\iNE9^Pi6^/cHR5>FZZ^QA<F/D6u*:5!Myq8<Sa:JW!>uP*L9*>4:yk1<lyaAD!p
!L=M*k <jCL=$P4cc?#wDWPkkD5&LEh%*1QLpeq4QR?5PV&*RkqX\aHHF\MQbYVm4=@Qn%$jQ@%KDFLKwHN+@ye
EI84%4 <4&cN+56ak!4NIRibhID6\h$Vewp5Y&y/m%q!e:>#qI:%uHbe&#yejnt5FEVSS::m>#>*&6Zquw/j98B
&YF<n1 qi5WkdMi!F%+PLXLKbQnGEXAdH>XnHM4R&>LH*A5Qk<q4c&*Kn:aydm9B<!+eY=\P*aj9jQLA5&LZaMQ
BNYL\c +DHZa/it@q#mhF>9naEA@QD8#86Vp%W?Dj5KWRQy9?d6j^n?1h>X:A4+NNVZ^VPhm&tnNc\^IKA/lA?H
5F$1@= C>=>d>nleujbGIL&iK1?<@8#b@$ima*ILAPiM>8894y915X14TS5bSTE=c$H1$=e<?pT%%TJY:DZ6etL
CIG6Q< FXM^%maSFu5he1m\@pDN*@^hpWJY^89!!%91*!!cn:NEp$FHA@/45K/^>t?F46bTdHy<+Q%yd5*n?S@G
@!Yl6k 9R#IRQBMwc<@>H:Q@?d!AV>4=/IA6X>//Zj=:%a/AHRNc+j#+jL<>9^4#SF*kBWhI9BjijYe*D<nEA%$
c=uc\H RHFw&%*V8e=wd?cd8R/$yyi%@?Ly<^h+$pF$B6Wy8H&d>6bauYGG^jM=kG8$Q*l^8F6&Xew!K@JA8Ml@
SSy#Nt %Cd@@pFnLw5LE4R*CVj$GXeLBAGQG\diam$?MVq&\TNHpMXMKWqNN\eV@?VBadjkIWj6Xq9D$jud:i/I
IS1NkX y9EPiM$n?hwGB:@Nc+JI6CnMeDbdYZYT6w5imPJ=FwnQ6*Q8qBH%<CILCm#uPt!:i94VDuA!yAqkYiih
N?EE=l G@yTl*$5L@Nw*=hbd$SS^%?PCa$Mk+%qkAlC8#yWJY5PRiaJ4PZ8>BiYu4mBtaGDSk+wP9mFhd<N^uuY
AW&lH< aSeI$LDZ5E8uq:#iZA++=DWPP9V#S*TIcJKpAZ&>565t4d55/X>w=RRH$BtYFd*BNP>dD!$5D@Rj4qb@
9NICAt !+HHk@ytHVD$/hP5^$H&6&ycA<6yDqlcpA6mC95ZN$uLPwj!!:qiWZh%1E\cWN%A%!yFSR/ZYuLTZkH6
iGPXbC R>jacP!LF4d/lbRRFkYk/T</^Bjne9PGXCbeKBYd%ReP5/I:^aqSJ?K<11<XJ*Vy5VNX&b:<=\j4qdqD
p4%@SX FuWT?BaSee9Xy@:#+mJ44HZk%SC@hu9\j&:8j:PuAb!wZ$19BIj9:BqM1Pp+imVm8hXp4Xw>X6jAY>CB
dkK4%I KQ*H+eH$YK&1y4*En9#1uhD<uN@w41MCC?d?XeiHSywNa##NTyk9cY1qKDu&uPwjweDdWS@Jh?eHV<Vc
RDK/qG Amew=\HW*?1S$^<q^E:*NQIE=b?=Y4c@*/cwKM>mFX?hNJbT\am1a8*XQGmQ$+h*nFX:XLYGcwRZ+J$^
Gd1*eW j?&NZtGQkX$9n\GRTkVPhk6B>hI$NttmHiaP?&6YjkTDV%=GVcI?yw#P&8Q<%j=>blh8pTAS%P8Gncau
R?KQe^ q@DqbFRTaE#^>%/9K1/:l6*DDM6BIpA1>pe<NSRdptXBkt/^:hHd>uBhyy*BjPn*T$ZH=V&Z#diACXcA
Lu5eL? :11C%qiK%@ia@hnm1AaBnt^1mQ:/GHbyNHtLk%a>#H*N5YQA:MeY%\k+jZ#V:5k*c$awHkn61hkp=$PB
CN1G*n @6+R!w?CHWVSkq1AJ%/uI#MaeBB6JH^d5I14TM?l?VS\8qCNDCiM$*=N+pSR9C%<1cn9LKiyCI@!GLK5
/#V8BW B4uC@6BTI/aQmF+Rmd&JPQI1Wn1LKeZBM>k9YVl@EYWFGiQF1dMYXqQKh1&CtTJ=Gd5^8SRK<&mBKX<F
jGK9TX Ldm5Xm^6wcBnQ8H\latVSa%4VA9A5FDFmC*+ySA?#XwI%niMaeJHkA<@R!V5+!1%tJMuNy8VQILJBpMM
>#6cwh C=KHAR:+A5YPF/*!aLQEKeRuta94bkl!teLCbh<&A=Y!^nJeG=d&V%=ABSp4p<<:5WTDE1l!DCX6^ddC
PTqN%1 4/T1J+hMCa@DB8BVXAMHKP+Y*NXjbZNYI?\$F?cID#mj1kbn*WFRFiJl<A:&JnZR/i+^iRFVBKi+ndbC
AdE!W1 XRbF%CM?Z/\4FnA/PtL1y&?Tat6M5YG>?#hRT\MEFAACAAkA@XX6JT9AmWnw\\AA8FEBADAAAABndGqq
!hka#e duS#L*BueC>*cY+#Mm>RS%BlbG%ydm>TbZM9RYS6cY=ZcZw!NGJyhC=mdZD59ZXaXhu:^9$e848:8:8:
AtQNS< 8?5e845XSDyWFKT:G\MLA:5F8\95GTihLkQ&8@aGHLBu^8@:9u@<8G:*hV\i/8N>:8hbc/?>6yZ4Qp<T
ZWA*nH +B>//I<C?yPD@9!E@yBAABa@8Jnu@!^?yH4dJ:9dyH4bbZ4dy*9aJ46ay4lab44bbL9db46cb#lcbCE=
Fn=t:F tKjdtYSaG&jdGKhdGcTb/&haGtSdGc!$MXllyb6tyJF11Jb81J=y4J=q4J=61y=l1y=84J=14J=m4J=5
nGHw6p 1y=kk1TYaKwYd/wYb/wYc/wca/\ca/Icdc\TdcTCQ#bWnVXYnVXTnWN@%XPP%XNKMFBPMESTTnSYTnFS
m+&G&= TnXXVDNS#DSZ#DbZYGGlpG8ypGeyZ&AqX&RqX&\nX&a46<bG46JPdwPDjJY#a4Ydew&ZY1&jiq&RXtPw
L9ApLw VtPpjqPeWW8TTY8/iZ8&Sj8KBZWk4b!ZbYe8wXXYTF%=%n*=%4$FN9%F6wQF6pQF61Mqhy9K:LiWP&^h
=WT#LN +:l>uhQP>e/:NnmQd*VbZiP/y<=6Z+QH@mdQA/&il>1>n*V+HP9&QhHuj*4Aj&ww<P!twHPdKijGKGi*
=HBn9* lTS/&Cc+Ie/&Gh+P!c:YCa+YmHP/1&&Yt&&cp&Yc9RXCuY=uutyqpwbpcbSm1y>myw>Rb%wcbqwcyJqw
mn$+@: J?14Jit4ySmwyS9l6FPM%JPN%JKM%iKN%PKRDNXmnNTmnhWmnhWmnFRnnFZDVXVDnFSDDXXCnXSCDXZD
uS\\wn DFZDDhYRIk^XR@YWRuYW\uYX\9YWIk!Wwk!Waw!Waw&W+w\WE+\Xpp\Wpp$XW5$X$5*q5<#qX%nI=X4I
-AN<hl 000dfb6361e00110334 Page 120 of binaries2.zip
=*C\Pm 4ncZLdCWLdcTLdPYZYMnY&p48<FS95yF5hyVyebZ4VbRw!=E8#Fe6#HcwCuB1DZX6C*V9D$LAX@CjCYT
pqybh< JXJH4lXT=!44#n#44u!dukKd9mKdkYLd\SK:pZL:$R1H#Y5h^>a=dX996L*KiZ8%!<+c%@E/>#&NH98c
lY/q>b QQc*iB:1<D:e=ZP$^@>au@@JkeA#w$FuN%QPn%E8dA<=6!M$D4F%6Wu%hpn%6E>\5w!%6$l!6py*6$%#
&DA5tT 6W%&5El%5ECwp!%Npm!Npm!MEp\Nak*%Ew#%pp#$W5*%W$^%+*VXa:SX+*XXE@S\&wu//ku/cuEGc6EG
y?kJRD cqH/1yEG18H/11EG1mEG15H/15GG1tRDXdK?TlCT*9!SiAb@WnXIY#qRY!qRT!qIY+t54WVSXR4YW\4S
bT@SjV X\4XXR#XX\\*WIk!XIk^Xwk#qp<\pW<$pW5%pW5#qe$$qX%lKyN4JyNuIXNwKXNmJXN8LdQGVuc6w@\/
J:u1=X X/Z%Z1wd@NT1!Jw%\h1%Ed4%5jwNTecNcYbN/aR!pe\ZqGZSuG*S9MK!Jei1Jhi1hbXXY==%=&444kKd
yNj&D! umLd9tK:kXL:wVL:pR4:$VWPw&5hN%e/dcq!*44ShX8N/++/6%&NH48d9jb%?B#w<n*e/*><KQD$KHq1
yweNMq M+IejGFH/IZ^<ClH1*k*&&R9^\SZ&!l:m^nE&eWt#e$8^ept$h+m^eE!!ha<^6\\%5\\^6RkVE<uXE<4
pm1le^ Rp<:&qAu^qA:ZEe>YEM^SEM^ZFMyRp5=Wq5qZF5qXE5=SE8FR8AK$FIK$Fd$$%d!%Xd$$Xd$S6JT>NJS
*Pek^i >NDC=atp4iTyw?Tq4i!81im8n1Vk41dkwc:wycHwncTy+K$y:/5y=/eq=/<nF/k4S>cVC>cVC>GZChYX
mW==mq ChiVn6TZn6GZnnPRVncRTnGRTniT!nKWYtp5qYet6hyC15Bcy5lB96lb5hlh8hSd4e^jw+K56VbWb%&$
NABCk9 jtYe\jwEw@YJ^wSM%med4$<&Zb>55n:FhEP1cXY/cZY/&ebM5>w5<:y5m@wem?ae!=a<1>dXXt*=%8&F
Z?GdZy Ny%F6q$qh6&q>4*q>9%4HAdYPR%6eBt6e>9Y/DHi/nZS:Z6pMQDpCQuMGPZeNkR=:PKimDAH1#k*8&SQ
^pFLCj y^ku/*Ad<^l:!&SZ&%R*&#k:m#k:<$R:1!l#p^An9SBD9WBhVY>%XTR@VVX@LVW@DSWQJRX*BSqQSSq9
j4WY6l bVqjFZppL&W=V^X=D!W=h!W=X&W=F&XbJ^XbS^XbB^Xbi^XbP!WbY&WbG=XF1e4c159b1e9d1MlcKWyd
<:Dh/H KplbK<yaK<naKPK!ST>YqLbXp4JVp4JZpZJWpZJYqZJSR=J$XbZ\WJQ\Wlj*Xlj*XSeQWBeQ$lAQ%lRL
V&u/Ee $^TN$BKN%lKN%SXN$BNNNlBLNlbQMbhK6bJJ5=ZNeFVIhFHM<qDJ>qbh/c?SE/TXE/!hG/KVG/!VG/1:
EY=J%? Kw^R8B/8CL*Xpj14w@WLak\Ka\&L+k^LEk^LE+*Kpw*Lp$*YyJ15TVNhq&FYtYt?Q58<cwXqhc=XZd=N
P:w@>J e:Fh^^1ukY1*4T%ii:9>nk/VV&+Ju6wShtF*?PY>WcEPXkqiDwqiVtF&FmHY=6GP%5q8>9FPNyGI8c%F
jyCH#< yJXywKGP4//Yy:ctp:Kmnd!e4aK<k=KC9cK<6a!W8dmw8aTa6bTE4dTpua!p6dREpyY$lKYW8LtMlKt$
1ZKVm5 PJKJnLmSnLml6LmB6JmBnJm?6Jmi6Km?nDk8YRpDPWpDYRqhKXEh!RZyTw41T+4yT+ulD/SE>cXFDRkb
id9?u$ !akcI<tKtMkIt<wIt<5KY<wJY<5J&ekJ&epLPTkIPewL8mkI8CpIiCkIiCpK?CwL?C5LBKkKBGpKBYpL
YKJ1+R p@XFKadm\TcTwibTwXa!aVc!+R:!pe/Kpc:KWY/E*JFWwn^Wwn^Xw:%Wa=B<%GJ>%PJ<%iQ>pVRTA#TT
VQ>LlK AnYV!XwyFK*WaP&$EP*$MJ&MeN*MTL$X$Ra=<aaF/H<l&&JnkY%HyjNwp?j8Z9@Dw=VVP<LP:at+PBEX
IR4=V\ =tmd+P$e/&wZbGpYat$S:&Kd:PEWcYeXbtpcaY$icGLwy1u84K=14cSwJCXyICFlJCqBQBDZESdYElDR
ZwWc4P ESLWE^dTF^ZYE^FC$lWS$lES$laS$lIS$lRY%BASWleSSFIVEXRXEXVBJcA5I1AmK1RmJ1R1Jw!Pm5KC
puMlQ6 CpL<CpICm5ICT5KCC^ITRFIYJq+5I1CKJC1kJ5yQmE>DqE>VnE<dTb^QX=^QV=#ZRJ#ZWJ#ZYJ#HSILH
\FY$ht VILHWwLdTyLdSy4dVwddZydHRb:ZWbHQTWZATW*RYXQISX9EXXjWVX@M*WnC*WVT\%#c\$LcE<qTByiX
ZVXR4< nKi%4BiTnc!*nb!*4b!Qub!Q9d!jk:!@w$KAp$Kk5!JTpI5T&XYb+1=M<XRJ>XcN<FYQChSMmhDNTVR1
&kK6q% Z&ubYPE+&Pm=8#@\/NcR!jGIC@8nIq#5p@*hI=^5@e%NR&\5E>\e+%#5k1*MR1*NKSat461cN5yK=ky!
HZaytT iyKTGmImTJymwy1mI11Ckp1<jE1<9C4<@P1CA81C@GwCjKwCjCwCjM4<jMwCjI4<jI4EWWGAV%/RV$+A
uQ+kcW q!\@u\\@4+\ku/\REn<Tim#F^!QJ^!QF#+5p#e<uLeAu#ee4SWkc9SlJkFeYjawAD=KeIC==RS=FJCEi
!dbY4A bTF8FYF8XTF8NTE8hWFPDTFPLYFPdYFPZSFPjSEPR%EPI%EPE*EPW\qPM!p8e^q8e#piC*qiT$W?T^X?
>8aJNu T#XBK*Wlc$%lG&$SY%$^Y*%^Y\NCl8J&llJ&S4n5VbAppS^MyS#NyJ#Myb&SLKSh4GSepc^qZY%p*Y*q
H?#PYJ QP#q9S\XjBF=V>YwIM&$GQ*mdI8G6W/n4h::SmtuhwXjPBAV/?&e=P<baGZla&wcct?V=PWTaYehaGyC
&cwp4e 6nINh*d$64e#%6GYEBHl=?ZlatZqbtND+9ypej+9>Rp@AP5T+e@M@@#e:Q>RHG?JnbYjt$6CSFBHXh:N
nDlth\ X6@VWh9ST5abAZiR>*XVD9ZZTI+&KEF>T=Zd66:A\>9CJ9jHyyK>a:%h*W%MjM#Na%!hp:^epdGDdY*m
F1SA8y kkJbtJnk@#+?+aPPl64d^hLFX6uJS6dXZkGlDk9W#Ek\4m!!:&9!&d5y=PT?1N#aED>4c&eDp$Ad/^S@
?WWmV1 #\lu?$BdY^ed/@?n>$<@6NRWZP*XHG*q*B\X@FEbDhQNZ&HbZP&?hbB<bHipt&PTt4K@qd=uyLj@!5lA
T1+uT! Q$5Lh\j:@+Q&:#=$NJShHFTh:PR>ZbYDA:W!p$&4Ky\Gi\IP:I1mWd#Iwu^BTQPEy9qYe:QXIiV5N#/Z
WP9N4A tpTT=8Y&NVJ\5LT\6#C*N#jDbVa9W#5pW=MFtSnQ!>dE!Nd+6R^6nR^6=tXwaGPw9!ADjY5pjV%C8plY
DI?\1@ THw/j$5ZTh6TS?69cTNyIqqwIYuk$6R\%%SjpIacLuXXJLQZWqPbq/t1<wJWqF:LSFtSpIKJ$t9Jt!nK
YZehKT G!My!C%K%pl?ZnJGe9PTNyTV66BRN>DXbYJliRPZ9+?>w=&<t:NTwK>/ay^SSaqDd:9j9y&SLEpZYCuu
=ZHtM1 tJ*QMyqM!h1hE^bXY9yb1pIC=T/&i%huQbp/>eQM>Qi*d*%*/@y*N/>>i@*1N%e9j*Zq+qiZ#n?>iP:y
PbJ^=Y ldNjuy><MuZ/!bqVn$?jiHV1&KMVS^<eP@Lk/KH:S\:eP#R^e*Dj#IG>h!h&*>&*/</iHdjH6>@iNZb4
B=JqeF ^>cd&#jjHN6$je9I>e%D%#aNZl5h8D4eh*t\=@JA%/Z?#w8>HSi/Y<>*6y#9cD:j$Zm?4RFZc@&=q61y
KqW1bm yyw#DXYu/>cj4Fq*wu4NmR*q^!6Ln/$4Pd1&/GlF+iH!k5Pq1\?X4DyaqH8\MPhA\a1J%XpV1#L&=cV6
n$9M$W Zbt!h$Z!*8!p*bpJ8#Qm^>Nmh/ZG:E1J&yEW8TMljH6e&Lda+LEa!6aw<6cIwM*lAb9D@DcF?I\Gi+?R
@PFcPE QWiCQId<*ad<ZRb>uecmKbeGi+@9*BERELCWGBMnw:iHka8Vp1?Qit!$aXGBjWid*@n&CJcmC<\X=*EX
pN:q6! udW1*LH$W=RF?ajD@E/9L:8#e?#LI\i?PL#@!eF>n@j9jnR^@uD9#ki:6><dH:8*e?5Ma4Xy+NJk#<Y?
%W1k1X #k6>HSh/&5=%6b#4dD:d$VVX%nDbWnjbZH8/wjy$jhYy8k$uc!6QdF^:9K4m&Id!a?9Ln1\6Q4KtCGE=
T=/cB= lGQJP%Cei/B\=Z+C!:=XGj6ZbS#P##=bpu8mJA<>M=/V6mW=cnktiCnMD@*mP!MC^tMw8?JC6<iFIC\E
?D1wj$ E@@SWJ<S^IVmNaTaBLkN?4pM?DwQiD9&ih4*ihn%i6mMiD8Mi6wP8XwP8qkMPypQPJn$&^9*&^4&&ln$
ZYeWL@ Y8u&YPm$tYp%Gc5*G1w&GKnW/!uX/!nWc59Zc54WcEl9XJQc1CJSyT^YyTm!RX=ww+4+Fw4u+&PHAkMC
:PK4n5 q*IL<4N#hqL!>qcQmnLI#:h4d@Zd6VPT#jIe1@M=%wB#LHFuDek4q:+?%>4$SHH8*V$:>:a&F5SGFeXF
^/E8cD I^ZGSlZGSBbES?SHlihHl8XHl8aEp$5>ujjtyF*w:Vnj$*/&1?X5b@NWS>MpAjq$W<*y^w&u/16P%t$+
d?%AV\ WaNDQpbAQwwk4!8bl*!\hQXBHQK1@aW=E@p+=CNFPTjZFP+4!Y6Pn5*$eje&NhcSq=MRFPBlbiFkbPBu
NICqGV bySqa#Lq=\1WEe*VW?%\5hyK>l!LCECwS$J>l^Fp58hRwQ8k9&8@4*P@n%Pj6&P9l%&Qt<*t!KATZ@hR
^kl=:5 NaWRBeqkJHtJaDq^m1\aYXcWLCMTJCWeICqWwC4Xa1#ikDn4K>j4K8KR6iS1NGW*18Pe1%S^#l5WSha4
!ZTB#Z CK?V+c<R+^n&56<@$Mi+JEBMDVYeubY<9NRnI\*!X>8%6Q46&BHJyuGPVjW5t<ybNw$ycRY4%!>tb/D4
c1Pt#Q <uP>%Nj=>QV^hhpbH<=@NXdGRS?um@%hF@1:EPy#*c*#6CjdG!hd/<<kQ!QWDhYI>wuc>Te&4n6i9RdS
NjpRBD S1mQXyaiZq6<8KL\EKKNWBjqHmqhQdX^#jD1qaG&X8KCAqSWXB@?%mRAQnwcY\G8en&XWY@HLYH?t<L>
eV^4cI S$J<eNSBHwMBdkMEdS!%8?&?Xbtti4wj@uwWMh+&A?WtE+%GI:X/\6J%<=bG6DXp16Yq1lF1FjENT1KI
jI+>j@ h1Y5\Dwy*mN4T\\NnX=@CTpJETjE&X5>I6IkL>?88e%@?/=wX9IFX5@#dQdu&W!t=FW5Z4>apIG8\<Z!
VF^5X# ^9dNZ$&iYJ?#+5P@4AaH!:C@!/YB:w5D*enX=%B$EKmumPk+$%L*GnX!>etc!8MwPq/nZqh!GLpcwT:L
Gi&Z=H u>1+h1K!nG^9!<4M@E>4QSMJdHnac\#XNki+dkwnWFM<B=G4EYw@F>#XHuaV?hqt?uwj=l\5#w>#N6N5
Eddy8# uE<QjiW/ZeX=%MnXNi4T%i1T4%Hn4ydp&S+j/tV>6$XqyMThuJY>jNRnwk##C8!d&\P&nei\^q%pnTeW
iT99NL e%=P/&@PA9T$dW+Y6<i*jV%%epQ8^#tQBLyhH81>NNTLY=wIEB\%ClBpcSRklK9QwA^bEmDHN/:Bk=wI
n+p/q4 EEV:ZGN%XXKetKDkj?t5iGtwa1TEBq\5N+Z/LuX%Q$KN*8AFK#:PYWKk*XCq^X!:&ZRSNZI%kdy8HnWi
hT!85< %Dn1cwRcYX1cD%WHB\9#%%>CYqLM$WZb$$enI6ywXaFDe$jk&P=a%wmL4CEZYRPS#56yLPQe+Yy%b@j&
*:PZRp d</h*4A1=!PePXqSLd+<$w?EY^wFTF@u?i:=ACG!ittAEKlQ%lABk8IcL+nqF>91WhyVW>Q<>!aYBa$*
-AGRSd 0004cee994f00110334 Page 121 of binaries2.zip
TG5<tM Q*8Q4hEwkZ4+haD+PB+w!nE*$Q<\=^BJ\R=n6XaL*Ya#dV\>Zte%ClAm49G5S1lSkKlJw1^iL<8@LTd+
PJ%b6i Le+1u4+c+al#pYNnb?DaunnY&E5Lqp/+<IcjP>%5:8#b?e*=1c1<*A@@cyye4J5wZqe&DX+iHd\$*Hh^
IVRV>k 5PeCHmCh=^bR6$\6#i1tGn^A/qH9kXBZH16ie:G>wTktppRmjealk#59Y/?><V#1IcL>RPq^5HnXS#tH
l!:^?T Tkq%tt1$Y8t*INVt&p&E1^9tZW%p!EKAcMmk!wle9X=icH6eKByeLPQ5mnl4l5ea=^a=NuRFdhpd#&b/
V+JFu^ u5*1Iy9nSVd9C<9<#EDd/YF:h>@+h^jPX1%i>ZHP\h=ZN\>h&V!ELI*TA/FG^n:j&@t/LPJb*h=+=w&!
H+iH@B YFN=5c&lcWWGDR*Nb^?hpaY+WQ@&8m!m>kN%n?cGBl@lLC*eccdXbt*Ra1uZa1HVnN1<?RB=b%qWp>1k
G>emdX KI\c:&YeyRnPjyyl5ec=^W/I<>aJ^HtT#ZRKFWE&p$p=qYYe8##6ymh&j*j^ZQZHPdN6D9Y>6uZp/6aS
\Ka&Xi *NWI>ZAj*qGnAEG8jq>b4K?cSH%%i=P14P#@alVMTW%X4CTPC5hwtN>\5Bh1y%Gy6VA$@QBuletIhFuw
FTtk4W 6N5cLcA&Z+L/4dKILF&qJLwnMeL^De=81y=?YtF^Jm6LuB6/KJ5uEqqMJ%uN#4BcuGG#QC&uc4/EM%&Z
R!4LtK q<Q$@n*QLq?w#q@>pTpWd9b6ERG*h&!=6ZQ4#dHS/%5Z^*iIPa1SkS=WGSH1e$SY#\>i=qFj:Y*QCA:/
Fm1ke< SG:WXFT<4C!T\pIeuJ#\cTFn\MdacctDLI$CbDnI+*BFkduSS#lH!Iu%Yi6*Pbl&&lq*&Bl$YPt*Y?1&
4alEW? t88$INwt/k%Gc59KI4K$56m8yClHK<9q8cH1/a<+t?cW86V*Bt<?pKkhiFVY+=Ta!*F&1=QLPhN&i#9i
>8bAeA P:n9&hXLG\9!Q@!#1ZK\hHk/HG>9P6dihLTq@pl#:bGt&wM%qSMqicjYq%%14d@W*+ZHCDGKYTmLLZXu
4iqw6E Y?6QhnSLCA6@FBiKdqNymWyQy!%JWYj:Pt>QVVdX%mk1KZ*$E^ty1Xa4mt$K<6mElnAW4!N4m!\?\ypW
>l/=dl IMbj1/6abcm&RX>q9b:!il*FTt&FDam1uqK:pX1:mZ1#5h4<WBHQcm$=FNG:WtIeq@S%mLMDZki%\tKS
91#hC9 u*HPw\iTdq+iQ*XpwKt=ITJ*1+c&/XI@>@k/*#8<@+j4X#aYFZ#EcTRTI\$%C!QDkll\5VM^m4A\Gk6\
&NG$@A ^&w1hRb/umnQ9>Dhh4/9a\F%Y<Q%kc/%1WtjAnuCRH5<LtV@!yTnJc8tNyShd1#?@8n?y>i8YJ1djjVV
#NtYJV ujnal>#^piBw5A@1Hm&MnD:<iqwTMFCSGKmwmPPC&GqyyJnw4dlb+!V+1#Xq&\^XWaak<4W/CnZ1W8Ny
R1Qpi6 ea:Y%55+P!q:iG8ESSt9KHK1:cKM:p<<iYSpjK^yatjL=cuNFtbGT#u*?4ueQ*4\^=9ZcwwL@&NWwpGE
CDmQw= p^DQWKDHtjwNKEQ\$YJH$>YlHqiLn+Q!%qAbn/FM4Mw+91=pJD<u#6+/\pk*\qBuFTYA:P*%$W?Zb&FA
>9kT8u #jCY!KBNwZ:HK555nI*?+?<mSE<VJe4V4KQRbKTGWKN&iuhG9KQNe5+PTl=i/1GSSm9!HY9ck$d&JB#i
TPF*84 %#M?%u^pw8@I^KCymeE!#kF8D++h?8uY>h4mw5>TtJRacb66nW=9ZH5ihhe>4Yj:P&Wq^D@<KX#MVG&?
k1H:!+ 498!p%AJP>hRXdWm<=>?W\=c/myhJZ!YKV\A>i1Y@=u#@GDjpai%TX5Pwc:XqN&htim$uLP>9bK:l*yI
JGtLWS 8GF&upNNT?DR49mJ<jc>P%1Q:P?d&NY?qLMkI%%jwQ9D+$h?9uP#61Vwe@WATk#WZY:YW/*%q\i/n*c&
<iS6IV 54+%j@9Gl:&m*K+aCn/dX%F+wdtt4tD%Q#/ySCIX1pq9D9HbElq+w14C$5V+e@$8Q9#5LZ1K>Z1Ki:KT
9XA$qY uG^6quG&W*S#X\5P%e@K5c68<l@eF4N*S<8B*S%H>uZ9*6ypbtK+qHN@pPinp<h?u4=hX%4!PWeRjP^:
yk^Akd p1P8n\=51/8tw/Q:<I8nhhZ&yWVl$$$XlShdc?5K@#FuKlIyW$F<M>q#c#RFDja@I&h/KqK&FF?L96K?
u5<E=R qcq9eLc#XZB#XcWE/&Y65K&1>^*aEnY^5@uk:9d>+&&:6#c<\ZtA+9Z+>Iqjb8:YqbX?S5=<NKR/W/$4
QL*Cyp ZT&d/t8wQ#a<mXPZ*=5ce:^/#bG%^YlEW@?^m9#PPy15LLYF+npYG*K!66LT^PR#@m:/:M!NGqL:<#Kh
:eNjS= :G#@=m\lbten:?1mRmH4btSbX>Z+>I%E:N9ShABF^:ct6#pQB95<PZQ!%@5#>iXqu*eERSHqPX&/cq6H
>5^wWG K\$6:ahjGTIn5mey+pVNPtVy!^&N>j?mIyNI$hJCt\Qh65YHuc4daGX1?lq@EhR*=ppLHF1h=Y^u6=T#
IW#4VE 4bYe1=M!PXAuI>%1jbX*#&D+@y%N?*i&:Bq4&D9&Btj/\SDjJ=Puju6\4:/m@MQjnwcKCmW6C#M#:ei+
4d$cA$ LhmAqYF*DGZ@!BA>I?PHZ?uI!:+>^B9=<Cl1=#1d/@>X=^P6KLWq!GN:R9nylmw45+>\y1iqbYhna&Fq
u9!bAm yj/$1aARRa+n1#Ke:i&ZedcWhZFRC9LZVp?%4K#$/PpNuhni8G?5j9iY8u$+=/X%pH+w#P?L5&h?j@Tk
%6L>E! aW*Fl:?Z64DA@uYq%+<jQdF:jF%=PT<9:+hjL+*C*<N&c8e&Xud&D:>TuIG&#X4@YGZy<a%44*T*hqT6
W$$+$k b&BkbKCna&KkZ^VDw8mb/AuNQ$<<b1Tny/inT>bV*^d89#$^Aw%AQ<w=%pn*SGQN+c/&:h&hedG^H/Z6
<FyJcN #M6&jHYtm+QDM5:t5m:&mpF?YtuJFyX4QH1/k!i&%i*bWwP$h&8htjE!#5QlAX?iu@4n<ePG6Y5?@L%$
:?FFBN BZkt5yP@PHQ!1@PVe>><%h:e@PHZ+=Qdhma*>+%L!<l<%DBwcLA9Njyp*adVDhX*n^?b&4q>d<*/9hZ4
AcQ+Ew >qT6uclih/l/*h:%=Z5&XI!9K>6bWd!#9HBHYeH&$9#6^ZudpI4!SqitDaWHnMYF:EmKuG!86VL:TMei
KXBdXk 1/G+HaX=FQqwWe/*=!iDqy>tjj9DuIj>/PyMX$jHJZXR%MbM^6qYIhBHM#ZSdF&bc%h:$N/6Nd5*X/Qn
n?!ThK u5$dVa*%q*IimR^/i9Heu%<<dqm*>mQ4F9l=>tRp*D>//N/Sk+>QHV&*j^@VB>e!<VHT6#qd*N&>\<Zb
8DP\y1 ?cPeSimw1\^WDli5PFXjNhXch/G#idJ^I^49ZG16R=^#*B*djb\t$tJQqiYhSLbjX*K$w9BI&i4D^c5P
cQet?V F?WeKq^=IC<V>de:$?J&JphN66bdjY\IGc&8MPLnPPD9&8Nli:Jp%d4XiS>?9cpR*@GTQFjH9@$5JTq1
pL*yFp dTL6bKMR/KYSGti/66mqw!X\jQPG<hENi#h9*D%TbY1p6+^#FPY4T?j@i9yF+@y%H?E5\LM9P@ul!YNI
H&i+p+ Z=$=Mh:cSENN@aHZm:K#w8d<$eS+YeEu>R<T>NS4>XWQ4$k?6d:5bQYc$>WXF^w&HKlcw/?mnBenAHW&
<9w\k% ^mRXtY+Q&>&JERhYyi@Q#>/Zq:puJ&**myVh&eunYWt:MlJ&y5SM6VXatb6@^M?cTq5CZIjJu9&?#5h!
<LEHhM W6MwkS?yILITW^9KZN:kdC#qbC$j+KtiEtNTWiDe*8k@QqK=i&V>up%XP\jZLPQMSD<cVju1!5Y@991!
/AtSYB cZ*qS*KDu@6Ai6!Va+eiHN^*htVA\iRna!+qQy=NEaG*6+%iPHwau*#:yEqPpyMRh/G=jp<p8T5=N59j
NVdK6b S%yE=I*Z<NNT&Rq\Fit4nRT/IaejYJW^RhAiS/k#E*iq^y=6d:V?GPe+Xdt6HncdA6%*^wh%y!hKCk6>
XwALqQ ?QWBcwwZ/>e9#Yie5=GWp/Ye9:6ceySS^Y1H6l4j<iG%8$e1^+jYnjYY9MF=W&#I%%e9Q@@t1/aN/#@T
J\V<mZ EnQRPeyJ?XybPlwbmA4\j^TcqdVE*9T+1=5G9:6&tS\a?I<G9A#W%LRjjLPkj=Nnw9PXFFy4wVhM>61X
w%cWI* H4>ubi484KV^>Qm#ue*YFl@l4MnGdMZQcTWya1Tp\M:K?6EjKhXI?%#NPyeq?T\qIYyqKPFwIi991ywe
$Hc<!\ dqmic>hc:VW?ZLF:cM&P@4K6uaYtS44LPMiFjZQ>/w999tt8191<@ZPmpe/J56ZZ^na>QDS^=8CBV:V$
PeCpZ$ 9@l\E?LbE8!>d%WGRw$5jd/4%h4C+nN?jhVT%Dlduc/1iJP#9wTDta!@m&ym1H:bC68Y>X:nk&Y:B51&
MZPVFb >SRSuJj/tYF#R5T*N/?@jQbh<<d1#@m#<dP^>JC>#4dW*h!%:j4Y$S>9ZM*J#9=jREcheL/6/c:E<H&4
Bch#$l 5@dpy1Pk96DV@up=t<yIn9k=u%lj=81$uLPilIPynJ?VetK\ZttthjMcn@H?pl&>SYPhBX5:Cyd:tYFL
*PuiAn a8S*6&/<?8Fb!&jq:K?ljGBF!4Y6w#nudb99:N:^>Ma%l!Z=>4p?kuW%^8NCWWGe!M@im!!>I8XCZ+i%
KdNYGD yiZu?91$NNVq#6an*k:HK$6hub!Ye4dWFZM\pjb*XE1p/JctY#YX8?:5Lh#Y8Z15A!q@KYelJwc6TXHj
c<&<%J *d+=??MQLVWdQ>jQJ5*D%Sj5e:c%@9ciuan##S%dEjDH^\:h9*4b\MDkM$J&XyEjm\4cq=P&9!luwtAF
QYQ?b< w4%*bi4F@m/d#<jbX$6%c:B*n=5%#uqJk+4:YXjM$Xk/\EpytcJdqt:XZP1/9ZQ%%4de5ja<lHyyd8Ce
b5uREa W&Ki*d$#?@NQ4dW%u?WHE?Fk*?nyeHJh!c*hP^DuY?Qdd?*chtQ:FlVWZ=\<NuQ=$th^NRM6Vcmi=4bw
bt8S&* <pS8?5HT%RiKe9eZ4y\w!N/Zt*=y5N9G!81#@C+tMyJDFP<lj>e8b+5VG<4hZF!YeBc#%lX#MbWtP!tq
K:*>ED WZVZyFp&F#tN6iYM6icM6iX8d%>q65VQAp\Ma+n##N&=Z*>y4c9>:#?a5kBj1=@dmjL<G:9Gyk@59dN*
Eb8!HH F+=/>\:p/l8E1^<i*9@Dk*8F?jq5dG#@?45wCQCX8>n8T+p/WLACZ!Fbqu?\iBYP8tAq/9E8DjZ?h</w
KlX!ey &@HRWNpW=nhK<i4#h8^&6pR6@VLP+1I&8tL8=nJlLm4bwj1X/bc6mHN#>qn#CwS/Y%8Pnjuj<$mw?Y@%
ZDTnV6 e9n&^qZ5##@c/89?!/pHEZc&KAQ65jn\!d4%6@j8tnt<@!:mQLH:#4=^>Ni@Wa?N*6&#<?jy&?hQuQD#
BAw1i/ >YZ/J$951EkpPV/iFA8n5hnkA!6VD=WZHFqZM4<<<qBb@wFmjIZp@6ZbX$d/@\6uYlwcNSHBRmj4:SEB
\VR@t= CQKAu$8jq$Pjl?&lmpI%a5T$\FqW!NFA\5>cL5=LjZYpaZYtXX8l+%lV=6ctLES:Y<8K\8#abVNSEkI*
H!&T%^ ?n8^9@:1dt8qy1bmbKBuatS+W\^9mb/ipbbGkI%XV$I$TEin#M%?G^wk%FZi*Ld=H54la+htn8!jQ4kQ
uScqkN wd/:j<>6lJwIED!4h+/l5wlwQ#y&/IjdN//eQqY#aaPXyTY!>#6ZnbJI?AW+59\<bF*Nhb/P&^Mnn8Su
/m\A\j H%%dnK?R*FCPL@yhZIqKwF/%9&AF/6nh*N^\F>HV9Xh$T$SQ^<dEKMZHa/WwF&NtWP948mWmEEEiwZkN
VPE6IN B44Qe>+SEhCaHE8%bMYcubt?y/q$1KNml4>YYc^^jbb%b/Hn%5b$lHwMwY:K*NT&dD/jn\w&Ylp?uln@
-Abq<Q 000eb8f783200110334 Page 122 of binaries2.zip
L=^HQe :5H>Y?jQ+Vy*:8db!S6Vb/=Qu4=??6V%p!i9uV^?>jnS1<iPZDq/?QKSR?l+buS\h$uiwe1!W>WX%:1c
@kTKKX :&\b9u>w+w8y$%?euZ^!=8RnNDa@eiVl<eMQnl=eYPy@aP<$95=@@P:iZcn*8I&Ad>>!c<eYFCM@*dn/
=k@^Yw \>*d6<=P:6&/ycP?9mJ@hZwwJTuAL<uLLe*B16VLyVMmcHht\5umuFQ4mp@ZXy:B=#&1V6Y6Q%Y#D4&Z
#l>*@e n&<wQ:/?:FlqCaJ@6KLkWEpi/y>9HD?!6/=1JD6%hEZ1cHdKTFd!eGdTeEdmWF4<WG4eRHL5RFJ$j&JW
Meb8/J Z$JEZ$L+aH#+=1TwdWtSi=ImJyImh5bR6paG+wpSkm>qH\=\&^:t6*6Xyy/!+qJ8pd+PFB8=JE?%@BC>
mn!c=B Daut#hp&ZjtPY?6V^^4T^^w#^84Vh4T8NDdRY9wy9FRRw!c@w&Aq58IZ=<<>uyy<NHu/+btVD$<hj*Dm
QT&Stl /Q%nS?+hQVS>?MD$IeKm?*inNEDP9DR/eGuVEK+6\=i&nF#eNHS?8Q@eRM@b@1/y95/yu9a#*c%uPq6P
aC^8!% h#Tjct<<&Xy@54u&SFQN<acN^?84n6Y8Q%1#:uD%tpQ4!\<mV&+wQ%qjhc/n/eyA%:Ylu4PN%bM%/+=Z
d+ewdV =P@NVBlQV>mXtdB4Se18uLShPip:X/V5!E4cqyG\LV%8LDX&c*L$%1SINAVaHB??KT=$NCbpJIw!EpZi
+DHNXh ly=Hj\$QGMWZ@@8PBH5V1?@\Fd#+Ttp@=#+jS?VTZp@:Hk@ddnj4LljLhmj#Nu9VFq8nbl9DJm9>Sp9h
=ZN:6Z BuPhBnQ6ht?u$pAjhhqqW+/<*F\J*5bJdm14A4ZZSl9Xy%t$4dVy#4jjYyiMNFcZ51WtiXNN+1cYh=\K
F*u$JP yCiS^Hq=bETEyaYFyPaqJQm*BAYRJHH^T\4\+*>>@cRAu\V@9Hkq?Q+Y?tyL^I&LB+pLTa#:6VnF8JA+
:Y:B?F SDubWeKL5LMmmZK\mZK\w&jR<<R@Ej@K5jC9It!+lNqaF5VK@LhatIXatITaGRWb/hHRAD*AlS+\MRm?
$6V#R4 F9wuSuwBJAc/JcIXwH<6GkE/ZQ!E&Bnw1h/cAWkN<Wl^X<5L$F+V4q?daNKeb6GB@L#Kd59GlK$dp=C&
TtA&T5 XMh94w4dZB%jqy5A@@j^:</A&=9u?P5ZBP15DVjaGG*aqGVcut:SpYuX8hJ&T%We$8aNeb5&^G=G1wwh
^I>iT* 1$$wZSu:j>D?/WiRm%X=8HpbSY>htGF66HFnktq4pqp:<uPGbXi&>hd%MX51a#c6R+4iXBt>cZ*W=9XS
bnu$A& Y#bE>Y@M%qFZ?n>/u@IlJ5Sjq8C*Q5y<jdnS^pmV8tnnlqnV=unE&dR>^d\##cI#\&4V&5lNc!I&XWS5
Ftp\h/ YlPJHt>iG:FyZjnI&4CSNTFdN5V&4p@NVR\$$XI$$FI&$qX>Y+d+WR*JEJe/IR%DHR$DR9MQ>LZX>dVW
EGV*LF hVZjqM/<6JbJi@Gw11ImI/epI/<pI/5pw/Amw/Eu1&e81&et1&i/IQ$F!iE!YTwFQWN6ZT$njW$pR#%N
pIQ4Wb jS*$A/n1cc5b/Knn$qa*$FLV%%Thq+EYL9SAV$Qqdiu@LiYq$qXV%JRXD*Y#4E\JcEl%4a+\1+p!4a$!
C?blKE cak^da\^daw#dap#dW5$c$9GWZipY&!1CB<6D^>F^+1\VdlCS!6CSm1CS!4II?XBI^WBI^X?k/XiA!X8
H=T#y= A!XPk/XPR?XPk?XPR^XP@YXPjcZP@YW8@YZ8jYXi9YW?9SXB9iYW4tJKi&F\i*FaS*FE$?1RDbu?c%Q>
hNXX&S K%KRA56TAp8Vk$1TAw5Vk+wT!EZJqMJpeu=1WF=K\Mwp@/^E@>Sa:>k\%?AAP*>9K!hZc!F%K^A&JIpb
+q*R#F WkpbpKR6cL%#tc4PMNhMMhiiac+:\>^\l1Z^DH9#Gc/YM#^6b*kJ<dYj+Y&j=G<>=hHW9c$y5cpmiu$i
!uQqNN 8VI*1Lpm1thneq>NWu6bbH%iWH&8j&NiWF5?8d&R$4a/1GtqV$&GS!%Tqkj?INPnJw5+bunWyLuXyL4W
T<K?M: yDnZJD9XJCI=%CVa%5Vd%MVb%Mdb%MSc%eba%Mca%$hd%EYdN$TdNeTaNeccNmE@#/NPMG6QM86I5hlW
IbImTE Tlp6CS+yCWHH$hLk$VJ$JI?YBI&WBw/WBI!W?k&Zik?Yik!Y8A/XPk?YPk/YPR/XP\!Y&jiZ&QYZPk/W
@wWbe1 I<=8jcZ8jiZijiWB*TYBHWXI=LdC+L1XkS9Tjhiu?XYtB/^LC%!dGqTSGqTYEqTYVC=NIbepp+5TA%jF
Q$=^a\ ?c?I>W&Q>p\P>+kQhapPhpcep?P<<%cGqJepiFECkE?QJGqMJY^EE6Gu%9SpK6uHZH?i8Y/T8YGT8ZGT
YA^ilm 6YtTw&YT8*YT4^$ZQ%LuyEDuJF@uqFDdTj91>64CEIS/8C%u6G%Fj%%!W*FwdX=kT*FIX*qE*:4I*nWS
BD1d9J HWYWyq#@=l#j=qZ?4Zu?Lc6^Nij=N/*!1%@lZbj6menZb4nZy49Xy4uWynnZJn9XJn4WJ64ZJ6nXJ6nY
\T1NC9 Ih1^X9Y^quY^FuW^=k&+#Jym#JynpW\R=>aE=G4V>tV#$cKApTL!KK+k+pHkCH1t&H?p!Hip&Hi+&H8\
KtSAkI !GP\!HYw&Ht\^HGw%GG+#G/w%Hc\^HwAHW96B<45B$1S6>$G!4#/m4&/m:\:C*&d<*#454!4$:&4$u$&
$JuTdN bQm6V@P9VEYeF%CZJkWY^9uqSjt5nQDMC9hMD@hIDjhIm@HKVQDNVkuIVci5TA>MV9CtBDwaY=y\Kq8A
maKtKD tBFJ$wlKBB$N1QX<Ga9Hti9QMnhPMVhN5VbQedbN<dbQ<ZhPCZSPCTJ%LWmk/!^@^=Sn#+:D&!6GYnI:
EMjdhW %<jX=qPcTwL:1?JG/yKHN!d$XpT$F!A#B!BZ>JSRip8Ci$6D8p8D8+4I:jtBLVl1*+cXQk*bZ9XbHuZy
=aAp$Q duXy4uYy#uWy#uZJnuYJ>uWIe4^6jaJNZc^%Za^qja\F4tn#S8VucNPtGNNt\6K6m=ai!jeuFDBTRKnR
McN@+J d/VAd:nAh/VRh/VIb/nRa:DRhcnRicnIednId4nab4nEi4DIc1DIa4DEckA>L4EhKHXA1Q8KZLwK*V4!
ee9dSZ QbyZ86Xq8hhpiG:M<K4P<EGY*yDt9!:X4!Lb9!#S4!nYb*YW%/wI#>\I4=^\4=\au=\+9=\E@^XJ@yu^
KqI#!M 91t^uuHlLlHBn1EW^+Ra#+^MmwtLJ\kapGTM1WTNTBJGXGI/%Ic?iGm$ZGByttJ4uiJ1t?J4^\pLhW+J
Dnk6F/ I*Z@LeH8<?yhS@L1Tn9KKHXF\Z&%TX9d5:b%bA*ZJuTYluRWW:4LRkjYSk^9mB=bH#%WGVt\N4!9NAR^
PN!dd1 :!+mh^RG6mHW8RV1Fb=%YS:%ti:%/RV1bKi/bIi/BAjEGWehl#ld%T?k^9&MS$iMiZPeGSEhb1*^8K6H
\$Xnlt <u!Slqj=ER@R$Ye+#&ep#*6+6hjRc5?ljLil%T=D?a:DBZdDlVbDSRm!=WCS&YCS^Xmp^u+&CPYpm^hq
S6KCnZ Y&$1YiGqYlNn*LVCwV:L8V:V6R/FY/b*hb4*lqV9NeqibRti^dGiSdFiSVHilWm^9kY^juuSj4p^Qm8m
kye*#W 9NPnWG/+y$T/J$h:yCX+I#@ubqNY4R^PT@G*e4KnqnIGeTM<QbC^bR!y=C^wR$8a&/?\NE?^6$=^6$*^
PyAWl6 6?PRSdy\mTJ%@!%EY/:qRF^n:aE6yd5HX+>%bHbZS4WXW*4YSw#W^G&yV^^4TNyck$aNMeQ4w^D1\ZZl
8&#tyC jYWlQcWW*NWFki%=@5&4jB6#9B8!QZHP</nVCNSJDuXJh9Pw/?K5pKWdayE5GtI5ttLNt^DuYB\%H6H^
<=BZGP b5nT\#qim@Ie#9Ei!9Wi#9WeY8YBNL#KjTnQbVDQiTnQaYm%#XC?%XCB^YC?&YCBChKE9jkDV4nNCi*M
P6ni<p RKGHAHwk$\PFkSRq\JIp#=>6JJj9dqAebFEi:XTS+FGS+FYi+F&c+FMe=+M5ZSD65\4*5&h&tGh&qFh&
h65<K$ 9M?KSD?p4GVj6AVjlGmQ5BDHAD>dV$>LP^eLES$mP8S\#qTTSmSbR&wqT:1\a6ci/@PlIhm^RFm5i$we
wl9t?K 1YhKwke@Iwu&VIq$u:Z1*VjY9ZKkJ1/%I1^#VjmY^8V^#5#hubp:&%K*N!X61$<a1+6H6Ei4pK5nB6cG
a^YTuI >XiE>JaFw+LiWaBe:hie=>iEWK@\dFkIEBemRBBu?:yE\6L^N4nm4By\YVVFYVcla:^Fe#^Cdh+Td>/c
W=9+JR aD/$\9P%lqh/DK>$S<elZK=DPT/D8e=D1^\H<&!H<1!GXy5Q=bpP=lpQ4nab#De?yMk?\\uVuHCQE!=\
C#4uCV RBpVBNNDEEH:DaY!$!ewmGSbcbjEi^jFiSXEi?XFi8bFiiXFiihGi&hHiYaRjw+Qea+pP+RE&kd=&RRm
Gj$RV* ?h8ElDmElH5wYnwBCteba=K$EbWEAt=EJY%EdSjG59E\X?h=FByCHVlpSFmmi$1!i$wK1bhR#=RpRX8m
D9c$^c /+^%+*DLl9nN#epHS\4&D?j6:e$i:$#d%b/&8#%69DXqS&QTYG*e=61aVS6SlpRP4k*9L/jk4m+th^IB
NaS<W= $4#Ky\q^#pd!1M<kLJ%KyAhCuaST&4al$dal*1a^*4w^\awkdNEeb>FCQGmJN<M=b*5MbZum!9dEH&i:
1<YY\& D&Y:DYY:DtW:D/=\HqylQ:VTjmnZbmnZanDZdHCX<XCiIhJ\68+%Rbyyk9M</98eeJIh1ytAVAh?:/KN
Pqh?Z$ FCuEqi6uua<+S*utlLqul:mqB:8tBD5uWy#m!E+^FMiaEKi+CJjEGI@WJN@5nICC@Imm+tm*IE<RNRAy
bE=Pk/ \6KI5/\STS=lN/L*V8ab8IFCA<Y!PIFZ8kiZ#G9%VppVp8k=K>q=J1^:+P48wn*>K@d$4=#wY*pAHZ5#
IlEMAZ >*ct:&=L*6&T9K5yeWh>*BcE8my1bH*E+D4C%Vn1\I/CAIT/bbX9$$4QS5R=!:$l$/$?\/Wl*cW^%dp^
Auit^p ^dE^!cE^&c+^!dayEet/PeGKpGX#9CXCnTC*JbwQbLwNbLnn!9SAn\h^8R=t8R=qPR>qP\=tPR^q&\^t
kP1:AL Y\&8MB>ecVKRa#mWc#m+Tu>:w6whH14ZuF@4IRG<q\XTGHG\AY@VywN+Niu5AIj5EQjMaJiMENiMMA@p
GRpeQV =<^a#?\E:?^p9?^W@?^$@<^W@<RE#@AIb%<@K*MHM*=6T#!mFa%JW4mbTayG%LJGhEb8uDphk9%ZSV8u
!uqBkb JL5YCM9&VMu%LlH^nA#B*/l4j%qZ#ithJWi*Fl\e!6*jq:&@Q@6Ad>bEh<c?nqTEithn@I/G8LHc&C*X
VBKMD^ </lD?!6CEi48+1CPjH?E8uYXd$88h$8Pb*P&b*PYi%PYT%Pte*P/e%Pca*P1jZPKjZP!dXPTDhJ4#1$J
Kuh!<F qm&JF1&JF9$b49%y8AdTF=ZlMyD8NJDlNJnlMJlyQ=lyM=lqNbl6Pyl6QLnTaGCqZu?&%pF*5delL>Wh
SBZnXc VnnQAS8bIIL8HdRyVNTIhk:FbXYW><wa:?^a:/^a4:Ran<Rw%?lR=*CKjXCA4b?96di*lai*ld&dybml
4QT/JR JS:SC5apYYM<wlYM1BTN/BYMYH&TlQ18muYjqi/ip8*G\e4*Vmp5q#\BZKad$V:4N4D9?KbXi:5#nt*J
>qNly1 Q:+q@<l\:5Hi4Q*h/dm/$9c$IqeudK@DWY@hGDY/QtJwZWl@Pey1TuhJEDJ&b%FAP\:e6^ZS#9X1ZiHb
:>l5/! p8*YuPZTuPHenFCu&DYq&Dau&Vau&nRuYVena!hb6iC!dE8&/E>*/W<lqQyc#kNyV4nTHRdT:Ra!dAa#
/+XKt@ LAa##Rc#nAi!>Ai!hQ1!6M?y5L/dMAelLyntk^qiiCRMM+J\qA?cPCCbGj\b\JeSAlpZcVNRla9!^Jq1
-AGc=& 000e4e2d32b00110334 Page 123 of binaries2.zip
?R!Mj6 JqAea<pPWaH&aaF&KJ<y@4awuAMIpTq&@1HPMyd&IIpuM$JNlT\6b$T6ap\9d<mmae+d9pym?D4CKN<#
w1LJDi yhA#yhk:yhk*yjSc9eR#^D@J>=^X/V+XNdDy?4H1+%9#D\*uHByciY\p>>n\!pQ>tRi/$ma/W9c&J8%y
+&c41# Th#bELi%Ntb#hhSwXiVI?uCWIRP+6$Q/!qBwp*8KAn9#@h9#9N5R/t\Q^Lpy!:py*cp=HducwVuXD4t/
J#@G#w PRXH*bJmnZNP6tyN6pSW?=MJJe$@ePyQRZL5V$X!GEm#G$m#GWm*HEk*G<\\G5nW:<@W/e9R95NFiyM\
JEZGW1 F*EWkYqlRpLLhF<IuknDhREa+abmhwltlXAYCGTGIGak5\CFlVyMWTVc#VR/!C+t%Dp&*Dp?^mMq!Te#
GZYY>k $:?\KKJ$Vd^dmA?I/8P^4G!MpyqK%wlc&alB!alN&anHmT!?edh5@$WEE%H>pBD6*uQY@ah:B<8Pdq=%
GD<Tph cpj^mY&FS$h#n\!8PD!ahYRk<*B9^pSu/6:Y^N$6md8cE*a$^&>9nB?4n>>TE:8yKuJ+R@nR86CBMnTm
W&8<lD Ciw1SJ^>CFh:61#\cM=&d<=&ce=$c5=\dE/#^%Gu&4cp&4Rp+/ndWt*cW1%:W=^/E^*:Ey#/Ey#:E=*:
GE1@tt $PMpy@+pl@=p?@+WJN9?XJ8BXM8BNLPBDMPBDIPBDJ*6bLtbyRbtj=Q1B#SD/JwkZBTALV^R!k=^LPDF
LF@a!5 BH:MCD5ytJelYp5!&eM+P!M\P#M\Ne$*J6:N&>>c#5AR>#P1kC4GmDcXnBGN5lGn1lGHwlG*8yF\RKL<
c\Lab1 +GYq94Q#QBWJ#aiG+1KjqRnl48/c<84je&GmatI+>@Ct%We*=^@huHhpJPj\RCb!>eE?uQcl95!DQSpH
Y@EQ++ i6L*hcV5dp=E6Dh9nEa^Mw!:t6JZT8p6C8\8>P<5<EP$&*I>Y%i+NYi:Nte=6?B^:hmT+hCed6?CqGdd
DbCAHZ ttddqtddutddt?#Rt?DRG+@p&J8AkM@LwT@S9n@J4n@J6n@b8n@Fwn@X4D@X8D@NaCBh>+w?>>%=\4#9
SFX\jh h8<uCyu<5VB<IR!uBYAHD#S!Rk+:JLLkD9hlIRYIeRSwTQuccL8:Gi9ct6E1taAM+YeWHVJGhEyG#P4G
Mc4dck HMyGjM4/Iw+BC8$uqQ4P+*kS!Y=eewVpF/ZRnhNGD&T:#8q$Hm*91:%$eP*^ZTWHN/@in!CQ=l:jqHh1
nZYWtH 4GB!Y<HW%6WuS*PQDtaj:M&e/ElGMdKnQuc5Jtd#^5lNXSEnqYHDc+KS1@6KA45K@VyZi:i6<t#NScNk
VY@KWK >=cX4m*bLm$4uF5#pb#cMl*cM8*dM?#dM?$/Mt%:E8%/+8^:a8%:a8^:a^%/+=D5i?Q6?^L5CNu&J>4$
56>SYA J%u%J=9%y=n$y^4$y?yhFcPj=9/ZdD@1>u6CeE5Rh9NCL^eW5EEIM\Rn1@M!t$8ICakwW!5bWTpdWe9k
>k9yjT SbBF\+lV#alj&XBE*$It9ply>L4CItFbuPiWDCH$RHcS8S^/y9P5jMebe8@tR=6#h\&8QDbihuym:hTB
eXSSD6 !uQ:%$*6Ly9eWZlt!/wVI!8QIu9*yB@5TmXCP^q*hRNiHDhXla?5C^/5wQTZBjcXBHRZ+c:8ZP*Vu8@X
=PF6CF 951nLhi>Lei6Lei%jcW#W65Ky@a5l+=5?++58?=E&?++&?=w8===^TDth4&^>4%^64*^6u$JN4kT4j8V
GjFHwN LQ1VVj6VnHcG1iJMlQ<uuF<L$Z+kDA?F+dakZBKEE@^\lB>/8KCCp!1Sm>/Xp%XZRESGTp=WTXNI^WBW
eL%CQA $$nKP$K?+=Se:@q=9NKEyBajTPN+y&R:<cN$^=SE^%ubqyM^@RM#q=w9V#cjQXy#itLh5b$qS:aXHN8<
<quTbF /5VtXce*4#1#PjjW!Iynk%pHi>IuPyQHY?K*%<h54aueWl&BWI>Ylk+n&t9IA^XBjYWBQTZ?ZWY?uaXi
h:L<=+ HjtiHc5>P%c=h?T+h8R+h/^Ae8^EYtujFY@VHa5+&*bH&ubH&jbE&iHCkh9&^64&^6u$^q9*JTBb>Cic
e1m8VC >TedV^4#@W<Jj^k?Iw@1/XjCeFeR#knAPB@$eWMFL*&IEK?V9ch=^u1DNeQ1XV9p/@hLhy!S/EIn\TuJ
VbByq@ Vq^TBGGynmuJnmu^6mu^qmu9wj%ZJl5Q:C#b9:Q+EG11h=ih&q$?8dh5c4\Eh@ZYXan#$j:MR>&y?#8V
wwiPHu >:Wu:Y=N&NWW8/M^FkhiG:t%PtK$Kt!ihq>=aG<yR8*VYiTNw<:#/Ml#/%nq&yH4QK@PZKi8PP9PGJ9P
1BRd6t KJ88CN98CF9<mAP*Ri1J68/N5i1J6i1N6?^N5P^LMB8MMb\Yyj4@m9N:C/5k*JGC&%J\T\18!hBepcQd
i5!y>K K<*a4<C#*6a<&TiRp4DcLt8DjPWPmjayCWT+hW15hW1+>b^c/>H!ka&uDqcePXp@hdJ?<8nGp@9ZHh>X
^iyyNW jH^d\jE68Te&==+eZZq!PQ9+aNc^\e#DjipHi%KS5ji&Ji%8mh@bGL66H9YG$KF%=Q+%!NZ?QYX?uRl%
cV:GB^ wYhHkYhu9thukWhuuq9ucyi8QGip#nnL#lnL#pm4#uC4#nD44uAp^N!tP^Kl6pd1mdd1mdH5ndZ5ndea
l\NSqd C%D@Z!jGQ=akVE9C6QR!*bPG?#K+H1CnNH/<1\SVcw!:>EZG#iZ#dR$nuB%hQRImX&TPh&d8HM4h8:%+
K^HMAC @/:TA#8KD8<5ReZ^%M:m$#8Ly*aYu66ieHb5>iTY*FPdXl:DE^6=P&qQc@!8yyn6hXFdN+b9&lA!5n+a
F8u:j6 S:$&5K<mwL9M9/9W4:Qay/9a1/9R5:9Aw/9R9d9A4d9A6TQGwnQKwnQT5nQM5nQW1nQE1nQW8m9MBkei
hR/I<i ah$hchWhbhpVdatnn4M+cTn+@!@I/D>h/p*I!!RD$\w\4RLV!k9/WS@t#AF#AM\djm?nG6=Q*%EGSR+R
dW+DL5 d</TVbdhtG5@NJS+c4#p#P:T5@9K#8$8P4en@<!YuJQDtWeH$k@%yP#9VN#ZF4?:JY=ZW@TPl1m^?wm6
j$*S@Y G<M&XTHcqKH%=IF%=L+%@4%4@L9L@dyLjZyK9ZyKQZ8KQZyKQD1m#V5mLVwmLD4DLDyDLD8DLZHWIhcI
iD#aJK iXjaG/k6ywXJ@#?CLLIM/R!l9=>B@JZ?^96cQ?uBK!9ACtA8Bb+Z\6dj1dDhMLecjw/B^*+\dk=FKpBS
jjCk1R yA@VbE8#FGyI66=SF*F1e@cypi!VR=uHB#PP>Keh/p<=$JY$4#Nlh&9e4tcW&FFnhSFdc5M*dR\b4TaQ
QuKulk dCD*XRdm6Nj/>bRn%N/>=X/>Jb=6WYd6Eiah+Yd6wSah\SchbI5P!mJ6HLXXX+SXh/Sqh=VFlJ*5\99$
k455FJ dj%@AqqtAiq>+4ldBA/KEw<Sadq*R$bQ@tRA5<:\W\Qe8$\#%\IQu5L\n/RZG?BXA4!KBM\LMDj+!\bP
G%Tt5S ceM/CWkTBB>iCBGqLZhZ/%9y64<=:6TtFTiG$iA^:XBj/wH8yL$heiP65V8cw5acI4dWla=YW+a*INSB
nDmype jbWB9Y9>i^D1NV/>Fh/>FX=6pTb6+cb6acd6wYd6\Yd6RiahRSahbI6P^D!EeHmabXi+bZi+?XXbSl#y
e/iSt# P>?dk9@9B4LM5mmiEIXahklmA#Id>A9DA?X*ETakV?9AV^a\/\BjD<CDcdn^QcpNw=thkqi%<KwMZmZB
6Fn\R: 1&B+=RG9:PCXQd\!lqp>PK5AbaJA+RI!wR\6\i+My&MD/Wj/W\>&I%en#nE:t!P*Nab94R@dXB5!WpMb
t8?F<l 4Cd*d\n1*^DaX?tQ%L@P4*?hd&8EeY8+eX8wTX8IcX8\cV9b4D*R9CPRRE%=nhyme/DBjSp1@BiWiqep
AMij^m !5DCQ$pRXWukj$NikQn/^HhEyi&lDI\KR\au?LJCEC8RPaDMCj/w^$an#delK<K$N5HbHF+=\P@y<E5?
aNl4kB jL5bHn&A48h\@RL<eST?HIe@T?BXKGD#6K*lqRqk8wBy\a<cMC+NPj#k!RGBZBAn!bJuJnXc=4i@K&F9
mW^5lQ i>!i6ykhLXHdtmLHGmP&%IiN%weM%%EGNyIH15n>G\MH1kMG1kJcIw^c\+%cR+^dk$*cKCb6Rcd6kjPw
DNCnhG #RuW=nn1WI8:^9!aE6^E:$hXR6Ij1#+!^F6d=LPYQNpFA%?TlE+BmGRHQ%de\&V&BdQN!=<V59ukllLM
!=861! LPXMREd/*k4*<!6@iBpHZ?/FK>@A4n?a5T8\=^jTpcj$j/$q#YZB*aQ\MkZt*GHYHGbNCGuBuBbkPuBL
pS=G:n CawEIa\dAnn^:=Y1^6iZ=:/4JZJQh>^+b?#P61l6dbFdtmM&NacQNIaPNkRQ%FIG/<mDNaE6aaa6wWbI
TiAk4I 4eFG4YVn6mCV6pDVh9<q1IM6i5ttL^VlySa<W+N:XuAqEYdWmLil*MiAT!?c@%<:HH&Y&MIZiWB<\Yw?
+Ynq\b CGjDW&I?KMme!!DQK+kLI4nk55JCXm^ASpeV8IW5/km#:nAZAw<&\=Xyh8\A*Q!i6GGPCV5Q9=&Ae\?y
V=9QDj V#\A4Ai?/PS==W/c6TA+w\#Sl%qNuQa4LjlKFc1F\a5D@$aWdqKECH%N8Mt?*9k>QZG:PtP*h$TQ6WX8
dweaK1 dkpjdRwhcRwhdkkidKA$l?w*l^k$l^m&WA^d!Wc6RWc6Aeb6jmb6CHYAiV5SIL65=Z=Tk=i/<IeXuP1A
!yuJBB 1X11i@1ETXC@JQ?^#81%\=EdSRqw+w9aQ!A^RlILd\*p+dMTWMtLk@Yj^<6GBMW<YB+ke^NH9tYKEIAy
!CPuTN VZmp8?DpcjR#t<I6a:#T#Z4AdAlkmjB<HGbSVV^CjiwH1pwM&nCtu/jw:<!RDu@N@:!C>M1jNG6NRJ=*
5LZbFn 6TuMG8LAeY>4\$NqcBABd+I&?nGmJXuc5^\R/9H8tB&h$YPhWX9cI$dd\phc\pbcRy4D>JyD>J5yB4mC
=BV$6= DF5CnX1S@PhS+^tC!8IXXcb:cula#j4D<DG/B$E\dRVViw5%@XNe@e=k?aCYD#wPmC=GBN6dRaGR<pPR
IZ1\DH PASJ95pbKbkQ6mnA#D^uM+K#Nh=W+J#JMB5D5%p\Y\+9B\Cdk1Fbnyq9+GW*#BZA!>W\/\i#/JY&MG8*
:Ew\yW !NqpCZBCtBq<4RtbAw5@CS<pKHF54R$i:+ud$SP:4VN/T&jpyw/I$jd\yqDhytC>=tD>bnKTRZMkkV4A
?^Ai\5 1NWQwVb6D#Dd+1TGVH9QBH=#l4qAiDbChdkh:69ANQKJ?tL/!j>#%Q>EKJBD&Sel9\+K:kZIbAt\6!WF
8TTClj !kJbEMkCC:>9GD6+KR4a1Nwce6J*KNE<N1ibeSca6wFd6kSuqL&lMB5N5+u\Y#Hy*A&1$d@EcnC+ja5P
:W/wEd /+QbFVAdl=61%lN9AuHPNwAHmQET%McE4GDPAnALtNTAMH+IIL+%SaA1#%=tjCB8b%@566/wLh$St:5n
4B>F5R GpN$twJ%t!l/#YT>=mD>=mCDqkDDqkDe$1&Eyc<1M1L?@#!F/6IaQD%P>cwSVp*BXB=MG<C$=mJuFeLX
mhIKV1 M9<4#qipIJ^>TXC<lw^?KWH\MAeZX#T+ALIa?l%^D:5yC51HS*BXH8aZWJRREkkRw19REu^kDhP&mDMX
!$>Mi: =p8aGZGPkqqW:>IBY\@HH>D?>nZ5@^P8QTHNqSCe@RnPdkVuihuD4BqSHM*kyS5<n\dMA*+6y91!D<?m
e<ebc: F=dRJkNBjLnRD^ay^hm/$tHuaP#Y@8k6jVnu^tChJwy8W>AC=*qL#/Mih6K+K$*CTi4BnRn+8k*G9+G#
Tp\Yl> ?&HcBcdNmVjn$y18<tqb@R?F?4hiRRl+w>n^Ey!SkaZA*\TCDIE5B<Hm+CjFKB&X\qLS!h6#SE#YkbhH
=PSwu: $FyDRnk<\WmAN%&V@b+u:S$Q8q<D1YiDCDPu+b^u<&G&FF=%\:MyKJ9q??+Y@NWL4\ykNwLIDc>F\p9q
-AB!H# 000b09a078e00110334 Page 124 of binaries2.zip
V5pDiB Dlkbn6!EH^9l!V:+wkE\>+YZZhiDWAEIIu+\5mm5wYl8H+\bG+l8CNX1CNb8JP5kNRZyNkj1NRjwN^PY
eMmX\M d9E*t6Vp^NESuFG^96aL9?!Cq/9k6nNMY?QQ9AQ%b<J:XSIj*$%K\4Aw*pe6k@\/MhAIRlneLcn>*eHS
:Qc!NM mWe8Iy/y6IhlVV@L^mEJ/%J?Lua:IX4iwt4GnZ&</RWcRy!l5uDMn9SnGN6eHQWeet\&wV!aZRh@6eCV
5iWN\J B:DlPY*ZK>a>*@E>PkZQW+nw<CBR&!>c&wq\8B>iS9>5kINQYi<>k1?ccX=R1PaVBuPG*^!lTk%<SeBH
q>S!<I k<4MmhE*TZ^LZ%l>mGbD5FaDlWAhSKBG4k+\RKl:QLWZ@KqMyLENZF+LD/?TZlVD%+E\:aCZFd!+/C%H
j*:C<m 4jy=PK@uA&<&<PF<!<tLFRe*nCAi#t//9HKJWjTFI$^F*ak#e&Y@SPlijua?NVEi<hTXDNWDVB6/GK1/
L6=S\b NjQ8PJVj:t^I?cXI:?hGty<*\Y\8#K*CIe>YA+c/nwe\l6H@eRY\Nuk%AHPyME5lWH59Gy9Rm$CaDRa5
^d=L&J H1au/B@MMGJhMJ6PyFAwQI?HYS@<5:A\&FbJ+^BKHiAP*q+R+5@TEKJSH$!kJt9Qe<aDJBBQn&MG@Qm9
m!d^jP 4ESID&=G\yW6ePRy/e<i?HM6*QiFcWemyjWIX!8>NemX@FiEyiASCk1^laHAP#Vj9&qAKD>+!:FKB!Y#
REYZpP b4e^4iyq#8>tL8^tK8wRVN5n^CM8J5B6=G#F6K/H1dKH8dyZI9ipbNCBwydeL$9W9!qpQHGQ@/eVPN:H
6YCct! S^pR%hq/tB$C:CD5@a91@BMtdB%SCyPIAA<m\n^\RXkA*N<C9>aC6kJ&*&H?<p9TZA@MF5G4eulSB&e9
+IM=w4 MYAJMBeP5\p\&$c19$%N<RD>AJK:F#TF1Nen%BTC<$J/+EHh/c6>S=aacC>!t#GH1\*WF*iT6u>Qj&W9
NCcqi@ HB8F^@=\w\L8tePM>tL:wdVe&HKjuNlTC@M@>=Slu<^CS@y8<RKFH=\5SKVI1jVbR+\4?ylZhnP9/y:u
VhIDtT #Lh?WpLcWXBR!EbduG:DMPLMYNuJ9i+k4=KnwlRX?6>yC?i<5lN&@<n/@A46k+i\/*j+/SLX<!uA^8Cu
Yc/WC@ c%TD5#D^NheZ&\FLJ#mnDI<pWM@VDwiZK?CZ9cR9uyG\b9nlHA#M<j^!B=:9kqP@\1$u<MNy?HaMZnVC
m#>e+w ZA:<9lM8@\1u>=E!QTFeFhyD%bGq/!mc>iRF%HlNJP8h$PZBj**bSZQ1+n*#nAPe:KPcPkJ>%=m9dCMN
t#BLTm :+QhB&G!GT+HL++F6N<%kjQS4p>&&i5n8N<QidHHMHC!yp<dap:9b5:1b5=b+M^YQCKluedL!&Pt!Mtj
+?Cmd? Y<qW$eP$ywi>:wCR+TwPYS+:H^b@L*E@Y\ni4b@>t&edynI<T=$^J%I&^:LlPi>jN$ujjWFXn\u>il!?
Te&Hnc PRlaHn=^PleDe>GLmwYZ/?Hea?bVQ<GJ9*D#%@#PunXHcu@Bi@eQ$9+@?A@?\4dyBj@?q*D+96CLH9nt
Lme@=Y PG*#4<LaKukSAG9pwChW4TXW9T=+MV$w8KX:9NRYQKc+nQP$Qe#+\@WC8NbPG4wBE&jlVBee&kH*Awu&
1<TpuT a#=AhIq?V?qhM=MKd&u=C&cW+b#C?!HQq#<B9Hq#W^Ym#h4MuNHNuE%\#86t1S!W>N+1\C85Jep1qy#L
<DhBkt YNHHXN:N8HFA&LPPV+Vd\+FiL$:R9*jK?!h5N:dl%8@PJ%@A>Fj59%&F9?:A#G>WY=?#D4/mQ9iCGl5G
NJhwJS dAQM=eNeF5\qAT1Ze%E\q+C*j*P=<Q5R@HTTb8NLqlP@W*jPM6:=u8HYN$#D#:t^w/SZP&HtHQ!^qiG4
n$w@CA GjyLn&D<b?H9n6DN4aT=IH^GbVBM4VNW9TpWyahtjVDSi\V4HNQlYiA<j!bCp/BumuPihwX:FDnbAZW*
y&e4IQ Ge@5w4tZB9eyMP%EeDd:i:wGj:*i5lMbu!mEiy@$i*KD:&@P>8y!hNtnj*M8/BbM&CjA#TIy#1*6:<ba
a5K^=D lmD*MK@4F\@h^!+maYdG/pBl5^$?:jReC<YPaH?=9V^F<?5b\Mbldl6kS/D?BjQ?9&nQjEH%em@MNeNe
J66t/Q Be\X+mX!LuNS/jkkec+eZnZB*Bc+<\&$9iI=@nQ<5Ij$=T&a@IH^$Vk6XkFaPYAh5QNu^69j$u\@AdMF
Cdt<Cy ^H<VBia<aXPacu?aYu5aul:%IXwNwh46AS4+*II$<Z=H9:9YInwLtHcDcV?aDwK:GVA>AwQVeKTHHne#
eDNiIM c9Q5mDdQiQHFPp8TSJ9+Ip49tZ6@T/jq*<YbcJkyjMSISAAW*TIaM@9^$Fnb#bVd!Xh?XE#SRWlE\NJM
Rppq@t k1YpB?@8!nwE$k<IT5q#G9M:lDD+4TpNuecKb?<Pa5qZj?b<haB14lQtYtG8G%+ey%4>m8@dB%#aIbkd
B?d=9! k4p8tEN?LwY=I6#A&G1<IZt^Dae<X\Z*n5P9%&H8HQ#!FK=>Ta&w@6RHM%9^q<*qEc>9ly5@\=@Hac=8
alIhc/ MZ\m+K<e&BctPl!1%lP1*l1t$SCtmVmj$PJc+I#i%^4+>M8MHn/TPqWF%/Qkdk:eS!%NP5#WRee6^t&u
T%*eES /i:pED&iHYFyW!Ji>N?mQi>\diILcm^Y#PZaWRY<1kmV<qA5?K/++AMjWR=NJS$qcTXJ^#Ct6F:t#G:t
Tj>YWm Fal#F$jlhlH6bC=^ZtM#Q1:<S8dTH1cTd4/%y$Wq:eTp?N#e\HF%VNkpX9dmJ9a5=8Ce$5PdNM?&pdBc
eYpBLT tK8H8Tb+9wZt&nP/4ZNW&AYa*R=#cHDZBNkctF5D/DXu4nI?QWM/?!NkA+C%\>uH<DN/jBqtn<Cj<@D#
jelc6= <KKJ?#ai=nLkbT&e9A<H@&LCh5HVeWAN=K6/iQTIhm^MbY8+/qC+iqi+ip8ab4?u\q%l$kJuPdn6TdwX
CDJt?A Bnh<<Bd8:Amec/Vijw#l<H/+XWi/Z\=>6%nQn<KbVcRbL+K#FeF=91uYjR9!&>JdHNwRi1kCwX^+\^#$
VyI@$9 Gm@**#NCIX#AR/=mVllkVl%pV8*BE+M\M$9JwKSjQ+?p5Ik?t&DiT1cTQ8cTd9c1MS/nZA==L6NA89BM
ZRV<C^ y?m>tN@ed#h?#bp:wQd:ajl?L?Ha6VBZDZQ4WcLTnD>n*jIK^8jaJu>p^QdB=CQPb>eA/\T5FX+hI?%<
9^jHVI Sd9:L^J!?/>u+i^#YIW^DM@TQ4lEJE\^#CWVAS=F%MyI9NN+9kYP@WJ%+k@a?bL^&@N$9>/DL=:BylDq
jNW18? diG1Y<LXBmLWP!M$#!t#LE#<#8iGCiuWSnnYD6MleH\*4L*D8H?T@5RW:L^E@&kIT8=#*P/At=p\+$&M
kY$iNp ^P&I*DBh%H!MGBMPS:&KMjGMCe\a+JQaM@yL\y#RX*1RI\JB9ESE<C/dh1Q\k4JNKHNeH*NCN*N!>$Kd
KIjn>E ke!e%!5SeXcRS+JjYpAy\b5Sl>#D9Gba*Q5Ak/m\5T&LjmSdjM?npJ>jZuySPDhymaIC1\G5qCl#1+pn
uTA!?$ M8R/\Adl/W*c/nu8R*<^Zd4F8?59>kN@ALaVHp*l%6$+^*d#b/yj:5P*#&D#LN8S*/t8@R:uuuDet+Hj
@eDPqP n\KGuB\Me&VmTMHQ:Z=@AL:b#u^4t8:E>/Tl*/tP@EV:@VlyMFl=c=n16pm%VXH1P%&q@y=hq!ccDSY+
<XmAhk n*1=*ZCllZ4VKbwdY/n8N5CnI6l/SKn=Fp*#cVniV=wJl&q@9D:m1G&JGDhbqCu^X*8+6Ay8BJL\M8wI
y*w5Ri X%IbV^T#VyZBQcPFFtXGB!=y\ynm\u#ZG\4lBp6XVbcaLydEd8aWAuItEe6=ZZ!bE/Imi5ICjGa&!1!q
6cZyqL ZRk!a&tuePI?blFibSM8:Wl8^=E:b4>n+!<G5Q6?e=8y<cBaR%T$9EZqAKyj9@jV@jCIc8kq:hw@=T=n
lEtA\@ WQ1T=<q9eP5d1ucM@ju*>DP9cFM^<T1MNl8DWR!9t$>8eB#+niQ&Wjm4E4Akw6L=L<wdMDRiVMDD?d6V
WI=RaG <Qk<jHtC>16Y1q/K<uCw!qmE&4aw>c6!DM5+E/jtWTN*M\W86XN*VwlPhhNP^<P>DNl<ki91by4yKn!w
V$!=b4 y!PJ+nmQ&yX\>XLb\n$ZPD5K6*NlPlStA1F>H>8JMdkbT@\ZtPJljqeH+kWZy4uiq4ewP%6pG?:pqNhP
=YCy1u :tHP:iE1*!?lG5:H!/?uI5Ch5=G=6Bj%GKI%q@lFhJlWBYRDcN\4/5Mja@q#y<4uaq=hab:hB/<GCe/=
Fl+4LM SQ?RStkqD8V^Ca+9d6K@*AEH9wbuN?HBD/VW**p/MCmbw**&DhYV*?Gdy*DnJ>LKPb4jHkAccD@cV64*
BP+cE> nQVLH5BmCdcid!paV+>#Z<PZ>aBF\J\Z6Ae1>+iwdAyZP?ak88^5$i8?D1E&kn6iyMpK695wl<p\E\jH
\Sd#RE DqIhQWt/X\LVcVCNmFEI#l+Eb*im#ZPCi\:EA#iaeai4NhB>Aa+*M5+pR6>^l8qCtQFh#Bp#8G<MY^ZB
FVDE!S q@jhuQWMHitVlyqV8+p84we=y+h=XR>Djyi+c^&*mKC1NLN5akbVYT>!M6iGCWHXEEbbD1EAdyiM#InV
&Q>::L YNH#&>l5>PC5?LXu%D*Qca<@k%h4<G1%ADq>+alqAXbE>HIwXZ4l/TQaPRi9d5LPF@VZHkN1nLG61MiG
RjaB/a dw#&&t?eZ+@VaaYAFeP#DkK!P<\=\=#hwy^^1yku@LKXCu@nwQ>VF@#J=kDq4tCXVaGK6<Yy*%^M>Z1y
wi@l$b mV4StJpTjaW4#QnB8Saa8p1/9Aj8F5J$E5\k%IEEcu?e<+\Q*95h#!QhS#+QIQ=4E8CLenl/DtdY\d:V
>qlQjS MDFGhTeEd69AQV8aMaGH=6ClDH:9+S#GAdIiCW^bcH!NE&bi*eNT*C5be%TIT=lHtW<8MaB&:Tkc?4G8
iPdVCV &Ty19w=QlFjRZWk#^!F1?%#Pu%@>?W9G%%>y=@@F8iMb\:hH1Q>C?d\K5FVAWwm*h9RTJRPYm/?j?ZPE
KhXJ8m ?w?LyD*QTTm$4*+LF?:m$$4aS9n%CL!/C5%#*C<uAe5HLBI\Q&K>l!%k>56ql/>*\ti&*RC#lnqdZHZ?
Snwp&? !t$WqbN/ZP<+B!1#bER<Q>a#J+a1HuB*Fb#d^Vk\VZi4Bi+Z\Npm?ypatA:G!?Y>MLlTD!li>8^ljbTM
Q6>Lnt Q*M#CTb:wH8ey?a<//EnNA*ZYi/$\W\FXCnBwA=MGWCuMwRJE=N9k8@knI1k5:\wZ9XY>#Du>#AXh9K6
11JP:P *m<pw5uQJ&AWwMJe$eY$6wh^dchkaJ8k8IClEah9yGlp^$8QH:C9jqmFudh@hSJcZ>E<@BK\VaCXAbbJ
N5MeKC eI+lFL8wGAJ%P9!!Ea+@a:n>I?t9ddlnZ=Vl=FG\wNKJ4Rh5C^#?m@/Za#CL$maeN!*t6MnYEVDmNNdj
b#tbml Ru<%@@89Nj:K@c:T:#:ZLLN<>bR8$Smd\H%ZtBlq*H!B69AG%a+n6Qe:+QRSPLMh:1#A<V=KkIdn\u5Q
pwHeVR $$@6Ja%Q5E!u\y%e/J?p4b$tQhkMS\=SuhlJ8leLD!lR4Ac?\8AyCL:<m=Du^j?*RuklnBP56bTa<u1b
%nXhCq m*6Rd<!=>wmWSk\jq/C&6mSZcV%nbT>VdV>j^kpPIWWbXV/9AHy!=$&jH?j/5Lc@duymw>RwVy?jll6Q
K1^QJ< 1M<@a5CJJSNII\AL\W9ak5KJJ&Q^+ed=?:S@hMD*E!Ve<+tE:hF^Jd#amNwQ/9M@pFAZnYWVZ&GiM*K9
5YEL4: FYDGBFnVShyGkBukC#>i1>bH/dI$@Z5=T!>Pee\QDLYJ>LCEcX>+5AKPH+VcY*S*#$LLHck?\@G\FKdS
5J#MW/ PDEHH1!F<:6I%dhJP+:BhAYed+WNh#uG46E<1IZyaynP^CQ>QluTqaA5mb>$YAb=mj^F/DZXhIRhR^q!
-AT&\J 0007cef98cc00110334 Page 125 of binaries2.zip
j=d$?? 8ykLi%A+MK@yE:W4FPDnWlHqqMli^XVX!%Vh\%&$n%qMSWTY*+hCd:?1%@wY68dX1jN#Mh>N51IGGBj1
eDq@nA C6dBH=8JbIkmEJHjWlB^LIWjGwlMRAwpNG@:XQn!JH*^F*#*9+ILN/l8jW6/Ya1jR<Gh9JV\9Im#+Y>w
!a*Jhj *QD>/<bjV!A4LA+wF5<cw\KHC6t^J4m+Hiy8$:jia4w#B6PXMF$A$:W\k#kjJR%iab*blQ@%RSMe8ES%
abCh/W <\ye//h:ZAmQM8BSHJVyRaAp\ju>1ANE/FlV&=q!?=pLiynKill4?1VmDkm^T$kK</mEB>A*DnQX>uJ&
/cPlG< :SHVDtiVEJF%w1Y5KjP:mFt<tG:E<u@<RlVdVEV4PmI8XkPYk!eDDm%\CX:Kw9\B<<EZpiKS/$&<b9==
ht^u\& Mn=y@#IL9npMh=+AXkjjn=Btm?DuJtLS/S8E>h=BiF+jY1Mm5Z#ipyn6u%>6klhEH:kZAVPwDt/Fyu8p
#bPnSd k=N\hRJ8:wZSP:RQi?DEEem/S:j9LD!akN$Zaj\1ViJN68*Z1NhSaK$hSG5AjuycB5lTBGeJA4Z\+mpT
/4YTQh RlSBCBTma$>9^tP=6Ihldbhk\TElDlplLt=Ni&Pt=u/t^l/Y%tFJm^w8jmaDR^ddLL@a4Xn&:$?jampn
<iT%&Y #<%cMh1HM:R98\uPPRVuXCIe+ld^BlM\9jB#1dk<CZp6LGZEZBij><Y6@te=*L>Gi@w:%lh6XBk^&+<K
4HR/Vu HK:ZRaFe4dpE4M/m%AqyjB4u%^N*cwTq4iGPM>\Nliqp8J5N&<<!X><B<nS>=VS:\X*/$=iwyujC>ATM
t+1kHW *1SbQW&:hSw14wytVMQkLhL=W+^qFAnRB4IcpFZ\M/h@w==*>SI=<>Pwiwa\=*a#F?HV!B\d>+qLl\n!
QM!S:D Ccq4TLG$hnP%>#J&>$lGHSQpFFYR+@aMEw<c^tJ?i*F/dk*&#Ab:BBN@CX:?ukH4I#mn8Mkk#B!Dt@N9
/T*KF! A*58q@8:PkimTeQb^8N#eX<jwMM#&aHI=HuIS8<!5DJkC59$Tb#uydIRHZe<<ZNa^:e!HN<B>$6RFFQ*
j4R=P/ *cWb9+^MT%X!k&9<F9ZNec4yedl:AYJtYQJtcQjewX5=Ld4?L5*pjwm!A:IlpP&BwkNpLTCnmFcEIHYC
9bTnKF 6nT?MGAieyAaFYjpP5c<IbRa#PY>#B8GJS\&<LN#!w4^mbY6b8khaPn1EmnhI<RlK!4GF?w5GqQ:&QeL
N\JDy% :Q4#P8!JD*aP5C9\:A9a@=#8%&9EZPX<a5^#Dq&E:LGE5Bh?@lTuc9?YWN9tR4\+HB=elT<dmYeRbBQC
d@NE!h ^91Lcc^DHFWBW\JM@p*I@+!#\5KC\HMBeHkV%hk?pY6daiI+DF&ldd>CQ>$M>>4k=lGe:iRE#jRk4L*J
D%Jj6M 5P<M1i$\%cqh5P<TR>5$qeek6ZWkKeAiAq#A%^Ne:ElpDj^MZ/AnpNWlRJWWKA<W\6mBamSNX%@GkkE$
e$WIpH qGcw:JZM&CuILTwq!K8eGEw*NMLa$<5#jEBCQFBaTNBdFZ^dnwW@uh9%%$:5dlB&uBE:Dhk^jHTM:eEh
+*&^*n mQhn=a8=EdPaG%:Luj^P\t@RDpTDP!:<qjN^adK<*mt@G?<ueSbc99SFmnnqy+\QD&>=p1/H$X/yk+9D
C68eeR ?Jl/em9XhDdM%MQP!+^qh^p9dcPc*klZ65PFFpm\lRRHcFwJYSpkVYH\I=PC*MAutPRXDAF&JIwB?DqC
nW5<5Z kD9+Y+CuJ@kbpP#qthXXBTY$yTX>AypKB%A9J%J#YwljTWBARN>Kt/pV^WWj&>APMiN$Zt+iK!Z&mQ\S
!<^16Q <p&5>M?4&Q%a:BRjhyTAjB!\CeBGmYcnHn<@kyZkb$/^JAJ%\BLC*56=PlCh5QpTtSHQPC:&\?aEah$q
tSPSq6 lDWJD!6<SJ??w999k1lPVMFb\bXWtq&:+Z+p*EYDqCm+*AZhq&l&ZIZ:*Zn@>nRjCt$lTAewS8D1R8*t
hPP*Qi V%JGpQ$l^A?5k<A=EAJe\ePdYn8R#6Yh&5eZ:D*wPb$!8R\5?hXW8XZ$YJJ1tjP:iVeiFFQ^FiRZ$FIY
=/bG/b a&*1bY49a^\eFR>4+8jl%^SnmpmKmV1K4Z:%=hNuGXP9NJ<<weFRWJ\H:BSkl\DdD@lJ1Fc<Tjl%lP:P
IqS%Re ZhI*w%R+/1YeHba+hn+NVN:1Iq+@mbkdL1q*<&XP@8PR@#Fu/YYuC!?F\<=i*u9B^M!GH%^hAcQH+Yau
y$bZ=# hF/HP+*Rnq!1kkhC1DqwBhKaB%L:B\LbBdGqMTTDNJucnk#/bCyQMyDNkG\KpS4AT%:QE6QQuD#AuNHQ
tmmd>1 uN*DZ4^F!1YEn+6DTpyaIK?M1cGQ1cXZa5%?AZa?eVG?MIy##Ha5<5>Z*%$6\A+:@nENhSn6*A^k6\B:
nXBZE! Ayh@a9@mCiD#<:5AG+JdV&lPjk%j*YH<9bkc=?!%&Gt<h9LdiN?R+jJKy$MAXH!ZQk9u%=dY\RNp^wWa
4&VPHt mSQ#H6MJeKeP$AD<cl5e1AYKE6FW1EKkEhn+Wjp+kDPbkY\Nkddk=\Biu8AaTFIk$@9:A>pC!QwR4kLe
akh@=J qF1Y/F/YlB:t%B/GnE/JyEEBRXVw8FTDR^m4B^n4i\THLklL/RwL<*tbC$j9@C:$=c9y1?8^dj=aK?uC
\JVNjp %*Rh9*HjuIZJ=@D<BYLPu+WJZ91V/8hLMHea>9*PiQMPHZ+KL&&^ujNbuJ1\?!Dp?SG$>9I$%upQ+jhJ
$9/=%M <y>#Z6J++L$$ETDVN9np&+\hNPuACSe+G\V?1D&YB:ICLkR<WBewY8D6n98YdIAdtGID+V=kVAd4AFKk
:9@e4b HdY*AWuZ#JR^aykq1weqHuH8F15<JTTp^M<41GFnV4hlqKt!l:N^ZFVJRwCQ^%KDq*L8t=Aj5L%jdMZG
69LKbT I:AcG1\FN?$ZD^kL=tl#Me/W==\>GKu:h=qtnG4\L=4j9wKcF+#aDtL/KGcS5<6mIB8@H:ISMjS+i*#*
l*jY!l /aTStWWAE@6ZuPedn>iuRwl#KDNtMK!FSuARIkF^epR@LE&$^#IL6HF9c^QT^XF:8aAclW4Sq$uBVq^E
9uYbue TalH^+pq1JMq4B6^bw:4+mteEDMK=lQp%%WWbCu8bT:4bh\\IBqeJmkkyCjBRNq:#Q>*dMPLG>myiK^Q
@T%dI8 FD>FkpJ+M*##GF/?AQ>bm&GM68Eu96?iAZadn5^C#ZPJ:<@TaB8JBm?c/Dh<F8QC+9$&Nu=Za/#:!aSS
G\LMe+ ebVACe@4**BYZL!!St@B%jiM+a\??ApRR#pSCJJaHH1<Sm&H><u#MWLY^FFVHMDBp<4Du=dH8bLF4b$q
b^\=ja aJAq1B9uHNuDpd%DKtA6Q\?Z4KRkd$wqW%E@e*tjYQa\L!8#uDBd&J1C<F<\L?#luSjbn=:J#+$A%w*Q
k%HXRQ 9e@6kW$9cTw^KT?M/c9u6F@@TqVD$*DkD/a9jkd5BQ^^AK/eJ@%STIQ:&Yi^q:N+D&Thh$>V+QR?BdL!
BQ!n9b M5n@p4Qp58HlnA:e$wbaaYI^/4^EmcH$QG1bSepVuIuKmE5Z@C^J^8+M\5+X4J:hLH:hLPS8q6B8=5ki
5uZ?Y? !jRSjkF8WTF8Yj<w=qY>VIW>AmZnkpITpkJeu9q^Ae?^%Ntj9@!!@MIQhp$9?c:hl%ewELdBm*%\:mi+
wBM8\n QA5VGJ#@uS8:DNl89IZ?@l!e@^pGbnp/=tkiV<PVcj1=TKwF#8>Lb1**VFNw9d@&LbZ<Rqd<X<=Tj!?A
:/SliI 8c<L&=ZkwR=e%wa5mWZW\8>CLd>k/YA%CFWDh&%/C*$iYTM6hyeYX1>8Fu?Ce*mQSPX^RRq=QlFlSZML
$pT8KQ ly^l=y\i48K6Iw1G9IKC4m=/@6@>/aql>:@c<H\tjP+$QQ1ieY!PC8?b$bDpAM#hkydu\8e\tJtFA#?J
E#*$R? +J*GCLH+<#C<&kJH:uGnP9lLG@%5BnZiN5@:?R*C=8?hCMLd8W?^5jmdlQ<L=*8K<EkF4mqC6RS+eEP^
PTn<4@ PL/WeeaEemWlWGBlmVXb@C%Lw=1wAmbc/1KG$1^Y/8!t18!&Pc#8jjPetRM/?NLHSVRe?RX+%XVF&FK:
V1DHCl tVP:PCy*TumqC@D#GW5^^n:/ISVD>9:YhiNF>MS#8l/MaiMe?\lGty9G<?H=NM#<D4hikm@G%IC^dQ1V
Cu5duN +>Xia4/8nlkQ=lP#w+uEXLQ@p8HJG**!?!D4Em:>eB4L9y9\9?b<T\4&TMBcIRliZI+X^AeJkuBJD!?I
ncqit* na4kL:A+HdR<yTpK+K\t!Y#i^&bi#c/Z#G4h#P4e#i4i#iLh#SLR#SG#R>K4YECWZ%yPtCP8mVt6q#X*
/9uQ&# p%lRKV<Zq/1mWQmbKRT=/8i4&Ltpa<?E9@tBlM*A!C#6F:PAQRZ5Ee\<l*KM<\AGpSnZZ!>lBlZBjjnK
PWK\MG q9tFBQm+i*+\PD@X@E:P^8@u4Q\^J$6>CQKHPV<Wk68T?DYuFd!\pl8!8TCiA&I=IJkNjNtYLQ@tZWAh
bpdwXm J\Tu>iGJPjT4k9><hIk6+T\H@w15QGadYc%/YK&:YY*:YB&/YX&/YV&/YZ!:tj&/JBKH?EW+8BVbJaMT
DmNN>a YSJ:GbK/^Xj&CI1JT*A#pL91I#E5@<?H&GR16ppDZ<G!FS>jH*\luIpJHJmnPjtT:j\e6GCMpbl+=J#a
pcd!#X 8XuG*^?T5IQ\el@M>RN?&nThcP4CmPqRn$ZPDpSR9G:l*luL1CC1jK^#R=BF@\*u?$J\SSC/8TCAFd?k
pdXW5: LIl6!VXqd%>b68V<KYw=^nVkC\5+bkVl+lC$!JpmA!H!IGPWmlP&RbC:Yi&:YS&:YX&:<TLw*T&&?kC@
<\tyXF 9JmkqICC5!Xn\mB#R4jMlu&mMtyCkn#PG<5R=LTZ#@//5ALddwyXE:NDY@Fl>cM91HytIR9nmMSaHVCc
nkTl?I 9qiM&A5wicu8k:G$ahVZ@wA@u5KF:?G*ReLTTa9V#y=LPL@8N@Vjd?aQ%#/Sn^Bi+M#%Dl99+IEIFmA#
E^9FZ/ 9+Z*ub!=qy\&Jiykw\I<5IEdNlA9Te!@TaG=C1ipwT?#:TC4ZVe8B\I!ES4MHy%Cij8FhW$+bQua4BZb
kYWuD> w%8aw:5pN8^ZMLZt=?P%>DTIiV+dMjjmm?6=&HFj4I$Kn>\&jLHR:BViH4@+Gu=@Bhpa^?E=&5QQlJ@j
A4<kwi yb%:VD$=T>1AWYN#$IZS*9/NNH8E>P%FK9^Mh\!B&wMay:k8=@\?!GwjlC#&1eL*wF98=Ha8<GRmIQ>d
\aLuN8 #4:<5F+Fd69BSS6GDW%DIY%bdlNLF458*MPI5BMlqBl88Jqb+@aIi&RI!9D#c\8^S*ikeVhj*p=he1mI
=>>+^E GJ?B6X4R<:>Cb?i8jN?M*Wl?@IAB&$JE:tb+hkX&a*k5+@wG:5*B1X>b<bt/A@D5T>IR^uV<Biu*H$m%
4k#eq= 4\T1MhLIHMQqy#VjH!W5HdW+Hy#udL9a&4$#NNVja?d=Manw9?S<Z^k/8jB6E5uMH?QM>THP1K<LEwXp
bmhCm& CWm!>&F%HPA&DtY#4YF%:Fu\5DMSF&/+thu<?#XY6DFJMHGw<QKE4GTJ:GYK:NbeX!eyLcCkLB#==cMI
EL+qaN DP6@ei!*u&Q@tPT/?JV?&J<5iA8*A*/ekj&I<^<LSjDpL/Ru>$u+CeHNeQ5y%i&jTMh@I?HaJ?H:*/H8
wTkwCj JjN9^/u\!a&M^Y4w5#kphQ\kb/Z@c8QZ?w$d:kw5eN:Fm??LTQ=p#wHE=kD?^G+M@4^LPBQNlyYTBy*4
C4*WI> CE:Xya@XyRe*5M9jlJGVtV$/lFj5W>RRX6Bp=jQ^bIpaaI*y$?#b4/VBJT*DHZ:^WBmGhV\h^Z=Ij9yE
&X:#4j dieL?t&9cCyuYdBLMHeY:9+CuSkcpyCPQSii9e&IHTbYnLjnm#!@*p@##RH/u\@k#LFS8QWq#e^9NBY@
jP=k6B C#$?S5^Cy?F4/9:5I%c=PC=!%u6Z?XQ/b^*!l#ZHA#MCC^6u^dI8l@^?#mHeEM5DYj^RLpSIBCwpIIVk
-AySmX 000d16991c700110334 Page 126 of binaries2.zip
qGeGm6 VBGqwwmSjMYaPF&cYN&:eKV#<mCEk5ILF:N:y?mG$%K^bWKl8YE6/S\SjW^lZiL4h$t:1T1wej961Zii
4nqFR# \&Lu:9$+6^1:aaqQJ6?H6bn+%/mL?\Kij\*nGIT?pI*E/EQtcHc>wJ+:k5<n+dNJG+kVkyYEcwkp:+PZ
HDkF96 ^/H#Fh6jJ@GL%%=6lC<j\@pj+hhS?GpNaYt#V^:/Kd$=t9+H+5E4=q$lGPWBZ/bQ+$^ewd>cAF<R9mBl
pqBtWa jKmTKp!mmNL=!6PSFbp5T+yb!KPwpYD%ZkDL/6&D^PLV\?KLn6$<K*c1:QyVLHcFum+@Z*ANT$RQ:/wh
u*!<al G8q8KucMN88hdPa\<6#ZI%n<pSit&Dt+<^*M@kCnQ@Iua$^HMXIHSm4D1I@M<h@:BZ::Dj4ttF:eI**%
Y9!XZp kKBcRT\jYp$eK@H%Yqk*#J/EG:@A6Z9Ep1VL5P%Q/y@G+i=F?K8JPC*+V5+1:+I5@tq/H&e?iCwMMT^9
BGPZkp RZ+jb?LK9lkiKBYEEpF<Y=5%a6V4yGq4=GlDleA6$5eZ\?!9#=u8@E+^bbDi4+@F4?h9?iNHnylllap@
LH5/tZ Sh$mJCVaFV!n?EP4Jj\#VRyD6w=AY1hY+HQM@Njb<!>#/#GNy:N5n*>tKMQwj<dkFRbSGF5Y^lmM1c:E
PTPmyj BAhRQq?Fb@jw&*/V8QYMc8aG>a@n^Lk9m%k9XEA<Zk59D<GlZ@tP@MG?/VuL+d>wV9=Kj?%4$55!iLWT
#bMVwM jq>HyMjduFZjM9P<p<Z@k^Budukt86nIjbV#a1eS!AtFk1S+jqyjQnaLQk+>jm+%EYF?/!m#/S?>j=%%
XSK1*\ QQGL^Su5Y1pCJVcNIcCZJcluRiRiq5A8!h/:W9qDR8Ie*maMaeaRykil8lC5BZHBR1ujQ\:A5K+jXl=+
:6#!9$ IhTDmWbk$15\+^mM1Rbn?9N*$4FjcdA9+i+e/&1Mj8+:tN8HD@y/98L@<R4NdCWXQ8&b6ul1P*XlZh\Q
MQZ*/1 i/ATI@%^n81Q+@DdBQZQQVS@%bNiJlN%$I&a=VD:lPqqBeKV@=u#W!HIaquicd!HM+WLRnu\#V$M&YmW
FhtTZE &XlpPNnFSGTENK\=:CJbI81+<:e/#<+/*Q:D:Mb#<?5VF:a\Qe\t&V4c5+V$5kV*+KJ$C>ieq65$#T$4
Nt!EQl dYdKTDEk+hQSPlCwDZu/aQ4FR:XVQ#jiDj:lG<Gd9+9P@TLRnNt*#\p<@^F1WV?MYw9D^EabGP#CTNe^
jZSCZX 1mi*<ML*1l6?QWZ#1wpK^^8@1FTChmQ<jA5cZ#HQ#FBl4jB>H4=TDy?C>mWkw::P<1&=I@X*eSd@#?LB
6uBuVT hb4amnq$8cWDq*MPaWG6BaPynLt$Xn!#cVGL*ZyY#!dYwDctlE%MGcQMPaQ$mS%Gq:+$^:DRuj6:i:!Q
K=CicF :YecPp&cLwd#miB8K5IS$5RW&58^ipL8&q>!JnI8B6VB^9nyKu#tZ\6TLYq51>h^S&XLi+l+lQB@%eYE
F9Wn\m VRln#:^??yc:>!ZHm#Ppk:@S*d%Hn+*l/=Q@Pp/N*TF%@5F><ki/8W=mYJ%D>G\^m$9nIljZ^YZA5?$\
X4>bJ* >TZDk#?y4^\k*e&E=@M66A?S#A/Ly:A@MF?pVQVJu+u#eT+waweKhkla\ntdFRIZIRi!$=mKGnGd>LNc
Y14CLa >PCnb6T6ijc\BQT\lQc\^Qa\yji!=ZRL%8/5Q::>V4:KVA+$V*E&Z&DjibJ>bmM<ZAi>iSBmCmKJ/@Zd
MG\ZNK K\MyLMF?^DqBw\ZP9tw$Ely!QC1m@MdcWlEYB6E/<SZB&Q*+&e9TX*>pP9kH:X@DSJNYV:RR#eVE@n/a
&@YwWB iML&?A9Tm%=1*KIbBNZ=ajY<KMSTnSkmQV4l/A*Tqk6Wh@4k=pF1LJYE^:L>a4Nl>MH=IyuQAZtS<^F&
8Fei8> uHMJP/T#LcRHlSuHu55NFFb\=JZtX/6p$i>qNi=tNehuJ%me8/m<lmBwTCK+PTT11MZL<yKL?LeiHJkN
pl=yAZ Q6S/Mk!dV>Li*RkXh?n&u+Cb#hB*ubTSTPZqSY5SAP/B?CIb5k&EI6S/?PqZ+cAmS1h$D5>I:w^X&8Wy
FMenke !Vj*@jt$CD5h>QNbtQ/c<il*6D>9Yy#dLMBLG>cFu^@b<\he8wi*c9m!4kVC\<HEc69ZwlD\T?DeEi48
ANm?15 !+\:V#Eh8Rlu9mM>P<j\My$K>:QJe5=c:?1YQ+8bJSe+*?jCISeV1MMZ$!PDFWy=\ELalq=>M=6GF=68
<VB9SW F/6?F:NyF:9VJq**4pa4#>MPh4?+/j>mI+V@\A/LewNZIjm!&=qE8DIAFZhyN6?p144L5Q5p6dpZ9y^A
\/F:+6 KanbmE#n:\8GFG1KKWuSM+a^hykqyy<9h<n6!bQeu^?@9B1CVaSk*Ty#dZD6Fm*iut$kenYZWCHM6eD8
IBM4ni H%nQj5j/?H9T*i@yd^/utp5kJycDFlh<#m<*I8ND:KjbeK$YHt!A/Y!+YR/*S8H1LhJ5DDH8Zuwi<P*E
D=1H%E WQyMVpdmZiD<FSii#<YL1PhHlbFM+CXp!T:j!cde^cdY^cLe^8P*VTj&mW@Tw$eGAw<<DS/cG#+K<:!q
5t*dRJ T+i9MHuN&S%j\*ddH:>w=W+SuN\Pt/ebm?+\S#=m%M&nMmBVBjtBB+YpRcaQhABLP!*<BHhpL&6$Z<AZ
M5$$NM 9<d><i!HjY:a<SC5!^BdL#FdRw#kewlF?QQKIQ=cA^ej$h??V98!m*SltGG&l=nAD!AkL=WQQHIkqn%+
BE/M+! Em6M9QCLPJ/Y\Q=u#LhP\+>J6M6PwKm>/@TV?PeMDcVj8cGedaE#Wma^MHSlF&YRHtTV:&KXc^i!&&LT
aIm9Bt ?IXLBpbJiVB6!Q@aZj?SljFDV?5HZ1dVG9DpNYhH\pl??P=\6<u+mw=:K?F&C##cC+iu\ZIZuRYbFP\G
wRP6A9 *l=kEWVn/MHLHN*QE6ZHqVdm?h%9kSm&i><KdLe=%1TFNc6nc/WY%6JHL:uAISu9JX/5lbqDXAi@b@6m
Z8e46D nBq@RT\5LH$l&PK>lC88B=dEpulL+5I8G?KmJG@a&$q:ew4:?Y1me#bhatdq6<\5>VpIm?D6*G9PTQ%5
Vk%D=5 WLnwb=VMbGb1RjE%CDKdRlij+=nyJGcd?5Ky<LhdJ8JjtjM>>DN:cG9<MMnq94ZE6DHeNwGZhkSpJ?L*
DEHqJW >ePn<55w8JMC$@q\6\48>MKGT?^J^=n<A+D5CBS4CHaGn8k1q8liSp1u>eQ9I#A5<MX99/AKNcmJ%cym
QkSET% ?dJa9mmY#aWZ59Aq1<HuI#ePH+#eQARQ>lLJVF+$5Bj^M^AV!$@Mq%\^Pu@S1DqB&\P?&kX@blM#hjM4
+Fc+he \*ZjM!pu>np+C!/DnHTHC*IJ!ElqKKX=FSkXB>kWP@tNN85iiCH4><K5=e@C!J+9#Gkjitk<DDB?cK@*
^hV@yh KDbk^wbut4nR>b:NpuZcunnui&9w&@e#:ytCQRiw:9ZBw<P\=mchCyup/RFBb6ST=A#t&AGYtF:S#ihD
6inMbE utQiZ@<R>iYlH/Jl4q+BY!iD=alkK:t^XcJaMNZjLeS4liPwH?/A=&8Jine@?ic+<J/ce+BHFuDZnLn$
kdq<<S aKpI+Pn=d^9\CwIu5!+^Z@VPE/#Tu\M!@=8R=%ZD5eC=kk*pXXc#1Qi!c*adH@=BN?/qjMk9e88\LVp!
jY!Z9% n?JybtL$H$dcQ1FRu1!IuHakLY^YaAe@8C=!J9!M*8BQ/&F/GAb8\hWyPHtSN9WSn?bK^pB*$Qi!a+:9
*wWNM9 b+u6bW*w6::$%HQ$989FT%:Zh*&QP66eh1\MRidCXwlkK!T^VDG<8kY@%W9M@>YQTIuZK+5RbB6+wLi+
e$!&@% TeJTcSFLy\^^QhbhhQL<pu9X@<Hwd*u=i$NuijHwRJ!#iVmbnZybNV4pM5:wh#@ZN@>b6j+uc=@?iBPw
AL%4ZK *5b/6<*9eYZWp<VRB#WS%!w+d1^a8Ln:kj*mt*iiR\1<LMR9CB1+VX5%#X\!Vd*8Mint$cpFWLEtDLDE
Q9#?>& >!J^JA?/n>%\d#:1$4@biqhdj+a/qp1N=ZFnc<S\!C8q5bX!YBVnAqY96!1h%=L/T!!hjcn*41$Tq88J
a??^w: @1KVhj=uwTH^bm\9p^DWeiISHT<p#YLi\/#bdu41h:*IZ*Z>u&p%jB8w+:bcBd!h&Id/jJ@Xl>:J<:<^
>I?lPM /D>^S8BKLZ:q=4Rd*HcF*\IZuVa@S8mEZZhI^\:A^Rtc/ttY4ki$tXuk+R?MTWM5md$5Cd$emj*P#Z6e
Gi%HZM %uR+ybZbqcj+y:4?pMcCbhJnqbJauk!YLaQqK&DJIk8J6L!ZYFlX/:laF!^\kHe@DFpZZ>9#SGWS59b:
A1!kMI #yYI@c<Ta$GC<K5I4GWHh\WdNBkSm#%khtJY#?ad*aL9Dei?T=GY19CmTZbt>W<!1!y\9Vtli@!8^eB>
Hh<8\Y 6j6qeC5BbwL^^8u*+MW%<:H\R\S<u\*jdGG@X+>9%9FkEKc*A>pNR6%ALVTRJZGAJdGQLd:ZI49KITZV
%Zi8L6 *nQa#5@Vbt*c&k&??IuyRmt5XB=d1aVqcYAy1k6uVyjKeRqpS#^59>D@IGG69:jJ81MEL:Vju<!Ku:@H
ARWiH/ iFQC?M88<IPBbmC4R+>G*:SB&<<YqD<5H&EG\#j>ijuZ!%K6X/e9<PL^LDhKK>cyjY#a><#+$GEaPRnu
4dYQq9 6<PhEcINm@q:d8FYHM!p\ZRlVFjDhC6M>RDFDem8+PjE!BNZ!=Len%BL^FR:?dnbl+e+lia+XyYbDhd>
d!+=Dw mN1MJAc5ZAuL%<BK>LBew&Xt>q&Ch>:Jb9DwA*Gl>?b?NZiXCe:1:+E5?><kC*?R<L!+F5+Z^PkH544$
D?kSyn /l@/#uwjbyPCtj&B/Saj!^LtK^Cq&mBHX&^GqXP6FFGm6!JF5:%V/@K*HP*j5@d>^ayQ<8R5GXBp\PMp
^/iILH apPDdB#%8RtwcGWti\HbHWKeIhCJlmPyuTY=n#FlRC8t&Dt6^Ct#\uqq6X%Q&=+1c!!BDm6Z^54%5SJV
\a%#$D 4N\BI#Q@#hqyGie=S*n\AS64LLuPhAuu*#Zj9!yD<4@FM9<uePbi+J^nFMnt&t6$=qjLQ5\1DVQ?/wYT
*jc8Ip n66KRhwTahkkR%etSXhl^quw444PXYt69?K/ELGjnqFN9TS>iRNiNSC#EC8a5D^NLB%i=5N$Fp!9k8q!
tW*9CD iLkJQFIlMBAw@tAVSHIPyFIK%&hPGYSJ/8NK:HdMY8>eXi?T$iI<NJm>w^1LyeWKJdAme/#AGq99lqGa
?^8RMG q^Y?JbD9j<DJm8@hk8tt$98Zd+q>@kdnjb!dhY%a*j5MJ9<\c*&8:@6Ra?N=GVcYdEGcMmGwpCT6qca4
8mP//q W&Nea!&@%qJ^ncjeGpi=>d:\hDj5\&l?QR%a9Tk?cm=X^IjMqZB*J#^enX<1P=\Ndw=kGEluRCbypYpX
bmHQK: k&m%kwAl8aEq6b<=1e<w6>Y%86P%ew94!PHRe\i^cGy5BT>YcwjqP&I%9qk\/<IK@PYJ<eV<QeXP>aNd
/>@6Mk ZTuBdiu*uGd>L&NA5W?DQM?biNeeWXFmei@VQQ^eP@&1n8$=niLnp6\eSYJMc+V\e%YXMuVqep^44GZZ
=9aT8q Y5185bc8CJLMmSNIVwH!W#S#Z$ylY+&^AY&5YkqBj6pLQ>/EpW9M=#hA1CXR*MGLDFJpik$!8JBJqAA\
I\4\NW m6BtTl6pV8+V#?4#4Bq*&*ZG5??Y:+M9Z<ZTaSpe&Hy*4NAD1@dDjKq\M:59k@#F@Day@^R!5Y@ldcu*
bdjj4K eJd<D=C=Qyp#D?F<ebmY+&h&/hjw@Ftq/IKt:\tNuFNTMuJ^wy#j1eMGEXkuTX1uJd1GkL#GRTI9V!!k
:4Y68y TtV%cwdR6ZVdY>nuD1lnt=Y\DytZuR^QjwAL9$LhjibkV!Bdk+<Z/JJBlW#nV\b9Q^!:5#<hc@JGq4R?
$Y$tZD y1Si==ayn:MQ*Z8iYj&EuXq6?GMI\!@X9uMXjqm^$<KK8CYeH:&^Zh=4jZVHQGL#=M@Qtj8jRF:pQC6P
-Ac^<i 00016a7968400110334 Page 127 of binaries2.zip
Du\cNq +uhw$%#>w&4SKdt\A>wyl?X6jRVaPL=Sl:?$wEae1yTa%llJ4*WYK$nu>w*X!CkT1I=p#CqnK5?nc<%l
VF1eQR iuYY>?e4k6lth8\w*LpCZ6ZWwX:+lAdFE%\y4Lbp/yAkwLnmX<YTHWElJwkye+k=yhi$+:dD&V?hNtMY
p@mEC\ j&CVBadjBnHjZ$h?YE4=M5Q51TQ</4HaZVnDE#T5Nu$Zb?%Q&B>9ebj:d?WI%E4Ll+ET@/4&Cj^D!I8e
8nG=W1 $d6knbc:5Q<h6b^#kmqnetFdXLI/bQ$!X81b#8ukE?QdXcFTV#Dh$WW96$9hSu#FY6:1AL1%+ZVS?jTS
BYQZtE Fa^^G?l&jEQ*%*ZYjj6Fm9Ma:hdTY/TT:ANBK$*FM5qLMIlYq$#q:$hF6kG!JVm/!6LqnDGu>?y9iiJ<
&@y\k? FuPh\G\\:H!8>nilQI?1\y@pS$@:eKHB=q$:@BaG6$#k96tT*h8$q!iG+5ekK@/>4?#*4#t@q5L@4JF:
a*VV#M H&h^iCDN\&/=W=h<RT=%RI#eySdVwX#WdPCi9XPKlPuB>:c<b4FHLDJ@qZPnYNn!qKS#N%DwGy*wpyMb
nhF*lQ X8VRybe^?ZeJF8?SeP/V1PmSL84q$T6u%EnXW/nM+A8YMktp5TKDWRB>mAX?+bYjPV*>1p%M&Z%/l^?:
$l#8WZ Z5LeV&PiL@:/LyVtcd#m+>4aS/95<R&>:alybPQqW*B9eNd+lMSa5w4:i@uQ\Xu!p*8M>*BG$YGntTN6
cMIF44 hEA^yp$p8EE^dKN!bKXM+4ytdaY%m61T>4<+bZ#y5YJTTyJjWq+w6=T4&yG=&b18&bb8nV*Dtlm?&85!
eB$>4N B#HSyDGN+E/^wuWMVpP?AR*BATF5<tSca\1RA!DaFW>5@QJMLiDMdtVK:hP@>Nn6J8b^Fa6?P9NhKQWZ
chj6k> ydcQC/Pt9Yn@*n4M=wPeQ%4?FJb^9mt%HLL!9#wX!E<Ri$Q@lDQTaYqFiyW^JaiNmpq4JZ%KqEQ!FWN#
^+TjHA NF%TiPTGjF&@>C5>dd1mSW1cV$JW$NiF8<KM9htM66tC46tPah8w\J%b<T?@q=#?nYjNRcd%&b\X%Z+X
FWGJCk edSBdlBCBpp!w#GbL5CDlQI=!A4ChWA+8bky4<@k&tPQS=nZ4>m1$+i?ncJ@WlM?+<?G:&n1Vt!Lb$j5
*mCM\+ XQ<B#p4@nQQ66#tL@jMik@iV>Z:PTF:T/d!m/^XC<8YDX!lRMlTCEwV$KnnFS5p8p^=4luWVptVp?GZq
bZ1AQ* BdVp?E?/ME<+5E#:$@?CluL>>D>ea<d/+iw^!=eZcjai=m6^l*XBEBSDbW<GPVK%HyuKt\Jl*tAR\Bll
$hhnWI mDkZMc*8M:*=qjhZtQQ9&Q:%Zp<L>Yam?ch>me65*RnNS+jJ9?Y5?8cP*@?X5!VSa*\t#p<p8AXFN@K4
B1HtZ@ bpqSE5Xhw+WDR:pqcqm+8&X$P&Tm%pq+tQGyCjB1Cwmymqpc!Z*y!+pF5&FlhFkwQCnXVLu@*h%ce*^^
c&jmjR SSX<8SacAmE>kiRhAM/w&WB>HSq5KiBKBkh9+MtybX#Xc*j@J=?ZYPnhb>@G$e:E5m=5%BbA?NtNPMH*
cIAjcQ B8y@^Qt6C&*8TMMjCp5+1@^D#kL@BQLHPPQyIcdC^F9EdS\6=lpm+i#L4=4H^6dLLhB1cJKp:/5ld!\5
+Z@eFy dC+9//Rpw!a9LT6LXlHeyR<D9WW^q%+Ndt9Ay=W!mi&JK9F:##WERaI*BHqCkAiapWtCbQAJk11%XE#=
+XK?pA R!#FR#:j#@p?\<ddKQenaVwMy5MZ6*u$J^:MB+nh+m/P@=T#:D58cLw95+T##D@5=Zk?M&ipVPEAPy=w
Hceh#t htN@AYM*KYM9hybihw=8FatXn5aT=n:KEw/cEpa!$8IC51KC$5IT=utZ@Gju^pdL<ZN=TeTE$kym$WWN
&u\6@6 9uH>@l#\N\N@c:\PBydSWM/\DB?VlbR6m49Pi4*EXq$<eV?HbmaBy1MJ#tH+HwQ+NwQ?^NGQmJE*Gw>Q
&we>yi +c#$:65E@E9Pa9<e<1h^S1Q?WCEKC+<dm:aD8+IFy&k&P&59K>8AuF1Kw1&B8I&m8IY!5IaMB:<pu&yu
lp&WI1 =wp99p^XZqk?Ed1+E1CTYNDTnc?M*baDG%hS6$=TuZ^I/*!ZWdEymZuq5MhQ#?%?9*=qN:/B&MWN?Iu!
uqbBEe %:wZC?hc+XaBVG+t*a+l>9T&ZZJ&>VZuD$=w9QP?AQip@^XupZ<P?SM=m<E4Scw\Qle1HuN8XTNPYR$P
?>WYX8 kT^&%u=&nq=P9ka&kTRY*kAt*nARct9*Tj@Lm^W@Y?i#5CMbk9^VKhh5F@^!lQSmD*Gh%AT?R1ulDlQ=
\:9meA Kw@XHZ:i:I$!k%NJ9>#8Qm8$:w^R+#Sy8lGte+thT\uNyMQpXql>YjDRBP&PLaB9#?6EwJ+Q/6j#hiwj
%h4MiK SQ&iY#D<49AQPW9?K#N@M8j=my#Ib<*EdeAn1<M64eWwS6HuL8Zqd1Qm&e\n%GetXZHJRB\@9&qNnI+>
yQ$**T F9&eA@98e4++B:9@a81dbd#^He^hl=?P\j$#MQ+I*HyhtNQG<^:8t^/ujdId#y+m*hlHNXND:IP*kym+
mQR%/W #wb:YZBwH*VelY86%A@n<J%LF!\>n>yw!StV>\%Q*u<uq:>LwhV@y9\6c1?<^1h!^meB1D4E=ZmEhcSq
u>XE!# 6R+1e1Aub>XJ=>Wput9VaMS+jGH=yVW^F^FELG9Jk:8ZTZ$a\+qj1Gc?kSQQ+jB#/yhjpRct/jNQTDKH
d#wM^4 nGcjnu8\D/c*\jRkwT=<c<HyWu#lB#=^uW5<4wdDy&DnSibL%VAVkP<G8hBW&!/yl449mikQ*uZ4d#?L
qJGdC% jjLKwu@FYhT%//pk^$e+m^Q4GSd:#KP!QD<w$j!hdLyLVt5cLi:h=IR96H5!n6@M=i8H>Lh?wu8=Hd@c
p*@G>8 @iK9%F9^%e9MEai=YeN4Xy%$:4uGjHe*VA@lN%ca:wdyh5B#w^/t%<HhC6KqG11b6ZC*HuajlbcdHNj/
V>b$Cu aCcJ&J9*>ddi=p6891D>n#ujqwc9bGH8W=yumZ>9bmVtnPNB%ypj=!#^%t#Ac?p5%?6>a8%^T@<&B9e8
\bHA?A \4&VXQmqIkM\?lj9q:@TX4SI!ulWN&%V:L:Ciu5Q#CAQh^D1JQ!MPDjB9Sa+ea!$:V#4@XcaHwCuw:D8
t5=FH9 L8PyHR\#!R9%<W+$5at$I&Fyujiu>CjeSR/N\b?LjeJ<Ei?@F$9FBed5uR&G>9?i5?bd1PeZ!h5V/>#<
jhDR/X <V9y#KaT%+^W\9/:DKa=X1uJ9n?QMh$:S4w\RVZVnqQF%Wb\:mjTa\CtDqIjuwLt&%SHL%K*ZGiiQAQd
eFJ+tQ d=QPdKPcKaY:idBuL<Q+aVk%C4eym#9Xc:<d>V$X8K@$CVh?EwRH\9BC:Q&@Q8>@Et9%VidTE=!JA#ip
/@\qyJ SF/j<9/9uA$YLY%HZJ:kS#Ri5jB:PY%Zu$VhE*H5A1BSPVaI?I:w=VC>abF#F:=?CWFGTdL^FtQPdWZ*
\CLD*a t/LSh%qHy/H<Np@HNPuiGD!wlR9dTFW*8a=8l!9heGYA/p++$ZkaLEtQ^cB?4ALDpqA6kD6&=tPey+Zk
dECX<& 6lA<FQ/5ded4*Nl$t*u+EtQNBE>&*!\Z/d$V*j?I5@bmRdRpk61hcQPCmYHLBnn?G?eQM<V6TP4k=:Z+
HRnbu4 DXttT+m>h69l#mam1Ljl&=N?eRuY*8XPuYHij^Q8HaJdS\G%jL58WS?=DKM*TQt*&C=%EeMbH=l^ZF^B
8XhJiD 6*R8Ylq8K$G:GH+bcTAu^LHDDeu*w=bchn6tSQ5uWZm%%N6<@>ZQ#Aj8ME@ebl\<\:l^c&lp?6\HAp4l
=McXmp Qb!Xq=VC?bXW85Vq@@PwuRn=Eck#+NEtY8\mnQ:CPdeX9/B!4lLjS*w/D/dZ\QWVWHcN/eyStJtAT=jk
GX5VZ$ +m%I9<NdPE&/jR&t6<C>Edm!uhS^t@*pihl<n9biQY\?\LC\hb:L+6&Iqk\Qu&4n%>\F94:VND6?^>lD
4h#:A^ wuD@uVeFjt9Hl49Elc8QlBe9#PV>4&Ly9<*Thwhq@WZG*P&M=X9HLZV@MYiF=e9XZ565eZeLb\K%L*/u
ETuJWu 8T<&$%^/TQj>GhwjhlLZ:^VAh!6lPlX8XMP/m+!H#5L/GeaV%?p1b/k!yluedp5Z*8aw9e&Ad<DdANN%
6*e#/N iL\<YA8ul9DqC9hVmXG=&!JuT+K#Ph#Zke6cpClIZA4>?ky$+nc?Z1#R!w@j!@=N#kL9*aVpT^H+Vik#
=$&WTK eGbL9epYi+56@AbL$AuGkE$CWZ*j!HH<M</c!@G?q5qmTn59Lt:^^We8e%uEnMeKwnJt+:S9^8Adwh<6
p6KK^/ l58>yP%Z1D59etdQ$DSMM%lNe??bJq&/AnQnMN%M^Qn49l1%HDGLN:q\?Z51d<aWnt6DqMDmZWKYe!aV
EwE$8K h%jQ=eIuSbimunERjm>1abntkD8e@=p#?Rbd/E&&/F85MSibA@e\P&?!5m:@b=!%*5Nbu>nhA1G&YW\Q
uK^&D/ \6WaBb/H\+9=Y#!p+lN/Q/PYPAJHjYe%uBml9h%EhY5LjHpcl1cy9P/IVX!lt6+P>@9l\Wam!XeSc=\T
<+hYqt <D55+H:&YY!p:iCSNi#YkkAEYYDJFk19:&d+?6w^NpnllJQm?Q#G6C#%6C4#jV8XcWt/h*MYILb$+MR9
Q++&*4 +jtG?#@$G/695ybha%q@u1Z1A9Pc$$^y8^qD^ly$uD+Db=%F#6bLPD9mRj$HGiy$aJM%jp?>*!JlLl98
8lh?>$ S?A:\iIA5&C/DG+*RjM%t1abeL4CZ*<QLq/Ba?hJP\>S+$QFRtKRtEu+PbRa5@nk\<Q:>qC4B9/9>*aV
thBRCP IP/p5BR%=@LLIhqlu\VNnD#NQVQJ?#a1M?w<:?dM8<B=Z6e++TWQ#Q&LPqk@lc68p4qtp4q/p4q1E6Ht
q>1Yi: !hp#K$H/4:p^#*pi6jMT%J/+1?>=RwWG4NiGGpQw6Ia?P:kTAw>TaTaDh?#hNcn\pX1t1Th8WX&hkV%*
9tcAq% 1d*9C4ZeJt$?C@eR/mKaKaAbFNG^?C$X:pZmAdJYHRJFmC$ySJb5<9@c%e56nX@a!$$Z#E$*LM9?&F:6
n58<\* 91ZKnMb::qQA?cd8e5I>4u@F8bcA9JGA9GGTij$p<:yJ<+!8h\!>qh@XdPm>l:MB$hi>#htXTA>@&GeN
>Cc1Z9 /:Yk&kCmFeBZDu#pINeaP6^lMkWiFMCnP8w4+/V:+:DuG1!iyqw^Vdj9L5*J+#DVAVNXeH$LVB&HVTjk
?uMW8Q eRFM>EC$A@myEb8mT^H:8apDSR\ww5RPd@P8=q*Ctb&c\p$j#p%4#5NtG=H>4cuMjXPXGV&^yc*hkpV\
\Y:8X< eH+dNhINV9mSG@j&y*K8uYK8tYK8utK8tq1A9HcT8YKTyiJMq+QHt:NJ@+m#!Z9<:Ll\9ePj9qC9A!Z1
\e\dZC +C>NdEBK:K<dyA%?/lBuVhXdJHJ=SQ#PPQj>+@T::6ApV>Q%*KG@i^#8n5Qpadm:A*y9pI=hlj&6wP%L
n&i\&* M9hkCDak6mJe*C9Q#Rw<DWuw!\caLGaIaYpKB\&Fm\/bYaPdZXSFY/@^$BX4@j6GK9iM=N=SCnp@I8V6
TG=/HK L#:N&<\dy*Al#l8ttC8upJNb%mDIp!^qp*!FS*?TajpRb<Z*l:M8kZey=>h!Y4!8^A<i8WP!QASJLY\l
GMIAj? TNaEJ%81EHQ1aE??kAC?mBC?#HVlktGJ$i9m&Z?IGD$X1=8G=D9$5VN\>#ceuwH+EVALBbNA1lBLjL8D
4@dk*M aEXmI%MpbRl!AKeAjMtVk!P?NV&PtyhE+caJ=1H%=/KZ=iZlaiM\ZFN9ZH6ky+j:jX&X?%cc$*^9hSye
pet+1M u+V/KSj<@nFn++VuIc>HpKha%p:lpM5uYWwuYawtQcJ1ZpqR9bi#<98V&YAS<n^uq*h^>wXZQqCyTh^I
F1k<K# SR:<dQFqM\/?+J#E+:yCICSTMDmMQ#mC##FhRCXNSLJat4JN*Q8iWhPZ:KFjCa#M$DXZWiq+$kS=kXER
-AKHj+ 000edee936700110334 Page 128 of binaries2.zip
^:*Kd\ nZMItHp^PHumd\h<C%MNCLaDX\<15my+GJDe#cmC=EpWQ9wRQqy:ZtbiZkEBHq=Ji&94:j9MKue*B<di
/A@jiw %%c=d/\?Le/\nDQ@^!G@Ft4<bnk@XB>^9A6PJmC9tYIyt<IlF?PeYRwu#&p49=i#?u5+G!/B@E:P@kS1
PC=Clh Q*nqB*ihF9jGXAb*i=Ki6/B@pyD4TpG@XaLB5aLBMaKl!j^PPj#YPZ\i&V#pVN:IhLG!aVGDcwtRCL+k
Ew9bn& N?bke:AQJkX=k5j<h9RP^J$5DCDEF<#<F8>pIW1mmNGFCNK1<*L!<\pI<QL!GimKHJt\*44L1t^Zdunl
p4uM=Z jT&X?:y1M#J5:?#wQq**PPH:>@S?LJW+bJb%PGjtmmut5mtt$mutpmtYwnN51$>\=B*u##u$8^VDP#k4
q%H8>R Lq=J?wcVDSjL*&6bL<<N6$ZPAZDHF8+=\4kqBEqDtB\w1+6^G1n\GKuI&<4Llpl+JA6F4BB$#li!#^YR
QI6^el !=F\!iEQn8aLmiB^VBY!TJh$T^eLCSYniI8RZjuJN5\We!1!I%kGAhpK@P#Bn+^Ck^SpDSS^&lBS8kBS
V<l?!C ilq?Hn+Eta?QM!&D?ikS@tMHddd65qt>QTTy>b/t!kM%qZ5cT$wlCk*8j<^=QpcR6>@86GuLy/nLy8nL
wj?Klj J6qLn9AW:hi8PS!*?Sm==&Bw%>:Wq5Ge^w+X>b*n\h:9+Q^&BhRndmXk<bd5quQ&ZnD#V?+LN+J<+AFF
GTY!lm /1Cu\C8k15K4y!Tp4<^1m1VKc/I1+!kuF!EytC&4qmQt6%IwPE\ktM^QD8eL#8KlBApH^+kF8+kF8+wG
KB99YS 8+qVjCWDI+X5aup<klt<KTT!Q$y:EpYium^L=!nM^MMuIMnL^!<n#:1^t&Z*eib>l&tQHdZi85Mtd+h:
AnESym +6A>VhWHC54*6GVjGAd?C<:#89uY?NG%a*@h$eNqP*jXdl6y*hG@+<T&G#h&Vy+iPuGw/>Tl#6MHPp=N
>^?&bl 6J@c&@yTmStVi&6/Z*j^Dlj#+&8Lh<q<iYL+LEBGqu:mSHB&kkj8pG@J^cPm!K?mIKT8KKTlKKTnJKmn
N@QGY5 LGmkLGm5#G1l\t/u#Ptm1P\9=^WyEEHlD@EZDQaZCA:pC*dnwhlLWP\qk=*Fk6%F!XGmRVum=BC^RD@l
qM&Byq IENGmnyh8BK6kSm:kJCAACeZ4++%Y>W8qy+nLJ5P5?\+#DB^^Gl5q$*lh19IHbQ/yw>pqP=4Kp\LW*$Y
VK?#h$ #n??=iiVF*he8L:#%NtSw<h/ny@wQV$%MuXl//tVR+j*h^#a$*bk9QZA4yaD&=9Pdq\^y$C%#M##E$hG
pRdLAp m#A6*mQ4^ZB&ZL^Wq6BLZ:lqR+!ZZiG+K=8KqdPJlbKJlcTmkb!\81KAG1K6JKTyJKm6LGKk#G/m\tP8
m!^b6c \tPt\t?5Ite8b&E4=8p1HP#MH?4EH?LAG?#IS:EVD4GZ>I\R6<$Y<+<VJ*8Kllw!?/w!!Iu#<Au!C@AK
bB@RIW eJqH5JbP5c+>^Ny\tKZ:MM9\aeb6S%R*::W6*t:8NV=kGjTFlQ^>hcXyMh1Qh5/jw6@icn>Pu^<>i*ud
4^5a>W /dPnS+=&H#:Wej^+:?uJpXPulw=MhP#j$dB@i<Q?5j4>t&9*d/y==1!\dJZWjL%#JVA/9Ai!%cKVZj+t
MX>ZLi QK?HDkSpa8*ejVh\C1%kCh$9+=/6bY>1cCNubC5941Mk4Itp!K/4!K?4^K&9#GiwLKm9ItmIT<BISeSR
$ep8jS Rh>e\56GMNlSAKEPh8ct8E4:lIp==wt:?dQa&VEKmA4mVlcW=:S8bA<>#Jb!pG*%Iha%l%n4D:N&HGai
46>N>R QC\^NGFd56*Ke6ec/<!ua4IQXFTt^Sh9Een#:!G@p@PJM@%uLt\/jY:p/NH8A^QNS\=%uDnSi@JE@=GJ
%=W1eQ >u%n6j5&%?#h6HHQTQYiwcyDQSX@X<D=*YX6mD8\q^AauSd*Cuk6J?L=?b$mKMT8uw5Z\4<p\+##+kJF
Em+iJV N=n^kK9?DIL^P>qmn4KFH8d#G=J\Y/ZqdGZmLK4nJCuqwMS4w5mqyTTmw+keL1TqLKTuLGmmkyn#G/kK
l1Zh<5 GClLG!uwtEm+@#?>9RhaFNj?@#?kkMD8#C!:!%c&:%AYhqq/::*D$46IEXASFSY^C%lAyAmwCNapJnH&
TX4eCK G8phc*4SqH69!njJ9duJVY/mJm1@e</CMV$*>@:@#@N/=ythHiD^NY<@e&dt#DqB9L\pbqK=yc:AWluP
kE9dP% aF5LiD\tY^4D<H8BDP<uE/+R?d$EWL&tD/@9w#j%$#9:LZy/k#iiC9E=6TCp>YPJ+u*K@l$d%5!y<H@6
pRpl5j iYD+\NnE$dHJy\eHi%/<&N=:1ZP\4&8+9/j@$6:L^=9QH&5+@>TPe$i&u#8<:eKSl6hZyE!4DGcc#clY
dJ6Qu4 jN%p@Q+:cPdEVJVd&CecFZGwF$ec@P4ddhm6MdSdIS^6+K9MH!VDHkKw!&Juuy@JpmFmaT<RkteP$BIu
*GGyQ5 YXE9!CJYP?5CHLIePKqK61?%qbih\MpPh:jnk8461PJy:ZuP>n\*i//HA<9DRiS8:ip46Xb!&DI?T!wk
BeA&I% XXYp=!DyiaZ$9pL/Z!Hni+teZ4!$D%@bl&@5y&@9J>4/@ViiCZe:Eil*>k&q<@6T%V81&S8p@=*ui#@*
B:dMbS QNA%NN\#MubweKD4!5Z&F<?%>X*1GHl^Z@@=#w9Hh=+>89Zewc*uit4Q>6ThQdD6@MF6*#tb#6\+Rne<
nH?cp% H?Rc@8%XNDdWKuSLPZ9tAtTtQ1Tkh:%L5R?dDF@=K?*?Vnle^wMT:K&a&a+BcV@\WTwY5YT4ieWkWhJH
@ct@KY =QWTcd%pdC<b&55I9E#Gu:HMYmQMDXBpKY%T4VuBhn^*Y:cuHe>B^hMAbt*:&NMeqASd\BbKGW:HGC/>
A686I8 DJe4DLe4WLZ9FVK1q<nwJa4:<PX>?Ly?jG5@*6L9XZ5&#PXE1Q&JRd9k><Y1>:VK@>:#8:>$5:1@d?>A
+q5#@@ *>/lkc/B*u$9ut&=hLIJLH9Q:4=!88*m5\%uD6ci:6q<1t9VmZ&ALch//wi*Lb=ycjmnwWKm5Y>*al>>
@>M=pS dnn$Gi*&Z%Au89qQ#FPbA>@%@9RK>4j4J6P9aKi@\8<%a%<5\t=uwctw5&GT*<teZT@A4lWRXyWu<EX>
HpJ@tK SGEjphXHJ9cTEd&p#^W!9BhQH5L#S+tTw$V^Pu=iMN>L!hjK?I+&QLWKw4Fu8hydP6uPI*l$eSLyjw:l
PL=d$6 *5h\9<L\/CY>i$ujZnKpq+#yJVL:wPhq@jncj4!8u>+$wN=^Ih#*SLnXmYj6W9<mW4*uyytyG^d@c<>Z
<F!*F? RK*a*j>mb@?q>lhQN%%+j5iqF^yjQLH4^ShAVh=&8tjVmd*4Z?la>*#:88j*dDm?b@PJjdYjJMy?<B!L
j1hw95 4NdAZuN9jGZ\:&:5+VJD1Qw^bjCJ!jiu5cu9Vj:!j*AI$L5%&P$T&B*$:R45:X45>b4bZ4n=&H9=&N+T
l:4Nm: Z?Pqa#DT8Z&E4k?EpQSHw1J:mjR?Il?I/5eZnSFqq!^$XS^jH//LA<@Sq1iBVWF#T!Xh9aZ$H!P>ilti
k9lJ&F ECnbD@/ukL<uChTNQtJlH:/mH?abiba%ZR/QPBFl?eIG8?wQSDd9chX*bPlWTQ/QQjhidu9^jHQ9?SdA
!AL#AY =bPN==?6Q*i5@8K#&!<i&*:?cP&y4uZHh%e@%:dtYF9%5hcca&*4n*X5QFNjDmQ6l5=^/hlZ%hm*HZBa
cPpG>h &4?>buDnm#pjH8dBAReYI9VnI1:GQn8Lub/iC&hkQAI#@>qcPKu>/D:#!/PtF=<*ideW8:MR#dhiku%a
LPYRBV k5YW%SIL?wl5=DttD$dSB:tK:+P1kj?Cj1J\kCkcAyYe#DnPnFnL<R^t&tq^:/jJkH/+5#jCB^&npD+!
wKyMW= 5w>MRD>dAI=SQ:/!H%<@kNeQAM?Ydd&SKTemPC<5q>h>bEY>=&D@nnZ=Z*4?^aheX!/$ZD:ViQqW\+8u
8+Iq9M h%+/5iQe$:Xun&\?h:V&*JHce\e*uila<&##!tQN1=:c6jJI$?1n#Y8icqq:8Ku/%SRNXB&K*Z$c?@wW
YCVS&N h8Yi$b%@GQ@6K<PD*</>*\%u9wdqilZ1pd5j8*5ht#/InZ>Ci@YB$ipQSHjQtu:^N6a@kW&it>Q%!n^+
lNq?$< Q*pD>p+X>k/\Za:h45S8LmW=&Sj\%H+!EZpP:aP/@Gh%yjaSGj%EFmK#H*\pp+cJ&Ep!dJ\M/IQJ>=/6
BLX4nw FRFIe5V5V?Z%EcZ>?QJ?9GaA*#!Ad+ii/S&DETWuRb:V4Zw?E<ui6:P@I#PFX!6@%9Nd9@Ip<eY#P!?i
!@>W@p *H:l?LcL^:hjjG:dtcPdV9Y5P>&#+e!BDchBtN6YQ>&$@GnD<5M:ql@c99^R+<yDnc8:6%X%4=y@*<6a
85DG%F *\*t$ZH5p\tV/R:5d^<c\Fq+upaDJ&/G64@9\D=/HZ9**+cjjayN9+E>P&%<@bH^N=>md*>y$QC6$jP9
KtPW5\ tT/=k:%?Cd9=A9b1F#b?EuWVZaQ>yRdd5>kQV^kka$Hh/CQD?1BAu#+wDZ!MB&L:!YTEDnVa?8G^tN&H
qcV<G: +R&BP+QnEw\p^@YSKj%EVn<5PE5H<PwBjNMA9uYA9uPR*nJw&nup5?yM8PTFAP/bX!SP:%mb*dE!9mM!
6R=yZ8 95M^?ZP1j<*#=bM:Ln^Zh?/bLiij1V%*hNQyA?6P:K5?5cj/=J:1E^*X#:XYHh&^>NDYJRi&L8t81>lj
PD*B?C Z>qX9&^Q*hJhc$19/l^td5Rqw4ERc:C:V^p@@R*44&@DnpcknH#ZA$9E9!:C&RB:y4FQ95ec:n95tndi
VdePGW NY%!ey4?/VVY<Zi!@R&Vm4jF?>:D6q&qQZ@D=K?:+i#&j>tEHew\pAa*EJGDbDnKe!AIcl@DD/%HA4H>
K^&Zbj bB\m6y?M:wjN+/A?B6nBA?EFh+dc\?CilA+qj<EA5RSJ*nJI*#+IJdeNknCd:S6!1n<j:u4T*@LFb1:n
BRR\du *+SGh+VGWDZL?I+qYM:>V&*@t8eL#>Yii&d#tcMd#l^ij?dk8yNh%T>$X4&\i@u^%8ZQ6!=@ytubwc&L
aeb/+/ 8:iWh&$y*:6=$b=Nm#w*L>t>aXFnXXF>beG>MPPbHpib5Q*&#RH55@<#Gu$+:<+H&K9*VN:<i8:$ei!#
J1IF#% m@R9*nd=/B65&jT<ZZeFu@:deQy4:PI$>w?:eAcjh!>kB>@EBt+cZunNaQWhm@c4>IFVB1@X\Tp+$:#N
^F:eZI GTGZaTcDwGekGRaXy4RjCw^AAMPlRHI@&M+AaZbFiELueLewWHqRdTpaIMwH<FYkZA#Tt\dy8\jyi+dw
Jtw+c6 ZWQ$@WP$A$QKnljh\$+yYTjhVJuLeKNS49E:A8M:VPM:dKVce6+hC+Q@*9P=b#ciA=IQ%J#eZ*%!*?wV
jWm/lM uT8P6%a?&%S^dPjTb=w1n?^a$q%d8tjD\5:%C#9YLh!>h8H8>YW6NcXdq^X5YyLZt?WC4/^n$DB>cK!#
kCGlW+ B?*a*#@Adp>nq/dNQ*++b@w%:N8@aQ*VJ6N*5iu:&LXHSk>jlwNnH=<&H:p:=@9Z5H8u5Li/5N5H5VeP
FqQk+< GR^ebHY?!Z*tDcMn1?H:t>u?tH>\CPp@RQ4*p*:>DJ>?lqe@\:5jjk#5l^4%BMI6<F9QjwbLQ<MbSL1j
Qm>Ju/ +aj<k<CuDBB=A$VyAL=<EN<\mP<awueP$R<P$R<N$a<P$b<cyn$%^Dna4$\:4iC$!a*yPVSnRAN8@BLD
t/$14R ?D$tTnXdn>Eh%y\@+9tVZ*tMhi:I?nM>c$:8Y*Xm#+wVHT6icK6<d8imb*cWQh&\/Mn&Saj1!:5&quVW
=PKQGR LGldW>m!81m=81lyhZFDXXH6+4\Nbhq%bXtQAk%k1!N8h8!yFdAH*hhne@:&j\d:Hypii+S*V*N&VGN9
:i6j8Y VGQ*Q<Q89Y<$jSH&4Q6p\9V?ldpQuwN94H#YlL&>FZa*i8<R>5a\69Wqw&mhaXa+yw5^mp*B?ME6yM<I
-AJm6h 000ef755fdc00110334 Page 129 of binaries2.zip
Fb*/Q^ \^ecly:h$hIHtRV!jSF/!WC9c#@DCc*+w:RuDlCbA$V^ILF$EK<b^LeN$ZeD\<P$E<P$p!P$W&AJ%+uu
HFca6> B<WXb=nTDS^nq6CEE&BG##I*!y%ujIlt@C:V?F*YdLbbJuiae*+*&=@>!u*?$\i1V*c6QNG^@Qt&ye<*
t!q>ll L*/8chG^:R8Q%yee4m5=WF9T9dqp#@4C%qZ#h%Zq:/!c*:lmjpNXRZ*q@A%qYVZFGVWL5!/pPWHQwBY>
dK=!A1 ER/G@<qb:GGZAYln9H4d+6Xy?6yHBt*VuL<@NJl<cN\!#bl?Ge+9A&hN/wA9FeKbjZdBTTLiS@$ad=@A
DEtZLq h4%qHLWX9tPaA1+NM#DjLEN6%n!&%$Zw>4FJN&VdE?E%8?KB648mTIPXkAE!ckCGPZ?RYD!IX\@lhWN+
/R>Hq6 /^D>\DD6?An6!kl6aIVYn%biHKFhG4Yw8<TTyd1aekRtZI+JV&dCVyyutnuQ8HCi<SZC?DaV1YdN^y6q
eDWkSi >Ce<u?!1P6G=:HldBan^5adTa>5YQqXZhGl#Re?tk9$dF?^hZ>Biud>4iZdn58#6qhqdK:Q4KuI&q&jZ
>K@p6b FKi6LElb8TC>ipH1X%H#aI@RAnlH#KqQDT>@ajFwCH5$Cp1$+iDDih@@G*9\P9dh^/C^ajnBjeNQ@wZB
6/!+tK WjS*wuGG/>C4lV8^d^8\&&nptea^Sua/yp9C9DQui1jQmhNlcZGae*Rp+VHKeB?AAwFGLR16C<J%+Aje
^1\niS bkF:BwK&!mCbMWkWknAQ+i8G<G*D>QblGPaZStmZS&knw:TlWcm/F/kibi#9XWleQZG86^uZcS/Zbe#q
haP!Ib tZDXJ5!$iec=ypc%NPNdDPP@5J/\#b^:^<L\X#%d@lnp?WVu$8N6IMbq^:aZQ%%j?NTYk5Md<:9Z=?%d
n+ehej t:8uJ1>>VX=LXZbnSidYJSq%m#M&q&h5K56eZ=1^eu:K5y!p!4#pm4!WpXRF9F?Wm8+S6YNjjayh8#@u
Q?@%&a ?*jt99GbXh8$/MJD=5NS:PGk\iRuuL9@\PBekjwinNXwXwlNmCd5$&%a@!CY85$kIe$\K\nLCeB!k4B5
9u!EJy d#l=jWwwJuNyI>&HwEPZAactu?EIXA<\uGj%A4EiA\#QAadZAMN:kPE#\AlCu6MHmRXDSMWR9taI4^*G
5S4V*: t+jyZTP$y$hwb$GaS&tDw:TBWXwj^PLb!!/YXl+YZA?e/&uP>VHn!8b^&Tbe>n!8u!p>\>SaN<?+C#h?
y=ky19 %RIX:ei&RTZ=tihQj?:bE9chQ6=Y@q#V\tM:my?8K#m/Kj@\l6!ihdu:14M:X&Y&4<^84ey8Yyc=dZFc
?6W/jN dYu1ywYyG+yV%lYu4mqMYb/dXJEb9!R4wV\#cYqtw4:j!#@45P?GDF@?kuZ:I=PiS<LN$<TCL#\u:^q@
Hww%9Z Q\Jdi9</d#D%j>n:a!nD%W?\Gp*G5R6:cV$YHk9jSM=JRnNNi<BS8PGw<lw5^b=ki=/HD4&RV\?$<6m1
YTEy?: #!DDh=Dln\mEpMGDbB#Ke<ER5ZmIYD&Md^:GG+jyuTQ$R!N$WDw8IMq/?5j\$=jebFIQT++Ht?9BtLH6
uaMQq# ae4q#+PI#C#nVW%##I^L#a\9pV>SndL>bGPD<$8i/hm^ywZQdC>/11:k!MceR&8#i6bphc@P:F!b%4a<
8b=WP@ 4YXbY6QT6B%Re9KGw5S%C^J4FmSXF!SX=TbYbMTZyeYYy5cYyMWZyeZ*y5qkulhmj#>1iQ5mCT=X:u\\
k%C/Cw =>yZ^q@>i?/hl@Qi@hkR#6T#De$ke^n%EX&Gb1t4RPm:n:bnP*bl<Rtaddbla1aBHFXi:%tDbct^dBZt
X?*/#d 4+pm@EebAaPMwEF!F5a5WC\khJAMA$*8RSI$9PPG!I\ltPhF\<VKaZ#DML=>lN+&R8<iwV<#Tn5%C5wF
j$eXSV ME\dGKMNR8mZBmTLK>%=QE<G$+QJ>TC=HuT84#uZ*yVLM8Y!cV\%nbF5Nm@h%Kmid9\Y!@kh%lP1RhFt
hnFYTV #9qq#?AnkW&da<>5LZl1e?/S>htH1>MQ4E#dZ=ZY8V!%4VJ=%?Kp^9Kp:YXJ>cXJt^dE%?VHXijEXiZE
y^t&y6 L5?P4emILW8JLp/KKp!MKpmK#p8MYy*p>!DhADd6K6C+cm&w8@+kdMJN9+P>@&@5*uqWnVim>C=G\\pY
l5iiD5 wK8d\yqiw><5\jdEa56T5a^w#DQdKB8>By:qk41+PMA8Ghp&GKkGDKA^awmMHmJn$SIR>RVka\#/Ku/I
1aF=F? VBwm5+DuaYI^<4^?BN</k4iM$QiP$k?Q$y<dyb$D1te>D?tZE:R4w#d^Pui?\IQJiS^5Z#P8\y\4wHNb
Ec5XkQ BM<DJ#Jw^p6w^qibQ%QNNu:L\8CuTeclbMBVt*PP4M5/9Cd6\M4p451p#51p*SYJ#iYJDcWJ&^dG%^ZH
ZT?&TV dT!MY=5j9VI4cpXtXGX/XEXcbHq!bFFCYH=5YG=MYE=MYGbMiFyW?CeFbqDhWuSda#N&@^#&%8ja>G&p
%8JLjN ill:>BTc\kCW=VZwYPkNQ/aWP^8J6j6n8!P^BX=aVQ!e1G\5IM5kPRZL<y/J6KQ:EmJ$uI^EGwHD>GE!
HMZah8 dblMHmcVEIt#/D?C:cuDbN+\WV^MLBplXw=A#@WniNMw9Z&WjtCW@9Rw@eRa:eIa:Rw!QD^GG$HLkZEk
9nm@aj u>%/\NqG=WW!aeWtaLC>#KB\T#1ZTZDFDM5RG1*I#GkR6Q4aQ%L>F69pF!WDn1^NQ:R/=eCKyQ&Xmb%L
6+THud +uiZ^:iW^VW8nNqcFL%qRjVG?hH4<1NZb$W5V\84TA%duB^Yyk56VkmhH^PeE^YeFSteHl/eGl/5C\6i
/JQIqH F?MEB^/9\P/*ahNd+aVcp?>bjQDA+L6@G@#%p:u@HDYbQwVh*#9*B<@=/G*bQNn\@t+BhmIRc@jE>wbm
IGj!aM VVw5&^PLVDG$#b1ZE\i9X4LhMb$H$!Kkn^GG+kw$A5u=\$VSMFpAbbLb\&VtMJp^C%nQGmb#l<u=\<VC
eCVeMR EYLyCLF1BF<HQI@mncQ$6qH/9qH/wVH/5&P$W&P$m&P\iw!M$<aRI!nlX<dNL6$Rq/=^Fe8>eA6RR##y
TnWK6n /Q^I+@wSZAZJ6YD\dAltFG*iAeLwB>X5++<=Q@b5@kPHX8wPLp9wZl1*h*Fei*q$e$q$a%HW%5KILjul
4t^wi\ G@QC%?cEXYiFX1YHX8lC!lPDF!aEF<WF#+<P#I:\#\n%V\*^%+WEJAaH^AaF^AREjLuCcLwG?<eF:I**
<WmFy# niFMW8QanYuG6tun:t>ML*^mMZ$Vi?6d:N:L&MQX/PI^+\uTac19lGN:+:BN&?e5KeQ<$+\C$:CRdC\m
YPS1W^ G<8I^Tmj:YVACCN$tI^FYe$hIW1RRJDX5lGmiIRwHCELS5n=I&R?wkB8kj55GmGYn^DXw@mGWd%u9GYM
:S$<a& 9tiM*nNGQ#yGj*/MhuweYKWNI<pVmNF^Y9<+mD4>?Dm?4><&IMuVkkNVneNk/@FpeP$58F\L4yak1?uG
TKjm6\ d/Pmeb66jN@T+Ii!dQan#>&Xeh%La9cXS:YZS4aWl#eYlt*ND/*NC>&aHdI&M*l%iuBXc6BTZWB=9H>^
jD!=Ta nH>lqH>?bEB&tF>/5I<8$D5y$D9i*!jG#!jT%#jM!@hTIRi$Jj:%M9dcR>QQQnV/^$9a#Rit:#?a>>%:
lyaHZ* &N&@a/<>\6=+A*9Rln%all+cb1C:Ip?Tld&Xn8&N\4a9tyMQtuc8YEwPFy!FSWc:EB:nDL>lSkn!uAy>
YjyXmV E8YnSA&\N$c5HmXYnBIXw<TmWdm^hJb!6GZbKLEK:dqyFN</lniPAe>+^^m>c+^?eI#?%Dn>8ZHc^ZFa
u$l!JY L5aucFPI!Rtw8uiehtce@9R+4i8c=iKDcq5@d%Q#Gh5+LCciJNiL!hY!iGwtP+tkZ&ec9jjaM?hHl9X$
LFyuSN qWj5LR%9L\=4LR#hYSC<QT?wNmhwa&dA&uV@%cu?K*V?Faq?=ZE?JhHiBSHiiYHi&THi/WGiPn?QiB?Q
w&T/B> YB?QKG?QeC?QEE@QIHjQ+nAH$D^:iAn:%=6#V##pnV\!dJ@Gnp*V:u^k@Pl=:N&QDQ:%N9dQ+&k$*ZTp
yqLiYZ Ptbt\wIb$H&T8=uaWW?5$SQL65PTknBhQCb$QMb\HYb+DVPCl<uwEim=aJSaPpy5HMPd^@Aha@mYMYL>
F*5&<8 GAk65ZKWYI:eLpM4XWn!&nF<$^liP+b9j<L#9nH/@uH/wZGw?kTINHA:/%pQ1CTZ^?p9nNG:+b?k4=&!
1cZ@*w T6nm\4Q^^NuR6l:RJkEFuMZ%aQPeYc!DVNQ9kGj&V=P5b$>^TEhleG6B$M/<\P$=AdYb@l9V@hct?1=P
%:Veb# >q/i/FWS=%Wi/%WT/XpR=y+d:J+S=J+Y+K:#ha9*ew*&eA**eAq%e\%!hjX*ejX^e9ZW86/=MijiXi#N
:WEe5Z D:EH>\*Hy4EQQthet5bi?y9=9SP\WjjyTi#:W>k*>Wm!@tq+MHy:JS!>a/l@SB/QQe#GVkhk!?!\dCZt
QB>i6= :bBA&F?%eB^t8A$#@EaaETNp<mn$ZDqGAHX:^8p>+@n8eZ#uPL=%HQmE\6iPEY9GmB1$5tEM*+\pk&<d
<mXD<p ^9Gted^qHP<ay?<hy*jQiu+iKJ&kDTP>X^GV/PPqCjAX9l@<LQl#I$VFCKP$q*LQ>#dHwYE>DATV/<4m
nX9D/L /nmYZ*IMj&=aV$hBRG6iRFP8@+=M9:wMu+&y*t8V9Xaqi1&I>/mIeT8Lem?PeC5Ihe$Ne5pIeE:%hW:!
w8$unk hwu#eI=!e\y#%ka:c+PeuQ!$Yt?N%q&6hZZR:8<nZy:GD6^u9#8N@jQ>8hMu5Hi@^D=/MPj<>?J:#<!h
G4qb%P tcRnc:bjS!D!4CeIheQV9>TJ^yS+QRHL6YG\uC=d&A^d1EeaLmMMu^FG&CmbNE4tk$I^St\c^>9G/Weu
YJ^dXT /F$ViN9EnPw6+<VGeYL>PLF8uFmLYA?*+LZn?Lb^9HEed^:H&<j^9SQ$uku+5<>N$E>N$F/eyA%Q$1at
n#t6a^ cXjSeu!TNnBBP#>BQ#cP:^uD/<iI!qG!EJ+I/GXVq8qHXKwwd#PcB<q^a*ADGh\AC&+pm=9Pb6<uDH:N
V@^aA/ e%8&>/=M:+b$4@yW4<$/#*XJ:19n*cymZC8mZewnZEyCuSeEPieGPtZ+cqP>HBM>HiQeNFHP/qAuhbCn
+F:Zut &q@6+PQk+GY9hqPyuY*XYl6%cJn<w:eN#*+=>>/4&Q99aR?/Wh9nMQdF^\aj@*MPdFwZwewem&Ie@E9E
e6yeyY #Aa:E%8cW$tGn#I<S^n8THLkKCN!qE\eJZQGmJI^wkyclaa:J9CYCd^^A6</AZ%8?4H1G4T!aXa%PB!6
/umLST E*nuBL%:%9PbYe<Vp:SJ6B!byQXP$M=MkQ1Mh+:nhYPkEJG=w&RiQMtCM!!>@ByQ6<jhTl%l\RquekHB
aiDhwk VN+Yk9\%!aCtXQehKY:%P6hNCT:4aq%YSYqZSGk4\l*LRnVFRb4=@8weH*YGq$P!8*&Cm!4GYSYl6R6S
DED>5$ &\Za&@11dL%6dh&6dX$wY/*C%pFtc!i#hdNVjqXn?EY9\ai*=<H4/&I$PX$>>94L4D6j#+HPm%Bma&i6
dB1i$+ l5\Tmun<MRG:p!E!K4yByw\^I5aaAcPMwFERbpd$GJp$StcMpR9G!eZn^Py^wuaC*+Wp:=nA6$*k>WD%
\u8:dK BLF=k6k+RY!aINbPEG9GmYwpHG\BP&?j\J6R@9hN$A>Q$w>N$5>MR5?DW:VSKhw+YIL%Th4qTj4JTj1S
ml1DwF CSn?&uFm&SmbQWytnMLqjJD6Wd^<pqq!&T/+IyytH5Hp?DN=^?qt9?G=Riheu?C$KXc:L61^P6K^Kq^V
Cijb>4 EcI8D*Rw>4e9<FZqiN6q8N5t8>wtPN6Gc&#C%VdB>6d?66a?NyRHbi&mwLS!TmPnXBLKXp\ySSRqW6^J
:*%KCe MZ=RnT+Jm>FFZ^:&eB%&>VQ#L>?e<>1d>H@iNulWk#w5lcCiCi=Q+DddeVwIi^lpELT$m%k!VlcMMjT1
-AEV*& 000ee99109800110334 Page 130 of binaries2.zip
64%n:F \<iAbEd<GKqDuuQH!iJ^wtKeYDXBdJ4A/=BlQZZRJ:EFdmjYV^A%E*Cj%Ylq@RT?BS$PwLy>A8<CJmjy
J11^q= ^!hyF/hw@XP$wTuc<BRW*n6JQ#>Jj*/TjkkeEiS=?SmbN$41S5t$YhXF5EqD1:4PKn96+l#n#8C?SnQ/
dkai9V De@%5b4NMb4%piw%+R=XwjbLk%TLA8^KjG$ZiF9uiqlu8Ftu8FkucK%nNXTEA^XmV\ZaKu&6qb/W$qYl
QCtFe8 hJI1NBKFT1!\5XIwlR1bRCHt!+<G+@CJah\55ZCpk9=^<6**=n^aA@Q<aBM1#y:w*a1j+\thD!e+thhi
WY=Rjk JXbMpKZnbQa+tVnPmByn^ADQ+&VTPJp&VtcNp@unbMpE5ZkC:EdWVBIdJwuNp$VhJFE@mY?FT/J&p6k$
VW<I!d CXWD!XZIh9WE5R/tHRj::J#E&!j^@bQ$y!jyy/bwq/hwjak4W@TLW@VVKPwHJtGSAVY@Cl=^Ml/yVkiF
ZQmF+P C=&LT$cJJYQ+muHJ5k8ywaXj#eN?\*N6yGyDtF%NmG%XwG%qkP$mQ?8FQqTlJ=ZuRYY/WYp8qM/bmuPp
6\DqSq wnXW8AMX4KL<dbZiqNJD1ZTXK:XTlSy+F5%+qk4p\HPq%lL1DWiuN9$JDp&Y>@Z#&Ii>/B\Zkna?KjdH
kYbKL@ @CPRyLhMGt=:^Yn%LhNF%@H<TVJquBGNmB6uAPey+&V/BJp%RibQpIZkYE!RT!cJ1pqmHSJdQ$X5t<IS
\eAi8A SN$WqA?P\wyJanucb^Z/8B+iBd^lEt<D11jw#$#S#\C>X/Hl<&n>?BV>KD\Kb1%Z=&=:!cDtFc#<Dcb8
WVjMNc !DH<8jmR=k1@qc*8GXh6XHhEXy>d+I@MDcbNjp5!aGPIVW&k>Wy@cypj6eTHK9Ptm4!w?S=W4l8X+W1q
@9#eV? 8FCJVqT5I^YywWL61TA:!5>G/WWy*SXKF?VbRc!\5%JaY!pWi5>e8dhWBCWHw1:S?qiQ>ePiqKFKwm@L
IFcyZR d4NY*Z+Jb&\5*QFkau^4Wtb%WpXWewhH\qQcmPNW/DqJ=GXP>BAnaeJeh>$<>by=^nX/%qW<d+wwtCJL
98?w>P pM!%W<RY=LqlCt?eIubMRi$dywnXp<T!TcITLaH\qbQEGulR<K%ViQMW9k>auVI>hYQi/X5ty&/\ulwX
^\?:pS hQjd:n4659ub9KLN?+KTBl^h*yWKaN8aMV8pNl86tQ&P*5i5C/LYBFJX@qTqL:Zat!4%ltHPh/i!*cl$
+EE1QC X!4btW4RW4Bw1KHuRF9K^^y/hqMwuiWKS+uCZkR>W>C#ZMKZm:l!AWj?4b@BL%RDQh:wXVk%iwhIk?a<
RB<^N& ?k*WpIiPl6>y=*:4djKqF@%#d?LVEPbWtQ$LEeH%eWZLhXWycV9X&TiatYQG<c@Quj?KTiZL$G4>Xd#^
9\cWt@ K6=$Fh>=qhl^qcmhk9/ZVbEXp?SmSAX!ZwYPT?$W9uNK$Q%!=8c8nRYqb$L<Q%W\@!En9:a!8<?d?<nT
TWWl+R +Ee*PS?9Y@^S\*y1A1lXj6S!Z/wClduam%wA\8^Pbd4PFA$R=ml>$dCHSeNu6nl4bck+w/IBQM5Fekq9
^GBT%d ^9Q:HpbR1i5Ve:84WNh$QV@Y?APcZ>4+GQCX+?\de+G#nbMa%Ew5\^+e\+=<#:=%VnuRw*cwQW/99Ra>
bnac%I 6%#FY?GTcLlKdJ+mXp/ST/dIMyl<5llSPpp5umJYVNG4J/w8jVB6\+N^bTGj9<%@ptR>c\KwKn?1$whc
DKL6TD :EYXiqGFH6S<N!4Hqey\wXKe1ES>tDXWGCwc9nc\PL6VM$ZnmiI5j>L#qQ&<H@u<Ca>6T>B+PI?S#Q4<
Y:TD45 Dh91&jeIQNEdMcG\/?<**WdjQG@\&eja=PetD=8^j>Ya&/+=T>>?A&?=l4hj\#88+d89EW*ZmL14SQXX
S#JWAu e9pW8SnbZwkwt!KYVA4Y9N#&:MR$^b<J:i>KN9?QAYFikeJe:pYXiMI\=:qSYT+w#E=WkmMXk<I<W=!6
n$cI5B pijb+1\YK%SY\LMeiJd^j@B<nnL@?Z>@GFeFtt%H>85<h1=EP#8mu@y=5B%R<jhG!%D5acuBk$H5w^9a
/u8Z8@ 1Wj$d*9uVG@A95mn1>ijw8?/kZhe^@hi^@ilbj6%jPh%w9ac5jac5jI1WZtX4IDkT/h5/?=ec8miFlC@
1BF8=N L>umQ$/!uyY?%DIjcwpZXibJFZ6RBi=W4m8X/WKqPpQQwKWSyaciR%TkPMMY*iQm4D<J11#p%5C#+EuQ
KDEIFn 5mWC%q*1mTpGqLQ&bQ<l$6q^tVR@E?/A^pu\StWpFDak:^ZQiZFM>8+uBt@jke@C:5ea1hiiynZj\D89
wI?HGT +@89+\eR*hiJn86E\#Xm!#Ym=l1^?l1=+m1>e6L:\Ki94FkHV&&@abn:b<4Fa$Caq*yVm#!ylb=WwV8X
qqa1Pa D+1GC=ZlVCW:WWtP5GlEI5@Bh4DqDI8#EutYKS!Bb^H!LQ!Sb!FH^4iWcT%FL+8M@tP^Q$H?BLJj!4aG
Nqn*4W 1jbE>$a!+DlZh#8^4#=GV!EV5C@</Lad#6Ndd8J:d?A>N@DDN@AnmM+dBA#&hYLDhYLNNZ#F%bnBi^<u
Y\D>FH b@!Pb?cjNK^utbi!\yM1</CK*cpFdnDMYe=WPkm#FlWNIBt$NFTkcCn>dbR??ya#8EKS#Va&lDPi=eA#
T$4cyl Z!dt!wBukTXWLdCWN9Aa>?RGM=d?lN8jIEXnkDnM%lM>VtlkBE>+Y9!!Fj98LY#kHR/<=I!EXiZjdtaP
TN%ct4 c<@k4dj\9Vj^A#j^w#j^a#j^\#j^nl6E+\&m>kbR#X^#M@ZN/Y?$44?XbI5@u&R>T#&Xm#!XyS:KInjq
!5aBdk jFhq4nPX+WTqcCthI^Y9kb+n:IFubbC6Elbuyh/#AuwYA<>!+NqG:%pkp@Kkb^HuB>W<6qVLF4=mcV^V
?EI>aY ATS@%9BQkm%Db>LHnWM6<8\QH:njjSZ:^$d5w?Qp*VSniMdWaQ>&M4Y4Pa<**eI:d?I>RQW6@NqdiQhN
@+1T6% w9Wt5j$G5jpG6@:%1ljju?ca@cyu$@@K5J+KV&Y=8*Klt:LRXbuu4M^^Xta+KbP%!mTNMp/6nHck\8&X
KcFGNw ITyqwA$5#5C#P:\TuQH5aCXZ/V$LbR1?VMcVTdlR6SXRDjLMq9JuKYPR*+KGKAjNT/8Hm<=$<9<C@Xu%
tWpPu* ed#h+YPCS%9RhbAQ>5nh+QFS?F^F1qciw#jiIuaD\:j\y&:ll&:l:diIly6E*W%l&:5>#YitGd>ptQe4
q5Y=l@ *tm#@GHQT#!Wbi:KEnjqAljwPW84VNM1p#ZKSLW!X1&MeqAC#<F&!DPFQC5W$LMW%A&=k$kP/4PNREaJ
?NT56m bE4piVdTWm6L1bA6%c5Y5CS<q5TBKd#MMuu+=L@medew@e9nX4QNnQ@I9#:i?led4bF#h/VZeZd?NTue
qaJ/lj :b:CYFN^^4V?NZIZ1CG*<IP*<N*A<!%<!\&d:4>Q^T?E=jju6iIZ*j+c9?q=pd8!FIX=9nMwG5yM4VJF
@+<q!# 1>SyqQHA5:$!$q+b4qIG&!wD4KFuL/Zmb==qhkKbNjKMIm&Xe1SmkKXWlLBmT/%aEmGAKRaWYVD9ek^?
ip!New y?$p?M?L!S<+HA@FBk6$>id4ZmY&kYC@SDT@SG!>Sh6\I/D#Z^>S6n>6PSN@#P$jFq:tym^^lYHPh%Lt
?&*Qbp cJWbn5yWnXKuX5ddK&Q5qSH&!nA:bbAN>A^Pkq+K=FpGQM8%a4qcJLeZR5<w$qIqV/4kTiXe1bR4qil6
c$JV+j R?GTGhlmCE9pcMEjalp@?t*Xn/>#BdQIb1P8?QW!<mSKBDZ:+:P@6mm1#1n!LZLNT?Vtq<k%6<!ZZe@j
$j<@Ml <NbD:y\j@nV+@$Z?F=J@SZmy1/LISdHATbHuyMl&XADQKSyqpwM!#q+b4XJG1JTl66C#Q@C5XEDQe8nb
S!GWRF YRI>c$R!+FpqqNu!yVb<KeYH11F6L4R6+$kAWwAqSGayl4BFeybIaTE5J5t9jnjaQ#i94#PQ#/4TZ<j!
#!!LD! mR4\JE^5ki>YQP$XS9+6^9^dy9p9>ik/j@nYE4W4cQ<:bn$9hFWWPm5KuBT=YpYYSyG8WTR:KBL6FdH&
pGn$ij C8A=*E:9YiFQKcBuPjV5JyQQiLcTPXnJXAKymm@X1:aG6upTJSimAHBtWF1KFS!^EtAyW4K64FqCY\8B
w5nTB4 P+M#^VJ/>Ae>e@>uQPAcFGu4#MLi6Im=^W4:<LbDFN#P@^McDYd=jh5q#wyCJ<X<4TJZw<nWKNI$Cy&D
&ElQpA IkF+Xmtm:BVl6wyRG$YRNjK5kJ+>=HI*1h\Fiya=mtS1whRBiEc1:ZkTY=:EBtEN+E1wYc\=at88&Ian
MTZAw4 54EW&dKFK1bAbeF*aQA$JHeymZ@=G<Ht@u?DJXbPdVS%i$Q4j*Qt=65jmVEhaQBd@L4#Ith=kXci=!nQ
??LIMQ %mk!%IwWB+ZPZlG9W5Vc#ZkPRb+DqAyjleJdL9iW!WGiZTR!b:FMK=Jy4KSI6eTiL%H^JC1?BNnYa+8A
I$lBJ+ /%\^RMWV1:kmi+/XA%8wbk5etZ!6BhjJk8NmaiuLbJ%qG9@@bQkJmpV%1/Xd@tml?F*J9/t/WC8j:!nQ
hd=8aT %em#HPVycutKk##JZl/9p5jcKmJ6FiE&mlB4SSCq>!#*Rb:hbVI*me^FLHMYTdXYWpilSCPR1AWT9Y$w
!Th+6E HDwZQ<ai+eAV1ZpmDehK!^Fw&Z^uF5?X!ZXnen^adC<Y!+jFKtZn4#ENZtebj5R^@Q55>!!^L!!^d!&j
uTudBH <QNpC@\uG@?+bB/<@@tRd9kX*i#QGMaNj<R9&Q:yL%tkqieD#&y=J9D5IE?&q!iy=QG&<lkdicT6QN^G
IHCJJb Htw6D/LpAR1=H@L5JbN=TGX8ALHWSTS%6yI+CTXclCNj4Qpq\Hc6RK#qm=^+X5=ewR6H+GdJh&j#QNpe
/&=k5q L=cqD+96^&aGYDKDLJplHI5\4pWE#!Kcd^HLb<RLGEqCS11R#BGSlTJGmhmmXMJeKtP8pqlW!=ldFc^6
k&m/W\ TqcnNZ8u4iX8Bhp8yS%Vty&pVE=Ve<@cGJ/*MVlHGb/#tVP1tn8tNly#NB:RtJ\R#*%PauSdd9!liN=H
5El<QF a6PQyPd9C<*8CM$?5nL@ZGV?8SlA?$^w?nHL/BPY$dh5lKZSN?!=Z^N#9mLt*CZuQAA\=u#QtQ5RN@\P
JbJB<> N@#?S<J@K>kLHGZ=cqtPk!#DZydtIE8&q!Zc!iQ$ut*p+hd!WEwiyJRHKyFute^dK9PW!n\pW8DbVTS^
8:1P6& 6bK+AISmb+HaCcGh^YpYb/HaSTB!=a9e?Fd8QIEHq?@F+jt\8V/YHF<&P<CTFeT^CPHPGI:mM^+dV4am
n#nPAW $$SplynMqnD!yBaFWtcSuLXR!T=ZYm=Semy6PXX&*NW1Zw&c9<GB5$uN16MR&#VtnX1VZT=G8>#u6umd
Tn=mki 6Q1b6kcb:\/q6$eTudGM#kVYZy*q9nS?X/cpP%jbQh@?RKH&+EL*\?ZiS=b+Rew>Dyi=HX:we1na/YCl
mqZ8jE >5AC#aH=/y+<??=eVZi8W*ii/@:=:q$F:q*#*h5TNT*S15+a%ep+?=N^1yM^hwDu@GVHjKZ>@kBJ9=?p
WlMpJD #$>!Ye&=aM915&MYcGT=cqpY<y^1L>Qb!SJ6bZE&5ll4YcTNLN^cBn%D%dIA8e^ZJwP1JXJQmhSDLHEZ
mmYql^ Th#EEne45b6R:AypItbYBBA*kelNKHK#E4pLSS+CK!??$J5u<PH!@Vm<AA+upGMb^GGHeynl$DAni5a\
di/cbb tTkphXbpKnKeJTb#JiS<KXpwb=RwLM1W#MXKXwW%i:tN=Ww:V4W>h/$Dd/PG9$ZD4hi\hnmTP=*Mt%#N
jp86hl huta6Qma6Q1d6kHJaVPT>$DJ:K+$dqitwD6H&y%9*XNwj/nE/ZCb^=FF*peYIetqdwhKZA+XIeu#NV%=
:yQ8<u Dn&=RLJhh=bDh/dn@t#ujZp8?@Jh>?Y=:5q#&=99*yuu$buunuD4#HZ6!HH6!Hb6#*Fy#*aB!>*bV48#
-AabcM 0003c44b8cc00110334 Page 131 of binaries2.zip
<jmp9X uZhukcXV9q1c/!DNWpp#XNJWqjSJ#%HY$HMaJR6S!wIW5pCF#F<8>bXKjcSTd:HET!#^FE5<SGJ*BLS6
wGjahw JhLnn9BAiF1J9K^E*pI4H+HRq!@\=@ED8d\kLniE\\un55N=4NpMp*E@GCa!^ETYtMmXEQqTawGMKJIV
R9wuI> yW1!ZGqSRVE44XqX68#Xhya%>y#%D6^NGq/hq4@Xph8wbi>$bnT=Ee%i>Bbj<>bA5:bk<@b\9CMKTLda
\^8Z?u p<nct&!=L=&:Q=QjuY9XM%>&wND/aIu/eJuL+ZLQ\&Zil$w>Dm%$P%npe1DR/WCBa<><VZe?MK#1#4dh
MiFyhB u&uVqYHZqiG\L<N^Z=dV*q!ZQaAe%<+u/Ml^/el&d5>!ATC*TG?YW^6EC<l*pPdaT#NX$uTXNMXP14PX
a*kTly J6yI+/!qMbR$myJGYE6uQC8qRZJykE#1L=Q/TTT?EwtQYPInEu8L^F+AJBMmlAC4WP\5jpI4j!6lwEAR
<1V/jV JPAH<*tlQG++n^QB5+#m5/Q=VJDlBAGbJCTT4Rm>+W\^pTQB</S+kR\9p8PqT4^MTT!t!Ey4^uIdm%X&
kK&?bQ 4DW1>n1X=Wa%B<ba!>9l#G>$+VY=euc=5%8<tK&?nNakjHew*l/Bh$cVuZHMQWt59Tte4uVi@m!>bMtB
ampY^= R5ZBldcH!+Bu=$M\\?+Hm>$PFLweKHD1ti@ap/@8BnHPBnG&kbLV1c+$/*&y14$y/4*ynu8!uQbpPuht
A:<&?4 8ZSt85Bqqp5H^Lp>E\INk&Yt$?+My:bMkBcTye%STdL5JBq&pqSdme=Gptk6mdiY^qLRe!RqDcipaWyy
amq$b4 mEIcyICiA&WTj/uEV/4*LJ=BJAI!9RWRH/F\ByBikhBjKA^ABFpJk\TCEAE9VMAL=*Mn?bdSjHa5u^ZQ
=#*=BH 6$kWpDwwGW<V+SqmQE8M=$4\jCt?RIaZA<pKIBqjw5R44auqN8SKY+61P?bcFY8DQZ8#k&Y>l4NN!&%\
HNImX8 +VY/C^5>?E*i*F*?qm%B#NaRSt5+5V8c$S:L:Elphiw+i>J+i#Q+?*IE?@NE*R5p*WYKulLd:tKH:mJN
E/M&@: h/FV>\KZ@jp8ZZqPZdtcjhpP?#JXi#N5>&Va:Et%/W^ShmdLP=QpHauYHat1hy&/QXY:P$*dq8dWq8:e
NmnTPK mum<$y4llFceYmDcGVIktTwp&W/m5=Wp&RDJpqlKE1PWSCwqEWyJ8EITKyeEA<p!CTBRKktRT9#Fan?^
Mhkuup &Bjla\Wq?@CFipBqAQmB?5AZBAkEMMNCTIlREC4kl\6+EZ^8FJ<Vw=e5aIKVHbCecwYum?mbau1&tJ+4
B4VnNY wihL/R6p>CI=9XSJL%jTq%nVq>4Rq>9kK&&Jcn6Gneymk+1%!b=h1:c5h?J5h?d6<BA&iI5djWR:@RSN
>ajNS< Rd#tEM8YeGbLqEX4LLM6kdXd^&qQ+*Xt<D6#lH6!^Z5L^Q5KJX&Fm1+Cc8><&:*=Du9!HQjpPuZtcD8#
5I$I9b NJ&b>l$b1w=$8@bWt@bpcui!jLhP6n6J$la9ca6V65dc65c4YyQWLetcFy&tYijauIJI%nauP?%K%pJT
SB>pMN 6E%/WkGPM/R=b6mKW&*F!VdmJG6^QCYPXa1B=GnpGWkP$*5Gp8Y#umXmj\u$:CeT?RK54H^S+jZnAjn?
8laFcL jEkAKMJ<jlAjXAq?mIAjBk\L?SFCZ1TAG!Zk^QI6+\T5BCFVN>PmADEGptp=Eq1iqDbjSm8W$+wX6FIq
MVBmYY 4X^JY/KpXX4Vq6uR18#w%T1mSpX85LjabM@ewtdZP*L1ujqd*c&&i$6&?M5c@CYNRcKhIeKteF=#NKeq
aQlDn9 q6&c\G:XeXyVii$b@I+5aYi81HP?GLAHLQPpudtKnq!1I>88Qe8lQhN^h+bth=yDY/11LeY&XYjh1qP$
8q\V$K J5ycEtR6ebKYYHF#nLk=X6aeyh\Xa:M4V6YW+NCW1Np=k&Nnp4bSB=cPnVwNSL?TBNedpnYNkBSNtw$+
h5tpXa ^SyKV1DEeWy^4EIe4SBHK5VlALp+VC+PqaqD>K1qapCkXA^WB+lFEC54YBaEAmmY^\ME#RL1eAkw^cBK
6w?:@d kA\LiXFCZw!AG+5p^\9amWC!qWWKqE#MTndQp=wZ!M!L=PaqC9NTyZt=$u\JbX=ldd:e^u!qLY&%Hd%G
RZm\Q% lc?*J#c1GX5$F4Xch1$#6>=NYP<q*8wu&^+w*^G5cAmXNwcLhpaJt&L=8?I=8*TYLTt<%k^?Y=ckLWjW
N$Gywn um5G:M+S:e/&c55CTF5#FK$b%1%yh1&yDm$yDm$/XdQP6ntScp=RNMjLh5XJh<YKt&K5hpaLhpaKGmNE
GptI\u niH!^uC1Mh1&Me/?Ie/lIhblS:^/S:\G5D%B5@&HyZydkkcTmEnTdNhyp1%FPp1WTIpiT+:Ti=bDwGTb
CS9HiZ PBkblyIq+pC^CCK!CkTuN1E\pC<I%DelPF#RmkAEe#plQE+an^QP=$V\PbECAFe9PX=ktTlpJ%t^kPSW
\!T:&= ETMhTkaFtba4Me?ZtldIVA9qb5WK5%KqYduTdAqq6yR!Y&=6XtX4964P9EbFY/imd*RkNnw!NtubY%!=
\1I\BX 6i/CPm>^uc?$QqC=NbVcF14eEc=wmJI%^wwc+\W:hh!tbN/8NH=#y4Aq!/w%T>TTchYTKY#PEDcuC*cq
MQGpJM CZcqmyyTyE$/=W/h#e+p%e=E8=$JNw%^%w&^m5baiYP$4CFK*BBy6TNC5CPe6#&e8#%W8C%E5m%a5T*W
i^n<mc it8W*hbw?@wakEN>4Lw?XkPZej1q8k+R4/=L$EATEWpcDQ6@WE5DBBRAAkAIAQ%XdTWpKc=y=B$AALa+
SmeeTt AAA9AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRaYS6cY+9WtX#L$FpdYq8X&q/NGJyhC=mdZChi?>4=Hl/
Njk18< y?^Y9L4dj6G>6TFnhnp<M<b+IIR&CltL&licG1FXk5Lh1>!>&Bhi4=CXnlAN5%RyhPFS&+yKVR99:wuR
w%iRuc Ny=ZihE5R&l!%N/$nai?Q1bR/WDW@k6HTMyPW%je1&\kL!cj=@t1:LK:N:A4q/81*jZw<#!j=?j*Y%L4
1NHMW& V:@aqQlw+*eh9!F?@#>?F!Tb@/:Z@$@HujyZHBE@yCkTL@TDN/>i9eI4@iX4jpljj!%i/Ij?lKhW5T#L
9D*8GN mHF+SqV1q5Z@n1LaW8VIMlP#5QDMl=6+dqIpF<PhuTD4u4jQLj/$a5qSbFq/HC6GlQe^*6IJFV\=VyJ=
ZL!E$D ybpq1aiH6%P$!!RMDk/GabR1Bl+^5EqcnkpP$qa4\q8e\+kV$$\<#+*>yHTVDPD6m$t:HS+eYHGW!kp5
wWeA#W 5&TwTuk+C/ql$F5h=&pB&#Q>&IP<l:MAQQX&hpc:HWYB\9mE$F&QkA=nmcbI$TN\EM8yAX9&p5R!+!RB
\6ydMt A#/MV64u\<CKaqJbXmSbqta@E9+qHqI5^:yF=\hnKX=TbY<9Zq?K9iRkVIpkaDDT%THnJ+4$1KXH84Np
W$/^@\ 4McLilS6ie:1q4MK8VmJh*aQ4K$$5mCyTQ@iwT8!I8PlkEpk/ctTJD9uSK/mT:@bwc!$YuHTVyZIm1Vj
c%@\Ew >JCn%LQPRiN9Lkyp*jN/WSyL9<&lKP9B$iE:4AM+nT\J5cVwlpLPmhlH:AF>^4+mkZbBc&T=QjZwumVh
ZLa4Wh :uW/uW@=\ehR9HR:uh/\&?u%lqt*t&d+TTtt+%=I8NcB%9?yJQZ+p@@T/adheNkLIhE4!?G\q/XqYtbq
H>e<qQ mXTI+>LIa65wDh8!i^Fp%>Jek*K@VPqI\ly6b=kP$\+VIeeAVH+Ry\aF&G*KXTTa>WBTXyMD:YjA:\m1
5JMT#Y l^%w&G%D!&E+uFEwE:n%jj/EDQDTnk*:kTR6yV6H\F&1bZ9DV6kqe+H:+!6jJptbbiK6bWB:D+pqTiqT
\&LC%^ w8b#8JAM8$^PP8eP1$#?Y#uD6a^ZSYHkZ/6JV%Mn/jcuNT:Dp9VPjL#I/R?Taa%4p:VAZW<$Vd4WiekK
NF5GQP h$L\jT$Pq54p9>d1Y$=5w=/qp4KW>QIeQQ>1l696DH6DuPJ/tMyitjFjFMDcaH1Aj!qLB@t<9i\nPL6*
N=QW@b I\C64Fj4VAiAa@nZT=iQX1Vdq:mAHHc/N%SG*KZCZ5W5DdkyNp1<>\+P!h/c1=$R65La#kMl\5Eu:P^h
SKJpBR ?wnXyu:kHZVTK=%FKED6X?J6&jqJLX#dP#6BB1FpL?qA:9a%du4hnumV>8K+@w>$b//$!KZ^m9<Y+wQK
daCY/K y@P!6<Nc6l^i@4peZ8M>Bm/1NH%\/dyQh44mhdjYuam?^4^5R%diP?leSDh\Jc6Vl>MX4uWNX#JA=q:M
W&&/Jd 8DMj#W+4CFKG9e5@t>e>45RW#?CKiH:\Fqp=C!>q+</%Mm^@SV=K\@AtX&C/j8u>Py%qaCu\$WF$1ZPu
j<?D:d >td>\iF=hIM4bSa5!P+>!=9*$T>u8XkLwIL6lGG9q/c#iE=@KV+BuhHYCG6td/h?He:5Sq=b1Hnhdp@E
/!bT1J Fi4Qk^q8qHn6#yYQjquL#8#<jn6<REGc>GyeJcqnE+D!inLQ%W@1kPw>tEX8KwlKc*jJbZuyw!n!innn
Gu&5iI :c?F4F:nDY@p+P$5HX+NXDPiQT><M/:pZ8hG@u+n/%*#4$L&Yld4@QW%YcX#w?bA/?6^hb6\%:%&1F@Y
P55LiH !j1\P>jnVFK!<Hy5wC<A%?969IGLk9ZyhSn\jK*wJn?t%8tF9b5^1cBmZRNY$t=+nV&qbQ>mWEJMjn*@
JS5FY& $bK4=h#b5m#6DijQZ5bp4<W?8wb4%V*+<k>yRyX#n8e$Keqi##^AyMlZ54JA:j:Ly:Zc5nWebtHbYdt!
SJ&4+B wPVKb!&quGn@8ZP>+a8in\/eypNS:weh:96qtuZS@SFhT=kQ\^$QJ@@Jy*S$j6Y=eZT#EB?GDQ?tyiZH
KiJN+E j5#qGj$Iw*D96=y#ayw<D4Lw6=L%@jRkVT>?C%E+N*ZDk#S:<J6Qbn+G?BIV#WYcapTq$W8l+a6GMB1J
H/tBXP qaZ%!<Fay$j>Z@m@%KVbQ<ucYj5k/>Ea:^%kQaEb$+4lHGW4p8+&%Z=?&5^=k9L\KE8ciVD<^$DN5AwI
#W!Eda \SlG?AVCtLE!@tB1SYu$:m&%tb?y@j+JYCqVNlFQGiT\&MEb?NM:ZyEMwd?Z+jSYE1N8a:1>5>DwN>Zn
I89kFQ y%1#B*$8kJtRp#EWJqteahtTlh+pT>wiHZ=CPpM+VSWQ6iydC$&6V<hJT1TR%nlKABI?RM5L\Hq?&^%5
m<wC8Y ajXTI6SIPE4V9RZyn64Wt4q&wuakikGZyC!V?TuYTn+bWi=+TV9JdMM\\ANJKpt/@tn4Y\8Lnid^l<%t
ceVPV4 M@<!VM>lNM&bJSu1+%MM:JXDLHt1!nbpCiKyBc:nQZMhP4?4R9C$?cGchN5HcV9$EImk^ajTRIcn&kub
%9ce>H t^mDkYFI8k/8>4DCBF5Lp1TiNy9:@iNtL\&:8=l$p=TJ#lmbdC@>nHA48+Lcl1#5^Y\\+d=@@Fk>@cTj
JbbW*Q u=^j6L5H9S*IpNIRh8HllFmH8@\BH+bMckM=&qPpi%JD:d?A<MtHtMy*iqq:tLLTJh5KYNK<!AaDAN9F
QEcSIk \NAN&X4*+tR%84h\T&w?Xb?1J<*D*p+9DICdZpByVMXi/XI\IE4\GFRD&/q\Bqk6G=GuyN:CmuS9Z#64
$e!MFl Nw@*#>Lh*YGa6N96qMMyTaCNGBZK&:bNJleAN+ANS$ZT6:=%y>F<@MuJ!jH?TSmGp#Ahip\&TTMYT=KG
kuLjT> +wP164n!&X*!uuJ4RXyeRFRh=@*V$<=F8*N?*n9AZJ=TdFGAIl5kYtR&T:HY9wN*aF^cSL+>d8au#ej:
9>5R+! J\i><*a*9Blt!hDm\CT?M+S%/yG8A*mJa5VG1%qX^5BAIwPw@LS@py?kZQdPD>KLH5e&JJERmEyRQckI
QE@QRK nNRtcKLM1WkQ<?Q>p/dcQP/j:1duF>%PE4cHZ6btaa?i5ZwmF\*+1YKL<hdlW%TF:cTd11yTuV+jumeZ
-A\ai& 0008563aa6100110334 Page 132 of binaries2.zip
AYAIkN IelP&FM?Q&j\LK65W*nbA*1FGVkF*9q?WeXy568=CLEa/ZpqFSuI?IS4I1$GRtXTuaEhIw$jNwFZ^hk%
9S*BFY +iVhk!T<cIjR8k%dihjDH>VKDnk<YH9?m$$i<+8mtlRV6#CXyDPEt/By%&9:mK#TLRiXAZ+Sp?KJ/Ddy
BXhlDe 4e@SSu1My$FS?ccS:Hdd:a5\yV$Y#+@lb$ap=>RGe=RXBK8dWL<wmtA<LtC*a<lJP?^=F#A+kYn!b!XP
^bp4CN DZNBE4&lb:dhL!m9dIK6JpE\>9Gl\qlNk/TZ6H9\dEwSCRGPKy8DW5RtPEbkI#wLP14yNHAuBIEpSZ!q
Abe!$y Cb^5wtyqXRFq!VC8ARWyV:=GZCI^GNkhn/H&BJaWY+db&\pPE6<1*V?L<X<XwVwFA^NqA>mGXId\1tFC
TnTXaQ wBkF+!AAQ9qQN>5lFW$@nn&@tAm6kT#mGk>j%k%hN8kH19w8pCe?iS1LYMjc&RHL6DT8@IDDl/II&96C
HyeKlj A\QC^m4AI@K\Q*ZH9q8R?/wKCh+PIiuE9puceDDZ\eAcwHVyLhuS>?>aFcSeiJnCE/T+lYEA%#JL#\aV
8!aPXA Q1u45:a?=/AQZEp*HFuhqCK#<F%@QHZJZn<IjN?S#S+!$M!k$wVekMmE4uRKE^+CTacnd?&4pcIcBWI!
Zn18eB eMepZI!IdteSVQpJ$Vn^PjI=h!lEBkXyDI9*XW%S%iN5ZIFtCp9jJRN>%>qKmC1#CkKZaMqtBm=R<NBl
ucKXyk bBtJ?>NI%V:$^+EdnCi8C/qmQAwK%%tn#V?mZbmCbB6\IwAw+M16S&18S4jW9=QhKeZXtCTuRaC*w&uL
kj66=$ 5&P8GhDHL$V1PnlBMbBJaR8\t>K??qQqV=+@C/bVyCE^>u\<HW@@%phDmtFtWa!SJ&^9IawASGXVl?!>
#Sk8A4 Y/1/qL:Ay?EM\CIupI@R*\hZqEFFAZ$1FmdF<cSVY>QXZCQa%yQhKWVG488:I^IPmtqB#V<tT>&S/=Qn
4PV?m& /WFP<k%hl<+N>b/pcm94b:6n>@ZWBSdaHkiV!SSRTCKK5Rta=+mltCd8BpkkR&twY4T9@pJ/5k6M?MJ%
yPQ&/^ y?NkC4ySC6#AV?LBAQFY?=%l<VRkqt>y^JT1*qq@5V9%KRXl<un/nNl&y<?uYWLihNpEqm\aHnT9Gw@I
Tt+>kE 8RmM^i?@HE<tE>lL@IIw+CIn^:=HFMH^WIw\C:>!Wd5R^kbI#4WXa8y5%@XJiA4uQH<?Jy*l=uGT\L5k
lZK4cD GcbRSBeXVMEd5K^@nLnapNTt>MHDKhl\ESG9:$?u#+MybhXwZJVWDAcWud=Ly94pB/RRlld+qhJka:H*
/KtuWZ 5w*@Se!V#tCM1\j!EYYP1y6L@1ZmkNe^cEc^eK^eJihGm&jRFa/q@/Pk+BkCt8>SF\E>^anDjALe\QFS
BK1&1V Lnk\:wEy1jh!!yun\$E\PwCVjT1aj5\%qYw*ySI+e/eVS&<lIPWYXAbVi$>&S@k<ySDTB*FAlce8dcLE
GRuHuW eED:WB\pDl!1!+kyDe=hWX=MmW4w/TPiC&REe+1u85&CZ+VHTLnKSPc&DERGXN/Rim@IYJlLS41IZXS+
aZS5n9 AW##AbhGaI/yM4nnqtGa8t:eEp\yb:9QmXtKijJD\QFZ?V^hWMMn=iHl=?D@&hnaYmL*:15dC5S4y5n>
\Qq%*9 BF^\*NimljA9i\?k\dN@YDF%w+ZI+IKlIQ8tL6HD@5hnZQEkIA/8dV:=uK\hd=56e$p&Q!cXt*i?@+JK
&L8Y=l #ckaeYp8SlZeTIIFh^CVyk6TlyIEmm?%6p#DqSVB%JMPa5thEFEX6>BKYF8J\djmQ8EHZD8MydYY5dY&
AV&Dmq wN#T:lFVD%HmRP%a\FI9at9baNHn1i8=XE&M%jie>%49GbRHqAdE%JTDtPK1EyK?CA$iyFAXC?1myLC^
*DCyjY 844&u6u/PKe$8Ce@:KCk*y<mdFlXZ@\KaG/%N8W<tpNqRtWb:ZdFRR:hke4jSF!<9k<CJ*WeCp#@$4@%
=T$IEZ E?SZ=TZDqJ&X>aWN>XBC9Zu+K$4+=>QuWHqWT^b#w5A%1RZ/^T8$LqN8/h5@XFWNbjtienaFB<<ydh&c
SmLdI4 aPHa&q\^n?FNWitI^FXadH#R!NENe8uJ4%=VtBJbE>F=1/6cY8NTPMMK^>EhbK:Xk4Z@HTwnqFHbRJR:
QI??VD GW?E1P@:e<A$JQBa=5maBNDunbYFSpNdicSG*$D&wWlSqL9ecWTZt!p8iPd&JS8@D*MN5@Y#S^5d8YAK
dZmDdY #1ZmmD+@1iPCS:n1My\HNN@LQM++?yL?WYNDk*M%bkwX@H/A@84Y&5=VSW5mG5F+jnN?H!PI@tkn*>DY
@eHyeP d/qkC6ZJ9S?kiZIm%eBMqVmJVdPRSG5m9Nm84t!wnRa#>SB%C8YaK*Ll?:Q$8V1Rj6R6hY4XGE$1/hG!
4lp>q! 61FF6:Vwt@<LVAXV:pLCScL+?<Z5DIDq8aJ$d8t!<p+D^@:mI^Y\XI&u=CWMX8=X96eH^aZBB+a@\u?p
<B#@IV AXY:6/D?+l59hq?V&JmG$Nh%cQn?6eA1EE$<NhIJ>A$ecpQhd>^=TNp*@6!q@PMbhnKn>?wa#FDlY6t/
qnQdc< 1?cNniNwj@M@Wp\F4!tw$DKtQHlZhY^h!lwEK=k!4LMVlJV/Q&/y!e=LGQ4=e$mniWJ&K1y!ecp\Qd$T
wMp!D1 >6IWJ#>=&H/pN4VIMe!#*e@l%>iWRTmD#/hBeXtX=*TttaS$q1JG<?!Lm<b?e>Fa@a8Z$*NpEA4=tH8X
FBTqVy Y&i6PIw4i=F/^5I!K6Sb/Q49c*?HC1A8B1RuqZYcm#CWWR+J:%/h\GBVG@5NhPw8/1!nP5=1T+wP1FaV
dh@ScE IQeCXPZJyYi1YR*k*aGFnb?ynSVK8iP@h>bpa$N>ep/Y$tlBjSt^XX&uYQBM+>9lZjW#Y18kKRYL$9dH
^ShT?V /8?>dAjBCQGMAqtJ\dWwb5LF9H<@cnV!e5kLm9H>dZj%pZw&cqP4y<tJ6jcDTjZtRh5KniY@@HHX=TEm
4RdANt tQ=NT%cj9n^H=$GQy/WaBTK5EWp\A/:6NV//??Raw6VbpiX8/$j1&V?QSmM!aX!IJRKcYF$8m88+H&tu
*T+CPm aRFljAVWd58Q6BhjVpi5/4l8R#T\FhihK<nK9*Q$SVHpRSn5dH61<$pZBe4q8ckTTqjFyeb#<w=^>?u^
$HGTL= 6:%8i<dX^%4#p#<KSpQY6SCb:5>=b$:#khW+jSy:@:n45w5C>*%%W$&4Cek1/wVqPcn!*&J!c@u$%QHe
VEw1JC C=iaHa@@4>e+VG?%pV/%T#pJ:K9!PH@<:<dy9^ytkykmm\6uY>ZY$??NlkVMS4Ltj9E&/dL=q/iG<*NR
Q5$1&w VNEV8Gne?@6@NB%X%P8L&yu?nhw<p@*P/aq5tFa\>c5S?Zi>pZ@T1!b6bym$y6Y6:d>N8Q#P+T<M$$nM
iXV1A4 <YR/e9>leY%F*h^@+W+tNcdQm>8/Ch:$eQQ^Qei\VNPhhtuTph\Q%KhQ1&/dWeqP#EHZbK/EB>4yA>8I
GGe>d/ a*eNtVN&X6hY*%ijQHVQ^ScBCAt^#1#iXLy=8HG:5N$>t49H^u64=5iNF\n\mil:yG>SFhZdn@*<<A<4
NFELht b#>^*V?a:t*9/e//iu^Y@D@lG=E?^YBR*K^$jQ!jVY*j>k/ZHNj>G@i>9jhYY>4bR:<>C\\iC&#@LR4n
adKKD$ ?PyR*diQwmZHRZB6d56dn94m4J#WW!BF=KC/!wRdjWt>8>p+nyb5B/W^Mh<#DjZFm=EISpkP/BT<V@P&
1FkDP% +?:?@6*$Z8V+/Jl81?Y51m>iF5JDHFw$?6tZ%iJ/N@^1@=&:l+1W8hZLWdG>6k*bL>*cR##MCMqjA*^9
PEJ/RG +?:K8tR@/Ran$%q^%dMJyWZq%&^Xe#Z!Jq9@=b&Fh^SJ?iaL1nK/i@@+IVh45dwputd:n&<iSZuu:uIW
j$clw! 4V\heR<a@:#=BhwR4ca4*1jlVdC*8yed?L6*eTSC%Q*=l:!+DQ^/WlhdY:@P+MGhh?<&9p6Lh:T9RQ&C
w=w\b8 ymJc=aq%lbl/*<w#Wj$1F8qGw&i\!e5LVM%m?Wbc#?J1Z9wQ1%qmWmT+I*T6=#>/Sl1QwHhXh<=/5@HG
uBqpa6 eXnNNRt58aN^eQGjcJ*pmtthCnPlFwM*FXc#1==KIGBIIXVcAWAnG>i+qhkF9CH:&X^Ge?DVbkL>QH6G
:q=Hm/ *Z9MDeH&Hhwh9Tt4#6Sqj+k%Fm&kk&e+^&8^nnN$&4eWG=>#S:?jZdFZWFtq%bu@GluF1%LtYVJ5\8W6
Kmw8Vm =jq/w*%QmNZhmuAuE=J/B4=EH/QS\Kdqu*$>RQJe8*IdumpHjQl%VA6c*4nARE=VLm?DdN4it4NZ!&1F
aRJbc/ ^jBFt^Fw?G=\9>:#+B$qDDRF:!Lc%*D##i1!EHJ%e*qQIdlQ%wI4\?HbVda#M4k!41VXjn?je#DQ8R:Y
a&8V:# 5LTZ<a!YykYNjd\w+F%$QB6ZP8jp+p99<5DmtDK$jp%4/YIL$#^6pPyKPcBCP^elc4?yjqpHl*<yLV6d
&=1cta JtYFG&\96ZVhwX*h@Z4FY%$GtK4%tiq/*TM&wjDSJYjh@j^?<Qh4WHid>+PdbTX&yT?>4Dc%$&bYZYaT
yjw=XJ lVV6<//8^Y94#=<=&/$6y>XcM4CG#\1^EB5M/wILZFbc>Gacw$lad/&94Y?64Y%9L&:L4Y*a1??jbBu4
b%d9bS VB+YY16NXhM$wc/apdu>/a1!84=84b8t9G%5Pab$1:u=GY@iD\la?Bp<j^KtNc/aL8lamh=hj*>>i&ud
!BILnF Yh*ihp^Jcnd*5<^tT\&&Gt<?VD8h<$=*lq8I+=WmTa8Lm=/uKNcYJ$8L*%V:J>>nT\&PL5cqd:ZD5F%V
?WCRk> ^R=!WZQF6:jT88M54eXP6ABYH1iZ&<T&wL1#8$6ZVX*YHdEH+t&KC@Am+LdYJCqZt*u#h&5^TmhnIHAl
qVH!c! *KP=lJj$!APcR9N<L+4YybXFKjK&yEecFkTuceubAAjZGhE=:*ZC<^/G>lGVBEuT?$ic64uPZ#?9TNK6
>/Qu6: w\$%:&<8X\PjKcd6MwN^\@NPd=kCM?CFKneD*<5%dZq#ScGL@!T6eZTpcmiHJT>d!XkB9A9lm:DVR>bQ
kcJQq5 A:FDVL6p9y4uKq&LB5LiYhb!XY61n=qk+YKP4E=9B<JJ?<ikmS6JMKdEK@=e$+=RF#aqbWHLn#TWq@=j
pmYncR jVjtNi?k1t5AZ<TRl8FBSc5DcD$i?%S5TnZjPAV&S6R+ZNa$NhjW9</aawyKk\6Z!N?B:TSlSS8Z6IhQ
jE%1Fd i=@knHBl6Ka>Z1bu6hq<@INCyNG5euR/F^hyE9b/YWHDln8qyS^6!u<F5pmIuuQ&:?F*Sc$pk:u!6N6l
8QnQcC iJ:&Tm>DubyCNun?dH\j=jYH?YED!QuSw!NTPY@t&tje@Y8FTVaM5XSI$nVFPkd1nq@VJk\K8+HX?@=S
HT>4C= #5elXEcmS*XW$hi6JB8GP@Rhbb1q6L9J?\K$=l&:=u@RILq=6A!q%j!$4@dXu/LipjRM8Dipd>=VL+$#
yuJJ8K &1\NQ1i9IQC#dZ!R@&\D*mEQcce1kDj9TCSeZXc5pL+>=<5XanAh$Qacd/+mdbe%An%e*5\lmiNW?kmN
BH!9\I TTRk!^:R6@bitecyS%9BW>:u\1T^9dL%KG@A\<5d\KZLC=y1JMt!ae>C81yT?4w@niuTCh:njR=y4AZh
uQ9RYW %bc?9u!pLRNew+B5N96>YbapCN5#+a8L#IN\tmyY^8c/W>1Yh:jRHHI!6bEnuE?l5u1ClJaZbMGZ\GXd
\>Gl4c E:w/w1A6GA4II6lc$%i*QumeH^$iHXFYwJ!iNVeJYGi!8Z6qjPGF=XtKItN>R%>4kY@j&VaN@a<=GKtP
1/QTDu N9p+8!jy?wJp#KI!=W5&$km@Ke$c6I8QNDL%:bbJEdX=hIVIEE!4b+?AK?u&RQR#aNK*#=c*Lm9t!KZ>
lYec5t a5b%Xl\JIZpMlbET5QhaQY81@XTG5F#*BjwT&dIm84\?!tmwattp<N1&yZH8$hHM$jNkMYIL\4yee?W=
-AeJR8 0004c3cf25200110334 Page 133 of binaries2.zip
yil5D< ebyaMi!XVFA%yT?@1N@4c*><qJM\^Q5A=m6Z?u$%wk8elZ>>84:Ae9SWn=RaR^HZHNbc%/nCcj$nEkh5
e9KZ9i *8V4V\+qQaK\\QWeJ+yTGVXSwl&4eXD*BtZ=<Ek>luNP%iQn+:\Q51B%49%Qe4QwuLFHF::V4RCK\pZD
I$%8cl 4?9$D!pYV=6I*YPmPYiX?$%Nlb9q&<!Xb#q<^\FX^APMJ>QCF?9h^=T=c9<WN8IMjjb\@\^FV>8whdae
+VaDD? ##LyPu//Y8k&JqjiDTG?NIypRBI+Fb%n#wetuVCTYhcni\@+DkDqh/RqDN#<qRi6i+/Q8MVq@YN+?BVJ
yKbJ!u V=Gq>kqanXk&Vm$D=5y$adq!G=DVa5LV^=?4uAyI?@+^mlXaA%M1nTiR*tSb\+p58WY\MwRyKCbm*mHq
84mE$> euL9KZ@?FE1V$VAl#iycq$S^HMWINL1GVKIYYm<j*ZV@mGNKQY=TmSXK1?ueEK&Z8tWwcLMLPwmiVbbm
iRuWHh X\?hPE$JWn8qp@SQ588#N$DyBkqJ*IyTmFG+1ni1/W8W\FXQ?#qqljdqnduhTPt?E44mm//?9^4D@j4d
=l\L^> Dnia@BNMQaLiijiGdK!d5S#LjKPEJQuF@BidjId^6CC@k4Znt:J!HPp^wjL>MjdeFC/tcj4!:!6\Da8d
=1&>X? N>e+qw^\qmJhyk9WyG@Qn>d%V5^w/9hyan*>ML5yT#iYYBVMFkuL%h#tmhk%Hp?14@weINWd>8ySm/Pb
<Mkml+ SKZw>9^?AD@VmwQm+9VFVXth:6^BRMy<A=C$INu#c$d?Tl=99$L8cS??kW8**WRi*<u!:eX*yN?bCX@6
mXWPS* ThB=1E=??Ra8*jcC?5X#HMZHRuS6V%&58KwTAjLbt@dCTZT%H\YI>G&FC9?%lZEhK+>X:T&+hBtlLnPw
QJX<XH Dqn<9t%%Z8b9lFXqGc6SlC^TPLD8SDRH!t>dtV@T*9lV4Bl$t+&+/!4mXJV$6\tZS&@<Ta+XuY=#pm!?
wF%jtH iTmTKMJ1L%<@@1y/M!dy<pnKi^FaIB#hK4J@:a:E9M/Y9ESpkVEAYnLjLAS^k:+*YDWM$:DNkmjZN#iT
ilnFik EM\/jEVXm5JDZCANPb&?i#a5\:Bn^@A>$*hLq/+@yI5R+>I&+tI\RI%WFJc$KLdwpQqYJh*k&:&5qtHm
4yqLYm KM!EJPp!!bk9q1S:6!n^1d\1dLBEHSJJyc@K<ybP5LH6PA/EjRDTXcKJVSjtiZd5J\Q\DCAL\cH\hcV+
ei:AHR wT5*DE5&nMmIa#P&dh<H14k+$!#=mi=$R!PDl!!h:>ZCRleYG%BDn&YbFDa6M^++4tt/A><4wLQq8cXq
V8<LLh iTbh9\lyPYKtLC4SetVASZRa5a^qL!%>pcPPH>P%yaqqbu:5P%A<nl*LSlc^W<RQe\&iLCNiMqd%GHKY
?WT+QS aRP*>D*dLbMWmyl+Kp&/?NGMq+CyW=YPI#lFIW^$y%Z+%nHyjn#MFDHWLyLT^Ste&QH^G+NA^<Nu=&<6
XKkA/Z I==%@5cQ9\InZJD5tb:nEcbyPPKGRV:?DXBLA\RWAAIACAD>XY$q\j?ZTlE9AAC&hAAAL\AAAGN5cYX8
NY\jNR hHM9eGh\L*hydnM!L%BHWGFpdYq8L%Jqe!>BbG%ydqhyinlmcZR8at%\#FyNd!NZh1YARG\$Aw5dcbNb
Cu=:45 qwKkTnaw5SHAt5$pm=liyKwZIkhI*I+HTHMCh\eITC&/1kG#CNA&\J+^8GKHAFpCT5WGI^L$GBC!+I4b
:!9W@B EBtn:CnK\QM*<k?ae?>>4%lFjVm#TCQ9%RhbJP9ee?:Hi/?p9@#4j#*Nej9#Q<4q@k#uF>n@G@6Y:kFj
9DCY@V >@<y6&=dc8hY\q:D*5eia%@JySIPJX\9+ZwJ%$54?XwN%&6+WeQ%G1:ZX9LVQ1:*ed&QN*%e:/@phnG8
LZd<iV ^:ki+*1MC@GKIZI4ZF@l?k4ZX:m?Ykp5>^4&Q9aa?$yM\cEEi$1\y\S:T4CH#aM>JhlVkn$q&FPCQY\!
c6KFec :CuBulL5KeGiE8^lG4CuBH6K5KeEi$1\l/mXaE<J>ySkV\u&qGAQ$&X41Qi^^>lZIkH51eGAG5B18HEN
CmaXpm N&Fb<GENL&1\y\b:c4CHyaI>NhlVk#$%&FPDQT\j:KuBul451eGiG8\lTY8\y\b:c4CuBu615IhqbtZI
*X@4IL G8w^>yXID*9/5KeQi@1\y\>:&B&\y\>:?nCmD<A?d5+8\w@/?EIjd@1\y\>:&G&\y\>:?4CuD*9/5Ihe
%&/:BT &ae>jhnVl#%>&NPHQi^i>qKNLat=4<Vq5CiGQVH5mYFQDH5+DGBQDH6m&BQDuln&eGnAuln&^LAulmE^
kZ@hG# RDqeeLMaQ+#^ySkZa6lDISVDuln&^LAuln$^:PG\+wklL=E!bM%KRk*&4GDQC9c5aM<K>uD+\b+X:FuB
%w&P=/ ulZ5YeEiDpua5+I>K>m#kn$4&MNlCu6Y5GeFi%c\b\XnXlVTAFullm9<iIW948nm@@NYiX#^uC1/=#T1
&B:=n> V5N^HBihY5NJN#6:eQmLL>DhS4&Bu#Secd/et8m?&@TcR=#Q@TH&</kbuWeS>w9w@MKyTG?w5@Mn#bdh
5cYmQ$ =p:G%jHV8q6*p/aAQbiP&IHcnKR#huSB!PBLHaR4n?@C5unVL=QZn5A*:EaDjE<cd1ayiF>P#aB\#@&I
4qLQeX KX>E+A6RhWmV$yLcq1bwE1L61QhY=p6P*YqWGm<1G>kdBnS>Aw@?lZG4yC=kH%ieNbh>jdLR>!*Vw8d\
tyCA*I &ZT\:%5\\&J\W^RZ&ZE4c1=VeZHWuVa^\TNw^dj1QCcNBjbD*NA!eHM?Yy6HuQj%P#4knW*>R^P+quI/
yewDm9 k?8+1TlVyAHcS+kJZ+i>T/l<d::>dV%uGZqDh8wt:Y\GD9c?dRIeN5Bp%8LR6p/ewuQC^+4N5GRCpEZu
bb^hh< mwYhWc*>?&D9:ICXVaPKC*S*D5GM@aIVAWQ1m\8P+m49X5:<9/5VS6=$D1GC\<AZEclcDQ5&mySnKedS
a6ka9H BYlT8dLiVuY$+AAA?@:F+\P4TlLu*la\MacHH#=<:>$DJdJlYTySbiiVa/u6D&&tbB9hhJ<TZ+$HmK=K
K&5//9 $:<wFB+?jMV#R<Q#41/t6KZ/bDy=M*$#GW*SJ#lVp!P*mQ1b:EF$Fw\CNI<&:tl8+Ltu46j\SyQHCymE
@6!l/F n9aKi+XHAl8>8byeVd=F@?$$hZ8/>/mF?/J:w<DHDTP<n8m?jH9Z<%=:\%QeH1PT%*AdcpP4w*VZeZ!P
:yP9W9 *d5/$4m8@<ZD\1MC9*im/cn11X=%#$cyJw^ckZ<YihHbKQJWSBkGSpNGSn<hkyZZwJJbh8\Q:j&Gl5dI
HeRYcj WZii&/en>nBT/Y>>?QjlR:/HN:4!W8utb5S5BYBMY9yuI>@b!M\GwMGa1WcyCLW%LQd/Q>d4<1HFPu>S
+%LN/q iE>\DjjNXT1HDY?WdeB5ST?l8HNLVYkR+*>&AS/peM6CtMbJDFhk:NF9ViCCd\GN9>8adQB>p&H<WwLH
m49a*8 8#$>:FNCQ9X8<tY&$Jpai@VlQyW5<NY+:uTV:!VL?PZwVql\e#*+%^&iyZChS1wS++V9S<V*WWH4:Kh^
Ja4YR1 J^5!W:?utBy8kIA?nVI/1:kGYa41D+PWj^<YHm1h4/di9Z^Hh:NXnKF%eBhjktih^d<Z1FeQ6e=y*ABq
R/$+@\ IwPMpL1@tndI\/MN@:4c^<TahTc?XjBXiYTAd!9Nh$1wGe1dKy5*w6wdSlt?dwc9HcV+Qu19eC6jqd>?
mmC%mB Cue:W?BS?cc6jIa\W9n5qn^KKAe/un@!9=lPYn?Z89H6%L<qZA#Hm&:^4lNRkq>hYhuR<mL46u8wnE4<
KQ4GcE m:mcnL/eTn^Q4%:iEcyTR/\NYJ<uKStlQjj5nlkk=L1Kb+9+VqwV8TMGI@?8HGq5+mJ\d+u8BpaM/<=:
mG$MYq kG?FZl#!\A@e!a@\Xh=PP#iId551SQVhMR>9B\jM%^GhJ/$j++5jwa^pbKd^+cca>@Aq1TQ^:!H^HZ$=
15IhjC T9m&:puPWT8Dm*T?1a+#9Ie9=SuHe>FluRG5?h/Dc=>qeGpW95uZcRV*%Sa:PM4\Fb&Di@pc\TV#d6T/
1wAVhc ^d@R?V:e<5lK@A8?LhHb!?D8a#:%JBNbd:IBHw%8Ypubqc=ZtB/qc=\SPV^=SPFwJ9/F#n?pQGcCjwb@
pk+YiT a&ytJB9BMM^BYymLuQtah*u?T>@d\B%/pe!yNC:H5\t?Z1K#pjY9EhBpM5M*w&AnWtPFk^mG4<<\KVn#
8?6ICI wm\8ymBB?y+nGZ<6t5lP@IV9:@$M*?qXPuY<*:c!\euVVII^MLZD:JL/Bq@MZ+PW$Cb@8I>%W5X4\4$/
$4^>^m 46I/E>@$QVAQtG=EmiN=XTPypIFMt4M/w&AdcZ<ujF$1YJHTPe$ZT/nMBM+KStqZ*a^*E>B?pME%DC9n
WnP1:Y G$jmtj^d<Tp&6M+9:%uJaXI@9Z@ya+K8j>6$M!u1<mEqp88Q9ln=wuPY:$dDMtN$hj>cqWcF??1X%hB<
c>Dt!V D\uZ%:nV*>>hN%Aa5WK/8t?m+>ARFa\P:=pHMT+>QCH@nu#q*^@?<$=enMBaNa&8y9i\CVmm:?d4iKK#
:XY:&H >1@9J@/>E^hLNqwM94pdtNmCd#R/8NQ$wim<#j=6?yHEe!:++T=e4BSH$@>k=K9yS:iG%GMMnD:&aGLh
&cVpB5 Jah:&6D=m##!AN9mMD8>m/?Dce:XXCF@i\6qk&5YL%Sd6?65XLAKX9+%LX5iJ9pS^/p>8kWZ6alRJ%Q5
/&G!b5 APZk\u\*M>XCHKN$wXK?lIN9^yXlPVTnD@A%H5E5B#J#ZLWED^QwyE&td/bVLwRn9jJZm*@MV\l/%Hyb
%tt5&C 4V!8uHyBqF:KWNl:H1@$A:XJIeQcjMnV!X!FbZan*+@W=MRJ$w<aJ6N9/euCG%w&9Lt^bJEbjiCLZ>XV
dIY#$c BjWAkNe46BS9pLl/<8=/?#tFT+?yAa8IVl=8GXdP*DJ#?>5GnqdP&Dc\LDD?kL+?dY:T1kL4pu?Xl>@K
Bk9!4F e!V%cNaD18h:d\9apYjCZ6PNQGH59+XHb>5iQa*&=P<RCA9\>ZCw@t?jmPX=!%:ajGb&<#Hckdh?B8?=
KZY!jC kEZcEdRj8SE=@N^4+8^FVhnmi@lG%jW1Z6Y6$q/6XC8Y6bZj!n@aW?&a6!j$Zb>?kbTB/@nSE9W1H\pK
HapAFN L+W5HTK9Tj:%#n*/C+V9u968p^@H$+<>ABItPl&Ame*:1Ky^n#W5?95?^\4>DD?ti^E+9>J+/eckEZ<J
@$QL9Q ^!EkA>uyl>mckAVXC4kCqJ?yXc\<eLei4NpK<MRuVAbuw?piu1Jh<hc$^d>D?kJB!q>e#8qQVq:VFjdE
*DuBLK X\RG5tKMF$hEYDM?%9$JiadVk@XtaI@@p5TAFaW18?eQtT=$HwIt$J9D4t$:<mE>&K!/DE9kkCZ$/mHl
9@Gd4d d8X*lLD8:#?bSE!b$5MVA+S6M<8XhV+u5+dpBtaI61?:*ihqNEK9AFI\CXLm/wCEb5L9yFDSn!MmmlGP
eH&+C1 m!DD<y:EtC6H>RIXG@y/wDy5DpG*%=%*8?Y!\S8lM%YkA>plwT6XSQSc/YQbmDGGGc+GWlIWa/H5bkpD
mAp&5& EI\DFZu$=$T*%?%iAyw=G+S6C&lFMBHR*qGikdji$W!^$iHJSRVpqwINjHcleuGK1t#WTiq#N\Bd8Lh*
8Lk\cL &d5Ehw?SGh^lXNKbG9mK$QpHP+!+>:Qn+=?\Ac&L%kZwctTSYl!M9ipquEqiMHd=Iw5^BN68q<XtS^8M
>G:G^N :XR<hm/BXk/yhDC!EFb<eWJw$TRkYnPY5Gd$FFM/$qkbNHF!RbueC/HuAL<p+l4cKN6CG5Q&wcMJI/cQ
Ie/Td! E=F=B@AFP#qlHCtq@VYt/:1yTG5GjIEWF5aEP?@PIVkyd6l\NGN:H@qHEqn=@AGB@Y#9tJZG1&MjnC?m
VD!$c# TiV44qJKcln@eXJa\:NEtW+I1/HLAyPLBddZqiQ#==w$%&lB#i>D/iQnqNAwY\AXyhjISDkdZh/cMT96
-A%S9t 000572b63e800110334 Page 134 of binaries2.zip
X9n?k1 >mmYCXID#8Z>Je#yCY<LR$M?u!K<y#D=DKXdF%E$+c/<4AmL+MTcaaii8Bp^^XuWW$mMj1u^6TZM*N:Q
YStF9E T:Q!JWXZi@pJ1V#SwBybF%+X&=y#wNN/tBAWB%?1>*#W4<k&wNNjR@QYP&6a&b>M$KI9+ibSJLD455ua
+tJnSI #XThb1%BZHG:%KAy4SZj6jb#R1?Zn$49H/@4B\/Vm=cT?YKW1q$$<8nAV6ZPIWh#qqyK/<6E?dV&<kpP
qFeA#q >Wc%YuyjiLet#JlTPW4HF+aMX*e*t$:DJKSTwG9wG/aRQq:BlutQDPk%uMyBFaE%mZRjJa#=u^6WN1e!
u*5\mE tNy4qV\d*DK5%*GH?5L9CbaWA8=<Qq<5Q@85dtPNC>RL=QJF\6mn$Hbyc/:HCQd^yc+Ycd?8A!*SZu<H
QqC&jG d=uuuM++AZi=YHT\D*w&DcVAHGt65aE!#/\a5bE\j6*4Mw98JuRT%=ib%JaQ/5!=N&eD=59^epdAm@tm
u*NywZ X/ac=>I@VtnPQQ9!t#1kG<KajuubE*cd+6+k#Ld$/N=%aLLKPC@C/%pub6\=6l+Q+X/puS\%Pb&cRym\
#Y*bpw V%XWpZRKjmPu=8uW=1@P/#^w&M<y4Dm&TPe\:w#n=bIa\>*$HTn8y=BBY:8YCd?tH*K5CD/BbESQaw1n
/J>PZH 1F8ZGaqSN58MTdAAm&e#IC<Za+chC?t!4c5%qQdQlY=D\Pp4k==K!RS?u9E%&<Iy<>!t&=t+I=%:Gut^
ZZLIBV CMj^8BQH+>p!%Mn#P5um4key^bV@YQ$cu+el@=!=J4ub=ZAVkRtaaJ@#1G\#ZaDdbjb84\i?m*k=uuW/
khPd:< AF+\Ll>/hSyIZeXaBdSRJtQdA+HXATd\Za+dqpD=\YCcNw@K%DFE%5umAYAZm?W!:5#a\?qG*>h1/%mG
@>J6Qm #k$E+*\b56Z#6aiqHmnpu6+WVh!ymJhpktZWi\9l8%mPZ=GDF#1$En@nt^Yqe<K+%^&EWEkIm=1dlBXd
^ZQ^mY tFRY6=4qwtunlZY$6&?YG:&i<F$5b\k8BT6cE/WF^*c=!Z!X!C:w#kjL#qnHl*c8\Ci?=kw%j<=p!c&w
H++%PQ TtZ:cGjQ&nKQDH9SE%k\F5ICnD=GQeG=S?Ik9yKBweGFLw\ZMFtE:1y\yliJFY\EE5lW@m&dJ?dS:8:8
AZV@dZ 8#t#6L6n&D%GbRh*btQGZVDh=R^&TD1d^a4EM&>eB$J<XiyPX?yiX>X<:Y\c<5mhEqIkdB+Xhuh&H?Yk
y=wCdT >P:8w=@/@\a=AR8?ZDwatNya@I*&YhE?5dX:ZYa%CBGFk:qIVjHW%REtZ1YC\ZM5D8A!K\#WuaJlYwSi
:q5n=e <M<ZKFXn+Ma#BWT8DbiL>nZEZ+=Jn4bhLCyW!M^w+ZkYlwNRFRGq4KI8A&#Q5Dq*cD5<&mu5qub&n\>!
buGS4$ F4Vi5\#:SVlD*5a^hG:HC>*mGh:HMCYGBVnb6p+n4wEM*B=@Nk+HWkSpQGhwIh!d1:YL!SQLHZDFh5DP
#h\RBP *Z6*&/#a9@mHX=%c=%X<@T4Y8Kkm5&Yu>81/M*5FFiJZm$Xhb%FQ?C+Gk:A>D5eDNd4wG4It#NuKWaXV
yNqhaL kXDlZBPph$8=p<PQQ@ntc%VuGPYK/+cmm!1CKP8RB@AS:Jp4tbYGlA#e\cKu:FClVZE%F?y%yt6#Eqp:
wpZHt^ yDJkD/A!V5Znb=@?nnRGDw>IT=XWGJFJj4khmew!1C#1K1ABEi/Ek*qCPEGZVKcKRa!=SB*5kG@BI8j8
IdS&a! FQJt<euVV*<%m!twc6@STaE8^*F<QcckYqJBaYPG!49CJl\AiAuCk%/c:hwCknYF5GWhpHMLB>5YuH8<
dJ!F>1 d=qHV:@/@t8KbiIZ<^tRaDt?ntPq?uLG4Me<jY%RLRDYIk#dIi<LL4Y>G?mWRWJ+b/hAdHhKijMh^NTD
a6nmhF :YLq/dQjjAeAapn?JGw$Q5DdNbtBKGCKdMdq*P%SAuZG+@c!FlLjDdc<#Y*^dLq<BFD+h8eS!mPF%qc^
V!DQn/ ?HiAbb>!w5LDZ*ja$#HmGP=Y$S&HM:KJq$R1S<dEhQq=8^$8^ME<5A*\c1AT1/=HQtRR5*&WN!!J/PJQ
npVQu? Q@nt?&YCi>%=Nc6hn#9Z5%<m4iJaX&8GSl4LpwmVbVEIQ\<HC&ADC@MPRq/I##@DKIX*ClSHak99:1Fk
@dB5K@ IIPP6@LF$4NQj<Wme#CB*ul<Zi9W4tjZ5^4NA&KytF!yWWuh^qCNe#lTXA*GTKMBE$du9AwHde+5un5c
E%eISD ppDC>>%6A!49HY\ZEXP@i\X^E#e!==mmcMcy9E#GJlJ<#nq$1c6Xd!D=C\N/VJpMYcCPlMTZJpp!9Tkj
eKVt?y FZdWcMC\?ePu#*:*ZY&YSI?ce>AkSD/P>dSYp=/:4y/CT@!A<^n?Jcq^IA9CNqw+1Njb8/bE5+tKRbq:
BQJ8GM THX1!/^RVMZyE1W!S9J*F15BeV*=pB^Tp*KTE4:<lAkm6qA\&#m&a=KiIE$h#XTy&LqWy:dMp+<@?DXm
@1I^MF mmh!/+cc1M9#euQGM*iVTduKFIRZlwbPt@km4bBcIA8%dbt?<hE/IJZl*NL8L81WYj1L4*/n/wRc?Flu
IZh4^p FeCaiimbbY11qX/AMGEwC&uBN<ValL\cn<Mq/My\\L6BI5P=?=lw\Lutp/h@>i64Bc4dQBu\pVd$YSb&
@CPAkS 9q=^#hWpa>FnwkBhRuHWpW@GL*kTbR51XEapR%:nWPa*S+myX=%pGJn4PacGbyuuG*\#K!+JLmned6jc
CI9?:G 6ZEaI/I?@/R>QkG8=w9nWe1=PjMRMjXjtbmTtJ$u\M6^F9X!jnqjL:5p4lDQGH*laiIcnt8j#H:S^9VA
1^Qn!c 6Lp^a$ye+5pF\/l<@QTd:&NW*CTHW4B<SIBqRMY@iqGyJ1w$++DEeC!FhS5iHuj?lmbmSRI*CjtIXN:i
YiMG96 Q@1V*b@</dd><dP9CDbibuZYwD!XVPli/5Nq<m!n1=i\FFik9G\nneLRQuq^<5hAQVGBne&$TGd\6Cmt
PSMVVF e8dQu*:K5HETX@Q%uDqbHG*R9YV@1qYiYwwAi$CXEnGNGTt$NW?K#QdEBQmD9JZj&Vq?RLBWMK1I1c@H
e:+IH9 BM9A5&X/nZA4/1XAy^+J1pWJ#Ya^LwV6bV85A:hI5N#\BtMjl91nuQWPuJ5#H#>>>9%*NFP<u6H+VyPd
Wp$kBe 6M:#Y:m1F/q%@HwYlYJMXVIMKb!K$w5tSLb=PCnqMS45H8j*#cjQJ9?P8w>By+QmLIQh8l\8dpG>VQ!4
=CZ%L% 5pm9lRRdA%Ghc=VJ$aS&Ru\6ttMea<#h\&R=S:A$=M=16X>&ZtHB&:qbD&?k/p^Kuy9wmb8i$HF^+uWZ
8IqD<D 6cJb6M\HNMewHHAKqZLG**@\%jj@$>j%@LcSHYqyDImmhtJ&D8Jq8Vh!J?kYNcJIi!^1kJEt\I4cBby&
\K%h5& qyT#>6mSN=aMYNyL$\hKC*mpkI+HhAI\q&aPqA?$BZDGC*wChC/6T*5P6A?MF?DM@n>dZ:**?khJS>&m
V@JcD$ JXu&^/?1Z4%/XjXi9$WWN*4RSP#!VA\qh/yBSc#b=!9VF4d6B/^y+cHI4pyMicWTb!F4iW#%CXL8uaPH
*bWG^i *@<I&Pc#L$iIw8kVc!>9C1kVSS%#qD#@C!&Z=Q!nK<LtTnci!A4qp1^u$15HB>>>*<V<&8<DpwQ%*uCc
i=6q:j wJ*^RTV=8y#AEPPZLhymaMt+^Q4XSa^SnJF@yNZ8VQXk/*>@Gk4Ab@*?c^DHk5!d16+RaZtFp11KMK$$
F$PCmS LX9pRhL\!&SQ1NupThCI+!m5YwXN@jF:I6kEV+yV^d#ky<8t&uIa6lZKdE8HhenSDIJHZc4a!McZ+kt/
+p1NB/ YLpJnN@:=B+^epanEm>Fn9&\9@1kLV8?=\nqZT&SpE1L:E!JyK$I^?N^LR//?bp=W8=mb8dP\RGbMqF>
H@W?8N RLy6Q5DkHadh=FSdXtRFZ&c5mtM<9+wepe:^I@mCc^b<C*MG$T%t=kR5Iy9t@9/Z#hGD@Ta:4Kq<w/wN
@Bl9Cl >A8V6tTiSK#qbSLl$P:Rq@yTI5=CJ8Z1eM:GuEG\eBlEenVc::?GKa?\IJuCN/LcpH+FdLwW4KhNlY&T
Eb#F&k hSp^I^:Q$kCKp<PI#bFqpZIQD9:!95<nh$TitYbiAl$%t*KJPZZ$SpA^:!6aZq5K?LTMcPnQHYqRhPZ#
l#M5D+ e*M$K/#N\cb?RnKBSm=\cVLkAV^1DmeN!+t1%qE@WbpT?TFCSyq+yMA^uqlk44BqHZ/!1Kj9H@#^@a<<
idXc*p k5mTZ@QMP?#Tc:@@nNMtW!*cGbM##JtXK6ZLmh%D<>ATm$%aMX*=SL!a9@\X*Id?&/&H@$jL#Ye$k5mR
5NN\Ea >>XCq<YPlYe@HD5/\b#4nF$6T&b!qZaBK=#XKtE!*WT<5Hqby#ply*?&hjCH%^SN$eVZyQWqCXe51YZ1
d#*Ftu mLB:A*j/dD?GK/9c9ubLX5p/6K^T:tB#p?pT6La=4%>P4K=&d^>5jj>5SPa:w5u9RSM?p1^J4Ei\5EXY
18+c1& e8BN&qNE8*l^ZJWwKRWLkqJc#/^8E8/LHjLJlF#M#@HpWDpk65$HNF+Sai!QYLb1Gda@HIdT?=NP!kuJ
&e5+bh uY/SnPLELnNPy>NGdCtSINmN:tAJe&=!I!am&c*N*+>in@=Aw^YRjX:8!jl%MJ^I@adtu\p=B&X<=t\5
Q9jF4F ^etKEFb5d6$@/hE!TTiH9GtI1GQ654E!GQ=EJDF/l6EXIMt=J<d9FPW/a&MJ?n&WtZyCndMXIVJQQn*4
RV%nwV IJRh%M*EYpXM\iTye4t9*9>N=GS+ASkE/$l1NL1>kK<#CS1/cSn^jEC5M*F<RJ<*n>4$#\iNAYL*Cpi\
T%wDYF CCduL%??h9@>?/Fc&j1=V:u\yFWG<kqV/V1S>$H/dS&Y8IS8bSc!kM$?P48RC\\dWZT#y!PaZDGS\nq+
Ra6q@p ?J+tlN=AGZB@%QMZul/6G:6MiN4kHS?@nwQ^TqLiB6u<qeLF&eWQ6wn*P%kL:?=VBE&\mDj&D6+T4Ke5
L5A**& 1hedhJWyIiNFajik&jMmSnWJK+iS\*^LJWLN4q@=D@8m@j#Mqk5NLL/H9e<SQmN$Q6n/:t>9*::%kn^4
G9n/MD %%>9I9ZVwbC@F#a5b=yuFt\h>@CRQEWyjmpi*:#!G>5>I<K&YFB=Hm@Ch:E!kwWjHHl9*:+b9QE#Wj:A
ny/:H= <YV$&:Gqjy$Q?KqA9$/L^H^IW5=8j4y?$#%:$@/B<^^ASp/+P>^h$cHe+5HBjeL%*kcY%B&wNatj9^%#
VCcScq XqGckZJb$KVkLNliYV@!#5=?iE+!p%tCAVKH8!8XXZIit*e*:u6AjSQNJ\m!j5J/jFHmVFY!I$aTcdi\
bVcRAK @8q/*u#<<6*#h%*p45ST9a8q@%Z+n5V>8&6jHHtDN&@j9QFZ%%LGjqJG+W+BnZlJ=p5VeBq$Q!&Y#e4J
PqMc/q 8?e9i$lAC>PlIhtkER^Zeue6@%YXj9TGPL6iCNbQXVQ$&JR\Ve9!JtCDJ44q>jY!bi=<@iL%E:Iuqa#y
DiH^:p D4yDuiSM<ed1#6K%E?<6E*d>>ZXI6\I:JGbutw>$FDaFHW9^+91X9a&TbhX#6=<<E\=Q&HMHm@+XLD>#
i*X5P? P/6*%n\GD8m/d1Bd4pBMiw&I1Q%l^Nj%^Pdiqc&CYdLM&:i4Z@edViEhpH:9*aJ:S4mi*%qdi!F\*eCp
=*9VkY ZN59QpnDmkSXWTi6RCZ$>jnt?yY6JiJd511%w+yI#:#^BpS+WMGCQ\hJ*<uj?c%H5P<Cp@I4ADL6SyFm
>ht!:R JKmcll#IwJdaZC<WPhT\!4XK4W=VHV\V?eF8ZWiTRaip:/\XMbS?iP89Nt$*bFKmbn9htEJ<FX8/&@HN
//98X+ \uI^VjHewXt#nt1XT8NH\1Yy4pHc4Z!5X!yEiK%+>?=D#*9u<\&1VI/6EtC69#eXlY?iqBL4^iZmZMp6
X!L&BG Eh%!:hd6!1*H=IwHw*/nk4W?#R5\4d6:/%6u*46*$y+:a%WtYYELI+:Qj4+^C@&/<jXC94A$+:1YXc6Z
-Ap>nJ 000b007614700110334 Page 135 of binaries2.zip
#5p/mW 16Z/4Z1hw6Xl:^cuNmytlX*q=t<I>?X#kS6KT5n/yYA>98b$J<b6MJc8F\wcnhA!kK@ue+Sc8ZY4Mj!&
y:HDja eyXMK5jJHBL$?6+teH?AQ+9wNcm=aFEdWY<EP@wG<PPFRl/8wiX/lT84i4%8XRn+*6Y9H%@NZj8bTF+q
CJRZey E^8di%9i&d5#V:1tn4Jl%dDCTaw^e^=#XBF^8<:TMuAV6h1ulX@QGbY/ShiV%:h9*d4&FXJICHRTm=6:
F=!?Ch t\<Jq&hc&:eyXX*!8\KtLwtmdH*Z<ch+Qn?jZ%&K@*5^4<>Y!ybqQiu@&H><hEK/@SmbWXL\^6:YN>=L
JwHjAR YX#1?CJ&=Ke4p^ZVky!RSaZjkP9?</ZX@Py1QQ/4P/8/pi=aHa4dB6<PG&c>AwM&X<D*aP9FtciKT/Hb
NV>4TS V$KKNkDHhciEXd/uCw5dj^>jYy%jnX@K=tQGuG=\$ZKQS4BZ4*CA6cK9WeT^l!qDqydWdCAcEGR!mH8l
N$mWQj wuKiGEKS8eH>$@#</9#<J@GquB:LGit!jdL*qNhdFl#qZPW^A1!Z1HHaZE<Vme#AXRW6Sc+:hhKNPk:H
du#4SX @=X@@YniYLy$ceuIGVHhtCpiuI1F#/Bn/yXd8$<TG^VwwLAp!&q1yk?JYmq+tmFQ<%eC?@yH5hmqT%pA
y=Jk*n #<%t>>:Ii5^kYH@e/H%?LZH\L/meAd4dybnE5\P9$SICh/jdXbmmE>c$@LZ6YM#+/NKq?Eej#X</>qTL
Mk=<?Z D>d#nh$9<<tHnTiwqTK/*i$>Hm9G!$/:q9DRW%d+$\Tkjt6:Nld:/BNC@pTE$J:ZS#aB%e%4&pMK%H8a
T:Fy!* GV&8=Ttnh1XbmX\&c*kmjiNEApu/dIiGE*/:Nt5Raq9t4duc%i@%?<QGp<S@DmmwHZRB!!W6Lk#:ZpN$
tj<WW% 6AkNn!$Dy#HP6/KEZV9IPBE\h+&B<Y:mZtMI&C=YRRQGDXy==KhnB^1imPXC81XQ:Z4at+ZTZAKa%mKp
m+@^ak *8dwh9bJw!hlSjt8!V$IuWC:ER*dpSqlVLhkt6S1@pmcSJct%e96DGpqDFm/KdLF%i%/DRT<wjK@+:h5
E$j%S* eb?+H!!Q/Sb*Myt*I^HQPDJ\9$cCCIEqkH8NB@j&G\%IHTLw?KnYwY%L64b5%R+Nw#FdVlJ\BHXM$K/w
h6Ra8h !CNJ%YG/QXw9edtTKP?mAWHSSVi&:M@!&%mu/^b*/y?Tm#6PKQReR&bJh+hN+Hc>*t/QS6S85\jc9eck
AFa5!H IeaTdyHw5**LW1XP%^un1?Te%Bddaj%PWjEA1haBctkE*Nm@6>9554dSB8DJNlcb8#=WDZt!LDW&iu$*
^Vy$^\ 1j&<wCZ!IWFH=T^LjcJDwePq/Q*G=*Aj/DLymCtS!!By%WAVI5#>q1&w5PYN<&T$?I$Qc>k9Y<6XPK&H
ZMVppM t@e\yDwDVBD5PT^bGia&C^QD1T$M!?e<EXly!WJTT&m%5RyQ%LII&cI+AQMRYukcu/PhBm$QcGdyeJ?D
EDkqdS KVLJLG:Ldd?SlHpHS15%JtSl#@SSTITGpi6Pt4Vd5jDBdXKDB5Hic#RE+$:HK1qc8E1bY^h6Pamhq6yq
#k>it$ M#aLAqZDaA1y%=uRL*JKywZKe=%GW&?APnm1\:&G%/&I1w8wDVDl>PyFY>w#X=bdenCHd:EyL1pXc?=$
t84yTm \@LL!JdF6VQhQHyBh4ZdwBEF^+F?Wd$p$wm!l>Rw6m>pw:#eZRN5y#Wtb/$I^qy+IEZymySCB*XC8m8X
dli%p@ T9Z^p@%jN5l>>G>^aF*me1$88qqtb>cKb?%&cHNLT#B8lWZNRkb!<ib$8u=LnYj^j%@JXc1X*Myu6*@b
8ylKJ9 jNB+nD!iTCITL11u/StmY*#W9yDX9^bZVqnS?Cdpu<tkeilZMtp:$!aG9^*C:bD=/C9X1>YXctZqM:D?
kyu?8l nFPZLGuCl++#?1!S?1K+I?V5%=bd\R+EZ</ckNY$\nljL\JNW^+KlabPlAtdZqh!%WwbDRhe@iein=tb
W8dK%Y !/tN6b5*&?$LWR>4BTdhp64&=c#S59d8uV6*uu>A9/L:lBaIql:nDWA48b>h4hKKGHib4l^cD$nG5?ua
J=@L:l Ytw^XT#iqHKY=YWGXi*1\4!K*>\>Qj&GN=Te9\ydXqC&XkuInt%TSE<lLwF@HIPcmY+=b%cle5l/Xw?S
IjmSX? &ncTZ>#MC:/6q4SpBlYM=Wn?H!Dm=jVX?hPZa!IP$iZ&R4HuXq^#Mb$kchpE8qWp^YjT<&R4m<uWY1H\
&8IBd1 !Gq#/PFIT&/FGLNyMTalA@d<9C$Ii\G&Rkb5=&bmCZ6:mVH9iEJ$4%jNcyt5VJ>L^?Ic:>^M4lY#n<C*
R@?=hK Jc1i#FI^hmSj+D+>l=Tjuy??pwSXVTVwbiL5568lPTTj#au%BAQHeCkj!X8QyijnlaXCRq6LLlcLN&:A
X@Cye& a:GCHdZ6yMWd=t#yMF<J&QNZy!@yQu$8eH6?ukmSLPN&$NF+SFNIamG^qM8B<J!EunNI6jQLC@GFBL$^
9jn!cw PN*5e989dWtaIS$B&lLVI8VMtIL8!>Q#E!Fl%b4Pp#/?EZShL/<X6MLCe4^\Pbe#jC5#btJ^Rq%aJ5KF
9c@Edi Sc&+>1658!&&J#pMK*i<PC*jV:<TlEuEDH9?p5W:/Q8XpmE/ZMX1DB?CMF%c@uJP&ql5bn/:pCXWWnAI
D?1X$k L^c!!*@?$+Y6CA6I@6N8Tb>FwE>j+lAhkn&l?>\YWiSR+cJ/kXCn\@G!h+RD+JaZqnXA=PebiHb?kV>I
GTH8@S \jTZm+XpMj69%!@c<I:5KY$=Phm?YbGewh!u4F5e%WC5ZdEIDAknmEW*&GNtuYi?eT%LEQTSIGnCA>?5
68VJK* S9yN\Qe6@91VG\=QlaKnI%&H&G$m?J=?B@GK*dM+BPV+nP^1mQ4%RP\HIL:jDnDuDd1<<lX<ej=ek4Ty
KWatGa LY5ETd1qH!^A?<p<Vc*=Z>#+c%651yZPWY*BdMtR=>Z=/jq*wHpK#JNVi5EP5cEItXE!GiFN>J8NZW#$
dkMmBl Zhl$HITZE+TwRhER<dKYJXV\B>%p+eaudc\LR&NaMqaS=9u9ecLMPZbHH@Qt:PPVM!FyWXBGm<cDb4M=
@MtPH4 cnd8NVt&1eeZC5!ZyJ4XAJlq^9R8<wnYFmtRYF9?SW%+==ae\:dVpn5Byd@mE&Xiuy#KdhF$:amt8D:Y
Y:R>:K u&nS&H<&R9MA>@ySkGGcaBpuhT=D8HFlW@Si<p^ZiK#qdLypK&R=H>qC^bI9e#$=D5GTlpXh6W<!H9bH
*TLP&9 /DZC$l9^%JNGuV\^SmyAaX*$Xb!8BH^GAqVyVmZ#u%A<ddZWuCSt+LC@kpEFt<B^LMF^>Xm&QYLh?&\j
#ehB6Q +KJ:nkP=FZRtLeBN^BqeET=kkDHbFD^YjCdD!HbkXC%@>NLL?at@/j*+bIj=:l\j\WWQMbbR%@a:B!mW
9Q+$A5 dF^FhucF?T+9THD/#QJ+Zp\YF%PynYR1qb>Q$&^M!M#VFq8*HSZd$e6JcIj8Min!bu$+Dt/IB%tW%EZ>
+@TmR9 p&J&=M<1iw+l&WiBL>%paAXEVKqp/l>V^XVTTGeE5CZ*m49T5yYe%i=9*Dk<kp>EPEQ%h>kj9t+?R!jw
h+4pc> WLY6>^DTwIM#K@k8CGHVBi&!tDeaPWt\GcI<\<k<J<pwV^LtZb9aBZ*CB#Fk$#4P*Yda*4QtA\^nXJeF
P?nM=Q +e/K4H!d4FlItIaV9mT?YqHDGEwBiR$HJRNc1Fq5\8SZtd%T15XbDD9mLAb5HTiV^u=LelmlB8QB+LG?
N+#Tlt \9&1yt+w\tBPE!>QkWS+EbLiTKWYX>MbQcPEjckI&&1BBmF@ncMMeFRFRPW=+#JSN^^Gi5j4mB$FbjbW
lHNM%Y \tjSiMKERF+D^%PRbSE$ajQJ$CV5&A\6aHkuIG/b/VntA$L+kA!e\ZC>mwQN/i1I1Yk+>Q8cMjqdha/W
6GZIDq mjATnYFC%Sd!<F+$n9G^KDSM1A!>S1CkuIG\Y*LL1$!\uKn6:SA^+iGR<X#b&KtJ#Xy>&LJQtFcEhSP%
BAAcLa BqQHVKlyep:CC<$JYHiA5yA$pFiNhJ49&dS=/AS!hl#@FJR1!*lHHQY>a^neH!=cE@81u<8#/:iRnF+^
6RyF<E ce:ntVCB?IM9Xm?NaDmPaky!ywGeZF\Tlt&pThn?Gy^in5XG@81n/5=S8X4qw:l#PHm=\>%X=JhHwYaJ
h=TeJG C6*4/NR6L!\L\kXJq#+LmTTQaBBP5clVJQJpu9qt<FqT:ky<n<RbJFYBC4Lm9Pe!:/Xy<4ccd1ld*WKQ
bmk#jk MH\FWHqN^?kFnhha/5\XFnTR/ShYM\!LE<kQ@T\\T:tKb\H\mjXX@/Sya#n5$VVW=:%^RZlJ/&BMDKAL
uj\nIi Z\EM5dym5qLB#JaFuTwtTjFLcaGeMS%XTVp/1lFbjmwA*Z\T9##e8wFty$F@>C^w>qE4j#F!mZBSbCpE
?JXqGS y5>ZtZTKy\k&PwM6&<\wMdPe!$eT6q^YwEdG$LtFc#Aand#Rhq4M#V5LalAXPFlYnI8cV%kaNESNC&5M
cZ6h49 dELP/N6/=6A9L6Sa^wI9#ua*VKD!Th<\cG+PmVc6i=/&\LQ9k6I\+:F?JiNmK8uVJd=\Kq1iLF69PRFj
w@&^TQ BeyCN5Ty@$S*^8kIj>HueSSct!J/R*\lSp>SK/w%hAHjCNpL1>wAijF4BSb&K=A#HtAku?iA<?$#PpTe
/VQ@bk mcYNYX9R/@Y\E!D+PAMC\dKHFGbMYE4D8IymCBeF*cV+Nd#FycDkZDNl!jKSCu!PE=+=RC?#iqqtXAc>
V?jj$> TG8V5BRC>apWyan^A+aZKqb!@4tY#X=@SGF6?KNYqa>PaNk!Q^tA9DtJiXd*W>CSFED:/NFPN4?5GA5@
G5>IeP XW\19pAYpwcm%&:Y&9b+?RajbdMtH#ElHltkK>lMP8c/:whd=F*ZQ15h:>#MA%6wtD%IRTAZd?/$*Yn=
%PpV>w $\pXRl%TL#?8\SDYVJDRMBReT>8VYiHJHBMF&m>i4CpH+5<Xi>FKwP8E+TFu@:EpkC*^YX%IB1Xntbk>
n/:#t& &Yw/mW\D9P<N^EA81ltmpQ^hyGXmp4N<KInJV&w\&c\kb+Kh!%lV&t5u$+nw$QY<wuJX$6VPw=$cWXDI
$jb&Qb &RwiXeK/FVeVNmj4=XPRQi@dQqq<WS*@XRD$?9NRcZqM8=K9GSDPtIaQP&9MpH?JkDuSP%SpGk$<X<=E
Zk*WSK \4:&up@&mEVRVjW<FnF/=iAF<k^Ji6ccWuPdRKcbGpP6IBaL!LJ1i^hVlB!SM:M%<B\W*hnYA:=p$Jpb
WS!VHQ At?F$9<jRKcqSXeC1\u1t:H1#cTeVVX/nY%D\dJhGdP\/ZT5=Aa%$?tEjeem4bwI@!=eJJ8GL8^b&LLT
kM@Y/< L6CIM<6/l4=Sc?Zyubllt!@I?Yn>#>NHdiC!tK>\G1cSKi5bwYD+b$IpFejI\p4l\ulpRI$d*W%&#64/
hh:Eak ShmW*DHLW9dMV:tl1anhqdA4>5?#VJ5$Qc8*HHi<KP>P&n4>*R%&Yuih9<@YheSVja^!t1h<Z:5I@*k&
h**kSm uMqkQGZTbtR<!u6Kd/S#A*:n9$N&HJ+Nk9hSX6c5WJZHalEdWC@IW<S9n#WqVP5?\b<*F4S@8HDHykFu
qnAh<Y *LKEtA$Y5?I4GYiaLRtbXM*ld/VJJmL%!A>9LC!:E&D8tF$LYDNnl5VMhpX<!cD^t6Fq?J8&^+DGP/#p
B\Hb@n h#h8nDpJh*#$8p4PSLnpP?iMNGu?Cq<LdNb!c\1w++V/Mcd=y?ldeKZjINkM8&h&YQ^eyRBdZBV:/lV?
WcGnnL WlBM$TlKelt#bJaQ#j?!DuHb&A#NVTTHFm&9iSqpn>u!&LhT#mG&m1cEFq?^jceFKQ$8KqZdbwptM:NG
EHL\+B F>eP4Swi/%Y9%eZJC&jS<!d=KNh&#c4bdc666T!GLSpe=YTCkVVBtNtY$&c/#BXIQJ1F@B!RLRctt%9F
5ABH6p BG\I6D:^wC$?iKNMIm6#@Ly6lDAD:a1LIA*/bMLdwG1cyXyJpK&BdB$*?E+A%a=1aWn^VW$<IT!NAW#I
-A5l!P 0009e1be1c800110334 Page 136 of binaries2.zip
<uHX44 ywHXlD:^LKtTkXNG$m^d5bWSlEEY#$dl^/QW/nY4Qk=4EW#hJ%pL\YNTIDEDW@yIShXWbLjyI1=qmBmX
*KP8#L ZwmZ4IyEY=cRW5aEaaWFY&M^??jpSBmZTc5RM<$IEy!jFccR6=p@jYWK\pBp\qdJ6LclYn\y=MmEmCNm
hZ=T1/ 49Gn+?4+k!VB1<+n<Sk:9t6+/ykpLNmGmCy+cW?CJ<ucBF&\Le5u55CT/\KWaG6%^a%lLabVX=WZk9Sb
pD$^Kk atiXqpytXiJ#Y=A$MG1I6CT564XdhA6Bq@HjtphYXR$ml1+#6*yb@y#iRJWj&qj%*\C$T\VLa=cp:yL8
KkJZb9 T>kMht=C#1cE^aPXCE?^BdVF@#ZDET4@#yEQLK@@B%BLA\RWAAIACAD>XY$q^uM$C&MAAAD&AAAAKRAA
QZ6D+N AGN5cYX8hHM9eGh\L*hydnM!L%BHWGFpdYq8L%Jqe!>EW$F4bZp8at%\e@L>^kABbWC5AeRCWM#I\AIY
%ak?1n d&DABSwkpk$NEAwEka\DB\+AcbDIj#Bm?Q<jRwEkTAnEJ\Ra?MHWl^$dwQRPpIZ<#D6&:AcCDj\YP*b#
9d1Dda :?diAPS9?MD\kS<w#+?5H1ajF\AAWE5DBBRAAkAIAQ%XdTYScJFIMRAAAH+AAAA6AAAAa&^ybY=$e!>\
:dpaje b*A9h&q8M#I9WEhRaYS6cY+9WtX#L$SVRY6qiY%le&58at%\e@K6a+AAP!DYAGIBKGaERlB\aMAP@9@@
I+X^Rt D<RMKQk+EDeDeRNEK$S9J\NDI%V<PJy/AFBLA\RWAAIACAD>XY$q6hLH:%aAAAD&AAAAKRAAAGN5cYX8
<tPYj4 hHM9eGh\L*hydnM!L%BHWGFpdYq8L%Jqe!>TW$F4bZp8at%\e@L>^kABbWC5AeRCWM#I\AIYd&DABSwk
y\btEJ pk$NEAwEka\DB\+AcbDIj#Bm?Q<jRwEkTAnEJ\b<Pi@#^eWjVB>^eaHR>T=kkETjAaF#LtjAY9/ePW?W
CMCE<! $RBRT\MEFAACAAkA@XX6JRy9@tp^AAAAjkAAAC$AAABndGqqduS#L*BueC>*cY+#Mm>RS%BlbG%ydm>T
LIq849 bZM9WqNBc&X=dYF#c!=mdZB#<1%nkAA:INaAakEwbkSCEHBk\A:?@@<Q^A!w?ApDR#5RM#>BtAQC#EC=
j&C>#: huT%RA\AWE5DBBRAAkAIAQ%XdTW1u#IE?ARAAGaTAAAwAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRaYS6
y=M?Qj cY+9WtX#L&FpdYq8Ltqnd?&YQ&ldS^#Hj:bj5jyppL%+C6m%q#yDdZ1Bl<qk++k8hTBL/FI\qQbwln+/
mltb!> GA!maEHl+e&FR8A&DY%yl+J^MlliIByEl@yRN&iyRiAl^SR1d\IJ@@4>*TuYW=HWyBSQ96Qy*8@Q*i@#
tl#Yk9 :p//H>EaBVR@Q$%T@lku?kD>@L\V/eee$Z5VSNQV*9:8GNFJZtS9@@\6w55y/GWM&n1c#PjKPA$ybjil
Wl!nXE e6q*W9FR4XdSm+dhl=l>J%XW<9WjT/HeL/@%!@q@!PqKWM#KB$G^tFHpSe\1ml@iKh+64q@Jt=9y*Teb
RN51YS 8Xa:V8@$&b?uYZ8Ren6>twqZ?!*NtQMHt=9QMuIc%GyQc:*+?cqNqI^<WEQJnE<DYy@1Vd?*X@+/?@by
%iE%X= tl/6bN=iT5?l+PTi\\D=id6j*5@K%E:*+E@>E&aZuF>:c@t1:KMXtC@SPlQMLbK&^p&cR%>\4hu6P$+u
JFlIqR 6nX8+Luyt5m:*Blu4tJ<ie\j5Y\Vuhkcp<#Nkw9cj<=#*h%:<*Ni@d%K#X>@wCAIKJjL$hVWFM*M#ND5
?pDEA\ :C#h8uYLFlaYcGqymS+?jEn*:>?una$NYq%hyjJZVA<iMH%LJ<S@Y94q=C</ijtT99uyb$SRcB4NwFp9
^5He>e Ku\y/BS$TuV5ZVV$Gk<cik&>bn@MRG?kN^AM>IdhXGTl6>Bd/C$WXqaIMpNt/$P=16EMt8nal<iZAwMC
%ewi4A k\KDAwNDAwMCk\KDAwMCk<MEk\KDAwMCk\KDR\iDAwMCk\KDAwNm/MCl\KGEA#9uZ5?STDXwFw*>K+NF
/Bct%u I:lGII%JNXneM5Cw<cDBw5HmqkWeGl\cHN1In9%TkWPDRaNBk$GYVwNDk$GD\dy@LP8ZEHF<6h*qXa:I
<Jn6pK KJHbL#XmG#AbBDWIaMBpEN9AcDCJMVIZ??%\5cFHjIQ+B9Fqm\#mG>GD\aDBML66<#8lZZRlp?&%aLCI
dS<T+I b<Ft\YES#&&6eGANLDm5ePDF*HbnpAYLBa5FlEXAh\VAanHR\5qCaeEm^<IKC@dEk5ZKinkYPR&!C<ah
Z=1Lc* JRaDk+HB\GBkMLnnBAaLBkaDk<GC\S$^MDAaGA\MBkaDypcDHk\MBkaDY:p4MAeta\^pPGp6i+S>qQ9E
wAn%R% #T$?t6/l:&q4c+6&huawTSJ/@Qk^HS<j$?HlId%+<aJPV$@y:P!M#5@Q/iLmkq16FnZdVN>XK9>/V+ZZ
%D=Hib ZT4^TQQ6$jdTcH8yhD5Mp!AbcweXb6Rlbt>$hbAD%NE!nM9SaIikH6TncDq!VkQ5hi@k#IQGJ@YpHqYm
P$?h$p wiQDJIw1FZGIp5E9kAqkHnK/XQIS/wPnh<%JqA^#pPt:NSk<\Tk#:IkR!1e?!B^LCiQFeGHI=9wCl%Ht
RIc=&p IR/X$tmH%:NZKmQ6eXkbCSDHj9:B9+!4<MN?P6*!j@+e4!%QGS8iy$^*e=XZ?Zmb4mWj#^*+@1mdRkj*
PZcnpQ :4tHb@cJX##QP+?n+qPZwc+WZYcdQ*JJFd*KLN9:dRjMi:+9eH6kQ9kFZi:G%Jq:SK*J>/p#<Rt%J4cy
Gj=tT5 5+l?<p5<a$t\LI*C&$Gn<Bp%Cl>Ve?=Vc1$>\6mQ1H?h89ue&E$?h=QQ*iS#N@ueG?h#ecu@:w!SF&X9
qkM!aK @CSbS4*TqP4%i4Te>ak1aSSq^mjIGu4tSbp8M:!$:Y:>:E&>9bm=?GLe1*Htuw9nmk#JZu!q%:*Q\9B!
>K4YNV N\\:e&HatpR@kS/65?lqiY/md^S/4Tt?c*:5*%BLA\RWAAIACAAIXt$qTB?8p5pBAAA&EkAAKAAAAGN5
1/ZbF! cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>DVGq6aYe!NC=mdZD6q<F6^CARSWpHWW+yIWwBi+&Wi*yI
lIbBE: J/cV:GFQNBEZ+BIm8aZee!DnBR@D\MDa&X8MQ6c8aZcby#<a9:/hH5!%ucA@RZ?Hjk@>#n!GkVlPt#j?
bTP84m $CGW$VWy*JKt@MhNIV858!tpP^u8\#4HeY^e1:FYcF$!:5P=V#h?ncBGTF#$!*NTL?WaA88hX#WV9\+q
W#t4Xm TbQdmCR+q@Pb1a$wlFA+*#<iBHjKpEltMFE=JVHjELL!eh/Bq1>FCJI^W+dI!+k&XXc$ASFFyPeDDc=%
BbhMK5 QmFVFFJ1<Bp!<\Ae?Q$FWbMQR<Rt\>jkE/uBKA9BGpu1IRw*GS?$WCm$LFPdq$pQWYti#EJ#qnYD\@qM
d6m$TY jQK!N4t1!^Jd?JAeGTINH^1PG%GY:F\wIN4Il&=E&iTyAmjh@DMjql$mW9EyEMHuQy?bYEnmA:ICIwEQ
G1EKNa **^8^\hLI!FT<GGIEG#JJ=ZGJn/DWJ5>Q6SSPn=i+lQ!^h&%=NN+8GiIXqZ*=:T:Mn:6=^hFbMWRp&@P
tIE^jY El!bn<i4^Aj!wlbT<yEPByXpdY+l&V!eD%IcYu=nbXW646*?\Z\yHPZ=WHtpnMeLcl:q?XB*yFTiD*e<
Me#9@> *@@X?+ZtFi^+T#%$K@$CWE5DBBRAAkAIAAlYdTYlqB\GdAEAAHaDAAAuAAAAa&^ybY=$e!>\b*A9h&q8
dDyAyC M#I9WEhRa&\9WtX#L$NMcY%lb#R8at%\6XI^d5M\DFVVAnGCBMkVDC<6>I#8@WPjWHTIlA!NN&9yH\\6
q@ydyZ AaR<\8lwcNCaSY@wtDG>w?IkBd1Y6u\!iV=TyJ>jN9hKdIQ%lQYK6ec/W\<qeIt4m*>>jY9qXt%dkBe&
Q&9d+m \#AA/VuL4e:uA4#w\mQ@p=Y/X6^YXZFN1NR9VMK1LI&:%4tY@6acRXZZRqR?ENM!D1CqD5d+$eHkPHch
dQM/NX MR\$VWQFyQZ?Hdkea^\8BXE?Yi9eJ>Abe!J/:&9=L8^Q=H<h!J>V65Q:HHteR+HW6#p96NaNCyqyHW!j
!tHM?t W\!HPK=!>RFn@bC%QIDD^4!BF\ITIH<VR8mbLw+N?Ikc<8hA$ZjRB!=At@SDDj+l^uCn#!15/KNj$F?a
uY6awV TS<H/aZ9jhE@pZ@eRZaqjiy+u4VdlwcIBJ4u>cQ8M@X**?Ru/p6@ZPuV+=b/GBMcT*+eS/T:/tQZ!YA4
iu!KPD =\SX$GXi5>uN9K:>^GDdM9<J@@\jp9\@?h@6B%BLA\RWAAIACAAIXt$qERn*mEkFAABtEkAAI\AAAGN5
FEq^Ra cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>LbZp8cYN9:be>cCNHFMij#+wq5GH6^t+Mh>p$<Sdln1tP
+^PT%9 lPl\pe=\nhNc%bA!lWA1A6:D+FP1C\RM$^$mCWpSCK+MK4Lp+A#^hAK=mWDG^RWVPLtTaIWu@#i#$8:K
h8H&Em h8\eX*yYV:Q9a?d>htc<imccwRI>iLBI*Q/?S@RF?5XFy*<<R@VJLMF9Xj1=SQSqkj%P@?wDww5F^PGi
E?h+Z4 R==AiD=8+V&/ywZ&R&HwP4=\E$WSi4aa?!FnZMeZt@n4^qb1NN!N^#NS5Xc4PWQb/h8%:V4j#D6>EQKF
+A9Qdj t>b@/@QZ?L%/4X/nnD=ARp4n!W8w^#w%ZD<@>6j1PZ?m#$@F6!c/#R:@y#jw4b#icDS&Mn4e4aPH1h:m
W#\R?P =kIG6bA<1:5AM/X#QQVj+:#?I16V*Gwku5dn*RSlw699!Y+P91ddN^+&LF?Wi>/wHBYHpH+=uP$qE6p?
LSYi1Y K4JEmPtXl?X?8Z?@B+q\H$KmnIV*l&Z!ly>VedlA5%a?T+S6Hu\i^!B&&>nG=*\^Pi9ne^:S?#@u$4aK
E$DqbC TbyDN!e46XDK$t@T&/:QXR:R%\h#Xl<<6*4F>K%jqlALZSdSm+i&u#@atWNj+R&WSc4EL?KRhhQku1Su
XF4C=! akS#6mT6=L<Vi9jtVd<QTt+%C9>@ucK@I84@?SMXCkW1qW1$5LBAT$6L6L!<VK841?V:Q1&64hHt=mb6
YapS#X dG#R?9w/QZ:<tMJ9DD%>c8l:/yD=S>Q4#q919HqD*@*!K#IICD?pktmuCu\J&AS5kt*GlWnB1\KBZeI8
k!l>FM nS8taFi\K!kKhtZ5XKSl%:B4&DWMtneW8wF86E6qL\qSELabq^=jAk\CDAIMAk\YCR\CDAIMAk\CDBaV
9!XA:J DAIMAk\CDAIMFl$MAk\CDAIMAk#C\AaPAR:BHH#G:Cw\CX<KwmHGQVJaJJJLJJKaXA4nqkFPQmATLBI5
/=e@9Z hquAIeEl\TEX&+^dKuBIMEk\TDD\$pq\TDBIMGl:+4XdR8S^q$/YX%kmJXk*d1tSY+FJIcqCAkWtlh\K
lTi<Xi VwXJqPK=nN5Pt^6&=FjI4=Cj6$kl9&I:GBRaqDF&&>^PTJ8h!Zl:NSk$<tt\cZBw=LNd!^^aA\$P#S^+
$DD=C& ML9hGKVBw5GmAcGS$B+B5GkM%AnTMGm\<LHR#II>$YDS9B/YlW<D:+K!S<tA\aDBkMGA\aDBHme\cDAa
@l^6+Q MBk\cDDaI\aGA\aDBkMGA\bMDaEhDAaMBk^G<:5Ge&A!k+EGRXL!HtEj?Z%p=?aaTS@Tn:T%6WZ<\:c:
LkSG4l 8$6:i*6$hHSE?@9:hH^<VN%8q$=QV?u5:I#P#<>yPB^TQ#d$\<8Z:?H*uJ4nq4EFkV>^6>96WZPEqkaE
8BFXJ: <eS@$l:SCB&?S&N*:Kj?dl6P??tP@jGKu^$Qn@&enMd8c5dj9nR?48dH&@#hTZ/+5?M=aMVPCX=?QBPP
ulRe?H ep?Z##<PTB>?in^TbBh9P9@N+$?t@NQny?bj8bRjCdL$q<i*S:eij\Z@=jHXqi9#B?!8BqMQ&M!:<#Pp
-A@t+1 000b45db6eb00110334 Page 137 of binaries2.zip
e>aaQd +?NMi^SeY1BHRcd=jnAb**d?PFmyV1+ki$ccti^?HPeS8/uj4y=hk/9G8\D<J8decj+MRZaBVqI@A5d+
WH^4ul ?RPTL1B4RZd>*:%W+J11=%&kZl8Xu<$P!>>?%Ij$4D^DQei%HNh^ZMN^Hib18h/+j46qQXi+bV*u/yRu
!H@DBH M*h%!q&heqiu*NWytVwq4WD5m:HVJL=5MSFp>dmc$?N1w1NKcYd<CEnWSEel$ccMu&jI?V961@R16&Cm
VFM8KZ b*/bP8*t?AjJ>!j?cnZtKVK/Q>EVH1e!aQK/4/LdiW8$hkl=D5H@lnQwh>C@Ru>aVGTY/DZiuZ@MyQ$4
:Xw*Au &A+S<!>RT\MEFAACAAkACFb6JW@1A=!kHAAALp\AAC$AAABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>T
Aa&k8l bZM9atq/e*B5aZNwMYJyhC=mdZD5&k6WW%i/APB>ppAA&!cpwNdiXbAtF8K4w/N>*lI\iCFmC!Eu%ImF
lQEu6H 61JCSK&6n/y\AtILcC8GBK6>1JlIe6JIS\%$wEn56FPq6^*1FdCpTPywS/FIjEAmib!:V:B1JeiJec&:
t+luAq =1+%aWY#pu#59j@>::*@e#S^@4SW+H&<AJ?^<NtBACCEV\V?pA@dQHD#Rd9^JB<ERbDQAB?8?:IKEPmD
n6dSpi <Y@:j&$j8k>LD>l8ii&JqM@i@$jm#GPQK>?ajZZ99hn=4<9#Rp:H#p*<!?!Vq6u%>>S8+i6=iW?jYjqj
B&^LWy SZP8ZdHah!48^ibBG&$yL^Aqhy#5/qDhp**t>aGNu%<ciQ9N9%y&F*%@>b:5H*LA1>+ZApAdD>nk*t^P
^MkPQc #p$d#Q=@pJMq\Bc\@e8h$WGm@dV$M%huD=%i@5n*%!aNLS>1&>4W@ZdVu\4c@LI$n1Y?85$%Q4F!$n9L
%kbtw= 1&*ZQ$uQ!!p8<K@haM=8cH>==H9d6CHQJ%dL:QSu5PKXj61^HjXDH@#!1C#u&cHhR#d^+#<?KpeKFQ:%
R>cCj! ?aHwpHWj8J/VXe=a\ut%:a*\dVQDm=<&?^e4?LXk>mda=^pMAM\=AQu6MQJnnlTAFu##LVQ\B@=L:JQI
^CpHDN jhmH:5P?eB>&$*%aS?AY5RX8/hdALjM?&tZh^*mnZIHciBAj1GY/APaJ$EdbABGwJe\IRVBCtFcttRX@
chCE&L &CF5Bl#GJu<5RkA/RRTQb>ya%ml4qJu>\JQBAAMij!#VA=kERZiAJ$H$?Gl+C4J5\TDub4X:X<6!ASbB
kP^I!a dH/TdNh4k*PCaa@>cyhqA%EEWS#N6LLMZp5VpP&/@LJY4:W!\ANkjA/$hDNyFZ=bM<D&EAw#dBjGC5ab
QKSa@P WeTd@a\XT\EIF1EIcH/nAQAEcnGA8JlEaHpFB?aI%MLJYB?kSX!k/Ep/\XT5S\lF9ML/EF\dhDQL4*!G
&HZPWp !RkV&5NT\MdNSLE6Cm=t$91VG$\He5P!4GaZA8&t=$u4<MP!dLC9VBi$WR4kRG#^\QEa6Q>$%^&^>F9Y
@uXEEA SujEK&^S$NL>5XFi/+A&Hul65a%FY15@%pycG:R9*LTd#T!t&R<dd+Znbh&!&IlqKj!!wRSel>A?V>1Q
c1N^Bi N6/D^c#nCSBqllbtk+*=$b9H9DdKu:#CdM>9AqEK$tJtcK?P&Mj<5$Zp!iC%Xl9#p^9&ij<5ZL6FZp8H
yIZ?y6 :V=$?S+5eb$\\?SqthjDXLT^YD?V%8yju?FqQ<#F&?#QZ59!$=J4mYY>#hJ6@5$SAe<^JtphyI%mHdQC
HE#h$\ jHd+q%jpuRy+:DN6eQpwdI<^#Xd+wti:Z@qMEA:!FGY%\LaR$64Y9<D5&a:+a#Fw+?HS5MjG&5+mQNB8
?<>j#@ &5V/&*c@%m>G\KQdDKK&Y=q\t@dAjpe=YN>5>&9j\Am+CIG*jHiMNAdDlLD<&mjnCVQ4=4=&5/Q?YpY<
n^DjD^ NWAdSTlYkaD6dY@ec=<>kX95>kQkTj>9qZn#/9cJ9Hp6m@lnEiLiT>njLJ&\Bt!bHlC\bbpD6!H@96j*
a&iaV= 4&/^kP<lP@!&A@hl+\P*:uqa\Lb*R8D66l&1C6S/?A<YBGw9T^aa5kP$Jb@TyY<Gbn$e>BZV>+Hbc$be
Wc549P P@h\aQb5Cm4:1T+\8/$KSSi$@BQ:1&tq4?GGV<LXC:G:Y%&NTN$<&q:MVTqap*9*?ZXuSCnnSNtndE&I
GPhy?\ W6u/IdHuducjpBj#tn=nXAl$a>B/T<PhT?q*%wPH^/bYlAqj8uMNKWBC1uc/4jM8%wEi?KwtKb%9GDY\
tb6yL< CTjjqBFdX6:F%mlCHk=:?WD84D5/dWME/8@4QdRGc86Sn>XyJJXqyaI:kuKb@ek#5w5Zyl8y4b8dNw?*
W?lkWT k&jmcYji?cYeyhL6dcEd1i*bHV^&M9eDS6iE@@=>y/?D*d9$SYB6LdZXcey118a>48ieD?@=*be$Jq/>
qyP%Eb QIj&ZVc%%hL=FSw8N#\tFB**8!@q^d!w:%/GhGPW%l&Z^a<LKhN1W@FI>Qd9DCXKXIcb=uh=%HbaYGK8
HiueNC !ESnSahRnj:&nDuB^mi9HYBQ5FDu<%i:8JHJi&NEu\q%/Nld5?S$e#T^yTi!\C\V6X$RM%@Q&ca=EXT?
\1Y/&6 L&Zb4VS\ZpWBP8:D#<EVtbVYW/K4nBFH/#um&jQR5h1S6?$EkS^IEJm+>hiRDjGWhunBYNE&qZy4mn=B
ljQjc^ lj?An4^6IF#+cZYp!LLIHQ\hRYAW%qwV4h4Bm+*teD/hKJ!Ei>iMT$9<nQIa9impV9Dkai\KXd9jm5@#
p^w$5e PMpJwhE^=Wd%PbGcjP@KX1Ke5!!W$d:<J\Z@IHGM!wdMDW&iwc!aPFpaI?a@iARuh:c9eFjXapYalj@6
Nj5Y<H I4Cm!e&p5C:?DkqQGJ$8$<TFl&y4=8ZZphtC4y1mVPh^ebMNtL/^Wi$dq*u<<6M:lCW^=hLF!4lFPIwV
Niphl& @Xip8m*yW%WyMu!?tT/QN%Nbc=LwD@VE$Ikaj9LZQHp+H>&6N4S1qPXwPk<X+^dBtBWiRDXHt/hI@9y!
+$qk5H SDRmLFH8%6BR6H&&cjwEQXi=a=JIyML4FMGuLmAW%5NRK8N+TMni6Fm8q1@DNZ!>1K8hn&6EqT1NAZ$c
$TEbu+ @GiLanPF9bcR!$5RkJm\$yJhIqTwNLVnJ6+cFPWdy8a6pLSjw<uqIT\1G%ccGluCE?yCPSM=/IK^8!ea
AwSVGC $Hu>T%L!hPtJTq^6A#$4w1t5Pe#$k&tmMJ!iL6aKqXXy9F/nbM@<bF#N/cnQ=ha1ktR@Ccn!Gc!8+AyA
?4KtS$ mPc$ynTEI%tP1!MQ!=e%TbY=cHmw1n%d\PqeBTnPMw?ReRVZJapb6DHQHwyL*=^j5!c%QZNIn=cLJ1&i
WMC%<T ZQEFiKLSVKe+!%^Aw6CWqNF$KuFM#Xu/lFSNk1!/?%NeMnq8iTI?\RGt#T1l54cR%ka%t/&ncWyVImNP
^QVbZ6 <VK!hpy:D<8:9n+8Vyj1!I!$n\4#d>ccEJjMFhaS:9C<mQ\cZyy1j:V/a&M#n@@W%G*Hh<=SIK&jp4h:
1WYI?N jXwFDXZ4^uq*n!>LnepG@5F&@5!Chj%w<k>^n<btJ+c?eByR%bP$JDFu+pmCVamLR\Zm=P:pwRY6?6TV
=G8lt6 Y?LTW5/\H<:jK/C\Lpca=Mnjdy\5Nau1/qK^$4Dd@pLjknB>j1d5ieXa9K&awlb%KC1$TVit*9$jJ$X=
myEiW\ ejPZj#G$8%PGh<qEP1$N!A!AVtG95EQ$8*:4$<<SP4XaYiZEVa*6I1XYuVHbDLV=kEXl4VGG8iE*^!Py
4<^AV4 1bJKcn%T8:^byBVNPLD!GLJwlTCK\u+F&A68HWE@XB?T:Ikm84WYiXd>!c>n>+RFTT:+1PFGdHHIT/Z:
JbhhaF d^%A!cYGJRRlqXX*%bSQudJ%E\nVKkDXhWy!a8W#6=$a:dMmaHqkcqlVd=!huu:pMym=WECu5B+FtQ#/
wVDXGe daYSP#eY:yK=/=dWG^i*#?ThA*PqCpwdG6aq8n$Y4i%\h?=b9Kn@6J1*bKWbNQ<b9ESlHa1$tCP*X/uD
E#ReJa M?AjjV$N//S/jEhWJi$%+il59tG9eGt6Y*+ZS#LH44W9@<kpVbt%ARS6c\Q^FQaeEFikw?bkeQjFyq:X
V1du\n \q\ZRKe1jJZbZt9tq8SZnQ=5#b=<ZC9ickPSiV+!<wd>Aa^X4^u%$dBqVa6ypcVB4MAQCqlW6qTa\B9>
6$1bQ? m#*%B@Glp>4yCpSe!cc$A9a:?i6G&>=?8XyyLC1nT+@+C6YIDXQ5W4$:&l:<?I!#RP\C\T1B#!5T$u1m
ulXujR ?a!p$aW?IZ<#h=4a/AB^GRwB%ZY*w^VknZYnQ?5i!B:Eh%1S8jZShC44b1iH%8\b@btFQ+k&6mnAFA&k
?yidtZ 6I:EEqG1n&B$>KGb?We4k@iuAlcXHYcH1MW?k6F9hBc1QTD&y#?BiDiF6Tb4?JE?Ql8&TN9qNmRnZRAw
AZlm!Q :%GeF!P^il@6Py5KG:JQ$hF^AIHNi8!auiktB6!\WHRVql9&PFBq+D=?4*NJ*%SMpXwnkb8G*Yu9eR<R
n#cLZm =EJ%64md+Q=AEP8l@ZJ9#Aey91+kt%/^EBMQ!ZVia/!FGCAYEp=m+M!AlVBm^FF98:w\%bLDQ8#%\ja/
\P>SG+ V>l!$^5\#EbnaX>Dm/h#BiFi=!HYEyc/AThym>qA8N>ZMNB+:H1ZejM=GGaMe&aZduRildN?!hVp61#D
J^+18^ 5AHTVwZXVKa9m@WS>pqwQM^t?/q#HS$YatX?i$QS^\P@HGn<1d?nB++Z:yKC6K&?dG5Lei%HQRH*b4h<
8CA=Kt aj&jb<*91t<1:L*Ij&:Dkh1tRnh=4EdGcI%Q?dKFMJ\N$#%5YL>&TiMP6Dy#W=aM%Fil=:+%/q@5^G&\
bHdyX& ZZb!cEm6L$9Y*#4MAblE4@JW*^Sq?*#$^aQ>>dD><Yyb<*M/cJZFa9q$145Ej!jIj%n&cHcEJjAtd$^K
Bh\DAd M*aBVSX*@$V8!h:QAidm^mbY%qHja:DCaXt1?IecJcjKZ5adFt5#q86n1!&L$GWAG%cY1k#b%LaM&mG8
KXZGTW WKkwMe\wblV5anMReR4kJPA/56%RSE^6QaBB8D$Z5@cM+#e8XT?a>?#$E=/D!k&>QVNiB6nqFLF5:l:1
u^/am* P*4SeI$=#^a?Jh*\^#&c5*!m:u<e#dW=J>wcQ\PaR^qT<pHLZi+G\nl&94*+:RQu#n>:?dl/SScV5!:+
&@lhJQ a45<F+=*mJ8P9pb6#\I+Hw<+d@Q:4a&D?ehtcS><Cj%:=>!PW^6ku/*JJWkR>X&h+<AA4ij<8MuHG\?6
/PbN$C h9Ptb%XL<18Q/<+Q\n:*m4uckulK1/BBP%lYtNt=eM%dyq>Vm9b5=@ZX>9bbb5F&#=cXy*Cw\<\PI18a
!c%\i6 nYhitd=F%mL4Xte6ZH6T*uG^+%\@4Kk9w8\\FKMP%Sk=VP9/bX?$Dk@bB1Z<K=?<<%=j>YGnyR88lT@b
/Bl=Ad QHEqydXGe$V\4&du=#9QN6eNZ5yjQeZaKM>e//\u>+%V&lSlNZXYKjJX5N*BFhthSj%a8/i<Jh5\QN^^
t=\:^i 5SQ4kDZZ5dRIny:/@\8Dn?W6lBN#%$&Vi:4:*yc<p6%/dZ>6^$C@G//F/4CE8YI1i#$cii$WHFD@\6nY
#lEej# SqPVVLp9dW9ppp91Se$d+iLENDb%BKW>B&kX<FLa*nMp*&%acc@Hk+Jm*$k6W/N4:PS?hTJwIm?SPnQC
W=KkYM G4Y\%tyGXVF+@+9LhLy$$Xd^Ib:i&ELGT1qS6StyLADwHHKNPbiLXjpjZ8@plVKANm=WM5ui:!H:uB\V
q^DwKt qE/XGRlduWZt?wAF%/9Z:y!RLEnY5>Fq?:Li:+HnLc1w%KmVKP\\G=lk*5ADJAjRiP&F1<SBkJapAF5T
yWe$Vc NnVb!V=4iX\%%d*WcCSFR4=a<c%F<6*5%9eE:qXy=R9q&pjuEtTe8VyX^V\Kc/QSDBui$4d?/M?em1dX
6FYhm< :&Z&MNlBZY*Cd5QAiqBpLJuI1cK\blCGi+?M9q^:K>hWI*#KW*?MY>9\c6#MdLLh$km6tG1<=8k\QYth
-AZqT5 0002f97418200110334 Page 138 of binaries2.zip
K@:19^ QW5:&yJ+$tTnmhAl#BW%mbPG!dQ5Ee$P^whWW!TaaQBY#8:#&NtI@G*qGLF&YD#&^&5e@b\/&PjFeXK1
m\n9Te hq$MbM#I<t^l>cj6m/nJcF@a@Ttw^cJLJWjJh4etI4#JFKEC+I?+>>:h4%hd#nGKbXy5wMFVG6^:Ij^l
+XZn\j 6Pe$KPJLbMJ91Sb9Ek@%X8^N*&#et<Lj^*T:m$#qQE6d/TT$Ada4K1*WQ$\SKkFnpdeTec=65K<G!SZV
<*MZN6 LJ*hA&uMluT&V4*YAVcy^W5bB6<YwcZEwN=6$Q%%6#YeFl$Fm^*MuFS\DhDt%Z$PmuV\Y95J*>qeFuLI
JG&A>4 PHIHdZn/^8VTmFLnGeJ=W56$ymYF!^bhAIYSbcw1**uqm5qk+B>:dYh9n\$I\8MLHXmLk%t:C5TI!Vnu
V4FjwJ QeLn?l:9>SDlA8pl$uaj4ZXcGR^lwj%5>4yX#KK>kLcqYke&STbKSL/Q*?Ep#kHh!NIi^F9EccHI8yZt
MwJl%j B:59XPQD!aIbe4kGi+<w6ZN<4!KbF5%M<jb=ILPj1FP\i\nAhDa!mjaGqSDYPaYMjj\!*?N%m@qGhPTj
1F:j>@ By1Z\pJ8FiIian!ijTEad%p#MdVcARyq%Tp^96jSFiqb9e!:jIq%I8Nk!%9:5\<Y>#m#hlKDhT:?5&&k
D&8V^A mJe\k&KP4y8tT4WGd:98YkIdhIVcQR<QHS\PN1\a^lQ@AZNDL@qK/d9Q>kL^1T=9Xi:5!:T:mV1/?!%a
$DTJ6B @j@/lMi!hFHEi:C8t#^@VI^9&:<\A?*1<L:5YXt*$8=Biq^#eHjYZFQHyc8Cbl5wp4IqE6@4%!u4pK4W
iT!54l *y\e&w?=L:Z5h\@T5V:Z8\Na^<E6<=cBI4$&45V*HLu6iZy=Qyte#5L@LiZ<k=NI##n?knBFW8<IpuNG
?BWA5+ @\nt+A:\e4*c!*VGQ^yCE$?I1etGBWQ1=i4=M#b1&+9ynBQBNPqFdK<GJXchG=MITXkpYp?TP%QF8?6N
yL*^@$ c^^9NCjECaQaG=*VyITME$Rl:N9hJeT\>bab/q?M!+ju@jG<#@Qh=>uN%#mlwA>:@4+w/lu<\Z/5&i>A
!k1EIZ :+Btudd*i?JpZNHbbKAKyEGjQ8TJS9+RjXy\><t#9CuwhbePE@PX&EWP?a9>Cu+\ptRlQpcEkD$6wZ*E
J*HKmN Yn%=QSCP8$wKmN^hIh6c<H#M$aXb*D9mSN!WdA8>:*qMSE9+u%iJ*%p:@Kq^9/?P&CPF:<T/E@NjZ^m=
y:iyK* Ey:GT\GE5t5<*j^\Dj=qECj5+59k=yh<*i1N+MCh%wL8id5#C\WQQw:yuBYW*eD&eFi?@\\?!#:TI84V
@yKEpF QV#5&p#GuI/#I?dn1c<jTn9:$WRNc1D5^qG+>&Z++HKM^=F$jbm+<%L#1I/IG*4=CpTRGtX/J!Xelhb1
T&d#de TXtP?=8C$@ulS@GwRGDmLt9ct^Q1eW&V5h&t6ciC/q@TYENwF=1W^@k@+dednF?GaRtHK?5LQH#J9<XJ
9Bb@n& ^QdiiuQ*ZH#G8iu/9Yt<E>NTqjhIai#lm5Rn?K:6uT=XShQ=NyjqElGj#:cidGtjE&L1hB$hMk^mZuI6
wkPm%e <PDp$L%<1IKJ1$6?yVpK6:!<j?5:^Fw=h\p9@Vn=*e?F/cWZj<^tL!I:ZjGaE>/9nV/E^qpQ#8:#@>:1
4d%8!j 8:cyH^#RHuGW65=y^:J$jaiQ/i6Hpu9\HZE4CL%N^M?EX8d9<:+:dCQ*/JV4hZq%e1W+J>Nb%/j>bm5b
$:dlHc >+P8@CuCRd+kpy4HM:+6DCPl<kdCu+X!DeJQXnlL^LTGXiNlR!C=nlFQFIc6Q+9BA@BCH@Tit>V5Ii#/
epEm\w MMY^T54%AWhH/?uj1B?%JF5@^MkGIXaZneHE#MCWy*pDGmA$9*^4&Y?5yL&dan/6nlHb9^!6y*LXbi4S
i^Pkec ANSDnDa<1a>H^&JYQYF*VIP%FqA*M!CZh65@NY4HSmm@CY<ui#4YPy!a5duQ+:w<yI5V<:YmGueyaZhY
Iw1T:B #EJwGm$^aD@YTTaGQDdYSQl%pS/G\*C+Lt1M:@:aR?=9Ba1T\Z>c!YdV6EQEaF%>>8leJ+tRcBWw+TW+
bDnTje N9T8h&D<d$SPMZ4*1t^CI%ukBF1cnp/+5B9PbF?jQBG^*%G#Lk^H+j=EHcpu5R@QP8ZFbLNX&WHLl@E%
4nMqq4 $6ZINew:TY4!c\NbGa#w1TENEh4d4yX4XeV@CVl6Bc@TAqbp^KbLckL!FP88+MSQPQ9IVeHmyAaP8Wc<
9WC!*J !Gump\tW&tq&>c5hF:DW$^5Vdu5wAHFF<^m5dZV4mZlq@DemXamKCbbuQ4GCN6@?Q&5$9iR/\$nkw8<8
NbtjEA 4N&%!lpPN9e?<i&BEaK>m>*^9qwHH$9ERE!L<jE/^I%8wp=F$Nukc4!C*+$$FA$?CVRWiuiSa=:GLP:T
EI8*ae PulQ!dd$$HIy:6LcNDiVu/<ELwhDpeSWIN\RH4+i<yDc&#mJ8VWuZwbZPbYeXq1JBQ?5ZDFP/Rp<$inj
uL!5u: Xh5e>Q8HtwpbHLk<GCi%><#EPuhBHdTI?du!bdRE*H6?>ChXThEAt\J+EPJZEtNDu1ukXMJD&u&Wl&yK
*<AW+B V$N\EJS11&qbycL5nZ<M#BXbAuA!i5pjGn8AS@^Ql5iwGqT<EVXei^&!Pb1&E6yc+b9WM86Fc5ZlFB!t
:Bh+A% IuYC%Ka8GA!S:M\NXG4ikAQbEb/Rblj*Ymcqm8SSJ85@Hk<MiBJ?GIS8D*X@qFm6N8\>Q56YeX>4+>L&
?lYdei F*NINN:pS!MMl1N^QD4y\iN^D:FiJQ65i!*c6tyY&d?D6+P8w%HNS4h#Qk+S$Y/IPE:G8!SJ5au%TF:N
wHV+Mm #=<8by81XLS#lB>Hi8!KJB8/uEkYFQaVB:I=NE!^5?Qi<T>!yp*4yB\S:T#AncXce**KKmZky?J#I$nY
:DN?Tk ?wwW4*%YQe$T>1Mq6LIh*8jA16#G:*<PK4dY1%bby>p>bYI#9YckLXBLNW#QWG%C>acX>+Cp9W\lwc$#
INPJtE c5M1DE!5d6TBcP/%ZyMLqQSTI!1XhKAMa+cPN*59h6<H\5%44X4cbYS$SDHBbQi%Y#5LSi@q&6yqCla6
b^+%I= q>q=d/F<J4clY9P\Y\ppJ$8:DLV^&SF:h!MVP>44Q5X@D/nj/?C$$P!YcYZ<Acd=n6Xw6w!c\LG<$y&X
9\MVWq 6F1W4PY/6J#J:t*jSd<IXL:jL&#JKcdqd4qA@REV?\B#hHc4AF>lF=&u%cI516Ww!5RG/4EmlRkw?uqq
8#KTRy :QT/HY::c$<:p$@C?%b$@HaZ/NAnAm&6Z1nypWqhVHdn>T=FN\CFqbKiquS6luh\!>RIE^5#GJ^qM5Fm
PiSAZE 6EymyTW#?+:&ZB$nP#1K8eW4<>TeEkG6D4&8JXjKiBaTlYklYku+k^e\P/&B5dVTXlXm6D5?MH4#l!cP
Kn=#Qw 4bZDT#>IiC5*q:8WmeY^jl>&u5X*ma+lq9VLSVKJjB<VC#Xnl:AY\HL5PQ>XkZE?W%Q6>=Z1epdjkG=b
lSqHed TKeFdJ&FK%yQWjj1Wu8ECMS&S4b<n?X&V:6\^Na9:mmtCu^#4wRZ5FTH##G!&I+%H=6baBQK%yk*EMV>
tu=TJ: XAnAi*yE\mJGh8L/^Ch9teC6T5MSAbFFMSMu6e=5V4j1P$dYi:H#:Fhm<Pb%wLK4IK+E*QtH%:4A$qyt
#E4i*I 8>5dc+XK\e/*6:pEd9JJc9X<bbQ9YD9E!Mb84EX@*TI?Y6@Pp+JmE\A=1jm5/\I<budm5%>/1<VkqbNI
Y:VJuE bi8&e!\??Pb=SjZk$n=t8*@WN&D4AQ?B=LCeX\tAMNXcT*D=5q<EGhqE5*iy>knku!\ZIFWeADmyCQB$
tbR#W? w:KF>XNt6t4F9mIbeF*+X$FdtX\461XMJXmLRX<VI\9%9^&bWL&Cabm&pqekMC>JSd\btbnH*eDI+6mA
N$IYbY G=W=G@V1k$8Ra@cXZjNZXY#XS^=t8!lcQ*l4$QpGwnl!TKZX#K8P^#\ipP>lbu%i*eW&/i=HE=6ZCpWt
S5SA>y !:#KiuyR*JFV^<#iW5\+?#jXhHd?!X:cIbZMB<6yEai6MDK#W:=VcQY1*R*%QV!=RwMWQ&<hqaA<=9&F
tJ!*yY n+y&a#dWPtyhh$aqQ6@?9JApBBJZMVMdd#V+MH9S\CX59cmM>V!+*XN!\KwMa+=X/<:iNn>R&LWhbiwF
C*Y6#N 9dP4kGhbuwHFB^=>apCZn*6St?AaYFlCBtA4bGaVXjpXmGX\$IY1:iIFi*KXBaA4p>&^^y4hb:dac>Dq
IMJT/8 5y\FX\>^^AhZbdAL4b1wtu@hyZN5dpt4^\4a:QyM:MS\#i+HM<lP*RqniueBCE=qal&>k!eYN:9M6+hw
VpADdA uRuA!4SYeQKNmR5V^8/m>H6uuH!@X=?JnW$id!DTGE&!#4I+9EWdM4J9l:#@8^e+V/q5He4IZniei&Hn
$A<9@T CT\?q+uF^@W9dq1BSjtbYNn&+w5AmGBG>wYP>>RE&uPKM:I9dlFITpGiMV8YjAhKq!XL9q8plht^u\Mq
dkW1pc RLNpVYIAuFt!QDa+YJ+qT=lqH<?P^aGJ^h&VHW8+JI>hq^*:DHAAJ=kh?=SnEm#^bMiTdmW$b5hiFR6M
qDZl#Z Wykh?!*=b+T!bMp*w4:JnmXjqYQ>mJH>j@:>F%BLA\RWAAIACAAJXt$qS@yIJ!/MAAAtK\EALRAAAGN5
4anlJY cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>mcZy#eG^le&k$atq$LtJ6ePY>!+:dc4atKGX$I!N^BmtG
HG#/pp IITI^IG*eaC8:P=BlawDm>AkG+&iNuA$THnH!K?\A<J8tmAKEq9aCA5^<PalBFLk\K?RmWCBInSR9eKb
%@mi!a hFYN#m8p8&DRS1ClZ6?*%p@Jy^/l\ua+L4y\eh&?hj*@>@@#j@yj?#%<@F@!:+@!:@?Sd@<Q?hj9@R@<
nBTy:G ?X@?F@$>Qkd&V#>Y@N6d4jR@@JE9@8N@@I@!Q*=!+6@i/cV@+R>?lE@@HZ*$==p@H*ubjP9b*>FwlE@!
T8pAZ1 #=>9<V6<+e5@n:?Wl@KB?9%YQtZ+Bm?V*e8n<M5=u?9l&?%wm^@mXjB#?a#j+$j!!BHjWQ/ZL@APGh>y
>XE^4Z yG</<piiZkA9D5@JjL5W@Ju#kjnH^<8LbV=j%J/C>=Pu!?Z/@NE@>91nEc@IWd4F!?DcP#L%tuq=@Lt>
\ep6yD 6=Eq%</HnWb/n*!<^Emw>9lE?bp<ZP@c%le/:@E1iEZT#Dee&h$c&W*\>iF/V:8L<@Xt&cZku6<:J9Am
PWEIl9 =*4:QN+\I=TMe<@+XjnKJ%/\qe@yL6B8jWhbb8#\HZjuik6+1$GnZyG?qF!A*A4np/jZ+19R<G6*>+*K
Wp@KkF 4VFK1dbdMLJd\56^uFS!@I=!9wnjTRDjQ8QDuKD+<$G99?ZN8YC49Md=Au%HwVJM8c1*^MkBZ#1=$k5D
ZJTdc> R?%&nP!NHF9ujPZ8c#^VZ=DQXVuGM#KXIH&1b+KydPYDXGw:Gh:/b!/a65uZ!9kLGac5#L>nc*iBI*%J
*AhYGN h<M>8*>&9>&9qC1X+Z8>6i/qeP6>y*+iqat9dG!>XA1>H*\H+=:VXn+%/>m1:&ZZ%L*<@M\F*^pN*5BP
BjWa=P l4eD/K8ZdT@a1y\*ayY6&j#i6HZ4:q+u$&c^qK*G1#ti5uYG\6n1<SbpSkl9l^Qu:hpe#b$qP&84Zjtq
>&6LwI 69LS&cmV+W=M*N6/ymBuGS==A?44JX9qId:iP*?pwwkjtl##>jDZVF%u^Z!:kBE9$hnlbW:I*L%^Jn4V
Ie8PJy 6<V9M6/?#JtnpStKpitM95/F66K8/Y&hu%>id/>!\dS4!^9GY+hZ#?:@pjy/%6cSQ^w=%4w:MJI*mYKX
YYHa=Y tW#F*=q8E$YVK:*J5LTPH$:IHG?ehSq=&:MP19A=6t*XNtaZZp@X&4=Zl?m$%d&<8@6/*=Wu%EZqEJ<^
L=jm^W WH*Xi!B@?eqiaW/GR94t>@ejSXnqepi<c&Jh#cd:u5p>dl#qtW=G^dBVL&jJ#t^Xib=*hynKpmu6<JNt
-AlGR1 000578c1a5d00110334 Page 139 of binaries2.zip
\uX&<W \ECb&aY=$tNm=QTTN!bVa?F*qKuu\e6uVm*p6iqjjZP>Y*$C:!85<V!?j@9&h88@>^@iLt?#>?P+VdNa
n:6?TS iL^<iQ9%Nl5@nN1HbiVN*@4^QHy+/@%eSQh9:>?ZD+?SH#%<!WmZYX+#Vcaib1b+*:i<iTN:*NdZ6<@+
$qql@t I@u@*qm/Ha&eZS8y?Ze!#J@:Zna@*#V#QQLAi>X>QMd$hV5/A\?=HF\A:pc$YZ//jbn@j:eQ:ejdj@:&
pjE/:% :yi@@##/>:eQY@@46@8Q<*jjQt=H*=an::S6Z<ZSe9T=@jT\LN9d@@I%i4ibQ!l9\F?%nL/9ZKPJM:dm
YR=N+c A8X^K8I$D@lP:@n>CQ!XY*:9&<NlIe:&T$%A^l8nh$Kq5@M<tW>V9FYNHAt6GaS%DkaRAZu<Fy?!?d8&
JHl=TY jjZ&\j6/?@QuV&<j9u:Kwwh=>C4/?iQQdjS8?!q/F$Yj*<&*$YQ$Lw$?iX?@!p&JQ4=>@@uhJ%F\tATc
bwmwk: B%wS94I=i=ZupYh+CFhkjy4PpY<Pi<n4tqPMS=u#Y#+9Ve!CN%J@R<Eqj5TL+4:+?kItDq=G/Du@S<ZD
8/!a>d thqS=#e<Fi4dj@:!:9c@#N5m@9#8>8HL1:hjS6u!N9:/dj:6+/i$LV=69u:?/N%@Pd*>>BC>??Xd?&4:
P5ecK% yT*p$e6*=Ye%6IwWM@Q=!4<L<GttR1*W@htSGNu1BdiGtpGny++PJN!:q^q%up:>u>qt6iKbM&e?@c5#
Bc:>Yq kZcjFN#k^Y?nB=HlWS5>LJi*:ihq*D/Mw9im4*HW9w8?9Z5d@bjVeqR<6Le^j96q8Z!W4@uw/CE#l*\S
Ea/e+h QKll&%/AV>?dP?>BqG!PyMP*Syq#q=&ZJ^j>D6L\Miyb=b$/ZPBkEi@1TQY%\=ttBCNDb9QVk@CVV>ni
X5an4G @4#>qIIQ&*I$tw@t&b@qcu:$Sl?NZX99#%@<6@EI$P#Qu$d**b*##dVQ9@Qc^4TSe=+twh5L6kK4u6qK
D89Pi$ ^jjP^HiR^8@5tIXRw$+8S4SA/kMw\>6S=\u$W<cdll@=$j!ntCK9+D?=N%9%>JtcB=1IV%tH=:/N=Md+
ly$d/p <?LB@/nA$+^pF&u+Lunyaw4MuGjukm@Dq1*BWlI:58?NiL%u9wMV6H#?*NSjZ!B#TMB8I9ncPZm@8!jE
%V1^de PQnG9:@HD#PGwiaJFWM+*#%TGITHyGLl=XF@uw9t$b4TZjM6>S/=8P?T4ZMHk\$w#V6qe$nCe*dZapu9
Z$A5J+ DH*ubknP5McENn6@+hA^bNl+/E\VZ14$!u6e=Z*1jtMKwZBKkJS=M\BKWtBB\plhA^EJ?iySFA$Z<&?&
Ga=eXt :hTMYMJC4&%uR44a!pYC!u=j*eVYaMSba8m/!NdP$@n//8c:FM&1HZd/ay?&&j^u<b5kIYw%SL^*RS@w
c4!TXJ lFeAhYdD6pSMw#MCMpVmcTntGje!Zy@DCY4\P/nun#4D:GIe*=p\+=W*8nBX=Nhed?qw=Lk/M9i1LDbM
L1*Z*@ =HhwFnLeSjJ+q?&w>H:$&1$Z?cu<:PP>$QtL=^YW6B?*@ta?K8XB/Z$/?6u:Yi/CN+J$n?YbZquI4@*W
TXMw=I 8>@M!@u>L/Q$djp=?%HC>*ty:=!B^/c?ikPe8b\np#H9VLIbEE>6JXmQ*%4pM64c9i\kp\QEyMEHA5E#
h5$t/8 #K>a:Pq4@GwBE#uwucJ*!+h&PX4P&>9Q!%Q^<QXXQH<dA\p?jIyGy*RbmVu?>8wlm6@GH#<9=?Jj$8Yu
hE1mHK 4dmtL>HQ$e>6i>8?i+\?j+4d?Q&ZcQT1?C#w+/N98byMeaJQA<u*JW*WYC<n>mNEWQ%tLp8llPijZ\Ai
ZQSqp= \mEG@+\&jQXEkP>p6cAN9l=l$y\=GH^4t8nN@@:d@JQ@8Z*%eN4Gd*@?<8u^u\Wj?NF@m4c?&Nl*&in#
1e4t=P 6*jCy!<j+/@q:eP@^M9!<:9mIayGjl6>99%<K/DnZj1y?Qq#hQ6FwPVYF>#%u#+=Lhti\:V6PX@SGS\#
Lkn49h e&1J#Kmam9yhZ5j9Ep+K+M?Y?mKy%:q#m?w!!<GwY#I6ij5\il^>mh@FZ^/m9+>BS@61Qw<j*6/Q@9/l
S?X:N@ PQ%!?mJ$ijjjlIH@e99\Qwy?@9\1?8jq=@6S>QHl>GQ:>9P4V@N*9^TC5:/&T#F6:+T9H$%L8uVY%n?u
5kbK9p @?aYB^9CGZut%=^=hYCpR%HPjtYc8#\:aM<=FM>qCDVlb:acMt#=A+4H/NZD@V9BQpLnq?Zn=&@L^&@6
6L5Ak@ P+q5Hw1H8dD^W^F@?@lXZ4^>@%u\jj#%$?dd%?Z6%*<SEZ@<>Ph9>><&dZRdj>\<jq+Y*:/$AlyiQZ=y
JhGFV! Q<WhX:aG#B\Y*Q4$bS%d8\RRuYi&QTeELyJ<=mI%h&tI&&XEqEJ*6?kXGEbwDtb8N+&te@#b8+?&n@Hd
w@Ck@M id^=9*u<>$CJk9el\<8H/Qd^+e8*h/QS?HV@8ak@j4%@8@*=dj^n9H!:>h>G@8NDJK4>=?nHddR>yXE1
Zih+6i NG=j*We@n!L@p1*d:1JyH:$L6yIhb/>n&Mm^XbubyYE!^kHde^LWX=R&Q+N1l=Q+I9T9?4wcpLRSM!e$
&lTi@< =9LI+y?>6+KbItHe^+hQT:@>DD>$j^LqHh%&ii1q9MC4%9IGAy#p=a8Sly&j$p6k%/XA6</Qbyw&<S\:
quMe<M @R+e$I:1W+#m#AEiJ?Fdk\&i+RyN*Y\:WD*!#9B*/>P@i66#>9mi<pb>KkWJA!HK4#:II?:V?=>Ht@u6
ljLMNT Xq=\$&XaiBpS9uBb9yHeHh@iZN*6BcwhGRXtalmNc>ydPhbyt8Xm>CpYV#5n$/H*icatX%ZXElQ#M/m?
=uRk?& %@naW1\D%Xh*C#!H&ibhXt&858J*B6FqcN#Xdk%6hjnWeZG4$PSj5@X?:tBlypl4QuKi<l#+nWbu65+6
i@1^kX AiWk4KX<pAK\8EtVP+y@@XF&B6YKTpbu9uyhZWY#JLV4:61&9yMXM+k8p&c16dXaa?8?=N&=:&mdj^iD
Seb:hq /kX+L6=!VMmRi#AC=m/@aM@X/@jXeGZ*b+@DY5NIaTwmd5M4<*NM%Z&LYw5HQD#cYp\yh!S#?iuStc**
w!4H>: ky1/uLkBX^PtWbeH:&Iy8#5PtH58>?Qy*Zh&kT?wTRV9AqPaq>i\^uiJKAMkI?IEC!Qp5/hbClW/Djp>
W%!lkh $1:Q!KmKCuJy6&CHmX\6N#IjYh1&a$e&Yu:JP5p$Z?D5k&YW:%tV<D5hJKm*#NBI5a1m+HM\&tWaVT$5
YJDXmt <cDmhqcj5=bdcTn46FF>$npbaG^T5jDQWi#IA1:6RPNZb>cJ!@^Pl9ua=iuB/cYY*!+KA/:K+Y\F/Hb\
yFWd!# bt:I$<Yqw/=Glkm=5++Y$5@NqSIW&u$ibc/A+NLNYYa%CI69PpX#4<Cj**jBuL1!8icJNe=^*u4pu@MH
l\9TCa V568V/$@?p+b6W\/@::Ea=yl8S<q\ui/+X&YYe#9&C@tD6abFNA5p$u:1A6/ZNdZuKYF\1Q9&dw%Sha$
@SB&BM qtP4R+4i4^1@hyW&qjF#wpkkBNq1bR%qtne@!:AXmBqlKA$bA$$4Fy@4uZ/ZSZVlKqH96tQ4ZENQI<5*
XIZJnh 8>VhSF@Nh8hi!hn9&i4eC/&EyRp%tmXDBlh<6e8@=?%&$9u8hKJWM^QB+nF<8&?y9<^met@8It=>DW&B
thRMyX uduuKNVd/AJ:J^qhpDw!L?ZWl*tB41/qGKk414uC:N!=NkQWXkt%c5=IL\etTiQZWXeHWpi@XT\FYycu
jhX:GK d&ymQRhiGK8:&nB@aiplM/k1G51uWVd9BNi@5P$1n4#l&#NdQW5y1a*S/H:8ui6c&/=:RBGY1:edZFFy
GBc:9B 6d1e*$ZI?mInm%@>5%4QNe:\%ERJ%D8h98IZtT8jt@@1KwjbjP/1&9nutZScLi/eSSqy#GuJtJGbBuF!
ly1SbX w+/6tpi\?wDJl*L#k1$hN1TNeQqF8*e8TiEd1LJ+a5V5Ci89yq6#M!4icPSKdjjC%6QyRRG4d%$SCtkW
Z:&BBG b&jKtK$qRq$8^Y!E*=Zb68hIqStDi%dtFQ4Lud%*BR!9K@/=c@KhW>hj?!=S+Y4XI+QLjG/Z+RVdHX6>
V=R?Hl LSYM4F>m&!E!kkeIlqaQdwZW$%jZDKDhL1+/6n&ZwL^#:$VHX5>^uBk%t&?>#qSyHwH%abN*K<eSG&SY
!EN!Xu y5BZZyh$<C=LHDDGYYa>PJB>i?:IqWi$d4K%GwtXLe&@?l$m\@P>H!Y\aZ\B6y=PKc5^qP!Peb=CI9:C
6wSA=> N#%Z/P&I6jDcRHtZue@Pq9PeNHR@*HwhAP#!&S1XK^:S54:ZNTcyB:t$&/:>S+H$!B\&@:4<MC:Va&y8
IwQEV* />&C\q@\GtV4/jS=:mV*j8:A?L$^>J!hlb!b8D4Yn%#htLZF8bPe4wn5u/9NV4M9Ek4P+a\5jLHKccb$
hT46m4 u/9/w?@5h6i@NDyZ\LZ+@+?YH%d<^e6@FPycXVNq/?p4Zqt4c/k6E*B:Kk!b!@S=ZcW18&C4b+1VbSRD
%j9uVZ l?P/%muZ\uLJ%yHqpnQZSbPy!95Z@WEZdN%/ZiHIhaH=uY9V+w=&1e\%L&GSMm1kZpST1djG%qM:G6&K
i/@i!D 54/Zl@#+:/MN/4iQ@#pmA^?LS+K/^<eQiQY*<4R@Q+\R1e@uQ:L==@:>a+G:Y$TQXwL1Yk\8mk\ZdLZY
#e9yHb 14tY\DQuhe&h8u/MV8w9M9H#:@5XZKbt49EW?M4KwCHW4jiYC5yZhY\>uid?8\j9:Sh=@W@L/CT58q<8
hRI4H$ q=@qHX:JL:@I!>@!TcQSS%^H/*puCN!uB:\MjkYNqCh?Xy>n9RK8%<Hdj5hY%%4q5tDK%1=i*4X4ic:D
?W%\my \uiJ8/=jReXLHb@Ga*BP%Ni6&tecV:I!Xwju&C4ZPl4D><Dc!S&Aa@C!Lj#8&*n8j=Wj9@%MT?6@VPWd
H1*p/Z 8WW648@hA#V<:aQFcQ:w5:tTT=DwhVDJ\k6u5NBFa\lBaauZXj?:@CHV!PcA6\k:DHX58<cFpi9T&nJu
BP9G+S /6wkidPZFFu1>yt6y+j5j4p=RVdiS8$J#+?m/J5<@6PD>?M*iZD^YT@nE=V9*hh*D*k6=i84h5t+I+1Y
DN8h4p u^Xp#huIh^FNZ:DX8=@:=%DeIaT6k+MbG*9<WReaP%!#hSG5k++Ktq&8BP@%n=aj#1#\wSJM1Zy:P6M1
qi*GKV BG!@+mW?SWYMl:b$T69dl@u>X+@@5/ZlI/Vj@@cSF@?P8cyZ<Z8?iW6>6X#CHDnFShQd41qN$>nYWP1=
l/%uyJ lC@>l6N%:Zqn/Gpt*?wI=$c+:imC4ihPE8&Z\D*SD1MM?1eBMFB@/&kXc64QAE=CDN%C1<HP1=@LEw>@
J?eX\+ ?&*#I%:@I<HtM8LFj*#A/:#>jQ?LZM#>X*aSYiMY6NcqWc!J^!I<^a18^Gkm*#XEPalw9V4?yej#LNbS
w!<Vw+ /Pm$qVDBJ^T$@1a=im>k*MBYDjik4V>@Mq4q!Ti?k@#kK%=F=Q6BHuhL::9%T9pjw9GJHa@9QkQNRB9p
<%Diw* Ck5%Y^=jl8=Ze@&cajK5p<^cKdS@&B<^?8%/tZ\N?F%E8%ZM=I>eE/Am/H8aXw%cHF+*AKAJDy@>Vhw4
m%k@J/ ^P!45FZXQaP&?mQHX>wKRN::i\*J:8@%%yi<TT=+$lc>L6DR+5!>C8i>wky9:mVZ8wCb59T$Fed%+Zn8
c=pEmK eb/Lc>ki$WHEe^LK<#5X6R+c#Y^qY6%mBaC*h&V>Ey1\EtkndFNnS5M4$b#cy\i@/*4#=?eiV:?#>X:u
Ay%eeC Lu*e+HqZ&HeR=1KB*CFtNc@5hi#maaj%:y&q9wCCY+e:51=N6P9Q6J!SyVi!Lln#:GZytlRQ1:WY&\m^
C6=WXQ $\dIh*C4I@@h1jP*F1Xwi6Ajuc9iY^ji8FcZ45LkuYQZ:YZB\wKH48jbBhA8F?K:>yH=JXL8cqpZ9jw8
X+a:\+ G<Xjbhcncd%/te8EG+i548+ywFw/:L5hqa^9FF1e=1+Bh86<@h\\9tYXP*jy8$+$i$>L<pNCL@Cl5dZ4
-Aanq\ 000a16df7aa00110334 Page 140 of binaries2.zip
PB!#NA <Qc:>JDjDS^5Vb*Q96j15h9Stc%djZZXa19j8&L>h6Tq1nTVcQ$T1uR?!TKD9hEu<VRn^SP66R$RBdM$
w%Z%uP XJai&/+>5dFAYNu<Ipe>K8?XCb=Jtj:YC5iZdM$MWa?/w1Wl&a/6q::Z%YP#46Vcqaa!K<65ZTd%*1JZ
Z?t&cX q+EeYX:C\bZSS!XL+y6q?#A/+c8T6Aw8mASQnG/n>:lmML8FF^/yGbaj+@1ntJe?66nB@#GKGK^EEiAn
^nuw5W \5R8=FBhh*#NLCQ!HX5XL*a^9dL^Wwa#l^w#X>^^QS?W\Y!$:dy/NJNw?TcB#&IQmbBG6MbCNM$&jmai
LKAyjw X&:DF*uTP=m44YJH8RG$ZF?aXyZH95PQ=NXQy&nJ^I$<q*\XnPuD44iI848iwZPu5*=e5NZ9&5w%\FGJ
<lwlhB eAMLZb?#JiP<WhjN^jSYB/5<B:n6!d>19mqDM8XY9a5@l$5<dVVV\9nX>@=FQkppFKDQTP@>@T?S*B/l
?n^bNY 8H#a\wD^q!jS!R\pd^Hj+#MyI^KnN:6*4c??%kK5aeh*8RL@uFily*B<6D/A4R*6YJ?YZDZV<^hRWhFp
\b1>Y/ q+p^\G%^wiYdiM@AJSl::=*=XHM>klKEk=@q&%j+LLjpm#ann&ml?jk=u\:j^u#!S\nAn*ILQPZ4!H5F
#c9SDL 5/+AWHM8Lu&y%1XLyG#Xpb4G5%GRhq/VME#Edq*8ym9bb6:eyRR#:elY+PmGVDVBcj&Iumuj!ZMB\Pt4
PALYm? B=BCP!^Q?emA:J*<XAkYTij69wWyW@P>IVDc$L/q+LR\%\hjQYC^FLuZ%4@5*#By6T4/iYDI<?du?Swd
wMqDH> ncHHyMJ/LyFl4n$:h:6*4bbiN#um8>ELFSuLN?Emd5*mI6Y9REKi^ADX?C4IH#@>mNmhpuGQ&!B*D+B^
SDcP6@ QmII>H?EGI^Iy5kE9Tj+P1I*<%!T>=!lMa*6?pE$\>Sqc#1X>4w/1HcF8p^@=@i6k*d8ud9:PqPwpIV>
/Y/dJn \>y$Bk1@bl%j9^B9jmKpGGXPl4@+CmPhDNQ?RcZFIdik?BZ9q@^tR**FJWLTwe^?q$D^qXXhW!dT^N@#
DCd<&E 6^9iedqtdc45euI81b!=bq9HXuj:HF9NFEJ^aJ85TpDB=RM?cWINA1X^h!diF4aJh9lik*cVaVmQ$cqh
H?C9%4 jyN9I1RwlFc<C#n>I:$%96:K/*#SQthN<44L<q$X!BHqc<uLcHDJy&%Zliwt:c^QehRq\*%L#X9K#5Se
4yKH!< w&C6#CGtW\N@4+I4CPGBTny*<T\w8:BNIyuyQX4*6yBlZPd>/e9HXlkc+?tjpItD*D=AZ&p?wMF+Gh>T
:nYFk4 m8:thp#aht14w8%%E&TMmF^9jDb*Pbb#pjbm:M5@*\:ZTi^bjbN!jp<5\TVF4YWM6=???54NEc*uChqS
:>1RS6 Z&$VCQq:?apuH@JCa@B%=N?iQu>1SSm&ayD81e*K%^Git?G@:c&?u1>#G/P8YDp/F?ZQ!WjZ@h+qu/\R
Gt+kM& *#Y/beyQ4=6N$XE&/pW&h#Miln\%u\E=ke@S8@nKMwcijLyq@u6PJQZX$^IYppY9lHQChP>6FAEF@V*=
W!Bk4e Kn>>iHeTA#WHYlBVnVADV9qH<lX$y<9VN?$!6Zpaj?ScLu*@4Lb#K%jQHj/%Gw*uSnE8Kn5&VHy@MeBp
D/R%E$ a/t8@PDSXN*V:=Dj:NHLEPY?W#CEAPiB=R^FQmiZKSb<JL@:A9/QQtpT1qV+@P:$eH6/YLamDuBP8F?$
?&:L*1 bje\Tn=piM/9tJ9%Lii$QVjF5@hKA#l4&hK+p<$HStNtR*m?>bXcn5&KMc+HKLP!bKdyLHa:*X6VA?Me
@k^aMb ddY\TJWc&n=\5k#k:@R#ahlYyFii?W1Mq@^MEQ<98Qwj/a>F9pXGa/H^E\*8%+^/@4AXEh<1S6\5V%&F
DZ\9Hu \#yB/AXX>4#6iSTFIaML$6SAYbMIDd@ZFeM>N^HD4IPYkRk9pJ*1$55YhiwVNRiDt&XSPWZ=1:bl+&ic
mZ\*D? uRRWELA6hlmTmR6h!t*^%bEIIcQVX#HCRnSRBG+P>BXGCZhM@u6H$*cPWlZ5u45181Di:^w%Ml5@PRi*
I#H5Wi 4yd6!y#*=tt!:LJEapuD48#jkSdtVFZuqhc9T^XQqT>^yjb8T+AD+i5ZEAklFAIS:<\X>9wEqTLM<K@!
4EL1wS &u>GL8NHPC/SR?kBtm/<m&1@nRN58>!G//R+h#AwV4<Id48yWh@F$/:*+mKi#/#JySPNd4cS5d4Y^M:b
=b\nm\ aLYpXD1^MARmI5QI8RE*nT^X%6Kd$C?%qt5VI+Ya^!N8I69depT?#wGT6?h?Ah@+/hncDRjQ#?ML44&>
TQeh:% K?S&W/M8DNC1IKdnP:cPPpVGY>qqLpccM:W\:+LYL&4@kj8@YHKiGR9=@AXpRVKERP>HA6=dWYLeKcRi
VY=W&e 9+CbY%?nQLp4!%n$Hn>=K&4MmP5et6wp>>p#dC>/w#X+#^^!eKWLG$d6B5T:SqLHj18&8l+V9^9m5X:y
mERD$> :EKG?ZF@q84QtecTH$>j&<\D\cKSD+l%9=C9+tjlmLdEkD@KX%BTGG#^%EK&cP<Da#1XBninc!^#!aZM
K<&$6M 6XQ=*5YpXejYpd5l49P^t/H*taWd&TCwha8hA?Q6yR/QjLh#aiTjcj&1A5+w>liXi?H/b$GCVQGCn!K8
q@M^=> 1Z@@KBd&q<%H8KNZEN&6@EcM<SiQI866V1hd1DHq?S&iNS1hBW%ubC?!bq6LwZaba<hY=*ZQ/8y%FV1@
HV#YDd c*9Q@I68KBX:T#/Q#nJ5dSmj#lWNh1E\^Q8t*Z&Clp/j/aB^<+TR$dK>pIRHqQhkj1G=I4+Itak$V5CG
?*1P4w Y<b$6\!D#R=qZR6MB\c6*4<huTj5HX5=B:HXD6K5p&d4N^nb$wN8F5d4?qK$YHV8nLYhC^IH9P55$:dV
e>CC1P *>aNc<59Q><VPe1L9>XR@1#lKIFApEX4=iEj<cPjQTCNE#CX<uWPidqw+yk:I/W65IadtKF*A%khY:jY
88Kj<t 4YShdVdQbLy1NW$*C#M!eG^nLd:ZDSn:G6MBhuaX!M>5nak5R/aAeu#@T:whSXHGc5GQWjR#i1tF/QL?
F#J<up q@JH9FqJuLZB=$jBn:m<#Ya#*^aQy1w@qncAw<u=<<TKNwX5dcdBM9=iq@9ZTyhP6t4VS9iM:B#K8qTE
+Nuq19 =@/dP=^lA<at\*QYt5885A\=Iqhh?PBhNQ6%ncH!XWqa$VW4#4N#/:ptd@udi%ytK/ti1?Ei8VP*@$iZ
X<LWu* &$!&*!&Q<M/ht>1E%d&JG&/@!Ih9@ZNI::q?QB9FbE!u6YdueETtKK/^l6EZp\M?Jc#LIHn*Cm8e4V8*
ZjyIGW #^pSll&aY:Q^N&@8QAe4k:=@uu/h8/bp::8=j5QP8qEpt%>M!Q18=6:quK&C&@WthC54?H9GhNwL>M:X
K<&l!? Y9$@Q::@#^*#Lyh58E$Rqm<c\%ch&hw6+NDB9!/Jw9w/:%1:4NQ+aq4#wqPpi<^=&6P:&BHnZ$#In9!8
%9ZT!Y kZF?$iHdyW1*F?DD:LDqaq*cX+QIM+i<m^tV:inm6w+a6GXu6u=*5ieXJ@i$\%%Eb9hqhG/!>h&e<+X5
D*#np9 nnwbQ4i$dM<FC=h!eG^%R$nu%y?8MjCeDthMy+GDAiJLpNW%Y4CyVuY5?$$&b\d6#Fa!$/WPMyhe\k9d
Caj<qP 6w!8l>/qS:1SX+M+F*j19Q4FSjJchD6Q!M=>4$8@<DZ8HiJ!lcd5ZuHT9VKVhZWtue$PZ$/5hZMm8pNn
a\K\pj *k&d8N@<iHII&@bE/h!uqll%lR@M\nK%wNT=Sb6+hl%:Lqj9BpK5hc8VadiCbj/h6w=5B9ueLJ%%SZiD
=tc6i? LC/D4PQj@>n6k%G&j4Md%>qV\#1iW@:866I898&t<$^hNekeud5=<iVd4dWctq8$Bu#j>ZVka8=>=KQX
/H>q8y tq9R4ujZmuE85Ya%cpWpYdh4!FwE=^jN::1Hw?8hbF?+C8q6X$EjuWjAZW4A!QHPA+!<i>&:8w4@!I$i
PE6MPw />CA=>atiJeLCX#jueZV/Am+6>1t5?dY8Z9iE&B69d4B\T*&Met*$b^8CW<*QtClP>eabX1:$15lY>6N
Scjet= q*Ie?cM81P<tw8huV=yquS8#L5@8Vc!=W^6d#?XD%%N4ya6Mt\K&Lp$^etPyPuqmw!aMFN#Q64+#<iiH
94Ink6 +Ltb%pB<6<!4/:>$M^Rc?&1hV49L&9ke%@4hZNK&k\X#E#=Lhy\h>\Zt6CD/wtTihZ8/#pG$h/=SiS*n
e#@yc= ZZM!X&>54VC@hX$AL9Zyh/%4=@K$y1QPWjy=BGd4aA&i4jXZBCbS/T:jNjY/E5KwY+S$>wdd<&!86@W8
CI$#J> P9C**R1?dPSYK4k&QP*$$H9A\i#LYS#@wqR@/paVL5a<8unQXha#LX=&K>*Plj%#Pem#%u?<w>ZX!=<*
9CF8lw F:5&4E@B:i8+>:wqEBj#Ih:e6^WCXwP=GB^^+=Cn4udphl?MHKI!m?Phk*V4#jLMIlke>T?b:*4R8/b=
^Nn@RJ j*/i5P#i+n\C5:YGXX%CwnYP<*aLe\!ECQen6@@N+Td@ItPpj9Hi^lK/6X*YJ>jJ4#bjhd5QMw6A:=&I
<S=R#Q bG+^Y#d9&pSHdmmpT#1eAe*F6C8@/jyG#?PGF+u!pjYwpS*W%<\b%@MmLFJ/*=ZBSqp*i*RijdSBRL6:
meMWM? &\6SW<@9pKw@u%<5LXV:$mH5$ZuB*Nc@RFdb8jd+udaTC!nWW#H*uiq^KeS5jt@bX94=4F8!S#6<MV9d
Ll^hpa VhX1ThdThbpDeG+\$AadZJQS*P<&b=\uJ/%jS*@5uaPBj:%<#%Yh8@YT&@Q<tZe^qGZncF*!<L^y4e9Q
\uFu^+ 8Kc>$dpB*eXt!6j8X5KZiJtD9d\@>Dni6kPnPwQwmpl#q<:nP1q8SeLY%@a^V@jC*j9t%d86AcN#9/@9
@QJX5t ?>$PCVhe%+W:d56pN>Dmynje@nw*$8/:9BVnHQ@i85y6\a<L+$Xj:$hhZVQnpG?Z!QZeblWF=1/V*k$=
dbuBqQ &t\\*5FV@G$ych%Ya1cEVee16GLq89pV6?llVwq#Ycc=4tP\WTu<TF/L!!m<i#=i+@QM#A%#hF9DQh^b
j\V==@ \=9w&VI>\lu5>YKQnQD%j%VDq<%@KiX>pM@%@$\uuyb!ITXHcLnEmB@mtEd+Qy%4:?d>L@KMH$iy@J*L
C@bG!l =@H>L*:/=*V?b>!P8S845\=9>n^$H*Q?^W?/iSYl/e<n:<<eKhCHkKQ!:B>H<#>:<4=yq%up!>Ib<uGn
hD8eL@ </9mF*<G\ZmGkk:<uH8=jqj5a9/XD@qe!hjXLt:mb4iy=J8/11wpcR:JwY4pI#+eD9J>6Y9mYH=d/JQ$
9e=ZYI I?dua6j5<MC/clbNZhZ!#ENhJ!@6ebt$!Yt=QLZ+PB%Q!?N!8V\in@LnJDpp<5l/hnkpVT$jiGBhN@XM
XJekD@ *4/wh9J?<nuGhhXXWmZ61baLT8VXF@Lkk#^jZ9Epd!DQPVTHCw?SZ#b+>/VYn>qji4?#K^WclRC=duqN
4DL5=w WlHLBVhJXelu9tiCK#4kyiZ>K@^YuqGRR4%hJD8Ym!4p4#!upni1G*!SJNET%=/$L!j=T#k1^IBTIj6+
1\jG^q ^KZIFewhVRw</bBE<9Nc*m?8<jc+4pc8Ct>eHc1/Z4d!HLp9qXAnd=NE$it+qL8Hc/^uwBC@pH@NIVbm
MkwIlp D<t9=G85#JG4da1CyIK^eW^m\S4?c\/+kiSB\l9SNE+cLlp4dMXXFjI&RmcEADjw=iYqnWn5W9+h=d<q
+PdPLC 8C8EH1Qp^VFY*1LB8+G^\n5\Ti=XAdd8eF%F$iB8SQLeY8/nZMmBZJXZkLkeeZ8Ew*I@KB/+LZlBJjcu
BJJ:Ya *8<c8$yR?S@p@pFY!NlGQ?TyqjD%aE@BK!6nedPN$E9Gk15R9C1tEMt%%lYjCjbSdpYPq^SpwVS!jK%X
wYPjM= m9EZu+SN+F&#u\T=$AkbN4/C@T<uwR/*WTT8\c&EjMn6m@SqXHZp58XiN:\q<6FAly9atAP>mKG8<lQw
-Abl+F 0001402acb500110334 Page 141 of binaries2.zip
C1/BYt 1nA&mR?+=5wJ@SEZkX8ckCIR8!8?a/#e11cCFQPGLA:<kqIY!j6FNZl=PpXW&TWpYeR+\TWKCZKFXa#Q
CEuB>p =BZ$L>qQ!uCY=:^:e9QqLctm!^NqGF1TJMwBWa*&=aWTJ/TKeaEwX4^9hm8FX4AD%JI+Ew9dTAGY9<I@
^mXT1Q pG4TK#ak\R6YNFRNH8\5Wl!dwa4qA:?EDqIIE?mM?^BbFlyP$jEE?>T?6QLqEXwGjkmbB#\L=m?Tl^\Z
1Q>CZR /&\+DIJt$#VW4EQSpAlSi>AIhV/RYlEZ1MeSJkX!DZ&k<FIPD6VB9$Bj1=%hcWMdLN@KK?>WbtD&XQnB
u@$E#h $\kZB\6RC:jB&Gy*68Jt1Bw?5+D%A4EmQQGl:n/EVKE&Ad*WYJHWbZSMqF4KbEZ?!tY&db#uuljpVhCE
nJ?*^N t+atBF/lcyKY6wpYSJ+kL!59AWQRWnIw/\*NZRX/ijYHYt^VR&Kl4&yFcb6&cyy1pu8wXQ%dGBmcAEwe
Xeq&?= bHnZmc<T81QFNMWTu>Qw?%WHS$$p%!uZJC<Ea!J!h%!?9ET%8*InYjkd%j9%Pkku*nwIb5E5DB5%qXDV
tubJKS 8lb=yTmwX<HXmV/<6Gw=%adCRCYpq!>J9qb$HWIwhA%eEV1Fm5wMRRIl=y$V%XyT&$/Rj8G4iwQmp5:a
948V\u nFwep@P+8ZG6@5y^Xm\9tEuG9pBuSXcQXCn/CNGPA+*cjnWM\&A<CINKXFcIDS9^&HnQR!JQ4HFdSLp1
qPcJY9 Q4YNcQH\hh!a@^J^lCcbB/EhlmqZWEBNle:T6=4npSiDIZ5BGPCHMPXEnV*ABME/tX%T#SZSkFHnSSEK
mESXql WG6=d&p^ldFSK@c+lwPF?+F6T6S=1A&p$#qMi<M\CMK\N*\PlLQ=LAnZNFG$Np5KF&Yh%B:l^iRY<p%A
T6CcTi +ALEAkZl%mT<p*@y@S$\BJm1Flk!VC&5#G@ISe54k16Lkl=^&mhiYkYJMq=CaRp5=KpWaH1IBE<Z6Y+k
!114nX d5ZBMXj8&%L$NkHTEbYXL%+we:mw^ql!8P86k%#+Galy1tcXEQ6<CGMaPkI=pc?/I#aBTmE1mTnZpI&/
55:d^@ Xp4yll6mLNktYHM+XF=+w@Cy&5ZKHNl%<PTFbyMcC#\tpP6RKje15$8t8lRLG9=GnXPnkPCkPAF?S=BF
YZ/8Da C%5mTEi<n#Cpn6T%R1&yZQ9B6bju\6akjJa@Rt:\uAeAKKITwA$Kj/nQIpNH4VJMNKD*kWIFl6E\@>4:
Ty*KE\ P=4htJycNE4&nkcQhllYZY:Rpm\FG!LeXHtnSICSAw1aTk5SNkmt#!$1BS&X8PKEKk>nyc+Y9E%k$yjC
C@&!EW &^MeWWRMRFMt^t^/FYc:tSlkpJ5H##Q=a1?tu@=i^E!eu^klNYimGTLA\w!InIcX\E%Y=AuATJ&F98JC
WB!D@@ K&11apV<W!SB#AS4BuQ!euLaFdCqFW<a$5qYud+clLLuN8ypm/a^m?MeP*qLXIEdCAjW$9+TSPDQwi#:
C9t+^w abnt\qYlXkkXaR/jN+*!Fi+TMw\41R!m$<E8%R=DltB:C+yWWhMlHBR*+ZILk:GK?kmekA+F>>PpJApq
Pcq5K< =Cm<kAVY$TqK%85\&G#YbdpSMnj<A$I6HIElBu:B8^FFWVm4S6F4BAWVdnIREGE^NAGqpmj6:/=&bd:d
PD+8CP BWH?HDSCcQD<LE:u\ClE4G6M$5Tpkc>PXkBSqwB$%RJ9G18ECP!nu^WcG8l4VASdcKBDLEaSlt#mqlBJ
5SutC1 REBc<jqSwkdtR?q9\6LQ<%$a=pNjCT%yuuaR@S$W9aC8AHhXWFm%Kh?lVck1cBW$WbNa?IuDj8CJj<q#
*qp8Nc j!k!VQtX@=:ZV/wcXH<lV9t1m5mZc/pM6PhRHkGLBIpL&1qGehQj!T5A:TBKLAmH1Z^R&J$<yeD:m^pY
XX!W!> <X$i\a@/EJTR5C#QT6>Q<$!E#W@q1*JuPp8NXa<qZ1iAjNB?+P+8/k+8CpAt%IGdjXG4CnLK!iT8l:8a
<F8ncE =9R%Aj=:XuYbDtu#E9wFkCSuPTEqCF<lhYAP:/#cSkA@Ni:AVZFl\p6GGuhll>Zj+DwbdVLE1b>Lj=lq
lwncm^ YX=/ibduIFm+EG:p*/V$h^6K5Yk<@C?SBBEdnR=kXH&Gm<uLptmu=Y&pZ=Y4jk+<uHRnXqmReNMI5R%5
>?hWpD %E#$cV<iQqNa<MCqaE%GNTawa1!Y/uVX4!LGYhTWk+b^Ft#V*<WIR=6CueYP$66R=b1Ghlm?PtFAAnP*
#Y4w>+ >mhky@\Vjyd?BPVK9*!IV$J5^%eB^BT+w6I\X4Yt1158WXAD?BMwLkX@cyV<9A=A/yYjB^MQDA*+IY\>
QwyD9& qIPlIAwRC+8D!IB!4+LTS6B<@ESWqdKL6&:wR^I+Iduh6E%^w&E4dD4n5qkSBX<Yq%pjV\!%D*8a^&\*
wEE?&6 &aZ?bCj<Lj$$FKLqH^lL*8+a:BFLHGke1LK#^uBM%WEKMeX\5mjmHZyGieS1MPmlFnGSi#eiXwGkmccb
BWy>Mj mTL6J:&4&Y\YJyVLA!IDE189Bh\yplehcamAE8FYlXCN8CwpTG4mJmG&Jq6*6MX1uHnJ<wVEMmK\=*6j
4P9IEF ?Cqe>ThC=XB5p<m91P\P^MyNIG?HmmeaEeLBF5SZeY*tEMVZqmPKZq1tVlk/9RDI:ZqWp^itR$>aK4BR
Z6wuN/ ?T1?aNL4+^8SRhw=KG^m=pq8YbVAW=<IEZFLcRe4IuE\qRpl<BXcGY8YmY^6/GM%8$Nu%wC9iN&>u+HI
j:GeQM !W+NW!mp?mA!DM5\FELLMJA9N1Zt=wSCYwitWiDH8Ein=/ST#\PkTDp?$5KL/S4$jmQE?wE*CHK^T?J#
=Pbe@b b5H$tC#8SK=Fwy?j*#B/phhaIq!!t<aM\9GqyWplaE45@aYLIjImAtpV6eP+?SWDPuW=VcF8b\d%VwCc
tyIjJ! +AHZIFMa1X^X#waycb+IuTE>lZ!EG:6Qk8iI$A1NhSym6=neyYGYwFQplbXjNW:NaZW%/QZ/\*#cF//K
LBh%ww 5&pEN!ZSYu=+He!Aum\Sw%+G$lBy>A4*KtE@ImTlp4#quSW\9t5Wd!HjFCP$1YKHA+mQa%wZ1C##hICc
@$R8Z! C@A!Nb5E&?VnC&FwBm1HT1bEajLjB54Q=#LnTW9IhBhaHJ8dAGilb+!d+HWPTLtEEFc<#C\ZtSW=un%F
!qcq$S Ka+kC+ZT&Y\DEtl>w?n$R8IAPPYiSceVW!b\+awRGdke%CkjlPm@$A+n+N\^+/Ka!iJ6&nHFTchETM*l
tWPq\P c6VnmNL!Y/FaMIZAPSBLittpN4RIWBnebV1KR4*haeHEu4wilJ&6Ja!ScNkH8ah:=RMGm%N>BtK1:/DD
p54qiR mNeBw^wmW##@CL@MWER$RK!eGGIB&k^y>K?tADX4Y^YHA?^\VjeKck8L#l1N6?W!IZ\Rq=j*8^RiB5RK
Tb\>:^ ceLP*Fj?Rq%Fpwj1b*Gq?FTcbc5X\lKnJ9S&Fy5\qtYKZI!\b5YTjVmbnIj!:A!WNmR&VMDX*qDRp!Cw
c*Kc<= J\TITwWIlSn^CGJ5wVYCaVWG5bpJ$S:GH4nHVW!?%wR=DP$R/qTE@=cnSCRl985>*Cn5EwkX/e&!Chm/
tYiakc t/mJ$w@W1EXwWpJ$E$L?&P^@6VmwQCW8m\1@k!\1\+4FPympp\pe%*AaTkk*E*^a#ma<SG<GEZ+PG@Wl
Tp5%KL 8FFmubDREJbGWFipEW?E@tcItVe=kFAZQAtY$DA$%pThB8$MT<GYA?I^CZQcVRmiCl6VE>^$y%AC*/WK
5*!?8S J<+j^qu1DJEmLXZDQF%6Ea?FQM5np@@LJJddNQVT\VAIlYKGN^K$#6RLDRZ:m&qTjMmMH<TC5p<^b9IX
4NVMHD ?59<aY%bdZ%#in!p:$YGNZ=kcq%DupJ#:CTY?edwc!w/qAL+kwpW=q^Mpk<5DD=DZ!jKXQBW4hSieV>e
?P5Rnk dKn=cIZlbC6#bPC4tNH*TD1XkYn1bHk#EKYjiEMaaNHR+VPQpd^CamIIR+BlBR416eV&MqYH9C6TCeD?
MT!ckW qVQCCmeAX8u<twQbylnBD6TX8WRtal1FhmJ+TbIKX*jR$F%KwRZ1l$BQjeRA=C#$Nk$:9mJXNDX8\y1j
/&R!4Y ?aykWnTD6lRj:^@C=QS?HYSDQ^n*?>jIMc*/>KY#/aHK&y5lMTF5uYu^JKc@ql8F&Ic=VeblTMHW=q^l
VE6I>P \cA:BVIFt1T1pJikTCP#4cBpy$lm%!\18@uV+Y=hDuMj&HiZR%WFFMQB:8RG1E$K%*T5aje%9y%1W1K1
5+bw1a %TwtK5K+uuZy1m^:8WYQC?HmJB&G+R?D1#!9k5p/REyC^JnK8wa>u8W%<#1Jl1YIalGVHJec<=>ay+8I
=8GI6F n*GQE\EHm9!lTA\wSX<VhcW:K%uEMi6ELNLSd^@iD^GuA9yPSGkuDLjpp@^5M9Etcw!NwVBMcy&E5jt5
k9Jw!p yNe1hw$tB#VnJX+>Fjiy>dN%15<Ll5QBtww?k:?BZ^Yl@T8=GmDcCRL%aduY$/BeB#FK4YY5nm?uF+d<
G5c>hI DJpQby^k6WqD4HtJ9>MjEmBTtXpu59AVuuD%8^CGTjkq=JJtIZduV!bD#@NTV<kXJl8%P&m5il=THRkk
+iD%&S +=XSjSdMAS%!QPaJd9c\H6MuB<QJ/:8B1d6<QMMMB&?iX#n%>R48SuleCR1y^qh<6cSTk+Nw=/T%IiVC
>MIWSD Zlm4#!14wla%eW\B/>RR?#eH%c8+T=6ccp$VC<E%k4XJTJ*pJ&Lk!eAdVFbDIXXIuunyePk:IpQt\$JS
BpKj@P 5SAbI>#ctHWX!uKXy:\l6eR?1>TiI>/t*?j#R5l8D1HhH*=Xh\P$?D!FXe6:QZZSDi$I/u/SJuJSRTA<
wQu*JX bk+KcwuW>p+Bk84mtc?F<qdLj+kECqcMJjL\k^K+*6hIFdFNKk#6C/E*\$p\uE+twHjmicEZZ5IJ?ai$
YhMRHw :uTtBaRELq$pJXnujJT<>Ky9aj:WE\bi/bNJPpm8ey:qP+T8#kJk9:S*@Re6FCXccqSWDDQiI8l<mSA#
lLTtX/ HmyDVA!h4T/Pu@\F?14Iln=Y5+CN=REQXVDwG%AIJd\y%jNp/hZN?Gw+tRdDhaBphVDJl?X\KAI=NMin
+8j@*\ j?T/=bI*\6ucijR$NidQywQ?St?MQEYw$q5WAEPIa*%?t9dW*aC4\b8ZJBBWEWIeK#W:I1XJVWkNM!^?
Ep5XX4 l$uPR?G\MKGR<BhYGTAcMq\%!uFYe^1Gh$^V!F&Jt>YASlXaAh\FN5\HN#eDaib4CP>pTFKb^yWA!C9>
jieNwH \G!!ZueVE6yTnNbmuqaPYPXq:/1LFaT#\>#WNeSV=KutYWXSlhybhJ#K>?NKZcHGJIL:RP\TqV+pt^I6
b^BW$G ZTGXcBqdbbpBBjmeYy5?+FIVblQyeJT9K\$/\nZl4w@\bnK+t@THjc<@:u6nd#kE^bwuCWVal=+Tw>iL
D=BM1J eEWaC+4\&%ti$1R4:*<k1aa1?SQ>J/@$*E^FYWG5$AuhnX1NhY4N5lQXR96XnE>M4VE:HB*WyVec1SQu
CB%1ZR p5tJ^1<maawVC?a:Nd9GmG+\/A*%mkAIA%mwTi<PbI::w1JD&CX9LQSBiMud9QRtK4%MbD?D8$#dC?ZN
qEuiHA jymDcaES/SV:P&^yeLySdLmi+TN+5<j=&4$^yXMJ5LmNXW=&aRBHCKpG$K!qyNc$wi1Q<BWb4$1qGH?b
9$^8F! NK$a*9&VYAaZkCQTEy@//!D64\c8t\n?Bn=Y!M/H^6^Td5Jbky@lGqFPFPIu/Y\tblqMDl&>*ajTTANP
MWbic6 qDSRG$!&#6/V^:<:PN>IRWST56EA+5kRNtL!cWd$AJeiJ^y@MA^RjRYi11&!b9F/\+#&Q\%/A/ySwNlI
\@nL<J #NLp8n@\?1u<G*6p1u!ITS1T*GFPa8GR\Gc\CFVNtDS1ylM\KVhW=Yl#?64J5al<pBj1YZ5Am5?HRFZ*
FAW5?9 i5bRLcG#KJ^^%#y+Y%5*DX6?tDZW9ybCM%<MB&mHE\WVZWbNkWVa/\&8KeI:^5@CaHENZ4@9Dadn!YR/
-AVCLL 000b08e3c6100110334 Page 142 of binaries2.zip
ND5jY+ VANw/>D*QREVEwcqT1%ec?qJ*A:ydiAdpR\WD#1pQA4\CeK#=K:#M:XGdJBQD*h1k$Z+abmW<N<lYmQ1
bMl@yd w<Xb5EKqyCK^4nGmT$N4nKMkZIQVlHd+aKE1mG*aLRGC<%/@*#NQ9>QkhNL9D\bD:$/kK+R*VIM$ZEPK
dP\pc& @TEnY5GMc1dppwY*8HAlDMlkF8S@tM&c=?d=LLAPPJjl%H/wYl=PD<<pdw\AX5!\18+%e/GKb\9ZpHFI
4dVQuD E6h$qWT8e/m&cNLB\edCLhHZR<^<XP!!^P#t&8Wm\L@y/%$uZ@PhN^l+4$XhkS#GpFq<lPJ\<kt@khdm
<l$J#B #1n=EXeMmWclnZ^>#m9!NcRCt%>%H&8Va<CI/YE@/AAVaATbjQ&pKFiF%+t\8JK+45=hN5tl$S!I=aZ6
N#AuC= kX4nS>:@WG6E\PycXbFk\Tl>$hbAMa=mmXZ@SpV+^p5u6MFAT:C/c#=1+kQFi?B6EKnmwmIDhWZ!Znk1
V1^\dZ H@lW8SklPEeKHi&+C%ZTW<mQ1E=IHemX>HyQL*Ce>BhcBYh4IuI=l/+Nn^$9KK!4^>G$L+XAHqElB+Nt
?!c4TC Ctid1Qbk/$Va&4>&!WHBEeQe/%?J1+H<C1W?mJ&RtaIDTB1?l6:tAm@MT6FGCdFmi&h=FbJe?61#%:qW
HaTbVM X?K5^@1PEu\Fm!bQaA/th>5tbqBnB^JMGXGQ1/*Q\q4C15V^6W5q^S14L^D\cR1MJT!\6SRS/kG8!mXM
c=e<S* iYGdTj@Kk?!Gt\Btmb!hwJ\nhIj1ZIZT$tjCKDBBu1VGYdAIMm#@1qLJDjILa5?B$e8C^Gt$L9T15m/Z
E*RlH/ &9:WYCPt<pYIu/FENn6wq!RdVPLDSj:FLBqTFiB44RGZBuG1?V5I<PCtW!uI1JA/HbjR<tK*4#d:hTt+
*ZCA1N Dwayy>:tNEu!6a>9CH@+k^KeBXqmqpk64jIqZ<@=PQ\<mhRGD=5b5&5EEd*Hw+S4qcJDdhZdGRBEDWN:
RpBPpT GA569KLPVC5G:G?6pT\wMdhY%%bDb%Ia^c6WBFkpNuC+Spn%4nhmHR=Y+!5IMI8A^I1Pm6qXj!HZubcp
^uS55y QGjhXLES?Jp*XNitcS^de\%ZHZ?DuV\lcq@*LEecIG!hRMB/%+J+\VmpZYqb4bY%K5VFYPinh9kJ=Ynm
W9C?ut $mA%KV4NBP$c=^AnAl$&nF#L\Y5l6ni$LBqe#ulKl<^:XYm=Mtalh:NGDl\tKXSMLBhjKy>bK&bM&n#Q
Dqe@Y4 emFV^Skp=J*F5*6yZ8nn<micwm8W$5Y:@lNX6+@&IJbLiJ8FG*YlDlI<Anhhk!y/%T4qc8&/uC*D$l#k
@PtIuK e#T=ZNDA5TXtSddTM6u%qN1>1P>tdcSM9MyQF<SJwy5VAkEqIb%w$AL/%:qAR^Fe6eY\Vlh^1tGIp8L<
D>WD9y y9&1!l1!<915!61:4X>PAuZNqdAI\*=Yc$ycwG=TcVXkqnR8j1WFY4lky/:E=9&YVTy/G+Au16&$D&$h
/RBWHQ @E:6E9NqV%%mw&n&Vj#Mdun$TmX%%Cb:8ikl1IWJhlFPc4DmR%E?k/@C%KBTKF@^luTEY8yFTE&mqWF?
mSdIuw qK*M5@c8JbRSalG9M1hR5T<ynlMX#%qS<=/n^$>BW/Nk&N\K\^=aJNHZ\?JA=YPBR&kyB#e\VMQl&YwW
e*PjPi YlNj8F6m8YQl/?FVjZyJ/nIp6jA@/wC/\GZVNQ?lw1/C4@#VEF5+c?TTVQJh$mwc9KI<#KC51N4Nppl:
9=KTRl Y^84WLB6SV!GZEcaMEtIKnwca6nJ&LDm&q\CD*#B&lW1qJwu^!*d4WTA?+aQ#R:numZY1:1JpW#F5^hw
G+Fp$5 Y#+5&^wSeB^5Aw&*%TRL9WAXG>\Y5Iui^llLWl%MCdya4nm1L?&FKL6Yka6%&DSH@$1^%P1cKt!nhY#a
&4nTH^ +JlN@t\Z$QyGE>ePFEN>b\6kCbRFNAiDJFQb@+$I<M$kDdyd@mT*NDqRX=EX*MkDF%b=P!C>SjMe=?PA
c9Zt\W kD?jcQkK1K66F:GI+*Q+ZAZGYCi@4pTkn%+u/qq:R#X4y1^@aDm?SPbZy!1$$+\DI/+yZqA8AwManaPL
XLu+jA &8yYb+mwchPchlk514Sh6cqKEiDXaHDuCqIC#DuAaV&$naWQ#NItLLpjc#b5mZqeV$\\NblN\XXm6Bud
NK=%Ia J!X<jZ+&?&R!w=cdZ>aHXXdA4Gj^WRNK<JXw+nE/RXFE/81R4i95/YC?W/HmwXDQi6D<Zc*1c1lZt!Nn
:<Z/QW #eHWhk5a#j$HWnyaAhZulPVlG:k86k8y\?4CS/G*PWVHqp$RdPSmdAe9C<P$aTMSd5>caERk@^6/Rl1b
ZB1:X@ unX\eZ1A+PcP\QiK\YAacG16@%RlFn?!8:%t6kGSYPEGk!\6iNCii*RwNA1dNIGl:EpK+?69$SBlab+<
Za1ZGX Nd&?EtX>Qi!jp>yS^D/4^GLHDhW%bAwHEJVN^G!tSdJ15^+!l^m8jdTi+pWZam5F<%jBM<pqw6BAXjYY
!Y%tSD hD>Xcyh/EGAJn9b>qYiY+NEiaCdF>j\T6hhY+>Y/QV1^ap:KYQ1NQjPM@jBe&Ca4kCnHm+F?*Hu1C!TY
d94nkM j9QCP&wJEQJZ!LZ$G?4dJ*RHw>:Fn#IjM6LSLq8Y=+GAWYLMu%t:pLmP*ZjudJM+6i19y1\=j@jtnwDy
%C=X4F mkX$FDDRXLwkb1>$Wmbt^*K%W*LaLX\#wLZ/l8I:*mCC^CbSjaXQmypX@t9@Cu^hii98RydcP<<bLNmq
eF>8CW DaPMJ#aImI&MVpqmR^%cqm@LellMN!TXTE^ih!*elCEYI$u5NCNY$kCAWeQBqQYcma%b4y/%6:ct6JeV
Gm/=>* FKYi^ad>ZYh45:PAS#8^4B:J=De44ajhPV5B9nLk5$!%?NdBwQ@/^u9h8jw*:NyASSMkyLpM1WTMldFw
AXRT:d ?K!%:pY?w8W$6jby8pL=&AMmlm/EFX?Lb6q#/tW>c%Sbi%wTMBBB\/V#cT$MIQ^LnQ^%%+9Put/t&hkS
bP5VYy *dA9^Alt1HPI6iTFL?Bj6YIydqNm8j:41::Zq+C<T*u>TTj:YLqemDmKX$K^#QBb$wn4W@HY8adNbwit
iX#G8Q W:8WuWZXMcA@ADH@S+F^yuEk*e&$TTc14EPNF^SE>K/jZFMc1%KRT#bK86tSRpXa5V%45yme\1SZw&W/
J*R$:k yyTM:<yZ:V&qF^uRCw@:4<e8+Jw8$Y!8deCt5EJ94nqc+G:1/?JkI%lkdIt@^qlPhemdLVT6JwRGDHbE
wwXNVC mGehQ6\euLI&nQjI%n/\wZcqchhe$=lnLG#mmT>9V5$ABMAVy1+1i9<F=%BWu+WA</<MBPKt:Q@Dnhi@
%&TySk GYBR^K:pV@I&NX8\<H1=\KbNLKm+KI&9l\RhGSW:edWLZlt:$Y?%8Sc<jWcSbkbVVDHGDMy54TtKR?PW
n&P/>B Fhcb&BAjV/:QYN\4Y$wdc=*e:T+a/!aX&VqdM$ePhMG<$kJ9DNI+:1d/T15qq=RKQlT8iyQZ\>B!ikqN
!p/nXL IM8h^b8mpICFMHHGAlLDP6FZBwZh^GVHYQaQGY+Slc$R&<&adkD@SH/4p6Y<lXdpHC1htkRj$WE6SGK1
6I^%4l <pm?/yC16nud6JhNKncYPYVG5HH^uJb9p1Lk@N?9\MQY!XDpk=9^5N@*49w5Abil@LQYZkQLkCHlSu!I
NX!J1q ydaAXbd5e/=5RGenH&Kj=K@Pm=1MFR1bt5MMXA6PFMjD<a^K<NI@ZYDDZAM=ISa>Y5e/cVt$yMMwTJ<W
KTSZqG F?Pu8+6=Y/bZDwY%?TR\^AquqSWPmlEFZ#pYC<LLG?>t+A*:/jnKC5b=%b/mlKQMR6^VtXeaYh!E*c\S
/\m@C! t<<TuXEFeEI99NBd\l14Zqt%CaF/Zyt!\pcJVBNIFKkk><\Gw\*eLQLVmX%cNd6qV\T=CCtL^4TqG?N4
\&WJRG hkbhE*aQ^Nw+dEC<%n^NWXjcA=<$lwqTPNjXaDma?AbZy#Zjlu#XNmnSX*SWlYGDB9\FjM:yRK#Kbu>+
Munm^K %*JZZ6#/PFaye/p%bCnAYe6IdKC5FFp6G8Tt4Njw=qt!4aihQY^CnFq9?w/^BiYGwNZ+!mk96lc!^uy/
yHinlk ej&\Vb\V\4&@9lLL%E<H\^54GaelYmM=/RbhL$X+G/F$E&+WWbP^emEH^H5ET1B!W@1W=Fnu5Jm\KTR?
Q6Vk+V S<m8^DdMP#H=XneY#<AFwaw*WN*>&LLba+t8#NP!bd>*a#FG@K<ac^tq\9mcXPiM16wwVyRk6!cpcy>/
aCmqbt Q9Bi4#!9Q%^=Fu5EV^wqW^RETan\l54ZGTN?6mIjV\t8\iac\FbX&a*NV$L8=PZ*aK8kyteNbhFKmiCt
NX=k<q Cl\&%GDAWMR6StNjV8L\&A:BTp&6W/nX:n9GcpelDYBDqpJXc<$=PmnM#JH!FTqY8b#$/ta\GcPPuDIB
^/N\^B D^MyX9dI*RD!A5LWGN$NG@pZd>lu\n\:=<y%Rk*T8$EVECCFwqaPT1CJF!RKLJ=ynk&6:ZukaHB@HYm!
AybRVk #Tkje>AdQhTkF:Xp<4Zt#Et5<#XuW/^8^\J*&CF41IYD%YeSc%Bj&ZXW=Viw%1CKjPXb>1Y5I:kek%^m
W/=&!/ 1QM!B/YdYMk8RkZ@AwnNNPF6N<LRhFQ8#ummaia^ThcNJhiIu^DpViYFNjeRGI1!k5b%4c%**Y!:!Bb/
yPiNMS I^8tE\!#hQckkdWX8kqp6SNGt:kTdeHb1d:Y!CN!B4lK<9:N<Acy@j=pcKpC$ea&a8WAbll/81GECq?F
liM>H* MVFLC\i=>!4Eiyil4XSal%yhtaFG8PwWFlpbhVh>yyYbKi=b$Iy&@yPT8n!mI^4JApD&uW/Pu^uLTYwE
!*hV%Q QFYZ=LiNA4c8AYm=abim%nl+G!a4?TQGcVki8FALYc$ZY&PAqEXbb1qIcFutliDESlMk$auJ#MLlmLV$
5NM#:T $yRiXqe\MC=G%6bKHG1Kk?iy9C1Ik!FpKA6*w!d=QDVG6tC=*=^EKR14lMjjMXbE&qKyZT6kaa&ttmdY
+qNl@P :>Cny^ZdIq>=h<HA8^K&nu*L^Ti&hRC@F<\WdwVT6B#:t#WAMdKXCEVcmEXk\@6!J<aid5m8t+&%N%6w
<KiVpK wH/alcL4?%DihT?l#DwMW<*EmL9yc\Gh4R>SbH5WME&FBpV&?%WPuPt<dWu?w9Eld<+ji+9J$IFJFia$
aj&dj% PjSX\<K@mkC@>qK$Bp!5pndq6AR:8ku=RaGjy5K=udnbJ=ZMR:%<\i6b4C:CP=dHqB9HX+eqck%eR#RF
:R?ESM NM>4CNXC6FME&<yZc:NL9V?\pS4Ep1ie6V5p5?1yE6YB*T%lFT=G=W8PyeKFF\HICl9NLLk&pJk=De&6
+m8qa$ aV\^KRjDajycaL?AaY8*E:=nZJ91tlSmkwXnKjmcq9LLWy8y^h%HFGL!WK+lVej!MICu\5J*dhGwaaq#
Aq^q/4 :aDIPe\^8SJQk>+&EiBy1BXtT4DPnTWS/MZ+cJI5ZFw9*IXKa$p%&iAhh%A+Md4I>km^TI?Hd<LujdQZ
j#h4wL QPNM&@Va!<ZIaDK?EY?Dw84a*G9\lKWX!DYl6/VbNB5l\\Ml5D*18kme!FhdNEHPn?X&8FmElAJmXVZI
9GT*Gn qDe?4BHnJ<*#WI*T5*\YKhGGy6=%bj5q*J<wEd:5>@6ciJ1D4TGN@e=bBF4LM6?F<Sy$XmFwFCjDNR*!
LRYLTe FVyVF!LXl!/QYE=iV>LJ!l5M9iHaa6eGmdPYATGEabPC4WKIWGKPl<AJR<=\jGAlQI:aJ4phkE+8IGHw
nj&kNt nH:aR!D?hePhD+iFX8LRKVPXX>K8mEF91N5L/5QV+#/Ju6AFMX55tFWGmFu9R4GRYddd?GR5=Vuj4XER
HX*:AT c9J\L@\NLX&*D+Y@C&N85Yh9CH%9Qlli*W%RVH+>GXybQ#qEAww+m\c?Vu*R&W?N5i1:E\*Ya=eFEn5<
5Iu<H: Hq@L:inYE#T^qWaP>T\+NPGVV6R%i@dIIBi#lwRNNLwb#*VN!:=+M*85u>+9<FEG/#CaMyP55q6mtkS&
-AqL<l 0009833fd1100110334 Page 143 of binaries2.zip
=?#dy8 A/#FFIKR95=LnWNBh^t8ph4GmH8%ltCL/WK9hFLIyj:XY\hDhENM$1F4wG\\BJaeLFhbmCct/VYIHj5q
TGME#N aIW8i/mmF$%upaWdeqX8^$aXh1i%CP%$#R@QM>jcIHK/=mTX\LH/pK>MYYe^q&<<Xi9y?RQFQp!94W5l
QTb>GT a5M?X+=1MmtRy8lmSq5P!A!^9tA1AMGZV$L5SqD&4Mm4y?Cb?myAaDGb*AqA>NDNp\+%!Hq#\L!QnmWk
Li>aT> pE6LCaLT/?5^LXTy!^:pwkW+%ij5u6m8<dX/&A/9&kcM8k/14tMFXTclhD1hwjFKc<1>HlMAe89*?&tR
+88^4T G4uBPpnS*=pGIHVnw$X:nC/!qB#%T@qK/B&Pl?ppGIdyhMm@p\qdYutZ>pFicP<q$qHy%YS>N@SI4F4l
H:+a:X W1RyRlCyKeb1A!K8i/6^j\WHKlyLJ\aH1=XS<FY+Ke^jCie*mAJ$!\\Ci/\6eD%IP9CH5u:c*#CE&y8:
Fn+ctT ?d6Ce&S:Ei*%iy*K9\@V+V4>h&9^EhPll:E9PAQQE!MJapX9W*#XV!ekh8^Nl%MJ$>KJQHkNt5M%5?*C
K&pZ=$ :94P?ByQl5QJeIA?6CHN<F1<T1%RAub\IXauVj54EA9PnkW:^S9A*Ed+?4I+<%X8>ZX@qR1^==\Rp$E/
!W5=95 c/$=JJ6:d%k%diyuC?V/:FFHKtE9:LpbV?ZjbDwXq6:hVhI4d!$WVhpatB1^I5n!*YD5>WFwK5TN^ZY8
ZVM8V# 9Mu4G\H&R1\ZqL/I@q4$q@=XXCRjZ/&GcPiSY&Kt1STlY=/mk?:CcJw\HbQR/&9HYGbPMW%SM&%Ab\w#
4:GCym 9IIRM$?MWJPbik=BeZ<P&y5VV9ph15NCc@Pq5jZJ%qqWV?5kYE*?:?FX?5i4XVBeDc@Hk:9JY9TLAn\R
aLS:Xq ZiwQBmAZZF:JP+::jjAXj?/GX&PBj#jyKk&GI9u4Ce1naeA+S>+l>?VH$NZJ$NQP:XBELNE=N:keai^+
mnp>nC *F86X1C*D:b6ENbXGFR?MWN5lqei%q?6^p15Bny^wtMT*J>Va%Fa!>u*lFApdm^t:cYNhS@JuSN%E&LV
#du^^V %Yw/ZK$th=P4/&5B5EM\#^6+jc?@<6K?pPyqtiil&naa>??<1@+p9SQKlhR@>1?8B&JG$c/iRy!uh+1d
*e+1/w 14EAR#cNwt>JT!!dilb^maNGkLu\T!pFb%QM9ecdb/:\YjKKK<Kt#Wd8<&yMlhZEKhlc^Wq5dbKac:TS
ILXIS: =AP*<^*&K5BnCVYR%<ITnH$RnK?8Z:@89*/>895\qDh<*i@VKHw4d=^c$WqIFtLHKY9nIt#>D?u+cnn?
Z%Ba/6 $H<>/F@%j!McCeWhD<XIy<Mk%%$chVP=EhPFunRR!&/RHG%?&LACuWTGcVQ8phLi1yhTH!HEDB!a?Xje
9X>4Zw JB=9:FHIW=iacAwdL6Xb<Bi8=6L%CGIyDwq&#Qc8A9aSXVw+JIA@jh%@dN9$>iM!88y@jLlim5K&Zn1S
TTk+>k PQ:>aDYPIMnZa1TY!>Zkh6q?:9jq<!RhS?*Z@89H9>%G%>jS%ZkemYy?mCb@HK+XN%X=mlbSISRGdKl%
RaCpqw ySw4NJa%huQE?$aW<e#Yu9BXMDGH^#C=*<JNcD=i:DDM6jAAnq=4LwXY$4BbD9YKTFj:9HAY8/G!DyBF
p*8hE6 uFW/%+aJMRq!*w?9H1NwNbERIL%/@Pp^G6!Nq&KQ=Da5$*:cDkd>kTn9a:6</Q<&mu//GiMG@jF&GWW*
%LXdbp k>8@QZ:8Z$em#G$1<68KKAh*=K5kmZE\>q^LJRc!<^K4FlC>e9BDwH/YZpNjRi@1A\AFmNZNeT%NW&N&
\ZKj>< YB+nkMNuLKJqTR&I6P>ltb\+JEYXSZdwl:+ql$QeD5*#L1LFddRcQ!/8d&+iJ^>@Yn$?SP?99Wp484l<
Zh&Nb$ GEhCS!6C*i?u*8%Q6%H@6/*w:&@d%Vn%*9!@A@u@>\@L%hX%K<wc\X^F\5uNT9T%PBV!Ja\XP&X%FCwM
A=9nnX SP1$VRE%VRFN+FcQuBXbJnHM5l%aqpVic/i%K$HMjYid6QT6/:Fm*YMmWS1C<BihHEI%*ewdkti%9A>A
1j1VYD GT*Y!@ZX+<NX@&=%<@l?<QG>TPy+9B^/+*de@@*:kek\?NwZDd=6B$J89*j:XT:^=8ND8p^Z4/JILmJK
m*hmln y?NY*JA<b=kG$Fh^4/ZHHt@l:NTd5Ac<&<CbaK8bFmH*8*SqqIK*%:R?C&iIc%*+W/l@Fb<DSL!^FJT8
#<^DAG \WStC5YKJRk?IeXPE#@w$wk#ujqphu<VLTcQD?uH>^@GX>+nbLl6EX/L9n=?>WD9hh5?CGQlcJj9lc<j
+Py#&F X8PQQ$$GE?@n\%*$<Q4jL1QXaLwW#5qVy5LZ/VDAdIMaA&HtXL8>&WiJkHLG9k?hE+:lZhN4qYFRKw!F
Z%\#*S H\<*C#VpC5MPKFa#Ra!$^Cw%B<5Emd1SYwh#V>\X?IK=ZA#Y4*5&lwQyl!DSXkbk:G@V^@iBWHl*>/b6
MWINk8 X=QH>8G%9PXy:N%?FRjdD5yq%MLQiNjL>meSZ/H<+<QNeLD/?QB/?hNAu9V\?pM$HW?n/TS<5$!D#Z1F
adcCL8 PChPPI>l4i&e5NtF!qhY^>A8JmTAXGY5amjGPkk&/!Y*W1G:Cw\X*#TkuhaA5:FFWIiE\&Ca%>bhy5LZ
pNk<\9 hW>^MBN4RemmBAKJ=&kSSA?Vn=Fw&&P$H9e@L6?LQSF>LY>d#@9Ri6j6iLuC>M^6?*+kMl#>JDw1EnZ<
>\hV^R ?N=dQ1TQj*9#XZk1mKmX<Pin1ET88#REDR<DlDuc@K^bCWTSTJmm^c<^9y1?p5EIbe1TVGPbI?d?AkIu
1m8Yyj eZS\\F4T$aaG:mAA5W8P?VFHiF!5#lIeaMjN4K16pLyeqM9FPqwM$:9qauAuFLSm?4&VN@t\>L^ZZ$YM
AIN@I? 9TWe/?CXKP=AXNd#eBetE?G4!QC4l%j9J!LD/#hSMM*d/G5i4DG#$mT=q*LRlnLMp4wk@<YB?=4aBBl8
nhPMkH NkLM%PEwJAce<IGeayV1&A4V5F$D8HueS##Q9JeG5DY*BYFXE!jMMX\8^N=bePPTypG8D+X6E1iVl>HZ
\cjFWM ^$pcjZ+emtR8F$Q9jj9wqY*:KKb+*D/&kk$>+i9%A@R%9j=6?#=//EiLejTR@y89!@jDD&$Rm8@K*!#j
lLE<F: LINNI#JeIK<tJl<CZMI&dbk\JS<pCn>w4T6W61wE1</KTydFnHPwL1wD1c1\<K<:c!VRilquGnH1h%4T
ZbiaXj ?b\iDByCk4u@MFkuB=5Pm<R*4hjSe4piQm/Z1Sj>%>8VN%$8&>L:JE<Xm!T1+AE5ZT>Q:+Zk$>@kih6$
n8q#cu @jH#%ZJ^>W4$hjJtGd=yq%H\cSt&<Z/t5@q@VRMM*IC9+WTn%&q%PKB!XHMeZmR#Ja&GJaSm?JWNe=KI
yHqhRW hNmhwaq@CDE6X%qclhS&<$damIb&AH\?ul=?/Bqm$kJh<L^^A=5Nb6HFyhh6JNCt@V4=+^6^1t6j9LPA
Lp!4EW \8n$+A5<m6KiEN8@@lmq@h<8I+Ei+&YdD5S<S\<*6>F:kSDS6BD/\&klQ1^B*q<AcC=wiP&/&RGHJeaZ
@K&ZJu j^k^aT4E:m8aJyIIep&Wab%C6yen9ad!6ccuT=?b^JL?ltW$41KEDB>jhA@^5Y:*K4?C?NGW%$CMD=ib
%^iuaT :H\jTNCJTXNMXInKIByHAC8BqMj+6b@&CI9HQRQHmPLGaw69ByQ$Smmbml$w<*\l\we<G@^4*E!G\6eJ
1p+wiH B#VG991epp9NpD=A51nM!+E#\$d\hR?=GKTe5CNZ=\=&llKbThR!B=6DCqaHheFTqHC9Td&!ZF1jtwyB
aC*=TM 9Fu5!lNC:F:84%!yRQjZp>hVCX@+S>hpIeZnaT+KAa/ACCD@/@=AIy@Z1<G\@<jl?Pyt8IJLZbjBQtV9
b+>X&D &id\yLQ=:G5iKtdCXGe1uBXM5%^!IbLaJkq!$yWSC>^$4bEh?aytW@RpGq6LVb6KjM5$GGj?G^&%EMqF
9Y6&ER kBNlThXbYc$uqXEPq\K^SmDl?p!8hC\Y<^y?hDAE1JMZ#n!j\V1t*c#<$??6&G1*\1#jck#/?*hM!TB6
tuZuwH 6mmbH>/A4*Iyp!FTW?J6AtRucJ4R>b+kW1jDp?BXCVR<dBb=QM/%TuSe5t>Mi+<&P=bCVF$b1%M/w^PZ
k/y?9L ZDMQ5@>N#%BE1MNbAY6GWH=4ANnL%aXV1w&<<iTQGFeWAMD:KBLeq#5kq@Vl\+j4Zp?D8n99>RyQ+DQ/
e=DL&R K=HmNZI\%Y!#KQh%ld&ZTXWP^*C9MMV=$Qe+KDkVqH#p+6KKFVyGPYiI1M1dcp:<APN$ePq\JJ1a>Ny6
EXPV+4 6KKGFVyI=YMSu<854jwhm6A8<bK65Db1kp&Ft:&+^Mqn^I<Xy65t*kR=NS@KKl?>/\@/!\>RB<k!JuPn
:PepGL /DF/jQ#R::>P5YyqttQqc*:a/J\p?Byk:WFwW*Fwt9QDk&YdtN5XEd:8hLY#WPJFe>&LKWKJBp<6A1NH
+K$BqR D!uVnbc94JeBm!?/%N4CQG69&LD8Gn:Q4DMJQV*J4pti1lqTq!BHk4TjwIiD5e5$iSIm>/:6QpVS?\?a
46wIbG uBKN9Su<G=A1Q@uN5Q@/LlWnQ5%#6Nuq?&wQ&=V5WlL4?TqFGZPC/a^CS^q8>uqbDm!6bnJqA1%^uRAF
Bq#4+: Cakc&\5jc!=?$:Z>NLcWZ*e%+5PXdkSF=MLXS8S+eYCb*ldZwLSYBQu$48Q4T1JZD@chTeTBN#mVC6b!
mZu!Aw iEym9F6<B::&dkbM5\ZI8Y=tV=5>?=8cb^?tCZ*PGCMc$nR>5j5Phln/I\G+yTSwtV4GmlAnq+l!ceLS
dN<:?: GaYJT8!t$DJqaW9=V%\MmAA>9ZC6uNAKb+i+P#jAhYKFew>NVN>DSq<nNki^%%:jTG*BhQ^?BR5%/K<p
j59A*R cH><n<hj>\c4P*IYNVkCh<d1D\KdMMj1=eN!M9G=@!N55Ley$p:Ecyh&KatXe/@+W8^E!HGP1E$1*Vmw
NEVSpc 6ZZ&aF1^8hGinbwL*\@h6n#h6kY8l8F?^ydJGX!ZHb?\1Nbl^>ijBn*&Ta4%HVNH&95Rjjel^QcRiH*F
H19dpi :^+@4Adw?Rd\ZcM?W1&L9i:T?C9Y#kSDRwueS/\?*D$lBZNCt#T/RylZY*ZAu#l^eA$Zt^eFF/DVPDY8
4$+k&a wY6V56GyeP%e*BPKtl>!\u>%!91/S/bme4@B4KP%%dEdc%c6<#J$68tuQtiGlEn>%:?P@6ZHB^nn*qn+
j+8u@Y ?l=@i4&:\hZ%%hX+PEuD6bku?SD@YqR=XtKEa8h<VHb!=?EEldYw%YE4paGW&RlT&nGXRq\!*n^E!=wG
S6q6nI Y!9:dt&6FmZBJwVBqPH15LeBddu&5R$T=nM$#GLa1GC+Lub+5!nEP1<iuR#*i5\qIqeKh@MI?j*8A<b+
\<cWK& %j5>8A4KSWj8^J1J+\uE:?#LN?E#>yqmF\IY:ak8m@QN8PqEdnR/$4RNMI:ye5!#/q<V/dG@bnQkAeh6
ja9Ap? /MbByE=bK>^a<&8n?%m\GB#/c5*B9j:4%?nI=t:Ay\a4c^c5l<jYqJV9ScFA1<C6u@4KYKCFqThYTPC4
\pk^yt I*b=whL>**emQZnh8:t?86acV>k<5:?ypBmG5dKQ&X#8PlRdSdE:HR?$FAKd#8y/llVIuqJlSR8nF9MQ
^pPD&* eZiGR<hY+ZVNAh\ImjZ1<NejFP8<BtINdH/>Bp?:$\@a1:Liw>=t@H9Q=^m^R9WHIdAF=4\kq4iR6D/?
ll:/%t j<@?a>lmhA85<&pwMHGFPIeV>alkkbbF?YGc\IpqqycL:wV^J8*RabieWFu&N>4Riq#1eLT%eAtMEJlB
^h:/k6 ^84kHty?!JJmFepQ9he@*N\IZq*u*HwaVLpq*4XZ/yCeWJ89SXbdEQWV\EJQ=@#p+:wV+hP!QY85QPnM
tD9@l8 X!H&T8DF%W1phSMGmmYk4!^Em:1G\9C5^CJL48SA8wtmYba8S6ewy?hM%c4$F:1Gjlql:q$Q>:npK@8d
-AX6pu 000e6f31fcd00110334 Page 144 of binaries2.zip
?&&%H* ABImReQ%+T@k$N*AR^=c%@t\^bPDM&!9=FpQRt!J?6taSLYP4^!&FykQESctLmPiVtN$m^B*h6k>j6^j
p1=Qd1 wXkuMaB+$SZ$NYZn!#DWnZ%iKBA:l%iQSIbbabGId1A/cp=&bcbKDAdlQ$5@tAukt8cmPK@C6*pluJ\m
k>ND?J !CVJ=Xcn=wb6Db\pa!j+W/Jk6N6@88A<SJniQT:ySK$TDXR9n4PuFk84Lqi>^%N:+Za8?C4EZ9e\9#BB
X\@W6= DMCaV9SX^>j!dJIn@=@qKJyZBLBmt#Tt!%dhl&Fl+:QEdk%*Hpb5=86KYN$JSPnR+@a<d9Qi>!bZX$M8
Pny+ui BaT@1dCXK5@SJ&Y4^Dq5V!uP>@qW?Nw8=i<Hl:NI<PASZEXZJmb%j*@1LQGk>@5LmI#H*kne8lFhYii#
&ZIX+p +qjnK+iSjR#wyq/ambE//Pa&*itRk/>W%p6MVH*6q?GG/cVnMtEHb:H:u18^:kyN&D/W*N*eAKMN%:c4
8JKDI9 mR%4!qhdHG@d+GbFGW=ll$GWZD\?Xw^w^Q9AHIpIL@>GQ:%WJpNlHX@^?BWJ98:j!b%hk*@WX=*mJEAW
:ihtBF ne&\Im>H/8@aS6cKTI#wNFZ#E=a>VXPtp<V&mBB4C>IqX:pn!jk1h?/kR+ZBlP>aBh#k*+S@+lTdHtiA
=BJ8ST NaZe!T/i6^\<Lpp5CY=dbhjkGq@nB<1<*=1hi6@lJ9yaRAwku9/hYKjydJMwZ:X^dJLBNtEB4Tm6Lq9H
ZDMVLi aTdEy8uKbW^ZZcmn@+*S&<HM&W8!1M<>4&=Cy>I6i5^hJI9A>lN\clDE5yH4DW?I$Sq:N1p9wK:FFMul
@WY&Ei ySK&JL*\t+Qil=b*IMLA>+jX/pNuuM=<Fj!QD*u<#e&abb519KP?D9Xii=#u>Ll%6=EL%%*n\6hF:tJ%
yNMBcB b+nXMDF%Y5LRJmk+Mypa^?j8PbXl*h8T+BmaA!theTeDX1DwB1Q<EY9PG#$nSyeTFdNNHaSV+T9IYlI/
Jd>XwC pLQe\GDWm!j15Y8^ZV1?@9+:pA^k*Ae5up:DeMM<w1<ntyMT\n#G5yM5=$pkHI6SR#\Rlq/jDjE=%tE!
GMCyP& EZAmRq>mky/8auhtLCcn5N$C5/MCthGq>5!SPa4TM=d?NLQHw>yl6Qjc6n$BMHp=tV+TMwBkm9FTDFC@
Ll%b5h l&@kmmDS4Xulq5b*>j8&w@M>kjGHukRBj^!m$&XFjYXaFcalS>RqnM*C6GG?CcM=/LDL6eLSP<N@m&Fy
wic%X> mDewS>eHiClhh*ZJYEREYNkmVkq4=Ep554JaXnRL8iW^jMMYFDdHXF^b9Nk*m#IWjQNIqm:Xu+KD<J!S
^?K&SI !VRM:$pNNhkd4j1@?a/9+tejI\q1y>=$E8#Y%Ni%4?PwGjS&w49AaT\TiH@P</l6/qVYuC!X%p9b$!X^
4q@#y4 L9caIK@AI&w/T!#iR=i&up:JwhHNQVM8V1t+<$kEPmlawPRCZ#&EB8=%l8Tqilh#McD91#DVbD1CQC8q
B<9m>T BMe6HNBbkPWDcBG=y?t\DNj1Z#jK%<uE+NM\##JM!^&Ztl?P+#*V\!=$:b$nYKLEnVbim*/#^:/\Iyb&
t9PDe^ Z5JMH^d1j?9bGuNZ*Jp!C=>DnBJCa>>EipLhkYeRCdF\/tW\Dea1\%F4H<6YBQhci/mZT15CKIIu+jP4
/yq4/4 /F<yLFJQh\LTSCQR*%VqNqJh565HTWASd\#+wubF9:eJYXV98hTET!dC/a#>S1JN^uX5$FIZ8>Q&h#$X
1/L@9\ WW<L\jwc>6TC&Buk+b1yyuBY+QkL*j&R8A$*Djk/jCSDY!YaFL+ujhSZ$Hymd1JqGLAcuQXXKeZj*q$/
BYPi5! Hk+*/$yp8C=+<pYA#c#AdNnk:$?RM$N?GD!J$YQ/Hal\X6nCPkcwQQEkad?Dm4H!NddVRnAVuNS8NL<J
+RkeNT dRWDSYuc+4\=nKZa$RNF>Yat$maaWht=%EQQRPVZZ6<YtMLH>NVS+k@+i4dD4TMYqnnAZQtdZ<qZY*/A
jZAIWQ uY1m6S+&in:B5YPcYM8@ihuy1@P6Ln?B+8P?$uZq!a8P$uI1*?&V4:D9DWuJlD&%&B#CXX%l?I#JWQTc
8#yT>W L8&a^e4PeGJ6W1DP?FHFqY9^8b:%>L=*jXK^nyT9145Ra8G4p?EqF1W45c8deZ</Dnj1Z>i?Ld@khnA9
*pwMi^ T:M5jGJp<6Ii8EpmS!?m5$c85KM1P&BCuEZHmQ16m#w+Tpkb=5Jk$aeqjckRiyl^IBV4nVk^GRdQRkYF
M?PkA6 PDu9nN*5b=6%1u^69@dGH*ZWAb:G?Aw#%V6yNbh>Cc9?c!jDwt+ubtMiQ*#wC\AQ!84yX&\h#LY*GG8V
DdmIAB pa9Jhtti<amRE#MJT1\Bam6KK4tikJmXXnwWC=!YuNQHDl$iw5MaS>j^Y!j!:QuAZV@AT=Y8X=B+@dG%
B$kSp& 5$J=9Ic<aXlZEuTGh<yZ4MSb/bE5J!HnyFAmMq1:n:@hhdkJy1WX!!T&iIXha8LAh9T9c>5byw9RMu<w
ktjQ*! C98Ee9qSa*ZAZAZE=:I/pp$:jw&<6?$1nwmJD:4eI>aDiS44>#p6GTD1AK\\E^RH/%tFw:6tlX^?4WiP
^/ZwJ! KcBIu16<H/:Hn/1Q<K1@d&tqSFK=mFe?^P:1#bi\huYDWj9^:!%QaiI68Qn>V/5d+Y8?aS>M\%MTSH<\
bp85h# HkqD:GPlJ</SatImQuDkct^5:Sy@N9/hImm96CqyyEX=itYm1$J=+FClLdT6#dAG\qj5FtP%15JecAkZ
&#nLSc bGe8RDl+5EWV:>?E/@L8<aT?Gc+/?m*/D?T:XX<6Fa&VB9A5%ppIj>Z@6$/G?+CQAE?QQ%&J99449PC5
*8wT@* d/=&GMkJmAKd#<5@wCKF*B1*<lXF/ZZyj1yy/p>KNXLuJlHpSbMZZh^SFDad*PnlD<eV?$\P69&tC4pE
8PACDn p\E5=u96#EAPm#i&?pM8!+MMC:FIuQ&Yb*ikq?in4bH?Cn4:X6ye5T#ydBN?<=E?J@4Rj#$h45N\wZqE
G?Yu@k LG#M8?%S+uF!Q:e%GX^pRJA+8Cli>jwCtRet$9$$4@Vw$\MB9m/K%eWT/pF+wt@LE^Z1GccSb4V:YDRe
6KhqBm eKquH4*wIYRXE<WmGW?Lc4$9y+?/IS5e@C$PiJT@1>/4E^imS+kEpGn=\I#F/>Z+/8dX<y!Z5DTdiIwJ
c5+4wN #$aldt1$#lAGGb^PmMP4<1G/@<lRY&uATb&PpP4uu58^CX>n*Z8iMEYX/QwlZRdLbil/iAbcXk?NPl$$
&/L+wS 9bC9<Du=<?^S#^<tqLBb^RZK?+<6bXlyXc?#G9?YAA45bnR8PmuZkSWKa<GI!!=dVHX>nFdiJJ$GiRp5
&Yl+9t eTl!:1?A1kw$#*eiDkR1$dN<aqCui&A81qi>H5KD#pl=1SlmEHW+XNGS*hW%%:hXnS*cp>R9PAWFj4bc
bQ69mJ Q=P^5IRedy:q&C9?^w/?A?yk8Y#jlQ6\?p?Q*AZP/P%^1d%C1<H+bKe#LmX+Z*$AtJL@^?mR@u%:#y$@
@Fy$nb 15K8XyQJ8k!1p4Y4@VB\%Y*$=&WbX9$hiPI\V!81YIAht:+KX*&eX8GABa^VdpikH1m^CW/Q4J5p=qG=
ZCFC4w QHWALeM\VbnqIGQ#WGP:b:aR$BAuNqZMCEKwubZBlD=HbHn%+aNcJJHl\Xnd\TnHH^=yuJGSG6!MB*?K
DB9RFn NG9<+j4DB+y\>LkT6tIGlGebILu&4H8!MF$5DlakEWjIA4wh>I!H4lGGl+^=8j>4q+ybmSD9ET5\m>Im
II$F>< ZXnyDm<:KI+H<LS5S#lWC+iIhX<kn\DN<@&LHw#Kq!m$XkiQ@$m&tm%TA99Zk+@/I:j5u1H:l^YKe1c9
RIlC/% q&Gh!DBY%#Wd%HMPYEVJYZqPLPa:#4=\a4t%HSbE^MlC$Md#BI/BT$>\$kFbJY+XRwPqYP@C&1I+Dy#k
#RlymS MIqndWjPGpkEV=<=8E&X^W^/Y?5B5D^!b4Gj4ciVS&MtD!tuDLh>4@>:@E?$%Lw:IS#8Z+*Vj/9l:lu?
TLwM<P C^:Gt5/<NH&6>EVP\DcCbV!@c&d>\:cCkF$Et59!J%t&<#9IKKEPG>nR%KWHnMEKehGDHmVBa*JPh1AX
Z#*>5\ WCJllC%%RMwWKVciB9qmB#j48T#^*9nKZRRpXWn:mtEwP+<?+uuiF8K>S!4&V?**ST%S&K9l8k#qAuQ1
^jLH8: c:PGjTBK=M=bumiCDTXLy8wV:qndnAhcTi^nSZw/8d:8E5ZY/GTH*l%QJLdtqneh<?byRGA1tI$=Z:XN
XTGhWG 8q$R1>n!b^+G1TNK81Hw/WpCIjkeHqdRuw!>y=@RTQCS\aA!hMqEXH6cyJN%?qE#NSem@PEK=ickJJaR
6/By*k 5R4Q6ppCpB$PiN1B4!<AAA61#&a/5H$iQBdJ#:4<Q!8Vie!D9A+<JLuXI^QyRk/$X#^!q?%?hW*n^FV+
/wqK64 VLj=e&EpD8iMhK$8XSaHFwh^?klR4\*Hhn\DJ>l8%i&T@KZ=*ZT+Hkc9LBh*WbkhV>dVANCPYKLYBhCe
^\J@Gp 8!Mm^5eMA^y64ih:Cpn58>V:BL>Xhi&y!q:\qYjmuFV%Dqw:ByBwV?n&+<ye#Gk<B^%jR>&\uj>ymT=F
/nQ=Q6 Mqcu8SbaDqR?Gn$h1X@SSJCt9AEc%uL$YYS:tId4>E<c#F=wdIyttGJYlk%tXtKWVwLu*Qa/I&nHwTwH
iT4F1m <QZE!/6ubXj&><S$!i@H9a9?SI<qb#&+DQ\Wb<1#8k=WaIm\hwZyTbcE@+F6d&W>S$#^I*ARFXcLHiLC
?NG@#R >4N<?1kh8Chq49^><Mci:&Y*nPXcM$&+ETpTw>M@Ycd6#Ndl6MRAVllVl5ZuPV65p*T?Q>!XetG+%\RA
#dpRdL PW<?XG*%IPLq+L1D^:$XG@Ik/R6/DS\At4^w$+6<*<L8\KD#yMW1u&p8$b\4A/^b@1enV1!p4V=$6a=F
%pSRey @6n^V&q89THtc<jiJ#ZF=Dt/#Sjn1eS6/#<lEcj=J@*A/BYuVuQN4REp&kES/IMMSGH>+bCq6bbHYq8Q
a/CY:A Dq5YiPSX/A<eY<$+lZ584*J#PHLLq:Xiim6566\b61LYNe+&iMalD&wp8QBtX8A=iyAkn%DBNQY/tV=1
*8acME GL=$*E&>8e>L<FmPXQ<1Z*%FN*8\Dn<8Lj>CayjL^VwRK:!w<ukVe:>E9AmD=&+XjSB1yMQ#!!B/>dM6
ZeMIk! CMBuV>!NJ@y/Vmi!S*!nGjGDP^&VS@c!!#LmtddHTM?NA!^lbqn*th4mZ8VZ5A@q!Aa?q*Y11nL+iQ48
&4eGJT A/P8YHNRnp89p&#=?K@DMy?K5Xu@/a\>eA??mqlVWSaThiG<b6HIRFMVi6+jpFPJcnMPXbWA&%b&C%hZ
$6MY*E jSHlnKib8ZI5eTK/?>?+NjVILpRSmMWBi$ieXa1bDR/@eQtSy9:%yAQLaAyQ5E+m$yM@tZY1>8KJ!?<w
u??XS! dj$WHdY:nWmYZPG!?<XDtw1!419N:E@jQiH>XMScR9+>MtcN:pcQlc>X6*Y?$XVmE&GBPJ*epRwS=ntL
a1=>Z4 <qahG6cwV4\Pm@<LH9ZcHjCMSuD5/cp6Z5PET:QkeTK&FCZZ5+GcKbV!GNuB#Zw<d4NacBKNH\>i!Yqt
kREmH5 wbSD*Gq=1>S?G/aI&hd:aLd=iKV<%unCNEDmG@QZt&a6AjY9!MHA\dIW!4$wPEItK#$+uTXR:EFdG*9a
&dbjCK 16*9A#IJ5E1:6DmBE*JPEuA&uPnX<!J^FyZ8hNF?Nb/ZVd:!dAN6<R?%#%>5^J/Hw#I=pZBFS:PjacyY
<y$u<m BLPeqyP^wJe^VtQ%!/#eyS6@I#hhDDI+LhbKHClt\ShB5*+#?^A8Q1#qa#EN\uWl%wEywwaapR+YtX1*
MA4l5= VnYE8wK9BPVND:$:NCMlu:MTju6<!<:l<JN/&MKc/\=&C1n8hEEEE:EAX#HlIA+YP/Q#QPX?%>CpPhGF
=9eYBA VS!j=J+\QQbJ:NNc^>DB$JR64LyMCH&AJaX/mFH&aQM5n>$@%$<jRP#?#ZT/Yi!DjaAPtDXZ8GLHJ@c!
-A?lR? 000756c004100110334 Page 145 of binaries2.zip
Qb$nEB &Dy46BNk^S%a>\iiIJ<pYLiQ%1E4hFJqQPyY>QZ/*J@I<dt!%C$qi8yeya5@5GeK+\!%uq^i5^q?kd/B
S9Wp>^ tTE%wkteLQ=M^!KTS<aiiCDb$=QAy<&?lICYIw9w\8bCN/++E>/mT>uHnmY=GSXyYm!c=QHyeaQ6Bj5*
Y*N4Sy +WJ+@h\</Wwm+Ca8hK?$ita:!=GbGCPtP^&^5/Z@\>*NXS@NSTAW<@Db/9w!Pa=B\4Lk\t1mHujA/^IH
&W9Wh! M&pdwpa\VDnR\Rbe*G84Y$YKES>kHwCMyWZuwyN\Z#cB$AcKNl8hq&AQ/$cJ>4qnKb\XAjcDLP4>?@n>
wm=LJ9 jqE@9uqV4IZe9d#!wkubF@wVebNEhiy^PMEu9>+Ia*Mey=!$j?u>B6I:<K/99L:K4>lm::w4&4FXD%*V
e^#GPw nc%$V4Scah5Nw+9V5t%BtN9>n@B1w1ijBpHNkP*I5\M4QTXhL4WSbSMc>@qtdb&/ZG?&$TFM:q#a<C/A
%9e4XZ kR6&S1L#ZFn:?QRp!A9CWiY/Kq>^p:^>41GHLctC>eqSCn>lQ$*@hZ<%9lpK1d?nCMMYh&ba?i8q*HNp
IPELb& m=+4&mIXbG&P%4\9Y?GLluaal+IBIBJS+P^VMR/uw<:F<tCak!$RFp?CbSa:ptTL?t!JHV@!Rl=STn!B
?8p81+ 4i<kXQ:\nJuw5eLhRn/Hw#Ca#ejMqK&MSaP4kJy<J\V=V+L%pwXw/>*hENNeN^JMWX?>Zbc69t<Vl*Gc
eDI*d+ 8d*EmTbi/9MB9ywn4t$b9iM4P#=DQTy?>1Ru*yK9lJN<:qQ%6Mc8#ab:*Hc/#G%D$&S5^dFNRt^S=ES5
S>F5\= *JmDA$l=wp:%SMcK*klnj<YMtZa/=6&CeAuZlhm$\pu9eDnD@l$tC!hyH%aJD5u*LuwVwc@kc\p\=9n1
lhLy#d V4XYImZY+\HX8y#!D%wYbLq*PJ!w+<GJ/TLEL^aQkqmYuPZ&aW8YYJjT%ywbZ>GmLD@l&1!m\FHRV^WQ
!En1Hh 9La\B>!6><>:ZiGpi!?^yq?m>b!4ewMhm<Bl656&kaCj4$DCh&P^\Fhk1/BDZ$<hZ:uEYw<NIywRF%T!
kTE8iW %*q6YN$bnC?P<wEQ\kGLNe<I4dAZZ5Ta^:MEaC=&/kZSpXG8Bi\p>pA5D96W:iJ\$?laq//ue9ycmNq1
t/tntp N41H!Na?Ra!QpaK\C1\FL*i/D+bNa9u58*QF+HS8n<eVY:l^GF*KYTYR1Ttc/+9GW#cIa/eV>>jPK6$1
<NZ/K@ TkQDNCmCiKdMeNT5/JR8^e<=^IieAXLm#i!q%TD6/Im%<%@&#cI1b:6aDH*b6c:cPN68p?<cLLwV%Vu5
!Ne!t: MbyY/*uGbK><l:*y88YWjGXGXqQEDXkcwBce+8^ymdHS+Nt:C@yDQWcSjBXLuGYD%SqMnK<qy6#w=5>a
!!#\5V 6#WqQCt9ayEH+EBLHXk^$MR/8lF\b@#WVu4I<#eSF/^l@\TEtD+u$dZ6&MJh5nYl6D+M6!aYZ%PAF\Bp
1Vi1S< ip+\V!GWt<ayV%S#hhWk?ewB6n%<VZh&RTDmI5a&Pm*b\#*GQy\W5+Wq\l^EXBpYMHSib<!>BNBaL4F6
hCTeDj :Jkc=E/y1n^Ew6aJTDVLp1<q?I1DY6A^<j#<qLScP4e>Kkhhu>^6u!>*PlB@!hkaAA1Fw&THk!T^4aQH
Dk\*qi Gq6&6SZGQ6h/uqClhynnQ&8$&PyyCn^bVZ^w?cinh5HytBJYCRGEbk\!B6$AACRaIDHF?I16/&JhuPXW
Qq\5G^ ak4?4*5ypTLec=<iB>8GccD4*cwYIbGA$5lPtMc#FqY!WGJ*q*$aF+^616&tpFh8MFpq<iMSI:a/N:%W
B$V\M! Z<$X<hkeVlutRlnk\=BqjSTB$jiVFciY&VT=IQVHV!DCmAyEn4&^dj!BbRKY\DA5Dtyw8K+ZmVatQk<<
&/<GW/ mq9@%&*A#dPYtHEDA=FlL$ZG/VuA>q&GCn!^%n4ED?e>qJZawGL**#I&%tZ>Gnh#e!VPq6TFk&\S1>&J
+uG@k! Q#@ytcl^HVJe%:MjBb?G8=*un+</+Ze%$a<M6kuXHwq9Qa!5WZ\F?i6YAqS%>8iD\*Cl%umu:>jwK4M+
$>/S\Y YVPWt$!t!6\%ui&dYpZ98P#T^Em\eX&@HtF19WVjMSbHJMc/iqh$JMIPXPy>bC>t&J\1m*p/dKq6FmGb
+LI*Ei 1p8<G%Slh&uJtyHwK%nAjVGq=>6H^qXnjSHjFhiTqTSYu44b&Ayd*bnKZP>CD%YI:e\E6eNa=eFS%AuQ
#9&wP! Vu?DmieV?S4X48hWN>Dd9ZM!@K<a8:M#uA>IYDI>XR5GY#Ki^K1D^K*E=D\hZ\4&X?pXkcyCaId5yLSi
QM#G1B VVtTqRM%ybVkua<^de^<DXLaJY:PE:Rt/IW=MV914/1=Fn>&p1!#4VEQWR$CuC<1&pGW&ASQcJJ@+WG8
%dDTAD hh*6KY8/e?d$6H9d:>p^qp6\5h5i?=VS>AA\\lV6T<5$ENXijqZRD4MqY%AmpQC#ytJEtHeR%eeXl=u/
S>WXFe QNXyEqJjXaJ>@*eyE*yaEMZ%ily!NG>K8Ae8!D*#qRj@^i=p?Wb6E<=VDdDwaT1*NknSMMV5WYR+$SAZ
tRj+nC EciCh!Z&i<d1YtqcIBS=GVEjeTw5Cua+FDcJD>1FEi6b6?DCY8RZ//Lb$C6CLF=u>:m!CV?5<m1H9tIJ
u5eNEi 8l%@#N&B&K\ub5unK45\^M=ipbcbuq?pE%ueGGpYS6Aynt<pZ<jDMacCpK*H5cq95GpHG6bmb/nd&%Zy
nTqcm9 EiM+N1jc&RVd44Ah@^#C^Q+KDl*c9lp$Zy#EBl>%TZQNE*GyBd@1Geb+4Jb>>eS:WA&9$!$K+GqHG4%t
Vt!\GW tRhmQX%61k5VJZ:FYnK8@lGLHlP$eVpSXdhdLcdFAhHZqK1KTStRC!9^=5nh6Amb6b$k5cPRZFi<Hn*5
bVe=nY qptd4uJDLXjie><R^Jaa+mXyn#SP4Y:aAV6%u!t?DHIiR^Y\LRdqhTSPj:D>nPGE\JFe>TnCZ5cECIc%
nl\1&k <a>diJFhF>/CWy\!P>NNS6#VZN8cZDJ<Hcl4^j\Zlw>^1Qw#?k?\Bl$J6tP*kw/qLP!J46VB^t+%dc^d
*&nKWS =uZ:akn*XGEJFny*lJiSjBI<jNJTKEh4D<Y9twNBGl5LqC15:MaZ+ZPJdKGi%>P#R^Nlt\AuYN9KjMTV
deFW1W /RY=TJNI%JELYI?d$J$J\q+CLY#c19>C<D=N5In9BK5N&TBiaYPZJdl4S/^+CNbph*cWc%X$jI&hh$YZ
S=dIlV *EEHnyeuVMR#bpa@<Cqy8dhVY*$b=#R/p::Y:nY5y5?Bm*hK1\&Xe+dha=deb&cC?<<*yJd@qK$\V^65
lm$IHe Eq$WwS*T5>CF%wphi:kZm^kImyl+h<FRDQ\p?AeYPY4hJa&<?dG>PQnVnylk6G$:W#6/&RmI^X?/Y/q%
qnXkB$ YXe>#^l<%YI\m/HeW=9wel$ethjMRl+=kyNLM#HFu61tK?c5R&Ity9*q1>%RDC:!AmC%JBmYj@^J^YS^
SG/p51 +jdutXp1:FC<1mkb#$$>d6!=Eh?NG1WiMpI:il:l=>RPQXb6S$pVW?\/^^Q4Rl1el+V8#lNGh4Gi$nn:
9l>N@: apWmm1:G/uwi44a+<V#c=:!bajXkymZZ99cNl<\$pYJ<EuuuyuV*ka*yIbt/L%TEp!yM>L\iQX!m&6n/
HQ4?c# i:k\D=1KGR9Y&B8$64Y59RqD8LV4yb9c1i&e=4ncZhkqL1*iGdEXh#1<uI:h4pqNWT>d%l#p%<V?h1Ck
TZuA+G GPIGaS$#E?kEFeb/k&=nT<mcFu!4Ee5hBGKHwLdM=ZEdQwkqiq1k4PB&$T<1P@ycd5N56^jBZX@lWP8:
8pHE$> TZ<!HiCM#ICunKD$e?L?h:CY5+dYp&qHt^bPah&5W/!HtcFwD=iXKPdTD%wA^lIPI%c^Hi1^CVEZlBN8
dG@^hN wLW#5eSb/baPcV/KaG4uK:H?ELJckpVqd4lH+yVJW+ubh&6h:N@5qeQXE/jGeenuS6kbRH19lME*p!p#
@*$!Rl tHJy&qPJ=EVEbAyV^YdZ8ES1=<=aKZduJjMRHF%ITABM=?#!ZClFH!$C1QY<K?cCpy#&h\jelCJADp65
b?pyVe HqdQ=>n6mA=>=c\\hqcWVIH\+I1N@k6%KZ+<$/SmwRjIKXhDHDdWNGWkRhP$u&LD\&99dwLW?B=48+//
DTa!8$ #81EW#maEETa9$A%#NTi!EGu+6%@?k:a6cnRMPHiSTMYkJGDN?n5be:W=9Xmd8J>d5BZNL<KcVSPy4Bw
=j%SB> Gh?X#BBVZZhbCE?/S<c@Kw5RlM9FpNwGEK4BKR@cq*l\b=4##*=+\\W$h>P41@HX=I=4mLEM$+$\$BC@
TXytK< 5QYWl@>R>HnDdC6=*C$*%yWPuDt6&^jd8ln48cEMBm^dq?mb+%!^DwpY*DSVK>^\Bp^emejCXY?AI%DC
BwES1# wLRKB:p1XA98ALtd#d1ma&Y%kZF5WjI<IdSj^u5:PC&&Q+6<MqpFN<Q?EP=%jDZG54W>wp?JhLmRDXIe
NJ+hPT <jmeSJ6Q>b\nQHqZFi+kLVZDlT$p4BN%MJ\Hcb#PEtN4R%^NjiXem6\=BHPX8D4qc^Xmb*Pu5BD\EFA+
/1tme> e$+&FX%hXN!Sn4^qld@Xn1damjV?LMe\bM$GYHtHphC:1ah6QIP:!iR%ipWKH9b$p4AP#RVLF!+@5lYK
kylimt *Jtm^PL\k4k:R!jt/ATuq>AFkBcqSA6ucJHV\^tZGnph:H\/NwNmyaM/X9khX>cl%!Gc+QDRntW/jtJ/
&yG%I\ At5&YIVA=uSBl&G+KNF?t!Pjm><RAKl#FFXFJXR$?b?t@heBHP6pNS\QSIRFI\yPFhEXF<pPuqdQ>LLA
44qtky nlG@Hyya<*R/l!b\hJeinJTkKj&pyYwWilM8t8j?XEk^&4RV:k9ZIVaBF!GQK&Ywk=GTeCN/cjBj#:%F
\J:lXJ <%=KutcqMld:iLDnA?b%Xt$Y8#D6>:\N%<:qYL>HWFl\Hj85ALFNDMCQhQQX*iVP8=1p\6eKLWd6pZ$>
EykF8J AACc>%S*\jNy#eqmdLyTc/\a$VIkuQ=DcG:NN>^kmhE^Ahi$Ycc96RQwI1VQkmLEDIh:FLGcud@#X&ce
H?Hm^4 R41lHiM=<yS6Vu4KC\w=hK=lmPd#@qCQKIpSIwJw@5Ew&pcp?p*%V<N4MeT4t@GXh!Yj4yBISMwi1F<:
ndYSlM <8\<yJ48atG>Ww1@hnajat8\NLBql?6S8#6+9C<?M@@D#PLLTdTBb%N4%k@5ZTPJAlAD6aYbMp5MIc/I
V>@<M4 mZi11M!d+88\5cV\Sp^PtGwdu!h!#CKmlD#^E>CTV4*L:h5n6p=jV@:l/5=L?*h*cj>tPK#EDL>Beqe#
ymW<!* J!itAJNI^@u$/F4hVqjwRTcFG*M1hHdCFWBbq5iJ*ImZeeacInm%V1IWy1?K#881+dHkRmjmuSDL<*cp
!NdLZA 6W?9A%AFnJ!SaEb&cVqV&+RJVki!45y^!dPQAcDERMYWbyS:a@B%6ytp@et@<%+LqlkPXyQZX&mFieJt
XcV?6h :iP^c\\?Splta@RMQRuX\ddEhKi5/Np<P#$1uaHcWq5Dhi8/CnI<V\R>=q%kZ5IPSeWiWS$*S9+WM^dN
EC&kZR L6$=CuDbe9p?aLKj:V^%Q=#Mq@idD1%dpb*W8b/PyAi!<HBeMJ>>RYLD<9S8iQX/=d$iVQyZk=8dIdTD
6KBq@Y /lwlb<@klGa+$j&8Etwial8FMYDe/NqQZKiQGlGIint%PMAc5AnWXwjEQM<^PnFXdDZJT6P\mhkqnC+&
e^h\:< !I5HGC4ewd8HbF^X*Mt#&&X$5C#aCaQHjlMuPXyHdE%S#<6RbAi=<D+LDZyKNI:ScG?c@dA9+h#XaDD5
yK8=8D 4!d!>^?RjcLSQCG#eD1/k*QR\cCaGCXPu5Ktb*D#bF<e8cSYtKhESy\Ta/YBBk&Aky+HZZRWd?14u8&K
hY#K!5 nCa!+VP%V9JNE?\EHVuw^IJAI^TttRFm?y?l$LD1uV<<mK<Y8$8A1DDiq#n$VPAF+LNa1QB8&H@>k@h/
-AnAy& 00041fae1ee00110334 Page 146 of binaries2.zip
/MC\l+ hZiD<6>A6PN=Tq?a/L4VqkX&=I\5jX4Xhlk4#&9Y!eVaFl5Z%4pMHJJE/q6bwnw$6q6jakwt*DDD#V*a
NlcA#a ^NkJnn61MDQjMDl9u5Z8twj6DWWu^h^9hytlmXTqPHZHGTtyTEPS4X$In=QQ+GuDl1F6Wjc^<?FG?Hy%
@4ZBNp %Z>>hV%<FlpC^yFI=cmNcN\F!kGaXk6b\P/Xil&wK5@S\Y^6\\P<&MAL6KWHehhcqp?\n%#uwI:wJ>Pc
XlAi6$ bGIul#aHWwk!BM>4bS8t*!Wub5l6ml>TPKEtPjP::AZ+:?XbbnF611$MmH^kP<W<=b1S?18+tT65m%9h
cit4l1 ahZjIMBeW5JSCww\@4be6u&5Y<9F%Hba4^=@mQ!EM<N&enRcSX9mCN\d#XR^FtRHSR5<^nyheq:?JdEI
Q=nI@H YqV!b>b%JA:adj#^&i6k=a<Rc<Z%hMiPk6L#4Lq+lVEtecm=/m9!1DlCmhKLiTcScREWp#8lp$j1am45
bdwVM% >Y8$l4BdGhGN6jbVZ=tV1i&aiKbFWhCI8eel=5mywYFNN8qIAd5&#RK^Q5lYK:!cu6tGPTuhPwQWQ>4W
DX+ya^ e=\q#SqXMdueRaR&QyS:tl%#mYKa?B<cSaS8d:D!QH<*pY?R4uCb1JV&tP1KTnRPRInDWyV$Sqk1Fyk:
*6GQhQ 9\P=y?m+V*m+%Wq6E<I:Ih&EYB8Ap6k&a=Le8LKDhMp4>N=HlM?AS4XKd&X4HETQq?D4:^4cPT&d%HY8
q/ph1H FPJ$?^BGiTipDj4ZQKWY\a=<Rt$Y^DKqtB1GR8PM\I9RH!Qm+S>jmTYnCTY$c/WW96=N?1?98cLw:8aK
5k\Ld? #W:\D9C9^%cu=ya<lk@B=>EPbdHCnK:ZdHn$PPj%mIM+t<DB1bwXdn%h9TI!JywYAVu>^DMY/ch%w>Ri
WnlB#V =4c!$V:MQ1FmF$CD>\HQ1BZnuP+5YQj%e/y%uk!J^9IQBc!6>iPMuZZmH9XR!!CyMQPHG@V<ChH>H=D#
Stw:AB RQqjRuM6KXwYS4=^jE%5@1ZY^G8qdMZ?yKc^\+8%iXL:HlWj1@nG^CLIp:h@A%<4Zj%X5^kSN64<k!*Q
%9n?/C wbCIVI\R@V#DeBDlFJ#8d8\=e!\$mn*iabIF!^1AqDVJB4bt88&#WLd!/>K:/y8&+uV#@lY!Vi\=Zpcp
tR%TqB WDXXPHG$Zpc%Nk6tAJH+%pQYNaXwjD*a>pZWBK%1!+\d@I<i?u^e@k%&tI$+qXbME&Sk$D:%QMMPFjG^
QKNp\> aw#$TET!tuQ%cDXX4tbM!YT:qM&&iabTZXtyk\Xqa&$b=QqNQQJNtQ\DNLW*YN*wt4D@YWK/pnp$QaD9
eDiJTj 1GM1S+aAS?8jWQ81S/N#HD/8*PA$G8W+RMH6eF^py9=XWiIMYq9JdZklZ>u+%@BI:$P#B@C6$QtD&9MP
/V1JFB tbnMS/WTLuKt>ZhB^bt4APD59R^>1Slp&Yu*VeGEPE?!\?@BYDQM?Adh8d*?c!^ZGq#%4+ja4<ESmPPT
/lJ99h kR=uM*l&J6kd&hkAKZDyTNcih#!Yl/mJR+59ilIEMc>4i&M*M+kXZEY?XuGmi5>/Kbdwme^Y&LiQD6Ct
/1t^&4 >LHXhtch5NmLVGJL*\J&eDTDCJhi&C\R4G+KKm!c8P&EN?k\%y\Ka!e>:ZD5@+Bt8N@$kBCjIGR+!Fjd
V5I%@k ?=pQb+P:<lZRD^qiKm\VP#^5$SKWBchSWXwt:FnRd9NRFPdbtMJB4iR96MMXI*:YT\?CyYe=Wp/IbZGP
liecLK L#SYZC%GIhi//WPa8>N5VKuS:G/ISq:j@$QMuyWeJ@>&l^TtZiik4/bbQNl9%AcD/m5W&ntWL+lRdDBT
&J%y?E ^K$mYG#c64+aK$=cXwFBkG:u%uIkJt#dF?8LwlhT:pFmF*^^iRV6MI?1dlJZB<hpK6beRF8bHBiKb6Bh
j<$hu^ FEHa5#nn#/!jAGp&IZ*uq*?\k+NSQkV8%*Q:h11q@B/DAT5LEu<Re5ZLw6w=k>&MiEA#/H#SluJ\PD41
1?jm4e kV55n&9uG@8iG#QISMQee\B=J^y8NAi5tS5h/D5\?$T?#6Tc<=/JQ5hahww1F44bKtanTnA&lLqCJ=<R
\%yEc@ 9k9FbKY5aZucwDnbYW56SAGJSQASZNX%&t1a9dVM89tZP/C6H^C>l8wYtM^i&w^Xew1YS%C6tSX%Fu4?
=tWCQi eGM=TVbt<NSm^W$%q!8!#\L54S94kY^$:RQ^5J+V!4&=FH&cY!Te5B5lkMBtP+V^nQnkhDn!pi@MyYm1
TuRQY& wynb!eF!CSLJ:WLqK^5y@I*YL#%Wyd9=F+\R9P+N=aYj>C!5I@1qPTl*dLY$A<hni*!Sa#A>/?Kdmm84
nXYD8b $iayywhD&QWMtahc!?j5SAdpWum5b\Wh6P4NeFkEP\SuENmBSbDdeniEpnL^>k!?=t\m*%qQnBC5>!w?
<:QV9y FG@e1dk^?RlP/6F>:M=QW/m4dk@RFRJ>NGI?5TMXLRA9NlKIhylVbKlCT*aJG<94=t!kcJ6mJTulGB5d
6KW$um nBb&HF:q!91WmRQ+Y6T%yc$AM6Dl5HlGWy\HTWM%YhuBXlMl>=pHk<>C4i?k$WAID9Xa?aPicaVpIZAm
tZKVVi Vn+4aa8$Sl8tP*cTiF%R%Mh/%h<kDcL6hcmhuq=5\w1H*C:b>JC<5E1l$Fb>:KJ!4RMKBLGSEH#XBXBC
njbb\H :cHSncH5mK#$WEjE4=Z8VNLukc?SiJ$RS@ACN!Eh5h96%6!qleWBZWM1@%6Qb?myci^A?6nJX1W+KYPZ
Mp+Vp9 nI1^6qaMLwJhyAA\=cAGSPlcIta>\V4b<eYCJ%/YHMhmq\CZkL4/kWaCCT?j#ZtSDl$CKSS15*pM8dK!
u6ktcc Sl/SYdZaqnq4@9m@mud8MIHdIAaRj5LFqnwM\E<BW?Z4/XTVBajKHAIcYNFCMEQXPh>w<\lnP#wkDQ&6
@+CQu* *BpG!614MGmtpDDSPNTGE^AKTyMVE5XMXWSHQaITEZqV&@G%G9DW%w<N!KW*BM%/QF*R86Db&$4kyYeF
n$G6uu &SECmS=dia\YkTciuuER:VP\A^BS4I9?&I/KWht%AqFMBQIkM!15hk4Et/RMa$BEhLSyB^>IZcXnFh/B
BZFcIS !$/l@9hW/^qu/M?n1#t!@i^w9BZ4%N4?qK4dQMeYLn9mnj$DuQ&nWqPFKd\Lm@LymBdeK+$DQ%k6MhE?
m9=t/% H6e+aBRw?JtGF?9m^tLi!<DGS6jDpm*SB:h6kH!%qwm+ih1^WAiAtQJEa<k\cQd/1?>F8CeYahwA*!R9
N:mnu/ SIYcjkFDhTahLZ8&Ky@Jde/i^atNQhW5SmH6Wy@we&4k*/1&9EP6/5t#6!8S+h<q%iJkT=NmtkAeETSA
LYTp1n <JuSHSyDMbR&yCLt&B+:LBq1%I*Nci58tEa*/8wyZ$>FRaXq8%iyjwemjN*4ZTy54^@P^L5mn6G/8mat
>e!q6C ?C?!Pi$q<9?MateH4YLF4q*KV65l1T^p5DMXlC*W@4JdCAX4qNNb#!q+&ICi>*hkm$cLcEbEGC+YjN#a
6qntqB 8eieNYL\X#AcblYNLXhcZwy41/h^<CLjpc61t?CAB16$%hukAhXXSJmu$8Ak*%Pp=&=4hj&pMu!MiJS<
ehlbeq yGQAuAl^>a=C6XNaCS!mHYD1qX#@48In&mjcaeZD=udEZKNaeE#alFp>#&d4jB*DGQDE=M4PZ>MD<%TF
1uCpMX XIB4b/T\P:nkRhEG@<qd?a>/&?>T=1:YPb9PDk#FnqkV?1JHnTQFFy%5nle>ZqH6RHFn65qFQL#n%Fei
cW<#BP cc1\8XIQ8?AJH+$tpFF@=bcP\mdla1=Np=8/Ec@VQJhVP<wdjaTCl6n#pJkAYeDdHHTKW<>p$V:JC5$@
!EtE*I qbIK++T?Ny?H8ZY4hV9VFDLjX:Nj<pk!q>yJ\MPVnnmpMLL6V5\lJby:+qmVmlXp8NXyVA%jFV$RD#IP
>16Dl\ ane9:VB@a!h?MP8GaEMZie@MHSYNP\i:K5+Ncb^J1hkiqVmeW49\EkZbWQu11iQBRSjj/T4PL=MwI&u$
wMj5ue QF$+W9G^6E*Hp&14kGQ$Ql@4a%hbhTjE&*IhbEYbd5Z=e4VDcy4a8RhdcZ*qNjwSm=*Xkl5ma>$deG\D
?F^=TH J6E=b%IZZc6DZq8mZY<XlSkcW#X8jRCuB<lbylLSlc1kGIiZ4n49c5h^CBJ:c4ScK5n*bSt^&=qqSJau
X=%EXw TYtCW>a%QWH9wZ8&6hwG%<#N5C!1+/#5Yc%el@^bPw/HZ6Tep<VS+a*PHuD%^WplPCbND1cjn6lmF#d8
uQ=V6< 4lc%Jit\FdDTZX1JNmKlX+B=aWT94mMX=&Abqj*8<J\kdC^LmHbJhE5jpVT%EID<jhH?q5nqE%X/4K8i
Ch49Z/ &cPcmVm6/XZ1qlR9/JJ%HRdSe^5MV6N+X^ydIbm1>SbTIli5Q&E=aLNZB&hwCY*IB!+$bQtE#d/G+NA\
QCMM$8 RZdmk!d=8u?l4RPWEkTT+Hb^T%tCk^iQ#K&h&9MPDVSQwFNE?=dpAticDp%+5yVY1qn&pnmZtZ:NTXTN
iVFA@! t*ela+X5$hi+eZ8$ckNCeGyL:IFWpIW^LRbSi=SVCw=CEb:WGk#V1qXapKJV=w!/euaDYbJ+:Fpp?/?<
9Ej4Il K*aA8@mTbZZ^MC<9*B#SYltLVj6InX6VMYe6tZ!m9TZa6i!\Nqpi8n*e^ZuXEL@@%b&94nCEXjeqETuY
Lh8qF# BY6KYa<Z+$:YiIdJ\<J/Y&nLeG9bTeNy=IyYupu1EE$n:LhFkpd%6RNMjZj?W/u^yi8XqJl8?YKymbaB
64PCQ8 D#ecYE<Me&\#+kqKHAE\N=6VDt8:al^mW6neCCX&kTQ&aIhn&!CW1LXXq<QFQH1YnT4k$&=BBBndGBpm
@?I%Yi S%&$Bc#F/cyD6:K?Xq95Cl$y+>dTay#BBYlCIRj!D$WD/=lIXLin$VwHMyCIPuLRW%6/c66uC<CR$B?\
1mTjyh b/*Xpu4FWPlR\Kk1Y$IF#4BNMR=LcG!*H$bIq:yF1NcMdK\??$u:q>RMh>kD?w4Xh+D>MW$?cu:5aEbC
#uQ>=* 5dSCB?1VZ8u%9kjDcSBMeep#Sq+m\%BZWXctlp@cEcNd6?!wN+*b6X^Flc5Pdk<A?n@kZthM4CLT5YQh
@1cuGm >+W=\Wb:jlRC^I!*5iwid+XNl=!1ca!bt!j4%!LBhpaRL4VYiu%<MF%whLMC?k@n$A:t<*km%&W+l#+m
!iHNQ5 yMkVQbpE9XmCiwGdhE^HR#8PbcB:tkK8IJD6lkXudJtSkLw88hbL^EM*?9HEu1T!dt%\XpnA*lBY%GMN
8&wRa= e:THTtGc4w*ck!=X&R*HL=<5i/iyK<bPB+Qc/wR$HXT\bW@+8i9/=FjuiG/kB/E!?/L4:85I^Z+it+1t
FHPKP1 b/d?hTq4!:Sbc@uESKNZX5l^dLpG/phYL>tJTI6KHKpJR=*JLT98d!L>CuJBL:JWRKE6#diqRje5nt<+
hMdT^M wSF&ZleM\WB^dE&D6qLLwFXecj$K+JCm@L>>^%WAme&=uMdDDtCC#mpudb++RtMS6N5B>L15k&tF15B8
^i>%8h Y=&*RpjE\RY\hiXMS%I+eKDueBNGYE!uQZ^ALZbRWMFP\k*q6>uMkChC66$SpY48?cBqBjP\McEYDJ4e
<1<=B? HaenSGNZ*=QcS+kDuAa#kRM>n9\dedYK:6ym!ySFLMm*SkA5V!GW%elX5/%!9h4<HwP%d6k+%8H6MEdL
q#MKZ# ZAne^HMXNMA@EF8?/KdFa&JDD<n+5t?HW>we\c<Kt&JVc4tamRYGTphlhF!n\pIQRSEY5R<8RH?jdA&j
^RHRu! >EAcPA=6?5EaS68/ueI&S+XcdB8%miFE&4<Db#&6@aQ:YMDZC8$95WH@e#CE/!=C?6jmaHCc^e1II/V6
Jq4ukZ 5dWAQPaHct>mnQP<YdDQlke:cR=IDTIlE>hS1TlDc8LCJWylt9VppJ:N\cDZ9ETBR19?ayy+$8V^CKHT
Rjp!dR /418p5cIJ^q:VEk6</KWJ!=#RHMjVLYPjmi^VWLE6iYdhl!mL@MGb\WX%6:L6AW*mPuA$6EXwZupPCaY
-AYwPQ 000ae88415600110334 Page 147 of binaries2.zip
\/\WL: YHC48G:51ZIjtD6qhtiBWtjFh!m+F1LlDXIHm^P49^jl*&EtS^MqSc**PDyFaC9H+mJdJcM#:C&Qu&hH
Ie<W4G eaV<SF$yS6LMtydnn#1XqqT1ZmC#b6!6G\QKWM>@be<QMleWTPa6Baai*LA+K%F5XeR<Jaw%PCy9Xtma
iJRbR? R<W^P%^b^q&CiuVnwHX/b@NK=jip>kL5*eSb>NXB%&:WXEq$%4=\BhYSnZyESIBV\6IZN^qdMjipERQ:
K6*/m/ n4YXNNHqLJWLDHAhpGIPuDR^>FZZ/jPILyLcM5b9Z!LPV=/#5TK<JSXhJ<n%VK?CC1JWK:GJRnQLJ=bl
&lyh/u 15ZJj@^Zqkt>kB#mV#l4BJ>D:I88mSj4lhekFq$VI6#S558!&jFJ&qjMlWJm\LDA8CGymjw?4tY9%Jn8
d>k6W5 C?#*@>$FQtdF9idmM+uZ5hmp$VdEMNRD?9k@C=XPlAENAW14<^?%b1mV+Dl9:l*!$*H99*E+QnPWjFM$
1$Yh%k @hb5i=GAuWH5!i%VP?pC8iQTyqmAE<<jJJcL=%:5=>Yl8mCIq>@\&ni@>9=:?9n@AXBLA\RWAAIACAAJ
\hb\J^ Xt$qQMGKE9P6AACYYRIALRAAAGN5cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>mcZy#eG^le&k+atq$
TAHj?b LtJ6eP!hja\h%ZZAD^XBPLPEn#!RWka&CSTVqE?#aFKN/IeIj4*PlBAk6l9S#hdb\EC*kGYMmj5Hh>VG
EKH:<5 H5iJ:6Rq<BmTJdPda61!Jeu/!w!y6FH:5Ktk!mR8ZXGTTlXcP%YdHiqKNRlL>N\:*?>n9Rcd^M5>*u%9
yLNk9G Q8:H:Q*he?/=b?/M@<D?%44jACuZuRy\KZ/@ek4Anjl:Cy!8nu@y>9T<pqP!Z!WQ1^>+?PH$T@/Vl@Dn
1=C98H %GWGDJ#q\eDY:ZDd^bP\#jPkei=??GCnCie$6<GA6^>P8&p%ZH::N4l^^\Ha5iPj+b\:>5HA4W@B$CYj
5BI1?: kd@cN\8*d*5WB9dE$G\&ainWJ?D5*:\L44q6Q?^@<WW+b@6BPPi<ZZDGKki8PQ5T8Pyt*L=9F\\<<*h\
tCdJ\b %T&HwQtnR:D5<mb<!MNn>&!DW:>!N=#i8BV<u^!E!:ajkNZj&AXZdu5cQuV6ZhBw9A+j@K%Q\wb@?lq<
5XGyD9 wupuDF#u\>Z*:wKLlqcB8Z\ZjP9bQSD9?\Ze\@+YX6\:C<?<ikk?jQW??Ql6V<Hbt%/Gkd*@DS@@$/iB
Xj@&RA 4L5V%9:^%?DMbk8G99EtuQ5JD15?MkqDD^/C1<hjlP>@i^a88G5:4Bn#+MD44$Pn8St88tw@jH:$Hll+
mn@$<Y eleaK>dCyh8ik\6YdwJ%Z?a\EP/DRjMY8PmTV<IF=%<CN&*+G:nk\kjlK#>>C/:<>Gya>hIS8HBwJ\^N
W1Z!>< 9kZ*lC@A$N+neMbbn<GP:#\F1?:+F#l+/BCeih=cPPQY*dD5*P9l&X<ikeaDQ\Q?\u:+>Lyu+a4:><B>
SnDVRp V?\C^*Fk+Q+IQnei\eD&9WA&dIN9:u+S44q&C1/=cT?\k%n8$Gb+>95@kI5jcENndR5G:t*B\%?ckZ%:
8q+GId Zwilwj6l/C?i\P?@lyZV4<LR!nhk=X&dai$Xj\>*dQbk+>i?n8iG+QQQ9AS*d=1GJ@@l9<B@aD><?aaj
W^/@hT \4%j@W8a*95CDL#<Mq^&&S#<+e$MLl=8a@yd+NZZZwQjMV<F@#u:T=ma?B/e<iSBGQn&E*Ddna@BVZ?G
i9uWWZ :j:KRhl+&@P\+ihH+Qy@QRLni%/Ay9W5*L#<jtkP:aDtD*<Py^4uA*9pMVn>yn?C&>i5k/E9HkHn#wjk
$jQPV: E4IJuw:jlMb%B?DGG@<e>9*Qadl/^T#<:!@?D?=$N5Kcpi@C&k$lnDX*a:<>AGh@@RA$lk@Atih9kt9?
Q1%5yu =BZa<S?H+ZM:PT^d@mu+&M1%<NJLd<LR^mN\SVkLK#a@Dnjj5\pGJk:A6b>bB&M@iAt&Q@+eVL*<C6#*
GcX9># 9Rmii@==iQCdn<I@Q9McjGS\K#VYdIQLd*pEG8j6l6P?eDeMVEh\%ekl?P&%h$Ln?q*R?L%>eNHNHC//
W!wLXJ h\<$X8/GRceFb/%=CC:@@j$\<J&>5PLS=?Cnq%<Q#d6&\/*@jkVMn#$G1?=?HJ=@@kl<+N##+dR%Z+RQ
P5=MS1 dQ+1ZLH8IdDZQRk@Qu\E*u44Lhm\/THp*aL9d9<^4L:\5@CVu@+d4B!<DNd</HYatbqBnZ=d@eDdd/hj
W$5@?H <y<<JD?$LE$^6T\=$X\%X!&c1^dNXa9t1pX#%X!Qt:CY/?6GZZyeDeIC*ckuN%hGVbQ5>G&%ah1lTbpb
E6djZW ^ncZ?<I*&TCNLb1tM*c/6tG:6lt=d5PMmYuT&DSD%<YWLh8YyWY8TiLRHI<^XdkV!!Qnd4\#NL*aIJkM
4:?!/H !&aYy5V#nLnnG6\J=Pw\/qwiN&MJ^tGtmEqCSYLG\k!w/XBCKMe#4nB6t^nEnBLcCwqHPGIJEl<VE+Mt
WIj/w= EW6pcY:ml+q6Y1:SaumEeA<*8VBFR5MpMHjcZnI8PPEMT&JEk#6^ZApQ4IRbDmt=iw=yeMpXFVZ\VSHI
A@bpW< M*LZFZaW61!I&:d6P==JA%9+mY$LIZMkJ6K!tdA6I+qMFnQ5Dn#mVGZFHM\%lMCDjlAq5dA%6SM:944M
pV+YF# TA#p1A!y+^LWX&=E1K?8GaTt+/E8!tS^kC44Ba^Vp#mwuX:C#MD&Yu=Cca5q1LKamLy?pHl8lD*BFbmS
DhV%/? PF+Ra&iJPApCanQdnlLCHI?#pG66QdFe1Y5Hbt/HLe6GVdI6%#F6^\$MqqllEDM<I+I+6GKZ+MlJtP5K
w<4mZY kptS8?WL%/K+a$qRN648\BR5Cq\LjT?Lew@!tDQdNYQLbEII$<YWym^AW#8^ZAqH#e8=EyMR=PMScZl^
K*hKBy MCW<NItZ1ld8!htQb/DDnL>EyTVyn8u=V4yH$yR1D#G+l=6b!jJDql$=YS+6J*Ti$*CJ+yyyEM6G9uVj
EX=*iK Z/!=>HwbX9TdmyKpCLuqB>wE9&j#X:>RIbK%?4G1qNj*aFtTKy6+G6n^=/wMyB?YMRkY/jbdAq^dEtua
5Vjt^L w1XySI@%X!1/Z:$L4n=Fu+emW+6SNI9MM5%^al4w%9k+b$FL/S8tRbWJD8q+caqqFpInhbmaEWp=GL:e
q4b1Ki q/e>e>^V8!wq?qT+QT+>K%tGd%CeFXGcubXF+HlNjV\ZlXlhcEb5uDnTVI@LHK4CmPk+%KK=Yu!uVaK+
a<JQ/9 JW#LedEl+<VAmc5yY1adYEppa$9CdLqE#Yibt6mkK5it+cI&S:HDeQ:18l=Hyu:mt:^q&wMC<#5STRI5
e?/lI& Di&Ac:YILDKRCXVHMVlqeiC#Rb8$*JcN1WZER#8&E>PZM>mG:VQGjiXYBbEIbIXYm%FLA%$pX=1k4^IG
X&N5DA &J#EamcZ5$!t8Fwi>/LE6^XZ^%j8ME+#ZTQnmuACqbW+QpqTJW\<t4nEwd+9QX*1YJ+XSPkPp+Sml^De
84RX!= E5wVntM4MIqICLFh^lG!+cCPJtGMeE*c\w:mw+*\PXZPXM4XykuPpjRecLFeY*L8kmwp+:ZW6P#Iw4GM
ViT#Fk ?A4Zh:C6yewE6mpJtt<IRV#Beu&%Al=/n8Wa\4LTehlLInh&DY:dka^D^I!=64Cn\DRVF56IeKK+8G/a
Ap@\89 MPK+u5FnR*C5YpaiTSITFuM#6NBRCE9aVtwce1:M$VCQkc548S1PnQ5+FpY>5uFWe^$1AlI\P<E&yRtL
b^IFW& 8JDlCGSqFF^bEHF1I!I@+n#%6Z\8anTXFlP^d:tS+!E@NL&+:^m^LBI4pTamnuDeVqC4p>D#PBNIMk/>
l%IaT5 lBLKAtI:YCj&45DNJ5mBL^JtCeKF99N:LHba#Y=mBEiyT$*tweeVMadim+<KJ+PDDBQJY&>C&DGcb^qP
$QMwaj RBYYI%/I%yX:Rimu88RuTaV1b6k&CdGVMLT%u5pMI:a>hIPR4mtp\yLA5mSh4C!Y>?q5hKu5tFDD\Q=A
SwC&LZ a8\pDC@E^^/Y/Y9EBG::&hm8bXF?E:w69hw4w6Zapm%yplnB54R#&Kd9wLYqVl!dMS4j#A:npe!%ah&F
\#pd?Y Cy=6&Et9GqpcqQA/d?eEi4d#n8a=We@\A<$mjDZwIe%MwijJ?bEl<SM=ZeuC^JGSBwy:C<8>YcNZlTV8
WMAk=S p>QZ5eWVEpjWw4q1Pit+lpJQHyee%$k+mZbjql#ZXyIpiyK^=Lm/mDZYVduE8ByTY@Wc\cZGqRTIXc@^
c#V@\l Z*JeySFP>Q1WyedXpqm%$:VW8Cy6ShF4iyeW%^^4pnS$W=/5ZQ&RCZjR6eM<$E+Gp%Kwd58VpC6lLc:\
k19WNA YbV$$FaW9X#l=PNKdTiF=%cDlTKymXdap+\4!/DY1by&HY6mKd%8GKq/S:tiC=SGpVFW8<Zcey<%SKP!
icJ=:5 d/V:=Y:?BEEnT%+5JG%W4mW6lhZ4mDVZBSN+4a\dy*%eyq\WWi:Kb/ji!P<CiIPYc:p<Z\qBat9R6aJp
FwjJ%? 9CnECZnAE/QwK&w@4+pt&d%$p6m!YKhITK1B!$HMlhu!ZG@IKy%Ee%%RYZN1d9$&uN&FNXFcF!Ze+d\n
@YR4+I ZM!T&y1GKMhqYt1BVFn5^@ZAFT$CHm#lYG+=V#c1pe6in^&Et86CZI5^XQR=ZlGS1YDwB:#RK>6CeR1u
^Q@:i5 m4t+G^S1q!=Anay:jB%eT?Bt\KMweW5@454X+1mkyVWS1k/88T=\81cLC&QNY6yL1Fjim\&VtKEalbyb
ea6QKw AueLYnuZw?14SB\tSl?8F1Y$QCi4FM#VZI@KqZhkybqy=nY8tVaJ^:I1GpeNalmp+C4pZ5Gkbjpw4NSZ
?yFdcp ^@e>9%mJX6FZSF/cY<PIp6k4Tk%eD!ZKu>cWXSKDcK=H+^y+QdW%qk8CK=I*8%YlaRS!8HWKI^unPMth
KYl%8J <tqqPYy!Ztky=jJ$5ZKW<9JBKlI+BTyHD8E<Z@A9T$Fy=dY/cyh14k5+\$tQ8#WbX9u58N>6l:5mGwTR
i:m&#e BjdqHqpkijXWQSPy:Xh#EbP<:>iiL5nXh*wEHDInuNyP$iW*cjt%=$y=D%!=m1bKVLkPPJ%5ZFNh:FwK
YBdNLX EjE1^LknL4GALNP6@i9AqTahk?5!?XyL1dFBbbqcEdjw:kBhHQ$w<86QZbAIbXH4nk%M1J>GQ\=ew/S#
5?ETpi JRRSV5IDIb%em=RVth4\Gq48aMHehRjLKFWay!cdY&^Z*uQTEGZ&tl?KYZM4II8yQI=DYJCtnI5Jq+ey
AcXcJ6 !nCFGd9qC*IN%^1$*8?9^8#H%ZA/qhAImtt1d*VmS@EL>TYXTbLZdc@#95L1Bu!\uAKdV5&>XmF1T+n1
cRR%mC cB>XK<I=c!X&Eqet$=y4l:lhQ1:d$#<Kc:h#FC6iuj^tQTANJ:5$Mu!cQ/i1iw+Iw&!Zq%uV#qJ$KJ:%
TuHTj8 BT<wc+?1KhK1\5wbdtm89dn8VDyH%@HiA&tlhFG=c*dyc/PH\^#X#Z^WKWXW6qQ>m<5$Zk>>4ZJ%i5R>
mCVR84 Nhi/hR%/AK\:9ubNZY6e%S#IK<NYwwhjbuTW#:KIXaY=X&H5F9c=4:/!SC>V:<9X/k+lXTIR%X9Y&cDL
6nHuiY 9bIP:^yjYaX<uY9F<!qn#KSY8clwbqk58Ptu4$aiC6Ne8:t!Dk?u9::/Hcm:>NZIN:nZk&9qnbiaJ8Dy
6eakq% AT1>=mSyqZ$5>+KM+1L//K6/?5DTYH6#djY+Qij%HF>Fl%:*%Fi@y+Nc%%hb9G&uHRT@LFcwI/>tL8+9
dkB:@P >NFZ$YqQNFi#^>\qd!FQ>QcHnY^\JVY8uiM4:ZTcquX#qSq>t1=D^u#C#&5*cpN#Adt84@p<^>h^/kY+
:uXI*9 &y$l*+lnG=P+P:^jC!#$>aed^jT&9::c5n>+clTPFKP<yn11+mG9Dn9MW/+6QZNhkC998EWnJ=C!MYZW
4w8YQ+ J&DhwWc@a^RtHj1c\+=hFQuYu:Cdc^1d=DK#WMP!XVY+4P4RPZ*6MF6MtQy>!>Z4YD8cByym>YLuiuSZ
-A?iK< 000ad821ee800110334 Page 148 of binaries2.zip
*uKnHI VSX4:$>mXe/=9wyWy$t>8>A1GTM>G56QT>X4b\c>41>YVX?LD1Y/WKR/yL/4%I>4^jPXYLKIIt11$T5t
iCPJ:C XZe?YeX/%@SXKypM<phF#IlYR%M$HW+^ybWlbqYu1%G%\%dBNc#yK%WDmH/bZn?8nj4cFm9yMi5yGAbG
h1jPHM >#G:R%>4M=w+h+l1hnlPDTmcC5:TVV@uZ@P*p=4jJD455P^Ji8:cn&66cVC#P6iq%RhZ$wP%W^tu9W+j
8P//d! ^<&H\Cy6I#i9tIYuNbGeY%CytlR$Xbuqm1hMi<Mi<R@N6Sd=/bK+y%d*6PG5nCl:PS19HCGDLu?a=nwb
jHP\L* q?P9qTGKK%Nt9^lXw@wE1#y@%c<\PSc8Hj<bTn+I>?LKuVJtaiSHccq^ww84!D5DK^%5P!tmV+YV!\y>
#yXa\w qF!=t:VTl#dL?*T8ju1?H>iim:+:@BHSt*b1ZFqm?XqIn^e\*TLtph>H4@lN4Z#R>e6CcXcy<4yb/aDV
RM&hKI RuP=L!&>Y4ZKe//1Xk*&cQ=\:$XySn:whm+a>&&FBbZGnb&K\<MKLdZTwk#jV$N?98?Q?%HbR+LCpEwu
XICwu\ TAEKm@8yeZFu\E@u^IYdXu4H9q=C%+h4hLVBNe4n^=$L^4Pe/b*\4u8w6tFGdkct&>bdbWJYnMS&aS!C
KXFDbB $DSEAVkLmBDq4MjbqC15tBJje?*mT41^XmiyS5HEJn%:BC@VqAbS<N16Q:jQ$#%yuLn\!#N@KR!K@tXW
ht:lB# jHEb/*DVQqib#SIXp>L4JScKD*hnqa9Z$pc%8=>5W55LI+ZFE*E51mqI!PR:+:NDSlRy9R1nZQI159^b
ycXPF= cWYQadadC?y%X?T4N+>Zw^TLZ?V+Q8QcbakLQmRji\Q^41j@6ZnV8^Tm%:+5kt8uqe!uKPFPbW!6tB&Q
4C%&M+ +a9&tCc>a?Gc/!K+G4#:iYZVwE\\GuuHK$=Hi$!V*4FwjX$M%=4Cu1m+*QHWX&&HF<Y%/nn^E@Zk6?Ei
Lb5LEk S#55NNine^Z9BXbVQc>**G/?iK:tim#^ylQcYPS+LpWTtt6@455/\5N/DhlT$hh!dA%5@S>6L^t8tSHt
4E^l=! 46D9AF>CZJqCTnZVyeW%nKtu%\e6*dmEF5%Xm?c1SZQXw4q1?hX^%c@qi1?=dpX=bG5l?id!=X8uqt>h
ipBPVB QwYjW<8ZV$&qQ:Q!b*c&QhX86%i*t/8dW6a*%$5bZV@cJbNTSuBDJtl?6N%5#:dd5:Kw544$J@%/yHyE
Nq%jwc ZRdYL!8hLi6LK!5p4Zh!bHlmb59a&Nn$tJVj*dJqS8=M#<<:<@Nej5##cdtX@p=QV<8WciK^LTk#E^QD
8>HD9* E*N#p!PV8a\YH=MnI*N#E^PacqytHb8bGB/bVQ<wiWF6?WhNVYX6qLdTqD#Yd1iZm=e*QKH!an%#I:LR
@E&Mim wwFpBXn/HF+?X1C8tcjZ6&WG/#p<p1chVNP1j>q8jk^@5IDl+Rpqe+j^eM/%W=At!6d$X&%ZyD&q5PJF
:baHMi 6!6a1%T#%qD6eSm44DiC#C>LZw#pqdhXqWX%iYZ45*?!Vt\b%T=nY^TuLa4!jJj\:H5/a=4uWG&CMqtX
&Hudai $ZJVkyXF!1#a=MN#SY>N@/mWdLYS$86N?!Bi*bc^cbpVc%EF==^W&cy$&Y@Gmt8Yq+XhdY=p5tnWLMNw
>lFJaj B?nS6N<NK:LD\:InTK=Vjh1#RuX4lY%:1kN45+w%d+t541\dKdB=G#TLJnlG58&!yVKc/%P$ce8N!C/j
JP*S%5 IqZ1q+L6RZa?TS68juw?w/y!bYAuP&Y$AD8uYu=c=6&!bZlPNi@/=yW**JCDdhi^X9S%hA/9VYYeTK5a
KlRQjE LhBtbShk=*P8<w?aW>1h+S566dXW&9R#B#85M1V/PuXW1qQhZVHq&5/5a5+%9e!SAmqCueFiZnNd:YMA
MnSV\J Y>Sh/$m=Ie/$NdQK$lJLtNkeM\yTd6bKwLlh&S8d#?%\H//=Rw&YaCe!I#CG6ql1:Qw9HFm%eiQG?>6X
Hwab1C 54qBK#8>9DmFVB1G8d#\VQ6!c%DS%&SiZypeG8bKp@*@nJ^9cB6*t5h*8VjP\X4PHlyKDyie!dSIS9Xb
b8kpCH PI\*S^5:/$NTc%JTIm@tPF#hwBa!Wtllwt$1Ei6FTa+i9Z9VJc<PD1R*FeE=mt?=5wu41w^:cYni8LW*
e^VEJE M:dmhZdF+6*F^Y@!>u=@u6@9>@^tSpq@p6*EV1*SjPd:QN@u?V%nVBaJql>q1dSE\T+6ac+4k<EPD5Q!
HNZhI> LPhq91PbkmGFwMBQM+%!E1\MY*DhQBM5P^IQpdXX+PhRAVM=PW6L=AWJ%ZZ/&nVj4qiXbEukyTmSalHb
J56$55 Pmed$m5EQT$YC<YTYN#@bHLYKqlN6%a#h#>@naQqhD$eZ8my/T?6%\?BK+BXeXnVc%WeLV8kWptASBKN
Q$nF^m <#FM5j$q4t<Yl!NeWh\XbG>E5!5Hm/k!4P!mwch%uVG6%8G$LjZLKMjtRdE*uk$YZqyL/A14RM6iu$bm
dZ#4^6 5jlS5BP%!l=kpk/%\M^IA>iRZ56K5YWWm*pWwQ@4&j9@@K*l9HZM&nS46hwIRj9<d^ZWqdBi?/$1BPIY
=i6CJW %15YC%k$YEX^iEuZc##T551^lC6LD=!44y\XdJ5mi9XW19PRF:aBK#8d//BV^uTX=/MY#$hlw*HnB<Sm
$C&EXp HQ\SYc^YqGKJVup<alb#9T+<M1QKLHC5amETc+JFaR+uYZ4&D:>=?*>*ZDhu4S%4JM!cT<p8n1S*duyw
kFY$wd =bF^IptmZtY$YnIRl*?8yqeil:u<hIwD&Jb+?1N?ZuDqC6Z%Pkl6KA#diStEtX:YEXJ^D1q94=JnLC8\
>MH&\w W4HQCMXT4yHZ=Gk^Xk/YI1XR?#Vl6PTl1LY1KZa%LNlREBdiSBGk=@@qj*9>knHmtwuG&64wtEt^$4Y@
bwa\BD YJ8:?dpZ5S@MEIN^$y&Vy6iY^Qw>5<QWD=hK<TwF%/mXICRJq4l@FuyFdFh8cQa*Y8jElGH8Y&mq$XJR
E8l*aJ 1/6c^KNk&&Y6*9plTXaiDL!tl!549tR8wFiYYP#1bd+NDklKwK18&C4Z4BV5AL%16h8VZ*=>pDYJY*JN
11H>?H w#F/cVlL+4AkP:K+:\Jc=QI\X@I!@d=t!%TCSZyq^SR4e&ID5R%QP=SnT:#eqX\XXVmVadip1ZWqFBHl
EK:?CV y%K%RpdqL9VZ:IpeyAnFNmnYi*cTnR9DT4EKLP>P$BNW/9Q*^<M!#@L<k^=eQcSaTLH%iMHm\MekZJ@@
Bj5R=N imw#NWcy%mnbSmYVbXDVXK@$5d?+u#b9ZpN=15\NMR9El!wR+<bHZB!85!1=HhauelcmK&PD6cd9t@p5
5^/WXe !6Xd\awN/#W&EH5idlJI4jBA511XFlD<&B8maGM:FC9Q%15ZW?yI1Pn1K9HF%FDm?S+!k$C4R5u*C1&M
TK=4/a ^JI4D5QTnY+$*#!wFHQtCKNKXEyC<X/#J9Tc=tD*F$@Wd8bXi4Y=1X5H4ky5i:BiGXhcn4JZX9K$NdC&
=y@+4\ Fw>=d$@wXbZVN%dmwN/I:#ZyS<*:QdRVwNYL$yJANW>494aYmy?ba%iRa9NKBHpMXn5PXpG$\Ww\l$^#
!*<*GA Qu?ILCEPW4tuReaJ4+Y>*&hTc>>>i9eebb4taNqDLw1XyNu$K*4VlpYTFllyGwn:ineLGp+6FIhyIeX>
Wlt^h/ E>c4\kyWWeeNC4K!+Cy4Dwu%^1A\HNc4T1<5/NX^Wq*FSyPBbb/lHXQIDma4L:T+%1XRK*9CaWAuAj+w
pQtFJp ?1cK:L1\/bn1+TF&^KG?lMR/@@8D4BF<?y6Qk!RZc=wl=e<$1QXmdZF^d9i%9L#\=bHSCubX#:C+T^uX
<%\Nh1 K!5mT1DZ$MMYH\k4%Nw!Dt8CjWy8ldM:\A&Zqq1wC<cq!p=XZX!I$FlqjhYN@EuwQD$:E1>EHZEaLB!I
>Q&=*6 4e4*61#Yq&lHuScH=Mt+MkeRcXBAIB/pX*9miGi6EN^NBn?btWqKuZK^yyFiF@juZ59uWbM%L/44JZX%
NG%%$C 6$Jk?$K8hhF91qcFd+wpXYEbw&VqlRl/SW*4iK\*+8$\Py9W@/>L4DyXKQyYD<>?<^<QHq#=h94S4H?K
Q*R!kA 4hub1/jiQ@Z?m*V#cLBkd?AG5ajneB:C5L:Jw/wV8hP^#y:$R!l&>XAQ^XFHZPa>IScB=:1XZDD#t!C+
q#W4+p G<#<bCb\TST8mdV1Tn6MBH8m6y9HT^tREk4EKMNK8aac^JBj&Z9S<1t6%?%AYG<#C1+41GWh%^LY$88K
n:cq^I uq=FpWP#//4!TuYX5Mmb/m<>iQD!9=</hdZ*8>=Md&attIEX#QTCu9<9@6Y4d:D%1%@^*dyIkw*wNT?V
kHuWmj 1!\u:HDl44c\SCh19TY:aKHGE#8S>ZAky89SZ%LFSmMZjEwPN^pE***Ze%*Gp^R+yqA4DeT%@duJc*A<
$\AF?M Z9=!1GCRnymD:aineMR*/Z4FMqX5=Zi$9kZq18>FQCY^+la<T1>1?^MPCXNqq@@%/=P#y*1FZwG8Hu9R
>%?Q9? V&kF>JNj<A8FM&hiQjM1y!8:Z#GPYFAXeSmBDi@@qtALR9aabSNKM$>SS\^k#+>q!V4+$WHDJ>ilp?\X
KtHl+t 9m9pVBS<qY*cd:Lnwph#ijdCuy9Z#LwTdDZK6SY1e$RedpN/SZKN4nLcV=N^YKR=L^J%9aF!DY&5<J/E
TC<biP &J#W6Zy>j6d*C*L%JF8h4BQ$A4Ie<kme*yp#X%@>u:k>ubBi\VTF?6R/Ybym?:Db$iItCmJ^NSTIw^t&
4<E4Bu *J:j8u*lW4j#w$/HjB\4#Dm8W*nL5w\cZl#^@pJclJDh^JhdS!jM%&SFy5+SCLc8Z1e95Wd<MG\Gcl5e
=9Ka*A 6l&QN1LZ!PdlW>WKy>j#\IdCBl$4e8B+1m19Vp::lPSMwaDJ\mNE68e:j5@^k=:D/D4?tVN9aLVcJwp+
GwEAQt Z!kPl?ewwq5hT$6wt!tmYJSlJhiFY$hH1W=umD!HPyZWY1FutG:8^/PnY#WXjPEQp?pF:9RuLk^*d1Y*
P>SatA F@e98nbahZ/TbE\VpbmuKIGX8e6/1H=q=n/$!THiim^a#DWjB#cP6KhNL8S^^=<i%PG96aJleucYw@^P
wVV48a mXW<hckPi>KQ\HDIj^#HwZl:@6ZjwaychX*#5l?l\GyVG&1Mkm8&#*9GRFawX6@hkR#dq&Du#$>qy1aP
QBwWV& CNXPJ#Qe5Hw>w6VtmN9IFt?QaBhM%?SHdHlka4ha/ZT&mC*i*%=MZ?NH1kY%XRt&Jd8iRFZ*\*RMB64D
KG!LZ8 EZtK>^+F!?I&==wHIV^L5q=INYwmSV>mh5mjVQ8FAc8HNS8tC=<IXThIE4/?@/JtudTCZ&D%WLJHHVbS
N9tZ!A $jIiqEDLh^FlB=F*KDVB!kD=4%MHB$MHB\eEc&ZN>*8YbS*Ld6dCSMqcVF<=*Xy1Z%@a:BJyb<b4&@6$
tcRbi< dd8m6FabFpXmRbc46h/1%@W+ZEj=6S#CK99m?ZCKXZ1Nn<SinGIHy6iqyZW=IWIQ?KMQ@AFIYacXVA8K
tFt%1c 1TQBktLJC8ku@>RdL$adtLyy!1NMym\G&8ykVYPtYm:a>d4aA%nFLW<6\&+eQ#maIw<lI6uMtt<anhHl
CdG68y +V*eYIJ8^MLp@Y4%>Ehj*e1Rc&Cw&>!H6bliEH1%hSemFE9S6wC15E%X=IiFHR=VBaiSS/4FkXl\le+Q
\?V<Na 1tP>PN<W&1XV:jbTZ<5eX/aLu^aKV=N4nF+LVk>lyWcK$cXwp:**B@TeBFpQYYLbVEZ>6bJwHQhqB!1$
#Gyp$y tZmIk\$I>9X8h/#BAuFthM%^ZDNdKVa=%VS6LdF&MBH4@dNu9@u\#b>qPnRXF>MT/*d/5n:Y^*4wp15k
TcFI^/ 1<T1dijwjqnHm9MRFm*m!4bDbi9H$\jWBuWS\?tXNy5kDJ??Q%$IWD$VXY5l#NSSH$K6YLCW4QQ6m%wk
4aqF1j Ft<uL?M\KAMNQetKXw=hkYaBLIVmR>n!nAl&@qHC>+&6VGja!6FDI\X4$=S!baKqYB?jj8pjQ9!u1RNG
-AZee6 000eb2758ad00110334 Page 149 of binaries2.zip
@h@jGD 6d9F95/m<PLelJAW1tHBZ!K!HGwhnTPK@hhIj5$L5idqy/lkdc=Z6S&1B1?EZ4&uVJm1\!*%XSm?9?QM
b#N9yC >FT^15HW$?5M?VRD^T9@eDBbQ&B\h=\p5D*%@I4&/lybyXjw4=XqG\d9uuK!hQcJVV>BLJb:FXXqcN1V
c8Acbe n=cNuNZItadq5#^9tKm:Z=PmuF!/<mbN^AR1#c!eK96&W>?nKP6%91kH/^I4dyi5l86ZbaEFT\qX9IcK
Bw$\e: WE!9e8VI<&ST>iL#c>!wHdVI8B>+:p4A5mb1Q^Vpj<WZ+/K\6MRBN$&kX/FYWna/!iV5<!6cc!K9jJMc
hdK9l$ cMM8A$&@<nVL!HLB%qWwq4=aC9aJwb4LJc^G\#JH!HEb98@uAC#N1\Lh@8S<?\NCqiSkuqpZ=Zh18:cW
/9:wiZ FJ4a=GQPTLF%ucw/puW^QFRPdWyCS#!QTuq$/hmkX*q8qGCScL%\tdPmV?:a$k&VA#4:te1YCK&GGL+/
y1nD$< w%6mS=wuGaaDbwp^YDjy#4LbMFT^=qF?%W8/5l%15At&At\LV?\w\d=$j@1Dw&b#PWFYw#E/b4m8+ih<
ZDE8iM awdHt&G^yl?*#@>5C1kPFhPL?&14:y1Mp>yWCa>6%XDDFWa=SJZD^^HZ%bmy$t6iNYNA5h1%k@W1y*1F
@:Wp#\ a1Xa9S?YZtGL:y5@$q+S&N\I&J=PNq4pPCIWm@#cm$mYpN$=>Vt!^NkQw$HF5GDF>k:pYb=m?im+GQAA
@VNA#G 4m<>?dbH\8:+PIYc#a/tGuVmlXJ6NBwt*+pDTY/j&L>8E<5MYEuST1pK4BP!FbdZdE&:BJN9iP^A4qA^
%P6%bR Djp%cwNDY\9IuNGuDX\=YD:AkGQ^wATd>#!XZ6t<G5qXd@?nQ?Nk8jbW9^C^XF?Kb!9ABy#1n5m\qCy=
b1Cm^t JN%#:n8j!$IL*tZMHEYpD/Q8uCmydXqY:##**tee:Py:u#$!DN<!HGh#m%DNFwe4jJIy%&m5ba9n?$m8
@6icQE &?tFnjp8yewMW&aebhbFh$KVqV:T$Y?6D\B:mDdE&NlcJL?Gw:DidlMbX8kXi&IQbhhu/qWi/PtZj&EE
\B+1%1 pCNymy*y1RwXWR\>b@m@^IcaJ%hi+jSA1SR1X/^Lu?jMh&:tR=i8F+uDEeEK5KY&mMVWQL*$+GZj&HtP
5JSAV/ nw/?@QitT%!T%dAe^<kYK>%KybM!ZDclq56YM5Ztww#BL?^Q&8XHFT=YR4ddZGSK9enK&4Rc=MlLn+hN
Ry=D?j MSyBpEC4cPi\YlX^8C#uEJBhm5wXZVp&:#hyN</AbQXwHF??181%*#4>?p>>wnDJSuReCwP\>6liZhCd
ZML@eW ATe<A$FahTX/Yk#ieS*$TJ:djihh*VtF4qw:NF4MNqGub>?F9V6?%\Mli@1#9&Vy>ZQ18je?YEm:bnNH
l<:AmM qDucMMmFqPlYMypPq!9hp^5da%k9A6kFi?HCFBh4b/m+JVI8yV1Qh@#Fkiq#%m%6CEFMdYkDSC1@cyPZ
ut+bi/ MXwNlT1l%:I6k^t!^QH6J4*qI>L4S%>dZGW>S?5$\GilT14lGdd>T9:pY::%h<SqFu!^X?j$Am$R+@4X
hSGZT9 hS\Bqc>#:1p@9CLQuBhuuNRGJVp%<>Pd#6&p?^nQ^m<>?PYZDh15yBc6Xp8d#jHEZwQtXIhFjQF1y16t
u+8y@B tMA9pjS=m&dYD5?5aIPbt6Mda8cTHN!=&V9cBqVb^1Pdk&+KE%l^j5$@qT4P5PCHpX=SFS5jmn&6NRBT
PY#1h\ iJ^J?a:k\V@BEpCqTmqb*:jY4MacZa%S<pEi=A65?d$ANuQw8Tb^jahuYB1KheW!5uQV4?SSk#lCX91w
kk:nRY maY>bie8@VuV11@+=I8HYZw=Ru\\t5*^&+t^dLE+QJ#k5h?X1&b1bAt/lT=4HNPhu5:+Qq4y5nC\?aqG
eEIJhC 6#n*Y5VX<h9j?NnR/tH51qdX=49<eVF/>YJmqa#DcwwMC>ad5KGn*/=aL6@:KqMMHCW$9pi8L+a$IGda
R\Yl?c 56bGL+$YS$jyXuWn&/CLGp%4nbA>^9ETIS5>S6cAKP\cN^FQhLyH#Lp@=KMhy^DamaZ54JGEu#WN*8q9
ecG>Q$ @6n>My5LICTRyG+5d&%6Ec1y+e/\AT@HZqEEa4+hS<iDJ&%:P5P&A&l%W#uc*6<YVa1LZ@Vlu6Dh=Y/t
Pw1/!? p:1ySiK<:w4XHd4jw/eaIqyj=#ia6yWjDnH%hLLKWEB?Lh6/Da9A^t\GIL&Y:a&>k$!Du^pH>i+DLFT8
pRJ&!e *IJF=DqcLBc#&dG^4c&^9c&>9h8*d+?Q:+*uNlPdPa8XEyR8b?6VCptba%$Wl^ZbpSE8&4kKF9:!:9pL
N?N@=M F\#=k=LGhZ4=j@YRHLaBXCHt=/#5XCbDi:\J=hL+c=t8HCjh4/WZ:Ip>EC8S/@GLm=V4C>SLLcd96=aw
8&6dAA l+*qC?VuFBP9^e</!Z8J/nH*Z56ybln*F*++d>8+a9X\GSA8y:li!*A^iHB9KkIdd=5<eZYMyDKb^q*a
*AyHF@ LFXk\&8t=/<XL^Gt^!qVR4Y^^^iBT6cjTRkeH:<>9yjLJZI=T!#j#>EtE^W5i?^!N?!+wCEZlEVRjl+i
?K\M!/ W##Jc@mV*+=qG\c@KEC^e^5dD+>*MqdCpS%wGlnIP$ntml*C6bJ#6HnQ+#AhK&Wdek9&^1&8DMGh4Y&!
QM+QAB 1F/*cW9^8Y14Xhwa*!1T:&iYbTV^R4ET\Qb=q=1*M8t+J4*VYp#u$u6+q:V>uAF/>cJ^GHG%<%y#+mqp
bXu8+@ qX/Zm>%MJtWE+11Ze6XVdMHQDlhV^X8*m4i!dK&S!L9GI4BqJSJ:8W&Kqc^t</?cBLFB&QwYj@1?aXAp
:qeb%$ P*C8CX%^45$cQ>%5lM!et=%:Bh:h^MV8*DT>81@>h#GSa\cIT=>@Tp\hXK\e\^^IZ\atLWhi&yB1la6w
HkY1yl X%\@SK%#QLM!yJ&l#Nbjd=@kZMqn?<4b%Y44m+eyF1A48^ICmyha5mX&^^??Mi\R@eaLPn+Ji4ZLWaQ6
a!1Hu4 wYjwVtTbZ<8&1tEnYAh*l#e#taNMFuRAeVnkyW=BVcNbXuE+hb#G*$9bWd4YS1qhI56mdFu<6S1JSG/<
KyGXjB TemKqVMaYcbck:Dq:uTHutJnX!1&lkh=ZbP5PZQPMN*yCV8@i:/ahT:jbb%qq&tYA<6%W+/?qQMPppqw
$J/=*G dAHaZbjY4*\A9DbTt!!Z=%St:S=>@QH&Nkn&^Q/X%eP*@+>&Fiq*W^N!B^FtQKK@nIQa+u=LJ!9F!6!\
+ck1Aw GphEaXll%Z+\V4CC1:LEMYTni1W6nJMNpw5!qaa<PV$emKXp4Wc1&!Xm9ZVyEtYcHTXmbS/aimYYVCqi
E#AJyF m?P%mF\w$!Q!wM5k!1X5@S^S4RH1+dF^%?Y*W1llRMaZT1B4ij8ua%9NpbPZ:>+>S@E\&?TTV>I@mSLK
Z+**H4 CGT%HKCCiRe8IltJ$?:IZH1D?ktSYaiPZ>#?GKl8d:@\?MFLH@+6l$1$uN&\:SkE+TVd:58^HHWQPN?@
&h\yim a:?ERI*:&?FmHj%aYiZJc\b^STZ5RMG1i?q&W!RXbd1YeB/BIp5qP$QFG9kpAA?uLqGtq$C1Q&bKQdb&
>Nq^im :Jl%4EE6$nELNA6k!ZPbIDYQttqC%&\8G$!&9tXR%c1C$1*6%9C>FK+Cc@:Z^Ji*^t5uju:9#4t:h!<u
!w:C+w SZatWF$uV11lqhRLKu+JEi<>Z>:ap#G+M#S&pXHqcNNQV4<=hVA%BI&K<&yG^+NGZn:8>/#AQZ>$>HXh
FM/@Kw :i!5M!@M=B4P4/m8R$T>5GAyX^uAI^p&Fm%hS14T1YR1B\%<h4B*wl??Xi\PD\>jak8\Ey$!6XKXE4LY
!q=J1: MeLaiw6:aMtYQI&eTYXL$J1ELW8+QyP6cdm:M4&K:A4#S9\YN*h8aiy+djEEYjj8*AHBm4n1TJPhnNIN
nnL=9+ JFZHpYGaZ$ZtuSH#i96^F$I\ZZ>?aX85n:e9q8cuYJiCWi*P&TkCC4L=<P&:$n:BcDPkyaldQA4D*iy&
Tl^#$D &a/P@WmywuwHYwCT1:#DVhY\V<t9!RVXcmZVLSw1Ckh/JA=/%9A\WGXMcdW/66jac6^P:G&T8mcS&:RT
K*QJT9 DbbdLWL&LX:e5J^Kam?X4YER&VcQ$pjtpYuTLY:/jby5VhMX6!uCHW@mbky/*?J+1pmw*n9^u^V59ZMm
tZAadb EyMH<X/:nwb&^+qj4uJN4D&<MJKiLLidW>IGD&YPFlHY@jb=5c%D9ytc^^FRNu5<uGX^\cQI4lQl6tA+
k<CQAD b1uXZ+K:qM5S*/SFaC@Wdk6^%dd4BlT\=G?@#XawXIK%wb?MHtSbcy=IZXQlXI8n^XFT5WIVkqApMBMJ
@blWC> W1?Pd^K?t?Qn!\qT*Am&*ANV4D=FT!HTtJ\?TwN5&d<kbPh+*DZX8D*>I\uK#dE:h$:iI#GaQH>?:>/h
PVkpZq !?j8up8!KP!1GymtYeGWdSk=<1@eCi?w5wyJ>uG:*d+6DXMu>ch>bwBbFQ=+i/Q<EH1KhBL1+Tj65GQJ
^a&b<* l*@ulHa@WX9>wm6^4\u:JSu$Bt&?\cn!K@daZ6R/mWA58K4YlKet&L!+Mme=*GFa8<RJ!*AtKl$I^aG%
WWAK5M ^4YcIqCL&T\^\A&%YHXDHlS9dyptW@JlLDN1Am^ZLAYda/yqcIq5Vicp&PmC!Z>dB+4DNPGP*CE5:>!=
6dMSMh S:VKInFL5iiTy1DKMWJAl1enCTeBhKl/uZ9Td9<yyj1G@$@b>eY$ii:uTL9lamPk!FcXmRmljpF&Sl\a
H!qIZu mLVXMRj\lI<ebT1KPTXhS#tY6TwGXCVDTw\AKRu$yqe4+>\+y^EMuTJG%Rk8ypML<YTj?WV6VhweTuBI
wi:qkR wGYT#/Sw9iF&9#@9*?<##hu:GVCR85cQu>@@>*pd5B#M8AK5=+NZc$Y*dtZqH%/:yJX9*H!6IFKu>!Rw
GWnynq dTRChbG%FF^hhW<+LM!\6TqV^p%LT%cta@dZ<:a6lu8hVNcl*FC<S?V/V%V#Se\SQttQD\%X*\nEmc6\
CT9ReN maIlke1lL^eQaTFbH^G+GC\^ckJcuD\Sm:ANCt#>bJLS%#yy^^4tDa+Dw6qNADbd:AbDDJ?R5CNjyFWw
e>Rhpp =BN8Fy//*&h%nJ=IC/*InZeeu^NyZn#/1LY5p>dQ?1u>!4l?jLCjK@PMMj#/?=<Nb/kHp$mcZY**e6qm
K:/1N? AGB\Ta:W<eJ:a6i>cJY:&=L8!<QZ\cSqN@V:!?NlG*i9K%l#QXTXW?@*y=K#V>4dd%RHEFR8Aw5TMAXE
TbhWL> QSRWCY#=Lte*pN<IdCt=cbj\>8!TMTdcAt5S&L6kpy%y6NP:QhQIYm:8pa?6&WT8I4DIX9#IpmWiTXQc
?#Y$la AqS$qGNFhQh<t4I?h##MjC$>AK6+Y*9QW:pb$aLq8Puc%cc!GFydYju%9>Ci@CYL4:41Zwt^i48WSNaR
$T@!&& QyE:?5!N?XE:G4NM5W1PFX?VmaSu#5taaYNa/<waL\$S4JQGY*:Q4E^MA1yWkWBIj#p=Yay$hp:DPp&P
YlSiS^ FBd=X#DBaI1bnR!+DJTR6<lJwG+QB<H$K#>?kD%&kujle9mjMLVB+EHjAhKXaCXDDKR>T=SFT#^CHla9
%8HaL: ^$j\Et>VGqDla9qP&8eum%*Cwb9$=ajDtdaQEdk!:>Kl*nyQpRJq4#W@Xmb+biZ9Pq/5t?wwWZjt/BJm
qMyk>M m%ydX+YiC\9YCiWV8i9VW&<T6TahEJ9:#BuZRVQ#6il1M@bJhXQ4EK%eL6CnubLyaFNQY/1B19HVn::b
<55GD! n$!F>BSwLBaL^$K^WGl1&pGWIW9%G=BT*6y8Rn9nJ&!J8Q=&e4VVjwIYDjLh8<EkR86HY\$GPelGYNCX
MpXWdd QC^mi4cdpl$kdBin/bCZlij5yBaAbk/TDV@4+=lK86jTP^<MZ*#+l>c!AP@WTpP\j%#MVEDTYmk$4EkV
/!K4NL 9LL!#^$pkDk\+FKY5>8iidj1mmWEK<jZDdItiX#L%cM#pl^NYBWRI/=HTWN>^=*ycFkulAtGPDiR1/Pm
-A+\9> 000b799ccbb00110334 Page 150 of binaries2.zip
y@l>>p 4Z\=1FXKZ*eDN?I6q/hC11hT5R<M9!mEmyGbC#Npau5E6BRDI+SwemF*SahL/P:mL>ka\\W\#kTDAP%h
N#Id$t <LaaJFQ8E^#9L=IFSpkS&eJbRqZG^A8R5AAVjdwDb=TBW<4uml@5pSH?n%jYZ:#^:66q&5mBi/<Cu<p6
\aFn$R HPljk@5ZMKHq?9@K>\<!4LSRRcbK$$QI%WYNHW=GaC^w1\TA=LdHT6MTE6T<^<EK9l+q4ana!HVM\9?6
n+@Ak: whceaG5k%>LnE/?M<p6We8y=<%ElWepd^QCKCXqwQXBitG*i*=@&C&4//Wd+elD5CN+CwCL6IWIn8kV6
MFk:$W NWXdj:1LA!a&^EXm4WymMZd1E4$khSF+euA1JXLdNQZ9Bda@Y*@^+y@iqu8911y!F&y1CFeelRFa4?dK
pq:CeD 8p+SiClFBySkwMqZ9b*a*8KpT\tT5HwkXwwKJJKc4=Z55N8@T4:1>$VWuiuI>%unL+iI1<VYAM?JyFV#
tjulGS T>lmj:P*tKtjCpF4l@mpTyjy?P4T>LR@=YheBaN*PRkP#8DFS6p9k&NA%W?wk&i>i?*c\a@99!@<Klqk
:RCl^1 bm^<KuRn1l\VR?npe/!JC&ay=D^:aH5Y/E>Je\yE9%!IQF^@5j/@cpehJK%PnSkLy:HD=thN5lkM6?@c
j+Cw:L FpuZe6n&4%1?Nu?myE+F4ZXdl<dm1#h@>STjJX@^MSLJlJ*BY9:%*QYtHQ4YcnLC%i%y/u!q>%JtR6>=
$>FPlq 8LVpn6=MTP5S%ymq?M&mS9B1LM=iAhw=j4c&^F?@kJBmySuHehTQ!S+n5Bk!nj@?4jim5S?!DKc&\^RV
9aC4?T F>ETa$\MjB$SZaPTVGSWX^aHMmAE>Kj*>E@*H*+\*QHKZ:eT1kVhc4yGnp#kEFN\XXYK\WBjXVQBk1@\
4XE16H >/pGtdh16=c9JM>1m=:wi+tpy$9uhdDYa\qeq=KXMqnqZ*iY1*M+e<t\Rk4nX%XWnwly1&4uy+MG46EK
a4nmE4 bnk9Cc5pWtAl489D1ItbkJm1l+!!u::$CP95y:IE$haS9BZBMX#@?q+Mu?<uw\D5JkJdZ>TYPM6<=i4E
WEweB: TFiZH%5$p1*wRkqN+X8yu!jI/49hq5t<<T:FT!I5itaIeB*$B=6#19m$pq66QyIdYha#t1@GQ5WVbD4e
L!R&L\ W<<&a+*#C%^:PQT$SCXDLPQlRiNNaajt>I^&jw6=VY/I/4$Ac/CHPq@K\dKDi8h+aGqy!Y+>KE!n>dFw
!uYdCk VF6ma\j*$lH#qcbH+D?K?cbQQ<LkmQ!1<L!MIdlT4Dk^d\qb=#j!jb>@C\udu^YGGAld^B>A%ITE^VAK
#aVy!V aMY<^jK^jtGPT!JKVtQDb!@hqYyi*M=ec8Y<qNncNMP%4TAQ45%edhJ5DS^c55TC4/I5aW8!GFwbZnHC
9HQZd> bMYDL=JtY>*naT5ZJ1S@QaG9k4G@^eRtX+%pJXku@bV>?jRwQu^#8a&QI?BH$p<l^5ntMhGBFWW=Lw8\
:=!e6H 6B>$PHMpeMZDPl1j6J>GLNXFFAX*G%T<^i#%t&WXY$d#5ji##FNG65D*CynyAGP:PZV1<1hq^WEP%1lG
CF/N#1 D=6jB*Pl$ePBkeWQ&j+TKW<FHG+$<N:$<h1tKqq<YqqbubWm:5NTcDqbTXFPmSVP&eI/>tTTX!AnpW\t
K=&t1B K6WqZ5yZ$bNQiH5/bIdj8=+nYIt6<Znklq?@EnJ1<uX?9Tl^NSyWWjKydIRqZi$Nq5nZDL*JB!Y84Kt*
*tcDdc <dT>=#R+ZEBR^MS?TqTB6SkC#*\#5V!uNaeRYHC^:GGFITbdnDF^N^JY^5Sa^&ejc=nnqK^YaP41FAaH
dBQIpS n#=>q?4+QM6j/*jWWMb+j>?QkdISB*?YqCe/5B1PXpc*hRI%1ydmw$5G^cM>1?&\6T$pcub!#M1@+X?6
DmFF>L Hq@WVhnq/>Y=ZIBl9aHPhXI+JC:FpZ@%9hwtVmM\ie>5nbENnpt?^nB?$wLBGDnB/:GiYXS<#W8^^Qu=
X6!c%p *jd&$^lNPXT4aGn>GAl@$#5@N&jLE8h@+JlaRA8?6el%aqu@S&DVbHyFb>WdHGPFcV?SZLyCk&t!:jbM
h=tuk! cbiCFc+=9Q$>6%uyqt5YMn$bbac*n<!nDQIGZ/X&6%5IJT@*<Bna8qFNiAetwq//Kw68<6Xw<i9k@DjZ
PS<EFM l\BM\Xc5JNW=FC*=SR$SM@t>!%?JW!bpH8#t1wR%b1a/TTMk#m\PG4l14dYNnh*V%HF%MK*lP5Z$/^6c
#ykqu@ PNHR=u=4W=AWDZG&H^AqF$9>PkJYEFdE^T:KMq?hCD!ujhF$R//iG41kB^Jlnj%>1=t$ZnHP9yH!@RPD
:CNIS# qR<!YJM/a^:C8ujdt&IKcuhk%B5PG/:XNayl?FhheVJ/ED9A%kDV>WaAP#V^TXYmpcQ+95+Phh1Q4nPn
dy^yMA ^XWYYK#/tA/hNF<=IBc+Sq%HJ5*QdV^@ZYQ4#E\dwp=#yt^m@4*Niw1aGNlmkc\9Aw5NkG=lmW5$$CnL
yqGlj4 ?1tTmi?CH\Yapn#B^DYt1wCaClj6*4H9!4LCBJ@?NK5W@#NcTe*RYGd6:L\FdAY>dJhI1>c$Tbl<nXce
^MW:?4 eJL\&5KGIl/&:dD1Gc:q4\PwkWCPaa*nWCGZ?@%:auwVji5dT4QihK<C%H#MZpaG!\G^+P6SSd:!$Yad
LY*\aL G^P:9?1bB4:&VG#aL+*b%u^414kyGE6*CNk5Fy$EaTpwFw8e4J*$VBi\BLbcbhnk8CPu%6C:Z1nqdJd=
#/Q>B& Y4+/i?VS1^VH/ylt8MLBI&58iZ9Q>mK*j1p4^*DF^JZ4@mbjw%dQ<L*1cwR%eANSbXlQm\bt&meVue9@
:tyG9i J6?qS9JKXRmD1edKW$m5#:\Sme+SuS*q+m8yJG:M#/Neat@9j:ind1JZEFMNJQ!AScamF=5R$LMmJwb:
k=#?e% YY&J1i^Wpu=Yy4T?cciRTE=hbe@K$DW>q4QuSNaLVcjKPt669V&wNdWW4JtM>>!SE$/W5Ti!Qh8L*MC/
D&\m@J 6$u1$YHQ1GqT>*Ne@yYi#<+N!t5CNKTp/a4q64R5NP&qH5k#GXn^Vj\>$4HKNaL>HBp=GcebCL=!aRL?
=GRDP@ W#hjkc^+AdadCQCeT?4WnImn?W<EadQpaLNF54/dFBFnJ%aA/%PMVe9>A^AFS@AJmSa=IX8Xc:qkd4yK
F+?lZd N&D6TXd=e>?Ntcl1ZBjNk+I$1yYPu4IQcHQd+wSdpddCb41<c#a<+jK9T*blky>R:A:BGkhe1&@RLw!Y
FH^S9h 85q$!tjYlu&yh>cF59tTtp^uYI$Xyp5A1^&5LE^p5G5J:@JESd+m1uDDSel/kDXmy$?+JNGjJWNeRMb!
/1@CpG B$B$akHa#T+HatFHBE>MXmB9H:+eYQFFQqL*J8Bww+%Vy4WEK/@!H+=JV?6weZHS6ML4\@4I61mL4!<:
6@SY18 i5?:!$cLSl8\&mNPNqt%=MeJjMX4=^dAYk8\Mq6^Vmui+9j^mLXQ:tJ/wHyVT?cSDQX=C%K?h5I^teh1
ZlJmbQ ERPS\Ew::PI4i%jGFEmL*DYB6W:C\p<@MJ:FVWIYm^KW:CC5dIqHN45EVW8K6L/$E<LNqK6eSKKp6S^Q
H/+&eY T%TDyjGc99$Am$kRae5jdm>1ST%D@Y=a8hipt/<9PduAw=n6FT?6wD@kSqb%XBlZX##MCi\=!qbyWy?t
F?W$6R C8M6<Zk:b/+edGCtE@ucPE9QeC5YW*j\<%a5HFcM6RJm\yZ=KkwV=qt$G&!HJdl#qwi%CI6@ZY!WCF9M
bSc+8A >9NZGwTl&Fk$ADc:/49py1%W!R@i%yiPVBZk@%$KmHkJ+Y61TB84=6F**%PXk5u/>mYqlG/w*:&whPVI
<i1K/B !+Z8QRWKW:ZHQNZLFQn^:wB%YZGid*KNMlK\C@>bHa@n6lw%XRm*Hyul:Ipeb+#Q=4K!HAp4\AmR:wRB
Cw:F<: #/$6?BDYtF5:W8GYEl%<RXVeqDjj*9Q#CqPNdCY?!5t<M/LWJP\9F9&#?CMca?PaGBqdpn9!>44TNMT>
W/ZI8m *>wpeqc5G\+>/=ID+Vnp?GbVqYGkZ*6D!!=bdGW#dE+*9R^X?:lMW:<wYpuA%MXZi>PXJjql<DYSTJmF
QQnBNu ^F@hRLLY$5ccPFulFqX1+5>A%<66<8AR5>nE5VD#NB\Gwt=6IdJdCK*Z\XIC1@mc>@CXkZ$PF\N4i%kd
ATbd*b YZna$SCa*YIB!$=b+CpQ\tRym&Y4DJRq^94\E:nRQwV%GeXLtLKY1/yP=j\tY>Q^eqtMymG$@@/KXq*T
a4<+Mn ?p?C41I1+RtHZ*+8lduVI%FJ%<cRYQNpQJ=>tD\@9GR&?RT5YF!1^ZJ\HDjZ$QdG8l+^ATRedFjpYJ^>
a>uk!% /VLDieHY<Bdi68m&E>+m>mykhiWjC^Ne?Bh^p^$NI/1w@Q@e!%eSEX59T6<tb/:FEB6mnwuSEle=JtaZ
cE5Vt\ !*!NSEL\l+i+q<1V*XZ^B5i$\W/k#BEVqj4L@:W8=dTG>XayLXW=eGReac^Q8u*b/WB=V%Re4RB1bWV#
*M&R4p dmWCi^+^ccc?i+BudZ\%V1BCHM^$ySElGnHkw9?bka#6ZtW$nLkmV+Gt9ML$ER+4T!#QScWEqk4@Bq@%
@?:Geh !!DaC1k8\$$!h6:%5lmYPJwaScKi:cjCE++SE&HbFI91^PcthLESnJeT\RB^XVbcFXp^eK==%G1pN?ZY
w<JhJ5 9%!9JKiqJJi$<F*W1k/j#Ne%p:F=m*qicKWW%E?wl?m+!b^SFZ#hteT$buW%*5I:+Zk:ew?!\iSlkc:m
8leQkT /E6bdE1wJAe>/=c>mLe^\^L4kJkKVp9c9=4lMCILwC:*+uphZ5JcqWS?6+^t1TnMj4X\>y+Aqn5:Ye=&
M<key6 KB\8qhDFV>iTb!XDY>YWi&Rp6:BW/pM&GF!4/*\&R$dAEA\&#DCNS@#pCZ\XVuQ$wtw1Zb/$*Q5pq<#t
KH#@Wq Lc%yDY8<D9qK8Qy=\MAuW6hIRR!^5H6NYtEVGtFa=:dPmTZAlVDKmwm=w<P+X1lLEF@BCp@$V5Bcj6:4
j^T*9n mat>^dk#\8wY8Wl^>q+*8%k1QAuCd8It/Cp$Ya<y8TFGquQ^C+dCATbC1#\E\=>i?@CmJiCC&<6jGAhB
MN@Zlu $Zuwk$aY@&jaaW>WZJG^$aVh1E8ewAun+154H5/Q%IF#@XQLcp5e&hwC6+cY!d4VjnW9Rl/&L#uA=#hq
8Ldq:F :Gm+u1\\ktw965TW^WJ/G*Wq5P+G4KR4YiFqlFW!%pNa!<HCw=:lan<YFBHZn#<?t=YMqWH^b6h?mJ=\
&H4wD/ RMSLXT6NLV*W^MQhIeL>#kS$LcJe@6A/%4/CMp>t&>Bdm9==b6kwKFb!5hGE=:\&Ld4wXZC!+8GpyeCH
5kAKZu hJ8<$SJ9mK<&^MWYe>LpkV@dJ$d+5I:we=KDhGT+6>mW^/CJWL$Jc\K8t#ijT<1G\&aK!+EV1m1Ilw+*
>>5bby HkbaJ?Sc:8*>TW55H9W\Y^SnVRW1Th\VLnbLlM%tN&6KDmYGJMKEPe^R\\\ktjKu@GtHLqmQeuL9BmLj
6I1/n< hH9AQy@XY89YMWbt\*QNKKB=nu#!Fw54WDb1hZK$TPyJ:nYS6P!\65ILcIRdXl5kAw+#4yMNp&mGPZFq
Y@WwNm K?#9Y^wpM:!8eNXS$\:BmyAm#iB&e=tS^XAKjc\wPipK<dB8/JlqSA1WkK%*ePGDiX!5XZET%n%WR^WJ
RuR&J: GwdBZPhn?IcABbC#*j$%#jY#cIIn#$nm9S!I6&PBAw8LAG!KaZWc!1jEDBQc/hdDI*Ga4HXm<V1J8AC1
+@=4Ny u\>9d&<Q@D@wctMM@/S^Ld@n*5BncL%HDXBj+q>NP!#VHQnhAwc@AG6Dm/B4*TS8Z?%l5T1=QTtTpDPm
c?$&/@ GY>SAtG>PcF=Bk6Ab5a!ai8Nk+!QbGHCE#iSj$Y?*yqkaIt\G@N&dTK@68a/#4^R#BdPTqMMjGZCdlc!
6=%B9W b:9:?9y+HKEAISFR6jb9@kj\jLw4tEy:e>KSteh^=8wK:<8yLiD#SGC*6#@jZl@8YDhZ^*BH=8L&^aG&
-AYe<# 000a9914a2100110334 Page 151 of binaries2.zip
48/kyS w&Q9wJkCh6//qEHm%dnY&Lm&6kM4Z^@L%$9K\58WnTd1^aZj%55S5R1wc5I1jRtD4*/AFXB6YEXI/!bJ
d&6^<A qYh!51Xh#S>mn8MQ+XFItZX9>k1?E&Kte<<JVeSn+w=AFmuLnKYbW=ZBH5pE%8Nj=\uY=RutK#QYXb9A
9E+F\Q VMh#Tu&mL*8YMl#5/1CHBYD4/#iLjah>5@J+!NYX16be!+X41Q8ShqK:V\XVW@:y#pk6=#%eDq+yN@DP
y5S8#n Gh!kC5Bi9Ql=^?ehAG$HZ4A?::l+<YLdRN9^eZJ&Nn8dSSDkhaC<I4?#6kNM=L?q<pYjG8edaSG5eMQ*
%*pXuC QeALn^E6SQpYww5kJYV4Fd4=p@n1GmpQ9%pH*lXYC@Q%T:DC\NhJGlw85aQ%yTJ$^BWcyI!eEDCTX+mb
X$$Zcq JlRaEyGJbYa5FThEymM1Vwn4kC#<G&HV*Ick/=$:6&:h\whl\y=a?%eNnYCY1@=FM4+j*:9ZZS\9ZWt1
dEZN!/ 9W^>8hdc%WiwMVN?eHD?@AF\h9eyu4mBqa1yuClTMGFd4@JLlC1wA<h6&&&A+5YPD4l%jAWZkuy^8/$N
EBZ=KI aJ&hVSaTlYkBMMCZaTe@5kP\N5+%N5:#?q9?kqkc1M:Q*b>99N@a?EZnF#6j+M8#A!aQHwI88NZH+AFD
k!MGY& jJ<@EPSC4B:l^@p^mVI\&5ZZlB#t48>B&RDCFZYYJmERB8<KT?%Wwn=PH+wQaVmM&c619dIbS44ibDAA
<FptwR nn8*FLI*CXkhPitKp$^$ZQXle4BI%%9mphnDu8lkhaZ$C4beAhkCY8Lp9Z6Ztk>uB=jW%5Pb%ee#\jH^
%4YRW@ hB1*>nnnB>eP4kFVh#9*T9AApTa%:IKYPqhTS%MiH^?*HRPCdc?<Ani^<J8&6w>kFYaLX\wFjNpSphlI
6CMn+p DFDhAS:id=#j8L?^<d9inR*G>ZeK*Vt<R!W%ZI*uGlecF:=akC^^BF/tWDk$\nCG+C=?lAqe@Byt%Kp>
t:qQ=< X5<D9HDBi!1S%Z!XP*9R8$+CY^?n&6&ZLTTlJVccu$:yRZBjC1j&Bq*bc$L^FZAq56:TT%D&Pce:ED4q
+yXyNT Si%jBMR9PCC8EDj%>p:Il&IZ/!w=#SqVRuq>mt=jwb6KElAbh^<k1Eew%#BId<ELu@*F6jQn+>jkA5ML
Z^VJWy >6iyPVkI#yTt/E>+W?4QMtFZR@yan<Hpy<iA*<P^l\<j64X>$QdB\\<i<9yw:KP^M%ePD\>4?pJ>wTqa
@V%??^ AM#P%5+CpQB=+<b>TNF?$j56ZH@XC#iMETS*eh*9@Zu9#=<@id/H%<K=laYF<EIaH&R$QAWa\y*TXKqW
k<:!hJ tnJYcIySDweE4+uVTGP\GC:@TmWJwC9BCpRFE+#8>VHm/lidNp4$ba4WyK&\!aL%=wRJ/m%tLVKYLdHt
\1^yAu 1*K\PmB&<bZM5HwaGSL@FF@J8B@*hSeB&P=mwi>\>wkQ1B5k!adp$yWjD<:*u#<II4I+8yV&PW/E>*dY
TQDp9^ l\K!^p?ihjXbTG?itW*Pj94StdG^B&Nna%@4Bh?NQZl\iL8=GaK!Wq?pFBphZiB%4lFaiB@L&:@+h8L%
lm68:& %@H&dT@l?!*<GW#dDj\B@Gy*A1:PX*hj*aP%MLyR&l5FLPqn6BTlBh@BFTqhLktWR\A:RV>CNkJJHWwW
A?WC1I E4P&Haa*i@n$q!$Nn&EBwC%jj5qB$#QE%XSn\At9\TM1?wN:XeWtHR**MlT@Fyht4ABYIc51mVIk^knT
+CdK<= =m8b+Z?<SS@+GCebalNZ<IYHTNk@Hq+==nEpqt\kTTS+64QBc?j@iQ=kjL!@@!CannmlA4<Aw\FXN5Sd
8!C@/a $*VB&8=YtEXK*4=$?=K%Hq!/hQ9&:idj@:kj&ce%*Zt=e^TIh<:*jP@@KQ9/wLdPe<@y>A@dHaI\Y#M:
*%6t!Z JXSaFM<Iq^J4/BA=Y&1<c5Cqq+5!EbwIFhe\tBXke#*m$lDd!HPJQ<dS*d6nP&MhSHi:C&p:jCV5FJQd
cDZi:P ta#nww%8L$&KL<KPpT$k1Rd9+DmBVDZXu@5<#@6^*mQJ#6**TEe!EkL#P:@u?*&iQb><<641\aMHH#=<
%kH#\5 ?C#eD4J%b=DV>5cNb%=C!B?&u&>94#<jd/>9Z++9%+uq1CNA/>cYA<6%iK9DB*kCZ\h5EZ/md!*Rh+mP
XRk@hE 114w9*K?K96/m5CnAdyc:mJVtTXM5NaWeaPJ6nM:PnLW1@S@RhdZ99<?w&5Iql%QHFwEBa%mHmdYFT!L
&t%^5V JPb!aG@wjA&ylL&aY\:4jD&&ejRjAaJ@HB9n9Vmw!R1Ci+#>9leGK9c>@PW*Hp&X6%VJ8wRAG<P\KcL<
Ipp&:R DpMN&aXwNQ4uq6j@F6cqu@@<>b<@>*P&u99=/@DFJ4FmlZA5B:=Vl:#:#8wk$QDk?ahLjD%eiudy^\<j
hwqn4y u4?D#CYl@NKS\V95=Za*HLBM:e9%!<8t=Skekd1/=WBVae#$&ApjC$>m5eitGD\F$Nj1HAqGacD$$QWl
Wy<JIW =QbRT$6XNK44X!=Gkc=u:1=d%6i^n&EJ>VE<a+J:9eLZQRGM\Y$e9bYyZutKD5R\IkF+JpNBPP\lP/Em
?N\95C GI6i4PLCWky&%tA+Gh^ZIadF6jE4yy=!CGIF%\$EpXY4HPZVe6k@Nw+!LR691uw$Q#WW%Zj/a*$Vb!4b
@SX?ZI \hc1nHd!$R5FLRj?=S8ZMleC*ZVy<V54n>jZ%=%Pm>M=a#Il/?LjcS?ML^>5S>nc?F4CA\FtuAY%??#B
/mMAiK l@JqN%9P>luVnKuRbIJ4BC+Wp*QGknheM^c*Bb:Gbyym!+A5*yDXIJ=QJb=HYT%^qcl&kNWEhL$L\AKW
!BcAcj JRV1VcB4DcqZ%w&hKwa:e1yZFl5G8u/ChLYHktIB61ERJ?\kEJaThw$j1CHmL*IbVp\P@&1RZTVEi9kI
jLWLZl +16SDti4X#Ejb?!YtL%Nc+\%p#!Y6R<Sj9?w1=Jm^cSdAYBLNCP^@a6w6PZA8cbL/!6*X%aiZ%1Ba&EF
!!CE@^ #=jiAW#9*q&A&+yqISK^Sh^PN@C6jdth%qI:A/&pVXqL#=+udZ5HbDCmY8IymbT+8>6eDFpVHG:unBPk
nBlpVC hbytuBd/XIA$+y/KSF#\A=#P\lkJltYR$ZZLAC%ADD4AeRCAXZAqc>kEV5*h>d6uCNmduK&tM#h4i9T8
aHa4VL ku8KlpnRGhS4l?/>%yLXFNJl^YXZkEWX1$6m*ZA/q58BjipqIabDITGIDeF@taJXkeZJL&QW:yXcDh/T
qCFjJG I?Bp*$HY9pHBqlqMak9/btY5I:PC:EK$18XAW>Q/!1MFPFbYFqaYeK&54L!#5uJ*aYy1KwI*%=R4+kJk
G@FkQ= Rb\!WDpb8#%\hLh%6=X$q*RV5p#d@ylkbc>/ZB/Q^%4m6uHcI4JIWa56+wKQnlCtLm5<&ld\BbLIJ8R$
ipLd+C KN&%=TbVW&#N+Yn=%\!?NmJh1bG*RBW$/#y&Z%LdjRa/P4QW1&+%aW\CCed\HJGe6R6kj$YTPE9B#uIF
WTkmNB 1$d?tZ:qRn$W<k\L\q/<pX%E4Iyltt<y&+Q1#WJ9uid6Z+?NK*9>+R>R#4dhdA4XcuWwW<Ma56GP1n?*
V?QB5Z uANaEd!FKeB&><Knu#$mmB<6VNGj*YX*Yi%YP\L4N4Wn=h#8Nni!pXD4J9VaAdmCLQ+^GqTAK:&a:@F$
tlE8dH Y#&8@InH=uaBL&$SG!EdeWjk\\FP^BR@H$=V:kkC/\Sb@hkE=!dW/4FCIQGcw/XK#FulhqM>+Am+*q$u
&tp?GQ AZ\VG\PjMXukXM>/+V#kwYFT4\d9XjX!mK+EbyKjEX%FFI9wSKpAqt4ZYMpEPV1GhA:n1!epQwAqhh=<
jEDku= mmAi:/S&#dhwSyql16>y9X?#Ct!W%Vj^aVlY!%1mTl?4K6Nq$c1CqnZENdL:b:6*S*dDI#\BnB@>/DKA
YQkF*G dh?NB@?#k>B$k^Y$^FB6??&L9\dp<kubjMCQYpem5LmYZ4\NL?Vu\=i6?ZD#YF&imG9+<w6M>Dy6j:n<
=J6*NM B:^iZHaG/9^<$k1WSV%LCye+ndVF^@Xa$:>W@FuHqiLGDFcm/=p#8%mj6DMtdI>GG?ewwZP@1EyyDGHa
\aJCE1 bmThX?AZk=Rn!^p4dCep4CKHyTDPMy!\Y8Kq\S?jd&N<SX!Z8CDYNY\PMR#1XiuBdYnHVZM8yCltnZVi
D:D1P8 5*C!wt:hci99V$k\qiF9$hLw1&bNM!>iu6w>bb>/X<Q%:8/jVc*$\bNSANZ/dnl66@w%Le?DY4JbR:ci
Made?y cT6=A%+Qc>8IcV/<^WMRikla5I@@F:\Y#pP5S:Y\V\9uY#$i%@DXb9n!JZjE+q=JldXt:Wh+8WT$b86<
hAkW/e Yp9Q\+>KtTPA/<\X4e@JlQZ6XB>I:Ju%y4WDLZJ?D9$Q?6GywYWm9tIVR^!1YHPtQpMMC&9+lMEc^nyE
=NN<6! Jwa#6C9CP^JWXc\mmb?maFu/qiuZ$F<I&N<\k#kZZ@YeLy<Ay/=b9ZQ?cha=Z?4aFn+:pMuk8>n56mFn
AR/PVD InIh$cw@c8a?LcZqAXpZ@1ByjZ%>Q:L8unJ4jcNc<&&:hjhq#Y!NyLT4h15LXKRYBql6dY%hkB6eEPE<
RmDyNX kM:#a6kM5Jd%=yMwBtS@w+ZV/ZD+L@tI1&a&y?$ALH^I5#tqZWHG\4iiNY8ymBZ+1tqY8J=C%uq+MN6A
4Cjl+a :#19cPabE6ctK%wcViabFMSm:mDnc+$N?QwP$dYGWEYtk6qWe:Ni:Mi=#<R\BlHJdBwdM<cG:?qmiCTa
VXpYtb 8WLC&&FP4KJlnRyYTWTL8AV*lajdlmXjDbp/9X!iwlI$*@LE:P#5F\#QYb4e!/bhCMcKSuZq<=!6%LKj
&JlGLQ %Ve=yNHWwMMddZ\%bY=c:>JTC/BKL&9y1h*&KaD+*c6VW&>w/h%&P?Kc%4TIFc^Z+G5a&h4&8ccql$8G
ThnTbJ F<Qc4+GpkK8H:^L*MK@u:GJJ>&K+C*ENn?du&\F</&K#>4p4e9uFKdjNwnY98CKy=56&c<Rc%pJ\YRFh
JnPqIi <WhbpKh9yM^PqMe#V5dZqbmB4%IM:\i!48>up+wIXSQK+ZlQn^klFP@9#QB!bC=HlIa=ZbNb\HwEa*XJ
^Cn/TA 4Id?n$yBdA\+EX@6R5GKZN&dV?a46RYa=XPaKWYcNWpK4TiR^Se1:qd#CBN8+Jk9KtC+qnbpDNH6\GRb
EL9E+D +L4&iH%S/=1cY4m5>cGqbGhG<KStnp^b4&myTT*<8h*qRaM&4J%B>hwXVwHhXNJ6Dp?CJH=Z<NYD?!l&
!<VS>q AdR*+eX$?G^?GiB/FkG*Y$5$:jMT6JKA4&?ENjB6F4XSF%\8RN*tNP4a!GZpKcKytb*$^ATZF54n^:G%
5G#Z/b lM=Z@P&HWP!?5\:I5lFWSNh%4q==EiL>unw?c9CE+4&1XlM/4/GpRRVLe$nGuV:=L?@Z*yQqy4wk:5n&
e8Rbt^ aH<%PMmDX$KRM\@&a4b?:SB!?GnPEYF#ekKu$LEZLNTNqQ1?\INLVQuwh&VXwAC\yc>1=4Za+!6ApSZL
MTe9MM G=4=ne69pHNn?ePmF8+CmK?AIt*8Rt5aeG%H@R1+tu%h=L\C98DqZAu:\8H$4%HFhue#V:d:h51u9Rlj
!FZJFE Pi948*LqZZnqmp>#8h\qES6<$B9NKh6W=G##Inw/wGm%5\6wNeEq=H^5Kw#hlpj\h>dlYewet\GniG&6
lpbMNy SiJKF!WwXSQ!>S$VlmJ&aj6u:D&KVYX=e$9pK@h!8Qic/iZWM15y?ISqF#:w+LhXm=l=Pmh8diST5DeG
dlJWZl bXTT+a1F^Bh9=PT4:4$KYLeMD*Q14Mcn^*/@Y*SwwwmE9muueHqC5b6ETXHX1%4K5haEFFqbZ*?D:CdL
%9&q?S ktZKAqI#dAblChK+Pb^m1II^4QtY$CJPlY?VA*9Fb\duFcEHm\k6J$C=8/T6i#m5?eKLIJj#RXV:6JVH
1bGj>C labYG&lY?KBI=Dd<pIl6Md\Iu5=WGLT:qkKAdY?E#im:^u/kyVB\cX1PkRL+Za#=4%WGZNEIBqln/#m1
-Ai9HW 0005111448900110334 Page 152 of binaries2.zip
@+QakG 8GaZt5Iplt6&%a8lB15>QRul=e^tBy5cM/&tpEEWJ^WXT=JamVq^Rb!X$mGDtAR^^mXCcwV+akc8DW46
Ldyn/d K14ZYRttjFSu=y:?@l>jZ/ti+QNd+d!#eu?@HQaB=!4niQ1Gn6KG/K9@!b^\4L&k>eYcH6>8Vm%iQR9E
6@^Q>c ZaC@jPwNhF>66=G96>*k+=^yN:Z:6Qcq>9cqqP<5lSHQl5*I#dDYQc!FZ<#9=qGK:u<L?<!jp<IFZBi9
#6\\Iu huqKI5NIhb8d@J!8bk&M+4:t1!mW\<&S^!DwLbab?FG^=dZAGtn:=RA?A+BBt6Rl4C%SFhj4GIQAeZG^
ED%/G1 hhC48:AXQ#d$Jnq<Z+#b9X<@%MH<mF^i#n&8ZnQMJRXiGX\a@IR$4BVEa:p>ua6/bAIPEbm+RWXP&Z#q
n#CM$# &XeT\:K\VK<^t>Y4B:@**PQ1Va+1&*$#j$+PLW8W+<AYbb1=&MV&jT*Xp9myy4*R6Hd8R!*X6L/?+uSc
uLqpEG 4wdBlIqaIlbLZ4MGqQ&hE?P::i%lZ*6:?<Q&D:Z\+NK#T?jD+Y<Cc&@:6LaT#aeiK=>Ww9t/85tu>X#%
>V/HD: Zi*&qABjdX4#wk&AjR^*8BA5Np6c/*QDV@DBe$&:DX4$B=wY\Knll<$yPK@XQb@T*pyyL#!jPNZC++mm
uVnb%# KHJQDhJ%Q?M4kHtV\XyjR?d\@TLY:L&86LNV#/p#ZDt5ya&%6h<GbSm!=:ccPLCe5WBaT6aJn%QtaLMW
NB>=tu LCN5t#EFc?C4eeRq@HcpJd+k<*j&BJ@pS:Z=*JV/+e<&^cKTq=&d%u/X4j*>Ba+la=<PjQ\uLjZ1S!pR
^H+E>e ^w+%aK*&+R?/LkG!b=8%^=jMNp9EDcC=\jE5BLLYj@ll5@dlN>5jun<I\9Z1N<?G\^yc9?D$*E::\5PM
CDeCa> 4:lRK4>+FiZ\XZn6hq/J^?*y<wXVZX%cq<*mB4+Cwu*NjRC4Dc/B9td6$5^/+aicB6V</R9\+#:<ReLl
?mHh*+ iE9VEuA@NhTCtVyqDuiyE?R8DkKM:WiK+pkdW1<$T\^kbbT>Z+iy!GQCHFc>%\?pNb#L^<pEFmR^EybZ
:%jXt= Va^uCYIqyjQTT&ytuYX$L6:ITPmwaRu&&/FdI/iY/*+5+9yYpn85DNZNucKVBNyM6PF=1L><!LkyB8@j
WGI1GB S?ZadQ+QmRMJ^\6k\5DjhN&=:pTFGi+CXkFwVmhw!=q&$*q+<QuC<eGDB@<PVcY\4@p*T$8:&9/dD%d+
5>4D8@ K5Yh88u<Pd#5C+Mq%b*&NePLNMDpdDN<5duLDZI+HAd>tk1uWCCEt?EmiY9GGa8>ENaeD5i4#jkLySKJ
T5eGJ/ Z&1yn+cG\KXttZZCqX&T6eDS@j9*^&Cbckla=G15*kVQ>LG>bDd^p4Xbdncy1S!D%VVC+lFJw!!tFIAp
^?j1#u dIbFQJ=XHQ:tDRP\D+Yjw$V?*%bHZEwu#Lk=Tt^>k^i/:Mq1RXdEh?jP/9ZDB4aYFK\NbjdX\b1\9/a?
+KLNt8 ?1n9n%YuYlJDB*:@Wiwne>>#liBcZAJnyt9KQSZ=9?c**P=C<$e@cG?9V/XTjcpW%Wke@B8+A1=T5t:y
5K1$M$ j=n@\Z#%6>$wieY/wwXVu&PZ\1=$!6^uy4!P:b@N<C&QRSljNq?%\SXn:ywCmYBP>X*>uSPM*>l#jS<F
1&N+ja HIuj@\Q<F1t*l14?tP1411*/y+<?c5RTy\=FDq<Hh1/Djw*6b/+Nt+bTL@nKb:p^5\tVPdQeHFcDmFmG
$K@AcB PD#MlZD!!a#qpynHuLlFLENPHbp=&Jj$YynjuM@P4B96J9udjTFu9cql+lPu@&AR\WDbihi=\?Ve+J*a
8GnRyj /pk$!H$^^1L5lmnYpR&%DCXPkVAPFMdYKh$T5cG%c4NFdDc*$<%VPXVbM5n1I^:8jakbhW4IkR*5WYDN
N==B=p y>cV9j^yN:d!cHNlTweP?GRdJaukl5<6qlYKAm<H%nDb/lk/SiW\R%nXXq4XGG&Mqua\99Jj8AmMZ?R4
#/V>$E V6tq8ZE%PFwBb^ah=*^F\!p?^Qm1t<M/4LZ9=:KcFHlH?D@5ZBJ@8%dmKm#mw=&=ZFlic*y?mWwTicLP
<F$a4* mG9DB@4Ah>aK&LD=YK:@1G9YuZVcKZw$$d=Itw@YI5eCG*bMhQBCZkS&KAGGeX%VDGQ6<Qi&VdpwmkAG
kJuuKn 4M%>^8pG5/t?QZ+?j9BkuDEY\@8I/1+&yqR=u4C<&LDd!%y&>#JpQc:8TIuL:eLLBF^aF*+&*6CDhW@b
TCthL5 ANdH5Tc\tkBapB!uYwb+yTK4Mi+RjGY@il$AGTNka/BWeTJ&QjKXS1HW5%pd\Nj/K8dtnBuNaiG<Iq*6
+4#Y>c *AlYIE%tKF\:p<Tal&W8:FNm@:^wR1pNj!p4*5VpMG>Zne+%*$c9L6aJ+p>CBP@ebJy%+m:9#!TZw$wb
=H8ACN +&*wN6tBj:bwKRLdA4kTZ=%P6\ZJmu>&/wSpR?j%DKXi+?$H#!Nbu#&IqW$A//+&hG\a4L%q*nJeZt?b
+SW4Qm q:Xm>@a!aK*a?eEDS^6hLFaZlac6tM\BcG$SbP^M4KpJGR8EbiYJXXTPYI1ZZkjDqX&MJ$H+^9cj&%<Q
byNC5: jPWDAHE1CkKLjF$q!\u+YmWawjLX+L\?RjwC!HcbpTWX!\n:khC\FJyRa5Tb%ccILG$e+CZEGZ#Xc+j=
9\dRT4 91EVw4uH&Gp^<&*58iy1lc!A4i/$DmVw*P@IGNCi5S<GT:/S4/iA4=FkK@^j&B*Pbc&WIWZG86%LCC!\
DQ&/:X >CDhmK&WQm<lXAHQaLB+&8@j>98um$hGY55t9G^/ApQYR<m/ZMZ$\ZVC%Y1%w$C&YMBaK+\%LTNqE!&u
y<5lb1 tBStlI%t<QW/&4=5dDIy%X*EX=!XAdm!&VkI4wM:Ey!9iqTCeH*6KdkcyVI^qlG&$YkSQ+G\?1//4M&T
&V4*=! Kq?XCl&i8bF4a&#nW4Wmk^FbeqwbZXtL+Z/H*m@J1F+yMkE*=AWwNKB4ucX+Ma*LuDdDT98VX8Ac<5#Y
*qLw#@ B6C&aXVm@EP&$BS8c@5c5lXSDW%9\*iq/b:8T&@:y+QAYnce1BjdF5Iu8V^YV>+m4FE<eBWH1cFYBCmL
WAEhIR KnaYI%HMXi^JXn*eRCZ@8u/>DpJ*j\CP?pBMDtPqRWdHc++Z!VGS=RwnPK//i1XCmiDVVCd=+q>IE4@&
NNt#DI :X1b%MqP%ltn@^^a9k6Y4VSX?hyJdk:dqw8wape$PtD>hWEqK=/6=RYK!%4iQ%Vi$tq5e>dRacR4X:Bp
uMBX8F Nm$9VI<!SPqtuk\CG6b<F\aYT6\**d\?nhWlI1yMBJeFm^FW>q$MYXk:@MWnZl!?C4^N>lK\<GHtNEPX
\clXtq Ii69^W!PhVjw&SWLmPJanCubBAFd!@b:aCBdpeMQANjAjlDEkC\R>VnCT8Pyct4&%5S^Xt>Q@H:<jpLG
>IJj?h %du:119ZnFlVMn95d#CK:a!\6c4qyCj4qKTP&Ld?pqk*e9CX:<%l#9Zy$:\=C\h$k^:?jq/Hqim/e^=l
:YWQ4q LYh#a^N\Pn!RMDV<#Yn/!<=khhbYphpWmE\9tnqb#aS4d/?uF+AFcDH9&ucGF^?&peFENW#h*yHmddNe
eS5&Na Aq%c@tLpLBjH?EHYjMBXMuaSeaXqSYF5t%wS=yQDeWAAT*bVXaiR\%kjGkB>mkQPEXh%dl#yX?G?>9R<
nCG8IV MQBXSIjJi^ZP/$lPY%nGFMWL1GLBl/&>q&p=QaG\EqqtDN@I!Pjw/uXeyQ#H^nd$Nj+/X/$:8S&<PXG=
a8ADL% #wS\j&KAh/N%ZPn5XAndpNqH6BVeHNT91F:4/kILQ%yM/^mbJ+6:=!9ui=Fw*S:eaWyJPI+y5+Q#!+4>
Q/6TZ% EqJ=V*Qm=9tDbSMTYcD6jMyM1HLCdke4GdBYK*k>cD/BJ^6aC\nGp18Dknm1<^X>GpL%uBnHT1AG/8M%
l15*E\ ^?P4etJ/wpM9d1JcSPut*G9E5tHM$D%JCwi!en8T5A%/WmhHjjmdQFAM!N=kMRunXpuGX>Gc:=n5WwP+
c18F6^ n4Q%p*hW>&au^mP1Zhl:Xl@Lumkwn*dKX5/bDdEp8qYk!abR9T+VZ=W%GtSC6JhMYwRYZFXiY%yChuB?
X:=qAE 5DnQuLuTby&$P+4LcG!>6=hNRNEaZ#qu6+QXqh:iJK69AkMK6i^/aSMC/$Bk8i$EyyQPX@B6apDZe!mG
Cl?6EQ 8ZQDylClHJcVtP<utCiS^Xhi5CbTPcH5TGI!C%<m4G+=pR8d8#:<Vd**yim/b4CHbdmyW/RRYH5EAi8F
KF^GQT S=81CN:e4K!i4:d8b+&F!/pbPN=c^k$F^XpGeRe=mGAPZ^</=ckL^CJ?I/+laju$/yP18=pJVK8*dN1e
ichu=! i$qht#jh!wbl5@GPDFilawG9qhZXPEZDt4V8nwBhDN=#LFbIIayVCRTYNG!Dkc@%5ZQuCFu!diI%NAYD
eXbB/m <VX?H:t/8uw@Zt4k1!E5kd6!XG5+?SS^LPJPBk&d8RHLAP^FyW>mXweJk>q$VG!*HlNp@jN8FhX1ABYF
yTRl5B tT8k$BYeuMMHLw!Qb@dWN$lm&qGM$t:wikJ\LVV\NYWiLc/plbTqRSembeNqeH=\t6/u+Rq98aChuB/b
@D*l<h wE@^Att>tuqSZ/M:ANhKwC#@@c&SKhK!5hm!Lwwd1*A#6MD%A<RX=DAAC/KZ1%e?NP=+#X+T\ukE&E/y
%ecH^8 *H\FPe#MaRupmBHTpa#+IylPk+Mb&Vy5DVPiyYFqI?KLN^nCd%:MCmMK>ewuRjAY=4C?uJe!GIkKj^T\
JlMYRF KB>by8/ia@:NRH<LQla+juJMtVDXtTtH/S^6\A&J6cli%\It^qeEmw:S+kpP4QBDGY6FkAubmt<$$#$V
EmMZA^ Ycqty+PM5WlcmT9ThZFHeLN!E=GhS&V6TFpdcqq\iIC!mRTV^I*SlqLJ%%1VmYAN\I%N=?Sn@8y4+9Hn
neGcSe VLjC9X:%@I*/6dd&@eHB4ELEaP:eVqJIawY\uX>BYAF5b4NcI%@HP!pY^4jS+*yHP1&XqaRyP9cY8=d>
Tj!HMb VAAQmNKZA*@qE!\!SLGlw*MX&5MWSR\5A/=ylIn^V#PjLcat+^JcH9MXMeP!+ppG1&dtX\J<Y$wlLIM&
6WT:^8 QXu5=S>TYhq5Zp#4Cna9!Q+ZRGb8Q&HqlAY6y?XAHYM5I19L+R<A9@4A8T<SYeT%Ju/elDAkY:MZ=DDK
^uihNc aET&9pGW=?c$l+&XVRw#S*ILbJDEaBLjW#Z5mXubi!&V5BebYZP&TNVF<QnGLa1Fuib$bVK+8y1IcpX4
Pd4@F8 +!:YTAjYm*mwH:DFQdAD4^<>it^<*DBn1nQLHpbkc/88w#peY:anZ^EqnZBcLPb6y*XpiXAjV>=RHpe%
F/:Y8h ^T+E?DajJi&$DHt<w%nm/nPuFWGeX<!8V>ApyE5a51lqa#l96\+aY*8TJLHpK!yXGwMhPMet&Mh4^LR\
SRAel$ \DnP#iEnSVu+&5tV4+%a&lV/Cy&1kn/mE>ca4d8Xk:Cm&V>D?M*e8BymaRV46/w=y6Y:5ip8<BT4w&Nw
lu>Qhi Ty!4aMy%kKhhj!<&^*dKETjbQb*SdKyFe^l\bZ^NeepKIqQkKpqLWRaM:<N6bJ9iyRtyDcnPdhH!lXNG
5m^RZA *<e@M1Hktp:4jPZXHTTM9jQJiR\bY#D/FI5FWMhiJ#i&wW4lK<j%ZBGV\*5bZ\HYI<j*^qj=KtKShRNj
NhntLd yh&EjQ&KMGKG#p%!ZP<%1pFmhbyPSk5/&Y#nmZ!XMSNT4!&I/Y=en*dddDaLkAy@Ab4qZq=i#5mK/Cd/
EnjEa8 C\=<H!9bXBX4tGSLyRiay5P\Q@J%tiQKMCL>Gy#Rkb$kd/Y!q?X19L$V$/MCW@dkA$T*9h:K/hVY%y^t
kH:Weh WLLAT^%ZRFX\h4J+RkG&8yIFKcct*Bdua:CKkdAkmbG^Cq<J%!?J5WX<?nWd/Xm$N*=e+q4ZpSqH%G8H
WS/T>X MT:^MQV9+1w8mIiHYVDS1GFXH@d64IbYYc*KDG:PlyAqiNH6uy>HVB<>?m=8@nTbVQ5S$1J#dBkQaX1B
-APa1? 000dc003c5400110334 Page 153 of binaries2.zip
XDtaqM e^u/!\<@@**YL&%euR8ZMiPpA<M=^Ne/$K>P\FWAldjS/Xd9Vm>dE%/Cqy5@AG>\B:5ANQ+hRNaR9tZC
ppiD<E Y?u%djp$k^ZqL/8epLkC5l#a!iuYVT@?CDl:\RV$/1LaGVM%%aGKHdw?lHpJ!XiGK</WI1$K8Md4?V#H
p9hRbw iAbj%dK%LQ>%PIh=%My!Hpq^M\JLJch/\ip+ThG^a$<GNqjLTFY>WtW#W/?9ME!@?>qu*>&@H!#D&Du&
WbNFbZ j!SMSRCS##^/@u8ucZ6Hb:d6yHV1LyZ/NYA1=H\XN@Qwn8$hqKKlJE&bWLS+t9CQcyK9iN@!AWCe*N/8
B!/juH Le&5tqB=VMNYi?jMlKwp4J<?i^y8^jBHSiM?mVaD:6RB&&pNCH6>1Lc&6FHF6Rn+TuQk/5pI45GJnwGm
F4<mW@ wnkI+mMC%:k^yKQp%XqJPI<nl4/C6DJ5peVa^Ci!+qRu:NFedY8jBK^B9e1tnjC49RPaj9i#4*@&>c>@
*!ReMh jj@?e@Xmcldqdkda!DtS#nu<?9h+k<Q^<i#SeMIpnqK>BPuZ\QIb=K6ANY96<KMuC9mkSK+5p*Sq*?D#
+5jYSF ihuRLDa#aNF5MI@V$%\Rd:HR5RK6u6*^V\P$9in9aAIiXC^w&LyVLDklea$lZ<8@^AteCC#+N9XmAP9i
iqy1DH 9Z8FQa!+Mp:e!8A4C$\Mul@?h\9lyB=#W8wtiFMCk/@#qe%AWR:#EqP^L=jW/*>?=:QQQ99/N&B>?TWN
GIK?6C 6#6Z#u6c$5DQjkE6Dek=<MQVwuPqan9ylEZ>&pHS+bPKj5$J1Xnd^a!#AG@^yITWu9n<DFEkNm#@JQh@
P!=e/E BG9>IMa^d?jVKJEudTe>6$N484nXm/IaBdEVY$/A=ZRhLTiBc&Mh<4XC#t%EPT^t/<aBYE:Z?#Y=?Nwy
c88N\X ?M4#PeqMy=WL+q^S^XBGpLlVV9whj<Jk5^#AG6Y4dk=j?P\dkPy@y%XBE+FB?BKmlG\B?c?m5Pt=@<%D
cA^>9T !8Q1j8iM/VZSBqaGp*AI@c4yJM^iGD^mS6T&@p+tmdpIVt6T//b+$AIZSba19hW?4T?L5AyqS@$ILPbp
QdR=Hu y>^PE+chH1AkdyS^mR<KTR=Z$MSe+m9bVRl6QiAcQ:IKwllPSR$bN1iW\/Ye4<1G=lF/$y4q?TTNCyaZ
:YuFHt 5JZK#dBn8mRYnH*:/dB?wKyZ=XjnwP:d>@LLA^X5FlJu/iGBAqkDeylXj<6QV<lY5?PhSnhYcj>dGt%5
SdYjRR SLw?aQ4%cY#F6ikQpuFWPb4^#t*iI51HpIyIlSqhY^LGp^mTuAe=4QH$4EVYTNnS!iIkT8KIDd^aW&Ab
K<KqD/ VPL4&LBL<lYMaCB4SVpdwq5Q*p&<94!wuQQ%PKEKN/Fj^%l4SAXZ1l:?=Q^ZPLAnl8^Pp5eTRSC4chkN
@*=CyS bny6nP8Vp6=?8llY%P9GLS*ZKMC/D%DFXp$9A*da1uTAmAwHwI4AwyQD=QBddKQh$YP/mqZeYERYI/?N
9FR?*^ WX+65Y\!1Z#NZD:&MPw9I%/PGq<%V#P>m4kK\+8hGMCV$?kt#XinHP/V\GaShlKLKFwy*BIBRh\W1HNk
i!EGl+ S:A1cVe%FkKY=cmE?HDpI#X^ikSp+$j&:8X<BX\:BX>Q<F*NitL>@Y!D?MtFMBuBj:YTiF\hCj6$^4=>
j^Bp#e $WlZ*G>>tt1d$M8=<PW?ZB>@DLhQWj48\hJk+P4lA5dZwREbtll\9CB/R&<aY$<welk*T\4@NXBw!5qZ
8K8aX* H>=<tnlQVmN<ba5bQC:n$>q>aW%Fqk6m#R^<ujj&i4iA8\LbuI!hHQWHAXk:llNNJqC\D$/BRZ^T=8u?
4$Tm8N DtX8SRWdZa+KNu+EnWh+&wPG$^EtlqjnXh#wbDFabZ8P/C\SCkZ@@^dm?ptGltYnX+\#uHMm?@ddti1X
ika+?E >cdu?/%dGKajZ@9++%e?HVkMk9k\ElXY@?GCX\4iK^AyPtV6u::k??^Wt=kc4Rt/hqAapeYd%8ymyyCC
ja$W6P K+jV^/t1R:5DXY#THMbNAZKNiqp4C<=ZcXJJdKhB8aK6C*#qthuFQkNqhXE<PS&eB::c*M^!TtB#Sh$i
uZ?%8N QwX<^euqDFhW5QGm<y/mj5=ZAQZIIeD%PmQ5$hP!Lu#eWAk#uEMRm/K>bDb4S<nVIeLi$\8h8Ptp1Nne
eTei?@ ddj%<TTGKW8#wn@CiME?lQRcun=?=bYB@n%:GK#I&CEA68A>4t=SEQ>JnNVaRChYB:bDH*$R^ekE&W$G
@HnAAX 99wa1y1EXkX=FAldPcJJ^FXekc<?QXTlAK6Na+b?*45qeP%VdTjGX!GJ@WE9dwkFZAQMeK16qjwX?Rwm
B<a:CW GIHqT9XIHJlcn6Am4kA5I46/<JihPq>QGAJPDXR@uFtQtH!cptW9!nwuXePKPKYa+m!t#&jQFBLByp:b
\R%Nh? kEDjd@&Vq/<S16i8Zj5aWD^<iA@\6IBEMD\m5AQCJl:wj&/Y%/ai%Y&uD5NIS1bm1e4WRjteddQCWb@Q
MN\=KW 6?Z##jp$\>jApRXQNiV#GcY#CEu+DFyZlC:A$cu5ujemZ<%1hX5j9T8>cLChJw6deamX^RtGE@AXDchc
SAT=X$ KaejwC:N=G5@EdcHeF$qaPP@bKu4nhM5h:&^pXqwTlth$JP>&KRB*YR\tj\LXSL4i:AWTZ^4R/yamT#S
LJQ%1T >t*DEA8%#hw66j*RL!w+4B<#aQ9*HAa<*\QFYwBQeLWI8wLlyBA&S*RCBZGWBamS4!CHF+m9Epki^6>m
mmDTXj GE41VkauJpc&BI5b*nKWQPh:kl&>Pb?$Ju8S4*ylY>w<S^@QpiWKhuRc!+wnwF<L\TB?kHL+yPS4ZVul
8+ed=P 1kILhC*9KT@11V?!>\:!qTn:QF*CG^uN%ukGqqW+lb+T<njWKCcVutT!#J=WCh8kV=upBujtmF!J4n:Z
E4*lMM VT?XED88^Id4u?!:hw%R9Zd6Y/?<<6=lEMRpj<qwA5K?X!CmE&Am9<C*QGQ<j/N#*Gk:5Y$hGHCmdS\P
SWDEKk S%$M@B\yk@Ha!69$iwN=?JeZYPPV^itJ!p4=Jjd?$YtPK:^=c&=4Dp:A>C&/$:@#Y8h:p>d=LW%t:%AT
$YpI6L =&%8d4d/jX8c!6lJj^D+c4HNPJG9=MDY!9ylqc<$qiJIuEab>ABj\hG=R&!F>S*GC:Y%9\lMjJCn$uTE
HCtHYb 1>c!nMlE$8+=+!:^=ChdReFKF:dSPLYPdKhnub&hPaFX=18wZSGNI*$/KkT5%#:?Fp4mQaKuaEC>X<B<
PjLEm+ &Aw1tABB@ENP&DG>9bN1FDh$SGujXYMXX96nut:d4KpI?4GjkZjVS+\qJQGX>I:K!kq6#1hiAtp@/hi!
>=lTEQ CeH^#KYF\C6F95w5D/#S/b%i?AHiHX6tk?WWuLhnVkj+Y8hIQBD/qiV\WED!6S?SSRXL8Jd*>K#iaZ^F
LThGDl bE@^iJQTNwV/<uiI@ZSj6j&XmGy9Y%&%ibJK@bw5@biEqTpn+>\TFh5QqA*NudJ6p/EyewZpK^K&RCH5
+6MStJ +j/YkwJQ8R6LeiLEY+!\BK^5Gc<wYK!+SkZdWwY:PAKFR4?KG@#bJ?Dt*b4VyC!GqVjS/#X9ThFM^\=\
TMZ>&: hEDHi4&XeLB#4^h8TVTZ+LDPY#%Y?#^L+IumJ<CXqh%6NS6WdDDy\wBVIcb$$H<>1jP%FuEh1BlAXIt\
6bThYN <jl1Ee$hkii/ID=WH?%WDS8iki&WG?yiG&\LlX1j=4/&h45Q4h/9chX4uam\u&AYXt*/4\J4SQaDjjc&
ejMu<G 5SBSy/5e/hNCkym6X/TGJX#l!WBBT\F*aQH$jDQd@nGtt$:1nLeP*IHI=VD\hVtG8C1\cu:M#i!e&Luw
RZ@<?i ++8>pAi&:iVYuH\uH1QVmCwGkd&WGcA+Mm5cV8dd4S/:HT9::X8cpyhNn^d9BHEA!E=1815#TdlmlBn=
WnjTqy Yueh:PH*Fd+Y>jR\9lJHm*yYecRMVS:y/dt#><+hl88SiGqP9pyQ==Q#VBDu*kDd/5&@YZMI@KY&bGal
^=%C6$ MjWSKY$$Dq/Z*p/uQyw&A%6n5<6dR4*KJ8c9CMJ?jI$J+n%pCR<NkA5:AMBT@J?d^C$/aVi!+wtmQW!$
@FACN* FDM/cBAHF9!c+CTl/GeeuJmWpPI!=%X/<>@h+nkLcQQRetKFVIByYbA>Si@GPy?QQjNepanh8wZY5c!t
Aaq/e$ GGX%MN:NQE%Wm#PDiB:yT8a\&E*9Z%j$/<pA?DV>PMikHFFF>\dHn8CeINC%h@bKZK5W9mwPdAej5QKW
&iS?aV HZY6*5*<t/8Ic4#EcBw#F%djZCjtaQGL=/k/wqGMG#JM48d#qSDYYib@!RtZ$W<NG9b\@^/Gb\H6&=Bb
kh8lXE HWJ&/E>5LCTZ^D1\k4DSnmyP&EVC5S\a>y5XYmK8tE@HwKFQYic<*9!!*m$P4KV*ntLpKPZjJ$LdP/cL
^D^lq\ ^ZbJ#:\h#F95aDyquhM$ya=m5llBBSW:cqbnE>9BJIaSTd&C&ZSh^J6IP>cBN1&w\Pk+CN<iVqmeXwH#
/y1V&b S?:wjB%T*EShn@FWZT%6YA<bm+mVHNThqd8P5KCXJ$jX^PBkb9NcHIVFTl?Pd1k#pPY$iGX!Gi8NMHcc
B#DpcA $%YcVYk=@W<JLBQEi@wLYq+y/B<+#QN%=hIpHuA$/^1Y1XmDJGcWnhJ?hVCIA\6eDk8?emP*dFLBNi#V
R/RK/q 6kG4@NTY@qbG&S$5m\jIF8iq\cZhuwc@E6d=i/\8AHaKwEY?!8Cm\BXM+qFDqNkj^CnmnCt&ZEh8Dtk$
HY+D!i jb<pwFp$WEEKFy*Y@nnPCcJpJWA5BjGlI\pnZ&ZpZ/&b!CB5c^B#!D9#n/?8p9X%JpiMtJhNNK1DaRqa
J%kP#S +Tc4M$PMk=:$#8?M41y/lY>yRW!@SbKaalN:PE@b^y^?1l+8H$lRpkhhYD:\E#9GH>MD^S$KaVFVl@88
AYb=$5 qljiNSB#MXmJwnY+uXc@/k69a\?j#^qljYGNwR**Tj@$CHkK^j:JNI6Y=QtLY%8VX19Xk*!%YBbeY=yc
uTDu$m cn^JhccdRj?pIbnwd+*a5HRNc$$jEF*9KZ!q=PVLa9^iD^ak+nmwey!ce$RudIL4%%5!+CRn^Ma>hV^j
c5LEm+ W>bKwbYh*eiFC*\pY?@T*n4Y1c9WAC!J+quT+<yj6!NnWu!HXK/5ZakW\%TlBISqpRqAq+L@i@1b?MZ@
QT?M+9 K%#K@SXeEJeZ6L\1G?%qP#5e&A/ejNSCGhkb9/aC8:k>ZX\<:e<#\n1uVijui#!iLdCeBIYqNJ:M!<5d
%G@CEG Di8lDR%IP?K%8<APt4HMSKdt%HSAi6TQTjny:hE$V\CI:bNWc44M^jBJpH5/Z^NI$=eHK9n5QZB9tILF
+AQBGR &eYEK\i&94SVd&mY%ZAN8\@#wpVK9u1>t/#e+&9MVeJ:TY8YVeX*4!8ENRBLQ?ja8GHet6KpZiShiW>E
GiZ&Sb IadF?%8I1lS*?9TXAVcKiaD?w*DDawpBZSA@>+Y1aa<ip>+PC^In11WhXSl^Rk>&^Y?iW^H$=Xy#/d<A
uDGjc? 4G*=L$ykDiIaBdWiW?cpDhwRX1h#cp9Ve?$ELY&FNpd@</cVaA\Z^kJ%c\<T%>Ec9uhQ:>>$HamJnk:>
$cA?6: h&t$FSC&l$&+SR?Y\*wwH6WLajVM86KLAQi5&=qKbW!Fi??8I&IhPtMI@+iwnym%JZlN%dATYNaD=QR6
?#6P#G Q4ueYNW4b>8\#4T#Kq&F/K:/qPR\Bj<@SX!L/D</\Ac>Aq*LliWEk9mHBtCQdilnAPSQnSJl$aMF9lyS
=^9wHF ue5/jF6#w@uhdY&i6yI=LwtNT*iV^GGi>Q?MYpc94Fm&qMJWWX@M$:Fme<jwh9EWNj4HyDy/4:Z*Vna1
M$6Lc/ jZ=R1dLBZkk4eyd#6ajlm5km8FW<AHAma<wKGW/!pX/!%e5uIPBy%!GJ/^F44u&VhmNlbjWD/hkVdMw5
*A%?p> K%HJ^LbVD!m#*upuV86mtL&9A9qK&dy>kGa=Z1$AdQpAT1d!Cq+\RcWV:!G8e%@I^ykd8qHM/wtniJCC
-AMD1^ 0008730d76e00110334 Page 154 of binaries2.zip
9mwEkL Se8JeJWI#nFw6*n+u\P>=d9T*achl68G6+#AcwcwqBVF<K>J:BQ>iQ&^$\qP4/^<a1Hm6KH!FAu4D>JP
V+SB1Z Dy!tR>1%X8e4Il9wb>W@SFDY=HKXV+<*KNkYdu6!!=M^k#/nqIYeZu5+uM@TFV9=8Z99EjHh1<iV8XIB
BYy9@T 4D@MJ?@ZKwN%tFE5GD6:kp$9N>V*mq\che=n4hSP!B$e$w/6iyulm6u%CnCY$C%ujMZwYpW=Rn^Ai&EL
!IXSA1 Em?I^ym*iI>m?SPq4>NAlK%KuHK5AK=#A5M6j4CdQLa$/l?N/=?*hB&4kK6/6RV$Ipnk^?8FVaZ4K%6K
9jTL<C aqaZ^SJbyP5p$JY&N>e=4y<cAnF<<q/nane%>Bj6kT9*beRS=+!#=1W>%NKw=#+T>ypnSNkm$1>Hia5p
CC6KEF u6FSFP!D+j#KCaY4E=XjI$T=RX&mBC%GMnV5c>>Ykp/CmeLhacFd6c^MwmwDVe!aqYJatNAXkP8utF@j
KBaQXW 6\>+muIa?X4P?A1kXwm!^IH?9=<X\>Ibaa@1Zm#?Slh?kW1&qQmcTCBjhRkqw9wNw:?@Jc+8DT?%6j*d
!FSh/j Xp=SdEAYLwSLdmeP%&l1cq1jE>qb64%T!i%IFd6hnP*Zq4E#VILwC4C1jAZD1RjXD4cuRpD:ee<4:/nS
9#@jwE 5@wMEyckCdD?mLhP#$wVyXP9lcq#>?1wM4=?:SD:X9489epu:HWiSqjuNVc=V9FK8a+q%Gb=PaQBVB$*
5uX!Jt \KyLaWWPh%RAwy>mqSMIa9Ln+IR8Hc5q41BPMC$5uQn:E*wuY&Wpm%/eiAEqMVPJV#%GPe\ASS#uFLc!
E1&%Iu L\CP*<Si:<<8LT&hl@9@\bD?*F\PC$5EqAH+#=$t:PH#6&9LVW$?u=1XqeFmBhw<Q+:kCPC8K!!BAYBB
w@SSmW 9c1+uuSRXXjFAFPy1FZ9>!mC?Jp:SLyu/n9GJX>=Bqb/5LY&Ty1h!lGqG5989an1HW:bt:pV5!F:THh%
q\!##q Gl6K>RG>BNHaGG<<i$KBqwE*V9P^GjA<#dc^aaT%IjH^6Z*:pLDIX$^4IF@:KTNbZp=!YFnE:#**QWua
y:8hyw Y/jHhBY4IC5$:FACeJ&VMMynVlHCY^@mcId#iD!L*Z:?K$@RCy&eaVynI1jR^Dw#+Y1c<?pqMqIWW@pE
hMBR?n !iF$iuJ:Hh>NW\m9k^R?Ya9nlP<yjiAd\Y<6b?+/+LwHwa*j:?pjAnei@uZwnmS5C@KXFeJ<eXwb\6$\
My%!A8 bLH!6wN!<%F9bjj^R\^Z?8=DN?&=Yp*ISq&5KZGn&tYLmYIBLGQTch/iu$bF$nn:E%J<mt*1mp151kC?
/b!Fdn jwwXdC>@YwEBGAAYa?EAeVpCm#8\TBD*F^#++ap9^AZEuS%SKe=k@Z?MuX>M*Fh&^&Z^5NkTC=6&pF<<
?y+A6N ARSFMDEEbJTE1GN:R5W+R^MLahV8TmH&CHbqb%JbAlL?CEb!VF=1=YFFed1KH\1y%5kCbWY5Tnbl+6$l
QwX=y< nc^EXekkcwM#BG6w*FSa1JL:&QM>=@/hkZn9d&dAbCA\u@tie?/>==/D1a+Y:Q>wP*##5ihTNhVHn@@&
V&Gmy# DXd1>8ZY:e9dq!>9d\<JYQG#iYmB>deR/:jwS@dmh!>?<h4nD<&SHwi5*tX@>6q@?FqYXhVd+DNZniEa
$J^:bl =J4YjS9kaepPB?wX&HXGT*wN!DHCAQR1DnbVw#dEFud<=8wdd^&%#aXtb%YSlAQKk194TF:yH%9\XA!^
5LqSwV qIiQPT5PPu4TbK&S=BcScD&u%CwFEZMtGLaJLL5p%c:9aai:wNiVpKu5Nhe\&QyBp%j<6jdVCjZ@WC=Y
/PLG=D C:d*I:Vcn4Nku!G>YypKWjyk>%V@mcm?84*>K9i%R9NZ$8\QP19myn9u9euj>L6uT5>>T@QR:%=5c&61
A$JKb! ct4:n6Pju9*R=5jw9Bk?QH9/@>==:dZ9yIVVB9IR/dWL^>K?Z1N6@bJi/\n&\Z$8hw@Imdk1#a*4&cI1
MDeKR= ymN&?KQZn14!Pi4<J%M>iwCy18@MtLYt9Z8\<FVHY8JwQqlDhpH5yF^tQWI14Pu1A</1LuQ>9k5=y+mZ
uhR81Y !9tankFd#/i\B8Fmmi!A+T49HqnmuE%&t1CH=jmZ58n$?5<i@>V+!&>I1N9dq/Z!=XB4=/86R$P6&>6@
48*hE1 5p>BKI*<CQ:H:@/4>N#+6$K%4YtnccP?/jHi/^&u+akju@/QiXA%qdqI4t>#>?>$&8W/ydnmlBpec+CL
Xy=QVG ?9hHBlp5GYL^5Cj8Le?\HW++T:Ej9Xa*1<4=HmZ4C/awW@QY?V/l!tD^<LD\QL5<@9MjhXFm*jNZLTpy
6Cnk:^ 4t!LS$!dDYtLw+5K/$naqQd^=Swj/!Kqh5ETh&t8P8WHGhQK\dIlj6/%C1qy*cbRL@?DKkT:ZEFkQ@>\
t#XL>K Z/a*j:nMVewkXMLb?Yyub!9cM4>/m85S:=Et<T/c91I9=I66G!>&h+>%$&nc@$%#?8X*Zu@6C%*V6F81
#+u@:p N/GdI?Tch94VSS64TKN1RV\A9VJaQpdaH\k<EEMMNl5#b*QVbwphiq&?WV!4T#nI>9ChP*#<@pBGXnTM
aA=y5@ LZ:w#Fu>wn>ZhiVp>Pp&6qmBFe*1Xl5LC>#FcpE*^8H!qnt:CYPV8l89\RJD5F%huHAyip*YnJiQT#a<
m=&ltW ^XGDEnmN=AqY::HdhPIJDy+cq^9@+lM>Q9npk\???kDna:1n19<*&/*dR$DcTpC=6*wuq\Ap\m#jj@uB
:iP9^e 54*=y:<:h+/^XuMu%+*8m/C/6hYhTH^!uMhZl:@/?QDHGC@V:b*Z*@9mm!?TVett?4ct:k%W18Xt*LGK
?#n=j< &N9yYF455Dp^B1+d^5ETY*ANSAanHDtXKE6<KqP8>p:5Yt^wXl?Pq@JFh?:<@E+hTtd$qSm1A9dlV^%^
/bD?hj 9mS>P1TH1QG^9Wc!M+b5I4<%n1jYtSt9b*\<Y4HLZL8MZ6u<Tk+<#y4X%Pl5tN99yZ#Bty$hy/ew#*WI
EeKhW@ 4BR&9Zn^=MtV%ThQu15tN8j8ZibtDWP68MC$6bPb<tMJAec6hTnVKpYJ6:jy!ijP6Z>:4^w@a?Mp@Vnm
YEey<< %Nnh8NZaeZ5Ldd<H6n:@HK&?id^D>@h\i??>y1d/y1aNtpjn&VnNDDZE$lB5&85:PAcY^HWMk4*AtmY8
SV&X+C $G5bS<R1enw^V9:X#HQA>d6n5+?PHeMyY:G?ZQ+Sqe/XZC%Ytd+?*C5@^qcH=<WJBhcQupT#aw?>9pi/
4VyGMR mbYD%V8C$RcmAN6%Dhb*uGn8<8qBjIb4eFChmG%4\E>?:A4YQ\E\$h9:!wVEVnm1$#k&hZH1+94Fp>Z4
cPJFd> wD6WZZ&9itma5b=/FXBqqHTmXF!uHWPh4a\idd14/dbi9d/?Vn@u+6kGaY45cF#8/Pma/Pm+MuBqRMdu
4u=mCF NJ+jMA*h6!m\k1yBFYYd8DkmZ4c$1%i<5eemF:Rlbn9eQ\ZB>pja\\aRPdFmM@iYi?D4#CL:@LFH5%L6
i#pL9K +A/Zw/4nc1wwYyT^R$Sd?c8jP1knW^$XE5h$nVQh6X=JN5eSqKl&IaE8bRpVMi&BXR:Y6NEWy@+c8NdZ
CqV#>/ +:V&PDqXHPIGaT+lW1d*%&6cEqc\CYpLLB:YdRLMLnaK^abS#auREyQ%>YG/Q^l?MD#$aFnVlE\@:ZS1
m*BT#E ^ct9adRT*TE<Z:+XQ&b1LI\c$a$h!^%jLuhe+ZH*!6h*B:/&a?B4=p^T*m4dcmSl<$A@qGkF4QDd/VuS
wTe#bK c/<p&=GDDjTZ+dmbiFk6YDLEEC^#bWQeDV55j@*I!JQ@SLnEXYeIK=J##y\=j+c^8uIX#jd6XSVtJcih
Q5ep1S k&yh^&BnntJ>5npq&lGPuZTV!J\VC8ihZN%kwmSa$t5T=\XJ4#Y:!jJp?awaa1QZ@ldVi$j>*FTiaLql
PcSbX8 dG>e4W?EeX+uHL++Fb\K4p<N4\@V8D<<9EuIM4yM=!&$?<F%/%Nh=XG#jhCJd%kjD1+Hy&leDDe!Xywk
?CiI/M L$>MVF!@j8XK!>&:h*G@i@j48^a6Bkt/w*GL+4iK^8WKKjFHF!eI?Z%Cc/DT\dLB@nFkbY5M454DKpPe
5PbXKY !b\+?WVQJ8p9H$Db1&N%ZGY#48:<?dw#BLabSREQHKnMbH#J>n%$RmX@59P@!lCn/&>a6it8MGG^Zkq&
bXE4@F SD5>:hb+h&yeFy/Dm+/SX86*//>ha//wZ=Ve=YJX1kyPnatIB\h5V!W9hLK4$ml/P9GSpt\nK#a<Fd/+
ADA1b+ NBWMEy:%aHCVS8eJqmtVuLVZyFc665q+:mbVZdyI<$@W%YK1+H4>?yMYb>^6iSq*bu!ZhN^Bwq:?E5@t
$iH48* 55nLFm94%W\IwtE!9X1\kR8pX\Ed\euC@9::JW1\tXNZip^8A4AYQ!K19&DnY$hTdV:V*H#t\QpD=!6h
CSPVcW yt!ID#wd4<wWQ>RHwK@c!Ip<dFmCkD#FG4I#ZC>c%Znu58AiX4iCAJhhT9=X%&:>dlh^*WWFDhC5=&yX
P<q=Ya G1\YdNtAdQk>Xw%cWl15d9A<w<n!#k=iWBVYw#EXZy1mC%Rb:KaAFJ4iwK@kB8dMNSkI%p+6Ia%\LMbm
V#piIE dcS*VH!mq/k14whdDl>?>@C:>QHhh%6c*tZGBQd/lL\Dwp!YbbBt@=4&?19HG/FZbP8^QyG=F\neD:Bk
ww?#qM eSd6qAtJ6+^iG>/WTT6lShiC8mNH$Ltk8juIpRQYDF8&B*?mm8%L*N&Xt<M8lVq$$85VLqlLXk!!LRii
5jR6AY l>W9YXqDZJQ%PL^Piq$l\WySw@GXhqV?CTX4!tmt$$%kmc54&BG%a=e:i>bkFdLGFB8!NENd1y&mK%m:
kIFl>9 8XpLh4e?%TRuC>t!hPtJt@V<Kj#JNFCQFJmI/pV9E/dc$NB\8PG\Q$C&=Rt+V1k6aZV*adJyc+jNAbSw
=h^F?P Y?SCaBCy$5nXa:$GiCtS\E4pXFLCi1*8GWuJm8!@H=YJc>$Ndpcl1BJZ\y4QqWdjL*$DdM6Mm^&?yL5=
da$\Ti <=waT>al&=8QNnhn/$d4jaA>5Mcl%&9%8<qh$m5Z1CwqtGTIWTPtjS^FZF&>nmTehc$S5:Gn8h18:QTK
?F+?B4 5kZEFINeB<lP%T:X46&94c*>6Ncl?d+<eF$^!=uId$:Yj4yIZJjY!EK>HbQPC@SnZ+Fcu@T$6KRI/@EG
$ZqnmV t4@mW8M\PDQb/^Ka<=w%K^dJjNaPc<FGy!Kp$nLqaRP<+u<@\Ic+LFJGW%k^^PSq4:Ahj4##5nREK#=&
lY1JqM +$d#DiBEWdQS16HS#\+ePjBbypC\qZ@e4#V<T&</4TcD&GBu^eJnPG6Q<h=<$VJhP@LTKW\^$nbTKwZA
Xj@K6S >LkLpdcQm%=Z&qhK^$PmX:XCQJC!9YMVcm%/SE1^ia4qX+*QhcBIVAX?&VWcT&8%\dXcE8Fp:cSk=L5k
>>>Vw+ jZ>Tp%YDuwY^6LkG^$Q9ELd6<YW!CGhJ4hMN\Fw+Dl>9cADZJ/V1CaZX!=9*@C8>4Vt:FwbaCVdTj+EN
/iu*Z^ MR=+e?SWImH^kFyG@J6H5u^+>EbXXZMX8I+T%T^^@i#Akd=MbV:b:b@9Y$4<16Q$%^Y5=E>wY:\QYpN%
=pPiQZ ^18:bE6YdlBTTBV8FVZIXyLJwq*W9C>6S+*$EFd?B*u=9$pu\GpQc:IV%d/kPYu*!kTu5uGXGAH:N1Mq
HBliyI 4LZ9%>cm51=CcYw/tn1Ap&m\^%k*c&9^Qj!ZTkMe?mMui5<?/itbdpmqGlLHn!@\hbw8M+l*11YH\d/C
jS9JP$ QTdAhen/iw%ZdERCF%B/kTlC8ukMTETMVQu:J=THLcq8+PY&Z^@nZtCQmw@?ww4G1KccJd&?edC!$A=u
?\yeYb nlRel6YhuC%YFm^m+nY%<BTL8q:Yb4@5ThZK%Yt=WNEGwVJZwwtGFF^4tjZcHk1Sn#Yb@&*V%lB#TJ\T
l#5J8Z T!!4^B145/&\HJW=BkT48IL5bK&CPiqR%XD%Bj:MXeWTnR!I\4Ib\y1meV^^uGdw^$<9uPaQ?Kn\NnSM
-ACDl! 00033afd0d300110334 Page 155 of binaries2.zip
dRYmN1 p&Buip%yE@qn$\=Z<@ZwSpTP/k<KX+kWpXPpDGAnF$/WRLBRdA9uHL&y1nDPQt18Yl%hSYQk$m#hZlk>
iIi4u= iJDpmqG=J>iHi<u%1twZKX!Z%G#H<dHSiIFwHdl=td=?T/PNJLmTk>$>BD6eYywMHaJi<YpIjWl+/^u*
lNwL\% Jw@4klW5LLFe#6Habj%@IT^a\*5:9da&6#bZY#6H!AyKhPdZiRS<aE&9$Vj!hL%S^ahQen$6$!t5jbpl
HNquD/ dBjWa&KEFE8@E\I5n8F$ZnYDhi&\GGIBP$d!JLq15DDEpdL?^j8pX@c\y#:HZ@:da:P/&YbXFnwq4KQb
iLTFqQ Wl4E>YDjHuLNHJRJ4F\1d4JW6YA*k<E\8XkDX1<yFwJXeL*FIBMG^y%8C<t8*TI!9aiIK^w@pWmVl$Jw
baX6J% &edhwLJJWPWE<Tbi<hlJiIcap#RI4Byi&L*MBWWRCFV\+m!yd&/8hw/\YwI8+EuuVqV^ZIA%JwpViWY8
tN&6#@ CXd4\5LP/S$HL\db=WTK8D:JiWi9<?&\+h$Y\RFS/BXITdZEGR+YkSQbcCQa#5Npln<?Pn84Pq#WbW8#
eM/$VX YjTLyXiKd69:eD%X?W6m!Bm9Q4!Kk#^M?KY4$5j=$niZ4TFimmF/<5QmcNRy8?<u4:qk@R/jMHDl=LXD
8Ew58/ $P8lc$u!1cZ$i!cLmyLem1>$bWZ$TuL6F4&P&I&FBhjDE6Iee**mL*@I@+btn4\+t=/#aCj*1LJ4<ELT
1@#%i< >MT=>B1?qh5HtMNGQhQA!n&tF\R161+e=TcPn/Rcyu8i?K8tKmLP5<M$C%yZqlkVG?lXCba4dWRC>$6K
1Cal1W qGD@P4G#<I@TPa4aF6@JbqhKZ^kF%Hd$nP*4M%^>T*!EtZK*hHiw:1=wA$w#YJ4CKp8<FBQNG5XGdVb+
1c>XNG Hqq*j8N$+<ZLFa8PldyI1CETLKtWYJc8lJJF>NpK/#WdTy1KmW&at%8\C$c\$!SaRy6n6N/MK1wtGbAK
nQ!1H\ h5utAQcy>V1qwp$6uy^Pi$jI>KtWV>TYwZkD$tlC&Pw9/tyViay%:LA6^>1tc1bEIlESdJpXdFup9wVE
p!kJdM SHbwkiSc4H1VQ!y?1/w$XIyiLWR%%N:?\5G?94+>*G5t<<aq#bBGHqZ6Z\p5e\*#ZSun6I1LQY95G?R>
nhH!aI K<6G?T$Sw=kyBN8:Y<T@J*Eq8bJi$ba9T*baCmePD6b51eRMbanqNW&wqK1#c4bMbQ$DYiwpYAYj#JWK
YKZFPe eaX%mjawK<bqM6ce>9D8IVLJ^SPyHyh8$$J&l&?1!Ip:8hPSp/6ZCVW&?lebLE>54GAnLNl?EY\JSeSD
eFh*V& ^*h?4V9nImDPmp%4D=YnNPwLqeVXMuZw>1FQ88/X@5aqd/k?wENae4KC%X+&1qaXZdbCNq:RcCH1q8SH
bI%iea SN*+HRtX+1NDl+1TdFnI>lcFEA8Mw1Z<jAl&GQPe:m&>D?kI>lQT1/RV+#1dq/Vw8nbXBtQjRtL:XcC!
dYlANi dauqXE1QVR%J=I<FLYQ/9im*Py8**c#6<I^4u8P^juYpG*1NpGDL&MXC5QnTjiXlM/j?ndn1cJlCy#w5
^+bG6# 6cI@%uk:ctZ&iX!hWZup5kK+jiu*m1*k9a^LeTY>CqnS4CF4JP8i8#J$dj<^6:quVAyA:yI<R$W\\!9R
%ZFPlM cGuwS:VPyPl>6DTW#ad1Qd$14w>6NyZPE?e4=?VG?FNqhiB/dY:QRtIFXe@u*NymNn5E?YPjtI!jlG$<
?*pAM+ jX\%E%@R&dD+ye:&#8T:YE?9<uKMRdBTYAQXW!JRcWBRq^pQt#qXM9V^t:P\\%J^99kPVR6=Hci<9H\e
$ZGkA8 VV\!jZ8=%$#tG/c189RTT1b:?hL&:!<lE=N:Sk=*Dt859Gi*=MVFMWi!Wbh5QF/+GqElNym8eLLwWAkc
$QZ$%b QRR:nLCh1M=u?dM58Gw:QLk%#a9jnq:F^YKDQhenI?i%iQC+SqYSBAj4=Q=t&KY1T!l#w45J*SKt:ZSC
#jkTVQ Z!cqc!jl8%n4aVXZG#uFa#Yp##E&^M4DSlaDkWWXEpeCS4DQ@I1X!ytqbIlZ5W*TZy:pC#YLK#&m=l?X
+Lh6ij d?lG44wD</ZLik#lGl4/X>G4h4F=M=/KAt95RuY\^6RnZ!5RK5E<FJwQRcPnwjq=55Nb#Lm#&XZD6e*w
?5$X6y %Ry&^\yYJN9V+=#emjh/^n@6qK*bS:CVHqm*1w$yR<Y^<E$h6ut6y^XbuRij51jM4CZ&@c5/8R=D#FbZ
YkC=md C#bmBB5^k5%p68@IYyM5JScj1Wu!9mdZRC**5Q1TQTmt%pN4tdIXb9<cZNKT^dch5eY^6EWd>>H/Qehm
5*m9Zu lmqhnT8:Q+aw<m$1?nFEM?$Z1pwJ/#^Q8ku49PkX&/@%HV4Sbpe4N4GRME&Ci#l4GYl#yuhH*F96eRTd
Qu##\\ %@*u1Z1%euZT+BZV/SRuTq8!&lS#RDjnBihml&j$BFbN?4A&RbHVddnVCBi!a5XG<CWnYP!tj1ccjpC8
WM!YmL n+44py#AYT+XFwG%e5?A8KS!t?Km+e*N+YE4ZPe?NNTy=A1\RcXZ1%llY^HhG/*/G!4Tk6ZAVdiFp9MW
$\:L4% ?Q=IZyY5:?kLBHPimGI6lV=WGj?18GyVq!>aqa#i$=N#5lT>Yc\1c#KZjw1H6iYV==^bnm/#Q=J\Wnd\
+=84d@ qyLY$!QVntSF#?L*uaM44q/>56l6pWW>la&\HabkF$t\ph95aRu5LTn&+G\^1%Z$iuT%Z\wYe+&&W+XE
I#y==% #d@QAh69kpGCP&VbDlt^G4Wc5NwWl/&Z>j%5XK<d^t&$=F<uKW+cJapY#aNq%cl\Jd&8n1:P4%4@&nbl
6QlGdc E8PMaEY^Kdi4h<?$QRjkS&58%@ijX5H?@d!w1djZPX%55L4h^DZcEh@FuuXmPNePP!9H<VDlZB^#Be8Y
u?#jhj PEJaTdPSSSa5kc$<Z&#pT9e1=w4!FHR:qchX=>PT:Z6CC@Re%ZaTbJL1=uB\YHPXB*=!#Ga>FYnY\DW4
6PMtVb l/l%pjdA6yFPmTZyhX/yFDm4\DlLH?h%&FR@pjQ55BH5mMwVV&t!Z41+N+9%C5Q>?hMeyhbii##R&9>y
X$Sp#Q qS=m!CdMPY/y/Jk#Llc9AHPh!c9dRB=&WZqa1JZGddHElQ1&P>jyt%ZLVbnHpmH89!Aqu@B^H?jK@#/u
u<i6\W VK8RDeI1$!Xne%mdaL+^%/B^54+%hpKw1LeT\X!n5ywSp<>QWyR$Tl4>pjW/Y5XiqZVdZDY/tq&X8At&
M<Au<k 8P%K#k&euA^$*whN+V!R5HXnauh>X5D?GZc+$L&1Wlp>KijApaccW@q/B1$==\BLwlW49+m9X@N?H*Qt
qN6>p^ 5B\/RdBAVawq#T/i8GWFY!^/Bh11j1+R^JW=tG8JkywZRbXp#lFWIT81yVE5nIQG5?I@mX\%YXVECK<=
qqR^Q5 bJ$R!1Nc\X!Sh<q*9w*Ql%c#w<TXKAL5/C1N11yt%851/jX:4hhyp<i/a\S4q+p=XX#T^h$5^ZnBbGe8
T!Wn<m @XT!Jl#&/qCh%aeHF+^ce?:\\N:eec8et>>pL@?KSTeIXuHXktWQT%S95&B9mYD%?nCedHFhid<=MB6+
W1y%h$ \F8%tZ$5<XR+B9ZJNEcSDDwI%RVH=!wyRC1qVi5Rm*i?cMZ8&8j\4kHyhS/tq\bldY+t4GS?<Xq#%T1c
kqaCGy luLmhQjk>$*Ze+Z?XYXPRK>+Rce=PtWZt*>myNAR:\6Yq>4ND+j%wdahnXZ!jQLAk1^*M1uH1bnn^E%8
V=h#aH @=@+YCRmbqeL>ndH^KJZkNWi>pm^maiJ:4lPV?%ZciRqtZ*G8TDJdm$Y$:IN1\qNWN$X&ZA?d6:kYZQN
ny5y1? eVVt^FBttV<Y<%\^njE5ARXae1cE6Zt$CuyFKla?w*n+?*yI>8?dXAc4tTM/kl&SuJnWCM$+SLA=Q%M8
uyDKkw Gm<$^W@Vc\FZXS8d#dBPwM&=8ZyPA4X@&69Pau&>Sp*dmZ:^5Li6aJWqF5E8@pGF^H%HhWAMF*8uB5pX
QE9Ap\ jLI!kPtRXY!iQT+y8WhkGM>TiMtm=Wj>#>?EZeFcIajD:1y^VE>qNNX$HqZ%4G<yYmKA<<?64lJW1FSl
jqCQ@V daa=NuGVeB*JD=!WIbbntYDL!c*PPRB@4W9H^KwA>6Qq/4Tdq4ILX1=PWy=N%YPQP?IhCb:Ym9Z55B<+
Q&bC4T ^S5b:G%4mSu^IkCLaG>b\SdQclh:6J*LT5y&9N4=1h^nCw6FnTq=9ZpjdpuS>dCGqTYG:^$&Qne5&:JP
TH+?u& >yNq/!=F^GJG$y^=FC+qL$yku=6jZbYM!T4NFSp<N$KK/=jQ&&N:PuD!=4AnGt*KFMh$a?Jw*m#&y!!^
1nLC>$ 6>wWh/8!/pJWlXmhJM^y=>^wRyqm:YL#=nqc49Hw&P*Awm6aywp9+SPc/>\u9WK^jY<XK\eLY*!uluiA
^&R+1t &H1dBeeC!iJi$14A\q*K6p*apY:ae8dJEMK1/1Bhj%yce<lG&aG!1+%bI?!G#4HaXBX$844/*HP4uF:Z
eHB&$F nE:ewH1t?WdXj>>aVR/TFi/ml+GeE#hyB@9a4D1q:H4ihEyCy@!m+9@j*9YE6utt?jctHy#KB=8qECPu
$+R\/E <eHPiEPVDFq!EHa&$M?nHuaCT5p\nHE?FEy5CRa$bt!XyJB%i=1#T!Eum*bHlP!pmF+5%%/DA&HbPT#4
XD@qY> aNJpcFyR\V:al<Je>**?9i@#9N?u#8=%YeqJFTiNHj@<i@+@9!iuVJ^@Imc@&6RQ\pc$e=R#u<ipXSMA
jn/bH6 EBY4\qPG4>I1\aEaDY!^%:51IVFA@CYnh91\\E?\^t?mP&:muEYEc%^&EtCS5\:YA@+99MJjqEP<9Ly&
IJiqIH /@*j*Luq+&J!9kic6JK6iqkQbQBNeIYJ!Ye@E:wCVS>ikN&E/6Ebl!8G\><Xy@:aD*tPDwl%Va>b8=M9
6RLn>C <JVnajPRFXnneFmKVZbDMA66*^5Y6XEwVd8+@?wJt=ccY&mJBhkilp=A&B=GWh>5Wp\5lMWiRGF/6PEJ
TP*1Tp m@YL#cH<cmI$Du/:J%@%M6EL8a8I+u@I*a/hjj@W1iqP=</HK&QcHJhNy+jkJLIt^FbEXu=@>5\#=Pk#
y8:p#C \QX$>ZVXphVB/q/+X>YH#!b8a9d/*hSje@kcDLH91bCZ^Yp&8$ch&I/hQmETwbwdD1QWV58d+j+kYNXt
\q&K<T wYI5tGL+bBSjVV\M#&an55T>aIuhT$jaViVncjC8HjT^#5PicjyRc\TD1/G+/lTCy@H%PMSBjIY*&?6n
KHmYlS L<=YRheAhINP#>%c6hp6B%EHbS$d<>@w*49NPSE>Z#l/kp@>&hGbK4H$+btH:tj*iQn\+jC#CiD4h<9F
*mkKDN j?/4iNkEVqS$ik!Xu5iC:I+8V5TY&DaAH9&N5MteFJHX+w&jkDWDdF&cP#FjXVWP^HGKAC!m&dn1:T?F
GSYL#@ V9C&^Wu5?Cp?JwDkHw+&QLBdZ:IV*5?4VkBnb?PWlPib64jZ#>:/$>KlmEAXPt@<=jI1F!<$c!9dtyRX
DS=lTP =X5Q!69$*WF:A@ee4NWLS$hH#+/RyNY1a&t%Km?ijZRVaF*?:4&?+t6\4!il4<N9Lbk4=1yV:chc5SIV
VuEL&? K&kjiiectuR$KwG>uB$YQVh$yVYDDLIK&K@<aA#lct</eX9V9VZbu!JnG$naHq6mSJ55<hD+//D5\$u5
Bjea5w aYi!CZ@W@jtG?><*N^Ha<WE?h9^FJWc&9Q*m:Q8Vy!aB#pP9l*y==kw$kWJB!6ikQC5q<tY/qnq9KtM/
ETEMNq XZ+VuKt#6$hHRNI:\FiA>e/pi?h\hSnDaYiId@/8d@^4QSI:aFnbH9N\#EL&TtE&hyJ#Vy@IY\mdElWP
#!lS*p %!S:^e^qR/$h+VNCFy%5mIyDP#cV9*wZt/bQtmXE5el<9hy:!5pPSMT>l6CSCM8/IaZCBeRWYd+F$BNl
M/@4nW B$A:N%5P!Jbj9Dn:byW8GZmm\w>V+#N#6%++61:C&!5QeKa=t$H%kDFjj@?MR@HM\/MnSBQNL/#@\b8D
-AN:a$ 0006ce1d8fb00110334 Page 156 of binaries2.zip
:i<ek* 6Z4PpSYiYQYQ@i8JHwklWP8QjcjF/QwbF&6d5b#IQ6K?>SFN8Yu*!w4LlK6j%Kc@u!l4wMW<NlR>miWL
Qp<l?a dh/VnP6NBP!N1?lmi#*CCVLZZ8N1IP\IEZd@c!^PaBwLp+uNl99nDWT*<TWA8&qN5HG!?%hG8Sya?c<L
1SjAPJ $$nS\$MNc1E#jZy8b8:!YaD%%c49D$k*4:#NnqT\Jd9MFT^Mqy\6Z9@qGeV!cQkIaAYcDn6MJ?EFAH98
a\lL%< JqiHVT&uj8\%LELS/ZEaIJPly!mHVi$TqIKX#dG&\*8&T?h:hE4w5c%R#bA&tBjSV\FVHHAN1IbG6TQ5
yE>CGI CB9mBpXPV+5PX$AbkG$IHX<u9lJqC:8nX+My@uJ#e%Ne:ADPQy@FAcR*&jKK8C&?LuTYZ9>ldtdt?R4$
EF8B!V jaC6MdIljBI@C^lVSaNh5H9@&AX$y5NHD\FPkuWa64AhZaiHJ<>MFIt\:^n=ClM+8b@4hnaRZK#W@>XN
IV=1B9 >t#bKeSPGXRj/XFELk/Lpy%ZRRtdS\^\8^dqP!*X*kFke@^4+K6Lap95V/u$n#Sq^mLeHBP@5aSM=dLV
F!dH=D c>Y4nWcn%\DPdt$By!>8DkRXnjH#>d94D^HXR+*1c/>%q6/+:ek/h@pY>Z#w5ZL><?9\R/ck!tG/nZmL
:h&TE* KSIbc5y#6?>^mDSM5N/bhHmCckJIJ:kZ#/b8ayb#+?N&Q:<8eZKeN@Qb$pq5P:<<<Tl:X?<Ve:A4mY+A
LuId$L !Ytu%pa@*n\Kc!66Le1\wW6Q!HVbX#iBuB<61b%9PtVRuV1MpKSQIZam1MEtj+tEHZyntl$5RqM+\!=Y
#QE#6# GP9?$Q=QW9dK*PpqS$:*PP#\+jHCc+XVh$:jy48##/p/kb^>>jt1nEeb!ww#bii/HTdj*D68khEFcn+e
Mh&1B% hnEb\A1IukJBIkj4:nP!\6<6j&\%TVI1WX$b+QYE=iNaC?*c\P1EedEE/melFndN%!C=Y@jSeC&:4=ID
5@#PwD 4Eq+hplHn#?hJGPJc&CJKhuyWhHyKTa:HB$*ZE!MQ6cFVpk%S%tH^>I=e1:CYH\Mnh8i*ZmpFZQ:>hPu
e%c:AM qyct\jTT\PKh4<j*=%A@j8c!NGJZ^>AI!@VMhWBYhYhJ?BH+/YB>Bd@%Ac@=@BKBBGC4DCjD8n5=:N:P
:w=Hw$ WbK#@A:LXum?%kNhjc4V>V>b\pduJ>P<&Mte\yRp^%TH>R&kjl=hqVpiRFqumw%@njpKMpX5mbG9!Nmu
X5cmY1 :G=:SGMA>8IRXJ%khtJ/h:j/WZMb+/5G@$@5a#j*B%JYXQd&d>??jj4PuV6j9@H%:jF^j?ll:9K/4!eC
uS!PTW Z%hY4+hy1P8B5tY1WXY+?8nkj!WLq&MZ18SK1$BZXymc*D&%/%:6PtA@kuNtW#eSX^W&/ZKVF\BDWBqk
VIjlE9 uKGIkM$ndAT5kB1KEyptudw?pWY%Ft?J>yZ*\M?T?byc@=waaDpt=ywVAN6\:&pRadja^d=?iGt!?tG^
bP^Cqm >?Cy?\NQu^K\BP$YYi8L8Xb+#5m^kb\d@HetCMjQ#e%8l@+:AY9t*D+u#91eS\b5kNd<G?ZbK64h!iFl
VKFE%k w8p8!BIB4L8A/8/bKc\P*=#/YH*4c&T>m+YV#q&CXSb*TH+/P5wi4cM?!pHY*$=Mkl*Y\yM?ic*yW??b
\a?m*F BeIwjPJQYi!\te>J>e:c%FX$5SA\IWWSNAy+1i!E1e#R:R<ui1WTaF$m:CuVwb@y#?SXu9cN$J=YK9dI
5bb=%4 Lqa+cWFV@A1Dy#ChcmkdP9RP%88!D?Li</e1puVakRm!nWnV!TYAFeVEh5>I:>X?=>e#aSMGVlAYR%HS
ht+<H! G&Jebqjn^QHPny^J#GN4wK8eAVLCp&%%ea9%n?MR1l%^Fn>4%1t%lZ?>m%m4RikWa1eiAp9?5\iE*Nwm
uN#%Ld !GaA#$aDRZ$A6JWWFy>at>wemKuZ59W/^aL6bWqH@TmW8Ne%AVdi=<Hi*m9<M>e@^+ZL5R@Sp#y8DkNL
IClJuy q$+lt48u?MZpPR1cqnY858N$jG^VYPV1eSi^bYT^aVi9a8L<FRAN:h+ne^A#$a5=%k!d<!NyVNycL4Dh
V&ui@C a&PHE?>j6j#Kp&X\5R&\^ESSa8\Y$=e\A&A^C$K/>kJqphyI&TEVQa$QaK#l/>#ee&#=HHDDHZuw+1H4
dXNh^b VFjbEFAYX*4^1=<V:Ll^?YK!5:RE$tEP&cWqNL?A/6I8Qab^h6m=%@ipq4=l+?EVW@^H66IL&dFRK5Z6
tZC8K@ iHnCV#5^59JmV>M%$i=XC#84TXbGNa68P+85/E4d:!?41uMDp^&Jk=m^WKhA\n1Pe568yEVYtnBqaJt9
Htp45q n6a$anE$\AS4TQuG\@:M*KlMQt^Z\wkdJVwM1\B:ZVb/jNDE9\p&?9*y\<:$E9lTENAF!Y9*A1XZEhj1
k%HWK5 FJ9ln&M:uHY\^*Z@:IbN8=&5m<%bAjDA^qdaH>t4beItjaGYu:Y\F?yD+:n/FP^\VX6lA&!:YHT\NLme
y/j5bE !Ln&Gn+tltwlWHF8C&G?/8B>\JRq56KQLSlQ*S!!Ca<PmDY\LuRcin//u9mSF8W=^:\lXn5>qQFkq?eD
%!P<tC klX&j+m\1%W5bX%CEEpiYXC>6H9y$m:QNlZjWStDmb1Wj\WLLPJPcuMHZi#<R4R:ce6P9QE5L\VZQcZb
>/qMJL c19D5Tyk#Y@yG&B6u+iR>V4\bnku=K@+9jD^NW^&$Pn&&MW?qdkwBMZ:M=C!E8DlwbH>^t<K1F/hMeLl
Q@\NW= EMD+8?iVMNbmGE5SMc^c41l%LT+an=G6=yW8jQ@bW%DCAuZPT:6LIu\NY9ZVT\:Z*iEtVVbBNK#Kem*L
LYb^!L X:dFZZK6CG:\5K^TuHPWQZ8LYB<Sq%8ucuSaXaen=jNcRDW%>M%1k4bM*KV$W>Ip&PH&\5jL#lJ#n/au
daT&HN 8QcE5P/Fw!K+&G<cXGF5KF!qL\@jGF5nH6qM4lQ+Ct@QS@ZpQ9bqtdEj?N$Q*KEqbANnKYli>b6/<Q+%
<NGA$b :A?^VD&A/b:\aujc\VyN$jCWw&9N<LW%IIE>X5$:maq=hGI?4LFLXP\bG+Dh5&VX$6pLS6i=u%H^JQ:q
u*M%jJ A69Y&i\G*iHP<FZd+dd:cH><&cDa1ihnayYm?k:A#DeN?FPT/jb/QG/MwPLp$\Bp^SL9#+B9ZX!<1\Sh
yeFVnb bAJCMZdX&%ub4%!D+lPH^jVd:u&mX4GEFYjTT/BLIe:/L5GLT!CH@c\ITnDF1jjmDB>#t1/mK$jEINKC
C<TH>< pSQNWGDLdteu4P#pNhu#kQX5DZ#hWHeV?yEh>6c+J9AK^quK<9*ZnBqP6ICw?!:/R=GA9eypjMDAmmYG
N1e:hd 8lMAP+IlX1@BA/u$:BGt1N+G?t$#M*ymuDQZ8cGbIbjYQH>*@Z!p$wQ*km5H*5hKEmN<Jec84Z\8tc!k
Nlw4mC #4niD*VFK#B\lwAiwF$@QRuTmM6MX!XHHqie@B^^IK^Panub!SRWjXAeIW6p*hQ/!t&%tcN9&B4ynJ4=
n<kFEI Ehqmn?\k9myD:Qn1Q8F*uI9h\4=14>HVnMX*iea8Rwm%yadJm/Rnk#8Z5Q^PG1uj@GZP4HpMDe*5n#>@
cbKA&8 h:cZqBJ#*SXuk9iE4%n=La>=aAZX6SWSMFnFZ6=%M5M5L*Qj5=Z8=mFuBhuyT%!WkPSX%hC>i<&aau=Z
+FJk!X X:eCYm%>p!Y@BSAlt@laPHAwuK?y&<5m\p&D1n/XGpM4jDZ%J9P^IQl&*9#u*=jI^mKMWH9\yynAy4:N
6eWcWK @tm#%^kJ!CKp^YdS9VXJ%BkZQil5MCa#+!=Eiu=96Qu!44uZt!myupwImyG^H:AlZq9S!?+TQQtkmTXt
@GSNmm j9lXS@nKS=5Aa/L4+jVl:4pmHJI599Ppue9Z85=#PHJTm:He8h9l$^*>?ZA^NybB!##NIjHWL4=t?X1#
9t>RJP jQYTG4ZaGNe$4p4MKqlm@GCRLL69w=$duMX/D@9A?%lX*4>!F\:cdiG/LM$SN%GByEtT^9m&&MSnH<%F
@GAVY9 pBm=6@!!tA=<5E!EnCy81/I?k9jDmkh&daX>LJRpFK:*1cQL5GIQEPE>^Q6el>Wm$jXGLWTV:F>6KhH!
ZHqH+4 %hilcA@AD<YawDk4bJKBNR*iNh1+!n56awW$LGiNICnb+TVt1@c9di4l6@:??^IF^TF$<w^6!L#V^cEZ
*TTKl% ThK+%pSFClS@Rn!B49/^mJBPVE^et*1mp?\$6b>@eLMePl$I5JnDG4+Ka>HHKqn9*@@QH#%h=TAmhlRb
mVi@6H &iq@LiKS4&99&a/Zl:X?HCP48:LwaWYptC%^8GeZ1V5lq8^Wp$TZJLS:NZdaTD+PjNR!\CK8TWbJ^haq
BM*YcQ WQ!4Xj>hCdMhLFBA=iHy$:eieL1D+EKuhinm$C#\c*$C^IEY<WnATICWd6je8@c!iQ=J195WAhXcnkyI
KCc/Ky &LeyC:C9X1W!AiyA%lbL%QR?/4l=8l:!TX1&^8S\l=5wE#:^jc%tP%:i\ZbX=BV5eNhMKj4XHSWWS:jW
bWjDue ItR6Zep\L8B^^b\46naE@l9\%tViZ/=Kcd41IK%N>%Wh5D%5:VVI1V:wQZ*\XtA5t8LNm^e9:1>VFN8a
JQ6hMw GG$8kw:<I9^adIK5$:*S&jPqHEZTAaRNmyIt%!p4R=#Sp<GwTin/1@9**\/\<n\e$^aZm1a@\mSu?b&$
y^>n^l bky^+aVLeYbw\4\nqIq*Y4L6QL@Rn!Y8#he&1%NWW/KI^:4eqLZCGZ8Yc+$JX&F5j8C$\GJ>>j1ji%Tj
j/uFEW /HqL@Na@l91?C=kYu#>@5c=EHey*%#>!L9Vi8>htb%??VPJYpY%XyKc5w1EFC:BZChAKaVq*DhB1bcn:
L1Win< 9:u@/cj*qSW?JPhKjKXb>5JD9NY<*L^lDtyytTSVT=RyJ$*Z+#A/+Rq4in5ba^kJutm:&Kyd964PZ+T1
mq<aTy /KWpGh:YnB$&@nXSbaq=1aL@?%W&^R&euHClE\ILduSpw4ui1Mk8c5A&IVGA@H>LP+86L+TcHMEV%u6a
CN=#C* #tdICQ>kBcCE4\:Z#/ktRVQ4uVD!mQPVleK*GA\9Z@NF%6Ctm^Ih*ctL?e1uLXq@a6:MP>q:L:q$4Xub
S/h&TV y1?Pw/9V8aSNw9WMC?#@n1@h?8?lQwFSW1NZi9DAleR*+W#l*XKpStmipdTH5V%lEpALYNyIRRFL1^pE
&nw+dW 4QSk%#LbV5D%M=@a!P=AkWaiectweGECn1w9Z#89D8D%lc>^=BSchh&<cddYIMc1+!C&At@bm8qpK&!?
LdBD:# 119VPZFVa6jpal$4^nYnA8w:k5lZD&8*?&eMul1qZ1NWLL/ek4PnT4bPF6yKi+c\5jH^8ZR<+=FD&TRX
Cw/#41 ISDna$QpqKjaJ4B??ubH:HDBS<Nat!D=lHNNNMM9c+c9yMtlKp:h1PdE\H/qHY#>MR<:Geb1yhE$VjJJ
PPQ9Z@ X9N$Ndn&5&hn6A%P:J9>P\HZ9am9ymYIQWG+qwNDQejh9+Q/BPR8N=4uu#\^MY9m/SuYWQe1EYW#X++M
ICPwX/ Z:Q&PFmS5JuF5^P4$q**66kDT*\XYKZW^GXmGqRGP@\6*4bh91bPcht/j=c\J:El^wK^%l\XDcCe^Xln
D:WqYm QpQQVG4?\d*/NKe>IM?^ItSywnZ9FX@yF*EbMjZqajmAwFQ6Q8y@jQ>99@@=H#Dkm&wbm1<m=+E!P\^5
N%>XkZ TewhKuBTk?!ylniNJcK%^k9N<*<RI1iMISa#@Nud=E6y<XyYCVw$^N+y:IItpjP9N!JeBhde*T9@?Cw+
Tyu/N* &PBlWRqwk!9FPj6aAt/1jG61#CKHVT$>P&^RVdSBX%@?EL+pyAenwlYb8CpNaS4aB@:*@bQ:8B8$:^/y
e*G#pp l@1uYyFLK4Fim@dh$eYFHGmDk/lRVF#t:hd65hZRZdiYiG*F$NX:X<>Zd8%<P+Ft?G=NHTJX/Y5wVZS6
dP*pS5 S/id!Z!/ckHA*\L8c*tuY8\c:RGKhm$&\^9&RLGm9Gb>py<?Jac9A4+icPX9JD9:D4nYc4XIE=aALWqG
-AV\Pk 000e7ceb38500110334 Page 157 of binaries2.zip
uAVjJm Iq8L&iBJNZjd6V^pLdBee6LCEbt&n1%NWJb#@:NjW/DENatCdF/!RF\XaJ%1Zn89:<815MtL@S=ua&I%
FRc\A# SiEna6y*=td5ltF5Yl6W@c8F4#LV^?Ac*ZtKR1cBD@K9i%p::Qu19=H$Q/\PPZP$h1>FACwX8>SK5J+H
uHdqmL Y=^G^?dcK5*S=6n!NVXPt%*5&Py1^NejyBhLb9n6km@+G:4TI6ET%<DPt:N*M9qqClQ%#Qmc/dX*QYFd
5cZ&G& JC#C#hl=G^VZB1Q1w/ckiDnID86AiQBD:HATB<Syul18#?A&^L<t*patySnNRNiT5eSyCP@d%lJdJ^5Z
Z1KRyn c!w1hk1ynw/JbZkC@i8uqLwYhEpC?W4/=6QjI14Zd5V*wLN<DaR>MidZn<dWNdA/ni$9LNnB5\GXi1K4
e=&pyR \VY$e#IXSJ$9qVBZ\J@lVaRFKS:i+/>&Zn^My%!CGP<JHtpP:6W+X&8BM%w6Hq:qaQMiu4Ac&BCYaY>H
HN@w@Q Imid\@JWMiD/+>8?%KRCykJy/^a/p%!^NyWBP?:Q\B/4@YaF4TG5BMRcYN@ecWi%$nRet=Cp\MH1#VD9
aAuG4u $tu@YnN$VVQi6dKumpH\%jc+=9FX\8H=X19%W*\6beREYD%JC^qtCF8#pXQ+b/a&ue&LmZu/t!iJ9aj%
>cXGt4 bln5<K<=F1bCW?nQ+d5/p/NE%$y<jnVE\+CT4!Xc\u=q56ta4=c^icPm$YmT>/=i^ZVD&8HIEAhRVRFw
S>\mMV L!Rm=F@bEChyV1PP</18u4aMjQZjMBba\QTk+uWjK8GDq>RAZ9wVjA&n59IhX>It+cBmDjGK<dA4Q/#h
V4+wkh @/#nk&Gj+HB%?LD#&9T:1L4c9P6Nay=@FW6<dJTeVw:n$EpB?%ka8<QBp&?#/<yL*Aku88+EM>#KD=8T
NYdVDH +GIB&bI%qkwCdajX\Iacyc1y9E4H\?&cL9Eql1lqkSVHpwT\wjTW/9R+c+F6t!iVT@tIYFIhMeS?u6n^
!C1CPE >eiPn+WLHhYjI/qphK+n#ia@&EE8!%hEKQC%1+A<5VQF99a9PnGe^waS^YCKk&WKMbQ:d1JY1Hc9k@LZ
1tJ%P1 NPJ4JdESK:yBnwj*Rp/d1j59<C1RZn*caL+tcSVRCK!<Pp:cTmY9aGl8jpcXj+>ycucM$mk<W%WuQZG/
:V$6Ei wmjaX6c?iF6%$#%hYYY1WKk8nnm&#9+&W*y95<CKn=6c89^@Ek?^?dXap<NKwbl>4Bp1%5:G^$^kEkN=
FnV*^n +nVH%y8p5l!?>BG1kc@=ma+IqC#M!@CnH\Q^@qYJPI65Ew8t<a1^%%a1&dyVq4By4n*Yta+KuKBKHLdt
PJaeD1 5u^FYA6<:LLD4#p+h4<m=#w!G>**Xu#%MXA&%eu5:J#w$wRRh5eZFPj%mGL$d/Yc>ALRXTum6j:ujM%c
8Zd5bk aHTCB+^4bIlNu6Q*\%Tl!6&TMmKb:a1TJJV6N<B&8?K%qjc<9dAPNtPFW$%bJeRlJYmYwjWy4LdEj9#@
LjPyM4 S+tbmK&i4!lkWXkcZY\8nnSu:<cZ&^qZa+k>Z?9HPVda9@I=:GQl?WawFT?$@XS^#yan\:yVX=4?G@%B
WA&i#n jLYBW<X@RZ#JBpEIhnk8a1V/mkCH\:=*wjlcCiPC4AFAKtmpKL5hH>H\Vna/>Kq*^FJnn$*6H/!DD+tB
%&/8j\ 5H=X=$yAhi%H/iIWRwy#TG@\nk<^byw6J:q<:Y?w:DW#eH1T!YK>Kc+H@WV9a5%ReV9iT&ba=?jb8*cQ
5PkTm+ qh=qP:?twR&4q>APAKC/S1Y5?Jyw914^+d=QZ>Ei%jEDT=1nP1MX%P&RWSWiSNKZd$\P1^8<8ZFVct>@
NmSnEE 1u?HLHbRSH!ha?JjCK^Z@8XHHRy:JTlC86PbjlPtZB9*^9BVpS1J=18l1^p+QetyJ@4iZXhXmdu8FA$X
$ktuBA B*&66mj4\5J<j\NQHmu*GtpRbIc?>DKE!nH=5wZ:\8m+Kb?91w5j>I6cda1H!d*mZ+qBW4uM!5<m&4=N
NHVi1& *qb/QNTZLbpE&WV@bm<:#TnX:BpHY<bJ+yZ4dIc9eNV$^Yi?#qRRK*^I>RkIt>:FMhh:L<4pE6IwIPb%
&dEH@X j1>c/letnaVITbc\awl**LQqC<ZeAqla<K9uTlRQdVCpPJEYuyJ8Wqqjnu<F/%jc<!caqZDeX<d/%<!<
ZNjJA8 9$>#85hcqcwqhZ@F%+MK@1&XeFJPFEeqm$%5i!jD%#Tj5LdpyEMu/1/9?y6b?Q#FF:<PSqnJ<S&!n65p
5\>tJt DNE=YQE#Cp$IueBc94d?S4<8K\QE&wp64&W49S%FY9\XuH>GYNG:8m@!mXJ@H<nZ8DBSWhQX55Ip<jBi
un9X%4 HBD:\pFw>%L$RJ>*Z@nK*S9/Z1q5/%5ceu6Buba#:S*BNVX$XbWa$+YN/=Z$\Z#kJME\?hbCS^iF5SSB
Xhw&Ek <jD$lSGItY/NRRKGu+b8dm9@GtD%H4aiXSLX+Q<Jd?/ESPe^c$?Hk8KCFVcp@IbR*hp^%%+n9tb:BwqJ
8m/nA* @JLkBd%!@t9@@@m@?9l9WE5DBBRAAkAIAAyYdTY@:aTBK\\AAC=MAAA4AAAAa&^ybY=$e!>\b*A9h&q8
BSZPKZ M#I9WEhRa&\9WtX#L&N!bYSyhHM^atq$LtJ6eP*eDXAVX^+A<F$T<%HRVWEhlB5CJ^@66FmKm6ImEY14
JJDNWi mNc&e*en&FP5>aQDHNy$Sn*SlEA6>&GJwWXFBJ%SPYi$6PJH%ZBb^KNTm#l$J1MmpI=<6PeHK/tRtCZ9
4TdV>k ZtKd9GVV5C!hu6httYYa=j*t@>/?@*69>\XNZ#^6Eia+W8H=FD\NPIdNk!eP9?\Hqap=n+D9V@5BALCj
yyuwaj HA<cW&FeD::j@6^&\lk5n:N>:/&+nE<?/E8j*nBX8#HJhGA$h9G19F#S6chiTY>Mct6QPn&18N6Y=idP
Q1Xum? :5!j9@&q:\dcl*c4StN#wa%5@/6<ad1l:adl\%Hb=FZ>Y#?:%:>F$hSi5j&KcXV&?S^5yiPH8XlAKCdB
J//wla Sth#ey^YIQp@!Ep%SuG&nb=*B+>pcZthy1VBc?8uZQp8huD>+NY@u?@ae9=V?XXYNmC+@ZV=XVw$ZSP:
Tac=L9 a*$=bcq/QViuWM+84mC+A64iKXiwcaP&KtN:$89J!5J<quc!+jVku6:\:J\ZBm5G1VitZk@Q\?W1huWP
9FBNV% mlS6&pP@tK%JZBP<<84GJ@<^@euC&TT:i\YLCTRF5M/JjA\ne#D<l\YFSS?y5ACB<^KJ5aGQ^V!Jn<FP
q$&EL@ GINNHaM6GIM%e:e+^h*!nN!6eA^^mVG$X$y#6VJM^6WKcW^y+&mqFAc+YpDmAQBFR1PRJPCZSCVl\&aW
PyDHmb 5LE+\HkACEKFFGGWG1YpJClBkCp^G^546GFCAHltLAGLDI&E1!BBCdAe=^P4V$9RGAFAWaI>45MKekT\
1#^d\y ^1#mElRtBcA\WtkpTIeNtG8QT:P!Swe%<4EkLDRHYl=y6!yYq5TW%WBF\4n\Z5H:nK6pJM6:Sck\RAAX
9c&\eI y@/XaymN1%XmPC$E*QIKN5#M%eLP&M#S+nT&QaEHlK4NPFDJXMaJeG#\TIJXQ5NplAq6I%R\PApKKTpe
lnEcl< #HdLJniEb9^:T^lJGwi&IMX8#T\5ReG/CtqwyT4MnFM!#B\B:am#:mQLe%tKb=cyKCt$QDbY/4BtcGYa
wu9=Ek \^bTlN$c&Xmn*XLRyny6EWpITSbYbwV6JX^Y?ekTKqbYDPA+lDdFdm8*n5I1ncEAp=LR\t!klJYKBwiX
S/8Khp 55p4JbXTkEqXh15pwVW>5lH5:Hd:!8C\Spya>d%NaYjl&N*85D\ah<L>WXlkATSMZwLeDFPSIwm9:hdI
6Vp%@Y 45:\6S@tItK@hqmCydYQJeKIYB:F4w<AZMiEht8&Y!uSaIV=dGcZX@chC4n5C!p+jFSWlJA$\l?/Tquq
GFaM&: M\Bt?!yK/GE5*G/y#cuC4qKenXXCK+NLR#XFqBLABt%BAhFc!t4<KkFe8pqMYtwW\tucB856NSPjq:Kc
VnbEAZ N=RADpLM<jl8jlRM*mceaDXQ!kBJPPe%b$ZbYyZM!NFKkYwD^6pmF$bdb^6*1$RZkAV&Y!YP9EI:$9p8
+=K#8Z m:P^PBn>I?\QqkiMuK*RluG&BMuhm9^:ja?:XZLiR#d:4h@/4h@/4h@/4h@/4h@?n/$=+TQh\<B%Tm:Y
@+PDt+ Yk=6bl+uc#JM$n&<uCjnbAeu/eK+Y84DqC<8mdm%>@yHBj<^X*C/#^dbdnwRYDqbt>Kj##?H:iI@F!S@
Q$5CD6 i?XcZ&ZQmha6Z4@NjGtJy%%ht^i@e4^Qi?KL9MY=>cd5Fb=&ZP*6+&@:6piiYLh+*S!KaS6:ct@H=:V+
9\!kEN 6KXj=I*Q%aW\dEhM:dhSWXF^98\HC$W9n=>#a!HD66Vi8jY1awp9Y/Q=#aQq&&+&qH4aB6Dj*#>Cu>R>
+?E?<i XA+DYuynlV?j:ei6MXk4B&5L+t91TQYBjem9twJNu=\JR!+W4a<9nlnZNLuL\>+>6KQ8=wqnu!JFNY&t
%MqWk1 R/j@lF\+t^5jw?9=^PBy8/N*%FYyD=^CmqI\:8pupA6#%5i@t@LkM+ahkuH*DPlPw4cNTntB^yZq^<jX
YSLlQ! @>6L*ElJYdZ&$BGp/ACM8&5lcwPmD1ZR&tCQuLV%dpt8/i\>P\EycpyRuD&F4lV%!@PcCl/$#6B:YAJ?
cH8q/Q I&%/QYwHFH4\ELqRykSD6mZi?>e$Ru@&&d>Jj$qnwbXbwMF41:*aIcb6btH@\89M9wSM5j@c$BkWX/!?
JBKXDK lI>*Zi5<XSW$@1Cicd@1#G=elhmeaFGeTp*mMc=4N$>X*n%?^I5N/e\t<%#qh1\J!?%V1T>NGai$@XSq
V+>&\A h:\Z!@91Rubny18ePna+6/bE8$DMh%&:i&w@<GdjCiqMZ=CFLF\T>ZylmX1W^ujh#K?LK?uwA$!:hZ1Z
SFH&iY wdIDtem#G9<<9/Ty5tiu!>+/u6Kd8<YLNbF8YXIE=//?E9j8MRH:WNB##T8y@#qudHa^4!dk5$bjSY$V
V!tLHC Em=pFG9FWZYi>8Y<&6RV!*#cSh1ADL=YHMt\9\<5VV*n&@b<ZkF6aBDDVt18FyV=66*1MGk#k<w<:jPm
qN4E6$ &6T@9iVdT5J\jkAiYiSyp!9PyB:#8ZVdiyQdq:XMjXJS\:BAH?B:/Zc5HeBpqj*1e:J/DLcLeX5nq4ZY
?=W9iP :%?4HNFTu*/bGl+yD+1XIip:=j*/tI!S:hC^=94L<jKbl/1SNNwq1>?&kwZ>8LD?hyS<S1^4L4MNVlVY
D*YZX\ n$6nE@hk9TXbQ4QaXhV&Zjtb\6XbLP!lGZM5WVH<TKVPk:H9%?>eJS9b%k*Yj/QIuLAX8Xh\wc$jXw:e
+@HqqN S$N/wA8EV%<i1e@KPl:d@HM:S&8d9Tu=<yX&STWLG!TuGq/d:@wFLb1i*K^1\=F@e*P#TdA=<1B<uN:V
mm=Nwt =5Zj!@yDmK9k<GX6kXnV6mRK5TeMmtM%<6WMi@6+j>y4/Q\e1KH*/64tduFh8Zb859JAubi+6?Q:Le5J
5i$R?X yM:lGu1QKnkDh%%11>MYyJ!Z>#D56%H>#Y<khcc6G695appW$6+tdjCY:4N+6M#V*4uh4*m#D:Eqmh6q
#<am+T >EPqBdG6Chc#B=i%KD%6Q#A1X!DNyWMXMlu6>ly\BR^bbH19@Y6lpR/$<6e%FyR@6Y$WyieLEnS/Z>A/
^p%aYG iJl+Wd\8*6Qi!M#P*%C?a!T:NnE#n&G6RW9#N^1\Ei*WRGbec@P%jL=B+HMqNTehZ99M=Z!tjTKhYKQS
uq=46@ qQ1M1#qMBI4FWR^d&Xi>cccq%1jhhZlF?N/IQIcFy*DI>?J9uuWa9GlX?8j&u>bc#?t6t/4bYEGN?5KN
wRNj># ?Y=9eBW//\JpP+MiCu^4j5QGp%jDQi$LNii$N@c=&VChhSFTK*w\e$FI^=1Vlu%i:IX4Scm>u/&#85*&
=<FNnN R+HLZ?4IPZtXaRN1%AQZ*iL&bP9EC@ISG*J=EhERi:KVaSN4Vq\I?\1%*R6%*/^C*n9y?/J%IheuFp8K
-A^LbD 0004f6634a500110334 Page 158 of binaries2.zip
NM<PBu 9NT=>:#dX8/hX*X8?^*$k\yVZ$hYdZKjq#y:9C:e?+>PmuakLRW&beM9KChbQhnSLC^>6/Y5Wuj*VHL4
$%R/Wk n//EQ%lB/IYXjG&+c<?eY5$91>\#QqKCbBa\yw6jahyaEbtGcVNh%lTVWpd8HS<>kP=KpP1MSW!:RaR6
R+aNhc T6AGQ8jcy84lq#Z9c+pYw1N\V=l+pa^yA?^YnN4w58aTQF1D^1$K#@Bm*\qPV?MHmIR8G%QM8%YTF8DY
d96mL# *1y\Mc=uYMY5Nayu+<Jek*<kByl8khac6^i&L>9*ynG6<NGuZ1/QCe!4:Z5@4i=>VkLLE1==bjLQ:Z:4
hMJSZH 6*:4!@:am:HW\\/j@4m4Qj@tMVc&!>NPtqc==@&5y=%Vt:Z*KIHLw>@V#4&MLAV9#41ZWMGIP?qnZapl
#:Weq1 /^tA&Q\=<8mb&t#EY89%h<w4QPQT9=8Y<nT%:J>w*Q#><8l^&uVWX899Gyn&=TMyPh4tb%^:n:FH<#9p
!il=YD $VP$::ndm%:5^h>Y99ZC^Yih=c\HnlI6MXk^q4:A#S4K%b:6yj656MIMZK<L%wP%$y:M=yc*i=FQ&/^/
:ij<LG jXqTH?NiRY5cS1\=:mnAGepk$=>@9HJ!mFXK54E@@wepnR#d*:tljV>Tw8tQmc5@/q@heYYYy!%p&L/d
qK\VaX pm\SWpKNJ/cN/$*d!Zj8q>n+pneuBm9K$<RMi%&:FNt:AdNZJtdEGDN&Sya=:V#N$wucDWpa:ttN#iXL
NS&EbN $R+%R98i<Z4<V8j#PN&6!jw\iHNTKCN8>:#k8dlduaM#a1ntGQ+8y:&w#TnZdppMbeV6ubjRmQ:jMlFm
F\dcNN LGMu%SC#+*tuyVZ#Jp5&d&C&%\lAF:w4E#I<wB!?d^qGupK:4^q&#/Dj9d*Zt$X:w5lmA5MY%N4kk>68
@ud?5K ?*P5lWNPT9*4k6@?pm*\&<jja6\Q<F>RT\MEFAACAAkACqb6JS*D?mGnNkAAJm5BAC5AAABndGqqduS#
ddpBIY L*BueC>*cY+#Mm>RS%BndC>TbZM9a*JqbGq$e#SmcZR8at%\:H^Qe>#I5Tjunedh6=+/%G9Y\hF9I>a:
V@wZ*< E:5H?VAP//bb##1p!+aEi?WtV9%&I#a$N*YQTAE<VKDyEcjBE+\Dk4#%X>mQ+K@k!:/n9\J/^BdAW&*?
Ca^>Bw LWBcQ#>SqK%=M$%SVSKNBmw45#J@?e55@P1@@/j@<5Eijn&D@=@C@@<Lj@+*?Q@B*m$/@u@?M:?QZ^@L
$:=M86 j@=c$9jie5p@<B@<<5e@@lF?+lFQ**9i<\@<l+j\=Wj$>WHp+J<%>A4j<EY@SQlTGj/P<WCFy?Gjn4=N
8\tety SQ@lGJ%Ju<W#Tn\MB$5<nL@FhCu+ymP&wt6bQAM@EMq@8c&Fp!#hFj+!@EH<yVJ!Gl%#aZCqZKF!NBK/
=i6Qep 5cM#iBRSD^k9?jHiB*Bd@E%qLQtYSp:wlDX!uC=Bd=X<L#/VlpBC<&^aFkuQeV^ZekPin/lEeiADRWwu
lp/5jB \wwWKn=@$9AF4YPldBme=j9\@T9?LE9MP1G#?DDIm6JX>qY%mm=WWyJPn\i%Xn\C8ySMpiwEZl*yyWSl
F*VAmL /S!R#@ERcV:KmG=Kq^WySY*\Dq:C&b+^<ABF4ccM8<HSaXa:YRyPNEq6bhSB4i:l*kiY#WtELeW<aDCh
*PQ<XG Y5YA<dkKd5TGYc*P1ntTeHVR$a&/KbaVcBV@8k&n?k^>kNiY4w6TQ$+#^cPHRjVW@81!$qF$cmY><t?p
\a:Q#b WXY4YE!ycuY5KMP&VaK\jhDAeZH#mER+tk%XB$<^tIRNc5ZL@YWdNm\j*ak8ISNkk8H&BEN#m5N><L*1
%y1!iS hdZ!6JFc#WNe4$b5GK!Hq=c8DS9WG9Q%ZTRikKhFBk/c1HT%!NV45m^%my$aV?YC:@qLNq#^PPlGyZP!
bYC+jD 9D5dlniMCIdH&DyE:jRi1XXEbB8k\iI4/yXZB@p^uR?/C/<dW15^61>Y%EdWiTXeaW:6FZ?K4/!C6ayD
puY/Hp qHX9bLG:@<?G^d+M?<Aw+4qAC=IB5t?\dB8q*LbTe&J4\&>XK!$?<R%@&Q9ApRAWhXR#JWWeW=ck#+k$
5@8u8& q/Xl4WRSH!Z#=ZeN4&lbMe=Y1uaiWTXt!%NN9keP$=L5&dBIRGwqH$nBJqc@1G4ZPa9W%V5%c5h4nd@W
qa&ZPG k=c$ttl>1X=qWem/6E=h5uE<\hYcb5tkqeCZNY!?Bn<R$$^bpw/eX$R##uP8X6T6KSyRKT44dNlE+ql+
?YVlRC =dDcLGtAuVG5LnI^ER^9XF4>tBP%w9ep#Rc*Ri/YQwQ^XR!N4bbGWjIa#HE$Zj*$JD1PF>N5ZB$jHDe^
mY=#\c @JEhJa6%Mw:&F:bbJIp#W*eeJa6#5#lQ+ttW8pYT8tS^HLHdq4EK8BCLw6p54R8GC<dk4IKDpnSnNX#D
jNMb4E JJL%+B6YNMJ&A^:P5iQ91bXuQecVK!h@+R!Cd!LD+bnq4Dkc5mRZJYjNi4!w&9NFt+$Z&@ZyiGPV<b?1
*+jJR< m@a+L14JXXH6Z&Xk+KjN=DnJ:LbbL:J#Q#:ib4P#S\6iQ/cMNNa\ZmJZImmHHVkd6uwd<nnwyW&\&=J?
>CjJT# 4=^XlFT^8wIhSJ%ceY*RY/T6mP=X$9wC9Sw=Gh?J^C=KW4PhNP%59Inc<hFtQj=VP!tVSbSMp1Q%WbP5
iMEwdP w%p/T::i#E#euGi#Kqtd1*c<cFd4cd1b4bMFV#SBCqKH+&6L&DX5dASNDh/NDI>5u<?nyT+Ppc>Cd#n<
>Na!QD 4A!YF4TnleM&nL@STmMliTGcTPQ<H!m?c1!*9aCAu=&hdWG9bZN?9AGb4!dV1/lMJth6/:dF:KSb4<@c
ZjI/dL 1<K/4V>jL:+8L4dNyN4/Mb!h#T+&WcVwXSiNBChiwK!WWw^XRwXk!BBWiuDG/5l:RFT<w%Fk1jwN&BKn
ySDhE% pPA1\eMMAp1JeyXAZj!4PRabdbM55t#edLQnbtG#w?aaXt\#Th4JND64Mnhh?QFS5<tP4wy56Yl?tm!c
QMSC>! by!hGZYP6FK6Fj?8w#Dm\p9Gm:S?K\FKGqRIeEmAa8SWTikyK\$^9I\=GKk*btmmPa#1n@&\JS<ZhYqK
=*uIG# JjQnV>CGEhLG$/N!h9IIb?ZC&4K1HMAL?Q?waM\HB$GXW*BIaD>^aVE5qbwCmW<mn/VRubZyklMK?WMW
5hFiwY #E:5m>$5?p9C%AwG%SjJMuaKqXSa5S+Z>QiR+t6ILBR!GbtjJC:AN>u^\qTkZ!9+m/PBDGhN9yBCaR51
/BRpRB Bn\<ZbmbM&FA+wAb^/PMdMMq8YtLdnS+4+A1CRGXdK1C^$QT\@G$<$Y$EklmXD&%!u>i1cZcMB6<6=RS
LHLu$X REkelF9G<TQ4ak#6G6aFLI5j4DS/p=8upF>X>pKABJ+a5:&\idwRXkt:Yyp%^%CaW%ZL1K*1dDnTNTc#
\5</#D X4K=C@+18:T8W/6IT\qRFY!+WmW15AMNuX#R8A>\MI=<ZMtjpkBJ6wSLBH\ptcAPn6!Byq\Sye&GnnAe
6RNtEV I/qKCTMaX5T<4aJ6kWm5EdXlJ+m5S\lI!5t#H9ekS1T=KVtlTlTDa!T>XlJ5bTuD@/5w*8IWJw&S!bEe
j/PJq= C4XG@kVqnTuQIJDE1SDiK$cFMdcGj!i565ya<VwKh!XT^wIPhLXcI&E?:qa4R#J&XmbTnMp=FW&t^nEu
\=l@WT /SGDpWwtk+EMnlFp^jnZ$SH8LIy6WypEI*^ewEI8VHTPc!i/1PBh5M@Ku5C:y?dWSRhtDQiND&lJHXq+
V^EALR ?<VEy!j^TZ!/Z^%WY:h9!#PDc+B8+Zni!=mYEII%pM+JqK/WcwpwlJJ\CAS^R5mD^=cAP</F$YScEBc=
iw^DV? Bu/j@ShG&W1RF85Xe*XGWb4F?YTTLb4Mbm+bL*\GmGq!bChHCem:tDa&P<tT>WueVkAen1>tt<\tGj!?
6E+i%j n1aI4/+w*DV4<&T#Qt/Pp/9E#M+*@#JyCw4^GPRh\$I4JI+ww/PaCK^TFPLSXwdiyW!E<DmnCLF^ATSq
bHSNyC SBcLc<JySt*bLkk<Ed^A:M>4WJb$9DYb*VTVSjPu4\H44Xh@cmc^Y=&Dy8NNNL9a*%#N+8nm16l51@Gj
IdkDPy m8M5*1/uXba+CMKd/Zced6d4p>u1iJPM6^i8ni$p*!Rp1a6/<V/RPPAIYe\!?H=P%nZH^lZGdJ&%#Phw
FRIE*J 5qS&iX5WcSJP*y=nL*6!IRXm^9+M!&SJV^dX&t&Qy<j6IkFpPD6jNBMD\B:WNq/55>l9E%B^9E&PG$DI
LCtJ:y !Tw=*p!Tp#YAyGT&cC/c<<%5bmh^Anm4*YauJq1jd=I%^+wwpEHC#bH%KVKKFB%\XthD:qZKNEnmZ$w$
G*/D?# KEQi=lmatEn=BjY%qh:FERXB<XYuFN+H=DBdLZ\^Bj!?&q^q1?N&jRV4>@\E*94#iuX<XY\46><edc/T
%pGytq e>D:eR5&*KJiX?81niFjMnp8#qcd:Q!+dTD/AK=5b5jmM%=VK&qXw*8y/ABZYEtKWKbG%MyK%m#Y1u91
!lHtXT ESESp!1qWK%MNPmHPZ>XSAu9H&^MuFSu:dk/P#%iVI?u!b?!a=epTiY!SVI=n:bZBinXZ&!tS$Y:tFbk
#i<T*^ A9HZ!ZpW4SP:1yJ1jY!VC@mbuTTLGWC8!WX!dN8P$XFilMPBC<mwDPmAMTJ#RR!LJElXRqiK!!WkCY/X
Q/\R<E mRK/J1i6CuaFlln><B<\9yccD5P*V=#Ta^Bn\THbeSSNp/?hLSa#AMYLyAFQ+jeZpS6ZT8hqMQS^I+tD
nK*&u< NXP+*qVm+P^EGJ+?hW54pAp>W\adJwS1P+!wac+DnR^PqMIMcw%en=MPaFj=w$l5\uJ<qaBH*$ea:5uI
Et$e\j +kWMi$H4+R\CJWDkW*98IL#E<Yq%WucXAW9#e/LwySyZmq?1Z5bB+*EC&^lj8tDDX6n5n5SuP!?F9GEh
nc!4A\ Kl45GB$J4<KE9uyQ6l\44I/LpB<&R98Fd=%VIu=p<pyb<=HA>Ew=BW/VBL>Jm6VSpC/WNnT#bmCk*L:y
HH4A^1 LM%RlJTF=u4<Gm5*DD!K^aZbeD$JaM=KiMX:^yLJpDHRl$t9ZaqE$#1iW*d&mI^p+TBYnIZ=ecyYtVuN
%%iLdF L<q%K1@LB6T6Xpj=hBpYy61\WBbP%/#++>nTS<nZMqGBj!uB#twq%F+JZyLbIKcMe\6b=Dk%lIe%dhV9
6B6Ey& EBJIPPNYtmhY!pdH+88aMC$DR/b%n$Chh:WVahRaK$ZMuSGu*6EPakCCC\l/G8FDnTdhpZAcl1GS$BPM
Wi/tSP W\%#G9lDnT!m<>B6Mh<W9cdYZ9WIlh6Q6qZI@/Xmy&pR=a/cZR9=ZjI<e6&k1=*$TRDt%DW1XK/4W%tl
:yqH!H @TZyIJ85PymkpXPNITVujhjWa%k$pTDNEV<emKFI/qMhqIG@M4?kmiS+\a\wJ=$&/FXJ/+:M%kInY+!W
WVpi$> H!V^FB^VS1?IIjp6i=LImKMT*%W1peCDDTBLTb+!YCchHAyi%1qdeS^j8hDwkk9STk=hd?\dy?\uZhqY
!HqAKd wb=uXK?G1lk!y&YweZR&#CteZJN^nBW4K#ZlFFA8k9D<T=RMLyd6Kuyh4YR?\Xq!F8ZIy*S1=j\%n4y<
NFc<:^ Zt*AmC>!tV<Tb/#GJ/=MlmJ$4nIG+l&6bBjPlt1d&4AXHPNiKc9ceM%A5dAT!qjSu>GD4nNR&+>ZyhVP
*wm#P\ PdZ61bZ!uM1+X>T1hW@MFh#Mi+P#WRpBDW/$puwc*yt!hi6CTPMEw\#5h<TuB6SdMZ6Sc1$9mBH#BG1h
Ica4?@ Y<IXe/BXeP5<lWdyMMyG\#K&4qjh1+RM/hTKNm^VEBb$4DkFw%/W?T6KnaT@b:$mw$/84cLC4%Ac9Gww
wR4J?w Awlc8VyjTY%HIZ/q/dwyP#FMCE@KtEX>TqTN8>S1!C5ND#L%Xt8#X1iKjd^RnI!dip/a9DuSPVn\c8^>
V&4eT* K+J&M$ACBWIMa$kbc@&5=JTtLL6iB9tL9YebC5G8B>nC4IqBBe1*D&BhtEV%Wa1n6GnCRey%FiXT#RZ6
-A@=6Q 00022720f0400110334 Page 159 of binaries2.zip
*Djp?E AP89^mnJ!B<5JT<AkW#t9V?V=waKS%NylAt%tFJKTEbeLPjdPnNGq!ebwKp$CAi&56RFW+uJpYJX*%&b
tRV+^@ tR6Ni1yVl?^+eCY=ePEqeE1Im!\qdia*pQeZyp@Ia<aclw%pC1L/Xp8/qtJ/u>CY+4yDdPB/%aNKWlyP
y&>Kl9 4!Y1w&IIFBlbtcF?\XREMaS!1jC8FR#liPK+GpK<W!VqGu$Dl!K<BF!N4/jknDAG%uM1E^VK6t+P#mGJ
Nm!\!! R<YlY4$@+iTb=MIb/WA8e/keB!TF:4iweQ5ESYC6*Xc>PtRAE4w+8iCpYR/Fe&h/cZjX!@PNp*1haP4T
e/14%M h9MjKy5Cbqlk+j%S=iLCanNGCW@^k&MT%Y>CX=CYaK#!+nVkLmB%H1JmHCk&Kim1e9%cB+iV1GNAT#a^
&&nQAV <ShS%:iBa?:q?XKF=L5/^hScCCIn:Dy%AnFiMV>MK5jQRMk*K=C8wYy6!Y4%dWXIp@8bDHQpl1GFeb#y
@JTYwK qJL#Tq8WBpkKKwdmP1%u@K&MBH^Wt1*bp6&9NW\nMkT8yP>L<XlR1@I5kwA/5pum5<KiQkiF&8j/c/SB
&NkN5$ A>=NWNTaypnW/l9I^EGQKd^:Q9*/DE>i@e8KSy8tKj*Mn@GuQej*F4a/^&GM$ZjHedw/\?8jJ&tq6qNG
Yt64FD RY6hIa>kTTW!Ty<LL\qET/1q15M=ttNcKjtE:k96p!t=tpFa!%JN$qyF\:m5#ttBeyRX6ZwjSdPFtX:B
/tK=8X =%hN+@HpLQEd8Cmi9aX:+c#kFRweTtPM^&G5F/kMjP5E@t1!dEM\1+^EkVkT$^Z!nPcu%4ENXLJ&TXH!
>?$%:J 9?!4tcu9WQLStwC$FGn&4#pA<j=PYR5+8w?mHZF5X:X/Z=pLiKYlR^mmBXZcFmb>et\94yB^&ZAa!9BC
/J^hq1 GXwCZG/&RL%PF/REA^=6R@WCDulX9?8SwR+VwTGFb9AhjEBIckp+qHyET#+e#y!&F:/iHEYe$+XPSDRe
M>XI<A XGWnqdCkX4?wdHdt<jQVLM9R?c$T^FQShBG=F9Y/+K88eam#Fpt%!LJiJ$%!kyhPE6T4bXAZe^YWl!YI
E=+S:! ILbCI\k6F6bY%*+tSKyV%$cPR6Y1dWG^PtH8jNL@4Ne!Dy%?EaeawmM/6cJG%%YL*1>I#w>\@l1pDm5*
j$CP^G YbkD%m8lq14A#:14k44JJ1nZckJu+4WdYK?l>CReE?i<Vw>JAXB+j%%dS4yjlLDw%hbDb=HPGwM1Km^%
mlWY>b :YJ<u1Paw+W4mlwk&BYjcAD%N!145?Ntk!Niu%BaiNVRRM#$?QSmC^<jd!>Ra/lZPCqyCAaYYHkGmiM#
6LSQK* CNB^m=$yZY+tDdjci/Nq*XLCBqINylRLL%XA#4Cp:m!ye/pWG9hlY1wJ&qi+Sp/^id*cwNcIHSN/R%V4
CY*Db8 ald$cn*N/k^lFGX/eNBcQGpDZtJj#KE+\Y6lGeBch8AGwSeK\tiWWSj9tdS&C6lEYlj1dFY9$a8Vk!15
uqnLFm >WCJcQFARnLPlJ^ETFN1hdR<CA>4N^?<DY/XZX1M1#YKhd%K@\Ien?Z&\1>XAkhn:nAP*CmY%^+S@^ZL
iiCNE< wWeq=+9PCp6GAcZ49bH&F@VK*DIYTd<$u%!J<<bSC\XXSyERV*JSJ+RABZYq#Gl%wE#cL!EId+a?q*pm
?%ul&y B5Kb/DXWmAKB%FXNRk?LhEXX&tuFXZKq4%^wLR=Npl$@WFbhb:lSF4TTYCnFKQ5cHSccjd6C8V11!4:T
>G?>m+ Pew#wQ$TuA:5p>uSkmpw%ES4B5TR5^Hn=L4^cW\RuCwyT*C8bah<JYZ4^lGcNq!QPR+AJ%VtYC%^X+\1
GFGykM dikm$YKZ4PqIDd@DlWFa9b4VjkuYFYl^R>e*ERVWFl$5a\p4#bBS*BF$eaDyEkCEcIuyV!Yd1GGC+q9w
1JZ8NV MC>D$<c46I<LTm+:9p91Yl%Bc=*4M=Il4ASe*BXabZJLpXu:JbndJnhCd48$c:<wI*I?SK+lpDj5@/N!
!P^m8? @!IGSA#C&w9+yMIkX<p?Bq1VF>!h1pT1yFG<qmRDnuyIXZ6/4Z&6St6:ZTFK$Ib85/4jN!&Et%mw6Z%t
tqG\bd XX5StG?TH6\T:LalI^^u#eJ/Ylkp1#Z4bAGunJMWwS$18$F$9E?GWP$u^^E%j6Gq$CeubD6JRuhNAE^a
D^wb$+ m&tm+eaBJlXhy<nit85c>kZjK=NKVG6Z1DGl9VRtW!p4Kec4%\nMK6h1I8JkKPtkCWI9SPbD<6EMEYde
=^aPG% wuWnYqlD<LYGRebX#MkK\85W#5b\%FDGDJJtpBw=FJ1MC^a?*D:DT$4Vqi9!&NBw1#c5cmX\FYtd5QTG
XHWlyw 8K=d!Yl:1RqdCAJjI*=KGV=S><jeL$EVNbbI!wb:S6+1=9#X@Bu$b>$MkD/6/1<9LlKDe>IeRD!ciA@n
d>pCa? ADiGQu?GGBPnNH/Y^MLAmlN=Feu+8HFA8ENPi%*Z#XQyqkJ^^YLD$9MV8yWaDyZTp5ZhEeyjeaJcYh66
udp<mG iLBeX+>p<\X1mjn+GYPqTNP/m9TKHRd?m1cpyRp9a$JWBkFGSFAcn&a+Z+Zj^GkVXDYDC%k#\Xh8W:aC
e6Pu>1 ?bkQCWqtX%GMRu?\DDTPyQ+aKZlRPKSFL</BlPyEJwHT^6JIYbDtp*EVl%eWm*/nwN4TVehp#tm6G#l:
!$pwFZ Au16Jwk6mQG*JB&q>GeEnM=5YhF<#VDV/it%nNCEDVZ\hK&DXhe94w8Mq^/uN/EDBBe=&:M$JJjc6!p%
K+k8Wc JKcIR8<kjBC<K%jy1C#I8R#nJyyQF58Jktqqq1k!ZK:XGq>S4=EyeNVpP5/SJ<hpq6AGa\/+C1>Sm*pk
W54#in qj^Rw=ceGIIacdupFlZKXE9K$a\NhSFyDbbhRF!keY\S#J>wM#ESd$^ce149tEI&WnM\WlapZmL?tHpJ
n!eK@d 9AlK&JbB4%9!aIkqKn1$5cm8Vj!I*8JTD89XRI/\5Sj\8pDXN>RtBi6h>F4liq*:Jt^/ISnWJhP1bI/>
*F=$Su IhIcaY@LDmT^>*LTQ&q%t%dXdaYV^uQqwWMRy49\9m6!Y&1+=GWEXKDKGyk6CEed8PwEXm1w:Fn!p#E/
qT#@Sn &nKPjbNh\S<JWlSk9jk84YVRK?iJqeH!ASje6aLAnRN^X>1YKtCyMNBJ5jP%#V^hnT=5P1y/HhYtDEZM
B?hn!m Zqt\#$9kcqjDnSeEqyl*S1F^Fcli4/ID>LG$EpyTHMckdhGAjS@n^>iWB^t$b#mV:wkenGB1b\L/XqVe
&dGjd# qdb6u@k#&9PlAcd5CMFRB*=N4dcD$l&R=A=A9A99p<SBCP$NT:QFBh5RAAR@=Mt*4$Y9G%!pCJ4RZb^V
V<XJK8 AIZ5d:N8\Bk1@BC8b6a4SqwKG/DZMXp&DaV:adWB8Ijq*T5&#G/*K>8GCC^tcd4NiWFa*5em4ctS+EGN
J4Vpm? *w!d8Ck\<iJ!+YYMT\!V:<KV:TET&FRwMYVeIME+\a+ua%t9M<^#RjMSjl^PRX+E%\C?ni1Bm&Y\^4uW
C+jJ+w 4*8pNLGJ\6=VmaWl55m?Gh&nFccq&!uZ:^kT!qmFD#?ek4LaCm<B\%5#P+4B>Vm$CXCCnaQ<M?KnEt$a
V5Hd4N =wG<M^ntGBepIii^Z&RNtIN^yFh$hPm6pEDEm^CemDVd$eSG<9Tk%1n5$&G8X^^\IbG$aj6YJV$lWp@S
AwPlBl VWqqQ+@n*T/&5?GIVaE#XRKK#cuR$GQ$R^RFEjYl:4hwnm+?P<WFGJQm+kJ6>BlpZINEM@VqiBYKRnRY
/LGBjA <MtbX*lP4Vpt:GRntq##R>$tc1XtSLKX*C&4Nm^kRJy/w4=jM1W8YTMYSL*Lan?Sa^+S8T:J!5YW1imI
8qptdk <peW1mGhBbXn#HEHFGnk>A4VZWN<I<nVk8JB/HJC/RQ/JmSt5NMCqVyDD!e6@E=!jtc5NP9SaMReCSeG
\HQmy5 Rk&\/6t\ECm/EaV=Cm*wetM?qSP%<dn46hS>#SJWjb5Jq+aZ*ji$Tm$%mHlc$!$GXTRuRED:W^RdpSKB
*A&ww5 ykWAnkYe$mDjku16KHBXlQ*XN$pVV5p:i4Y@qZNR*w=u6h4Gi*==Z/@cMP>d$1&a*E@k8FV9BESwPXEd
%!JJPw n^t/tEnnK<=e^\c#D?bDG>uDAK9=lQPep6eiLM?I>Y4^jIJPW@1QQDnKb\/\LtRa?&M#Vc#RN:RwTCXD
b9V^R< TtPt+*1:FFXcn$LDFJXBa^M+G!Q:F%^H>ymR/L?/SVQ5c/=/5t=+1wpp=CKQbdHBuX4Lc\<XlREW\&6L
RY5TL1 9GJWR9AyL!lXGJN&9e?PGj8:KSdA\9=!pp+4M\waydyVS549&lBaFV6#!/BRIh%PDY=>/SXD6dFFp*$P
>j^k8= *l@L9tc%aT>=nSX9SV9FKk\?dXMcqB$!8AW+B4<FJ\N/NRTT$VNnL4lFE#>Bl>%TMnFDhbM9S\RTY1Fp
W^?9Xq !%tk+dRl91!WeAyFthBbYycBK+8qAPYa?Piw:b#6WiBK9Jp!BG?K4=\p4IPwLSMaW!>XJ?:<&RATyQ^&
SY<8bQ mu1e\NA9+I!#$:MC9BIpQ>lTm#=+nhEyR!mSi#>G>+V8GN^c!/X:*Xy4Z%N4yST*XZ+*$5$JTqdKe\Ge
46b4FV 1FZ:V!LiRl+5*=TMKt^\#I^dQmaiEWW48wwGi\4GnL\MRD?dGc5e=X:Aem$:T%lkNc=l\\d<%YDknTL\
RelAPC ZB+$9*lEPS*qQ$cZcTqw%uS61/dZ!<<JKuebh@X*AW!^&D>*^W5?Ic48G91EPR&/66K*XnEK%C?iL/ym
$e=LTN ShIQBlP^RX>MhBVq:+6RmSbqw$%utPQSyB&VF@jw4p4QC=!!R1&:1IlMqXTc/ttJyk^>u6\1EDlwwa+m
PaH\<y LcBL<l=W4XlaTLY!6<Gd?<Kn&InJTpXTFt5niWlp>!<Pa8VKiII9EmLV$Ia9+6P#W<#e#:BX?wAi\dGC
XnP!DB <@DE$+5Dk^5FGH9Fy^jT4YZKKKBkm*81bG8wa+/Z6#n&T*K<NS8<d!CY8ICkV!e\pi$>=+Td5C4yQk%h
AZ$9\F kK^Z#tu*k&hCb$Cm19JhL!BwqR\Q:lN8pnc54mjdlJIkXW51eZdcCc$QiAkEy$Hi1NK<P8!dW5$dTRMW
Ye*WEA >dI@q9%&ZM6WI1dm=J&*MEuZW@i<Da!99ElmMWuE?9k:1E::EV1YVy+VI8bC9IT5M&tq$5yRd&5Se&6T
9jMJ9E ZJRh@tHLJ@j6IEKwtH<lG6$1\%&FHtHDZA^>&HA@5Jk4dYGG+$a8FjFtA8I8!Q^L&SiQ@W$TlWJN#44p
PInuj\ /:M#ZW=Pa:pYWHw/JE=NBdZPX8G^IcwbbA\bFp5ZlMCj$uJuY\<>qH&*a45d>y:P\1&>4NbI6\6&Zp$*
HmqHAj P=ilEXZcRDpBSD<5Waly*/a4PwSTh4k^Q*SBi#jLA<yjT&WMwpm*MuMhWIyZFWE8Lk^$P^TnkJXCydnu
A#aWd1 Xq#WXY\/u%Q19t>5i/y$:\wVX:aLLyW?iWu/EE6=Mk:6y&Qjq+pJc<4XqdJLdbdq>9tA:5DW4hbqHANe
t\a%FQ %>64WppPlpCLG>m$LdVd5N=:AyI%aR?l&G@bX&5WYpIC^BC$\DQkkwDcN^IcHpX%<u\JtQN^l=qCZm??
H8>Qm! &+at:6JEXhiVDCC^:G#a>QictNCcCkcZuTGJ&Y&cLkN>Z+a>Xj1dCh%kIT998u\1F#w68Y9hh4Sd%D*T
bE**4u y+\$bBpN%+ISlZqu6Y+DeyNW6=L8wK+X*\VRD6=JjGEIIeLjTTe=h?ib<$kHy^C\p+b=c1P@cS6nn!#1
uW=Ntt Cl@//Ba&NGZw6C4TQaBL%$GqlWV&tFJ@%TINa/cA##SmPiunnMJYk6C!X\WdN6y#1QBM<??Rq%il#hh%
Y%t?a% #@4yhnw!><a>ZNL?1K%iYuaPEIK*!St^+XjXGuYQJKMtD9YaWu?NYc*NehVyS*G#WChhjXp<dquKd6!K
IuHQA1 /@#hp>JCu!XNW!Y>@j!G+*a5tS9J&dnIXq4FCq#l$5^GG+B6AM5^<!@P>4clmV<*85>H?8S%h#jM66Sj
-AT>c> 0003bda716b00110334 Page 160 of binaries2.zip
+a:KW9 Tc$5KWPR:9qmSATF#m6YK/>H!S%FIlii!tYCj?BiT/aLwyDWhF9AtFdWX8tIP^/%Aqi/:9p?%AA5@c$8
Fk<w+t p6=VjYld%Y$jJCXwXqAG1y*:V^:K919MJ%WyY!+C<PHHQ*WM6iu6p#NX1AcLJacueuZQhGPa:=V*$q*F
%n61yB ?6Rdlw^Y66>&G%S+:^EDDYi$AXk/QWI6tb@DIaYM!EqIat6*\t+aLR6J@#D%11SlV:Flt%d><Qc65QhR
#GZ4mN &?!:NI9K/1W6i<?^$#T=i+1J6E64CLC9QHIwJD\&IMj\pDHb1lATRD/^:Da8$Bc\:1Fn4*VSBwc%Wn>e
j/N<dc Kq$i>:cYhN^pyDaeha$lyV/:Ln#1WDiSlX&F*caL:9cWN:1kKWZY#ld/8%LpR4Kbwe94Vi<Bld^^RhNC
X/J8bV y#8qRt<CdpKR9CyTQ!#XLTZ4\8MiVjjWR<MNSm:W\VZBWpAYAnDDG#u5hLPPC$/+>*R\&&$W:LbChZYh
*H+nq\ uq46c&1XiFu!\#%KjXBH6%6THl1uiE4TR?wlmKKiA\#Ju#:C!*S%#%k!q?+bK#F*YM6V%4T1Wqa/wX11
&#<9Gt eCd16WYFd>%TKQdn\q^w5C!:S?!XuX1%clZCL#@HyC6dh@Ye\QaRHw=%I=N5dZC/aC$nyyk5pIKKNIly
ShAqbl A#6?MHdc<p?lk!BG#InNY6N4CKK!G?Tkjd*1R:wp5FZ/^ByBA@4a^VKK\qM>hbii$V$9SLjFVM^$##6V
C*l!c> L6Fwd&Jp+wj<4C4&hP!l5i6SutyF5+c:n!QyDiR5R@6W^ImMNNTFQm:b>%iYVniwT/<Gh$aG9hKKw=+k
CJLXVu 8FK5^j/au?bTTW5^Ph!kd9cjHb:1TqV$DLPTt!<I8X8KinSW6K:KjL\**N?QV?IVY^:5\&lPVl/hQLKQ
B8*t/C VKX=Y9VI5qdlF&%Ty&tN>@F+dQjyMTEH?\j&BL=Q+hRLT@FDEa:5%DJ5^1d@SdGjna/jlEEPuDhulE&A
yi5+5p NwI:uJ#k<*VIDV\!hBHSWKDncAiC/QaS4mk1JYJQFk<ji@SG@5j!Xi>p*et/p*Wu/$:Yuc\:YZi!:tVh
hdEF8K !d1VhTj4V6ch4D6bh:L8bN*J8yN%J?6P%y&5P%q*58=p*et/p*Wu/$:Yuc\:YZi!:tVh!d1VhTj4V6ch
<P5Tuq 4D6bh:L?LYX6jn!!69j9?<MQ&>X5>F*te#m*GZ//cP+?1#?:?+PV6ja9m6Fq84w>&4K5L+1Db<&DSb*h
j@NQ?h ?<HJt96tXdS=y>jLLF<$6=@X?MeQVqdjnEBY$89!b$Z>I58jNdQ=D%SYj*<P/*W+^#??Rd*P<$Fi4$a@
lCW@jR \QZcFC*<K+wX!uya6#=y$:cw$?!H=+iuT^C1ZhEDI$:#RS*t+AeaZ>PCkm^y5WqC8G%?mLL8MPJP%y&5
<dj/5k @\=qddIj61#N#Q9DP/Qq<pZtj*@R*L4:%I>?&SbjDN4Q5%Xd@N%Ht9w/@YJ=tShj6d<1<taGaP+*kM6l
pYy=JF ?Jijbe@l?Q$d!H4d?*G:G5$9M#>C!HVwS@jcQE5ZjnS+D:I8@J$&?:J8m<Qc4@Lt>8lFY4Rpc?/LV?D+
YKw1## /Gb/ub?8SuYd?c!8@THwFjTbD*M@iB>/@db=$A:9kE^Q=@pK>Zw=#*PThbkZB#iW>ThD*#^hFZWNm^Xi
LQSG\m ul/mQ9M9p>\@jl>/uRPIT*LTc=KnZmE4Ab#?p+MmV$c4G<y/6^q>i:l/kH4%hd5c#NQS/YE!!t9<?jh*
^KiaFJ XphL*>::ey+P96utw!WpJM6tkHy6S9P$8D>QX+Md!QwA4kNLwTY>?nV:Kwh%k4mSj9:h9:=1H<DNq&tP
\w@dEe A$kwIWH4G9tX#=5Qq&q!E%tHy&!wyFie&QedMa:<b#liYV&NL1LlN\@khXw*N:Flu!Rh%G@iQ?S9iAA/
EiB!\Q m8\9nHKHt*c!:tV>m=VF9S?+4Mp4ZNR%He5:eE:bDT@:4<yc@&dku>?=W?S65j\E$LD*!@!#hu<=4?Hq
BVWdMG 51m9BTcc+cn>l!K9Ed8?#L=a#9$>@<Yk*q:uI8*>yS?>!Id\+eiZh&dQ:>#%L?:9#$dN<EH:#>uk8?!V
I5#:jw 6=jXZ&cnPkXb<^pT\^m%q!?#?&pNL:Z@=qwkEYD$M!?!Z1dFTi$j6\BT948P4DXebeRjH8V6:XGN@Q#L
C#=a9L 8!Mp/Q*w<YW&9aG5#h$9u=P5^jaIbIWkZ4jD@BBjc9>khD$V#p>!pjXFM9!&>8M/#/?u%^#\\+k@9Bw$
lHbjJ& 5@^==4<EeDi1@TL*$@GLG?t%ibDMYhd99mJbL*@8p#6j%jBTN/N4w5R<V\aw/\tMMXuCeN9XHM#qY4KC
>BEC^% cX*Tl\>Y#i%pu9qy<#@8ku/j=j/V^>9mSuw6<tW:YKdF+Qut<V$Cu?*n?$e%9MAeHF=V%ny><CpML+e^
YymD*G a8Zk%kyiL/<4/*APiL@PS@QDYd/WR\D/+h4@PF?NdmD4h$Y:cpC^IGYVE5y8AZ!DZlGB\?@Zp^WA?t?Z
6TT9%Y 8MT\p6AtCd^ih:$&^RD^j66tVZ/:ZZu@DS^cbTqiNeud:P%q#W>jH&/CLMhS:h?G?WeXQK<^SipY/VZ>
B^eybp <G1bnjyEAl>/F#GuTX/@VJQnpid6RmWuD=pmiD=&9W8BdZXD+6@!c$YDHWde!jwnqHZ=Dt?@*L5=ejZG
cDqJpJ QN>d!N1<R\:^#8Fdt%Z#ntWh?Yj6<BiA#y/Aj*?AlHl:1&njjHkAH8D5p&H#<e?#n=jb\?Hq\Ni4$Z>w
h8d96$ >:/bb<QFeDAjVlb:@#a4F8T::i9Wn<ak*w8Di@:Z?Yq^eJq?P1njmc!L&u<C5p/\9I+y\FNj6Qu%bG&H
!Ei16i <?eA9+d+DSG&#wi@A>\E5m:#\aj#$c&u1#iYFhInLD>A+kCB8p:8#q>t1=jy:LB?S*1>Q^C>W1HniX:W
bM<Hmj d++p=nqa\idJ=e?LiV1cH#*^KP9yuj@bDn<EYieH\$E:?DC@l1#Lp<FZ4Ne9\Zd9L#jbaJP?/an?81#D
KP%ty$ jNpp>$DY@S#%C1pbRQmuq&<8/&@*&pE:1yjFCen/hJTm4M8nu:Yw%@$&HR=iDIdQB<M*h/ZNp!QYK#+e
/l+Wud PpG>69t:pZWAMHPFil$p:Rw5pGD&9Ve9eM!#id1*&66Ll*5kc*J4:?i\Zu>ju:dD+j\u\*y9<HA=i4le
AZ%66S 9dq@BMHt?Yk+#^n*\+k?tqPP?T=5iP:#nG!+!XcWA8T?<NiRhbpWBc/8PaB>5L4=#G?Gq@<A+K/qc:Za
IctZeJ GPhZd*#Bhyt%KRB>L$pEnAn#p@ch!Jy!qn#M<:iJNQP>aiiq<G5LNn^5Q*4:IBZM@ZL%9D8/jRi!bp4+
alq@ku J<qd^j\8kYn/FFu!>4J&\?lQj9MPbN*l+b&5P%q*5u+QbY&iLQ*w%<6uGhc$q@iHhb9X!&#=QH5QA%%A
?ECC#@ ?J49be5Q@N:Q$>G!HV*dK+a9du?i:m*4$dD>+DGA#l9JP9q6Mdk:4:Mna4G^R?SPM^9X:$QY?Y1bjdRA
5NiydA !JSDHwG!Qp!u\<9bEFKJiRFHl#iX>eqwNL1@dLN=#4K&&YM@tL%+L:JtkFCd+RATy#uJ?tFiDDhQl8*\
FhKP@: e$!b@QKt58+Z>$ab/QY4EVbL4$C9a#?+jjq?bN&C1R/HdT1!*5wH\=iVadMc11#:N=J%tRHRZ4d*n+/R
Q@j/b9 H5:1>9=lYl\5*+?5*<&Y!&L=iR/!D9einydLB*5Q<+@V+aijn+d%LW\tdmV4LX?QpKZ@CwDhN&nDTRPa
dD*51& ?>9*I?5e$+S&%SS65!yT*&D4Wj8VLC?Y^Rw!qDa6dmV4$L?p6:Hh=#ua5CD6>!L4*q>W&\GPLu8#BQnj
$GhGQJ \9:T:E<+Qtt8k:Vj<Xj#%:KQ:B*I85NNP%u@9e6cF#<m9V:kH<uNd6LtlY?LwmFGDF/Lh8WLi9p?!Ny<
H/MuBM >LN=e?88H@4@?HP5P#>+piX%ju>eb:@<=tH&:dA669@$=yHu^Y1ijVw9/45%^ECIYKN9D6QbKM>Z5??F
^DINSE 4E>w6&8#dGb#:\j?G@kndWcQ&?#ie$D@ELjVb9LGN:uM&8KkLjIHPWTH:$DYpW?i+M96:+Y5E$l1@L#N
y&BLpu </JGP9GT>D1ckq=#Q^ntchFeA!tmiC<iF16<?X<HyNjld/cV$ai@G*>9>Fyuch&k4M%hXE*iJKNQRc?=
G9j\W< H\%TAGdZaBbS9L\6S4k>\t>@>6qw$K/KEhL5*\6bb>Vmn*I65S9id#?=X/>Gy@QXcJuiQWC8QT&8whjt
#m:MA$ \jcj$/JPj%iRp6N@dB?M$6<$9<1?D:Liyld@^BjyuLy>c8:#Z/Xb#p%A#VYc8dbb4!!CT5chE*@@8Q=Z
6ZyG^M >KyuICh\9?5iiw66Di%u9R@BqYba5J=>Z&RX^q?Sjy+%%<VbP+!+p*Wu/$:Y9=&5Za9>Y?@&dZPQ&<JY
NBIbX^ XB#&KZnlQE5lqDW4yK=Y<MddjTZ9Y6b<&A^HZ>G?!?j?JB?MSmj=/HjZRn9@>L9B@I6dHm/E:V@D86l?
/V=eLC NFk&k?ZL\jL#B\<jyt@iK*HQu#VDB=eHZ?KP%M5:9&&@YB:Nj#Md%Z=$iGe\1Y<wK:Y?HIG5hhdiju\J
!*GqMw \A=j4lNlt/u@NXKAR!VyQ6kd%MW<!%HY#aPlV\b6@8bL/Jh?D$d#6KE&GN\*pH*=FH=DYee9X$>8Km98
==P5LX <X&kZ8FC5&Y?inBc=pW?9I=it&<?uGe9m#%MFbdyCGZ%KG5:?YCQYQ\*%?8LJa#tM1e&tMVZ!VA@lBRM
qW*FlH bb*u1>FNbeXpJ$Y>jwYnj41/QY1i=y>ec/p<9FWkbj<BV6C!Ltw59T##\dJ?<4@TAj:&=uw>^HTpTWeH
HNGH#R mDlliTX*99J#pnZBQep*q4Xh*b?DuYF*@:iH1^u8@y%i!+cHQy6uhVHe\/565*1b:E&Z!>q!PV#c!?aj
F\VHIF Lh?<V?ViAEeDGen\YiH4FY$?cNIbVB/Pc4m<5c!RALRykiKm\a*VVi:Vc#Eu\^RG5=eNL?E?:S+jk&Gq
nB*RZT Y>qe??a&@FtBw<EiJJn5y*/Lt\@c9IB<lGwA^e%qXjWeFykSZD<a#@iK\=>l^DtA#^@\5XQ+%mD&=4H5
L&Vm>K wa+GN/he48:+/&+@@nhp:SyZKR=t:^Q+l*TEB5GdD*c+cTj4V6d9@hjwZe9/QZ/+##8Zhd:$\&WK5PiL
8P:=L* 6un1@W<iFyjL:MQ:ddG<@%+/abCyctb%uc+tH*/B9Bj&TcTDYh*An#eS@/@IPu&bF6@CSZCD:THPbZ/u
&/51l< tR$&/iy8?@K>!Aw#*D!y&*SXDPmlw*6yehwtV?1Z>A!mG<tcdbLlTdQ<=SMAJ!uJ?lkEd@Q<j4==d*1h
pa*yJ< %JeyyCCa/dRu!jD*:YwCi9*!1^9K/q>t!dj#LBql+#p?nGR$bqqZ<&j9Shd6eNk?1d@Dl<tm4KDQ=HRD
uuXcm* iwWp+Pmt5t/#\T@1>MF>bQt^>*>$tBdDia6:j>@LI^i?!>yp8N!t<6DS@Y$^#J?6/Hp@<@!G5u/ZWXIe
^M?IH$ 69wmc#JaNSpiiB?!ZtbaT&9dA9C?>:>@kPPd=@eLTALc%N>W4/<pLDS%I>??F@8q>Zyu&e\<?mbKqnIe
!X\Y%M *#b=</#44<u/K4LtB?yp:=H+^:ajVAA+A>Fh\>p:pZYHEZi!:tV>ee1KD/SI&yd+?6aZ#i1c6NZjZ6dq
DZ@k\+ @XG>kWHNj*P9ymj5jDJ9S9@:ddwequ=iHNd!QHp@jn:HBwZ4jMHbu*ke\uV:5:V+^YQj*Fyt9@RHk>yQ
wPNdd+ </dAS^KqN=IXewpcMkD@%NeAFL?F!/b%Y:V@4:*4?Y$ml<Jt&/=>M%1lyVhYYm4&Sk>Ai!MRchNdI4Rm
V>cR*M 9dYHZbWdyp$a*?#TBQ9tj>Wyuhw*:*8VwV>&F*WtE^aRM+1W%FYe>@t>5b@H**69Ac^MYZjw!#wB/YA4
P>+8VC 9XPlL6blhFPj4I*Y8GpKHHPP8wk6+S=8WN+$^Py>DqlH!a>kI?BB4!jiL5AmCNV%?Bk<&HTTJW^KqQL8
-AbK?# 00099db787400110334 Page 161 of binaries2.zip
8kB\Bj 5:yaD\It?Tu!yFmKajP>4hp4C%bm\?9yP?uiN5I/5R^<ddBl1#@ASkD$KunE#J1%5aK@#k<>:I<\^:yD
yRZa9X *h\w&9X4c6%/\mR@MNVY9kwa8<q*MX6RP4CBb?C4m$baV#Jd/FXp>k\*AwdKecCL5EQen4PFZ9G&5MQ+
?l=$$M TG*Z&#?ebGymGNaYGEq4l^l@LN*EFGq@6HSY!B9q85tGbV!h&#A/&nE1EhRmiX6QqXa&wF+6Y8MCdmb<
p:TSIy !/k!!W>RIBQaMC>d5mIPwBujH\!H=aXi4T$*Ak68eQI$VqLtiNLeBbEYPGCiYHQFT9C&aHZDn&<+X<>T
&M%MWQ \G\<+HX@Tc:@S<j@?1ap1*8$*9yN*#9Y!Xeyj%n>HFnba4LAFKpeuw>G#N*\Z$!abutd^SKiT+VdSEZ!
X/6Hka MLCpX!KZ^Gumjny>?mVeypI^Z*YE>KAQ1:ItuJ*#&?wcE!bu$F!LCXN8I+l&bFPTVilaPN>jAqat1VC:
lyD4/8 <Xbka%m6LS%I8nH4Q@P>a$#qWuE$ackamMTTa4pDWPRKE?d<Zq$t#Q^cQdpX1Z=:6+PD1QVhJYCqcWXd
DPa@1$ /:Xp%uIR?WqmL<@eE%l1EY6Fd\AWtaFIAJFF/PRcE&dtTE$tVCqa%BkZ8nJA4Kt:5^T58>w!eac$FSCV
pnKJTh hlLd?NB@J4d*lX19kVX=\$A+Ik\4tVDaaKp?i\DNVG#Z*CJCq=kNMnPaukdHdCqa:@6X8lEy&bheh?BF
Ht#CCZ B=1^8IcSyl%iXRpJZFk/Jw/SKXH@a5K+Yp!ac%lZX&HMCH^TT<AK>=yXBkPHI6Jj4MS+W#iQNNXXb:<j
H>*G@G JW^G:tIt@*CFCSQ*LqSj!+bl65SEP6J=b:S^eRqaCZFZLjH/Nc:/A/C/*JTi4Lyp\tD<i*$tVDqPj=a#
>Empiu N^nMhDt?^FX*e+F>!Yh$H/#//BdZp/9%EX85LhaYc+8%^hymddG&YF85LhaYc+8%^hym@R/^qp?YQq@@
MeI/Pu #%$n4C+tJ#PyauAyC!+LBkp:YAAuyw<QRcyiaeu$uu>GI5l1ARCj\lwic5h:i1diFBS5jnRS%1WinRhh
bL+ayN H!8!R*^S/M4QyQqlJ+YXdw@*b1yuwT*ih#%<e&8VR&XqnXkF$i$qLyB9mlX?Zm4>TL1nTHyN5Ma>=mn*
!Qmk?Z =?w6$yJHY!PdHM&+?iBG*qjN++^a^@=eF5GyYB%5/%\>RK#9p>6C4McJ9CJb@$KFAmMSXNG>nZ6ajt#p
\ln8ce E&&pX?5+6&TtNMXmXcMnGLu8i\\1PQT?+4uCDLEiwq/j=kwnE%C9R<S/dE8>h9Yy5wh%>IwEAnYda^$m
h5M>F1 J^@$K6NYI/\9qPX:@6!N<XE8>%MWEWjTVZ&8V14y6h9DK4^Stn=Yi?JFdY8LHWqDC%N&Giy%ZE89TJaw
$@GamV >C4WNtBF9YK=8!a&4AHli=b9HPL>&w@9+mQqS+u6@jnCl!h:FY*aS:1NkSh5W1mE:+kl%@aXF91/I>uE
*uJm8& K1bQl/?E4cuZPYPha9\B/JYhuNqtN5!T9$l=1X*AR=j+Y>FR8WTFV%FcF$<#XhB^pKh9pcBVSBFp=1J5
1u>9ql YK^B4yFFEC!cChlFWZaa8V/t$bwVl8Y1PE@\Z^^?#\61!d\!X15BXy:QJdGY>b59N<LmZIF/FdW4nH%P
XSa@P* Z/Lp==hHEXt&nEnlWJ!<qFWH%NiD>X9%ESj&jIL:%4CGldQA^j@FdndZt&QFk%!H^EcKl<+aeXYQTknV
5k###& MDWBe!FHl#XXM8hk6k9+GSV8t1Y@8TKt4bLB<KceC\=XTn4tX5hRd%dJWT&Gnq<n<R/S@I?$M/N/\Mp9
LXppye R\w?RPV:A^=bwH1jHuheyT+DaX!5*NQ5AW$Ddcli+e#9Jaau#6=%6EN1WuP5kWjKI1Zi<nC86Y=Mph4k
Vu?FkI 6@un6Puh4=G9?T$KQ$pM\&JJaC!TA8JKYIZSZI<+E:D@wIn%LahPp4a/A<GRdDIh9Y/GqdB+N@J+q!LY
dmXn?D KTEu>dcmEpp?qn>HC6eh&C*yHp$kcpan%!KnktY$I6d>JQpL?Nd^Fy&>SkdMqLM#q\RnARS:/w?bQhy4
14eXkq l6ZwDLRkD6mI4mBSb@T\*5!*E#Fjm*:\q*C@S#+bkX+V$+pJnl\9JQ%IV1yM%i8J<I*I4imBP6<aKw<K
1%RBZ\ 9b+>BePaYa+bhcaQG>1\N+#46eBI^pnTVNi/Z:WKpc%F#ub@H6DHpa8mF6$/k+=AW5y!+kSS4Mwpn^:%
dhRDpy L8lXG$LJ91Gm$!eDtDayDjAu9FdJcWP>Zmd#u!<:ic*qWy9NewtXbhyt:EZ#emq!6aaNHiB=hT\yuCqT
tZ>jDp *pQ::V/?T\u@Qt8t%%#dK^=!1y8Iaj:AwEm*FC=:\jHC6nC5$>ZcFXQ*q^8djXj=5hc*+!QKc@Y6%PZH
XReP9p V#/Gc9*lFt8L6eZcat&^6qld4C*YFt8L6eZcat&^6qld4C*YL+H%i:4?BqBLA\RWAAIACAALXt$qLGBC
E:mAM# S8a5AACYYRIAK\AAAGN5cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>netXpcZS#PGJyhC=mdZD5uZ?M
A#T?MY HeX>\L>WlIi#S\L$kbT?lheECmRFA8cBTdY1&w4k/=A6IWB6N/JJ1nT\WG1\\Jmwj#C4N9FiTDRdN+Hu
&i$QPM jetSlSSDi!qJ<Mm51WVWBy5Ki6uEySaq1XTl&1qcc/ZSFSCY46@b*@9i8@MBN6nu:>j*+<*8:M!>?e#*
5%kn$j P>@9h&ijj<@?=4yjAT%ZuAl\Aj=?<RTA1@D:BDk=Qj:bG:Q#1b!Rj/h!Z@wF>>&Z@hL@>CH<eiIKA!bP
$cWLa* >YDm!%N\\:tQ\GdQk@ab8?G>:Wp+jZI#VHm:+cT44+GLd6\MX>&@B?/@@=@k>J6&\eV%n$L99E@A%*j6
!p*dZ8 lS5*Q\AVP&KauJ!E*wpDPP*ZdwHLd6kN8=>:Dp/j&kiuu:pNVqu6\MYuuRiZZI89:>kGE#N@C=he6^<t
Aq&@n5 j:RjXq\$Ci@#<Nl6t?HEL>\KJ:e9AQ?u??DC1V%\#Xi*\We*Q\d98@\YcLhjkjj?^phk\#@?HD+<iVNM
HTt8I@ ZPHDyi8*\Vt>%YCi9\&??eRPmHj>Et+Vn<QK>Z6l=1Z><K8Z:wIQ*jAwuLd^Bbna?h@\wV>:DNm/t&H6
IGGyc5 H*<J*n@bl>=ZZ+e#Qm^l>Reikh+>??HT/ijk?>@cC&jhMkW4d@hk#!89RH6!E%^!!Y:+%J@iBlMQdRNn
Ydw>>: =X1+aQNVeNc1ndD8<^It\q*RNc?De<::CJ#XPR?8*9A*eNdb><AZj9aGjQVn%<D1=\@C&d$6$H9pDdk6
bJlkGQ jBb/P\@CKce?CQh@?%FajhM@\::>??H>b//FW/:jDm9P8BKiPHAR&uj@HPT#8?Hn/=/Am?@eAZeM6wHn
uy$ClT PDB^b\TjuI=katwu5A&d+Y9du+QLL9<iZHd%VlD:5N*iJunm?#?Ae?@?MdVZ>tFmjS@8??\#5G9HK>D4
dIWcA< *Rt>9^#k::?GXW??BL%X4<G1Y#dB&w9@Dt:c=MFhZ@wKu89By&cil%5*QkpQ@j%@ku@*d9n<d@<R%u@^
Balm>8 4?DJue@C^A59\IWZ@lj<@4WC#9*Mn:H?hjDT!!@Dd=pjk@@ai\Aij9m:eMyD?&DmY\P++cwH+iw@^*F@
ClD*c1 eS@eheQV5PEZB?HKj#pI$#8ilWu4Cdn&@D6l5ue@VQ:\F*Cm$RH^nRjl=K9@CG=e5\=/u#+I^5**\uq5
Bj6E1F I#\Y9\:6K@dAXXj>Bi#/u%jl$yX:+Z>@?Z>\5*MZ4Queh&D6llB8u>!P<*aQuQcXQhD?#B=+j&enZQau
K*JYKb L<L>@@+1jHKLlBZuj\\?8Gw6QQ@</>C:/!BeHP/Fqb8&\4Y*daTJl@jA=b>aB:j@+Hta&9wWjP?FF?GP
qiydtB :$d\%NNQ\#%ji\D?aibq?ED*!>Bi5^p888+d$D=#P=#$l:jC^JMSZQK=@jCdc&?G>yZdwQ$:8?Cec!Ye
Lb:u%^ 5*+H6Fh6l/:Vl%QZ*A5Z@i=8tQn&Vqn=\FQ\/^hhCbP*dIj4@?$ktB><EFdj8lYij9wk9PiMDy!$=6Q\
9b@Ztn up%jlI9Z*R9&8u9kJ/<ilDjiiAM&dL\ZijjlP%M@kY9P@kQ+/e@?FXb%L+R%Q*wFuuutGhVw?jRL=8i#
Mj1ZSj Z@1jQ1S@pC^QMWtYuSBZ+pyCZEtIK\q^JTG8^QY\mbl#jS4W=ejXaKJQk*y5e^ZeNNpY*$=jtHbwetGG
=ucNT5 5T%%Yjtt/QLa+qp>a+64G:b4t::465&atTcQVVN$Zc\=b>8/6ek%YS!c$#HYC4hki&#cndiEyledDK6l
\?!Gj& &<LCtuliMHic\B%B4w:k48XJM>bkHGG1tCXeJYc5#D+*He+aq*nGXcb6M+PbWeL:IjPaSC#>^MjK#PBJ
YINlFG JBLhty9+aYKdqt9MCV#CyIe9yVJX\5Ppd&/^9YScTTaF6mRakV6!ZJpM4ERaD18+iw=yTM$XFVZ\VhZZ
Ak&NAV b*VSXZaW#qtS6G*dh#!VB:d!E>6YTq?BtNmeLbS6GWqpmqnkhJCSFPtqiIX\DcZ\wB>ETc^5wubp%%hZ
XKiIAT GItBHFND/4kM>XWcEi14c\cl/Zmwm:ycHKDKiu$l8epe%E+9EYbki*N?\uqjJKm!YIt:jn@^*Cm\5VJi
J\*4X* !B\9mHG!SJIFAdPFdWeJE++uSTlJY+<5X?:cjdP\\=bqw!dbq88a68MGlpm5MIkFuqFBHF1^!*DqbMJ%
Rq#\pH FeP1!N*!qY6^LFkcqK*MIDCXmALZamK\PE+LGW6l8&b5tWIybdya$>RNELWn!=XJ%L!CK#MbR#+i$+aZ
m^mZua F%MtR=N=tYylTWe@uwEPM*/#6CdLC1duP%tJbVZVc=klQZ!b6/^@/LanJ:?G=InGPY&ZyX^#DSL=!yiX
Q%$M%R @cYcT&?eaWY@1Y^Jm>K9@IBM<D5Y9@1qC4F<%N?5TupLH1^cT66tHkE:@F^VA?tHXR=CSDS?!+B4Z!MN
t6@5^J ?:\!nim^916C<?y6eQW=?n\etX1Cw%pWqtqPM>NA6<dHtAW6yY?aBp>NeMmuK$85L&E<Tk<#M&IbB<QZ
pC<<%# bZ*cM/i>6JnYSJ<KZ$>4#$1*+S5ew!LP<:P/CX!98a@uwlC:C<%IVDNHt?qyjWZYIcM<%JK=YuKL#aK+
BIBS/K 4$#LeZEk+<VA\NXWe/adYEtEup&k#DtZyjG5TAMdXPZaNN^?dEc^I<!+::1iSKb?+y6!#4T:C1>*IyaE
\DJCSF &J1JF%6#VDeb/A4y^DEpF*HjF%&d#dq>G&84TIb&dCit4!Qa68$LIj&+nZ$FpRy$l>ce+BaBZTJZu1C9
tIMQQV Eka+uM\Ty6SSypm=Yy:$w5T*W//Pu:4DGGc/S5+X+RVyye#^YbIyaiL^^GWP>**6/ZLH<1\kRuiaJS\u
Qph8tw SF6cK9YE+>kKVKaT^t^ZTIS5PKmnTSknZJQQtZHkw+*\JW?h1a!4#SPMpTkGYm4ZPS&:wA4yjC$*LV8!
\aNT#6 iK\#954%HS^4Z?84dY1C=t6KMW?JRq?6RIcia#tG51^5HjcT!I%hR>y&wQMR5SC84i\wMM%E^DwVuKSe
aJtP@b ZDhMBHNe#=C^wS#5YteiYSI!EW5#6NBRKE9bVtacC1:CIbl9k1848S1P#95+Fpi>5uFXe^&8AlaIP<E^
Yad/D= =atIyNLyCGSqqF^FEEq8I!I@pnL#6Z!yanTXqqC^d:tS+!E@NL%ahw^aN+thcBMSS:l8J/nXTil=Wmkp
%+J8lQ Gahi\lpZAdMh:BNuX?DtAZLk1$SampqFh*:jnB%Pw=5a\ZH8eqN+/QFER1D*+1QC/iTk\E4/%y6Thw#t
Cbyt+m YceVWIZ%mlimhbXiEQ1bL9qJE1G/GddNRy\pAt&6b\4DmG$Q*TCpc!165C!\LE$ZP+9%jVwdZTw:b6\\
thEmaX eD/\GCiJ\D@E^^tY/&5pFL:&<:YhbEq?p#6un^89mNh#T:ct!YIEK:LJaJ8?k>cYP*F5^tl<e#8MS*LZ
-AB\V^ 0004c85821900110334 Page 162 of binaries2.zip
VTKHeL Sw\&1tV?\p:G>Tm!yIR*jD5uwGnuLeW=$hn$A<<#jA*wIe>Nwijy?MnR?JpPX@I$eYSpmiL^Iky9%lnZ
&LhS+I Ia5Z8NKu*PIS!TPTEFiTa+=41Cl+ZHbeI?Wp=L+5P/=#TbJRpLH58L1INcclZGbeDc&66Eh\8ZFqAYIN
%b/H<\ cCCZG%h6lBQcu:Le8FwcK#qN!+%411$w6Kh*YZE65CbJt+d!YPZ1l$K=ZhePm$R:/!cXeB4La=A4E*M!
DV=PXB ^Yh^NpbdWYm:\4HHqh6PB5?6J\6X$lBT&GPM1<mlN1tchlN4a1X/*Va!>a+KQXew:jLYcbkY!:*q9tm4
aA+j:S h1%5bPY1YD^B$M/4q^6J&:Y@JY6FNQ8ImP8mFd^?#p*!BX!tRqKm$6ZQV4%Y*AZ\8yb48dLaCeFm1?6c
Ib=pTK RVJhN8IEMyCJWe/X6F#$^JN<R4DE%5$/bWXYV%^&<T1<4Ln1Nh&qp^DZSbY%wPa&d<QbI%mVXP8mSDyT
?X:qRe D1YLShLa$^AX8E\4*TAVq8Y+tdnmbeJDJBLd4iJpw=/=HQjaRWleF?Nc41F1kiM%WdpKlu+kT:&!LSTu
jFqnkX hK1Em<YkXL65A&yW*8Md+qwBN\MbSaqd?ZF%4ybEBc&5mW4:pMS%phMNZX\ec#:TZ5K>/q=5tMRC^TnX
XPW4ZG #FJaLGpXZA?y4^y^tBkLeLW+=>W=*cWTHuE>JFe=lJZuyqp&8PdcyB#L1tpeN=ll5JK4$1YT\b#qw+lK
t1Yi>4 Z^*j>@^!J%yNZ^F=bY+NI$ym4&\%eD&W1HlcW*jJDEbeD<W%<Mb1c/\*BNipGHc4S5MI>HL4qEa!^uXT
StLKPd P6ZV!u4XqLLWWm:%/ZLuKJjXk%R5eEyWnq:CbdHlZ:iCMqj$/1bFVq\ZeacVMZh4e1#/&ZF@%A/QbDRa
nuI^=8 a+8Whap6W4%?1upSc=V4X#GVHjh:V^jq/n6nEk/=Ee=5y^4^t$mPi1=en5FX1Gmt^E^T\8qa+=4y+5lY
nkBiV6 mEnYIebDiaqFbAYN>6HAqThDm?5K@dGYYtPD&nc%Mt<^PkFGPQyS=Dij8tAS!yL&HS6apb=GQ\^ew&S+
nIi\=G J\SVVmIDyb%em%YBVGN=DT&*Y#J**Y/XyR4n#GSLT&\4bp/Yw5\@=wjnyaWX$M*WH5hlI5l1^tZA=YGN
?##!G> Kp%l^t:%AdtGc*Y6+@&nMSjmcnnDTtkEbbn1G<Q+Wj^TjXp6TQJG:ZW^X$VVkHi4ENl$G8=%t1K&qK19
S\A/Np >qG>I+^bc:tV8BbME>eleWh<ZHi5j^R&d8ip4GR>?M%uRJbPhuqp?L^+VnYhPT1M<1K5L5$tT#tlbD+Z
=#T:6a 9KD1Qc4Z!LwKc&ipRX#Heh&TDK?8$?MZ$qLyw1ywn8l4i+#DHDZNjFS4ShXib@wZX*Y<Mjyc=?1M!Z5T
BiM9jt %/b%DeaAdD1?hpNhG%#VGMm4$qb1nF>tDLW9<w^XndqZa?!Y>uqBjSWJdXNjpK5%tpK1bTD16/##SXh/
CbtF!N FS$=54/KG9pt%=4uW?YaYcN#XhQM5N^\5=C?GpW1nLmPelXDH5:C?8wQwS:SX/N+Id$^ZG8jiIq%Ayph
1@>w:p +Ny4VyJ?NeeKL<kw@/kF>DX>?5Am4PP=#w&=QiiNZX@XpF/Q%Xh@4IQc%Fjh9G%uE\S@YcJWS%t@8L!@
L?Hant 5IC?1tF:Rq#NMdFLMWKiG8<QG@um!lyel>hZQ8\$4Snq1m@$idaQGc>Vj6G:$XmcT<lNjT*mHJ@!%I6\
?bSDtF 6ahV9yHEMYd^cHy@4y=aYNAjdyjl:eL/c89=+KY4eJR!Kuy1wmwj<l1!\#LnPpiS/!Je=hA6Gl%A/5HW
<%P!MW Yb>AnKac@cFXtA*yc\E:hqH$y@/Ew%!#*KVWF/6$Ydd1BqjWHVyuRV55qyKtQt/=ipN:S:NEW=^?5HM#
G5&YIT 8=8Gmw*QV^J%#wY?1p!uYZP/<DwbI#5c/=>Y&1?hG@Tt9qwNjT$uXD1FwuSC$q&qldnYQF?NJe<ww1ac
I^#@VZ +*JTVihV%K^*R%?%p8ppj%VtnHk>NeY#=SS4YnqmWZi/&uW:dJXe\+c?<uRBwR@VY+l48:t*^W4GSD$q
C@=TcX \<AaQYaQ/Y5nwwpLl/lll?QMkKKypCJ:/Sj<G@=&$9Cd%JAh%nPJa6iF8Dc&Bk64iF>ce*Fqa%k:6ZZc
Z\@JJL G@b^*GIJ4NM&C9PKq<m5J%b\C&yh5=Jt&tc%+!uZ*uBM@wP+NnI@I^KQ%i1^Nq^WGYY9RPNXK&R\+k@#
&>=:PZ Rmjnc9&%epS^LYV&!%W%ckba>jmXQ5Lp#ZAh?5>RmpX+HFjyXDpLw#nKK+%VI%^XMSqE=YDdTbq>Ky%e
ppumtl Wi1n=m4hyJ<>6Fuhy*Qy/jtF8I:h>D*pn/n^6DQnKlLL#%N/5wVyqntQ+n=/#Y?cK^bh9&1W==&tZ4iw
T16wZJ HHBic1:$6cXQh/*Kkt9cK+E>qD<<jqPcWT!/\^9GjV9Fkp4n^p:N+SGqqqybW+d9b!p@*@iu@cmcIWFy
E6R\yD TLWVqAIK!@8yeZqu\M>m+6JN1:^nu:dRLeA%P6VmGlYQ&A%9GM?9#P/En>^D6R$#euM\w:di1m1KemY&
%w^ma> T?MRlKclT5B=RwTq#u1el%Sl#bV+^HYEK^9FYk>TnbKJ#edPCFuX1R!mpw%dj?+CV@hpiiLTL<@>yVAw
=A=c@V ==hS<<X%45QN=q\6ttXyVw4&T!!YH^:F1ni9baN1n#:bqG+9nFI5uwynXc@BR1E@M#+@bESS1qhlXEnS
%uh$=4 SZ=>*qw=a+V6^wy:w^*=/TiQ%:MWT>@piJ^^HVHEJS>Y4L&Bi69lj!Qj>DcF$h/ZJZAh6yJFmBJ8Ta&y
QLV%Rj Fa9D5Z#^MYHTY^bJZJjA%bCn#!8dBlhK<Mk:ZHp/QmbMi56C?4wW4k&FQXJ=8ePy4&THq<T%:nnJI@Zk
PeP\>W 6?EiSn85mP8l8cy*A18bQ1>*&G/?iC=^jVQ=ymM/YP^\dpXT^HXl4m8G$5P$B&!=/G8%6ka&@Wjd!+b4
6MRZap dwTq1?k#\JeSX=Em=eS$iZENa?:S@1Dqt=ekIc+p^JYE8JIRX=J*n!6>LNe:#ZYibNpJeTY8JMTXlLmT
u$*K/$ EFeT+pyeTak4CZEqIc+p^JYE8BJZE8JKRq^JmC5JeTWl45TXlLmTEFeT+pyCZEtIK*EqIc+p^JYE8JIR
<ZKudE X^LmTq^JmC5JeTWl4mVEqaT+EqeT+pyCZEtIK\q^JTG8^JYE8JIe8%#ZP#S/!+@4aG84M/N@>R:M6%44
/PwjpL P@QaTteYV:ScYd9#5:&bnn/BZ:N+?pDuAI*&We@X$SjNDDVN4h%Yc#dn&1%#:R#tP@4EdIwYb8e:/&t+
tm\8!C n*c8A>VX?hpD*a+G&Yy%^?k4ap^QbF>RumE=m4utnL1>?jtyXttH6WK&il%6wEFVVp>pK18=V6F\H!Ne
Z\jtA< $hIPip=tl\@MkyPjce$W?n4dc:XkwM5#YJGG?/ljZ*6cY^HlwPWkQte\**Jc/jw=lRhV8#6\=48##tDR
ESZ6ZN \n4aV:e%T/N>>Q9DB#1#k%/*WN=8=i8&P1%YL*Ywt9*RWB<d<T6/\aXh:cJtXy4e:i4Ihqk=TXtQqd\E
1KHcF4 CZEqIc+p^JZpuiDc:hJ+H56e%*jTZ+P6uXb996NyRbbBuJuyVM%*6*dT@FKStMD#9V=GSSn/bPZqL@4h
m^5H*C a:\?/M#w+buC>+^HBq6:Lj*&B=*=^>PMc/iVy6N%TW6cuPyp>V6V:\4Zd5aX@=CbX4e*Q\6bBlF!tAh$
*tYcp^ X4lIJA+G?Fbt1@J^\FXQ?=tYj49+<*H>u9Q<iDh:tZLXI*Gk+n1XF9GT6Q:n:+/?#8d/&t8qN?Lte*&h
<CKZ8P %c>Au/:4/&CtN>B9w4Q?iNFZXMub4iu\FF^^SH4/:pmt8w@@j*6je?a+4uQNHVihASbIktqMIF\yD&XR
HG#RhG ilkB=#IYb1LX6?iHA%CT!?Y?6>>81i\bp%QnqtXXmeaS?IPjA^WG*CWH49cY$qN^bWhWQq4p1jkPab>b
?Aw!*1 BhjacypP@jTWI95C:Z+ZjYXZuMknV9ZANadK1#>\4c9@m%Z\YWdkJJ1hYMZ+VF\BY\*!ZE/:9p+d44:\
51!*&% pmcZhPcX\$ye%lb1/8@jau=NRhXY^MPbjcl4/R/TAHuqYR=4+LLyc\^^\66w%?QqPj1/&G^cjYySpQI&
dHp@JD D69J=K6MIuAHJJdQ>cIYwcn&@m*YVVNtKu##qFMjeCGS!n=/iEk1SGLCkG/K?QC&lmLZ%$qiuwP4VBcj
?k8l\& w%1Pejl&Au:Vlt?@L9%N9y6:?H+t!6/9t:l$*bVT5<blii:8614d8*4*@n$d9u*hue$eH+y1j%@=5$?E
!@Py/l V*FVD*9V5E8MNuAh:b%\VbTG!Q@J8Q:WBSA8Z:G<^JL+X>a?5ebZ\6WSnQnNW!uF1!%dj8aFl9*NwARV
WecCKq YmH=l*!\GLckLwK%SZil/GZ@ldlZhG<#&tl@cI1EutRLlbZ?\/=Dq+ZtJJK9*<!8FMN^b!ISm5l6SjB%
ET#LLj K?VqQ%!q9lL4N//c#8ncd?A1@!<V@kuVlt9c4ItGK!:^?y+5FWCQ%Qbh!uY+:q$yh:nCRP$*S+yb*HP:
$\14+! dE4RZAk%>RyGQ++::=$IGn>Qm8*i1h$*an@Q\VWXQG:I+DBl1tG@d941m%&uq8?J6mNN?wkZD5Re%TD6
qA9JmG 4Xe*8LJw<4\:!NSPt*hd!9u1CyMN#*c:t#8LIky+K4itTVC6Y+5#DuaS$mpbL:?HK*I#QnnWHXhBMu!E
XPKc:X 41@cSZI6V6#%Xa@\d&n4yT5u$hjCp#=\lm6RZqLnchjZ%VP:K<jl#eBpk?>^b%HlC4qX%XiC8ZZSn>SZ
t<HlYL wmJpG+Tj11<qlR?jc%t1QH1lytW*:G<JG&d=Xu*XI<i4N?Q!qWN^TCLIW1wc#@*KwnIeZSY==TKT>K\Y
/5LkTy >*^hG6mPK$#>@e=1/1hJeC!4!G*VX%^XYDwye6N?E>XRylM!I*+QX*SKDj\/E6<d>t&5LYd=66Rh6aG:
KYZHCX qCK<BNjmcw=5<tw<6*G+Y9<<%<VJLP+Z/88YC=Hb:Q8+5=4/1$:?!SIjdLV&/JTh&pWa#<mM?A%ebhTq
\\%BeA @:WkFQZ6#/QqZP%Q^MX6$^XQ$h*m?1Xh8S:&^EtZ*F@*Q#iCK?8SMjEK?=\9S9>HK^n9?hlVjtP5j>^8
&yw>tn Y?%RZ^=%6%/=%/&cC%H@^\a:HSpV\+++&5B%+D4c\QW*&p19thKeRk+9+ak+Q=:9i@T%qyjE6Zli\4jj
4Vy4k^ NhdZ^lY@N/pl8/kX4PeBiH<Vb64tkA%Q88LbTXpF=LGjKDtZ^mGZuGLI1?^hKV8<XDMR=Qkj/YpPlYC9
Z1ZMeL !F+8>dpt=$yY4b$+u/?+H$F*5>ne=MMyMlMMaMmVwAVdp9TTjcCF#\l4Pk6Z&=$G%m:Znt5>9ABtlbi>
?BCLNk &kZYmB/PCX^>Vmq:Cq\!!#FiZby##MWMQ#+pwybLe5RC6b#IXS+BPSF!p*MG>?pNltAVS>/#YCASESk5
EM>K>d mkw&ZCL51b8KZ$ljX#mm6M9eeiWn*N?5<C%eai/98ck6B<bZ\9@b!#uBFc>El1m>W9F!wnnSm//9tRw$
XJiF?d Xu/d<Ye<=\6&&iDGee!j>FZ6l#/%bjX=h>@kp@\!8H1%QQGH&hp6@6VHG=jVD%nlPZBc&\W4J<+L8RBh
W<m*X4 dWWit:C/XiN%e=6EG$NnH#hee!ZBNjpccJLLM?^/Q:L?y8I1$5<ZnCn!NLNqwS&+dta8=9RbX@e!8Fbt
Y<Q!LD NdGu41@VMnF/#?=9DjijAl\CewtMS^iRN!ZS9AV>DDK+lwAnCq%jy=4J8Vt4wT:L$?eI</8whJZLBW<Z
K&9tT$ RtB!<k6NZ9X$Ql@aA5@9JA1k&R//>6:5@eHLwkMu=TjKQLH/F=6j%Yy>M\:ZKcbyD@e*T*#V9IDV>XYH
VIZu59 $R1Ywck&8TRLJHp9:/Kc$YW/^VCS\>\wcE>^JZhHShVJ#^?uL%ncqTA>TjWRS@P4neNkS>4N@F!:tF+F
-AAp#? 00044d7075200110334 Page 163 of binaries2.zip
MEH#=B %=+!&a=^PKZ9&lHYuHM8>?e?VbMYE=FFQ?j<qB!E<HYDS::/^*&l%<BXJhlZpYb9q+G=e9\&G$TX8#*5
=RIG/: %Jj45Gupb?D/KHk@@T^N1d+G41P>8^%^6IH4cAQZ$Rc8A>hjdBQJ@nDC5ER\9:Ki\FIh%nNcP?8EB6eu
DZGt>D X^b?E+Fm>+ZRKk=b9:u54>RVAZ8J@dC/JLJ9@!E+J8CNCNFquQF!iVSL=>N\4hI4BH9Dk8$5HLcFnXt/
dpNjuF hR9^4KRbaAB/F%\=?:1/&l^XelF5&&9*SG!+Et^\5F81K<K<EXZi\tw>y>A>E$@DqTuCuP@cWw!bm=$q
b%WPbw ul!+Y8T/k@GC*wYwF6dNFn\MJFW>C?1baPlq^#ZDF^I:4l:imIYt:tZC^W@ZX#APmcy!4IylJa6uXl>P
HmbYMl :dnKmPVkl%#iS%<FTyFEX6IRijZJQE\:4w+<9A$d481N1Iy4!4G6khW#<WS>Sh:G/4wFi$pVhWhhWYyy
c8F!F5 P:h\teE/>Vdn5Dy!+SVMJIP5?lVME\G9lDMHqJ^6YV+yM4jCY=Fu!5A+luB+Jy/Gc%nkmZKdBV6lw4%J
YKZ/F4 +*A+%:4^Q:%N<S!&AZk#F<Iyay/I/lp95XMjiW%8!4K&^IXFukGEZGPk/=/Jy?H1%E%<@Dd@Q@6Z^?F:
pu&V56 l9?*tX@XG@HLF9\6YbQylDu%yQ&4IuWdlNYH&5mcEuDHZ9M&P<hH*wlj?<Z+G4mPN8^Nw\%eS*584l>l
9QCwX6 FBL<h?44=!DDJ>Q:k#lW#bkJkWJy!^VGJ*4c>l\^*S\NZQi>DZnwZYitciEHKE%Y%:X*ya%\lYmt%LpT
%6:&ym Jt?&j#KCi@MEZNDIc==\<VY5GqkWR%I@lP&^e9PqW6L\/?%w+Lw6^ep5D54mD+8Vpy:4H\Ba99R1pkT!
W%%^:c G#MQW@X:wXCEw!b@Ea$6LB<JBM:N@!%*YjRl+8$VRXQn:BVZ:Ynk&69WeXWYj^u^Tw>w*nkq1HM+tT9A
W#tym4 >FXnm^%9BQi6qt6!&LyYk6@K6!K*$tn:iu\C^uXTZLinki8h9wKblqwAQa$@Awt:ARY<HbP=AyB<M8pq
?\\GHV MVAZbXbcW8RLeW$a:SFw9<BcdW<dY6:y4:cn@DF\9hNZ5QlZI%pLTW&JG*&Q/AE+c@:YaQacTk*SP!P+
jinZXb 4$y\u\wI@!<cl\ZKmQqde+JaJub@k#kZI16jw$iX4tQ6?Mi6t#18b5=tLDZbY%$J>hESPP55!u<Lbyj=
K%QcKl h6+J:lGMZ!>m?Rh/^j?*Edy@k>#iwQ*iPH#*N*R#ESI$>RE:*VeXX=t%aMtny6\$jb:k8hHA>c9CK44*
kYHJ6c cP64XG/jB$Mdn:41@#C:^GkD%>EG41MNZEe:HhhHl9:/:b6>yStM9Xwaqt:JhqZ&wt6l9\ebVd/^99H>
p#Qc9X hQ98&t4<Qe9IQ<D%1PN4SCF6N@=@Ijc@$ASAtRl5MA8C@BAn^A=S#M4?E+wGDTEwEMGiTaN+KTSEBC:d
?FK^i\ /R6&ahk\I&l+MV+V<Ql9LD?$iyFcYkwE^DBwh5b\/S:y!ZdKB99Q<6YhEZDZDhjN?Q?b&L>/T@C+=QGH
&kA*Ya DBeC=\>4#L#ky458lI>bIC=9Rd!5Rd\mTWE?e6%PZ+J4DIjlpk@YEGWlYFlLIwMW*4i&+/1FkKju+:4X
T:T%K# <YZceN&M@@jE@1qeTFjH98Sm$hmI!m&hmKpElwFVeYXV+L4l1yn::jRF8E:!NGjn:h<Jja!1Ii4V9\qI
=qi6h: T#n5?w1V>jt+6w=4/uX<><L4><V?Y69*8uE+p>?n5RY9naR?S=A:bPhqaE=IpkEbq=i#FCuW+mJPq*IF
NTnLPl H^hXNWM4d*<u>Etd&e$ZB:?ICWktndnn1mj=SZDXP4/5VDcH<j?P&N>1?%:VNAT:S8WLeY9L<?L/85T6
lHaQee kC\ZcEet$hTTRjZnSXPb\HiJ$#=j\ThC%YuqbiQ6N$Kjcn+Iy!V9t+CaX>L<Db?&P5qhqM@GXhce*I#a
YW?Ly8 y*Zn@^hm@<6M@V1QFnDuVTDZ5n\$/tIy?bN<dMC6tlZ#=jVb8C:Ku>cy@LFi:?+RM:CVTRRidQXe58e>
Q+\ZHK D<BIkX+A%<>:DnQ?6@+X9tNuDNbKLhSAyc4:N>Le:@>yyY546$S*8:N+SS/CQq4=jwY5VRc*M8<CiqY:
mwm&eE ^Bil^GeS?:>W$>ZSy!>@QE9?GL9+bZEhdhkSS^8+nnb\@ei$@Q1+<nSk?ljmtldbP<hRjJk<?Q6VYGda
@iaVEE W*4+E=G<qZ*m\5&66P+$@@SG/&QL#><w+C&?qY\Hy9H1?c?wb9==5Y9WE*CYEjF*eh*C9V*F$w&JTlp?
GQDlbW :YF6BJ=p:GCNDh6w@m?48Q1K8NadZNq\NSwX^VW+p=><6q%#w6H@h*Fq>H6c%qq&?V/wiXk6J$i+wy<B
m1dYT* wmKPV+#t@/*$Xb@lceh%Wu@eXl:ZF/1eWjGZ/q?t4?HHiWd@Q%k*pSaJJjnAK1P18hj!uQwu9X>DXIaj
iLkSD@ +IyQnPd@4ZANCEyQuhyjc%pe8EaS#/V!R$ZuBhjEcT1uGj*@BNey8nSVqBq&caRK6n+pK=:8GP+Ma@l^
JVKMjL JYYpK!4NQ!*y4jT%hIeIeK%phZ+XX$GeWk#Jq$kitW5\?6j#nQ=@km6dituea@p4y+%w#hRbBnPH1BP5
j!/imh u1%w:S9lY1%$DmTnGWNJ:j8/dkJBWyhjDY9Tc$+%?9@bPQ#VQ?p%GGdH8KZ*kjPR#!11F*8qKM!9l^NC
<$jc/* Hj1d@GRe95V<@:8+@yiqLXn?>&P<ZPhWj>*GXaZAJm8S\CGD?%4D@E1+n9dcdiA/eB%6+D4c\QZEX6XR
IZe:hc F+*PS@eMQi#FK>*QlJ*G=NQA>d<$<HKED\*?66lay=uFNKqHAFu5c9^MbC/Ad&pi<e^bk?c!:TX/iGjY
lJuDiJ /M?F\j%V4<!$>l9%khu%5%uVmcLTH/q=5eI#at+R/9X<XaVXmmT9@kVKuD@BFZ/JwDH@S:utEPZhD%m$
LXJAEb ki8puQ<w/96NldlD+ibLcjWS4qNBjWEWhK#jkK9b>SXZHK=?#*9kVXAwj>DY@Sw4:d8pF<BXVeBG?YLS
Ipy&45 \+EF#LB&ZK6!@qQ^*<SFAN8eQQ8l+\yjtb<4\5lWhk1$peNeni8EKw!4+Vy6D%lcNi>B\hZitGR&ZAZ9
6aK:6I $w5p<#N^JdX$:9wKR&il#TNk?q1ZEFGiu4>uEp<\uahG6?M\wRy*R<Z%11Lh@apZ+Y18K%Sc+W%jMW/A
6%$t+k =w>T@LkSXG4qB!Tn&J8Te1\LQ%6jm$!j/bljy/Y!M1/yS/Cl^ElW#u<PW=t@BXjW6^cNZa$8d@h&+q%B
c@#JSX Vq9BhFa8ui*>Cp5VpSeymDSRPTYKbKCamT^&8HbBLYpKPKQZwLS9cc5YThdDy?GK!WFR<=@GacXbW&iA
AE9VTH B<iQej:H:%1BBt=#MGa\<%Z*85I1yi@J#LX^PPt*NmuWyn/RPt%=D#4I=u=N/6h$6$p/Dy<=Dw5R/Zae
lpS?<D y9LbI<DjT/yDhphG<YX1M?6pStRQ@@\6c*Ihl^?Fj^*in\yB4hh&+\>\nXyPShcY*Kq<qNd@#w#N:e%c
6bB1*p =Dw>bP1@!XQ@:SIA\>+$:E$D%+H44$%!NMV/!/%tG4k?t4W5FG!KaNZWBYnFdphDT*TqWu*4YckI#bEF
mu6i/& /AedJ\^@M!jMV\Je19P9ki6Y+BT%TyH8:@8l#!%Thpk5Jm68Gkm9NiR\Yi%LXDp>6^Xqh6ETt?^#eF4J
q1d\pQ D*\E!tCCd*dHChM=JtS9tWQaPYE8*q%#!W=81ZXkW*J8hR%q/DmlPG^iZkNZLZCc8Ydbb@6YRkAZAIyL
j4a$uW bupnM1wm1Xqiai=Z<lZbnbQX91^up?1AA1a=4*?/k8Yq64%P+<<+ai4BCXQ=Pp/aV>61Tt6G\WHWkcZA
&WbqSb T>/iSG+?ZMF\<S8+YwHVAl+PXKFL!wHpXV4=B%TH1L@1V<$\6bm?en+=4$eSaVayKa4%Bqh=#t4ulKuj
&tyMLM #ku#TYJk<Mu>5W1=pPGKJ/\6M@pZ$hipbFMCJ1KDad9GIal6\mw/pmnI/++4\+Lu4Kcy5u8ent8#ednT
IyYQ9h Atcj9DBKHleVcF^Y=aV=eKZieMJRmHy%^Pq4PGG?>LLZC@&L@XT!neMKhDw4bQmQ=%jY6bGVcdRYtXhD
RPw\h6 ^KHX4WX>W\yLCI!b!?$qWK&tKb&>?NP^\>5nM^uLT!:P!a*5CVI&y/h\\n#Ghew!>t9=X#>qH>^5R<l4
ZF*BmM /G59eAw1CT%ZG8$RNFRc@w%Cy:IaVZ=nKW!>ytuJb:6lHXY9NG9^e$B%u<nZ=*HC*K<CbMk*mpaVEu4M
E1PmYM IAC$Jj!L4IejQiC@IB$?QcPPhRZiKN*>/Y:Ji!Iu#GjSEN$6GY$e9t/e?I*>/$?5t@Fh&X>?dbh>J#J=
jZQA8w <C/X%:AnDn9mcAQZ$Rc8w\%eS^8+Dq^HG:mPNuAhdiA/&5B%6IH4\HY$ki6wA>jSB1/nDX^Hi\he$#<<
AZ>NlI jYTq+J?Hc$RMGtl#1w?yJ6=PIGSwR41>e8ppLR\$+b@pPTuLn4<+VwbjHNhHXbB9Bi6:Gdnu+Dwl5DT%
L<WMAW HJe/b=BHd%XM9XcG1/SePplqd\RmcjD1klQAF:A5uNe5TG+nWREVAkjnN>bm8bTWZkK$R$1+dn?B$5dW
<=Wh\4 wn<w8b9$^IpM:J@BhMb^BAL@tZdcCN^KTZ><KB8jlQV8SH/E@!88$wGRT55ewtZ/V/BjWSH#M1iJqE5u
EVS&Fm B1+yKGq>cqa#5=&d+*!HK!wn8E/L1+?b$ack4QCPc!<!ePB/W*K*ZwT4%kK%14n%JyM@K+6DWuIXb:lG
1H9ch: HNcu+byIWAYFTWI&k9T$P19bC^b@ZpR=6Y<wN?*:h%HJ1^JhkT6Vb%1H!mqVTNMP=Z=*a$@Cn#IE^F6>
h&HMAB QW48<wY+6nY%ZlQly9ipFZ$Qml>eTe@DqcGRt4/lwy5Sw66^FR$PmbSLS%DHbEH##p=FW@Nub1%q=Zdd
Z\LM1X >hWa>J8Xea@l+^G81XRWGWkH4qb!>$y>%Wq@I/?mLV5ybem\6X8KH:C8$QVEeXk4NM8ETYF8XQCe/eRJ
/n<C!5 S1I&F?w$Pk:jmMBTbKZl8b!dFy5BZ@Tl4tY4iPH<Fte6W\BPEnJ%4QCAnDJJunw4MuCe5JK:E/WVtjY@
+6<p@w L6J*ZDh%DFXYIq4@\QSXiZ%EI=++D6eMIyPRQ+<$/D\C&8PiCLAipjbGD*h!$=WHc*WZMA&B1!Mh:Dm?
LNl\a# !MuEQwFBl%XnN!/u^Pu&SNVL#tVY@/19&#J*\^X*u/*?khJ^!qyEX=+y^TiP\$bmhy#\6>9H+8@k6m9P
M^pAXq *+Jp:>hqI/$DyiY^&Ada&d@G4peyjVcbhF^%HSW8byQ/y>wqLJuEKkhWa>C@@cm?TqaJ84I@+H&u!8*/
4V$t<$ tkjDnnn5mL>kndypp9wjM+MjKF/Nc:$+<@6S<@qjA$dJy!WI@^t8q9&uYl1XTCenmjpDte=c#\ueP^em
TkQd#T ud\qDM5>SG8^hEyG<cMe#6Fnpa8?1W1#=X?D*lSE<bbkHC*68uq?AXlS?T1uX<DXpuYXNmL5hAQk<NC<
VHjH@Y *TZIL6bh^w$WucQkw5<WqJMDG&Tn?AEjRpcQuBLSGCXGCcBEANNRWaIaZCY@ZnLIEp+p1ptWA>kFZMa8
&JCiw% Q\iR+aCSR>=CM5pFybi\uQtAZcM4JnG:Bqw:@#EJ%lt+wqey^:a1QRliRj+met#MF=J$/e+K4A%S/YqW
?BcAVp FQ>SKymkdFIPDFI1W>q9k@\F9SPbkt<CJy<p/y^l?ptb#<PXe/uJkjPwk9cqJEiR#/!$PcIBbPe:46=l
u5lMkH W<atMd5G^DH1LHpt4lp#AtTDYe=ucC=i<jTS!9JT<4Z1nY^L/YukV8wWQ/T+<p^bba1iJbYi5tCktkKP
SNeu5Z 1/NXJe4=SGIyEA6%mmlq6QJ+6tw#<mP=/>?h=5h\bSukZGlhapcRJF6i@&^em+^tTVwuQjayqEqPLE9K
-A@PM4 000479a880600110334 Page 164 of binaries2.zip
TVV9qV =Y>R@$AhKF!&Rw/mldD&!y$#iFXpFK9KK:VJhKpLJTYGmVt6RRi<pMHAFw\>KRpIMqTVA^ZRTj%WeQKG
MwYVhT c@I%$IVBNaA?SP//$j#$pbaKiMWtyWG!c<myYTW<i^^YGnYuZH1^=6WF$aE%k>a@w+j=5t&I4nE\Q5#G
P&T:1/ +ph\y^Iwj41?ll#a>FZEB*1S=F#JEcPLW^$C$\?81lmc/*t+>u?N?WlZHVImLAS8u/pc#a>TINtZpB+c
Nu#S6Z DXJXilHG6Q@p?hYSL%?=6t:y6//eZ$XmA6M&JN8=hLeE/u&S=!6?&lXh66QYAYI85D>Zj=Ae!S5&N1J1
+F=<cS :J!dM$ARdb$GChewebJe>X^eNVLl/>LlluPHL>^A#C:9h?@SVdN9u<t/6:=$L9k>C8y<!1FnE+4%?iQS
cN\hHI :RHlZHp<wD$Z%>Ei:/wjn\WQ8Z%?a5n?W*$a8A+:+tkD%>EG41MNZEed8A=eS^8+nnb\HY*kP64AhdTB
9KiiCd /<B%6IH4cAQZ$Rc8w\%eS^8+Dq^H?:jkP61@59%@WE5DBBRAAkAIAA6YdTZAI4TthR5AAM+#AAAwAAAA
@M6uYp a&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9WtX#L&X&aY\^atq$LtJ6eP*c:&9dbl+AeCpKWk/MuY+9JnPu
Z*1MQW !mX58aM:bqh\6WuPC4jSMin8Z6?dLctL@ick!e^hW1yc#k^%C%:e4Y>5eGj8%j/A94mW*td:QPIYQJ6n
HD>FEY d%d\c1jiIk/&SK=kpYbF85iJj<mTLVuHnnEYFd<I@cA<?n:j=@6<>eS@iLNERpiZF*^?BV=9\SD$G@CB
RaDiRY \d@Yhd9>@/%44Q%yZa1mRAM9t#Lwpkbn/6TiNGa@Sh5<Re#+Qmj?TQPYXtmFPSBFCbNNdFNJ!&/b1k8m
i<dDFE kEtM&dNqqKDC%CXEQJANu8$+btEGWblH5p>W#K\CLKR\u<pBWVEc\:HNMPDbW51e1AmWtj&\be<!NuGY
tiV+PN V^6dZktHIJu!MuEB1<hEE/8il18n#=9<R<=^=uFNFA?XZI%dwM#tPQQ=j56?8Sj$yM*tPJK4N+H>>>:c
5S4&!c ^%Y#@H*\iQ<@I5iA?@:i+L+VS#cT1>YYkqS49MTQ5+=HZb9/NT@?IGM+*T@W?ZC/6$#<d@G6u<B?i\K:
q$nipD h\LLDdFbubZXT/uQ%uSYwwdbJZ%<w+Q5NQm5/P#ln6+mNRG=L:uyt5aKNKP#YEQCiMph$q1FTP46jMyK
J^5MY$ ytn4p5a&<#XKc>H=tJY$$F=6QkmCdNM>G&t%pw/>FX%<9XSPb?6YMN:Tpt:iwl5CydZBVc^^YFnRY4El
uVLF*< idWYJYP\e^Gc$FwR5/k8DtRFek:KHh8hlt+8G5JA&/^#9hqwY:nGRi+B/$$RcB5#IHieA/^MEQtS%*Gl
cYLKLB IDAnYyEVuw^1RZT^pehkm*Mcc@G/peidhDAq%jynh4nVpDSn5DB8SI#JbK!W%c\*kd/m9Y>\C@QEYQK>
:tnSB% 5McCtEY$hupL6ej!=H8!^m4=8nbtF6<Ybw<XkNYMX?KE15aTVAaVK@K%L+8CL6i%MTMwClGq$DXBE4V%
a1DVW/ wXDVntFmDAyQVkb9V$>w<tGuIY66i*GEhdqDl^mN6dWZ1N:cmQiXkSdSYSA#:d\l\/\MFy^8HV9/E:+d
/4BWdT 5:MEwk!#p4a?FQV%\hyih!XNuwFeH&alXF5j9FlGdT$E9wbBAa@I:%T?C>H>>THiZ<?5<\pjB9p<h=8<
@\TkpJ KAhCcw8BtQYN+c\V>&Fl*#!Eu:iZ51k/bnXB8yJYY+JK?G^b*:\pH6l9KN/??FKcZCiBuRL&5F/\d!44
Q@5WV$ jjMY%>RH<u+/WMt8QWntI/K<8>JuG+$ulNwG$<TcWGMck5lLe1l9DIwW\1y><S&HRWKMV!</q<LVp=d?
w>?W4t ZwQR%hVbwZ9*W%w:d<HFaXc\bdR&P:V9C?9!dLnqB6W?J#=/Q?p?keZ^$Z58B#=CL\eZcteLla4%^SJ<
jXheP1 8E&Fnj8?ApiW&C?5^DamdVMt64VmKXy^\4GLyLb>J4dwhFc@\Ruen%lMdeuy48+==lP:mPQaDw<b#HJW
eGCVe# ed>Ky55Sca<^5Re%wq!w4qdLG+e!bYK#+jEe9AHBXtl^AnG#:h!^h89j<Hu4YHRE1<:JI#6^At9V=A1m
<yZ#9p ?SuZ:h%m>+=NnZZw:JGRn11E^q4$Fk#MnSbAwF:TYP8k?^+1MuNaXd:8YCTc=^!:XBScpP1iFF9uPuFw
PDC@ID M9LlDYd>a4Ju+ZlheG\#WamYjc+E!:5:<RXYjBA/D^1Iu6%e\^*d\Zl+y\V5*8<kqY*Ml@/^**plchua
S><^56 iYCZkd*S58eFqj%/u4:>m91?5hb>jZi#P>5/?>t>/=?4^+DED@CyQTcb@c8<hn&%h>/y5ui*QR<Lcq6k
wyR>YZ *eRVc16GT<4%hCuI1i#HC1Q51!!&$<wY$DlMVI+:wVD+%+q9S4/85haXXb$K><&FjHmeD%%:h4%uZXt%
hi5u<I bZVYwYy<+dA&h@46$H/!&j%=!9VhXP4iq#h>L=R%9?j$HQ#uc9?@e#G<@9d%G=S^@XWjQ:VZjK>LM:%9
+JA&4h M/>Wqb$h=4i@j5uA66idnK+5b/nqd%uX&wR*tSB!5CpH5j!D5M4T#@\ZM=>eLK4ZMS^VR5l<STG6LK?&
AB$AE6 X:?@<udtu&<X>@55m/G\\JIY1$664*%@bVH#+K$Q4u!46up9JuB=p6l#15h:Vjndt=q:j:q*yi??BVi\
YdJ*%= hhKt5h?jYa=@6E!?w4aX^at=BIZ<J5Cya*c%CeypHFSK6bWaL<JZ=CBd/LM$D&^ca&?D4neMVWC@lNZ9
*=M6NQ PM%QMGA@$hm\>kCkM<i6F:*BhpXntRE%6YMBhA@MHcM^nFb@WZY9aXJ@4c%G1Y*N/m?15td4DaYMLaFl
eJ#DIZ c=S%L<nHpHKlXnP$<%HdLyW8?eRaXta=#uDNP&$P@?yYKiCJYS&:dtNLqXM6/:jH4LnjI^ndL+>5AFmH
l6=Qk\ *=M\6J=piZe%ZR/IFi^6qp<bY5K>@%$\9S@pJc^eQnl4cMilMSRcB<*9JLRBLb4YXNDNY1hH4L>wj<6l
ib$mJn cDH%Ccu=jW??B!!h\K/eaA>\ntkuwj/%Phk/RlRPe#SepS&tFtiwBCLImKm!YZanR5Z^lVIl&c\?hId1
qNWk!@ YNcXRP/YMH9J&:ZlAJ!pNy&PAmGl1H?5b@QAVt%n>l9id5@qCHkwKpatZqipZd@@uXtta?88BGTQa9dN
A%X+qi 6Y=<9ZMitLyJj9A<eYTD*YhVZGqwNR4GG?nb&VQ*Z:nqil=a9@@T#G#HLwSY$=CuAB/9*6p9HutuN!La
BtI6:? lu9Y>S!NZwbS4GNDE^CM&Lil^HR*H^+=Rw?Xk\mlKC@TXVqR*i>a64W@J@i/:$R6G&dAjl\F>nqcpZ&>
alD8=B P5tC*\\LW8@>mXIi=Xy:h@#IM11=kQP6WZL49jiu9u%iakdqD1:yNiLHG@#PKH%J8cE?&nC&lac/cA?*
Yht^59 pyWCL>u&YtV<aya8LlqcAcZkPtj@>M?Zm\@ya6G\Q&5<bS#=^1N!+>Nmmm/YVT#q8NX+qH*X$4Jb+:?d
uW#jTb Qu9Fut\pTu>cKBdy%<#GaIN^Dy@PnT>t%^h#^4c?@\KnMA@+e9NA?1^y?C+maA4S?S8/XDcJ4/%6Y?qR
tlm8JZ Ny$*wn64=b@<8+n#BLXcG6%&Du>H8m>1dt$S:B+SD=Cy:=B\/Pm6h4mh!ph=K4=LV5pIyPDGF5e&k/+K
EAZ:K\ 5CWE#mh\+=/kWCShZ@nJ1S9I*@N*niNLFE8p1\L5NmLG$%qDm^hb*qXq:>$FG$c<&4P%RZFIHjCi<9+>
+B^$Vq 5LqMljFc%&ab9S$D^djXRp^PI%N=qbYbkZPBkK$idIYI!KcQi:p/QHNlmWq#:uX1I=iVWA^n1b=FRYAS
jMcJV^ RTGPdS+?=*?NTV>%PwtN<E$bubuhXhqYqw%NL=\=u8QT/nu@H=q$uZ\?9bXKMa=L:!CM!9c6?e$nt!LJ
9$??ht P:eFKaZFu4&D>J&>1t*bhe=@kWt=A*h89>?IFda9ZR1w4XX6\ZkZY<<&i!ihF:QKLw4NDdER^XjJR%=J
TlWWT< <&C<=XSb<qQWS&1L>1?*e!C/BA@mpH9I!1<V/im^hhiJ!6+/l6W=m>jhb:u%hT1Zc<m&iLS\dHEjXjF#
9mHiAY YJRZLE#Z#1luLhPhN>\H$1\G5lm*BLjW*?j1ZaLcB4K&Iwqdqpi#qlK\91*i&qSd1Y9Z1Ci:Nee?n^NM
mR%?XC ytNn^Ea8dp>MPGpGIVk9$:EMWh%hh:M5VqBW^!b5+aid>5TLL>MlPM$=1I/>DEE*JmD\C6j/R%#dJ58y
weRMDn +8dXP=6#Eu$%#ce/Xq:1#ITqX$9c>8dTktW=\meJudZ%:M*+#iK:X=P*YH1<66FIy69&Z$8hdLD%=ume
d*?^\i &IlFeB\<&&Wt!b&Jh>bR>:=I#/cby6JMl8V4$8XXuGeMc*Y<?>WlFId=Ei4/pdWlTGNE&#&5GGY@5CtF
QGG#hX We>*JE^lS#+La66jTBq8lZyEtHHtel?m1I*j&VG^TZ=tPu\4lX+INLLGjau\K5W@uW5qWq>>yi^<iNHR
9YmA=& Qu5D45*NPXwY?>VA6tL&:I*:@M#LN^P^C*/&cNB#HZ%j:leSdtpqq*kZHdQFFw%6HXhpYY!hLGTPq:!S
L@+wLY ha#iE:AP=9R:Yn@J5<#Ve@Cj!Zj&V9QlNB>P<<E+99<FWE5DBBRAAkAIAA6YdTX^XHicTBaAAC\#AAAw
9c:AjY AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9WtX#L&X&aY\$atq$LtJ6eMXd*&5e^=a8!$LhTEK6c+\\
a^1u?! 8pIaaa\S\5^1nQNnVG!M<DZBG+iLMTaaa=dk9T\ldwL^mP8\*T^lNY@>5m#5@S9<wHlk<>AQ!y@WaPN8
I$wa5@ $EQ6>*&u81eqJ>uejhuIM>NhZZXP%cq#99PnK:j@eYjw>N>LjK:k<?TMe#9+uHH#dk:*@:*489>Y\<j?
4\1$J^ !@ZQ=du><A<ZQ@@<M*:b+9ZQiY<@@GMV9q+:6?B>:X:n@5*9?P:*j?*i@M4*SV>Zj89h@QHSypc8?:pl
1c$R41 :>@i:P=j>b<d@e6wib<6iui?Q9D?YRa?B:ndKnDSy8AhLmcVTibm>N#QhqycJZ4NX<<=<u*51^nh*m?k
j#DNND #/X*<:m5MiE1\RhLn#n!KZ8itJ9GF@mPt<mLilN#jPW\CZ@4%9\6@Fd*jc*^PZ8G6dV!CLQa18+<+<Td
*C&49L ?cj#tubMcy8*$98+Tj@$p9Py:45XnE?#&T^iP/#qdnY@h!9l&GjQ=nYYp+@4mM6JtpSDPjLY@b%&#KA1
8qEK*+ <A^>$cpdk<ZiA6jXli1=^m^:6@B8ah=%w&=Wj^1@+KmF<hm%w=+YQtZ@uDP?WMYVH<naFXY!*i:yhJFn
Ta!jEc IWc5y5FQ*I=%JtH@VqJ:V$Hnbl=L<T<#*$wKFIb@<Y:^&ZM$PbQ?D>4JT!i%aQCPK*@?:4q@6*eHlClR
\!KCJG V8$?1hh:i@jS9yj=H@ARh>q&Z\<GKjWt8aWbnej+K4\E=BPNnjaV6GPh<?PuENwL6y:YlEE%:*\>j?8=
Bc$atE 4@awQ>B:j=<:IRwJBFj=><@>Zj#W>$Z*lF/D\8M1!#GHh@jBK@N%?5@i9+k!u?hWmVwcQ\>#<Dut<L+*
wV1!^8 B&4V@tSCGV^?b/545NaFZ$EDNTXVB=MB6VLHR##I6p>cZ$*414Pb*L@6cT^*<65i##h@l?%#h4>6?&>P
!kJP=9 >Z#n9mT9$cQ&i8H6$Wj8ai>8G8:?nH:DEc?jPne@#4>\i&mbHm%m9w>C1/@W8nAhHpH>b8%Fe>jh<&=q
ZGB9y: Pm\lu/qn?!&$^@pG9lN@%>*%:6#^VX<PQ&1jZ*j85\!KHB5&^L:&caI9IGQ1Clk%tn@t8JZn+enn+^:n
S=>p/p &VWRypI=jVu>=Jt8$V?y5cuX^?=#e5MwQ^%NT/&Q+\4RVLM1+4kMPJYVITnWSPY11MS6:Vm#pWN\jGAn
-Amww/ 000121b776100110334 Page 165 of binaries2.zip
P5:^WN d^#pGAD/ME@PDmNyy6Au#n/@EiS>&:9%6/MnDIYPVIinI$wac*DZ$SqD8e/MSH!PPWCBadYy&?P+nYPI
jkHl9q qAQL8l\P!!>5*CcqaPMTu^p&4PKVXWphc>#Fa<?B^=n5Ed/GS=@d!I<L4+tt\kKj!\c=X5:*6pc?qXC>
$ecteJ J:>5cmP^%56STkhF<ZBZ!H>CZ#ej:+9n=q96^pj?/BYY/E98P<ihI&%Z%GC<VE*JH%NVNnAy4G5E9aBA
j=NFdm n?:b91?GDY#cu1J:%F@K!LX>KTM+kq^>$+jeI<\lhCdS+=91?&hy:WQ8@Rd%WI6:leYJ/&8NP<b1&&XQ
:Jy:4L l#dPu4VTtA/QS*=/NH8CFa^tM>QP6F=ud:b9S=KnPP%AFy+#d4l^MScSiY\a>n*FX6nP+!9n*1baIheP
N@!%kZ !<B$\PGtl@abh>CB?5kLBAMl#FN>/A%n&/QaV/lPkR1tWY1mN/hH4@yWpq41Ju6^Nlpyj/CT$J&RCqc$
6>5#Yq Ql%&w5A8jDGnWeEdbcLS+Mbw8Lmn+ee&E$4qKBA+<6C5t:%=NPB8NG4/66aainR\VcM^#i1ymGTn8lTN
tlYN?p dieiJNSnmJH!D!L^%HWwE^Rqk@4J%uB:Lc!ty%bcVcDmTMGd:Rj@TbYEWBw/9QC+8Wwyk5yQ@nl55tpN
C<AR&E 1C#HBJJJ:Pd+!dHVY#F5Bl>8d#4lR?#@ZHyXP9pK<@lIY<\9p<teS%C=1NY:&?4X/TF?jc6Q<:=G9^nS
#SbF4^ RtY>lImTD9R=c*6q@4w\?4dtdJa*#ASF4T:M^?y#pAh84ZCPnw?PS?##Kb=G?#i\J65FY6w4p>@\1G^:
:c^4j^ JQ=V&aCH=h@y/<!4aiB%R#MB4<WEKy1/ZXGdLa=+$Qa4K99iDX4MZpQ&\6XW%PBFGKRpSDKmjKRdTQ^P
6lWQY# WkYD+5=^W^9Ae5d6K:4GT/Kd#R\b$#ZeYpi+n=DXba&MItqmETd!JYbmSXM$<CwMR+KTWXqCw>6!u+G<
#cJYDk MIYTF9E!wQC/QFYqtL?nZbkSGt$9uTuRI8l5#Ey#akcp5SFR=ldm&qiTl=u&&/Qn/W$ZPL!pD@J%d@aY
L\iFeL G^1HFE?w^bREmCPKyR&*nbA1<P%mHinK+M85uj5LY4ejb\&6ubRnPyDb*P5M>@6aEBE6cYVbwZGV56*w
lhGhH# !AJyS^tyZkDXPDk?Gl!n/n1Sm*P$+u&jAlMc5yFRYuFd+$Xc::yNhFTQCJk8WEXaTjGbu$8a4FD8<ywI
p\*\b/ KM!8ZXCGaN!!iDX8EJk8$KNyy4/<Tc1ZuD5@wS=ElJu##6&PZdB8F?@D5qNc6>&*nb8MF<:SLPZ5yGG\
Hj&bd> &+Wem@+48b^:Nb4KV^>y=kNbS\\y:nQ/YyGN9VKN%#N8E=+ljqp5lX?BI9nF#V/n1BkwpAZ96##GNKL$
y5VNwH kiI?*p5C%i!?cHn@ST</bC9F#XbGny9PjcMWnD+ZP%=dpBNyt^V/RP%4b\mPy:HeA1Y=%a&*\InhC@t8
wI/tTd jYaB6dta!8I%:1=!P+%QQln9LWdnV?#D8Eae#bNyjQBjGE>Hi*J<dyp&jmK=qF#n8SSbkI$**=Z\Ln5%
1IRI>* QnY&?LH^Kj&tKT:%*Mcd*#JQYF&SQDH?!$Sbn?@YD#JFDR*%F4mb</LCIF?PjWNF#H4n9$tWVqal61Ya
6/Gbt9 8QAp^G?J=Z8yQbWD%Fe*jytmm@NFkGbMKdSKG1*R$!kAyejC<=WJu?C?G\995Acj6C*<&STC&:PLdt:e
N#/wlI QwuT@yPQ$ZyQ>%6B4/:/i?Nhi#K?J%?#=Zd>F&+8H1D%e@tZJ&:AuH@yZ8utQ<t8l9dE1*&lKu>!q<dI
!YE4Vb >P8La:j\/yQElS+LDEwj5$>eqc?t1<P=$YLy#5M$DlHuq?X$8ZT4MCJejbJ\nM*55ZH:cc%$C/N!CtN!
CF%VPF /#<8qiYw=Aet!bcFciC#BleHwVBYp@AXM$Hb1PebuR@^?WdM=N^M\b=KMdX^<LkZkm!&8b1jSk:#&n$E
S\\+Zj 6/Wj*huyEm@KR:e$KHF#8GVel#Q8lRwj61@GQcid<#Ije9@MZB*l$6qV&WAlnWBACGV9ed+M#whLl?YA
n4c1h$ uKi8QFM8Dh#cTb=@JcYW/mZwDV!%J6M&LqT^+$tYIZ4eP5*QLc&Yl?S*iIlFnn:kq+6MjJwjnVQpk&d#
JiG!XN !Wq?cScm^QV$Ck?ZIE=^ZIXE@*D&q#ut$YtPnY\!<YGF6cHD/SWTBE=\9HJa8uLyeLR/QX8Yb<5qN%$c
6wu@\B nM/j+tmPy8p+Hym%!/NFyqkH&8VCM&#%lMIDPP*Kk84<FEiw:NLWLS&/E55<i?lGd1uQEV+1n:5kXllN
^aaS#6 ZwW*kA+iMR1RWmkl>Ic?B4kA:W%!lKY5\KwPB%SVcA!&et/\hyLVmmy/\JXFm*^Za/cJcECYhp+8MdZw
qBY&dV F=mV8^DV^QpKpGe>YKN+LQ$Gn=mCienj*PY:5%GLl#DeJdjd/*%Pjk#L#l<wVp+c>y?4X6Gd\DD/wHe$
dGMM1E ht/eQmL1NC*6#*5w<N4cS9iGRKnmc1?158Qu#6#:4#p?h&>+%^C:=4QB:/nk@G>Xt>P%+BbL!chF$Eel
L=>$hn #>$?lcCQRu/M>lWk/Hk<#6!6Hu:18a%dJZwCCWh^/Y:kwkSmIwkXG9J/ml@l1cGwnj!TK*=R@aV&R?hG
wiCh#Y &DyHbaVbqiYAY+l4ZJ\68V%l=GZuHmiGLA\YDEnw#KDmqjith6JV1@>p%Vc=:EHukTHq>P#l$w>A!NZ!
G\?1N4 dPA!AD65cupCM%588aWWXHQBaFauk5p/FyjY?uJ9ZB/R!/E\Cya<ZVwDuDI8dkt4KN*RqRS65DuBSibq
6NNLh@ AWqn6hc1DXXCyb<kB4#yecHR@pFe*B?eeVpepk9Am6ne=@KwT/$lK%p^<A/ZF6CIT$^A!qmI8u1T^^?Y
w+!ImK /FEG4d\IT/W#4QwqH1yGKF<kRZ56pRd$AR@q/l@\GLw@8nQ\bH<ePQA+BMej1RXDaNIJHw9K#LtMm\4^
F^!:9l tSa4Rt>Wqa>X6/ce4Lb%nby=465VB>&eu!:S*khEQIh6Z\pMZLiK4lKathNk$l=&9VIGF4>m%%9/IHGt
4N?dl\ uJ:y$%@/Fjw4THd!kGPIa@AhA?TAeZMV+N#=%DFDaIt5S=8&$chh@k46?cSClDSbp&%hC:m4ea^y\tlF
n:iS*< KBw>@YD$>SC96iQu1u5udiIZ?y^G8e8K=:=EyDaI/LN>C9Y?l^Rmt8$+ha#nb6nHJ\1Em<ci>HC\i+c6
hJpN5P 5Mn/i<YW5Yb!WT*IMd>n!pcu1=\h9%pLBJ/^S^hj1hKn&/Kt8tK9b#Ta8%6+Vq@d9wKStTjNLEw!qNG6
><>pWM Xa644Q/%cM!^p9AZ1<$lnVTHLS9&qw/G1KeZBDY1491YA4LqYpYH!6J5I!EDFap8pDpS%!kd1C:NcDDd
ASmbBF SnkXE8w\DiJctnT#$PSpyJL!y$iD1ZYVlGKF$Rk=S=BNIc95^S:!@+u9cL^MJD^GY!&NVPHulDT//MGh
ICRY&b CCcA5SBjn6%?djYc?WuPnGMmqGTEpC5NkXt1Z5bwRNFBmBQtJ65>@*hNj6qmAJe@$q:Q&k+AI4$&S69+
66\aSS u4XE?>nVMGyj>+Q8P9HZ^YE@bBQZhQeX?F6Ya@ia!\aDjT@kbT#IFTkq\Fy^jREKY:eJ\VZ*^M@X1<nT
:D=FM/ ?jI4e!6?Lq9G=*^L1dGM&A1+GD&\ApWIhP*>waL:c?/Cb/IV$=>W=tC/pkYn!FkbJZ^B+la>C*w8a&Jd
5ZS$MI SbW1X%Ze8MwF9k<X9</TXJJNXV9LFAm&FTeF?L68#d6:Xy^TAR\@icLJ5W6lhp/\hWukVHAp+bmnQ8S5
>K18>e 914q9G@%I*uN4lIqZ:$V+1w%4n!!kkAXMm>C!a$1#>IulpVw$Llq<8icp<4+a\D=?/ku<iDHcA*A/185
F@KtG% IRpqb6W1lj$:dkQ4bq$86pym\yYb!J9AN<@BGE1AhX@y<a*EN&1+b?T/Ybll6EWNc9&AWcp^B8J$>c#I
tC9i+/ B:+WRAW*E48EPcTLC@DFd+dBBSbi8C#\NXqn6TpG=I:DY4=CL9t:n8>8dFBWY/Gq/cWA&=V$N&TmSYQ4
PVwuHk XJ?$PI#K=I1WnZLY?PPeFhPAPK$k5i+S8X>Bt6>tAtAdY:$MW6MtFk$cquQcQ*%tL5:@S5:elD1d?AN$
l#aI4E c\w@dk4BPtc$u>WIEGFFLij5kQZKVBwP=QLb9q5*#nHF8et*LRL4jW^nWSn^Gjt5P6P<SKeLEqnu59cl
SK\E\L kI/ek&bLWkX%KcbW4=k*ZDdL&>D:LLQSQFDhe/C^\uFe/uKQ18>SnWV%S1BtYRdt8MKCtHSZYLXujnd/
X:Z#qK DN?8aP>@EW:68i65%^tIuG@?F%Iw+*XqAH^Tl!iade!66Teje%+C?aV#Y1%X>jVbPXLQ41pQ6P$:ib>a
D\Jh9: T?LiJ?HKwAd!B<XMYliKX:nL1A!^c>?98^h6?XyDI#qBZSE$wFFRtClNSKRG4lhYANN>?@ddyRk6<>lw
*Sjqi& JLJ88=IhT%qyMYD6ZSQi59J9:LbcCm<hC?5hledqmX&F6Dwe8jtRAli+$XJ=+YS5n8Y+PI?kaXG++5##
qwH#<h Rkh&PQe^%tLSTEGD:K@qle&ET!Bt=1wT=YalbqPbLM1F^MBZMlAt^B&N:!RQu/Xe\\TBPQ@Xuuw@kV*+
LpyV9l imLZc%bT%Iy&Za%FVVm/!$8^P+9cHZwG/Akm5l^&5EDG&/$PLPSBh@pe&yFe<HQl/hX8%L4$=5y9bLL@
/cSC>H BH>=X#:%cZkQhEh*V<L:u546/j=4ScF&Db9/Vl:Ql<y!1M94:Yl6XVV8XTn8Y5CtRIiw6huGi$?WXVA8
FIEX^G cM84*dtd^nDL^/%ubhJBm%p^S$w15^mD$bIlSMnj\tl:R>4$:\K6SP@mXWtiSX#jFkA5W:HeBS1%9TF6
KLJ5Jm ?uip5b?H=TV%BDkeKKSFQha:T/5:B:=/Q>4$:<KdTkb>b4^ZYk4jMdT#%%XBJ1$WwHDM<LK/p$phKDTY
Y&%?ce hX%&&PeFywD@c4Ti^1J8:%N<8!%!H/LXn%!$Npb^mnTMFu%A<u&IAiNJ1Dw:dwJd#BZTLFye1PwSVIqW
Hw?yc8 QNGuydIndD*9=\=&EEX6lGl1YieB=9k8J1bLYhj=CMbP5I9WXuPSb:6&wXQENWhQt6P9YmY5m1kLV!\G
qS$L&L n:&>acywqC=EBkbq*N@c6C?1?S1q+:9I5^E=*#l6iK9$<w$EL4jI>&<8#6!ML#/^<hWZMCZ4WECXPIwR
/i$5+M $BXtpcRImC9h1myJK^djhiXM+Lt?4^hTGV$J:Q$Tb@a*mI\RB$AAW+WRkb<^JikJjyX*E/wm4+?=C&/#
qZbP%< R$#wcG:Ap:DY<R6i@Yenh@GL6J$k5YFAcVGV1WW6>^mdTSq64*CF9qMuNPKDl=VXj:kD?RiS#5Pjpe:%
MBkIJG twpFwpmp+%ymyAuXnC^+!V$FZ6QFJ+G!w9pH\d+^/>*e&Y/Ik:%SXJmh<CuTlLmd9h=YbXa&hbV:l8tM
WLFN<V SeuG+aG!k/@+hDASDD5hH\BM?$thmVDwjmZH%$qeShWDNpR/w!SRALw:+HpPj>qTVy19GLM5W1aJw?kF
ucJTd4 /JXYIY1h&ulF##qQYc18Ik$LFX>mJiq6AZc#!lLueP\u1+KVq==*Ya*S6aM1P<cjLnV\q:Y5WRVBYul@
JS?t\J \$kpwi#CA$*ciNtCm\L@%aLS9iyWnKPW1YaYq!a/*BYTIW&kQiE!t$HmL5H&<bte$@uEdcP/*XIqapTm
=H/HYC &6kJt>%pXwI#yP%P9P#wZG5XQiY*jC+wZRtW?Fa:WQIiYLV4A+#*/ISVL+FPRn1NP$XH@Fw/tM<%R?M&
8Bamh@ A#FCh9Vqe6BRWFk^4ctJtw5K&HTX!d>9>CSyD5>>pilhclWKh6$LH^eA4n5Ze+tn9:cM5H&FJHDFy1bT
Ely!JP Rbduw@bAlhRK%yQIW?15XhL!j!d?nH^<aFBaiyk%XlTwb9!:E#W6j@Na@IdPPwG:=W=kX+&hMm:^X^Yy
-A+hK& 000212fd26200110334 Page 166 of binaries2.zip
1MS:/L +=@\ZEVkj%+TXlEPeq*DBi%aB//^Z^hD&tF9W<NbHHG@a%tlaSY>cCPDJQheqS%uPLCYt!1uVHdFQ:!c
jRm:GE &hBdV:ie!iNiWQYK=*Y8<<u*q96q9$K>ppSmYbm!>pRu&L^!S/^$QhDY\i1PNp@=ZDQ1L9kBp^w?mJal
PBWWnX :hS<lBlFFta1QE>DBb$?J$%c/kiVTY:W5<yPB*%KC@5?b*^5Rwi41^u+Y*!mTVhKLP!kVcJh6*iQkqL$
L+6F1j CLuZjJTT<pF1b+1Me5nRELj8M+ah?/#lAlQF4+AbSLR6RdtiZIpEM##G9P8KL6hpy%hpc:CS4SBLw:M6
EyY48C 51Ahw6@6jw?k\EHI9S=yepMbq4X<LX^#P9@6ppH9uR8iTI4LGtNQQpjM5TZ5WK:H15:+alj*K=YtJhJ9
$lBI:T eH<ck#8LJpL%^kT1p\=KC/IVej<LA?qWu5@=WEKb!DyeHwW!VM1ESF%CPk@uMe5@H5JX$6EXXmn^w1E*
y>w&1q ac/6nKmWAwpZ$9hK4yYXHhjQa1AV8TwjAleYNbVRBTySS<Yme6luT&TYGhJ#YJlk1?FjZGMq5hYIRyEn
NZnhhP nWKZVBqm%1j^Ep&^dETlGC<RkeW/6lL%c^X^FTIP4q+^5!HtG>bE#niG&>A>i8RJc\d/Z^l1K!Yw<ACZ
chjR?c Lb$p8GZ<y:S4HPb!ki@R#I8+j&>dXmEH/i$Q@+e#&Y@?n9@H+@ij:j=@wZdtj\BRT\MEFAACAAkAC%b6
1#n<kI JX9<uYiCIRAAFFeAACkAAABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9bZbldDlmcZR8at%\#FyN
SenyGh e>6Yqu$wkRV$Le9/5C*SV8!Ppk/WeYIpVy1wVA$:tb=PQNbMb>SIi6Hy&bA#Xc18LIie/mwJ9+B4:8pX
yC95$J 5VL@BlhcCd9=K=^#:u$QACZb!i#GMpDk+d%:#:99j4$L@Qdq#9hG@n**njpA9#>/^l#n<E!I\=n@?e=W
hPMJ1\ @#^:!L<aS\@HCMeM^%!day^m6Mhwn>Ei#:XdD?$>ZQVR*pN:d/=DS&kjwZ&Et^HcS*MqN$Q:DP$#6M@R
JGN=d: MJ5LC#NH?^#6e:VQ$V/jK%9=/?Ea+bnltC5WuGLkmaEuBy+aiARi<MVAE\NQDD\^<Alp+ItBJ\ciGHlm
w&k/AZ +JFyAE<MQDH\^MAVA\?uFkNQDD\^<MVAE\PQVFjR<G?Ea+bn4mIAul+A>MC5B<I>EBG^+GEQF#*k/RFQ
k?%tEB D*lEXMDVA=+i<QTAy\e<In:k/RFQD*l/\NMDHw1$B#\>+PpBV\>+i5AnaldJEA*@bnntKu4kGRHQCHlG
R!*J^% \DMCHqpP+BpB#\kkStA+AuFbIk\cweMIN!QkGRGQLB9\nIBuBD\n+BpBD=h!BD\n+BpB#\l+S5An!!84
!\u!Im %BMpM@td/=ID#\^+b5A#A=+b<IkcAM<MiGdAM\PiGjCIckDQDHlt\DMDpBtam41A&A\Db?k$R<MMiKlC
>TJl/A M?CbAe<MiGdAM\MiWT9SGK+TJWM$e%W%+JpD#^^+=5A#B^=SQ?CbA<<eiPdAM\eiWWuktRQQHHnt\DMH
CA4WPD HqFV+JpD#^^+=5A#B=k=XSyM=mA+^?A=P5:b?Q@<Z&/ciX+a<>4<@Nu%#e*4N=#jKd!lh@bV+b%=\$e!
!Xn&1> :pFlqn161jp4j1i6quG6*6Rd@5Vi6y>!id@\Zuu=YtFY<qh=WSSZ+@FXE!N^b=d^i@Z1!kTFN@Fi5ZW!
:PM>JJ 9nTN\461n4*J58*%pcMQ!m5eeZJlRG>=jDI8m4^@P5F+5+R:wZh?MyD:CZ4=yID:b8EN9BP@d=bPV!at
S8#<Vd 6L*ZcqnhuAVS1hAQZ=&<K1=Au9%^#ZGN!%NTAQ*q\itk*^@$eRj1y>/A9CcD*Lni1#ZyWM1C9!9+V\it
Dj<lPl eiFNMN@qX!iD<@=J@?JTMD58k>NJZ&aSVp:/+#GtBAu%9eGt:RQpZc?4qI?Fa6@+A/DwK<*?+Q^<aPZA
bX8mnm @9kNJyDYK<WiZJ^iFSiu=Gty?wPV@6X^nS=q=%%+y$&lMPEhi6dy>WGnPD<X9Q*#T+\Iye<G<b?ea+=%
qZGmb: ikQnV:AGyIh%P=>MJ1>PB?Y/Nh%1Fnu8$Nwau@d:X/TIPjqn5*R^tEA9VHk%RLj<hBBb*c!6Yl<!RG@9
I4><54 ZQVw%N/NXSet1kMD$Fkc>K?EM/TMph:a/#i\j6+qu8&eu=+D^iV$AqDGXFe5+cMFZ9>B4PP^QuK4G+u&
iMQ\EW V@<VjT+uq=RY:8yYeATh>5:BhiWTR!<+@Mw@><aNTnq9W9?BFNhZRHTJJ^iW9*>8GkRB?iNK=IM4d^JX
A5keX8 FuEGnY4py=M4enYdp*+?/F?m+&WjMlbd/qQVRFq%CQVN+<uybDI?Sde4>l1R<PA<u+\H=IYt<@:KLjcP
!wqhJ@ pj8ZYJe?8?Y<pGu$B+M4qT:=nL&B!B>ck9=QJ9%mnPjEW>l=p%$8uHmTXd:yS#C4V#C4jN\ZTHp?PC<W
!TSP%$ du=F:yQ?lVkVRJ%e!w1N?&I:M4jJli95=ycZe:9k*K#ha?ZTw<IeZy*DZnntpwa#+YC&eP!=D>WF1^!@
CQ6BuK K&M?iFZp==ha!idq?RB@YCj&ei5$KNhywP6W</QRmb>K#ck$/1<LupL<djiutwY@6n4&m:^=?ub9@44Y
<Z<:&4 /:Z=A!!@&?qP9*h*nhb\&Btc6L#9hI68^>:@I:DD1#YtuXc4K&%@MecQ5m#>F@M%KA%d*Tu>&%q4cEn^
QJ$Hl> *\&<d%Gad+Ah#=5a%8yMR&yY/\h>:1hFpj*ijAPdtwI#P\!yT%*6<aZ^Im<KRCjNI4N1:%\dcVjq4wF#
K^KV4$ t%SY\Z5/:ZcEnp>Jhpnu8jE!YEenSZSM&b/H^l!Bh=HlQ!TmX*kc!d&JyMYa4Ml@R:y*8wDYleu#h%kW
*qYDK5 \/El*e<MdSjwVEVWPhHR5&Rtw+jbW+JF^B?EYXDp*Sip8DP%$\W^EAXp4MMjRjNVa?=TKkwF1FLCm$#D
w*L1H5 tQe#ZtSKJ^PR^wIuJ#dpYJjMCPaN$Bc<uTtBN%6i^^9?t?YAXa5+NDjWXTMM\YGZLadWI+E6Rpuyibh^
W8w515 q!14L/E@Z^Xtt!KbCk9PA6Qw?C%whHhw@qZY#t^GwJ6cpbIQPD\YpyF!WNELnpl\pH:/6RH%*dPPw><l
jI$E\b @Y+Z>D6GPA!u=1ZqpJiT1nlR=I1Wh554FcNIn+!X\&b*YlNQT&n:HYllR!V%\uJIKSLqIGi5ehcWNa/+
jGi5\/ ^t51RIGjR4Pm4<^9IS9ae*e+HT:Kb4tDYZBcR@NC6Mh5\*mMmFwEV=nR:LWI4V1uNA5n<ACDmF1WY8u5
Meq>d9 1C%NXVnVRwRDDw&PTPtjqjwh1G@1hCdQKAmRYmLqQ=QKE5b#%y9R:IJKKAw=:BmXkFKBhVHCTF/JcJJY
JwS9G9 FDDQ4TubD<W/SJMd6Xq&Beh#a^ySb9Y4piXaaLN8cZ^QQh*YNTnZwnnDC5Bd$B>MTRFd*CY11@ViFYch
p9tyk/ 88LBpqR9Pq*Sm=#>DwjDahiyEHXyKM9eEeFX9aSEZR*\i!bC1Hy=ZbGS=Wlbka=1C&d/Wm!KZtnd/PFF
d5nm$y 8*L?AqpjyL\@LaEWBMLjamm/:HW=Gk5d14pbi1qtKkc^dM^Pyu+y$1j1phDndtw6$!pNVw#?#W\/je/%
1?lqq# dZa=Mi4E>qBZX%!NPNtP=SyaI&j?%WmFYtm<qFyha$q6Q$!9McVDEKN!@A/H=PB<4$/%R!pP8%$*!?&K
iP^FtB 1Lk1HQDD#&u>buGcbbhF44qaaSRy%/<L4&P%X%c\1<yn6ZiBb?ZNqPi^5?iKb>XqpYhSRQpdCwp<#RE%
aR&Y== !:48WkhX+#9tP6hMKeEJpc5nT1/y+&1:ZPj1I$!4i%c8uhdbXBSb?Iy$y!LhnuL>$Jm>TB!ie*9m@?AB
d9QatC aHi@!c\uJPeCS1lSSZ4JILy&L1nkTFNhYV!QwN9k9u:Y1m!q!\l/%lSQQLT<^W55$X/kl<5/Ji56GTEd
yZC:b* pVlIQQQyTH#4Q*pQML#*W&%jFl&YmQh*=q9EWB5u#/acJ/h1<D:ZYL\DyL$4aabPM6MjcAk8+Ep*W9yZ
EG!+yJ i5/ID^5T?cTQ4ILET*kYu:ck:Wlw9M!LlHhn&LEie6ub$FV5VCA=:n:Z?lq5&K*kX^^:PLZ&aBYV48iM
@wPpK! hk>NGh1SDRwqM=@R@4P5QqbVA:Wt=!@PXA\ei\!8>A*QJR9K#XiMJ$6RT<Fc=mt!V4RS4<6SH$piqhEn
l1F=HD L%E8DmiILml$F@IXF>:l1ET<d<yjH/Pn#&l*W>4h5NJH/<<aQ:6DP+wII<uketbeu#J@HK4FPuh@Xwk1
HP$6Zm m<Y/WbRJ+t=wFVKL1Z?HHShtKyBVF&e+<n*4h=Z4jdt4e5Q1GyKPWu1d*K?%9$eQ>4BdD$R!Kj#cpNmc
!i>WZ8 MtIjm4!yL=JQd6uadj$pQIZENZyS5^Zb8P8MG9&QNGi#:k=GJ+qZqaQt/54XCq#QJ/bVtH9DwdYDlVB$
uENcM8 %lGbw=HwDw^ymRtLhtiXS*Z\GIH>RuPMw$X<yV<Z8/WZwG<\Ny9Ntiq5Zi@$^Q\>yDa5^Tcbna&&19LM
y*8=$t i4\#^abbliJyW!/!YX>E=nM*pH$V5Q*VI4dT/>PGCW1nSbpMS&W!jL$u$wn<H=#YHR^4eWIn@XDZFu/d
FF:C:J GB<a5$L=cd+H4*<*9Ta@Ym%!wK^=a*&q@/ydNS8Q><\6/dV$DF*Qq9q>/iPI1<\ahY$d%QG8R@eB5&Nh
<i\!G$ %X^h6$6<HV#KBA<594TPD@HpTN&:%d5<5@kZp*HyGd1iD<q:4@SDNlp9%>dt!jeSAt^&LXE>5mkbnIlb
m=R/V* hF6aWIYkld?LdEKcb&/Zp!yinBX$cT4^<:bE984=$J\kI*TdMquW5$LVN*knI49HdLy\8ZZECLM8X16V
hbuiHt #YThXuPJN:4Q<qX&8a&Vla%LQnYLji%&Mdh=$:ydTbG$1Zy/Ya9:wQXKbGj1I=5T6C$/YMK8!?=VF:&k
>D$Pa\ 9GInT&K#EiM1:!G*Xa%n^pW6u%EL:R@5&FT&hhJFTKLBq$CwwdElQn!NYkd:\DYKT@QuLnN8&XeS%TeT
T<pRhC DXXd@=6#YEPH4nmhL4XT%^!>q6&Ky1b998N?wp6jdkKhaWq6PZePD9%T5WjHn:::GZ!\#=mWp\:&%aHa
YtGMVL R$h#m#@aGpNDj/NV1ZS<b@j@DS6@!%cyKQm&>eSYP6+ZL:?Ge%m4Ic^aG8nh%H^6T>49!Qq>1bW<km#W
FRj%NS 6KS8pMG#H:m5ZQjD%6*cyBX+hq\N\Tp9H&QeA%hqeEauG*d1NV!y=hZWDZhVjI^p+n8$I\tEa4P=5Guw
h9FGKN npEKC+Hp:l!HYYY!I/$a5LJaWX>*:pAN9/u:jihNe%XDik9j:5<+G#8H1J/TR/EPT1hdeuNXm>!WHDjp
@84mK? abq5k>=cibPLJ@TN4yj\R%^NpWh8%lN&m@V\Yu+icRTR?ph?nX?bbyeXDS59^G6KqQB6yQc6DIy!p?>!
^<Ki9F ee9VipXhd=&pSDH\%I4eR*DXFN4t&DqGjq:t&=Kc=84n55^q%YW>Ry%ptaXV+kh%b=hu8j4XRuZ6%$b=
Ra:RbR iyF9/$^c#hI/XKS^=$qiqwXpZF1YKCJHJ^J6dtm>TnVG/nJ%L%e8pPi1aJVCR&SkL?9$H1y*dGuI*n/N
SIGWN# NG9&4ch15tLBBNNt&hDLXJ/Gtyqu1iVdcT41XQITd:h4LjjZ>9/S#ZC4Z5!W/:%+9>n4e@9$lY*FT1Wj
P^S5EA FT@#b?+b9MkLt\M@Me<KwA6i^GdyYbCbn>HuY?6^jnTj<Nt#q%&#qG#q=mti9dA?R=+FH*T>&D6?k4V:
EGi41M L%6d1Z$8H8nQjQ:M:*1hZ!Yi=:XdCi5mThLh*>1LlNKn5w=Jwh^d1G18%VLZJ:cHb1wQRNe$a8!yP&au
IT<n?\ <hw?n6WEKMIG44^&E*#cTbLIahaT+=Ml?i*yD5XXGcRY164DLNm$e1&@bhd$4yXEq#E/6S1C$i@c<KCh
-A#ZGj 000600e66ca00110334 Page 167 of binaries2.zip
aJjAeA !%GqAcpiN9LI<5n8aR$m8Fwk:&\pukHP%TBJanm6h6IPVJCajX#lM9BCuJPE:TbJNpM:m*$*m!C41la4
qMRc$j 1ZyFMG=KNdA?B/uBl1+GG%mjCR<KHVhQ5:hP\FG6e6+Yiykq+Did\N>I#Fykp4cZ<GkHtM>/dDcTJN^M
wMQTym p1CNGi$D>X/Fin?:Wj5\#5<<ZMS>9daL=F@cqT6>>>8\*!!ZLGL*kVWMVdIJ8IwX/J5i=&KcdT<k<9*>
cPPIQn c<kZKmkq<95L!K@XnEY9qt\<?dn$?:<IPtMDM/kK6>tGNmSltJkpDm%\4MIGdpJwXLm^+eZ6N&K@Vl@I
8@Hum\ HyZaddb/9S4hFB?p/P6SSAQB&>H:8RjLY5B@F@lDKuaCT$$&k!RP&q!LVh^B>ykb#t#d8#cH9N\j&1JP
\=i>>/ Nah*:C/=$DB^5>+ND@&q=N1m:4uh&>t\Im%&CndHKItZmjdCHI=M5wEyeA=RG!^D!FQT=mq5+<:nKc#Q
9PmTu? aFj*!u/pijS1blbtwQySmG?TKMX*yFXN9YuKJ/T!4kM%X8p+m%<!?/lYEe&h*+p19+Q+FAiR8RjW$Qjk
B#?w5R ny#4P4MDL\995L%aVPKyKhp*%n:XFL\lWT&pa=du5NJ*JTnc&Gle5LMdLCqDWR\:<6TS6a#8$/?Z*6H#
^yA!@< Gk=nKBnDSa^THYG?Ri1B1EictumSSy5$Q1&N8/9:Y>Yq>I?WdCdGpV:nTPejEEP<>nP+kp:mSt=#:qpt
iEww!u YT&VtD>ylNX^9kHHd&6<@p5mqcBySn>&&*6:L@c>:Kq><*mM8QD5$:&>QjQN9lh+/ej!d9En4JYZjl6B
L4N9>M y9pu9?A>=<?<*%#+@5ZF@6jt?Ec5@/F<6^DhmQW@qG<y<C^+Ya9!C$<p!neq?1:IYTQ^Ny$ydcP>nqmB
Gwm%<B 1#L<Q:X:H4eQ$jicG$me^KXkF%KQ?D\j%/I?jN=BcBAt+!VbwAeQ9aB8BV>BI4/ePw%ii:SKcXWDDauG
i:Rj@c MEMwe+In*c&+h\58=9M>Xlcw*V=Z^/GX1nJ>FBP#^SFZ1Ky1Yh!dq:wIJIeBedcDYADVi\Q\Ju>mSp:m
ZQHQkp lS@edmML+EN=Ak>nNqb4pj?IPqm>qNDauwyLw=i:Y\b1Y^JmV:/D#iyae@X<+tYc?nd&\%L*5Y+d#KQM
JdJjYK Fl\^pacTpCCpN+C\^LqHec5\+euDiDQ$iB*W+n&\Q4n^MpN194d?5X1Gb5\EP==n*XNW5X%H/&dD%48M
9ND4%* *RStWS&^J#ujdlkLaPlEDHAIlpGwej&R8XRT^J\HumcaGb=+deSM^i!5Fyl*d*pbw9pde>HC+*:6eYdV
\9tpR8 EqeZK&N/PRc>X1K!<9Y$nyae>#a&GEMR/bKARSAmd4hN8&G^ByL?wW*Ci69G^S6a:>>+lTIIYNS1Cqa@
lNScP? S&49NpKyjV*5R4lNCXK:JT^#ppY$K69>MI=DA>$%HwJ&5tq\*R/DpLGdmAFaE6daR@=HR+9dwn1*IX=<
Vc&wW6 >cI\wyRlbLWM8QKi%Z\kp/5m6ldDeltR/YbX!\8jqjHb/T@$%F5Ydh*pdmAIJWRHbq9qZ<i$Yqt$9M%i
jc>BWA $9YG:VPidttYd/%Ja?^G=NBR+6!6M:Ju4FkIEtj#IbmL#bhIq61GM8QhLWnpZYRXX<81FXyCjTNiBtQ5
bKY$w\ NcX8Jn9M1H!:I>W8&WEH:9%=lakb4uyN<hEB#l*ji5w*IJI>=BhEp?=bj%@Sp>neZ4N#<:D?>Qn<9Wun
emp1w* e>$V<8%ESWXY:J8FKQ9Y@nim:JHh!iw*Mu5&nn%F:I68^N&@&Z%!aN<Aehh:M\4@#i/=A:8HjY#mc%Hb
VX^=NL >Rn6Q9Y^^N8YINm$Ndb/:LyVi^888%uj%4mm1GG=9C5$DmVciK\MkIQWb#dLiKJFNGb:>^dmVJuA!==$
qjC6+K 4d+udT:8X%i#Mt>MyY=Kw*>HPD@kX^n&haq8Fa%twX8bKc68+5ID+XH6GyyC6>4PNBb*tP+4wFADV=Eh
%!unR@ TV+Cjm@F#EX#1\yl:ePiilJ8t$886?\A\jj\q9&l?!/G6inwQiF>u/6V!Pee9!84+NXLmpZtXZQJ@Pai
&*kX!L 4qH6<HaZu?ww!eL#p96J?i4C:4I1?h&e8t&8V@*cH1^S:hAPFy?/yhQQZ*=XT4:&emJ#McQIm^95!&bS
k%#:*1 Ikj$&9:JjY%$jZhX=M=lmw\hh*$V!9eQiVp=1YLe8ebeYtF=#L?C1NL?%j48J%neGi%X#?^Za*J?I4\Q
&LND8n nVuYN\S&^!FP$:+p$KT#9l8lh:$91tTdF9e#!<^8d6uyKAujiwCY#eI@5%+M8=bAbklQ@Ti^9N1VWQbJ
%Ve?AQ 8Qql+eq>$c:MXK*$ebTpW8ndT6*Heni\Z8qnY=phYA@#tekkZ1m*dj@5q+W//pP%cRp84Glq6t1G8hmZ
HluSRK 9<8*jX6+:$*jFu:K:%6#jk@Qe!Bu66#B5XZIq<Bw&eS=Hei8I4A/pFJZN4NTN=X@?Qb9EM9/X&#&yhcH
?4G4aW >VqMC:X:>WNGC$XGlEbch%LqRXidS*bibq&&mubW^P@dX@mmXXMEWH%wc??&QGK#%=Thii#wZM1ci8Yw
iYMX+l IqiAwi#j>P*nk#h@?^mdQe!M:!STP!&hqaEnFmZZQTHCXiw?^?VH1=GGE9ucTtYE!%ZN^TQ^ILK4N6Y5
=h\m1^ ImEd%YbqFth%$#?/Yj%j9:jpu1?b:lZtRFy#m#JZIhC^yq\XKaHItn$89$XIuiMZ$yE6\^hy4uPVXeq!
^8JNX$ N!<:6>#=c#e*>L?^aqZ/:PcY4h:?qijB&::!QDaHBcGLSY*4a1ndp%/M*b^Xyq?qSS1^:/iyt%dKn*6a
1QPkdh *w%KVj#kLjNTZdj#81h#iym=*WCXaL5=wYu=>m>LD>@&bYupbpWj@#AT4SN*!i>NSBWqHPk:YX$9?uZF
<58KFB TD&VNemePQBa=!ZQene91jR\&+&Ed9T@9X#Ldq!=EcZki>WQhi6yYjJD5n\QTB1Pp$qk^$mAPMlkJ6qq
ySBYSA p+RIpEXtkGTXd$kALyK9+Yy?=9=PYPee<9J&6#\#t&#eF96iXlWj^XPumw$pa8:D:LyuX1lVqiByelP:
9Aw=hn 541L:/>uddk*u@iXY?SZ9W@!ARjcPlDc%&wa<?^wheJ\5+BNAl^*/ahc+!yjaNXqZPWYC+ilYAjR9@SJ
N=>DT4 6IJl^pnL5wbQ@iT<eYNhq<XQQ/!TXq\hLQP\dGn&X=:STCmwey#ICI^XAujBCZCliCItRSt5k=Sc8>!6
=jKF=G VY6IJaCnTwpb+>Kiay:^y\Q8he+nwWc/@tDX:u9Vi$c>DRH5lbY1:p/RC=F:C?j+!>VJl1HcLni/R$B:
Sy5%#& dA6*l/^+j145k*n%aKZ9?*!iHk>&:A>mKc#?cV&XuKcT9W%tqj^4Tn6RiWK$n/5Q%AX@yXQ!TDLiN@*<
bct\AS W!nkK@hP4ZPhjld*aL?qZ+D6i<i>pGd/@4N5j?T!eZ#mGqJP<:?>?y1l@6c1>R@Rc6<nS=aPB*ndQC6u
PtNt$< ?Q5GQd!w/^*t&#w>DE/uH^\11&h%&I^5SNCSt\\=^?11HDaJtCJdS/iNK<NS:PP%dwM<b*/FqR8Bey%C
EkLX^Z C4M!6:^XT!!uw4hVI>ti!Q5VmK8SG?YGN8Zc?5njZbe:K+iluJ6Bpw>+aJS#H@#FTY&V>+@tHG>K<bF<
+p@YN! X^Y8q+%QPG^pb/jWyT4=EV%M*kF<&W%pR*i4#<IMFNpS%XC9+HnNyinjLeH&*11SHK^!>cyKq9>deM^5
@pkC^t wFn@l!G#<a*C+Y?dN4l@W\!8ucPRltbMde^nXN>upYhAmP#Nmt@hq8$LPZ*LJiT%%=8@%IGNTM>cd9^R
!VFBBN udRd1W<8P=Ni1tcMc?qRakS$mh$Z5L84*INt69MM+ut4i+S#VQJ>ui&Nw>Fhwl4C6H$eR&S6SMLD=9W5
jdlM&b #w?=u%VPKJ^:1LY!n*I9m?6:#$=B:F=!EW@p\?!b?&aH$lQ!Pe:YW@tP?&cuH$:/inb=a5hhKkDmd^Xn
ZS@KZB @B+^^nePZ5F@nd@?J5>6Bu<6LwV^ldEllR8^8PLT&WpcBFQP^Qn9maN+dlljNHw*u1yHp@y@D:B*F$8>
cDGdbJ $WPbh*&uPa/IcmI!dPR*a1iw?YYSjXyweTi8*%uq$dE9Ja+J#5Qc#uiJ6Dln4<1#Pb5dA%XpYeYy9%a$
VdmTPX ?A#u9Xl64GH*G#?GA*+4wiyhjDDb18>G!WJ6PKCJdqBZqn<@LR\Ac?1T?^$61\!T*^Jit*eId!8cZyAB
SpKVpj CPZ!GDCpX?N>pj8H!nW:XZG/>ndAnm#!l#LMaNP!>=5u^jy&Zq9LZ414Em6ZZE5#&%5A:RTY=l$J+jyh
X$*b6% d$ljj\VSVhquLtN69LYh%APb8u?V$#N@99bnATdn5JMN?YkXP>Lte\>EpJWaeF&m4ATQNLe>XXw!95ma
k?WTaQ b5dI#:6@eT@&LEQ19Q8m1dIEc5TYGttQ5XtyY16tWyZqQ4?$Tw$1n#cbH!#%Bdul%m$4a4m\QAn<!=p=
jPK?St #8#bmCaa+S<$@!eLeNc$4MWSkQPAy*:e=HtjWk<PP9e:C^B4+!9DiujSNYmCb=$9H%n&nGjVVH=\QwAh
6m65eh PAqM=/Fuuk\#wy#VIQDm!&hpycJ=LESym+D^E%e^F:NkpYh4Te$:Z*IXA*PCCi8IZQdTS!:n!*6ESmtX
TbeaG# YH*dBD8Y#ASZdMmjq<$JVD^EP\&yZHwBI1+VkwaAqIcV</TmwMVRGZlmy^&Z!wGdDZ&E@%9/tBIDFG9=
ul%dD< GDbEnbdapG$dTlZ=lk$+\&QpQDE?D$B%q=\Zky5IWE+TJd>*EWbyNkT85Ie#eN+^%nYXy+C*JQ+CLeQ*
uLeS6Q c=t1q4iFbHGDAA^lqNE6Vle=ubDpI&G4++n?1Gtk=:@&Nb+miJP!nP\M@d5@KtMS!u4I?/lM$WSLB#lL
$Tp=/< mE56X+VC*85eimq1KppWAp=9DnJ\DZZttVVPEacbc<m/9#A>C%T#%&%:aP9qy+?yJbnGQ?hVd5+wA<9P
NeH:@Q jNbWVYa>p9u9b6?=C/#LMG\PI^k>\&M>d@hqbe*#L<qEyqJBA$tL1IFQ#uV/p*nM9>w>@Dpm!n#@Gceh
nwEWP1 %GqNSHVpL@QAJ9=/SXtDmY6\&F!D&S5\Xn!$ZlX%=<k<9*Pn=RK*R?mHLR#*FDSc9C%=4VGdVZlbbw#i
$Ik*SZ kHtRtut8u>T+qH4bVBDn696:S9>%yCq&JTcdw$wjnpLebc@I5Bj&=al>=J!TB>5X&l8JmcldQ5knhWLS
EY&WMA ec!wDQ5::*T?Np8Y6M6G/d#cNciHQaqd9qhiGjh&Pqd?\D/?5ceat#dy4wL/qE$ut#dlDD:dMApYLZV9
C6/EF* !6FdLpi8iZ@udhHZG@Q$!a/V:5^?k!ZQ%/q>Bu1B4NZ>lqbn<Zm4q4RC4*Z8h>HG69J**C6>:Y/%p4<l
S&A8Qp K+iIJ59>iEQ8tK5c=YIPq^#d<:TL%l&qV8wmS/ujK6Lap4ySSh=K6dlmVlcdAG8dey*IHi?Y*tc@a^HP
qE=@Fc HBem4LFFGc8cX:B@mVMim@P\?d!mny>XHViL#68:wX:*^=/Z:NaPE6YR\AN*WV<^ce5^SbDZ$8iEdDyS
Z8&kVG QIp$L5K$!apaY#KQTp4$GtPlp*$AVL>AHYDbR@d>%ia?WNIXGKZuFHR%q<6#$G+1nFp$:PFX!/h&D>=+
y*W9Wc laWHVd4Ah8a9uXIH>EPK&C8<ka$X=w#MnGj9!8&+qT?Q$M:Dt1tA8*%BP>jnCnjemu^eRE:9cE#Wehun
t9eX@< VlH<dtiXaH/dah%@<Ha6:F!%1aP5/S6Z5^MFwHq6:GGVeTEJqF9:XG#5pS$X8LA?:P\11\X*N5*GG/8Y
ni%$%n Ic>1?\SbR99<ZMn5dcMbn@ue@<>LitGmYhm6GhcnbhKC?P^DZ!k+G:8A8/PJN%YpG\>\!\Fp@bCS/&#Q
aAen!a NL4y68<d5&GXGk/j/<QZhXGALamktERJ6dCH\ZyEQGWcGk@IdF&HiyX>%i<$&RN:QV&nhmFDme+*&4*Y
-A#DKq 0007ccd089c00110334 Page 168 of binaries2.zip
cI/nmB jiJjtV>jeS8Tk?@N<#?JnX=MbqmuI+6p8L?Rt44De/A*wqnXijtd%YVGQG95nIe^Dl\XKp@%?SQlQtm$
+F@PQK HJq#+!XAMVZ5i*d9c<61BAKk!B5Hi+b%X8KieAp^#<t#wwXYtc?YSa+ZYZ9SYlm9:>!FWP!huYDb!yee
RleNY6 <XWc^9&+Z$@maGhAj89L=tuEpEpu8KEiMFan/#^>\<NDH$???$jq66h1@=p1Zj@i5Ny4+bw9<N%Q$e?m
RDq9qI mTn:aSy@k4hdDL1PVQSHZuW<9&@R%/5lS*@cV5W:&?y\9!W4ZZPmLNBJa5DL=#VbZEJTh8LIa#CZ&*Eq
nu?$n4 ^yGDjMX1:Fm4WbDT#YQ>yWnWKlwk6Cb&RWPM%HhJCHMQ1be5?V#1^%8EJjuA!L5iAR\N#KI!=%y@9TC=
44>l1n h$X+E8<8K1BR>y5bY$W@%p8Y@cV\5kmAKmXhYie%hl9aZ4Nu9?#%6&tWPk^D&JdcyFPLXH8@S+VwkuLa
eF<YmN 6R8Vh%X@!e!hiY=dC<WGJT/hS6^a/bJ$^BpXW^PPTj\p:<t\Th&aBmLLNSh^w5F*^65i!X@JFPTddP&1
LdWN/8 P1!Jhp1P<hRQnZmw%+?S$cPkQnyqy=m4/?CF&qGH>FN=BM+*cL!=ii#me:Iu!j%<1q9NeW#!6RuESJ>n
+qi41* c/SukXCi:+9Cq&?<mNWG&i8CnLnD@w9&T+=I9RN1<@KjH@?dZ#@5><Q<n@u>5Q>ZZ$*X@>:@AFBLA\RW
kJwCCL AAIACAALXt$q+JpQK?EBAAA?CRAAJ\AAAGN5cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>qiHByetXp
TQAw&Z LtJ6eP*XMa:WMBRGaI<mETEKH?G%HAK6EV$TX?AYXPPJypm=uIA>CltqtGPRKAjA$laa!jnl&JQ^?>NS
bqn8AK $K%HLn:b<hnK<=<QH^>i1>\iWu?d?yjW9/b?TL@ed8Q:^5^4q?*F@?!\5:hwb>AVwRiN:uy$M+JnP+PD
#A8Pya htBQekPKuR=GitwniBkb=ue#@=J8HC@T4di#hB<MiI\+ukB&P/jhZ8A<lpe+L/Fb<@ld?yG9k@TQ1JTX
5!!*6Z :<99jFI69D?q#E@\tc@C<e&X#@L=:#$*WA?Q5RZ4wHHeE+:ZpmmiaH?S+D#JJ^luW9n<6%i+j6D+@==/
?*HwI< 5DNZjyLnhtE6u#hLqI=$CTV4Z=?>pi+dh=Ri&mqa+Wqjdk<WP#w:/V?&uiS<nu1A?^cwA*9VkN&^BW>B
VHnH9S k&h@1@1du%%VV4Vh=?t#%>KDe*I?h@/>qY/Ckn#w+!FIn>#pc:l=b5wLdubMPRe&?!QqHNke*qHPke%S
HcVBaD tb\D>@^S^=\Dh=>KD6!>qB!wiXX!wL4pRHZJkiy8^4^LPjA5ZZKkP8ZAIJ%!IJX6>V4b!Q%\VGXd:i%c
&@w8WT 66ZB4GXdHYp6Y=G@/ha5$p<Dk:ud8WGuT#6Ky=KB>XPB>DCjYMN/P1L:RPDSG@D<!aKh\8?JQ/DZXHu=
T&^qVA 99=u@\XRT\MEFAACAAkAC%b6Jc@5Yu&?HAAALp\AAC+AAABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>T
NJS1W\ bZM9buJqbZN\dGF#cDFmcZR8Rp%R:NwNWFNZ9kD\p=CakK/BCH:WuTXkwlBqc&*Sj6mCCDY=TA5lkSyE
+pw!pj WW54wGJdWXiFZFDiC4bQVBQdY1%AE!SJI!5%ypI%ei9&6jT%6bcANc8J9t&4WJ15C1SC:u*u*mBc+dw^
&K6<NT #4#yt>p\teue!a@@Pj@#Q^@*RqLcH^eD<9WMjMjAh\eNkGV+y5Ej+8XPBeM9?6CdiPE+V4\DjA$CFAV/
y4JyHC a9#d@q@d<R>kk\K&qT6umQ@!u#<tQZy1t9KX8hh4:<it4Tw1aJ?LiVdyp:qu:ZPQ*Xje$qWFBa>jLF=W
phTcAh 69DGNZ9@Y?n>&AJwijc16WlT^>u#Hc4:5p?5et*>/GjZu%::%L/9:K94>&Wj!RM4!A?JkD+blIL:5*q=
RQd=e9 \*bM/Q?Dt1\A:wD6J*hul<d#$\bh9D/*:>!cKX@htN/*y8@M46aLj&w>59cMZ=dP6S@di&b\eqLN>Q>a
4CZ*WH 5>j>!*5bBZuqc@&LP+c:D>wjyu#q@tMj>y:VQnjnCWX=5b>&a5i^94h@tC4Qi:J9Z=>dM8&:1WY$6cl@
Y&:IDw dS:Ha&>/i@Ayie&eq:k4#4\T>91naiYQY@*LFj#ctNB65M%#GABa<\D6%wdm^^mlkD=t?JIX?AN@E?5p
Ju%P4$ :RH5?Ai\##!A*jaA%lP+ydpD6$HP\C*4AiJ!H1C@paPB&kTREKlqDRIFF1CNhAM<WI6dcVnPaLPeLC5H
R:TFSj @wT!R^t\G>9<5VReBPH+tMp5N<eb/a!$lw/dQRawAPcQbYGAliNBHnAd<Cd#+C:Iea<BieMu%u6c#mDk
KwIP<! +Qn&&WSe$w:JG\Nd:Fhenl6E+uk=n?ZpYEqLV!VmD9yqucS%M5A+MDpQ&mA4aXG@4BWwD8KwFecF8aJ=
+d/qR* y1EJXn>#^WEB#5HSkMa*EkA5WK5A6EEYHqlh\a==A4X\MDaHcGtDwG^&EM=CN>N\NAF%nwh#I<nK<c8i
6E+I6q aVHCk5a+KA^8^e9hpZA!E>cj&tB=cEPY+:RP$1DhNy?\Hn<5^\*d!l1ENlIFHyw:AZn?AP&@ZHX>N8m&
A<ue\t hRh=EqB*JLSB@6lI$u1kVRCpLZh#CP9$^#wJ/+d&tYG:*eylYj&\CW:aZ<=61@BbD81ZDedlQIS&QtH*
5W4bRJ d:$Q1*BP^pGpFXyaDY:Y@6hPpVdTu:yT8Ph9A=EwaSXYcK@::B@<5&ZE#pBcy=9%*yCh:=?Fe:iM6EE\
M5@8$P :9l@*wjFj<G65Hk=%5&\FN$e#mZCP9%4M:#6l:X+l:%EYw/jqylLHPehN5n6*^nleB>nEhbD&EnPKTi5
h1uc*k b+>@hWW<1aDdQ55Ny\@1@kQL/wRjHL9>1tee>^C:KMeCa>EI/>:<DM8^t?cQXWCdALiGk&:Pdk/PRd66
*jH*BI G?j4*Z:NZ\WP6&+4mN#6bMFqGwQ6n9S\@t8*Z?8GAwiVEJDHh+<9GE\VniQZPytAY#uD/>y\R@&%cII#
EMIJI# RB8Jw?6B\QcPC@jdbm^\1:l#A=n6@/MT51:8HMnli%tcQ=cG*@<S>yaN\y$BY^aGA4aec?CY@i>ujd>%
K/LNjc 1\n+GdLuN&@uBY/^Za1Adj6DnwB6a:M=aC5M?TJR/&:jG:<<RF8lt6m#KWAddq4<ym\\/=/JGNc+A4P>
>MX!S> mN!Wp^&a6eyN&1J@qc8?6cQ>Lw!=ID<8VZF9i:bK1dcM6Nic>:aW9Z49<d*Jq@C%!QKSSeZR:V4jlD>@
M%MXP5 L*6Dw$^nIBpnty*HVGwSbPQL:&G>hG%!nR^ycL1:8&l\BuJ%8Z9iQi#qSub5nEayVl*S5VpyJe<46498
>^Ypqa ah8nG<=tl<Yw>He%&wqYT9R6&MT*:tGSV$YMSJtAX*%Zw&?AtGYGD/<\N%Hd\Sy&6VE%VJ!6t*HZq<4V
\5ZuK= JX*F/ZFGc98>IE8RPL6NKEKY*QWq86V+>EpRu$%6G^HitakW:8p>/1Sjn$d>/dhMZ?VSP^#WN9w#ddBE
aBwDMB LFWhmnu\1\lak$w6!LqC9&Cl6IN6aaJwcZY\kI*WId?cSCK?iy$hlH!wwLVZBM@8qJbu9FlXemSP<K8q
!=1I8: Kn\&NmeLudia8y:dSY<LhWJ?qTRyJEM?/a+@ZddXTj?5*RcRXtwdJa=c8TA/LbcLNG5q6^jW@:qYBYVM
F<wFB# 8A%Ajy*Ta89EciQWm&5pW68#eXK6L!<@\9*AGI$cI4hiajV8y4T@$Py=hhHSM5*:IdFYhbd95l**Tq/6
RXYtB& mlhiNqw4W^Waqd%<@9h6mFSXES!iZ9?\RE!YyXiAZ^bXVpVcD&TDmBPKc%T&LjSI8DKb^+/P!pRcbWK!
^SF5@G @uyuan9WW1BZt=cBTZ4<EyZqcuhpTG8$Ep*>Dqt1VK+n4u<nLatL4k*St&Rjk<eMPI9CitMqp11\=BlN
GIN<Kb >iI=!lmXNk8Y%1Bk&yZ$D$RSapV9b6mLd$STYQh$9ud/m!EX\a@6TSaa<6W!6eJ?XT=NtTFYN11Z!K!$
@cF<h@ \\+4XX$=a&^<$aJR9mVb9FkVnSlqV>9tZbZI11T^@GyVbk+/69REwLJJ*@NV=D6+=WuycIbI4\/Y4a^h
uw\L/b 6\5=K=RbbM&\A:!ypm5$m9HFGF^qI^wXElQBuBpua*^\W=@d<e=tVc^pb^J@5X:*MYNhV!&L\u1C>dKb
S/8J\6 RkCTEtPTJak88nL4&+mZPye$1B?Xj4=H?8c4RP+Aa!u5Q&u<?yW<SLXDXc@cIXj#D$k:TyBntdP$$hI*
wMNcp+ lE4#cyD:eTKH\6cPN+d5SBQn+/LCw&Mq^<ZNc9YZp*=1Z!E54DmC/A<=/RMF<N=9hA5iTV\1baTA^LaF
Np#L16 I1X+8mb+:hw=*8#MA?t1$uE/&YH\P/$HWP^HGBQJEhiF%8/wnnm54PK&!TS:yF>YiGhF=^4KM#Nu#pi=
V<ewb6 F^KDKK!H^%btAEF\dGk6Z#>H\4+ktbS@ZQHF/l@18BHTb/YdReJVXm4:D*1SSw&kGWk?W!\<4VFMp$tN
j6Ja9% m:RuDT4lm#d8&:y4RQMn+FBaJ/yC/5F!9JXh\BjHB4Pq^w#5+*J>i/y54:D^WLcX%4wWSFLaueI>#S<<
9SY?yT VB/G^M15bpqX6J=h6LHjeNRYa<8YQ5\Ltn:K+YLwE1DF<*t?ApP+1kcNey&y\QdTaV*MRI%G@HhW5KaY
SPu*Z6 WJ^nB\E*Bjuch?YMJmyGN:FGt=1V8<TpK!!c469*NH*<8%acqh$nPB=%c?mF?>XI:ZQ9d9tlw*?6hM@P
8THYDP h/4#QcDEFlyEah$MJH4b4j=<5!JXqq9VnPec*#69YDi*@4FhX1CdP#LNR@aTCNGtD%>LtS!SIXl$W>:/
SR8?#$ bIii@R@>18I#6M\NmRpW>nP&Su@:6Gldye&Cl^%dR@iJDH5\wnwItFtjph?DG/HDeyhF/XPFd>+?5p!P
hJt/dt mV&8\PW6LX&H?X%K\#aRIa5cV4Q*Lq8ium=??a/n&BjcSVl8Luw=>+Z9EKQwF!CLG%tSR^cn$#Q**ZH\
@H5ycu /qM#aSGbpJ+TudJcN>WJ%AXk!QcVDd>+&\:8aLi9QHnu$dAWZ8*e189Mic^F55qKm=?Iet=SHB8+M/+u
a!SF?* ytdt=D5*hT?h&BR/NyWi*bY5Q5mt6=F@NQH&D&A8nP^94?8Y:RXBYc6?Xc:E!cLLiLFB8?Eh@hPJ#Qlp
nGLDE1 8GnAuW^l\X$\B6^kB&=bJ>CuQ#im%AjYHn*bp@!l$AMRLV1ebplh&AuHeJ5@D\N*qMd\wjc<<c^P4nHe
nmbYVT ABMNR^Zy^T$K5%tlGLnh*#QJA5R\ek!K%qq?6lWi8kRKqk=XyMLW&+>=L*dDn/+lY$HnLpph?T>TLZab
+<4q^N ZKCZw:T&P6L&t@8JlLu/Md#WeT98DmSq+e!SeZ@Me8SI>YYA?XA>5d=mPPa1!na+eq^NQh*DdR+G/1Zb
eKmw+: I&<TDy^w:t6VD:KD<=N>K+Vb/@A1n8HG$l!Lh<lm9HD&?<?QnL6Sqy5VL@iA/cyc*<V*byia#*eZKe#a
!R*t+c eK+G1^QXm$jiJPA/X@hQZaieRGwAlN*W4<C\up&Kp:aik:*a+4MiHuNC4GPphSu%::a%YWNXZaBFSQL&
W<PL=I tt^NHX<YN8W8**R4X=:1GCE!et4n>wKNji<wAN%R:S8mJ6ete$681@!:#A$Zd:Z=G1?m&nVKZhFQDtQ8
#yjBEA Pk\<Iq$@6QGed>QLdLKmhV$P5$Zl5?+KWWd!KLhn*cc6SVaQ:Vp6TqeRW/nZjKLptDF44&TjX6+:FQi!
P@+EWG mn+ZGi%P#4#lRyPVKeyFE<pchjRZyEl%$w</tw*tymF:PqRqPn?KHjmy&GC^Lut!u5H$ni:l:C&Hb8bM
jMIdS= E#dwn^GVk4Cu$KlM=tn@6>hy!<Ybt5wZAI8ee/$qnhYN:b4&@>dJ<tWD94kcRenEk6Hm6qmc5PCeJi6l
-A9PKM 000a1c7c68400110334 Page 169 of binaries2.zip
%6A+?w tlY+Bi9St?Nq5iKI5Kt!beV>HYG4SL\N1cQh>icWKkbN=ttZjF6kcZilJq?e#/&Z9T1RhA:%X\!11$c%
iLqcE+ G:9^4m:lem5=SGWDJ#6$+wh&Ttd6aZ!ihZKw45Jpaj#Y$Y#8e4\@\wa#mEXnwQ@u:ulEXThRqR5qkyp!
\qE%+% Z/+\QunS9tk$C@M^iH&TF$\kJ+L>ayeyH$GmpYTX9M*qt@8ayAK6iZ+$T*V15MIVTl#wZC/LSKNq:$\Z
dD^MF8 KcX%TSG=J*^6bwRLG\=TQTY+lHiS%i!+iBNj$mnlX6Ia=eHly8^m$k/Kp<6n5/tjMVnJXGED=ykGb8YK
KZMWIp hGY/WLwm!i:L5/e?VNl&pN1myP$@pXdR<pECy+4@BqnIPSC@qdVieWqJW=bVQ@V!4e&K%:#h@Q*Hq6cq
tX@Tp+ nH9/ydlHmn4:!dkb+iEhB?@^H/ZEQS4Y==IXZn$TW<u<iyJ::ZMyYSaZaY?wpn:lWV>heRN+hwK:pQ:a
$bm9IR *wmm9Qt^Z<+w>E^YGu55Ltm9mXVlmIW/XY\!n:bTw<q+I&H^>1?jZX?cJp##%hYNQcBPVt*@ttkkN<<8
Vm8=Fe $<!4=$=Gjq8/jeXLHE*4J6K/qhJ1CZYdh>DI:Wb9!!<1dGp?9V%?WX9lt14pm\:Cj5?9nNbTYm!SWWTW
/w=qCy qWK?d%@EG:#jL*1m/9Ku4@QN<!\YcD<VlewRT85JHc5t14qLK%pqc>tTP@:^W/1!TLG\y=iIi@WdcdtE
6G*%mR 55qZRIkR#kyL#%Lq%:&@JB#</9G4#6KH9$GcmL>&Kj:KyP%Nyw\LkF^QVCu:m9mylS<YeMN==a!c>CVJ
EhqC6! iZ\A&4c@TKMmKL5LWIEMDkJ&dQ>y1&1u5lc6m5tIbad4#TamdtNqeJ1a5465ilj^iGjA6wI:X>jKD?aB
\^K?=S Pn%JFBWeX$#p18/D1LAuKc8K^/k8JKdkS+B^&lA641iFktRGwM<5W4k?Aky61HF/E8WpTtTYEG9b\C1Z
CVmE<D i\wm4Ybu9%kbLJ:i9nN4HSG*PmWyI=:K%kJlNh##9JcYFq8F$DC:R6@KT?ViVJjw:Bm$15cHK1u//\XA
hbq9%/ cpwk+@a*<<<1p!jJ6cKRlTqHtNuH:ND!/*kSabSyLyjqE?QZ%&XiH<!R1qS>Qc9SpF^NTHkepYjba1Ti
G^>@R\ c5u^$PkTe16!GF^ZJW6TiR>4>ijbhdaZc4Vj&e<BBZ6B6ElHNREVtajJk#XtK#*D41kXD!#4NAG/5bHB
#dHiV/ LXdA8Jp1%b?uWhlEEJFBQB&$hL$@5Dy1X4nT&H6mtZL5%qim?H1%B=SJ\9t9y%La9<EVA*Ew>%45ui=!
EJ<n=E Yu:RRQHYp6w*m/RlakTH+%6>S5hXW/TKVW@Vp$6bZ:NF^\%uQ*j+8\=ZH1*4HC<+*knnCkSeMWYdB%HA
btpu6P nT<tQ&dd%+P/yEp\dw6?R8+4wKIcnqHbQ4nBGKnYPh=l*^J/>F9Mue#k!<*\aPlicD:K=59t4RcKI!Jb
#DjPcP %DT1LaEbp8^d!5/i8A#a!Y@>:C&>pL=>:Y1\e<@Ge/CMmclTKHJqXhaKn=N&m*uAp=mIJqmea:ePV4l\
&EaPna D6Cu\@/YFwRJlIiw6yMIiRNSX6:?T%p@MMLCY\bP5V1dk#b6XNXWbZ<E!mcKlBqnS$>#GF$mT!Qnat@l
uRBD&E J?CpK8/wtXc/6PLClbJpLt#+N5&dK!8iGn*N$dQ?6pSPLpjuVX/<hA8\YNCk4XlRj$u*PitZ5K:mHk6H
Q8b4SJ QluX*8R9tJIyJa?qA>>&69b+cH$DaV*>G<ai:ut?lDaF^6X@u5KhNQyMWP=4MGcTeW@Yi@6\VIR:cQm/
!G?1VA m^N/5@9&b9YjA/XTbdlt>QH6FWTJJWdT>qk5DuMH4dW51tnAG&V^tt/m9>5M!tKXG*c?Q:1hbenJ5yG:
$X?8ZV 9ueFMTP54y9\FK+Z>ytc519pdqB/qq<y&VY19jFc9Wc9J8N&&q96FpWqlpY=nHlTb@@H6yYbnYBdlKTA
AE^nYl PYQ$FYh@Yw/y$Qh^XS>i$u9J$pHdM4B5k4i\??TCYdCi>bw>w5^SdjjL8umlL&:jX@A\=nnXZWy#tG<8
/?#Bq$ dHI+T6y#GpGb<I$bEa6GH/P@@&<y=^@VSJ4G<di%*c*qnKYA8ZnJdYHd8%J$*Sm=T#c=kF*aRBGq6hM8
*ij>\N =bTLK!=YpV5>%JP\W:1/l*k@AF6eMd61yY8bYuDSkp1$:mXeNlw9<1MqkYD%D4JclHKeWP\+M#e#BdRV
IBIVh5 dy4$@MjB!ajuujh>*8j>96>*S8VbaVjNiw1D=N>&AmijF@<<:AtQ>#tQkl1nR%+ELe8mQak##$t^\eMD
9HD+d5 SLkc@1$jI<W!q6D^@Q^=niwy?M!18hj<+jLQ8<iJhG9yuMV&XW^ulb:M#cYTQ&\Q*@lyXh<9!H^Y=KSp
YDD&XQ u%5?:t&H<VqE6^t>V:^aQjy9aqSkET6ZXD=>i&JnASu*P1T%LV??/L=>E+XiTu4lIRQlYP%=EmKuqyVu
P8@nu^ SG?pBR?&p*tqGwP?iL&VjQutTq\/4LmbR9@Dw+Hk$djRAJtVicD6*e4!#\ej=yF#Q#NBIc>htub9#tS5
GFLG*S #8:Tq>E%B*Xl$=iJl<V6::q%*FQw!:i#Du4I=:$*1PydYljtw5Tl<=nSMW\6S$H5EDG@Gy>BCSQj=6D9
XSQS@$ HPRH:DI!u%55F9NTnc&L/8jQ^l:wpWmc@G9p+i4T^<H1ta^y:1ZbG\pqa//uAFa+&6JVF:Ml88kNnYRm
Y?%mP: 1n@TW4TEtC<lb5pN4@:PmR#+Se4l6lK!#enyqJ#Fdhq+6J+>=nK+Iup%?aMuSKBnuqANHqIZiH9<w>:C
ZPPlF5 w&SeI/SbNIL!w4*<!Sp:bNR98Qc\H*<GW<+HwwiDXWh&>XB691jSTleK^e4w8CNVLmmZNwuC*%aVHu@@
WWtR9m ?jcRC\>4mB&X\*@9J95KcdK1F>d>8?ywI@HP5NQww4el\RqTn5JnqbVpicGjC&FHLC/1%tq#e=wm@eyJ
4H@&EM n6c#Znip/4^GZ*bV#5kINhbDkaHS&$P*uNZpttJEpDdyk9:Ll^t:>nZYRtw6\<K$K>G1J!bSiKLdE/18
^W!tYV %HSR85=Tn<knwwdjGM&P@1HeZSJbd&/P?D&+<^4t<SPIE:9nt>BlJL9&YYiDPdI#EGbG5:Mhy?^cc45Z
54kmEN R9>DiGD<G*w>%ZZ5\Ik:dmiyN*4FRwR8+HiB!MSaXKc%mDPZ8y1mZC>5hBktinDuIXSjMdtX$nqj:jF1
Fn\61$ 1XMMZAJpDGht68M!6LE/pyVWHFP+1Yq^4J9eKab:i5neWG<=4VXV#q5&!GNw\$uDP6Yi*mW*dPJIWI<V
QwZGe& 9p?yN5^%lem+R<XTTABVJ+mTJwd8RN$Z4\@VNaZ!S5KK>q6#=MA>/mB@#Tyc6\@&FnkPp8N/q<PXM*VY
@S?5AF *NTBp:I!Pt#Z*LA4mAX:*PFj:WMS4&:G9=Np4de5EJ?Mc#KB#^p8=G#KTeMD\+IV=8+&BG9cA*?iiPTd
u8buXJ 4S:6/Kdc:N:e/e$uJ#nkmT&M95LShE&Lq&:>JHGp14wumQuSnl1Q*?iGaWwDB::?tcMym*kqACCSwXt\
P+hMKh bknT%Ei8A%QBwXBN>i&hh+LE4h6B:^FKE@:6TX/Z4JTWuTL#QYbjXX#cpqFFZ#:!8>*+HSTjtEY^KaI5
9TCW!J t*/1#hnZZpZhBqJLActIESh*499hILJ\VSDXRZ?*9:K:6Me*R9VRi:1?>!&DdcZEa&qcZSNnDR<@*#!R
A1LABV EtG^$IR#THtV@p1Wp4YXMNZt8jG!nibTW5VpeKTZtC?L?KSqpZ4piiTHQYT=<1Q$A=DnS<X>?WFnIdTB
E+d/=T MI5+8S1GX5K1$96d*E6GK#aXlFGe<FRTIe45w@c@9Rb**VaCKP6?#Gi5\@k@XJC5dGF8lVDK\MYDe$GW
&YHL>t LANBip<ZeGpk^X>^$ZE^%<HIDi#Ljk6WGQp%e:RZm@4J#Vw^+5H>hN^\t</d@ZM5XcLNW=R\X4NDqnLI
IkG5c: 5Bm*J&LJ$ly^M8JSlH%6C6i&X%!l1huE/C651@%5tyjq*b:\JkSTb<!DBnuIaFykYtTZDtFlb@jbhdb*
/w@#aP \^!b$8Jk:LE\/II1^\4@d^c@Wmndj&1ii$Ek4YYMEi=XPe+ha+tLdhi$&D/bF1&EPIy9GdhXXpl1b+9d
dZkb@u jKbMi&1cw&*Rj9eYI!=!AaHia+tL6%>ZDXwi%/4V4EI=<*u4Ha*qdP>RGb^ic&wAeD?YFNW#4YA=AyY\
S%lESk 6Jpw*KR66>^N%J16@G^Gt?*cS4GQLY=u4>W4j\^5Dwq1I:P9c6Npend&<k+I!9$NS=cW1%a!&th\:6<>
?uAJ^b \ea/dG/ZIB9p:$:pCcNbZPpRuY^li>/la6Z8jlP\yPV5LYL+TZL#jXpBY>^B*@YSbFD$mWN5Vwm&9@Gl
E!p<:+ hFH?:>uaecT6?cITCBZ&=K5M/:^J8SGC&NlSI=KyTAaKl!CZG?*d+c%j&84edM<:bwYGB!?AS4%GyGZ+
PaCSMY lT1dZPbmm+5cZa1LAK\9p64M$jwKd?Vu=t9a&LDB+M!Xp@NILdWtSh?&q>eq/qnb@u:ELWqN!ih6FnGM
<QRn4K nn^#w5#A^tL4wjXRESB&hTJ&S1FMKtyXV:LGHY:9j@knE/@%PE<RZZV\+@^EjlIdm!MPH*KXI*RqY#SN
8nXcp^ $de#=hL$\&\5wSw/mbkBy/*<ct<c9HmmS5jNTe$9aM$N\m&j%GpBX>jEV>=CW+>LF<hII=LaYhtC!1bB
<=J45e Y=*+Z16D$ylFC:!FXMLVPMyVHc\5W9:BX@We5AQm18yJ^a8QeSbbt!%buMuKB8+H44%9Au%FlkaS8Z6H
DT*Ge* VL#Fj8d!Lmy@aGY>%=89>E4Ai@iB$1+p<G#Aj%%nRXIJi>^Q1$4E&cK>t@c+SG:1Li#<Je>d&QbSN!5d
DB1*P? j9AS6N<5PY&5E<lAqkp59iYB/T+AAV5d8Qq44%wC%4Swmw:9/iAI\eBTZFCdhJp>:lj/CmRQCMiqy>IF
K:NLlk SRCIF<@nMd=R96ZQ!tI%*mS6A^C&FIk$cl+A9MWKMQ>^6yu#T*bY@bQDtZLk/9\?:WS88qdT8lkK+/\E
^APEy> q+?\5wV?+L&Aek&CINwmRb1wj6Xm^Z5lq\n+&%lbHGq*R*JulV/@hyZGap?>5HSZ!XZ?^eMiF+KMZZ%h
@eY^%V #uWcSeNJyXc%yISuBAKRZ5uP?4!//!hpB=+Fh1YKp$%NH:=?GXDTtFDK#9ayZnkhP+1dt@>p#&tWTbiK
pL<iN$ =ZR!n/8A&hpy*#qwi<cBC1NNpK=RcdJi?+TdRR4:?BLQMk<k4bC%*=y*TTt=?u4jQmMGWqeYP+6YGZ!I
^b/lmT QdQ>F4IqPbiV>IaN#AMbMhwe*1/:Mqk@4mAqRt:?9k&9@WpkcFwdk<Zdu%$#RG8H9XC4!QLGC#HW%\qq
^9aK\L BD8L1h<y%DS%hdtkjL9pnVG=!\HAFT98WFZ^kW8::eZRY9td59ApV%KdETM8aXYF<wZ*Zd1&ZiawQ%dE
WBy=/H =Syn5aGi+kQnL#S:hYjl/IMaIDwZm&*:y895!lyZ@YA*+^AHeGL%FVG^L6AbkC>tynCQBkFHH+5NV=!y
FPu1d4 IJe^^wu=K\=Q5GJdVHdVyBhi^14Q#n:iHbP>d?la:pkTkJWh5Xl<YE<5#/=+J^bLuFn?JkDJSE^&&eTd
H*W\P1 N+G/lK!a:QJHBNIepALH^%LjV?umbKu9p4SEjP^*IB6AedItCRDPPFpBF>RY^MtTadqu+tN^aPL\K?Nn
nqMTp* !bRWeE9na%<CH8D=+&QuiTdSKp><LJXYank?>1=EbJIS<dH@yQ+Lwnlb/t81kjla/nM:#kbY>9@=<%>R
@PPt*p T\MEFAACAAkADFb6JWT<?tC/m\AAJm5BAC+AAABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9buJq
we&S>i bZN\dGF#cDSmcZR8Rp%R=d*Qm8N/6m=wX#SWFGhRX4lNYlTZ4PSAe:6:E4+cbAkQDnR>dVkiFLuNHiR4
-AHm9R 00034355ee500110334 Page 170 of binaries2.zip
&Qd=NK :MD5XkyS&Mb5Ip\Me85II:p%!FiwItlp+aH9K=^J*?F>lbNeE5WtB8:%jY9>JPi?6=?kubpSpSEPY$94
u^^G>A *:j?@9/*@?N@?q@:QV#?V@u*:?Zj@!Q@@h@qZ:@*Q@D:j@6j>Ph+DP!jQqd<&%86>BQ?!Bj@/V@>J@tM
<Li8Ku :=#=6*e?/!j<\dj\+j>Hn@:Mq#<nn^@q4##+^R\jhy:?uiMdP#\N@@Z=%=9^u*!Q#?V9+lpy9m*jVQF6
/e<FdK jDZuT<qjjti$+&8N<A#<\5#?&h8P=Epn919<#>Nj^Be:#=:G:@u6^cZ&Cn8jX<I*>9pM9a1bZnBie6D4
94WJM$ !>9mK$hn1t@y&SM/an*:Qq?CQ$4%9jTb9ART4ZhnyCVlPd:iK*5D9S?#FPVIL:SW?pc5WiHI%>@$>AXH
J4WDAq 9lI%cm>8yP?n::@V*%YKqTh<qu=dcAX%8>H*dDXiPEyJuj6?!>chZkFj!t/S++q<>MtZFMV!PWKj4=jI
QQyjty ?=HP?Kb<YcQT&Ca@\W9+w\6l$A5$6u4y9L5+jq9bVpuBnTdXI:91q1*?Q@j/I^WuI#a%<bCL/hl1Aw#9
Y1wep+ P<I>p&Fq1#>!+pnm?E&jd>Vhau5C4?L@Y+dBQw?@wL4q>CJ%9<+:yXe9F*HB>8@X!q%F^%d!Xd<mS^%d
*B>DX? VYJT^%bjGiYydJMRqR>iPJSd4<mI+>%\:NBdLCI^c6tKq@99!:Cu>QGN?BJ&A:^YeC<Ik#nN&@jB#*c@
nyMjSn bc9iN4LX?&jw1&e!LNKn18X$a>T!hc/9:<@MA8l65R5ZV8!e66m6h&1b8q95t@D5@Nd&@QhpiKjZ\VhK
&hZ^ic jh@W8=Nl?aFulPF:Kl*Gh9/MdDWTXRb+5jkI91y&$I/=?<F*Wd$lY#%9hMqYeGQYYTXwtP@pFb@NX8=c
cFdQ@D cVYDcH49tdL:@+$Mt*^=ckNuM:$ZpCC:RLWNI=YN%N=&=<SJyR%@HX8yjGadj8u%jSJA4?M+p>LniGp1
%$hE?\ @J!Se<6Q4c:Mb9yhm1@?%FPNNw*^S#9Hh4&muat6*t4cH9p&XjJClw$C5yW&pM=t:8!ma:8:b#Nu/u$u
C9XFpX %L:1tn/eBW&yVhR9^%hVC6QLpi>M58j4Dh=>+X*!ICZ!GHp19l=?ae+:NTJ%NF+#*uG>=$/KPy*mBcZG
VkXQuI 5p/G9bpbF6Webh8IHFBnLNyFEVQC<Edy!Q&cd&!F>TSuY:NBe<9jkZ<%RXPy=XYpik%iQQ9\<P@Y5*l?
pQ%LQG @&H=blj@EDh#?e@!y?n?T@StN4+jNjhS=H5j@HkY*ijijS:NQ<\??jjSJ#?/n&h168%cDX!aSQF8ymP@
Sym1Kl FX\SBu@p\EFK#w!e8=cdTPuBD$dGEbWd5ZC?G9+L68yhu?QJP>@?l#5w6wtCw#:LH=tlwTV=5&ndjHq#
iE$!mR 9*9J:%?Yd?/@jju=#hhS>Pbjh<XLQQ?<i@94=>*+%/WI?M@N&#lcn4+%Z?/Z?jqN@G*=ej8Zi>WjL=$=
@JDm/? Z/N+mcdEWI+ceBX5b&%weYCq9Xb8W*/><$ePIi&WZc$e#D1&Rnj+I*J4^9hK1X@CX<?inJ@MVC=T5uu$
QA\F$b 6uu=?Pb?>9Lty/>j*9#4!>5$8y>Fd/Pj99#WSF>tH#>>nQ:/>cM*d@Lq^%*$^j9%=e%><@Dq\/i9H:>E
6eLJt= >*1nCTuIDq>j&>!8y<JGcP4l*Tl+qH%>HqZhDKK?Cu@k+*j6a1uRQlXHbSljWhNIyC1mN*N?@lj/X?j4
pyw8t@ S^ePAd@:ej6N?Jw&ij^XcQ:%:ahjb&u$h99!+u@:@HHhjQt!jju%<<n@h5/@*Q@%e@G6id9:hu+n#%=?
wG\dcT LL:Pbk/>P1W^=/RK1p^JVXnNXSmGdJ*KBb\b8T8@AKJtHV$HLB%@Y&\JL&T+!9C\kwDW9N#PwC:?%<SC
+kl9hJ +/mJ:yjLN<&*bh#en=a@NdFwdQM&iuu:adq6q9/H?@Pdu=19!=>?@d^<8G@?ZZVjNG?YY<<bS&41cGV&
@8^lpE *X&Fb!a<Xd^I@h$bWHJPlaDDHJRmy=&=uuVuZI!15VwDb+$Xt4ka^9FQ:jCINt:YlTp:8#@uNYRapHd?
IXq^yX +cj$+@w98C9FcJV8h4:AC@u*q<?K?iTd\5wQayBEj8cjS*BL1R8B#CdSInuw45#$Y!QW^k?#X8^M96VM
>j%I/w \q+TW#5\/G!S1dH9wJIn%1VHd@u*#@T9dYDlIJNu>!icj^ddNHy#:?&E9!QDZ?wN:HK?$BdTFd+Im\WQ
IZd##N j:n*Q9yii$FtkBZHk$cX+bStikR#&q19FqWTAcW11wdH&/BH@Yqum/kJlBm:C:dcQ>ZW%Mt\Cu!u!kAR
>J&VGa =kjqLij#9+#<PX!:e?5Gq5$P:y#*yytu!>@6SwWBCV^^49Km+8t*dyZahYS*#Xew4KH1TFHd4yQlthM^
aAl:QI 8&8ym49l4:RL/#1&G4WMkHc6DP<eE^&\E\/6C%:*D:kau#a8%h<!B$qbkw1IncRI8w8nPZAl%+^l5<j9
&?diSy KB\nXct=EdkXE??SA>5GpbRnVwb>R&RZCRELPjY8#!<k^5#FynSCP&MM4yF<*bt#NXYYj:@P=6>\C/QG
ldpHcl 5=6nMST+Su5Ci8iMM\mTNBVCi<*BMMZY<ti6dN6=I:M/D8/cy=\dPuDcP9LM#e<:dXXIy5dKt#tM1VEX
J&<pRB d/d#a:/FS\yGhua#FMnkGwXY?L<8HiF9b@NS6QMmiQn=b#Cp<Ga=hGhY:PTuIy?:$Xy??4Q*5#@:\Z5n
ph*N&c :#9@kT4%$$l?9QdtQ/@u/@uQ+>$Q8&@?iJS8QikA*<LZ?=:P1WIAc$Khd%B/=%I6M:yREkekmB6CC#+j
>Zu+1Y EdnnZuk8tDcEShPkQ%j:BT?:M/TqjEY54mnKSZHu/P*!9qtPqu:$=9/<FMV$>1jS&=<mwjj?R#Nc4yjS
uKC6Nq q@Z<=c&A\#i@j9!/HEXL?j4L:AQk%c>$N<&ZQQ4/JY:m/NjI?=l@@e>9t<@$<ZD!95LCpTX^nBqhmwqk
h%%DiS qX=I4*du<ciMSInHFWYanB5kTYiWYPmE:!L1pewF\SQlBdC@/1Cy>Q!d6^^>dh:iN@@/X<F/Z^:?6Zp:
ccbDQ= >^>!+jV</?^nMj://<j=4Qn%<>h98#j@?nqi#4>>?dBdS4+++c<j94*=>QZLq@ZHl@l4>Pbd+d@MS&<j
<AMPh: 9$cp%J>h?Q5&mTPGWMqMY>89\d1L5cFlt1$dnVTj++Kq6I9dbnMZlNQc1?>XT&=Jkdqmj+Xqy6J9:*hj
Mwi44i @G@^l@nqQlJp?DG@d>=/A8!FdY@89!#u=&?S5Hn?LawdRenSR^S@jS869\lImn:iN$YVj@*+ejS&HkuP
%^Gd=: i9t&ZH8#L@uZ/I9/mqtdDLLeHKZQIcPbR\ec%a*c&C8%&&CBj&4iIG*nNq?BmVh#?RXuc*j8ZZ!tIPlj
uGjG^j *T&Xu\6!?Ql\j@:<RjD:\>hjq\@^!=ijSH@#6j#w9*^=mH@>@G*un=8j99+c=eL*?EXp?AX<jjm!i=uL
k&kCGB u?l6@Hu:<HYb^!?NiB@Bqe*H&G#Gd>lK4n49uny$AA%L!RmZ1VG&KyNhFD6!=8pmEVHVyEy11XbNNLlj
?Ct&@Z %9nXIW4=?R>j9Zt$&:/<&Y%@n8<@^B?mj%*GjlSFP*>=H:*Nb>>?@T^<QShjQ@#$?iZ?\$=EaQ:ZKJ@N
l:RVCb 9pTnl%&$?^KQwpI?L>jS@WiBZG?LKB/>hBphq^hSh?C*!Cl6$aFmSM$FKT\!J:Y#hKYbZAJJMc8cKPB4
VPM/V\ c6n1\K:BEM@><m@\4/pLl?Z9PjJhip^<4Bmp$b9b:EQ$X*@$?j/nkPL:1BFLeS:j#@\*P=jPY<1q9&p5
mI?HR9 eBl=H?V%Qykj@Lm&DM>q/yac1Ap>L&%qtAl%%GFE=?a/$Knk^KW\Y:dP@I8ehA6&Zj=wbnI^W9>1Dw>@
HH9RaN j+K:y=DN:?Y!:/pQY*GWAwF@H8Y?8Jj=@PjhP8$1A!Qiu:XDL:5*P+hjhleSB/@HN>mt?NJ9bZlp&i\8
BEa484 mc>!uq4!Suuw$GCZ$VH*cyuR:>>VJYhpYS%@l9!\b&t@>1?:y$#<&M%LVihuB6N*L1ikabLlN\8S8nTp
iE&BSt *=a&ZGT6RMDq>4%P$n^/TFM$@!K@y5^6L*\&N^M&cq@QHJk@M9iK>=^dJENl+C?V4%&J^IX%ip@X&AMb
lM8Dt: tiIAK<+6<?M:661he@EqVcjL//wAhh41M==PY<X$Mt\yC>@y4Nun?am@Rq84mR4<#!Zaqc%E:V9DT*a*
!I/l%D tCuV&MKWHLiGiNmFni=9/^JIuPe@8Dl^=:LSe:N%tnBN&\!b1*8$1jP8htIbNeXKM<&hMcjiyS%MAA\Z
kYt=FI EHy/qk@%ZNA>5=!Gy>DI$lPKW#*NciCVE:Ibu\i#yjtt&Y@aiqE>AuHn/N88nj?6a8jCIMcPL41&=Hi1
$b*e+R >%H4Bq*6=DIJwDq%=^X&jqiuGquc*+IP!8T8k\uPe#ylcIQ#T>N$pYF^kRR=^@^\t^mcYZ&1k#L!9?Z=
qd:EbL unhT@aXtSDZwHLX<hWu4Lyu6Cw\1MXb?5MDVeE\/?++Mm&@Xp5\<M%St8%KZTNCLdWGYT@Kp4YV!!Y*B
lbhpLB c?R:5?K4j>XCw>?cEFjJ+i8>PVi?!*:!qWi:6y:uPd=/4GLaQW*dGpeu\^4C&Y51nltbqKW8+DSRdwVw
L99YjK @Ve9&byaqc9bd>qK<YtNyWbSQt%K^%cNZ?i#Ly=*M8CbLjKZ==@MGD9lM%Ntq&LyZJe^MP5+58nCH:ZX
uAltMY NmjDI<M^@uhq%XH:tt&KSbtRjw@?QQhN9^QR$cY@T1%&41H6BX5b=?\<@#8&84wuakZ@+@u5+Y:5LAE6
1C6*eI SuSu>VT<M/Q%ph?/NA$\$nd:QhPu61l*y>tL%NZ/YnLtikNhuh9eqibAh/%b%%9w8ZRaw>FYnWj?SZX9
lF#Bi^ b<tRn1&Rad5F4WLQHW/B%=56#:<!NLL<9jIXGZYc6l$L9=dTWK&lB#C&cuX?b:WhB@F*Lq#*$w+M4*XQ
TBV9>X LtM&8$!JP8FPZVZp8+aH8@WnX=5h8X8qN6=TnI1dLw\\4VuVPdn\*b9#?eWI:i+ACYwVa9Al/h#X#%IN
yL%LuC chK$/&Y\@/u%VN6C5H<B&N1:bkLXyu\9Ac#j*pSuw^!PepWVhXJ?X%FPudlADqB@>V!ZbNSjVC$8EIK<
+EEAil =jq<*qy#\\=Z5*Miy1*FyFbC<5#Ec4#6:w#u%JMC/P&eE&/#qcqVtJ&JHBu4?N&XtdZR=J:1P+Q5/<Yq
8Pd=l& NPGYq<A6aT+!6dBbj+C<9&Z/LHt5YMNVIjpkyJ=jZEq*SJ>?thC&+4wQdPBjXA>&F6JwiG%iHa\lKQBM
$u5yFn M>9/lcamtCG$q&y@PnIM+i8N$&wI<$+#K>i+H?BTLC<l4/c9=<AbMRd1PV89bcnK89hDLpEeGAi&u5>4
n%@bXb Db=JF?=IB*I%l/y?\ELw!^aXdb?kB*c%&>%FHdIFEp+=6iDpwl!/e>?:CL6*F*G?=%8>#nB%P848j%9b
Aee&/8 NDCnBF9iH!\*E#d**wDCu@GLd$n1?Y9dFiSKMCPZF?eFh\/y5^A:^aEtp+c8h9=q4WQh!c#LkKa1ata9
K^6Mqa bq*jB1:=I5/*K1T?1?<\6T5EWRm:Vy$&Md:V@DBbn6<Sq?<>CHWN1:Yy59Z<5mQT%H+tV*QpupIL#>hI
ej&YE$ J:Ya%>1muIPpW@Hw%/uQ?C1hGjna8Yl6qK4=HZtcSqRI9LP?L+jHY4c/QI5lwC:bbQ:b\b:LHBT+4@ZZ
VW%lk5 tZMc<6MIyM==m+!6=$ameiHnJ@qy@8G9Y##=+V<@<Gw@jj4E#+<^Qw>!@P^?6M6^GY>k8?j#V\>d9H+i
uD9Wu% jhw=&WquLhi/Rl=l!e=w6D+ZXRtkJeiqZah#ZI\=5yJQ&**l?tST4YaRc+%ap^!NHB1GY8XWWQY!^6d#
NDY8ed iVd:iP>>?FX?@/Fy#un!Mny@qSjF5:@Ji?G8+BW?+%Ic##9nM4:ek^u+$X4?%!!ZZ\t#$yp^EFjmhaW<
-A/#WJ 000a15b5ce600110334 Page 171 of binaries2.zip
l!%nYV #<YuI%>qaGi/T$db9@TT#b4/dp5?4mbkLRW8?ue^AQQ?956c!HjHIP$u>i&P4ij##m9pI!>h*BAXKl&>
cH#G!\ !E%@G+?KZ=F^?cy8cIpZYpIT=PW?*wP9H?:JBE<5&qjYC>Vl:T/:HlZ1cCK$DcEXjLe&wA%1CS^T>^%Z
uFkMn+ <qF*=49&\6<GS#PN/hyPSAkPYNqaJc^q/@q?N%y8#@n>D<9qE5d9IRKitu&+u@p9+P8>98wZZPLHF!VX
G6+SVa bmQq/>5tY8Pqw\l<HTtwt&5XXC@LEMF<bGpET+8%86Y%u%pm%ZitnadC5hY%Be&hEhdPJ@hQ?b4P&$/@
jYqAm< tdwaymM/6wKnZ*a95H/jw@\u*L<G1ePh@@di?$H=T6T!?+#j>Z@>#G/!6?D4:1$<E/@hmL/&yTjLMYuM
ME@kub /:99YRHR<9=P6##4j4GE^WX69i$5euhNRSWLT%&:tD:Qy<>^lT6/DTH5X*&mJ/m@edV/w#jNX%#^q#Zh
SXdHyI \q<cZwn*Ij/=?Cc@@8bdAa/B4@Kp1CEM@I#C5%A<*+1Du4?kM/YL#c#l%9Zi8LJ8ct+D1Ra9NRqQHaEc
\NyN1Q aXuh&WLu%KZR6A>#^J4k/L6ew+da11?nq1$#NW!\ltD4@eiY4/M#:?yH\ClGi9LN$RlQ?myYat#m<HtN
kSn%h/ %$IbaDSTA?+BiwERjWa//@!>J1%>B>mMY4?65?$8G4$$PNm%86/tSF#^\F\!:wR>mWnVcuXWD?Jl%<$u
DLqb9b Q^c#1mb6Dt&h#b&?Y9?CjH>8d&@=6b*B\dq&GLi=WbVZ@5L<%>!?>bhW+$X@bFp!PyT8><dcZ&CX6YX5
9:Rh9D b9*T?8ThGY>e6cYk$6uMEp@&w4+qBPnWZe1M&kGcZL?EId!Q5LtcJ%Ik9DT?6lYmNwHWXW*cHld4m61=
%>i?kW Vm86p49$qh?&F4hNpq%?IN%%uiGi!+L8#BhcMY4$t*Sa&?#dFe1hwh1N985e%V9k?mW$HBlV:Kk\u?q1
KwcQa* bq<WEE9M^w!V*%&j<\tGW!%pca%4&mFjC>t//&mdN9!L#HELeN4KuLJq*lYn$qHdSiKKZcdVM!j+HT=5
6p8!ch mZY9=46?CiYXeQE4Z>?dmWN>kaFXLDG!b5nb9E9R#X8adk:AEm%#@6eqt>k\Rj@YhymudhQG>&pj9&X!
+qj#Ze &8Y:4K:XJYlH9u?bpY#hTw8L8\K4*h#WcHd>Ey4dyltl&W=HZ<:*/a#Gl<p%AHqQ:j<5HSh#ReSC:Kma
>qX$kn 4*h\en8da/BPF61h/lKyFpcyLqpEQL6A11/uh#V/Va%&hNEX+lK$ddjb:4J9&lJ8J1Gn$YXt%dWmcL:J
I4ij8# iuBVph8GR9lt&h!Q#qRM$n4!9pV*<yR*$ThAP#C:AVwiW^B&+!mi5jGLL\YdHFF&wwn9GktaGI$RJu4c
XZIYMD PKBJSd>n=IZPhR*:l8>hJyYb%1=R+:Z6yZPKT41#a4!#Gt%tXY5%M?bkGHV\B5EKWZ^IH?<RMiM*TDjR
@:&@ma \lh^9mNQRec9e$XY+q+@!LQlnlyG#ELyWpInH$SV8EV^=i&ZiEq489K:PLb66HW!:NlKeDX#deLYG?J*
SPQ=L< *W1ic!@%&lGCNq>nh5yq?I#hA?&Z+I%/a==WBZhLc#ZZ?NZ:L<K@pj>SkD/%?1>FEZt+J<$Q+w@iu5>!
wR6cqR HYLGaQM@AtQCT?N*TSaeK&:p4#P:Qt$e5N!ll4%?%<&#e!MFbwyNl1*uy?%YWnmWYp8Yhpi+@JWG1L9S
Y9q\kd 1B6+GGqhjYdDF?AT<@EjFT9NZFm*I%@SaZD?qdjplVe<uSNSiRAaM$JyjHiJ?@Z=@HWPtYDXVF=k=L*F
mTP*1Z S&%VHlup$*^IG&S&FeXb&^>5F#1jYj%^=5CDk$P8/KW^pKW/pWqk&Jl/Xldp@XVeyP+XbQE4P6WZ98pd
Y=iZNp mnPp>c5<?/*\hjeY&IIb@^Gya$m@JVDcn6Ih:>hHSDwZjE%uEGGQDV^h/?C8/^h*T1c1y?FN&\ECJXh=
p5bM$j 6wdp%QX6Yk%JW$S6:/D<wqlZ4hK^LKm^nPIt*p<q!#eGW#NV5A#1898Cn?D4#Q8M1/dy!JEuS#BL6KGa
kw&t\> R%=FhZTEPJAqQ*B$SCMGEGM6q>1m\pk%ba#tnh1/mLWG&^TRFtl<qRnNu:ltamdiNGtywd/9KYVQckci
H!\nW> qRYbq=kQNC?BF\GFL&uL%&?$aMATP*:4/\n5?n4@C*?pyS#q1!e^\6hSIS@9\j1GdXKm:<dZHjV%!:qy
>n+?Ab l%+Ik:yk&nFbjY@4cV*L*1ahTFL4=X9@=MmNci&/WVl4QHh=/NaJ<%%$:wyt!\p84a!BC4C5pd5q:8m4
4WiI?: 9Pyd$XSlYY#^!S5a&uR?Q#jLZ?W@EXIWI4*+KVXb?Ky^+5=D?WAL:1/CwI$D<//$dXZA%MFA*+1h9^ut
B=8<<P /Yy$:hDS:1Kn&p9dI8bFYjA!L\F6h+I:9!ha$4\#mIaYPL:?P95BNyccpJJ^<EHjQnem*#F?@R9nIA@!
MCD6Y* LM@pP!IHa=nc>%4$:XB^X>wiZTd?QNj#+S^M&mWE&#4\d>k//1B$B!T%A^D9wuPT8AlLi+619pBlG\JA
@Y%8m/ 5WNu&9a9^6i9WFKAJymLuA=Ww4?9Z^wSll%?Ch15jIYuyh5R94/lbQNC6B@YNRBjaHu@P^qY5>8XdX5Q
TidjB5 dGLyheN=LdE/^&K61VQDk<=:K&:Tw5Dd5=qe?jAGKwdk?@Pb5kep<HWHmmZmFk4iSPl+<pdK%+?Ie+Z#
CX+FLu M@!/QAX=EikAjk#&!I56Sei%%P>tyF^kM&6uV<$Z6y:F=tdenFb:Y:yJ8e8PIW5bP?LdV:+DbjPS=TZp
XT!Vb4 <4=whlVPNY:dBBlk+!L@C@BSCltY?$D4LIL=BkyJ=Q#tjL>5SB\<u*!FwaP%RkISL$I+MZQSnk65LE=9
IiyqQ& &VyLL>Nl@pX^\G<D!XE:94Y#ulC4y:mlyQR!n6Nyq%Eu\#MXBa%WCSTdu!$N@Rb&mF+R1A?<@\b^>Pjd
kCS*w^ u/GAe#J8@lp!Gk8NZ+Tmn:DqiBX/IX/L&PVq&eF#68b+:TRd$?R8QuSnwmP4GbG&XL6quR\dGLCtu6tq
4uGwd+ ZjJTy:KiTSB:q$%?b4:tEbH451neSJqFS>A@w/8YeFbaDy@n@$BHI$@jIh#%tG<Wiq/E<WJ$?ydlA&\V
YclH/C EnQw6ABVQ<LCYR8@d#G@b1^e%PPepibI6DDR%kB*F#J5CSR*CKL=CqjR%eb<qlNh+*HZc?utt5&yuq?Y
+J@c8E qp9Dm+:Q%NISG$VP%PpZPFWpJ+VA$d<D&WBKBE**Ann8=TpN<m*k/+/Pc$j5:&!VNiGpP6H4?q5%B6X^
pyR&wQ 9JG468uM4<:%PluY8TW*m1u>BL/Y/u$DEc/e/B1QFdy+M?hjeii/dLDcaQ*YX=6lEG%ic=!V18/Ji5/W
S:PT?B 4!M<u>DyA@<lD\:/9B>RF@IW?/Pbb8/kd>8maJWMK+%=Zc/*C%G6>cl6tGIbhP/%PS9Q=lj<L6un6aH?
K8At>q >!Pc:X##:wLY4*14tTVWI5>I!Sb#Pl1y:wFSeKB\4!@MK<=TeV=y\XDlDdq:Qm>n^j:?B^VA&9q!W8e1
JMm^<p M\+\YuWuudu<:1l%4A+:c<8kyWK/TR%6jdpwl44GFlj51@Mi&F!#p?G#^VWn5%ceFN9B?d\$1RjcJaK:
T1$kNE F<N\@mbGS9n1ETVDMmMY@AaSZ<Nk9#Ca?Al&$=aDkdT6WDb!%1dlZEN<8uMJy:aw$*cYyttdK=6dAe4Z
S=dPCm ^L>/dh<jZcVAZiLNT%9uVj?1ReKZq6RZVYB<PF9XTV6@9kwTbH#:AZ^<K=hi!DP&Q&<@m%YT+Ae66dDB
X>Zh%m Z?ChqwATn?j#G=kutGM^c!>c8uin6cQj5HZuW6\nq>?h8iEEq/!$9RC?5hZ%u<^$lL!XjC>XXDF1DdQm
:aJDS5 qkH#mCD6e%jSWE8ltFHXRQn#>cP!HHVjm:1tuTVew^4Z1GAL@t4kiGe#5X^u+j#>Z^nVMj:^uJ1tltc>
5?ipl9 4t*X8?nq%\BX8+!:?45By4uJ9*dFY#^l4P+c?m^#&9J/bH%4P$YB:1H*m%Y5tjYD!a*+Cq9MhBVn>@8&
I/&Ia! Et*Mlp\9EiQ^y5Y$+tia1@T5C5/w$NXhHItcK6t=WM?XcNK&#%NdBhwe6KYPb1/Ad5F:!&1HlT&yqq+M
w/Q&Ne iG6j?G#8telcShKW6dE+bDacF#@MpT9VG%^EVKbBlw9=#>8jEdq9$T4>A%h\QMn#<MTjm^<<DAww>y4@
uF^\IZ ZFm*qyjPYlR<\p!Xnad/t8QXEejLpy!Pbw9%dSNLYpB\&\t<&ilm#+p&ai&5?:V6AqT?cp\:dm$VnAFJ
M4KXkp he#*L^!C1=Llt&QmJt9D/u1!9dap!G4J#w!h/+S&C^:cBKiH9NHP^hZ6*JVn9GhlkEP>cw>6*p=4tT+S
D#p\Bn 5>QkZWia4P8y&:eB@/yKMniSBNdH%<I/%+@Rbiq5V+mJC@MTytjYT8W1R^inSbyd5?KmVjm*I=@c6\PE
m=PC<6 5NQ<C>QwI=jl*4W>\y:ta9nLu9aDt:l!lFt?:>qL#ZTakLpLmu>1e@Hwd#I9%NdpSu:$%?*Y1bQ9jLp4
<+CNK> wF#\pDp%S?nIH?*c6TGPM<kaKm!&LkmDQ?qIP>58$EN/cXbG*S6idGjS%q=q/<!NC*bY#R$:y&$n14YB
T&h:^D ckAIP&^iTNP?VXh$cE9b:S94$kZZ8=u?\Qk%hStD&e!NMt5h$IyZP$I8LR^$E+1#Fm8%qiIL5?LQ8wyN
4PLI/* b*NTN@iN61iht%*S^NYwe!+:6*uJ?lBV&+#DiV1%jW5VaSh!hcZ5%DZLc96<m?=E%Ei8L8M4\QW9bp%&
/Tkj&: FwMBcGpDt&5L:RdYL#aknd^&l6DpN:%p//^6CYpll1EF9RN?T/D4G&pdHw%%6q>C:9tdDnP%ed*b:qHd
bXB6jn ^J%/5%*Zp!\kMi%p&L8eNjHc%qRS8PWYTe^8cDy6$@hyP%Qq99Lcd4A&K8?/jHb?&&tyZi8nL8$&/%d/
jeTy<A yDQu5n#u4k$nY8bh&j16SY+Y/8/5P/l4^jhc$C:Y!Y^l/$I5j&ih=N1h=?W#h*EPAudWcJ:ce%?=N5cL
Q1=GF\ bFFZ?HC4Y%VRZIdPXWY/BX^PD*c8pKkY$?194pmntKuFb<=n?hdHPY6HCh1Y9X$4\=:4PZV\#MZjdX!?
jFNH#X c>6<@Y:ZV#jy1Lp*:iG!>pjZ/8ZK#m&E$DE=#&V+i:dP8yXpdPJ\F6Q14*Nqc^QQP9++*G!yp//?dBa*
tEn\pV VY$ch/h%@t=VY66u!h8$5>=?@aG9:Xl&d!^t$!JdPuJaRT6eL4J^DeCnFm#QNj@mn!:G$M!ii&:P^@4p
wT+u<m *ZT**G&49=K6T1qCpG/@GBNBdiiX5qZ%$YJHw<l96*J=4Z*RZp6NF<#cwKadAhP$wt8XutuHw/9AyZ/*
t^mp#C *+eN\Ndj/5?5>>R6dh6%++Npkw5K$ndX49$u@&^#X<6#6E66=KIFQ44?1e6Ri^h#e6/84RcdJLbd8d1h
M8m+PJ dk4#jbj*eqQFd88NR5cSnh>&A!w/i/SA\@heA:B%i4T%bN*DaaYMtY<8TcZh6?!G=<yC%n@MZyXQ:W!^
wKP#+? y#L6?KQnY?*5wY8#:<I5q6ZVWZ1^^</F!h$YE&8Zhm=k>N*KwVdkGdZI5X$!b1MKdRCwV$!:\RYPkHXL
Ee#JH< ^::4wt$#4D6ul%PZLy>jnJb$8etbp?Fb%^mT86%%:cyDN$VYVlX&R^jc:Yp@/J!tFXp:YdmeT4EZ5tGG
VTklM\ L1:*LlaW/8CCC\6>N!uX>mbkCMHm1yt#\%dhe5t/h6&n%&$>>LVB!G@4+C:AewC5heAKd?#d9l9Y<X5n
>/+<1R jLEhdNRNCucnWF%h=+K6w>?\%j^q155>W4iww=8Y6KX^Dp>biMkik6u5\kC&\b>d+iX%he?=ST:hnyY=
wXcma= hqndqnXZXWq*:wc/WwZ9#T:cw61@d1VR=Mh9:+X#qtt*am@6&P11X1*:%V$tZht/1?i$&S:m+dpdbLLS
-AqWR/ 0002af2447200110334 Page 172 of binaries2.zip
41l@5l B6<y:EkS$=\TTKhmDYK8kS&@PQhh!#>hB!HGZBHdcPShNAT^:Ca^/CXj*bI8e&\:6:HG$IBd8=nPb8%Y
@l&W@* V#iq=:tbF/dd=y1a/jch8X!m=*wVb>:<u*XZqXw/6hDwi4T6X4^4tD/iYY?kSlt8V<YE!LPG84cQ!?d?
b@Yn&I $6S*A?4Y1/GhpT%j1ZH5CbJZt46m@%!*8i!5ybkG6&Y*&5<PV*WqK8+\T:Z=k5l>SK@HT+X$:d^B:*w<
b1A$=i u1@u/%H/\%m8b4*?!@w9w:>+P^iu#j+!W1:KF/=Judh%Q5d*=/M^%+V<MQ=l6Jc@Q<6Vm^H>l$M+N1uq
n%%kyP 1Sl:q\@/jlW/*aSBA/:DGi$R+Gkt::Bia=<P#eBjQL/IeclN^*EC\Zn:F&kWT+uw!hLLS+@iH@d:jd:j
Nu9*W@ ^@K9*Mj:jT&j/n!4+#k9=e?$LJP!18ynZhjH8K/t^$1?FXj!*LLIe@#Gjq@5&\i@Xhh^ubV!V*/9LPZZ
FqA1RS 1?m$nJdXTV+6#$5<?DE/uS4=ZyZIw/1P<8GIN=M9w8XT9m8@nZi1<eL^Zq+y#?W!1tQWuCM<1<V4J*!?
pylEBI 9QD!hJJ*tydXWj+i<bw%Q<yL+*H<t>AKMtNTHPQ4t9>IMamXT//E#G1KC$@+!*JB<u$lq6iAZ<9=mZ@4
?Dn@cI ey@penh\VeiT#=jLQ#ZN/dYJV5*=jBKIJ6eqPP*%9G^PT!EYXMyX!?9LG?FKiippY6=Jdq\e<%?P>$%1
9dIK<4 iduZX%BT!XPVw>B^Tq=jejh\B!y=+@K+1HEdEuqNjJJHZN*&@lD#ymqn=XLqE@:l^iYQ5Ej+tk6%CT=e
t=#6aN :^D8dau*=T@y4*eQ8RZ+wj^cZFXq!c@p9y?mKutNV4kpMLeByYj=E5SG9PTn<kGZi$#\QCGullVl%jd+
9+t/*T A*tST/w1?ZXel%!VWCbe1Ck9=?R%pbeC5VFj5BRYkZJe>@H+w@CXkpmKa=Cbk&C<iKu9Iu\>+w=ZKlD!
VJMwKR itCXjB8<X++/45cR+NKJA?SZL1kC4@A:eupWawRb@LSMG8H%/%JFLCG^<p6HCH$qWu\TEc1*AjSJZ48W
Bp/KR: X=e4\5XE!Xpai\VLTyFYpjdtqJ!Z4=B5ihMn=BB*KRGXh8FXLVJe1<I1Q!mFqPEaD>^F?a&!ZJCuEJj1
PTq1<I XPG%KMct49pFX!uS9EiqmI&IREXS1!JlHu==GWF+G#:Ra$@G1t=SIQp&<mp/Sa*R5<mG\!CnT5AMpK@C
\iy>d+ V:AX85\4\8<piMt#1D/+nK8FEB=^qZI#1A^JJdVmynqhldaJleJeCy@aA6\/1mk=A^QVuPX*Kh$=4hpF
LCF:C< Z*tu>yV>BcSj:nHE5DTJTGBDV5KDB91/FD/A5eLhp%/NKFjM1+S>mpTnw$QkiYH\HIdR4l4/C4&RY*a?
#pKnh6 R>mlpmwFImimFR$bmH6YL1lwwLlP?Q=XCh6W61ay#*H=i%\6Ll#GqEVZ:tJF+eR59EK^TqAWq@9+Rq@=
VWJ@pB Gh>X#kyn=R$y^dljpSqaMWn<R>ciSc\l*eKEI<&>TJ@c6ClyQwZli4kJk!AIXb>+NZL><lIu5I&GDMVK
qe+IX& yatW\HbDli5n#d4wDp#WMeu^#5hj\NeelNLu%KK6MLF<YekM4yXCW5uhF^?lDwP!1dbaSeLWFTw9Z@CT
JFt/4N cFX1YmiaD&j:ShlPT81!kaECa!uDEB<whp^F1iS@u>bBJu\hV4Q/?VpwSMnp&8kWp8RMF5bK/XF6E!#h
kF@YIi 1iINw/8Dm=V*F*KQ8B*HZQkK=$JT/Y^1&1laVa#/X*4IE+k>RjSE*ZDbWPYeKu/l5GC5<J8@Y<eRH*qH
q/AP:B !LDicBP*mMVT!=/ShV?hEmiSR5kC=ppim=X\NJ\MlPAkDPy/Y?6d!q&ww6h#JdcywkBW!kq+MLEJyh1H
4L#JE& KYkG*&8%VmZ>1#uIP4h@Mi^4VEGEPV&1YW4P+nZkGJeJDD:8FE&F<uXQI?^eq\n@R9Xh8B>VBP1ne?tS
6@L#ZK 8EIACQE=eD>!A$<NdZ8FT#iZE%jH8>+\!+K5/IG9\ZMkY48lbb4KQ:qS4&ye/TQpBy/wG!1E5BP$mlSL
<h@qWR +@!^@LH*D!K+hY/t8Ib6*+QPQhXSjttlql5&jjucKLEJmCX/!9E:#5&1Maj\E?DI6iVkXX/dW#E:Ekt=
NmBaWN EJJZYPIGiAJ<XV1J5\AAX4$N%DS+LwIM%tp/Dccl\nEaTwEtc44JQDEFa5:QDdAEyCItL?q=mj8I48B#
w^whFF e5hR/8qiwXPyVqbRTk/Hq$T<ML!eKN\TWp#$BL6NKY+6MTTCqkqwDlmQwA+tPTpX\WTmD!e^QC%cQDX$
kh!Eb6 S:lKEV$K\QQk?k>lYE>LwVb<ukdBXCV=PaV9KWuKE4IFdl*%p/mECAy<VtZGENIEIETARkn*6>+@qHTw
QluqWw /uYE1/ZCJ8W4Lyh5EWGn$J%iI%E9EA6\LPyDQ=>*!Mp$XwR+B\>A+wLYJCH&wmqPI6I44!P?6nthV*RY
tbj1@? bBA5n@!>8\4*i:BXFFZaC!F?QlA6X4R>%T6qm<JR<!WVZl$hq>u>pumbwp#dqQ^CjXZ$WNNjEuT1ZcKW
6>Tea$ mq&W%!aVaDd^e5Jpai#^GMw4:eudC<dGeRYhl*5qVKS\^LnQ$CRKeWYHIw/cmFkiBP&%kpVw/449l/Ej
d@AaH# CFiuYXBQ5&hRQKZV+eZV:kJ@1LaK5YR4FBcP1Gb<R5>iW1Yl4VW\aq&VYQZYJRKhYIMhawKnC5K4RHb^
\RLMj@ DmhFmM6#>GqVlJ6^8Nq56^LqdPYQQp1cbXw68/p\V\T:>dEFFSGe#?84kmiSQ&XTDa<VH=>9l$YYbj5\
RD@yGT ECJllRPlY6kK6MwdKM>hEpEtS:Y&akPEiutlCHEPu%lStT9VI=yT+1dcIH?<N>\u%&u8FS\Bat9WFiIc
I%e4%1 =R&T^?&t<Cj:WK+w!@\%TT*&Y:m8YH&Pku:mb6Nc&qeABmMY1EL<Q#DA/cVITY!TmQB1PN!u&Z+6Gy4J
BAnA6P u#IDa?@5*qNi/GDBSMBlRm/aE^E>C\#%nT8:BLw/wjb95MNKLJ$FWYKNV<V9DKpaHkK<umB:^?w\VDN9
eYD!hG u/X!Nd+9j$ZeJ8G/<J&nXZyn8l5NEtDJAYHk?yKpemBM+#BebcI^GkV8eDMe>MDaNIQQpV<m^$FBBF=e
9d>i+J =jRm?XEe:G6Dq&&?DIESZ?XI%6e$WA^TlNRyNAkaEYE*:VCMZE/6!>Zu^Kyp<kGmhkJEFBij?cG@*1@>
8kq&:Z WEkN%!E@lj5\XHJB1Hp59k<@k$1GG?L/11MSC&\NakZcW9nw?bQu\MPyRL:RPlTjKnd+GXd+TX:wMApI
QB@N\& PctAJ=CY8DkRIcM\k%mmaq^Cu?mWcMHA?^i^\/TMWq#t!qbSYRbt14AXamnkXkDcnal5t1XyKB@>hbaY
!?YWE9 wLpAa+WNld?q&%EawkwG>%wmXKdn1SB>G11Aq%\mAwADPcuVQ\RBD$L!l<HEG>d\4YIBk$^pP^5Mk&eN
\XkCm\ l!Y!A@c!aLim#^He^BkC:+QA>$nyVa#J8N9RX<y\SeSWK%8y1l4wXBV*E*!Z9QIlEKpX?wVia8mHi^BI
K8aPeM =w4tb5P>\B\jYIL816K*ek<CNYmp=WiEGSHSD5\:uR/ahM8Du@4DdJkXX&Dwe!l<jT?5tjT8lM%BVN6/
haP?u@ bHB8^CIAT&BR!NiyeJF^S/%yIF\IJPFI9twp8qenVLaCH^Nyq?1daPF^NR5l59A!Z=kya46PJ=pa1LXa
V+&PpW VH<6^BakNm8a6%I:Wy5Lll4A!<cCbQK!!m*5j+ZBE:eI=/MKi?BSVX/+>n^S$@AbTCII:yLn</VZE<wD
DZ$%V\ qW1cpDNnRZ8eEJa\?Epa%!yea4yAQmikq:E/R9K>W55\SYNR*wK1%LBi4pc$a\F#IiVKQ*pM>/Kk/$IM
8$%:d> XiaLnaJi5\#5Ljc^PT#n/:/CY&VAWVPQeLVRCan>4Kpa=NeR=Q!b^AyVi&B1TG&>P%WH$iGliNyyRHmC
DI*m*\ Z^aw#S6EdbXZkqN5wC5pWmM^SB?P4%QaadtPtFA@*&6cS&YRuItl/tWm+a*e\wNIc!4YN$$#EPpQlcGl
J$#BLk @IP?b6BZkQXR9PLiwWSA1+1+KYepK^yLl&kJHZGKDdDmCcCaj8G+G1=ElH%S%pB<nXAdVI8pieV=bkG\
Ju>!Np +tFKd+uwSe^c=LJCmCD$ntqmlu=aA\>iApK%/T@AE4EGLBdqAQ$VRjE=NT<L+hJBVhEEJplMeTkjJ&Kj
Gd\RLy J6DaeAK8mlALa+Za#NJk#IERj%GYTpc#Tm%hD@Ie<DuIHmFRQB+tp/^*LbbPVDB<#ZR1cDlc\VJ9<KZA
Vw@p*t @$SnEXymJP\wHkpeF!\/VH%TKu#qi>j/qkmIlc>pwwLmtub+n@lFLYqTL^RlSqW6qKc$T#=IucTmyMyj
##GAw^ 5JRcDJ/C$m#e^nSP<m>u!lFP8p\YGtI^u$CDnF#uGjBPW\4JIh^+IlbBMbTZAiIZc8<P6!BX>Fd?*MuN
>/SBpK y^<:I8XMJBel\R^\jXb4Zl+%j%qVh9tHh@^IjWY&8dc<eAYH\WTKTDYwJRkSq^Nq?$pG8$R6#ebmmWQ/
TwiL5: GVFMJJd/!9@#wTG5!J9#QZ^#ILeF<:hCLpBak=TkcP\4pMH#bnkbD\QImRk5SFnEh41tBw8tB6BYBWPA
XkNV&: ^MIB=IMkEaCc!DkDI^?B9cE9CeCj8wCaMQ5YjK$W/ih%44JdMp<BC$w<IKy^FkR^KYl$^hZIy#*e4D\k
n&S:D1 $>>^%qk4Z>S$D@LPME\qHT^R%LG!@C*D#kVPVEk>S<qC5P@Rt?CiiWMw1tDEcjk$wSMCW:QuP&JEKARW
F#QJ/6 T<V@9ASdq+Sk<F\XTNXk455XXKZCawuXT<apiWq8qyyY1Rpn1N>+%hhtC!e/&R8>ciH6wcebuY9c$pk!
HVbTXJ XaSJ/uc4mY\wlCYLEh=Blbq8QywFFS?LNMByWR\up<q\5AqC?R#QK5HN<%T>pH\=BX9LZIqhMNHSAEuL
YqX*R: ^TXubCaniDCACjnYTkGVE/4ecl^HGPKccbi+VbjX5FIX$dAE/m@AkdBFw1>DEFpMC>NaAZPCL5Il5WSL
#hD!K& MhT6wCFPLQtZ=Fw8kGFBSJFw54tT+G/BHNaG>&uw4RXGbBN9nJB%G6Tdb^+niRWnJcAJwXQClIkCR&G5
J4?WBX =8jP!IMSN#F+Lbu@%CSGdMud59^FdbPTCZ4*VAQmc*weJt5TSd%bWjmB!K&Ie:yZ&S$CQc$u$PBYbR8R
kc%Jb! K5TYla6kNc!#tAQ\:ekeBEt61uYauKNACB^t1^8SXuFdK<k5PH6e+e#MQkIh$X/<Bp$5WaKw\C6MMbM=
c8%NY1 DdV%%DCuLuGlcKlVRdXt<PjIT!T=iS$Ca\%mpTwGC5llBVb4apA+Gl@aF\wKyC?j>/K/aRF&RtXNZ%Ya
H=+kjY ^aSt^E+%Ge6\qqBK^Hl#B?MB\j1$DneQC!F%Iw+t/@i9=HiDaAmQI+k@/JP4EN<k!E8Z5M/BiJtTSPqk
/%Nt\V 1S=cYI8cSKKJCBja%:HBXjLXjGC?%=\aDdIG4#F#$<h:IVSqGBPPqb%C<q:?mqehDuEQM1ipaZmu%pu?
qGnwQ1 !PP\4a^I=EaRAm\aSI9AVp6GQy?GDM1FPt<\bBAZM4eWI5IJ@$=qbX+6CARt!MWH>CWtJAVWJ%4lFqZD
h6%*p% #p?BTmuI8YCQI^S^wZ^qyApQp?@X#+Lc*P=MW6$P5%DDGFAqqJyBtk!6an\W/=p1@M?e^8Il$ql9kR<%
h&pZAb e$K6!aGleB?iYHi+<@Vy\YR!:t<!*md=L&R&i</uQQV%m9I<jYJc<&bMY+Q:h!RwSwc=Rd\pZ$TJy6NL
Z69G=K ^iJp1PKEZPQZj/k6%PMVanKZ/YJImq^jeK$&b$LlFi8W$eX+k+E*GQeup@Xp:R*qV#a$>wLikH@BwlDE
K9ANMT M1/4KCj=MRD@RuEjkyJYb5CD+hYk4?=K@mChXp/DI#%4D&/&uwdIn&TDj1p&=$nq1qnajcWkm/>q+GMb
-AwSyJ 000d51b749300110334 Page 173 of binaries2.zip
8IG#Sl pd\!E^\4yJB9@WK?=mH^L%N1qPLcEl:XMi9Jyi\NA>KLmm\Lyc9^eD!e*A*q+a6^<6dml!DR#9HI%YaA
#u=p8F m%uI<DA*95dHeK%5F$B+&\@DDT^c+RpH?!aV?AQGQtZ1dy:J%!SC4HQ>byw4yn&!4yyEXFWYPBwkmWlV
D84FR* dd#&*Qlu^V*BVj?AXDGEDD11PWHN<Pdkc@%u8aV6JNV$k+CJChT$Q=kMl#jBqSCL#NepGQwVV/C5%*qb
%%*JbZ MBX/KIlkA?5Hb+5ZZI*XjIZV8<EjNlTD4Ym=pEwSynTWTKmX11^>JCiiu>@L4jF/9V?XGtkC*hj16aAw
ld=<+# lK<T+y&bVFAeRZ!X8:@MnXNjCbQJV@wiSuh:6W=@Z/HTIP?@ERWqdlKcB>+6HpLhYnSX@H:ADH*lCdGV
<!$qSK C<=tYW%^4qFAFT=5TlFCB#cC4He%:G^c5Bu1h:QySnV&id1SME/M<NXWDXQ#8lHhHhPL5GqCSSQRC/W\
i6J#KQ pX>^ZE^8MGYaGLu=NNh?ByltpYGE5VX#+FynbHTZcHF<*d6&wGmamtGcmE+Plqh>d/%YTTAhH!SZHEel
h&c1Mk Z#PcyaqB4l+BT^mRZWYR4VeqnVRWwt?\I\TJi%XY@qwG!*V<SbXXW$/u/E:?e\$BXn1aY&E>LIwm%K8V
CnG9&B =yZylJlJ$%4nPCnmWXNiAq@W9%bWiJll$B^4=WKiP$A&yHYiI5u:dNkd*IyN<94RX$>+/<E$?RERLGS#
me$&H8 :W<&h5YRTNFcDY1S9D?5y<4VeJP%n6n+c5#tM+PktGa>DiSA:QQtE<:Z:9tIJK!Qw/1JTmwNqyc9tl!8
J6#XhL NBh8>qC64T6<\#aqCpiRmWBCk4qm>y*Wh:&4K:wTtPF\D!GiiQ$XtNyZ^wJa+CdaJ&Y6AL*W$!5Ptdcu
NHjNJN FTYZm&EJ$n5k&dtuntK=L*WRYnKtQ+WIQ:<@>Iky%Pba!wSy5$y4&Mle5T@E^Hi9kVM46m4NeQCC@i51
4u#*Sc yCK#6WPVmq1XZQj:9iE?5M5BG5#G@X/@L>/tV\Ei\6hRpmW/RaA>XGyFe*uqawqBLhqeB\X%4\=Nq+*A
kYC@eq wQ6MKac@CR$G>!nA^?CwlG?QbuQa!KHSVJiu1<nZw*+Da89+TmtAu6IPJ^aSYDWh8Sn=L$^?u/1$Xw*h
>\eGWy l4hC=qwIFceKt\ST%$P+Xyll<W5dS/!@F4wBJ1a$NKlX*IHWcbqSaSW^6=K4Quu9\5GN\8Di%dNG5Q1@
w@X=dC <dH8?K4au1uk6pKpyZ86c1w>19SymlJyl+>tt%HhKQhtnjNMPHk>XL*c15Z$?u^M%qhDcK8I4jnK6iAu
dcuN<X H^bJ#JTwdWdl#XAKEJKipX+A#iH#5BSKHX?#<QIStD##DwVB*jGbtXMQqMyDue@%XI&w@1Y>aR:Lt1/5
PIuwqy eIIm<%G#S!/XcjSY5MPIdwZn8ddAIdwD>1>FSRd>V6dY&Z+C+SW\h!Y<lV9%\X$aIQteI5lYRXc>DYCT
4!Icn$ RYMtX!6<Db?FWu^bV%8*FF+c1MC==nA=DFSbwi9V=?CY@*5Cwy:tBD&^e=^J&:jm16ucSmPtC/R8&M6\
w1+A=H bN<B/#pM=FXl/>4!y8X?LY#><:C>=:BPk*:@*Xna/1tjkY9Fb:a#VP+k^pQl6Yw6wV@6%dQGA5>%4VbX
:=Tp+: Ad//Hd:+uZG/$G<LW8+=bRXdA@4bZkS!!6nBIBNMyAi6!6ET1><*neR6CVZNBn^<XNTwQZj\5QC$\+G<
:8^>ZG \TD5@AF\*E4+Cl&hiB=^pu!XkhlM:Y@lme4CM+XcTIR>p:5FyR5y96Ny@a!LNj=>L<bcy\1Dl+y<FGWX
twbp>1 $CYpMkjVi+lR8#ANJAdac?FbnA$:NkpNF$e+%ETDk@dP$EMq4Pik!e6kI>MT!LEXR1nEptw9>@A++iS*
:#lluK uneii?9N>t=<h\jD=EF+=b@ndSmp?CcMXtCTZBBtMAcaq1H!ce>dwYId6JdJ8h1HT6*N:#JKkbb*i6iu
yW$</Z 5?a>/TiR6nLtcniZNaYm!^V>Q4p&JBqj%bCyHddEnQ8#B=\R!#i+GbkZBIM!4?h6l69\!PSStiZl?m/a
FFcpKN RE#qLnCMDbSdlYiMWledk61y?M#ub?Gyj1mhJZIGKZQl9Rl$Fh%TbpZStbya<Z<Qkw6Ap1XM/Cu!L9NM
=R%&1i dRZBS#TDIGBq\4S$SKtHkl&86Q:M?\Th#jj@$wMj9d+I95PX6\&b6dIGGETReRDRL<GP?B5%TmB&/MEc
6WY5uq W!dB#/AIIa6bGV!ZG&F5l=c#C?h1&PL8%KkEn$ZS5@4bJQn*E4pqLnDXa4dGa1R5ad<tDJI%Ttn8pmXk
EC/c#a AeSV&tH=biaqtHQL\hKemiJCRMSk<P=@#qy+p$*Cw:w84hQ\5WDKd5QRX9lKRcbNEnPFkCA#%5wNEFdC
k5IY!t 6V:ZS@Y^!p&X+ZDnlEh?+=@PG4MPad1jwc\\!Z&W$c6EkT#:qtPFSCRH8n4Nn=X&H4N>eFF1C:Ptqw:t
=&h+ed nGGd6CG==Y8iDcC5@j/\$/a:\DGLja>c=+p%I1&m^RVMFA5q$RHJp%>cb\It?D@l:Fa8uNTG$\&pGHBC
Fj#aWC Yhp/HnQM?jJVD#LdS:TA8FW6<y5K:W^HE:?adwib#6^Tb&m\tcLZwhT&F<8DtML8/a\ZEp*<umW?>%$J
BqT$wN AP4%NhmKRLN>VCpnJpPt<DGV/+pEGA6RF+C%lREubt&W5?Gmjy/GNjnJ9@K%m%NXl1t+#D%Pw&lqdA%1
^eiE@H FF+XKX+nmRc?kwle?:pF?FRR++XY+Y4&e4PX<en<i/IXPh+ddh1wcJ8PS^XLbk+FMA$G4YX!wI$%wXI#
IBCu4? G8XV8cZTcGeGtt>!>>!l/1*?q<S8F*qS\8HWw1<m^e>M1RV8qa&9Ahpe@XjDlwH1?l%BSH?1JXGpG<k^
EZJ/N6 8l8E&IV9&qWES#M>X6w#Xq4n5%CdPMYYH@$IjWWFJFHeJHh6NZlHKKkJFXylhq5:F/%BXa!+pQ&n==Q<
!B:bF+ NH+@MVS4!Et?FlP>?a<Rkp%RqwGEqiR4:HAd$dZ*E!t6>>YhwakM#nkAY?W9*8MXjcW1p>1#\$4+*yK\
1YTc%c cC^XdM#T9am#Fqd&LTdPnc<c<BEQI=XdCKuZ@i841!B#tPtJ>hKeyhTFC5cVInT^BM6#SK?hA#lAH5qc
w=mkXJ hWFndjR4^BAL6cK4K5lI#GR8PDjYB6ptYTmyX!Z#XY1Ci*>K1qQqylcP^Hh%#wwMP?:SHa4+Y#5pa1cH
Gat$eM K<m6>4q1=McM/QFH/t8qNS*t@Te$VP@/j\lyIlF*9penq4+Q:$t+aBt=%J=phPYZ:CeSdcY?b8GG9L*d
ibC1mG GqVjQJhmtCDCW\6&HKZte^BFXWhV%k\q8Yq^c<4KK6Z=qZ#XwnmGYFln&#6ZCi\u8B:>jew+FeJ>:dAm
WeSN8i XQkZ&tFNXDBA@:>ZN\Nk@QGRF\L^i1<h?N1\^JBKT$I%Y=Im+c64uC:&G#HIcy1CwPC+Du/!KeWW%<GS
*&?in+ Ze@!X/LWq4PB?b9n5:1d1/BG%J9BBpPCT^bZ&dlqZd\caehcuMCqQLEbF8$aCMqLK#VD8!yKM4P5ieR1
=XHekY NMSXq4M4piD?u&@/kcXE5n5PBct&=@LEA=/=%abdMXtu$!58I1/%nY8:eitJdc!>V9JtljC%FNMKG@WM
WG+pQq Wdape1i\&&t=IuH>4dbdcm1mN&cX1wGmtQL6//*NVnGZdjkJQnW?Vqq=DY6#PaASC9<l\nH6MGwnYn5W
I=B+WE !>T@/9eqIy?+VEtYN?1lthjCne#KLWMFJ6>L#FRI41l#G<ICd\GQ6>dCBlp1+GCu$NmTGhBcEGA\dSNM
=aAVdw <4t5@6=#pB?q%#5LADlyFL&iV/<S9nJ%hj%^PubCLn&Z4FA>cX>GnF\LEXQyT6&^$>iye:\FTi*jDwc6
M%T#q$ P@mecKS$#F%1YV/Ft5>Dhj#M@q4qc=\ZR1\+t:6CVaeta<9@KKcy6qkH=5uBSGiQ6>Y#\8A4k>JKct>4
GGC#1A <!QNGX$HjG<wT+:t^&Kj5^awBD%SIcjq6t%by8QX^uduH&tHK$SCqmWH1j*?8D>yp%:=c+MSqcM=yh#=
uilucb yqD:hPHuCXRbH=G9el%*dV8^hYkEIFV8/DNq?Ht1MNHMhdkyu<*1lk^+k%<Iu*4ZY1NFiT114PM9d5j*
ya6=9N C4cld$Q64w5Qw4ELRa8wd^>1dSIWW6Zj+H@$4^k?WN@%!<*kh6!@GR#:TG^TuV+91+S\w$caV$ILT/c4
86ELGT 9k1pah8emt#B@q4=\*=m:aiJ/\J<Ba:IulW/VW6uqWB^jX!4ik:J=61\+Sm86eJE#^pF<\M#Kl^aLQAA
/D\Nl5 5cG<8kC^R:kw!+QwLAy#V$HyG6MNMyX:nE*R9=b6LD@8>%eD?ZA:b8AKu*NiuwS:+bHVQWJ8paq=Iq>n
A/Gc\# HaRS&*T5&ihuZj@dm*dmZJ5+n^9\W>GEytI8T=hQmTu4EBbcuK@K<@X:JyImVB/hCN^m89h>/Qk1>KIN
HKR=+N SRmXm%1ECKVp+lneqEuy!51IXtBI@!d/Yl%Le#tm4dSM+::1pd#RQ*FiEhG@hi$JmBR>eYNp>VFcSktL
MGw>%K ty#kKAy1:Nd/^HN6mK@nkuEP=DhkED56N&cFpW?6X>1GcKW4p?ey8>JPCh5#EeSM=RcH&$^iZl:KX@pc
4jJTN& QVj^IR@pQ5kVFwj/RJ8$h@pc=YLMip/q@liW@#K+Hayqi9h8M1TNpI9lHAMcLtmYDu5$<yj:SYq&YE#+
X1n*+j /W\<$<%LWw!N5h1ARTA!hSFASp85ZqTI&%VVj#F51BHkuWH?CB*WCWh=Zq<nNeKF!DD=Y1kAdXE<FKMT
Jn4yW4 lwhM\Cl!QGKmupZ!yqBY1Pqit&Gaq!mQ>B&+Ec9dt+F*=R$tjjy/*QQpHCYJ>yKI1=FZ#PYqD*9=mu#F
cd@$=K 9Bj5eFZ1ICE$TWY+$Q=@by^FbDbI@$<BJRSTtCpPy^Cha&q<yA*PwK!Y=ieISILBPyGh?ltF9lLR8TlT
@F4::j >N&9RVAaDIh^CA@!N!9iB$L$NlVkGGw66E+MTmA9\h=y^4\Tw:?:HZm4wVi&Ttn&j4p<Mbp8St=LQYYd
4M5wZE \eGNjZLim$%MuD/PXX@Z<Al84pQ#6Ihy?I\yt!u#VkluT$YI$@nR$+meNT6%N$L5t+nX1Kb1q1jZM<h?
b@p%&l e@t%PN\Kph8>9=a*<8ZLeB68C+Ycl@JJ8BpiukXJbdVG44$CjJZ+>S@aXW#\PLpbV9w\V#iCB6nwETa/
tb*\K\ Le*&tdIR#CI9LYcQ^LJ4TD#C/?6Sy=Jkt:c$pF9?nhZB&u&lu6dQlwtjc<$&d89n\BXcpW+PneuZ/Q68
@j^C4S BG\L8SmW4RDalE==@&#Q@tY$B/IQ9<mKeFPEh@Sj\8NDGC:&:+9/wC&8:bRA>DXSTCXRa!XGYLA\CliG
cIiNyE t8+\NcR#B#EMHH^bLQj&+CaN^GKeq6BZ<lXm9N&V$8<h4D^RemPbGYpYFnPPPmbGZKCXK\9pik?94>c=
KAdwYV lFJ!qMTJ<E\+6R$L9>BtdZ^ac$ep5qy*wDpINyuA:+*AWF!mKC6+!=wp>bXXEJH1:Gy+hT*!&:?=eXH/
56*b^d E<\><qYEIAYW6SBT+?&lEDPQI5t^dM=cBVT?:w&6Y=9Z1htYIJaTAc!RiWV9HcWa8b*KKT8!VmLCtRGt
+KcRej *=<=B!C?B6QA<K:QeyN^TbkkET4qD#/p<kGDFRX4ylJ95CXF?C8TLIJAFGF^N@NNLp8?H6^P9MFkMy^+
>#/kY= FwbpbZSCA1>tq:PIakbCIMbdq?KA9m1y6R+pmV4lZn6\p:8+Kpb8PGQi>Ak9m+d&8&uyQK6Yd=EPby$K
5/m4lZ k!Nwl8cI:BLCFV<ju<Ved4P$<Ay9L*VKy\L$Fl+4ceXh5JaZ\N^RiCjib:8\GNST+?D4+1lJ$*k\>N/>
%SMWRn /+<H6>=c\+?5\Hmp5H&1=bE6YLGSY%kaS8T+H&\IlbmGtAbTjb@6JVB9DtIqmlY?q1EF5aKtE8*BI*1C
-AwTa= 000ddc803ab00110334 Page 174 of binaries2.zip
k4%6ae @y1:Pb$+XunYLm$J%K9/eND&qDXILV^!h8*JX^+:W>b4=DLZh$nZI5<dY8kYG%h#>9#w5wC<@99+/t4m
pmE!X@ iSK/*6C:Fqu\XFYNV5FwmY!4Vy#9cZXe/88^=FkEa:1CG4Vh6u#hY!Yekn6%Gw8<$^Q8NZM8Smw!tK^c
Gj>MDe mcNJPIEtMAIV>+qw1$Rw\4N\LM#$9LH%X1&>6Z#J&wQR8R/Gp+%<IhRGm+A8qkE?$EN?SJ>y!dyIjn8a
nYmqL% *A=YcFtcDC&JYTcIawn\=VhE9ay$Y+^lcX$8Ec%Vb>bcdB<HkB8IFcJ6Jqa4S!KEV*T9#*C9KDcKX!kB
t1ATT/ jMhD1>EFVqt9LLblM\@t&eqZJqtL<dAap6K^$Dq&BM6@$GpFiwZa!RTM*hbdh5^d?9:IYuPqYZ>9en8b
cF8:>E wC9k%k9E1IG#$+yVMH^CYbKuGEMT\:hF/@eCDVc%GE9X%*n9TF%Dm8*BjB@JjYc8Tb*4<!EVidpZ8nbl
Dp1BV\ tGuiZ:GllP6QZLq\+pR:lue\RZKwu&MWi$M&L+#buCL@%tR5?5uYR!>a5+unduLu*\ZbRdBu9KDIWq&h
/KZt+w dSJ6Pk^8^qiiwQ:BbP$K\JnSm*V/P=HIWT*BYASWkIt+hjcZCHBKYJk*q\Qd=I*lGE^lqc<TS\MdE9pL
SQdW#1 lNw?whj^#:%%<K#IP=lpbyF:j>L!<SJN%PmQF@TjT+T>KdidVP#R&BG/%5<DWV5BRLj!jVTZni>EuANj
ICPC/: DNTlCP685L1c$8iR4*<jD/@G@dWuh&cw#T?l*N@q?eRS!=l<FYLqFYH?68F:G\k+w9/AF*AdCZCj%@/&
Eb8ymN G=^pCkVb8+%Y4+:HeIM&yQwYVTT5<MC>HXSbi>hX:aa<Gp!jRX5VaF&EteMCFXEqFBSTlK@qDTemqpN=
NpRRB: />5JCFnjTRC?4R?cGWP96QZBpK?L4Q>PNFWmX>RXNX</^dVKK+A@Ikt^9?M^d8ycPCii6pCPk=&6TDnF
NAmJD9 ZL<RW+V^yBa+^c+Cul^L\KZu/dGawq=RQw?bhBTyF86i%lQFln&&AhlaXwN?!1k/LA:Q?X&\*jlWVbLb
TS/ycG J$9qM:/Y9>iDwjnL1@W:<FW<pL#pXwIA>c/%>X/YlID:h<QJ:c*<9qll1&:emVqeNl#+a?PdWCE@FpLG
E&ECZn ay+!6qN#+8aX=WItDGLEPKK6<m!@SeS$^Al%<kN!E>M/$IH6A^1@caKD8:C8MyQknX9%w?$iWeZ8WTKl
Vm!/Cq VQk/Nn$XiyE@8S+M%6eTec@G1M1IZCKu5pcjJJJa$%!N5A=D\ie\?*V\4wVIAV4S9KGq>\V!$?We+/Ne
J/Wk&8 5an\iD!klFKI\^nyedt!/E\##dWcY\qB9LWcy/*dJCLWewycLQD^YVSDF/HEG$=AwwTC*J#b+DFd!G**
CqQK4$ B5d+=iMm&T#1Vdnbm4Ehk1@KTkLcc:AYTh:?Yu!ttJ9d8/84wYk6MQKmt?ZV9ASH955%?*k<:=a6EA\d
BTB:HX y4uEytBcw5Y=EQ#!XlBpMXETT8==8>A*bu#NRc!9yqEled#ZQw^a!$HQ>Z8dyaNyk1/KFD?J$LIhSQ=h
LE%BhZ c*N<1W6bIt%\RjJqW&?CnIT?E&P$GkmleDpD:e%bIY%$lTVDTmLT>dZcuEP=Se6cd4*lj%N>ni8J>+<*
l/$\\S /KdEZ/&Kl65n?lw=qTyBn6lZiTW?wLLdeF1kBX8+Fb*SQGX4KpTG^>h>MJaS4N5^^Z#A<XQ=%G/GRYqa
:dm#ld KB*jVcEJ@/La5GjhY4c8lw>FuG\P\WF<<Ic?STkXbS&MRiX%*^+m^9L%T4#t6emuJ$K<8WMMQ!*hXmZm
#WEdBl aW!JX@Xc:QXkApYk!\ua+b55t^QK<4DebTEm*F>hm&1I*aQjtW1Ml%mJ&!cRB\K^BWS+6RduLZ=qVyth
p15AL% &Y/hl5:/I15TZE@SHZ5<KKY>5c%ARwaYq%YJ6#pe/kMC6R$>#qyWWymH:nq>ZQh:\8N?@/wQZk<AmAb*
^\ybyd a+HIky$PAw544T$4H1dh!aa*R/n4EHlLK@6*JdcFABQSqG*n\q6h>%dZ<wCh>eQ+mdZ=yD14j>Z%ZuJL
:Y\j*T B1LYSQ?/&M#t&8S%6DQHWa5:yIN?m+EF4XN4PiNIC+p>XQq$I*!XeP?&J?=ECH4$?19H^@:%>cPI<4k*
h?hG:F \N>XH!TQ=h4/@ejHXRAEFWk5ytYPm6MBnF@qbtbieBP+=u%4cpJ5K4m?amiaaIi%TnBiE*b&!!RH1D$4
PuqDR9 5KIEd:jm:$Sl9Ee1LLM\i>9ApJ!Ae:q9+cVddqkPL+@@+qBEcW6\EwYX!WI\5EC5PlCHE+\j^a9i4ebS
kCE#\* **5+N+Q^\@qFyQm^h:*1>%=/@i9X?Qi4/<j?1qq?GwnCnu*^^&Kh6na@$5:V@Z*>L4kBW>Fj1QqMhykL
/<aHnF J5I\Hpphn+Y49Y9l:R1MFSid9\?^YKByWBQkDJQ\Xe!Z5HZ5I#>BiKF#hSDk/IVqCKe1+XkpG=GE8a6J
Jpt^KF J<G%Ld>kJ$n>ZJXQV:uw1qn>aH$ZDiWtQ@:?/&C%lL6yIMm@@>S@?NV9N+?QD/8dQ/+ijq\Nt9HkVp#^
MCt<4L Sp^^#i!ENS5#n!nCkya#hN/lH$$n89%GIhFSB>n!a4@8k<\XyJmYPFM%LJplLp8Ncda\%mJJ8yhAk:ya
K\>dCl ?e<lSP^?\ZRnh#b^KX>mFdul>5p%4?8m8aW<+VA6kti=<S8JT<eQap*ijQw<:u8SPJ941C<MjZ#ySeLW
q#8KNX Q#bS5^1<@jVR9:=y?6eCu>bcWNl1b\eEC@1KhQqcdkSd&lH*c8MSl$FQdQGL1#!4%=Slpm59BmpP+=lL
>ETHYW 6=aN1+C69w1=FkdR\hymDS$!B:w?NSXm6SQ:%dqD!##4hXD1GA@!jPYmPnA<pXBqe!iWmq<a*n%iZ+*H
XV+Nkp !^e^\y@p:w\@mh#&leTqWQuH=w>Nj@Y&iit@/:?Iq6%=h?PlRJTFG+K6Pc@PJkVlJ%4S/HY5<%+wQGHj
#Zk!:: tE:5mwEhm\BVmwZeNcKA4Na$VQVK#niT86*/Eljm=\BP?h:Yc*CaD89H$LCPid?#MVayN%4ikD?j%qaw
QYl4Ac lnXiQB<PW*d@A\iLe^w@QK/Hd<:NYml<@CR!LLcy6%#?8H^a>Z@@<98Z*pDWYM!XjQ?8L<nyDwu&R:nR
ij!R*C S4bE=!TQ=j%p8Bt4bSKK6VFT$/Fw6SEBEE8$H9jWPIpR>\AwSCGSuWA&HB%GPdemmcm9X<B1n#:T^F#l
BHjaPj bn6EhC9c<tT49elaBn6+@AGVT=1$4k#4mH#DLGFRaCl^/YT<QH>h9+ui@8l=!@QLRQ::d:*^\^?n/I?4
/P:/Cq Rj@q<Z/%i99!XqDF?T!&/R1kPN\i*DbA5<Q!BlLpVAKSZqHbmdjJVIc^GwZLKXlhZ6Qn>M#9\MYGW>J\
5&N1Cd %I^VcWpaAbLmk5W&:dq5k1p%>TMSB^yjdaeiBnk4%CKbmkA$41!mYLqi>pX&CDcd#TRRHC!lciRNSX@H
j$jJQ9 u@1D!BN>dRAtw6:=$^>@:A&cB@G8j%#>Hub1nBTlGNt6!H/>PPSV9Z&@$A:H:QIik1>!P#l$JBGS/Bj=
D%\6M! 1pYeRq=hKTXu/ZdmeMGc@atXhh*nJEER9N#cmIYHdhq/\5T1Y*nDNV4Ht==4p5kClq:/RX=XJDkDYkwt
G&TLY\ G+9VQq**^&<i4=6^*@T%N^DJQbQAQ+4$*4#><XGi<>L4*R^8pJAJmpI4!:^@llHHZ1BMZcPLu%kCE!HC
^=%+Sd Btd<pT>N%$4uNSXY4BQllF9%\NKwMuaNiMYw46*tyAt8c1tdM*T:==J:Wi+NSLA?!SWwdJ#F@N>V8VmE
Hu=5>6 >X$k+m9^>%ymhHE5*y6w?hZ#wK?@q@@&H9=6eQ/^*@S/d<Z/>9<aLj@6b6AAcEm+66+WRd$XjX&wGcB@
#PR<pI 4Y5l<w:RH>qHu!&W&EcB/BGhNEtJ+NZE%:TYeIJWCG^8nyW6llTu89dEh9HHY*M/&18P5ZihLLiFN\$d
+>m/lI tka/XnCqPhRyw^LVe8XVXt=A1lDcB&jjuM>j^&@Qb\GD<pIDuC<<EJXh@6k:4@6@QQeGk<@u=q*9S4=@
@M1>k8 i*8LEVlBSRhW&:t:WGed!wW*DIdwjR/E&EKV@kJ1w8Y=el&wei6^KMuZMLWFJ15RqKkl6kXhlM*n<cm\
/l<blV !l$1HA8$pmVe:AY?ktVS%<P6Ij+ly#$p:5q%WnXl#XnAaSaWe9N9ly84%SD6><#AAQ/#WD#w>=nL\G85
%qJ%J% B6hC:ABB\JX<Ibek^EwEIQ4I=wJpt6P@^9Yc/w4RFdPAGHjNwGJuZcYD>kKc+Y814LNPWFk$?+G9LMG!
a/?IBI bRL^EJ#PYHEV1?9R?GPFhRE/4MwFCW%#&*PqHE$nVnM46:A:AbuGDW#\#jyYRne^:tNNHE4<!wI+BlI\
b=hwIe qaCYR9\Hwe/1@$+RMS^FH^pKphDy=tAJ4%?\$$mR@*An\mLERt5l\iGEdX4uSK5Ck6FWZXYI<Sjp?GkS
Sl^YTd EbtLt5yq\\Z!?$^i4F%/&QwB//VmuDY&BnSejtG/m4y4N6WEt@a=c?@8ku!h*HpVcN?+Q^qjnV%N4K$%
qi@\1w !8ud:/?ajWVL<=ZeBcG$L/SiZZu9kpt+aXd<AN@DYcST1\RREW>HqhY>ekulEc&XI5I6Y/@hJ#E@Sc:L
iPDH/c WW?9FThA!FntaKm86qFVS*!Q&D!L^abAV/IiC$j1qVYKlJ9al6>$ZA+#Ykbhi9%*a$ce!B^!<Faw9Scd
Z&\XLL hw%kSJ:TG/#pL&RcqM8@1@:/*+8npleXmCK+?QkE*JVDNAWBP5=<RS5Vn=&RAjDT?bWLBp8W4BA9>Z1t
+9n1hR 6BwAnMebNEH$FTEC$V?dju^pdT%?=iI4iQIa?&qR#V&h5bWuPtktnT*kuG/Z&%8^1FaVKNdVlVnZ/+kQ
C6wQ$Q <TV94kWkcAyS\6e^SQj/<iH^<jHVw@JX>FXA$/M?XwQdG$@e#umIpXPBmnHnHBG?mTJEehZlB9NlcJ5W
6\k#iX H^GljLHkBST?I:FFE!LEAmh$6\XC9:J$6YcR!mX5NM*YFZY$Fw<tR6Kt1ZVDAJRXM>9+pGnne&/=9\Z1
c*WX8F ++<QTm#Ep%4Kcd:%aCC^>LYR?jn\AGI=FeC+@hPnpT@E4wVa8!#aCQwTGX=kQpe<!nAIlynKCFAI\q^/
aj9Z9< pB&=iXS:5YPkyyW#T#&Nalu6dDY\Qy&%QX/:8hbI491c?1jQ$Xk=+uJQd4!ypqcC6ZpaWt!n%6al81$Q
D%ZPn9 \8&^<SWbql5YNNk6ih$j>Fcj?Hn<>CD$w5<a*B*kG@JZ4lA%PMD<pL$Wt@4\N?:=AX@lZ9*%EJ*5HKDD
QR=C%p >qQAJkHlmyyc61=eFC5K1^%hCecuE<$*5ahA/%im#96>8*pbuXDAT5^NHC\VReDEKWQenq!*jimnEGLZ
</*Imb K/N%BcbBSnZjBAEGS/MHQISec1$a+J=RDq+LZ$Z\d8?8%5k<lai/Zp!y4<@iHdei/D!kn%GW@XPJNana
&46DP+ $+!pRkE#:GCER^PMWyFLAmLt=pY/GHRSmAS9ZWMmYq<bLiuib$$&4b!&B6nMYtQm%hyla@*<qGNY%9E%
19C6=y /9&8D#Fin?FA\hb4C9iDWE98QqCK@#!+F1cKCE9eLmJ>P:uCwB5ZZ+lh9/X@HTJhwRPQt/G*aed$YCQd
$GjNNK hNV?8^Ct1hQZc:48qRD<:bRnM6GTK>Nhd\n4#T+9wem@1quLnSSALZ1t4WPh6\441X9IYdui1c&ay9Wn
WHAdIw KFwK4RP/Wcd=^&D4+/j&\b5luKVHXW=@EpMMdLEma+NN?TTRW*jj4INJwANWR^Fn>IJq$^lCh>J&wKJa
LEuKGj K$Jeje@c5djhc9%KWKK&EENB4auAdj:WyKZ\Zy8:$R>\/:S%GtkJQ$BVdGp4=tH9+kPe?tTqyEaWWSIL
*e\\44 *+4+yu8a*lKX>IVZIBjNaZKSE$Ejp#8jFe1EYKKA#^uC9acVIQP+NGPLjT6wIW%aWW<h<L>YHKES\E4R
-Ajaph 000f3ada8df00110334 Page 175 of binaries2.zip
wY%%D6 BH5:p!YdmG6h1c%hMJcZ&GPQK=KFYDpe/aDj!kRa4nXpy>Q&YG9LLEDVuuAmjF=ph&NR8w^iiy#9a%bW
Wu$F\n bNn4QWT@jRk4B@*j>TQw<CjMjQj@jDMa9EN=b+NtlYuJQZybmu/KaakJ%kqtYWZAAj$nhJm!k:MaP<j1
9IAuLn @9dWR9tIl6tB!jGJYMN%JZc4K=k6m\l>Qiu?@1DjG8E\+Llwh1\VqYC&5$Q%+$PYdTb*R1u^qTLK=Li<
GRw?X> <Z>Lc@SI9nbC1LD&EbNnkpCRNkmG\6lNQq%lQ?K>RGSASF>pP=#+YJ#lV/&FqC%yaywG*%F1\FnkSKa6
<:4XQ9 iBK8m:&&eH*dNnn6hhF/4d8#8VjVLRbElNMQy#yTh%eu8wR$wZjX!cmD&Ml4y/<c$ZMkVB/QLaZLn4GE
h9WDk8 mbDlV<yZIdZj@*MkIh^hWNVK%@n9E?kM$CGAp+jBZuEtt9ZH8EAeF+W#96%D*e:&TSiBNkIqy*q85e*Y
+QPYSH ?tBmDwTyG$uPVRT?Hy!!D1:/AhiX!4@nWiP8Ywi5^b^lmPh8<lllB%ZWABw^1mG:YlHteccPYNIu@*6+
P1iewN WCdL$@><k+HhaFkE+cLA#pBCCaq#JtpYCE+ewne1K&p+PaMpjL9#XldlZF8CVaM:5eRll9B\Z>lnuG6X
B:Nw/T y<C@ZBPL+uSm&1Vq/!61pXw?@>*k=tb\b@PW+bM8c?eTFjc@mlqiFHhbIZ^6<Nh8n:G%FiHtyZi>dFwl
45X?1! F6*kj#:b@BaF@pd\PjKuS?+M@D9ul#LWREJBFH855>TF^1en:jA&Lplwn+CyBeVE^Fu=^J#VK=1R4R?@
+X=ZTF &C6j>VmI*CAmYm@K=Fq:I91@G$#85G15BK+=/8d4&palF<<Eqwl!lM=GdJNh8@#B9d=i18miZ@A6^>qQ
uY1Yy5 ^qj+*WeZA9Zj9i6L4ISMMj^4LGa+SHpiA=+RbR\pR#An/$YMWXF9w@S4=**+JbIV6cctPA98nuFA*>yY
V%<@am F*MD?%ja*h=kRyW+GH+i>YC&lIl%+uwuVMLbhyNe#KdE48LXI=C/nAl#H+&#jdC%pi?i6ejN$dy!jBY*
%^J6V\ I@D@<SHeGc#H\?Gh+Ii<p?FR!B!G5FDeQI5NLykwaJl%&L6pW&@qanyZAjAq$KRR9CdYX@9><uDD@5I+
p85N%V #6lAkt@j9Z8H=AC%qXPpYQhS&:JKLj4HhVHhdwbn<JWcK/^ejnJ&QWRN@@?n@9hCaXiPdnXSn@A<N?Q^
^9j%8> 5Ml1*Z8yW&G\\&n$\e+MQ+TqEKBVcZNiMS=$=lh@HIkTqJlyNuiy^/@5L+@V$XpP=M11a:XEJ:LaaK#N
p&VABY RX1R&\1\kmGaQ9GRHc/b!4WQXJA^ikd84mPiKeR6ijn*&CM+IpZNewYK%i4^5/NXjud8:DIkJI##NZKK
n^T*em RSGKDPiXYwk%jI*aJw@L1Bm>mPHpww*C\6iXSi1P=lXlI5Ma=GF1daS9n*HI6R?G^\cXHDI5@*b#e*W%
DkyY8T ?R@D5T//$c%H+Z9PeqwLl@biqiGC:SFLCt8nP\GdJSjDZQM:\t5KMH=C\AG?@4qy\SVB5mn8/5bdV#dm
K%XJWE YLAdje?%SFptWCKaaEkbC@JkEJtZaN=e?H1l1=&LBj#Q6AYVe\H$m:th1lN*/ww\B+t/+?VQiC>@ddQ:
nmyX&y $\#Jl?j*iyRBq?\qtEtGLP\QGj^4T!nW6qp!Kc\Tnc>:j\TQq+18HpYZt\5pBVq?/N$MXmmjB!X5W#Lt
E/?j4p QlPS*YFYTAmda1Ec<::mZ+<\VwLq?/*CZqkuwAp^VnFLR^IweGT#a&^5jiE%%!I$eK>GyA*//t/GIH6j
VdN>AV eX<C69atPmE89*RRq!n?%SFK6kyl\4#jL=ZLyFY=Tp\Bdi=wjVC+&B6M%5H/Lq!I9md:<E+Z*HkCFLP>
lIZukL ^=&hkLCu5$+WJPkjwIJcH6GquBm\?^#e+lqW5MV:n4F&4qT8l>#knKyu6+!BK^yEit5JZi5AhT!ACV&X
9IY\9H lb^h=MDJqGGqXk>=mESnaZlB6ymtAjkKF8M8CP&D%RXjH!nFI5VD1#FcShl:8YcQ$ZDC>dAV=mXCH4DD
A<IM9$ Ekh&y&@ZLXT/@p/IX!9q1=l44BA8!^a/KZe6#MHbD^V!nY$?CkN8G5MiV/H/u=md4jWwHNbKPR8WdTHD
yk6b$F %FkqBw<ZdGAkM=5j!hhqbKa1?mSt/^^>V/#A^S8JAwQ6Hi5=eV8SnGnTZ*PqMma5w?Wy1ZkRD9MTVt/@
qPG6T\ E?J4Jp+=CL6p6K5L8W%h6TKb5B$XHk\VpP#K\<RSM5Am^5>l<QtpHRY%^ZSeqqCk=pwbSyqk/S+m^H<p
i=e>p+ /e9qT9ZXCduw:>YFDK5qnmT<//@8$LIFjc&=mmkRikDDJ>n#Zk\4Iy&Gp#q^9J&$CNm=HJe4S8IWw*5a
apDb@X $p<apDq>ndWm1SXBkSKI/Ln&lLw/=YnmM%a<li@QZL%pi<W=C=SRlwY9WNPGB=@ba>X:\Lec8l#11@pn
6c4E$5 !HB4t^Sakc<@4qdw!M^!uw8pE%aAmGA9NmyuTJ6WCciJhRbwjGGcPqkBR/#A1ecWQ5>L$$FGP@TPnX#e
&Yujb@ PS+^5a/d?5!^V/\aFqJ^WEH=H19T8GVVF9IVKS/!:iSSY+l=\4I^h6X:!&<bZ&t\XI^Flt?hDDMtiCCC
!$!Eu4 /1HhJd\L@/b<%X$%HkayJy+QQD^F^#iRDwQJeI8pT^9ThbB+lSD&Qi#Qk1p+*ShW:69DDHEaCbeju:kS
QTe*GB jQQ<jNVGQA!6qJmDLdMk=!E%PM!wXAPXCEa55MulVm*8ihX@hJ#>JQTS4&1H>W^6nEKeQ<pXh6n+e^Py
HM!+M* Ji/@8$c9iAE55h>pcm=R6R1aAm#<J=\=eAa?pB5h^64\+<^9&!Mmu\h4NIpj=b/eVp5>+a^n%u4tub6q
#m\\KA +&plEmGRtimYyluG5kFS+jKP=^LW6uqJ%=lMu<46S8Ie*XY/AqZCR9uQy@+j#?y$+G5h4Z!5B5+&!a>Y
NV<=+1 u<$TZ%<Q$Z6P&*Ve&5c@qI$TKjdSn4YVZ@i?q5kQt<NyK^$RaYRIaJ!taC^RaKYLA6RYG=cI>W\?WRmS
it@$@* $k!N@5@KX<\&q@R?W#&ZkGjB5D$D9!N<FV$nA=eNXFPd^MWR@>:EGZ\haHE/Ac#EE@&4j5hZMX6k4Dla
L5!#E& dNk1+F<q#uE:\Td$<CqtZ4BdFa%LHMXEe5$#a&T^ZBeGMG?c/=I*uJ:HuYnM58*6SLMabqnWNW1Pm?jy
p!R5y/ <^GdnXB8^YaC%hm:yS:d^6W8cD16/lmVV+KH8TmdjP$6hS@6T@@*T4S?%&W5RQY+:@#4n+TQu=lAF65$
GRGYM? Ht:&+Ry^#kaLG>GDkZ\@D!5w@GqiJ##=D*MNidt%@HBZYhi+Zi/w6<=5SXK%=Dqa&GjASVwaAWD?tKil
*qinYb wM>H4C#/+NEeHYAqRadlPmVZeJSYlXQE5D#Z>nnKn#ib&mcnhetCytnqtaM5mAS/A%T\EMXi5!nb8=Dl
i!VB$l c@M:9iERTca6<@/G&EK8XR*Z*G1@SWQcYejECj+Hn1*ZZi:W/<5*YinkAV+5m8mta=:\Fc5X%1*PAGFH
WPGkIK LCKd/6VX%Pw+*AQ$V*4eBF8Iyu1+aIuFK?8^?y\GWY?EE^=El984<^Ku1mC>!Aki8iFi@&1\886QGkWY
BdePl6 Q<y*j1?&/jF/MNu++VdDH9k15#&PGi^^^tMbJ6Mp^@V$K+?D#AETL*ClG1l?=tpuJ9wt6HNCBPFw/%m5
l*eA:$ *Ri6ZNn/H8G<A9E>G/+%\n&qJJe<lWIeLMWjl!/W6l=pIV=uIZ\>e\e6?K1+Tc#6ABN&=DHVLw@S!!QW
Dw*ydq >Yw\YK&cy6ZZ*$Nd+aui4hGpitD</4a$Vjd<T1L%!Z/DHq=5aWF/EH#%it%^R@ZXu\\WXRlKbPIW$Itb
DanqL8 DIy^ZPe&Q5%De<+$$kpupnCmp&ESC6c/l6n:W?4bek^$dXFq9Tm*+ibcSSk=tG5ii\1?>n?jVYMS9D<C
lIaa9q Mn:&$P\:>QyuDRXYnPmJuB/9WJR4\yDueS!RH8A!WkIuVmBtYE&C/$P*+5LASF9m8Mc$ctGJ<VW1uN#i
I8P+4P ^?!Ec?9ELl=hHa1PCl!HAJ5PT4FNL!SE%M=\+c#8NiiPJtciK4S$m+%?ZQL\mWkm<ki%VihQ@i5@+t\Y
8lA?4d =jnnk:JdA68dt@HX1qHE>Gu%?GkXu$?m4^K?Hk1iFbVbVkCdj5Iaa9auXmZRKk$1+qCLX&%J5y?B4j4%
**y^9# Gu$VQF*5mQeqj*R#l$%eqV\>\?*!y5dm\BnqK=c:q6quP#P\QLyYW>Fd+i8a/+W^Fwwq&cV&j8Xhu<$R
up4tj4 $!GbA*45ii@Yp/c^WKCF@+>Z+#FcBiBjWaYDS\<BuLnY$IjP%5j<bEj4+1k9bGHc*E89L+kn9enDEQF#
NjR:G1 u>*=NZGDq%\V4Ce@HB5>8XaphEyLZB6QeZaKSl!?NI$hcKwd9<6pYt:1niM4mPZRtZ#G1AbyZ==6L59\
PyEa$E %KQR6DyjbMhXe^<qwA5&&Sa:W8wKM/QW%IKdk6QCA@muV##ywWy:hpydTk*deeM5dR*!iK^NZi^N$=#!
VYKL>C hGHuk8tGYIk\55MMt5BZwY<Q^61edS&?X*p+an8<LlJDKZ\L9uJ96NJJ8qeDd@#&4QG5SdWc^9?Iy49G
B1>Mam aujH%+hwNbqk64QM6F?C?<l%<aB<<KC\tbqXNpJWuG!\eE:M8<m+q\$5u8&l$Wqm5Jmd&Vuj#qpCNtZ6
ZRRcQj pdIA<CjdEQN^<<I^bHVHVe\%enEQh8Be\uN=E#S#^aikLMc/\d<=//b5yQuSIDLY$=VaLcXkw<EQBGe^
w<TJ<\ D*ZJ&5jXWQC?PHHEPWSn#&S5^w\6D/Maw>EV1V@wED#Hi1&aCW6X5>SHi/JLWamHZZD*i5&Ju5lPGhHh
G&m<e> @6Bhu89bcI9AR5A@qn!KA6p8hP\RKe>L*ct4Vh^I@R9\DALI5BtmlmJ:jtF@!JtM6Z<IaeWZDi@G\jwe
al=1^M cRK1bi!u1+q+uCLel6w9<h$1twDHy&kQ\jKpY$Z1A%AmNbZK/1>DIh8EiN%Y5HRJQa/N=uHj&1tEPQ=X
G=ucVm 4HDCk!/^i?%I!E@nn=mHcTi=GZw\KnLF:E9APQH&n511ywut/j\nY&Hi18+&==c%b^ViNpQ\>V8NFZXF
YS^Xw\ +?!&Q5API#HBPA9V*kVEli@6he&bHt!N$W1$i&91GZb/9??%TbtiGPIu/\<>qlI//lGYZLLHW$I1dE$+
#5iaTu /e^\ZGHbPWNaY?CEjbH%kWtYSG$%1kRlE5RHaApV*mZ@WIVHu8<6dVyY\!C=I%<u\ZB#F=\%chM>%8n:
lZW/?Y L/bF99?SjY8ddK1nG$V@laeVD4ERm&qP:n8N6&KeYQD6>hib*I:Jhc@6%@QE\::Q*VLkp//pYB#%KFeh
Htk#1! cijbXEllqWRVW+JTV6QX81JaD@nm?ZJ/hCDeVum+e$bamV&j:#$JVedi&qjqNdYX4+d4#Vde*qFjP<+&
bSPJ\Y u+J\m\$qJZ#PQ>RE^Jq6b^SMn6Nn9JTu%?PpIY*/PYT8e<XQ\hnCJb:waa9&DM<n/?ee@M/Qhm+<e@eu
>Hc&9/ *eAp/19dwt$yJyQE<lhNi\^&PG#L698u4BRbNqLXMIt&kp:$&d^qy5IPMnmjJ=5lJmBC+/6^>l\JQBS1
t+hS4K N*qYI/dLn@GGb\=pdBkSi\^TjM^6<4BuhnHEae<%Tp:ELtZyL&*W$$P#eJc^IaaL>=wqR:Vn$R+R1^Ih
Fln^8M 4\jQlJV@m#A^XJ=1!WGR^V?h#*d&PJ+W<&C5J+q##6<>G5>jK/tF@>p+!<hchLY+!>+H/t@NFb$dpi4\
nqq&RL VmRaG#Fkl*PBL1W8%e*&G5FtcjEu^K<CmQYp6<LX\u9ijn$yWwH>bK5C1VH!MP*AFBh>eEiQupZHR:KV
</d*QX B1R#p<Sni1i/K^/iHcI5V5jcKbCIKdt+V/#V>PE:WtNMcGJ/Da5Y9L!:BeP^pB1W&!D:@6aI1ZIHJKkT
-AwEZq 0002cb61a1200110334 Page 176 of binaries2.zip
*!=X&R St^@^FqB^/\>ya4ta4**$u$I4+l4ll5IuAD*?&K&JJ4*P\FtA^9Yy^#$iC5^*Gn:d6\l#V#Jd<th#%!K
j^qXTp Fi9=BG^/%=kPGjL*cI8*w#?=G^yDT9Zhq/c#NPlcK:^m9Bhd/LPJT8>E5>/8RYwiVI8:mEi*<4HadHkH
6Y8GtD ^DJJ&B?#l!DJPX^5&\y4NeTVnN%ZDR?M41%>G^&:k11\uESnHC$F>PX&b&:4Cw>/eajb/La$HDkY/T=9
JjE*+\ JFh+hBW4Dc1\MBH%?^PHP*l@F9XSh$ylcuBVFPIjMVtP?Ti9TQhnLuda:>eyF&1I@+MA+<Tmlbn8IlC:
DnACLL G\k@$awwEqREIBW&l:&Z=cHhQ$pG+&nB\19a:$@9984bjHY@S!FKM@@cJa8%M=GDTRe81cQa51X$/W=/
W/%<4= ^Q\eE/iw=qa+PaY*N4Cq@5BR8S=e>cwuE\NR%M@aVynXIylFMWSFDb1cF4wLT\J1dLHnCy#mDuaGAHy^
%:+diL tKKF>qB5*6@hBhP6MFbMeBE?a<$Y#:81aH&udCA4tKQtcypneWFVHh*iN$\m>tGmSaVZF?%PKGAB@nN#
>hbl!i w1N@WcY4VbCVQ&E<JeIS^V\>E<tXb%ZXVBXYi<I=DKBDP$e>dFu$Xm=duG!BW>G+!pnwTnGj!H<pW:m/
qAeRb5 FY!>FjaHcLC5F+9<@j6y9uq/#DhB9eGTCh8yRStPc%5K4a*?Rm8Puy9!=GK=<I!X?#=*j*w+WFJ8=*:q
E4NC?5 :BKSE*MVIReh<Aj8KmG%YFtJ\?j$pHehC5t$#BHcpTRIiLLuRmDIK\>J4qSZ+RDia^5VPn?=4al$:k9h
ANJHak !LXZp5Ht4dB9!9pALPa/HK4DhLE=!Ij//c:iHMKDMQWyB=dAdEP>EWQ5qujDPAEpdmtK%hHYnA:/::BQ
JukE!E MC&W5%$1lqEhb#1+klpJF<=j<?SEtu<SDw:SYnQ@RkM=y/&/IiZA8S*PV!a<?y*IYM\hh?%56$XY6K%@
qb%C6w Y%$T^YXS??%G@B*&@B!\L96R9V<ee9t\mD<FRt#AI/&j/*aYTc+T^^m^\lJPJhdcI:5GQA#*Z9>=<PjB
/C*knD P?&&Yjtk6DAbdu6FXt9pJ1c&NwYtBhTiI\9FVn\dZGGVWE^T8b\&tMBAaTNmSquZYT^cJm:ZFSMkF%^8
XW:Cn= c=HSQRRbi$ueipVhhyd6ScJCmRD*&KShQmX=hamVB/G/Pm\Ein$j8C1!ntQhLThPb&4:wLY&+\6i+M=w
A9H=L1 8hP*FPHd\Y4\dnAkbwI/6/*@&mQPpuMe/9ckI:PKEcDl1=*6!6NhdZ*5RpN$uthSWG?jSc=QBAGJ?FmW
M=F*wK 4:Ck$qaFq%m&W+LT9dWTkdF:@T>/qAWC=iEYw>:wyMHBni^Sj5nj!!6Na=eV19Xe*%npAC/h&AqkS5kb
ANSISA D*u<&?uR/%*%X4j>@tDw>dFKTB!5CQH15tP9n^$LbXc:%&ZcmKiLN?k8%a:L84JVP+8yyT%NnQt=nlKh
hGIZ4W ^TIIAjeZGIK65CPm#QM5*+j=ScPnMldECtMZ\un65H+1*jH6nCQ!KYIJ>y1I#tJ9CCR4bEyQ>*iZPJ>a
wL@jnM PM6ntyN:6Jmlejeh%l#RRtP4$QXq>8qcy&G*tCF\ccPn9tPDM!PBF#XW+&kVuM+$R=hGGLJ5l9yPRu&q
JF!Nqj EB>=cnh&<CdVQJ>teXnupNS8\/TRGP6&SP%?SQ^*RJnQ*bFS\4$WES6#y8&BFa4>K^^dI^B<H>nJYmtI
:TG^\P JTS+AaRR1:T/<c:Gu5e<8b@89da?1XNac^B:5LMbc&$uQdbn?D\u*y%<Y!?$n/DR/mDVA^L1XH4ai1Lw
Xu&m^1 MtF@+qGQW=Rw1\=nN4DTG5WZjVa<cSd=t1euQitVC\CmT9eAqE@VGCj#eRitudF+RJJm!uanutRVapHh
D^tl>c i<#/wmu$>6b:N%ljiRQ9D#nEGPdJ/$44KB6lu$TYa>NtuPm?a&LF^C&JaHwt^qk&pnNQkRIuu6ETYQCe
KB<&*p MBw>&T/:t6cMl!@pRD%m=k68PVMm4Z>KwqIM&PmB!<@I6&JX#yIuJZHFT8ZPZlAtKB+YnJ1lqm<jeI94
&Pnwuh aC>K/V?JGiW^C5M^>%Nk1R+AqR?\5445D\FjajbF4*T6Juh55APCuyYHF?PAY&&Y6j+R6PIH+aTlZS%W
&inlYB QK^YkQNJwXNJ%/QuZ&JcyCl6H/#85G5b!:R:d8=V+ld+NmjAGHK&4y+%VFS>=iJ?<LX$b$bM5$L5eJ1L
KS&Q<Q 9nb$4P>89eG\n&XC6MNC5iDl%c14BHA9RYF:<*YbBDW8+jd6mmhq/AEZ&PbEFR$tNE&VP=FmXCejiDVp
P#JZ=e CYnTJSV^Mdi%cT#Y:@<d^wyea%ZLNLjV!kS<+=DJTkSp!WtKw&$%EuV+m@1eQLCDaXlwRY#uF@/jJP#>
<kRpCb 4+ASp^69yaey?n#NX$^VcnNantC5heLmLn*nFVtKKXN6JTFjhiTB#cYiB%l8CCS+Bw8iB!A!FV=l5Z&D
>uX>NK DaGweTt>it1648:i<>l*+&^HM</4$HW9QG8Fi>45kWpKknm%E*9/HF^CGLC8\$lum1aJIWq?nbnyhuLF
DR*W*/ bR\RaaBl*<MaXnjVMi=nFB?qTX9C4EqVSSTq<pjL=h4#dj%ep+&RnQPElFRJjbkni#ZwhPR=^R1ihK?w
qb+8Yw dTX$G!c:npi*\CJYWkuZpIJCtnc!IRL8B99S>yut*QL<nB85MV6em<kB^#dH\\qZ%cpbSlDp?>$Mqlce
@lwAHM +YE^MX*wTuIid/q#lT4LdK8h/5p&&1*G\$w!VLh^/8y>\tYIuM!mpq5:\VG&e^d&:Hd<Vq>6A$88e146
AGE=1b LQBeb^/WTkeGK=G\Wl@V=?CGw#:Ie$&J>RR=CdH9q+%PIPm+PEJqnZLpMd:G#n$qhPXlQlSLW:bldA8E
D$R/D& BJ$hKV/JNkaeFV@T%t\IlFE>\#+AWX\euj/WMH&C!eJE$*BHl4Ee?/6=Y9c?@I&/^na:\eWWaljph8HI
9L9%/m Y/$E!I%Dw8PwiqP1#?FTlhBm4MBPA>u99j*d5@ci&?FYPQ1J+T8k$<DI^H!6nt!9hXtZY#Xbe#Fw1Z6R
ci=Xue pqk*^C++BtqhmB/aK%bAN+hQI%Fami8\dwiJ8bJyQb/Fth9BVc=dh*@J&FmuILt8A#5pq=yH=9#@c!Tm
KqtKF8 4WhPEE5\$b=uYJIL?MR#>J/St@CK$%iG4Xe&y8S=DAwIuRSMaLXCZ$jZQc:Z+*K>4jXG+%RHIpPtD+<<
mTuM6k Hm@YMWkNY:EAR9mK5^=RuZ#QW>KB%JmaT*TJ^:HY!&NZb?tw#P%<CnkeHhQTA/?$bue/J#4<*#BbB*jH
t+9E1M ^i@EEyDmR?aTRDnBCIWP$e4tS&anWBQClpY+HFkuWL\ieK?c5BbFZy96Dh<Z&K5V&^uJiwJ5TR8J!/u6
Shq%*8 iHQqK%6+SY8Hh&!c4uDYPp+mQ45n!XDT=&tkhma/D5%^t:t:l*#V#mDWX%lm/B?D$^!L%!b5b5F!?l\i
L4!e>9 FlVw!ZFcQbP\Vkk14Mu<c5JDu6bIR<QD\pR^@d:GnlC8%lNT8jtu%JYaY#&!H1e#%&wbKn%\uEjR@q%6
w$X%Y! p>\@/85RB$<H:$>al+mMI#NXT8&$=GmT4Vk9<@@GD4N/4<eY&X/TM&!e:yF<=cchm5h%%IuPZYt@Fk+\
TiS!DK ^:Jn?ji5iSn9aiXtXD%^l^QCJq&Gt/cpFAQp5MEw5SSaeqyp&EHQCmYQ/5TBY/\&%<jKYe!!CACY%l=p
ERWZ+G ?I/GYMDyp+RJWNnZyp*K/hE18n>al@X?/%@*%9KwJl+LLES?G/AtbER$La$%Z=#R+I=QX6WPPq$e<6nT
mVMaui cRt95%hcB@&A:jtb:=t/y5Jidyldn!uJ@8Pa!S@WJwY%YGRh//FanFhbJNeV6p15dIi!\8eMPal/N<RB
qFLQt9 t<?XbY$cJG=5i%i6=?C$^<#F>Y<aG:56R8XC#%8HwqdS/cV:D5=LLT%y>h9^XakDuAn1naIJ<dB:acJN
$h<KZ& 1Ra<j&6CEcb=AuSmap8V<NkhC#PM5F1EiB?:XhY%SltJFmhL^ikm\\InIL+d:PVpPel%<B=6e6#FeP:&
a\Z+iB ##Fa18$<Jl/b@S9G<mkhDSc^k$WEI*q>JS!SV>lM@cyL*1d!E5^LwF84Aw&m4DXZdmLkEXic6ZQY*IXM
!bihuG EjaR=km=t5Zn=5j%Y6h?d4h/aM/t#6$yiLW%Q9M+$=DdF>k:Jl\hm\^nkajIMJyNEYG#NuQm/uq>/PEc
e*>+w1 kIucb=J@l=^wyuBpDGSI#dCI5IR+!ITjIyc>qtR58%<X?#MNkDb6P/V6Gceu:AZ?/$A86n+#=hb/HAEW
EXCX:b Huqw6SWM>:1>^CLHlVZCJN^ApPVaLtHNE\Il1:*aaFXXuPM>?R?C@DG?J^IIW5<GE:p9WJ&QuX!5^@B&
AD=c:i nNX6M\mbAe#$@QHtqVqt<JadHp+uLTQyie&/!/G5N!WPCChwR1hkpi+LZ\@5=Jm1hm4/lMVMl<QHdG%n
TylYyF 6p@LlJkPTd&5qA>CeJ8T+ZBSBZjE=i\HHy<$>GCGMSWFX\ebSq&\aR#4FLa/&uyD=MdmT$lM^GSdNSt$
NZ:bDq aYWYj6&!VcK$Cc6ZwB!BX%#@1H^Fnnyn#^^Vc@lem:/tuw*pB6y%1>9Z:iGF+aKJ#K%!qa#NRYtS6!ju
WHIw\N &nySh\R+%+\LdlK\NFpDih=PMFYH>q1BENmC#m#41?M4EnEcy?mSVG1PYpke/*G%6S$1nl*ny=NdI\qm
#B&HDF AThPDKX#/t86=<ZphXB1VXbmP1^<Byw\Y98l<bX^DnGmIGLMw&>%=V==HAI%+jljkW>%9PYi+>Iq<Tw>
m&P<P& BJ:6i%8cadFN@^l+p=9l#SB%AGdm&KAF*JRp/uuab$&F6jPN&wpaFYR>pTylIkAyw/a>HFYDH8F$yKba
!A+5Ph ##C&M/LRKkh!TSi+m/MC4I/n/V=Nk??y5YKL6#mik*V1B*\G/ZEIyKmHCm%+?ythKLDR/>$ilwD>jY<+
j/4Ik9 iZjuAj9D<88yCNwZ5Y!PEZN#LLPnTKRB8^=$:\VaCCd$#&tG#^SlT*CB&AbhT/hKA!*&T>m<*wb>bJBp
MpqPt* NMqPAb$<4WWP:NBd?l1Ne+T=R6kB/Xua1K\AatK8X8GVLw69D/<9iWCGb5FEP<hZI5Q9BBB:X?PdIdy\
KuYtd? :4CAne6^YMF1EtiL*ZICTwYdEYpbm+WPHIZT#9PVLmd1PI8&<pnDj5T9&GlQD$bjE>SI^nBBAW>c8Bq/
@ZN\jV y5tBq\1L/wVaLW:X!HDAnI4\>mtDhXJdDJy16*9anmjNGM9HC&^pGW/G*n?K8kKwmGh@^yE1ZQ<nuBZa
<bThH8 k!bZZmTZ:*AuQ%t:n?6YkHX$Iqd$mhmXQe1/55:XR<<SqS<bY>6uc1huc1k#=bE&#$EBLy4CBu9pGjh4
VL9@%\ b+SJ:J@EElY\SmBNiFyt!qhm^eIam?Pw*LuahubQ@a@Dt?DYt\lnX$NSX&Tj\NiVL8=/ShGb/$BJdG^H
8=S8>c +^ES8=M\#BKVhmSY$eEC=BByk55hYT$I/1!4H6^b<l4@q\8t+kWWI\nAEbeCuZ^di&Z%YV<%I\^Z8<bR
>lKukI kQAXhkm&Y@^M^uNRGLZVCLqnTeXPlZH<lNPn^BWl>yh@jT?+<wT#K=ReDw^TtlPGVZB/JCt%l1i16Lq8
1I6\>N JtN!F/\#jPZ^QFVZC84K*KEaK8d&NKu+!5N*^MZ?&QIX^\Ntiyk!G%NKbBMqhHMKm\5TDX/dm&X5J>i@
>SQ^dJ *iKRHuBZ?L4j+tCTEL\6WYTyy\Z#uZd+Ye$bmK^iB<M4<Vcm1eMd:\b<uW=D6@thYdEqmcYlkR*YR?VJ
Lh&+^n SnD&RtH6YNRnt>JQSIScMIAkJ&#SP86^S*w&hWqqEP9B/nVSeI&\Dw^%Ru^FCBt8caS>#>S&1PM+R4B+
LLV@&G tbDh#eJZ\a#DHJq^:J=Yn\wFPiB?ePD8:5aL@5QRi#eeZtFyw&D@IJ\m+h@wqn%B^D^R^u1A8B?=ekh4
-AiMNl 000e4c1e6a400110334 Page 177 of binaries2.zip
/V\*#n /#pC14A%EZKX/&:a^1D?Rk<#%4+WqIu\Ypj8?NS>lD#/F*111Kti+yAtyQl6WCK5MZG^b/^PRytMRed>
:a9\bW AB8Ew$>=<FT+ujD\RQmiGGiWlLGi==:VXt%DWh:%bC&m?<=:>&/!9lqiZiFR$Qj5NpA#DLPJDWyBFdFm
aL&@VB beDLhtF#um6&c:AWh4PLLEIl@=lwM1St6laQ1=\pC==n^qb549/C\8JAKqnleq48\eiXP#kP$h+iLVJ1
Du6CbC u/m%Ga=KkkD4wZnC@AEk6B=CqdGnWG\#q?LJ$\yE6/LE\e$kGL+d**m*6#jiFWK:<Hu1jQ<T1QkX*T!9
B^Beki J5Qaq%ZbkX5\V?*Mcd:Z:ebedR9*C4*Mn<yS4uCw6LtKI&\+n!P8:AVRSARPQwSY8GV!%BmL9ShAXGG+
6mVS*# B+\RemHBIHy4h^dCJTK8/>:<eYGapYh^pe=R##NnIIR6:Q<+tQSFj99kc!q&tHm>$bPBMKb^+1NTh&Gb
w=d*XC bS:dG688A*h\YGuNkXAAdnXtJTm^$=868?1MM#HSB$M+4MaaB?FN\&jMHiAI!Q&F%+E1q%pK<=V1wWVW
w:kDX\ YB4cBe+S89NMBL#MpKMi6DQXk$1&NXiMC&VPJ8?84md9dmj9*6&M?:i*kNyV>5qnyiA4eSMTMXc=%ZFu
>KF=A\ >5>*1+Se8qT^Cn4T&>dA$5:n%kaNdLHGm>1PV>$m!4AJ^+nXtD5RE!y/8+HZMaXFZWC8jt*JNe>FP%n^
AXXZ#8 8/@DmX9KKG!h+I\<yZh:kH$KaadSmy1^/4cinIhZZu<kPn8aZN$kn^m\^JcA4&j5bbQLY!acumX%t?P%
J4XF#X A?AS&9GR>i/eBJ:n$:#1dAELG#XL99R:EX5hn#!*\W/uE*!PmR\e?:kBYH\YW>J/HY!XKupKZiwIbdCV
<jTmFu kw/D&$CJl#ChTEI?+MRD5Fc9CPbK!Abj*:$L49yZk>9B:e&\#+aJqYFLadPBynuy#6NK!=PXqSab^Pwl
qRXX*# l:GT1=PXpc*>Pt4=CMe4c<hklF4AYZkP&+V+L&h<mV%C$Fl\6Wc+5>>KbNi#jZea>wN%Yt5F!$nG!4X&
#nY?bd >SV:FVPLi@RDnQG$LHlWIZDHy6:iiN:68:/*^8dGkjlZ8d%*/AmEGY:euG8Dyt6!%w=*%AuM8CY&bMK+
C?\tW8 %lVqEa&BDd8h*cwKbY8qPB5k?<jiH&J8uGF4QlA@?5mk5#BS/IlJ9bc^/HRLFW@+hyIaEnZb*TYy@tSC
!H*e8S ula+yR=cm:#m>mqu%kIp:@??941/G1=8B$Q5Ad\hIH!heySCjR/#^Dl8<GShi\^&n4GiD^PV$y\uRY5m
wCbScC jM@XANYb$:wRAp:+1\B#+mJcemJF:DCdwYNh@%aJQYliiC/%#q+K5W/I?%PcLFku*:4ZLAE%/Cn6k$IF
#jYwW< mp^HpXl5^!itIPZV>i*6GMhY*6+PJ8@/X*&<%bSGlMWaT\BClBM&h?Ekbq&HaIjDI#%lP\B+&Gqm$L@S
#b9kVZ RqDFa^>mlTG8?%Ni$ud!<w=^1aP%T+6*l?6@qp6*!Rq8Bk*1IlYN%S+uW%y5<dPDR#^=@qBnQHj8Fa#^
ECDPM6 wpB^Fuab=!qqR1cwLE@A:4?:9WFHReqD45FN86kVF9imBGAJmwYtE@W\NV*ma/@u\hicuGYW^CaWFkBR
DlaJ1Q aEH+H19GI46#i9&**n<5>FnjjC1*b%FQ/X^LHQ!PZ4dyQ6&9>YVYEGic!k*a<^Rwb=yTVcB/A*aawI8c
Ip<:>% \V4Qm:KeMjBm8WZnDtPj:A+&Tj/K?N+PBqhZTQtkYThm&y+DpA*VuWk#eNTF8t1AB:b*4%C^#9h84$:J
ZeEEWi BmZYSSDd<$lGFL8=&RLPN!Jj>Wl!nd11/lt#JPlm1*u/Xkc<Q?l9SH>LT#IK\Nn:lmWKn!pK:JCSeJce
=>pWl9 LqCaBBM6\/lbN?#4^LiRi@9qFu81&Aauj!h>VHWe&VB#Swb*1W*BkADSc/MySV8E8>LEN?h1qX/6HiHZ
+qLkGZ MSDHePbaK1^MTm+QE6@L+$cZ!*>nu!uHK=A:F?KRFEhIMtXdF=4@>?M@mc9FEap+D^Lt!ZhaRmnFKbcV
ANEV9e \5<EMM1HMIYVCbtLeiqWpX5CJ6ZlQB9myQ4?u\i*X=BmJP=+jBA*8kI!9ZJD<SJ5^e=>Pp!hA/e9bXnH
YNutyD 5L*c/$uFXM:1FRe9ECG19!$yDA1QKiL@bu^qqy1:\4AdMhAEBepPlaQQGW?/D9Vkh+1\lV1Ydt8=uAdm
j$u:DQ YWkY/B1*/hTTSaGWHle:bMHTt<FX9*e#&AlCQMA=SFmmlHWKHJ$D^ieVW68YWiGbSpjh<kXApS9&*%el
Xa5KQ+ nBA5&Y8m<^NKbZ#WW*wJNAR6k/@H8G/Zc>bH^HVR>mu<1^lI5Zb4DYeSFRnD>@mYlnw86q6dp?Ii5?8b
BKA+>& 1*W+Giat+mqVFjl!K^bJ?H4hR#6e@<?*QKEe^L\&HMuRwWASP1E<cyccXAFnabw+j:t*jITh&<6=HtSk
qWkw&V It&kX:/!W=DH8Nk\!au:JZm&1tdaE5AJ=J6C=CeClP+m^D+!Fik#RF+Xy%/KLh+:a9*%ZmqNBS^tyYcj
XtVY=q pF>5bZnLR=Z^ndE9FQj/9^8mc*ZF4Z:acDy>a5aEcJ>\+wSpInZ*6LVh?ApL8R^m:WVbtPj!tBpGHAbj
*QQYeF K=/@yNZ6C6>H<XiQAwp+m^S4FBH#Vl\FH/KJV=AEpp?mu*8@CJ:6eQST#bM+H1@\HXL$WmTm%8KL\/t<
a9wBZA j+EDLa!6Y6#cKn^W&miAadjCWY/^@B&lBLaiuDnGw<Pj+uFPLB1:L68a\>%!nVn*w&d:V&$V+uFq5@@C
R&pT/l %@ywLV:e/wEEPi9M\BXSlS*c&nF%%M/b16S/M\mD%NL\iu8h!1*bPIJQaDaN5PGJqL*pG^4#1acyY%%D
RtRItQ :DR&$\MJ%\YR^^YI@h*kGu&h!KH155kKC+1d5*a:!JhEm>HJ=auyM*tCPNIwVCG!NE5LXLHmXdp!XttH
/GM9y= <LCS\cV+S?Rqy4Hmah\iVJWAFK9V!VV66F@ZQB+heS:Z6aNaVTi8C#ZH1Slm9LHEh\n\tFHp*AW4:64X
^CmZ$F 9hWKyk%KaQF5H&a+ENNEu\Mw^=tIM$M:GC1iX1JyRaEB6a=Lq:E4^!cE61RMCITVl<yZP/?%bHWbnjtI
ECLFmy /j=\%QQwDaZJ9eHmhFD$VGCBjGJK9wcM=MW+AXmFAmqwn6DN=@6:LJBWY!G@A9Td1^TnIK%C@Mn><L/h
k$\F#u Gm>Wm1:i@P+c6Ib5l#&lauyC4M+DRq@6IICEI$yW\Kp%=d1CB^QlQB14Ptq6SQilMl1wyyw$^BqYhNCe
P<B=nK #ZiuLwd$9EpC#*wRcWXiHLwd?95lCeWyc#48B=DBRJb6RLBL::YeX4MZWlQ@ILWai\+Zt@bcQM#aTj+M
\>FScW Samk4w1deAn1tY4d8BwAh<Wp%q=mS>e/DKHjaLQ!mW5V&K^AnAX?Lln%cAeh#l*<k!=N#TpS&ki:bR&4
<Q%WYh lw<JpY#D?elRa4KbLX<B%%Y8Pd$mH5nj9LhTQ?Ftpd<9pGW#IicbbuT+/LEw&uYh88EdK=^$ERh4+Yj#
%WDiJ8 44DAdnKCR4^k^%:Flchq/dL1*IKKHyVEe9=a?R$J%yyZ!PKGNiV<1H\%Cdb/F:b/CLp</BLql*1@L+JR
Zabt*k n*/jc1i^4bCBEH6D=AdbFRFF16kwYcN?6iaSlIZHuh1$\8mb/duBJuueaA*<>P/>%mT+Ha?c15PQ&5yT
NF*u@$ /blhyY%hS1ZLe8piLN%h$$Tm4w^9$Q/y?>m%+^yKjE^+SpZC@C*P4IcNFnkqZC6b%Hk8&j+91JAH64Mt
5c%YHj WAbVHhQTkb=N:5+KeXenePJR=H6/YM>$F8hMFn!$5M%j/N:&K:\cVSNPBGZH\%I:miq1MZY9VWBeK5K^
iapXwt Ca\CXJyi4?Bj&S:ZeERN!XJh6Hk$b%^ZQPMnai*1D*T<lmZWBFRH>HNSly<#>VH:ad*k$LN8LAl5PGAn
anX\=k :MVA^XFF\>J>eH9dR=F^H#^QWhWJKZSEMjL9h:!>\tRTB!GR<SQKYB^9TC@u$>FV4AWc1B@jbpGja*!6
d&nJWh YW4GGT:IaaAItt\Y8BuVHDpnIS?X4#yHZ?8bj$pW@hic:Z4QJXXYyBpVV&Ke>/G&K/KD5BmHW&y>VB%J
IyNbDF KMN/ZqTMk$&aN%##AMK^6bGICF?Qi><@l9IGV*yYJt1S4&=&F\XGN6\lc1<$:eTDJ8%8<nA^DZ9mmmQa
uEn8MS J==Dh6T=GHc1/h^:ZqKyy>\ZdnmCjVqVJyXQAjNPIW?V=yDTjy@Ji\S/YGwRdnbddSLYIq1m*51XTTFh
jqi4:5 Y+eTlc*d6RJnuE1:/4jdhYtRSXQ86FEAl>9CDF>5qADbABNc5WMah6Rn9T5:pDXt^96wXTycJ8bi&NC1
DLH@tS jX8WP@T4\nd6liHa\t=u@hE6S$lBaHWYMnIA\5W\*?PGb5ZhSL\Jq4^AP*Z%kAaVhAiY&e\\RaSEIt\V
V$WQdw V&SeK&1/9nBMquaYd+$pb<XD/^JNJiL$:Xh#P&h%uMbbIa\NBVYNK/ut8bMNPy5Ta9+L96JK&aJG=MJ^
:MW&LS $dldACCciSQV9<la@^ckFKB!6>X?Hi&YY%ndQ98uTl5HC&64Y5GPYWLEYtLa>XbdWNjc<dXi4Xjjm#CR
G^KmkJ lD5:XGSXSbk4B%CLBdqMm&9#BMV8tPjcNAYY&e\c?Mwplwa+AFnH*HYAASbZdMLZ9nZ5RDV@TLi<nByP
#9GIDy VAwl$$*&qL9hLwhc+Wy86TVt:QSYJyYBMp&AmTh?Z<A/kc&Fy!%Ra&?\euP$L5Pi%ZewKVKebkm1KYJm
J+FPuE SY/YAC1&MVYwa$!?clZLjCYkj*RtZ^t/eu@HMYiCCpa1%L+n#Q1CiA:C/CtyMQ/9b=#ykw%?h>^Cm!/H
^udb%5 uL$hl%^#NYljB5c15JnucN^qN#RtER<q!:Em^y:mB+$A^DS%KWe6E<CeM$^B1Q:/Gm%6d<Tb4SN5b=h9
utmZ:V &@l:^cd?uL!lDnKnqGmnQ!Im^t<KtX^WH&9nCBKq6MNXB/X%nipyPT?RS$GblRijMC*4y14eCa%^NV%!
KeIi\Y u/GRtnMPcjXXG@ShGtc6%MK>>kc@FiHy%pawwc\5Yhq=YJyTbD$Yy*Ed5h1\tnmQ\\+D8l^WqC%V!1bA
#%PS<: 8R%=yX**^=!W@cL^K/jDtYpEBw<Rb&!mKW\BRYePy6J:H&!R\Ndaq%d1XAh4VXeJe%=liDD$n+WRc!Xb
<Y/yEc V@Zy#NMRnc*\@\8pVPX1q!KMy>h8WSF$F19Rpqe#V4yEpebXy^F^pi!t=cu*eKde@S##eFphMhAWS5I>
F?kZNM 6YYm@yZ?5YLYB$:h8qG%q:9WcSV&:Kn?&8nuWRFI1h$=qi*w#LAEqhdJJ%IpNB/QP@t%9mtJI?Kc8$ua
ytM*=: b^dJBc8&Nq46WMB+eqE5/ZTXHh&*#VbyRIpV=+tuZBZc#l>bF\+DX8\#%h:GZI<QT>n4Bkki/RtlLi+E
RBbla: lcF8G&CH1!H>ScX^I6P$cwuSLyC^NWTEtAiRK:HaFQVhw\>j#WyylcZ=Vb5LZ%4n@yJHbHH%k/Jm+HYK
nL98eR pZaZ1>LyZlctVHtENJBC$wK+$4XFGq>L/@nq9qqFL59qpX8aKw#d=B#km$NREiyi?tP8A\X8DSENMcaD
Dce*Gd LhKTCBcb$@Wikb^Qi?!6ui\/Eea^BwtiTat1C\+TlRTjFDmyPX+m44PVkKt!C+6%6B6ID==@=jqT8J\y
uDJuW/ B^hLdX>tEKS>JbZ8H#bYMW*P%Xy54&=59?jSVI$R8iAZIctJNdqZE&11PaCNaQ8*6X4t!JKPji$\^th6
ayl5q5 M%eS%p/mLNQ%S:^i5j<u*cm5e&Le*HVY\5=4yNQSCNhJZ1\jqXn8uhd6V#mjK&?Dwmw$b%#cYdj$m95&
=MKVZL >c@B^qt<%VF9!$YF/#\46K9KSnZW\^P=5Gba5/CCy1NFtYXhk:GQ\5l+<B5SD5LyW<#jmiuYaaSRb#=#
-A/BHY 000f88c284200110334 Page 178 of binaries2.zip
AQ!+ZM WweqP=AQ9qwHEA8P%kV5QLw:&KVSjl>NuJi8a%M>#EL+BH%64ceYySN88bI*weuRA:5ZPmyHI/#DS5Da
9/\6Wy 6aWRC&W5n&SYl<c#=VHA94ZV/9V^Y>!QtB@CH!PwE>/h1/XljubP&J1^X>*L$Xa:Tw=L\Mi!B=4qGtm=
T=HhwZ FWJ$E%m6ecynXt=:CHkDdK1pbEcPCiuZ^M+>&eLSFMk<aR+!y8elZtTdXXL4RlDZt<M^My:=YtbE^J1h
@/M%Y^ \IhBJ:</SyD^<LL/TQB?Rm<TkbMXJuENFGQ&:y<4BW?+4@Rt^D<$#inF$#aBJydW\hahtPAn^#p4ZL5c
<wu?:N <^l!?k/pjW=uyt<5jpJDD@wtab15n>?G+a<J%>V4jHbqc%B!i*X$/G$6lKWM4!/B@+DuDiaeDTP!nmK+
N1HRXS WnBX</cEm1>MP1F!J/HtTR<GK*X+y\R/%qa<>L9yyD9IyAiqBTJ#wW:aypGjw\NlhtKi9BJ6k!AaBpNV
I=*A!k T*1k%R=F+!*QGHZV!@mFSc&Pn?>4Fq1qHWqlnhe%W@!hDcaIF#ay1wpJnZVIYJLLNW\K@%GkjLX?mKT>
Sn6=Q! $pTnFT:BSWZ9!CYl6V9ESM5D@DjN><DDmleyidS\YMiJLWSuH5PkTAp>p&^m!hkAdcNPic%AlpW$P/bY
NZJG9W V+XJ%J#qdjaju@:H*%wtSPtWB&*&bhI\WW46qNm#\u>C^yN=HhcQPX@WhpTk@eMTNil&=\!i^Zd^AcAA
=$W8QL dVmaMWQW!+u8&udZA$1\IB>ZXheJP<&Ey?kM#uVZMGNEnlNDy9kKLB5Sj1w=a&?IA@:wSdC&IQ*$B:V8
\lZ$\R apbZq?*^8B=YNX:%mFkZ1$PME>+FT+9D1bc&S6$/le?/EIt1hNR%@Zq*4F@PNQjWeBN>dYpTEhH+!a5j
GSqNS4 #bJ6pYRA=69Cb:KduZwL=FXySaqGtGWntpA/YVTFlKlMnyH>Z@@Re+jT1aHcIF&q/A%8Hj$Ty=NPhT=h
b^>1eb \a:amZF5+*\PdZEy6y?NV>cb^9akZVuP1K&D?Gmat&1dM?!\*IK1hHqVu8mF5jHtnG\YdW\6+q=mQAQF
+?YZRe <h1A5T5WMLdRYY9AeZX6t6VW>unjC4G@ec/\VQ8aiIRdt/m8DM8b<X>!p4ZSZDFdSSPRa%9KaAXSp&KW
=*Sh94 lSHj5!:9++\&N/#V8T+W^Y5^w4/F941#=bGwM^#NpS:1Z6K&jLQh9cBywkapY6tnq&W&SqM:XQ+D/A&%
QLKdXj k5WhW?QSd=\4$%cE4Llw>5RC<=+kn!CQq+>i6LPK6cA1wPJZ*i?X<ERLhnK%+=GJq8pWKP*h8C$#B@^D
5Hky#^ P^#d!accR$dD:Sp4C:AE\FG&RJ8?iJ&F?+cF8^Z=K9!Ed>i&Su5^na#RVq\kNiG9jk9:k$Ljp:PyNDBa
/cKcMG c@ncSPy+XJBhdAeHm?^yt^dZ6>Lid=n8%&aJGe<SeNjcm/klYt+^&mJdRac:B&+M68e%T+\EMK*MBeHb
NnNR8h Q8RJ8Q^e/l>>AJG^9<c?16%GZ9:muwWP+InXd#EVV#m^5T#p//q&J*mibhT+SZl/aMPbt>CVh9V5&D$1
#LS:pa Balu#qj^P#AjhjeItj:FqY>@/j*@/jH@AqBLA\RWAAIACAANXt$qcWR1!V84AACYYRIALkAAAGN5cYX8
q\jAZj hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>tetXqe*B5aZNwPGJyhC=CVXD5uR?MH5X%\B<XRVl:lD@>REwb
CKtw=M 8CbRVFI\aA=M1qXwK+K9+&\JAY1:Ed&+nkML9RKYMTc8KtdX^q:HmYd4E9lapmN:q&LcemYJQVJ4Kq*W
&FB@IS HnaXXNuEyTeK1XTl5%P%<WwnFSCY/J9b@>?j<^q5El@#949:>5@<&Y>?<>/<iV9:*i</*%#>K/Dp&qMB
l+Ne+^ L5Z*q$<B8AF@V+HV>jE9*ych%*JK@19qIj$DD#&W9ctZPwS@Vq%p\eBbQk^5&Rc*Zn\BY*$jY8j8l\?*
BW=WN* l8Ge+c$\+P?H$&=eAbjj6lX8&H+A6t@@b#nu>u$\eM8VMHVJb?G9>5*AdX5jkaE>CR\QD<QR1a@D&d>&
PEA\iu J%^>/*:a@<ILeM/&k*DPiV9lnPW8LDu:E4n!J6!?h!eMQQ%*ePZNl&D+l+hk$iZD<BEjn>&>FW:><q%\
c>uj<e i86TCH=<EC:dhkBYjH$uZLH%KjnINZhC1@W/jQk*Qku4@?p%?MV\HVB\dRBZ*dMVLlycDtV^V9ntM*5k
BpZcK! &je#8J9@LT!>b\cij8WR@PyX??Dn6#+Jb&><CRd&@nh<@E?iA44/Dqn%S%?FM+jdMQV%6?DeV\la@6EJ
Z?<%MY GH4kEF\%>kJ<:%5#eMGh&&Dy1A<HZu<hY5Pd+Mw4><Qu%>$NA$@5BG9yK4l$/:N\\dKN5QyLAkcmjVBI
j$\N/V dwcLL9ppZHD?JZDn?4?BC!=<AL:<p:jlm5?5kPW9HwELl*dA$MVdeHj$QA#6QRJuuQWwdQ@&p:D<>u?B
k6S\wP k+eP\buu4aI#d6pNm</>Dy:=?SFw*j<cmPj*\&hYQ\NL:65D>#/?E%#ZlaH:a9neYA\D&@aCZd<X94H:
NC+X<I Bdn/tpt+?5c>\A>m8WPd+Ju9jS<89u<cY19cMHBQG^:/+lV5&@M/DA*hB$N@<Vm?@#W5&@WKDC%:E=dh
4TMAX! 8RqYLjq:8H&VD^8??nW<N\Tjj@yF8G9nLunmH@+Lk99*\=e?@RP+=!6@Cd9&Qk<DL:$Eq%$&C:>*E+iL
Xn@JW5 S/a^@e*\!189\t?SV<F@#9\e^5i@C&e<eSAG99W+*H4Dw*Dnu&K:9*\RN6#/HK#@/SG+:q?Q\Nmi=&Ha
dW?GP5 jkb8Yu\jDA>6l?Ej@BSP6e+H@9CneQ1Nj\m*4X\NR%<+A6ahD<IqhCM<qd\F4Y5Q\A$*@Bu5?=<*+K1q
5hkLm@ M@C@Q@5@8MQhAC9ZjAhY4a>khHk*>65DeQdZDpB4=ACeij=G8Q1QZ+d6@@EGjG/HkEYLQ\WjY:aKZu#^
%#\9R$ LSnceATYSDP\hNNneNQhG&Fk@ABe<>uXMQ4>F&Hda<@C=E59\:*jniHb==/DB::^CQ#n$/@CS\i*RG9q
/48kcC X4n<=wilhh=8PP$Q:wKBZVFe8iaR@Pc1P/B%*W=w@ja?8PktASjh5\hc!*dDwN8G5%a?CJj@#u+a?Qbi
PYd*BT YQ4I5@D4q%<H\*j8lq9?@RmRn#$K!?>/DJ=::kl</N##+dTXZ+AQdjwKLFu>IDm4H+Aj9ZEE*u::dXm@
9LqNXl <WHp*ad9dQ5S4Ln\>?HHQ@p*YDb+Gc#<+i5\NVYFG9&P@wF**5ui%E5hWu?MLE\lSlceGK/G1^HD%anl
>6@Y!= c5S\NYK+G1:HVZndC$!nLn!8F8X6$/kuN%jPCKE:Aph9ECemnJMweaVcq\Hlk!!^YbdP&8E=q8M=JQC<
:?Jp$A FppwIT\lJQI<VNq&HFXc:BGcSGR5\XVSDm!QnuuJnwn+mWW^GbdNdW!J=#u%^k!+E<nX=e!#jWETBedq
ee:Wp^ SCa$bVIqmTS6Sq^GKSN+^yQEeclFTb!!hpS>KlBLP\$\MdXaG9NWqicqRbR/^Qc5N5enXQm+KTTSKa9T
lw=hED N6ul?PtaFFS\LIqVA?:EecWm6FN88dVm/49EEww4KtwaKF*EM&4Zp$+e6i%aPI+V8D=lwTPD%HGpXDpR
HlAZ#A E&$:ZD1&qecEJ^!:k+kF%%p^B@e5KjFkEMbyIl%D:eTP4^/*Wk5=cpQ1ilV%XXk^/16H\wm+Q81mTycE
RFcBYl 1LJ?t\6G1I9c/cielI:jDqLG&n^FqeXE#A9c1i@FwaPJMTN%@VDB#lILGwdW+a+Vy=T:98CSMNy/a4p!
P+6LpM #&tV\k:d6wPc=NmiT^#ZC!&i&qGaeD\n\!T!E+@m!Et==$tKTbG:HWnQb4lnK%CPJGFIJI>D#/a<6Bq&
>5L+pe C=EI:ukp5RtZWlIQW^JXkKF&a4qTkbyZeKYEW8VnW&X+eVCqImLW#%RL>>V5^:jRaebj1qQTdIj+kb96
+\Z4pl $T!q#pM6+iNtZ4L/w<1P*V!QpSM/#&q=XHQNNanuI%?&H<#ZZQ1>DC9/VYXJT1VcCpJnk6?*?Y6R1lDN
Nb%1FN Y@%aXe49i:A1TbhNjRQ5?HQXBnKI1lkEn$*:LRC8daW$c4QKNKLH?k5X$/@iA>iAwe@DpKuNGbyFdlM!
X<$JN* SwtFdp&Ae^c$qIFFLKbNeMVGKp855qAY/<PW^DVnaAX1Z=*&!bm9h*XK>Kq\i$^=X11M\GI+K&I5Q/8K
Zeku+? \QGcBZk8n4C/mMS<nL4KVI?yHFtF%MTl=5*XFn5eGmb6TY#Z\+bMWk5u4pT&mSjcca!iVTlJY+WG<VDZ
96e<WI E^6W=aSaZn5leiJ!p4R>#^jINEkDI64EGbTa*+%yGtJycAeT8$%XpcFKwD8PJSlQ&kEjhGndc#8aY5am
^Q44b* elIuJaGc\dcekHMSJC&5K+^q1C1$&=#bB8k<8dIWjbWw^PcpNmhC#VK==t4:\w@V\NFe*WC:\#nN>K!e
9SH88p K<IJhXd1BnVNqDD%YiySq\YB<uTbc@6&GKM:VFPGHcIqdKp>+TT^R$JqT1uneaGRLSh%NI$TlE6at!Sl
**w#@e kDamEE\:W^qZl/W+S#J#wQq!%bFAXCEX4&ZEhtKdJT4mK:*A^daPqL+/SBEpd$yJjepLjdXDEjt8:X4T
1dK$=t 64N^&E>nL@E5+VmlmpMpuH8PhPKRpJRuKlKecm/iF/Ye8y=9meTTLqc6Iw<$nTlQBIq5NBVTqw/dtacC
Ab=HLw K*eN#GQk/mt8q19mQ1:NWK<eHNW<q<tRl6^J5W%b!tMlXVkCYXpqX^:GkntIKImF!H!6RMkEVcZNbSLa
Iaa/@A Z8#/!A>NL?/:X1KK^E1WmWlmHLhV%Pw$<u*BJbJMIn>qqQGRPm:Ymd$4>QIJelnIqN8TCtu8@B/LHhc#
HL5cKy t\VBMia^\u*$iGLP$Z5JWPFWeJBnInY?T8ppcJ=XPAFXYI%+EXyZ+ahSpPqTpKa^1y9qPDVCV5LS%91E
t9nqqu Y%dm?PkGIX$mqeLT$LaXZc\5WjjyHHTyuIR!!<L?RBQ5JB\9JMAiq864#CX8B@uadtSijlP/Ld*cK&d%
S5$AMC &JKncNIE\jK5M#kpeNHcMnhJTILGN:jDiCS*dZl*wXLpG$:c1$ciBTZ<#65=wbu69K6=V6\#@MD!CF<D
BS%b:k i5S!W?n:cu=pKj^WVXj!MHF5baHm*5ILd>d1XTFN?8RMVG#^lMRSnSm8Sp+/4yE$p<eF^#YYdt4eq\ZH
lTP%6! 6b&t1bqpLDm8HtJNVFM8MK/Y$qc#SuClecWlak%NR!+$45wIy&b>!pLncm85^tqccF!%61KaNd$Lmt8B
w>4RMu NW%dymqQX1=B^KW*/DqSEYmuk&pq#LVqTemX<4dR?G^Gi&k4mqt8eQJ^ba/d\jQ1\WKbN5Rw:EuGqihR
C+h6Wq t%TJ$<Tc&q19Y%ct*uGl=^KqXh+/njS88da<+C*b18%d&Z/%Y#^B$M1Vq\6JY:X4!W4l#Vym\*ZPBH+:
c=%MJc =!baH=iyEE%WiP4b1eHmLwA@cH8&J+1XEDT^B#$:VMjKR6^RlCK%!4/m>+8cYJy*CJw/1qm*VEn4ke6B
9BXFi* #IZbmq^91m4h%HChW%pLcq:#Ny#VlVZXYliu\lYmI%#M$<ccl4nASY!>RCa1>=Nt+I1XAR?iCm!*tmhd
848W\< >elq4<ePI5N%L1:qGC4:HK?J#FW\CpJS/yXnw:mqW<W>*A%L6e5YwMdqQd+P4lX\Eww+V4*Kn/6#6RW1
y^INES cGXNyK=DGK=#uG:w+6^a<=d&W?bZ>&KnNPEwX1qt65VhpqdB>cn/1lBH1hYH1<$a1</yKmZ*DhinelWh
*:JdGD YFq8tpYDc/=N$4Z6t5a^m%wYLdqK6Xe!cN5BC1@$%R$CQ!lZw6Z$FbFZ=6c!+nV^!%JD#$iJm/e%XbZW
?ISwaB wwd4$dmGjp>6VhTC+JwW#Y:ZcFmlGt:h$pktPE+K6*ycYa&cRySc!wR/Zc+ebcJ/pI1GdwuKXWP+KBd<
-AVL8^ 000a2a436af00110334 Page 179 of binaries2.zip
HIw9iy 1%JR&pY6u6=ql85e#uDc+&=NnqW>P^=$&?G8mAcqhI=>6WjuTF+@%e^EG@9%ZJVRD@#c$#t=Bt/QkEN8
nK96l$ lDQdKd9<JmP@>F!b/IG4WNFMmcp\AciVnY8tm%%LIYJSl=l$^CZtpEYt6Z<b8LK$a*BhyL:YWtq5YF8t
HDLu^Z X5a68n6AF<eknwQtW^e$SyuZ8tMLE=1u$a<D%#n6ZAqByb8KWCwu%/dXSKa^9Ec&N%k!>:#BKpwXJbuJ
Ji$@:J FndjYjTeLETbj<$Q\/!FFXDF%B:HwV#MWmdqlM9HFFYakmSi>RY=qteQ&l@$4<d5^>X!P=ZRC56yctB%
RXZpR# +peJT9Yq6WtT*&&9m::Ct\b<5JwCE:jlZ85R6T%qjdTQ/^ZluLWYP$q1p&uD6WP<Ll@Z/?pjSa*dPb1X
*B=nkc 1E>?<^/RlbM>Fq5BK==V%V%HSuG?K/15YYeyP=VI?+IjX4ZH>SSbXXH6nLAM%%=eh/Thw?6a:+G$XL1+
yRS98y &mXh?641+VDHVVMj%$1S6i%M@=I1nh>DZ?6e*S=^V<P%cX*DHkCdn1@VWNeGX#$H<18\qi#lq%ph=jM<
@qllcI aqXn:6eai/X>:189QDZL%Q6!6d6DTLWISQ&YhV:wC4?mI:4GX%+n*?Sc<*!1GDN6XC=4tltXC&://c6X
QIK:/a lMIM%&/89MQD/c?9RRj1Lu&%mk*l>?Bc?<bLVBPK:ABVZuPc615?XulBXuqSjjSXQ*%kG/!>8db:*J:#
4te/TN i+/95pP9i?y4$NNBdi14K6=^5k/Cd#a9%XHWM=j*F@4w1?!$J+a4/VF*KX4Iq:*>aT5jZGtDc?j+!n1h
^lkWl^ ypZhZFZGkGZ4pDGjDI4c4edRZEJ8/t5^#\qMuHwP4p=u!DeY&Ma$/R:9N\ILjj*lXnt>:c?9n8wQ9l/F
*PnK6Y a<&w1KtJ1u#I1<MPm+^4&<^e=?A1Pt:S1Atpcp\X>Rq=h/k^/BmFcai?F4AVD$X>/$@W#VYLVR1XYiyl
ZG66XY &c+dZF=*/N!?hynQJ$#>kiZ1h/\h#RJN?y56P&/q/1qm+@8ViJ%#wc<!$&uc:C/5V5dKnmd14/*4hZKD
T1cC5u *6SZ8/G9bajTZTnYHhLeXi4H6id=Km^=SBE%%iwXp&w/u:^t9S9/1ySMBjunMtdE/1Eyqk&utNLPEjP/
PX@:4% $>Y1&&G:=Bw%>JZyAeS<tX+@41*t&la::VH4KStGX9e^y$NjG#PcyHCIGua+!R\wtk4B5<&k+N@\6>PG
Mu8VT6 *!R::LD1TYd8&w>4a&p\6#9ZyVWHX>1D6X5dy@%PH<e4l5A/dc5\4=lFbDZSkq6a1=1YNHYb%a1uZH8n
D=%eVR H9EQ\:WS?itTyKhY>:Vl9Iww?\Wc9^wl\!=@tBW/tXVn4=$nTtyV=1AeXiQtBK5?j#XjaZI5ZD9?GWw^
9mJF<< CQjmK6\1btEXS%tqedKL1!\/A/<edCe6w$?qp<6LjXSelbi&5+e&1@6$uuq/9l@Zuw8?P@\S&b6&bq^=
M9qJ@/ ckh=TE?WML$!=qHeS/@=Vi%m$A&1Rqqi1jc/iiYA5%J#ScA59X/%Kk188qaD>tn?eP>FcXa^/Ha8GA<e
!AYZ\W nRYX^p9et5QDT!&%5/K5IMlCjpERnAX^%WQC$yA1J$kDm54:1Wq=b!DI=5Tqt%b=^+FbR6iHc*!$\VW8
tTV&!/ +5ihC<d#uNth<K=:1I=Fam<H$&*4:TwlL$hmy#RPaWR5YRLPA!JWP?6JQ1YKc1apMF!:8NJ84QXJ1qW!
$l6eC= eYnQHmG1NJXBqKJ^/<@4<*SQFme8@jLeZ+4C5u>bNX>e^V1<4M@Xb4NW^/VMiwt=+5QhYNZm6c^Sui+u
YkdMIp t@V!\qln<YYT!HwKGuH%ujH=IT8P6X=FeTFFFZu?9LT!^*DHT!V#8!5K>DiQ%/MW<%@p?AHn&tYIT#/$
m@cnR@ GH6D?b/u@+%+$*5Wc6c?#IN4y=W5ymnSDt%M:aRjn?GL>bkt9Y5Sl85<8F1m?*qqanE8Pa9>+^Yua#&t
wH@u\1 Ti>cnL:Pl&6DaW>WZP=+/18^\@QmYuie^Iq/<N9!n1Mhqwd4$duK>\M4$e@4HdidL:=u8B=L9PtENla>
hY+#<t up8SyPHcu?8mn9C\YRP&WQT%Gq6D^@!n:RZDNVjC\yQtP<AZEFi8pVLDhGF^nSLtt@XBC#e8aeS\NYK+
6YlTFS GnFenSm8Su=^ZM*Ze4*jZLj$pMZ1Ndq+<bd<h*L^=KV/5*lteuJtetbtitb/i5Z$>QD$5Jc%\&6S%1%h
Xe+!bB %!pV?Fw#5Rc*<L^P1uJmIXl5Jk<ZQ>ud\@Wn&bXpqiaX/6y$bcXp>W/5GStjYnI/8t5W=j4S#hh9*u\>
Jcm:K! :8$/*E6&Hh/%K$6byN$<NV+?QnI:P#9SS&bu5Z\5E4PPZn<%Q4Jtw9^RK:IQNcPd1G!q+wJX&&DT&jEy
ye6XF! qSj4WXY5t/m%EMwc4Bp9aLP//F*1w9H/S6W%#d+^WW81&%P@hS^c5$bh*+n?DP4K?uHhM4qqW9*w*?^Q
t9wC&> JhQ1NX&n84cVcuc^iLt1QmZ4!pdAZC1@KuW?W6R>ZXZa1G%6@5I/<aN6*y!BGqYky6TP=m4\yZ+Pb#9b
#mj5B@ =8nlE1*PMK/pA?!/miKVKLDn8u!hF%MZaHX*XXiZjcycI=ZhWF@h?GdMP1y!#p:pbCjKlm1^119J4uNW
tJ^1dq y%YaJp1e%XdHBucMpR^5^ZY!j+N18F5/!YbWc\$>ZDX$h1H4K1anI!P18c4iQX\%\dGR#h1yXNm<84Yc
\w\=8R 4Gw=6A8/+R5b*#\?XY8qZnJ/iLTRLI9C&qVaJ6lb*jIbYKX*?k1G4@n#V&hk/&mLN51/wi=%PmjYNF6\
CMpM4V uck$aLaAY%+\K1\!I4P#c$46#NP91&q5\Xi%NwJF5qqH!QS%5uhdd8ty46PVVZXhY:iLJhE%BXK<&Kty
HR/+8a KY&&%yc&iD4@@QNY%/Khtqa@j/$6LDHc8k#1%NV+XNFMhXP<K>>Je/!H/@1/8XNj%<&l51Pn&Pd+whbi
cBFH1Q 5j!<DS5&9Dchh>j<qdhR$RtXHS:SGXXFYSZ4/9w/Wil4DndXX#cq%C?*\^Q4cqT4I&Y#/\dHJy?6>HY!
@>*DHl b*5YLdyq5yN6&Sj4\=&?iGWQM58dM@%@T5+*6I$##?PFi?Me%HJ:cPkcZLwt$!L=XJ?F$pq#hG8:PnS1
*i:iCc VeEqMll8We&kHunp$IPJ61%ELLm>>Nmn::1ZX@6Ki4QC8BB$5PWeXVk4b>%e@ebd8$m&ay!iZ@m8=?A*
Z%A+t> jZ8@=@@9tSp=9Wi!HMiJJe>u96@j9&jWykecDCWj6C%&+n!h:AAuhk1C1nm6/9pV<wS\G6Z++5dYJAH%
G?HIp> DF!ZjwS165!MPPDD*Q9W$T<L5QAj<4iub1!jb%c>W5qLj@YPpG^HPbwEC?G@ZV=DZMpQXtCDin%4$tjI
#VDwii w&le>>HWaLMRi<Lp!u*aj*nZpR8HtDA@HbEJI/!CKB#lNn@@!IJDXpBYdHQFj44?@+t9&CKpYA5TdJ&E
y*Eq*Q YLFI8CH!JXkyQMKW@qEKFmt&#MEm4wXkFBSi#I:>t\>@PdN1jGBb8&cyXBwB6Hi?a&VFI>b4QX@n=$NN
8<aR/T CNd@k<X=!LE!H%=cK9!EXihkkT5ND$!9qKNjI%m9u+bpVSyZHq!Z^IFqVBuWJ4W6+mk?^j/$II9n1&aS
JhnJBc E1pT4Hn?QQEni1Vc@EYwWL4TDFY5FK^Q4myu$c*+t@@<%aFub1^Lq!wS5\TKLbWYS?IHh#wKLZ&%n6C4
jX8+58 VJ^\kJW@YPj/=I#>T=a&%j$KDTjLE=wq<qM=X+$5w8yLlQXRl:LlkqB4ZpPKVI<1FwH>1a1XATGR1QHA
R:QykZ GkBLd*DmW88k4&bFZ$&@a5?WaE<\YHHp@bKF+:@#4<@Qt:PiGct$YtNJ$C5FY#yiLKZ9jCXjckehH=+R
u<LQl! M!M?GclZiky!9bL+!8RZ5tkaCmy&mabZyXhPql=tFF!FGZ?11hX@P9K<yW=LQGY?9MdkaM96QM<k6Sn:
H+5Ije hMuKdI&eC%y6Jcnc6uwJ#I9k6F*m/8Y9y?\H!<pK^bcFERh<YCW1HMGQ9@1/pVR>5w#K&QL\t5twpnY!
9?*Kn> iA^?jMPZj#C8dZyE!pK\Iu1nAI6<tPt%l6LlINXAdRtTyZJXiyXRJh:%RT8piPX!#jM##y?F$yjcLJiX
p%cyZE FV5I:IYKDhW4QKt6lC1?w4<h<cIq8qm%4@!D%#?BX!iCdNCIWjwyAt&>@6dn4%Py^B/qY9JM$!w&pmYy
VnCDkJ X*I:Zn!Py?@e5u%NqJPVhqpQ5HW6H>dm/=M#%yik+dK8/>MSTH%pPhm/$K8T#jyQk4wiZ49Yq$+EXuVa
pj&%N! tn!\5SP\^4L&RI^h@!qkR*wlA1!KB9WqTbXEuD!Q5YK6qJHXTeYGC%dYtEkVY\@iQ!*tMmcFG1hpI$e5
=baT>i 9MdyuZCFNX1/a?NpkQZDlBHLCK8/YZX@R6!pjap<1!P\RB%/AFXDS9bqtKEk9ZdYA&ADSl\k/#<h1X^J
1KS8QL J<CuXF:#E\61p6BCjeX9^ShJXn/9ulDdC1wnM?TC1p\Kwk%D\bId1Y5b&$C*RwANXLB/w4J\>Q*yeC6:
RM:Rb% >>+5AIW:8*pqaeMANW+F8^m@lX85:J\kAXc&uE=<da>AQu#G?wlLT*YM6TClP8y#\hG/jAYl%*Zll^L6
N&dtYD BZLX>aycVXT8Y4cy1Na+YK^aB!6&MNl%pSGHbiEI4D1@C11b\/y%ZuVSD+yYBQ<uwpF^NmDCF4SehP::
F#t<QW S5X\:@:H*d8WyeuB$lXZcI<Z$:ji5dY<TjR=X@VMTY5@??J4W?ZD8F@1aK11QiPwh4HW1<yjXFQ+/Wc5
hV9=Z* bcbK4p$h1wlcNZc8Npu&SKeAY:c6>SR9Al9W1\LL1PLiw84R<RTbemZ*N5Hd=wIquRw6L?cC%V5VT4DP
EeSn*Z ZC#S!44*:6%>>6qi%CP6mBJ>wIT=E^?#qNlY4^NbmVVmELC<K6N>tMdZJc$N#98tBhtTh%TDHQ@!uC6C
HZ&Kk> G\:%$=B8E<dK&?/wYeK$YlNhHKdaQ*:#$e:P#e5Qbta8#*R9#*\M>+QLq#@==JXZ=H^uwF+^YiHD6kTL
AQdC^9 Zkt8<$mMQetLdpXdqNdBPubFC9bEF!^*+QStMhPdu4=:N>1djuc/=@FM!cV*plS4cZG^hMmBcp%QpSEL
aElK=Y \haCZG8<9W&C@^PqX*b!wTaM::EXWAqjeFTILTkjSk*4C!#a%=SA^St9MJSeeT8hN>NQ<n5Qh@:\d=e@
j9ijmh :u@T:$@*y/iui?ViI*@5>:9Z4u*<!Z6$@jc*dFwZw6j%nu<!/Am%wyiCe=&/cIHXJNq&4c&NVXT%E=I=
Gt\naQ <S@%/Iha4nKj/h$Fw6Hw>Ljj>q$Q%EuJipK4bF%j4C:eEm?w<=I9A#ulk8XPjKLLNVT?C4$KB>bcMck:
FapY>@ w>Jm>wwJX#=p/k^KqAcT^VbeILW4j$tmcyAh%>8*H<^p56q5H?:V&Yu!mh#Reu9p<X4@Y9dc6di99e*w
cCqRhw BqyPiwAXauX<89D%aZmMbhQJYylmu<m=GBi5qlEZ*y*QJbQJ^nMN1\8ua5>%5>>tDbwDe:RMKu%+bI8G
M>HwYA &m>t=9e<<VyqBmIF1!6Y&LD5Q9PZI>9?KKTG\=Y&YbA?dHj5\QSRbptD<mctX!jEl4FY!i8>QVjV:Yiu
*F>=kA 5&IJ1n/!jdjje?Gw$ah?>8N4d@?:d\Il>K1%EyFi:dDJ9ylNp4b%Hk<n6HdaE^ql6a!aJCF#S*<>9^\D
maTe*G 1w&lb^1Z56P8=@:<A<81C8?NI^8PL^V+T#1MJQjPS>N+TMH/Nm4C18jBXLFi&=R44S<Kt8?GTdakB/XT
6aF*Xj 4*dHy>muPHGHhZ:\5YR#5lZ8H<4SV1dTABY6QmILT$jLlP9&ZawZ#Qp>nNaZ&G%h4@ckLS859=buW!b8
w1EER+ !SJ5E%q^tGAZ%5:Qa/iWc1NSnLY!jeQ$MyjG^8bLkVWFYEttd>8SatQ6?9:^@uY@aNY=L/c>J!eMK\&9
-ANClD 0004074dab600110334 Page 180 of binaries2.zip
ZG8ned @u!+VX?KetEjXN9HF9*PuC89JD6Qq/5e=9l!A5t%KR9B&6LW#E\&5CSXLFmZ*F*%!TX*$G**+@jRyC=p
bMlw94 :K9$1n8^TlLb$QtEN+:#J:Y<W1^wWKD\kRW:>&:1NJW/BcTNS1Ja5jy>/\QT=J@Q=jbGSChCjJ:/nM/a
V$8h^J J^h!1WbnD@JmKHmknMWHmcZEVRtYp<X!DiVDhXt#?yn!$#wAqy+HnK6W:NPNYIa=*NMYFmNjMZuN9$>*
c>b?6$ R/H1kk*wXbGFTPbGZdh::bZB9WSdA+8u:RXe%6FJ@=KRLFQ5Ct+yQ6FTJ<EX5J+Pub/iA6bm!?y*Li6T
8#CpCK ydYL5q@XFa:j9AIBe&9lcJPeBF@Ry6Q^@1Kynn$@?<9TmYXT!dScK&9:aCSZ1Xi@XQ%w5YA=%$+I&E/+
E4>dqI Z6FPADXSJ%^=N5\P#equD:1Cwy>5iIB%k#hCF8:S:8Z*Rtd4N1=ijcNk4R<n>wu\mV?%+4dIubyI5m9?
hcVX=h Gud88XPmX+DdGAK\ltGNDR<j1W+\dVCSL^ctH1/5ZQu5\Z%Chcl+QuLM\bb8/aNMXR!8mC%XNT=Y!jX5
=Wp15u li?ZIF#=?DXAqS8<=P5DK@VK>?eE>%=hQKYV&dBK>YkYh@PZ@d6lWLEVR*pD!ZGjj8/F/bX?<GY<>+w9
:dnmAT \61!lLW%\j41h:W=l*YPGXuSNQa4%8@ED%K^!9ntEBl^a5#1i%+%Ye^XXYiyhJ%?Yq#aidQ=#Y@ij#%B
tVaAbT 1DdY+5eC/&J<%6FG%E81%lFJTK$t^eycJtha4$81jQWNPt#WRpW:k^SZS\yYA<u?*BuRSySP1M:DM4jl
yZ/VFh K=>hydWM+/iJXu\bMPK\?N4ui1X&HHZ@?V66<>yFiqZ%kL+@WyDNm=JC#N#Q>M^JdF?di^T^LPMw%TlG
ycuP%& LQLT9JJbNVuW//VBZ!L*^cp44@:6**%QhV*WmI%jH#ut*j>Fe%JS=ZqIZ8YZ1lk5%>C$/T\$98yW/Y>4
W8ccWp a>Z1t#TyZl&pYEt!E^yjjX%EqMGL4Ku<<PAAJImy>khR#i4=eE<B:nHBa5WC&e59B4jDcGDqXBa%&:VS
u4wCTj KWPdb*qK8>\YMXd&u4AVV#%cZe%aX5a$4C/eZu*LME6I1=\1aM*jjQ?WbFjE4d<R*!E44R/?:AmyPq@W
iIHuZE k&m6aK=q#4YP^I14hpXXNekFY1yZB$janqJ1iCcF4BD6j?Fu+ewLP#%Y9?lk&W&E%=DE1ehDdE>/eI>4
ZZjc$? %i%Fcj:p\iQMm?9c!EGqVh1iHQTkh$/=H:MRY=QDHXZJTmQ?<j#ScmaDYJPY/Zq>w>8%8kI5G>4\NVXZ
HCl&55 @#YX/tqncKlaZYR1yuDVWqcPQ9bm%8au8!Iut4TiH1^Zj4ckP5B&$Q+Gl?8XH^9Nmn6T4?FG4LbKmFEF
bKS=?W *R#\=yhEeL\8FVDSZTw%JHN!?#yc16YiWK6HH/JA>n5baLpnPZw961BXikWH:+6ja66kYjIEaN91eDbq
Bl@$FL lH*%+hWHW>Y1EaqE=m8X5Ry\NdIGILat1pm5%\uX?PQ/@:#PMm5cYSiqp1HG+RhYJ%9ue!?6K<%*hJS>
<BITCn MWG9Z+XR=hp5#MCYA&lH%!9m1tJ5J$lXhtp:568E/4KX=nh@/MpMKJ8XbQ5BtDJ9+l<1JWbyE*jlA/yY
Jl6RVn ?QAIZT</<?FZ1nil$md@?M/j@a6N&KJN\h5Ve4\n8n!9Q9!#&*ZN/8=SyFKyJJQDhMiLSXbq*kSmJFjm
:uZB61 chHw<Y*u8RaVK&AhX@+MYCjF5bhnmpIlFK!?%PCp#Pc9jF:6PH4nXBP5DLJm$M/=1km:LujA4k6V>86X
F$dLKj <&Hb?C!99QG@X5@6B\ZdS>E$=K?wCdQ@%$M%D5&cqF=hn6Z%bti>D:>CNc^\G#$n^4M5beVCm&Z!^LLm
RqT!R^ F#:/pwF6j9VqI^j1%I#4Hl$B%F^88Jkp?::NVKXXGe6N$J1X^<@F?PP68e%VIhdE^LHIyEnGyLY8WVhS
EMjVQw Sm$pVMqWdiNw4wVX4*caC$8&/9h%lF+ht\&C<cd%>hAPFEX9&?1CIn=/9jLGQ&X/Lw1Y$%pEYQcZeK/W
lydXG^ DjapPNaih&HD=bKNip!^H5W:c*#+wpcXk*W8E1#c1WR9itD:m&G>89NG%#%+kY\h*jtb/WGYBA511&T8
qeWlqd GC5YG:E1*eypbyLF^F1XFcdEk9iQy=#CI&:BkHY#!n!a=Mtq?ILeu&Q4Xm!G\t&=BaH648I:I<><kS:H
>dTGG? X#5MK#y^dJ>i6i54yBQLl<:A9AtH%*>=Q6PVha1Eq9XlbZ<C+qp/u?9B^#VLk*8TK1y#8F/nQLy!\bI%
JbSlFV c*:+n>KK@eQPRYAu$#NVBdp=uk$BH4:^R+8<<M59jDR%FjjMcmbCamy=5pk^pWw$pl:dwqa!%<c4m&JL
X*1T9< ^QHLyRXu<mlBi%GAhY&Qi#Q=Zu^SH@unM+=648P:pJ5ZZD6E=C4$K5N4KFXj>c:$YlBa5X=DtCwd6u%N
kGZW+m ^M@8Y/:A1ya8YB=L/ceiQFyY%mIj@c+RPSuY>bAL>*l+Ji8Rm>WVdMGN4@=CJA%/wSQATp:m8c8::4&w
E+MZ^l P<iKHy+:Qj\V9HCI*4&8/=bKedM/ERH:Ha6XYCn*ZLcd%KP:tEawXJw8Hejnp:h#y:VFTP1d9hKmkA4j
>5!wh: &%J:L8*bXd%>Lc\+4!:P$>eVZ:$q=npZ/XW#BQ44T4*m%Ktnpi$MuL/KP8h^Kydy8dK9kNn18hE$A\\+
DSRw>S Y/%Km!?Ljql5hj58H>dl!yZtVb+4=P4!a?&NyD?<=c6#hMZKiu*!<hG1T<8q1$1\Q>:<Ptt=@Lq/4qG6
Q8^LYl Vp^E^mGwDk@Q5&eE59Lb=Pa$$6GQd#tVt=\14Aq\bXZ+1MJpMluLyh@^kZW$5KGTdVa=%:!e9\aekQ:K
R$IK5! iL<NdwBR9SdE$NAjaAi*EZE/9Q$wpSNWtRu*jHE#K!EVyGP=5dFp5yYEXStHqLMT5T4\%>aqT@E%&KSP
t9HHE6 XK<W/mGl!k/$It8t@!6p%+pP6nC=pF^qJ\eCP@jk?%\!R*</eRin=$:5:c$q%!BVc5TMKHJ>$G^e:FCL
%^I>IA $?*BEFt9J6k<kBT6=+w1=FIuQNE=ZB%8NGJ*dD65+FTuHeY&L6puW1%Nd5M%h8X\aWDP%Ap%auKVZB*d
:@XQyX %!bYF@\NpC5dK&+hNXIXq4Y1/EnyVt8=$VSnPldL=bLJ6jH^9d&>I%ljHE*A+?=8JJKJEKAC4GXqLJpP
DhQQj& k^WjiFHZmJySW#FqaEi<>NXd@N\N1JX?6jDu<a4B1BK\^t%!wB/<hy1w<FyKYEQZ11RTmhNEI&G=RZMR
Ze^kV5 ?=kkKb4etn!TF6^+np^cn@hjyqmuh6mXk%84<<A<F\tNkiycwuc=HHKFdqMPIKSiC%m9!KLWQkNe/9C<
*ANy:# TR1&I:bP/Eu^BZwhmTXTqTn^5y:Tc>@%b:4Vjc8XY<:q%6cT++#yiISkuVmckFYqN@JFlnV8=PytDNac
X$CWcA ql/5H&48n^S6^:@9mY>IYd&j4BlSK4+w1+QVY%89*S>KYSa@dZk$l+>wJ6hIJB4FCQ9ZZK:$/cSkTX&/
=w?Kb^ qh5W?XKn5deQm@k\QC#??kY!**J4an\G*$>E@LJ!<Ia\pV&^c*Vbyb#5cp/G6X$YF=>4XJ$BL1!@eaDm
HwIJKM 1kZaRYS^?R4Q5k1@aGLbEEYt/lalK!c!6bLDPRI%B#jm9^BhmRFZ\IAnwNTn%ap1AX!6X9<CQ1yGSNL6
iS^w:# Ywbl1KcEwPwKCcuN&idXk%9<h=8eQE!uTjJ+c#+YMin@m$4B86FI/uR#a9G96TIbkt\tE#Fa%%I>*cEy
8D>%^& +?6^i18\\KmCYIhTi*?=Q$4qT5u?DVC=e9P%GGXiQFTqNSIXclWL!bd%1<K+Y696G6w?QCC<e5H/49eY
beNYLy Ql!5hAaF&A=?*+Vha8I$qVTm4w9Hymy#/6G:bT*HapA$q%5iI/8qMmdl8^HKh=YT=Y^ZDeWY$BLJ\R&!
yWq*il aw@E&WQQXGVbwnt4cbyyI&$c*qZ+JR?j#+&:>&:RW<L\YIPb*DLFuQDqukVK@>mLS1PwyFI8:DEdl1Rw
Cb/I*Q uSD=$nPd==>@94@QBV8/j:N=>k>@in@F6B!dhJT$hL6EjVy?pc/aLCt1HC9bdM*#ad*K<TH%b$/e1$1J
jt<4bw k^HYZ<CK*W*JamN^Y1!I+!L6VHb/GhXKdBP\^ycZChZYYLLXky\J=G1yNKpmw&wp5$4Su5PN\M$I8BqA
!k%ha$ i?AyZ/T6AuR6Bh98!d<^/>%!uN*Z>1wnL>&+h??i^*$eknRj=l1wncZtC%wK#5mTb#5$SV=5Lt^BQ5H#
J=E#Zy JWALpbXnlZZ>=5%Zj!PkNl4nNlw%hVADB?>ly&@nIm<kaqj>5c8I/Q9VCB<8PH1jR\j4&<!u<md$Ln#&
<F:qZV laKXa:1Z:5RkFKXIKPJy1>J5n=Q6kXTV\<ME/jIa$!wl!<S/1ZZJ5n/A&!YWK^G!XmbnMLS^8JtMdbjp
%VWQ&q !LBEjk4*\^KZc=^9ClTGDN?h@K9e@auT/Pn&^w*bi:NE/kii1JTWIYP+YLQM6EuBjCnPISJiS>J#lc&n
jL%Di: VbE9DR&NZ!hWPhu+n%jiy%54G1hE!+>\:Yn#C##^yt8%Sahjb%JGX@&%!@V>Mil:SYAdStR%4H4#R*CX
k#Eq4a DR%j>#<MLW?Hb=aVmWR^SXJKhZV/ImZtY8%c8hk\4PXqJqb8\SZ1\KT8IVekDI<jILIbe55aJpX:V6qC
dV9S8/ %P5K&e/RkMe:BWKteu@&Iju4>EJ^5:R+Pn4/%9dGBkk&Tn$eIAFik/VX58aJIyX1FVb<cLDu&^k^d>eZ
t8?ESP cM$/^BR=<dLW/8j:%?6#aqkH*>yMP\W<G8/I9EXhlwK>YP^dL\9h5ujIaG<Y\Y!++N?p=^N4S!5HJFhX
$KRb/q \8LiSEmAyZ<XnaBYm<B%#HCSDjhWnCY6I\6DdTZHwFwhy:XNlBa&8=AeSTSMDJcSJR!4XjQeQKi/lZlL
RJABep J1A$&J1w1EVZQhG4bD^#anNH1G/@6W$E8#F::\bLdXtQ&YChbq><%XwkWe>Z=yn\a/itC9X1T1ZBmjN>
6>:dPt lQX+/eHR1VVw&J!im64m<uZp^ZnTJN>Vm%&PWG9Lh<laRu4%V/?CLm^QF^bj%j@WM8L%AZ4>LqqpXDe4
DeaeF& e9iSmK>m1\QE%XcSW<&NJYpQI5p#+EwEp1RMqDSH8$i:E:6k6C#>DcKFBY#N/upedmbqT@>qJtPc^IhL
/l5XTD Zy#=5NmdVXBZ^#e&j4i>@hawaH&LPQGNi:PWWhSp5MR$q<GN>wJkZi4d*kGK=a@4>jySmmhMR+*aG5%@
k?*Li/ GhVQ>?eKEHXVR\&/b/L^\?>qy1MJyVQwZVupSFlhSESnK:qCY%:&NcDPpj/8D:REX:<S4$59>9eS:\^D
=e!\W> lbewFw8JJD6IWhjXemhA&:NcVK8^MZIJ^BnGKkMy^R6J<C4Jkqjb=wRkYJI\kY!4BC*IF6lcSLjk$/Cm
q5a&Tl R=pNL#Dli1YSni*jdY^5dANYEP#&>naIFlS4RpwM5n*kuYa?y@i9unSlXieR#$@@YK@@>*M!Z&1Mp<*B
1C9e!* JAttaF?P9@5eG<HC?99Zj?b:k^Rh1&@@e$Eu!><Kn>#IVual%+IV!J8$5N*S&?NC4*Yq>KAQ/&yhu^qt
?RL#AB H4!=te5E1dLN?u%48XkE14peaB*L6YVBcmG\Fbpt\c4!qeF$!h+mlnbDXA8GLNDTeE9Sw15wTk9\FWEK
CkQ:$B 6+%6a5QdXLC#N%n1FDW<IXmCF^S=IE:MA@=*wtX=INLlA?LC/cuc!Y&YE6GEKdWHXEq:mYE>j4RyB86D
Y4&4Vn ni>*X54$HjaeqawG!Hd?n:D#m&u4!9N+?pcqdWk!<6$PCkmlZCHVJdhaWFK1tpI>54PPw5W1$GTuMIA5
RHDhGQ hTC\nZRuYkhpI/Wl$c:&La#*^b%GMNWYwW+dac%YJaWq5tjy1upw6LYMHTDyWMt#Wqd#p6j>@Vuu*HP9
-AMuem 0003b34764500110334 Page 181 of binaries2.zip
/jmljX Hi&=@kQ=\^>@@Q*>P?j<Vm=TFV:J@uR+j+nhdFm6!<9P>G8pKu>>Lqt8T:DYHRid1=yjq/P%i^B6MI!6
\mkS4+ K%jC%i>%N5TW5QwlZ&$p1dyqG8d:uQwM!NaD8>S<T4A%lHSSq5X\6<Fk!TCddZ@=CNlCqlw&JFwV6N4G
BC4nZT !*m9kXwSKaGq8KtlIWM^MRqY/FDWKWV1I>/aYm^X$1cNVJ>hjlWM++i<lumFpqbc\!TwRu=#5X$=%yX@
Ddt+n= @ai%/e$qX>NAh?Ja%TqGd%Tu8pq!P=5^5XjhMcj/:JWDXW?PbYe4yXjNdpTiB:c%5d&h5aJe=<lu$c8^
p96kk= y%PhtkP1p+HGSpI/MDhZD9Z%yZDW+^ZGRnBe1EN+/A/HbbkW=pByH8?tATkl6YH+CFc!ShWT&*tD9C*/
NH<ptE &nc^>L+N5R4Bb6nDR8kEaFG\mqYJ\mhd?Fld=nXC4kb@TA+Y1N4uRIBh6=E1bnCR*b\$H<5tE8Bn*?qw
bLu*E$ 1Tm98@KLZ4EqZ??PE6G^/y5q=Gb5dc?=Y8E5itVEq/8YN#%Z5Dt9j^*#PFl9MXGP9iQ6uW#X9?Y94@JR
@$=$hm \4<&A6ZB\j1h*j%R$6J?ptk$E4TCqyWp^1phklWYVyVBEpHCCk?AFtpYTbi5&bSRLcF6c$Q/S4GIPbFJ
HpYB*^ mq*u5b$lD+5PX5dEM@$?WG#bEY^J4aZD@Ej/p=K&JwP#uQhiu8=>?HYuZP^T6:J1Q^d4t*:++XLdlZ^L
I%?E/i SeZI:j@Xm\5ic8u%M*$>aM:V/hG>bHJMn8W^y=%6hZ%aR1%BXj4Zw:nL\V/9tJm+$1t\H8j1wW>=J%GF
PDBea: t?wiQD+aAKDcHlI%wuy=P4KiN!FtT8q\lZ!bLXceVNJ6GEMqRy5!=4E/kiDdQ94wua<\TpbuC*<D>9kT
^4F!?Z tq@YK+l$Qa>M$SkLF&51#XKS\whAT:a5LW%NyVZTVNZ*H!?9QZ*nX#?m?!SBh9wQ%H4E^=h?cN6@SbWy
!dWTak IGq>e*d/1cNZX>PduLdK*6$:MiJiY/i*/6J&cI9w8uc>!iXjI+=in=c%@?w8PYtCHY@9JKmR9t#=B<Q+
bq@wpi ^9abiHP1Eu6V+aGh9LQKW%>aqRP5WWc4SaILC^*:?!uDCC6d!*lbq/a\!RbbbSFDwRjG9\KNI6tQ\MQm
^e=5#> Q:FQEE\ctW5bkk6lE\pYZT\w%1SATJyn\%bEMaRTMm$=ap*dd/+>jjyZQ%dp*18/K/?ePKEY\n^?*HbS
=DTDDl L%Q+@%951GK>85Jl6eLV6YMmX&5@6w+&4qw*%b=YF\WQX=FT$?8a&<FYVi4kdYQpm5T/BWES4j@^wYdF
RT*=nq KqCcFnE/+uwY:R*kwt:F$ua6dH:##Vh9:5<VP!cLF>Wq!PcctLtK9!/1#Mek5wkYl9udD&dIAG>L^jJH
S*@J%a C^kTa+GC!wt&=tMy/=Epjc/15AmG$*dw+h4V9@5u6cMPpqbVWGY\HYy%E+#Kc%&<u*Bc>/>c^?qenV&J
9kyp/y ul1Sc*Gh1>HdSL#t:G56>%16%\quEqaL+jkuc44MYI?DYmXYV:q%#&e<$d&<m!q@a\q&\6pw\F$Dy/hH
^+t$l= Q:$WT4E\PWJm=bJ8&?ddCKLR4WF@LDRLn9YQ:*+emj+yk/ETRTYybnkthkqYVl5IW<!qSXt6wGJ\!cpk
?%LZ/H ll/Cb@*>L!w$!NK8&mhEcR8^64Y6C4GmZ659<pI$$88w=q>4:Yb:Z8jRCW>4T>X1iPL@Kj6:c<@T9/4p
LJ&Bd< N?Ji9/dicGe8R&K#JdGCe&Y%Gn:DJ=iY:W&F@pZ$Lwq:1WcFYN%qNNd4Muj=^C/&E>b/cwjkGpbKYF>m
eh%e@A T/ETFayN>eeeHM?d9*$@mn@6^<pMBp#d&<&EN4>N&a:R1\=YRcXwZkXTJXYI+4@y/N1ej9k4ZpZK?=wQ
mlyu$* dNW6D:F&dK$wE:#%=\?Q=MbY&T$RZ6!Iy#6/nY*EuuBu\6&%Z#@BRG6AXn5k%5W9+8E^4cSSw#JS?DjM
k$K@YX c:cIK1wXatFbR6ZGi<@E=MPEJ>X!=Pwaa6ZVCAR:P+69euw6+G>t$yAL#cMkBX6D!lcTX&YVlcnN*<tE
l=8ARI MQe8^eAbny9IEG<*a*Ymke6PPAHR*#>FM\cPl=XCFTG\n@u/?1e/qna*Z@&q<1\4^#yVQL@R^p%L@*JS
&i%^*t &GAp/*@mcmT?8VSY8%ik1?hbnR%5E@GcdSTeVTqXWD$X+6##>FyX$cS9V%mb/uGeTy%Vlb8TmIdBCL@Z
%j/VtC 6iTY1!5PJ4XGNdLPS4!nJZBLaL!Y8VWD9km6n<C:#1P6yReyWCB465EN\!uDNMK:u@C:u6/^$R<+XlI8
Hc?S+H N5MjbSw!KmaYkm%^PX>P*cp+CR6TZLI\P=/Mnw:i=6TGQP5^9&p:#hW86c&&%\unDGN%Ri@<:#uS\Vtq
eZb^AI wpd*TY<1Y/NQlL:*6Yy^cjYEn4KEDqe>lHY=%@e9k%n>SQW+WB*$G%P1GCe#Q%@jd=cYuBbTL9hPF#KN
W>Yqu* StXI4NI&%m5+&FqeGMBee>RFM*8?t$\\JVZC@FIp%Rdbc=6yllPj*NI/E?VI^Y/9C<jKk5&5Z>yt9V1Y
qy&B<B YK=uFMXj\dV5qIV:R*qek@w/%R&^!ATiFYiRyFw9Di*nql^yk%j?EJi>Db&84h=GkZRCm&wCnM?6iF^N
YN<C1F 41AuQK=NuqXR1=an89T1=P4Y1#8M#dpE?<qja^tC5W+m%&=$VGJhq*C\96A@!1:%d4uKd+%1JWPee$hP
KLMyKS HBDn1:Gp/XY$N%%eLHdZ%!Nd1pLNM%w5He:9^4K1MdEAt@6kZe1WnHGi4K>FimZBIqkdnT@iT>IeC@$1
KiQ6Fy e?\#<@HqC\>PenYadP**QNNL*W89uZn!+WqPb&q$h5miqc46@>KS$K8\jAXN411:5=B5\h8R!4%@N#:l
Q5Ne*5 IX5q&Im*QK#H\&Q8BNc%F8b*q!t^PT/M<KCjkmcZd!%N9ji!PI*Apc9+6qF=TeF1>pI$y1DAcZdJw%h^
d::DBV cNJm6qnQLE$q*HAm/*R/hYbJ!MX88\T:#Xp5Cnan\h1$ENttSc8PDSdlW5wP\e?$##E\mjLa%w:h4/$L
CHu*95 @<*6#lZyYi9R6iwhK$Z::DFQ<?^eAR>Lw4Pt/JiTl$:^CXM=QD>JZ@CRy>6CJn/Sn+6QJmJXt?l1?Nic
!kYdwj <dDLmC9BFmATB4t!YCeHajAYB\+\PH9%uitX9bLhK/WmAtk8KpjP+&CZ1:lG1w=M!5cKQjWG5+YaPD\i
jZl$cj <*RTq!:&*Z:yaiuKaAtS\GJI*EBqy@:?55&&GLH/lEE8T/^tE6@kB+I1LV4eMp:RTmyY1@u1dThCZqu=
?eh&mb <+K4ejDV19R%l!hlFjC5MEFX6yFD!wkXFA6wt:Z$p$GmZQN<\!?XX*KhmFT9TFR4md*?XX>V:myMFG=e
%*1KDX \RAa8E+ib/\Buk\SDyc1=u$Q!jw+ZGY+qI6KtVyD%!5dam*S1hI4KlbimY!&J>EhVpEK1:R18Yy/nd^9
Fjj8mV WcyDeSPcbBIy<MWbkP$GS:C$BGK1/9L6Y@AV=Tp9yTRGZc8yhuEA*FhP!kAb=X1=8HC$4De&yKZ/6GZX
dA<XDn 1WyEe$kQ&*1&<8?CD*CH#&EWCukpHQ!dZLN<9#jnc:PhJ<AbiKC:q/k\8!/\EY?>Tec^umW=MDa+4@GV
D5y>ne YAu4aNmi<npqPHT9=*+9P+F:F%=E11mTjuP8m6QS$T!iKEdH5FV4Fh@hYZkb+B/Lha@*LNb1@c@I@wqV
D4SE1b %\#4NM@VhQCEKT!:&QX?u&q4C>LKT4K?qAu1GL4IFX@&4i$6Em461N9yQPa5lFuy@QDIcd/p5G=8nwwD
qHnIdG bhkM#/AkpYw4$MR:nXc<EXqAi:>RwHh<5/TV6%C*pj^EHt:+Rd/Ye=Y^pu8>lKbZQZ>%/dX\GdGiBKT+
h$d*ne >IG65CG55A1FT#@ZD@9S5H1IB8HTBP9S/?#tEd?9QH1q>*e&t+Z:4eY5hl!l/wiy/VZ*eXIa+w\$\JV&
Np##H^ $ARAb:H>M!eE$bKMqQltlQD%&N?TulX*6K+capE4Y8J4hp9qtJ^dZ%u=<dWLD6bbS/:C9iaJBB%ImFkB
=K<>lu LIJe%Ee4Z1#b+Q$k9n^Y6DqmSiAGKCPbjJ/iAYwEu=y4^$^PJB^=Vu%au>El6NGd^\E1DMTK8#ACk+E=
W?b6W: u!\k?pw<hjuiGl?/J4C1I^cnG61k81I1lZWeLBWtqtSlkk@C$5Bt<eK^tCZyLqd%mHeYtH^5bWT+SJaa
=iAQeN bE1t8AF6MahPaI6D6t59CG4XNm#<$RhwBbQRyN@5%@cKuDBZ/?yWQdn!>VQ1y/Z*TSP>KpiB/+J+Fb4l
/L6eX& %$XVC@V8Tc*C4<FQmQXi/%=489Z?StGnMBPeCX4BwGXbANc!?Dq9bRm1^4Nb6<ISL%pbn?4?Nc:q4^mj
Ga?Z1^ *!An9E44j@&VnaB%EINlu5ulmS!j<TwhuFuqZuMc$mDh/apFG>YQkXIFy=4?FVA!XWaLmK9APt5R+HcP
DIPNFb QC\H\65w%AbE9N&\LX%5@*w@+#JWFk9*EGK%X65yXELB%qXYdapXX/<P:j6=BSNFVJZdT$=HLd$L/X49
#VR4uG $lJYYMAq=tuPicc\ed?%>Z/&Nb8>q?XB#@eY+jp\&>y/CFi/NX*a&IAZcCbyBbQY85WnV^@p+ScBn=\m
1Yl8ma n\81<1:8+^dE9Q1!1:nMbJ5tEi4kIGF6HB^eBdq&5^WY&=nkFuw+VWjC/NG\tL8SPlXWw\X/bLLP5Y%8
1X<Vji 9W/\j>Y^*yJM?ZuSa+qhE=4\lc<m^d#KaXG^NLQDHybh4AtY6e^=LD#=:NBRBL=%ew9Fmk@H&8eeRb9&
LT6iF@ mb*ZjpT59Pm:<9e@u@X$%JyYe6$ejab!#bQSkqekYCmppS:RZL\HLL@EZ?VLdA\8?KP*5pCX\G:e*$l9
LVtY!^ JAE6kE$tBXu4An=I#ydXHPXmi$/Ql>%&YJB%%ni=J6cBc@w!FmFY@Z=cKn4bGEA#HLcuuGKVZb4!@ij5
NXthdW 6HQ&yXi8RjiIC1/8mFkWJ1bun&Ti+:HDm84#>PwTdPSntdqt/NbA/!ZEBABbakR4a!a8W>Am:9qP>1!a
&51BhW qqcPZVqRVM6klF9cK<+t=544d$^Z6>Qm:elj+AGLKFi!uhGbaQD?BqA:*M8CPGP^L&P^:F59aXj$L&M9
Wel>DZ \ij*awj*Dk<Q>=yKl&pc!ZSTDA59T\HGAYK&w865:ZL85MtFXjd=Yc:&4@CQ^+<D%yMwX:#li6HG\jwy
6mwhT= 6YtSC^Qu8tSNhNtnX+h1IdlS\IjklnLF&4bwPXP*KjV155PL:F=l\Q5dZlN&5>Xk>Vb5X<HFbnlk8yRS
t?wXTK c+mSNXYKii1>9%?&F:D:b<yJ^HyR+dwlKjLaq8Hcm4p1P9pR&e4Z*#l6:l&5$*^mK$VD1FiWc>T!knMd
@>CVcc kDWN/A=nd<WA/E8^:@Dlyhl=@9k6?K*&AP^l?4DWqHdaq9G!!qbT8@1DmDqwSYaAdZQE:Xh#u9&%4Fi6
8yXS4S \/*EYk<YGQe%?pG1p\FcBk^!XYcaFN5ji4a=8<c%M^jYHF8k/Idk!XhRYtLh\XJAnF<C*JK1T:mnJ8Ic
A=$XLl P$VVBa1FQ>HAWpV<tSMS\^i\MACGJIhedF=5=<mIR4G\^B#pwqbNC!eIX#t=wX8h9<XWa5WNBH/c%tE6
p#?k*4 X!4@91ahcPi$YKT#bZ6u#=Ib^qnYYk<Gp^5dTNWH=M+DTtD/Zi!:BN>:/PQ#QdHEw%Km6Fjmec+WKq$6
Ly*mBh qZEk&mF+HuIpVA:amw1w%B5L1^:Y%ZyXM$Eq<KpueZMn:5IAM<^L>k*d/Z\G$9W>Yb4Xn1y%$4cIXC9k
LmDXQl *KA:QSJb#SILB+6jbG%&XNP4C!^nnZ$TE+4F#Ph=GT^?%c6aVG!k5u?G%5I$!H1^6MTkYBPCaNQ8D%u+
P#t?mT d1aN4ZWXZuBatZNy%W=%em=LwZCq<=@Z*Ae>P&&ZWK=uS$ijLbAbS45bVAbSkKZD\$iJ&QpE$D#@6#$>
-A9*dh 00026406d3000110334 Page 182 of binaries2.zip
l@tb*t 5b+i^Qyh#*j+J+um?WVmWcKa8Q:wVN?bWq<j*EJ>IiAbCwZKwZIHkA$NAh!4pm/E#DN1\nQucWik/>Y:
qaDR+9 yB#?aZBP!BWMMF!$an?AC<F=IVW9=:9j<Tu*ZFZ8XYVApCIl%\$^t5R#pSXkZXN%qMCTZpZl*/6ZyJyA
9b$D/? 58^p*Ye/cI5Q?P%!qW6N\55KT$^%Scqa/YFDGC:P?#9bBGPB1Z%4S&XB6L94wL%Pclt\@9nG&6P1hqyQ
\dR%W^ lX1ui#i:Sy<6^@MLnDW=k%RQ4??XAB^m:iqBqn&ui@AGlQEJS#FSQFMM:<JD*&/jGMDYGeBaKDmJtw%c
lupW6D T4GitEt6qhLYD?9qylTIFLEGcIMnat$B8abylaHeSiyL=eYSy1=mp>S4kdk&!WF$k\w5E+B9TlXmXTC8
Fi9%8w 198#e\YwCS!j^GV5=M=$ZCh\Vj^5uWyNZJLI9>%\l<AmcPXl%>h6$\#lKR6^nIqYiCNe=e4k9GtdKtRT
whI%%< 4uXF:NGw9H::LDX\?X@6<DN+ZGP%>pI\DF\ZFmd!tV^/^GRT6Fw1QVwDcmS?y^HtV#@BHS=@kp@l?ZVQ
le$WS+ #b/j^u9G^&<Y^<Qn+jB8iDi%&=jcVi*9>8**:cjkC8$L88Y!$G!RR8QtZC%D4QWlYQa5Ka@MNQ1^FRSp
MFT8GF NwSX:J#1N1cedW8?Kh@R<mk%8*T=X^ENp\XPN:pGcdbAwbMMuFRC8#d6t1l#yVp5X$VLq9mYZud/:Jc&
w5%EZL Cp^<%b@^LI+aDZj95QuF$CuDqa4t>SPa55L9:PjEB5VcGRlVVt5!YqV49L>PMK*nyLY/#Rh@>t6Wc?@b
RN:u1j 41Xu+F:#iayipY1/hL*9VLHaW:^JJPF?Gt:j$yMa<Mt*+?QnQ+*n&B$jB:L%8#5Ahmh%KyZc*W<l*D=G
lilmXH i:YeLyPnnX4cIpB9D!iqX!@YcQhpRHJF6cJe=\L\c<68hyVqlPJ<bLnnZqY^KayGGFFil=Gk&*XB%1XZ
+V^w?M FSAn%:H1iFn1FdX/p\XLyul^5YbA4N!&>VbqPHqSptm+&$C4bQI5YHC<EA*S9Cb6cEXD&@:>QC/LMY\D
YC?M># 1VLbuT*Pbtu/y6L?+cn1<qGn*^LEVJ6uq:4GFla!^BXijwl@#9V%QSyQFG?PI$Hk?T$Q?c!N:9Fl+Dye
u*wyGS Q#+\Z9>=jj$y8P*5:J#cTi&e8kncSju&lWwwYlV5DCk&/1:+8*jy!j*149WTcV>a+RCAdY^pI@\XaJ$L
%\:HPd WIZJNumDp5?\+pin$4$8/*wq:\ymBblI=D4eakpGG=SkHeGK\IpuhCJ8@+4XJyI4a4&JbFt\6^b4bLCP
RV:kiR Zmi5wa#eV4ihkbD+#y&GhdWFILN>4TPC1=\uRkeWE%X\4eAW\VTt+JjE^SH\!RAC4=NJc?iVI?*Ahwj5
R!lJ<8 4<t%49YCY5?Phn$DM!!^y55RAy$y:lbJnSyK=<QVI>@Kc*lpiHl8GMeAwB$aB4kDy?wQVk&eR4w:KaAL
AJZI+q !8&DTC4N&Y%WXTmeI#ch#bjKDt6L*yKBTaC/&4KK&/aA:FiB8SdA&t*aamWt4bEI=bjHQP=XdplBM\^c
Pk=9=I QW#wA$SLmlW^5b:ymAT&&k:jw4Ayl8?Pt#mWaL%kQZ1N=\pueLY&KTT?&$BkM<B/cGmIq=uppY1qe9J9
X!VeRy @5i$y+1QDAb4w:P^R@MD#1wIjD1by=cK&uu6:FZ^R6jc&:6=6k8+kuP%mC5+R\^@m46pZ<eJ+<nIcYVw
k$YD?u nK?$n$iRLKBF8AQDA#CGB#+jGDmAD\/AL<A>hSGmKRmX4:KLZc<!^X4kXM5PG?BSX%6k<Pay:QQSMneZ
>69wjB CG9djpt8cEB4bc>AdTQahMnGp!<eMbT5a+uXuA+H^G5k?4k*H1c=HJV4VVFa5N/A&H*AGY*ad56RHC!L
TRtPjI ^Hj99L*h*L!?Q9VEYlD4N/*XqdyPj?DkHi#ta69Gw?KW\dGTER/F@JXnapcPDQH*jFmLQD=iHQekSm?w
i%SI<@ >i^t%%JZ%:NQRc%a%p&Y4&LC$4eL5SBBJb\9M5kZ^Z&peYVpleaZS%+akhh=lC#nTGD+\h!DAMq&8AZ^
Nw<q/w jw/*#\j1D?yQyZb&W$CY\/ibyKlPcE!%:V/1d+lnl+N#nRGBNWANZET:P%H!F<F\CF9<WhnEYW:edacd
j8NqyC tlJTbAyJI1GB#iX$B$8JV6#LFiB^NI^j/McNG$K^uy1Vh@$<9&PHIK?=R@M=tPDe8Z9*:Y&:+$Je=84^
DC9I8\ wc*Pp/5:Btn#&tN5qtam&WhknXPR$=d>hYK:K>$:L<yViQn+b!L:^jS$:#SET!DX&dM\8kn4Rl=L8pQJ
*?j=>J eny$D4l&k%!H^+GTWGtn8CaSJV#l+!R<nVVTD5VGB?V&lkeDD\aD4\$HH1\PD#^A/RLbW\jweZj*Ij>J
KLmJGM m#VYTZatc8W=:y$C#jX#k+HX:=E4aMW?luPBkdp=mwb=W^I8j\G=R6lEFj6yLZ9qcBm<c>N%lkw\<EIm
Ih*tRn \IRXm#G^YJiwHC\tP55m$jqMh:AAEd$4jcEdW4Ca/%RuPyyi+@ELmBM6MT+Sn>?>i/Hn!eIaHXJN5^##
PjicL? k>@Q6%&D<GpKF>lei\i:kEQaBGKAq!DW414BGC69DW&we:Qp+V6+4BIm@cKZ5HcSYqG8F!+BX/\1>EG!
$>Sk6: Rmb+?F6B>aZGEhEWB<FPE6ZLnbeu8RZH=Q<^hu$^dX=b@yF$bNpJ1\VNY6RXFmMb%tNlMdB?wcJ%BG4b
y?9>tk cB&Nned&pBCLnR\jYXZRTmRII&XD>5F=mpc^G?iy&c4BiCaQKW>SE6pK*Xcn6XTncJW5A=%aXKKKc1yS
FE+Bd5 +5e>j?/>*@$?t?:i#@>CmW9+?ZjP:=^::nu^&ey5MB/6#FcmqYARd6EliB!CK#LWR>nYWCmDp@&IVjGH
KZ<>>y AZ5L+uF:9#Y6t95Ytq&A>SuC?kn6<DL^%eWuY5SJ$XNd&HY+^d%TTR@l!qmwJSkL\N/TlNX^^VlR\>WC
umJ>nl K@BX9SY<!>uQ:Vqm4Zn?1Vu&PwcdPYTK**@@4!<B%Q%>uI^E5Qd@\!<RTd!\ikKWEyd\4?/5WC?h!IE<
Z5$N&X VpXBdVSkn8Gbuqdnu&G>??VK8>mat5nKtwp&aHbmAP5@nw%8b!/+ENbJ>KRt1ADt:C#iAW4^lK>t/XX*
N^:qtG QDkdBYmB5jRRlIhkJSIeRtR:ZYek8AXSVIput+NNti*t6V=/!4%tkKEA/nPR\I?C*e9WRAD+8n\&J$/N
6@\=*@ W5LyI#E9ZMQXVQp#Zc>cF\Q:*iY*qTT&Pqlb+YSN@HPWe?*c6@JNyIj>R%6B4It^/d:*&c>?QVC^Jmhh
Y\Vl#1 mbaNE#?BX\Xk?\DaQuTyJ*6:h\Q<$X/J<8EN$jdqSC$\p>JH*ZE@cl:>@ERaaEV%^w$dY^QI%qkMe+Dk
b@eF\P Y<eA%j8V\=PVDC4RM#+XB+ICk6*m#1Dme5I4*&\$Hw*DDaCNS\qXRLeuPkRQFcI5tGKMcFp:+idP$^d*
#Q>@8B 19M%bY:tBMDpdn^:%9MMAqd16lSeZu/G4RVME%aumc:a%F@59h/%8qip/%qB5S^iPSMW/YI@HNEJ8/<E
^tC&H* MTj?LjE4+Q4>F@RGW\Jat!L?w*Xip8k??Pd96pAHV@#8+#j:NHSR6Y*Ayk$#Y*&@@SY&IKXt\w8>+T&S
ty>B^I Yh*^/cki?M@aV:6^D*uEFp$9*M+^4G>8*J8a\Q*TGDnZMPI/6u*lQ44Y!cukqPC1\LFdkpq+\mWYAP9D
\5Nh5K uwN^88BYmaydV^Te:SA1KFe6k>EP8NmSFaylY@lK=d6cj$TGbZV=WSBlnT!VECc?Iq*J9b+W:VXPlXM5
#Z//#b t?bq>Gy8=aAbj9!a/b4L=d4kkuW%y^mL\I+<FwT%CKh>8*AT+i9u#Q$8@uA5jZCY@i5j&6llp/?A+<iB
Tic<*P mbe*1LEKNjPuT@SE\yKGV@y?>h8jj6H#R#k&wca<bMwH1tWcQA&G&+^4\WF*=<:>Bt>$MXiS4BMVEEVF
pDQ&ZY XkcI4dX6F%4laaRX!eyEXR^%^y%+^=8&+qn+Gchc\hpK:u<V4HTB*CFVZP6E:WTcPDA!HyBDwh94JnN/
F=m?yd HWa4HIELIZ*EdWen\&mGV/y#pdhRNS$S9Rw#nHSFXEQbZDcW/?wmaIq6q=WqqwT>!\EVC1h&kqm=X*/L
M^h<@Q JTK5%SC*>DDHWSJ1QQM=MWJT6WXmbP>C1FQimG&b\<6Vi?d?PbLYF&k:ZSWa?&d/*B8<pKw*ANb:N\DW
c1DLWy \F?B4DEpc^l5yY65&$XTtB%49L6dM:4cM4^iiE^/?R>Py<>J=b<Ad6#HCGP>aGWDBHK\AqEQEXdpmkPB
NJAcaB X8?1=b8$k\Iu\R^nh?A>kLPdWX*G/WDDy@VPXiFWY@h11tFpYFew1%a8qM5yT<#A&l\5q5JM6\wu+X?b
nC=@>% @IK\T/%&&J#p4M$!S*uDZc/El8W@EYZN\/XtdhhY<EB5*ZA/w1j6*F#S*8QN>B6c>^BYyP4Lq:GZ5W<G
5Lb$u= FkjICMP@Gd*4liBWNy9w#4wQ4\KtduhH$XEC?Q:thl<YP@+G@DTe:t#hMI^T#t5a#1+Fh>IAZLQ8<$/j
wwJWNZ ::R:+e8=*TFj^dhRYmkibwPSu5l>IG^tq@PJq*SJuG4DX%M%8eCjI1^:Qe9a!JB^^V+>k165lqhwykRt
b#td$1 l^FZY%IC#DAmpe6q>hYqAW8ctJQE8wMFZP&JCVC+Rk=*pXYuh<Ce$*Y:k>ZQpw4bR^CMQBG>Bmp!icK/
Gn5Vew 9*I@TdM4B@$GAn=#/\cD%61S<%ytb6ct%/d9Vd?=h?@indWdBPyLNMED+RFt/@a*l^&hF!IZJyeuF\/#
J6HnC< <aX1AeKcYWj%htQ#=t#e8XCEX&pHuqE$HA/*+j#WebnF+<Yi\!#AuqlaeQyC#8bCw6:lYQAB49tCy=F*
N<@&@6 dFR\D\YE*S/FYGeH?j4\R!=S%CeRT6&p6+NA88+>R%mZXT869YE4Z?hG6&bpXtJi8hebe!8H/TwS4jPV
eRyPA@ ^6n9lCYYlGWHK#NPV!&GGQu/AhM%S>IJ*pHpuFy$p?bicRme&WXTK%4=nQ8Ec5%Y/EQbY&dHK84<D*^l
\q$nSJ @hByt\PMc#N4c&9*6map1u$DjaVyL6nk:e#ycuYaXXQ^+uq*5>GN/4h=t!Icy:Qnhl+Q55YN8GEW<whi
&8Q%@P +=616aT+y9MhyhKlw>ylkAqPF?5L%ca9FQZ=Gp%$5eGl/BCG5b&:TNmQ:IdaHQB45eMa84pAT?^NGhpn
5<iXQM 8n+CYMEMa^561bpwNbE/M5yBYG>>l*RN/cBcGe8YYD4aGZ+#LiPp=+iXj<*qBLSLT=?*by!$pi@$n96!
Iue48l D8kXYanEBT6M&ZNTF595$>cjD8T=TCC4L:K:E$nyk*P6uEXIEhY64VYCNVaA1AJXB@wAXWB&P?M1FawZ
e%+4Qu $L$8V^WLl\ZQ%Vm1+YaSSBG1yR=Q$ataPk*DZWk:/9=Ci6QlNbJPw=F8i9JyV\t<1#QhZCkWR#+AN4Sb
@MjJL$ >KGAC9bWImTJ6#Nma&hEI15N4nS^XZRFM@#MleAmZdE^<QL\eIVtbcm#e!>Ppt1!+K4u@EhGIHkFGHRn
B8WN>T #PmG81Rw%n!5^SDjdTiI&d@tTFn#B$Q6\64$5L:*S\Pq^LI$Y1iP#hm\ij18e4IQi$#Qi8^aeHF^^\VV
8/c<$T \qeChk%9iMSmc+6RnR*$DR!EX:>c*eWF9@NMb?b$<dCi4YMP9=lQd^c/KLFW:jC!Q84\hHm>+Et>V8Qm
P/C1c^ :Wb?\ck&N168\DubcHmM@GdB/RR<N>NA*!RIy=C9WW\pEmFpLInmX<4DBqTwe:Rh^1@NAb^:6NCuQl4t
4$qXIR >1M8AFl9tyjBD\Ra8up?Q1c4aW#=p^t&iXilu4yMF&5l4Pqkb?!CGQNNk1<TYCGI:cW\iynDe<!6/+E=
Jp%^81 EiGJAJbq<W#5^IHalkWdjQCMTp@HdhMdNedithqK@Z%1:i56VB1CX?$D1lKtb?C1uetA5uGhLnTLSReG
-AIGtd 000b267630700110334 Page 183 of binaries2.zip
5848e$ 4+WGaLWRS@>clc<XV!Nj<==m<SD=/t%8*t\WewY$i:MD?:I+GpYntZcWDb<#qKc@YWbS*MD9Q+?MyeSV
^NMXkN :a#IPq%cCV#Ew^@n:%kTmbc=TKTc&A!:>yc=?@M!N^/qkY$ubje6aaa=/Y>X\:V#m5F4#tKCJYXDMw^F
nYWhJ& T<!EqiEtS:DK\Y1JCeqZBQc1\9WI95I@R:yZ*mh>\HA?wE$%e?ARVi+XQ4c9LGwt$LpPnqHL/4B%&HXK
te\k6V t!\:p%1DC<m/>d6AkB\4wZ4t#Jqc:R#8qhbe4k8u1\BKiuJ!iK1R9ntXL?R\iimB4&%&pH?FX*q55JM4
5M&YG5 iQ!*<%XQ$&kW9hn%4FHMF15lCHHK#5&<\>h\JIC89pa/*emZ\BSZ!BLZINaB^u:EySQK\:=nh9tT<!S=
MS<Fw\ l\=l:Ti?I1CQcGJSlQl/Tt8ZF=/^8hebnc>CNaY!h9jKQqbG5TTh=P//*F9ZHP\j>RR^^#te+EDlbE<S
b:8Z@% /*ya8Fe$\\@W>4jaLXZDcYkTM18u6d=ujmI1HY5>X8+X4iVH%Y#pqGYMFlady4CRhG8Lpp8^91>Y9\JR
WVp#WY ?^HYX=FcyDQT/iy$qcyNeK+Z9y&e9Fk>QXZ$PGcu8th9ipSGwmQj=Gbajwiu/Qe*Ny5=j/PRJX\>^cdD
9h>e6> MP4PWDqh#Q11BVeG5w$1B4IuKnnPBAm:%%pD\8/Eiahh8Fl>Y1kX%^Xylt6kll?JWStT4mTdpLCuWpI&
VmPb&> cZ89btEVt?E8E$uEX9$SDiuWF\n5&^dCHluyILCjL*&QlK$AaT6Z4*:^@VWdZ/?djJYuL>GcHDZXV#EY
ci66S\ kX*4GSS>91uWNKwK^u9HlYK!=uKIDujR6>:B@dlaH$uk@nN:4&y:i@j*eL5W?LRePh%$bP6%6MMZC?=5
5h6=HR edM=Ba4+y8N%$q5H@?4IP<DVJkHZ/8&m%$l9A4n@qD?p65=A=A/D5lPA6L9cZCknZ>G@%mHmmXa&Ju8G
@YDlYG ItAWyCa&kdZ91!8/DmP8PJ<IJDDN!^mPKDM5=+1>tB6N#il:4=y:jW48het8t9RXWppnI1!Ye5K>hXEL
Ke@%ZQ a<Q%T&YINj>1=T9+X@*+yjRT=l!@XtTS5hMj5&hq8l+:/DGQ$QY8YL!4^qk/p:yFbSG^YHkALjC49XeR
*BWDcV R\^Flum4hDI!/jluD@9Z!Yc?Yp$*MQM@m%/%&AG+F6BjPmC!Pe#u@Z=@8qGA^$cl:mXeke6P+K9S!Bi1
#m+NwF /dRVhFPb96<hItDbE4@KdMNHmt4GL/&M6#&jw%Rj^1w$k<wFjH%4&PV4w?jtJJLuP=SLp!X4N9j/iPS6
DYnmt6 M<k^iYwcbDQaij8^SSFVyCN4J4TTSNMRm+!VDGC@6Me=&1Gje%#a*Qm^DdcdQA9=!t>8@Q/d\ZX=jkN5
F6q<\k <PCit4:B\F1tI=68qp/qBkIQa:FFhK%wkAuWaE<\W8tb:ME!qn<*$L<PV\%Qwj1=DcnGy&a*<a5i5MQ$
d*CGFe Z$EwiY<&<u:D@?hGFZDhBJ+CajQwiEPkt*#$*d=!CJCqh!6mp/XKNDwWbMJt\tTKhW85M9@cZF<!\#YA
>mln=a FT\K>9N?T@S1X*ca/Zy1JhZ1Z4Y6uP>aNdXbhSHFC6JylG$V/Ykba4WBK:aQQql1/%@NNnh*y#@:4M*W
m*<wl* N>QJku#/>T>jDZKVQPFc%<G%K4dG<EE&bE%bLQH+HdlVJYq5b!CMdIZjF=nGDRk8i!ya+lC5!DwqYI<t
t>Q$%w bj$Tqphkmym!?+d\4\aA/9ZV<8J4\&8IjwX%8H\?XMPle1n5\!qEGQKewDA&el>e:C+!qp8KA=eCqHdC
dn!c^! #NMhnc@$p=?EtGc99:@Y#^!Xp+wR%?e<VSMdTGjGLdJJw!66=h!/DBBaKYwXV#qymVZCtu6%S$R/T>dM
@NAqQZ Q!eT>VlHl=Y*JPdqaMaHyJyE4CPkjjD8iSHcHPP#peePjL%cPVkNIX&^6q=ZlAWn@A:Xy9Yld$Y%NBTl
Q=E:\a QShK$GPqA!KL^T?V1qbmmllL8?jP8GF+EXk9wcw9RBWat#V1VNmRM?R5??y+l/6eS$@4C$ZbFCP\8^yn
aGXk/i A!%>jkT5H+L/hcF*4jZ9CXlh&KS>tP*\Z<T$MmYdCFjqZ5pMm=S@4w*>Nj<e/lKE9j#+5b+n^m4m%4$/
dLbN:X muR\%JuT>8jQYw@yKL/tXLcJi^Y&GW9Qd9e@/khmCXRQk5jXmS\^uTj<*4nYdNIM@QFjmwhTX&I:CP84
i:II:% QdVAqR*+hb>keBuc!TCIJ41?jTTB:Ta%VB5*\FZ@8ujhm@wymT<R%*XnZjVbl%Z*GYXuGRA8A/bq\Bwi
wCh\ey !&YT^YAdl8:9RXmXCe8KawW5j:k%ZC<6D!<VZY65i>@mZ9\<BGXP#4?hG=%lB/dJJn*qn<F4!G/B8!!?
FN@JW8 qtR6ciJY\u:YtmL?ppNa5^Ttya1aeNYdG\le4aC1GZA@Zn\9VQABu$$@68:jP/==XmD4i?HA8Dqm!lJH
an#AeF dI&u!A19AF8HE6q5Ip5Q>CIB!kb*^IQ^!i:J1TDC!kYq8FtHKTjMDmNb9Z=A>HZYVR9?cyLAFb\FwX!8
^8SaVc P<uLq4MJd!KSVNB/uel/!^DP\1hH=b%&qTtt^kZ!5$&+<w??k<Q@?lqa1bt\G@<aIQ^ehuq@MdiD9#t^
F!n^Xj tYP/X=Z!Q/8<c=hhP/uZdIwF4p>%SY^Y@h6#^KIp<X6X+6R8#lG!CZ?/B\JZtSw&#/1??=?T1%RWD15e
jSSa9< ZhZbmq#hMXG%YYK+SIX\DHCFRKVb>NANXmqLVnCP^>W15\k6%RkVZ?QkZ?P<>Y4+9etE8%S$FB$P9MP6
?%%?Ch =Ab59hIeJ+t9ByJ$\iHwkE55h\IbC$+&&kM8HSm:nSuFMBiiEtP*^1p#EPI1j9JSAFL!qilK$#Ka4<wP
LhL&y+ #\&95PDEYwu=iS%Zbac:yQ&6b>9b+:4aAlCENVh%PQh@h<b&Cqb/&G9Z94$tcm=c+qj4!Hh=dtnij1+e
jJEJlR %/<%5qKD>&MT%W@EHK*FuaAcB/j%%=G/?J%^QC/*5lILl#NDyaLH+&q/<AG\LaI9^Kae5/E+HpQ54uSQ
i9j=&e VZbn#SyZILJ1el4i%>qT5YW68LP9p?5M4Jl=Ayc+YJTa+5ikqGBVHII+FqV^K#DF&*!ie5Ze*eHPV<IP
B$CVT< +#wF+4ij?D4tMnXVdR\uWV$ZR<yi#D%@!PH4b=weNp@q9A*Bc&618N:mcwYLNRq4G8Kb6mG5KCI&c<N6
6CVui? mWR#LWG!/Rpjw:e5dkZ^Z!eWYSqadH?+cQG69RHLIG?V5PwF>kVa&Rquhm8qK1M1eM$C^ew+c6EH%K!I
8Tm>n6 tqJSXaw%l!c1Bdk8\6&!T6tpMMb?wt!!dPB*PQm@\qMyMRn@A$D&BKwuqMY/p^YWHbh<yVWCaNd/M@%n
@Xb\MT eLq+4JkLl!kkZ></yccWnRZI$6F9#wI4tPH@J4yY&tDcJw!hSMLia5LKcln#PIi>&9T5PM!^JA@yZLjt
c=Te+$ JZSeb:lC=<G<*6^DqMH<e9BAa!5<?95ZFXqySPXm&IKy4TEY%@aFA8>leh48>qCyKtBF%ncL=\ZQCNtw
DH@:#1 Cc$5QpSa5/WC4GJBQld=wl6\N4tP!Cc^Q*5b*1!kMCXPJ=KDSltEFDB&w>I#%IPW*h:N5C%GZW#hu\Sj
un<>J/ PZwhb9eKT+=LywFF^NhVQMh1:9tL5ClH5Ia=\k#j81\F4@Z5#/&8uCV5W/5lduPe+$5FLB<IcXiR1Mql
WtTYYH Kha=Zdk9K=8\*hK@&&E64+4JqI6!it#a:PPe5mku5$e5$9Wn\DYVRd=1/&KY<KkdXKhE%eBa5IbX\6%5
aqa>9y k=Ni>&Hl!HY^WDnM9tbd:B>Mky>NXk5/y^eT@5FBSLbMVnbKt#8%Gl+CwKVmJddFh\T8hIkPeM*$4@dn
/yCWh* cB9&4#T&CP*\<L<<F+Mm=%:$yuT?:8<4ZJ>!9bwIZw@GW!Ai+m%!LhSy*c!#YYI/*Z^&mj5SZQ@T^qi6
Gth8A4 %u?j5lL#qARGPKtDIVbGi@PD#dWi?PTA+F+iAj$JuuYY%hRmD&Fl4Il!\L$C468%d$+4ZQN\L&RH@Wul
Nl?m/G G/pB4CwunR8&9uaZ18y18#4e+GSyXy\jQmPDXeFu+ud^MDGIkHQAA=TNItMnb*BaEbi!Ti%p&8H@kXmX
h1eAt^ b6n*b\Sj=W\d>K>mB8mL9?\\I</y<FZKJqVDp1=%m\w?CtHqaiuw811cMENa9W5mI!6SdiY4*ByKeSD&
5H68C@ w<B%Z%59V&m\E4LqZnWLtB/QL?:wDZ@6@qW>I/\:+XHpc>NEFZB%M>YTQI?GKphNWAuYc98qah%S?uVh
KJ*KDj VFW$Bj^F8l%tD\BZS6b*AyPK9B>LJ:JpnTJPw^J/GF5QkNuN4AK8a^ut1DDDNC9PHJ>?T@Nk<%jM#b!u
+ZBSCj nP6XT@B1NeWl/%hRE!NlS@RR>pjLia+@6uRQMb8HHCtdlB!iu:jB?t?DdH!Qmch%TkknXTq6mQ=%Md!t
YdhBAY >>P*huQt=*ek#HpaYHpQ:QDwte+K<yW^#ie>?eJ=mallI86Wlh<Ac:QK%<?6Rmt^#8yy$G<$LdRGZA<P
&n6^=> $EcDLc/ZKWWS^h$Gh4K!=Aqe4MqZ\M?FhAX5^+dHdH!XW>QuZnBjy+t9XPy9<yY&eqT8!Sdp%P$Ip+5F
ZRKKc6 \w+wD&6XV4aa>44iu19qBK\NX>YqBliNGJ1i?NPB=qwyeQX9>B+Z*Wy:EhyQnwi@q6YJFtl6&8qDNMPI
F%lB9F c<bXYYntmc%=k4j1^tJG@:wJ4YGyFHa:IN^qbJ5@k&?H&?8ZV6dV6BnyLQ$L$Bcnq?WeBXCYh6yHSjEy
1C@ykT KmiF/%Q$yc9AX%DEa&Mt4luGqaGFl$Y^d&*uK$Y9@:h:6VA=b@G\<wS#t@y\T#e>$eTyQc+#Y5H/qZ%8
6k=6/= 5ky4:RhLeAP@tWH+4jR45eSQ9T@NVyE#1balGEw+BWd\*QLwh1&#5qBqXQqCZHE9X?M5=jAN!9N:e^*N
DN+yp6 =5*t9<JhLtA=LA!ThI!dbG===b8/M*bpijPJKF5Y^umnB!ld/<TNP%W6d8wt#ED$4\K5PECb\l\^i%Z\
k6e/Sm qXChi^=RmZYSSlS<jY4u/@>uXaTH6i#C6mj5hdP9KVi66hqlWRMn55Nm!%?R>i:LE^c@m1CCEh5+^Y*:
y^Qy=j 5YM$a99i\J45bDXn>dG&=4@WFGSuh:Vt?1dWFF!qm@pKlBYe>S4/Tm\$SWBERSE<yhPd/edtbkPkdY14
$CCqp> &kVh8!=^Nh%96iy\4#P\VFtlm!9BHnVFhCBLcCjJ%/jnIH<#!NjXMVp/iT#DR@?I4:kA&FQn4Dl%*TVV
bb51Py E4TZw!eqQt&j?Di6MWmuye8*4IR><mT5/Fl:ucY\6Y&+lc?M/^ZSa^ZYV&Xqk=tw9lMd&Gll%YR1tPLn
JcJ#\/ +aqyYXPe5qNYd>ehCI!kHB:NdKMhSn##+1GRZXjLaw&J41Ym^:L!kPyl+mDy>nVTca@HSLZbBQ#E*<<*
VSmNQ* hY*qeFMNkKR5BV!kuna1\NnP&9<!h4$^Wh==Qp%jcDiw!J*aTL8#aIjEcTuFYBDhVlq8Gym!S<WwStam
J*J&Jm EVLhi\V6pmHVWlywV1uJH6t?eR?tVy8:wG?a+Nteti+LX/$et69eqy^ANTMM4y%k%6bnMBiQq@j><@9*
>XuE=5 QDQW@y/bka/kle@#?j:@+%5W$!ec6S#&klH<Mm@YjXuJaXwa%%BcW=wti^lPR/iN4/b?>Z4@aZ<jy>VJ
JL^4Pm H5:pF:=T8\yJdBDY&VGbq:AKYMekAl%6Cm?NGWQk+Q#d4q^R5Xuquy8u8?P%EP&69@q@T$jQ=h6GyHL4
Z/GH>B u\9>iutkb<V9><&$CF\F4LH+SAnPiu#B8NG+T1^mAm/#w8R%uZ%YFwMRwjHR\>Db4CYCXulAVpi&X:Aw
5tkGM: 6q!t$b#Aj!AI@<BD8B?R5!L+NLtViml>jq<QN>yJPV!F1@+IXX:hTdn!X1tct6IcJP^h!hhP4eKYXF!C
-AcZ\c 000a0c7f99700110334 Page 184 of binaries2.zip
&#m#lR :PG?jQ4%CaQ+Ya+d!%/5pc+n\8Lj&=/H5I1#9^iZuc@GSGNlDp8/5k\Gh==ASb/Yqh&:B>=<5bC@jlGZ
SN5lh: 1GyjWmP&dV4Y+G1ueHNI9&+1I48JIKZuc4^kJdK!E5E#WjJbcF\=LN*nFbE+t<=TdF6YTI/WH\<q54FX
>+^d$p LcCb5IT5=XyX1MI#kZ<#ZlMVJbk1kD5%\!qb>ud<PPHJpMPN+LVKLiiDa5h=MTA<mLm?Y=ym6kK8ijm1
SYjIb& =DD/PcNQD$851YHDV>G\9#<6kM&bRY!EJZV5ttc5d69FtG:i6Zp##qA8K\Pm#6\dSNpph%lSEDH1@:yh
?\AT6i A=8L4BF8<1L@/9QQNmBjNc1&A&<WSCa!&<eXc>eyZ6QF5K/Z!MbZZT1DkLThIEpdiyl$wRq6h*YulSWF
u*L16? >$+\TLKa5kBkFPP+GDCJtc?N#Fjeej=a:#e9=hZZ<BIw4RpI>bw8bp:p<4X^T6nDQ=yV#!$XB%#@a1bl
TIk$*M PVcl6?uah/:<*qlX+qT9p1/&@5%Y\yRPCF@5KZ6=y8Fn8wQhH:6=&^EHE8699n+&%u:$1NGN=TC5am%N
Ph+XJ/ b\L>PuN^M9KiknRHYnk4JTHY6PMXw\uDeEc/SuniDIADJ=KR9yI+EW#6:NyXpa\J4Y9AGqeGekKR*aWJ
5*/mw@ u5tDbT&paZ&5aVXjG^Sjcj<1<4Yaq95B^KZCeFJ<XcMq#Fy@T14@6Pm\?tMMP6p6J!J5j>=lVlLb$#qL
uT@=ln PS^t$*E=\n!<tWD>@999Z@u&&&<@c6p$A@+=kW4diATpKI@h>XY9Z^5#JZFaXIHdVPJPHN4QaWSlN/$F
\Gk+14 Kb<EBw@wYqq%EF456^PEq:AKeFjZDXhR!NCKGZc!SqbFK%bKlpQw:8ARCq^?VtPA9J19nC98c$RFY!#p
jWl$%B MJ%T\XiBK@:IS<ieej?<<Tchl\*tmXEI!/uQ+i1RFDWJi?H$n^/H&eTMF>PHDlPw4:#!\!5@9H\QHLtb
%^kAha awpyE%XaVmTM1%:9^=ymG%@Dhw8+W>9D\NjbVaD4&yD!mWiG&jPJP:=!ShnNq5I$bmKdAAWd/k=XbF*T
$#8H&F Ty:YL1+SZW:ET+Ka*$ENi*HVIF6Pm1>VndVm&pPL#Yp#ep&kBnh%+w:5t6J*Fc/yHL=KBT9m\/M=quD\
Vqw99# ^*k:Km^m4/M\5h>e#*H/ceBKN!e5GwhW@&a#aQ4KD<@mRh<eF^e!1t:i=my!Pclj/$?>mnZFT$6GA&Yu
CH!N&\ 8XP<$+n:D\#$?Q!DSb61uT#MQhN9dTj<+k//V1^u\qyTRS65lbPaADeGLm6tipAtaSY!AC!aV5BZDE:+
Qk$81j RSB:6S!itmG?i8VK/=1cAG%F^lNkZP<T4w*em6@id<8@ey/Pm>b?XJ@tGE?%XBDD\WTnpumN5Z4=/ZyB
T@=l:E 1FeSdiLKbnTH6@$A=>tj\ZqMqpP^\JT&HEZFNpHM84dCb/>>TeZmy8upZPawNP\A^j%>k\$Z<@LXMm+T
#k/$qh ^Wna$LV>m%c*G*\XN4XyX4qK5B:timkbY#X^ZZWTNkHt$*AR>/bRC/Y\mL%K9<+CZ>&Q$bn+GPX\KwX?
iFYnQl Dl>W5EVYkQJjq>19=jK%!Ynl?P#y/b^lI$m5Lch#e5/$uq5:>XSkdi1%Zcj<Q*tHRQ*mm!<PjPGlSh/c
\SpeqN y@C^MGy5ml\+>Td/9Ena5E*HG89mj<HRauEV!GFjWc+eFqnG^AeCh>$VkP?JjE9K==A\lT%qhSF6JYXn
N6:W4u E\l4>*Zm1&9%QbP^eRi!E$BauAtE4i\?*@#C\AtF/%RDCmutK!:TdWmlHHdnA?^lW4D\1A8plNE=yy9X
G%^yiW hd*E%SHJ%+!V5pH?n$^?m=l/he\tb&M\9Lp=hE%aDd:cK6cjSW#L<cJBVX%mL!SI*YklHmGGWSBHZ<M&
%WQHJ& AEqak:Kh=uL#VnQiXLSyhMWX&/eaT1BKu81QedB<K#/VZ!eN1yDJX#6u/b4A!H/\G@%cJ&FZyippnPLI
Nl=jtl MJnEYKJ+5RlDmTPkaTY8VWZk1:y=RV%!FQmcIq#^<>LT$pA/aQIXC?1h>akm<D?cK+S6G9a#$*4KmPD@
$?9HGY #/@cttHbhFw/y!iIZ*mcGFbB@/X4Y9X@<nNCFe:>?\imQPAh?Ry+I4DS\wEwBakJ*cwQnqQK%ka5Bb^6
bnjNEY i*XyM\VKaa\QM%<qN\HbLF!YJVCY%\ykPH#YB4iX&C+&A%8YI15J4C9CaWLkK#8%k4H$Xc9V>5S<TSBn
nR@*1I E>ZA%!Kjj^+<HeZZy6qm6J5E4BlqR4+!5KpA+p4A%pt?<tnEju8AtA#m$XydyIqjj5TQhRymthc=JJ#a
y!Ih/L H&i5*FCu%Y8:KJbAA?n9QpbM!&@n8a<DEDF*nnT6L/TQTFktK&/%&y6LYB6j^jWL5y6\DC*I+SYZ+m1?
FR>p9L b9qaq1qq#!cG^!8&Yp4l$w5KJTe69mYe=qcpwn8V8b:J^tTpkyCqj<K!VGRV+MYCkn&I<=%A9/ID/^%R
LI<cN& ?b#jII1QQY/=tD/XTkp=*CZ=GkBpXV/H8>ZH#MAEP:AuXSF+=1eqhSDZD/?ccXkymY$1Nn?!F^^<DT?J
!^p$B+ Cl&ihh$KtMLnDANd*:6qC$6kALc?<uBl+YX&Z8t^<M%!LtE:db6KPk%:iAHqMPB15NBKFwRilwaL<Dh9
@VV:&8 <NYK9#XiWYEqthHm*VlcW&k:aRiYlR<4maj!P$n/k8D%:6whyF>hKua<9i:l\%A\atXn$/aVG^t8*V!J
NpEy66 jEW=QN>n<HY1B#!cn#$i>ANa?Ab1eNRuVpbH9yctChq$1pjGaQ8Z#WThMy#!>EkG#VB^LuqHXat++aP!
k\>1P& LG&*A*9/Ru=Wy+#%qLKQupNll\<kyGjwPl\6SF!by+Z%?MqlTXkEN9wG%dyh\!wLt+y%EQcG=P6mR>Fp
m$VSiB JCaXK:%EMI$YitlqyT!tQ%qhB:nG55yG^yhXDnh6H$>t<=@aKLdqhGhnLlXdZF&NV&ACPSlcq*ZbLKjk
l&G4NS hW4YZWT:CRNP&l:?VZEDStA<C6icRHGZ8<56HS&pK=!?kdDJX*6BayQD$ZtKF!56+ptPJZwd6aaX!*:q
w?*@1Y Em\yml&e9ZDc^FWQIFlY<^F?>RWmm4AC4weB#C*%>aR1QRw4pdC6E6uZLm%LTi^W5a=Ty+FK1t?cJVt5
*%:K+> nTdEhZ%wjYk<qNY\+4Nk9H8:K&9bQCC$pwG9wXCwA9M@<Awjh+W!cAXnt^YPC/uhpWu1$KKLecWeMlFY
?nHJ:a M*a+5?Qk=KGYVb6\C<DI!MAJJajuWR+V4ALZNBlPQBeheJ$4DRTI5Kq@EiQM^KK4JhMk>4KC#V#Fk<*I
C!TPbq NuaSnhy/etnwR$*a5Jw&e$q6liW>=SLcC/jX+uuX\cHG4F*4%*I+jMPDmJ+=k!?Ac&E>!GFAp=C6J:+Y
G\ae9+ 58GE%<*#Eqi:/YT1YQ^h*iCEDl4EaDeShJKcEhwH5H=<&4L$8!BVK:w4jy%N&8\yE5TmJ+eCniPm#n@V
K>!uP9 Zd5^5/P6Fl+Hc*hpa:w<&dWcL\E=DLCGCm#DIp:ET/=QHm!nFC#BiqZb\+$?N?HK\HdBqR4AK:#bC:nP
&hF=+b paKq5=94aES@ny+G\+dV#@<!NDR/?yQ4JVJ6*bqRy6d5%Yp$6$\8>+<bnNZIM4wZe5Z\$TXb/m<$j?X6
T9FNwG \9T&ALaiFT#BmT1Ynkw/%dj8=YJ!TXlV^+11W%WZZ6t#ML@w&%TNjGY/Ew\S+B<?EkJWQ1=%&:8:9<yc
<#aqHM y5T&akXeDFYB4ZSkL\>#D$iw8:96?9YN!NZJHbP%P=K^tMuZEmS4<PHDhVGbAtC?Z1hPLDTdWL>/9cwi
ky9HET eeVGX%C6kXT1!>&Lp4kL>P9euJDEL#Gj&w*^E5/lIX6#Kp&D8S=5y8*RqaQHcpMbaSF@iNZw%SH48Y%G
e:GHD9 eR/\^myJa&\V<N#ePhDyPcMPE^aX/&GkdH&>It#W*W1p4aw6K>Ny/Yk?\ubTQ^$:Pu/jd?ap/qiV4=lL
cEd/9n BeLGFcd$b\WAXuhTKF$qwXhEWRTm?:?ShbGTJ%S:nGK+DV6\cI^y%5#!IK=ktaEwn46MPS\b#l#e&WL1
%LqE\m %V<@MnBm&MMDk+S4%C*ZncSTciA444<6V1MeJqV4Ak51CG99X&@WEciu<nYVcZ5^uh:bq5qIm>nY1!MI
uut4Ze 1%ILikd8qAQdKh*Awip1mmZEWGRQC?E#t4CCy+Z5/qRYe5pEQqw@YBctp=VE8h:P=>!5VkYJ5\*XEV6j
dmQlP1 J<ay*LA>wZFFCFeR%^kKalNbc%$JmYFA6/RAHNQEX^QDRT\>*pl#JADa!euN!bkCFl6FT4n\I^nZaTe1
5R&LZY Q#%aNwqlj%C98%EPu%B<QaG+8k<k4MWpl>PIK@K%m\V^HI9lRPyGy*Qctp*B>9YhuN!/Supy9^q18=K?
6WtVlS i:eta=5=$eiENaj?G!*^cy?lYDCwX@tclj/C44cNiiHKA^LZM%4DE1wD>iD!*BeYMTMLlL$pCK5G5lt:
K@YyLe 4GZ<u!^mMy!1I#bm^pt$lwbZym$dZ%i/&>w&jpZ8n/q+a+uI^QCV+HBJyIDhyXlBBASdbkiIaeC$4Ly5
FkwCGm <tA&bmbtE<MQpc=QIuFdtDk!nIZ@LiDqLM/QwBn&Gu#6KubHpc@CYEw#Z=G\ZTCGT^qYeGB6jDWhHbZT
jL>Any GX$#ClF<$u$qXZe*uV+T6Mj?V>JaAt$TC^XLSuG:*tmwwb$!l\/4YhJn@j&m%F>6#D85BjG&\/BX!hWl
8MLmnQ Dh9dY^p6nHK<&IM>#jY6=!XlHT4YKGEnPT\cPRcb4?154yTWqE^ECqb65CbnE^5*A4BbJ1^R9H^DuMZ&
c@4#\w %:l&j&K^FaA/k#PHD%Z94K/iNQmKenmCTjmJhaqyua^FZINa+DRD8ILbBGL+n%1@Nk*&Iq<>8PtyGL*Y
4SH!j% 4uRKq$DlA^V5uPB4ZW&n6qh6\<INBd8GIA/G^nhiThilXZ$5J#Rlk5SN65Y\jQMA5H4pnNktdZDXmQnV
e4e/J6 WER\j94X99jPeGY=Im!+Pyh:$hYJI1CF9jY>FQ69%jW\d#C8\wp>1tdbGqYuN\\Q%8jk1=Y$p9S1Je$*
d*SY:@ X>9ceK:@d^Y\Eq+T+BlkQK8n!Wncp8Hk=KF1MHC4BX>X5S6ZHc5pP^P&aCKD!Xi5IQcNLI^+S!Sj<Ve&
Dd:p^n CP!ME1^muXe1ubb<Ve@NKVq<YW^H:FjD@eNtm\/&Znq!5BpB/91KY^!$Cl#MGZYKqyN546PTYDJ&:J!h
aTZJq/ 5uyu9FuZlFJa$qX98A^:@yYB9W&E4WjCWt\+K6J%Wb%iL?!JLS8TiPteLSj4$LALQZ/Nc%JkKmBNCw!V
FjTl@B XCAeQ>d&+lGi<&QqHu55GT>ZI9Iu4Fi/&FJhb8%#/h!5WdNwEucqbCj%ek#/!e5b<Vdh$Z*NGFy!S\?\
^lIDAq &hRFcyZ=m98jAFhF&MCCuc?tRV^q>q+b&dwu\#SdjiP:cZcCQ*IEKVKnI8b$6eqPYAF5j*@:W6mG4Lu=
ZW9cj* XCX!CNbL!<=>:<LX\SekdJSnmT^>1YLC4hT4y::1QE*cp?Pu6TR&Ch5w%45CaRqZk/RaD8Vaj%cknb>>
T#=k6L %Rcw+8TRdA=ndh/9pMc^bC\^?XHL^bbHn%yc5pcNnM5MQSG\#NjIeFuL9TJilkXGp>h:R9K%E^*a4tIQ
!wJVBh E:cZnCW5:!?t#jIkmDXlF?T<$L#nVE%B#IRMB4te<6m:AZcX/t4cewym!CL?$Jl^KwFqP\ka8*VPy8ae
^h4uYj A<b+qAqLaj1@W4nC6/BJ9I&R*ac^^N+6SNPBKDXd+W<5!9/B4&RSZ#IGKIch\N+kJ=aI&:P\?&Ip^4Bt
pHLZGS Nb4m!i>pkcNun:$wSnn>\Rt5Ci>bmY*Ttn/EA=wi#SVh1#dp5Cd5i&djS#^SMwqVj:BBb\Sn\*@$*tuT
wM%#iA jCXXTw8C*F&$/BZZi9Hma5bXAN9RcISlHhQ>Ghe?a?\qiF8en*yS*BdyRPuBQCHFTS^u?iFX4&PX5>K^
-AhbbX 000edf712dc00110334 Page 185 of binaries2.zip
FJ$>4W <P<eQYhdK/&HnK4Sij*HJX*H%IbLZLN>SkaVkdBS@HF/i<WNDJhtLEL:>jK!/wkY8#9C=&!YE!D:8TT5
iREn?R H*BFuky!Gq#NMqt#tH:=h+V$=K&V6++e?WeCNk?$S6\^t+*>V>uFtcKbS<*NSje5T/Z9BLK1jpKJ+V<B
F<W9dj 1qmK/F>aRCu5Xdnmd&tk&C$WLBIYbZG/K>ZL@&Ew&L4WDYNRuVuQ6FGFEtZSSCmptl1i1\6IaG@b?mY*
T9\u4D 1y=JB&EN^6IMEC\ye@!GnduuaZb^Lnuw!wL+@lpJ/?%whAG#5QmDiklZn<aXCZ91#YX6P4W9tTyYdi$k
/+h*+& $+pIP+J<NemJTSqBW?a1\9y4bP86wX59\QQYL#tNq*VcXn1cDN@$Q6d8F!*PL5+&N!hFZqcdVm1*I^md
I#a$:R iI8HEjn<QjMDRFeR\$1@p8EEQ/<HBBVcTulLw^^t9nK8CC\?L>5DADqn+Hp!X*CaReYA/j4^=?1pGK<L
9med<V :MkZMh+1=<N+:T6EKRZAI9@ctC+>C66BFRyj#FlVuVu!!$AR*>=Gib*d8ATJ*Djt1\@=Cn!N?lua!%WC
lYcX*> %?QZSHVm1NECwPdW*yCEjRS<qYkt5%dPBii@ANRZANGlwX8+ujq*YTGL=hMPLwn6jShdmtccb*FR>V8L
>Ylk&y #WqLyh^h5X\N8#whn>^:NIQ#=@%?ZPcMm^Q8*Jp!=8m=eW@dAhc99Da!uYdD!T/IY+t9qFk*HEW>X^y\
uINBT6 QXI4hyX\TeD+5aCENSB+N&<!aBRF5aP\hl&L%w#BR%WJ!4mTFF/YZJP\CnTA5JTGlbj:iN9/86#T>IeD
ttHtX\ \LyXthQC*tY6ahWikJ#tnpbBYMDX^qdNXaF1>8?QQAe<jVD$+AX+9n*$+MER9b*M=pGYWuduL>K!M5S%
+Ky8cu 6*>^MTp^NVt:/uyQ6Ft/y9<JJ<LRkAt5j$Gd/WVVqFjNM&%5>HiJMn$!kSHMNG/m\>E*nP5GJt!^%K@H
R:+?\u %VJJqaLFw5V=nw$<$Ze>I:8?+yt=\J^ChtjG%6^5nIluX<ekLH5:$m4tkIG6DqTmTlEJuyB*!cT4LD4#
N:CWn# IFQLCXiAE<Nw!FeQStDkFTkeXbL+niM&aJh$&EuK+S9l@\VKZmaj6knpMIudyDKVlLEp#n@jRp\jDL&\
J#=j^@ y&<QQS:5ijBZWXTS6RunJH*V91KPVdQwl@y*:>=h=c>c#Jy%dadylA*!?/#a>G>ut8pP<C@$IF5H9E*i
JA+tNH Ki?JC<ce&kY\q$n6\E<>*$8Yp^dEh?e&#Aq5G5kiXu!%:iNw<9wPhY6Wtc:Q%QE*M4Il$*jX1ubWVGCV
FVSeJb m*ZWll>tLKFtJF6McCq?KPeNw<tn/TwE<YM5q!k9B</Yw%a6Bnnh#Nhm=m9n8kC*>hec%@+^#XkD&DA4
1XY1cH YCL5P\X4yeZy@C&n?nbD88h6jMJuD@=DAM8/NyqNmn9l:Q5hHaP#L\H:EKm1lT4ENe@bS@+VGFl9NDe*
<#e&bQ 5\#tKapDRNitP%NVh\\=jMK>ydk*in@Kklhq<h&8>BdGhW8ZW4B%1W:NX=YBFaLa8*PZ&kRtVcbnyZPT
lL96=h 4@C<Wt9*de%yE#dCt5CCXT\HqB+Z\@tQuqMHX*eKKe\^BWMMm^&S=YjK!=G\=iX\*%K=KcepMeaG5I1+
/F6=V# BN#Tq%>:<=I^iyy5+mW:aWHDww1qcPLZ5VW^Vj+*IAwH$ESMeiJJaQ@?Qj9*>PEdu?c=H#:w/Gma>e&C
4qNFGT F\1w>4T&L5DD5@bN5&@9?\m1H<kKXP&lyT6N<M5:MiXX8KLH$IS/FiT\l?4&RAKVIJc+BncAHEb5N6T$
4$@>ba m4XDq%SkR9B%wGXHlh1h!4&>*RD4l5Ce8AJ#hXh1udYJiyD+pI&\c1k:A#5tqm@kd%!GDbb\H!88&tXB
!F8P5E #YlIYKWel4?u$uQ:>wH:YMEGkykePY#PwhwRlBW?/SYT8QDW1<iZ:eA8KYA=E$9yHVcJB@:tT*W?@jPu
K@$TJG ?uVe/mBRH!CIjaG*EhC=@jlKL+V%:@/15X*?=S</Pta:jFn8+P9^>\#$6AK\4bZj6S:@<5%Z<j4#<<?j
N\kNcy j@:<B?e@kLN*:>/dN=69Ln=i9Lqa=jjnDaCq/yZi!lNNJ?CZh+h^qec5G?NLR5HPI&G^tZpL6ywB$HXM
i4#l9W YEVHVZJa<qY9Hi\%JQC+T9<@5&F8#kD&tA=JbG#F@#^b#>T\nh4cFdL+8PbT@#ZiP!e*uq@Tp@5hXlQ?
N>SqqX dIB4PRALjD*k/S*5a5J!4yp:5KIK&G@58M1NLGE>WiTV#+t!Ip\<AP/P:!WjQtbuP*lF<+MP$KN>i@yA
JScX*N =kJQAe!=@jL\b+H>i?kR>9DqHZ5cZ84\+X<!9*8lb/TuqidP+9t8>Xi6*:XY\VqXhW1ht/h8Qn/%YFZq
DqSGe5 >@mS%:SJB*jykIHVNNW$NVXq<LZS#*#F=4I6VNm:h+G9>W^a+P5eiT6#^d#?VhlN*GaK9<CbCnH\mpHF
q:=#BH 1XLh*eJtpyJ+LqC:%8nE4cMuP@IS6qMBT<mcT#Z/4+pXbeeN65y&b1Xi<WeDBX5iQaA%y%GQRJMFMeGK
FCL!jI kqnX@Z@#@?%>dWmecdytN@qntnYcBi*lRIyw^\u15i$+b4PV\#G^JyB!Km\uIcbJu/E>y1n5uGnX$tBp
Y:&*Nc @ECFuJk@J#>:DePtGcncPdTI&R!XbmEcdah!V:db@6FBpbn$$e=k\G=R\uD!h??9=*u8=*qjM*Q?L98Y
n@Cjy> McWynhbX%@*%*Qh%t@mLZ!R>uMX/@eSb#ubT1KmD\Ca?tby/B6iSb$?QQD$!>BS8mGuZ#^FXB?tF!k5Z
Gwt\a5 HnC1F*=PaqR4R+R?ZJ%DS?DL+aJ9>j\VFww?%*1P4^jZ/jdBm\@+?weQAGT<tuB@=TX/NQ#Jy%5bX8G4
BkI\w< YSL/HLEEZEpE9c?tAbMhhLCDTVLEEnt6uH//:P!\JBZb8@hpe?4&6FFXRHY@@t6ZX+nwq4P@EDu+TMYJ
ABVyeN DQFNZMBClHZ!*<aW$!te+i\P4<WSViFTTTJln/%bN?VailH+Tyd+w5^#EJy+h/IBt#AB%nNetjmAVQwZ
weJ#Y> P&cDpwSPa6b%ZJ!lLLaDpb*/JQH5&VDhly+ND\$QjW9CeJWG#p<9jAy9D@Ah*QmVJ\qhkQ:db><PI/VD
5uVJiN W+D1J?kymcuL4e9Ln=jQLb?d9D==Zc+Z%:?<@5H%L:@<<5YZ6L@!W85qR&\WH$c?H1bDVL*HLE&BE^G&
nbYLQ* BwAe1Kpl\w+SbY8?SeI!==:d8wVyVFmith+&cldVbH/ZYEu8:RDYqV?<WZ?NCL9tkQYCy!&D4Ft%RV8Q
4?j?Jn TlbwE%IXA#MM\I=>B4k&ZZT+Tm@ZSMN+Le$pNelJ\CAEVn=lC\W>^m:ZelbFj1tZPN$/%kH=SYI5AcSN
J:m8X% ILVD\>>8Dt>&IT$bYpcVpeW:D^/T^qkqWZhwe&kV9tRa99cV1eVaqJF%^\$>!=QLp=PV6#?@Lhh%hd%+
Y\:X4J ei=F/:qYBY5/hSmiN8J4YjM%Bid*8eqk?:A<nmLlNb#Z%c\naT5qk:WS1QC%thSuYpmWpdm/lN6yD^!+
EyhRaX hyXI98JMeXT#%nVDmCd^<NRC4%<9P!j4KC9YPL1X\ewlP44c=iL\1:%C9mK\F!<C46kdR4NIDC9ec?ID
h4>=p6 Hc\pGtNjMwR%jcj/!p^KWA!WVRP\HYNVC%PJ1WSme&4#&Ybm<<KtEahnTAHSB@\PQ@EA*n&+IQy^/=9\
eiI1m9 Fi9\6jAh5LBAhF*tC%hYI119d>@?Ct>j*j+cd9B&@jd%!Sju#q$?6$#MV4Zcw&p/uF:#>ymN!XEH+n4X
1\d+8i S/SFZJPD!cSE^G!IP!i*#IIcVtD@yd&m9aYWPXmJ1lHFqXE@n8p1uEZY%1p6TZa\RNYId>1hlPwW#pXQ
$/G1da cI\LBb?%P%HjYk\:8qMN!NTLF=t9TFmApwhC#!Jhmc<WPqYjPa:jiXjHb#$>&5McQ+5uP<6Wa$NpP^dG
wPS^iZ FlaI&p&AhZQ#Ae4>QTTTIykA14wiMNVI&<$H<PDN1eRC\k4jBemKPum+%nA#tRXWeZp\4wZ?/9lZeMG:
cmp+*V +%<D9HlNu1M%Q58$>!ZwPXD:Z<FcwjWh4AaHT^=%wIaIm&$F<KiGTlNwl%iiLn8?apB<4*%:t8XV?=iR
MbIM=S y4\jHK</C/yAY@i*5iy/X8GWX=#St8+I5pZNYYF6Dw!^$Z59YCE8#:9TGN\bSLVy5+5@99lbA!ywAK/9
QYENF: cDm@hy^qCTRkdlywPJ=#lKYa&JSCNKmVYc:@m!qP\$@eAdC8HW$euV1/mdeHlCdjAqAjEKnEY\AYHw^j
!I6F5J NAZ8y\NVWFaRZq:GhcVb#^qWi@&KAIadWQn#TTc%kJyS\M//@c<aZVRASZE8hIA<dM&AEJdGqCkm=qT$
:wGF:# /^QV#+pJ:QH@AEcaJe!YcDp+:u99:pbaFX&F4%j*u68^lqkIt@aP#u%p6\yt9&8P@*m\F4Z5B$<*Q4@I
WkIpXS 8H+Ghyntn\BL\JXt&QE9=K5e/^!*WVjn!m9Qiw9FmI?%J<H\\*ak6G6A&aYneG$ijZA$BNRIFQpk\?Qk
D6:9&M $WiQL9C1a%#:CVABY:N*5=PV9c>j>^\9MKR@ky6=D>j4%=>Q+k:c#LI=FNcG&N94t&1kmLmcM6ccAYYI
yXQ>AC /SPuX<RTX=:y6T$u8bH4T=Dh6M9iu5aD%:1:G>8/8\<S4uW4K^/$K!j?<KaBLIteDGF%<KS55TF6wiC6
FQmiF< adcwF1N#NcppAA1S$5YLu\FjJ<:YupY?ppdKPA8JIF?y$Yu\/!CdpymaCP66bciNbtL@<8q$j1%nDT/p
SHCPRC H8CE8Aca*uJ@PidCA+@CF!!5adTaq<!hVHB&59l/1/eHIC!<L>iQjkS9Q#LR9u+ND<JettK+VC4CX!8l
dm:Yk8 MJc5/W9!HDjaaCE5bVw+m>bZTdkC5Ch9F\1t=iT91ZKI1q?+b18:EZD6Q6Vh%udwda?8Enu6@$P$/G<?
Im*WK* bjj1!Jy8c+unpEXQK%Lk4QG?N/^pK!jRA4@C\jXZE:WpywF1GlQn#iM5k&QQaK89n?R<\lJni>^G>uAm
9<IRKi K$ZuHenb6jVc@AJCC^eAJ9S$mH=/!>!@bj:qW*kkZQBFijn!FFhRq?YZ:h%C6laY*%><Q*IhQ>=D8NLP
u!8dRT WnPL+Qw%jd/&IpYyXY?MCD8R4FpHaJMIc*Jk*SB&yi8T/Vubij>@e*=#5HGG4C>Cm6ilR>ji94aT8d==
<n6Km\ p+VI:=t\\>dDA4By6W\9RNaabCMK:5F1JH4M1NTbH%><>c4yFjP%qnTNpLDnb<<&p!\pun\QNnG8@K96
+MFkVN &t&^m\WN4G%TNC=Yhu*l%5Y%55AKq$nDYd&yV&<yaPZ&+NbSkZX64Y^i^@B6J*<GpIEN:mG8Ly+/NZJK
#d!*kM ZRS5AaE6Vq1HE?Nj*T99VBLMd9Wq/5G51THC%uBEnLNw/<dDun=C?%Z^Fj*Q6JX<i:6^b1b:y48N1NyY
HEKZ>D n*TFc!W$\%%ZQ>y4^9tPYhLBlF%naC%q9eZ%G61m!EadXD*u/mV\Ju:<YhP4mXijAdwVb=6b%Am\^d9N
YkFFyJ 1QayS#wG%=JJpI&L6dk1YL%PPulCAX4Ab^diENcnF55+&Tu#L=@iEq\X4M6tlk!LyP?QnJ#KuT4BH:#l
c&Pj+j t$AL\G/>yyZk/BH5V/L<1\N<DNAd\Jpp<dBJ4E%RJ@WARL*i>bCLVm6h6+Y9j@WH!q!uY\DY64cbR&&H
\Yj>nF ENZS?6FHl\+hin9K%:1QuH4V8!4d?aQEVdJ1pklL5bQ>dV*PKtTDK&#nN1IRb#+DA>\El9k#w85V\QWh
5Nk:B& +Pu+&c1#8NXkw1GckY&w94:wGYKJ!hnDFn%k#dGC\^XVS$V&/C#BGwD15DRjA@yHb+@P45&YAXj*m!Jc
:j*YAB =F#jZ%#M*e<BwCZeWq\/lY<=@QnW!Q8LAG!9jlXLTP#55G8PHWPYwwNNepmMjK%bH<ASJe^l\SAnaeHH
-Am#!$ 00095d8826300110334 Page 186 of binaries2.zip
Xj+Y8j ZyeVqH<YWh?Ytj1&GVLAw?j4S?9Qn#+C8q/N+94!I+L$%:EdP5\c$GH!5G6B<PRDG\>6Nq8M^p^$QTit
w4d6*N VkC/4!dGu=^FMF?>M+Fdbc1I5A$aD^P$^%RhtpIu&ek8E#9tn*9>&JDqeBpNeSqkA1!A5+H<Z@ABjiIw
:mn=GD Vu\C5QmcTGpSbY1H^mPNW#tC%L>!DG^QV&@9#@V9c\t4:VD?jM@JEAP8!TVAm4Tq!CuJphM/SW=A&M4P
/*a!n\ >\uZj>e?#e6VY%Aq6H=$>BFmmt8BH?%@6L<8SBXiEwj&pJ6R&%&S5FMePwtV>bCNM<ei1uG\ymBtiwW8
aFVJSb FZAqpn=B+\8AXqXXQSuHjSXWpMF#uj>qVw=&QeK1M>>5<AITD!5#CID1tqwpH1j<y&i#n>IA&b4cI<:%
RGqVT1 NdVCm%L>^w*mj$QL+p6@I<CYe1iR5K>:+*<P+c6>+V&9J18LKT^/&CSc+l4/XBJd=at\mM@J+>S#>HeM
:6%9Ft K^B&y9=<@Wdd/Pnw?T1<ni:j9%@w/1N:!I8HXX5mA@5^LdRm\y1k&CY!dlP&k%cBG/5eaJB>QwG+:u9%
eNER5= &V9EX!VyP/@&EX&4tkFaDJ\GFF>D\wwq=q6R1uV>#GW:<uj$V?4@!en>LZkb8LqAK/Lem<:%%Ml>6TX?
i6WKTA =?@h@6yT!WktFMPjI+/9tZSDHqCp<hABbK\qLAJ4CI8Y?P9:<J9@u%@kQpde!4k>5*H?@HtA6cy1A!lR
5*GPqL >Yn@@nk#9EKJD4uWP+T6%BH9@FVw!k9wLwCH:Xnw5MDcauE1p\p+!>n1Iy?Kk%Z@iC9lC4d*%V9NAC5R
wdWakT 6uqm*\V6#1Sqm<VZ=\n55eKmM5S+dDSm?&@Mye:65>a8$BPcS4:G1&H51XQp>6i/e\+cNlw^G&8@pM*E
XEGeV@ FqwDLFnmdNEu4Pc4?*RDcnDa!Cp=WE&EHWlTTJ#5P%%b?SAJY*u!jjlj@68&:LGi*t:e1MK%:CjPX>F%
Wc#^K# R9kcMeWuQ:y#l:l=B@#y8^kF@/N<jMj6AcZI!dla*<p/#ta!&dk4q1$RERK8aHdjAd+CS&pXH:lZ&tFe
6:k&ZF >iSJ<<cE$BZ=YyCVlX$VP1ptNw%5/GLL@wn8t+H>XE6p?GcaG<kKJu::R4bNw!HtuhN@L+cE*H=\!MHI
^Dj#Gy iucaQ6&ZbC$eIT!!6GchbFVk:n\T>mES>1>#P/YjG4yYdC<l44kK:Rue#kK8X+$hD4C>hmi<j8yA9eGL
Khp?lF BSFZDJ$ebe8^!Ga#WXC#Y1dTZaA4+AmG?J%*Jndk=/6/M4F9Z#P6ykcIN!TBNZa+MMV*S&T\A>681Q%G
4R*lwc h!qt\1LAdHu&#!V5:C$*h8?X\4tkb+<&/D\!6$P:y\&DT/Ye%uQM&LJtlK@$$=*lCXFIc=I%PLYjJMIt
neyE&I PTT81ct5FA<:XN4=L:IdAnQaquy<:iPK8:P+YPuqXdlWi1Me:A&DIT:Yq56>VuAFB#6F\K=%8LC+4Qd4
p!ik8h Sn^6KM49KWGZW?qtCJmc!cumjq6+@VZ9M*#FDhZNLJ\I/L+wYGB*qaehMT%XuC:*?wM:RSu9##jES6QG
Q4Fi!b qp!#bmyq$S+apnPRdhN/tVl%inqqZS$Vl*EVy#wDPJ>Q\VAkm=b+uTMu8L58\J+iP4Z#u:H^pN%4Sj9=
=kZlA< bqwDDGp?L9R+kdnY^jnZ!18@9:HuJY\qZBMTPyqMNt&1dDw$N1#N8K$*&ikGDZ#KY5jB5W/A<Z&HuC4\
X:t9%j 6dtb?IwSRjQGBqZ?MZb1iqH\Ame8V6liPi!V/!X<@X\=qhHHbLPipNmui^ll:X$>K$^>C#awL\YL^C&!
$Qhb+W SyXIEhbaDa84i#w\emIQT%\%Hqb$n<DDTk/:<n<SX:8Zb4y^jALN&>ut&9H^<X1Hc\l8*eiAH!F+M+RX
$R9Gik >@c?JGR*pdAM4E6pHYXq=dq#6Py>MG>uy&ZH$RAn498c&YE$N@<A>!B$4>yAaNpPR?^p?Yw>dEtF^D%+
b<hQI@ GL9X5&ZdmnN?Fw9I#8:qacNbn#LEi54BVS8=JjF&n*k8y$+TS?I5MjP%/I?yEYGVawuln\PYWy%%Cy!A
HbtE/w iEP@?n8m/#VtPlWXT<$V6Ecyhl\FWW@W%hX=<dCDh#>9==W69b11q1:MX\1hF6nH<nGAn/\n4RM%1%dh
9ZRARB &:%nTQTPeRD$CiLKJMXX<5&IK$S/G*A%!<u/aJQB%b:bp&@nM9EYI>8#yb9VM$E=<e?*^FbaLKA4!%Db
1Twq?h ^pm>h#wu=<+qP:RTA&\=bj&4i6EJac8F5AAwl<SM&BwMmVF$/919j$6<4cB6d^W6G!lejLcYhG=JA:Y8
k&*^KP dmW8e14:YMAd58AT\I#&EL6Z55Qpa^eYXP$y:ZCNRl8@Vc+5^!*@CR*\S9P?jV<aNJ99Ab/RuJ$uZA%j
/u!Iiy G<+XVK?NELcpt^Qq&qJ#AHcy1Ni^MD5:?/hVYJ?8Kl1Y>nF#y1SZV^9cGtAZuZm>i*%F@Y6GI1e=XDnm
%tm?eY \ApJP%?VXB/YAD1^BIBY&MlyykEF=BHYlwuc5^4YAN%9ZlIqA&!HLKwA/!d^NdEkqyl>LNiLW?W*Iy9!
6DtZj< Vyky>TBkY=@5\:C*?Re$\=lud&#ec:=ZlTu*SlWCVPe=k=eGt<+XR5LtXHGCdq5+B&Auh:\1*4<yeuJ<
/C@!$? XVwb%k^dYKN4+uP&Dak5ea>y=:Al5dHD85h4dIBWn8d\WIeIT+E\@D$uSTemLF!QKtmu%nTmP@%Y+\R%
Ha4H5M InTR8G$jwFwZq?dkJ&+CH:EJcFmRJVRNmdE1Mb#aJLwm6FMBa\qch#IdkXaB!^tq*Kcc>>%Dy+4\kqMh
pi8LG\ BX#9dXA^=j#1^5a1&YH5FYt+9cZ+KmH^nt6PqLei%e!YMZy5WeK?Ghqb9!!Sec5u*HRktX1#Su!pwEld
FdE6Bj Wyb+T\?8lH\%V$yDeq+MMh6lJP\<&ia=<4CuH:KQ*a?B5K^wuK=wYS$kZB9/Gql:V!P1:qc8jMN5VCRA
AHKSw& */H\G1a4\ZcakmeVQ%qp5c6AG&RD4Zc5mGlcVDDhPkFQ\QKHjaDt/KnBhSRIC*b+qjqKuI*!XSm:TAi^
dB=$9u jQZwPaBkL^aBP@6uGYLjCwj!atd?c/TkL$jbE9e=p?Q9hd=i&?G5/kZKYMJcD#6uCA5*Im!b+4y4Fcde
I:LReq lP5^b%DT1=dpKYRTPwc5>MtukFZHApEL4L&kWL*kwiw+c#NbedNyQ#SPtWWwF6p$NWunw\VaM<*:N5D+
PDB&<@ @kD8qR1ikPc>%a*/$hH/$hYN%XZ$4?Smlc<iaW81t>lB&?M<4F@6EW9<y$$^1V!YqZ9N<wI>$#&tah$1
GF1\ky &AcSkpF&^&i5Im#lY5^t@i+C\nZJlEX5<h+<jYwPLjG/XBNZ>p?#dPw$elaMeX>jH?wCaiN^Z+T4hi:8
lbE=AR FZGdC\6M&p&/JacyRZw#aet/aIBNLLm+YI=q6cNX&&&5q$6#e\1K%CC?cib4<:$j:t$k4QXkji?6ul>F
%c*QmY aIG81+/9u^eKj5ZJqwt=PSF9y9PtN*I81GQmQ$ZaQcItnwbL4u8&\P9l6:ae6kyaM#*18hkIZ?p&SluP
m1*Lnh uLLEe&mJEXhAFkmLllmB9WdB5GT^$@WAcC&4/G6ew:WJABd:MkualTp^!wuNlL6?!aF\kpp6Z6cn4CBd
Z*#dtA >ncjP!6MkJcb6RS5=<c>nhGNXeS%hbV+8ky$4S>6A::CbjLZ/qijd?tAYD!51VwJ4w5!piZG=/QJnkth
HtE4DZ b9<E5GZ6Zu$#4Bw6*iYR#aZAP5bG@T5l?#\=4\md=NAJQkX$ub5V\qI8&mKESe1?%Xk:+Aa4%%epdI+^
ymIiCR ^=Wuyn4pI9TtFKIeBJ9LAK9K^e4QyuSC1>IdbG9c$F4kHd@ZVB#>aSXkdY5d4Wj4P+1hAQY41@Y4#S\Q
9#SuXV D\+iE::/D4bptp+ZIZSbNMC/JDcVnc5/9bt\Kt4T+VB4a?ieLw%y>AtALTnG=l^nPaYQ>c?il=WWhm=J
>b\*?% WLPHuX>@KJd+EFykCwm^mdk=TiMj%GiBdiV5lRN$/j&XBHZeEp+MGNWkEk5TJ8E%=kN4KL8twbXTSVuq
4ZpS5m y/\G&DS%p^G<+^Ahnc:i?$6$1t$ILLK$ZwC66*d+<4E6=X>Lq4AqT%kMV$eIYi%lk*+1b+y99YtbmK=L
mPYZSh &NqB$ea&R>^5kZY9ut1khpG^Kmk19kcHY&CJjeJT9EVAJmptSp65CW6XJ+!LG&8^*TJJna^+yAjR^6et
*XTKY1 Km6Q&F:1DkGXpiX*k9RCi?CECcVwMac$lyItThYFmJm4E@A<Z\@AGyamVcq#B@/8u$G?jwi+jmCh!iER
WS8Ipa pESPSFq/K!!cy1eI5GW9J9:#pl!qie+#1J188m6EPL8qw@aeDc#&PI&4TH%aGN81Ce9AMtGS4&mJMaeq
?G%ML% \pyqkt#^>umTn8Ly!EB/K&J4E*YXL/jw&i:kCRnLYpNi9Q$GKa6<lal1PGHm+mlu$=VSqK%5w6BXPYL<
B<mqcb /ApG9/84\NhX:wRFZGjpH8Lc>B*baeDX#wu5GAh4Gc6KA#IH+G&M%aR6/&Su>6@mZ8$M1nekGAN6wdAu
Pb4bj4 a^%jjWPeGy5V5^5Cm:mmJc:pJQb1Q+bP$%J#Y14qpnJcd?R$A^6:4uNTA&8>4d%SatMIT*YK^BHm4HDd
8^wt?P HiBbbNPt9yR&*%plP\W\n6aVZ+Gqn<n+%6i*heN6y9::thYJRTL5h+QuFF<>\pwPc%DqWd86uqnCtmQ&
D4qL#N N/C1li#LHq%F&/ap\@e^8Bc*yHjcMdapnJY#mDn@TupkEJbShIaaZi\<jR49uc+pW%^*mCKucTpVX@Fb
V!RtnL AiY>tPa?nLHChRL5GDt@KLk?!k6E&C5*Q9#+&lYMup#JYJB%uPWktANl?1ahG6uu=\FHAQM9pcYH&4Ay
KeGjAw 6u=tB98h<i?b%Ra&\+NN4\684t6HEqkdEw<EnP*^!5S:^$=^&M:8\XiW&5p=:^wH1$G&wGd+e^\<5jua
\SVAqu K^:GG\H4?I4I%mRS%#qm<V4n8uL%RIW>Z1?wcK@Nt<e#aS@8ui*WVcWE&R=D4\m!aI5VS#/<h1Bqi94c
?X1>hI N$eT>nTk\<>u#bEA8q5Kp<!*55l&%1?TK!Yu&k*A+y=%bG5**kP?ZkbMkc>N4>XM%++q:K+:4/MDM\bY
8Mt%ie =kC!5cMnZ4IVZj&#S#nMSWS4l9iCXbCNbT#?LLH=K^h8B9I%lKLFFi@my\DXPSWVH!K&$69&h561DTi<
GY^^H8 eLG6j8kH^LywjHKK=%wEYaHZWZk1<c!#i:8FbWkPhX%JtQ1n^VbIcMpiG:K/dBj@@Sqc*dcb%i>Z9!e\
QyE&>h +j:MVDhhM<VZ:+m9%eeeDb\h*4Y=#wm:na^ENn^+:b+S\5:8GVbFNkDq:KD&u4Dc/VPQ5c#DwHD%?k!w
pqm@nN *N1cSGDJ@PcXJTcE$SRDHat^VNlyKV^Nu:WEB%66/lj^V4c!4yQc=FX$p$:nAMhcS&Kl<<4@/G<^IqAX
M4>4DR $@8@QRHB$:DLe1Y//N1MGXH#PpH9dE>8+SGh%LkP8H+@$>%&De$9YPGb:t8Mc!Q^Fj*4>h/6kt?HDc^<
Fa4XPy EK8A#T%ctiK+5yMZEy86Q!Fb&R!uk4CJqV=>854IX^SaqYwdW<!+b5LtVJGAHbAAtBmdJ<Lt\eQt<a+P
?KHb^b uh:iN6X@DJ&/B@Cl<Hl<LEdN?JC/qjk#>yZPqJ#QPGkZynw@dG#<CPHeN4n&Z#*>>GcCkB*&Klmlt:Y8
JAqZu6 qWwin4MhXjW#mPD**>e#T&i/tc/N?NtDqPbkXiL!PXK^5H\NGM9n69h#=4B:MT\VB%t5bi\6W*tcqVjQ
FlaN&m 8*yLCu4e^HlBn^&b/cB+aE5PYP\y>9JZX+*n\d9B\^RuEW4+j8+!Rn#Q>^&\hac\%P^WWW?ammX?1C%^
qhdBBV ZF#e&TF%iWS&/6tS18/Y:jaYT%PYR#%\hd*4ClcRl#eV:4#HI45RYPMPym6*qnQ1W?iB4RDl/9eA=:X4
-AX$R^ 000f835bb6600110334 Page 187 of binaries2.zip
@SjtB* \FPC>S4PAB:5dkSe9/Nd$?&6Qjm/c#SwbJmcdu5R%tP5/$/e6cnity&hne%iYe<wk16$TM8Wyw?5X<&Y
BR+k1d R+Cm#Eqtk^X5jP:XCw!dN+SNCp$qhEL!4y>GPmJlZe%y8/J@II?MlZj=QAL:<PHDQenKH*icaQdj6:Xw
ZD4cAw nqyF%JbDZci:Vl^JEF<l=cGDAkbZ%+$hb&&Bp9<SVj9a/A^d*P<6uI$#*TmZ$Nl><CDkiyt1VbicVF+w
ca9lml latT^>eh9+NM#q4WMH6tV<LPcuBu4TE8i#&tSwt>=Mu6tmd$wkHYR%c4=H^lbX@>8wVnK\QdeHkiZC#l
IiF?5t tthkH<<qDaiB^d?#qynKmT#LlXYuQBI<D&@#9*6I&P>ymL6Y8p=$Wu=TJbb*&?wYd!NZY>=?&ZZ/>Itl
5aj5Gw lD*\wi8CQe>V^qlm/4W$^qRw5GIh<NTHbHXu9n<+$>mNhG&eAbwC1w*hnRedD<+$XGQa>N%*^%TJ#lJ&
P$aJAS %!5/?eCKltJp&NtXuYb%/PTR>Se:teNZZ$HJ!GYwMjqmN8C5@wG6wG8Q/K&FP$/qBcG%tm*^HN6l1Wqa
PT5:c$ ^qJMnQ=#j#?h/qV\Yi^d*al4jk:NMZCcGX5Zj^VL%>Py5dF8!<<KpiLdj886/j:>X+G5ZW?9eDtS&R1k
wJX*jj D9%&tM=1#XpQGq+K8RScKYnaE@p4M#lLD+:$ILL$AMLb!HS6BLw&4nbhd1K+chJ@uyS:*hY>kR=a6iEl
NX5Q<G 4qBeDll:T&*Y5&#X:6X5PtE#HE\i8dpXiqPt&Ah&5iD!X#Z#dQwQ5yqYTua\@yZACRtdX!+Ya?LKqWw5
9WwQqc E$<L6PBmX^FSny*!<$Val=X%Qp@4@Dt:p+@/kb^\dS6pK>/1PHD6EKEKXylQ<>m>Z9n6$BAh^k<dbE&u
aJ<%nh MbPXC<:1FAm8Kk/SDmKICCdJJ9Ah9Le/\NF\$?hPd5ch\P//\KppLd\qu:Bd9d&S1T><Mt&#$^:Iqn**
+m4bGK tqG6Vc^t9^XSK?H@^ki&/Eyp+m$YQd=/BTh86tpk\yIy#5<bT+\kI%$B8ZYPiCF$+l\YaHu44cWuA\Ry
\%CDH\ ?hl=MMZc^>dF^W>hK*W9*#=$4d?qlYMqDIG9QbLqcRB4Rk+AJGw!VY?G55BbF@%&&C1XdT=jYKkC/+9W
BHNJ*k BL+Ct6ePhJQGCa4ZAK^LB=8q&uVM$bZ=1m1J6pleatBLPmd8XRnI6HQMGZ8\CZP&dN%4^9LXCb:y1Ct<
F6Kn&= nL>XFRwZF\Nndb:n^<NY=!^D\PdJC6NjkC6tP*Cj$l=$5YmJ4+IqBqBdqybtJkaG?b@k$Y!KGhnKYEQe
QXQZk\ JiJPKG>Rh@ZEXhTSidS@@#h%hXa=9895XIee&LEh9lC$R&tD&!Gl<FRC#VZ?C<I<>Z5E5y65dmQLlnG\
m8nN^K hC$huMB>bp&ZAhim:%>*XPHjD51WHK+mi4wqMZE^y8\pQVGSZbnc8@wLdL*6E*Gwb5My$T%XVcEjM<4Z
GN@nLI nD<e9t#LV8SnmdBT1dBqJ\V&:i*&^8/N/81:>JDH>Qm<?Nn=$&<AXkq*hXt>QdT?Zac6uZJt^+SNaB9n
E$/DRK eNASqWn<e5wEWA9pZiqlM4?%<J6uaIYSttmHtcWE/>KB@1YDeG64I4bidyw5?9F\VleT#dSPTXRBeqbX
yMw:K6 %c<V^>Thb8N\FXl%YWKHVhc>18tnmEHPb1QlE@/aw4jt=c<b%:8JC%RlY\F@T8/TwH^MnCZCwmWtF@8\
YqXCt? <81Jl4uDiaL><h#h8eiH=<RWE:C@1@TBDd^4q!hS*GZZAiC:8lynYiXw^^HYDkh5c51cB\/4Pb<1JmhE
kt!id8 9p8Nnj$HqlySSG\J:8BjT$84qPS<X*%MQ#<nRS&SPW86>nt?8dbmd^FAdEN^BN1!Dyyed=MTmm%51hSX
DwiKKj %I<#EeJta/8K#FeFdEb9pcJ@GKRcE#FYCQ8aCJ6H5Pjt=8jbEy<?nNa*Q*j+<YFlNYHKSR4nl@j8WVVa
1bt?ak C4S&H<DVMeyHlaSid/46PB+P=#:I8X/\A!EhmVc&8ReBX8Aw<BV?:t@5Z?yjA4a8NVb#4<S*Gqj^4$EC
&\NNRe 8!PawwCjt*qG\u1:8%&BRm5WKGDh16QWuqXELR4waI%P@ScD\Bl@cG8Hk\tInBQYYS/ALJd!WjG\CG!i
*C<y@B *C&:*ZWPm$/#^&XM:</JKYdCI1*=EGCQHNaZ5?&!?#8itpLDk4ZFt+K5VAmRLS=!XR4V=jldP?t#pJl1
VD^@9m uCcTw5$F$*5APd4W&E?+\uYRDq@B9d:\$$E9IHcqSB^CbYS#19&WFkH+i$Y>E:9b!E*Dt4KH4&abt?>i
Mt9HNG FcwB8q=edJE%8Ib%mbScPuSyIM>XaatIBXn!6*tEWtKuGtb5j8:8uLtI%PTN=?X$y#Li6S4u&1Y^Qh*X
H=%Y!= q:Kudulp=#QY#u*InID$w#w4#JIG<A<jamF4mdm=SJK4njI*j6!?hFBct@/lGNyl9$B5LDF@5tVTYXeu
lRP+jA XqQ5&Yn*lItjNK!K4u=%&K\X$c8F5&+pNP8Q@pdKmpaH*njDt1:\Nc*XYGRmd$1tF*B>#NuyuAc&c*/P
Ty<$jG jT=n?qkwK&@\LS^q/$JwA$k^Z1w<WV9FtyKtEeymN8^k9it<4E%q^Rw#ujHVH>HRZ#5C!$4tCP5T*tpH
w9Dqwb YJipb\*h1!?Z/9F%^\$b+*5m4GmYn*C9p*hp=!99iMk!1LNq%Tb4SJbNd=Qm1:iTmj<PkT%t\+K^^VY:
#CIVme y^*PFme^&btu5qQT8qm&5q!H+wB*yY5?u?eMl>!4aT!lT5m8W\6F=h:=n5K&:t!4iWwE&IWA&CF9YG9I
iHehlV uAaw8545?=EqKq>XdLi*M$$B#9=&9CG5:RhJJH*\MWVDuu>%HW+eDZP/p:PE=R>!Vu:cX#*NbGNeLKFy
t@jR8P q+lLA*RtPpmu\/c5Hh1&1GcMNe=E*T\XnH$:dF9u%Z?Fn@<eZP!<qJDtDGHuJHSCF$wu4R>Z%9NehM#u
!F%Jcd =>^qV&P^laKSZcpM!c1S^i$RJ@4$?CwC8?cA*cVCBM@RM1\*^euc8S?Bqaip4:SkCa5PmHH%ACHcn>6C
aIwFlG ENu&@9y1wY9YE//Pq!ZumEui1>CJZY\$KI:8tLd\qn*>InPbM^Kt4==8ll9k#ka!DEYh#Sb+D*etE^5*
Sw&CGL bi*@h95=q@8byA4aPa1pMN=F^y/8!bMnNwe@e%JR=8Q+tmRnG>PuKIaaQGyqX>*V94/pq8tlI#^ZTFwR
8t*CYF *A!!SFyXwpBe?X>9*4lBmQeLZcpS1&ZcAE8!>WDb%e8wK%Hh>MJt?G4KXJet#G#hnyM1L>t1E^<A/KA+
/\=Q!P t+&*^RFd>R=dP=qn?XwM9G5t6Mq^dydQe\!GQ1^8GlP6\?%1ny*!HC9N*Z$5ylkQ=KkCST/&5pcPi+m+
DYYWS4 &JNcda@=iIT4b1BtjV&8A:Y4<uVqT6iJE$?V4TuQ%/hV8mFXCD65Stehb^&!+q%9mk4JDV4PqXpVP9l4
Y4:DkP d&?l4TH6LZCu5cHc$VZC%%!Mk^W6ybLKacth&N<aG>Myu6Kk/5q:d$+>*GH4da9Pb4TP^y:IG4=t54:8
=BB4SH uPhjeXHaJcwuJ8iE4<JaPyDD=EaP=C4:puStc+\9nYuSuD8LG1ApFC1S>*%LY!AMwm8uK$?9%D&6:b\#
>aVL16 1lEi6PqWCK#Bhek1GmC!F:liQP#wT5B?#Cj$VFi=GFmE6Z%GBAmP?VL#JuA11RL^44HD8b*k/M=&5Zu>
d$ud?$ mhuRF1eeXT&!GTj9R&a+PM*^h5>1QDQPNH6J4eZX<qZQ:&6XjjVt^+@hBeD!e<dFQ4=4jY!iKlb<lN=X
HGn5tt P*A+mai&b1/HS\c11:qZuFZIB@y1cA5y%l=Y/41//p/e4S%+QtcXtXL8nN<Sqq$5Aj6Lmb!5JwW#^WVb
Eim85@ VR54Aj6Sm>C%\y#bd@Qtyyd&:bd6yaq1my8PLShn?ByVIm+b95wH*QRplQZ1VpG:p^&^ymJVPZB=Zm@m
l\$kQ% V5:ju8n6Mw=<pA$h4iK4:%<#PuDm4T49E&MJ^L\R>1:+YEyqyRy<ek\q1ihb<mqJ5mMpRVKAT4eDMt\u
neD<+V a1p+Bn$?<Z!k%bQ?!GR<!9JL*bymc+ub\:+eW6lKVhFkL4ni+NYY&:KJC<?L6w%ld6uiutHly5FL&ZA6
Hij5#* lJ@A1pbmVYLuai%Pq1$>>SPXNpIMZYZ\%iN4N4J/NldbMIbmZKQ?%X?Y\L<1Ae58N5>&&AbQbItVhCBZ
ejlmlB ?T!Xcl$\eyqJ*wItpMyF!PLG1VPD!:yEF9:A%lL#JC9Ctq::DahPNpF%q#*k$ZT>eiPdh/iuLX<4yqW:
5+cQPL HA8hd%TVFV/#:B>TB*#%imb&hwJ<N4eZa<P/kKX6wETXXdwTJe<P?>F\=BuT?tRcYPb4K11pp9FWb!C4
di*E6Q G5q>iVi9jP^lRQbu=k!AAtP1FQ?p5lbHK5acTG<eh\TR<bWLF*QYnw?jGYl6Ze=p9S&NtV&kXaSNt#p6
ZdAYTL G^Lj>C?yKjK@wJ\dA566GC=1wyQm/R1BiwbXES6i/NXLBaa%WuHchcFV!YW>q4C!y%AcFI6^W#6GV<4N
dYV15D :dy%+1LG=i$Th!FaQKB^CJ8?eEQPCKwb6#cZj6G9=?Swl<yPn=G!j*GZ!W1q1PV<\=<<@MuKFE?knk&M
dS5AQZ %!K!6NK:BllcP\/Rh4ctww1p1pkYIG6L4C=$<mIu\P?qNeS$@hbc+R>9*Hn*^w**DK!G4ac8>Lu&<Yyc
+wmBSX BZW5p\*=G4HD6pIe=4P&ma$a8<XBeYCIM/FTYNVhCc/Y4<W>@K69#u!LdEnL8KcmP5!868Y$NZNj#ZG&
HtdV68 p#SJ:N*Hj+G%+4\$NNZ$QZ*/dK1XyZZ\dT#@HMEeQ*8t5@Q=</DJSy<4bn^w5%HGy56i4/En:FBI&CHq
Y*NAB% Z8@eeFb+&#VEdXhIiA\j#NDt%?1GT>q5/F>6Aq5KK<T?k\XDdC$^uRCak1KSa<6Gu>8w$KP%m#=j9R*k
>\WmtH EXk#1W!emJZMZVuB=mAe#ymZWW>Bj5t9BXm!^HjJE9?M#6uJda/%$9/Z5yXlKT6J\%SEnnV4LcMJk9qA
PKk@Eq a<ZG^B*Wc$klecn5ya+BGFaW%Q!%WLNm&:dD!S5%P&>W+/dt\j>wm/\iZ*Z9&1+m1P>kZc?V5<S1wX%E
uX%\L* kEk>!ew5\9@iw\jXR#8<N/l^\A181Sl4+ap\Lk1\j+WNT%TJRGD9R4J#GhjbJb&BTcie8w/:E=HTMp6V
\tFQRQ \5QFcA^q>ymwwLmD?mFWD99TM<YC/<eA:K>XmGSc#Sql!tcB44m5+W!49\DQ=&8pb<K!>R8BGRl:*&/p
NKam<I =aKm>4HcFthmhKjpJc:e1%h8!tT#i^yl%$L1+^9caV?y+nMG!%j5@jn/eB=my@#l8j#l/84uVdla&Nem
SW^6B: =AH!Mp%AqaNy<w#/*\P?^wSR+Zlc&1Y^HBInkCh9^nFY4QChh*>lk!dV\Lw6Qya/H<eHcI@p5c#HX\P4
/^F541 %#Pli6eW511yiMT=YAtKR??wDch4$5/1MMc=X<QZdBkRi>>JQ/pihR%jW%:nluepKK<n:PtB*@G@9$Bk
KT6cWH kcKZBq1Zq@&Ku<!k!q?!JCWh&tL9dNe:Zk\>4a+q$=c\\Fn8I*YuhSyabah@@?/@Vp9pY:G>:W<SEIE*
*PEBdV lK=14/E/jl&^\4BBcTKu6NpFbai5bLE!*XH$>Nnmdciqc+@TkTpW9FQ%VE^tu$tq9NK9yk*mcmZe>py#
%@id=F SA!ZT1I:Q@4k!%>>hX9tw9WZqht^q5&+DcQKhnlWYuK@VVGpc^BCcYDXbK8KuA!5L^%jVhV$n?<=K%\l
dcY^Lc $#=$l&j@qlw\>^y5cM%ta?^\/GCDP4HPb*M&l^$S$V9D&G\\BiCKcbpkjKVh=mM&dBwJ>lNu++!\ipyV
?D4wYG @nMe<NWHNt6%b>D8t%<R8&<KlG5$GnAt&I!l5uyTPa/9^k+ZjXT%Pa+&kNt^KnLEt=c9L#Xld=45>e/@
-A:+!p 0002806b3df00110334 Page 188 of binaries2.zip
5@KKZX V56Jn1$kT1tJhBM1NlBX5D^/>=*n1<q$@NByN&KYZil$*/5:1TtA\I=ciP$lPb$RWndylCYCn8VACEjW
Bh*DyP iQ$IJyc9kSl84:Z:=yhBZLX<yquRq9JtWPZ9\BIHl:5^:qXHV&/QW>4PRPP$*G>mCB9l//@j+/1l1jn#
jLn*qu #I<b@hu8b41icZZQ4jP9nK4lc!tGy#yAN5*E#5ZT&e/YZ4TV%hX9c+N6@LnqeN%S8Bd>X$W1dmhF#EX<
NH=l$C 6Vmt+8ydbIh6G5hHGwYm<NX#4mpSXHLIKwtA!LiY:/=C+1BR+RJBy\>N9SMtJB/P>:DIX+1G*/5\B/<!
p>Sbwc ?WQ^p8nDXjSLCc#XY+:t!p$&eM1bjHXZq@@65%FT\Byp:hqP:=/ln%@V6h=8^\8dhLNEnH6>M/:em^E<
elBC<P YB$K>ylq4?+F18!\q5JKyYPpp$\5FX5V*TMkD4J^ShmWM5RJ:mW%5L+M?Ky!uAw%$$XmnlWXLS5M/=l#
1N4yMH CtdY^ii4:&EnPa>i4ACw*4iEhe*m5W=T>^WYPiuaC%j>ppkyDi5RYc9M/@n1dSD%!$%c=Xl?t=ESE#b=
H@\bb? mwVy9c=WPl$+hueMGD?tpFFJn@j1TbhN:GRmap*aq/cZDZD>+*8Cwe%eYZcXwJ/idmSWp@<TdCCXiyQq
SCabb9 1#R=PYGaZSMIi\e<htPGIi\mm+69?T&Kjl1u/9T>+P!$i*W#pnFeV?$S%mkqdiI4jyCJ5<NBuLad=c8#
y%AV$+ pPt!n/Wuu^RKGeaZuHSM:Nn4yV1tiYJNCG5%^%</#ZEJt>+V!<8%ykyLYF1WPN%aT*R>+%h<HF?XGe/=
I@D1Z# tNE?B:8SHk1:Y$G=YL>F$Y>t<SewG41Yh9^S>YnaqIweEPtVZbHtLX5:uIwyD&e!1w!wt/PnjC%:dKWn
bcBS!\ 6R+NdT1hTwY6H=t5V>nR\*1Y&L!A!4bK:FZ@l=S*la>j*4RFSBeLX%m:QQ%Y!%p?Bl/V8D<VnaeJ&cCN
54R=nt iDiItq\Llb1Jqa1mcXFWnVFBEmj@K#*H<N>1M^!^\>qI^$HGtX/VVLya%jI%=bp:HVc=W\cZtBNj*h4+
@kCZA5 em4k1bFm5pw6bi>+!lG&GGiCFZiD^uqn:p%6\uYI1*aa@QDGH/h>:%yBEbSE\lZ6=%th5>M:ZI4l/+nH
uW1yFB %%%hu6mNCau9n?RYJa5XF/8%dJ$bC5e\mK:tYVcCZDy>nT5P1\NhW!!\ay?Mc>qYwiQ65E=#!PRWLF>V
Y&+Q*& Q4IY%VVQn>9>etGqPD=!!9n?XWn4JhbqN>t^aKb\lp^nI6aXmd@@>J=6cnJW4dB5uc:w:pP&hu:mu$lt
$iZA6= qX!DBZdEM<T:C6Fh:@SPPXlF&MKYNBWZA*iV$i&lY:V4%bQ5L$TGPHV!1qQT5y>e<1Z65L>P!J+i^iE/
wqy*Fw Iu!NA>X15Gm6+HI1Hh@<EVeEGDq^h<X@W@>uD+5PhqlHVlIRG%n%1c8WlPpVnYiy$i1MhVjTdY>t9%&=
^1BwQ$ cTR*EunaZY?\a%eZuR!\m/K!6&kLV>HCtt:W:?Xh4%bjc&RptFWQV!=X?qyYJXcFk9DXAy8J%J6pBb/i
y<+N^w J9Q=/1RtBe4$tlWyhhyKLE\b>FaGyj>MAK1!^BHN/IC\i1wD*9*SGYFQ5wL4VQ&%NWDZt5+^i&:wAtLN
Y^JaKj X!ciKlL9?t:XQ?M^6WV=\pXBXy1K+?N?at89$NYc+b\XY56/KnNiy1PjpLJY41I@kS&P+!6HcpHeF<NZ
bYn\a% !%A#Z4^k^P!em!&u9PZLeX+%Yp:$JAeX44V=ahm#\+#5#@<wca&8>nNZCid#mPyA=%lb4Ry&ma:9Z%*k
jtiXE> FP%MnG8d!N&*+ymL49DWY+\thEc\b\5*cDFhT#y5&4M8wRLe5y!biZJp?M:nc:S@&G8t+5KK^%j@!J6F
n>8HwQ P>dpt!66T8%m!>GV?\DMkL1bIE<8t!a&JP!\HeIc54M/\qbb@<Je=WRHlW&tY/4/\L5t^/ep1e=EA&KZ
D^m>tV =nnCc4F@Q&dc6aMAw5htZc!a+m%VKT:/<qyWn+DMFbqV<KY%kmHJTPmWW6&4VtQT!ZT:iDkX%=Dw8y9+
Q:6LWd j#SPyKD+1yRt+Z9!+ckSCTbk%&^^\1\><da:SYDWNnmmPinP%?Y\#pSPN&?i@DqHVe/=8n:\dRb/ttAh
dbNqtR /P6Luy*1TK8iBZP/SLl/jB$Jmp/:P*5R%44apj9G^awqNm&KDp<:VWNdS<WK/=%#lc%kmmPVDe@VXiqA
k=5@BN c@*!p&@5eDu$4*y#<GIIK?i9^4&Y%itb@iQp#n4WBqi%FFJ*dEZH:HYtw@tc6yY6Dy9y8Qq%M5L@bA@u
4P:&Pb K4RpFPt6\piN&ENZW=YkSab?S/*l1?>j9XGhiEl6VP#K@<+Y?^%QGqSpK%ylkuXE%8Fb>jhm#NSX9CX&
^*H*aM 9uZNCDd+eXMIc+dDaTp*/XKb%J65HEPJnWn#1*jGFJ8atK^wPYlS%1XT@cFjTe^EZ=@TtKmu%&?KEbc?
mS:$Zq $kyh:mi&6tF@bM&XBQ=M1bVjdbZ%BAhDZKMNy/ZkuKjpX@<yh5LV&B:ZQ?HtXLF&KKlm/14wGtiH\<K@
Hn>9nE q:^cZ6pSaeL%@%@@V%:@F%BLA\RWAAIACAANXt$qDyke/\5BAAA?CRAAJRAAAGN5cYX8hHM9eGh\L*hy
Q:Xpq= dnM!L%BHWGN5L%Jqe!>^dYF!c!=mdZD6qd$N\nARS1FpE/ckwKe<yYRN81#AHE:BCJpmT:l*k^Rd^@hn
>!LWue ?$BEATFS=NAXV$@pQu!PPJ+P8$&1R?^>:E95c?^6@KRm4!8EMHXbK:@pAcBmc:4Xj?H@jh</9+Qt^:+?
VB1?Z/ u@85N>1*C*%j<kl\X4=VHp4&lkd\?RENaDa$kHtkAe#YtF9JMYBVMkhk=kDMHED&S\GEKaC\\\DCh\\k
XtJ#\t QC49qR<a5QVhP^?$H&a>EPNpK^/Vji=^<lLjXjutQXT@*$/4<bX9y@M6jF?ij%1N!#:6*qR?%Vu:XP^H
pepcXE =V*=Z9qYidp@=IXS=@5*JJ*9y=Z^!E:GI*6=QP%ZHp<5Z!h&WL>@*n!>@?*/j@\VjkBRT\MEFAACAAkA
K=lX@I DXb6JeScDZd+ARAAQkpAACeAAABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9etX&d&6qbC=mdZD6
uXc9#T %V%8FDEWB*C9BttkmWXHkjSE^!Gm6cDuFF!AMqY<T+SelmQNbw1WHAGQW1V%ck5e!dJ=?/H5@#<WHAC<
&Xil>* 54R@iY#=+@u=+/jqK*MwT/*96X=y@c=%wd>DPdZQT&66Z:H<>^@i#j\\<&dt>e\h8@d5a6qb&Mt^w&eQ
S^uFeu dp6iTTS*hwAiy9aBJ&mK9eMJtm!^y*cZ:CQ&q!\nnt<#46m$pHEVVS6VjiuBW!^9Hc=9pbiC/??T6:k@
lT#h/= jY\B>%PGN6J=4j^Ej8F&/HwlhB=FLDt:\Qanj?<teyWh^+5P6$Z4eAN/lLDc@=qcIciYZ1P#n?@Ryc$?
Lw&p=6 W*#Y^WnP@V$=TmAQ=\$>6nid$L51k&D<X#EYZbctJ%@&I#yj!WV?+lI/Jb@SMipm\h8J@VT#d8FjVjj*
aSZTt4 wcZCuw+hV6/&#jFiub#cVeV&:Q5B?^hn%?l1yKN<aba>iT45qm$:GiQR$SlBD/9DEV^:9Vwe\dP:\PQ%
B%ZkLb wV&ld$NL/J@lpDuPX#Nw=tB@FZb9!hWGeyGSuQj*BJ#&MZD&jSR>k4MjN:bk?/?d\QqZR?\H8NyJ=\TY
C8?$L\ yKpX94j=iwEPSc<bYGQpnRhQLX$/eG4^Y5DbD\%h*L4hk18GALyyCJA%5=M%5%8$S1CRjTXuZ^!N=#Jb
9Jp<WR h<DVi&Wn9%@jQ4CHn1&bu1\V@Pji>>>RT\MEFAACAAkADXb6Ja5p>JFFDRAALp\AAC+AAABndGqqduS#
Jp!FPm L*BueC>*cY+#Mm>RS%BndC>TbZM9euNla*JqbGq$e#FmcZR8at%\:h\NWBNZHkD\ZSJJKMkm1IQkpHAC
#+R:kc 66NmKTyCG+qRYpY$6y&:G<Gia9*pMAiY#wku8kGy^h=batlSEWFuXM+bLT*+WVXeF9Gw%CIP#nA1AuHp
eFWFp* w/$mK/pR#JJ*L:Eqn&\cNw9V&ybqw5:!j9N@d>@@ji^DnX$<a^Ft8cLl=%u+ceI^LA=?eQlq98kEdPl!
+JMjl> ?jFn9kAA=k@Qm<GWGN>LPGb@ci5=Cm9kdV>+h*4<=^>*^e/5u1diGKE@/I^h9Cw%SZ#>&hhnc!Ict!NP
e\#Gp8 P^X*//1WqMnY6QudZ9&l6:q@n>Ibt\K66HtuatF5W?QNyp?e5qG4i4b<id>ue$b6e>G&K*1u:E9J&E4L
Wiiud9 H?blL4/aF?ceVW+i51=i9+Ge#MFw*4dG>8ukWw=Y$K1Q/L8?ae1XH$L/N9Sh@hj=q5*u9%Be=YSh9J6Q
W8p?e8 F%=qjGNXIV5&FNIDJY?qJGe48MX%>T/C6uQKFZyGu/qE%^#^XlTbuedSVt+/*di*$#<y?iY?wn:/:Yp*
GMI1+F @FN^lbJduV&p+p%:tXiTXPF49Xhi*Vnl*#MubEhT*J+XLPd1qRZ4HC:EMCwb\*>cWDn$pSJ#eS&/SYFe
R?<Kj^ +FM^V?Kn5J/n5NGn5Ftn5Ad?F1j=Y+GP9^YNIm+^m9bKGL=Yn5u=YlGDpTciXpJnkK<FFA/AWC#TmTkC
n=+Pej jutJ9aT\GXqeLA+\ARC89mKc$Eq$E54LI<\XI#EVF!5!aTIABAa5DJQ/T8E1TNC8YQLRn6YlJSmMAGB:
I8HWA4 tDt8^dwt8<Ice+yL$JkEkG!yTEhRF85!#^!Z+YS%F15Val/ad#K$A5y5qb\5lbGqREuB8QBb\iiMK?WW
9WCtCH ^&hFKDFAACY9@yXktIt9JVGeERF?iRWdb8B4aYhp<4R+k&$LE\CSMlMHT4qT=\uHlwAmPPW#VEca$CbC
YKd%?j CaNVIJ8Y\MF56q^!R&VAj:TEntJ\cLNpbt9kaApc%qZERC6SakceqtPGAGlHuHWjY+HX$kKDZEqLwBX\
y:$&LB 5SKLNWA4^!\&t!dMX5jF/5!Ylnb/!G/uCBHF\ey%5L&E%bKQLcHpbN$AHIjR!5!&iI5Vq6V=Ap^CRR8#
jGVKWh kSaXb%Sd4ISLZyG$LA8VKM&YyKDXQ:aB*P\&<<yk5VycXQKnqZG#eP^85%kBnP9=\ApLBkAFp=ikMtE1
B>%dXL $kS^&&^%*PwMZ@6lLmL&65WTHK%=LBE/^Aywdu$E+DwtMq8D&W1Icl*Mb\P*9DKjXMBqZ$VD+cPpA$TW
?/B84/ D9/lLb>VQkNkMK?mlBdG\5&Y#w\Y6iZnZC\J4S\8DcW$pW<AE:SbYWSDQ1j^T\K+hFPaJF<uk6P$Chbd
@^wT=1 amC?!8e$d=AADpLM5u$*QA+GH^NPeJwu=aAml8c%way!6W1=n1iXAGW/^65mN=!65+t@JhEFII#:Wapq
R/8&&e 4>CPHH1Z^dqaHDm@lj*JCwCP6^YbMN/YwQld<hlb*>N8Th=u!AauLSyZ@A9c!N$Ze/X^G/YS8\<Z=Dqy
TtX:bI ySXB$P=Mqqc54uA/d1NIGBt*<&Bpw@Cc$*HXRS<F^i&W\6@X#4j*1\tS:id&ZuT/9d>YH@$Y<?yJYQNt
9%1we@ lI<q/QRA\yA8+NP@EpQ/XIpyW<VZSkj\5*Jw5\k=eL/>=1SIu=wye6+T6!%YllETp:NYa4Ba?I+REPC$
>6#^NJ bhaNAANy\E%<LJaMLW$\uqPh69BypRcTphB<4LdE*Ej\6Wdt9DW@4@RAGTcK=GQ#aV=H\4eEQldDwQZp
Yl#YkV aT%:\HTbLEBA<:MpI#j^5Ja>IGtRMIKHq=#Nb<5?q>RSNN/#+A<$V@:Tc<ywdAi+Dd1BH4RNcyqIJ?$N
8hH5Bt $AN66>pPPl8*Dh\B*%t5uMq$$4dA8B%t!#kj>+/q9h&<&98p?<kR>1utpj6/pw<%FpKdpM4L/y5tcS=h
KA@L?l VyZ#5u&VNH=<Lj&J:P6Lau:69jFy%9iGIq:QiWC?l*EHSq:YSD:h+@j*a68EL*wwX1>e=/n5PjH/^S8&
-A+j/k 000cd99c29d00110334 Page 189 of binaries2.zip
PbyIXW Gm+65dX4!qNDX+=*cC8?Vq&eW1XQYtF4^=ZjQdHc5V*/#Q4F/?jTLF9VWZ+*NLuiwe*@PuX<m5cHbX8C
1HM+HB !:<LDA!e:5l?9FD<&9m=N^i!dH*=9V69bC^^bM6WW^<8**14P6@GXwPiuy+S?1V!EVpIGMuNFYQ=@HnJ
AW$X8c +G?NQK#JR/m1yHIP:pi?Xi86@@!MH*Jn?+dR*IB^6bQddG#*+S&X6!1Pj+EWXVZ1D=@?P*LndEyw5Kdn
WHd=yn <!bd&^/$w:Ip=?AyyCkN+==?B4p^h$Qw?:KHZ:J5Q+!:6%h#E4YN6K\CnT6QC=%i>V<:ecXiBcZ1\$iS
/RNAqS w4$\:8/F1QWIQC^n%N+&PYu1*B^X%6y=%lMy1k@LPH5KZTt1q1jYbn%5tKY%5RV<lVJy6cn6#hCCS<mN
S5PtS> AlL$t=da:%@>CQ*b>hPt@*e#Fl4aBc46661P:YjdPk:&u+LYyE9IFQ9j>B1Q/dp=q@D^%u86y$w<^l@T
+Q1SVl 58&%%1TcXalN>lbQX?bRiLD%*1%V^h$un61^Q1%JXK1%*I/%jmqh!y^LW<aldV>X*B=1^\18ZWm1TdCY
iXQT8^ !\u^VmuLW!>\E%49hb</AP#b>*^ca^epIk8ZX<+GWX/PPEbwjbm*e+8bwIN58&XtY%N^C#KSJ>d<a*=i
Z8Flh/ dZHHL18>e$LYtdLbn6XV\:JpP=!:89KGh+<itIiCqt>iTed&PcP#m\XqLq@YPCy1<k!:EJ?4hk856LY9
G@CC<% ybbHX!^#cBiyZiKFcney!@:FQV@/nGQd<XWS6P+iLD8y46T%\LF6#@GDN5Gn\Nc?JC/Q@8lX^>dLD^i/
BDu:\T +NL66nc1/E#$eahL6/p#1uqb@dRJGYW5C:R8nyh8!>wB>Ed=H#+uT$hl&%mQNYBbR>YBhiTIq9:mt&l@
#e9wI# 1eInSI/p:=RQ1+LnS:d>^?81Lwe1bl<8ShJw6:^1/\wP>4Q5148Bmqpl%4uM%DhSXDW8lp9eR%WDWa4b
n//nGm 8hcmyl<K#&T9TiSkD<?cP^AaLJRmhi+L?dB1%!4=!Lc!4?4dnAVQLem#kk66%TA=el@%c+HGHi/?dFKj
4cI#+9 p:X5&<dthy:YFLpy/9KX=w^mD6bDRXi@Ph@/DWa<M/yP&akn@?dtX1%4y9TRay#Y%1cG*p@<1+?%+PBq
J&Lc=S hbcd1uFJIGI4tnKPq!uY5P#hE#$^d/L#5:8K&chyuLjbi8j/8eup\Ww:ei?G>k\5J=A/?/8a9W49iN^/
ALb5hu 1:FTuTW:4?lk&i<Ci?4iS84MGFYt!F!9RKT>6Y49#i%u<TC=4d%*6!jnuT:E=wX9p#PQ!AHENwRb#^=c
WBWyd8 Xp@c&l/kI%ek#YX<M?S!b6l4\BZRQ!DZ&8*jAR:y\JB@4LFAQtqdI+=Ne\%VcS%Ba><S+lY*>cG&>tbC
JGeJ*G Wqy/+a/S:L4\lFTYNZw5Vh9alI%wy:t#+^4441eJt%\h41TGmCQ4u4?e^4dQ^BJ4Xcy<l*FXS\l*N:hA
FWykM% qm*8K6$$i/Dewh%>bIZ@9wBWqwWjWd@n^h<\=\l+^WmP#i%Q%l4Qca&dT4qa%:KeC#juD*8DK>IaF!DH
8:RAEC GW!@?:9#1#ii9Py9c%<8P/i?8Z?a>hMaF!G%a9wTF9m$4D*b6N?P9ZB>P&wjJGtM\&d:j9jq4:apu:#K
hM=%SX 5m=qPd$*l5Z6TNK+LWlD4M@qSWS%!MqYqk$91:nkh\&%:R5%*/=C*n8bB?L%Qnet=uy66%Qu#9QDnuL9
+?R5Jc 9cEbh6:BQC#Th:Wpqph%&ct##i9C@i<%E4RDGRp\phY@w=#p6LFnPFmt8:/kYNN>J14lb%jCu/!4:+YX
#\h::X R4Y@>e!eZmM5KN+:Z81FbBdR^d1>#4alamwGW!ha4V=aXpD6G^@Wm==KWDu^m>k&Za\6CqP:9&k>y8wR
ZI8VKT F6V64\<TwcN\4=@dInud8ym6G&1DC84!<CAXG4jEQ>/Pje<:NpdwIlbbdZC8+E=inM8\>yd+8?Fcq5&a
MCWF6? 5#dnliq?%5HjG\#$h$BD&dAZ6t?c><Y\4in^V:&5Q!a\4DGj@VRM:*MKDC#lt%j/5dq>#I:bMi9I@6!L
@:p!TN 5eVGDy:?4K$=:hb^L4dN%p/cWd#*\<Vul1a&a?e^AqeEjcCih^qbCN/je#?5mBX*$tic9KdE=\Fm$?a1
@wCFet ktc4p^B44NLiK!!!ne9<iad5PZ4bj>C+cReWRiQW5ck6%Za*5i%4S&ZJ/44u4YiQIejTYlSB5>V9DdeZ
@!4<HJ :hmLj!y?>?YLL\!XM^+<S6RHa:qa:IJl61p\^:c>VJiJ!VAA/?8C<XC=yCPl4u=%J@LVN1NYY^DS^ZyY
Q%uu>@ $PwHEY8ajk#k4GTRc<<@ZVub#!pq8hmj@+5pNT#d$=4ijAAyWj8*<DYj>1^y8VLH%tc#dNe64$R^WmIH
dBwdt4 D+<b%^t#T#l$ZtITi4$#$V8nMMcNbY?wq!JuN!B!bZl<5C=?q:Sk!Mcyqp=Wy$hk8K*X%SW8SV6WB?$H
5dSley 8l8l8+d&+$!:K9EV:<\IZ%de>nn9ijm\Pu9HB>N%\eLhR@cmP4=R9Vueq^Y*M!/5B9&@bRLe5QlhhHZ\
9lk\uw nyiGLKPKt?!Xte=84\/AN9SW^ti\q^^<MDCI:ELd4#j6teY<j*ijQa9&^QaBQSkeRK$Jd6#&tQi^A#^!
G#p1YJ WnK&Lw#bMV6tj%W:mm9q@%BLA\RWAAIACAAPXt$qu4%XEc<+AAAtK\EALkAAAGN5cYX8hHM9eGh\L*hy
<qb5+& dnM!L%BHWGN5L%Jqe!>!e&FnetXpcZS#NGJyhC=mdZD5jW%#HMibbt5p8@9Y!pNPI\<P#Ec5X+:hA**R
K9qEH9 lutn%%+Hihpk!%+c1FQQ:pY/1X5pXIYDwlwnRqW+qjNRAh#/L?^Q<F@Rbie+j/FdSK5Ky>#*M/9I$ZkI
yt6WIK kt8JNJyAw:5?<<**/*p@59md@@Gj@56:I*^>Ad?@kN@@C%@@P@!?N@1A69?j@<#:<jYl@QJ4SV?n%a4@
TNmle+ +D@+<Pe@@^u?+ybAQ/MR?A@?\$*+>nj$im>^<M<ciwejiNGHBN<c\#<ydtn\MQ#1/Mep>A9d/Ek/F+@\
CeD1Fi 8Bp&i6!Mu%K/FQ#RF69R6T\ikTep<m8*6ZCRyd9CN<Mu+wjG!GG$#eZBidqC+&kphGNHS@AwEl+\Z9LD
?GhPR* $Z6\Y@!pNH1?ybEDitKNdKhL$C:Q>?IncRlENM?GbbL\GMh#JVjk?Wk<pkMuSC1hEC6WKQq<y8ELY5hE
tYbakM &Vk+!@jl?#h<LqQMQKGniDQRm6R%>pY&Cm?WW1JP6$i&Nn\C8ySMpjIE*l*^^TP^hA#R=*mINB<?wb9T
kCANJR baXKaS95\W5+P^AGH1C\%jm$H^^6b4cVyPBEE>XYSl*b/l/N*4M5VpK5F@GA\jS5FRHG:W1+ESqt6n14
N?YEID +pnE$WbHN?1uYA/kWj#dMw#5M*RC/=d1lhjVccb+>DCIAh6jXC5hSe>Y+m6@Iw+1Y$Xm9LLXMcMM!#aS
biSdly \9JBA$jq=lEJeVRd!k/ialAJG>tKq@6?GVbMH>&ILmEVaKLkDklDeW4njZBj<#Jdih1I4iaS/15SGRdy
*?wMB* ahXT*dCS4Tqj*!XmAZlcbPDAmWc%Scbi%hL4FD5Su5bF&@N>M6#\PPlG*nqS:%/GaaeS\uAdT+i\ujaS
uZ!YWp Y+XEqkEcLL+nZ%p:!I:yjNBhYG?I4edaIX8SG$q9qXDDuMw4@lXd&WSyFaMwit>E&h&@ptGSL<M&MEq+
851VSG LqCCbIB5G!#LlyjdNmyPLG*+w&\q=SQd<KjSi++IIK?nuQHpea#*\M?EPFjpWXiTlLiT?QJi\^w6G8N5
N&K4#u w&#uEVWm6n#XbH6kM/upRIcFAtI4&WB!N1ucSYY:#qtmy6/yWD9YNZ/yBjYpVcSj!qhSC6FL/>RpG<eV
SbCnE! *K^yqk^KCd!5ajE%iEJKM&YJPnJiCe$+#:qKWc>VNCA9LP6q&CSmYFl#tG&YPMDGGLTLSE\I\^6=1/e=
:w?BSn aT6cV?J5NB6pd8pe>K<mcC!%NA4Qa#DH!WH=5=QpPF$iFLQt?QC+ViFLebR6%>p5&X9chyqq#l!++!Sd
1e%j9L uy9qibaiJLqdb4uLq5eJt&$b1+ALpTmcVY>hFF\RBteXHHnmnFX*DbNI$wM:4HCE=Ra5uGQDQ&A4#*1K
NymBIW B#hP98EMkt$m\YGj=c\aGyIpq&Su:Z1&dL4#bXjMq49%/Y^45>p*#WX*uNdN@qZh:F$XIPCu:j=^X6lh
ZR?aQt 8%+Y=&F&9C9tb+?Z4D@GJ?y4GC?SKSGW\\ceBX86DXpe6NIt!1&u#+&#myAcbqiWk/SuK?wG:TJ8JZR9
AbP8wE V@wFjDX!MP=JSC+<5hu86>%<6p!/&hF&Qj8t&@jbM5u&5/Q%Wb86p*p?#::e#p*culj#Jq8d1&/&dM9%
dmGBDG Rd/h4:MqV#SBCtKH+&8L&#W5dASNDh/NBI>pu+<nXSiD!FilHR:QqeGTRn6THJbl@ETcSpT!IyyE@j!j
\CWXhp !L?14:eDl+Du#5>&\Fjjul>9kic4@aP4^Gj:b%*uh9Z<yF&9#:14&4yhPF<99/\9h8%?5\5#PL1aZ&!V
M4kj/w SNG4Kw$+J%bRbwwZaSXZISk!PyWBuLE/<kERFi6wFFk1j!P&SC<p8E4\MIMAL%/8EcmL*>ynwNG&&dIw
&5$bE& b8&8PG/Z6nl1n$Fn&@&5&#<w#64CHT#D:KnhFphZhXE8&=>q!:chFYhGnTNy14Xm**WWSp!+b:^I?65I
jGhBBF WFKuRwBDHBRny$ben&@W^dAc5#NRc<#RSGMa=S@daW5&L8uDqEdtJ=!kDCPpVR?P@Q#pMe:KldY?cS#A
j%tNwe C@l>ZDQtk+*A!kM\TCA@cY*SLZpNkeRtpWXT/M:MhNEI^jklmYIu<5XtF8$qaYwFk&1LSI&hRmWqX1VH
l%!enF Sj+>I9<cA\8FVEdtJ$645E%&6nRN<NeK@tJ9IMNbp!$pX>kBm\EQH!#N*Jp+IDHAnPPSSyblV&dcwltN
TAHZJe %m8mTpJAupXX<HkMi6mj>4cINIEkSnNk1@!!yu1XaSd+ZyWSRIkjlF8t/YQ4WuV6/6aFLI5hdNS:p=pu
*+M1Wk q><$>pKABB/a54!\iL4wXkt:Yyp%^%CaR%ZL1K*ybVlSHbNb<!#8k4><H>d%dBX1KRB1wk\*!pRFh5Cl
mDKm^d p\5c>!EP^yGN<*!YPEmTJXRS5JEpknw+MkecemWWNl9c\uCM1QLmS6C6mHldBh5CpbknK5NPENpkITAl
%V%\J1 J<>/PwAamectbIRcaR!PpjncmLMXXadj1!Vh+SSt4bHJpSkK8Wd&BPqNKe+kpMTlEN+4Saa^6wb@J<!&
*8cIjQ ^qm^Pky*^XPtkk=WY/$SN=@&&51RnI&XTSSnep^Fp/q?#Eq+^GCppeqkIINnBF4S@@ZyCHiYyDb4VIai
d4#uZ& Q1&SISetPWjhTT+c&A9!&hkV&H61Vq%!cGb\*@TRXP4I\8+Vp=/iyCjy/X=#&P#eu9XuBuYAd8F+*u%K
jacqMD KwSkDcl#A1WdVdWp=EKJPATCPCFp\XNL\B*u\tk\LRmLVAQ9b@8FZ4aSyMX<^XmhWbSGeTHdL=b6aR8Z
e*TPAS #bclAMT$j&V*n#Kkh*uR&8Kp!NaucdeQ+HB&Nh<YNm9k<#w=RHl%Si/tZb>u&@X^i=^hbYb?99*u@dat
?5cN1A H+>P*nE56JLEEYd$KTaC1?TFiLTNwd$WmSAib^RlMm/A^Cep5ckVVmN1!*JB+IukBYJ@%pFS/ZSuC466
?%$:>S >=j6N%<C%q8Z*:V:1T9QkhQyNyqj:G&9=tq!eXX9h<*5t@1+THj4k/dIHDnl:eF8qt@Z/=N=id#Nb45L
bdNTQ: %/X&9>ytSKqLB9+?JuHAEDKbQ6y?D6a%^paN+&!h6b#Q$YDJ>*FdptkRV6cijT>deppKyI#>GbcJT8<9
#bVq8d t:ZdHS<eh<5MpPH<jNu8G\D&\Ldbeq&pabeBm>Nhh6\CR5:K:Hm:u=&5ATSq<&X:$b=9=*P:u&cA5:yh
-AwW$! 0002bdf350300110334 Page 190 of binaries2.zip
T9V*j* eYKT>jp&Y:P9TGI!THJ#JH&KnBJFB^#X&Sl:ibpGCj!>iAMj+#dH\MRptq>RY>9wZS!qIMm@/yVCjpAP
nSZn:X <*Ib/kQA:?Z&1mmQ8@WS/P@=Ci#/q*X=jFZ9G4jZHt&95uQk?*EHM6\lZ<6%$/Z\L>5@45@KdZF?*LZk
Ph+Pjk jRBZ69Nn5Sp95bY+16:hK#yADjQECM*WCF8b!S4FYnXQk$SE\ppXL/qYVnVw!S!@K1KE@ahdp&dNYVh4
%&Shhd #p/Qq\jHB>p*^dHL51^^^VLdQ$>&X#Z\NX^5D+:1duuRkAmpZ&duTdLPdNqp#j4ablj\6#nJquPAZQ5Z
QlClGt &dH6?w!P=pZaHdmInH^EB+\SPSjE5EmeXCQyTnG=BCVB4HKmkK:Jac8CZaElSp@?E@yZ4?E\@IVMcZwM
1@44PD jC\aJD6LpwQ5T&j4=S^A<VJ4\XKE9YZmbw&t<\wa?1!X\MGcA:nikjnB?aqpiIcyY>JAV8kbH&YaEK46
W?Xh!% McK/8S+$MnnSFGbpc?IGPipIhnX@qIlMYQc9+9Dw=\nhQRqb8wSlL$pj#5BSAkR?6ieP*E8cunau91<M
XSeXP4 YJ1jE$W9#c^S@NIMIk+cn^Qa^9nTSSt&p5*8p@k5=%/TN<^DSaN>Spje1&SCZ:\uT+/X4I=LMD>5JP$Z
pPeVm* j*SPKjEnp?hF=^PB/a*tFDlME9\tIXKjluT^6KGSNRMB#i&dZ6IMiWlSNDjI4#F#+<CVXE!anheVB?c5
5@5&8I 8Fi<b!1SDApDuW^<:W5pG6d^uLK^S&RpmwNaMbZMn%P&!5^yjEttW@P/LEC>6n1Ky*%WVJXlTXp+%Xt^
y$$QB* ^/tqW<nYe1IC9&tCuhqK1L$S9CT#Rbp!nm%E!ZF1CA>4&Kk@$TWReecXGme&tw%P^hb^\6VHDJuYQYL1
nl6G1B 9K?hTEcN5XLC8VQK1jhyB^EA\RWEQa*pR+$G*aupNA^DI$qQME+%uNQAQ!ypCS&Hbw9#VeqLdB%Wn=C+
nRm%94 9Y#Z^QljKuacBqH51NG%JL<>#!QZDj4c!VAJ\Dq%>R1N/?6WX6L?EuTRVDa>VFDQ1eIRk@PlcSypYDTR
tkywhe IM=SjnktllKyV@XRB4+XaWpV!j/CM/IehN4IX$%c><q5LVC!^En=RRJQ\VE?iaEMmY@bpmSGDJZaL1?J
M=TdIJ BB=5BFtc=QFSM8ukYQC!V5&Ka@@KlWaZValYe8l/5>A/#Z:TqY$V/*qG?Y1wmmF#/tPNw=hlD8Hptw^n
%ly86T 4Emb%+BVRLpR\9M9ZnKcYJc4=GY&p9lEa<qSqCPd$4PX+>e$/iN=qREn65kX+WmM5R1jtDIbm1S#NYMk
@S\%pV %6FKhPF54LcyDF9BMi/F511N%+\yFtcCj^H>Gh*wikG%R*@qyZdPwi&A4SVuNMc>\Fc6i&K5+PalGJ!N
J!HZ?Q SlLRaERd1cjluTqc6!//NA+\jM^?J*^wSL$Nb!?<%9wmGTqQwNc=^X%^D4TJby&u$Gk/nKLS1MdYDcy:
AL:G!C nTSDi4cmDM5WSIXPFcik%$8KeEYlpiV9tc?aWTjV%qDlX%Ic4DZpAaT6ZJ%9yLcnEL@SeN*+uk\V*bNt
L*ITR\ #JJlTqTF&&5%=IYGB=q/1:Xb1%QFNq=TnI!dBpca4Dtqe*Dk#T!EVkn6b+AImkp^>CE?%j1b==DG?:/Z
HyMiAA Rd/^>jT^EP\GkC*PtklWVQpPAc!Lp/k&TuGWFp*aTdt?w8^XZFAP5Q=1nCab?WR9eRERbIwR\yp$N#R+
jF*+&q tpa>VK#FiCplGVG^HG@4#BlXV^JA$/kVn6qK4\4VmMkSa=ZjjbtbC$%/1FPD:Hl\up!+=CX\TmkZ/TX5
VCZ1ei =l&a>=hMu!TQGY5aFyIDIDX$Y6K%=NPHCY$y4n9EBt=RQYkpyPH\Y4\/MwbAkSHNnQWLVpXRlqA8Fjhc
$P/#*F \SCPJ+/4IbS*T1Sew#6\KJKZkK9^>STeEedAip=nIpNb%5*lPRS^!Dlpc\kuHD\VZVknQenqHC4:ARtl
NpmRXF l!$1*D=BHql46<&kDltBlCwuF=\$!mF*:5\k:G+Ged=^W1<VVP%6Q@?^5mqklktY9D?!ZE^actbI+Tti
=^:+J= PCNT\#b&BYpJ^tyiuAdeP/ViRnTMA$WtBX$%dqn4aHiT>BqR#!It>mLy?#b\#IM+Z/1RjFiutFwLRTTE
c6n!aQ jchPVI\*uB<tq8M=+QJNChT%XK*%#NdRNaR$8b@JeI:eMLR\nmMhL#G96EYyk!Tua5m9p#:nJ=<I?Gk$
VH6qmQ Y4Pi#c<%uEbpCN^I*=jm5elY#dMIA81VViKjFjaMe%DIjc/@J8w$aG?GyKa$SeLY$EIpDu#Mai@=\bhu
ADF$lk iHD=#!YNN5>#?q5h+%>:n98Y6nuHae#Rh1hyZy:l>e?#9FHb<WupYq@II%nTCI*T=<I1kYlJ8hV$PEhn
H^?ehW VC5qu>l>wZ$!u15blLW5%TT6XVTMcuXPC5yiX6kcRyLMq?dkC5+9&#dk\WWY6uBSQHwH><Jb\T9WPJVY
V\&j*V tIDDYC?SGdn4BL/%SdEqtPWVaTCP^QTFQKQ^1ZW5A+*wLnFKj9&R#b#/nmWj4RqIT+FG@^wDWN:jchaC
j+KIQu 68+lcWj5&=Y6IVVtA6=y/PCGTKG<:YDT>+@6^SXtZLd5lk1<WIGTAJidL=G9B$6mkkGL61X/AV8<b6n%
JTMp:! !FCHE/E^lGd\HY%ADGwJPHnhwmWjhthP&\6jDw+Tn8qmJ!IKD4K!qWyabG6aN4a+C*n?RXEWcQ#KDQFW
c+lhHL e4BMZIh<ZjJX%#nEiahJ6eR!Z@jd:AR9uYZIX<8kL8W1KA>LEEF1Ja$kcdGwY**:tTSTubw&MlVKXt$L
Cd511I T6WIe?iV@nJjjSw:@SJ&MbTP/NtKHF$*HX1@Pn5@\9q4MZZa8Q&qPYT?Etyycn#ZZhZWVdcQjG*&+Wm<
9MY+j? hk9/Gp6QptQmtNjyNmpAT6=jhe6I>+5pLAc%>hlbyLQGwIwKT*&:GB@u!Phw+a1<BlB&^RecRQ&6$845
P?THe% 4N*mmNeu=Bai6#RRe*B<i4GD$&i:C?Ra<lWP!q1CkVWYuwHm>A\ehNylb$wjt$uD4jdicFuZm>9AXIQ^
dp8cIZ I8FiCiRIT?4PEny:VcF^H/cqt1B>IhjIIVd41+%5Vhk\wVXE6m:upc<&$K#PEWbSyAed4eYD6tAq>pRe
XJtN1d /lP<FyaB4GWDdlB/ITF<lE>/j<>Jc/iAVcl%5e:YDB1>PDlww1:HqIkYD<Rq+$#IRaR$yXbH/pF+YL9=
5!NPYH aDiaXVbyKYy4p11?T9<CdE@q>yJjc\RPy6^lHHPnYF=:VQt9XDa>>l\9Pm6bMuIwji?N6L?kXicY5WV/
tw^mCh yjukSw\*nqyTWD=JJQEpF*YTECCu4mp#$k/pTj5qBPHN$ib!uwmBeCF<nSYmtED11!c^l$Y/wl466PI1
tckCN: 8cc9ZG\6np&TjZ:AN*%u8NE5cCP?WIyS>1X$YG#&:R9qc1kc?$LuKM?A>p6\PLBHapeKW=P4ThaMmCFt
JAl*nR w+!V/<iuQpF\1wR5$dn/H9qK!NcQI#b68EHtPAKeYJqn61S>Me4d&EYm^T:S/WRF9<iFpXm>t6N?CiaX
l>e5uc eHFL%#eJPNRPDT^nCT9NpEucJ?nTCNQFAWmmJcY9tt!mlku!d:HD*MitnSjVQm+!&jj=L1q4>Rqc/>\\
yYu:dT I^uhT5VFjaFXJ6eL#hw9\dq6MmNp64%hl/XQ!QlRek&B9GH:u@m>m^RRMSB4L>KVBy%eI?5aTCe98D6X
c5u>#+ E/pTS4E8TRTeDJC1>9Sc?%KN%k//RnSBG:9NttHj6CVeSEK6HYbY6SYB<$*Tk?6Bdq5T\quSLt$k^TBc
jP9wR9 4XquT#lpq8WI:bDbLcLnQSKEbm<:V1n^m!/FNnpn&ep!8t5GaMJcDBMNN\=\W6H%nB#wZN?\L@liM/tW
G#1<8M ci$LNTc&q/apK4/Sa4^cnblb=XyNRnpaCnywk6AKpjkRjVSDlBq*KN&IF6dkjK%lpHGXM4IC>*wAS/M:
uBGPck cmqmBpwLCI$eEp*CBawQ6!@\p6J$=jw+Nndc1k\4Y\qeJhwtLL$l48>YM6yic8ITkym9EV8qGV=l>+je
9yY8N9 L$EVNSNQ!wJ:S6a1=jnX@A9\#:w=AH*T/m<9LnKDe>Iikn@cD\HGAYaMdj+eMTb/cV!Z!ELHmlN=qen+
l>CVX9 8HFAewee>41?t/jSJRXmmpYGyieuhm5^HQLTp5ZhEb1@+kC%5dbj<GC=4y:I+k9pE8Zn=+!XEk*4G8I4
h&nAIX hlmEK=1Tnmdey+TwDAKMlKA$dm%\981\VXEt1GwGF:BtH>?=VhpK=PN<TA\!?+ymE98DbcByI9ZHSMGD
ta>b>I \mE6iuEMJKqP#CSR&PmNqAXyQlp*5Z6F58kVPhYPdnwneWby*eLS?<DZbl?^BYZ<LXFHIj$bAcM#/^8c
L8ljWi 4#qGPkP??kSF&FADV></&QV>+1yp4Hwe*5RPEFS!qthyTQdc6!p%JE+S^h=BPBG5K%jy1C#I5R#nJyyQ
Y^$yad J55Jk$p#QdIM%dXb+#9!NVE%nyyM^#ut!VGaJdVBtAP8\ny1MR/ppl>!%JISR^AnLbjewpKS11ea#hla
c\Zmq! F=HYaFpF^AWc^^LB?SN6J1dEG!e6PhS*uEI&WnM\Wlcp9EV/Iieq<CJIaienZ*hp\SBLNLSyc=Fh&@R^
6DNCct :iJTD9QXRI!\6Sj\9pVY6>RtBjw8jG%RZ>ilna6iCAd%\dR!tZ%9>LSG54i?B$q59b#$V%yhy6Z$T?Gp
CCmGGG <X##$NEJ$%%+*SYbLSXe5nICKyBqLe\Y8KM6ZHWjNBXahm#^!R\N4W@V$BbZ<CZDFAXIL?+qVRc?ey#a
+KGXh$ GC\jeMFhK\nePJD&yY&yAu1FkW/KuT<6=8q4hHHSWVQw1Da?FnEHbeFlZkK%ZRW*ZSJa+4\#Ew%cwH!>
?AWE1W Tk:S^yItiGIe?1Bh*aJ<H?Qyc+1DDMw#HEq*^B!MaGyuI9yYXN!Z68$\<Yi$=$MhnP<Vk4EP@BJddR?q
$wAHcT i!DJHaB+F%+umaPR6DiwbweK&^IABD5W!Lc9lc>dXFIEVYk8#5tBR9T*ZdekDA&ilN4MjEXQT&+D?Dwn
RR!hl1 !ccBeD?5NkAQ5L^:Radb:Qbq&?mBST^N9#k9E594YKR%NSE<1N/deSMZBjcDtF^+t/GKajBhB=I>SALd
FZX!W< BmtGmB5wtGZa<YR5<*YPeT=\Q5HV+SDMm/AP+G=pD%!5AB*uW4?8phLAJwq4V<WZS5<m/&b$nXcequ/q
Z%1H?R *LBnTFLGTu#<+^TWyXd!EnC<NYhH$dpi^#aBC4B^pQ?C?MmnDMM<pHWG\b!lRlJ!uwXq$aI+GEh<SWPH
Z$KL>8 %kwVmHkSklPJSn5c&EmeH6tc?GE/#A&KA!+Gpna8*&1pJ$V1Kdww!R@nPF:6au5bVqkWPFIqwNmiTly/
XjXZF% lucI9CCmQ8V>D5ZSyYiu1IAyMT/6WWcQkea%WDSHY+=ZIT>Ea\GdZATF=>Tca?JKNp1Vc*!w!$T6%I!I
W4h&WA N5@h5m4DAkcp1Teb&mZnXYYNTBD%Lw9<JI:#mJn4p1leSJtKnpl@R1+c\qqkPjweh$mPBk=9MN\%qG<E
dt!:Ge inykQBD6>!q<RN8EmSu56ECt#6HCTR8@p=mjM%ac>ck#+l\JF\bmDdAb!LApWHRlCPe46KDLnjqWV6VG
6?QldF +::ZW6e%m%MNZTG=NL#wZmA66hRkEpmuP*T1tJ\AA8*QpG^ETkTcqkA+quBIm@pY=G6Dn15l:K?&Tby\
Ri&yIZ QK@w%j=YnpF=Pb:Xcl89?iX%9T4D9G=Jq&J!Q+HnW4$VEKHqSG$<b8lmE9Y9PHN>Nyl6MG@c!lwG$PaV
L:pd8* nuM</^/wb<J<6Zk<RceD?5W<PNJuD4E8bBn:a#NN16A*6mlIJWNKa/dQ>jal14Ri^aayKwPtJ8b5nK^j
K>tcDK eH&!^<SA@<WqtuFhe#Pkhe6VVWqCL9JaJl9M1dY5i<kwhKDwZn9KK!aiuI?@wFBlS6\NwVlt:P<P5AAY
-ApX8n 000dc7c1df900110334 Page 191 of binaries2.zip
PMHueu %=eVhX1bWeAw%S&jcH:ZS5i1&JqdBmWX$1@W+NcZRVFWG%5$&Gju@cG5c%abDlLZYLFY6FK5RijV6h+k
h!l6iL :SDBLeE\lB$aGiC4IbCMqlqn\S&K?Apc:I/CmVt!t&\=IyDaCmXL#tIcVl9mjcMJy%mWmb&q*5heYTwF
+nj=Hb KMiJj@dc#6qBCq\Vd<bH=$*?qaPEhTT%+\VGRbC1E*j?dAEJWu^:kH#el/Fj\BFuy&e%YCWIj4CqFt*\
IMV<FE G4%VkXCmCtGG=kuNMbm%np9*84VY95VYSqQeX9P:mT=P$GTqQBjACX8%@!VlJiSS<w%uXGGnaYde<mHq
@i@wLY EbG$81>w5KXk#Ml1AQ#b#yuqTQeT%NZ*p4DEcq#Lkk*+1$ZHt!Sk8RJ\j9taan1Kj+!11Se$c@1&XVQw
uDJD!8 =ieAqd8M?@1:AKbW=J?:+mYiEFd*DZ&TPa&<66K*%nAK%BjQF%Y^E8pHk+uawm&thBVF:<6amSbtw$\Z
y@\ui@ GPQSyB&VFR>w4u^kBciwWP58TmKuTlwN>dSE+&PjJ:eK^B!$yI+TLcBL<B=b4Xlapty?5MCd?<KV%InI
6#\eXl TpXTqLYXPCT^i^iHKidKiII9Mp1twR^jyKhuy^m=u&G4>CE>k1PE+@DA$+6Dk\5FGH8qy^jT4YX<EqG\
Bp9T>h ^VXX5nVWea/Zq#kPT*K<NB85d$\5eRFBu$=kEn6+#kp*aVZTjS1:AJt9HNQ8Se8E^wBIXic:kWQRKlq8
eF@E5H *CQeJG%ajW?&mTXB1ya$a8!$E%wj<BAVuAd#Sw*G%ZHhqHLiTBmk1Jj65c!*+%1tJtIcD6==CbN$QjZQ
+$LlDY &$D@!p1Tmpkm%5jQ\D46S?m#hQKeEBEZ!p8Iupp4qXcGBp8LPLet^WXb+S?ZjHLjDmKEl9M9qEc*t8F8
L\^k>K aw?\+X\MuY!+H%nEqba\\*anq$y+MRHqLpn<9c!L^@+t<WK^Jthh>8Zbtc1VW%?8BbRBD!tuywScb=9+
hi\\j+ &BDqDGaMGSbLF+VAH&?=5&&AH9#R4Nn?lwPu5*B4L:M%$iYC9XZV^e+?N1JKG!kHkGmH^R6^&4j6m\/^
A8pNRH qB%9#A>h$N=Nj$n^1>iMRbLwWtc8A$4^1mHI^aYBjwXmE4FT4BRQ#IyL?wyNd*P<499G61hG%/=\+54&
jpy4># #1ZSJ!>JH/KZJ?QRin1&jaYI5IbejTudc:M56<>HhAimd4W8+^nk85Fcp$bmMASc*MCtdcH>k9ZBE=C5
R\W5aW mY5ISZ:>pK%JdAtJEEQRA5?Am\S1*$l5iBVY!jMqaM=uQYcKed*adl8d8L%Jt4+uGWCm:&ZaDNictNmc
!I4G^a CkJZuGET5%<$:YQ/*5e%Xj4J^G/\GJZ*ZV/Nm=&Y*LX8?:Sd$n@T^!j15w!/c<GIpuqu68+meyNR6=H8
j&ScJT wL+X*$VRD6bJdGF$IbK@p$=!:5+#=+pPVmFkV\*u1a%?$ndGRdKwL*#ww%6a$DSDy%YS@kFe1kiNFlLb
qRw#PW ap4>Xa5$nJpmQqPQ=cTQM+qLCYLLZlNq&GnQweI#nd>nZN:ENq@ZQ?8uZ?uI8Vj8+bL&S&*%$4J#lBC<
y\L8?? VM/IDL@I%1S@JBp%ecnFqQy4!t^6n=PiQ+1dJZZT%=jF+uw91*Ed49Q*V$1Ljba$Va*$>9MP^?%aMneT
w#adn# 5*GS#X9FCq#l$5lGG+B6BM5y=%?eHT^DE*68hJ&Q>Mu4/t/adct@Eq8bWwak@jQFKBEWP/?a4c!QEn5K
>ClEkF ST+?qe6E?<C>qy\8TGJR$!<B+:Tm6pwu*QGwFVn9?8j:WAP\>Li/SHyQ>cF6Vd><pJmkWaGQ1Zd8Q*pp
GD/p%X ///KpDXiqq^E+MPQj?w#%Gc\V5+$5Sw5plmj!6W@$+%l96P<q/+1%1jiMGT$59!&Z/DCc+<acDmnDeDT
uMAl:w /SF4!j\eDmqpJE=eEp8:p?!G$dKR>A>V4$wi%^RdqtuqD!@jmt5Q6e&?D:Pw4P/6H##HV5Qp@mpt$m/6
+<8kc< L5C?<MmlGQDamB#nR<bp1WIMAQqA*!>ewCXk@WQHZ8mmnSuYS8&\%*S=Pqlc$8etE=ZlyG<M<j4589mw
q:6\!6 R%%EFqeX>w588N6Vh9SPW+159T\MX/ZIlYR^R^@Zt<EDCuulkwcFVqhK^h+EZIRkeXYmhqm1Y=15m+>:
MBaPG9 NQ%VD\$*GLqaB>eAT\FbhMAMd&T#$<W/Ll4l\hQBdL>R5F<K%hh%Bt!%L:FX@KZul*6+jXBH9%yTHl1u
:EqZt: iE4CR?wlTJKBAa#Bu#:C!@S%#%Rmq@+bK!q*YM6V%4T1+l8hWC%XPJMM&1Lmn!+yFQq^eT:WYj4?EZ8?
cS*qYC b/6Y4cL:=iia>GZ49y+V5#&El%Nh!CSLG=\14GZEqJIEpqPSBnF6aMeVW/e6@?R/CGKpnNm5NaPGIC1:
&1&@K9 RR\/=K5?yE5eY/NQ4BE$wI>h>EpTu?1y1@TM4utlhF9Kmbu?iYicT#Vct=ma>BE@1+w6HX6w:H1Wy%4S
S@F=PI 4PH1+$S/A#uK$D+XETInDZY^n$9Y@Zu9hIG/>Gy\b&VpK&pe>RVBqXI6>1j<NJhGYw4J+Eb&5@*5<XSj
I8E<L< w1JutHq89mDpd5u4$XBS8l4#+Ym!6=iiyCjYH?:BcE=PHy<<6w>Nw*Fc<6k!X?GDN1uV6Kb:8D&%i@Ta
:JuQB8 pMP>R*5CQ/h\/IWq@/EIS%b1GSbnM*!S:&il+!hlpAHu^Sq^EcBN+A+uJ@k<HVIDn\%hSDkW$*G$ApF+
M5RXFV ?^k%mp1J&JQF\<ei9Yu+Y*q6*qyc4@@$+X6c*\ycm*!$GI@G&Yk<Y5A99I&t<Hhe$IdSKIQ>5CGHk#bV
GYuC%& QQw6ylZwYSTnjLKaVwnY#RkyyR*nDdF^6MlG?Slwld?L6=19\Li5JA1L%clendKPcF$A6*Qmc+j:F#kD
i>J+qe <Dh:&@tcE^9H\FikdqECXXQc5EJcbj>wM<c@m:hhZ+GMcRa@1?t1HLZ=yMl=A?q4t/Pi$qj+&*c*h9mY
pMPHMy %l@bK:9&/=c96:Vi$91nwZXT\Y5%\q@+nG>qq8N*&k6@*mFcK>^cniwAbNblMbyR<#h@H$*CP?Xj1W?n
k@KD1p W%yZ@D$5ykHBMd/@8:SPR5m4MuSn&McMj96y4jSX9En4PLT\6&kuwRZjY5DY6=lY5pY5qj&4y*WcF5VQ
B>+Q#J ES@R96X&GG%S6!4D>>FcpEFC9kdS&?/6yyXwYE#?Nc$X1GuLdkk@VEq9N&<@4i&1#yG%ihuVm1?eKeWN
GB4&%$ a^Bt@H*4cRX:C?cy#Pu@bB9RmqCm+A<VTyc8*kFc&>EEXdNcqhEPk>qFGed>LaIt&nl/B&kNm/LNRIK:
A^Fh\9 $W5?b!TWw6@Bu*iBXu&^SSbc^&m$&yYCnI4\^L6Dc$j/YTt6t\ubJ$V?$=CF#d6Ec:5ceb^D6JdI%=\l
mt4\AI Q^AiCFi<>V+uR5RiFlNiBD^M>ttDBJNhjkj</@iGALm>ACDMDIZ9p$u%%6Pcj*?+k>64keEIFN9^PH9d
b:^cX\ <ZCw9y@YZLEE5d$MiWdqpLe<#9pL4\tqa&=#c:i$*6L/N4:iBX4dh=@Y9JV5TmX@A<j4LYjbY6=c<?yq
6&\h=m AFN9M/%qy#RK?G?b%m/4l:VtVG9>X9NX5Z@HjA!h=GG/MKT%qL&Weuy:?h1?^Nj!?&m6*kt?=5yQ%hjm
dB=1dd i@u/V8n4t@W=:h<P4h&DB?Hy?%$=u*=dBIk1N8*pF<9&*lidn??>e:S8\9N/iytZh/a:y9X=jjlF?*C=
Aw#uNm Ki/@e:SYwT*4484=iqqW!@dPF=6R9aP$luaK6BJjX#?9N<?L/w6&9ulHcR$QF1C9p\X??R4=81nG%cce
%eH%e! 9wQ/&6ah@K94Etq>88qC%8Xh9SH*@E:b+aNXkZCEuQJyNh:EPZkH@Y6P=b@AaWMY*Y*:L6J/G/9j$uyL
46^tVV /%6Ic%8<&:T&<^Ci*y&8X5?L<E?H:Rj*uwVy4:4/6?Q8%+YtQ@/1+Y4a=L>hZXd%=>%9/11hA=n:QiB!
5Vq:R= GQ:q^<W#&Q:kB4ViCYHYqhQFbSGtCJtil8u>4m4!bbmPj\Bcq?F8X*!//i1ut%BY:b*y<:#8mNa1%B@B
dBV%t< >8uN?Lw+LcedCP!L#Ta<Bd+CQ/6JFea@BF?@dl>&p:6A$=NFXTJjL^hXSdSP194\l4V?hBLcJ&Y>&aC!
!/$:dV \68Vy<nQ/6P5Cy@<EH^hAInLK8J4XmFjITwBuQ:V\:4Ky8WNcd*ZV4>?Yn=E9wbNX++Z?jV$cVc6N9n*
i*6?kT 4&?5nqcl8@@yIl>@6c8tK\lIX8$a?hyPF*u>aJGZ+^9R?lC8A/4REX>DZu^ikb+kd1T@j@ZZ=>%D8Qp1
MqpV:c 4*AAGRWpKF*VWIc1jZ?Xb#ilhZK1?VtG?$e@4Me+Cl@niEX:YqYm!XeQ+j%k$>=ElpPY>XC@@iElj<5D
?bb=*b $FEW*#QKY>^$T?564h?d54n@n6Pc9bCL81bliRQG1dnlbj>NYni@H+huh?@YXXi9QkI$HMK1?4ndY!$&
Wk=6!P <Hbbd/+FJ64J6Q8:86wkh9&8?P%1Ei/H*++*8?6eyH8\C6Qu^RSP@8V!:9#b*Z9l?aP>?dThQP#?5Sl@
!^e!dZ Y*#$?4TG!&K/!aHYcw/JajVc1??KB@pG*ndl1&8BSIDSZ\Tl>VK9V#dlp\=A!4jZwZWDX=u!!iP18#Qh
FcJXiu aH:?8*6VVNCH/TiZ^eENcG*9jj1McK%*S$A4PQFNN/ti+65tQJ^iV+T4p$ywjb=N96/E&cc145jZC9DD
AA=Neb qE<8^?&<iqcEV\HeVVhlYaYD&jMd<dX>tC&a%t<@J%w9j^t!8=>9+G*VV1?JE151G!P6J#DGdAZD:ewF
bE8hd9 mM8%cAZS81TVD<9&V4aw\pH:Q?<Bj:?w\pij:Pwd<dY8X6%+qhjnb>6Q:lQ+:D==eLTBN=mDy>iphbM@
XaH1SM @AWM4+I^a8Zkk^LiL/>L/&RBiH>VVShQ=>XKNkHwl&9@@cKe*wDYd?88dIG^RGYdE<48AH\DZ^GB^<4>
IhuZ^+ K+?$c9?\RlZDTpKZbjB?ZZ%6/#Hm@c+4&8yPX+d\FY\1m^!9tqXh<j1$X1e9D#jDLMjSJ4^P=l>b<G!D
Bqa6LP IW19yNi$\?Y1tA+VCd#yVjmeNu9=M6\*%L/i1?VkwXAE#>88h!tR4Z=I@Kt/qni+^am*6Q+N$4y/k:hj
$+NYqH nY/i8H4qQN>4$N1?\S#m*ci9LXd6G/b%G4:wJ9<X$NquaN<japK<?/D8Zu%+AB:k/JNJ??E9m\>Z^cQJ
:%Ct6R =Vl5!8q@/EbjLa4JenJiVQcZw*<@K^dy8^M&ibnPkL#ul@jD:/4V?9A!@<X+<$bwZY:CS$D4QydZMRS+
!^=eCE E8188l/6*YV^DPDZBH@A\&/1!S<BN\G61&4<@tL/\bQ!qYtF<AnLD^A+kKQibQeY*^Zqh@u</iaN<jZB
yPB/Dh YQlKla=uXd%=hTT^1EAK6y>h@4Ji=NQF$YeBcV&>?:?/!j6A/?J\M8:G:%jZwHX%M9/e?jwy!P/D%daa
6/qZuV d@NZHhFjyuXT4h45Q6C/X!FjIVRDCQ@p<6Xy@ePwG*jV#cw?AX1jVHPphZZ$<\:=86jqp@H#<iVbiQL1
9DZ$I* y4V>:In=mk?H#yC9ZjXtcB$D#C!S4?P5K$ECCYdjj@WC^/Ja=KN!NMwuI/A%?&D$T>DZj>1ehyQJ+1iV
TawE/b #Yn<cDX>6Cyj*V+Caa61PqpWnQ6lSD>bWI#=JtS+Ec1CbLk6TkwB1qCHc>C/!8wc6Y5BaB?pdnEQ&<uq
QZwquc *\G+/?lcHVdGljKXL>m6mm+HwB<pmIASaZ#T9SFce+/TJ%Z%Py=tMb4$XkyjP=DlTjiV%*hTWh\9!&j>
q1V$Q% %6$dwLZRlH?Y9bdQ:\PIhykm!%/j%u+a\<q9*\C66*n+q6bdYt>y@SHT&u/&C6Qj4d+w5Kc>inDbhMXt
*HN^#R Xc!iFV@ARJjk9lcna9XiGQ$!u////Sini9L<#1@#$Yw#uZV9jRKk<$c$:9?lH6>ddIwn!tJnl<nhhn:h
-Ay>BR 000c092be4700110334 Page 192 of binaries2.zip
k%RyIP @BC$L5yX<bMqRKaK+kmp>XF?MLteV!CWYNT\hZJVYn?dV1eQXq&^1JnY49kpnPjQj^BcC$Cw:YRMkhPC
#L^Bt1 cH&@1mjd#!dh=NeaMwZXVYuh1?>QC?D4=%N5qm/B4:M\9uQ=\>C/A%GhVLyecQ&kGp??&=?$=WSy*d5S
Q!SkPl 4c5CkQc1i*B$lPula6M>iJ4Zl/5jl6b9=/6X9jy%BdSPSw?t1>ZD$cQ1\*#!@1?up<$HGE#emNaQ\tcK
J<qHZ% Yj4QAhl>lVKe6aC=9@=lcF%ktNCXdh&%bb&HFq8Q8y<YXd&1T+lR84!?Ec&V<B*6^ucjb!DDk4S@EFyH
%I@e/P *<8&R^^h<YwB<L?H@cZbu*B<%q+Hcd@lX@8Zww@mDhB/m=68cZ*dch*Wj$N<jel@5y9hBFhbh*ZhWpaM
l=jhkQ *888DDY>@SlwdZ@!<$Z:\d$\Cj@^q%l*j9m<1DdXk>tt?NXZn+19J%&>?+hZ>##Q!$Z^m$Y>8deBH\ki
NL*a56 c@4X$*\?4cy!@1Pk>VNc:h18&9pmlHH+C4:p:jTV44n@DNA@?P&<*Z@qt%\YZZ*a%hZDC4#D6$D4NGTj
e#Tjnm +h8hH\Y6?^DWlEXZXjWG$+tZ^NjyAjC%C8NJqhj6NbAmp9j<WX%Y1@<&J4=Pju?\Q**@n:MjDX<*Sd=y
6A?i&N phd&H4Ktc4QyL+C9XbmPe\Bt%<k5IuqXX$>^iWVa@j#n/dk4/!tt&Z<W6M/y^S@yYtE*jNl>hH>VVp<Z
t!6QhQ =ZTX*#9EZH6iZ+P9:eQhQ?d%J9>nVW#P@:=:PM%@*@/t?DHRiwhc@LNR=\91>6q\u*?bF^W*AdZZcPdc
y1FktA FaP!CDIbX$:<>j*/Z?C4HwE=kRh>>>B4LG9wQl/eBFica<F/@tPlXVL?m9T4w4$t#4:FmLi$*6J/T?9@
1uHKen Q%4:F99ZZ8*dXRGZlbXWHA+=YPG1!MGX6TYt45yR98b%5#hNc#XyJ>QQch*q5*BTncjVp&4/^&8luZ@+
Blil5Y +*n^&\<CZAndj!cdi9iV<cwh4:+d4*:><NGn@NX:Ji/Hp*d!<QL\W%!Siuu*D>%9X$iL*<?ut#B>iui<
18m8Ha 9:pl4hV/ekT$dw48#miZAP#\:Vwi6n$I9<MW+ATVhP?N^y6/WXSI/@dlJGVn4uy%FjyXGMFwu4VWBwQ4
+bFAC< BwyQu<AuyHZ&ZjubVYuFNd=L=C6ecL/1!wjVXXXZp?9\6j*1@WZ^ZV*CWGGXV=HYkLS&???NKI9@/u^>
Q>A^wS 9wLSZFdWByPFVVcyupIIl4R81uJ/W%w^&MtS4=@n1J?Wh/d6p?1nc/uKw\>1VNt@S\>**6RdLL&519F1
%b6nyw <>u@#5j+/hZ=?lVDpVcjHmLmBQZK:u+iFpS4lt8Td$^4X#=akJ^lh@@ZV<5=49+>8JaMV$K^KDd%BB@8
1Qm?K! 9FpXt%W&Pqm6=19X=GlWLH/!i9W?pj6nHA%EIJM9/4AycjFBt<>l<uBWp>YNcaWAwM5JFNe6Ly^81=Bj
8kn5VZ K*M!!YE\w&J!PeWH$9M&GFc?p<Y%4!:DH>e+G8^Bk5q?Euc+?KC4/9@Z*9W<6bFn+e+CpY=KdcWYdt#X
w%!E&# D5ZippMT8IYM1<c?&bYcGuM#l=$mN^R\6G+T\Wc//X?XmS9yyut9*j#cuR#hdtihXL4LXVaNF8@VW$99
j++I&H Th>:D@!S@A#A%5h/w=/lSa?k?tLME#9e\lXuH:/@Q:5*l6jNIqb?Li9hTIQBKXP>G/8GH#?C>a/+t1?D
&Hab#p eytG@/$:pk5^C#=w:KaGc+Q%t:@aw4F?\<q>Fw/X1$mXALPuFi^JnE>:h14pTmha%XpKE\b*19#APcE*
?C1T46 X%1+:+W<CWEG#5NdGjl@kdX@Li\qNIIB6pQ5T:Q4B&Rm>N6\9ST5$MQ?!AYlLetVnmdCnpN/=K:#HET%
TtpG!Z 5MyJT5?>&npC+$VpYA<BiDCta!bL$?8tt\y\RhDVCiey@SV$J8n%\*FN4QFcyyheyk!J==mMlK*Q5Gy?
VVj<ly 6lT5GcZl!F%lMquEC9yM^^QRK#kBy*Y^byK<h1Ld\X%?=Q/#wdCWB+#>ZW4KlT5bW1w!WTRh*ek5NYe/
H:EBFT #@jDVW&5X#J*mt>DjZHZlGk9<ea!5E+qu1YFaC%tB9@WSjt+/Xl\AwKIhjZ/\GHJ8+:F5JV^t#?98<wQ
!M>jCn MN%::6IwmjJqcZt9//?\Q4T5b\q%=BI*@yH&k\:A#AP=mS1YC<Hc&IkN%kd4n+pXE%KpIiV:>TFc4!68
#H>AhA Y*%>4K4D*ATE+8@dL5?\5<$>?*$iqwPK*A=hpW<?4w<+ElT1ZQDZ&^FF/Ghd\4+?nH=X!b&+V%#5G&<^
/eBVBT JbGwlSX<CReiRD!JDk#FT&lY8GDDHFmyNQdaFZWC+8FP@CS>Xc#>aMe8GlPM68QwGiae6RH9?E%$WD:Y
A#b4Ck ^PyeBqmH$R*BEZCk%\6u=tASiGLd:BR5&HmSSp^KFLQY8/yaD#$t?eu#yBmCajQ6uepHA/QE?KQ^J&HQ
YCuGaW ctEhGR1&Nw^lw#/DI\B/=T^kb5*KYMFib<eP@CQM5Y=SN+?K>9AcG:5SMepQhLW^H##Gd4J>#BaWD+%u
J1^DmH Khn19BdYm>Vpi8YytcInwIp+>YRihwn6YJQ4FS<L$\?9=G+%@?EmqTNN5ddAWBnV^@lnaWe/V@8nlDXe
jp?+6G QC4Za&NalK9bGEbDP\VJ9b\ud?8XXNJ+%K9B$VmHtRuj$4JI<8Mq!ASntBX*$n\PwB:jH\aP#ZK>GqM+
\L\wna AuM/PFp<nWJpiNLeAyHtPGAiGZ%9qPBnRc8GH#>!4y=Gn>q+\PyiJ6j@^9B@/JTpXa@YG:9yS<e/?mdq
mE>E$D >/6jA!8hV^caI1ZF<>GA8S9?nAqVL&<#Z<C?lH?Y!JC<<DT1qeBEaqXm@*:%>w%@S4mp4t\Q1X+ZXtYX
Y5aa9k MH4Nu5pHVJmM\8%KVJnCnWmWVX/K=CW$#K*4LkA4FaV4@jDE$%Na4R*yCdI%/d=#:ZNM=XK!N/G4KIlE
9a#F9W w/TbyXnI>I+Je:%bqRp#8%a9ukTm#6d*5BPqYq<AXlJZqDFPCYwMA=HjSQ4d%L/BySc^q4RGRJEymARR
MB@na1 caBGHnBlJncy!IRyBA5K+$JZiwk%6nwL\d19DPXVyK&AtGR9$1*Q*Zh<>+DLnRyaw>MWlE8+ykWVBt<a
NwuAt5 w1ddeJ9!*aw8InTJ&TBVniqy5M<Yk9Wu6$1&AppPBFN:<CI>SYqa\$nVQXbYCSFMYHKcYJ1ME@p@VBld
Q6BtBb mRu#AP91K9SbAy@pA4DC5&cp^5ClkQRZI#Di%M+mVXZb&i?ykMuI*5:pu?<^aeLkX9YX^nDMqylIS%lu
DnyFuA 6hI&LAD4VXZ&Q^Zu6P\@ANXqSj%P6Ql9tDAa@%/hCXQ$$*?KtS5G#Hk^65S>e*MP9?R4tk>FjhCdTq!N
#>dl@D nhlkddA&YB85DhaGc+P%\hykddA&YB85DhaGc+Q%!%i^5@V%&9@b%5J1R:RmFVJ+G%N9W/?S5IMFeEK<
8aGXP8 &RRyi@pF$*9?P^JBqA5A?BJY@$Jb%qaV?VGuaLPVEVe&6pp+dLqRpl*m<pJZdmL$*#4S4:Vc4D&SdRQ*
S\JKaQ \p?&nY>&dZR5nckR1<Bd:ek+<p&^\5>9W4$T>mRp:Vya\+Bc\6!%QENc<uBucKIqKhPj:hC=5uteEi8y
kbQ8KA 8^b=eCyYB>8=q68I>VLcHeT1Le>Kp9X9Xek^EpHt#b5\\QJnR^hJLd$c!=lJJqISLFa%QIGic%%mWMG^
/%m\ac e!ZQFTcI>Sn%?ncVGJtAi8$n%uNV/LYq41R=41JZJBDI!R^4H#u=wFeSh&yljT<NG:l4i+yd8e!NWWV5
q*me#@ TV6&td\wy>hYG/9\B1G:YP&J=dY6DVapNMtH5p%S4/iX>IypmX!9ZP+CX6R4q484M+aXIL!p&ha^Q1@h
/<Ww>l <Ct<pt+a/iDyi?jjDE1PaSjILkbi$FG8E6dljcdMB!#$>X#RpbFWZjW@eFNS4#QGP5H+A>A49bmcitPa
bP*+h# Suid<qJbn+e8+h@=nhIqKq\M\6l\qe1enwM<jaMEuV!KINY*beNCBZKN!INkebnA8MnLDmQZS>hce*!@
J8bVI@ YBXuCj:#\?>bRT&Sqeb1FMDK5ypp^6B8@iYGG=\4WK?<ewY^4&qLFQ#<+mkmVSeSKi##p=im/wD<h4B?
e1$d!$ 4#dm*JcQ6><dXn>*F4n\j^p*L#j1a<YDZI9ESwKH#ll^Xa%KCNM\$S=#IRiLNXXTc&G&<@kbFG:4yd?=
kqAQ11 J/ayp<H\5b\LFqYc:Ppui=w+9b1eXGLw8LWpQE<E?#X&JpV%YQLQQkEdILCDHk9WE*XA#9h51Tb>Rlqj
:6#Hk^ &XS$t<Ti$pT6MPwGpiKJ5:N:!mI%1V=Y#\KlkSButD?66G/Mph4kh6u4?NLbj\Y&=uaI@M6EW!!YBINF
$\<CE? EEBeCm9Zm1plw^#<D+Ja#^k$EyXSKRmGbJQ^<Kki%wTG>eDCPpG5+!T=1PcKCmV=GQa#W4mik:ip&mTC
KbQ*wE 1CpJVQGWeJ1TpqkQwtD9+X9uP&S!lA!aMcNVG#qNQAn&%y%Ve#Kwl%Y4FLVAD?tR4CBSb@mm&5#ZCbm9
Z%V4@M SY*@#8$9ka&GwNhIXcTeIeeLTV?CJYYt/w&a5K*ADG?DPn>1Ip=!9W:j\5CaGIabhea9cw=ly!qVc=+t
M1p9DH KW&mw14T</1pD*R6ML4@n^==HSnQc>F6WGkIJCW$T!^QJC$#!cNF9R>/XVwl!aEtjK?d>GDcJMVDn@Bc
b6KLkG Vc=1/9W8tj>5&ep1LbhK9!!YYFGpdebYFC8YIq8y&>AAuqZHE6#1QPW>*H@Y^Zel+NjViu4NqLquIei1
m!J*SF mSltG\b=8mX@%\4&F>:#@TyN4h$d/8:P5Vt\ydi%9l<dWV!wd!Z9Qu=^G/1^l^85DhaGc+P%\hykddA&
R&kYGi YB85DhaGc+P%\hykddA&YJiB>Wi/@kBRT\MEFAACAAkADqb6JY$F>i/eL\AAqqpCAC+AAABndGqqduS#
pD+!8q L*BueC>*cY+#Mm>RS%BndC>TbZM9euNla*JqbGq$e#lmcZR8at%\:J$NnB:FieejK5Kh5$j+/A6TikN9
<t<4R8 E!mRFBM\L=lW1/16mH$h5mWE1P%GNEtXBlbKD!\\J1wqb6WtZ5iJb8Mt<LKZHFqIMY$9JRpi#JyKSG&\
\+^qHc 1cDNJm/%KEtqC6XP%FwuDYhAYJw?5>@:jy\Q5PF<#HNj?#E:a?%9@5<<<?#5/>>#94H8X$Dd=TeCZIB@
KSRj8N u#<B+E4<PRFG$?Pj8V+:u>wJ?W>1>/VjeM<>&S@>yR@l4^PZYVB&1k>nZ>wC%=*:EG#&jYmh5Rji&=1A
hMjeVR $!e&\=m@B$=chSW59*+#ZLq%L&#h?5>\?k&:ai#cl/F#*5jlc:9*\jYd:+Y^uRqMVE^A=<RyPP*ZdwJL
9di89\ 4>5Di===Bp:j5l>PQ*M:uL#cla6PP\<89l1*d>5Pa#N@B^hje\AtjukAqm&jkQj=iP!Y#ZDm=&?G$haF
QHI5YH EQ^pQ%!+bT>e>bZ6<JHNn<D:L45JY1&Z+L&@<YFa@$<@k\>N*Alnq\h\!iS&PKi#G5n=&?Edn?/EbQe9
eAqa*Q +Bd?6:Bmel@M9HAAj9YT*jDB/^/G$#a<B&P:jkpj@LNHkK/:Ehd?<SjlqIp8hL:!Gy#^IRG4*@<RhP+/
d6Kmtt AJhMQ\Qj??a?PP8tLdDmXl@&99RT6Ca&\5WZ:+FQ@8p6MQdAh4BY4IWLNn<Bb/*eAP5?J&A5&k%6ek&e
b/u?q^ e>/H+c#^<&DX?4?B5</?C#:@$>jlI^?:Cqa@i^nP:t!D#pP9\!*S$>DbhSlPQ9W?&Q16l&H%Dj<C?\<e
ulumGe kFQPZA5uZ:5Dqy%^BV^/<DC$:9\bmKj*\MjYQRwZ*d+Vdy9cD1:4\6n6MZ^mPwc^Ld8A46<MZ>*^DF^/
\JcR\S &Zjl$qY:kP@Hin5d+hH9jS@P9jNH$F4dldHJL6##tchk></ZwNP=HVy@PaX@@^yYQ9aChFc?Cm69&kl4
-A9kB= 0004b638ae900110334 Page 193 of binaries2.zip
#?d8>\ L@y:8GGnD*h<<e6+4kPjuHpYd6:\GD#\D@<N\b%:+HP@@RPa@MJj\YP:uwc^==/DC!@<H@n>1#te??pj
u1k&+n ajq4+IWZZ+VjIl?F@>y*EB=<<D6\<kQ:ai!dW*DhqjjB1n@H?@:<j4nn8mhl@e<Q\^Z@ilmth#+NE@cn
1W/H=A eQZ=6<NEb!6M@PDueKI%D9#4><Hw1n?C/>i5k</uDwN%+>%\H6$An!T9Ri9!9ZDqqZ<B8@@*Fdlp^V:+
V%pJDm 9%<ekl9hP&DNb:<Nc>hHeP9ED8!*i?G$L??F%1j*\munG?DTQ*pi69:uK@CJdRKYuj>S?MDK6jD55/>B
i^1Zt\ =+:DeFG$D%b59B?89tWDnD&+F!::?D1+>j9Q\yd:u+D9Q9e<*QchGJ=+<pt+//9*\n@P9An9d*<JYt5&
JwyF=& \@J49k/6M*jATZ>+M+\>F5QFu#$A9:u&Stlh5S%c9:Md#4qc\DtVP/G%eki$*T/e88b8YQ/:i&D5Y:6k
LK8!1X ^d%Q\K<99\Itd6wB%@:HaTAj8A>Y**\@QQupaZnQGiN\$yyQ\Z5&jkE8Yue*PP98kl?@ellij@%%YL@l
99cu5E d8VhlY>9?VFehjaj\E>??8?\5u$l4QulT@DWW$?lwqZ/DWyqj@TZQ1S@GX8cSw\6PVNeDXhnl15^\>Ya
JCV<m! +Y4MeDXen=4^PT<\N*ZyedWw:=1diu^#=a\R8m%\$k*mSIS^EmYP$Q5!IL#NEy6q=c^6utM=upMC#&8S
^uI:iQ lBLCEpIm#<PTe+/nc+5>RyPIVChaK61G>hFyL>pYEV?^KBdD84tNJjE<y>/$AZeM8d1eida9TKLB8J#I
4y4%N9 lCwtFWpp/VLmMp1b\DPiJI=DLWym^dwS>cqALF$XaGF1MSX#yY9#XBAyl>miNej^CBW?dkyJyGKS/yJ6
hubA/9 n1?tycCCa$&eGuDHnm5Xwc&+=hKK1?<TT&m8KNR\ILK4#?lhV#y^NGjH\uGe\QWJC^$bKMiSWq?BtPme
hHycKF \/XnY!wtQPHaHWR5iHwyZ5E>T$w<GIT^T1Sn1B*d<hZnq4KRa?yIZa?mZwWXw%+>EpdE>XGL8qkTwtV>
eT%IX& LliMWBjX/T6PR5ijC^SnZc=R5qmIiWFZ?X+ePqkaL/T8H!daYYJB\=A/*HFmSdu4C^+Jw>bn!=X=VyeW
/1!+c& j6m&HXTTa*58eX\96Lm!w#DliEcGTYRuH5YSp*LQp^TLIue:pJ:NeMjYwB^J\yBIHwiiVZqwM?\YIlHe
6j4klY <WlmE!/qJB/YJLwCR?*ae1WCqXh\yaST=PNV:Zl^MKWmI6VQyIX:i9dnY^k\+\>NT>J5l@mBt?*S4GS/
mYYeM# DdYEn=6=#j1Z4n6&<&8MHhN=V58nKhheRV\j?dL>aKH8$l@pYDF8Kt9TJ9XYEBwZ@LdNZ+NTRnT@/&>W
Yd:RLm W9:Rk%XNch*WN<CPQ6jWRRbSqaQk5dq@T+B4X!PN81^!nSm^91Nt?6Xd+Bw\nHpaM4W=R:jIdWKtKdE\
y^E#4k 4Aq\#wKiM4CI^XIZHLHy!lQ4T!mL$<PW^DVnaAX/Z=@&!dTj:1aqMcdC:YphYip/Aw9l4Im^@K!8A5h4
Lh&dqF F8C=PMLtIlL#ciy1N#&64<kcyCaQ6YC866nt$DDyTtK:H6:ISFp+eTX!numl4YKMdEJJ=n!c#th=P4FB
:>I!&5 KTjE<4wJmSPZp/V4id=AywEKmJknVq9m>Y=MXam%Ed#au1P/!qAZTD8PJSlQ8kF9P*VP/#yaY5amelJH
lQ?w^= pWDQaF6P\LpIplc&Fea!%A*ce=#bB8kC8VKF5WwW+8&pNmhC##J=!6Z&lS?4\Et=8pEcD8M$$:N!4kku
$*XS+? VC?qdpBXJpLqM?XSq\YBnuTbc@6&GGM+VBZDD6ET6p\n+TT^R$Kqw6V^8EDIqw5cXXGCeAtdI$pawI<I
6B!K$R BE8D1a!4\^VPpe\ecKFe=@VeBTYp<:YM&E=55$SujKWZ8Hm9A/%Zl&mC=FWy1T>=wXe:FJH9&1+qdV5d
kHi@la l*$Xi+quCeeJhS+m+h^#yBPHlCmi/E!\T4q+Z1R+hV*jEwpqZY^cb^/ymmlQBIq5hBVTqw/d8acCK*eN
QjTJh! #DjA%hNeLXjujX!dwc+eHNW<q<tRl6^SiE?b+4GRPl&B4K!TK\>n\S^EFMSCbLFYIGTC46LtMkq5L*b>
YTe8Gl =Ii8F@hhK>FXamQcSTR^n65KXc$m*^heI5pp<lYnnIjWedFN:F&lq$?R\$A1dp51yHu!?$d<eD1:TSAe
W^lP>? a^+n*MiIJ?aew=eABciVk^\L/Wh9WnwJ8tihVpAJ/^E9R8<1@DAKMm$FT5WwN<6^cIThlKP9>Rt*4MV^
hu&kJL MR^C8pS1\hLR6nXhdC#S#?peDKtelDLL\9=AE?\pHQ<lAjc\ZK<^q:kh=GP:5RZFVh/eM?l?^c!iY*I$
QW+bT# VbwkYJ=%BweELuyd=maJThD==u+an?TlDi?9XIy<\%GDY8SbW5L9jb\Vt6uPt=4u^AQVD!#Q<DYkS!^*
EidF+% ld/9=$iY^p@%hCXQE<hYqmkidL!Ib1%BDhJp!JYB!T$ip#!mMeQX&HHHNbJt<4np8MdTXTb<YZJe==ST
IeY<kh byK^=Ll/mDW^6*KJedY$Y5$c\cZGqacINVR*e1q^%W=atjWyT+&44dGcwGtyeW*XmtdY>C+y4kXYyX4t
=d6R4l Xl/9ZIPIT/@6PXGScKh6XSp#>@I+=E4=uEn^&a\PWC8cYc=\@HFqny9B<?4JR1pcbkS:uHHqPhRtXiI$
T*a@R\ 5Tw:%ZZL!8RhF#1ZcK*!$YtW:yb4!\Qip1*c9yZ6X:9FG\T69Hm=pLSX?:hp6jBtG:HlPt<B9=6#E&^I
EGwDSE !FSaTqS+?6&yX+8uAH:d>t^QFC5lcGK*QV6W$&WqdmlCwc!!4/V:SW6M=S&CKphZ/=aFcV%^&ec4<LLm
:tLAM? 1qh%p/+!ZPeXc$HNc#/Ge@1\1qS%5SK8ED*ya1+cc^4mAli^$\W!WdtjNBNZ4E^+eCY\*t1idNW#q+Ni
bDccB5 P+kM%@t+qtPwHHK<bnKZaBTEw6TXa/P=bXDFQh\NT>qqC%Dn<lqjD>eKPAqFHC89m8Q1ZG&BA1&<mW#d
XYZjAe EId4QKedYy\jc*/ujeZ</qq5yBKPbyW!5!Z8q4RK4pjW1$aeKY5IX=5^Xy*VVW48G/=H=Cy/5LLeNa5G
I&?b^6 %%^N$4Z6t8KaST&Lqq!q*m5b#NpBG1@$/kcBH=R4$Yy/SiTX8:Y5YCX?YY9w?Yl^<dctdyJc%HA>E6jR
b:W$6K H/nYSC<I4qq^&?$cDT9W\/%dP5pE^$ulXt<4/%FVmFKqVPnV=eySJ1wZ1Ynwq1leQaTLa5G@4kX64tnX
ycYNF^ T*ib+VyQMK\GQK*J5iy*^+N?Q>!Z$cCW#4P9>?k<^i8utljS^u:>Kp4w8*:6/d^eA*hA\mF*\yu9qH%^
u<y5MV p:FF#=YJAdkKmYamy5IpuI+*4ypY?=bC^KIPMiuJT<^n!<#hZk^etiwbZJjyn:ZWmk%4!>VK9EX@B?nn
KVwYnt GMS^$H#4k5bwC%y*dGFB<#d/WiAc1>/XEFT/TwSTB:p&4Ta!niE%54%&!h##&qYYKpw!q!%594*wPXtK
tuRyH! M9?aH+cZFq=AX%N:Haj!MC8bqBM8H$6WcR1TiNWH=F1i*ddj:S?NPa!4=jcK$A4LcYyk>iJHC$4=$6wp
qEah>+ !i@*%$Xj+W$H*1/t\MS6lNhym61Y5n:c^@YGeM=c!=$p6et$+hynZq?M/\&Mn/LG+=!WqclQj9MipKYV
/8:JmY QSbdAT9iW$%:nw#mjFhWq&chyi^RI8<Ljqm%H6hLbE%F6VQCMq\Heh&tipjZ/eEDcTt/8NwqjZy6DRma
tEL$j6 +/cdn&8%!Ny&y4?pK8MQ$G8h1#5k:&t+N4%4PABkM@B%GuJ6eE*uRH/X6yID+nK4y*/ib/^1#Q$ca/@$
JFK1nA #$Q%!yXbyn/W1>&jR1yqIP1Q4QNBX@kXHhE*99Ic?TdZY8SV=blyw*FbW&bWL4kbyqi4TIWb49%eiW?E
e#?T<a M%!9RR@1Q4%c^ad\B*C6jiIqqkqFhwDy1Ftyd6ZHmmnIK9>SR@Tc9u%kG/!D8e+NiD#uD^^jba?8B?w%
Pd9M6d GBmkN9Y11*ie4IQkH=8ZelV%m<9uC$Q$Ku9>miFKB5^hmn9p!<H^5JWQ44VB6Zh<bd%B$:J?494CkGZ4
E/E>88 pQE/GST6Y+&l8aVe%G5^#\qMuuwi4p=9!neYiI>y$y@iu/5uFwdG\/%!in6e4+:8D*+/C5eyw/KqJ14!
LyjlLl Jc<iQ!\!4uNt=nwQX>H#mEbQIQZN%FtjpQiuGwPiWbn&/LYAuZlw?qN@wu/8YY=T/I6qPm#dhajL/\Gh
R>l%Xy P>RQ<+Yp1h?%ZQ&i6cNbwmqJQ>m=th%Ny+1N#$@mhe/FZtYtch45L1^P^51PJ91*udd4=A/>1Xi:whi!
G*8JKZ R/XhKE+:yHt1NI^4LjLXYQKMIm4XGyTVckcj9Pc>G*4XI6NJ@4nMGdF/cwyq\!tY6HQE9B=$6iy?&C/=
p9Hic6 Sk&>5uRAMS?tN+^41:t&^XaDbn$q\>D1Q?d$/LW^w$tKkKnll=QMkcK4ED#dDA4?nZldNiIt&iPHhW<!
NGtp6% e>hlZB6Lk:uh8!/6PdnTAc#h&nn6><a+ZnEE%tqdlZ9FT$VYEm&+ldYtcWp#4dNc<bT4N^1R@#BeG=tj
u4S4l= Qp5G1u1kD?hXS6p9$QnXCBu&^eP5$GSTnd>&nmmyVbtDeqTNt^P5?9#XjIVJG?Hc<=?lFIQ\IK:C4ZIY
<qKQBd XuGWXa1VjX^q$Sq+FYA:15\?qWE8L@Yw8RyQhdPZN19uhJ==i*+a%+GL9u9mEVtah8be8dKDQKWuTyli
+V5+%! tjMwu1QZ+1c=a6AN1pyb*tkchjM1AGiqepYkQZ&/cqWWZNNYDhkn^ePDF/Xb^cDd8&A<eFI5KBw9eY5B
T>?Et< D!>XcthXYWGRyj!CIJkP+11HlKWn%WFRCmk1u/et=bPBIJ5Vq&FcFS$HbkuhEK:^pRdZ8HnF4ujBiH=q
4Bmp5Z >mT<:^t1a=Ha!<H$?*1:K5nLphkyuWMaEW8YkQPECE&D>TTjWpW%X^Ia4u%ecV@Y?mVXKyp+hGCQEFYb
dk/k!a !mFK$Zn$=\%=8!jLE=h^iS+9SYHb9/^cLK=#HX:Y=&1#Yb4tyM^/mju!\@%a>iK%:Ka/@Y<&ye5L+^TL
y#L8Ib L=NE%p9RmP9QnM<QYZGe/m1KC!8c!K@Qc!6:DHi<SDK@9/Ek@iV^iybm+a5e*&Xe?^^^!aeYa&<w*@L$
qGhI6t 9=F9iw6G#h1ZBZD6>bLFFCZcqnyVP?FHa@lmA/bJd>1E+dwA4ydwj%?bYI^L#tL@cPZy&IBy$y5&w>iF
pwM$a1 eG$I>qnq=a/tZw$jZlDZi8Apn6YL*=b*FQ&\NF!Q#FY?HXlJ?4:iWZ9++u8G/^9JN^*Vt$YQ=qIpcdkP
&eLeC< =:15J#%5%wA6Fd%Ya&9wtQ>wi<q\#b&\<KV=DQAq^JYuTJql84T+Sku##j1kyb8ZMGc+GnNenSt8^k^Z
jiF=W& a?<eX@P^ZG<*X&X5!bul86lw9Eu4yN?FGc/LnG9/k%?h!Z\D!l>In<CIGmuPXKZ%\iKC:KDl84m+ctl6
W+u4+! JJZT%H5b^\^t^c/hpc6KX+j#wwd4w8LcHpW\1qCy*8mWMG6eS#J!#hL=6n=w8C=PQ\!y<p1Z1:j$?TF?
:RnyB+ GEd1#I$jZpJ^W>MMX#QQMjaP/*ZW/HWJel%Ft\j#1PF/QHL6nG@FL>\au^qQEa:Q#KT:I%NVI:k^n96=
5@kAEF TZ*CeD%P8G/c%ihuAh#bhpiDuXS1K*VeYVTFM=9^j=8hHW>Lnmk%bdk8h1/=i^%^W/:1eikmX*$EeiI9
ZpPDkm SN%8c:A+L%In&qYQak?aMX\ZLhjqM?lcZ<bjD?5@^a6\B$8>Ip\6#VcK6LNJ1jGbYhYi$Vc4XY&+LnK8
T&<SbL l^=j6i4k!C?%l%Yyn>ZjXaFXKheeGp\lV:%>TKe6WLCyV>b8&HBhbF\::STN1=HN%p!Xi5*>eC4L#1FP
-AwtCE 000d220b39700110334 Page 194 of binaries2.zip
&DcY6A Q1VPntn^=pWQGc/Lni81d5y\X5899YqTe&yQdc4AQw=/ub&c$whWF9?P#$#y9nC8Md1H^5i^4JuuLD18
u@Fm^+ n:5bRw^6D&IM%BpjGeHRcXQJXa?98a*W+!q$9hwSc^&uJ\#Z^eZ%aLhAPNLbNDp!jtl$hK1:1dN%6l^j
tE4c&I 5eBpG&QkqN?t>PD5=I!PyGd$KL5yt?+a4w9MD:5F%%!XdiR+8&q$bLaYN&tIP1/CeV#THluQ%$q$>D\&
/PVNaW D/5M%$W=9ncDy6q$8M$D=mIi%4H\TQwkV/ia$4B+E+:L5/qLNq\Z/jnc=D1X^pe9#:\<CwXiwa&^$kk/
8A<#Te *hF$Y<hKMDc4*D!eMq\ZuS@P5Kdy+PK4uwBC<CNwitRFDH:dM+jGy&d@u:%48ZIeX:LeaXMi^CKekB66
RIc$TB CFc$aB#kGRiTB^ckH:dQDjk^C:=c#HqdVN\IkFR1Xj%155TW1kY$Y5YjWqSeBn:^8YFa@%5@Pi#?##l9
@kFkkQ Cu$/@KMY>4X5X1XX\<Z*j?5=48mG9R!+A>eu5#jJjQbj@/#@>YMH\I\L99?4@nMj:wD\**a8K<LEd8D/
5=RI?/ dLlPH8&9+wV>8!6<hq6?h%cG+9<b8D+h4mP?ciA/eQ$:6i@jj@IJGcJ/u5dP>W%*5ct9jkX@Q\=@QG<j
@8uCmV G:k?X*MZAM*jL+//Y%jeQK<jG:k?G/:HJl?d:<C<ki9qRS:><P@aD>@Y%>EQ9<:Mipll+D4c\HY$ki6w
>h&GFy A>jSB1+D%>EG41MNZEed8I+&eB*6HF#uMKV*><M%4w+!@9FdhY/tKu?FT1*hEVnX+nQllL!KuN=wG>J?
%I14:S iq\DQyRn$F#b8YK+<mY8FC9lSFFwy%JyH8J?hq!n/Gw6G=Q/?^#j$FiBWW@ac/wZL9*SulZZllH:Yli*
4/!L8J ><NRTPeJHjREqQYE1T^\Zac+j^NeyciNQqk@9JWy6DM8h*$6*4pyan@LlWQeV#??itk41IJeEQlC4C++
a^Sj<N HV<ZJTpSZGPwZEKMV1/S:&FZl4Tjj#/<Wati8@L!Mhh%=J#ZChZ::^tm@n*Y4#IL:9$1m&ait5!Mqi&%
R#*4GF ek=q@X*5E1MNZEed8I+&eB*6K*BqH9L<uZGhTj?JK#qjmh^pF5Tecct<p61Z8tFC#95*YSZJ$5j&@@+N
P=6cCu 9%:Y/=E!^LQId=anejYcHBYyJ4Y+E1p=HZ6w848RZW@LR*Bq\%X8JD9&6W^tRb\ctB85\6&RGKQ<qHL5
n/BhP\ 9\C8iP!#\<?X>+Vj*P#ndJ8KK!T^Hdk88m5j$i9Va@T%NH*%Vl%^6iq4$jw8PH&y4#H:mB>B</9w1/lp
nw5J?N YXW<HXiSmIh*^FR*1VBeT/5!DG&Z+pN^bdDJ9>ZAe*aN\nc!C1/lqn\j?8pwBuab&9$1?5yVBn%ctM8B
qJcGE/ c@CFN*jkYnd*B/9kp@VAWVR:5w4^pdkC68Lq8b^*jb$:4m:#G8ey/5k4t+W+d>YZ&Qbjau!NZ6XY^MPJ
p+P:KT uT>ddk+TD*tqSVcL=>#%Njk\a#ja>Zl:nL/8NywYF&8ITL&p$uG6$SWbSPAPmC#u>cIcwKm&@^L#ykWn
/IH/=b FZ==VLF%8JBIaSeeQCRFInFlRDhFjNk6Q59%bbc*^?A1k<Z:1JcnH:+ekF?$+hh9c>6JX&MQZ+>E!dt6
CHu+^E m$9uVVE?1l?Y=?=11h4*!6Z?c#d<?4I:t#ueFNY?Z@m>V+V9+1ai>1blq^l6+D4cK?EcKR/S@</+@6AF
aeBD<5 +E?j5V#FqQlu=n/llGjChTIa<c8nuLNVY:c<qlYG@Y=Rkkp6p@^D#q5Mt%eZ\XdDhKLwbj&F8FjeZnjc
H$<61G /Q*RHAl*pm\WX8+jhl$/LVRup9#<cucq+I>9JlKlmN\&BF@ZVE:?\%Z1K:H:^qZ#QY:6E:nK@?8Mj@#e
wuD+1H ea*httm++lKu?&TyAL1q68?e#<N%9=X<lT5M%K+:W5#mu8yyR+LtR1myX#D/hu##jlNi+?hJ5h%9c9iN
tKHN$K &P5^8McM^\$bHCbMNi!Z41<8&*X1?b/yd&uTS#m^I?ckBtquh*YBK+5tL:8DVP&$cdiq*F>hadLl^d:8
nWCF6L +y6FERW<qX9XJJnc4MWJG:5I/T+bL=@DFdpbd?#Ln15k/h><$%i>Sby1tLuy1&:lZ%?*W&hPw1?bb**k
@4bIXb DFik9MdK<//9t&Pi#8!H8+HJP6@nt$YFC?SYXF<J=6bXV/t9SEZI%kp@XF>#>G<8qd\YijS<mi68&P<J
PNW<mh G&d=Xu*X4ap*b<dqM:6mH$YRPSe%u48NSYW+VEZpq4JI$4Fc*NN=cYA:4nD%6&>YW#@NktQiSG=hZ*FX
maF>%1 b4qJpb9iN%H^id=Db5VueMXN1aFji?J4\::%6hp5*=c/w#d\Ked\n4H#HJt1>=1eG5?6H!=&j+=L=GkY
1S&#iD >^Q%6ihCJDd:Q4=bVj%FB@>wmR@YY#9eqB*cSSn8pSu^CX!q%/Z@NCEW>Y*Qw?Xe:W@E!c*4mmM66dun
ZY4CQ+ ?1GhPS>&^FGu*B@ZQ^iC!>8SMjEM/=\QS9>dM^l*pPj!X<d/l@/%^Vd%:hd6qnQZ8pX#Iey@YGDHI&Nm
e+58tB &BFHG:kPZEed8H/mdjTeKe*SJ@<Wnwn:^@N>nd/Y@JT+b5i4@@J9DiY=eeZubnXpb:YC6V\A=!:CVP9m
Q**4jE 5iCJb#\:MctAHNaVPcXe&ciea9Byp:W4yRq9^R\EKj^D:nV=VLBZJCiZ8qVmNPYpYn6#84@m9uqh#YJ^
/&C6YB p\/u!EI\kCFQkmJ5T*KZ:D!6jI?\yu9lc16Vd%WpT5P%HF+A5<LLY8$Ec$RL^\T8L5YaHHuPmYWd:%Ne
*8p*Sq WpnbDD@PS/Kcey!IBYw=pIw<AuLAy!4HDP/:N^mCVS^y#&KBSESk5Ck1&HCJ5KNtKu+mjh*kmNJd=wa4
=Rde4k H?H?bwY9@k^#j$qbdVp\9lL?V$/PCc=+J#JE:b&!p\N=E4%w?ywwR&Qq$+\@+#mh5MwGN<:E@E=j%Z:w
H/^?b@ aq$*q*d*De/py<HX1iYJ*<#Pd9GuLq!+uL:BC5?i+%bQtDq^Ytu!$NYc=dH^&:Sy9G/15&mn4?^C^#WX
pJJb15 Eq!nK==t8V#B49e6/TeXX=F?P1FHpcibLR96\LYd8bnni%!uy<G%MK8JQVb>uhibeje<@cul@4PHR$A8
G#nun+ pj:wBQKtKJwZwb>iPqj95WY?/i6eEp*Vp6SRq?Vyt\nn1/l$pe5FV%SKbb4pA%Zi>ZC/Q:Abu6>bFEC#
QA4P6C HZV8*i*>*5tpA\jqFYTe&N!Vnc>16d:wl<5e+4!H?=5q9tyi\N*%Xd9SAyclwDc=KBMp&bi>wGb$GW:S
nt4u*i VTT@XQJ/y:mTt/Mm/PDun5MuVP&!q#8J=SBHhb9%\&BH&5*<ZJ!:4$jpF*F6KbQ%/Ihn@KwXaWpyyZ^>
NJXkN8 :N$\cVESTjS#TR@JRjAjF*npm46>L@Re8KwE&!#T:P*TMSePZ&cDKQJ6N&@1\*XaNQIneL$X9B>@qKbW
dMi!&n ukQZ$X:hnnnc\HY$ki6wA>iB/$?&tYS>GGBaIyljYR>k1k:4GY&NhWKD/?PWX*+SkYL%lhA1>pq@8c!9
=lEG\S %BMBi+t>YF$T!hX@EB\V<Ed+MCWeeZJ=ME9u\*A6eqeI>waFi:J\&Pw:5*S6F8JFTVQAAQR18HJ!bb6K
FTk!QY ucnRFMC&9VXQSMiXaIPD*XJhEicNKLIL1@WTjjNMQA^ZykB#@qVZdM^eQFum!aG4Sc=QMF:R1^DX\4yb
AHR!Z@ 9aPByKluRV$VDL%58Cd+RpLD%eEd5hLe9E!+?PH/C5alWXWPSVE5bQHM/5MyDXjypTd+IhjZ$XiBWmTS
$J<NiV qDSE*q$$D>PP/$RP*wcP1*wnm8IcW/mdb@XMQFBjpdi^Ve&C9ecbt1M8K:Y$HX5=L&Chiyq?YB&=eAwt
weTe%l pp=YjR4tmaBZanIHqB!6Te=pGX9l4WkLJYAe9D<<E\@D%c@\SE*hkl$^$F/peW\+Xy9^Q:=M<S!&D4md
HJMm/% C?EWMW>Eea!*$KmQuCa*Jbqd+5I5#\BC46HSNe@E\*Ch%E%<jJ4@%@:Xj9mc+j>q^qj%S9!$Bd<uc#Lh
J+I<9n aW!>$@yXpdwM\tyhdYBNCdlm4*tbqiM6d<VQjVA<B//nDZ9VcAQZ$S/L/=5jlRV@u94/Q5n\\jV?IA=X
+9=!CM M&bEwFD5teI+w+h6#SHm^hdAhX@dkIh?c5\$%Z<Dyep&Ni*h1BP8EC$WG%jC:M#&V$b\d=/AE^w=#SQP
98&5Dd 49lNA+8Cn?1H5DXY1m+Zmly?*deG4u$1Vtb^WBb@YJ!W>F#@AMB!8XYSJJDhtHtam65LlTIeNd1VcG^l
@AqIcE ?akkeK:8V@tYXS<m:teEVa&#W%#:%5C%6dul1m#?$8QqF6HePTYweVmbK<D$XYPLJ?+E>:Zpe*LatqcC
b#5mmy *<4XLF?q$jdqPAQGhXJe?>dA>Wyj\W^D%aPi^l&B^M&AA6/P&X\BTD/b>bLktdM!K/$^<It+S9V&CLSj
11<Wy9 ac&&y\$6:jSZjT8>DX!9>BW5@5XI%u^WW&Ku:^E>AGjNu^4MZu\8Q4nJCP/LE6#HDML@p@ylkVJk@Nce
P$Embu IJcB*X$k#yuI/6jwX1H#YD6?8*qV\>ZM&a!yJn84K/E?PkJuuWZ=>&B&GY?ZuiAi\jnqJJb@wJjhZ@ZR
lj$dq= :Sip?kL6e@*\%h@R^aTQ$NRd:HSjXF^q$aIq6=y!$:S^kyhKA>iQC19wZ1P6:$G=jY=$dV#119>thwuS
Ne$<6n B1/nDX^HG:mPhuhed^u/!=e9>yXtMLS1abm/SX6X&b9Plh$ibDT:!44n&8H/%dZX?G8tpd?A/%HH%+lC
@y#ka/ /t:<@$D5j/IJkBIS&GBYBQplSwkuSDE4?+@QGnTEwEAEi$aN+mWjESG+>5Mu4MK\aEdR<Gy<J8D^:!\@
VYGy=9 6DtSYq\#BMR\cDdGeLp>$wQ%Lk95Z<6Zu+!A8*Se8@H@QdF@ebdkee4nD^t8BM+j%yl=\W%ZZRkj5$Be
jN*XMI :pG<4EG<IpqBQuDyl$@BNjnDeMpHc+m!EK!5JbFBC8>1*ZHXR5D#+*H6hZ!bP1:h?H>N:B@#mZS%:HLK
YMDWGX Fw&N1N#emJm!b^k+FXe&BT+hX<Ze>eMu+D4L$=!M6*<u>DG1l1BQj^iRquDa>SWH!?N^4R*Z&P4+:wZZ
^E4YNy 4+u>6dd9ij%\I4hHa\6iuaR?BbA:yMqJ^^!SJAM!LmhHKbA9iRw+uQMbjF^W%A!69Q&N$Ch&5=9LE@\m
VG8JTc JmAbNMKP1^:pJ<FX/@m!M6pe^9<4au?4:Z6P$^D5EyR9bNy1Y6cy#W8tDbCqDP%IJJ1cE/l?uGk1E@k8
D*i>p> ehmqM@lE1E^cihq+?+*Ry=kQaqKT>!+k=w$$j<QFZmi=mjLS8M1ep/5S?>St@Q>A:H?c1X@H$R#t9Bup
u>HiqF YycHSp$5Pd&Vn*Y+SdNmQl!?N//4<1e%Ku@M%=5:^A#5bBKBB%5>q?^+#\M\W1Au\QZ>t5PM@:Z>lK>a
nd%Y1W GaP%Wk5%WC:1@k&$6P>@N>P%tX8p1>XbPCMQRS?6hD%D%mchY%=&AV&4ZiKDWMKnmQ&j18u5/N&QQ=+q
/KTeh< h@Sh@LT+nnd5mKMNZEed8Q+&LV$@4n\QtQ/G8MbX%5:Bb?huB@:?/NeF>yRY@pRp8:JPZLqPG&$:#V?>
#<nNkX $Q#a<9M:Bd#F6=K6\DSiQj$S%M!@4HcNikL8bWV<LK+>*N6S!M&a1JVl<^:YS8BJ^k4Y&LCN=9?$m19Q
Y&64%d mG8=\JWNX/NSWX#>bQKVe@&cP^4>Q+54+::uhX6pqi?<twjXeuKEK:wFIC4mPGM$@!?q4@wM##885@4n
ZqC=X^ iuqeq/q\R5XjKu?a99y9>#Q/@<K<mdSIKMEHXllX#b&Y=>R@/h#tk#L<AFieMb4@q<LXI!k>Nty@4YX^
$mLpHA +ByEQLQKD^YhX%\V=nuj#in@K:nPaawLBSql%$1waP6<6PLyE<PhaR\@W++J/ayK<$>4jCq>#e$lAq\L
-AdqQ\ 0001753a81400110334 Page 195 of binaries2.zip
uCqn=S Yb%j^XWRy^l<hDtRR?aTnQ:qjpd@Z<GXLd$$:LH<lYMuYnN%l5F5R6RJb5>Y6QcFeC%YPkiT$a!l1Qb>
akkNYC uViBIKuJ4@k6/nX*Nj4@Yn@<\#@yNBlt^:nG%+H#pM<t1lhcyTmM4+eVRl*/ZZ:TD=>m@9<54u<^6RZL
N#5X## @:/N6@Pe/5@d8KkR&GRqEnlpeF%4tJ<J%>Gi8\%eB//nDX^HG:ni5SW%%AYn<>E%R\6:eW4*M&PqMd5+
8X>*I/ eQ&LBq+P@/dB*^adP&qtMe*1EWAY8^w@I=pL+E8cR#^#$1C=bG8JF6/bNQy#bZD@qDM#4X&uQnC:jnJ4
NAa^Q: PqFR?mM%L^b+S5\NR1&i4+1\YJHp#h&BM8hZeIXj\t9M@%G8&Rjb?\cLNuChqjMjSZ&@1BC*#%^h#4Ze
$jwNaS \uZP1C?Ikw:qC*A%8::mm5*N:ZpQ*AYF<kh%&/?^$4=4jAJe%RS5qC<YQi^b\QSd\:Ww=#>q>$XeBLDN
DaE$Et !dQ9G/:\qdtqII^MbchAG#uM&dnP1MK+Gc=#j<DmyupQC1:inWtt+!y+=%aptS?JK/tqe>hZGDw#ha?A
\GZB6& /Y6bjWB=i9/cRV#ChP+4ZjdDlC4eFSZZm+y&>!iilK8=4qByld8?wy<A#S@F<Hal1Fn#N$lG5Veq=XBY
<!:ekk j4T?blp?+#G?#t6lbX^Vn$BFmbGkuQ@5=:^<Cc/wd!$c8^qh*8:6^F=GVq9GeJbQHi*hBp5VpSMymDSR
qN\Bek PTYIbKCapT^&8DSB4ZH&PKLZwLS94y5YThdNl?GK\WFRe?@/acXbW&iAA<iQej/H4=1Bi1/LN&a\<%Y*
S*wi=D 85I1yc@J#LX?PP19NmtW1n/RM9i<B?%pW:5t6t8c&!Rit+@5l$YIhNpQW*:9EiC9JhWl?$bG<YY1C?6k
t$S@pI StRQ@@Iqe*L6l&?Fj^*in\JBdiji^m@kG4Tem5\68XH=KK*@qStd/+8%\GY?!hS@pcj?/SIA\>+$:E$D
YGnjK< %+H4#\%!NMV/$/$pG4niG4W5FG\PaNZWCYnBcphDT*TtWq^6YckI#bEJ/B5dJ\^@MTjMD\Je!8TiA>hi
MXyECi +BT%TyH8:>1tT#XRtyBaVFde%BQim$>?661Z1HJ/*=cX&WXLdLJLj6JKj8AnWAaV@LI4VynGMTF4!?V>
XiNw*T #kq#<81ce=4pK:WPdI#V6E$Xbik+wnl5Yy<DX!%\t4kpYYi:t4$HF\CKT!dbESpXphRm:#D*K@tK4MdJ
&EG:6L cq?Yi=Q1kAKtVp:@hAHLT/q:ueajeeKWk^Pt<HteMP?Y%ST*lIKD1ANLu6jWu$T8#y@BeQEJZK*AcRaQ
hiu5ZH B/4RSiXAem1h>A&1R>Vi>XWTVC&t4=#8uNinmDCdqBVFewG4QGiqeeKWL?iEiTe^MQmp>qnFqMq\^SNY
F&ZbpM %+Zep?l4XLIyASQS\dBha^QENu+VHaup=Z*HqYHBt/!t1dJ:*B*Zc9%\wSZMQtqqqD#PJ6C\d5wJ<#dq
GQhl>G e5EJR#:w%RGH#?GE?ZCZ4X:wH?#tuK\jX1Dn9WKGj*q<bb$dVVKMqm#n1k@a6L1%1G>Kj9YiMZJNi\qW
l>?R5$ 1&qK>=:<ch@l:JGbniWq=YtTL:Iu!NmeH5IJe^9ZPWuj4?Xj*b!eu^d4Ry=DZ%8BW%BJcLuTaJ8kwhL\
B9AP*u d^R/qeqwhJ&qMLccynuh&\$:WZFK5^diB%T*kZ^:HCjM>T^A8u!ncDRl+a+bBIA&lZ?T?jC6B@\uyMN*
J1EKq& #/lnuaFZmqh@8qu!H5kJ<%+$SFhVS88H#?5uQ4F?@aF%M:\1?<9Q4dK9SCaQ*1u!GudEaWeediA/&5B%
bCiyDe 6IH4cAQZki6wA>jSB1/nDX^HG:mPNuAh8I+&eB%6+D4c\HY$ki6w4+B4@M*VS#d!:uG+B5TkkVcu8BBL
:CluMl =H+AIWM#$8&XT!h1acAb@$VHWXq&*Mq^M9#p8N/1ku\yYNjK\D$G%^tBydGt5JaqkV!/X#F%Ylt8pHLy
Ne#pw1 IJY>Ewmp\c5LVkCZ\dJ\9&bBey%EBW\I:I*jYI9qWqS/ChAPKiG/9V#F#6TmL=VenZ4knk#5:<GenPMI
W+1&%: BQ+L:dRS?Cwq@ZE?h#+J8d5:<mQ<j*GXG@A^%<R?YKd@DQwXFVG9T=^J8ZTC=^K>p6dHcnW#/*%#uK>\
hcl#4R SYYE1hHm/tNt6CEwK:#n&wwMHLliqN\6J?G16WC6Kt/=!PSQ!8IRqX^qMq\DN59DeI$p1ILCJCIdRi/$
XKt4:k VFc#F!#?9Iy!/4&l*LS49$Wq4$y$B1=MnYphK1hMIXX9KLX9N@ap9JRlIF#1/%F!q$@E6Y/^6ywIF*hQ
^B@%*N Y6H*wQnBqjR+ZBpK1ipdK4wFIdwNX>FkH$t=hAS%DBc$:P^WNFh*#/!%yN^88:+ck*/%M8:B9>*CNicC
%p9@Vk IkQ^\NXK:y/y4#4wh@I1/6qJMWGG6X=T@IB%liaH>5NcwXpGVQJLya#uVAhPMBLXJXPn$bu\m\k5SXac
Y44PwS u9N>$&IV+A9Pq!**mliV/*HYMkVkICFV^\wQTC<V=ct#IkQHAT8=P%P<I:Q?^$u/nt6ZS%>pJ1L%D$^j
XKF*Y9 qhhHNPKB@ZBJIDL^/Z%Qk=6HRH9aE\G&I>Li/PH8*HVt\X4hBW^D+P1IB#8P!*I\5w6k$GHX&M:qFDqi
ETbMjN Hkl/&V&b>V@1c=@thq#^:a9XQ%A/VytL/M\#^9DAj6lI#I+D:uL=tN$X*HdF@bek!dq6:cS%wLR<J65A
:&pY9n P:uuYQWwyW?ZTeNX=%H?bDcy*>W8aeppXntkGIQ?=cu!LFpq8JZ>AY<4Xc:u%#\ah5SlS@\Jc>Ryk>S@
5CNM:/ GBueRQF5ZM9Jth?*tp9@%>:bHDeP\%AaN^dBA=6AW#!=D*Y\GqcALG6lJ&=Bm\jR?hpwJ$8nnAe+PLGH
l&qBaY GTF+BpSR+1iZEcQLaS8Eu>QXh@>bqqaD/Rk&Mj@BVth:ulQaP!e1*bJ9GNbncNbm/6Re<YMM==w\!aX9
@p6?D5 q6LF>%<Dd\yR9G<\44:6ip9qF<mKJ%>J?\&/?tbh\$d\P&+ADA@d6:8!h4F$Gl8yEtYttmT#MVuRID9m
kWD/8m B#\EkWhpIByHauRGEkGpwY/AGI#TQ?<CYMKBwJ1YlWEZIEGZL\\aDwke?lcSceTGq@A><+!8pdyH#Mek
uaKkXX c=iuIXlH/A19t6V6dukR9AL?wuHeTnpS$tYhFckN%jA$Fw1@lwJlw$pSCFIYW?&*AZ?Bh^yV<Cc\=NM$
!*:JmV uRXLQ$*KedwY/cMStEeD&JjiKCM?m&F#NAP!j#=%VaTt4HnEjA#AMZc^=EyhBYeE^Abu8TVIZL#m&=e6
$an#QQ q1jC%$b!&JdlcZA=cTJ?58qcqm\YW*nYLHyG\eDVFQD:wH!*mBa=EC\F5NBESBuSK8G:NVcHH?qS*!dt
IFFPbK ^*W6Y8CI6^p^B!Sy!=88%4X4NY91uH1eG9idj4C8Vjwd$D>Il<!u#bC4bmFYi@ZIA1/KX4FlZKFHVNi^
p$uwy^ =tbktC46#qd\YEBka/euNSXBT*WtwIAP<6QEpai8LR*PN^SZBn=En@4A@M^Kt#8+anjDIQtaVLc5\qjZ
+ZJ@?H aePwpdH$/yA:5idAZaD%F*kwy:WlN5hAjXme+yh^PVWD<VQ#qaYL=/8GD*mSS6Tqw41R=SBIQ^k%WJ4H
yJhCpW ed4Pu$+?5qtHXwR%k?%#G+:=MRTT@^Q1wYPRl8FFCp::F=>jKcj?udZ%Gd>%=9qXI/a!QW1!j>d?t\JN
jBD158 Z@V:Xd>$Sch%&qakqw:%==E?IEj/ynmNcDmh<*E^RBZhJkaJa\!eyKP8%hZ8VQk?hjnE*CpuNlAL!j9S
=G9l@n =>%NT>1?\4wj9p\Y@Q6hWMenl#/cWM#Q>/9dDuC8:^i$c*WN&??1>&9BL69ul+Z5b@MlhI%%^LDRNT^$
EnX=hP DR6h\$LZ$DW5hA$LZeNC%:DRNT^$DX*DR6i\$DW5hA$LZeNC%>A%:FX$DZ6J?\hRT\MEFAACAAkADqb6
tlIWqC JS6Pd4Y5LRAALp\AACwAAABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9e*B5aZNwMYJyhC=mdZD5
9y>&G8 tZ>5Y>h%^<?nTI6mW=Nm^e^Fl+lY!Fb/^bI5Sa^&C!KKw#4!Jhtw%*iqqyynhSpGt\!6FIW5J:LEb%Wi
#ujJq1 dHYabW:KD/NIJWYM^e6T!kcRM1RwbNyl?!<VkqD&TMlp5KH#JFnmtqymLIq*=%G!a8!QnbcBwRQ/lAeI
Ia+GDH D@j##4uujM?=>#:cu*@5PTlh#?Bhn@emB?DAt<M@=ew@C*8Zc9hYL5cae8@#&kIb>u8yj<9?Z:MHH+C6
PuI@1^ &Dh::5?@=u4*d@:h@w$QHk*?+Mmuw@jDQ9?m:+V&i9&*:d<+<qHtTQ!?:Qc?iPLEN&>$@uHjH@*/X=tN
VpH\n5 %?Z:aW<kc<=e<A9&^a@Tm<Q*^Z:4^dYi1/644@#\H#PZ?#:<>L:a*??A:=j?5aH1EBnk@6mPnn*&kPH@
uu86pH kTd:Id>9>lj@QV1e8W!&+5cuS>c99@VqD*@>%jYZ%lh?QLj$!6#j?SjKaqZGVQ!%lc%D>1G9@6XL4?W@
pbSHYy i/9qSMhbj*q&D^k9I@9LL*?aj&!>?Fa8e/VqY+G#uYY!D!@G%>@+=Xe<HZ?\jup>L#:/L%@^eZ/=QJ<j
uDFy^B Mt8:*>n/R<@Rp*>y@Q:CD/4@?l9Xb:?bLC>YPP!A+R#/@KRcINpB*N$Fya\e!cA/5QewCiYA9^F>pu5A
nD%ReY >8AD5M<<AH9tAhnC@qp89*?&I4h@69IB:PwjaL/%Y@6qG/F^9&#qFkTK?&S4<<D&!:Ip^=lcY=t4VP4^
LF#nZF #/A%1HEcb<ylPRaXnB$+XJuZ=&y#6WuDR$<ekAAW!&E4m%DJYEWBukD#IVP8k94<Aina&:H?n/^?C@TM
Z#j8#! @ikJ^Y/JQhB^AD$8!/+?D:YMuVXZ=9VJE18!KZc*!tJ#JVculwjkWAi!FWtFqe6mp^D+KbPVcBhnlZHt
8*Nqbm =MbptdHT!<D$VN=Zjt5Bm96qA<B6XdL>/RwuX6k9m<p+9W?Y&+K?J!yayZ!ca*KnuD8I6XGS%Jiqb^Rn
Tm=y8l C41wq>F+py*N%&I^K&\=&1k5eL85Qyje+yA><:VCF5yk>Zu$6ZIL&XwbCq!?ER1QIQ8@h6$h68J#Nq>S
cw8<Bt cJV#6elYqMQYq6kC5w%Ra5@t>R1dK+jNKY\i&Yj&&B<q>bZJM6nGHM=Z@#pd&GH%eqq5FeM/SQbylj%J
$$Zq8> #*&\kh\lB4XJbFEN?e1j@QCDEq6dn1+C?cjQRK&55IEp5y@85I?W^@ayK$PJ#iW4*>yqu!/Q^h46K:EX
Hpd/5l cQjkj>+H!#=nTST9QupcybnZ/#>S&F^=Q8P^H:X+D@6JmhYZ!T1%yM@h\%dp!<5S\*Y5WtELCq84@!CH
9>GJMV im/Wy!9qT\W8?=X=LB<=@$lqMwj@bC?YyYjGC5w11p?kLW=l</ij1e^i=MylA<k&+6L\$:#?wy+XpV%#
lkX:+: S9@QF<81*\DDyV5J6Sh#qhmtm?l*dWH@V^jL/l5BlpWIyi%:aeealwuVq>WuG%qT9>jZ>l\6q=Wde@6p
!6$>kR c=u<M8!d9ijB@jye*D<d8HeBiKL<V!WqZh&d!L&#LFeP!:H:*<LibT6ad6>5bSH&#i1V?&i%9@*Y>=9P
<tJJKI &t\DE:^wJhPhQY9?qE6ucuG4BZJ58&j9Y*GSBSldD@MVI:%5a$N=5y*a*M!!/&Dm^T?IISj^dK=85m=y
QC>YIN cFTuCl5n94c%Qdb:Le9ap6jB$&6IJjDJ^tdmbBHL\H!&!t$bHmE#W!!^HTZNG4ipyuTyPBjak#jS<Mdq
DmZI/Q 5P94?PmY+5mNG&65k>$EZa%whhZS1IjNMZauZP>Wu?WhhCd!8X$Y/Md^n+yB6L5SaPnE=5chXAL685e$
F%j*lj #mAX/hw<nmLWQp:=yka?$=jiR?jYeQ^uNaRRHJJS*FqLHGN4:CyahW=m5R^HQCXDSNKCQCnR/K&b:Pe?
-A&VQ% 000a40104dd00110334 Page 196 of binaries2.zip
dDK#<P ?^u:N@5IV#4b6tKY#c>5uHyj<hphDBIl=FqVk4Aec^AJZ&&pm>hPqmc/+#Qiw/dDRlSuNXh/Yh>ThmPB
bb1a$c Qy?#YkdCjPSwcXnK4ycdHBN$4niVaIphNJQ^J:b16M1<$F*qSb&bnhpMP\:Yi1eRNyLYhYZauTlyMiq+
P/cqjF \whYV6$VLLcSG#XmL8a\S?k&&\+e:T/8FeAwBm<bR!=Q6tVqh6lmHt&1I8<9SSL5Ln*Zu4ALXXbZi^6m
uMliq^ !5Pbqa*XCMc1j5DKT<M$EmpNP!wJI:yBpbD84y/%*R!958KYiwmuEm*8?4#>\6R<t:5JyME=MY:q+<ZT
Y=:B6? 8HW/bHMj6lJjhD1:y<4Xc\6XXpiRymI:eT6i&>^iwYnZMVHmMwYFmG<uL5T1P!eI=Pm4Zh%:Qt>8=+JC
1aB/4> k%YMBp1l#:JmNJIIbA9RWHZaPFFH!E=Rm?uJwZyDeMR*5:kW*+*#iubGyd+pTCPEMubDiYF1w!?>9HEe
c!kYcy mCSILmE+*%%C^#mN9cubEtyNS/j*wu#un64F%+%E&?>KQDC%$ytaL+BqjDkpa1!YqIj@EJRtG*RGF^@6
I1jI/d >G:/jHjlt+hX#hKE?A/K8FTD6*8Z$564C$BM%9wLX6K1PFlR91VK6yCXpBktbCh<dH6G%k=Pll8t*p!W
qt6q^1 SIc/ZJu4Qnb@FSyEb$kK<*M4?Q#uXbaLFy%SG!V64a9d@9c:^a@H>^HhqhNj<?=w9Hn:linS&>%=iM4!
Zp8LKF >+P<IC#mP+6cGe!eYd:pCMc*a&&j@<kp\%lh!^e@<N+6n<VK^pyu>nn\aW&D@SJSdPSpm/ZjwyJWDaSE
a4wkK$ !C!N>P+M:aA/VkkF8G@HPueiLM>HY>N#BTBCGENF+^nY<*WecPXJ#m*!pXQ^Ge#pVtB^ub\aykZN>*dS
j?MHem dCDVNV?#jl&pwGl6MQHSVdbhB?iNNmQu$GmE/FG/t1K:Lm/AtR?de449yHe#un1==9NQw!cqEWqwIh$J
8T^*NX hkjPe%AF#t1DPSn^pjbAaHh?ihC/lC6kyDMd8@tNZX/e*V+NuyBqjQ\hIh4JekM15<95WDpek>T#8B^N
F+QQb* LY@iKA*>qYwwKQ+bEHJ!>&ZLN>cn%*\LeCV5+mWu6nF&*8DWk14ccSl!t=/hd?@8T:!@M#Ryt\l=GaJC
&Pi=i4 btj?&+t8!P^5>nT?nWmDI&R&Y:R*Rd?4Zqd*c%VnMS?NSqPhJS?LS6+SFJI1PlJd*LYd<j9cit:CW/LX
IKAEdB &mKP6LF65>1I8nKb/>*%GtHJt>=IdJa/?dJ51?LDwCEuy*eFuV&bZq^i9AyHmhQFY?l5I1<h5qXXYY&/
wm4\LM 5?4?!TM$%Sd6t6=YSk+a1w&lX1m!i6I:Vlj9yGLSw@M*kciWNk9a^u=8=%R&G/lHc<S/%dq8#?#thG@u
kj?S5# G69eM5kYDj>h+H<Ym?\tiL4HV!J6:$JZ&CyPDphc5%1D^YDW85\1uQcpmF&&5&8N>dB@@R<:DKuy8!C>
?DcykB :a$9:Sdqa1Vhj/eAn%FyiKTBu>8!DekP8S?1DG1?Su*?S5!VZ5&<#a1caVZ&@=AN/PX4@yqnJb@Z@QGW
cViZ=Z b*wT8wm4wc=b8QaKd#CC$SC$Nd66w>S1wnQh:Rt!>yqlnLM:J>/WNhdH*/P*h5R^t@HTXNhy?D$mnqNK
Bka<?> =uQRBMP!A+^cnW:DPj@YV/dY<%\mb%Y4VXd?HhDSX*QS>l%SdukZa?&hC>BDCi<R1i><TC8CBY8@!Y!d
JWhTc$ qPwEt4+hVRqMJd6Xw$Hyb&B!4ZG?p:hKQ1@imEXdM/ilqRaqPl!=waLDcBu%DFY<19?CldTh#IC=wDcB
SwD15k Yte=N\Tpjc9Cp>1^P^?nEY>$AZ1>wib1K*?%1pF64IH#w$S6lwpcKSmeZb4qB=PGWhCP8iw:kF:JQS^=
A+$\M4 acYW+BYjl$buV5QZQhSDCip\k>6te/nWek6Zy^%VTSP9H<@Jbw%L+&/yCSKbw>Q\qDi&W\^>/eWW<W=C
dw&j&< Z$wch%\k!eERy\E\R:Zc1S*VTYh==+@/?YadGDlXuiX6PEDj\?uS&SKem5e<FH5:wTQQleXYyC#Ku6&5
icWaEL hlq6c9eF*tX>4Pc5XpPcJMulPkljJB%\t:TXlLXhVFEcI=MR<E=eIqbJhcFiXu/Y\Xk%G/5%ha:k$NAJ
$<qDZw ae\NNS^uDF+FQmXZwH4V%^T+c=/R/FRBQGqKB?kRtQ64#M1uWN5Fk!R:\*!I&D<&%/Bhuy<WP8DwHB^a
eM>GVR I1T6%Q/!Ql<lZeilt+knDbbS*cClTVq1tA*AeRKuHu4D@uC1bFi&cR^JmFlAn<C55l^6h5ZS+QSX/F8t
^X\%X9 w8lCTqCD$huj4/=#CweNjKl8tM!chSymM%Y=4<k1YwCuatm*FK^XSCQaTWlWtykaAc6hH5JnnXp:K16A
FLDIh! RGtTltiJMPREp$&5?lQRSY$R<I6mXGpq^TYjq>K=/^m4pDAmkhbk6Cu:T:88!l\$9CtGB=8J*+BN*/ad
Eq#5H6 pH+ZnD/b8=WmEq%CeYR*+%FCYmjBu/dDaVMehnk^!kLGcqRN@ZbRQ$pnuqB>Hbnel9+<<K>BbbFT*D4m
wF^$@L 9tS:?1mZ^9\F/I6J+VwdDFS#aDdDYL*SbHa&%E!+HMN$eYlkRB^XlcRepPPk*:\6lan9FJdSuiYWN@K5
mWnml+ G*!LaTLI$PKR+A8iwFaqt\hX$QR>MFqJX<laQ/CS6HkkD#$H6c6SF&+t5t8>4K$Xji=F8:M$PA^wF^=i
Z*X/YV V^Fm1?q9eRh4XGEuyXPVp@&GTc:qGGn+BRl5y$nDCPuc#M=9^!I<ndnBu!KYEGm1HhX?dNY#:+FYyaP#
6DwXnp ^MIS+ktymKCm/phAlWpMdMSE$h1i^Y%w^P>NphaCBPaI1ReR1y@Q^GPpdi&Vyu4*lAYEpESnp=J<YAL^
:lPEEq NNSRQHJ8i+WRca&9d@aXM^+W>AK<8p#Dd6CN&t8:@Jm$u1$cVqPNP\pV+TQij6:BmSj!$CBABh6Il&6C
8C#<$I ^J<>6yKKw>ty1>AbD\5&pDYG9nZ$tYVb/Hp#:+LSMCE9yP1d1mV6q=I\KIGidWiEWIPRtX6ujcq&HJ1H
?6?RiN Zn?XbPAuHY6yXN1%AQQYDewVFw&I1yMek^P1<T5A+lA<npwWuRJyZe%GI/i\yPKV$J&t&H!B?>KhGD/a
Kh6D&+ u&Hy<&b4XbNJR5uGSHi%W*5RXBPn$Mk&9SQBIJ&j\%W?mltJaw/mlMeXVGym6\kSeKu*n1uq8lwZ:wPJ
KdG*kc >+LGZle/A$cl>KW1=dJccPVpXK^%Ge9C>%*\*/alXCL*P^9KHN1tYcyG=M?QB>GJmEi54=eMiXBjAk+:
FBFb>+ HKXPq:W%5<$&&#FJ4VelMEWuAjmJQ>%iypHmai#XMdDXcRqQCL$q&M>^l&*R\C5@8DD9JYNRwQEIVeWn
bM4!t4 &Cm9R%iZNA!e4dw&m#pL6dY#FE>N$ykPhi>>dYnTQZ^Sl1ATbuauVS&P+amjBh=QiYnEh^wC1!p*#6jS
tmww9T iH8b+qaXt^FtDHR6PHh/P/Ty5n<PuEZ=?MK!%DE$\6NM/$yZjDHqmYINi8kwXN81A+!IIiLJ5q8<YCiM
5*y&!6 D8LpQXEJJjaGK6KGaYc*9YG4?SI@6Zqn>SdGT6HpLYVB/kmpapS\9h:Nap*c<&A!lwSWX:5+YN*!MqRb
m<A95Y We$+Z^w<*&\XaqN#T=SGceaN4/cyDByuNaaCV\T+bW#VeT8^aZ4^?4nFwl+F4BWqXCu9Z^#YDyLY#K%V
=iWk=D tXPwuAJ$#um^L%e*5>tWbV\+M5i/#LkqNcqGSB1jwkQB:!VB=XS?t$K:F\Ve%bBV%/J^t9LEF=R?1hJc
Sdi#L+ :hX5k\nDwhbX6m!M%>NS1p!ZjCR/LkIEDW1aed/maWAdcw@$>8D/T@^ZwYe?mm&>@kyd@Zk+ZEMVLD%c
at9!?I a\iNPwVBcw&/Gy+G#1pwEw<KKih+NiFS6+9^YMVZtweZWq+And&T>hI\H!a44E5a9YCehGFQuCdi+Z+*
D<%cpW 1I^!KXT*/al/AmbGjH=@FH8P@#y$>?DS$/Ch^8PN$j=jyZ^@eB9Zuh@d=jIEIuQSE1ccth=M6WRYDdk/
$&PhM+ Y=&dc#!V^BEIk^Q5i1+H:8&TQ9Iwyy%t^mELWVe*yG\^FCAGcpl/YpN4\Lt=6ndFAHQAR$C/ukD$pTcl
KWhpak c*KV*q>&ZANWkTPlJNiJT\+FJRwJq6Dm>j5YyKYb@qtMjqAWH4:j>**jH=@9>*&YC5nh=?&<n*FK+D4F
I81AXC uNMNHyt\GGLpeq4w:>D6!aHK?ln%&K6wykR8iW5>Z#6McLHd$layJ\P#QJ/ZB@VlnK=@+!+!HNTdmZtA
JcD$mR qamA?8qieE/LD>^Dk&5jiY\&dyTM+CXw5Y/RuJ<XbyEaB?m8bkQQImRtYtdPc6FPP%+A#+KA$<i!:/Pb
4\P>%w eZBJb?wh5/F*5T+yR\/e1bmwR?kHB\+tqdeRI%6tL8!46%%?D?1WhSFDQ:8AH/J4P+8I6VGZTCq%S$5q
X1bBYJ R!V4b^pW=6V5/@wuPQWhJDtwtc<*llJTtP$!9JIpT&4e?%+!lT:u9lqFLm%E%yJ&^l+jJ5e+qXC/$kw?
/N+a15 LkaHek?lX/AiYT&>q@bI@nDmi@8$P#=QF/i@mta1QwdutXD#MLYw>W5QCIbCmH4b8J:Ec>uZQY!!E<!<
L!DcqD u?9l8C+/k&t*</!><=\H#:?CB9Q\uTYNNM4JDuRLiy%n*c%$h:tq#QC+Q4Rc=upN9Qp++W&4Ht5WE?n#
8AbIt+ S^MiB=LiBZ\X>uDe#SDJy\SSpmhIcZEY#jZ&1huh51p?aGlGc1>?T=u:dQnIY:i5!5&Z$ZDFm##>=$l#
Q\1:%C Z\Ed^ahD^\98KG8*^ZA=N@m:H:ABY\ChNi<>tX8i#8mepGPuEIem*cT?Fq&ee$t4yBmabjuFjyi?MdbJ
yYNmYn nqJ^=%*$i/Eq#&jnw>P9dC?n4&h6ah:>Ptu8aw/^Ge9EqN!imH%Y!W!6jW#?nj4Q@$MaZc#@&bqHP><=
GJe8V8 ?:e@@h4$$ijd*un%6b@@<l>@pWLnbawW9lkmPR@!>L4GTdHZ!#NCF<=YJ==j*+%F<\kh:?!eijR&Pj@#
K#E+JD D#edS&?$:X^>qj#$=@hjSm@<!M5\6q9pIPmP&l#KbZIe/+4\>n8P*NV:XdKd:H5b5T9tj#:#/IPJT+<?
EEJ:PC jPeS!Q*k/ujIl@e@lj*?P=:*PAjyTIXlpbE6HC+6CyFF8=cyjw?RGjj9QWV6l/8n*@98$ht9@d4/#1PQ
T?4aT@ #9:+/NZHwR@@>T@eKJlmpGQ8DHtRk!y5mBt!:RhMcq?MY=$+?h8/B=$hQm:</6HnT/??Xu*:$h$*Hl%h
m^e6V^ dj:F&?l?Cu*%8y>D#m\^m^:AK9HBmiN+\NeyhLn$8nX6G4tL99^kbdV?/HHw%iuGj@#q*dPN=y<@tH/d
h=m%pi ?a$dZjpIwht=5/V^w!ZE&iBDDlhBd451D%EE%&nWESwiQ9/k@58*H:@/Y9&NZ>:>@QVPc\>Cd#@#MIY?
PYyJ^b plJ=\VqM1n4QIi@CeMmWA>%5kNMH4SHK#n<k6L?@i4u?k=&Hq^:S6Z<<9jQu6W5Zj@q@*Gnmw=5MP*?i
yult:A HP@TR??Kp#&Xt^Qa%AJi6X1TV^E#QH!qAD1VT:@?%S5@ynyQj*ny:K<?iBq>=X%IX$KG%LWwANLikbXt
BZDE%! AyKBu%Xd\/GN1?kL?j%6c19R?d%jjR@YQuw<@iE:Z/y6Rn&/I>m<C=jIblE/Fe/8p?QWLb=4%%$nw/*t
N:P%&d F:tCk>Pn*@?L**^>=d5@QRN4j*#%j*#nc/@ZZukbQj>Nq8YEWemkuquEhF+w%FX*L<TK$yJdD!PqE5\Y
YK/ncc 8@*RFaa6Fyw6+k:je9RyX>HRV/IiNQ<<1RIiAVTK/<*EViV^+9mANhA^EZw#Z/=wC+#a#w9Y<D@e#a1<
yAZ<Tw tI1u$L?EC8wWS!HXWNn8i&uW^BLQeWkiQ!Hj5uI\M=WLyBnBi>NGBdMRT4hpF?TeCY<C&TD$k\t\M<jH
-A<#\h 0004ccd89d600110334 Page 197 of binaries2.zip
&Nih?X TKQj+$NSHB?^&1kn%C=Yy4J+kjX*&Hk4@kVF=lik/d8H9lJG<+^:tDV?FGAGam/5EQWe+kG:b/w6W>qm
/CRNt6 ?Y^>LBAF8d/VC\8Y5i6c>lYpJ/JIbEPp6CS\mPHmIjPHHyq^a&QX<k&Ei4wBK^aXX8B+NNicHWeF#/^L
R9ZW$c j^<>m>l8S18SGa$tE+?Tcj=MC5PiqG^48<m4DE@6+GmWk?cqqZXEcKP/ePbqNN$H1R+X!B:kL!S$P1FE
uIK*SF l*qSq8LYqP\IwSnwuE5:Eay/8CiDc/e5jay$^H5<T+S5B/#9uS5$NSik=dCT4XynIMdbP#!YGRPSuKQ:
!!dN:< M=blL&iA*KDh%>Fq1=wHQmTEEae*!Y+WMbLW&m>w4<TDAGNi9HdjG1>QkTbM@n/981CF8CAkkSF4bCnN
Ry6##V IwkphyXwjcwj=FyVJImP/E9q+cD&DQptA9#VFqyF1G$p^TFDjS?N6Q6ujVeL=BDeC^I$FMJh5Kal+Y4L
I<:9Lt #E:q4hXTS9%B$L46Pd6NQKn6<CP$IMaD/A>+bENhyJqX+Y@p=DcI*1$bnMiSC=&ac1ceC?wuN$W9pPBD
&yXH+W %Db<FcF=$QtK%^Dm*SAL4b^6bMk^hFlcl#=Bc8Rla6Zi#MSaPhY@c6*qledJn%Dd@piwY*T>nDVaI&wH
+mRGIB bBbnKDtRY!F+EdwW/ElC%4R6E4>SBtS!^yLLXEt?mhwG*pW&Sptlb>&Lj8=P\T^:BG4InmF!eA+^Qp+J
SVuTX4 Yl:b*9QF+84+YPIHJ4*Bc/5*!V=1M!HHcYIKnVEe+?!wpX!A8wb6h4BRY5TJVuh<1$DN#Bu/nj%!Xt+9
A?kQE= WLqu#NZ>R4l6<C1aXW$lLhbyR<=Ce*jY81N#/eSWEP9#Ky8EdIIi+l9FwX^Gi:H&L9#9:>LS:6&&a@nc
MY=4RL %lFAR+#Hi\:&Y&:=FSwA*<CyVl8kB#AXE8WLwh4+WQwb?k>$NpTc=H:dK5*LPIA$miQD@SD^aSwlmNFD
CtlRQ* blL&1\N/wG?*G/QFwiJa<pYV/u^?G/Dl\:aHIBhTKjw!<pR/APIiBEBqG=4:j9W+JYFdYIcR9k5JVQ\9
CFREGA wh4%w4?>T8XiIpiZ/8?&naBeF9K1q8T:pcQR@GGE+^npaX&lPkCL@uMZJ1k*I$t?6L6Y!8yj6M:wE4q@
a1I@kV 69ByY?N>EMP+pYd#SX\9%5mB\DD$TqP9N6QuhFbaKFE#&!LGVGE4PJd/44ZjELq:^n^1Y:pKARZ:@eQd
J/d+TE 5MBiMHE45G&RPMa<TP9V\T#IP>5nFua*e44*GT8wRmVeS4:Vhq\dAT?EM:K:b?i@CQ9%68#5YmFyq<:a
m&P@%i ZBu!KWJ8R\+Xhm5=@S9YdBXWac4@$LbT*k8\QRLTF5N81P#N4CD\HwAA=$JNQIj\Hj$GPiK+Z6G+$SkN
h8D6BD D1Vc4CSCCEQ19&$#4?W@Rc\j@cFhuQY?SP%M#a^R*#Db:hcl1GZIpii&ZZcFhw:LPjqFK<?VJ4VRb691
T55@4\ >pkP?eHPkVB9c\5SQNjm6b&dIL1CyD5ZR8RZDqaDui6dYj\i*T<5lF@pk#b#jT>+p\W:&&&?<D#pHC5Z
#5X@A$ laZpCQq6FH95CpTk4N$WnhDGbn*aS@hLYt5Q&$4%!$ZWCZcPLnp+kElBqhaWu88+S4JPymPRGTc@NSky
<ZZME5 LbLcRZdwL?q?!W*!GNa&&<nPRY/S5!HNbR9*5nXTDk5&14XntVR$9NR8EdKpGV:R&S!hKm/>cREZT&/#
!+IM=? dYN<ih6#G@\b&u9?yWIVdDXL%d+F6p1nLlX1/IH8T+QP6eQhuHct6daq6$ac+^=YRH@kmISuYikGjK*#
9imm>P FXeK#TX%eS+R%&=TMnK8pFubL1XjjFy8a<ZML+y?>Q5mL/GZJ5k^>T5?knwG!IE&b*jww?R*G:&TZ\/S
a<@#NG G=tlyYjIWan<:EV8=6E@K>>BWjVKdT?KkAF^t4QA<Y!GNy!BSKbP<9m>j6WINjcc%K<iume@6?TT661>
nwE6w? M:t:=>^wTPGV*a+1PX=5QY5nbmjMd+8*P5CjD@KSyE55pFC8BH:%<C^hc>EGGqjQDQ<L1PBcy<?GGKml
tey\VW e$mkcbc=AHL:JZXqli!NyBXN9pVKD*L/u:VYY6TH6m1E@*$u?FYm5>9*i1%yc8CTuIDcB%clJR\p\c@?
&nQL&T bp@X5BF1pw%6FiTiIR>Q%nd9@W+8MPeGj@dbWZiB+D5YiS5J$QL9c:h/IMW&L1h:XN<:yLTd$j/c!4%9
*KVGuc yRQWXu9aXqqp@Pnbjn:RC&hpcqaRS4m*CtShq=V@NEH&>#/GSkuc%>H4TW584L*dFtbjM8@>#9KT^IQe
DSeH$w JT:cQWHG@VS4AG^\dbEHSVX?nbD9dGm^yPPQ!jy^KYZ6>*/I*D<D>ak<dD9+JqyEa#HPaCHHt9*W#FDa
nwJW+B 1IGl?RZI5LiXqtKJFhKERQwi8Z?i4u%<CYyK:bZQL*<ElXd4DuS+QLDjBBIRC*W$9p^IV6ilhDi9:/1!
:QA<H4 <kXTM/i@@a^%GYVBynD+>u:nD1CQwNI8CqBVttt&Sh6\VSjMwK/Q\FF6yd5M+/?J8X:Cqp@i9&V>&hba
HI6jPI D&W>uRKT8qK&8ZCB=BIRCc^Z<GHAkyZ^Ia4c4?<tbjH:yQ=kZdh8\P/i6?AcjE=^/8><WVVW#*k>*iCq
%he>X* cR4bpFWJ!hSjbRDF:k>1ucJ<EV1P$t:dp:Y@?S#bJ*6ll^>>&S:4Mt\VyQki4J8H*?y1qXRP<*9pStQ6
lGZ=9j RFEN!GXd/?BZ>Gdq4KZ#m$&!6ntZlFythD5FL<lN6FkCuD$LX545A>^aHhdEijFN$nCuQ9tiqZP5KQ:b
GNdj^@ F$m#68i%kX^^kR8nWbLDaGaHd&Me1*XTN&t*<KC$P??WL=Bt9VJy!WYY^TI9pty#&&bE$b@Kk8H*\:i$
A9JRT& MP$V\&FjhwTaY&aF<H=YW&WJhN=e#u/S=ptdNc9k*!V%VKnV=WdQ&?QkHM?V*TLpb^4C=!/REJpbwQ*N
AHT8ZF GI+pIt>THpGS!n*16aE&n=%jImd<1eJ?XW?@IFC=LW=PJ/MD/1/VAttYmqyQb+?LNM&Bhbynj+GeaPlj
Zehhl< e/@V?uK4c^E>F+t#Qm=E6kEDeZ:cWP5F5BNFK5$jF4%iR+d8#N#>Q4&uh>BB^$>p15Qj8bN?NNunmWW>
R1BaeY F$u>L6$8JD\8M*b!@=4=Z%KH&^eH:Rhy<@DRF9ab=LFkjItRV@^>QRH$*C&yX?t+SJylK>WJdKhWcN$T
VV$/H# %e\B9PR%APNY#iPm!54IRT<B&q&/I48N6AJ!E:&RLWKp%tInAXJVV1+8t:mwheZ<INjeGpkDEP%E9dJk
iPHIw* C<m/b9TJm91Z/Lu=YL<mZKVRERA=tC8CQ:86jm@iK!RBnbMbE/8C+it#IddZH6h%nBWDL/LJJYepCnwj
hAG1dd uZKjBCNu\Z%!pB9DZjMPBc^iGhh>C<nPP=%#Zh%Thm$HAS/Lw8jm@u+JudjkBQIDAGiq=bMd^AjFut:S
nSJ#1Z F/P5p<%mn+A>N&*S:q=F9#aa#MZyHhD$amLmn+^TGAPXHHpaY%J96XZt!H5+Ep*LhMyZ#KpKewliL6J%
bAj*nC Y<<iq@eu5*@pS:48+A*lQKGMJydGINPXKXmWkuy>VPq%54BjE&B8Il4**HaH?CWye&%mhjYQ^6=Lwc@@
/&NXb= 6$VT^V=F8^beA=de=k:Geetuc@B%Qq@GTeHPMi*ihtX=9>HeQ!=tA&k!JjQ?<D8R6IWPea:th%uj66yZ
/MklCF $@!j5me/K>Mp%elnyT@R4\X5KVXZ&KpW>GWAXe<qhVF8P$Nc5^aQ!#MPbbYTPS14Ge&\P:5M/%J9Z+9P
j<mnkk 5dMM8?TIZ>tt6IbJc19@91k/9SidF51ldS*9$wi1>Nc+MbXVF8j88CkDw4=Y%NXWq/b%$LEejNy81SlA
##nPa6 A@@%HKiF#%CiHDeQmBJ^e#k#ZaQ1N:K6Gi%PP+*6\paJG!K:iBM6!jwN1<uekQ&?<EpmNY>:+#H1QPZ?
N5m^Xh 8^#L!?CX?@Z^wLdw:>byB1uN+KV5d?@Tdab8#SDKi&QkX/45eC!&HcG\B\pW8Z5MZV<+46XJN9@J4R=l
uYSDVN *tp^SddGNePb/wb&KSP$Dt&#uEIVQ%J>8QhL+Fc$JSh<pD\TiGYqRjKN5ZTQb<GyWMbK>Zw=Le/^C>J<
qpPZMm V&6Y$!!C4X:+6tl\e&$QIWwaG>k/#MwTLneKt/T$QiRXF&&^EKWn%ZT>*=pT\11T&&>^qQKLcQ!V8N\n
KYd4/9 QQPRRZ+L>QM<LF/><1C^8=HSatGdFWeQ#LWDZa1%/%LEYG=FcCaIj4ZtF&@=d#/EqPF#W6hkil\aX>b4
?$X#X^ ld*JMc>#mhY5AqbjVm8>j8Vy$jZcKV5FVSbhmm^TRt9Wt5W^mE&/l1h1N\=*54w+^:5Nm*Y^MapD5Y:h
F1&4GQ HqG&Rlbbblwc1m645h8PkHkjGdBZB$TDn%/+bNi*6uQn&4!\^QSb9qG4nGYeKww1^ka>*kLb&cQuK$6L
MZ4DFt CjyptE?\kW@dGP/&km9BtY9n84a$c+6l/+!P5$N#M1e:w#l#4VX\&W!lc*unyp>G>>F6H4Awk*4=VpZX
/ZQ$qk B:a1&?X!q8MDVFiLKuJaXA%*&PiT6q8&Mue@RmNBCV5M9\h^kC+n9IC+mBnD8a&J!Tte/8>q^D861?a5
XDuG*D #wyicY=iYTWYYca&<m//6laS$&:\^\AW$G/P6Rth5p9JnyY4GPMIJ#IDLdM&^99>e?F8WS>1?adbCKC9
HVAPbT FPP!N$pjSiAlm44>5/#QAWq\c#W*lHGu+FF+c?*$RBqLiw>t^E?#cBb<e5Jy8PueT^K+MMelac:VH<W+
E&MKSu G:^T%DZ9VS6Klm!:tnt>F@qaq*/>=XcN/XjR>jJQEktDk=Q%wY:W/iK/9T/ZFB?1=AD5&Hnl6lKmlJ/h
j*85?@ *cKGyaYWZ>p/Ia<<?Alh#KX:iq!\XJ1uI+?wELFFDX>T#\HYWi?\QqcnWpt>AJ+TF6whiQPWHjWKtkt1
VqqHXK 9kYyt!a=@^!9mA5<+N/$lDQD81+B*8KNq1&K$:45/kPMi5yT8y^C#%eT8F<G8R/DQ5M8C%+?Pu>PnR?X
<6IT&w mlL&<*N>+5q:MXd>jIeDu=B&TQ$ltyu<64nkeu85+59bDduH=iyc$yIDPX%Y&LCA$1%*=1b\:LcT<MhQ
=j+?c% =bwyNL:<5c\bkGF6MaMZd4ynphmeX=8u>Ry4Hw:6XF49JEYehQKhLu*#lHFZ8+w8Vj+w:qKmAHK<cBa=
PCSbGY p<=$6^49WKHa1T1&i<IS+$Vq#b#j9:RE%inWXy?m1hLj8&W^Bj4GcMPkKI/+/FF%mFM6LqJiqHV!*mLG
uHNTT> Ta+#M6uVC95!?84GnGLImke^QZ=dqE%4CXY&S/DJ$KYp=y!*hiw6P?>Q/@$&XjZHcWnTI#cQ$JYm=yLi
^T1mWb CpC>X!E=S%&h55<I>QSIcX*8wlD#XGhA@pq%dm=8yhl/m?L$\uyF>m*G+Zk+!LIwqyVmQjA=<\4GcSEC
!d6KH/ tuG%q8btl4Da:ZAP$DFFp\y?FX$d!^5>CkZA/RA*^$t+*=%AQZaXdNYu>DJ$$NJ/:hFD/>M6Y^YcXk9@
\yDj:H RmZwW9y:wBkbwLhkn!5/&C&RTMSmcVju+W:qHt/Y$p=\G$4Ec%np!H9w!uJGNVAhEpy*wC#MJ8Jk69:&
^Fe=ba #$p+LYtI>:CAJ\9$6V?J6cSLwlTP/5R%1@*@/5FWIuG:^\q^FGWE4pN@BeS!kaD5EteZIV^8/chM8c\8
%Lwt5m ?^WX4$QeY?H^EF*Jb9>iq8khVa<:dA6:hF4P?696AL:wBT%mZn4%\TG5P1K^LKVuiut:d5t6DK8/6kAT
Y?bWX? HNAaCq!e\u+8&m<y5Zu/5^/eF<\Y!l85j\6$hpF9T\wua>=kd8wjd%@wCRnIu9J+GNSF=WddYRCD/l$H
VMitaX R9dMKbp^P:RRXbSMk+V&>@NX89bTMIMqH@kX5lp5c/NXqJZ/A8/aypYwZQadJ#19VlZ:JTMN1LVSayIi
-At5q8 00086dd8f6400110334 Page 198 of binaries2.zip
y&K5P! wdHK!G51Zw1FWd9P<&GYhwW*KdHGMM=STM!h=4dtL5aAI*PW?%Ej!X6!e?Na%QWAn!S\jaaP*1L&Q4>j
q:/&9u /SMZw*D1:TjeRHP9PybI!iw!jFb>yG:JHXk8taw^L*H&6C#P<u+$B^EXbXpiK?$W16qQhd/^X5aGy4jc
1WkJ5Y =tb>y:IBc&ePSuCQT=WFZayVtAV=ti<YW*JjX*VPt6/@e^19>b!YFHEityC>dRB?6TM$DDC>V$q4KK/:
KF1%PK DaAMk5A\mkG/**FbI?P8$@%Y5?P/JC9RQhWK%&yDXbB:eck!Fw6lJdKW:HQdAEJ#9Fj#?S%ii=T#:kM9
C*WiCd u9yGA^^Lq%b4^D#aYdQ&i@%\8dCW%k!QyGG%F!yLPGJj85%/P6RqD=X4P!XN%1>h^?1<SW16V6c&kqR8
>Bdw&H L8=BqbGmGp:MW>DQw+Y+GPDCN65=89>#=$>##A=pHX&@AmF%ZN8awZIuy>bHj?dTbY<HdDwBhaH%T/p$
VMjXu$ F*W8*YpN%k6t/>X54P6KY1yA*qlb&>81lI:RcHdkiFjX%eA@MZRZD$uX\+\qHRHG%6Hq6Y/FC1e/=\<B
GJ&u<\ kGQ1G?dE/E^w?\lhtM!8@BcR56?D+:IVuIN4^:EpI*kTH85G58jTb:#SLCYYZC/RYtZ:iK6E##e:Q9$*
qiJW?i 64kac^elR*aK9LA?qQb4uAQh6wd#46N<dJadSX&uyNuG6ct6>XD?Hl1wnA!a89S^&1H$^EBYlM%DJR4j
q:==Gq SlJuDV#pJ*##:FBSH>1G9LGV&bk5R?^@FYhIE^KMGE+1*R/I>59:c%kYwSa9Yn1Lu!&hA9CPKij+<KBb
YahDbl 4$/W+I!8q*LE&/e4Hj^6@h</F@<yFE@X/Bh6Twhqb%#+dQEKqPRBG9e4tiHkY8Ei?uIyX!*E$ywYVpy1
d9:W&> l?>#hZN@Z$9cwDa6>qw/j:b$?@lnTqEDqe&b@Z#>+FW$u56MpcZ+tLGW/8W$B:tMX/F11+dkbT&h*=#+
/AWyCp dQHEblp&YCCNTtq6i:u/KSwb8d^CQppPJZqyAh<Mbk@Ihl::@iBjjt6Y+uyCGD<89yXhy6ehX>c*M6NV
&BL8%> :/ML8$YV@G>J:%4WA$k1pXGM><iM&\=QJG!N\q=/\ncjYJ<eu/RjeqDctCyXRP=AbyD<S9=ZH%@Rye!X
/eh^t& >eyBmK#488nlBaeq>$8j&ew<Qm!Xq#Mlaw:P:GZZk??n=*NDVjLa!Lu\GMdF%S9XQZ&k/JI:YNbn=d&B
LbMyR# J##*cnc4=&m/QT^6V\=WZpEZk18DBjNbYhjn?pDtT8X\p=k+FSPEX9lck+GV%&Fn4HKFq8/S>X\&8*!Q
Jta\S@ e6XMauwG<uk51R>X!QB?MSQWudP&%k&Za@VJ?Sd$nZ#S!n:BmiHJ!ZjSldFX!IRZ%!EeNF#Mb=84BimF
pI8BXa NN:d8yZu+p@pttR<YABw?mBdKleHM1?kpV!q!$QLk6P/Ql\pY?d8*qnc/WW*Sc1#QjVpjP9qWuuZTu9V
A!5hen 8Z\Y*$MZ>M!k%VyAD+@BL&aGCn6q4N8mLR=A=+YuHktatFp6RJw<j4B%BSiDAcV9Z/HFCmLVyiLmMpCJ
FY%d1w *jYetqnpuJb98G+<ydP=N$JuH>Z%Ne4#T1HuKn4Nwk*KQ<Lb!hIGLl^mLLh*6=yD@@mV=!jI%5liabX8
/dQeCh <Fw\w?5yyPeGAAE$<$W%LYK<E11Sk=FDdAS5N6pc9%ij^C?bcY#8XmuK!WI$auDDet/CQn8mc\a+%6B?
t6:!A4 L4lT%#X<W=m%=Q=k59HWI^CD+\Y4ml?CcWHu\RH/GAd5X$4KC6+1RCad&hj:NXck?&Z5%ch$*nF*GmCu
Ce>4?b Xl?iHwIMl/RDP6anbl1Ak\:PES#e1k?QLTB@K@V@bQIyuS6d$!9kw5*qB/YmqkR:b+MQ/P\G1\uAu+Qk
Mellk8 /cHL5AGM\ya:@@91$#@GcTbQ#/S8=6a\bjShGAhHyA>MaCWS\&8q#M48RStuQadV+tKP+KeY%?8E*uTc
HZ%%Jw GEyEW9GnkZLG+tYq^bn5A4uNS1Gc^<p8/+IEeATyQ*ZAG^bk1yL5ep/LSbE?Xh1mn\dw59wYGH/*EkSV
KquE5Z +>khphJqEZ6^4QCW#nX4uucID+>Bb#i/WKTQ&bC5ww8LB5+YKCkHud55QnPT<NNLt@VyG9wK/lm1H%L!
Bc!Rl& iS4hp=wlu+Q8bJ!CjVn=E:pi9Vn^%PKC>VnP94//@!*X/$j/6uY?8&uSWNWV$5b?V8=C%mY#QSN/&5::
1QpWS= ?bd<!9BREuw=KVhG@ZpwDkA!q5BFY1<k8!<qcPk#@RP=mj@uB&+%>Mq<WbED/Q@u>Z<BWE5DBBRAAkAI
YlhH@E AA=YdTZH?QIDB+kAACa4ARA1AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9WtX#L*N\dGF#cDSmcZR8
IB4Yqn at%\=d*Ln8NwqmawyR$RX5lFm1+SVETl+YXIaKa\5#G%Ft/EFnpa#HcA$mLkwbY@RqkLMZTCTEl1IYAt
>F#c8y &MKDSRmp\IY@RmaMA^4BliwXcnP>4FhIS<FBC>lCe::9uJ?WS*i@\I!=8:qhhPHl8Z*u?9@9@?j@>L@&
kpMK%/ i@n+9?VjQ<1@@$i?@V@pZ:@*Q@Duj@qj>Qj+GNk@@Xn#d&?>%9@\S::+q*@=F@pjQ#u^d?>$$9@\B#@C
!/NuVp y@<jjjVu99\bij\5j?YDZ<#^ci@y*\X?5MjD<K*Q9>/e@?SujCTjm$ep?LH<MMGQ<hYCL!X@?bQSu1<%
Hc6i^& \mQ\lLu>5:eh!aNGjFj=#6Mu+w8>b\@n#@#&+lJ:ld*QK?Ed?*!EZ5XeL^k9Pin%=Y*^qcM^$dj$:AEh
ja^uXk 5b:>uC@BZ!Z/Z9yIZkKJ%45^WyL\GF@9qd&B*w>=AuLpCT&X9lF4XDn!>bti98DIX/JG:eYN>H*$@jj/
ejXKKZ ZKXaieJH/a?FXqC*H**LX8PFw=VW8b?*dN*4FjCq:Ba=u5luu*^JRC\jI@V=iwt<H<ted<1ZNT1NdjId
X1mCS> 9IR@PlMG9WBn1=e58w9nn=Z6qBVecFI>5168&i4@W/<@WuE!alMVD:tan1$t\Qm=I>\#GXc&?mMunmTP
QXuP:a Q@V=S6$66kj\K9::Mk#&iZ!C/ydVm<R>uZhK4%+8+w#6*/1X8+1P4iT4jpYPP4cc^CTP4d+!!qQbJmE1
>4K#&+ H:^\KLhipSHH8?HawdhaSGLW5lW9>>?YaW@y+^9^Ji\GiK*kulEGeX1$:+Qj:Z@LX4%6bK9*V>BZ#&Sa
5%b:Yw yEhX!?uG1GZ4Rq@ju=5F$N6mF!/e&D665X99%DJ^6>k*+hu:4i*=d<u\Z1?Dd=V+91q*J<Q!C<<I\<>W
X$WQ/> Pw#6@B*bcmT1DQBm<Sq<Xi&kHZQ*k??mipP&i6:wuK*k^4!#T6A\*<p4@nhd8Y?q%R!m/d%u!8:@X#J5
%8%:jw <8YyDb#Q>X=Ak8\C%VcMXDaTi>8>E!iXN9^%dKZ!tY*+yhj*TRC>n8NMRw@nJau\e$:P4V/&8nKj/$<y
CXSl6> 99ydV#ZcNMaj:S*d>a4&J4b/1&q:=MhW!VMbNk4IX6yAPy8F5+8P:i/i#b&y>=%R?/y4?8E5cEJ6wu+=
ubwR!B 9yyTtF/PjGiTQX>9<Q+#:=IHKbGQpcjm/?EJC>/yEctn<b4#n85>h%LW/SR9KDGYhVL5#e&\1Paw&$dp
!F$JTc kByn$T/KtBGGN$yG:tt?5SZYp=^6#RdNLb<D@&1CyqLL1$n$G4^w@9:?Q&#t$iL8@iy1H@$RNR9=b9XV
DwAL=R iQe=9J1Q:$dNZSn/*u5@twh*tZiZla9*<+@?ZjnSD??m8by68%aDF!bS9J9J!G<FX+VBH#q\pJA#I?i8
DyqZwE =TbTi9CLpZFE=Wa5uK?G@+!6i6eZiQDi6?>\B<W&WZDWb@pnM#TWJH<i:y4QX*j:q?#8bZX%>@Z##%hj
6?VDL@ S8HX9?:#q&n^cj@&%$@:<c<4EjCjt:hS8By>dV:j4dLVXjS%>YH*@b*1n=jMuc>S9ESVamlHDdkK64M&
6Wm<<? 6Dm\$q+46\t@*95nl=D&!1=YD8ahY/Ed@BY=Nih:JhR9+c6uD<b9=maZChp<i68<jLm/t:>e@jVq<>Y@
k>/1*d 94^N\46=?Dd</jNQVjl=@8Hnl@DQZ#=+m!bdjhmHu:%jZ/:8t99Q:#>??jA=9NMdVWlBh9n/&8b&QSW&
lR9Y5B RqMQ:$dBw?#4+/n1blD%XjkLH<?%m/XC?%ReqYF<SW$npc1I*6#=?X@wZ=&9H=$=BD#*\?/4<DXy58mL
Sieb^k $Q#4&@i@#yQ\:i:q^j@//ePt?j^=>@L4y=H@>bS>999#y@^4<*d@>ZRqn%=>!L@M=\/>P1W^=/RK1p^J
!Zcp\E VFnNXSmGdJ*KGb\b8T5@A/JtHV$HLB%@Y&\JL&T+!9C\kwDE9N#iwC/?c!KlehTEh/9XXjN%FVX*w>XQ
KIRAJ% VTRc&:\NZ>/?Z?&cqj@?:uV%W@Nq>hP9u%d*h<%@CP?c=t1%<=^^yKcPStdj*XX+b5IV^a9W*:$BJihW
<Bu^*? CDnMRTq!&y94TjdP^ckc1#N\%qmlma6lHQ@WDw>w+?bhtLK*?*QcRIaBcSj9j$w?dL:HZeqHw&T@>\Xi
qclnlN !L@9Q!utp^<KK>?LRSL=YZ\c\T$qLkR!t$TL=KC:M6N9nXAdQ<^d5VQ=WnMLi$qM:eCk5$Yt^4/DTw=a
DwJpB! p^/@=h<@$d?&kaYDVJ:hu*D^TY#V/P4P&\6@S+c@%B9a=Z!tLcR4jBEYC^=?j?h><L*&k5\AK++HnT4D
ZDPQ/M Ce*$CGc$6X+61mRCTqSWDa?*Ra@/$<+YWSMIMjbudLX@11tJp&EX?E/XATDMD<ydLldjn@\FZL6#/\cY
u>$##J #R:8ujittcjL*?>H8REJQHCl<1Lm/dh8qhl%bHjNX!m5wiyIWh8?p?G=$#G:c+tK8?G9yA94P4ac6R!A
?B+Gk! >1$M:^$VHdAVDt%!Z9eQ8BmjNm:Sb=tDyC^BSeSGWkVh^hEe8JB4#4Db+$<WnyG1^N\I*I1J><mBdaNI
!:wa8p !lEu\:+l54PEkIYei6eZb^Bn:tJVG1G>MRdZTL:8#htcK58@Z?iL4:mFaiQb#dEaCq!nQRG>C<abBEpc
1iPaad C8G>FtCaat9=5%G&:d&SYS$Hh<%VLk\hPG$hiidtF=&&KmSVa?ZNHedWtIw*$@p^*<InBTN:8^pKbHCN
QESI#B Rm9<Z=iP<Hj#^Tnei!E<@PIVGJJ:<\!/M<@*<q8S#@%wI:@>&j9bu@@kZeu:Lu/kT9$$pq>99MZQt<Xt
%5d=KC <jN+@<Q?1#<iJV5QP5C*<QY?J\81EMCcWPedqN/:XM8eLyVEARnml6CCL$aE:4kZuk8tDYHSNPn9%Z:B
^PDhTm !?+NcTqjEc54muJS*Cq<8:y4X1PXH%:huXcCtN:?NH4:W!n$*4%9S19NK9!<Yd!<FZB+>i8HL/6S8JK9
e1DDGa Q<@jA%:>TujVjM:CL=?nJky@Dd$Q&bj@<4d=SB<QJ?<4LB^bE5ia$cYaCFdyljS1>^=@!$mEiF^SlMt+
YLqq5# AbJpVwtFV9k8wl/yZBA<EX+A?/5Ptpw99u14$bjt:X*#4*<Y4Qj=@q?d6\9@QlNPL::MQ?VnL:>?YM##
!MGJ1h Z#>>?d1@?6hQ$Y4^>jQ:@T4$^Rq@ij@%/8PZ#=<*H?/nL?HX%>^@Ya#iQu\JTcp@Q@Q*dSJHDKGTtdT&
IyGTTA Z+N%F&ND\#SdN^yyQ5eFT$pZ6<*uLkmu6Xjj1=depkIL^j+K!$!q*>:6Q@6jw@jS!%$w!QBDh6i<>RVa
W4&H4W C>88:n/9F1i9wdB+<VYMGpHI+Z$ajZpddn+LTAw@*DX=p**=<GH$hlEK#u4=86y+<<@bq@C#?wy=t\!!
wcJcpJ *B!q#!Gn8WMHG6YN&6k45h6kkZ>m*mBy+#bjkap*h@pFb&9*:q%<ymDwZ>$6qh<Le9l\j*j/>F:\?@&Z
l6B$P= Z%j*$e9uu$S@5+*</6<?*$i@j91/><jNV%>?DVQli@RmM9\C96=@*4<5=E@+N91$8@?!!1KZS4!Q+M4t
-AIRC^ 0001f35c53f00110334 Page 199 of binaries2.zip
#LbytF R&R&+#h5JXihh$<ePwCGJYTE!>RaY=ZJLwwhPjN$qwmac%Iq5XT4Jl4ep#X?halTj9@DF&<S:ue9X@9h
a8w\yY #>Hh??l>?K?4!A@DeP?9:5K*&j#44=?E4/j<!@8jQ4*e9h?LCC#?HGd#?ih\hL<Q>=?nWbnL@/6NiQhB
!<!K*u INjdQI^GL%%G^?XF%B*+LVJKYuTkGFF#RR1L#Eu6LX%yJyhAW5!1Jk4+tl1&P4B4MMS#V@+F@nX^+dD<
X$G#p\ QaY?T+?Jn^YDNL1c#>?Hj@bHu?+?CCm?C^8^FKj^*h!@&46$*pw8@c1^\GHp9bjZi&>?<MQGMn#u1X61
E4HwFE wCd$9KTXaTLWWaeSub94RKPCE=jCdNp/><>!$m*ahjtn8euETQ&4PV#?@Ru8upK&8JQL91M?:MSSCkV?
KSAymh ibV=+q+Ym=@*t/T4DI^+j#aP9i!9>k/@:M<mDq/Qd:BN<cZj!9DI56qhEq@qQLHpnjLRweE8w&Q8%VKl
:HR8Lc *:/uT5:I5n4?HQql#>J?:X>*V=u+5b8ZtM:QDcd9ZW=B\!VDd^amhYqI9!%68MlckaDL:Z8hyHu$pKbw
!i<nd\ @qq?VbudZ9l<aTb5%L/iPVB@bP+X::t\TIdC\CiV4%&J^IX%ip@X&AMbtiIAK!+5<?M:661he@EqVcjL
TT?bV/ //wAhh41M==PY5X$Mt\yC>@y4Nun^alQwc*XSAY?e\q&bT6S?>:\p6$Nb5w$6nAq^/$lHublw@9d8kRT
^ju9QA =@u*Lp:e8&#$\t!hJp!VNpQt/l=6/4!4uXlGVdHTZHNu#Kq*cReVAMMFlJ/i=WM>F*VQLcjlKVT!>IVm
wKC@NC XE>#G9nQChten+Qb$u#V@Dh5Qc5ikdl^?HZj^9>Y5ZNlEGNHF%%d<n9S?/l%k/=&ey+E$J!/<\y:9/6V
>AAQ$% nT#6d$EHbZLj\RVuPb$\6MH=8Yp/!:C+RIKea*/+VR#N4V:XRSu=duY/++%Wj/EbWR$/S!%jZhK/T&c:
IlX\%X A1NKnJWjLQA$HJQM9!HD+q8%JHQQDJZb45RqE9SmY=Dqpn^JK=q<eF9\G9uP4Qn1Z:ZR/Let^FX!?HyZ
cWI6ac y<b*&W??<tnj%9M<^%iQXR!:y$qd+?lpYEM+i$*FMTPV55RFuAdKnSC>@?aqY^P4enZ@LX5yQ1&^%CnK
\pAV:A y$*y&K4^/&Li^jNPBn!#Sj:1>JMba!h<b545Wm!h/#IGbl%HFq*+w:dc=tS+bDnG@/c5Ptyj5$&^KBPT
myeA$P d>Gj=*:wh\I/P9hZmhZPNdR>a!9nuL*uj<NYX@hE4PB@PJ$<*I&>JcDFmP/6uwb*b4R?<q8ZykFG$tc@
Fw^tpD =@4RF9Z8NZ8S8FyjT<bCd/C4e=8:$l#w9nZ4ik5>q\=nNN11<ek@1?:6LSuT5SW!dLikXimF\!u\i9QX
1*NClB /XiGSyc@X:+mw$:V6tjl%%Ic1nZ$AMbY4e:94ddnIQ:ili6i$yHl6i:Jbe#t=!qSJ>!J1+b<$@Bk6*:p
PKRAXb c4Mnh/9W^q8KWZHVtSGtNYe/B^i?9#1hZw#R:k/RwDalBl?TLF#>LNGRJpt/Zkd:V1%u$lcC@VQA%6+%
6CeP?% E/k&=Z5PaQ*&Jnwd=ZCWK=1wp@K:muLm^AX!kQ14=:ppw#+^5dlACQJYy>Nyb<$Ni%#N*uta6lcVYAuJ
!B<GX> M^P4<dc:M==VV\1k6*hP8M%YJp=l>mb!bK#nh%ht%pKVi/n9DLK9F=jRlF6iA4iE8enE\td>BjL?q8t#
KiS#!i =LFmDW?F=L&Riuy^Jh$Sjjy=R68K/#/\kZ>YQhldTKQl6Zq%MIck\DQNdP5Ztwykl6Bi19*6!DCE4#hP
eG+C\m 1!HMP<&6ZPN?kW8^9IT<t4/iA&jEGKnu:L&YwT44*k?bBHFkHNl/Pt$$iCbh8CMh!NWe19wBC/HQY%T$
#FSeHe jaIi&NX8>&h%!BbIPPZWkyPLe8nPji<5:N/j^jtid@W/\>VJ1L9@dYZV\I\TdHq@5N^M&MK:AwW@++qZ
BlyZ1i JQZ$yi$KemYape8L<+I:l>SbmL*mRJNJR%h:@:#Ywi=p*tXAE^W^5^j#4t<D%*\Y=%5XW6@Xh=ncFaIw
*b$u>/ lF&uVy5a*&6?tC#He<Vqi@hCZeN1dcJ5Qd*5mVT%u<uVHLtu$ML#NhJJLPc%6mnuIPqWQQy%/nP?T8aG
Hu\!Tc Q9a8Yl5qcu=Hu1aSFRL94i@L+dGY4T:QakmwT#cbj*c\=#\HBi=4@ZZ8uId<NkTyC>+ma?8ypWle?QlS
:9NQ$L jy8>@@MPD::@L@i<&w<jQ@L@l\n@n#L<:t/$#*AbX:Dhm<ZH?^%iQ\5@:y*5JQPYc%$ln:Bpd#Scu+81
#^:V=& BNCT+>K?\#p8^l^b!cj69uB>MwqYM+m%S1^JnpaPDWP6Mm1wiqqn/?p$u*?+<>:@K5?@d=wVH4\KV%@p
5mqD&X SjHw4@Ji8C6+lW?+qMd#V4mM#*hkBu/%pi?c%iwLaXa!N\dmT4!8pPi=?HVp1\#5VZjJKQ8ZuLNbW>>6
lm\uYR !ejXBK!q\EZ@Lkbk*6>*YR9=/Smp@cT?*dH%hNy:8Z#tya5dwpIqw^i=/Y?nWj+4Mm=j%A&6<EI4TIK<
bpDD>A *Ie:<QZ>HbukmWZ:\u1BP4#>ihinRl%NlLal6IL9%kc$RT&BR?J?+pw?/5=<%%:+&?Bw4nFh&+pI\RE4
TA1MPd G/8E6Y\>*i%H1>$J#*?@Y1%k@P=D+Ku=?:8=@\K?*8t4j5aqjulBWt$?W4/?deINZnwM\hiSk41FXpH%
H4CSlD 5k\SLEcYS4C$YK6dZj8bJXJ>b>ywKB^dZX9R\lql:Z^!@=T9!cL6>J84m&E/wtM4PQy=@\L4>!uMj5L>
IK9d!% c=A/*Q69::\jqK>ELj6QiK:@/!h&p:$FZ@h9=bF+:Wd$6T$>Ya=Ja%:j@e\KkJd*h:4qYjiLJT#Pc866
?tw\8Y b=G:c\11YFn1&5Z$eV=>nm6e$Y5Iad@1A#%B@a&n%S>hNX>\^b<*hA9jN:\R:**$e@=Xuu:%NRjH\Fh=
W$!^G4 WNkRBu=C+XpwZ8#ERT>i$JuT^YdYeP6/d%^bN#G*kXTDq=mEJ+=AndC5:t!le?JTcN1HPYJNeQSN4qFD
6t<QVH dNZZWe9Y8SwtYEP\>i=D!>jSmZj%A&AWI#*=+YmEB*$SK#E&ejm$\Y8lDDAc1RH*AL%AmD+mtZj?ZyQY
nyJTic 9kN5S1*j%6u&b+%iGl#5Y%%9W!K8iGA8GZjCHpTpcdW/1kj^5P9tp%?LYXYV6wC&#lhPZ/%@RZ/?5Li*
uh>qAN @N4i+PBCP+#d*CnKc><#@:Y\H*&jcL#wn!^LSwjT>h=a?\8554cM#c%jYl?<N?PN1:aWXDKjY?LJZ6T*
QlPqlc lACh8p8bWV6Ap?8ZMIV*AVbZ<$RKlFjG%:bC%CcR81yJ&<NmZXF:%&tqXZKZ99Ld%8K&TdLLD!V:4nQe
\R5b^! e%uR9jqCK$cNjyMPc=6>8$K=M%V:$Vihw*wHZL?ElkNnml$X=lNh#j!#AtKJ&bl^<494e#:BeK1FLK%^
L:NP$S VV4pc!Fdh^%6$+b@qnq8AW=dtXP&LLymXDJ18$le5e6$i8+E9<PFLdH8%Z#ZL/G<Em=?+i6:e*GwL#C\
T9#Bw8 mmXG%k\=Z*RJ8pWL$<$BYKJq\Y>h5wpNE@S9dah=$nb6jJ9&<X5tJ%&?!?ycZaJ&=Q9uGeuY4dT+8C8\
E$QI9V &5%NnGdZL/G=dbwSt8%p>Qq$q<^yjJleA=D*%Q:Qp*G?EER5^I:!^YaQJ:i*PRd1bK:h1T/SctGW/yJF
9mn+i! \QM#yPy/ipin*>SwS&hhIT=B&*cd:e@:ym*lblI/Gy%uXq$4k8cd4Ae*Edq6KISZ1?b8hKJmpNcS>#t<
>ET=Yd p+helS<B:eD5B8l+VEHan<Nw#5a99lS5epnbCWP?c!lkanSCtPly++AtFj&PpYe/%#Z5G:=*tXStY46C
9YDyq% nhi&q!+wK5uim9HPc4TbXc*X#JtDahDBG\R4SQEljd^D^I^jIh%AC=@F?a+<BSt@LlSbmZ6>L+?GP&wa
4D#Pu$ MR8qK\tNjBBN+SLFq:hj+TY6/e49+6m&$hdJ5GM4\hZe6Rqdd+njhT6=44*Wc$eI&u!N&TtZ+VN&D:Sj
6I>ZTp knj1!n!yC8/P%t1l<c9*d<K@pj>BkD/%?5>=Hu1+J<$Q+w@iup=!HYLGaQM@AGQCT?P=JA8PFVj!%:qh
%1^t1* u#aPYP=R\%/@/?db8=ECM<Wt\>d#$*a4KS^K4CXL8!Ne@pwD%Q%w%A$<nLT8Q4jlC*CJ?jkQmyZtL1#d
L&8N8$ p/@wMDn>!q9!\l8iLImwQACMPcE$j44C@jy$?4KAVLB1Jm<\<6:m5:ayn\#!cV/pDVK:m8K<:R?&C%*M
SnISX= 4j++h?DB\TFZ>NIa!FKh!CR\dE\<K\9!jmy8W9eK59kXuiwL*@TK+k^y@TKQjm6<*d<F6tDGj$V1GNL9
Y%/uFX CI^&w&VQ?@WBpe+bZ=M=SNlnA$@ZP4n9?5Yhp1u1cZnVhwBA!XYi4TE=eZ&dXpQTFFHdP!lQFP81XV1Y
/Z6L8+ BVYYWh#E?/qp?ebkctaCqpFh>=@^GZ!hi=>\%VRhGjLpCGcJNlS#!K8wnw+RB:LpB+/PcMRAa1#qWq6W
=$TV9P GKptnNG<WX5Z5hbkt\LTAw&9E1H=E>hM#MTdJm$%%Qe%li^b#eC#5mD#Ew8B=mZ\I1D\JYu=?yWYDFlm
9B&juA #^>>GaFhZ^dj<%hc!qG?ilInjBuq<9pP4G@aJmZ/du#hR%<@u=y&/IW\1A8tHbQX>:ci%4Q5dhKBJLXi
EEhkJ* 99XQn6!a%4+dldQGe=iHdy$\*$Zu4tm&uPDT!lmwAM5c8X9mn4:I1:+XVSYYSScjZMHRJw9F1Xu>K6?E
:Mm@&a TFGI>PK*%GVl1<cJi\@qA!&+8\1CNk+586K&XREVB\N>K*d?bymu1>G%R$j:5+=1L&tLtGhq\jP<BLVh
i$uDwj Ci:mntBJ<<+kGq4k?Q44@AjaYGyCR5dBB**>%Il<S*n/b<bBH8SbH5q*SA:GMLZ96indwiK86D$/V@^=
LQ<APe 48jDPbmpT\m&hiDj5HZWRipPTGwHIN=F=!S^Ebd&F6X<keI&BIBml$/$:b?N4%?kyABNMBebHclEj%<?
am>H^b N!IMi#\J&1^<lciq&^C?ZqG!iTHcD?5ckM?\9Q?NDK9b:e1&4Re&5jT/+d!YYJ%n5hdW8iFB=:$XN&qS
XH8Zla +P*JVK=<8wKKIjn?hKL5ARq<&aNmmdmFk15RHW@iTQu/AZG8eH/Py<6DpBiBD8DZaI?<&Ey$ZE9>dpdK
X?Zl:D BVd#h9dWjGH4YY^8^5%w6diqt=R::^m!qLEn99*Qh/B5MdK<lF#ib<&P\4qGdb5AA&^e=L<BH!YRadpQ
jA4&%d 6M+mtFhRTCLu1>Qh1lF^<H#!FaaP%kwJSL\I+eVeSV585LE+9YZ4QDqQl@qu^RG@DTSH:jnY*uyC4J:m
>GI6Hk lyKT<#lPy%%GuR#QXSR$WmXRdH/&NQRX:BC>IFAjiQ<X+8k9hn>DAShp*PIVbDRTGn<LSS>k!@E1>EK<
?h!WKC F4HJ1=PD=&#N<hyJN1dJZZ#w^pSHXnMmdaq&!#wbNnBkVV*#e:9pJW=qQbMk>m/d@M^>#TMm%&XS8ap!
TNX4kb m+/kj$=ZLiG55B\?^@?Bnpai9pi+/#HjKQT<CPPF/PR6\\jaJmSt$GpByu/AldMYj6>mj5%a8cnHPTQN
jIV1cC pYllwK$B:5>p&BIwdlBE<^Y8wK8N?T\u85dn46jT#VYdW#&>4C!Zllehu/mqI#cIuKnVL*C1TE+IkcQ@
6BAtLR ALKBqAmc:kS\*MqDG8Sd\Ne>Hhii&N@bJt9CTZTm%@Y*ck!1+*knX&*VtX?h/*W!4HNLdlSV?\q<LhZ:
&AEk1j BmJePhE%Hm6$<idP9?LPhhqk6eH/w!<&\!Dc9NE+J%HhE@YeK%>HiD!l$*9?R^+e>Hp@wC:pKjbHM<*C
H#HM4G Rh?&SeE1GXac<:yed^imY86S&#DFM8nCc*M&u5$9?F&!^&5D@Y>HNN8==9$b4X@$XnNJ1EYipbI6=uR$
-A5RJ> 0001e1795c800110334 Page 200 of binaries2.zip
@8l#q= W6$Dw?BA+X=jtFieJ?J<py!l\lY=i#16I5Z?@u5W\N4=eqLuKnMPMFy%J=t:@P/whc\PP&9LwKXC8ppN
\:%A!m dZ$=K+c/^laZ:K9#H6le5=Qlp<W%I:NYuBVd\@t<NIpH&mYC8^QDeQw1Spd+/lEp\#InF9\KEh@AaL<\
e5Pu@/ tQkAh6PYA+G$4XA&e6ct+X^DjLJ*Cci&KNN&qmbJt!6dYAHK%<T@it*jH=&q\F*m#W6c=$*@1pHC==dW
+uR4:a F$%k9D>b%Wp:j:+IEtS<?^=<jC8Zu55nhn@9QwqXp8AHLdY\\b@luXcAEk?u$^ZME<!^tLWZLh&:$h4S
R=atkd d>m/h!u8pe99#6%\kp6Y&q+A*>n1?p@tPpLiT4/ZKKwa6abbee8AiWTR>1t4cKmqWM!wcmD<?jJBYR//
XNK&8@ :$Shp$+T:qCNc%T\BZ<%eL##8Xm8p*D?:u9GhI^@QKitmcFb4&6d>e=/?VXA%T:n49=8kGql<1>h<SbQ
e1lQ\T GK8:ln:LuLc<Hquj&q=SwQ9R?<W1%6#/\iSGjIE6bn1K<j6hY+p&bpPtX+n^iNMmY9EV#FX!WkXuXPn1
S9E8jB Lw=EVbZ5ZcnuTnSJ&?iy4RJ6D6yTS*NZRLjk9YY%\<KYXE9PB4!%L*!?<E^p4TJy!6yaHDIjnjMjF5mX
+*1qtW /R*PR!dVIMQ=+8jh#+neh&mX@wE4PP:qeZnk#@pQHkaFFH56j5/6Y<6L=m$KHtGt!pbDje*^/wnniWqP
MVhaHk S:QF?4cJJT$k8P$E*u^$68hEt:D&%u*chkE1Z#YtHdiYCecAyD4t?&eP\XZJ<MM^ebP%aZW>&X=dEtT%
J&hJG! bG@G#uXC8\WQdaLVR>=w:?L1ht:Keh/#MMClZ4ZHNt?u6W!ZmNq4<K+nVNd%%P*dkH>XJXtaTAL4+&6l
#kp*@j ui6H/LJ$6mjE^IX=ChM#c/X!qcG#$TLN4Xq^$Td<&=FQ:h5BR6l4@wXy>JHLeP@dHtFQe#F<51j>\Cc8
:IuYT1 HGGYu*9&WuMhJtD8k8Kj&F\<?y9MC:W%8bEj@ut*e?4pP%@8CmluQGSP#SE/<pj:ht&I+\\!lk1L4R9C
ZpZW#n +E<!$5/&M@TRuJ8XWjiGb>6b6LXZ&Vy*++KhXZQD#pudmGy6wBwA\k/dF>K$d>MXHhyTh99G8uVB>Y+t
GmZi9* Q#B?VX#GaD=*w<^cB:Vm%b/RT\5D*aVm9MXKdcZ+#K#+</=m$>te^M%>w?%y:&bZNHE%/y#L*t%i5n:E
HWln*$ ^DdneJ=Pdh@KSNmFZF$yP*HN56w?*/I:EjYS1<9+CuD>5%tV9eXkAF4c\PdcR48B>dMNTCP9uTE$?W*P
BIHk/4 &Vy9Y$JcmGFwRi?A*^Lw?pdclphnui&ZpH6?%YGtN1+*&#%1t:kVd::9iyIFJCchDH9u5!bi&=w1A4jc
tTi5by IaubDW$udjw?cYi1*Fhi&\*YS8Xhq<@id#566Y6>%KZh=6%Ku&V8ZJdu*LXlSM8<K%8@65nNR6&>hRh%
qbmdSN 4jliC>4FPyp6dF&I=i?5p%!:<:^5:m:PReCPG5%Vi?+4%<b+qm#1Cl>8ha5Kt59R8cyI6+DL/eHiFSLX
AW!Hk@ aq4>%SXyFDP%?M^=LN@/PPj6KEHd54h9bhl#QaePu4u+8+*L>&&d4>@6?8ptHVZ*yn%e%9:wY4%e&dtF
#lw*9F EDwt==pMj<9YidiTnE$e#tJc@ZYldG&mieejl=56hhLXq<*mJwqN+?/%#6>6Tt9:LHtd>6dd4:@\6S*L
MB%A>H :w*FdFypT$aPK&mF!$W&4kF+%ILqlibj@NHbGJ4be<@N?Xmj9J98q466>Xi!XTqXCNL6F&Mm1P&<W4c1
*Kc6c! Qq45cBV=:Xa84:WQ&t8y/aJ=G>S$I&CcXuT6$uQ6iHRX8MV9>98\Ahn/Y@&=>b//yY*:du!RVHBSRhKt
twuGZn &4Z@=J>5:ty%C9iJnX!$\EjZQ*Wbc8>5V5:d6>Xkp<S&K%i*$$%l98@!Zt/1&G&>Wek+59HddpBFb+<W
mIS8\A cQmic\C&Vw?&q1^:PK!RMjjNJct$?=dh<F^b!Q1H&c9!5b$y>qTtHZ>$jK8hQZS6>q&a^dJ/Mp4P>6m=
u!??ut MLudatL6$5+FnL=bPhRGQKMYPdbL^t^WwR$A>aFJN:nAEdB8/hk*ZdS6luZ9:HDm$8YL5>GTLne=h#I<
=KeFnC :^yDE4i:4q%%/IdI&1uCd8lC8#*6F=*V6CJ4J\9uW!u&RndM$MZ%*6tCRl%eeGGl:!cq&6+EDCFaZDX*
b4pICL h6m1Y!=b%/=:>L16l=+&GQq6Hh\FYA/R6R=a+a*>&HjDPu=4lM?&k+&/ReF8FK14/=!^hjRd6y1@VHT=
wSGcAJ S?IYhZVVp4a$#8EyC\@bR#Cju^uAN9l#K:!<48/=5Mmq&:G!$A=4&:Lt1m4J*6%RX/4\9jqbY%V:%+$W
%DWq?K t9#+:d%\#nLyX8\qHX6h%cy%9:4HyC6dh@YeN66DQL^\k$\&&8A:lS$yaqyRA8qW4EHMNdDnmR9j6j#V
CP5pm4 hSBmLBT^nWdiYWMR!&+Tk=:#%T*yM5i&h^64DA&+6a9JjN=8>ZSViy/diYG/dcGJtY:jte5qi1+*ei+6
GTF8M> @pq*XctqW\8N4pjdc5Y:l8un8jWGcyVl?qSMmD^41G9:8G#8L$q<N/B89S4cGhu!qS4HumB=yaW4>m>$
!L/e9Y t<9iYwyyeF6&1@*5<FSZw8IP5$TdL+neS@S/9FSI%>+d>C:H+<Xt5SpqQ+#qcncd:#jjn::*>m=Pt*<@
VM>k!: W1:KF/=Judh%MedQF/M^%+V<MQ=l6JG@Q<6D<^H>l$M+N1uq1Sl:=^@$@Ty$8ktDBq!HM>wl\NFe*tG#
tA:+$\ \V+htwH9Qd/IeclN^*EC\Zn:QVTKyWV$bPuqw$j98<QlEGZ!:+A9C9t1!k/XjHYw1mm1+1KI!kKj/&Wh
De\Cb/ b%Xh^$W=m!4<!R:bRV<m?#@VF=Qj%WWSq*XeLc81K59!iD!8nuF<Cy9V1up>NjlQ@w<d?WWw9!>4@SQL
HN6B8W 1<8ueBYit4K5!qqS!CXXyX%Z^Bi4+?apu+6a*pYiJN?H^@C+Y5YuPI:4TN//%liVC!<4?a<j%X>/j/eZ
*41&BI HCtlET<XL^4^qiY%m/K11:IG1ZkN9ptBZ&X<W1b*m9@J>%tBQ*KBjAl8Va#LCb8X$BZG/Eqi<b<Ri\LS
$AVPEG #c6<^LlI8i+KF$q1t>NSjm1W!Z&4=HY4k4hR:u6SqPZ16eGNqI8bqZmLiHWM<a4HWm=V*1?TQ*Lbld!k
Qql=H= *JBaQ+SY9XJRG\p@C:K%PBRFL#mVX\hdc?E8L^\j+BX+46RcP=Y@@Ey?B<dKI<6TZ/e5lhI+LHu:V/6X
R<=TP6 KD\>Nc>NiASj\/Qe\IyEqyTGEnjuhPS>=XYAC$155Jy*Iu/N/=mpkGjHGFImamLQYFc+AdFe4H^N69IF
Q^b>Gm /?JH!DDaIb<kpyG^NTKn!KEKq:&5!XL=pDiSJ^hCd>R!>yA=@l=+Zd\Z+Cy+IJhY<&yEl5PnMLIS98LT
DPL1a5 X9yFw&!NqcM%lRlC9%wJ:/4u!VVFm^WkFuVLP^6jK$w^mcKPRCiEEjKVYHkcm!!D/1yWDyZ%L!LDpiwd
&FNPQ^ NKJRdeXLX?RIqLW5PnpRF5kqP%11R^X>1//STIh!RwSB@5m:Xu^!YQL=nbARCyqHT9H1?QwKnRXjKi^!
&cL@*4 hYBJlTi5\KduTVy<!mEyBXR1kuBTZ*GDiHMK9c+X?9XD8daTh%naZepNt$H6KlY^8BRbJ1qknlMWM#AS
1Itc!C Q1m\<6m!bY4VHMt4Ru=dbM/\PZWX^1w<bHmLJb+Npai=ec>\EtKFtbA=wXbMXBQ!etqwSG6^ccC<Pb=i
J/6A=k w&*mVhQbhMh:1*!F4NDRpXJKRl#LLX9Ju>DpNRI*=aH+G?NmeX>?/j$i9PA%S:nPA:R%c>tc!a&5M:\c
XTwJi= LqQW1%pht%e!q4^Xi*Tt4tBA=a\V*qDiEl!IuYA$MTk<N94=>WT&W5dAlGIJpc>y8qjNdn8bnIjVcyaG
S<Qa>n P^wI/C6ip%acqJatecEKm4AB>%l+mn5kZMJL!n@!/m?>:\yidIS4y9m1Ee:+Z^Xu<DbRXiHLEeIuF$t#
^R8//4 L@jMTI&?+T9aYnkbL8m6VIn+l5I95d5\TtGnnBW?W%JK8k<RWC#^bjt<*e=T#=5G$?p54RJ%kbCZ8A\l
9\^48M *#Z%58LX^c>!dVEEY&%SAYhb+E+5c:WbSR&jW&StumwR#W58\Fn#PSX8JFSN4ppp?BVKm<d1nEDXIi4+
C8h>Jw T9EX6tcW+Rkiw/KLwtAy6YHelLDAn4GNZKE!CR?EKTukGw6/8R/CaPwNl4NyNZ&cBwEKMnZ&iD^SM>Y:
q@1+km \ncF8HXNYFJhwdD+eRW8S$AE<mF&?P@E9MDCSG1WcJbkl6Z1SYYq*9kI>$BPuNRd\IQJ\?t15uQGXm4@
1WR4d$ =C#?+a6KaRJqTY+a#Ka!Ft^6Gm1#QKT8TT#aXh@&L6Ky<LR*VNQyW@D$NA68<cwCL\R:4PCWRRRaT::K
:E^/!c m^*nq1@1BMVWpXR+&Sy&tBaGIm^1h6DLlntP%A+WjIbaiXGjE\&J*NMXDIN=aBJ:^qkcNakdiF1TDjmC
RHWX>+ klVlHpE/RtGDGFw+IGw5ZA=XT?&tWL$YGwYZV^Bk+i65PlXmmT6\q$8^=4RCBXtL/^MbpbjFP%Ic+ZQm
^D1cSM ekcJl>dG=P99edEkMwQVIX54<>8StumK!T8SudBWL9MI^6b+YZqMAWB=#qkaN4tt&QG%IF@BA@CNhpV8
6maNi\ 9^l$8Z&<i!J/lA$qeSM91%4*N?p5tE&FYJKdC4*QAc+HQl6P=/kQJ/cpj+ZMth+4Z*pFIkaARjkH&%RW
XkFWuj mwPl8IwIcKE1A$:\BZLd?AFZAdeD^aD#4akq1+/9tYy>bVbV+VR5PZkAw\N=I*+T^$P\KA!lVcH/#aCA
5@a8*> lSH4m@TRy1uw1@^=tlZC%ip#*aK<*A#ZI=k#Jlmp#MalpFkM^Xh>LXTpKqNbEc51Flpt#1i9EeWFY<Fk
/TccE/ Z15<JKwLhSlc:FGkL6?I56RE=5TW9EQb\S!RQyjG1!B@=XXkeX1Bm$P+Y$EXS$#5Ne&1kcLFbtuppZuj
p^cd/S D\JjBHetwGp/VjH=Td!P!ky6P4SVbJViqTkSP6dkXbd$RyTtpuhPyLpG9BKMCJW4cJ4wcHC6<mNFV\WS
4AF55a jMu4wy>RSCBjjQ^+t?dBb4jb:aJeMbMDFt4pa6w%iWQR9KRuyC%yWWtD$AjAV8APyJyME66RQK*FHKYH
nieb99 DhkKnla#+cwwc&Y!kkjBqK6yX$^H8$=X1E1u5LnVRm!ptTd&L:*jF$w5VSP^IYSa#VC+w9HEpacEL!aZ
duK^E? >jFn5A6TQ=C:H\TV*Je@dR^knyuSwIARRkwRWhBcFIa1RpRDK#FQkkCPXAqkCF^l@V\aDk<JmBX#NC%E
ej<D>P Y$YRu&+Llnn+qJE+wpS14N=>KP\1lDZQVGE4TG=JA$tWDa\IImNVNJwak9hCuTViREItIjZI&C85/?$&
tW=Z** TXLjF^wD*$<V?Y?V?@J*b<\6TC#9LRlX$bkJdmPce^A1lQPBB&9kK^ycGq^:8y:e>Id!wwtILkm6b5FV
q/I&cJ hW6tdRP?K4\M4GSJQyDatCahjl4\RtNtmFZGEBnCH6ehZ+tZqLMXubB/TR$pkIIq@BVWW<<&RtG\PW#T
9caqWw FFVKj?+nH@5MICJGlA^kmb&!$yRGwZ:XwWZGaiCGiXmwc9!$>ZA1pJ<Gp/EAaaGH\E*VYTde&R!uSXa1
k=kY?H HWiNn?4a\1<nAqkFW:GEpDND5VYMBZSeL8bH<DXmjIbw&CK#T9%GFGqeDnM5q$MF&ickNDpIX+Y%=Cwq
J\4:8+ PTDSG$YM\JlpKh+8ywpTZwkam#YMT9eBhwcI/%ac/aBH%ZdCR*&<aJwMaJZE*akp=*LS?YD+>QSP*XkF
HlH%:T ?*k<qwccRGpDJ$G4BMdm>m:LGhWta5Bi^?B4RhMJI%w=P%^yIwXZC4RFIA!H9^Si?y5p<TeHpCmEkpb@
-AZE!> 0004f3d3f4000110334 Page 201 of binaries2.zip
mFn!db A/+P!X9@EFtkD@qlBkNE\&pm@KnNeDL\AZJT6>%wd1J?98u@k=D1BaGEN?PlWCq<VchbZT<u9a8b1C?A
WdBGk= LnYW?FiVH4D5mHhD=CWKB1G\TBp>HpM/=GKRk!FNqN@Icc5kJ:XNVGRAIMwF!T59D=5pFYWXpmdC$cE^
\&?/mW X1qXawY%pbtu>wQby\ItI8cXPtKbqRD/Q!q!156uH6ZpVXJ9KBdyKb$YI5hQ6&YhC45l!qNF>b1TP5d6
TAK%ZL ^!9nX&LEwk#1mp1nHk>GtABEeBNpFik\Mn8MQ<BD6E&qS5MNBibbKE!Fy+u91?!tQ4Z&VGjBYnNPTMtJ
>yKcIG /mCQADXA5w%Z&eX*5iawSGbY1%LFd$%mjaH<Ay1tM*4acj!/qJ<Qb#M\NmQIFcl=amT6&mA?/QmKmKKp
KYcp+c T>WdIyhA%KpP9mBjii5#WpuMV!#l$HAME^<&kCudXDk1Iu\IN8p\Ab%?wPw1ZIZTd5RlA8#5C1eB8KEP
Bq6V?% Xm>4Ben$pPbpNeaYQBE*m9:ZF&Kb?5N$$y?Kd*%KkaQDbw9##iR:YPYcaS*N=c6mpLAMKS@m1BuV$65R
EL&tj% MhZ1Dlm1%W8l6RRHC*W:^6dMEl=+YW*?NE&=FBWX91dJSC#VabkIc#hp4NC=kW$t5cA&*XEDwC@$PRn8
5Hc8mh +AAKlukM6^VameITJVK&A/uQp#V9ZR^FHcaCDAZ!y<HV8*kN?wGmb4P6S5NmhWKAL8EwRqikhhkt^Seb
4HGZ$R KNWEE9=ZXC+mDV5M>*\k8a#Scb1K\4K<lCYCZPMwkI4C4^:p1\V5XByNkp%h:S9ny5d4lidbIE+qEnNq
u/t>4^ :bDuK+LZl8AVM9\eVCbVGHZlu@B\KwHeLIky%#BTE5VTbeaRE8VyZp>EN$DZGt<CSkE&KF5XnFi15HWp
cRLQKn h4m1LLEhKd$$VYKWFh^ZmyyiQ=J#ABD?S9:CJqF:=eidJPk$qy\NymTYtDlVcB\DLaJcJF51T+uJNaKy
<PDdKe 4+AW5AjyePnB5miM=J=I*w^PcDmn<n+!FKuW?AL@MneHVbAR<Wnwn:^4bhhi6bEYeq/Ie!K%qRwuLLHA
jw!RD@ qBP5Yc!A:KP<Q/k:?MHpAQWWQRYDweLEFGhMySk45YYu5dAVlFJknLpKYBYp5Fbm?5Lu/ZR!tR!H$*\+
NnS\@* HAa#aCdl/8M6@c&Amtp/T!&#1VE%ekilcHwwKm>1#+T#=6Z\^uHljE:FmLeEq1llnYk/TT<!9J1MhWaF
pT*C1R jyA*Y/D9EEKeGtMuWNep>X5wIhEACRX1N#GPmVTZJqLMF6YMa+6c5bNaWPl5?P\H$?H\#WBW\b5MRieM
6#mD5/ 4Q$4DjQ\TVn<>KT=EBhTC*^AwC@PZ\REaFMptRAT4K<$BlCLA/QDY!+!nIC\eMEPWkwHRpdq!+!9?4KB
jA@Y&/ 4W&TA?Al#K>TChA@Icth8kb1u1ap6qKdtFYPFem15@+R\+Rwa<8QA68d4el9P9R<AW6Q8VhB!CyjySYk
l\k4:k Si<CCThl4N$?q!\=T1m@Ew:GJ^cJXkn#YG1I%CTyBQAyeP9AVXVZTLNy!qEnYtGA*MC6V<:qR<DD>MB@
dH!cBW \6ApGFJ<jdqMNeTP1jk<!&ibck^nCA&&awcX\6nIelV!+tq+CkWPCm^eD>b>9MyAQM/5tM%8/=5?JXlM
!@Gtl6 XjX$m$TWMdbYhVeV@pye#SIH4d*tjW#k6jT&JG+1Ld@A%DjDhqJM?B+#wJ9Rk+Ia&mKkRlA8FAiHRMnP
:R+5Eb XX%dT<^$Awnq:T?!YYESE&5QRL*L%QT%jBcS8X@K\+i+aj*iBWK+&!ETVPJlVXtJKccXZZ@G#:lXhFpC
6kYbq= /yk!RYJCa44ctPpmLI%tER:>$96PC*?Fypt4!Iq#q8p>mP5:8E$^SIF*tJDaAPy/pB@I>RtiA<Yd\D=k
5JHlD: lNMyDbS<6?N6#Yma/F$qcm?1y&$cpP!!j8D>teI5mcd!H1XFY5%t\IcQj?XJ1MJT=GDkN/Q1F5JCKSF4
4IG$wP #k\+\*$6e6J^IT$Rt%YKKNDtdSZ:F!+n\WSM^%aWM88%kuyla#/pi1b$4dCbu8iNQTF+CE^<:ubIKT=\
%hQ1/* y\bC*R?!ZILCyq6=$I\F$wil!5JW:qqjFRD<qL5qyP/iiPd4ld!MYGGt9R69t^WG/DXN%#CL!*wJp4GE
Z/lFNK TE^ItLytVwZ1YP^\cZRjFC\YYyBBAF9Cmp::kZFNYJ5VA\8pTMYK!J@N$AQB<tumV%SNcbuIZD#uKb<X
>RZpPV B6Vw>TIBmq5</qdE/jt&d<I\uL+b>JqIE:kk*#<X$%qR@>JVFDFX@B<Z/cC*e&R5\Xnl:C8V#ALatWbq
#4Fw?u dVq1Cc%MpttV^d>cKBKX>K=cpCFnM%Tbu=GLJmhFJ?FnIdPVTd>@+>%Ml\J#J9\RawZq&%bj/YTlip?:
K84w!p S$&yI<aT$%Vhn6YC%RnklM+6HNYpJ=y1amFtTbldBI>Ve#hQ!MWkMLn6Zj/>+y6C/\uIC+i9tw%eYb/b
uFqWWu HmiPXJ!W4#VLMiNZWl=XLG\I5iT4^4Sq<VT+\LWaa?Fnwc9>@9DN<D<KwiIH<XiIFWaL5dhDbT!JFR=X
m#M!jF $&CG&pRHJt+>=d/AlMHF#tq=IEVy</d+nM!\ihaLA1cuh<j/iTmQIXMyeaZB#MaT%*DXIFXC8yI!HLuK
5c?!&e 1TZpmq>ElnY1qb89cItq#5le^dw*:NA8!JV@BwPd!jZ%nVeGM+hV?/DP\Wb*BwybMdu<aM95tuA+*Y!t
MVpJ6u c1TF9I5YRh9huQLuW>!kcci5+P8$mdj!*Xm=ayi9wCIGKBa!V/EYT*FH+hL=KARjMR%*lQn%8:1\b&8!
t8/CIC M&JJp6F4Wc^:jZjuN^4SBJQBt?H\kn1K9^QwKk$KTKRwd<*yWFT4YjyW+Qt*<uY%GSa6pL\MuEN&!BLj
?6#b>K +9aI:k@1Da?nBumTj@jN4Z#Zu/uZkSNV9lbcDEMAnGyC1P$ptd4ZVIFDyeC+a5+$lkqT+ynDn\+c/BVF
V\6JE\ aND4Lpb>nThMHR!<m+ERPeSj%XY:!yT+aymcqXI9tS4jH@Q^FIdunMLYWStM=qjV>GuZapPEP6Q6!\&?
D5E@Fy &/1&/jYZYy5GLEbIl*kPmXnY4mmV5RNNND\m>eLZYYGCHTFS1yEuM<VFQ#Q#k@5>eVD\u\jZ@Z/j#Wpd
Fck:kI V:p1/FX<$WRqYTmBSadkIm%G^k1BTAeY?aY+#Y11YKPq%@nbPteEd$H>dMwKZZ&c/Zh@S&aX*ei!WFBh
/A\<P* lwKkRk9*DVya>BbbXl=\Vjkcq=ylL1\wHtutZkT8*%i&Wy%ElMWA>@5DIbGjQHW&Rm>aLJw/yP=T4+jK
e&eY<A M<KhXLQb/iVm1ZwT5k%4KH*Vd<In?%t\XYZ6MaChVe5in%y@nE$L?ReWCKl&@SIqm@M\VjY!NGNV6TJM
!uSR=? wj+L+l\4C@ASY8qA@lT&<hJ9LTX\wNediMLY@tT!FRA^8S&CXIquN$K9!LH1LckVXkhKiQCpTh:ybAmE
jlYj%K Y=Cu\Vp##\EZXYG/4Tip:kJMFX>:w@IMAJGbcXwc$1+%ZpPJmDZe8Na\9T#5wh1iSH\1GFGD4T#V>HCq
CdmPT* %cmw!Ai>\iD<91j\NaM*R6$6qHR#HTIIE+eD?:8bTHATWHmXSGE#XP>y1yyeCc@+WXAlHW5ha?$:i1yk
ac*V+^ b^I<lq>>1p&CL$5FCbw^wmk9kY:4<68QYnMlNNM$RT4%e1N?:Q%iW<h<?1G!I1Q<@\>$:=a6w$?a>H6i
+uIy\V **5#:K9pEl\KTyj4E*XNBE&ypTJ4$qTIlikYeI<X\&=EyMY$KE^h&=j8kmM%VjW#JdnQ?FZ8%k$M<5Yn
5AE?14 X5w%NSbb:\Vmt4nLT:KbB4qk^%aNQBDybKlhjVe4C>ZpTtN&by<PR6lkMLFLah%M#P@p=8bGmEV&AEI4
89?kTm XwqGCjVl1$pPyXY#m?j=+HKBt@EWXInK11iumlC!5:whi\NV:TItH*6IIRydy/1/IV5NEWlwJ4B!Xe?/
/V+CV4 K85#yycc?VD8hZq1?cu\FVXklnV5MT!$TDGS?@1:@6C<A9CN+MJ4YtC+Gk>EKeF!I<ndFKu^bGKk\Qud
I9/E6l qKuQJ:FTIBRjXXCb#y+:uNd>BQeqa%bBEVPtJqSb:%iqT+F1lqjLmPY5JHVwmEY5l?=LIpqGp!!*wNkl
p?@Rib ?1wSMA*VIhL/*CH9kc*ne!u#RPlt5>u8NqP%TkCFmwdN+cS$Q5DIcc8&cwRq>lR+D>6EQ/SiXEG#M$8y
aX4>K\ A1%*<dKuEw#MlAS#DP58n$myCuMRa&jYw/nyP?*<11^MHeh6R1IDE6dR\JkP6y^^8wc6l!khCKq9BqMu
&?Ct65 aYD4aD$iQ/SM=Mln<8h$8^ZD=NMGKZ\A6<BubHihSW/l6VVE^R^@<JFYbwL%KhM8CJTHl/W!e51M$:SY
Gu!F1d CZ/H>E4lIG:GJFGp&h>qyR%k5Vbacm8Ib4e5wqQ<D=@#i^V6M$MVLP$Wl$%9IL/%j!bip*E@RBwR+SB9
^lu8XI %AE/L5B^CqqYa1iM+!nWmy1MY9pNXHWYtA\VC1ahtDn#RNQ\be&5!^bTL*<tcyEqnNE?NhXBG8PDcY!M
ewKP:\ Bp8Y1T9YtJqILI!^%niJ$n=5W:&5IpQ@%ntem>\M?6jDNnlL<@G\$GaFjTa:i6mw5=M+dwlAS#\PySYc
#*b:T% T*P5^D:lNTySYGAubY*l=Lbqy8u6hQ4y6P&b55KCt:JiQpwwW>aKt^V#8LKymYhy@dYEnikDmhRWP$CJ
u5CK^A *MV5F@E=4Hp:nAFDDApi*A!tb^cD8wD:tLt\MC9+StY=6ITy<6dkH@INS8%6\M1+YClcy?wyuVt&Py!p
9//pBW pj$$#X=jXFuq%p!j$1ey4XV9::XjYB5DTKAt5R>AV=YqImJ6VZS=St594F^@6j!aMm\@NRKE1:FI<A*A
bCGACX $WZc!qu?YLG%*CY44Q<WVeZ^1uqh=qPmJqHY%EA^WnTM=/c*YRaSSp=LRl+RP&6B5EEqT&aE&#BeG?RQ
5JpN6a tI%aE#=hw1&$CY94k4Q&qaPFhwZKee&Pe9dHcTZh5e<E5ZS=mhwIwMjJB$BMk=9lGdJB>1@T*1P#FuiY
<DAj6a @&K$*8?&AL#!X\Mi/mN5eHC:p@iD>WX!IZ%TF^5<ca/t\$\W+j\a4<*hCLIW^y1!5p:FD8*INK*R4t=u
><<X%^ iBn!5E/EctTqZS16JZPIGH&t1MK:&+C@c+a!F@&kNa<=Kp=%Xtw:Gl:%dHpG8RWTaiCP=^MDCa1ETa5R
hYDA<* !>#cFpc+CMDT#k=*ZHZY/XG4XL&?19&Vwwn?I!4J/BetEhwDC+^u5\/5Be=WbRE6qqc#ttX1uF\yGHtJ
$ViIh1 :%ARKDW:A\*I?@<\AF5>F*dkIyc%>wNF4edw:RFPRiM=KltHY*Yta1NT6eDV#a=leR+IZ<EwkhnCPb%y
*q^W#e T!^=9LY1i8<mkAkaX*9Dtw$knXXJkJnaZ%S$Wl!44YTj9=cR&9VFYZWjjGWHcM9ZI8?S%MG\8?95NqjB
QIdBab 5I^=yKED4L#e<41&&:Rq*k>e\JP:tJ?/YnEalZ&1ypY1Fq5nXp4!4nVQ!1TG*K+dJma8tXPCDMe5Ntc8
mj@ujW XVLTkM!cPuV/R#8bqLF%K<MI@>D$>I9tEe6YZ@@96am9^KjZdjme*mMEu5YF<%9F4uLQAdHmDky=PVaS
$BIb5B m!S4MRep:HaY<&jd/W!JLRwX+tpZ%>AV\!R<*Ykkl#bLiinG+BPud%dNMYb:hqc$R$HIBnJyyPcJ\!X5
$tHbk4 ?GEYk1&Wbhd!X@E\Vbjnc?cBXGSEk#aPRj<eE#YMG!EZT@X#CDHKpk&&!EP!#%RR=FRN$+/NdH^bEYJK
dacDh1 d#E%IT:M8:btiL14%T:%pDHF*TJZi^hcp1aM$^nmFdX4@c#9F\ptLdM^a^/:lJMDV81T+HMKb1wn^W*4
V#EM9G N^VlN<Q&P6=l:Ci&>p%>8mnlVy6YC?kTG<T$m#k:=Dpl%G%8VRpR?iemBiauue4b#nTS1^K#@6ZWE%wk
-A=pdX 000be1ee4c300110334 Page 202 of binaries2.zip
HW^TRJ 1MQMqHbZ4$+unW\%RcTN4X&LcF!$=d6TM<Bqc+YNa9ll5<P6%<#:jTcWAJyMZ#@FbkJL/&\Z641ePuVp
GB#Vw= ?P1id>*@8<%&TK=!aIJZ5\Xj1c^K/qPlEb#JeLC6u+\+h8XNLbD4QY1yP&a:BhYGwYe:+*W+tL+mdNel
>6QYWa q14Y\lG#yeah6cYCt?K1Nc6SJl!XkEa?VX*A>a:nZHT6FlDP5m!*cF>EJn!FyWDM1J*A!8ZQR//Z\\R5
NQJKwh *qCA$^PWNZ$mc+9$*A+H&<ybZhSe=Rh1q<R\cd5M/w%wiNN^m11d<YKhItJJ&VtKWtqy1+?X6Xm\9+ub
*8uqtR KNZt\%>kkaZcmaEtwjbVR:dGiwhtI4^SwG!$&FnCLd!NhwKJCJQah1SRW\kStRtt1uWCA4TEPWBYbhuk
EmS9?E *yAJ8cqYN*1ZM?*Val6$ZN5+BhI1P8PF@%$cniu8pmZQk9$DdaLNRTj#4/Y4j5!9abpG\\89hjiIMAC@
Q+IhP& +EKDK61B4*tY86^qZGIWVKKj\qGu^N4qYE<>^F/a?eS$L#I^\E=VB!JteY4KmlctILA5+1X41ZlqF#V:
elEIS8 :KK1/tc<&NK1w$?cL/aJ$T+aBaaY+<b5AENikwCbh9kP&n4\?6iDwWy\EN!nV:i54A>MHpX/1dZk4ADm
pQ5C*k =qWu!bT/LD>$uMYalGLKqFT1t&W/<Tt%wwbwTX&5DWTkCDSFIDik584H/eklI^XSwmcdy>CZ%\wnBVX4
1K/#/Q /+FFX&h8i>RS=#DF!n9\!=5*R&H4bNl9I$^Pe^WWDZ!wwk1D6^4wmN>8GlbR5uaRh1jE/5^pbFIutEqC
$?\?4P HXymS/!tchJ6WYmK6Ai<BZhndNYb\lA%nFPw</H<$QhSKidpmB6L1Gy&*Bac$pYe1aqhpd%p4M+:S6P$
5Rd/LZ >1+H*tDT9=/ahAY*tPc1Yh+CX6pJZ*bBFIkee%aGe$QHSm>C?dwVTuhujK&58wtWcWZRFDC+K#V6ApdY
8YLW?K c+eNKWyPYi@Lw&8@a#jp4Nc1PJ6k*e6u&5XmqWekBp/?81TTF4DWFNi@5JjLdNhjlc$AVWP9:^JB&SF>
Cun%yH 1m^115PC\81jJVPTtM><Sd+m596>eMVcnie\dFZtF1jQ>CN>\6CC+PL1Mdaw6eii/GC1<Ku*:5l!%G9D
$ca:j/ hwmRWW:ySl6%iQXke&Ic5&iWMqXa%hHIXE?d&#H@!mbq81=N@&dkiVji=GJwTh9dE4*+l91j<#^Qm##X
Q+ti:: Q>SbnqM%PmS18Ct*9?:GH<^#k=pBlDmqKT+R5PP9/!%%GS>#Qyi4FYaX\Xi$w*IYJZb#I?4j=G%+M/%B
#h6ZeJ !hItei!/d%4\H&9VD*6?%D\Z1hnjITwa@aplmWQA\VWPPKqH#ZKDl@k&a+hNiD4DVe4Ynj#d&a!#bmin
Vn^k?u Mu*T/FX#E!LKKH\E&:L?b?hbk!eEDIamQ1HbWJkcN!GGjuYcG1ayX?B>AKFPkG\iDk^<NH%eX585mM+C
6?idPP YM+%M!eF<=\LllC?V91*jajkbyl1nC*1E\M54uY*C$Slh&=!tj/%bytEnN*J?+NTe\8b/$aw!M&$clYY
ay#<%4 YjG$LmahNpVtYGPh*6WSVjj5pyiQMyT*j*/Ge^e8BmJjIJZCp^>ENHK^tRyb=JKYV!%DA!J*4hk8YZ?6
uDcFAY 6J>+?a6*QbtI9k/>NnH<KKkImS:pI+AlAqA1@!JaKQb+#\T6$8i+wV1=Bq@86q!P@pTDBeHE$$1hK%FF
t#Md1J yZ^>nC^tHdyC4d1d5VddCyt5PIwXj6#!&ueBd8ZBTMXh^S<l65nqLYdFw%Aqq8SS?L6:B8*L/nuLu#u:
=#I5@F #jlXnhNl@Ya+GHlD:?JmcJH44ZnQFejYNHLM$^R/t/hb&m1C$I11T8d+t8j?byQ:#nFpLwc6qpk:Cd%%
bu9Zb* YttT4RJkw5mPZbLN8S9MwJDPPCT>#<616yX\Qk?EYKHT*^\&B%@iSj=Hn>t8Ek<lZNjMV4Y6>QKXa#Qe
+W#PJN mGi4TdLIpW&>!jZ%bPBhCLW8^XjT=Yl>VK!T!KdwIwpX9bY:l5+y+T5^a5hZn89k>peY%qGVumG/6MRy
RB>Bn= +^*lc1#KP4T8EEh1@^G#AKF?*N<@QD#eV4jBNKj^\nVRIRGJG!@*&PCdc\J\t8aBPuG&Kd//DddmMpW%
H/thRe d6p91HNZ:NpGZB#eVISWFKcGC96#EXC$tY6CIC>&6<I$ecAk6pk=9FNIXIHS*@mM4^+i6HPLNc!GYJXc
lHbPVp y/QV+che6D$HW+hV%^M%WHh#\hHSPL#@?QHn\<NYTL&>qTl^en9eVDadqAnH44KQ9&N=P!1Z*I?l*lYt
Zcd+CW /Cj!BHtK@HkLat%Pp1=yna=Yd!*W>q*lwectn*apP1Z\pGjC%!#QhJqI?B6>#jP^S$P5pQXRtRtQ6&1F
:@XJA5 c?SkblW/>%Mt$uRcWlk:QIQ<RmwI^eh@*54HeQNHF58GR6=tLMT8=a5^&5p<D^MHIG\+HL>BGYI#HY=8
4JG/a6 l?Q^tH\d5wX1yupJBaCyJ$lmKM@F\!&8^E1LX&dVC<EPtXH1m=CmcbA=QLph1%htS<lZMSkdZ?:$^y#C
luQaZS \bab5Q\QHb&be$XPS&LYIWb+NR8#8%XTi#5hjjl+i\6KN\@n>Yb>I^\X?5dn\bmNGu*6t<Mjn&<*HE?E
KBk4c9 P4pVq&V?=Hw<FAC+&RnFJH::d9aL?$\FTWc*5MIwI\<>#=DEa+GEP+yCnKbTtl%9A=ZN\hiAaAKJ^M4F
dak4ZW PYT>jEDWFX#wBBeHE1d1Zb>18a9wtd==A?q>t1aHwhactnS^KB@b<<QDQ%=8Hm+9L!@Y6<M*d\a*N?mZ
<+L99? E@QJj>$HY\VqB1\uN#eA>AKFl9*N>jWF?4B8lNpkNm$!+tFpaCy=^B6BVJ/\hY^J6StTD1?^BSlX5Eq\
PA6W^Q t?SGCt5DFJAC*KeRkLkw#J5K5bC\nb>*i^mawJSZYR1bSXDZW#ch%8tGpBkJ%YC:R@jlkGW4NCQJNatT
!9=N!$ nt<9L?RQ6Zl\&?@nM>Pek\GyqF@kQ?Gi=%&9J@nJwQht5LtSKB^j!5M8NwL8J!LVM@BXI>q$M:tb*Il\
Rk!m$\ mEc\\InG:q4M<G65QRkbFXEpb8#6+HtitctV1E+mwaJNjkywN4ueEJw\Jd/!FHwh=\#5u9Ib>!5<w/X!
dB/mSy 1t&L8bwyED6E8WKR&nb5Hm=:>+IQ?<*Lh<&LjQZnAH=*MQm$/9>l>YQV>PVH<wM9ku?cF/F@FX+&L&@D
u:Gb%1 #e%*1#9=Ty:<w##lbVl8@u$+#A8Ne?Scu<ZZDMj5+NqMA1i8BEZc@^TJASmQL<i<m/K\Fn5Y$Pt/%F$V
<hn\DZ 6MQ!Y:Edt:!L1atH^a4Xw16QE1:1*Z6tZ*9FbI?\&\DVtI*X=T\4@>R5L!@@ILm@J+Tij5SpP$q@/Z%c
>:w&!y >eLt^%A<eQM*wjXFPABc?&En6?D?6P/>ZZ&<FCC!Y1*qCj@i9%^>HG/u#:?+8c8JN:&+tR\9$BckjaKB
4m:+8M &IkRNX:aaaDS*YdV*%\KKVRGcj15njTYlHFLJwT6A&G>mHq8GFG:PFpYjHy/%+/aFbY%6aubnSAAMEec
h?b^Ge a<<PEmHd#/6%@%ywQRt61:B@@*G%GkBNlZ*l1#D=E=yL%@L9w&mX*IGi<DW<Di/d#dXR&Ph<9Z\PZ>/M
#aqm&u =TGVKjuK896GeL>aaXG%mYeib+c5%kyDIBlQF9<Fnt$8L+Y#5E=cEnVkbHPqEi\\Pk*\mIQXIk\Ra+hH
tw9nK% <hl&4IC*dGamV4ER69iwbX/=8e>@pp99CcN/N<LMj??NlY$Q\qw!/:9t>PNX$\n%1>Z>k%!$\K!HH8n8
M##TY< 9Y9YA\nDy=Y\@LJyH8:/&?djL+e:<JZqm/i&DbkimiNEM&AmVB:YdMiNNpLubY?>FnEiw=8+&tt#c6nE
Gn<mqM HX>*8bB/&S>n!uqui/!It<+cPMyTh%MXeh:jedVeSVhD*bZA^VB@k4\KZ<MipDGC9NZ>/p+$>i=V<$u+
eV/qi$ ?6*1S@t^<A/\AuPq/=BmjqwL?=5j:=56>Q#jL!:B%?F\P8QMm8CmTNS%ep*4QjHc?nJhn4dQ\PN+/:Wn
\Gq=<y Fw^NYeYXK<YDVF>yt94Cjqku%XjtYW5h#G5ZI&uVmw=$X&nhJYD1a@kyWuLVQ!FE@<MK6ppa8BGSDd>4
:E@Ka> @nb+8@4^W>l<FLQVjGqiSEnF/Y^I/^&pXtne@KMI@h%*#ejX*j<5V@C8SRIt6<En?Cw<Kj//tj^S/BRJ
:cbu1D FuhpBYbM\L^!KywJPVFNR1kT1>ay%$S:8WJCm*ca^G=+N!\%pdtST#cy^I^E5WkDHcG/p$iCKA6li*@Q
>6%@6I IF8ZaD#?cdWNV*?AIIM@aw1c>hW1HIRN!L=9:wS:1:@JJ\BG$hi4%h@pb1#8^QliCbpjL<FeieL\\bNd
\N%IjD 5NqNu!S?bVNBCy5$wSpiiqw\uMW%?cyJb8\FELc&^AL!ep=CTGlkmA865eAP4<iZlIt&AM5mw1YNqEu$
Q>6LPe nY^DYhy?5EICABZlLVNF1CjILZn?p$VywXnW?\8l6%t8X5PHeaPld/E%9BJyF849SDWHILbyQpGp^VD@
Y4*Qa& CTK\cS4$p&^8SSmYW*ukelykh4AAKh+dhLJ9BGPyGaaMa?$K8+?bVqJ%JdFmuWB55KQX1kH?C>ZZTGZa
@nATRM *R\tWR?cjBeCEL8<l44YmJP4#P/+=QB$l\:*yT$*YXcR+icheGiCWJdKCA/6Rp><=6Zy#lQ&dmDDIBaQ
J6QS6S 8eMW6@D%Ln#h4FaVieIRBM6nZ=wt&D:BDmNuJeJ:!%bk#:teFKYWW^M!hpXEJ?11ZJZQ@R&eTwZc6Yat
A+ih/# Tk/YMlMPL>^*Ii^BM$=RA1:cPl+^$+m^^qIbY<hQN/+jJGa^EJ$CEIPn1P4!4X#5t=Ne>9kKXMP@j6pI
9CDi#W YXjNuTe@GRn%^Me\8kM5Gl^?Yn&5\9H>cmueu+4nYm*DJtyPY&JEqC/jQR+wRILS$p+<LDh*BXnQRD=D
1$HZK@ *+>^FWI5VkZyCVcn%!EZhiutNhnlT&G5^\mYT\%$Mk?Bw?lECGKQwT/4RN6hdbu91jad%NaWGlj*Vjn^
Aw<W/G >q$ajy^<DD?K8N$*H+hC\$j9eB@tX/He$9Cn6:+Q\haNH1cjH5K6@Hejd8:Dbb/K@H+M\?j:5H18Ph5k
SEhbd! CFF<:ZCmblmJNTBE=Ak^!eSt^qtYi?Mi>bX@FT&$Dndt9kFt$*c\VbVlDnhycp4H44F:mJNl>D8^NbYm
N1qJ*A yXY:AW4h>%FX#<H$YTLSY\TlCNRt:HWWFWGADl$X*N*HZ\R>G*+lYmnmPedD^<K::jSYk6ymt\ZQ\dKI
wIt=6b 6A<t#mY!uR:H>K:tekTkI!5BK+%<14#L86XZ?e^\J*WP64VMSIbe8Nmt9nwhZRcF<LYK/!Xch:lNAyT8
66RTQw n44\!pp\5p%1\#LKWjqeQV?q#>P6<ECC$e$YIYtiD$W%hlI%=q:P!A+6AH%9AN+mLJF\D8K=Ie%dBK=V
9YwjI< >5pF!\4>mH<Hl#EBZ>p@m4?$VWCIVCYBYmLE6jGWck9Gyp^YL8Fk//l!i:p&+<G/6eP5ekA*wjl#^NR%
84LDEE F\ciV5%KGY8AcXmk9+qXy%wLFwZ\A=BGTLRGV:BXFGiVTIn5JcDPG+#=^^5QBy!kIbWdJXXm>PB&q8j9
K@!5NR bw?EdTXu8E6BmNDZIh8j9R&#mGlWYDYI/CJXX<<wXc>DiJ>t84V4?MyYIAS\w1ZnMYC#+PE<c*hNmG@C
14Yn9$ =nBh:eubIS%S9>Qk=kK6+:QA&yK$Yw!e%Fd+m6VLlyKJbRCHnjBXnL%G:H&Na>hij$QYimS&5t/JDVV>
\Fc!4< ?F\65ZQlP:\/GtGHu4XA1\\@FwnW!>nFPb8^$wlQ<yZGdT\jmNMJtT#QDQ!Lchy$Ct864^G*AHIRH@N?
9liay6 4%\QMi%bp+R&&uKFCm5#I5l!jXQpmwSIlGD!^><EwFQ+!uVV8D<i8A>95MEn1IYZEwun%t!FYBHldec?
-AZj@< 0002242c0a200110334 Page 203 of binaries2.zip
X^SD*Z Ei/Yk^$R9wJa=c8/HATb1>hZwFc^VCpAa1<FE<4aQM$qZBj%eu\XH8bMZq\PNn+KAK\ictXJeIQ8>nym
MQLynq 4l#nd@HHG\iD4e6aY#6nJ<NXJD?eVG::p?9N^Xk=!=%CmdBXJQe5PZFJ9X&D*D:+8wa+d+jVQN%miGRy
FLi^RW >$=4X&W/b6yNP:$>D9RqmNhPNutaIRGn#pdbTp5<H8e&d!q/ZSi88L?D\w=d94IwmXTDRAt5+eT!MP/W
eYG5A5 dSwLYXHKRR9%LA%K6/AN9YlFP69BCp>8B=64XeRWa?NC1k?&6p\%e5eZRt#@i4Ii*A\ta=GF!VcjVm9!
V4E\qw FREPbDm4@w1^PA/kwIGTIu#Lq4RXLFMS^WI1LM=q#>#4JeGVn?R@J4JD%\1VwhdMlBbVmddZqbtQGX\P
IS5YSP l6>R9PCK9@>pyQcG!CJ!+pMd/G\9*Xc<ntm4eP>mMB^AQkY9=%/Te?\YJ6nEawCEm?m5h+H5Y@>C*4=@
BFFRdq nW#dhMn5L84nbwi4/5=M$@k5#JHLP!IKb*FX:N>GShiEYBpLD<6>Tmi&\8m/#^^S*dmNe^SL^HVD&HcB
YdJ*d\ >R1R+iN@aucJa#l5hpQjw+$R$jZMm6%#wNbRkN4%ym?&b!m?bw\Eu?i65SQ:<8Hlaa$\Z#/Eub5*k8$8
ktT??* tZj64&>EnG<u$>9ye+DmS^H@A6^WyEMqq6*/8pQlFmHa/1kh!1KMME&ZS1ZDE<I:btF1:K/%dqhWeyCG
*BF=+e EYJ#F?lw?dLA%F8DCmMu+D/1BhdPAXA:XY?h5SW:ntwkkPqcp@<jL@69aHpAGp^?lhTHi@*qR+@nCSDp
Y5=imJ N@jlS@^5@YcAbQGWceKqF4XRj!&m#SDE$8Yp5Hdpc<$N1X^YFWu\c1nJlJlmQKaRM/y4EKDbbq@SKCG&
!5aXK< 4hXyKl#b!lPH*qB:P/K6j>B&NHH?L4BX*bpm^b$Ay>9y&Mny>/<HA^4cDbQ?a=Ac8w?HhW@EYKV*5w<H
YHdy+/ !<i/j$*GVwjd:dVaF5XnXt8?!Rb&l^4apXTM4LLA\V4!5\S$TttQQCX#pb:aMjXLR/#qK*aS\G/NjVZD
I*a/X& ^BJeBaNqjJkyl<F:@hEy1!k1tb1Y44%ii?#qA5YyZ^w%c%Hced?4dQVQTSZ!TC\p8Rq=h>b<\kY!+Pq8
Nl!H:d tw94jtJNWkRWEDEhi$NMuR^SH^KBawGn%1dhHZMTQih&#B#*N^LZ$TWmNcH6PJSmFke$+SSqLkenmJNL
\yB>cY \lnlQL<^WnHcleY5W@l#LGS4^?t4=jM$eGLc9<RMVj@TW>i/>4+lXVndA:Em8cl&kc?>\jWcZua#*cc*
A9Lut& IqwTp9%IP:#l$wNWS#I<8J#D46aCB#4Y=FI*a^Qeu96pEj5#S641<IThia#Y5>#KQ46Ddn696d/9C=L6
9RV@9S a&*baPLkKRBm^iYnBihE?E>$iLj6?Cy9PED>ByWeWhbL*wVXGdHIm@eGnV*?E6Mb/?HFYQ!#+GG=!pjY
5cKjt# PNIEcHk!Taa/aw>lX:pQJjwH&BP!FHZ6#JJ^6Ri*I?bHq?VGdJY^bm=WJZNLJEbw!6FPa:R>&AaN5$5>
aN@TM> +imM61pw4biPkqVDtwlyIq>Z+K9cY6b9lNl?:#=5X8jEkyM\V?B4iH?@Hq#$4$X@BZJ6l<LadV+4cIh#
i&NB>@ V1/T1/uwK&e!MmT?5CCXTbF6Q8m<neQFbP\nM6e%E^nc&15FLBaqNZ=6X:LwMAaS9*EXAjyW8=4K!1&>
cITI+^ #K^6enh4?d1C9kIe>hi\\Q*%+QJd4wJa9Pc/=@mKCwhay&5ka\S6+5C+$?m9p&qAKCHWmkQDeyel<pPl
A&A68l /C6k?HN&kA\:C>#Gh4$%+V>&KG1+:n1Q&Aun?MwFJNyw*Gn!$LWKe+wB\@nBXL!y>9^G!q@$+i+EII/^
ADw=QH 9Fe?FDMRH+$FR\#8#?l5Y9NqMm!MlS9/B@q&LNlTR8Bk8*9YjY9Q=G58*tcmk!em^a@ew/NVl\ZSMGM=
EAR1j8 a!u@k<d/P*1Ii4ZCpHFB&uJE5c^Icn*H%m:H1=Zt\J?ii\d=i<MKM*MT8e/\E+=a44I8=>%#85!HD&Sj
Hjh64G I+SRG>$H6BW!*J\^>phCp=c9<k+*\quSYIk4JA6>ylt#E8p\\eVJMNFSbt=9jt%RH$Tp9qt*iMuJ58bm
khG$N& eyk+AaAu:X*L4IDF1tYdq\DMFj6%$8ZS#<:h>N=MPd<?Sa&!$p*X%5$P!4jyhHKyp64\:uVEQwD?pCYd
w?lYWq M+%FIa?$*5M8m^Sj>\a*E9PILR=8k/Zayqn$hWy>>XK\%eP+hw/%k6n+41%QklAhDP=%<Q?!J^=&XtSe
RTVXDw WI\kIYII/=1Q&y+jN9iK>5jMZn$NHI1+/P6peDX>l$I8A&1u5M5MZVidB^DWNJ^SayYSbejB9ep8V%>#
D^uF*q ^K/@+T6^<4XkSbSjA*HY<K>XuLKPLkkSa&JanlhMWyTSX\$V%tYSY&=aW^KZqp#E@$D+4FL\6qTSaiIh
1FPLSb Gi9YL/9QCa>eD%^9jtiW!n%H=ayXdT^J1/**!B1*u>Q6hDk&jVSBGCkW9ER?5SEyQ4*$L%iue:in6EJj
S:FNCC ?jn4m\5I<VDhbkH*%G/y4#1cHE!\5!j*hQZ:K><?K$SjY*9pABVJFc?DlGmFWKjY*D?kW8=&>PyA?JJd
n*L:Dw L<T1%@Z!!TkXu#C=^hR#lkM+!cpuAXl8+4ucQcY=!HCDqHm#dwpFa!>Z!6jVC%l=c6Rmj##n/+N:9Jl8
6R8?ce RhK*ep?#G@W=Api=%!$X/<T6iDpZGy?+Yk/&ch#/%$/ITjM+#jZRtBXV^Futnnda6hMP11?AmDDD8Py@
MR>YMW 8BGinmieSSPXFTnM<yk&9FJu=da>B<6k+t!V6wqeRm=:eK/4pN8L1R*jNa%V&F=LK^<8n%>j>JGQ!aQh
91bP@G :Bj+uAudm:ChTTCVcK%E@^QWH\Vw&NVCdnQ+q1$89lP?/y+u+Mt!MnRShZS1i^NCCN\=NN/ITeK$Hldu
Rp*5#Q yBBlCX%uMdjm5%HWdinJkqR8=nJEMq<II*E9D^wGRwSb$FDtPeiD+K/##B<NP4+S9k:F\&/JJVaVmuBP
?+C>Ee e?^9wK+=ZPIKc<FletcYkZF=NdXN%F^96+MFne5XFJc4/dL&9A1nX+6$S$cI9h:%>jWFppGeX5Epi^C<
<Z4?Zj a@1D/:*6eB+$WY:VXG!VEc1edPBL?yijRB\1#SKw4l@p&<aBD5hZAeXwA:6@RH4*b4Ih:1am\<CI5BEA
9REtem ^DAVw1@aGI*?4dny?PymHPKtM:^I?M@>wmhG>aXnb>8>dh&8!QtZ=X@EXpn$wh5KAl8Zud/#5#W1G$>p
ZpF>+5 k?m&&t:FNnqCG?W5mL&p1&qw5d=VbY&e<V*n/$hl:d$EQJja@bH8K8l4N6TkT8\\?PwN5iPSIFjp5ta@
jIqN@# d4Bbc+^ndF$:^d*5C@#HLmwcJ#D&EHZm1%*=&tm5LVZVC!!Qt*A6Bd8cunB=^Gy:\ZNVaKK+MtFZ:eV=
%B+Q1h ZVyCqc$wuA6>>l$Gk@>AL/9WQpmp$>J/4<!>:+pMn>HQFTDPKVceMSmt89WQVpe\I6dV45yPZ>iZdbDV
=e*$ej eumN\p=8&\4S8/*uNZZmc\69a!=dSZ%#ap6WdJl>lq%Y\i!#u68\4HT6kk/\#6Ld!iVBEh1\SEhQ&@>P
+=%lNt /TaE@5MKuCiZBVu%#@k1wS&IjikNkJ&C&%V<c%bNjh&aIQw1Q5e:CMp?q4IjV!8$ceDuIC&^dnPJF8cA
/#dS^G =M$+#bA&1e9\>XWdh#6*$/XMiWcX5G#4N5dIVT*Ty$DB^D9EGLYPQHE/l6MHY@1eXW66R&wj\FeT&\k1
6>Ji<d :Q?lMd:CYI6bd4/JB>C=&WQV&&$ccB@MS5hY8RSSQtP*eFDB*ADA\kWeww&4SucqPk6&LPhWISEH^41l
%>>R?X JQ9RLymT>W&S+TGZS8mPQR:$#qJl:J>$i^mnIS88#Yby6R%kt$kY?q<cj4!wGRdyQ%KGeTQWYH<<q&FT
@FR*#L ?yHlHcwB6*tAjwq1/>NMVAI$lTSaLB!Mb!!@HkZuFIA\E6M=ANHG4$w+Ewa<A$IHuLP1cM$\#!Fle#wZ
KM8\eS ea6CL>8Nbc^ta\EDFw6<$qPk6Ge5%tKh?NeA6wuC1<lZ9%4*@tD/?1QKePPC8+<CNH:DX/RwLtENk&q?
CIwQ1l k**l6u+wVVmV+\*laC8P<Vdw$5kw\^$8:PJZblN#qE6\BBGZ$GMT1l$1$VFXbp^F?XHj=F=5mC:&&5^$
LGI5X1 #@8$!IAimjh6Va<I<ZPSVjQJk*FVn^ZmB%1%*Fe>yh5?Qud^K<u@1PFh9!>&j^6k=\L=KpRKY@H@^Ph?
wGbpXw XtB@^Pw%b/wCdTDwMITnYBVY#^XM^In4*NT9G&XEJ^iZayW^p=Jd*Ynn>tk<eiyZ>NY64:eBG5#cQGN9
?<Fcj4 +1YShi1IZV5by4Q>R>MFh8e!nIPDtFEW+*S#k*JtkLPC1y%PZI8DSYQVln9iAYTP9H15CpEDRejaq1ic
ltFLMD @6>^*k\QD<98EC#N9*AwqQ5K!wa#\>^wA@HXVY1a$ypF:%mk^DwEhI6pYq^Qm&*H%*Z@+hS!:\@6X<LZ
&QDpdL W@j^WSDb1e%TjG4MG9e9QiTeW9C%VDXFm+X1XFlkSHA1^JS+9iTckVa9+jCE!!8PQi=Xl4CjZq?bJ1+K
X8m#Hl NeI$VZa8ppAJDHByY?&5ZbH!NMW/y*e4dlC4NEGLJTdS$:PRG1CS^bnb@+M^>tQ@9$j4/dLXX@uX?yP/
+t>*<I uj9%<HI5kQkh>LZcykyljJ<LjdDHW&\Vnt5+/n1Gbc/JmVb<hWaanB&Q^i>4:<hJ\!I>i$mQC6Nb6%KV
cEb:c: X:YPTn+>BXMd\BIWW$!F4=1^=Qqqdt9HM*4uLl%jlc!VM<VjPcwS>:Dnh5&+XuD&?m#P?WPnmjHiG1%+
qt\1Mp 6?B4X6m/!XTZuPmyDD9IMG6Z#HK#hNX#YbmP6&A5E?JR:JDJM@d#/cT%N8n^+JPa/&61N:Zm>tnM5DX9
K?jd5y NuWhBdw!X*e9BSXp?M\Mai?8WQuT8#1%Jlu\GJqlwjaT1didp/w9+SWS5SlmNCH5kt1Njwt6#Tj/9AI5
1&$>tZ Q=<pn>^J*@BwkE#ktmbl#uTXu!@:mGBVuXP$Dq\PDh8PADab<LDD5wF:La&9\p>5aKmiunk?GPni%hwP
+tlui> PaLd!YdbLJ?ta^:YB:+Pi4yq?CV/h>IjNw#PGR+LTP/n^PHmHHFHk$9L^@VR%T?9^d!@FSqWZ&GISYF*
IFtPT5 QLkFCThiQV6?HFb1<$/VDZ8heq$MDmeFuFn11qA:e+ZFHI\@u:nSd/bDbpl@5=biaRQD>NPKjC$$6/c>
PaehX5 Q$J1jw6tLK\YBq>^n1J<J?nwbMeCjNRp*RQ+&?>j4\e*/=P/t\j!Fj+%jLm<RQw@!=q9&4ZLmMDa*E9>
1qwLKW NIG?HqhNdMHHDpqVl+Ghb@W<pM$KX5RDutChhMBF%!#y+GCy9n4teCqFtPN$P8VA9WhFyte8KF8=Xl^#
PJS6G* **pR@CPtJCXCwk!jKMVmYZTS>EqF8@iA8Ha>EJ&>*q\**<n\S!l5H\Z=INAiiLjEa/JdQ*\l%6?!H?tX
<c:I+& S#QB6G:P55LKYY?TK@H5@iE1bZW:WiXYT*Je^VyMV>4c8H%/1pX/4VRuNp1ZYVXeSqw/6w1NiC^&\dQw
qLnGG: K#hG9!BT=jF>ay9/@W>1yp+4EQq\V&u8DTTeGR\6S:HtQXCeCL+mMTF&PGb4DaqF\EPjI<E/<^KceBJd
p:5<+\ AaZ>^kL*k!DZcL&@&YVe?c/=l%i#bqu:Khaenhk6+Z*^SGLFi&K%BliBC:KwXme>?/dpCSae%u%Mq<F&
IVZLWY #PNmSacFJLdR4ESj%&>QK+e5H5\Dj$R>?9Jm*YnM<*H>kQII14EQR8yY+u:5>/@1uMXi!nCDPmw55=\N
IpBb#9 #@NF8tE#Q55PC&Q>\*BkieX?uy4C%k#e4Kya&bwhiy!R+@WAac1\6mJTJI6iJ\$dRtJCF?SkIE!Q\uH!
-A@Ee< 0000190430000110334 Page 204 of binaries2.zip
tLj$Ih FYi^8CMKV/8:ju?59VTN5%F$Si5i!4PuXZmiIliNjimnLYKdy>DZLE*hbnT?@\a!QK#yZ$WpT>Tpk&k#
J^@=c< /Cn6>R@=$DPJSy>qqtW<B$MVLbb<6BWq*FdPTJ*N>t/\PRB#u&c/:Gq&d<YinFMeAE:Q#+LuY4/!I\4H
:$l+9: a/%PcIp+KhujjJCBd#SFjp:5\+Y+uG&KQ99j5@NQ>+Aq:PL!ijIQ:QCKl#*DVpVMVKkAD*w>j^L+dcm#
i>p/:h Gj8B:bZZy>l?dq%Swmj:+ML$*MFH6W*Vhwe$WlQyP%*Pn%cWmIijIeKd:aI#99J@?dRbiN+u>Q4^?KmY
6iiRnB =LDbmB<hN<$*pa+IMbFE<C:NtWi5aQy%i#Bmb+u1Eu>a/wqi6c:?!8F$DD*$?n!Zw&Y#<:Bau/SFXl4T
aG+\/t Pt5qtIhI^VEQQEq44umeeR$#\%klhychXu1YGh9Rc^RKHujdku\qT*t1ENncDDAnyBK5@!\TC5jD&?Hp
X9iAWc yIYi5?#E?uaemL:tBYedenNNI4=Rwa&QQA#>@$udjK9wPe5>&mSYuASb=X:dK@KAZPJMM@a<^JJNF44V
^Q#EDK Q>b#^!CGS^:BG:Xka11GtL8X$^tY<#h&!HjlNwl6<>9X1iM49*=lF<FKGc65JY6QH>udyn:unLeQt\pZ
qM#J@q \qdSDdB@MdTq$KqGAiJ$Ek=H/aRbM@EGJklTiJ=BX=D6M%#u@A$VN*w/$c^a&5catI*DS+6RI/=Q=5AX
FK:e\H #<nS$:9!FjwB6XW<LkP5m!wi6>ZWaRucaNK<\i#Z=8*JmG*bilK69J%8NH>^*q*kdci:dj1e56a5AT^&
$b?SJM HhmCLHW/jnC4$C8=$1XIWWTuw#AFB?epTXi^e@p%^8T%AM5X#^uYw%^t1M/?IwYme^6^<Wkb4q!CwCK^
nZ\u+d Fe+n$CMTwhRaD*?W/E4$6a6mGLE*INZ#N=>PQLLBbFua?tW5kh6&cqmmw*cL%6yA+DD:@a6CMaRiTAT?
E:m&pJ +uReN>4kN9dt8ePikyeqGn4DF64:Z^d6tjeqNW?*Phe<8PmEKIhh^4FCa6A=5:Yu&LJH4KH6$#yCDJX+
JBmhpR lM<=uVH&hL4#QQaPd%T1uS/jt1GEkELYThM#uS&iwLW&uiXF!q*LbeDnA\AthAp/n1DdTZmm*S^5I\kt
L95V^> %lDZ<>C@/?hhy1*Zqy#S:RBV4NV1ed/AW#n<EYEEdpEFQ#P#tWHtEWu*J:FNnZa@&wq>!AB5d%iud#=i
J9QHDn QHcpd#dJb%Qlp&a6Jy6k8p&*RZN8t5R/w@c/Db/^1eD/%uB<kPP4yhjE1PLpZY6eK*JZ>8@4&ZR*LXh:
uL+KRT c^$=+/dCGe$*e#ja^JC^mR6Hk^tTKDpbmkPJ&Z++Ne&b#8=^Wle%quMRaP^npXeQ*=IKCecA8y?Q9deu
*h1^8* R^n+REdyNlZDjR+^=Pjd&&ti*8aTH*Lu9SmXbVBnhhAG4uA$=5TPMij?5Y1b64X\:$ASH/#d@Kq+uZHK
bR1*>A nZQaAIdSqJZ4?tb8MEd!=>XYekm:b6$\1P:ME/5e9EQHPMWB#+q\#HL%QE9Dd$m>\&:!jE^1@e%Xh\8G
?T@Zau \=&I<HP^Vd?>NiJ5<8p#n9LJ5>V^%W+iRFap^VFqTV/E@?DiJNG=6K&F>*$QLc*J8G9C:Pp5wdb%%H4C
t\iKtk 5B%Mbpi1+/kM4G/AN<qK498bYlw<bSXkX6\nlNZNQ6CETHiWQu<YR?5p$8QiAcETT\m\deG@X+y&G+GA
PpWWV! AkPu\i*MdDCYWm##Y^YdawinjDLXX:k+Y:w/FTCV?*L4el+niYSmIuYE>kb>>P<K6d*L5:+JN86Xbwpl
LKmd+\ 6QHybEN#tAXSEXc?X9Xlbmee&NJ5FDyEk&FTR=9GYuK^dwp>IYln#\Qe#dH8X@C=kTZumkt^WiD$$Bj8
ZP!?M% yh61>!\^:@R=je/u&?qY^Hic+??&i5!KZiVPHeTy!CdD<8aH@=D/\<yPSed^!Ww1@9w<H9R\cT5:?EKu
mYYiB> /@S\Vl6PkZpEu$LmR<%%/=Ek>ZbKB$9nyA:>TVAe#t=:jhW#Zi5qqwuBHY?LQAi^$*!I:i5dQXeZ/$I\
dkRlkY +aZG/Z!a:5nXNEZ#dDddQ6@PH9J*$*hC:t!d#*dXDkjSX^F&!^X^QtXylR9j5FnJF\MkaCLG&q<eB8lI
&>hhSW HR#/95l9pumH<&+ahy#P6HG%4QWe+JD/J\y@=EHd#HZddmS/HN5@dCehmG*GPVk&ncXu4BjMPaqSAYj=
9Y<Fn9 AXK^1&Pu#YK:*BanaP@RFK*XIBZEQ5<i6>6qQpP:Ym1@pJ>mtS!^SGWSqm/nFJS+&KViDN&TeXQZ1XI/
PKckjK /F@$i^:c58X?iy$XBt5^bYX:CHYlNi*VK</J^PFd+K?8XkYwV+&9%8T9^$@uK^/M?1w8q1NLR9Q#e%4q
!5JqB^ KZdR+I>&mPWH6?PM8&ACpIyhG5>m8bhQ=T\15&C=nbcQn>8q?NZb%1%%=HqZXV^Mtd/$I%&I@k?QkAWN
Q#NH%X ?!V:9?64e=HZl&pRMW/?1YJ^p4DcSZaWB5I!:NEXa6Zb8@X$hNXmZ1i&!hbXJ!ZTieaS>T9#=!^&FW9Y
dP=XyY JmtE8=bahE@q%pBF\5FknKc\?^9+i:b<S5hn?d!NuwVDtPb<bnC68EteDnT&QStD1RqmAHu9y+ESmw&a
9na$@H WFeS<IujYtFNQipAC?w/kBPX44A//VlPa<eXKYMBuHn&SMDiEN%=IDicy:j4?GSMp<&V$THF8mBLh&CS
H1iQVF 6LP6lQJD8YC^FVqG1^+l\?Y:?Q=h>8=hXn/@R$V!?DnVDZR<:$4EKy%yNV@FGeqEmj+::5Jq??99pGy?
#8RPN9 M:kaDCVc$\Mq9$p>>he?ipV5MG9+YJ*WdkCPG#%E86ahhtleeweLyZcYEQuMk/ylmSpn/JHGbXC#>Sj#
B:LiXV Xtq?CLV#n:%m&ViM4WR*5etp%HNZ>G<tAeRYK%B6Lcu61X&m6hYhBVLF%w^eI6lTkNQ^4:*iNd1SL4CG
Hn+45n #TPl<Dy6jhJ!@!LEkS*uWyVEQTS&hY!uBG%wYPA8/qj!h4/TCm5lllLDhnlt@XX4:IWhi:?5by!kV4QD
S!=1!u LuKG/dD4/wBBpMw9b%u^GD@4aadP4bhwMKtiu&#Qhwd+FeQl/bTd:XBeAXyMSCh#=9/c&^/LB/K1N@JJ
GAiLhX CSXDjNc96?:SN1YSBHbL?qnPwYjK&4nSGq^S8ZNKe>cbdZN/16Zu/bTHCK/em>X%5dE:G/aKwmC*DY6u
w!M<1y G?!$/#ET9tbeQ5dcJ#4R8jWy%qN?w>I&b4QY#L48%C&kV\5aJ+ql8ZJlPilh>K?94:qwSc!\V/in$L<4
+BhtR? iHA5M1nchZbeQq?j:S#kti<<^X+M<Sbmm\aNjFLHM$9nE=cW9Ma<e>q&/#K+!:I5=&yW>mS4n>lbjjiA
^6+GeJ =W1=VkCyLIWGa<JT^@JaMXF>bciLCG+%W&Ju<8?A1e6*tH>:%6+4D/64?&KcGBj+G<>XASRS&/!?:b>V
:MnJA! jhMqA/E:ETVTDuepkI&9E#KZ@Wd!A>^aSN+l1%hRY6*a!ak@FWuGYFjZuKAuB?/\Syby#B*!h8*y#W!\
KT@QtG /eE4yi=iy4:?uli^%Y*Rm9=Fm9$DuI++TECt!jZpi9nG8@cE4<JW<#q6FaB%Dw\=</RQLtTp99F<i/*S
1qRW1c FQm/btFH/KYd$hY6QGCIMbd\R+Bq4NCJZC%%a&i5!%ybH#14a4ej6k6Ty+qnhuqlAAn:B9ZA#6IYR/1?
Mw#Yq1 SmX1TVBNawNSASal>yJC+n?i:@Jt<Mad<ESFIAu<K9EGdV9^JjyYCTa+I<1ndHtwDbJpY4KI:V#5TE?N
b=1Vd\ W::1cVSpLlwKHtMec:41=l?kB6#aYi8bPhbkj<:YTE<++tF@ZFTK5/C+V=FldP#P15dIj/V:@dF#C#i=
=!1Qk$ eKc+CyAPH+5dRL6Wj#KbDDBY/uq$4^VmeV6?Sb>DIWcn5c:Abia#1t6Ld/8lRRDDhjV8XBcAmcE@%S%p
/c>*RA :%d1aitN>cBmiC@&E>9JGt=l/*p:^8HRu9VN6$C/CThXN/<cc8q=1Llh!qiAMja8\Ecp#BMIPj/68AHW
C!yEY! Au5aESl!C^Aw>ct$/&:<mlpuLn*D?5V1tc5Ecy+HMtPMS*K%q$h9:LVVX:bCIqWBnaG?^m%P6QQDdhh5
<kJwyQ y1Y@5?+y*iae/W=iu4tP>Z9HX#9b8/FN%/Q=cIiJ@TF*=<hnmIp@?EKV<JXnt*a1pJulDcC@4!%5by$\
l9hYCY I=V:&Pn1Vn/PI$Z\hcdL/NpkuNt:Kq@S\V#X\*h+6F9DM!H%cP*c5MTMB=#cp9KD:dA+X%jd?$Xbk6&H
J6qHk$ =&1$RLBC%cLpWhWeC&e>B@+5C/deHX6M/ZMk^J9pj1Z>&HI>uP**EPJAZTXtS1\?5D:^Qlj:KF@S?K8u
QNenb\ k6Q%LP9T8wL4mBM<<Pyd?qc!qKh9$5Ft!DcKumteKN\bMY+91b:C/<T*+/58%hiFyTLBi9C6=e=^Rn*!
lCI5GX A#MPT$h/jk=V@+d>+ZiiFE$<Nw&nhYJ<VhVu?J6jLm@dPeI^W5Vet!nt1ZJ?^<:\XTttEZbuM/YP4@\5
k6B=Dy L9bJhIhnZn#!p+Eh<1$%J>h6qZqX/hq=*@IXdc#cnA%bFdME@A%%%Tq^GuYt@DKiuep=&DkZR+#>^#n:
cKRk#B WaKAAPkwQ**S6YBwGZi$?ldBa4EC@k4\9:V%XaLp#D#FCka=p5Z#p+Hq>j\@8YmXaW49pBTD#i?\cFnX
HbMi1$ >hXPTq^1t/%8\wbt6k+&PqNa*V*M/apRdI%b>up><bB8H5Pki@C4H*ttDMT>P\SpmtZ<B!DmS1ebL:n%
kCEw#a aPwdZ$q5V654Fuknj#nGDET5&%*h#HqGGttp/CuhEd>dilyT!cWAR<Rdn:GYK:CA%/&#aqN^/e+p1&#/
JV\pKk @^5#VHZXE*MRY/%$\<HS9Xm5i<a=AIpeDQJh^VLF<p%$L\TcQ=W\Nhec@iACX<TPNmXYp&9/eVuANmhq
Cp@4d@ 1#HYHZ@H%ZqMy:R#XddR88Z4SCqGH*!JAYCpc?LZS4GYuaJb8jPRPA<jbS%jPaKyc@1$Sl$!B/LAY8li
mEL&?K cXG*$4I1?c4H=#mFuY49HFy@@E@8pJjlWG$Vk%hIMdekal5A=:Y^hR!LQeHa*T:cjZM1hM\XcwWh:T=a
ZK*>un HHl+iMdZCZKw\V8$!dHGGqw/paZdiquwRtuhiH#P%$^ZahE&XdwmAC6JGn#@>XWV=TG^nKCdKKc?qn#a
TTG<lF acpKY\mRaBMhFnqp8m?4Q?WbS^8m@w&9%H1kqEQ+G$*F1&qTPJdbKc$/=Y8u1LpVE5W&Vcd1dVk<Rm\^
nJhVLD =ct%S$SY^@LaHyiw\^&&$=*8NP8cp>p6h4A!L+<cRGXcZkA>%iE^QtEBPP+aM89MT<Tc&Li#Pm%%?yRC
5BJ?HJ >a+6@/%uHAY6#+Eai$^4iVtwVVSDLP+KIVVY@?!+5D8&e/F=$hyFkY9P%Vl=yHmnjE*FN1EQ?AmF%Zqk
4M*9t< km+>kJ/H!QB<=ha</ZAMF?Bd5CmamdeK6W%S&XC45n#ILhK#DQ/8Sy/#SHGhJ%9mqLGb^4Bi:8c5!hjW
m54VtR >DZZ##+Z>I+>4u:eeIP6TDH*G$T:184P\NMnI&L>D#K*lcibinwpn<@RX/^4bi955Vpi*b!5D1jyaW^e
bL\mX^ $umG@+*c!nBmVhV$i6J6%DEkwqlqlujm::DL+Se>%^jADXWhHPL#lK?AJwTekXall*1EA^&P?@BeHuQn
dpRG?I Myhyln<bXn4w8cM#*i=CWB1:<?JwG?ljN^MVbK/ELCR$MjVjuJ?FGhZ6iVk<y8EMJ:Lu$dbD/R+YLF=S
Q%8#AW whBF+!6&<qR%jS*PYhFdZ?IaPSSDEhRJa/8N+EVN>\<8>GDLmY@PqYI<S5LLyY%yldpjQ5*5iE9<:?bQ
AbtpbT nMj+nZ!p+P8E8+Ye9p4<C6QCTqS+QIcYTRGe+JpnG4hFlb%<$VIYJ&BtC9!l4VlQ@8mmYDL&YL4nCIES
-ABT@Z 000eaf577cd00110334 Page 205 of binaries2.zip
5jjR!@ YTw6VYE4dW!Ht^XT9eTN=NJA1*NqyCQtGDZZaMe%^?+#q1bHnJP1ZjTa8TMV>KAlEWG66Bi=</@DKSdd
V5!#1X CF@F%Ru&S?J^JalaW?KpFnFK=X#5wV&5wYM5D8YD\dh#h5=G+pN/Hd4a55RKIb:Fy%6hemm5XdG\ISmb
n%6$wE W/>h&AJ@hN6lCeGJHwa&k#N1pdEYTuhSFKnC/tHJ:nCBTM@\1KJu<JX:lj+nkw4yG&cKecp$^G&^R/$V
kBBLh5 9aR>Qeay>%GLlqYGVX$qhpZw$HRLJ<FbhdEM@E9&I>w=Ab1T\AH\5E>VdB@*VGF%B@:lwCGhCnKcJMRK
$#SXl< KdEB@<h&iHybH5XTcDVdWW6^R^y=TA5<B9C<kebmF#:QZA+X5^>lWuVV*w!R&EEuQTKwA<N/$CIm11XY
9#+ep> pa=8jcki=aE+ILRneMFZXX^=Ak=y\kHL1SCLE&DE\idh$mGPQYl!YIuNl\Y!%Bq6E6b1F*tk*I*Ru5Dn
WR9jF% LJbXS!%ZGQQ+u4>CZ&?w1lji<A*up\IlDp&YlLEmh/?t5nVkeCq/6pbl@DVGXt:%Pm#kC58T>NBt^>un
A9HhZP Eh191p>>6S8Z5hI>$^I:@i\lTZ=yN%=AbR?d^Pp5Qua#Jt/^Aq?8Ab!6XJnB:&&F<?n$DKnKDpHD/un=
Th*hPT :t:/Bm#6V@+w>F=kmLF/8pY>C#KH5kmM$:G$GpASq\/k<AC6R^jtkLG/kRY&9nu!MIKa?*waAR6wlL@Y
V^+Gqb mKtAHT+%C%9uPMwV!B<iXlV&ALyMaXFkK6LppJ\S/$E6kRllw4a+PmHVckT>Vu=A9qnlE?e<D$kJW4*!
pBIZ@l 1RebF4c?<c+uN#haR9\ELwTcTpTQG%&HX9h+hww:l!@mIXh8@EeQD/m$V?N+5uGRP6a<q*a9cEY5uJY5
yjXLIF 1@NkD:pkL4ZAmRwFS8ay^QR/A=!B\qcb^D/w5LqjTW^V\M9pIBN4@%qSW?*Fi8LeHaeS<bl\SEH!LW#V
B6?wwu H+ZPm#iVIZb&w\#\DqAANiwVaD9p:4ZSGkD=ckGAVSI+#tb85$:Ebl56cSN6/cGl4KAya@YMmqKNyCnG
lNh?GA F8j=AMMkPaE19?BE<:CRM\R@ME/pE/w4cLB/lIWTypJqC!w8*T#I%:kuNa$6M1%cb5H#bDP=tHK4<?Sc
jb#5MN TL%kuh9=DHahalNRcLm+luZC+ZlK4E&IPIZqqn/t+wT9<K&Mn5BaKm%<NpFnZZK88eLSIjAS5L/M/mwI
K46YlN 59A%EeQ4FFa\ekHV:D=ww&A6\FV!6cDmauj9^y%Q56PX>*1GZ+Z9eVSGP4tYRPimn%Ha@8S/MlZ\p1H#
utDZ/Z +BZ=Q#khJtK+KThY<dZ#^ttK5^a/&ZtLQMT+=PGElB>RV$*c+kTyp*bP+V!P*@PwA94:tD9Q5HiHpGJ/
F/Xm\+ dwp=S!MB\dq^<yJbX8!YAQw\T#k5TXk1j1y9==Q5dKL$YcNcEZaa5R4:G9@INbXmu>+Mean9hMd/6Lc>
i:IE$! mJ>wXtT5\5ScJ^nh$akHC*ZW%XJHTt%e$GP^>K#1yS=GLkc9ad/8L4YiW^1R&^aytuwq5GQjHNKJjw5t
+j1w*d 5LiMcTkHFEYRW<+><L!KqM5^A<#H>\$8amRC^=T\Eym^!TAT^8d@@Abk/e&\j*M#8dl+M=RdZGHe>>W&
Yhn:y$ kALB+#6uXLSL#FFc8jH@!M+hJN^Gj?hJm=<%W^Rc9eiM*LX*GZGPtTbSY^kp6GyWQL\wJYtiLWWDI1/C
?V^1Cl *NCEb9>#j/6HM$dCW*T<cShjMFSmhVEtcp<bF/&AjFHnanMbVQ/n^/Ql*wl6/mPQCL:wSC>C:JkH!1^C
4NFG5L a?!T4iJ/pF4G++j$LLQmpLWbW$+u9Pyy*K!SeEhJVITl@dLme^mN5HbZ=n!ASYlpqpKIFTF8aYJXCaI<
YlSu?+ HHKZaM9JaV9RYHl/m*X&&wj1+DE\+>dPwhVn^yl<A%m/98Hj/@:%DScH\A+jn?\n+MbV1P941*dbwtG9
#jN=y% h5jQ/4TiH4qpJ!IXuHWCqNBk6hC#H#tImpNGn&D5c+#>mNb\1KWJHFe/R&%hn/SFAPBmYQb\w!:4?Z:T
#ZHEDh A8MyyVlN@:ujN9H=a#%ql:^q>I/c+a+mH1H@bn$Sd*M>EJ@n>WYel?m4biM6yJhhB=1:D>Z4FN#!*W/H
:jFcLZ <ASnLHBth6nmj!:C+/AcjBV1DJmlKiyM>blV!#?!Z<LTeEYE%XFRXtLnc4cFJVaQP!^+YLlkaq?a4caa
FEQ6BG IRA^:%1du^SQJ46hG@wIeZ#%NAM?FFHQ^WS6ByM@m8kKtaIq*k!GPE9H5H1wZdKAV9ylZTJw6LX#>*nk
$w!FA: 8I*C&%F@#CajX#aiWi5$CN9W6Sb\a9@jZ/m9yV6Z<^u>9AWWX8lFHBCeR!eeTLZ#!hBNG>/qj%>pk%:9
V@%p8M 4F<^%bQP%NPtBbJ6a1pSAkuTiBTXHX+MeClIj#DyD\aCt+T98YuYmb\XTK\V9KFYKYyh&XcXtcbPpXG5
M$e#YA %L*cwaLa$5e&i?dR:VVyRlWY6Z*wMueGcp\HeBKlDS@IF<hSARjp9qNaMFc5>MF\ay5>>VjBZ<>IHj8V
GuqDZE 5bJ/&GkwZ>BaB>F#B4klhnph>5Z+\nVB\%:$y#k>qQj@KME4W+qcRu&%9ylC*cWy@5GP@T8aY8PBZ8ny
KI\wME =DA^^LdthDRNE$ycY6GTq#^!N*15^S$p+\CJ>a\dnPMKZ*N@M&nlBPL=*In$nGCjkb@VXi?A+/iRPh%l
=lQe9? GVQ!+^4AR$<DjqQh*ZnZ%#kK=WdQ%iZRC8?@&N=ZdjhtWn8$DpW>mNuK6$n@w>!BbWqe8<=Vm$5HJiw+
H&AiDG a:W1$#/4tw5bBScjn8Fj6E:HNTcktL%GHJ8HbSJMIZylnIXcme:KD:4$lC16=%n9aaWBwn#&+qm/nW6Q
PRwT1W I\RJ?5$&:h<M5jqN@wC#jZT^QbdEVh4AD!HtGZ^unch^=CdbYi*RE+NhRKj&68FbBJn6Ap=E*pWQ>!VT
y55:4/ ZnY9j$N8VeYDJ@1WAcj/eQk:y5BT=MRb5F?!h\V6ZldaJhdY=T8ZB#nbLp*p#^AYtPeK=c=bpH+%LcnB
c%8ARa AnS9Bt@i9NHt5DjCZHR9#HncN58tuDNmKl9MDYM:&+F=V$aTSWFCC%8XtttEi>VyY&TY6NdLbaaFe^Kw
W8h:cu m=%Yj>Q?Jn&ynF%h\SQ:%$A8V5RYn:wb>Q?a+qViwpByXqmh6IB+\^Kqn:ZAK6AVeVBKqHc>p4YM@J^q
BI$aC^ Z8dw1&HQ%DZP4L?i+5l1QXwek\HY^w>WNnSaA#665/==enL*PPl$8EEJBd+e<NHHYV<K&9#5RF=^*hlV
@W^u!B m^!d4W$1!ti81MX^mAFnP%nmMVbpQp$b=+qaE^YV#qcR\X=58IaQC8BIh=w<%y\^qjWh:kATe5EN?Dwa
<nXi!V KFMHN^e#by5wcC9W@%taQNywtTcRhCDKFaTRJPcSuK:<CYyDD6?TXNZ8R8e1/q4Zd1&c9?p=wXc%K%uZ
=PmC=N KhkamXIY6BbbJ1^4=A$AwlIh#m*J^1=yIVeR%?P#FA@\kQ:AXBt4C#B*\V5weWw&B>Ecn8dtw6@@l$G@
Mdb#wS @#8Gm<<5XeGyNmhZmMERT*N$+VhdN%q&^6+plSTEy#!9YB96tWXnyc^WTam$:/LYR=>Flk6%4%y1E1CN
K^I/P@ dJPi?#kF4AD?y?4m>P^$Sq6<5Q\E8*?EZBV8Wp@p%^<mCIDAB4dBuH*eYHmecTbbXHtkBqkp8Dh+$?<B
etRmd6 I8JMq=B^#51lSHAX/59WN6e&6EiJS+wW8dbDa&NAmcM:SB8ct6W&B1W=C4^<@Dj8YtdF$Bc:QRYEmTuV
5YbJHc c&J=5Zq>?JR!IHnC59ay\^*6aHQ@DuT$jyBIlJjb8cuujAYi\L=tjLMST\h>:jjEDQeENktW$LQFZ!HA
T&95E: S=cKhVu?KZTbMVcy5u4A8uPq!jbD1jZICEKBkZk&ClYcR+<=9FY\RaYMJ$c$=L!hjAI!pTwYt4DKq6pJ
<M8?RX <QeJM*NMq$8+I<Ri@LaSE^DbR*+1b\y+y@=qw<i*cdET^%+1=VmVA5iMkdi@G%#@Dl*L8nqj9K8PtnCF
5D^mQy Vd4DS65bq=Wi6KMHMCqjK/Ti6KyhM/q^bLMCd\mQ>GDDlZbZkhm@<i^MSnt8Qm#Y/RuquWK*Q^TRYIm9
w9qnhI WI+dAFmq^JwhVl\$>wd=nKEMum&l1:@yPE5n4DK>AiaRXi%h>Hn5tkS$#/Yb+TNdn6Fq*ZD\>YmNdK\a
n*VTbj X&Xd:hD8Lm#w+\mW:6PHDBj5<YFh5LdCtb+1X6cl%6Y4&B&$!F$::NiD#PK5\AAh6u:\lH^%mwBQ@y8T
kLK5Mj &I%q&Vae5D6kL+^1$=I6dK^4uV6b:J5Y56jYW5?Q*k$&#AX%cZkaNXNhE6?$tNn%5eZYhp:Gc95LYpQR
Q:RYF= a!kW96wW8GaiPRlW1:Qmkk+>T#:tCa4w^hT8luLKkuGceuAVIa<E4ek>IN@G&ldB*5EamqEbED%JA?&H
QpC9XE $FTL1cei<MawAKiTRKS6@pX+K@>h>//jbkYZ#6Pd89qqtmiYh<\TX!4G&Jqpe:YcjPGY@IlwAVE1E$1R
QNB=P\ W#\/$yqnm*^K<6XFPc!L!L6!9wFuikdahkH5BAtie9RDm#+aHkRHX&KHp^%ubXh=ZGaPVY\w^S9:L5E^
>hG&qR y4d>uV55ldE+^?C^$HlElHbqe?qM5eHZ85y#yT$5F66qdpd<\F&yZDKQWL&!^n:hRBIVH>YFNyV>ljXZ
i>58>p w:?!h6a6M#Cab$^%i9=\$BwiBl8S#pi&Eb&*JNdD<RXXh*L:5&l+^TPAY?PW6+Xy?c+NFIVB9^N%uZFL
NJ^je9 LW<TmyF\P8pk</58MZK6+61$^^:/1D&EPZJC4ZNV%m1pJ#q^udG/bP5T^HqZYpY#*jwa5H@tNnVtuJmh
!%cn$w AGP%C5$qH&^c6CaTIMS^wPe6LQtb&bbhBDnBA&tXZDKY=#N/HcXa^hyDPWZhQj6k!NGVGmchAXtb\la/
Waj<<F G^G*9bc8SMhS4^Xuhc9cDu/\i$BjT6VX<qYZVWaEXVljkTk^$QPnC$^FCX<$B+MBkqq1VSW+BmDa#X\@
4B*Wni Z1b?G8u?w6kXXuRjh\iy5yPEB\#&Y*w9lK8*qbaRX=y^Iq<b<nAbe&Vyta&F!:1$8Z?Zh<aeX<!yCe!h
+yCBEE \k%nM=KtqFuP%BpDH49?F>RpHhKMNb>S^p8iAaWXAW!w\i*p%VJ%w%L<k:#m:c*YYkl5PI#QAyZENHql
%*yKbF VtdH%mhjb/S\H8ZkZIdF<YCaw?apBB6@FRknT/^SD#^84KNucIt\m+#cNRe5buQCYM>\muSP&H4HTt%y
4T6HBj +\+5QV@HyLnT5?HqVb<%Fa/k*WL&JMG+F#hRyDy>5h$F#&LKq61AS&8wZTbcW55LFYKQB^6akIi^?6/*
/5>nPV H\Ip15jT@P5KkR:BBGwVnAFcT$#GFtXdbMi&5$nhJInFI=tYRGP1*ja+5+9nd4McP*t=ccDTA^mAIZEc
yu8:XN HK5himJ/EKSa!bynb%YKFjHC*?%8T^@GMXX<KuYjXqqa<X#L#l9>WE8M\&M9L<i@wSYw1TTIC%umcDm4
APa<1q ^iq$Y1inby&$FF94DIDXANwGS>maX$+1^nT@6YcdNN4JhQ%6ZP4=/ldb/5F1VFtWRA$X!hWqT&t8:dIm
\^BW#L 66Q^dc+^EbAt?Swb\GVDJT#pDCidc<:JS<iZ4\l15%qVX=*CD4njQ>BMmjB$FS8qQASMI\A$FL^1m/KP
:+umWJ Cn8dw@TYmlnwe\mH8h/Z:W+bb<F=hA5aDj@K$<M5IehlE:Fy+SN<DR@NS1J$m&/B<t#9TedtP=!aX<jY
?Ec$n@ k$Tl$dRR5pC:CHttMV*5Sl8DiPD!8dc!//TaQpcq^ym9I5Ye=nmiqKW$V&lC$+LhE5VPiG1yJeG6c+4:
/9!HAq bqC#mVXSE?8wR?HY:i8?LD*H4GTjJLjJ^ly9NA#L\hQy%5cBY4TCt=Qy:eXa4qy*4qqkM#wjF!BH/n\5
-A+k6D 000c403171700110334 Page 206 of binaries2.zip
I6bKG+ TcWh:1>:*^KLedyKC+k+&&\F^K<NZdbhVd/N4RBR1555tH4T!E#=!qWH:D88hI$Wb\kL:Ye44Y<8Lq^j
mnwpp^ PBQ4qe+lIDh#BFjV=?q61kFm6GVbmY$uFnMYtlnStcFTZZP6^&tkmcuI5>dyGKuib4*?4Ytcyde#K\^V
yw5T&V YEX$tZMm#T5Pmna&p1ESm&8Am\>/pJ&cYwn\pdQ8yVXBc4>L$jah5Y<6e@pZD6dEc9^ZT?9<%\=>Y$:$
tjy48l 4C$BGj8DT&&%+ZIdT%dyEm+46cLJ!TC^hdiNB&N%NM4VQ9P\hqC%/15aZa18eqVh#/ylub*EbymNbw5=
qcJj&6 tKZZRL/GTJ@4\hK$6LGi4lTXXl5B5b#lLy&!p>*CX>#PLZ6cC>h=yp^qXbHDBn!6RXTIEWS4mG5%V^Z1
NLYJ=& hlt!mc15Ak$QR8%t9Hb/&y:dAQ9HAV#c+Xhdq4A!yy=+RGH#GmyPBNld<n\lP*^GWY%lMSIua>^eYX*w
D<:ZNA mhn5EmT^\Imq>c949qqpYuq9R>%*d\&mla=wY:&*6DN>dK/EVaP\HaWL/>l?GVt?wpHV##%9*SLch\&5
a8pqZE \c$incwND!6tuNk!@e4E$=GE$@F1H=5PE^ePDTwYLp5Sjcbk>MhL:iC%NXJcith@p=pbhDZaYmqdJ<Pa
WGtHi6 !D\t&MtYuTYFtBKjedh5Td=G%y4Q@W6/<HdA<Y1#\tPTjGcc?54YGR/V1dlPY9t1XK:W9&w&SwLc&N4&
4P*QM\ pDwTekMVRml54hi5*Zt%=yJL5$c8ma#Rw@!LP%>hLq*6hM*y/^XZl4R4y/m\#!/WWuVE/VkpuGHQC8*M
4VIdud 1ZuRTGpFuMIbakQFt\iL=b\h^ttPtmqlek#u8d*mNF9dQ>Yw@>GD#!\>khcI\5bFq=wiSZ5ilQ>a6lBP
RGEZ8N 4bG%*SNmpc@j<Vp1h\D?LP:^bEBiAe9RFnCt%6Ny^XA/NmT&bpm%/*^8#j6V5te4eQG/Hn/Y++!1\bq9
@$>i6F BYmc#6V=1TF8pHNcpcG&@kTwCehR!th4QCWG!QV+DqWlBk:wp4bB^TXaWC4**RC68JGTh6mWqZmY\JSL
A#iCki ha+&CECtbkl\I44N!DSTRW^SYcwhnteY^<dZnKQ/P=+TcM*W\6jjiB!CJ1TDapZ9/Ktqq$XPHAuFX%$$
ehl=8? %tnSnlwL1X%mpNkPmmX>VCJ1%+#mlInuDwG9P4VFInF*LpDHhEp*<t\qlWjilqNQKyDFI:6aMy9R!F\X
9M1@8$ p<qZmLECXiCt1q$5q?a+9D6Z/E>J@qbdi$PMkpL^tDdAmhXw>Aq%4S4*A%wbT$JV^%n1c<XGY$\6/^+l
4kZ\Z& 41!*FYbe?<*C8t9NZy4W/6tbd9nLkJP6!6H%p?y8Dnm9GB8yh1mneqJa^\+wCSdA<8Dd\l4h5Rw@yZFC
*J^&=9 nE/?@w?hAid@&P@D4AmnK!:i+JnnTYQaI/X+FaaIi\Ak#V1l#:65LVEuRYFjawc9pVbYqBaYLN65VaCb
N:8ajC Fh&8T1=V@quVEnX=%aAiI95MGujXa?:tNI^a*SJTKXDqiKDbA>/mRuPJ8Wp\#u98hWlCD$ZccRSBjeZm
iTb?6i DSTbRP!4&#GG&J*N?%m&wupuN8%l\ppV9:1/:5Tpie*=#FmdlGKZSVNLk*:EdPd/%DtZYB:Xm#h!+VGh
*THiG8 K@cFm:=mkX!tk>y!q=B*LCu>d6!/$AN@ct5K%X1HKm!JHZheXSFP$%5t=Ewc%yDHETL=#VTM&<WqyKJu
a9iK5u n>T1^6b/BL8EiBFQ!NKNLB#Dc$hpKq$?pGu>=#pDn99S!ZBM&M:hYWnimYe?amhE%MIH>ySGRjZw%FX4
PtP?wu IuXh1*8QT%9n\4=BVW@pF6Wy5j?XbeKSY+w^NXbHlI/y81Mq^DX@KnaK:ZyN&=@IEdtaBqGVwi#@bq6Q
/PKL^t 4YMj5bwu8^JwINy<d=\M6/jIKbdADedME+W%a<hl\dS9XPYb&=yS^W8C$q4dBT9NaZEtQYKZ1SZ4QMIJ
HT$dyl :=#YAdG\mHCyIbLG/mAKQX^8lThnPtk44P#4c?Pt5iRYX%y>XI<Veq!4hIc+$p@PM8t+WFV^9C9qBRQe
*<#Jiu Yy9hG1T%PMMjeSEAKMYIB14nn#bSqdt/EN&5t+B#RIX*CJWPm>L#ei:Ce%Na=HHa\tL*tPiHIl??54#y
S4kIK@ !tw:hD19!E=wk&LM>/!51q^#S4*SXXMIM8H>w6LG9!8H+ubBIHbaIY!y%//b%qeXt>n8DJNqKbwuSep=
Ya+Np6 5QjMBcbautcG4:&QyW+JY1\d8BKYTQH@>1&/wuNXZ/VtDqQYe/m\hu4%!hX&lNSX!CdWYJ6t4cAMa+n=
wJGeqB nd4l\BX:K>l4wF6HCk9F/Q*Rwd=tL=e8?ca/e$MXXH$XWp/aJpQQN/1Kw4VI4=nAL=&m#8J&4nFYcuWF
a\u*uM SkCN>Ziceey@E:tti9Jl^nHemDKM=6KnDZR!=<@BTj1kw?5:DT$@WY98TT84GHbqk%/qGdC!hQP>uIqK
b^\ylC YXFLih/X6wd\*PCajNWnce9c?8JklXHP+RkblnTC!M&n5LDd^5Stc1DMhPDQcTjDk>>cJ6FY95RTcRuG
u!Rc@W 4+#YdT8+:Z=eYh!?WwY%1WISZiBTdj8kkhGXI>!\E?uCb8bcMkdhGV8de=%465I/J^Ba*iQYA8a/XPKZ
18un/V *M<l:A&m1P4?MQFT88q:a&^yaIJ@#BB9<6F9&CwPB*JmpST*R$BWR?Y5&:N:%B=dLFAAa&QLQJW/*1VI
<ZwmXS Ap>b&aahk4BIe@&KFN&jNA>?t^Q=@@dH@\6RT\MEFAACAAkAD%b6JVVdVIFK4kAAqqpCACwAAABndGqq
cMNn!S duS#L*BueC>*cY+#Mm>RS%BndC>TbZM9e*B5aZNwPGJyhC=mdZD5uR&MHhX%kA<XRVm#lJ<?pFI8dBIw
PGR1nE hqJ?#aJJNW4cm8DZ/$\JAYK:Eh&+#kaG8kW5a$!&14mnN9a+VuTuLwHHpC!bjTttLX8T&FhtVKYN&5Yt
G#61bK km1V8NTmpEwXYn6XG$c/ikYEJZ48@M@:YT>kp*m==?&?ub@:M?>?>=^::yp:d*@Q?6dcZ\MqX=<M5A#@
5SeTnF 9uAT\LZ+i^Ketl#@$5*y?WSP!u+V8V@=kj99V@?wq#1Ed!e9MYDwDBiG6t!Dt!=5\%dZledb??GDnTce
I!9H1B %h\KR?=?PPY/XZDJ#X9l&8$HaQ9&j+c#d6pHR#e?BmMZjSd?c6>B8Hu4k#C$J+Jt5\pnJ#<Cb@:GdZDq
RTYQ%: Vj6l@:QQ\qudD5Fb=?!E$%dcePtbF<Hq%?Q&ZV6l/It@k<69PA#NH^&GJbe$+WM8H46nK=#<qh9l%Ma!
d+CL%D <H=!CC:ihkBYjYMuZLd%ejnRXdhBw@EKjQA*Q\Ed@8qq?Hn#Xlm/&wM4:6\JF+!5BLJ$J*#4!V$R:j5=
haTiN8 *MH@FydjiSCiiQE\@QwX??BnN#$Gb&=/Hwd&@nh<:E<iB:4&Xqn#S%?D$=56GQuGG*D&^\Y5@HAdS8+>
DuRh$u DFhMQk9j@@bBPP?&ddB<*IWD4:\Cnibt8Q#!@jD=5V6k/NGhaC^jA<8&QkZu4hkEc:<5aCnaB<QpB4nk
&uVmJ9 wp@AiihiBNh6?B5+:@^:+T5@jSM8?<\1YQueEVl@bAiM6N?EP+JuaGV9EVn6nIhk?*eik=Y*@A5ePu\a
:6uQ+L Vn>uDb^&+&=ae9a%<PR9npDnuyhBQLMjQ4Q&Tdn$:n%\%!M:\db6GLw:lM>NlnC$dT@RDX9lt:8jlT89
uGP!dH twa44>5L@BCYP:Ibu9#?D?DCi&cl5caFR*i&+Q+9#eC?Qc@A!MnhMQIZn?Dj9+aX8%/EpSY9\+4dN5Pc
&YjwBX T@<id6u5\5c9jS*QneDuu*kPd6?$C^:>l@<C:=:><PXQ@SD8@Pyj\1/>#<DR<<@D^SjQ\i>j#?HC$XqM
:qJ+nW j\P<?NJL<N9pp@CjB*<BW%Qjk>MiQRSD**+Ed44&Idn8V:HhZ#kEG&>/Gnd<:Ale</>HaHLQM>A$u+V4
D^>:i8 q>+N#bH6$Q#l#?Bp+%#kD#\Ey%:*l*D#/4W\<5WnaN^/H%^EN<Hn$S9R8QwAZH96u<G?@*pN4ql?EQ:*
\l/d&8 =@<H6>wdajY/:<KcDRGMN*hn9#$Ab*:>ADSGD<Dy=&/CK@@+Bhn?H/@B=*aIYLL$p@DSFY9k8ijikJGN
NqWXFM S?DT+CA5*@\\ZH@HJlmcPkBZjZa6nQ@kPhn&<FM\@j\LeNj*Run1/cjl*t<?CQ@+^E9\+iE6$Fm>FT/=
\4*p1F +RFwuLMdV9uC:VC$K+VL%^&G*%y#K#T8&RtN*>pHF%\9+II:>$Bn^Y+a6q6\^84:+JLj*R>D*>pL!^><
yV4T>T Cn=!!VZR9G$**Qn9S+B<>CFaij9D<QVVS?ADb=<Ly/#?Iu^k<%jl$4Z*kdZ&Z9n^c$jk#VjjlA&d:pQi
1d<NP^ Ljn86l@D19Q@AH:!$*?DFeMZ\?wj9RI#M#Pw$Y<qQ@DYY?pj>XKH%J8Y^TqE!/IV#XX#%cK=c6Fe6Ym8
qJ8ML< YnSZ#jYaCi<+ut:W^ejXwL!qG@ZE=5wbIZTHb!Wd^AwI+!TILKH&yWj+MI6Mq1a#hnmYaVpY<S!uRTJK
c1Y%1@ CI5ICS\HW*a5T=WYPwSGAbtMMFY\A<8np$/$I!B8bFBMltX#E%QmiW/hTR*8PHK%PZNMX=BIkdE=pSGN
EwHbZX ta^JJEtLEb6S!kTieTT^LGyRE5c5FXCZC5VTmn%MVA$Yl#^YyVt^F<RYMS&n\@EIFT=8Cpqp#IK+SZba
Wnc:uP dn\yBSWeT?JWk#6?ZKu\#bkdNm&=8na^lPKKm8y:SLdWGdZ4TC5MPtawLM9!dJe\*=JidFqT1l!ImZa5
ZWy:MQ Lm*VmEQCI+:hRaTCJ%p^B*eMKjGk=+h^JC%N:jmP4\+*akM=JwdWhmn11#BC%FiH?AG^ZhSFqT#!WYZh
p6e4$& FliMWB8%$+$=<T&*+<YM6ZmMKw8JtPP%a6eJjR5Va$b18*/EuTWW%Qiy^T$4nCt*ZeEDwdZ%?HJqn6Wm
C=ITN5 8S$&VR5%!VIht%m&+^5<NkM@+ulG?qFkSk:FpbN!^=EWp!J*$=PP!ZDHXKA5TZ!jTB:/npt=d#L5FmIT
eYpFdt *HJIbBI8yTRPymT1AE*6?HKqAnW9=$wJyenHye4\+tBKSWCwt/wY:1ubn&8k\+!@NEqJ$^*miuc/S>PW
lPLu+H TS=1CBe*5=LXt!w:6LM<Yw:4QKjl$IS4ypE<G@uTjY?l=6L6b%nSd!yKWmLXq8h4E@!i#X?>RwXw%8y9
mnIVuC X/ZekRjLpyK!1c8BHZ88maH$knIG\WQhjw8Ac$5lDX15NI*w5j=TSji4h<HXa?n#MGS1ewbtpb8EVFJm
j4%niY wF9n+b\FLcXuEIMqJnlkp/WqXqpwC=QDqIR$=YB+cq?hh5tpt?\tKhGu\8%J=XtyMn!D+c!I5i!5KkLH
nX@Yt5 c?dl8VDA/kIT<pq1K#M>1ZKpFXIhl%w\X%Q55Kkj6TR^dRedMwwNuLkT&TGPd<alinc?JB&HJ9Nbup^5
1d!NjE WJWnanm6mITS#WuWel^ZIFM9>wnwEG6aau+:yLGQySHMdHcwK6JZCbKPa\nGw=dHl!*ceXwYyyclCK#I
yNJ^AH mwtub4AN!?NeiFED/@JD/c5K#R=uykc/RK+5Sq<q<LE=1etJWLNMuuA%ZiGG5YeqZG$9eah^t8paGXiE
:$%+>8 +!hb1i*SPFZC&GY^R&*tie4Vbddytu/I:nCNGZcIlnBq+kqHpipVKtNKLaeLlG#a1KN^ECFe\nwp<n&$
edMe>B Eb=kmVPXe4XanHMpQRhcKNiPt48kC1q+LTPtFbw5WlFj/Zk&64Yu>NWmmmB=ZW41Ty:41?tL\LXN&=Ct
!\qY6l ta:Ddl\/pYMI!@JXHCLm*LGpFj1E^D^TpiA++iI+Re!y:dmGmA^ya>W1<pnnkQJIpMBER!FNchtycem=
^Ac9BC eq9DjB6eHeZX5FZe^#ab/yYFw=ynM?qVu%5^6mtLiTmpCpekK/Qk!9%RMA5SicER1c@qCStl1VT=nD#V
-AH5NW 000b5d69be000110334 Page 207 of binaries2.zip
D1QlQ: CY$Z?cHy^Z*dmFTSYIp!EXGI+*cMYl$H4m8+SJJS+McMM8=V!<a/5Zj=VnbB>n$be%NTIjYh*:hnl=Qb
Dc$e*e VaVkGHMa+T=/QCHu/L%+1HA1PMk^pd4%J1WXwZqY+RSWaVZmBYlhli5HZ1yLZl!H1G/GbhEAP\qHY?5T
bVJRja dlmS=cIdlHTJXAyLjhNWhLG!TN&u5>Cq5mLKDAQ:A+&\p*C<EA>:YKc9Ibi+:YXn8=aF?W%P^?4ZZmG4
\uV9Xu ^ya5SbNGCJcuueEmuw*Yq6qSSCI$9yph^mPbc<N:C=Wm&:DmjnZ!NCnlh6@P<jX5=^*Ne<K?+RiYSjl1
nBh^9N $APYtWLZXjMnR?Guc41TlaqDI\$W>^iii:NG9\yyNCCuy&PL^!YP1EX#%ZLCeR&pun\8P1/l6GQ69m\/
Q?M?NR 4y$+n9Wpa>F^hSB4yJ6!pZE%qLd1NaKLnT9%Ec89G*K^eXXGPNd4W^adX%Nl%W:Va8PccC8KZ6P:1Lnt
QR\*tm YPP+wb9!SPZ1BX\/\++X=IF&Pl!Z\uSduwBeKi?IBJ@JcB>6ShHLFW+<45!!W*lPNXkw+=ywlV*B8QIM
L+S^EK cy$15iyaa#QS/+cS1uia/:qEcST*VwNp6%ld:9GGdFV&nZT@*M&jIGlp!a8FyI*K6cTq<Hwhwia/d\K*
&+P5\p qZEVdIDLqE6CXDn1&cuZ<:5A:4DytI:IX$LR!B^&VD?iLA1^jiGL&Cn/T4Kj%<Vm4EQR&FLF&pXCYk%e
XHw@Zk DtM8#Jduiq%Xceic/:#KtqN#/4jl4B/5ecJ%aT^5Id4C^V!84YpIe%#EVBdIBMX?XA>e5TLk\YPB=bd#
jn4np& bKMc8i#*&EGk8e:H6SlD=aDnFbGbCkciL\1>5p\W8*C18IP:j1F&/RLW5LnH%<Y%BE=<Eac^W@y^Xc/t
MCqQNK RAW64aqM/lCc/#!uc:w+Q>c5yh&a8iY>&CCPPIyS1JpyedikqZM>14+1^EF5DPB1M5dKe/yK!X*N>cle
e1/Cpw SShYqyqtWiPccbP$VdPmee!klpEL4qL6FR\/ywjCT*&%Qe@%myXwFZ%F=KY=Na\\n6!mXN>^WeL<cW%X
uiB$4K JVYw=uw$44:dX%5n6TC+Iut#t^Wcl1?GY:5\plGPp<I8u%bYw/aRlba!wW+ZK$ibKB?pw4=hwLLXEC:!
M#PHL6 Bj?1FJSPZ18V:DLNhS=uPP=#6!dD1y+h>*46eE>Ek%I/#::cw@Mp4=/1b/K%@Yw8T8n:j8*y9F\>8$@A
9aXL?\ IVQC1i&WQZ/Vqq>=4p#$\bY4cK4EXPmA$+uGNhZFu1WRwclCnL4mE9QIE6*c9\yeYh\%8C=SZ&8yNNc9
JV6n\F LFM4+lc>HcCHw^iGZ9&yC^1mLGnh5aEJ>hQw^+B4GHi9lKDTnwW9qbN4$uImW^6iA>MbLyk:#uAbyR1m
VCGw4d %GRLp?@Mi$+cw5!?=whl%6\K1GI1n?NR:1eyw&LC=YKKMp^BI1j<kq#DMajN>@6Za\:mc6nhTtn+^VVX
&1\wBK M:4^w*mF?6LKJMu66hh=Z?F%A#=eVwGJZZP9p^C%KYX%6A?4FiGe6SI:mT1Vce&%T=\iH>jy/^<F6h5=
QqcwcE CT6Suj^tQTANJ#55ND!YQ/ic>B\blNt8KLPtucZwWCL4C/=j%l=YW/SXBbW#\6Be?*HhEZiQ4yQ>B>JC
:en+ha /eJ!q@Vwc/PQ\^#Y#Z^aKWXY6qQ>m<w$dl>>4ZK%?<R>Nhi/hjZ:AK\:9qbNZY6ep#tRY+c6bB?@#Pk1
cH9Gb6 u&eS1\y#6<LaKi##RH*q5X/tQyC4&S6C1pRk14i55$FZ8CWh$VP?<k4=P6iK=%QGtGt6equS#KBaeDNI
VJm+## Z+$<FKc=>uLqZS:PaH*%8qD*/K8Sd\m*D>jKN%=mGq?pB=n!t8P+Xjc^*A5!mw5cwK@J$\it^61jc/jQ
a:E@EM :Vt*:@k18@T/4:=/jS*W84/1+m$4:TD+^?TFPwy1=8L?\kB>qh*&SHMqjia8iR8=54<@dGTDK/%^:S=j
KFS1HE YdjV6KTZ1<4w5ZRhM8cVZq/:WS8cC<l%je*uPb/PW<@D%iwP?aaC&=lG9iH>VnY\MNAjdlVV&<H/c1u?
NtBC:* +CcneJk\!t81w!wi<81!\!Lq&6E#%*t+m1=dNGwC1SyVSZ%<*l61>LyGah1q4#u5!EFS*@wV>HJNa=NC
H9=G11 bbdJ5G^YDT/9PuV&RD9MF^Ktj6>!hd9Yn1cBymn=a8h/hDibK6c?Q+qZPij/KqPhy9Z8\1ypnQSwyN:N
X?BVV@ yF+4M?l%jVX4?qy$1KRLlWtH%HiXBuG6iL+KT^bSSE$%?5Yp/5+u4%n9t4+1JXNB@4CIGdF1cI1q\!tt
yRim*n NDQE9Py$Ncy&&C!+BnX>bepAw4>Md^DZSu%6m^u*tjWWDH&n>=nXyc?%GW&WP$R%P^!qBlSNliDyyyj#
hi+1?\ 4@udee%9pq%&YQWpQZeh^LY&NJmd*i9T/wM4:eQc4w#Vd4iQ+?SDaJY&pb6Z#CLTttnP#c>WVR8cTbuq
S1#8Kw m1hMi+M?<R@N6Sd=/bGw4%d*6iG<nCm:PS1*HCH>Hu?a=VwbqiP9tTGKKqNt4^lX\@wE1#y@%X>l<uc+
ADTAp1 h9$#qH\R:5hX&GZM\5mQ5qLnbA>ZtZeGZn4aXq^Eu\wuq^j/1LkKJ&/qD&&Y>?pe@jV<IK=>F*%*?TP!
MK$:1Q Q?*W8QLa>LKRumlkPpZMI:?QZ9GdP9tk/=YF51#T^P9tyRQPC5$Xu4L$!cyXpZNNc6Xkn?aQ>%?Wb8TD
1\hG%= d9iCee>K5KDTPJFheZl+wcXtYyVliYuI#@P<TT<5i+ljGFLqBCYAk8J?cqVeGjDTPZHlyyZi5ciZ$A*k
?Ne&/5 Gl=6eA*#S?!/F+^uPhM:+V**WC&DlE+Gy6jYt&XCZw#EXtEe@IAa5kCeBWSw+1^H&bR11JkTV*Q6+Wy:
BRQHLy 5Xau1WdB^KJ>i+Rw$=RGWa4c4V>u\NM>cb!+<M5#j!u\m@=qXH^^Fi6\$n=Zte*TJCcq%$9MF^@8^cwY
GcDjdL 4/YNc9W?&bR5L\\VLK/MIqqNRRP89nM?P&TEacJZRblLZpYYQ!86/DHeemLJ*N/K9PTd^/6SmwW9eu!j
ZbMn$G ei$^^AWjtw?>9u#Z$@>c9PqhC6X4Z^dA6h6K=qPWaEhmVM&IH+9lm@YbJ4%nEb44A4kcw9h=bYI\LnpL
qCC<H@ *YMXy&N>ypu9YLT?LwS4VYGQX%#8YP1465ML+qy%uMV^i9DdeI/lHbcc/>G=!9eCK$ti%#6tN%>eS*N>
@QiGMC P@Gt+>ya>Fk8SbKc/&C8T:4C\*wN&GLS%*J5>T*>n:aZDhjMCA6H/8<AZ$SeiaKWcccLm&5RMXi9D%1<
84FlNh eRp6t15Y#XYL=1yFe>Z!!?P19=d49ic/be8YB&19XKcZL5%@y=htd@k/PI$@B\@P#1=TQ<%XVbV%#jXK
DBl1eZ ^6cQhW5dZ?9c!*BLJYl?bLa=m%t^DC^+T/%m6b%9%m=EXV&h%blXq%SYTFy9i>uw%MVM?Qm8<WRtQn$^
:q#lAB <Yue&@X1Q>u%/1=hiWyMP#+^MVE#NVW%Pne*%^+ke*Nb?c>m9yty8YZ6@EM%5\?XjK1<1R=P#^=WLbSi
FbEEu+ Lmcht=ySidEiXeXa8>JCKP8\b4!AtatJ>J1VY6R%#d*Y4mSN&nQ=$*Yw9Y^8hHS1NQpM/5w!4n$!4X:V
eZ1HJ< &c>/4<45>K#/\a@VdJba1%VVm<ZLZce8YLXY&kk1NYceVa4b5lDJK<>1#K54Kq8j9dBP%jAVKclM^lWG
d<tktZ FIE9>jN18yN6nyhwFhpyJX%k^>4=J%Fk<V\Y1dwFJl<6Q6Q/@EQNhnjTdLQA&y:D9EuP1RS58$TTFy/W
cY=Lm@ Zq!!WF^X&6G=hi&^!15AY>>R:V!KbKhGS=QGXq!uB:ZuqlL1q9wX1&58\Nc\yle/XnJNc<PL!#y*&kbb
\V4J#c E!!Ic$F&6t!y6L:<LY&=hZNJ!/R!M#E%XaL6L?P9=qVVuyBk4T65Hi^e$9JJ%l#5&Q4tbZ@?1i^DFYk4
wpYK94 VbTB^X/ue11c=uK8:XID=uK\/uw!t#K8nMkeet%*GeCK^4c4aJP&Hp$!JQw/Qan1QQw/RF$Lwtp%!nJM
5HW@6= wHZB&5b/NZdL>MIX6qynXtGl4quqC8^M\uRt5c4K4JZNqLbXbyjnP6mE/>SE6:/P>XQbmW^qMeQeP4!A
qtyu4$ L/\<b?QGnT@QNqP5Chwec:QW%#HFhV#yEKt?65i1?64P>ZWm9%=%XVNKI>c%/#c+MML6Gt%5<%EFhp=h
5*Nd?I %j<#enc^db#yHh?mF@qRWW:BkhiAApj\iEMKnCJCDqWZeTTHAEi^pK$CW\Y*ZVDElC:kIa%%\HDneBD^
H1mS4/ 5LWYC/TZ^9Cq&+8IAp5aYmBkD+8%FK/Cpi5%alVRSpyImXdyqFkw&M4Rbc>>*8@uuSp=iWq>&Id=Md@=
I4Q!TJ @=?Q>^pK419Bw<qlL9N9!=ychd&1iNhwCPPqMmXHqwTMYuqF&lat8@\hFM8i&jPSJVVy9Ym4y&@pAT\5
**8EDj PJNY&CLH1WW%!!Q1IhJ9th=dCt!aD*Qu$^XL@l6^%Q!6!huWZG1yW1&ci=>i=w4%%AFTS6\w=N8%R<TX
G?Ykj? QLACG/JZ<y4c^FWdSX&\@n<\CVM4HqC=M4$!TjLDiF5Q4n+L^uLX%T1\W1IKKZ8lLiw?Q5X?N<t8lknY
yDcIbN y5?y6C1=plA4Fu$bdS/^cCAqAXYCFa1XZ5#AI1:FaBRWbPtlL:@&<MiQne:XqJ8JX/wnI+D&#yeM4ZcE
b\t&l^ 8J&AtdD@JkJ5I@DAR1>q?84KNPcDZw@H1me$LP!^ZIb^ZjXLXyENC/@CbXn$WC=MHywlBhuI^KXM#K?F
P!aBQ# Ek%Bh9W:yW<!9K:/I:wR4XI5ij+<b$4iwW^F!tXq8bw^E!5?%MH/=CwVFN&KY=@@&^>*K+cSYn?^9t>Y
y%?WyV RdHX/pkP$HywpXh4T:&8%F1BAC5jGB=*IF+6D^ppd<4:\85#q9BK?l<+X\^&Xbq\8GDF/Ylbqqb%REXD
@jWY:M 5A1h%1lMD4u9WdDFwBW@R:G*<TutBTP5Rpw#=KIA!/EYC9BDKBc6FqQ5W^F!FXiCFaPXEe&uLDn?:@:*
d\nSS@ +\XnyGJG*QZ%$VG#!qe@X=&></uu/VGDHS&TELi+ER@C>d1C+85l4*MG^&CqGcNQ5DT9KTC>!mBKn@L1
H6\4@= enBbYpdlNbANF=WNTy&CVQYMlRaYSFbq^c9L5tl?6q+6jLBRhFZuFw@8=P&Sh=quNYGNb:&lmlZyp%?9
qGHwKP $whXw5IS9QnV*^<pVemYK1dlnq+dl6?baCubZCX>b<&Zj:A!4EaC:GFNCFbEd@1a$wmqZypQR^aWJqm:
$A\aP1 KP5BQZp1$LJIeiW\=VeMY&j5W\/KdwY<mQ\/%BaLLPYXqdDpmV@^:dC:Q::1GdEW1#!=GlR5k$wTe$mp
SeYF*y ?JqY1=X4/yR4c#p^BX5LGnH1AalA&&net9@tH^NVa\AXYAJb6=SIX1Xi+h:9=@4^9d*4utX=!M:k^dAc
X@quAZ TYZE@yRMeZ*K?lL69NT44jhldQWDPVEFK:l/TJVMk=jD$1XA?e1ml<kL!CEXJcQY=tFcwd@RZw88&P<R
BF8k?# a\Za%YiB^Sp=y$4QNBJ9&&%FXRS>uD\hcp+<<MXZVSGdS*>#WMyt#E8EKWE:apaY/wS\NX/Fi=@ekP^P
NaQQ:p >a/FA^Y%plZFhTAhRZHX>e4!yu!iyW&&/5Da>AC1Q<m?DFM51/AwX$>CFdJ>F6XXL/BZ>1cyC@6ch#Iq
Bij6LD KdPekjwKVw6S<uR:LL:mAKBl6dBcLR\Y^Wb8^dW&9hX\pNB<?DA$I&+$jAuw+9:ZmiH%L#=b8\SM+<DT
KMc%&6 yER4%TyTdJ>\4Z/wy\I$T1&$!:\%5TKhYG<+4jl>PM@CJZJiAhXYQ+Xt?YMXFXhQD:EBtmH6JyTbm1=A
6hQRZS u4VbYy4@Cu>naEuNy!uYR5<6aTIZbyY$*uD!WL4G\ZLd5FZLqAeqCycTZYuZ^I&HCmday!Fk>iwXaj&/
-Ami&k 00014c3d8a500110334 Page 208 of binaries2.zip
J?a#TE tVTeV*::TXeSbXTyYypQZ/ute8cN!^c*aZZtF$mAdYtC%jY/M5B/JeXlt=V>:CZa?p&XA8LQin8KeXY6
@qBbK> #iZXaEANNYHQ<&jDA>L6WXkSXNamKLQ&cD6Q8nV&yuZGwttRew8AauqC9IwTa4>iLcqZtZimHl8L6#S=
=B%PwE wq<%XXT*D9WGI*8%ke/EE1\>j#K^Q6hh/*+!<%e#c^Iy8>NFnLlQW8L$bW8c5HylSXLyeN5KkB$e=<P$
GBTDGt i?V#aXpKKL&1W=1FD5+X>c!@Ld!8T4q/YqPmRX/Y\wy4\lXi#dePZ@9<@Wj99QiH/ei#5:Nu+Vc:i*d*
?T1kBI :Ai:N*@\A:/@E^JelX=^$i\#am&BE\$/*CulbNpJ%1/^*Jm@X6tlKM5ieVC?L1a*Ty*8#Ce#c&6h+N1q
!>ITSw VMGJ+\^59CJePJi4:uGm9pK\WSAbMW6$A%^Fk+#%Jhl?Vn+9>KwkM1wT4cnnm@K>I/+/&Ge#ZjZ%EHqQ
!BXT+e Iy?Zem%4Y1ZN>EH?$V89@56@uL*b/>*5#5&w%b9y>Z1hC^h8j9AYZdh9*>chYL+pV/8cLc^YXCh1IbFX
i=$*ua hR\5c=kR%db=8/:F1V=Xkk%t^GR>@qM5/!=pRKw#*Yl$=w59iw:TcS#@/J9yCcFW:+\9ATt5cIIhlGQ%
wFARKk ^Xjq\qy@Dc$m*p^4KK+YB49<4Y!DnS@/eE!TtkQLuc>d6/ajh#y#9Vt!inQ\C@\K*>S!8wV8*M$=AQ#G
hdLwJ$ lViA:nE6ap8%=!\WZhWieGCJuR//4<T*A$V&=HNmIXk6I!/?PbcE%j^i$?&AXJ&8M@jFuEFdES^8SiXM
TQw?N/ n&&SPX!eZhm9YFyPX?C6mWQ8?Q:wG8DK+m9i+Akum+yN4Fi=FjG6mpXN@&A&#PYK6W4P\%9#5<B$bw/6
&?CJ%C H991Wc!adM@yhiGahit>h?HtlVj?W&VEQDVk8G+n\RaCYdB^tthk<!6M8VY?$cNZP<EIT/LX@Q/9F+bn
&5Ptq8 RLW=>L*tmdpby?K<eDYX1p8l55DKjypWG:J:piV&$a==Yib*wt<n6@uR<\\EX6?GDw?9ncLt9YFWciJp
Zmn<wl I:Nmik*bFlbF#i1^ZZ>S9SdX=mjuYpP:I=NykCyZkCwq&>Zw\w$Chnw*L:!qd<GGXLC/EaeKX8\^pi+m
>NnZXk Jh8YQTnSQZq/uGAZ9#p/&tlT15%tKda?%#QMTtd>L:ILPqG!J8PLVFRVpXL#du\u6>P9&Kn###Pu58#y
VjPFA8 W:KDkXK4qk<#9a4&eJlWLS>d>J+y%?QAi8Hq//y9m/+w>n:=LIGmPnp:P^hewZJ%GFL?*aH9lG&9e@P6
t%Z+J! bj@PPp1e5F=F$<qGAWupmHRLm/HN<+KYd:1Z@Tp^F6L<t%MHW%MHB$%ambKde8bTX!NR+WT!&i$SILtI
Y#@jVX C6j+=Eh$iGBmL=6wN4i4P/TPnZ>w<iM9P*L!=Pjd?IPBCK=C41njJPN4RKZ!:RjA19k1Y#?i=/Q1BWH:
lZ9kPB \!6Q^Ad+XKSej#Zh8SBP>Skn:pt1=Ed8nlN%nN*PdhH/Z@YCi#waLB/nWPp@:=5YBkI8/^1ZSejVJ%mW
Y%m1IT Pd%=eHA\hEC=q6a:e=%PK4Z8d1qe1T>>PFh>tRVMY+6dwP/l^Hmj46^PSW@XcWw5uFn5M$kVFy6Q9H/6
ZCLmi9 5d\yFK\Xlqay%8beQhHV<\LmQK/J1M8%Ra6Z>aL#H$&GRhYwW1l#tkGLH=J5q<Ch9jp@!<j$uASX*$AP
\N<5H6 :4t^uTbGqpSc!4Y>wy!+=W8hqGDuV\LWKRK*PXRc:Smb%LZl+Z%Ip$bwpkVj+u%c*C^PQm1Z#*>$Q#6F
S8ISeY #+E/\>w@q+59&64eAV4>!:K$b&16TdtY%Z:PRPdDQ14!@T8$&ImFZu*#Pe?I4/J<>dBice5jSa:*y1F<
#LXPKE tiMJ<LFGnFLmL9>!bIVqabc61QHBe9k$DNc4yjw9tG6DdGJJ%YI4^tq^wDq^j!QtLt\MRY^6888PW#YT
E5qbX< \>t/cQBZ4#C&%X#<$Y86#*@^>6hk\BCHa%j/4J5Iiw%j%%N%%yS4aX<VF4\mt=!H1H/Xik$%aXaNmFA4
l6+>Vm V&Tde4YXaBFa:^m=l8tXB\:P>j^H$*NhmXBn&?G5A&YP#+S:#IWhK6k8M?S@@nIaBKSkhd&m+q$d=ySk
CF=RiF YjiJY@Gl&yDqB%8M4<*jn/R!^udywJVKpJhY1by%96eKTmZ\!M@e=QtZ@9c@@8GAGDbR*c:t8F#:PTlt
yRRV#e dZ*?1=AZ^ucwFF6dWRPWMl%tQq\w/H1%EE<L1%cZLNY4dcpt9IiBlyDFl^c%!KDKcZMdjth*h$dKWb19
XukX6p SP4V/+#Ml^&tY+h?MhEK8HSXuNuu6icEX8q+&l\#dw44??KMLN@qcR8\wy?mPjHp+!Wn%ZE#yyEmRcHV
mS5+uj MW^X1LIGQ*#qeyQ=>>+?aFF+KQF4Cy6?!?*WeY85KN869JSSA:F!nLJeR?PIIZ1%<F/Hwm4:+%K\XK>B
D6Pqp8 \Z14CuF+i^n9RNF5tG<8uuy9q*Jm<AVeuk!6QRLab<J/mPY^6T9p!6SK9$huu&jd//mG6WICLJ/PWiP9
id+>XW hET>wST4=1>WZm!N?MYj%be!tWnEZa?aqW19b^mRNVG\6Lp9JNtjuG@<dIylHSw1%ZN>Ad^jVc9i6i1*
k65S8l F6ma</FP61dthXC5d^?4X!*/eP8T8aZ$aZ:GT:LiM/^a&<*lY/@5JIS#@4ZjhLw5G$I*>cMV@F8ePKH+
G#e@9C T4PtukcXKLaCbL@WIm\@hNwtV^HNW1Bpkp1YN^bSnJZHW?VE:ajV>!j4haAKYN&pC%\BK8VC1c$n8SjH
>P$y/F \ecjFN<<PeW6iPl8QEh*%8pYdHXSNMJ\apPHlhw%XKT1@Z:6qdVKin+eMGHq^HI@T:%jyqjdR4YPEt5R
/^$KE+ 1+!9&mmATQNc@@yH$m6mC?QDMCXN8M?k6MtbRjG%!<1e4pIdBc1W:KZb5=>/^\SaQNCtC^aNahP1l#Rw
qAnHlp YFI5NkGEaF>/?IiP$#H4+%5A%W&PDmjJjHA1qWt=:wJJ51Y1kLy#8u@LJmu#\SBNtLcqPaMJ^!h\m%N4
1tVWVk E\@EhRPHl&Z@\66lhN^jV=85eMGKy=AFH8i1C%amDY%X1Dq&T>q\HtLX8@@ZpXS:5y$$=:9=j>FZF%t^
1Yyl>^ TIb*8YI4:Bc>XQuJy:nW\d5uh4DVluIu*1Xw$JE&tn!^jd6V:@?Gkj&:>:<@c#lk8I/^Niatp>q54MRt
4h:GN% tVL88n8cHYiS>R1q&w<9d5=9TK4N<b!M8@*e*wR6VNn!6c@b@D1cV$NW!/nt11u+!6/TZ6wy1D/9W9FX
HBX^LD iJtu#c!H?4C+V5dV\m8e?/hi@j8P\+%WEeX<=h?yj!Q@NNQVDLnZXY&JLp1cKk:XLL%hMu@!9I?4j@eP
@@:aAK WdYDX+IX?La5PHH:yWi9hl#uFB#W#>>>ta!myXJ8!uGMbLaWK=YcMaMP9JmbbCq^6#:TS=HXLn/t^T*^
&KKn8* +PbGQWj@naVicn!PY=#&May6KdB$!PwRhVZL:DIPMV+51qa:CNd*BK^/J%#FXA48PmE@j1bi^SXQ=*<a
u>i@KV !ZRhTXXV4W?i9M$$$!N:hDNhc5Jhj?+p!i:!AL84BM5%i+P@wYCqE$VL%yQy&Wq^1apwa^>?@$@4^P@Q
4qtZba uuy@e4JcMTG588/wT=+5WpwpEp$tX!BdH^84=/yTpj%F?<q?k1ZBEFt*4>D1l9=njKTwdVZyIWLPINS<
RBZ!ST %\=y+=5<kYN/6a9/dEmRLJ1>yY?Z/4YwG@F1IMmG/BYq\=A&jjSK!8q!9iqIi\HMnGt9%$q%!H&8$?E:
wj?<n8 hjRtK^^T8ByC4ueEW$+YFyCh98#V1*WMXuIP#/ije>dYuHp=Rp&5?J&j9?J&w!#^ByGb>j&6BeAce+p>
G:MTMy XKL<1jn5Ic6^YCwen<@dYb+8$emc!/qec4MljhP1#J/^A6XPw$lPKnR4nNhVmdY6>b6CR&5A4K*!+cL6
eELWy& n:DiM\wh**X6XAiJdIbu5BRLmdI#Q411Yy*49EDc4P6<8iTiYp?q4pLC&it^#VyW6pcJXIpJG*A#w@SI
#Wc9j% C:LyH%?$jEb5&TE:H5YJ^j$qKJQk+cbX??uQ9@915^R>j/lDGQZ/?Q:?Q5VW+YE*/wk#mD/ZYWEV\lSh
8?8Gmc <eaG%!ykHi@9>JW>F&Yte#$b!/a9?^TL4Ll&#PX?LXFH=*E?dNpB1y/c6$FGLH^aGnGP5KEy5ZdBFZ?S
\5J%Wd D?+u5nTBDjXlJFPm$c8y>hE5*JKn!YRTcwk^%+XwS4+B&SMEL<AFFV5aL?FSIXBNa5JSSda!a1d@%>I1
t=IpjY YP#Emty!%lDX$nS*+4@?cT!Y:JC@BX8k?jjT>9a&!bTGIcbT9Ty#pAN1hIAJLNmiblaM^W&#hITw^y@R
*5!B!B mTS+&4*bYLPb9SPmKJ/V=LZ^j1LVy$16hHyan964w=e!<HllitYCqX^^4TNCdGlG9L11lhjN@aPET\D\
!h+tn^ m4QdC+eLWEGpw/QbdDI:ql!DR:m@9W<ZmGS4K=LJSEm?+1dawt\X&w1#!*Jl8J9KHRH5TCW>jXG?TX8d
S&JStu W&Vjdn^PLlk<yTc!9$WP%A?@Ppkp/cN*HaP*RI!Wt!AShTkl=c1i!SS/#XWlDb:a=%Vlj9JKdkj$iw/t
knD?Pm \bMQX@KkMH8#9kBK@6HYSh?lS%NaBZb%SLpXMPN!T:T><tn@%dKD/dAZwqlb=/DL*C\?P!H%/l&@1W+j
9+8+Zu bCTYTLl4ptwQlhkbnY6uQZ56td%:>?:aGIG/\Jt!XajdPADiYwypWty%nI#D*NQl?wHe%I^TY#S^=AP$
yt!5/F @9k/\e:9mhuQp1=Saj<>TkY:6:u=Xa^&jFZ:8ehEc<RI%%KGKd9CI/\yBE8/VYTHbnMdp=G%8d$Dm@k\
\\YSiH wM%Nu14X<wZN<j$aMimqwFqmK&ajdWDN8H#aalPT4WN=RY/dZc%i$QS1wd1PQc:uG=BnkqXe6Y/m/lS:
RABRmY \c$:yhiq:MbBIt6$HbV!!HyF$b*48MQbGEDN*5&TWcHpKBTD/<!BW=HI%6aYSDcC>!<l^NZ4hTPVAeGT
elbZ%/ i/1V/SlG6CLDucdZ8Bnn4WImt=/h9elQ&wtJD>M*#5A9H!=pI\aFGyYChcKS1aQlTC1Ki<>e6F$uA$>6
#$PiBi PNRa?HqELqwtcNuIaV?>YX#e+FSB&h<eec\:=@1=ubhjP!!j@>%ZZ>P\Y>1#NRkYNlR?ibZQw!9?!8#D
X1EER# MeS+GQ9Am+K1Z!%d4>a>@4ki1tTFaBFZu\>:+T/MQquC*mwq\M%E$mwp&%YVLjSHJ^Wdny*M\wK+TlbL
A\1\&H q6dhE<CYlFbaL8ubbeaNR4XP<NcNJeKYw8%pDMPAnHmZkbZP1PJilR&SXW^acdk6XcdlZi+>q^%#41>^
lLqej8 RAR6I=#bmQFw!>Vca!:M@mc1?WPFQC6#BjI5I>X$5bmiE9uT$MdS^^@95NZQuV:**8HlQ@*<:a$t@ija
\/#jD% lP4Qa4>WYY8D#hKHZQIuQpkl#<idlQB\*8TyS@bN6CIjSlHYCyD%Rtj>J>^TM*FReyYXwdc>&u6L8dFT
hJ?S^K DJKSc/QZS6q!8XwJXEmXWmR=btE%A%F&Cbmc>TP+EdkGF!/I%1B88pjJ:ytkIR&1?J&9G:d>*C9d>bE#
$G&>?E %>jYmJeTnpbF1LQncGJ%^BbDF!ZlKL/c*P=H#MuN+1%>tT<Nuj^*R9XnK6mhe$<i9jTL*$<hMK4N=Kb6
$Iq=6J /=dy&#eYw%hW5t*W?TiN#Xyd!LYk&p&?dBlV>Z@Tl>S4WhP4ulIHpmbab?:EtlCLNmJK4KLCeVnV:w\#
RhQ6%4 q$wPd\^u4<HmYEX%e?LEi8wE!Z:ll+6CcwdAJY#4S*HC%1TtVIM6WT&l8meDK=l\ZM%=Mp*ShZHm5>l+
FM>@<8 >jV4D?=hY48?hkp+RXRYIw^1NH9w8/RK<6/qT6*n@yAG\^>J#^e*>#i+YAH6&JWhwhchujmj#:>N?@?$
-ABYGF 000c97b405e00110334 Page 209 of binaries2.zip
d1&K4$ 1>l<W&*=5/RqIFq^dYqB#Y@IT<Qc*IZJXd^!dM*TbknC=KyPGe1%EcJZL%!9I4+cQ!w%T+uTki6Eyb>^
XLqGwJ 6Iy5J\W%\@D\6Y9DFC#F/9J/Fi+k%SMuAK+L*=l8EX!ACG#nS$etkY5aHY4KlK*MthLmTkw/FMk91TBp
4Fu1q5 $+6VG&CL4=<?@iAikAY8FRwXjD#K&qbwt<kJKnj1GKJn/cDE&:#XYPSWcea$jk=\u1NpQ#=>yjCE6SRy
=CBctq %a&$ZWRHqF?9w1=Y$LKu\tDA==1bdEuLiwXl=S@!I?P44!G8*>THH6mKK@wkIk6@?pZIjw:uSTPJb1KW
JRi^>y &EkpM>wlRXbM!y4laW1XMcZX/9aC#aMn?=A4RWAqkbYS9M4dE9RG*p9IW4TANW=M&VR#GidIAm*ZJ=wI
/^dn8w bNi*tX8^dQWBMD%>twK>V5BT54\phXRcFaa&!5GLQC%NXF8>NLqadNTuiHEDZ+tnuS^V/5h\/#j8W/$i
XFIqhN 5EGaiZ^ABXZ&Y?C!ah1nEFeppAqa<4p$FC9=nJ?Cd=6Pc$l+j5t1ZXnMNWT9aaL>e4TWAK4A%hW>4e8*
Sh48DM &IC1$+MW8MTwbupLI8t!qW1SHGq4cYq4u%T8+&C<9Ly=RbT81R\nT>tcS&ceCJjIq5Aq$ZcJkTW8LA6L
8in\?y ?G&^T61+>^:ei@Dk>Riu+R8e?Q1q6W6Sy4:hmt\$P+:li?$c%V$WZ1QEHy+$Gw%6tVA%a>>WTW#qaM>6
uLK8t% 94k@JA4cb9P4Z#Y$XNV!@J<=ETJb?ZE4/uNQB4VKEbh>BZ4?Q4X1=+9!aZF?wS=^cJunSYqkLbXA4b1h
T!DEp? >S#q\>*WP6N1DHJkKG9kJ1C!=lK\JdjMXtbyCZLkyj1TRTm!DJnhCX1Dw\Zh^w@kJ6CCcyhM$66nVPX$
AP6MQ= N4uP?N/DZ>+D41hQ@=IK>5EqC6d<j<K8N1c6K$*uJ#>tkcT!q&bLbKH^$p5YuHlJTanGDPDK4l^qmlPV
C$DnF$ Jn5NAc@Xm1?Y!M$WknBTE+kt/4>/&S@4VCNI6Mq/51MK6L5c$qAmi?ypRXXIP+SA!EhLJL141JXY?d99
p##lKl ^#u*uuN>$#u*?kNMHN8Qu@h>*9i<=#*C4KJ@bW@4AtBZZjV/X?Y%/X<FZRFi59uBX/it96<1M^EqX/5k
mtb\pA yuu<YLL%ee*B4iSZEjXj:>9X5TGZ?McLaZX1RyZkKYF81!X:&YBJ4EuZIn%5A81k!YV<P1W:YH5M1>Q%
+R?XZk RT?lC4nGRn%Jt^t?V=d+@9&G:6:iW1M:FmNI$RaQ?#<uXIhqTpueR\qeqk1N<uC#ADaQIC%C/\/lSRcD
c=eF#N VL#%y8m9\CBDXFPn&tFAh^dJPn5:t$FWC+A6Ap58q4LLtGN&I&>Zi@C8IK%L!XjCbeJN1K+^Z%*i+JuJ
+?m$4V nVHpKn9Qp61HZJnGnQ*p<Q1<caG9@5QJQt=<I!hVFPhclG^e/=DWcT$pIqR:GFbVN#uttp^p\%w9LiK4
:TJ@uE PePuj4?8YXpuc!!9hQ<cVVCkP5>bGjtb*HhLiZt@y/Glt$C6JA95F#R6E=KwAdp/#DhCJKHJVdpF6pVJ
9EGVZX lyCFLMJK$IIqBtR9%BB6*i^4AXy4pR!EI4QIXWT&AGwaqNQ&DF4mq895K/WcMqY^!:VG1>y5wJL$D*+B
hen?nD #8+M#dImIW8&#I91+L>q\6ae4Kj/a4LR@@\iL>$8@n!XleP&!uc6bbw!8J6C\1wKX<Peu?K4/X>%B?8W
4q>Lt4 e?JSZdpy!V4j&<c#LKy#a5p$ZNy6GQ=aJh4iI+DyY4C=PbWKye4\CGE^GJykeLH5RSuZBpqL^6cLTK+k
5M@4Nk 8C5AIBqnN%/<TN5LEq9!6mEkde*n^:mpwkblJYCS6e#Z:h6BE$P5p&SLuF\%wX*qY@hEn=tNR8>K=ykj
S@*6N: lPCwbi>m*?p>=#aFY#Fw>S/qTha@H\XeH^?8iTmuhiDB%=8iVXMVDchWn*M4HY&=mhYCWMCcWQq1C&B6
H<&6:l $P4>A+m9twP%CG8QZ??ZM1m>9Wc9WYcm8t1yad!8NI^ah&Zb66S/eMSu%R6GIyFAyN<Z/B>J+XkmA!6A
&9YNyM DVG!hI<5Lq/<BKXWWaS/Ck=<BA#!Baa&liknc&6PQWanVCPVIW8MnEW9T>Ky*?YTwIKBFhAmTbNC@qwK
j$dLQ/ PTu@IPqKB6@?5K>8<S+ZSdB4>bwV/*<?YuMkj>P1k/u>5wpKdV5/:J*qmlwuc1Y!XpEH>j&RBi^t4\k%
!$=K=D &^S@kSuPPimtnaVN\V4#hdC*6y=5eG@y9PF*1$:JRuaqbuV:%>y>=u^K<T\\Q=D*=d&nP>FXAuklPXaI
WaqN#k akJQbCZe^F\S?AC5tHlmdA<j44ukSY?LPYTRWciPEp?J5aB5IR?w68LJtyl#9hIY4@caNquRW>nqyE\&
T9H/Z$ aj:\9!1tu?$@<c&AFaId+?Gyw/hMZG9Yh^ytRH8%@k9bmNceY:PZA/w4uHL&duXKwdN5J!JYWeW%@^1*
?p=RJM <5Pck<&Fqja<C1+J1<JcIc#J&LP%>jNE%qLDAM*pIl?XqM=JIB5cZ5wZFY$\Z+G^+ani?TcSGG5>5:/i
C!lY!: R9A+15ELap8lK#qWk6dN9=dmGQkJylyJi@lCnbiynWIaDVD=X4+DpR+jCG\@ctK6/kJyTam8/hkt*T:B
JeT9ij %q?<?i#bP=SEK1FE@@#P<uI^6Z+K!>aPtlMAMQb>LBa<KJ&JFXVNbVE=4XLZyw6bRmYW4yk9<K>Y\8pu
<9D5!F ?K1p1y\Im&j%VhbLAG89aZChCF=Rd4nMCDA+NbX\#qJHGF1B4H\9PFX%?uVh\m>TlJ=dTmT&#G/BLGie
D:4J5W *GS!!S+D8MSbML<ZD5Q\@8j:LS=p1cR4ESaaC%^6NRud+qIJ&$N#SCTRyXbmDd!cSNKCc\$8Vn?d@1Fi
c@tNyY wIyB1:j<FQhwPk!\u61N%W&MKq#hi<:X*u$&@%1$cN^cc1y&W>ck%S4+JY^=SIeA%l:BT4:me%mJ4%#S
y#XPPk yM/%c#8PpXaCXE8B41ZDMu/*EnaQiq#NV/cWpEpV=SH#$L?mW>^Gi@4$=JWD*yCEqpYTVE8A#RY^BNCT
+F$#h9 ^\X\<WHBYWD&<N/*Q5%F91PkNTM5eaEam$F51!A5m8KpG&AnH:9KM#^tVaRL^XPT+>lpD@LX6Zi^w1?y
W>E/S/ +uX#wYVJ%Y^T:hFWW=M%5^VkYk>cdW=QW\?Z8ANjuZ5=1NM\SbYVCZWSl@1bFkqm9Ye\+/4t1uSFVC>y
T>yMQX ?jI^SyXlNYL8yKtc4GC??a4bc/ka%uDE\+a+w1&dlZ>AK@Q:J4Euyt<&6aRi6AldkBWQKcaEcauP@@S8
u:*6PP BN@dy\Mb+1t\^HpL&i*IYW\u69RL8mcXWEdtDMW9!L<C=K+@Ve:%Lb/R1IIM*u!w%K+>Qq1#t/dnPL/b
mbAPjp #?:tH9HV#/#G4Rp4#jPChaqF*bLmV1DKZq^FE?9lItV6i6lcAlIPl^%TVtiS4QP>qP<FYI$R%=G^T%wX
ya1?NK we:d##jWbKbXl$NaSlSW6aX+W^8E/^^<F9T9qmhCT/FS$ph5t>$YdZ<Ey\wW6Xn6@b&bVu<4I@WTG?JC
D<GCiC \XPa#XA8EStL\W/LT<TpM6=bJTi41tSP?Li+#p#P#i*m/StPd&yVT98Z^/hGD>bcu6X+wnRT^#nuBW*9
u4*E:q 6Xb&PhHI$?1Y=LD#lebZB%AhMwuPjA$ZqTZC%d<m1kC4aK5^nC+JT\N:#Jki:NciTaY8ml<AKCXXXYk6
kQFpay ZHHhLBk9@C#we%m?Xu&@IXTG5AK?DLGXKj+SySRG8P:R&e6Kd+Le?^qyj+X$KlB9Ki*WK1RVwPyPp6JX
HED#j^ $^SJp/<e5@d5j4LS$ZGP=>\wmNqmiK&=*9KnNhu/EnEjB!M:Ju8S!4dSuhyYHhKZFVY#e\l+uLa$mh9t
5t<hGc Z?Nl^^S^ej!/$bq+RTcSZ6K:j\&+G1ZM%qnMmIW5/!WW5e9X9MmL>:WbBCGZBKaS\XtQE4aSZ$<@p:nG
^wnRC1 idWt>8KciRP^Bcj1hZP+R/Kak%e5>L$:iFqdbE$86mAbT%SFHaZ=j@T^ymb&Jd$PmK=cQ:8C?e:Pnm5u
iG!=EY Nmt@SLa&N8wX5@naecD>S<QKG=be@jhZ:Z*@Hje!WPl1hZh&cPSb:Gc%:QBjTQ64jFXcnlTuEuQkY\&A
lM$/C5 qc^\6\G\NykVZt6tmQQ#&@A%=anLTuARXaXiW4DXt$Gc\1qV+tw&T$!uX^wc!lBbML+a*SC$>MQhcF1$
te^Fbl :DL=tu8jplEbpY$1=It\GhSN/GHbE4hI11:J/lkd^BNJ:%lm/pB&uk$\JRkj!pIayG9=p#QjduL1mYbc
lpuHbT h%5>*IX5t69w%PPec#t%EdDT+CbZ9J!*CF1#*Z%eK#INc$G5XeWt+&GL4@cbaPEajuh5HtBq85cR4u+S
1mm>Am 81?K>Cwt!6?8/=6W#dC1q$!1SmIiSSL4k9nb/R/Bc%n\Xa!btecGEKqjWppe:\#PnN8//>HZ@m&&^LMF
\^%QPj D#9a:V!#$<w#AA\5YYE8p%1%6DF@TaG4ZueRZ6Tj8JCjPLtqh+qBFjPBH@!1*5wdZnWP1B%tiX**bEiu
#Y6+&u \$aG5nH/NdYVy%N#?/I?Ctw?REW&X%R/ydSmWQ!4nJG$TGib&Gw\YW9SCk@*KAGkWMJN5tt>GkcDX\Z4
6FaIG@ 1FBXDA6bm/>>jR=<Fh%Nb/I4nYYW+ee^Gq1JKy*aLC<F$1pF:c>I?/NF*u/WAN:P$wp55cl?MGY^/tlh
SE?jEu !XR:jk/e<YXLY&KMqy6qc\D8F@hE1R9S>j5^yTP$dMNkhY^X?TwB6da:GT<GXth5*IG96pXZcu&V%kBQ
mkMk<N /GG#ybiN4<5jaScC1qqwmmaYG/b\n>n1b8@1c9=9Y1w=yd9ZmEbXBhTIVSA4kW+^Z*qD5=tb\bYuwSRa
+8qDmL a<qXldDTDwh#u+/\ZlKPquW\=+qdYXH%>:h+1jk61RA4b>Fh/#=+DZtKT$9ICIN4>e1TXnVDP@eJ#$1M
dM\F+I *V\+bnbjpyZ:$!J<LY=&d>9H\Gp:Cp$a^>Z8$R:VhBLJuF=CHHdp1:XKtD/8h!t=^Lk!4JXq58/i$$&A
nE8wTW :h=L<q811GFQYAyk?&DqyAlm<1>>p^VwPQB%jAaP:IWbnc+<jTP66:JX&>LD?S$AtnhhLKcdM9kL4w4B
<8ZV!G *:dMe6dJLe!^uGYF$=Z!=lPJh5wNmy=NX&8@pTX!^NiHKIN=Vk:P?nM<<cL6w$G>iZR=@BQdW#kAc$M&
SHic?\ EXh:EIRhF?np\6d<1//dE5==miX8mt8MdpTXaI*==dwKwbleQe&:%M%?LL4tNFADePByKThdAI6<nW6k
6cK59y qXdE!Fd\5nDTRF6:n&IqZMAZLRp:C++%e=V\^LAHy?6cC#\XP>8TNG*^t1lHStj4DiI4Y8jFXJ!J/K$K
chTcCR 1a5+9N>5d4Gmt&@9Qhp\adWY&9TJF1T!\FN44?^I&BhRN1Ge<WT^h:Wa1^E&Z8^jFTHL$EdPqlydDbDA
5<*:6# YKaWR%#>5aapeuZC#Wq@>LB9<>+lG=acN9Q<IJRWVJeDnk=&a\Q#NKah%9tKKCK5++^6iu\t4TA?4nYe
SY&#X< ^uj=Khyh$p+5uXAHF&aLXnwSGi5qNi#XnZE:jl^mQT6Q!lui<lcV41jK9XtlyJC4t!ii1^&%VFmuyY^K
!hVF51 1FXFDl5W9bC^i9<$9RtKA:RKW:W>GRXjm$yNMV>\quKGByd@Iq$45@+aF9euLewCZ*jJ8Tp6i6YJC5e!
HM@*p$ ZRW5F/5IakykZ<DZhFymPpM*+<yGy4wlbtVjFmFPBl$5JmXc!eWY64jKQDEHP*JJHqJ&LipK?8DF?LK%
n\WSVD :FwS8<&584CkjGDhKCtSD%:hQKeWtJ&&8l1KHR#$hJN6l$Zq>X@:m%6TKK$8\$Y/TTF1#4:<^^/@KqM/
!Zk8tM A\V4%ykwKpT&Y4F4Wynl+D<1i?tyTRpNXLnAaPIT6KaqNlMVe^6VKq@VGq*NMa:tYN9YRb$ekZeZGcCR
-AKXtJ 00007c4378f00110334 Page 210 of binaries2.zip
9%ZYD6 XXA&u&G*YlknWW!Ph^aJ/$W$\ei/8iB\JA<9jM$RPlkW$=dcKyiJc*8!jPi>d!tq!HV>>tY%9:*YlFT/
<^wFcI X@8YI>w?eewi8&yH#/L/d4%Zl8JcHjTV#udF9<dFttn=y^Na?JAF91IJ48\G49ynqTLXJGw%%*y/9lB:
@Q=FWR e/qSV6npK!C/HMBV*mFkSe:J&1cCEp+!RX!pl&hWbLX>P>K/HcNQ=mWmK5FKlG$XLqaeRNnbqlb4uYZT
PnM^H< *bKpI8:Si54+56nhMq>tWlXVVY&%JhaC85%>m%4dJc$Z>PuJny@c/#d>ItV%dtjl8FNDliI+J^i&4aE%
L6h5AX Y:qahY9&BQHhWmS4nBblhFP=1D>Yb6KXT@hei@eR4yb1+njEmmqANCXWd<k:\lKLFLYXtAC?T9?ca::K
u!L\NP 6<?wSteiSRY$=8dPN8Wp94nj?VAqpWhkn:Iy#plZK\ndQ<54=QCEmLahZ@SDnp1yMGLLqut*lJ&YAYXF
l?KQ@+ \\G&\deY?9S?Ytd*8?t?8VuN9hw&#nR*whdi\Hn^>E=^R\XXCh5!VuytwpkQ^?Pck#*TdRCw&blS&e$L
h=9ia? #IG\GPTI\m/<eX<QQlhd4yF:Fi>HXnMlpDemkPkN9ARa&pnAXE=!cy$DHW\RM%<%b=St4pbuL5>Ew<IW
KVpA+% !<>EdH&yG?J\8J%#VbRhL8TS5CKjKF*5dH?=lG*Em=+%:5PaXbaAd+qX8SXCq*5NFp\5pnj@a*4/tdwy
&n#@4: 6FnkPQ*t>HSj$>^e^@Mybhqyn4duZyd9KK%9NM/ni4^/tdd6X6h=&B&6W%8JuLc&%q184>WQ&/bNX%H@
d@+HE+ b4MR5JIbJ4yY64tb1KJ$^NX#kQekLuK9HnLBARD%Bk!/wl9BYE<pw9J%R$*<t*!XmWTt/>DM=ikRI#8i
XIyEq! V4>IWJIbG!B&wm$G=tdEck:\6h6N\5/!Jp=PJL%=@Bl&G?k/T$TY9<&4KccqiT1C+RBu5@:<NP$PnFk&
bFK8<p +T:8jZNNNADYy1c/8w:u4!d!mZ\?:9GFQVqQJNi@jI$&G/qYh:DHp<d+b*Dk++l?nncRnbmi$lQ*lH%^
EF95!9 V#/e\S9+RVq\Pq8eEj^9QGG>^In4@ceTit+=F^u8=tZIMXw9lcZhXZ+8BLhKd@8D4*K81G>Th/<a8\aC
h^PTkV Ap=qAGiFIXaW5RlkV$>P/jqlaaib4yink*Be%ktdLqdE>M+G$Q^T*4<ARY#4SRE5y!e!CtG>c@kK%w%c
Mj+cDj b89XpyKT&9pqE%SKT#&5LdH!\b9:>uM+M>%pnn1<?4?tN^icF841>8!=etW5u<@p<:/\D>:wMw#4!>ZX
!kw8Yj /i1$Nj=i8R<!5Q1#NCP:9N!@nN>=D^=lH=^=H/D1\?j!9BTGi@CeiEVEVd<bhjC@WtRL4bQW%k4RCHYV
DEVC+> Ee:G86pM$!4#aSHp8DuZ=QLtiS5CEd$1dkZy!nVhaR=G%uT^MwLqGXlM@C6<XjmIjMZ6X\aHVYSN\1a%
\X<4bH B!9=Gu@Jq!qIIa^m/TIFP\WR^YLGDpa=4wF8^*hhXe5JJnC!6jP^uYK^u8S5XqRmp9Qhh/+CLT:c*DeF
&XmWi\ yuWLC\5X:!$5\FqSWZH:>5ej=\<A1L=?*+k9MNIjCF!@5cQ/?1QQ16PjCTD@mF:q4&cmj+V4Z$cneEbu
>48i6% QwM@8E:I\tCpADkjZAL+XD#\B@k^RD@$B*\6<PMI@Dj>eMKjB<J\BXama@yZNeyl9q:*M%*>6MVeZ$q$
cneb&4 4T!nqeEVTXEm+S1a+u%??t^t&BMShJYRDquIa4mD4>!nbBJFAN6y=ajq^1HC9TJhcWTqJda<4FQZC%<=
>PVPS& XValZ!tJiJEIT/I+\<B/bq9A5iJZYRR*YQ:4D:tyuaSZCKbpeyV:TLBik1CX*GuVhNPdVR5+KlaYLqXe
^*LwTk 89Vi@9&Z>8@j9:m+?MEHH^^+$w=naGSpbGJpatJ%^@*XS#AR9q>?HeWn!niNd$Rdw%@n:S9SB@kukP!N
uDA<A? @l8Bpi8BEeAPLwE%iJIB9EL+/KA^5Va^MDA!MdA&5Rd@\<kE@D*<>Wk@enkj#86<nT8JmWkbPXiEFaba
/>l4hG niHHSbFtbYtQ!^We/>!aE*R6nuIa%WhDR$PDR#kaYRAdbdKquGTkM/%N/Pl$uapKYAeHL$jbEKhjpCMY
BIPqk@ X8AqF5IFE5KFV\T\PBYA5Ga!5?X4ZywCc=jb+Nw1uD5HW?RG1uwb&1X=anFLy5*cM>T#iP+$<BV+CiMT
\DLttT DkD$HS\uei#chibM#i/cII*t+M?dec!84A!8DDa&j6$IX#BicY^<CpjnK$@ldlj<%NnXPQnk\j%HE+<t
JF&5L8 hp#RILmCc@\<\d%4\VW=X6jkiiFwNt@Y<ACwS$cI9V=j8BDZ:LDF%\tA6TwLFCXkch%WFiF1Lk#6kbDi
@$&V1N N>XJbumcedXY9TNhChcl\eElNJ>\Dk$?GmLGkpTYlqkV^CLlbNyllc>E%:Nu##JqBYF@\k:H+@q&t5Wb
5!JP\6 \\yFFE\ZQ&pXFeYb:c&bw/iCJJjm\aj%KIE*DcPB&4=+\ejA+TW::G*DhQBXWSi^Yj>Edpbh%\Re@ZD@
bFELyM P@9j?SiE>N???6qZ=<?jj@u<d&Ce?hZBk\jZD^=eY6wY&laK*i$KhZWh/i41ikyIAw^Qu:=!=?th+9H$
\@d<Tp chjk+Q&l?$D8Xjw8IGTy=1Y:<D^L1cZ%8?9$QWp%y?/tWujlN@D:5mY<V\jBP\CwA+F>9u\<4>nl8DZ>
ZD\>%= P8EHl=16kwQYtGQ:FwD%<#LGW!+4hI<qNwS:%ZQ?FL\C4w<RXHMkdaW6JtB#Hp5St\G5PcFny?6b^BYS
Najy^t 9a!YiL\IYJ&9mZmi8Eq=J=yaq=aa*G=:?^P8S5k@4EY1d9&:@@G&>K\<eBNVEX6edDZc6yY#^CJ%8DW@
k=GhtN JXyq%6XXXH!+?M:J4*D<:Q#=*@:\\=e+Dy$:h?:i9Z9@m\8*&*Aecj9D<BEe^+><j8VP<V6\Hn@??ZF#
nJp\$S mHad^!9l@y&8y%&4K+PA/6&X445lQAA=jI/&6n?$6RGPbRnqNu=t?DWiju1+4c&5dN5Tjk$A*mABt%j/
kywKJ? lmm1!a&y+G^XFT>e>Z@Pm=JyddybM?^!=&uH<Gtdi&W#nHSqWAtRRcdcEDEYSDF=YM*BakC:whul6Jq6
T^+6>R A4+PM1^E&cnh\a:dFnNS<1$tM$cSK?YikK>AYI>uhlceu!\\<YY9q6Rd@wiH5i&HN?q?<ACbmq^%l+JB
\TP88F R^cDM:JXa481nw+>p*68*#==<19#9!XEj#l$/NC6*:>?/>c>i:h8jZ@4?&#&6i^NQGI^@$&@@!cKE\aQ
MaKX$\ D8!^$i$\<A@8hHY6NAP#8<1P+AHa\d?Q^iB=dqc>=u?N+K$/+u<Nju5Vj+5Q\X$@jG@kRWD&:6I&wG+\
nmcBMM CMDG^$^eqVmuj:kTWTXeSj?Y114l+YGc\=Gt&BYp*b9/qCTmuJeH&dRe&LGDWLWG&XBlmkPKJYaHK\T^
aMan$u *d?tyZiFJ@kIDumc!!I:pT/iZThDDP?ACk*IEmNnWVpXQ4q+5dYRdD?RMQeTdJ?9*=yhkwA<iR1ZQBK!
e:$ddq K@DP9M$k1Ndt8jp5K/4N?uX#<VEA8?j&+5tZj@QqwWP9\@u:i*>#Rw!6J@d6&&h5ljPtEVQ\em^&LFb/
m4ZL:C #DlYi1!$?^m%&iDYDKX+&%9c&!81^p1:Ahe:CGwZMH!+E4<Rj5S8H$?<EIyXnCj<nKelH<JHAX!AFk/A
6:E$uB N4m**JjQ&QlK*4ZMZ$t\XmFhSj?AN5SX%JST#VBYnHSP#tG&!a^!LNWWCABhGe?QNGRjEYNyJqc6leEM
eWk4Cc MRc\mdm8l\qay86HDP\k^V4n!4!A1y8WdTWQWEq+K%9m1a5ZD?^?<81W6jJ\NQdN/Q<#ht&^Vb%=@tEj
+m1mqw ClY!C=wt$$%VWte#15t/Zm^95lBN14Tt<W^RbIjc$b15C@GpF1tySdt$lq!R$1TI8q&y1NN\i^lBSq&T
>wWuH/ qD\E<aJTbK68m=wG+VVVBEJe5GCXmnJWTy4H@X??:#9j5hQPHlQ:?Nk?Cj/h*@@&@T>aMX9%P54jR/@e
HlD8Hh iiWPtE%#DdjAya%+HCLIn\Hl^eXW$Ck?@lt&k\eB%tQAV\FwMm<&h<1h!1hT>m*d41Xm1bkhC>T8ZR6^
jAy$bN +nXC!XkYdlaLkM:A66=\hcaDucFAAC+HQEe1qp<BmACiQa%\=8&y9IX!>PG%QD=Qd>5YCNT+@GM%@yyY
JQ^6RE j*dcE\^tMlyjJX$@Bk8JaRWSZD/BhMZ8qF&NJW>!WIK!l*5n&HXaW/>G^l1Laica&kT\l\Xnt^SlGXhM
t^%I:F IV:*!*!Xy/KV6BlBauPI&K91ZamRb@?bM6c?P99TT*e&*^*A86Lh>/n/5KQ/+n<Bpwj\hkCl4WLTdny/
AXC!$$ \Eph?Q\1Hb\!VRNP&X\YG%I@>@Q:B@@N=@PhaW^>6P%^=?H?QZee:uhEq@BINA@j@dWVi&B@/l45Qud!
ly?:t= =Gq+PHu/>IuK$/hQu+#FHFQ\yA#9+KYZWSLjcIh*D+e5>yRqB1icmk*D<&kbHp\BQ/N\Mn5hi>Vt^1Q^
eHY*FS YG^dHH@DN8D*Y@D+q5&jZjCAkl%R@ha/yDZem<:1nG%t^6XXQ5F6ISDYL6X%+Eq5I6qDk*^N8EamlnXM
QG9Qpa hP*VN$Fbki6*bw9+Z4FB4QE%we+X@kVPIT\u6bbbbDc^$u+8TQdTT=u@9L6>aLieP$mN45+Hj<K?h*e&
5I/qKY IdKdiKt8cwFA>Xa+A^hW%^hENbe^>bJ@:u<a%?k8JPlP^6Zuh5QZ?>+P&K5nePqLh?<R4@y&^GIj\wPn
:PTm>! <k#eu+nl@XS*>&p<hILj<TNK+l865HihCJ&C+$N+5T!q<Ny=L&XQyjB>n>!DiHDwBPC==<PW?A*HkM<@
ibeZYQ +tQcu?9%BMEpN9XdR%#14SQWdZRGLGDZBNMX^LC46pR$iCbwi#M$#bVF<Lu#i5\j6G5V$FXAMWmdRVaG
8+>n&> qnV5=^XGmFkb^F+K@J9=C4l?EqcZB&9a%jl1p5P::>*N9QVTZ@/&jj9Q%JLnH9XZ+W=Z<PeP@HVuh*@:
GMPK?Y *T8H5B@$ypMa@ih6u*%SlmLRDHa5bAwKLJ+dGLmL8A/9B%n#dkHeV6^b^\n9<MZjm#@$?Wd#Eqdj$1ua
FX?EAL i*6<J&PImc@d<cX/ab%nmuhiuknjcCXel$HI8tN+jAlj&?ZiBbjMPyC/q?qMD5iT?nSDDd>1G&liQPtZ
C!welI L6iD:ELR?bZk1^ae:kW^QDNn5\G8&EGL6l^&mCmS^jwj\/Mukk%$caBpkZy61pA^@H&mu#A6HS\$pDYA
>=S!nn 4biE>i1G$:%XBLHAFc?R9qI<^@$EE>ba<VKbVX=6\6@B8*j99p>N!%/qAcF+k^*S6mG#/e/hX*=/jGTE
bqXNdm 4t>^ajitXL+lPc&iw41bkaH6h>@B4*M1Hm*LI$&u*LmJ4*wWhui+h*Wn^!/nPE:qw:B@uQkc&<lEnm*B
kjYYHT ^+mwyVF+&DMenjalZ%5u+QlT@ES$q<N>RkL98IapV1XTLAi88a@nPjBJh?wSI4%nY^%w&DV!>e6AnV@4
H:+Le5 <Sl<NZKdmK/&Gj<M#y<Re6k1%c6MjkEuB<&tRnE5a<Q%#!Ra%>I6TdkS8KXKQS/YlG$1mDnyB9FHYuSa
myI&55 1NjB9pFBYFc\^hq4i8HQQhp#l:9t/G&S:uGNQ>lYI/tSaEcdlp\X4Shpi9Cm*Xp+D*pA4wiB8=5qaTRq
%RpAaP X^T8WVChHkulm><>cNpWat?=npnV<cqa4A=BnmQ:<N+HJuE=PLa*duV=jPQ$ut$PIe&uh5ZKkJH4W1p6
>KTc#$ jKDPnV5p<m@d<W&#aBiu\XAG9w=jh1GCDRaFZ:WWtkNhZc/bZM/Y\<+<wn%qD99#qMkCK^4\GCqY4^$1
B<tcEy 5Rt6JkBmT&qTdQqpKXNY&p=wPhZLNChD\i=YB4GJ4*?qm\SPkeAcC9an*TA&lTZEcGTM?y$:wmc4Z<Yu
-Aln$y 0003432508700110334 Page 211 of binaries2.zip
T*?X^H X:Gb=K6G8!6X&aSSKljdT#IeaX6q8C4AtnF\uST+^wt+Q9!c%/W?=GNDSDBM$eXZLMPujTlAw:l9RY=6
l9Swqn R*k5!Fej84Dl<Nwd+VBdaV:j^lnKaQ!J8@GNWd6>tD<N\lhWc^\9E#9k85hH#1\4deP#^<h5G^bR@tS$
:ID\9c Pa^$A:y&=aC6PdTXYA#Z?wG96aTw:JwTJEF*XRV>m:\ewt9yaFLjpLYC5aiF5/N:5ALZkwAVynhhTmV8
EVkHQ6 >^NdBijbI6dV9#:>>FN#YIKWQ:Ypp:$GbejRI\T56I9Q/%W\Rd8BKn16&iJS%*ntDBlmcA@@kKSdV/nG
Z<e!Z# w/u%JC^B#5cJSL:+l@aR9mEc/l\GuM=$ZmjIn5PLJ<CQ>dEeDqp5eeIXA^QE%#$AIZ+PL+y+CuG$I/:D
1%EC5Y hn9kNnWL8^@c4@Mq%B$I$G?wej%+#PYQ$9WR>Yh:Fc+cZT5A^=pbDIS%hVFh\YlCMX!4X#D*$nj*K8YH
iS+<#J T9Y14PH9/5q1Ty6lVTaFa>tL@a^YanWF!^Gu<&\RF?4Z@u:NAGQCCwQa=MDKwV=mww?Sy!KtH\qe4%Jd
6kVwKK Z/&HD5FcqcJXYM/KAFn6uwnYi6&w45l$bLaH\XmJ+*j1I#<uGw&8S%#yWH\>Ceh$>JmL#KQJJST6L$><
idAi\K VW</AjuJ<qB=N=6Vqp+L1q!ENd\&#H!Np=>EX\hhC*a<VVTAY9ZN>TjlR+FbFklQnhtPw>EE9?G+j+PR
%+#Khi IB5YFwI>&+X?NincmLlT+@$8Ayc/*9q=WNCV16nXR&Ja<%=%c:kJa$*>jaNCAmjX+^bF&ATbV4^cy$LE
LZ4H$I GHH1KFC\^NiYFqc9AqlyEb5Na4%dk^m5^8&c%jm*I&wY*DpB4Ib5J4ewX&G^paT@q<hX/iNYXWqW=196
R=98/p Wk:Z@c9a&VWmD:$biJN*VuT%kqY<l&X!PF!H8*<PV+KMLR?Z@=pPZ\eB9HF<#$u1>ByGZB?!GQdXBVcK
!QJCpS <\&=ENG/tnlA8C&AcH>ya>&LaiM+9@&ycV!E9#n8tRi/ul$\=1\R41^hkc>h*Qeb8%Vt1PEhRe1q/TZP
R?wcVb nw/m+HCB<>yu$FXmt#SLanTJC\X^pWH<$cX*Y%4?m4mYpuHhb!nan<\=mXyFQ@>%X+>w:dhN9dm9$8Bi
iL65D% My+E4qh5Y1uXlSH5T?$%*R^bjHakpyG+Ll&:KQbtbmWM5#c@MHt5:S8pK>6@@@:Z<Q$Q*Rk9?jbM*km9
TY<dDY LTj@yA?Im9lSAHp6Lk4IE>i+JwWGu*WlKi5i+FGdDSp<ca9TTdMdil8?+N@\?&@k:wYFJbAMj=wu<>/R
y>T4BW \\n4QDw%6Fq^yk$nc!X#YP8Q*!9wipV*ZpXXD8GK5Jatm:e6k>Iw@q+R%mTIX#Pe*yX?Vyy<y6K?eN?1
kGV6Ab C6a$k\6P!FPHbLh<*lpjq+M8451Y#a^5eD$*lCabjAF4e11$Wc5S%VmjY#buMq>NVp:Gj%6*5Qu^=1Gl
E%%?uB P4#NZ1T%>im^uH@Mu@6>@IYqwj?hdy?i?\D&Jn@AXheQl9=:CPD>Vh*Rd&+AMV?Ah*?N!\Bj\<hDaqqu
wc*F=p I5\48m?Dn^uF$>c>Nid*9\Yuj8y+*hDRhd@@Ad:5d<c*jhG:kK6*j=4$Vd/>:?&l!cF9aH@w6&<:ue/I
nLS:XI 5J9WWw=%R8BKjKY^Cq*WJ*mmWY91TtJ+6$y6$8nK/qZRqZl1l4jWJIpNZD9Ik>WX4BLE1GAN@b48/@8E
CMMSPM ehWW4NC9Gq>yHm&u4P#qJDQeHZ@I!HJKN%yQLI14WnLJFNn1=9\tn&J1RV+9eCEDyqQ\#8dNQ*&^<MZn
\l!*kB kG*#^ibe:5HF&h\5jHE=@\b4%wy44*MNe@<!h\9Z%BNdE%8@BY!j9a<dL4m1bd4Pe1NBQ1@/aE\?*N4c
\1DRJ$ lT6^jm9eY*Ey^?<j5@EcZe:/\Jy6#m+5NAC19Nm?4$h8Vq=@NibJ<6K4yK5%l+m8STueXb9Db8%G@/&d
MmA:I/ JjP41FhX9mHwc4KcTp*A>4Epqmc^THJTCybVadRFYI\Q>/pwB\9mZ?J4SPKKauleDJNmVPWw1ZGh5d9Q
PlaeZW D&#C65KmKAjLZX@p<nquJFI$^F!p*<MZq*Fm8w6up&hlwdt=?pG8ia#F*Fl8DEC%VnhPN<\%NN!/hi9\
*@^w*P :eP*d:h5lX9m&#>mnkVk?nRIakRYwA&XW+9<#qB=mKFNA:16E/&$eI94hYNY/=nX#<n/c&m%hR\Z&&ty
/*D4^J HSGhX=B!+yQVY=GJhPm+i4$>lG5%mYG\tulMphW1%P6N<XMmBb&tZmMh!tymZQMFInnQQ+apSq?u1eAm
=kj=M+ ZpWRI&F^QcjQmF9%J%a#mA8mE8i84n4:Va:$E<M8:8$i+LR%!q<Cq#Ykep\>Fj4+Sp*JI1wbb<b=BaDh
4dkM%K :HpHkY$tSHtN>IHXt1YF<acG^B!mi4mq=jajMKMy<T*t\YDCBFyICCKmG1J@uZSQ#AXpY<5B&C+C%nwG
muCFJk RPJCiw$Nac&BZ$GyEk8>C<^YVu#C4DbujbQV/<%+XS&HY1HD!dWEK?BcP$Gkh6WCh>Ee91tRdYBBb%1n
qlb66i M:\e5J4/qhYW%<$twYKq6!MJK<y$WBB#/N?EK/en*qeGeX>jGLMt#GuEBj+4Z*X!<69jH/+!Vpw\>6Y:
RcPMHb Y&R9H<yp5qZJEw<Z1*1<ykqVSel8N\lLhB*##>1RXtNAMCB5R@868X8*E4i?@@=&k9IyMWQ6cbLDc+G8
c/#aA& JIQFSk8!uSJjSBaa&>4cVyVq%Ikc9/$Xdm+Y^eDZLI4l@^ATtBMXt#IXVm<m1<6l?69STMyh#GY#BCYI
QVmG\N aT84%/:cPcMu?B!KaW!BPjLR=L&1qXiVMX!+Kb5YJdFelhW<HW*BGl+5LikMykey+mTZhC/6bk>HqLwt
=uIi<Z ZQ@?eFX5&Z4/>@j@c>c>KFW45NYhW+XYXaePiJ^K9<1Ca!>mGnpdeWc8AEPiAF\>Z^^hcM+?!AGt6NZa
m?$^cw TFJc&/jdG>wdE4iA4\tkK@B%c<8#\FdT4qIE+%J:!GLBu=BaeA?BSP=$qRhc!:6\lb$VZlBRX+*LSwpV
mL+49D NnVM5w1\?@aFSjJyldMJ&bw^/nkp4CCGc%EMX&iJ4/Sec*t<R1$eL*Q#>bJ=>A!K%c5W\><Z+=w*lThp
cwD/+Q %IkJ1#\hVq=dJTiSI^Nlmk>LS&jXRKIll*GC?Zn^pEbh!V:@%DH*+l4SwwpGccSKunlk!l*&t86miB@b
Mh1we8 +EY/PwQB?e%I%\%bMJaA$dR6:eJMFbKj:a*6cDkqdmh8p&=NjL9%n=!*S4CTZtW+icHhIldjP!&BWKkV
eAHYS% KI6bNKlpZRB1nT66e\ZTNl46B?n/^#B^dcEZDKeia1!VE5YB4Jk$S5n18D=bm&I+Y=*L$knA6hVSt/^l
T%Xqa$ \QXtmSlp*%DSwRiHhdyYpQQc*\>PVq/aT/Y4PD5CHCD5h=4qbK#BFu1\$uL1p\Fmp\NL8Jwuq=K^Q1+t
EX!AZE ?I$@*C6GNP/X&I+@9&6Sdp#YSZ9XAhQ&SFYQ*t1TP\VkAiBESedyDD1D<^+Q5BXE<JnNF1kJaP4KCMDl
PEB&Qw S?FydY>9B%5a@t%N@GH4%n>?m&T>L!%lEL1eRGFPuGB\A!E5uWt:YkPWD+PXWbVwlBqNtA<D\QwjIGZS
T?@#>k #\uPA&NJ\YJbRIRJK@qKj*tFH/S844w/%=8#5u:q&R4I%#qnKFTDWtBe*Yn\>ZNyNcYL^c<G<YCyRPe\
dWinW$ ?4AFkqkt4=u=&1IuZ>^ZT:BFjJXqktk&<RSpNdjeQJl?KL?wZFdT4w8&F>ZRP^dFB#\>=q=alP=byG#G
>1nkhA m+au\d1R*bD#%+#a$kGbTkdww5%D/cZ6@bk+#GuD>$&\awyVbc!6euq=?XSqbcYn$kAZEP<MlRLqkW++
P6&4tH FXa^Ey#&>aE6XPCI^%Deb:QN$!!Li^SqM$SaXBcEK@@q>X&%jwT%P56<4SX<dRVt#4$8J1mAHP+R@1dJ
P\iL<b dBLFXy?S<%ycLH:%J!KkKAldadcIm$NP=yRJqR4#dwGjw%WhCYu!5GDw&%=b$BnhqhjJ8tdNBWiPbjCl
nqHL#m Ky+!iPZF1u4#bBQX6IP1wYD4tRj%P45#th\JN:u6^D\!+Bmc5+#5je\Cj%1J+LXwB1Ni4Y^d#y<1G>&@
I9dPSc @@L?HcNq!b&u&mwhEqp:*EKa>NcbDyRq/jV1B=EhRe4tAFul:e!n+@wG8Dn\L$P\/9y%H4DMklnGbFW4
c=/k?u mtGe>XmdyWpLe&IE*Y$$t+m9yMCEinW!aD=:y1XA8?cVyRY?nkwwMtE@%\Z^?Cwly$5K&H/MN9ZL8MR9
FYPHRy <^YZt5dFiF\SG>dC^C@5WCJ+Dc9YXAC>XtP/HSlN<^qnVL%=TD4KaSVD\S/Q=&m/4H6qI>^kk:8Nw$uK
>L#b5D RR!=A8!yeI:ljSGPIDM+nDb94HJ=eQVSS6n+e!54n@cQ=yeN&mK$kSD?Y:jT#h5b@Cqd6t>bd\hpA:c^
?^ZqmY 5S!c^WSbXLJW^+PqYXTlk:mK9:uETtI+!*\q8ndY$5!m%=m9NMi?$euLaMbmnw#=K:wYPc?@EFBMJD:?
+DwWc# 4MqpPep!&GLC68B1uW^5dNFTuI4$K#uZ%Mbnd&FbPY*QZ#NRSd18YVNC4di+$ytH*@XwMWSNDpjR+MT/
ka$n:B 6mduqb+iwP6C#TnlTknB#*ATt=kFkGih/auY<I$8#8duyH+KSVC1!dJHK@TSFRZ5!5yn?<6&66EElVaL
9bG\n/ At8^l?#&$McX:mtF:Ju>P#Hh$Y=QB$D&?@&A:DTbV+D5Qm4SAqnJ6yN<lc$BkMRl8:*XyFLZ+uCdYnGK
FyP8=6 cp=Mu:9=P8F/Z1RPG*!XT#qwNR&ccX4w\4KPJeKT1@PQBLEp4JEd41@utPITEYpPC#F5AyR:RZ!VN=EX
TylnB? jt^Gn!aSpuD1W:#%etJ+W8GX&uWi6G6/hG1F+TF5l*jF5P<4pLdV%Xu8Kt<NW/I@dG9DT4M8u!wn151L
*cLHtY aWWC9LJ!8R!p5S!PkhM^LQcNK^JY*QauW>mEFMi8ktFMHk<Ia+?kdE<V8n6Pd$du/^5kjHHAL9P%T@CX
1wG*<\ ltY<S4n!>LuGN@VF%*PGiqYJEwP@k1iJ5iV4NDZJSXMPVS#b*XG<CK5Bt>k118wK?cw91y<VE^T$*l+m
P@@lFY diIh6>6kK=LXpXYKFa$qlNZeX<ipauF#C9W/:?q61EFeni%MM5b=\*bWn^V!NbX6wGbhL689jeJAFaHh
\mCklK 8G=@5k&BhdVFW9taBWBeAq\X5tei:ZSn#&Bk:JaSMI*H^yC!$yZF\BN/P&ACCL:mu@5^1NNGEMNH1*pa
MHmA!& N9K%ETiN+WnAEnqQ<Cc4%>&9F4p=lP9lR8j%qQt^NGuwYAV&GSWpXnHmXdLZ8FlTFhY%JC:>Kq@qE8Ji
T&uPmL A$:SdPuiMaZ1G4ccWpiN<cI$KLnKw*hMKmR51XjpSE@QQlDDYbDDPplu!tJ65Xk?qpIl&6tbN5L==TLA
=byJVK FD6X65+E1wa8T?P!baP^eJE\4lLbS<t&YB6V%w:%!dacNJ?!$\$MdA<FmMHd$jn/Mjk$&Y4k/>F5w>C9
/C8>HY KIedCXe%4@itS&NEAX@b!iqdncX=SX:=/mA\64@@<DQ%clY&PEd<1Vp>uJF6WZV>cDY?huA\nJ8FEb4e
Be+Sac E\$jj9:B9dlwMy45$4YyPnSQ/H1CHV11Y5TJDckKL%iN>@VMi^1t5?u>W^KcJiK4\?Ht\XGALIWG=XwN
LRImNJ laI6qchGX?m6T&dKc5J+8G\bB\DTWDH+6:S^c1yd&p/AK@\CN?CcB<=8Aj6J?LJIYZJ+MQKE\BK8>Hjj
aLbiD: Rq^^kH%9qt$qwC?%%!he%iS$M%<L#KdCGGK?RB4uC>j5EnKa8IwL?*q^GT^6=kwh!XibA$N<9e16Cw<I
NDT!8^ YP<^4Aj#Gq6J6/c1DtqDuk>W9Zlw*plPqB4Y*F5uW6GWAVZY5\?<%>+5/FeBKtHXZib\CE\w^lD1NKL/
-A:K+a 000da5c163e00110334 Page 212 of binaries2.zip
hu&:+t KIM6?hGXyWJaJdmT5<PnTRLYDeK+#ZGT?LwmwH$58Wk9wDSGLR9P4A%ZA4Id5Jl8H#CY168>LIi=>WB6
daGJ>! LeMK\QIaPVt81Qbb!Xj+>/TJ4%V+clLDk/Z@WLec6lNwYA\tX9!@CC8BFZ&eLlYp\Yk>F/tMuu15c8Qi
*5SJMd #p9X8pcw%5W%ny^5jnnQ+B:!bCT5S6NjE/kaYAi:E=k^*:Ak?C1Rkq9*+KIA%mGtZFlWRB@*q$j=jiyY
A<p1jk nC%!huVbeaFu5dynJ<F\Inp<^dk/Fku!FFIYpE&QyG$WyED4CSmL<Z>$ak$=nGQn1lHaw:$$?jw%NaZ1
I16jA5 &hyuT&+K8y4$c=Gdp$n$ed=c/c@kYTySS$teiEdt\!mL8KBkW9D%Zhu\y$Z9+mV=c5J%6>GqlkDF:du6
VL?dDl F#WB#Mk/S11i+QHAXaV8kYBX^6S=9TBnk4<ueuQ1pc<N$%dE%aAX?H4lk8MCI>5YW>DK519K$YF+%=L^
%ZE4h8 mYJ5mdVDbY*mLA:HTbDD6BG\/<4wj+DR86q?CkRCKI9Bqi*%NKCP4d?Cc:CK4=<D4nmKNZ5WVCWicW/k
KtGZ>Z >p4>K9:N+?X<j4eiSlSNJVBVA4\ek/9Tbqw&Q>Wa&>eHlK%9+6kEA&6$lnFbVl<XhF*V\$%KD55TD1qi
4@M:WK Jcnu#\@<aQb8Fl*\6hm#k1WpmqG@B5<Z6HI8Ny!<cHGm&jS@nF%dVF6uu6h1HtA1JlA$MXIbllBpJJm/
1^%cIR NFEtDXpNnXq4\GY&M/pCWjDb5BqE6KhA6NTY%VaFS^8q&Rh4>&FVkaPuw^HMC<TbTB6=>!HVSnCl1*$a
&p?kYG XwXe%m&Ebq&!R>QJwbK#QP:@<6*P5Wu:Hh6^mAtZu*@@?\Z+tqC+F9kk4wn54GH/:Nwq+@8Np&YEKu<C
L6J<P+ j>cWdh6VW\X6SSFn!&4F&?NkaA4=m1kT5BXJ?8ab&GH!bbG^l#B*q&DGpww%:CcMRRBbpc?X/N9pcENu
+BQZPC J!:pQJNVi>PHYkh$Fa!H4^<lZ#&FVSE#$JV*aJ8j%B4YnDq6qJw$eWpN\L^pYp*9G&FEX^TS^VDD?n?:
Y!?AAp D^1wHk!\i4y/uqe??^uWYFZw9St>Z&4RbK8!uDACm:?+<auXB<Hq/4dwEmEq=C4n!6nC%ikP/!i*BKAK
u*kida X69la$>=:KnwFeqZG@m/QTcS4cnqyCJT>8BB@nGA56n*DIS>EA!Blt%9*d9aKuG>Ddl&L8PP#5S=Rhhe
k5tuD# y\?*QmK8aDi6jR1w4k*q8kdMNN&G!<&biPid9XjZS&9RJMc/CSYdwJmV8^QYuIByZP>j<919epL1ca^h
%mt@c4 !%HZiL/i%%a\ad1:?T4PYjC^#SRucQ%Xwb>61C*%k>/Jp+1$cDYhdWe^HF^G9k1e/KTV5?wISc8^de!p
TuE^AL C\WNc/GRey#5XmSkbR1AdMwFdEXG+\y<*bb<uc8qRTbKFtN*dB5+QJT:1!bJnIV6ZqS<dc@54KVh1/Sj
mtYCV? eY5!:\H$hibiQ6NAZMX:=+CL4>MGZ??*@>*4F!>P%mT@%epLTY\R%6%bX&I$VCqWQZ\XPeRuKM+qZZ?u
%LYVA? 9b5A<dRH?:d9*q**^/WR^5iPn@>9+@TM&hw^/NK99LPkFXWP8#tJ/tML$Y&JKn/PbT#LKwh:w>ZI$JL>
QXY68! $#mM>$mblJ>jd&ihyDX4+c55&<t/XY$$\5BcN9w?RlI9ncZ^C&#mLdJyddKTdY:d9aCM^WEmwhDEKNyP
I/RalM t1<?+G8ChtGj=$*ub^nYBQC%AiNNkP4S6cFPd9PZH1JP=*RL8/uIdM1ZMJ#!P8\pCN6qENcqac>h8qTC
LLdp$F 5pYDjt=4:*Yt*=\?NDQDScVa<+bC/!w\>i/?a?94mjZ#mChYSkk%8:>jd8\!uS$>uJDlSd/!jk%YXmNj
^88?5b C=19>itK4YlbqE/tNtqJ$kX\iZp$4TDFV$nb61ZIdcYhXL%!j$ARX>TK#:WL&$6+CWpM@#@<%*lqMNP#
@9G&mQ cYH+CTV^%Z&adAhkmdDhC6e8u?V4ihylV%88E:RnLye:$=Bd?*RNV>luStAFZ$W6au9*^D69a!Ym4tw1
/:#=jm 4q/4KVKhQIRX5&FtTtqaMi:jP\#?p5cXT/@MKVZQH&SMh<@9*6*ee=X/i!9ZMYD1P<>p^Rh@L@k/L@Z*
9N=!=y e*P5\hhB4?YEjk+PPq5Nlqa/pc?clKqCmt@+AH<6m&c8#C4D%mw4yE!?&qqLVPin^9k^n&&eaWq8bR9d
d>hDL@ k4DKKJbJkDF+:$VRqeWIBc4a/pR\iHlmjKL%4Pa4C6@#8E9*QK:Ky9Zt9IaIuy@J=hbaDK@=SQ8LK/%P
=>BVwb >9B6>F@bHm+/V\&R</:cW<V%e^tdaGBH=K!JE5DKYcC8D^l8Du>96$dWnNXi\yVP%c5HD4^:F!BN@MnH
DAbRZJ G/H>6BXH^Q!4D9>+i41jh@X=Cc61E9ePaBRS=jAE!tHR4@YMKIJyQJQ+q6W&T5>uMq$R4?IZ&qGGFeCB
q+i8T: E$%:jN1wBY!*DmJj/a^lZpeDm:Ct+TC!1F9kHa8t$<1D+PwwVq@VjCXeJX>>L#ik*WRH=DA1YD+89w/+
:P9euq >G5*XwSjYKn^lIcjQqQH%plB:NY\JTY^MSdS&@&1w^IdW9inWdidRQ*!!!>j8H5ZT<1Yj=RRG>#l^Q*M
Hq\GHG %^bCh9?Qd$%4\k//A$?t4:Qa*n1?Pk4&eCZ4X\NLiiedQM\Bbeu#tT%d$4Dm4X=R6X/LblQc5kn:PXtB
?8<?y1 1?K5ym^BG/*NY\bl&ZJ1>@K%lZdBKd+C\8h>uiE#8ZBP+&4!%SMj@9^6#hj<6+w:VWyB4GNPqAF$4Wt/
Q>5w8e >I##9lLDZWK>58=u>Z1TRH*llee9QQ:h?uIq9*XyL^4=N&KQFR4mYNZHL=/nLwAb%\I^9ccEe?wWHV/L
/FAZi6 enm+5u\h?Jw18C/Bd$w?Ga5tGhl$jW1@AJA5E=5>:JVT8kyWiJm4yhmGyZBh&q:!EJabt//NMGFQ:D6Y
>LJN<V 8bIIln:DHL9mK^yL6Bpb?awp#iZEw5=P+K9W4&5=weQ/d*u#4+K9F&1?nT%<^cXkQ*jHJ1dFtPqTc=JK
88VpeQ 4:T+4jt1W5Qpk#$GVF>+@B$<=>HP>#FScdk:lwd>R5PmPd#@^ZPT5DNFwqm6\6mL8LcPn$/ERwpXp5Py
5$%EWn kw8lKjeynEW6+88a%4=+kRLq6umBc**BCFqRcml\$Bw?iBD5bDhjCX^bQ$HI%mduMhP?RMGJWHDW^hh1
@!tcm9 @KEFZ%Gu=yRe>nW$NCm?=ldJHm:JX^wZe5E\n@Ki?ET^u\P99HDlde41/NnE6N:Q<a&EjX?L+T/qZ5>J
Q?AkYb >jyZ@@n+<iQ9QAjuc:ReeNWwaE1=XqwmKAqLuQ&dF$ia5P=&b#&mRhnDuM+li=n+YkyN</RyYNE+bwKh
=Aa49F Tt$*i9u1p5TF?p\A\<PYW^DqFI#5tGp/CeJGp!CJi^d&uVlYZdpTDNEIVIq4N:&bcTY!=m5V6lMNa5V$
dnA^*l KPLcJZ==Jiwqm9M=^hbV91l6b<HM/4DqNE$L5D!LR=@NX$P>GyZN:\FXAhRQ+LRey+*AFPWZt%!4+JJB
Whe:1> @*l5jQ<4qAHc&FD6p\QFT@<Y\WIpQ\j6J8K4F4\:uVJW5jq/Y+MK>:RqN4QdKbib4FS5JkCw#lNj/:Wp
P=G?:l =lkFac5Jt$uP6?*8/eGkW!IS?t^$wqZliu9F^Xh$dym8<L5IN#Vp&HAKC:6yS6XL/ECm=K5:u*QFJG8?
NpV5VE lFNdk+LahGGq4&N5lL&&I&ZjN+4>6Z4Xd:uu9kbIt=1cQtk/*lLuqVq^ymtCY6WllVD1&yh8WG<5P:FF
VFqyNX p4l4\MNZVL<C45@G%Ia4NRa?T&QiI=:Vqym?cG5d&aX5^kwM#?eD\Nh/nc#dhJI/FkkLk9nA9tQHXlI4
p+Ik%8 RiC4q5Qh!#:JX$aY?N4J1?y>PSVECG1a>C8H%yG9V##%VVk>:^q<LhFjy+L@46J@aV1=N*S<A%%q:9Y$
XJhX?/ dAlD*m$?>$EVZp$$lT8Ge<=y+*K5Ct>+$BmP?>pij55Ah5a#XMR5M8%1bj<X?D1=Xi?CEa/V6i&W9Anc
Q%9*DD XBp+P#Y&:RJ&#lJ!PJ6KiXDq^\^YZlBjNc=\WEZ4YnbqPnWLRa\G<imEIahZCNeYkT4lK9tK8Paa&KM=
:NR::p Pd:lHBXd8@qKCb&Fb^c5kVDPi@=%51mAVc$mNFbk:aD56Y98cBN?b#w%@N:Z^+G5VjjkND$Eu5d&^BBQ
$kmV*< IK1A6dhKTGY5LRXe5hGPVGIhKB:$FD6^&S41X!GHBZkEyI#n&?yD?DmZuA%e!R1eyhcXwiT5SF@ycSL5
8#N5tY T^u\T@P:<p=By8<aX9wTh9&&MJ&EII+I91JB9D1^!u\qR?@9!clwPe>:/VHKFMdX!QRWBHE+LQncclmh
/PMNiJ 5m=<\HB$Lq!RmF*SJqPp&HC1$aNmYBC*/\I&5XLH9b8:JLLZQNa\6iaaK\jmkCuBi8@i!ahXAP5iSlTR
Fyd#C? :ik>CW?E>^yCdQ>++\by&J$Jm%e4KNn&eT^dw#lmRcEH>?#eytWqK^BaA%q:LBPaDhkTi$aRljM5ByHl
tF/1M! ^W:Y5dNIhL/eLD=Y=Ij##jq=\XhB&dGKet9Vm6yPc65MV$Rnde$>B^cPXXcDu^PetGkjX@4%C\CR?Ty^
I?!plQ jVuum@tGePAu<BZ$K$GdG^W^YDGFaMM5ZL69N6N>m*TPhGGJ5QiNypt^a>ILdNH19t6GTdm^@qq>b#NX
:La*:M AP4qi=e9\=&B*eNE:WA=jBN9eWZa%Vi^py\Eej>yR<PclN$:$DyA>alaL+H=uK%/P=XTalhnTJ8d%1d6
!@NtV! \HP?+eN&&i#\dCy4C@Vy&8b\W?P55<NJ6R$*==8HubR8yRBeM?Zq<Q>dbW:>pmtIp@M>qIXF9p/MG9b\
^Gtyej %!kIZ#@m!wRFPS\iRmu5>\$lZ+G\aWV&TD5NMh1kZR98lI+$mHh&aCMqAb+WF4F4:w?KW^4d8d&e%b8m
5SmmBw nJI%dl^/I916j@aBRM4R*n6=E5V9uqkHT&AkdFZX!jlNSyY5=Jhw+bF&atjea:6WJ4aXA$+V1/GXIQE%
+n&>Y1 binVVLp%C#jL!i1Q&XN&STDRYHBecnhX>yV+ckZk+l9XM?YHLXC4?jqh?ic&=4/&ichkXMq5y?ELqG@C
VdLIbB *Wp6tbIa?#5P:D8Be<NBDp?$6$5=jD8I8yS^SdwPwh$$=AjC^6Ak96PAallP:k5&Yj8uS*TB$?BAWWdu
P@6l#n &?d1<5qIyMaw@Ze6N<QNAW4FKtT9!T*Y=5BLNZ1eBatW\+56>+m4VFkAe$>HS=\Wc\h\Flqd%a8YE>uE
bY%K8p wh@T5wJ#QAdItMltEHaS&#lE*Xw\WZpwYqBwwcBFEwJBXD/GFlS@DB<4A5QDe\dY?ECCGJANaCZ+dICK
*G5a=D LIaB%8H<49t?=u^dZ*QdApCdVctRMRCd41X1n$&4\ubbV4Z#C#&HV1AeDkXHVj?%K?kuZBuaIhK1<Iej
hSuH%@ =jBR:k:^qRV^F+Qe^*FLqIdN8C5tjumSCX9#4LCECnFG?wcj=9N6:pym5ZahBeKNe>Puyjw&pYX$%X+*
8uJ?9p =iVRtLWSNS<BwPqqIa#uiTR5CPL^1yPIb^!Ji:JKC?Ja@C?yy$eAP&P/5YL=AaeT&aFFZFetWd<Tjm^&
uIWVNq AXeLd&tBKn@WX#RPD@?da^9El185X1djMS/XjMw%VeNaj=^9:t6i\G6l*ppXnKK&hC&KiY6#5!I%blI&
Wh!Dit ti@yRdMJ?B1cpH#qHS\Jp/<AbnmZ\*u*1GPS4&Htc#kw^=tNiAMVi$Yq1VqyLdKDFE:t<*WuQ1^:I><Z
:W<!yT $T=58#uRCY%mbC^:P/YAhT*4p^/TGECk^$1%EKcE:9PC5MnZt!CHYhZibFiHBQE4%CXAw@a&V49G5RuC
&qCK%W LtI6jbhM\K+ppK?&Rlb^^W^=?Y!/aB9I%qeMD@eNb^$B9\I&&Wn%M9k+8XWY4RXw1bASWG*D\CC&S#yt
-AJX<M 00024e8e4f700110334 Page 213 of binaries2.zip
m/cL8q pwh\ybP8q!YKCP6Y5k%HlwMaB9j%5*FDDuiNJ+aEZ&MwjbG9cDjFkLDI%#6M&HB+hKBwdIn/^a9I^KVd
?5+w>B QIwWC?C?@Kt%ZF%Q*wkSF^NYlTyhY#hNdG@L?ZuTcnw6=wYM<Fky@M=cFF>N\lKm+$Sa=ijE1qARm<Fh
KZl/Rn dlW:wQp/IAW^h4>&HmK?K1Fd!LD9<uSPjySPwR^^LVm&ik>I^tLtHbG64hlPFic&MpuL!k?Dct*8I%RZ
$@lPqE ANiW4njGTpWW\uBL8/IVY$uK$=EaDp&$V:TjXZ^6J@$cd+plZ*E@WC:HC!wR&Ia:1GCJ5dqFwX?Ll6VT
!8>kFX lFyW5Bh&NwBB>Cc68k@Z%n:>beR5e<LkQ%cemk%4LtD:V*8SFZmcP%MN88yhEnRP9ppBT+TNCeKCRa!1
?DuWTl 6yeE5d?Zm9:n?*@BdV%MYFK^M=:CW+T%qRpdDK+RZ&$F+qk!kCw#8dXp\t1u6wd:?94?:DnGY+CAua6t
?+6Wkl 4n!NJG5#e>95@XSEc!MS+G5j$9WRtLk>&bSJ&LtpleBGw8tqJRZ4YD4/>PwlpXeHL&j<I=P9=*&?GP6Z
NGPy\C uHk@=F9D>SS?bP!RL\!Ebd1mA<6>p6w<Ei1u&/XkT>9CV/%hu:^<FGA>FZGFJqAR@:C>ZVhlCSY49J%B
mn#$1C a+Yy^Qc&i!nmDA>FFKZ?a1ZQ+MDJ!+cGSWG<y/PKCe9B^LkKGMe/iu@:SQk/$&wi&/B4@eEmR<5KN5S!
KjkMtN YJ?^M51SX&!:aM%PbZd6AtAhDEWb1NI6ZXE^q#dM=AKRNlKlG5MDl\=hZRD>cuRIyKQ+BVJqcVPitB:L
=lk?:T JA<e\Bym#NKNkln?9hc9*TmH@jGYPEDyw:XQ8dWlZBWE!K/BklY+luP6&q:%PLD8Xw=<WRF^^LJ&jdl&
&?W%Ih FCNZjZqZ8cqw/XDh5G=ky/hhG::FMuy#I:pcEZ/P=$1eW\6yB\bdt!:Lw%\h=Gq<QNaSI%#nFJ^Ab&j<
l:LJE* #TiGJDaC^h1LBR>&ec?1eQLkKmML?lp>*/=BYN@+1b8\$4?h51hE@CKqTJ8MLC#R9KaDcA?LVA@*RZN/
hHXTBD S<MKa4kmp>>*Hi9YkynNRdQy9y=DpABXmq5MTL?ClkXee$PIck!+i?iPXLC=t&S*TnjSNS/SR9@9GMMS
m#@T:u nT1umBWwD*!Zw%dlb1@Dk:m?M?EbTw!dahF&G4tqkB$\F%C4uddt!GHbtcN&lA#Gj!NeHSLEHVGR^JVK
Kkiyy1 ARG<m6HmZ4>T5XYlZ#C\mG9@/R$=RFH:PtKAE$ym>HVe8GaNiQZHuG#/nd=Vjcj1/4IKYK\GF+<y>+Y*
aJ%?k9 ?4uwj^:AGX#Z>^$C:X^\6jR\4N5tae8TX/>V<lYDVYk%CX#y6\Xa?wm9bDaN+RIwZApKRnp&bBJ&%R\e
1SQwW5 8B^a*T4b=k*8a@KmjNebVl/E*+%+R^QaY+jy>j88QXkALJ9h$>MdZtT:8n!ddEt=Mq*ht^B::@%GcXk\
Fbu%\S p#4&DKEAn86cj&a4FeQ$95Xd$p5RXk@q/5J^c$VaEPCcNdmJ<WDHB9A\LykXjHZ54Vj1?p+B5leeIa1>
DD:/:E 6LX%MBL@!BdtFw=hQ@dX?qj4%?&W1=LCqh8Senmc9L=99V1B5I+mY*>@9%9\FZ=dIhT9JIj>8FpRCI6<
d=+wnj yiE*R$QAX+Y4+P56\Xj*AKimHG#?caV1:544#wVqKW:CT58y9Z89G>nycYL5PRb&5GRL8c1V8EXGE=iE
^RY>yZ T::Cy:BJVNjJp*GMJeypHd^4+Rh8WR1&T8B1An9nYw>L$HLL?9n1c9B/NCYIC4^ERPp8unmW*HGe1V:S
6CWM@j *q#*:\:Hjn*Ry9TNw5#&$mEe&:beZd*<*%udW!MnIwyt$$=taS&X/$wwlH5qMZJu<BY6yhl^NImb4!CH
<FjjJ8 %#C9lZ\hC6>^KXkXl9Wa^B^KNC^mWKqm4u4huVWS&Rn*SI1!hbM8X<hW5hN1^c^4Dd^4M4DM8?IIW$MM
cB#p#P T+4*pkktaB<?^C\5Ah5TR>5jQXibc5h/y=<<MRudd+\X%$Ia^VCGE5hHR%<BZ+tlnwGq<XjK99\4\ZwS
lB1!hl B$j@A!X:ZMk1kEYiABlj?QPJa+AyZ89bXEwubi8Xn6YEZW1Z@i$/Db4AtnXeBu9&w@6u>V\aeGD>TNma
J8^S%N +85R+W1EZhPE#j&K@XjSa%w<eE*%4Pe6T!/\Dtm!ln@yK\+?%W#!jJlmaEX<+5a=>Hhtmy4h%EwFpmAM
N&ye?C 1$qZjDFaVwAy<jWi+ww:Z8Qp$8GFACP!qNKy&9@KE#F\SBP&8N1JFi#+/8n%cMG^FabbCc5B4?N<9+=R
^9I^/5 @iRmZKj?+LA5#6w:$ScA@!u8EX^i?jtD%*:?G8qZ5+=CRT5JP=jB!VDauBPc\NR4:ZW$=uL=>@lm8NkL
cQNH6$ VYBc<py<>bMeqwL+V9kw<:ZjHae%IlNm4HRpw19b!&i@i%VTQd#YZK4q&WNaLatF<eSw1ZJ<L/w5RMTM
9T\6Je NYEN#/m6<ZEK@mP!VZG\H#=DM=>l^di!Jt#Mj=N\XcMy=H+5>ZacSE^@NdC+h+BNa5CXYcq\XP\X1Dyy
WAMuQn =Cqk?kP<Qj4pu!l@Yl4bKTT4p@wKF*?8QKBVudXhbSRGZ/p?eZ5:HeX?>Re$akJRHj@w:Q*8?:iN?W%w
<Tt*/5 EMPQT<D!yl\AX9DXXLC>k<dpK>hYyL$!X*i1V?/c=!Lb8kaN/=tTCd!&C&\=pc?#%!PK!ZmmAJ>Yt=JB
m*$dc: a4<a^j6=^y41+FB9kNcHwFu9WTcY*4jw9\t??6*AXw*?<auT5HK18NLW9JKDNi\mAj5X+YwIZ!?1#q@n
mMJ?L@ QJmLn*:\/PKnI^iQZH#$/G*P9D6Fq4NN1D4@<8:KenYni9n\k\i&4ewyDMaKw^mjqiGR/bWR5ZX<uQce
bKmq\V u=Z/qemGLQW@nGNXmG?XkF&nHde+$wkW:J$\ZtEj8+1**Ac^KmJ8@?^E*/cAXbS/@EYa1B+tX/q8l@y\
HB>JX9 euZM5j>e%!J$:In$Q+!!MuX$ZFmEm^T8a5S>!&YbZ5iqbRB4KNdTR1D/@C%\?WZNKh#iHFGndI5JT<A8
BVIYPa pp*MJuE%!tFE$KSy%5t1LP19AhXZH\Gcn+:RSL&*+jtjbFXF%9TP59SJW>YX%b$4mSBki9l\KBV/GC$y
\/JP#w k:FGb#6qHLd@a@t%cl1WPIw>#cBe8=G8>=WeH8lc>YQ%V\8bmd^5G\k4?Lyu:Z8C5HjCCbywN8*^FIWH
VXZ8/A $l+<MS^\w^4+<H9<l1DVpN<y8/+t5Mtwp$!Xw!kt%GV>pd8iabD<IVqH&kY4FNlja^*MR/!hPQ/R\ttA
\AputL bS!S>RFh/XKEjitGIm!QKDa!ALyWjFGW\%SZPM</*<eX&*BiBW^jBXVlnu<<?wQ^GpKWRZYt@4i!emY+
J9QRC< A1wTMP$N>i:jH#JhZ9jB*Q6@Xd>GIqmPTY#u#Z?c4\DK&SC\E^$Ap5NDcC%>1k\uRXk!uFm@!lDAlnpI
!SCKe* j9^AIMDdGM8Xh6*XeJSk=e@?MG<$%SunMAY8R5Q8>RLLeX?Y561k+dNBu19G\<BXBP^Z:%%8cnwPqG%1
@<Q?G\ m4hRRC$tT\m\>B@=85wFy/Bk^hebPWhD^Vj/^SwAli4m+CJbVw9h4iM@Ti&IcjbQF^HWm$lTaP44+hhj
yc/jCV l@8S%^HhI$j?YXJcW>6=/=iXK+A1iKGHD/?8@u>:Z^5V=*t8Ge6@eCRM%ty\XMtnkblnA<ZEnm%9Hi$E
F@YuW/ V:*!$IuPHq8BKPqSKJphd&5aXydGdGARICWtj&4%q^i4p9Nnl/adlQB^Ncq&BSnC&cEdXchc^aZD?mMB
?=+!w: P<JcEkuL1w:@:9*%QM@>9P?L$>?4jYiAMeaa=y44@u48?:w9hX*1/8y1*9qF<+9Z@l&CT1mTZG%d5n@b
n%+Q/X qpHCXm1!6\EJt&tMWb^wCB94:d%:4*iC@ln4:cli1Tb\X8+?EL/YdRI4\I/<%hR1R5%&cL99au&%YHC<
dET!H/ 6h@iH>$Z5><IhT$a\ywelp$^P6t!%aVtaJW&8t:!Pu5JldpF&C/#p6m14bu+C4n?M^biikqNSBmB%aaa
*?jM8> ?H1EqY#hj&PuJ:P&yZkekCZC@16de9*1%1@?/Xj8?9K>^<VWW$SW$9juh?hZCF&E>4@<H+jy:@@Hj*@9
*E>ktn QSTn^k6M11AK%/*<phjlh8TjZu4yyh?<@>L:::@@&9899jcu@@T*Z\Pwj@n/D+l1X>hI%$kdcaakYT9>
i=jT$% qVY6:><wdbnkWu8^KBQ4bd:YFqKF*udL%=XGW+4h>6jVFjyaI6RNdPPa>m=+PSC\>WVcA><<b%KHCc6m
Thm!<H +1\a&ptXuw1S^L%XhC56Ly4EXeE//Y&ljpwtGIF>5=uPq^9NYZMnZ>L>D:@:u=!jyp$:uMY1E*c+*TA6
P\qJWa iP\*lYh#=NLE/j9*V^<<jj4Qj\bw?AKcQpcn?=MPXIAQZRD6wInZ99j+Qd#j@jNh?A+HV>?@hGum$1YS
IkFA*? L6R*du9$S6edZa@khlT8D?GP%^@w>8GHV+<&u#ucjBT\H:tE5MIQp\G&A4KX6a4i5*IG#P&AFNkcJ$#p
9*HyKF ^L1<5X/kc#Z^6YMWm#8T=?Dw\!V*JN=y%Y9:SP1thhhK^+4mc$h+HE5!u85iaepT&/1DWNalK*6\m4Kk
n6n1uu VMF14LB!4+L4R?w=jak54TQCI4Cnha%EYD86M*A=4@b&LJb5VP!cujkWIJ%FIYeEh8JTHMC+n?5*Vk<i
h++BDy 9H6cN19AP/cy8XDM^q#+&a/jpI&G&<G:k/iHVl?Ed#B^H&AF>uY%6d$B6?W*<H4$/DLeQu@q$T6!Qj4\
=:Pc/a KF>hSNY8Lq:FpitH\DWB1Qy<jXDkCl9%&jdm&:*ii@CyL1!XM&GSei%*q?$B6muF=t:eZDKck#l<*+i:
D:?Ay\ cZEL?N+LlK1D>y8hJ8#&@!PuP9EF6^\&4cJme4IYYVHIImw5GW/S=#A&hYLCQtaEuP8dTFnpK^LY<4Y8
?wF<hV pZ4l4TJB:T5tDbdRmaHNYW5M:<dBEN>a^6bEXE9CKHVm$9*+^H&/lkd9\&%n5IPNLq:XeQ@55>uQ/A*@
4<!Xw< bKFFj*9?1/G9+J<Jy8kwcYMKkL4<B6:i8Dy??iyq8X/=@A4hAii8S&!y&\nXJEuB\@MGh4lTthH:4nKN
XL<GB: 9cjykIMJmt?ALM&c\iP9X114lZMQ5LyVM4kmZ=iuScbpT%Tyq91YTHH5\54Km8d4!p>*QHQjd&V@iVq5
$6p?&@ SlX@VaXCpLZRRn/Cd>5tE9ch1^18cj5aLjCdDqeGh1\PCD9Y?BTR=hM/CJ^iYhTELRt\ZkBPm&C=:ESm
YS$>Ti Vkn5\1YJiQ^?jGnw@6DRX^6DZ%qW1=Gw%$S$m8/A4nCZuP*=Idnm<I1IV<SH+9k1Rb!YAXc<^5e@Hd>/
DASL9& >i1u<MdkGwkjQZ4nWi$dZaB@t/nAJ>IbHC>HM?#5MFatIHCKNdIl:w%lE#Zmmy*WAG#5ZkhdanVE9K=S
c#Tq9$ <dXFyGjE?1Kwb^NyWX&wF4wceL@==R:K@>jFEG>\TE#dae*/5J!q4Fnn<HKe59lYdaX#huK%4jq9@lq\
><=%t& jXN\yX+8kLPSS8#\%t\eLASPJtNTLua#8DBYDudTTFmWJWkC5lN^9N&Qd<R*+GJT#k1i%/:lG>$b+6uQ
:R*NIC BF#<&w*:<Vmm8nCT>GAhl?9VV^qW9Q+I6#@BG+J:qW#$MlG:dbpXydFCV+jVc>/i$JGCCb\KQM8CpXP5
9^<PiG kE*^ElFV<FNhh=kTSqhn@@4+%Nd^+!^Qku%Zi=8cGNhhK\G?%9<$T9b@9\SPEntJm<*a\%XLYVVG1D84
bK+tkT YY9D%%IAXphZiMpmwkn5t#^Zl!^6SpV4#8J:=C5u5aW^KnM@MbG*5eTlawmDFlpL%\JAG%@aEFk*SQBQ
JP?AEn aMZ*%\lekbilSRW=@PL+B4\5pul!ml4CdRk1jQj^*QnlV#>>>8#E5^MuV9#^^B@XlTmQw=uGHW*ybb\c
-A?kSe 000c543b2ca00110334 Page 214 of binaries2.zip
b?9@*p Yp+VZ:uyRMXNmG55Sm$ED\1FCV4Q/tXkpdK^i<SZBPj858M4B5R*n&>N5hkX/un8JXTdTP=^^d</X81@
p$YjpY <jeqPet8Z%+HD<8LhdAYJm=YBW?=TehbRhc5wJPIKSJYQ9b=kLl?@CbeH\PYw&jJ?n+hk+h%LE8AjH$A
NCjP#: phNA+\qnDZk^FkZi*V$>H4Dn&S!6M!F=W@lSCXq+QW+5HFw+6HEwjwnluGW\CWq>GcRSX9n!nWPHJk+6
X1^6#i $Hb!<yMp$y<dB%l#BqX%Acwuu9*^&hXQQ^$uT\*^G?=?IWtVNL6Z>1>&hLeN:T<GV6k5R4eaPXk&^BRS
SSb@<a e@H@p19dFa5u@neKST*S%aR4B=1cPm>&hmK58#^M<jd+y<@SJLD:X#nZMV+&RFqB6qTW@c=G^d>p^SAu
n&kYE& >jELH>a?iBQ=Cl/YeEY?nnW@yiH<5\!5/ZP1dV^S#H5l5hRVJ+N<^awmQ1E+5JPlqXB4C&64E+et%kAu
GRCTIF 8DNF^RljR:WViiili&*ntwIX<lSpHmSS&jEd\NdD#\DZE>&E=$6\P@E?j$B+u*&Kbn4:SbbZ?4SSjh=$
qHlKT^ Cjq:jS8Sw:WD6SI+wai>h\<h:ABGV8&IK\LWjuyV<jW!S5LHq=1Y>yH%9alTnJ*HPm@8Aq#4Hc4<+eI*
X@5iT6 #%?FybiIk16IiD:YAK6I/%ViuYyiIGam\1cA1<%Qt#@?GHEhR^t=MamYkK>uSWipYe:cB:w8G%!*<^da
>tWkkN dnMX/^$/+AEAK5Vk=mC1<\C8c+j\&nnpW=SXdQmt5j*5Gu@=G4\p?6FGbba#6LR16+!^&iHNb>&qE/Wn
8MlmC4 S^dlJ6hLS$+eRYTB^+jHKVSHh+B*%j\%I@9X=SpaTaHX:eIBWeR^Sm\FjFMAc&$1%q66R?K4*ddCe@p+
$1Qjia 4dRAWD8S1E$ZP+@SdbhQX/H5u8h4mNlhp\dbVMAY=!a%6J6K=H*Vk>ZVepEdNja*d#=6j9wt+Ay+59aN
Al48Bm clPM6wkMnn9TRX##9Q9MbMpqN?*5\JXi6tW!kGShAF1p:AJlhimnR^>>^lR%eJKTnRMaeD$E><<PHXw:
W&kE+& BC<IlBXiIqumK/I/idn:YZj*EaDXwY18E+5u8y<>P*#+^?Q5EJdNL?4=X@MMJA9e4aibDhyl?CPq5Nl5
T9uRn: Y!nec:ei>lGYt+m9S*=Geu&6Vj8tpclNB^BW8A=e*LZ4wk<1Zu8+V>G<$#tQ*SdJ&=#bE1e#16pqnC^L
TjY%LJ kbhaD#\A1=bKT/i@Bq\deZ1>GWq/FttKplPnb$pX5tY58Xamy>4Lm$HCa4K#&V&b$#h!54djCkqdAXR#
biHy?@ c+c^AJuny*j@!LIZ:\D@IWG%pkFDt8BiX9#?!NdFE$DX^TP99%=<*X$E>IuTmYe>l*NAdDDb*Q%K9!pB
4XM!M! c@l1DQEbJG\6<^WIG!Nk\SDQIdC^i$la\9Yk<c@=@>tK8$wA%&uc?HVk&IFnhN$?5P6ApK@wZ>?JZmDK
DmM64a /=K8t#Zh!FhBqt!^B/!ChqLySk81kjbBA!#\>iPua$BaiD</cuAhHWNSZyS^yRRYK$:A%&JiiXm#py%#
yCK9/q YAY4mauyGTX5MZNeY^NwQ#4pkSpqRAZaHtJDDQ<PAl=/Fe5PwQHJ\+i:1Wm/YH\hjw4Z+ad9?J+H5E>$
JcpjQd h#@4GjeG\%!DNiN1LhcDFD9aLmR5QMV*>&LatJuCS4:&cp=HP#18!w9/6Y>\E^l1NKPe&VFGhdlliQk&
#C%dDn \B4ChYYq@y&hJtQ*Z%hLj&%^ApPBm1P5lZb!y!8wMt9/&<dRAD>F\lJJChiuLRA4/1<B5I%kyL4I\%=Y
NTY&5F ST&8cdGHybBaZn4cl!h+TBTiV*kS4qXt%tbtD8Eh8inWhK<FMDaQAZ@+&nWEN5G!%hu5Mk?qAK\uIB+u
=>FH4* RCu8j^%C@>eJaTB6eZG^?>utaa4N5$+1Rh6lP*?T:t>M^YKAK#6aNM4waAHZFM+yWiVEy#Pje>m$@Y>b
+XjDkd NLY1hd4l&LEGBuX%?F#D<P*d8&=n5cqi*p#e>E+weVX9aweqeqw\!E4@SBDacGl#Z1FJc\e@iQw^?6Pu
^*ypF\ \6e:b+Gn8<t>%w!m@4$NmAjPqMVHQNq&Tc!XuTB5e=PB@+ipV1pp5FaSbD%W\%1A>4Q$KwB@lRpKX5YN
a@!^M/ Fi:bjAc^\!KmTk8u!*<ud*AlkeEWq+C\p!HCE4Kc4&!Ia&TIW?^lEe^:GDuXmmEY\4ajQFLE*hd@/@mW
$Em%I: KK8n>G9D5iHd\NYc+jYV\Njdi?4DjQZcJj\%D4R>ujmKlE$84FpjY<t++CucHH8wi8I<Sq@&DPCK5D+F
CXcKc* hHE^BiD/hI#+T66qY5a+Hwd:l!XumNuD=mZZeYi?H4C<ykPjV<whAXXB>1?+D6G<J:Aej<iMV6dy?HFS
/1VDeA WuSbe\wQ@w:ZmkQe<tL#K?FBZI*+%APKmHE/FKmc\wk+%Z8QSqyTCC^EVlRT4=\/RV%HQ?NqnQCiJH&H
B$:ItX +VyZ5*y!>iV\un&:Ltn:c^+emBap8Q:L/+19bImJ5Dy/emtQkqcBt=9MlYE%!D+kZMhiBD9MG$hc^ucn
5!BW9/ HacHKG+KkhPA%J!Pcq\>D\8YtG>/tF*6hlBp%!w#pcwJP?ub4DFjK!bby=MPhK=klG@qGXYeR@kF*P\C
VF//L> Y>VCAE9ejhk9\lkHG?S4Y+EGp!^l!eQGKEkGaIt\^Nn&#&@Bd@+jn%P=H%hdVK?j1#tHC=>4%p@mu6E>
l:PeD/ i@beCEDKAVF9lkWehVq^9/D/\d8EK^lmDJ$YMk6mmcYD\8*Ch8a+q+9IK=$C1hYZHj9+/Y+k:I59Qt$b
MR@LXY 4cp=Y\P+Ay^*c8DCHX?P4$i=tLX6W^%yamNk=bwWF/9pE&*IEwD%&9ik?yEd86eup%my^X\!H>yQ@A9:
Sl@aY? klQ9wEe=jd=tZR4:IMZcGkWCF6/SJT:keCF!q\mLKe5y:C6+4ZYK6@hNdVY6%\C!\!jQ%hD%&PH1Z/ji
JBtC%n &j<nJ8h%nJV&:@<Sw9!n/:^pY@lKlMW4a\>*MlZX*y>XyayRFWlFEXp^\5D*pVHpc<8LmC/a*l4eFjVm
u/u$Fn GPN/y&Y>bY^kRIA>Ym4yp+Y!1%I1aF$#t^&N=cplGiPetbu=j5HPn$lSkRh=canM:K?qB8*TaqHX\M6<
Kd%$VZ iEZpJYnLS8VE1<Paq=j\%S=WEtGSudWnawlVKR!JC&TIHYG4P@+N@A?@=Q&yGBI9uc6by*Z5h?:W+MK5
*4*F++ C$FeDY$QZJeL>/Z@/L1>:HyZ+m9ZJ8kA\HnbSNyDq45Dw$GXMyNT=WheZ<T+F@pKaPJ84>%n*>&=e?ep
/nh*QP +uwH:VCZmA8P4!ap6q&uQhl/R>$*QZb$^$5^>Pn%Z&YH*hm>tiQq%l<<+Eba!<d5=9t&Lh/YkTZ*$KN@
#IT9e& EBMTc@@Ku:*QE/IAap4$n6kR<?j86XeLaR?Y6*@Vc4\4GPJXZB8L?&IlI^\>ijICZA=Pba5QMC>q4:bD
i\uMqC qek18A+N^yt\TTw<tYJ^^y8%!w1kh<=VYwwa+cGIJAptGP\8\LwdeCW\Y%:EFa6kaP:kWuu1KAB\B^/b
I@CB5Y W\W&^I1\iK:DX+<9LP/&J*FXIIn5n4b+^m1L&jY%JtychC?8equYmNMJ^:d1LFCENdEVE%d#qRuLBWTP
KRXbK6 uFJmmIG\FDuXepmMwXQ%+P9d4%Wb98L81D56TIP#h?48RB=B8NbHPhkLd#E^#Xy6m:LBFbjRDR*FnaeF
eFh^Za YNh5VVFlF:G1j9?5/YQ\hh6>bN8?j9wmLqX<<eZha@n/1%q9&h*Tkn<!GJ1Y>jYYS4HDna>KPuBC\9LB
iak#J> DlYh/EdI>9mu>%+XV!#^S#QB=CcW?ClWhR5t$>Y\NS?+!m/wY%\5&TPJ4QK\mP8p%#KTQ6Q9CI5!G&TJ
%*IEYE YjewlaTqpBm8@:d>H^DRKhtR&$RLY5/iHd8D^>au/!@WZ/mQe4A4:#A4/j4kA\@WL^HYK\bZh4Gc5iJp
9<>elu #dJ#nY#YZ#:tME$\Z#PncICS5BA5uV6=:8Rh*HY:9u:8HG+#B5c!Hhb<NaT%=+Dh*RI5EdjH4&*=hjjK
cBiGtH >#6aJ$FXWZ!qaJlq1G!8^X9E:TL^9LHQdIt:8*6$P=jD%bewT1NnJcpW=C8GV#m:H=6uRT9naV6YPkb@
DdFKPw <:Py1TttK*nayba^VA6HWh%&FLYw/!QnyyYXL:@p>d!C:BZD$\@M&q/EhRMnatJ5W6WW$#4q<YKwZDT5
6$JZ@p mVV*EMA@@N5Zh#P88%6\#jm=hTR5SP+uG&4Y%\%j5T^leQX/Mi!=Dq&d%KVaa$WWA$WBA?^H*^5+PR$1
Z#6iNi u/?dyuQYdBQQ!^b^l/&p%<YmqW!tJ$D5l5HX5Vmd4kMeS+mhdIq4KZJKyTS$c8jRccZnQ@>$T<Jl*QnY
Ah9WB& 8p/LQMd1+EMncYZY%@6lp@#^%L6ETdiAtTD>WqCq9#4QjBZCJkqa=&R#kiHZ$GX\#SnuC9j?Wa^?AW8\
bjI=%8 985u#$Gcjie:wG9NKpP<96+5:4Z=nbLy6etdtyN8VtT?TyimL^in5l%nmGj?C441NiK=4NP%KV6a>YYR
Ym<Hh+ FT=:L6d?<tH@tp&eebEV&&EmLH^14qcF^C54n=i1bDpaEZc/5a:PNWpD>c!B6V:wZ!GF9VJw4!5PZMSW
>IjNj1 @pdMMDGYLdGldCJVTXS5dB\k4Rh1\pKKLE<uY*b@%%LV$9Lh:8@Yc^wkeAe\d>=eB+CHG+C81^\*\hZ+
Mm<Ha? SmqI&HLiHP^\^:JldPCw%&YQD6n9!YC>cNm4NSW6eHt#S4^a<1A%@i5mI/aNehC@<5<t6RqKYNuDA4D#
Y4VP&a ?JGBdc<YbG>ZXbGDyZe9NKHRPmw1p1kmwB46Zqi1H#<iApMdn&<MYZAHFhTDR>Tk=\ELtc#!5ynMb6LS
=p*Gpl $NwcE*9X6Nn8VPbB!>lN<KRaLc$DtMQu%kHYtuQ$CHF6Fq!d4&+194KHbW9M%WT/t:dmZET%J/A#>d!F
d/#XYI E+c\!k+:M?#BK89ET+K6A=bh4B:Qy=@D&tG6me%F+4ucqGF5LaXPKCmID?<bZQh\$b<:VCHVKZADJ<y=
hTImXt pVTRR>cH?E8&59GN?NDRaQAca6ASXRdYeNdYm+QYtMQn6FiL\IbLA!&@P>*!Hd4S:*antkAt+dwKdB$?
m1/MB$ 6\1+4k85A&jCjN$8=<$kFq<$b8BCJ*ZMwHKhtWnC?1e/Id/!N4ahI!8dI1bhKF/$$Nw8LHIRQcyi4i&\
W\ReAh <1@bpWI@t%%$5QmG8CJlWhp%qbwu\4aDYli4cJe15Zc111FACu\FpyQyYNu^11+@#YAl5l6D=#%5\dX8
N4wb\l mHP%6:k+YWXbMMh<My5&Pa%FXhkc8GZPAE>4AE9AhS*4&IAqQtwaSn8<19#4?Kb4m@MIt*jAEtED&:EC
kl^1Q= IdFqdBTi66!pwtFFX>5>bnLu$1deDLb8!pEWHeZdt!TYeJ*W\V1N\1IlVmGG%5PtnIihM<WJ#EXNYYKL
K6Eu+% I8K^kknItEqw#hX/XcN+V\JhlDcPRAKW>Ba*bAWw/W/$NVYKVDKnpCY<Ey1#cZX?a:<I*^L\h9ytC<c>
4Z?epW N:<VZAHNt/9uG9DS/84//y$Bc+hL4nDl?ql6=<Rm9T9=deZbdBlaZb1+>4!\TeH1SFtNyILa+E*bE?>/
@qjQ:X j/^JEVWM$\14eQZ#X@n?pP4MF*VwBNThn<$n9tmh=>6uGXkkLI@QEYiuGlDQPq1QwHCN8lBabCDmNSE*
=?RZ+L F@di!pYEFtVnPyhhW<m/54FLcnpR4nm@t1abM<J%hSn+C4k&DB>D4:wK%@D\5abljEV?6Y6k+PGb<W$h
nu&@?> EB9CYp6ebFmDe\A/cK8phc+#E*Z/i5$HN1*&/?Y5GT=d614Lp6c?>M^a5J=J<9!4W%q=pJ4u^MbeRFMp
^WhLHp :N\e8X$IuYbDlK&1c1w4!L\5NnK8eNV58>h/Cb$tMlt5JXuT/t9l==LiLQm+wmIG=:I&=$E8XpKKVktB
-AtS8I 00048da4a4b00110334 Page 215 of binaries2.zip
hB6Fth $*+Njl\FuncA:d%=E<EEPIGp/<QaChC\Cnj4Z=8j&S:Y\D\BGV^mTwq:uwT\+aMhA/!mdESHnKJ4JY$Z
P+4u8L AQH1CY<?WBy>/M:aq4!jpiW\8yXmnw1deuwl=kmH^HPc5Kq=\Bw?#5&q=u<uwXQ>AjG8XHh19bQ1:cX8
RW#caI 6+K$pXj9FBR@utCdT4R%?DJFVhI1u%N+T%!MdqaH^\qqnt$k:F@\=%H\w5PI/?y1A<B/dBnyTl$i8A8&
4/:MTq Aju/EN:i@uBV?hi!I&^bCI8WZT!Y8F%eE#aZDJ%&W1>Z9SJiPP!maSaDpCH8pt1M65lKB:YhER5!N5^Z
R=BM:A J8!IELbYE#bFwSMSFwChJeK&XnpH8:ZWtGLCap&=ZSE&tMhY4>#Fy*8BpGWMLd/CKL@FHc=ejqwk$t4P
W*4X+5 Xq#q&J:KcW\V@PH$/nwi@h@<+e&GaY:ZYX*q#l%kc<N$m>D%:e@6W?aSqnVm5j*j*BhL$qceC!i^kbla
XSC!wc ?>l4RXD>eNlwAbVL+q%%A/*Zl4pbNMYY5b+h#uq&YHLaPR/hWpJa<4B#TNnW9XqHYItIMhW=t/KnH#1:
ymEG9S NeHXTlSu!SI#6Il6^wE1N@c?TTc5SMntmIhCa%8CT4Q@4NA+tYb4W1Pd9ANtGQn/\^<CuMiEyk*!wGG/
QE5!hm +idA\\G<9@&KQGP<TId=?5Rh/!!/\w<e6W>P=wI^eiAk>1Pb/FYaZnl5#%=:nPmC5<KBjl>H&cI8Z=Ve
AQGn*t aY\&Mt+m\9dQ&=CaeEW$=!%l=\Fae4EZ?ym\W*Sc6%VHJiWa^5<P&HA:nAMY8aee#Mn\pueVP+!Sen^?
^AGeTS MD:lVQTcbD%JX#itIacMkhYiA@H%+B\ETeSZSQMA\#yNLi#V$/9V1&Pe=n\eiKV+/p@6TWYQ&a1&iFEV
&hZI4t %8>D4/T>tDkRFX>VhN$=!=Ey:e&wBn$B%wWBbV9VVV?L^>h$%m/e#kJlGWX4mCq%uWi&I5cW^M:miYwX
!QdSK* H>SlZL#X8m/JEYI48P=Whnw%adtWYTMapLh$T@J:\Sb^9jLq8&>hjM<GWBJP&/y^J8M1T^Z*iqG^<@%#
E*nZdh !NQXXW9ZcTDy>DEEFn+C45BXRLY&?bunK^CY*c5e/=RDqh1AaH\AYQ?IjTdRZ?wh=8l\iHLVTLLR4GIy
MZ=@iD GqhGXnQYQ+%%>iGe=%@V&iWCbnc%DqkpdC!Fu/LQYeL84iIYa8S4XX>nQ^ymd4MAaGjJC\hKV^IWh!lk
ycG5Kn p^q&tRdVBSe8V^^</=&>1C9#=WFZY$^!p<\clXBBbPXd$6<c#y:Bhpq\yWDZl5+DeD5GLAXRP\>M+:Zc
ckpp&H ?Dc=%+iA1!RSSeF%i%9%uPaZiWm?KDpQ4i/IBDdwatimGy6$d=MYim!4<j5hY/XDnCXk&eYG#uMM6Nq$
>#4X#$ aa+IP?emy#q&5WJahLFEYPK4uMT&N5S5dkSSM*4luc1JK!8uJ6KB\FYCbHp\Ed@@=$=cuk4Zkc@iG@K!
pNmB$e Y@c#C=1WKtBc5!/a@@+$+n4h<P*16&B<D*Tm>b%8/MVB9$:Chi#6bkD%ai&HuCD/h9mJQ1@ne>Cmt+*%
!FWFI4 #*Ze!WMqpP#MBB5q&L*PcC%:XjQQj\?5EeC/1DkaD:8TZHcp6u>iR1h?8M?Jm$YwPhqyb<bc\1I6jtH4
N4ySYT dD>!t+GX4+m+yQS$Q/PCX+buneR#J^aP9wWKZ$=l5iQppI&jHLbJN66BbAuVBWF&Dd<%+N1J8H/:Pn%N
w?n8k= LEW+cjTEHnRIZ>>?bCj%nB$&1GL@Ll?F*4Ke6TPWaeKT:nX6Iym^S*a#RXS%?81K\$aR$9P8M9V%QGBF
Nt%E/^ c:BHeM%G^W%\FhChP5bmVcKjQnW*^+SqP1:eqnMhN5YhBRRYZk4+6YCG&SJHNDySt:kHLIMdQ**@4cb*
SQ@we& twCtcAd+/u9ej9eKFS9n4maX6/i#TV@&bi<1j:XGj=85AZcCK@*&&&?QMW5:CXce/y!idyy8iWlYiPD6
*L<ic6 !/SmajtcN+T%#j?*iPd&Fk>+LJc/>V1:kCXYPc!^^ib8W6ebp?W+9t4*81pd$Xt?QPSpZW=tVjFp8C:l
a?n\L9 pE$ZEpla=m5B?\W/XkJY1lP#mK\lLAhQXehT@j&G5QeR&EB^\9>DZhL=^M#E\hNut%Ctaty1T86t:4*R
FAPhjH *9Eil<XDWp=&STkVcuuYjI%4qB\%k+?hPHeMaET?Iy^pjiHY&aV*jak4kw1q^QE\Z+QuP6KYwkndp\6t
nC/N!D 5eEVhmc5^haG\*bVnFX\6aw5iYYG=j8dPW$QYX&k&JbDkJ#MTdy+PK8PNL5wACc@tkK1+mNpdMwCP<9X
<VFSQB mX&6t4BLhRqp/%\@W9b*5*kF!c1lQXWuPW1t=ll#hM5Hhc4%RAjAiyBA*TBp?h4RLXC8W6FQ1Cc=4yFe
pAmQ^N aMItn#WRS\XYwtqVb>NF8P*4*NepbatHA$?=AF5$HW=q+%?j8Fanh^uCB1yPkZ=m%$+e8NupXiqB>5kt
/I/LQy 68$kZRZXIGp*Zjli*udmwAdZ4NjHb$/1pdD#:FeqZQwC$AT+=9l#>^A$65SddDbJp1APETYc>^Pub&h*
=IYXHR QADwkLD+MTGd4CGYdp$=#W^+@MJW//:HHS*6h?@mci&G<NXe4uCeVN1<JypSXCuhbTPhuDk&#db*H<MJ
N<#>@a QN%He>nI%/b>$?Bi5T:ShXTX/AIP>wuWJlT5iZ?aQZnEHk!hblTm\aXhd1tI#X+6Zh$iu=\AHIG5Pw<F
%\VDHZ ^l4@tk9/X@y@&kBaNL8%@iR9EW=+cC$^$LGcR/e?\GHLXJ=i/ESL*A?SquY^5@1+LllBXb?/P:E\$pqa
ESVQe> $8ERQaJZ!k59XQZ68RBp:dlL1c5\h8mVweH#iB>Tda64DquKqBaY>CuR\y?u&iLCnXuclQm!eM&?y1dX
?F$/jL =6ytAubeE$DdaSWTc&SX%Yp!F=1wb5LPcGR69G=lX%1uPY1%p&iGe@:eC6$h5Q4eLq?Gu<ucaihjhV@a
y%q/:6 e1EjT^H8>5WZlJdpPp^H55TT:QDBVwM^^Gm&^SV9XHnmkh1V6@6\bWhXFXMXwZ&lc8@FA@Y+bK8>+!!l
/Ap@RG bE=w#%Nj^iDk?WH&6EJb#qnZp4bR=cb<FtwwSy4iB:k!4J$I=$WEF8mK8JIh:l4*=Yb$%GSdV1tQVhwE
S+F*YG dhXJHi#wb>J9P#YwS6NXN9>^J/JX5\@1qW#tuEuYQqbSFq=8w6<WyK5hEG?M55Ry65Ry4lMnIi5^hMJV
WKl9!W YAD%lSiY:6TTe!WZm+!F4*lXFTemK%CQh^*a&>jccmS8Y%59*lcX<jd&p^QtaAe=CyBK@\\?&FC<=MMi
eK^BVD 1tlkqeylH1<BIAFKAFapc$nnSQm/%DSG6iGH6W?XnFC\p8nPaiq8=aXCJ:F86+VC6SLek$tw81K@C+i6
db1:Wb +Fp^t1:KHPetR>yHEka+ZCQ=T5BTKaI5MRL:BehPuM@&##P\%YmJAh4YycZy5eIAlqyE%u:&5an51#5=
<hZAeu YJaAI6G8?k5ZDq!<iQH&un%:/89hywiVeR54?hhB%#p#NGlcW4uwKKA!4Pe65BQHPkFDADcM/^LA8w?t
FVjd5B 4ywjDl^XTnNiYeIn4AHY^eT5iS1IucIb//%NhE8:>CGh6EyI<l1Bcm+$Ji1Kmt!LYjjT:&@TjM$6F^K^
d/khnq ?Z=!yuPe8Z=BwPFu=lC/**H6ahjY<cdP>h1=G@Rq>DXkmie+nY$u!qdZ:$lYBydFwi\mAjQ^hFJMK\EL
Eq%JI% @uZ\9P=#W<MB:5AA9uLnE=4LI&D9k*hFbmK5VZ5F&KY>eF61k65$N!P?*V\ipQ*Kc\h4t9>^ZAbD1LJ4
Pw^h/d inL>@::ib1D96BKCNVAkKd9a<q1JQdDyQYmRI!lLadHkG1mA1bu@dPMeuchVG58GGEHnwDlFLyaai&G+
I^<Y@i eT:Sn*?h?GIP:niwTCYeqcm+ipjGYtCh54l=X^>LCkX@9tA5<Ti&Q=Ye:HqneVGywblyRdyal&Vk<l<I
jNqA^E VZKq!NI?BLPy4/pQQkBjq^4p:QZwyM@ZRB&SGd6Nw$@$XyaV&bLWmTh#8S%QAILAt5YJ/a4Z/h>61<NP
t9!/5V THqTVbYFCB6B&dLB%Y+phwtPE&AyAC=IXw?^@SI/AeI^4n&$J>A8>>Qj!6hR<MT&tE+Jb1MQ&hpPY%m6
=YREtN XDG>*W%!>TlyD>tHVAjnqRBqF%V:nPqkyd>I^wey>N&HNuhyd^<Am5A8>i*6a=W+!X=4Nc==%VGldDEC
6ew&E$ !tF!YaJnV/W+GBT4EV5Q&w1q1+i4Y$#56wyM=n^a5#9c+pqF&RBjA\MT>E&YB@4b^SL>uJpq$NA?T^dd
Bi&p@B QmjAwmt?RjB!ZbtI?@&J4HY#K+/\>ZXTQ*JNMbDG8qEBN!AkXR4y54C+D8LuF?+*VjWlqAk5C8km1CnR
?PZnhn mcACZb6wN1j=:aFHRjuFRD#MA?#d\qeb!PJSP>5uQlta4R+EV^X*m/J4n/9/q$1d?wXmWR&nG%E9N44T
!=u@mZ P%Rt/J>%%TK\@S\LYSjLQlcB:ben8*8JPZc4VFpK5M\NuC!h@+SQAV1mWPX*:Zh:8eLIlWF##L+BpbNB
FceDP? %lqn+&YVC^dYK&a$:!$5bQW6Ec^NLKTLGy*$<jnTeiNin+/H?bwQ?Fhp/Zb=Y\&ttyQa1EJ^5KHa\G8*
4!9R:? %/yXy#^I=%bmFn&lMdeM^KGehcG^Slb@iG8H@XYN95BbX?&<bLFecjwCL5cMamhVB8=A:IuDCYPKmc^M
W<<uAc YDDaXMYa*euDitcaNt9XVhmtF1\WL6mG+!Gi&tLKCteyqbZ&XHc8VGepdChX4%1Q:#68cd4Wb^+eZ%1u
<48dFm =HWA#dA4T^S>WLX@%Ve^^EWtdE>A9CVWKe/R#unLy4*JHKpPd*8:E?*8HnPq:\GdC=Tj<Pi*P9B?+PRB
M$6eNm P=q4VADj?kp#k/!Nw=C^uMt5jDZjL/^&V6ck!5eAb4TuQk^6kK<h>YhHZG>lpyDq/MpBP/lu6W#CE%h$
VVJuM+ JeJ?MuT\n*DhR6ZX9n+S9q:1c%%1:V6?@QlT$+CNly@LX#:V&Tc/q6XBkDV=tm\&GD\FhlFZDLCIcpYJ
l#iN#G nyu>=5X!SDl5MBXW5^=>e\FNWQlbQL+cYL%Fnjn%X/YicAlLqJ*n$kQ/ZDyyjSW5MXKaQ?<8e<1iItN5
kdG?X^ l:cCPa+CFmYP/&#ZKDNYh^54ZBY&R+Q5a#Y5lQuGqXc1aLFPjS@m8ZTe%PwB%PP6FA$*I%%#AiF1=YAX
Gt%LE< a&Xe9E\R=$&@8HG^QdpIth!Kl/8:$6wKi=M=?Tm?G9=FA16Ca@khiA?*jH%\4!wLe&AD?1eQpLAeBHHw
t>\6#S hEQeJ%9mj4LE5?$^1S*#F?GJLRM:d$c+a4EIbD6$kcKn@t=9:+mTTyPGycR1PYAPK*RNSE>TqD4Q8I15
ip6pH4 kcW4HlWlwE6I%hbYiI><Zc%q84:lbR5G&dJZ?ThDVIk16SnD&G:9BCC!Q8HDYqEmN#p:y::6:V1h>J&4
m9Dt1? G8HPBdT5NGX6*BSqlw$YId!K41d/yYhNmp=IYAGYplpPm16nJudte*n5n&Jp1jt+RMn&6yM\c1n1%A/Y
Y>56!i @P:h5!N6cSXLy1XXbmHnEjc<tw8&!J:@lMNmR%ick+hH6IBLqDCt5L88>Zk4Z<jlRSNKI^1//4J@McI5
nR!E$l \bnTpIZyKm/dhuF9P%bW>$VcB>Y8EdjC&Z!w:69l\IyTm/lH*BC!^Ni$+&9Ym=#MD5:N:8/nN?ayKBa1
8A:m^\ ctDJ!%JRQN9im<b&Zw:XiSK/%4TZ5!^jkXVIP>yZLLIAKw*u*V%d%=bwT&6y\/\$ip5QiedWudTDXZQ8
hSdnNV NGRb=*Cb%C9w4#+k8qb^:#yHWII1+u6emlIDS?Y%ZqJ%meDS8mX5eMBDd*kIMha6lXjIBtB%l*SFh/n8
TNQ1wb !d4q6JCG9\M*Aqw@dk4q4&!+Wj94^KQE9NRVMVlKjPFMMb*deP\$8%JZTNDAl&6QVhZTCFjBTGuGcD$Q
-A/aSw 0007121934800110334 Page 216 of binaries2.zip
kA*P*y LnZEJHYq9tPq@tShZiPDpiZA*HqYDV&Km#ZFyCFnmM&e8\A:NLkl>TmnTkIj>p+bP$\:t&lMnKHhPk/l
+ZXEb: XA98ySkaPDMiPKjYH9cJKp^I=GR*9cm1E%9mkFKMC+wNc?YY>1$\d:HqX9>64!!l/cw65BLY$Ma+y@pc
+DQ+Y+ EN#IPw$w&Y=%BIGhy<!t*!R:DC^Xq1R6b9dW!AnkB5nG1N5W\KVBh%pTWPCXT*YMeG>hZh*w/MCD8hAK
i/R6jw =4RiFM:a4pW#>YFt*c<MQl=WKkaI:ChDG>aMC//K48:AHw?M68A&Ne%J#pBZcPFHMS@SCpPB$:aNmBXl
aC@T?e F!%nhXHZj%+D\Hw/a%aGJwK9m1*b$JMXq4IT91cn+mduZ4G+BT@II$jN$R+XJ&:MGYDyE@&e:d^cjS>R
i1R^c+ cC!RIpYM^jkI$61C8tIF&k6*yuubYSpdF$TISWm8R*%MmP9Q^aW1eaw4Jua/n?h+q1+jZHu*HiNhbeWc
cecyR8 V&GdTKy%Zim/QBuJ%?&<hc>QIk\^%+qN%/pwm@V5$P>W5dRNXRy!kXb@j#q^dke\A^^Y\DJj$^F<Xaca
%kd$I* eM$ZQ:>l/$:>VNkj*PA!MCi&<>n9BMC&\W<?Wph/td$Idp\lmywmw/PNI!N6!>tAVqw8=DuT=phT9cmI
D@YVAN 4Cc5Wl&^$LJ:NbJj*Fi#^SMJ*JR^bjPi18tC1HHyBV$C1&=^<8m1Q!tlp=PBEKYa\Jmhk:am9A&emFw%
WWj\Kd Lt?LdXB=N@9><PbM9:@JcWJ=nq&@&5&G/VJ\W4Ih6MR*AFkyFe>^6Zl?>6XZZ/&jaIGhjwARpLXZI\A/
EtVQ=k Pu1tLWKT%M9HhmT5WNbWC6uaDn+PElbnbcE4/9P>:Lky4XMtimIh%4FcYkX%^lS6*HFPIHB/+l@4qHWB
AC&j54 1t#K^JLFGku1aGN&/QLntJ=N6@BW&?F\yKTuqTP6<jQ=tyMBL?I4ZQ?ikCWZT%ZkL&:<+Mhe*!i5?&P>
qFw&JV Hcj9V&T59pN/bPSBZTQBij4M@RilWF5hK\cV:YlkGXwEhpMK?+Vwa=?\^4&?i@&D@j5bTnNZd@p1RuHV
Yk!TSX neVZM%*i14TT+16jT?R#YI?8=Y*d/!SB5c+Wb\Q1?$Fa^ReG=H*<NCic4#bqCEph\bhL*JRP@e?K4#&m
TF#chy /tcAqaMeDy%?@IMdtJ@mm6nGpZ:eFKJFP!wW>XR!Cj%6%XuSbMAT=<LSARKdMNWJG8M^J#bTA6ai>w1G
?9H/#j >RPWVN$j<K/5taBPFn@^AunZRnMGVY:yWpqJ/SV61b!1Eken1d!bA!l/nM&F6q1t5^Gk14wimX&Y9b:\
YFShVj *I:?Ni*hk5D?Nj/X#EPSbjuiV#G\TNnEnS6km6@GhZanma\iGHe1LBqY^kyw<6mZ1Ny5+cP4j^PQ5D^S
V*c>at CaTXR=$4AYW9nT9a+X<dK%#F!Y8X:YTqdQbaI&u/u&q#?+ND@qWj4n?^HMZ4>!:ZeXy*Wmu8/Rp:S/%5
:D*hhe ElVJutVqh^e&ST:GDMWi6u$$AK@ktk:JSdLcRXd^qSK%<y@IFQeuElkEF<=$ndT%baPAJ8\nc=ChbE9/
C*W6pB PZ^%EXVY%!c%CmDG^%IT!!h%EaJ6<QGDK!mC8@>qp/@cduN!4%Ymtn^YwL&9ZVtQ4!ZF%*!a4+E$S!Iu
D9YYk& edG<S^wq1IPFy:R*4ykYbNScIF:/=@M%XG=!Nnn6***mI1=Y$NnN=HyuS%kFYiRP9P*!T+<T@jMy*G$<
SB\Ylj $Lc<4LTBuBylSp$Zt%:?CQPV<\pdBDkKYdq\?QZuq4CD+q<jK<dCw*iS49@mkmatc=Ymc>XYDhIX9K9i
JCTyLl >?*+cqPh<4bjI\+ba1\T*^JLdARKwlmdh5GP>Wj&FR=Q5=Hnmm+*SVlZ4i=1dWGa4%FyFd&PYJKej4?Z
CQ^#uh Z9u<@V>iyYG<AMtX>W%u:NTN=Y5mwlhnMlAT?==YK*St9Jmaey&lKMIT5CacB41KL*ZDIXXMYSGeR4+&
%^@<Lp h1qFYq=:W+m9V:dDX>tNh^C!yYIIYB$GBpIh6^Cwl+4Dh9Q$y8X4kK=yN*DncXbb$8AH\6WRNl&5JE4/
SQGXcF 85qd!@LYBPZl^SR5yul/lCmHJnKXJI1q%GXhEGl:%#&/cuPem+/JiX1PCZ51nK#JZn?+@m<&wht1tyJ\
@nNNEC iI5@lRH^P5FcGMpbD?ecDnSj\?NZ\Zy^&dVEMGEZuaBmKC4Pb9$XBi==&QVNeEtu4^HyZ!kP<&Ia\>iI
L\V6p/ kNnuc>udw58+?9?E+E6W>HA^BdEXl&wmItu#ZK^=<+E%<1V$uhhaH5m9@4MSbkh:^YT9?*@>>>c:G4b8
4yd%+P MddpZ#5dAhdGkVN6weZBSS5+1hi#LlL:QSVT/RT&&Ch5iJR>ZEuIKdwcZLj#Se<Pb*PBeCu:HFD=KTd@
lMqW?W Ku^NK@?cDctt&1V6CiQK\N494>VNMtH^yHTG6<=/8ZE&\4?1jNdj\yBY$lGbDM>XdR\F6G+jG<K!HZ/b
C5d$$R 5%X#pGQhK?91>ppJ4C&ZXe9SVPhZMc<m+uDSTe5V&Ina^MTLm+8l$>l5JLR?ZY*&1tdyR9>aB<I:Z=+h
I=mY4\ D9LXqae=4ZKYJ<nZVHyHXN$8nW!E<@bCapXcL#b&h6kLmaG\u@ki%uT!EX<=^/tcW1u4FPNL5ZA4YiHC
1beyEK tSH6E?Te#8M4VWHyIuFEC+WChqGu5h%?^=PQdE+Z/1Z+W>:?K<Ll6LjJm@YNcBXq^tw#Y:/tA+qPX5u%
K4=<iW PbXnE^CYJnq8e8ckp6kSXc8hqVd4nhT1*pp@lR%A4D^5St!^c##>8XW\6nG^TZWR%@&tk5mu/YTA=VRH
ZTtc!w *Y$VC+l>4i!l4p5aYI9=HW=%hE?^/#uq&Wqc*l%\5h/lnD%dM<>BD>HX/Vb==iHI<11@e1Tm+l6<5wY9
JWGl>\ qdVj58H=X+84jdW/99LKQb?yCTWBwqcpbILF4P#Pbnm4!w6bQ!S&*W+L&5H1#wp4lP9L41uJiXjnZKic
e:j:$# /ym8dhukqt?X=\m8yn>CPXm@Yq#YEdE>5m6%B<TuR^%u#9/dY8*&6n?1u9P*u84maV1p^%8S=\eiM%<4
WPZk*\ #?X4N?&@<*w6DX>hnpQjMPH48tR!94!Tna8nI/eIbIMh/!wp>w=lDdcQ^SJj?jKDZ:91@qTXhc@mZF>w
4Dh?kQ QW8!1+WSd$8qc5A6m4e$hNWKI4>Z&c\NmW*wJBJQKw?h%FF^Lw\1&$VjDH9?Nb5LY?K$%FeX8JyeZJhk
bb!aD+ ZNQS@4ZHuk1/&X:H%*VI5<4R8IkuJXWPt:E^eRSl5#u%8?:I%+4E^J#ytK=?SuZR?6jBK@@%L?b+LpBZ
m@WGN= %5Ak=^w4FQ=%EFdm1<y#m1FVuTjdES:YE6cKP=X5/&qQV@CZDHj4d@IS6\1dNF>*Vq?6bFXcm^\qBFjn
KPM!TG aEQ=1&1/<hKejNGF\%=Dk+C/^nQG&lR4SZc95*KuEWAhFK8ZuD9ZwaGhDRj5wPhj/ZmPC^JX%46TPE\\
Qw&BGL N^Xm\Na#E+E1TdmPYLSF+9^&MGd!t^ThSkG:YG8LR>QJYS%NEF9J8/yXDWW%hLXD=BVaalCMYTX8EnuN
N+D6cj 6Ey$4L^tn%4ta94hKe<S?=lRV@ccpc<#!JLeYd>YR?Nh$=+l>5PtdFTtk@@Eqy=NS\\T>u!A5KiI5L>>
!@H%4+ iWwFVbc6yn#eXIe&PDd1jp<9kVXhMET>9LdEV@S^uah5*6TIm:ipQFE!yYIXE\hHHnpE:\uS%Tw*SYR=
lA5kYL uu>NS/TZ8NNQ?GwhdNkRW&Lq6m6!$c^p?Pwj6dD%FRuLNZtLIt\&HVmDnS4\XH#Nb9$8eRth+9H+wCZ5
FGEcb4 KbZy@GZKFQi*y1cei&WX:K1?8qmlN%a+uR^N4Dk::A^^$h5hFwBV&iX!\BR4\t:!q8jI\iRe\/1&S%La
n%WH5N XQKH/eJ<6e>>ScF1%APVHq@VWYa+y>QZMp>@Y4:!auF=9dC<D55D4!qp#VJ6:\#A%TtnYK4?1P^\\kFL
AcLZV5 ^:D8iQ&KGhilS#@=m/*6T&?EwT9ZE<>S!HR/tRtHeN@LX<<G?@4Ebd6\VLLaIw6Q&EP:wQ1H1X^&h\6h
TKjuc6 h\1djFVX$yG$LeKdaHYN6RWXZ+QI8q=qi<\kk$d\H$<G+mcZ%>B55hMT65yKFYiJE&4%<w=eNiYJZHCH
WdZ*Vc qj*95IFNDeP/M8Jj*PFeqSEN+9Ilw66c$>6d/J$juelp*LqXXmi\ShMZd6cH=TPqJ9#nkQK&GYB*Ku8L
IPW:+V b4@Dbw?XVNP:mNEG>@S$w$6j6DGM1ITH8@&nKlPbhMc9t!j=mZF<VWj*N/u$6T!#&utKt+T9CYMGcQa+
Mpbd:c a<WALLB4!lJ#>hnNGwXdaaKB5WjanK=4WWR<EShXkm61C88*L*8?XWTDVD%m/!!k&y5c9W<@TnaWEJ8l
*P6=cW d<NZm/4&4=EHP$#aY?dXWHTqamMEJFnt*EP\\bnm5Ipwi/L?p%H=1+&HZhmW1FkVLKNy<M\H@Y5&WQju
i#<E&6 a$G*#WXeCPW=^k:dEqBG%GP%QD>Lb8phC6dHY4=tHcm=dCCHD$4Vbi!AZVKyW=%B!>dj66wWS%JYa+Vy
yG>ue? eXM9$DX&Ny/pZk+jYMXZ^%cQ5D8k?mSkmp*5JIe:t/d\JBydbpaK!M1\L1y64%1j%m/Fnk1I@a+?jKG9
?4#jSu &SEtp?e+B=9%K$L1YDB94HCibt+N4p/T$G:FTc46C\8<\>ZEdGwqyLLDAd:tw9u1>hiIk^$ce69RnBGi
yEcac$ <nwp1uVI%Hw5luS>L=+WZNN?#+IyJPcXHe+HV88i/FaJH>t<c+t==SPYGT5nd%LcM1mmEddLtd?Q4%+S
bIuXTA MiQyw:9Sd<L%@%@@V%:@F%BLA\RWAAIACAAWXt$qD5+C?MIEAABtEkAAJRAAAGN5cYX8hHM9eGh\L*hy
y^Tlnt dnM!L%BHWG6qiZM9WtX#L$6qiT=ya&@6q#>IbEee^:?iG%^\ajWKK?H86Ipy\5FWpyA>LNIJ%=nYdpm%
16>\9+ yBBYHkEjCGc:C\TE/dbIn1RIBC6lm#^!eAh^mqVcSBA5DHJ\c:N9aeNN94?b6*>hX<WpqjQ<9Zt@Q#P@
AZ>G\> #=5b*<\CE<nl<iMbTQu4AjA=/=tbwH<+AZ\<Cj1>ml@#\Be=<Rj>!\?A>\ZG<XqCuqGpQ!u^A%^Sa9?H
il4nt> PA/XZH^IpwT%YJ#@k*Plpp6Me48&=K9X<FCWunBX1XTCwSV$4e4Yyn^MB#&N=iJDjd\?jaY@8Fub4KBQ
tHCwjb V=pR9ZkWM?1Pnt1wy#9?!8cAQ>Pul?L4Zh%uy@?Vc@V/kF/6X4j:hL44?$>:iq%KCEk4MayiD\F8TJh+
Tn54\t /4?&B@WZ@V4c>T4n$YpjPwk#*h?:5=q?lb5Zcha19T?hFQ<8JXM6T1MWV==pp9k/tSJJGHNTcyWcyecn
j^q^i< E$4C==mT>Eu<1FXC5jWbyqwFVH4=NBP^Fip4Tk^n6=\955=u54ZiYieJ@wh%LwPa@\XFYd#:4DjVwKjj
Nt48*@ iB&8+ZZ\@>Q4W/#XW%>Q:&@:&p<k/@cLhm!%1+c//Nwn^lq+e\b59?J:59qEXw9?bn5Vjl6iM@a*lQwX
ey+X\a >Zjdwi*k>!AjSmN*?*FK@p#R?Q$qe4pe<9p<CwWCbthuMVe*l@u=iT\5LGBycRq4c&6aZX*F!5wKqyiZ
l#Aw*6 EZ@6<Q!=\*e+lH64<j4\HR:Q#9D6V#@L\FA$^XB5WBX9mnbFt^KdC!Gch5$HVd8tZd9R#NB8cDhWDP*G
RXn%ci ?c=kcdi$Y>w6DXatqL1n:t^I=T>NMST^8bCiN$WGSRbFBpWGn$RGSRbFBpWGSRcQTRbFBpWGSRbFBw>P
B*t1Ki BpWGSRbFBpWG=Yknl!KHEk=Ppu<>V!KZwXmKC/>MF5*ptwp$P>Xp<eNAy?cDJw5tm^<Yetl!cHJwI#aZ
eTn@99 lwwetk!cDJwMMuTcHJwMtk#Y4*kdlyB=\tY#+XYi!CnSZSl1=nbpMp^1tMCR!VC*whP\E&PpL^it\?it
-A\8lR 0007a477e3b00110334 Page 217 of binaries2.zip
HJVaWA ujpN<^9tq!p!#G@EVkbDB8Peu:a\E>yuF#KbZp5G!*!YdJaeq9u<%AwH^<CT\\wHZ<^QN^6b5qm!YEJa
Eb#4TA J9SLkC!YDT&DLA&YLLI54LB\Vm^b4I!Hb=HXILNk@FJ!bHBpeGS\bHBp<M8JDJaMnk!PDJaMjwtS\bHB
%VS#Ya peGS\bGBZXNwJ+Mnk!PD5@K6aS@5#LGla=DYMpieS@pi?d+qS8MJj5D/?nypa>9b&eH8:m+PDk/\6:iH
9@K%y/ w/MnHB<j+@V$FPju=:m+8EC4%WKn:jB>4ja9:Pe*KA?qDFl1=h=#Gpy@^EiD@ta1$9NH@Z=^hCS#*<$j
uKhF+L *c/>PAR@VVHcn&d&llnb9\SI/ctZ@Bkc9p96Jj?a>wQ?cH#@$Rl@M*&LkjdS*j#SGH<=qMW4@FFYBkJ/
<:GC:D @mkcFTAD+CN1$emAb9Mcj/j@+K@X^94L8NL9QiZ!<BB$<@eSDK!kbt>%%dI!NMH+d<yN#*N@*Pp<q:9l
ASSC#H iT/eW==N*J>V:5<y>?iW?*QKde+y*T&\HIXQb4clS^*>aVQ6>+Ndiy<j*T$/$>E=LuV$:BP<8Lna4$jS
p$LWS8 S4aSyN*>cYP^1>imMuiVep?9qe8%cKQZZn:%$W&?$=h@D#/=^i@Bj\BRT\MEFAACAAkAFFb6JitGc#Hc
ltK$wi A\AANl+AAC+AAABndGqqduS#L*BueC>*cY+#Mm>RS%B4bZq#L%Jqe!>Wd&>5atF!MnSmcZR8at%\#bp:
YHMZHd p65\DIcbG&T:XCqeyh?bdZet5&%KZ$FZeLFNTq>BXXL:Cy1>Ae8$ul^FAjuLMAmCFCq:p&AkDW%SFItQ
!Z6Qaq AB@??8*y5+9!SNeZ8u:T>bG8D?+VHm#Qye^8485\?6W!6&6Li:1cdd=LmhQyhD\iD+jDj4>@iZqSXhHQ
8lT\d\ *Y=H?jTW!qDJ%bbW&8Pw?l$im&#?&h?L8/8jA%?/9^@RJpNFia9!G1ZLPPHq^!Gwe#qjJT%<WTeN@DD&
5hlmPt C!%bQ1kR8$9/N4m8Viy8T%kjl^EK$QqZ#E?dn1McS4XJLVXJp6*GF*DSC$1aBe:uM/F54BNNA6\/Z?wb
CG%!/h EQNdy>@#@5e9$$V6tEIYYTAcRRqM6BTwhkhAwa^ajYWaDJw1E!l#4DAPJ?mSmybJk%@hN4+MN*#Ck69L
n/1Z59 X=FF%$1F+eKZF@ipkG8QiTA#NS<Q6@FqBMkAatTtHCju4taStbQMSDlm5=lKBbTFCTLDbYY?Lald+JyB
hP1V8? yqIMRBq4/+9QAT+=L=RwT!?PFy4dEh@Sj:*kY@DjBZGWw+K4EE9J?hLMtQMFW*t9<H%+iKBM*EQPPM:i
AKCZmE 4<K6a*Khp4!:e\9e!FelXm:Rn4nC>!4=pEmdB:n\ap+d+@tKiFL84PN#4IG@ku#JX<bu/d^91bl<WT$6
d^RIJE mw=SKBGi?6Dk$y\4?%9um?cb\#Ijyed/?eKZtJw89Ql9M?KXM6b+kIhmlht%jp=n<tR8BnBCFGKim&Ne
1e:^lq $Abu=?Y\ZI@QMJH*jy1tBHE=#M4?%5P5K1>YluKJcG?S\QiCGJT@1>EF8HNmmqJ<YQjjhDAMbH<wNVJ&
p$A5l% +V18%9c@5i^We6+/akqZ9bL:d</ZEXNAyp1ILP=MtSCHS#p51:?1%/9q=WSeYYYF+wK9yK#uZ+p+^Y&9
jBnkdd u=&PdC\!Qkjn$$\Xqd1AWV4+yX><Z*ZijLuXmNk5#*!b:C^E<R$n:AKZESQjeS#6iNLV*&*&RYT8IIdc
y>Ge<Q @y9i:<I*LDLu/^DqdT?4?SY=YnbZ%C&I/*BJFFMT#yH?C&HEeGHVj:9/8<E?<tSD<&ZE#\ujiuC?C>?\
c#+=PA A+ySCPNVcYGj1:hC1+lL!!&V4!TLBPjMIuc^@$4E=MLtFN#d*\*&WTedC&/JPG4Z<c\^@@d\>ZQT%JcV
!NJBC* 45d#nh1Pw+Bae8T$+45<EuZ/8A!WmHQu*hDjDjaBWD:bWP=<+=qpK>>$@ed#T??=dtNt5eFLSD14uc<m
bn&bZd K?E8cc99:LtAY>9!>QT*6#!VXZ\*AFZyh4/+h@%><$=@G@ql>wP>lM+D5uLd9Da?+4n>:/yd!m9u*ec*
X*ldWI >N%6l!*@T88NpbN9li^@1E^Y8jNj%n>RT\MEFAACAAkAFFb6Jj!YQV8bAkAAhkWAAC$AAABndGqqduS#
S\QjX< L*BueC>*cY+#Mm>RS%B4bZq#L%Jqe!>Wd&>5atF!NGJyhC=mdZB>qLF8&#ARlttplRRISC^+/YLAWIh&
5Q&&nj CYBBBX4A/NK>:?J/CL%JTRb^Mh^H/CMa<BJAk@MI4DyW!:&DN\j\\Q^Hm1+VBD%dP8q$@Qn4!NP*:>h9
8c$KHh ldN4HB>^@MI^^DERd@!D@4uw+<QVZiZ?w11<+^<8Hl+i+Dqm*X>a/^*@PIRV5ZZ$\w#\b^u8=XJZSEJ4
P4k1y= F*d^ThJ5Gpt9&R5iK?S^$dL1I+MliIk/HpX#uNyMNGL#jJCjmFdF%^WSLk*CtF=nLPNW+JqS#yn?VmnH
Z$m/+q 8=&IyYT^dubV\KpL^?6$kRC!a$t^mLY1=^X\m^N9<Hu<n&jW*F%pJ5Y$=1KA!ZNiX#h*t8JWty5lJbGC
V#RRD< aWTu5t!yybj*\^jS<iJa?14@GY&*$8!bN*&8:*mH:J9lIMW<G+VXjE:ha4F\QCH?19GJF*aA/yPu5=p$
4lXX4B P!@R<RS+KPG1Z1F?ebwPeW+1GdP?i1EW<%DN/DiDyPNF\4<A%uj$d48ht1MZcI4Ce@Y$Z%>#A*pw$4&I
8R<I:a /:&kP99k*9hT<W+l=Dpi9Idl55*#&Tjw&#t>Zq<lp?bPGM>LtYiYTSYZ8IA?<Cy#PCki#ZuCiI<>#R5<
6$KCVN TuQW:\nda>!WbX@IT*5@T!KiPW/^HF+ky>e15^c<5uR<q=jIp/eJ=jpwHWQjd4e=+/*99&l?I/^HHAVC
iHw>!/ hWyb4Y%q:PG\bF/jF*!d!jeRPEd>@Q+LQN*MttbDad?k<BDIQK5j:Zy9Tq5/Zy<ZjH6:qWEk4=N4\SQ9
XlwmHL &Qk&/je#A%qkb:X>6HyFpV&kQBV!kt<#!mbu*ib=&AR&>KD9N:e!t=@wGY9ZF66IqKX4=n+9?BaNelY?
4/\JcT FtTM=$YT^C8jCG:+dk%=96G>kn+9?K9&^PPaPj5i$K8j1&/6/V>&ln8*J%BLA\RWAAIACAAWXt$qhQB5
Ti*a!t tb$AAABGARAAKkAAAGN5cYX8hHM9eGh\L*hydnM!L%BHWG6qiZM9WtX#L&F!et>*a&>\LtN%et*P5R4C
GVRYl: MBRF$B8#mhBJedQk+6lJHKVyb:pbehDN%e%?mIPj$4qLF$WH=Zw^pSd^\Wui8+H\kB+M$lR/DVIDnADM
JnN/du SBEKlQ^V<jw6p8&RQKJXMBm*@ji6Y=jA?MB1uMyeeuF/e<yhuJi!pC#8%>tB4P^jhYq=K!\d>je1*m?!
t/B6/$ !eu4pK#:=NPSb#t8!d%+jieVtal!H:PNdGWuB#p^%B6RT\MEFAACAAkAFFb6JYlJbqqVCkAARA<AAC5A
4Fc4WM AABndGqqduS#L*BueC>*cY+#Mm>RS%B4bZq#L%Jqe!>4b*hyinFmcZR8at%\nXh@XFQZHd<9Q!CJXWJP
aJPkBM 4B^Zc$kVV$C6#tN48/+%$GCVWDhIA/mI+p:h\XaHy^*kpiy:yhAVcFhDln*WdehwaR6SC?%S+amaVN*S
A\FiE! 5i/WYkJWGyN8*TptSNkKBHt<*N*:*k8J?&9Qe\@*+@h::@j*>*8V8%&jB6n9BdS$cB%Gc\w6A9&Lj+wq
9WNQb$ *Iy@EEL\j*#/@<Fi@F<1wJj#N^eAIMpWGESuDAKD$hIMKCC+Qb^>\6*?$V14w<FJqRPSXnNp6b:+8QCX
u<WCwe wy%qKn&R:nVqt$\H%4?8%d/meFcBFVD^#d5A&J1E+V<wpA^nL8>DGQ46BP!HbADT<H+$$BMayIVVtaSB
qQRA%y IXQuT9>iXHQ<nqM+V%q&huT:Q@uG:T?JV88F*@/19V:4JZm9l/Vy$qB*/9j\4>tSW=A8ItEJQRFT\@C&
c^5CWR YaCWKINM4P?BX+nwu?=Gw5Nd/dPSpDj%J9\5=VRT@TGMpcZjDTL?G/*=CNMpQR5Z1NRw:Q#^K\n@B<:i
\dwc>d @@yiWHkh*t=MR*mGbQw>e*yEd>lXkuWu/iL\<FV1hSm!h<F:pCEl+=<G\mmEwiQRmVG5Y\Cy@+V\\Xc+
*d8wjT F<=:IB^B<1<nZjdCLyd?+F6=/mT/ct@5FLwQ\tmM\9#\FN\AGYSDbF\qHEHaA*@P8w8i%*Q$GAuuED<>
F!>W*1 5^Hb#>MSl6Na*uEamHWl/?bIik:#Z$jTQuy&P+^BJ8SF>@$JB1A/6+q<5JY?X+DPj\\u+a&F*=HIwup5
Lb*E^9 @!c/aRcYpk>IPqTi?lY/>k8$99Mp=Hi^@pJ48k4=E<IuYQ>AGJ+ARp\@m%aa$\eyjD/Yk%XD=@@GiLG?
$MBq#l MTQCHbk?bej?YGlG?$Q+jInC>$*dn<QacaV#l=#CH!Ce/p!DD*cVTKtRZ9k9kc%S<ctu@b$Q6=>jMhk6
&+LKuQ uFNJ=WAqML6%uWZpICBkX%@6au:b9eSD?id$AnIbk<GH<uWB=Z<1?n5=E&X\ZKbApC8V%j&yS@XJ>dS!
p<8up: <6&\F@Bqm4+Xh^wD!cZ&XP%:%eEp9NX@QFCPN#5+@GSjYnX:@kKHu/e@tGVy*S^iZ=L9b<>ZeQk==ukN
d6T*p! !!@l:#9:\ZtY>VGiu<!HLC:u?X?:8a6XdbDDG\JjSFq/L!?9?nij5KTG8D$9Mm!@uLj*#5$iF>+<\?Gj
\M&>Ve VF+@XJYp#?4?q&KniDQB&%>>5&PP:!@+i##R+YFbuS^iXj%>lPZQ+HDc=La^Xl<4V!@dB>@Ct!4?@8n*
iSHQGa h<cV:F%?NKjuC6:e+8<j?iE?K@wK#<@5<=@DG^YHq@uCI<u*4jL5awaB*%1^@Bwab8pcDm?NnHqCTj=K
mu$hVR P%9:?l/<GiW^/a>NA:+>a^!mb?:m#j8<9EBQ=YY<wVk5:K5P>TVqT?4>ABqJ8p@ah<qZl#jVHCcmS#$n
SI>nPS iLPS^:G^I@%++?IVmPtbbPp&Hkemq&Ja%t+iH@FWZ5R+uuSdb5b11WR<\hdKa@/piILHL@6/MQ$Gn%hF
IGNNhG Qj%WCkZ5QF=!Q%JHLR*G@RYY$Z$n?nRuGAh^k&d:9e>XkZW<Fw#%$Q4cm5X=I+R%d8@X8WX>mE6h<M<#
pk+1nw L6AY^<!C?&$+Cqy=uBHyk>@Y>Md4CS#iP?N#MlQA!LPQH?5m!@&>ed^5iA6>MpkjBA5eL48/jpN6ENW9
FDFihk q&>EuZ5%R^dE#9H%6G\ajlAitGLt\B^Zu4V9%FXQL@$JiJXq>+^+>l^m1ta9+*tInL6aX8&um!btb4q<
JN=FND ZXwb9V5dkD8:44D^IFdMu/@%ZL#IMAjB==mh!aj?R:YXyYE8858&\EN%kd9?cPA\wJBDMy=p^wdDjdXq
P>aAD< NW/\A#t>/8lbV?^1JEL:y%I&!\WZ=EY\dt^?#F@TF=S$6+5ck8VF!d4KRCqVdSTMt+qN%EH+:=m9b4a4
Nq!#89 MCTY&AWG19aLd>RVCe#*8CT@Z!+#iet4wK!/>NJIXCW66\l?T:*RC<nAZcb@4%qSwH9pb!A6CDbW%*bX
a&%IBd lnVc*n#yW>hwXNCB!JHRXb6EbE$uK&PwkPnTpeDMym#=Z<S9uphPYFJCHn*!VaP5X:=pAMh$KZM:QHK=
IkX4FF RqQS5iWF:PQWae?y9j6q$wNN^>mTEVL$pjqSm<!:>w$V8AeJT&5Cke>chcwXA%w8\RM#F+j!FBtVl\jb
S5MF\6 HPp@=Kqe/^IQZZpula%bNF\hC$yqXY>1h4A%>Jcu$my#b>kGt4S5VY?+:?9NqI69YXQ$:QuXSdFk<Z:b
RS>cY1 V?Y&:Y#MCNLuFVWyXMZ%LjEHEul&p&lKJe*temB6DkkcGk>94#j\PdwGbGhq6BiKY9te*?M%t+lBR^+u
ipB<$q D\mmZ4tqiaiDG8Zw+4K16X1SLm6F!QYANHyea=R?a6c:Pj=XJd8%=t8WJXjN%i###LR8ZiT%6Xk=it*J
-AV#Je 000e4c8e64000110334 Page 218 of binaries2.zip
1R1XD* H5Zuy6G%c^^eDS?LZhctY*:6K6h\@Eh>5>yNb#cicVS^Qa<l>$n!SD1y#5:%!Kl9bw*DddMW4iF!uDpY
w>ct9= pBlN*%l#hF\N$d/?qb&PaM9=jE:i4GeYtDZ&dR4=!!!8DP?Suba?w&99+P!ln<%KbWMGe:6:E@j+>E$R
$MD5C8 qlb:ke*A#aS1#$HB8>q#5mhcZ8Zw1IFZ%I?@eT/d$&@%YLhRh8/ewWun=pbAZ#t\6PkL5\>p5#kqTkGD
TDcdFB yq^VKPD<LWTqi6LSJt9i>RjP*/k%bY1Xt^$Y=?Ka%B1tyB1DDIl+uL:<qtDA$WyJ?da1e^tXT6M?wPDd
md=S/K 9FL>q5nq&AcW@BYmAcjI<Wed>TqQJ^RdCa*SRwn+<!LVuMDTw1VeQL@A<S&++Zn%dR*QD%wLM6QXVaTJ
Gy$KPG W=uIWdTy#D=LDl>T&ebPq:hXw1&*euR=bZubqt=yB!c8LZX$N\Dh$>aVVk8L^e%kJdlGmQZA^4yeZ6Cc
9%5\Zp 8WPb*ju$cT:F%Ch?wdlkFbpM%AHMV&S4H@qq6/S#bj4GSmW&Z6%iKKuaL*IP=Fn\LBX%Y6#:JdcVb1Xh
h@6jhJ l?%b1XA&ND?YJZh$11<l@eRFR?%649I#Sbw#=piSje1<>C^%$&BY/<B!BXbj6VQQ$KV8Ni^L%*ZtPAGl
<IBt*D 4<>iZt^6GGnWH5n>EXcu?bbXZmlZh4=e*?dWw%<ilaw9>=8j!XFp/4ch^ZT*TcAw4DnbQqB5R^qAEKJY
5E8ah4 RYjKlN#tKHm&ELtT$BTAn*h+m>b1<*KLeZVZW+ST:ZVaB^^YP^/$!Gi=VSu1QLtt^RCAqEA&8m>am/$Y
^TYCqm 6\Qyh\d4LCP1RKQFcKWAIeEtKq/VQLw=:\qCBWRYh9w&*bJe5:WiKRB6dEVFqm6Tyh6S4\ibdAApDTwm
qEVN@a V>Kcybh!ASGe4BLyP6R*kIIL4#n#MQGXyYkqbiS:kENDmETGA8Dk<&ZNIDm\:t5qES>n^qEk?%LkFMVH
PHX#:% 1EMH4Cq8jZ#Mk@Xw@4eb1eSDn\Jm>Z5JmHP@yTDyIakt^Hy=Ey=P9FqAjQ=4p#CPuD*ybaq/l*lNpn\$
WIi?iL @<Wci\KniT5yT4wR!hy9NC=CA5%@tTKJH<%@6<YX\Ilpe$kT@Gn?j?bPi5tm?Y>ABdyIZ\iIJy94wh?d
M5w+W< &Y6%m%AaBET8:WcCn8d@=5KMBEc>1!M9wT?B=4@Pt6AZ#@5ZyjcH5NKmi8ku:Z<BWE5DBBRAAkAIABXY
JelVuP dTWd18FXyl<AALa+AAA4AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRc&X=e!>TbZM9c&h*cZw$atq$LtJ6
JSF%>e eJ%:#+<nS=aibdG:jPmDNKX6H#\HDcD&?1CDG6JkQVhKTnL/pB+$bG+TBlJCN/c!k\hm6<dK#MlDIFi&
NXBAG< i=p<JFLHPe^jae^BYQnT<DIbiTD!V#DYkHwmD^#DJ?@e^6@*pqZh6i9LVBbb4GI^<5Z:>d*9SWS><i@@
8LSh+F :@XE4l#Qj+6ukij@\jPh!XViu@&:!i*%*9p=Z6@Ka@L66?ML9@kY94%/>R49@EEip#@<aZ#lF>@CN>Qb
K#BF\W mk@VGYj+/A\9d*!JS?F>W=/@t1a5m@X/4ZPn<$!uJ8uYHS/&e5aX#lYh1?6V/W=%Zj@Pt/F#Bn<YduBq
*bI?SZ QiDG@qV:#quV=m8XRk+Gh>$GH:cXeZbdt54WqjhF%@X&\P5\uB1Db>u$Fu@kJ^#pY1Mkb+59VFedc@GV
E5@mL= ^ji%\$DM5QP<kaZMHuM+XIM?YcPh$%w=bR$?ZY@665/N+*8+A::dM4j+9e@6%88?6KZh&6!9D^c1d9I<
\9jQyY myb=qB1FGd8/e4mQTuTTcHZI4Z&SY9$m#*Pdc*eaZ@ZB95CdpaJMZQMEu:XdVNnlX6E!VhRmYpS1wbMZ
T^CLF< WbyeZcZ/Ku?Sy^9>Rm>iRJLGH/?Y\jY#b%>>?cXTpcEbdbyi##@//PH>/ALD%Z!lF8w1n=I46blj+Ri<
+jJce4 mchcQFTL=d>=iQ?Dl>QQy9i$k8t/6Z5&8SM8d%@9@H@i8@hw?6p%jGVk&<pjjX$@9#>NKjj/n^<:ijye
NnK\86 KW\+@^PGV6/hjSWluypC&b?4S$pCJV::/cM@9*n$QMF9@M:H<@Hd:bW<?uA!8Z<^VX&NnJ8c:::d@j:*
M?!@ba 8#6Z\WhSXRYC>H\=SJDN6N6B!+<iZym8t$\8m4iGFAXV!StLKd&=*HF#eJ5aASAGX/wTlbEep+udIcZ!
?8WYhD !FcRkwEXBP%epX@QJnPFILWILKM?V+JI1VCN$mmA9C>uchGuAIy1S9$XltKT5D\EX/>Gw\RdDDa8qX<Y
?@a#Z$ edIIF96W#!dVS<>4k*i:T9:!wKJkW%R:W*VQdm\/*SkKqy>@4BiylX^%DWNH!HdKqd<wKN9XP+bLpd=^
J1DwLJ ^\Wpt&!W8:RL6=k:BdtjQi44@*I4>&Qa1hw%NiS8*@cqe6d?J@uy!q/qEWIeeu@!Bj#:?m&=R+EyF*XV
1SwPSQ 9Hy::DT@$SjJ+/D#qaMX=$uu4>@wT*jTTXX%N+kk&I^#n9aySD9%!iVhL^+CNY:6jLG4K5!+45#L8&Pu
VquJ=L >9^P=HKA^GG=8b=MQ$mG<8Xp8l:qdHdWF%@XVZb<iB:4JHAup!R=SBC>YM$tF@ej&94q4d+Z>c:41HE*
ytGJiR G+ia*Vlpw5<J5+mYG/WY5cde6Cqy=*><M:*R:M/*ttlV:MabQMm#N=>IDkw?iun@+t&=+^XY%cneQX8u
qG\Je1 cl^:ah>&tn4\:i8wcjLJ>M:a/e?Lecd**:^>*@*u6#?l+KQ4#=PV!N*hRcN1HK8M8Z*LyG>@InDR>:Pp
DSS&:n GQ!6j&?EhPNa\NEdJ>$J6Q8M!a<i?8+jJyP@8S5Lb!F1N:1hH:+4h>J>PQuS$/S5@ld?@ei:aZTi<>6!
cA5KZe #h%QQJ%M:$i%@?Gj/u5:64mh/QTjSN1Vb=NHn^+%#Vi\<!n*!VpWHy^jVHG4wQ*t@Iu4G:pQy=G*d<ZX
AXK:cd :9jn/<8#n\wEcEFA1I9^4hTMu@!Z#&Budadj*5cX&w%#D/w#aBS%>hIcW^D+^wk@9/4*J5?@mId8j<HP
cGqyEC 8#6nL<+&84A:M\QphADAWi=Kn&M%=D=K86QLY**Xd9#E^#itY?S$Vdl&69:tLHj$%bPu!KPwKiDj<>ly
<*dD+N Mk=b:Y=!eH1&e4Ei:#y>iI+A!Q%K8bP=qZ6#/b9Wi?Qi?1=@>hQJb^@qVZG+qZ6#\d^*^%=$h@$:LYnu
:9*+M9 6P6@Pbu?>b*a8HC:*h&!1p#>Z?>?+8up\%Rd<<@pZ1A1*SGDJC@89BFB*?WnQjTI1:?=M>amI8+I61c1
hdFC4D *</n1ZGwC+9I@nP=T54lY^yjkISXd<9X!jwy<qC9>T<SX:>@K#eNS?/?i=NDNiDi91Z9^e1lD6+D9&KX
Wb9n<F iyPD>%jFYLb^neuLPqHZd?SiKBSWiC#ZG<*ZKc5?L\D$YMGl<ZjjwR!4A1\Q=h@5dw8@Bi>EhKX+#aFd
*IAhEK b^*H85@/LRY++Phh%aEZY6JL8R=<=Bmm6Wh=yEqu6%e\DcajjSkE\bT@BJQbhHyj@u^@<t!K*&/tuwP\
E%/#Zk GtZ?FI/Wh+NJ\KH@BG=&+eCMndKytj*Sa+%@QZlRcH^hn>j#b%>>#5j%X%>?<hYMZ>jC^4:E4&?8/GFW
S*uI8? qAbEHlZhenn$%m9$HnpiK=*q1/5+=Bhwe+l49nj5V#Sm!Y6j>4dy?mdNI=t&m4L5^R4nRKtVNF<q/TdG
WQ#9A? %>JqcSm%:VEWlqd#A4&yl4/yB4NCdeW#yX!KnDJ<V*T$*P<yX?pAL^8%l<jbMiG1B+:$9w^5ltquHI/<
XGH&e6 IF9Eh\%?EeR&VA@6aSY1@d:h:+<Rc>Ad%ZYJ4>4nF1uS/JJeanP$JyV4Xwtl+kEGHPNayWGI8>nacLSM
yDaWuS /*Y*>uXVN$$>hB+hEwd1qe=#nFC+Bi?pw>YXC?%<j&n%@MEtlALPFwi/hPnMllQtnSc95TcCIM#e4hk8
L/$TI+ /Z#Fi&EKRd#H!Ncq+d\>HGQ4%5/9%/Wy9G*Ry$H#DkRYDbYDn$CPXbJccSN^q?t?hi%l*?4q^&EMqhF=
XTutaG mbpHN?DBQ1&BpFYctVSDa+W=bLR:DAA%Lh\c^=65Q#@ASZG$4hGIqpZjRG+JM\?hT1GwV8kp?MiCSKet
/E8Bpj $?naAwl%5LC?k1e+dZS&IPy>DXN=W=ctdI#LaGVn^NaGnq$bJZ#=H5NJ6j55CBAnt#kG8@ZTDy8llFD9
c&=HWE 8\S^=SARt6cGt/KWHB&@dSaRjN#Eil+k\PI\4Ih%=$1$n$NjeYnbMQ1ky1c%$TNCwqt=DCGPeIK?+Tc:
^NWSkc ClAbdu<\F9!&G^lWHiRm!NB%MJL\aFlJK\:6ac%k94eWtMh#Bpee&:Je>+kyDKiQ$NNdR!E\F*\V<S+T
wa*#$S K=nN%cJqSIjbb5EJdMJT=HK?cK66a>CNm^B^:C4JNAHWMdQ!=a>DbyKN5lpN*l+6&@>l<Jm%y>#Cn$I+
4K<>yl Ze5pk1hWu6HmX$HMJA^NPKZtNpRDD#Y:D9LkICS\l:!%VGE</X#aGXEJ\?hQ\\%MFedRuBGG8HLD8peW
m&TYXD F@AW+6pkMmGY:5S$X?JjS>lZTZc%dQh6m#E&5B61@ATBnN!npSlWy:1G!IV86e\i^JR#Kp9y/^Tl8IH5
iJ?dN/ NF$G8IeLN\bGlnAMl5tcalnTMccRPH^FcBJA?E+A6<yeteCdVhlC$bJbm@pCN41?/:Xl/lP9/CREJNSG
Ik4wWY Ipi4:PMaBk4SICC8/N/\4BGNHD@5ILh1KpEuQtA!VIG\6*KeelweAFS^8LKe<^/l^eWXIFbVu?Cq44e%
Pe!B$/ a+4P\dBMpBc6Z\aLSGqA8b9a/V%hbiMamIH$GX!=k*?GwS9wH<ana^HYJ5mtPZDELPeALA^YLqm&AIFD
il:CWT T#5lk^9Vh#B+*ZT\KmA8Z^pt@nt!E$5@B<^iILQbl*S%HCKLaGVP88LKWF$^BTQ&+WklJWmbeFqI/jcK
H<&q?8 KSCG1YpV*AJwT:uAD8QNcRj9NudWF>w!1CT!<+kPZ1XBBLt\F:\FQ!QELPJmwN!!PBuct=>uWAK#pAA4
q94=+R VypX\t%TYBeykPEB:Z!IdXiL\8b*J<KP4bAtY1pMH$bymRnPMDVelcuek=c\6A&Z>\=:REn+NSjATqwJ
C1QLA# !I:lA#SFWDlGFTSDJmI:l+9l*#uDGaG%D\k=<*%H?<BTTCdtW&hb!VA!pqDW1bTplCC6F5E?bHEI=\FB
icq%&R @6ACNB1^NAAcmyhF^kl$k4FMJwERyCCtQ%$T+8CtR&Bni8tJH=HtSt:QCWh!A<a%\kpTM#k/Z<$Cq1MY
6u^Z^P w==CZh#mTQhAKtKVe/<4#JLDLWqL\wlGP5NcCJZbHJ/JN?$IY*DVc8mSS!eEbNqa?6elbWT\E=lN^mLI
T&Ry>G 8yJPCc+M!*VS<n1YP/+*$5^%Cen4EBI=1%ti!VyQLkqJ%1HV/Z#SdtIwjKT/eFnVt\+&1p@AT\kHT8kM
:jL+=E R%c6FE?y*A\$I8%5Gwd6Ql=4tmXA:&Cp99a:SnbAM$W5I*uH8k5ApJDGaEd+dBqVuw*6B4X+j\SiIA?/
#n/XVP GnA4K=PGSRlT/FJGNMilwPFZA+YbBXSc>N*:HebkQIkPbt+<IkEJuByDpSmMejA%^5NtRjCAckLkSh?+
FEYlWD SMWi8E=dX/kS6q+J8ZKYjEjlNp/ID+VDhJ?@C1ntCFh\q>5BKZ6M8&\aHZR8*MK5XRKY?F$4$hnqcjkB
@8lF4u %N\#m&ViQi6a^iZh8wKbP$a>B=@Zlb*WCYnM8yS<QPcDlJW::D9jmL=eZIPb9ScHA1<IiB^D\wVkAwaA
BBLQci w=<8>tQ?Ciw</SEZ%Li5jYj1Pl8LknI5cApyVmySaw\?tP9nqAB\AMdV&1mjk$MP:/B4$WNjEbIRuGE1
=MYJ:n FuD\M?m@wh\jHm\Zw8>i^45V=S/QaXN&jYF4mII9e=ppkbdIR^/MjmT9#eW4VDYtq=n?ahN$Lt@ul&Nh
-AX*$M 000cd02e7d800110334 Page 219 of binaries2.zip
:hCYNa %jA9RVEmWGK&m5+B@6BS5FYu:ZW:w:+*e48lca+Ybe1eK6AQtJZ$VEITkAW:SaIG/DH#84\Pk:pd\=tW
+8SG=B ChH5QkANCetljZYtCawJBKwTad:mY?eK6BQ%w%jIl\NmtXEhN$*%dSn9D$hRyLwGZuGTGA*@kMMV4A^9
?iaM?> b6D@&GI>e%QpaT9Weu?Ai/cLjSk9pjyDB:!mn#JCBpBA+A4%W?i8Y>9C?c6\FyN=:/WYN<&*\V&<HyFE
Y>KSYF h69q*DBR+mLlhYV8jDHck9Sc<&D=RKwkFdd8qEy/JI=yXEuBSkqBRGhMB?c@E9cQP$P9+BB5JQ%bXe4h
VbVA!> D<5yDLh*Zje:%H%YZ9kE!R5MmImXGdW%*1$^!Kd^$*ceMB:I?Q&M9^%L/GPInEauiF&N6IPwCT5:TMYk
6?6#&C Jk*b4qlT!>D?9NuPuuICMV4m4tNQa%hnYiD*mC\Aem5h66VRJ\6WqTN=Yw4keBM\Nd9eD?6V=epmXT=S
:GZ?9M 4BtRl1pLK^?QLp\\WSP!&dGmLwN!MkH!w6<lhKCMwaT8!Ee#wcICPmb%wA^HJF:@emqWPKc6\\cNQt/W
a6H:Sl 6y%H?eWALhuPpwdyTn4qS@STedl5N/1:R8QkyCDm$jubqL\$FLpw&/9DYI5!kk*V!dcIujRAFTH/beC&
bmVJyM AbRBc5M%5\jp\>aB4>cyyC*qC4?m+mt>5JiTn!#+IRkqD?Z=<&amQD^e5X?+>W8mM#Ih%CHSnP$Nt<k\
+Q11kY pRyKppS:t<qi!nq^$p5jSalepRLD^NFSGkXchpEt?!1RellV4ty@iCCRG>aI8%4JaI\Sm4S/jw?Bt?L9
9ywm%j 5NTS=D6GEA1VbqTH%!DVyDAihKMa/^BbB6uX<<5j+ib5\!l+Lnw9Yj4QcNjP1EaaG64=JNSCYq=E!Z>+
H$\e8P @/it*d?*Wc%A?1IFnh&@E46S*dqn5<NpSqCXZaE/#T+:E=l?>%P6\5ijjABYk+pFAS4BPb$D8cTWtE:K
<kWjK5 V8paXtAN6dPwSP\EHdLyF=hbq8+9@?PQq@nAjnpFp=$j^Vp!$#lP?a*/&KI:=dXmApLyKIyYu@>FnlwW
Z!eAqQ j@p4hFQL+IGhaJLJRVB!dGmbEmVp48P?ydPybRyEZPc=@H+XLhZ?<b>h:k@Bn+MEPBhD4tD#YQ*yL4^l
+6&?QH QbD\bJYVYyApcAa9$6^i:<QL@iN&F6!9WnXq&E9:9Th*kA**a&k/6IVPP/XcaEdM%a6@ne=*?YC?@@9L
&I?wkd &i^na@$DiITMWk1DND\HwaqHY#989cbTATE*TZ=^CdJ%NRuh?^<5XaHi+NW?&EnD\dy9S\LPH$wLPw5W
8pq5Jl nqMI#BKw?@iZQ#MA9qiV^=ijcX1!@*ai!MJM&w/5XI!h6keAE4K6hBmqVIKb1$<?@R9!@?#^P#>hchC@
FumPYn 6jEBp#eY4AwX\\JIemSakcF=%>pW5?d#q*@&*#/J5y?<<<+:EI>A/%A^4%5WFGqHE<ilGLmbH@kZFI&9
=K8j=e Lj\LY$ZS=a<?8d^Wq?>?<9luVA468bL^R^CMid5bF=Y5?A8BZHc@$!iwDKF=hQui+$<99*q+?Zjj@I1>
VdweS/ yidCnZiwC1Pb+9PVq$WSBLGDtTDZtjunu&Dw4*@>K+AtCDCt#GaVDjL@IGi@GYkbJnbWQeICSZ^NjcQq
P&@tMB y?<<@8bj@jyZGR6*SEw:/t9/q@PA\RC@nuDB:EJ:a<6&PFuGqiPEj@b*S81>%DFu8I^R?Ky:MJ<LI=TR
S!E:K\ *p6Mw\B!!1a9&!V==L**9@@bd&!&aW1lqGJwu*PN4P!dL%:B#PqBEQdRM1TjPP:@&&GD8II@H@@t$9\q
DlqP6w CG*CJR=&PbDdwjM#hjM!ZAwqJB\RSQb8W^MiP:CSV4*:#8Q9L:>QIBT=BH/n^pt9^^Y!dZ\XCq:Fkn?6
LL*m@@ E:@nC\!<j9#?=ciZ*!@laR#GN/+cA8<:#baVQR%KbpDMAQhZ%FmjcuNCX\bDu>:@!Y<8@#9RhdRcIATF
1@XQE* uM6eFG9<$L&i8%a\h?<It#B9ThqAb?$++d@MpL%EATGYcAM\:T$M#bW8i#m/I*FZpGh66/W48%QbiRDA
SD1T\G L\AYZDh4E^+6RHYRhcX<!#W!#LwcjG#d+*HMaiWyF%JdbQ=9/=XdKaWHbn^*dM:I^VF:9@/4$lkQ=yy#
yYM\VJ hSGnn*9F6eHP\XniDbm=laW6YqESt4ClbheQNquZj?6QpH61hl6b/**9k85EewKD%/uPXR!*Ml?kdm^4
Y+cyK\ Ha4\\@#6pWqw@j\JLGM!tc+S+<ndHEq!A9Qj?q:ptmltC8hSJK$*q&%h%%j%$Djw4*iR6^65&KPj1:hp
TWtC5l @Al%em<XWhqNCyTqp<m5Wuc!WLd9LQC@H9+*JuE/p9aZ5FZ>&ujIEpBTd!*5l*K9Yp\:Gu6?$B\EHtwP
6EEF/K G4kG*S>/9&TP<Dn&SX?>1JH:6ipdEEm%TyL5C9ujPyWIwW^A4>ccS%QR+QjR$R<@HIYi6Z:waTb#<u*l
GF\$wa V<lC&yqYnmBa1FIpbkaBSl9W:$+:*=kHe$umEPFp!^=S%S*S1CnFT5TaekSL$ppC4q:4pp6P%Rp<*?@H
ejp?>n pkd1M1CeeM*dN1X6HLq<!@*pqYyyLKCXacQC8IJBC5VDMAF#biue#Q*A>P*4Eu+R^^BqM*iI<YNP14YB
J@M:^6 tjNTFqEw6*k%ETdAyjMPhwIh%8mSkJC5SPCW<BI4BLp\$leBWDMGnK^*@eP@IMZb5B!=RZ9?ARn6*Taj
a=ee&R W^hk^dkED=dqEcQLaw&+KyDG>dMyC!jlPZ!CdkQBadm&iqyS4n4MN*aWLNVRMy#SQ?GB9tCaBMha%qmR
kd>cpV \+&&@A9SR&?A5T88iT5SDE8lkX@yV1@bcdK:H@^5cej!aPQFeCk=4tR*8tIp1pME9dQD$uLFVI=48H^d
QydGbm $$6%W\&#kA^F+Qqa?Scy\ESe8%CKGe5bkBIqk5\FLH/L=QheytacBXNlKA\6^*LQyiRVc48S8SI%HBN+
+\*w>W \/=jilh$V=Sd?YKR+uCWq5N%9:YEb<D*CXXGyNJPhBjLJ%B&W!GXIHeAeA^>AN+V#\H9Nq+QJ@l9QMPF
p\4Ltl jtFyq^\9$KHt51AMP@66Zj9BADmGIb&meCP1MP8?LQ\BTAuShd=MtD/a5bAHSyYXRtl6a:n/&nF!>+E:
ABAmG! KtGtB4X#!=X#PnAmNKj&nP%LK/9a%LhE5T4L@>pMR@jD>S\EV<w*X?!R\haj<C$S4mG=5?F8C:6J:pJ5
LyJMP\ :SahpGWBGIdn:Dm&G$?+P>AhTHJ$%\t/6n!YEYh!uw9:j#\*^wWEQ*Aq+>T+X<5D!/@4YTyT:#D4*9+&
5cV<pS p59J^Kt9LJA!J9PtNBSK8j=+JTV$!eCXlk/%<DYMVW!GZE5nR*aWw^A1NLX4#bB88I:Cqc4Z?\<&48Zt
=d#uW? AQJ?c@&GV1+Bn@ME:S\KKNqEKk5pPRb!QSGAXZFq5CunNyn?%Y=wTwb+:lmWABhSGJGXRmwluu$:a/RA
RnAm\5 p<h5kiI%NG/c9NpB$p*DVT9Am8hTu?SBK51TCZQhd5YVkHcWC<!ShVdbJl51YcdQAa/M!!khA#KXdElV
LbV%IT FeG*FM#q4dIBPnXq\X&Fp89GR>id\aF44AHDD1AnI<hh%ymG#9TeQ/@ZKHwDTyLuLka14t!qXD*e=9VB
5au8WD kmkqGYt*e!IWBhG6RHRP8IYYNdIcym*LSyc5ESYR8?6elVLtMYtiDwVwYNIwk/8ApuPdp?b/#=&MltYa
GTe9?$ K<DeBWFE>4B%q=AFw*JH:hYb!pwlbX5uY<Y?Kn4Ekni!:M!F\SMAG+$9a88\%i:EhWFiG#5c#Gd+@RwI
h*&S8a B5EuMYw=:paY%Bi8q5ZeVl>J*k\46=Xl!CJY\mmNYKQ5WBkt@$lLPcwYcPZqQXe@bAWwY1I5MI<+c<PW
MI&nWj 5Ht=emh8t@T!&A*y*Bd\uwhGG+m$4#iq!<Eb*Ikb:int@B\w:J=R#Ad81=$KewecVTAcd8:wcILyuK!I
8BAQ95 k%9JbMiqdL=AZ!=@Al&+c>S\K^J8<p*=Ni:c8hhnQGDRmJIHc^Eu1A6Zqq8XHhiwB5b?&WDkmRhXYWwA
uS?<:E 5khWb$AiuZJ&WRduAnNI<wml9te<IDa<Kq4lKSp$kuFew\:!^CqCR1LDn4M?IJ*!4>TBZEA+wYM<:WR1
t64*?b :HY!SHd<hR88bCp1VSQTPZwK>5/TS$lwV:wytPP>HYnj^9AR4EZt+\a>?$tKplIwykc6SEWTCQQedIXh
q1whqP G?+cqdW9ZNuL^w?ZSMGM8eyG5kP1I8$pAqqJqPHcXq#MlNd$Ljk@a=!\D5c?AWnnX!k4HNcNelGX\5$\
:d4qEI c#A:Z#18W\>pqn!48!aS#aF%ZEpS^n*C#9kV#>lCZWhjwPS+:9aT+t4JP9nG5KQLGaZ=/J+^l!TQdDTC
1Cl@hN LWtWJ/cC$#TeLEKmw#LRq&44Y*En*w*<G\@$hGRynh&lDk+Nn$Z*4Neq=\MjeBijZh$Tp1M+Wi*NDc=G
tn1ukp t/$h>:Ydymw^hDkb\:A\y:!Y:NamemMWNp=ya9kI@JB@5N^DlFNq@*QhY==qAC\jVi>GpM!yGjke%MRd
mT$Ct? K=G:F*ZHw>jIYFanR&=Inpt=1LC>#eVJuCk#CFt\TWiCJ$ZShY99bdh&MG9jwYF&/G!%XE5tP*>TE5XT
I@NiaQ kqi^iE\4\1R6ST+SPh>%yJEGRMWJ+$8pem9BWcnki=LRadGemTFVIWb\I+P:<S6AQp5NDKn*b=ZXQBY8
*NP&mE Ia#RkbCt?YmHW4RqPWCBKi5%jLVGEI@YKS@64FM1N\aIqa@#tDNAJdC!4\cNK\Qc9!W5I6iySp+h:ht:
ikhk%B JA:\K?NKAy8YpyXi%mC9NdlqA!ckdTtZBD5FJ&JpP?Jd6PJ9+9h^p^qbaNcw9:ZjwlFan%&X@J&#H6We
T*k5KN u\m1eVw=eKEB%tHY/C4S^9HpPtcC@tNa4>juPii*^aTXWGtaQPh/qP@YcK%B*Zl+9#R=&n^WB5A5eK\V
mCbD\V kGXWJTQAKnj/S:ykyE#JLeBB=*qqCy%ZBXALIFK5!jX!wlp8XkX::kc=yMTjWcR\GHAIwbY8&N6JA<uw
@d8PRQ bkLKLm>8pQCe4V%*k\KZXMb<ZWI*djLKXaWd!kw$E6MR^qWZ+AYK@kWuGm5@^MbuRk9*X6*/bDnlCuqp
V!cdNu QW><<QRFu1@bGGp^XuLtGbaH>CY<cQ$%Qt\\acaRJBc$PG#e\ekML?Q&%DknyJ:HIC$&ZHT*Xaq$#cNK
Xjie$$ :+Bb9TG!w=:^Z\=k@#WCB%GJp5B%&H*KcW6+bAIb5BPqtpI1GZ5:M@TF^FSb=>86iW&pp!&F#EquJdam
:LhVQb NwMkG+$Pt8VEG#8k/Y&pFc+y&HPX!LEba<i:RQE:B#K?IW$G^=djXGdpPuYFu8PETk\#G+?aM@KjEt^*
yDl9%4 dTyW=+!$cCXSP\F9lWhNaTk#K6kd54>p8TCyq>WWPc<mDQme@6wh?P<d^1BHKbG/A\pHN=whk:p5?h<h
h^B$B# QKwm1#Ab>^bq94A#^HK:k!S&jYy+P1WpWwLa$hBRF!GHdyIHq^Ca*L@WJEiCeC$y<J1Gb6KWZGatFTWd
5c^nAE ND^IBASlVTkEj?RAFbhVAtGn?RkbnQ#GIw/S^RmPkl8S9dVVpG5K&b\CC+\!!+*!%C#+:\!c:WI=um9n
:5aP!u qn!dTS=L+@pF551/YAQqyQ18>Fp5X+<$1^lc!G$%ak5=Q&MDShB*hDHmFK?kq^DL\a1He5:HGBKtLtkb
Kh46E@ ^jJwG5Kw+R/wuDTSkC+BQS+j!k6CCS6QJ:9Gp5V51iTwlV<J9&Hh>uLClV&kje$X#>4Idy#L8c$Pp5?N
8lqHBX uDMue&XGd^VGnH91<8>A\uP1\R^4qBbEJhhiXq\ZTHM$?WF/:yEcX^JcIJiMm8hMENF5G+Ty5DFGpy%>
#R$D8! FK*pMPMNdhC8aMq*/:P6K<mXW&b>YXEZ+J>5+<uBCVqRKAl\LmdAR\R>?M$k=&FIu^8L9JeFlk/F#JQq
-AQ\RJ 0001ef4f44100110334 Page 220 of binaries2.zip
=BN9mH cJPi>#ZWhV4YBA%tJi=qY!LEq!eS*EAGWbGG!*?BcJmLl$8$HCTau#p+V/RJ!ch%GSw<NMH#V=/4k^*4
nFqF/c 5umTjD?XI^VSYI8pYw#WZMwjKV6D1pCD<ZXbnSF8T+1qwZKiApLdi!HpqR4uJj?>c&BLXqIcDNXZHbl+
kEd5Ch Z$wC5!S!i<:NXn!tktSc&1nXa+q!:MmRw%#BLHuimdTdG?T%uIECLGk=ccY$YNu\j/DP*IX&H4kX9\Mh
IViaV? lN!ty=WHFEdtu!G:+mwXST6b?e$nhSD1D94EVYY!TNDYbp\FcRb=cwQS/5^Ie4n9K+t\VNPdp:i/+%wb
Zc=YmF uRM:!#pSapjQtm1b^JYVuPeQFKI1I5/PpbGSeBKVKumX1$k5C\lyTh?1H9*4Bc!+/w8mK>8c:QyH89C/
EKDE@X b4jMSSEi+S9qAybju:nHZbi!6G$kHTmVJZIMkdGMEwkilup:eK&IjTj6^Xi+11yl^DXQHiXe+wcqiGaD
6C\=dq yaYLI\DtE\P4Sk$a=jKEql\>bQh<1ylHE6H<S=p<p/X>lkeXq4B!BiP^IueYjmcm&h\XJ=ANq&@=eVu/
H?%k9y >@<AWE5DBBRAAkAIABXYdTW4@%8?LnAAALb$AAA4AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRc&X=e!>T
Lw\YDC bZM9c&h*cZw+atq$LtJ6eL^cjW^dX=a@I&Yu%KEYH\:L%MuILNkPM*kaBWKKihV6qLa\!RTDDME+LG$Z
Mi@1dJ ayhJTLRlqNAk$E!WJm*6h66pt8\A8=6&&uwGwl1</bSYc:bNdMXRlE!mGYdVRK$<RJ&^66I1qZa%W9je
V^c@8u i>@Hjebt>=@68hj9<c:6>*8@<*ZQ9jlHQ:ucA%R16kD5^HMj94:E%:ekk++QHRNX9mY>&D8$\>ARP=FG
S6$SRK l9C\be5Y&LL>NL!RcaCZPmyl>qpBM4dZ\nXDAd^&>AY+WF$C=:4@G848!+VjZ*VB&hycmM:<K>V8KRdZ
*=iEW1 >l1+ej^9+I*ly?HZQkE??d6#pQt#>?DG#^?DZ%ZZ\BblQ@#G>^T<@WRXdCq/CA+>cwWQ#>TAL#MZ*5:e
\KN+9e D8>$8YDlS&Xk%itk^8YCF<jP\dtYCqkjeeEDj>pJb=94+IEQX!D:P:?D@%^bl8m:9+LQ#!B?>$@ky@55
y>:iI% <N4j>pLt&Vtw@j=PEK@N\L8Hi&D+YCPah^llhb5b*t:?Ma\ac1BePAm8nqP\*F$D4\&&\d9DHSC+?Dy5
!YBH6u ?YE69HQmWjBX:adMqtEa@y+S#n+5\Q&QHwXDlh?Bi%heMI#Q>dn>Idl?&kZ9HKmC<S+ZjDL!C^k@*RH?
HT6LkS $uKwNiZB6b<@D&<ejkdiQ>IJ\??hlw5PP=#c%\E*V:hD&FMDe!Ni1D*%V*Cj=&q+KCMVVnR@Cd?<eAG?
E%#+Iy 8HkRdq*^\<F>\:AF>d>\CQZ=k?@BL^&Q\$>4c8D:Xk6eeqjC//ec+d5@cAbjmStCL:$A9=9@FP/ehaH?
uVdcYA u&N\54wKj9EQL<IZd:qAMB\Gc<M%?CK&AL>=>VtaHec^*cW+HkVD>mBpHk4AI!*9R9=Vh?BWZ^<alDu+
>ZE#WP <bNQR8cqEJR+S!C#=!P+**aIuu?tE@:<%XiRYZMiMt@jlle9uILMM@?GZAR+ZX+Ply@hld9d!/H><Du\
hNC66b D=/E+Qk+FB$<mQi:C:@P?!H$%i?Gq$16<MkRn8Qu/wRDePHePdl#dD>p6CD8t!Jpq8N:l$jkyaHu\Z?\
NCB1>b Ch+cPRW%l<jl#4tD<MaDS4n$:EPk!&8FJWMS6KDP@nD#Ih\<&RF#4\*DZ##!DLSch<L$^T:+h1pdQ4CY
a\TG!c \AtQG&+Z+dMh9\6FHZN\%Q$e=D>\Q:SWF5MH#%dD9?!6kiuHK/H*$SL+CG%=E9Z>pYE:/8WW>L6KaKVD
:>!&XK BZ6&dIQjQ9ew>FtM+Kpwl>?&CuD\4^/EjNhBiHDdNnlb?#n$t!*R<6nnePHXjmk/jR*?&%IB=<6&R8dl
IR9pl9 aVm<:^V<j8Rk@QqQj+JIMAn@n1@*8^1k%h$Kq=4*\u@qqeCH4l1++HHB?@$8?QRjL+J>=$=\HZ\L@uBk
REGlwb D+!WCJD*>=@Dl$N>IL\cBKFIkA6D#<QX6*1lcHkPTwS4aCk/D/i*F<Fen\AZV=&GtbpbnPm9cai99&au
9EaA&1 $5kRH1a+!ThNEk>6XHB$1u&19d%>uItZNJ5ZP&u>6u=9j*<>/jYe>KQaeqEGB^5d4/?84q16%1kwPtYb
kZKNbh iuQ1#Z#YXjHI\1Dd<>8bnLe#&F/Cc4QSX:&**qbjV$:%HDKBbcmIm:A8q<5cnWaSq*dSTat?!ekm>G/Q
#P8Z/H b<Zn#@jL1J:<%Z#5njtNlHB:d&>::&B9d1?6q$HL/DadwTh#Jyk!c8N%R6bqJcmq#qKXL?E1<$VWy#^?
WVBtWd I1cQ/YtF!P4K/8:X*hkdh#e&:tne$d8n6*^\5H\H>9Je1hqI6>paZP+P:EW:hlTl#K*Y%q19YK>E4=Tm
&cLGRd LJb&qlJ5=I9&I&!JtmupEj<SpVS@*P?I^?QY8NZ^wJY&&kjuHq!bY=*DZn6HyIk%Jn8WA$y6WT*yX&19
^4CWka wMT*qycWnua8nm+8hm<8Lp=V$1w9ib:!?^$G\/Ipjac?^SIDdcTnHD6Ye8Za%tQH4yC&tY#FnqLTYXI!
AnF16k KpuhcF%h>@#<@K$/lCcWKXPKnG\Nm**h<*YpwSVTX&Fl+dY/G*Yn%$b9nFcM*1BTeTPqdQ%&mjS&lT^%
dYhEmT FjMX<+WaW*tpXibX#qjPI*Iu<yWFNY#w1=8@Pu<X?@#M%SqJCk6u5KYTmpLq@l\WCl&jKcSjS#k1qbZ4
e+JyI8 yPNlj4=:5XVB>Z^eNh%RHR9F8tIl:HkP^WmLpRG</A1yQbZEyHMZdStlDQL6L9wK5T>XH&&wZF>H+Abp
>nYY%P :FRm6nZnG=CG>XqEu1>dZJTVW*jGN!L4SCyS$!RnjZP\BHl&HVY>!JJTXSehDDX5IpNKY&<aIkh5R@R%
>5$PaP 6E=/PyqqjYmIab^hZ&?bu%?p5ItnbKVcpLD9&nY\c+CJ@aVhdy>EYX/iZQd=5Q6<bd/!54Y!NbRkjRYD
qEW5Tb SlR*huiQP$HFp@A$5?S8MqqNj4?XJCPH\&E1K@8eAqhTSXP?CR44MC:dJ=j6!$S<>P=N=N:GJmPVH4jd
J%Tew% uZC#&?PJ*Nh9M1%+VQViDkj&kumB\@F^AbG&k1!5A%qLKGNLi<j&w9kuKjA6k46IJ=^ye6*u>nY>@HI&
=4^$*d :T>Qq!aaeyN^ncEmIZeQ=bN\J%w:G>bn5a^Ree9C#jlhE+EquB#^AqQy#MLX1%eZmI^qbSHk9SK8#6HW
IGZ=PR ST&MMh^N@jp@CK=n#Z=G6Z?^k?Am+cbkp<Ta1LIu+R=Y*a4^ulKcHZNapdLDH$jk^JD/#5JT&%IYI:^E
nLqn&L kQjTN&NW#^R*n*\>:4Q9Wd@V+YB&dFwLNkYbtlEbWZ68hY%\$yaql<T+RI8d%ba%SuZNGJ9PEu9PWq\!
E:MF/a G=HQl61Y:i>!jQ*Mk+JNTJmy&w*R\i#1XNES&q>k<qQGTZ!yy5ep^9i5DRTZ&uiK%DDpMuSMk>9l<BFe
eBFkIX =q&!na*Bq>QF=WId<>6Ek#1&Q/86VaJtlE$Wh=daq>a9XM>Hqkh+9qaMGkpYGRiymaQb/SNCVwEXy?\+
5:A=6Q n:8RXaCKZ1KMq=aWQXQ:$4KJ/nt8=i6jI:E1G:uJmEbi&:NbJq4+L9E6Z5?Ed^8?JGW9:jW$KH=FK$T1
IJFyqN =+LqkT<=9m5$VWmMmatS<>FNW?Bi+q\>QN<CAw8kdYNM$^^jYmA!j>dwihd9W^LWGw&t+Ny$pnNXc#&:
$pFyJ# w\%>!<*#dTQ=w$$m4QCq>9WTwdkPLX>HW^P^ceK>^kLb8NcpeiXbk/uy^GYNBn:FPNd\ZewcG!N>TjI6
q1KLib n<J*$W91d<dZ#9MqI>m:mtiQ^>&E<X1b^1u1VBnLRj6AA^@GH=5$iqa+=P^HbI\tV+MT9%n@Tu\LJuh>
GuWuhp thy\LZ+pG!!:^R%Xtn#Gm>%%hhPj<@jQM9tDR!q9EVIV^myj%HN>P4:eDh8M1G6P#X&PSCK+$d8Z@Q=W
H\nS<$ jFtewhIyL9NuG%qkWH>&yPYL\AXwa5/LKqeTmdYNV#utZ#Gt\<Xpt5Zbq/^5dJT9*#=\PZ%Y<Qmi+C/Q
:Sn&CY i>#G+Mcu@NS9Tw?d<iqT<%pqZ>FXFPN4V<<*I=T%%1QBNjc5dj#$eeht8B%LCbq9*TJb^6XV91J>%?XN
lN=e^J 5yGd=:9kMdyV+P=*iDdB#dmZpQnt#a@Yp#YpyGeNd6J5%&G/^I*pYDF4y8L4Mb=Nj+>AQ8NdmZ#4Fd+t
Ybc5@a Di=5#?Th?&K<b@t/NA=8ZL6MR=\@HDhy>H!<1ipJQ5=c*AV*/G#qnISL:i5@weH%&Ae?P<Rb8G&TV%j:
^Hchyi Qeck@W=QD/pHWBKJm>k9tp!iJl:Zd*IQeMAhE6?<9LyPqc>@RI5:PYt@w%LEewVZaGkyaeRm!Bl<anH8
/E*w\j \TKEqq+JLCI%8FmA8LuccXd!1<1b:lK/QG>ki9=M!>h8=%\J$@h>GkejT&D=GnT8I+*nBS=Y\H11puD>
^tDZ9b nu^8MtpJW6#K!yuCV4ISeb9bN+t9jdKM8$i%%ViyebNRT=?yhb4yQyS#*8FJNCi1tn%4QP=hl/iX5<+M
WuAaaX \=*Nt^p6:e?>ub6Lec$DQN>R=c$G*1A6Hl>91w$bdYGju#B8+1^SQN8!#n>4HeQNR>\T8l<^^Ql?6pu<
4+Y*I< %4q>9LqVlnkCX/%6E4>6py+JZ:4BJPPiVJ?9^PB!&c+#t?L&wcw>bYjV9n@4y<Eh!=8bGh%KN=n?h:=Z
b>ewmG E/V/GDm:Ci!Ml*nZJu\NDlc@LZtFw%ecG^6Z4#QeZZ!<J6H%N!*n!t#!^FDc8?KMuElWdeJ*^q@Re+9^
ZJ<9Fj LS!NI8#1K5Y6GukqHh>R1SFBpdD>SL4dHnh=cAmu=V94h<Tyu16S#TXZX5q8&n4n?$wc?%dH*V=enBLp
$!aty9 !X%uWnqZ#PBJ5IXmP4/XJu>BZQLu\w16L41HS=<^Q9BKTn*Hny8C!&RbQEuY\M8:6t$Iy%khqkFGq4QK
N5DCD4 W9K6NyC%SAFhb%eZXmBhK^GcW^dYJF\%#?Ncd>=kC94a+66HkZ*&keuLb%ZT5StD^+%=PpFYdatEd\Qj
mal/>q YGXh/R1Bnb9w*p%D^inY&86$\:KXbj:qZTiwVJ/auN\&8e%iq8k^49pt:RN&69Jjy1RJ<5CJT=j9t@/<
4Wdyc* 5>5R^i!M?VJIX@%G6P@pE%ZNXXZNymy5XPnKu/=VE<TiGb$I8#yIaJ&6%E%D^^PVFMI?!XBa*i+4c!4D
+Hdmia >jec1/jymlVy4c*=kpE*btVMWinGJp/5hQ%9heVJ@tbBuFd88G/IP&t^HSK&%5+NDyK>cNEyq+c^YDYS
yLbujN GDb/mMZIm*V!b+kemBVHmpPla416Xm#6tMYWudN$IpFpd/$6Gl#MqZdAZ@/t>yF8%hbmy54NSW!B:AhQ
<!kIb^ j#P\uWXFk#6!e@9:/ca:&auie@V@H#ZYjB&y=9anL6N#qCBuV/<jJS6hR?S+NQ$=Ta/t&C5d+l9yKP8h
Y8d!VQ #W@L1MlZJ9^@q*5SV9=ISm1XT+5?Ew$KWY9WlaKy<Q41hb\BBl8yVZQLbhS/mT@cYILQhp4H:FSuik##
>H+8eu 8B<R>>CM^KPamX^Ymm9BDnJaBSYF/qmtHJYi\iuW@CFwV6%tjWS8KGSp\1JZeR>aEbmTZXXRe^q1Q?QK
RRQQIL eBYl1Py@iJLQ<mpeXpAINA/bhSQTBY$p<///bFm1akJ5w&#q@#Hl%\SSJm\VFFPj&etMY6XVadlPR>kT
@tNW/k wLAYPnJmbVyiZY%59C/npu@!1GRyZ@tt&i#PWWZu@FtWQwhZkVBSMAY^/Au894CqR$@?^lH!D4E8be8$
H9yqkD uM8bX9$@H8MlmL^jC!K9iZYM1TM\Ri<9H+++F=E9d*I4SX%6=G\4pc*ueWWuH$lSlSmDwYiJP*8!nkqC
-A%!wh 0009b920f2800110334 Page 221 of binaries2.zip
E\$6&! #mL4FjW<MSGRqE+yP%aJMJbQDFcPYi*@LTXM$Tq!lEZ=IKltFiZuKy/\!Maql#?KVp5+aNHL@CQ/V%\1
TFI=?V ZWw&%>cjVLhimq&XLd5TBbWk>!TWd<RmtbeiDnmhEdQbw9KNjEBlp>l1WTqjpXP4wtSNVEh=Y?jRcJY<
utPp*/ Cy9V1VPHLbKP1Ta<FFb!Kh6G&&4nX=SJCp=?pD&R\N+kl5/btIlEbN@F5EFeZVnM/NL<wee$^jpW6Y&!
Yu\Z*p 5Qpw!6qW6ZjW1ZqDqkYLLmI=F8M4*y8\tJY<kem4E1^1&!SWd:%*a/=TmG6bK<?$wDNLTtZ<uM/dqkt#
4qta+H BEy$wF?SaH5J&>5y&CI\Ik1cwJZ=CqT=kmmuDVt4PK>KZnRmch9yQKIQB@SeWN?X&bLe8IG6q#aub%JS
Qd6LkM >l=SG%nM4WR&I!E8#SKTP$emw6PkN*jwI$4i$H?my1qW5HVLVBMmjPLRbGbBjT!^P^CRHRm>Tl<=+lRn
eAYn?E PVq/FqiM5$!*Q=WuM:/mM$tN#HYhKq%S$D!Je=Hk1k/N8E/L&e#+TuPnPkPqX4LZ/?YDXZAty!jX88\^
!I9w/b !CM5wy:S6mNT<wkeeI1YeNkT+VIHT%T&%EwtG<@Mu$YNM/5P4SndKjIQbVbHbG8T<\ktTy%=kq&#9DYa
bFm?+& qm*>6Rj=$Rt>W*a!5qQ%KEHqK\$G#G#mq@^K:&\NV+RutKM^$t?tXdKZ<dX=XYWKTWl5lI5ntV:GWaS/
aI<B!k qJR4SZEMFe$$RMen4/h$betVdjR*Nlyqb18?LTcqDXGNedPPqXN!/lDF6wlbJ*5Xii9\IE*K1hnT*@X+
JW>:Zt 9d*<nVWbWXCLKn:A<cYd$PtqpwMtT#F/^GLYTXMWjb/IdYPia4cqP9cYE*<YSH/&EdRyk</K4Y1Ap$Na
/QA$nw y%PTFW$ey4miVA!eR>?&dXR!+T9liu8>t8qhVC4mSY%FJ=%$NB8VTGKi>aHX1k@4bPQTS:Eq5jXK\BT%
uHJp&l q@!RT4/:wJJ8bZPS!Fed$1TXVV/4$\XWCQIAjt5EXTBuEtL<<yS$dbJ%EZlep!CTbn#=mWS6?ZEVb\Gq
tGF>p+ jmaPHdFPlFpA!<:&XT1/1yLH^<e=yKlpc$w$1p%bT8dA!@Qt5JTjLbILj/I#=+VXEnPm*=tG4R%hm5KP
kq>1tT !#P91ApaWX+QmTpt+J5=+RpyS<k?jC<5+WyJ:HAKV/a^SIV?K%ShFTuIWd:m$GR^NuQ5!/E#Q@FyijK*
p9P!*1 /AJlySkkK8lQnq!9EpIWh54JL\/TJ\eu=*G1d^6!hDwh!^ATad%?AuZQEhb9>GZJqSq5?*lTJTq!?WQk
@&MEGe :T6NFQRWCp!E%aWKt!QCb4&iK*:TYLhZa59+cnP\!FaIjQ&lL1DwcEeIJ\Lbq!YcqwDEuBY#Nk$1=<pT
ueJHB# **c%4G6X4K\?k!BH44wkJRp/qDPl5$mFuH\PTJW<C/a9NDN89iVKFBdJ6p?%!:aXN8aq%cTCbwIRDicR
u4J66= GVXNby+SJZSIhc8wYu<+Sed\!t!S:lTjIdlqAth%kdh/K>9l/PkI$:Y&WkBE%IWw8?Ly&yKNT@mKk5cK
eRYCGk V5*mTNTE68J/yd1Mal$6dhSXwJ+lc*F=Z&b<y!ld!qhW<1<k%XDJP#!mJ4:^iD+R!NGF&TVQDqLX4nTN
iycuwD plqhtY<:+/5yXDY=T&S#lKlb4%F*EMPl5DuHImqcA6Y4&\<TLuM1t$KZGbe1Yqu8J/WLVjHc14#H\qkW
+MJdZj +?GJRLlDt8XXXe6:HJHIa>^$IF6ZetdCh$wqKZD%1yI^ST/1yYel@mBGA^*9hRVW!X:qK%*6XPbehhcX
Wp?94i W6YWbN?wTnbd=Jbyknb6K<<nS1NS1\p41wCb%l%!Z6b#e#J%LK>c^&qmh/w>j$wyGnXG%e#IcqblH^Ay
Rk@!KP <LYel<%a$W1K6WlLRZW!yD?I=uKXp1uR\QtNW<+Nc/ENG\6K*1K5SdFXJD6!%y#A\<Xlm%:^bL/?ak:6
WqQ#eP >cwyw%iiEPkQ4/d!!j*?l:D4nY*nQP>jPjb!tWRDm\Z4DA+lG!%T+kB$MtC55@W$iF^ypCAN5DB<MXML
XSY/t& ENd#FXRG&DSZlFnddEmuwHPwyEWud&5Wh$XuTTRMNW4TXTMJ/%4BFV5pcbNXH#1dFDA!/Jb%+L:8?jP?
Rlp1E\ ::&WqjbIThRy+i>?#@@uih?n#?qCyNneT+:W:u1l%RQq$kV!/Vt#QljYAwjtSZCTh+B#!JmSmRmXP&JZ
^1V466 &iS>jHhW>!8queTVP+TKA<na%KqGdF8ceGBXHKZ6kG?mD8j/Y4B//KFd&lTJ:XidwAWFWHBtB\<c6?:9
G1+uXF V/&itk4Tk+4N:NF>=E6XSyR%d\46A6>d8X6B!/Z5imTGJH6/qRem:nFhuBX>5HW1Q6+I?9^k4PXV=KA>
9@VXmj PDMJ<V5Cw+VJuB@T/aw!ZjZBQZ&i5!PA!cdP<pl84kEcZqY\!&dRt=tteN*JLXQtn^Y<IWD+WeC!q^*6
ThMqW= B:XpKJNWd+i%K?i6#XDh*B4ZHNlZ#Sw=$9^MJlGKtVJ^Zd4A?5$h+N8:d&4WG^%hwmXL=i:u>uM=MK*6
t6ZXqp ^4l8XpE!yLCSCDZtkyB&p*aS$1$LI?GKqC&TV!>wGH4mQN8WbE5V!K%+ZiD1ZpRq%tWE*6y8VIpADq<e
wF>>T6 t+E\<=Y^PZtRd&?pR?I+leQqV\1/8epjn>j>^yR\b%Pjq=y>6CwwQdhY%W\eHbnhN<kLt1@$bD8p:H^H
wwee5A wG4K*V@y9%t6X8hY/@GyXV%aTbBLcM@l?PyWR%WHLphuETiVi4Y<e:A>Wmh/yN&#ayniStM=Yc%P^?yt
P$#C+J jM1Z8hjW=uaauN@&\%Nd91!DHlF<PX/^a5?N^CYW?Vuy#EtC*=FT*6@@lX#a1Fane@B?MTXe+WjWpYPd
Y=VmtZ WBy9NLbW4\\KJwN?/MK6$TGKLNbHRqbQ$YW^6>XW^d>Wnh\J%&uMd=1cLhM*G/LXJG=tmc6mq@mTVS>e
5>H59K PiwhdHqFl/mMT1!KCdNhmWS?Ek@Hk8G#GmaJD<bqRhHC\GuB>^dY##$=8Mu1E/^5:<BalhS41i=VeQAn
THmJKb pen&h5#*S$\bC&8VWlLlKpimmCZ+Hy!!b>Y$5KhY:@A!IDK@/j6!Vmh=?bempVD&SyK8uDRk+V:E1/%R
BI!AC? KB\+>mX^A%ZRL!nPit9jW?X$4?j^81NcPa4L<DAV*6+Yyaa5PiI!Ne#Qj#aW$9QGVW4AF&S@qD$w/NGb
P>cTpR Xm>dEGyqK56cy9enwkjX@amk+!cE4KqRZE%M+e!Ft/Kk%BwSPVBTwWJFqGW@MPFqIWS+RcV>S&K^tFdj
d>%np@ /IZiI#PJ$Jbal?BL\+l%W@C>4^NJ/w/e#dKEWZYt\ye=Fh>^m/jAG6&+8CS#u1V51$=^=RKXHNmH>paZ
jW8RJ6 GGTeyGc*>/*uNy@LCm#NqJW=<*^quFhtq\>ET@n9</F^NXI$MX/J+>dNwKnR=*d5S*?$5dl=jJPJ!ebY
NFmbQ< #X\STM^C\\*S48n^tc+5HNJcN<lHZN6l6cQQ>htW#<ujAjZMX=<B88d9QQCQeVBqXW#AD#ukIF*HVH<p
S1>Ch< B$4n>p$=11cnPH>VHb=*h#Vl*Z%e@L/^eibu<DLqL!<?69uA=*&%>kmYFX/NldYqDh<@IGE^nBjtIQ8a
HS5&Ic t:L996W9Yw:qBPXF#:E<iPCJna%@@\ic994t+t>>/ap9^iP!kIuHa/F^#Ky!pZA$=!8nX1wS!u>pbX+k
PnXD\! 8$WZeK*CZSpuBukb<QC!9:h^:Jh$Eq1CbZ@=>BN@8j\Z>Q@H+?NV<Zw>NNZ\XalR^b#1l\uIF/iZtc:4
dWjjCD CtC*Z?\D!IBqDTBAFZ=F=Pn^%/?RGM1^ML#J=8IVj@ljQ<T^#TyWF?Ej6&QtXtNXt?nItd<9%i+HR#Wl
Ha$BtX cLh9F?tY%q54485TVMHn<CHaw4BQZ@p/GX^1#wew8Q:D=jnt@=14+ct=&QkHWPCM^<N#MXY>!mWNCVp!
d:iFIu 9lS@9kSw@SWEQkq$Te/Pb>%FpHeapmmj99GT+D6Xn+il$hla@%Xncu^49E*%*PSejZ\8Jt%H4#JG?8Fk
Jl>hIc 4kb$AZaFG<N8H!+BwT\RNYKpC%:BI::9ZD^?+\heCY^9VeZ89d1<8Q/%Pik:u/a/E811/FT>EbPJhnpI
pKN=%X !55!N5hXqPEJ4d9TZ?tnwC<W+SJYLM54AMpw$D&T>lDXK%kZL&/e?jB#HEMK<c*R%kPLn=*=c8\u%J/I
qE$FG8 9TB#&*Hw8+YGFdlcR6K$Vk>EZiudRLhVLILEyYlSyA+RBlpj?idt^4EQu?FA@Xb&<L*%#jZN4**^i#8<
EDiJiI WaFZ$BQXPVNMY!1YXS@mt$4w\jSTFLX>BwbG&Cl&RPKAR+^S#IM!PG@/t^8L@@Vl/^e@D&e&n=<?@eAD
c%L6c& /?8dm*@>FXZW$cJ!yB4=?:q/PB\Q!KwIkYIYcWTFL>8%RhC&C:k%>&q:yT@MF&LH+&p9XWl9dC^8dQ:8
4$b&P< ^5dG<W?>Bh?Pu>:eZQ#&*@$1&/Q6Q4n>Sc%q#&*:QQGZM?Ekh58#aqE<d1PM\b!I4>GB*^#l5cni\Z9@
<FEwLR 64EI5C?@99uqX%:b#F:<$^5j99L>F::!e%qNI6@daq>GNZIbQHq%&%TNy^yHB<nm6:hhG\/A6m@Q#>Ve
:LB1V% J4\Aa!cDBpj/\kcmd9#?*!^??j6+bJ@SmlEcL5mNGYKD$RjnhXwInc9CYe6GKujBT+D68<DZ:q?iu:e:
SKXb/p VXjIGTS>>#<8A8wtw::\\k6H@8#8!M+PHtww@dKpG&G@$XDJXpX1M/k+iJcFVG&!==ZM9N6E9m#q\Z5A
h4LlmG 84===k1k99I9Q@?mB<dtBc5N=<R$lj9Q&&4%9nyZ*+=91^W/ncGyn#%YTL$&E4dub>^c$^X!@6dG+tQ4
tuc>D% /&hPHF5<>8E@@!jqJIkkw<ND68i#It:\/9$M&QVecq!65RiiG>e1iKSJdAHju5<alqFD95/*NnaZAjX9
j:NQ&& n&&??LpjQAP^w$BQL?kK%jSI^A*iJIF:M<Jlp/wNLWPMSE^+FyGyLa@=ieM%t5D*8a8Lt+?6L==+ej*K
YB!!FR nc?Zk<VkYG4p\eNRae@:ey<S:WT=$/nH/k%ht*+\$5HHt$XD&nI>M#MJ&\Xe<J#%^^bQ9L#?+wqQP?pq
X@<^St ED6R6b!CJe8B*pG?!u>ycjqhWQG><Lc9N!tcYjWut$%dQ?a#CS9=Q4i?8Hnm&GM9*:n^Q$i<hBuW/pW^
DiW/l/ lMGL8<FiM&uRSFkCk=#*KyZ+/1q/@j%+R&w%/Q6^yqPbNAm*L:>BV&#nyV^*=5VLm%h8@A\VpqW8D!^P
i^>juR TSaXHXwHIdyjZd?<qH/u9q&@>?14:>>n?%yYA!ZVLGR!<#MH?M=pM8DA6u*p^eW4J*:=cRIbqM8Eb^Ww
n8dM5: P*yB4=bpk#+dAG9dIZ?::y9**nj9\XEQimR#VLiR#cC*BtbqJ?a#hlNWdupPbV<H\wSZZlJMWe8RK=Lc
?Qwi$p KJduk@5!@+InwbS=udhW4=9^X%<%/@X:jJ#!^>M</Sh<yXubmW!tQ#TGNphJXGk9/!!qB\=qJ:kcPK&Q
4E8Pp\ 8:YAyR!4Et!E1Z^R*\:SJ8e6&1L?w\4Q?VPX=uBE#uatM$SemFY!lM^//ZRc+Nmi+h#I<I+Gp^4j?:bK
VGj/<F XKcu^G$yQ=4SXkiNWj$CZ+A%dI@!At5#uX=!1QwwCAjYb^BmAB\aq6kAYnu\<Ta#d%@CjK9PHLC4jkae
BVNkn= cel!h5mE5#%\yCWC>QBWkTP$cJ%&PFCi%jS:&JcWnGyKH8FBj<aaDk@\JX#MC^+!nEKLAkWHm4#AZRPc
DpIYPe Y4BJX!Xk^jeR8mZNki6C#pcAt!D>X8\:^JjnIyA:+yZVFJp6PteX>DpiE?cCa$T@G9Bu#bFD<DWWJu/H
t=nP9b W<A*\RYp\=XhIb%&QK/*WA#i!AyyWHB<HN?STaaEH6yDkb4k:!Bwp4PDV5Q=^$1uPV\L\mIBe&e<G1A9
-A?Vym 000e879ad2700110334 Page 222 of binaries2.zip
=bt1lE *:ij:PHR6n@Kq$S6DJ8C1+At9nd!KyA^RS+AZK:dpVBqB4uIubRBPnA5@P\aHVkWM9%kmXASVkm:Tkm?
SZ*K+Z RHkIy##tT*E1C\qykQGbZhm^:t1V&y+K$LudI>66^jEyHGYa&8Rhn$8AC+EnISuVC^VB$PKCp1wh!Ejq
&ukR@R NMtaQbkW4E$NSaC?jWm<!qSCwdqS9tIbPNFWjBQC8wdDmcHwP+p\8G>=TTYpwCM@\DewhDRyQ^pK^W^#
CM\bP? bD$Yn\RG!tFCYVN@Db6NW1$qTALlJXHaplA5jjNw4!eT<KH?G\1N4=4/PkPZtBCi:k!H\<CctY>#KLl!
<%G1@6 !QIG+MBp*AP?qGA\t^!ywLW66\J*K:Rh>4XB5HkFCy+aBwVqMY!!YMGw5eyATe6YqJ+n8#mXA=PeL+@!
GlH:ad nW*F6uZZFSeA8HjY&IXX:IDDcGLVLRWNyLE%E<4FyHSZY*!+Q$:1<Tw<*kmQD4:yJ?AP%?/kwBWtZeYE
H$w:Pw M?B+^abqiYWHZ\?muJM>dltT1wIPCpyMC=FA#8F\a#YaXKqlNIdF+hyR?QDRb8bD&$B>alE*ECwi!IkX
aG:c4& bbeP64>l\KK%qN!IQR9e#/^m?/<%Kn#b\D>NNqHFR\X5\MPGmC#KbYuXMl?nFD^>m?=B9mQAS4klDF1d
6Lt$@B 9J8<Q&m+6taaJF<B&4iNRX4+1<PG#LTXdRZ4k$EC#l&cF*\@%kkCqiDL&*Tkly/AKA&A>KSHCm!a\%NB
6?j:K= ^CttZ8DZ\R4LaZ^%+M@+DSy%neR4eW*D6Yc#mZB>@IIZjShC+<ASSRcJX>AYYctudZZjRj*8B@1hGe%H
NtTPJ8 ju%<jGSukR@SCn>44XKJNIeV#Rum&RhS++6Bict5!HLW+8#EB1+yiEh4GA:lt$uWV<&Nc!HDXLCX!uDN
>SbiJ! Zt5mutG:<N%%*bTXwlkq\\W4t#9CkeXNaXLLk#IjKd5K/k&njk1e?JRK$VMTFRpd@RpChpHGAF%dTq9q
>dwuP& >EDa5iBK%VPdt1e6QS<iN:TCI&HiY^%94J:!FcwCuq!#t&5h\?$nX^ik*!qdT>CiFKlFWNwXFw&baWi9
+Lyk#> /+J/R+k=Mu1:T::?9l?PNda:&5ju$ajbXha/jeRF4pajP8>?FnJRc5pJanK?GFk1E&14lcyB!l*m9?1+
y&849e e&h!=FQ:BG=m#i=QhEnMlq6#*Y\&bXtA:anWl=&9mM:\LYw>4t+t$QlT9cHK>pQ8m>BSCVaTcc:biRC8
b%V4QP 8RdPJ&8>LEmb!w!Bbeq+=WRHAu4R+=9wcPE=Gt&%j9F4>H5jeCcAnWSKVd5ESG68$Tkc\Li*P:BT8npZ
ZZSF/d yL#SmV%XQ#<idWXduXauy:6S=DjTbXl+Vp:d6dW<!Lut%ww%*Q?b51D#qTbM9d/\dXHcea5W6aB81>Q8
1Xlqjk :GMbi*nl@9F5pZDiLuW/CA51SnIk/SVpIcyiHR=Ykn=Qp+l9!pK?4W/*iLKcC&+W?Fk=c>wXH<++PY*$
\wblZm Q%Fm8pX<T!B5:ba6Ecjan1Xym%Iu8=5t&Fc**Y*iXuijSD/id!W#!lcP=uS@Iy<HXBjpnPw4y>CJB*KY
X8T?8p R@IYSbdDG=N&!<!*$?=&m?4iI9$G!F@LNwEjm^CyVljhW5pwInK:J@yTYhKpDptSb:bL=SV#:ZS4uYyP
hLKbBi =*8awC6B^BBHFbEuRM1qWk$M85dKK=eL#qIKSX^\qDiSS%M#&kM@T*pA&\c?uiKB54*!G$$bMj5u+YJL
b/*A:u aFdVuTLbe^ShJRXTVcXB^B:JtWaeLG<Q/?j$\E566cKhcLhd/^auD>#iY4tQ4IbM^>CwGdZL%i1hQGBP
V*biBH w%*SDDmdjTh6Sd$WmqmFK$@pKFwClww?SYJ8ha1hp!^u\je?aIG/y/#KwFlS1<HqItHE4uHTAeIk$!Y6
w*ydS: *lDTB6NCVd\DET$F?t$DdL6aXP=:CN<DdC8VLqAq%#HecnWHq%*CZ=AV4S=BEm/L!SZFcXq#<S4i:4?t
aQa%6< !lT6Y4X84XkN:15>AF\=\HaIKRll&Y6#%h^cLR><8#X8RnF+DNJqm6Hp\Xl:EHeQ%@CT&h*h>==$CBlk
Zl9&eP c?wiX\Fd+XVL1M1WK=MGyB/nL$D^We*q<9pTZ4wni&/eI5q5GB%EQVHXki9CmLY:t$w>*Y/%8$WRXHH!
>6MEYj kk4Qkt<qM=LtKhWdqPMN$m%?ha%85R1+#JedWVG>RpjCy/!+^F\Y=J#clY#W:Zc/dZkVF@u8Td+Bb+$6
ui@P8< CSllRc&ECk>\wN#6dn/Qq?+X8KnJ>6JR<nkF&j84GA*cllV+lh$uY?BHLVA1hD<b4mKKdpZuCqSFAXen
*6kYnh WIc6IW@kG+Y*cF8i!AC>NE/>SZmt$6Ln&aiD1iFJDB5Rt#6hlDZpniISnZCGcRQ1$MDqMT:lcwdWLYtw
E:j!Q1 e#JcKlZlVS^L4AB:+C1iT4?BPjMI<V$Kp%&!KumwcX%EA^YJD*wkwkyFI>SS41B4hAZ$hLVWLuc/<N+$
!Y#F99 59Pk!m4L=knymm+SL5y#51qhpa#Ai+H\=j9=I84DS^eYKpDXkGij18RmqHHK1G4+cHXKJjnbCXwn4$\>
Gmh$K< 6=nFc1R6=<k8PG<W9Sj68ZcTF*EahW@m@9H5Al^D/k4Iy1BtNY4Fw16JGS@SWk88u5&bcw!q51eCX6A^
Xda#Wd +b@VIlt%c8!?RVwKCAQZ&ij*KkDc*FqncCwec$DY#W8#Ap%%w$C/G\Sn#!4L&cV<1YaP/cnF\SqlJ?Y>
XVQPae 441Wb^iPjlh6!nbt^^cTu*D#TBn+kpHZPl*\YYCK=6FCcHkn%j+/Mqmy9qTmWn&Let=*&^l1Ltm*=E9w
%YhLh6 &htnH/HERe^n===/<CtD/tS&*9#%$uTuJ6Sd+&DdGkk@ba\C%%im&9B+QF4\kC$uI+TX1!pX>q>CjtQl
Vd%N!* &pip/!d/4b6<<A?K=#kwh$4V#cJ:jd1EVw6^B!MQEEk6$aISV%iChqV#JJ#RSwp8mFumH8C:MH8iA$aV
&hku^L I<ba<5GVP$qWLSl95VN^M8>iL&FF&GHCZZn8ql%Q69pDEc4WTHakcl*J6%5n&ImtZ&c<eQ=b\u%+\tnc
Zw/L/> :5K=wy6<16?Ettcm%IVpB?Z4hBRWT%J8A&!4NWmXQT9R5i!NHJWLeSTQjBEYGJ>Wu!<l/BL+\qYS>!at
*L9I44 dKMDwy=>@L@#c/Zy6SZ/9KuehLE$ZWLulbDZdRN5^!4@?bLTL:KPPlyw\LeXBcWWIdAHayb!npTPLy#j
^IGXLJ +>#ZLK$%IX/NJj>1k1kTdDZZQFID6$Y?RJ4+y1D>hhl!^SBYDW4lh@+DY#NedKi&#%aqXqMaiiHw\8#X
8PH94F n%ntCYN68yReT<+?qY?TZJl9dn4cKWZbq9EJ8GpI#KL9bbQYB1WYZWZWmpy#dkWj+$FyH=?Ai8*<*l/>
:it>u! lm=wIyqMnn*%uV9!W?PSdm/*Q>&NVpi:4N6&J>4Ja5qP\%>>MK8Nh<CJ8DQCdKS@dAtZ1BCt999w$aW%
pN4T:D NK:p\kJkI8\dnC1AAVa*ed&an*caL:=dL\%X=JIuKm8h4JRAc^e8Eu%I=\8wGJKVADi:<CeS?JcEB$TN
im^/\m @>9nTq&wN%i>DeBH<1&T$\Y!iSS#FA14NC%Z+S1w=/tkVItZLA!6tS1!hqe6YiEmi/S/FDBub/<hVj:$
$pd<#F /1QJ!8^*#q?>>6y4**l&d$a&CBEybkDi9>:Kp&$lc18FNa!XF86p1F&Q*htTQ+YW\jm:VX*MXRRht:%&
AlQ!Ek LZu66Whji?*1u9A1%aZlHl/YM1Lt>9PkamiQjEG@Lh!H>K/%qHbWRA:GX#I+6>ySXE6S:h!wSt:QJ5eI
iY^1T$ hi!u4<G^>+bE4iA!iAREI9qK+Q%>1EhL$<kXw^>*Q^cQhB#XkcwwDWK&KFy%&kH5:dHpGD\jSc=Zu@*G
iuD+JJ Z6ANXYk/HFHGnKn+:!Ak<NuyFu/RLbqXm@1!qJWG&^J$B/^4&SP!F+GW8#p^RVwLN96Te8\<wF=>@up8
mitYE@ :@a+W5MLAc%<6+wjAWId<jhL/i=%:DukDaq9Ft#/*dRMGZK>t&5<T#y9S\^!F5dG$FWR>cNuu<X@hEGF
iMD*yj caaZhC>LYKB:t#+%:8^bELB#BN<9!u!#Z64C/qt+4YZJ/j>AGuP:lZPe&%YW:%9Jq^/>Nud6$a>\R\Qy
?uFAM: hc?mcXjRDdTd&^h<#*+!*aEH&4QF!\hH!6cTJVaX@H>lX/@mNlCE!#Sy#B4TLclTaeSX%^t8Nkl5nCCX
B:&FwB \CqTBahA\Cl1:kt8PP=iIutEK!Ze8JCLk+QAXeF!+#=%h9=&b&WuMWq##jDN@*/#P?K!^N\bTAZB>D^n
YwnDq4 NH1cQw$tL>Q:!Re?IIqM<ibc#6qm*m%=XRHQT:=WdZpwT@A4a5Yey9M&j?SKkAdGAa5#4&&S6WK<$/e:
IEu=p^ =$&nN=QJN$=a5XSTM<j9^8M>C6+$TX#1YCY=qWHeG1R$y<ycZa1et5ENmwK9<+EQ*>%Qj9l1=E6lJFm5
W*nREJ T*DSt\8<XbV8t6I=qt6Lid%G@>Ey6uGT:e?TP9iVbdnJDdGDRLN9\c+9tH&#X?/jk%SqZ@duyecd\6e>
&M\Ap1 $q?NhbZRl69Y#^bWCu&nHQ1l+LeJ::KKF&n=cqVZF@E1<*1lBh#D&P*TehQcSq&u:<hYjt*4@4u@N4@c
w95a1l $ZPn4WyY$8Z+HKXnmSPHCN=T5mya<k+pj?@ZX6*b^$m&/&:&hhdSd@a5q<#<hmeMED:5C>+aMJq*GETE
T=M&&@ N6*JV:?jJk4$ijcPljb<S$Z$4PAcE=14PmJ<M?ZPXQISd8w<1+DZY9DXGQ*Bt8FcN>V*VV1Ac&S:q%EK
K=<X^$ 44&mSe?*XQT^I1DkqBa@m6mhLQncLiI>Ln=D*lR<i^*k%YwiT6b?6X%19$IXA>#?dPEY1l4VFdZN:XHh
jl&X^H ZjT6<:uaIDXV4bWVm^<DKkyBm&IFc%mISPYJRyeQka!Y+G/MmVkpBdaPlZ@D9ac+XZEp8CqyihG4F*6V
@u8pp^ YcLVeebKZJlBu:H*Y:SpHW>&GY&NtVQ#i5ac1L!bQLqu8L&/F81kn:8<>HAlydtGd5tL/L\#T:$>@$qh
Nw=4KQ +PS<^L^SaFZA&AWq>*y#m<n8Pl4@81VSaH9V4QdLI<HXC@DP<A:TFYhJ>mwE#NcFiYM*iE<?ewELDR:k
Y=q\pA dctjR?a**PW#q:We8=aJcbK!qXmZ:d9w&I>HQQY<e9uC\wEZCqHVEN#Dk+1l#ESma?LK?A<>Gh>c?ilq
VYc6JJ +<Le@uPuu$uCm5P81:AK6lBEePIFC8elQy/amLV!9JYaN\9&qhcK+pl!Xh>*ZekXKN:BQc*S1T^&e!$T
nJG:\5 bah46h$\i>Y$%X^JX\&$>?jk#y\#WF4ZSbhS+R>=ZmdT#CGVAyVXY/%qyiQc5:AKeKdKQnY\/M+yBY<@
L$M%#> hby?uC*m\qDBNQm>/=qd/mJB!?=e6A4%V=HPLHNAhRi@<kbYiCqF=qY9qq5=9*Ju\%^T<==<GcmnV?#N
IXA*HB 1GZFhnQ>G>HPSyenZ\W=inq&<#^?d?9?WJ&TwPWX5V?4c*cyVL8W@$=cSD^L*<=?Fd^K+CLihZljlb/X
C*pYWF \^%bEh!CN^Q@KkZlNcc/#@q>nmQDkZTYJ?q^@Dkj%D?u?c1E6N#kcG!QawF9nmaKq$bG<$6=a<9XmG5k
:!GG%N bGb/RLj&^biiTX=bh!lNiBRI^AIRt19jXP!NJ$Huj=?SljPScmbD68J1pQ9H:A\=V%\kNVS\BbcL+Z4n
8KQSaN tu@PId&tN%IGw=49K*+jHuj#udI?cc1KByD6kbRMhQP6GHj?u\qw*HCIjWP&Y9RE<A>RT\MEFAACAAkA
bW#!4? GFb6JSuqt+mkAAAA@kIAACeAAABndGqqduS#L*BueC>*cY+#Mm>RS%B5d&e9etX#L&JlbHNyb!=ya&@h
/Hyu*w Vn5KAnERuX$q!$IIXwJhTm<liDDBuEDTB4#L=mmYXpG\YdB+#mTFc$DWVu\#d%:tp$tIGnb4F!R+6$SL
-AVtnS 000ba6ba30700110334 Page 223 of binaries2.zip
W!*JIB %nZVM4jMl8c=S!&>kM6P#lWS+$PMpXW1!E=AEVEyTjkD>HWi/kq9p1y8QPWtHFY%a=1uyHV\$:dT%D<K
A>NtRn S58$4^+N@5$@j\H+Cnhk8AKHGZDykLE4GyqP8GJ8kNN8#<QDJ^99WE5DBBRAAkAIABlYdTZ&8?C8j\AA
AB=BeW AQ+CAAAwAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRdG>uL*Jqe!>ud&>pe&quLtqnd>&L5R:CMA^E4\YF
kjN%#i yY1bYMuIZ<CjpW@Ly#B&mmy%RWLmPChVImHBCGi@ZP!VkW:q@S/t8ReP<yQ\+mI/dHPGHt<WemPEaqd/
=**BFa ^Bnq6tF8pMY5dGZQj&yM46t+Pl/c9JyVepN#Ze%ni@&:+5h/mJX<d5n:44CIKMIpn8JM*1:<Sm>RT\ME
h6khTW FAACAAkAGFb6Jd=qT!WWARAA@kIAACkAAABndGqqduS#L*BueC>*cY+#Mm>RS%B5d&e9etX#L&^9b&qn
4bn&dq d&+8cYN9ybK@dwM\EMaQYmqlMb&/kyn/F9RqWQ5aLEl+m4e$Y^dp=t%+FMcPGVypRLq?b/QYSw%W1h@b
&hI!?p Q6@h#*?\IEykbjqAww?W/BH?Cd%Ej$bQ/N:XKKWdM1/SMh/JaVKPI:^p&DXm>p=MWnL<WTaP>#aKD%1*
VnBR!Q Rdm%WBB1WS556mF\$DwE>kN1J=G9hp*#=8Z8aIj?6Xppeccdhl5DLYX8@it+ADJA9V@AD5J6:Q6!j6b%
u:Q+JW K1*K@96?>pXFZ=hyJeBQ\1wXwFdAeRYRA/ww<S6R*RcEWK5E@X@56GPic?b#\V#q#GcDQ?PPb$4+DGRp
ZTXq8X &kG6<Y\F=9tE%$M?9!A*w*+FK#!dlAFnD/4=p+1qRL+\aZ:B^6iCA*$BWE5DBBRAAkAIABlYdTZG>HZk
?<:By& mAAAAQ+CAAAyAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRdG>uL*Jqe!>\b*BqeuJ9em=ya&@XVnET\!AM
+hAHCp E&u8GN8yc^u#m@SJ*4#!NJ:T5d>\bJKBype8a!6dGNuCB^AaKh*kiA@AuZWmE@ppA<a/\+APep*p9BaQ
yn%m66 Zpwy4N/^tnBdm+i*@QkHSFXy6iyu\:Y&Pmyck@wK&ju%RI9!Rc8njQtq@=@>j*<ahkc9&c^e#ZIpL^6D
/%NEBH l#=:$D?jY4$AWE5DBBRAAkAIAB^YdTXWj\4IMAEAAQ+CAAAqAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhR
cShA>u e&M9etX#L&FqiHB4Ltqnd+YS5Y:DIBCGL$pqGC4S1Y5#>m*cS@J&Hm!X#R^=KDa!IQEKHV6/!+JE@\NE
TwqW@N t:SXD*/jQ*:8nAZSD8N+jCCJn#*SI@I#hISiwS*hXa@&>EjaP5ucqtVk^Z8QLC8qVm1qJSt!JI?jwh$I
AYHpd< 1b&SV&jM$<u=:8L%:B4dqXq<eAR4kn*jD%?V5&=%X@*6P8t9@6J^@ta:MG68$hqyBdCX/\qwan59m6G@
%aNl>G wkw/K9c&MXE9u$m%V@ATRqnClN<SZpNk<AKYDY9p\LH=^N4BG#=&MEjWL>^<aS:>lT<l=HDJIijKy1TW
RCR+Ip e$qqeE\=Cehdj&8eC@#5!XQnF5nNV%Kip?uZbZ1=cVcb*6:$&^#?%4t%V?c*!<=EB^H&H6+lHPFk4:Y:
/=/wGP $jB<4>q/n*?p5y!F/Aq/kh/k<kqRT\MEFAACAAkAHFb6Ja$cIIP8BAAAblIAACMAAABndGqqduS#L*Bu
Y!qL/p eC>*cY+#Mm>RS%B#a!>!bZM9aZNnLtqnd?&ZMYlnS^CGS^iFy<Ik&^!8DHh^FVhy6uKX\$W/\#XP/&=J
l=+b^\ /i/yCQlX65yA\LDhFWqImnT8XclKph9cd5/Xm\6GaD$\TBDI=J?b%hN:5w#QlpAK:>NwNVQ9#Z!:P?\?
ChW<D# EdYwVc>j4=K$9%+RjaN?hhZ$L%6EZ*%G<K6K9*cI9t&L*@V9Qmj/b\Z*+dje<kam<cRXL?miX8mHm5I/
C<a4J! 8jBnPB!mF\94l=m6p$6M<uYubj%=E:&dX/%ui8<p#@9RVyLi:?i>@kt/yHM@Q=1iwE9/Ei/j=8l/T?P^
^TYdFy 6WuTb@p4Qh$:TjuMj>KdyH#YwF5?C*<I*jJbiNE6*wQ/tMbn%Z5L#%8?8b:!nehh+pjpG*i:E?Z4/j!K
#4w8kZ j$!WT@^Ku&VRdYC1H<4+5:!a/bu1<?H4@GRFNic4R*W>=/YXk>Vba&V+hPqCZpG?Sy\nCIdha1u#%XV4
Ic@/IE 5#wj$u>a=%p1:G!Kty!t/itb*R1PPnu<YK/P?FGaHdE#yX=$?Lp:Tj/<$?64#5/l=i+hFnd^l@P$\>bh
5yk6F+ KS+T:BNFlu8:m@8BLY*Sj9\<DV<Mcj#uL>S86/uV/hDK!k164c*S^5aGdY=8$6dYFt%9d>Q?@n:6:i*S
&IQ#Q4 :8+8:i#5WQE>$>8*VD@TPjEw$l@uN*V?<TQ><N99!PAkHlIk$XTHL\idk<&Jni$YD:9HD\?:l>&#QSbk
qFS*4F D:AHKAH&\B1KI8\S>kl:lCHKkpJu/B\6qX+iEmBma$8QL\eGB\aHBkeGSRKDA+MDk\PDA+Nmk5GB\aHB
5FP\1X keGBRhHB+MDk\PDA+MDkGDb\PHA++eC//@CWSK+AmSC&IaQFI:qHIw?kHm\/DZB/@QBk<YDScRGHB+eH
>^=XPE l\>ma=51eHk\iDB+MMnWiZB+MHk\SK*+cFPIQHdFNL%PmaIVuY&1pV8AKTByRIIAywDeAe/AICFILLdq
hT1?bZ $N!\I*>A@wD<5pRB?aQa\SDAEJl%&Y\q9GaZMquiCIcIjBF5ES\S?ZSylRN#EMESlRMD$?ZGR^E5ET\S
/\\W98 EBEJ6RVAE9Fk^E$SlkkYKa5wLFmVCJaw</E5Wk&!CpFLmeHAaGA\MBkaDFyPaIlkaDA\GCIa6MVA\GBk
&EC?%! MDAaGA\IDaEhDA\GBkNH&Y5RA<EaD#J8<q:YCP5w?=HGqu5<jWE@$<HBki#chH^<VKiuy@V?@Z5/P#8n
yND?+H m+5L84!<yK84K:1?91c!LGp/uhL+d/cj*4%:\ut?:IkjLY&X9<!Y6ab@6D=TY/%4?NjNW?<c@yJH/%t#
/u?KSy c@l9Tu&\*n&Cd/E6?ljGZ!+bZ#%88Vm??9Q1Z^lj4bt@Md:dY8#pd+!Qd/5&<#j+Q5E@GA^8=d4HL^B!
6RkEMe Xj:G?JdEd+^Q+6<P>JM6G^>LdQ*eQuX<mu?@u\^?Qu>b9Z=u<Y&y$9mpLj4=l6L/Nyc5<y6d@huNVdY<
i$E%Td /Z&Xmc4/wMFk!iyuNZ@Djci?1Qu$R9XmC@np>9>/u:Q*qDi6=@iW=@iW=@iW=@iW?>=VZ81l8w+>ZIXi
Ih@L%j \wA#Je6M%D<@#Ej%R:nMGki9d9d#W%b$HqY:884b1DyFG94Md<>#Pl@4#&8<hNC\uVCn5ua1CFSb*<6q
WB6e@h <:=u=&8q4Y@&Q\>CD+teW@k9YL\m?lhRT\MEFAACAAkAHFb6JhTI<*!dAAAA@kIAACRAAABndGqqduS#
pBnQ&J L*BueC>*cY+#Mm>RS%B#a!>!bZM9buqqd!=ya&@Nn#EP\!AMSV?lE1M:hR%nd>EincN^FMcPnE^%db!p
Q&=Kqa KFKpnQut=?W:KGDATeX+l?w#AR@lW^#Fd:HD4Z>LE\/W?pJKBm%=!VpL6eN>khtkyT%>ZE@E%YDZY<pD
@bKXDt 1:W*&nA>5&Zm4X>lGXk6J=D6Qe4n@9*@luMGE9@98+^le%^djELj8XGnTnYWWH\P&Tjj:Sc9PYkXc1<&
Mt91GY <$u>AFBLA\RWAAIACAAeXt$qH5Kh<\SIAAA&:kAAJ\AAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jq
mR+TZ6 e!>6aVE#iDI$LtJ6eP^dP<#nXudtAkc8kh@@nMTHK^iJ1:kY5MC&Xt%kG>jd1YP>VRyZ4kMGMKB8m!SA
44S6w> mnT8YdlKpXYS!t/!%SaL<JK<9A?CBFLejPheWmL%T#PctYTSNXa#$1@9u95+>**P^/M99@yqG@H4q^>F
GTk#R\ $h@l:*@m@Vi@mKJjSB<HRSZhiZ*D@/N99kq@/B??@QDDD>EQ@@XD%Q*H9$RjjjSS>QHHH$ijjQJJ6N%8
yMAkkI w$<@@VV/:LQQw5<@@##/+w59w1?@@n4//189wm?@@DL/%c>?FZ*#>#:/>c>>>I@Sn=G9V>G@@/mmH@@$
P<k%he y?kj@9Zj$MIP:\QiS:^QAi:\5WQcDtp:T9Ml!\HyB*\=IQ&A>IMQ^a=IQ!L>CHBE?6F#XhEJ/Tipu=B?
B8KkTw R5IJ/S:aA@6VcI4@HjA?+p%yQnTQn^%$&EGHHZVaRRhYCV45wMMPP8!k\\+/5J4RaRehh6BlB^%&$IFX
C5>1CW l\+:/LCDDn9w5IMPP+<$/LGDHn9T\@9RQhcE@l*^Q8H6R=il!\GNH>DRAbWiwA5QA+RHjDqAq\N$+YGB
N$Z&p= HkjweaAil!Pq?VBW$PMAHR:R+RAhcPkP$PMAHR:R+aT&QD==CNFP?HiclujHGl%*lH$ac4S>lE=HNHyE
96tJme A$jwhEVdS\mQ1PS+yLy<tA=8G?qw@+n&n&mjy8mI>w?WDl&P$PHwQW>dtIpD6$/c$jTiwMMJ:b&k&\q/
C/uHFN uNAiV!*ykVE+Ra<V/aGP<ZTn$At/uKDLCW1e$CA9Ail!R5EVMy&ReII86C^PyA9t=AShVnRi4A86By1F
+/Vi6T I!<qD^$<hQDR\WMHD^%+PWGHE*V\$MFDl^N$+CWGHV^$<NDBR\eQHXA%*pmHDl+/iPnkwaBH?!hW=qHR
\pN<d* I>QlRHPEijVWB6XNiR:S*$d@HQ*tN:?Jj99d*$djj966>N%**$Y@@@*9w??@@#://cijwn@<+R@SH@@+
^6+&+a ^/m11pl4Ha*nGHZ@:cN@?6*95I>yS*9?H%G>nKlikn+chP?M5Z<BL^NiT*BD+8^j#G9SA:95#nXCy=^d
y*?86$ jd9Gn\B*G/^iX&WY\:pEuM8=/!K>y%jQ$QYZ:^eJhat:lWWcKyn/Pj%^p&VYkMB=TADtIZGZC8l#tY$=
>1FBuK 9FMbh/:AWE8QA1%pLtY66MQ?cB5y<*Hw/Q6Kk6yS\9W8cLj8#%L!Z8B/9T!!wYXu4wC>K\Hwln#hdPLB
5EuZbc >BkbpY>j:@Pmk@dY4TVYPP?hyR<VylE#HPb!KdpQ#D*JiijP5>n*m&#wG4jY5$wQAN%:W+#Kia8q+N8/
F:jQhT :8a<LKpuCYy8/!1y/laDWVb=Z16P%HuiqC8J9Rikt4&AqYScbhNjMSS%u5S%!YZ/4p/VYlZ%wB<E&u41
W6:QbI lil:w&$9tpcI5cyL:J1%^BZbN1@#dXc+91!*V/uTKu*cW5/F=EHkq&CcqhC^Z5SQG>qW&:S\Hm&NTX#F
pkF=u+ t?ipMA!TN+Bp<=\Y^uVYh#KX&n6$6K*nNI/#LKhiLCW>NyQC#Kqe16=dNSdYY<!4>T9J?\C4wdt1m++Y
\6*Dti u!?VKC%bI6DPIJ9im#ki5JkCcK5FEC9A&a#B6*!j6%l/^uj=Qt=St^^F9=J$tCnjW$yhq?lQniEL@XqJ
&MW$\j HkNh8RTtM*$yW:Sn$e+\=nH%Xett<*1kei8HinD?RYD/91%=P&DFi+F^R+ihG6HPYaLFl+cFe#n1/I9Z
/M>tkQ SX=4d=8<$Q%K<n/An^hH6\QYHM&VmtQl8*EWQQDc/$aY&u6#Aj$cLLL%Dy6iFtKwMhTYqcNq#A$8JbTA
Yi\E$j iZK>GQFFR&CwAk#ISVIy?1:A/4J6P>*Sl^X!:Q!RX1J45BV^$Vm9c&yuAT!D+wdE+NkXWyc?qBInS9Y*
+Ey5$+ hG?HBliTe5VEaaZ$1yI6>k!6N%jIRj5k5bDpa@p&aG+Ay@L>hy@luT9ZnjHk@XDl=t6KckeDn$?$\+&c
y!cX^w BXlJ%6qwd>QJnQWt/a<h$M+pwVP:^@iKG9JDp6Y&%@W?W:=9<5FhJHFFG@*hki*EMA^K+h$=TBJI^D=K
8tdZE5 MG^quYQk8#GunlC\T?C8RE*A+ckb/IDJ1Thh@mwX&I#WDyI\aJMEK5Vd8JcdKBE+Jdcd6I1#FJ8IJj6+
-A=CAc 0009c17379900110334 Page 224 of binaries2.zip
d>TDSH nLeJ>A#bJBKwTK<TA4PE\YaJYEKZ=@S!>6#PE@cR1F/u!46^t!LdGTRBaECh*KR9\jP&^4FRd=<4RjjT
c!d?An Qyb=YpEhTDbRYNedTPmR4?P1T1pQuXKhXuuX$EpSJGuXqGRqaYW&FX&HLHFhEYh^\hq/bE9T9ApZJdLl
mHYnJc b8A!MPTeHmRYP5+*4k*bC1Xc*cqBcGhLJZBaEeD\C$ym+H4Vmlb*QW6/&!1YmEGXEAtFWnlieM9GcW$c
q>4GDb 5MV&1I:1/#W/aawKP+yGup+na>tPwHQh/=aNRF^Wjch\qHk!5=#6/G:SHd:BItMn^4GJk/K\WF\w4&p9
hj<%Qe J:Kni++q+eXYn<h!LDWtpT\p*\/C4l8!bL!tbFVK&imw:+MlnY\ad<6Yn8<c*C=ptyG%Rk5AG41\EHBG
?%J8/D aHcwP^y>1=6Cy4RVDNYE?=WPaJmuhGdqCa&Hy8=mMieXLXiD:*W#VGZRc%GQhW*ueQAAhDed/NRmGbhp
TV%bd8 9tE+WIZp1nE1jb6DAc4cPFnLXa!dCqZ#8T>4tVicB\<cyGQZw$w#lG8b4Xc1C>qGZG\>DatIw!hyTEnn
pn#biu tYYwAe81%*^MXhmDMI8\h4D:$u%NXl>L5mmnH9Ae:LPe!=DSKGTF4ncG?<MG=eYGt#$J1pDphCPmc5hX
bVT$dV ^%q#4ny>T4q1#BQ8Va\e>RiFL6u1@ZdWQR?L6h\wb$Pn9S:m:b=HTyPh1IY\*uXaTiSLhG%HBu5\LGpN
6JVHd9 <?1n6iMketTka>BS^wW!!KP:n9+9*J!Znq/wGlc9uc8&=X\%B1CpdWC6I1GnX/l6pR&d1LRLy@PTDWb%
9>ZakP &\4ieYa&@6p*M&F$i*9^eY$@PaE&4G4D:c#L5NI4d@Y&:@#&15>DeKtNT%E&&8ZY4Q*npI%1<w5&&Zt/
n6WG9D $A=4^&!JFq:whbp4d@+PG*C9/4YDc>de\JSNZ#tMuEqjQF4*H4TI?#?nWn/\bqww^9=<Zn?*@9#bTLM@
jL?pjm &@!+!/K>Ai\N!R*&#LwdBJ:4#!#bG&t/8<BhpaF8Re!=BXkWtmp8e#+hHkQ&FnBM&E$ybG+X:Dcc?iCc
l1n##? ?de4aG=LnFq!8W6k:wF:jNeTtLht5#N@b+NJ\%6T&>:Ahml\T&5?bPuPPb?+b?C8kd%p5!>Jc*QnJF>$
N\w=tD J%BebIn&F^C81*+y8RWC!dww\$8AVE+&P+PFWkp&a9uKyL5!pHa>tc<Z5JbM\E^MLt8#BQc8JFBecWPe
Td6S9= &@DlwC>qXmpnbJ\ZJedb\ylK!SkpDa!15pR1N1Z8Ad$EQVP=5EeqedpL$L6:E9Id5/TK$?$&Lk#5#\<C
WBFp>a Y8A:9K\5#9PSjLA<m/XMWymHBQcJ4PH1Fia85G9RFZt/*?@lNZZ>k/CWXRE*PN*p5GEjAh&d5nZ$9h+n
VH/JcZ E!^u*<wa%4A9G&Jy&y!BXwY/B9KPlI^*N+#pbY9#ICBmkV!q8wbd@<Gk!Kq96R4WMyNj^J9RwReSda1\
=5he:\ @nujA9R*RXC$H8!56RX\F#A8\TS^R=\$<I<p@Ld?NlnQRL<yG\HmNh5/T?u=SctL5hB\R?t<e6lJcTXq
jc4\%N ZyFn@mAkPqwZp=8&BGaF:DId*M61u&Y9N?RYj#CA$=q8uy?#PNpuA=F=P4TPSwe+T&Q55*$<8ABmkGT\
k$GLRC K+p:A$nIKi+cib/jS\BNcc6WI+tjl/i*AM:*T\DJ5JRMN<4kImwL?NHiD:J\R$=HG#u^k*WDMbXMTSjt
#Zp<B: RWDKBjJ6YqZ?ClR9RZA8+VP#P8!hLwC:A8a&PJjSHSc@1y1?L:C4mA!Be5X?*@RA<YmJte9yQ1ynpy#B
YA>nW> TpJAXRA$6dkGk1I#MLiAQRQjnVnweGdVA\+C&SqwTYCjBkpDj6wBCdJX<j+C<n^Lmd#EVaBqlQYTXLmb
5kKQeQ QD&>pXmBCScTL?WYlblqk&RFewCE!dk%eEJ8Z<XMnhl4pG?ia&ZhE4BZc#w%^4m@&Jp*yc14PKiH?NmB
*tIJ#n 8CNn*B&YHYtwtmS$a%G&V6X^pp>qCKR=15Q6ZKIHSThpNYCQ<8bM<+HeidyeXV+^e%n\X5mJ#cQnR5kW
1*$>uq 6^h#GMSGI^5>ScCd5lnc$D=#e/wMbyC#HjF\lm@1\M&%bud+eVV15mNEC:FVk5$QMqiyKTbSnJ%aL1b4
R?jVl5 DF9N@Q#R5qF#Q9&DTVT^dJ^^@8/+el%IFGap1S&tnwnNtQtWWGam<QAjnY4S$4lBF&>Ec=uQbJIGyh8T
4wMJi< :Xa*G#:BMGTYnY+JG4lYJmM#kESw=qYXM?iG\X&\dMTL+Wm6Y\I\WqTi<Q^wG&#Vccm+/^QqbutC#t^i
hE#+Qk j&H#mMGVXSZaQBKMemd\cH5Q*I^t*WTXlch\XCdH\8a!ltt6We1\$blqC%RaDZc9$m!\dA+:/Qpy$J9M
9&8!Qj 58*#itSt48@dMetT1TG5pD#LlR9Lq:&K&V1?eB6My4&h#YQK4eI\Eye&EZC#dwGt1>>M$=%bNu9N56HM
Jk1e/p t:I$:L$Ebk=Xhb$L1+eI4?D\IJ61qGHthHd$*HWI^aN5HnP1M+H*p1c:qMGK:MSe^8p%Vhj*F\dl#HG^
CIFPMP 1u:TetLb#IXqC>9m@C#i&di=%T<y6/ph*1i*Kdi:NN%W^6/t/haBHR68!%^@Z#J#?q&JkejaQL9k$6=K
Dq/Xjh $:tZ@N6LQ8EPeG<e@Q<ND8Q@DRQ+%>hjZ??\hF<e4#jn*>#n\ZCQ:JLHw?q8T6b=Lm4QXI>dBQ4Nl+yd
9\ab\h uYL9A%au^99Yhm9m$1!nFe>eaCBp=%IBeDRZu+nlWa^^+VHIGVm#iQ:n#M%5L$>N5=A55/*ciWQX1$/5
NhTaJZ iiV\nMceI^ibTJ9m**w?&dYh4NFk\@L%y=eAh8yhmiu:F!i+QyjSX>uP6dpZXV81?mKb/dhb:btYSy<=
5@qPl< ek>hwMnFWic%IMP%LhkK/qWe1=/a6Rb?<@V\*m%Bj\ZmY=I=qm<5+XaX>TYdK#udPSSkBiI%CD+G5ZG\
<%i*!J PiXI>J6qVY9B*k5F9R#DtLQ*$e4>1/!1Ww+pc?Z&Pc8%44jb\CEWtS^pFp@^FP<KFu!>6d:MZ?%4Jjie
Eanabk #bPqnG!X<I<CGGqD6h@51$FV@E/?*eRec$*Bjjq?H<jbut^mC4p1it@HSJaWaFJVPE\PR^\cnMTt?cac
^M1LnR T$?kATl8k8IceBp?k\K:nj/IiJQ*e&$W\6IV9WXSp\TwkkY+IXt^dBRlN11Pu8E::DA+Nk4ba81CL5ct
lcacS$ JL<>d&#Qabq\+c6ccXQIAWc#M$^NEHD9B9y8wAml4mAt!&CRmAt\FMHXm:yymYFy!P?cRS%A9bSe\E!=
*b#=lP &iC?hGP&#:J$LIp4d&pcR5\qEZaWhKEHPdd\I?4TKmu4SuZ6tC8PbXQ=&LcnuIAppL<XwI^*VX1X?Mk^
dG8y&K dKJymy1aS+1<IpW=ktn8\kMk5G#E/LukweinWQmAQ$bSF*D5kqiK8cwF?YSWTI^NX<I=XE*SjZn<G+X#
4=*ZAn ^bn4F18Ac6cNFFmSW4Aa/$*MYn<AR8SGZE<?1KBIMt?Jh8QF%>F/\!e&%19NQt<>lWyTIJpkyyQm#tm!
N%VN#n Wbbnk<Z:AHaw><?T8AGDthhiXVl5tnH$B<pZ4h<P!A>Y%V:+\TTTPA/\wkh&$WhlR5Cc\b#Jw5Yll#Ru
aP:Bpl twLwRDn/nRqndeJa6\9RVyL?4mTWIc=t!CcK1c$^N//wB>XkW+YBh*iubNYjpGb=*VY<Am&LP6:%BVFC
Lc9!*u Vb%ut=^CpCkZ:^<eI1YFRMyGa=$$G96aGinGwb>9BlVGdT=AB\qSdqXhJ%8Ja$DnyCBC4wwyAE*Rh1RR
ucKI>! QiLGF/C@D:k&bXReA5GE4AyV=q5?%?pCK4mE+bBik<NBXkPFlNXadeTiK64k8Q\+mQQ>AI+capFXtmmK
DE:PD# ^JX$B8FamwHKwkCa@n\IQEiJ/uwW>Q^B%&tcbPkPZZ1<tE5/$Pk<1PwTK#PluWdQw^yD6\mj&<pIyTSJ
^a=n>a tL9FqI>u5JT55<*AtXJRuF$4P86tCWc$yNDIjDA+W!qRpkBPLZMB^y6mBlTy#BLemq^yE%PI1mPK4CFG
D51\T! phj>PG19/cDB*dy=9W<#ip4w4Mmju&Ke&9t4y:TlCW=nYjEEE+l#Gcj<FIHD&@M+whM@bM9nhM=&B8E?
JhRFP$ %Y#bt/qMSS!4Eju4y*VwXQL$KljWY1K/IZ%/ViD%W#KWR#KDFCCNPN9#e>:=6uy/^yqAcmeWK$9%$#c1
H9Vbt* XW*Ht?8WwwlXwp/N/aRTYC/8JGdXMEPLnlJSGJ/FbwHXbTKZKEVHIBkW\p$TISMcKDa:J%LS&PuJVCyF
+kYat+ %\1Nhwm/djEyPkID@wSQpuTtt!SI$wHcDbLTcpETTl5K%iyk6VyhJK<#ymjutFWPEiA+S/*+?bwnPk?:
6&AP4A c&mJkmVTL6#CbHtnw&kdNb5iq=^wKWA\EHAw%ayYmQJFmNNM@uJRBFuDXlWhY<5AbW%YWQlyT/qEKSSH
M88BW5 W$LeCcy5mp8u8!8a%Y+K5=$a6>=SpGuQ%P9$Cu+iln&P$/V8HD<t\8b1NFN\tAbV:>PBcYGH91Zd6G:D
%H6uX= /pYbKwp=I$e==^Xji#h?@$M<NE%Yb%\4a:SC5bN\CGABy\NMiFJD!P^%ln8DKFXMKV&5\EK!1&\&1L$m
8N:!FG =9#L*\ET&$6Q9RXF$8ykNJVMWcPCjk/E%9NX*b&y=F^lAhBEakkG*GEF^iY?>Pnt8A>iqnW>t1a?EqXJ
J%?RH# Mj&Z116/a1qSY#GE&qdbdqF:N?p*N!?KM+i=ID:Q^PqXaI/dH!JecuA*TdI:qMH$\!X:1?wF<ZtX:VEK
\A?K\e M#m9%6%m:M\F4##&hbpZ1?^?qNyd1::BGd<dmjl#/+<>B^Qb5/8<Ctc:>j%Fth6BR!<C+^/w?91uyY?Q
TeEK*? yn89Vujl+6\TLJ?A8E6+&&XlL<9MC@+etHd=timW9A=ji%qt@cnkF4w+<W9JQMG4u&k8kZpQ!hYuw#kH
6:^BCc inV4#CXG#T\D%6+Mdpi=&VhG^m&T4LpL*m%d1J5Y8^k#@tYw8cY&9h5l8?/Dje8Q6liTjk+dw*WSkF&C
kRShm4 ?=Jd&cdQeHi:<MmTDFB/%4*+<e^>+JdkjyVdjcB1@lWR@jK$KF<C?^ma!@BuK@nZib4uJ><?y@V\QbBu
\QnXaw pqk#bbbA*\ZtDXF8>+Ll?td@qBYc:hXe9BP\N!SqHG*GRcd:DBa&YWlbYmm=&heG:9Btt%bX9M>piRdb
1*8Q&p E8!9\j9E9?tB@F6QQ/kSH\/a9hFFW=JDl?:<V*9jq6&wpnZ6N^/<ZJc+nIn^MBuG\+kk8TZJknj>P&Iu
GqMhYl mETT:cy#?uV@@dZZ1k5GIbK<:5naERD%5IdCHnWC<=5QuuHRHR?\#D\i<M!j<N@t4t%qkh+baHcHA%qb
pha4Vt h1WeVE@Q6N8b+MAnkI6yK=a!cqbFS>\\IHBpJq@Xay9@jlD6B>*^AJe>wd!h!HCQB@Nk<5<5pXc?!ML4
TCIE?/ 4^:IA4*?>b/bZqcu$5RM$VJt*M>Mjb&Sa5b%<?8Dbn@A8lWyt#9@dV5k@&$+<6?R=5uLEQ9YbYVmB5G*
^K:wT> H4R<8B$Quy$^V!/V?DSLtqY/ytW!K^pP&K>ReLBu>G>@iKA9u5tu+?PB*eBTQjBuEKcXEmaDuuNjHWR@
Ze9a#6 8e#JY#PL!bT=IX>wqVpDF4PW>HLJtNj&\\M?cNueYY/9D#RSYJHkXy1HNH5y@9PD=iWbPdDBbhRaKI1m
GHMa<@ J5JSN5yApXCMwEZV6p$VcXdchnCQ+bun\XaL>1EYZl?A:&#\A@AKkjT4A@8VM=kbVBJL<=QSkj^E$JMA
J#>w%G ^5$KbWp*d/Q^l\jkI:HLPPWY@iTAPj*aH&HQjZykV&j5F&hG:6t$5<N+ZSuwTWn>Fc*XjRabmBhA/p<Q
uBlm=Y ?9Mb^MR#$a\b6VAVF=!QB:euB>Na=l>^yVW*ni*%9d+j=B@dkeXqQBn>b?/Zqhh*9RH/jb>?%FFEME!m
-A48i\ 000dd8a105700110334 Page 225 of binaries2.zip
QYq\pK j@tYJTQ5ADBNJtEpq\M+k91HHJS/5I#AVLe#@nKMI^G&C*V:W\:Y?uARuNpPyAQHq@i<Sd+tl4*+?yq=
uTYC>X DF<PL8@Z?<Hui&:I%>W#PNk8?$#dpaM1Xnm@*1@bNY<G1d$q!iMmi<<YN:dy=!XQ$9\T>*KR@d1tmZS<
J4m/k5 H8BMtq&9i9ALB#!D9e94XYb?MPXpZpn!QL6i5GYyb?SuP:lee#*ndEe5VQEhY@Z6$mqBT<>+JluPLD&+
cww\k9 9Q+MW+5b$a>hZ>/9e$DLi8J*Q5e=Np5jnd^b*=hqn*+lB$lX^\uiVH>\kE>H@pBPMb?hn<SuK+EX<wDa
$J<:d/ Zc<$!:H#H?KVA?Z1T<CBI:mVA%ehTEc>!dVY!W&AIe4hSm^CQCqab9!1m@l=jGcT1any9bQhp>Dh^ku#
j?$ERX jE589cN?8PpNyFhlA&jtB?S:^119=l8!t8ZY+LJl@=ZQF9Za/Ntinb@*#!dq1DTqX#=VXdw4n1Vm^t<V
W#6>i/ wT*JAl?VB=MiI&\Ye>5aKF8cINN<=Knc%$ph?$<=Y&aj1SJ9y&pD>P!i+?^VuCjZNYk++AwAT&58YRuR
AhAeaN pyBd@8F#ikG=JVElN:e>G#?n#*dSdCL@dN6u=n:tb:S4iCmM*#1/Vh:mDIXBZmAcI<Kq#kEZY$4kw=1:
MhREqQ uFNw^b/JbY/utl\lN@Apb1?&ej+iN\i**n+#K1GY?N9<%Yi&5Q\i>&E&Q&kAuZC%W@ccpl/t48@5e+bm
!HmKVB TA+/JuP:q=DdjIIM:tnIF=<=kH/Q1JV:LXTKNMkjWQ4C9NAVSQWC&D4DW+jQ&PNuhk4Tj&F=ZpJl:w!!
9m4PVm HjTdAt^mQGZSQ$Z>$JZ5V!E*i##ln1W+9P*6%SMbQ\1i8Xe56VQL:NtLC^E*bq5?p$!#ZwuuPVj%Ni!y
uXbq5k Ct!:lJ8PuX5y6SAiEZtCdd8Zd@jq%%q1Ep\E1JRTyitN>tG#SBaq!nQ/QeK4*uKDM9Yq:PIA</b$WnVL
4WPq1k <DAp!a8X8BB@j9!hmENAbl>GZ#!bDpH968E:AWF41c<=6mnHL@Pn::*CDlTk5KNMq9JRFVutMuMPhyI9
HK8wJN +e\tS#ylyGqG:buVC>tS4B@ZpISTDQn=*paRc=K/1dpFhZyXCMa##uujXMpG%VMyEBF>p/hqB$:LVbc4
!+\DpI ?Yh14QIw>A\VCTJ5R4jV/W8q9B%@l9Gu=REnw!/KXTKkSihhk*l8PY>wab>%1etA5q?T/J*j/wHG&k1/
*1iTt! mc\E*m=GtkG&P/M%nw5Y1m9Wid4KGZAuyIZI\mk/NRybHPi!:p&9wJW<&+F/Xn@#pu?pVj#?qm=?GRAT
W?cAiE ^*CE?j*@$GV8&!SQN:ieXEpqj!m&S^S1G6a$V?8TEA:YdR9TP8hiFleTPtbyZLKFVDQXe$/XQZDh8%Cl
mY!^SV /aGq?Z!9+8dKyBl9a$GSN1VtLiCaSL+yH\j<cV=wuh1u<y5Acp!y/VJw9P&/SL&<H>\QLCyq9WRA?5%T
K8p4PS ha6b&\n1d*Y9GmduJBC\MdC*jJ95/!<>>S>F!FTpnSJHyquL:6+%:SSPaX?@u4t6%<ZE/Gii>VWm:K8+
5RZcXn kq\JR4aq6/1^$h5W:eA#1a4=?K<b@BjJ9=$5<#1I@E^*j8\?Xy^Haa=9B!$*l8>S8=ju>iB@8LZhN&C^
1HTw6C mJd/4y9T%DKknMRXq+w!RqaSXAqpP&MtBl#qWDYb^I%A5k^JtcPTH4lewdnB#WjmN!+j1lJMYc6=X8NC
j>81dm XP$<^AemdWkuL?6/bj5IN@^Qw%nZNpZV11Ap*kCd1NPpJSqN&44wdtP@4tl1%b4Hua^9Byn:Y1ikJc$G
Y*@<AD ?>/XTi6IN=1\J?@<L5&k/ZNTQ+PQ^IhlI6@5Cm4A#HT/wW$9TB?j^qMDai1u#^Ph1?L#5>d&nthdQ6/8
CAFL9D 9d/*eDL1Xkq=%p=b9J:N\KT+YX/dXA<G\5qeLk%mZRq41/4+JReqm4TMqAPVnlbSYEluc&$HiKNL?yqm
=NNi:D jB&qHYaM!:Pmh<!:pk1P9P:S1Q\MKX!\#S5w6ppEthT6DAk6CA^A$?4M/*Gh=1I\Md61Wl*Jd%KlVh6w
q/:ei? 86qGb\WybAJRQ$4QB^QSIu>\chb&Ah&QIblEkeSA!I\wVKGMnm41!$ccd^>XQwQQJ?SC>R4=jP$?9Y@h
yBnM$F &e8*GWc%WK>1?^LWcKcCecHwum^DHLRi6V^?lGiXVtAdS\9p>4lZ\CV*Bam&W:1NW%BWS511dcP8=IiR
p!c#*K >Yji*tI<KRa:iaMDpyVuwQ>5AYG:Bc6DeWu&61PJt^lCwPWGYVaAGHK#8I%R1<PtQ@yMDMen6Hyu>4*I
CB&*9# peQG&J^SCiqE+QQNGEB:=9!BVn6k$FdS$%d#u>u%kWCTK$WAjQVy!pRc=R$MT9NC>9La4lSQR@KBJj^H
V/>:na HR\HMlLjL9NTS<?jpc?LyjeW>d4QQ$>ZA^mSi8QSdiyQXk6ZkeF/=+a/eDKFk9G59Pedbhb8nt8NRZX8
1EM5$8 h?/Kd1k4ic#R6/M\h+AE6<nRbHynS>Y%tdlqJYPwS<N>lmdXVPcS\Bk\9Qu%twImHXt!EEIJNj*<b4DP
KC*u&4 HkwdPSK\K^\+wQ!!:ltGC5?muP5kQ<Q1I!S<<cw\5=D%l\+#tP89I1Iw56!$8X+LudTP1cDuB*WX5VSb
$Bw8+< &d^iyZFaV&JNStXVN4X=HDbaH9pKhLAqKtTNm\aFWXJdpte4L!51q=CHAuT>/=qHjFw55HC>yp@:DPXN
KjRRZ5 uQ&w&Hbi:l@X6X<9P/X^M/c\i&6=Ew^y\ADMeln$kIlqX+GGYLFy!q*P$THV5cjuk6X*udWV^i!iQ91E
$!8I5M 8jYDZM=A8e??TJ=$<$Gw!iNP=AXP&+Qbb\*/SB+:LpFDqdhkYu#%#D?MuMLE$8hI!#/aML*$eHB+5Gi4
tYB@V1 \B<?\p@n<B>i=d/@6Z8N>Q\++Q#LYc1HldN#@@/e%@?&<6nS@6WZ+u/D4@bQ=KQ?d8YFWe:lld!t<@$h
W1^^/H &he@8wN>bb?k?\Ln<%P:\\EZ=b5ak5>CjIZ>&4>YFt96N$ZmRpb**5jVDDDhBi&i9J\h=QbWAN$ZelWY
cWGGNE /@*\CCE1hhpi#TyikZC9l6D6Bq@>/Qb$/6e^YPl#I$TuVeddt>AJy#JQR*V*FWHAGJDFjb\q18I!Qyty
Q%C4t> d<<w+D6t>jYdy$Ie99VLa1M<ZSPZYl+5Rq59&WT&j^@J/qpCiNTcLpPB9IJIW^RFN<EC15dN65W!#\9V
b*l+TB C5@LQIui++aJq$?KM**dpEkT1*GD&Z=VQ$XC!h@J1!*yln@F6T>JETQ^ApIklDMGmX&qW@YNlM81+HQp
mJK8w1 we!!YK\khw:*E&IPV8LY8Im#86@DJLjDnl5G>\WWJKFqueb%tnNd=P9/wRAdyYjpW*Gip8QlpJ>Dl\c$
w*Va\W ?d+yTApBM^F5J=DFP89Z!ujcDw@YZ^@FeKwjB+^kKe8&cSaZRGFc9$Dk\J%/GHL*@:RJ5tZeE1j6q?PB
LI<>P& <?L?\Pdt14u?!6P$BliHP=pn>/QB@Wy@=ZH?m*\^k14Z1<@WP+\HY65^=Kin<CZ&SwL!PG8Rd>iHJd&N
>Wi$Z9 c&!Y6Y:u&?PW!J$C9REp%bc^cw5%?4w<6qV=dMTc!l$AEtS>Ml5%!eEKK/A&V^DGnkN!C96B6&X<AIZl
<EeyN@ RwLINI$pVwi&%9GuLZ8J+#6RFW^:TIC\WNC1na!Kyi4$EM=CKN5j!L6/k/XyDKlqdj9XTkXm%4$?#6\*
NWq/Nk 8H!b!ERnaWD#hRklRu%Lc*IcJL1NaW<^lSLiECy1^q5WJ<6<Kp?:6GWFIe5I&KD$M+YIubY+6&+Z\4jE
@bpQ>Q BmipNI@\6&D>XFFF:RBnKkB4$te45*+Vqt^6FPaHQaJd\k1&L!m:B\nRy/%+Qln$5/T>EZDF==E%^$AN
&>kY$V &EQpqnVy#+NRc$y=\$lV1w^l/J5lm^=yp5!JqPdW?%hAJV:$TI/&Kap%dwVL^@4?X6ld6/:j>B?VkE5k
S*<EZB IZWuudL9w+:pEWT+YS$uqK4ESkc5A^y!^KV=%b<^+LQ^QJ?&haap9n8i/H^:K<tHHRAFESc45*wbjIN9
WN9T4j Fi?6d4yDiXP^P4+ynH^+X<$cXiX1F8pLLM<LZFq8F%Zy&<iC&tcPZG%ccFQhNIh>nmCbmwcW!Nmh$uKB
DZII4J au@T*6yl+#u59EHyQ%p8:*<an81%<y?!ZE!^Lw5Mp&$QKM/aJqEVthGb1X!ZCNbFIG%nb/qI+*IK?k</
*6%F<\ #6KcFTNli!dLl*G>LL>ctm!RK*Z=qeZatCT5XSEbpY8kq+1jGDVCTQNecZm\AaYi=TM65w?kh/tV^Q+Y
hiwN$< AcZ%>Ye1L/8J?JW!5TF:qHA/^hH\mQNaaycJbXnT:ck>pIaGYZQ>1H8kX%?9i*hK!J=XSqda4BwDA@w^
Ci@8b* HB:eLdw=wCZaYmKA%%AH:FA@#II$FTB=i\91S?aNYYhMXXuZC^ZBwmdL>y*X\*4HiRHhe%8cq!TVqt?Z
cFZ>D5 Pq+&u/\Zt/V*k5yWnbHTShy&IMI^tm!Pwn*4C@<PJ4<TaL*tb6ntW<@LtWenR$YPXaCtpE5L\XwIeHQc
8mGShp qE*CDHL8FGi1BuhM<*nM9np5MQwmZq9Xw%QPKqIE88hw*:=YunjJ#WpJTXqP?\>?w*IC+MCVJLKEkNDk
\P<M?u GwZ%M*H$J?QNHWVcIpe5QM:nbWILby=4@G^dJTS4Bjk1$tF#cCc/pTt9ee!^!u$bJuq:C?jS8LFHD8MG
!1T$e5 ti*=S:N9G4QVFR=&/9Vb5I^t^9%$Etudp%H%*Z&^:jYCD@H$Bn?I:?+4J:@Gh/<aXH9=DlajW=Aui8Bp
Jjh/eQ WjLcEZjhi<^9lZe1c4nj+Me5pGDWiF4%&9L+n:XjB?^H&<lA98&5<9c#?QS?k/BbQmuaD^Ywu6dQD#ER
pDZBlH =:/uA9\e/DnW#?QR@SYI<ZhlTD@@n6>>qQ@K<4!ck9/%Jjy/aj#a1u:Wnl?aa@jjQFnF9JS5?$u#Q^Jk
8?Ap6S Vu51=>HJntec+a?4KuAT%Y&ibYXeeQa:PG%D&Fhiy6>WmD$/qt:dTYH#&#b\RnV9=dbP<HN*E9WPQt+w
H\i$FV m@##YpVuAXa*Z9bNm:9y\uS$a#lSh8:E$ENC/i=qP84#HZN$@db/8\^*6ElZ6@P\/G:&q%5LkbQwSuGl
KPi6Vm GQ^hGp:uH5h%1WJtZnSaMdina&t+WcYYy>!H&umF<<uL%B=!VneNQRqHMwt9V8mKlHP^Bq^j$6iPV1Ip
PEHukY L6b4lN@NYPZ6!b?8KlGnJGy=mqDN!H1JIhnSyJV^/WdGylHX1H>JcFe$bVWB1&84\LEWAl<FWp/NIq+#
j8DQCt 1Wa5c+C8kPG&1tV\X\D:$WtWnkqbLL@Ae*et8?SyWmMbCab<q/cX!Iy4batKp&K6M?#J1yhyR5hTyTqe
SCd#lb C?:6Tq!byQ&6V%MEG5*HY!#L<Qn6w^pC^%IIkq@mI5:#y9J$i>MPD>H8TC#clBZ$YLDATbRan4!/GA+K
>*J*l< %FWDJSBa/c$4E8N8ipet=yXAG^iKd6%NTmp!FX>4JnM\QG*HJe9kbVyL#FNJbQ:kbR11B%KaIn!BL<@K
mTa!d+ G\V$AW9IVEQNnY:>bMALuERHVckCLlQ=<uS1e?i19wP:H9C8GY>NYnX=9JM*KXZ?G%XkG6M!!$GmDaqJ
5NYMu& !4WthA1mWTHlM:Ci\LF$>N@nin%EqLL8a9**?yG!:Tw!18###Kk4eBI>@q<l^BX!XADtKdJYb$\#a9wh
iqM+=D &G=ktRbiy1RQqqFWkplIYk+!1$HN\ZkTJi>JyCq1B<hTmwlV\G*!YSepW#+4V>pw5ae%w@5AD$9Q@8Ap
&u?4HS 1uc5/DpTqqwt8kK&GVS$#6KCJ6hpkTD>DwHBhHA5uYkMLCH$$IL5AcT%d:KmS+HH\bpwjW5nMJ5D^%J8
*a!?mp @c5muT1pX%TyP!SmnuecX8ddcNjKd\eh^p:>^>!hSK8%AH#IHN$dWq1c%E\*$5NyZ*8LHCm6W\V>wDtC
-AtqY% 00044383bc700110334 Page 226 of binaries2.zip
iLmTQR @5?pJ1YSN!tNPn!wY!Ckla\q%/d4PJbTiLqm^hTNB5^c6N/^XAdADnKBdcSm+>IX<?a^5bRHVS/Vlam^
6P1jT$ P+tV:A4B\XN:m#>&J%Gj\BiqH#EE=G^W9%?M9LBwaDiV+cBPcM<<AIAjK>B%R<jT1IDC%hVY<8d:wwnR
/=qm!n :^!6Dc5t4\jVFXD?D:^MEaiZp!9nY9Yn\IJFZW@liIC%A9lRZub@LJQWnMR*RtkeDPYm1SQeneqShXPA
PPyFG! 5C#99::Aq^FJ@SGG4c!G5Tpk?NHp:>hWBVJyWtw&L>Qm%%8&VFWB$T\/qaJQC8jT4ul@1/8wm6?94XW9
Y+eVpY W:N=tey+ueZ=^^W=YhKH=E$<:#@n9j>5RpEQm/!1n<clVhSJ%M?N:WA&yl4aTG5GMpR#%Nn$EZn&!AJ4
aP5w9A pM:u:W6*@y5Z&lwlyDXWELq!cyXR1cmYiyXC>\6#4p<4uJRq*T9$/ct:EAELhyNI^%b?%*laa#*p$>!$
mBqiWj j>#ZP<!uWEhV4+ClJ???CyNB@:pbR=\MRJ!58a\c^l8X*anpq>Lu8DyTnbhd6K>*=DjaRRE\1a8eG@WQ
PyI@Hu 8F:T?Yi*KAnt$:p:#Ki?MNa?RaV8eAS=jF6P!kbJcWKjQ<Nq&WnT*$mCqK//jiLK8B>=b6#p4>naQ@^u
ySm/KW Y/ud\/j<4*\tQwZMk9Wd?c61pnJ?k\pe+InAPe%9m+<Q=yRll9N:=B**beBE*j+J<Pp$V!i$hX418J!?
V^u:dp Y&CjA#Z*M5Q4ye4&*$^Qeh/h!Pta66E!PhE>A^*@yuD=Z$qS8YhX?ybk6%@@j&p$ie@65/Gt$@Rj\Ad/
+ka=Pj I<4RKTH\H+Ny@m1M</4%@6qa<:@!@EtB9l8R:L<T\D^L9u$lj#khDXBjcLVh*6:MHQ1u89Nq51mRm/a:
=ik*X! Wl@8c:m#J<VpVtniX^QI\e9$qIY5HQkRhA><wAQHW5Jw&PC8FWI=KMMFEtuVSEh$cyHak:@1\&W&iCb4
iVtMHd R=BLYZ98&WC=Y=:/QbDhJGEp4Y4VNiAJ??laitk>mA6phR:V!8pwDShilw9TdN?jC>C/KWR$D<!++G=Y
WbHES\ $dVH9b!DGc4dZA%8dnNJwC#4ZaYC%:uR5jS8=/D*8$ZSRICCEC@%Z\ucHd^Majt$m^q+\!J9=um<#P9L
+kRA9+ ihn9iDjKYPm#uYtDS!>VeIYm51ldn<!NT=EA^+Ji6$VWNdZj1Ny>h!#%Mt<F<=4>c4?CJAN!^&wVkSwn
wFJ/uq 9\tF*jkwpawLnWyI/hhm:ejkM9q9PWma*XX!#++ySunPA4RT%^tJ&^/*k\M#%KnJ4%pmVaGSHmLQ&nSy
nlJkSj &uT$dM#pqEj6Dq/t#m:J=#WlT</niWtm*thL>y:%a^?@Z$:Cd5nmhX/R*E=6qyY*Y*9>mKXHHT<44^>N
N:jAXF Xe1>?nk*qdt?y*K*>Q*KJKj5YynmCm&PMLk:iypCGI\SmbQ*X1qJ1RVc<M>k<K$\ZiBaPt:Kdtmm6/lP
>=DCM/ q66e9PjA*/k&^lVFdk+W&>k59h1/SSybPe>6Ldh$weydKY%B\1/S$IQWIBlS=h1VAIHH$ReN=1uA!@VY
LRBFni wiFHEXC<\jW46cmI\WC/D1%%ma91FnmYc5#q!#MR<6ui^Lp<8&LdH5P^QGNyK65tDRDTWPZ6XB/IkGq=
#u8uhX EBZhbpCW^k^lZBMat*w$VuNcNVXL9W^*tG+Fwlp+qyK1FGHntb<DEna1<kQc+aB*8eJ:+PBamqF1L\<\
j94Sau THn+/T&Ppt>nK:&wZ=hB\Th/^XwR!XR%H/aQ&\Q9hJLR&NTneWRZA!>Vjp=P\EFmhpe9W&CR<Aua!lNN
^5jqt: M*Zu^1%?9Fd@$dEW5kDVbqEI*PZ6Vb4^NI\8nE?NnDmL/Rhyccw6b#&ZMnS>RHje@HWCL>MwK8LF9d%B
DeqjRd 8H?pXlkG/\Z!qQK1ILHhJuX*&^%L<R*R$&yqjPSkY<FM\C96*#\+e?5*d+nh5XTqlmm@mQwBqSLy<4jJ
=5VDK? BumX/%66d^Fc@5#&=5yG14=cwTlQu<P%&t$ImXIjLW>qQQnIwmlc/1bVwZ9p^<LLqDBhSN^9CL%MLhRD
wNbIKb =D$!pS/MH^qQ%w?L\dT!yBm=qln+*NG?%I%XNA!L6^5ayX#VpmTLhYF=lmbi^4+\A=\^kJlq9d^S\Hl+
FQQ&9u uPYGY>e>>#:mT#F5LmjiDFWGYAlkbZGS=Ayb!/t<MVWBPGpWiXL+cabiywX/te=nt*%e5k#=8EV#$uy6
#G#APm pt5K/T=?y1d1jPlq&ljT^m@!d1VStAp?DWQ<>q=$94%=@KDN*!?^>NMpke>Ked&pNaVW1SDaJ>h+4jpE
naH!8< kLZcXFFW6*8ben?1N&$pub*I*Cbu*\NuR!#j!FX5P!1P9/WuIqY^NtZb1\XS6eb4=Tw\W19YLE9DlEZ4
4ZCAaH 9W^>?l#l6==y!JQm?1+Cj8i<BKVYV^W6My5MpAcR4$jCIV$YXLT?MuEYG%14iw4@=CuZ$Y$D++\$/i=t
G?dI<@ IE%yR!>VynHP^1B6#Qe#aK@i=FPqW>eQn?aBnb8hAeD6DCF99%:c!Q=PiuVpX$lA6yeSjMkd>?48q5G/
#*:hdw wcu5QH6GDd$GC*%uyi8$5iw9V6MByLPKSp/dI!\B8G$>m9Y5LD!WYH$@\/&Qww&k68<<D1AkG&H8$VkF
tnI#aE #$aP#N!<5KSAS+%tkiA!IQZDkM>YWuNt*%@\&TB8&uG?db?Y5q>8E\mTBVKS>SQKb9LLP1w>:V%i&Fh/
nS=<>a 681dDPNBAN1SyNtpPW*4>aSQSal15E&hy^CNp*HG:^ZAF<HI&KLGyy8HAC/VZm?>WR$k6y96ePB>i@*P
e^\\ae ^D!aen=Cc$#Fj=&$=/cKF+SuhBh+WS48<RSl:49tEJQR8TjQ*Fd8^RNB>Dn+>l$E\5hAq<4>RG4@cWmM
#J&jj8 49RXQ1SR>DMGN#q<y+?/KD1Bb?:b8*LaXV4EpL<quVN>p\#$hiD@$kHXn8Nnn6hQ@XJQ1dDnH>m5@nuY
Cj1mXZ <J8@j<=V@bJ4=Q+?VPRjll4h>!npN^#V4$mw@#Zq<XtM+@S9@Zt8TQeCyB8QQ!H#W$j%LZu>V6q>8tHm
ViESpL j1>GZam5QZFbeM>S%d64!R5Jw8QQYR/QB6G1M^XR%nd?t*8Gcj=p<Ayk6Kh&A@c+CdwVJblZ$k*:d^?@
yP#P9Q y?1/CnJmqj^hBaSLyhIMdR:MI1^t6dYbk\^?Q%GjLW@Qi\MQmN1b=^qAk=nqpb>ZiV$h:=EPmlh6BS=L
X9@?=q qF!#NMNQtq&VuX:yEe&w@9k5FyuMkbF^DmT!B1JcaF>/J$^mPi46T?%$6ADjtHB1B?IS5>qV:S/<VHZt
a:ebA8 =J+eemFYL#?l&>w49Lt1FbpT!6<JKAhR#qZ>*KYH%qJB5I8TISLE9d$qaG%a$6Jk\hRDVkD@4ek$iAm5
C%:=qA TL%>/TbuIw8YcFEmydNh%CGjDw5jGJbKeDtW^N?PN$AYMjq9PLFlI=ZQkXJ/BXlTw\*+a9bF@&FwqBZM
&Q<m6: dEZIG1h66PdR&dFL?uFq@l95ECXa9byinW&QX1SVaFLK4/<95YwhDWZi8F6XIEG*1>@qQVt<44wK9W#:
AqJ6kB =JLHSb*tE6+j!5M%KRqwtuq$Kw@hy?FkjNNNjRW\cHucTm<yJZciQet6Wn=b%<T6qN:E!AM:YueGJ1Wp
YFh+eG T<b=#Y?>XjXHLP<n9b1J#1mGyDFVlX/t*5aKYX4qGQDjqG$%EIckMK<HVWcQ+Yn8/GuXKiWB@KLAu61Z
W9$II@ #y1#KiZyWRJAi/Sqi8yhCJ?FJ1YkB=9GpC@5/WN>m9!kYe*J1lYkXjBC<N1b@wjI>MCupI8w=NRZ!l1%
*4>y\q B#+FWB9wXW8e&y*LE/%N&R%$in&+uEywClttihDKyqckayDhnjAblcAtLe>8Wk1<1m$Z$kIJRNS>6hS^
QlHq+: P<\nhHQkXL^M5@YpQjW!^TQZha<$=!nAFphjQT4PhV\Bm%$TtycmPKZ1A5:I4>:yNWC!%L$$BV<TMiw5
qP!ipd MeycJ$y$&HE^P\Z&tE#q:CZWI=nct:XebB\^bYTXRyi1B%@kbWy^IZy\&MpF=bt<LaAT!a+uRJRESGDa
j@@A@S np:6DeB@SA=haF<KyDCu!nW$q<A+!>Jc:h5GP^NHw8e$aejIA?1cPV!w4l4eRW%6i8patwt&iky5+GXK
bH9Y\d :YljCVawn<eVN*:95V^wlWl!K@4=ZB=%E1ZV1:@i%\?kIuD/cDSyyi&AQaSy5#PqhW8#PF6KR#?cqALQ
DLb=k% yRptYwPWJ=LS5/A:4QW!&S$F5I>iyp4FBEWPR@V^5aM8E=SH#WMuVcwM!$NhjV1>q49qKd%MFYE&t<>1
mQhWPE 5$a*k>=SRdt5p!bT&k/ETib%S>/^hFnnbnTVRcXmbK^M&qR!+k^Mb$XY9p\=tkZen+6/taLS:ycEcEJa
Fuw?LY uw&eT6V^YB/iMDL!LA>TBLil>Q:P=SVaq:+=Ip^9u5tMQt/wXpd4D^P6@b8DX\LeTii*tTcqypLlDCFq
twYIi: M8>NXZd!*ZKF5Wa/D&%B=4e*<Ejj/GWK$&I#9JtFCthliYdTIytcHycHC8uI?Z/R9qC*RqutAK5^NCp%
YTFZ8? 6C@F$FdLe1CQITMdVY%T&MmSK+=6qRGb1TmhtyRcNTtF%l?&J41Xb\556>!EW>LY5%1Kb6kF+YX1nje!
Qej&D? :iSXnp=te9u/5FqlTDKXMlIjBww?9tB!Q>H@\bj<VNQLy/\B/GqL>X*CeTd:8CdblSukNL^Pm@n#q=Su
LS:\?@ pIXWqq@#VJbbA<%TF&>j&td9q/J!ZZH=TF5+N=HJuH*p4VZZ6*^^FSmyqq/t$mB4?YjnY&cjX+1n:h:N
Q^<Y=Y +::WIWMM@Li^*e1nMHXhQYm5pR&yQkcd5cpP1mNhDckWT^kQTiP\lIX!LHA?QXqNutJb$dEWJ=m!kFPX
uD%Npb *qaNHm^p+Tw:du^Lj^u+qyc*Y=VKPc4FVNIP+H!DML$6RN*RJlq6EhT%Z4/=imJcH^mkH6M/kilKBb56
lMJdaa y?YA>@4QkFR=pX6J?DjC64PJd6/hhJ+>:C84Jb:C**Ihe6yuJ1Z8t>&S<m$%#^YCt#G&cWu$*cyuIqAJ
CaPiue /:hh9&%d^#>Dq<ah%dZihQ:Jti&9@e#G!6#@iV#aw:*#*@h@H4PAja+86t?Gk#1tC@P+Z/u9uGDH<cV!
N*?=dQ e*D%@DII@VdmjuLVX+nIKVb@EhZ@XJjN@jcb9=%#8bNN@kCT@A@<eT<T!>*$9@L<F@\+h/KV*R?ja&/Q
/8Q<mc ictQEpcQ>*au\6yVq=L\WWJu%JBH=%:^*?+h:eHL%Aa?G69RF=^++qk/Bb!=MRT9Hw%N*YFZ\ackZ<l@
6hPb^Y P#*dajQNH8aX/wVyaB/CbJ+#6*<E*BBQ%D>Kbn+Y/FAcF*#tPdFN4:LuX^4iPmnw6Bt5?w&+DRHWjA/%
GT<bIK TaiY:NHa>E+?<@9B5qacpQp$Hpl8>8SqGmm$p^pHh69GiQPM6WhnW/j^94?d9*\P#FD>nj$Z?CN>y\mi
4JY#DW S+p5tXPMADZNpW5K%@cD5TtaGnRmXTq4by^qpA?bpTP>RwthPRbH?>IJMB5%qK!KAe61MK*dd1KWDlq4
E:CeHB hSMT&+B?>RXp#FAkku/IApDLCM^Ri*LhpMe1S@kcE4%mYYI#FTDJ%R%56t&TN1XJ5GIK9E^6CSG^k8:9
X4bb:Y M:%M5:W5L4pbP>lR%ZXK>l5eT!?da!qEm*?qaQhwXq!S%YXbR?BF?Y>VD:P#KiT@qYqiLKdGK6ncQ9:+
6JQC5E dAbkeuH9#XA%NdZN*!:kMnS\9yT9?enMPJy465\IHakAIu^A^LKMNkL^+iSq1yAW<C>EY9T&AMAn5a\m
$EMTmu e*bFZBEct/1K?M&nihRJ<!qJ$:KTeRPWK5Dj8l1w++&kLkAII@<PE4:P@6c#P1PP=C@h>Kqtb5dP>QEn
SD!%:V cpkEEByS$BI*/eeFWIhV!%N9l5wukDITT^i6>DKXbneM8Ci+dBLV66QJ&JVwJLj1Fe&dAT&$!M5pk\:!
-A1uNW 00038a3c72200110334 Page 227 of binaries2.zip
GWy9C/ +F6=9LEy+@Yd^%Ntqau9/*WE5cP:a$eY*Kyw1aAFYH\uqPZnG4/??n$PiAjWuWwV=+uy<hSHL%M\w4b5
$Ja#jH ^+1Bwkyl#!14CBB/IYH5cF</S&Cu&Wm/qkTycEJhY?VZImK@Tl/NhSX+tVKT*<5D6cW1c8IFchWku@FX
S?ydJS TB!MZN?wpIbHk>RI#!T@N8$!<H8IGlb46^lV\t>$/cVewdHySF/jBNaTFN8Dq/qXCcS=i+dR9uShI?t#
G^AKA@ \B4ltSJJeI=$<Il*/%^Ht\dwj8*E6mN?l!yb+%m/AQZ>QYkEmjABJmX>I*eC#$!?yl$1$=S>Y\+Bcqmm
15Cc^m PG%S+=Hc$PZWLRp1K@A!JXMG!j=:iWL:W8p#EB?pky&Q>1%t=PF8ibJ@154/IdGWbpEdNpAl>p?QC?!A
qAC11q AVk+ECE4<jJdcPAnC^t9t:t9S>SRY9HRFi@9<dKkKAiZ$^6^nK15\Rjj9W^B@9MTXTmQV&Lj9W^BPm%q
1Ywe<u cNd/wec?R8c<&>LlL?$@8&My+$jj>cXA%hLRQjWA/HB$\jSl!1W9AZpBN!5lLTch$m4+/XHDCmA%$PCi
Z<NJtE k9<HL%M!IpGXw4u1:tW1Fe&&#@:DV4W:q5JXAGJnEh:qWtFEAkbhRStB*EmR:9BiA5hT/6E:idJGPZQT
@PWq/K Jb1EyD?hld#9+MnBDJV4Bnch4e^i:Tk91V&lly:eN<maJ#P@8j8jp4yqyT:bl1t^<Gbw95J$VTpytJV!
MF!=b< XtAp<Gb&L>M&tw&/RBJ5pwFwnh6nmnQ\6Nu5^1ca1^^&PeHVSA=nPW%?W<N4NpIdcyw:KTXA!kThG!a&
ty?w8T tCZ\IAF1TN=kVPtJaR/MVSX@e#&TCt@K5bT1V1S4RMSCcw6<8y5*NuX1dEw$dwAMlapmwHqT5DKFJ>SA
Hj@I&M S9>IVC?$L+XT%#k59A6RyD1Klyy:LQ:YZLiNda4h6dG=b1%%ETAk!$&qkX^Rh!N1iPPPVbEqBN4ybj1S
:Ka@ZB i>#j+&?\WuB*L>N<wY^ju54mB#^GPybtTZ1FqICL/56uu1d=JX<Hn>p%eSa9Mluqd>p!L6qdZqy9dK4&
I%TbS* yjSFTK==jyFljT#V><<tYqI+VEH@<Xj8QSJp:bJ!m!S>#>8w?Hm9K=m@9Ki6S\%nwwb1:nj:NAndRZFS
dk>hDA q<$l@5bWcP>qP6DlqDaN5u=V?>KFZ1cK=mp!^%!X1EtKlS#NcwjyKw@JihnQV9jDkbhFXchkuh=cIS:=
<Mw16V j$hNM9\HchQI6TdPF/CGC965yy:VaZu5b9IkN>La$e9$y6=C^LZA<FI^kj&WDCley\iauh#bdCkeib$S
yIJ#IM 5Dy9PnAd6Z^uy4Tb=+%eih9#Y*a#Qq*</>LedW9$WA#8pKl$JGmhaLGDq?tBZHLen4WlMnh=?8cid#*i
DVG+Hw NauG<:%DPM>Dh<h468?#>%V1A?*!nlw?Ic?<kM*eTcZNjb?$=##wb*<HNHNja&#Qwd6^HH?dZQauc9*@
kaANIi FCd#j^d:?h@Qj^aeieLTZmwJuM:<mA#uZ1cLll+Wj+*5/A+:D\H$>Ml!i&Wm??AX<*#e&kilB&n>\DaL
$^^N9u ZJN@k>F+?G@k:^\W=\+Anki/j\ke1q:HHSAMjIKQRu6ie6RL%l*9NZqhWySt:Jh8?8$T*eq$*CdTh+J=
$uX?y$ P+4<yD5he$qqK8c?&n+H:%P*8k68b+:ilaE/?JdATyDMnSZE9JpR4I&Fe5/cWdXul^#!t/%>RuMNY9?t
!+Vc%E Ye!NWT^?cHaY=IX/AA=Rkh^S+m!tu#wC9iQTFAWq$4GidiJa:Rw5*R98B:LCwk<>5e!S*+QNV$nwy+&m
Gh/qHa Yp1u1MHJ<4b\ndjke<h>6E*P<iCAQP*GYLM1XFFcBClJZKl*i+CL*c4m+#M8EyWR1ywWWRX#q!FKKG6!
5\k51L mBICHJFq/61pKe^lk:5F@AEt5BbG@mBYqGW4FKKHVhm6@@Z&m>b&w\Rkbbc*<<*9\&5&>e&F5LJXGFqL
EKTGK! lJ*9>kQm/>NAHYl5\Si%q/@ieVE/9K5jBPLm1yMYE9E!yW&Pbatp!8DMVTZ\^+abdb6B8/4YtWKiW8=t
^\*Ec+ \CCTT/6C#Zi6JkeT*YVlPka@K6CMZF5+h9bnpPw?W9q1Hu#QJeqF$%Dw$\j$E$!qkNk&in&:5i@6VC:5
W>@V6! 6ME<Xh5$<14J9y#Wup9#*GaRBtdplT:nLcBAAGtyXLeRY>6DSe:LSqi=#\6&M+^&86=$TNlFLHAH5@Gh
MMDtnu jaG$ba4+:T4QLCq>Tb!mTjM^+XPXq>dN:qNi*YBu4/Y?TCP5p%?ZkqLReHTiBnkWK?1Eb58pKp1eid5c
>I:ATZ /Jk65=w^*6AupHwFS?C#l1SGAZ=\kThluhdWu?+lI+4?DAX8lNYZFIH#yM!4qw*Fk%ad@LZlLmy/ldwj
1=5EWT G5V?T6BA%nm=kmApIe4X@CyWpD#AQVp#mm\%&B\bK/T&8XFJi\=@#Vht9AHV>&mWnEP6etmDA#CZ<hSw
cWtZy^ G=b<NYmp\SmBP^hLKmE^P^n/i1JS6ch:8Z6=hpEmqRJe<Z/>8!85XN%5d$^CBQupSpbm8WApHwSA=u#*
CHWjkD *byRK5##<V\Kl#j/RZ$@W5jp+jKM>GPMB=i*m^<QDkjRe59/&<*Tij8+iaKWMmT#b8<^Mw*GmRu@GPE&
qe?=5$ CQJRQ?5tq$/NVCaB<!XY#iZKtWHB5pmhKthZ^lL<y/\F+J>FDFwQiW?n+wdA&VA$%DIXWPaAJmYq^Kh=
E<1qSj RX/!DIQyi^y6=hpQ<JBiwRDNH$:mk>1JK^%ebkdK9#61l*XN$!9p:itj#BPj:+JS#6q:Z4LY11wCVqBt
yP+/n$ LQ8!%a#iyXqL<HDRCwc!:d9I?!I/nyILKKe#S#==GZRZIwpT!B:kTPZmXMP$Kb#6B>l$p$yNFlL#VZ1=
J1?Zi\ bqq?kZ1tN4hjKaumGP?1EcIJ&CSA*:ZM4l/Am/HHiu>N8taTybP^C8QN9CY*k8eLLB^<TYlh>nhD8^Gk
*4$tu5 dIYb#M*d9ZMu5TL:YPuI+C#/aRNkEMmBe=B^ER+PI>&AE8qCI%qLlF4+/tC+m\GPe9wnDd5JR6@+BA:h
PnYHWd tYin1KiX8uiH4W\$1qk4>e4eHcPXec9AAK#qRYKy\mGk+$+SqiHt4q\G</abyNLuc9$iDB6T$YkZY9QV
#uiSDY !aV58FlFm=&ZYDy:5QqwT:1FP9<TY?B9WR$jD/\9a6MdyFXDiG@N44GjtabXJuPb%hum\i18wIk+K!qT
=KbbeJ Zq9PYW<iNE/L6hEqEm=MbFEDcVmbPLJE8p^K4J/:Y%FJw&P<^LXj!Bq>bm>&qK^CP+eKbaC:nM!Z<A8E
kYA#P@ ii=ViK6wFny\6j\nw=5D6Nh&Z%I5^a4<p=MtNC%Ne5&<cde85%LhWuC\qI?V&96u\RZt%^WZ18JIHTjI
Q#D@\I J1C=SQcScaa!/L&Z/<EC@K8+S4i@#<tXl\Ye5&wC5R*+t+W46*DlT?w6V&i5DT4hNwd6dh<j@E@huwS:
6ea9XZ +D\+VTcX>n\+h<\E<^:bm/=P5d6<8N5QT9TaLuu$+/RW#Tct=u$X:yuD9nj!^i\=1CTqS!=MjHL&pS@m
1lbKkk RWu*eMdcR>I&IMVI@VRTjid%GnLl:CECP@m>l%uEt=Dme:4YIckN&Zl*VQIBpS#8X@&>=K<9DB#e/&Q*
P8RLpa Gyh:uwd<wED@>!iZ@k>??:@^<<?I@@*InNX?=%*=B!*YljJ54:@:+V>@*C>iW8=ijiY*L?X\t@EI+d$G
n=VJt/ Bi@e9J>%+K?&DdaB>l6#t8jcj@a\X1puuFuGA&q6k@BWFi:yF/ldH%cV^H&G:^eHN=Z>te<bt1h1&SM1
Fww!:< u:@CiZ+&jhp81wbPu\JLKlXLH$MId=6M=!hcdL41k^#cQQ6F6**?<uikWtK:PFZ4\!e&QS6t6?jdQcqB
h!5uXQ LL4YeulRqYX&Wl?Sh&Yu1l5GCpnN8p8JqX=TpARA%+c&R64kieY%y=LP#Gyb&!QI>9VFI^1WNZH%iB&b
>kHhpk R5V5pBj1R<dHt%u5TeiIht?uFSQmPtTQ4iBe\HEl9*/1Wkq!EN%T!=JWqejnT%aWyMa>XI>Tt#RmXe<I
S6Ey:T @?Lh<$EN+ZGb=?WP^l*Le<j5nuqPV?1uXTdX8Z/Rjqn%$IYHciR%4^6bQEN=mbI8yBc5HbJui*pqX*QP
@4<FEy t!Kian$+e5\1>Wpa$&/wjJ6/<M5&\>E/NZb#T:9*aH9A:Qca@qu4bRh+pwWCT+EYCX+TKTJJ48#:CKcE
F@HJ%\ 1G?aauc$BRYQc:yFcXb8cZ48$N^R^=1KM=HZ5nh49^d*K<8lLbRJ\?Adqyy<unHec1dm8kcD^<T/L=h&
y&=1$L QndAl/Qm<yGu%+<4/A%hn/w1T>NKQ+SmP#S*M5SVFX&GM\yYlhQlPhH9iS8^>8bNjt>d?9:5@bmQiGI\
Fa&9^< EI@i*?K^B&&GP?Nt8EP#BY*lMPSd\IZVut*L?JyC/i$GEmeCZBZcG8B#ZJ1/wGLNabb=YS/<lLZ9/Dhn
*FYW$: Jjn!VBmI\l$:p^$1KB^WZViMy&FRMdQlMb1!h*!Jwq8k$WpM=td&H>L^mBMC8@4<mNq&cF?cW#qNEekm
9>w?e# N*cAGYi+m@//QQRFKY1t#RLI9iIHCtZlENAt%#^NM^4:B5Pkn516y+iE=dpDtqa>X41X8#HRKnTSBN*w
K$mERu ^LC*kIuBwAaM\&KM1XM\l>V5l9:W5J1kH/WZjH?b/$5nt9\6b51ehJi?dKTGyWYju1%np66CB5=y6J8W
aP6C^i 6QcaVEj%6KSRD\wIYJ1w8eaRW^lMKpMc:J+^yp9Q/eG5A$wNhqIhDe#J*@Vcdt/jDq5hqRM\Y%WAYl%G
QXHSnt kW^u:&?jeRtDYp9:X1lTu5ipkLh?1wdDBQ&5QJ&jI?J<nW\PNRNycTqaXJi</YB^mkHP%HXyCW6GK\%@
Wh:=9F B$/:MGL6\E*!$/FPt::VcZd5eTPFDM64Etjibie?9n%#IultWckmFu/CjqKiiC6Qq%!c94ppEFeAActM
wB?nVu XQPRM4Jbpu%t5lcSJkW#H#Ll%KMuVlQqPuE/9P4iqQ@T+n/jFq:p$AImw4@t8Bq+i\u<H\iu>\1cH56n
iLcyuJ $q4S+%6Xb$aG*=4qtXtihqGXZheu%<R5*TkN5Y+Metq>>4W<Y>JEc5!A9cue:$$h96S//=y=X5t=G#W5
A?^EI! bq?E4<\RZkW++:/Ci8lbE%talJ<l%DkPtM?eLmXy>:#y6nb?G&<\KwW+?jnBpW!*ahGXju^9Fd!B8&$Y
<^<XL< YTwcN+=XNh\>=*+dDHlhRei:1atb\qIYkFpE@6!ktm&$/XdnMy1h:KtkN6m<Q*wM$N!8l:KmI/Q/EC?E
aLTuc9 q4y@EQ4/mlnud/IyG6FP#=K!>8WDe&&5jREhubNEZ<TWj#X/%*eXDi=415YZ6JIkdi6:Z6!@n<*#SS^?
AdIm#u 4Ie@\6H8tpn@Cl4Td%@?qJ*$P@e=bS#?:bDV@\NRT\MEFAACAAkAHFb6Jct#81$CIAAANqkAACaAAABn
??1>L+ dGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9dYE+iDE$LtJ6eMSdQe##SuJtAAQ4\wj:ZqJ!=Tc8#4YA
XKtyQq A>^c6aE4amChP*Y5*cS\=VykAAQ14pmCyEnntwY4FLF18+p4F\iR8>^@LIEWi<@5plSFTh@:Fd=a:!8N
pb^m+i b5uq#9:NM#M:?8##Q@=npX=@jK<w@kD/Nh:@kjjjFi@uC@>RQHq>uY@??86M/A>j99@???L:@@&?WQ@#
qn#^ld :<X:::%Z9Q@??<WHH*^R9L!<FB>??GH^$WejFS>@@HH^!TijFF><<WZ^?iijF=>>>qu^/cijFq@@W!#?
/dFujK >Kha@E9^a^H=yjn9H&Z^+%@?W9##j@+ZYnnkjeL:nQeq5\h<HFB&RNtB!tK?=aV!E:/eWH=C?TutctiW
PKQQW/ u%F?BuNG?VttS^WZqF>RjpH=BRWZqEj\EZ!<=KdT*\u9M>=WFuQ#?DlAlkNpPECGA&SIIpGGA&R+RIaD
-AuL+9 000b92fe57d00110334 Page 228 of binaries2.zip
L+nl:D bDlAlmRtbDlAlkNpPECGA&SIwpPGA&R+RIaDbDlAlpNEGiR+RI+D!SFn:q/TlQ:PiF@\n4uLpPYE^p>w
Ae9pIR /ITHumBLGkbeQPHLCdKeIE5cF5l^kl\u!HE/W%uMR\W=VyDlBBqPpIGG:kR=VyDlBBp8cC9mM\$l&5q@
#YFMF5 q&q+D$tm<+H+tIecdb<l$^tNu6HAGVKh$jabF<>+!QqM#+y=PqLdKEj:b:S@S95$SYi$j/b!!HCGDPea
KpB@qZ $:VqtVmq%pp!t6+LbLmk9R6p8$CPC>yLW$6!aA\8pPNCe1BncdyS/RJbLyDqAmE8cDA6Ael!ReWLd41k
5uSN#1 +AJbcFqeTBdM!RY!ZGk<pm!$GtkY#tpySekRIWPEDBE!SMmRqlNp8ECGCBpmbLlAl4VEIEPEDBE!SMkR
M<c!T= IRMinVjKIWPEDBE!SAkR$j+FD+8wGHHV/WS#lHtM%Aa>t?+=FZ>j@F9^=bhjFq>>>XZ^#VjjFN>??&*^
n5n9NJ \\<@FN>>>%*^$$<@FV@@@HQ^!!?@FF*ZFX44al#HR9%jLQ:%#*@GQ1ahHhN@Re>NHD&Z&FkE=+#>@*lB
wdN/et MG4IkK==l#@/6<:q><!@T8jZmuj8PjW^y1j:/CiciG8Me*wckm^k=q?n!&81d!DFR8&GG19/@W=ab%n=
l&wTFM $4eaenWtZl69ydVi/LdX>J:=%&mTQA>nLuhc6qdyth1b>^MjB>HmNl8pW^w>u*kj!4+9k&?4I&QH19Yl
Vl/pem Tu!m%SPK/*ueMZ9%t:G9yQh6Z*e96Z=G6hN%d:%&w81/t9tbd#tLpjEl55d:l5YJd%?n&luic/<%4\I1
WhASe< 6X/KGAYLSQ&GW4u#4P=dd^*9QhYjiepHa\a8ZePNHwMH4@WkJJXQFD!ZWp#qI9N=HYk4R>9*R!N>+J41
wTH$cl #>S6iD>\lt=/E/S&VMmbd@5t^1btWhatwnn#jb6wtGnm\:We%IwTL&HdYpc=^$lIn4=lHwnmPXF!=*tm
SCuik5 mee+8ES==>Bi8@ADy8NN:XlbhhYw9YhhYZa5$=I6jMRNT#pw:Th5Ji6bYhd:$dGKa!t^CB1dVQ$N*hZi
wPPI%* hV6ty@qu8<+S:<#APCdC8imayuWeY\tK1R&aNc^nNR!KF46ZLK%#%:dRYXk@a/?\j=^V!n8D@c^dZHhS
cHeLZa T+%/Hp9DwLd#iAb&9I6GK5n4yDTwlQ5\i:nwHQ>hmed<WFehX@mmSt:wtl54Fw*%eu?W/Ghdq*Vh8ca4
XR1kye 8ed/6#+yE64e>P<WV@W\C%SQ8%#Qtcct?/pe\/tdujCpF%Diyii^9te8cRqIa!cFNCp6p/t:8b:+4EG6
/6l=^W 9jL8Y5@M6/X/#q:L5YVX>jHyBk!E!ZyRV&4N#Ny\amjFQX<*b44k*K&Gj%#9i4<^/:9wkXujt15m9*%6
Aa^X11 6jnt56FQwGbV#>:R/%Q!>h?/ji6YN:4HDh>iu>qy@c%^e%%l\eX=9dm=?5%nb@k#Tb$qcnb$9t+!9JHt
5nm>n% \*1*A65Yh&AZ$a*tCZ*q=S#D<we/j#5%M?>dcS&Dd9c?4%VEp9a5aMQQXG>+B%B6/VEV6buctVi<4He9
Z:=nBI w</$%:j<jdtEpRXFAAXY%:#nB919G$9kZKK>&9DR>jX8X#Q*nJLcd:tP:$y=mAMRANwQu^w&A=e\+#DT
bLLE^^ E%Zn^M<$Swq9?lu%VXXYkIPH6N6RqLj>:4njX/EXEqaFl4ZjX:9ncCc16>SAL\46F1w*QGqwaC\yap>t
+>=jl& \E^6y6/8iL4QSKBeqI*qI*C>X+aD*+G^#!nYTYlkb!V1@B$Q$CyLRKTHPmd1bn=S+/:ZT?l4LB85k=1A
HE@&mm W9hqZRF*Xd*jET/1961Xmi:*mc@*?<S*P<CAAZ=WEq9IwS#YAhb^6\8PaC$1ltXwwk=6yG&q$nJF!&yI
<M=Xii >6/Eh?m*eGR&Ki^A@BQ8yT%JkEh+ciSAiGt%cqY8*?d4Q9HiDEA6R:9ZaD8lS&q:an=GV8M^+S*\<E%J
/?$/$T MLnkZhn6!Eu\dXuCaE#1*GSAINYJAiku9P\u9D\t*J6\Mq$u%iJ5Z\$S>1l<PVLk6G9KlKQPZNYcVtyt
%bMwKl \4Nd9J9:i/@ZJ6\#N*m=w6jub*W$+iJXD>:n%m%?cj%&D&qV*#:G9ii+?C4i8FhW/C8+<@V/8?Lh*:S>
epm9u5 =/#dq4wu>KE$:4tWdkM%G%S%Y!AuYdDn!MyM!!wBZ8LZ%KZ4T^QL@j:B@Y:l:<VK?\m:6TZ:Xc6BY!dJ
ij@BBq 9\5l?*q9yVcDMScdC5FR8RF%G?wZ/k\%lG1/bT%XXZA*Ih=R:95P?t1wZ1R1P\BN^*qHQ6cc!m59M$@d
+><ciN medL>$eP\^dZ/*G5u%Qa8@6>k#EX^>=E:Fc?/:JjIV#$8Hc\>tWy6ALARY?4%!n5iQRMiDCYLZ\ebS9!
Hu+lh# m^4:nELjw\dWpS/VZw6KcD#H\p?De<KqFwF^Hq4JCb9l::%CI?9HH9yLNpG\F9=kR@+W6jiaRn@DQ!A@
n5>GPQ w&hieBQb1CLu<L9ihK%C?%L\IJ5Y4mq<cjIN*$=%%Me!SmY=lneb$D:=#/t@n!pbLLCkWHek@>eQk9e\
4=XXG6 X?IR+CQ&k=W>X+NwY$E?*85W@ie%ly:<eRt:^+b%i<FtQm\<d5Va6bEe*Aa?IhyHl:Hh5Jlp%*nV:+MV
e\SC\@ YBCmN1aYjpY%uum>+q&L#pm+<cJ&b6eDnu6n?l=&^?P*/W66/=:56a1tEGNkLY\pPJ<>S5MPQb:Jc$C$
l/&mLa LE6JGLHR4yP$$GXHb69E#?+WmK^KISXFATmm$Qa%G*1m1@iaKG\%?P$$#1t1LHeNHke4Dh5BCC#SikVA
YNVmdi i^pw4pH4liIqXw+nVF+*lGb5TGuSRpu?=^^?mmtmlb$yHJ+WjV@/CLPCHM9wMeGe\kK\t@4iE#:u?Nhp
*^wpXS ^=NZq?N\JnRDc+H#KyA@ml5byy4Y4SBa6:ADBB8A\CRIM?:1nYR<M/:FdJBN+N1GJj?<cem?M$^KMuB!
TaqqNC ?RyP6@nu9e%A:!iHNH?BIFtjin<bB5/:Ne+8iu&8b@N%XLDG4i$A@^AQj8Q&=:lu>9Eu/md*Q/?#=jwM
qyiMP% H4pmCVV=?e5#:QLF8W$Q:*DQ*X\&!<iKj$=l<w%X5/tVA/md5qjC\1&!yt%Nyw1wt?m&QQNKAepW:Nda
cDpNuH 9PHp<JAjl&6Q/Nd@t/mh@EDZ9EB*qD9YHG?ytQtZY<1PbinJ\Fh%Hiy!$Q$Sjq:Ju6HZ@D@ktIb1>ETH
WS+kIJ mdb9yS#cSpwLd!DCNam/ccN4&DQ/19<Z141n?P&:$4b/1RX#T5DI^@DCPbNpeBCXE%*#WAEm?*&Q1Y?D
DJPCTD bk*R?S&yk=/5>nI1Gk6DiNajISc<uV8/J+wcVjd:HqQw%:+uQR<>i$Qhly?wkREpwBp%D>DWAnkKwWKn
5jS:uC +$V>l1KhEHJ:n/tVL/WlGlI%SHYtqd:q$*%^kQhN>kjYaF&mimeW@PCbiqq!^auQ%GnCAhLLSQWhhdBn
KNT9e% GG%u5K%LqGjKaTWSHRGQ#5^^!nR89aAj^:yh*eBi/*qjB/5E:L\iFD^jKIBL\p:1cd$Db&pA=en=KMtG
<8VXJ? \w6ljtC>pj<cQi<Jb#\dCaYhp1IYFA%w^amllQ@dpX?cDuKmZ*DQaB$HB:<T>VuYM+B>=I#C!VA\JDu+
6iW\kb ?d1i4?Q=I%$uA!k==G$A@GPAkE<D<I=\m*DZNA*$B?ch<M5RL9b$*nD:9jMJF8HipHF9\LbI>WZG9SAI
:XXl6! >@D<hB%jSB4AnI9$ZL1?\l8:^l5#+>GMH/uA*n1+5\i!^S&#nlMVZCZHbu/Au\=9:B4tj4Q&F:BaAG#n
@J!/dp Nm@\NV9/?6b\eN:jP9Kdm5VTSK$>ii4kjBJ+Qb?en!aj9V\yH#*bQc61FNkytVeQwkJtQ1SLPG:t!EM?
@+CRmN >eRD8#$5\ZW*9H@8cWQ9T&Cjll%cq%%ad5TCF1YM=n/8/qK$SDWTq6<d#uw/k*ul<HM<<dD=Y<9D%a:p
&#&FGJ XhhX@Gu:Wi/:?9i%TS6IcHe%Q$$KL>*l85RL/E5/pmJIZqIRp@\G$e4EC?%Z<\Z9tVHuX*GbiX%P+!>=
:Vp4Q5 P5hDi#Jy1HYealQ*wYH$mmj@nM#yNyAKc?Bwl1!$\+kH\QF\$$IuQ##Ci@FSY?^uTh*D9tY45@H=HA>/
DnLiu* kNeCNk4ppHa6aS6CT#KlQ1mP:RkX/DTD8e\4&dI\e6E*t6RJL>FEyBGk<%qBI&Ep:#w8DeZd!P@A<!Dk
M*khcn bK4u@8j#QXbXHLCD=@@?BW:khS$!P1/D9<>&Fckjpy4&Gq/LDIN8!%1KWSwXi5A*GWC&bbk+hAiKYZuV
KHWCMk Ek/&b9a@!Q/Huq#mcuT8S?h:Fpw:IeMt91LJRmE<NSJ/F%w8$Q^DZ#dpa!pM9<VIp&=wAwQjn9:*9&5m
mqHGkt @GD8HH^Im5eGV@FNq+CbAwu\qNG<pktHjA+I81d5+en/:V+ui+L$6qemBKFmP61nnaiHSVJEMQ&idCdh
<1P&KW e*k&iqJMh9d#!BBI<?uC9qMWu$#?H8&9Eh*YyQMyVpVAXZQt:1JLZ5K4lX%DlmHl%LV@YW%SY\^Gl:bd
E/J<N4 iG=nTajDen==IlHNKnBqqnCq%Yqq#\X#m+S:<bGieH+!9d%jdeidGCu%kCK%$=1c+qD/Xt?c1*>tH?uV
M\<a11 ?iD8V8HyJj:=wNSeXc?=W%YQiijiLj:+dtHK=>HM*:4>dd9#ALt*Z*jd#B**4uI?8yH!Smb>==b%+i/j
W^HH=d 1:&h:CMt&:WE/e^9m:#t$VJJeH!HF%HX*BQCG6K@EEe=PlmlW\HcCQDdl1FF<hR?lYNkb1=\!A*D:ak+
d/H9Z? >/mu*k*6k=!u*D:6Z$>AAd?p*QX>a#YniB8DCLK1yL9&u/uaWCS#5R@1qNh\%WiYEFB9=<jJ88=KiTeZ
\FTIZA ^Z6IW$B>9P#JL:VAK8^#H*bXBdl$myi\/Ku@R6B=DSSb&e8qQlNmFLASF9#V9B<uQV%diqpjhhI&Nd8j
^H?1>Q @$u@AcQRY+KBl5^1?HFcR#>dHiD\J6^Q?#5P6VTnYQwdwQW6VN5b@^#Ad&\Ju^S<FK:tiw&pPKS5:66*
*XW?FL A=ubPnSB6ykG8h8ZAACAl9jpc&y^QAycGFqPJ^6il/9BFACK$ReknN#9ML#iCDkkA+AR/4J6YpPJLtDl
ZSq&9w qeLKCZ!XS#HN9>t>RF:eX9aql>9BW=RQeqTaiNnC&RFc%y@4c$#Y55\qlXQJ5eE+ha%#CR?ByDVjjhZ4
nEeL/V yLe^9EERAQPRE8G$8h8YhLBa6&R?pMEYcFec8A1\uTmPKiQTQk\=&bQ>q1%ciChM%uVi&6b$+LmeyFGe
i=*&D@ R?uq*Eu*qWBQ>IQhpibH$<K#L68byTC^EtK\1qT14Nm<@8n<q8\k&C8\Y:SQqPK=j1nllb4dAN<cn@De
a<QB9n RP=ZZXZ%+B?w!Ft@$TKen8@\Rdp:u5:%LYP$VqMpe+YdNNHyAMb=j&<J&>6+KdqnQ5hNX^e*AdEduE8u
pYW#nq kqPw%N%A&>SNb/@ulY<@L4\tRmcd+81WQF\Rc?*l*CM<95t9jAi+8ppH?c*dZ*ql$>eHT95Ypi@PD>j=
*bih$Z uheD^i*=:GP^=u^Me8V:a<q8NJI%X+65#8he=#G6*qM?y:ti>lJp/RY9E9MwLn4ua^Lk!YDy?L?qjDiq
C+tBIk GPGkIahEpjE:=ZG8??@w6F@y=BjP?b*LPX>5c#yAtN8*k15Hdm4qa=a%uipA9!wB+:8m5A/5*ne>4!qR
H/$9c< E81?=6e<#tm/#pVww%LmQ:d:F/%j>8&e#?tdjh*98E5Aa1Pi&>jSCk4HVXH8c@6VQmchI*ta=k=Kn++y
<8YG:C KJ9Bn>DDY5ma$ky!Qmje#*=pqA^Te%=LcAVBW!l$#8>$E6c/^J/pw!t@/G6!+BYNV$=j8m:dJ1S<VCpa
8T5*jj XHiV\=JG&SR@BN+AS^6NGuDP+%R<\QL^1lEaqpdB%D<iqXh#Qme$wSlXyH!HBq/uth8u?BGqn%mtQJNZ
-ApF%T 00088f1217000110334 Page 229 of binaries2.zip
DBk&:y @*uP^&#4J41Pi^9DQqAcE&>mqPRSN/u@ejL@kAPKjCuY6KEbAw5DF?SA#9teX4Lpd^GPyQ#aij#BW>aK
y\E=Y1 *MShZa6qIeD:1cj=^=iTPX/NjFeP^Feq=a*8>!Z$>P#@5h&S1Y4H^J::!QiC:ZhGX/Xi<ntd1m^*DRZ$
y?mt=w NE@^%*u<aRVAu1D6HXeH+6DGY8Zan6K$@!pKM8Y*aC\NeD#%u!wq@\@duHAkQTVVjHSDYl><m1QElB*p
h4uj?u d1:Yu<:4L!t1G:&?!tillBch1eu/H\+<!*y/j8j4yPZhSAp=F*!a>V1A5E>&kE%?KVbYQ/S?d>TdY?XF
+RQD!E *PV^4hL&*M4@Y=@%PHj@Z8J%DwyDL*lJ/8NZV9X@+t>e$!4e!y<\:6j?weGV9J^:?DX@t^<+@Q464/h9
q\bT?J uihpN\6kk5FpV/=\PZ@/ZH!*H6\Y^#i@w%l?B1Gu*JIb>#L4N9teWInpD>$9kYbH%4J=>R^\<#8KPe<V
>Z:PW! !mDqyXA<WNyIDde/@c+l=*PtlJtW9=bMhD4@$=wM*Pp<V=QqVEhDmmBZtjuen%IqE%DT:!#W>ZeYm#lV
5DWpme jme4n\BCm4QXQT<=*AuAI!Z&ZjM/>%*/?RDq\cQ>:mmH@Y/a#@QTARD5Y>*XZ4:$hm+ZP!=+W@Q4:!#K
%@TdJ* /ZeWYaR=9>M*GR<%=duwIj$?\6Wm#9th\EhJCRQwbB!A9\ACF!Zen8p<#<IqFYSjM<qG!mia!yXEAR51
#R<Y9n D4i@5%mY#bVuPiMlydSRjmhLb*%m#8<$bEhkq8D9DMBAP5@l&5EntQM//W68@@kGWm*ujI\H9MSjm:t/
%eW/J9 JEh^J9m>/Yq*i<A?pe?n!*AiVwRpREKEiPQLLEtA:i/iub&I*a:yeS6njkSWXqbqclTjlV%>F6kDw>ST
^X@:5j >b/4dSj1N18?e#byD+%h1=+#<>K\>D46$\%uNtt@P^844lQMNHL<KbPkdLV&?j1Plhe$=9XQu$WEmE$:
Iq*%*t aL4LP5@FNWNL@TcIEkk&4*i4Nda<+#y!?ZV:eSP<BP%yNQ66#RB<yM+VX>MH%>\c?kW/=?&Hqj+uacB:
&>I%iJ *K%yZKSh+81#AC:yLSIjtRaC:/cJ&k9!E<FF*1K:/w:*LM<K$YHJE6mHhGuPMwNT>5NCTaiS:nAnb9>L
EJtkV* ?KJalAK^p&*dR$<b/kWwdbZ1V/n/NL#M>8bmje>G+K%J5iAq<teV1PKq9uNk*lNY%&JAb&TDepdk<Z\e
+4<=?D jMHbnLe=#kV@#kePj<K%99@Wh?GBl!M8%9X=Qu&YY?SMt@k5*?Icq@bTZJ=^>XY6<Gpu=:QP#u6$j/wZ
qYRj>^ l9BNEi!LC1EQu<5a+#j%8@nVitQ<DIG<j&6+@Wj:Q&$I#PtYK%nFd@PMX%:/hq&juA+96HI9Q<jYb4Ww
TK9:!/ p/=*BQYe<ZKh1+:#\9<8QQBNN<MK1e@KbhcB9HTS#*cdN9kBR@NC>*BA:u>*XeR6AC<AITLBwh8MXhj=
ntJqu+ hI5K*SQ?X*uj+Y<ka&w&:6?V\tB$6&c/NAbGJV>nhI?Y&$XehE/4QimQd1XVcd6dC*!J\aq85?w+!j<c
MV/yaF BC*\qtWi$1+iQ$b@@/G19uM^D/q*Xj+uSNCBn?^LJ@q*8X/^@P^#mqT>bX$uGB#RctJhqd4N=ELXdS=/
b%8J*M V6dl^4n5>nc18>*y@b5hC*h=Qd:H:<#hpu@J/V9S4\5hCVlqXl44QdV&Y9n8SNGA5myPSl5quh:iD8#*
jda@ah mj+6XB*u/qQ1P14mVPyaj!%/\K49nAB\6jS!@mVeJD=d9>P?J98Q#5Sw*Mu@?t*!%m=X%=q=didnHRI$
MkE?Rq Wy8WpLBWHii86uEGh9eyGhN%QjBN/:l:$ZiPQI:Xpieh?&jDnbqY&j?8#Dkchhc6tRlk#K18p@ZY9dQL
<lSmuu +l!XFeB=%uQhXQYhPL$qdl%Yuc^X$\l+NWkX%149DJ*CRK^4*j?TZS9H?YQ<pAiF>Y!d/YpC91>PL\6%
T*lm!h udkJE@KmQR&#d\&?uT#?VXZjPR+t+6=VTbPd/4VmQqmM^Z*ZlKmBShdM1i%&8j<C!/Wmw&S>X?+@9<=6
bMH^%h K:/q<kllGNqH1H*A&StS1>AI$8L/i8yc6QM>qqImk<5##^dHnEe*+NXdw?dN+uM5*=BQaCWYKHnhB!j/
1Da$Xm KCY8^eWN4GLnWYN>>R\E4E@u?yP<^89:Nhi%1HeS*99$8#KIXT=<LPiK<n&&aHpDIayIinW#5R99<VRe
?uLI9I lCY@Hkd6pHq!4XM#Q!kePHQp9C#@bwqFF6Kj9Ck#?hJNP58!+i<&$PJ9W:Ru9?E9N@D?uj&@ejmc=>VQ
SYMJ@= 18^$Pj++bA@Q85<aq+6P>Q#?i+*k\m<Q9<LqwLP#QK/%+Pp@$ZTG<@NuaF<PQhGu8Qn55\DQa*!LT>X=
E1mne? A5>A:>n\n%Tb^?1Q1HyP+q6F%a:C6M#@R8X@eWitu>ijEeLu?n%TQ%u*^YiB9B<+=/I4?p/9kX<NGaMi
?h&IpH *NCMa*QZ>Eeeip:*GKnuR9=8HQkB?B@+*BA1#=8H\SpYkk&Tj*6D*Hw$F6@4QywqNI<$6w>ydy4Db+Ew
&Ln41w cqw&Vw1?E*u:R4IHV4YK9qN%=EG?/nqB8uy&RRR9?&+t@?Qm!9Mt*i@nN8K#CjpMqu4\kMWy<L>=H1ib
cpduGT Qw6$<XqM64NA58uRh\K6w6$R+!cMLe8yCPwKB%d$uQ\dqIQkG8&QX1%yp:4w!jN/5Si5CnnKQl!>EkCZ
M*kKqw 5ZMc?%G9Qk55$k?dypQumVD<yP>p&ZBEDGW>N1&SB5TdbXnFMCDieZ$E:4Z!QN^@uE+ApX:jE?ujKGyA
thu*en ^HZdJijth=<Fl1cnwCQ4RGY?kETPm1$y*GGmY$JGMCJJKDyQ/yl+4bcE^GbmZmL:F#*upm9^?#yPHck4
KV9tw: =a8KYRC\A9lljZn^YiD+nhNh4QyP+N?WkBVWh?=tAA@Ym9/IW><=YJ@wIRHd$kQYH@y?eQHRe?JB/DTP
iS1wX+ JA%K*T!?B@KKl/>9&^B8dW?j^by>FwK*Wtj^S*5#CQ/J*$EN6<H=/w@A<w$/#+X+CV\pZk+&$hMk=!Y+
6IquVq ^!*Eph>R*81EW@ZWlZK:E#c/+4@S&DB9y<>m!T/EZM+1<*Ie?FjknQ/IYHC\+tHF^+KFWlmYLbR@&E^m
jy\bH? Q/uP<:EKb<cCk1WXd<<+iAlXVn!<>8hPHD^uMkpuLn+9L*ZpEC:&?aKZBV>jhVK@Lmn=dZn/1X:p*>%@
LYQkEe jQcu^=@^9=en?ehX*9BetK=a!Ejy&hwRV%^:/kQt?*e>$LAej/p:jD%WwZRZT*&??BKY*L>D\nd%k1R?
DupnXn >?@^j5#%tuHM?YPS::J\m9epYTIZC$4J@Bc8/je!^a+Qy$?Ep&IW68?#V4LMR=H^c:WQ4Tte::VXIBIW
L4I%Gk p6\%Qy@MNllP1&G%#9NpYQE^K^Bb<JZR8%d/Vj9<<Sj4RQ6+M?S6WnnPQmM?YST?T=Vc%a?Gj4!E*N?p
+KwFQh A:@a9%9y:iKEHw!^W>jJeiCy=j5%Wee*bZ=BQZbHHP5w+KThd4*wWuQt/!Mdwb=1Aiy4@VdI6CLHDRQW
L%w@Wh mNa6y!<BEdnje!F=I?/dyI$+y*ND!#w/$JG/kEt^#njS&+Zq5Ri!kHAm/ilFS=md6cVlA/B1%9it9aFZ
%aGB9j :Z*DAnuG!Vnl6W=+%hpunyTc5t>4Hl*uX\FYEyjWJt*aTQ<=mGa6dILjQB=kPPBCy8EX*?e@<@n*j@:B
qIE>q$ <#AjcX@:HBWS?<IMc9Xl^BA8P5=W@apFQ#H!Qj8ITDG\PK+lYdA@^t=H8V1!L1Wwj<WFAX*jeSWChTtL
qY\*TE :aDbw8j\=R:L$$u5Zw6<mih@F&Q>jRAb\@$iYSHkQDX$>C@#^N$Aa/e>dNl@H:M^kDee<+nJLhIGbEGa
1i:V\F etjeLZqit+*jB&>M8*J?jjNd?:DQ&5\XQ<C%\+=uaP@$VE%$>dhnEG/P@H#e&yc?9EucwwV#CZTT:iXd
D>LhhQ a>uQ>?c?#Y^@IFHlF%M4L>:i!L<@5T6nE/^DqHKZ&P:b#nh*4l?!9maHpJD4aM51auy@>H>CAea5/%pq
?Jan\Q 5lT<a+jT^/JP?Kwl=@$bZ/81d#pu\C1B#D@NA^Q<bccYY4F:+au?K9MJ*%R/+*iN5qi@?jN$Jb@k^dP@
aP&%w5 @>ZZ@SpJ?@ck@89>j#&9RQkPJ*?*Vj5=H4*8J:ABu88PYSAV\68KRVwZF:l:&5&LVL:T^QHNNjBenQa5
EV&F9\ V!+TD1pL#$DHAIRhLZP+CL?q$FVLc??1cD5WHD#K5uI?YbX\$j<6:cM@>jVkYX%H*/%4H*e4DbKpCbSV
\eECi< &?n&4N<6BRkb6eYiXQPDwy5D#6&&ZQjMe4^>@w9^YZnJ<\DWTwtML#/*%tGMRA/WhRHHb%Y\W:B1%@15
VQQMHS Y%Pu#!&Xq%BWj=#q\#uy?FT>uD@%dFIG/CmQ8Pw@<*4XV848VZN**EB1EKlmB=4CRI:$Z86$FBLK<LP8
R^>HkN q86:IJ15i^@?*&QFR??a4@Qch@%qAK18EI8uCV^\Z<FZFa6d&+itnIGHwbkFhF1J5CEj:quu#Q9HPLRN
n%KV$/ //%he:<**dH>&VVDRD%nPS:SPedwL@+F1*Fhh6X5bll*%5Zdl!Q@uTb!+i&^VbbH/NR85>Hp?/1MQ?Wi
=C=@1G M9=SNZ><tQ:5^=+/q<^d46h6ZMQV@n**#*u&tKJ$#wEieq/b?\*$*PFIX5tQlwaCVh^ZS9SW?eVLbeBq
8lM&!J SmI\luAb@<@>VbJ\^I8QKHb=8yaEuw@ucWqh^:w>n56\P@dH\PuY?Q#I9DJ+5FM+L$B>@yBYFB%=@FLw
ByyK?D pwNG9ZG9>@<=eSp:i*P8>Em:L=5=4u/jM&:::P9%<ZMh@bh=Q#LE?B:@n9\?9kkq\=j^M9=DP9T8bQ\c
ACSEpk Pu+^/9<>/lPY@\NRT\MEFAACAAkAHFb6Jj:iTT?GRkAAN8+AACeAAABndGqqduS#L*BueC>*cY+#Mm>R
DbA>VT S%B#a!>!bZM9dYI^M*k!NC=mdZD5ZD&5/$b&ukWM$IC5Q=J!=TJ^FheCFuB4%Rc&ei%PHY5*KX!=DlnA
u^!Sn> kLw6pkAy$4lt+TyF4CKX*eTXm\ZIwen=A\tptH#uDCXS>+u*/h&d*YAh/#:>jD#DtePbM#QujD^<u**?
&*FMnd ?=Qk%?@jE?L9<Q&jiQ@N:+V+uZk@CEw^<j1c@+t99\=j>Iej**@@9jn?9:+Z:Z@<m*n99jjE???@L#:+
F5P#P% +AP^Z1@Fl^>?KD://CQ^<eejm$<??WS<<eWZ+9QQQ^ijjjcb?QVVV<ZZj?@FH@:k^V?KH+YZS@H9Q#dm
V$%w%I ^#@>Tj#D9@+dY6nm9ej:kQe^\C$?6nm&^dE6HjPl!B:H>@m^^@E>n8>>PP&A+\eeQ\AeeQ#k8Ty^^QEn
\ju%$% nl>^@IkDS^#*\B:aH$NV@LjH?+A*HjPliZ^5weMYPt!l\^a/5E4RaR5h66BlC^&&$IHXlA=d/LCFDq9w
ceIbX@ 5IWP4Dy$&EKHLZVaRwe6hNl/HIMiY?m^JV&<D=jHt6DjAi<n*n=eMuVbw@E>G61n$n%$+Y/AeI<ji?m!
yq1YS+ l!:eLhBnD#*&$GN@wGM?hBZ$&EPHQZVaR\j18n*$&EPHQZR+wm&QV?=C6BQ?npQ*dqtn\=c\D%&N6k@R
8<n9Nc /aBGD&nkAJ$PcQ5A+RGXHA=Wq\@D\Y*nPNw@wQ$D&1elP1D>A^&HDkjweQCil!&M^J=dJ<%wiI@R+an&
WVyHPJ n6D6CD&PcI?Hq9SAH^!l^=H$\IZ^ePPpI*R=RyenqDmmRVaB/HLEmWeWP8LAEd1RYS^JF+#JEdwe1V>a
y!$4*j F:IGGwWDt=KHDl+/iPnkwaPHDt^P$PEIHV^$<NDlCB*a^KCDl\+iPunw+KED15ad^/GDl\+iPukw+NH?
mQ<S/m EbX=uPlScL?uMeI+it1D/1a!i@G*+y@Fq%>?Kd://m9^#VjjmG?@@Xd<<MMQ+4999lM@@jTV?Quuu<W9
-Ad!pY 000c6784bf400110334 Page 230 of binaries2.zip
ZQ>u/p 9@\m!4IWTmuS>:%w@>8Lj@4nH#GQcWb:@miwZpbWL$E9c88W5ic*%%@<yjp%Bueqj#W9G%=9@H/K?MB$
DY1nM+ JXQA*E45BHm\6khAY^V+y@m*\m@<HtSnCT8tqA:1DiN&Hn/TZGdZDVCV\PyLdW@M=jaeFPPG^5A<A%R&
Bn9?Ei u!*EK5#*bm*t<=WMe*<p$bdPMM+:DTYGkVQu$S6JJwA^#^adD!QXPJJw/^$?Rk<@AyS!dbWX*mkIjJSX
a>tb#b 4WPh*Q6nCb&le>qaB^pQw#IKu/&?pX!AH+NyCaQL8NDqFJHTZV>IeNGF#LX4aVNRa\V$yESb*=R!DII@
lTLMtq bhL=/GVwlB8JeXE1h9F!qmtut+$R1$=XM#GQV#iTF\G/t4Q>&!=b4ZdymmZKtZ+%u??T%X!/P&B^B%mq
&Iq\8P 9M:T^q6F+%NXjVwV/>w=NbbaZ<Td^u54h^YG%5wTQcn45uEpTT<TBt+M*m:l1%FS\Xdl%Wbp*l8=keT/
j?86iP y1!>q<6N=M$6<JMT4d!K=:&naZA1Y!TNM#LP!WlaW4HE!8#p#eu=Lt6\QZWG*R\?@c*pSRD68G^iiW?G
c+C:GL $MZ4yMcB$I:M$G<8y%IQA1&>puEGm<W\?DdbFB=&%yYN9=EWYWWGaF&WTZ&=HyT!N=IV#d<#8JFMA/Nd
\^Q6Ry ybw<$1w%Nmy4K%jT??dcnyJB/\GWa=A>BXA?V&ZSX^kMVjMH1+D!%M/NBALn/XBB:Vm!6GF<YGIG!X6A
y#!8mu 1KC@4R%4\@qq/W1h4=c%d<8i&mFFdSmF^+D&85>ctGMP8<L%>J18m^4Fn/8pKLHT1eL+J1tMR%hEMM+\
yN$JSI Qm^yaeS^d<@FCJl:En8TBECDqMb^Emhy*:wmK&GJ=V1Q+5w/Le94pD\G4P$\^B+4e?S+jI\96Kh&4M%H
h\/6M^ E4uBqG6l/P5eHhppQca4n+>nmjKYqk=@D:kB!Q9FdFTXGd%K&dyRVPjy1w\e&1p\MinV&$iB4YFmYEB:
$^mqnm NPNXM5<>LIpdHW8e4Sb^adFTJ!&5eVijqY&Zak%TpC#n\uY:hWitDHB!#SWWV<DtDZBnd$MF*W^p#y&!
@R5YnY iSyl<iCF/=R6/PLQ+EaT\IyAEa6hR$M&u@WK/>65KY$da^D5nRR?WLeS<*T>lBte14k4KmFwn<A55Qq8
FI*MXH Ny<uEc*>DtB?AT=j#?a#BnT=$R5mbapNEkc$H8mmmiDqcM8%mhpt1&TEh5weViSbnW<A4H8/B4AMYnL+
p4m81l EbAqFa6pmeF!dbhqhi6Qqe^nMT8yHbbkhelJkm%CS^mb6G\>h!m&CuI^iC>$Dmyb*wMBVNHTap>AP%+Q
FdYy<^ uA+8AT$?PGCC^C4!c:AXZNh4*5eh4Z\$X6lq1Aq>BRyVkX8%QJmG>YDkLC8q\^i$eXVCSTZtSc6aHVaD
ja\8T8 &B5dAt!>T9N/qYC^R=h$6ZE!:Yl4M4#9!84pTFQ!KhKTC^uwt<eNN4MVZbX4c8NqTw5LKh*K9PnpcZCF
yty$X* VNRX*B@56A:PKn\8LLWGc\>XnT=#VaL8=K1%ShY/mtFlC86<Y?iuZFI=Lpac6AY8%@TTdImhKb^ZwFku
Q@PWE6 I$8t+H$Nw#dBL&4LbbwqCZbh8BHc6#Eb5GLuG19<dFjRcw^BWHI8%y%n*/MwF?h#$APu>TcQq^&jSS*8
+l9kCD Ly/e9dk@NALZ1tp<S%Z4T>Y$#%B6K/46Yk#hqP<Yb*@NZIw6ibjCp5MVlwVpJqb\>JwG%XLZS*A6B*%k
y*VXZE H8^Q&tB9616aHZ6#D5bHhW*ShIW#=$nkZ8AI:dl1hcp/D%ZVBhq<1QyJdcNmiXqFZD!eQmytdTMdqHKl
5q=yCa d4Jy&qtCN5Fd9/1BiZH^ttticQ9GPjC6aQLZRbumJ4l1<$#X+dh=W66RnGdK8LJ4MV$EM8M\!&w%D4yG
kKZjGF *V41:NH9&*Mk8D<wV!:w65!%Pk+9S=HmVY%DMe!@&^bG^hT6#tVkhm4Euwm1d<:lkQAlQtC//mq%#JW@
@yDm:: iKM!c>@KH9^%98^9>N9@+=e%?9@W+F+Ld6hS1%6>9TI:jhbnBN=nSC1#atMtdA#5a?B<VlDR<pqLPH99
y9Kl*: mnd?M+F*y8aC5G<BYw?+*LiD//cylp==JTAjp*a#&6+M?^9hG4+&iYdpt#q!GIehbALeF4N&^PW?BAcK
Ptu$Yn !/5VEY?9Be:B&$BE&ZRS8yn<c:qGuB&<FY?:VLc<5#<GLDG=SiAEA/%:BYyC+qY%Y5^&MlQ#*D$DNIH%
<@I9n% GN\4y14qdF*JhJ&8p^Mtnq\6$9Wmc<t^M9X1u1cLhX@aB+EnJlhB%+!+*AiB4ZcIpQPqpPRh9ldWKaL1
>=Vwc: VMVwJtW<%R$dmPIhL66Yc?uRhl>*n\JLMTXSCG#NW!DM$:MpKmZYIARkFGK@G6Sbl:mG*YMEaF$K9:8F
?&tJ5m ASYF<X%CNAQQDV$GblJwXyT=tdQYVG^eRHpQXG6$L?I&mYXwE1m:wH<KhLQJEE+q8Y=Q4iE?w:CdXn^d
IwM<pS ^:uC$iJE6#uPIJwEZG^c/$tAph46!t!*y9kIaD$G$=KJa9mh^m5^Z<>Fely/p>eh:d1XYK:tK^L+B<AM
TK\RT4 kBiW$bB+N:1ECRqFXqqbJV6T=>YAw1p!nat8\hlkwJ^6nYu!IqChClPi!dRHAdRL=N5RIV<A#EAuTGJL
?ZjpbY J+F?EFmmK^yW:c11<EWe6>=+uc\da81^5YKKqZH^KDBEnDTZWZkIaP*hXc1IN?lKFeCy9IBiFiXIWySM
4Jm^@> i=\q/dXaFDQAWJ^P=TI4<1S&^pidVYPdXKVRDYCX8&c*w*+HYNbE+A*kSuIBGP$1ZjGNEAy9AJby^Li6
Z\QMFJ kmTJ4yIAmI#w5k$&DWuSQ+F$NX6JE$AJ!Rm5^EI!d/KcdLeR1#MwN?6q1MB$/Y!YSjX<WXN+:>y5IVbT
h#d*#+ X4Al+%9cJtKt/Wm!HIAtStW?C&\iFd5AYHIjb:umTJ=AtiY6QaPakD/DMt<Hpm$+F<F#AhBF/\L>RERe
<cV+4X 4b^uaF5ap&d*En@I#IKnChDJI9RPE+#Pt9P6P$i<pB*<Kp!tkYakL/=65SkNQAe#iE+QQJJn4+qmd1dn
W8$l6G PJyHMX4DL?#M\M$NDm^d9A8?V>9TqpFWGnF8kRwnB%Kny#IapmR!#6uA5uYiYVbd=HpuP^+T8J=S8c5C
&Zywu8 B^QaNZ*%XGu%$eN>+kp&D^6X*PuA=w$JQNKuhY%j<c%SIyKc#iDeEk?d=FkEmuBPIYZW%e#9ZFp&>lt9
HlX&X1 XBnSXapReFcw1+lq&=^bN8&nhJi5T:kBtld@Lw54bumD<&^9\+b\:Ep:E&^i+NL1RPBh#nFu*d4=mKbd
Zy:wIA +B\d#muY/bu$$\MX>mdLS4h^bK$>*!*HBh&\dE*VhI%l^p^=W/W=&>6#WepWt&jHdN+6=jatA*mHynNQ
eNY$AQ Td<yKt!\bVXEteT!1VM#S!!d5?<Ykh%4S>>l<<cW&+Qu*NJ$$%VatH>:!5!N#*w5jib=N8<?=Vcy&#Qu
1pVLy% 9AMXhpN+9bJJiwnNi^qN>>946>h94#<DI&ejI<pi#u@:*/#6&VVGEh<%Yqny^8B+8S&D>np\pj@&\648
$&>68i =FW?Tdm<J5\N^BXZQ9\id6RG4??<ka/BiSVenI$&:%:BDZmDeS9X4eN6c$y=c>8m$H!9tkB^F%HYE<WE
Dhb1eG *:BKclQ8alPIGhk:p8TibP#A&XPnXb@W>6pKukN&uFjJc18#c%kkCC=C>q!#E:QFa4/M!T<mME6c*+9N
>k*IK$ !eM6!?by6X/Tc$ayH?<KLlR\jdpwY!*mdL*K+cFV9lwZ1#tdaR\tJPVm1&^&#16E\CiETCQL4uK*t5eJ
Ry$X?m QF1KKIpb/b!QE51$+IH^y1uIZedqELNt/hPF4@Byd+Gbp8nk+aW94>IbJF#aPTiJ1NNb\qqHV$B>F%^a
K5TIX8 NtaJKLE1JJ/RW%hpMeJlXI&cZb*B%ehJFL&j5p4BpT+#SJTW5ET=dEbtlZ<J5C1K!K^QDaJK%/W:GTqK
$EWARA @8J&yLWFnEu1Ein%qATA48jM+qmK#hbJtacwK&RupjI$dTkq5hY&J9IQl^Ca^LKtCDtLI+yJEVuJF\Ht
L>9tku PlG::lCEKWRiiXt%*6aJ6>N4^*1\%kVeBcm:pl5?pSLFh4HMhpS8WGtaFijeWWwXhSkX1QnD8#I?NXpZ
k>NenR ^p1*bITX9wDVGESqydlZS5Z$ySlq8/!:b5PyJ%EyaScW^F4&Ih*LKe=i<%ek^/B@Aul<bD!\WlASm^u!
5c:Yd* Icqe+X\VX/VFcy$tCGqDSqpyjdTS45N=ZH@RnSIQ*^$R^%!9=n$qyqC&w@X!S@q<$4!lNTc:G+PuE6SK
I8p*N@ IYYW#m5h\tWcE1\$qPyuQCeL6kqF5pY@&eY+9KB?XNbcdmJj+*wm#nX5Khi\Wm<BFC=H1%tIZCNT5K$1
#j\wTI yYkI^+w?iHEeIje%VTYql?8^kicqdN</Z5YWMpLbe4A*Vn\pRh*FtjP!nGntuuk8hFq8GblJaP<C/:6N
c+%IFn tT%V5nhFLD*bbB*5?t^mtMjF&N:\cejkIqGWE6n+j5MY=$<X&X8#m%6iqtYZ4Jt45Y$jh&%ldaXF$VYX
89Z6=8 qFZudS<*n6N1DVP%pZ<J5NTe<=YITS6IKFi6ZMaSVcK1^X=B<?<MLH$=N\LiZa8%8K\w^6dayBZqG4pm
p*FF%B Z8#KhBaITb4&9p6wt^4G^>ieQk%:4G4A4tL16WThu8?EnIB=XPJ5I!Q4&=#T<aIE:T^l/q:%Pc%BX6aE
HJMWR< JAM#BwNpZM^nMZDwe9RaHc5TKVNPG1Q5e1^9WWX*PLAi#Dhq9N8SKMytImqwnbmqDdy*k/ppX<S=Ehk%
TddQbk 4n/D*R/TJT*EBG/LajwSWGb+9mCpmHE^LXe4>HXW#8h^yP4NdIW=F\M$dbjPX4$cJQtGAW5GeI4Fkp/N
*b=k>P Bc$\EP&!#nKVSbR#&t6&Qh&P14K1!pyeG1\!\lW*qFmcaWMNhP%5W>PK\qql/>tc!X>m#K1F&PYY551a
?Ie+\a !BW:PSS41/Zauj$9jZtCkTWL5Ypm&Vm$k\bMk<?/bXDaHJ?TRS?y451!AKyIh^hJncuTW%cqyc?+Q=$j
b/!@lB Z+nm*YahiNAla=YbVR!ua@iKE^lJXh6$+iauVeEinlE#y=ci4uB6^L>%m%&=di&RmSti94uD>\V!N##A
b*@BZ4 \p%GqL94?JbEK=8RN$5pMl^mXR!MMn>h\mtY>FuI:y^iG:+HFwy!YM9kEXMaw5+Sm:Z\DbyE^IXytbZF
WPTZM4 SlSIh>4NXL\m:6jR\6X5Typt#FZT5^%$D9GwSG?tebQ6#nhnutcIDe<Z1aL!K1Y!%A#/ww&Z$l1+#m$Y
1kSyd4 Dt#<cZJ!LhVCbll*JXa8lDNedBYKejR$nyLIMSmiYS1FE8RlmXWEj\t:TCCbM^&!IYmNLFLPjPVj:Wbp
8*4mA$ ql=MwF&d#/E>R9G<d&m6jQN/SmqqXHXCXY5dA1M&ZR&itS&1yu5cqJYbwdb\Q%bjNVDt>kp#c?+HpTRb
:=PmM* q%PnbBY?FcDMuWn<>y^S4Qnem=u:$Vu1684S+$Q/mRb9D?Yjl6>V!WVn=<miQq@+!n!qWhZQ%cdjqVZ<
<TGPCX 6X*Qu?G^$X<V<cYHi*C@q18^?qVw9?kXnS<=%bQknYLtL4k6VLinW9bTKK%@uKV&ILnNenPQJMMN/@nN
HmA*>h k/eQAnMq8i^w&IYLiyNER*4ehc6:EL\p@+$bLe6j?mHRVwJRDIewHa*VFI%9bpLTdjKBQA8TS<Fp@66$
hawCwT bl\</l&<<T+X<HJiDakY1?Cq#?aLTW=A6J=ZemuwTVcWI==9KicRAM\BXtN\pX!K9TV@VXXbbBHQ6bTk
m?YL^< <lA+QXPMHCSd^BW<<^:8JFM:#5lX$nLymlCe!bwH\hPWN*e@=i$tGe+%jeVPdmISkd$YiJYp%qiX%*FF
^ucCX? >>wSDdh\qa88aA:EElNXX9wBWAC<LiZ6ukSS!T/J+&SNcVIBqJMA^bJd+G/LYX5uTdK86PwRS#YI8CmD
-A8&iM 00084b8690900110334 Page 231 of binaries2.zip
eTFyE8 W6qApqY6KdS1G9$kiFH?t<5*t$4GK+1GZk*I9b/9!1/VVZl+PtVBpJPAH1<>lw:VZ#AYb/Ct\W88^\ct
%\&I&& JK4wGdNZA+Xa6a41>d^5EIBh&FucpwmlnXME8LdXD\H%+QneyDFcBC%X*J1T5$yiDily8111$qXb\Qma
#y$wSd =KHYZekG&tVq41j<ykjBC//Hk:c5KdKMTdIS$G?AcqJ!4aDTmSCCSdVwPcK1ZS6!XwlWwtjqbhSEn+I:
quHIDZ YbZ$MQ8#kLKY!1#Q?Q?^iAdwl+ySKJ8V6WS^bRKhZtA6VVy9mEYLEEMVBj$k5Lw%?NFl5@+j>1+6Y%aW
Z6BQj@ mj4uS!+#$>iIHI?VeV!PTFREaitjHV9AX#:Q9jZw4qy>889e>Gk1CAVEb5ePqHw@MP@QWN&YQ9X$99XA
YYM54> 4Rj%/W^&PHP/dD5A^K8dY:Xae6uJie<RR/&aX4YMRNbe<DJ=<&<P#PuMcFd+%4Qe9l<k@DaNkytBDl#R
AVuSQn QN<8@mDJeMd+k/jLnkj8DC&w?#II+nK@C8!XmTkb/m!AXpGXS#GM@J$1y:w<8thyp!CTtjG%:e#^Mu=w
jL#D=/ ESXyR*cjD?=Su1\HYZ#L$&R>E%@hkXFX&anJwja+KF5=MA=weTA1^Z6kaGIt=cVMilq>^%MjehCGG#tK
ERlWXN lp+4!taPRXk#W^HeEnJ=:td<@$1=^<^$FR/A!db$Q:Gi&T=##&uuyyRkJqbN&dbqItA/?V4/Ck/MQ$A<
+Nh:P4 6HHwXn@XaF5B>qGh6E+G^nDD5ycD+&<C:*LBQB!QDDa?X\JaYNhMQynWI&MPG?Mab&$bY?R@1lCkMqM$
W=i:BR l/y&h>HkiNL%6iZ=l@:tEWH6!ndRh#A$Wda1hHj&bS5H6wudq^kyyDJY1a8&ySFql8V1?l5+nWW!y+tD
4jnYQq HcipujKkWR=qC@P$Kl*WV@?4<l6Hll9QK%CDm/h$NAD*EbBdq>HcnJ+HH8tR$wwVD!hVR?5<RY+F#ehK
Y>F5h9 Yh\cpB8kZC/d@+:c94PYViSb9&#F\ZhRHA?F1SXqG%cMm#<HJheW!N\qQ1J5JcN51I&%M45%IIccS$D9
:D?i\^ M?RY8@tD#9B#GHLdd*$wt?QG18N*jNpaAhRiyyM8J9+dFQacbh5=4#V&8uILZ9+F!G%D<@TdY@<tVHj&
Y&i:SN :@Y9wqKP?QEDmPAM?ipjRXT@A&9>&?4#^*?W$n@DZl:^u#<V%9uVwEd#RQ><E<AN?&6?1\wu/6FLNlq8
KH8G9q 4hTj%nnHS!Dc<qX:\W!Hk@tNGttP<>^mR@eDj\c*Xn*NSe@*Q5FAQ@y^pV*n!n:m5jTCM5a5?F8RVh@5
Nn!GXm wHuwSD=YaXQtY@!B>lT&^SHcw$6W6P1^RtDQ8j&6H:>FS/yb6I<@6dyNY!t\qHy5udwi=llSh9ynY^!$
CiD^^u :PTpcGcuJXSY!1GF!M+amnTq!YGc!h*T6lh$AA<5t=ac8:&QD#$w=9^K?@T!N$/?nd\+:K>l4u=+:hRj
dPwi+8 8p91J?+QWREnL=J\nbWq\w%WtAT^XGWC6ELtSX1WhIdq?QmM6Y%Kc*InwdJ^j8lSwitua>XP<TYPd<^M
CJlc#q \&d#I688R+D6W%HH$K<FQ>!6q<yI/emBLAFDe@@6jw54BKjRIyPe\/t84c*IQ%LyNd/B>aaiD@G9y:6B
kauIXj wWu\j9jQ/:N$h*44Mm/eTB5NE>GBD/Cj^+Q=m5\9jXLYM8WaHWl\mZJW6PIZJhT!!w15mbXJb#EalhJ6
lCd^qP S>:>RI8myHPmdM?F\*1Yl@TLPi9q@PXF#b\IGI@NVuRe<LtNl=e*iFaRbiP+&LKRR=ylER\$w1uG5P6E
#+mM$m C%GtL88wZJbeQecB&4F8Bb<^:d&y#YHB5^wQY5PP=B%V++*d&9Jw?%:WmKEI8JW5Apc4W>*N*h!8:YNQ
YGndwp He\<GNK>$@yaK$e!p*Yc%ZRDen/pCI$5t\+eJQR+Ylt48cX8ANVC>p*cIcJ1GhK4c%P*C?C*95pVN^B@
y?=?>m M:+?t8H%daXeD!@5?Etpnj*6F8&D?tAM!K/&4!\$T$<P9w9wIR#:\dpXcqF=Q5m+kZ6V1/E6B=XE4hX%
i/a!w? VePdZD@bNc$hi$Z6XN5!tm*HTmp^K&>1uG!XD?6bqku<Q86m88ILbL\e/lFC@/1&?5E<uWVc1H^XFDS!
PhAA#A ulX9?F5bBat!n%$dJ+wk8CT%ba^4K8:FLWY<GSm%TSGGBbMABhD>6nP!EGVakk5=6XWdS=&yBV&qE1&G
H+5Fw5 tl^LLKq%:aF+@#J99W^kp!dFQW6T1A6TK<:#^EPB+@i$teA=iyk?VmJ6htunyP%cykd^h5p%KQXVjW:e
u#Wha? Xk++E&uq=B!ZMG*CK1QucP$awYRGRPq\ZFAt!DIFw!:L1i8+dQBhhhjm=VAHJM?VI8GkP*L?!!^PSEu&
@$I?B6 DW*QB6Q=cZC:qGjVHaj&TdGNuK!pq*Q4:aE*$W>#&bud1wHbyVV\<RyqZP4&*m%&GFuCeFk<dM\WRT@C
cwRM?E y#A6XGWaC5^C&F?\LjAblM?SjW@BZ<HE9je**uKny&yZwbGS6VbPX^ZYjeX=pt>d/nTXp=lZi\$>4qet
tG6#4V Gk1pc+R!$$KHbYJ11Kq:4j8cA#TbqE^ul*c8HWq$aIw58C9W?^F4YTEMpWHEMC8<AGpw1DEeiR!IHQN>
pFNk\t ke!NHL$eP8FF9MY^#e9BnS@HL>Hi^N6^yjJV?/Sl*XZXNy??6QEM&qZH?nmKy$N9^*ZN!pSLpC@unm\h
GY%hYB H+^Gpy&&ZQ:KLu%L:@K$1F@Ja$#8\@VP@aCSW&8t!w^CeBin=hi+tKdpA/ctNm+W%MhX8N<Rkw#9eS\l
mh<\wp ?9J=Qn&cBFtYL5TVRaJYk9?6%Vt$kluIQJNPFuVp$R+k<6GckeyTqkMIqh%=ypVSpmI9Tw\5H1hX8TLd
V<^6<< X1dZP<epA%Cb$mJPPWmWdMMiQny8?:kPwAKeBq#5p*eF+KMMCl>a!p!um%ikP@:W!ZXG8P6mJ!Fq\V8R
L%=iA^ %B^#Rw9V@JyL/P8TGZywit4En4thK#m^>lBkKKL$+b?MFFIH>pJ1i!nwM+Fm<XDaS&@TYw@=jYlEP*CI
kdF?WJ K*YPRWyVa+5MY+6lJ+Fce86cJeQuIm\?ZQ1yW^!BAa/mPe!M>uXa#MkP^%h@R/8#5@y1uCEWhj>kQNME
%XHDb: B*6E#$6ZYL%^Xe*J$hV1SDF:X?cj?wM@kVQW#1VaI%GbF/n&W>?Aq:hu*wiC@md5<QNL#NQB*<m#?4eF
VMK!qd 69=9%ieQ6/SY@%MEMjXHm*MM9Q?9=*uk$H9>?%$JA1DXN4Ga%#:k*>dX5HV*C??uC9C//tZdHhlu:Am5
M^>*SV RWj56A*9RIM9VYi?D6L9EC>9yYCLbX!h6wQGAD6N!/9Zda/E6\P9B5nQNe4p5+QKR4&M$JyZJiWJ=58d
j1wcLK @*CDe*$&\a+nVaGF?yeq4EI9iH9pYc6lGB^j:WFKCt6tXdJw!iQC\*LI\I6qCRiutt>RN=R#B6^kXN@1
t?>V=q p?c:AAqVQLDBS==tEYXyed9S1ycSEa+nlkChHbwkmB^j:cE?YNw8L9DuZB41qNHqjwtjcjT5&mN:\>8&
ya$F+N :$iy%iIT*C+^1#y@4E?h4i6iTPY%CcVdeAQXbpqH9pnIER9XwpM:eyaNLQ?t5q?YS^+Z??mLnK:!5Z&Y
Vc#$c9 95t1RjWmF>w?qEClSWPbCGZjD#Z!Q>GN/#tGZ@&yX<Ih<nGSll#j+BLh!6y/Y5\Cb<VRwqdE<T&/**Np
MZ@IM+ e#C!#I1+TGi/:JFZk<\TcRJ5+QTewSSDGAeq1<?h<Vi#VLHRdX\6l^i@h4=6ahk*VT9Id6X#P86QNpP=
t@65hJ MDQ8Lw^6#DIW4een1GI<PXGqE?w1uE/Bqb@LNE>EN@n/4DhA&w4t&6HF=AYiu6PKaTycK>8BQLWV@kbP
ddV\qp a#t$edhAtG!hAWKcAb^%<l5F4cm:T%1*bil9<Lb>>8=CQT?ybVM^pk1j1&!S\\MyV=DpAtpclM@D5j1$
C!y+mJ D?k?8FIT?NMnPF>&hTiGSjYtF#MiY/@+&#LptbK*p9ER@+wZDn5hjTARX/!b1j@LMBGLT8b9E/Kj*lqS
PdD8\< uV!1ly\:nckXwA1GSCht!kBCJK5eSQeAkY4uBRak1Z1y<?hkwLILpe%maJCDEca+9nIaB:8V1K1kql?e
*AX+*W j:P?ay+c$:^lJ:J54Y/mk6+Jkn$@>Vh!R?iJKRhLVYN!T1TXE*tVTDy#9WeMAV1#=%KSPMm/8VpP^uu?
MSH=1N Ycct1@J$iNwmKT81#&D4ATAHP@bJE@JenZ/RyGGQ+EGYD1PS+=4j1b<qkpYbGtHHJt:cEKVVL@a6DtIG
#MQ:9^ B4C6$p%6LjQGLLA/cHV89=yc?V+beb$6BK!5dw6:PnqC$wqcb/6d%NuqKE#Nu&pwI&y*cFw=h^D%K=Me
H9#&#T IuGce>@aJyb%qk&La%u*cykd:t@n%6@KSCu1:FW1bhJ?Hn?n8D5%iaB9SXRpidG^d>HwmQ$j!mK@S$Yi
H*&<M@ <=!D&#LpyM@#D&^LRkP:\u4Ph$T*aJ1c1Y:m4Em1X9R<Q5K/ehA4S?V%NW*j!9G9d>edi5ZmJ&:Zq&qa
VW>qpb l&q$L?m>qQXDJMALh<G5/EGhSwLtjk/aF6VVXR%BL8BHbH@IGI5cWdMbAC@G4^:1\%*QAY$uaTw4:6Wm
p8QNpA W&pE&iZSyby\/ul8EdtBeKn@5cVdSwm+J=Pk1S%bT9bh*\@^Gh=+P>$9%m44pICEiai<e6Ii$4A>VZ@$
H^XRWi aWycyHe+%keG:y+$wLIB$Sp+TRJGQVb5/B&EPSaIpG?dbJ5ihqc%@5JNkKltCh9BGwW?*ht?FjJ&etY1
#KD45q yHHnay#n4Ipn#N9/5H+D:p@h\j%#Zl@Ri?:dp8NF>!RJE+9*&:1M1EqA8&Q5>^II>Syni4%<A?B:wS9\
$EuVt/ q:Bb5h11L::MC1e#Ha=tXPtpdM/d/p4:\ZH!F:c6tIYyhWiSN8MpB8&tSPnZk4@p&KDjYJiD\jZJu@ml
hwq$ie B%?Va&@6N<iE*$F6hmt&ah&uQa8$HbRI#@w=Q@j1S@Q4u9$yPQAp>QQ^Hin^FV@qIbjCH!VetD<iHQm#
<Wp6m> Q9GiK@WQFYp#@<N*?<jX=<ZE?6iuE>W@V%u/m!X=MdQ?I5H1>\dm^&iadVw>JSD/Te*YVKLHNVcC/=:t
kJX86# YljE?Ma+@G4%H#KY9tkV<\4N?<GhjTdS$Zqn9NqeSqEECaV^Ijn#uQL$tPd$qLH$R^hd@#uqMu*1jy1l
kWWHLq 5hE<#M/Ge*q>c/M%p?l1#MGP6wnJY$:eQ5cQ:LIDG&=*T/&j>+!qu*4a?5?i5jVa?%dID=lMBQdKcjWE
:8H<^Y ==*e<G@bt*$t$hAScWFeDAj!B&aIEk%:mKehyyC*qyh%n/\Gy+YVyl+#qn:$e?++DA$1RHVplNA6B**P
p$=8>F YM1=FNcIW$/YKXK*@*qCAPHHqy&^/8M1D%w9Y!bSwD6SeE&a*&GhNJ!L/q#1=udQp9#Pip6Imua4565h
Gm*WIC L5R^jTp:1!!J^1FjLFA?ki!l\G@B5yZ@aS^y!&Y1t8B!8%$DyQnm*iERTIWZ?hlD5lnCEPw#H*A<bSJF
c!tY:j /Bl>:k1ZtyhnRVqb^:m\iAn=bk&uQuPJTajb1Rd6TWy=8#!@qB!8Rtjmt%\1>ujJV!^R!4Kw4DquLAZb
Vt#JA1 pA4PVAe8N86>9cyQD!ER*#=9KuZKJMy!ZZA+pcSDihW!@n=*T/5Z\+@m^KRY\M/wV$qK+jKIykZ@AiYS
#6FmQ& cXcFIlP$QkWQ:D/^I$iunlqLGhy4thiB?nB6mCY9u@8duLi\A8jKQ68kW!bSmK<6@9P!9TlqjPcdYybS
1wXIqp Id&wH\A1%4l=TFIcp46VkT/tqu+YZR8?I\k^cwWbZBYtLYPyG$#4\HAT*C8%=%Aj>5acy!46#JQTL:a8
lLIDK+ 9HmZ*uPb8k+<wy%19DLQVi&dKM1VtcQ$4A8@a=@q^H<DFJiE>KwSR+Rp6ZX!:b^IF<1VB@NmReE?bm!F
-A*8?F 000ab7760b200110334 Page 232 of binaries2.zip
^BLD?P a$+6%Hp/ukb4%$8TQ:VQIyP!=tAmMBMRA8R$IM@&AH\au$t$d8kyA%PbADKSD=kk$cqG@$DE+kk>whE+
TwIL>8 MlHbK4b<S@+d9yL&%GHckew\$$eS6M8WX6TY=JJtSe=Sy5la&1+bT&HjFN^%6BAneNFqik:E^AHh4YD$
C4+AGH C&lVGCbBWD^TiljdZLhMwy#!%CKJJJDeEcqXWkQIEFJ<bA:Y8*9BLy</<yT^FF%qMdL6Ej*YMc8LnGaH
mk^<:% bqNctwY=&t4NYNy#L6NiXNA?E4/^IIZ=d9\$VwAL*T1BwXR<m^%@\kbyeH\tWVLDh&GG=ucJ=+EMVy\u
4?:5tS iVbNcauR9qlw58a8%ZIZZ:QG5b4QGW8dICB4&TjB4XZ6JYwSu%w*RT#yX%DTpE1l5uuKYEyFw=tkTaNL
\<n8wl 6^kQwd<dQ/XDb*ncb*>*1B?5N:&LZtcB#+6k#JRl1/kEDN9QCXttKcaTa46u!wN:IpAHNiPW$$jHctd?
:B8Q$* t@Z<6:DqEL&iSdPt58qw5BnPV^1&JjQTbqCX?C<AFBk4$dLpQLc6>G8e$bZ:9F9B>W!*Phmqn*>iqQmp
iu1M## B6wuNl%hlqcZ4wc#pGJ@^J4%nHWeM!<c6?e!HS%\/cL!HA4mbLSGu<dW:nyc>m!$=d@qwe>6&6V1ij=l
9Du^>V LeuD?5A<L^1^4NS/b<wwJ&jCMS\MF<Du*/LTHNTPN+l\ZLaHJ@:dG9&lZJCJ?!IHkS#Q4GElw%1@P?\e
lFG5dG Jnd=d>aH\$:m@dSRjLq+ZE>6#Ju>%+yndS#6@VaQTmtHS^#98iPeJ\&WeX8@Jaj%Y:ubA!^m:Jj%&=@A
Qa*9Vh tjn#PRNDe>@Y%/8@kQZ%9VX@VZZ?a6:HS1I>wZt@H>@%*$bhD8pZVtniQ%aL!:#yCj<GJ64@&ZS@LhD&
iMaQ?k k\Lyj<4AeFL:Z\14^:?TXjaByjqEt#X9$V*%#ekcZji@Fbj/k:KbR&JV*y</S1&j<Vi>GhBna6PDFJ8L
D*ScLt <4uEkwMAh&W+jd:M!m!/ZJ#K\6d%u9Zj%8?9@^*9=6hd=6X&%J:a%HACW%<=q=jW/m%c^ywNeu8X5hVZ
aCm@pC E+EBnP?<pI=dQ>el6JMd#8B%ZAGhL%6@4:EZ^:6Bb*e4&:F:HHPb/41tJZ%jn>^jwH&LBFEL:^$m94n&
99<PN> mR<+ZbVLYKw*@VbQ:4A/>EmLhpnii8+w*<b:@1EQqYKWn8Qe9Q:d+C<Denj1aeAjqZJ@XP=8%Am/c1X=
c%dJ8y Cyw>JVcX>&6J#6:qnpTk9CWhy@iIe=t!WHGA/:LlMYQyJan<%m^WhYP/C8uunBJSeJ@AM5G=w&Ld!E=&
NNhc+# #\E:YyeRk+HAeh!h>h>EEDTn9PR/nIKPjDF@6!nyEV\VFMu6Rt:u8WKubKm$Kw!AW:d=DJZkEtp$Vbkm
@y^\Ab :Kb8MtuHKkj8jeyai5d5hHQ9q4+IHEitbW$4lyJQmt%wdKe>lD!lwAdBc%<D4*cXN\+TT5MFpdV8dw98
4hVN@< ELNGDt+GSKcFlQiD<**IbR1BiajMkSVBQ5tkPJjyC6N%>^L^ZIiMyTjM#mL!$!+lFLE>4GYebQ\bGBmQ
bK>yty >dHkcM1++dnwE>8^+/Cu6V/ha*k^k+nq**9LBV*b8qPYW=eKahCM^lpjW5PTH:W@IWG8PKW9*R6tEFtH
aF?lYb ACVnFKnY?9S4:wF*>Ytd&pe*u9$=i&/jR**k#4ywSkn<HhPPuSKd8k\GnM#NcmehepHuFcdV=@Tqnma*
@MRP%1 P5#PFhF:bF\\/yb4dwlhcG6pWYWQA#4&GXIenA?MZG/jc1$QKFh4jdmeaBQWZB<P49FE*YM8$<YneT/Y
:Id#B5 *iW!Nb#LXCE!uN1HNihQGW9X/DV5aabGjB@wwRDHlDqtFuJRpEI@bT#X\N<<NECn5t#!lN:M<Im@6d/@
+PdLnS wWNTETBkyq#:NCYNm^15M!cjISb\#Y>#!H@1M/kkJu#NT+15K5lq&8W+aW5k/1iMyRwt59PWEN9tLhKl
ZHtai9 *uIFGd<8l<Amu4teMya/ScYS<@YCkX9Ya$uN5Ic@4S%npVSDwZ$RCAul!ht>T*w$WEPAiwAR$b<Ku@QB
<c@1Gd J$Q6ZVJW/L*j^BD8TWw:M#R\y>DbckdbMPF*!%kce:^#q>&KJMt\J1DL!ADKQCI#cZm6pA^D\kDiIYMy
5/q9ea +MM<KjM:R8Y<QRm9RhHX=@al1=9$dT!pwNEjquF$ciwyk?Gm=>#IlFIJJyeXSESPcIlX6@K:X:%Hekub
GPaEyT BIFQWwy>!CD4PJey/&#FW!<+n?&C&Tl!GW9XqMT=EE$LClIXG<b/+A$I$+t19hLhiF&B>KYhF@TCTAET
pMcMkH YuLGXBwa+hK*L1J*SeySu$/IIlBnF$DI9BiN4IWuMRGaK&mi<mWA:ey^A**KW?WmMnATDE<JdyeNJDG#
+iCpH& \ZS&aDl5hLJbmM#DGS1WGtp46&lHZyNkLRKI!/Yi+dH1kdy^*EW^?MmF&X4nFVK$%i5\+*VYc=kyC?ud
LwPue/ qeVE5q??dI#:q%:wuyh%QyjY!F*cMt%1hi1*ZKbA=a!#//e#dA>t+#P68pAEl6:eiEFD4+6BLRX+19k/
qKJPy: Ya?/ubpPc>&\G6\CX>h&G&bMXhb:\nI9l4!8Suh!Em^Cl%BIQ^Xy:^JY^hY4nl$eSdP#1D1S*+Y^K#ZI
npmnMm *>ncKe9LNEMR:*1=5@GSm+9\FdXLi>%/?S+F+uF\^R&<DEqWFH=d$n!RBS+hlGP5yLE9Rm?4^uZyh!/q
kc!/jS pkIZ9PCL#R%L!=*?Vn&?a4&WqjyI/&/QyuF>twT4+ZH\NT!%dqu!d9^qL6pLc5PY4?E6TQbGBec5YQVD
A1w9#/ H?$:WM4V&j^VD/@Yb\u?e#CHd!I<?q*W4N=w8Pe@@pmP/S\K!*yAj+Qu@jpC<\aV@!Hm<QXY@@@=6$F+
4bbh?+ =y>XYtQi/an^y4+iB9ZjLiIn\Kk@\a:D1mGtut#Pj>1:5tSZeTVKH^<P&=llSX+Qt&E>4InBICEC@>F=
*%c%#5 MmYR\H=DXZXEh<X#SNY>j9lmREIwn<+kt5H=QN#!EQmL\cd@EA^=Hu?@jM919\IR!=l^iGFPu!%5j4al
>>adcJ Z/j+$yA9?T8D5R/mGcaQ8RyiE9ZP*Yi9IPkpJFQ#$>hp<MhN?d<<DjN@WDCpJY%D#4\HkwtQGh5?BH%&
*cL4Z\ j?^>5ZW/hQL>$95:CQIZFNCnKGweh=>VmFDZt/GIdy<Y/GS%uF>Nc#NQLVGQKSkSLH8$nVnku/Pi/?Yq
My6j#n Pwp9QWTS&yBTM?<VX:Xy^dTdCID@BwAB\J1iypPYcd*yKT!YwHa9Kp9dMc:AQ=%Q$N>tEC+9\k<#IK@h
?!ctc< t8=^khyKWd%#yXtXT1N5yPL:?tnKSPlSjlSyEF<15@Zdt%h6YTw=4&PLRtF=SJhHD>et1wnCLFQchL>d
YZJ&#% AMKi#*da?>9DBw<nc<eDt=5qDn8CQwPLS>WL1G4#dIqkm9Yd+L@baFN\ED!:ymCpqFjdm&545ZA1n%4G
I6!8l% 1&B!QSVbC&buBSL>dPE=m?+\yWy5NF\<d?$nl?&6CIjapd>$Hw:ZVD+TAGNmwc!yX+NLc1G>Q8ZaQjB*
@1Rw!j VG*1E>\WlJSC6Fe^SRT?l/1<q*B\89eG=D/kY&Qdnt9k>#T^@R=$4QmHR@5\8!J6SIutu\?%BNi=@QNI
ytP9aA mHWA^4VHq?IpYH+>blL4ywaB%ScumwwTtk@HVEFIKVh*H/MPb=i6S@1c1m\D9R?C1GX1ydwJmK=eP5BS
^w8=I5 1>*dS\=dMpL#T9!i9SQqNEJAWNANl5MwNFR8/ZZQMt%c#YtnI?!S^PIJN</4iXa+uhFi*qGH&b>M#S9M
n5=TMy t?&S#jB88&Hw&t/BY^qe6%K\P6WWbJpKkTI?a+6TGhYNZND\jCdet4nmS?t^l4nQJd$G<cXt4yLwh4&%
tZj<n% NS=FRPai!CIWKd1>9QR#!Q/EDJL8cmH1+j=D+tC<kE4GI<XVLuYRbRyJI=h#Y!:e*6?W5S/ZAekNSqGX
dL8FYN MwEPXiCJeLpq9Rd^yVayiel#hAMaQk=I>1N?PXd$:?\FWA%VEFIKnKREEwp8n&Sm1ym:1iKY<Cm\abay
IBA#@K cIKCQGpV6I@+:yZY$<\@WWehFqi$E?HTJd$G<cXCyJ^FAkmZddBX+eA$9=y!b1m!Vk>byt\FCm6@hEd1
dRjj1H WjYc$6N5cGA>D1d5G$S6#SLtLe6$y58#$8<>$@tC>9Gc=:ABacmLiihu\\GkVy#$Clk%!DKh1IhVGe\4
Gcktdi HJ^p4VtKXKKG/eAH=twG<cX4uSW$Cy5qL/pHI1<WeBwNEbw8WpeQ4!yj8Kt<LNQ%Bd!&Vw9B8cK:\&a?
H:DNkk 8L8#k9/G@6wmaFtj*GcyWbA88lTNPkTdYyJdl!8H=\8</K6um$G8E>5:\%@5l=VG+GLVZ@Y$hWTTk14y
\t%cy= 8j48\LhEAK+C>hhIq8p5YcdkY<I1H#+YPun?MA*a>pNLNLjuA:a\AkjPXl:#K:*e$#KJ+Qny^=j11Z>e
GhCpP> m1bJeN9mT@Kpt6nXd^:VY%dT^4K+9+%LLPZ+$n/JutAl$6CSD>*%$k\$4NEt89Y/T=RQ%Ga\1EYYKaia
QH@!M* amtBL8I>y=H9Vk@j&ZW4MbQjItw&wq?*D*!9JG4PHt6IEt%dCWLREupcCh+4WRkY6GLF/CW1TqDbtTDJ
59EKR: N4L9&ARlySZuq1/\aY!HlY*k/H#K<n$wjth18wjA6=TQTbay@c*\LaF?!YGZL/Mp^htd?cly&QmJeHqd
l:Rw8< 89n56LKl4X5BlL9RBT+ITXJ9ybEqP<&:ddFFd8YH5Z<kmNX5YbWmRb$*J1d:5C\5iH^LM#t*!\9Q4@*t
kHhJ9t kjXj\SdBh4ILhd4Su&GuHSW!I86$$JH9HC$&beKJFIIp\%KYTKp&mmZ9aH9b@ily=%91pJbyh#h//Jhn
8QHP*? Jw^>=c8GD^K%L?4VR?F6@HL\EDJ/&PJ^K*h?RJlMN**ae9!d:*L!u$tK@8?AtZ>ZtPYj%=@Z@\9C?I>?
/IHKAh :9hHwd</XyqQ\VF/Y/R+bbp!Z*LZ?%8YY:DlR&LyFHDt6Q@\PQQj4B8\DtC/uiYt>RjtuQ&@&Sc8QASR
BCjB>l jB4+IS1ISLju#*bA\E&*n^t*#9wl9uRHB9q9yn%w>SQ@VX9!#@=wP!Mh^+P!P6dNXuXHAMEVidiDKNL<
jAp99# aNQJ\tJK<1Ik:&9KGC8VkP^ww^b+MWk5DY*W1Ybj$yIZJVpWqSq4^&BVWAmZ6LTtkQd9AhTyaNhP\M4W
99p/:T PAENieLN=EhGADHylGq&ipq!tle9^kSbyl^Fi4>hp:IYHPwbbe$NYcamVL*iW*k9BjGq9Ptc94mmbM=e
=iHct# Wnc*P>dJlj@&np:EN9M1:<<!K:l8A<ulp6XWnWhJ6ail*nyVS8K:<w^wFwi98XAF>a/K%\4WpBFA5EKR
?e\\B8 Waw1B?=We=B!Kl\#twCuGc6MAb^SqbNpw/*E+\!c4k@^yWJ@A=4*/LmW>^l4+uuqb=t1DP1&FYEE\y?D
*+AKt/ hk>w*8V6?1$Xb%CNMpjqlqtuwRWNk%FB\RbZR*X$*TX=!pLMMNlWAD+q/teF+E^Jq1uqjqGNq%4n<CC?
D$Eubh %NK4LJ4*tqqD=&Ic?6Khn<P41I!6=>GI>ueTSG#JWQ6b:Em$q%\:1%4M4ESJYmQ>kucK:/G1i81wmF#i
=V&Mnh T%Yt><e!NKnW@DBW6AK%qqSSC$8>GHES:leP85?:?WN<1cpbuYR$d/1uEe^F*y5&+>+?Dp>pNy&4%jnu
Fdjh@J Pp8/yeZ&kB*Sn!/6=#SctC?G5#d$Y>iDj4Pllqp*h?%RhZFjLKn$\&BVk/KbT8pG@e*QM4Zu\:4PW=cy
i:FbRJ %PL+MF>D5^S$w/R9?l88*whV?<RNwMF=$<HTANKKpN=li#N$5BADn4ABa\WqjVPhhRw:P&p4Rhqc*bY9
1*Pl^< kW+JARh$i\jByuS!n:VM8Tj8?cLKStK\AJm8cbBacl&iHlqM?PYKm:y55u9LcNMcE9XGPHJ4X$9ViTX*
-A+M%A 000870ed3e100110334 Page 233 of binaries2.zip
%:$i=< K/@j/%MMZHVql:c5cncbjDZhGljhDQJakByT1>CbN$tn/H!CLFM$Xp/N>WBnBXttZ98<#@Gq#=I/LeIZ
>l5D?F SYZMlkwGMdb=Z4:LAu$nJP4N<+:hID?tVE5bIIN/i?4jjhe9XRYGF*AZDe5%byj=1CFeBGu$9Jb^*<bB
E?*C@6 5Pp<&^+CmEY!VIGHhaMke*V$/$C*:Tt?qQ4d<B/GRet!GyV#%Y5?>4e>5bVN&+*kh!\G4Ia5E:c<@We=
abBLl& u/y6&/FiPntj61hu%4^mcTlADaX4CAXtY5%B!mtLGMhc%YAP8m^V8m5Ziw#TCD\^p@JDjGqbn!@pu?1%
E6P!BY #@y=A6pc$tPI?bTy*=D/BjGq9D\t?J%lu/%&4S@R@D9!ynX>1J1WHmpDWC1p+NJ=Lc9B:pLW$LT*NKbB
p:qP\^ JwHD9=>q/9C*Bbm*!#LqqST*SjmnadCypneGXDLH^M!i@Dj9&9:jHPJLcbTlaiiNXTRtwe%IAaKd*D4^
pl8mmt Q<4V:JXmFcI8m^aJqqZb>4ZXZj8wIca^cZJq=4kPkp$h@udleEidbXyEV*y+q<t%cNLup%NQ@MST</LJ
uAI8:W Sy1tDclp\6Gel9Ti$9DRQ/B$4lKwndjEW5S!eqJaSu>@#:5cPN/>G=eHaD4XF:epl&MeVc81l>XI*&kQ
hB1lMp Me$eMn/RT#:kYX>a%FBN+n\tPV%B5GtA9\XbyuFdewcV+5^ITT\6JdEWcB+9#L=nh1:6RQnul$VX$1/k
Tmn+## eGcqe<YBy=Ja14i**am>qhX4ajY#RyRDm/4yAPmjF4nYn1!ijnj9AhcX&F&AGp:YR%qbAeXP$DJ#pA#G
8^ee1! yEblXVypdlL4muYZK@8BanLZbe!PZVX&FG+LcdC\*@:Y?GCh&:WekCNFaJ9\MT$#iA=R\=CVPHqR*BF@
hNAiGw &:NM6X6:Nh9H*N@y:b$?aZa:CmjPn6:P*h5y\QEt=XE?uHy/e8yy:d=6etb\Q/FtjMVjQpTeB6!bA=Et
G+ltkI ^P!tRBh>@11k#DqYW+FGPySZH@mYj%=@Zu>i@=4Z*\i6j^q??/W6Q%K\jpQ!\6!?9*RP*8@:$w9Yb&Kc
:QjJV= ?:\P=ceijBdt6*=#BVZV4qI>J9V+P%Cn@q8NKm6hinw@Q4#jReTENFWj?G\PbN6NAjY<jqa9K==bKdew
$Cy4ke /H&In<B?B4K>iA?A?QW864ZB9lJyAq*w=59GePBKqXc9:HF:ywTaB>EYG\VKSJI1*5l\9nMDBK\^k*uI
%^cEn& :c9W98\G8bW+dVH4I8qZ+/6>Q>t+/DC=R<HBnntWtJ$?mwVV^RJedB*V/JI+Yqyh*yL5tVAVnE$JL%hM
wGcYV% eiH5%>%9&bMF!=\LZ#^#&h6tjRc+B+KbB&$yFwSF^F*#lA=XY%LLEpW&Za!FG1tj?wy8i41q^C^w&mmM
\ISy+# !!WTVSaAmE!6A?!ZA<Eu=FXRmIuPDTRP&D\X?BkuPt<F@:kMI:c\1qq1HmbIKw<QabktS+YNEyweJyKT
8k:bFK tKyaXA&jddFaR^l>E8$NlLPbb/c#iYC&G8J=*e+I=*NQBN?A\K8uw*+*^:wi4q<NFe>5XwRi4$i8B@G^
@=j*YK Mc/uwiGRS:kC/ZGYLiAAAlJt5#FyjDBueP<^TwjAR6B<6Kw%plySXp>YKY:6c1Ci*yLV?G^R*k^#CGb*
FDBmRu /AJ?G:t:te*n1L19EKl*NmndVA=lFA+nehbiXw@L:Z/LInGe^m*8yHpkA<$&!>AKaaTN^<%JSV/*1w5l
jm=C!q EHQ6!e>CET6wi@9Sq\K@TN+k@VmYKeQn<>kkLYRXN\BElA^1!$metEVVHuY8#DAy56wT8hBG\ubc&SmT
y5Al@I iV*MnnY1N5KKFLKm68*n??i\96GCiZ\=/>1\%qGJC?Yw4ewHMh*Y%k$Fh*8>IjbB\iQ#t6!5dVe8$NlE
jwtIZJ !aK^qI<#c+Tu6$F&b^&!MS^FcH*RkYHWDcIlcJAD5cq8LN%L+Ty!DR@n@>9dRpK8mSt/bbi6b>+WGA<W
K^PcNI +qT8WeL/TDdInI8wEW199Cpb\VB%t\DMtC#F$4:pcHBG=d*kaSJ8aVtm9dYFXQYt&@WM9ZBC<<whWXt^
mV*5*N +6%TYMj!VYNlK+4i/yE$&a*lFASmI$EX=<dj/5nkm5hS=JLmq1HB+ht614l$586=8EAH!8Pd><aM6N6y
aaeK4h SjK1Z\i#C^n9Mcd6Nh<MhKAT#5yC<>ttm\a<XR/uaELhm*8IbkG8=t5N%c8TyE1/>hK!bXwQP8V:ZZMC
qTjRES Jw@S$FK8ALquGjt\/IIVYquTK\^bSnD$$4qeSi<NRnZVc<bPnWb%\wMZ%#uaMZVZc!iiB#RPnaD>tanM
^9ht=4 I=LleWm5\=!BuDFdNwqeA@8:+uVqh8n+@pGD^8=yL%b$P\KBIX5iReAVAe@Iq:L1iYbHT^*MD\JmD8Kb
Y418A& <SS<\K5StIq\+AGR#Hn1kaYF6nNDFY6a$GG5Al4uqNA\C>l!TYEJP:plDbPh$h:uCtDQ$LcIy?V#+j^/
Vdk^Hq YVyp$jhe%$K@YRbwV:FeatV>^&ciaLDD<p&*<hiCCiD&BkiEG@>TDCdwd/dHEkmdPW/Y64TKk!:u$&1d
DqFG?D V+5ql/b6*W$C!mB%F>#Q<>n*uDuKbE=$mn=L\b*WVLKh%G9eQCny=8EYAm4+W9XayXmFw+GlBH?Sq!=a
5JK8BT %V^:TXRthG9&=8E+I@BWLYamAItPa&QQBqP^/uKQXjyk/mQpDw?CRZiIbP9G=yLTGE@DGW%pGyt\>E?/
+uV4Qc t\9*cIJu<EZI4VN\8WT+?#LEZ+wW/qmJ/:njSE&A8=i?l+eNyIw<u$Y?jI!!Qp$$ccj#AZeJw5BM*V&m
1J91GF T^4Lel@%m*jKm/uA>6b%!!YX^AYi1iI+1S%&HV+9BA!dphqYQQD#jYlTcLP6nNj=:6H%wi@l:AYMKE8#
qBa9Qa :?&ubhhJ=BnPS<*KHeZJuu\lnQJ!TZpq*#kb5h=T84ihjAKJ?Qu?Wbu1!&4+R:?PMj&piNAdNLnSGj#t
/td/q+ %h:9G#<#?NSQ!4a9i4XA>1V?TW*d\cH+wI*?Wn8jc?Sjqa6>414@CE9@9Q+mwQLjyH:>1/mh9=Rk<+<e
VItV9e !5E:<%i9w#G@$d4cG8#?P9j6h<:Yp/%lJR/QZjWS\95E!HmLTGd!mG5@iqtH>Y<SBi+4aXH/A<?<d@t4
y8a@DF 5l^qu#A$9<&<&ewP+YGYahVu6KXNeepmHdX?#bjc46w/QD:E%^$\8#X81&??5TkK+\@tj!nB6yJHjE1R
ADeEM+ dVdK4H1H<FA/9&k&M+:uaNPh=PLd<u:5IZbKk1T?I^l*\8^RhDuN$@E4kVBqWcbPwqYkF*\?XIBSTWP%
SBK:hA RwcXbcpWHaSHJRDNaT>SZ4YZaq^QP&i6EKA%KcDW6\8@*b1+m4j$$?h<#A+k$8ieCX^C*X\chh4IhX=e
&Ray^K q%VeRATYS6em#=<NC&CB56H$jEl:&LdV>a!V&*IPc5ZS>XK<?:Gp+WytEMHCX!C=jtyIEH&!m&B&?u5D
ZAP!?H dYnp1d?6c$YZ6kNEw=C<PXJ@1>MT$A6k4diSPyV?l+yB/F:u:tcN^:ZEp5/dXpR=R=R6V6M!ahCSN#D8
+$6a#\ 8DS4=>mM<9XjnKV%dt:5D*WtLyMp!^>J%6G><!w4*cY%iRQnWqT?6dhiI/1QiYq#i!515R4!=+m?<DjR
>WjGjL at5tQ<!&TeCERZmA#R9hK*HMepi%i/%5hpKcG?n%5aGP<hudmudhWe*ZbppP%5R$an^w$=RbLp%T4e8N
9bpckJ w\PwX:hX%+lqa9k+>QX<kScP&tCw6FqaG5Q$ApnbNy8cdSeB9uMc%>5QKhKH?G#DK#GmKAb&VcZqRN<$
jlXh=D n?kGuLnI#n?tLm?Zq4M@8GlL4?$/*A4PEjBkD4>>R1*mc8mKDEW8pR<N<K+<#X1dl:\><kJ<=%l^1d:@
?eXZ$9 WB$G9EGPiqcGDe:a*>J/!dFDRb9eWj!Q4K+%1uyeLBC&Vt*GphD?+>A>jc#nu^FS&c:6M%X^R&+$H6N6
KetL*w YicQFH1$<KlDjPh+%F6K<GpMY48HTAylcHehVH46GYaAH<!A+&Xa1:\M*TJk>9TPwubYGi\!Ma\&9VGn
j9e/># N5jHwYmZ$>w8KZn*n>JnG$Zyc^L8u$&LQm?SjP%9W/DJ@*+?Pw</p$a6DVaR4%&8X<HkESRcL??BY&61
>51l$j u5P4KPmCD<4a#IhXXAHB+>B^qLhwXHhBMjyHn<e%!q<4?PKVD5aDd*/mNyHd8X6=MPnljQ4>jLKwMp*E
J$>:k6 =k+ThLKIFeE/bHudqZekRZH=b5\PYp9B1@wZ!/1XjS#c6cuD<$hI8SKAE4@mMl*wi5!H<jye>u:Syi$#
M\dy4j 1B?&#=QcJ+6KPb<ZhcTBL\IV6C:SM\j+M/cbYe6ea6T=DY/Z4ALq:LA&6TeX1VAcA5l/pdmA/EPk=c>N
pp5SS\ &9ZuGbVNdiWFAcNuZd%n5#BH#dYQtB/A^<mhdaTMM8Nk<T$lXLI<6Z5e?t6VuM$>m*88=>aJt$K/Au5K
a1VJ94 :Y>dm8$N>H$&cGi\M>QP?QQWQ6^jPGPpemQ?Y4eYyN8IVtyZ9<!:qa>NnJL=6hn%Yy!dPd+BF?B*#$ec
9eHLH/ KQ/^\>8ph91cjTC4jedqED$B/d:X+5hC=$9YZ&m>>lh1dLcGZ1d=y<Zp$d@5$:Z=RXH<6/pu9*NP@^Cm
ER@DNd >:?CyQ$dEd*@AFBLA\RWAAIACAAeXt$q#9\k#H<kAAA&YAAAJkAAAGN5cYX8hHM9eGh\L*hydnM!L%BH
6!i$Bn WHNnL*Jqe!>6anl+MVR8at%\#F5>nQ\&hqeAA#RRZ*B@#a\4N*EX%\Me+NbdG:kmB6K=t+/%t!6e8R+a
CGW=aE \MB$X!SBW1S^4eJXmul18+t4K\+RTjEdEyCC?V%T$tltb@^*Lnp+8#9:>qET?jml>*6j?<tu9@t:yu#>
bBRbY? =y&t?S9RL@H=F*#?wut*Z9nd=5uZq@ZtL:?5lL:^^:jjj66<?=@jN9a@@4q===%*tujjjdh=::**tnh9
@beb9Z *nV99@>?<<EHH#Rjj9ll<>FHH#Yjjjbb<?tuu#cjjQJJ<@HHH#hj@m+*9@%6d9/l?d:J/6L<?@it?j/Q
N:LmE$ j&#?@q@@DTMe<Vule<duW6pnjl*ShpVdphy!9iYE>lQ?PKH>lQbV4w?h$Z=G?^uMGi*uZLy1Ltm@wQ&C
b#$pmh >k5cLtnQ+DQ+jKqDqi<VQth<1C*Z+jH4CBtPpPEIGa/RwakEGa/R+RkbnyDlCBtKtJDlCBtPpPEIGa/R
L=j:VZ wakPGa/R+RkbnyDlCBtPGY&R+\k=nmSH#uX/SSL/Q8N#\TjZKWPYE\a@acAVPn%Bq4IM8HnCH!jIewI5
5q?/#w bXpk^\q!uCDH/W^68T+X=DlBllNpPEEGY4wV=DlBllNp8GC5nN>qCVFP@d:M!*55Ey&Q^Pi/%Bn:DJuP
k45m15 GQTMAe/R/a!^#:l+SmjuM@YX/*cW5hGP<e<a@+#^ca9PGQ>M:bDlDBuPPbh61#6^K1PVbLT>F<l\\ZkZ
&H45+b !HcBHBiMX:cY=MAcZCDHliVA^My&+/ELbLqAqk8E8GDAekRk!\WQZuDVBR$Z!ELH+pK!aE<8pPXC/%Fp
V=L!I% whNA8*A8S!qDlk\bMtVIpCFDluKeIMMFMtVIpCHDBVKWI\abMtVIpCFDlk\b$DW?cIeMGVJp!JAlRMd+
@#jp@* F*TY<YDGVceV:SH&MhMa%Djhe&4?89tu=9QQQ&???PKL=1899t1?@944=4999t8??icd=wejjtl?@QHH
?^!k&^ =k>@?EQV>**nuG8tcY45j?ZtH*@@i:#H>Edu<6NR9+YnjwuNnWnB^@Du@@IR#M?$NM^<^Dj>4J?Fj$ZD
eb6E84 c#+<89/a^yS#wn<^/VJW16S:F!NJ+yjQ\45a*C%@R>iJ?iZ=/FhK:YFDjdC1=!bG#&T4dL#!Q1ZPJqBQ
l\F+ZC w?N:+h>CR=YY81@6MZR??V5c44#V5p58YKthy*FuQyti>*^IdLhu=1Y*C@<&mlYMbZuqZ9b>q=KXdd?Z
-Ak>bJ 000882531d900110334 Page 234 of binaries2.zip
/N^lGS :lq%PW1Xww6C!ldNC&<up:NRLl8XktLb15w9:T8>c*jSV!yEF@mdAd^Qw<1P5@!M?5SwYB>qG?n?lVec
VCyk45 B:FVLAwX$Ze19FZ5dVVR41ea^yG%PmkVS^YhM8pbVb$!iDa/aZ#EiA9QIF5&9M6t!lq#LQ\wdY&j/V$Q
w9q5Lq /uZL?*dE<#a4HCqc9+l8K#ZyqtjaN=$<%ne1Yj4LM=@GX1p*HK6^pB\LR9#WRq:SKpq$ZPl8A5%L?@J&
6\AkKi wX%Q9=w!&/p5YydbZtY>a<Ru*Sbc?RQQ9t&:PL$w%b9E>n#=h6jFaAV9l?S5:pd5B:bWKI5Dt+by^K5V
+hMie* +#CP8A69%Tl\pEP!akVF&/pW>kC<Nw:&JPJF\C94dPjwQdI&8k/>YZ\e1b88R/PQ^4AS@V6L:#FilcAQ
8i=!NR HH\cyJVc++B/MiL>RQ<VHhMaVh8#GBKdJ4wik%CV^y6FR^WFEpt9SN!1NQYaA8j%8j&P+dawPNh$Hi$?
\E4Ge\ PhPKuH%a&qNp@e+pWmKMpW\?Y8c1u4QG$4!naVG8%>HMtL%Sj%WdSVe+Wk5ak>qaPl\mNhm8w@64i&AG
yGH!DJ b:Aw^Lp>+mWpBKCyqVec9$1HYP11btIqcd$i+/%/udu%8Zy>jt/>9:cu6C4q&8:hnD>?Wc4?1qwjpP5j
P/&QTP *6%B#N$j@lWG?W$9X&D/beiQX@!/Z>eaH>KFube!#m*q4G^8ZQ8>:!dehE>9ZAYT+N^DG4h<ae6^<cPt
lQ&J?h A%j\$FXe>DN%G:yb4$e$+5%QhCJum9i=<6E>ymAJE4mW?T=pdF/!R<ylT:5Nj<X%Z*jpnw>/D*!c*M?q
N@>StA R:8V9JWM8Nb#cYL1iN8*\J<uNJy?6?N+k=>R$<i58e<@q\L?kGnbP+ujbuSPRy<E8%B@S/GQpll#jEw>
hGF=ym \ENKKMC*W$&Weh:8Y5+GNaR8akVia1ItQ1M8YmZwJN^T9@DR&p!l*>jWQtqu@SmWeFID^:S*E>bBTcJy
*=64Qm y9tGyn!KSQQN+@mA\l+SCwbE%HKWSME9hML&4d!Yl8/#I=bBKyha4+AeEXR1Du^qjJI>$X=KQqQ\YIm>
/chkH5 IS8:p:8SKHlR6:RH*&qheM>I5kina&IpA>F*ak^wD+M&kjR=B5Vyn$b*BA^R=!QlHmReK%=cSZlJ5FH\
nC+1t: MkYeD84QFhlAQ!\YiAXMpM4#BIB+y%MWbX>kJST<<*wu1j6BKcqJTS9PITkM8aJ4IiWaCSkAD\Z*w6MX
#TpApP L:&Wn9b#LHkJuJ\IJ+F:BcjSQ?@y?a1LJHdB^XD\n6:FkuiiILKnhX4\LkD9ZMF@R?6V6G=XIFX6aeE1
6KnmJ& D1j/QD$a!#wMBThBji&@+N<hL5bZ8LZCZ5E:9>1=4@Zu4MYi+PYKd&@D^Yi+eh@<Gny?J8+<8?=>?Q<\
YG$%j! ju#h*+^4Fbmn9@Q*9L@#@^aAD*j4GY/BQh:Dah&ji1VKZYRCFZ?PP4*/hR@ySy4/Qm%&$wc/ljhdP&IX
?+HtWM c+akX>/uWI=pPb>ht8&*u/ALjtGI%@jHB@iHGj<\Y#6Qk<+*c*i<X@BDhm@G66BuA?eei9b6NJSXRlh1
$>IRWn X@&GVuI?Qch\k9a:kct4k@Rb\m9kA@WH@!S^cAkNaG6FkBWN9W$?$$!uP*/taaAQTm<$*$jmw/b&cQRu
#J5CN9 qQRe/Z9kMqennQaP:1@TNL:LdGL\$RaqS&9kuWeGQ/@Rmh*!%@a<e1PkEI&AM>yJ=4XIAb4\GaYKL@+B
+P#tyq eEI\4wEdp<6K\P>/\!*<RThGLa!k<dHGbb!jyC=*9?abPp<FIIJkRR9+hmI8%N@^tHnQ!Y^m!tiGVyk!
I%*I+% tuh%@pb&#p\KmP8a/tmiAF8e1p49?WLl9<KQl^iN>hBe&WDYBPcJ8Xc/+SMwPjcnAuwM$yB9tAa6i=M>
tD@P8J eNX%9RbKABaFpEhNPWwk>pyqn4#T\K<<Fl+mhPW?h<BH1SRtHauTTwNG9@CkWjHk/DpeiCt\@$!l@!/#
pbqVAJ 9kY?\T>1JV\$PLbP>d$te%V%uQ\>y#kZSDYZ+54VHcV\eX@Ly^H9Wh8^Hi<1:WF:!%1?wV!/68?Cd4Hk
IPn!4q FCVTjW9+tqLK=Nc/aXRDDLII1\b>8?!+JndC:CA<:bmaGAH+wDYLSh@R!\<:q?IRQyA%tNB^D6MI?^AV
@hAYD! %dwDX5P6H4FMIZ6bQM?W1utPnp9<!hXAZLS!Ipedlm8/J?&TnB#I48n\i6M</V4bZ=BuDLMnPK6dhPAw
ThwbQc 1AFFCAN9qI#5QD^u$i^HBY8NGk!%B^16/6&W15/6*eTem$PDCX*>G%<9qGc/VwNl\hIeRjVdECA>X%#W
LCu#64 qJePc/A9qZ:4DX5a>#e\@E8NQ*hA+aV1EAXZ@Vn!y5y#46D%i5YN$uG<leEbN??iY?<Q:na585Bj^eD!
VIbV1Q 6K@\XQn!S&qjcKm$:DuMKTZbDC4?:4N6i&AG?Q9=#**i$9CV%IY5@kw9TKmmlu6cS4@*>^ceh%j@V:?w
$!cRFA %P*c:8hT<<INQ\C+*MSXP#uLD#*jej8M95*@5<JAh+*yPYW*jFB/NIM\$IQR1dnaRY6a>bT?#j>L+kCH
/hAQ1R D9/K&D?l8L:j<P#\SlutKaSJmkj+MVBDeiTb5m5@kJJ@IE4MADT?yypJ^?AubKbui5@j$tT%&l</VI?X
S&p@+k %\91/dA#?TpF:891:#&teKPk#/CG6>R<wTP>*cbZRq6L5X%tLPV1AL@?qlwAa?WZ8?M=NT<>6H?qFFMG
/<Itkl ldd%eccF*>!Z8+MeMQnIZiae/<%NFyQd$kSM4ZR1@4d!aW5u=Tk/W!uPaY6mwZ&qHF+4KAQNM=@u?+yj
BPKkMT N4b6Q\GZhN98XLC\Auk4AB?:tdd\k\8XSGQJF<AQB8YFp9*I+pIJmeqQhVuR<yK=P8J$\>$jaKGRQ8*M
Z$K1a> CAeatCpuCq&YDA+yauKm!X@M#KV5kH9KbQm9Cj+#DN/aPtMGM4l\9iAyZTe<yi6^9i+yEE>=Ek>Q9/N%
IQ4NX< :*1J>W=YTnna&HDcj+4jDu9cn=4BtlZJnH8t\CkeYpcS1RG+F!98\e:$<*Z$V>hB8uw>%P5qAP99<Kdw
=PF&qV X<!!S6n#kl6^>X68FH?ee&n*8FMVZlYZ+8*%EwqhkP<ZHu?PZ%<BdE$R#qk#J\wZ9<<:j+M4K\:/8cQ=
RDmqa< ?RZ*bwZ9q^Rp>Xj+Yb:=!<&G$P5\dGWaHaJ=9A*\an?up6Dd+P1KXc5jY?i/TpyLVw/S&Zm!YPbWF?#l
#wC1T4 X^w^Tkp!GCtqThj^k#\AI5K45HK5WR=/GYBd\&VQy6&NkI#Cp*+\MMDZjnVF4ecu1iB5Dt*@SqKeS<De
PkSb8d *+!@^FN8ph/^kbW\qNB8jQNGBE*=ytqII@mZN\L6Ph84Z?\6A/:bY#>>$&5ibjKTbawDTY%9D?C6IXhQ
jQ\T8p F=N1kwJNqKHV&tc9+ImMnMJhk<aEuJT&85ZFDuW=A&FyHTqSXQInJi!$DpJ=9MqRQE9V?JSZ6Vj^Bh6%
b5KHCS yJ*tjA8AVTw85uNGDGw*YGipaEw:^<aPQMZd+A=S=KDph&D?a%5:LKh?cStN##kjpq?5umY9B!NpQ&pw
MV*aeZ 1n#<=aF<pFXAm16S4MRemELhT+qy\1e*WKAh&=P@1q&u+MaA6?nkWCAjbq^Ljkn<9:cHw5Q<^FmM#NSN
R6Si$* Ne%Z\lhLjm>MFAiq\KLH9q@ZB@MbTd>CdkYZMVm6leD<A9u%eLPnbypMD8CHMIaCndu@FW\c!u8TH+d%
@hSR4? H<9/W<CR+w$SKGayZtk:mq5//+9jEqXj+6H*<VkKZBb:k9K1m9J#5S+k?N?SAEX4IAk<w/+j<!lwkX%Z
E1XB\G y1F:HQ5c^!T%F$R4P&w*p&RW>\\%d4tWKJDjBpX?H?eCV8<F#A&jlyd!ma9/aj&a!Hk#SIFwV9emi&&Y
P6?t1i @nBknXjP?S4M5y\HdPDaqjl\#h8FG$WSZ?iYeQD5k@wIV/e$P89K+dShmcJmNVe9/&%9%#Dt*P:9Ay?4
wp14Tc uk#lWV=y5d69Y/?=^bV<uY/>n!5?m$8G8:ni@/n<bKZ?aX48q^#@j9&inZKZF4#Xn$@n$?F=99H&@QkT
MQKZEF H4@mjAZJ?+HIeDF#@N#h:KJdpZ^h^$h#>Y+F/y6VqY&9KB<XkS^X/!X9TSlj@Nk+B!yI@%I?J=t&qY!L
Q^L&KG \&SDd$?!9:NV%qaZH4\@GL@EY?AZWeRK>uQd!*/Ep9DRTqA?Z8^kKJQlS9WBGB@/dEw4D1bB<u:G^aJ@
pe!!ZI lI5D&^/q?ka\Tl>&4\TDmyGc<qFP9i\y=8bXKY?Jiqj1QILXdV>TAC?wt5?K/5C9C\C6P!t68kZ@wQAt
EHyKKF NZXye#KKZVV$LjP!6/@Gu?eF5^:8HSa?GWQlI5AaM>LtPI>Q8Fh\*jI^TL*cD$Jwac$RFj<wLm\XHm8X
QMJIGn F>Fw6=\4aWa?MTMiuE^4cbi%IR*qTy\PPJ6GRZW^CZl&&I5!@qDGB+^\hVZEBKAX?K=lKB$IQ>M\VSS*
Gb:et& k4:J=D9CIi5=>LymdK<A=65/l44?@8ZFbVyZW4YK/y^\K/^kR*:NWP1HiEhu4K+@aGEH%QLLMS?%kq6I
byXq>c y9:I!bFCX%1R=+8NEjAwquG$kQ$&1uF%I/+K\ucE8+uluNpAHMPSbNEJaIeicS@5\DFmt5?jW<^K56@1
hJRh<R QGB6nIw<m&BKRWqS&?SQDRJj\^41/Zm4^pucNT=%y&B\dpZ%p#TZYIjqQ4b9k>&*hyp@=PR:uK?qnkZY
kP*id\ RptL$n4%BdjulTu8&5dM:ayhE9G?>Q%pZ:?kEalX#dK8=pHLX:Hcm?Y?/B?<<LZjt5injH?ym=9DZ#iF
/w!eTb l^6>+&P6q/MCIi8&/d*%#$Z@^Rh1a16u=@&d*:e\=+HimkRqdl8Z$j#%FQk:aH&cd@M*+5=<!RZ@hH:8
^c&hp? EdL<$8QH/?tIN\jq$a4jJQA&WW^!L^h*<@ZAQ+tLT#%t!hC*W:iB@#q9N^h!L9Ye!\*Z8GKJq!:%uJ8+
%\nJWD b+up#8jX*S@LXip6>bmW/adK9+bP!jAqCRBB5SVyqn4P1$WXF$Xj5+>#QYi6B!8JjW6y6aKZeT%Qi:&$
yijE1% e#$t%c9AAaqB:*a>=V&tF<+u+Fp!9Pem4uYe<MJWmh9JnpEj5bhh6C<:T@YelF<WJ?^*I\Xm+DFSQIT!
V\*nXj Z=H!Ge1W\MKhZ%*4MW6>b>eCkeqd!L:pn#J/JD&Z@SCYP5=Ailn&hS=*R5Ej!jBnlZSXQ&PY!eHSMGNS
Sm$dD/ yKyL*1W/Qy+V^a!QyXDy19iy81Kn8p+d*WmSTml6KmcEZ:TDj1K!CnJA%nyPCEw%hFaw!ZHJb994A\#4
AaI+4% 8b+VjytndBQ6AcZ1%9E>F1#EtRcjcYNZjVnZa%Jhy+i@GPFqhbu\W?W<aH!Q?WCh4@YeVLwkdGanVp5u
+!>pSA 5PWCHluFaY5>b&Ciyp<B4H/1>al%@bPucKGn<w^mV!#uj%j4MhQa1?qN&&H@Y<q^qEa8?J:1R@e:Pkh4
dLw1XH jijlyTMeWIiSLBA^9B^m>!In%ZMG18hWi>piKQBcw6Cd>ahZqtplB@nk*hX9>NEI1u>JucD\Gc!A=A#\
:@u\>J m9lT%TEFqcyR$64N$VjKaMPnYYI&=bi9QMX/Pq9meqkS9#%@X6X/t%5%VcbELm>hLN=4YP^D185piQCt
bJ\SDF y5@nZZ#uhZ*hY4$\q=Ea?I>?5XiJ:hJTGHALiG:XFw6Ijl5Z?>QK<!uBJ%d>+/qMNkd@y*Vpj/c@e6@5
1K#R/1 c:=5Zw>ucQ1@?a<C@:l=/=JeJ?D?d+j@M+!@8MmQ@/@lt8Bd+kC=qmjh?uN#</8Cq/&%??n@KQ^TWDYH
DdhnLm X>e/V94jAV?4VZhNt+c^q<MN*6ZjcP/TZ?6V4ul=u!8<@V?Kyj/V+91?%K&RQXeTDn/Y@&Na/ntZ\qFu
mCGjXZ nS4TQS/:wSQ$*6Z5bRkdPY=1eDd@S%HHu?5:+Xd!HhYqWN$KED$NaCtB$jFh4ieEQp:%85SA46$#e&m:
-AijIj 000d99d133700110334 Page 235 of binaries2.zip
cXANI& Nc<Ze1T!E&njQL=MaYqZ?@<8=61THNYX+CejN</NcdBZ%P9SbqmQXkVCR1?AQ$=t/YGM8<@$jM*E#LSN
a%^&Xa &\kp1K!5!tRdnXZL%YhSD/:1P>QPF<aH^9>8E:?DHycn/nw#IWKaBFcaP?I#ePFa1G@J@V\TTRc/6FqK
K/=%/c b&Lhntl1CXBZu$Y:Tw4PE*kI#tA/ZjThkw8khXZQmZB1tIXnP<6c>DjkYMit</T!Wec*6>9G$F#/jJ&^
/!iq/h &<chZZ\YyJM=G<:/#4R4+KF^Xh?y=?=\QdC@/DpS%mq9CMSL&@Q<=$RhVhX#Iw6Mm$*TZ>wm+&@8<?tN
ec8\ut @b=q9jw5+4HjNHFyuDecTwByTIm/qB:>nFRtyBFyWd?JuuPuu6Qi:8D9tNZJ#J<#=9tt1Q?5ip/@1L+H
@#hyly @$4kdNM9K+Ti+!?jtF@pWiK#&F*#XVnJipVG^bq9@kVpi1L9BJG%n9pM@R>T4$RiS^^J&kLnpiX5ueWN
GV@Fte F*%YiSL?iEWqeN+EVGShXjB*6T9?TwNKjBd$WVm=1<e^=L+cd/d1V/n/Vkch4chL4PApC?6eN6/XGFFQ
Xhj1+X tH>Cd$It\@=pPLdyeVmuhmtYaB%/Gb<>pEV/:tLKwWD/VCi?JhGk?SNcH!i+#1+^QPZwtkLbELMmAi8c
=wH<Zi E&D1YjJGtd@X/8KmaBj94C8IFhD1@q<ALu%BRX/*MVE+lhLu/=lPt^4e^V!NQ/4*8c@Lk>h6L*WD>+&8
lLG=?% wu*y/=&/<8j9n^>dZT+T8b/#WuYi4c:<Lj<L<TL59E#\<#QQjqL?$?I9&Nc^F8XV/WlXjK4u</4n9QwJ
K:FtJJ 44^RCqym4AqIieumZty8I/6DI+JEK\/cZ@%wC?EW%BXhb:%8u#4P<K^T^Jw6^8j%#XYWR$l&tF%5qeX%
8S@hcA /9YyZVTcBZ@MF5^>aL<H?DdNC<6/H&Nc?kj#?Et6VdeyiEmBPHnEDLBPbph1nln<ihj4@c:=8S5?=?i:
55?Rqt WwPS@B85phJ8Tk\S=$BpWqqDwtTb@?P^!LKL#uPiBh/5Ay5p@yqFhJ8YhhGm+^TiB<J?1L8*H!NniHVE
6X#Z@y mQI=+AE^#5t\4EMX+TWF:W\LSQc?48*/w=/Xin4ShiIn\LQSIH+^qdCK+$qj!Xehb*Ld^k*BKL8S<eiS
?A/6VJ NyCt:<R/#u:6tK<I@@Ci/p4ER^BHTW8MEcd<4IiBScw^XX%u5u*Y#XJAkj$mlI<d&W@SeaL@QS=Ga>1&
lTj\KZ jS@HFiiNCE^?q@YhtLth4June>y4ZdiPn/N^iu+e#:w%>c>Q*TiPY8bh=4@4YL4hLQ&PShib^lq4DQ^e
YL+t>5 4JwScVGM\1\%jci*1%bC>QQ+laaH/m!/aqNaq6DPu$C5J>Q$u6TAW41Tqnp=eE:piGd5VFj%uc5!B=DG
=q#Aq@ ddMGYP\h/dInAVa1W6@J?h&RF\n@I>?N&TdIi1!5Q+C>Z$<*AuZISuThQZYjtHbF&Wy!i><D>#Zj>:94
li\5GX ?4/#k>LnRL%1d<jBaB+G8$/D%9*5eXX/*W</dyNT+NMpjEn:iNqSSTqACD45iVice!FG>J?T*?d?SZ:j
%piii4 hJ&^/AIIP8Wjc%*!W:\aXFMp?Z*YF>T/LkWGlucMVhA>9@MX%!@%$XM<c?XTu&N:ChPq@l4</dZ\:j\#
:d1C\A qQiuim5XJM@<t8?ikHAXKq#iu*uK5<:%5*?uHd!k&=PZZin*Z^:@:H<Q4:=*H?LZj9hZ9e#4:^9Jn/*%
p6hbIQ iqd4u5cyPq#BNh?$q&ZhGeGq:qu<EiGp:e#uW@K+64%WLWIKy*%>/d%4Qk9GBhGQuHYj49K@L5kF=I4j
85ty$* !Dj!q85J856l=EZtE\:Z4Tt##a!n=ZVm/i9Fb$E<^X$/#+nnXh?JNJ=/NS#S*4M\&9W*^Ajc6dKiM=lQ
hJ9\*L Shw4@K>jI9nj\+IHXJ:u>puK1E=>LMBRY:?*jKm\>uh:>Xpkt%=EN%j$uXItI:FhVNb*Y5R:lhhX%<uk
QuAt*P #$tmD+I=9tXhp9mZib:6H:TH+*hG9PH+uwkq<SjJ@iK8Qk8AYV>6a>j$uRnm+F<4^S<EF:4L/I?w?p=/
EywpZ& B%aRFd5:WKZ?ke?LaKQ!QC6YhQF%LAnuDQ@hRW*w8KuhL9415^mZd8:HdY8/V\SbVFHSh%J88hC9$FW>
CcZnIh =\E?jnNmY$l5+CDLtSCcW>N%cy@Hh>PHyS!i\mi59F+MMm/R#uij^VdnIJ4?E@Pb<IIeqj4P/w@AZD?w
De?5eA /?V?5FdE!^SA#em@9ZtPH+NMEjnmbtbyG^wyl#k#&\+J%6XupW^9/Ril#yQ%YiCj$<R@/n6uSX:1%&tl
yjW:p5 9^BaS%$u\JhKikPi4KbAQF+X=*<%T%c=WYmjiBFaVFm8R8KT:@8+k5<GM&#Ci\9i5mG*Q%KwP6CKj%Zj
!iNuQd Yj$S*M:4qHkyN\S>D\4uw@1HHcVPRX$MnjLAT/ZZihmRkGJ@9C8<H\jtFDlZ+PVKwR4iNymISa+H5M6b
ww6&Dq ihb*Xu>E%5jFyyQ#nE+5=Fe5dQ*M<1J54%%CTVKj&&LD&%nChC*uNXcW>b$N#1w?5NGtwuiwYQnE9TJW
WZb=pp cBlb!&wluHE#?E6u:CT9jPW*y*:QCa<8@c<VnqY<muZ:T&&^+hR*hQT9nj>iZk@^l*Kd?F>q/l>Ie*^+
RZp69C =*XTXDndE*!<?BMcL^SjRWy9#\Q\Z!y=annuRb=5JD:>jKG&J=KZ=:jpm<dLi=i!1:A$5GyhQji>P:H*
FP@NKA mkDS!X%kXJP6qV=*cVk*Gm%V#Q8R>*9B4&V81phab%6jpieA/G/#p*4c6EV^SW*TWCTjpC^VKjd>LcMD
CXjhhG hh#/u\@&ZR=:Z\+P=wZZ?*L@TNtIl*S$H#Q\m4yP>9YcH&EF>w$WALJn^u=Yb>uH^FuJi*aXli>S$Se#
dBe*lI L$#$SRA6y@ERHXQHRY9DE=CFX+\!R9jZGjkcuNmBhSbpIH/Q5jkW&K@bnjDY*MBCjDM*^j\>HqJaNh9l
qDI5YR M=Q1JL/QJnuy:K*4bq=$mVuQbtPXLWdlEb#R=e:u#5n<pTcB%!Z^B\dBn+DFFL+c9SuGBD=5w\Z8^Y/p
4:=$1q :nLF9S@**chT=<YS#9ed=whlh?CKH@4@u>puIP5R=%?5F=>$FMi^@%1!+b\L%9!JMjiywyS@ySVI$$44
9VewNL 5m#$Q>lJnhR%k4$6?Mt:tHaD?n%wFAM*qd\D<:yq9*4?TSc6Hkj\hJybpa$p8J$<JEp/\8#4S8y/ucbK
GjbeY\ $\YLPh>bV?Ync*DXa?cw<$yIER:lm^mEF*1ubS$\@$eCJEdYhQqeq6D+Vc4my^EE#/?ckk@k5CS*\M$>
RN$%EF pRhZ9^<81n6>?eDhiVKW1e=#:mMe!^&JBQXt@J#wY#dT!685Btw:DYER?h!8mm#:+t@Cle^CdItdFJk=
b1!hP: KcMm5dSQZ#8hLhVj5i+4hbKpm@/VqTMyj/=!a&jnj/#91S@P*!>/$T@m8uM9Tmejt\=P5815!QVqR?/1
HVkQdL @:\cy\8BdHd&4J@?+\bj+^#9=eXtX+6jC$me?%19/Z<wQ:uE+d<>@t</4@GNL@=bS@m:N8*9!4\X#=*Y
%*R<DK #dn8*?$Z*#:ay4JMpi8>%*>ZF@@4RKN:cAwNmR8mK\<bKEPM+eX8\ELVR9%KL1?>u@&5jHJ9!?jbJD4y
#8XE8E ABB@l?H$ReT>neKB5Kql5FJpSaa<<4/hDID\LN\W?IpL=j#^YajN@Jw+PAwP=9t5edqWJ<@/deG6KlFP
jYVJ>F i5\?1Qqt^upV@=PP5\$IM4%/%1%F=!I?ZY6a*/&Qeey<nPEtQ=?D/=d^N?Nn<mKLPE>=ZyFc:nAj\?%#
tEQJD+ bPZS#8#*dGbW\<nHhT&V/E:4$!^KudHpA:SNcJc:/Y<:epQ*Sc>W9=m/=V\BVXiy4i=\*pi$1\aNmtu=
>y&%t1 %V@+tBDDy?+A=p*jYRJp41i:q@G>?NQwt*BLj:6NY:88M@=8LXN$:K?hIyaWd4GAl?*NQLpnnwPmHb\w
eeVMQC &Y&AnGW\G**:%BiBl!SeX/GW6@iX6dy!Ai4=j^<d&/BF>@LNnX:4w/j^bahHh>9uaV%mN=ju!Ck%AIBG
ynCY%V +<cS8p!@#Ad<8%^ZNK:w9cP9i=Qh+Z9I=<TAJu#<Sa*6Z\ZH=tpnp9QjPd:iN+\FCtY6*WlIhV>%#1<:
9lLqc6 =hbmS%nal<VZ>=^jMSEV9@#GG\w#6&Rj!FWN?X4Hm1XA@!=dab?R9?</>kK4ZnP6Xlh^>XF<Y/t<n!6>
jbly9w i9!QcT=b*a?pHnmD$cd*?Ei>\/WR?Ay94T@yup?ACj/>d@Yu$ywLAY94XY#ld>Y?$+nj5+*j#eK@WE5D
InG@8H BBRAAkAIAB^YdTXXc=d@wWIAADd8AAAuAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9etX#L&%nMVN+
:F*<LA MnR8at%\:F\>4P6Gh8aCBtlA1*hFmuLqIuEX%\IYeG9XB4b^:W+hc#eyZLpPGMCA8m&TACuT8GdlKpY5
JJamN% IyZh^JYLBekll#PeARtptH#uDCtS88K><u9JJpc5?/+8Q=:l#Ju@e:+=jJ>?>we/+M<j*k8C9<Hjj<j9
BndAy\ Z@$8CH+Z9P<FSdD\?a4@BX>>=j@RD!/???/:+L9@?C=w@8&jk9jii!>+@@**k>@@@9hBFEZBB^><EH#+
Pl:BMy +ajBS^>>FH#<<ejB==>@Hu#&&YjBy=>?Gu#!!TjBX*@4kn@?$RX@H@\RPHEP@9WHGj#\=#<Hj@jQ@+IT
&89?ja >9k>+9iE*:PHi*#6eY?Qi*8/=*!TI?+jeZHE@TQ8H=%@:IV:J>\@Ab^\@?R+1?CM?&jeQ?Q?GVjP8P?A
E?CmuZ HdA:?/L+=+njE*:yu9QF+&5QHjdRaR<h>6CBXaIPi?m\l\=:/LCHD1\thNlDl#%$&EPHQZSk%cHDHn45
ZhtTqV weMiP8!l\>:lH9VaR+<>/iGe4^=4Rn<u@J:^/*!Xwe5SlS>S$BGbH1ELN\PES%\ewe5S8uC#RI<n>DlC
^W4$Fa n?PJ:nujXNDnCB&P$PEIHcnyn6DnCB&P$PGM5l!?8RqSn9<=D<&:b+%Pi<LPN#ZKQpGuE\w>waAVhD1l
RR$CaR :BPEJ&S!PqFi#ueHq+*:KQ?E<p<wu:4wlQJQhB</uKDD!Vu8N6<VS!/hNKQ8QWPHM<w:R:e#>DmnQP=c
/&Ly/a $kN6eIaib>IDFiQ8^pNu/HKGLteweWcBQATk!^pQuyHwnB6u/ELD+p!/wE@P$PXM:eG/$GmkZnn^WHLR
AQC9w6 \WEHB^$ehHDRkaeVhDlDB\ehHHR+R\eia6DBRReHHS^$eNABYiMZ>/GDk\+PPnkw+FD?Gbp=QPmR/Hmp
jlSLAM QpI@Pm1D<1a$^?C9k*<M99nmm?DLL:<M99://?Cdd:+J99@???Ddd:<Nj9#^^?Cuu*+Kj9:==/AwmpAy
M&S6Z6 FjS>H#V@/aJ@?NPjMI>ySn9?F%C?nCljkm/R&l1q&%@B^@BuC8cm+dL>6Z\Wj*#V/<u%AEdJ4/W/^n4/
IBGNe1 YNdaA*<>q<!:c:m+>6=64<//@:=put!1$e$#+>iR&dVR1/RhRTM4jLyRG?lhh=WRZh*TNWuESVL&%?SK
ZD9G?> <=>LH+?%HyKbh9:MLYmu!TcjIh9yM*SHQ\41j4hi4dhhc%8q8&RXdPK1MWb:TVBI1B#8L//dwY+#nK&b
45%j<9 Th+KVCew>hyWRpZSHV8PtFiBe/4Le88$\6&\/uDD?d!uEyT98mL8R+Q^q*hC!L\JM%HJbmb=G#B&m??%
E%1J!P WMw5ne5^YT:mW8a!C^<FTl8XycK&Ft1441@C5BITjVKZPNX9NuG/Y&?q6VIPk1*M^b6kI^1u^PbyqFC!
EmBA$W JTC8Ge^!G/d^$EHbdlYq/aEq%wdy+bAe%m5cJSPkF!SJl$HtZFnGYi6wj\qFETjS?kA%nbeWk/SL?^y>
&bk1%M mk4t#tpyJHw91&44Bwtq146b5u9AQyh\d<qMKw6S:8SluYL\?HKc1k!hp*GK:\eB6Lb!i!l>BYReyclG
-ASMI! 00088619bc700110334 Page 236 of binaries2.zip
^uqD\C X+4e#mTlECHG6FGh/BT/6?!5w&>6ThKPEy>M@TKkFN16TITte9I5Vdaqcy#%XE=Xhkd1>6nPZ\H6AFy4
\Wul#y $CtyCBWYATNVG4pty*Japk+TKcweR<K&55eFQYyhk%qp*E#!CBA*pyaYy1clBSQDABP#mp8FpTEcqFNK
!JF+q+ c4ei=V\K1Jp#tXW$A:p\k\uDBbKpGmRw8CENDE8RRWj%wR!+km\l4T@JHkiaP%ma?GNcYXb6K&LS=AI#
b1tGjR %!6K:hc/CVD891RHeJTu5qTC<+&H%F!jtWTYbakq\1m1RL9X!Mi/tnK+TJw1FR&Dhk1YJTQRYdJiS+jN
W\V=E1 PpyDK%NMk1cQm:LH$wwG=aa91RwQA6@YDNBiJTaD^l8XM=MwWjRNyq+Z^=q^SmTy\nhqRJKeJEW1pT!t
8q:y?c bBakHIEd\FK!NyhhJ?pZI%9#aHNb>JR&6F<IcKBw\YWkB&CjTWcA6c/1cq/^P8Rnp$%1TG8W\^I:TyTI
81MbGh D4%MX$GS8!^b4ZbyG5eXKkZJaTi!iBQ:XSuJ5mIcATVFbqm9KhqFekYnaiXw9HEGR1bBkQypl!DJZdNh
*dKp>W dWM5nAC%c?L%CQIq5BHG=ZG\TuNdq%FWXtXTwCXIW6qBM1:+ChYlqqI%+uDkJatYnVS/&tc$*lIwD$<J
\N6c8J ^mpYK=J5%kqJjLLNiqiN!WlC5$nVhk*dTnba<dS@Jpw#KY8hT^q11$Q1PINi4I&:AAt44Aqq:RGMM8Wq
?lBBdI ni!\<q9cq$PF95m/Ek&EhqiNqBKV%W8MdYTP&6Pw5+c5HY4Sqk\\:B?aldDp/BJjVWP#Wk%tDhp4j8@*
DKY*1* n\C^8e/Ac6QP%88L^JLyTW5Eqn=6cK9Aw/Hp&W%y!D\#%q849JK\6cQyD!yaa$mTEQPuaa6yTGdbuPL9
&aR#W& Jm8*l+R*YqNuZhnFl=K1nic%Gl6YTHaEDAtVddjaGtD#$j/RytqBp%Zdy45?\<6&&bh5mA#&yDd64b?m
ZnwMbj G$XLwM?c4nF:pVXdb6l#!nKqCa^GW%LRl*JV!4bbnQFqXWPdI>c*6qF5H6w^GbIwDL^m6cqIWa&qLZ:c
NT!8j+ qXnNe#^GXTl+c%dRAM6u6W5/59yIAy8ISnXKeiH%tba5lAI@&AcZQE^DC!C!=q$jXhCEMP&8Yc?H4HG@
nYtCXL T?QC=<dJ15M8k?Ym$9XGpHun9RqKXqA!ZNqGdIJI<Hkua#kQe+PlwNkl$Zuh/I6FdFRh=yyMhH!yQG?M
iT1:6X N<yu#:T1!jGnZuS<?ZuPi1#yNG5>!Z1Y&%WDVJWlmVjlJ<p\nDEnMV&yRnSMnXa#Q&9tI%:GDwqGD>j\
#cV9T9 5^PZeMtn8?t5=c^d4h6:8bplGW?5i#%@8VSZ6+8@&=t%*#/H5$5><h!%9uq1wa<i!9w&N*%^<@S6dqPh
MW8?Mi F^W\!@C@tWtb8jIQ>G::&?i*#/9V=Fj@wRZyL%!nki<!p&Z$MYD8kA8B^@aTd^n68LI@I&udX^t</iI:
XcdKPP Z+tZAh5k+\w+BZyS5y!MtV6Q+JH6WBhQY<pY^mMM*nPJWlM8>#HAlJpla>EP:NpABwq?LupB5FGwQa>H
=/yiY< Fp1dFTY5NK=pc$hLqi*dIW$:pcmLSi9B/HC+C^uw\dJEp<EDT\1iH6^9GJwQkh6u6mN\hSpLbePT&At!
&^LDnl ^iR&KpJL%le=+ip8lw>BNPbDAD/CEFqYmR\?^C&wFwCM+j%5p?ky!X1ACGB*BV5CY\?m*XW!i?aRnRCy
#STVNB huG<ViI+:pQm<\=JpWVdDF/YqWYWqPulKabZ@CCw!>*V$>PdVh#BBkh+<:RlwAj\hAXQw$TtBec*QEV\
4$pqG^ <M\:k^+&5!$QyTaZmnkDmIn41\CKGBc$c&RtZ\dFBcCDac?Vq&*Xe&D8TwlakG96@b^*B1KWdbN^%4y6
S5W/M% SIylw:*Z%nC%aYtt&HaA=lYACYlCWZaKB9REcLW5$W%QDIlnw5qPkLNLpyhAFR661t$5PnnHPbMc^q8K
\l?@\S VXYpw55EMiPtER<Be5mcmtk5<m+jA%mB6y9Nb5&8PEA!BXiJ9bFMkJ+pW%&<YRZ4\&/D<b>ZQbjBP+$T
IuYFhc 8#idZZJ+&lVECh$Bd=/DRhGYjM$4wC1wiZ%5Qpw$LR?!KqMtA6<C#DNwXTlT?P/&E^LnnW>w\k\Fa^TG
V<<apw 6K\1D<RF6I5A&lqVm*:W&wN&D6w4aBeda\/n^iZEn6y*BnR%dRZu9^Fa*<K$/CC1EtK9\nT8TBmZtF$D
@waClF EFM\qSmYWMbe!:FLhDeF&V$A:#?KSdudaqXyB=ARPZEBVILai=Iy&DHIM>Gu<VaqR1N%YK!TMm8nha\&
ylR=C1 y<W:FeWl=9MTLP!FTC<AEkJ8CuC68!SaFcGlk^*dAkR^W!kiRDKC:RZRIXaSHdAl54?hh?ulpGLyy*Yn
1indm8 /ayNhJFp^YbVTD/wwte&G!Vn=RYT\!/XSG6lM*yK8mddW8$W5c?HKP&IF!NRJRPdS\eytHZM&ZuJ#lN+
qJ&8#B SFXhkYtJhM9N\JeSHbeQqmBLmJbnbw%A4WcVn@k&b6uIYnDEB9HltnHi<ykhI45BZW?W/VSJh#R=/QVT
/9>Ael G!=&pHqD^q8KXAp:5HqM6VCd^+wTp<QMu4peYH1#mLt*yt+<GYlNp+@$DBF6bE=+ywRL>Paw4R:E56Yi
dWND>c beM/68Yl^<bKtiJVEVNu<^uLy8q<4P!aFeJ/WMWJH!T1+j#&/6+QB<\6$$*6/&\iH*R\kWeDkW1T9emH
bSF!:j b/BdLQ$^KV%VqmpYAa8Kcmu/pca#W=aNmFm&nKp\a8PC6Sma8TuL^ndYISaNYbww8C8&KNTdpA5H@uM&
CG++%t V!&^iVMC:@1MHuXn@8*8M!NNh$PFVXk&Yyd#+SLZ^LLbCe8Ye?i*+?yQ*cNj>LLWAy9ZLqF8i9tbq&m/
9<h1CX ST1MTdd&L55&<<%+b4#8lh:Re5TqZTp<a?=Vduh$t#^#l*>:pR4VD:J5?1GRy4il*N/Pyu8ShQ5jI6^?
<XpMjl +>N??@#&?V<c^um#Cy6:c/^=MiVN9B4@>uI$Zd5eb&j8SF!c&%k/a?+EK!wj?Vc8je6Sdk?C?XL:44qN
>?h/T$ XB$%9S^1/kGc+Wmhh=A^<t&\IAe:d>!h4?Bl!d!bF=I6=#dQ?lJZ&X+%=a?htMBlXqYX1CnaR86cXl^R
&$WFF# XG$yWII6jQIZ!B1eAQ&kbLb^NcGWk5t+8^u5:8R&AeSNttuEJRXeb6L:C#1E/+B/WKm!:4c4XbSEV#6B
<p=N%= ^<#dIImE!6MwDmuKa\5LFP+X*PeLKBeBpypb<MN&?GQD:iwk1ye!KKebQAQ\1e9Dc9XEJF9d51bq&LJ4
4@mi/! qmXQ$T=c<!p\?dDR9Wt*RnpKa#RWnBCnq\b1Vw8CJL<M>DFA!\cc=nNQdd6pq+$TY+8Tu!p:@Tkk=>8#
B6Sdl$ dPSX&#CVHIyyKN\T/ZL!*wi5M<X^ThKTk>La9I<LEddEu%CH%tR<9\$\<JukZhA*?cN^A8@YWeTVwjCw
pI!1B* Gk+5^*R>CKlltGWnP^+PT:\P%5!I6p=#hIYQECNdu<J+e1JqnP\#Bi?8yLFJNWVV&nF\/leDhHwm4BEJ
wH!eM\ nT1bbSW<M:k6/EeWLTm&1PPR6BGIKil9AXNW&WBSWaBXt5H4y!/liDGtqM115WTklIdnq11<:WVZlKK9
E!Y?<1 MLtwXen@>JF^d\PIIp9n8CB!WuX>%/B9Gl8mX6#\R=u&RWB?XwlKiBcHSKkJB<%bZ^@Ddbkq/>X1W#cY
TS%FuD :lEjJLM?C/Zwl5nF1/ID/K?kZbV\M?R+WqAXP:m!#N1&KnKFTqF>^EZSYj@MJDQA#ty!KHMmIck?NP%D
IWwJ<d n96Db&ZGhh8C*FY+1tZZ$JAY8bIXna1\RV?%:>\@eJC%mDa?VlXDZKG@KwqF6*/>C6$#aIawHV^6NW$Y
A4?X&N 1p@6a@lpXY+*WW<FWe\eMbI%pbqEbSJ#y4JitywJBt5^cD6>D=lFCRFJ$WDI4hl6!iZQicpK?=lwFDMh
B$yZyh TA<C/$JM#4yKK>TGR!#^uS:T*Ehhh1Jp+wdYnCH8WyKAih9Gu^MIDyIJK<@R9kDWZiBW9^ZYmRM&M/+8
8mCFLA FXMeMCycn1*mR\u1laiA$%ZeK^ithN=H/>8d>b9%l5IVl@HGm^\HPNJALLcwN+Yn$@EL4^HE$HdP1bKZ
:bq/KL >hiAjk/MCwqCcWLm@ebu5PSBEqbbR?6TlVw?CLCR<GbW$jaCJDDN\%#:iW#^5JlL/MW5CaJN>Ma#u>$8
<c%:&5 CFJq/E@TWYN8T%F5BY@XMu+Gp9+Ka6b#Jlq6Z9:t*FJSSIi!N5VedtW6*kV4M4<L%lQRi:ALX1Y!<wA@
S%nCZA 8Tc%h&RQEGiIphmHVWWdP5W$TmbX!Z:LR^p&tG=l%+WN$:Y:#hVI&uk8tcp>TG4HEkwcncCqaeNM5<W%
k@E$8\ eMu/\q6epqF*Nd/AuGqcBp4XHpCd5Gq!ny%5!DBV?y1MRnEbcJmDqAYdluT<WD+Fl+yiNiNkSV=PJmP4
5aX<&@ bi=VNt#F$k=tRqp#W<ppJIWNW>W5m6W&q:BmWWJNG\GNLLKWNRYR1*\T&*d^F%w:GP<6t>yKhk$#9w=t
ZWd+5q L?$tdIJV:KXmFTmP$#DQS*#aLBtHhw@&NXHBdT%4+8T8@w<QZM#TI6=FehecQmcm$\5>upuW^ccwtbAp
/qmWiC jnS/p*B@Y>&q<jc\wjNdVZ6E9N%8C<#Q?&?MMc86/IT\=NNIbN*ACp1^VGDByFhFbH4aJIImBF8u1mKP
P>kI=/ Ph!+yYR=%4Pcp6%/YjyK#M&eQt\a&#JWIhqhNMT/Q1QNZZ5cFCy$6D*#C^&wKY@XNI/&ba*Y4wpJJkeE
>>%IRQ Q?ERQ*4jQ/Yh1iNDVdR6$d1e6ZtY6VZ5#tRe+n>N>m!<lBuA=&+^nRtKm9C$KNZcGn$lJ<hG+FPA+iSl
K1wpJR @5!D<at/9dKn+>qDP*kZqQXh5qT*n^G^N&NmMV=^ElXw>Q\NM#%:b9Laa6WY5@dZby1b9yj5@&h>Zl\1
hd%YM= !+#MIm?5FnW\D&X>t@j@Lm<<lDVy9!#>Nw%lt\i^ZXM5TP+D@<*^d%Jpjti/lK@NwwyjAe6SdtaB/GH\
#bWj#S n#F5D+B^:jj*%LNpa\J@<4^/\>dCJWcNW$?BZkSZyN8Z\DV?dZku%I#u8G^&9VWaDtaHdw^h=H=d?5%5
XMMwbP mFF#@lYLS+BinHJ4F\E5i\\IW&im\n=KMYVG=QhBjkQ1==Ie4yjM+WWJtbMXaEQ@8k:MICdQKnlpZh+?
c58bJp AC1A&!m*S+Ll$uYR$J8uTdBP<*T%CNcLaJ15m+KN/NJw6TbnCB:FIi/!*TwJZX=8kuYW:DnR=$Fk49F9
eCMLQe 5E/il:\>n+^V>LaLXdG65/^=EYTQJDN\%HNbTe%Ba*uy/bi5KCS#i^RaA=<GLtYhVeBMMkF9E@?t^4jP
>X^Lh$ Cuwn?F&B/ayTlqpZp8hQL?*q*uy5%QA1EX^F89patAY&QSIMS\ELhdybS>H/DVHL:\=c+9q&I5#4ZDPJ
K*8W%t +IdVj1d:c9Ip/D*d^<Bd^d?ynJyW^D%SD9AZytBb<n^bRRCPSHGISeY$TD:EeHEpncM*cuZ8CS5PqHwh
ZZGw/4 #ALd41C>CZuDMuwF%CA$uRX=A8<MaPDD9E?jXuFIL+ePbjk*h5IWW=%iKG\X9^9+Pqmw#&$X45B:NXlw
b9=MQb bW<94LXZaBeBZJiybJcB=liP$>V@9\D=GI4HyDqtW%@=YD>%AVtB>y/E\N*/tHu@*HaY5*G$*qQR#\m!
qmSml+ Kcl?ASn?^+JPE5ujpF4YW%ZMcGLGa4jCenkFilFeR&uGYbK@Qu@Iw?#n8PjDwLeAcmblTuTZbC455d=S
IY^qd% ^>ERbBKVi8HCcGwChk48TYnl1pZ9n^TWB*IKblI/cqDp?4w8mj4lDW%/p*kP@P8nqP\KBwt/Tk:DM*CZ
mGS+*< =ZcZ$eFJnnZe9?NM<bdEtBF^=pNcS=B=WD$DHGbJ8SEX/Mc5q+E@^cL^>q@6jX8Yw:1Y4j@+<HDaB46F
-AY8l$ 000396b451800110334 Page 237 of binaries2.zip
=>?$^u dk?hwV&$mDhCDQ#HZZM8ASK&I#L*+%VX8SqXJ*e/HeaIJKE%NS>S?VkA/!GbNC19iDH+L*kN*A66\9KP
pWQ!>Q &h/=/kEG^jC?#mhyLRDT^/&WJ*+T#W%/Ql\9n<9^JI*#ZpSnZ81LA%+E:+^!/PQy/*km\X=juE/kPPIl
HAC8A\ kZiPN*&HL$=+Abq\%ud1@IIZW>TbSWNJIdHT1p^Py\ueW19T+5+S49mbjpEQDAE>HIZhH?#>=>SGBl>S
*!I<<l 1K@y4Z5^?T@pb@?Cl%b+$H*y<tLk8dWpaLy*IqW>e&q6YpIw\Abq+mYpA+nYSFHZS^Qi5wCLS9$:XL#!
S8y?dA Pt>IlEVum+wd?%8@1I<hNtde8u&B*E^LZA$DGBP<JZ%Vb5<w/mFmyaShnw>uKT6SQVh<bnp*jkauIPjY
4G$I54 G@&Mup:Z<VMPCy9eVG:q*Inb>?R/F6hLR1*6cLI$BnKuKJ8yAa9BkkVAVqeq>%Sd8qWtQwPBFR??y>Di
Qn4TTK T<m68BaSET1L:#pVenPA*PJE@w?\Z@Cb*u%GMX/it*:G+uV\Gi=%ER4DWqJS69pV!td&KF86KB9*ti=u
<q?et? h\%enS>!PndILi5Wmq1\6Jj9GRm=bR1=ib@yj?p#BQ%CqP$VFEcW#d=B&XlXS%E?@ATMjaLeRnR94Ky=
eGTj8m d5Qu#^k#&J@+mT@Rpa@WjAKq^q@CZWK1+deR%jBd=#d+w8d@89d<GlStZ=C\6!j\ZZNCLM:?p5V=8*Qd
!yH^R5 PF*ERi$@Buu>t4LY?mb6j@pd*1CNkX*G*&&NPmHaqaBt*6+9$I9BG8uH*@lcc><\nuZ?D:=NHlqkV6k*
S*Fi$a W=L>%e8>@NAnTp4h4uh8I9D!GF@Gp*^u@4\8Hm1@mK:m+YTy::ELaK=tIc=:8Zi\DLteV6i!GeiZI@lQ
$?\\du \%>4V+&q+K^VLk=>K<wa:Ka>$I<>+aR4\P<=&89hkQMLNwHc?J^Md1<:T$/uiELlaLC^HX?TmcmFFNyq
ktpE+\ Mi%*$c#cM!%mnX>1V=e>!&iXaV?V^DaYhBY*wILtTJFTp54V>#?#Q=Y:QyFVED*9$l/+X$GyWBb^Yk@K
Kw*dqw V>B*bu&LRFQ+yi4RhD%#Z@<Z&!MLl<9^H55m@hc/?4B/Kn>l*=N@adinp+YqLDX#<kFB#+qw/HPJy/Y!
=M*:4y p?I^\11wdIjei&ekAY6@PHXwW1uRP\d48@b$#/VCpqSN&8llBw?1=j=<54S+V+/%aEPBewMGTXpkb!44
65M=KA @:y8qb%EhwZT\1SA!uNy*NVNR+d/jH/h5VH6Di&W#&/X<&L$cN/QH:q8AA9M8LSHJ^5*HD/N>aDR/q+A
C>85pW <E/44MTG5l%GPjp5#:M$#V1I4AH^Td?1Y?1C/mm9m$LipjZw:Xd=M/jh^t^DM:8lN^5dhY*48!p?<Fl#
*1J<^m Y!Sdi?!upil5qIdB<%VTbT8aiHYbbtdGFu$p^XtdFquQT%*XDjGZukXH&$hqZQeatuu1DW&#!jQ61FMH
Xjj::N q9=&wD?pW*5BAy@!%!p?MGtDCK56$:ImJSGiXYnt1#LIPpI4Y&&HbuJD#yC1pbbbqV:#8Y5uw8^6<Tmq
$k%4HL D59pZ+8!VPP!:X5cq$X6im<:Q69!1XZ*V6%9$H8F&p#L<6Ey<%Bnw=cRV$VF%+uqV@@!@NqM>LCl<FXW
Y9@+MF *MVC8V$Ql!S@uhKp8<VH\@ZJ<kYYtA<ya#FtwBbDe?DBN8dF<X!!JyWcW?4+e#1%hSyL!SCqWymXGF9T
a8&*#N nGD9HXi$y1ITiBht>#MiVVK@<bbpGRy4P%nFQWwmb8F<+D8&TaETq=pMIBbW4I\e=9A!ic<cRlBhG/qq
W%/Ehi qEnbQLY*AeK\bKSE6N/CbXW:&41wRT$bAJ?W&J9BTylc9#RqNDjC5mA6C>ccjS:JBWm4TRy6T>mS#ucY
F%ZZCq 5q5!Z9R<jRXVaNJty#T6&:w5hj!\@nY9jbVAG5iyt?HqpXYT1CihN=Q^==TCyIANaFTN#qJM=tu5pKAu
p6tpLQ %%p4q#8ulE??@*Aw<TF+YXX!EhBj^:C@wRqhZjFd%Zh4+d8+C5HwFA<cn#Nye?&SH6N>>$VY>nm5W&bq
CdD^=^ taHl4thtG?18\JtWt%e:y$jeJ<j6G/4:4cY1iuAtEE<h1JnY5=:?a&\ycaueiXBH4=c5M4Q<uac5C1up
+TtBAC 16PnD6V\V^pZdSyZ:XRy1?<dpkPjI+4Rn8R\=^t5PeQQ+K\cMJVawIkMT=NSY+1PLV$$4$HLZMeQJ*!T
&!\ynq ^:JTiWiL?/LqJbVS$>aK@k==QkDm%B5$\:FNycC4D+yP<A&\5KMCi6>5+>8wVB!4nJhiFnFb:uN4iP9B
+LSKJl AaWIF^k\CKH=1B^#C@8+En$KNkXBdYZ$FG:/#IGhTE6e\YB68i^?>11aq6pt=*1*G^a465&L#LwVHjIF
V9q%BI F@9t@5mXLS@8kmm&pVkdQ@>Hq4be%8K^&ta*TBIGQFdq/X1iD4HeM&DudXBdwAttAVnw+SF4^hJFpXaX
8kE??: AFG/1DHn/nG+TEHjwB:nPH=jj^QaGMAPG<\*qS+5Du5?wQ1<I!/umGYW!<\d/Rn68?:q+E=c?mKD>QEW
<ZmZXb FXD:G5qQtIH=yaLD>Q:!$d\6q+*^CBPB\=^CW8dVw9Jn?Y><acp^AeZ5w?dW&6>u&Z^pLjpZ&Vh+&>#n
ADZ*!G @*1S@d>JI@yH5Q4u=&XC?W6D/X<<ud?L^=ujk%d?XWLe?<c>9h\dGM+H<pS%ad?wED@l>H@:%9%<AC:5
eGc?w1 KLEc?yh4dXaY*D6i6X9%/MLbdb&#Hu^ZA#y\yQ<:nZHQLQ6>i&VJG5j1H?I<IJ\t$n*F=uq96GCMq:eS
Yl\XAy :LDQjZW@u/<^h#Z*J&QWl5X<w5y?n+kVTy#uH!\^8J*XF9CWSy&%FCqeuA=T!B9I+9LFS/XuTW:/GVc*
SY9#II AQ$NT6X\XpY!6KWMnFTNQe&dDKL8Fj^X>=ijKN!ptpQ+N?:L=Y@c$?6a+KKS!>HVQduj!+bMFL$/&PZA
MD/Zwy B9j^\G*uIcB1<NQY5ZnCRtB5p<9%eiE8@&+blQJ8ml4=*#eNp5L^hnyj9//Ru@*a*%^:MJmKP%d%6QG4
14u?mV tb!ANZA9j\XMX$MDlZJ=dLN8Dpk&w%yJ!dWwV:AX**&QXH^6B/84WuFLZ\pA1qnGm9*#qN8X6^RuW!h^
DKFApy ?$Qh8DldkdJVuI:u!^ZTIK9&:D^NKq?PkBtAPw!tjmAT:RT?YDAj<G/uMT%<R4S%p56Sup>yyBpQ*lIY
aypV+N =V@\6^Sn?HWtY@:dXuCXc48&qKLwl#4a8b\bqIAyREmal\PSkZEhDa=\tqKa6GRNRTHTQ1Z/%%G<FqD+
kM+>Y@ QX9j+%#PWC19+H8!DA^Vnd&bQDDPDDP5F?5T&AdhjLau\LCSpail#6A=1uy1y*4/9m:yJn$hA:H\BJEj
XWQtqS BTc#m*SB\RMIjkL\y!=Gubwq=j$!XF&NAcKqDJA&Thw^dE>hb^p=GBC=Aw!V@1Z+t=&IXyX1FASuH1Na
YkS1@q tN9YhBBpqiWhjJSc?i:1y$*wYi6ihLB&+k+WetncMmt1tlAky#&:=CKwu>*=kh$Z+&!DPE$S!LV%ndLR
yV$\=1 ZZ5\H#4Ep@kd*JbR?<4+VhM5e:maqC6T4qtwVIHVkSq#a<#Qe#JheVlX>AZ<45nC^Tk$6MYTEy!BTJL#
DVE+uE YMj4@e1#yl^#B8RYARYXenq?XCP8/DJ?6MQKFatSG@CTPKaYBVK^RLBKBDBJ/k:ZwHeD/EpE#n*bRG$e
LLV\HS Bph@+dYT4w<\E&DdbjZ>jJ%>HS/<&!BTA1^JEcMCSlR+pJ^i!ek1!68%:GjtyJT*i$En6HB?t$*%8PuD
5qQC8+ Pb!EykqVw+ti^VN48XhRJ6iaQ4K>=ySMtJXI4Jb4K8P+6RGeLni5ncI&k<B&Gudbb?H5*>YRhbN&aVJ=
A^FIRc =n!ThCKeKZ$A8+w+NYpn?C=J@MVh\pVSVTXFaY=CGS^ABJe?FZ?8i&?eD<1/4T/H^:Qm#pmZqYZ=uL4>
GJ9WES MtJ5TuqG*S?Zi/Yw%Dwj!D11Tk/H8G$%BPj#41Jb6\VRpSyal@I$$auqNkH8B*mI#n@*/IpM?^tke<&=
t%B:ye @?NSH&jwe8YPq:wQ8D*&8#IG16iBtD*TI!$Gj*#juw*mQ?:t/?+y@bn$cFtethW$^H=AK6dJD46Gc>>J
AkNY5@ Kn9YThuS1KH9P\4el9^=T#LkV@i+DheH%BNiV<eLRlPa#LBpKemA8h&1Kd%n18D<Jq*1*W:^y?*e&emV
aH8CMQ 6J/kIpR4Gll<$8LVjq/GL?CmQl9yEHk?ZYM<G+tMYHZTcPP9/:P#dZJ/QQN6@HAK5ANWw/T!BTb6yGW?
8a@5?W 96RMWbYyn&1aZ+MK:aiqHLY^%!@%VMRMi:$?hK:/jqF885XWVZwFXKjK/A9M/=$\lQ>bMQ#%*LalHJm$
K1A+At GihEcM#c4*/QciEh\G+tNV>VG:^eSAWBZ*A!V^uEY?Jhk&AI:$qR9:CX?WP^>yJ+?C9H<LEA=Vh<cLK%
%bIn/@ :$Mw9Feld?Sn&8BjKKS@MeQmL!J\@/PI\Y9L@tyn@>/*@tuQL/Lu=uebQH@l=<i95H?%>\bJw6=Dij^Z
l6PW8< *SL*mcZjdBD+cN+9NC%IEmWY$ZMSmG*\@eQ5w&Yd>jl9Q$^H>mZL>QYy8VB$jVVQtG&Q=L5jVSLNNm:C
Qki=XI EJZ*$?FT=96b*RVwt>qN@?d6Dwdb@9AF4E6m1jJR#I/!#V$?Xu9?$^u^aFFuj&yStCV1u9jW=A%?*5G\
W>Q*cy Y1/b:hY+<VG&^NJl&Jtl895!49yTyLe^5bR?6y9tFF&eDBGL=a?hl$D!M=I>%:tA55<n$$<T^j&XFYmD
?iI*a! XjkIM=:c1V4y5bcq6$LJK:laXX\5*5>iamu/c=e:%&MyXV9\MiGIV&X1Q@A@6KHIuAe!BBD!SVZqy>we
iCJpWJ KWAwN>81n+E/qyF&ShmF@/bd4$tmeItH4e*ZQcF%5yum$?q!WZ^#nPLnyc!KB#iqyibJd*H^8FAD/CYY
FXj$p& A4^1a<&9p@@X6#SH\h*I1hA/bt/9l&QbLatqDueyV1h:w1hAG&duG4XVaZqi!>@$N#>JhFbC^n\yTRXM
D6dlSH BpIk<LXGTMK5ck$W*HLXaI\D4XWRWk4DcVYbM6Jn1$jT>9kDHd1P\h5wZ4JMkZVmc$mB$Q8na1<?qJll
*jZLVq Z:<PIhW*W%CRJAw+#I#P:R\+lh^+T%uEIQ&NluJEK9k69iWPdbBa19dXD15BaT&6/:IA#kXcRFFYKZAB
L?m9<1 E!TYckjL$cy8ZEyH>88hed>#pZKJjp1tid%XjyKw?:6#p>MLyTIB6Lm6$+6CmC9t*1><MTj?I#5JkmAA
@H1@ZL YTnkummqM:WH1^<uJe\EYcc>C!5qFtbJHet$ak@/t/QInJScPYZMt$ia8:t8Qe<6XZT$&+$H\W818Y8S
w%Pyc! AZRj%9bki9j+d\lhnb=qNEDNDL%t*YbFWptS*?4Iiy^TN:K<^FJ5Nik*wRZMHpnJWZ9Su%4y>A+6c88Y
b5LRtn 6qT+Z:5HpQTyJWpWi#<k=>AA!+DWkktN&!!aYtn9k>^uTnENthFDEFI/t/\we+np+L<wX!h@^lXh%NBd
MJ+>L@ $nmJMcu%abay9IkGc1QHbdc8A%YtZS!A<8ITc!llI%$=9WF9%weqKXlVc=Jw4!Gq:j$1R^etlQH^n8E4
nM&BZW dTBhBtk5:+KLjhn#*@RW>eIl5LiX:m!DRt+W$1LnCtTl8y@DLFMRy*4q%w&n1@LD<cPN$%uImW#HQD$@
uSGP&G M8njh*k<GMw*GchMEpYWV%^X^jWI&/45ju#IXan96:KSh&=^Zh>a<+>Nin1e4%?ZXC=&\H?DGQDiYyte
<6q&Kq n&qi!B>!%pN&QX!#/eH=iyK@V*d!E$5J?%<j5p!ScX=SGNjH>8lK:m#9B&j%ML+lRDi!5wnTm/JFiAkZ
PYWhtQ q*9hhelHSGcN>JwaXkb<=*y@64B#q+pV6LB&TT#h?G<hlaJGVdM$n%RXkl*ipeHZEiEME$6y^WWjL8/:
-A#S5? 000e66bba3400110334 Page 238 of binaries2.zip
@JRLiZ nYTG<j+E1tdyMV49>185:e&EVduB86bhBZ^d<KnXlaku:S8$9:qFp5L9QM!kCen/TY5ZYlJnVQWQjej>
^MwYR9 ch^98IB=@4I?by=eP8#tA$8P<9w<@XBAteYE^Me9eKmFI&MCC&A?!*Rjptbchk5FM<P1@6DF1jE?8GR!
6Jt!=H BP+1j1CaP:bdH<AS6h@y6/uC4Z>cH:!FFwdX?H@abTp+/AMankj>iBYaDV:yL%D6t&Q/nCtH!yKBHbjN
tjIYVV C^w8n+^Cp$mM@Vj1=Z?u$6NF>VP61Yj%h!6YeiP@$J#l*:R<M5M1h%#SQLMVRj+ja\B=<*DAu9t@tkZy
p>9%!W W^jND&!d@#T/>:8Wwj@qF@1@1n*tq+C<9$qN?p@iu9uunSDu+&u?#R/!??NN=\pCWIj*WL<h/NLqTN59
i9DEFH yuILIkjj=GqBw4#<%N$i!^wM+VuXjh4WCJBa6%I^#6%6E%b9L&!alty&8Rl8K\mR!9qE5@+qiY1#R>m<
5iWAdF +LL+i8KiJF$B%6YtCjed%!<$&*HYlhwHItTRbVw/Q:hqE$$:n*HYn<99&TC^%ASaG9XSM$RQ+?me+ech
hymmeI #S5D#iY*ete5/6dAm/te>&9n5p:taud&n&dMB!JppGWcbSNIJXm/Y^hjt5C4YiQYy11YmmCd8u%mcR*M
1XTXiS 4qd!C6Dc6yuAtRGKLMiL>L*A&A%4N1NAT!>96Q*IZ&=C@#iwG?Ec$kHwc!BlpcNqAQXW+SW@I:5j15\!
+<lK*G 9d55$!!=ZP?Qm<1Ike#h+#T=Jyp54$&YjJ&8TjIkHPeuq8dq=Zl&Y:Q\d4yi:k\LGL5TQuFhhVq<qh&+
mj>GX* Jbd&+/LL+hI=L:=8$Y#T+!HS@NP9^iW6Qb!11L1qdT*Xe^9DiVt991RIqNL*iduE/j&W6L9>+CDLXK4%
/5yiNd S!yhIT6\=j\5W=CGe4n8*G1Aqq=</WydGpFdtyK+tj9pIGe++kdSlWe8/B\+6qqt4LuTl5GFe4$I:\W8
!MjI#u d>$$=jtWSZLQRDF5!dnJwA<cy9TJYIaMBL&\QZ/YKe+cjR*T>d/uj4*ZLNPIp^bl*u\Pkp&6b6qbdl6H
%q6*4V tl/y!4bSSeqGVh=<L#eXNd4:R%j8Zny>4nZeb8!Gw4YBmHb/bn%XyWR4J1Qq4F\WuGQ+HP8i6*LNM4W?
@+#I>l M8hILL1l!#hkyR>=hbBa1ymhGym+#AJZpc%!bbe>5DqPli*J5&ibPn88+Nh!8al=J9<D#EJwbNT+AyYk
yCQiK8 &aE&=Zt\=A6TVq@cw+Cd6X=:$Hu>^NINk=RL^dKbSCdiu=1CM5&GIAm:$GK<<hPQ6yaSyuCXDjDEZP+C
M%dc!t Se=\bk6E9P!1h6DElQ$G^=bqCmRa<FkPVy?ZbSw=Z\dpkyVhHMTZ55bZnBm>6>S\BE#F:9:$4n%Batqu
F%RQ!Z IHFW6#KwyWEmGaehG^Y>CmE!DTp+DcFT^kuIA/GMRBplVL%GbFM==tib#t%!JnJHt:awLVJttewp+u!&
Y&cdM^ &8V8LQDZLNQXcR9LF!Q@JA%J9^BYk@6ahHIA8L\H\ccYiI!DBuCm#ky?:APnP8qdVRh/aWRlbIYWZ<9m
aYTK=A 6ahSIPJ\C1lt/R=YPWKWH&\Ky/=H?w!ye$M8/TZP/65bYcb!d9eWSkRV#Nj>^FL+cYEmbw+A$L^uXX^P
$Nh:A$ >\\GT@iLHB8\=Sy5!18I8J9L&iZ%AkiQ4P/1nAE?tl+Pn:SEjwlMKNu6iL\ZKb*LTj?=X%q^^SuRb8G8
4X=k\* :pbY\%C9DDa%SmdaXyyW1jQTqtWKcA?:LK$<HB5Zi@S%$<STta@mNG6%b^B8@*IL+WE9QTVLym1=M<Sm
M8mKkZ TT#Xdy:VtW8Jl*w@5H5Ge/:ii9hHnl^QuhKy=duc+/LTIGukk$:Q\AVcT\iF8S%G1y9Z:Wa@!%SZInI!
4M*JPN TES&ei$Ww/:>dSlYuS?Xhk:t>ne9S^655c6<%PuAmi4l?dPbFw=8X*P&V6i*pylYkd=ScY6iJw9I&1Mn
ppB6V$ EP&TK>q9dkI8!%TJX*bku\@LuNH1XinX+F<4G/#=PF=/1@<PeFDcX?8ZwtPwC5V$P1^G8K5kP4jy<wtt
=i1B5q u/5L<k4ntiF>dBk#By4e?A6$@1$+Znm5l6iINKdj%nia%5$l9S%Qkjl!P5FiaRQ#LGVi^!S!G<DPVPV8
WY4F>a HA9I!tiK4Ptd?A8:iad!ayq1nwjVE5bqR^n9DYQk?/w+c68*nnbLm+Be=!<PF/Vl4qEQ&$>P1H4SjyIi
6:qGi= YGY/q<MB5EDYmwP9iciKi9<neNwQwqk#&Li@wI9*q*j&9&!G6/q=Dkj@+V9?Nkn&+Si?<Ra^Q^:N:QNL
u6&><S HYuD@NbJ@DWR:Qh?\d/uyj+Tti:F>i8Q#9T@@?h@@Cddq&u#t</*d9C<ih<a<>ja69<+DQuc9E@kbP@@
P*cue= BNSHJj59</*h:V1>QMD5::Au:V6p#aj59EPEAKNcyitm=6&*nQ=QRLkel\ni:?ZZSS:9K:1%dA/cF<K#
P*kZ<c iiZClSQ^q5?$LXiCLea>b8hCKF^5+8C<cKVAWXd@Y#H4>ZT=Zm:u!@Z/hdwN!\yW:V>p$Z1/Q#N/*C><
/ey!!* 6>HhLR@nCktV8\jwH4VW@8%Y5&PR4GC>k:uMB6y<MPFQ/ZDA$LBdJ!9D=PkMpeP:yL9n#pDZPMKqeY1m
n8bJyV 4mBQRP=P%^LhGqE*\Qc&4iKHwylBFGpaiWwNd5VwJ^TieCJW9XbP@E*1pT1L\kNRSW#Z:cm*dn>aK9QS
m>ABtJ PjA6&@hk/#S9>+N^mZTDHFialM6m+qJ1qpIy1Y1ydYTqCHZZF@S96+8WS%F!9L9+WpTSQ6ew$mCpqC!h
iS<bQR BDwuFQ>6ebQKXRY6+FQEpTWN46MDHQRAyu1eAECe#qK%KHDy@NIGhVGc%MYIjK?qQY5m5DHljEBE#L1F
DX6TcQ 4+59HRlEkenT!PtpLGdZh%k81%&VYk5HIcY\$*L<N!NZ+q^KT?:RcGE*X?Qnc1&*l>bqta:I@b6uNiSb
%&i\9V ?H!EmJddR+F^H@CnXw^?TRi&:4?1\^^Wb?HmT/%clihX&k:TiSpI!!lTiI^qC=^SVw:1=CiYI9mnLC98
hed=?I Ka\SjMHGnCW8jbk/PZhEM9S?q8qM+AXbmGyJ9y&&>n/klZ!%kqyTa1m=nQ4QlH\p?ZStbuXMZPJL?#1X
HnRTk= K=Rnp4PllbCSR1#ybkiPlQDbQnTT<TNa@E9=ep8n9I+LYEcB^%lXbiua4T:LXKXTNaCmaewmH+94?#YE
nmHCwm #Kyj>NaianlRJPI@8<p:Km/u4!8:elljt6hqYlT5N1GtG+e<K&+yCYSc%/8^Y^Ac!Z?Q/mik6t=/XltR
ZWqJ%+ ^14Nca8Y^de!YwlVc=by9<niS#ij4jhuJee/&hQYHu=mIctF:YHTc/NJ4$F<KXCe!@Z^mAGGeSI:ubNc
SlV69H ?b54D<WM\j*BPJQBE#E96yEbnX=>wN*S$G6^iA/!VNid\QuS=+>Tu4l\LIQ^\*kS8Imqi\k?TH4h*^>G
WWu+FF nBd\!Zbit@4AIN?\jpa!X4I<CCqFd=jB\8?bt#1Ly9lYShk\<Tt\jbBq!nQN$4JS:dS*G=TJ/YnNHmmM
y=:8?y Aq&8Y&Mt!K=j^+?eNqHbIek!Bccc>cDAMw1WMAe&Edy^KnQD>mA:N\kyub6upRF+A:a4a:?SIXVq5E/A
BpM@&& wJ&Kc^lj#t8Y/WBe8dWDl>Dw6/iuaaF$ZZ&El9$NZ%Fu4>%6$JBSq*+R^Ji!n&L?%ja<ChhTma#WbLBG
*Y?A@\ keHtRWmyujm\MSmuI?aP$$/=+pC<cV$VGHWGYLJMqTThy#Hw&N=<*jM&qKXCcVdwd^d?EqXb9tyYCbnJ
lm=lY8 =JQiu:6kW?h5F^XAT?Hmq!*^yhP#BhMSi!ZpGY<lyZ&GnAhGa4V+F@RGjkQ*ITyF4i#ILNQSbbt/Dm@N
Yq*A&A ubdHnH8iLp5h4uD/\Z8i16#!:uD1pHD=PB!9q<Py>FNPkYIml8u<?DwC4MYXp6ZPM#q?!jBAN8!b@@?w
Q>=M?& ik$y#VY?6ESWcYjdG\JW$?QlDtY1HPiS=iuleI<RZ*4JdJBqK58%$@F/^%dd!w@Z>e:GXB!+/dY6h$C\
<jD=KW u^/uhGE4i1XG9wWcGBh=15A!W\$tF/&k:#!KG4caC$F!ApZTbbq1jCu@NEB#=h<c=11/VAiGuZcD+%5m
:hAZ5q &NT+LFN*8Mu^LdphG=ha&e$$dF\YwDIcbBJtlK5NhQ\9RJJd<*1w4nFdpMLkmWThWVFZ!cBY4wwS*ZZt
jj@qi9 u\S+=&WnitFXYy>y1ZyVS<6WY+N=HyjIl4F:ZtpMMm=EiXTj!H:nF8&1d9>E8P#*WqA@P<GL+h#\*1%m
K9qdSH MYFlE/l<@F4HWRjiSh5FjM8ku4N=6Ab99KuuQqncjBbl&SeWhS@I6^E*R94Hi:=q<N5j?JbB9S*iAhQ@
1mWlZn Z!ZAdX=F=k<a>?ju#<>@jQmFG9tRyQa/IIN@6/@^yY@JqQ5JeAjA9Z:Hdl/%8+SX?+t!caJW$aCW*?@=
Je@ltA d!F+b9%upbha88$k4K>N?E#1Z%KC@GiiA@%ip%FZ%eF&&Dj:niQm:jCTbV19qLjq>/^dR1^9BItq!:HY
mYaLi? ZdJ^&cn%?G@:aNMqPH%^iHik*&!DR+??D<dKw?N6YdjR/Pe>hqWmbdT4E^B=15GtCyFXqB6V:SYq%#96
KRF!SZ *^lt6BAyk<STwut%e#+*t1N?j^KtY@q9?&DVka!#bGL%nneW>JQ*kpM4%<&1=X@VE1PR1wuG+^+CCDLC
S/?MQY 6TmV<%YYipG\KjC*<?%?$eBSKXA9>&h%^/:8qB!Q%>9%DINkG!TY!lwLD8&=%cK<nc>FX5qZTYul?G<u
Y?@GyX /J*5^u<#!t8AClIemL#CW6?M$@X+c+ND!&4>1+L9Cyd#?Jy4%ijyFh!VBRFW%JBpETqebCuiVXt?byqK
Cmmn1k mRcIVWyP!CBR5MQyLa8L%1Y>hW#9iIp9dSh5e?HM=aSHiu/t#=ml+BQdy8RtqbZXnEMRZ/dS8juA*X<Q
CyEGTZ LZXCB@IGVZ>1JLuX+ASl\R&lH4FB\#PWc46PL+jDGSq9RbayPYchXjYtp1$Gq&Zc\G:PFa?:?FKFa:k=
ZJlR&I wGmiFM/\/jMRGYtdV&^Vjy!LmSkBRQRMmBmXVAj@JJCaIDdL<:^9/uKm>%p*Np>!H^%1PIAtJYXtQXXT
w/%$W\ ^LZMNkm!VPG%n6clCPu$<mu9tF\9M#MywZ8NL<&lYB!WI\GVt#JBSqyZ1!eb/B+BkPj\l<pb1aM@EipF
Se%FQ^ u^$&MW#QKyem6=umi$Y?tJT\tbHYqqYGGq=SR@K4Mlqi<MC9&/q8k<lVRqLwCEpc#a9MpPa=Kk>&GEka
IDI@jL dG1%F5iyY^1?&!^G4q4nntaIe\ZCK<W9HH+H9K&Ia$WhFRCS>?A!%WDNY1bblK?D\%?HcJBM=wkAqe4k
BEh$Ru lFmq=RSWCii\Bb9&AMw9S&TbntGY1Y8Qa4^B5CtTiI=K8Zbu/KbYQb1:>cG\FF19Bd9BXHGld6JH+tmJ
pFNHiG wCL<DH6DB1t9dXbqEX#$F>TRl=B*8#a?ZW1kjtHpcXj4#W1J>T#*^&:6$j5VbJqm:&tT!+kDKFMSQqj!
Jn/@dn k>=AmAy>I!Ai!mNppV^n+EX%Kq@4k8$Y=Ew8w\!mE6eiaT&a@dPc6tb!/aQ:k^h>hW@1mTd/Zycy/!En
:k>XJ> cdP>!#LFZNX4JknHV>&H<cYYpaV!Niklm8bbNXSWhNIwT#FILF$J!>%IGuBYPcluE=CDyD&qM9nqjFNy
NRBRGe D*mTetWGtaScG/CGIQeBcMe?kk&!VMuI:ck&#Nq&QFkd$l>#Ap*L@PbutR/K$=Ei*5PSH@$8LTdPd=tX
BcqK$j !S@#t@G#VHZZ16iJERVk1a>TYJaN!&^JTK4QEQ1pyHa4QRQPqmQI^RQA5Y=BDiu6XW:q@Xa4L*wNR*Z+
=t@yVu Y+P#tbe5W!m/^^YbT&yG\HnBym5cl+5k$>REntaCil&+p5/neA:mT:Fi+ZMHq<nBkjKqIM9ywjXybkEh
-A%P=E 000f95a6d7f00110334 Page 239 of binaries2.zip
^@dyd> \$DlZmLcyIy^Y81X=/PG6M/+u=ZeF?TjNk=@R=TChXttM9J9$b#hDwjL>i6C>\$tqq=h5PtR*iY6^?N$
WRLqS< BH$T/+P+i6/Sl6KXWEJ*#?QlIVjL##J%NuFutLA$RQC?u8*#BJlPykbbB5n6\G1DqHt=qM<9PeJE6\8c
iIjEFy Z6!tFVZEhL18S+eq!*RJ9qD<4a*/^jwmY4JMF<mP5RBBq1uJq=DT1PQ/dWwi=Gn&ANqYFC+INl*YuFQ*
+\>$pe c^AtWQ&5l*aRD&\y<Vi<%?YL%lyjFKCGR:DGD&tRIj:tbbt/#DC*96djt%h6<:mBcS6H$\Qw4Ajk&i%4
Fl9=Nt S!iL*1VTh5H+jQ4cyy+&D8eLWMNhDYb&jn5B4&AVJj8FWWkj/N>WN5c<W#4*@V5?\!cPZw^=#I+=bnc#
MT<yAd u?*>n@bS?*L$G@\61A%6CKY>=J>?Y=<8t15*aF*+K*6q&M@/4D<@j*:?9<Pd@48c<@i%?/>k&9A>TDb<
#jLALX tMPG+X9%<l8a:V&#:8<^G9j\%+/ab6=5X=nZpP**&^4t@adH:ut^$bT>DKZj8/ei=&=hFAT+&BDa@H1m
n@#&F$ m+&#N44wy6uj+LP?WY9w84i?5:uH:i<J\Jy+Gy$\+Qh:tN89bAk/hnT4VSj1jNq1kk*\:a9V%j/6B#qP
4VHX#P <\4=V1EPj<=y!:FI\HCm?h9?i!B4m%8neW<ce?<WIYCSMDZLa?*bX?hE5/W%<XInHWJBQ$A8!T&BW>$<
i#LGna YF<ZTln8hn9VR5m&!TXJ+#5JjRbNAH>N/tILFyY<e/ZpSw:&VG/*Y/GBiDM%p51AkBawLt+*P8l$Vb&e
A=LllF d+RR?Y9Qk#MSl<6P?RCw6wY6P*qMwQpi:SbaBa%biVm1w^>>&Wd%bS5DZclWNCtAMe&*/HNWjVBZY%DZ
>TR1b6 jwJRy\@iRbkpnI>A?B\%@YAlXDWX?Y<XDbbb<MR*/9/W9%Pw$SbwMhQ>8wThYWXtace+?GA&DL>eZcSS
Z+qd4E <5B^qk#a%NYNhk+Eu</ZDVyaC&Kdl8*SdTWHcT1>^VVDam1tXhahh/VXkIyXKCGG:wWtS@tRAi%N:tp\
/>&%al jyd$iCcuWRwN*BJc6kDMlndL/ed5EPk&qL=DIpaZ%9W$KCPYyGE#9YM:AT6>jD%8%?NF$#dM<nH%:G=W
!kHi@H XDY\\#uCC4MqqSbD<mTqX/bG!Kp:H<?$iQX^MjRqLPk5Q>BLu8AGSkyTj4>A/?^IFluIK<IM5NCnFy*4
wQbnFa b8mqy^QH!pJliAemJPCbQbWVVy1%ME#KnZWh!>GYXnWQiWM+/S:?=p<:6*GBC!S*GuGtTq@Skm=jZGqp
AXbbdX 4tuXD^Zm!5el+YA!M4R9n#9M=M6t:GZM&Py<VH5ZX>kY/M&+<D:hK<TSHQeb&thi4c=NE<^\Skb>&9cS
cNca1M 8p!NJtwBG^Imu1QpWk:KM4WpF!*CiSJ8nqJTA=tDM^$I$:F/4M8yuR+Juj8CF#c:j^Z=kl>wtcmqIu^=
&cB^*6 \N=>jKY=e@lLp!eDE#?&S<tC/8uF4Fpy&8<pP^GX!1NcFiTkdB>Qh=%n&/w541BJk=C:GamPuEeSLp5p
+ybwSA cw=T8W%D?mASGE/E=$PeL?%bZ!AIwZC?lndeB?TMmdjqPcEuPlJtGkP/=CcRhLnap85=cy+4?lH6P9P5
R6:JW< u61/=9*y5DEVhS#BMKy4<\cG<ecJDZFBRBEd=A+me^VAnhXk!$p>?hDF<1nd?69!A4c4#?8qbKh1!89y
4<p8:D <uD?BVn@/Z/<1R1jbG<uwGcinC1lTVh&mDu9n^PAWwtP/eC/6twcpaaEG?e\bV1c*uebtcBPBWtuB9Ln
At:YFH NGDc#5+5u>A&ePX8ZPaDj^&^LHh$tF!WS^Y6JClMANQ6W6A/WFPKY85tXaR=cLaKSuDZ>SSIewcF?<SM
+hu!*E nVVuc/jBH4kdPCB8k&ckT>::TP9N5hXHD?YA<6Ai&JZ^H#\Z<GSKXYW9:VGWb64ZNjWYP&*Sw1F/*G8H
uuH48b R4u^p=jJ$#&ALB<=4TPKk<E1n>K?=kmGkRtDmVpZ6QF6IwNQ=1iSJMKwJM6V&YPJBtQJ$iK$#8w5w4+Z
%1=9yG mV?bbTRN5W#IBKBK^qIB5Rd/yeA%i#qcSPPHd&wi*8LS\yVLZ!54/8&YiLMy#=e+nduEIb4H@FWT!:Dc
HiFtQE WAEwppd4G!l=eEHG$?>!XG!9Z&^6Pby^DS:Z1+9>+8G?kA\!lkbV:JXecK\X<D*bRPw?RyDPT1Q@ecZJ
AwY%yS qa*h+T:Gm*iZp!88h*XM%JSVujDN+44K$akbSNd8mN\!5B&$Ve86adjbLW6NJ<L%^Cde@RdMy!JT#=/F
\<Tt8C Ch=S1:wQ#B$NSN*&X&w*dtF@@^9?&n>IPjZc4c#EFW:WhA@#bwt?a>AFD@nR&NyLW^%&S@9:k1:ij&u<
=Y#WDj +6*+6*4\tljpu@4DN5DJN8l9y:5!IV4=V*Lb>ypQ@!^P<duk@8>FQj:<@Qu=D/Bp=9hmnM$@AMb>e!cj
L:<APd +tFCCG@+X1y8j&e:+L9j?:XDtE?Z^E66hWtXY$^1CPGbJj=>h&S>CNNaXl$^j4n&%HVX@ReL%jXEpX<=
*NaC@l cHH/#SZe@&8j==&iDXePDc&n%wTwBeJ#Fml&jDERZKw:TEjYM9EHpE*K^KSwQ+B^&+t1Tj@8/dmkEewY
&<IYFl &C>EKI%kPl4PI8?5Jwp!V=YtITpT!!^&q:M/pqIYta?:lTYYeDR8H?kj%=1Q*4WLmQwGnHQ9?Jnh&Hm!
tNJubB kQDZ5M/<H8+8QVFwV==qdb6qLQndM4tjD=euIRnKY8LdDdY+XG**+!W8H6nTjuN:qmBDXuRjd=AjHpw\
u&n58< du<&C&cuJ:1CTC<ttd!E#<IlVP@9D$1+KD=j$&jBaqm=K6pApq1H+pQKml5K^=%XuuQ%h*G*1/y$h?G*
FwHdM> CJbBLcK#&%*h8X=PqJmhH8#nDhLF/y5BBH%qFttF%\<btVV6lP=H>S9EiTl6=M=q^6a*8Qm>8%aL:pN:
#SG:t% q&pJh6V>a8MCqVeLIXh<=%5MVdAQ5WJ8H5yuj=4<%+nC&@F+8bL#MJIZkP=ZR%!dh@DSV&Kk&?CqhZq=
^e5w:X BjQlJWl*Hlb@eZc+Jd6Dq>4/^/CkJeM1qnZ6GC:n*&^+j:^BL+E:upuwqKd%XBdQTDNJLWww$PVtKDpZ
mn6LdN Eh!/mASLHX=WhXX1+1K*m^EEijlcSbAu5/bl8AS?!#FlSp?l:Y/HelVG@ba&=bJb?^4n1jHM1!<dh&Le
EP8W%1 dw#$k4y88ybaw\EIj#!kAWcB4PMNb>AD#=R1Qi5B:+%DcQd5C#H6GLTuLPTH\D&hJlHq8$$w:kkNPDHZ
>/X^YB K@^Mt*Hjp/Eedd#H+haicm$%^GLMyA5BDkAbD8Mu:>pi^NAWn/VP!eRD^!Ycm55DY!H5S&BdWZi%QR/D
S8SHWD @1awt<\6m:b9u4Q48TTNXwaL&JLX>CLMD9ChjXhta1==CW^pi=/J?p4N<=RpYb9CWqH8XSZH#\wA/eCa
H\CV5l !uymSm:hF\/H%Nn1ZnR#t\CW989*n$MKcy%<&*MB\QP41S+!>%bS#+q+%>?<+d@lP@9bt+bS#a9aWh5D
#@n56h Ry!&=*/9y8IKI#\#^X<u5KkkdAQ@4aI9IbC=Kc$m/VCawD8FR^9uQlA?DwM\Bd>d!\Z=Pm@:VQ*CnLP9
&lbnM1 i%mj\ndhVwHiwDj>Lc/Y>6^8hb9iiZ@AlYaGp?69>!S?jGEct?R+bq1!4PGj!Clyd4=+n<QFPaQdYh/?
*ZWPph \<AEIHKYXany#hh9F=D9jJa<ajS4i!nW*6<j4qC!%n$$!AL<8yYVQB1\m>PTMKyn\hT*P>A1+@ctLp?#
cFac:P CtKZZtE*JccG@E/^&#N>DdV<qWY+E/=Q=q*ci9bWH#N=qnXNy<<#dLkkBF\@\&dV%yK4y?J\KJyq:dKK
N$yj9G PwaljB#1DTJSE\Jl*IQqkTF6%aY8?Y9ew9XcSi@!V#ekTY?9+:YbCKu!9D@MA=61d8m?d4D:?@WtCB#F
%MIJ8K q*LjTjh99WX9&I%?9+bd$y8G<j86jF$k4GeYeCnee$*lP&M?%GC9E5Y*>h#jLEP^5V*AJNJ?Y/Dc*YhM
:Jp$Yj $FcQDQHd>dd=N\Iy@mpK*B<p:h@:?Z>RT\MEFAACAAkAHFb6Jda5Q$IQIAAANqkAACaAAABndGqqduS#
hCM<V4 L*BueC>*cY+#Mm>RS%B#a!>!bZM9dYM+iDE$LtJ6eM^dQc#5NubYAAM$EN99ZtuGqb8+m85BFuD41R%5
i:EcIa ERQd8b8P6b5W4q\HCtBk8m&TICuT8FdlKpW<6h*Eqa5FSE4<l\TpaL=D/t@t#4#*56natjh$#=CT!MP@
B4BRwB <=&QQQQb=:@:R=E?9*8uKQ+Y<t6e@+444+y*<+&@K^=<95+Qj@%%F9RQZ::@@99m?@@/96D@?T@FP??<
V/aYHW W:#::49Fi??>X#\@Q^ejj9ll<hFHH^Wjj@^^<epuu^SjjQFF<juuu^ijjjbb<ituu^bj@*$5j9@:YQ^n
qM4Wtn <YMS=cZ+n^>X<iPj@qV<\:@>P&w++D4lP8P/=PRBj\:IP!D9RHp^Q*JC@kqjV5k@Ij<W<&6u=J?Sj$dm
eB>y45 nQ^#VEWXF?SjpH>B@kWbF?SHyCQT<bK4T9>P8M/+KC@t/9HuAB$P$PEAHR:RIcpEHR:R+RAhD6DlAB&T
bb8yQe t6DlAB$P$PEAHR:RIcpPHR:R+RAhD6DlAB$PEZuR+\A>D1SHnLq=TSQ/h<b%\SX#p/HLCbYjWNEJlb/k
Fmdqq6 T?wG*D#l!\t/uKBL/ldweaIiJ?l^PqNi#F$FQW:R+RRhV6CB88+EQW:R+RRhL1k4+t@1R6TV@%&t:n$p
ZL>?cQ ne+HT5je%cn:DJ*P1QTMC5:R/a!/#:l=SmHuM=WX<*Cp8yGQ?5?w@+#/canP1Q>M?hDlDB*PMcbl!!N^
6u^=6F T4YVbnT<F?l\RZ$Z/HcBHljWq+cY>EAjZKDHljSA\>J\+/WLhLqAq\8W8KDCNAYk!\W9Z9DRBSpZ/ELV
Ycp=?N +pK/aE\8$PXC@bF$whqAw*BPW!qCl\khIuTI$CFCl#ThwMMFPpVwEKHDBV1pKRahIuTI$CFCl\khWDR8
S%H$$H =EPHCB$mhIlRIKL?C\1LiDHmwhPJ^knnGKpPKy8iPSX@W@^#<iYZZ^bjjjXX<e$**^Vjj966<eMQQ^Vj
l5q$G/ jjhh<hNQQ^W@@@^#<e599^S6&^dGtGIe^$L@h!#?/a>@^D1tFS*V@+LKVTp1q=K^WMFb>!6<LBT#p>!t
>4/#NZ 9jQ+$Bij4#th:q^JjNtty+@j*6<?+JiCTZw$NqAK$p<!bEZw9*PGyHX?Vt?p8=h&YS8pje/*/Z%<!hJi
5!Km!P !+d91<E:1/1>$H=N&?BbE:^Fj?S4V4>Bp5d=n<*=*nAV#LZ$m*R8Kwq<=!TLB1&e$/HiCX:%ki**#jDW
X8RPWy tnt>qi&NyQ^=uH#=JFN?$:dqp*Cl+bP<VpPHWpd$uK#cmy8k9Ypy#cTPyEyphZThnuQ/VSLqeiGh$YLH
>85Yyw pLbl/KLD9Y9bLGpZXDqm1L\R/j&eDqbJdT!Vni>pcARLqDc>:KtKLJFtYhyJWn/cH\LcZ\?/qEa!Z?j*
I\mI>D H<uABJZydchTPZPceSbn*i1wwNjIap+Lt!Y*>>QeY4t4114&4G!m*EtLNpWcY=L?yR^BhhHKQ1d&h<IG
&IX%X/ Xch$WBZu:<8wh46&J>Ew6ePANaH!!%KVdEqG6Y>#iyipC=FYpKZu?XPH&%&W!FjHLw+XJNJnPWqKQ+8w
N:Laeb h=X&e5@d65F#QFDcY<bG#Aj9w&Pi=uFk!u8DGXI*Ea9J/:+^YCk8N8lNa*&i@@Q+W^4c+LXkNh:*$dAR
/n*P1# 4R6BP+@*QJ:%hB@=L1J>NdMNQWh4mEdR!:>8/WqYqmZcn*y==&qX8:cpBiKHy#%DP/j:*58&qet\lNX?
?X+4u9 YM^9LhJ:%9MK:^p*QNN:#5w&qY5hL/F$6%MlYWBL=WB:^WYD^/CCR*PlD:yk5tiG&k*qjVJe$@*F<PV%
-A9DK< 000c4c6ff6e00110334 Page 240 of binaries2.zip
9uFb:= 9>lLi6yu+$j98hVG>LChDTX$e%1:dEhVQ9/EtI\JLJGhC4VVC=P$p<G&&YDVk*QFN!d?:u94<%ua>ZGd
/B*Al> AYHSd:dw:94LhPP&81W?>@4*%l9?8yV<>di8j<YyBj>8yL8jV4N*Tt?qY&B\!y@^>L+piMw+>WATNK=y
DS>bRT NJ1REnQS!nEBm/Gy=^:KLjDdiS:bJi%D$\Tud/S=KIPGFYmAHmH!MpTV:EYkqdFK6pqD&%#SA&pF:N=S
W8!@+H Z59uB^L*aR:d1lY\*!WZ=aBc1qL5^puKF&t9!6&PM=L:i*LkbKJDIDt<lS^XHFTMVuQ<BdS4$bNHa^>J
ceI&&: k>ha^Ek<pH:embLDhMmh1EmP1!#9yGEGn<h>^RCB94Ea5jba:jch9=b!pdCLa?%y1Y6JeyNP$5H!p!j!
L!?GhH F6IqGT%cJyWSZa\T=cNDa4&S<mahan*A@n?TRRLuPlR9T%EqPce4Z5qJ=4TkjD&&HDh<$G$4>lnuy1yK
FQ+\:A \58tLC9C^\dnuhJXShL*FYAA<:e9ajql&@6!u&Y%X:C<NwTiphGQ8ndptVuhAP<IB=9J*?5%%1tJdmS>
?<S*pZ 9RF/JcDDKknWn:FSHyAT:KBnY1%/?#+e9=DTIeEi?djSNaRBIh*FiQA8JK?YE>==K#:AMJ5F:\DaXXKa
uC@iVS $VR\Nu<Y\HmEq#NPGnmA1Z^9!>LT@j4X4kp$+e1Ew\u9:Ad9!M#NiGkYc+u<%A?bJ&^^d<JLP?Git@B!
ldG$Sj 6wb$*/**E=:/%?QYNS:PPLam1j6#eP@^@Si+eRMj#4?iYn*EuV@*@1>c@\yH/%NZ\Pq9FQA91@i*KH9#
Hac8cb @q#SSm#\B^CaaM1/iVytQnhJe#<>q*4#9J@89!luk6uF*=n\D$Jn!tb\be^n9T8Y%@%4=V\ZwZ*Pl*t<
pTGC%w L?juVYLi1Ak8+PT&a1G^*b:V\qd:I&9&HH=?KZt4*!nVI1Z?+5iPk#bGlu#?YMI\H*e%iq\<\&lCiWH%
eEPA$C Wut\+!MMRRi4Zk=PC>n6D9n^BwqYScN$ML^$qHbp>!W5=AMJVaB*DtcY6:\D@hjTS%tD#+J:14EBd4BS
RYRCyM %kd<Dw^CNC@piJ&P18*ECDX1=DTmebL+FNX*Z<J$C4KD+H&N^:jI\MHEAN:%#HWnG%MQeqAh/mjLLb5*
bd@L!: TS*%B\IGE4:DIJ8P8Y/I9pN>>!V1J\InaIRV\TakbZIRA4RIQDAPRy6BTBVtYGyj+6t9qTC1MPD$XaeP
PN6GAP VBy6#QW<pLHl9SIAHeaXeWLW*\ukmyNe1%IB%RGQWlle$dRK:=AeayA<G6^Q?S9ytaytMCGqn#IcIRN/
Yw%J@1 &Gey5?S#GkkqiDB6S*!&BF6*pa*SeHRF=*\EpDLiIR&H#HXX1VC>IX6FXKp8Y$caXJh$h$+9<>>*?^ce
V<qj%Y u4Y<WcZR1*^^\TeT&uc6JLib!1?GmWaVQhXKe6B#&ykaE9<%tB%a9ucRp9Skc1D?wlqZ1+$J^c5^:&<N
*dB<+5 GEt+A==Dwq\%!mb/VDVb\hEDtLbacaDHTKTZmHYC\&Wj#5m/WcDnwipTH:Y$FSKTHl%^cCeqa:AaXD@d
S<JqLT 5lmd?ID^VR&9uB\4&p&l@Su!>=CllpG=JZ<&k^9<t#+lJEekM@QW5QTFYH1!t!FMn5HEi>!C!^P?V#8b
LM1Z9# <*5&9:eADLtc>ly=*Q?D?1h>V=>eu!#uQP9Ziict=Md@mYHb*9Sd&8mZ9hTFL&/di<*@dPbC@!8bL9mN
%W:t18 yewF=H*P^*Lqj@cGD/c!@FV8Y<yJB^9qK=kNP@P+B@JN@E<?!eD&qZ=d1X:^wh\D8HVJl+yd*V/*jNj1
Z=tZ6@ S@IP@:6KA/Y>qpAtwQSL1ddy>F#w/pFb4MAS1>!#J8wP6EE?qG@mj/E:<1wCd*qd!a:QMCm?pV*6a*qa
Hq5HY9 mYdAQLkuFiSpB?^>CV#8/<A/:!H>nR#*$pHZ*Z/uAaF>yAWSilBN8AKl8T@liZVwSj6Iiq8QI>u:LP%4
@uR95W yKVudBm1AbaSjpl\\G9+L\/?k:8T*TwB8VL^VSn<Tey41b=+IH8JtbZp<MRVXXFQde/j$@q?/J<=E\^?
QImTwJ tIpqB==^=cXEj\P68puKXS4dANlyKbIp?6aL1dGGy4SZ4inJSEA&bGwWl>qQp4dH=:Tqjew?tcKcm%dC
KVV*Ci tKt1ct9ZmFb\XLXKLkXjJbZLiS>ImmV=KGljjJKGQEDCw8mVj$RVKw%H\\bP@S=aLRpRw!5=peKEtCHn
hRwu/u HluAGBY<AtQ^91L=DPeG4mT5I/5H&nBGB4!IXQ=A?^$wu\CP:6iMK8^4c1<njMKZNC<J:!\iI:^#\C<5
hip%NT X?BdPZy9N<R\&R@C9YdB9WC+N^IjB8+By#G6WH/V65p<*W@q$@%W4uL?MY+5iDQ9$\X@SYTY@eNyI*l>
4=N1ij *%@lD4FlG8BekJ?AdmHG9*Z>!+:\R1>9cQPCqnQSN:MHMh&a<Zl=<bcii<KmdQJJ#kCYD\Lu#+\LD#:\
l*/V*a !y#Z!XMKQt#eL>wI%Q:qm*c#$#&>pDT%W$@l9X%u%+L!ie4n?whPy=&ZMLRA*4lYE&VXBQPCqNMHhitP
8Rkhq\ #u!iBkZKM8!QheIT@kVm\c*ldC%u*LXqXj54\4\yL>bQdjt?\D4\T6S&5!>n?=9ty*6/aIwqe%tD?XWK
p&!e1D ?kiQ:%n6y1Mhyd1nSdZy^?Xe$/@Wi66?P5h1aQNNDRMY481#N\TjJluMG#t85FiD4tqqk+nB=H6W4D9\
=bpmqp H!9!5E*#FZlAVIX/VNF?HA!R&4a4uiN^AlanSW$HmXd%X\=pw=kt##yLHZ9ikXQwSuY>&PpG:Ked^GBk
<PWB#1 %*1=c+!u*Wp/p4FRCnNW!bdZ1NuLjWuuSw:^6q@HhV4jk:$@q4KDa^=b5R94VkRM>L=5cI%pth999h+J
@**5=$ +DHVdC<amIS4JBe%/?p>*cD!wEGATBEG8/=/tCp@DLS9kAp/>8qkKw%DP6<D@n5lGaDDy/&HVj9Sj*ZG
JR\^4e W$Z8AichGqJ5AXB&pJn\ICF%VW8uXk\Y%:laF8lPcyeF:RPV\=QwX6BLTZ+hSq#kMYR\S>8G?S#QiXtm
<t?wQc BYu<4\\Euc\Tupa>5wH&LWPi@+u@%k4%D:TDGlPyHP4kF8<+<#&$1Cb>Wj5SQBuF%YB!bK<>y**L6NhJ
q*+@j$ ?#y?+F\\j:5SbWP>J:+G^/MWlFMV9RG*^Tl%TtHKl&bWYlDblYM\<Ridn?YY>Vb9a>JSuW9#e#:QY^=I
aN?nm5 ?@y*LMSEY/b#!c9FaW&Y1FIdQ>9IPaDl&8C8^+D&@nuZLZFdIn\YT*wuh:u:<8WZ?+Z?@4:lc9Li5M@+
K\E6pp &q*KF<h+9*u>D@Ta+%*e>j:q+\NI:><8FPj8e:C415tV^K@#\t/i#&:Q:Le/&#N#XSA=tR<leNMN^ln#
@XBFb= 5u+Vhhql@bAiLB>uB#41!Q5LJLTtne8=@qBZuQ#DDea&=wykY?@96BT=&wTZ/+j14>Q/DYR^aF=B#>wB
44uiZS h6HG1H9c>>tXme>pQ#/wJp1=ilBBqS!PRJlHtuCTERFcB!4dG\Z+dy5ZRJ@*i+lY6$>:RR&HPcTht8=a
T4ZtKX :Zc\Ie%aqS$h#Dn+y?S8Gq+J6hT9bC$/eK+F@+!Rw>#PwH#8kP1bq%!@1H?&j%IMDAQy+$B85+6MBk$t
KElIWR +M#RCtcZ>S&dpup?LQ=DZW8R\l4W4tGKeFBI!X&kERPqpW9:P\am\iD!9=\bVWPD*R*DAEe5DMhhCV6Q
e9a!*M <V5W9?L%?L^Q8E6MPQpXNT#yMyM/YVeS&I+d#\u@$H=JPEX?Fi5Ab/wCG:enW<>hAFG/YW@w#%jQQ6C=
b1SBZY F=hXl*hk=QF/HI=6XSFlwECNbI4#@QN6C^Q6b*PI>qPH1&A/WR:BJn\e/lVjIZdCy+k#@JW%M5Bw=9*+
9jkdJ* &@X6kpc#4WZ>P5KDMkM#B9MwKkH@R<iqj61\*9l9DbekVCPKaY&F%@J&Eq^+#j1?Me9+/:c5tSDy@P@G
ZN?EEN *e!u>nV^cH&Vu%pSaBQPk?wiT>j9K$*#n?wuB+Qt+*#PB:=Wa4tk+%Wy4LiQeAI\Zbb+D9%eXX#:P*by
Zi*B@k +mX$aEu^M>PYYA#=!HIcj\wI&8wQlTba*H4uY^/!QJenZqBaB5yHXuMNmJqZ#:S%8il=FR@nb>!#=4WB
$iNMPI qh/8AbBtnai<S&^8+^!h9<h9Z4#5d#4$Sb!K*^V@Y>e@^&M8Z=jlilpw5\c&*P1%^uh8^>9i^?&4#^TQ
$qnGY= Te8F6Wji4A$^dn1*!!6nmi?e/c:NDcN:8Pb+#tZjp!BMY#?9%=T+y<EWn+pHkGq+$p##Rq8Y+8FwJ<TH
p!uRFM Jc=#8&@5J?8VQLkWBEtIdHSi!HBEbXn\!l6CA@N!5p@^tHVi*=Llp96hY&N%<CelCM>C*YKl?#tiE#1W
1?pjPF k9BSqXyXP4KujYni4&njI<X#Buup:Z/k!FJ+&c8>NNGmyjcF@#HHa@dE:XyRNN4PmZV5AZM8/kA:%<hA
T<A9\l =tmJ+?RT<BtG5ydAWbCHDnke=ulP?Ph>bGVB/KR4LQZDLuWWjyACjDhVAYdWy4lP$G5D?KL6H@nIRC+M
Ha<?6R KHwM+Dha5LWqnqPQ+C@GN:Lnw86eE@RHFS&VVQGeRKk^l@9lDdQYd$JQ:k41ktKd<=M\=ulM58Wc%MVF
N5MHI= d6?RXTi8wywRLAl<!Q!QeBA++CqPX6Wk6Abjt4Etbp9^uNSXV6E>m49AiG#:H@=CC5hR8^$9/<X!1q$q
t!\X/c Tp:^umZuaI+PaCX&GHmpCjhC@d!ne%1K/=RynuQj>MhKm!P<JQ^SV^Z6THy%=NFWqRb>cuhHMEE+XFBu
SelLnh :Z<$\NQ<yKY/&c:\ASR=:i&+*qBDabW>Mb@k+M?SH!Qy>G4qj*CKQG%NydN\Cl5NmjFRZw:uJL8iAw8G
C&6Am$ #t@uu=:t*:YX5<a5+T#J9p>^&Ht>$!JYjbw^RME=VmDHDKV#CG8ZM\p#&aqyH<uTTTj=AbP@:G8m5*je
S^%+^F @M*BnL8P>:5KXQCdAMLbFt@Qibdk\tY@#4P$@=n^$t9XlF<q$u<d5uQFc@@CQ#T+T!Q8bh9@t&d@yi6j
ZkMbXE #8&8^*&JD*W*<b!V9*Q:8+pR+<Lm69p=N9n1ZQB1Jm:^udNjc8bjGE\Lbw*u6Kqc&1hKeTZV:^!tcT@*
m:jn?@ dbyw^q:u#=Fnbuq?@l*FbAh!jChRMMYqWF^*H\n*!Bwa8+*u%CdNy>mQje^4phc6u5:>Wkm>TeZuNYut
uE+kV> bb*?*9#Patu?HN?=&:eXYpDlEmt?W=Wq*!Fnm89$A@B^%Mq@Jd6y1tP9u54%uM<RyATuK^G:X*I==^8Q
<LWu:a hK+B*=6?b@E1@</mVd?n!J<=9nQKpjDRy9lFRH+@N6GWR=#nPTh<hLRZPi!Rq?I*RD8t<##kupZ>MLhM
a\Vdl= +=Eq@qMQ#eBa:Y>@b:G+E%N<J=SQ9$@wme=bP8LT>u?c8bI5TZEq&D56?9*1VCL!SHEiL5N=hCIRTGl+
FY$:%4 5FPd8TTCGG4wYuV@1qeXTTRkB8Ht=t/GA?N5?p:p?ZSGSH\jNblCG1m>GXLVhRaZHMhQ>8Pt5ND/jZbZ
PcJumZ \$cAQH\Y^X<Sk/R=wip<W#?Kd6NZjTjY#i+/=/d4nCJ@>WGNKk<ZVi%Kyw/u/VpJCDQ:Sld$L$n@V?K9
*nZ:DR H6^tNdW?W$+uu$ZI$^hbXhN>B8w>S@BP%*WG9I%/pct*w8i<WM?=jh+In<SHZDLR#i5+a4u1PnGQL6iP
T=AEBt dc%=n8M*T>&QnG<?41bHjkY<yZ^WjBd$Wc^bZ/V8kV$\P$8DCkWQp*dmD%y^#AMdaW+LBk/W@:LR/mJq
Dww$65 HZa4tYX4k\n<Bip@5u/A?%>$49SDPLyY<144</Y4Qw#%b?t6+#ae@kR?\PW=%j5Xi/n%HVaM8>GtGnCC
^MMMm! \nQBJJQ/V@auAZntmk918n$ll\Z5ZWW?K5?jQ?Q6&t1CD*#k<Cie/uA<\hN/Zt6@^M6XH@JP9SSQk%Q5
-AQjk= 00021dfd31000110334 Page 241 of binaries2.zip
<I=<*G ?Lm%lL9k*INQLD/P>$IM@D5m?IQ/=@*uS:*@9Z41j^p+@Z5/?qIanL>RhV#wGwHZ9?#F*+Y<@?*+VS*D
@8uXA6 dqC8Yyj\D8@m>/8b=*\y9mu:9cpD=9Iu6jI*YBbTiJXCAbF/SA?/#cd:QQlj<PGi>^*4Hd+J9!^iK9u!
4DIHD% lK%KQ>C8!W!:ticnHJ4MH/NTc?Hn<qF$t*YFy8eM+jHy<Ajj4D5/hJ/IMK#@$hHE#4n48*PdWLE/mj@C
6ERI&j @6u^?e>&HPnDe6&HVSMCE*Yh?Gm/#cdn^N<Lu@M$>Zuyqt#@8nu>eX9di4/:kWeahu8*kap?qRJpy8S@
:w+@&q $p=1#&L=p#XXc*RDWNe=Cd\NCNHIt4E<NN*tK58MyFH%BwRhaV9aV&!nVHVG=$Qj1a^Raa=9TL?4pA=$
K1Aeyh iCjVZyXnyDn!djLimVKFHjhZ:VwN8>tq:^Ve#FbNIu:lhK1PM/&#uTpRMJPhyj//WSjwt:+#WMT+LuL?
b4l^$n SlIZIBS=aNJGjAAk1@=WN<*LBKAiW6N%k6ec<t+e%#m:=AECkDM6=$<>b%dV15Epq6u&8=&Jd>&iYV\w
ttjGN: ?p+k/E:i%<aHJYa/+tX<uD@:911@>$?yY1m?T6F%pteVV#qiRq/^Gb!\&^X%uGR!w4j5LVbSp/HpL&It
w+DLih Y>:HZt&A!#A9:LD=+@\#4m#P8=$@L!eFF9i/ic@XhSBhy!?/#>X&%DtNij$cpBM6?\^8*ZTh!<l/eL?C
lY8lbC VdG&1wDdH5iVt4+#GJPGC=qi+Z<y:DP4IML@=DmY/?lQjXQM/uEVHiiXjWA>>V*&!9\YTN%$LdNZa:>R
Y$PdSN %+ud5&15MZVWq9dKVd*Yw$E?5u9h+/AwKJ&W*Q@S55%9C8$L5:S#t^:wwi>j?u#!!VyYYW=N*!Jlm4>N
:9:%n+ >X@=8Z^Z@1XTH=Z/YT:dkjGbtiWRK&1V1M$YT41dukL^Wde</yJ*bq#$i$XQ=\@6*?wQdb@E\bd4q<LV
b@1abH \c>VP5YyiLRq@^WYiw^$RN!@N?\@G@?kjiHkj&jj\\MNnI@6!dh?tLNKJ^:d^RhN/Gq:6wdQ>/@i:<d*
P\jb9F tn@m4Ph5HcQwV>4Ry8>p=G\?l%w+<jj>?:9Qw8Ay/J=qPi!p:*S4>RF9hADh@SGHd6PZ?cT5V/$ie>j9
THDw&T bLhS#%ZGKiVRqjqd%*WQQw5$hGc@dKuyP%%*t$aEAkRV=Q?>6<Wjpb1iM?\jQZX!DLjtcmL+u:N@VRjQ
ZIL@\4 e\ndQe8++%>d:K?K&+FcP9P@Q844#V::LP\$k*hST%n$ue#%M*Akt149BF@LmPmH4qQnp?BEH+RitPen
a*mT4S yCLl4n^9/%iJ8MSXY51^uWjw$&=\dq&AbMPn#&KnDeACapVj1aZQJVAuenR&ZtQ%S#ShJ\K@W^6FRK8j
4aiX:D Q4DBRP&>TkjQ1@aCuJnBcc*Jk1RDa=Vb8y&p:<quMR^1@J4B/b4Pe@5cRbF=Ca1?e=9bk>SN#+tp+\w/
>YJ>m^ GJqVMN=l@a:H*jTetEibMBdZ<Tb+J/1?mG64=t&i@a9Qa5iQFn#WD#5quR*@t4/VYRR8yD9$uek*+nA+
iPaS1I EdN95:^*IBFbn:++ljM<@&ER8bDEj%AyaIZ15a@m5@AH*k:ZiinwD!p/WQbt6=F%*uHN@RV&Puu/I?//
>d<=D% #u:D^hj$San?$@SlAS>4?p+?CBk+Jp\E?<Z6tJ&EwK>h$4e?$tiS1<@CE/lV&LcR1k:WX@\nEdZk8*N5
Y:icIw @knBRiClu\5iAm<9+:==+l?tetk/V#\aBED6y6Fc+KLi!*:uul1e*1wSGM+SK6/Y9NyZZ$I++X@Sh#b@
WiIQ:S lH#QRuDV!REjyh^d5hCu81E9i?DYFTNqh>L$T+KXSjqZ<jaWB???4KPTX*Vp9nZKYy^4Audja64#>&9=
JnR+dl 9lHiBkQ*YPlQ95KjX%J@/>e@@**<@^n@Vd*#1a*+aN^:Qi:+c4Q@qdL4$TZ$@9S?A%@^41a&VjhCZQQ?
l\dq^= uc?#%nEq=*=yy@@w1qRea^&GByw/j/LAFS5jcp&u?t6hF6@9mcpj&+Nnmt$ulpYL&tAjk@RD^Xl:9/+Q
<ZKuMA 1n*5Fk?1>P<4j1Zya?wRV/Mbh@y@?RKZ&+SS&AaE5WATZu&>SBC1BQHep?AwwmHL4<5jN+/a%Y*P^GBe
=RMEG* uS\Q@F/n%HeDRPZQmiXJpD*QRJu#IH:$PGn1HyA<bnjS>:BbGw^^?LJM9QEV+&%SpILhkC6R5blDQ>RG
>tTe9Z n/T@jml%4bA%D:nt$R+pN95%N6$die%c@HuFq^Dm*4NSlVNaEGdZehw8=Z$jqBbt<pA=L1BC4^Hjl\uR
D\w6/J lPYwFS6?LGG6=#==6pD@HHV*%X&@kL@b*n41#DMh@DmC/w@Dmhe?LiGZlV+AtNS^l*WkDTYi<n=NF<QG
N=hl=^ ZtBnTZ^1$<eNhA*=BNIM/8TZQ#:q?yjQPH:kKF$:j\V+qM$*Wh1:mieFMm9?^FwuJSR5luWR1iNmC5*#
NWyBeR LLna#+4!t&&#%yiG?V^SZW>h!pJ8TG4KA>LFy%$@5<b$!tFy==?&Y^<+pbFFMh@bh6^Q4PDWVKaTMA6a
W=^:F^ /\+8bh=k/p\IIK\t+CKDL@jTD@X&KZ4aabj=RNGwuW84/WG*!BTAmp#CSYdibGLG<=CBu+1?XL=Il?XN
@Di1d* Q>%pQ68?\#LP5&h=H<>/HkCnK?H\W9#5*aY/F+P<k:w5d!+h?CMil&6=pe8#9@q^@tNi!@^pQ6PLZniY
<%Gmy8 ?XJ6b=:hV?+tTSu+jmK^%HWqAPlm@^I=ih%i/5F9BRbNtjL$@MeK8Ee<<?8D:PYRlda\iPmX%98!Q^W+
u#S+km j%VwnD>1qD*4Ld@*9yWau+^#Q*p@!/<&K9@4<Z>cTZ$i>#5K#u<G</@j49/NdkwBXC%HQK9=#NPcS#@9
:6hC69 4h!y!LYi?/H454:P%4N%H<MT&Iw8uM$C#u9BkWeDjm$$%jLY/@lycnla/^AFH<NnFRdn?M@4ceja*<cA
P=5nFE HM*q>nXICZ9w1IP^Z/KLP&$wRBkVViu4YdRpV^y\:naIDyd4&iJ!Q8yC##i\=B%yMTA1>M8Qt&X@C!m=
k\BE:t yu+JmJWZp<>/65I\Y1GyVw?Gb::hkL8@Sa/4!bJP%$Yy+n$6yaL>5:9iNuLAwcMi%W\dP%\kZn8F6+j6
yl&D#K >ck#c6FZJGehh%V+YD#4qXymX/JGW9N/8kBNJ=GYYY@+AeRqPE6u<@TNipL!nauEQy9S$TH6qa+9+>Mu
tjRq*4 5LE>B===@j41lunZS%+Pj$5</X*9?6e$VZJj4mDpCMdtNq=+9y6SqyZ4/hPw98tSKDPbJE*\\k:L>bj/
!<6a/: 88*?@KRPTQKb?\t&@PN$*?wL?a=1Tl*@b9w45pqubkPPtJaSmhtT=^q5QW8cMQa&*8jXt6pm=a9<DPi=
4/\XNV B*9eq%Zc$MMyB@bQ@1baC<Pu<W%J/&bql!CJ\WBnZk4>Vp!aQu6SN%ERE<XWNjM8MF>lY#bJ%=j9k%uF
#M$$BG X9i1X*>=Y=lekFe@NQW>ZNBPK&:p6c5\G9&D*?j\w:tFKLlWjX%M9$aAcQFR/XYu+R>*^ENkQ\Y>q@*H
+jh<^+ *\u@d=YMQ&JL9#HA#?1VQ9\NWE5DBBRAAkAIAB^YdTZl?umTNEkAADd8AAAuAAAAa&^ybY=$e!>\b*A9
=VRFm4 h&q8M#I9WEhRe&M9etX#L&%pMVN+MnR8at%\*F5>4P!&e6aDDMnAjiiiZj&+eyG+m85FH8DY1k&<^4Y:
+%h#Tw :XT:TiHKhcAAB4b:SSIkSS4ZKq!qmLhIbVh^=iIBEmZ?mIRYTMF<M>S1yV&:%*89Z\y::#%u>YpwepkP
IG%j=1 l<NQe#:>:E>>^J<@9ShF@+D9@<dQ*@$lm9+R9S<EVZVu<^Z@n::/Ku#SQ%^<>>%*$Zj@<%&p@89jw9ji
qib^BN i!>/@@**w#@?<a@Sh48NQ9nkk?nDD#?MQ94ww?nnn#?PQ9@<<?m###/LQ9*$$?mVV#/J99yHH@*=##:/
H=@E\h =?mH!I6n>J<@!PmH9@+%?1h@@\?$5MQQHn<H@B\D*PHZD9h&8Lini#+W&iQ?Hlh:*N@n@6/H^\/+j<D>
nA1#*? A<AB>\?i1+1P8H@E@TQ8H*HnmQ5i&AQ:a&mK@?*^e<AQ*jPlij#cRaehhNlBl^%$aJYk\\+/:KDDDn45
4ka4ma wAP4CS%&$GEHHZdRaRehYHZw5IMPP?m\k\+:/LD#8Ae>h6BnS*y+H:4Ht6C@A*/P?QGl!>Bqn<d*cGmQ
F>dea^ T9jRlaeB\n$8>6BqD%%+YKDHHu45wej?RQh<GC4w5aePi?m\l\+$hH9w5aePi?l\SF5i9*pI$W:+h=!G
>VPFeL h<ecHZcEjSl16H&AVke$ipADB?l$RN5HCA?w=HCk8u!aDt+d>>H?Ai$j$D=N$RH6H?k?hDlAl+Q*QG%l
1PuNy9 J9dePtqG$*8EDpi$h+S8S?l^SH5<6cRH^8AIQa/pB#4G$+&Hn6DqCF&PWPKIB6pEwM5SD^=S/IkdS?lC
#S:$!# buEpZVAuS?l!yQFkZekccBaPdEwiPunw+KGDl\+iP4A=RaenhQDR\WPHI*SkE+MPHny+/PClk+eP1Bw@
aq*ImV 8A<hQHV\$MFDAa@&n/nM+$GQR95>#SHt$XMdXDiX&Wh@H@%4>MWZZ$Sjj9qq>QZZZ$jjjQNN>Q***$jj
1Hu@bM j966>PPQQ$a@@jSV>QQQQ$hN$$Sc/?l$PpZ1j**$L*@=C>a^4YnQ@!P1q^HXT>BH5dQc&PE*<LH<YaC%
l!/ue& bL4Y9+t?+GM$j$#RiuG>q9^Y8nNaV^<Z>HYL/%uCHVIDV>W$Z*aCAT+qwie4MF\t@!K^T*Cq$e9c:A15
h:Y1t# LGl6cJmTQ8::8A:&yHAb%!cWYput/b1u$bn#:C$pF&BjVQH>anj5bX%515I5\XK!KCcda456T1^*a/#I
??wQ$^ N>8mpV\hc\uhwiuChblGb!%@DT9JP+G4%i!YEmytLiHyGbK#!h\B1ycu6I\6*?:d6I$N*WaQXlJn*SB*
ZPS!1R Za<9k&tMi/X%HiMLJb$NEty#B5NhEIwNM=lGjq4Bjc$kmWP^\iqSTD9W9db4aP>JB8?HV6VipV8&I%*F
bW5!6V <eD6VBJ&%M=$YbGtSVycb$V&6Gu48H#>P1*MT9KYIJEAadTtXc6Et1hyZmSW#L1+*G/!JtW4iRGiZ$mc
wm5BZW &GqqdbYYyQbkXhi&dj1<dZ65N!5J46LKcyEq$nuXyjm!?D%1c<iFbFW5TM^Tek9AYy!ya<&4%wpwEt+R
XnnlL? PWt<Ep&qbjcW\EwiBFy:X^Yb=At!a:a6bT!c$CH9b$ueCp%&ZdiaMc?/Vuujm&4\C<ty>k#eXG#%#H%k
:KNc=p qHW!!!T%cJZIe=LFLX5Kq=N6b#\t+jRIMDD4Nt$1liwG%?WqNhS#P&eJPn%WLR!kX5=WLY\pd65aFbRu
EwTeMD hH8YhJC<C<AK6H*HClka8B\VnKEXpQlauGJH/1IhH=@iCH\AtK&&4Ea^Yt?$/e4SYtXb/%p!?EF*yAE/
KTi@N! HC/t@4SCia5dYF&Db<pE*E%k4+AJIDk$<yW\QXHGZtcJ>tQJ:YDPMY:W#1QAntWHm&<=R5QA\XM:#RP+
d>t@iG qHSNSTQ1nYlGnI9Aw$:TLN1LyB#hFin8kpW^QbbNmW@VT8P1SHk9mqbYbeYG%E?&>!nAat1q^*BW^k<$
?=/\y= @&=R/AT$umW\!!F8tynGWKaJ9uYdnG!XGJBbp5B%ZIQ?48RChNWp@CqH+?KG/8@LIlPKNBCE^KVwI\Bn
CYm&@a ZYHJ%P!#ZXhRhZ/ph6aTtibCKdF=jS1<dDc9$qG&:FSbw85Y#lK%eVGAJIBCcDYD1&J/Kkd*=ul4JyjN
HmLXST E1PT/GtEAcVd%9k?&ddcD\T$4=PCRdI6Cc\pDMb<W>c\wPS%mwW8<%hJ4L5M:dk^j?bi5aS>jJHpV#uM
Ih15@% 4W9KT1SQSYeeAt?W&BbFZyJLSL?dQC?&1NKTyNpm^Gn4IEp&RPhmiGaC=K>=K?RklJ@Jp1ahNhyy!Ct$
-A1Y/d 00093d9818200110334 Page 242 of binaries2.zip
%b1@ck JY%VFRA6pwaATXBJYe1BJSnaTXIqCX6Nt$CGhaQ>b=PjTAPaAVpM?LlTamEdPec+F5adZ5GKNDBl4/<l
Ke^8SJ G$k%>MHITm4YLWlm^jGB66+BGMjB\wBNVEwh\MXjG>4+dV>K:QN\*4VL&lAKW$?hWe1GeJpqLp\y#/<n
!5wnE* uTkI\Qik%MC*iQ*aiw^bA^V#<%QpA<bayCi5JR%h+pFXw8dRn9ayNYI6w*Mc9/5V^yG$\bL9Sq%Zqea$
AE?CN1 wnQaA5I#cNZE5XI^hh#A#/Ek?Y8K&XAll+WWLFMpa/Wa!R^wRLC5K+9&B@K>CIwpLRlABE?nnGq<EDlb
y+58:t <qphFaMC51$eu^EwC5He!FAMGBZu$dQAQJHZFttYbDpdE4yk8/\JB%m1V8bQ5HwWk^ynFpWIcmB!R=jq
%L#QRS TS4MEwQT=ptbJ^^<VQHPPVSFaMLlP%%li$9CE%c4\ejbe/kcqe9p/TqW4iGj54LMp6=VXEQFNmh5Buyw
^dAt!n C!\Xtm/8q+8%6JdRcN&q4=+FdXI$P8RAB$\K#A5tym8B#a*HAI4V4p+hSa#yaP>6mA*ub&LiiRbaJj:4
X5A6nH PTC>SN4lbGT=t@=TNa$ydSG<<S5Dd*G8tmd^ZB6Hy>NPap!bWHE#uWyY^Z4SC5H&\Y&!KW/uKVJN59Dy
jTiE&^ !GI8!NDSan/cBjP%=$hk<uciFHQu>E^Xt@6Xu$YYc=:H=q!M%>?/54pGcKN1de@HXR4^X\&9u4P#Btai
GF>&@Z ?c6u!JW<\t=e>?>Y%cF!5>VG*ul/4T4FYjb!nKR#*pY$jtJb>iJ!?e^cuVj\G+>XjXZdBGa8=Nd\tqZh
@aBJV! >5Yb@@ck4p::D<@D&%b>=!H:lmK@6@/<Wb&@AY6tl6@Sb:u@ZE*J@!9#6&T@b94WZuGyhMi8H=1LDW58
:@#I%X >9LLKN4Y#Qu?^a*b+SFk:aLqZX:jqNmbCtQP#X\DjXh!6>k5kAPuHXpttiCwJyR#M\G*AQa8tPk*he*F
8hkma? 9RGE5AwlDG>md\Q5LRt8uSptAk<Smt1&mD$R>E$N?Vtae$6\S<IS*=ub6ijV:lt+M<8:BBR*C+R*K1c\
&!E6&< ?kLMa&D=VA%XXNZ%*mGR:nXFcV=P<5+F$6C=Zy^\YGBXH\JYE/6d^+HLjR^a&Y!j<%cpt\c^&c<FejP<
dTuVX< Ld6VptXJB&94&/LAbWZ6MEnV4JR$BuYdF&p&kb=APwNmq1D1db+HL9hBEDhyyYV&cm91\j^1WEL*c99e
4wL&kl >nEPHnl>y$JyYccI%&ttV4YY:StIJdk6\YE\FpuV^d$c:C%RAhk%RG^MQFbJ=*:>1$EyuFi6aIP&1p$p
861eGn GdcLbR%R^5H?+S\iAZR8Gcl?HHp<uecY+K=ppA&hhn*PS#m^ZRBPWLIyb&A8aFZMZEucXPI\Wpwa5:LE
9H/K^j N4qBch/DeLkic#y&%SnhB+Elp&6Q5cY##IQAntqSm1akGqd@cmCd6E!iZlZbN8>MjMJ^!XGemDXdq=6N
il>MX% utZ=Jle+$n+G!PHH#DYFE/WL#NXL+M:F?IA4pmThhQ9XwBhJpSP#uLR1L69i+Xmy/TVea?DnebRR%Q+?
dAWkbW mJhkWuTl>YuhlX5k5Jm!JS:%C9m:aFq5YAC/NmjB9@RkWkHVhq%Yct</Np5mP<%heFYMCR\^c*$Q4Iw=
t^Iu<P LIdanAu=Pp%AckaPIGupRMAHTV#MElR#6$A>TqXqYViYyTVQpLi%Fl8mHd\1N$ue+%hQSGG=TYXhdluw
W^&q$% <ntNaYlJQWpaRGKXdLP<=aM+k:^wXcBN+DZ#@KVeBFwGZC^85&K:+Se&>Lal#a4udD!Da9PeumWb\C#J
TF1JAL <8$CAQH4H%PL+uWtKmk1LhHLZddJ!:d6$LDVAq6ESm<+tP%Pm&*Bd#9+FSSYVbDAW&Z$>yApXqhJXnI9
\TM8Rl MSCb$TR6EX+WEim^!amn+%CQm$pV+k94lq=K<8tGkla61=m9?eXd#SEAAdnhZ6alYwd^&Sw?tAH^d:I<
>u4$dD lWX4hT^:S^VY^Fe^GaikqEIl8I8J#TP/CnHE^PcSlBk8F+AjAH^kaamcMJyXMN!eQhMMdQLu$N$GFyaD
STC=ju IY$tqw&w5MEQ+\tYRy+QP*<Zc@#Ank^WXDD8\M#SjldH&FWGQtcnaNuKaa/+8QQe4PGwLqB8FQ&Eh5\R
Y9pCQh *the&D^SKYd#iLLRG!L\TH9w+&ccdmD?:S=NJ&icVlPBS6##=AcJbS5Ci%Y*#>FGEGp+$L6Ia6uc\LKS
niIduK :Y#VmmJNcIS+Jb9wylAML%=nK+1*cS1N9<9tYbti&d^A+DX=R/8dhR59Emjh58eV/\a+y1?itnk<w>8<
/L+N5+ KhPGcdwL!&aDFVc#dG9i<5LMDVRkXhiNQS5X5YhqiC6#PTK>TCX+I=6HFjSM8T$JQNb6ZNB$j5WA^8hu
jGpHE! l8tbpTj+VT!dQS9PNVM*We6VKb#c\9y:<>H:F>k<a=betu&Iyl9Y#=^XjTQLN6^l&Scp$qLSZ?nVA=Vd
e/Et<4 Fbu%$DM4t8+FFZbd/!6tdmZTD@ZtHTm*?:yhZ><q@S=pyi#de^8QWXS&XjChcK*jhZ>?j^>:l#G:P!X4
:pekA& mZ&I8Z^Ddd?G:Z^BbC%<C1@@tjBckPFBeKZauYIQX*$@+ZKt@!cCc=F/N45?w5KIT^9PJe*bn/$p><FL
yLij/B /6e5E8nM^T9ic8hqMZQN8F%i@M$p*VDqeE\9Iu$k#y\:^+d#P<y*AVj!*>\!Vi=l5M!4QL<e9kl+y#@9
5EjAL4 !ImkKh%6+KBC%V$P@5/MRuJC!!DdN4^Djli\?1li/S9F#MQA&p6iyVEKmlLl^@NY><wRMWkl4Mk*SbaZ
HHP^Jp 1cA*nkCddHS%S1Em=SL\m>=+Tm^+Y#AE/5AEW4lKmnVJ*4&&RLNNibYKNCXin<Jlhe1#M6q5\q95Lpp1
PyR?ep Jb8C\qlPa/VnWhw^6=qX*w8eJP<CR4^G4:lyyMZ4#inhXK\8$\wkQip%GP+CGyicYDbiJ\lM/a*\qKbR
PN%+Ld 6%p!^mI4?ik4KPZNmpV\aaQV^b1&WqaJy5Ie=@tekT!:\T<p\&$JA>l!VihpPlMP8mZGbKy6wDR9H::e
>CWu%X k!C\BKmYRtww&VTmLaqZw#jmy^GNWk/Wb?cKEmCJ!PN$JT*KXuR%Y5dSS&qZ6/X<J?BqRm^At*dYG!uR
Rm!bBM QC=/6MQyeb4P!b!5FwBmaJbkLYGYVjTW6Ii8h9p&KXQPqIDc^BG1/wS8V*&&mnLplw/!%M1V:DBQZXul
1=K+&w NE>uN$niBVC#I\Y^P+MYy^l/^b^JStq+I+:FyC>q=6\E+:WpHHuC+e=VIy?uuDdMNkGMqD=S/5?aFHuT
mb\A>N TpyHqHAIda\=p4W+>S+*HFFGuML+IPkt\ItKhGbLN5Tc+ESIQJS1!yDQS:MAn<4#+=jA*RW$TqaWGdF<
yE?W#P b9Cl1=T9X%N&L=FeGD!FlyN6pbcWBI6&NPaF$/M^kdZ98Bawip+<JGD8k8EFwH/XWR/VW<bYJW\e:S4b
eiIW\5 XybYBC$EZl<$%EH4MD?*Jb=>h%pK>6+$iyWP=%W8LWVC6th<j!KtqFd@/FRu8lM/X:jwV!C8B$jbj$/&
>PucVc <Hl/B6WThGa8NqI^uMAbeH=8ptYCn9!!bdc\Qb&wy?k8pV<$lqkq=TMA94PlZG4+S<4aaV4FqBq^@:w/
VmY!ah mdJIa*IXuqqt<liWWVlm%cJ:Nj$mTynYNuiakX+C>a9A\/eJF&?j+ZN%wGynRYtB:nL\b/9!b:CTXJTy
K%jV*C PRE5qqVA8#C9VIuSYZ9Ku+p*CjctV5#X?JyTS6H*bHTWE>hR9&9Spe$p%Hq%w1R/A9Sc+pSbyk5JkadH
>p?Xub KBRV!SuAN>ehbcPPy^G&R5Y\hPP5kN%banqk>%Jk8XqKkei>M!DJDWDPAH5Bn\91qpqcqp*H@n1R^BY=
1p^#@& ICPVVXGKEl5T9j6Iw&il#al:$IVwYqW*PjRa4pBb6Ky9C4KpAPKEABY:TKdDe\l<WT\ue&H@MGc95$wS
\+9N=u tbyI8\dyW>+BdAN+9RD=K$wN4IyZTa\FtG%T$jMjMGA/^/b#$<^XVXKYThJ^%l*ACXawt#RSNbP!&:\l
HE94DF Pw<w#C:Jm/RKiZLw<ua:<c$aut!dqcQtMADFC94LD*h>cpBVKac81<dcXTW%kP$?^RbDwNL>Kb%AW>W^
Hni&e9 %l%eB$9Ru\RPtAB&41FmwK1T9/$?9!JJ5=TbRmci*MSLYj/Ln%w^NWYl5tFdtNlJdC/Y*:EM%9RTu=w=
*w*1Wd WZKp^KKGN&4P%tQIVk\5lb%PH=!5KLEeYAZKp>X^dCtaS%R@!JFmFKK<8Zqd%&ky@QEDVZDI1IW^ua8F
=Xu^/L 9M^y<wp=qFk9QNR&uIXC$Pnl+C1SbbW>5:IX?pM>\&=ty=eRqMJZm%IIi4<BX/PEpGPVh5#p<q+>68&W
k\ltwL u:k<dkd!N#BPGqYRI?WwG96IqTj^qB$Iu%mYHC+S?>^SP+Ee=&L5^EL&^8XEb@n<EBJS=pNT!PiR&dc5
/4RV\L BLHSGEc5c$1V=Y\IR8Yt+bhk=K4dy+$\QCDE\ndhmZeQFBbJ&Tc4@5!jePcmKaY:l?e\VtNuMk1P9N$&
46yabt 6VPKPDHXQt<FSe:pqpZTw5IiPwSmBSZVp>y4889<l$ZLW!!>WeA&ybu=S/SW$>>$tbpG4eQdBw1bVV?>
FIZaqj Z!Cit==lmyVPy+4Qm4hQ*JjV51uDu+9beFnYIc?bW\?ZXZQKKS>YR:F?K4bP\\tuYu8L9*Vl9ehk44Nb
G!tdKw R?Rj%kWV/nSt=&je@M^/jP=th6&5inyX$/w/n@&1N4N?/wEp5h>dj+d\1tP&VLQKZq9^%\9#=YjthEi>
*9$/ui wt9%9RT+^/1t89SdE<99Rui>cR:5<1>G*X8u^@=!j8I9J:=Nj#i/AMMNmdYZJP4:#%^aQG^W5bw5$T/b
#E1!tH 9mY\>*QbjnH@:RYHPQt><QY*Aj!Tn1!YZ\l9PS*J#Dq1Ym<T%1/AYW9C/:$L=@aT1BiTcTQm6/5L+P\>
^SkV&* !Z$Ru9Fuww&ZqBI=anqE=8j5Nba5\DDeqbkHW>+Y^R#qJlGNyTl:#N\Fn^bVNh*Cha!NpwPp>tp:pm9W
\KFFRD NbFuebDeBeNK<wa56:8T=QWGWa#?Q?/8LXqTZEuYu#/PucyMHm6mQY!G>dAmEEkIajCZE^+lpal<uFNh
ASR?ZM *hb*8t#th1qIHkK>\8Z8Ah=A+:+1YF%>Hk5QQ>QZn&^h8?5FMBp&yM8!!!wYIHYZc%pYSZYqI%Iw1hC>
Ak!E?1 K@\X@y8tXT8tiA*CYTnaa+GP%FL\y=@hn?\ZWQqX&!dVypeANQXqDT%hYR!$a1^#dbScc+1Vb9Y!RD@d
4HSuhu >pLKeqNQ?Y?u\4Rcdw94B9:cu^b8VYeY6a$W1NKcq5M?/qNV5$JG15%P>FuPliXbITG&9iT@JVT=iX/#
6WaTPE w6N>\W1!y+W1F8ynIjqbHR5L9h+<:%c4GpYjdKMGaC$nyID%tkt1e1M<C88^<PVIPnKjnaq6M:Qe=mQq
MqPnyS DaZ?YAlHdtN*Lj48YkL$P^Z1i&E=F6/e++j1w>yYBG%i!ALw%nV&W4MDN\\9u>dN*!5\=HbklV$W:GMB
y@Ljp< tA9FFBCnL6PjF@^c/:Y@XlR4?9*8tFtyyquY=S\VP<Bp*!m<aduhK#iuS?kJit4!ha@1WT>+WXn<1$J!
*YNNRt Ad?$nhdhqeGE@S/a8Y>AbLIma>LPN\899<L4ApVT&k\hk&TlWH>h/M>H=ALkJtY=ZuW>YIdE$h/5YX5G
1h/4^$ tbYuu&KY+ALi/X:\#\1SXdqI@^H><?LjF8kyKD#iAD5!np1F@ueL#Z/BmbuXhS8BjWPh^/5ct\+55d\=
!%p!c> X5B>5*CkYM:j=X8!DQLK%D!YV4yNCm\5uZYXFQL>b@GIFLd>A6SKl&68id!?TWX8R>=Q6#kR6+\+a+jD
p>P*VS B=dp?RkZ?Il#@BeuR:SnZHCYIb1QAI8j=An9K1A\1/G?@KmEL+dC>Whq>5LqZ6B$=C1iCcenweD$KJwR
-AXPQ8 000cad5d4b400110334 Page 243 of binaries2.zip
%1%5SD m^<jZX*t%KPZ6TkHP@#//B$>TuZN/:+8!5$?FC:F8RD?JPDWP5h&\VBTF?SCqhYHRq+Q:WPlB@DqlMcw
*WC&>h ?1!Laph1:F*Z4:QRkBZAM5XaD@<M/Ji\HXHRkRe=:+Ciduq@kba9Sh=^b/J^1/8B1<q6c9w:BM15aK/y
Eh8heB *FFlCWeajtMJe:na\9jyiy4i6D^%^:@VZDp?TZ+&M?TtFAMhcD9GVMF#bHE6@dXXp&^&R\y6^aDEM*NM
Ha4hju ApjM#8$\6HFQP\B/DI#BHeY$5+mAeJ>^>L\@9el>5ChJW?Dea8?6>a8E+j^H>1:=&iTe?G^lj>9h#\tQ
tGR8m# I\ERBmm:5VDeejMQGBhXCL6T\InBI5VY\/1y?RD+^LVJ8BmVCLGVhLu8Ky>n\Me\R&DNPZE\YLmdybAd
Ce1GZ/ nS=>DX<Dh+LetN^hl*Pt$#t\Xtk\1MdH+SF:\8bGNwk?tIG^911bFE!u6j&9/!AI:&KKC!N#nLI^L6a^
GbR%NM !pcu6VZXb\4%eTJHeki1R=A+B<kN>:HRKAN!\*$td@8jF+*^PWB8QTC*?G#^HH+&Pth@NntHt5:^uIm!
jR^#Gp *YtI4qZTkWC%HX6yaSGbC!md=?DR<6VQc8Z6#4e<SeISD4lDd5KkmtkiYMX$#>djI8T&G!!=+#u#+S!l
qQXXyR AV<>=\\h#W?kI@?AbEWeKWKT!#hkqL5Z#\u>P6*uiPuDn%:AY9+856:=u@?6?y#X\\u<>R=q8@89#Yi$
mNK$Sm /dt?&64nne:*<jQnyRYtP!CK9D<TmFjV=P+Dn$$9@yJ+?A$X5Qhu!8qVAZhk<d=C#h:!Vuh/1A@EXTi%
Cq9KPH DNCq\DHQeD:9H=D8d$mA=/@Qe5\WWbQ*9/$Zj4m\e:M@!8^bb/D5<qknpa?/!Z*@yk95bLDyEaA^GIE5
YVhj!Y n#A#*XQXXauJ@j5K/MBuk6%B4EG\hPND+RmYw>*%W9V1L:!5l#?$>N\t>uIV>\=ED!6Hy1i*QLYtn*!I
A*q4^K >=#t?Dbl5+KK1K%94BpMVS4Y>F$N6eN1$TL+!MKTHXZD/ib$$?nRhQ6?m\NH\\D:\6VAJnhFZbek:y!A
bSeB9X jy1!?%KmyHh/d/bq!SBDK&/R@h9?<$jY4l&<u>1?8qdb&54ELpjwH/Hu5>mwV&?cPDS>>@8$>bZYuPWF
FwXq$V yn5IShyBc?EDy8@hL<Ge/^&wDq1iXT&998dF%N4j%1!/ZP1S\tBcET%nw^5XnM!MHAGq\*4dQ8=p$PI+
kZCEQV ^$wX/>=qjt9TiKlQ>18i&8\nS#BK>SqDjX:5?dnulNbIb^*/XjE!D\6DpIQwHXQ<MGAlBQ:WRl>69HGR
C&PqMX Q=t6=!P$@qReI@u#CIJhK1^uq:6W@dAZbKeZ@RiEnI%N&1AQ$h9Gty$+tV^q?D<TYwZP8nRWmVAbD*n?
eiK!&@ &QjK1pdDhNCdDw>N%>hYGDXVP&!RYwNe$RApQ!5BJHLhImwn1QeZY#uwQ?A55EtdE$Sp&:?QQ^t^*D>X
\*V$5d ^N#VA4YwIh5M:$N#*EqNqNcpGL4a&K:%HN5mMKX1VSy!NN/i45LKP^FABGZ1GBaTD8n+6A@^>/&e6D=>
@GZ\5V Q$cVNkRCyweBDq!X/CRcw1aud+HG>*EW5JaLDMCnaP%6wXFD>cB6&6bcduFXcY:6cEhh><M/>NT:^>ay
IFVk+J ckTtyCMacn\V:6\WZ$><W#ET=%h4N?4quWBljq:##$I+C/j/AKT+mhMQjb*/b/WyXywZ&iL@<dQl9uA/
RZ?QbZ !i4mewHyJG=9he+Ch4^GiKBSk\QpMK9<M^?cbqS%96:Ai6twb$K=T$*9p6QjXR9ebX<6eNPqG/<h^*MV
KIqc6G dL914C!!G8MdHK5w1N$\XE&<w$=F:1nJ1ml%dAPM8k$!91E?*a?QaXuP8=:$i8!R\ZTT+YiaK^aDF^Ap
Jk=+cA >i5t@ejTq@L#wBX%ZhjYNNnd9nakA+#KdHXQI^%CIVbXXa&E@Hk:SXp!9YPcBw4y1#JuB#4YlGtl=TCe
allipi A1pMnBe*Jh8=mZ&dy^h4DIYKDC:AQ@Fk@ZSelm#wGZNR>Hy/#ZZDRhjWb+Qy5!AXbNTiY#J$4mkM&LeI
1JwHNM &D#N&=4yItCdqD<8T64:pP9F%VpDNMAC&FNTJH^k%ApDCe>t5nK!SR/KLNm*\e/KQ#H+atdhil*u4!SG
EtJMKk PNVHR^Myjq!C*C4l!Fn1d>aIk*!ttHyk^TXi18WCG$E8Dq5/FEYQGn\1XM?KAljWXeDQ6%Y$!&=B\:Fl
Y9Ku:& yJlAw8Q#GZy6/%!Cd<i<ndnN!/Tl<N!iBl!nBk$jYQek+$1@#/=Ryye^wEPQDBk9dAnH@B8cbFa\@WCK
JTc\Yw YpJBMXBPQ&eQM>CLFkqpPV!N=DGHGau^VZq9GN<<BLTV/LLBGkaiAac#a&bQ5GJL9blut8*!5mm9%:=h
PXcPKN @N9FNnW^HSVKS*dV:A=BF8aa#:6w6B!$#C4Cul$6F+Gu$GQjiEWW^6@+ipEi!#PRRKj>?@B>$LP8idk4
qRM>De LYP/QBhbJwQY^YZn98Tm4+9Ml:Py5/+D@Qc8Q6/9=e?iK?Dbh1+1t5il5!twF*kLK<nB/m1H$^@MPjYp
#F$5FJ cETE45GD+J5\LX\e*!J<FtAP&Y/u\aadPT@*?$^Q<pcDa^6LRbNRlCQmCL?>Y$VD66lM?*^K+a6:HDd5
ytq<Yj &w^5tiiWcYu^^+n:dX1HEh&HFh=?NPM=TlL!&LNXGm6Su9:K9hJwPnh@K!L$8*w$\HSQ?GWSLiB*6t8w
MM$&w+ tYpXH?!bhM1h^J986V4!mSZd5*n%G/bXD@Rh>?#BZEII8\MCd9b9>Jt9D:pW\HA9:@aR59<>6KFEl81P
q8G@c< CMZ$#kD\yVVQ9^d6@a6!Tj<XkQJj1<>LnjWj*@p9NL&@?+@:<#we84u>h@*5WqF@P5K>jNZ*ERDLQC#B
Ajejh9 w99uQe@D*@:q9uMB^y5ce+@A$uh>D+9>5WMq8qC5LtPA/$B<ilaDm59du%kS?nk69K&TcIb1Yi>\n><*
W^M<Sd IeR!IW!yahIMw?lBF=y5NhN/1d^Y8Vm=Qm!\PeJ?Z1NZmQG*L*Cj5&=aIa9HDhwPLa>a5MaPKLRYB=QA
aLAJpt 8@*6CIGcwtZ/DlD>#ettPw6YqGaS!HTG5pH?j+dRa9Y@5KV*ZWht:^tE<8@J1YJcEn^:<AyweV1^9AwP
>BW8<G KMAJac!#<A/J\K=5u494R1j$?%B+R59^5L=N\8%FhYXSFE>w>P#Ywmbc$E%9EEDe6K11+Nu#94&Xwd$l
=APMmc qnj5e<R!m#Y45pcbqScPqpLk1dYV$hn#lNhKZNAtDAk@1bam^b@bR*%wBb#y6aE%6$>^9wpyRIPC>tN=
D6%&cP Th/hpRmmGhXYAKh/%>+RDt$lZ9B6j@*<XZW4CI+W>\H&aK@?ie%ANT^LGIh:8&+WTZT!bZ<E9JkB$bjX
#+bnEu a@BAT*:X=J$c5hpd<VjbVd:bQt5w=pC+jB^aZaLtRVZV6BREkdu$4yehlmh1@qXBkSbDhpBp/tcm4\KK
BJ:q@# DP#w#R15/DdBQTw9!&#d/:Pdb6HLKjN^GVJ1h5q>hEQh1l/Mp9DqkL?lPtA*tq9E8iMMpF=kZd8!Z+jG
m\1Jy$ DHy<Y^>8L1KK$bqYK^!IEBA^&?4GRBbpNR!=>a\*VjMEj!VuDl4@wK^a<&!/1c\:k@Qc$Lq\ht<=n+J4
uy1uMd qVKmLq>$wei?$uS\CmN5iMXJ!AK\h%k%=JL%?6ZAHqbtE\Y+m9ZL#GAa6&+aii6:D99bBpAmS:FXYXHu
uhiduR mlB?HGy9C9cD\#XZ=@=D4%i9qupMpQySlF#pHd?eY%5D+MFhJ:Fd5mAjk5#DHJX8+AEYDLZ5X:E!BQB&
dWkCcW #=ccn@ki#R:%wW:nPC&N/n+@!@JcANiT6BQkmYGDatyNjdq8CkkJW:hm\I/h44W9KK\?D\e$Ft\M$\B?
Z5J/dP q*RBihMKSYDc1MHyn96=aFpLPWtwPb1h9tkekXLJiNA#*+<H?5iQul%RMdny^yk6c!Ak$hV:S>cawj?W
kJ#9KC 6VJIS*KD<=LZ%*LqCDMbD@#Thy?X+GZu>4bt@ZJd?+aBGp56J?Q9P#FBm>1=#pGqSTam%daNtB8BTmMZ
S:iqPH 1qh4ILQVBtLQq#EZHte64\PDyV!^XFptGY/<hB?PkL*JD8#uBa/RNGK*At5h^t61QJ$C/<a6KW=P#>Fp
B@iK:l bhH%G6b\<KLZZTEi>8IYbuu?+RiIbw4JiL*lAyi1^$/kVR$*Hub6wRH#M4Qb@qJylVE6KMVyNm*k&h:R
YGej*i w5B!Il8<V@w+twiphD:FZ>t@5:*=P$uAAXP6^*cny<tw9p^G!$4&>*NljiDFNME1\*<E1#?Id/l6>PBA
^AJJ+T G4=A*Fb<6ql\B#IS+%6VIACNNZap?k\I*N$q^NG\phi5<e!cE#YXW^uphXcCYu4IyiCSTpT!I*XM!J#H
6d&#V& ISM@Tbj8?Q9#>th<Nlw=C<tdlBam?^Nll?IJuPGT#TBld&KBWNRh5^KbK^dZd:4/KPA$WH&W#Z!&t4SD
A6TWDR q&jC449NTJKR5:EdLP!K15wb@=Khd?+?#:ddu!:EiW?CLnDkA4#8Lin@t1idyL5Kpy+HYqK^GPVqeqc9
X4CSZV 4bYZ6/?9Y\lSQV\LcRcSCXtYbWKAm:=1$hl66bK1kkcBFc/Cp?\PIGHI</Yqj+an+RL$dBNjIKllbc#/
@^uaqY u6wy4ItZAH5hp?IFd&n=n<S#l&\Te!IT*Yq/NHJkdk^VeLCj@1*\B%5M+RLP9?p@d^E#Q#@bR#+aiV?G
ai*#1F 5T:R*^+m?hQY:P@Hh5eL9GmXL?kNCRDuZ#ZRF#pPE*qmt9*D9@LJ?t&e+u$e@nI!@&dE@!*=*#<G@Q#H
q@EZ>B /9Qa<6\jRlZjdj69:8FjJ?n<pu=##CRcpj<n:iAjcSP*l:5?u\QuNLZK>HYXpp!m@Gyapwhy=6R1@J%*
P^DZ^& N1jJVH*/T9&yt^>V1</uZKbQKLR!NaSJ:+:tubHBF*?TVKKebY4N1m9mknthuJ*pSWl#*CdD=iVPa/K:
yE9l$u d<Wp\@w>a/uAhGq1XJHX#/jwHZqBJ@>qnYDBbYItWjbeYPBk4?GIjBB@A6ES9iuSA6njVh4&nKZJV6th
EmSa:P T!1lbWm6i5>a/mJHd&@mMe*X:a\YLWc51>>ud:=uEyZEbdTCypkNY@&Ik8EHJ^JQY8&NA\lPa4%MaS?w
tl:#AN CR9:ES?TqD=<u:m=bN6^6DNwLtnK^%!t<^TZp\Fl^h1YXT&ySMc:6hdnX?tw>$!mpp6PhbhLS9<CQkY5
Vb&9=q +TmRF9i%Nc@!41m/pFqL%eDQwK%I$yjK$\TmPn%#%%C\^?jw/$i=i9!uYPe$a/uJL^VqZCFMFR%86F=P
L&W5ly lV$P=tVM=*m:>ZQMJI4ehe%I$X4GtkFVb>CCk4m^DNiL>u=q+&FJVDydln:VJKWA<H=iX/c+*Kd8w@N#
MMDj:W @6HnIjRX#n9/WnX#t4GWIyGew9WXH?WY/mNP+Yq>wF*blJj#bqmH\^\!mc1R96RmtWIGyGGGbFS^QlIk
Tma9>6 Zy5pb5RdYpL?W5uQeWyTc918H!VZGcSc!qDpPjHF54=XHeWL6?tR!^T>d&1$/FQl*IXpeQ$R8AmJ<Iy^
atHVEH VH@*Lb/jl1VHVKL+@>q/@4hdpI!!yS<nLeyR#IF6<8D%nHduAa:eM=amn6&MGXdt^bm6%^5L$?lcRFHL
BeXwP9 58cQtPR!uTSN1b<kVYB^u>%pVE94\:!aPR\IuIquibJ+GZE$Mwt/aHet68@++QN89PaC*q9pGSK>8lDu
5P\nE< ?Yn>h$>Tm5/p4X8=*:cAK+y5ZjE^LZ%+@iPVtlkTVCT=VBEHd>B<l8&K1ctjjy?dNHAipBTWRBMul#u^
Z\H&QW XCYVKP6!PZ&yS%>qpk5pw@CJA?RG5G&A^#5DWe88@SV?&^n=d#lFL>J$HN1t1W4qhD@i&JY>kkM?XKdH
!64RCF ZKceINDG84td/*@q+*QJ1cq?T9ah9*cdYjQQ/*dt%h#Y<y=JNKR9NRXLt8k9%=>cQA1e=4\IdN:qF#H5
-AE5L< 00083e465f600110334 Page 244 of binaries2.zip
yL6V+X E1imqQ@YewLdEed8j1Y@Vu*91K+\%>LbMLFMqc=<#Fn1\QwC@W5JeSBcMqEZH8wn6JmlC\d&>Nj!5?1l
AJM%c> C*WyqA\d>n&VKHCKhVJ\bnekL:PS=:1BatZkiYuKu#AQyI=P5*9j5aFXt4+$@:nw&VeXS48M@kh4Ly^q
WbZ$1Z VjHn\8Md9ILTnKXDYZY/y%PRepH/V*@8Q#Q/n#u$H&y^clGlZL4ikV/=qE!mkp^e8A4N:Jw5d/!1L%i&
9PBhay CkBdQ^eXIHYTT>X%GX6%Jj\*N61m@6PB<d\^:bqGYTn%PHtC\^HhitR5dYQGW8RIAaYy+&$IGE8bpI#p
Zi*/YL *H>G8E#KHC^Jwi#nAkn4FKhCJqEY<K&\!a1iX*R/#GP>TQ6CbwbF>4u8#ql*@y6RpRVIqE!qk48JkXd+
N>5di! kV5YbCt%+!bR$DZ5DHm8D&>^4HH?ed6=%DuWpK*I\PmXip>:nnI&@9B:p18AjkuuiuF*b5PhBSeNZ9#J
Zq4apE PmaSBmYiMEpEPe&Bajl5jSDJiP<aMt!1alQYiKDH!MbH55CPEnu&SHQS/9nPj#6tPh8nGBeL:9V4+%u^
u=RA6Z &yl4pj:Au@5QCJ?%kKn?K%RlDZN<CuEp$4+pZ9cQeIlQdZnTi^^@jj4Q:5ZDC+Rl:?LMFNA<YX@LMuZ?
?^BKQy @@XH$wp\diGI=tEj*Zw@8*@wy9>pnj^!!Pm/+=HLd\KG@$Pj/CqY<4?R&@Jd5NRV^P\=w9u9J!n+n>Wu
EuXNc^ PHN>%d45@%!YXQ<c*jNjndD?6:eG@l4WjaLF@QG=+\wkHnquLA*@Dyi8PiVKQJ9K:XPPc!Yth\@#$?M<
KZ*nqB F&G@<\Ln%V5>JDaX9C&8HQ^<$LB:dplP$yVGI+iMycGS5YWZdGT^MdquTbWF\6&^DT/$q%!EK*=jQ##?
V6Ldb1 LD^VNCT+=%p>waHJ:5klq!tGi:?*q=B$Vla=eVGHu#^tLI%aGlPT4Ppp$=+R5lblAB$h&/^bqcp#F8#M
@\eaSa 5q1M>1nHu*H/wpW5+1K1N8!qlS<?Tjy\VG!KPZwiJa$bS>^1GNmlq8%HpYMTQ&H@k#%n/i:jJ9tcIN8J
FWhEka RlI$K4nAKiB9mbid=!S<IyWTk>EyHD4?VJ#qYp9@&E+YanY?GpA>#<<&Qmb>THKb>tZYh^Ye*D^HSu%S
/l1wNZ FCYdB$4P$/LZYcuuNJey@N9m%m!PZC/%%l#4hJ?@+K@</#N9ZG4jNq8Ga*nydQKKIt1V@iJ5C5ijbS?q
jGbk#b 5Z$^VQ1cnd4+9QDXjtIj&R%FqieX4?/T?mT=VQE\ucFkC&@8ylCjPqMZ8M?cba%c8&8y4W<#qkd@NnMC
KhttbE a<G8@Nl@@wI^:k^1F=dIDCZje=pGN%<ZwBeKD&6:c:5CV=D+9<Ei91*4$jd$*HaAWe#V@/:R1wVhj#V5
milI\k NFk>=nK>4jphtb5aQ\m=VANMy*LADLd9^u9G$yDC+adHyP5A=?\8NZ6tD+%qd&=IZ+>id9/AIeLhiQCL
cD$1pm #qi^c#$a8:X/>T$X^GDID5kcMaJR/BpMlCESHnTbka@=V^*uHAAcB%RPSDZP<+hiEtC/TYe\RVytLGZM
NMS>a: dlXdcn:QR^MLNA$!VkX1pRnanlqLR$#K>aHEYVGFqWi!k<5dMqT&@Vbbl4aWZ<*W\M@+%Nc!ed6QX56J
BqNdw: LqQZCDLHcB\DmN\//a^lQ&B<t4F$n4\anJ&kC4EGH9$H5Jbc:4pW:wqNae@D%9jwQ>VqjkHlZnnJ+hH!
k9nHmD DjY^>CW5DPJmjjkciJ#FlX8HjcI+W^>!te/M^p*khBpS#V4JbeyK6uqcdJ&9T=1^XBInlJma#kjmchlK
+BK<%< nVXY!^J#ZS\Cca/^ZSQ1&i1eSlMjGLtHu/q?tMbNV!$?N%@66knwl?ip:<PyKtAEcLRay?@Ka\uVq?Fc
C4<A+9 KM=TAqZnMbiyhI\dE!/ZJH$ycI\dPlw?w?yah>qhi*H:A&&J::pp/W6qa!qAA^A#&:Z4tVYW^N66Q!!8
B\Acuw @:@&4m#LWX#d=l<j5TLCylpS+&E!nIeS$W8IBZ>e:Z$ETDcPnM4MiuXj4S5j6eyyG>PwP%8:cTaDhHJV
T?c!JQ Da:Y<@p+%NCPmpWFFLV=VB#aTYPE/RlDVh?VwX1byan5kVmcq9!>\L=Ftua>En5nBIak&NSqthwit?X^
ZPdqY1 k*nKGcTliBnd?%8PaZB5Q9J!qBALCVb%9F8aFDRF%HHIZItK%5#Nn@etiuDlK?!wC%y\S/iA?tbd=hB\
?Z/1Cj mLdncIduquMVdN/GLF<&NqkJN4%Jq8qw9:ttH*eZW14c#E+=#DLFN6Eu*JLYbTJ5u>yykl<#jbQj$qnI
@Gq6<\ p>\b!61w=F=M%DbNje>Z<A8NKt5tqlK8:81+FnM6:Fak\YGRh#F5HP&64hN:5k#^DVipm+8!k@5@bNXA
*1bNZt F8==Lyty\Iic*CX1T9nw9kHd&bFqZKI>i\yby1Nlqmt65e!<FC=>X+GTJQ^e\@dtHK8w</PBFW+W<=h4
LQtWY6 &ia$jBeadu@q>8ME#5N+ji+*dn1!#eE8E#m>I>/B5=\pw@cLP\Q\Jbe$PeV&=?Ih5S:t@FZc&e?!wyWq
F?:Al/ G!mLXLQ1W>BPC+b>#<ny@LTD8dENMS<IkhMPmMwV=<PhA*G%M\IAc9weHMPGehG155%PSyPnbY6*%k!C
A=QEFK R8l</^VGQytmRbPi1wMph&cb+1<c8mJ#E@KJ#LGBJHFB\+Kn=PiYhyI*m9:*:pKnNC>FyV*cBWN#E^b>
R9FqIT XRMH%!QBPpQi886t=/y@#:A/GXCVC5WtJuC1eC<Ky\\^j5%&%ll\Y6qhZA=1pSb^iSJD^nH=6WwZ%>^M
Tt9iVC N99%XEW54l4mulc9*QKJm5IJJQBqTb#Rj9$$tYpKc/CH$*:NHJt@pm\de/&c%hQJ+R8Z:8E@&a=a1bPR
t>CAtn wX\:CD?GZnL@Atl\1dd=!jZ/bJHHI84mnYhQ>wARElm5@j\*j1Z<@!qGwX</*X><>Sp<8>T&c9*TG?\Q
yG?JW= \Ai@SKl:AXI>@>MLV64X1Z!DjQaFBi%jhV&HeiW@m$Ji5V=jdjt+Q*ZlI:c@y@<cu?:Qek*%I\4yBC@1
hF<\HV P&pTajAMh\QhSq^wQVFN4/JIH!NQnRq9\QQP$MQQQnaYMhB=tkntF!#D#j8dA?wn>pnytEqX!w/*HSlZ
FHBqkB pE6/:6cFYcd?\PmRLn$hqp=cZY#JQdLkCVAiM@S5TPWmPDqi:e*SRw^@NSduH9WSY*&^ZRdd>dGcHd1q
*^Kk$e BGYVM8W\kjYaeYFI1V?ZVF/t^8!FP4n6/b%Edn!muSEntR</F*GmycK8M%D5=J<8L#/<H8/P^@LjXk9l
/J*X+q W9baWV!<@@kWWw11^JEJj1Vp9>qTZ9l9jlSyGFK/L/ctp\uuIM?SPR&V<N?CA!C$kZ<Xe=M$k6YcRi%B
mDKVj9 NmVZnAAL%XAI$eI<LYVPQ!TJ&8LFBWub\mc6/\RX84I%$!hkYF8Gh5cW/V$8W1p^A5qyEFJKWpweC^EM
J?jd9$ 54S1a^RjbMj9>/dT*S&!nVDLhM*9ACB51WTI%Ndi+HLJcT5!m\VK5lZwiylWuXKWaL\&M\tZ9VSMaGt&
M:WEwl 6F6l%tWkm1TJhd*ae!9#jDmCVSqFGp5WcbBaT9:d?=&YXhQej5Jk8tFKXSVj5Q/MWI@NRbdy%Pd^EpXD
KL$N1G C/HwHn#GKK9JXckN#Y>Q@pFIBjAmV=VcAdPJbMhS#H45LX/q\qem5h1Wq5BMLcF%m4maSJEGIcWW:eG:
:jlZPn mX/KT*+9N%N<+8:RTN*haSNtta=I9*TA\5=QFM<jET#HhGZcRT$?H&hCa^@81IQH\>>B#m14WBhj8nG?
t9dMtP FFCadV&%@Th:MJT669?//#HE^hlG@eVTDY+!dhtlDki&piVAtQKcuEdRYbt1PKp>!%VaYm/epPDVkT*!
Z#qYwS S!Rn%FphucAnucApFlEP!&FuMtYT\Hpb=TEV=w:+W65QB+I:qCeCqcucBJlDaKk@?TGqlw=FkqCy5dTH
>tk*9P Hbc&cTPK6Rc/kD8m/=qq!mR+iB/^bAlQG@X8Lcbb*l8&9bX$l:S>+SHm6hiV=4XLitX</im!VGu$iL@H
LdW4cV k@lCkX/ay$%QdMHlTCm@k=BT5GFdM:Y<yZD8HNctZPD&Vcql/p#$km^Vntk+cScF+jWaIed^P@+ddEHd
mt!Tw* 66V6w$XupQRcBJ9CB4NWWbE!tll+XSqXE\dPcGAEy&&ZR&?C?FKM6S%TVPALF1%hXYdJ$AM^R=>dMpiB
J=8:Iu DdJMAV>+^cy*&8T?PC=y?H!AB*cdYi&A>dCqRJS$V*1FJicSbiyI4>KZDA6mP$#bK\AD&b=Bw?i8Sycy
CiL?EH F%I/S+RcF%y>w?566#^TREIWwtQmww5+bhy8/dJM:Z&QqlFeFuLFk>NY8/Y=$k<NEj&//jeDQD+jTZyh
mAehj? 1#C?FNAS^ypFMA>GDa!!lJpbN%15E!M/tZ!:l=VCuSK8y$\T:iJ!Hw6G#an>uLi?4mPC#<nWkPteT<SE
h!P1#l 4$Xc48mI@jENe%9l+BAj6Ce\nYVG=4DZP/@HDADM^kIy#C:qXCJQSc!=WiIJG\Hd^>E8:Q\ENj4W6ALT
X1IBql BmGqtt:9jLS/+:SanSmp?XbepyTMYFE@!%Rc@N!mC?qk@lH#AIiGB@MQuQ>c\TAjc=5q@Wnc+pd*M5cZ
uGA5$H K1TeIn$d#MT&9thww?k@hh@HDF4wMkVK=AXVFllj1pcJL&%8u$Xp6F%c=P%aj/dhCL#ujpN$/w@*h4LV
Sw>adw <keitJ>qckjaDPp::$DDk@XBaB//4\@&kY>1L1$ttbekC%CJL$*kn\5aqcpGi?kC<h+dCJeS6n/\?PQ!
l$j!1# 4#KkYHbX*#K?%L=SDLaJ&kP&%R4acyb<lk4jASM#V8R::tMMaFk>9mWh@88&^>49cGDPk?Wk!uLVNtw8
:>G#C& %R#G=b>TWw?PLRT6HZicN!jFpZiMpl&B?cBICt=q=y%mPi>E!l*RM8jHLq>Mb9d=qlnV^Bq$C4^hGhHq
eak:*Y 4/?94Su*\pyyX=k=$9ticGqP=GWtL9%El#k!>wk1Q9^dTI=+n8IL#tFumKqI6LGGH6G:TV%W5%Z\NQS4
8epCuA Lb6?4uZ%$#8Hq6VZIV>TLI<Z?1Sa+l&jccqD#i1nuP+\iA&</J+<%d@y%*dIRl?4aI@k<llhGQ+*jHGS
F^nPRA u9mcd*pI99R#LQGIH=l@un:&jaDu<ku<@:tAj@u%@LM56>@@#m>*lY8S1J/i\LEL@y5=\5+9\$j>$YG/
Q+Ptl9 @M+La66pVCBVN\E$bM!L$eX+G!MiAtm<kJ5k!#Tk5p%HEM/?G#ciHHhQQ^wR$Yk9wD&K&mZ@naDhjtLc
j%k%Z> C$ZXRVK1i$NiHbQFaSl\aIPeJ*e6uJ>q85Nmdub%4mQ8a!jjLI\9uZ%jBc*P%^:@#W^B5Kq5^5/iFuWY
!h%1t5 IwRJD8*:S8!HJS>PV/ihCW6A8>S9Kd$Kk$%X%RPc/^HQw&t?$Sak9RCR/!6=a*yILQX6%Ipi>&*S>c\:
6$YanY V@/di5k!=chKY8qPRyAn/FihtctAu$c!Mtp&B@+duQ<klYI\\w+AEk\5p#^N5uT%lXwRdD4E6*8Y=nq5
%^!YTM ^GZ=hI?VP:JMIW!q%At5#!C^hG!#V&innnai&SX+uYR\W*Q<N@+*JLcyyW+V8=4q+6Ii:RN^<%%?K!y*
MBjV#> /P!PR<ejH@dAhqWMSwR>k%8/#FZ/*p^dkACPc%yn1S6nWS%pthy@A@X5KYIcjLhy$VPk6cNZinpPhW+\
6Q?NdQ L9ITT+utSc+HdXGehmn%kW?T@!aGb!bMLC*#P$wyWiHcw/XR1PEHhHDwNp5YILNha5?ZQ&NWCXIi8Hq\
uS+F@p #^h5$K:Nl/+wC8G+BFttEqmHkC:p!!K1aubbytNH?X!LjFQYcH=<KhA<Ll6Htuub\=Zk16u9AJGl5m+I
k?h@!L Nt%V%JCPaIZDDJ8l+@w8kGZGu4*J64Id+V>8j%6?bmn1yl!N?^%:m9d86i*TJY>9!WyudD@aFHB6D^RM
-A4$:k 0000194978d00110334 Page 245 of binaries2.zip
!yMuIC *8YIRD8!VMqh$+aBnh6VjGqy&#y:pKB=jh@lZkYM6TC^6IRqF@C:kZWnVk:MImBCPBw4Ru86EIRPTXFX
VeQbFA kE9*QMYt:c4bwaa#pa/&:e4F%4yXD@RnmD!NXn\FRALIL\S<!LF<emRda>\>>iNLJ&m4VE5V<K:wAGkp
pW?#88 >+?5$\BeqA5%DAE<i^A?H=b8&&RHpKWYBJ#aE\*Z%<Fij#tY>!Rm#<T&tRn*b8n5e+LH@aEc66&\LI8>
6D4W\I 5k1wRJBqYnXb9N1HlTJK9NGeDp*p\WcR<mDaqPlpR+iuTSA=%DJ\GuJHT%K\!kKmZ4VkYR8iAl8t=Jc:
5J+&6? IEJHymQbi+KbYFt$$WD#NH8K>lpNFcDmE1mle1ll$/F4*6MP58W\@:S1<1Ry:uhp*ISby9J<SFMeJJdm
j1&iej iqI:w1$AXata!qR#a%nIabCbihe#:peW:Ack#1!HJp*I=:QVn@\ntX@&i6c&c<8lY&$VW^%R&FWy6I$A
$/bdmK NeT#GQIj/aKap!DqXCBRJ=I<5p!ZybJRWkPjMjnnB@GqG5$jTVD&pWBYD4X$D%/Y<C9hW@ETT^Fa=JIS
:^BM:Y 5IWF#Zt=apRq<$9?WSE<RNmHHi9Y^q/Q@XT*&l?9wEcV**GwweQp=t1X^P\#&NRFiSmH9$tYKjY@qDkd
Za%&Jp n4GZ<cZ#XPFY>aWh>eH<BNVqn4bjn!>p>4FQ6mVpamBHRNwd&dMIN+LiXbW%bQq1cX9eu\4@PXBD9BB!
G$R8Ct u@%NQGR9!%TwY:!n*EN^YcbEnGWu^Y$LBItq>81BRa1!e8hwmmPB^J6GEE4V&qS+^+1dmtCBea:Ran5=
LJVBn* N$p=<<XKw$8T^<C961MVY!M$$ik%%F%QDMh%1CEu<h#P%DBEqT#VVF\/A9\N?a%Hq1qhPiVFY1iaknY#
*RG5j> VJ6X+p8uM4$q>kuV%I?aZVS&&Z%Fb@!<6bN1Q8/MTybkW&cbe5?w1BQ5E8JwpF<*Q*+$+Mbt6:S^WcVN
^iEtQC ^#6c\=C<&TNRX&&jjQ!b&*98wabaZe+T<A61GINNF#tA+G@a+VDCVD&!VAub^ZHHZT6<nFkehtTA=l*I
!\Z\u= HAc6?J+X#a4<$>ZBhH#HD#dX:tYN%JSwnbtA\kQkdBmqk9Y5cKP^P1J/Pqp^KkC%/**WWDMPdTPN<ADn
LX>$Gp nAjMPYS8##Kqa9l+l/8$&ajQVm!Nep9d4S^H$\QiQMnNBD@qQ8DkQKMD=6u?j?b+j<j=A6V\yBiiG=IB
Tm/E5/ <HQkd&iY1RuiMiaqN+ILiZI$hXmHQhiKRhq&waMPZHACuPpBNR#JjV/4RV?\GA<AdyeQ:bSK4#S:hAmW
<FRPpZ 4?khj>P?L94JuYn@kNci4Pp<$lph?TC9hy@<GVZ1ESW:Hh58:/&=jlWi?i9u+*@5?jtapKV^eL4tj?DQ
>QKcR> @@:?#%C^@^IA>P4%d:MJjjHt%hkdhMQytRD*RIq<TbD$D1C@TB4+dTNCHb1<iYEK#\Q^%T:LA*p6*GVS
9l5wyK q:@#tJDnM!YldDY@eA%ZG!9PeHy#Kim?LcAJ6M9GM#A%AiaYd6Q+JP5#6$>RNP>c#*BtY$:Fp1Sq96?n
1c:5=8 QE$YDZ\a=aVy%ejFaNdtcGteEcwTaJeE&NPW5K1EFMS*uCbFP&?S@eLQYSCeEqV:#GE9thl*KHWN*8F*
WWEXmi qF&P*?QK6/$#=w1:4V\cKIVX%i=hMc5YT%&/cai/$CY>=aqh+WK=P\%%qmbyLjRdw=j+j95ELKC^Qp?V
j116u$ QCuFNB9i/ctpm*p!MwJ^ELAtZIGPbbHtmXMEw@K9j@^aWYMC*w#m9J6bqP=Zw<X%&>@pBJ6IH^GHeGbL
TP/JJ> uI8@cVM56qN+6ut/WQ8XIdYLeTBhaAimdDik/8FncB%&<e9!p>LH@S$RJby^b/?wVYkq\B&aZtj$T9aM
iRQiVe TXX^LlIMGKC5H@iTKpJ5^Bh9cZ@amKuSqpG1Wtd9#iVMXaP6#QSl%L&N<b9VtIGqE?*MH8Bm+/ELSZT1
<B^^p% IXkD16BGal^KVRR%>>NiC*QJ8d<#8#BWakQcy^PhNDpWZYB&npZc<btRj8uML5Wi1huV+?HQbY9nbLYq
1*t%B1 !RqtV#11ETk/u$M:CHFP+w^/ZQCBPeDFwGqydM&lSAhm8<^wiwVDtuHNdK9<?JF*JK%CKVJSwGy$8TJp
IlwFVn plmM5QFKSla1?ym^jCFmM+&wYA8BSLpMQ*I:6NPp<&wt!L<VAM6E6kXRH!jS/VYn5+5G*E&=N=dcwH6S
ie?CQM =!4/Rw@aSmqckkkT&jCa+ZCG5Yh5$4YKSLt5wFTjhy<eIYa==*@CBIPn8htCHV=tm:Si?+n:MbJR+?pI
weW9/^ 9hQHBw+d$i!Sa9SjQBL^4M>!/e?\ed>>F8QGAAnKL=*Gp&4WHj:!BaZpCqe\YJ@h45>a^kSE:WtYA5!m
a>Ad#+ &$JPdpeqSu#PbbbGkG8B?\nbiKYHFyySuBSFK8/TTCnIp$SmT8*yITDA>S@:+ybLb>JDLSdp8KG:q:^R
&X6TcE E#BG1DdNt&l!cFFCycGtCul:9l/M!qw<9TJlw/48@lc#aSQ6WVCdyPK/TeGLphEKkHGS:nteABkZGC8!
\nNmXe ##bIlAHyTG%>uZb><$p/HI+Z:!EJ@w6J6ded@Pj+<PcVBI?1Gk%&kkS$E69WthE^h9D6BFLhbd*tMQ^p
ie5^/w ?&WHkGWe=wcqEL<!??Y%4Ablc?HY^DX=uQaKq4bem4l$LtC$ElTRt&b@&>^kDNCaM?*yFH!MbJC9#8tS
HE8t+N hQn>^YS5m<lARMQGR?NIR#Bl\!BEG$/G\BwTdKYn+Q/NTIFiic1d@*^tQS+CTu/qh<b5RJ5:lP4!ipmY
:>ni*p p!qQe4Hu\/q<XAb&ukA??>dl<SYl$%JBl8n/V<nFPX<ku44J/a&1*jZE9B/kWuA4EBTBLmX84LJ>h/%&
/^\SAD bVeEp6WSD+Q>MH5N9B=NFEJMBbGmae>PRq6^QSnk=S^5^$Tcl8d?k8=BCeaEICQ=mThm%EbCdWiG:@RR
ty=QM5 p*1?WAV1tn5E^kH8WnYa&6&AndEIl1b5THb?TY\:YNu65cXaFF$qKbyhYmD+qi@aNbH\V>EZ8EJB%!c&
QaHi5> +k\DKquKnT9w$mTy/nbiI#W8hDud%AyVA$KMGP!cCXSwF*j:/P889cWP#R:c*kTd*V$&1tc*/Nt1?L&w
L?H=h\ qwTMVR^lZIeI/:S1:=<8q^SLq:nPyAjQhum8c\uy%G+W!4myMiQ?ybq5HcIy4utGeKN=+qbBp6=JnD>!
*N>1qp XlGtlR*HBF!/k%+a=lD/tAYnAPdJ&?!YydI=quB&>bZed8uK&<8BK+phwSanQuNJMe9b^u8/ICMqFRmm
kWZLjB SF5mEcJ4I%thXyLJ\SWy*l$K$YddYh<N5J#4=Hiaa\%6R^F*/n58Ru8Wdwm$?N:i>G4Bby1dlV$6NYjp
yR%q\% jY&5y>p#lZbNX@8>Xl?jPkIW8Q98ImS<Ie!?LV@6d4Z#>q%q1dpMAA&IePbASN%/?<^I<Jdtp4mk#^X/
$M<\uM <GbInD8%^%1hXYnwCP+SILTijyw^>^j?Rnh/Z%^qQN1jRKDGI*5<XFEibT/k#^!jNB/aGj/P*K\@y^<$
=X+Zn@ */9aR#KP?S/H/G5h/N?Q@@*d48i@?E@@5R@>Vii*n=%@am\\9*5t?ytu>uSp</WZ\RXR@>X9tt@bBZ^=
5EA4@G 4FiTht>jBmP!u@IVRG55<F@6Zl##+Lh$<$k?K!9#\8D9\P^Gtm#4:+%>\ZZ8yuYMS%>qtZe!yk?dZ$mM
Y18Z8M L/b?=bINbqnE6+G#@a6V5c9HVGLQ4wVt?:PD4j\LG%^W?FX%edWA#=b^wIDGF1yG!EythCdGlQDI/bDw
ES*G:X h6W@bV?=/yBcSTiYM#@JI:GXS=uF@WYGlQ!p\?#M+EyG<##N#66!?^V+/?F/aJT%AN!\%+Qhj?ASSAT^
AKlh?J BpW+F>bt>5auH%ud^XTwlE%NqDAmWJV@i@GAV1>qY<$p>@d=dIC$/AP#&/wDSH1?u4t<jjIIV<<HJip1
twIqJA cy\!j+N4uYTTRc6a6BZJX68RbGZW*LJTQ@nW:<W:1$dGpkyA>u#nb$T\CQjJuuZ^Hy@^9<h!qJnh?/$n
/aLAPq #DC@jpBEen&w=Sm/aPG>KMpBWenpLe6qELwLTC/Edt\hPuYRt/$*Y@>Q+?Q%HJ=m<Mn^!uw@6pY\DVnn
+pYeMl MWB%F1M&I#84#8XA:^*Ducl=@aBp1Zw55NWSFA?+KK*nQIY9FNlAWYe9n$\a&=u/PC=L/LnA@b8n=Fc+
B?AG!m TF46n\cuZp!hYRkPVNeTCDk>PI>Nu9ub%Zkk=?cyBy?:GX&h#5AhF:1ndMtW%ZX?1?G?cWeMY<uG>N?b
Ii>kb8 q:kidBPnNke56<:Y8JRclXP*%&tA+y^cZ%9GD>FpG>p$!@Aw9Mnu$#@DAuW\5Wk^Xq%wt@\&\iAZY*wJ
h+/CC\ %=A+qub!Qk$$:@/SpElmpNRZP+L\BCk6nhTc4YaLaR=%i5Mhwn@Sp5=qWk^6$1APXtXV^FpYe@<lYEqA
>*hY9Z S$&Qk?PhM@l9F1ZR$@ATBAkBaT4%WBM%B?//#KcnYykPBVTkyFnL>G$Ch$68h!DIah\1kH:lhPlhk\t$
bk!Si^ &Qd8>AWypilbZS$uCBIk#eW@/^*jTa=*#4M&b<n9+#6dL&SH?*@#?qqZ!=*$JN6udLp@FG^8>69N&k%D
YQ?w6p YTLMJAIPbl6e/qAC!t9SG:#yeH4TLy@>B?bY&a?*XuEItDcu1*#&S9X=NR<V6Zi+y?5l?bi?@6$6mad5
kc1SA> VuP+Nu8@bhtN\4b=\NXAtN%DNS5ZeD\aT%\Ht1YBHaVthNkh$/ED5@u5$iKBqptLu+jp:TP@9ie6S@>=
nT4FwM e+DihGGwhPqJ+>Qyy59uR^up64WjcVVph<I+MIhw8\J?1nA^T=KtTSGMMdWa%k4E+HB4\A/hbTtnnW!H
5u1XHn dt@1AI?Q?YeZ!p:S$nW%wuDXQy5%@V\>6^*%M6a\/I<Q%$NLB*p?:X5YLdeQQB>:#=i8Wk9biCLi9E9i
ZShKJS J$\:\Vmhba?F6DK^*k9&ytT:knMYN\T/a6j&AqV1<5JR&i%<<>SF:Qq4#/Bkdu6/Q45$ZBbbQhJ>JJ!m
u$V#kE GcKXpJq!5tEDHLSc$##de#m+j+1Sh>h+Tm!R$wjZBB8e:>cJ:?nBLk:NeZQ@c8q19Aj$jK&X<#Hd=^@y
jbjhCV j*c\dTQM\&^<GQFLAcyld>Pek:<#R4:Aw9tAJDHKL9NYd@u&#Ym=L!:wjEDjLcG\#cMQ##b5q%Z:!wNI
k/6yXA tu/BHV*iTAdL+YBQ1X:th\ywi+h6b+k8M8<>BM=dX#pJq&i>/yp1QeDQ=yYh@Sj%/i?Z*@8>?qpl/:5>
ipCEp/ ?RY*n!j1d>jCj^R@?D&m#AM8eQ&@*<W\@k/$m9jwQ%BLA\RWAAIACAAhXt$q+bE%<b+kAAA&YAAAJkAA
1BlZVi AGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>6bDl+MVR8at%\#F5@nQT&eqeAA#JkI?<::b+4N*EX
VH%u4T %\5<\K&9N9CKGEnudn9XdqK+el$\kIH6ZyEETbHG6RyZKiK6:Tc8ZD^AyMV@pIAW#G?Gwqc:h@9hq+ek
?p5&eT #6&*N#8pSA/H=Q^tl9\?@?L*j%9^#?@j1/1@B9$Gu*@B=!?1>*QF*%S*j4:JD*@#VTd$m!<@@QBD>eN@
^BHXlJ @qCb@@nu/4***19ij@@>/5MQQ/\iHl/1n#:/1Q4+++?4V#:=yQ4$$$?4L:@<594mm!?1##@@9Q455<?1
@C@L4R d@+8XZ@+R/4?wj1yT8ye@j6Q894yV*?1@9=j@\$>HQA=+uQC==#bA@+eWHbA&aHKWu:pmQIn9l^SjpV=
d#6=^W MiZZVmk@wj\E=wV!W?Kt1nQK#!k@w@!MknQKE@kEQy%#X@^:^PiED=Yq*D*?HCDDAVIeIMMBM4BIpPEA
AbDjF$ GR/R+RAbDyCB^aRMB<l\kA\H!HCADC\/bDlAlkNpPECGA&R+JJSBnkQpPJAeKiZl5TV$i<LunE@KR+a5
-AD?AM 00022fe198d00110334 Page 246 of binaries2.zip
pBMLWY S*S?SEhHNH1ELK\GXB:^=RlbnyCF%RI=nyDnCDtPJ!yLYXYR+\kbnyDlCBqIhWjIeaRMS<l\Sq<Jj%tF
qKPmk4 /Cj@ulj%Hqmm$+H+qFYN9p?R/aSPV?nkBJqP/Q8E!lMcPb&w4bTuk@6GPjw@wj<V?1eyP1H@E=XDllNp
BQK%Q& PKZE$=bu+5m>p&R$9YjIeEb@b<l&ll^u>MhVT*JAB&jIeTa=MDCid4^$lm^u!HKGEGh$!E5A5y#^+lpQ
cp>4ce uXF\lm!$LM+pC?dpDFuPyA?YlXaD#eKJq%KCDAp!JMmRIEPCDL!eIMMbMmVIpCDDGVL\EwMMCVIp!JAk
iG\\u5 R+IMcBwjqEPGBBpTbEkRIKH@M^yLiDHlwiPS=kn#tKkQcy8iPXb@Xj%V>hXZZ%Xjj@%%>i&**%djjjhh
>+tl6H >iPQQ%djj@>>>jQQQ%i@@QJL>i899%b>*%jY&t1i=<4<X/4?<a>@^D/tHb*+Z$Z6Mpj6Ey81Pq4@j@Hn
c5K*qM IJld/JaQ?KX@//j\6#Ve$QK#=ePq/JaGDDck\=lT=GcI#+IES^I=l/>+\Bd?l6wdYuy#du*j9wZY5yW%
lCCTYj BNB6K%C$<m=G+=N*JCVJ8jC*%N*!JAu4M+SeH4!J5XB*\?QlVp1Q@8y?klLe!5iycb9bl?t^N?yB8eK@
eeWS&h SnF<%1NyG4qVaL1?/ZjDZY1Vdi6p9XXK:pV$lc@qtQ\5al^E1tedC@<c6eG$?P9N@nEtPeYwSJych$Q6
PuX\#S !tNki^YDe+%MRW$4Q$!lC:Y!D5>ycYLll!p8NL^IjaRI$IDT?6Eacd$m?W%<VkitEL\Y/NcwDyP9dPFF
lWt&u4 m=W+!JDEpA#/F#L#4%Ent:d9/!lcKFIPQktSPtWm6bPy8KJ^kn#KS>6PKcp=yGqmQ1lttu<*JQ*+1FwX
/cMntN RyDNJB5Vmdcbm4au8m5<W%4W6INS4y5QhJwihbI>6A4c>4TihM^$aq+<wj@HN6nteb4:Lwwu^Z!$RnTw
aSci5S :$#TE?anRLtD\<VGTYyQ9BcV^aINHXRj4Ei>D6l!QBLc$PC6<caL9ndBGj#Rj4PnVXTGV&DinFk!^48l
jQR6lA %kQcNb&LHu!\cn?:aKPYT81I*Y+X&WS1Z%C*htlpF%#WM>ZV<+1YD*c>5aE*aEIy>1YSG9K+%P%WRuXR
mhIbbS n/%B8$FJ1wA$KEj*#Rm:+*\y>*1@M%lK\iuchnVkV49Aq4GtL%CFGEpPQ*F><GNN+%#6V*CLHin1RMW8
48m54b ekP\WqMZ1cdn=>%TQtt!cQSmcTe8=m!G^h:G^YLuL!T18/wQId^p+WN?:Nq:=jqeV4bwEZ\y6\69QX5%
aDHPA? MykFM/=I1X<j8D#w*@ciY!6Yw*qX@l9*H!:+F<INdG*Lu>YHGQ%d<QJC\@yiiM=/ln%*R@&F&86/^$Mk
=E<D=S jLGDJw=Yp<$$&G5?W=eHiwjCAQkW@kjW&lTw1^V*5PTY<BDj*VMcMq*Hiai/?dF9h!K<K>Z:j8+d&P?^
Glkec? :h8=C:F8t4:Sh/pjttau#X&1&yS/GIb*yY&ZYk&La*1h\1TBkuXKMA\LDh%CT:qNVnH8*1Fh*&1!?^5/
\uZAEu *cG\pCEM9hw%9dJcPY6TeuZV6tRk:%EdP5u&NHV#R8YY\t1n*\kw%YkjhPGBA=qjKQFedpXVt*ae&#FF
56wm<A AGkHdhlYyR=wpKt?wqkD!*ljyq+yDjiBcN&TZRjjbq+DADJh/mWAwb=E1=RIWVTVi1MT@CE^p=<BZlKh
+Y@5uF ttGlR9a\@%kHHhu*8t>+9HY#G#jWG+*YaCu6AH<R1>LwkRHAA6emNlk$nXYE9VLBdRIS!6aVHwkh+^=i
lc#65Z WM4SQ1kbL*$a^WV&Qy1B<bMApcnXI#WZDGCCAMB&qnaAwBZ>PMc:kZAGn5XA#Y8qYqTEIF1JAdlWN\MB
qcAACY X$wbISdeA/lt9A!t#*myGC<LV1Jh!i$#@tFd?tHjE8D=Bj?Ah==^1?BhJ^n8Zea:+JT81V!awa:5u*5G
&i\aku 4LD+9:Hkbc!ywaKZK::h+CIEa%^eeQRF9A9SZ?NhLQa&8JeCt?*::nu88Xh^$h$A!A*i8J9!b\Le\b%T
p6BY*w <Sw8@ed>F#Y5Q5W>HL6$?F4<>*I:L<M4whACW+5:lTYc+:aZ/Xyji4qZj$9>mu5qIM:+CmqmlmuaAul6
nwbS/P 5Bm$@q?n4AZcDnCk:@T<Z@Y<BN/\yXmR$^=^^BT<&P?/<YqIWjh6Q$V@G8Zi!Z:A!nhWZm@%h!mAcW>\
ac*AmV cN9>EDq/a#n%AjFS%<BY!!:NQiEb&Y&hZ1MP@4$h5b9*jZLE#/mVhZJ!wjM%lS%mi=>$A$5iRCXnJAK?
=>p?In tCdyni^11ca\KIwFb9<cVc46AC>8EwNCY^=YMBtF9nKNN##/S*^Aaa*8>aT+Dja%Bek%Ii=CQPk/Xc6J
<dIV&u D%EMtBc6:B*1Ct@V>AER#\$mK6&B=*/&H:%?==FHDeWnQNFDT6MRp%chpylBwE>CWGtEWl:q$$DnW\HW
dQEqn+ lW^Zjp5BN&$Dk/>X:GcyZP=HZ<qRiKIJ<T=Cap6B66:Dk>GK\plL<%@#@AMi%eBSZed8RlG@>9ZC%=tu
!a*J+/ iWNeP<EjwZL>RHP5W!e#Lb>8R+PWTdeh^4&HS+Q=u^B@!lnE4t@dGtm#X&ueIVC6&=b\H%StKmW>D$hD
TjydL> T1LEa^*Dmq9cQ@ADt%b1^Lt6FW?#t^/qa:1Zhuyp*p=:wqktn:VPKCtChhBJ:D9kc<RQ=YFMN!tQPDFG
ARuEqh NTFP6Gq5cL%CMnWadPB8bJ#*tBVC>=J*\9=GJI86CE>Ep:?L$Zb\qPFQVbNJeIh44WFLPRXkdP@kTNXa
^#dmi@ D=TH5^^G>$yM%F/6ELdT=1dqadEIGpZFI>ZDl5BBawilGNLF9quE=jD&KD&tJKY<k6+y>ES?\E^^hT/u
YG5<G# G4jEHTt+nj&QKicAy8C6Z?IdXC#8S1:I?8IM+yYyD\#adE=#ityJ>EX8N=h9#H<J^Z:#@uNbN59epF*K
ecDYB< 4PYa#:HCL9WEI#tDGW5<q?QDybkRKL@kC5JhpPy=@MP^HT$ucwGC9EKZ<5K:pmQN::nRKYWwEF\CPZ/G
lC\X%n +:/MeT9@T9\Ze8I#LM1:$HBLjiHyP#bj@#6DG&SS\D*/T9\uH/iIjiupw\b6ZiHd6Z^dL>*\wKbtD@6u
hn1bSD &qa&E:u^dd>Vh?q4<X<>GLbS:$1Bj^Qbi!>X+pJkR6K#8$iBi#QHP>Fqt6HAF#\M<qE?>qDGP>Iw*8!F
LWai89 H4Hd+bFn!RM\ZF$n@LlDKV:RPV/aZ/KJME?ph/a\V?1ywT\lSwRJBJ:9G$P+<w#8mJb^*1MIw\Ry=q$y
G9bAC? #GI9+CjWtD6d/\AeMXy$@pKHVp<LD<4>SH6NN@&:KB+W^ZXRdKaD1F>+@+#H\N:wWh1wbIwN^b@TEY/C
H$FYuC &4VRPDN%SKFu8il:wh$X>RDAMhPY+maut4+n8cctl@4C!lQqiF$>>k$B4&^/:A&5e>p*t6Ihtja>kC*#
CSa!>? SLHP+TH!iq<w@EHKm&eKJ!Nymt>6/lT*::RGMLp\hkAmmn@4YwN*FPG#^$5GNXA$bR\FZED$GpmC?yqk
S%1Qwe n9IIt9\K^n*KB?X/cy@11Z*hed6MKjFLn%MtY:L6%LS4AaQ>LDVn*W^+l?ha@=iVK%6\d&dee&EtjM8+
npKm?i =!/+l@ayC+KS#hI9:VQ<=9yNZMql\Ab9L9m^Tjh8DZ:J:!$ke5G4Di=pS=<jmaujw@1\F9@&@T@SXCn+
AFFdy1 =K+QCPtLY>LLwRSPX*FiLP%a9*ujL*HhAq45L1EqD9eaw^d<ZNHaqk=9+5Tqq:yi#9%YlbRKPjuk65iQ
/pCAuE c>T:1MtSS$A?Z5^nh4TA+YDP+/WLPw@MJ=R9@\VauJ^AH/TTZd!pH<^8S*:l5&\<+Zd\w:dS!/dVA/Y5
K^!Num ?uwW&BVkEajW14F4P%c%T5w/*85@11i&iSIIBw^1B*h^apLR?b#l?5jWBuEu=hi$q&?icql:?N6\LbWP
YwP:mq M*nRFA!*p?QIWR8>JGT8#^NK@@CjY:L=bmCFQ#>+&PA/LT<lB\4:KACB^\^*G8/9\iASnCARwj$69L9p
:!E/Qu a!kj&CWiWV:ZCZS!6JFkPe<n@PRJD<:p9FM=FcCDy?DDRl&CKpF^m>jC>D&GK1T8ydc8up#jpB=:pS\6
8cY:u& T=ky>FyQ4c1y!@cJ<tPI#B9FHiVt!:piuJBGCVntccyp5q5B<S+>u!uM8=IK1@NS\YERZn\yIcWICG>t
Y++tlY 4Th!+HnS\I@b\W\:M+AmMKd=bdNpMX$5S$=j=QM>>N54LTqlGa#8N91lQCLllQhcDnCu*T^!HAP41?n<
VmDcTK C:JnB4BelppDF9Dq/eFDuTLHacS@R@1uGRMRwJ:T#bTRNDSBy1Q$CPWdyGmHjBy!6Z%yamu<1cWh<kEe
V9#/BX YX8@nWH46p6J:\^qj9H?YPMJlPX6!?h?GDhbcc6/BZPN+TpcQ@T^I%^i4X\u+htbeJ5QA\n9S^y@tHa<
#h+:d$ d+8dP&G4lXEbRXSL&!pE6TMhA95qQYmu5iS@Ay@nCh=QwSa=#:MtPI8=Y?#1dS4TnwSmu5>IN@NT$/L5
F4YLE> DHan6Ypwm$w/ZSj8tw>eG<yYCMC=QBC88:QY9u^qbJpQh/YbpkNhcR48^4dct*M$i$%9#>q8<*#?J4*+
8Sy/CE Wtp?8M1ZMb+>>q9*j/jXb/i5%>hc*G&Hh+=qZ\KG<Jd%5:dDaLq6q#u55!Hu%/&=c5hbj+*L*4&k8R#j
t9a8t< L/\jtJ5hu<jA1#a<8MCuBSRGe$C<6E@uCi!*D#BZ=4J!5W4l<&&&TX=$:9p+k*6y@/D@J5hHRa*pS$+:
uqYJ8= ?K@\&E%Mmab1%I:!SMYQD$PZ=JVYpXDi1BeZlhCJn^u45FqB&Y9TeJPH=!9I=m\Z6td:%AlL<cYkDADe
Cy*F^t dEu*QH^H@hNFBa5wMN>QiFS&dai8J\^1CAZ@aI:l8L1NK=QX4tG<VKPiccDEI@AXFPE\9IYc$pXycw&C
YaDkWN jWc+*:S<wPV+YCX&VY&dPyZ*B$yLnVClC@:=XqGEa4qdRRhwPc?mc4kQ6hA94H=?4XP%aD%M?%aBb<qQ
MeWI#A 5Iy51H^1!BAG^?5W=jXPZ@R@KAGDSY?wJ+Rbn8=#KM:Vaj+tEa6huw%+$kEIiuPQAR:CB#&68KFS16Ey
n+ue1h D5&pKW<<:BG=$KKb>nN6mpZ@kIZiS:9t>RjA@WR>YkR&I=?Z1Rp?n>hKCE/ab@*Q6YmXXy4>Y:6hq\:w
mAR^85 V\6JQEy6EBWl9l<Nqy*RE=A6VVKKPaY!@qIuZhjcYMa^6hQAF*m5+ANH#\BIE/:EIM^quVSR1<V<p<Mb
$!AkVT u>5Z6KlG#n6K1ja/eS+LM#e>!KRjbCn=BPm#IRiF#@GtBH*Dj/TLNZF/=I6qFK9^5X\1N?%!J=kZ\8?k
t/htpu &:c>*khLt51PuFcmm#?YdRkbIqkdR^@cj@pepICRIbQ96!#uHPSL$tb%%^eQ6*1P94cEdLd4PuNqNp5<
!Dm6Lh XHA5yt%?4?TkXn96:DcBTF6m<eJ9ne/%8WXEtmPi@J/:TPh8kNZh8buy48Xh$tt&JFdjAbjC6Zy?!@:L
+>C&Va je#q/>cQj*:?F@^6tLZmYXmny&ZhZ*B:^c?ZlM9*MS*BBd+P69l6?j:K<61TC%*Wa%hI=&!A+=Qwey>#
/1!1pE #bXtV?!Cq?=q:bV:tLTVS4=\WPA>G64h6KB6JAe$*?Ne@VX+bTFdXW6H%e6>#p88%Mc^!ij9e<=#Tj%C
B/+dIk tLdi^+\%DIMe+R:9t=+TM9%iMy+FRReped*HGjpED4nAh^HD>Ab&+a%e:*eG8bj=^kQh9QS8#ZelAPNn
HJCZ#? @?9VY%@8a>K>V4G95Slk<Ep8plw>\e/bBM6a:uQCQ8+S%4mp>uZd\J$WQiNV8e<bP+Y/tlF<CGH6*$jN
I9D\D# %!^!Y9&mmG/=n#qMtCHaYd4PkGCN:$H\9hbS%u^ldwu@anjZGmk*11GXhM/ZNMhl=V/uT&NL>kp6CLLG
-AiHG= 000475170c500110334 Page 247 of binaries2.zip
n5T!p$ c=+QC1M5pP%m/8#FSARy?D/tpD:SubcRbE9&$5KwBn!I+MW^Dyj:uNPePwE\WN6ih\QXT$uuQM6>Vp6H
T*i<D5 tyVZT9X?85y*tn&HScyHwHiJ</iH9cD:tEG&W@>GR8@:bt=l&JZW#R=YFiFpC$YY?E?@cRLlRL@4An!R
MaB*/Y V9>qu<TdKa1uki>#8u/u>u8/H<4Zii%F@<QAF:i<49qmb5pVPDeI6y=chcF#9nNyBF:B@K8c#/Xc#dEj
<6M>?h ^*?$#w*F^^qTI9CAdu8C=?55XI+9a&h=Q\%V*K/@iqq@6GHC%p>MmVh!VIEQYmBpCyuu?Hm!!Y&9u>?e
:@Bb?4 S*l@^c@uKqmw=G?W@ii\HD^j9GFne^%RLje+@bINeW5C#BWJ@/\L>+GY5<>+mj$@1nH?iR*hDTVCY+6h
e%ERAD TTmGdXn=9@h#J\#hFC<KhG>F5@<9@Y?Y#\*?lYj*PZNGKHGAH1:96=C:=6*&98nY4Rp9@D?LT:T&@AiN
QBGGec R55>Vp/plm%Q*ia<mh8eFZI=*N?Bein!@!I&^+Q=VHA=J\^dqbV:uiXiC6*nhJVZl=hZ<9*qQth?\ZTD
VLZ%=K <k9+Z@ch1We%i>4mJX>eVkGLw=d*c9u@FP9\q@8heQaJ=kLjA=DAHh*AHpyd:uMG6ajj//qiK8DB8P@N
dZVlM$ <CBhPe>D^GABbddiVj@h#LXpTawn\h=yPS%AuCnQw<6\Hy$IJITE>MSP+?d/AJFb$>Y4tu^Xn\\TAlDC
&@1E?G #e*hnH^?yh:up?N&#uaR/i9y5?nX8/49QICHc+4AQ8k:CXd!@KcRYZYhwiIn%AHDTB@NuLt#X@YeB#yX
PnbWVA kF<6HAkq/uJelVVE4K#==4Nwp/DyQ*hNMXle?p:kI6jP1y+#8DMhqDhDnI<DBYMmh@K1u9Qamcu^<cjB
GJwl8# H6^*+9=j$y5Y!eVLb%H<FeG4Wt/68p?@tJ#yP=8?$^I8wnLR>J^$ARJyayIlc$qVR=5e\em1uyM!Ak<C
I#JHi5 k:RFBLdFj=G<WWLHV=>FCMMCKWjXiZ1*9I%ewN?e#Q!CSte\elBF#$u=S#Bj\/LSD=XyiCZkw+H?5?p=
dwiBD8 >=ZTH\DNKh^4bQ$4^@@%6b/4SA>=/n+LF5Dp>Mdyhy*uZQ\JVh>JE#Ah5<*+DNpu&uce=6F/A4\Rp:W#
YKX%I! %1N<k*pM?GMcPWjG^Kb*Fau?$V*dR?L!NR%?+1ic>b?iA\h+:CB!C>lXD<u4?DPiY^1=&Tk<RPmtHYKa
LWln+H iV<cAYt+uy$%ncyV6B+=4b?=mqL#XccFBSdc>@Z/jRp:q#?ll<?hey*ReNKD$Ta86HQ$AEq$Bi/MLZpZ
CyF1^% J*w1XbPEKHLcXn@!QSL*M6TnTuZ=E?+X%&e4=N++mp$ti9R/K6hLi%e6=Qn4T6!DDjEX@XRi@DRcQQm5
&R/#5Q ?:bb=YNZ9i&uPy^#9iH%l+@j*CEWK9In1@Aj@kX@@NmaP^:^9:eun#9Pje>WM8yCnJYX^SP/mNtFyq%=
E\uJ^S /DcQ8+:#G@>4V4!&ui@PEqe4n1n58Q$^CIq@b6FQ&<uZcpVHM>y%e@G1G%//#/yQa1>W4c4h44@XKTAa
!=CE*! iHM=$LFGQwl^LeL9mnjqJ?*!9aC*E4+SA5SDnJPI1#\<wSME*$&*&ZTe^CQw!cc#P&hIVKJ=TYhjM6V6
1THmWF @A:h!\A<CMbt4kE^EiQ?i&pu<jut<lNbn$mZBXcJd+d/DZ\PPn>tqI$@ucuwPcPh$J<Q$=DQ%=:D1dNA
/NnuDK \/#yYdVP$EEk@+hi9SFYGLlwt?DRe!RmWiijm*dSTXH\1L4PwPh$Ew&Cem*^<Zh8$#hhJ&V%KEt/hh&$
%?d@:1 yQn4$DaF#qb>y/eVS/<a!A#hBl1B+IEbmlYwMI185cXl&R/#Z4c8?+^/SB$=\F>CkPy*>1Q6B&6I/S!k
Ii\>$p NW&Ep*RT$5^#&QNiiX:Sh#4PFMB@Il?j?&Ib?96!jMI<WQeip/BDJW^p*Tj$u5Tc!4kVL+%CEW+jy>yP
RiWj:P *#Tq5a=*MtKclWE?IuFn1::VP*6akp@Z4=>tCZlQyaPl/WD:e=nYk@YjM9Gb$@&L$GpiK@HJ!Ya>8%YI
BGM#n1 %VhNy%mkFVXS//ACd1qiKEikw/$u?u6<5&u/<9mn@^lByLth8jH%E#^M$DZ&PCSHPdJPYWKQTihCiSp>
YEVdRa B*GnhG>WqQ+6A@R8/T%*<#+yVhVBnw6cchVXMCk^Lh/?DV%5G9w\i4Bw@/ZWQ$:Rjn\pCC9E<Hu?SVZe
p=^^iM &ka5J<!q@qN$uQjQwZ^tnIGGALKB<n9?iX/Z!@yR6#tcwJRt@ILu9+p%?SQZ8b:>9waCqba&QYlw?6Ic
*<Kk?l yn*:Lqm?&Z+Q^a6S%98/9u>BT!B<d!9GH@66>#J<?MFiiMu+il&&>:Bc:9@+@eKLB$H#@dDl?Q</@y*:
Y+i^b+ *jy#6+LD\@eiu9/Gm<?FS:ukLu<M+d:5eM@:%jyq<:AZR$V6aDuj@SGF>>&ME6*9>/H#hN^&L\qA=+Z?
\lT1C5 tmMjQk88^<hL><t@\KehwqLIFC>@SNh%%u+j@j$^Z8X!mZ1F%tK?ZjiDBN=<FmE6K*mi4QyPMa:4ePLc
1MSuZE JD*IKe#XH>H$uPm/ej<L<YIRkjmj$%>#dD^Q4WRdcaN6iI5kKV+Mp=T$*@1m8QEi%Q^??m!TNM\9t4+V
iTAZAj WbNLSTjlIlS\^Njkn:n4P1E9Sy^DZ+6RDyKHnu>/wATe<AH>w%u!<5A?BC*?wDn@/dM\5=tpNZ9ZiSL?
t?Ll<^ SkJD?p:wP+GHAVG//VulHWBd$?m5%4j$&F=BF%Q%uMA^+H&iCcDah1AhH*?&a:I/j9w5hLJ!5bR1&Luw
JqZSj1 P#Yh^$V<6Pw:WeW4*%H$uLReCBaeZWyRmtCh6l<ZH>4%1\&HBu>@V+nCGX+F%Pi%$RutjY$jQk5#H*K%
1:aMP5 NM=K#<B^nCiadNN*+u+A\ZQT18w<ub&FV^4YNBF+@M>4@LqVmPNdw$</em#\h/mX/DhSN#X4:hPF6%:K
^N9\F6 *WKA\#yRt6d\R<mNiP&b+$L<5@wnI6&Dw8<<mVK8*lHdP5d/h/=5q9!DE#</JAblZik<E6#6+hkt\u&c
TK&98H y@BbaIIW9KZ=Fm#\t*nu!Q:Emu<W@I8?e^/ZBZ%9#Q<Bib%Ej5j9hXlYA5^6qE/@8e/^5L/VHml/Vl^6
4bWS>Z L?a9R&unBJZu5hJN&=hBJiDp^D/LBZkLHqppIWXXh?Ej>#?/Q/Ll+FGZ@Qi!98dAq>/\aTSKn1G1>lu%
P=yZ4e iN9!9?H6ZY@w:*la>b$h#lyh1e9k?>>4@e5>*&#mT6*Mh^Xn<!/Y@?E1A#@jX9Jb@\5j9Cb<GPdCB$+<
AX=&qn mMChFu&<R?XdN?/QHj<J^J@q#n6m@Tm?1S9/##@<a:W=QGR1Hd@/M4RCSQ6ewM6%a?Qn@T?^dZ=<>$8G
Dmc#RR u*1j@uy@!%%*E!6YWiyjjTbqF%CB+I9PJh#5N@ReeQ>R1FbkL*/S5PJ%E/E:bh9>/X*c\mQ=STJwYDXj
qSW%#d ky^YJMlie>5QjbqqAk<$EwWe/PWY4EiEBy@nPmp>^:5i8M=DAjw9tYu1b@$F8S<@KKnn6n\!S9c%8D#@
9b1W/d #Z%EDX<YEc:1V/BpQpA4/HeRJ&RHG<InBZdHu%pHT58m\/B<>IT@m*lD#GtkA@1\J<H6V:A5NpkCX$QX
lT:kp= %^+C:uu8D!tL8AS&yDn\X%<CS$X?PDt8W*^d9!CZITkF#8*uSp\CAdQ\P9RFWjAE9#etZkWj4t@lp%nR
QD/?D4 V/X\J#F\BL^9Rt$c9<%+86:G/*1jdC<YS:1PE*E+E99VEPLdJCCIQGmaJa:naPmK5ItNE?59KF#4iB9@
W>KZ#p 8l!?6l^e#?MJ\eQ\^Y<iMwn4#Tjwe6FXaZy^m8Ghq5#4hMKjA@Ec>PpIMDX$tRliy+aj>N#NmZVJe6:l
CQPtA: &R?P<c%LNW6NE%T5<mTmDEAcV8GK+tw6:?hS6QSP<jdPP8/#EtHM+JM5GIGi%SD*bd=+<6IJu=Y8??NE
*jleZZ Kc?b:c*!%8wp>H!5w\%8&>T&wW1Np+Ci&IBKk&i91Q8Gdbnaq$>$Fu*#R=<uaJWiADpB*9YE??klQNM\
:*BF=K yFNTN\!E$+L*^?61X6!QG:?yT=1AV9Z<%VtijyD=DPD*<PtLYQNkuHlYy8k@:i!KL*:uQ@lhKc=jwnCM
=Z^l8? N1I1u<9?TElu>?!\>jJm$e<h6T%WAkAh4?mdt\?9TF#=hJ@/#$>kcE#8?9m^@V<JG+<iN&@^/tcwhw@q
*FX@d* >$n8Q&1W#XDw@tZ@<tQ@Q*d<Z/:\Q@bb\&<KQZ<qI@*q/8?<9E\Iqpq%^Yu4D@:8+b85>KPe:Qd9FwQH
=^6H?G dcDDw5WQQYdSqaN8e5IZ+4N9GhPM?tTy5*#:Wn@w@K\@<@%mpjqVj@qcd^6T*LPIi</5$<L9V/IMtZ*d
XA8X+* p>TLnVjlyEK@L^+u\<$u4\eP:w!DbV^dZI+kMLiJl^h$mHBJldM\%6D*8tHTGy&%9C$W/A/*KQ?/%e>c
V8EJjj kR%!k%D$Q@\kN#$:Vp@EK@/#*l#^d#<@Z@%Z=nF#bI4D!&9+tpVa%bG$*9CcL5Q=9$qtaN%ycH4cWte5
>FBB>5 >eWn1P%RC9j6aB%61#j%@L*=c*HZH9/B119e4IPlJP@#aT%cTP6@&M<k=HDCD^cZBbmF%&>>HJ@4m\Tn
FERS%t EuGd$QM>T6c=<HSq@C&/q/yn*5%>Bnk8*NJwt5pPNBGCHmpDwyVL4EuklM:S#NBB$eSB@!i/Ai$8VD?D
W>c<+d kjhe9KWJ8!%@Db59@5bTbk^hlul:eNy=*+:QE#ZQ4#R5Gj/:XiL+cXujI<GQ<WZ*9J@cRIie>b9%LHDW
Z8<$Cw a?AyMRK4<YpbbQKZV9PZ<wYw#65A+Qy^RbTMmbM!^$mAt=AIwTyCn:Dqdnn<m5Z9SL5969TdpaL=P5*k
q=%YYn L%$h/$PQ*j?QPMXIc8K*8PD=?ad1#Y=5DA^BRIAV1^*mKmR&uMiLZ%A96&W/PS>@V?1BS9pij>CuH$*&
TuqcSY *kDPF#q/F*K+b:#p=<%j*V^@@G=<jmyIP8@18py@>d%8K1B9d#6=9FjpPQ+NPl#@BXBLA\RWAAIACAAh
y$GAGh Xt$q+!6>E6<EAABtEkAAI\AAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>\b*A8cYN9:be>cGNH
*dB4@d EMhHb+eumI%qaX\b#uEXN!G\SVAye4lIb:nG6d5qyV5>ePBibV?+JlA\dHhFEyIm#X%:leCRI6:cdtI+
C:?wT+ eHHBE6mQRCI+!PR@P?>ViwJ#IJDC<#Sc#e#8#t<@@HbN%KFF&6#5pen9n+m?SLt=GW#/5W9$!RJS4/j^
!P=aBm n#6EF^?K4jG9QmD/i\q?cRN>AyZ?SJJHNEiT<KEp$WIi@BkPl!nF\?FD#F4II!:=tyEw4TVak%Jm6hPV
+VuQ$k Rb\PWBS&C95ESY+@R*B!kmK*B:DnE^S^i*>Vhy=:Kl/Z?VRaF@tCkCnQ6&BE84A%*<4upE?DHj44^lT>
WTFih% MyY>euS$%B:ZjFXe<%X^#Xh44#btqj?I!9=WByZh:R:\kS*4@Jb&Y6my&5X/HFIcmS$Np8D+K$*CjEVc
STBkuD jcSVBF9D=Z^%mS4#&:y#:qDlQ9wGPu\QjVQdhkZ/GQwF>BtW:/nD#Z&8!Mum@jj=<Lel*j*/A!$8LtIG
PJ@5K: 8:T$6ET41/8$94=PG^5d6LY%Sh9d&:T@9$>:i*8$8:6LP#5:qH#N>QRy$:h$RV#&>M9FLX&<jW9j@QR#
GyM>e9 MlmwlV1wX>Qk!<Bu+DQma/%m+dj+aiG*<F9Ybk=?B:?D+iB*HLwmD:?H*<Q9+jD!B\tdadQZXPG^WAeX
a>hlTh H&6/jBp\GDAaMBk\BCR\GDAaMBk\GDAEVDAaMBk\GDAaMAS$MBk\GDAaMBk\GIaQHAaeSnn\nknDC!V!
S%E&a= PKmH5k+bLBdJLSJbhG4BE1aBRa5jFm\YLGFc\GHBaeFlujlay\weFk\YDBaMMuWYHBaMFk\?9LG<VmH!
-AY6<E 000a87d297a00110334 Page 248 of binaries2.zip
E:^t5E /PQ#/VYB!Bt^Ycec8S&aHJI/JHBke5n6EHVw^Duym*W=Rt:+ph<l9$N?YTKH@E:<aHBkeM^l&ZRqdMk8
wTE^8@ bLK<Hk\i?V#aQDk<<wYqFR:MkRiHF\+MLC\*Gut\iLB+RHkpDF5ALB+NQTy=PD^abF6+aeGciLB+ta@A
W&YNem I46BX5GF4eSkaDA\GBkMDIc\ueDk\eBkaDB+MIR6BkaGA+PB\eBkRNhR?MHAaGA\5Ji#Au&kM$bDSmX4
@Te@/: ba&\nuKilL/qn1YQ/H5/PDkkiheeH^@V/ipyub?j$<8ZL?u!<yK841:w?91cdt=8KM5!tp\thQiP/d5Z
PECeXq L@:FPhX&hI%dya^uWb5$+8Q?PQl1STQi%$m>cMR#H9inb6GI*&clad&+B>?WVMiu^y?%nK@id#a>94J>
M*\C@/ Eb<cZ!unQN+a*$IqwRLmnjGhjbdL\qaSd@CNwyH$Mnh?h9duP<l>&njGl@buW?$d+&6y*^ljT@:t?HJB
l:n/^i Bayc?Pwd6V$?pu:%P+<*>?>MjN\Z1ehS8^cjTT8XSqT8Q$Y*6*W<npbqPMSj9//H5\1?mDeGN:P@1Du&
K@9GNk 1h&dbjVi<u?+y@V!8$y^H^@Tj*kjn@ILiDRb+Mt9edH/<+6qh=CG!$BZ+5?Q=BJKqD+*wV\TP<*4ViRK
q>RlPI TuG5hu!wGiLDSQ5>4NIPP:Pc#NG!D9/jGYJ4DXj$@=b1u9R?>/V#eJ>:8M<>*Pei:uQ#:uN4+jLS^?pX
5JXXp4 qNdk\NpdScwlZq%/^9ZLTt+9=^IPSdH%ImI&T:!H\^5H>*JS9#iKeGGy:PW148&Z%@y=j/E>>bcnCD4P
Y8ydG* <kP=J!J&MRcyLahieiaXl>!eN%<uj@XJ8cBKe:TIJ*nHJunHJw?J@kFRT\MEFAACAAkAHXb6Jdm!jwa:
RX8hJ5 BRAAblIAACMAAABndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9eGh!Ltqnd?&ZQYknS^VHu$/KJdDB
Z*=#D< pkX&BGdnYE&5IplMIDa8euGS#uCNc%<%yLnmCwFWBK^\aG$bCBlG%SXJTI1A5W5*1qLEW>6NDAEZF+^A
%@@PSe e4WCR!d@N:Nc:e44pL5RTPGSbpj99bq=9@u\9timDPXwdc%IZQ=+R9RF&4W%K>KQBcKQ5$VFw4N@qCG/
HQyi*& tGjb&d><n?nQBil=DPyVXJ/QT?eJQXA/>p8hnt9+k^@>jl<6c+#>pnG8+R?4?HG9=Q%yaZt^FbY&p>9h
GHbtZW X58H%A%q*&?%@T/cWDb?/&DeSSQKB?k@d1Fyy<=uZAqCiiI@mQ!=9pG:t=Rnj/Ee?b5@P#:L6+QI*<5#
d8J%p1 Pwa>uE@K8ij6@FTii#/Z/hBWypJ>=jR$H@uLqCt#9b&Q@DZ<X@ZV$@4EZ:d^9q@j@mV!q&%5?mLD+>%<
1IIXJW YXHiLJbLK#G=ZG<I!G&*9/LSKAql%?NpWY:a>aVupSZmW!9uY=*Ei9MPh!y*puLBnR@*N#CyN&iEDZ@Z
k1K%>Z ?95D8umN&SbSQ$D>DQWA%a\wa=L**CF*et>@#@8@>Yu$/\?W!?YwWCnR\5ICqWwqYq=iy6ZXXXyjZ/iN
wldWRK nR*c&>8n*h%h&6ubwc&6Liy<binbM$Qj$kYbkcbjLwb$<iaNjjQV#*\YjF>RFcy&w5BDRCikE/\#4w5W
Y*6LuG jLXRwbjRT?PGKikX>A1Ckq+bP^Xy/DZ$GuwNlia@TMkG56HPqj%IXIZKP8Qe+!HAIMAk\CDAaJHAIMAk
AKu<YV \CDAIMBkMeEk\CDAIMAk\GDS\TDAIMAk\CDAIA^$+BDkEM!Bh+ShumZln$LX1Ma6GT\T#mWeTW\1\YK*
@:J9?W AWcJH^I5Em^&Y<Al\THBISZ4nN51eEk\TDBIMQDYTZBIMEk\cQ9G$t+L+eh>hLm>\lIy\dJ^Y\*jCp\K
L!!\dl VlWeKDAy?Fa\Kp!mFM>q*HFa*>DD9+J@Bj><SA4?Fi9BwMCknLHH=p=CY8>M^5i4\cDlV+NNk$QDu#%c
+>y666 =5AicHBw=5DC:HFnpAcLBw5GlIbDi\ZAwnFRw=PGRwPF4+XtFy!JBw9t@dA5jB9+FJT>TkaMBk\GDAaM
Lmp6qG Bk#&PwFBk<GA\aBBk<FiMVAaMBk\GDAaMGB1XPnBaMBk\GA$^\4MkepMBly$pyLQCPjI<eVP#Z$pjWnj
Bt@1?J $@:?Q8H6R+iHl*S$hEVu=?h$euJCq=iZhHX%ShjZ%*S#e$P*6:e$Hw>yhGjw8>i9*!FPybVlILXE>5w\
IEM#Db 4TV5k/YB%eYclH*JYiJN\q+^k/Xl5puak+whGG@ikt?t#Nyu%q>JYX><*p4K?yL&??6L&8?9n?=R<CB4
%y:l\R V%pj&+nN\*6<L%D\wF/Vltq&66EL<y1<%DR:WdNGZ1@Zc#aydZ&iX?Muh/CW>XY>b4Nb1%E+\i#/1qZQ
KV?X6W h1Bt5=hLYS@5NViBN@Gj+K6!l%4VI\<Viiq&:kEP@HL&^Q%%HV^a1>ZJ?ZGJ&ePlp@Pb?j8wX5PlpZ$a
^9yNKX BLH68*i?CKZ^*W&^^<$y>wS==9+PK^Z/^?Z@pKeW\%^qpw@*/V@M^@NlA4++S8+<htqe$Hb/dljun+<D
bF!&F5 64@MFALa=h^<pjXWL^&n#bd>?e@#QtXLj1aIi:d<hd$$l6^+qh$eeXdbYGtQPy^MtGA$hh9QQF\:5VbS
FGYi/K <j>MQ+?//Q=9ti/V!?iibl:#8eh<:nGji<#u@ncj+&k>eNXFC+Qk:Ywmip\m=nDKepI:y^b*^FE^nEdI
?=tR>D B\l&N==#C+S&m91V#SWt5k*i%M6^+F?!Mph^jMQ^dEj/+HpXF=ESb=EKXK8DTm#+&1khBn%Y&CmZ?8d:
iAFYhL 6?@b9\BRT\MEFAACAAkAHXb6JVX>pCJSBRAAblIAACWAAABndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!
X^jN55 bZM9eHJ&c*I8cYN9:be>cCNHFMijLkw4pEGYBW=EnPJaVh\Em!pTw!LGSV4DNc:hDctE#Rq&ERELAthB
m58dyL mk5EDPNKSSKTItD5FAa%1qLEW>6NDAEZF+^Ae4WCR!d@N:Nc4T#=8M5HyQC5S/Q**5!<**^w*#NSm6K$
DQ14/^ 9D^QZQ=+R9Rb&8XqK>IQGcKQ*mKcu*j&D%NEF%tYuj*#6+u?uIPi^/B8wQJ<ZJyQ/IHT6H@WdL1GH*#y
iaFdKH h46wYYQ5H^unGu=a^S>V^Y8NC<5=Q!/Bp+MD*&>BPwnpX55QYkhwI6t$@Q*lAbyI*pj@wa<ttDtjeTYM
lddq+L =JH@MQc*&?qpn+M\>8hun:NiEMd?@F&9/Rhl:M@ji=hkH@84XK64\Zm?b@uC/ZFC*16<XSYblL%RPN%I
^8>j9G ?N84FN=dT@w4=C9=&B>=j1XT!Mj?Yt8aIQ@^cQ=5=$9c*eZ*TM/b5&w&/$EP:Q:tZy^>$tw^9>99ZK6V
pILXiW :ZTPId9n!N%%4I<k>H\?TnLHd8>CL+kPdCR*KdG@RbmJJwm&%<!<PRPM@:j4:/nh/b1D@u*aQ$ZhS#WD
KY\SS/ TyuJi?/Rt?p*9?jh*:w$?QX:T1jVqMqpcG=8n9L=QC$8L6LT$lK64K#R/8w1dY>9$>dYFt%8d6L/?nw%
R$y9:Q 9#D$>Ktld?mCVE@VL^h>8un=p4:?<Th+EKkTXcF1J\y<CPkEhIJ%^uYS$E6<phBL/KX^\^V$CuwFRWG9
4+CVp< nJ&KNQRcik&>lpL#D^K!kY!$e&WjmcyRYYiei*\IMAk\CDAIMFkpMAk\CDAIMAk\YE\\CDAIMAk\CDBa
:hRYu9 hDAIMAk\CDAIMAkDHVkEPAS#+B%lq&hJ?FGwG6Y+JaNF\4tEI+qJJXn5N5Aw<WYCSaLFdk5+JDkpPKSm
EDVHlS uZFdBR+JBkpGCRdiPkpPCRaJBt*jYNy6Ij!+S$jdK!!SEm\d6>Z\4eCp+FVBkRKVkt<Fw<IpT9Fe^l&H
\hmi>y >R$>@C9+X@DQS/VkZ:EiDAwM!ll:dP+pyQZPbH!<Gk\c@nVaNDk$@NtnbR:5kRcHbk+5#B+*Btt\cLBw
wyjX5X RGk+6FeALBwDNVyyKDSa?Fywb5GbcLBw*k@L\4iBV$Hb1&VAaMBk\GDAaMBk4^MaNBkMGA\aNBn5FRPD
Y*<h8I AaMBk\GDARPtSwWiDAaMBk^Ge/#AHJnMaKBBJ!u=nHCPHE@5*N^H$kj$Hi*5:BDiQ9V<?ZM/QD!p<@N#
nNZ/nG Pnp=we9LT:1/81L4/&8/8dtl&>6dGk/HNLk#>G&:@Vjm%I#T:<$55d*au%Wt:L&Fu6Wqtku:k4Mpt\q:
WDyuFp $jRY?yQNlD$5&wHJ=k*+:yZ:>u94L<=aZ=@8WQCB#5Wb/:MhmGBt?@V/8AMh%cq9:hQ4R!tX/5#C>qu4
VEZCT$ K=iPnw:1hi6@Bq?=ZLIhZtG98\pi51ND@Tn>$Q4a#n*wwjY=D1ZTnQZ^16mPD8ZT>Q416jKwR:ueu?J9
TNKhcL NB4%M1dky>?j64jd:Wc6*CB?S9dp@Y*Z&ymkbp8$@:$FL4G>%tmWG:bE>wqjB/cHIX/H6jjD5Jj5RMq:
y^#8yk B*5t$=9<lh&*V=ku:!@dJ$jj8:*FI4%&?V@pKjNS4nLK^:9$H?dnZyTA=+dIuahwB=$5b*^im=wl&6!#
wNjZyu \1uH>4%<%S6c?ie%#klVFeH>M1KRj\j&8:NKli&D5&wu\*IuTk8Sak/cNn<MB&P**hV4%Ycmh9H@VNhD
YCm$Pt #du@Y<d:=QK=nhSnQ9ia##*te+@=*C9#Pa:YQXhh6DAI*1=G$aNVE=8bnLIh^F!d6EZS^/aGQE<5q%k&
hcj$Ry TZ8cI*@p5i\TkWm8&:nNkh?PS:T55YI$9p&I9l^Bw+memKbS?I!m:nnw8Tk*<<**V>?#j\FRT\MEFAAC
?4lZ*= AAkAHXb6JhwCS$a:BRAAblIAACWAAABndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9eHXmc*I8cYN9
lQkCRt :be>cCNHFMij#\w45EG&CwQAEMh1+maaynIye4lIb:nG6d5lqXAlpBABL^^akt5CAeN$KyKRFAHlNAa%
h#9Eh\ 1qLEW>6NDAEZF+^Ae8MXHGV!j&>&X:8TL6#qA%J+%4Pn>>:M9N><TP?bcIWK6LP#RX^?j$d$Ph1hHSHy
E%DWK5 ?!LSJ/6EG^9i@9EK$jWc!>:?^RhEj/^D#&NRu/Q!jF#Cb@TYE5wjlcF9?MGH+ZCIqnXP@5k=*@DDKu+6
9/>CAn qKA:K!!ZttqyiduXcVc:pD1^*P$&Y>$Ptql&*idy6IMtqp@Sj>yE$%w/u@Mqm8ZEj=V/<*&n^F<><HLm
u@+Ryj 4>l9Nkq!:I<8?<*/qFyS+w@6yW+^ta@6#iJyK4P>*yt$59dmcbD/I:XQueuM*>4qT=lu@kcD!@&RiYJ@
tPJm@F XHwVml#Q%\wlB$HmL+A>YP**?%FL>njkQm?^*5D9h%C1V%@>NBkMAu<eyV1=RS<jw1DJS$qSHSQ\@EE4
BhDH4l QnAm&a<kyN^?FiMJ+8%%T&@PBPQ@#jydyk:#6RVhl?n#Giwy1y9Rm59je+<eF6:@uk>@HhLpq??wWClR
4</<?^ 5Xmp>jX%&6#eyK&6Lh4i*1dh*X*c&>8n+?NnPnw/w5QDR#w+PKD\T$e9Znn/t1:JnT#>jD&t/>i9/c5j
&4Xu$Z j8TnS>YwB6X/WiGqwFQRKha=*$XD4@FBR/?l%<+QM>Ad/A$EA:%^MlXb/C*$FuwLliW9JGRH&Xu9Tl/N
!qEaq6 cqBb=:^:9BRaFBkWGBRaBApMCk\KDAwMCk!CCRaFBkWGBRaFBpEHk\KDAwMCk\KDe6CBR+FDMRh?I&S=
$*Y1b\ R5KQRdYw#m<bLB4PNS^yVK4BI65Aw<aHDSaNF6pYeGl\cHBw\#4u6\weGk\cDBwM9HWcHBwMGk^Yj4G5
&S48\+ *$L+<a?N6%eJpXE5P:@X<G*AbPDW\IEBp+F9A/QBJMd\ZM+jl@mGH9+N@B9+=!M!<G>aD\aDB8PeHJ5@
1HYZ/Z CT*ita!Q%+LB\y<Ft\YHlV<=Y8dAHql\YPdA\8T+MemC^aLFA5LCwX\B5FkM6PlpwdBk+Y6ltRXua5Fm
-AcM%i 00094eb90d000110334 Page 249 of binaries2.zip
=CH4n+ iV?ElY<Du+KS1?VA+MDk\PDA+MAk%\pMFk\PDA+MFk^!^eDk\PDA+MDk\ICyWcEHk\PDA+P#HC5\B!b#
c9+k@e GPnRTY5?I=\n^^Pbt@6w?wm?ybPVE@+%w4P#M#w@Q/i41!8/8Lmkt=5d84&>yd8:P:1@9/iHl\icV1e$
bq4EMN iiQwt%:9d<TyJYW<YqyTi&Y<4PV5w@JIhJptb!>:T:dJ&T68XB:ut=\>15nAdQMijHNq*n/*@51T>YZu
lRZP%u 4T!8D*Np:jQ4w%ydPpk*&PjYS&%9y<e!\%RY%yiPj!^H6MmZnB>VPZyeap@Gm*u<%9Hi9GS>XK%Y<jdt
%5cA#P Ji646^8%ctJiZF?dT\MhKNtj8jWS>Z46Gw%Ti=+9Kyiy%&:AVtM<<@dIn$hddSM@jB$#>#hK=tqWc%K\
FXN<H> BYW81S*u%/9X&8&1pGI4e6?P^>kBDPq^n/NwqPpRiaL$@BFKS@q9tL\!>y^=+Z=Sj9Ve:c%W/J*L@!FQ
nSDEHS &al#qTRjH>J@tI<HeRJitmJ*u9w$LyKMD/p^YtT6/AMS&Yw\bduipa^\9%kZ?!8puLB@P8mLQX!dlGGZ
m=F^#V <<6XTTeD/u9Iimtc#N\PX>/6luEXGj@QDJGFDp9?@=dbQ9q<:9uKW#:*qM<>=ZNQ?h^j=uMe4Wi??tnl
^/=c>6 EL^>#WYQVETN5^\9N!V&!#^^9JbekJL^dEh\y*S<qXMBT5jZGl^:JY5R1+SRD8b?jAMV>9BG@B:F<dau
btyh/+ uYkYu@*uVMDtKLj$q??j@5:?CXBLA\RWAAIACAAhXt$qLJ!pSJkFAABtEkAAI\AAAGN5cYX8hHM9eGh\
?ne#6Q L*hydnM!L%BHWHNnL*Jqe!>!dtR8cYN9:bi@m>^GFMjj?T=wIAh:q5AkMPT!Xh!pteyXnI6$Bni8*R$y
n4DtPb 6>MYAY*q*Y+DAeN$LyKRFGu<F&!XIy:/*MSkePFkBJIdT^DI!@i>$Y1%94Q#m$CKt:&*$u69=4&Qbta%
C@M++T :+kP/IlPV$>I&1>ZmD:H>jSWXj4iEH%/THS!E9&jHBChjTl/>H@^AhH9^:DLGMk6mMTV64lC:&kL@cQF
*Qm&Ae Iq:pk=9NbwP4YFn@mDqi=CMt?V4Z=18l!XB1m/H%?1ww=55Cq/nQX<6m6Tyw6a^/&T$LZqFli4*wm1Kp
81NFBF wt!TZV!CmS9XReENVPYKl@\JP9CmdLV@nCkybkZQYR%6WlVIZuD@NDJ&8T4K48Tb/DJ&mZT#CiJCB@ae
myN8SN 4N!6T>E^8yn4cA^9a9yPXb/6i=^PXY+q*GSi#uuNQC@nhE&c!Y#h4hE=ly?$/*cNEY&9W^!:=q+qL9BB
@$ip61 h8/jj:Ja!>lba?L<ItCZME>MQ>?VutZY4$inKMq/X5^Xd@Y:kL/k$j15b>G>$/P:=+q#h:+>S<K@IAup
KDNd/6 EHLRm>\jdmBIIw?XdKJMN8?P<SHpM$kJ+ih$ADup@Z%8+t+??99:jQQLly1j9/Pnw!M!^6D^<VFh9Z1X
b!#M+! 4q&:S6i9Z/jyhEw*d6!ki@j8$b$:h?n&:h6$<?bNYu#JhQe8$>h$Sq\F?8t5y4PZL?t4H*=EBk6^EA<J
ni+d*R WdZ+54Bb&K#aPHb^5D9ePNkh:I:nMA?:l>%D<dB:%qAWaA?\B>kDDEF?pNAbPwiaTn<P+mFm+=kiZ^aM
KIkTX/ Fk\YDBaMmkRGC\aLBk5GC\dFBIMFk\YDBaMFk/KD\aLBk5GC\aLBMt#k5PC\\wFN4+?uJQL^pADl?Mlk
u/VmYp eWn8pMkl1APLVkPeDnePLA+5Pm*kePB\+HBidB!uCl\PDA+MDk\!hR+eDk\PDEHjYCFPIjLEV?mu%!1S
Y!$^!/ 6/J#uG4p>tD!TP1S\IQJI:iH$!PI>^KL+*Jwd6mS*!P@S*=bIw@<Z8^k<GD\#Ly5eTYeble!Yh+AlwB<
8wh!cR AY\BHAH=hGtFA*MR\BGEA\?t!+%BAT\BLAERARq%C+AqaGBAy\BDAI65m!A5YJMAqmD#wT!!G&RX9G+q
mE+=pm BkPDkeHAaGA\/HaCR\ADk+HBEMCkY\\MDAaGA+PB\aDRENnB\GBkMHCR5\I^EI\^pNHJPXpn4KP<RnY&
9ky#Ek >HH$MZ%L>?@jJ*t@Q*n\kB+?jElQun!l^+<j$>PuV?ub5&j$+5WLi9Z1Fd%?@b1/41QtN/b9Hn*/B?jW
t4!GEt ?XbZF:dBu>eZ6V%@qXb1G%*&@Gu$^A8SZQd<PXhyHT@kMim\:&>#Hh@tiE?*J5<F?kI?<cwjQWd?dXP9
VJ*4$j ?NNMR4#>@PJGBA#Q!I\/=BJan\m$1jlNBSq/=HWMuG*D^&T$:dDNt:XXlW8iX=C<uR+Ba6+/c?QVtT*!
k^K9u# #6&tW:nd6NLwcbYdud>@hyNydm!/8Kc$>R>Qu<u<^wd5XPX:=^^#qk?*/FAQ/dqPc&:VuLN+81et>ln<
yWV6\! PW*bWMb=Jn*pV66&?qkHm+BBAqV=uy>GYjN5i#@cu^nT9wHp&mGL*6H/+\CmqF5lRDQ!G>nd9=ERQ#Tn
&1H4DM %Nkc1VR/D<AaZiZ%Y:?QuHk:l\b=+c@dhlS?QKBY9#HXiQ#?:$d<Fd*ZZ?*u*&9%iP9?cj5@%Cpujc&!
X\k%N@ 4ee*>B@Y++qY+CD1WD>*WmaT6%LmJTZJNXpYbdKT<4dnB9+=K6\GhlVC4FjWuM&1L/>%@J4NTyM&Y4eT
n@!VcB GTuAWY/&w>J\e*C^LC/R\a@@b#aJbBL@d>uNW/#udl%e%uPZ>h^qQZhb#:&*uyN!1+wTn\6G1STqQ#:m
kT+NK: GdI4!XAt^Kw6cttLN$W8ejy1\?SPD5w+Z6#RZN+j8X4k1D@16ZpnJ:iVa*X$tA:nbW1ewA>Hen#j<>*^
eP@^Z: K1$cK4d6MZjlt?@j9tj@AFBLA\RWAAIACAAhXt$qw#h/<TkFAABtEkAAI\AAAGN5cYX8hHM9eGh\L*hy
?6C+=h dnM!L%BHWHNnL*Jqe!>#cGa8cYN9:be>cCNHFMij:^\ppGF6GR\C\#q!E#jlaJweKZK+TGi+^4Y:IbX\
X!lMPR abBRAqw\YN5=EDBMy!I=pmIkuCIBNcyT^FQdVR\BF^iMaG$CYaMlL@<*5=J&yVZp<kEyQK8u<Z69=4*j
IReNK5 jGluVLSAm:T^5W^Tju%C>DH1nR&u$6hqw9ijEm$9i@>:C$VuFhG>@=N*mQ=akq*/RF=CJJ/W<Ap>WEL*
FM#uaT wVD$qV#+a#kewlaL8\<^?$wiMeuZZCqF$!J/$J!Wq6hd*Ya#k6bN>Tl161I81qVu1Nt=//JK>R:c*#XS
i8uH>: 6R4n5T>J1w@#J=N<?%K%ppt?@h?Wi6=KJ9u&\<1u$Cj=>yQ99+M?!bj/y@G<j#d?YKhT&G!XJ9pwi8:%
ChmSy@ NF>qeBlS8VVN^#><EEYqcd=n$eN^9EwRDV+eDQynQRn8B#JK^Hj#G+VeS@Pt^Hh/lA!DQuT@HGq#/KYt
*BVmX# LCX^*<>hWt1qC#dYR<4Md!5yy\HT/iZCuZPD@9?&@AIb#p5A?#Q+Q+J$IH^DC=#j=^+=ZH#:jV:<iWk*
/Qbq6: Q:&t^eXFKyjL6LT$SC54K:T&6pd4/?6W4>hyc&8Lhuh*cYhul:c*6?uFm^eWj5d$/lZVF*SPQLL$+*qM
+Xeaqa =&@i$PjjjI5MC1IlBtK>19CqaFP\KdG^d/Jl%@lD\/=l%?!:GhkN:AcKkh&\C$WYhk8:lh*CaPWHCb&l
F\m*I# 5@Yy*KMlBmI&>8u^yeCk\KDAwMDkpMCk\KDAwMCk\PA\\cDAwMCk\KDA+NDBwMCk\KDAwMCkGDb\KHAw
!KL?PM +eA:\k*QpelnIBdCj5lk$Wm8pWkn1AcLt\a+Nj:RaNFkehMCDk$PDR=6^Mb?15Cl\cDBwMEkW/jBweGk
@:d#1^ \YDhG<9/KWRi@>l$iyWnMpy$>qPN*AbMBppNElk\GiR&eBwEMWbm5X<Pq^6&=DjId=Bjq5kk9^E:GA\a
%Ia5dD DLNdN4<T&tWZMqqiC\cLjBb5Fl\Y?h#TCkjt\ILDCkeG=yaduT^aLFk5IC\T8m$AFw8PFw$5DBa55m&5
iu<LIK 5GBNLFm5#Ihnph$k1&DeXtI\MBkaDA\GBwQdVtC\aGA\MBk5GN\YA\PDkeHAaGA\IDREhnA\GBkMdPY5
4V8FJZ RA\Ea*SpNNJc%kn4KPiJm!%6NL%LZ>Hi*l:l:WNHS$h$euJCb&huhHy/TleZF*S=iWqZX%h$jZ%N6:i*
KpBVQ: hHh*S#j*VF@&iu@nuCww<cm\VQ!%8Knp@KQ1!Np!Xe=j>b=5qjQZiFTN<%ZPu>Se^&#%Fu\#bha@M@=c
BI@b/J \jnmVPNc\jlm19%im=NS%juu^^jZX/84>dF@ju#=@kZn!@W9+59&L@DZcdYKh#uXm@\!4LyM@Gw>Llkj
mH95wQ HVR&Ki8jGX?:*V:a4I?1IQV?tjH%i4%&a:M8liKC<jWcQRSw8DLQ*+c@$Y=96q&b>@eRZ^#y<nl@h9@&
Fd:l/: G6KA$8ny?KSM@A$@Bljh?ZP@nu^$:+?VJD5<%&?!:?A9q$j=Z>m5Q?jP:%@^=*9Q:N=cnj=!?V@eW=dV
6^=YEe 8<4+Qn/p@?\?HqJL:5Bw#N%P6!M%mq\AaV?YP1HteR9%#YEyCFAHk>DFDm1Hk::V?^It/N>V&EFhwWE@
SIRYCY C4%b!u&yii!8Y<!hLQqCSy+?LJTS5ARJIM@<@!*VijL*8beLn@i=^@9e+**8<V:*$H%8%h%H1nn4uDkh
pKSN9J b&<ei@H/=NI#!q=&J41eh8tltF+GDnaJ%\t<B6Ln4h%8$AGi5W++4PXIuQ4><Xn%tu#RP9d>$hwh4yRi
GLAI%< !JuDhN#hH:4VM<<jek?<?j:li@bQWE5DBBRAAkAIAB%YdTWT6!5B<ARAAGaTAAAnAAAAa&^ybY=$e!>\
\<G%Pp b*A9h&q8M#I9WEhRe&M9etX#L*Nyb!=ya&@6q#%wI$eW^=>PC45RC>uB8DL++my8k5k$b//+\?A$^uCN
Jk<qK8 W=/:IcWlAltTR+KAV$%RIMa\4q^eRqKp<hXHXKYIy$lqy+nl\MWFY&AJBBIa<9J@M:94%XwTeW\/#?yy
4qtD+V >V=t*t@unZjGSDp1$MPH$!V64\hEu?I?Qi*%n*JEH?eJj1jTn!HSb\Z^i@*#>+n?upIejp9IW+mMJ/*?
FK*ln! kMc$896R9i=9e8FH1>ZCZT#5Q5V5d*KJTd=86H+%cX9pPmZ6Du1@t8mDJm+K1+t@$Sk$<?Y\h1$#l+*!
GQIwdQ !%l9wt8+@WXaT+$Zj9t+@DKqh&19Z+j%XQ:k/uE=4W8Ai#:8qQBhekFy*nkkwR?866*ehclDJdqZ1#ND
&A8TRF #^i<?GbI:=#<EejnKlEZ6!dNV&b??+%Gjaku1pim>/9D8l<8=e@Ed&Z$pT9uLcdmnlJA<yBeT9KSQS&*
ZlZcTF AHpC1WH+LiWkibb%Ql&6>Zmh6?l@ZPj>cGHHBSp$G?V8nTcS&J8en/a6@NwNWk19!p:9@IIF\mW19d<>
VCF86+ :jy*Z6VFZ>wPjuh/QN%lhE?V=!hILu156Ik6kGDq%Si!:+QRn%t+@V!%@t^S=:ej1FAwWBmGNDW%SVM#
85N!&? M#R*N$j#<@P$8LlIT$6L6LG^Ri94/:T!5pLL!<6W@+4y&VPt:?ma8G*y%?NLPu:*n4:>/YhpWBANMSD4
6p+6Yj XaW9Bb8CVatNjamGZiPHlq*D46q*M:Ad&A$WA:6lN^Sb&C*5FuaLk=YCRtjwdH$1h&tIkamNjZy<KVAw
$c!^cj MCk\KDA+JDAwMCk\KDAwMDlMMCk\KDAwMCk\PHR\KDAwMCk\KDAwlk$eCl^KPFB6>*mPSC+D5SD&n\\Y
bna\c= niRcmVRG%YB^$\Cu^k<NFk$YN!*k$PDR+NBGdP!uCl\cDBwMGk\!hSweGk\cDNc6iP8uEHu<bcQyXa:I
!EICy4 KNHbV#X!G#AbJDXIaMBppN9AcVCIMVIY?*K+*LAn9$F?k@^TIwQ<S8^kMGA\#K=59lLcbSe!Kc<Fk$W?
qP#4l6 C#aLDw6<44VCkVt\+LDCkRh#=WauC^aLFk5Im+S8CaDFw1NFpIZBkpYYlSWY%MTC^ey<PBbbDXIF+=aT
-Am5:G 0006f96fc6800110334 Page 250 of binaries2.zip
ZNh=/j k+HB\GBkMDAa*HICk\WDk+HBaMHkqlkaGA\MBkaDk\FDR&AHA+PB\eBY*nWaA+M^PnKC6Jacwa:!QuJn
!puSIc T+!tD?q:&6#eJL!IcGhul@d&>8nw/IkPD\@y=PTEVp>Q/i#5nM:Q#/ud:hJkMKDPFhP4k+Q@5J<udVc/
:<w4Z1 >+KSnYbujRV*SnZuh^F*<E<iQ>:\l5^BEQ9y&u>^ERqS5i$nl9^\\w$Q4c$S6aQSj4SmyXJbe\Ebj=T?
V1FJ<5 YNt9:H<mAeQ?8FFq@@u#S^I\&6?nA@aB:hH?JPCDMj+pIP%HEiNm*k!+Md?bkJ9#L\FBR8nG>\q/TR4W
A1RWbl aZYX^6cQ85E8X8#+?6Kd*h&#:QmS!AeBd+kt4w@^@H:>n9Zn$hyn=:@Z/&Z?Vt:/i>*8=TR@<?ZE@pQ8
bGiBiI Ej:L+j#bS4hwPD8XIQqYhI/Kjw66+X?K^AbS9%mCEYM<khRk*MJb4wY#ZI8C#HuPu%Pi=8:QKjjuqQ6#
$w1iSI !9$=bhI=JZW5!d\tI>*6/MXmTwiqmQ$>n4@\G@yc?nXLFa=&Quc:ni^%n>4y<dG*6Xi>Q+4w8y&K4>P:
aES^?d 4eu*y%/<WZJt>$n$>9B4jM!d:#d@D?ami?4@\Z<AWE5DBBRAAkAIAB%YdTXSYSq%5kpAAEAQAAA5AAAA
?kp&@\ a&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9etX#L*hyeGX#cYSqatF!MT=mdZC>q*6WFNeb\L>lqVXc5>bK
m?%QBE VDWKWn\1cp*T1D&6phX18n=IqbhSand6pbM$Q4A>I1pLP/8Tw+uN\@mwtnRRA$cZ/1wS5EYaJiI^%bla
WmITAm BdG5MG9nmRw8k:w\8LM#Z:<:8^mh>y#?%>q#:>\j*>\:h:::9bmbc4YAjp&uNydc/>R/1ZH$/:$GD+m$
85GHhT *k5S+d>e*#Q\V\&<#MD9GjmEkY<aiAlAQ>ja@j$&J:!%8j@?E4DCI*Qm$na8Hy*?bN1%Z/ScX$DMp8/&
MlilSI &4S@:n8dP9:D*hbh\BXBZ?8PQwPT*6<<<:tMi4D\1NJQ9?/XhEIKQuAhi\IiSE!!/c#IWY=i\:Gd%C8@
ZlSh^b XtIK$1:ied>/byt6#&>@%j!q/h1e6QK^:m*Dmm5EV%NDn$t6LJ6@cR+G&5SRTLtVbD/JB^ati:A4p%jd
JmZ8pV !>5YtGX5G@?1kFw=n+ITKnBj^Q4j#PMSBV+p&+Q:#hj^!J?V/FWZWD/w*G\k?h\b&eRBZ8Y#8+HpF%w9
A^?PYk E4j#&Km$VVC*a\M*l8&b=I:kC/d4YJhSVK#!wZLjuTL#N?l&i@At!dFd?jK\?VSmY!//MWV94L=*libn
tkLJ\% 1BkQaVh^ickjQa>lAi&/!yT&b<^NhC@Y*pWp8hL\MyNnmmbktLk>>EhhLtwiZa=*ny8aZND5GGd#k>hw
AS:/MV 9!VH/Q!&RcTQ4:EaW%DnR/mGy6H<dTTjHbhMj%H89E44j+ICHn&V\!5y!1*6NQ<$#cn9PejVnwJit4?J
mLqW1V YMEhjIm@h@WY?^:$/Q1l>dZH#Zhy@Cp:c<c*b?u!Z%K:!@dZ664MhLiN&mZmt<EQcV*W6lIH&jPNZ=D?
%mCF%B WB%C:Ga/DkcbZE$pYSp%Z#CBjW?u#aJ1J6PZj#:ny5S61L=Fhydh<d1yM*FkTbG6?9&<>L*q4*TYtu15
e5Vb@S AQ6La=KK6l@ME4*uPjya4G1J&6MZ+aj64&V5\\\bD>q4GF^kiaB9\F<M@uLb\H$M@KTBZ#V\bkMjM:D@
aPYqRC @?@@D%%YA/<\<C+D%^6+\j>kY?VYN?6<bLAtey85XpVDwN=#?i*T!\@\tCyi*j<he^?l%u#4AZt8KFX?
TVGRbw aQ%P41qL8@=Rey<HLBY^<65Z:4NFXnD\hQA?D<hXZi:Gh?:#XApq*<F^4ml#KAlm=hFGc!@#9K!&b\+8
V1MFam mdKyKiC5cuY:X>N+FnY#ykS\<yK5L&m<p4FIJmuqbG!u<b?wQcwmZ*%#mZ5jni8wyRkX9w=XbZMQ$dmN
R/*<8j &4MKijmXK:9HSe>upy^j1dZ9Lp6*SXKKk#\nhG#9+m\9\C9E9NkliSyVj#CcN4mX6mh1LS1YLZ+6l%Sa
G<npH* Vh54=FF5td<9<*umc?^#XFqS*A9uLKR#iJVp%cJk^@SDF*aiy$<u=15$ZJTS5QMAGjP9mSY5%4TL/iP!
/wu41h TINd/P^pm1!aMcFlc+N89&c?c/YeY4E6Lw9t6^J*mBniQZF\bmb>eD>kCRI4EmeuH%qCl@$Wedi91u*&
au9hp\ :M#=P<m=5kFGCJy/I/F@a@y!eyamkKEw!*9uyt&jiItMq*Sm1Y&X/mEt=>!WwP=@$&XBHH8$+jL9jIha
9?I9Cc T1ZV$>VTI8+uu1pFAPNJZY1iMt4/1dX8NRTRTjJ!qGb%>X5mL4<E+CS%w?^M6F@+hDutW8RAGKql<>@S
eI\:#t @=Ja1AFeAQm==HG8q$<6SX<qkEI1eYyKHJaWl=Atn/d=LY44!Xb*64%KBHminp5Y6Qjpiw4wRV*XV<X%
lH>dX& qS9Ej4=<RRDaC^D9Cb:N1D$@FS&$@qumhiZnddc?RphHN$AZ&d:mV65YN:nRIhD*^6N?9u*6+1/pGe5q
!p&DS^ >bd8L<N*dW&?c=9HK$w6\P?yc5mb9>Z&jy#E&<MAH>D:>u!eXJqWywwcQZ?KR6LV:5RJd*+1lKyJYSLN
F$j%HM L*WZHZVE=$p!/ih^p1iXqI#j$EXu&AM\p@Td?RkMeKIaYH6b>@e?tiQm$9JqVSCyb6qB==%^aNARVY\J
wWHW\L IBp+jXJMYW#M#HkN$WHB/mahke&&+G&yTqbc!CEGp:%pQ@ZGI<N=kWi!6&ppV=k=/Gk8BZ5j&Y5P&c9:
byAKZa RHL@&yCMA9G:^Gj/RI/>1cbGyjFjYe\+MQiNb!u/!tV9@!J?LMG&\!HpP#1m<ZD5*MEbhpq6JZZCFGy^
9B<A5\ uHXL6!\ltS@aYW#PGyw<mV/QPjmd#J?>:&Yk=A!\M8\#cnE@uLBnppNC9<pQX=l<\<\Dm1kI*lR@^DJP
BIkqN& i4#<JjSIL6+Lp^kujnKHq*kuTH=aDCNJmdbD&c&1c5a//$a\i$pn*?>YyM6t6HnJyM>D#MA<e4uPAYHB
&>Sd^I T!bHY9@HdDtA49ndQA5y\&uHm=eKNhcW#>E%#8!!iCF=H$wltLwJ#iukN@5lby=e5\#5qy/SBVA6qtL&
6&*4EM Hmh/\Su9#>5HFqPalb^Tm8$yhiJ=mL%KDPQI><Q&YQti**!9I^y4i/aQQQ/nJ#lX/PY\^b>1Yi?MFy4e
8Ad>!n +iMy44Y^6&ZJFe$>uXPk^BSGkdE##Qp:C?AMl#IXF!=a4uFZ@ejlLkkHlZMiQ?R8B:?@E$bRQyYK8*8A
N^KCE% S:n1>eN#WKkJLVWuwFCE8nw@4AbThBQjA$1l1/:PC*6kppMwd8?B*HdZnI%iPMu!:<HcMFTL4lu4ZSCA
*^jhPZ FDIMT5T$m^pdZVAWSwmCkAYAhBn4YZ/K^&@Gb>&A^k+Z6^HkNSk8p^tTCnk9EG<Hm?T*54SNdAKwkZnB
ZKXGE+ H$uDZ6kAeB*mtV!D=C+YQAdBa/!AKPCaQAdkb^DjR$ZAt6=W8I#p^BQ$%E\Q9R$y4JI9/E*XXhCZMc$H
l$ApZ6 Ca!951=w&A4+PENQaQ%bX>6>lbQ#D4QlM/!VJI$V96duL&XhX!nM8XY&Dt#T<$$^K%9$=+<\Dmk9ewGh
#85I5! 84^bq@McJ!1h9jWHq>%$k6Nc>ih@#P^dL6R+Z$T?mPWuFE>\k6nDiD&VN?XyZDi9=<N!J1>By+q9%8WN
6DcIuu LDtn4HGBGy&bn=qcey$tWhFLu#E5u#qW#XT>Wye9bHJjXY&5l44eRT&YE5TYLyt=G=T!>V\hRqP81L@9
J4W:&J K@c<15n$L+M?9$jju%BVXVFX=%GM1@MhqPFaPwX=nC8%d1pGP*94BbPpCL:eCy$@$6P>KG8lTMHAem/Z
$uk!=t K1@Mq$Sh9:h%jdYKZ+pFPk@Zp#!9Kw4mbeQb4K8YQlNEn?+F1%m*XlZ!Faj4j4%V&PTRFpt/n*#PP48m
LGY&c4 Ke/@/h#P8lTuJEkS4&Q9k/FNLS%cYPjV4H8$XtpJHIji@aIbC#G!9Wn>a/:Cqdu/htC8:yq4#+ySJ^$X
e4FD\y @ii\6nZC56:#NYypiVmu><MCWtiET!H!Aq>pPXkZeZYbj:kim??6A<ea/nQX\A$Ghl9abiBFBy=waJPB
lAu!j? t@?#j9+*WE5DBBRAAkAIAB%YdTXHp?C5GbaAALlSARA6AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9
8@ZMuP etX#L*hyeGX#cYSqatF!MnR8at%\:L%%ZJQ:@@>@DNkAFX95RPu8:tc\nSE4GJ$d*R$CTpyKw!Lh*b&C
?8:$*> KHb*Hw>^>QR:9:@Zha*acD%?ju?>h:8:&+S4hd<iQF>^9ZbN\/kD8?+H/CID@9GBj+Hk*&j\d>$QZD@M
R>L*jh Z4b#$Q@NZ8=FYN!N5LkVduEuDH<:FPJYKQ=tCPFtMPFGMPF/EPF/IPFcIGE/kDD6V=#&I%:%I%:^JW*=
?=6t&5 RF#&Jp%/RX#!JF@!II?:p<jeLWhyq1NW!^G1%dCd%dC4%bCL%cC#%cAVyh?J$8hI/ZP\:4Y*:kHaYjjc
G\a5PP YjjbY@e=WQwhKIMRXpPPX5PPXmNPX1MRqtQPqyeAL8RJF@KpC?t!K&pK+Ec/RmXNW+tAc%VmhS4lln9l
j*LQ\? J5^6h<IhD@\hV@^hV@\>L+9:ZlaQ9C\iiq5<<4b+:GMPiA4\NZ9tc@de#@TFu?qLQ>NZ@lB9AuCA6+G+
^pw8km H\NN*kYc@BSp<l+RdQI^GA9+FIL>PRV#PSV#JSV#C!AM<&5a?4h\>P@l/D<mnQ?E?T9C/B?SS9?MM9wZ
B:I>nX #L?nWQ?JS9$ZeBK/@uiW$ePV=k?m#S>EYh!H8Shy5eD<M61JRD9p*I<$BY8@:LPee/8SPiEAJ/8BPiEP
@ttenT pG%I8D$pHNkikG$Q\4cHuYcEA>9n<:dJp$!&TR65*\K&QYb5*%9K>lQI66qVTLZbC>n&K>n&/\DVJXX@
@<?:1? YL91!IY1@#84Gnl@Gtj/JM:5MTDY:HGM?cPV=w#tX>G?qHNIPJ##CT<!=J\^=M#CtSIPC+jmde<e:#ud
!PQbwS Vm9al4NNY<I&a:AjMAZdnB:5F\#Bj8*QyQ4h%/9?B:Q1@$VNS@yFkmukid#y5>MRV$?bQw$#i:JRP?\<
wW>CF* ClaiaZE:*PJ&GC\<FH<nlHA>tHA6CBaiTLkcAG\Vy@!Iq&iFV+CEi=HGQcGEn:ydn6CkpnLpbnZpC6pi
tl6#ld eJ/^*i6A/ZG\:4c*:4cD1p49dD$bkPQNIB\1J8M8bFk+ChkG^iR!dQ91nG*CNhn&nSud?N6\GdpL&:=Q
4?<GVb 6?%n@km&@eRZ68%uPqNG@PuB^4$JBLbNkP$jk/Bk@^RMdGMl&!HAN8du$BudZ&DX9+dD6mPMah6GnKpG
&iNI+5 =YK8i4^JNuthnH8XBQE!EeiwHZaPyj%SnNtnp&aQw<*9S=9hm#K@E&F?G^Btjm9M@Gcw?e$Rm?9BF6iC
#E$@p! <NeC<hPB?K9??C9??Cp@\yRQahKHMPFNuQAmnu5T^#&Ia^/pWSyylEwchmMQ8bIHZT$HuC*:uT#:AA/Y
%^SlYu QR=Y*ZaAT1e6yhPG$tXD/dcq>Nlb>hyb>hqb>66dDnlaDnyaDnqaDn8TS^#Jw$/pMTjT8BQ^pnN^\wW+
i\VEP^ /WK<:E1eemXeeTXeheNQW@HZ1Qn4XQ\NG9/t8<W6h+9dH8b*QM#9iynj<#T@:&Z&\M95wbjbI&>V\GMj
?kwbPY *BMj*FMj*DNj*HNj*A5@p=j?J1@<5c@>5Y<C5G<Bkhl*kSnAV$GaD$HwD<Hwn<HwV<Hwu$QRu$PMQ+ec
!/PJ?X @^y8>F8+$i@lSu?Ew!DXWZP1b/4H8#TVh/ptQ=+^iZ9G=E&K!d#&SN#LYiFQV8Ei^iIiunT=F+&:HYq!
d==:&u M>#pSynJ6XCVc!G+/SDe%YDeqTDeXCB8K5B$$6>$\5>5\6h5*Mh5*N65#N65%NN<^NN<&NNm!N%mEEC#
-A:GJd 0008edb670400110334 Page 251 of binaries2.zip
*IuVc> GKBc>L9l?%*\9T/EHthC6^P^!=HabW@5ANkT&&^J4VcpXt6TM+ZWdEX1wbBcKcR&c%IHBLHVl6lqT?!&
NmyL$/ JjdaEu46CQ*&iMAk\MFmCPBwMiJpMiypQ8bpQ8=5h5uFdMLFdNLF:LK4&bT4/SW*$/6W*DRXh+&K8$:D
Dn$TtG *ZDH*ZR*8iX8e65DC:nnmdu4mduumdu9mZuklZuwlZ:pnZ:5dj#E&@myn@E#H?Qu95a9jI$A4@^R4@$l
$!<y!Y *kICWD<GGL+LNQ\yCQW?&QBVmPGZWMNj\\^@l&!n/K4ypj/RmZtjkRZ<qI/FuKjNP*?hbAKEQ$<\iZIc
mD!tj* i#<Yi#5KQS%thDpENS=pPBykPP^uPP!LG9SFDjmkB4!N?kGiSu&iS4$iSn$$+&/ceSeN*WqFh:mlP%#S
=mm8lZ :T:whth$1^P/^SHV:IByA6lnG8!\Dddail8VPt8VYk18^kyZa+t4AyBMK$ttFRVVewJbtRXEBS=kYpp\
J94E>b 4TLk1wt+GmK8qwT4I?H1!TaNAE65w!Y&!SLVdIXy5eK$WnD6FHRH\B4hcaQ85pF*&/B:dNG>65b>h5d>
:%uHA6 >pcAAZ8nRRinIRjW5AN1^AE%/tk+=tk+:tRAtAA+G%^&$RhM8iyjhhWDVL9yVXQ%4qF%4%N%d>B$d>J$
TQ=i@Z d>F$d>N$:\Dehi?//>##%Hup4jQMS@iXu>/:RL%Q\Rc@lS9?GaH/b!TKH8tQb#GAD%paIB^!ukp:V<Q?
Kd=wD# tAy5a%<qa=<pwP@FGp%HGw+H/@Z=c4h=cDY/chT=1Ni+1Fe:1XW=1qe/1qe+cJVdc=VdcbVbcbdccydc
64*B/D cJbaR^SVNC>acX&\%DwQIG5XpdTKmN1FBP$Ckp+BZmjQRmjQZCeZaK1Vdc1dnhM>m>QL\8yqamA!$Q4y
Pa5apH ^9yyS9yyKQ%WFHRNTDjT##DT##VT!#LY!$L4bWQw=tB$e#E/iVD=YJ$CE=%CuE+SVl6\H1h>Ach%\XT4
5<bw<w &FV4wyqYmbqtmdqt1dqttdqtPeBC5^K9AcnG1%eV%G5I/4WE6VwAWc&i1NbAWt$pR#TSXb56XX6kYm%X
Q:imiq AP%Y!l$WmE/A6ZKQ6ZK9njKA9e1+w?wXX@W::l4QjdTB:X>CDj+IN@^uyCFwED@qaD=t\<DCQ&bB#6>u
Z6uCmh aN=qaN/tab+uGh?LR$&F/@Z/chdVXEweFQP6=dLIMtpE/VMY$mut$5qt$ppAW?qEAE+/\WRtHwCXQR*A
IR!>BS !J:C!MabR<Ra!RFPw8SPG5yFA\#pw9VqI9ZqI@Rk\uZq\*RW\4RXR4WkRnRXk#WXk#RWk>RXA>YXAqRl
$*M>9e @FWk/LeDXbYCXBYD%STD%SXD%BXD%SZCABwK+SwKES4!Eb4!pb4!WX4!$Xy!J&Fm6CFm6iZmhAC!y\G/
nTyiRd 59EAQhpEQhqEQSqApy=$5n=EC5\bA?qWR+BWt1FW81EpIAMqtYEptVXL64EEIAetF!%SkJW<b!Jbbm=h
4?F$CQ V=V66qcahFc>:/u=^q@*e+nBu?GG@++!@DpQ<*M8=lMACM?bER=W9<6E9#^nhQ?$\YTEVwiQYyt#\qqL
W@FB@F /Zk#5Wm$eLClaIC?kK?ikK?8kI?PwDhAY>ALwCZwChAW>NARekiwC>EAcpJWkK1\G$BF&BYkLP\CWBJ^
Ky>k&l XwS\WwB\qBh^pBh%pBP%B<mK&5tK&etI&WyD&EmJYRMp^TpACZF\\%yT#EbT#BakJYaHa!<q/mAN+Rkl
wY&iy5 +mRD+T\4+kLnKm95Kmj5BpPXE/dJA+VeaV\WID\XlL\AmwLiMD+AJWFjCAE@bRC@Q$!ACpRkVJAKZ=A1
VVy$J# Z:A1Z+k1j/kcj:k/j:Tt\Cph\XRDpWKMiB%Bb6Bi<VbN@bYj#yeR@Z>EGH:P^\B?B5\KB/y@Pw6?p&:$
M&m&8T MNFkKp1:\%jqkwN5CpE5HC*pw<hH%iS^Xn9l1H4eZ8Y+uVK*4jJ^Y!WIG+DmeY8A\kpKRQ/EFWAP\GMy
dNkdtI C$GY+TFL<=BtIW4^ECX=CJK<iIpbLMRBjPbmjPcmjGaR@Kam@KdC@DmAEL<JDFaR\pRR8w&DMaW^k?A#
!T!me5 F+c\AIn\+tEIwlBECB+TDFpM\lIk#tMFR\FIuLCG5aE+D4AFTB/*A$kh6=jmh1An#i$I+\VnQI84DLid
t\&n6\ LLi:HLiZ\9FAFb/Vt9#yl5IXFqL>6w1kl9#w4@N:tQ:uR9VuAkCGLl#!uIQ?Me9+iS41iy^PS\R&^5EI
ua:N<L w!dDh@Vkj1=hP#p*:>1/BdB#Mb#jDPjK:FmNuY6m!*ht!&c8Hh8Q:h54L<BDWJY^X^G%qVlmL*ZESicw
B&jG1e y#^*tB49GRMlwH4aZ9GSq<cuaN$9Sik9RDYhAmnXH*QSd:PMH1Sm<kNJuJ5aypL?h%u?\4ylA%qZ%Xd&
SDZb=q lK*EaTjyI^:!^<LWiVNS\k%EtT88K1@>6H<=l\dM&j/=AQ$?%@lqnnuXR86@>4:&ImQIc!9Hb!6^CKn&
1WL*5X X8TP%iK@aCI&aK9\$E9nq@NwCL41I8Db?KeCuD@F<H@T98$mL!^kI<6nJ*uaVjbwmP1JLJS\C%utJqZ%
#:&ZWB q@QG</yBuk8NB#JeF>^*\:y%*L6&cC9I/ct4/c1y/111RKnRWhaBKC9NwKSIS%6JRX6^Duq6BZp6P9J!
KXJ%YK Y9K!M<nJckJpbYCpASwAGcq=yAGT/qIT<$kC^AF1EkA^CHE^XZHSGeSEIETFATy#mAnSWSaYuEFIaA+q
*?JKn4 RZ+aQmYBPZmX?HpXAZ\<5=^R+KX#ZIGHD4e<D:ictKme6DV:yp$LhNtk6G#kTQ51eTjyChRRyC/:KQ>!
a<bK\e \ZlPNen#y%J4Wh+nnQeT*5eXm>J8D@X>PVH//hHDD@j894>:/@&ht#@h89H8^4Y*%/??ub=/e@Z!t!8V
E*:8Jc 4/e89b\ai#p??tJ5?Quw+QQlkciD@W<Hiy@$h#@8:Z#W$@Gw8@%Bb?8Dn8d:da**Yl48Nhjhdc!>$%B>
&Vh<eK y/:1Xp*F4i1!t%YqN!6LdyRZZ!5>j/&pcQym+hWLBXjP=W+X=p\XbE<XbE*qbWLpbq#PTb5+t#1itV!Y
wS4u:9 unmTGn?eetw+KZaw+iSkjQVA/emB8Im?&QC?p/G>$eE>pWE>EaHh+j/hwd/h\h+hkb:6Ai:6@4S&Q&14
TR*Tl= n&846$8Ly%P#l&P#8*$n%c:S%cdB&d4i!dLPpX^4V/1%JXdd+K86#c85VC56eSWpdAWSW&blZGcBKnW#
dL^R+C 1HMkV=hiGGy1^PQ^nMa+&Nke%eRhyR=:K^\:yeNjbma^:4nR<?X5b<c:CP:hW&=6Qyaae:?y:uX@>/8?
CtA958 4ye>HT?/Yy>*6n^4d*4c&9C+yi=^W?$n+K11bL4$@NZm\m9FBXjP=%$8!4qetD%beHamL@NTV91q:LT^
VIlLl% #JT^nPVS>KTS6IVlM/iHp8MGp&IHE&Q/V$j%u+wEYuwlLTHhWWHhERFh5JcPaP?8aP??ML?S/KDl/BD\
Gda4RI p=bA#^1cjdtnbbt%PZnnVdd+Fph!5#Pq\hpKcIGhYFSTVC8AE:JJGZCCN!+%S=YaGbdk>I8^85WauR5a
wi<Y/P 4R1eZmXY8<^I9STqXt1kY1KuhFFZ<cK&@AW68R5c$8jXyQJWJM+1mtdJC&jKCYZICGSI<cXJ<1cJH$<X
F6Zpm@ +#+ne8!M$JFp\WQJ@AiTiQihEVyeR<c?GP\q+AtM*l^S/w=Tl#\Xn5bw<SZnJEaeqBb+Q8YMa6\?TFN=
pSJ%y5 PC4wRX6Vi&=Y8JN>yLMDIMLJQ5LSL6#BN5#iJ5#PP5!PEtlJPwp%dA@$9HKlaPy<@tSS#tSl>pVB&W8\
tbW#E* =LG#1YNbb$a#ppjTp+bVIetD5PRBIDp?tm/==&SwD!R=8C5m5DMMp6\jGVl!K1InPmTd=8Snm5ayK$4^
cNe1Z& <l#b!:X#</c6dMk>HG\u64A4:>qPPH+\SEc+AKXST<LY&iKB/k1KYVtRVMKYEhCqFpaZ#R\9tlwW+@R9
lR/8&\ aHVPG&6X&^Gn#hAWEV+491PYAN+nqn!H!TePpW+eJB$@RD!&H*>$Z:n\5S^F$W#kYXa\R=wjpm#Bp!y?
eaaMGW +w\w=DqbGQKe^H<kpY>@@QE>eai&qy9whyWW5#EWEE$yaiDbR@=w6CdjiSQ^AZ9FBjZbWEFwdtNPJG8S
V*jmSA 8hF$eiGd5cF+Q??X/:@Ib4bTW+P4F+88ZC\C1m?j!/Zd9yTjhTp*a^#pGcnPVAG&l>MTl<@ED/YeA4cB
pLLli: /wGEp*&uw@4mIu1BdcA/M1n@bPnEtXQqwREEda*Di:uY4%?@<qP9??GH*c\d6dt&^<wIXiL$c/\61t\5
yA?Lum K1^MIhXEVCui8AT&DcqGc*eE?!nLTK@<iPSD8@LpBM<1mYWymGVApW/uS^4aFn8iIuw5BckYPy\peBDa
/H>pX1 VnnBFZ>5X@@ycHq=ldtH+Dt+#$H!pL9e5TkN9mLk&W/S5d<BBm!/C1J#G?>F5lck%G<*XL?>NJ\a/L@!
CPHtBc t^Zd81ueAnXhe8=1!VtR/58khMC1J?DTMb/VQ1ecyHwpNYEIqI+=%jHSjTDXRHXM&MTb$=$JMTSh:e$e
n1y@*@ Z>%%b%@*k>bP#qS=pY1<WbW%4J1MLRYyB14NWXC1MV1haZ+15nI4i:a<9Aj!4CKiSc<i5wLy$9^$%TDX
RTZaR@ 1cLeKcJH=%SD1V//5<GFa1CyMjeR9EeP&W5iy5phm\Ti5SL>6py#uie9ePhbS%=pdtM8BE8ikh1>q9wj
kMq+qd J$cTkqd*ZEE\9qb&ad45AlSy8IBA1pEBAbEGBRSP>VmwIR\FbPnMKclR\\WE&L/eqbJMhV/$h?@j/Xu6
lMP5EK &4ni<hm?EyS/FeYMMhWZkY4\B^:89:4uI%#=<pI=1yLb!4P1Rcyl%iq$%XCllqTuANWk$6!:Ri8ky/a/
bt4PCT u?jDB$HZnmy*LEKh4\A4$Y84QDMaLJkbDP4Im#J/LnDT8N@c<P:!YFJ\+C1i6&$GdjG%mw5AKNKkkBRZ
??m1WM Vy&nF^C+XnMYEFn%TCyeREC=ll4E&K6=GcDcd>m\<i>*apGl\i*lQK?6WAt4Ly<4IKd/*bGB1uK!K*8&
Jd8D&: P41*RFEpX$$/Y$WT1l=#6SwWELleR:Wc1AaFSPRw1NYJJ@dWP%w8<G\LQM5iC%ju#<hIhN8w$Ke%Q5Q#
uK4>jR TJ>!F*w8NNc/*>d$dtwmPTSw=det9u%#FhupiqZy6e4T/jLm1/Zu4$AFyQD!nP1eCebcjVaXKmAbwP<B
GtCJuK XCeMyy!/ty<b/Ym*d6&/:#lpRP@cepFZpc//DP=?kP4SE^Y<1tjK5Z&F!tK=G4I=RLY1=Fp+%bu$XMM%
c=P6HS bKcAmB$HLTNIhTL99kbuClleMH1&pVn5Kk6G*@^=cMqPc=YbTXF+Z9SDN4NuJE5lS96BS<9:K=QJweG4
JX4&&H i:dE*ck88%=hBmIN1khRDaI>hcF\4qtEcuX?%9mCbnE%+Yyi=qq@:+$dN*:*$Sqy**dRj=64FpH*A@Ri
JyJMQX XiZqX9HM9d>RSTJQW!=HZTbHVTwdhQQwBYVJbqHpYBL@j6D^b9S<+9BBc+pnLnLeIY4<PYnJhw41#QR?
M5JtFu @clKJpbdn5q#EXduaYj4?/8ZW%d*9KYcauc#68JGdRYWc1C/9Bn1WaMCAqK>ZLPapZ\J>K9##\1jPQF@
DkZ$tp MR4i6tF>qMBl$HBWYy8ZY=1A:nSwc6Zp=Xi?q@Z^A$X1W9ucCnP1XSqWL&wYRcTVBR+&86u1M*8tmB>^
KG=dT: q8EPXlM+c!#Xb1WKHcmCn%Y>l++Qayp>5^cb/D*5c96+:WyKYPnK4$%mB&i>Lj=ia<*hy6w:hbY*ctjH
%\^4D^ h<A=KCMq=$HLCFSjlt5%jjBCX**nR4/*JZGN*nc5Z:>4</cn?@h6*dd6l:WXGdp6dIZ1WmDTwICWE#F>
n6H4pk eiG1C16+68W=XK\yY/TuZKmnYKAqX/Alt/<8uc51qRN5K+qtKwk\Na5k$wKHt1u&?l41nJ/6^I<+!S\Q
-A8km> 0003405035400110334 Page 252 of binaries2.zip
nAteH+ WlZINJb16qS:P*ipG#:\1mZLqPh#PQ*HQS$jd$!jCR>d?dWJd>%WkNWd!n<:tH>&ICinQ#86@&^cV&yC
P:PJt1 b*VIcGLMhG:G>MWm1I#Aw=mbbnEujVI*a/Rk?<n?@c91A1Xdtj6IA6ckltw@YX^+d?LT&dSWjkGBXi@I
4V#Sb+ 6tF>KQ?lKmKtCk^l!Cd>y!QXX9G<Du>wV=w$j:K<TJK5WKKMaKIWj+IpZ^K\KmPR4!CT4!Tc4TlCH!yC
YTcV6D 6X1CB=VwbuhHjab?HjB5KZdERjy+kIykPp1/$XIhY4ASD@H<6Pt#W/bcMp^=Qt>t?Lm9/>P6/&em\%hJ
pQYLM= &4y%dB5*dGJD#wCE+GSuP:CJVbF4l=P+RCEBP^\dh8Xe*qS^\a#19M^dJWYuQcl4pY\4J>umdNWX+D+R
cyn6*K HV!SFHM6K?ZDRNidt>jXXXXY9d9Bd5+!NDRT4LR$Bd%HNRYFqdhuYjeDe9$/=Q4%<QWMuC\dn:EnNHb5
Qk9TZ9 hn/!J$Z<SJ/<MKkl\H!cFF?1/LEYV&h>VW%G#&T^w@bTJ@^WBFNS$9WpDYnSEeN!L$%t#^jMWW<Giu/?
>YjS*# e#M%K8J9qpw\mDDa6:PMkBuQTAI%BBw6Fy!>WZdiTG%%WVk^wSbHeti\>%B<hEXawLP8y1&C6K&<XDAb
MbLAqw V<Kb4Hy**p%I$Bt85TNYWe\HE&LWFBZ?=u9bl>lwj*Bu6lVjYRWSwBy$y%8>ZjT%tD\VSa@cTy*\XSbK
EwYKu% MbC6IY4enblb#ZWu*PJ&PF=DYw#JM>:+/YD9=:8*$1Im9$9DJMDGp1&6MHdt>BVwZb@Qud^aiPLI+bZ9
<Sh#cy 5y&DQe@M1MPQCy1\!=uJ!j+?Z@8pY%p&JE5LRLNMNunRX%j@&=:yk**>ub9QT9IA%YumJ%y>*A!aQSNE
\!56uM n6qIu9BYEp:Wq/$kcN/aY\kK4=HVpJ4*9JiN6bmAjndW@?Z?udVw!P@XB^BAdmk!%y#I#dlYet/kMHj#
pS5R#4 w9udBShhjy=tS#I$t^eZeTW:NV$<>K5QK1%dF!HCZY%qYtNHGE/PW%hT@F:9^ZRQb++Mj+aMj=59%WBd
J$uN!: m>G#lek^mkTQl/J\9J=e1aZ&#MJc*=tqu81TVJ+9E4HQS\c@QL!ZjnL/i++khuP&$i^9XbdWy/i\54K8
@*1dQt 9LGD6EmH8#$$*SRZeVW*LV*m1#&9Z:jPl?>\NRqd/$AGk@*9/Bt^jy*j5h$=5kIhAS/Muw<jPtkt#G$y
$j5*9: #p6VEIuVqd>k4pNj4p^u#J&5^8!=lG#!at#+q$eQ$tNPjpjQ8#i8T%iY8F/WW=YS8tG%+at#KG?:l?NR
clRDeV !1u?$%FkSJP^Yw8<bD6KE#^YR<dYPXtNyCYwK!q>^@em!<tSJZc5K<VHREid$dPyEDhJnNhNZnSGS/HI
eetl89 VIi?/y:PpI8X1kTV=%JL$=jnI:<?ibRSG@N>S^Dpk#9HVkdZF?S8bGFbiW84+\jc1LdD1jEk$6eK5nK?
SnQ&N/ wWXi6</Bi%<%\dni^Zw$QWqDYjp:9lHRd\#l=8wN>VZW$YH\jMlE/DlBqM>bXnSTY#Ejy>j9TF@5QdQA
IHnQcL ZqXeuME#w6VK:PYq$h?iQ5/Im%*=/Vc8Z\<1:TaPDydX9M*EaDP!%bHeXXGGaGNdiW9>Zb\NXnmR\\HR
P6@Kee uT9M#9mtuw<D@:EcI1dB%Ya5M%qDbSZQCBaY#m%dNt*i9GF6W\FYi:j&B*5d/8w!ipaLu4AR=ZiRER9V
<SIlWA XM4G/9jc#*^5wR??5eB#tdZ=1<u^*=<@#V\X6@J#Ti:u/ww@iY6waLm%JV+&h6i8ZT69#\&KQ$b:w1q?
HCWj>m M!ju!q5iS4LpcewPJy\ePuQ/?4uek8SEJJIN!e4KnpVMky\F\a/Awj<e95*GmpC\56JpSP66LB4edMEI
AhFV6C hFZQVk4T\%tyjWX=DieKub&eX4X68G9LWKkQTp?Q$dPS\AqVEZ+:cjEkhiX$nMER9Fy?DnYt8wEw6<G@
c@uZ6Y uy4++<Y##NPuXu+8cc/huZ/$X?Mnd/e8@jjh&@#5:JY*l!c*hbV8hLS\H#??ctDA$KDD\&EpQYp5M?ZB
yw:u*1 WQ>EW$N:ctJ:Tu^d<8uPqQniqQn&^Nm&yLmY?Jmt8Kmt&InGtQCGp&ENWTH%kMmR!kDQMl6<udNXI>Z8
jpk#LW Wuccl5w1QZauMj+GWM#6TRPSkV>NZTI!H&bhjFHh!VpR/tPp4#?jw5PHDQq=VIRE4KWp@NXWWw^Sa</Y
=tHY:H hMdl/\YiK?!Id/=i@9QXm<#+$!5@q>TiuY*i4p<Gil@*>:\aHdne%eHP#4=TW<mG!DNWi>DcmDJejc*I
>l/Diq AhaN!ZJCjiH?w^uJE:uyX\1#L&YhAiPh/h^$+DpR4b>9c6Dy/VRcE#ICal<jQSAZ$S<V&leX*Beb&B5S
FEHN<X $B*mA@1*Vb:PVVV:T:pbG15NIS%E?TyM>W55nM=n6Eimk?NDR%diZuuj:1HwECN>QWdQ?u!<GCFBK$pJ
t?EwZA Z#YXbJVlJQ\yD@wHQeC%?kLQ>8T*$%N@9ZtXqSm@mti8uS%?6Genk+C*+<M68Ye*d6m\\9aHPViD#9u#
mb8T?d #yca<DZ%H++kNy!YFi:#y+$t^w!puByLmd8TthThjEyYTBB1nH:+RZRLG%Zw?DtMh18ddZi\X%iaZ$iI
qqCh?* V%8kb/8@i/5j4eYZ&8#6&8V8PJGZ1cG18p1i^RX1<EdqJP^FM<QBRA>QMtGXF8VEpatpGBT#b#%iZ4Tk
?F#=V$ kJYElK?KelLKaH4&<$1A1%Rmp&h&SKWD?i*%1*?>jZ$&MYGX84FuS:iZ<<9B*1e>HbMXJZyK1+!=BHd9
\&nN>T 4LIq*K899DLRB$&?4YtTe=*B9l$S14Lu:WlFNChjC%Q8A\eYdLPHbd$P%@bIYbEKknFIiHi\h!h58\Yw
bha!ny >uF4>uCc#M@TZM&#5#BQLWc4mwB8e4E?=?X&hQ??qdjHm@Bj#Wlp4M?\b^:k&XJC*Ah+NnTa?=DnVjk#
4BL?u! Tl1TVJ/4uK^?9HH6H?@iup%KZKXLnGVX=#qty1G84!B*pG9Q16I$8I?$i#uj1Cy>j@McmWD+1kE9e5MG
YFbFXw qlZ@YMD9iNlb#a:8P/$tW$+!cjb!cR9\cQYq6um=VBbtc/16+yq@C+jGut$cS\<wCQB^d6/</p9!WJC<
&VA+>M uB1Qa1:QpGeBAdKE8Li!WwKBQ9$nnZM5>P^5@i:YnZ??j=ihuQ^>?<>8CqLDMcE*//1i>ZcP>*T9MhLj
a:HFcF eDHi6:QGE6eS:A%Wk$lQFiX111q>^<eHZbyWR+&^=LkFuuX=iI\F?C%uQV?kj+aS=4/ZlTcVb&T%1?%Q
$KH=kT h&:>/?Q::DMy*@G%:ht!/V#JbDIu@W=#@c*c!y>9*\n$<@8@pA^/\tHc!5%8Nl&l9t%BZ1BRZ#tj@*$>
qtm<jM K^<@YtF8PJ\aa&VAuGeipGj?tV#4/>M@H@wEB6#RqBSq>F#nb9j?:8%@j@1a<%$>Y+kJh98:*/!6lD#Z
M=&p?@ X>>9dZ^#?/aiR**:ZlhLcdEYb\ywED9D@NyByQ*h4^RZcK14j/@Hb>t+IhbR5\KuN=S\$5nAaIHu8V\u
H?KRm$ /85@l#<NT9>AKLnYpy4*9I<hYW8%j*@9#u>?@yTVi8b:9Vd8uh8LLW$ue#Q86VWB#*ecc+H\F+P>V&=e
I<SyNu p=PV?+/TDaX+/?!JHaGiZbGBuiH?\Hb:kMjXm$Xc*<?#taS\4TZ89LEt=Jtlk$4*nBER5JcW>AQ6wIEB
WPb#Dj @RQ:hF:/t&w^#D>Du6$hQ#/+@=<9u*QVW4@LC#8\qjMMXt<pQ9y8c!Q\jLiq+Y=#@i&GGqCwZ+$MQ4w&
$!GQjX @X%TnYVbTJES4*ekhRb=>b\M:a+M/wwI/A#*/\n!tm+>y/Yl<X*im>L^w&XpZJtFWbGl&uBT4DEK^iD=
T!8=kS 5D+9L$=I!E=KKplN>R#K<Ejwa?N$wE<$/#Dpta5hYRe<Q*4\*%>@!W%Q?@59VJB4h//=<ZB5&P*t8wjh
>/*1KR :jjdt!HX4a$k%djlXD@4/@4$>HFEYNmYLX8??Xu+8HdHw4R:*P&:\@&lFbI^aV%S\bD1<ADR^=588@D*
tD<1!t QaQiDpbM1M4c9JJ5Ww#VQ&iwD44$VJ+QHWL^<XtImLnI!WbwctRaG:&uj!y@Fw#e@Q\G/Q#ut8n>hQ9G
PZ#Rh? @@9#n:!M>L>#/PEA=^b:Pep/F=6L/au*&y5j>ZW>AJ+:Y?>*6ID@#1881*#R%9Vq+d&y+YF#M#Q&4%qm
S>Qid9 6*:hPy:hP>*XFP1eLL5DQHyn\@9nw?uLI*6n\41nwBYTZcF?%!58@l*QLB5*ml#aG&Gk&YCLB=JL#FHF
R!%!XH Ju4FGP*i8AkSiMR$+*u@jlNBRa1plLiT$mqhuX\5lu+1n#t!Zbt/5qbH8G=jLQ^@j@%%Lm>*\+d%dEkE
%EkSw= P^6!IelFIBB5LB8=6t!YPZKRKCWYa/^dD\aI/Rq*/15jk#w<&Q8w9?6lV\hR@cC4:S=RDSeR1Fa*%aFt
JIn/Mq Ehl?Q6n:/h:6/&Pn1WqJG841IN=L4lyh6?+H%w$dV8#bTbIYn<j1N:nb>wj=Db!PkqbIJ5XCm*=uX/LC
cFWXQ/ 1wP:\9%Bn>*a&BlKEaJ%YXkbRLB8aYe:6u8uBn?Qw+yetyqSnT$BTK+kt=RT$HVQndd+LJ4ViwaXc@1K
<JI$Ta CpR^WXe=8VBN>XTW+VqV*Gj+LAh#*E=\b^y>4Q@lnId<m</Y>$?j*J&/DHH=<y*JT:eu^t>hG45%Nuy4
j941ND bPVt!NCNwaEdk@*ZB@18>jiC/@HK$6dwpN/EtNGW8J6F&jh4!y@$h4/cGH5%iiuq?Ml#MDaj:u<&%Qh$
W95aw+ wGht1Z>*?$NwuZ@Lk@bt$Qi+B+R*%N^64AFq=QQ6G=<i*L5:ict>61akI!M8LNTLR1dm#cpt^y=/GmhN
!hqt?4 WIY&^Faj%=Gw\NH+1LG$lHFw*mN=ND%^NDWi@C$QJeWPJeaMJpRD?RN^+d*SIcD@jH8w9#$>8eLQw>Lj
dJnkce w>LQ9eKZX8=DLjh&K@N$KjN\L1E=qXAhL44bF:9cF49cqL4aXFQ6//q&dXVdV1y6p!P=%w+AXR\4cCq:
qVhCCC Ph/+\h1<NhlHSyCj$b5LB8M5K\51e+KBZl+YW&yl>m6$EkpG+pk/$mKMh>t%@khHEh:G<AAR^XhVq%>M
D$#*K4 ZHy?ci#b?Mm#$cGu\\NQB95jD@R?:P6?&A6H6K5XXAPR#PuKp8t1Mwmc<8tcm16XbXQqF!?ZuJ?<YDSS
CT5+&: ZDl^Qu@<ZP=+ae=aRjbwj6bId5bIh64\&hTl#DNDGetDcapD1jF>Kch/E&N:RCcVape!pm<ZuL%iWuT#
$Qub6c :Q^pX51q%Qml8LB&H>eYL>htH>htj@jtRM@tRK<tj@hGZ&1>6&8>q*Phl%M6#cGYckiGANW8NqZPqEyH
kGC=\S 1\y:ewW>1S:<HQ#ZBq<JLj+*1:DE\c99wBY<$Eyye<NmW*&R$k6a*jMa:ZQGtpWw>Z\D%V^h=S^6lY\6
!c<M6$ ?dMc5qu1$yt1Wyp1p9p+k=MEW>EVVFPP8:h9>#M\CFJZm>jZ!<cmL=1dXSH^j<Au/GDpZw4HEl*?hi5P
\RwFL8 :>y=@MB?:9*:n6Hb6*ii9X!Aw^B:nuL6kj+:>$P8*Wj&$Nq%bQe<+NEa&AG^E:AheGnHHN5PdRh5QdmN
4WHdc$ E%V+A=!dARi*dnt+qSQ<BQ\e@lZ<&/$#9#&\BYL@qp$#dPcab^QH9p*5?#na>4Il\NAA*IAAN>mSi?eA
:ejbln 9&JDeAGR4A!\eCHt&MnFC4EHbk5T5Z:SDEAApSCl1Ru/e1A5F%8aXSL\6YVmZ^FGm!u&y9#\9<5*Zanc
d/j/Ih &pqw+\\nw\KeTatFiTWSTCdXp$u@k5><5yAadLG*=j?pji*F&pA@D+<Hlw9N#T5I?GwT5e/TZG>J14ep
NA9/5t @!eKBjn*a1KN:5W:1+n\@5@iYm=H>?=Nh*RwI=NKCSaXSEINtXSHBwdJDXcYEJdptZN@LeM@V=9jP?YR
-AtpuR 00007b4b4fe00110334 Page 253 of binaries2.zip
&:ui\& :&KKE8jXEljRpSKtw@&XcC%Gekp$=^FlSGNJJEVWb^AG1DGnK5/ICECFEdEbqBekC1E$k!kh^TWRAekL
=mkI$B C<5eQ?=1cFDk/6Lk:ATmY&6J1kQyyWB8G!G5Gth8pQ<Nu=cKAbBp/H^4hQ+hVa@*#IuC@lpJuantH=Gw
FwEk1F 9!Ka?BQtD\b?n$D>FkGhtku\K+V^L?HGZ\Bl^y@D$ICjR!E?lcA@\u\I\d\Q\j\WDMC?C<L?CQMGEIl>
te1T\d HYn!K5DpbRD8SRD8PeAj>^Vkb@4E#@TSL<D5AeDH@L/Q?X%9mN9iF4i>LG=/+kE*QQHZQjDZQAnV:wT4
tkP<HX NPIXG9E!nVlJJW/+pT/=pedh!GP8=BFZ!&EZ!!Fu!$Fu1*=u1#+uT1<nyeiS$8XI/ZT\:4C*cdi*cRZa
4hc>Aa \hlc6\B54J66KQNaW=15Ke$W1!aI!!b41$aA@d?#19<SNZN!1nWCN9=4n5l=@wSk/4j<DwH?LRL>c\S$
&LpInA <nHAL?GaL?HR/ekAwK@?M<!uWP^HtA<lAPl<eV<Ft:\LN9pS=t$R:p$R:uWk\QRq#I5A$?j?y5@<#b:/
b*V*m5 tV*^M*@5b@:I#?KS4<WDH+9:Qld*jC#8?8D9i8N9i^EAN:$IN#\J%#&J%#!I$?/p1?/pK?/p!#RAiaJK
644H5^ 9pT%HKhcn4qbndlcndnRV/^HGZCt>D6d>#yb>#lbh#9chDuchD4a6n9a66uQMmQeywZ8jN/<NSDiak%y
MBmNy1 d:c&A4cdbqW*YXuTV*AHFQ$%k>EckLaEh@p#kwqb\?njaaDl*?B#8@$cnkH<EndDF+bl$e?lYMl#CMCE
L/FSYY LuuPM/R/CAh=DkTaA5?9AAGR=^j?b5@>#b:=AhZt5G1L^:+YD*$k%R<k%jl:*9k:ZkVALXn%VcDck*mh
<@*il+ RjWWWE$qV%KBde6LdyD1WXn%MGTdM8l5*i>p*ieE&*c$kY\:&HaA&@c#&NpA&&&&AP9YPY\kYt!YWp&^
Fd6VnZ wn9=a+abX*?8CHN@i<d1nNlb6$9wZe4\pyJuQAjlIM?\=Dh$!TDQK*n&ujF<H@b<F%b>t/:cE/Rc<u#N
F\Ek8t uWSZQRY4uwSXZ%ycNYY^cu1\b%XD\cdddtY&DdLh5mnaRMX9EQN?jw9+Gln9CI8F*DLwZhI\R+!bJM?H
mwj1WX PYmyMC@4&S^+jnRd/j9Mpd+>F?pF1tpA<511B=\l%Z%\DitBXEM%bM*Bb4LNKIVP4?Fj#RK^T?1hLemM
pGR<+M MX=G<q!a%?B=SnYD=\YSZq\>F1Tc5aCM\/wB\=B6!8A!NaRy&G8#QTjl!?\=M:?ELTF6nZ^bT8?e+TWq
d?j!+L j\n?C5?kQpP1@XiJ>A11F^TRtXyNt%WN&dbcM6lja*8JT9IJj98A#+9pMQtj*RWLahlk!d59NL!m=PW<
9n1P?Z M:cDm!K>X6WLcnY>YX\/&FRw&GP8c:ZNZEtY469$h@%y%5QQ1&qjP*PGq=T<S5>\P#kV/iXWL!kkhN5Q
Vhq$w/ tG9%55Fi%VbD6lhWE5c/QhMlYS#9YiEj+LeMk%*kuFH:&5$#/9$=qPuS=y=mTe@jyH1yY4%E5Fi^#bl6
n&qQi: ^pw!PXNJ=89&<9GGP>9LC/i@RjB?F\9@GL15<#ZCJHqJ#&6R9ZRBaR:&6>qt1CSMViV$4P$F<b:4p/\p
5mIQD^ uCHlnCYF<V*Tdc<1@NM*iX/pit&yZm4a!>liN66L%t%aPGG=iC>wKBeLZ!LleEtb/\w!%HDIPj%NLdc>
BP4!FY WQZ@qY&V=Y!9qt*tT4Kwdm<Z:&YEL=>\D>I!JYXlDX@5jK/MA?j9b6@PYqS@?u8X=P<Ij@hN\leu@MuT
M\dDLS CX?tyC\X<yt1<yZP/T>?Te<jX9T<qMt9cB?@S@XiW$qb$N>iR%Z=P8eM6aZJPd&&$D8Hw!=YK*liY#@p
H?6lP$ :*j@9pjubQqG<@WC=<5WqyX##qnM=&4L!6wZSH$%#>l9:tB@Yb/@%@jG4yD&4&w>9#u1T&ljLi&L/@NC
Z9adnJ !R5NL/<$:N8H:a5HtC8Ej<uMj&CiKqqebL/=1nQPC6K%4%^pqk#<R5uM=aLS<HJ8X^L+6!inF5?ejFt?
kQK::Q <m\6@@<H<<8Wh<dML^jn=R\9==dS&MKJ%4ZQ8C==4&?cG@#<njM1Ju?*!C<Vi?aaM^qiSi?TXtiN@e:M
V&p6B* k8MIc\d>^/KH?u*y@eK\I:=1i9a4=:XYG!8bLbnkt19&+JFZML^R::#dic9MMqe:InN@kG\i<MQj+T@V
a?bd9H ?TWE>VHR+GPk@1hkk$>B?1<>6Me^$y*1\8$1A5*!9QZT*NZml!6FDqaIHckWPqk4e4lSuL6Dl4>QSZ#M
NmiQ$b RPEcRj&=t@:KB*h?DX>%F/^y<9d4@b9PGX=RI4+51ktL*hLFLtN!=y8itIlmku=W>@h\%H5@*heiYt<<
:N8@8S 6X>TNi>cK$?b!w!myRaM^i9pidP+D!V5&^Y@b&je:l&SP:bGeG+P*:Iya9Ptp=8*Jt#btdy>*>p>*PiP
/k9wbH mycLKqVJ1NZIKVa4!QXyKW@mhJ/=4?H\beTmI$G4:aX9*kYLA:!EZmc*VC>?:8n6Ayq#^<j@6V^@l1M?
DKTFHd ?P8?eFP@RXce\EpQwTS/>eZ4FQn#?a?hPZ\\j9@i!G*dA#t&?HF5<tZu<GJnh$i\$Xnb\LWZK$eA/>aI
LMJk&I ^P=a6pPJY@nT8cV#iLRKSa\K^hAZ^NEXe4lcXdNGNcNPVc$^nQbVG5QPbZmh>AQKC++t#^/yZ*kwijGP
EY!T?I ?N1>MCh=*nB#iljuqpu5<pyuFwR\4Ad=d#TK99#y4*CDL$G/4>\%y5^q?\*FGyV=CkTPyl@hu*S\j>T8
^WM^=& 9aGei@$&e@q!:QJt&?1F*PTFbQhE545n&h\RdK/5$LW:ayMjapeaeu<5&@GELTJyZE1=9EduJMnF5uaq
*SP:Mp Ck=q!m=qKt+qTw/q!6bX11SGVZT@wj=%58E@+aWwhBd9>LqXE+!:a?:+@1J>5eRj^cw:k4FK#Lh4m>IL
PXL5iJ ut/B&+XYGZ#PjeZlQNH$d=a$@B!k<<SS=RbS9p>j4EKKP=6*d!LZ49C6uIH5uL=5uN:58:\*:jZe6M?V
Mue1AF a:eZ&*a9=Ga9JBStD#b&K9CMwH9i+wjaG++<H5e8qMRyudFZM+@Q=L\EyWVi1XTJY1:tXcHyZ/EhXKWd
B$Yc+C W1$jXKunYcZ6XK%FdNdYu#LXZuu>%Z<b%\nN:yhX><nmQ\*G9\9/9tBM<uKT=\P<!DD>K@d?5%n5wyhN
=^jS<@ Z<Z*S:nlT*i6RYQJipY?ZJ/Ded8&BY:m<EPCWwD$bGZ#SG#&a69l!dHZa>M?D\+8V@chZplP&DPHB^5H
VQY\IT FeEPi\db*8/HQB4PJlLHIb9M1bc=D=ZQS#k9aX<m=%ct=FG8=qPyFXmqG%ynEFq4jLIiE>6kEqPHDc5^
c$*Mc@ >KnTJ6h4/F+nG!:<w/M9^IL@%9/#PC%4&mpL>\nn!mKkdyHu?X4B$K:NT%:c<JJ/w=nYnNGj?8eAk*=D
FRVWW= !TKSa\u:hwh8&8!LAHwS:m\\4El*BIeHel5\:M/^H?DB95eV8e$V8etVnePhnRMahwEmDV#9>EQ!STDq
^1hjMk V4G4y&\%#Ny9WTBkh$GTYmLuZcdpX/EYYKWbY1$VWY5RZaiPdeChd4SIcmKtNBPVt5^nG:B?hRbYNS41
B#:hL4 Q\ca@GN^T^*J6Ql18bcFei?5ehe5:*ql8YB</9q9mw^i#9DC@j6:8PFNmt1dlpkt>::Idb!BdG!?4AlQ
/KIyCR Fqb*FqacBQAMaHNHe41#:*HuPADB#8XB>\#Xb*bRMX^apeA#DdHLF!ERkXR/#cF:by9J&aPWRpG*attj
%RTRVF WwZAeyYRC9Z\c1*wG6*aPwNV>in+Sq^mM#/qlb#YT5q55<q16<=wJee*aL$16hEN&9K4Lk1C9&QZtHF^
=^yikE ?JJ:b>Wh6G1iGV*@c#ZQe=Ibu?K*eMMuNM%SE>pLE5hQ:>5i^M:8l$AC!h/\b>w5:1\AJA&^&b%6q#9:
aZ6AA8 jl4HASw:F!kSHwlNHk!iZXnb1c!R=*DI5%:1h6Pe\:bFRl+ZbRJKFWQKXTM1NW>Y/=/8%W?1N$yy\Ka%
Wmth!Q tYY$EDLdLLQc4M>&&PX$P8b*P8Y*P&T&pE<&ay#L%XT9PT4@Fwbta8qlKjSX5QM5Guc69J8YckibI:%W
JZ#TRu *XnwtTHMC&wF8NeDB<$8dhE<@5PSP:j=I=E?4AkjYLIZK/5u/%!iYYp#unqw!P$$>4%W>9%Whm=\&^&a
ccVFc6 l#LMDnwd#m\Ib^a&K86PZ\TwG\4^HLyy&*G=l&*QC:tZTQ8ZKabW1EbYcedY/CZYwXL4MbqNynp6?Q^Y
GlW9h/ etE:ydDD61nVwdDL8cnL:X\*>Z!*Y%Gua$cnlW?yqq+#T84LmlPM9/#AuLy=q6lq<@$/^1b\!Wk9<9!j
/WDAjA yjK<\QPplW1XFHjcwX&luJ6<&bDiCMk\8QcCaAY1QibW5\IRNEkyJ=X66^9dZni&QXVkuHW#@EMw#E+5
BDAbeN CCeYNnjYHd+I*pmpRkKHZ5b&$@#D6leEcTXT98Z!\bW1+hYcMdX/CjYw%Ab5XyN=Zm9^ZJ6Xeah6TchD
w1n%A+ YbhVcdjL^Y=1eR?68NinyMinyMMqy=ERXKN9X1p8<hdj<BQ$Vd5L?Su?y8MX?E^u^buiV:NVuY81$16F
8Gd6e? ipHhGDFXLlI+E4PV$=?h#R5Jm$Y\R1yljKDd5/yuweGqk+4eRWWC!d8yCMm#P!9p&bZJM%<WWntb*VB4
<@?9jF G::kpH&^kEiylF?FdHCXWumNip!hVu!D+bptdFcLiX+d/Z\:ycVD44#L1c4dyd4H4c1HX6u4Z6duYh44
6Z*!48 Zhd4Zh46t6hGmY:G&6S1K6^$W9\Aj:Z^B@4E&8yk=@m+MnN#G6>j>TX#6RLBw?HdPD$STDeYXm4\Cc\m
aX^uTW Yd&S4D=IlC?T%Si/Abu*bFBNn#RXSB1=C@c<k<c/^b&XA@KMwH5Gn:dDn=Z@JEL6DD5ti=9X8WN8F@q>
JnV\hk !<YCK1ZD18YncqZn/4WTGk*PNGM!&<##&puukPhP!HN%6&6hD:Y?^:&?%/Pt#/8!#:8<#/i<#:8$^?Ne
dl%yN6 n*NcB>G4Zpi6H!@$W!D$$iCj9m9$TTVG$jiC99VKdiJ!1meJGpZC^<K&dkHiuDi!Aq!AckT4B?#bq\*l
V&WS9k !#dn&S9ByBy5V\Z:BWRcAWWchC%w4F6y4J8AjKkhlPw#p51!\=>XKAcluey8pdQN+j\l:%K?pHKS!E1J
SLNB9y tG1bW*XKmR$cKW%/cT*GYY&+9Hb<WahqechNYdhDha>4jT?61hin8e?#1h?:96?:86?u56?9wn?kcmCw
lKbKe6 b6D:jI?%j/&BTm8PD@V/b4+6jbajq&Z8A@LRXMb!#M&IM1yi1XtMYLFblG9%ZS86m/LeEV5+kVTunT\P
#Z^^*h G%keN:CAG</\cp?kq\*l\\bJ>ytLNNkFWL<P16JWBMINAWaq&&lI$A=!khJBlW5$NB=pRd1\5NFahkc!
ntp^q5 m5amDNM+KHp:cBePBbj!SyeLuc+WT/1YQqPupN/wq6Ypuh%mpN8GLtk*QhhBKP/$K88&4iy%486#c?4#
=$Y=kM cP*#c8**ci:*cin*1S9\4^$KdSmJcl8Ndl<P8NlN<c4Tp:9mwQa/\QRNk/mba\EB1\Q88BB@W@wM@^K1
1XT$Rk 9:K#N>e!99XGNekhn>&>#S&BhN:I+kl:B6mD/+$5L5ApEM8G<GID%/#i5G%9YLWHA8GPREC6IRJEtk&$
bNSkq% l8+k#<m>XMSP+JpKi*bnRdyCuueF5w4FIa*VN>ut:@T/eDm<nQhWlXB!qXlGnZS&uWJiw&yl5&bSm>/=
mc@lKm X5ML:bnmV4PTLqJ=N/Y/%/G?#/Y=n>dc:>uY:>$/+N5/+N<!FN\!E6p&F6M=F6e#E6*Y:=ZjdGFjwmN/
B:kuN< #WZuyh<!D9$lZ1&AH<SLB8aPy5#MRwh?XdCZ1Nnh?tJuD8@!atN#kmZVQh69&GkH&Mnm^ML1BqWQlCed
-AS48M 0000b5c8da600110334 Page 254 of binaries2.zip
8Ftc6p 1!i5tq/^\dWu:JtlNh^ER?+EupHyaQV55uEt#*FIw+^NNkY:9I1Bb==VqaIy%YJb6hL=>R4uG%XLtnZL
di8=hw YuVL&\#KP>AXudmKLu^XD:tt%/c?#:Gy#/Y%u>a&+Np&/N5^FNR%E6+#i4JuLLb:LK=:NK=:ML!^$!Y?
YleMG= CwMy$8S?=Iq?/a<DLC%&pe\Z!<N+jHDyG4J+Ht@=MnJE$5kWQ84H8RtWCLyp^*uJpGeHTDWLWP&PlGw%
l<8/YH \BPY:AZj<EA\Xtq&8HSAJb1K&EKh1^5d&ck5P\NalW<lDVM*Y^j8<4^+PLTeJ/bKMKqGLKNPP1>B+WKn
VN!n11 Yut#huY4jq$d14+D$>Bq&6CN4?<q%jhS/995G98eYkbe&\a>Pwd>8pjD?5imB5hmB5bm?<bmi+Du+bm8
YpiSC: H9?TSm6cmcHMBc*DV:%lu<^/X^d:@@Z&FtBX4H9j9>S1WyFGyRY:i>8KyCAtmwEw*h*hKTAk*h*hZcIm
5%*9nq TKndZdy66@95e*ce@V#Q?:#*QdNt%1\A<d#Z@?@%9dmY^LD+*N@=*4<:bkc:Sa@Jn!+tQ&Dm&Fi\wLF>
?tGFX$ iE^Ke*n:\ZZ6:J&cum9E4elpHDI\M+B<HZ\WbMwee#XAdah<^FEVPENLA:!&FEtE5/kN$k?Cwa1qEA*+
IAA@u5 &bP$QwK1t!y/QWjc1Wnb6%R#6H^VhPZ&^J4hcZWHel8PqDS1X#jy%nj4N:Wc6dcd6Hced?t/%Nl>ycH:
9K4HP\ iu&QSYP9hZP@W@8Rb>i\j>>\WQ>\TN>RcP>RTNhkTD9k*PhZ*&khXHHYKQ@Ey1a#Y%+A%C=G#F98LEAa
MVDB%y b+8D@b+wb=P*u5deY#mI^q+m:e>?^4WH%+jJ\eT\EmLh\tKbp#Q!+mcwREkRNikYRX#dWWmP#A\lI?tB
a8VCee Y^1We&A<CFCLkhjY!JDRmpT#I$q/pVhF$a*TJK#!FD&L6aLL6$XX:p&wPblTh#Tn@pS8w$=^p$FX<?u/
H%wYPV F8PY%nMh:Yi:Pm=$hX:1/L4T&u&68eim8h?8hemne>m*i#mkh#mwd!m+d#Cpd!C+c!Cw9V?wyV?\wh$q
Zbh/p= 8idc6SLD\*uH%#??4j?n5#HS!d\le^N&SkZ9<aW8:<I>XF>Qt=kpjieQyGwyiIuTAT9kSp5$N\VR*GDm
RF>e&C 9aG<AQ<%S%DjA6<GPbQ6\BAGXmBpJ>k@ppF/I^$mKKTS*lCW$GS^G#IDFCHYJICcdp>c/W*bGmN<IYPq
!6454Q W:=1WMt&&I1D!hZcGZYG&R*G?a$tSe*uTq58XLXi4G?:&NJ?5cQ>aujHyh=P$=+85?/iG^%>%l&D4y*D
4<B^8T Qq$n@q*DAh*Dkh%DRV&D\d$DRh*>RS%>ke%>AjYh*upN6^*K#?wYu61cj$#%P!jA$&RlQ^Ph#AEb9=Hc
H=V8+8 G&!:%D8C5h@#&t#AVS99Jci5DA4&cAdLTLnRKa+IN&5!KHSB&R#L8b5I+i5CdJ#lC+mcdEMl&+Q^PI*m
/*$Cep k5mbSuGpW8\yFImcDH6DP#IwZTBuK#LhC1RH\6tH5m%P&DSV^1NRK:J5j$1XVudN&eL/!&YN%!8d#c6d
VZAS/4 LY4cLiw/LBw/#J5:4:h*tuX*Z8u69NLjjd&@#:J@\Kq@!K69&K>u&L<VcCmke#C\e!ARtLt#Q:C>L/C=
!P498k #/?&!/i+%TG+!8^m5j/i*GQ1p:hP@iRM:>PFw@+Cb\JpqDP#SMSS<#V&\4VSt1SNd$iCmw!HCA$cpkIN
J6ILG* CX\K!&AT/daR=H!hk#Q/Z&B+IVIa=TGe1T=$IIw#uRyiI/mB1\Futn&$6BnpVKFbpbq?>1X5V^C=p1*k
c6+qnu Xd\=y8Jai4X^Ri&X<9yd6W&&nT&PLi*Pdb*PdX%P4h$Pdh$&:X$YuX*Zi:y9DQVhHl=\GB6$H^9!GS:!
%ua#!* /^@!/^4!/^n!d^9$d^$IcAQ1D&n6<&@5>c*8>m=1h$&w9*Y:@P!JA8%N8WjYjG6u@MLiGFS/iIA5HVZK
/IDuR4 ?VZCiZFne&/pIhCi8HE1b/81@\ySF&lF=K#HBL\Kp5GCSDIZbM5N=k9aX=I5RRqHwV4RcE=$KwTMmpb%
\$\HR: AJcG41dcR$8L\H!twF$l!PiX96V6miJZeyY>TujFXPtp%X:I4:>b$YnZ$PLc%8db*iHV%?ZV%?*h&?9X
Vla/l6 *i9c%YQZ&YQb*Y<>PPk\Q8V/aNDn\bD*?JD9<JB9:/B9^/B9!+B9W:>ja:>jW=>jW/>9ja>QbbhuRaj:
1TAlWY uYb:#?14F$5MD?Rh%^1:h9KJyj+Qnpc5&>C^$%+ANV6ud6REa!?!?\:Rdn&=JZcXqD8DbYaW5m$Xe4aC
LQ9L>D 1CqpkQ1tEKVNFDb58TXIB6^5KTJ&XIa>aA6cmp:BPeQ$wFD6!HR:MkPh5wMqNIpG@P^H**qu=dZ<hd=q
*k<eXd l/K4nbL4#HIc4M1cZi4d9N5:@Q8/kwc:k$h:kpb:A+h/jj4:*H4:uj8GZEiG*i<Q8#<a<uk+=Dp^/D$/
FTqP:B =D$\/N$%+N*T:>*R=%$H%P6h%?%X$?Xb*8ti%?GY$P4p&&BlWZuSAKS$mddYI\8>=:cG4%&MmdZ$R4R=
LA#b/M ZM*m9DB1*u9SEh1Qd=@P&/IT5F\aNdMDDltatawJ$Ab^VTJbIBtC!l\ySRBuY:KII$*TkRbKbRCeapin
k1K1Bm PKCmp8&aq1alw8KeHelT@mK:WlT9F?#$4hCL44tWWu<:6<ty6MY46mP\4V8$4#hmyC>!wm>mwm>59C>w
mLtE\^ hMAjYHh+^Gh$%HN5^G%<&HXm!P*?pMjapPjRwGjQkGhd9&h>u&h%4&hq6$hqq#8AZN#lq6*8G6@1/Nh5
jVww6d bXN*\/#T=GTS>8cJt:4#N9w9Za#\5iFm6NtN#REb=+!l@kL6d5P>CTy!H5I$b\T!A:8jki!wGHa!wE$C
8u5Wb< qdPFEIuIGSVJD6RXhlR^K:n<S:GGQ$m^A@uM+k!mA?XMkXNMJQDjFZ/mY?+wZek@+Fb8EqFnu6LkqNjm
nSPmBb W>aYXNeb$haV*hMjP#RRh:<@=8FA%KQB!IjDER>GR??QBw!Niw&M8I$M8+\P8+\N8a+P8R<N8Qj&8:Z%
^Y=QDL 8hZ%8Xj&iyS%i=S$8wFp#t6*VY>#nt%%<G1\6c/#NK?=jLbWj&?4<i+=c:&juA&Je^*wMJ\+lPFJG<jL
6%E%<B AZq^%Cn6H#$8qP:SCq+y=p1nPGGR:RtY6mXpNh+=YyIR&8n<EmmplWDpM5DwA@TJRLhB:$tlANV&NNk@
wKC8=< \wPAnyJCe/VTuimIGMK8\59>q/9F4VtW5i6!41=npYqk6Z%K5*>SS$S>h%^:Z$L9RNLRaPL+aQ#Dwjmy
T<N^C& pjkua*HVa%GVa<EVw>+n\//D\$/DR+=DR$=Dk<+DA!+>aQVh=%Ld/%dS/%HT:X:R/b4h:y#S=y#W+lVY
$d^1$5 dP@cbH&:*5K5=wyJ?iqD^TjZ#%4y9uR?@ed>>F5QI?d<En:%5Rl6X=P*ZG^=e!ck^tpQt^/>1:uGT=n8
:M5:!I kmY#QeHT6lliP?^L>qnuCI\NC8^d#LE=?AkeVpITG%b/IGS\#5DaVk!/=*KJaEZ=TFYq&LX1Ci5%:&#e
Mt69TZ pLy=Y@4YjSt:n6$>wJ>&@H#8Pd5K/+lt9:!8tIc?=N:B%PHBqQHlP\>H:$!QJe&P^<?MSW&NBn<aAb^h
:4qkXD ?weeikj6ikj5?946i@5h8uwht*5ec*1eT*9eC44e5n1eW>5eE%whIy46jSy5:P564>Zi8Fl>=W!=<hGC
/Vkj#8 p^5j*V#=w/QBY*i&?XImeKK>mYGCZinB9N!Dq+!+PcN1%h+Yw:nTHZSdBDMVLY*H@pumX&%BnMC1n#q!
XFb%eE NMhKEYTwCC$N8pWuad4Z!8YScp4*ht?4NNS89Z1l&?4GkIQXpJQ6wLNh9=%Xl+X=k/qy1cFS:uHhHP&#
dTaM9B ^beec%&TP8McBnKGl#MtS6Mt^%Kt^lNu^tNu^mKtS\MjDu8MDDu%D6q*Dhy$Dql*>h6$>6t&>>k%h6qX
MTV!e\ h6pZhnqqhV1q6DuE66mFNN9/NNw+%6<&4:W\4d=1ZHqJ4>#pcJHP>4:#i:?%$*uudklnE=uA=\BP#BNm
y@GuD@ i4@u96BncZ4yh/Xw8%1kPAPElmQG&aELNjyJu4LHcN<TbI=etMYiEMtKRuWXF\6XYuX9*+=GW?Nlb?8y
Fq>%b= WN@u!dE@=Kc@LM=>Xb4@11#ky?Le::LV=8@EQRn!:dyqZu*/hP/SW>pGb6WiKV%*i$h#J5e#y<bVy<dn
HKi\$k y<amkbpjn@lMDLpPDVu$DN1&DXm*>F8&>F1&>Fk&h%uXhX1Xhhnp6N8t66qF6>kENqq=NF4b%>??YYhl
dke$Dt YuQnVPXX\:ILJ+9QHC#R*q=>c6M#c?**:kcjpLW6bn?%BPA<L>qdC9#lK!j84qQ!SHyAIteHL5+e1PFC
C1!DlL IaZmSIX!SIw*c^IeQMLwREwS+GeZCauaDbwXSnyDnyb#MTE@bN>>XbV>614pR*Q6^@bGSE$j&^4iN>Y<
M9eWqk 1/9+8cLwSWdK\!C@F4QLlV1GlXhhG5QLB:QG^4Mi*$>=QB:>ECcG#<T\&@mk+<CkZiikhZP@bZ&9SY*Q
G%/BKV #dw8<:1Pt=Z6FpX66??%*w=49l*acPFYj>P/:8cN&l8Zc1/h1dymWG/1Y*L?SLHl\b#DY$8Pcd^&%9@F
l<BhIq &@AZd>dc*%KAL*JB$$L\WjWc:a=VqwbqM+ZJteP4HLulmAq<Q!D5VKY=ANHw#nTGE^Z8$LBGqqpBbGeJ
58cMCZ <dnN/^88uy<M>j$?I?q%TR/ACbB?dK9@yc9=q?/YV%$6u#ydj8q5@6VS>Kt>+SMC@Pi1$4up?D=:&?4L
4kwEX9 =tXYkW*BJj&JjcMJ><jC^ph<Swchl\j6lkb5?916&969NjScXQZe1Pm/X6F^4cL6ituL>d!YG!qN%<Md
V#9!Ea 44uZtXuYZL=TjjqeqcqS^WZ>59QcJihPFJ$=Y1B@KPjw4wKDt1>hYYQl#$5Fd5^4R?tCF#RS%dBQQW^T
A*\w5M ^A&yNJl?J8NC==bbVtdmBVbGlEBt8FKFZYtmduS^h:1EG$*emRIHjW=m+nEd6S4M#p%HB:$1#u=jY@c^
\*D%n+ 1S4CBIS:Yn@*6Z@8/@mqy\*we&@:=>+&kB*A@\Tah:c<c/l?uubu$Mt^+9#X\w8P>R:yjRH6\*+DwP<d
&w!JEK 6P+b8NZdh:P4>&bL#+&cu86q*XiLPm<Z6b5Y6yntNbttN=4GNyn/%q/$1VyuYtFmZG/mZ*bGy<V+bLHS
jauk!M 5eLVS@L%D?cePyB>bHj?\W*V6:VSuS9Em&XR+L<5DQ\*:P=dC>@!le*\/BG?<:/c9$uFV+VtTmW:W:Bl
cXh>kc IC@PLA<nNucmWy&wIGwaLqSSX^wwCMZh/M5>/JIi>JY86BW8\59DXFY1#lyPl9t?LM#<$FD=CZm+5@GZ
p4+hna dk^!j?i9@b$IajC/A/wQ9wdp8%5B:dj%qe>TE:86LI6PGSjw&VSd=QVb6\%ah9Shd?8:&6bn%6y>6d:d
t4p%R\ 4L#4TpHuyi!&<@hc#1a*t1VWteVWu9G9Mdc4QH&=VN?kXFi:YQh+pe/^Ay&niceP==:<J99+*5#Di:IP
^D@Kn6 :m+/6GQ$+kE+Siq4<E>$Gk%nnkQ@nP#/\ICjSwHni*eZ8B<Z:$5=HntaJ1>V>lKl8%Akb$K>RWHEmk5&
G=:Mm^ M$QPaHnPeKcJ8hCYA:BAdnSR5Wm:$&Ve/VIBM16!Dl$aedj:IjQP?=yTBHIVE*J9G^M9iN*XAkVAjpa@
I&^9tD *>jBSA*#BKKiVal88Z\q@@CbewPA>m8qQYaNQbj18!@Yhq&w:dla$ZG?wP%5Sw9^uYdD8Ac>1F4h+Cwh
YPMPkI #+yVX8WuL=ai$!5/e1Vk<MH<I+h!D^@MQ9^N%5EDtRj&bP#dtd+HKtjZ=m:6#imiY?biI\nekB9+4>=5
C%j&iH 1aL9%!X5Z#j<I9bSe@%ELTXQWaa#*CFA^1KDkp=KIC<IuPG5M6L4RVPDRBcBpPqTduRbIHi/uD6h*y&t
-AIZNF 000c44e1a4f00110334 Page 255 of binaries2.zip
iGeA88 +CY&KpF4W/9b^jta+NhFYS<d1*:ycQ#e*RJk@6Ld?p6QM<D?wdu!R&Qb?+c!>+*q:=51QndDTIHApXaA
8w>QZ: #RFh*hH<14#\9w>Hla=^*kH#Y9$:HYjLPp*KP5/W6BpX6^ntNi8uN?4E%b<M4V98Y*QE6iKRhip*X+5Q
4<MAW# GBj6P%t\==9e*Z6!>8#P*4M9e<??nN%:$*j68d6nb?1&:Tqd6/h5*y/1yXY%Y?$9\n=uiJ5?@Cwa%PT<
AY>RSw kKQdbj@N9Nej@8P51\b+*u%8%P^+wwcml\nDGb&jJ*B&IHBtlnMpVPR5=p1ZhKjL8nQp*St4QBm4QSqk
py+dJV 5KMeLKPb><*SMVjHH>IV*%WYjY1yA<GLAG#:$NH+ZZZJTFyma$SAhcl9XZlAhYSRW&Vk/N&E:<wKQ4VW
E4n@Bt Amj@A4Ic^uWdDP4G/1jJ<i&Z4^d5QX>?!LhJN:%FL:9=XFdnma!/a!p%S&K1D\XYHZC6*GhX696K<W:n
<RV+!u \8*ciX5Q=t#hp:Xq^:*NY#P&kEHR#4S68%P*:p4b5nN=$@a:G:jiYd<6TZN49QLc9I&1j@u4Muia??8^
EJCHjR dT#*I=4epBnn#G*&Rd4+F8X@+>kJX8jAQtm!N%=b&pPa:pSqbm>c4Vt\cPMqHMcbSuYp$b^wDBictB6>
l^@$KV yV6D%pNa$XNa!WhW#W>eM*DF8pTNZR%u##<JC*lXAJQ=q*dE#H%6H:8du%eY%ad=?^1jXKR6W&E5$^Jh
V@9eF? hqB1tdEmZ+u4>dFa*=<1etHChAQdA$8*k&wEXCa@FYcNPNmYHnLI*YbY9n?w>uBm#VeJXj8n!@iGqi:&
VM@ICY LhuyWL#>S6HY5\YdhZI*He:i5Qji?8%y/:di%h1Ww4p^ih&tP?8**6t\I\qw@ddEhX5V6Lap4N$Ty:a=
i?4aq> c5*ci^9Y@tCnk@8VA@mjQIH:G5J>F+Gei>V@t:A#HMNPQFMM&w>y^5lLiDBAn<a5IXDPn6!qMyZF&aqG
uY?GCB e$a+R#<#bD&FFd^FqQ!Zc\bLd+=R&J1>?*mj=i%u<SF9!kw?N6iCbAcJ<Y6j&@9&&thbMZpubS\%?d#Z
896Dje <&Z5=1<?^D>+WtBRY&BIY&Dml8b*cj+kSpCM\?nwdj@W*jK^9iF%SeFWpHiN95Hh>hybG&&Kh\RWd@e6
t/qY&y *P1Y9<W^h@Q6uE&tYS5MM6eh9dj8t@S%i?=1dW@Y&J!w9nFBjZ&<&4w+>jX^c#jHc&&L%>\i6*b49McY
@KK=Vp PQXN5cwdw=W*S1#TT6?$+jF%Ha:><\5C>#hAtT?&n&6l:HY:=cPpSD#wXBhaCcPb\PV5TBm1EMQbCbwb
Sh1qm9 lIc\C%*endHTR^l!>lFh+!?lH4STK%J^a@+*J$ce:F+pSd?yKQ#WYwh!B5u<84:wYcL4yJ=A*Dd?4tQ<
KVKKZw lj9=:?*t6>QkP:61&ScJbjLWbXhQH48jhjh>c>*uHnR/tn?&%4$yL\ADuKaL=%LYH$yYQ*h99eY>>he#
X?PF9N %q%M$#1d11Yj4Hp<TiNAw948yLY:p#S*Jc#hH18&KWyqjbTKFyV1?tn%LdGcP&I%h<c8*SG45T%YhZPW
@t1$P1 <wdINi5nX/?:8*uV^FYh@$P+awL#$lWM?F@5Dtj6DjDZ+<K8!^N:!Z1JmBX$V#4XqW4FPiNB\WwQbnKD
:tBIR& YKa/I&aGucA4ZeJDYNyVXN=LXNFZDHBYDXm8Em/uu499+Im#:a9pGIR#1DTcAdh*uW*>>=I$Sbi6wm<D
4TZnq+ H>N*<XMFq1$kL=PmMCXJ+h8&S1E/!P9u^p1$LAGeRYK@Ke5Hy$ddqa9J/@jGKB&KW#$by*a5S8%kqP4?
DJ:RVy TNZhpTw:\yY*lm66nqDbF1Y&I%J%c=nT?yDXc$NZ4\%d9VbeiZ&p/ybwDeB=d+#tulmNHXHKt!JY4\6j
9@FDnI ySY=Ym6><=aJM=*FN!V@#YX!hBM%!BB$W#RSP/>6@E#5?Y6F\%jRQGtR5\5&k5cnGJeD5?>Dctac*RYc
/eS%%h YhTN5h^DSMyVXBck>lbV>BFj:Ti^PqS/Ve/i9cM86m>Ta6?CV4AN+h#d>41n1TpyC1iKEyapL^MXYmbH
E*?5d$ ZZbMl5>n9WCtkYb@wPZL&pKMe<9Hq41*=aZQE/Qc4=^Q%NwW4LA?YHF#$KyNkc5&BK^cH/C+DpyBK%BB
LcRbS$ M%BSK&kX?P1/RAYNADuXRHuXIAZ%pNXcaWwd\%Y&SK46mFDhF1/$MW^SM$SiQWSYQX^ldectLiNZhSi=
a#kt>k wwH:1l!AEbS&aBV#Gh5t@S8PHd%TAN5J<^iPHTGj4TEe9wL8kZFGLe$WDSZw>clwJn9Sce=$tk8D:ma5
q^=JY\ +ma1:m/?\pNC^uP=uKipkyiWww@MGn@yNTG!c*J&:\F?@m+=>m*\M#LEBtPRN=$6Let^kP%K!4Lq=GWc
ZHjZ8q I1D:Y^c\pe>Fm<>#HX@<h9:w:aL=Jy98S:t?1T>Dm^PWM\n==+tSHYduE:VY?etw?M11A@uIAcpB?e1y
MaLMa$ ?<1y?ep!=R<py?w9y?Iuy^KkwBc$TnN+6Sd<8Ew4YHF65L^/5K^1pI^KpLS1tK#c*R&d^5%PLiWTEmJ\
aGkm%& PABHH\cE:J1G&L&@nD%9k$TpqIkZk?bGw:4S1iCnK+*1\q!#y4w\1C:CNCBZEd14KN%NnPG?ZNlhW6lV
\9+ZS6 Y6^LV6J:6c!*<twjhSXjVZZ@Db1Bt#aEcY1F4FK/6&QHwN*6d^Mn*=du\*!GuD9?MhA=Wbll4549y5WZ
>aDeHb 8wp9aV5@WD!tPKA>nBbHp@tePJnQeFViDnl@cKy?Zb##LC/5@i4=iK%%96J4jKXXjGXWjYSWjGRBe@BS
ZRqX@D FekZjqV^pXEGu\GE@iXX@BXWAlVXAqhyBC11B<m4BkKH!/pE!1wE!1kETK5ETKtG!Kmq465+j8ZWRyj+
p:JZRJ LZVN#m6pl^/e\WMieeYP*akDP^+!^V9qa^YY?+w!QBp$V&GcJ+Q1IR#qLpJ#F/Y=m>Qeq>QhJSpi$5Ji
DhNSWR e1Ji1<Y<XTX<NFj+dyd^*/pa5F<6<MnG+JM:RuZ*SSkennLWnnl<MElNI*un^1:4yp>nR6/W=u%11j$M
W/%Vl\ m&e+8Q/=yjJlYpA<AT?Se@^B!bE\8??K$#@&69!KDMNBLj&l5i4uku6#pRHNytim%/:%qq46I\%+A5:K
l<uWQc pK1M5l<EC=\MPIQQKQuIK9uJKj9JK@uLK\WwKAMF!m5H!CpH!mwVIRhI1RXL1!b44l8@jI4nmtCPT>/+
Yqa%QL kZ@9DBi\$Pjm9WR&:BG\G/QVVWV5u=CR1V15pcwtF!Il+m>C>^Pq?auS@MSy956yQyJ$H^tGn:!\#^wS
TiKpyW Z#XS9*Zm@q6YBP!SDn\pH*S!Vamli6nbViGti!K9Hw5^N$!+jTHb&n#N^9dPyi5S&@jHc/&9N>J:E8IL
#b4QAC B+NNeDAImMFBTt@L<<4M>BQT*JBn6k6&8y:>wVLuR%56kI^PjaBCBbVjL@QTH98:X81jCFNY>yJc=TP6
ZEcY=$ C9\MjT84:C?4EkTmRBHp5\d$6w!TL?A58<bQHtm%9<L1AMW%kRyKkjJKpLPMT1C$T1AWpF1kFCmNqBM%
5uF>TS %Ga6hBi/@y4:AtEWPQwp#ihP=>AHQ5J%eInhBF%6RdhKw9QXd#DD9@e$cnLau46BPX=KLHI=QX!THm:N
/EW@h! CJNnlK\TDqaSChaTDh+5F4J4iek*p1HHyWQ%FMLPKEhe$w1/9nZt>wE+G?%EB=Np=?6y:ubbZy:=j1FF
L<bGGc @uEFL1GyBqhm%&<6P9#NlKjV!?#WD:Yqu=y4\bD\W%5DGN?>:cmjK$!56V:P\duXV9@H/6\Q*a&j?>6@
6:<Z=+ HimEW*pkuF94*qaXjb<iQ?Jkpd%*S/C<wyjWckT!11?e1l@IaZp%ADqMcXQI1uZR$mlu8VX?Ct9<X1*&
e@iW!Z Y:MtRFpyWFp=eLX!wB#PYVXITmNIct&kyHK!&y1*#uwLZi&?WJ=M&%&a5d<\c*>?#8H<QQLwWlV:6>l#
*a4Vm? N4>*+YH+L6MnFd5$MqbLyCkIJ!8J*NERVhwkq4BhQG/jSN\S!Xkh1XlD8hm#muGZqPP8c5bddE8!Pbn5
/jnnWV yHjZ@YK/>/%MQ/jeRL@CpMm!<D6XWSq%5dq%pbpFqy/^&@jh*d1=!@#!<<TIN$Zb:!1K*qYW9C59jq>V
&W<y5S <dG%@q%4#je%8dQ=ea@TA46<Ln>M<yuNm9/yJ9>Vd#QIFlR!1Le@hVS?1K>+qb<^F^*ai5Wpeb&t4:Tm
/d&GjH n:RTE5XMkS+\RGF6$CyRa/\FAiI4A!A4?Tpw?c>c+\<k1!wF4qWJWqeJWqIJqAilwSwkDb!5ETm>Lpl1
q:nu/@ a<lK>Y^N=V<Z9&pDL>wQpihKV>yejG^:AZ*&<SP:C?nDiieS<1nl9&W*jQi%E>WH%lc8Z=G*WT^9y$V8
J6FSiL N!8!V$lt/p6quJFN9/CRd4a/@abc?1%%Ghbd:>u9#*R=qi%=Ke@j5nDE4Vk<5DR11mIt1Ta8w#Ey9!Yq
yNiCd> yQ%8iWh1Ya%9dMyJ\>l%/<6PHuuk:jS>c6!44L5@=&d?uHZ9hW:Y&@KmD@XXaDV>wcQl=?cKq*YFQ#iX
664tFb j?l5BKPT#+A\lA#u<Z:ycQ4aZQP859CH>Qn::ubFJ\/F4qH&pX:nA<&5=m&4+mY4An:/!Ku/!19=AaEZ
by6Wme MK+S#mCeFbWC%1\JXFWP$qAJXqeNYkQL9EAb>RBka/u%khJdR1S*^Ml91N18!iNm#EZ9n\E+n%1cnqtc
8&kiVc nq9C=/SQYF>/aH$JJj@aFyJHu#e>a<hy?EH:e?WHqM4*T%aeq!\*pCw:K%N/Yd:+?8wmC?XCT@XC&*YF
hjipPC Dq8LuQiX8B<9<Va8C:lSEiJTHSqaF^jhpHmuMVt>JVY:Qc&k/%=bd%b%j&:haF=>d&yS8c%H\8+DKX5&
iB1I6+ 6X\!ATu>a%4m#:u*Z8ht95:LiqPa?//$<EN6^cjt8w@NhS>AyLR%j8=1bb96:&n<&FRDc8?ZPZhuIu!d
wY@w4A L=5pdN\IW6ed%lm\uQPYR#nL1Zw#T#5pTWDJB:6FyBNWWAya6TbRTVqISTXaYVXIESRdcwHTGwFTYpFT
Aiy@V6 G+Kp6+ZK:p=Y&hG69YeB!L#8:wLS:46=yh@m!5C6K$NRq$h8Z?at@+mL@MC6W?YH=P4%biyN=i18K>di
n5H<D# YqNn4XJq4%uq6LHKbX8%?==14!M%99y%ASj4R&+*Suw$^+T%JTS&yKS%yYZ*bPd*=SRQ=JWQ=%iQFncM
B&Zt## q#SQXLR>KG9yV4mZje+5b6PY4AN:i/*Mu<cGkcCGAXJi?K/!?F%F<j81WyAld<8K*yRW918A4#<$%5AA
#?jhJ4 S%c9QnbX9!$9?Cp4iT:K9@9Y=a#h&@*qXu88BJ#X$LIbEQcCpFHP5H+GJwiwaieI!k>qYG!AHuCXe6B1
^Ri1Vj qcDXaMCmFmm4HmT6ET!qGT!%LpS/e=ne648c&$jQHX*wTS#@Z9kYP6$*4$KbI:yy%u9VDCe@8AD=l:cZ
Khim5j t!+hd#!n$ZqVw>XG6eXi4hqydcQLlpd*:a&i?=y<nnRH/LREtdTGZt8L5P8I<i/KD?>J86PZit<kI*ew
$pc8i+ 8*A+9*T58HK<6Gcm9Q=lSe6phj6WjjiVy6/HFe&6ERu*#y1tHD^cw1e#/GA=F^*<a$dTt=Ke>>WqH?4K
JWJGy4 RjC?4!q:W=#*Pm@:hWH8/@\e\Q^DZeYHl14*6YX9TuJ@9Je$F?udb*pqi@@PAFp=F=EXd8L!uqLKZnK1
Gy/AM$ *4J1ZpCR6y1*9L1*9IcQuIaQHL^A%IC#Q<ybaW&kwuLRKlXk=mB=6TAb\Fp>YEw>YHy6mQT/MNq%h>h1
>K%@Zn VX9we6?h=6>j8puSwM&XAT9pET&*4@ViM88&MGMnd$+kd+GT9#J<?*L*hj*YG%6::Zh$8t#weN@R+dGq
^E=Y+$ #Y6u8?@B>kCh#8B#ZiHZimK6itNei8Q<?lQDB?+pDKYtDYjpnPaWnlYW*m?yjFBS?/m/+ZFh<%S>?=QG
-AeT?9 000359ac93d00110334 Page 256 of binaries2.zip
SwGtVQ :6t&kduPEcDJ?1:i8@uXV4==?thKhW=%tX>=:Pj&ZW4$#\Wbd!9!*%eZ9c<G^m=<Y%d\6mV@hWHPt/Le
JW$QtZ N<Y=Q^ht95^P@m+=cn4E5>9mW8/BuaF!5ua$8C@hnm:8LCd4L4uGT%wF$Ace9iRkbG@=6h=!c*%pWhTI
Z9:enn ybteqRIXqIMWXICbk?RAb%A\1\XL1RbL1+hIc$VI18c5X@95496jC>^1a^Hhh:w$:uly#NF$%N=$^P:!
Nenwe/ pP*qIb9LA>d\Z1@AGH&*#Hy8aiR^?D$*#b4N#nbi*6=/e$8u+?b8:^$>9u8:A+:&lBn$lq@8m:IimHEh
tipaI= nQeiTk\e8lM?plI:inh=LPQiiHdi@j#mB!WXn!y4H>e&VnY$Qtu8tGu6tt*9t?<cihy*@*u@\?eDp*Nh
Ga=!8J >?<ZNhR:?tRiQyG:j*?n5j/w+?&bWP@9W1Jibmc>!p*>PT@>FXB8&585%J<!p4=Qnu+YG@Rp!H*E/Xd>
=$htVC BaP$Hb5DbKV61jSd!Dcu&!T1NXZWWWVcddtmB#C&LEC6:kWk!&5C?RDWIFKkyXHP!kB!IIAM8n>kbqt%
?uhYw: aBt%EGqXIEA:XEa>j4Xc<#edmZe+?i?k^i+FSNSn#\8QQT+<e4@+!P*mA>iLE!/ZJy\9nTQ\S^%MS?%M
aB\&qw l?$kiR:d6>$\LVZc*uS^R+@D#u:@\@%BPu&lb\am#RbndIjnQEeTApj8lI!tlw@hnS=QV=m+q#1Sujpk
nGLA\6 L@>leiqpSjXWdiPV^6cbq5:bny/=44:=u1GujiQQB^>?P@V+^hD$m/Gy?e:SpjVC!t6YtRiPb8@aXZ4+
YZ5:&A RM6b@TGd/+<<:cd>ZGaC*YiCQIAA&?pAq\ei6kNYbk%u>dIQ:IyWW@be96!iR4MEpNHhVRIpC!GKFXua
ETK5mP u4HCSWLiZX4bW$:DW%:LT&Gh6+IY+twNyE>W<bNHlwHR!Wlm!EHIAC@KPWScLR!M8NZX^$!?YiIhbwl*
TITZ:d @kGc>#<*/*h8%9j<nM@=ci@#$%+Zy4\k?WpA*?*mR%eAH=K@:<^t?$Hd!>$YJyXuNjweDk\G/R&FZ^!M
ect<dp 9Daea#pT:#Kc=DiYHDb&N*I<Qid?9aRHYZei=1R>!58iLC^<ZFa?ZX$*$>A<&>I^%>+:*#Q\6G@+&eDw
CNw8=+ <<H:*\+@@Hd+MWD>:iDp<:/Jtj4PwjmMBp8ZIq&n4D$HMuj6!6?@y@#w@q4hI\*Gy=4P/VhjMGm/wFhu
a&5j6n jKLp?Q:$:S5nXhd+TK=$yw9apYnYkyVdk1Sd&MYl=kC%INtTVLPnT#lJ!L6J1Z4IcZw14APw9iR%9iR$
tw?IP4 aLew4?19wBIIBd5@bPIIN:MKWKm$cwTeYy1t/9e&uQj<\i<u5#n@F/EtL$LPQk<??!#w:LQAe$<D#<$H
Z^utSI uJ6D+M@+uu<C+TQp8Y\@:uT^%uS4q@YBIZ?npcn4w*GYa\q&+$q8+!pB>>Mm:tjEVtRqV8RpQ<!:P%q\
MICJXu d:Iwh/1$/Eqq^W^h*Y^V/%^4%*#Z\LP?+iiDa<?H:u<:M9Fm=MELkB1+89@B<>::#>wHu%T%*p<9:A/M
%1bcCe 4DG*!Ve$8Z9kaPKGDhF1!kBylCwmqhXlc^RCbKR<^MYhcML&JL1>EM%PpGanTLETlBiX*<R&6GMZD6B5
?!LD:M cBIPa9K8pkl1iT%QldYi<lyi<yC#u\JA4SwAck^=>TA=hTR$XINqXEJpXEJqXMNq%YJZ1=j5*IVP$9@F
5&hhB: hS5b4q9/eMJ@GZZty/k#Q$ci?THm#Qjlb:+QM@p8#AVA@#aale<p#&::C<D&p=+Zmp>46X:dQilnMBy4
eWM=E\ QybpP*:H<Z/1?@*$kIuM!AjbmR>#W^+YyE$Y*Z6epnXXunhhYjKpyuK&wZ/&yY&89ihy>?D#@6F9IiRH
Gah8=9 EQLI@Y?H^y<QnD@9G*@YQjc$dZC85ihJbe9D*QKl8LRP9>B1T>6MHh*I>b4iWm6hSERe/R^H8JGJ:pTl
VR#$!T \h*SRqR:Ibw>In6BKpB6!h!G!4!CAP=EBjCFcFaWMZ5SGShJJZebhR>=DR>=hbT#4+Kcu+IcGJIH!KtD
6Tq+:i em=RBuTCK5E!!1E!KtG!1lH!1pt11m$uh8M*q8G+l\#^jn+<d+d&N6:wVd#S/#mn%:FG4&KNZ<Wa9+\&
>QJjYi B8S@mn##a\RVQp1icH8W@LT9ThZ=#Z%8i5QSX<iVHi:jhb6I>*1RGjk\J?yS*y*J\9VJp1#HbVuVFZuV
\JF5ZB %aXQcp6u/19utl9t&>1ih9a</^%<QkA+V+DEiDH<AEIiHH$?MQK5d?Sy%@B<c@>5jhh$bi6pWe%Eb6HI
HYt9JB ujV85IkcP?6$uWNlK19eSWRhRC$BL/CkPyCw>9AFDih5L$m%^T^6\iKMdkCG6=Y\JA9dMTRhJSSeybR>
Q<j>QE RFENPC8wRe:!kLP/9=^GkA!B5/^KtJ^1#C4q*C%4*!A:99=B8JQMQ:Gd^9#8^*WdP9a:KZ%MN9!RjQ4D
*+ybD# uhQ9p$/@T\R!iy8ApEjk@+!Rj^X6#LR>F@t/!%9d4a<Pl%&?u&I@piH=INQ*WW:kbH:W+<I:n$98QT:L
ni+F=% t/w5jFJhNFNZM6NaQ66eP>@c>LTn@Xq*::M?qQQ>=\D%+Q*uA&Mk1J@%D#@6Hb#9/J64:y/ydb51d*^W
nu5d+h WDtSYVmTp6EdHh9p=bJ@Zn6&ua1*8IRVBRpKEk*q:EBCIhPbqlcmw8q^C:E$<?Je^PFReBej*bwt:mA1
AkWuFR +!1=!pNG&X6iDS8J1\jIcwC^hlAMDiWRIMBbj5$hNcXt:V*w9CW/ceqeHQFt*cIbI&@Ip@!u8+cjWnGq
eA^qk6 GH+E\5ln<I*iJSnl69<b6V%Gjm=R9?:14pFj++tp&\<!QS:q?E*tB#$8nJk1Tb\8!=m8#H>TZjKp4t!t
PYJ@86 wZ!t8ZK&6Zc?4ZG?5?%yh<?#9wHu@TMRd#@RKLS^H\K=8&??4Y8&5jWJKLBL1^@pqa^u=A+uy@XESVh/
6>PnDw PSciQ^/@V6qZZMKbI8^AwkMQ&<HLKGmwyXHWDwnAq@CkSm@Y8AYnk:tuHVE&%aw5a5?RhF+8:!G6=I*M
?p$Hyp L@uJA5+5M\jLKkjLKMY5Wm#c1Vq9c$me6EVuLauV^e!Jit>DHy:*M@meaRmXd9kL1nSDTJ+Dj4Il8?&N
N@K#a: wP$S<n@HGhYcd8l$PDEcejqly8QnZN?y\1Dyp9Dy54kuFYqQc9Jt/pyuGmyut/ytY/4u&t4u&l9tP%8j
PDJqGe hue>/?%@%nj$4Bi\HaIC%X*Q\H^Z@*^:#%^#?$^>$*Sq#YS^/aQe9LH$nKE:Th&Swa$iqkXu9+qj8<yZ
Xqbm=C VB#lDLQCF6:TB>IG5lXC$\NF#R^1mB4ilacEZVmAbRlcl=Dw61APEbN#q%V!luQW/9+!cwE!1pEA5nTA
F9MC:M 4B\p1^m+TuHk\9F9ua!Jp=a<y+5@<CTQ:p4KM9k%E<n\%*6Mjd:HJL<kjHddj^h&w8#58t+uudHa/+?#
FpFE1c *ccKk1jLI1e4+y=Wye#W=5\$qM+$A5m%e/$Ae6%<S<N<X<9V:5/uQcA4:H9c*V@j*j?$i?AyIN#bP>ji
:H8+iu QRj1cnCE1YtaK18cLC!i!M+iT$5hTw46mjB4eL6caLR#Zp*PS$VWteKAuEqM#9An=A#F$TEmqmanV5a8
:tCFlW Pee8?GJi1RGMVSX#FJF%Z::Gi/YKu:S1IF\KlGaPpF46Lc8R5t*DA*N>PFiMVFy?l$^c@5A%T\@9m<J6
R*^Kcd iE<t>6>!DID?pa$wC?yZXB#\F:X>&%Z%&m5:Bu!MJyJ9VSZ/VbhHVXjGQ/qPtcuLttpwBtcic/&dc/8j
%$dj1$ c/?j:\Tet=>&6V:6cy@9:J#9:J49:Ju9/IW&BtNDMEJ5cH6TC<^e>:m+@FFi+WSt%6nhqKHE/P=\#\du
5XGBtd e\X/t?KXyZ!ESb\yhNAX&5NLC%El1Jte1WlER</kR:RGypZVA*IttVMqSBDyJ5\RWRjGTnh^Bc?Xc@^q
dE#nFT qAJqqQ!qFL$q=b#q=h9QuLl@?\#HnPW#J</=+l>htNl=Lp9>M$@@N/BeIAPYFwVQ\@aw?RI>^Xd4\/QB
5!MV@h F^=qPp!Zl#?yVy!y9V6du#ZdYDVZZIpt^q\HCPet1I/t?Zck=4q&WPN%#4X%#4X&#DTB8ABPdy/8dHle
cFm>hp Xn%bYQwkJ@>?S8bwe9JkZFSZ1G8>9YHBCc*E%T9>lEXhkJ<S#4n5EH5nBS/$NCyIHpF6lh!nCYVFVW^5
W:Han* 6AZSaTMDnGXe^GR<JSW>JSW<q55+T$4q:h9Xh>u\kjWF:wqmbI4?*EJV>D?\a@>ZkV=W99+@mWLle@Bu
c\>@:J l<>l?$@y?pXG/6%Pi8PJN/cKjGh1ptd4$&ed5?ccC8hcK?dcc?hAakC<ue*#Ha*A&NDl4iBn$&^4K/mw
kDyDDu b=9cu6T*VNe&VXZYQ!/4iXSe@nC9/H=t#6nh>JGp^IGa<M+k^*14W+YH%mayT95Lm:6RlS$S%I=py4H6
qXYNWj Me/&VNRwdenbBuIG4pbRR>4pt%Ap@M+XF5kXh8nF8ZbWWTj/etjlFT/m!$NXqSyPc\>cZFl<j9:JE4D@
Fyu/Zl 1%AQpV/dC9S=<F<IQpb?!thu:dZh\@:uH&Y/#FdF##Zit&9Kut@Ju&<6ui?wu8?5l+Rl=Idb%n1R&InA
^+4^Ci 5KXyy1q=y1Fy84bl11y&54\KR5+9t5nPHe?+N=1TQBRj&^eb*PF9XYh?4GC9S1I<+C#lTlYF6!#GPD8R
H/</1A EZ6n$YE4mAlnnq8clX1RDQ6BDQI6SPAF?K1%EAXEpCNh&GQF<wJ9>uTdt!+!Se^#ey/H&=*P@X/m>*5^
:AhHlD RWXR@!4T+<F@Ejka?S:LDS*&P9eVdKa4a8id<!DpqwL=68KuHSZ#HVZ#\Mb6>dNAKPjttytttyuG&mj%
ljPeYQ hW>1c/i11l?ZX#\1KZ%RWDTSp*j@Z8dw*hVlyQnB&MnieN>&:?8%b99#6!5uTK@$a$m+IJ!biAte:WlM
96PYX$ #nd\>n+ab!FwcT\>lG+^ZW%Cd\?Ce:+FPR8B::EqWb^ESXP&dPm?j1WLt/Ip#5\QjV*&Q$4$iPy*XF@p
p@M?/W n<HH!hhe*nwWcnFVpjRW&Lm%DJ1=4Zm?HZ!5uG86kaSd/&bckGyut18jNFbN%%XP%XSPXXW<4ml@XFL!
jRM&&u 5LB\Inj*jtdtiF4cTHLTaEJMj%Swh:B:t>8Ftk5:<nc8myhe/W9u=G!Q9aAXCBLLKGR5R%nSaTpwbIue
T=F%B= FiRYkjB6SJaIbB5AYW\$bhiYV4P#^JulLmD#1^#aB^dHnnBH5j>by5hTKb9?KF&+CZn#b<L9<:9$yDD8
>Zhy*k YXQXW%A6k^/\4YK86Y!&BckT!R1Ee*Q6p/d1/j4K1h1!^%Yqp?Wqp/XFD\5LH8Vq*5@KHM>IG$&>M=\a
:$Ib=J %^<V$S5i&BZk&PJwZH%tY>:/NjGT$u/MFc=WWEKLPJKFaYmREPG>IeIb1V1aH?%BFGB?6wI\IXJkZSV9
D=yG8Z diT@CGRlG#LFYX\5h8Qc^p6/lAu=K@mEjC@Ad5EDi^<:>tE8:G!e9/lFt+DA*@BB9Q%eYic#q1d=69c=
FCE5wq %8dbqy4byw4bb1Cc&id/GcCt&meN\M#qW>Wqn!8KJp5LHlZuQ<nQuenP9H<9dT#6#5mh8KHa!Q:IpJ+R
VQMIyj u\+j/&ad9T1>LZq4%<T9pQbu4HCnmd6RSJ*IIKJBIW%H^8BahDBHK%SMFCA:IVK\6A&\K+AyKGTN$eaJ
+j>m#l k<@aIyAnN1k%ttw@hPM>IR!\6>&<XuVJQE4H!t/@W>Ryb!b&e!:5:C6Rj=d4LXXLcAKe@?@qF&dVQPbK
NAKjDR ey<%h<?*D5\%h<+&Ne+%%WDPVZWIbGDtm1tcp5iXlbNqEQLD\6\H8Xu*M>QH$=JHW?KGE!IHw+Q:\@^/
NbQiNV Aq*dQc+**n^ciW\4X%plZtKqQ%*CnT4tDDtLPBA=p^nw:Kk>m#MFE:^qPuIDbCEkG!Elc%TCVNtSKc:m
-AES%b 000e784532300110334 Page 257 of binaries2.zip
j&9I/E aqH4XX59H*@mjR/hp<Suk^?/Zm\!M#je/CwlHM!kyhKywSTRRII:V&y5=FkBYRn:Z^X/@=u?4QlCR@^i
#kl9Q1 ajyhV5B5cjuV=8H==4G=y9/=yw:by1db^41bl8wu>XZV6YXVXaYV=ZtQTuIiFtW@KMmi!Lq*Q!N%LDX^
WhWlc^ =E:$WF#aRJS@Z/lu6=>h8?9FS4Q>Fj9WelSpapXZ?NHE*clkTAkmtw&#Qe1bPhEBa=uIGSG<B:Ihllw!
apQ#?$ F+RCpJ*FSKM$qS9QH=wQNGHP\@5n<@C?=$89Z%hbGemkSnKwCSTTDV?@Gl?jBB@jCmD66i8bC$@&9Bii
^KbS9+ 8nH5@#HuL:RCE::?t=4+J&X%M#WnM*Zn5\$n5+$>M\$6M@Z%V?11y/9LymwKJp8#H^Zji%mR@mD9:pS&
aSESBJ !ul/$tl!:HBC^GB5TH?pZ&?\Y=iQbb9V/abLP<6*KtjJTpYLLQiFuMXkd5DTn8FIwn9CmGdk1B&EcA/I
kK@cDw ti$RkSePRtSWGGyE!M%nuTkWF%HllQXK>TdjnH9wEmepH@6e$JAJaFDDGhSaReFDA9\d?jkpmR4YPaC/
NcTuYy @RHHil<ZhmKej\NX58tjyZ1@Fl9<Xt4\4#J>%8i4CKyeWBl\k:j%1XQbya>!t1e4ltd4^&ad?tj1&&h1
wII1e= /=>WX$!XF$!YbD<1!umau@wkP@H?9hn^8%Gnh<KH+$MGwwQ/\u%/kq\/je#dHHRc#t$y*:ItW&yqqLCE
RAuc<C D%ZMnRKGlGD$Li\EPJQyPGyW!G5+P+&:&pGI+mkEu:tA!=EE4*^$ahDhX+nq:>ZwND*$ZcVB1>nVQ&PV
Fkli46 <HW&bwA\HWCtlCKEbVpkA$WcjpNeey4ER8aB%#I4C#I*1!wR5@yHNqkkN###FGPEtl%^?DH4>L?4hd?k
NCNpDm Kq#M=9kyL*R1Kjbli8q5%jB5*jlM*eCV&w+uXZXV=cYQT*IjFYa?#E%=pBX@Q#%!LCX$JDFwPM=@IM1u
V:Ip\> N<!nP>Cl$<85#i=+k@GG<k&4:pt8nGBIiEM#m+BP$JuMeIJmeZcEQTMCH$YNSVVK&SHBm>^RuiJKw*p9
HG?\\m F\>aLh%w9GQcR@6X9B=^R6LQ\JyBnRCe1YSujn=Fd5KwE5+iAmH#&QhCt?$X%^M&J>h=:XPLpBFQ=ec?
$E$Ay! IGetIwn4R+Gl$i+4RwLHcBS9$AXwK9yP^B6@tVc:*8R/@bkVPb%dPX*e>cSm+EqX@*Sq^%Sb:iQm+peF
<$*PIN &R>#Wl>p^6%Qm^lQCS=N>B?K>S/IhP<NhiwP5P#\9NBthdlBj*&b=11MFXLlnPYiXGc^+eVpnFkcjkTj
#+Gyl% EWEp:AlhDXeB+EIAhDKAVHEmWb\S\y/mI9:Tpuh*1uhh*j>hlQ+9chnMGDI6FuLGEwXMI:9#<aq!+%$4
1*1=ZJ 5!4%$6/jI5?WYF\+9NcVVk$Ty6&nW+NJR1j+?PTYLcQn&a/:uT$*F8DMBJXucLL*MEuIqEGLBYjVAT&#
n/lenE q>uH@/:S@T1>Lw&eTW6>qFa&XhA^Zhw>Xh\!YXV%KD@@ajdhB^u^>?>GnCeHnTd+D5Y+DWR+>wXah@6j
m*t8AL :*A*c4W+WH>C1%S6Xhy!tVCGyCh%PXI@k/+RSIeIY6$=R8DA+TLPVNTR5!QCGRlAhmbS*ClWh&GG4@TK
FRF#R4 eK*XhaddJy!P@^C9<@pic*:5e+bl@8%4hGwalE\J=M/K!*9YQR*Zi=hkqG=&Y%amnE+NahBTlKqbA9^4
Ju5DAl <Sdb8p1J6eCKhcpe@hemuFG>#he?9tpHHRbZGJZ55WhD+c>1*d>4PjXjC\l</Z&l&+@b+jeVM^:hLb*M
M#*m1w 1b@M4b*MKZ1aqVGSunCiGn/Y=D<T=#EW:hkjd6WZdN:nh:HV>XV46b%%B#XKqBV9LyeNFbd!wpt/WTXe
*uqp?6 RZyRtclBkCACuEWSmTA?y#tS1cle1ZSQEYH9FYIBm6Lq8l99P^*>IWd*jad8Q*Ka5#VwFM*V8DQk:$I+
u!ennH l%LI%u^<!*HCDI4W<^kh%QBKWkHI6\YLMhwE?DYR&wQXFn//P@AFXuSyG&BHC\MWeydNnc=k$+H\m*?m
!hc+w\ #HHWZCH\W:alCBAENVm#^A>6WQ/nTtel69>X^$N9eu!?VR5jn4u:KDu:aY4&\+#$mhV+<V8l\M\n5Y=D
QyL&EG WdaDaSb>kXh/jM=$Pl>8Nh%e6%8qiJXC!uLbEGEyd>wKD!w5wX&ywm=W!NtFI8^KadmRlX*JwH<WhaEQ
tkmRM! \BJ^IVNeKDR*G6%HSMSVW5JDTT:@^Q4Pc:8iBJ#<<e:JZ*J%tjMG&I#Bd*u/K4L?1JqFGW%<jGI+P4@V
&ZLjVm Y%G*%#6jRS5CPE&aq5$#XccChRuLjEm9GuWG%4yaAR#a8y<?9X#WAVKplJ:j:@R!!+kucyAAd@MNlYpR
@Et$>Q NWuwQN48Fmi%Qyh1<\Bd!<Q\mE^?#uJ=h5h@QC45RZ#MYGVkcI#QcJ#ZTLVVaLnXRQD%j9?L9X:/ujd:
YQIEA! Y</61>&/ypliLqqCJql+yVh68RhX*B%WHXRSX/wIRP$KPR8:ka>WaZi15AhX%JMt/5WR>SWXDX?=+w:G
B#*C\a 1nK>Va?>D:?I%u/bjP1ZkqN5A%nt9IF?meNX^D#AyWQLCAB:@R?nlp?/ilPFVAWXw8BJDl5LW/WN6&4W
>C?tKy P^:/pG#\Mhu\l%nnHw>Lh5h66!8:4^C%bB6eaLRLHK=9XQJDjttw:9ddD^NP<EThdR?mLISPniCH/RS@
5a\P&^ q\C@bKdhDmLij?P1aiw9wG1t@1#YjX>5<nLd:>6$@#F@!?FA8@F\l=GAt\N?X+iC4k\GuP@#QNXy8cjF
cWW/@^ RKNt9YKB6HTT&Mwk^ky9?uJQt4kuXe!hKkLpB5Z\AHkb\6+mw4:makE4JMQqyPJZ!?X5XY+&*9dI<>CL
QjbMCB YP%*Ycj?YcLD18$JI%p\nAZA$d>ZtJa4KHmMbe/aa/nl$&/cM=ly/eBlaBWylV:jw@m1$&nkySMdZREb
k+J#?? G5WHqC6$T4ma<PAj/JRFL>yQW$$$FBDcqAAyMjXe?>%E&u<n1HhyiCAHBPpl\e?9nk!WJE>8XYGDnLH>
*aVcl< p/k11D?1hQ>bwjM?Y@hnpeF9FShibX5>T:k%/ubt\Nq+JMB$QQDCpP9J4t5:Y*R%1#eyFT51yMpwSpuK
BQ5dhF BT?ZDXwlHTA8=T?&\q6E\yMl=5WR<^aX<=be+TP>IuT%ZMw&6j4VY+e5>*$dji^X^wuQ^h4@16D=C*@#
\Ly5%L XY\XQn1&djP@lHk%XISimej!w>kn1Ph@TnNmWKQBpJBGhlAW&IpVqtDI>Qpj\SN?J8d5NlW9^H8kA5pY
XSp#K1 F==p$NJApTbM!<Bukj:pAI:Sh6K*Slw/kw>@NVk%dt64EXF@KnbALT*A9+GjV$qI<Ckj9\w+wd=by@R*
4*4?Wt DyphL&D:S/Z8:+n?XeHTQ<y$jm*X?/$e/QTu+569<1=>u&:Y+ZG1+9L8Iy%NSRjYF?@iqL>#i?c8Zct:
4pa#tJ h/j8&yP$a%je=m&St86C%hXmNt6YGP*88dq*$9*k$/CnQ>*SjuNQ?&P?>4<1V\E#eHVE#PKH9iBjI\&:
GwIIWE NtF/y1DAhySll6W8uIa+A\!/a?tWEAGBVVlp!^Nc@!^kVk+D\=@i/aKAAnTCJWRiMKmyJCFnEZw=LElw
a#pZu& &XuY%#:qGj!PV:9^wt&uc+j$DqF<jK9RZ:FVdjZupqQwt:VW6kWHy=I5BAT$1GS4M8peQ$R6ccP:nwM#
kl$VY$ VymI>=>A=XC@AbX^/l?q5MJ=jjj5m#CVy!Gte/E*bmI5b/P6b&L6y8Q5H$jbVadiuk+#@!HqCtkt>Dnk
ZT4HA> tPm9?AM=bhBjDh+DVC&p/dp4I9BjNDSEcEXwM19LKiC&Q:Hbm$GNahDm?jnZ+JDd@A:<mW&cjek%pBIQ
@b&iEA SA5DbmE61C58QCwt*E$lYRE5GuId6!udC>Nk6q<=iQP:8\b5>mdR*1EPSmllNEw\5hVSWqV<6jVW/#^D
4M#y5C yI!MFlLeI!RICt^DRaH%/Di<!D#G\bpItapZS+11XQhZXCW<>BpS#!?lQ\X?HD$P1:E\?KnAG\B6@Re:
TbKdAG @<eyJplwSPE#GLn#j<kCmSHFwMcSBLZSXAV/XHkKu<b=q&ew!klBIEiCqBAR&E+q&a5^?1mpA+a:X4*J
8?k1ch NMIZSID=4^=!SL+VnIBPJq#j?nyVt=8&yBk+YllF/Aw@wZwHHh>p+nH6dcAXRkRFDyEEn+MEI\piRQ6m
<#@wT\ PtWq<A<Ib&:P1I%blAq5Wbm@ABXDjRI1?pwXM*@&M$jVaA*B$RTSX!*k*$:^YeauDK8+C=9?1tH/@@kY
bpl=mH V=DMhE1WINaEL*Qk/A\>q$G*\1ClbX/atHA9Q=?MCL&CR44qyK@B/tRSptnyCL4Wl%HukLFBq$wl*\du
I8Q^cD nyK$RyHnHmL6wjALaDRKDkkTDBVukwL:q$F9R*94dn<KtpqI$FlAaCPN+ppl*eCdjmVtIM9TTG:kuQGk
\VqcY\ \CE#CSQbF8y?SQRBX\Gu*8e#^j$qKPTuQtICB!T&BjwdVR</IP@@CHnD!=bJ9m<<ljJ@qY8IDMCnlASQ
pM1E*R we/y<h/LJ\@+8%Vq@NFTWF^+bNp!mkm>RE6S=ijeE^^hLiluaX?bB=hVAi%*>\^yFBlVFLLh5tXm1F$*
CXbjSK 4q:%IPaITq6bPkR&BPp1Q@</G6tFR4=JJyu^<Tu\<e5kjkkRE6\H!l+!4KmbuDey4j1dpNJET/Pekd5+
QIn5W> ITMeYHkJMN<SqRj%FqW8D$$quy=PPn%>=@SanQGniGQ$?@EjJ#cNml\w1+KZLbMCd>n55Cd+:jB$KNEN
1Le4id M4$NPXMm?jmp\bjMn&9mERV?Ct5hP/#idmYVVIWED>n44@8d1<NFua@8!pBY1?GA/JeeA:SHwJA6Pi4\
Hp9L@+ e8e>d:JPI?hIyKDASmHBd$D%RmP:M&m^!@nE\WpH1k+l\h%WpmZS#+ICK$E6#aac+#\ahc+@+q^j^LuB
4wYwIh 1LPb6qe#de%!He/lV8aknINFpd=B>BySd?lbyPkFCkFmEIS$@dnCy^K%j<:YBZ1hR^B!pDZT\JaS!=cJ
TYdMC^ \BM\/mniEG5X@ABuWJYB#>QIW1kB$LQk!S%n4A+5FlLWBRE?FHYItj>XdD$9c9=jpi%GwQdDcB6MSb8k
GZdYSc ZceA@#cPku!%yB!c$tRlA$GBHZTKD!kPRjFMEnyNk$<\CKPR4yGEnIDlee/\Cp$<DFBj?MaFuRSD*^+:
#W\+I* BKcwbA<c=ZcY:Tut?W/AnBPGbBBEKLRt*@PwMZkipKAIC8uw>?t/Q>*V@TtVybiIhtt+k?<B:*tqtP!4
RDQ<Fi LF$kePS9$@VSMVlITQBZ%HphkKeJhpc5FA6G@^A1&ayP<S8IPQ\JPRZR9kApIS1J#Q1uRljPW&Wc5tkn
*1Anb# \J%$dbD*FwMM>CT\bS4Wu:5RILapIY$K/TJJ/A#+CH+SniKG@FIdIWF6IeFD^LIp\&adPI>WbIM\!A6!
R9m#N< yqF<cSS:5yCSuIScj:kl+I^DbuwaI+#TACy\9L\$#8EpwiP!!$<A%N\!P&RLHALi19aY%S<!hIF?#NB>
4ZF^D# FH<cumuWJH:?NTTlqe^GRZ:yWMRb<CZ+=%ACcBT@BQPhd>At!GPiCKlQ<P+AukLIWJG=c!:VAAe8K\H1
=bM#/u >lCRH5C*wFRDBS8CVl\WG\^cFDCipMBi\B^AFlLTBY$KcuIc^R9RBmeSGLMR#+Id^>aC#6ITwa8dGiXM
\+5+?R JXtDI@Q#K+NTjP@cNW@9uu#H:tReM9mV\h@8aZ^4cb#B/cpBlqHlymhjyPy?!/:EG%jJRtjBY+&>8lN<
Jm8?!u >eXh1IFRJBpw$PiqLki?T>Q>Dt8ZA%48CPhIpyCJ$i:L<B^BVyPZYP8#Aky==/AJ+BR*5kYZRB9cP><K
=+@<!9 ud5IFiBj\<?@tp+JBDWdtZTbVLwA1tl\GyIE>WDlRTXjFSVaAMyPC5pM>AlWmk5\BnyP\cY@W@G9cn%p
-A@$4A 0005453b1ba00110334 Page 258 of binaries2.zip
$W4WJj HZMyuM*=?XRE?LYRcRRJ**NdYJ!=IIP@#q4H?p8ek>EZAwI:Bjm*u>l$+qt!L6BVk1dm>eqC^u^<W4Wi
h1m#%6 l@BQ*4pJ@1IR56CFbe8Y#>@SSZ@1YR1WGCMWCetd\6T#V=N%$Hb=AS1C$Bdjw?eF&kV*hPGEK4LDql8+
pJQ9WS *HJwcTGBQaIC?!mp/+KCi\V+%+MKl$!/RahX^#ZAF9\8Qn+bAZ+XE8tCMC&NT4aDYe*HJ$jp4LhD5TQw
&+Eq+w CqwVL5/ES9Yupt:#</$SENkA/luA&i4WiykdZJ^S!PC9PL*LcYq?DkGB^5?uyKX\FECdT&J1NyEy<LcB
b!cRGq dean6jHQSF!?llc^&y9X<E<C=h8lM!HB+B#Q66GbV>IFB+SKlu1cVGmSXN*u!QpC#lG+X#<F&$DPVn9Y
QLXtnT %AL^tIik\CbRZTBXlCVw=wTEVmHVX6dA$lTTPal8WH/AAp?Euk@Cmp\CuMYJuP>cd4jSeYHuHLwRb#DM
E8lRW* +iiVF?BjT+WFn+R%!ntQnjNLA8ehcl:5B%\RPJqpD5=NGtpVaDWDqKD:BCkicnyi%%4dBBV@I?Hc$<l@
*Gaeq^ y?N$&@&MpFph&RK:A%N^84lAtEM#p&<1TY%tjnMtiLREiGRka6PABu&jBBej$T5neN1j$ym:tlHP*9#<
G<9I%R mkICY<E\S+BjFjTMAkI:/ZCB<nbIJ^K5:XiA/KPTZWSwBYVTXhk:<!5RPZeG/8:Z<8Qm#BNIADkPmB$k
hEqqPe K6pieN/y6lw6Ph=m?W#$M#k^6Xb=5^>#5Wdpk!&wNSTtk<ME*B:HRn&K%lWR&Dae1n$b1#5bA>Zld\SG
=kBElE BKBZ/k$<Cd/Kc^*<niECAq1%d1hbu+?Bt5TEHlMZ?C%9+?HFJ8<VpR6@pmH\V\S:m#FA8IWD#mRlHR4b
CyT++* FuKGd*W#1J^BeApJuRVl#Mi*E8TJCK&IR4ICGW+T$q@GS!h!@4NeV*==&FL<DGtRdWC4CRm5B^EEPG>a
!BTPJM 9R16Pnk5nj6bTn\I1d:CF1YN@niRn$<MDQwc9a:niFG1pFK$44j^4p/@p\?nhB<kGkk&AIMCQn:SmWnh
J^XiDN mRmYqKZ>\RlSlHdpjwR84kq8SVKFH8*uYPQZeZCS=Y$CBQ+B6#hC?>wBB>l&@B5wyA5W$t$BjnXRd+Be
hnP<Gi R6JJS%BkD?kmBjm*kKER1D%AqApK:KXVkwnF5/TwFBm#I%M^m*Bt@bhC9mEk5EqRaCj1=+%4XwECmYly
G&1HA< XuVeA=&PHkI=A8qpI?m58yEdi^lTIc<WFNkhb+aRntFcEaBF&a=H/Fc:uy#A$IH@4lS%W%!^in^eh#^M
ibikWH h\!V4ET\MDZP+8nS$VBh1FA8lZEK@NSQWYhiSS8@A4Sn+VYDVH6n6A68ZWXYy9SIknypwW5kl^F9G+Il
i!wVhl EnJQ1\k+k#RGA&%?8B\J\Wcbdy?PP&/n9S/M&eF@@e>8HA1:9H>Q*9+>Pj9&bP@dp<XL4M?4KLtA<q6I
iPTni4 +B51ZAcXWJJY?ITMDh<n+$EPT#>N%Wh?Kke:iDb&NB/@cP8YhEHBZcAaQ4h*P&ykFC@ViBlduC4ka:VV
QN$*K# ew*WNwB8JAS1GCkaekdl*PY4P^SMWBBLk=mIu@\lAq=$DGm@nIa4lt!$pVBBSu?GIA*IyE9A6@#<C1Bk
HpnBp\ B5+BXRiIC&BnPNhB<RH<We=>Aajl^BR!Aj=dIX!M!HZ*?N<q@$8?$*H\+ApqyR$mDNAQLqiYXwA#H9na
<T*\i$ EEPNYuw8:eLTn@#y$^>cYnyCky5$FVc#RWaJl$PNET\K\Ja=klHVdy\pyBiw8&yFIBmnDRV1w8wQaKwQ
L8ZT+c !H>B9Rk%?V:M=Q5I8AkPcRN:^^n@HA9ZcqHcTG=5RpdVq\WF69D^TR5IdAandkd%nkC@MpuREITiMC$b
=Lbc\+ #RyBkbZMmTpM>d<K>cK<mybPw/Sp>Qn^E$BHn=:W%N!!YqabDGQBpQanklwNcn\>y4L6@@h4@l*aj**H
8RCQ65 n5MW<1aHpb!RPRkQa$a>1LqqEEiKWFYZ>XhadwDT/\Z!$?%B=c9dne8HW<?D#*+deldR@k:RD8hBG>RA
<B8GFn wQ5D^Ra!c!E8\K<PkJPFkM?nTCRnECqk\EklPcIDe^ybCy?Xa5/+F8ku^R<8HWXH?!#KGhY8uZ9?WRwu
kk@ThW DbmVT\XaWCQyMXj1@%YeVW&n\VG*dnp!HK4DE#KSMHA9aB6\bl>1Yl#5HuZ#a^8&E*q&IiwE<pdpBhXB
YI\SLE WL8Z:u#A8YiB=!D6aN/$cXSj\JbP<RNIBiA$*TH$@4nIaNASJDPDGw59R%\@1MW&K=Yu@!dnhF@9D$6H
#9@jWa MV*%M\huhIKclS4yE>H$iFwZ@%Ye:/d&kGQ8&*i5J+By=uECb&:IHITBcRHd1\eNdI/j+RCL\wV!lG4#
AN<jGW aKwX$/\j*JYE$u:Gm#dw@pC>IW^LFSVaV!ch=ihVbFDAaBDW@B5EBVd*i=@?Ij=54iQ?1\jYmhNqmLNT
4$*T%y KP4bPBMRnE6H<i4Xb!LuHV9&\yq1bI+cSW*5E*6Lm4?K<?Tn%$kmHd>#*bnFte9MQCDn5iCnG*^&6?W^
A/G$TG I+AZ>!4PFpZc+w:JVdeb!FY*!XZ*mR?<yRbQ&9BiHPFuRGEQB6$$5niw+tlpN%BnMKl^RwL/wJMC@TN4
\5/VH4 LIpNJJtVJNl<XKY9/%il?PPQ9+te>?+=kM=Z<$R>&ND?XRj@??@@PZV\JDn5=aPuiZIttypN5l<VM4B^
aL=Kq^ 1+jP=j%ZeMK+d+q5t%^bcuTBi8\JL^Ca>4/A$y=ny%%pDtiTSipXJCFR6H8Tlc/SlM=STKdIXqW^WC1n
<4#%tW =S>#cIMM&%p#JIm^p@\L@9e4@+EiEPi<b<<BjGtAG@X+>>nZH9#+eR6\&G$cJ4AjJPa#pVP:tatR$bVa
w%>mRC 11TBR&annPNF&Da+R>Wni8S?ehLn\pK$>VaiAKY5CL&GVDISwiZ^<etK$E8FBME\eDe@9?1qQRHMwR$/
cJ>+P& pCRcG=8MTwkh?qwWB\?iJuL?yXS:IhVnR<??>8B&6ujBaYXq+LkQYQw?4*#t<DMHb?Bpt^M:YJAS#5$E
J?N\V! !B!E/=^$/^^%J%\8QZTFh#%CcW@l6H*QA>yQjM<P8F!18t*8i<4>\k:ZhdL:cYRjWH+ICS/qpt%uk5?@
dDC/ki ^kiTlFEpQl@%Ii*4PpH$*?HD=+te@%F?/6?%eCZwh\J16Kl?<i#>%^/<1k4Ync6Zu*mE%5?ayhHwGA=l
D<&JZc !&e<N#k+e=1bC#JK8N+JR1=%lBy*lJh8AhwQeNwiVNyQMN4A&$>BpkVBJHpianL6d#V8jd4+y8XQiQuH
Jhw=bn yH&cI$diJB6FS\%qbV%C>HBlwh@\KB5we?LA@p5+=@*:D#%NP@yj!Q/Y9=BqZBd1E6&58<QbYbPIHtE9
LKEc:8 HmPcSnTF@SjZw@DR6tQHVtmwu$KHK5!W=4a$IVykyeGiG$9pnDwb=V^1d#4taM1p:R^wZ*wEkL6jbNL&
1KVWTa +p$d:TZBYQKuTGd=B\cTd?LluYjiE&lZ&%>Bq>nab=+=yl*RCay\SBF\lwyp6q^m+@4%&+<iQZd\+PHb
$GHGa/ %KN@a!9I@$c&k1B:dAB1bNwpCy*eRD=G\a%DeP>RA1J+$GWnu+uFZwD9mbcS%6&\+WmG=ZEeNa?W^m$h
DeI&Fh <AXL+:t^PPelt<9DhyhH:E^HEh4nVyA&M$\I$W$5T#lwj+?N*FF9E&qj*i@AQ15V\nX>FEywmDAEhRkb
dKRh\I Ln5ckIEumTTnwLB&MPIk8n$Xy+$c?:h!ZRS9BLGbENVSGN6a=EW$P?ewIaFDDQ1^Y<i&\iuRGN/8=pcN
R18kLP y*Runy4D$6!wCdp^aAW91kY$l&\B:e9R*w/Z<DDlHh%wERly\\HPm^C&iy8aJJImRblyF+Ie!6+RAHWI
b:u:L? KCQBCImQV\wh?>S/:pP8L&B8B5b*S\DWtJQDtShG5cGP+tIinc/hCRuykMy@\?w6$@G5!Yh8a^P#ttiA
QucuRy LMuXGP4iY&b>6?EFdkD+wM$X%N/ANt49?$/<\wR>86Hl=I8R5&!$w\F6a@bb$FBie=ZeE=lBXLINui1L
Xabqw$ e/:#*I@8ZCZTBy#@4NJD#W!aC\$nGD8C!>=M#lTTlcDkLn4%\C!!1kJww>QSQL!N^Rkudd?9yk*9#tyl
l#&b*h S1TN&u9aFkpV%N=PQP#NDBNjutF!Bw%8ZtBDmXl+e1dB^>*a<@G6SDtu*h4=B:dN:!@<kk=RjqVwEVcE
n9SAyn LIRcD&$<N<KybAhp@jH+5^T+wwi8En=BkKM#@^#&byamZCWj:>BiwHQ59HG%$^^ijh>>E>+Aacu&hkQ&
Zh6B:V bqWtTJl\&N8p\iaKF%/WTVn:Sk+P#\jT!M+$mm8?a!VFjCi<K\J^Z!Xm:*?X/Z?JM\+=F8pVa:A%>!kK
BnPW<# /ScbbQ^>Pq!ujy/18$Vkm?YJ*^eKpt=#5&:#1=A&Ay^w:#=LiDME^N=ZCPq6!nP><ewE6:jNaZ9<D!j<
+u5EQE ?iEM*y#^*A/EV<yC%u^S^b96?Fe?e+4%>&J5&*CbZu8AKj6^F9I#&k?muNF&mSKCt!IPXL1hRlebIjA$
G@FHm! 8DANkD>Nlw9Z*JGC%>9EwVwQp*M^S*9M9y6ZiwGVd$LcZSn\LkS+D*8iDBL#lFCeQMCKE+:$Xyj^J@#J
tZGMmp +eVCaAE#M=hmcYRubLM^p@QyHi4ee>wAiNINe%:H+db$JJad$SnuCJLkcRGBVb+tl>@m1\da\m=Qp!@E
bhuW/= uN9uC^YEA^d\ZnTAhl>!n^R&+M\<+RKP=+phn#!b^QJEYm\WP*MnMWY\d:FdkDQFDR#1ee:GP#TIE+A+
nlZP$F <PD#6*u%4WVWSE9HIi<EdiXRpB8CA69*c?+p4mC<YaA=y<<VtY9qHNuCcZX&:EQIVbaGdq*lAN/NA4?^
ePVC8V NPB+kDMHP#BQSPtSlP+?my*#I65A@GpWV&Vbpeu=t:Y14L%TBPBt!KdqBT1bWAJ1>G*Ewt9B/G?upt+L
KD+SYI CS=cI*MW*S+M>\anY+LbqlK\XS6$aS$\@!+N5*w!y>W=5HP/HhVp6!<Q*:+<hP9!F+CdL^W+P4w59Z1D
D5T<h^ WFCl=!!#4GLu#LY%kPKQFM?5FjN>cm4MPSQm9G8t\X=%#+X*H^FSS&ESHa*9QcPRdARF6ww#V9&Nnin@
6T6/NT 4GIPM^ic/<aZJZG45:AV*I:*yGnIVGIL9tPYy1PIiAC@lRP@<4YS+uLIpWpahQSkCM\eKWS^?bq:m=$Z
h>YXPt TjA+ei9%HlWX:6qZ\F^F^ueJuCPapJu%SlTYYyHI:wWD:\yP+ePj9\qD?#?I&JGLPFna<#tZ*cHdCb$y
KQmD=< dukm?ZG4T?PYRKa+<NHdq^e^PRceXcX$5XeyKQD>Tu+a=$TEe^#GPj^L8?\mPLbB$plT?KI\eR=&$h%$
bijZnu *J\V&S5/TyB@1=DAn4Hwp/\L&/6a%$Y!4u@p^w//HR5bD5Qn=QE!B9Z<lDY<A>l>K!l8=p6NFdaal*Y+
bNdZaV qp\R5=iHjw:H@5dI^je@w^6wmShCwt1&P$/e4RIn?uaZ$!X\DmX\V5DjA#yPyJDM+N+p:^N5q#8X/*Fk
ZI@RB^ ==lcabG9ZAJ=jFhQy8=DG*md6ReIdY:ta$6n#tq!</8c<EwYNJunmGP^L$HGN<JJeFn/&>A#4AZmcPPX
<wyqT6 apFL+^#PHKyAQ<hl<^/\e!RLuRP=<TnKpFp4FmHZiuNebecGZa>+IVA4b*l=@l?q#I+XZ/bHd&THCN+=
Y\65nX <!E:<+u@qLtYhCmY!ZFaVjZqjdt5*X<p#16nq6Nq<Yp4Xe=pD5a*PT?WG<K$JM#TcG<aAabCRwKH=?QP
IRTPQu MG@ktejcCME5$a5I\/JF!jQ$QHw^#8?a:S@dZy!$le>4t&RBb&Fu5@4ZbM9P%WEE#4FLN#QlYlX9Q4kK
XF4alD 8bJAi/ZXN!h=HTF+AhSl#PKbFmhMT^Yt*RE9<DPLSDyQIX*n9yCB6j<pn*uF*^jJ@%t^wP%^?I>6L*CJ
-A6wE+ 0002b7b2f5900110334 Page 259 of binaries2.zip
=DhyqZ J@pF5C@A@QR/L&#/F@*V95LMPCl+FqBC!cS4bNJFCktM@1Lw4F4q!#?PZm8N>5ZC6E^lYny$NbLTwFEE
^c6TXy BZcJ$iT=h*%@DZt&6PFyi^\?i1>SXFME<TSQND\H>995&F$QPDKZN4Bi@m5=+?pcme*XS!/lX8FwyuDM
Dw!VW/ #Epa=&VE$8BwTRL<Y%Tq>!?$IZqy=Aqy<!Z+SM+LmSh<V5N#bH8YpRYBe!VZYH5yX5SHe:GE1at\JXR5
MRS/wC ^CNEw8E5VL5uVE6DWlwY$tTl1&De:ZlMG=$u=>/>mbJj/E1H#@mFQA9B=*L?E?R&$W9SR9^^?P!i9!VM
^6+L@G lB^DtIyjCtembGRw^!\Lw@HXp!YpB=F#DEltEV41=#6Id=kwJHlMWGDjlJjlm#DCNp=$4SQjyS#HZIQD
6*V:eD N!w9d99Q>^b\Q5J@^9+CKul4/C<J@&ckljnn=GZEInBLL=$#5W=A/:EE=GSQIqSqZ?^TmXNJWamjW$Vw
pkbK:Q BRn1P&m4paXM1WJd&HblBb%FX+Z\dY?5He6S^5lmHN!R#:V>w9D^1$/I5eMJ$+Gy8WYFj^8QX5D+G&l=
H\AV@/ 5HMPZSyu*Ih\pp$a*mREu9IMkInbyWb>DihwyKZ8m6CLSPnbwPwAjTKXdM9Q9@dT6tPQCi8i?EI#c&Wj
h56R^Z *\IZa5K$jVl#uakNQyI=QJ*Qmy%WR!JiHPM<h5@#4^D+j9cG/L>=Gb5?mqlCQuQM@KBPByA#SPn=CKK:
BcZQcy DGblFw$WDGELZ&NFVB+$NLJE/SWm>GJlYyaI9GQMRZ=?yZF<QR/b$Z%I&L/C:<:CX!:a+KQLe^#PS\bR
1lcQSh #I5nMQP@IbmjA#L/nGPmulL$:E5mjnQ+YZ#cihHhBS!weVMD#uhA1I4Re^FLy&DyEeZFtihJEaGFM\mN
wm/@ie QFFGuTmnE4!kW!LA8H/h>LEBc>c5F*MqFF8<\DaPLRmj6W:H&6cC:Y%tN#?YQGhR#6!RF\V4BJ@89WSh
:k6cql &?bCYEBbi1XBtJ!HyWI1El4^lAtK<K@lnQmbWTqKL\FNJmS+lCTpZ*9F9J9ZpmkLQ4aMQW1En!<i8dE&
S&DeRM 6/C:mVnN#+y>Ju>&#k6A^4l>m\6=a5WZBR:I6c+h54S=6uDYKm14*wkmuB&LdL\JJj\+/ATVRi!IM1yE
HnVTti /CWMYyRA@!b>#hMee#LM&&Lj=J#5:dNpY:Md5mYa*>GWb@Kk!>Me@PG8AC!j=>nNnEMtE8dA?B&t:>Gu
mKkWdk lHDIBi4TF8j@aIVCZn>HE^c@F41#BN6mC1EuSa8NHMBbqF+8!L>FTEB4%BKj?Q*C$kdPu<Q<#BX1dL+h
e^6FnZ =V?/KH>tSeiiG$@bue\BtbP6C@Q^N:l?hEX%BtnG@l!D69T^hkm9Nd/wBhaYF?HM&mGD=+a\Na&jZ/Zp
E41lYn 9M/DliaNpIu*lTcBi:/KQ=j@tR>Xade$N&e8!G^+Wcw@eipqI8?D%q>4budPpX<cDLJ6iTKEBpR6DP8Y
tQ:\S@ i&L\j1GK@whQelV=p?#VCQkeAnJhl5@dIQ=jiBIiZYu1=8TQ=e<6!B<W89kkBa@w^VpVIZMVS6t?\l+i
c8Ck:d l$yF$9>4PBNyj*G@B:ib\\mead\L$$A66&PQwnbiCIE@e\/4@>E^F>e+C^@dE8aVCFQEm<^X>uHN!RPl
6y+X$G n&hmT\>&T^M=E<*<A@KE5l@bCSQ^@w\>Kk/X<FipB<@haq@XniI:N+Cjp$mCJn5XtTu*HcF@?Sb^EdEm
$c#RDm ZcRJiJ<C%k8eAq\SNIW>Ca5D>bI+L\D=b#eY*6ei<JF<RN$*Lu*69CnZZ5iRJW?H58ckcBVu@c6WtK&Q
>=hqYE 9E@<QaQ*n?aiQD&SJ9mPw\pI4jAjNkHYC+C9e1PiZ^R%N&e&!LmHQhCHH4Kii^l+^QJ4y94@M<=E%FF$
hmiFuJ mq8<n6+::A&<SaT&P?+E<Id^e=C:Fd+u6AK#Cb!bNSl:E!CnaQ8FtwD=^K59wEaP!+8#CRhuXqb\RZ:9
>nKm=P CiX*&Pw4Pah?%TwMeTXFuP:?\QIp?klSZB?S=+y?RPZJjFj5DaG$kkhZK*CiC&\uA6aEb^h1kpjINQJT
*:/@y> WC>mcTJuhnP#RWaju^y$%Gwy6*>l*?*@Xb\l=GP1b4>lD<Q>B/bj&jZbG?wZd@kkX+/&YKRliLdCT$I4
bQHSGh 5E+ERlPkV!$pwtb@kl+LNYh/eF8ctB5iQJ/Wmn?nh8#&Bc/T:Q?FM<hZ\$4Qu9+hjdI#yu>^CHu8>n?l
u#t@Z+ +JPkj@M%=GkWHt*B*SCi#IdkQBh+uRkV&AMmJ^h+S8VeA1m@b/E?\@a+Y1+HAT@$LPAN56=Ln8mqtqqD
#B\i*^ !9ih^?t@@QWYFi6y=pTln=n@*b?>ZdDt+GkLapMR#+mQlFcAVaC%A8FJiRl6ZuG><QNu#*Ktl^9Hp*?N
!FAK?G *!*/#PX<p&9I4aFC95c89CZBCKw%9jJjkZyj1:<JIn=BHlX*8#Cdk>AYHA*BckZ5ZAB@L@iVV*uGNX=Z
1w>5y6 +^WIX+B\wGc*6PeCV^WHj9A^nD^=T$I+/G5TtE*LlaPCn6\G^Q+:WQh@kIKa?n>jL@^u\ZH?G\wep*i:
p4\ec4 eLRFS$PAp+LnhBmFD!I$BVZ&BNenIHp>b=a>R\nhInj1L#=G@LQ*ciLV&&58tu&n:QFXlM>9hB1%PM?G
KGN*A8 NBkSL*R+6!<4cKtNldWIY*N\NAVcCn\je9yFa*NpCF/BLQ:weAJ1#5i%w/nB1jjJ<@RL=#N?l!$Q1:k#
wK$dPD PLi?lEmKBJ^Rh+9Y6unqc9THu>:@ePHFpQJPlu?nC9lKaV?IHwVD*8B*LhImiQ8C5TEawa@!j4ay/=G!
HVYh@c W+5ci=EMRd6FawARZW%EnaadPMXkMaAWCZ>kb!K\BQwu@<*?%:Eke^FtkWXNFcD@b\CQtQ*DH@\Yk>?@
<?&V9n yD?a$9?D8\MN$Q<Lm6WwHM&B96XBHw?SbeWI$hkeD@BqT?\9GS9QEFc*!BakdK/G1JF\?*$yuAqPJpJG
+^6wqp CaM@u^$5lQa9XM^i#QCjtH:#R@1!yan\W@@!a:=d>LCEhtG%BYkI>EHJ?GNM@%>m=Dp:db:Gj5&XIZm*
EL+AM9 TM^1q19>DZmmly\DPj&<EGSt6edCm%AqeQ8HL+>S#H<kYH8#6\niFuAT%aL=wF:$ciD@Q>DtTG^8a/Nb
6AQt4V @W@&AAH%FTh1h5:@#epbh#ILM6G*HHk@?=\G?kZVJ!B9dlt^m?5dCEhAD+kiuP$J+ITuWjMP:j@9cj?C
$i=$pw $eb:Sy:GJkRIS/jDA#Y#$MI=e$H?nEBt+mZ\@PlNtA#=i1F#KS?SR@F+*91Z9L*REJLH<?+hmaMcXt+9
CJcEwm pmRe*8cknaji+5bGt?DL1LtenEQtJ9\i$:89FQyVuekP@K+dpHa*5kVRS*nAQWe9mSjdHI?=Z=K>ue<S
Fa</ik c^Lm4Ali@1G>JGh8E=KE$>5<cTQmMDbdkLC:GphN<DMub$:CeEB6DQTYT&<IIu/?G*8/Pkj\Zq:A&i&>
N>YaID +Pltc6EbE8Ka@WeMPG6w5+R\RR5TRt+9TJ9D&*<GLEDdl+$&!>WLwWa+e:LFJ%S=Cc:T*mI<cbwLPE?H
EVnHDT D>@/V+DQ<\dPP$@a$y84*5cA5>u:*$8^N/EP+WmTSd!>AG%&%J!e#^C%dNu@BXBLA\RWAAIACAAhXt$q
D&PaYL qHYu1!$jAAC&PAAALAAAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>*cZBqe&qpbYJlenR8at%\
>@iM&L uX9Nd^6uil>6KepFkwBVtVaEFMa8EBe>:GEFPI5Y/IFP=5MHN^AVtuIAdYCnbMmD$FwN^ZeYiDY%6#bu
^*?C%5 D1NJlEY^q@+^Yc!6h\/:e?6Kl&KBANZPFGCCF9*a*NLj:*tH5yV&5l%?mB#NM<@H?*!@D>@=!@>?+5k^
Skw6^? \?6Q<a4\?ni<Xy!YuP@?tZN^6J8ZQb:K$*u/%Q:lk/j\>9uuu?QMN@J$99uG@8GDy@Ctmpp^Mcwa/:p!
D\HDw^ 4^@cQ8e/W+Zl&:iQWthXtiHIeaPmMBEiYcb$a4KI#/nR?D9QcqQn@4YyF4EeYd&wKqY4yI^nXeVFyIyX
I^^A6T 1Wyk%^u\kBKD9=GyeFPi!jlK6MbuuS8eY8lFtRJlDaRkA^hE^K<EQiBnZDuQlK$!XnW8mjDj&kA#@lVb
a*cibh IqhX5el!uTZFbAI<iAP98MjaGEAbenjGHR8#\M&4lSCS%jkcy$RIDERC9CikcR+i%R^jXacd<H=tBnwK
YXFmCD E+8W54wEMpD4HL#uG1l%QNM^lBM4a@d\Mk1IIY9KY&e#VaR^d1!=D5WCEDZ8RQLHb1#%VB=+KnMiV\FF
>k5/Eq \DEj8M*PtP>+L4T8^kYwIX/h#Rp!H8@NB4M\HPM^GwW+9Nqk!tNtk6q$V?9SiH\!$+P^8c@JE9B?YeYA
d>dNAh C<dBIA\G*uV1VePkQ^yPl?<Q@GEa<NEjicQSEPi<$VDAj<ajA*&5e$n+jD\p%HB/G?hHd#$i41@%d*ij
WewSi^ DFi@?@:&*iH%@81nRik>G4Tt\YDkn+ClH\cRak:C/>u&Zij@PFd+>q*uP*k%Z=1nhj86cYAYhX*y#Qt>
/9I:JY n?ucXC58</QjH>aB>%D1i9d@AHY84\jR!lKY*%y@QL6=?<:dn$h**4:>=PD&p?th!<<:V:=%PM:/WP@F
!$>uKj ihJ%Y844V>P9$$@VK$iTSktPTDYH+hNk:eeykN<J^$XbPE+a9adk>d\TGyXSM=jHL/Ed>&e9l:8np@6i
6C5<by +nkHR%*Z=+/n$9F5b#RPw$KyLFF+%%pc#eIY:/==t#$XlpGA^S$NB*+aQHTe6VDMMwm1TIV@?%GckNAw
TQPFb1 T#Ik>/^RQGk\FN\KND\b9NwLAm<Eu+PV8kLiCD#nYE<XwKwwm5Gnh/EIM%4EL?!NykbKyRjtmZN:1Bdb
8BYtcb $\8<i$tTC>wwK1c9q&QXKD%:Ll<H+ZA/A8KRNP@q<a^+Ha5*\1FTTGy?iT&H\G99Fi^P#j*y6D>?+1\P
9em=ij b&d^@BK@WeN5>PR!:B1e$Cj!!S@DEML:R>N%%katn@:qEq/ICM5KaX>XwuCtyk$Fw#$c$<+n&APe&C<8
kZy?Lk <H/jR1c+py>elY%BY9Jlh/1B?NW\*Ic5hHXJ#1FXyVTQ86?CHY541+<HA/&uR^M?k5nHYjc*Vt6m<d+S
qpFlZ# KjluCLtBdcqQu#bEG<89y/Eci+PB&Zd?KBnEpduk%?q/4dY\TFNLwDNY$cj&LtGDX!/CC^1D*/p8T1:9
HeQwZb :!+S8BeX>5J%w+clFZlkLp5kQAG@/>++=l&ZiP$^TS9aTC*=ZqZtM98lAh+:CF5#<H5b4*NjYT/@u!Y9
!nSNu> X@ny=T5C+L$Sl8y@+&$%t4H#?9V1:QuqK%cF**FYQjpY9+:VIAp#>Z1B%hW4kHeN!+W:@q%!bWHHFuce
8L$W?^ 91bbZeH4EC>YKltD!K6+*:C\>%@#&&4$?WLT\L5iK9Q#C*:9ybdS<Gpn=\6!XmeYd:T<+ku+uXLPT*:D
Itn+N& >G6L+jNG8QSh%m+djpNn5WAu*?&GPlN?=e!%NLXaGqwXRJ?Q+eER5c$hlcQt!t&u>eNBWV\G9%<*iC%5
4=T$D8 $MAG!HT/4j8SkiQ<?\c9YiL>I#>EJuDBd>kw%M%$KSJD>kIpH?b=w?EY9>y&9D9VDQ=1KihY$Gl$i5X6
EX?cWp PN=5uqk@&Yw<+L%H#t%a#iREiK?8$W:/>H@b@w54J+C*hYe/Kjih%6?p#qXnTL+F1/=/p8<a+XjpjBZ9
V%Q1Y4 KmLMXcKSH%*X=$n+4e*5&*wXAQd=XbIScK/wJQB?:=%R=/?\9qhkw#SKQ@*BbdSSyJ>jaYG!LZ1X@RS+
a$w$AD L@MLy=Ppq#qia^d/>=i9$QC^h>dDk4:>d!:lZa<p>L+GD1Fi$jkT*uXqJpA?QcmyG@i?ju%QhSG/G:YZ
K*LMbq 8Q*cyFdHDG&P<&R/K$1edcYj<pDwZ\b\?$jNhlRDG^:yM9w#uyL:/jRkL+w84i<mVcB*S$^TKtGEwVwc
-A1/V/ 000b33867ba00110334 Page 260 of binaries2.zip
8^CX^^ TY:^=LGuB@w?lS/GywnybJ&8Qd!Y9N:y98M%H:@ddd&FckZ*j/jd\l<?lPtyRtadtj>QnlTGY1qK%=@@
<^9\nT @1CR6WHTZYdJ:=@aIX6CMwyTAX:l!h??#=#4<cN9Q/i*iV^?QLy>eV\i4h6$HpYH#uIyI&y=9*^R!m!8
KXn@FN #ASb@WZlyTXHm%AGkike>SETT*!51t1SF*nKF>A$#!w>#%uqFDyBXbRIPLAtiJFjHeM^wjDBJ^a\NY5p
S>&ukG pKD4Iyc/lAWMc=h5aqCLIISqp9ayui5ekCmheDWRwD#D%SZjeG9WR=yiptWTmmX<*p5Kbu4kBFWLeJRW
$L#K$& F?E%iEaXSCLmLDckaMJ1dW:YFcI<!1SI1n&<tJ1mHNSp8BR*VJ\GN!Hh5c*Ea6bwp^ITR/IPjk9!twAp
Wbw1k< 1bn1RyABR<&C4=K!pC5ALDl9+yp6FIpMFJBn515wcFA4FPhFI!pI8K4ppy#XL:lGTck1pkEyJaYm%JEZ
9S:kiP L+nMWFK+5mRw#lA*!4YMNYIF&5p!K64mI^WZqqYWt#daqEyRFd\l?K=ahbIi5y8\@wY<qBVkyIXcR?t#
u1!$&u tw/q<ncX1plDqwtAantu<M?cF?Heam/Cwi#GYGc4#&C1%Flc1ZVQa!C9Kqp<wEaJdQAqj\mcYM9QLX/K
QCad6E 8>BTd5im9XCL14yRJF5iK@/4L4Y>SIRNcqD<p&6bZYIwdWtj$:BWGeem:YSBE4E\KQGyi6BMLbyCC$wE
1$Al<Q S<:%BXjCF?y=Y>cDV$En?p&%p9ZCcYqKwB+9^H=mpVXNGX<l6eI8M6m\6%=Y?SWka8phFLd%INl1C>^$
X\ayHS I!D8c9GStDC5W8\a?K4+N?AbIlZMH/pGS&Y:JXkuaI+Fb\I#L1E#P1GkFctB%HGlEDQHT!\tp=aFNNPI
N6h>?q pL?5LeYbYBVw1Gwn<wjcGF=EDRehIqAcVQ#QT!Gn#F9pttl%65nlWlKT&/\B&dhLCFKIRlc9158DY5!a
PmMD!? SdGT!/4I&mXQeJZy%EADqd1SwkmaHPL?XYu^+4<uJ!i:1CCBQ1iqtT@y!/!c=#GSquFtdRjk6CLm?JK/
*IS^4: iHLmVV%9/MQWIQTcq1c6B6dTwIqyY*SRpGXqQZWl!4#Ri\DE$S@$B#8GP4HAJXDCYFRRiABWYJ?^\H?n
deHGmG E8dDV>ZiIPl:QmAB4R@\\LqwwT>eDCWP=e=LMcPpK1$W/by@PS$Cd8l%Qh@*#i/lAAM9cBhJEIS8ZEeN
1*IHVj 4=F6EZG>BwAMkHLaHj19DuC\u8bK5+HGXcZy$SuK8ppD4ma4MBbm>i:/4i6p>+E^9#=>?CPFKIB%4k!6
api?k+ NBc<eeF%w&I6SK*FYF=/#dFKwk>PnV/M#Kq1%yp4H+94mT*FBj6/PYJ^Xy?<AqVZY\$w1H=@^?\<QAY\
kVbF\d P6YA\QJduakSnI4cPqkwZ$pD14LSEPIF*Ha*\B*<X\@$\iFlekmYh/uD%HC8IwJCSpJ!/SV!4yWt^e\#
K>5E#D bIECd@BAH&4%<PHy+cHEy^!mEyXCWKln/R^K@+*5XJBVm:\GLe>9hZ%@h?jB+iGL:BA=#+6b+=lw/>V=
GtZqCB Rq!VSF^/cDIdiEN9=QXd9E6@=$haZdJ:iu1t#LqXQuyeYS^V&K/j4K>FK$THZS>mB5&Hl?4$nMWKkKu\
yDbVER ES$&Xb8YAc&CS4Bl1AHt6da>EdZ*n6jcijZkRK9VR?JNpq<dPt6Gb#a$e^*V6$9Ia\wHwB6eG/@qi>AN
6S%EK= +D*<$THqhBaqb&iy1FiX&h+8A:?mt!9bL1\<=HJp8GYXw?Z:YN?hW*N/?8IIXJ>1CwyP1:K8ARwTRSY^
u/SeQQ bBZ6VqLDAI9:V4@X>*biAi*P&WQ\jHb&iySMK>l5^W=yLY%i<TZ5nGa9bYG>lq&<Ai?9h$H#aSSBYttE
a:BZ5k bDVY%q&JA!4FC%WIB#Ma$AA!=l&kY@=d*9DB:w<PZ!R9p6N@Tw/PD1P#bSMdC\^ZwpY6/NZ#q<J8q:VK
uwh=/G PpFWP\>*Dw+PD+?m5$Qp<piSGYamaT\\I4$S*<5%MkNl%!P*YB?B*@$ucBZRul&tb/Seuhlt5DTyEe^+
@NVKhm u=#^hCleE9w8@4/LSjLDl\?nl&hu$Yu/MDyLD>u=bk?cQi6TG@wALi+Am?5QSVG\SL/5WjAAMn=Lp4QD
>6VyV& w@R5Pp!PEnN8hJF?R*lqRqK<FLS4bNS:T>/l#lyceRcKV+?m$?SI$Z<\QNtae*FA!kPBlkY5WpE<8K9h
C#8Lt4 $>QwLDqKZ/VEZpV\F%ClGLykqHmwmp/w$tIHR%DdY1PL:Qc>:YCH6VeaQaKp#/IZ+JiNb!cWYiPl/AwK
#MGmp9 I*^i6<VCS%LWjtlPn>IWty\e9WkPw%P4>qEJdyuSJk6JDtFDPN+Tdi=&:=L+RSn5Hw\nAKiuWMmn1IDZ
<LwpjG WmhWy=\PY=aLc/#mGSD=u4i$A!<InZSTj^YqS$jyKYTGGt65>Nm8d&WDKc&^lJn:NN/B6#$p+cG9YBZC
ycA6=n T&FlIianhZy$IQ^YNu+Wqc\Pk+1mnIi6Bm*i^%S?RG8XHpG4%Npl1iB?kc4ECLItNEB5jRG!8nZ!%5Nq
dq/Al8 WbkWD<@Tl+eSe&c6>taD1^4e!KpYYnGnP^kGELJ9A+LulTkjE\9<RtGNEnw:Y&bIk5JpG*K8SM#b$55N
b&:tBE jMc^\dIknSJNT#yWEk:X*uVWtGFqBHeMj#WV&X4n<:5Dw>J/YhHC^^:CH/PmSSIRG8/tEG>mp^cpm!ii
e&t\!9 H<DtA@F$I%?a4cPej<#P/iul#8u84y=Py!b+cPM65EInc&:pVQ8p8R@D/\i?F&T!RK1RCq+n5LCIG+VG
<*8XRq H@q:Z*L@T5Y!9RT:$A9hFXYtc9Z:@kkk&jP8N!=I<<GlQn#a*b&?<9y:k=e$I&ytTR&Bi%ZSmVZaFle=
:YW?cK /G8Y@eQl^!hFLeAHB!aeBRMVl9:wutVeCPXbZhqaNmKpyDc?%\@9aaE!yEqh69GX&h%=Nh$h>ENQ>$ji
kJ5\al H5M9<$&t=A#kNcFcnH?Rq?<S:$?eS/nQC<ldl@&yQ^wF@bE@<1dec=PwLXGMThPJYH9jF<V?BJS?*tXu
e<l%EQ uP$GA+@J%MeQB9/iD:ew\WSVMTW>dN\=/B+G@6CA#/hPK\kCA?Bbj#45V&GTQt?5dcKj%bJR$jqM5V=*
cpj\E% bHXDj#naAeV#+eiBN<aT1XhakTHJpY&w5Cy5\mpqG:Q#wVeWw\*C+Y\\*cPek=h:knchlh/$:\>BMiQF
<JGYKm u1Ti$EatK4^H<ZIKl1j?eDSWI#ZawS&ekGT^Rk&<w/H9\^pPB>+P<#4+6\\PA*X*SywDJHQD+Zk<ly&i
9c=#PJ GJlB+k**^Ay=T?SyRRBq>j4tT&c%kGe=F4Fckc5dVkE+A&T1HmRJdcERY#I9y:+*DbBenn#8VYR&n^aQ
M+thj> Db%GTZ$CEn<inIAXdqZ9\V6b+/@V</EjRILiEt?qtPwkCM%S15CIhVcTVWVFdbn$#N^Lq1aQhtEhAXmc
nyYI8$ Iy5P?kPhTY+Ve>NW/1%a:?%>jALHLT*aNBtaTL1^kE&tIVMicE*wlcCd@qteHdiY=/\W#Jl=ieWhBnlp
ukuHq9 FJy18XQ^T\DJ48MA\N:\JW8ZZGwT4cS^W5AKaa#Spp&W=ADP8WM!y9@1?*:kl#DQ95$b/Dnw@idI6tDb
wu=?ZC %cSK5w8iGc$/T?EkkBd5?5MlquB\j?RFFm%ihau!pKW<k=VK$w!WYlElAKkwuw:w\XyVYEN@APS>w9%T
<t5M66 /kdyXPVMyBHQpnT?\J8c*cuY=lX6lKpL>B%LlR?+4yLKDZVD!^hEQ1cKYhE&uV:N@hWtZ:44VWhA&l>P
?ZBZA4 Yc+ptZR$&DCwIucI/pK^9deEVyT^tbdQFIVtN/RZ9A>nL#X>iy=#9^=Gke4L!JcXBbS8a#JnuBpRGuHX
#t9ISP y*bN\%BKW%lStSWZyW%X%PV&k8c#Rp@Fe*dl@XcS^8CB6VKpqqY#B6+<Vtw+Y=TbpG1TSyj&NEjD4pRc
LZd/:A PpHti6NSGLBEb9c/mDYNabHbBp1XEi$!@CYJPcEc5uCRSIIqF#^bW%euPwuAcXRSQY1$P5p9da^G5F8m
*N8+pb :jyht<yD4$b:*QcZVw6cMPTZnKbXdmd16bTQWmndCbju8q$q<aT?F$Lu6R%mTXR9pwR5=:mZ1cN$cZ4R
DGWVGW 4tVWXDwInMkTY!*wBpMRQV6:hMCLWyR4q861EpY%BWXTBIXDPG<>c4II!h4<aEicVY!M\K*uhRtp$H5<
I8=Fk< hT^LFFqSydPy4aGSFdi/\ddZGu4*yZp*+/lDNteXDjY5F*tN?w:bTW%k6w>%J9#iJhW&WuW>NVc5McCT
?u6pql dPQXNaBkW*Ybt><c!SL+JN:^1NENidXaM$H==6LLyLiBT8VRp=yhud1J<:J9#T6iEl>4!:6N9ndDYT*b
Bd8jIi JMmcA\\aWWyV\e#C:n!uh8NwHBD6hmM1w6e!V1KbcEtLy!!VM5IN%CKy4bSyVQTe&yi+&l$!F+hYl!HY
ENFB#j 6u4ReeNClqKK4*KARF=XHMGYFtIN*FCFpmM4qkTekKLX1M^X#*WeSDN+PPC6^QN\h1R1<>S/%aRMqRdc
!4XC=y HBC^JH!?6/NWBhAXl/+%W?h^Lk&98wc+wF&qyHQWVCT<M/tnBjehjwDJ:496FeibVKT>m\I?#\</HZmD
PNc9HK GQ?4c\EGNbE!L/XBEpw8Ae?l#4P1I@NIEFpH+RT+/KXZP5le<BpWjCt/4DI%%$Hj/mKE=Z5HC%YV&ZbL
GPETYR K>h%/C&kWMB!:ub1cZ4DK!Bj^mJE$6NbE!9E&*Beyw65C^T9Sa<B?l$pP=A8jHXh@I6:uV$i?I?KVm6C
HEh6YN KaKRDDXE4kDWj1CVSj\MRC%%*kH&N&Itbn9Ry?14@Ju:Xl:#buGeeK+lKteu!=VcG@/J#qHb8J8Pa>>Z
qkNkJB 4qY\ucy!d^1&jN*&iyp#6aTc\BJtMFT+Gb>T/wj5<Kt1<=t#SqE:K!*+<%+NAjh8F9XZic@64Bhq?qXi
HY=J5? =4dXjjJTmujpN?PaLmp@\N4YFWHj#LQ>ul6#eh*4:$Xq+1++p*1SXdtCbhWMFCH:FWE\N8^l%PZ?=51d
PMbCYE knc5Ve<>h1EScwF:9bhW9Zc:Ba6k5^FJED#B/GVHH+WcPk9NAVAwW*!:pSj:AN*WaC?1>>9P9ZK@:dd*
XR+^#: pK=X=IQPIE:tTRLXKhlRk^Vh#^\5b68Jm!>e>\>hl:!Y?k8e8ji+*Zc8EZCSp#5FH%a6<Cmw4<WClDt*
c=d!yy 5th6=%ci8c/:Q/u#jji>6CaqLiY86B*EGhBw<kJLXYQN\Q6Z#G1AX4uPi=Bw8%y<$9uM9diI1T8Bm9el
M#yW+b 1FZA4p\185&9I1laGW8pA1h^^VdpC>jJC/^pqje&eX&NmQDMhRJ#:1/+D9HiK?P$n1MTapkWYYe6^EC\
=Ym9qI 1Mj6>cICduZ8jucDBw<KB@R/EYDdHZD>b5J&EuK?uKNqXZpA%6!iY=hy?cK>Z9?<6+K%eq*eXFXaqH$Z
%/9wmh 66Fy8?=G8:&!j8:K%Vek:#mQ1u$A+klB^lj6N!Hk:>Pch1S6#Pa&XN6^&>hhF+Ji@<J645/p@j>#%?*\
uZC&IA K+L>RS8XZ@6cbX#*4#WYpQ/=\L?eQ&l94IBqy@WMq*c&+B=C&HMF9HK5VMy5*6d^Qq/1h#P4/XtyRRj6
P#R9Z/ Fj=:yRNl4^&+Y/T=:c:F:C@68%5dL9S\BlN4V^d::d4/ld6i5djH9D@:AnA4^A%hd<FGN\DeZuqD$ZQ*
%4Sb88 PtTl+>!KJ&cqKQc9+*b6&Y/kjhR%qcLhA<pR?Q1?<AeH5X+ljT1Eh$kSJlb9X>W9%111h=*ilj5PeI%q
V/HX%E ^!HXn66#&t8<8PPT@DKB?>8T4&::Xy#Nu&d^jylq??9TYm*uiRH4/$EyRC?8h&/=uW$TDd^5<^j+9Au+
5#EqXL >p$+%bNaQ%8DTh#R?R=VHcRM!YJ@ydj!k*c:DVujI<Hp%@&P\R4H\t@uiH8NKhmpiH#QGFjZuDE5=^PG
-AT$jd 000b1ef347000110334 Page 261 of binaries2.zip
=?tk5! <Z$wSe>bhhdQuhuP#@aQj1^?=1+/PSPyD#:<=Gej@QmV+>YKKZJ%9k=?FR!5?G5hM^JXZ:Ty#C9P>?M<
S*&#4+ ?eai/u54?Eh8t1?@c&pw@&<#hc$\:1LtV8ZEeLM^i\aDAm!eZ%E$F:?+@bcCC<md4@@?9Sl+p&L<*m#j
?IDJeJ XnIqPb<L*uP5$Rb\9\uLcT:?!cDDku^=1>>NM+dJc1GKp=9\#GPIt66>^P8+&?+QX5cqVyh+j*kDiyZY
D\=8NY T>kdMVQ:wllZKkTk%uMA\$PwL%c*X6\*=p>A+><%F@@H8?>Cc^c1?j4%HSSSNjF>bEdeXME>CFwWQ/ik
V1Zp4B dtX$W=<&F@@uuV6MSbbpjQQ?S%4Q&Qtc#\>R&<\%WtmtQQEVL8kj=+#pT:#@@tRjVmXi<99ND*hm%9n^
m%al@G QNNV4C/5/cCKaqWYh>*&6wPMNCw9cQ:9G?>#iT@\:4?JkpRu=&We#^B8IQZKTQI@X^?$N%A$IKXe$9^j
XC!HjD h?+k8GSLYZ$#*%HXaqJ?yLn4N++q&=p$$:$=CpF+\#ymHanH5:>/F^qd#ZSJy5H&d!F@bJ!ceGeXiC5#
=?CWQS ^lLDEq?\XGGFcN^NieD>VPFZaN4H:9Etu&HMHc9JYKbWK!:aVKb&PWG4+Bmm<wY:QNyPHyiM%5&^^9cu
wPqmAB =6k8J+due<Xh964YqbtM?++8\W:K6Q4m+951=H\k8@KLcnLljP^M!/+&FBXKByEjZIKN<%Ih$QD@\V*8
^hS/>V 8T9MiGe=5AH9I8cRwhISy+euh5emi?dCaQe::keh6@XSERuiHk%/c\Y?ApVDhbaw9MF$dQHTRBD&+JFH
uuw!6M a9kd^$8<@?y8@SSPl>/9d5c6hSL9XwYM?#K@m=mqTTed:ulne<p9kykNC=B%n*k4ww/#<>4<F6uaVBWR
9d$pBS &F+t8/6RyB:Y^:yGy@$i%J9<>:dE&<pERCddyhBJd5i\!+B$NnIjwXk\!pcR*p**k#a!#n!!acFHH*aQ
V9%VM4 mS9VPP/nb^YWkuk=1p^bR+Rq%YLD+uY8RYEkJ$5$9G#E&MXWtX6Fqhb&m\I!Hm68@T9*y49XEZp=K?<l
R<ZW%X FBL9&<i+Zei>lqTm=8a+<AMaKiTpbKiBh?CM\kGRdF1YkSec5>WlId*P5Zl*y1$qB=h#ZjMN>l\bFn^\
yy*+yD jMy5Wk*A<5&&$*+D^tH%SBl=A<EQ8R<!$l^JWBduYBp:JpF=A&?nXF9Ei\9$YEe9E4^YL:lB9TDl$TJj
w9KK>y EL@MDLCJnSeD&XbQLq>^YuH<CcmH$D5d^^**L:LcXpQ5+hbXBG&R$p=ewNH#F?/jN%malK\*WhDm9kcQ
byd#NW !:aC=>JVbpG=nDeRWNGVHXk+q=KF?>5uGAE@^Q56W#QR==\%YLB!LbZhcbD=?XIbCtcL!:SE:@cPP:D<
RG>@l^ #X/dRcP8&DNnp5QmSwa#=Jl#J5V>eKPl56hbY1M>+>=D#XyIy5a8A/Rqt*&Vat\uWkS9#!a&G+$!<99Y
%YT5Q% l$li8BQJcaqChAQAtj^akF9?E@pN\&cDm?AdkN#wYK!>j%mbWDiAh<EbnnmLm=wP4NAN%WyDi#h/t%6+
5Cd:kV dwwB&H5h$@ubDS@aB$9%w8S&eCNtXC5V?M1iZR@14*6<@KERDS?!hd!%dnica8/+e#6pETh\GVIn\y>C
Y/hnLa wQb<B8jp9u$B9pF&N?t^Q45J#b8#Re=55&KHL:id8q4&t%GI::5Ntek^ju4MY#BV/dnH:Z6G&Vc=wSNA
yZZcMc pPB?GSLT?BTe!HmP/amIG6LjdpS?@NNNX%8N6=$Nnubw/lX@$<DlIHFtT!Z<$P&Ij4u!h:P*#1u#VH+<
YG/qC5 MyGSJQ=p\&+Y&Qab5NQai<eCj&^%SEn+dJ$hEcCXH%F\8AXJB<ewXG%9\B4?&abR*Y6MRCA**S?*Pjpj
>E=9e5 &dpkPDjDGGmp/LihdFbK&ZqDNNQC#R?YiuK<4ldEbd5VdHBpHNmVSwuh9BLp%q5hY&Mp@d%n$HGQWJ^%
>$Nh%b WZd/Sid8J5*WTCZiN%haaT611KPqt:i/8bjbVRWPe<n9XYkB!INuZF/bnEAtkCyGyG6b:l^dh:YuYJZE
V9d/nM +64nb9MZ9mLjqbpnS8=aN9:EJhMCn6>&GSFkDVjqS#1&&T*Ym1he#<EeP^BpJ\i1*t5@$/kab&uakFYT
!!qujN =5e!NKP+STn#ch48XRnH?%clYHQA%aMC%W#SeF@NELhMam$+atR6q\#LVEyh$J>9L5Zp>9=SL#i1+GS?
/ub#M# \!/=DA>lqjpdu&d?^an5m<Y#yj&LyDc+b^L4m*%>JX9<5tQNFwtSRT8bMyNNk@*iSt@nR$KD?Kn+qb*Z
^K!X*Q +W>*KtyC*E#9NE^!=MiPuHGiw6ljmtq#k#NSylpX1yjZeHkFibK54<#Q&XE*YTpGayVHYJ*Z$%lGk1/M
/VYQ8& !5mpDLiiNJYM<*NYKe6tb8eAA8=EMw5n+\=EX&d&uV9QP4E@AY6G8kR4j=<qW^YKCenC@l\1a+Ipa$8!
CE:=?^ +XXJ\^*Sq%w%=9\eQAjLi8:iWY6L$X+:p:X5lXL^pc5dd5G\\DH5*e%q9I$l4Y^GpGKaVWXu@K81aRcw
9#wE+? jpQWXC+hW!kT9?ieFt=&TFl9=<JZXDTnTkn#JW*kjCGw8jQKGWSp\e&?Stc>*aY<bI!qF8dFqdG!dERC
Z8j1CQ Im9dD?a>%HLZuddG#Z++pZmy^Zt#V!X&qI8+bD4PDwX!RyA@JLN:*=^tM#JDKZNutS&Qw8yyXb9quE:M
hKQpyc 8eStSQD!pi>KEWy<@=#Hh8IKVPZeetIDYeb/a5QpTka^GRwdt:K@4INEF^!c?yXMFM188QR$1>yP*bu@
wY#\W? AXBLA\RWAAIACAAhXt$q+XNkE6AwAAC+hAAALAAAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>*
?FAmH: cZBqe&qpbYJlenk8at%\9F6Nm?NIp>cCb54Y$t=wH>:nuKdbNt6ByTAFZaiG9Y<jCpdN!tDj>ki<LLXL
h#\GZB FhmDBPZj5Jj8q=1ZHyAQhh%d9?hqLkM?N9Rj&Gw5$S+j>1B>ImJVH:d5/nu5yBT!$8Z!p$>EbPSH!Q@$
SyhbHS #@@%d\+Z:V4PQ?D%Q!Ad!N<=QeiYb*<9$m+@<8u<?KP<$EF9+jK*n*>#N9@>*5qinb\T+5^G#k?RDFJC
\M8iiJ uAZ1pA^TRy^*1EM!TAq^Q1AP!TAq^QtEPmTDqBCuSB&TRW1I+@#AS\ayIe=*1EE!TAq^Z1EP!TAq^Jtl
NXNKyy D5pkJeSbwA:JICZEiae/JIPWEPeD/yAMWpKeV/lDMpkJeW4WIStplPAL$awF&4NAi^bwD?1RDFJCuFiw
B?XKnS R#JICZFt1EM!TAq^F1lDMpkJeh/lD5pkJeV=kDwpk=RR=^Q1pA^TR9BQcA@1pBLm5Ga!Qp1I<^*1pA^T
*jqRDL Ry^Z1EM!TAq^b1lDMpkJeScwR#JICZHiwR:JICZE?aA/JIPWEPeV/yAMWpKeEuXIBmpln4NGi>bw!S46
wBQ/Xk YcM>1EM!TAq^Z1EP!TAq^JtlD5pkJeSbwA:JICZEiae/JIPWEPeD/yAMWpKeV/lDMpkJeW4WIStpyH9Y
%RBIQ9 Twq&\H5kGcTEPK>Rl&TRE8LMWIhppBLmLFCHbJAT+4^DHbJBTwn#AZXIBmpl#mjWIStpyQ5T>=D!q%<k
RcuPW/ iC$D!L>C@lQ!C:pS9l@YE=Qm?%GHbJAT+u^AHbJBTwn#CZXIBmuyHyBbTZ$X@RYTRW1I<^*1pA^TRl#$
LPCNKl $S<kt@<6ud@?=T@el^*TB@$96a>4%D/1qw+P\%DdR+hK1%A4HeR1nQRd4XAC>WdlnFRWSIFTJHVBb\K6
\KjWDL Au\/XIGtI$Rq=B8FY@:G1nS81R^DAnPajAu^V@TQ>HWEQ%FwCl$EB*\$BY<Bm1F%BGS<tIFS^*$IcQ11
>>LXep kP+EV>hwJEQ#ukCdC=YAlGAJHDB9tC+\eGZ<WJttBQIb!%hV1+p5kY4GD@caNqS\kV?>6LDTFwaPYiil
5a!yA5 NwVjRQYkCi\*w9I*ty5tZAtPYpKMNY855\#6>iXFTKml\YdCwwFAaM**Rw91wATKpjkVyB?DTE$ITT65
EHSl%a M!&K*>e&pF<C<pLZuqD:GhG&jB<4*AlY9jkXq+DNHRaAik1$Yk5A^aY%jeFR?ltjTk?$?k1$a&WkB%V@
W&A6cI LNBQ6ZH#ajk5ELaZ+eWFhI&VaJ@yRi6@=cTDd<@XGPK45V@\qcjwmwQiGhmQXYjZq?At$GLmC?J=eZFB
4CY?d! mu/t/Y?DJ\M18KwuA@?Jh+:D*@4i&QQqwH6e^u!6*/c:dZ%YBdhQQG>A6@#FTlQnC!1cCY6Nd&<H?Nm&
4b%?Ze jbmVT$+uDnpd^:a\u>5:?PT@eBWRV*ZI8C<lj!IhM?TnJh@?:tLdZVC!il1Gkkw6\=Y&t+*#FiY4QuV+
LLSZ4S Z^684:5qhahD%nN=qud?kGLaD=VaF?Ze?WMKHIF64I%>@!BaBmdCV<Y?L/$i^9?+HZ<bd<i5D%#HPX%j
BiKAn^ +DWjd:?IC>Q4htQ>PK>hHBW1Y!N=@wW8G#:\GaE+J<eiKNE!8<4Gn%j*>?5%CWwQ^&4bY@jV*4Kj>JdJ
N8X?bR Mp*:@X%@N$6u!T!hyqP<VKi#cV!N1/IlCpipa^:AGtX*K$wq%^wML9=E8A!4amA5i<9$hwq9*/Y:YVJN
6ABbGy $nlJb9N+Ny*I>$@Mq>PX9/:^=V:Ew>kpWaKDBu1P/*q8ka91u^9j5u!=:5ZL/bu/Rb&j$iuH!T\SRuHM
L@VmJN \yCY%9p&b^%Bj=/F^a*u1@P<Km/FDK@\ewwa8i81ujXy<CZ:584X4u@YeAA%T<CWCe?TiD/hYPSbQG:*
=ph!qK +N##DX@E/#l9@kGwaF!A588Bep^At/%4?Ry85t:k=tyHjIGe^6A^E!a%V?N^l=QYuPN6C%jmhI+DXuZ=
1*%hhp n?#QA?=H@Fq@&icd>HeEQIWDJVE8E#c^/w=Ykk#ii:kMY9AB#ty5Dh#kP>nuC<jc\ZZl8ZFKhEE+Qh4Q
9A5YGw DiX>9p^+/:G!<bEtZ&6jj:q8<W*:Td1dEtHlQEum&au\awDd8D/nEq8QHF8Q^d=d5t>w:Z9d=u8L#yTm
L+!#FF 6^LlKd!J%H\!EuZkdq9h1YA>=^\+KEB4!#h8<W%&6>!LRVyN!L&T@GRIhBq**NI#bkbd$=8kckFCaAQj
dK!##@ q#ZjXa69Q$YATyeMQTZaA?N8PnS>1GjLN/@=\5AZNLMV*PX>&=>*bFn$X=kb8wb9:/6%6#:d:G9/$J>N
ZqWt^C kaq#5Y@PA!HNuc%>+<+BSMXRhV4h6j/Kh>GbX?96Q8/+/#6!/W?/+58#i?H44%y<Y><*&<HM&#*aGCQX
hRZWVm iW9*Zy69&\lR6l+d?*wDZmII*>:/:JnL?HG/T=5/XZGZh\N*Pn:t:qC$&Dhu94VI/dJ98\^k+baGEEnP
/+bJZ* 8uCQ<TZGleSu+QwDYwqb9mh\Ed/Tqy1yS*j%yKN<Chnc%>6m@w:FmPC8V8A/*1#FF$NVe9ny:Tt?\DX<
La/lF* ci#Ewn=Rn@MF$1=FH*#QP9lGJ@k/dm^^Ew^q^mC+/=P+ck<Z+d4nR*4T=Q5@i*@Y6X@SXpZW^Vhi*dcc
kFbF9k +jhccpjWnL9$*PT:uW=*=!&hYV&QjX=4=wh<</m*@4XJ$i69>k#e/>FWwDGy\+R4T4b6e/@Qt@@W$QME
u/#M!J nI&ij&9m/6X69>iKt?M>\nPM!>QyGL1%&JF8<e$^EannJ8/=+d8qtXEk@Tlc*#hhN8/9%5&8w=b6/*8k
+tMy91 m9BN164T%>Q<Etjc=19$AX?cZQ6n&wT\@9^4c##1Lb8SecQT*pHkXudYk/GIJ:e1d9HFPn68YCijnT%j
JGE?It &j$\>m&dnLA?cBp$&1*GJ+h>Cqa/t4aGm4\%at?uqZ%>*uRS99iu?6E&Z9b/n!^>wG&huGmeN#X<e@k#
5iBuZ\ AVP899>%i9^@MJ%i49@qJK=QjNQ61ZbX@ZjM?&15nim?QD6BN<ECcZ%K$^kcJ:HiHej%B=W@C>>K#:9n
-AR&D> 0004daf972d00110334 Page 262 of binaries2.zip
K^*E+W hBP5tyLi?55JYQc5*jnE9C?&iwb>cTiWeiQ:*+:!yTXdC5c4w+!bLj4TWV$D%nh<MiFRVd<1h$eNp!^:
WAJJA1 TR?Wn+\hG<?G4GQnAuW/<T8t!*\N:91IjWGqS!9W>BcWd?>:=+iwmnFy&hd9^N*IEyW:<!aji&QFY=KK
<%im\H YTY@:dythhEWwFl&>&=J%&t!88?hNd=<R%E+ytpAI^@ch<MBllhQ&1=DjeZdwBJD9iX>4:j1bY5/WXaJ
Tq*N$L /R%i9P+6%:*XekZYPAB@j>>L#5:P#^Y?RE>+WV/JBVuq\RIh!1:&<Yy*PYYNm6tk:=5N$1*yLP6%9:j5
qR+CVJ L=i*!#Xh?8t8u@IF$$peW#wIA/6Vi1>c?%5wIMV6@XHc^=Vy8\&1mkbBJd8n84G:6huRli+e8ip<:ILl
>u/=N8 h&?muY>yM>X8CQ<l8&c5biZ#:pD+^\KQqhtV1Qd<Z&:@@%E*6h$d!SZcGCWu@&LQ#jbL@kXZnF^jiF5M
?nw4PY 6&dQq#dG<B:Z?R&:u&a&l:jd?5X5+Pa?8:mSa%tQaZZd!Qna=IM!1RmdP/EemA+CZGQKjHEcJG+tCRR5
Jjl\49 1qC6Q?@LHukn>/RqbSGa@FART8atCE*TmhI4T1NHBbV#mbXIc*8Nc?GyQM<i1Mt*TEKKI$=k<nTKE*!W
SFZX#? /\py\Wh<qVc9%cbibA/8liF^^8*Mut/?eQ=QmC1By\STKQkK<aN!ZBT4ata6iM$Tjq$^wJKJp?^TEDcB
mbiEA= tT<$<WaTXlG%kFPabGbmZ9PNSM@/Ec^>NR9dK95wLcH&K!*yRyP9W&?AHFJYn!H*htj4L>cHVhChc1+<
He$=8< t9KQNmNF1WyVm>m>I&wH$#Y<XW&&w^@yl6V9eK=N:qXwpuDY^K^!I5#8JhB1RqqbYY^T\ydaGuVnauwj
kitiDu ymNXZGeNk!yhcyZME^bK>m4JPZPh8#NRRbcT$^HuD4Yl!+yZuVy6KZZ9ytqnZYiYPRectQ:MuCW>#du1
t?mb8N IJdlEacQJI$eHRL1w:\=l<^8LDFDG%e&5aMhT%LjuBDGGZM&Q8B5KZ\5mCyX&+!yQ4T^*8N>^CTT*GZ*
wPtYH* 19L:^6XE++45LDq!$A+M*#wb4l>#cbP\%>cnLYH4ZbLj6&/6PJAReYmeHqTkBDu$4LkS*W<e/I+*dA8C
B+cEjM MK#T!9I*RR/1>wmB!iVKiJ+t9>dpZPS9*I>$!%6$/@tH4u=hGeE<TSDw!5ZJcFaB\ybX4mTRWF6mhm^W
wT/AlK w6ydPl?+$B&M>><LhMYj8:t^hCktb4YHP4VQQ6A%49l&AB$QwG%+deIJ/:b!5qAbV\@a!iWSBZQIW\>%
BHeZ1V L#!t%\:H*8@P8nK%QD6TtW@LI!TX<w$BPwLFKh<KV\#LwY:&1nC\D=AEhpJmaGZp5J%k9?FH=\AuXH@k
C<C<cC IMd=\n1iT&BVN8CGJ*p%u#Q=HjC%Pp^HF&Z49RDeFVY/=#=Q1:SnWhACJDkC*%cA:i4tab/nun9eu>1S
h*KMIM 1wIB=VwL%=RCbRSwj^CeXED%CM!^ibPFGl+\HadBW\E6*J!QB^eukQ*S!Qh=mji+Ni4Hu^+9<n*BkItC
qwtX#q c5/u!>jQ*^e9LkFK+99B/Yuy<SH?<AG6aY%T+jtRM?wDZip!A66LW*#@/h=p*%d&YnF<^Gi4BqAiSqk!
$Et&4R uAZNu^eEC?DwM5JbIS>hkR#*a*@>:9Bk5RBa<cMHIT#A:5N#/Hup9#b5I!/ZZkNy?JYh9:8SmtAjCM&\
+MEq4G 6C<Q?jQSC/Qt/Pw!84/?B4L9hjiL+YFncuyN^yXyZiNJDXDY>5Q#=!>Gl8=XFBEwI*6Q9*+yWIP*?%FA
i9TPaa 5JZ@Mt?C#8Zt^jQS=Y6tG$XZ%>HN>j#N>S!WB%$?1:>i#/FB6SaX\4ab+D81?F/Vt1?9=>e*%%dZnhZN
NADXcS w?%wi^=kK/+Q^4h!eT<t@QtdESP?mm+N/9We=VyTZ6CeDVXneNCKY<M\QP^#k/JY5KHwYlin/@Q9S/<N
!DjPJl Z>C>AjANpK<ZyG69EDcY/N%D1>V&jZ/wQFjI!TteJZC\pa99S+V:t6&KFR&1<\WSZ5\b8LGKp\hbA?Hi
KR:h#V MR:Y:1W<R<6wtF>#!^e6ku&@iR*kK#4a9DjZh/S5kq=EutwMCJc4GjGQPSqBi>cM4bCM&wM%N/u=>iYj
6=RN!e Cjd1/91KLd!+A?9F@G+?X#SE!1GE1\46wuq@D6ZR>eC!NVRqWN4P^B:&@B5A@=tAkj49SQj/HcB@t6<q
daKiBY Q+G\<ly$:X4bdMh$nkyD<TqL6$HaYFleVQS<?j1Km@AFYeBCpnqM:QEM!$!%c5I1QD4QWF=8&S4KFn!9
lZVS=W @Qw#/@t%RZ%:jj&YCe@9Fue5ID!Rta%h1<8eS%eL/pN\4!LLT5$jcpS=k%=G*$k*a6k41Qn/LY9=:1e=
Fmk9tN PC>m=Z8<kkqC5@Xmy#y&=lu5h#AP!yYc4auhiqnmC<PKi1t<BiZFY%AF/p@AB?GBb!c5a6=1X/IiB%Xd
%TalY$ !$%!D:XSnZ?bmDWmJX6Rk4%=!:BMiE/+utiiH^j#NuyTI&#X!8bAbd=epB>MwK#hC*HnG>Bq$L5FmBI1
cFdbA! $!VChFuMqdK8JZ^q:t=YmlJGtk5ibYeZXh\\NnXKEA>D*HnNYwa6/ZmLwQEYXNtyCHwip/JXyX9XZMZW
WQLIG/ c^pd^Tlm8Ec4\qk+=&=#IEa:mli9L#p+Em\=<D8AL1kVWRF!HJPtieJ8#Y#Z^n1\c1+=K<>GCcdcHA81
8PNAa! ?ME?#tyGl\YehN1:8:8*dF5P$9GCF65W6e!GCH8&656A5!hX4!<GSY:HH?=A\4icNXe>1lllWkZebQ:?
NX9^bC @h*:u<md*4Gcd+BKEwE9?4B8:BGaZSBqdY5hT+tc<!wPG*cYeB$8TjQ?bST#q6M:AL?@k=EBDj9T!LTA
#9m9lc ttu@!DPdL4IqaKJYBX16?$NX%F&%AiIc%9IGQ:%Gp@Wwtmey/Q=MnGHi6@P*:*k$BCnDDn^X4a&1QR1#
Y>A9w& N!CB!$S^Z9@p=4DI+6QG4aFIt*<V#lABGcmm/Dq/E&pbA@@e\FLMGnTY8%Z$P6mT>B1>6QblC+$dEIku
KAe8=! /R=HPy%RdmyPAQ\#hTGwtajkG/a4V>b:5t4VDVShLR@4H<n\eF?NRI*S#*VmR5X^$p?YqLXdAl6SPJwV
EN8m+G LQni*QHE:wcu5=HNtHt1*m=9/h65!$lpIY@PG<lY$&c/W/nJqB/<Y@dTFYGu!#lY$S\?^dA*EnW6Kn?t
+<LCPS /#Y&>ny@1eM6<F!*6SDKc$$L:I=AX<9Xpy+iZqKtMqL\45ZhDR$MVJdZDRL4?=/u&89h+GDZqWySVS#6
+i@1B? hKdBF$1tB/IJidpmeMJQy=EjWbBpFWiY41@+h\*$\+ZDZh:l\e/9%#B5*kBq?q+<k&WN*hR\Z1a#=X>i
p\^8\L Y^%nZWl4W1<?9D&a4m%R:4&NDq!9FIwH%nI4tW1@*<eX>/6iG1M:<WVuTldCDE8QdhJQFk49/E=4c?m%
HjPiZn *cdbl\5KZ+WjV<tqWKd<wK+^NVRN\yl$CC4lFu:lnV^e9FFSFKj&cadXNDJ9<=W\@XB<J4wyGZcb^JTd
?<FEB* #%%aG>yi*T:V!LjL@yEQ\MI<ei&>\DZ*XH9B&dWV+hYDaDZ/+C\RnR59I414=i$M4jP<n>:H\cVjI%**
Iq=4<! wYmMVyle?9:IL$bdpQTKEj/F>u!<wHM9wdWP45jAS8!k6#+Z8S@B1<m!+Wj*I^1+#b$uTd1Ca!W#NSwB
h#iS#E eVRinawSkiW+6wYj<+$clw>qRK98t:hGl9^#uli?u1X>8NE<h*LQQqVX==bMqJ?QSmBa=PckP%>i9Fa?
\u9=^I 5EQZR?/?Nh>1Iki*KnAekC<>!qE>RJT:k*nbl?ISLRY^knYXIti?S:KQDZC9k//$AQ+SV@yp*/u=AaV:
88#pH@ $S%ME4I9i4BkXaC=Bcd&15e*4:\Gaw/9hk$pD9a4$P$u4956ub::4bw8q>p!:ee$F!#+#DuAM#bZe&Qj
mZGG#m aX9NRZ9j#uMdISqq/=wjVy*Vp@HwS<5MlD*?GebH%>N>D6T:mc4bCqN*Y^t/WQ6:a51M?#Y&:Hy8#WtA
!b@lNA V\bQ%Lp/m>Ra$ZuGWYM*eL%9mdBi<w>LWkR5hkFGE5dRL#Aj<F=iBAh&XaEbuRK#W<\:u>SjkVy\6@RL
*JC%nw 6*M6n/Yw\w9VHTQ66M8@TNk6mY@cu&GY$9Atc&y8B?LN5@%NX>tQXtbnQLA4I<m**4hkCqR61HNiX$LS
=pQEZ* ja/W!Y!1b%PA*1/a4nI$DcV4$epX^J9DPAuRc1$p5&4F#/InF9G9:k^wQE>Ran@*+^qmSEy^tb=<Y@G+
>m:kKY AL1^*@Bthm1Zum^u#Se<Lk^d>6Z!MEBkFm%E*C5a<>qkwJ+S:DTiV\FK#$ASaRH8!?lAk$IQqbkYewJT
GAJ>j% ?dQWekVLpZeRnqWWWpLe@Kw*yGe\lCmAu#G5wKK<J?DC$@G5V*P/=a=?$WHaKb!=51:d5C=*Z%L#+GAA
WRt*S1 54<y=aSc4CnF^F\FXE@nTVKq*^HR$Z8Qaen*NTa/<8MG?kEYbnt#mjd!K4bad^J5q&>Wc\kRh+:w$X#P
D>*IAy !Rb!YNSR<*NjMeQ&py>:Ced*JML$bWJ/98*9$Jb$N=8^pkY$:5GmciuI*8GR!+qbV5/?1b+4GV\dmtHy
jLht>8 h$i#BF?j<KNtQ@hY&T1JMJPI+>q5qpKt5<qEW/TT>YIXNq\L#wT>nuGiiEp/Hu+Na<iK9Vl<Gj=ja%jV
QtSZk4 &pmTSFZRMLcl/!CBBP64HYRati$1!II1GF%4wZSRR<5kk@w\X\%waQjcA#La%#uML>mDG:y@#j/QcyDM
Cw:HPn cH#$^w8I@KmTQDPTQ:w6Y!>jSGSpbFSGFAKKFW8bq4t9&#PkulHqFAEmnm*T<*bywF1ZTk5ZBcjyy@k+
jaweK9 *i=48:Y/tAYht&LJhIpS&hD&@m9JtPk!+W<LChcp+MkuJHVQ/Np/Q=IiZ:eRWPQK&pE?J9Nc=nlM6*$t
PC/w=Y *V+@*H?>P^QRL+DHN9+CK<ZV*te6NT*k:Xp=$@<9nm<eDLT58\k#mTmnZBHdFe:!\Zwi6thjSemAJXZ#
nmHPPp Qn+Id<Q$&n=aHGR!Zb!IL$1Vq//8*Nd^^@T=Y8EI+h*#<@p>c=e\Bjd#F=n^euHSVp#:XNedc>X9NNyJ
>S+pAE V$YTW9DM=h%c$W/EW:QmWpkead!@8!iK=Ic@uItPmj=&6STH:K:y?QVL*k6dF1Z+%DKQ8mjAqp!:bP+E
/!BQFE DEGV%%?hQ^M5LWCETB?j#<+iH&k!Q>>>8q%1V6^iAuDda^6&Q&tIhbH=hLNH%*yayb&n+y1iSBl#<@pe
>SdQ6V m^:^jdn@nBPpSQjl<a\eJQP>&AhZXq4EY++4$:MXiS=i>bX/YQ$1ye<pk\HNaPL:+@Q=>y=mN6k#6tAA
Kwp&R* 9kQlZ%bLE+eyR=j=WVZ9dR!AQdw>%KH:WF:\QYn\NT@byGFa=#l<#By?JFhJ@#!nmZXHj5#addKtw6?+
\JTm!4 m\=P&Inw>1=9RibVw5^*XAcQRn/L<mI&#BjH9LG8u&GdVS=/!%c%ZT=N8I*/%8d46W\StV8\a@TIBR?p
b\:%N5 \>a@aqMR&>W=/JJteR!a9DS>QN@h@dLCY9C$d/XwY^QbA4@l8w\dQdTnuS!M&yXV:!mA#$H+uCa9nn$@
eS6j$F !MJ\J#c%^RHq?MKuVq*?QZnKVL:t$!J!@p4CtqRCHMak9NG$6Q<eM9w\N4e$nak9Mh+?*PQ:@b$5^FB9
qTZ\&K /4M?H1hL?EJchtnDnFVdbaB$PTXEQM9!<pnT=%8ekmaFp/#=tDu=EbVt+4S#@CV:<&?lhdWbE?^NKn%T
FEtYHQ 5kWjSeyq+RN8/#HX4&J4bpW:A&bK^uSQ5QDX1:96y+>LmnC/jN$C+Td^W!yH4?^y$a#QXEw4D$Kcn9B^
Vcl99T CXDmjlpMwaAhQh!#cl?&=?jIqG%ZZQcV^wm!@i#h9@HZ\S&5QV6LWX\/%:NtYd4MKMJl<W+FSuX<1a#y
-A6BmN 000f36f5b7d00110334 Page 263 of binaries2.zip
ZV9/ai 9/6##Fi+T1JLT\R19n?l*l14@XP\Pjc&bGXM5Nw4bnG9w1l1>k5KcY:6?WuF=I>y1X@>^&4:qa@VW<mB
E!>wI! W?=*kF$S4BF#>qM*uE@<Am<HBL8aAdVZ>QaeMqM<k@a5cYqNmpVNN1bC6#L+<jtSFn/c91SeL1!ZAuQG
Ri1jbH dTY=:H^TAV#F\ybRE/A&9Y98XJP^&Jjy=bR%C^$:9k\JwWQZ=*eWTZ=lc>dCi6TDRL%Q\XZKd?HclC^^
NZm1G5 #E8:mcJIWJ9ildSS$i++cpIAG%hXQZeT%4Fepy5t9@\Ic!cd?wnC=!Z>QS?YCVPIdmZCI/c+pBc+la1a
i?E8ii u#kI>Z+?&#B/#wknSb+pXXT#8Fu1q9^1?@n=K$&qb\RDT<9Z&ZB46@!G9aZl^TYNwqySh*Gi#1MNbC:l
VZVLAX qLNu%t6=TKJwIu^F@A#><iN&?*uLkq=?NGSXWP?V6?Z>t?CTKi%pS8^8q+:6kcnZWdVtEen/:&&bu9Rw
h9:yFu D@Vdi>E$k#L</8M9:CEyFkDjQI*=1M/*Fp$=wZSlB84nTdeX\^K=GXB=EBeTVPH>cj!CAGM8C=J%:\D>
MjlaId !qka?bIA+bklb9VamaQy/*PJFNVR81&\SHADwLjp?KJK@w%BTB#J$u%H$y&DIpQSRJNi:\DRT=WDZ8GE
jR8Z#b =P$1Z/JhXY!QJkXHDwl4u<^J^p>a$SyA@bL%uKBaqCRip?LN?%t6W<jWWVWZb#ZFu#V<F%dPI=E::eBw
^$a4LX 1&c++e*VW=CNF:ZGjcJ/Yiw:E66EaJ%X:@y\?9P111K%LkJVq588L!B#Xk\JG/m\:9ITNqcRlbZe6+tQ
BX!cW^ j#$=CTNanRiF&ml:Y!NtNGTBX/^cwJKm1<&9/*w6w^6B5^Pm8V8\RpGaS45Q9Cc@=bBDlMLE9n#?/WDd
tWY:CH bWNnE8NZe=nY$abGVqDVmKXHi1QHuCV?c=S5wuW1\&M%9tQu55hEn8wtIiC*ydCqZ!nE5wjmV+p&Kb1$
kJ9&+w da\PVE%lyQ?Mc6L8nq/amee!%6T1=Lh%$8^1uc?qDwiuGE\L8E*Qi<!yZ/Sqild$5>EQ#4%nTK\Y^m?a
I\5lae JF+pZ$F9!VMqk8!4Z=5DN!km5CTY6/MBmSPuETSNlV>\Vk6Le!E?yqDZDZkT<CZyjinDNCbPJ6!D6Kb#
ciE61m HpAlqqd>%q5ud&%+aiDP>9*TYnK$MTHet8&S@cm%q4L<B@?XMG/F\IYL#@A=B$5Mn8hpH/wukSQ5d1VK
GB=<+n \J>WbL<wNRdl81uGJGH/jic:X?H=KGlWCPyRA8&n+J8FYJQCaEqpM4*tkFF@\MRm5qQ*VmPM1tccllXL
Iqy=C< *1XHj%m^#HX=uKL>&6IaC<G<ClaYQ&4?PyTjFnV?ZkM*QaNb1>jeJP5lP!P&Aate&cAIiR<NX*XFC>M+
+ANK#a ThnjVPidt6<Zd%$q^5db\5:WFlNjE&EL9F/9aLTt/Sh5PiR6?qa%q%a?tL6e?N:RY>Pn4m1&b<#&YiRj
&$cmcA NKKhEaQC%^F<IGMK>ukH<hP4</R=+Bj\6qAH^FLF^Wk5MZnWQGMJGSJQTLi%mJu?9I+5*Swi4$pPaqn5
ldnC9A SFJLq*?yTdmSTD=Mp%=etlH56A<pG96++w#AtWcBebM^EXQER+At*5#*MQX9DEp&VWWVSLi6BYcl!4lt
tpiuYk ^#Tl>al\VELmLa5FYZPB6RIcRkST!H/EN$L!dRdZtDVJPGIJJ%G6jE%I6&dek\\b8y4ZHlYn&leDVqwp
Ma1INT Djd\cWV8n+DBP<&HAEc@QPpkX:KS9mMSp1CJMEt=%!RdupbNL@+RlR?<lCZXmn1RSe&nIq$Y?VB@S?b5
#RW?nZ lwdEVHFAQwt1HTBHBD#A!+WTJ8kK$mYdF1JXqAljSKKiL4SQV1a54EGH4:KkcX$jkGED%1d1IjNH9>Wk
*>&nRM 11JRa<kh?5\wq===a9JJ%dCT/T9SFd+lw+n61846SnIjll#MlI>iRmTSIVETQ%i>Qka^m<ckD>Gd5m>>
!alTKc CdtnDH&d!%I\l8p\</nHc\Sl?aja%a+*1p!b^&JjlDVRKRc!NH$CMBYFeYbA/n%\V4A9\Z!jI%qGSnR!
CRHFVE ltkViPkibB!nhQP6?W@+?QiMlEJ!hqN+H4+/*#T$&JD/DJRKnQti<YcJSM*wCckbTW&aEVaJtD^#\m/#
u/%J:Z plAF$ilL/:H>jyeR*%GlibD&1*?Mt^%9C$y\K+uyDqB=uRB\aKVLJGjWe$GqV=F#A#**EQ*J@Q18@e/Q
F9XIdB p<t:*W:6iXT8P4mVCR&ZXGkK=Tb</:Gk>wHKp8eYt+k4VXu^m55V1cpaF:Q<9?%*@uJA6#hcGu>kYZ>5
<mpHu$ 9@4!+VASVkNV5D^nX8uX*9dVbK:C%$m9#=JZwKaCQNd1k@D>$u:n5\p>jlel$/k/jEpe9^Nd#BV\/%8^
=M%GtK Vtk#!QS^D1tjy<cj&IS4&=AbS&Pck&X<WDGdQ>y9@L@JQ+t9:5!Le96!NK^WwF\/G=<ZE!E1QVZ6kDV9
$Phq&% nPqd$@V6Jh1V5nk&1=e@D8A:6e9S&hHL:!bY6+IkNFu/1I%BV4@QZYy6#n%6NkuY\KbZBYt$::y9QKF*
nkyG!B ^q+CRXdS%eLL!@^\=ZTd>/W9LH&DicX>wDK<ya6j8t4Y!bw?t&cic&/+QDK4q=jJ>=MD/bi&MHBbZd+9
^<FJRp H!bn&HNi1AFy#>KD+Y695RFZjLhFYb\AiV@jaVIbT=i<?BGl!iV\@aRDlmqSQ5L>M6p=Ju%<>PYCVT+<
wGZ1<? W+?hL%Q=NR8@^L^mV$J4^tQ*AZ8tAFlm&@Lw=W?VMj#\TEXyP:VTb\w<quE1?V98E<9Xh/=1STc$pSnZ
e8y/4% LVedZtJ*l<NpJF6!dEIRjQELG*18/&l<IA<6M%ke%MBaV?Y+^q\p1/m8V/@MK6DN!*t+&QD/ntX1b&^&
d=jTRI $d/$EY!Mc$\itth\d1^na9L>XK/R^eI+e/RX*ha4FXm%dMVtw\15qSV5VZq*ZD4R&wJV!JGLi!+E$M4b
J1pdpm 1F+NCnj:nL#kDQGNE4d#GcVD+Nn?t=bHw^9E1TJGXk8<FBcI/LAw>QFqaN!EWt!$+?WC/F\%LetqwDmy
TTAJ?F >Kk&yCC?&QqwN1aX6dN?KXwcFG\eaJ$:%w^6LW!dPCM^jT6Fqdu$j:bH@K!WN#/+w!YnpZ$eWlK%B:WS
^+It$R TXKTl$aMljYjucc8VZ$4iGCnLDdn=kLbku/!<PjC5Y^*lM^9m&BQh/T/T/uZWi%5c>\aLBw5:J^nPI11
4TtN&i nLP991^J&1lnpW4ncqjSKM>ctRTlP?MihMPSh4RQdThN!1/dR#?EHVuHe8^GnCw/b#q#>?\F6>Ltc?%T
p*ZyCq 1/^b#cl6YlZuKk+c/C!<8c>4FZZX:C:hSwcjaD\mIeDP^HH&JStiLdZ&t:YN@6u=kw@h1?^Iny+\>w$:
ckHi=p u!AIda=@8Y18JLntQTN9D:GBKGp1p:cLj5H/^utGZLyX<$X?pVwVNqpcYI\nVNPw&d6hXW9PG+t\^*cd
M8QiPI ZuDRPhS4WtA?=ApKhR6ld9cc/^X??m:ibG=6yjc<PAGG#Rjic^b8R1%FN$uye=5PjqV1qb1mkPBVd4\P
i+q\Yj =H\lQiL^*WD$/YLYwt6*BMT*q<8F^MkV48$E^y=BM#H&$+KL&npYqa6acF:Byj*T1?NGDD!dCh>NcF^n
KQT8m1 V9n%e:=1jK^hM4Ap/d6M1<%tVEiC#epAnIA96BlymM/E5+ZA+1N&:%b:X6B94?HR6\/%!<c*+T&nZkw4
T!$CHh ZbbZMt4VpcXP?&bA=6#KRW89+VTq$<Bm68/1q^$\=\ZIRAL6lwR=eHDbubFN!:uMG5Qui9*PbLh/ZpXu
8q@/EZ >JK?5*:Zhe6JS=y6dK+D^e1*#d>+uEuT8hA=pkT##/PZq%N*tbSuD4w+*N4PLCb%>8^%KA+^TWIS%P%X
1T>4Ri 8GtP$%1i8/dlFFcL4#M?MwQ8Fde+PQP?:c\<?KaDY4N/!b#^G9pNI<eGmlMDWMWHjS#5jRX+bnHjlX&H
4E$=E= Y9dnjjdSLN4\ya8Jh1PZ8XcYy?k4utDcdly!hb45LVDu/MTT%=Y#1Li^l\Rqq+F>jhGBy^HJGVN:#M=Y
SKw*<n ?56anPjXwq5H$#4$X#>6MH$d$!46F5<tJ$R+cC6P<6YVTc#5dBb%+4ycic&:m8hSdNbI:p>!H!@=^kIm
*N#adN ?pIPdeBSi4:&%kt=LYTliGQ6Em1l$dImAX+HnDidNREV*hVGl%I@cE!4wq\Il*^h>\TP:@t@dd1K9h:<
Ai*VyE SJk@h<!Kj4/t<VSZthH?Kw/8*E?mZePa661YTK8TVHSM!QPRE9?DJd#buHBp$e@EN^tnpSu<jT:Z%XMn
?Ldp^N A*BXKAJ5d\dmc1L$ZItW&?Yy#\I/DP6LN1EW/Ih4mLt=plDC*u$pV&@%4mlP*Sw!htDV#BaweXHY@KTp
4TSn>n ZdDeu6V4hhNp9I#n^l??DSTL<WcPd:lk&h=ySj&GH1ZS\!*ReH*pmN9Suw?iTd5etLLQJ#nehERd8cT!
A!$mCp #C=!DymNP$KmHW8ppXXtY$$SQm:Ph##HylZe?MYT/F+di%Ap6*hbYjI>Zt:59Xj$ZEP4Hai:*$!8l*VB
WI<aE: 98=/JX%1k>qqNh!M%h>KP^j^Ai^^ibXhIKK+hb*G:NP&*<p5Z!%Rc4P6Y>:L#!F5&c=5Z!1PT@QM#SS^
@/K6iR R*K\RCJY>a91GhX9<FH5#Nd6hIQ#1BPA8G5Qi&MN^M+I98PLwHIHG^Y@4H9GulLK%KL##LeT\#C8R>h<
FMIPWF yF1*kdq&bhXeht5!h?Mbu1&bTnIN=1=6jYKu5JbF/Tt6hGJXYRj#1dM948QeHLZbpGyBLXT$*bPaetbe
>dpHWT >!kylp=#@W&6YiXDmNhH?8!5ShHX/Vad9w?J4di&Zb^C91uSe?=K%LXD!6M1c5@ZqyXZXb4@hd?SwIYX
YE6PJW G45Jl!FC5j1SInV/TY58hd:ZS!$ABu@Yc$TZle!$dN4CY5J&wNhX&%i/!S8RHj#NbmQeKMw+t$=6H!9^
V=t=Ju ZtqRCS$kl$cNI!:HFMMCtMFyRjAGj?HMY&#eNZ1!$<ttMhNb=ieNWPi&5iLkhAicX:9\&H5qGY$ayXM6
AE%SSb e<nh*q:bbIa4GFFX#!b@%VKp<>E1%=C5He:#=&yVtY*Iy*b>1k@a+Emp4*X6iYW\9FmwRi9lKGQDTt$L
a6V9!n tLuYD8**QXbit>ij>l?TVhlNK99k#L5ZB*#e<im9Glth/4hpP6*b8I6kcp@%5+16iihmaP=tcJ&&R1<%
qyLD<% 1Dub&@Ca4!%d8BHyLwCVYW?t^hkt/*d+P1/HP+XwZkhH:KZbI<Rp*J*1%unQdShlhjC9Ni6+9eXkbt>k
DF?4%w =qeuuy^KtAX5NMtRcZiB*EGuj&aqy?bK6>nXY1hdKlh</#h<9iG/CX%?$?DGe#KQM*i#QjN*Y>K$i%Db
F1G+@c ulTepZ9%:t9G:$wh/:@dAPh9QH1>@\NRT\MEFAACAAkAIXb6JaZuD<&HBAAAblIAAC5AAABndGqqduS#
\+bAYB L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9XE>QVFNJR$<8TWNQ:ba>cCNZEMjHJ+WXuIZqIF\b#9E%eSMM
YQIqEW 4\ktSR+Z%^nDNc:hQXIcaqCRA/enaA6TJBA\9E=FEyLmRNlFtkMJFlKIZ&$*MRSeZQAGVmcRGB\!?e?<
LG*m:% ZZ%bMudm+^4Q/8*8#P!<?i%:V@8GcIL!NDhZIyHj:lE>^uX8VqZ/4pD$Zw/wXA4?h!iID8?LH9\j9WZ$
kn1JhB #!V5EwQ&CE*/E/uhw#FT$^@Xc8EmB&:c:Vc8atH>EZP+!CEtPh%R:y8iLEKjc9XE>a8ibQ=tjci=e>uj
P66*X1 we!@$/p@ddYm#$4>@p/q<m!L*$B+</u=iCA?1t#$=Y<G91+@y+k$liV1u@wA56n#F#/lcF@<\h&c&64c
<&B@Y/ G8ZuXFJ@X%J@X+d>G9nHFTNb$N@%>YmD/kMh@FY9$j?Y:QX\??GI>pDiSJKuVi=#8mVHNPb&&u:NMb@>
-AY?1b 000a1a6687200110334 Page 264 of binaries2.zip
<EahQi %G8hmQpew@L*A?/V\ZWiZ4mY9@p/d@@Ty5:Q*%I?u/hCwWCVp=M$QV%NM#M#ND5:T@Q#<:T\5EB4c&8$
pqhPPh 84yK!<9L6LT$SLXQtb+<aj1KDwq@>@Vn+T5/jQtT99#?PVLI@Fw$l?cDmnXFBnaDt^Edl$e5:Ba*FuaL
$Aadpi 8?WR=tB*5D5wDudH&lX=&D*5HuaQk=e@JHTG#n/p$5PmPVT^eWmQp\GDAaMBk\GDIwHBkMGA\aDBkEE^
Ma=hkX \YDAaMBk\GDAwPlkMGA\aDBkMGA\DB5+DDmMeGBy/P5ymS\P#cN^iGY\YCT*TGVS1RYLDkPeFneYLBa5
aKwhG+ Pm#k5PC\+LBPdB!GCl\YDBaMFk\!hBaeFk\YDF/@YD+MIjKE\/jDc=VIGhE=DDX!P#A=JHXI+MDppN9B
ISQEWe /hCJe>IZl?uR*LAn9$N?l@\!SR:=uhnB+MDktHZc\p^a#T=pM4$iDB:=QNk<PD#!/hRKB<dAk<MLB%=M
nA9=tj y^6BHm\iLB+RHkq%CaDFI>DnIR?DB+55C!<5tBMQFm@nwT!!GtRYuC+qBkPDkeHAaGA\/HICk\eDk+HB
m8t%Fc +MGkT\\MDAaGA+PB\aC8$YAHA+PB\eBi>k4$ke+aka!H4JW=\n#Kj1J>!#PY*1F9cH%>uT1XCt%9d>Q8
Xn!m>G :m+hHB#R*6+iHS$h$jH^Mb&euNDy/Tthub*S?jp=hT/a9t+$du&j8uYJN$hL>$Mcn=Rd?<9qe9Imquch
#k%aaJ ?L+QiSa9$Xp+XVhZHw/Qy!yp<?FR@8RFJc?C9^G94FSZ^8iuS1NSHhj@$Eb#!b*4mj4LZi#kn>>QJVe@
Y1*iDe Mn/JE6tN89/BcItQ@=TN@L4^\!L^eT@?5k#Gn%k^A@qH?aQkkj?+JyP?<?9\S:LqJ<pX%WPWZPY?SSta
4=GGS1 tVhR1$mhWpy4qc\id>Q44<hD9b*Y8W&yd#9%m/kG9jqFC!Yl%K6cdlbcLbT<m%Pjw*V>aX@L#$J>Z\9T
Q$1&d% CQ4%^:q9BKN$BMi5V&YZ9iTb@L%C:PA+lZ48$eShQZhZ#>*Xe*j%*A*18Zmw^PKl8wK%%mq4nhQV6Tcy
IyM8YL >n%jVIXauZE^FB#RXa%L&KT^RSi#DccWSClMwKhT#Q!bZm!@4j%qWm1G%6XF?uRciQ4Y94Q@AqBLA\RW
DlBH^N AAIACAAlXt$qjNp8F@aAAAD?AkAAK\AAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5NGSq
VKREIB a*bqem=ya&?XpD>9\nAR^X?kWmM^8FQunB&SYD4!phmM^FBLHeLHmhRBN9JSGD8i^GCpTB^*q*<WJck<
BHcFZK =?Z!@JQ6m+FESyc>RjW:Ah/qjwk#<XKe+MXatGBE\S/EWBeh<qGYyXThaZ9AZBehP1Y9i$Y9/nP4+wMM
!VHFG% pI9VlYuieue\hZqYtVTD\DHN>@pIF*u@T689l5MSMK8+=^S>854:@aqZ%i%/58Q:jpp^6R&KFBiuH=GG
K>Hd4t imuqAS9q44C6m:ndDZQ4YA=yiK8Yh^h=^&*XHPMKn*J+Mu8pj:Jdd+eQVbk:A>N@PkqNk#Sk=tNnpq*Q
m&IcMH <664=59unjW!BQE*Z\FRT\MEFAACAAkAIXb6Ji5+$:@PAAAA@kIAACkAAABndGqqduS#L*BueC>*cY+#
a9ShJZ Mm>RS%B$d&>5e!>!bZM9dDSqdtM8cYN9ybG^C5I\EIc9XcnkWChZP#wYjAB>JDeFB:Pqt/>TePlwHpX\
NM*jX> eR\+KDmeh&tQXLGl/Hj=i:*<=BITkIkm!!dAZGPAKiW=KTP6TBEMuchm/EC=AW4XmaN?nDGWiRdhAMR/
DQqJ&+ ejAWj@=q9QDpXKeun/8jH9HLRye/=G6d:IQ4%#4Wu=H#Nd/XA/c$Pdi+HatY4^Z5c6?%L8>X>h%Hl^Xj
hBCm%c EF@+>N&1QHCS#S9&4ne\i19VdjHD<&ELR$%/KmEN8wTwGypE<ZL\P6Q6&Suma!t:9kBRT\MEFAACAAkA
pcWuHp IXb6JRp#L>RLARAA@kIAAC5AAABndGqqduS#L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9dDSqdtN#cYe8
*9%9dS cYN94bK@T5SAEMauh$KER*KX:cY$ZElyeV=T4CKIbMFm6@JbAq8pVB:BVp6L!\WLm\ZHtet@VcGe+Lj=
e=&btL Mn9:t<&GTRATGut?B>d:B8CT+lW=J>?RE#kVynj\k:SewQWRiNCp:*8K9IJ!AiIRiQAT*@/wZdFIWb=%
tSE1yE m!RQk#!EMQHGtpaZ5Pd&eVh#+&%ynNI^N<:B9L<$ZS18+@*B%%I\uR<\FI#e$>6JRWcH<!M?uJPCmS5N
:P8\J/ bh%c+w!:=4N6ZX4h:mN?4/4Z=\^Fu4t:iNBVH=kZ/tZ8m@CwV:JL@hLI<bPhuFh\951#P\9@IB^F$?MJ
wuiNMC Q9DJ=JT<qX>#4RT@aE8t65EB<it+YJQ:G9ENa*$DWE5DBBRAAkAIACFYdTXk$$pNC\EAAQ+CAAAyAAAA
6MDelK a&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\$c&X=e!=ya&?NpdFP\#ARl9?&TEEKpyqat=GS
9F+jS+ uc4tphmeLTi^iPN%pD#kS<uItC&YmnB*66MtqWw=?@jh=@66S\1\+6E$>=D+YkMQuB>bDi8F6eJN/6Ec
n>%=Ka F+LTBFFPM4n\*uPYubkta5^Jlt#JenX84e&Fpy6RGYQ!l5:etc/Xw5+<pk\8*N>eZ?m4%4RGM^:=Rb#<
$*dCVq WPY4J+dN8b:/yq*$C>hujujp>D4*u/?\Y:C%>t*G*HajV!h&E6p\GwJKuA*^nMZQ@Hqa<98eeZCY@bnP
@V$K?R =\8weF1Qj*N<^j>DnkZ>w*9%4Z$XYIPtVX@pW@cX!LPu%$EQi6n&LM<%5j^M6A$cK8^SlV65pubF51i+
P@C6\Y y<VD*m/t?AXRT\MEFAACAAkAIXb6JT6S$pL=AAAA@kIAACkAAABndGqqduS#L*BueC>*cY+#Mm>RS%B$
C>:&ed d&>5e!>!bZM9dDS#cYe8cYN9yXK^dwM\ED%CJd^W6E9ZMubp#=B<EqIHI%WS*9BT<VH=Aj/mHSp:ikPJ
IMCD!1 +jy5\DG$!bI:Q^@9:6uaB$RSQM8i!N4Qn8kF<R*IkCMR$aP41S%hMiWGKVWF/*lw&^dSb6kNay/Chb8!
eEm>pT $^@4ydiC*CJ9h@Biin+$eBLT%:WitnkZ%aW#C=*ZC&?\XJV9wk4&E^@:9A/+1e=uwaL*J?M?D:pX8Q8^
IG6CLj TVGuVlCih^H+$!hn/Zyu!FB1w=VQ1@5qy<<XN%@jm^/iEn<Y6@1#/Y?96X1hb@+iu9h!#cj6k9yGZ&#+
Y%Skhk 9*>Pl%demRTIkTlAQPhD*T6\AC1AP+1AtH<BWE5DBBRAAkAIACFYdTY^Anm4M\EAAQ+CAAAyAAAAa&^y
L:lMlE bY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\$h&q\bT=ya&?NpLFP\#ARl9<WJE<w!eJ/HSp:hwNZ
9X:/E# aPA>#NRympeiK+?RDmnbaEThklleReX^Q4h&1IVE&bjj98?*a^5wyC&ZFWK<LaB4$S9JyiThbIFLbY/B
@J&#FD Q<Jyl*NSRyNB%*YmweLc\S\q6FAKu^DGGH8?=WdmNBb89ETC4WdmmNnQq9@t+nnnPPN1$IFNl5lNN5S/
Ee6maM Ml!=V\bh*y+Mph9V85!n\TJ^H@@!yE@b15EP\#a?4b:eVE*V%LP:&&G#1c6$M??9t8c^#4\%\#Cw+el%
wEyVH5 k#y#K+b6uVpRDFZtCIa1<>KKaebLQ*6b=ZF8n&H\u?AhmLpn*numTecjaS:T^V1@p8iJ9ulQ:*!kQZ>V
w%<VEI *^=w9BWqV&Qy1DikeRH1kZKWA+qimBa>1tLEG1Ia5WKe4@n=+b=j?IM:GQ+BWE5DBBRAAkAIACFYdTZW
VKZtXm G?$5F\EAAQ+CAAA1AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\$h&q\bZa8cYN9^XK^
K*KeHI V5M\ED$*CHiypm\\E4HAZ=R@+Sjc/dJEe1jpM:JXa8pu%L@AqNWna#a/II=*NwW&Ep^IuQ*!:6%h:l#F
a#cVkH SAc41kyTi=pSZaH9kRy+AA^h^J!d$R@t+mduE8tC+:$Hc$VmJyFE8nTpn*?\?V\l?q*Z6i4WeDyw!:^c
%yV+pd RaP=h6CyV5uYHZR5m!?&WZ@*@ew:dZDMw\?@j9a:c5*#:h&b6p>d%cuXwttKZA/a%G1i:VA<F<^/\KkZ
+!ltZL #P9Tel*u/MSlGMwmuT^c$#V4<8Td6WFbuASReKbnAW$KcFL\>@>CjnGj8>\69i$jR:cV@cbjB4MV&jVZ
*kV*EI w?t#aHwL9mT#j!QneW$DMBJq<p+*8F1=mAP<FRuACB#!/bRQWE5DBBRAAkAIACFYdTZQ&$MSRRMAALaL
R^n*n1 AAA4AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\+bGXnhtX!Ltqnd?&YQWleRSCAS?@A
pVwuJ: K!SECFaY^mLEiw6kF?\FG&8::RMBt^SZYReC\uaYTWmKNNbZHB!pmFN4E$G\TQAF>A1DaHD!#i/yh*wt
Tm\bkt $SBTJQQi9Qh&btjt&=>::$SGbFTty??K!?hSpRjey/h#W>+$SP:WSB//DZ&Mnpm>PEjqGtutW=4Ne9PD
<u>yRl l*c:#h$6qp<^K#e@*PTZ@@JQm@%qGh#undKd/#jj=?&QdVu<<F41>dw$Gk$bH^?ZmapJtb!eqKtyKbtb
&cCc@* tbHb&XqbYq1TlaWFtb?jq:t=PYp?M%qeNHplY&JjXN=9HenYy$@!@P$:KkR$wkuX$k^eA4cALdnNTyiI
8C/&PW QjIR5Wj5$Wya\y/\J^wJi:KeTlT:aqj5mpH>B$udcJ8YW9tIcELhb1W<q\BDkCHAEGDITDAEGAIMAaaA
uPJ+Tp R<cEIeARaAk\BBk!Pk\BlkBDkCHAEA\dHAGP+B!<I@L\MwpjCXZW!yBlmSTQFIwpndDpceAbiam\SFn!
Vi=HKP 6MAS+al\^PR&K%MFS+Rl\lBl<KtLeERaIk!c*%lcyyA/=hDi>IbMqIK*4W\%6SNMmcKJAkttSP&EM=Ep
NMnT6I Je>qbVq!di#WV>SQ%QeqT6SQdwel\bDM<4KXqam=8yQ=<mwMTn&FViFR/8YqhR:tRPFR=&BkidpJWqkW
w?hl*e FkXCKbm*AC^KwNJJMTk59m*WYXkVlWX>QnKL:\bjlbT*p5FkMBkMBwQBpLeVDA1D\YA\KA^=m<FkMBkM
acGw#Q BwQBRGwWP\\Gk<Fk/6<KeyDMCDR/^il4^D4/>!Vu>n=S:554YX=iqyYXFXqhZbY%6VZb*N!Wna$N&h:i
NA@cwT qy&hHhud&=Q>@Z*yh46!jH\5l!etL>jZj@<:hVS&IWNjhEjuey&@hhVK=#Z?ZIWV@>MB8b1@$!@u@y!>
=dL<>+ hc$@b=eej/>1hX\H+*?i*=Q:?Ip?D?@LV@I!tPH^LuLW:S=I%bL1aLnj:GA\@LL@*D*$R!MZ:61F>He<
b8PG6l T!8hS#&y#jSTDJTXc1#CYP9*Z\#c+#6jV=Ad^A?I^*eG+m@JqjlLe1Z?FZ<SP6#!+%*h&q@>aZ@?DXa@
B?cKSS +LP^11y8M6acK*Kt=Q>F4iY@Fin8EDX4>*TZ4F&#W@Vdp#:Fha4L^8\:WE5DBBRAAkAIACFYdTZ#11Ac
5&$Y>S D\MAALaLAAAwAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\+bY=nLtqnd?&X9$6eRSDH
Z?<c+q S?@k4yAa+dATe4EI5h+mYCZaC#dYh95ZBG^TZGYdREDa#mIJTbHG&8LkIEYeYy5IkT5MZpB6ktA^?e#8
?ItWLD Gi@<peTDtCKbh@Qi&??<&jt<*hEuMmdn$t#iFde9+!IQ8DcdiTl9/!J*KmIQZePj+GNTLeF^8ebc?Ti6
wceFW# X4u+\W&:*id1m8YjtJYLH!:=?L@>$!b@&ad:9F//8Z4#Qt>@c59S^#hT4XcqZ1@L^MTEVE%N!jV$6M#M
-ApqpF 0000067543900110334 Page 265 of binaries2.zip
WBbYW9 #Mn5:K#M#e*J<9K!LC+8!5LCk5#Q#$94teuTp5qL&SH:19Jl=%B&>9jq^d9*XAl+^BP8bSk+BdTAFq!#
m6k#9d <plEn>^E>Iki4cRq>ITiGCV$bHp1WZSFX*SFWQ?DbG!MVW8yjER<+c=bKe<y\BBkCDAEGDITDAGGAEPA
VnKWw? IeCRMYEIMARaAk\Blw\PR+Al\BBkCDAER+Mn\BGek^dJ4=hJ@Em++qbiGbbI<Wml!KRSq4\MBCM*EbaI
t9TNJy T%+YPCIeEa/aZLP!XHBEGCIMERbj8klHlCHCwQp@qyaqyE+=6L?<ISPq+GM4T$*6BFPmcKJAkmqSP^FM
Lw:mAt VJKT#&XqP*J6hPwu/mj1?^aq/mjZaWk\JLP<dYWua1:8bL/>CwNTV&FVPJS/iY8hk#XRPNR=iLG<*TRy
a#ll5e LA1LA1EW#C$Am=KwQKRICw8*lVwLi/K\1K>Hb9F8<F%I8bWMBwQBaDAaDIdeVnAwDAcD\cA\=BcD\YA\
!XSl&6 GA\Gk+GyeZRaDAcD\hT@Ee#BbEcm<XCM9pj5w*<@<6#?VJV:<qyYXqbphZXX%6dYbH%>Zdc*6&X#e%N&
>%YPC? h*hqd&>Q86&8HB\e!QH^5b!euMnS1et4na%jj1h8\VyQ4:c#8HY86B9HG+%Gd/9nQtK?b@>IH/X?d$6/
iuCAQA l!Q#>?*T?k*HyZJ8b@HGALb$H9Y6Mu6qj1@YR/\M^5?#Qd@#:ST:Rj:\l+@<#qD?Bd8Wj:FhL6c@FC@G
GVEy%V A!M&bG@k@Cjm6b1H4+?L%Zw@C>?tuY%dY&V!N:&GX/=#5%dj&#Y#:9N#@#^yhuVQ:PV^aMN<B%BLA\RW
nS>?J+ AAIACAAlXt$qVL<c#q5DAAC&C\AAK\AAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5PGX8
Y^/aAL a*Nyb!=ya&@6q5FL%EEW^=@8\t<QWkumThA<SF/dR*p1lE+mhQGc6@pLBCGC>8R^kpTaVl+1/6DFe<LC
PHNCl5 Rwh<b:$pBB+KX!k9IRT>Qt>tMVhZ1TAK/9%<9>@Pt*u#@e#Me*<4MmCDMnF^Rh#iD+ye+np^pb9!4CF!
EQQS58 4mb!&YQ+DZ^A/1X#WE/^b9/Vb4M<@PJD1>Zm/SHLj&JYHu==!G@@:b<&?<QYY?iNW5*%u/@#%y8YjH#>
IDFEKj XP4%8nRcDSpcGyLl+YEbHS&X5dE^tb!eqKtyKbtju=i=8VtbtbtS/iqych+%8ZZL=KF5mi&49N4/IF99
DWR6Mm *5tD=!>RCHnEE//qGdkFawFa<JmXIbF+=EMpHwqHK&tJiCKicCVm!jJWw5TX8BJZA84@pLTN6ttS!qjE
6=w/RH E?+^K@LeAk\BlkBDkCEn\SBkCDAEGAIMGSPGAEPAIeARaMnwMARaAk\BlkBDMGJ\BDmCe@AhpbiZTj^K
Pn8llc 8PJYqk^LSD\mFJp$\yK*ke:Il\lLlCX9C^\SnklHVB/#5qX\SBkmDBEG*:wIS+Rl\1D=G$9LF1JVL8%8
?6nBFj d<lEKZnd!qcnuYBKmCaEEp\J:WSuayKWjC+4^=G%mcPj$E@w?^Eq>JQHaWk\JLN<dPWpaqb*Mn>ilWHS
h8kc46 W>kWDpW9H/%#5AeKl#wHC<9HVbLCw4AwEIykLkFaqESqpBJRYL\5%Fp+E+XFjV<!m%iDu$LKyYR\GA\G
:ZC/yT k<FkMPS!kpFlMBkMBwWlq^kMBwQBaDAaDE!NE+jBaDAaVQ%h\S^MbmRck&L$M?Ie@Z&T=@a^WT:KE%qa
a<pkwZ YJCqyTXbZq/Y%hXX&h#eqQZ%hhui*ychuS*b*h&X9d$>PVk+pMQDR@u+&iV^&64j@==1L@c*w!@Thq<:
dQqWi5 6h?u:Ne@MnLTihpi/en54I<+QS@6YitV:>uebQHS+y$4epd?w>8*4%&Sp@4phn+\aM&PD#m=96+BhtJ=
?%<<AC $nPk6%>1d5eHYHjq*j:&XdhnA::L:%RhkutGcu?@=B>qi*::$&iMGc118uu#6H\pD1wXc9K:F/Hu6#*@
*ehS+P cp$&Xqb&V=VDWZ=6Wna&?ySLX>@:?=bV%%#k%/^#:Q+:?19K8#6u@HTwPth%@::jKVT9@+CQ+?h>IdqR
%5/@GT @PhF4\*aF/ul==q^*P#?>Y@i^F9*#N+i1Z+FWE5DBBRAAkAIACFYdTZGBPB$\RRAAG+cAAAyAAAAa&^y
c\!&Zp bY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\+c&X=e!=ya&@6tL>4I$eW^=>QAn9C^HaKX!b*Wbya
IA&LMF %btBkPG+Qh\K\#X8=XV#L^lEmAWGy\$JGKbVpaTpTPP@aCF\mHlRI:DB^J#A^Rq#ILpRLMV+=j6tX6JK
/Y@:d9 J/%P8j!C$=Pib8i>:<#::M#1^+ywkVL$/NE1mdWiEH&P>9Fn%/YjQmV/PEQI^@$qwlh4SJ@lYELQ+A8W
u?/yTR >epHNME1:ptXmt@pkaM\DNFKlN&VtH$nD\uJ!>#ic?Q@&PR/q:jCF?+/Z@JRH<^?uai@l>V=:WjKb4P$
IABu!+ 6LSE!<9L6Lc&S894/:T^5WH=jJ+&N#hyd&?Qhuh*cYhul:c*6/u!JhQ#=$#j$Vu^c$59#66$@8wXjjQ#
BhGL%H L/mk+By8+Nb*FX+Wakw^JVH&Ew&+^wFGZCP8&R<#mB9EDVwGeeN8K4KIY<R6+laBK&>I>Bq>64/Wi&m+
Q@DhyX kW8MjZt<KDAwMCk\KDA+JDAwMCk\KDAwMDlMMCk\KDAwMCk\PHR\KDAwMCk\KDAwSk\eCl^KPQAb+W:Q
:qe<JN penD\C&e@TtDScP+SmGNTVXa*DIk1ZGk\cLB+yaFHBweGl#cTI#>WwFDk$GDRaNBqp/DR+NBk<G/V!#4
X^ca4Q q^B%@MQG!/5epXHTb:@W1G*AbFDWwIABp$F6k/VBJMdIZP!*\>XGHQWN/l9Wq!$!1G<pDkaDB5Q565*9
wFI$uJ lHdXlW!&%+LBwy+Ft\YHSV&*6eKBNdDk5MKBE*QdnWEYLBa5FlAYBh$qABcLkSamm+AFm%\YXqm\J^a5
4M6/BI X6dD5enXIL6k*KZEaGA\MBkaDA\Gh#tB\aKB\eBk5GB\q^kaGA\MBkaDk\FV\^EHA+PB\eBY9m5\B!bn
AV@&$^ DGTI6Ja>\n:K>+tdY#TcQ1EjcH>@u\+PD8n+?JlPVp:w:P!MVp>Q/iLmk1/848n/?yy8dt:w>9cYwmmm
+=DK:l #l>M*%i4W:?ueuPd&*69*HL&5yXNBA8F@CV=bcQS1PX1>Zy6MKBRt1l@&cnuc4qe1=c4%*1^Wu/!96YA
6Da$:N 8?hq9Tjjt1K@hM>Y4Tjjttu?cZ4HD*Gn*yPu/VEAqt5$?1idQu<<wFH94?a$9S5\pE@Z=%4+BbPWV=?@
8cM=<n Q59<5?yu=bE>TK:PVQyb=@>L?1&66?e9iH*/k9d%5V!>\pBjT6lYIWZ9*:*AGFk?Z$nS8\wDt6SV/QN+
inX96Z jd=Wtp&ji%8>H+Dj+ip4&n@j^BpW$6i#Q1nRY=:W@Wy55LhC&9Z\Q@uph>c:Z@9*&#9mc&pnP9#X6c9B
SIHQeb pY8@DVK?jV4e4n:J?HFj8jci:q*LC*F:hDjeH+$jSTQ>$Vbc<G*H@$a<c6Kl6JYRktS:%G?jBWP/iF!q
#XBu!9 N$<<:>jn#*@+@^l@u%4J#8>V=@iy<@9W?Z*1*@^@/phmR=F1eZDe>ybWFId#*dd+IF>P=mZS<#n>d9u!
TG*i%b dPMqIjn6Nw*Qe#e?R^w:9<\kN8m?pciS=Z6n9NSQGV?eL/jQZ^/V::bj$>D+<49q!!u=w4hQJ?VL5R$J
9ATcn+ B9q!ib^AF5Ay18Y^kt=*T4+*9<>Z1/u=Ip@MP$G^PLwE@jwJkmIN=@69uhlGN9kj@D<>C8/D=5yhEC=G
uw5RQV <E=R!VSnD%$dLw1H$DTDKPkEuahNiInnCn^MiPXlFNBK>JRYw&ZKPH<T8<SYpF5SDdTH@yjKu%BLA\RW
:FF%/y AAIACAAlXt$q9ninJ$+DAAC&C\AAKAAAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5PHNy
KpJ+GV b!=ya&@6q4>QZEeR^:@ATZeF&CEFFbI^SSVcdBP1SEm8EJIdY6Q6Z*ATncXRWX5KRqw1Cn6KmnV$q1=!
SQIh/k adcG^pmYKG#BTjmKp=BenD?#i!B?*NqPZLm\>:&=>*bth8j#b8d8uVTtee*N@TAjd<iqu:nP#bYy@t=J
4\<>FV h!cpu%&H@I/M1XGN+^w^N51yna%/<aPdV1jD%VXYVyuXm^?8<9u*<W$QjiX^9e>d6b5d@:*QP/</i9j!
%5L!\F L#WcDdXcLW%PVty/iqw#M#Pcub*X@Q!<FlaY6L1/1yYXFT$6LYq^eXEdn$$QH=4?%IG5t@Zm+E\Hd>:w
q:i&+! !V@@EmEkEWqI46QAS$AZ$AZZYZYJ/CM*EZ%EH/$8T?kV?5RpwW>Y6qJGu>Fu>BqF>m<pe&N88aa1S$RT
88!kKh +n14+jpIMARaAk\BlwIER+Al\BBkCDAWVBkCDAGGAEPAwcDDEGAIMARaAk#B$MES+AnPRa8W^!5pjmRp
ut+ZLY I%ajGbbI<Emk!KaSqyIGnJGdCE8EycRFnklHlCMt%%qNFS\SlklDlMFVF?GIMERae9uF!nYF^KqHH1R*
1#@Jij FKIWjG+%%eSPMCYCJkIptBK^E<dEJmu=ZqdLWYKnJ*+mjmK?q!kSQ:pilkSDMm6q1=YIJd1ViZp#DJq+
c$A\Yh GdaMS!biKc%#pIMMS*aPH1!Wt$Wbqk^LBmIV5LRALJtFGciMI5QmdbGhlbypYLLuw:B+N*kXWtpqk<Fk
i@Hn*+ MBkMBwPl6BMMGRcD\YDIMJRYk<FkMBkMBwPB4SH$MBkMBwNqj$i\B=5bC\&uGL%G%NHjH&X9>+t/4&hc
m9M^/d Y%9V?91/Nne*6d&>4j*>ji*6:iu\<FBHS$e/Qn:Y!etJi4&i#5@Q>i/>/iu8:mjjW=<#?5&l+>J8@YHn
XBqt:+ K>pBG&I@QS&INNY6H6jZu#LeR<9LW4e=*M/ac4jd!<Zllu$Rj11>$>:=^S&G</t><?nS4?+\kq?:Xl&/
5Z<eEa I=:@\8HHWjt=eLl1y+kZ^d#6eC8@N^^8=><htyiEbj<cwH<bknw<iDC/j8w%6&nb$jZX</&6+=9:D<SQ
m5YE#R HJ:@:@:=SQ@!cN&S?i@*?#i?H:j6@X:9:GN&5:PQ44>tHtI@8^:@C@=<9Jd8j1E$pRqp:IyMDQSZ@i+l
$JDVNW 9!F@IQbca<mEjRBRT\MEFAACAAkAIXb6JT9>5+JtA\AA6k5AACpAAABndGqqduS#L*BueC>*cY+#Mm>R
?hE9L\ S%B$d&>5e!>!bZM9dDl*cZBqLtqnd?&Y9$65S^VH9?wT6@DqSRlYRw^FmQXWXl5WT?E%NtqMNj?CVa16
YPI%&: 4ANblPt&!M<mnjW?5qYKPMY46Iu\\MIk\n=lIWJ?uH#P#K=b#i/D>%+kSVJ*#:%*#np#*<?hM>/4NKh=
kTHKF% 4c&>I&<@#$5jeF%dK%%>$=ViZyA?hB@&EVcuSk*Pc$b4q=@c:Z4^k=6?9<@XQXb?M15ZQ>#qy@@dj:4b
\M:\G4 9>#8:@Nt*e&NX>@u@b@/i9HnX&w$Gtw&t%ycY6L!<4JYXqc$8411>jX%dY^5cG>9V:8:8>4c&6Lt=1dc
NFc:c5 u=1iQDF>4qQbhhaQy\PhZq:15&?@R!FkEW6a46*AKiAL?IL:4KbE@JGdmD@mn%cHJj\Jj/KV<Ce4W!un
K\<Za8 #@k#@w\n?^<pjcN98W1XI&IJe=>XiW+BlkBDkCHAWJBkCDAEGAIMAacCCWPAIeARaAk\FHRaAk\BlkBD
BDBj^u kCEaQnkCHME=iEiW^!5pjmR5a%ajGbcIiERwMttEyT\D\elNlCZCWyaFnklHlCMt>%qhKnkmDBGGCIM9
qab4bZ ZaRn\lBl!PYNqi5TwqPQQF4iWIlT<L:XyWa:\bRRVRkptBLcmYBmpyS<L19qKN4+$W@wJ@T>SAu>=H+a
AGlq5w Ek#J4JT6XmIYhTj#<taaMuwb6k^HS1?W%nqak\^Hhk+i4JTdRStYDE5GImNa6kA5taGbyI\n\?LdIn5L
-A=M#F 000e6c881bd00110334 Page 266 of binaries2.zip
?8TjJa Net\bF?Q\8K:\c8R!qa!GA\Gk<FkMBnKhwIl\&A\GA\bl4LFaDAaDAcD\YBkck\@DAcD\YDb9^ZM\YVG
VJ?:tE RCMyS1<ShjV9Tbude/Li%=jc*>@Z\eGBDk<QhZS$yJPVE^$jH?95:E#u=?i/8LnR%hYXdt=8hH6:1^i@
n=i\d1 t4:whq@lP>XV#*1D:i*6S#NjcpNcd:G&tRt%Li4qCc<=Zt<c%^9Gl@d/++eVGVPi**Q8^*9$y!ne^Ren
$CWKXJ ^VLTn?H$?Fne:H:>BlPL4n86/?6^@Hw!QnS%9P*<SjQ8SJ#F1jHP#q*Gw<u+iD#^uTqFL^yQT=6IiBD9
t9Te!6 QJ^l?HCC#6Mc*=pcu$maHm<IyI\V@ldYZeL$?QCtQpSuS6^5MH*Vn?MD9VR??Cj@V*ttq6%m9&F@nK+&
ACFR!: 69dIS9i@QG@b:=?$94du4i:H:Xc*yXd*Lc!B1hl:&GN5EX5a&h!E$b?#4ld5i:8$6l:du%BLA\RWAAIA
ML\uQh CAAlXt$qlkNi5EWDAAC&C\AAKkAAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5PHhyeGX&
K>ZI/E Ltqnd?&Y9$>WT^VH#!/dh:ekIk$&JCKFpZw1Kk$JJapNNh*<C#RYc$N6ImGbdk5%#<Ka$BN9bTGulpcT
iyFN4> VTk$aPLTEVRiQ&htq%$Rj:#K=Pt=i?:h?e/be#=*b9diFYqIW?dt4w9d?/dIdc=#e:py@:bF4p&I*HEN
/ZX1&I 9+e*yFW/t@Ih/?TQhD4q+khj/44t/w4qn=mXm^<8?it9@hFt9>p8:9N&&e&6@::Q/:i%>N<<p%c4Ji%&
L9Hu8p Y!auJ&X/iqytbtbphubY=8jubYFlRXbZX&XqbWYYqybpeZFSPk>M:6<*iT^:al>WZ8>>qL%*:?VS<^hW
YlFk?Z CHnEE//qGVkF6IAYZLMTE6EnZ!J/SI>YlmZ$lJ=wJQSpPbWw81I48mKw@!ByG&*VWmwjEW?+c%dKe\w\
we4b6n BBkCDAGGnASDkCHAEGAIMGSMGAIMAaaAR+Alw<MRaAk\BBkCDMHR+Al\BPjkGbF9L=Q+pZDF4h\!LJHm
tTQ^lL pWKSyBGYQA%$S4=EYCI5iX4kmHBEPGJ!#eyW\SFlmDBEGH#1Il\SlkmD=miYqmtpVnq$ML$lE/ZkdT6V
SJmhKq Vi$EW/JwwpCCKXE:$bqIpyLu54Ie8Va/>SQ%E@X>mSL%p?5\JBmTYX/&5lI^X*e!Z%/FRctu5CpeT4&<
#h1Hk? 6M:BHCke/l#eYF=8Bmp5Cw5CwSVMY\AYbcATyAkKm&<LhSdYSGFSu+@M+49BX!Hq4YR\GA\Gk<FkMPV6
G?%5\k BIQCaDAaDAyD*tI\GA\Gk<FkMJAcS+jBaDAaVQ%hRR/TGRPNwBl>nXlHj=@p*B+V=ba<qdY%NXqjZ=iN
8+Mw*V nR*b&61T*h%h&h:iq9*>jVp+PJDD\$M=Pn1Tp=MVPV$>qj+up!jh:y@#un4tGL?i/\P4lpI%XId^XVab
uYI\<= BR!5BB!QPp49iXVJeD^MiKumYQ?X9N?MH\XiHn<$1!:^ZiwjwVYd#S@$T*X&hnd1H:hN6?Z!?l4e$*E%
u1Q??: qtC#BC#LcILGA<::B\EZq<AV:tV#kA6#hlGkbLnchnb*T9>QA:/*W/lQ!C<E!A<CCFu?Q@>Q1ce/W=&:
lt&CPM hhXh/$&<6FeQ8*h:nbhtD:5*?w*8SK@S4dn?I+%Zu/XS<^inl@hFJ8!L*PT^MtZY\i9K4Ij*<hPy1?y<
RmdTQl BXBLA\RWAAIACAAlXt$qVB?C=cAAAAD?AkAAK\AAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jq
:BZmNN e!>#NGSqa*bqem=ya&>naGAERkWFARaRiMHE\CAGyDYAYAGIHaCapaEFLNjA^IADNIASR$MDlAJBIPQA
h*F=Jd kRNAGmV!H+\a@9?HWCAIEkISk^F<L!>A+Z@kL#A&NpD\@@<9&L@jAEY??#i!@HhWicA@Q/Dc\L@B&Nka
Y6&^Xn #99^?@iH:twDJQZ@Q*S$G/Qw1EcTH$dkQ!HRAMLMYDBDQRd?*%D@@<@=@^DM@@@@Q*tC^kMAWE5DBBRA
4/VpeA AkAIACJYdTX+6XmlqRAAAQ+CAAAwAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L*M$bY=n
Y+AeIW Ltqnd&NkaASCBRWBBlB+\eVAIAcpNaBaAakhkJmSkRW5%<DEkAM$kBFDR\PEApEk+<CBA$AcJQIjnBn?
1HP1%m @+hRIAkTAlFDEHAdk\CC#:<jCDan<Z>@/Qn>GXq?R#?1@P@j!Pd^e?#j#&^5dADuh@@?#dEhwaEjGFAe
m\V$j1 Hb5NpQY\I<pQbjCjYMDAnkW#aGJR$9w@E+kdkjk\RiMBWE5DBBRAAkAIACJYdTYVGl:=6RAAAQ+CAAA4
hCtmbV AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L*M$bY=ne&quLtqnd&NkaASCBRWBBlB+\eVA
Ia#5J4 IAcpNaBaAakhkJmSkRW5%<DEkAM$kBFDR\PEApEk+<CBA$AcJQIjnBn?@+hRIAkTAlFDBDAn5dtNna$=
Mcw^q+ tlF<@9*:>*Q<NpD\j*@w?LB@M=L<l9:>*BWCCQuj9^pacl9kjI:>?=tN&T@A?h&@j*N5*+DRD\\wnw:N
%<&YX@ B5n8ah??GhYBHR^DE9\uC6kDW\w\FBnakbkbmBpl!RedBmY6@#PB8BGID^M$HkBRT\MEFAACAAkAIqb6
XnQ:^4 JZ%i#D?5AAAA@kIAACpAAABndGqqduS#L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9e#S4bZq#Ltqnd>YR
hJqbJQ 5R4CRBBE=+Jk\CJY%mp6A@/Aj&W/D/:R#q?^DKRJB5!ucKhhmlVndlIpY\m&&d&=8deDB*iAp$:VNdTi
ZLCL+L EdAS*+yT$X:p5Pk#H?FH?Z:B?<G$=XBXqdlP&C?Rk&u4TLe=%EHiEF?@tB^#wJl\*61<QbpejJ5eMY!?
JKpCAD FP$!\/5mGC:LIy6!h?u<qHt&uLCd^hj!u&wibKlJF$TnK#hlqCQ9e6WNk>jC4@DZ%S>RT\MEFAACAAkA
\T#nbH Iqb6JYQ%X=CqAAAA@kIAACkAAABndGqqduS#L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9e#S#cYe8cYN9
>uK=Ac #W$=D5I\EB\uTIqE+XT$8KVpCV!JnnSIK>Gp<&N+AH+C#/CpT!TKbhhBmq&E6Ju%iD^:GVAT#nXR9Ayk
FX1*8j J*wRP8FJcLCJNTw\A+wHSKNw!CPEIKwbnkjMw&lwT1<%w4<I#yNuSiIH*!H#uT?S>u88d<nt/<<^<dD9
#\i/6l ^#*j9&&d!X6y8FJY:/6uPt>d!8iS@<e%=854Am?B!n<$RmR$9*\q6ML>+9w9WE5DBBRAAkAIACJYdTZ+
9W$ySP =dy/8AAAAQ+CAAAyAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L*M$h&q\bT=ya&>naGAE
Pi1TS& RkWFARaRiMHE\CAGyDYAYAGIHaCapaEFLNjA^IADNIASR$MDlAJBIPQAkRNAGmV!H+\a@9?HWCAIEkIS
J1++Mw k^P\a\mWF/D\/?6S?i#jC%A%<!QLF%!@LwDEb@>RY%8I4L8k9L^RANp\*6ycRYVdkAbeFECTB!pRRHEN
*DNB#M $Abp?i<w4m5wKPAauAH>u^n\l^qINAM^pN+QyQeA/R%A9ABGM\JywFELGKA$pL@XHcn&@Q@@DjJ+4RAA
8=X\GT WE5DBBRAAkAIACJYdTYnM&ep8\AAAQ+CAAA1AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#
kyN<8F L*M$h&q\bZa8cYN9%bC^C5JADIdVKq!ZRq%e:ild/CQb1WWwSB^/D?H8c>\4PN*e#hHSRa^@Y4BZSMFN
a#PI+l p@98:=<eyIRwR8b=Sl4utGkPZaIe4EFE$/:HMd$J:k+^>/KJD?eeXC9THSLySXNLi9%nMCYl6a4qy&@$
*kK/T? Mud\cCXN+DhE&/MN6+hqDD+y$:w\XVDAiJ@baKIy!>uwn:\@bcFQ/@4qAa$jFD?^T9ptDpbpNRG6!GIH
>%J1V\ IyEKMHCwZ>C@Rt@\h!DK@8PIB%BLA\RWAAIACAAmXt$qlt$l^i<CAAC&C\AAK\AAAGN5cYX8hHM9eGh\
6NnQ4: L*hydnM!L%BHWHS9d&^#L*Jqe!>#PGSqa*bqem=ya&@6qnFLZEER^$j9\C8<=A^mJiS!San%F5E8&A5&
%t/Dh4 X%?*u$C+J8BX%wGA5J%FEyImnb@k+CBFHEmuVc\5FA%ERaJk!PR*8/aI*48RJmq$*5%:6@>=8@N:M?5>
:hL*6A ScbpY646q4khV+5<=6y8=/G<dane1+p<eR%@lp>J9RTuyeIG?TPDRdu+\bjleMnXFe5jMT5ZQ%#!$=*h
D/YB=/ c4Q@dL@9<$db#jY@*?jD#$M=?@lG/9Y/NBwNtb&hqdt=PXqaYJDF^WZyhD1!6LRp*Y=ZXqhZbYXqSbcZ
lBAGiS q&Z\*GS6#iTq:Iq>Wjt\>%Z&nw:p^d9*bAl+^BP8bSk+BdTAFq!#ep6En*!J/BE>YytY$BN/ayDRp?Yq
XD%5Il SNEXZhEXRj$Qp4E^Nm&y<lH^lL6tJV&uAEPAIeARaMlIMARaAk\BlkBD^wRl\BBkCDAEGDI/DAGGAEPA
^qe1m^ IeARDA&PAEh\Du+n<8NqEn<T44mXS+aqpn!TKLJwlCYZkYDpT+Rq\yLLApiEI<ISp&6YTkXHlCHCEGH\
jPlpue $pW+Ik\SB5&@YFyKTJ=!/HX=R!bK\ehYTp*8BFMmcTJBkmtSP^FMLJKT4&YqHVp*P9pV?SQ=9WYJ@Mq%
8%>=6@ GBIM!T!*4ZRm=8^P=8%XGJS<Cy9CwiVL4ZWPc1B\1HQ\aLuhVFJaFBaFRpta6\A5!pVqJpXRYH^d1LQR
Q:W*Km E+XF9S/b^ZiDh!Hq4YR\GA\Gk<FkMPV6BIQCaDAaDAyD*tI\GA\Gk<FkMLA$nk/D\YA\tQ1:knXa#Jlw
l8=G+P *BTn>+k??95p4?**SHpp4/ZZ/$t@*=jN#W*b&61T*h%h&hubpj*>jVp+PJDD\$M=PVtS<@N#8d!<qLM4
i:??^u p%jd&*j91Z>tF#QayDiC*!L4d8QnF^jES>n/lQu#%ZGtV=!j&#%1Z66+!NGwYe6&M&/u99cwNjy&>dVY
SJjhFB cXc><X1uM%IdF:?&b6Z<Z@Ht@INKQyhd#iwc6@+Wh=5Rq?4K*Pd@W\d86VE8G#jeBl9&@bMX9&@&+?HE
N5k#Ee yZ<CWE5DBBRAAkAIACJYdTXD8jut&kIAALaLAAAwAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9
p:ikel etX#L*M+bY=nLtqnd?&YMW6eRSDHS?@AK:^\B4G!8F\Sa4%F5A9&kw&%*Z/CkE&KT&MhCAndYTRlKhL+
<&Q85D CR+PW5Ty6atXliEMSJ5kYE^?M/8B+J$tVXLw:M&>6@>=8@N:P*99uemWVE8*&^G*4>Mmn#q&8>GX>!&S
6^8#<V B\&SJ/:l#@Aychdk6E!\ju!p*/<Hd=\MBkPP4ql<^K\i9Lup@Z8:$!d@&Z:j=/&/t=6@9<<HZ\b!?9th
Yykw4P NJ6NcdXcMn5:K*N#e:K\5CCLm+9T/@XpcYqJ%6jZbZX%XXbYXtS=iXu/L$#Y%p^i!::aN=XQ?>>q@@la
P%84u= Zu*+TIcEb:#kY48J4+TY$JJ4Xm@J/JtVnJ:S5>XlBd&kF#wF9XlMJa18/I18CPw@TQyG*:Ttmyd^k46t
4:qS\/ NV%jCaaER+Il\SBIMCRaEk\JlkSDaMKRaEk\JBkTDIEPR+Il\bBkTDApR+Mn\bGek!$T6^ep*k188NXd
AenQnh lmYVQJMwM&tGJbcBaPap\=JlmYYBI<PS+enFNc6LBWiGIePRajCq!*BpGDIMGp<54W6Iu64$euqVEJZp
=56VY? jc6LVi+CW!FyIWGB1bC:EC^MWw4QbdWepS8h@IZ<lj^iwpL?+nwMBabmFtY4qemS*et<9A1Dpp>lW#mW
-AjIRp 000a9c86d3e00110334 Page 267 of binaries2.zip
HSG+9A jFFc=&ANFA=%Dt+5!5$klWXlWTCWlLEFaFEGKleyk5Lm&$KhlbwwLP44ET!?G:\KJdcT\YA\GA\Gk<ER
1kD>R< &\pGleFkMBkWl6lmMBkMBwQBaDA\Na+Pk<FkMJn/P+I=tM\acF!W5>iIP94:I?d&c:I<p4i!5dElt=8d
CGDj\S 54Y%Jh9d&:K*6!i:8:6!eHAkl+iHeuS$JKQSTM:P#8V<@F^PL$#i:P#e?y//6*>p\?i@dG#elqe&PV=@
QdR<IS Mu>L@Pd^YQ9T45j4+HandE\<\5QP<MjF$$b9VL^c=&SGG8Qmq>ciNQ+1*y=@PJd9!n46/lQndnjE=edb
pmuFac :=#>?S?ctVE8%#*??9JW6=j+<Nbyj\JRT\MEFAACAAkAIqb6JiE1XPpCA\AA6k5AAC5AAABndGqqduS#
:4\&GT L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9e#lqdtN#cYe8cYN9:bc^T%^BEIhH*+FZ?JJV^M4malFmt!&m
Gpnn#l XaKRKkk&%ud:F\k&KT/NhTBB&P/KJCSFGu9l+CBFuF1dYFpaXIk&RdCajLPdJuBQERIy+4/d>>:?buju
!HW6Be &>q%u!JnMm:hdpi<jB<Ziem#&<%X?hkY8XiJQHINi+cNTc5+^/Yl>QJQi4*!<I8Z\YDA$^ZLQ#E4D:>e
M#?j5$ <66h?c?L@iQ!=#=9q>*e89$?H*\d!QuZD>J16cVhd59p=KSMVW*J:P!5#M*N!j#<9C\5LMnc&y154K#I
/4H\bc <9K!LC$6Ti?q!i11!S9bF#6V?dL@R@cQn?Z%y<>ECFnEE1cqG4kF6IAYZLQTJKJHZmJ/SI>Y8mZ$lJ/w
wEjYVC JQSpiTlShEXZhEXR@+Ppd6SNT/l<ST^l4qpJ#!*AEGAIMARaMlIMAaaAR+Al\JA^aRk\BBkCDAGGnA=D
m85$*i kCHAEGAIMASDk!QAEb!DM!JQL=Q+qVDF4E\bqpn\TKDIwBGYuAcepbeIT+Rqy\YPCEiEI!dZ4KRKnklD
S^#Z## lCHC+KtLeERaIk!cV!\6KTSP8jS*ipMtT5H4XqJN:ASVItkmRIIyEV9lVA!Tpw>qbVq!dHVmJ?Iu+95T
w:@+<V JiIu%&FIMCT#9G^qJYKP:tT?9A1DEp>lW#mWiHqyuaMeKB#1HE\5L#ihFBcFSaFRA8a6AI9TWYtpCA1L
&$5#FN d\6%F6bEaXHQS&d^*iC4pQJYMlkMBwQBaDAa<ucCRYE\GA\GlTF9MSkMBwQBaDAaGByDl<FkMBlM@X9B
*Z>$IE GA^thDRc^il4^D4/>!TQ:Y&mQJD*54/?Ly8dt:K%6TZd&>8!6:euP#5:euB\IIiHl*J$hCRuJ!h!eZEl
y!9c+J q=iZeu=q<1:j9@6P@iXT%#j+Z#R+ll8=%B5dw%9aMBjb5MZHVj/b$=tl>G*^4NH9I@Ru#y+*nq<#ka8*
cQ#TV> S!Q<8jP\41yKhuhH?LN:&Bu?9H4CNJ5?iJ*VCct1/ea5%h/@tt@&%#QVhZ%Nqn8ha5%?L*J>k:6>jL9@
hw^cWj W==!W6#HJ4AKG!9H^!n#w+XD#?\XN4^^=F>RT\MEFAACAAkAIqb6Jd/Sb?HwAkAA6k5AACpAAABndGqq
4?N&=9 duS#L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9e#l4bZq#Ltqnd?&YMW5eRSVH*=p44yARLc\5Ll/EYE>q
%#FE<W F&\Q\edcdn/BIC\yDk/5A\Fl8m8TpBSy@ASHBIZ+ct%mbcEekXY+Rpn^<u5#%\T!S>KaI5:i&>u=#<:<
tub$Mc j#69:9bEY4Ik*i+#<ZK#IQKC869NVjuaEZu/SPTqc<R4wmZ6$4pkDYYRQ#IaqMwQL5dnMdW4qn>mXmw@
Nj*H\p ZQLVa@t9m@*n<85?:=Vh*Q::jV:?Nydd4^?p*Y=Ly>PS^eXFYXycpyYXFXqhZbY%6VXbZ%?Zub$h&h4c
*<Q4LP p5*NVhua&JDBc=Q6dbP*em:&ZiZp9Jd#/&6=<?p#DwGISCK$NAPukBdRkt6Ydwuwpa8IH6GnqYEJQcEu
FEB!N& Gkp>Yb=KFF*SFX$S%L?R6I&&cdHKS!RT+bwXi$+BlkBDkCHApJFkCDAEGAIMAacMCWPAIeARaAk\bHRa
D9Vj&> Ak\BlkBDkCEaGl\Bn8Ae@Edp^<5pjmSCCT8QDE9EQGIWtVVCpyiB#5lFlCZCpyeFnklHlCMt%/\5FS\S
aMW%?J lklDlMGZL5ISaak\cQ:F$4KE?JSDb<5dMqEK*4c!%HkutBKtCaMEW<I:$btaJCYj!$w/5ne/@ku@lL?u
<jV4Ne KPGjZIel\bDMe6yKJtJ&h#JQ4<Kk?Cq5Cwjmq%Q4HK!B\1HP\aQqhDNIaXFaFAnFMG<BYJTB!p&KwLD+
bA%DL< 6qBuITeKm@y/bBdjDb/FqLiT\YA\GA\Gk<GR6^MMCwQBaDAwDHtL\YA\GA\Gk<HA%AR/DAcD\YD1:\4t
JMZjD> aDJnwHFVnJ+n<8n9p#!**^Qq8d!Z*h%h&h@jq+PDA#p<QJT#5#M=Pn1Tm+5L8d!<qK84K=qMJuJ*h!j*
lnpdNP >@h!?<Qp*Yn$?J=/5FLZ!?YmZ@&8i%yQ!\%XW@@!6J+**84qi5=+tW/u<@^FbulN+/Y+T/@Zt>hjXZ9>
<BLa8a ZuN@=YY9%>k@19wnw4u@8N<jXZ9N@mNK>dndH9S@!8t%&jDa4DWpb4Y*V+i#cJthMNWZKjW^:Z4+S%Q@
!EBSiw BFBLA\RWAAIACAAmXt$qmS:^p8pCAAC&C\AAKAAAAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jq
!FS$$8 e!>#PHNyb!=ya&@6q4FLHEEWl*?uB*iFq<VGT5nFI5R&$&kZlFRm&Fnd#X<k&KT+!n1RIE^*SSKTIw&>
6ek$Ql eFYK?Gy6auYF\V8IB%eIKX/?thYRkHelIKTI5@h&h*+#<>/*:+&:TnZN1N%?wN!?#pmQ8dddyc9*Viui
$wM6V# 4QRpc>k#4Kb/NVmnCc%Vj8y$1p5?8Pu%iq!#+8Wu>?1Tn!#q$%*:4=9@+@d:Qt>Y8:u?>@8<>/Yum<@9
kt/hI5 XK@Z%Y\&NVe*y@u=iT$5LGl^eXFLT$6cZq:Y%6cYNna&6Lc&y6ZXXZXi8Da*Zc>$LB?cQl%@$@HbtX=?
j5dXh& ?EmEkEW5aXb%A/iAF6BC%4!cE6EnN^E>wpi9qmZ$lJ:wJQVp^bWM*hAN*SA5@$HTh@y8Xcl!SC^lYjM1
iM@Bt8 QKeAR+Al\BBkKEk\BBkCDAGGAEQBlCHAEGAIMARaCnwMAaaAR+Al\BAeDa+AS<ke9CQK+^YTjCVMMK<i
?tLd$X GbbI<EmkmNMIT$pDk=GdCE8EycRFnklHlCPt4HtXKnkmDBGGCENPZaRn\lBl5QLG5m1F^KpP8$y9KERy
ESAl=k =L=Z1Tb&kmpSNBEk\bTIuSlMPEpy?@K1HCW&P9EV<SQ^e+pT<XQYaWk\JQhT61wT5WVQbLt<BwMS#&A#
++TVd! PI^+ydTbk^\aHJa=iLBTdlabLAcLAYEELF5AFtPlMepRDJc<LT!#WBPD^ZI?Cp9iDdpK1Y\ql<FleBke
iPD!Jq BwildCeaDAcH\YE\GMwYk<FleBkeBweB%^k/DA/D\?CY9^Z+\Jt#$JpWa/+She#jp?I:#+q/yLjc*6:Y
NYK=\^ :8/8>9d&6L?@4/PnI^$eHPnp=ETuy/j1>@5/Q#@ZcDVT=iYqL4/:*uT:h>?yY&9n^5>&<^6@jN$tnA<G
^!1h%S +<Gk%bw!#w#Y8nVJ@\Dj4b&hhW&J4^%jiVylQD@EYF%jGW:nX:e^jH:#?m5Qw>j>ce@j$PHl^QmpeVme
RCdiSn t4?JZ>V4<iH$L?:hV4*X@%M/5%P5l8pZ1%*yDi\?>9CQ:u<AWE5DBBRAAkAIACJYdTXakGeY*RIAALaL
<M+%IZ AAAyAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L*M+h&q\bT=ya&@6q4FLZEERl*@1kXhI
6\6Eih El54C&MSa4&XZSA5BS648@$ZdAI^nZWkIt^upaTpTGM9ZJWmVyEmcKPp5DCIEIW4lEAt*?\cMMW#BIRW
Yu15T8 ejjt:h9j#8=<d&j9*ppnG6ZM#ANF?Vw1QcKhtcqh9i%L><cp^/FlV:AS>h4k1D4Ki9%wjd$%WdpbDAc$
4Xd\:I wZn>!L$%WWPK!%*=4+9@+@L:Pi?*$>#:?*M?PB#w@PMd>Zw>>j6>VW^McHJ!WqNVW=1iu6d5:K#t=8c$
k1na#j 54KmycWqLT\5cH=?Z86QZe9L4yjcq=?bQ8^@$@:JmX/<i$?ElGY5aNc/mW6CT&kyNG<8GV%#p>E#i9a&
Jh$m=\ 4cAZ>EKuwBi9T<uRDh*RDeHmC$uj/d8%WLXt4GCliR9QJeGRaEk\JBk1Ek\JlkSDkmHBWDFlTDApGBIM
BjqkKB CacKDpPCIeGRaEk\JEiDI<GSkwQjmQy+qTS1\R##>5m\bIJuAtWY#dDWdYA\e=Nl!dDWdaEn\=Hl!CW$
85w9jG d%5FS+al\=BlmK*LeGRaMk^Yj:G5dTF^Y4Y4:W&X1KVwi>61aliaCpELARyMlhmF\eImyeSc*6JSa/MV
1K$=<% 9^C@ED>TXIljRwil\FDec>ycJuKNHtTSZwQBmGi\GS^G9J4c+GAQDA+LDl/5yy6JBw9BapAaAi5SkMYa
:lh:>E cDkbk5ET^<KClb\aLBd:WXumNERYTn%KDwQD+DA+DA=DQW+\GA\Pk<NkMNRnBwQD+DA+DA+DT&QwMDkM
dlZVie DwNd9C6ak<Yema=V#yEn<ln9p:y&?GR>%G8641=1dY%NG^5d&64c$6:iuub&huS\eKCnw!MhH^@4>QSW
DVq+M5 F^eZ84!<%Qq*%/96:d9*%C&Z<V?N?#nqBwel=ad^wZiNn&9+!/h:@mbq5R6!&Mb^/ELV=m=qedEV@Y1B
^\4yRq ^e=H$&/*\@CcR?e+DwHRQV/<eY6n@P#8tN:8@=RjI%#Cu46@wh*HD4HQ&Ke\lV&:b9VH<D%^H>!@eitj
QcM1lP WE5DBBRAAkAIACJYdTXHWGTy/AIAALaLAAA1AAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#
e!Z54q L*M+h&q\bZa8cYN9:bc^c%SBEIeu!eG:IwlyWkYMKeVWY/XTAmpDN1uV#d<RC+5VIdXkCC^ayFDS\mb>
a!6!hm +CwLM*ZTtEJTSQIEp?/I+9nN4kcF8/kkYynht:h9j:69=68h9Z5uMmdnMn6:XcK<G^i=RV5:Y:4!9C6!
lWe>RB bWLpbtnadY^MPuX\ZEcWZ9qI4%id1N#$?**cWL^<^L$&WWPK!&Z=4+9@+@LnPi@Y$>#=@ZQij>PZp>jQ
1ZHBZ1 yNQyTLjdqeuJTbtctyLy/YtbtbtS8dp=tb?jq=YXFXqiZydF^WXbYFmR*n&ZP*heH5ti?H8VX*5jbP@w
NnqZ+^ TB/?iEtElCtYMc9h^CYlJdRWt6eym1:eKL1m1>jHMuyG#*R!i9dmTk#h$A*hEC!?pQTh9q5NXcymGR9N
=RStlj c*k8CaaER+Il\XCRaEk\JBkTDAtGkkqDkmHBpGBIMBS$GBIMCaaER+IlPSweCa+WHQ^GqPWXp1kbM<#4
C4V41! ptFSkm8BFKeKT>pGByWdlWXlKh5Cl<KleGkP#i6Y\cE\KA\KR&!h\1E\KA^Yj4G5dmF^c4Y9&=5KWW:S
9pRyZk >:4X^M+\baJtAtTaM4E#k^puPae94?pw5hGJu+tjmS<y!5VQwePRaen8JY$%E%1mB%tp%&A\+lq5BweS
eNn^mn 4/R&PNkDk<PCk+YXhQPR\YK\GBBG\HIEaDEiNCabk5ET^<KClb\aLBd:WXnmNERYenqKDwQD+DA+DA=D
Q%?hC/ PW+\GA\Pk<NkMJRnBwQD+DA+DA+D4nF$GB\Gl<E6*lZ+\Ju#wDNJNZJEH8N>Wu#HHJZ4<qSYX%hqdY%N
<?&>:R %6jZbZN#W*b*h&X:i%9&>@jq+PBADk<Q=jn+YE=QV&W\GMnJS=euY%8Z:/t@X64#!>DS>q9d65Mt6e*=
1eiaw@ dVN5R68eP^k^Zl$$b&jD^:>:M+$AcGTD5mSN$+=a\Wch$I=c=eaPbYqy>B=XB^hM&Qt%CSipwTBeu5a@
-AeSG5 00057fbca7500110334 Page 268 of binaries2.zip
D\=nQh @n@qeiN?c\J:/*:6Qndtjlj4aZ*$E<aH6J@wj<a<:MFQ*Z+BWE5DBBRAAkAIACSYdTWRe+Iyu\AAAQ+C
9/WB#a AAAyAAAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhHJliT>TbZM9XEFVT$JBWm=JR$@FpnET\nAMBC<^jcmw
$$$Bmk ZjIL?JXdq*/YupQJA#InhDKEaDDMyPHpm:JK=NmiAINFnH6Rq^E+YD/cw@q5H4D#b*qES>pHe1/JaVem
N#A&&y aypX>RHXtlk5<dJY\Re8V*tl=cTy15N<#/yh@ui@ueKn\Vjh<t@h=%&Pd\Q:Yu1epm>:?X:L$FVY?Mbj
+669^h hAWtYwC\$i#qHCh/D9J1%1y%>n<\XM9p9kFRT\MEFAACAAkAQFb6JXMKDcy6AAAAmkEAACkAAABndGqq
6mViF% duS#L*BueC>*cY+#Mm>\b*BFiGNwL%Jqe!>CXXSWV$+8Rp%Re@L6atRAk#Ik%kBmCTAYB&JGBlc\8AlW
GL9maL HlM$kBFDR\PEApEk+<CBA$AcJQIjnBn?@+hRIAkTAlLq6Ac:RYB:JblhDickTICbDA#eeAtk?>llik8A
YaQ@8F ZCTnClBMlBypbnpTE/kVwd+AcCw!B:?VAXBLA\RWAAIACAA<Xt$qRDQVt=WAAAD&AAAAJ\AAAGN5cYX8
V&8#u1 hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L%Smd*SwLtJ6eHYMMR4DMA^FXXKIVRdqGB$D9pH*Z1h$KSm/
Ald$cM GDw$1&<S<JBSPWKQp1tLBqiT8@dLZ$><\#>jQ6B$Fb@E+<<HPFwi+b>m?+!^RWiPdh8EtqS:WG8Dnpc!
a+NbBS 5pmZ6uS!DCEE>@Abmen^qJH*6FQ^TM8Ll68I#A^\n?mI86C@<eu5%kXR!q\1p@d$c&t>Ca!#u:$S\Jld
d*MATt dQwCWE5DBBRAAkAIAD^YdTXCYw^Lj\AAAQaAAAA1AAAAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>T
TVe9Cj bZM9XGSqa*J=eHR8at%\e@L>^kABbWC5AeRCWM#I\AIYd&DABSwkpk$NEAwEka\DB\+AcbDIj#Bm?Q<j
nj%eG& RwEkTAlI#IRCmDteM@uL!=tNnaE$\*j8*=?B>Q@9HQ5*R@kkFj#@Q@ADFSmAnPHa9luI@@?jw&M#mM@A
jt^BTl D8VD#Jw=e\LuBE+RD$/DnIhI#$RAAFBLA\RWAAIACAA<Xt$qcayC9IRAAAD&AAAAKkAAAGN5cYX8hHM9
>b\NJD eGh\L*hydnM!L*BueEX+a&k9WtX#L%SqdtN!iZB$LtJ6eHQ!@eaAAYXA4AHEAqDM!MACFt>k\AWcIJIN
9FITG\ DSAKBIGMA\ePAGtR!H<\a9n@H$KBIEkITM!EAwk=uDP=nWGAe!d@jmDaDKS@j?n+@SuE*>AQ+j@?DXLJ
nmR8Kb #:F@Q:P^5RF@>?@jHN5*M@ADDiQw&G\AptMH<tFtk8kJuBM+\VVIAwkE#N1bAFBLA\RWAAIACAA<Xt$q
N#dkGR Vu\BF+$AAAD&AAAAKkAAAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L%S\b*B4bZq#LtJ6eHYN
FA#Y8D MR:CMA^FnaVWSk#qGI!X8AE:%/Hh5MRAG%=>C<bKZZIpJnypMN<PmAp:>59@68VD<WW%V1khc98yFc*D
8=JZEY b@wZZIjMFb:+=J^Bh!\itXX+8wYt*/CpKpqqaNZ&wh%=VDKB+=JCL>jRa5?ac+6hcG*AjS@eVJeE!n^Q
TP5wcb 9Vap=X:a6h&eyJ$XLPMM@e/?AXBLA\RWAAIACAA<Xt$qWBYbNwRAAAD&AAAAJ\AAAGN5cYX8hHM9eGh\
b+Xj++ L*hydnM!L*BueEX+a&k9WtX#L%S#cYh8LtJ6eHYNP\+CMR^EnaT$5mnCMTl#Bu18A^YT/hJS=^\W6DpG
:VZ#EF ^*DF4pSl^9bKXI#n9GRtu?QyVcp#?wDi4:&ldjlC@!RbmmT<5BlnkP=aDDJLiLtF1c@Kh:mZm\6EcDQa
Iyb!G9 FmuBynTBm&tq!LXXWEu9D+4#8$@qwnCiN+::$+5>u?Wci&ZKj@yQZ%BLA\RWAAIACAA<Xt$qj9hJRbaA
jL#AXb AAD&AAAAKAAAAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L&FpbG6qiT=mdZB%VVEK\#AMhKGR
CAJE/Q VHGj$dGkJhC6i@<TKFRFk>GYdQqKRcMZ@/ahQbX51tS*:euu<=*Ah:q?ZMNhiXRij6!=je*J@RP%JXEV
BLV>BH G**puFW6pZ1eTBMdm@SC:LAm6J?RLSaK+L*IXyB>&hc%1Jj=LicZGBj%@W6BPQcLkt+\ti>TTpPME\IA
484yKD 1WW?<*PaEQuE+$P4A5Be?^LZ*m>RT\MEFAACAAkAQFb6JW%YF<TVAAAA>kAAACaAAABndGqqduS#L*Bu
KGyhVc eC>*cY+#Mm>\b*BFiGNwL%Jqe!>md*SwLtJ6eHXMMR4DMA^WTeGGDMw#Pkd<k?:>T/c/T<HR^hClZ\q+
QAKRjC !Ck@wW@J%EYDK<qhi>Ly^B*e?jKBn19\JJ^?QMDS@AV@pH1aWlehiY16w8w$Y&m6m+=ce1JAn:aM<w\l
5BX@P8 BQ>\EauI<^!S>:^VeWn4m<ddlM\MeE@wmadk*9lp>65KKGW?q%q:*Fb/d\dV^T*PXKJwkhtGL%BLA\RW
&t4JXC AAIACAA<Xt$qN\MK4*+AAAD&AAAAKRAAAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L&Sqa*J=
kkKWhZ eHR8at%\e@L>^kABbWC5AeRCWM#I\AIYd&DABSwkpk$NEAwEka\DB\+AcbDIj#Bm?Q<jRwEkTAlIqEMB
Enbcm* ^B#&e9:!etbna!DN<J*:>&ek@j<:^@:NED=IBj@@D@^ABRaka#m&d\d!@@@u/Nl5ANaN=MQMKm<9aC>k
#TJy1K B@HkNMl+mHR=AkAAWE5DBBRAAkAIAD^YdTYFnMD5k\AAAQaAAAAyAAAAa&^ybY=$e!>\b*A9h&q8M#I9
l+1XEI eGh\SZlncC>TbZM9bY=neuq\hC=mdZB#<9*GAAFqRK\B^AJR#MnAAlb9aMAFGmCTDR$RCkTBnAMHDkBy
#j?hy6 pMl@MGL+@^>CkTBICEmWR\HEHQb!dtMRaC@u*\<Et+H$:\<h9#?D?B9/Ij#j9$E1?Vu&:&e&Nndk:@:>
cI$mN< t&Q:bkb?wGEeHb5N\KaA?VA#RZRBi\E:tAbbAJGAYX5PAFBLA\RWAAIACAA<Xt$qW&pX@IwAAAD&AAAA
b$!hA6 KRAAAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L*BueG6qiZM8at%\ha$^CkJBDEWnCFt\YI>l
&Tw8:k 8iAN:L%LK9>&Bm!$<!1YA>95pc#eaw1abBR4j?dQt=<M=HB<WhQJ9ZN9Q%:SP96K@/S61NwR=a>=uy*S
ME4EEt 5V^p%lAXLd@\FVEkDIEC*RQ>iYRy#uHl#M5%5>k#=?n<4&i\e#<pN?ZCVyttMwBJ/4%1bL5FCd*XYACl
c:5ZE\ *>w*WE5DBBRAAkAIAD^YdTX+:V@HXkAAAQaAAAAwAAAAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>T
jyk%1w bZM9eGh\dt>*LtJ6eHQ!@eaAAYXA4AHEAqDM!MACFt>k\AWcIJINDSAKBIGMA\ePAGtR!H<\a9n@H$KB
1MeK?& IEkITJRVCYbP:ajRM&iGk?tP#yuVkjTM<9KKTCABa6hZhQTZp\kAWE5DBBRAAkAIAD^YdTZXTel&=\EA
T4CL?L AFRGAAAtAAAAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>TbZM9etXlbC=mdZD6XL>4FEEajVj:+&=!
QlVkKN h?F&*WbDbQNeMa$RepGIShlh6w^!^eX/C!54MWHRKwRnJMFm$#qhTFIaA?EIce\%Ek+5dASdC?5W?R8C
hMHlXT PLPHE9A9EP/^H#Q5?::*9Y<GJu*ThXHmpR*MtqYH4/MCG$K9h\Z?kY$LHS8\4*>lijpy:N+Gl5ML>H1d
*D6V?H iL+\n:Y%%:nY*PHlQwLA^>ubKaa@L6D6Q5Maa+#^j/MFq>bkt6A9SEMJPIS:@qqkptnGJH!G=VMlyXTa
&tNCZ: qIIMn@8R5Cp!NESW&R%$LcbpwR1ybEH!jFBWFaI=MlN^5y8pJc?pLHRP?iB!WLkK#WY6Fae6XL&KcjFR
Gn+\16 /!9>GaY*A:YqFw6TALY5=B&JAqZ6ELNG=EX>T?iWKcHuBVj>#/\jj%L1@dbkFDQMpuKCXnubq/>9aL!6
mlp%?t p=Fk+1YtnuCeQETV1P%6L8%WQ?KYaJ!RNp*yH:=B*D8=c5<hKbYVRidVVt@!hTI/?hB8%+?WyY%qtS>t
mm!$VF HPqHVt=&=PZ*yVc&9=$!1tYw@iZ9G>:E#kFY<Y/CuIulbyD?!ILJtZb!EVyG+/Bt+T4W>\a9Mee:5kGL
=whiXR 8PN&+Hd$AV:?8jj!FTVSTt=:/cmQVWlubcXVX51<*+ib!jL$@?1wnWMZE@1WX1%=VJqd4j\GWE5DBBRA
^wJt9+ AkAIAD^YdTXi9CJB&\EAANRCAAAtAAAAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>TbZM9e&X8bC=m
J8VmHL dZBNpd>4FEEW^:<*<^mY=Yc=Z+SDTHNXRNEJV<KYl%YKKGu5k5&J6bYXlb5>bE9@AiH1\!1KnaWmKa<\
uBLam: mVaYW\u?E^/H:?%h\GWj:M:*M>@*uViQH9<$cJ>ZWkhT^%ID1R+IKn*d/j<@SEd1HQjwC4ViaD+*8L#<
hK&kVP np<jNqm4Nn@H!epV4NeG4<>Wj!9jw1$&iQ:\CkheaMDTn\*!bN+SI!<6B?py1\M&waC^^PShA9&K5qw$
nV5&Cu 68^en%uVMTn+ZJSwXjE^4hL:mC*%y418/q51m45um^=:aXbJuX^yP*B>M&!bP!H=lBTVDhc9wQ%YTqFn
$T?i1F 5<cwWZa^?j5:X:hE$TV!E6pGhDZ=N@X4=I@/IA*uJ1AH5+\^Cmq/jT**h5p+c+ccZ/C:Z$AVM*P!P$T9
V&NaIq ZZ9S!\BiLlhhaYWYXd>8&iLmI^>>uZ^Yn?&y</kkHKSL6<!GHG1hG8lG@M\jE85jMn<Wmp&Zm=a:dCwP
tTFkCC #ba:t8XML&Rt+e^1/StE%Q8&nq$DN\^Ni^Mn!dKDIFq#VCYkKKdMBNn/dSp\Vq9GlcqtE?lRucyR6$=:
umN#?> 546:Cuqqpk:cdauMq8N>G6</:et>8/jG=45<+qJ\6h?9h&uG:GTlVdG\8yL*>jC6hy<%@WnQ%@pHWE5D
wJ59&c BBRAAkAIAD^YdTXyC>^BkkAAAQaAAAAtAAAAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>TbZM9e&qu
N8MH=J dm=mdZB%nV5PAnEMSI&E=IImHIM!b/DuP1SC<udyPM\Y&?aaHMMX8^KFGh54WVGJ<?KbjK/*N/Z81A91
YRwei1 9NiBn8EL@bNpKJL\ke$aA*VHayJb\whdYN18jIhdmR=EcC9aN!uB45Vkbqwye8$XXNLuVHH?>KqeFMa!
pc/lSj eh#uF*8?!mN/bey@&p>jWE5DBBRAAkAIAEBYdTWi%Xk>9RkAADcBAAAqAAAAa&^ybY=$e!>\b*A9h&q8
Dw8##? M#I9e&lletXpL&q6aYhqe#I$LtJ6eP%h9a:eNlBt<kRy$:pN>kHeLyA?yiy>qFWCI$<S+F!pWlWEeL&8
<jRhn* ZBqJ5&YAjaZ$KSn?mS1SHHKGS&pqY<J+jd9*HY>tKM%<M/S$Q@:$>thln4j1*\@1*^@jC9Gh?9<d<d*>
ZuFSB$ l95?QKTRZ=ka1<AH@m%mLBi@qlX><bP$LcXyZeji=jVj/qq*#Nh8bp1I:85=j\+==C5ZGDQh%<TRT<P9
A#1dY^ E4J/GBDmV=KSaZkb4PTn^NL&L1*@JqQMMX>mD#N%N+JTA5E<9k:@L#&#+4qpiBMJm*PC%b&RFe:5\XG$
X@tLMt kkYPDXpc4/?Zl?^i:wXI!<E@JeWWk+M%SIWF?jt#FS5mmw=c#6/q>h<!JVntc<6<aLlbX6Bnh9*:u^^8
-A!5VA 000dd7b226300110334 Page 269 of binaries2.zip
eMS=P# A$Wct4^6@+8FKaGRnek\N!X^<R9qL&PYFL?<C\ZuA!^<lVN:=MmANVY>DS@@?cmp/FKu\Qp$TdEtE8c!
l:@!Xn iI^C\W?Dh$y5<E#?IBj@^BVDDR/WELGC9a919<G8/VFjkXdWttZJA&5S=CP#wkSYdNJZ4@/V+F6:9F++
ZBWQJT PVwR8jV+!wV8e9Lm*^dJMC6@XiDHE/wDR5lHNL#/@N&9:*!P@9DuB&HVjTM<6:JRj9n>@j6AMBhbMCRD
&!XGRM :kJ=GVB@85^:FW:t4CCHH@uAIAeq?t$i:<dZ@qetY%GGB:b#<h6ySBjnk#6H59FlNZ9d/y?lh84EP?b4
l!H4hn W@44WKn$9A^G?X#aqI>:V#6eKJQPA$YyeBHpA++MZGTTE6n9e4qbKauEC\jyE^:#9\*hLjSJ=88G>wwm
@t:d== JZAJ%Z&SI<P5@FYBH#P:V^m#LN<EL<i$@8u^TjncQ>5jwPP=qaW4>wFAF%H+kL&Ieu#kP8i@ulXk@4#P
EqT^aN tkPKDKljwTqBH6?d=H=&#welNPRDHQ\?/p%#&PCR!T?4&h6Yj:>c&q&/8A#eAl<+=584yKQlVVyS1y/u
X^t+$l +km??5mtKEFSQB<\ecA5tI9!t\plH:Bp\EyMCV\j$J!H$$DG<Eu@J@Eb@?9IjL9VYRG8D=15y+tkna@k
&5c<LJ e@$H=%k%k%i4Y+EM5@JZBX/pE%miD@D\5N:@:i?@YQ&BIy=XYjnP@!T+m?#dkA@+FwFhPEk+y=>*@4PW
V+I:qy IG+P#FwED=HA\@HH?Kp5VS4P^i>yQZ1MD+Xme*q:&?49XuXjB981KIGTbQ%a6+Lk\\J*G\#S*lT?aP?W
8*+Z+p RAu#6WH>y:!5KIHyEuR*^^Q<c<\H^J8Vt5hP&j9tSPEDEE@tA:u:C+L%A6kj<AVAEwPJD>l&^GWkht8V
Bw#SWP iM#@PD:6j^&b:WqmYEG%Q6n/91jjSAbP\+iLET=%ZkhA?XE!#MyjFZk^Ja\:&I?Kyuk8Q1n*y?a@4V>A
=:q!SX \dM1C?$jpNpDF?Z=AQ^B9=EkeWw<IuG%PaMQ\I$E8jG6%YMI6XG$B>GMm&?+ep&M&+BXVlX\1@*G4:H*
8GA&5a Yjy:Q1BwAQ\mEJ>mKJ%1cJSKN?:MJ/VWiQ#<@9CpQlq:A*^^9ncw9?91Z\dHB$!LRL$N^Ph*!AhWe6e^
6S>KQq lNaj<Hl/j!BQCRI?+CmBIRDth=?$nH5PS#+\/Lm1GM/LyG#wm9Eb@&Qna@+*jPC8%VQS9pkJcQ1LwN/*
M+CEXS T<QECEuAm:mGuSb>FC5\^AAn\/#<XaE*44%HateH+\MM@H4*F>A1RYX?pNP>m\y<IKIE/t51H*mAFpGT
ZqJcn& D!nyEWyA=kQ\%KL\kTT?a8Wc!=5&hMijJ?8%aQ^<9Wd@uGL9B9Y*c%KYCjkAGF<L>E:%bPtaRdSy6<q\
LJF%Zb ?D1Lu/u^dimih<L:LD=>FTj\&jucy9/iD&k^Q&9:A+Ep?aA?aXK5INMjTLKCLB>Ad#tM>^QC8\qmQ8Cd
^GSRSP Ib*/cVIqmQGb=\>p^p>iL!w+c@Wpk^J\>jh#RctGYHla\<+w\hnHmI5ZX9/1\CQ=@R=Kj9EcjFL5ekD&
\T<A4d qkKw4kT6j*#Dj*JSqk<EqMC:FPMDW:ij#ki8!EJDmk@M^w>C1JX1QG9q&mbNX:LNX/tT?bR:jkN<%6=6
hW=pZ/ /t?D5C@bMD!>W^*#ATZ8#Jjn=?N4>jlN<Ju=&1d?@1iC%J@pd/96H+AeAKME\j/B/W=pbL&kP1W8mq?B
#%ck<A E4lL:<%JT#9<hJ=jl:lFpC^iYQt4At@#i*iYT8l<kI=@Cl@AKpH9I4<uMQbQ<p/NGTWaJdPjeNwRGQCB
4i+wlm #Q$CpBL$Bj^5@DmEun6+:hQ^*JX46<>HSVD#cy$bB#ejwm6Y^q?Q#>m:bj$lB<nkmb%1!Aj$CR>K:KB<
$@SEK/ 5L!wd9\t?Q^<dXN@TAu5ynWML<e!H&MCk#kykZ#A+qE!aQBSm&@&JCL5\WRBH@B:?LH:C%bL<S8pBQdK
a^%\!\ yXMCCu=&ul5caPc^e#9&w?KqIu>X+QZ9Q15bD%K<T$m9^>j^kYqL+dm>pMwHpEw\&GIBKXPSD&C*dKD<
?6JAYh 5J?Z=El#IPRDulXeT@kiKjqH1eP#X1=lQ6XyFH+^Q?J<Tl!@FS/#h!@/b@DEVuZAB*^KhjX%IFE?Ja:j
q8<L>e Cy?b4<*1Q&$F!?IqcQ8#?EC<l#DQB?CVmIl<\B?W=\@+qG1ZVipyjmG<y\V&K1bVA4w?#TqBItH==kBT
H/ZuD5 *HH#X\ZiXmH#pn>Z:HQ^TV=RVQeY++Y$pdlWKRhbHn1u?D\m?5Mey1W8&B^kQX?I?Q\m:9kqQH*qiybQ
i1^T!l jTa%yZTm/%+:@6L+9i6Q:%VDjC4u1VN9L&9<yjF:%>?6F%CP^**cd$A+BmqV@aF:@5HF>QElC\$iy/Dm
^hpCXB b*jYRptSm?I6JVBZ5SaKJiD15\aqECB=SeXhSj/1\I>uLm#&Ke<nw8I^T5BK>&^KkDn#m*^ieT6<5HJN
/u:DKC &1<i%hF=HXnnL+*j8@=By=y$$$SWS#eej&u<49Xj:jtE\VMJjbS8@9eL#HaZ&X&$WN&%JF=#AH*:wSdm
?RJ@9l HalejcaW*\JQ4&G@tPeXH:LV9#i^&9*5#<Z9Zj>n99cq@&y@9CDwFXD?ltBh8ND=>$ZT5<cm?LFLIPpQ
i>eNBA KiL1+%J<I#!4ln*ppEMPPiTRCpwRLB\5YpF5B>@8PedQ\S?!n9\QWE5DBBRAAkAIAEBYdTZY1%/!>kWA
i*b$Q: AQaXAAApAAAAa&^ybY=$e!>\b*A9h&q8M#I9e&lletXpL&q6aYhqe#R8at%\:blBm>6GFMjHT%qyc\bb
d:tnan tEKYa6n5yeWuC@eRMIFTe8%*!Cqu$WPqJC\T=GBBCcqQ\ajRhuMI/GV\IREjtk?\AT%:eQa\*<Gu#tEQ
Qw@/LP /u69S6Ja68\$Titq5:b@P*w#a?p@@^p>?aej@@1KWjpb*6@Ci*dAYAjaaq@R<XnH5ZV$Y=YaZm!PFjAQ
M&5=c# @uu:>m$Rn?V$aut8kH>+CD:Eb!k>ipFlHD@dm>tC:+n@&?Ne>n=5@Q?+bI6Fi&b\<#yejPHyBn/ult!&
BkS4\A K>/w^&ecb+1NC5h>YQ>*ap6>a%/*F9\Td4D1Xu^=E>8#Nni=Wh!iT#/\kpANGQKh<cd!teb=QwEQJ/Dm
SeuNh@ j%n@C:GqZ5!4dc8DBhj%eadDIVhah5M6R%%F1Hl!wumiKnI4N4uNcGTD4LkPN&a:+$$L<b?N\:k\jGu+
bKAZcm <@wFZ1cWqyVT**$iY5YLm*j%i9dk\iF>t6e+Tim/C:JPl^t$&i5=N%naIdN6G$<^5<aBH5lPV$?y*8?@
I\pa4I ?wtn#Lh9MaQdncdP%:j\jK?/<#q9n8MkN9@pedJpRHbJ1MRFm/bP=Q<cSbFj#A#V@bu8H^nHReeLX18L
<mTV:d \@8HLb#Z>#k54=m=455MPw<jK:>1FudIjN?Q5X$TS4k<59Q#<^QTN*$qPe45nWcDp46<F1*IB=+:G9HG
R5tY%5 iBdAnhVtu#^Pi@GEbSuwS!X&@1TC8q/T49LwISnY6:XkTP\QyQ=BWB%Hj=46!L?bQcB=#eI\Tb/KmyQJ
eB:M%: yMM4d9lX&<Ecn^Me#Ac@Tnm6L@9>@muWD@4>NQkhbH:yh8i#pn9*^SZ6Y>%d<@tkMi=EIjt1<H=\Xt+N
EtKS<= %A=I:SlZ+#VFuj#N1N*tnq\qwF@5*K#5>5%NZPRD/NiASd/h1P>Bau<p>k@$8Cy?Ibl8^*ShZHbbC?eX
GV#XA$ >BpumTl=hH^<:LKKG*:Xh4DDMQSn*GbD&uaP$lRMC@ZVNE%@B=q9i:?Ml4!kTlH$=C+DbTQYM8?#unj/
IKNe\B nnjGuXA?!@PXZ5bmKbX^wE:*c#!P:aA$VtQeijdtD1:@!E?WZ&hJ49\1ZQJ4d1%T!:ej1?<BWu?5a@>A
9pkC+R n/9m:$AG4V<S6q59iVLAiW&CIMV6yYB4PkYnX6#IB:T6+Pa+%u+hn>G9IGjl%@REbH:b:e/@L$tcb4HT
AS&qYW dCuJS#&dp+@$8?6/5BCc+w+e+^uwbT!mZAdLycBq*eqED+puCKS^G8NP5lk6FnQ\c=\w9<cJ<18a>NC9
5G%ct+ +JLW<dMd6V1StL>THjw9e&ZaMl/#NX==6=IB?kQ$Cem9tpjV/bV<1wq*NQGi+$66:6yYhlSw9!bkZNA%
bM\e44 KQ\KG!*+Nj*D/*+>KCt5EJ<<RBAJZ!VL:hJk!?9Cit&K?@pK1be^/ky&P!94Bn$ey#H8*C^R+M*>>dJ*
&!wZj& :iL$MScAMaY#WIc6M>KGLiyMJ^?cX>/hbNkC#ejk$^CGLZn$ZQt$+Ic8!qb\\ZJM>#ud5m^p>Ck>SaJl
&KmA5w ?^^qlwb8!W^K8nE8<#!A=:Y#a45$mEd4NeibVXVLYESSnuqtYVe+^HEc+*E?I>1RVeq:5YQjRLpZ+&QB
6i//yK NSnYmR:9a#+kVMPc*DB5\p^iDd6*P8mQ>&B<!ke$5><iVq&Dyc+^W:yip1%EB8pXdw5bQ9Im9*q$jp=%
<pD69h TLk+!w!?1TmjlcAZ/ByJ$p%6q<IpNBT:+pT%nEWW=FGi!:J8E5hyn4M&$WdHw1:wYNV%?aS$Bd?1@NX=
L?IH1B 4c/*Vym\6d16Dc5I8uaHMK?a:adlW%H^GH#KK$JJKL?ldIH!Ai\G^l?QXb=41%!DyZ*Fk\NGM4@58ue4
%68Y\w =1GQ/je!q=J<yLdLDi/L/&WMX+h?QC94hi/LP#tXXWH\/\9T6c^uW6*1/!\NY^^jN?#R<%!aX>Ab:n@C
t\*<h\ IJ5iM=PW&y4yn$jh>n*HqnJ4PnuZ$/*PCp>>C@jF5%#qdKD@Y4*PjjHN=/$Z+u1!>98ANXXuZGipW/&m
Y%Lbj9 d5etl<P8y/+pn6hb%?pnT&&a>S!4imT6e%><T@:/WjGNem&tp@Wjn9T9AZW8%e^Z^^PVX<QlZjF@MZ@Q
q!HC+h t6ch$eBkV@^V!6>RT\ECFAMWAAIACAABX&$qlieQ#aeEAABtEkAAKkAAAAAAAAAAAAAAyIEAAAAAdGqm
aJuMX> e!>\b*BnbG59h&q8M#I9WEhRe&S4XWp9WtX#L&S5b&qnd&+8cYN9WE5BAlRDFAACAAkAAXh6JbWHm%F:
kjcnp! CAAANu+AAC5AAAAAAAAAAAAAAKTB#\RAAG^yauM9eGh\a&S4L*hydnM!L%BHWHNpc%XJL%Jqe!>ydYFu
pa^/NW bZM!NC=mdZBRT\ECFAMWAAIACAABX&$q!He?C6aFAAB&FRAAKkAAAAAAAAAAAAAAyIGVDRAAdGqme!>\
u84JA< b*BnbG59h&q8M#I9WEhRe&S4XWp9WtX#L&q6aYhqe#R8at%\WE5BAlRDFAACAAkAB%X6Jj9*Z@RPCRAA
c&#ui/ 6p5AAC+AAAAAAAAAAAAAAKTB5SMAAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jqe!>DetXp
cqtk:D cZS#MT=mdZBRT\ECFAMWAAIACAAHXY$q6qwhQb\TAABPKREALkAAAAAAAAAAAAAAyIELHRAAa&^ybY=$
8lWE6y e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9WtX#L$N!bYSyhHM$LtJ6eFBLARIWA^RAAkAIAAlXdTY\?X8y
%p!\tR /^5AAN=RAkA8AAAAAAAAAAEAAACpkjM9AABndGqqduS#L&Sye&59h&q8M#I9WEhRbGq#c$F\eC>TbZM9
<y=96B R*JqbGq$e#k8at%\WE5BAlRDFAACAAkACFX6JR$F^&n#DAAAjlAAAC+AAAAAAAAAAAAAAKTBKp\AAGN5
8Y1@%T cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jqe!>VcYSqatF!MT=mdZBRT\ECFAMWAAIACAAIXY$q
$:SkQJ ky&BS/EpAABtQRAALkAAAAAAAAAAAAAAyIFyYRAAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9
*ZdudA WtX#L%NybGXmaZI$LtJ6eFBLARIWA^RAAkAIAAlXdTZ4LmTnPqpAABb?AAA8AAAAAAAAAAAAAACpkXb?
-AX6L+ 000b28487fa00110334 Page 270 of binaries2.zip
khE89t AABndGqqduS#L&Sye&59h&q8M#I9WEhRbGq#c$F\eC>TbZM9W&qpbYJlenk8at%\WE5BAlRDFAACAAkA
%c!SP* CFX6JhtS=h%VLkAA6p5AADMAAAAAAAAAAAAAAKTB*NeAAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4
<6AE&G RZB\L%Jqe!>VeG^le&lVa*JqbY+^LtJ6eFBLARIWA^RAAkAIAAlXdTWybYQa/HkAAE+yARA#AAAAAAAA
lSnI$A AAAAAACpkaAGARBndGqqduS#L&Sye&59h&q8M#I9WEhRbGq#c$F\eC>TbZM9W*B5aZNwW&N!bYX8NC=m
FZDyS= dZBRT\ECFAMWAAIACAAIXY$qpTdBy!wDARDiWAIAM\AAAAAAAAAAAAAAyIG=j\EAa&^ybY=$e!>pcZN4
FRi4EL L*hydnM!L%BHWGSye&6BeHA9WtX#L%N\dGF#cFNnetXqdnk8at%\WE5BAlRDFAACAAkACFX6JSy>T5Gn
l^DSDq ARAA*kMAADIAAAAAAAAAAAAAAKTBNIMCAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jqe!>y
a&KZ@^ a&>8R&F\e$^9a&58cYN9WE5BAlRDFAACAAkACFX6JaPqnA^8ARAANkRAAC+AAAAAAAAAAAAAAKTBJ+WC
8pVd9M AGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%BpcZN4RZB\L%Jqe!>ya&>8VYFydm=ya&>RT\ECFAMWAAIACAAJ
6pPR:n XY$qh9tScceCAABKDAAAL\AAAAAAAAAAAAAAyIHllkIAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6B
ZJ=>t$ eHA9WtX#L&qnd&=Nd*X8hC=ya&>RT\ECFAMWAAIACAAJXY$qJ?XnZ8+CAABKDAAALRAAAAAAAAAAAAAA
Db4iPb yIHXmRIAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9WtX#L&qnd&=PbZe8cYN9WE5BAlRDFAAC
HI<phA AAkACXX6JY<1WRB>ARAANkRAADEAAAAAAAAAAAAAAKTBDw$CAGN5cYX8hHM9bGq#c!>*cY+#Mm>RS%Bp
wLjSQE cZN4RZB\L%Jqe!>ya&>8WEhRbGq#c!=ya&>RT\ECFAMWAAIACAAJXY$qwFwI\Z5CAABKDAAAL\AAAAAA
6RcN:$ AAAAAAAAyIHcnkIAa&^ybY=$e!>pcZN4L*hydnM!L%BHWGSye&6BeHA9WtX#L&qnd&=RetXte!=ya&>R
F+Vq%5 T\ECFAMWAAIACAAJXY$qb/RwT:WCAABKDAAAMRAAAAAAAAAAAAAAyIGmpRIAa&^ybY=$e!>pcZN4L*hy
NH#Vib dnM!L%BHWGSye&6BeHA9WtX#L&qnd&=Xdt%9hY=$Ltqnd%BLARIWA^RAAkAIALyXdTX&#CS&5\WAAFaP
qkIwnh AAA6AAAAAAAAAAAAAACpkccWAkBndGqqduS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY+9WtX#L$X%bG>!
ZCcm<& aT=mdZBRT\ECFAMWAAIACAC/XY$qA^6SP=<AAAA?ARAALRAAAAAAAAAAAAAAyIGptkIAa&^ybY=$e!>\
?+#&\A b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>lbGS4bZp8cYN9WE5BAlRDFAACAAkA8qX6JRSYHuYZAAAA
CFQ*F* QkEAAC5AAAAAAAAAAAAAAKTBny5CAGN5cYX8hHM9eGh\L*hydnM!L$X%bG>!aXB5hYhydm>TbZM9dG>n
p>5\G> c!=ya&>RT\ECFAMWAAIACAC/XY$qb<I^1F5BAAA&BAAALAAAAAAAAAAAAAAAyIF8uAIAa&^ybY=$e!>\
p:c+%@ b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>5d&N4MT=ya&>RT\ECFAMWAAIACAC/XY$qet#HppIAAAA?
M&:+l\ ARAALAAAAAAAAAAAAAAAyIEVukIAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>5d&N4
:RD>Ge Mm=ya&>RT\ECFAMWAAIACAC/XY$qCk@+H/WAAAA?ARAALAAAAAAAAAAAAAAAyIGjukIAa&^ybY=$e!>\
kq/SbX b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>5d&N4M!=ya&>RT\ECFAMWAAIACAC/XY$qCk@+H/WAAAA?
LJTdb? ARAALAAAAAAAAAAAAAAAyIGPu\IAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>5d&N4
Fn8FJY NC=ya&>RT\ECFAMWAAIACAC/XY$q5#KeM4MAAAA?ARAALAAAAAAAAAAAAAAAyIF>wAIAa&^ybY=$e!>\
YQ6XcC b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>5d&N4NT=ya&>RT\ECFAMWAAIACAC/XY$qcQj%#baAAAD?
P!^4V@ AkAALAAAAAAAAAAAAAAAyIF/wRIAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>\b*A#
p1Z?6q Mm=ya&>RT\ECFAMWAAIACAC/XY$qMM+Ia8+AAAD?AkAALAAAAAAAAAAAAAAAyIFcwkIAa&^ybY=$e!>\
y5!Tnl b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>\b*A%MC=ya&>RT\ECFAMWAAIACAC/XY$q46+pcteDAAAt
9LCXZF CAAAL\AAAAAAAAAAAAAAyIGTw\IAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>!bYFp
QpqTw\ hG>9dC=mdZBRT\ECFAMWAAIACAC/XY$q%@lwPh<DAAC8CkAAL\AAAAAAAAAAAAAAyIFGy\IAa&^ybY=$
+t8D&8 e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jqe!>#bY=phG>9dC=mdZBRT\ECFAMWAAIACAC/XY$q*T=c
aiK8nW C$5BAAA&BAAAK\AAAAAAAAAAAAAAyIF!1\IAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8L%Jq
ITFApY e!>#cYh8Ltqnd%BLARIWA^RAAkAIALyXdTWDu8D@bkEAADaEAAA6AAAAAAAAAAAAAACpkRc6AkBndGqq
Sl?nPA duS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY+9WtX#L*bqetqtiT=ya&>RT\ECFAMWAAIACAC>XY$q$B^N
T>euCD HPAEAABtEkAALAAAAAAAAAAAAAAAyIG*4kIAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8XnR9
^H%imK WtX#L$6qiT=ya&>RT\ECFAMWAAIACAC>XY$qtEy:64aBAAA&BAAAL\AAAAAAAAAAAAAAyIHl5\IAa&^y
S\<=hH bY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8XnR9WtX#L&FpbG6qiT=ya&>RT\ECFAMWAAIACAC>XY$q
R<?Xt: $Il46J<AAAA?ARAANAAAAAAAAAAAAAAAyIHp6RIAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8
b%14X1 XnR9WtX#L&X8a*J=eHS#cYh8Ltqnd%BLARIWA^RAAkAIAL%XdTZjl546ykAAAD+BAAA6AAAAAAAAAAAA
ENEJd1 AACpkhY&AkBndGqqduS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY=YNC>TbZM9dG>nc!=ya&>RT\ECFAMW
t%&uHV AAIACAC>XY$qMM+Ia8+AAAD?AkAALkAAAAAAAAAAAAAAyIHG6\IAa&^ybY=$e!>\b*A9h&q8M#I9SZXp
T&*SF5 d*JlWG^%b&q8XnR9WtX#L*BueDW\Ltqnd%BLARIWA^RAAkAIAL%XdTWMXyJceREAADaEAAA6AAAAAAAA
DGD$>% AAAAAACpkRC=AkBndGqqduS#L*BueC>*cY+#Mm>FhYS9etFRdHXucY=YNC>TbZM9e&qudm=ya&>RT\EC
ySYW>> FAMWAAIACAC>XY$qb<I^1F5BAAA&BAAAL\AAAAAAAAAAAAAAyIG<8kIAa&^ybY=$e!>\b*A9h&q8M#I9
S?dX%= SZXpd*JlWG^%b&q8XnR9WtX#L*X8dG>nc!=ya&>RT\ECFAMWAAIACAC>XY$qA=:k@&aBAAA&BAAAL\AA
hpyRdp AAAAAAAAAAAAyIFp9AIAa&^ybY=$e!>\b*A9h&q8M#I9SZXpd*JlWG^%b&q8XnR9WtX#L*bqetqtiT=y
QmHptN a&>RT\ECFAMWAAIACADhXY$qik*q6*n\AACaYRIAM\AAAAAAAAAAAAAAyIEZ9kIAa&^ybY=$e!>\b*A9
Z%eq%6 h&q8M#I9TY=#hGF5dGX!L&J6eHM9auX#cY=qe*M9e&X$hZA8at%\WE5BAlRDFAACAAkA+FX6Ji=ei*qj
=TajH9 HRAAbn$AADWAAAAAAAAAAAAAAKTB+K+DAGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^qem>mdZB#L&J%
k>Yw6y e&q8bZN#L*NybGXmaZI8at%\WE5BAlRDFAACAAkA+FX6JTaEN^KnMRAAFu+AADaAAAAAAAAAAAAAAKTB
$4bNq4 p5\DAGN5cYX8hHM9eGh\L*hydnM!L$q8e*SldG^qem>mdZB#L&J%e&q8bZN#L*NybGXmaZJ+LtJ6eFBL
Sa6#8d ARIWA^RAAkAIAPBXdTW$9lkd5?<AAJlbAkA#AAAAAAAAAAAAAACpkau?A\BndGqqduS#L*BueC>*cY+#
?jMy4R Mm>JduN$aY^5bZI9at%\e!>tetXqh&F!bT>#bZS%eC=mdZBRT\ECFAMWAAIACADkXY$q#khabbwjAABt
wB9Rmi QRAANRAAAAAAAAAAAAAAyIGN:kRAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&J6eHM9buJqbZhl
=jbIH/ etW9e&qpbYJlem=mdZBRT\ECFAMWAAIACADlXY$q/1Vy8h5\AAAYjkAANkAAAAAAAAAAAAAAyIF/DkWA
SnS5:S a&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&J6eHM9buJqbZhletW9e&qpbYJleuk8at%\WE5BAlRD
h+5nQ? FAACAAkA+XX6JY%#q</uBkEAqqpCADMAAAAAAAAAAAAAAKTB1V<FAGN5cYX8hHM9eGh\L*hydnM!L$q8
VWJ/AL e*SldG^qem>mdZB#L*BqeuN9dtF5L*NqhHX\LtJ6eFBLARIWA^RAAkAIAPFXdTW8NY1+4l<AAGa>AAA%
e/dJIi AAAAAAAAAAAAAACpkcFGBkBndGqqduS#L*BueC>*cY+#Mm>JduN$aY^5bZI9at%\e!>\bZJ#d&=ldC>#
SDq+e+ cYSqatF!LtJ6eFBLARIWA^RAAkAIAPFXdTYVEYCV8C<AABb?AAA&AAAAAAAAAAAAAACpkcJtBkBndGqq
SjjAhu duS#L*BueC>*cY+#Mm>JduN$aY^5bZI9at%\e!>\bZJ#d&=ldC>#cYSqatF!iC=mdZBRT\ECFAMWAAIA
c$MitY CADaXY$qHT*Ywc\VAACmNAAAL\AAAAAAAAABAAAAyIG8qkaAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5
KWC$c< dGX!L$X+hHJle!>*cGF$e&=qh!=pd&NRT\ECFAMWAAIACADuXY$q*8$qlYIFAACZBRAAMkAAAAAAAAAA
a9TJcW AAAAyIGu1kaAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L&6qiZJydth#L$SVeHXmetq8b!=\c*JR
<KL#I6 T\ECFAMWAAIACADwXY$qtGC6=SD1AADTGkEAMkAAAAAAAAAAAAAAyIFb5AaAa&^ybY=$e!>\b*A9h&q8
=pD6lu M#I9TY=#hGF5dGX!L&6qiZJydth#L%BReHXmetq8b!=\c*JRT\ECFAMWAAIACAD^XY$q\!qSRSEMAABP
#u%t!P iAAALkAAAAAAAAAAAAAAyIG=tkeAa&^ybY=$e!>\b*A9h&q8M#I9TY=#hGF5dGX!L*SqdZB#hHXtbm>8
5w<kLy bZSlLtJ6eFBLARIWA^RAAkAIAQSXdTZ&:eydJAEAADaEAAA4AAAAAAAAAAAAAACpkScuB\BndGqqduS#
-A!m%/ 000ac7a592e00110334 Page 271 of binaries2.zip
5LMD^@ L*BueC>*cY+#Mm>QSY^9aYSqem>TbZM9bY=&bY^9eGW8cYN9WE5BAlRDFAACAAkA>FX6JiIwBCHVAAAA
&?/HDl NkRAACpAAAAAAAAAAAAAAKTBk/kHAGN5cYX8hHM9eGh\L*hydnM!L$>FdG>lbGX!L%Jqe!>5bZS$bZI8
T>buZI cYN9WE5BAlRDFAACAAkA>FX6JcD$pKKRCkAAqmeAACkAAAAAAAAAAAAAAKTBucpHAGN5cYX8hHM9eGh\
W%Ntc< L*hydnM!L$>FdG>lbGX!L%Jqe!>6e&q6dm=ya&>RT\ECFAMWAAIACAD$XY$qdwa1=ywBAAA&BAAAJ\AA
My4q?5 AAAAAAAAAAAAyIF#6AeAa&^ybY=$e!>\b*A9h&q8M#I9V$X5d&FpbZI9WtX#L&=qh*M8cYN9WE5BAlRD
jQ8nni FAACAAkA>FX6JcD$pKKRCkAAqmeAACwAAAAAAAAAAAAAAKTBW4aHAGN5cYX8hHM9eGh\L*hydnM!L$>F
mCyIkt dG>lbGX!L%Jqe!>\aYN4aYhqLtqnd%BLARIWA^RAAkAIAQbXdTYL&mk*tAAAAQaAAAA9AAAAAAAAAAAA
w8>1l< AACpkT4BB\BndGqqduS#L*BueC>*cY+#Mm>QhZS5d&>4SZl\etX#e!>TbZM9aYSpc&X=LtJ6eFBLARIW
w#n#8$ A^RAAkAIAQbXdTZDX!\4l\AAAQaAAAA\AAAAAAAAAAAAAACpkR@CB\BndGqqduS#L*BueC>*cY+#Mm>Q
u@bVG! hZS5d&>4SZl\etX#e!>TbZM9bGXneuq\hC=mdZBRT\ECFAMWAAIACAD&XY$qcayC9IRAAAD&AAAAMAAA
FNwl!C AAAAAAAAAAAAyIHp\keAa&^ybY=$e!>\b*A9h&q8M#I9V*X$dG>9c$X+eHJqe*M9WtX#L&X8a*J=eHR8
RCITN8 at%\WE5BAlRDFAACAAkA>qX6JW=<ASiNAAAA>kAAADAAAAAAAAAAAAAAAKTB65MHAGN5cYX8hHM9eGh\
b8Mui4 L*hydnM!L$>%hG^9d&6FiHB!bZN#L%Jqe!>\b*B4bZq#LtJ6eFBLARIWA^RAAkAIAQbXdTY*\<mAy\AA
pVQW1t AGaBAAA^AAAAAAAAAAAAAACpkbHEB\BndGqqduS#L*BueC>*cY+#Mm>QhZS5d&>4SZl\etX#e!>TbZM9
mq&CtP eGh\c&X=e&\8at%\WE5BAlRDFAACAAkA>qX6JV9wKSKZAAAAbkEAADEAAAAAAAAAAAAAAKTBl<WHAGN5
Ja=m8= cYX8hHM9eGh\L*hydnM!L$>%hG^9d&6FiHB!bZN#L%Jqe!>\b*B4bZq#d!=mdZBRT\ECFAMWAAIACAD&
ST^VdF XY$q8CkNFyaAAABtARAALRAAAAAAAAAAAAAAyIF6^keAa&^ybY=$e!>\b*A9h&q8M#I9V*X$dG>9c$X+
K#*Z4E eHJqe*M9WtX#L*B4dDR8at%\WE5BAlRDFAACAAkA>qX6JSn\QtiTAAAAbkEAAC$AAAAAAAAAAAAAAKTB
LQaVMY V5eHAGN5cYX8hHM9eGh\L*hydnM!L$>%hG^9d&6FiHB!bZN#L%Jqe!>\c&<$LtJ6eFBLARIWA^RAAkAI
n+pq\K AQbXdTZy>tMclkAAAQaAAAA6AAAAAAAAAAAAAACpkT9IB\BndGqqduS#L*BueC>*cY+#Mm>QhZS5d&>4
^Z^d#B SZl\etX#e!>TbZM9e&qudm=mdZBRT\ECFAMWAAIACAD>XY$q!%wSYmEMAAA?D\AAL\AAAAAAAAAAAAAA
?*Z&Pw yIH<!AeAa&^ybY=$e!>\b*A9h&q8M#I9WEhRaYS6cY+9WtX#L$FpdYq8X&q/MYJyhC=mdZBRT\ECFAMW
JJYyX1 AAIACAD>XY$qK<CJTPnDAAC+WREAMAAAAAAAAAAAAAAAyIF1%ReAa&^ybY=$e!>\b*A9h&q8M#I9WEhR
!>C+b1 aYS6cY+9WtX#L$FpdYq8X&q/MnSmcZR8at%\WE5BAlRDFAACAAkA@XX6JTRy4tupHRAA6nkAAC<AAAAA
>jIMdl AAAAAAAAAKTBwJpIAGN5cYX8hHM9eGh\L*hydnM!L%BHWGFpdYq8L%Jqe!>BbG%ydqhyinSmcZR8at%\
I?i+?J WE5BAlRDFAACAAkA@XX6JeH@q$wSL\AA6uRAAC<AAAAAAAAAAAAAAKTB$deIAGN5cYX8hHM9eGh\L*hy
w&G\&W dnM!L%BHWGFpdYq8L%Jqe!>BbG%ydqhyinlmcZR8at%\WE5BAlRDFAACAAkA@XX6Jeb#NA6nAAAA>kAA
8dl4#q ACpAAAAAAAAAAAAAAKTBL?eIAGN5cYX8hHM9eGh\L*hydnM!L%BHWGFpdYq8L%Jqe!>EW$F4bZp8at%\
CR4a1T WE5BAlRDFAACAAkA@XX6JbFwpWk^AAAAjkAAAC$AAAAAAAAAAAAAAKTB&ieIAGN5cYX8hHM9eGh\L*hy
Z8B?eI dnM!L%BHWGFpdYq8L%Jqe!>EW$F4bZq6aZN4LtJ6eFBLARIWA^RAAkAIAQ%XdTY%$5j9XkAAAQaAAAAy
:@Q%!h AAAAAAAAAAAAAACpkXZwCABndGqqduS#L*BueC>*cY+#Mm>RS%BlbG%ydm>TbZM9WqNBc&X=LtJ6eFBL
<:SMF: ARIWA^RAAkAIAQ%XdTWKd@=yMRAAAH+AAAA6AAAAAAAAAAAAAACpkjLwCABndGqqduS#L*BueC>*cY+#
6#8Etp Mm>RS%BlbG%ydm>TbZM9WqNBc&X=dYF#c!=mdZBRT\ECFAMWAAIACAD>XY$qKy<!BQkEAABtEkAAKAAA
h/jlwK AAAAAAAAAAAAyIF8/RkAa&^ybY=$e!>\b*A9h&q8M#I9WEhRaYS6cY+9WtX#L&FpdYq8Ltqnd%BLARIW
b+9F%X A^RAAkAIAAlYdTXIH//T!REAADaTAAAwAAAAAAAAAAAAAACpkc#8CABndGqqduS#L*BueC>*cY+#Mm>R
unMQNN S%BndC>TbZM9R$^ydYFuMnR8at%\WE5BAlRDFAACAAkACFb6JcGWHAb5ARAAhkMAACeAAAAAAAAAAAAA
R9KLZQ AKTB8@AIAGN5cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>DVGq6aYe$LtJ6eFBLARIWA^RAAkAIAAlY
j9tVjI dTWSCQiITAWAAGaTAAAnAAAAAAAAAAAAAACpkY#!CABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9
mR6:yZ T&X=Ltqnd%BLARIWA^RAAkAIAAlYdTXQ/kPewB\AAC=MAAA6AAAAAAAAAAAAAACpkjZ*CABndGqqduS#
+l\YaW L*BueC>*cY+#Mm>RS%BndC>TbZM9atq/e*B5aZNwMYJyhC=mdZBRT\ECFAMWAAIACAAJXt$qS@yIJ!/M
4>Gp@R AAAtK\EALRAAAAAAAAAAAAAAyIHkFApAa&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9WtX#L&JyiuN\dGF#
FZP/$C cDSmcZR8at%\WE5BAlRDFAACAAkACXb6JV#BmlL#4RAAqqpCAC$AAAAAAAAAAAAAAKTBYcEJAGN5cYX8
HhQlWH hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>mcZy#eG^le&k+atq$LtJ6eFBLARIWA^RAAkAIAAyYdTY@:aTB
q5=mm! K\\AAC=MAAA4AAAAAAAAAAAAAACpkbhQCkBndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9a*JqbGq$
iuXbD< e#FmcZR8at%\WE5BAlRDFAACAAkACqb6JS*D?mGnNkAAJm5BAC5AAAAAAAAAAAAAAKTBC%\KAGN5cYX8
YbV6p! hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>netXpcZS#NGJyhC=mdZBRT\ECFAMWAAIACAALXt$qLGBCS8a5
AtSd6Q AACYYRIAK\AAAAAAAAAAAAAAyIH*pkwAa&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9WtX#L&N!bYSyhHM+
FwY/pL atq$LtJ6eFBLARIWA^RAAkAIAA6YdTZAI4TthR5AAM+#AAAwAAAAAAAAAAAAAACpkTdACkBndGqqduS#
<XV/d% L*BueC>*cY+#Mm>RS%BndC>TbZM9bZbldDFmcZR8at%\WE5BAlRDFAACAAkAC%b6JZFWh=yIFkAALDMA
d%>Pwl ACkAAAAAAAAAAAAAAKTB+e5KAGN5cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>qhtF5NGJyhC=mdZBR
@4:n\* T\ECFAMWAAIACAALXt$qY@!hb+IlAAAWX\AAKAAAAAAAAAAAAAAAyIF9+kwAa&^ybY=$e!>\b*A9h&q8
W*hQeD M#I9WEhRa&\9WtX#L&X&aY\+atq$LtJ6eFBLARIWA^RAAkAIAA6YdTZktR<4+REAAD+JAAAuAAAAAAAA
ky!VE% AAAAAACpkVeEC\BndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9bZl\cZJqbC=mdZBRT\ECFAMWAAIA
CAMCLK CAALXt$q4?^cjd+eAAA8VAAALkAAAAAAAAAAAAAAyIFhBk5Aa&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9
DKXVqG WtX#L&b!bYX#eG^le&k^atq$LpJNWFBLARIWA^RAAkAIAA^YdTXE9Qyk8w5AACa4ARA8AAAAAAAAAAAA
mBpIXK AACpkYenC\BndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9buJqbZN\dGF#cDSmcZR8Rp%RWE5BAlRD
<LC8Fm FAACAAkADXb6JYqEK5p:1\AAqqpCAC+AAAAAAAAAAAAAAKTBdc<LAGN5cYX8hHM9eGh\L*hydnM!L%BH
5h#nbk WGN5L%Jqe!>tetXqe*B5aZNwPGJyhC=CVXBRT\ECFAMWAAIACAANXt$qDyke/\5BAAA?CRAAJRAAAAAA
kXp51P AAAAAAAAyIH$Yk\Aa&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9WtX#L*F6aZJ4LtJ6eFBLARIWA^RAAkAI
*KZ4L5 AA%YdTZEYk%&?AEAAD+JAAAuAAAAAAAAAAAAAACpkWJeDABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>T
YLMmLw bZM9etX&d&6qbC=mdZBRT\ECFAMWAAIACAANXt$qm!V$pWWNAAA8VAAALkAAAAAAAAAAAAAAyIF@Zk\A
plj58+ a&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9WtX#L*J#aYN!bYSyhHM^atq$LtJ6eFBLARIWA^RAAkAIAA=Y
RqKK1M dTYi9XWS4#kAACa4ARA8AAAAAAAAAAAAAACpkSB5DABndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9
P%l#W^ euNla*JqbGq$e#SmcZR8at%\WE5BAlRDFAACAAkADqb6JY$F>i/eL\AAqqpCAC+AAAAAAAAAAAAAAKTB
ihiG!5 C/WMAGN5cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>!e&FnetXpcZS#PGJyhC=mdZBRT\ECFAMWAAIA
y>k^9j CAAPXt$qG$=86c\6AAA8VAAAKkAAAAAAAAAAAAAAyIH#%A\Aa&^ybY=$e!>\b*A9h&q8M#I9WEhRa&\9
5W6L#* WtX#L*N\dGF#cDFmcZR8at%\WE5BAlRDFAACAAkADqb6Jej+<kMHmAAAJm5BACwAAAAAAAAAAAAAAKTB
^Nt@kA =\INAGN5cYX8hHM9eGh\L*hydnM!L%BHWGN5L%Jqe!>#eG^le&k$atq$LtJ6eFBLARIWA^RAAkAIAA>Y
kVSu6T dTW$&$!BT1+AAJbbAkA1AAAAAAAAAAAAAACpkVcLDRBndGqqduS#L*BueC>*cY+#Mm>RS%BndC>TbZM9
DEVC6i e*B5aZNwPGJyhC=mdZBRT\ECFAMWAAIACAAWXt$qD5+C?MIEAABtEkAAJRAAAAAAAAAAAAAAyIHIPR+A
XG@KNy a&^ybY=$e!>\b*A9h&q8M#I9WEhRc&X=e!>TbZM9T&X=Ltqnd%BLARIWA^RAAkAIABSYdTZylt5^&kMA
4HG8PQ ADaiAAA8AAAAAAAAAAAAAACpke$?DkBndGqqduS#L*BueC>*cY+#Mm>RS%B4bZq#L%Jqe!>Wd&>5atF!
-A4d#u 000829f185400110334 Page 272 of binaries2.zip
w>jVdF MnSmcZR8at%\WE5BAlRDFAACAAkAFFb6Jj!YQV8bAkAAhkWAAC$AAAAAAAAAAAAAAKTB<$IPAGN5cYX8
$Kd9Bm hHM9eGh\L*hydnM!L%BHWG6qiZM9WtX#L%S9d&^maZI$atq$LtJ6eFBLARIWA^RAAkAIABSYdTX$<G!b
<qka8& uRAAAEaBAAA1AAAAAAAAAAAAAACpkhhFDkBndGqqduS#L*BueC>*cY+#Mm>RS%B4bZq#L%Jqe!>leuJ9
!HEj!k h&N9eC=nhZJRT\ECFAMWAAIACAAWXt$qcEqtYXMKAABAD\AAK\AAAAAAAAAAAAAAyIG<Sk+Aa&^ybY=$
T=I!wh e!>\b*A9h&q8M#I9WEhRc&X=e!>TbZM9c&h*cZw^atq$LtJ6eFBLARIWA^RAAkAIABXYdTWd18FXyl<A
cKM1KY ALa+AAA4AAAAAAAAAAAAAACpkXlSDkBndGqqduS#L*BueC>*cY+#Mm>RS%B4bZq#L%Jqe!>4b*hyinSm
kbtFyJ cZR8at%\WE5BAlRDFAACAAkAFXb6JT9@Y:+8MAAA6uRAAC5AAAAAAAAAAAAAAKTBS*EPAGN5cYX8hHM9
1b!q!I eGh\L*hydnM!L%BHWG6qiZM9WtX#L&6uh&q/PGJyhC=mdZBRT\ECFAMWAAIACAAaXt$qGiYdmKAAAAD?
CwM6Kp AkAAJ\AAAAAAAAAAAAAAyIG?wR+Aa&^ybY=$e!>\b*A9h&q8M#I9WEhRdG>uL*Jqe!>maYS#cYe8cYN9
Y6b:XJ WE5BAlRDFAACAAkAGFb6Jjc:+K=@AAAA@kIAACkAAAAAAAAAAAAAAKTBw/IPAGN5cYX8hHM9eGh\L*hy
i&>DQJ dnM!L%BHWG^9b!>!bZM9b&>9bHNyb!=ya&>RT\ECFAMWAAIACAAaXt$q9tXLJSRBAAD?AkAAKAAAAAAA
XL+uRD AAAAAAAAyIFww\+Aa&^ybY=$e!>\b*A9h&q8M#I9WEhRdG>uL*Jqe!>5d&hya&>8Ltqnd%BLARIWA^RA
kPZhbu AkAIABlYdTZG>HZkmAAAAQ+CAAAyAAAAAAAAAAAAAACpkeKpDkBndGqqduS#L*BueC>*cY+#Mm>RS%B5
$F%pn% d&e9etX#L*BueGX!et>!Ltqnd%BLARIWA^RAAkAIAB^YdTXWj\4IMAEAAQ+CAAAqAAAAAAAAAAAAAACp
dkAF+t kbGqDkBndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9aYX+eG58cYN9WE5BAlRDFAACAAkAHFb6Ja$c
N/Ec\n IIP8BAAAblIAACMAAAAAAAAAAAAAAKTBBKePAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>le&M8
6AG\yA cYN9WE5BAlRDFAACAAkAHFb6JhTI<*!dAAAA@kIAACRAAAAAAAAAAAAAAKTB</5PAGN5cYX8hHM9eGh\
BB8kRy L*hydnM!L%BHWHNnL*Jqe!>tiYX9Ltqnd%BLARIWA^RAAkAIAB^YdTWi\y*#BEkAADd8AAAuAAAAAAAA
N&!aDc AAAAAACpkhC5DkBndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9dYE^M*k!NC=mdZBRT\ECFAMWAAIA
KAID5H CAAeXt$q1dP/4RIkAAA&YAAAJkAAAAAAAAAAAAAAyIEb>R+Aa&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9
jqw@bB etX#L&%lPHk^NC=mdZBRT\ECFAMWAAIACAAeXt$q@6=JL+bCAAA&:kAAJ\AAAAAAAAAAAAAAyIFjFR<A
ma$GRZ a&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9etX#L&%mMVN+MnR8at%\WE5BAlRDFAACAAkAHFb6Je:<IM^@
ZFXY/I IAAANqkAACaAAAAAAAAAAAAAAKTBKqkQAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>6anl+MVR8
ZSmY5c at%\WE5BAlRDFAACAAkAHFb6JXX4q9?lRkAAN8+AACeAAAAAAAAAAAAAAKTB:ZkQAGN5cYX8hHM9eGh\
5i5i*k L*hydnM!L%BHWHNnL*Jqe!>6a#E#iDI$LtJ6eFBLARIWA^RAAkAIAB^YdTY&LD>CD!AAADbaAAAtAAAA
hVCE/e AAAAAAAAAACpkhP:D\BndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9dYM+iDE$LtJ6eFBLARIWA^RA
Ce\\Ip AkAIAB^YdTZl?umTNEkAADd8AAAuAAAAAAAAAAAAAACpkTdeD\BndGqqduS#L*BueC>*cY+#Mm>RS%B#
*yc+=Z a!>!bZM9dYR^M*k!NC=mdZBRT\ECFAMWAAIACAAhXt$q+bE%<b+kAAA&YAAAJkAAAAAAAAAAAAAAyIGj
WF*dlG JBAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9etX#L&%pPHk^NC=mdZBRT\ECFAMWAAIACAAhXt$q+!6>
j^W6:^ E6<EAABtEkAAI\AAAAAAAAAAAAAAyIGBSSAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9etX#L*BueC=y
V:9ALB a&>RT\ECFAMWAAIACAAhXt$q8LJ?ln5FAABtEkAAI\AAAAAAAAAAAAAAyIGlTlAAa&^ybY=$e!>\b*A9
Zetcpu h&q8M#I9WEhRe&M9etX#L*Buem=ya&>RT\ECFAMWAAIACAAhXt$qNZ&RIqEFAABtEkAAJRAAAAAAAAAA
Cd#9^A AAAAyIEhWBAAa&^ybY=$e!>\b*A9h&q8M#I9WEhRe&M9etX#L*B!ht6!Ltqnd%BLARIWA^RAAkAIAB%Y
u!yH:1 dTZcAphGP\WAAGaTAAAqAAAAAAAAAAAAAACpkdFXEABndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9
R>XQ+N eHXmc*I8cYN9WE5BAlRDFAACAAkAHXb6JT!eyETaBRAAblIAACMAAAAAAAAAAAAAAKTBL%5RAGN5cYX8
IVJVkF hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>!dtR8cYN9WE5BAlRDFAACAAkAHXb6JcM*i9EwBRAAblIAACMA
c>cC1L AAAAAAAAAAAAAKTBCGERAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>#cGa8cYN9WE5BAlRDFAAC
PCKw*Z AAkAHXb6JSK*K\H\BAAAblIAACMAAAAAAAAAAAAAAKTBeYaRAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNn
d?/1aE L*Jqe!>#cYe8cYN9WE5BAlRDFAACAAkAHXb6JXFbGZY!CRAARA<AAC\AAAAAAAAAAAAAAKTBwt5RAGN5
:6\Xw* cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>*cZBqe&qpbYJlenE8at%\WE5BAlRDFAACAAkAHXb6JWiV
CPM+jT +K\bqkAA8FEBAC$AAAAAAAAAAAAAAKTBuuWRAGN5cYX8hHM9eGh\L*hydnM!L%BHWHNnL*Jqe!>*cZBq
::QjN@ e&qpbYJlenI$LtJ6eFBLARIWA^RAAkAIAB%YdTYWhci4LS<AALa+AAA5AAAAAAAAAAAAAACpkRIMERBn
y:WYuc dGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9h&q\bZNybGXmaZI$LtJ6eFBLARIWA^RAAkAIAB%YdTZl
LB#XJ= W&AT$CkAALl$AAA5AAAAAAAAAAAAAACpkZp4ERBndGqqduS#L*BueC>*cY+#Mm>RS%B#a!>!bZM9h&q\
<dtc^Q bZNybGXmaZI+LtJ6eFBLARIWA^RAAkAIACFYdTYF=\@Nl\RAAGaTAAA4AAAAAAAAAAAAAACpkbNWERBn
Cw%<N8 dGqqduS#L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9XE>QVFNJR$<8TWNQWE5BAlRDFAACAAkAIXb6JZ#b
RYX:l5 Llj&AAAA@kIAAC5AAAAAAAAAAAAAAKTBa%pSAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5
RQp8iM NGSqa*bqem=ya&>RT\ECFAMWAAIACAAlXt$q/#nV9<+AAAD?AkAAKAAAAAAAAAAAAAAAyIGmYlEAa&^y
l!F!yZ bY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\$bY=nLtqnd%BLARIWA^RAAkAIACFYdTWJM!@WC\EA
R@e$W* AQ+CAAA4AAAAAAAAAAAAAACpkdbdERBndGqqduS#L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9dDSqdtN#
5%/#?\ cYe8cYN9WE5BAlRDFAACAAkAIXb6JYDVTR$LARAA@kIAACpAAAAAAAAAAAAAAKTBCq$SAGN5cYX8hHM9
J@e5!q eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5NG6qiZM8cYN9WE5BAlRDFAACAAkAIXb6JT6S$pL=AAAA@kIA
q!Sc$X ACkAAAAAAAAAAAAAAKTBZF+SAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5NHNyb!=ya&>R
qJ8G4N T\ECFAMWAAIACAAlXt$q5RI+1#MBAAD?AkAAKRAAAAAAAAAAAAAAyIGdZ^EAa&^ybY=$e!>\b*A9h&q8
mG#TuB M#I9WEhRhG>9dHM9etX#L&\$h&q\bT=ya&>RT\ECFAMWAAIACAAlXt$q%B96LBeBAAD?AkAAKkAAAAAA
/V%j+1 AAAAAAAAyIEXaSEAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\$h&q\bZa8cYN9WE5BAlRD
u%#&iq FAACAAkAIXb6Je@dR^FBA\AA6k5AAC5AAAAAAAAAAAAAAKTBhGISAGN5cYX8hHM9eGh\L*hydnM!L%BH
XyPI?N WHS9d&^#L*Jqe!>5PGSqa*bqem=ya&>RT\ECFAMWAAIACAAlXt$q</1kGk<DAAC&C\AAKAAAAAAAAAAA
NTB#YT AAAAyIH?bSEAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\+bY=nLtqnd%BLARIWA^RAAkAI
H#PN*Z ACFYdTXM9^4PY\MAALaLAAA4AAAAAAAAAAAAAACpkXNyERBndGqqduS#L*BueC>*cY+#Mm>RS%B$d&>5
$Y=S9j e!>!bZM9dDlqdtN#cYe8cYN9WE5BAlRDFAACAAkAIXb6JeaE+HVBBAAAdlwAACpAAAAAAAAAAAAAAKTB
#:VZJG >&\SAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>5PG6qiZM8cYN9WE5BAlRDFAACAAkAIXb6
?NBwqk Jd+*w!hPA\AA6k5AACkAAAAAAAAAAAAAAKTB@*ESAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jq
JH:6q% e!>5PHNyb!=ya&>RT\ECFAMWAAIACAAlXt$qK@&#ktaDAAC&C\AAKRAAAAAAAAAAAAAAyIGVhSEAa&^y
Btb:d/ bY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\+h&q\bT=ya&>RT\ECFAMWAAIACAAlXt$qlkNi5EWD
\@yL<y AAC&C\AAKkAAAAAAAAAAAAAAyIFAiSEAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L&\+h&q\
a*ww9H bZa8cYN9WE5BAlRDFAACAAkAIXb6JW\jk8YkAAAA@kIAAC5AAAAAAAAAAAAAAKTB#Z\SAGN5cYX8hHM9
>&WeaG eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>#NGSqa*bqem=ya&>RT\ECFAMWAAIACAAmXt$qiLXawbWAAAD?
bSEeB\ AkAAKAAAAAAAAAAAAAAAyIG&jSEAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L*M$bY=nLtqn
YhDDML d%BLARIWA^RAAkAIACJYdTYVGl:=6RAAAQ+CAAA4AAAAAAAAAAAAAACpkbF?ERBndGqqduS#L*BueC>*
@6m4p\ cY+#Mm>RS%B$d&>5e!>!bZM9e#SqdtN#cYe8cYN9WE5BAlRDFAACAAkAIqb6JZ%i#D?5AAAA@kIAACpA
kyLuPd AAAAAAAAAAAAAKTBn*<SAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>#NG6qiZM8cYN9WE5B
-AnhiL 001e2025e9700110334 Page 273 of binaries2.zip
wB\wp+ AlRDFAACAAkAIqb6JYQ%X=CqAAAA@kIAACkAAAAAAAAAAAAAAKTBkwASAGN5cYX8hHM9eGh\L*hydnM!
P&AK*I L%BHWHS9d&^#L*Jqe!>#NHNyb!=ya&>RT\ECFAMWAAIACAAmXt$q?PY/i4kAAAD?AkAAKRAAAAAAAAAA
mN^%Y% AAAAyIF6kSEAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L*M$h&q\bT=ya&>RT\ECFAMWAAIA
D6jYh# CAAmXt$qw#NuJL5AAAD?AkAAKkAAAAAAAAAAAAAAyIF5klEAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9
B&a^>\ dHM9etX#L*M$h&q\bZa8cYN9WE5BAlRDFAACAAkAIqb6Jab6IeZ9AkAA6k5AAC5AAAAAAAAAAAAAAKTB
6AAnww d+MSAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>#PGSqa*bqem=ya&>RT\ECFAMWAAIACAAm
^HL*5+ Xt$qR:u==6wCAAC&C\AAKAAAAAAAAAAAAAAAyIGullEAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9
Hkk1C9 etX#L*M+bY=nLtqnd%BLARIWA^RAAkAIACJYdTZlKqVyAkMAALaLAAA4AAAAAAAAAAAAAACpkeiJERBn
MYMYdi dGqqduS#L*BueC>*cY+#Mm>RS%B$d&>5e!>!bZM9e#lqdtN#cYe8cYN9WE5BAlRDFAACAAkAIqb6Jd/S
^P@XGQ b?HwAkAA6k5AACpAAAAAAAAAAAAAAKTBEw$SAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>#
!R6?NK PG6qiZM8cYN9WE5BAlRDFAACAAkAIqb6Japi<bLyAkAA6k5AACkAAAAAAAAAAAAAAKTBRbASAGN5cYX8
!^WSL& hHM9eGh\L*hydnM!L%BHWHS9d&^#L*Jqe!>#PHNyb!=ya&>RT\ECFAMWAAIACAAmXt$qYIBuF6$CAAC&
M$\8*% C\AAKRAAAAAAAAAAAAAAyIF\p^EAa&^ybY=$e!>\b*A9h&q8M#I9WEhRhG>9dHM9etX#L*M+h&q\bT=y
ec*RPQ a&>RT\ECFAMWAAIACAAmXt$qS%Bp1ikCAAC&C\AAKkAAAAAAAAAAAAAAyIGWqlEAa&^ybY=$e!>\b*A9
npBN&k h&q8M#I9WEhRhG>9dHM9etX#L*M+h&q\bZa8cYN9WE5BAlRDFAACAAkAJFb6JSB#kmtjAAAA@kIAACpA
p+@QpL AAAAAAAAAAAAAKTB^JpSAGN5cYX8hHM9eGh\L*hydnM!L%BHWHS!aZp9WtX#L%SBW$6CRXI8TWNQWE5B
a#d5C8 AlRDFAACAAkAQFb6JXMKDcy6AAAAmkEAACkAAAAAAAAAAAAAAKTB1ywSAGN5cYX8hHM9eGh\L*hydnM!
+hpP=e L*BueEX+a&k9WtX#L$JXXFSQVm=CVXBRT\ECFAMWAAIACAA<Xt$qRDQVt=WAAAD&AAAAJ\AAAAAAAAAA
enMSw! AAAAyIFht^EAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>TbZM9XGJ9hGk8at%\WE5BAlRDFAACAAkA
mX=PF9 QFb6JWJcnE6@AAAA>kAAACwAAAAAAAAAAAAAAKTBN=\SAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9
+ht^/T WtX#L%SpbYN!iZB$LtJ6eFBLARIWA^RAAkAIAD^YdTXympK<lAAAAQaAAAA1AAAAAAAAAAAAAACpkj/e
d?5d<+ ERBndGqqduS#L*BueC>*cY+#Mm>\b*BFiGNwL%Jqe!>WbY=neuq\hC=mdZBRT\ECFAMWAAIACAA<Xt$q
DLqcb? Vu\BF+$AAAD&AAAAKkAAAAAAAAAAAAAAyIHKuSEAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>TbZM9
R?ypQ9 XHBueG6qiZM8at%\WE5BAlRDFAACAAkAQFb6JXAXtVcEAAAA>kAAACeAAAAAAAAAAAAAAKTBu=+SAGN5
9aIBLu cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L%S#cYh8LtJ6eFBLARIWA^RAAkAIAD^YdTX?>$qBqkAA
\Ty5yj AQaAAAAwAAAAAAAAAAAAAACpkYmjERBndGqqduS#L*BueC>*cY+#Mm>\b*BFiGNwL%Jqe!>lbGS4bZp8
u%&MR& at%\WE5BAlRDFAACAAkAQFb6JW%YF<TVAAAA>kAAACaAAAAAAAAAAAAAAKTBSKASAGN5cYX8hHM9eGh\
liqD4c L*hydnM!L*BueEX+a&k9WtX#L&J9hGk8at%\WE5BAlRDFAACAAkAQFb6JVeDC1>?AAAA>kAAACpAAAAA
%XX$YS AAAAAAAAAKTBG/ESAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L&Sqa*J=eHR8at%\WE5BAlRD
=Mu>$N FAACAAkAQFb6JaYM\P!DAAAA>kAAACpAAAAAAAAAAAAAAKTB+KESAGN5cYX8hHM9eGh\L*hydnM!L*Bu
%L4$jH eEX+a&k9WtX#L&X8a*J=eHR8at%\WE5BAlRDFAACAAkAQFb6JXNyFj!KAAAA>kAAACpAAAAAAAAAAAAA
N/Y9Sy AKTB11ISAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9WtX#L*BueG6qiZM8at%\WE5BAlRDFAACAAkA
@LX%6G QFb6JZn6Q<hYAAAA>kAAACkAAAAAAAAAAAAAAKTBi/MSAGN5cYX8hHM9eGh\L*hydnM!L*BueEX+a&k9
w&Rqt@ WtX#L*BueG=9h!=mdZBRT\ECFAMWAAIACAA<Xt$q%WuIh8eBAABWBkAAJkAAAAAAAAAAAAAAyIEZyBEA
V?\#td a&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>TbZM9etXlbC=mdZBRT\ECFAMWAAIACAA<Xt$qZ4\mRh5B
6Z>P\: AADWAkAAJkAAAAAAAAAAAAAAyIFCylEAa&^ybY=$e!>\b*A9h&q8M#I9eGh\SZlncC>TbZM9e&X8bC=m
+q&h*& dZBRT\ECFAMWAAIACAA<Xt$qcR9eRaIAAAD&AAAAJkAAAAAAAAAAAAAAyIFl1BEAa&^ybY=$e!>\b*A9
mhaR\p h&q8M#I9eGh\SZlncC>TbZM9e&qudm=mdZBRT\ECFAMWAAIACABAXt$qH6XaQd$IAAA&kRAAJRAAAAAA
Fh^+SJ AAAAAAAAyIEu1SEAa&^ybY=$e!>\b*A9h&q8M#I9e&lletXpL&q6aYhqe#I$LtJ6eFBLARIWA^RAAkAI
n&D$HB AEBYdTZY1%/!>kWAAQaXAAApAAAAAAAAAAAAAACpkTi!ERBndGqqduS#L*BueC>*cY+#Mm>#cGF!bYR9
+kE?aR cY%lb&X#NC=mdZBRT\WGAAAAALWA6RAMQ\AAZ:kSAAAA
